From 1ed304881cef884e89ae8c1607fb47f832893817 Mon Sep 17 00:00:00 2001 From: Jonathan Edey Date: Wed, 7 Feb 2024 16:24:01 -0500 Subject: [PATCH 1/2] Test mailgun update --- .github/actions/send-email/dist/index.js | 38592 +++++++++-------- .github/actions/send-email/package-lock.json | 395 +- .github/actions/send-email/package.json | 2 +- .github/workflows/ci.yml | 44 +- 4 files changed, 19407 insertions(+), 19626 deletions(-) diff --git a/.github/actions/send-email/dist/index.js b/.github/actions/send-email/dist/index.js index 410dda0a18..c7529cc1dd 100644 --- a/.github/actions/send-email/dist/index.js +++ b/.github/actions/send-email/dist/index.js @@ -1834,24372 +1834,24390 @@ function isLoopbackAddress(host) { /***/ }), -/***/ 5046: -/***/ (function(module, __unused_webpack_exports, __nccwpck_require__) { - -/*! For license information please see mailgun.node.js.LICENSE.txt */ -!function(e,t){ true?module.exports=t():0}(this,(function(){return(()=>{var e={271:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=r(185);class AbortSignal extends o.EventTarget{constructor(){throw super(),new TypeError("AbortSignal cannot be constructed directly")}get aborted(){const e=n.get(this);if("boolean"!=typeof e)throw new TypeError("Expected 'this' to be an 'AbortSignal' object, but got "+(null===this?"null":typeof this));return e}}o.defineEventAttribute(AbortSignal.prototype,"abort");const n=new WeakMap;Object.defineProperties(AbortSignal.prototype,{aborted:{enumerable:!0}}),"function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag&&Object.defineProperty(AbortSignal.prototype,Symbol.toStringTag,{configurable:!0,value:"AbortSignal"});class AbortController{constructor(){s.set(this,function(){const e=Object.create(AbortSignal.prototype);return o.EventTarget.call(e),n.set(e,!1),e}())}get signal(){return i(this)}abort(){var e;e=i(this),!1===n.get(e)&&(n.set(e,!0),e.dispatchEvent({type:"abort"}))}}const s=new WeakMap;function i(e){const t=s.get(e);if(null==t)throw new TypeError("Expected 'this' to be an 'AbortController' object, but got "+(null===e?"null":typeof e));return t}Object.defineProperties(AbortController.prototype,{signal:{enumerable:!0},abort:{enumerable:!0}}),"function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag&&Object.defineProperty(AbortController.prototype,Symbol.toStringTag,{configurable:!0,value:"AbortController"}),t.AbortController=AbortController,t.AbortSignal=AbortSignal,t.default=AbortController,e.exports=AbortController,e.exports.AbortController=e.exports.default=AbortController,e.exports.AbortSignal=AbortSignal},48:function(e,t,r){"use strict";var o=(this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}})(r(475)),n=function(){function e(e){this.formData=e}return e.prototype.client=function(e){return new o.default(e,this.formData)},e}();e.exports=n},475:function(e,t,r){"use strict";var o=this&&this.__assign||function(){return o=Object.assign||function(e){for(var t,r=1,o=arguments.length;r{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype.list=function(e){var t=this;return this.request.get("/v1/ip_pools",e).then((function(e){return t.parseIpPoolsResponse(e)}))},e.prototype.create=function(e){return this.request.post("/v1/ip_pools",e).then((function(e){return null==e?void 0:e.body}))},e.prototype.update=function(e,t){return this.request.patch("/v1/ip_pools/"+e,t).then((function(e){return null==e?void 0:e.body}))},e.prototype.delete=function(e,t){return this.request.delete("/v1/ip_pools/"+e,t).then((function(e){return null==e?void 0:e.body}))},e.prototype.parseIpPoolsResponse=function(e){return e.body.ip_pools},e}();t.default=r},345:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype.list=function(e){var t=this;return this.request.get("/v3/ips",e).then((function(e){return t.parseIpsResponse(e)}))},e.prototype.get=function(e){var t=this;return this.request.get("/v3/ips/"+e).then((function(e){return t.parseIpsResponse(e)}))},e.prototype.parseIpsResponse=function(e){return e.body},e}();t.default=r},126:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){this.request=e,this.baseRoute="/v3/lists",this.members=t}return e.prototype.list=function(e){return this.request.get(this.baseRoute+"/pages",e).then((function(e){return e.body.items}))},e.prototype.get=function(e){return this.request.get(this.baseRoute+"/"+e).then((function(e){return e.body.list}))},e.prototype.create=function(e){return this.request.postWithFD(this.baseRoute,e).then((function(e){return e.body.list}))},e.prototype.update=function(e,t){return this.request.putWithFD(this.baseRoute+"/"+e,t).then((function(e){return e.body.list}))},e.prototype.destroy=function(e){return this.request.delete(this.baseRoute+"/"+e).then((function(e){return e.body}))},e}();t.default=r},135:function(e,t){"use strict";var r=this&&this.__assign||function(){return r=Object.assign||function(e){for(var t,r=1,o=arguments.length;r{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype._parseResponse=function(e){return e.body?e.body:e},e.prototype.create=function(e,t){return t.message?this.request.postWithFD("/v3/"+e+"/messages.mime",t).then(this._parseResponse):this.request.postWithFD("/v3/"+e+"/messages",t).then(this._parseResponse)},e}();t.default=r},826:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype.get=function(e,t){var r={};return Array.isArray(e)?r.addresses=e.join(","):r.addresses=e,t&&(r.syntax_only=!1),this.request.get("/v3/address/parse",r).then((function(e){return e.body}))},e}();t.default=r},438:function(e,t,r){"use strict";var o=this&&this.__assign||function(){return o=Object.assign||function(e){for(var t,r=1,o=arguments.length;r0&&n[n.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!n||s[1]>n[0]&&s[1]0&&(p.searchParams=n.query,delete p.query),[4,(0,l.default)((0,u.default)(this.url,t),o({method:e.toLocaleUpperCase(),headers:f,throwHttpErrors:!1,timeout:this.timeout},p))];case 1:return(null==(h=s.sent())?void 0:h.ok)?[3,6]:(null==h?void 0:h.body)&&d(h.body)?[4,(_=h.body,g=[],new Promise((function(e,t){_.on("data",(function(e){return g.push(e)})),_.on("error",t),_.on("end",(function(){return e(Buffer.concat(g).toString("utf8"))}))})))]:[3,3];case 2:return y=s.sent(),[3,5];case 3:return[4,null==h?void 0:h.json()];case 4:y=s.sent(),s.label=5;case 5:throw b=y,new c.default({status:null==h?void 0:h.status,statusText:null==h?void 0:h.statusText,body:{message:b}});case 6:return m={},[4,null==h?void 0:h.json()];case 7:return[2,(m.body=s.sent(),m.status=null==h?void 0:h.status,m)]}var _,g}))}))},e.prototype.query=function(e,t,r,n){return this.request(e,t,o({query:r},n))},e.prototype.command=function(e,t,r,n){return this.request(e,t,o({headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r},n))},e.prototype.get=function(e,t,r){return this.query("get",e,t,r)},e.prototype.head=function(e,t,r){return this.query("head",e,t,r)},e.prototype.options=function(e,t,r){return this.query("options",e,t,r)},e.prototype.post=function(e,t,r){return this.command("post",e,t,r)},e.prototype.postWithFD=function(e,t){var r=this.createFormData(t);return this.command("post",e,r,{headers:{"Content-Type":null}})},e.prototype.putWithFD=function(e,t){var r=this.createFormData(t);return this.command("put",e,r,{headers:{"Content-Type":null}})},e.prototype.createFormData=function(e){var t=function(e,t,r){var n=d(t)?t:t.data,s=function(e){if("object"!=typeof e||d(e))return{};var t=e.filename,r=e.contentType,n=e.knownLength;return o(o(o({},t?{filename:t}:{filename:"file"}),r&&{contentType:r}),n&&{knownLength:n})}(t);!function(e){return void 0!==e.getHeaders}(r)?r.append(e,n,s.filename):r.append(e,n,s)};return Object.keys(e).filter((function(t){return e[t]})).reduce((function(r,o){if("attachment"===o||"inline"===o){var n=e[o];return Array.isArray(n)?n.forEach((function(e){t(o,e,r)})):t(o,n,r),r}return Array.isArray(e[o])?e[o].forEach((function(e){r.append(o,e)})):null!=e[o]&&r.append(o,e[o]),r}),new this.formData)},e.prototype.put=function(e,t,r){return this.command("put",e,t,r)},e.prototype.patch=function(e,t,r){return this.command("patch",e,t,r)},e.prototype.delete=function(e,t,r){return this.command("delete",e,t,r)},e}();t.default=f},277:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype.list=function(e){return this.request.get("/v3/routes",e).then((function(e){return e.body.items}))},e.prototype.get=function(e){return this.request.get("/v3/routes/"+e).then((function(e){return e.body.route}))},e.prototype.create=function(e){return this.request.postWithFD("/v3/routes",e).then((function(e){return e.body.route}))},e.prototype.update=function(e,t){return this.request.putWithFD("/v3/routes/"+e,t).then((function(e){return e.body}))},e.prototype.destroy=function(e){return this.request.delete("/v3/routes/"+e).then((function(e){return e.body}))},e}();t.default=r},747:function(e,t,r){"use strict";var o=this&&this.__assign||function(){return o=Object.assign||function(e){for(var t,r=1,o=arguments.length;r{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype.get=function(e){return this.request.get("/v3/address/validate",{address:e}).then((function(e){return e.body}))},e}();t.default=r},750:function(e,t,r){"use strict";var o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var n=o(r(78)),s=function(e,t){this.id=e,this.url=t},i=function(){function e(e){this.request=e}return e.prototype._parseWebhookList=function(e){return e.body.webhooks},e.prototype._parseWebhookWithID=function(e){return function(t){var r,o=null===(r=null==t?void 0:t.body)||void 0===r?void 0:r.webhook,n=null==o?void 0:o.url;return n||(n=(null==o?void 0:o.urls)&&o.urls.length?o.urls[0]:null),new s(e,n)}},e.prototype._parseWebhookTest=function(e){return{code:e.body.code,message:e.body.message}},e.prototype.list=function(e,t){return this.request.get((0,n.default)("/v2/domains",e,"webhooks"),t).then(this._parseWebhookList)},e.prototype.get=function(e,t){return this.request.get((0,n.default)("/v2/domains",e,"webhooks",t)).then(this._parseWebhookWithID(t))},e.prototype.create=function(e,t,r,o){return void 0===o&&(o=!1),o?this.request.putWithFD((0,n.default)("/v2/domains",e,"webhooks",t,"test"),{url:r}).then(this._parseWebhookTest):this.request.postWithFD((0,n.default)("/v2/domains",e,"webhooks"),{id:t,url:r}).then(this._parseWebhookWithID(t))},e.prototype.update=function(e,t,r){return this.request.putWithFD((0,n.default)("/v2/domains",e,"webhooks",t),{url:r}).then(this._parseWebhookWithID(t))},e.prototype.destroy=function(e,t){return this.request.delete((0,n.default)("/v2/domains",e,"webhooks",t)).then(this._parseWebhookWithID(t))},e}();t.default=i},501:function(e,t,r){var o;e=r.nmd(e),function(n){var s=t,i=(e&&e.exports,"object"==typeof global&&global);i.global!==i&&i.window;var a=function(e){this.message=e};(a.prototype=new Error).name="InvalidCharacterError";var u=function(e){throw new a(e)},l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",c=/[\t\n\f\r ]/g,d={encode:function(e){e=String(e),/[^\0-\xFF]/.test(e)&&u("The string to be encoded contains characters outside of the Latin1 range.");for(var t,r,o,n,s=e.length%3,i="",a=-1,c=e.length-s;++a>18&63)+l.charAt(n>>12&63)+l.charAt(n>>6&63)+l.charAt(63&n);return 2==s?(t=e.charCodeAt(a)<<8,r=e.charCodeAt(++a),i+=l.charAt((n=t+r)>>10)+l.charAt(n>>4&63)+l.charAt(n<<2&63)+"="):1==s&&(n=e.charCodeAt(a),i+=l.charAt(n>>2)+l.charAt(n<<4&63)+"=="),i},decode:function(e){var t=(e=String(e).replace(c,"")).length;t%4==0&&(t=(e=e.replace(/==?$/,"")).length),(t%4==1||/[^+a-zA-Z0-9/]/.test(e))&&u("Invalid character: the string to be decoded is not correctly encoded.");for(var r,o,n=0,s="",i=-1;++i>(-2*n&6)));return s},version:"1.0.0"};void 0===(o=function(){return d}.call(t,r,t,e))||(e.exports=o)}()},175:e=>{"use strict";e.exports=function(e){if(!/^data:/i.test(e))throw new TypeError('`uri` does not appear to be a Data URI (must begin with "data:")');const t=(e=e.replace(/\r?\n/g,"")).indexOf(",");if(-1===t||t<=4)throw new TypeError("malformed data: URI");const r=e.substring(5,t).split(";");let o="",n=!1;const s=r[0]||"text/plain";let i=s;for(let e=1;e{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=new WeakMap,o=new WeakMap;function n(e){const t=r.get(e);return console.assert(null!=t,"'this' is expected an Event object, but got",e),t}function s(e){null==e.passiveListener?e.event.cancelable&&(e.canceled=!0,"function"==typeof e.event.preventDefault&&e.event.preventDefault()):"undefined"!=typeof console&&"function"==typeof console.error&&console.error("Unable to preventDefault inside passive event listener invocation.",e.passiveListener)}function i(e,t){r.set(this,{eventTarget:e,event:t,eventPhase:2,currentTarget:e,canceled:!1,stopped:!1,immediateStopped:!1,passiveListener:null,timeStamp:t.timeStamp||Date.now()}),Object.defineProperty(this,"isTrusted",{value:!1,enumerable:!0});const o=Object.keys(t);for(let e=0;e0){const e=new Array(arguments.length);for(let t=0;t{const{Readable:o}=r(781),n=new WeakMap;class Blob{constructor(e=[],t={}){let r=0;const o=e.map((e=>{let t;return t=e instanceof Buffer?e:ArrayBuffer.isView(e)?Buffer.from(e.buffer,e.byteOffset,e.byteLength):e instanceof ArrayBuffer?Buffer.from(e):e instanceof Blob?e:Buffer.from("string"==typeof e?e:String(e)),r+=t.length||t.size||0,t})),s=void 0===t.type?"":String(t.type).toLowerCase();n.set(this,{type:/[^\u0020-\u007E]/.test(s)?"":s,size:r,parts:o})}get size(){return n.get(this).size}get type(){return n.get(this).type}async text(){return Buffer.from(await this.arrayBuffer()).toString()}async arrayBuffer(){const e=new Uint8Array(this.size);let t=0;for await(const r of this.stream())e.set(r,t),t+=r.length;return e.buffer}stream(){return o.from(async function*(e){for(const t of e)"stream"in t?yield*t.stream():yield t}(n.get(this).parts))}slice(e=0,t=this.size,r=""){const{size:o}=this;let s=e<0?Math.max(o+e,0):Math.min(e,o),i=t<0?Math.max(o+t,0):Math.min(t,o);const a=Math.max(i-s,0),u=n.get(this).parts.values(),l=[];let c=0;for(const e of u){const t=ArrayBuffer.isView(e)?e.byteLength:e.size;if(s&&t<=s)s-=t,i-=t;else{const r=e.slice(s,Math.min(t,i));if(l.push(r),c+=ArrayBuffer.isView(r)?r.byteLength:r.size,s=0,c>=a)break}}const d=new Blob([],{type:String(r).toLowerCase()});return Object.assign(n.get(d),{size:a,parts:l}),d}get[Symbol.toStringTag](){return"Blob"}static[Symbol.hasInstance](e){return e&&"object"==typeof e&&"function"==typeof e.stream&&0===e.stream.length&&"function"==typeof e.constructor&&/^(Blob|File)$/.test(e[Symbol.toStringTag])}}Object.defineProperties(Blob.prototype,{size:{enumerable:!0},type:{enumerable:!0},slice:{enumerable:!0}}),e.exports=Blob},556:(e,t,r)=>{"use strict";const o=r(594),n=r(271);if(global.fetch||(global.fetch=(e,t)=>o(e,{highWaterMark:1e7,...t})),global.Headers||(global.Headers=o.Headers),global.Request||(global.Request=o.Request),global.Response||(global.Response=o.Response),global.AbortController||(global.AbortController=n),!global.ReadableStream)try{global.ReadableStream=r(902)}catch(e){}e.exports=r(721)},721:function(e){var t;t=function(){"use strict";const e={},t=e=>"undefined"!=typeof self&&self&&e in self?self:"undefined"!=typeof window&&window&&e in window?window:"undefined"!=typeof global&&global&&e in global?global:"undefined"!=typeof globalThis&&globalThis?globalThis:void 0,r=["Headers","Request","Response","ReadableStream","fetch","AbortController","FormData"];for(const o of r)Object.defineProperty(e,o,{get(){const e=t(o),r=e&&e[o];return"function"==typeof r?r.bind(e):r}});const o=e=>null!==e&&"object"==typeof e,n="function"==typeof e.AbortController,s="function"==typeof e.ReadableStream,i="function"==typeof e.FormData,a=(t,r)=>{const o=new e.Headers(t||{}),n=r instanceof e.Headers,s=new e.Headers(r||{});for(const[e,t]of s)n&&"undefined"===t||void 0===t?o.delete(e):o.set(e,t);return o},u=(...e)=>{let t={},r={};for(const n of e){if(Array.isArray(n))Array.isArray(t)||(t=[]),t=[...t,...n];else if(o(n)){for(let[e,r]of Object.entries(n))o(r)&&e in t&&(r=u(t[e],r)),t={...t,[e]:r};o(n.headers)&&(r=a(r,n.headers))}t.headers=r}return t},l=["get","post","put","patch","head","delete"],c={json:"application/json",text:"text/*",formData:"multipart/form-data",arrayBuffer:"*/*",blob:"*/*"},d=[413,429,503],f=Symbol("stop");class HTTPError extends Error{constructor(e){super(e.statusText||String(0===e.status||e.status?e.status:"Unknown response error")),this.name="HTTPError",this.response=e}}class TimeoutError extends Error{constructor(e){super("Request timed out"),this.name="TimeoutError",this.request=e}}const p=e=>new Promise((t=>setTimeout(t,e))),h=e=>l.includes(e)?e.toUpperCase():e,b={limit:2,methods:["get","put","head","delete","options","trace"],statusCodes:[408,413,429,500,502,503,504],afterStatusCodes:d},y=(e={})=>{if("number"==typeof e)return{...b,limit:e};if(e.methods&&!Array.isArray(e.methods))throw new Error("retry.methods must be an array");if(e.statusCodes&&!Array.isArray(e.statusCodes))throw new Error("retry.statusCodes must be an array");return{...b,...e,afterStatusCodes:d}},m=2147483647;class Ky{constructor(t,r={}){if(this._retryCount=0,this._input=t,this._options={credentials:this._input.credentials||"same-origin",...r,headers:a(this._input.headers,r.headers),hooks:u({beforeRequest:[],beforeRetry:[],afterResponse:[]},r.hooks),method:h(r.method||this._input.method),prefixUrl:String(r.prefixUrl||""),retry:y(r.retry),throwHttpErrors:!1!==r.throwHttpErrors,timeout:void 0===r.timeout?1e4:r.timeout,fetch:r.fetch||e.fetch},"string"!=typeof this._input&&!(this._input instanceof URL||this._input instanceof e.Request))throw new TypeError("`input` must be a string, URL, or Request");if(this._options.prefixUrl&&"string"==typeof this._input){if(this._input.startsWith("/"))throw new Error("`input` must not begin with a slash when using `prefixUrl`");this._options.prefixUrl.endsWith("/")||(this._options.prefixUrl+="/"),this._input=this._options.prefixUrl+this._input}if(n&&(this.abortController=new e.AbortController,this._options.signal&&this._options.signal.addEventListener("abort",(()=>{this.abortController.abort()})),this._options.signal=this.abortController.signal),this.request=new e.Request(this._input,this._options),this._options.searchParams){const t="?"+new URLSearchParams(this._options.searchParams).toString(),r=this.request.url.replace(/(?:\?.*?)?(?=#|$)/,t);!(i&&this._options.body instanceof e.FormData||this._options.body instanceof URLSearchParams)||this._options.headers&&this._options.headers["content-type"]||this.request.headers.delete("content-type"),this.request=new e.Request(new e.Request(r,this.request),this._options)}void 0!==this._options.json&&(this._options.body=JSON.stringify(this._options.json),this.request.headers.set("content-type","application/json"),this.request=new e.Request(this.request,{body:this._options.body}));const o=async()=>{if(this._options.timeout>m)throw new RangeError("The `timeout` option cannot be greater than 2147483647");await p(1);let t=await this._fetch();for(const r of this._options.hooks.afterResponse){const o=await r(this.request,this._options,this._decorateResponse(t.clone()));o instanceof e.Response&&(t=o)}if(this._decorateResponse(t),!t.ok&&this._options.throwHttpErrors)throw new HTTPError(t);if(this._options.onDownloadProgress){if("function"!=typeof this._options.onDownloadProgress)throw new TypeError("The `onDownloadProgress` option must be a function");if(!s)throw new Error("Streams are not supported in your environment. `ReadableStream` is missing.");return this._stream(t.clone(),this._options.onDownloadProgress)}return t},l=this._options.retry.methods.includes(this.request.method.toLowerCase())?this._retry(o):o();for(const[e,t]of Object.entries(c))l[e]=async()=>{this.request.headers.set("accept",this.request.headers.get("accept")||t);const o=(await l).clone();if("json"===e){if(204===o.status)return"";if(r.parseJson)return r.parseJson(await o.text())}return o[e]()};return l}_calculateRetryDelay(e){if(this._retryCount++,this._retryCountthis._options.retry.maxRetryAfter?0:e}if(413===e.response.status)return 0}return.3*2**(this._retryCount-1)*1e3}return 0}_decorateResponse(e){return this._options.parseJson&&(e.json=async()=>this._options.parseJson(await e.text())),e}async _retry(e){try{return await e()}catch(t){const r=Math.min(this._calculateRetryDelay(t),m);if(0!==r&&this._retryCount>0){await p(r);for(const e of this._options.hooks.beforeRetry)if(await e({request:this.request,options:this._options,error:t,retryCount:this._retryCount})===f)return;return this._retry(e)}if(this._options.throwHttpErrors)throw t}}async _fetch(){for(const e of this._options.hooks.beforeRequest){const t=await e(this.request,this._options);if(t instanceof Request){this.request=t;break}if(t instanceof Response)return t}return!1===this._options.timeout?this._options.fetch(this.request.clone()):(e=this.request.clone(),t=this.abortController,r=this._options,new Promise(((o,n)=>{const s=setTimeout((()=>{t&&t.abort(),n(new TimeoutError(e))}),r.timeout);r.fetch(e).then(o).catch(n).then((()=>{clearTimeout(s)}))})));var e,t,r}_stream(t,r){const o=Number(t.headers.get("content-length"))||0;let n=0;return new e.Response(new e.ReadableStream({start(e){const s=t.body.getReader();r&&r({percent:0,transferredBytes:0,totalBytes:o},new Uint8Array),async function t(){const{done:i,value:a}=await s.read();i?e.close():(r&&(n+=a.byteLength,r({percent:0===o?0:n/o,transferredBytes:n,totalBytes:o},a)),e.enqueue(a),t())}()}}))}}const _=(...e)=>{for(const t of e)if((!o(t)||Array.isArray(t))&&void 0!==t)throw new TypeError("The `options` argument must be an object");return u({},...e)},g=e=>{const t=(t,r)=>new Ky(t,_(e,r));for(const r of l)t[r]=(t,o)=>new Ky(t,_(e,o,{method:r}));return t.HTTPError=HTTPError,t.TimeoutError=TimeoutError,t.create=e=>g(_(e)),t.extend=t=>g(_(e,t)),t.stop=f,t};return g()},e.exports=t()},78:e=>{function t(e){return e.replace(/[\/]+/g,"/").replace(/\/\?/g,"?").replace(/\/\#/g,"#").replace(/\:\//g,"://")}e.exports=function(){var e=[].slice.call(arguments,0).join("/");return t(e)}},113:e=>{"use strict";e.exports=__nccwpck_require__(6113)},685:e=>{"use strict";e.exports=__nccwpck_require__(3685)},687:e=>{"use strict";e.exports=__nccwpck_require__(5687)},781:e=>{"use strict";e.exports=__nccwpck_require__(2781)},310:e=>{"use strict";e.exports=__nccwpck_require__(7310)},837:e=>{"use strict";e.exports=__nccwpck_require__(3837)},796:e=>{"use strict";e.exports=__nccwpck_require__(9796)},594:(e,t,r)=>{"use strict";t=e.exports=W;const o=r(685),n=r(687),s=r(796),i=r(781),a=r(175),u=r(837),l=r(30),c=r(113),d=r(310);class FetchBaseError extends Error{constructor(e,t){super(e),Error.captureStackTrace(this,this.constructor),this.type=t}get name(){return this.constructor.name}get[Symbol.toStringTag](){return this.constructor.name}}class FetchError extends FetchBaseError{constructor(e,t,r){super(e,t),r&&(this.code=this.errno=r.code,this.erroredSysCall=r.syscall)}}const f=Symbol.toStringTag,p=e=>"object"==typeof e&&"function"==typeof e.append&&"function"==typeof e.delete&&"function"==typeof e.get&&"function"==typeof e.getAll&&"function"==typeof e.has&&"function"==typeof e.set&&"function"==typeof e.sort&&"URLSearchParams"===e[f],h=e=>"object"==typeof e&&"function"==typeof e.arrayBuffer&&"string"==typeof e.type&&"function"==typeof e.stream&&"function"==typeof e.constructor&&/^(Blob|File)$/.test(e[f]);function b(e){return"object"==typeof e&&"function"==typeof e.append&&"function"==typeof e.set&&"function"==typeof e.get&&"function"==typeof e.getAll&&"function"==typeof e.delete&&"function"==typeof e.keys&&"function"==typeof e.values&&"function"==typeof e.entries&&"function"==typeof e.constructor&&"FormData"===e[f]}const y="\r\n",m="-".repeat(2),_=Buffer.byteLength(y),g=e=>`${m}${e}${m}${y.repeat(2)}`;function v(e,t,r){let o="";return o+=`${m}${e}\r\n`,o+=`Content-Disposition: form-data; name="${t}"`,h(r)&&(o+=`; filename="${r.name}"\r\n`,o+=`Content-Type: ${r.type||"application/octet-stream"}`),`${o}${y.repeat(2)}`}const w=Symbol("Body internals");class Body{constructor(e,{size:t=0}={}){let r=null;null===e?e=null:p(e)?e=Buffer.from(e.toString()):h(e)||Buffer.isBuffer(e)||(u.types.isAnyArrayBuffer(e)?e=Buffer.from(e):ArrayBuffer.isView(e)?e=Buffer.from(e.buffer,e.byteOffset,e.byteLength):e instanceof i||(b(e)?(r=`NodeFetchFormDataBoundary${c.randomBytes(8).toString("hex")}`,e=i.Readable.from(async function*(e,t){for(const[r,o]of e)yield v(t,r,o),h(o)?yield*o.stream():yield o,yield y;yield g(t)}(e,r))):e=Buffer.from(String(e)))),this[w]={body:e,boundary:r,disturbed:!1,error:null},this.size=t,e instanceof i&&e.on("error",(e=>{const t=e instanceof FetchBaseError?e:new FetchError(`Invalid response body while trying to fetch ${this.url}: ${e.message}`,"system",e);this[w].error=t}))}get body(){return this[w].body}get bodyUsed(){return this[w].disturbed}async arrayBuffer(){const{buffer:e,byteOffset:t,byteLength:r}=await S(this);return e.slice(t,t+r)}async blob(){const e=this.headers&&this.headers.get("content-type")||this[w].body&&this[w].body.type||"",t=await this.buffer();return new l([t],{type:e})}async json(){const e=await S(this);return JSON.parse(e.toString())}async text(){return(await S(this)).toString()}buffer(){return S(this)}}async function S(e){if(e[w].disturbed)throw new TypeError(`body used already for: ${e.url}`);if(e[w].disturbed=!0,e[w].error)throw e[w].error;let{body:t}=e;if(null===t)return Buffer.alloc(0);if(h(t)&&(t=t.stream()),Buffer.isBuffer(t))return t;if(!(t instanceof i))return Buffer.alloc(0);const r=[];let o=0;try{for await(const n of t){if(e.size>0&&o+n.length>e.size){const r=new FetchError(`content size at ${e.url} over limit: ${e.size}`,"max-size");throw t.destroy(r),r}o+=n.length,r.push(n)}}catch(t){throw t instanceof FetchBaseError?t:new FetchError(`Invalid response body while trying to fetch ${e.url}: ${t.message}`,"system",t)}if(!0!==t.readableEnded&&!0!==t._readableState.ended)throw new FetchError(`Premature close of server response while trying to fetch ${e.url}`);try{return r.every((e=>"string"==typeof e))?Buffer.from(r.join("")):Buffer.concat(r,o)}catch(t){throw new FetchError(`Could not create Buffer from response body for ${e.url}: ${t.message}`,"system",t)}}Object.defineProperties(Body.prototype,{body:{enumerable:!0},bodyUsed:{enumerable:!0},arrayBuffer:{enumerable:!0},blob:{enumerable:!0},json:{enumerable:!0},text:{enumerable:!0}});const R=(e,t)=>{let r,o,{body:n}=e;if(e.bodyUsed)throw new Error("cannot clone body after it is used");return n instanceof i&&"function"!=typeof n.getBoundary&&(r=new i.PassThrough({highWaterMark:t}),o=new i.PassThrough({highWaterMark:t}),n.pipe(r),n.pipe(o),e[w].body=r,n=o),n},T=(e,t)=>null===e?null:"string"==typeof e?"text/plain;charset=UTF-8":p(e)?"application/x-www-form-urlencoded;charset=UTF-8":h(e)?e.type||null:Buffer.isBuffer(e)||u.types.isAnyArrayBuffer(e)||ArrayBuffer.isView(e)?null:e&&"function"==typeof e.getBoundary?`multipart/form-data;boundary=${e.getBoundary()}`:b(e)?`multipart/form-data; boundary=${t[w].boundary}`:e instanceof i?null:"text/plain;charset=UTF-8",q=e=>{const{body:t}=e;return null===t?0:h(t)?t.size:Buffer.isBuffer(t)?t.length:t&&"function"==typeof t.getLengthSync?t.hasKnownLength&&t.hasKnownLength()?t.getLengthSync():null:b(t)?function(e,t){let r=0;for(const[o,n]of e)r+=Buffer.byteLength(v(t,o,n)),h(n)?r+=n.size:r+=Buffer.byteLength(String(n)),r+=_;return r+=Buffer.byteLength(g(t)),r}(e[w].boundary):null},P="function"==typeof o.validateHeaderName?o.validateHeaderName:e=>{if(!/^[\^`\-\w!#$%&'*+.|~]+$/.test(e)){const t=new TypeError(`Header name must be a valid HTTP token [${e}]`);throw Object.defineProperty(t,"code",{value:"ERR_INVALID_HTTP_TOKEN"}),t}},E="function"==typeof o.validateHeaderValue?o.validateHeaderValue:(e,t)=>{if(/[^\t\u0020-\u007E\u0080-\u00FF]/.test(t)){const t=new TypeError(`Invalid character in header content ["${e}"]`);throw Object.defineProperty(t,"code",{value:"ERR_INVALID_CHAR"}),t}};class Headers extends URLSearchParams{constructor(e){let t=[];if(e instanceof Headers){const r=e.raw();for(const[e,o]of Object.entries(r))t.push(...o.map((t=>[e,t])))}else if(null==e);else{if("object"!=typeof e||u.types.isBoxedPrimitive(e))throw new TypeError("Failed to construct 'Headers': The provided value is not of type '(sequence> or record)");{const r=e[Symbol.iterator];if(null==r)t.push(...Object.entries(e));else{if("function"!=typeof r)throw new TypeError("Header pairs must be iterable");t=[...e].map((e=>{if("object"!=typeof e||u.types.isBoxedPrimitive(e))throw new TypeError("Each header pair must be an iterable object");return[...e]})).map((e=>{if(2!==e.length)throw new TypeError("Each header pair must be a name/value tuple");return[...e]}))}}}return t=t.length>0?t.map((([e,t])=>(P(e),E(e,String(t)),[String(e).toLowerCase(),String(t)]))):void 0,super(t),new Proxy(this,{get(e,t,r){switch(t){case"append":case"set":return(e,o)=>(P(e),E(e,String(o)),URLSearchParams.prototype[t].call(r,String(e).toLowerCase(),String(o)));case"delete":case"has":case"getAll":return e=>(P(e),URLSearchParams.prototype[t].call(r,String(e).toLowerCase()));case"keys":return()=>(e.sort(),new Set(URLSearchParams.prototype.keys.call(e)).keys());default:return Reflect.get(e,t,r)}}})}get[Symbol.toStringTag](){return this.constructor.name}toString(){return Object.prototype.toString.call(this)}get(e){const t=this.getAll(e);if(0===t.length)return null;let r=t.join(", ");return/^content-encoding$/i.test(e)&&(r=r.toLowerCase()),r}forEach(e){for(const t of this.keys())e(this.get(t),t)}*values(){for(const e of this.keys())yield this.get(e)}*entries(){for(const e of this.keys())yield[e,this.get(e)]}[Symbol.iterator](){return this.entries()}raw(){return[...this.keys()].reduce(((e,t)=>(e[t]=this.getAll(t),e)),{})}[Symbol.for("nodejs.util.inspect.custom")](){return[...this.keys()].reduce(((e,t)=>{const r=this.getAll(t);return e[t]="host"===t?r[0]:r.length>1?r:r[0],e}),{})}}Object.defineProperties(Headers.prototype,["get","entries","forEach","values"].reduce(((e,t)=>(e[t]={enumerable:!0},e)),{}));const C=new Set([301,302,303,307,308]),O=e=>C.has(e),A=Symbol("Response internals");class Response extends Body{constructor(e=null,t={}){super(e,t);const r=t.status||200,o=new Headers(t.headers);if(null!==e&&!o.has("Content-Type")){const t=T(e);t&&o.append("Content-Type",t)}this[A]={url:t.url,status:r,statusText:t.statusText||"",headers:o,counter:t.counter,highWaterMark:t.highWaterMark}}get url(){return this[A].url||""}get status(){return this[A].status}get ok(){return this[A].status>=200&&this[A].status<300}get redirected(){return this[A].counter>0}get statusText(){return this[A].statusText}get headers(){return this[A].headers}get highWaterMark(){return this[A].highWaterMark}clone(){return new Response(R(this,this.highWaterMark),{url:this.url,status:this.status,statusText:this.statusText,headers:this.headers,ok:this.ok,redirected:this.redirected,size:this.size})}static redirect(e,t=302){if(!O(t))throw new RangeError('Failed to execute "redirect" on "response": Invalid status code');return new Response(null,{headers:{location:new URL(e).toString()},status:t})}get[Symbol.toStringTag](){return"Response"}}Object.defineProperties(Response.prototype,{url:{enumerable:!0},status:{enumerable:!0},ok:{enumerable:!0},redirected:{enumerable:!0},statusText:{enumerable:!0},headers:{enumerable:!0},clone:{enumerable:!0}});const j=Symbol("Request internals"),k=e=>"object"==typeof e&&"object"==typeof e[j];class Request extends Body{constructor(e,t={}){let r;k(e)?r=new URL(e.url):(r=new URL(e),e={});let o=t.method||e.method||"GET";if(o=o.toUpperCase(),(null!=t.body||k(e))&&null!==e.body&&("GET"===o||"HEAD"===o))throw new TypeError("Request with GET/HEAD method cannot have body");const n=t.body?t.body:k(e)&&null!==e.body?R(e):null;super(n,{size:t.size||e.size||0});const s=new Headers(t.headers||e.headers||{});if(null!==n&&!s.has("Content-Type")){const e=T(n,this);e&&s.append("Content-Type",e)}let i=k(e)?e.signal:null;if("signal"in t&&(i=t.signal),null!==i&&("object"!=typeof(a=i)||"AbortSignal"!==a[f]))throw new TypeError("Expected signal to be an instanceof AbortSignal");var a;this[j]={method:o,redirect:t.redirect||e.redirect||"follow",headers:s,parsedURL:r,signal:i},this.follow=void 0===t.follow?void 0===e.follow?20:e.follow:t.follow,this.compress=void 0===t.compress?void 0===e.compress||e.compress:t.compress,this.counter=t.counter||e.counter||0,this.agent=t.agent||e.agent,this.highWaterMark=t.highWaterMark||e.highWaterMark||16384,this.insecureHTTPParser=t.insecureHTTPParser||e.insecureHTTPParser||!1}get method(){return this[j].method}get url(){return d.format(this[j].parsedURL)}get headers(){return this[j].headers}get redirect(){return this[j].redirect}get signal(){return this[j].signal}clone(){return new Request(this)}get[Symbol.toStringTag](){return"Request"}}Object.defineProperties(Request.prototype,{method:{enumerable:!0},url:{enumerable:!0},headers:{enumerable:!0},redirect:{enumerable:!0},clone:{enumerable:!0},signal:{enumerable:!0}});class AbortError extends FetchBaseError{constructor(e,t="aborted"){super(e,t)}}const B=new Set(["data:","http:","https:"]);async function W(e,t){return new Promise(((r,u)=>{const l=new Request(e,t),c=(e=>{const{parsedURL:t}=e[j],r=new Headers(e[j].headers);r.has("Accept")||r.set("Accept","*/*");let o=null;if(null===e.body&&/^(post|put)$/i.test(e.method)&&(o="0"),null!==e.body){const t=q(e);"number"!=typeof t||Number.isNaN(t)||(o=String(t))}o&&r.set("Content-Length",o),r.has("User-Agent")||r.set("User-Agent","node-fetch"),e.compress&&!r.has("Accept-Encoding")&&r.set("Accept-Encoding","gzip,deflate,br");let{agent:n}=e;"function"==typeof n&&(n=n(t)),r.has("Connection")||n||r.set("Connection","close");const s=(e=>{if(e.search)return e.search;const t=e.href.length-1,r=e.hash||("#"===e.href[t]?"#":"");return"?"===e.href[t-r.length]?"?":""})(t);return{path:t.pathname+s,pathname:t.pathname,hostname:t.hostname,protocol:t.protocol,port:t.port,hash:t.hash,search:t.search,query:t.query,href:t.href,method:e.method,headers:r[Symbol.for("nodejs.util.inspect.custom")](),insecureHTTPParser:e.insecureHTTPParser,agent:n}})(l);if(!B.has(c.protocol))throw new TypeError(`node-fetch cannot load ${e}. URL scheme "${c.protocol.replace(/:$/,"")}" is not supported.`);if("data:"===c.protocol){const e=a(l.url),t=new Response(e,{headers:{"Content-Type":e.typeFull}});return void r(t)}const d=("https:"===c.protocol?n:o).request,{signal:f}=l;let p=null;const b=()=>{const e=new AbortError("The operation was aborted.");u(e),l.body&&l.body instanceof i.Readable&&l.body.destroy(e),p&&p.body&&p.body.emit("error",e)};if(f&&f.aborted)return void b();const y=()=>{b(),_()},m=d(c);f&&f.addEventListener("abort",y);const _=()=>{m.abort(),f&&f.removeEventListener("abort",y)};m.on("error",(e=>{u(new FetchError(`request to ${l.url} failed, reason: ${e.message}`,"system",e)),_()})),m.on("response",(e=>{m.setTimeout(0);const o=function(e=[]){return new Headers(e.reduce(((e,t,r,o)=>(r%2==0&&e.push(o.slice(r,r+2)),e)),[]).filter((([e,t])=>{try{return P(e),E(e,String(t)),!0}catch{return!1}})))}(e.rawHeaders);if(O(e.statusCode)){const n=o.get("Location"),s=null===n?null:new URL(n,l.url);switch(l.redirect){case"error":return u(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${l.url}`,"no-redirect")),void _();case"manual":if(null!==s)try{o.set("Location",s)}catch(e){u(e)}break;case"follow":{if(null===s)break;if(l.counter>=l.follow)return u(new FetchError(`maximum redirect reached at: ${l.url}`,"max-redirect")),void _();const o={headers:new Headers(l.headers),follow:l.follow,counter:l.counter+1,agent:l.agent,compress:l.compress,method:l.method,body:l.body,signal:l.signal,size:l.size};return 303!==e.statusCode&&l.body&&t.body instanceof i.Readable?(u(new FetchError("Cannot follow redirect with body being a readable stream","unsupported-redirect")),void _()):(303!==e.statusCode&&(301!==e.statusCode&&302!==e.statusCode||"POST"!==l.method)||(o.method="GET",o.body=void 0,o.headers.delete("content-length")),r(W(new Request(s,o))),void _())}}}e.once("end",(()=>{f&&f.removeEventListener("abort",y)}));let n=i.pipeline(e,new i.PassThrough,(e=>{u(e)}));process.version<"v12.10"&&e.on("aborted",y);const a={url:l.url,status:e.statusCode,statusText:e.statusMessage,headers:o,size:l.size,counter:l.counter,highWaterMark:l.highWaterMark},c=o.get("Content-Encoding");if(!l.compress||"HEAD"===l.method||null===c||204===e.statusCode||304===e.statusCode)return p=new Response(n,a),void r(p);const d={flush:s.Z_SYNC_FLUSH,finishFlush:s.Z_SYNC_FLUSH};if("gzip"===c||"x-gzip"===c)return n=i.pipeline(n,s.createGunzip(d),(e=>{u(e)})),p=new Response(n,a),void r(p);if("deflate"!==c&&"x-deflate"!==c){if("br"===c)return n=i.pipeline(n,s.createBrotliDecompress(),(e=>{u(e)})),p=new Response(n,a),void r(p);p=new Response(n,a),r(p)}else{i.pipeline(e,new i.PassThrough,(e=>{u(e)})).once("data",(e=>{n=8==(15&e[0])?i.pipeline(n,s.createInflate(),(e=>{u(e)})):i.pipeline(n,s.createInflateRaw(),(e=>{u(e)})),p=new Response(n,a),r(p)}))}})),((e,{body:t})=>{null===t?e.end():h(t)?t.stream().pipe(e):Buffer.isBuffer(t)?(e.write(t),e.end()):t.pipe(e)})(m,l)}))}t.AbortError=AbortError,t.FetchError=FetchError,t.Headers=Headers,t.Request=Request,t.Response=Response,t.default=W,t.isRedirect=O},902:(e,t,r)=>{"use strict";r.r(t),r.d(t,{ByteLengthQueuingStrategy:()=>ByteLengthQueuingStrategy,CountQueuingStrategy:()=>CountQueuingStrategy,ReadableByteStreamController:()=>ReadableByteStreamController,ReadableStream:()=>ReadableStream,ReadableStreamBYOBReader:()=>ReadableStreamBYOBReader,ReadableStreamBYOBRequest:()=>ReadableStreamBYOBRequest,ReadableStreamDefaultController:()=>ReadableStreamDefaultController,ReadableStreamDefaultReader:()=>ReadableStreamDefaultReader,TransformStream:()=>TransformStream,TransformStreamDefaultController:()=>TransformStreamDefaultController,WritableStream:()=>WritableStream,WritableStreamDefaultController:()=>WritableStreamDefaultController,WritableStreamDefaultWriter:()=>WritableStreamDefaultWriter});const o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?Symbol:e=>`Symbol(${e})`;function n(){}const s="undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:void 0;function i(e){return"object"==typeof e&&null!==e||"function"==typeof e}const a=n,u=Promise,l=Promise.prototype.then,c=Promise.resolve.bind(u),d=Promise.reject.bind(u);function f(e){return new u(e)}function p(e){return c(e)}function h(e){return d(e)}function b(e,t,r){return l.call(e,t,r)}function y(e,t,r){b(b(e,t,r),void 0,a)}function m(e,t){y(e,t)}function _(e,t){y(e,void 0,t)}function g(e,t,r){return b(e,t,r)}function v(e){b(e,void 0,a)}const w=(()=>{const e=s&&s.queueMicrotask;if("function"==typeof e)return e;const t=p(void 0);return e=>b(t,e)})();function S(e,t,r){if("function"!=typeof e)throw new TypeError("Argument is not a function");return Function.prototype.apply.call(e,t,r)}function R(e,t,r){try{return p(S(e,t,r))}catch(e){return h(e)}}class SimpleQueue{constructor(){this._cursor=0,this._size=0,this._front={_elements:[],_next:void 0},this._back=this._front,this._cursor=0,this._size=0}get length(){return this._size}push(e){const t=this._back;let r=t;16383===t._elements.length&&(r={_elements:[],_next:void 0}),t._elements.push(e),r!==t&&(this._back=r,t._next=r),++this._size}shift(){const e=this._front;let t=e;const r=this._cursor;let o=r+1;const n=e._elements,s=n[r];return 16384===o&&(t=e._next,o=0),--this._size,this._cursor=o,e!==t&&(this._front=t),n[r]=void 0,s}forEach(e){let t=this._cursor,r=this._front,o=r._elements;for(;!(t===o.length&&void 0===r._next||t===o.length&&(r=r._next,o=r._elements,t=0,0===o.length));)e(o[t]),++t}peek(){const e=this._front,t=this._cursor;return e._elements[t]}}function T(e,t){e._ownerReadableStream=t,t._reader=e,"readable"===t._state?C(e):"closed"===t._state?function(e){C(e),j(e)}(e):O(e,t._storedError)}function q(e,t){return pr(e._ownerReadableStream,t)}function P(e){"readable"===e._ownerReadableStream._state?A(e,new TypeError("Reader was released and can no longer be used to monitor the stream's closedness")):function(e,t){O(e,t)}(e,new TypeError("Reader was released and can no longer be used to monitor the stream's closedness")),e._ownerReadableStream._reader=void 0,e._ownerReadableStream=void 0}function E(e){return new TypeError("Cannot "+e+" a stream using a released reader")}function C(e){e._closedPromise=f(((t,r)=>{e._closedPromise_resolve=t,e._closedPromise_reject=r}))}function O(e,t){C(e),A(e,t)}function A(e,t){void 0!==e._closedPromise_reject&&(v(e._closedPromise),e._closedPromise_reject(t),e._closedPromise_resolve=void 0,e._closedPromise_reject=void 0)}function j(e){void 0!==e._closedPromise_resolve&&(e._closedPromise_resolve(void 0),e._closedPromise_resolve=void 0,e._closedPromise_reject=void 0)}const k=o("[[AbortSteps]]"),B=o("[[ErrorSteps]]"),W=o("[[CancelSteps]]"),x=o("[[PullSteps]]"),D=Number.isFinite||function(e){return"number"==typeof e&&isFinite(e)},L=Math.trunc||function(e){return e<0?Math.ceil(e):Math.floor(e)};function F(e,t){if(void 0!==e&&("object"!=typeof(r=e)&&"function"!=typeof r))throw new TypeError(`${t} is not an object.`);var r}function z(e,t){if("function"!=typeof e)throw new TypeError(`${t} is not a function.`)}function I(e,t){if(!function(e){return"object"==typeof e&&null!==e||"function"==typeof e}(e))throw new TypeError(`${t} is not an object.`)}function M(e,t,r){if(void 0===e)throw new TypeError(`Parameter ${t} is required in '${r}'.`)}function $(e,t,r){if(void 0===e)throw new TypeError(`${t} is required in '${r}'.`)}function H(e){return Number(e)}function U(e){return 0===e?0:e}function N(e,t){const r=Number.MAX_SAFE_INTEGER;let o=Number(e);if(o=U(o),!D(o))throw new TypeError(`${t} is not a finite number`);if(o=function(e){return U(L(e))}(o),o<0||o>r)throw new TypeError(`${t} is outside the accepted range of 0 to ${r}, inclusive`);return D(o)&&0!==o?o:0}function Q(e,t){if(!dr(e))throw new TypeError(`${t} is not a ReadableStream.`)}function Y(e){return new ReadableStreamDefaultReader(e)}function V(e,t){e._reader._readRequests.push(t)}function G(e,t,r){const o=e._reader._readRequests.shift();r?o._closeSteps():o._chunkSteps(t)}function J(e){return e._reader._readRequests.length}function K(e){const t=e._reader;return void 0!==t&&!!Z(t)}class ReadableStreamDefaultReader{constructor(e){if(M(e,1,"ReadableStreamDefaultReader"),Q(e,"First parameter"),fr(e))throw new TypeError("This stream has already been locked for exclusive reading by another reader");T(this,e),this._readRequests=new SimpleQueue}get closed(){return Z(this)?this._closedPromise:h(ee("closed"))}cancel(e){return Z(this)?void 0===this._ownerReadableStream?h(E("cancel")):q(this,e):h(ee("cancel"))}read(){if(!Z(this))return h(ee("read"));if(void 0===this._ownerReadableStream)return h(E("read from"));let e,t;const r=f(((r,o)=>{e=r,t=o}));return X(this,{_chunkSteps:t=>e({value:t,done:!1}),_closeSteps:()=>e({value:void 0,done:!0}),_errorSteps:e=>t(e)}),r}releaseLock(){if(!Z(this))throw ee("releaseLock");if(void 0!==this._ownerReadableStream){if(this._readRequests.length>0)throw new TypeError("Tried to release a reader lock when that reader has pending read() calls un-settled");P(this)}}}function Z(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_readRequests")&&e instanceof ReadableStreamDefaultReader)}function X(e,t){const r=e._ownerReadableStream;r._disturbed=!0,"closed"===r._state?t._closeSteps():"errored"===r._state?t._errorSteps(r._storedError):r._readableStreamController[x](t)}function ee(e){return new TypeError(`ReadableStreamDefaultReader.prototype.${e} can only be used on a ReadableStreamDefaultReader`)}Object.defineProperties(ReadableStreamDefaultReader.prototype,{cancel:{enumerable:!0},read:{enumerable:!0},releaseLock:{enumerable:!0},closed:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ReadableStreamDefaultReader.prototype,o.toStringTag,{value:"ReadableStreamDefaultReader",configurable:!0});const te=Object.getPrototypeOf(Object.getPrototypeOf((async function*(){})).prototype);class ReadableStreamAsyncIteratorImpl{constructor(e,t){this._ongoingPromise=void 0,this._isFinished=!1,this._reader=e,this._preventCancel=t}next(){const e=()=>this._nextSteps();return this._ongoingPromise=this._ongoingPromise?g(this._ongoingPromise,e,e):e(),this._ongoingPromise}return(e){const t=()=>this._returnSteps(e);return this._ongoingPromise?g(this._ongoingPromise,t,t):t()}_nextSteps(){if(this._isFinished)return Promise.resolve({value:void 0,done:!0});const e=this._reader;if(void 0===e._ownerReadableStream)return h(E("iterate"));let t,r;const o=f(((e,o)=>{t=e,r=o}));return X(e,{_chunkSteps:e=>{this._ongoingPromise=void 0,w((()=>t({value:e,done:!1})))},_closeSteps:()=>{this._ongoingPromise=void 0,this._isFinished=!0,P(e),t({value:void 0,done:!0})},_errorSteps:t=>{this._ongoingPromise=void 0,this._isFinished=!0,P(e),r(t)}}),o}_returnSteps(e){if(this._isFinished)return Promise.resolve({value:e,done:!0});this._isFinished=!0;const t=this._reader;if(void 0===t._ownerReadableStream)return h(E("finish iterating"));if(!this._preventCancel){const r=q(t,e);return P(t),g(r,(()=>({value:e,done:!0})))}return P(t),p({value:e,done:!0})}}const re={next(){return oe(this)?this._asyncIteratorImpl.next():h(ne("next"))},return(e){return oe(this)?this._asyncIteratorImpl.return(e):h(ne("return"))}};function oe(e){if(!i(e))return!1;if(!Object.prototype.hasOwnProperty.call(e,"_asyncIteratorImpl"))return!1;try{return e._asyncIteratorImpl instanceof ReadableStreamAsyncIteratorImpl}catch(e){return!1}}function ne(e){return new TypeError(`ReadableStreamAsyncIterator.${e} can only be used on a ReadableSteamAsyncIterator`)}void 0!==te&&Object.setPrototypeOf(re,te);const se=Number.isNaN||function(e){return e!=e};function ie(e){return e.slice()}function ae(e,t,r,o,n){new Uint8Array(e).set(new Uint8Array(r,o,n),t)}function ue(e,t,r){if(e.slice)return e.slice(t,r);const o=r-t,n=new ArrayBuffer(o);return ae(n,0,e,t,o),n}function le(e){const t=ue(e.buffer,e.byteOffset,e.byteOffset+e.byteLength);return new Uint8Array(t)}function ce(e){const t=e._queue.shift();return e._queueTotalSize-=t.size,e._queueTotalSize<0&&(e._queueTotalSize=0),t.value}function de(e,t,r){if("number"!=typeof(o=r)||se(o)||o<0||r===1/0)throw new RangeError("Size must be a finite, non-NaN, non-negative number.");var o;e._queue.push({value:t,size:r}),e._queueTotalSize+=r}function fe(e){e._queue=new SimpleQueue,e._queueTotalSize=0}class ReadableStreamBYOBRequest{constructor(){throw new TypeError("Illegal constructor")}get view(){if(!he(this))throw De("view");return this._view}respond(e){if(!he(this))throw De("respond");if(M(e,1,"respond"),e=N(e,"First parameter"),void 0===this._associatedReadableByteStreamController)throw new TypeError("This BYOB request has been invalidated");this._view.buffer,Be(this._associatedReadableByteStreamController,e)}respondWithNewView(e){if(!he(this))throw De("respondWithNewView");if(M(e,1,"respondWithNewView"),!ArrayBuffer.isView(e))throw new TypeError("You can only respond with array buffer views");if(void 0===this._associatedReadableByteStreamController)throw new TypeError("This BYOB request has been invalidated");e.buffer,We(this._associatedReadableByteStreamController,e)}}Object.defineProperties(ReadableStreamBYOBRequest.prototype,{respond:{enumerable:!0},respondWithNewView:{enumerable:!0},view:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ReadableStreamBYOBRequest.prototype,o.toStringTag,{value:"ReadableStreamBYOBRequest",configurable:!0});class ReadableByteStreamController{constructor(){throw new TypeError("Illegal constructor")}get byobRequest(){if(!pe(this))throw Le("byobRequest");return je(this)}get desiredSize(){if(!pe(this))throw Le("desiredSize");return ke(this)}close(){if(!pe(this))throw Le("close");if(this._closeRequested)throw new TypeError("The stream has already been closed; do not close it again!");const e=this._controlledReadableByteStream._state;if("readable"!==e)throw new TypeError(`The stream (in ${e} state) is not in the readable state and cannot be closed`);Ce(this)}enqueue(e){if(!pe(this))throw Le("enqueue");if(M(e,1,"enqueue"),!ArrayBuffer.isView(e))throw new TypeError("chunk must be an array buffer view");if(0===e.byteLength)throw new TypeError("chunk must have non-zero byteLength");if(0===e.buffer.byteLength)throw new TypeError("chunk's buffer must have non-zero byteLength");if(this._closeRequested)throw new TypeError("stream is closed or draining");const t=this._controlledReadableByteStream._state;if("readable"!==t)throw new TypeError(`The stream (in ${t} state) is not in the readable state and cannot be enqueued to`);Oe(this,e)}error(e){if(!pe(this))throw Le("error");Ae(this,e)}[W](e){ye(this),fe(this);const t=this._cancelAlgorithm(e);return Ee(this),t}[x](e){const t=this._controlledReadableByteStream;if(this._queueTotalSize>0){const t=this._queue.shift();this._queueTotalSize-=t.byteLength,Se(this);const r=new Uint8Array(t.buffer,t.byteOffset,t.byteLength);return void e._chunkSteps(r)}const r=this._autoAllocateChunkSize;if(void 0!==r){let t;try{t=new ArrayBuffer(r)}catch(t){return void e._errorSteps(t)}const o={buffer:t,bufferByteLength:r,byteOffset:0,byteLength:r,bytesFilled:0,elementSize:1,viewConstructor:Uint8Array,readerType:"default"};this._pendingPullIntos.push(o)}V(t,e),be(this)}}function pe(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_controlledReadableByteStream")&&e instanceof ReadableByteStreamController)}function he(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_associatedReadableByteStreamController")&&e instanceof ReadableStreamBYOBRequest)}function be(e){const t=function(e){const t=e._controlledReadableByteStream;if("readable"!==t._state)return!1;if(e._closeRequested)return!1;if(!e._started)return!1;if(K(t)&&J(t)>0)return!0;if(Me(t)&&Ie(t)>0)return!0;if(ke(e)>0)return!0;return!1}(e);if(!t)return;if(e._pulling)return void(e._pullAgain=!0);e._pulling=!0;y(e._pullAlgorithm(),(()=>{e._pulling=!1,e._pullAgain&&(e._pullAgain=!1,be(e))}),(t=>{Ae(e,t)}))}function ye(e){Re(e),e._pendingPullIntos=new SimpleQueue}function me(e,t){let r=!1;"closed"===e._state&&(r=!0);const o=_e(t);"default"===t.readerType?G(e,o,r):function(e,t,r){const o=e._reader._readIntoRequests.shift();r?o._closeSteps(t):o._chunkSteps(t)}(e,o,r)}function _e(e){const t=e.bytesFilled,r=e.elementSize;return new e.viewConstructor(e.buffer,e.byteOffset,t/r)}function ge(e,t,r,o){e._queue.push({buffer:t,byteOffset:r,byteLength:o}),e._queueTotalSize+=o}function ve(e,t){const r=t.elementSize,o=t.bytesFilled-t.bytesFilled%r,n=Math.min(e._queueTotalSize,t.byteLength-t.bytesFilled),s=t.bytesFilled+n,i=s-s%r;let a=n,u=!1;i>o&&(a=i-t.bytesFilled,u=!0);const l=e._queue;for(;a>0;){const r=l.peek(),o=Math.min(a,r.byteLength),n=t.byteOffset+t.bytesFilled;ae(t.buffer,n,r.buffer,r.byteOffset,o),r.byteLength===o?l.shift():(r.byteOffset+=o,r.byteLength-=o),e._queueTotalSize-=o,we(e,o,t),a-=o}return u}function we(e,t,r){r.bytesFilled+=t}function Se(e){0===e._queueTotalSize&&e._closeRequested?(Ee(e),hr(e._controlledReadableByteStream)):be(e)}function Re(e){null!==e._byobRequest&&(e._byobRequest._associatedReadableByteStreamController=void 0,e._byobRequest._view=null,e._byobRequest=null)}function Te(e){for(;e._pendingPullIntos.length>0;){if(0===e._queueTotalSize)return;const t=e._pendingPullIntos.peek();ve(e,t)&&(Pe(e),me(e._controlledReadableByteStream,t))}}function qe(e,t){const r=e._pendingPullIntos.peek();Re(e);"closed"===e._controlledReadableByteStream._state?function(e,t){const r=e._controlledReadableByteStream;if(Me(r))for(;Ie(r)>0;)me(r,Pe(e))}(e):function(e,t,r){if(we(0,t,r),r.bytesFilled0){const t=r.byteOffset+r.bytesFilled,n=ue(r.buffer,t-o,t);ge(e,n,0,n.byteLength)}r.bytesFilled-=o,me(e._controlledReadableByteStream,r),Te(e)}(e,t,r),be(e)}function Pe(e){return e._pendingPullIntos.shift()}function Ee(e){e._pullAlgorithm=void 0,e._cancelAlgorithm=void 0}function Ce(e){const t=e._controlledReadableByteStream;if(!e._closeRequested&&"readable"===t._state)if(e._queueTotalSize>0)e._closeRequested=!0;else{if(e._pendingPullIntos.length>0){if(e._pendingPullIntos.peek().bytesFilled>0){const t=new TypeError("Insufficient bytes to fill elements in the given buffer");throw Ae(e,t),t}}Ee(e),hr(t)}}function Oe(e,t){const r=e._controlledReadableByteStream;if(e._closeRequested||"readable"!==r._state)return;const o=t.buffer,n=t.byteOffset,s=t.byteLength,i=o;if(e._pendingPullIntos.length>0){const t=e._pendingPullIntos.peek();t.buffer,0,t.buffer=t.buffer}if(Re(e),K(r))if(0===J(r))ge(e,i,n,s);else{G(r,new Uint8Array(i,n,s),!1)}else Me(r)?(ge(e,i,n,s),Te(e)):ge(e,i,n,s);be(e)}function Ae(e,t){const r=e._controlledReadableByteStream;"readable"===r._state&&(ye(e),fe(e),Ee(e),br(r,t))}function je(e){if(null===e._byobRequest&&e._pendingPullIntos.length>0){const t=e._pendingPullIntos.peek(),r=new Uint8Array(t.buffer,t.byteOffset+t.bytesFilled,t.byteLength-t.bytesFilled),o=Object.create(ReadableStreamBYOBRequest.prototype);!function(e,t,r){e._associatedReadableByteStreamController=t,e._view=r}(o,e,r),e._byobRequest=o}return e._byobRequest}function ke(e){const t=e._controlledReadableByteStream._state;return"errored"===t?null:"closed"===t?0:e._strategyHWM-e._queueTotalSize}function Be(e,t){const r=e._pendingPullIntos.peek();if("closed"===e._controlledReadableByteStream._state){if(0!==t)throw new TypeError("bytesWritten must be 0 when calling respond() on a closed stream")}else{if(0===t)throw new TypeError("bytesWritten must be greater than 0 when calling respond() on a readable stream");if(r.bytesFilled+t>r.byteLength)throw new RangeError("bytesWritten out of range")}r.buffer=r.buffer,qe(e,t)}function We(e,t){const r=e._pendingPullIntos.peek();if("closed"===e._controlledReadableByteStream._state){if(0!==t.byteLength)throw new TypeError("The view's length must be 0 when calling respondWithNewView() on a closed stream")}else if(0===t.byteLength)throw new TypeError("The view's length must be greater than 0 when calling respondWithNewView() on a readable stream");if(r.byteOffset+r.bytesFilled!==t.byteOffset)throw new RangeError("The region specified by view does not match byobRequest");if(r.bufferByteLength!==t.buffer.byteLength)throw new RangeError("The buffer of view has different capacity than byobRequest");if(r.bytesFilled+t.byteLength>r.byteLength)throw new RangeError("The region specified by view is larger than byobRequest");r.buffer=t.buffer,qe(e,t.byteLength)}function xe(e,t,r,o,n,s,i){t._controlledReadableByteStream=e,t._pullAgain=!1,t._pulling=!1,t._byobRequest=null,t._queue=t._queueTotalSize=void 0,fe(t),t._closeRequested=!1,t._started=!1,t._strategyHWM=s,t._pullAlgorithm=o,t._cancelAlgorithm=n,t._autoAllocateChunkSize=i,t._pendingPullIntos=new SimpleQueue,e._readableStreamController=t;y(p(r()),(()=>{t._started=!0,be(t)}),(e=>{Ae(t,e)}))}function De(e){return new TypeError(`ReadableStreamBYOBRequest.prototype.${e} can only be used on a ReadableStreamBYOBRequest`)}function Le(e){return new TypeError(`ReadableByteStreamController.prototype.${e} can only be used on a ReadableByteStreamController`)}function Fe(e){return new ReadableStreamBYOBReader(e)}function ze(e,t){e._reader._readIntoRequests.push(t)}function Ie(e){return e._reader._readIntoRequests.length}function Me(e){const t=e._reader;return void 0!==t&&!!$e(t)}Object.defineProperties(ReadableByteStreamController.prototype,{close:{enumerable:!0},enqueue:{enumerable:!0},error:{enumerable:!0},byobRequest:{enumerable:!0},desiredSize:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ReadableByteStreamController.prototype,o.toStringTag,{value:"ReadableByteStreamController",configurable:!0});class ReadableStreamBYOBReader{constructor(e){if(M(e,1,"ReadableStreamBYOBReader"),Q(e,"First parameter"),fr(e))throw new TypeError("This stream has already been locked for exclusive reading by another reader");if(!pe(e._readableStreamController))throw new TypeError("Cannot construct a ReadableStreamBYOBReader for a stream not constructed with a byte source");T(this,e),this._readIntoRequests=new SimpleQueue}get closed(){return $e(this)?this._closedPromise:h(Ue("closed"))}cancel(e){return $e(this)?void 0===this._ownerReadableStream?h(E("cancel")):q(this,e):h(Ue("cancel"))}read(e){if(!$e(this))return h(Ue("read"));if(!ArrayBuffer.isView(e))return h(new TypeError("view must be an array buffer view"));if(0===e.byteLength)return h(new TypeError("view must have non-zero byteLength"));if(0===e.buffer.byteLength)return h(new TypeError("view's buffer must have non-zero byteLength"));if(e.buffer,void 0===this._ownerReadableStream)return h(E("read from"));let t,r;const o=f(((e,o)=>{t=e,r=o}));return He(this,e,{_chunkSteps:e=>t({value:e,done:!1}),_closeSteps:e=>t({value:e,done:!0}),_errorSteps:e=>r(e)}),o}releaseLock(){if(!$e(this))throw Ue("releaseLock");if(void 0!==this._ownerReadableStream){if(this._readIntoRequests.length>0)throw new TypeError("Tried to release a reader lock when that reader has pending read() calls un-settled");P(this)}}}function $e(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_readIntoRequests")&&e instanceof ReadableStreamBYOBReader)}function He(e,t,r){const o=e._ownerReadableStream;o._disturbed=!0,"errored"===o._state?r._errorSteps(o._storedError):function(e,t,r){const o=e._controlledReadableByteStream;let n=1;t.constructor!==DataView&&(n=t.constructor.BYTES_PER_ELEMENT);const s=t.constructor,i=t.buffer,a={buffer:i,bufferByteLength:i.byteLength,byteOffset:t.byteOffset,byteLength:t.byteLength,bytesFilled:0,elementSize:n,viewConstructor:s,readerType:"byob"};if(e._pendingPullIntos.length>0)return e._pendingPullIntos.push(a),void ze(o,r);if("closed"!==o._state){if(e._queueTotalSize>0){if(ve(e,a)){const t=_e(a);return Se(e),void r._chunkSteps(t)}if(e._closeRequested){const t=new TypeError("Insufficient bytes to fill elements in the given buffer");return Ae(e,t),void r._errorSteps(t)}}e._pendingPullIntos.push(a),ze(o,r),be(e)}else{const e=new s(a.buffer,a.byteOffset,0);r._closeSteps(e)}}(o._readableStreamController,t,r)}function Ue(e){return new TypeError(`ReadableStreamBYOBReader.prototype.${e} can only be used on a ReadableStreamBYOBReader`)}function Ne(e,t){const{highWaterMark:r}=e;if(void 0===r)return t;if(se(r)||r<0)throw new RangeError("Invalid highWaterMark");return r}function Qe(e){const{size:t}=e;return t||(()=>1)}function Ye(e,t){F(e,t);const r=null==e?void 0:e.highWaterMark,o=null==e?void 0:e.size;return{highWaterMark:void 0===r?void 0:H(r),size:void 0===o?void 0:Ve(o,`${t} has member 'size' that`)}}function Ve(e,t){return z(e,t),t=>H(e(t))}function Ge(e,t,r){return z(e,r),r=>R(e,t,[r])}function Je(e,t,r){return z(e,r),()=>R(e,t,[])}function Ke(e,t,r){return z(e,r),r=>S(e,t,[r])}function Ze(e,t,r){return z(e,r),(r,o)=>R(e,t,[r,o])}function Xe(e,t){if(!ot(e))throw new TypeError(`${t} is not a WritableStream.`)}Object.defineProperties(ReadableStreamBYOBReader.prototype,{cancel:{enumerable:!0},read:{enumerable:!0},releaseLock:{enumerable:!0},closed:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ReadableStreamBYOBReader.prototype,o.toStringTag,{value:"ReadableStreamBYOBReader",configurable:!0});const et="function"==typeof AbortController;class WritableStream{constructor(e={},t={}){void 0===e?e=null:I(e,"First parameter");const r=Ye(t,"Second parameter"),o=function(e,t){F(e,t);const r=null==e?void 0:e.abort,o=null==e?void 0:e.close,n=null==e?void 0:e.start,s=null==e?void 0:e.type,i=null==e?void 0:e.write;return{abort:void 0===r?void 0:Ge(r,e,`${t} has member 'abort' that`),close:void 0===o?void 0:Je(o,e,`${t} has member 'close' that`),start:void 0===n?void 0:Ke(n,e,`${t} has member 'start' that`),write:void 0===i?void 0:Ze(i,e,`${t} has member 'write' that`),type:s}}(e,"First parameter");rt(this);if(void 0!==o.type)throw new RangeError("Invalid type is specified");const n=Qe(r);!function(e,t,r,o){const n=Object.create(WritableStreamDefaultController.prototype);let s=()=>{},i=()=>p(void 0),a=()=>p(void 0),u=()=>p(void 0);void 0!==t.start&&(s=()=>t.start(n));void 0!==t.write&&(i=e=>t.write(e,n));void 0!==t.close&&(a=()=>t.close());void 0!==t.abort&&(u=e=>t.abort(e));wt(e,n,s,i,a,u,r,o)}(this,o,Ne(r,1),n)}get locked(){if(!ot(this))throw Ct("locked");return nt(this)}abort(e){return ot(this)?nt(this)?h(new TypeError("Cannot abort a stream that already has a writer")):st(this,e):h(Ct("abort"))}close(){return ot(this)?nt(this)?h(new TypeError("Cannot close a stream that already has a writer")):ct(this)?h(new TypeError("Cannot close an already-closing stream")):it(this):h(Ct("close"))}getWriter(){if(!ot(this))throw Ct("getWriter");return tt(this)}}function tt(e){return new WritableStreamDefaultWriter(e)}function rt(e){e._state="writable",e._storedError=void 0,e._writer=void 0,e._writableStreamController=void 0,e._writeRequests=new SimpleQueue,e._inFlightWriteRequest=void 0,e._closeRequest=void 0,e._inFlightCloseRequest=void 0,e._pendingAbortRequest=void 0,e._backpressure=!1}function ot(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_writableStreamController")&&e instanceof WritableStream)}function nt(e){return void 0!==e._writer}function st(e,t){var r;if("closed"===e._state||"errored"===e._state)return p(void 0);e._writableStreamController._abortReason=t,null===(r=e._writableStreamController._abortController)||void 0===r||r.abort();const o=e._state;if("closed"===o||"errored"===o)return p(void 0);if(void 0!==e._pendingAbortRequest)return e._pendingAbortRequest._promise;let n=!1;"erroring"===o&&(n=!0,t=void 0);const s=f(((r,o)=>{e._pendingAbortRequest={_promise:void 0,_resolve:r,_reject:o,_reason:t,_wasAlreadyErroring:n}}));return e._pendingAbortRequest._promise=s,n||ut(e,t),s}function it(e){const t=e._state;if("closed"===t||"errored"===t)return h(new TypeError(`The stream (in ${t} state) is not in the writable state and cannot be closed`));const r=f(((t,r)=>{const o={_resolve:t,_reject:r};e._closeRequest=o})),o=e._writer;var n;return void 0!==o&&e._backpressure&&"writable"===t&&It(o),de(n=e._writableStreamController,gt,0),Tt(n),r}function at(e,t){"writable"!==e._state?lt(e):ut(e,t)}function ut(e,t){const r=e._writableStreamController;e._state="erroring",e._storedError=t;const o=e._writer;void 0!==o&&yt(o,t),!function(e){if(void 0===e._inFlightWriteRequest&&void 0===e._inFlightCloseRequest)return!1;return!0}(e)&&r._started&<(e)}function lt(e){e._state="errored",e._writableStreamController[B]();const t=e._storedError;if(e._writeRequests.forEach((e=>{e._reject(t)})),e._writeRequests=new SimpleQueue,void 0===e._pendingAbortRequest)return void dt(e);const r=e._pendingAbortRequest;if(e._pendingAbortRequest=void 0,r._wasAlreadyErroring)return r._reject(t),void dt(e);y(e._writableStreamController[k](r._reason),(()=>{r._resolve(),dt(e)}),(t=>{r._reject(t),dt(e)}))}function ct(e){return void 0!==e._closeRequest||void 0!==e._inFlightCloseRequest}function dt(e){void 0!==e._closeRequest&&(e._closeRequest._reject(e._storedError),e._closeRequest=void 0);const t=e._writer;void 0!==t&&Wt(t,e._storedError)}function ft(e,t){const r=e._writer;void 0!==r&&t!==e._backpressure&&(t?function(e){Dt(e)}(r):It(r)),e._backpressure=t}Object.defineProperties(WritableStream.prototype,{abort:{enumerable:!0},close:{enumerable:!0},getWriter:{enumerable:!0},locked:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(WritableStream.prototype,o.toStringTag,{value:"WritableStream",configurable:!0});class WritableStreamDefaultWriter{constructor(e){if(M(e,1,"WritableStreamDefaultWriter"),Xe(e,"First parameter"),nt(e))throw new TypeError("This stream has already been locked for exclusive writing by another writer");this._ownerWritableStream=e,e._writer=this;const t=e._state;if("writable"===t)!ct(e)&&e._backpressure?Dt(this):Ft(this),kt(this);else if("erroring"===t)Lt(this,e._storedError),kt(this);else if("closed"===t)Ft(this),kt(r=this),xt(r);else{const t=e._storedError;Lt(this,t),Bt(this,t)}var r}get closed(){return pt(this)?this._closedPromise:h(At("closed"))}get desiredSize(){if(!pt(this))throw At("desiredSize");if(void 0===this._ownerWritableStream)throw jt("desiredSize");return function(e){const t=e._ownerWritableStream,r=t._state;if("errored"===r||"erroring"===r)return null;if("closed"===r)return 0;return Rt(t._writableStreamController)}(this)}get ready(){return pt(this)?this._readyPromise:h(At("ready"))}abort(e){return pt(this)?void 0===this._ownerWritableStream?h(jt("abort")):function(e,t){return st(e._ownerWritableStream,t)}(this,e):h(At("abort"))}close(){if(!pt(this))return h(At("close"));const e=this._ownerWritableStream;return void 0===e?h(jt("close")):ct(e)?h(new TypeError("Cannot close an already-closing stream")):ht(this)}releaseLock(){if(!pt(this))throw At("releaseLock");void 0!==this._ownerWritableStream&&mt(this)}write(e){return pt(this)?void 0===this._ownerWritableStream?h(jt("write to")):_t(this,e):h(At("write"))}}function pt(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_ownerWritableStream")&&e instanceof WritableStreamDefaultWriter)}function ht(e){return it(e._ownerWritableStream)}function bt(e,t){"pending"===e._closedPromiseState?Wt(e,t):function(e,t){Bt(e,t)}(e,t)}function yt(e,t){"pending"===e._readyPromiseState?zt(e,t):function(e,t){Lt(e,t)}(e,t)}function mt(e){const t=e._ownerWritableStream,r=new TypeError("Writer was released and can no longer be used to monitor the stream's closedness");yt(e,r),bt(e,r),t._writer=void 0,e._ownerWritableStream=void 0}function _t(e,t){const r=e._ownerWritableStream,o=r._writableStreamController,n=function(e,t){try{return e._strategySizeAlgorithm(t)}catch(t){return qt(e,t),1}}(o,t);if(r!==e._ownerWritableStream)return h(jt("write to"));const s=r._state;if("errored"===s)return h(r._storedError);if(ct(r)||"closed"===s)return h(new TypeError("The stream is closing or closed and cannot be written to"));if("erroring"===s)return h(r._storedError);const i=function(e){return f(((t,r)=>{const o={_resolve:t,_reject:r};e._writeRequests.push(o)}))}(r);return function(e,t,r){try{de(e,t,r)}catch(t){return void qt(e,t)}const o=e._controlledWritableStream;if(!ct(o)&&"writable"===o._state){ft(o,Pt(e))}Tt(e)}(o,t,n),i}Object.defineProperties(WritableStreamDefaultWriter.prototype,{abort:{enumerable:!0},close:{enumerable:!0},releaseLock:{enumerable:!0},write:{enumerable:!0},closed:{enumerable:!0},desiredSize:{enumerable:!0},ready:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(WritableStreamDefaultWriter.prototype,o.toStringTag,{value:"WritableStreamDefaultWriter",configurable:!0});const gt={};class WritableStreamDefaultController{constructor(){throw new TypeError("Illegal constructor")}get abortReason(){if(!vt(this))throw Ot("abortReason");return this._abortReason}get signal(){if(!vt(this))throw Ot("signal");if(void 0===this._abortController)throw new TypeError("WritableStreamDefaultController.prototype.signal is not supported");return this._abortController.signal}error(e){if(!vt(this))throw Ot("error");"writable"===this._controlledWritableStream._state&&Et(this,e)}[k](e){const t=this._abortAlgorithm(e);return St(this),t}[B](){fe(this)}}function vt(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_controlledWritableStream")&&e instanceof WritableStreamDefaultController)}function wt(e,t,r,o,n,s,i,a){t._controlledWritableStream=e,e._writableStreamController=t,t._queue=void 0,t._queueTotalSize=void 0,fe(t),t._abortReason=void 0,t._abortController=function(){if(et)return new AbortController}(),t._started=!1,t._strategySizeAlgorithm=a,t._strategyHWM=i,t._writeAlgorithm=o,t._closeAlgorithm=n,t._abortAlgorithm=s;const u=Pt(t);ft(e,u);y(p(r()),(()=>{t._started=!0,Tt(t)}),(r=>{t._started=!0,at(e,r)}))}function St(e){e._writeAlgorithm=void 0,e._closeAlgorithm=void 0,e._abortAlgorithm=void 0,e._strategySizeAlgorithm=void 0}function Rt(e){return e._strategyHWM-e._queueTotalSize}function Tt(e){const t=e._controlledWritableStream;if(!e._started)return;if(void 0!==t._inFlightWriteRequest)return;if("erroring"===t._state)return void lt(t);if(0===e._queue.length)return;const r=e._queue.peek().value;r===gt?function(e){const t=e._controlledWritableStream;(function(e){e._inFlightCloseRequest=e._closeRequest,e._closeRequest=void 0})(t),ce(e);const r=e._closeAlgorithm();St(e),y(r,(()=>{!function(e){e._inFlightCloseRequest._resolve(void 0),e._inFlightCloseRequest=void 0,"erroring"===e._state&&(e._storedError=void 0,void 0!==e._pendingAbortRequest&&(e._pendingAbortRequest._resolve(),e._pendingAbortRequest=void 0)),e._state="closed";const t=e._writer;void 0!==t&&xt(t)}(t)}),(e=>{!function(e,t){e._inFlightCloseRequest._reject(t),e._inFlightCloseRequest=void 0,void 0!==e._pendingAbortRequest&&(e._pendingAbortRequest._reject(t),e._pendingAbortRequest=void 0),at(e,t)}(t,e)}))}(e):function(e,t){const r=e._controlledWritableStream;!function(e){e._inFlightWriteRequest=e._writeRequests.shift()}(r);y(e._writeAlgorithm(t),(()=>{!function(e){e._inFlightWriteRequest._resolve(void 0),e._inFlightWriteRequest=void 0}(r);const t=r._state;if(ce(e),!ct(r)&&"writable"===t){const t=Pt(e);ft(r,t)}Tt(e)}),(t=>{"writable"===r._state&&St(e),function(e,t){e._inFlightWriteRequest._reject(t),e._inFlightWriteRequest=void 0,at(e,t)}(r,t)}))}(e,r)}function qt(e,t){"writable"===e._controlledWritableStream._state&&Et(e,t)}function Pt(e){return Rt(e)<=0}function Et(e,t){const r=e._controlledWritableStream;St(e),ut(r,t)}function Ct(e){return new TypeError(`WritableStream.prototype.${e} can only be used on a WritableStream`)}function Ot(e){return new TypeError(`WritableStreamDefaultController.prototype.${e} can only be used on a WritableStreamDefaultController`)}function At(e){return new TypeError(`WritableStreamDefaultWriter.prototype.${e} can only be used on a WritableStreamDefaultWriter`)}function jt(e){return new TypeError("Cannot "+e+" a stream using a released writer")}function kt(e){e._closedPromise=f(((t,r)=>{e._closedPromise_resolve=t,e._closedPromise_reject=r,e._closedPromiseState="pending"}))}function Bt(e,t){kt(e),Wt(e,t)}function Wt(e,t){void 0!==e._closedPromise_reject&&(v(e._closedPromise),e._closedPromise_reject(t),e._closedPromise_resolve=void 0,e._closedPromise_reject=void 0,e._closedPromiseState="rejected")}function xt(e){void 0!==e._closedPromise_resolve&&(e._closedPromise_resolve(void 0),e._closedPromise_resolve=void 0,e._closedPromise_reject=void 0,e._closedPromiseState="resolved")}function Dt(e){e._readyPromise=f(((t,r)=>{e._readyPromise_resolve=t,e._readyPromise_reject=r})),e._readyPromiseState="pending"}function Lt(e,t){Dt(e),zt(e,t)}function Ft(e){Dt(e),It(e)}function zt(e,t){void 0!==e._readyPromise_reject&&(v(e._readyPromise),e._readyPromise_reject(t),e._readyPromise_resolve=void 0,e._readyPromise_reject=void 0,e._readyPromiseState="rejected")}function It(e){void 0!==e._readyPromise_resolve&&(e._readyPromise_resolve(void 0),e._readyPromise_resolve=void 0,e._readyPromise_reject=void 0,e._readyPromiseState="fulfilled")}Object.defineProperties(WritableStreamDefaultController.prototype,{error:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(WritableStreamDefaultController.prototype,o.toStringTag,{value:"WritableStreamDefaultController",configurable:!0});const Mt="undefined"!=typeof DOMException?DOMException:void 0;const $t=function(e){if("function"!=typeof e&&"object"!=typeof e)return!1;try{return new e,!0}catch(e){return!1}}(Mt)?Mt:function(){const e=function(e,t){this.message=e||"",this.name=t||"Error",Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)};return e.prototype=Object.create(Error.prototype),Object.defineProperty(e.prototype,"constructor",{value:e,writable:!0,configurable:!0}),e}();function Ht(e,t,r,o,s,i){const a=Y(e),u=tt(t);e._disturbed=!0;let l=!1,c=p(void 0);return f(((d,g)=>{let w;if(void 0!==i){if(w=()=>{const r=new $t("Aborted","AbortError"),n=[];o||n.push((()=>"writable"===t._state?st(t,r):p(void 0))),s||n.push((()=>"readable"===e._state?pr(e,r):p(void 0))),C((()=>Promise.all(n.map((e=>e())))),!0,r)},i.aborted)return void w();i.addEventListener("abort",w)}var S,R,T;if(E(e,a._closedPromise,(e=>{o?O(!0,e):C((()=>st(t,e)),!0,e)})),E(t,u._closedPromise,(t=>{s?O(!0,t):C((()=>pr(e,t)),!0,t)})),S=e,R=a._closedPromise,T=()=>{r?O():C((()=>function(e){const t=e._ownerWritableStream,r=t._state;return ct(t)||"closed"===r?p(void 0):"errored"===r?h(t._storedError):ht(e)}(u)))},"closed"===S._state?T():m(R,T),ct(t)||"closed"===t._state){const t=new TypeError("the destination writable stream closed before all data could be piped to it");s?O(!0,t):C((()=>pr(e,t)),!0,t)}function q(){const e=c;return b(c,(()=>e!==c?q():void 0))}function E(e,t,r){"errored"===e._state?r(e._storedError):_(t,r)}function C(e,r,o){function n(){y(e(),(()=>A(r,o)),(e=>A(!0,e)))}l||(l=!0,"writable"!==t._state||ct(t)?n():m(q(),n))}function O(e,r){l||(l=!0,"writable"!==t._state||ct(t)?A(e,r):m(q(),(()=>A(e,r))))}function A(e,t){mt(u),P(a),void 0!==i&&i.removeEventListener("abort",w),e?g(t):d(void 0)}v(f(((e,t)=>{!function r(o){o?e():b(l?p(!0):b(u._readyPromise,(()=>f(((e,t)=>{X(a,{_chunkSteps:t=>{c=b(_t(u,t),void 0,n),e(!1)},_closeSteps:()=>e(!0),_errorSteps:t})})))),r,t)}(!1)})))}))}class ReadableStreamDefaultController{constructor(){throw new TypeError("Illegal constructor")}get desiredSize(){if(!Ut(this))throw er("desiredSize");return Kt(this)}close(){if(!Ut(this))throw er("close");if(!Zt(this))throw new TypeError("The stream is not in a state that permits close");Vt(this)}enqueue(e){if(!Ut(this))throw er("enqueue");if(!Zt(this))throw new TypeError("The stream is not in a state that permits enqueue");return Gt(this,e)}error(e){if(!Ut(this))throw er("error");Jt(this,e)}[W](e){fe(this);const t=this._cancelAlgorithm(e);return Yt(this),t}[x](e){const t=this._controlledReadableStream;if(this._queue.length>0){const r=ce(this);this._closeRequested&&0===this._queue.length?(Yt(this),hr(t)):Nt(this),e._chunkSteps(r)}else V(t,e),Nt(this)}}function Ut(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_controlledReadableStream")&&e instanceof ReadableStreamDefaultController)}function Nt(e){if(!Qt(e))return;if(e._pulling)return void(e._pullAgain=!0);e._pulling=!0;y(e._pullAlgorithm(),(()=>{e._pulling=!1,e._pullAgain&&(e._pullAgain=!1,Nt(e))}),(t=>{Jt(e,t)}))}function Qt(e){const t=e._controlledReadableStream;if(!Zt(e))return!1;if(!e._started)return!1;if(fr(t)&&J(t)>0)return!0;return Kt(e)>0}function Yt(e){e._pullAlgorithm=void 0,e._cancelAlgorithm=void 0,e._strategySizeAlgorithm=void 0}function Vt(e){if(!Zt(e))return;const t=e._controlledReadableStream;e._closeRequested=!0,0===e._queue.length&&(Yt(e),hr(t))}function Gt(e,t){if(!Zt(e))return;const r=e._controlledReadableStream;if(fr(r)&&J(r)>0)G(r,t,!1);else{let r;try{r=e._strategySizeAlgorithm(t)}catch(t){throw Jt(e,t),t}try{de(e,t,r)}catch(t){throw Jt(e,t),t}}Nt(e)}function Jt(e,t){const r=e._controlledReadableStream;"readable"===r._state&&(fe(e),Yt(e),br(r,t))}function Kt(e){const t=e._controlledReadableStream._state;return"errored"===t?null:"closed"===t?0:e._strategyHWM-e._queueTotalSize}function Zt(e){const t=e._controlledReadableStream._state;return!e._closeRequested&&"readable"===t}function Xt(e,t,r,o,n,s,i){t._controlledReadableStream=e,t._queue=void 0,t._queueTotalSize=void 0,fe(t),t._started=!1,t._closeRequested=!1,t._pullAgain=!1,t._pulling=!1,t._strategySizeAlgorithm=i,t._strategyHWM=s,t._pullAlgorithm=o,t._cancelAlgorithm=n,e._readableStreamController=t;y(p(r()),(()=>{t._started=!0,Nt(t)}),(e=>{Jt(t,e)}))}function er(e){return new TypeError(`ReadableStreamDefaultController.prototype.${e} can only be used on a ReadableStreamDefaultController`)}function tr(e,t){return pe(e._readableStreamController)?function(e){let t,r,o,n,s,i=Y(e),a=!1,u=!1,l=!1;const c=f((e=>{s=e}));function d(e){_(e._closedPromise,(t=>{e===i&&(Ae(o._readableStreamController,t),Ae(n._readableStreamController,t),u&&l||s(void 0))}))}function h(){$e(i)&&(P(i),i=Y(e),d(i));X(i,{_chunkSteps:t=>{w((()=>{a=!1;const r=t;let i=t;if(!u&&!l)try{i=le(t)}catch(t){return Ae(o._readableStreamController,t),Ae(n._readableStreamController,t),void s(pr(e,t))}u||Oe(o._readableStreamController,r),l||Oe(n._readableStreamController,i)}))},_closeSteps:()=>{a=!1,u||Ce(o._readableStreamController),l||Ce(n._readableStreamController),o._readableStreamController._pendingPullIntos.length>0&&Be(o._readableStreamController,0),n._readableStreamController._pendingPullIntos.length>0&&Be(n._readableStreamController,0),u&&l||s(void 0)},_errorSteps:()=>{a=!1}})}function b(t,r){Z(i)&&(P(i),i=Fe(e),d(i));const c=r?n:o,f=r?o:n;He(i,t,{_chunkSteps:t=>{w((()=>{a=!1;const o=r?l:u;if(r?u:l)o||We(c._readableStreamController,t);else{let r;try{r=le(t)}catch(t){return Ae(c._readableStreamController,t),Ae(f._readableStreamController,t),void s(pr(e,t))}o||We(c._readableStreamController,t),Oe(f._readableStreamController,r)}}))},_closeSteps:e=>{a=!1;const t=r?l:u,o=r?u:l;t||Ce(c._readableStreamController),o||Ce(f._readableStreamController),void 0!==e&&(t||We(c._readableStreamController,e),!o&&f._readableStreamController._pendingPullIntos.length>0&&Be(f._readableStreamController,0)),t&&o||s(void 0)},_errorSteps:()=>{a=!1}})}function y(){if(a)return p(void 0);a=!0;const e=je(o._readableStreamController);return null===e?h():b(e._view,!1),p(void 0)}function m(){if(a)return p(void 0);a=!0;const e=je(n._readableStreamController);return null===e?h():b(e._view,!0),p(void 0)}function g(o){if(u=!0,t=o,l){const o=ie([t,r]),n=pr(e,o);s(n)}return c}function v(o){if(l=!0,r=o,u){const o=ie([t,r]),n=pr(e,o);s(n)}return c}function S(){}return o=lr(S,y,g),n=lr(S,m,v),d(i),[o,n]}(e):function(e,t){const r=Y(e);let o,n,s,i,a,u=!1,l=!1,c=!1;const d=f((e=>{a=e}));function h(){if(u)return p(void 0);u=!0;return X(r,{_chunkSteps:e=>{w((()=>{u=!1;const t=e,r=e;l||Gt(s._readableStreamController,t),c||Gt(i._readableStreamController,r)}))},_closeSteps:()=>{u=!1,l||Vt(s._readableStreamController),c||Vt(i._readableStreamController),l&&c||a(void 0)},_errorSteps:()=>{u=!1}}),p(void 0)}function b(t){if(l=!0,o=t,c){const t=ie([o,n]),r=pr(e,t);a(r)}return d}function y(t){if(c=!0,n=t,l){const t=ie([o,n]),r=pr(e,t);a(r)}return d}function m(){}return s=ur(m,h,b),i=ur(m,h,y),_(r._closedPromise,(e=>{Jt(s._readableStreamController,e),Jt(i._readableStreamController,e),l&&c||a(void 0)})),[s,i]}(e)}function rr(e,t,r){return z(e,r),r=>R(e,t,[r])}function or(e,t,r){return z(e,r),r=>R(e,t,[r])}function nr(e,t,r){return z(e,r),r=>S(e,t,[r])}function sr(e,t){if("bytes"!==(e=`${e}`))throw new TypeError(`${t} '${e}' is not a valid enumeration value for ReadableStreamType`);return e}function ir(e,t){if("byob"!==(e=`${e}`))throw new TypeError(`${t} '${e}' is not a valid enumeration value for ReadableStreamReaderMode`);return e}function ar(e,t){F(e,t);const r=null==e?void 0:e.preventAbort,o=null==e?void 0:e.preventCancel,n=null==e?void 0:e.preventClose,s=null==e?void 0:e.signal;return void 0!==s&&function(e,t){if(!function(e){if("object"!=typeof e||null===e)return!1;try{return"boolean"==typeof e.aborted}catch(e){return!1}}(e))throw new TypeError(`${t} is not an AbortSignal.`)}(s,`${t} has member 'signal' that`),{preventAbort:Boolean(r),preventCancel:Boolean(o),preventClose:Boolean(n),signal:s}}Object.defineProperties(ReadableStreamDefaultController.prototype,{close:{enumerable:!0},enqueue:{enumerable:!0},error:{enumerable:!0},desiredSize:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ReadableStreamDefaultController.prototype,o.toStringTag,{value:"ReadableStreamDefaultController",configurable:!0});class ReadableStream{constructor(e={},t={}){void 0===e?e=null:I(e,"First parameter");const r=Ye(t,"Second parameter"),o=function(e,t){F(e,t);const r=e,o=null==r?void 0:r.autoAllocateChunkSize,n=null==r?void 0:r.cancel,s=null==r?void 0:r.pull,i=null==r?void 0:r.start,a=null==r?void 0:r.type;return{autoAllocateChunkSize:void 0===o?void 0:N(o,`${t} has member 'autoAllocateChunkSize' that`),cancel:void 0===n?void 0:rr(n,r,`${t} has member 'cancel' that`),pull:void 0===s?void 0:or(s,r,`${t} has member 'pull' that`),start:void 0===i?void 0:nr(i,r,`${t} has member 'start' that`),type:void 0===a?void 0:sr(a,`${t} has member 'type' that`)}}(e,"First parameter");if(cr(this),"bytes"===o.type){if(void 0!==r.size)throw new RangeError("The strategy for a byte stream cannot have a size function");!function(e,t,r){const o=Object.create(ReadableByteStreamController.prototype);let n=()=>{},s=()=>p(void 0),i=()=>p(void 0);void 0!==t.start&&(n=()=>t.start(o)),void 0!==t.pull&&(s=()=>t.pull(o)),void 0!==t.cancel&&(i=e=>t.cancel(e));const a=t.autoAllocateChunkSize;if(0===a)throw new TypeError("autoAllocateChunkSize must be greater than 0");xe(e,o,n,s,i,r,a)}(this,o,Ne(r,0))}else{const e=Qe(r);!function(e,t,r,o){const n=Object.create(ReadableStreamDefaultController.prototype);let s=()=>{},i=()=>p(void 0),a=()=>p(void 0);void 0!==t.start&&(s=()=>t.start(n)),void 0!==t.pull&&(i=()=>t.pull(n)),void 0!==t.cancel&&(a=e=>t.cancel(e)),Xt(e,n,s,i,a,r,o)}(this,o,Ne(r,1),e)}}get locked(){if(!dr(this))throw yr("locked");return fr(this)}cancel(e){return dr(this)?fr(this)?h(new TypeError("Cannot cancel a stream that already has a reader")):pr(this,e):h(yr("cancel"))}getReader(e){if(!dr(this))throw yr("getReader");return void 0===function(e,t){F(e,t);const r=null==e?void 0:e.mode;return{mode:void 0===r?void 0:ir(r,`${t} has member 'mode' that`)}}(e,"First parameter").mode?Y(this):Fe(this)}pipeThrough(e,t={}){if(!dr(this))throw yr("pipeThrough");M(e,1,"pipeThrough");const r=function(e,t){F(e,t);const r=null==e?void 0:e.readable;$(r,"readable","ReadableWritablePair"),Q(r,`${t} has member 'readable' that`);const o=null==e?void 0:e.writable;return $(o,"writable","ReadableWritablePair"),Xe(o,`${t} has member 'writable' that`),{readable:r,writable:o}}(e,"First parameter"),o=ar(t,"Second parameter");if(fr(this))throw new TypeError("ReadableStream.prototype.pipeThrough cannot be used on a locked ReadableStream");if(nt(r.writable))throw new TypeError("ReadableStream.prototype.pipeThrough cannot be used on a locked WritableStream");return v(Ht(this,r.writable,o.preventClose,o.preventAbort,o.preventCancel,o.signal)),r.readable}pipeTo(e,t={}){if(!dr(this))return h(yr("pipeTo"));if(void 0===e)return h("Parameter 1 is required in 'pipeTo'.");if(!ot(e))return h(new TypeError("ReadableStream.prototype.pipeTo's first argument must be a WritableStream"));let r;try{r=ar(t,"Second parameter")}catch(e){return h(e)}return fr(this)?h(new TypeError("ReadableStream.prototype.pipeTo cannot be used on a locked ReadableStream")):nt(e)?h(new TypeError("ReadableStream.prototype.pipeTo cannot be used on a locked WritableStream")):Ht(this,e,r.preventClose,r.preventAbort,r.preventCancel,r.signal)}tee(){if(!dr(this))throw yr("tee");return ie(tr(this))}values(e){if(!dr(this))throw yr("values");return function(e,t){const r=Y(e),o=new ReadableStreamAsyncIteratorImpl(r,t),n=Object.create(re);return n._asyncIteratorImpl=o,n}(this,function(e,t){F(e,t);const r=null==e?void 0:e.preventCancel;return{preventCancel:Boolean(r)}}(e,"First parameter").preventCancel)}}function ur(e,t,r,o=1,n=(()=>1)){const s=Object.create(ReadableStream.prototype);cr(s);return Xt(s,Object.create(ReadableStreamDefaultController.prototype),e,t,r,o,n),s}function lr(e,t,r){const o=Object.create(ReadableStream.prototype);cr(o);return xe(o,Object.create(ReadableByteStreamController.prototype),e,t,r,0,void 0),o}function cr(e){e._state="readable",e._reader=void 0,e._storedError=void 0,e._disturbed=!1}function dr(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_readableStreamController")&&e instanceof ReadableStream)}function fr(e){return void 0!==e._reader}function pr(e,t){if(e._disturbed=!0,"closed"===e._state)return p(void 0);if("errored"===e._state)return h(e._storedError);hr(e);const r=e._reader;void 0!==r&&$e(r)&&(r._readIntoRequests.forEach((e=>{e._closeSteps(void 0)})),r._readIntoRequests=new SimpleQueue);return g(e._readableStreamController[W](t),n)}function hr(e){e._state="closed";const t=e._reader;void 0!==t&&(j(t),Z(t)&&(t._readRequests.forEach((e=>{e._closeSteps()})),t._readRequests=new SimpleQueue))}function br(e,t){e._state="errored",e._storedError=t;const r=e._reader;void 0!==r&&(A(r,t),Z(r)?(r._readRequests.forEach((e=>{e._errorSteps(t)})),r._readRequests=new SimpleQueue):(r._readIntoRequests.forEach((e=>{e._errorSteps(t)})),r._readIntoRequests=new SimpleQueue))}function yr(e){return new TypeError(`ReadableStream.prototype.${e} can only be used on a ReadableStream`)}function mr(e,t){F(e,t);const r=null==e?void 0:e.highWaterMark;return $(r,"highWaterMark","QueuingStrategyInit"),{highWaterMark:H(r)}}Object.defineProperties(ReadableStream.prototype,{cancel:{enumerable:!0},getReader:{enumerable:!0},pipeThrough:{enumerable:!0},pipeTo:{enumerable:!0},tee:{enumerable:!0},values:{enumerable:!0},locked:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ReadableStream.prototype,o.toStringTag,{value:"ReadableStream",configurable:!0}),"symbol"==typeof o.asyncIterator&&Object.defineProperty(ReadableStream.prototype,o.asyncIterator,{value:ReadableStream.prototype.values,writable:!0,configurable:!0});const _r=e=>e.byteLength;Object.defineProperty(_r,"name",{value:"size",configurable:!0});class ByteLengthQueuingStrategy{constructor(e){M(e,1,"ByteLengthQueuingStrategy"),e=mr(e,"First parameter"),this._byteLengthQueuingStrategyHighWaterMark=e.highWaterMark}get highWaterMark(){if(!vr(this))throw gr("highWaterMark");return this._byteLengthQueuingStrategyHighWaterMark}get size(){if(!vr(this))throw gr("size");return _r}}function gr(e){return new TypeError(`ByteLengthQueuingStrategy.prototype.${e} can only be used on a ByteLengthQueuingStrategy`)}function vr(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_byteLengthQueuingStrategyHighWaterMark")&&e instanceof ByteLengthQueuingStrategy)}Object.defineProperties(ByteLengthQueuingStrategy.prototype,{highWaterMark:{enumerable:!0},size:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ByteLengthQueuingStrategy.prototype,o.toStringTag,{value:"ByteLengthQueuingStrategy",configurable:!0});const wr=()=>1;Object.defineProperty(wr,"name",{value:"size",configurable:!0});class CountQueuingStrategy{constructor(e){M(e,1,"CountQueuingStrategy"),e=mr(e,"First parameter"),this._countQueuingStrategyHighWaterMark=e.highWaterMark}get highWaterMark(){if(!Rr(this))throw Sr("highWaterMark");return this._countQueuingStrategyHighWaterMark}get size(){if(!Rr(this))throw Sr("size");return wr}}function Sr(e){return new TypeError(`CountQueuingStrategy.prototype.${e} can only be used on a CountQueuingStrategy`)}function Rr(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_countQueuingStrategyHighWaterMark")&&e instanceof CountQueuingStrategy)}function Tr(e,t,r){return z(e,r),r=>R(e,t,[r])}function qr(e,t,r){return z(e,r),r=>S(e,t,[r])}function Pr(e,t,r){return z(e,r),(r,o)=>R(e,t,[r,o])}Object.defineProperties(CountQueuingStrategy.prototype,{highWaterMark:{enumerable:!0},size:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(CountQueuingStrategy.prototype,o.toStringTag,{value:"CountQueuingStrategy",configurable:!0});class TransformStream{constructor(e={},t={},r={}){void 0===e&&(e=null);const o=Ye(t,"Second parameter"),n=Ye(r,"Third parameter"),s=function(e,t){F(e,t);const r=null==e?void 0:e.flush,o=null==e?void 0:e.readableType,n=null==e?void 0:e.start,s=null==e?void 0:e.transform,i=null==e?void 0:e.writableType;return{flush:void 0===r?void 0:Tr(r,e,`${t} has member 'flush' that`),readableType:o,start:void 0===n?void 0:qr(n,e,`${t} has member 'start' that`),transform:void 0===s?void 0:Pr(s,e,`${t} has member 'transform' that`),writableType:i}}(e,"First parameter");if(void 0!==s.readableType)throw new RangeError("Invalid readableType specified");if(void 0!==s.writableType)throw new RangeError("Invalid writableType specified");const i=Ne(n,0),a=Qe(n),u=Ne(o,1),l=Qe(o);let c;!function(e,t,r,o,n,s){function i(){return t}function a(t){return function(e,t){const r=e._transformStreamController;if(e._backpressure){return g(e._backpressureChangePromise,(()=>{const o=e._writable;if("erroring"===o._state)throw o._storedError;return Wr(r,t)}))}return Wr(r,t)}(e,t)}function u(t){return function(e,t){return Cr(e,t),p(void 0)}(e,t)}function l(){return function(e){const t=e._readable,r=e._transformStreamController,o=r._flushAlgorithm();return kr(r),g(o,(()=>{if("errored"===t._state)throw t._storedError;Vt(t._readableStreamController)}),(r=>{throw Cr(e,r),t._storedError}))}(e)}function c(){return function(e){return Ar(e,!1),e._backpressureChangePromise}(e)}function d(t){return Or(e,t),p(void 0)}e._writable=function(e,t,r,o,n=1,s=(()=>1)){const i=Object.create(WritableStream.prototype);return rt(i),wt(i,Object.create(WritableStreamDefaultController.prototype),e,t,r,o,n,s),i}(i,a,l,u,r,o),e._readable=ur(i,c,d,n,s),e._backpressure=void 0,e._backpressureChangePromise=void 0,e._backpressureChangePromise_resolve=void 0,Ar(e,!0),e._transformStreamController=void 0}(this,f((e=>{c=e})),u,l,i,a),function(e,t){const r=Object.create(TransformStreamDefaultController.prototype);let o=e=>{try{return Br(r,e),p(void 0)}catch(e){return h(e)}},n=()=>p(void 0);void 0!==t.transform&&(o=e=>t.transform(e,r));void 0!==t.flush&&(n=()=>t.flush(r));!function(e,t,r,o){t._controlledTransformStream=e,e._transformStreamController=t,t._transformAlgorithm=r,t._flushAlgorithm=o}(e,r,o,n)}(this,s),void 0!==s.start?c(s.start(this._transformStreamController)):c(void 0)}get readable(){if(!Er(this))throw Dr("readable");return this._readable}get writable(){if(!Er(this))throw Dr("writable");return this._writable}}function Er(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_transformStreamController")&&e instanceof TransformStream)}function Cr(e,t){Jt(e._readable._readableStreamController,t),Or(e,t)}function Or(e,t){kr(e._transformStreamController),qt(e._writable._writableStreamController,t),e._backpressure&&Ar(e,!1)}function Ar(e,t){void 0!==e._backpressureChangePromise&&e._backpressureChangePromise_resolve(),e._backpressureChangePromise=f((t=>{e._backpressureChangePromise_resolve=t})),e._backpressure=t}Object.defineProperties(TransformStream.prototype,{readable:{enumerable:!0},writable:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(TransformStream.prototype,o.toStringTag,{value:"TransformStream",configurable:!0});class TransformStreamDefaultController{constructor(){throw new TypeError("Illegal constructor")}get desiredSize(){if(!jr(this))throw xr("desiredSize");return Kt(this._controlledTransformStream._readable._readableStreamController)}enqueue(e){if(!jr(this))throw xr("enqueue");Br(this,e)}error(e){if(!jr(this))throw xr("error");var t;t=e,Cr(this._controlledTransformStream,t)}terminate(){if(!jr(this))throw xr("terminate");!function(e){const t=e._controlledTransformStream;Vt(t._readable._readableStreamController);const r=new TypeError("TransformStream terminated");Or(t,r)}(this)}}function jr(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_controlledTransformStream")&&e instanceof TransformStreamDefaultController)}function kr(e){e._transformAlgorithm=void 0,e._flushAlgorithm=void 0}function Br(e,t){const r=e._controlledTransformStream,o=r._readable._readableStreamController;if(!Zt(o))throw new TypeError("Readable side is not in a state that permits enqueue");try{Gt(o,t)}catch(e){throw Or(r,e),r._readable._storedError}const n=function(e){return!Qt(e)}(o);n!==r._backpressure&&Ar(r,!0)}function Wr(e,t){return g(e._transformAlgorithm(t),void 0,(t=>{throw Cr(e._controlledTransformStream,t),t}))}function xr(e){return new TypeError(`TransformStreamDefaultController.prototype.${e} can only be used on a TransformStreamDefaultController`)}function Dr(e){return new TypeError(`TransformStream.prototype.${e} can only be used on a TransformStream`)}Object.defineProperties(TransformStreamDefaultController.prototype,{enqueue:{enumerable:!0},error:{enumerable:!0},terminate:{enumerable:!0},desiredSize:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(TransformStreamDefaultController.prototype,o.toStringTag,{value:"TransformStreamDefaultController",configurable:!0})}},t={};function r(o){var n=t[o];if(void 0!==n)return n.exports;var s=t[o]={id:o,loaded:!1,exports:{}};return e[o].call(s.exports,s,s.exports,r),s.loaded=!0,s.exports}return r.d=(e,t)=>{for(var o in t)r.o(t,o)&&!r.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),r(48)})()})); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,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UzhwQyxFQUF5QkUsR0FBWSxDQUNqRDFpQyxHQUFJMGlDLEVBQ0pFLFFBQVEsRUFDUm5xQyxRQUFTLElBVVYsT0FOQW9xQyxFQUFvQkgsR0FBVW5vQyxLQUFLN0IsRUFBT0QsUUFBU0MsRUFBUUEsRUFBT0QsUUFBU2dxQyxHQUczRS9wQyxFQUFPa3FDLFFBQVMsRUFHVGxxQyxFQUFPRCxlQ3ZCZmdxQyxFQUFvQnA3QixFQUFJLENBQUM1TyxFQUFTcXFDLEtBQ2pDLElBQUksSUFBSXZuQyxLQUFPdW5DLEVBQ1hMLEVBQW9CTSxFQUFFRCxFQUFZdm5DLEtBQVNrbkMsRUFBb0JNLEVBQUV0cUMsRUFBUzhDLElBQzVFekMsT0FBT0MsZUFBZU4sRUFBUzhDLEVBQUssQ0FBRXpCLFlBQVksRUFBTUwsSUFBS3FwQyxFQUFXdm5DLE1DSjNFa25DLEVBQW9CTSxFQUFJLENBQUNuK0IsRUFBS28rQixJQUFVbHFDLE9BQU9hLFVBQVU4dEIsZUFBZWx0QixLQUFLcUssRUFBS28rQixHQ0NsRlAsRUFBb0JyVCxFQUFLMzJCLElBQ0gsb0JBQVhzQixRQUEwQkEsT0FBT0MsYUFDMUNsQixPQUFPQyxlQUFlTixFQUFTc0IsT0FBT0MsWUFBYSxDQUFFaEIsTUFBTyxXQUU3REYsT0FBT0MsZUFBZU4sRUFBUyxhQUFjLENBQUVPLE9BQU8sS0NMdkR5cEMsRUFBb0JRLElBQU92cUMsSUFDMUJBLEVBQU93cUMsTUFBUSxHQUNWeHFDLEVBQU95cUMsV0FBVXpxQyxFQUFPeXFDLFNBQVcsSUFDakN6cUMsR0NBa0IrcEMsRUFBb0IsS3hDTzlDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vbWFpbGd1bi93ZWJwYWNrL3VuaXZlcnNhbE1vZHVsZURlZmluaXRpb24iLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9hYm9ydC1jb250cm9sbGVyL2Rpc3QvYWJvcnQtY29udHJvbGxlci5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9jbGllbnQudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9kb21haW5zLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvZXJyb3IudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9ldmVudHMudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9pcC1wb29scy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL2lwcy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL2xpc3RzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvbWFpbExpc3RNZW1iZXJzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvbWVzc2FnZXMudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9wYXJzZS50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL3JlcXVlc3QudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9yb3V0ZXMudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9zdGF0cy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL3N1cHByZXNzaW9ucy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL3ZhbGlkYXRlLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvd2ViaG9va3MudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9iYXNlLTY0L2Jhc2U2NC5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2RhdGEtdXJpLXRvLWJ1ZmZlci9kaXN0L3NyYy9pbmRleC5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2V2ZW50LXRhcmdldC1zaGltL2Rpc3QvZXZlbnQtdGFyZ2V0LXNoaW0uanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9mZXRjaC1ibG9iL2luZGV4LmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMva3ktdW5pdmVyc2FsL2luZGV4LmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMva3kvdW1kLmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvdXJsLWpvaW4vbGliL3VybC1qb2luLmpzIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcImNyeXB0b1wiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcImh0dHBcIiIsIndlYnBhY2s6Ly9tYWlsZ3VuL2V4dGVybmFsIG5vZGUtY29tbW9uanMgXCJodHRwc1wiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcInN0cmVhbVwiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcInVybFwiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcInV0aWxcIiIsIndlYnBhY2s6Ly9tYWlsZ3VuL2V4dGVybmFsIG5vZGUtY29tbW9uanMgXCJ6bGliXCIiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9ub2RlLWZldGNoL2Rpc3QvaW5kZXguY2pzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvd2ViLXN0cmVhbXMtcG9seWZpbGwvZGlzdC9wb255ZmlsbC5lczIwMTgubWpzIiwid2VicGFjazovL21haWxndW4vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vbWFpbGd1bi93ZWJwYWNrL3J1bnRpbWUvZGVmaW5lIHByb3BlcnR5IGdldHRlcnMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi93ZWJwYWNrL3J1bnRpbWUvaGFzT3duUHJvcGVydHkgc2hvcnRoYW5kIiwid2VicGFjazovL21haWxndW4vd2VicGFjay9ydW50aW1lL21ha2UgbmFtZXNwYWNlIG9iamVjdCIsIndlYnBhY2s6Ly9tYWlsZ3VuL3dlYnBhY2svcnVudGltZS9ub2RlIG1vZHVsZSBkZWNvcmF0b3IiLCJ3ZWJwYWNrOi8vbWFpbGd1bi93ZWJwYWNrL3N0YXJ0dXAiXSwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKVxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuXHRlbHNlIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZClcblx0XHRkZWZpbmUoW10sIGZhY3RvcnkpO1xuXHRlbHNlIGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jylcblx0XHRleHBvcnRzW1wibWFpbGd1blwiXSA9IGZhY3RvcnkoKTtcblx0ZWxzZVxuXHRcdHJvb3RbXCJtYWlsZ3VuXCJdID0gZmFjdG9yeSgpO1xufSkodGhpcywgZnVuY3Rpb24oKSB7XG5yZXR1cm4gIiwiLyoqXG4gKiBAYXV0aG9yIFRvcnUgTmFnYXNoaW1hIDxodHRwczovL2dpdGh1Yi5jb20vbXlzdGljYXRlYT5cbiAqIFNlZSBMSUNFTlNFIGZpbGUgaW4gcm9vdCBkaXJlY3RvcnkgZm9yIGZ1bGwgbGljZW5zZS5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG52YXIgZXZlbnRUYXJnZXRTaGltID0gcmVxdWlyZSgnZXZlbnQtdGFyZ2V0LXNoaW0nKTtcblxuLyoqXG4gKiBUaGUgc2lnbmFsIGNsYXNzLlxuICogQHNlZSBodHRwczovL2RvbS5zcGVjLndoYXR3Zy5vcmcvI2Fib3J0c2lnbmFsXG4gKi9cbmNsYXNzIEFib3J0U2lnbmFsIGV4dGVuZHMgZXZlbnRUYXJnZXRTaGltLkV2ZW50VGFyZ2V0IHtcbiAgICAvKipcbiAgICAgKiBBYm9ydFNpZ25hbCBjYW5ub3QgYmUgY29uc3RydWN0ZWQgZGlyZWN0bHkuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJBYm9ydFNpZ25hbCBjYW5ub3QgYmUgY29uc3RydWN0ZWQgZGlyZWN0bHlcIik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYHRydWVgIGlmIHRoaXMgYEFib3J0U2lnbmFsYCdzIGBBYm9ydENvbnRyb2xsZXJgIGhhcyBzaWduYWxlZCB0byBhYm9ydCwgYW5kIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICAgICAqL1xuICAgIGdldCBhYm9ydGVkKCkge1xuICAgICAgICBjb25zdCBhYm9ydGVkID0gYWJvcnRlZEZsYWdzLmdldCh0aGlzKTtcbiAgICAgICAgaWYgKHR5cGVvZiBhYm9ydGVkICE9PSBcImJvb2xlYW5cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgRXhwZWN0ZWQgJ3RoaXMnIHRvIGJlIGFuICdBYm9ydFNpZ25hbCcgb2JqZWN0LCBidXQgZ290ICR7dGhpcyA9PT0gbnVsbCA/IFwibnVsbFwiIDogdHlwZW9mIHRoaXN9YCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFib3J0ZWQ7XG4gICAgfVxufVxuZXZlbnRUYXJnZXRTaGltLmRlZmluZUV2ZW50QXR0cmlidXRlKEFib3J0U2lnbmFsLnByb3RvdHlwZSwgXCJhYm9ydFwiKTtcbi8qKlxuICogQ3JlYXRlIGFuIEFib3J0U2lnbmFsIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlQWJvcnRTaWduYWwoKSB7XG4gICAgY29uc3Qgc2lnbmFsID0gT2JqZWN0LmNyZWF0ZShBYm9ydFNpZ25hbC5wcm90b3R5cGUpO1xuICAgIGV2ZW50VGFyZ2V0U2hpbS5FdmVudFRhcmdldC5jYWxsKHNpZ25hbCk7XG4gICAgYWJvcnRlZEZsYWdzLnNldChzaWduYWwsIGZhbHNlKTtcbiAgICByZXR1cm4gc2lnbmFsO1xufVxuLyoqXG4gKiBBYm9ydCBhIGdpdmVuIHNpZ25hbC5cbiAqL1xuZnVuY3Rpb24gYWJvcnRTaWduYWwoc2lnbmFsKSB7XG4gICAgaWYgKGFib3J0ZWRGbGFncy5nZXQoc2lnbmFsKSAhPT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBhYm9ydGVkRmxhZ3Muc2V0KHNpZ25hbCwgdHJ1ZSk7XG4gICAgc2lnbmFsLmRpc3BhdGNoRXZlbnQoeyB0eXBlOiBcImFib3J0XCIgfSk7XG59XG4vKipcbiAqIEFib3J0ZWQgZmxhZyBmb3IgZWFjaCBpbnN0YW5jZXMuXG4gKi9cbmNvbnN0IGFib3J0ZWRGbGFncyA9IG5ldyBXZWFrTWFwKCk7XG4vLyBQcm9wZXJ0aWVzIHNob3VsZCBiZSBlbnVtZXJhYmxlLlxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoQWJvcnRTaWduYWwucHJvdG90eXBlLCB7XG4gICAgYWJvcnRlZDogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG59KTtcbi8vIGB0b1N0cmluZygpYCBzaG91bGQgcmV0dXJuIGBcIltvYmplY3QgQWJvcnRTaWduYWxdXCJgXG5pZiAodHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wudG9TdHJpbmdUYWcgPT09IFwic3ltYm9sXCIpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQWJvcnRTaWduYWwucHJvdG90eXBlLCBTeW1ib2wudG9TdHJpbmdUYWcsIHtcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICB2YWx1ZTogXCJBYm9ydFNpZ25hbFwiLFxuICAgIH0pO1xufVxuXG4vKipcbiAqIFRoZSBBYm9ydENvbnRyb2xsZXIuXG4gKiBAc2VlIGh0dHBzOi8vZG9tLnNwZWMud2hhdHdnLm9yZy8jYWJvcnRjb250cm9sbGVyXG4gKi9cbmNsYXNzIEFib3J0Q29udHJvbGxlciB7XG4gICAgLyoqXG4gICAgICogSW5pdGlhbGl6ZSB0aGlzIGNvbnRyb2xsZXIuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHNpZ25hbHMuc2V0KHRoaXMsIGNyZWF0ZUFib3J0U2lnbmFsKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBgQWJvcnRTaWduYWxgIG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBvYmplY3QuXG4gICAgICovXG4gICAgZ2V0IHNpZ25hbCgpIHtcbiAgICAgICAgcmV0dXJuIGdldFNpZ25hbCh0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWJvcnQgYW5kIHNpZ25hbCB0byBhbnkgb2JzZXJ2ZXJzIHRoYXQgdGhlIGFzc29jaWF0ZWQgYWN0aXZpdHkgaXMgdG8gYmUgYWJvcnRlZC5cbiAgICAgKi9cbiAgICBhYm9ydCgpIHtcbiAgICAgICAgYWJvcnRTaWduYWwoZ2V0U2lnbmFsKHRoaXMpKTtcbiAgICB9XG59XG4vKipcbiAqIEFzc29jaWF0ZWQgc2lnbmFscy5cbiAqL1xuY29uc3Qgc2lnbmFscyA9IG5ldyBXZWFrTWFwKCk7XG4vKipcbiAqIEdldCB0aGUgYXNzb2NpYXRlZCBzaWduYWwgb2YgYSBnaXZlbiBjb250cm9sbGVyLlxuICovXG5mdW5jdGlvbiBnZXRTaWduYWwoY29udHJvbGxlcikge1xuICAgIGNvbnN0IHNpZ25hbCA9IHNpZ25hbHMuZ2V0KGNvbnRyb2xsZXIpO1xuICAgIGlmIChzaWduYWwgPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBFeHBlY3RlZCAndGhpcycgdG8gYmUgYW4gJ0Fib3J0Q29udHJvbGxlcicgb2JqZWN0LCBidXQgZ290ICR7Y29udHJvbGxlciA9PT0gbnVsbCA/IFwibnVsbFwiIDogdHlwZW9mIGNvbnRyb2xsZXJ9YCk7XG4gICAgfVxuICAgIHJldHVybiBzaWduYWw7XG59XG4vLyBQcm9wZXJ0aWVzIHNob3VsZCBiZSBlbnVtZXJhYmxlLlxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoQWJvcnRDb250cm9sbGVyLnByb3RvdHlwZSwge1xuICAgIHNpZ25hbDogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgYWJvcnQ6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxufSk7XG5pZiAodHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wudG9TdHJpbmdUYWcgPT09IFwic3ltYm9sXCIpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQWJvcnRDb250cm9sbGVyLnByb3RvdHlwZSwgU3ltYm9sLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgdmFsdWU6IFwiQWJvcnRDb250cm9sbGVyXCIsXG4gICAgfSk7XG59XG5cbmV4cG9ydHMuQWJvcnRDb250cm9sbGVyID0gQWJvcnRDb250cm9sbGVyO1xuZXhwb3J0cy5BYm9ydFNpZ25hbCA9IEFib3J0U2lnbmFsO1xuZXhwb3J0cy5kZWZhdWx0ID0gQWJvcnRDb250cm9sbGVyO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFib3J0Q29udHJvbGxlclxubW9kdWxlLmV4cG9ydHMuQWJvcnRDb250cm9sbGVyID0gbW9kdWxlLmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gQWJvcnRDb250cm9sbGVyXG5tb2R1bGUuZXhwb3J0cy5BYm9ydFNpZ25hbCA9IEFib3J0U2lnbmFsXG4vLyMgc291cmNlTWFwcGluZ1VSTD1hYm9ydC1jb250cm9sbGVyLmpzLm1hcFxuIiwiaW1wb3J0IENsaWVudCBmcm9tICcuL2xpYi9jbGllbnQnO1xuaW1wb3J0IHsgSW5wdXRGb3JtRGF0YSB9IGZyb20gJy4vbGliL2ludGVyZmFjZXMvSUZvcm1EYXRhJztcbmltcG9ydCBPcHRpb25zIGZyb20gJy4vbGliL2ludGVyZmFjZXMvT3B0aW9ucyc7XG5cbmNsYXNzIE1haWxndW4ge1xuICBwcml2YXRlIGZvcm1EYXRhOiBJbnB1dEZvcm1EYXRhXG5cbiAgY29uc3RydWN0b3IoRm9ybURhdGE6IElucHV0Rm9ybURhdGEpIHtcbiAgICB0aGlzLmZvcm1EYXRhID0gRm9ybURhdGE7XG4gIH1cblxuICBjbGllbnQob3B0aW9uczogT3B0aW9ucykgOiBDbGllbnQge1xuICAgIHJldHVybiBuZXcgQ2xpZW50KG9wdGlvbnMsIHRoaXMuZm9ybURhdGEpO1xuICB9XG59XG5cbmV4cG9ydCA9IE1haWxndW47XG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbmltcG9ydCBSZXF1ZXN0IGZyb20gJy4vcmVxdWVzdCc7XG5pbXBvcnQgT3B0aW9ucyBmcm9tICcuL2ludGVyZmFjZXMvT3B0aW9ucyc7XG5pbXBvcnQgUmVxdWVzdE9wdGlvbnMgZnJvbSAnLi9pbnRlcmZhY2VzL1JlcXVlc3RPcHRpb25zJztcblxuaW1wb3J0IERvbWFpbkNsaWVudCBmcm9tICcuL2RvbWFpbnMnO1xuaW1wb3J0IEV2ZW50Q2xpZW50IGZyb20gJy4vZXZlbnRzJztcbmltcG9ydCBTdGF0c0NsaWVudCBmcm9tICcuL3N0YXRzJztcbmltcG9ydCBTdXBwcmVzc2lvbkNsaWVudCBmcm9tICcuL3N1cHByZXNzaW9ucyc7XG5pbXBvcnQgV2ViaG9va0NsaWVudCBmcm9tICcuL3dlYmhvb2tzJztcbmltcG9ydCBNZXNzYWdlc0NsaWVudCBmcm9tICcuL21lc3NhZ2VzJztcbmltcG9ydCBSb3V0ZXNDbGllbnQgZnJvbSAnLi9yb3V0ZXMnO1xuaW1wb3J0IFZhbGlkYXRlQ2xpZW50IGZyb20gJy4vdmFsaWRhdGUnO1xuaW1wb3J0IFBhcnNlQ2xpZW50IGZyb20gJy4vcGFyc2UnO1xuaW1wb3J0IElwc0NsaWVudCBmcm9tICcuL2lwcyc7XG5pbXBvcnQgSXBQb29sc0NsaWVudCBmcm9tICcuL2lwLXBvb2xzJztcbmltcG9ydCBMaXN0c0NsaWVudCBmcm9tICcuL2xpc3RzJztcbmltcG9ydCBNYWlsTGlzdHNNZW1iZXJzIGZyb20gJy4vbWFpbExpc3RNZW1iZXJzJztcbmltcG9ydCB7IElucHV0Rm9ybURhdGEgfSBmcm9tICcuL2ludGVyZmFjZXMvSUZvcm1EYXRhJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ2xpZW50IHtcbiAgcHJpdmF0ZSByZXF1ZXN0O1xuXG4gIHB1YmxpYyBkb21haW5zO1xuICBwdWJsaWMgd2ViaG9va3M7XG4gIHB1YmxpYyBldmVudHM7XG4gIHB1YmxpYyBzdGF0cztcbiAgcHVibGljIHN1cHByZXNzaW9ucztcbiAgcHVibGljIG1lc3NhZ2VzO1xuICBwdWJsaWMgcm91dGVzO1xuICBwdWJsaWMgcHVibGljX3JlcXVlc3Q7XG4gIHB1YmxpYyB2YWxpZGF0ZTtcbiAgcHVibGljIHBhcnNlO1xuICBwdWJsaWMgaXBzO1xuICBwdWJsaWMgaXBfcG9vbHM7XG4gIHB1YmxpYyBsaXN0cztcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBPcHRpb25zLCBmb3JtRGF0YTogSW5wdXRGb3JtRGF0YSkge1xuICAgIGNvbnN0IGNvbmZpZzogUmVxdWVzdE9wdGlvbnMgPSB7IC4uLm9wdGlvbnMgfSBhcyBSZXF1ZXN0T3B0aW9ucztcblxuICAgIGlmICghY29uZmlnLnVybCkge1xuICAgICAgY29uZmlnLnVybCA9ICdodHRwczovL2FwaS5tYWlsZ3VuLm5ldCc7XG4gICAgfVxuXG4gICAgaWYgKCFjb25maWcudXNlcm5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGFyYW1ldGVyIFwidXNlcm5hbWVcIiBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIGlmICghY29uZmlnLmtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQYXJhbWV0ZXIgXCJrZXlcIiBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICB0aGlzLnJlcXVlc3QgPSBuZXcgUmVxdWVzdChjb25maWcsIGZvcm1EYXRhKTtcbiAgICBjb25zdCBtYWlsTGlzdHNNZW1iZXJzID0gbmV3IE1haWxMaXN0c01lbWJlcnModGhpcy5yZXF1ZXN0KTtcblxuICAgIHRoaXMuZG9tYWlucyA9IG5ldyBEb21haW5DbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLndlYmhvb2tzID0gbmV3IFdlYmhvb2tDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLmV2ZW50cyA9IG5ldyBFdmVudENsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIHRoaXMuc3RhdHMgPSBuZXcgU3RhdHNDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLnN1cHByZXNzaW9ucyA9IG5ldyBTdXBwcmVzc2lvbkNsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIHRoaXMubWVzc2FnZXMgPSBuZXcgTWVzc2FnZXNDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLnJvdXRlcyA9IG5ldyBSb3V0ZXNDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLmlwcyA9IG5ldyBJcHNDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLmlwX3Bvb2xzID0gbmV3IElwUG9vbHNDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLmxpc3RzID0gbmV3IExpc3RzQ2xpZW50KHRoaXMucmVxdWVzdCwgbWFpbExpc3RzTWVtYmVycyk7XG5cbiAgICBpZiAoY29uZmlnLnB1YmxpY19rZXkpIHtcbiAgICAgIGNvbmZpZy5rZXkgPSBjb25maWcucHVibGljX2tleTtcblxuICAgICAgdGhpcy5wdWJsaWNfcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KGNvbmZpZywgZm9ybURhdGEpO1xuICAgICAgdGhpcy52YWxpZGF0ZSA9IG5ldyBWYWxpZGF0ZUNsaWVudCh0aGlzLnB1YmxpY19yZXF1ZXN0KTtcbiAgICAgIHRoaXMucGFyc2UgPSBuZXcgUGFyc2VDbGllbnQodGhpcy5wdWJsaWNfcmVxdWVzdCk7XG4gICAgfVxuICB9XG59XG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbmltcG9ydCB1cmxqb2luIGZyb20gJ3VybC1qb2luJztcbmltcG9ydCB7XG4gIERvbWFpblJlc3BvbnNlRGF0YSxcbiAgRGVzdHJveWVkRG9tYWluLFxuICBEZXN0cm95ZWREb21haW5SZXNwb25zZSxcbiAgRG9tYWluc1F1ZXJ5LFxuICBEb21haW5JbmZvLFxuICBEb21haW5MaXN0UmVzcG9uc2VEYXRhLFxuICBEb21haW5TaG9ydERhdGEsXG4gIEROU1JlY29yZFxufSBmcm9tICcuL2ludGVyZmFjZXMvRG9tYWlucyc7XG5cbmltcG9ydCBBUElSZXNwb25zZSBmcm9tICcuL2ludGVyZmFjZXMvQXBpUmVzcG9uc2UnO1xuaW1wb3J0IEFQSUVycm9yIGZyb20gJy4vZXJyb3InO1xuaW1wb3J0IEFQSUVycm9yT3B0aW9ucyBmcm9tICcuL2ludGVyZmFjZXMvQVBJRXJyb3JPcHRpb25zJztcblxuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi9yZXF1ZXN0JztcbmltcG9ydCB7XG4gIERvbWFpblRyYWNraW5nUmVzcG9uc2UsXG4gIERvbWFpblRyYWNraW5nRGF0YSxcbiAgT3BlblRyYWNraW5nSW5mbyxcbiAgQ2xpY2tUcmFja2luZ0luZm8sXG4gIFVuc3Vic2NyaWJlVHJhY2tpbmdJbmZvLFxuICBVcGRhdGVEb21haW5UcmFja2luZ1Jlc3BvbnNlLFxuICBVcGRhdGVkT3BlblRyYWNraW5nXG59IGZyb20gJy4vaW50ZXJmYWNlcy9Eb21haW5UcmFja2luZyc7XG5cbmNsYXNzIERvbWFpbiB7XG4gIG5hbWU6IHN0cmluZztcbiAgcmVxdWlyZV90bHM6IGJvb2xlYW47XG4gIHNraXBfdmVyaWZpY2F0aW9uOiBib29sZWFuO1xuICBzdGF0ZTogc3RyaW5nO1xuICB3aWxkY2FyZDogYm9vbGVhbjtcbiAgc3BhbV9hY3Rpb246IHN0cmluZztcbiAgY3JlYXRlZF9hdDogc3RyaW5nO1xuICBzbXRwX3Bhc3N3b3JkOiBzdHJpbmc7XG4gIHNtdHBfbG9naW46IHN0cmluZztcbiAgdHlwZTogc3RyaW5nO1xuICByZWNlaXZpbmdfZG5zX3JlY29yZHM6IEROU1JlY29yZFtdIHwgbnVsbDtcbiAgc2VuZGluZ19kbnNfcmVjb3JkczogRE5TUmVjb3JkW10gfCBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKGRhdGE6IERvbWFpblNob3J0RGF0YSwgcmVjZWl2aW5nPzogRE5TUmVjb3JkW10gfCBudWxsLCBzZW5kaW5nPzogRE5TUmVjb3JkW10gfCBudWxsKSB7XG4gICAgdGhpcy5uYW1lID0gZGF0YS5uYW1lO1xuICAgIHRoaXMucmVxdWlyZV90bHMgPSBkYXRhLnJlcXVpcmVfdGxzO1xuICAgIHRoaXMuc2tpcF92ZXJpZmljYXRpb24gPSBkYXRhLnNraXBfdmVyaWZpY2F0aW9uO1xuICAgIHRoaXMuc3RhdGUgPSBkYXRhLnN0YXRlO1xuICAgIHRoaXMud2lsZGNhcmQgPSBkYXRhLndpbGRjYXJkO1xuICAgIHRoaXMuc3BhbV9hY3Rpb24gPSBkYXRhLnNwYW1fYWN0aW9uO1xuICAgIHRoaXMuY3JlYXRlZF9hdCA9IGRhdGEuY3JlYXRlZF9hdDtcbiAgICB0aGlzLnNtdHBfcGFzc3dvcmQgPSBkYXRhLnNtdHBfcGFzc3dvcmQ7XG4gICAgdGhpcy5zbXRwX2xvZ2luID0gZGF0YS5zbXRwX2xvZ2luO1xuICAgIHRoaXMudHlwZSA9IGRhdGEudHlwZTtcblxuICAgIHRoaXMucmVjZWl2aW5nX2Ruc19yZWNvcmRzID0gcmVjZWl2aW5nIHx8IG51bGw7XG4gICAgdGhpcy5zZW5kaW5nX2Ruc19yZWNvcmRzID0gc2VuZGluZyB8fCBudWxsO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERvbWFpbkNsaWVudCB7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBfcGFyc2VNZXNzYWdlKHJlc3BvbnNlOiBEZXN0cm95ZWREb21haW5SZXNwb25zZSkgOiBEZXN0cm95ZWREb21haW4ge1xuICAgIHJldHVybiByZXNwb25zZS5ib2R5O1xuICB9XG5cbiAgX3BhcnNlRG9tYWluTGlzdChyZXNwb25zZTogRG9tYWluTGlzdFJlc3BvbnNlRGF0YSk6IERvbWFpbltdIHtcbiAgICByZXR1cm4gcmVzcG9uc2UuYm9keS5pdGVtcy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHJldHVybiBuZXcgRG9tYWluKGl0ZW0pO1xuICAgIH0pO1xuICB9XG5cbiAgX3BhcnNlRG9tYWluKHJlc3BvbnNlOiBEb21haW5SZXNwb25zZURhdGEpOiBEb21haW4ge1xuICAgIHJldHVybiBuZXcgRG9tYWluKFxuICAgICAgcmVzcG9uc2UuYm9keS5kb21haW4sXG4gICAgICByZXNwb25zZS5ib2R5LnJlY2VpdmluZ19kbnNfcmVjb3JkcyxcbiAgICAgIHJlc3BvbnNlLmJvZHkuc2VuZGluZ19kbnNfcmVjb3Jkc1xuICAgICk7XG4gIH1cblxuICBfcGFyc2VUcmFja2luZ1NldHRpbmdzKHJlc3BvbnNlOiBEb21haW5UcmFja2luZ1Jlc3BvbnNlKSA6IERvbWFpblRyYWNraW5nRGF0YSB7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmJvZHkudHJhY2tpbmc7XG4gIH1cblxuICBfcGFyc2VUcmFja2luZ1VwZGF0ZShyZXNwb25zZTogVXBkYXRlRG9tYWluVHJhY2tpbmdSZXNwb25zZSkgOlVwZGF0ZWRPcGVuVHJhY2tpbmcge1xuICAgIHJldHVybiByZXNwb25zZS5ib2R5O1xuICB9XG5cbiAgbGlzdChxdWVyeTogRG9tYWluc1F1ZXJ5KTogUHJvbWlzZTxEb21haW5bXT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KCcvdjIvZG9tYWlucycsIHF1ZXJ5KVxuICAgICAgLnRoZW4oKHJlcyA6IEFQSVJlc3BvbnNlKSA9PiB0aGlzLl9wYXJzZURvbWFpbkxpc3QocmVzIGFzIERvbWFpbkxpc3RSZXNwb25zZURhdGEpKTtcbiAgfVxuXG4gIGdldChkb21haW46IHN0cmluZykgOiBQcm9taXNlPERvbWFpbj4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KGAvdjIvZG9tYWlucy8ke2RvbWFpbn1gKVxuICAgICAgLnRoZW4oKHJlcyA6IEFQSVJlc3BvbnNlKSA9PiB0aGlzLl9wYXJzZURvbWFpbihyZXMgYXMgRG9tYWluUmVzcG9uc2VEYXRhKSk7XG4gIH1cblxuICBjcmVhdGUoZGF0YTogRG9tYWluSW5mbykgOiBQcm9taXNlPERvbWFpbj4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRCgnL3YyL2RvbWFpbnMnLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlcyA6IEFQSVJlc3BvbnNlKSA9PiB0aGlzLl9wYXJzZURvbWFpbihyZXMgYXMgRG9tYWluUmVzcG9uc2VEYXRhKSk7XG4gIH1cblxuICBkZXN0cm95KGRvbWFpbjogc3RyaW5nKTogUHJvbWlzZTxEZXN0cm95ZWREb21haW4+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZShgL3YyL2RvbWFpbnMvJHtkb21haW59YClcbiAgICAgIC50aGVuKChyZXMgOiBBUElSZXNwb25zZSkgPT4gdGhpcy5fcGFyc2VNZXNzYWdlKHJlcyBhcyBEZXN0cm95ZWREb21haW5SZXNwb25zZSkpO1xuICB9XG5cbiAgLy8gVHJhY2tpbmdcblxuICBnZXRUcmFja2luZyhkb21haW46IHN0cmluZykgOiBQcm9taXNlPERvbWFpblRyYWNraW5nRGF0YT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybGpvaW4oJy92Mi9kb21haW5zJywgZG9tYWluLCAndHJhY2tpbmcnKSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlVHJhY2tpbmdTZXR0aW5ncyk7XG4gIH1cblxuICB1cGRhdGVUcmFja2luZyhcbiAgICBkb21haW46IHN0cmluZyxcbiAgICB0eXBlOiBzdHJpbmcsXG4gICAgZGF0YTogT3BlblRyYWNraW5nSW5mbyB8IENsaWNrVHJhY2tpbmdJbmZvIHwgVW5zdWJzY3JpYmVUcmFja2luZ0luZm9cbiAgKTogUHJvbWlzZTxVcGRhdGVkT3BlblRyYWNraW5nPiB7XG4gICAgaWYgKCEoJ2h0bWxfZm9vdGVyJyBpbiBkYXRhKSAmJiAhKCd0ZXh0X2Zvb3RlcicgaW4gZGF0YSkgJiYgdHlwZW9mIGRhdGE/LmFjdGl2ZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB0aHJvdyBuZXcgQVBJRXJyb3IoeyBzdGF0dXM6IDQwMCwgc3RhdHVzVGV4dDogJycsIGJvZHk6IHsgbWVzc2FnZTogJ1ZhbHVlIFwiYWN0aXZlXCIgbXVzdCBjb250YWluIHN0cmluZyB2YWx1ZS4nIH0gfSBhcyBBUElFcnJvck9wdGlvbnMpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnB1dFdpdGhGRCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ3RyYWNraW5nJywgdHlwZSksIGRhdGEpXG4gICAgICAudGhlbih0aGlzLl9wYXJzZVRyYWNraW5nVXBkYXRlKTtcbiAgfVxuXG4gIC8vIElQc1xuXG4gIGdldElwcyhkb21haW46IHN0cmluZyk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ2lwcycpKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlOiBBUElSZXNwb25zZSkgPT4gcmVzcG9uc2U/LmJvZHk/Lml0ZW1zKTtcbiAgfVxuXG4gIGFzc2lnbklwKGRvbWFpbjogc3RyaW5nLCBpcDogc3RyaW5nKTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ2lwcycpLCB7IGlwIH0pO1xuICB9XG5cbiAgZGVsZXRlSXAoZG9tYWluOiBzdHJpbmcsIGlwOiBzdHJpbmcpOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUodXJsam9pbignL3YyL2RvbWFpbnMnLCBkb21haW4sICdpcHMnLCBpcCkpO1xuICB9XG5cbiAgbGlua0lwUG9vbChkb21haW46IHN0cmluZywgcG9vbF9pZDogc3RyaW5nKTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ2lwcycpLCB7IHBvb2xfaWQgfSk7XG4gIH1cblxuICB1bmxpbmtJcFBvbGwoZG9tYWluOiBzdHJpbmcsIHBvb2xfaWQ6IHN0cmluZywgaXA6IHN0cmluZyk6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZSh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ2lwcycsICdpcF9wb29sJyksIHsgcG9vbF9pZCwgaXAgfSk7XG4gIH1cbn1cbiIsImltcG9ydCBBUElFcnJvck9wdGlvbnMgZnJvbSAnLi9pbnRlcmZhY2VzL0FQSUVycm9yT3B0aW9ucyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFQSUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBzdGF0dXM6IG51bWJlciB8IHN0cmluZztcbiAgc3RhY2s6IHN0cmluZztcbiAgZGV0YWlsczogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBzdGF0dXMsXG4gICAgc3RhdHVzVGV4dCxcbiAgICBtZXNzYWdlLFxuICAgIGJvZHkgPSB7fVxuICB9OiBBUElFcnJvck9wdGlvbnMpIHtcbiAgICBjb25zdCB7IG1lc3NhZ2U6IGJvZHlNZXNzYWdlLCBlcnJvciB9ID0gYm9keTtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5zdGFjayA9ICcnO1xuICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzO1xuICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2UgfHwgZXJyb3IgfHwgc3RhdHVzVGV4dDtcbiAgICB0aGlzLmRldGFpbHMgPSBib2R5TWVzc2FnZTtcbiAgfVxufVxuIiwiaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuaW1wb3J0IHtcbiAgRXZlbnRzTGlzdCwgRXZlbnRzUGFnZSwgRXZlbnRzUmVzcG9uc2UsIFBhZ2VzTGlzdCwgUGFnZXNMaXN0QWNjdW11bGF0b3Jcbn0gZnJvbSAnLi9pbnRlcmZhY2VzL0V2ZW50cyc7XG5cbmltcG9ydCBSZXF1ZXN0IGZyb20gJy4vcmVxdWVzdCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEV2ZW50Q2xpZW50IHtcbiAgcmVxdWVzdDogUmVxdWVzdDtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0KSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgfVxuXG4gIF9wYXJzZVBhZ2VOdW1iZXIodXJsOiBzdHJpbmcpIDogc3RyaW5nIHtcbiAgICByZXR1cm4gdXJsLnNwbGl0KCcvJykucG9wKCk7XG4gIH1cblxuICBfcGFyc2VQYWdlKGlkOiBzdHJpbmcsIHVybDogc3RyaW5nKSA6IEV2ZW50c1BhZ2Uge1xuICAgIHJldHVybiB7IGlkLCBudW1iZXI6IHRoaXMuX3BhcnNlUGFnZU51bWJlcih1cmwpLCB1cmwgfTtcbiAgfVxuXG4gIF9wYXJzZVBhZ2VMaW5rcyhyZXNwb25zZTogRXZlbnRzUmVzcG9uc2UpIDogUGFnZXNMaXN0IHtcbiAgICBjb25zdCBwYWdlcyA9IE9iamVjdC5lbnRyaWVzKHJlc3BvbnNlLmJvZHkucGFnaW5nIGFzIFBhZ2VzTGlzdCk7XG4gICAgcmV0dXJuIHBhZ2VzLnJlZHVjZShcbiAgICAgIChhY2M6IFBhZ2VzTGlzdEFjY3VtdWxhdG9yLCBlbnRyaWU6IFt1cmw6IHN0cmluZywgaWQ6IHN0cmluZ10pID0+IHtcbiAgICAgICAgY29uc3QgaWQgPSBlbnRyaWVbMF07XG4gICAgICAgIGNvbnN0IHVybCA9IGVudHJpZVsxXTtcbiAgICAgICAgYWNjW2lkXSA9IHRoaXMuX3BhcnNlUGFnZShpZCwgdXJsKTtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sIHt9XG4gICAgKSBhcyB1bmtub3duIGFzIFBhZ2VzTGlzdDtcbiAgfVxuXG4gIF9wYXJzZUV2ZW50TGlzdChyZXNwb25zZTogRXZlbnRzUmVzcG9uc2UpIDogRXZlbnRzTGlzdCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGl0ZW1zOiByZXNwb25zZS5ib2R5Lml0ZW1zLFxuICAgICAgcGFnZXM6IHRoaXMuX3BhcnNlUGFnZUxpbmtzKHJlc3BvbnNlKVxuICAgIH07XG4gIH1cblxuICBnZXQoZG9tYWluOiBzdHJpbmcsIHF1ZXJ5OiB7IHBhZ2U6IHN0cmluZyB9KSA6IFByb21pc2U8RXZlbnRzTGlzdD4ge1xuICAgIGxldCB1cmw7XG4gICAgY29uc3QgcXVlcnlDb3B5ID0geyAuLi5xdWVyeSB9O1xuICAgIGlmIChxdWVyeUNvcHkgJiYgcXVlcnlDb3B5LnBhZ2UpIHtcbiAgICAgIHVybCA9IHVybGpvaW4oJy92MicsIGRvbWFpbiwgJ2V2ZW50cycsIHF1ZXJ5Q29weS5wYWdlKTtcbiAgICAgIGRlbGV0ZSBxdWVyeUNvcHkucGFnZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdXJsID0gdXJsam9pbignL3YyJywgZG9tYWluLCAnZXZlbnRzJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybCwgcXVlcnlDb3B5KVxuICAgICAgLnRoZW4oKHJlc3BvbnNlOiBFdmVudHNSZXNwb25zZSkgPT4gdGhpcy5fcGFyc2VFdmVudExpc3QocmVzcG9uc2UpKTtcbiAgfVxufVxuIiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuXG5pbXBvcnQgeyBJcFBvb2wsIElwUG9vbExpc3RSZXNwb25zZSwgSXBQb29sVXBkYXRlRGF0YSB9IGZyb20gJy4vaW50ZXJmYWNlcy9JcFBvb2xzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSXBQb29sc0NsaWVudCB7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBsaXN0KHF1ZXJ5OiBhbnkpOiBQcm9taXNlPElwUG9vbFtdPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92MS9pcF9wb29scycsIHF1ZXJ5KVxuICAgICAgLnRoZW4oKHJlc3BvbnNlOiBJcFBvb2xMaXN0UmVzcG9uc2UpID0+IHRoaXMucGFyc2VJcFBvb2xzUmVzcG9uc2UocmVzcG9uc2UpKTtcbiAgfVxuXG4gIGNyZWF0ZShkYXRhOiB7IG5hbWU6IHN0cmluZywgZGVzY3JpcHRpb24/OiBzdHJpbmcsIGlwcz86IHN0cmluZ1tdIH0pIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3QoJy92MS9pcF9wb29scycsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2U6IHsgYm9keTogeyBtZXNzYWdlOiBzdHJpbmcsIHBvb2xfaWQ6IHN0cmluZyB9IH0pID0+IHJlc3BvbnNlPy5ib2R5KTtcbiAgfVxuXG4gIHVwZGF0ZShwb29sSWQ6IHN0cmluZywgZGF0YTogSXBQb29sVXBkYXRlRGF0YSkgOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucGF0Y2goYC92MS9pcF9wb29scy8ke3Bvb2xJZH1gLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlOiB7IGJvZHk6IGFueSB9KSA9PiByZXNwb25zZT8uYm9keSk7XG4gIH1cblxuICBkZWxldGUocG9vbElkOiBzdHJpbmcsIGRhdGE6IHsgaWQ6IHN0cmluZywgcG9vbF9pZDogc3RyaW5nIH0pIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZShgL3YxL2lwX3Bvb2xzLyR7cG9vbElkfWAsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2U6IHsgYm9keTogYW55IH0pID0+IHJlc3BvbnNlPy5ib2R5KTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VJcFBvb2xzUmVzcG9uc2UocmVzcG9uc2U6IHsgYm9keTogYW55IHwgYW55IH0pIHtcbiAgICByZXR1cm4gcmVzcG9uc2UuYm9keS5pcF9wb29scztcbiAgfVxufVxuIiwiaW1wb3J0IE1nUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuaW1wb3J0IHsgSXBEYXRhLCBJcHNMaXN0UmVzcG9uc2VCb2R5IH0gZnJvbSAnLi9pbnRlcmZhY2VzL0lwcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIElwc0NsaWVudCB7XG4gIHJlcXVlc3Q6IE1nUmVxdWVzdDtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBNZ1JlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICB9XG5cbiAgbGlzdChxdWVyeTogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92My9pcHMnLCBxdWVyeSlcbiAgICAgIC50aGVuKChyZXNwb25zZTogeyBib2R5OiBJcHNMaXN0UmVzcG9uc2VCb2R5IH0pID0+IHRoaXMucGFyc2VJcHNSZXNwb25zZShyZXNwb25zZSkpO1xuICB9XG5cbiAgZ2V0KGlwOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldChgL3YzL2lwcy8ke2lwfWApXG4gICAgICAudGhlbigocmVzcG9uc2U6IHsgYm9keTogSXBEYXRhIH0pID0+IHRoaXMucGFyc2VJcHNSZXNwb25zZShyZXNwb25zZSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUlwc1Jlc3BvbnNlKHJlc3BvbnNlOiB7IGJvZHk6IElwc0xpc3RSZXNwb25zZUJvZHkgfCBJcERhdGEgfSkge1xuICAgIHJldHVybiByZXNwb25zZS5ib2R5O1xuICB9XG59XG4iLCJpbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuaW1wb3J0IHtcbiAgTGlzdHNRdWVyeSxcbiAgQ3JlYXRlVXBkYXRlTGlzdCxcbiAgRGVzdHJveWVkTGlzdCxcbiAgTWFpbGluZ0xpc3Rcbn0gZnJvbSAnLi9pbnRlcmZhY2VzL2xpc3RzJztcbmltcG9ydCB7IElNYWlsTGlzdHNNZW1iZXJzIH0gZnJvbSAnLi9pbnRlcmZhY2VzL21haWxMaXN0TWVtYmVycyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExpc3RzQ2xpZW50IHtcbiAgYmFzZVJvdXRlOiBzdHJpbmc7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG4gIG1lbWJlcnM6IElNYWlsTGlzdHNNZW1iZXJzO1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QsIG1lbWJlcnM6SU1haWxMaXN0c01lbWJlcnMpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICAgIHRoaXMuYmFzZVJvdXRlID0gJy92My9saXN0cyc7XG4gICAgdGhpcy5tZW1iZXJzID0gbWVtYmVycztcbiAgfVxuXG4gIGxpc3QocXVlcnk/OiBMaXN0c1F1ZXJ5KTogUHJvbWlzZTxNYWlsaW5nTGlzdFtdPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoYCR7dGhpcy5iYXNlUm91dGV9L3BhZ2VzYCwgcXVlcnkpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkuaXRlbXMgYXMgTWFpbGluZ0xpc3RbXSk7XG4gIH1cblxuICBnZXQobWFpbExpc3RBZGRyZXNzOiBzdHJpbmcpOiBQcm9taXNlPE1haWxpbmdMaXN0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfWApXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkubGlzdCBhcyBNYWlsaW5nTGlzdCk7XG4gIH1cblxuICBjcmVhdGUoZGF0YTogQ3JlYXRlVXBkYXRlTGlzdCk6IFByb21pc2U8TWFpbGluZ0xpc3Q+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQodGhpcy5iYXNlUm91dGUsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkubGlzdCBhcyBNYWlsaW5nTGlzdCk7XG4gIH1cblxuICB1cGRhdGUobWFpbExpc3RBZGRyZXNzOiBzdHJpbmcsIGRhdGE6IENyZWF0ZVVwZGF0ZUxpc3QpOiBQcm9taXNlPE1haWxpbmdMaXN0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXRXaXRoRkQoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfWAsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkubGlzdCBhcyBNYWlsaW5nTGlzdCk7XG4gIH1cblxuICBkZXN0cm95KG1haWxMaXN0QWRkcmVzczogc3RyaW5nKTogUHJvbWlzZTxEZXN0cm95ZWRMaXN0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfWApXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkgYXMgRGVzdHJveWVkTGlzdCk7XG4gIH1cbn1cbiIsImltcG9ydCBSZXF1ZXN0IGZyb20gJy4vcmVxdWVzdCc7XG5pbXBvcnQge1xuICBNYWlsTGlzdE1lbWJlcnNRdWVyeSxcbiAgSU1haWxMaXN0c01lbWJlcnMsXG4gIENyZWF0ZVVwZGF0ZU1haWxMaXN0TWVtYmVycyxcbiAgTWFpbExpc3RNZW1iZXIsXG4gIE11bHRpcGxlTWVtYmVyc0RhdGEsXG4gIE11bHRpcGxlTWVtYmVyc1JlcURhdGEsXG4gIERlbGV0ZWRNZW1iZXIsXG4gIENyZWF0ZVVwZGF0ZU1haWxMaXN0TWVtYmVyc1JlcSxcbiAgTmV3TXVsdGlwbGVNZW1iZXJzUmVzcG9uc2Vcbn0gZnJvbSAnLi9pbnRlcmZhY2VzL21haWxMaXN0TWVtYmVycyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1haWxMaXN0c01lbWJlcnMgaW1wbGVtZW50cyBJTWFpbExpc3RzTWVtYmVycyB7XG4gIGJhc2VSb3V0ZTogc3RyaW5nO1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICAgIHRoaXMuYmFzZVJvdXRlID0gJy92My9saXN0cyc7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrQW5kVXBkYXRlRGF0YShkYXRhOiBDcmVhdGVVcGRhdGVNYWlsTGlzdE1lbWJlcnMpIHtcbiAgICBjb25zdCBuZXdEYXRhID0geyAuLi5kYXRhIH07XG5cbiAgICBpZiAodHlwZW9mIGRhdGEudmFycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgIG5ld0RhdGEudmFycyA9IEpTT04uc3RyaW5naWZ5KG5ld0RhdGEudmFycyk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBkYXRhLnN1YnNjcmliZWQgPT09ICdib29sZWFuJykge1xuICAgICAgbmV3RGF0YS5zdWJzY3JpYmVkID0gZGF0YS5zdWJzY3JpYmVkID8gJ3llcycgOiAnbm8nO1xuICAgIH1cblxuICAgIHJldHVybiBuZXdEYXRhIGFzIENyZWF0ZVVwZGF0ZU1haWxMaXN0TWVtYmVyc1JlcTtcbiAgfVxuXG4gIGxpc3RNZW1iZXJzKG1haWxMaXN0QWRkcmVzczogc3RyaW5nLCBxdWVyeT86IE1haWxMaXN0TWVtYmVyc1F1ZXJ5KTogUHJvbWlzZTxNYWlsTGlzdE1lbWJlcltdPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfS9tZW1iZXJzL3BhZ2VzYCwgcXVlcnkpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkuaXRlbXMgYXMgTWFpbExpc3RNZW1iZXJbXSk7XG4gIH1cblxuICBnZXRNZW1iZXIobWFpbExpc3RBZGRyZXNzOiBzdHJpbmcsIG1haWxMaXN0TWVtYmVyQWRkcmVzczogc3RyaW5nKTogUHJvbWlzZTxNYWlsTGlzdE1lbWJlcj4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KGAke3RoaXMuYmFzZVJvdXRlfS8ke21haWxMaXN0QWRkcmVzc30vbWVtYmVycy8ke21haWxMaXN0TWVtYmVyQWRkcmVzc31gKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5Lm1lbWJlciBhcyBNYWlsTGlzdE1lbWJlcik7XG4gIH1cblxuICBjcmVhdGVNZW1iZXIoXG4gICAgbWFpbExpc3RBZGRyZXNzOiBzdHJpbmcsXG4gICAgZGF0YTogQ3JlYXRlVXBkYXRlTWFpbExpc3RNZW1iZXJzXG4gICk6IFByb21pc2U8TWFpbExpc3RNZW1iZXI+IHtcbiAgICBjb25zdCByZXFEYXRhID0gdGhpcy5jaGVja0FuZFVwZGF0ZURhdGEoZGF0YSk7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wb3N0V2l0aEZEKGAke3RoaXMuYmFzZVJvdXRlfS8ke21haWxMaXN0QWRkcmVzc30vbWVtYmVyc2AsIHJlcURhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkubWVtYmVyIGFzIE1haWxMaXN0TWVtYmVyKTtcbiAgfVxuXG4gIGNyZWF0ZU1lbWJlcnMoXG4gICAgbWFpbExpc3RBZGRyZXNzOiBzdHJpbmcsXG4gICAgZGF0YTogTXVsdGlwbGVNZW1iZXJzRGF0YVxuICApOiBQcm9taXNlPE5ld011bHRpcGxlTWVtYmVyc1Jlc3BvbnNlPiB7XG4gICAgY29uc3QgbmV3RGF0YTogTXVsdGlwbGVNZW1iZXJzUmVxRGF0YSA9IHtcbiAgICAgIG1lbWJlcnM6IEFycmF5LmlzQXJyYXkoZGF0YS5tZW1iZXJzKSA/IEpTT04uc3RyaW5naWZ5KGRhdGEubWVtYmVycykgOiBkYXRhLm1lbWJlcnMsXG4gICAgICB1cHNlcnQ6IGRhdGEudXBzZXJ0XG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRChgJHt0aGlzLmJhc2VSb3V0ZX0vJHttYWlsTGlzdEFkZHJlc3N9L21lbWJlcnMuanNvbmAsIG5ld0RhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkgYXMgTmV3TXVsdGlwbGVNZW1iZXJzUmVzcG9uc2UpO1xuICB9XG5cbiAgdXBkYXRlTWVtYmVyKFxuICAgIG1haWxMaXN0QWRkcmVzczogc3RyaW5nLFxuICAgIG1haWxMaXN0TWVtYmVyQWRkcmVzczogc3RyaW5nLFxuICAgIGRhdGE6IENyZWF0ZVVwZGF0ZU1haWxMaXN0TWVtYmVyc1xuICApOiBQcm9taXNlPE1haWxMaXN0TWVtYmVyPiB7XG4gICAgY29uc3QgcmVxRGF0YSA9IHRoaXMuY2hlY2tBbmRVcGRhdGVEYXRhKGRhdGEpO1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucHV0V2l0aEZEKGAke3RoaXMuYmFzZVJvdXRlfS8ke21haWxMaXN0QWRkcmVzc30vbWVtYmVycy8ke21haWxMaXN0TWVtYmVyQWRkcmVzc31gLCByZXFEYXRhKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5Lm1lbWJlciBhcyBNYWlsTGlzdE1lbWJlcik7XG4gIH1cblxuICBkZXN0cm95TWVtYmVyKG1haWxMaXN0QWRkcmVzczogc3RyaW5nLCBtYWlsTGlzdE1lbWJlckFkZHJlc3M6IHN0cmluZykgOiBQcm9taXNlPERlbGV0ZWRNZW1iZXI+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZShgJHt0aGlzLmJhc2VSb3V0ZX0vJHttYWlsTGlzdEFkZHJlc3N9L21lbWJlcnMvJHttYWlsTGlzdE1lbWJlckFkZHJlc3N9YClcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuYm9keSBhcyBEZWxldGVkTWVtYmVyKTtcbiAgfVxufVxuIiwiaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi9yZXF1ZXN0JztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWVzc2FnZXNDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICB9XG5cbiAgX3BhcnNlUmVzcG9uc2UocmVzcG9uc2U6IHsgYm9keTogYW55IH0pIHtcbiAgICBpZiAocmVzcG9uc2UuYm9keSkge1xuICAgICAgcmV0dXJuIHJlc3BvbnNlLmJvZHk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3BvbnNlO1xuICB9XG5cbiAgY3JlYXRlKGRvbWFpbjogc3RyaW5nLCBkYXRhOiBhbnkpIHtcbiAgICBpZiAoZGF0YS5tZXNzYWdlKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQoYC92My8ke2RvbWFpbn0vbWVzc2FnZXMubWltZWAsIGRhdGEpXG4gICAgICAgIC50aGVuKHRoaXMuX3BhcnNlUmVzcG9uc2UpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRChgL3YzLyR7ZG9tYWlufS9tZXNzYWdlc2AsIGRhdGEpXG4gICAgICAudGhlbih0aGlzLl9wYXJzZVJlc3BvbnNlKTtcbiAgfVxufVxuIiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQYXJzZUNsaWVudCB7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBnZXQoYWRkcmVzc2VzOiBzdHJpbmdbXSB8IHN0cmluZywgZW5hYmxlRG5zRXNwQ2hlY2tzOiBib29sZWFuKSB7XG4gICAgY29uc3QgcXVlcnkgPSB7fSBhcyB7IGFkZHJlc3Nlczogc3RyaW5nLCBzeW50YXhfb25seTogYm9vbGVhbiB9O1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYWRkcmVzc2VzKSkge1xuICAgICAgcXVlcnkuYWRkcmVzc2VzID0gYWRkcmVzc2VzLmpvaW4oJywnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcXVlcnkuYWRkcmVzc2VzID0gYWRkcmVzc2VzO1xuICAgIH1cblxuICAgIGlmIChlbmFibGVEbnNFc3BDaGVja3MpIHtcbiAgICAgIHF1ZXJ5LnN5bnRheF9vbmx5ID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92My9hZGRyZXNzL3BhcnNlJywgcXVlcnkpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkpO1xuICB9XG59XG4iLCJpbXBvcnQgTm9kZUZvcm1EYXRhIGZyb20gJ2Zvcm0tZGF0YSc7XG5pbXBvcnQgYmFzZTY0IGZyb20gJ2Jhc2UtNjQnO1xuaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuaW1wb3J0IGt5IGZyb20gJ2t5LXVuaXZlcnNhbCc7XG5pbXBvcnQgQVBJRXJyb3IgZnJvbSAnLi9lcnJvcic7XG5pbXBvcnQgUmVxdWVzdE9wdGlvbnMgZnJvbSAnLi9pbnRlcmZhY2VzL1JlcXVlc3RPcHRpb25zJztcbmltcG9ydCBBUElFcnJvck9wdGlvbnMgZnJvbSAnLi9pbnRlcmZhY2VzL0FQSUVycm9yT3B0aW9ucyc7XG5pbXBvcnQgeyBJbnB1dEZvcm1EYXRhIH0gZnJvbSAnLi9pbnRlcmZhY2VzL0lGb3JtRGF0YSc7XG5pbXBvcnQgQVBJUmVzcG9uc2UgZnJvbSAnLi9pbnRlcmZhY2VzL0FwaVJlc3BvbnNlJztcblxuY29uc3QgaXNTdHJlYW0gPSAoYXR0YWNobWVudDogYW55KSA9PiB0eXBlb2YgYXR0YWNobWVudCA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIGF0dGFjaG1lbnQucGlwZSA9PT0gJ2Z1bmN0aW9uJztcblxuZnVuY3Rpb24gaXNOb2RlRm9ybURhdGEoZm9ybURhdGFJbnN0YW5jZTogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGEpXG4gIDogZm9ybURhdGFJbnN0YW5jZSBpcyBOb2RlRm9ybURhdGEge1xuICByZXR1cm4gKDxOb2RlRm9ybURhdGE+Zm9ybURhdGFJbnN0YW5jZSkuZ2V0SGVhZGVycyAhPT0gdW5kZWZpbmVkO1xufVxuXG5jb25zdCBnZXRBdHRhY2htZW50T3B0aW9ucyA9IChpdGVtOiBhbnkpOiB7XG4gIGZpbGVuYW1lPzogc3RyaW5nLFxuICBjb250ZW50VHlwZT86IHN0cmluZyxcbiAga25vd25MZW5ndGg/OiBudW1iZXJcbn0gPT4ge1xuICBpZiAodHlwZW9mIGl0ZW0gIT09ICdvYmplY3QnIHx8IGlzU3RyZWFtKGl0ZW0pKSByZXR1cm4ge307XG5cbiAgY29uc3Qge1xuICAgIGZpbGVuYW1lLFxuICAgIGNvbnRlbnRUeXBlLFxuICAgIGtub3duTGVuZ3RoXG4gIH0gPSBpdGVtO1xuXG4gIHJldHVybiB7XG4gICAgLi4uKGZpbGVuYW1lID8geyBmaWxlbmFtZSB9IDogeyBmaWxlbmFtZTogJ2ZpbGUnIH0pLFxuICAgIC4uLihjb250ZW50VHlwZSAmJiB7IGNvbnRlbnRUeXBlIH0pLFxuICAgIC4uLihrbm93bkxlbmd0aCAmJiB7IGtub3duTGVuZ3RoIH0pXG4gIH07XG59O1xuXG5jb25zdCBzdHJlYW1Ub1N0cmluZyA9IChzdHJlYW06IGFueSkgPT4ge1xuICBjb25zdCBjaHVua3M6IGFueSA9IFtdO1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIHN0cmVhbS5vbignZGF0YScsIChjaHVuazogYW55KSA9PiBjaHVua3MucHVzaChjaHVuaykpO1xuICAgIHN0cmVhbS5vbignZXJyb3InLCByZWplY3QpO1xuICAgIHN0cmVhbS5vbignZW5kJywgKCkgPT4gcmVzb2x2ZShCdWZmZXIuY29uY2F0KGNodW5rcykudG9TdHJpbmcoJ3V0ZjgnKSkpO1xuICB9KTtcbn07XG5cbmNsYXNzIFJlcXVlc3Qge1xuICBwcml2YXRlIHVzZXJuYW1lOiBzdHJpbmc7XG4gIHByaXZhdGUga2V5OiBzdHJpbmc7XG4gIHByaXZhdGUgdXJsOiBzdHJpbmc7XG4gIHByaXZhdGUgdGltZW91dDogbnVtYmVyO1xuICBwcml2YXRlIGhlYWRlcnM6IGFueTtcbiAgcHJpdmF0ZSBmb3JtRGF0YTogSW5wdXRGb3JtRGF0YTtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBSZXF1ZXN0T3B0aW9ucywgZm9ybURhdGE6IElucHV0Rm9ybURhdGEpIHtcbiAgICB0aGlzLnVzZXJuYW1lID0gb3B0aW9ucy51c2VybmFtZTtcbiAgICB0aGlzLmtleSA9IG9wdGlvbnMua2V5O1xuICAgIHRoaXMudXJsID0gb3B0aW9ucy51cmwgYXMgc3RyaW5nO1xuICAgIHRoaXMudGltZW91dCA9IG9wdGlvbnMudGltZW91dDtcbiAgICB0aGlzLmhlYWRlcnMgPSBvcHRpb25zLmhlYWRlcnMgfHwge307XG4gICAgdGhpcy5mb3JtRGF0YSA9IGZvcm1EYXRhO1xuICB9XG5cbiAgYXN5bmMgcmVxdWVzdChtZXRob2Q6IHN0cmluZywgdXJsOiBzdHJpbmcsIGlucHV0T3B0aW9ucz86IGFueSk6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICBjb25zdCBvcHRpb25zID0geyAuLi5pbnB1dE9wdGlvbnMgfTtcbiAgICBjb25zdCBiYXNpYyA9IGJhc2U2NC5lbmNvZGUoYCR7dGhpcy51c2VybmFtZX06JHt0aGlzLmtleX1gKTtcbiAgICBjb25zdCBoZWFkZXJzID0ge1xuICAgICAgQXV0aG9yaXphdGlvbjogYEJhc2ljICR7YmFzaWN9YCxcbiAgICAgIC4uLnRoaXMuaGVhZGVycyxcbiAgICAgIC4uLm9wdGlvbnM/LmhlYWRlcnNcbiAgICB9O1xuXG4gICAgZGVsZXRlIG9wdGlvbnM/LmhlYWRlcnM7XG5cbiAgICBpZiAoIWhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddKSB7XG4gICAgICAvLyBmb3IgZm9ybS1kYXRhIGl0IHdpbGwgYmUgTnVsbCBzbyB3ZSBuZWVkIHRvIHJlbW92ZSBpdFxuICAgICAgZGVsZXRlIGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddO1xuICAgIH1cblxuICAgIGNvbnN0IHBhcmFtcyA9IHsgLi4ub3B0aW9ucyB9O1xuXG4gICAgaWYgKG9wdGlvbnM/LnF1ZXJ5ICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG9wdGlvbnM/LnF1ZXJ5KS5sZW5ndGggPiAwKSB7XG4gICAgICBwYXJhbXMuc2VhcmNoUGFyYW1zID0gb3B0aW9ucy5xdWVyeTtcbiAgICAgIGRlbGV0ZSBwYXJhbXMucXVlcnk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBreShcbiAgICAgIHVybGpvaW4odGhpcy51cmwsIHVybCksXG4gICAgICB7XG4gICAgICAgIG1ldGhvZDogbWV0aG9kLnRvTG9jYWxlVXBwZXJDYXNlKCksXG4gICAgICAgIGhlYWRlcnMsXG4gICAgICAgIHRocm93SHR0cEVycm9yczogZmFsc2UsXG4gICAgICAgIHRpbWVvdXQ6IHRoaXMudGltZW91dCxcbiAgICAgICAgLi4ucGFyYW1zXG4gICAgICB9XG4gICAgKTtcblxuICAgIGlmICghcmVzcG9uc2U/Lm9rKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gcmVzcG9uc2U/LmJvZHkgJiYgaXNTdHJlYW0ocmVzcG9uc2UuYm9keSlcbiAgICAgICAgPyBhd2FpdCBzdHJlYW1Ub1N0cmluZyhyZXNwb25zZS5ib2R5KVxuICAgICAgICA6IGF3YWl0IHJlc3BvbnNlPy5qc29uKCk7XG5cbiAgICAgIHRocm93IG5ldyBBUElFcnJvcih7XG4gICAgICAgIHN0YXR1czogcmVzcG9uc2U/LnN0YXR1cyxcbiAgICAgICAgc3RhdHVzVGV4dDogcmVzcG9uc2U/LnN0YXR1c1RleHQsXG4gICAgICAgIGJvZHk6IHsgbWVzc2FnZSB9XG4gICAgICB9IGFzIEFQSUVycm9yT3B0aW9ucyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGJvZHk6IGF3YWl0IHJlc3BvbnNlPy5qc29uKCksXG4gICAgICBzdGF0dXM6IHJlc3BvbnNlPy5zdGF0dXNcbiAgICB9O1xuICB9XG5cbiAgcXVlcnkobWV0aG9kOiBzdHJpbmcsIHVybDogc3RyaW5nLCBxdWVyeTogYW55LCBvcHRpb25zPzogYW55KSA6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KG1ldGhvZCwgdXJsLCB7IHF1ZXJ5LCAuLi5vcHRpb25zIH0pO1xuICB9XG5cbiAgY29tbWFuZChtZXRob2Q6IHN0cmluZywgdXJsOiBzdHJpbmcsIGRhdGE6IGFueSwgb3B0aW9ucz86IGFueSkgOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdChtZXRob2QsIHVybCwge1xuICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcgfSxcbiAgICAgIGJvZHk6IGRhdGEsXG4gICAgICAuLi5vcHRpb25zXG4gICAgfSk7XG4gIH1cblxuICBnZXQodXJsOiBzdHJpbmcsIHF1ZXJ5PzogYW55LCBvcHRpb25zPzogYW55KSA6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeSgnZ2V0JywgdXJsLCBxdWVyeSwgb3B0aW9ucyk7XG4gIH1cblxuICBoZWFkKHVybDogc3RyaW5nLCBxdWVyeTogYW55LCBvcHRpb25zOiBhbnkpIDogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5KCdoZWFkJywgdXJsLCBxdWVyeSwgb3B0aW9ucyk7XG4gIH1cblxuICBvcHRpb25zKHVybDogc3RyaW5nLCBxdWVyeTogYW55LCBvcHRpb25zOiBhbnkpIDogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5KCdvcHRpb25zJywgdXJsLCBxdWVyeSwgb3B0aW9ucyk7XG4gIH1cblxuICBwb3N0KHVybDogc3RyaW5nLCBkYXRhOiBhbnksIG9wdGlvbnM/OiBhbnkpIDogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLmNvbW1hbmQoJ3Bvc3QnLCB1cmwsIGRhdGEsIG9wdGlvbnMpO1xuICB9XG5cbiAgcG9zdFdpdGhGRCh1cmw6IHN0cmluZywgZGF0YTogYW55KTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIGNvbnN0IHBhcmFtczogYW55ID0ge1xuICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogbnVsbCB9XG4gICAgfTtcbiAgICBjb25zdCBmb3JtRGF0YSA9IHRoaXMuY3JlYXRlRm9ybURhdGEoZGF0YSk7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZCgncG9zdCcsIHVybCwgZm9ybURhdGEsIHBhcmFtcyk7XG4gIH1cblxuICBwdXRXaXRoRkQodXJsOiBzdHJpbmcsIGRhdGE6IGFueSk6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICBjb25zdCBwYXJhbXM6IGFueSA9IHtcbiAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6IG51bGwgfVxuICAgIH07XG4gICAgY29uc3QgZm9ybURhdGEgPSB0aGlzLmNyZWF0ZUZvcm1EYXRhKGRhdGEpO1xuICAgIHJldHVybiB0aGlzLmNvbW1hbmQoJ3B1dCcsIHVybCwgZm9ybURhdGEsIHBhcmFtcyk7XG4gIH1cblxuICBjcmVhdGVGb3JtRGF0YShkYXRhOiBhbnkpOiBOb2RlRm9ybURhdGEgfCBGb3JtRGF0YSB7XG4gICAgY29uc3QgYXBwZW5kRmlsZVRvRkQgPSAoXG4gICAgICBrZXk6IHN0cmluZyxcbiAgICAgIG9iajogYW55LFxuICAgICAgZm9ybURhdGFJbnN0YW5jZTogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGFcbiAgICApOiB2b2lkID0+IHtcbiAgICAgIGNvbnN0IGlzU3RyZWFtRGF0YSA9IGlzU3RyZWFtKG9iaik7XG4gICAgICBjb25zdCBvYmpEYXRhID0gaXNTdHJlYW1EYXRhID8gb2JqIDogb2JqLmRhdGE7XG4gICAgICBjb25zdCBvcHRpb25zID0gZ2V0QXR0YWNobWVudE9wdGlvbnMob2JqKTtcbiAgICAgIGlmIChpc05vZGVGb3JtRGF0YShmb3JtRGF0YUluc3RhbmNlKSkge1xuICAgICAgICBmb3JtRGF0YUluc3RhbmNlLmFwcGVuZChrZXksIG9iakRhdGEsIG9wdGlvbnMpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBmb3JtRGF0YUluc3RhbmNlLmFwcGVuZChrZXksIG9iakRhdGEsIG9wdGlvbnMuZmlsZW5hbWUpO1xuICAgIH07XG5cbiAgICBjb25zdCBmb3JtRGF0YTogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGEgPSBPYmplY3Qua2V5cyhkYXRhKVxuICAgICAgLmZpbHRlcihmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBkYXRhW2tleV07IH0pXG4gICAgICAucmVkdWNlKChmb3JtRGF0YUFjYzogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGEsIGtleSkgPT4ge1xuICAgICAgICBpZiAoa2V5ID09PSAnYXR0YWNobWVudCcgfHwga2V5ID09PSAnaW5saW5lJykge1xuICAgICAgICAgIGNvbnN0IG9iaiA9IGRhdGFba2V5XTtcblxuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICAgICAgICAgIG9iai5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICAgIGFwcGVuZEZpbGVUb0ZEKGtleSwgaXRlbSwgZm9ybURhdGFBY2MpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFwcGVuZEZpbGVUb0ZEKGtleSwgb2JqLCBmb3JtRGF0YUFjYyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGZvcm1EYXRhQWNjO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YVtrZXldKSkge1xuICAgICAgICAgIGRhdGFba2V5XS5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtOiBhbnkpIHtcbiAgICAgICAgICAgIGZvcm1EYXRhQWNjLmFwcGVuZChrZXksIGl0ZW0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKGRhdGFba2V5XSAhPSBudWxsKSB7XG4gICAgICAgICAgZm9ybURhdGFBY2MuYXBwZW5kKGtleSwgZGF0YVtrZXldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZm9ybURhdGFBY2M7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbmV3LWNhcFxuICAgICAgfSwgbmV3IHRoaXMuZm9ybURhdGEoKSk7XG4gICAgcmV0dXJuIGZvcm1EYXRhO1xuICB9XG5cbiAgcHV0KHVybDogc3RyaW5nLCBkYXRhOiBhbnksIG9wdGlvbnM/OiBhbnkpOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZCgncHV0JywgdXJsLCBkYXRhLCBvcHRpb25zKTtcbiAgfVxuXG4gIHBhdGNoKHVybDogc3RyaW5nLCBkYXRhOiBhbnksIG9wdGlvbnM/OiBhbnkpOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZCgncGF0Y2gnLCB1cmwsIGRhdGEsIG9wdGlvbnMpO1xuICB9XG5cbiAgZGVsZXRlKHVybDogc3RyaW5nLCBkYXRhPzogYW55LCBvcHRpb25zPzogYW55KTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLmNvbW1hbmQoJ2RlbGV0ZScsIHVybCwgZGF0YSwgb3B0aW9ucyk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUmVxdWVzdDtcbiIsImltcG9ydCB7XG4gIENyZWF0ZVVwZGF0ZVJvdXRlRGF0YSwgRGVzdHJveVJvdXRlUmVzcG9uc2UsIFJvdXRlLCBSb3V0ZXNMaXN0UXVlcnksIFVwZGF0ZVJvdXRlUmVzcG9uc2Vcbn0gZnJvbSAnLi9pbnRlcmZhY2VzL3JvdXRlcyc7XG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSb3V0ZXNDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICB9XG5cbiAgbGlzdChxdWVyeTogUm91dGVzTGlzdFF1ZXJ5KTogUHJvbWlzZTxSb3V0ZVtdPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92My9yb3V0ZXMnLCBxdWVyeSlcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuYm9keS5pdGVtcyk7XG4gIH1cblxuICBnZXQoaWQ6IHN0cmluZyk6IFByb21pc2U8Um91dGU+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldChgL3YzL3JvdXRlcy8ke2lkfWApXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkucm91dGUpO1xuICB9XG5cbiAgY3JlYXRlKGRhdGE6IENyZWF0ZVVwZGF0ZVJvdXRlRGF0YSk6IFByb21pc2U8Um91dGU+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQoJy92My9yb3V0ZXMnLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5LnJvdXRlKTtcbiAgfVxuXG4gIHVwZGF0ZShpZDogc3RyaW5nLCBkYXRhOiBDcmVhdGVVcGRhdGVSb3V0ZURhdGEpOiBQcm9taXNlPFVwZGF0ZVJvdXRlUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnB1dFdpdGhGRChgL3YzL3JvdXRlcy8ke2lkfWAsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkpO1xuICB9XG5cbiAgZGVzdHJveShpZDogc3RyaW5nKTogUHJvbWlzZTxEZXN0cm95Um91dGVSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZGVsZXRlKGAvdjMvcm91dGVzLyR7aWR9YClcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuYm9keSk7XG4gIH1cbn1cbiIsImltcG9ydCB1cmxqb2luIGZyb20gJ3VybC1qb2luJztcbmltcG9ydCBSZXF1ZXN0IGZyb20gJy4vcmVxdWVzdCc7XG5pbXBvcnQgU3RhdHNPcHRpb25zIGZyb20gJy4vaW50ZXJmYWNlcy9TdGF0c09wdGlvbnMnO1xuXG5jbGFzcyBTdGF0cyB7XG4gIHN0YXJ0OiBEYXRlO1xuICBlbmQ6IERhdGU7XG4gIHJlc29sdXRpb246IHN0cmluZztcbiAgc3RhdHM6IGFueTtcblxuICBjb25zdHJ1Y3RvcihkYXRhOiBTdGF0c09wdGlvbnMpIHtcbiAgICB0aGlzLnN0YXJ0ID0gbmV3IERhdGUoZGF0YS5zdGFydCk7XG4gICAgdGhpcy5lbmQgPSBuZXcgRGF0ZShkYXRhLmVuZCk7XG4gICAgdGhpcy5yZXNvbHV0aW9uID0gZGF0YS5yZXNvbHV0aW9uO1xuICAgIHRoaXMuc3RhdHMgPSBkYXRhLnN0YXRzLm1hcChmdW5jdGlvbiAoc3RhdDogeyB0aW1lOiBzdHJpbmcgfCBEYXRlIH0pIHtcbiAgICAgIGNvbnN0IHJlcyA9IHsgLi4uc3RhdCB9O1xuICAgICAgcmVzLnRpbWUgPSBuZXcgRGF0ZShzdGF0LnRpbWUpO1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTdGF0c0NsaWVudCB7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBfcGFyc2VTdGF0cyhyZXNwb25zZTogeyBib2R5OiBTdGF0c09wdGlvbnMgfSkge1xuICAgIHJldHVybiBuZXcgU3RhdHMocmVzcG9uc2UuYm9keSk7XG4gIH1cblxuICBnZXREb21haW4oZG9tYWluOiBzdHJpbmcsIHF1ZXJ5OiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCh1cmxqb2luKCcvdjMnLCBkb21haW4sICdzdGF0cy90b3RhbCcpLCBxdWVyeSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlU3RhdHMpO1xuICB9XG5cbiAgZ2V0QWNjb3VudChxdWVyeTogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92My9zdGF0cy90b3RhbCcsIHF1ZXJ5KVxuICAgICAgLnRoZW4odGhpcy5fcGFyc2VTdGF0cyk7XG4gIH1cbn1cbiIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuaW1wb3J0IHVybCBmcm9tICd1cmwnO1xuaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuXG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuaW1wb3J0IHsgQm91bmNlRGF0YSwgQ29tcGxhaW50RGF0YSwgVW5zdWJzY3JpYmVEYXRhIH0gZnJvbSAnLi9pbnRlcmZhY2VzL1N1cHJlc3Npb25zJztcblxuY29uc3QgY3JlYXRlT3B0aW9ucyA9IHtcbiAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH1cbn07XG5cbmNsYXNzIEJvdW5jZSB7XG4gIHR5cGU6IHN0cmluZztcbiAgYWRkcmVzczogc3RyaW5nO1xuICBjb2RlOiBudW1iZXI7XG4gIGVycm9yOiBzdHJpbmc7XG4gIGNyZWF0ZWRfYXQ6IERhdGU7XG5cbiAgY29uc3RydWN0b3IoZGF0YTogQm91bmNlRGF0YSkge1xuICAgIHRoaXMudHlwZSA9ICdib3VuY2VzJztcbiAgICB0aGlzLmFkZHJlc3MgPSBkYXRhLmFkZHJlc3M7XG4gICAgdGhpcy5jb2RlID0gK2RhdGEuY29kZTtcbiAgICB0aGlzLmVycm9yID0gZGF0YS5lcnJvcjtcbiAgICB0aGlzLmNyZWF0ZWRfYXQgPSBuZXcgRGF0ZShkYXRhLmNyZWF0ZWRfYXQpO1xuICB9XG59XG5cbmNsYXNzIENvbXBsYWludCB7XG4gIHR5cGU6IHN0cmluZztcbiAgYWRkcmVzczogYW55O1xuICBjcmVhdGVkX2F0OiBEYXRlO1xuXG4gIGNvbnN0cnVjdG9yKGRhdGE6IENvbXBsYWludERhdGEpIHtcbiAgICB0aGlzLnR5cGUgPSAnY29tcGxhaW50cyc7XG4gICAgdGhpcy5hZGRyZXNzID0gZGF0YS5hZGRyZXNzO1xuICAgIHRoaXMuY3JlYXRlZF9hdCA9IG5ldyBEYXRlKGRhdGEuY3JlYXRlZF9hdCk7XG4gIH1cbn1cblxuY2xhc3MgVW5zdWJzY3JpYmUge1xuICB0eXBlOiBzdHJpbmc7XG4gIGFkZHJlc3M6IHN0cmluZztcbiAgdGFnczogYW55O1xuICBjcmVhdGVkX2F0OiBEYXRlO1xuXG4gIGNvbnN0cnVjdG9yKGRhdGE6IFVuc3Vic2NyaWJlRGF0YSkge1xuICAgIHRoaXMudHlwZSA9ICd1bnN1YnNjcmliZXMnO1xuICAgIHRoaXMuYWRkcmVzcyA9IGRhdGEuYWRkcmVzcztcbiAgICB0aGlzLnRhZ3MgPSBkYXRhLnRhZ3M7XG4gICAgdGhpcy5jcmVhdGVkX2F0ID0gbmV3IERhdGUoZGF0YS5jcmVhdGVkX2F0KTtcbiAgfVxufVxuXG50eXBlIFRNb2RlbCA9IHR5cGVvZiBCb3VuY2UgfCB0eXBlb2YgQ29tcGxhaW50IHwgdHlwZW9mIFVuc3Vic2NyaWJlO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTdXBwcmVzc2lvbkNsaWVudCB7XG4gIHJlcXVlc3Q6IGFueTtcbiAgbW9kZWxzOiB7XG4gICAgYm91bmNlczogdHlwZW9mIEJvdW5jZTtcbiAgICBjb21wbGFpbnRzOiB0eXBlb2YgQ29tcGxhaW50O1xuICAgIHVuc3Vic2NyaWJlczogdHlwZW9mIFVuc3Vic2NyaWJlO1xuICB9O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICAgIHRoaXMubW9kZWxzID0ge1xuICAgICAgYm91bmNlczogQm91bmNlLFxuICAgICAgY29tcGxhaW50czogQ29tcGxhaW50LFxuICAgICAgdW5zdWJzY3JpYmVzOiBVbnN1YnNjcmliZVxuICAgIH07XG4gIH1cblxuICBfcGFyc2VQYWdlKGlkOiBzdHJpbmcsIHBhZ2VVcmw6IHN0cmluZykge1xuICAgIGNvbnN0IHBhcnNlZFVybCA9IHVybC5wYXJzZShwYWdlVXJsLCB0cnVlKTtcbiAgICBjb25zdCB7IHF1ZXJ5IH0gPSBwYXJzZWRVcmw7XG5cbiAgICByZXR1cm4ge1xuICAgICAgaWQsXG4gICAgICBwYWdlOiBxdWVyeS5wYWdlLFxuICAgICAgYWRkcmVzczogcXVlcnkuYWRkcmVzcyxcbiAgICAgIHVybDogcGFnZVVybFxuICAgIH07XG4gIH1cblxuICBfcGFyc2VQYWdlTGlua3MocmVzcG9uc2U6IHsgYm9keTogeyBwYWdpbmc6IGFueSB9IH0pIHtcbiAgICBjb25zdCBwYWdlcyA9IE9iamVjdC5lbnRyaWVzKHJlc3BvbnNlLmJvZHkucGFnaW5nKTtcbiAgICByZXR1cm4gcGFnZXMucmVkdWNlKFxuICAgICAgKGFjYzogYW55LCBbaWQsIHBhZ2VVcmxdOiBbcGFnZVVybDogc3RyaW5nLCBpZDogc3RyaW5nXSkgPT4ge1xuICAgICAgICBhY2NbaWRdID0gdGhpcy5fcGFyc2VQYWdlKGlkLCBwYWdlVXJsKTtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sIHt9XG4gICAgKTtcbiAgfVxuXG4gIF9wYXJzZUxpc3QocmVzcG9uc2U6IHsgYm9keTogeyBpdGVtczogYW55LCBwYWdpbmc6IGFueSB9IH0sIE1vZGVsOiBUTW9kZWwpIHtcbiAgICBjb25zdCBkYXRhID0ge30gYXMgYW55O1xuXG4gICAgZGF0YS5pdGVtcyA9IHJlc3BvbnNlLmJvZHkuaXRlbXMubWFwKChkOiBhbnkpID0+IG5ldyBNb2RlbChkKSk7XG5cbiAgICBkYXRhLnBhZ2VzID0gdGhpcy5fcGFyc2VQYWdlTGlua3MocmVzcG9uc2UpO1xuXG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBfcGFyc2VJdGVtKHJlc3BvbnNlOiB7IGJvZHk6IGFueSB9LCBNb2RlbDogVE1vZGVsKSB7XG4gICAgcmV0dXJuIG5ldyBNb2RlbChyZXNwb25zZS5ib2R5KTtcbiAgfVxuXG4gIGxpc3QoZG9tYWluOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgcXVlcnk6IGFueSkge1xuICAgIGNvbnN0IG1vZGVsID0gKHRoaXMubW9kZWxzIGFzIGFueSlbdHlwZV07XG5cbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0XG4gICAgICAuZ2V0KHVybGpvaW4oJ3YzJywgZG9tYWluLCB0eXBlKSwgcXVlcnkpXG4gICAgICAudGhlbigocmVzcG9uc2U6IHsgYm9keTogeyBpdGVtczogYW55LCBwYWdpbmc6IGFueSB9IH0pID0+IHRoaXMuX3BhcnNlTGlzdChyZXNwb25zZSwgbW9kZWwpKTtcbiAgfVxuXG4gIGdldChkb21haW46IHN0cmluZywgdHlwZTogc3RyaW5nLCBhZGRyZXNzOiBzdHJpbmcpIHtcbiAgICBjb25zdCBtb2RlbCA9ICh0aGlzLm1vZGVscyBhcyBhbnkpW3R5cGVdO1xuXG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdFxuICAgICAgLmdldCh1cmxqb2luKCd2MycsIGRvbWFpbiwgdHlwZSwgZW5jb2RlVVJJQ29tcG9uZW50KGFkZHJlc3MpKSlcbiAgICAgIC50aGVuKChyZXNwb25zZTogeyBib2R5OiBhbnkgfSkgPT4gdGhpcy5fcGFyc2VJdGVtKHJlc3BvbnNlLCBtb2RlbCkpO1xuICB9XG5cbiAgY3JlYXRlKGRvbWFpbjogc3RyaW5nLCB0eXBlOiBzdHJpbmcsIGRhdGE6IGFueSkge1xuICAgIC8vIHN1cHBvcnRzIGFkZGluZyBtdWx0aXBsZSBzdXBwcmVzc2lvbnMgYnkgZGVmYXVsdFxuICAgIGxldCBwb3N0RGF0YTtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgIHBvc3REYXRhID0gW2RhdGFdO1xuICAgIH0gZWxzZSB7XG4gICAgICBwb3N0RGF0YSA9IHsgLi4uZGF0YSB9O1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnJlcXVlc3RcbiAgICAgIC5wb3N0KHVybGpvaW4oJ3YzJywgZG9tYWluLCB0eXBlKSwgcG9zdERhdGEsIGNyZWF0ZU9wdGlvbnMpXG4gICAgICAudGhlbigocmVzcG9uc2U6IHsgYm9keTogYW55IH0pID0+IHJlc3BvbnNlLmJvZHkpO1xuICB9XG5cbiAgZGVzdHJveShkb21haW46IHN0cmluZywgdHlwZTogc3RyaW5nLCBhZGRyZXNzOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0XG4gICAgICAuZGVsZXRlKHVybGpvaW4oJ3YzJywgZG9tYWluLCB0eXBlLCBlbmNvZGVVUklDb21wb25lbnQoYWRkcmVzcykpKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlOiB7IGJvZHk6IGFueSB9KSA9PiByZXNwb25zZS5ib2R5KTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFN1cHByZXNzaW9uQ2xpZW50O1xuIiwiaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi9yZXF1ZXN0JztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVmFsaWRhdGVDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICB9XG5cbiAgZ2V0KGFkZHJlc3M6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KCcvdjMvYWRkcmVzcy92YWxpZGF0ZScsIHsgYWRkcmVzcyB9KVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5KTtcbiAgfVxufVxuIiwiaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuaW1wb3J0IHsgV2ViaG9va0xpc3QsIFdlYmhvb2tSZXNwb25zZSwgV2ViaG9va3NRdWVyeSB9IGZyb20gJy4vaW50ZXJmYWNlcy9XZWJob29rcyc7XG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuXG5jbGFzcyBXZWJob29rIHtcbiAgaWQ6IHN0cmluZztcbiAgdXJsOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoaWQ6IHN0cmluZywgdXJsOiBzdHJpbmcpIHtcbiAgICB0aGlzLmlkID0gaWQ7XG4gICAgdGhpcy51cmwgPSB1cmw7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgV2ViaG9va0NsaWVudCB7XG4gIHJlcXVlc3Q6IGFueTtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0KSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgfVxuXG4gIF9wYXJzZVdlYmhvb2tMaXN0KHJlc3BvbnNlOiB7IGJvZHk6IHsgd2ViaG9va3M6IFdlYmhvb2tMaXN0IH0gfSk6IFdlYmhvb2tMaXN0IHtcbiAgICByZXR1cm4gcmVzcG9uc2UuYm9keS53ZWJob29rcztcbiAgfVxuXG4gIF9wYXJzZVdlYmhvb2tXaXRoSUQoaWQ6IHN0cmluZykge1xuICAgIHJldHVybiBmdW5jdGlvbiAocmVzcG9uc2U6IFdlYmhvb2tSZXNwb25zZSk6IFdlYmhvb2sge1xuICAgICAgY29uc3Qgd2ViaG9va1Jlc3BvbnNlID0gcmVzcG9uc2U/LmJvZHk/LndlYmhvb2s7XG4gICAgICBsZXQgdXJsID0gd2ViaG9va1Jlc3BvbnNlPy51cmw7XG4gICAgICBpZiAoIXVybCkge1xuICAgICAgICB1cmwgPSB3ZWJob29rUmVzcG9uc2U/LnVybHMgJiYgd2ViaG9va1Jlc3BvbnNlLnVybHMubGVuZ3RoID8gd2ViaG9va1Jlc3BvbnNlLnVybHNbMF0gOiBudWxsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBXZWJob29rKGlkLCB1cmwpO1xuICAgIH07XG4gIH1cblxuICBfcGFyc2VXZWJob29rVGVzdChyZXNwb25zZTogeyBib2R5OiB7IGNvZGU6IG51bWJlciwgbWVzc2FnZTogc3RyaW5nIH0gfSlcbiAgOiB7Y29kZTogbnVtYmVyLCBtZXNzYWdlOnN0cmluZ30ge1xuICAgIHJldHVybiB7IGNvZGU6IHJlc3BvbnNlLmJvZHkuY29kZSwgbWVzc2FnZTogcmVzcG9uc2UuYm9keS5tZXNzYWdlIH07XG4gIH1cblxuICBsaXN0KGRvbWFpbjogc3RyaW5nLCBxdWVyeTogV2ViaG9va3NRdWVyeSk6IFByb21pc2U8V2ViaG9va0xpc3Q+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ3dlYmhvb2tzJyksIHF1ZXJ5KVxuICAgICAgLnRoZW4odGhpcy5fcGFyc2VXZWJob29rTGlzdCk7XG4gIH1cblxuICBnZXQoZG9tYWluOiBzdHJpbmcsIGlkOiBzdHJpbmcpOiBQcm9taXNlPFdlYmhvb2s+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ3dlYmhvb2tzJywgaWQpKVxuICAgICAgLnRoZW4odGhpcy5fcGFyc2VXZWJob29rV2l0aElEKGlkKSk7XG4gIH1cblxuICBjcmVhdGUoZG9tYWluOiBzdHJpbmcsIGlkOiBzdHJpbmcsIHVybDogc3RyaW5nLCB0ZXN0ID0gZmFsc2UpOiBQcm9taXNlPFdlYmhvb2s+IHtcbiAgICBpZiAodGVzdCkge1xuICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXRXaXRoRkQodXJsam9pbignL3YyL2RvbWFpbnMnLCBkb21haW4sICd3ZWJob29rcycsIGlkLCAndGVzdCcpLCB7IHVybCB9KVxuICAgICAgICAudGhlbih0aGlzLl9wYXJzZVdlYmhvb2tUZXN0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQodXJsam9pbignL3YyL2RvbWFpbnMnLCBkb21haW4sICd3ZWJob29rcycpLCB7IGlkLCB1cmwgfSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlV2ViaG9va1dpdGhJRChpZCkpO1xuICB9XG5cbiAgdXBkYXRlKGRvbWFpbjogc3RyaW5nLCBpZDogc3RyaW5nLCB1cmw6IHN0cmluZyk6IFByb21pc2U8V2ViaG9vaz4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucHV0V2l0aEZEKHVybGpvaW4oJy92Mi9kb21haW5zJywgZG9tYWluLCAnd2ViaG9va3MnLCBpZCksIHsgdXJsIH0pXG4gICAgICAudGhlbih0aGlzLl9wYXJzZVdlYmhvb2tXaXRoSUQoaWQpKTtcbiAgfVxuXG4gIGRlc3Ryb3koZG9tYWluOiBzdHJpbmcsIGlkOiBzdHJpbmcpIDogUHJvbWlzZTxXZWJob29rPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUodXJsam9pbignL3YyL2RvbWFpbnMnLCBkb21haW4sICd3ZWJob29rcycsIGlkKSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlV2ViaG9va1dpdGhJRChpZCkpO1xuICB9XG59XG4iLCIvKiEgaHR0cHM6Ly9tdGhzLmJlL2Jhc2U2NCB2MS4wLjAgYnkgQG1hdGhpYXMgfCBNSVQgbGljZW5zZSAqL1xuOyhmdW5jdGlvbihyb290KSB7XG5cblx0Ly8gRGV0ZWN0IGZyZWUgdmFyaWFibGVzIGBleHBvcnRzYC5cblx0dmFyIGZyZWVFeHBvcnRzID0gdHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcgJiYgZXhwb3J0cztcblxuXHQvLyBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC5cblx0dmFyIGZyZWVNb2R1bGUgPSB0eXBlb2YgbW9kdWxlID09ICdvYmplY3QnICYmIG1vZHVsZSAmJlxuXHRcdG1vZHVsZS5leHBvcnRzID09IGZyZWVFeHBvcnRzICYmIG1vZHVsZTtcblxuXHQvLyBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCwgZnJvbSBOb2RlLmpzIG9yIEJyb3dzZXJpZmllZCBjb2RlLCBhbmQgdXNlXG5cdC8vIGl0IGFzIGByb290YC5cblx0dmFyIGZyZWVHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsID09ICdvYmplY3QnICYmIGdsb2JhbDtcblx0aWYgKGZyZWVHbG9iYWwuZ2xvYmFsID09PSBmcmVlR2xvYmFsIHx8IGZyZWVHbG9iYWwud2luZG93ID09PSBmcmVlR2xvYmFsKSB7XG5cdFx0cm9vdCA9IGZyZWVHbG9iYWw7XG5cdH1cblxuXHQvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuXHR2YXIgSW52YWxpZENoYXJhY3RlckVycm9yID0gZnVuY3Rpb24obWVzc2FnZSkge1xuXHRcdHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG5cdH07XG5cdEludmFsaWRDaGFyYWN0ZXJFcnJvci5wcm90b3R5cGUgPSBuZXcgRXJyb3I7XG5cdEludmFsaWRDaGFyYWN0ZXJFcnJvci5wcm90b3R5cGUubmFtZSA9ICdJbnZhbGlkQ2hhcmFjdGVyRXJyb3InO1xuXG5cdHZhciBlcnJvciA9IGZ1bmN0aW9uKG1lc3NhZ2UpIHtcblx0XHQvLyBOb3RlOiB0aGUgZXJyb3IgbWVzc2FnZXMgdXNlZCB0aHJvdWdob3V0IHRoaXMgZmlsZSBtYXRjaCB0aG9zZSB1c2VkIGJ5XG5cdFx0Ly8gdGhlIG5hdGl2ZSBgYXRvYmAvYGJ0b2FgIGltcGxlbWVudGF0aW9uIGluIENocm9taXVtLlxuXHRcdHRocm93IG5ldyBJbnZhbGlkQ2hhcmFjdGVyRXJyb3IobWVzc2FnZSk7XG5cdH07XG5cblx0dmFyIFRBQkxFID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nO1xuXHQvLyBodHRwOi8vd2hhdHdnLm9yZy9odG1sL2NvbW1vbi1taWNyb3N5bnRheGVzLmh0bWwjc3BhY2UtY2hhcmFjdGVyXG5cdHZhciBSRUdFWF9TUEFDRV9DSEFSQUNURVJTID0gL1tcXHRcXG5cXGZcXHIgXS9nO1xuXG5cdC8vIGBkZWNvZGVgIGlzIGRlc2lnbmVkIHRvIGJlIGZ1bGx5IGNvbXBhdGlibGUgd2l0aCBgYXRvYmAgYXMgZGVzY3JpYmVkIGluIHRoZVxuXHQvLyBIVE1MIFN0YW5kYXJkLiBodHRwOi8vd2hhdHdnLm9yZy9odG1sL3dlYmFwcGFwaXMuaHRtbCNkb20td2luZG93YmFzZTY0LWF0b2Jcblx0Ly8gVGhlIG9wdGltaXplZCBiYXNlNjQtZGVjb2RpbmcgYWxnb3JpdGhtIHVzZWQgaXMgYmFzZWQgb24gQGF0a+KAmXMgZXhjZWxsZW50XG5cdC8vIGltcGxlbWVudGF0aW9uLiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9hdGsvMTAyMDM5NlxuXHR2YXIgZGVjb2RlID0gZnVuY3Rpb24oaW5wdXQpIHtcblx0XHRpbnB1dCA9IFN0cmluZyhpbnB1dClcblx0XHRcdC5yZXBsYWNlKFJFR0VYX1NQQUNFX0NIQVJBQ1RFUlMsICcnKTtcblx0XHR2YXIgbGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuXHRcdGlmIChsZW5ndGggJSA0ID09IDApIHtcblx0XHRcdGlucHV0ID0gaW5wdXQucmVwbGFjZSgvPT0/JC8sICcnKTtcblx0XHRcdGxlbmd0aCA9IGlucHV0Lmxlbmd0aDtcblx0XHR9XG5cdFx0aWYgKFxuXHRcdFx0bGVuZ3RoICUgNCA9PSAxIHx8XG5cdFx0XHQvLyBodHRwOi8vd2hhdHdnLm9yZy9DI2FscGhhbnVtZXJpYy1hc2NpaS1jaGFyYWN0ZXJzXG5cdFx0XHQvW14rYS16QS1aMC05L10vLnRlc3QoaW5wdXQpXG5cdFx0KSB7XG5cdFx0XHRlcnJvcihcblx0XHRcdFx0J0ludmFsaWQgY2hhcmFjdGVyOiB0aGUgc3RyaW5nIHRvIGJlIGRlY29kZWQgaXMgbm90IGNvcnJlY3RseSBlbmNvZGVkLidcblx0XHRcdCk7XG5cdFx0fVxuXHRcdHZhciBiaXRDb3VudGVyID0gMDtcblx0XHR2YXIgYml0U3RvcmFnZTtcblx0XHR2YXIgYnVmZmVyO1xuXHRcdHZhciBvdXRwdXQgPSAnJztcblx0XHR2YXIgcG9zaXRpb24gPSAtMTtcblx0XHR3aGlsZSAoKytwb3NpdGlvbiA8IGxlbmd0aCkge1xuXHRcdFx0YnVmZmVyID0gVEFCTEUuaW5kZXhPZihpbnB1dC5jaGFyQXQocG9zaXRpb24pKTtcblx0XHRcdGJpdFN0b3JhZ2UgPSBiaXRDb3VudGVyICUgNCA/IGJpdFN0b3JhZ2UgKiA2NCArIGJ1ZmZlciA6IGJ1ZmZlcjtcblx0XHRcdC8vIFVubGVzcyB0aGlzIGlzIHRoZSBmaXJzdCBvZiBhIGdyb3VwIG9mIDQgY2hhcmFjdGVyc+KAplxuXHRcdFx0aWYgKGJpdENvdW50ZXIrKyAlIDQpIHtcblx0XHRcdFx0Ly8g4oCmY29udmVydCB0aGUgZmlyc3QgOCBiaXRzIHRvIGEgc2luZ2xlIEFTQ0lJIGNoYXJhY3Rlci5cblx0XHRcdFx0b3V0cHV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoXG5cdFx0XHRcdFx0MHhGRiAmIGJpdFN0b3JhZ2UgPj4gKC0yICogYml0Q291bnRlciAmIDYpXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBvdXRwdXQ7XG5cdH07XG5cblx0Ly8gYGVuY29kZWAgaXMgZGVzaWduZWQgdG8gYmUgZnVsbHkgY29tcGF0aWJsZSB3aXRoIGBidG9hYCBhcyBkZXNjcmliZWQgaW4gdGhlXG5cdC8vIEhUTUwgU3RhbmRhcmQ6IGh0dHA6Ly93aGF0d2cub3JnL2h0bWwvd2ViYXBwYXBpcy5odG1sI2RvbS13aW5kb3diYXNlNjQtYnRvYVxuXHR2YXIgZW5jb2RlID0gZnVuY3Rpb24oaW5wdXQpIHtcblx0XHRpbnB1dCA9IFN0cmluZyhpbnB1dCk7XG5cdFx0aWYgKC9bXlxcMC1cXHhGRl0vLnRlc3QoaW5wdXQpKSB7XG5cdFx0XHQvLyBOb3RlOiBubyBuZWVkIHRvIHNwZWNpYWwtY2FzZSBhc3RyYWwgc3ltYm9scyBoZXJlLCBhcyBzdXJyb2dhdGVzIGFyZVxuXHRcdFx0Ly8gbWF0Y2hlZCwgYW5kIHRoZSBpbnB1dCBpcyBzdXBwb3NlZCB0byBvbmx5IGNvbnRhaW4gQVNDSUkgYW55d2F5LlxuXHRcdFx0ZXJyb3IoXG5cdFx0XHRcdCdUaGUgc3RyaW5nIHRvIGJlIGVuY29kZWQgY29udGFpbnMgY2hhcmFjdGVycyBvdXRzaWRlIG9mIHRoZSAnICtcblx0XHRcdFx0J0xhdGluMSByYW5nZS4nXG5cdFx0XHQpO1xuXHRcdH1cblx0XHR2YXIgcGFkZGluZyA9IGlucHV0Lmxlbmd0aCAlIDM7XG5cdFx0dmFyIG91dHB1dCA9ICcnO1xuXHRcdHZhciBwb3NpdGlvbiA9IC0xO1xuXHRcdHZhciBhO1xuXHRcdHZhciBiO1xuXHRcdHZhciBjO1xuXHRcdHZhciBidWZmZXI7XG5cdFx0Ly8gTWFrZSBzdXJlIGFueSBwYWRkaW5nIGlzIGhhbmRsZWQgb3V0c2lkZSBvZiB0aGUgbG9vcC5cblx0XHR2YXIgbGVuZ3RoID0gaW5wdXQubGVuZ3RoIC0gcGFkZGluZztcblxuXHRcdHdoaWxlICgrK3Bvc2l0aW9uIDwgbGVuZ3RoKSB7XG5cdFx0XHQvLyBSZWFkIHRocmVlIGJ5dGVzLCBpLmUuIDI0IGJpdHMuXG5cdFx0XHRhID0gaW5wdXQuY2hhckNvZGVBdChwb3NpdGlvbikgPDwgMTY7XG5cdFx0XHRiID0gaW5wdXQuY2hhckNvZGVBdCgrK3Bvc2l0aW9uKSA8PCA4O1xuXHRcdFx0YyA9IGlucHV0LmNoYXJDb2RlQXQoKytwb3NpdGlvbik7XG5cdFx0XHRidWZmZXIgPSBhICsgYiArIGM7XG5cdFx0XHQvLyBUdXJuIHRoZSAyNCBiaXRzIGludG8gZm91ciBjaHVua3Mgb2YgNiBiaXRzIGVhY2gsIGFuZCBhcHBlbmQgdGhlXG5cdFx0XHQvLyBtYXRjaGluZyBjaGFyYWN0ZXIgZm9yIGVhY2ggb2YgdGhlbSB0byB0aGUgb3V0cHV0LlxuXHRcdFx0b3V0cHV0ICs9IChcblx0XHRcdFx0VEFCTEUuY2hhckF0KGJ1ZmZlciA+PiAxOCAmIDB4M0YpICtcblx0XHRcdFx0VEFCTEUuY2hhckF0KGJ1ZmZlciA+PiAxMiAmIDB4M0YpICtcblx0XHRcdFx0VEFCTEUuY2hhckF0KGJ1ZmZlciA+PiA2ICYgMHgzRikgK1xuXHRcdFx0XHRUQUJMRS5jaGFyQXQoYnVmZmVyICYgMHgzRilcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0aWYgKHBhZGRpbmcgPT0gMikge1xuXHRcdFx0YSA9IGlucHV0LmNoYXJDb2RlQXQocG9zaXRpb24pIDw8IDg7XG5cdFx0XHRiID0gaW5wdXQuY2hhckNvZGVBdCgrK3Bvc2l0aW9uKTtcblx0XHRcdGJ1ZmZlciA9IGEgKyBiO1xuXHRcdFx0b3V0cHV0ICs9IChcblx0XHRcdFx0VEFCTEUuY2hhckF0KGJ1ZmZlciA+PiAxMCkgK1xuXHRcdFx0XHRUQUJMRS5jaGFyQXQoKGJ1ZmZlciA+PiA0KSAmIDB4M0YpICtcblx0XHRcdFx0VEFCTEUuY2hhckF0KChidWZmZXIgPDwgMikgJiAweDNGKSArXG5cdFx0XHRcdCc9J1xuXHRcdFx0KTtcblx0XHR9IGVsc2UgaWYgKHBhZGRpbmcgPT0gMSkge1xuXHRcdFx0YnVmZmVyID0gaW5wdXQuY2hhckNvZGVBdChwb3NpdGlvbik7XG5cdFx0XHRvdXRwdXQgKz0gKFxuXHRcdFx0XHRUQUJMRS5jaGFyQXQoYnVmZmVyID4+IDIpICtcblx0XHRcdFx0VEFCTEUuY2hhckF0KChidWZmZXIgPDwgNCkgJiAweDNGKSArXG5cdFx0XHRcdCc9PSdcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG91dHB1dDtcblx0fTtcblxuXHR2YXIgYmFzZTY0ID0ge1xuXHRcdCdlbmNvZGUnOiBlbmNvZGUsXG5cdFx0J2RlY29kZSc6IGRlY29kZSxcblx0XHQndmVyc2lvbic6ICcxLjAuMCdcblx0fTtcblxuXHQvLyBTb21lIEFNRCBidWlsZCBvcHRpbWl6ZXJzLCBsaWtlIHIuanMsIGNoZWNrIGZvciBzcGVjaWZpYyBjb25kaXRpb24gcGF0dGVybnNcblx0Ly8gbGlrZSB0aGUgZm9sbG93aW5nOlxuXHRpZiAoXG5cdFx0dHlwZW9mIGRlZmluZSA9PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiZcblx0XHRkZWZpbmUuYW1kXG5cdCkge1xuXHRcdGRlZmluZShmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBiYXNlNjQ7XG5cdFx0fSk7XG5cdH1cdGVsc2UgaWYgKGZyZWVFeHBvcnRzICYmICFmcmVlRXhwb3J0cy5ub2RlVHlwZSkge1xuXHRcdGlmIChmcmVlTW9kdWxlKSB7IC8vIGluIE5vZGUuanMgb3IgUmluZ29KUyB2MC44LjArXG5cdFx0XHRmcmVlTW9kdWxlLmV4cG9ydHMgPSBiYXNlNjQ7XG5cdFx0fSBlbHNlIHsgLy8gaW4gTmFyd2hhbCBvciBSaW5nb0pTIHYwLjcuMC1cblx0XHRcdGZvciAodmFyIGtleSBpbiBiYXNlNjQpIHtcblx0XHRcdFx0YmFzZTY0Lmhhc093blByb3BlcnR5KGtleSkgJiYgKGZyZWVFeHBvcnRzW2tleV0gPSBiYXNlNjRba2V5XSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9IGVsc2UgeyAvLyBpbiBSaGlubyBvciBhIHdlYiBicm93c2VyXG5cdFx0cm9vdC5iYXNlNjQgPSBiYXNlNjQ7XG5cdH1cblxufSh0aGlzKSk7XG4iLCJcInVzZSBzdHJpY3RcIjtcbi8qKlxuICogUmV0dXJucyBhIGBCdWZmZXJgIGluc3RhbmNlIGZyb20gdGhlIGdpdmVuIGRhdGEgVVJJIGB1cmlgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmkgRGF0YSBVUkkgdG8gdHVybiBpbnRvIGEgQnVmZmVyIGluc3RhbmNlXG4gKiBAcmV0dXJuIHtCdWZmZXJ9IEJ1ZmZlciBpbnN0YW5jZSBmcm9tIERhdGEgVVJJXG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiBkYXRhVXJpVG9CdWZmZXIodXJpKSB7XG4gICAgaWYgKCEvXmRhdGE6L2kudGVzdCh1cmkpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2B1cmlgIGRvZXMgbm90IGFwcGVhciB0byBiZSBhIERhdGEgVVJJIChtdXN0IGJlZ2luIHdpdGggXCJkYXRhOlwiKScpO1xuICAgIH1cbiAgICAvLyBzdHJpcCBuZXdsaW5lc1xuICAgIHVyaSA9IHVyaS5yZXBsYWNlKC9cXHI/XFxuL2csICcnKTtcbiAgICAvLyBzcGxpdCB0aGUgVVJJIHVwIGludG8gdGhlIFwibWV0YWRhdGFcIiBhbmQgdGhlIFwiZGF0YVwiIHBvcnRpb25zXG4gICAgY29uc3QgZmlyc3RDb21tYSA9IHVyaS5pbmRleE9mKCcsJyk7XG4gICAgaWYgKGZpcnN0Q29tbWEgPT09IC0xIHx8IGZpcnN0Q29tbWEgPD0gNCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdtYWxmb3JtZWQgZGF0YTogVVJJJyk7XG4gICAgfVxuICAgIC8vIHJlbW92ZSB0aGUgXCJkYXRhOlwiIHNjaGVtZSBhbmQgcGFyc2UgdGhlIG1ldGFkYXRhXG4gICAgY29uc3QgbWV0YSA9IHVyaS5zdWJzdHJpbmcoNSwgZmlyc3RDb21tYSkuc3BsaXQoJzsnKTtcbiAgICBsZXQgY2hhcnNldCA9ICcnO1xuICAgIGxldCBiYXNlNjQgPSBmYWxzZTtcbiAgICBjb25zdCB0eXBlID0gbWV0YVswXSB8fCAndGV4dC9wbGFpbic7XG4gICAgbGV0IHR5cGVGdWxsID0gdHlwZTtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IG1ldGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKG1ldGFbaV0gPT09ICdiYXNlNjQnKSB7XG4gICAgICAgICAgICBiYXNlNjQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdHlwZUZ1bGwgKz0gYDske21ldGFbaV19YDtcbiAgICAgICAgICAgIGlmIChtZXRhW2ldLmluZGV4T2YoJ2NoYXJzZXQ9JykgPT09IDApIHtcbiAgICAgICAgICAgICAgICBjaGFyc2V0ID0gbWV0YVtpXS5zdWJzdHJpbmcoOCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gZGVmYXVsdHMgdG8gVVMtQVNDSUkgb25seSBpZiB0eXBlIGlzIG5vdCBwcm92aWRlZFxuICAgIGlmICghbWV0YVswXSAmJiAhY2hhcnNldC5sZW5ndGgpIHtcbiAgICAgICAgdHlwZUZ1bGwgKz0gJztjaGFyc2V0PVVTLUFTQ0lJJztcbiAgICAgICAgY2hhcnNldCA9ICdVUy1BU0NJSSc7XG4gICAgfVxuICAgIC8vIGdldCB0aGUgZW5jb2RlZCBkYXRhIHBvcnRpb24gYW5kIGRlY29kZSBVUkktZW5jb2RlZCBjaGFyc1xuICAgIGNvbnN0IGVuY29kaW5nID0gYmFzZTY0ID8gJ2Jhc2U2NCcgOiAnYXNjaWknO1xuICAgIGNvbnN0IGRhdGEgPSB1bmVzY2FwZSh1cmkuc3Vic3RyaW5nKGZpcnN0Q29tbWEgKyAxKSk7XG4gICAgY29uc3QgYnVmZmVyID0gQnVmZmVyLmZyb20oZGF0YSwgZW5jb2RpbmcpO1xuICAgIC8vIHNldCBgLnR5cGVgIGFuZCBgLnR5cGVGdWxsYCBwcm9wZXJ0aWVzIHRvIE1JTUUgdHlwZVxuICAgIGJ1ZmZlci50eXBlID0gdHlwZTtcbiAgICBidWZmZXIudHlwZUZ1bGwgPSB0eXBlRnVsbDtcbiAgICAvLyBzZXQgdGhlIGAuY2hhcnNldGAgcHJvcGVydHlcbiAgICBidWZmZXIuY2hhcnNldCA9IGNoYXJzZXQ7XG4gICAgcmV0dXJuIGJ1ZmZlcjtcbn1cbm1vZHVsZS5leHBvcnRzID0gZGF0YVVyaVRvQnVmZmVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiLyoqXG4gKiBAYXV0aG9yIFRvcnUgTmFnYXNoaW1hIDxodHRwczovL2dpdGh1Yi5jb20vbXlzdGljYXRlYT5cbiAqIEBjb3B5cmlnaHQgMjAxNSBUb3J1IE5hZ2FzaGltYS4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIFNlZSBMSUNFTlNFIGZpbGUgaW4gcm9vdCBkaXJlY3RvcnkgZm9yIGZ1bGwgbGljZW5zZS5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IFByaXZhdGVEYXRhXG4gKiBAcHJvcGVydHkge0V2ZW50VGFyZ2V0fSBldmVudFRhcmdldCBUaGUgZXZlbnQgdGFyZ2V0LlxuICogQHByb3BlcnR5IHt7dHlwZTpzdHJpbmd9fSBldmVudCBUaGUgb3JpZ2luYWwgZXZlbnQgb2JqZWN0LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGV2ZW50UGhhc2UgVGhlIGN1cnJlbnQgZXZlbnQgcGhhc2UuXG4gKiBAcHJvcGVydHkge0V2ZW50VGFyZ2V0fG51bGx9IGN1cnJlbnRUYXJnZXQgVGhlIGN1cnJlbnQgZXZlbnQgdGFyZ2V0LlxuICogQHByb3BlcnR5IHtib29sZWFufSBjYW5jZWxlZCBUaGUgZmxhZyB0byBwcmV2ZW50IGRlZmF1bHQuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHN0b3BwZWQgVGhlIGZsYWcgdG8gc3RvcCBwcm9wYWdhdGlvbi5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gaW1tZWRpYXRlU3RvcHBlZCBUaGUgZmxhZyB0byBzdG9wIHByb3BhZ2F0aW9uIGltbWVkaWF0ZWx5LlxuICogQHByb3BlcnR5IHtGdW5jdGlvbnxudWxsfSBwYXNzaXZlTGlzdGVuZXIgVGhlIGxpc3RlbmVyIGlmIHRoZSBjdXJyZW50IGxpc3RlbmVyIGlzIHBhc3NpdmUuIE90aGVyd2lzZSB0aGlzIGlzIG51bGwuXG4gKiBAcHJvcGVydHkge251bWJlcn0gdGltZVN0YW1wIFRoZSB1bml4IHRpbWUuXG4gKiBAcHJpdmF0ZVxuICovXG5cbi8qKlxuICogUHJpdmF0ZSBkYXRhIGZvciBldmVudCB3cmFwcGVycy5cbiAqIEB0eXBlIHtXZWFrTWFwPEV2ZW50LCBQcml2YXRlRGF0YT59XG4gKiBAcHJpdmF0ZVxuICovXG5jb25zdCBwcml2YXRlRGF0YSA9IG5ldyBXZWFrTWFwKCk7XG5cbi8qKlxuICogQ2FjaGUgZm9yIHdyYXBwZXIgY2xhc3Nlcy5cbiAqIEB0eXBlIHtXZWFrTWFwPE9iamVjdCwgRnVuY3Rpb24+fVxuICogQHByaXZhdGVcbiAqL1xuY29uc3Qgd3JhcHBlcnMgPSBuZXcgV2Vha01hcCgpO1xuXG4vKipcbiAqIEdldCBwcml2YXRlIGRhdGEuXG4gKiBAcGFyYW0ge0V2ZW50fSBldmVudCBUaGUgZXZlbnQgb2JqZWN0IHRvIGdldCBwcml2YXRlIGRhdGEuXG4gKiBAcmV0dXJucyB7UHJpdmF0ZURhdGF9IFRoZSBwcml2YXRlIGRhdGEgb2YgdGhlIGV2ZW50LlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gcGQoZXZlbnQpIHtcbiAgICBjb25zdCByZXR2ID0gcHJpdmF0ZURhdGEuZ2V0KGV2ZW50KTtcbiAgICBjb25zb2xlLmFzc2VydChcbiAgICAgICAgcmV0diAhPSBudWxsLFxuICAgICAgICBcIid0aGlzJyBpcyBleHBlY3RlZCBhbiBFdmVudCBvYmplY3QsIGJ1dCBnb3RcIixcbiAgICAgICAgZXZlbnRcbiAgICApO1xuICAgIHJldHVybiByZXR2XG59XG5cbi8qKlxuICogaHR0cHM6Ly9kb20uc3BlYy53aGF0d2cub3JnLyNzZXQtdGhlLWNhbmNlbGVkLWZsYWdcbiAqIEBwYXJhbSBkYXRhIHtQcml2YXRlRGF0YX0gcHJpdmF0ZSBkYXRhLlxuICovXG5mdW5jdGlvbiBzZXRDYW5jZWxGbGFnKGRhdGEpIHtcbiAgICBpZiAoZGF0YS5wYXNzaXZlTGlzdGVuZXIgIT0gbnVsbCkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICB0eXBlb2YgY29uc29sZSAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgdHlwZW9mIGNvbnNvbGUuZXJyb3IgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgICAgICAgXCJVbmFibGUgdG8gcHJldmVudERlZmF1bHQgaW5zaWRlIHBhc3NpdmUgZXZlbnQgbGlzdGVuZXIgaW52b2NhdGlvbi5cIixcbiAgICAgICAgICAgICAgICBkYXRhLnBhc3NpdmVMaXN0ZW5lclxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKCFkYXRhLmV2ZW50LmNhbmNlbGFibGUpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgZGF0YS5jYW5jZWxlZCA9IHRydWU7XG4gICAgaWYgKHR5cGVvZiBkYXRhLmV2ZW50LnByZXZlbnREZWZhdWx0ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgZGF0YS5ldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAc2VlIGh0dHBzOi8vZG9tLnNwZWMud2hhdHdnLm9yZy8jaW50ZXJmYWNlLWV2ZW50XG4gKiBAcHJpdmF0ZVxuICovXG4vKipcbiAqIFRoZSBldmVudCB3cmFwcGVyLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0V2ZW50VGFyZ2V0fSBldmVudFRhcmdldCBUaGUgZXZlbnQgdGFyZ2V0IG9mIHRoaXMgZGlzcGF0Y2hpbmcuXG4gKiBAcGFyYW0ge0V2ZW50fHt0eXBlOnN0cmluZ319IGV2ZW50IFRoZSBvcmlnaW5hbCBldmVudCB0byB3cmFwLlxuICovXG5mdW5jdGlvbiBFdmVudChldmVudFRhcmdldCwgZXZlbnQpIHtcbiAgICBwcml2YXRlRGF0YS5zZXQodGhpcywge1xuICAgICAgICBldmVudFRhcmdldCxcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIGV2ZW50UGhhc2U6IDIsXG4gICAgICAgIGN1cnJlbnRUYXJnZXQ6IGV2ZW50VGFyZ2V0LFxuICAgICAgICBjYW5jZWxlZDogZmFsc2UsXG4gICAgICAgIHN0b3BwZWQ6IGZhbHNlLFxuICAgICAgICBpbW1lZGlhdGVTdG9wcGVkOiBmYWxzZSxcbiAgICAgICAgcGFzc2l2ZUxpc3RlbmVyOiBudWxsLFxuICAgICAgICB0aW1lU3RhbXA6IGV2ZW50LnRpbWVTdGFtcCB8fCBEYXRlLm5vdygpLFxuICAgIH0pO1xuXG4gICAgLy8gaHR0cHM6Ly9oZXljYW0uZ2l0aHViLmlvL3dlYmlkbC8jVW5mb3JnZWFibGVcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgXCJpc1RydXN0ZWRcIiwgeyB2YWx1ZTogZmFsc2UsIGVudW1lcmFibGU6IHRydWUgfSk7XG5cbiAgICAvLyBEZWZpbmUgYWNjZXNzb3JzXG4gICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGV2ZW50KTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgY29uc3Qga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgaWYgKCEoa2V5IGluIHRoaXMpKSB7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywga2V5LCBkZWZpbmVSZWRpcmVjdERlc2NyaXB0b3Ioa2V5KSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8vIFNob3VsZCBiZSBlbnVtZXJhYmxlLCBidXQgY2xhc3MgbWV0aG9kcyBhcmUgbm90IGVudW1lcmFibGUuXG5FdmVudC5wcm90b3R5cGUgPSB7XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhpcyBldmVudC5cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gcGQodGhpcykuZXZlbnQudHlwZVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgdGFyZ2V0IG9mIHRoaXMgZXZlbnQuXG4gICAgICogQHR5cGUge0V2ZW50VGFyZ2V0fVxuICAgICAqL1xuICAgIGdldCB0YXJnZXQoKSB7XG4gICAgICAgIHJldHVybiBwZCh0aGlzKS5ldmVudFRhcmdldFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgdGFyZ2V0IG9mIHRoaXMgZXZlbnQuXG4gICAgICogQHR5cGUge0V2ZW50VGFyZ2V0fVxuICAgICAqL1xuICAgIGdldCBjdXJyZW50VGFyZ2V0KCkge1xuICAgICAgICByZXR1cm4gcGQodGhpcykuY3VycmVudFRhcmdldFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyB7RXZlbnRUYXJnZXRbXX0gVGhlIGNvbXBvc2VkIHBhdGggb2YgdGhpcyBldmVudC5cbiAgICAgKi9cbiAgICBjb21wb3NlZFBhdGgoKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRUYXJnZXQgPSBwZCh0aGlzKS5jdXJyZW50VGFyZ2V0O1xuICAgICAgICBpZiAoY3VycmVudFRhcmdldCA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gW11cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW2N1cnJlbnRUYXJnZXRdXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENvbnN0YW50IG9mIE5PTkUuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBnZXQgTk9ORSgpIHtcbiAgICAgICAgcmV0dXJuIDBcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ29uc3RhbnQgb2YgQ0FQVFVSSU5HX1BIQVNFLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgZ2V0IENBUFRVUklOR19QSEFTRSgpIHtcbiAgICAgICAgcmV0dXJuIDFcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ29uc3RhbnQgb2YgQVRfVEFSR0VULlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgZ2V0IEFUX1RBUkdFVCgpIHtcbiAgICAgICAgcmV0dXJuIDJcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ29uc3RhbnQgb2YgQlVCQkxJTkdfUEhBU0UuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBnZXQgQlVCQkxJTkdfUEhBU0UoKSB7XG4gICAgICAgIHJldHVybiAzXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSB0YXJnZXQgb2YgdGhpcyBldmVudC5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdldCBldmVudFBoYXNlKCkge1xuICAgICAgICByZXR1cm4gcGQodGhpcykuZXZlbnRQaGFzZVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBTdG9wIGV2ZW50IGJ1YmJsaW5nLlxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxuICAgICAqL1xuICAgIHN0b3BQcm9wYWdhdGlvbigpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHBkKHRoaXMpO1xuXG4gICAgICAgIGRhdGEuc3RvcHBlZCA9IHRydWU7XG4gICAgICAgIGlmICh0eXBlb2YgZGF0YS5ldmVudC5zdG9wUHJvcGFnYXRpb24gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgZGF0YS5ldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBTdG9wIGV2ZW50IGJ1YmJsaW5nLlxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxuICAgICAqL1xuICAgIHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHBkKHRoaXMpO1xuXG4gICAgICAgIGRhdGEuc3RvcHBlZCA9IHRydWU7XG4gICAgICAgIGRhdGEuaW1tZWRpYXRlU3RvcHBlZCA9IHRydWU7XG4gICAgICAgIGlmICh0eXBlb2YgZGF0YS5ldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgZGF0YS5ldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZmxhZyB0byBiZSBidWJibGluZy5cbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXQgYnViYmxlcygpIHtcbiAgICAgICAgcmV0dXJuIEJvb2xlYW4ocGQodGhpcykuZXZlbnQuYnViYmxlcylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogVGhlIGZsYWcgdG8gYmUgY2FuY2VsYWJsZS5cbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXQgY2FuY2VsYWJsZSgpIHtcbiAgICAgICAgcmV0dXJuIEJvb2xlYW4ocGQodGhpcykuZXZlbnQuY2FuY2VsYWJsZSlcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ2FuY2VsIHRoaXMgZXZlbnQuXG4gICAgICogQHJldHVybnMge3ZvaWR9XG4gICAgICovXG4gICAgcHJldmVudERlZmF1bHQoKSB7XG4gICAgICAgIHNldENhbmNlbEZsYWcocGQodGhpcykpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZmxhZyB0byBpbmRpY2F0ZSBjYW5jZWxsYXRpb24gc3RhdGUuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0IGRlZmF1bHRQcmV2ZW50ZWQoKSB7XG4gICAgICAgIHJldHVybiBwZCh0aGlzKS5jYW5jZWxlZFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZmxhZyB0byBiZSBjb21wb3NlZC5cbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXQgY29tcG9zZWQoKSB7XG4gICAgICAgIHJldHVybiBCb29sZWFuKHBkKHRoaXMpLmV2ZW50LmNvbXBvc2VkKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgdW5peCB0aW1lIG9mIHRoaXMgZXZlbnQuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBnZXQgdGltZVN0YW1wKCkge1xuICAgICAgICByZXR1cm4gcGQodGhpcykudGltZVN0YW1wXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSB0YXJnZXQgb2YgdGhpcyBldmVudC5cbiAgICAgKiBAdHlwZSB7RXZlbnRUYXJnZXR9XG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKi9cbiAgICBnZXQgc3JjRWxlbWVudCgpIHtcbiAgICAgICAgcmV0dXJuIHBkKHRoaXMpLmV2ZW50VGFyZ2V0XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSBmbGFnIHRvIHN0b3AgZXZlbnQgYnViYmxpbmcuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKi9cbiAgICBnZXQgY2FuY2VsQnViYmxlKCkge1xuICAgICAgICByZXR1cm4gcGQodGhpcykuc3RvcHBlZFxuICAgIH0sXG4gICAgc2V0IGNhbmNlbEJ1YmJsZSh2YWx1ZSkge1xuICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkYXRhID0gcGQodGhpcyk7XG5cbiAgICAgICAgZGF0YS5zdG9wcGVkID0gdHJ1ZTtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhLmV2ZW50LmNhbmNlbEJ1YmJsZSA9PT0gXCJib29sZWFuXCIpIHtcbiAgICAgICAgICAgIGRhdGEuZXZlbnQuY2FuY2VsQnViYmxlID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZmxhZyB0byBpbmRpY2F0ZSBjYW5jZWxsYXRpb24gc3RhdGUuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKi9cbiAgICBnZXQgcmV0dXJuVmFsdWUoKSB7XG4gICAgICAgIHJldHVybiAhcGQodGhpcykuY2FuY2VsZWRcbiAgICB9LFxuICAgIHNldCByZXR1cm5WYWx1ZSh2YWx1ZSkge1xuICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICBzZXRDYW5jZWxGbGFnKHBkKHRoaXMpKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplIHRoaXMgZXZlbnQgb2JqZWN0LiBCdXQgZG8gbm90aGluZyB1bmRlciBldmVudCBkaXNwYXRjaGluZy5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBUaGUgZXZlbnQgdHlwZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtidWJibGVzPWZhbHNlXSBUaGUgZmxhZyB0byBiZSBwb3NzaWJsZSB0byBidWJibGUgdXAuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbY2FuY2VsYWJsZT1mYWxzZV0gVGhlIGZsYWcgdG8gYmUgcG9zc2libGUgdG8gY2FuY2VsLlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICovXG4gICAgaW5pdEV2ZW50KCkge1xuICAgICAgICAvLyBEbyBub3RoaW5nLlxuICAgIH0sXG59O1xuXG4vLyBgY29uc3RydWN0b3JgIGlzIG5vdCBlbnVtZXJhYmxlLlxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEV2ZW50LnByb3RvdHlwZSwgXCJjb25zdHJ1Y3RvclwiLCB7XG4gICAgdmFsdWU6IEV2ZW50LFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICB3cml0YWJsZTogdHJ1ZSxcbn0pO1xuXG4vLyBFbnN1cmUgYGV2ZW50IGluc3RhbmNlb2Ygd2luZG93LkV2ZW50YCBpcyBgdHJ1ZWAuXG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiB0eXBlb2Ygd2luZG93LkV2ZW50ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKEV2ZW50LnByb3RvdHlwZSwgd2luZG93LkV2ZW50LnByb3RvdHlwZSk7XG5cbiAgICAvLyBNYWtlIGFzc29jaWF0aW9uIGZvciB3cmFwcGVycy5cbiAgICB3cmFwcGVycy5zZXQod2luZG93LkV2ZW50LnByb3RvdHlwZSwgRXZlbnQpO1xufVxuXG4vKipcbiAqIEdldCB0aGUgcHJvcGVydHkgZGVzY3JpcHRvciB0byByZWRpcmVjdCBhIGdpdmVuIHByb3BlcnR5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBQcm9wZXJ0eSBuYW1lIHRvIGRlZmluZSBwcm9wZXJ0eSBkZXNjcmlwdG9yLlxuICogQHJldHVybnMge1Byb3BlcnR5RGVzY3JpcHRvcn0gVGhlIHByb3BlcnR5IGRlc2NyaXB0b3IgdG8gcmVkaXJlY3QgdGhlIHByb3BlcnR5LlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZGVmaW5lUmVkaXJlY3REZXNjcmlwdG9yKGtleSkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGdldCgpIHtcbiAgICAgICAgICAgIHJldHVybiBwZCh0aGlzKS5ldmVudFtrZXldXG4gICAgICAgIH0sXG4gICAgICAgIHNldCh2YWx1ZSkge1xuICAgICAgICAgICAgcGQodGhpcykuZXZlbnRba2V5XSA9IHZhbHVlO1xuICAgICAgICB9LFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgfVxufVxuXG4vKipcbiAqIEdldCB0aGUgcHJvcGVydHkgZGVzY3JpcHRvciB0byBjYWxsIGEgZ2l2ZW4gbWV0aG9kIHByb3BlcnR5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBQcm9wZXJ0eSBuYW1lIHRvIGRlZmluZSBwcm9wZXJ0eSBkZXNjcmlwdG9yLlxuICogQHJldHVybnMge1Byb3BlcnR5RGVzY3JpcHRvcn0gVGhlIHByb3BlcnR5IGRlc2NyaXB0b3IgdG8gY2FsbCB0aGUgbWV0aG9kIHByb3BlcnR5LlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZGVmaW5lQ2FsbERlc2NyaXB0b3Ioa2V5KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWUoKSB7XG4gICAgICAgICAgICBjb25zdCBldmVudCA9IHBkKHRoaXMpLmV2ZW50O1xuICAgICAgICAgICAgcmV0dXJuIGV2ZW50W2tleV0uYXBwbHkoZXZlbnQsIGFyZ3VtZW50cylcbiAgICAgICAgfSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgIH1cbn1cblxuLyoqXG4gKiBEZWZpbmUgbmV3IHdyYXBwZXIgY2xhc3MuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBCYXNlRXZlbnQgVGhlIGJhc2Ugd3JhcHBlciBjbGFzcy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm90byBUaGUgcHJvdG90eXBlIG9mIHRoZSBvcmlnaW5hbCBldmVudC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gVGhlIGRlZmluZWQgd3JhcHBlciBjbGFzcy5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGRlZmluZVdyYXBwZXIoQmFzZUV2ZW50LCBwcm90bykge1xuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhwcm90byk7XG4gICAgaWYgKGtleXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBCYXNlRXZlbnRcbiAgICB9XG5cbiAgICAvKiogQ3VzdG9tRXZlbnQgKi9cbiAgICBmdW5jdGlvbiBDdXN0b21FdmVudChldmVudFRhcmdldCwgZXZlbnQpIHtcbiAgICAgICAgQmFzZUV2ZW50LmNhbGwodGhpcywgZXZlbnRUYXJnZXQsIGV2ZW50KTtcbiAgICB9XG5cbiAgICBDdXN0b21FdmVudC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEJhc2VFdmVudC5wcm90b3R5cGUsIHtcbiAgICAgICAgY29uc3RydWN0b3I6IHsgdmFsdWU6IEN1c3RvbUV2ZW50LCBjb25maWd1cmFibGU6IHRydWUsIHdyaXRhYmxlOiB0cnVlIH0sXG4gICAgfSk7XG5cbiAgICAvLyBEZWZpbmUgYWNjZXNzb3JzLlxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICBjb25zdCBrZXkgPSBrZXlzW2ldO1xuICAgICAgICBpZiAoIShrZXkgaW4gQmFzZUV2ZW50LnByb3RvdHlwZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHByb3RvLCBrZXkpO1xuICAgICAgICAgICAgY29uc3QgaXNGdW5jID0gdHlwZW9mIGRlc2NyaXB0b3IudmFsdWUgPT09IFwiZnVuY3Rpb25cIjtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShcbiAgICAgICAgICAgICAgICBDdXN0b21FdmVudC5wcm90b3R5cGUsXG4gICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgIGlzRnVuY1xuICAgICAgICAgICAgICAgICAgICA/IGRlZmluZUNhbGxEZXNjcmlwdG9yKGtleSlcbiAgICAgICAgICAgICAgICAgICAgOiBkZWZpbmVSZWRpcmVjdERlc2NyaXB0b3Ioa2V5KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBDdXN0b21FdmVudFxufVxuXG4vKipcbiAqIEdldCB0aGUgd3JhcHBlciBjbGFzcyBvZiBhIGdpdmVuIHByb3RvdHlwZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm90byBUaGUgcHJvdG90eXBlIG9mIHRoZSBvcmlnaW5hbCBldmVudCB0byBnZXQgaXRzIHdyYXBwZXIuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFRoZSB3cmFwcGVyIGNsYXNzLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZ2V0V3JhcHBlcihwcm90bykge1xuICAgIGlmIChwcm90byA9PSBudWxsIHx8IHByb3RvID09PSBPYmplY3QucHJvdG90eXBlKSB7XG4gICAgICAgIHJldHVybiBFdmVudFxuICAgIH1cblxuICAgIGxldCB3cmFwcGVyID0gd3JhcHBlcnMuZ2V0KHByb3RvKTtcbiAgICBpZiAod3JhcHBlciA9PSBudWxsKSB7XG4gICAgICAgIHdyYXBwZXIgPSBkZWZpbmVXcmFwcGVyKGdldFdyYXBwZXIoT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvKSksIHByb3RvKTtcbiAgICAgICAgd3JhcHBlcnMuc2V0KHByb3RvLCB3cmFwcGVyKTtcbiAgICB9XG4gICAgcmV0dXJuIHdyYXBwZXJcbn1cblxuLyoqXG4gKiBXcmFwIGEgZ2l2ZW4gZXZlbnQgdG8gbWFuYWdlbWVudCBhIGRpc3BhdGNoaW5nLlxuICogQHBhcmFtIHtFdmVudFRhcmdldH0gZXZlbnRUYXJnZXQgVGhlIGV2ZW50IHRhcmdldCBvZiB0aGlzIGRpc3BhdGNoaW5nLlxuICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFRoZSBldmVudCB0byB3cmFwLlxuICogQHJldHVybnMge0V2ZW50fSBUaGUgd3JhcHBlciBpbnN0YW5jZS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHdyYXBFdmVudChldmVudFRhcmdldCwgZXZlbnQpIHtcbiAgICBjb25zdCBXcmFwcGVyID0gZ2V0V3JhcHBlcihPYmplY3QuZ2V0UHJvdG90eXBlT2YoZXZlbnQpKTtcbiAgICByZXR1cm4gbmV3IFdyYXBwZXIoZXZlbnRUYXJnZXQsIGV2ZW50KVxufVxuXG4vKipcbiAqIEdldCB0aGUgaW1tZWRpYXRlU3RvcHBlZCBmbGFnIG9mIGEgZ2l2ZW4gZXZlbnQuXG4gKiBAcGFyYW0ge0V2ZW50fSBldmVudCBUaGUgZXZlbnQgdG8gZ2V0LlxuICogQHJldHVybnMge2Jvb2xlYW59IFRoZSBmbGFnIHRvIHN0b3AgcHJvcGFnYXRpb24gaW1tZWRpYXRlbHkuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBpc1N0b3BwZWQoZXZlbnQpIHtcbiAgICByZXR1cm4gcGQoZXZlbnQpLmltbWVkaWF0ZVN0b3BwZWRcbn1cblxuLyoqXG4gKiBTZXQgdGhlIGN1cnJlbnQgZXZlbnQgcGhhc2Ugb2YgYSBnaXZlbiBldmVudC5cbiAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50IFRoZSBldmVudCB0byBzZXQgY3VycmVudCB0YXJnZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZXZlbnRQaGFzZSBOZXcgZXZlbnQgcGhhc2UuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHNldEV2ZW50UGhhc2UoZXZlbnQsIGV2ZW50UGhhc2UpIHtcbiAgICBwZChldmVudCkuZXZlbnRQaGFzZSA9IGV2ZW50UGhhc2U7XG59XG5cbi8qKlxuICogU2V0IHRoZSBjdXJyZW50IHRhcmdldCBvZiBhIGdpdmVuIGV2ZW50LlxuICogQHBhcmFtIHtFdmVudH0gZXZlbnQgVGhlIGV2ZW50IHRvIHNldCBjdXJyZW50IHRhcmdldC5cbiAqIEBwYXJhbSB7RXZlbnRUYXJnZXR8bnVsbH0gY3VycmVudFRhcmdldCBOZXcgY3VycmVudCB0YXJnZXQuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHNldEN1cnJlbnRUYXJnZXQoZXZlbnQsIGN1cnJlbnRUYXJnZXQpIHtcbiAgICBwZChldmVudCkuY3VycmVudFRhcmdldCA9IGN1cnJlbnRUYXJnZXQ7XG59XG5cbi8qKlxuICogU2V0IGEgcGFzc2l2ZSBsaXN0ZW5lciBvZiBhIGdpdmVuIGV2ZW50LlxuICogQHBhcmFtIHtFdmVudH0gZXZlbnQgVGhlIGV2ZW50IHRvIHNldCBjdXJyZW50IHRhcmdldC5cbiAqIEBwYXJhbSB7RnVuY3Rpb258bnVsbH0gcGFzc2l2ZUxpc3RlbmVyIE5ldyBwYXNzaXZlIGxpc3RlbmVyLlxuICogQHJldHVybnMge3ZvaWR9XG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBzZXRQYXNzaXZlTGlzdGVuZXIoZXZlbnQsIHBhc3NpdmVMaXN0ZW5lcikge1xuICAgIHBkKGV2ZW50KS5wYXNzaXZlTGlzdGVuZXIgPSBwYXNzaXZlTGlzdGVuZXI7XG59XG5cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gTGlzdGVuZXJOb2RlXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBsaXN0ZW5lclxuICogQHByb3BlcnR5IHsxfDJ8M30gbGlzdGVuZXJUeXBlXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHBhc3NpdmVcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gb25jZVxuICogQHByb3BlcnR5IHtMaXN0ZW5lck5vZGV8bnVsbH0gbmV4dFxuICogQHByaXZhdGVcbiAqL1xuXG4vKipcbiAqIEB0eXBlIHtXZWFrTWFwPG9iamVjdCwgTWFwPHN0cmluZywgTGlzdGVuZXJOb2RlPj59XG4gKiBAcHJpdmF0ZVxuICovXG5jb25zdCBsaXN0ZW5lcnNNYXAgPSBuZXcgV2Vha01hcCgpO1xuXG4vLyBMaXN0ZW5lciB0eXBlc1xuY29uc3QgQ0FQVFVSRSA9IDE7XG5jb25zdCBCVUJCTEUgPSAyO1xuY29uc3QgQVRUUklCVVRFID0gMztcblxuLyoqXG4gKiBDaGVjayB3aGV0aGVyIGEgZ2l2ZW4gdmFsdWUgaXMgYW4gb2JqZWN0IG9yIG5vdC5cbiAqIEBwYXJhbSB7YW55fSB4IFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIHZhbHVlIGlzIGFuIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gaXNPYmplY3QoeCkge1xuICAgIHJldHVybiB4ICE9PSBudWxsICYmIHR5cGVvZiB4ID09PSBcIm9iamVjdFwiIC8vZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxufVxuXG4vKipcbiAqIEdldCBsaXN0ZW5lcnMuXG4gKiBAcGFyYW0ge0V2ZW50VGFyZ2V0fSBldmVudFRhcmdldCBUaGUgZXZlbnQgdGFyZ2V0IHRvIGdldC5cbiAqIEByZXR1cm5zIHtNYXA8c3RyaW5nLCBMaXN0ZW5lck5vZGU+fSBUaGUgbGlzdGVuZXJzLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZ2V0TGlzdGVuZXJzKGV2ZW50VGFyZ2V0KSB7XG4gICAgY29uc3QgbGlzdGVuZXJzID0gbGlzdGVuZXJzTWFwLmdldChldmVudFRhcmdldCk7XG4gICAgaWYgKGxpc3RlbmVycyA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICBcIid0aGlzJyBpcyBleHBlY3RlZCBhbiBFdmVudFRhcmdldCBvYmplY3QsIGJ1dCBnb3QgYW5vdGhlciB2YWx1ZS5cIlxuICAgICAgICApXG4gICAgfVxuICAgIHJldHVybiBsaXN0ZW5lcnNcbn1cblxuLyoqXG4gKiBHZXQgdGhlIHByb3BlcnR5IGRlc2NyaXB0b3IgZm9yIHRoZSBldmVudCBhdHRyaWJ1dGUgb2YgYSBnaXZlbiBldmVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgVGhlIGV2ZW50IG5hbWUgdG8gZ2V0IHByb3BlcnR5IGRlc2NyaXB0b3IuXG4gKiBAcmV0dXJucyB7UHJvcGVydHlEZXNjcmlwdG9yfSBUaGUgcHJvcGVydHkgZGVzY3JpcHRvci5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGRlZmluZUV2ZW50QXR0cmlidXRlRGVzY3JpcHRvcihldmVudE5hbWUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBnZXQoKSB7XG4gICAgICAgICAgICBjb25zdCBsaXN0ZW5lcnMgPSBnZXRMaXN0ZW5lcnModGhpcyk7XG4gICAgICAgICAgICBsZXQgbm9kZSA9IGxpc3RlbmVycy5nZXQoZXZlbnROYW1lKTtcbiAgICAgICAgICAgIHdoaWxlIChub2RlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAobm9kZS5saXN0ZW5lclR5cGUgPT09IEFUVFJJQlVURSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5saXN0ZW5lclxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5uZXh0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgfSxcblxuICAgICAgICBzZXQobGlzdGVuZXIpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09IFwiZnVuY3Rpb25cIiAmJiAhaXNPYmplY3QobGlzdGVuZXIpKSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXIgPSBudWxsOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBsaXN0ZW5lcnMgPSBnZXRMaXN0ZW5lcnModGhpcyk7XG5cbiAgICAgICAgICAgIC8vIFRyYXZlcnNlIHRvIHRoZSB0YWlsIHdoaWxlIHJlbW92aW5nIG9sZCB2YWx1ZS5cbiAgICAgICAgICAgIGxldCBwcmV2ID0gbnVsbDtcbiAgICAgICAgICAgIGxldCBub2RlID0gbGlzdGVuZXJzLmdldChldmVudE5hbWUpO1xuICAgICAgICAgICAgd2hpbGUgKG5vZGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChub2RlLmxpc3RlbmVyVHlwZSA9PT0gQVRUUklCVVRFKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBvbGQgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcmV2ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcmV2Lm5leHQgPSBub2RlLm5leHQ7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobm9kZS5uZXh0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuc2V0KGV2ZW50TmFtZSwgbm9kZS5uZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy5kZWxldGUoZXZlbnROYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHByZXYgPSBub2RlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLm5leHQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEFkZCBuZXcgdmFsdWUuXG4gICAgICAgICAgICBpZiAobGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdOb2RlID0ge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcixcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJUeXBlOiBBVFRSSUJVVEUsXG4gICAgICAgICAgICAgICAgICAgIHBhc3NpdmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBvbmNlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgbmV4dDogbnVsbCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGlmIChwcmV2ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy5zZXQoZXZlbnROYW1lLCBuZXdOb2RlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBwcmV2Lm5leHQgPSBuZXdOb2RlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgIH1cbn1cblxuLyoqXG4gKiBEZWZpbmUgYW4gZXZlbnQgYXR0cmlidXRlIChlLmcuIGBldmVudFRhcmdldC5vbmNsaWNrYCkuXG4gKiBAcGFyYW0ge09iamVjdH0gZXZlbnRUYXJnZXRQcm90b3R5cGUgVGhlIGV2ZW50IHRhcmdldCBwcm90b3R5cGUgdG8gZGVmaW5lIGFuIGV2ZW50IGF0dHJiaXRlLlxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSBUaGUgZXZlbnQgbmFtZSB0byBkZWZpbmUuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gZGVmaW5lRXZlbnRBdHRyaWJ1dGUoZXZlbnRUYXJnZXRQcm90b3R5cGUsIGV2ZW50TmFtZSkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShcbiAgICAgICAgZXZlbnRUYXJnZXRQcm90b3R5cGUsXG4gICAgICAgIGBvbiR7ZXZlbnROYW1lfWAsXG4gICAgICAgIGRlZmluZUV2ZW50QXR0cmlidXRlRGVzY3JpcHRvcihldmVudE5hbWUpXG4gICAgKTtcbn1cblxuLyoqXG4gKiBEZWZpbmUgYSBjdXN0b20gRXZlbnRUYXJnZXQgd2l0aCBldmVudCBhdHRyaWJ1dGVzLlxuICogQHBhcmFtIHtzdHJpbmdbXX0gZXZlbnROYW1lcyBFdmVudCBuYW1lcyBmb3IgZXZlbnQgYXR0cmlidXRlcy5cbiAqIEByZXR1cm5zIHtFdmVudFRhcmdldH0gVGhlIGN1c3RvbSBFdmVudFRhcmdldC5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGRlZmluZUN1c3RvbUV2ZW50VGFyZ2V0KGV2ZW50TmFtZXMpIHtcbiAgICAvKiogQ3VzdG9tRXZlbnRUYXJnZXQgKi9cbiAgICBmdW5jdGlvbiBDdXN0b21FdmVudFRhcmdldCgpIHtcbiAgICAgICAgRXZlbnRUYXJnZXQuY2FsbCh0aGlzKTtcbiAgICB9XG5cbiAgICBDdXN0b21FdmVudFRhcmdldC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEV2ZW50VGFyZ2V0LnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICAgICAgdmFsdWU6IEN1c3RvbUV2ZW50VGFyZ2V0LFxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV2ZW50TmFtZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgZGVmaW5lRXZlbnRBdHRyaWJ1dGUoQ3VzdG9tRXZlbnRUYXJnZXQucHJvdG90eXBlLCBldmVudE5hbWVzW2ldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gQ3VzdG9tRXZlbnRUYXJnZXRcbn1cblxuLyoqXG4gKiBFdmVudFRhcmdldC5cbiAqXG4gKiAtIFRoaXMgaXMgY29uc3RydWN0b3IgaWYgbm8gYXJndW1lbnRzLlxuICogLSBUaGlzIGlzIGEgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhIEN1c3RvbUV2ZW50VGFyZ2V0IGNvbnN0cnVjdG9yIGlmIHRoZXJlIGFyZSBhcmd1bWVudHMuXG4gKlxuICogRm9yIGV4YW1wbGU6XG4gKlxuICogICAgIGNsYXNzIEEgZXh0ZW5kcyBFdmVudFRhcmdldCB7fVxuICogICAgIGNsYXNzIEIgZXh0ZW5kcyBFdmVudFRhcmdldChcIm1lc3NhZ2VcIikge31cbiAqICAgICBjbGFzcyBDIGV4dGVuZHMgRXZlbnRUYXJnZXQoXCJtZXNzYWdlXCIsIFwiZXJyb3JcIikge31cbiAqICAgICBjbGFzcyBEIGV4dGVuZHMgRXZlbnRUYXJnZXQoW1wibWVzc2FnZVwiLCBcImVycm9yXCJdKSB7fVxuICovXG5mdW5jdGlvbiBFdmVudFRhcmdldCgpIHtcbiAgICAvKmVzbGludC1kaXNhYmxlIGNvbnNpc3RlbnQtcmV0dXJuICovXG4gICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBFdmVudFRhcmdldCkge1xuICAgICAgICBsaXN0ZW5lcnNNYXAuc2V0KHRoaXMsIG5ldyBNYXAoKSk7XG4gICAgICAgIHJldHVyblxuICAgIH1cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSAmJiBBcnJheS5pc0FycmF5KGFyZ3VtZW50c1swXSkpIHtcbiAgICAgICAgcmV0dXJuIGRlZmluZUN1c3RvbUV2ZW50VGFyZ2V0KGFyZ3VtZW50c1swXSlcbiAgICB9XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IHR5cGVzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGgpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgdHlwZXNbaV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRlZmluZUN1c3RvbUV2ZW50VGFyZ2V0KHR5cGVzKVxuICAgIH1cbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpXG4gICAgLyplc2xpbnQtZW5hYmxlIGNvbnNpc3RlbnQtcmV0dXJuICovXG59XG5cbi8vIFNob3VsZCBiZSBlbnVtZXJhYmxlLCBidXQgY2xhc3MgbWV0aG9kcyBhcmUgbm90IGVudW1lcmFibGUuXG5FdmVudFRhcmdldC5wcm90b3R5cGUgPSB7XG4gICAgLyoqXG4gICAgICogQWRkIGEgZ2l2ZW4gbGlzdGVuZXIgdG8gdGhpcyBldmVudCB0YXJnZXQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSBUaGUgZXZlbnQgbmFtZSB0byBhZGQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgVGhlIGxpc3RlbmVyIHRvIGFkZC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW58e2NhcHR1cmU/OmJvb2xlYW4scGFzc2l2ZT86Ym9vbGVhbixvbmNlPzpib29sZWFufX0gW29wdGlvbnNdIFRoZSBvcHRpb25zIGZvciB0aGlzIGxpc3RlbmVyLlxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxuICAgICAqL1xuICAgIGFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBsaXN0ZW5lciwgb3B0aW9ucykge1xuICAgICAgICBpZiAobGlzdGVuZXIgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gXCJmdW5jdGlvblwiICYmICFpc09iamVjdChsaXN0ZW5lcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInbGlzdGVuZXInIHNob3VsZCBiZSBhIGZ1bmN0aW9uIG9yIGFuIG9iamVjdC5cIilcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxpc3RlbmVycyA9IGdldExpc3RlbmVycyh0aGlzKTtcbiAgICAgICAgY29uc3Qgb3B0aW9uc0lzT2JqID0gaXNPYmplY3Qob3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGNhcHR1cmUgPSBvcHRpb25zSXNPYmpcbiAgICAgICAgICAgID8gQm9vbGVhbihvcHRpb25zLmNhcHR1cmUpXG4gICAgICAgICAgICA6IEJvb2xlYW4ob3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGxpc3RlbmVyVHlwZSA9IGNhcHR1cmUgPyBDQVBUVVJFIDogQlVCQkxFO1xuICAgICAgICBjb25zdCBuZXdOb2RlID0ge1xuICAgICAgICAgICAgbGlzdGVuZXIsXG4gICAgICAgICAgICBsaXN0ZW5lclR5cGUsXG4gICAgICAgICAgICBwYXNzaXZlOiBvcHRpb25zSXNPYmogJiYgQm9vbGVhbihvcHRpb25zLnBhc3NpdmUpLFxuICAgICAgICAgICAgb25jZTogb3B0aW9uc0lzT2JqICYmIEJvb2xlYW4ob3B0aW9ucy5vbmNlKSxcbiAgICAgICAgICAgIG5leHQ6IG51bGwsXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gU2V0IGl0IGFzIHRoZSBmaXJzdCBub2RlIGlmIHRoZSBmaXJzdCBub2RlIGlzIG51bGwuXG4gICAgICAgIGxldCBub2RlID0gbGlzdGVuZXJzLmdldChldmVudE5hbWUpO1xuICAgICAgICBpZiAobm9kZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBsaXN0ZW5lcnMuc2V0KGV2ZW50TmFtZSwgbmV3Tm9kZSk7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRyYXZlcnNlIHRvIHRoZSB0YWlsIHdoaWxlIGNoZWNraW5nIGR1cGxpY2F0aW9uLi5cbiAgICAgICAgbGV0IHByZXYgPSBudWxsO1xuICAgICAgICB3aGlsZSAobm9kZSAhPSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgbm9kZS5saXN0ZW5lciA9PT0gbGlzdGVuZXIgJiZcbiAgICAgICAgICAgICAgICBub2RlLmxpc3RlbmVyVHlwZSA9PT0gbGlzdGVuZXJUeXBlXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAvLyBTaG91bGQgaWdub3JlIGR1cGxpY2F0aW9uLlxuICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcHJldiA9IG5vZGU7XG4gICAgICAgICAgICBub2RlID0gbm9kZS5uZXh0O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIGl0LlxuICAgICAgICBwcmV2Lm5leHQgPSBuZXdOb2RlO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBnaXZlbiBsaXN0ZW5lciBmcm9tIHRoaXMgZXZlbnQgdGFyZ2V0LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgVGhlIGV2ZW50IG5hbWUgdG8gcmVtb3ZlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIFRoZSBsaXN0ZW5lciB0byByZW1vdmUuXG4gICAgICogQHBhcmFtIHtib29sZWFufHtjYXB0dXJlPzpib29sZWFuLHBhc3NpdmU/OmJvb2xlYW4sb25jZT86Ym9vbGVhbn19IFtvcHRpb25zXSBUaGUgb3B0aW9ucyBmb3IgdGhpcyBsaXN0ZW5lci5cbiAgICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICAgKi9cbiAgICByZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKGxpc3RlbmVyID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbGlzdGVuZXJzID0gZ2V0TGlzdGVuZXJzKHRoaXMpO1xuICAgICAgICBjb25zdCBjYXB0dXJlID0gaXNPYmplY3Qob3B0aW9ucylcbiAgICAgICAgICAgID8gQm9vbGVhbihvcHRpb25zLmNhcHR1cmUpXG4gICAgICAgICAgICA6IEJvb2xlYW4ob3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGxpc3RlbmVyVHlwZSA9IGNhcHR1cmUgPyBDQVBUVVJFIDogQlVCQkxFO1xuXG4gICAgICAgIGxldCBwcmV2ID0gbnVsbDtcbiAgICAgICAgbGV0IG5vZGUgPSBsaXN0ZW5lcnMuZ2V0KGV2ZW50TmFtZSk7XG4gICAgICAgIHdoaWxlIChub2RlICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBub2RlLmxpc3RlbmVyID09PSBsaXN0ZW5lciAmJlxuICAgICAgICAgICAgICAgIG5vZGUubGlzdGVuZXJUeXBlID09PSBsaXN0ZW5lclR5cGVcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGlmIChwcmV2ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHByZXYubmV4dCA9IG5vZGUubmV4dDtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5vZGUubmV4dCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuc2V0KGV2ZW50TmFtZSwgbm9kZS5uZXh0KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuZGVsZXRlKGV2ZW50TmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwcmV2ID0gbm9kZTtcbiAgICAgICAgICAgIG5vZGUgPSBub2RlLm5leHQ7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogRGlzcGF0Y2ggYSBnaXZlbiBldmVudC5cbiAgICAgKiBAcGFyYW0ge0V2ZW50fHt0eXBlOnN0cmluZ319IGV2ZW50IFRoZSBldmVudCB0byBkaXNwYXRjaC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gYGZhbHNlYCBpZiBjYW5jZWxlZC5cbiAgICAgKi9cbiAgICBkaXNwYXRjaEV2ZW50KGV2ZW50KSB7XG4gICAgICAgIGlmIChldmVudCA9PSBudWxsIHx8IHR5cGVvZiBldmVudC50eXBlICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImV2ZW50LnR5cGVcIiBzaG91bGQgYmUgYSBzdHJpbmcuJylcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIGxpc3RlbmVycyBhcmVuJ3QgcmVnaXN0ZXJlZCwgdGVybWluYXRlLlxuICAgICAgICBjb25zdCBsaXN0ZW5lcnMgPSBnZXRMaXN0ZW5lcnModGhpcyk7XG4gICAgICAgIGNvbnN0IGV2ZW50TmFtZSA9IGV2ZW50LnR5cGU7XG4gICAgICAgIGxldCBub2RlID0gbGlzdGVuZXJzLmdldChldmVudE5hbWUpO1xuICAgICAgICBpZiAobm9kZSA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2luY2Ugd2UgY2Fubm90IHJld3JpdGUgc2V2ZXJhbCBwcm9wZXJ0aWVzLCBzbyB3cmFwIG9iamVjdC5cbiAgICAgICAgY29uc3Qgd3JhcHBlZEV2ZW50ID0gd3JhcEV2ZW50KHRoaXMsIGV2ZW50KTtcblxuICAgICAgICAvLyBUaGlzIGRvZXNuJ3QgcHJvY2VzcyBjYXB0dXJpbmcgcGhhc2UgYW5kIGJ1YmJsaW5nIHBoYXNlLlxuICAgICAgICAvLyBUaGlzIGlzbid0IHBhcnRpY2lwYXRpbmcgaW4gYSB0cmVlLlxuICAgICAgICBsZXQgcHJldiA9IG51bGw7XG4gICAgICAgIHdoaWxlIChub2RlICE9IG51bGwpIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGlzIGxpc3RlbmVyIGlmIGl0J3Mgb25jZVxuICAgICAgICAgICAgaWYgKG5vZGUub25jZSkge1xuICAgICAgICAgICAgICAgIGlmIChwcmV2ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHByZXYubmV4dCA9IG5vZGUubmV4dDtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5vZGUubmV4dCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuc2V0KGV2ZW50TmFtZSwgbm9kZS5uZXh0KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuZGVsZXRlKGV2ZW50TmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwcmV2ID0gbm9kZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ2FsbCB0aGlzIGxpc3RlbmVyXG4gICAgICAgICAgICBzZXRQYXNzaXZlTGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgd3JhcHBlZEV2ZW50LFxuICAgICAgICAgICAgICAgIG5vZGUucGFzc2l2ZSA/IG5vZGUubGlzdGVuZXIgOiBudWxsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBub2RlLmxpc3RlbmVyID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBub2RlLmxpc3RlbmVyLmNhbGwodGhpcywgd3JhcHBlZEV2ZW50KTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW9mIGNvbnNvbGUgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiBjb25zb2xlLmVycm9yID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICAgIG5vZGUubGlzdGVuZXJUeXBlICE9PSBBVFRSSUJVVEUgJiZcbiAgICAgICAgICAgICAgICB0eXBlb2Ygbm9kZS5saXN0ZW5lci5oYW5kbGVFdmVudCA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBub2RlLmxpc3RlbmVyLmhhbmRsZUV2ZW50KHdyYXBwZWRFdmVudCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEJyZWFrIGlmIGBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb25gIHdhcyBjYWxsZWQuXG4gICAgICAgICAgICBpZiAoaXNTdG9wcGVkKHdyYXBwZWRFdmVudCkpIHtcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBub2RlID0gbm9kZS5uZXh0O1xuICAgICAgICB9XG4gICAgICAgIHNldFBhc3NpdmVMaXN0ZW5lcih3cmFwcGVkRXZlbnQsIG51bGwpO1xuICAgICAgICBzZXRFdmVudFBoYXNlKHdyYXBwZWRFdmVudCwgMCk7XG4gICAgICAgIHNldEN1cnJlbnRUYXJnZXQod3JhcHBlZEV2ZW50LCBudWxsKTtcblxuICAgICAgICByZXR1cm4gIXdyYXBwZWRFdmVudC5kZWZhdWx0UHJldmVudGVkXG4gICAgfSxcbn07XG5cbi8vIGBjb25zdHJ1Y3RvcmAgaXMgbm90IGVudW1lcmFibGUuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRXZlbnRUYXJnZXQucHJvdG90eXBlLCBcImNvbnN0cnVjdG9yXCIsIHtcbiAgICB2YWx1ZTogRXZlbnRUYXJnZXQsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIHdyaXRhYmxlOiB0cnVlLFxufSk7XG5cbi8vIEVuc3VyZSBgZXZlbnRUYXJnZXQgaW5zdGFuY2VvZiB3aW5kb3cuRXZlbnRUYXJnZXRgIGlzIGB0cnVlYC5cbmlmIChcbiAgICB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgdHlwZW9mIHdpbmRvdy5FdmVudFRhcmdldCAhPT0gXCJ1bmRlZmluZWRcIlxuKSB7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKEV2ZW50VGFyZ2V0LnByb3RvdHlwZSwgd2luZG93LkV2ZW50VGFyZ2V0LnByb3RvdHlwZSk7XG59XG5cbmV4cG9ydHMuZGVmaW5lRXZlbnRBdHRyaWJ1dGUgPSBkZWZpbmVFdmVudEF0dHJpYnV0ZTtcbmV4cG9ydHMuRXZlbnRUYXJnZXQgPSBFdmVudFRhcmdldDtcbmV4cG9ydHMuZGVmYXVsdCA9IEV2ZW50VGFyZ2V0O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50VGFyZ2V0XG5tb2R1bGUuZXhwb3J0cy5FdmVudFRhcmdldCA9IG1vZHVsZS5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IEV2ZW50VGFyZ2V0XG5tb2R1bGUuZXhwb3J0cy5kZWZpbmVFdmVudEF0dHJpYnV0ZSA9IGRlZmluZUV2ZW50QXR0cmlidXRlXG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmVudC10YXJnZXQtc2hpbS5qcy5tYXBcbiIsImNvbnN0IHtSZWFkYWJsZX0gPSByZXF1aXJlKCdzdHJlYW0nKTtcblxuLyoqXG4gKiBAdHlwZSB7V2Vha01hcDxCbG9iLCB7dHlwZTogc3RyaW5nLCBzaXplOiBudW1iZXIsIHBhcnRzOiAoQmxvYiB8IEJ1ZmZlcilbXSB9Pn1cbiAqL1xuY29uc3Qgd20gPSBuZXcgV2Vha01hcCgpO1xuXG5hc3luYyBmdW5jdGlvbiAqIHJlYWQocGFydHMpIHtcblx0Zm9yIChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XG5cdFx0aWYgKCdzdHJlYW0nIGluIHBhcnQpIHtcblx0XHRcdHlpZWxkICogcGFydC5zdHJlYW0oKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0eWllbGQgcGFydDtcblx0XHR9XG5cdH1cbn1cblxuY2xhc3MgQmxvYiB7XG5cdC8qKlxuXHQgKiBUaGUgQmxvYigpIGNvbnN0cnVjdG9yIHJldHVybnMgYSBuZXcgQmxvYiBvYmplY3QuIFRoZSBjb250ZW50XG5cdCAqIG9mIHRoZSBibG9iIGNvbnNpc3RzIG9mIHRoZSBjb25jYXRlbmF0aW9uIG9mIHRoZSB2YWx1ZXMgZ2l2ZW5cblx0ICogaW4gdGhlIHBhcmFtZXRlciBhcnJheS5cblx0ICpcblx0ICogQHBhcmFtIHsoQXJyYXlCdWZmZXJMaWtlIHwgQXJyYXlCdWZmZXJWaWV3IHwgQmxvYiB8IEJ1ZmZlciB8IHN0cmluZylbXX0gYmxvYlBhcnRzXG5cdCAqIEBwYXJhbSB7eyB0eXBlPzogc3RyaW5nIH19IFtvcHRpb25zXVxuXHQgKi9cblx0Y29uc3RydWN0b3IoYmxvYlBhcnRzID0gW10sIG9wdGlvbnMgPSB7fSkge1xuXHRcdGxldCBzaXplID0gMDtcblxuXHRcdGNvbnN0IHBhcnRzID0gYmxvYlBhcnRzLm1hcChlbGVtZW50ID0+IHtcblx0XHRcdGxldCBidWZmZXI7XG5cdFx0XHRpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEJ1ZmZlcikge1xuXHRcdFx0XHRidWZmZXIgPSBlbGVtZW50O1xuXHRcdFx0fSBlbHNlIGlmIChBcnJheUJ1ZmZlci5pc1ZpZXcoZWxlbWVudCkpIHtcblx0XHRcdFx0YnVmZmVyID0gQnVmZmVyLmZyb20oZWxlbWVudC5idWZmZXIsIGVsZW1lbnQuYnl0ZU9mZnNldCwgZWxlbWVudC5ieXRlTGVuZ3RoKTtcblx0XHRcdH0gZWxzZSBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG5cdFx0XHRcdGJ1ZmZlciA9IEJ1ZmZlci5mcm9tKGVsZW1lbnQpO1xuXHRcdFx0fSBlbHNlIGlmIChlbGVtZW50IGluc3RhbmNlb2YgQmxvYikge1xuXHRcdFx0XHRidWZmZXIgPSBlbGVtZW50O1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0YnVmZmVyID0gQnVmZmVyLmZyb20odHlwZW9mIGVsZW1lbnQgPT09ICdzdHJpbmcnID8gZWxlbWVudCA6IFN0cmluZyhlbGVtZW50KSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSB1bmljb3JuL2V4cGxpY2l0LWxlbmd0aC1jaGVja1xuXHRcdFx0c2l6ZSArPSBidWZmZXIubGVuZ3RoIHx8IGJ1ZmZlci5zaXplIHx8IDA7XG5cdFx0XHRyZXR1cm4gYnVmZmVyO1xuXHRcdH0pO1xuXG5cdFx0Y29uc3QgdHlwZSA9IG9wdGlvbnMudHlwZSA9PT0gdW5kZWZpbmVkID8gJycgOiBTdHJpbmcob3B0aW9ucy50eXBlKS50b0xvd2VyQ2FzZSgpO1xuXG5cdFx0d20uc2V0KHRoaXMsIHtcblx0XHRcdHR5cGU6IC9bXlxcdTAwMjAtXFx1MDA3RV0vLnRlc3QodHlwZSkgPyAnJyA6IHR5cGUsXG5cdFx0XHRzaXplLFxuXHRcdFx0cGFydHNcblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgQmxvYiBpbnRlcmZhY2UncyBzaXplIHByb3BlcnR5IHJldHVybnMgdGhlXG5cdCAqIHNpemUgb2YgdGhlIEJsb2IgaW4gYnl0ZXMuXG5cdCAqL1xuXHRnZXQgc2l6ZSgpIHtcblx0XHRyZXR1cm4gd20uZ2V0KHRoaXMpLnNpemU7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIHR5cGUgcHJvcGVydHkgb2YgYSBCbG9iIG9iamVjdCByZXR1cm5zIHRoZSBNSU1FIHR5cGUgb2YgdGhlIGZpbGUuXG5cdCAqL1xuXHRnZXQgdHlwZSgpIHtcblx0XHRyZXR1cm4gd20uZ2V0KHRoaXMpLnR5cGU7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIHRleHQoKSBtZXRob2QgaW4gdGhlIEJsb2IgaW50ZXJmYWNlIHJldHVybnMgYSBQcm9taXNlXG5cdCAqIHRoYXQgcmVzb2x2ZXMgd2l0aCBhIHN0cmluZyBjb250YWluaW5nIHRoZSBjb250ZW50cyBvZlxuXHQgKiB0aGUgYmxvYiwgaW50ZXJwcmV0ZWQgYXMgVVRGLTguXG5cdCAqXG5cdCAqIEByZXR1cm4ge1Byb21pc2U8c3RyaW5nPn1cblx0ICovXG5cdGFzeW5jIHRleHQoKSB7XG5cdFx0cmV0dXJuIEJ1ZmZlci5mcm9tKGF3YWl0IHRoaXMuYXJyYXlCdWZmZXIoKSkudG9TdHJpbmcoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgYXJyYXlCdWZmZXIoKSBtZXRob2QgaW4gdGhlIEJsb2IgaW50ZXJmYWNlIHJldHVybnMgYVxuXHQgKiBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgY29udGVudHMgb2YgdGhlIGJsb2IgYXNcblx0ICogYmluYXJ5IGRhdGEgY29udGFpbmVkIGluIGFuIEFycmF5QnVmZmVyLlxuXHQgKlxuXHQgKiBAcmV0dXJuIHtQcm9taXNlPEFycmF5QnVmZmVyPn1cblx0ICovXG5cdGFzeW5jIGFycmF5QnVmZmVyKCkge1xuXHRcdGNvbnN0IGRhdGEgPSBuZXcgVWludDhBcnJheSh0aGlzLnNpemUpO1xuXHRcdGxldCBvZmZzZXQgPSAwO1xuXHRcdGZvciBhd2FpdCAoY29uc3QgY2h1bmsgb2YgdGhpcy5zdHJlYW0oKSkge1xuXHRcdFx0ZGF0YS5zZXQoY2h1bmssIG9mZnNldCk7XG5cdFx0XHRvZmZzZXQgKz0gY2h1bmsubGVuZ3RoO1xuXHRcdH1cblxuXHRcdHJldHVybiBkYXRhLmJ1ZmZlcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgQmxvYiBpbnRlcmZhY2UncyBzdHJlYW0oKSBtZXRob2QgaXMgZGlmZmVyZW5jZSBmcm9tIG5hdGl2ZVxuXHQgKiBhbmQgdXNlcyBub2RlIHN0cmVhbXMgaW5zdGVhZCBvZiB3aGF0d2cgc3RyZWFtcy5cblx0ICpcblx0ICogQHJldHVybnMge1JlYWRhYmxlfSBOb2RlIHJlYWRhYmxlIHN0cmVhbVxuXHQgKi9cblx0c3RyZWFtKCkge1xuXHRcdHJldHVybiBSZWFkYWJsZS5mcm9tKHJlYWQod20uZ2V0KHRoaXMpLnBhcnRzKSk7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIEJsb2IgaW50ZXJmYWNlJ3Mgc2xpY2UoKSBtZXRob2QgY3JlYXRlcyBhbmQgcmV0dXJucyBhXG5cdCAqIG5ldyBCbG9iIG9iamVjdCB3aGljaCBjb250YWlucyBkYXRhIGZyb20gYSBzdWJzZXQgb2YgdGhlXG5cdCAqIGJsb2Igb24gd2hpY2ggaXQncyBjYWxsZWQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnRdXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBbZW5kXVxuXHQgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVdXG5cdCAqL1xuXHRzbGljZShzdGFydCA9IDAsIGVuZCA9IHRoaXMuc2l6ZSwgdHlwZSA9ICcnKSB7XG5cdFx0Y29uc3Qge3NpemV9ID0gdGhpcztcblxuXHRcdGxldCByZWxhdGl2ZVN0YXJ0ID0gc3RhcnQgPCAwID8gTWF0aC5tYXgoc2l6ZSArIHN0YXJ0LCAwKSA6IE1hdGgubWluKHN0YXJ0LCBzaXplKTtcblx0XHRsZXQgcmVsYXRpdmVFbmQgPSBlbmQgPCAwID8gTWF0aC5tYXgoc2l6ZSArIGVuZCwgMCkgOiBNYXRoLm1pbihlbmQsIHNpemUpO1xuXG5cdFx0Y29uc3Qgc3BhbiA9IE1hdGgubWF4KHJlbGF0aXZlRW5kIC0gcmVsYXRpdmVTdGFydCwgMCk7XG5cdFx0Y29uc3QgcGFydHMgPSB3bS5nZXQodGhpcykucGFydHMudmFsdWVzKCk7XG5cdFx0Y29uc3QgYmxvYlBhcnRzID0gW107XG5cdFx0bGV0IGFkZGVkID0gMDtcblxuXHRcdGZvciAoY29uc3QgcGFydCBvZiBwYXJ0cykge1xuXHRcdFx0Y29uc3Qgc2l6ZSA9IEFycmF5QnVmZmVyLmlzVmlldyhwYXJ0KSA/IHBhcnQuYnl0ZUxlbmd0aCA6IHBhcnQuc2l6ZTtcblx0XHRcdGlmIChyZWxhdGl2ZVN0YXJ0ICYmIHNpemUgPD0gcmVsYXRpdmVTdGFydCkge1xuXHRcdFx0XHQvLyBTa2lwIHRoZSBiZWdpbm5pbmcgYW5kIGNoYW5nZSB0aGUgcmVsYXRpdmVcblx0XHRcdFx0Ly8gc3RhcnQgJiBlbmQgcG9zaXRpb24gYXMgd2Ugc2tpcCB0aGUgdW53YW50ZWQgcGFydHNcblx0XHRcdFx0cmVsYXRpdmVTdGFydCAtPSBzaXplO1xuXHRcdFx0XHRyZWxhdGl2ZUVuZCAtPSBzaXplO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y29uc3QgY2h1bmsgPSBwYXJ0LnNsaWNlKHJlbGF0aXZlU3RhcnQsIE1hdGgubWluKHNpemUsIHJlbGF0aXZlRW5kKSk7XG5cdFx0XHRcdGJsb2JQYXJ0cy5wdXNoKGNodW5rKTtcblx0XHRcdFx0YWRkZWQgKz0gQXJyYXlCdWZmZXIuaXNWaWV3KGNodW5rKSA/IGNodW5rLmJ5dGVMZW5ndGggOiBjaHVuay5zaXplO1xuXHRcdFx0XHRyZWxhdGl2ZVN0YXJ0ID0gMDsgLy8gQWxsIG5leHQgc2VxdWVudGFsIHBhcnRzIHNob3VsZCBzdGFydCBhdCAwXG5cblx0XHRcdFx0Ly8gZG9uJ3QgYWRkIHRoZSBvdmVyZmxvdyB0byBuZXcgYmxvYlBhcnRzXG5cdFx0XHRcdGlmIChhZGRlZCA+PSBzcGFuKSB7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRjb25zdCBibG9iID0gbmV3IEJsb2IoW10sIHt0eXBlOiBTdHJpbmcodHlwZSkudG9Mb3dlckNhc2UoKX0pO1xuXHRcdE9iamVjdC5hc3NpZ24od20uZ2V0KGJsb2IpLCB7c2l6ZTogc3BhbiwgcGFydHM6IGJsb2JQYXJ0c30pO1xuXG5cdFx0cmV0dXJuIGJsb2I7XG5cdH1cblxuXHRnZXQgW1N5bWJvbC50b1N0cmluZ1RhZ10oKSB7XG5cdFx0cmV0dXJuICdCbG9iJztcblx0fVxuXG5cdHN0YXRpYyBbU3ltYm9sLmhhc0luc3RhbmNlXShvYmplY3QpIHtcblx0XHRyZXR1cm4gKFxuXHRcdFx0b2JqZWN0ICYmXG5cdFx0XHR0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJlxuXHRcdFx0dHlwZW9mIG9iamVjdC5zdHJlYW0gPT09ICdmdW5jdGlvbicgJiZcblx0XHRcdG9iamVjdC5zdHJlYW0ubGVuZ3RoID09PSAwICYmXG5cdFx0XHR0eXBlb2Ygb2JqZWN0LmNvbnN0cnVjdG9yID09PSAnZnVuY3Rpb24nICYmXG5cdFx0XHQvXihCbG9ifEZpbGUpJC8udGVzdChvYmplY3RbU3ltYm9sLnRvU3RyaW5nVGFnXSlcblx0XHQpO1xuXHR9XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKEJsb2IucHJvdG90eXBlLCB7XG5cdHNpemU6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0dHlwZToge2VudW1lcmFibGU6IHRydWV9LFxuXHRzbGljZToge2VudW1lcmFibGU6IHRydWV9XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBCbG9iO1xuIiwiJ3VzZSBzdHJpY3QnO1xuY29uc3QgZmV0Y2ggPSByZXF1aXJlKCdub2RlLWZldGNoJyk7XG5jb25zdCBBYm9ydENvbnRyb2xsZXIgPSByZXF1aXJlKCdhYm9ydC1jb250cm9sbGVyJyk7XG5cbmNvbnN0IFRFTl9NRUdBQllURVMgPSAxMDAwICogMTAwMCAqIDEwO1xuXG5pZiAoIWdsb2JhbC5mZXRjaCkge1xuXHRnbG9iYWwuZmV0Y2ggPSAodXJsLCBvcHRpb25zKSA9PiBmZXRjaCh1cmwsIHtoaWdoV2F0ZXJNYXJrOiBURU5fTUVHQUJZVEVTLCAuLi5vcHRpb25zfSk7XG59XG5cbmlmICghZ2xvYmFsLkhlYWRlcnMpIHtcblx0Z2xvYmFsLkhlYWRlcnMgPSBmZXRjaC5IZWFkZXJzO1xufVxuXG5pZiAoIWdsb2JhbC5SZXF1ZXN0KSB7XG5cdGdsb2JhbC5SZXF1ZXN0ID0gZmV0Y2guUmVxdWVzdDtcbn1cblxuaWYgKCFnbG9iYWwuUmVzcG9uc2UpIHtcblx0Z2xvYmFsLlJlc3BvbnNlID0gZmV0Y2guUmVzcG9uc2U7XG59XG5cbmlmICghZ2xvYmFsLkFib3J0Q29udHJvbGxlcikge1xuXHRnbG9iYWwuQWJvcnRDb250cm9sbGVyID0gQWJvcnRDb250cm9sbGVyO1xufVxuXG5pZiAoIWdsb2JhbC5SZWFkYWJsZVN0cmVhbSkge1xuXHR0cnkge1xuXHRcdGdsb2JhbC5SZWFkYWJsZVN0cmVhbSA9IHJlcXVpcmUoJ3dlYi1zdHJlYW1zLXBvbHlmaWxsL3BvbnlmaWxsL2VzMjAxOCcpO1xuXHR9IGNhdGNoIChfKSB7fVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJ2t5L3VtZCcpO1xuIiwiKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcblx0dHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCkgOlxuXHR0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoZmFjdG9yeSkgOlxuXHQoZ2xvYmFsID0gdHlwZW9mIGdsb2JhbFRoaXMgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsVGhpcyA6IGdsb2JhbCB8fCBzZWxmLCBnbG9iYWwua3kgPSBmYWN0b3J5KCkpO1xufSh0aGlzLCAoZnVuY3Rpb24gKCkgeyAndXNlIHN0cmljdCc7XG5cblx0LyohIE1JVCBMaWNlbnNlIMKpIFNpbmRyZSBTb3JodXMgKi9cblxuXHRjb25zdCBnbG9iYWxzID0ge307XG5cblx0Y29uc3QgZ2V0R2xvYmFsID0gcHJvcGVydHkgPT4ge1xuXHRcdC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5cdFx0aWYgKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyAmJiBzZWxmICYmIHByb3BlcnR5IGluIHNlbGYpIHtcblx0XHRcdHJldHVybiBzZWxmO1xuXHRcdH1cblxuXHRcdC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5cdFx0aWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdyAmJiBwcm9wZXJ0eSBpbiB3aW5kb3cpIHtcblx0XHRcdHJldHVybiB3aW5kb3c7XG5cdFx0fVxuXG5cdFx0aWYgKHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnICYmIGdsb2JhbCAmJiBwcm9wZXJ0eSBpbiBnbG9iYWwpIHtcblx0XHRcdHJldHVybiBnbG9iYWw7XG5cdFx0fVxuXG5cdFx0LyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cblx0XHRpZiAodHlwZW9mIGdsb2JhbFRoaXMgIT09ICd1bmRlZmluZWQnICYmIGdsb2JhbFRoaXMpIHtcblx0XHRcdHJldHVybiBnbG9iYWxUaGlzO1xuXHRcdH1cblx0fTtcblxuXHRjb25zdCBnbG9iYWxQcm9wZXJ0aWVzID0gW1xuXHRcdCdIZWFkZXJzJyxcblx0XHQnUmVxdWVzdCcsXG5cdFx0J1Jlc3BvbnNlJyxcblx0XHQnUmVhZGFibGVTdHJlYW0nLFxuXHRcdCdmZXRjaCcsXG5cdFx0J0Fib3J0Q29udHJvbGxlcicsXG5cdFx0J0Zvcm1EYXRhJ1xuXHRdO1xuXG5cdGZvciAoY29uc3QgcHJvcGVydHkgb2YgZ2xvYmFsUHJvcGVydGllcykge1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWxzLCBwcm9wZXJ0eSwge1xuXHRcdFx0Z2V0KCkge1xuXHRcdFx0XHRjb25zdCBnbG9iYWxPYmplY3QgPSBnZXRHbG9iYWwocHJvcGVydHkpO1xuXHRcdFx0XHRjb25zdCB2YWx1ZSA9IGdsb2JhbE9iamVjdCAmJiBnbG9iYWxPYmplY3RbcHJvcGVydHldO1xuXHRcdFx0XHRyZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nID8gdmFsdWUuYmluZChnbG9iYWxPYmplY3QpIDogdmFsdWU7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXHRjb25zdCBpc09iamVjdCA9IHZhbHVlID0+IHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCc7XG5cdGNvbnN0IHN1cHBvcnRzQWJvcnRDb250cm9sbGVyID0gdHlwZW9mIGdsb2JhbHMuQWJvcnRDb250cm9sbGVyID09PSAnZnVuY3Rpb24nO1xuXHRjb25zdCBzdXBwb3J0c1N0cmVhbXMgPSB0eXBlb2YgZ2xvYmFscy5SZWFkYWJsZVN0cmVhbSA9PT0gJ2Z1bmN0aW9uJztcblx0Y29uc3Qgc3VwcG9ydHNGb3JtRGF0YSA9IHR5cGVvZiBnbG9iYWxzLkZvcm1EYXRhID09PSAnZnVuY3Rpb24nO1xuXG5cdGNvbnN0IG1lcmdlSGVhZGVycyA9IChzb3VyY2UxLCBzb3VyY2UyKSA9PiB7XG5cdFx0Y29uc3QgcmVzdWx0ID0gbmV3IGdsb2JhbHMuSGVhZGVycyhzb3VyY2UxIHx8IHt9KTtcblx0XHRjb25zdCBpc0hlYWRlcnNJbnN0YW5jZSA9IHNvdXJjZTIgaW5zdGFuY2VvZiBnbG9iYWxzLkhlYWRlcnM7XG5cdFx0Y29uc3Qgc291cmNlID0gbmV3IGdsb2JhbHMuSGVhZGVycyhzb3VyY2UyIHx8IHt9KTtcblxuXHRcdGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIHNvdXJjZSkge1xuXHRcdFx0aWYgKChpc0hlYWRlcnNJbnN0YW5jZSAmJiB2YWx1ZSA9PT0gJ3VuZGVmaW5lZCcpIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0cmVzdWx0LmRlbGV0ZShrZXkpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmVzdWx0LnNldChrZXksIHZhbHVlKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9O1xuXG5cdGNvbnN0IGRlZXBNZXJnZSA9ICguLi5zb3VyY2VzKSA9PiB7XG5cdFx0bGV0IHJldHVyblZhbHVlID0ge307XG5cdFx0bGV0IGhlYWRlcnMgPSB7fTtcblxuXHRcdGZvciAoY29uc3Qgc291cmNlIG9mIHNvdXJjZXMpIHtcblx0XHRcdGlmIChBcnJheS5pc0FycmF5KHNvdXJjZSkpIHtcblx0XHRcdFx0aWYgKCEoQXJyYXkuaXNBcnJheShyZXR1cm5WYWx1ZSkpKSB7XG5cdFx0XHRcdFx0cmV0dXJuVmFsdWUgPSBbXTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVyblZhbHVlID0gWy4uLnJldHVyblZhbHVlLCAuLi5zb3VyY2VdO1xuXHRcdFx0fSBlbHNlIGlmIChpc09iamVjdChzb3VyY2UpKSB7XG5cdFx0XHRcdGZvciAobGV0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhzb3VyY2UpKSB7XG5cdFx0XHRcdFx0aWYgKGlzT2JqZWN0KHZhbHVlKSAmJiAoa2V5IGluIHJldHVyblZhbHVlKSkge1xuXHRcdFx0XHRcdFx0dmFsdWUgPSBkZWVwTWVyZ2UocmV0dXJuVmFsdWVba2V5XSwgdmFsdWUpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHJldHVyblZhbHVlID0gey4uLnJldHVyblZhbHVlLCBba2V5XTogdmFsdWV9O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKGlzT2JqZWN0KHNvdXJjZS5oZWFkZXJzKSkge1xuXHRcdFx0XHRcdGhlYWRlcnMgPSBtZXJnZUhlYWRlcnMoaGVhZGVycywgc291cmNlLmhlYWRlcnMpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdHJldHVyblZhbHVlLmhlYWRlcnMgPSBoZWFkZXJzO1xuXHRcdH1cblxuXHRcdHJldHVybiByZXR1cm5WYWx1ZTtcblx0fTtcblxuXHRjb25zdCByZXF1ZXN0TWV0aG9kcyA9IFtcblx0XHQnZ2V0Jyxcblx0XHQncG9zdCcsXG5cdFx0J3B1dCcsXG5cdFx0J3BhdGNoJyxcblx0XHQnaGVhZCcsXG5cdFx0J2RlbGV0ZSdcblx0XTtcblxuXHRjb25zdCByZXNwb25zZVR5cGVzID0ge1xuXHRcdGpzb246ICdhcHBsaWNhdGlvbi9qc29uJyxcblx0XHR0ZXh0OiAndGV4dC8qJyxcblx0XHRmb3JtRGF0YTogJ211bHRpcGFydC9mb3JtLWRhdGEnLFxuXHRcdGFycmF5QnVmZmVyOiAnKi8qJyxcblx0XHRibG9iOiAnKi8qJ1xuXHR9O1xuXG5cdGNvbnN0IHJldHJ5TWV0aG9kcyA9IFtcblx0XHQnZ2V0Jyxcblx0XHQncHV0Jyxcblx0XHQnaGVhZCcsXG5cdFx0J2RlbGV0ZScsXG5cdFx0J29wdGlvbnMnLFxuXHRcdCd0cmFjZSdcblx0XTtcblxuXHRjb25zdCByZXRyeVN0YXR1c0NvZGVzID0gW1xuXHRcdDQwOCxcblx0XHQ0MTMsXG5cdFx0NDI5LFxuXHRcdDUwMCxcblx0XHQ1MDIsXG5cdFx0NTAzLFxuXHRcdDUwNFxuXHRdO1xuXG5cdGNvbnN0IHJldHJ5QWZ0ZXJTdGF0dXNDb2RlcyA9IFtcblx0XHQ0MTMsXG5cdFx0NDI5LFxuXHRcdDUwM1xuXHRdO1xuXG5cdGNvbnN0IHN0b3AgPSBTeW1ib2woJ3N0b3AnKTtcblxuXHRjbGFzcyBIVFRQRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG5cdFx0Y29uc3RydWN0b3IocmVzcG9uc2UpIHtcblx0XHRcdC8vIFNldCB0aGUgbWVzc2FnZSB0byB0aGUgc3RhdHVzIHRleHQsIHN1Y2ggYXMgVW5hdXRob3JpemVkLFxuXHRcdFx0Ly8gd2l0aCBzb21lIGZhbGxiYWNrcy4gVGhpcyBtZXNzYWdlIHNob3VsZCBuZXZlciBiZSB1bmRlZmluZWQuXG5cdFx0XHRzdXBlcihcblx0XHRcdFx0cmVzcG9uc2Uuc3RhdHVzVGV4dCB8fFxuXHRcdFx0XHRTdHJpbmcoXG5cdFx0XHRcdFx0KHJlc3BvbnNlLnN0YXR1cyA9PT0gMCB8fCByZXNwb25zZS5zdGF0dXMpID9cblx0XHRcdFx0XHRcdHJlc3BvbnNlLnN0YXR1cyA6ICdVbmtub3duIHJlc3BvbnNlIGVycm9yJ1xuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdFx0dGhpcy5uYW1lID0gJ0hUVFBFcnJvcic7XG5cdFx0XHR0aGlzLnJlc3BvbnNlID0gcmVzcG9uc2U7XG5cdFx0fVxuXHR9XG5cblx0Y2xhc3MgVGltZW91dEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuXHRcdGNvbnN0cnVjdG9yKHJlcXVlc3QpIHtcblx0XHRcdHN1cGVyKCdSZXF1ZXN0IHRpbWVkIG91dCcpO1xuXHRcdFx0dGhpcy5uYW1lID0gJ1RpbWVvdXRFcnJvcic7XG5cdFx0XHR0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuXHRcdH1cblx0fVxuXG5cdGNvbnN0IGRlbGF5ID0gbXMgPT4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG5cblx0Ly8gYFByb21pc2UucmFjZSgpYCB3b3JrYXJvdW5kICgjOTEpXG5cdGNvbnN0IHRpbWVvdXQgPSAocmVxdWVzdCwgYWJvcnRDb250cm9sbGVyLCBvcHRpb25zKSA9PlxuXHRcdG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblx0XHRcdGNvbnN0IHRpbWVvdXRJRCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0XHRpZiAoYWJvcnRDb250cm9sbGVyKSB7XG5cdFx0XHRcdFx0YWJvcnRDb250cm9sbGVyLmFib3J0KCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZWplY3QobmV3IFRpbWVvdXRFcnJvcihyZXF1ZXN0KSk7XG5cdFx0XHR9LCBvcHRpb25zLnRpbWVvdXQpO1xuXG5cdFx0XHQvKiBlc2xpbnQtZGlzYWJsZSBwcm9taXNlL3ByZWZlci1hd2FpdC10by10aGVuICovXG5cdFx0XHRvcHRpb25zLmZldGNoKHJlcXVlc3QpXG5cdFx0XHRcdC50aGVuKHJlc29sdmUpXG5cdFx0XHRcdC5jYXRjaChyZWplY3QpXG5cdFx0XHRcdC50aGVuKCgpID0+IHtcblx0XHRcdFx0XHRjbGVhclRpbWVvdXQodGltZW91dElEKTtcblx0XHRcdFx0fSk7XG5cdFx0XHQvKiBlc2xpbnQtZW5hYmxlIHByb21pc2UvcHJlZmVyLWF3YWl0LXRvLXRoZW4gKi9cblx0XHR9KTtcblxuXHRjb25zdCBub3JtYWxpemVSZXF1ZXN0TWV0aG9kID0gaW5wdXQgPT4gcmVxdWVzdE1ldGhvZHMuaW5jbHVkZXMoaW5wdXQpID8gaW5wdXQudG9VcHBlckNhc2UoKSA6IGlucHV0O1xuXG5cdGNvbnN0IGRlZmF1bHRSZXRyeU9wdGlvbnMgPSB7XG5cdFx0bGltaXQ6IDIsXG5cdFx0bWV0aG9kczogcmV0cnlNZXRob2RzLFxuXHRcdHN0YXR1c0NvZGVzOiByZXRyeVN0YXR1c0NvZGVzLFxuXHRcdGFmdGVyU3RhdHVzQ29kZXM6IHJldHJ5QWZ0ZXJTdGF0dXNDb2Rlc1xuXHR9O1xuXG5cdGNvbnN0IG5vcm1hbGl6ZVJldHJ5T3B0aW9ucyA9IChyZXRyeSA9IHt9KSA9PiB7XG5cdFx0aWYgKHR5cGVvZiByZXRyeSA9PT0gJ251bWJlcicpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdC4uLmRlZmF1bHRSZXRyeU9wdGlvbnMsXG5cdFx0XHRcdGxpbWl0OiByZXRyeVxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAocmV0cnkubWV0aG9kcyAmJiAhQXJyYXkuaXNBcnJheShyZXRyeS5tZXRob2RzKSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdyZXRyeS5tZXRob2RzIG11c3QgYmUgYW4gYXJyYXknKTtcblx0XHR9XG5cblx0XHRpZiAocmV0cnkuc3RhdHVzQ29kZXMgJiYgIUFycmF5LmlzQXJyYXkocmV0cnkuc3RhdHVzQ29kZXMpKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ3JldHJ5LnN0YXR1c0NvZGVzIG11c3QgYmUgYW4gYXJyYXknKTtcblx0XHR9XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0Li4uZGVmYXVsdFJldHJ5T3B0aW9ucyxcblx0XHRcdC4uLnJldHJ5LFxuXHRcdFx0YWZ0ZXJTdGF0dXNDb2RlczogcmV0cnlBZnRlclN0YXR1c0NvZGVzXG5cdFx0fTtcblx0fTtcblxuXHQvLyBUaGUgbWF4aW11bSB2YWx1ZSBvZiBhIDMyYml0IGludCAoc2VlIGlzc3VlICMxMTcpXG5cdGNvbnN0IG1heFNhZmVUaW1lb3V0ID0gMjE0NzQ4MzY0NztcblxuXHRjbGFzcyBLeSB7XG5cdFx0Y29uc3RydWN0b3IoaW5wdXQsIG9wdGlvbnMgPSB7fSkge1xuXHRcdFx0dGhpcy5fcmV0cnlDb3VudCA9IDA7XG5cdFx0XHR0aGlzLl9pbnB1dCA9IGlucHV0O1xuXHRcdFx0dGhpcy5fb3B0aW9ucyA9IHtcblx0XHRcdFx0Ly8gVE9ETzogY3JlZGVudGlhbHMgY2FuIGJlIHJlbW92ZWQgd2hlbiB0aGUgc3BlYyBjaGFuZ2UgaXMgaW1wbGVtZW50ZWQgaW4gYWxsIGJyb3dzZXJzLiBDb250ZXh0OiBodHRwczovL3d3dy5jaHJvbWVzdGF0dXMuY29tL2ZlYXR1cmUvNDUzOTQ3MzMxMjM1MDIwOFxuXHRcdFx0XHRjcmVkZW50aWFsczogdGhpcy5faW5wdXQuY3JlZGVudGlhbHMgfHwgJ3NhbWUtb3JpZ2luJyxcblx0XHRcdFx0Li4ub3B0aW9ucyxcblx0XHRcdFx0aGVhZGVyczogbWVyZ2VIZWFkZXJzKHRoaXMuX2lucHV0LmhlYWRlcnMsIG9wdGlvbnMuaGVhZGVycyksXG5cdFx0XHRcdGhvb2tzOiBkZWVwTWVyZ2Uoe1xuXHRcdFx0XHRcdGJlZm9yZVJlcXVlc3Q6IFtdLFxuXHRcdFx0XHRcdGJlZm9yZVJldHJ5OiBbXSxcblx0XHRcdFx0XHRhZnRlclJlc3BvbnNlOiBbXVxuXHRcdFx0XHR9LCBvcHRpb25zLmhvb2tzKSxcblx0XHRcdFx0bWV0aG9kOiBub3JtYWxpemVSZXF1ZXN0TWV0aG9kKG9wdGlvbnMubWV0aG9kIHx8IHRoaXMuX2lucHV0Lm1ldGhvZCksXG5cdFx0XHRcdHByZWZpeFVybDogU3RyaW5nKG9wdGlvbnMucHJlZml4VXJsIHx8ICcnKSxcblx0XHRcdFx0cmV0cnk6IG5vcm1hbGl6ZVJldHJ5T3B0aW9ucyhvcHRpb25zLnJldHJ5KSxcblx0XHRcdFx0dGhyb3dIdHRwRXJyb3JzOiBvcHRpb25zLnRocm93SHR0cEVycm9ycyAhPT0gZmFsc2UsXG5cdFx0XHRcdHRpbWVvdXQ6IHR5cGVvZiBvcHRpb25zLnRpbWVvdXQgPT09ICd1bmRlZmluZWQnID8gMTAwMDAgOiBvcHRpb25zLnRpbWVvdXQsXG5cdFx0XHRcdGZldGNoOiBvcHRpb25zLmZldGNoIHx8IGdsb2JhbHMuZmV0Y2hcblx0XHRcdH07XG5cblx0XHRcdGlmICh0eXBlb2YgdGhpcy5faW5wdXQgIT09ICdzdHJpbmcnICYmICEodGhpcy5faW5wdXQgaW5zdGFuY2VvZiBVUkwgfHwgdGhpcy5faW5wdXQgaW5zdGFuY2VvZiBnbG9iYWxzLlJlcXVlc3QpKSB7XG5cdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ2BpbnB1dGAgbXVzdCBiZSBhIHN0cmluZywgVVJMLCBvciBSZXF1ZXN0Jyk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICh0aGlzLl9vcHRpb25zLnByZWZpeFVybCAmJiB0eXBlb2YgdGhpcy5faW5wdXQgPT09ICdzdHJpbmcnKSB7XG5cdFx0XHRcdGlmICh0aGlzLl9pbnB1dC5zdGFydHNXaXRoKCcvJykpIHtcblx0XHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ2BpbnB1dGAgbXVzdCBub3QgYmVnaW4gd2l0aCBhIHNsYXNoIHdoZW4gdXNpbmcgYHByZWZpeFVybGAnKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICghdGhpcy5fb3B0aW9ucy5wcmVmaXhVcmwuZW5kc1dpdGgoJy8nKSkge1xuXHRcdFx0XHRcdHRoaXMuX29wdGlvbnMucHJlZml4VXJsICs9ICcvJztcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHRoaXMuX2lucHV0ID0gdGhpcy5fb3B0aW9ucy5wcmVmaXhVcmwgKyB0aGlzLl9pbnB1dDtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHN1cHBvcnRzQWJvcnRDb250cm9sbGVyKSB7XG5cdFx0XHRcdHRoaXMuYWJvcnRDb250cm9sbGVyID0gbmV3IGdsb2JhbHMuQWJvcnRDb250cm9sbGVyKCk7XG5cdFx0XHRcdGlmICh0aGlzLl9vcHRpb25zLnNpZ25hbCkge1xuXHRcdFx0XHRcdHRoaXMuX29wdGlvbnMuc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgKCkgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5hYm9ydENvbnRyb2xsZXIuYWJvcnQoKTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHRoaXMuX29wdGlvbnMuc2lnbmFsID0gdGhpcy5hYm9ydENvbnRyb2xsZXIuc2lnbmFsO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLnJlcXVlc3QgPSBuZXcgZ2xvYmFscy5SZXF1ZXN0KHRoaXMuX2lucHV0LCB0aGlzLl9vcHRpb25zKTtcblxuXHRcdFx0aWYgKHRoaXMuX29wdGlvbnMuc2VhcmNoUGFyYW1zKSB7XG5cdFx0XHRcdGNvbnN0IHNlYXJjaFBhcmFtcyA9ICc/JyArIG5ldyBVUkxTZWFyY2hQYXJhbXModGhpcy5fb3B0aW9ucy5zZWFyY2hQYXJhbXMpLnRvU3RyaW5nKCk7XG5cdFx0XHRcdGNvbnN0IHVybCA9IHRoaXMucmVxdWVzdC51cmwucmVwbGFjZSgvKD86XFw/Lio/KT8oPz0jfCQpLywgc2VhcmNoUGFyYW1zKTtcblxuXHRcdFx0XHQvLyBUbyBwcm92aWRlIGNvcnJlY3QgZm9ybSBib3VuZGFyeSwgQ29udGVudC1UeXBlIGhlYWRlciBzaG91bGQgYmUgZGVsZXRlZCBlYWNoIHRpbWUgd2hlbiBuZXcgUmVxdWVzdCBpbnN0YW50aWF0ZWQgZnJvbSBhbm90aGVyIG9uZVxuXHRcdFx0XHRpZiAoKChzdXBwb3J0c0Zvcm1EYXRhICYmIHRoaXMuX29wdGlvbnMuYm9keSBpbnN0YW5jZW9mIGdsb2JhbHMuRm9ybURhdGEpIHx8IHRoaXMuX29wdGlvbnMuYm9keSBpbnN0YW5jZW9mIFVSTFNlYXJjaFBhcmFtcykgJiYgISh0aGlzLl9vcHRpb25zLmhlYWRlcnMgJiYgdGhpcy5fb3B0aW9ucy5oZWFkZXJzWydjb250ZW50LXR5cGUnXSkpIHtcblx0XHRcdFx0XHR0aGlzLnJlcXVlc3QuaGVhZGVycy5kZWxldGUoJ2NvbnRlbnQtdHlwZScpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGhpcy5yZXF1ZXN0ID0gbmV3IGdsb2JhbHMuUmVxdWVzdChuZXcgZ2xvYmFscy5SZXF1ZXN0KHVybCwgdGhpcy5yZXF1ZXN0KSwgdGhpcy5fb3B0aW9ucyk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICh0aGlzLl9vcHRpb25zLmpzb24gIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHR0aGlzLl9vcHRpb25zLmJvZHkgPSBKU09OLnN0cmluZ2lmeSh0aGlzLl9vcHRpb25zLmpzb24pO1xuXHRcdFx0XHR0aGlzLnJlcXVlc3QuaGVhZGVycy5zZXQoJ2NvbnRlbnQtdHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG5cdFx0XHRcdHRoaXMucmVxdWVzdCA9IG5ldyBnbG9iYWxzLlJlcXVlc3QodGhpcy5yZXF1ZXN0LCB7Ym9keTogdGhpcy5fb3B0aW9ucy5ib2R5fSk7XG5cdFx0XHR9XG5cblx0XHRcdGNvbnN0IGZuID0gYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRpZiAodGhpcy5fb3B0aW9ucy50aW1lb3V0ID4gbWF4U2FmZVRpbWVvdXQpIHtcblx0XHRcdFx0XHR0aHJvdyBuZXcgUmFuZ2VFcnJvcihgVGhlIFxcYHRpbWVvdXRcXGAgb3B0aW9uIGNhbm5vdCBiZSBncmVhdGVyIHRoYW4gJHttYXhTYWZlVGltZW91dH1gKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGF3YWl0IGRlbGF5KDEpO1xuXHRcdFx0XHRsZXQgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLl9mZXRjaCgpO1xuXG5cdFx0XHRcdGZvciAoY29uc3QgaG9vayBvZiB0aGlzLl9vcHRpb25zLmhvb2tzLmFmdGVyUmVzcG9uc2UpIHtcblx0XHRcdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYXdhaXQtaW4tbG9vcFxuXHRcdFx0XHRcdGNvbnN0IG1vZGlmaWVkUmVzcG9uc2UgPSBhd2FpdCBob29rKFxuXHRcdFx0XHRcdFx0dGhpcy5yZXF1ZXN0LFxuXHRcdFx0XHRcdFx0dGhpcy5fb3B0aW9ucyxcblx0XHRcdFx0XHRcdHRoaXMuX2RlY29yYXRlUmVzcG9uc2UocmVzcG9uc2UuY2xvbmUoKSlcblx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0aWYgKG1vZGlmaWVkUmVzcG9uc2UgaW5zdGFuY2VvZiBnbG9iYWxzLlJlc3BvbnNlKSB7XG5cdFx0XHRcdFx0XHRyZXNwb25zZSA9IG1vZGlmaWVkUmVzcG9uc2U7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGhpcy5fZGVjb3JhdGVSZXNwb25zZShyZXNwb25zZSk7XG5cblx0XHRcdFx0aWYgKCFyZXNwb25zZS5vayAmJiB0aGlzLl9vcHRpb25zLnRocm93SHR0cEVycm9ycykge1xuXHRcdFx0XHRcdHRocm93IG5ldyBIVFRQRXJyb3IocmVzcG9uc2UpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gSWYgYG9uRG93bmxvYWRQcm9ncmVzc2AgaXMgcGFzc2VkLCBpdCB1c2VzIHRoZSBzdHJlYW0gQVBJIGludGVybmFsbHlcblx0XHRcdFx0LyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cblx0XHRcdFx0aWYgKHRoaXMuX29wdGlvbnMub25Eb3dubG9hZFByb2dyZXNzKSB7XG5cdFx0XHRcdFx0aWYgKHR5cGVvZiB0aGlzLl9vcHRpb25zLm9uRG93bmxvYWRQcm9ncmVzcyAhPT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0XHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIGBvbkRvd25sb2FkUHJvZ3Jlc3NgIG9wdGlvbiBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAoIXN1cHBvcnRzU3RyZWFtcykge1xuXHRcdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKCdTdHJlYW1zIGFyZSBub3Qgc3VwcG9ydGVkIGluIHlvdXIgZW52aXJvbm1lbnQuIGBSZWFkYWJsZVN0cmVhbWAgaXMgbWlzc2luZy4nKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4gdGhpcy5fc3RyZWFtKHJlc3BvbnNlLmNsb25lKCksIHRoaXMuX29wdGlvbnMub25Eb3dubG9hZFByb2dyZXNzKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiByZXNwb25zZTtcblx0XHRcdH07XG5cblx0XHRcdGNvbnN0IGlzUmV0cmlhYmxlTWV0aG9kID0gdGhpcy5fb3B0aW9ucy5yZXRyeS5tZXRob2RzLmluY2x1ZGVzKHRoaXMucmVxdWVzdC5tZXRob2QudG9Mb3dlckNhc2UoKSk7XG5cdFx0XHRjb25zdCByZXN1bHQgPSBpc1JldHJpYWJsZU1ldGhvZCA/IHRoaXMuX3JldHJ5KGZuKSA6IGZuKCk7XG5cblx0XHRcdGZvciAoY29uc3QgW3R5cGUsIG1pbWVUeXBlXSBvZiBPYmplY3QuZW50cmllcyhyZXNwb25zZVR5cGVzKSkge1xuXHRcdFx0XHRyZXN1bHRbdHlwZV0gPSBhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5yZXF1ZXN0LmhlYWRlcnMuc2V0KCdhY2NlcHQnLCB0aGlzLnJlcXVlc3QuaGVhZGVycy5nZXQoJ2FjY2VwdCcpIHx8IG1pbWVUeXBlKTtcblxuXHRcdFx0XHRcdGNvbnN0IHJlc3BvbnNlID0gKGF3YWl0IHJlc3VsdCkuY2xvbmUoKTtcblxuXHRcdFx0XHRcdGlmICh0eXBlID09PSAnanNvbicpIHtcblx0XHRcdFx0XHRcdGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDIwNCkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gJyc7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGlmIChvcHRpb25zLnBhcnNlSnNvbikge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gb3B0aW9ucy5wYXJzZUpzb24oYXdhaXQgcmVzcG9uc2UudGV4dCgpKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4gcmVzcG9uc2VbdHlwZV0oKTtcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cblx0XHRfY2FsY3VsYXRlUmV0cnlEZWxheShlcnJvcikge1xuXHRcdFx0dGhpcy5fcmV0cnlDb3VudCsrO1xuXG5cdFx0XHRpZiAodGhpcy5fcmV0cnlDb3VudCA8IHRoaXMuX29wdGlvbnMucmV0cnkubGltaXQgJiYgIShlcnJvciBpbnN0YW5jZW9mIFRpbWVvdXRFcnJvcikpIHtcblx0XHRcdFx0aWYgKGVycm9yIGluc3RhbmNlb2YgSFRUUEVycm9yKSB7XG5cdFx0XHRcdFx0aWYgKCF0aGlzLl9vcHRpb25zLnJldHJ5LnN0YXR1c0NvZGVzLmluY2x1ZGVzKGVycm9yLnJlc3BvbnNlLnN0YXR1cykpIHtcblx0XHRcdFx0XHRcdHJldHVybiAwO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGNvbnN0IHJldHJ5QWZ0ZXIgPSBlcnJvci5yZXNwb25zZS5oZWFkZXJzLmdldCgnUmV0cnktQWZ0ZXInKTtcblx0XHRcdFx0XHRpZiAocmV0cnlBZnRlciAmJiB0aGlzLl9vcHRpb25zLnJldHJ5LmFmdGVyU3RhdHVzQ29kZXMuaW5jbHVkZXMoZXJyb3IucmVzcG9uc2Uuc3RhdHVzKSkge1xuXHRcdFx0XHRcdFx0bGV0IGFmdGVyID0gTnVtYmVyKHJldHJ5QWZ0ZXIpO1xuXHRcdFx0XHRcdFx0aWYgKE51bWJlci5pc05hTihhZnRlcikpIHtcblx0XHRcdFx0XHRcdFx0YWZ0ZXIgPSBEYXRlLnBhcnNlKHJldHJ5QWZ0ZXIpIC0gRGF0ZS5ub3coKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdGFmdGVyICo9IDEwMDA7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGlmICh0eXBlb2YgdGhpcy5fb3B0aW9ucy5yZXRyeS5tYXhSZXRyeUFmdGVyICE9PSAndW5kZWZpbmVkJyAmJiBhZnRlciA+IHRoaXMuX29wdGlvbnMucmV0cnkubWF4UmV0cnlBZnRlcikge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gMDtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0cmV0dXJuIGFmdGVyO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGlmIChlcnJvci5yZXNwb25zZS5zdGF0dXMgPT09IDQxMykge1xuXHRcdFx0XHRcdFx0cmV0dXJuIDA7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Y29uc3QgQkFDS09GRl9GQUNUT1IgPSAwLjM7XG5cdFx0XHRcdHJldHVybiBCQUNLT0ZGX0ZBQ1RPUiAqICgyICoqICh0aGlzLl9yZXRyeUNvdW50IC0gMSkpICogMTAwMDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fVxuXG5cdFx0X2RlY29yYXRlUmVzcG9uc2UocmVzcG9uc2UpIHtcblx0XHRcdGlmICh0aGlzLl9vcHRpb25zLnBhcnNlSnNvbikge1xuXHRcdFx0XHRyZXNwb25zZS5qc29uID0gYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRcdHJldHVybiB0aGlzLl9vcHRpb25zLnBhcnNlSnNvbihhd2FpdCByZXNwb25zZS50ZXh0KCkpO1xuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gcmVzcG9uc2U7XG5cdFx0fVxuXG5cdFx0YXN5bmMgX3JldHJ5KGZuKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRyZXR1cm4gYXdhaXQgZm4oKTtcblx0XHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRcdGNvbnN0IG1zID0gTWF0aC5taW4odGhpcy5fY2FsY3VsYXRlUmV0cnlEZWxheShlcnJvciksIG1heFNhZmVUaW1lb3V0KTtcblx0XHRcdFx0aWYgKG1zICE9PSAwICYmIHRoaXMuX3JldHJ5Q291bnQgPiAwKSB7XG5cdFx0XHRcdFx0YXdhaXQgZGVsYXkobXMpO1xuXG5cdFx0XHRcdFx0Zm9yIChjb25zdCBob29rIG9mIHRoaXMuX29wdGlvbnMuaG9va3MuYmVmb3JlUmV0cnkpIHtcblx0XHRcdFx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hd2FpdC1pbi1sb29wXG5cdFx0XHRcdFx0XHRjb25zdCBob29rUmVzdWx0ID0gYXdhaXQgaG9vayh7XG5cdFx0XHRcdFx0XHRcdHJlcXVlc3Q6IHRoaXMucmVxdWVzdCxcblx0XHRcdFx0XHRcdFx0b3B0aW9uczogdGhpcy5fb3B0aW9ucyxcblx0XHRcdFx0XHRcdFx0ZXJyb3IsXG5cdFx0XHRcdFx0XHRcdHJldHJ5Q291bnQ6IHRoaXMuX3JldHJ5Q291bnRcblx0XHRcdFx0XHRcdH0pO1xuXG5cdFx0XHRcdFx0XHQvLyBJZiBgc3RvcGAgaXMgcmV0dXJuZWQgZnJvbSB0aGUgaG9vaywgdGhlIHJldHJ5IHByb2Nlc3MgaXMgc3RvcHBlZFxuXHRcdFx0XHRcdFx0aWYgKGhvb2tSZXN1bHQgPT09IHN0b3ApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHJldHVybiB0aGlzLl9yZXRyeShmbik7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAodGhpcy5fb3B0aW9ucy50aHJvd0h0dHBFcnJvcnMpIHtcblx0XHRcdFx0XHR0aHJvdyBlcnJvcjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGFzeW5jIF9mZXRjaCgpIHtcblx0XHRcdGZvciAoY29uc3QgaG9vayBvZiB0aGlzLl9vcHRpb25zLmhvb2tzLmJlZm9yZVJlcXVlc3QpIHtcblx0XHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWF3YWl0LWluLWxvb3Bcblx0XHRcdFx0Y29uc3QgcmVzdWx0ID0gYXdhaXQgaG9vayh0aGlzLnJlcXVlc3QsIHRoaXMuX29wdGlvbnMpO1xuXG5cdFx0XHRcdGlmIChyZXN1bHQgaW5zdGFuY2VvZiBSZXF1ZXN0KSB7XG5cdFx0XHRcdFx0dGhpcy5yZXF1ZXN0ID0gcmVzdWx0O1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKHJlc3VsdCBpbnN0YW5jZW9mIFJlc3BvbnNlKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRpZiAodGhpcy5fb3B0aW9ucy50aW1lb3V0ID09PSBmYWxzZSkge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5fb3B0aW9ucy5mZXRjaCh0aGlzLnJlcXVlc3QuY2xvbmUoKSk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB0aW1lb3V0KHRoaXMucmVxdWVzdC5jbG9uZSgpLCB0aGlzLmFib3J0Q29udHJvbGxlciwgdGhpcy5fb3B0aW9ucyk7XG5cdFx0fVxuXG5cdFx0LyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cblx0XHRfc3RyZWFtKHJlc3BvbnNlLCBvbkRvd25sb2FkUHJvZ3Jlc3MpIHtcblx0XHRcdGNvbnN0IHRvdGFsQnl0ZXMgPSBOdW1iZXIocmVzcG9uc2UuaGVhZGVycy5nZXQoJ2NvbnRlbnQtbGVuZ3RoJykpIHx8IDA7XG5cdFx0XHRsZXQgdHJhbnNmZXJyZWRCeXRlcyA9IDA7XG5cblx0XHRcdHJldHVybiBuZXcgZ2xvYmFscy5SZXNwb25zZShcblx0XHRcdFx0bmV3IGdsb2JhbHMuUmVhZGFibGVTdHJlYW0oe1xuXHRcdFx0XHRcdHN0YXJ0KGNvbnRyb2xsZXIpIHtcblx0XHRcdFx0XHRcdGNvbnN0IHJlYWRlciA9IHJlc3BvbnNlLmJvZHkuZ2V0UmVhZGVyKCk7XG5cblx0XHRcdFx0XHRcdGlmIChvbkRvd25sb2FkUHJvZ3Jlc3MpIHtcblx0XHRcdFx0XHRcdFx0b25Eb3dubG9hZFByb2dyZXNzKHtwZXJjZW50OiAwLCB0cmFuc2ZlcnJlZEJ5dGVzOiAwLCB0b3RhbEJ5dGVzfSwgbmV3IFVpbnQ4QXJyYXkoKSk7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGFzeW5jIGZ1bmN0aW9uIHJlYWQoKSB7XG5cdFx0XHRcdFx0XHRcdGNvbnN0IHtkb25lLCB2YWx1ZX0gPSBhd2FpdCByZWFkZXIucmVhZCgpO1xuXHRcdFx0XHRcdFx0XHRpZiAoZG9uZSkge1xuXHRcdFx0XHRcdFx0XHRcdGNvbnRyb2xsZXIuY2xvc2UoKTtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRpZiAob25Eb3dubG9hZFByb2dyZXNzKSB7XG5cdFx0XHRcdFx0XHRcdFx0dHJhbnNmZXJyZWRCeXRlcyArPSB2YWx1ZS5ieXRlTGVuZ3RoO1xuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IHBlcmNlbnQgPSB0b3RhbEJ5dGVzID09PSAwID8gMCA6IHRyYW5zZmVycmVkQnl0ZXMgLyB0b3RhbEJ5dGVzO1xuXHRcdFx0XHRcdFx0XHRcdG9uRG93bmxvYWRQcm9ncmVzcyh7cGVyY2VudCwgdHJhbnNmZXJyZWRCeXRlcywgdG90YWxCeXRlc30sIHZhbHVlKTtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdGNvbnRyb2xsZXIuZW5xdWV1ZSh2YWx1ZSk7XG5cdFx0XHRcdFx0XHRcdHJlYWQoKTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0cmVhZCgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSlcblx0XHRcdCk7XG5cdFx0fVxuXHR9XG5cblx0Y29uc3QgdmFsaWRhdGVBbmRNZXJnZSA9ICguLi5zb3VyY2VzKSA9PiB7XG5cdFx0Zm9yIChjb25zdCBzb3VyY2Ugb2Ygc291cmNlcykge1xuXHRcdFx0aWYgKCghaXNPYmplY3Qoc291cmNlKSB8fCBBcnJheS5pc0FycmF5KHNvdXJjZSkpICYmIHR5cGVvZiBzb3VyY2UgIT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBgb3B0aW9uc2AgYXJndW1lbnQgbXVzdCBiZSBhbiBvYmplY3QnKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZGVlcE1lcmdlKHt9LCAuLi5zb3VyY2VzKTtcblx0fTtcblxuXHRjb25zdCBjcmVhdGVJbnN0YW5jZSA9IGRlZmF1bHRzID0+IHtcblx0XHRjb25zdCBreSA9IChpbnB1dCwgb3B0aW9ucykgPT4gbmV3IEt5KGlucHV0LCB2YWxpZGF0ZUFuZE1lcmdlKGRlZmF1bHRzLCBvcHRpb25zKSk7XG5cblx0XHRmb3IgKGNvbnN0IG1ldGhvZCBvZiByZXF1ZXN0TWV0aG9kcykge1xuXHRcdFx0a3lbbWV0aG9kXSA9IChpbnB1dCwgb3B0aW9ucykgPT4gbmV3IEt5KGlucHV0LCB2YWxpZGF0ZUFuZE1lcmdlKGRlZmF1bHRzLCBvcHRpb25zLCB7bWV0aG9kfSkpO1xuXHRcdH1cblxuXHRcdGt5LkhUVFBFcnJvciA9IEhUVFBFcnJvcjtcblx0XHRreS5UaW1lb3V0RXJyb3IgPSBUaW1lb3V0RXJyb3I7XG5cdFx0a3kuY3JlYXRlID0gbmV3RGVmYXVsdHMgPT4gY3JlYXRlSW5zdGFuY2UodmFsaWRhdGVBbmRNZXJnZShuZXdEZWZhdWx0cykpO1xuXHRcdGt5LmV4dGVuZCA9IG5ld0RlZmF1bHRzID0+IGNyZWF0ZUluc3RhbmNlKHZhbGlkYXRlQW5kTWVyZ2UoZGVmYXVsdHMsIG5ld0RlZmF1bHRzKSk7XG5cdFx0a3kuc3RvcCA9IHN0b3A7XG5cblx0XHRyZXR1cm4ga3k7XG5cdH07XG5cblx0dmFyIGluZGV4ID0gY3JlYXRlSW5zdGFuY2UoKTtcblxuXHRyZXR1cm4gaW5kZXg7XG5cbn0pKSk7XG4iLCJmdW5jdGlvbiBub3JtYWxpemUgKHN0cikge1xuICByZXR1cm4gc3RyXG4gICAgICAgICAgLnJlcGxhY2UoL1tcXC9dKy9nLCAnLycpXG4gICAgICAgICAgLnJlcGxhY2UoL1xcL1xcPy9nLCAnPycpXG4gICAgICAgICAgLnJlcGxhY2UoL1xcL1xcIy9nLCAnIycpXG4gICAgICAgICAgLnJlcGxhY2UoL1xcOlxcLy9nLCAnOi8vJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgam9pbmVkID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDApLmpvaW4oJy8nKTtcbiAgcmV0dXJuIG5vcm1hbGl6ZShqb2luZWQpO1xufTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJjcnlwdG9cIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiaHR0cFwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJodHRwc1wiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJzdHJlYW1cIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwidXJsXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInV0aWxcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiemxpYlwiKTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGZldGNoO1xuXG5jb25zdCBodHRwID0gcmVxdWlyZSgnaHR0cCcpO1xuY29uc3QgaHR0cHMgPSByZXF1aXJlKCdodHRwcycpO1xuY29uc3QgemxpYiA9IHJlcXVpcmUoJ3psaWInKTtcbmNvbnN0IFN0cmVhbSA9IHJlcXVpcmUoJ3N0cmVhbScpO1xuY29uc3QgZGF0YVVyaVRvQnVmZmVyID0gcmVxdWlyZSgnZGF0YS11cmktdG8tYnVmZmVyJyk7XG5jb25zdCB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuY29uc3QgQmxvYiA9IHJlcXVpcmUoJ2ZldGNoLWJsb2InKTtcbmNvbnN0IGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xuY29uc3QgdXJsID0gcmVxdWlyZSgndXJsJyk7XG5cbmNsYXNzIEZldGNoQmFzZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuXHRjb25zdHJ1Y3RvcihtZXNzYWdlLCB0eXBlKSB7XG5cdFx0c3VwZXIobWVzc2FnZSk7XG5cdFx0Ly8gSGlkZSBjdXN0b20gZXJyb3IgaW1wbGVtZW50YXRpb24gZGV0YWlscyBmcm9tIGVuZC11c2Vyc1xuXHRcdEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIHRoaXMuY29uc3RydWN0b3IpO1xuXG5cdFx0dGhpcy50eXBlID0gdHlwZTtcblx0fVxuXG5cdGdldCBuYW1lKCkge1xuXHRcdHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLm5hbWU7XG5cdH1cblxuXHRnZXQgW1N5bWJvbC50b1N0cmluZ1RhZ10oKSB7XG5cdFx0cmV0dXJuIHRoaXMuY29uc3RydWN0b3IubmFtZTtcblx0fVxufVxuXG4vKipcbiAqIEB0eXBlZGVmIHt7IGFkZHJlc3M/OiBzdHJpbmcsIGNvZGU6IHN0cmluZywgZGVzdD86IHN0cmluZywgZXJybm86IG51bWJlciwgaW5mbz86IG9iamVjdCwgbWVzc2FnZTogc3RyaW5nLCBwYXRoPzogc3RyaW5nLCBwb3J0PzogbnVtYmVyLCBzeXNjYWxsOiBzdHJpbmd9fSBTeXN0ZW1FcnJvclxuKi9cblxuLyoqXG4gKiBGZXRjaEVycm9yIGludGVyZmFjZSBmb3Igb3BlcmF0aW9uYWwgZXJyb3JzXG4gKi9cbmNsYXNzIEZldGNoRXJyb3IgZXh0ZW5kcyBGZXRjaEJhc2VFcnJvciB7XG5cdC8qKlxuXHQgKiBAcGFyYW0gIHtzdHJpbmd9IG1lc3NhZ2UgLSAgICAgIEVycm9yIG1lc3NhZ2UgZm9yIGh1bWFuXG5cdCAqIEBwYXJhbSAge3N0cmluZ30gW3R5cGVdIC0gICAgICAgIEVycm9yIHR5cGUgZm9yIG1hY2hpbmVcblx0ICogQHBhcmFtICB7U3lzdGVtRXJyb3J9IFtzeXN0ZW1FcnJvcl0gLSBGb3IgTm9kZS5qcyBzeXN0ZW0gZXJyb3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKG1lc3NhZ2UsIHR5cGUsIHN5c3RlbUVycm9yKSB7XG5cdFx0c3VwZXIobWVzc2FnZSwgdHlwZSk7XG5cdFx0Ly8gV2hlbiBlcnIudHlwZSBpcyBgc3lzdGVtYCwgZXJyLmVycm9yZWRTeXNDYWxsIGNvbnRhaW5zIHN5c3RlbSBlcnJvciBhbmQgZXJyLmNvZGUgY29udGFpbnMgc3lzdGVtIGVycm9yIGNvZGVcblx0XHRpZiAoc3lzdGVtRXJyb3IpIHtcblx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1tdWx0aS1hc3NpZ25cblx0XHRcdHRoaXMuY29kZSA9IHRoaXMuZXJybm8gPSBzeXN0ZW1FcnJvci5jb2RlO1xuXHRcdFx0dGhpcy5lcnJvcmVkU3lzQ2FsbCA9IHN5c3RlbUVycm9yLnN5c2NhbGw7XG5cdFx0fVxuXHR9XG59XG5cbi8qKlxuICogSXMuanNcbiAqXG4gKiBPYmplY3QgdHlwZSBjaGVja3MuXG4gKi9cblxuY29uc3QgTkFNRSA9IFN5bWJvbC50b1N0cmluZ1RhZztcblxuLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBhIFVSTFNlYXJjaFBhcmFtcyBvYmplY3RcbiAqIHJlZjogaHR0cHM6Ly9naXRodWIuY29tL25vZGUtZmV0Y2gvbm9kZS1mZXRjaC9pc3N1ZXMvMjk2I2lzc3VlY29tbWVudC0zMDc1OTgxNDNcbiAqXG4gKiBAcGFyYW0gIHsqfSBvYmpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmNvbnN0IGlzVVJMU2VhcmNoUGFyYW1ldGVycyA9IG9iamVjdCA9PiB7XG5cdHJldHVybiAoXG5cdFx0dHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmFwcGVuZCA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBvYmplY3QuZGVsZXRlID09PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIG9iamVjdC5nZXQgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmdldEFsbCA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBvYmplY3QuaGFzID09PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIG9iamVjdC5zZXQgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LnNvcnQgPT09ICdmdW5jdGlvbicgJiZcblx0XHRvYmplY3RbTkFNRV0gPT09ICdVUkxTZWFyY2hQYXJhbXMnXG5cdCk7XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIGBvYmplY3RgIGlzIGEgVzNDIGBCbG9iYCBvYmplY3QgKHdoaWNoIGBGaWxlYCBpbmhlcml0cyBmcm9tKVxuICpcbiAqIEBwYXJhbSAgeyp9IG9ialxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuY29uc3QgaXNCbG9iID0gb2JqZWN0ID0+IHtcblx0cmV0dXJuIChcblx0XHR0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJlxuXHRcdHR5cGVvZiBvYmplY3QuYXJyYXlCdWZmZXIgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LnR5cGUgPT09ICdzdHJpbmcnICYmXG5cdFx0dHlwZW9mIG9iamVjdC5zdHJlYW0gPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmNvbnN0cnVjdG9yID09PSAnZnVuY3Rpb24nICYmXG5cdFx0L14oQmxvYnxGaWxlKSQvLnRlc3Qob2JqZWN0W05BTUVdKVxuXHQpO1xufTtcblxuLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBhIHNwZWMtY29tcGxpYW50IGBGb3JtRGF0YWAgb2JqZWN0XG4gKlxuICogQHBhcmFtIHsqfSBvYmplY3RcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGlzRm9ybURhdGEob2JqZWN0KSB7XG5cdHJldHVybiAoXG5cdFx0dHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmFwcGVuZCA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBvYmplY3Quc2V0ID09PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIG9iamVjdC5nZXQgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmdldEFsbCA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBvYmplY3QuZGVsZXRlID09PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIG9iamVjdC5rZXlzID09PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIG9iamVjdC52YWx1ZXMgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmVudHJpZXMgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmNvbnN0cnVjdG9yID09PSAnZnVuY3Rpb24nICYmXG5cdFx0b2JqZWN0W05BTUVdID09PSAnRm9ybURhdGEnXG5cdCk7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYG9iamAgaXMgYW4gaW5zdGFuY2Ugb2YgQWJvcnRTaWduYWwuXG4gKlxuICogQHBhcmFtICB7Kn0gb2JqXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5jb25zdCBpc0Fib3J0U2lnbmFsID0gb2JqZWN0ID0+IHtcblx0cmV0dXJuIChcblx0XHR0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJlxuXHRcdG9iamVjdFtOQU1FXSA9PT0gJ0Fib3J0U2lnbmFsJ1xuXHQpO1xufTtcblxuY29uc3QgY2FycmlhZ2UgPSAnXFxyXFxuJztcbmNvbnN0IGRhc2hlcyA9ICctJy5yZXBlYXQoMik7XG5jb25zdCBjYXJyaWFnZUxlbmd0aCA9IEJ1ZmZlci5ieXRlTGVuZ3RoKGNhcnJpYWdlKTtcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gYm91bmRhcnlcbiAqL1xuY29uc3QgZ2V0Rm9vdGVyID0gYm91bmRhcnkgPT4gYCR7ZGFzaGVzfSR7Ym91bmRhcnl9JHtkYXNoZXN9JHtjYXJyaWFnZS5yZXBlYXQoMil9YDtcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gYm91bmRhcnlcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gKiBAcGFyYW0geyp9IGZpZWxkXG4gKlxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5mdW5jdGlvbiBnZXRIZWFkZXIoYm91bmRhcnksIG5hbWUsIGZpZWxkKSB7XG5cdGxldCBoZWFkZXIgPSAnJztcblxuXHRoZWFkZXIgKz0gYCR7ZGFzaGVzfSR7Ym91bmRhcnl9JHtjYXJyaWFnZX1gO1xuXHRoZWFkZXIgKz0gYENvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT1cIiR7bmFtZX1cImA7XG5cblx0aWYgKGlzQmxvYihmaWVsZCkpIHtcblx0XHRoZWFkZXIgKz0gYDsgZmlsZW5hbWU9XCIke2ZpZWxkLm5hbWV9XCIke2NhcnJpYWdlfWA7XG5cdFx0aGVhZGVyICs9IGBDb250ZW50LVR5cGU6ICR7ZmllbGQudHlwZSB8fCAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJ31gO1xuXHR9XG5cblx0cmV0dXJuIGAke2hlYWRlcn0ke2NhcnJpYWdlLnJlcGVhdCgyKX1gO1xufVxuXG4vKipcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xuY29uc3QgZ2V0Qm91bmRhcnkgPSAoKSA9PiBjcnlwdG8ucmFuZG9tQnl0ZXMoOCkudG9TdHJpbmcoJ2hleCcpO1xuXG4vKipcbiAqIEBwYXJhbSB7Rm9ybURhdGF9IGZvcm1cbiAqIEBwYXJhbSB7c3RyaW5nfSBib3VuZGFyeVxuICovXG5hc3luYyBmdW5jdGlvbiAqIGZvcm1EYXRhSXRlcmF0b3IoZm9ybSwgYm91bmRhcnkpIHtcblx0Zm9yIChjb25zdCBbbmFtZSwgdmFsdWVdIG9mIGZvcm0pIHtcblx0XHR5aWVsZCBnZXRIZWFkZXIoYm91bmRhcnksIG5hbWUsIHZhbHVlKTtcblxuXHRcdGlmIChpc0Jsb2IodmFsdWUpKSB7XG5cdFx0XHR5aWVsZCAqIHZhbHVlLnN0cmVhbSgpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR5aWVsZCB2YWx1ZTtcblx0XHR9XG5cblx0XHR5aWVsZCBjYXJyaWFnZTtcblx0fVxuXG5cdHlpZWxkIGdldEZvb3Rlcihib3VuZGFyeSk7XG59XG5cbi8qKlxuICogQHBhcmFtIHtGb3JtRGF0YX0gZm9ybVxuICogQHBhcmFtIHtzdHJpbmd9IGJvdW5kYXJ5XG4gKi9cbmZ1bmN0aW9uIGdldEZvcm1EYXRhTGVuZ3RoKGZvcm0sIGJvdW5kYXJ5KSB7XG5cdGxldCBsZW5ndGggPSAwO1xuXG5cdGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiBmb3JtKSB7XG5cdFx0bGVuZ3RoICs9IEJ1ZmZlci5ieXRlTGVuZ3RoKGdldEhlYWRlcihib3VuZGFyeSwgbmFtZSwgdmFsdWUpKTtcblxuXHRcdGlmIChpc0Jsb2IodmFsdWUpKSB7XG5cdFx0XHRsZW5ndGggKz0gdmFsdWUuc2l6ZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bGVuZ3RoICs9IEJ1ZmZlci5ieXRlTGVuZ3RoKFN0cmluZyh2YWx1ZSkpO1xuXHRcdH1cblxuXHRcdGxlbmd0aCArPSBjYXJyaWFnZUxlbmd0aDtcblx0fVxuXG5cdGxlbmd0aCArPSBCdWZmZXIuYnl0ZUxlbmd0aChnZXRGb290ZXIoYm91bmRhcnkpKTtcblxuXHRyZXR1cm4gbGVuZ3RoO1xufVxuXG5jb25zdCBJTlRFUk5BTFMgPSBTeW1ib2woJ0JvZHkgaW50ZXJuYWxzJyk7XG5cbi8qKlxuICogQm9keSBtaXhpblxuICpcbiAqIFJlZjogaHR0cHM6Ly9mZXRjaC5zcGVjLndoYXR3Zy5vcmcvI2JvZHlcbiAqXG4gKiBAcGFyYW0gICBTdHJlYW0gIGJvZHkgIFJlYWRhYmxlIHN0cmVhbVxuICogQHBhcmFtICAgT2JqZWN0ICBvcHRzICBSZXNwb25zZSBvcHRpb25zXG4gKiBAcmV0dXJuICBWb2lkXG4gKi9cbmNsYXNzIEJvZHkge1xuXHRjb25zdHJ1Y3Rvcihib2R5LCB7XG5cdFx0c2l6ZSA9IDBcblx0fSA9IHt9KSB7XG5cdFx0bGV0IGJvdW5kYXJ5ID0gbnVsbDtcblxuXHRcdGlmIChib2R5ID09PSBudWxsKSB7XG5cdFx0XHQvLyBCb2R5IGlzIHVuZGVmaW5lZCBvciBudWxsXG5cdFx0XHRib2R5ID0gbnVsbDtcblx0XHR9IGVsc2UgaWYgKGlzVVJMU2VhcmNoUGFyYW1ldGVycyhib2R5KSkge1xuXHRcdC8vIEJvZHkgaXMgYSBVUkxTZWFyY2hQYXJhbXNcblx0XHRcdGJvZHkgPSBCdWZmZXIuZnJvbShib2R5LnRvU3RyaW5nKCkpO1xuXHRcdH0gZWxzZSBpZiAoaXNCbG9iKGJvZHkpKSA7IGVsc2UgaWYgKEJ1ZmZlci5pc0J1ZmZlcihib2R5KSkgOyBlbHNlIGlmICh1dGlsLnR5cGVzLmlzQW55QXJyYXlCdWZmZXIoYm9keSkpIHtcblx0XHRcdC8vIEJvZHkgaXMgQXJyYXlCdWZmZXJcblx0XHRcdGJvZHkgPSBCdWZmZXIuZnJvbShib2R5KTtcblx0XHR9IGVsc2UgaWYgKEFycmF5QnVmZmVyLmlzVmlldyhib2R5KSkge1xuXHRcdFx0Ly8gQm9keSBpcyBBcnJheUJ1ZmZlclZpZXdcblx0XHRcdGJvZHkgPSBCdWZmZXIuZnJvbShib2R5LmJ1ZmZlciwgYm9keS5ieXRlT2Zmc2V0LCBib2R5LmJ5dGVMZW5ndGgpO1xuXHRcdH0gZWxzZSBpZiAoYm9keSBpbnN0YW5jZW9mIFN0cmVhbSkgOyBlbHNlIGlmIChpc0Zvcm1EYXRhKGJvZHkpKSB7XG5cdFx0XHQvLyBCb2R5IGlzIGFuIGluc3RhbmNlIG9mIGZvcm1kYXRhLW5vZGVcblx0XHRcdGJvdW5kYXJ5ID0gYE5vZGVGZXRjaEZvcm1EYXRhQm91bmRhcnkke2dldEJvdW5kYXJ5KCl9YDtcblx0XHRcdGJvZHkgPSBTdHJlYW0uUmVhZGFibGUuZnJvbShmb3JtRGF0YUl0ZXJhdG9yKGJvZHksIGJvdW5kYXJ5KSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIE5vbmUgb2YgdGhlIGFib3ZlXG5cdFx0XHQvLyBjb2VyY2UgdG8gc3RyaW5nIHRoZW4gYnVmZmVyXG5cdFx0XHRib2R5ID0gQnVmZmVyLmZyb20oU3RyaW5nKGJvZHkpKTtcblx0XHR9XG5cblx0XHR0aGlzW0lOVEVSTkFMU10gPSB7XG5cdFx0XHRib2R5LFxuXHRcdFx0Ym91bmRhcnksXG5cdFx0XHRkaXN0dXJiZWQ6IGZhbHNlLFxuXHRcdFx0ZXJyb3I6IG51bGxcblx0XHR9O1xuXHRcdHRoaXMuc2l6ZSA9IHNpemU7XG5cblx0XHRpZiAoYm9keSBpbnN0YW5jZW9mIFN0cmVhbSkge1xuXHRcdFx0Ym9keS5vbignZXJyb3InLCBlcnIgPT4ge1xuXHRcdFx0XHRjb25zdCBlcnJvciA9IGVyciBpbnN0YW5jZW9mIEZldGNoQmFzZUVycm9yID9cblx0XHRcdFx0XHRlcnIgOlxuXHRcdFx0XHRcdG5ldyBGZXRjaEVycm9yKGBJbnZhbGlkIHJlc3BvbnNlIGJvZHkgd2hpbGUgdHJ5aW5nIHRvIGZldGNoICR7dGhpcy51cmx9OiAke2Vyci5tZXNzYWdlfWAsICdzeXN0ZW0nLCBlcnIpO1xuXHRcdFx0XHR0aGlzW0lOVEVSTkFMU10uZXJyb3IgPSBlcnJvcjtcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdGdldCBib2R5KCkge1xuXHRcdHJldHVybiB0aGlzW0lOVEVSTkFMU10uYm9keTtcblx0fVxuXG5cdGdldCBib2R5VXNlZCgpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFNdLmRpc3R1cmJlZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZWNvZGUgcmVzcG9uc2UgYXMgQXJyYXlCdWZmZXJcblx0ICpcblx0ICogQHJldHVybiAgUHJvbWlzZVxuXHQgKi9cblx0YXN5bmMgYXJyYXlCdWZmZXIoKSB7XG5cdFx0Y29uc3Qge2J1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aH0gPSBhd2FpdCBjb25zdW1lQm9keSh0aGlzKTtcblx0XHRyZXR1cm4gYnVmZmVyLnNsaWNlKGJ5dGVPZmZzZXQsIGJ5dGVPZmZzZXQgKyBieXRlTGVuZ3RoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm4gcmF3IHJlc3BvbnNlIGFzIEJsb2Jcblx0ICpcblx0ICogQHJldHVybiBQcm9taXNlXG5cdCAqL1xuXHRhc3luYyBibG9iKCkge1xuXHRcdGNvbnN0IGN0ID0gKHRoaXMuaGVhZGVycyAmJiB0aGlzLmhlYWRlcnMuZ2V0KCdjb250ZW50LXR5cGUnKSkgfHwgKHRoaXNbSU5URVJOQUxTXS5ib2R5ICYmIHRoaXNbSU5URVJOQUxTXS5ib2R5LnR5cGUpIHx8ICcnO1xuXHRcdGNvbnN0IGJ1ZiA9IGF3YWl0IHRoaXMuYnVmZmVyKCk7XG5cblx0XHRyZXR1cm4gbmV3IEJsb2IoW2J1Zl0sIHtcblx0XHRcdHR5cGU6IGN0XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogRGVjb2RlIHJlc3BvbnNlIGFzIGpzb25cblx0ICpcblx0ICogQHJldHVybiAgUHJvbWlzZVxuXHQgKi9cblx0YXN5bmMganNvbigpIHtcblx0XHRjb25zdCBidWZmZXIgPSBhd2FpdCBjb25zdW1lQm9keSh0aGlzKTtcblx0XHRyZXR1cm4gSlNPTi5wYXJzZShidWZmZXIudG9TdHJpbmcoKSk7XG5cdH1cblxuXHQvKipcblx0ICogRGVjb2RlIHJlc3BvbnNlIGFzIHRleHRcblx0ICpcblx0ICogQHJldHVybiAgUHJvbWlzZVxuXHQgKi9cblx0YXN5bmMgdGV4dCgpIHtcblx0XHRjb25zdCBidWZmZXIgPSBhd2FpdCBjb25zdW1lQm9keSh0aGlzKTtcblx0XHRyZXR1cm4gYnVmZmVyLnRvU3RyaW5nKCk7XG5cdH1cblxuXHQvKipcblx0ICogRGVjb2RlIHJlc3BvbnNlIGFzIGJ1ZmZlciAobm9uLXNwZWMgYXBpKVxuXHQgKlxuXHQgKiBAcmV0dXJuICBQcm9taXNlXG5cdCAqL1xuXHRidWZmZXIoKSB7XG5cdFx0cmV0dXJuIGNvbnN1bWVCb2R5KHRoaXMpO1xuXHR9XG59XG5cbi8vIEluIGJyb3dzZXJzLCBhbGwgcHJvcGVydGllcyBhcmUgZW51bWVyYWJsZS5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKEJvZHkucHJvdG90eXBlLCB7XG5cdGJvZHk6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0Ym9keVVzZWQ6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0YXJyYXlCdWZmZXI6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0YmxvYjoge2VudW1lcmFibGU6IHRydWV9LFxuXHRqc29uOiB7ZW51bWVyYWJsZTogdHJ1ZX0sXG5cdHRleHQ6IHtlbnVtZXJhYmxlOiB0cnVlfVxufSk7XG5cbi8qKlxuICogQ29uc3VtZSBhbmQgY29udmVydCBhbiBlbnRpcmUgQm9keSB0byBhIEJ1ZmZlci5cbiAqXG4gKiBSZWY6IGh0dHBzOi8vZmV0Y2guc3BlYy53aGF0d2cub3JnLyNjb25jZXB0LWJvZHktY29uc3VtZS1ib2R5XG4gKlxuICogQHJldHVybiBQcm9taXNlXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGNvbnN1bWVCb2R5KGRhdGEpIHtcblx0aWYgKGRhdGFbSU5URVJOQUxTXS5kaXN0dXJiZWQpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKGBib2R5IHVzZWQgYWxyZWFkeSBmb3I6ICR7ZGF0YS51cmx9YCk7XG5cdH1cblxuXHRkYXRhW0lOVEVSTkFMU10uZGlzdHVyYmVkID0gdHJ1ZTtcblxuXHRpZiAoZGF0YVtJTlRFUk5BTFNdLmVycm9yKSB7XG5cdFx0dGhyb3cgZGF0YVtJTlRFUk5BTFNdLmVycm9yO1xuXHR9XG5cblx0bGV0IHtib2R5fSA9IGRhdGE7XG5cblx0Ly8gQm9keSBpcyBudWxsXG5cdGlmIChib2R5ID09PSBudWxsKSB7XG5cdFx0cmV0dXJuIEJ1ZmZlci5hbGxvYygwKTtcblx0fVxuXG5cdC8vIEJvZHkgaXMgYmxvYlxuXHRpZiAoaXNCbG9iKGJvZHkpKSB7XG5cdFx0Ym9keSA9IGJvZHkuc3RyZWFtKCk7XG5cdH1cblxuXHQvLyBCb2R5IGlzIGJ1ZmZlclxuXHRpZiAoQnVmZmVyLmlzQnVmZmVyKGJvZHkpKSB7XG5cdFx0cmV0dXJuIGJvZHk7XG5cdH1cblxuXHQvKiBjOCBpZ25vcmUgbmV4dCAzICovXG5cdGlmICghKGJvZHkgaW5zdGFuY2VvZiBTdHJlYW0pKSB7XG5cdFx0cmV0dXJuIEJ1ZmZlci5hbGxvYygwKTtcblx0fVxuXG5cdC8vIEJvZHkgaXMgc3RyZWFtXG5cdC8vIGdldCByZWFkeSB0byBhY3R1YWxseSBjb25zdW1lIHRoZSBib2R5XG5cdGNvbnN0IGFjY3VtID0gW107XG5cdGxldCBhY2N1bUJ5dGVzID0gMDtcblxuXHR0cnkge1xuXHRcdGZvciBhd2FpdCAoY29uc3QgY2h1bmsgb2YgYm9keSkge1xuXHRcdFx0aWYgKGRhdGEuc2l6ZSA+IDAgJiYgYWNjdW1CeXRlcyArIGNodW5rLmxlbmd0aCA+IGRhdGEuc2l6ZSkge1xuXHRcdFx0XHRjb25zdCBlcnIgPSBuZXcgRmV0Y2hFcnJvcihgY29udGVudCBzaXplIGF0ICR7ZGF0YS51cmx9IG92ZXIgbGltaXQ6ICR7ZGF0YS5zaXplfWAsICdtYXgtc2l6ZScpO1xuXHRcdFx0XHRib2R5LmRlc3Ryb3koZXJyKTtcblx0XHRcdFx0dGhyb3cgZXJyO1xuXHRcdFx0fVxuXG5cdFx0XHRhY2N1bUJ5dGVzICs9IGNodW5rLmxlbmd0aDtcblx0XHRcdGFjY3VtLnB1c2goY2h1bmspO1xuXHRcdH1cblx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRpZiAoZXJyb3IgaW5zdGFuY2VvZiBGZXRjaEJhc2VFcnJvcikge1xuXHRcdFx0dGhyb3cgZXJyb3I7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIE90aGVyIGVycm9ycywgc3VjaCBhcyBpbmNvcnJlY3QgY29udGVudC1lbmNvZGluZ1xuXHRcdFx0dGhyb3cgbmV3IEZldGNoRXJyb3IoYEludmFsaWQgcmVzcG9uc2UgYm9keSB3aGlsZSB0cnlpbmcgdG8gZmV0Y2ggJHtkYXRhLnVybH06ICR7ZXJyb3IubWVzc2FnZX1gLCAnc3lzdGVtJywgZXJyb3IpO1xuXHRcdH1cblx0fVxuXG5cdGlmIChib2R5LnJlYWRhYmxlRW5kZWQgPT09IHRydWUgfHwgYm9keS5fcmVhZGFibGVTdGF0ZS5lbmRlZCA9PT0gdHJ1ZSkge1xuXHRcdHRyeSB7XG5cdFx0XHRpZiAoYWNjdW0uZXZlcnkoYyA9PiB0eXBlb2YgYyA9PT0gJ3N0cmluZycpKSB7XG5cdFx0XHRcdHJldHVybiBCdWZmZXIuZnJvbShhY2N1bS5qb2luKCcnKSk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBCdWZmZXIuY29uY2F0KGFjY3VtLCBhY2N1bUJ5dGVzKTtcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0dGhyb3cgbmV3IEZldGNoRXJyb3IoYENvdWxkIG5vdCBjcmVhdGUgQnVmZmVyIGZyb20gcmVzcG9uc2UgYm9keSBmb3IgJHtkYXRhLnVybH06ICR7ZXJyb3IubWVzc2FnZX1gLCAnc3lzdGVtJywgZXJyb3IpO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHR0aHJvdyBuZXcgRmV0Y2hFcnJvcihgUHJlbWF0dXJlIGNsb3NlIG9mIHNlcnZlciByZXNwb25zZSB3aGlsZSB0cnlpbmcgdG8gZmV0Y2ggJHtkYXRhLnVybH1gKTtcblx0fVxufVxuXG4vKipcbiAqIENsb25lIGJvZHkgZ2l2ZW4gUmVzL1JlcSBpbnN0YW5jZVxuICpcbiAqIEBwYXJhbSAgIE1peGVkICAgaW5zdGFuY2UgICAgICAgUmVzcG9uc2Ugb3IgUmVxdWVzdCBpbnN0YW5jZVxuICogQHBhcmFtICAgU3RyaW5nICBoaWdoV2F0ZXJNYXJrICBoaWdoV2F0ZXJNYXJrIGZvciBib3RoIFBhc3NUaHJvdWdoIGJvZHkgc3RyZWFtc1xuICogQHJldHVybiAgTWl4ZWRcbiAqL1xuY29uc3QgY2xvbmUgPSAoaW5zdGFuY2UsIGhpZ2hXYXRlck1hcmspID0+IHtcblx0bGV0IHAxO1xuXHRsZXQgcDI7XG5cdGxldCB7Ym9keX0gPSBpbnN0YW5jZTtcblxuXHQvLyBEb24ndCBhbGxvdyBjbG9uaW5nIGEgdXNlZCBib2R5XG5cdGlmIChpbnN0YW5jZS5ib2R5VXNlZCkge1xuXHRcdHRocm93IG5ldyBFcnJvcignY2Fubm90IGNsb25lIGJvZHkgYWZ0ZXIgaXQgaXMgdXNlZCcpO1xuXHR9XG5cblx0Ly8gQ2hlY2sgdGhhdCBib2R5IGlzIGEgc3RyZWFtIGFuZCBub3QgZm9ybS1kYXRhIG9iamVjdFxuXHQvLyBub3RlOiB3ZSBjYW4ndCBjbG9uZSB0aGUgZm9ybS1kYXRhIG9iamVjdCB3aXRob3V0IGhhdmluZyBpdCBhcyBhIGRlcGVuZGVuY3lcblx0aWYgKChib2R5IGluc3RhbmNlb2YgU3RyZWFtKSAmJiAodHlwZW9mIGJvZHkuZ2V0Qm91bmRhcnkgIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0Ly8gVGVlIGluc3RhbmNlIGJvZHlcblx0XHRwMSA9IG5ldyBTdHJlYW0uUGFzc1Rocm91Z2goe2hpZ2hXYXRlck1hcmt9KTtcblx0XHRwMiA9IG5ldyBTdHJlYW0uUGFzc1Rocm91Z2goe2hpZ2hXYXRlck1hcmt9KTtcblx0XHRib2R5LnBpcGUocDEpO1xuXHRcdGJvZHkucGlwZShwMik7XG5cdFx0Ly8gU2V0IGluc3RhbmNlIGJvZHkgdG8gdGVlZCBib2R5IGFuZCByZXR1cm4gdGhlIG90aGVyIHRlZWQgYm9keVxuXHRcdGluc3RhbmNlW0lOVEVSTkFMU10uYm9keSA9IHAxO1xuXHRcdGJvZHkgPSBwMjtcblx0fVxuXG5cdHJldHVybiBib2R5O1xufTtcblxuLyoqXG4gKiBQZXJmb3JtcyB0aGUgb3BlcmF0aW9uIFwiZXh0cmFjdCBhIGBDb250ZW50LVR5cGVgIHZhbHVlIGZyb20gfG9iamVjdHxcIiBhc1xuICogc3BlY2lmaWVkIGluIHRoZSBzcGVjaWZpY2F0aW9uOlxuICogaHR0cHM6Ly9mZXRjaC5zcGVjLndoYXR3Zy5vcmcvI2NvbmNlcHQtYm9keWluaXQtZXh0cmFjdFxuICpcbiAqIFRoaXMgZnVuY3Rpb24gYXNzdW1lcyB0aGF0IGluc3RhbmNlLmJvZHkgaXMgcHJlc2VudC5cbiAqXG4gKiBAcGFyYW0ge2FueX0gYm9keSBBbnkgb3B0aW9ucy5ib2R5IGlucHV0XG4gKiBAcmV0dXJucyB7c3RyaW5nIHwgbnVsbH1cbiAqL1xuY29uc3QgZXh0cmFjdENvbnRlbnRUeXBlID0gKGJvZHksIHJlcXVlc3QpID0+IHtcblx0Ly8gQm9keSBpcyBudWxsIG9yIHVuZGVmaW5lZFxuXHRpZiAoYm9keSA9PT0gbnVsbCkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0Ly8gQm9keSBpcyBzdHJpbmdcblx0aWYgKHR5cGVvZiBib2R5ID09PSAnc3RyaW5nJykge1xuXHRcdHJldHVybiAndGV4dC9wbGFpbjtjaGFyc2V0PVVURi04Jztcblx0fVxuXG5cdC8vIEJvZHkgaXMgYSBVUkxTZWFyY2hQYXJhbXNcblx0aWYgKGlzVVJMU2VhcmNoUGFyYW1ldGVycyhib2R5KSkge1xuXHRcdHJldHVybiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkO2NoYXJzZXQ9VVRGLTgnO1xuXHR9XG5cblx0Ly8gQm9keSBpcyBibG9iXG5cdGlmIChpc0Jsb2IoYm9keSkpIHtcblx0XHRyZXR1cm4gYm9keS50eXBlIHx8IG51bGw7XG5cdH1cblxuXHQvLyBCb2R5IGlzIGEgQnVmZmVyIChCdWZmZXIsIEFycmF5QnVmZmVyIG9yIEFycmF5QnVmZmVyVmlldylcblx0aWYgKEJ1ZmZlci5pc0J1ZmZlcihib2R5KSB8fCB1dGlsLnR5cGVzLmlzQW55QXJyYXlCdWZmZXIoYm9keSkgfHwgQXJyYXlCdWZmZXIuaXNWaWV3KGJvZHkpKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHQvLyBEZXRlY3QgZm9ybSBkYXRhIGlucHV0IGZyb20gZm9ybS1kYXRhIG1vZHVsZVxuXHRpZiAoYm9keSAmJiB0eXBlb2YgYm9keS5nZXRCb3VuZGFyeSA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdHJldHVybiBgbXVsdGlwYXJ0L2Zvcm0tZGF0YTtib3VuZGFyeT0ke2JvZHkuZ2V0Qm91bmRhcnkoKX1gO1xuXHR9XG5cblx0aWYgKGlzRm9ybURhdGEoYm9keSkpIHtcblx0XHRyZXR1cm4gYG11bHRpcGFydC9mb3JtLWRhdGE7IGJvdW5kYXJ5PSR7cmVxdWVzdFtJTlRFUk5BTFNdLmJvdW5kYXJ5fWA7XG5cdH1cblxuXHQvLyBCb2R5IGlzIHN0cmVhbSAtIGNhbid0IHJlYWxseSBkbyBtdWNoIGFib3V0IHRoaXNcblx0aWYgKGJvZHkgaW5zdGFuY2VvZiBTdHJlYW0pIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdC8vIEJvZHkgY29uc3RydWN0b3IgZGVmYXVsdHMgb3RoZXIgdGhpbmdzIHRvIHN0cmluZ1xuXHRyZXR1cm4gJ3RleHQvcGxhaW47Y2hhcnNldD1VVEYtOCc7XG59O1xuXG4vKipcbiAqIFRoZSBGZXRjaCBTdGFuZGFyZCB0cmVhdHMgdGhpcyBhcyBpZiBcInRvdGFsIGJ5dGVzXCIgaXMgYSBwcm9wZXJ0eSBvbiB0aGUgYm9keS5cbiAqIEZvciB1cywgd2UgaGF2ZSB0byBleHBsaWNpdGx5IGdldCBpdCB3aXRoIGEgZnVuY3Rpb24uXG4gKlxuICogcmVmOiBodHRwczovL2ZldGNoLnNwZWMud2hhdHdnLm9yZy8jY29uY2VwdC1ib2R5LXRvdGFsLWJ5dGVzXG4gKlxuICogQHBhcmFtIHthbnl9IG9iai5ib2R5IEJvZHkgb2JqZWN0IGZyb20gdGhlIEJvZHkgaW5zdGFuY2UuXG4gKiBAcmV0dXJucyB7bnVtYmVyIHwgbnVsbH1cbiAqL1xuY29uc3QgZ2V0VG90YWxCeXRlcyA9IHJlcXVlc3QgPT4ge1xuXHRjb25zdCB7Ym9keX0gPSByZXF1ZXN0O1xuXG5cdC8vIEJvZHkgaXMgbnVsbCBvciB1bmRlZmluZWRcblx0aWYgKGJvZHkgPT09IG51bGwpIHtcblx0XHRyZXR1cm4gMDtcblx0fVxuXG5cdC8vIEJvZHkgaXMgQmxvYlxuXHRpZiAoaXNCbG9iKGJvZHkpKSB7XG5cdFx0cmV0dXJuIGJvZHkuc2l6ZTtcblx0fVxuXG5cdC8vIEJvZHkgaXMgQnVmZmVyXG5cdGlmIChCdWZmZXIuaXNCdWZmZXIoYm9keSkpIHtcblx0XHRyZXR1cm4gYm9keS5sZW5ndGg7XG5cdH1cblxuXHQvLyBEZXRlY3QgZm9ybSBkYXRhIGlucHV0IGZyb20gZm9ybS1kYXRhIG1vZHVsZVxuXHRpZiAoYm9keSAmJiB0eXBlb2YgYm9keS5nZXRMZW5ndGhTeW5jID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0cmV0dXJuIGJvZHkuaGFzS25vd25MZW5ndGggJiYgYm9keS5oYXNLbm93bkxlbmd0aCgpID8gYm9keS5nZXRMZW5ndGhTeW5jKCkgOiBudWxsO1xuXHR9XG5cblx0Ly8gQm9keSBpcyBhIHNwZWMtY29tcGxpYW50IGZvcm0tZGF0YVxuXHRpZiAoaXNGb3JtRGF0YShib2R5KSkge1xuXHRcdHJldHVybiBnZXRGb3JtRGF0YUxlbmd0aChyZXF1ZXN0W0lOVEVSTkFMU10uYm91bmRhcnkpO1xuXHR9XG5cblx0Ly8gQm9keSBpcyBzdHJlYW1cblx0cmV0dXJuIG51bGw7XG59O1xuXG4vKipcbiAqIFdyaXRlIGEgQm9keSB0byBhIE5vZGUuanMgV3JpdGFibGVTdHJlYW0gKGUuZy4gaHR0cC5SZXF1ZXN0KSBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtTdHJlYW0uV3JpdGFibGV9IGRlc3QgVGhlIHN0cmVhbSB0byB3cml0ZSB0by5cbiAqIEBwYXJhbSBvYmouYm9keSBCb2R5IG9iamVjdCBmcm9tIHRoZSBCb2R5IGluc3RhbmNlLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmNvbnN0IHdyaXRlVG9TdHJlYW0gPSAoZGVzdCwge2JvZHl9KSA9PiB7XG5cdGlmIChib2R5ID09PSBudWxsKSB7XG5cdFx0Ly8gQm9keSBpcyBudWxsXG5cdFx0ZGVzdC5lbmQoKTtcblx0fSBlbHNlIGlmIChpc0Jsb2IoYm9keSkpIHtcblx0XHQvLyBCb2R5IGlzIEJsb2Jcblx0XHRib2R5LnN0cmVhbSgpLnBpcGUoZGVzdCk7XG5cdH0gZWxzZSBpZiAoQnVmZmVyLmlzQnVmZmVyKGJvZHkpKSB7XG5cdFx0Ly8gQm9keSBpcyBidWZmZXJcblx0XHRkZXN0LndyaXRlKGJvZHkpO1xuXHRcdGRlc3QuZW5kKCk7XG5cdH0gZWxzZSB7XG5cdFx0Ly8gQm9keSBpcyBzdHJlYW1cblx0XHRib2R5LnBpcGUoZGVzdCk7XG5cdH1cbn07XG5cbi8qKlxuICogSGVhZGVycy5qc1xuICpcbiAqIEhlYWRlcnMgY2xhc3Mgb2ZmZXJzIGNvbnZlbmllbnQgaGVscGVyc1xuICovXG5cbmNvbnN0IHZhbGlkYXRlSGVhZGVyTmFtZSA9IHR5cGVvZiBodHRwLnZhbGlkYXRlSGVhZGVyTmFtZSA9PT0gJ2Z1bmN0aW9uJyA/XG5cdGh0dHAudmFsaWRhdGVIZWFkZXJOYW1lIDpcblx0bmFtZSA9PiB7XG5cdFx0aWYgKCEvXltcXF5gXFwtXFx3ISMkJSYnKisufH5dKyQvLnRlc3QobmFtZSkpIHtcblx0XHRcdGNvbnN0IGVyciA9IG5ldyBUeXBlRXJyb3IoYEhlYWRlciBuYW1lIG11c3QgYmUgYSB2YWxpZCBIVFRQIHRva2VuIFske25hbWV9XWApO1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGVyciwgJ2NvZGUnLCB7dmFsdWU6ICdFUlJfSU5WQUxJRF9IVFRQX1RPS0VOJ30pO1xuXHRcdFx0dGhyb3cgZXJyO1xuXHRcdH1cblx0fTtcblxuY29uc3QgdmFsaWRhdGVIZWFkZXJWYWx1ZSA9IHR5cGVvZiBodHRwLnZhbGlkYXRlSGVhZGVyVmFsdWUgPT09ICdmdW5jdGlvbicgP1xuXHRodHRwLnZhbGlkYXRlSGVhZGVyVmFsdWUgOlxuXHQobmFtZSwgdmFsdWUpID0+IHtcblx0XHRpZiAoL1teXFx0XFx1MDAyMC1cXHUwMDdFXFx1MDA4MC1cXHUwMEZGXS8udGVzdCh2YWx1ZSkpIHtcblx0XHRcdGNvbnN0IGVyciA9IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgY2hhcmFjdGVyIGluIGhlYWRlciBjb250ZW50IFtcIiR7bmFtZX1cIl1gKTtcblx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlcnIsICdjb2RlJywge3ZhbHVlOiAnRVJSX0lOVkFMSURfQ0hBUid9KTtcblx0XHRcdHRocm93IGVycjtcblx0XHR9XG5cdH07XG5cbi8qKlxuICogQHR5cGVkZWYge0hlYWRlcnMgfCBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHwgSXRlcmFibGU8cmVhZG9ubHkgW3N0cmluZywgc3RyaW5nXT4gfCBJdGVyYWJsZTxJdGVyYWJsZTxzdHJpbmc+Pn0gSGVhZGVyc0luaXRcbiAqL1xuXG4vKipcbiAqIFRoaXMgRmV0Y2ggQVBJIGludGVyZmFjZSBhbGxvd3MgeW91IHRvIHBlcmZvcm0gdmFyaW91cyBhY3Rpb25zIG9uIEhUVFAgcmVxdWVzdCBhbmQgcmVzcG9uc2UgaGVhZGVycy5cbiAqIFRoZXNlIGFjdGlvbnMgaW5jbHVkZSByZXRyaWV2aW5nLCBzZXR0aW5nLCBhZGRpbmcgdG8sIGFuZCByZW1vdmluZy5cbiAqIEEgSGVhZGVycyBvYmplY3QgaGFzIGFuIGFzc29jaWF0ZWQgaGVhZGVyIGxpc3QsIHdoaWNoIGlzIGluaXRpYWxseSBlbXB0eSBhbmQgY29uc2lzdHMgb2YgemVybyBvciBtb3JlIG5hbWUgYW5kIHZhbHVlIHBhaXJzLlxuICogWW91IGNhbiBhZGQgdG8gdGhpcyB1c2luZyBtZXRob2RzIGxpa2UgYXBwZW5kKCkgKHNlZSBFeGFtcGxlcy4pXG4gKiBJbiBhbGwgbWV0aG9kcyBvZiB0aGlzIGludGVyZmFjZSwgaGVhZGVyIG5hbWVzIGFyZSBtYXRjaGVkIGJ5IGNhc2UtaW5zZW5zaXRpdmUgYnl0ZSBzZXF1ZW5jZS5cbiAqXG4gKi9cbmNsYXNzIEhlYWRlcnMgZXh0ZW5kcyBVUkxTZWFyY2hQYXJhbXMge1xuXHQvKipcblx0ICogSGVhZGVycyBjbGFzc1xuXHQgKlxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICogQHBhcmFtIHtIZWFkZXJzSW5pdH0gW2luaXRdIC0gUmVzcG9uc2UgaGVhZGVyc1xuXHQgKi9cblx0Y29uc3RydWN0b3IoaW5pdCkge1xuXHRcdC8vIFZhbGlkYXRlIGFuZCBub3JtYWxpemUgaW5pdCBvYmplY3QgaW4gW25hbWUsIHZhbHVlKHMpXVtdXG5cdFx0LyoqIEB0eXBlIHtzdHJpbmdbXVtdfSAqL1xuXHRcdGxldCByZXN1bHQgPSBbXTtcblx0XHRpZiAoaW5pdCBpbnN0YW5jZW9mIEhlYWRlcnMpIHtcblx0XHRcdGNvbnN0IHJhdyA9IGluaXQucmF3KCk7XG5cdFx0XHRmb3IgKGNvbnN0IFtuYW1lLCB2YWx1ZXNdIG9mIE9iamVjdC5lbnRyaWVzKHJhdykpIHtcblx0XHRcdFx0cmVzdWx0LnB1c2goLi4udmFsdWVzLm1hcCh2YWx1ZSA9PiBbbmFtZSwgdmFsdWVdKSk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmIChpbml0ID09IG51bGwpIDsgZWxzZSBpZiAodHlwZW9mIGluaXQgPT09ICdvYmplY3QnICYmICF1dGlsLnR5cGVzLmlzQm94ZWRQcmltaXRpdmUoaW5pdCkpIHtcblx0XHRcdGNvbnN0IG1ldGhvZCA9IGluaXRbU3ltYm9sLml0ZXJhdG9yXTtcblx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1lcS1udWxsLCBlcWVxZXFcblx0XHRcdGlmIChtZXRob2QgPT0gbnVsbCkge1xuXHRcdFx0XHQvLyBSZWNvcmQ8Qnl0ZVN0cmluZywgQnl0ZVN0cmluZz5cblx0XHRcdFx0cmVzdWx0LnB1c2goLi4uT2JqZWN0LmVudHJpZXMoaW5pdCkpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKHR5cGVvZiBtZXRob2QgIT09ICdmdW5jdGlvbicpIHtcblx0XHRcdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdIZWFkZXIgcGFpcnMgbXVzdCBiZSBpdGVyYWJsZScpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gU2VxdWVuY2U8c2VxdWVuY2U8Qnl0ZVN0cmluZz4+XG5cdFx0XHRcdC8vIE5vdGU6IHBlciBzcGVjIHdlIGhhdmUgdG8gZmlyc3QgZXhoYXVzdCB0aGUgbGlzdHMgdGhlbiBwcm9jZXNzIHRoZW1cblx0XHRcdFx0cmVzdWx0ID0gWy4uLmluaXRdXG5cdFx0XHRcdFx0Lm1hcChwYWlyID0+IHtcblx0XHRcdFx0XHRcdGlmIChcblx0XHRcdFx0XHRcdFx0dHlwZW9mIHBhaXIgIT09ICdvYmplY3QnIHx8IHV0aWwudHlwZXMuaXNCb3hlZFByaW1pdGl2ZShwYWlyKVxuXHRcdFx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ0VhY2ggaGVhZGVyIHBhaXIgbXVzdCBiZSBhbiBpdGVyYWJsZSBvYmplY3QnKTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0cmV0dXJuIFsuLi5wYWlyXTtcblx0XHRcdFx0XHR9KS5tYXAocGFpciA9PiB7XG5cdFx0XHRcdFx0XHRpZiAocGFpci5sZW5ndGggIT09IDIpIHtcblx0XHRcdFx0XHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignRWFjaCBoZWFkZXIgcGFpciBtdXN0IGJlIGEgbmFtZS92YWx1ZSB0dXBsZScpO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRyZXR1cm4gWy4uLnBhaXJdO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdGYWlsZWQgdG8gY29uc3RydWN0IFxcJ0hlYWRlcnNcXCc6IFRoZSBwcm92aWRlZCB2YWx1ZSBpcyBub3Qgb2YgdHlwZSBcXCcoc2VxdWVuY2U8c2VxdWVuY2U8Qnl0ZVN0cmluZz4+IG9yIHJlY29yZDxCeXRlU3RyaW5nLCBCeXRlU3RyaW5nPiknKTtcblx0XHR9XG5cblx0XHQvLyBWYWxpZGF0ZSBhbmQgbG93ZXJjYXNlXG5cdFx0cmVzdWx0ID1cblx0XHRcdHJlc3VsdC5sZW5ndGggPiAwID9cblx0XHRcdFx0cmVzdWx0Lm1hcCgoW25hbWUsIHZhbHVlXSkgPT4ge1xuXHRcdFx0XHRcdHZhbGlkYXRlSGVhZGVyTmFtZShuYW1lKTtcblx0XHRcdFx0XHR2YWxpZGF0ZUhlYWRlclZhbHVlKG5hbWUsIFN0cmluZyh2YWx1ZSkpO1xuXHRcdFx0XHRcdHJldHVybiBbU3RyaW5nKG5hbWUpLnRvTG93ZXJDYXNlKCksIFN0cmluZyh2YWx1ZSldO1xuXHRcdFx0XHR9KSA6XG5cdFx0XHRcdHVuZGVmaW5lZDtcblxuXHRcdHN1cGVyKHJlc3VsdCk7XG5cblx0XHQvLyBSZXR1cm5pbmcgYSBQcm94eSB0aGF0IHdpbGwgbG93ZXJjYXNlIGtleSBuYW1lcywgdmFsaWRhdGUgcGFyYW1ldGVycyBhbmQgc29ydCBrZXlzXG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnN0cnVjdG9yLXJldHVyblxuXHRcdHJldHVybiBuZXcgUHJveHkodGhpcywge1xuXHRcdFx0Z2V0KHRhcmdldCwgcCwgcmVjZWl2ZXIpIHtcblx0XHRcdFx0c3dpdGNoIChwKSB7XG5cdFx0XHRcdFx0Y2FzZSAnYXBwZW5kJzpcblx0XHRcdFx0XHRjYXNlICdzZXQnOlxuXHRcdFx0XHRcdFx0cmV0dXJuIChuYW1lLCB2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdFx0XHR2YWxpZGF0ZUhlYWRlck5hbWUobmFtZSk7XG5cdFx0XHRcdFx0XHRcdHZhbGlkYXRlSGVhZGVyVmFsdWUobmFtZSwgU3RyaW5nKHZhbHVlKSk7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBVUkxTZWFyY2hQYXJhbXMucHJvdG90eXBlW3BdLmNhbGwoXG5cdFx0XHRcdFx0XHRcdFx0cmVjZWl2ZXIsXG5cdFx0XHRcdFx0XHRcdFx0U3RyaW5nKG5hbWUpLnRvTG93ZXJDYXNlKCksXG5cdFx0XHRcdFx0XHRcdFx0U3RyaW5nKHZhbHVlKVxuXHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0fTtcblxuXHRcdFx0XHRcdGNhc2UgJ2RlbGV0ZSc6XG5cdFx0XHRcdFx0Y2FzZSAnaGFzJzpcblx0XHRcdFx0XHRjYXNlICdnZXRBbGwnOlxuXHRcdFx0XHRcdFx0cmV0dXJuIG5hbWUgPT4ge1xuXHRcdFx0XHRcdFx0XHR2YWxpZGF0ZUhlYWRlck5hbWUobmFtZSk7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBVUkxTZWFyY2hQYXJhbXMucHJvdG90eXBlW3BdLmNhbGwoXG5cdFx0XHRcdFx0XHRcdFx0cmVjZWl2ZXIsXG5cdFx0XHRcdFx0XHRcdFx0U3RyaW5nKG5hbWUpLnRvTG93ZXJDYXNlKClcblx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdH07XG5cblx0XHRcdFx0XHRjYXNlICdrZXlzJzpcblx0XHRcdFx0XHRcdHJldHVybiAoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdHRhcmdldC5zb3J0KCk7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBuZXcgU2V0KFVSTFNlYXJjaFBhcmFtcy5wcm90b3R5cGUua2V5cy5jYWxsKHRhcmdldCkpLmtleXMoKTtcblx0XHRcdFx0XHRcdH07XG5cblx0XHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdFx0cmV0dXJuIFJlZmxlY3QuZ2V0KHRhcmdldCwgcCwgcmVjZWl2ZXIpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHQvKiBjOCBpZ25vcmUgbmV4dCAqL1xuXHRcdH0pO1xuXHR9XG5cblx0Z2V0IFtTeW1ib2wudG9TdHJpbmdUYWddKCkge1xuXHRcdHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLm5hbWU7XG5cdH1cblxuXHR0b1N0cmluZygpIHtcblx0XHRyZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHRoaXMpO1xuXHR9XG5cblx0Z2V0KG5hbWUpIHtcblx0XHRjb25zdCB2YWx1ZXMgPSB0aGlzLmdldEFsbChuYW1lKTtcblx0XHRpZiAodmFsdWVzLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0fVxuXG5cdFx0bGV0IHZhbHVlID0gdmFsdWVzLmpvaW4oJywgJyk7XG5cdFx0aWYgKC9eY29udGVudC1lbmNvZGluZyQvaS50ZXN0KG5hbWUpKSB7XG5cdFx0XHR2YWx1ZSA9IHZhbHVlLnRvTG93ZXJDYXNlKCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHZhbHVlO1xuXHR9XG5cblx0Zm9yRWFjaChjYWxsYmFjaykge1xuXHRcdGZvciAoY29uc3QgbmFtZSBvZiB0aGlzLmtleXMoKSkge1xuXHRcdFx0Y2FsbGJhY2sodGhpcy5nZXQobmFtZSksIG5hbWUpO1xuXHRcdH1cblx0fVxuXG5cdCogdmFsdWVzKCkge1xuXHRcdGZvciAoY29uc3QgbmFtZSBvZiB0aGlzLmtleXMoKSkge1xuXHRcdFx0eWllbGQgdGhpcy5nZXQobmFtZSk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEB0eXBlIHsoKSA9PiBJdGVyYWJsZUl0ZXJhdG9yPFtzdHJpbmcsIHN0cmluZ10+fVxuXHQgKi9cblx0KiBlbnRyaWVzKCkge1xuXHRcdGZvciAoY29uc3QgbmFtZSBvZiB0aGlzLmtleXMoKSkge1xuXHRcdFx0eWllbGQgW25hbWUsIHRoaXMuZ2V0KG5hbWUpXTtcblx0XHR9XG5cdH1cblxuXHRbU3ltYm9sLml0ZXJhdG9yXSgpIHtcblx0XHRyZXR1cm4gdGhpcy5lbnRyaWVzKCk7XG5cdH1cblxuXHQvKipcblx0ICogTm9kZS1mZXRjaCBub24tc3BlYyBtZXRob2Rcblx0ICogcmV0dXJuaW5nIGFsbCBoZWFkZXJzIGFuZCB0aGVpciB2YWx1ZXMgYXMgYXJyYXlcblx0ICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIHN0cmluZ1tdPn1cblx0ICovXG5cdHJhdygpIHtcblx0XHRyZXR1cm4gWy4uLnRoaXMua2V5cygpXS5yZWR1Y2UoKHJlc3VsdCwga2V5KSA9PiB7XG5cdFx0XHRyZXN1bHRba2V5XSA9IHRoaXMuZ2V0QWxsKGtleSk7XG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdH0sIHt9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBGb3IgYmV0dGVyIGNvbnNvbGUubG9nKGhlYWRlcnMpIGFuZCBhbHNvIHRvIGNvbnZlcnQgSGVhZGVycyBpbnRvIE5vZGUuanMgUmVxdWVzdCBjb21wYXRpYmxlIGZvcm1hdFxuXHQgKi9cblx0W1N5bWJvbC5mb3IoJ25vZGVqcy51dGlsLmluc3BlY3QuY3VzdG9tJyldKCkge1xuXHRcdHJldHVybiBbLi4udGhpcy5rZXlzKCldLnJlZHVjZSgocmVzdWx0LCBrZXkpID0+IHtcblx0XHRcdGNvbnN0IHZhbHVlcyA9IHRoaXMuZ2V0QWxsKGtleSk7XG5cdFx0XHQvLyBIdHRwLnJlcXVlc3QoKSBvbmx5IHN1cHBvcnRzIHN0cmluZyBhcyBIb3N0IGhlYWRlci5cblx0XHRcdC8vIFRoaXMgaGFjayBtYWtlcyBzcGVjaWZ5aW5nIGN1c3RvbSBIb3N0IGhlYWRlciBwb3NzaWJsZS5cblx0XHRcdGlmIChrZXkgPT09ICdob3N0Jykge1xuXHRcdFx0XHRyZXN1bHRba2V5XSA9IHZhbHVlc1swXTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJlc3VsdFtrZXldID0gdmFsdWVzLmxlbmd0aCA+IDEgPyB2YWx1ZXMgOiB2YWx1ZXNbMF07XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0fSwge30pO1xuXHR9XG59XG5cbi8qKlxuICogUmUtc2hhcGluZyBvYmplY3QgZm9yIFdlYiBJREwgdGVzdHNcbiAqIE9ubHkgbmVlZCB0byBkbyBpdCBmb3Igb3ZlcnJpZGRlbiBtZXRob2RzXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFxuXHRIZWFkZXJzLnByb3RvdHlwZSxcblx0WydnZXQnLCAnZW50cmllcycsICdmb3JFYWNoJywgJ3ZhbHVlcyddLnJlZHVjZSgocmVzdWx0LCBwcm9wZXJ0eSkgPT4ge1xuXHRcdHJlc3VsdFtwcm9wZXJ0eV0gPSB7ZW51bWVyYWJsZTogdHJ1ZX07XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fSwge30pXG4pO1xuXG4vKipcbiAqIENyZWF0ZSBhIEhlYWRlcnMgb2JqZWN0IGZyb20gYW4gaHR0cC5JbmNvbWluZ01lc3NhZ2UucmF3SGVhZGVycywgaWdub3JpbmcgdGhvc2UgdGhhdCBkb1xuICogbm90IGNvbmZvcm0gdG8gSFRUUCBncmFtbWFyIHByb2R1Y3Rpb25zLlxuICogQHBhcmFtIHtpbXBvcnQoJ2h0dHAnKS5JbmNvbWluZ01lc3NhZ2VbJ3Jhd0hlYWRlcnMnXX0gaGVhZGVyc1xuICovXG5mdW5jdGlvbiBmcm9tUmF3SGVhZGVycyhoZWFkZXJzID0gW10pIHtcblx0cmV0dXJuIG5ldyBIZWFkZXJzKFxuXHRcdGhlYWRlcnNcblx0XHRcdC8vIFNwbGl0IGludG8gcGFpcnNcblx0XHRcdC5yZWR1Y2UoKHJlc3VsdCwgdmFsdWUsIGluZGV4LCBhcnJheSkgPT4ge1xuXHRcdFx0XHRpZiAoaW5kZXggJSAyID09PSAwKSB7XG5cdFx0XHRcdFx0cmVzdWx0LnB1c2goYXJyYXkuc2xpY2UoaW5kZXgsIGluZGV4ICsgMikpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdH0sIFtdKVxuXHRcdFx0LmZpbHRlcigoW25hbWUsIHZhbHVlXSkgPT4ge1xuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdHZhbGlkYXRlSGVhZGVyTmFtZShuYW1lKTtcblx0XHRcdFx0XHR2YWxpZGF0ZUhlYWRlclZhbHVlKG5hbWUsIFN0cmluZyh2YWx1ZSkpO1xuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH0pXG5cblx0KTtcbn1cblxuY29uc3QgcmVkaXJlY3RTdGF0dXMgPSBuZXcgU2V0KFszMDEsIDMwMiwgMzAzLCAzMDcsIDMwOF0pO1xuXG4vKipcbiAqIFJlZGlyZWN0IGNvZGUgbWF0Y2hpbmdcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gY29kZSAtIFN0YXR1cyBjb2RlXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5jb25zdCBpc1JlZGlyZWN0ID0gY29kZSA9PiB7XG5cdHJldHVybiByZWRpcmVjdFN0YXR1cy5oYXMoY29kZSk7XG59O1xuXG4vKipcbiAqIFJlc3BvbnNlLmpzXG4gKlxuICogUmVzcG9uc2UgY2xhc3MgcHJvdmlkZXMgY29udGVudCBkZWNvZGluZ1xuICovXG5cbmNvbnN0IElOVEVSTkFMUyQxID0gU3ltYm9sKCdSZXNwb25zZSBpbnRlcm5hbHMnKTtcblxuLyoqXG4gKiBSZXNwb25zZSBjbGFzc1xuICpcbiAqIEBwYXJhbSAgIFN0cmVhbSAgYm9keSAgUmVhZGFibGUgc3RyZWFtXG4gKiBAcGFyYW0gICBPYmplY3QgIG9wdHMgIFJlc3BvbnNlIG9wdGlvbnNcbiAqIEByZXR1cm4gIFZvaWRcbiAqL1xuY2xhc3MgUmVzcG9uc2UgZXh0ZW5kcyBCb2R5IHtcblx0Y29uc3RydWN0b3IoYm9keSA9IG51bGwsIG9wdGlvbnMgPSB7fSkge1xuXHRcdHN1cGVyKGJvZHksIG9wdGlvbnMpO1xuXG5cdFx0Y29uc3Qgc3RhdHVzID0gb3B0aW9ucy5zdGF0dXMgfHwgMjAwO1xuXHRcdGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycyhvcHRpb25zLmhlYWRlcnMpO1xuXG5cdFx0aWYgKGJvZHkgIT09IG51bGwgJiYgIWhlYWRlcnMuaGFzKCdDb250ZW50LVR5cGUnKSkge1xuXHRcdFx0Y29uc3QgY29udGVudFR5cGUgPSBleHRyYWN0Q29udGVudFR5cGUoYm9keSk7XG5cdFx0XHRpZiAoY29udGVudFR5cGUpIHtcblx0XHRcdFx0aGVhZGVycy5hcHBlbmQoJ0NvbnRlbnQtVHlwZScsIGNvbnRlbnRUeXBlKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aGlzW0lOVEVSTkFMUyQxXSA9IHtcblx0XHRcdHVybDogb3B0aW9ucy51cmwsXG5cdFx0XHRzdGF0dXMsXG5cdFx0XHRzdGF0dXNUZXh0OiBvcHRpb25zLnN0YXR1c1RleHQgfHwgJycsXG5cdFx0XHRoZWFkZXJzLFxuXHRcdFx0Y291bnRlcjogb3B0aW9ucy5jb3VudGVyLFxuXHRcdFx0aGlnaFdhdGVyTWFyazogb3B0aW9ucy5oaWdoV2F0ZXJNYXJrXG5cdFx0fTtcblx0fVxuXG5cdGdldCB1cmwoKSB7XG5cdFx0cmV0dXJuIHRoaXNbSU5URVJOQUxTJDFdLnVybCB8fCAnJztcblx0fVxuXG5cdGdldCBzdGF0dXMoKSB7XG5cdFx0cmV0dXJuIHRoaXNbSU5URVJOQUxTJDFdLnN0YXR1cztcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZW5pZW5jZSBwcm9wZXJ0eSByZXByZXNlbnRpbmcgaWYgdGhlIHJlcXVlc3QgZW5kZWQgbm9ybWFsbHlcblx0ICovXG5cdGdldCBvaygpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFMkMV0uc3RhdHVzID49IDIwMCAmJiB0aGlzW0lOVEVSTkFMUyQxXS5zdGF0dXMgPCAzMDA7XG5cdH1cblxuXHRnZXQgcmVkaXJlY3RlZCgpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFMkMV0uY291bnRlciA+IDA7XG5cdH1cblxuXHRnZXQgc3RhdHVzVGV4dCgpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFMkMV0uc3RhdHVzVGV4dDtcblx0fVxuXG5cdGdldCBoZWFkZXJzKCkge1xuXHRcdHJldHVybiB0aGlzW0lOVEVSTkFMUyQxXS5oZWFkZXJzO1xuXHR9XG5cblx0Z2V0IGhpZ2hXYXRlck1hcmsoKSB7XG5cdFx0cmV0dXJuIHRoaXNbSU5URVJOQUxTJDFdLmhpZ2hXYXRlck1hcms7XG5cdH1cblxuXHQvKipcblx0ICogQ2xvbmUgdGhpcyByZXNwb25zZVxuXHQgKlxuXHQgKiBAcmV0dXJuICBSZXNwb25zZVxuXHQgKi9cblx0Y2xvbmUoKSB7XG5cdFx0cmV0dXJuIG5ldyBSZXNwb25zZShjbG9uZSh0aGlzLCB0aGlzLmhpZ2hXYXRlck1hcmspLCB7XG5cdFx0XHR1cmw6IHRoaXMudXJsLFxuXHRcdFx0c3RhdHVzOiB0aGlzLnN0YXR1cyxcblx0XHRcdHN0YXR1c1RleHQ6IHRoaXMuc3RhdHVzVGV4dCxcblx0XHRcdGhlYWRlcnM6IHRoaXMuaGVhZGVycyxcblx0XHRcdG9rOiB0aGlzLm9rLFxuXHRcdFx0cmVkaXJlY3RlZDogdGhpcy5yZWRpcmVjdGVkLFxuXHRcdFx0c2l6ZTogdGhpcy5zaXplXG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogQHBhcmFtIHtzdHJpbmd9IHVybCAgICBUaGUgVVJMIHRoYXQgdGhlIG5ldyByZXNwb25zZSBpcyB0byBvcmlnaW5hdGUgZnJvbS5cblx0ICogQHBhcmFtIHtudW1iZXJ9IHN0YXR1cyBBbiBvcHRpb25hbCBzdGF0dXMgY29kZSBmb3IgdGhlIHJlc3BvbnNlIChlLmcuLCAzMDIuKVxuXHQgKiBAcmV0dXJucyB7UmVzcG9uc2V9ICAgIEEgUmVzcG9uc2Ugb2JqZWN0LlxuXHQgKi9cblx0c3RhdGljIHJlZGlyZWN0KHVybCwgc3RhdHVzID0gMzAyKSB7XG5cdFx0aWYgKCFpc1JlZGlyZWN0KHN0YXR1cykpIHtcblx0XHRcdHRocm93IG5ldyBSYW5nZUVycm9yKCdGYWlsZWQgdG8gZXhlY3V0ZSBcInJlZGlyZWN0XCIgb24gXCJyZXNwb25zZVwiOiBJbnZhbGlkIHN0YXR1cyBjb2RlJyk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG5ldyBSZXNwb25zZShudWxsLCB7XG5cdFx0XHRoZWFkZXJzOiB7XG5cdFx0XHRcdGxvY2F0aW9uOiBuZXcgVVJMKHVybCkudG9TdHJpbmcoKVxuXHRcdFx0fSxcblx0XHRcdHN0YXR1c1xuXHRcdH0pO1xuXHR9XG5cblx0Z2V0IFtTeW1ib2wudG9TdHJpbmdUYWddKCkge1xuXHRcdHJldHVybiAnUmVzcG9uc2UnO1xuXHR9XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFJlc3BvbnNlLnByb3RvdHlwZSwge1xuXHR1cmw6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0c3RhdHVzOiB7ZW51bWVyYWJsZTogdHJ1ZX0sXG5cdG9rOiB7ZW51bWVyYWJsZTogdHJ1ZX0sXG5cdHJlZGlyZWN0ZWQ6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0c3RhdHVzVGV4dDoge2VudW1lcmFibGU6IHRydWV9LFxuXHRoZWFkZXJzOiB7ZW51bWVyYWJsZTogdHJ1ZX0sXG5cdGNsb25lOiB7ZW51bWVyYWJsZTogdHJ1ZX1cbn0pO1xuXG5jb25zdCBnZXRTZWFyY2ggPSBwYXJzZWRVUkwgPT4ge1xuXHRpZiAocGFyc2VkVVJMLnNlYXJjaCkge1xuXHRcdHJldHVybiBwYXJzZWRVUkwuc2VhcmNoO1xuXHR9XG5cblx0Y29uc3QgbGFzdE9mZnNldCA9IHBhcnNlZFVSTC5ocmVmLmxlbmd0aCAtIDE7XG5cdGNvbnN0IGhhc2ggPSBwYXJzZWRVUkwuaGFzaCB8fCAocGFyc2VkVVJMLmhyZWZbbGFzdE9mZnNldF0gPT09ICcjJyA/ICcjJyA6ICcnKTtcblx0cmV0dXJuIHBhcnNlZFVSTC5ocmVmW2xhc3RPZmZzZXQgLSBoYXNoLmxlbmd0aF0gPT09ICc/JyA/ICc/JyA6ICcnO1xufTtcblxuY29uc3QgSU5URVJOQUxTJDIgPSBTeW1ib2woJ1JlcXVlc3QgaW50ZXJuYWxzJyk7XG5cbi8qKlxuICogQ2hlY2sgaWYgYG9iamAgaXMgYW4gaW5zdGFuY2Ugb2YgUmVxdWVzdC5cbiAqXG4gKiBAcGFyYW0gIHsqfSBvYmpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmNvbnN0IGlzUmVxdWVzdCA9IG9iamVjdCA9PiB7XG5cdHJldHVybiAoXG5cdFx0dHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcgJiZcblx0XHR0eXBlb2Ygb2JqZWN0W0lOVEVSTkFMUyQyXSA9PT0gJ29iamVjdCdcblx0KTtcbn07XG5cbi8qKlxuICogUmVxdWVzdCBjbGFzc1xuICpcbiAqIEBwYXJhbSAgIE1peGVkICAgaW5wdXQgIFVybCBvciBSZXF1ZXN0IGluc3RhbmNlXG4gKiBAcGFyYW0gICBPYmplY3QgIGluaXQgICBDdXN0b20gb3B0aW9uc1xuICogQHJldHVybiAgVm9pZFxuICovXG5jbGFzcyBSZXF1ZXN0IGV4dGVuZHMgQm9keSB7XG5cdGNvbnN0cnVjdG9yKGlucHV0LCBpbml0ID0ge30pIHtcblx0XHRsZXQgcGFyc2VkVVJMO1xuXG5cdFx0Ly8gTm9ybWFsaXplIGlucHV0IGFuZCBmb3JjZSBVUkwgdG8gYmUgZW5jb2RlZCBhcyBVVEYtOCAoaHR0cHM6Ly9naXRodWIuY29tL25vZGUtZmV0Y2gvbm9kZS1mZXRjaC9pc3N1ZXMvMjQ1KVxuXHRcdGlmIChpc1JlcXVlc3QoaW5wdXQpKSB7XG5cdFx0XHRwYXJzZWRVUkwgPSBuZXcgVVJMKGlucHV0LnVybCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHBhcnNlZFVSTCA9IG5ldyBVUkwoaW5wdXQpO1xuXHRcdFx0aW5wdXQgPSB7fTtcblx0XHR9XG5cblx0XHRsZXQgbWV0aG9kID0gaW5pdC5tZXRob2QgfHwgaW5wdXQubWV0aG9kIHx8ICdHRVQnO1xuXHRcdG1ldGhvZCA9IG1ldGhvZC50b1VwcGVyQ2FzZSgpO1xuXG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWVxLW51bGwsIGVxZXFlcVxuXHRcdGlmICgoKGluaXQuYm9keSAhPSBudWxsIHx8IGlzUmVxdWVzdChpbnB1dCkpICYmIGlucHV0LmJvZHkgIT09IG51bGwpICYmXG5cdFx0XHQobWV0aG9kID09PSAnR0VUJyB8fCBtZXRob2QgPT09ICdIRUFEJykpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ1JlcXVlc3Qgd2l0aCBHRVQvSEVBRCBtZXRob2QgY2Fubm90IGhhdmUgYm9keScpO1xuXHRcdH1cblxuXHRcdGNvbnN0IGlucHV0Qm9keSA9IGluaXQuYm9keSA/XG5cdFx0XHRpbml0LmJvZHkgOlxuXHRcdFx0KGlzUmVxdWVzdChpbnB1dCkgJiYgaW5wdXQuYm9keSAhPT0gbnVsbCA/XG5cdFx0XHRcdGNsb25lKGlucHV0KSA6XG5cdFx0XHRcdG51bGwpO1xuXG5cdFx0c3VwZXIoaW5wdXRCb2R5LCB7XG5cdFx0XHRzaXplOiBpbml0LnNpemUgfHwgaW5wdXQuc2l6ZSB8fCAwXG5cdFx0fSk7XG5cblx0XHRjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMoaW5pdC5oZWFkZXJzIHx8IGlucHV0LmhlYWRlcnMgfHwge30pO1xuXG5cdFx0aWYgKGlucHV0Qm9keSAhPT0gbnVsbCAmJiAhaGVhZGVycy5oYXMoJ0NvbnRlbnQtVHlwZScpKSB7XG5cdFx0XHRjb25zdCBjb250ZW50VHlwZSA9IGV4dHJhY3RDb250ZW50VHlwZShpbnB1dEJvZHksIHRoaXMpO1xuXHRcdFx0aWYgKGNvbnRlbnRUeXBlKSB7XG5cdFx0XHRcdGhlYWRlcnMuYXBwZW5kKCdDb250ZW50LVR5cGUnLCBjb250ZW50VHlwZSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0bGV0IHNpZ25hbCA9IGlzUmVxdWVzdChpbnB1dCkgP1xuXHRcdFx0aW5wdXQuc2lnbmFsIDpcblx0XHRcdG51bGw7XG5cdFx0aWYgKCdzaWduYWwnIGluIGluaXQpIHtcblx0XHRcdHNpZ25hbCA9IGluaXQuc2lnbmFsO1xuXHRcdH1cblxuXHRcdGlmIChzaWduYWwgIT09IG51bGwgJiYgIWlzQWJvcnRTaWduYWwoc2lnbmFsKSkge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignRXhwZWN0ZWQgc2lnbmFsIHRvIGJlIGFuIGluc3RhbmNlb2YgQWJvcnRTaWduYWwnKTtcblx0XHR9XG5cblx0XHR0aGlzW0lOVEVSTkFMUyQyXSA9IHtcblx0XHRcdG1ldGhvZCxcblx0XHRcdHJlZGlyZWN0OiBpbml0LnJlZGlyZWN0IHx8IGlucHV0LnJlZGlyZWN0IHx8ICdmb2xsb3cnLFxuXHRcdFx0aGVhZGVycyxcblx0XHRcdHBhcnNlZFVSTCxcblx0XHRcdHNpZ25hbFxuXHRcdH07XG5cblx0XHQvLyBOb2RlLWZldGNoLW9ubHkgb3B0aW9uc1xuXHRcdHRoaXMuZm9sbG93ID0gaW5pdC5mb2xsb3cgPT09IHVuZGVmaW5lZCA/IChpbnB1dC5mb2xsb3cgPT09IHVuZGVmaW5lZCA/IDIwIDogaW5wdXQuZm9sbG93KSA6IGluaXQuZm9sbG93O1xuXHRcdHRoaXMuY29tcHJlc3MgPSBpbml0LmNvbXByZXNzID09PSB1bmRlZmluZWQgPyAoaW5wdXQuY29tcHJlc3MgPT09IHVuZGVmaW5lZCA/IHRydWUgOiBpbnB1dC5jb21wcmVzcykgOiBpbml0LmNvbXByZXNzO1xuXHRcdHRoaXMuY291bnRlciA9IGluaXQuY291bnRlciB8fCBpbnB1dC5jb3VudGVyIHx8IDA7XG5cdFx0dGhpcy5hZ2VudCA9IGluaXQuYWdlbnQgfHwgaW5wdXQuYWdlbnQ7XG5cdFx0dGhpcy5oaWdoV2F0ZXJNYXJrID0gaW5pdC5oaWdoV2F0ZXJNYXJrIHx8IGlucHV0LmhpZ2hXYXRlck1hcmsgfHwgMTYzODQ7XG5cdFx0dGhpcy5pbnNlY3VyZUhUVFBQYXJzZXIgPSBpbml0Lmluc2VjdXJlSFRUUFBhcnNlciB8fCBpbnB1dC5pbnNlY3VyZUhUVFBQYXJzZXIgfHwgZmFsc2U7XG5cdH1cblxuXHRnZXQgbWV0aG9kKCkge1xuXHRcdHJldHVybiB0aGlzW0lOVEVSTkFMUyQyXS5tZXRob2Q7XG5cdH1cblxuXHRnZXQgdXJsKCkge1xuXHRcdHJldHVybiB1cmwuZm9ybWF0KHRoaXNbSU5URVJOQUxTJDJdLnBhcnNlZFVSTCk7XG5cdH1cblxuXHRnZXQgaGVhZGVycygpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFMkMl0uaGVhZGVycztcblx0fVxuXG5cdGdldCByZWRpcmVjdCgpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFMkMl0ucmVkaXJlY3Q7XG5cdH1cblxuXHRnZXQgc2lnbmFsKCkge1xuXHRcdHJldHVybiB0aGlzW0lOVEVSTkFMUyQyXS5zaWduYWw7XG5cdH1cblxuXHQvKipcblx0ICogQ2xvbmUgdGhpcyByZXF1ZXN0XG5cdCAqXG5cdCAqIEByZXR1cm4gIFJlcXVlc3Rcblx0ICovXG5cdGNsb25lKCkge1xuXHRcdHJldHVybiBuZXcgUmVxdWVzdCh0aGlzKTtcblx0fVxuXG5cdGdldCBbU3ltYm9sLnRvU3RyaW5nVGFnXSgpIHtcblx0XHRyZXR1cm4gJ1JlcXVlc3QnO1xuXHR9XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFJlcXVlc3QucHJvdG90eXBlLCB7XG5cdG1ldGhvZDoge2VudW1lcmFibGU6IHRydWV9LFxuXHR1cmw6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0aGVhZGVyczoge2VudW1lcmFibGU6IHRydWV9LFxuXHRyZWRpcmVjdDoge2VudW1lcmFibGU6IHRydWV9LFxuXHRjbG9uZToge2VudW1lcmFibGU6IHRydWV9LFxuXHRzaWduYWw6IHtlbnVtZXJhYmxlOiB0cnVlfVxufSk7XG5cbi8qKlxuICogQ29udmVydCBhIFJlcXVlc3QgdG8gTm9kZS5qcyBodHRwIHJlcXVlc3Qgb3B0aW9ucy5cbiAqXG4gKiBAcGFyYW0gICBSZXF1ZXN0ICBBIFJlcXVlc3QgaW5zdGFuY2VcbiAqIEByZXR1cm4gIE9iamVjdCAgIFRoZSBvcHRpb25zIG9iamVjdCB0byBiZSBwYXNzZWQgdG8gaHR0cC5yZXF1ZXN0XG4gKi9cbmNvbnN0IGdldE5vZGVSZXF1ZXN0T3B0aW9ucyA9IHJlcXVlc3QgPT4ge1xuXHRjb25zdCB7cGFyc2VkVVJMfSA9IHJlcXVlc3RbSU5URVJOQUxTJDJdO1xuXHRjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMocmVxdWVzdFtJTlRFUk5BTFMkMl0uaGVhZGVycyk7XG5cblx0Ly8gRmV0Y2ggc3RlcCAxLjNcblx0aWYgKCFoZWFkZXJzLmhhcygnQWNjZXB0JykpIHtcblx0XHRoZWFkZXJzLnNldCgnQWNjZXB0JywgJyovKicpO1xuXHR9XG5cblx0Ly8gSFRUUC1uZXR3b3JrLW9yLWNhY2hlIGZldGNoIHN0ZXBzIDIuNC0yLjdcblx0bGV0IGNvbnRlbnRMZW5ndGhWYWx1ZSA9IG51bGw7XG5cdGlmIChyZXF1ZXN0LmJvZHkgPT09IG51bGwgJiYgL14ocG9zdHxwdXQpJC9pLnRlc3QocmVxdWVzdC5tZXRob2QpKSB7XG5cdFx0Y29udGVudExlbmd0aFZhbHVlID0gJzAnO1xuXHR9XG5cblx0aWYgKHJlcXVlc3QuYm9keSAhPT0gbnVsbCkge1xuXHRcdGNvbnN0IHRvdGFsQnl0ZXMgPSBnZXRUb3RhbEJ5dGVzKHJlcXVlc3QpO1xuXHRcdC8vIFNldCBDb250ZW50LUxlbmd0aCBpZiB0b3RhbEJ5dGVzIGlzIGEgbnVtYmVyICh0aGF0IGlzIG5vdCBOYU4pXG5cdFx0aWYgKHR5cGVvZiB0b3RhbEJ5dGVzID09PSAnbnVtYmVyJyAmJiAhTnVtYmVyLmlzTmFOKHRvdGFsQnl0ZXMpKSB7XG5cdFx0XHRjb250ZW50TGVuZ3RoVmFsdWUgPSBTdHJpbmcodG90YWxCeXRlcyk7XG5cdFx0fVxuXHR9XG5cblx0aWYgKGNvbnRlbnRMZW5ndGhWYWx1ZSkge1xuXHRcdGhlYWRlcnMuc2V0KCdDb250ZW50LUxlbmd0aCcsIGNvbnRlbnRMZW5ndGhWYWx1ZSk7XG5cdH1cblxuXHQvLyBIVFRQLW5ldHdvcmstb3ItY2FjaGUgZmV0Y2ggc3RlcCAyLjExXG5cdGlmICghaGVhZGVycy5oYXMoJ1VzZXItQWdlbnQnKSkge1xuXHRcdGhlYWRlcnMuc2V0KCdVc2VyLUFnZW50JywgJ25vZGUtZmV0Y2gnKTtcblx0fVxuXG5cdC8vIEhUVFAtbmV0d29yay1vci1jYWNoZSBmZXRjaCBzdGVwIDIuMTVcblx0aWYgKHJlcXVlc3QuY29tcHJlc3MgJiYgIWhlYWRlcnMuaGFzKCdBY2NlcHQtRW5jb2RpbmcnKSkge1xuXHRcdGhlYWRlcnMuc2V0KCdBY2NlcHQtRW5jb2RpbmcnLCAnZ3ppcCxkZWZsYXRlLGJyJyk7XG5cdH1cblxuXHRsZXQge2FnZW50fSA9IHJlcXVlc3Q7XG5cdGlmICh0eXBlb2YgYWdlbnQgPT09ICdmdW5jdGlvbicpIHtcblx0XHRhZ2VudCA9IGFnZW50KHBhcnNlZFVSTCk7XG5cdH1cblxuXHRpZiAoIWhlYWRlcnMuaGFzKCdDb25uZWN0aW9uJykgJiYgIWFnZW50KSB7XG5cdFx0aGVhZGVycy5zZXQoJ0Nvbm5lY3Rpb24nLCAnY2xvc2UnKTtcblx0fVxuXG5cdC8vIEhUVFAtbmV0d29yayBmZXRjaCBzdGVwIDQuMlxuXHQvLyBjaHVua2VkIGVuY29kaW5nIGlzIGhhbmRsZWQgYnkgTm9kZS5qc1xuXG5cdGNvbnN0IHNlYXJjaCA9IGdldFNlYXJjaChwYXJzZWRVUkwpO1xuXG5cdC8vIE1hbnVhbGx5IHNwcmVhZCB0aGUgVVJMIG9iamVjdCBpbnN0ZWFkIG9mIHNwcmVhZCBzeW50YXhcblx0Y29uc3QgcmVxdWVzdE9wdGlvbnMgPSB7XG5cdFx0cGF0aDogcGFyc2VkVVJMLnBhdGhuYW1lICsgc2VhcmNoLFxuXHRcdHBhdGhuYW1lOiBwYXJzZWRVUkwucGF0aG5hbWUsXG5cdFx0aG9zdG5hbWU6IHBhcnNlZFVSTC5ob3N0bmFtZSxcblx0XHRwcm90b2NvbDogcGFyc2VkVVJMLnByb3RvY29sLFxuXHRcdHBvcnQ6IHBhcnNlZFVSTC5wb3J0LFxuXHRcdGhhc2g6IHBhcnNlZFVSTC5oYXNoLFxuXHRcdHNlYXJjaDogcGFyc2VkVVJMLnNlYXJjaCxcblx0XHRxdWVyeTogcGFyc2VkVVJMLnF1ZXJ5LFxuXHRcdGhyZWY6IHBhcnNlZFVSTC5ocmVmLFxuXHRcdG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG5cdFx0aGVhZGVyczogaGVhZGVyc1tTeW1ib2wuZm9yKCdub2RlanMudXRpbC5pbnNwZWN0LmN1c3RvbScpXSgpLFxuXHRcdGluc2VjdXJlSFRUUFBhcnNlcjogcmVxdWVzdC5pbnNlY3VyZUhUVFBQYXJzZXIsXG5cdFx0YWdlbnRcblx0fTtcblxuXHRyZXR1cm4gcmVxdWVzdE9wdGlvbnM7XG59O1xuXG4vKipcbiAqIEFib3J0RXJyb3IgaW50ZXJmYWNlIGZvciBjYW5jZWxsZWQgcmVxdWVzdHNcbiAqL1xuY2xhc3MgQWJvcnRFcnJvciBleHRlbmRzIEZldGNoQmFzZUVycm9yIHtcblx0Y29uc3RydWN0b3IobWVzc2FnZSwgdHlwZSA9ICdhYm9ydGVkJykge1xuXHRcdHN1cGVyKG1lc3NhZ2UsIHR5cGUpO1xuXHR9XG59XG5cbi8qKlxuICogSW5kZXguanNcbiAqXG4gKiBhIHJlcXVlc3QgQVBJIGNvbXBhdGlibGUgd2l0aCB3aW5kb3cuZmV0Y2hcbiAqXG4gKiBBbGwgc3BlYyBhbGdvcml0aG0gc3RlcCBudW1iZXJzIGFyZSBiYXNlZCBvbiBodHRwczovL2ZldGNoLnNwZWMud2hhdHdnLm9yZy9jb21taXQtc25hcHNob3RzL2FlNzE2ODIyY2IzYTYxODQzMjI2Y2QwOTBlZWZjNjU4OTQ0NmMxZDIvLlxuICovXG5cbmNvbnN0IHN1cHBvcnRlZFNjaGVtYXMgPSBuZXcgU2V0KFsnZGF0YTonLCAnaHR0cDonLCAnaHR0cHM6J10pO1xuXG4vKipcbiAqIEZldGNoIGZ1bmN0aW9uXG4gKlxuICogQHBhcmFtICAge3N0cmluZyB8IFVSTCB8IGltcG9ydCgnLi9yZXF1ZXN0JykuZGVmYXVsdH0gdXJsIC0gQWJzb2x1dGUgdXJsIG9yIFJlcXVlc3QgaW5zdGFuY2VcbiAqIEBwYXJhbSAgIHsqfSBbb3B0aW9uc19dIC0gRmV0Y2ggb3B0aW9uc1xuICogQHJldHVybiAge1Byb21pc2U8aW1wb3J0KCcuL3Jlc3BvbnNlJykuZGVmYXVsdD59XG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGZldGNoKHVybCwgb3B0aW9uc18pIHtcblx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblx0XHQvLyBCdWlsZCByZXF1ZXN0IG9iamVjdFxuXHRcdGNvbnN0IHJlcXVlc3QgPSBuZXcgUmVxdWVzdCh1cmwsIG9wdGlvbnNfKTtcblx0XHRjb25zdCBvcHRpb25zID0gZ2V0Tm9kZVJlcXVlc3RPcHRpb25zKHJlcXVlc3QpO1xuXHRcdGlmICghc3VwcG9ydGVkU2NoZW1hcy5oYXMob3B0aW9ucy5wcm90b2NvbCkpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYG5vZGUtZmV0Y2ggY2Fubm90IGxvYWQgJHt1cmx9LiBVUkwgc2NoZW1lIFwiJHtvcHRpb25zLnByb3RvY29sLnJlcGxhY2UoLzokLywgJycpfVwiIGlzIG5vdCBzdXBwb3J0ZWQuYCk7XG5cdFx0fVxuXG5cdFx0aWYgKG9wdGlvbnMucHJvdG9jb2wgPT09ICdkYXRhOicpIHtcblx0XHRcdGNvbnN0IGRhdGEgPSBkYXRhVXJpVG9CdWZmZXIocmVxdWVzdC51cmwpO1xuXHRcdFx0Y29uc3QgcmVzcG9uc2UgPSBuZXcgUmVzcG9uc2UoZGF0YSwge2hlYWRlcnM6IHsnQ29udGVudC1UeXBlJzogZGF0YS50eXBlRnVsbH19KTtcblx0XHRcdHJlc29sdmUocmVzcG9uc2UpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIFdyYXAgaHR0cC5yZXF1ZXN0IGludG8gZmV0Y2hcblx0XHRjb25zdCBzZW5kID0gKG9wdGlvbnMucHJvdG9jb2wgPT09ICdodHRwczonID8gaHR0cHMgOiBodHRwKS5yZXF1ZXN0O1xuXHRcdGNvbnN0IHtzaWduYWx9ID0gcmVxdWVzdDtcblx0XHRsZXQgcmVzcG9uc2UgPSBudWxsO1xuXG5cdFx0Y29uc3QgYWJvcnQgPSAoKSA9PiB7XG5cdFx0XHRjb25zdCBlcnJvciA9IG5ldyBBYm9ydEVycm9yKCdUaGUgb3BlcmF0aW9uIHdhcyBhYm9ydGVkLicpO1xuXHRcdFx0cmVqZWN0KGVycm9yKTtcblx0XHRcdGlmIChyZXF1ZXN0LmJvZHkgJiYgcmVxdWVzdC5ib2R5IGluc3RhbmNlb2YgU3RyZWFtLlJlYWRhYmxlKSB7XG5cdFx0XHRcdHJlcXVlc3QuYm9keS5kZXN0cm95KGVycm9yKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCFyZXNwb25zZSB8fCAhcmVzcG9uc2UuYm9keSkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdHJlc3BvbnNlLmJvZHkuZW1pdCgnZXJyb3InLCBlcnJvcik7XG5cdFx0fTtcblxuXHRcdGlmIChzaWduYWwgJiYgc2lnbmFsLmFib3J0ZWQpIHtcblx0XHRcdGFib3J0KCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Y29uc3QgYWJvcnRBbmRGaW5hbGl6ZSA9ICgpID0+IHtcblx0XHRcdGFib3J0KCk7XG5cdFx0XHRmaW5hbGl6ZSgpO1xuXHRcdH07XG5cblx0XHQvLyBTZW5kIHJlcXVlc3Rcblx0XHRjb25zdCByZXF1ZXN0XyA9IHNlbmQob3B0aW9ucyk7XG5cblx0XHRpZiAoc2lnbmFsKSB7XG5cdFx0XHRzaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBhYm9ydEFuZEZpbmFsaXplKTtcblx0XHR9XG5cblx0XHRjb25zdCBmaW5hbGl6ZSA9ICgpID0+IHtcblx0XHRcdHJlcXVlc3RfLmFib3J0KCk7XG5cdFx0XHRpZiAoc2lnbmFsKSB7XG5cdFx0XHRcdHNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIGFib3J0QW5kRmluYWxpemUpO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHRyZXF1ZXN0Xy5vbignZXJyb3InLCBlcnIgPT4ge1xuXHRcdFx0cmVqZWN0KG5ldyBGZXRjaEVycm9yKGByZXF1ZXN0IHRvICR7cmVxdWVzdC51cmx9IGZhaWxlZCwgcmVhc29uOiAke2Vyci5tZXNzYWdlfWAsICdzeXN0ZW0nLCBlcnIpKTtcblx0XHRcdGZpbmFsaXplKCk7XG5cdFx0fSk7XG5cblx0XHRyZXF1ZXN0Xy5vbigncmVzcG9uc2UnLCByZXNwb25zZV8gPT4ge1xuXHRcdFx0cmVxdWVzdF8uc2V0VGltZW91dCgwKTtcblx0XHRcdGNvbnN0IGhlYWRlcnMgPSBmcm9tUmF3SGVhZGVycyhyZXNwb25zZV8ucmF3SGVhZGVycyk7XG5cblx0XHRcdC8vIEhUVFAgZmV0Y2ggc3RlcCA1XG5cdFx0XHRpZiAoaXNSZWRpcmVjdChyZXNwb25zZV8uc3RhdHVzQ29kZSkpIHtcblx0XHRcdFx0Ly8gSFRUUCBmZXRjaCBzdGVwIDUuMlxuXHRcdFx0XHRjb25zdCBsb2NhdGlvbiA9IGhlYWRlcnMuZ2V0KCdMb2NhdGlvbicpO1xuXG5cdFx0XHRcdC8vIEhUVFAgZmV0Y2ggc3RlcCA1LjNcblx0XHRcdFx0Y29uc3QgbG9jYXRpb25VUkwgPSBsb2NhdGlvbiA9PT0gbnVsbCA/IG51bGwgOiBuZXcgVVJMKGxvY2F0aW9uLCByZXF1ZXN0LnVybCk7XG5cblx0XHRcdFx0Ly8gSFRUUCBmZXRjaCBzdGVwIDUuNVxuXHRcdFx0XHRzd2l0Y2ggKHJlcXVlc3QucmVkaXJlY3QpIHtcblx0XHRcdFx0XHRjYXNlICdlcnJvcic6XG5cdFx0XHRcdFx0XHRyZWplY3QobmV3IEZldGNoRXJyb3IoYHVyaSByZXF1ZXN0ZWQgcmVzcG9uZHMgd2l0aCBhIHJlZGlyZWN0LCByZWRpcmVjdCBtb2RlIGlzIHNldCB0byBlcnJvcjogJHtyZXF1ZXN0LnVybH1gLCAnbm8tcmVkaXJlY3QnKSk7XG5cdFx0XHRcdFx0XHRmaW5hbGl6ZSgpO1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdGNhc2UgJ21hbnVhbCc6XG5cdFx0XHRcdFx0XHQvLyBOb2RlLWZldGNoLXNwZWNpZmljIHN0ZXA6IG1ha2UgbWFudWFsIHJlZGlyZWN0IGEgYml0IGVhc2llciB0byB1c2UgYnkgc2V0dGluZyB0aGUgTG9jYXRpb24gaGVhZGVyIHZhbHVlIHRvIHRoZSByZXNvbHZlZCBVUkwuXG5cdFx0XHRcdFx0XHRpZiAobG9jYXRpb25VUkwgIT09IG51bGwpIHtcblx0XHRcdFx0XHRcdFx0Ly8gSGFuZGxlIGNvcnJ1cHRlZCBoZWFkZXJcblx0XHRcdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdFx0XHRoZWFkZXJzLnNldCgnTG9jYXRpb24nLCBsb2NhdGlvblVSTCk7XG5cdFx0XHRcdFx0XHRcdFx0LyogYzggaWdub3JlIG5leHQgMyAqL1xuXHRcdFx0XHRcdFx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0XHRcdFx0XHRcdHJlamVjdChlcnJvcik7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnZm9sbG93Jzoge1xuXHRcdFx0XHRcdFx0Ly8gSFRUUC1yZWRpcmVjdCBmZXRjaCBzdGVwIDJcblx0XHRcdFx0XHRcdGlmIChsb2NhdGlvblVSTCA9PT0gbnVsbCkge1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Ly8gSFRUUC1yZWRpcmVjdCBmZXRjaCBzdGVwIDVcblx0XHRcdFx0XHRcdGlmIChyZXF1ZXN0LmNvdW50ZXIgPj0gcmVxdWVzdC5mb2xsb3cpIHtcblx0XHRcdFx0XHRcdFx0cmVqZWN0KG5ldyBGZXRjaEVycm9yKGBtYXhpbXVtIHJlZGlyZWN0IHJlYWNoZWQgYXQ6ICR7cmVxdWVzdC51cmx9YCwgJ21heC1yZWRpcmVjdCcpKTtcblx0XHRcdFx0XHRcdFx0ZmluYWxpemUoKTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBIVFRQLXJlZGlyZWN0IGZldGNoIHN0ZXAgNiAoY291bnRlciBpbmNyZW1lbnQpXG5cdFx0XHRcdFx0XHQvLyBDcmVhdGUgYSBuZXcgUmVxdWVzdCBvYmplY3QuXG5cdFx0XHRcdFx0XHRjb25zdCByZXF1ZXN0T3B0aW9ucyA9IHtcblx0XHRcdFx0XHRcdFx0aGVhZGVyczogbmV3IEhlYWRlcnMocmVxdWVzdC5oZWFkZXJzKSxcblx0XHRcdFx0XHRcdFx0Zm9sbG93OiByZXF1ZXN0LmZvbGxvdyxcblx0XHRcdFx0XHRcdFx0Y291bnRlcjogcmVxdWVzdC5jb3VudGVyICsgMSxcblx0XHRcdFx0XHRcdFx0YWdlbnQ6IHJlcXVlc3QuYWdlbnQsXG5cdFx0XHRcdFx0XHRcdGNvbXByZXNzOiByZXF1ZXN0LmNvbXByZXNzLFxuXHRcdFx0XHRcdFx0XHRtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuXHRcdFx0XHRcdFx0XHRib2R5OiByZXF1ZXN0LmJvZHksXG5cdFx0XHRcdFx0XHRcdHNpZ25hbDogcmVxdWVzdC5zaWduYWwsXG5cdFx0XHRcdFx0XHRcdHNpemU6IHJlcXVlc3Quc2l6ZVxuXHRcdFx0XHRcdFx0fTtcblxuXHRcdFx0XHRcdFx0Ly8gSFRUUC1yZWRpcmVjdCBmZXRjaCBzdGVwIDlcblx0XHRcdFx0XHRcdGlmIChyZXNwb25zZV8uc3RhdHVzQ29kZSAhPT0gMzAzICYmIHJlcXVlc3QuYm9keSAmJiBvcHRpb25zXy5ib2R5IGluc3RhbmNlb2YgU3RyZWFtLlJlYWRhYmxlKSB7XG5cdFx0XHRcdFx0XHRcdHJlamVjdChuZXcgRmV0Y2hFcnJvcignQ2Fubm90IGZvbGxvdyByZWRpcmVjdCB3aXRoIGJvZHkgYmVpbmcgYSByZWFkYWJsZSBzdHJlYW0nLCAndW5zdXBwb3J0ZWQtcmVkaXJlY3QnKSk7XG5cdFx0XHRcdFx0XHRcdGZpbmFsaXplKCk7XG5cdFx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Ly8gSFRUUC1yZWRpcmVjdCBmZXRjaCBzdGVwIDExXG5cdFx0XHRcdFx0XHRpZiAocmVzcG9uc2VfLnN0YXR1c0NvZGUgPT09IDMwMyB8fCAoKHJlc3BvbnNlXy5zdGF0dXNDb2RlID09PSAzMDEgfHwgcmVzcG9uc2VfLnN0YXR1c0NvZGUgPT09IDMwMikgJiYgcmVxdWVzdC5tZXRob2QgPT09ICdQT1NUJykpIHtcblx0XHRcdFx0XHRcdFx0cmVxdWVzdE9wdGlvbnMubWV0aG9kID0gJ0dFVCc7XG5cdFx0XHRcdFx0XHRcdHJlcXVlc3RPcHRpb25zLmJvZHkgPSB1bmRlZmluZWQ7XG5cdFx0XHRcdFx0XHRcdHJlcXVlc3RPcHRpb25zLmhlYWRlcnMuZGVsZXRlKCdjb250ZW50LWxlbmd0aCcpO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBIVFRQLXJlZGlyZWN0IGZldGNoIHN0ZXAgMTVcblx0XHRcdFx0XHRcdHJlc29sdmUoZmV0Y2gobmV3IFJlcXVlc3QobG9jYXRpb25VUkwsIHJlcXVlc3RPcHRpb25zKSkpO1xuXHRcdFx0XHRcdFx0ZmluYWxpemUoKTtcblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Ly8gRG8gbm90aGluZ1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFByZXBhcmUgcmVzcG9uc2Vcblx0XHRcdHJlc3BvbnNlXy5vbmNlKCdlbmQnLCAoKSA9PiB7XG5cdFx0XHRcdGlmIChzaWduYWwpIHtcblx0XHRcdFx0XHRzaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBhYm9ydEFuZEZpbmFsaXplKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdGxldCBib2R5ID0gU3RyZWFtLnBpcGVsaW5lKHJlc3BvbnNlXywgbmV3IFN0cmVhbS5QYXNzVGhyb3VnaCgpLCBlcnJvciA9PiB7XG5cdFx0XHRcdHJlamVjdChlcnJvcik7XG5cdFx0XHR9KTtcblx0XHRcdC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vbm9kZWpzL25vZGUvcHVsbC8yOTM3NlxuXHRcdFx0aWYgKHByb2Nlc3MudmVyc2lvbiA8ICd2MTIuMTAnKSB7XG5cdFx0XHRcdHJlc3BvbnNlXy5vbignYWJvcnRlZCcsIGFib3J0QW5kRmluYWxpemUpO1xuXHRcdFx0fVxuXG5cdFx0XHRjb25zdCByZXNwb25zZU9wdGlvbnMgPSB7XG5cdFx0XHRcdHVybDogcmVxdWVzdC51cmwsXG5cdFx0XHRcdHN0YXR1czogcmVzcG9uc2VfLnN0YXR1c0NvZGUsXG5cdFx0XHRcdHN0YXR1c1RleHQ6IHJlc3BvbnNlXy5zdGF0dXNNZXNzYWdlLFxuXHRcdFx0XHRoZWFkZXJzLFxuXHRcdFx0XHRzaXplOiByZXF1ZXN0LnNpemUsXG5cdFx0XHRcdGNvdW50ZXI6IHJlcXVlc3QuY291bnRlcixcblx0XHRcdFx0aGlnaFdhdGVyTWFyazogcmVxdWVzdC5oaWdoV2F0ZXJNYXJrXG5cdFx0XHR9O1xuXG5cdFx0XHQvLyBIVFRQLW5ldHdvcmsgZmV0Y2ggc3RlcCAxMi4xLjEuM1xuXHRcdFx0Y29uc3QgY29kaW5ncyA9IGhlYWRlcnMuZ2V0KCdDb250ZW50LUVuY29kaW5nJyk7XG5cblx0XHRcdC8vIEhUVFAtbmV0d29yayBmZXRjaCBzdGVwIDEyLjEuMS40OiBoYW5kbGUgY29udGVudCBjb2RpbmdzXG5cblx0XHRcdC8vIGluIGZvbGxvd2luZyBzY2VuYXJpb3Mgd2UgaWdub3JlIGNvbXByZXNzaW9uIHN1cHBvcnRcblx0XHRcdC8vIDEuIGNvbXByZXNzaW9uIHN1cHBvcnQgaXMgZGlzYWJsZWRcblx0XHRcdC8vIDIuIEhFQUQgcmVxdWVzdFxuXHRcdFx0Ly8gMy4gbm8gQ29udGVudC1FbmNvZGluZyBoZWFkZXJcblx0XHRcdC8vIDQuIG5vIGNvbnRlbnQgcmVzcG9uc2UgKDIwNClcblx0XHRcdC8vIDUuIGNvbnRlbnQgbm90IG1vZGlmaWVkIHJlc3BvbnNlICgzMDQpXG5cdFx0XHRpZiAoIXJlcXVlc3QuY29tcHJlc3MgfHwgcmVxdWVzdC5tZXRob2QgPT09ICdIRUFEJyB8fCBjb2RpbmdzID09PSBudWxsIHx8IHJlc3BvbnNlXy5zdGF0dXNDb2RlID09PSAyMDQgfHwgcmVzcG9uc2VfLnN0YXR1c0NvZGUgPT09IDMwNCkge1xuXHRcdFx0XHRyZXNwb25zZSA9IG5ldyBSZXNwb25zZShib2R5LCByZXNwb25zZU9wdGlvbnMpO1xuXHRcdFx0XHRyZXNvbHZlKHJlc3BvbnNlKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBGb3IgTm9kZSB2Nitcblx0XHRcdC8vIEJlIGxlc3Mgc3RyaWN0IHdoZW4gZGVjb2RpbmcgY29tcHJlc3NlZCByZXNwb25zZXMsIHNpbmNlIHNvbWV0aW1lc1xuXHRcdFx0Ly8gc2VydmVycyBzZW5kIHNsaWdodGx5IGludmFsaWQgcmVzcG9uc2VzIHRoYXQgYXJlIHN0aWxsIGFjY2VwdGVkXG5cdFx0XHQvLyBieSBjb21tb24gYnJvd3NlcnMuXG5cdFx0XHQvLyBBbHdheXMgdXNpbmcgWl9TWU5DX0ZMVVNIIGlzIHdoYXQgY1VSTCBkb2VzLlxuXHRcdFx0Y29uc3QgemxpYk9wdGlvbnMgPSB7XG5cdFx0XHRcdGZsdXNoOiB6bGliLlpfU1lOQ19GTFVTSCxcblx0XHRcdFx0ZmluaXNoRmx1c2g6IHpsaWIuWl9TWU5DX0ZMVVNIXG5cdFx0XHR9O1xuXG5cdFx0XHQvLyBGb3IgZ3ppcFxuXHRcdFx0aWYgKGNvZGluZ3MgPT09ICdnemlwJyB8fCBjb2RpbmdzID09PSAneC1nemlwJykge1xuXHRcdFx0XHRib2R5ID0gU3RyZWFtLnBpcGVsaW5lKGJvZHksIHpsaWIuY3JlYXRlR3VuemlwKHpsaWJPcHRpb25zKSwgZXJyb3IgPT4ge1xuXHRcdFx0XHRcdHJlamVjdChlcnJvcik7XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRyZXNwb25zZSA9IG5ldyBSZXNwb25zZShib2R5LCByZXNwb25zZU9wdGlvbnMpO1xuXHRcdFx0XHRyZXNvbHZlKHJlc3BvbnNlKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBGb3IgZGVmbGF0ZVxuXHRcdFx0aWYgKGNvZGluZ3MgPT09ICdkZWZsYXRlJyB8fCBjb2RpbmdzID09PSAneC1kZWZsYXRlJykge1xuXHRcdFx0XHQvLyBIYW5kbGUgdGhlIGluZmFtb3VzIHJhdyBkZWZsYXRlIHJlc3BvbnNlIGZyb20gb2xkIHNlcnZlcnNcblx0XHRcdFx0Ly8gYSBoYWNrIGZvciBvbGQgSUlTIGFuZCBBcGFjaGUgc2VydmVyc1xuXHRcdFx0XHRjb25zdCByYXcgPSBTdHJlYW0ucGlwZWxpbmUocmVzcG9uc2VfLCBuZXcgU3RyZWFtLlBhc3NUaHJvdWdoKCksIGVycm9yID0+IHtcblx0XHRcdFx0XHRyZWplY3QoZXJyb3IpO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0cmF3Lm9uY2UoJ2RhdGEnLCBjaHVuayA9PiB7XG5cdFx0XHRcdFx0Ly8gU2VlIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzc1MTk4Mjhcblx0XHRcdFx0XHRpZiAoKGNodW5rWzBdICYgMHgwRikgPT09IDB4MDgpIHtcblx0XHRcdFx0XHRcdGJvZHkgPSBTdHJlYW0ucGlwZWxpbmUoYm9keSwgemxpYi5jcmVhdGVJbmZsYXRlKCksIGVycm9yID0+IHtcblx0XHRcdFx0XHRcdFx0cmVqZWN0KGVycm9yKTtcblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRib2R5ID0gU3RyZWFtLnBpcGVsaW5lKGJvZHksIHpsaWIuY3JlYXRlSW5mbGF0ZVJhdygpLCBlcnJvciA9PiB7XG5cdFx0XHRcdFx0XHRcdHJlamVjdChlcnJvcik7XG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXNwb25zZSA9IG5ldyBSZXNwb25zZShib2R5LCByZXNwb25zZU9wdGlvbnMpO1xuXHRcdFx0XHRcdHJlc29sdmUocmVzcG9uc2UpO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBGb3IgYnJcblx0XHRcdGlmIChjb2RpbmdzID09PSAnYnInKSB7XG5cdFx0XHRcdGJvZHkgPSBTdHJlYW0ucGlwZWxpbmUoYm9keSwgemxpYi5jcmVhdGVCcm90bGlEZWNvbXByZXNzKCksIGVycm9yID0+IHtcblx0XHRcdFx0XHRyZWplY3QoZXJyb3IpO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0cmVzcG9uc2UgPSBuZXcgUmVzcG9uc2UoYm9keSwgcmVzcG9uc2VPcHRpb25zKTtcblx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZSk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gT3RoZXJ3aXNlLCB1c2UgcmVzcG9uc2UgYXMtaXNcblx0XHRcdHJlc3BvbnNlID0gbmV3IFJlc3BvbnNlKGJvZHksIHJlc3BvbnNlT3B0aW9ucyk7XG5cdFx0XHRyZXNvbHZlKHJlc3BvbnNlKTtcblx0XHR9KTtcblxuXHRcdHdyaXRlVG9TdHJlYW0ocmVxdWVzdF8sIHJlcXVlc3QpO1xuXHR9KTtcbn1cblxuZXhwb3J0cy5BYm9ydEVycm9yID0gQWJvcnRFcnJvcjtcbmV4cG9ydHMuRmV0Y2hFcnJvciA9IEZldGNoRXJyb3I7XG5leHBvcnRzLkhlYWRlcnMgPSBIZWFkZXJzO1xuZXhwb3J0cy5SZXF1ZXN0ID0gUmVxdWVzdDtcbmV4cG9ydHMuUmVzcG9uc2UgPSBSZXNwb25zZTtcbmV4cG9ydHMuZGVmYXVsdCA9IGZldGNoO1xuZXhwb3J0cy5pc1JlZGlyZWN0ID0gaXNSZWRpcmVjdDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmNqcy5tYXBcbiIsIi8qKlxuICogd2ViLXN0cmVhbXMtcG9seWZpbGwgdjMuMS4xXG4gKi9cbi8vLyA8cmVmZXJlbmNlIGxpYj1cImVzMjAxNS5zeW1ib2xcIiAvPlxuY29uc3QgU3ltYm9sUG9seWZpbGwgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnID9cbiAgICBTeW1ib2wgOlxuICAgIGRlc2NyaXB0aW9uID0+IGBTeW1ib2woJHtkZXNjcmlwdGlvbn0pYDtcblxuLy8vIDxyZWZlcmVuY2UgbGliPVwiZG9tXCIgLz5cbmZ1bmN0aW9uIG5vb3AoKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIGdldEdsb2JhbHMoKSB7XG4gICAgaWYgKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gc2VsZjtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdztcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIGdsb2JhbDtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cbmNvbnN0IGdsb2JhbHMgPSBnZXRHbG9iYWxzKCk7XG5cbmZ1bmN0aW9uIHR5cGVJc09iamVjdCh4KSB7XG4gICAgcmV0dXJuICh0eXBlb2YgeCA9PT0gJ29iamVjdCcgJiYgeCAhPT0gbnVsbCkgfHwgdHlwZW9mIHggPT09ICdmdW5jdGlvbic7XG59XG5jb25zdCByZXRocm93QXNzZXJ0aW9uRXJyb3JSZWplY3Rpb24gPSBub29wO1xuXG5jb25zdCBvcmlnaW5hbFByb21pc2UgPSBQcm9taXNlO1xuY29uc3Qgb3JpZ2luYWxQcm9taXNlVGhlbiA9IFByb21pc2UucHJvdG90eXBlLnRoZW47XG5jb25zdCBvcmlnaW5hbFByb21pc2VSZXNvbHZlID0gUHJvbWlzZS5yZXNvbHZlLmJpbmQob3JpZ2luYWxQcm9taXNlKTtcbmNvbnN0IG9yaWdpbmFsUHJvbWlzZVJlamVjdCA9IFByb21pc2UucmVqZWN0LmJpbmQob3JpZ2luYWxQcm9taXNlKTtcbmZ1bmN0aW9uIG5ld1Byb21pc2UoZXhlY3V0b3IpIHtcbiAgICByZXR1cm4gbmV3IG9yaWdpbmFsUHJvbWlzZShleGVjdXRvcik7XG59XG5mdW5jdGlvbiBwcm9taXNlUmVzb2x2ZWRXaXRoKHZhbHVlKSB7XG4gICAgcmV0dXJuIG9yaWdpbmFsUHJvbWlzZVJlc29sdmUodmFsdWUpO1xufVxuZnVuY3Rpb24gcHJvbWlzZVJlamVjdGVkV2l0aChyZWFzb24pIHtcbiAgICByZXR1cm4gb3JpZ2luYWxQcm9taXNlUmVqZWN0KHJlYXNvbik7XG59XG5mdW5jdGlvbiBQZXJmb3JtUHJvbWlzZVRoZW4ocHJvbWlzZSwgb25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpIHtcbiAgICAvLyBUaGVyZSBkb2Vzbid0IGFwcGVhciB0byBiZSBhbnkgd2F5IHRvIGNvcnJlY3RseSBlbXVsYXRlIHRoZSBiZWhhdmlvdXIgZnJvbSBKYXZhU2NyaXB0LCBzbyB0aGlzIGlzIGp1c3QgYW5cbiAgICAvLyBhcHByb3hpbWF0aW9uLlxuICAgIHJldHVybiBvcmlnaW5hbFByb21pc2VUaGVuLmNhbGwocHJvbWlzZSwgb25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpO1xufVxuZnVuY3Rpb24gdXBvblByb21pc2UocHJvbWlzZSwgb25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpIHtcbiAgICBQZXJmb3JtUHJvbWlzZVRoZW4oUGVyZm9ybVByb21pc2VUaGVuKHByb21pc2UsIG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKSwgdW5kZWZpbmVkLCByZXRocm93QXNzZXJ0aW9uRXJyb3JSZWplY3Rpb24pO1xufVxuZnVuY3Rpb24gdXBvbkZ1bGZpbGxtZW50KHByb21pc2UsIG9uRnVsZmlsbGVkKSB7XG4gICAgdXBvblByb21pc2UocHJvbWlzZSwgb25GdWxmaWxsZWQpO1xufVxuZnVuY3Rpb24gdXBvblJlamVjdGlvbihwcm9taXNlLCBvblJlamVjdGVkKSB7XG4gICAgdXBvblByb21pc2UocHJvbWlzZSwgdW5kZWZpbmVkLCBvblJlamVjdGVkKTtcbn1cbmZ1bmN0aW9uIHRyYW5zZm9ybVByb21pc2VXaXRoKHByb21pc2UsIGZ1bGZpbGxtZW50SGFuZGxlciwgcmVqZWN0aW9uSGFuZGxlcikge1xuICAgIHJldHVybiBQZXJmb3JtUHJvbWlzZVRoZW4ocHJvbWlzZSwgZnVsZmlsbG1lbnRIYW5kbGVyLCByZWplY3Rpb25IYW5kbGVyKTtcbn1cbmZ1bmN0aW9uIHNldFByb21pc2VJc0hhbmRsZWRUb1RydWUocHJvbWlzZSkge1xuICAgIFBlcmZvcm1Qcm9taXNlVGhlbihwcm9taXNlLCB1bmRlZmluZWQsIHJldGhyb3dBc3NlcnRpb25FcnJvclJlamVjdGlvbik7XG59XG5jb25zdCBxdWV1ZU1pY3JvdGFzayA9ICgoKSA9PiB7XG4gICAgY29uc3QgZ2xvYmFsUXVldWVNaWNyb3Rhc2sgPSBnbG9iYWxzICYmIGdsb2JhbHMucXVldWVNaWNyb3Rhc2s7XG4gICAgaWYgKHR5cGVvZiBnbG9iYWxRdWV1ZU1pY3JvdGFzayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gZ2xvYmFsUXVldWVNaWNyb3Rhc2s7XG4gICAgfVxuICAgIGNvbnN0IHJlc29sdmVkUHJvbWlzZSA9IHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICByZXR1cm4gKGZuKSA9PiBQZXJmb3JtUHJvbWlzZVRoZW4ocmVzb2x2ZWRQcm9taXNlLCBmbik7XG59KSgpO1xuZnVuY3Rpb24gcmVmbGVjdENhbGwoRiwgViwgYXJncykge1xuICAgIGlmICh0eXBlb2YgRiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBpcyBub3QgYSBmdW5jdGlvbicpO1xuICAgIH1cbiAgICByZXR1cm4gRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5LmNhbGwoRiwgViwgYXJncyk7XG59XG5mdW5jdGlvbiBwcm9taXNlQ2FsbChGLCBWLCBhcmdzKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgocmVmbGVjdENhbGwoRiwgViwgYXJncykpO1xuICAgIH1cbiAgICBjYXRjaCAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgodmFsdWUpO1xuICAgIH1cbn1cblxuLy8gT3JpZ2luYWwgZnJvbSBDaHJvbWl1bVxuLy8gaHR0cHM6Ly9jaHJvbWl1bS5nb29nbGVzb3VyY2UuY29tL2Nocm9taXVtL3NyYy8rLzBhZWU0NDM0YTRkYmE0MmE0MmFiYWVhOWJmYmMwY2QxOTZhNjNiYzEvdGhpcmRfcGFydHkvYmxpbmsvcmVuZGVyZXIvY29yZS9zdHJlYW1zL1NpbXBsZVF1ZXVlLmpzXG5jb25zdCBRVUVVRV9NQVhfQVJSQVlfU0laRSA9IDE2Mzg0O1xuLyoqXG4gKiBTaW1wbGUgcXVldWUgc3RydWN0dXJlLlxuICpcbiAqIEF2b2lkcyBzY2FsYWJpbGl0eSBpc3N1ZXMgd2l0aCB1c2luZyBhIHBhY2tlZCBhcnJheSBkaXJlY3RseSBieSB1c2luZ1xuICogbXVsdGlwbGUgYXJyYXlzIGluIGEgbGlua2VkIGxpc3QgYW5kIGtlZXBpbmcgdGhlIGFycmF5IHNpemUgYm91bmRlZC5cbiAqL1xuY2xhc3MgU2ltcGxlUXVldWUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLl9jdXJzb3IgPSAwO1xuICAgICAgICB0aGlzLl9zaXplID0gMDtcbiAgICAgICAgLy8gX2Zyb250IGFuZCBfYmFjayBhcmUgYWx3YXlzIGRlZmluZWQuXG4gICAgICAgIHRoaXMuX2Zyb250ID0ge1xuICAgICAgICAgICAgX2VsZW1lbnRzOiBbXSxcbiAgICAgICAgICAgIF9uZXh0OiB1bmRlZmluZWRcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5fYmFjayA9IHRoaXMuX2Zyb250O1xuICAgICAgICAvLyBUaGUgY3Vyc29yIGlzIHVzZWQgdG8gYXZvaWQgY2FsbGluZyBBcnJheS5zaGlmdCgpLlxuICAgICAgICAvLyBJdCBjb250YWlucyB0aGUgaW5kZXggb2YgdGhlIGZyb250IGVsZW1lbnQgb2YgdGhlIGFycmF5IGluc2lkZSB0aGVcbiAgICAgICAgLy8gZnJvbnQtbW9zdCBub2RlLiBJdCBpcyBhbHdheXMgaW4gdGhlIHJhbmdlIFswLCBRVUVVRV9NQVhfQVJSQVlfU0laRSkuXG4gICAgICAgIHRoaXMuX2N1cnNvciA9IDA7XG4gICAgICAgIC8vIFdoZW4gdGhlcmUgaXMgb25seSBvbmUgbm9kZSwgc2l6ZSA9PT0gZWxlbWVudHMubGVuZ3RoIC0gY3Vyc29yLlxuICAgICAgICB0aGlzLl9zaXplID0gMDtcbiAgICB9XG4gICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpemU7XG4gICAgfVxuICAgIC8vIEZvciBleGNlcHRpb24gc2FmZXR5LCB0aGlzIG1ldGhvZCBpcyBzdHJ1Y3R1cmVkIGluIG9yZGVyOlxuICAgIC8vIDEuIFJlYWQgc3RhdGVcbiAgICAvLyAyLiBDYWxjdWxhdGUgcmVxdWlyZWQgc3RhdGUgbXV0YXRpb25zXG4gICAgLy8gMy4gUGVyZm9ybSBzdGF0ZSBtdXRhdGlvbnNcbiAgICBwdXNoKGVsZW1lbnQpIHtcbiAgICAgICAgY29uc3Qgb2xkQmFjayA9IHRoaXMuX2JhY2s7XG4gICAgICAgIGxldCBuZXdCYWNrID0gb2xkQmFjaztcbiAgICAgICAgaWYgKG9sZEJhY2suX2VsZW1lbnRzLmxlbmd0aCA9PT0gUVVFVUVfTUFYX0FSUkFZX1NJWkUgLSAxKSB7XG4gICAgICAgICAgICBuZXdCYWNrID0ge1xuICAgICAgICAgICAgICAgIF9lbGVtZW50czogW10sXG4gICAgICAgICAgICAgICAgX25leHQ6IHVuZGVmaW5lZFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICAvLyBwdXNoKCkgaXMgdGhlIG11dGF0aW9uIG1vc3QgbGlrZWx5IHRvIHRocm93IGFuIGV4Y2VwdGlvbiwgc28gaXRcbiAgICAgICAgLy8gZ29lcyBmaXJzdC5cbiAgICAgICAgb2xkQmFjay5fZWxlbWVudHMucHVzaChlbGVtZW50KTtcbiAgICAgICAgaWYgKG5ld0JhY2sgIT09IG9sZEJhY2spIHtcbiAgICAgICAgICAgIHRoaXMuX2JhY2sgPSBuZXdCYWNrO1xuICAgICAgICAgICAgb2xkQmFjay5fbmV4dCA9IG5ld0JhY2s7XG4gICAgICAgIH1cbiAgICAgICAgKyt0aGlzLl9zaXplO1xuICAgIH1cbiAgICAvLyBMaWtlIHB1c2goKSwgc2hpZnQoKSBmb2xsb3dzIHRoZSByZWFkIC0+IGNhbGN1bGF0ZSAtPiBtdXRhdGUgcGF0dGVybiBmb3JcbiAgICAvLyBleGNlcHRpb24gc2FmZXR5LlxuICAgIHNoaWZ0KCkgeyAvLyBtdXN0IG5vdCBiZSBjYWxsZWQgb24gYW4gZW1wdHkgcXVldWVcbiAgICAgICAgY29uc3Qgb2xkRnJvbnQgPSB0aGlzLl9mcm9udDtcbiAgICAgICAgbGV0IG5ld0Zyb250ID0gb2xkRnJvbnQ7XG4gICAgICAgIGNvbnN0IG9sZEN1cnNvciA9IHRoaXMuX2N1cnNvcjtcbiAgICAgICAgbGV0IG5ld0N1cnNvciA9IG9sZEN1cnNvciArIDE7XG4gICAgICAgIGNvbnN0IGVsZW1lbnRzID0gb2xkRnJvbnQuX2VsZW1lbnRzO1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gZWxlbWVudHNbb2xkQ3Vyc29yXTtcbiAgICAgICAgaWYgKG5ld0N1cnNvciA9PT0gUVVFVUVfTUFYX0FSUkFZX1NJWkUpIHtcbiAgICAgICAgICAgIG5ld0Zyb250ID0gb2xkRnJvbnQuX25leHQ7XG4gICAgICAgICAgICBuZXdDdXJzb3IgPSAwO1xuICAgICAgICB9XG4gICAgICAgIC8vIE5vIG11dGF0aW9ucyBiZWZvcmUgdGhpcyBwb2ludC5cbiAgICAgICAgLS10aGlzLl9zaXplO1xuICAgICAgICB0aGlzLl9jdXJzb3IgPSBuZXdDdXJzb3I7XG4gICAgICAgIGlmIChvbGRGcm9udCAhPT0gbmV3RnJvbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX2Zyb250ID0gbmV3RnJvbnQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUGVybWl0IHNoaWZ0ZWQgZWxlbWVudCB0byBiZSBnYXJiYWdlIGNvbGxlY3RlZC5cbiAgICAgICAgZWxlbWVudHNbb2xkQ3Vyc29yXSA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuICAgIC8vIFRoZSB0cmlja3kgdGhpbmcgYWJvdXQgZm9yRWFjaCgpIGlzIHRoYXQgaXQgY2FuIGJlIGNhbGxlZFxuICAgIC8vIHJlLWVudHJhbnRseS4gVGhlIHF1ZXVlIG1heSBiZSBtdXRhdGVkIGluc2lkZSB0aGUgY2FsbGJhY2suIEl0IGlzIGVhc3kgdG9cbiAgICAvLyBzZWUgdGhhdCBwdXNoKCkgd2l0aGluIHRoZSBjYWxsYmFjayBoYXMgbm8gbmVnYXRpdmUgZWZmZWN0cyBzaW5jZSB0aGUgZW5kXG4gICAgLy8gb2YgdGhlIHF1ZXVlIGlzIGNoZWNrZWQgZm9yIG9uIGV2ZXJ5IGl0ZXJhdGlvbi4gSWYgc2hpZnQoKSBpcyBjYWxsZWRcbiAgICAvLyByZXBlYXRlZGx5IHdpdGhpbiB0aGUgY2FsbGJhY2sgdGhlbiB0aGUgbmV4dCBpdGVyYXRpb24gbWF5IHJldHVybiBhblxuICAgIC8vIGVsZW1lbnQgdGhhdCBoYXMgYmVlbiByZW1vdmVkLiBJbiB0aGlzIGNhc2UgdGhlIGNhbGxiYWNrIHdpbGwgYmUgY2FsbGVkXG4gICAgLy8gd2l0aCB1bmRlZmluZWQgdmFsdWVzIHVudGlsIHdlIGVpdGhlciBcImNhdGNoIHVwXCIgd2l0aCBlbGVtZW50cyB0aGF0IHN0aWxsXG4gICAgLy8gZXhpc3Qgb3IgcmVhY2ggdGhlIGJhY2sgb2YgdGhlIHF1ZXVlLlxuICAgIGZvckVhY2goY2FsbGJhY2spIHtcbiAgICAgICAgbGV0IGkgPSB0aGlzLl9jdXJzb3I7XG4gICAgICAgIGxldCBub2RlID0gdGhpcy5fZnJvbnQ7XG4gICAgICAgIGxldCBlbGVtZW50cyA9IG5vZGUuX2VsZW1lbnRzO1xuICAgICAgICB3aGlsZSAoaSAhPT0gZWxlbWVudHMubGVuZ3RoIHx8IG5vZGUuX25leHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgaWYgKGkgPT09IGVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLl9uZXh0O1xuICAgICAgICAgICAgICAgIGVsZW1lbnRzID0gbm9kZS5fZWxlbWVudHM7XG4gICAgICAgICAgICAgICAgaSA9IDA7XG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYWxsYmFjayhlbGVtZW50c1tpXSk7XG4gICAgICAgICAgICArK2k7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gUmV0dXJuIHRoZSBlbGVtZW50IHRoYXQgd291bGQgYmUgcmV0dXJuZWQgaWYgc2hpZnQoKSB3YXMgY2FsbGVkIG5vdyxcbiAgICAvLyB3aXRob3V0IG1vZGlmeWluZyB0aGUgcXVldWUuXG4gICAgcGVlaygpIHsgLy8gbXVzdCBub3QgYmUgY2FsbGVkIG9uIGFuIGVtcHR5IHF1ZXVlXG4gICAgICAgIGNvbnN0IGZyb250ID0gdGhpcy5fZnJvbnQ7XG4gICAgICAgIGNvbnN0IGN1cnNvciA9IHRoaXMuX2N1cnNvcjtcbiAgICAgICAgcmV0dXJuIGZyb250Ll9lbGVtZW50c1tjdXJzb3JdO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljSW5pdGlhbGl6ZShyZWFkZXIsIHN0cmVhbSkge1xuICAgIHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbSA9IHN0cmVhbTtcbiAgICBzdHJlYW0uX3JlYWRlciA9IHJlYWRlcjtcbiAgICBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ3JlYWRhYmxlJykge1xuICAgICAgICBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemUocmVhZGVyKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZXNvbHZlZChyZWFkZXIpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZChyZWFkZXIsIHN0cmVhbS5fc3RvcmVkRXJyb3IpO1xuICAgIH1cbn1cbi8vIEEgY2xpZW50IG9mIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlciBhbmQgUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyIG1heSB1c2UgdGhlc2UgZnVuY3Rpb25zIGRpcmVjdGx5IHRvIGJ5cGFzcyBzdGF0ZVxuLy8gY2hlY2suXG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNDYW5jZWwocmVhZGVyLCByZWFzb24pIHtcbiAgICBjb25zdCBzdHJlYW0gPSByZWFkZXIuX293bmVyUmVhZGFibGVTdHJlYW07XG4gICAgcmV0dXJuIFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHN0cmVhbSwgcmVhc29uKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY1JlbGVhc2UocmVhZGVyKSB7XG4gICAgaWYgKHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbS5fc3RhdGUgPT09ICdyZWFkYWJsZScpIHtcbiAgICAgICAgZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZWplY3QocmVhZGVyLCBuZXcgVHlwZUVycm9yKGBSZWFkZXIgd2FzIHJlbGVhc2VkIGFuZCBjYW4gbm8gbG9uZ2VyIGJlIHVzZWQgdG8gbW9uaXRvciB0aGUgc3RyZWFtJ3MgY2xvc2VkbmVzc2ApKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlUmVzZXRUb1JlamVjdGVkKHJlYWRlciwgbmV3IFR5cGVFcnJvcihgUmVhZGVyIHdhcyByZWxlYXNlZCBhbmQgY2FuIG5vIGxvbmdlciBiZSB1c2VkIHRvIG1vbml0b3IgdGhlIHN0cmVhbSdzIGNsb3NlZG5lc3NgKSk7XG4gICAgfVxuICAgIHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbS5fcmVhZGVyID0gdW5kZWZpbmVkO1xuICAgIHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbSA9IHVuZGVmaW5lZDtcbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSByZWFkZXJzLlxuZnVuY3Rpb24gcmVhZGVyTG9ja0V4Y2VwdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCAnICsgbmFtZSArICcgYSBzdHJlYW0gdXNpbmcgYSByZWxlYXNlZCByZWFkZXInKTtcbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIuXG5mdW5jdGlvbiBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemUocmVhZGVyKSB7XG4gICAgcmVhZGVyLl9jbG9zZWRQcm9taXNlID0gbmV3UHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIHJlYWRlci5fY2xvc2VkUHJvbWlzZV9yZXNvbHZlID0gcmVzb2x2ZTtcbiAgICAgICAgcmVhZGVyLl9jbG9zZWRQcm9taXNlX3JlamVjdCA9IHJlamVjdDtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZUFzUmVqZWN0ZWQocmVhZGVyLCByZWFzb24pIHtcbiAgICBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemUocmVhZGVyKTtcbiAgICBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZVJlamVjdChyZWFkZXIsIHJlYXNvbik7XG59XG5mdW5jdGlvbiBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemVBc1Jlc29sdmVkKHJlYWRlcikge1xuICAgIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZShyZWFkZXIpO1xuICAgIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlUmVzb2x2ZShyZWFkZXIpO1xufVxuZnVuY3Rpb24gZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZWplY3QocmVhZGVyLCByZWFzb24pIHtcbiAgICBpZiAocmVhZGVyLl9jbG9zZWRQcm9taXNlX3JlamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgc2V0UHJvbWlzZUlzSGFuZGxlZFRvVHJ1ZShyZWFkZXIuX2Nsb3NlZFByb21pc2UpO1xuICAgIHJlYWRlci5fY2xvc2VkUHJvbWlzZV9yZWplY3QocmVhc29uKTtcbiAgICByZWFkZXIuX2Nsb3NlZFByb21pc2VfcmVzb2x2ZSA9IHVuZGVmaW5lZDtcbiAgICByZWFkZXIuX2Nsb3NlZFByb21pc2VfcmVqZWN0ID0gdW5kZWZpbmVkO1xufVxuZnVuY3Rpb24gZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZXNldFRvUmVqZWN0ZWQocmVhZGVyLCByZWFzb24pIHtcbiAgICBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemVBc1JlamVjdGVkKHJlYWRlciwgcmVhc29uKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlUmVzb2x2ZShyZWFkZXIpIHtcbiAgICBpZiAocmVhZGVyLl9jbG9zZWRQcm9taXNlX3Jlc29sdmUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHJlYWRlci5fY2xvc2VkUHJvbWlzZV9yZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgcmVhZGVyLl9jbG9zZWRQcm9taXNlX3Jlc29sdmUgPSB1bmRlZmluZWQ7XG4gICAgcmVhZGVyLl9jbG9zZWRQcm9taXNlX3JlamVjdCA9IHVuZGVmaW5lZDtcbn1cblxuY29uc3QgQWJvcnRTdGVwcyA9IFN5bWJvbFBvbHlmaWxsKCdbW0Fib3J0U3RlcHNdXScpO1xuY29uc3QgRXJyb3JTdGVwcyA9IFN5bWJvbFBvbHlmaWxsKCdbW0Vycm9yU3RlcHNdXScpO1xuY29uc3QgQ2FuY2VsU3RlcHMgPSBTeW1ib2xQb2x5ZmlsbCgnW1tDYW5jZWxTdGVwc11dJyk7XG5jb25zdCBQdWxsU3RlcHMgPSBTeW1ib2xQb2x5ZmlsbCgnW1tQdWxsU3RlcHNdXScpO1xuXG4vLy8gPHJlZmVyZW5jZSBsaWI9XCJlczIwMTUuY29yZVwiIC8+XG4vLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9OdW1iZXIvaXNGaW5pdGUjUG9seWZpbGxcbmNvbnN0IE51bWJlcklzRmluaXRlID0gTnVtYmVyLmlzRmluaXRlIHx8IGZ1bmN0aW9uICh4KSB7XG4gICAgcmV0dXJuIHR5cGVvZiB4ID09PSAnbnVtYmVyJyAmJiBpc0Zpbml0ZSh4KTtcbn07XG5cbi8vLyA8cmVmZXJlbmNlIGxpYj1cImVzMjAxNS5jb3JlXCIgLz5cbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL01hdGgvdHJ1bmMjUG9seWZpbGxcbmNvbnN0IE1hdGhUcnVuYyA9IE1hdGgudHJ1bmMgfHwgZnVuY3Rpb24gKHYpIHtcbiAgICByZXR1cm4gdiA8IDAgPyBNYXRoLmNlaWwodikgOiBNYXRoLmZsb29yKHYpO1xufTtcblxuLy8gaHR0cHM6Ly9oZXljYW0uZ2l0aHViLmlvL3dlYmlkbC8jaWRsLWRpY3Rpb25hcmllc1xuZnVuY3Rpb24gaXNEaWN0aW9uYXJ5KHgpIHtcbiAgICByZXR1cm4gdHlwZW9mIHggPT09ICdvYmplY3QnIHx8IHR5cGVvZiB4ID09PSAnZnVuY3Rpb24nO1xufVxuZnVuY3Rpb24gYXNzZXJ0RGljdGlvbmFyeShvYmosIGNvbnRleHQpIHtcbiAgICBpZiAob2JqICE9PSB1bmRlZmluZWQgJiYgIWlzRGljdGlvbmFyeShvYmopKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y29udGV4dH0gaXMgbm90IGFuIG9iamVjdC5gKTtcbiAgICB9XG59XG4vLyBodHRwczovL2hleWNhbS5naXRodWIuaW8vd2ViaWRsLyNpZGwtY2FsbGJhY2stZnVuY3Rpb25zXG5mdW5jdGlvbiBhc3NlcnRGdW5jdGlvbih4LCBjb250ZXh0KSB7XG4gICAgaWYgKHR5cGVvZiB4ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y29udGV4dH0gaXMgbm90IGEgZnVuY3Rpb24uYCk7XG4gICAgfVxufVxuLy8gaHR0cHM6Ly9oZXljYW0uZ2l0aHViLmlvL3dlYmlkbC8jaWRsLW9iamVjdFxuZnVuY3Rpb24gaXNPYmplY3QoeCkge1xuICAgIHJldHVybiAodHlwZW9mIHggPT09ICdvYmplY3QnICYmIHggIT09IG51bGwpIHx8IHR5cGVvZiB4ID09PSAnZnVuY3Rpb24nO1xufVxuZnVuY3Rpb24gYXNzZXJ0T2JqZWN0KHgsIGNvbnRleHQpIHtcbiAgICBpZiAoIWlzT2JqZWN0KHgpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y29udGV4dH0gaXMgbm90IGFuIG9iamVjdC5gKTtcbiAgICB9XG59XG5mdW5jdGlvbiBhc3NlcnRSZXF1aXJlZEFyZ3VtZW50KHgsIHBvc2l0aW9uLCBjb250ZXh0KSB7XG4gICAgaWYgKHggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBQYXJhbWV0ZXIgJHtwb3NpdGlvbn0gaXMgcmVxdWlyZWQgaW4gJyR7Y29udGV4dH0nLmApO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGFzc2VydFJlcXVpcmVkRmllbGQoeCwgZmllbGQsIGNvbnRleHQpIHtcbiAgICBpZiAoeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7ZmllbGR9IGlzIHJlcXVpcmVkIGluICcke2NvbnRleHR9Jy5gKTtcbiAgICB9XG59XG4vLyBodHRwczovL2hleWNhbS5naXRodWIuaW8vd2ViaWRsLyNpZGwtdW5yZXN0cmljdGVkLWRvdWJsZVxuZnVuY3Rpb24gY29udmVydFVucmVzdHJpY3RlZERvdWJsZSh2YWx1ZSkge1xuICAgIHJldHVybiBOdW1iZXIodmFsdWUpO1xufVxuZnVuY3Rpb24gY2Vuc29yTmVnYXRpdmVaZXJvKHgpIHtcbiAgICByZXR1cm4geCA9PT0gMCA/IDAgOiB4O1xufVxuZnVuY3Rpb24gaW50ZWdlclBhcnQoeCkge1xuICAgIHJldHVybiBjZW5zb3JOZWdhdGl2ZVplcm8oTWF0aFRydW5jKHgpKTtcbn1cbi8vIGh0dHBzOi8vaGV5Y2FtLmdpdGh1Yi5pby93ZWJpZGwvI2lkbC11bnNpZ25lZC1sb25nLWxvbmdcbmZ1bmN0aW9uIGNvbnZlcnRVbnNpZ25lZExvbmdMb25nV2l0aEVuZm9yY2VSYW5nZSh2YWx1ZSwgY29udGV4dCkge1xuICAgIGNvbnN0IGxvd2VyQm91bmQgPSAwO1xuICAgIGNvbnN0IHVwcGVyQm91bmQgPSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUjtcbiAgICBsZXQgeCA9IE51bWJlcih2YWx1ZSk7XG4gICAgeCA9IGNlbnNvck5lZ2F0aXZlWmVybyh4KTtcbiAgICBpZiAoIU51bWJlcklzRmluaXRlKHgpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y29udGV4dH0gaXMgbm90IGEgZmluaXRlIG51bWJlcmApO1xuICAgIH1cbiAgICB4ID0gaW50ZWdlclBhcnQoeCk7XG4gICAgaWYgKHggPCBsb3dlckJvdW5kIHx8IHggPiB1cHBlckJvdW5kKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y29udGV4dH0gaXMgb3V0c2lkZSB0aGUgYWNjZXB0ZWQgcmFuZ2Ugb2YgJHtsb3dlckJvdW5kfSB0byAke3VwcGVyQm91bmR9LCBpbmNsdXNpdmVgKTtcbiAgICB9XG4gICAgaWYgKCFOdW1iZXJJc0Zpbml0ZSh4KSB8fCB4ID09PSAwKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICAvLyBUT0RPIFVzZSBCaWdJbnQgaWYgc3VwcG9ydGVkP1xuICAgIC8vIGxldCB4QmlnSW50ID0gQmlnSW50KGludGVnZXJQYXJ0KHgpKTtcbiAgICAvLyB4QmlnSW50ID0gQmlnSW50LmFzVWludE4oNjQsIHhCaWdJbnQpO1xuICAgIC8vIHJldHVybiBOdW1iZXIoeEJpZ0ludCk7XG4gICAgcmV0dXJuIHg7XG59XG5cbmZ1bmN0aW9uIGFzc2VydFJlYWRhYmxlU3RyZWFtKHgsIGNvbnRleHQpIHtcbiAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW0oeCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjb250ZXh0fSBpcyBub3QgYSBSZWFkYWJsZVN0cmVhbS5gKTtcbiAgICB9XG59XG5cbi8vIEFic3RyYWN0IG9wZXJhdGlvbnMgZm9yIHRoZSBSZWFkYWJsZVN0cmVhbS5cbmZ1bmN0aW9uIEFjcXVpcmVSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIoc3RyZWFtKSB7XG4gICAgcmV0dXJuIG5ldyBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIoc3RyZWFtKTtcbn1cbi8vIFJlYWRhYmxlU3RyZWFtIEFQSSBleHBvc2VkIGZvciBjb250cm9sbGVycy5cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtQWRkUmVhZFJlcXVlc3Qoc3RyZWFtLCByZWFkUmVxdWVzdCkge1xuICAgIHN0cmVhbS5fcmVhZGVyLl9yZWFkUmVxdWVzdHMucHVzaChyZWFkUmVxdWVzdCk7XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUZ1bGZpbGxSZWFkUmVxdWVzdChzdHJlYW0sIGNodW5rLCBkb25lKSB7XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLl9yZWFkZXI7XG4gICAgY29uc3QgcmVhZFJlcXVlc3QgPSByZWFkZXIuX3JlYWRSZXF1ZXN0cy5zaGlmdCgpO1xuICAgIGlmIChkb25lKSB7XG4gICAgICAgIHJlYWRSZXF1ZXN0Ll9jbG9zZVN0ZXBzKCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZWFkUmVxdWVzdC5fY2h1bmtTdGVwcyhjaHVuayk7XG4gICAgfVxufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1HZXROdW1SZWFkUmVxdWVzdHMoc3RyZWFtKSB7XG4gICAgcmV0dXJuIHN0cmVhbS5fcmVhZGVyLl9yZWFkUmVxdWVzdHMubGVuZ3RoO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1IYXNEZWZhdWx0UmVhZGVyKHN0cmVhbSkge1xuICAgIGNvbnN0IHJlYWRlciA9IHN0cmVhbS5fcmVhZGVyO1xuICAgIGlmIChyZWFkZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIocmVhZGVyKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuLyoqXG4gKiBBIGRlZmF1bHQgcmVhZGVyIHZlbmRlZCBieSBhIHtAbGluayBSZWFkYWJsZVN0cmVhbX0uXG4gKlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIge1xuICAgIGNvbnN0cnVjdG9yKHN0cmVhbSkge1xuICAgICAgICBhc3NlcnRSZXF1aXJlZEFyZ3VtZW50KHN0cmVhbSwgMSwgJ1JlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcicpO1xuICAgICAgICBhc3NlcnRSZWFkYWJsZVN0cmVhbShzdHJlYW0sICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgaWYgKElzUmVhZGFibGVTdHJlYW1Mb2NrZWQoc3RyZWFtKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhpcyBzdHJlYW0gaGFzIGFscmVhZHkgYmVlbiBsb2NrZWQgZm9yIGV4Y2x1c2l2ZSByZWFkaW5nIGJ5IGFub3RoZXIgcmVhZGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljSW5pdGlhbGl6ZSh0aGlzLCBzdHJlYW0pO1xuICAgICAgICB0aGlzLl9yZWFkUmVxdWVzdHMgPSBuZXcgU2ltcGxlUXVldWUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHByb21pc2UgdGhhdCB3aWxsIGJlIGZ1bGZpbGxlZCB3aGVuIHRoZSBzdHJlYW0gYmVjb21lcyBjbG9zZWQsXG4gICAgICogb3IgcmVqZWN0ZWQgaWYgdGhlIHN0cmVhbSBldmVyIGVycm9ycyBvciB0aGUgcmVhZGVyJ3MgbG9jayBpcyByZWxlYXNlZCBiZWZvcmUgdGhlIHN0cmVhbSBmaW5pc2hlcyBjbG9zaW5nLlxuICAgICAqL1xuICAgIGdldCBjbG9zZWQoKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGRlZmF1bHRSZWFkZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdjbG9zZWQnKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb3NlZFByb21pc2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSByZWFkZXIgaXMgYWN0aXZlLCBiZWhhdmVzIHRoZSBzYW1lIGFzIHtAbGluayBSZWFkYWJsZVN0cmVhbS5jYW5jZWwgfCBzdHJlYW0uY2FuY2VsKHJlYXNvbil9LlxuICAgICAqL1xuICAgIGNhbmNlbChyZWFzb24gPSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcih0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFJlYWRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2NhbmNlbCcpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fb3duZXJSZWFkYWJsZVN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChyZWFkZXJMb2NrRXhjZXB0aW9uKCdjYW5jZWwnKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY0NhbmNlbCh0aGlzLCByZWFzb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGFsbG93cyBhY2Nlc3MgdG8gdGhlIG5leHQgY2h1bmsgZnJvbSB0aGUgc3RyZWFtJ3MgaW50ZXJuYWwgcXVldWUsIGlmIGF2YWlsYWJsZS5cbiAgICAgKlxuICAgICAqIElmIHJlYWRpbmcgYSBjaHVuayBjYXVzZXMgdGhlIHF1ZXVlIHRvIGJlY29tZSBlbXB0eSwgbW9yZSBkYXRhIHdpbGwgYmUgcHVsbGVkIGZyb20gdGhlIHVuZGVybHlpbmcgc291cmNlLlxuICAgICAqL1xuICAgIHJlYWQoKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGRlZmF1bHRSZWFkZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdyZWFkJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9vd25lclJlYWRhYmxlU3RyZWFtID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHJlYWRlckxvY2tFeGNlcHRpb24oJ3JlYWQgZnJvbScpKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVzb2x2ZVByb21pc2U7XG4gICAgICAgIGxldCByZWplY3RQcm9taXNlO1xuICAgICAgICBjb25zdCBwcm9taXNlID0gbmV3UHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICByZXNvbHZlUHJvbWlzZSA9IHJlc29sdmU7XG4gICAgICAgICAgICByZWplY3RQcm9taXNlID0gcmVqZWN0O1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgcmVhZFJlcXVlc3QgPSB7XG4gICAgICAgICAgICBfY2h1bmtTdGVwczogY2h1bmsgPT4gcmVzb2x2ZVByb21pc2UoeyB2YWx1ZTogY2h1bmssIGRvbmU6IGZhbHNlIH0pLFxuICAgICAgICAgICAgX2Nsb3NlU3RlcHM6ICgpID0+IHJlc29sdmVQcm9taXNlKHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9KSxcbiAgICAgICAgICAgIF9lcnJvclN0ZXBzOiBlID0+IHJlamVjdFByb21pc2UoZSlcbiAgICAgICAgfTtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyUmVhZCh0aGlzLCByZWFkUmVxdWVzdCk7XG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWxlYXNlcyB0aGUgcmVhZGVyJ3MgbG9jayBvbiB0aGUgY29ycmVzcG9uZGluZyBzdHJlYW0uIEFmdGVyIHRoZSBsb2NrIGlzIHJlbGVhc2VkLCB0aGUgcmVhZGVyIGlzIG5vIGxvbmdlciBhY3RpdmUuXG4gICAgICogSWYgdGhlIGFzc29jaWF0ZWQgc3RyZWFtIGlzIGVycm9yZWQgd2hlbiB0aGUgbG9jayBpcyByZWxlYXNlZCwgdGhlIHJlYWRlciB3aWxsIGFwcGVhciBlcnJvcmVkIGluIHRoZSBzYW1lIHdheVxuICAgICAqIGZyb20gbm93IG9uOyBvdGhlcndpc2UsIHRoZSByZWFkZXIgd2lsbCBhcHBlYXIgY2xvc2VkLlxuICAgICAqXG4gICAgICogQSByZWFkZXIncyBsb2NrIGNhbm5vdCBiZSByZWxlYXNlZCB3aGlsZSBpdCBzdGlsbCBoYXMgYSBwZW5kaW5nIHJlYWQgcmVxdWVzdCwgaS5lLiwgaWYgYSBwcm9taXNlIHJldHVybmVkIGJ5XG4gICAgICogdGhlIHJlYWRlcidzIHtAbGluayBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIucmVhZCB8IHJlYWQoKX0gbWV0aG9kIGhhcyBub3QgeWV0IGJlZW4gc2V0dGxlZC4gQXR0ZW1wdGluZyB0b1xuICAgICAqIGRvIHNvIHdpbGwgdGhyb3cgYSBgVHlwZUVycm9yYCBhbmQgbGVhdmUgdGhlIHJlYWRlciBsb2NrZWQgdG8gdGhlIHN0cmVhbS5cbiAgICAgKi9cbiAgICByZWxlYXNlTG9jaygpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdFJlYWRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ3JlbGVhc2VMb2NrJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX293bmVyUmVhZGFibGVTdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9yZWFkUmVxdWVzdHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVHJpZWQgdG8gcmVsZWFzZSBhIHJlYWRlciBsb2NrIHdoZW4gdGhhdCByZWFkZXIgaGFzIHBlbmRpbmcgcmVhZCgpIGNhbGxzIHVuLXNldHRsZWQnKTtcbiAgICAgICAgfVxuICAgICAgICBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNSZWxlYXNlKHRoaXMpO1xuICAgIH1cbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlci5wcm90b3R5cGUsIHtcbiAgICBjYW5jZWw6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIHJlYWQ6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIHJlbGVhc2VMb2NrOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBjbG9zZWQ6IHsgZW51bWVyYWJsZTogdHJ1ZSB9XG59KTtcbmlmICh0eXBlb2YgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcgPT09ICdzeW1ib2wnKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlci5wcm90b3R5cGUsIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIHZhbHVlOiAnUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBBYnN0cmFjdCBvcGVyYXRpb25zIGZvciB0aGUgcmVhZGVycy5cbmZ1bmN0aW9uIElzUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyKHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfcmVhZFJlcXVlc3RzJykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4geCBpbnN0YW5jZW9mIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcjtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlclJlYWQocmVhZGVyLCByZWFkUmVxdWVzdCkge1xuICAgIGNvbnN0IHN0cmVhbSA9IHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbTtcbiAgICBzdHJlYW0uX2Rpc3R1cmJlZCA9IHRydWU7XG4gICAgaWYgKHN0cmVhbS5fc3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgIHJlYWRSZXF1ZXN0Ll9jbG9zZVN0ZXBzKCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHN0cmVhbS5fc3RhdGUgPT09ICdlcnJvcmVkJykge1xuICAgICAgICByZWFkUmVxdWVzdC5fZXJyb3JTdGVwcyhzdHJlYW0uX3N0b3JlZEVycm9yKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHN0cmVhbS5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyW1B1bGxTdGVwc10ocmVhZFJlcXVlc3QpO1xuICAgIH1cbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIuXG5mdW5jdGlvbiBkZWZhdWx0UmVhZGVyQnJhbmRDaGVja0V4Y2VwdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoYFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlci5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyYCk7XG59XG5cbi8vLyA8cmVmZXJlbmNlIGxpYj1cImVzMjAxOC5hc3luY2l0ZXJhYmxlXCIgLz5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1lbXB0eS1mdW5jdGlvbiAqL1xuY29uc3QgQXN5bmNJdGVyYXRvclByb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihPYmplY3QuZ2V0UHJvdG90eXBlT2YoYXN5bmMgZnVuY3Rpb24qICgpIHsgfSkucHJvdG90eXBlKTtcblxuLy8vIDxyZWZlcmVuY2UgbGliPVwiZXMyMDE4LmFzeW5jaXRlcmFibGVcIiAvPlxuY2xhc3MgUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9ySW1wbCB7XG4gICAgY29uc3RydWN0b3IocmVhZGVyLCBwcmV2ZW50Q2FuY2VsKSB7XG4gICAgICAgIHRoaXMuX29uZ29pbmdQcm9taXNlID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9pc0ZpbmlzaGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3JlYWRlciA9IHJlYWRlcjtcbiAgICAgICAgdGhpcy5fcHJldmVudENhbmNlbCA9IHByZXZlbnRDYW5jZWw7XG4gICAgfVxuICAgIG5leHQoKSB7XG4gICAgICAgIGNvbnN0IG5leHRTdGVwcyA9ICgpID0+IHRoaXMuX25leHRTdGVwcygpO1xuICAgICAgICB0aGlzLl9vbmdvaW5nUHJvbWlzZSA9IHRoaXMuX29uZ29pbmdQcm9taXNlID9cbiAgICAgICAgICAgIHRyYW5zZm9ybVByb21pc2VXaXRoKHRoaXMuX29uZ29pbmdQcm9taXNlLCBuZXh0U3RlcHMsIG5leHRTdGVwcykgOlxuICAgICAgICAgICAgbmV4dFN0ZXBzKCk7XG4gICAgICAgIHJldHVybiB0aGlzLl9vbmdvaW5nUHJvbWlzZTtcbiAgICB9XG4gICAgcmV0dXJuKHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IHJldHVyblN0ZXBzID0gKCkgPT4gdGhpcy5fcmV0dXJuU3RlcHModmFsdWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5fb25nb2luZ1Byb21pc2UgP1xuICAgICAgICAgICAgdHJhbnNmb3JtUHJvbWlzZVdpdGgodGhpcy5fb25nb2luZ1Byb21pc2UsIHJldHVyblN0ZXBzLCByZXR1cm5TdGVwcykgOlxuICAgICAgICAgICAgcmV0dXJuU3RlcHMoKTtcbiAgICB9XG4gICAgX25leHRTdGVwcygpIHtcbiAgICAgICAgaWYgKHRoaXMuX2lzRmluaXNoZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoeyB2YWx1ZTogdW5kZWZpbmVkLCBkb25lOiB0cnVlIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlYWRlciA9IHRoaXMuX3JlYWRlcjtcbiAgICAgICAgaWYgKHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChyZWFkZXJMb2NrRXhjZXB0aW9uKCdpdGVyYXRlJykpO1xuICAgICAgICB9XG4gICAgICAgIGxldCByZXNvbHZlUHJvbWlzZTtcbiAgICAgICAgbGV0IHJlamVjdFByb21pc2U7XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuZXdQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHJlc29sdmVQcm9taXNlID0gcmVzb2x2ZTtcbiAgICAgICAgICAgIHJlamVjdFByb21pc2UgPSByZWplY3Q7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByZWFkUmVxdWVzdCA9IHtcbiAgICAgICAgICAgIF9jaHVua1N0ZXBzOiBjaHVuayA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb25nb2luZ1Byb21pc2UgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgLy8gVGhpcyBuZWVkcyB0byBiZSBkZWxheWVkIGJ5IG9uZSBtaWNyb3Rhc2ssIG90aGVyd2lzZSB3ZSBzdG9wIHB1bGxpbmcgdG9vIGVhcmx5IHdoaWNoIGJyZWFrcyBhIHRlc3QuXG4gICAgICAgICAgICAgICAgLy8gRklYTUUgSXMgdGhpcyBhIGJ1ZyBpbiB0aGUgc3BlY2lmaWNhdGlvbiwgb3IgaW4gdGhlIHRlc3Q/XG4gICAgICAgICAgICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4gcmVzb2x2ZVByb21pc2UoeyB2YWx1ZTogY2h1bmssIGRvbmU6IGZhbHNlIH0pKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBfY2xvc2VTdGVwczogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX29uZ29pbmdQcm9taXNlID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIHRoaXMuX2lzRmluaXNoZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY1JlbGVhc2UocmVhZGVyKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlUHJvbWlzZSh7IHZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHRydWUgfSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgX2Vycm9yU3RlcHM6IHJlYXNvbiA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb25nb2luZ1Byb21pc2UgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgdGhpcy5faXNGaW5pc2hlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljUmVsZWFzZShyZWFkZXIpO1xuICAgICAgICAgICAgICAgIHJlamVjdFByb21pc2UocmVhc29uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyUmVhZChyZWFkZXIsIHJlYWRSZXF1ZXN0KTtcbiAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgfVxuICAgIF9yZXR1cm5TdGVwcyh2YWx1ZSkge1xuICAgICAgICBpZiAodGhpcy5faXNGaW5pc2hlZCkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHZhbHVlLCBkb25lOiB0cnVlIH0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2lzRmluaXNoZWQgPSB0cnVlO1xuICAgICAgICBjb25zdCByZWFkZXIgPSB0aGlzLl9yZWFkZXI7XG4gICAgICAgIGlmIChyZWFkZXIuX293bmVyUmVhZGFibGVTdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgocmVhZGVyTG9ja0V4Y2VwdGlvbignZmluaXNoIGl0ZXJhdGluZycpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuX3ByZXZlbnRDYW5jZWwpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IFJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY0NhbmNlbChyZWFkZXIsIHZhbHVlKTtcbiAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY1JlbGVhc2UocmVhZGVyKTtcbiAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1Qcm9taXNlV2l0aChyZXN1bHQsICgpID0+ICh7IHZhbHVlLCBkb25lOiB0cnVlIH0pKTtcbiAgICAgICAgfVxuICAgICAgICBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNSZWxlYXNlKHJlYWRlcik7XG4gICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHsgdmFsdWUsIGRvbmU6IHRydWUgfSk7XG4gICAgfVxufVxuY29uc3QgUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yUHJvdG90eXBlID0ge1xuICAgIG5leHQoKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3IodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHN0cmVhbUFzeW5jSXRlcmF0b3JCcmFuZENoZWNrRXhjZXB0aW9uKCduZXh0JykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9hc3luY0l0ZXJhdG9ySW1wbC5uZXh0KCk7XG4gICAgfSxcbiAgICByZXR1cm4odmFsdWUpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvcih0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoc3RyZWFtQXN5bmNJdGVyYXRvckJyYW5kQ2hlY2tFeGNlcHRpb24oJ3JldHVybicpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fYXN5bmNJdGVyYXRvckltcGwucmV0dXJuKHZhbHVlKTtcbiAgICB9XG59O1xuaWYgKEFzeW5jSXRlcmF0b3JQcm90b3R5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZihSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3JQcm90b3R5cGUsIEFzeW5jSXRlcmF0b3JQcm90b3R5cGUpO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtLlxuZnVuY3Rpb24gQWNxdWlyZVJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvcihzdHJlYW0sIHByZXZlbnRDYW5jZWwpIHtcbiAgICBjb25zdCByZWFkZXIgPSBBY3F1aXJlUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyKHN0cmVhbSk7XG4gICAgY29uc3QgaW1wbCA9IG5ldyBSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3JJbXBsKHJlYWRlciwgcHJldmVudENhbmNlbCk7XG4gICAgY29uc3QgaXRlcmF0b3IgPSBPYmplY3QuY3JlYXRlKFJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvclByb3RvdHlwZSk7XG4gICAgaXRlcmF0b3IuX2FzeW5jSXRlcmF0b3JJbXBsID0gaW1wbDtcbiAgICByZXR1cm4gaXRlcmF0b3I7XG59XG5mdW5jdGlvbiBJc1JlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvcih4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX2FzeW5jSXRlcmF0b3JJbXBsJykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyBub2luc3BlY3Rpb24gU3VzcGljaW91c1R5cGVPZkd1YXJkXG4gICAgICAgIHJldHVybiB4Ll9hc3luY0l0ZXJhdG9ySW1wbCBpbnN0YW5jZW9mXG4gICAgICAgICAgICBSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3JJbXBsO1xuICAgIH1cbiAgICBjYXRjaCAoX2EpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBSZWFkYWJsZVN0cmVhbS5cbmZ1bmN0aW9uIHN0cmVhbUFzeW5jSXRlcmF0b3JCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFJlYWRhYmxlU3RlYW1Bc3luY0l0ZXJhdG9yYCk7XG59XG5cbi8vLyA8cmVmZXJlbmNlIGxpYj1cImVzMjAxNS5jb3JlXCIgLz5cbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL051bWJlci9pc05hTiNQb2x5ZmlsbFxuY29uc3QgTnVtYmVySXNOYU4gPSBOdW1iZXIuaXNOYU4gfHwgZnVuY3Rpb24gKHgpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgcmV0dXJuIHggIT09IHg7XG59O1xuXG5mdW5jdGlvbiBDcmVhdGVBcnJheUZyb21MaXN0KGVsZW1lbnRzKSB7XG4gICAgLy8gV2UgdXNlIGFycmF5cyB0byByZXByZXNlbnQgbGlzdHMsIHNvIHRoaXMgaXMgYmFzaWNhbGx5IGEgbm8tb3AuXG4gICAgLy8gRG8gYSBzbGljZSB0aG91Z2gganVzdCBpbiBjYXNlIHdlIGhhcHBlbiB0byBkZXBlbmQgb24gdGhlIHVuaXF1ZS1uZXNzLlxuICAgIHJldHVybiBlbGVtZW50cy5zbGljZSgpO1xufVxuZnVuY3Rpb24gQ29weURhdGFCbG9ja0J5dGVzKGRlc3QsIGRlc3RPZmZzZXQsIHNyYywgc3JjT2Zmc2V0LCBuKSB7XG4gICAgbmV3IFVpbnQ4QXJyYXkoZGVzdCkuc2V0KG5ldyBVaW50OEFycmF5KHNyYywgc3JjT2Zmc2V0LCBuKSwgZGVzdE9mZnNldCk7XG59XG4vLyBOb3QgaW1wbGVtZW50ZWQgY29ycmVjdGx5XG5mdW5jdGlvbiBUcmFuc2ZlckFycmF5QnVmZmVyKE8pIHtcbiAgICByZXR1cm4gTztcbn1cbi8vIE5vdCBpbXBsZW1lbnRlZCBjb3JyZWN0bHlcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbmZ1bmN0aW9uIElzRGV0YWNoZWRCdWZmZXIoTykge1xuICAgIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIEFycmF5QnVmZmVyU2xpY2UoYnVmZmVyLCBiZWdpbiwgZW5kKSB7XG4gICAgLy8gQXJyYXlCdWZmZXIucHJvdG90eXBlLnNsaWNlIGlzIG5vdCBhdmFpbGFibGUgb24gSUUxMFxuICAgIC8vIGh0dHBzOi8vd3d3LmNhbml1c2UuY29tL21kbi1qYXZhc2NyaXB0X2J1aWx0aW5zX2FycmF5YnVmZmVyX3NsaWNlXG4gICAgaWYgKGJ1ZmZlci5zbGljZSkge1xuICAgICAgICByZXR1cm4gYnVmZmVyLnNsaWNlKGJlZ2luLCBlbmQpO1xuICAgIH1cbiAgICBjb25zdCBsZW5ndGggPSBlbmQgLSBiZWdpbjtcbiAgICBjb25zdCBzbGljZSA9IG5ldyBBcnJheUJ1ZmZlcihsZW5ndGgpO1xuICAgIENvcHlEYXRhQmxvY2tCeXRlcyhzbGljZSwgMCwgYnVmZmVyLCBiZWdpbiwgbGVuZ3RoKTtcbiAgICByZXR1cm4gc2xpY2U7XG59XG5cbmZ1bmN0aW9uIElzTm9uTmVnYXRpdmVOdW1iZXIodikge1xuICAgIGlmICh0eXBlb2YgdiAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoTnVtYmVySXNOYU4odikpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAodiA8IDApIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIENsb25lQXNVaW50OEFycmF5KE8pIHtcbiAgICBjb25zdCBidWZmZXIgPSBBcnJheUJ1ZmZlclNsaWNlKE8uYnVmZmVyLCBPLmJ5dGVPZmZzZXQsIE8uYnl0ZU9mZnNldCArIE8uYnl0ZUxlbmd0aCk7XG4gICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XG59XG5cbmZ1bmN0aW9uIERlcXVldWVWYWx1ZShjb250YWluZXIpIHtcbiAgICBjb25zdCBwYWlyID0gY29udGFpbmVyLl9xdWV1ZS5zaGlmdCgpO1xuICAgIGNvbnRhaW5lci5fcXVldWVUb3RhbFNpemUgLT0gcGFpci5zaXplO1xuICAgIGlmIChjb250YWluZXIuX3F1ZXVlVG90YWxTaXplIDwgMCkge1xuICAgICAgICBjb250YWluZXIuX3F1ZXVlVG90YWxTaXplID0gMDtcbiAgICB9XG4gICAgcmV0dXJuIHBhaXIudmFsdWU7XG59XG5mdW5jdGlvbiBFbnF1ZXVlVmFsdWVXaXRoU2l6ZShjb250YWluZXIsIHZhbHVlLCBzaXplKSB7XG4gICAgaWYgKCFJc05vbk5lZ2F0aXZlTnVtYmVyKHNpemUpIHx8IHNpemUgPT09IEluZmluaXR5KSB7XG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdTaXplIG11c3QgYmUgYSBmaW5pdGUsIG5vbi1OYU4sIG5vbi1uZWdhdGl2ZSBudW1iZXIuJyk7XG4gICAgfVxuICAgIGNvbnRhaW5lci5fcXVldWUucHVzaCh7IHZhbHVlLCBzaXplIH0pO1xuICAgIGNvbnRhaW5lci5fcXVldWVUb3RhbFNpemUgKz0gc2l6ZTtcbn1cbmZ1bmN0aW9uIFBlZWtRdWV1ZVZhbHVlKGNvbnRhaW5lcikge1xuICAgIGNvbnN0IHBhaXIgPSBjb250YWluZXIuX3F1ZXVlLnBlZWsoKTtcbiAgICByZXR1cm4gcGFpci52YWx1ZTtcbn1cbmZ1bmN0aW9uIFJlc2V0UXVldWUoY29udGFpbmVyKSB7XG4gICAgY29udGFpbmVyLl9xdWV1ZSA9IG5ldyBTaW1wbGVRdWV1ZSgpO1xuICAgIGNvbnRhaW5lci5fcXVldWVUb3RhbFNpemUgPSAwO1xufVxuXG4vKipcbiAqIEEgcHVsbC1pbnRvIHJlcXVlc3QgaW4gYSB7QGxpbmsgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcn0uXG4gKlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSWxsZWdhbCBjb25zdHJ1Y3RvcicpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2aWV3IGZvciB3cml0aW5nIGluIHRvLCBvciBgbnVsbGAgaWYgdGhlIEJZT0IgcmVxdWVzdCBoYXMgYWxyZWFkeSBiZWVuIHJlc3BvbmRlZCB0by5cbiAgICAgKi9cbiAgICBnZXQgdmlldygpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3QodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGJ5b2JSZXF1ZXN0QnJhbmRDaGVja0V4Y2VwdGlvbigndmlldycpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl92aWV3O1xuICAgIH1cbiAgICByZXNwb25kKGJ5dGVzV3JpdHRlbikge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdCh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgYnlvYlJlcXVlc3RCcmFuZENoZWNrRXhjZXB0aW9uKCdyZXNwb25kJyk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzZXJ0UmVxdWlyZWRBcmd1bWVudChieXRlc1dyaXR0ZW4sIDEsICdyZXNwb25kJyk7XG4gICAgICAgIGJ5dGVzV3JpdHRlbiA9IGNvbnZlcnRVbnNpZ25lZExvbmdMb25nV2l0aEVuZm9yY2VSYW5nZShieXRlc1dyaXR0ZW4sICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgaWYgKHRoaXMuX2Fzc29jaWF0ZWRSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoaXMgQllPQiByZXF1ZXN0IGhhcyBiZWVuIGludmFsaWRhdGVkJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKElzRGV0YWNoZWRCdWZmZXIodGhpcy5fdmlldy5idWZmZXIpKSA7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kKHRoaXMuX2Fzc29jaWF0ZWRSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLCBieXRlc1dyaXR0ZW4pO1xuICAgIH1cbiAgICByZXNwb25kV2l0aE5ld1ZpZXcodmlldykge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdCh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgYnlvYlJlcXVlc3RCcmFuZENoZWNrRXhjZXB0aW9uKCdyZXNwb25kV2l0aE5ld1ZpZXcnKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NlcnRSZXF1aXJlZEFyZ3VtZW50KHZpZXcsIDEsICdyZXNwb25kV2l0aE5ld1ZpZXcnKTtcbiAgICAgICAgaWYgKCFBcnJheUJ1ZmZlci5pc1ZpZXcodmlldykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1lvdSBjYW4gb25seSByZXNwb25kIHdpdGggYXJyYXkgYnVmZmVyIHZpZXdzJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX2Fzc29jaWF0ZWRSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoaXMgQllPQiByZXF1ZXN0IGhhcyBiZWVuIGludmFsaWRhdGVkJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKElzRGV0YWNoZWRCdWZmZXIodmlldy5idWZmZXIpKSA7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kV2l0aE5ld1ZpZXcodGhpcy5fYXNzb2NpYXRlZFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIsIHZpZXcpO1xuICAgIH1cbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3QucHJvdG90eXBlLCB7XG4gICAgcmVzcG9uZDogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgcmVzcG9uZFdpdGhOZXdWaWV3OiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICB2aWV3OiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0LnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcsIHtcbiAgICAgICAgdmFsdWU6ICdSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0JyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vKipcbiAqIEFsbG93cyBjb250cm9sIG9mIGEge0BsaW5rIFJlYWRhYmxlU3RyZWFtIHwgcmVhZGFibGUgYnl0ZSBzdHJlYW19J3Mgc3RhdGUgYW5kIGludGVybmFsIHF1ZXVlLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuY2xhc3MgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0lsbGVnYWwgY29uc3RydWN0b3InKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgY3VycmVudCBCWU9CIHB1bGwgcmVxdWVzdCwgb3IgYG51bGxgIGlmIHRoZXJlIGlzbid0IG9uZS5cbiAgICAgKi9cbiAgICBnZXQgYnlvYlJlcXVlc3QoKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBieXRlU3RyZWFtQ29udHJvbGxlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2J5b2JSZXF1ZXN0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJHZXRCWU9CUmVxdWVzdCh0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZGVzaXJlZCBzaXplIHRvIGZpbGwgdGhlIGNvbnRyb2xsZWQgc3RyZWFtJ3MgaW50ZXJuYWwgcXVldWUuIEl0IGNhbiBiZSBuZWdhdGl2ZSwgaWYgdGhlIHF1ZXVlIGlzXG4gICAgICogb3Zlci1mdWxsLiBBbiB1bmRlcmx5aW5nIGJ5dGUgc291cmNlIG91Z2h0IHRvIHVzZSB0aGlzIGluZm9ybWF0aW9uIHRvIGRldGVybWluZSB3aGVuIGFuZCBob3cgdG8gYXBwbHkgYmFja3ByZXNzdXJlLlxuICAgICAqL1xuICAgIGdldCBkZXNpcmVkU2l6ZSgpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGJ5dGVTdHJlYW1Db250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbignZGVzaXJlZFNpemUnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckdldERlc2lyZWRTaXplKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbG9zZXMgdGhlIGNvbnRyb2xsZWQgcmVhZGFibGUgc3RyZWFtLiBDb25zdW1lcnMgd2lsbCBzdGlsbCBiZSBhYmxlIHRvIHJlYWQgYW55IHByZXZpb3VzbHktZW5xdWV1ZWQgY2h1bmtzIGZyb21cbiAgICAgKiB0aGUgc3RyZWFtLCBidXQgb25jZSB0aG9zZSBhcmUgcmVhZCwgdGhlIHN0cmVhbSB3aWxsIGJlY29tZSBjbG9zZWQuXG4gICAgICovXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBieXRlU3RyZWFtQ29udHJvbGxlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2Nsb3NlJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX2Nsb3NlUmVxdWVzdGVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgc3RyZWFtIGhhcyBhbHJlYWR5IGJlZW4gY2xvc2VkOyBkbyBub3QgY2xvc2UgaXQgYWdhaW4hJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RhdGUgPSB0aGlzLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtLl9zdGF0ZTtcbiAgICAgICAgaWYgKHN0YXRlICE9PSAncmVhZGFibGUnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBUaGUgc3RyZWFtIChpbiAke3N0YXRlfSBzdGF0ZSkgaXMgbm90IGluIHRoZSByZWFkYWJsZSBzdGF0ZSBhbmQgY2Fubm90IGJlIGNsb3NlZGApO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbG9zZSh0aGlzKTtcbiAgICB9XG4gICAgZW5xdWV1ZShjaHVuaykge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgYnl0ZVN0cmVhbUNvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdlbnF1ZXVlJyk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzZXJ0UmVxdWlyZWRBcmd1bWVudChjaHVuaywgMSwgJ2VucXVldWUnKTtcbiAgICAgICAgaWYgKCFBcnJheUJ1ZmZlci5pc1ZpZXcoY2h1bmspKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdjaHVuayBtdXN0IGJlIGFuIGFycmF5IGJ1ZmZlciB2aWV3Jyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNodW5rLmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2NodW5rIG11c3QgaGF2ZSBub24temVybyBieXRlTGVuZ3RoJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNodW5rLmJ1ZmZlci5ieXRlTGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBjaHVuaydzIGJ1ZmZlciBtdXN0IGhhdmUgbm9uLXplcm8gYnl0ZUxlbmd0aGApO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9jbG9zZVJlcXVlc3RlZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignc3RyZWFtIGlzIGNsb3NlZCBvciBkcmFpbmluZycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHN0YXRlID0gdGhpcy5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbS5fc3RhdGU7XG4gICAgICAgIGlmIChzdGF0ZSAhPT0gJ3JlYWRhYmxlJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgVGhlIHN0cmVhbSAoaW4gJHtzdGF0ZX0gc3RhdGUpIGlzIG5vdCBpbiB0aGUgcmVhZGFibGUgc3RhdGUgYW5kIGNhbm5vdCBiZSBlbnF1ZXVlZCB0b2ApO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFbnF1ZXVlKHRoaXMsIGNodW5rKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRXJyb3JzIHRoZSBjb250cm9sbGVkIHJlYWRhYmxlIHN0cmVhbSwgbWFraW5nIGFsbCBmdXR1cmUgaW50ZXJhY3Rpb25zIHdpdGggaXQgZmFpbCB3aXRoIHRoZSBnaXZlbiBlcnJvciBgZWAuXG4gICAgICovXG4gICAgZXJyb3IoZSA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgYnl0ZVN0cmVhbUNvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdlcnJvcicpO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFcnJvcih0aGlzLCBlKTtcbiAgICB9XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIFtDYW5jZWxTdGVwc10ocmVhc29uKSB7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbGVhclBlbmRpbmdQdWxsSW50b3ModGhpcyk7XG4gICAgICAgIFJlc2V0UXVldWUodGhpcyk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX2NhbmNlbEFsZ29yaXRobShyZWFzb24pO1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xlYXJBbGdvcml0aG1zKHRoaXMpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICAvKiogQGludGVybmFsICovXG4gICAgW1B1bGxTdGVwc10ocmVhZFJlcXVlc3QpIHtcbiAgICAgICAgY29uc3Qgc3RyZWFtID0gdGhpcy5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbTtcbiAgICAgICAgaWYgKHRoaXMuX3F1ZXVlVG90YWxTaXplID4gMCkge1xuICAgICAgICAgICAgY29uc3QgZW50cnkgPSB0aGlzLl9xdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgdGhpcy5fcXVldWVUb3RhbFNpemUgLT0gZW50cnkuYnl0ZUxlbmd0aDtcbiAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJIYW5kbGVRdWV1ZURyYWluKHRoaXMpO1xuICAgICAgICAgICAgY29uc3QgdmlldyA9IG5ldyBVaW50OEFycmF5KGVudHJ5LmJ1ZmZlciwgZW50cnkuYnl0ZU9mZnNldCwgZW50cnkuYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICByZWFkUmVxdWVzdC5fY2h1bmtTdGVwcyh2aWV3KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhdXRvQWxsb2NhdGVDaHVua1NpemUgPSB0aGlzLl9hdXRvQWxsb2NhdGVDaHVua1NpemU7XG4gICAgICAgIGlmIChhdXRvQWxsb2NhdGVDaHVua1NpemUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbGV0IGJ1ZmZlcjtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgYnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKGF1dG9BbGxvY2F0ZUNodW5rU2l6ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoYnVmZmVyRSkge1xuICAgICAgICAgICAgICAgIHJlYWRSZXF1ZXN0Ll9lcnJvclN0ZXBzKGJ1ZmZlckUpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHB1bGxJbnRvRGVzY3JpcHRvciA9IHtcbiAgICAgICAgICAgICAgICBidWZmZXIsXG4gICAgICAgICAgICAgICAgYnVmZmVyQnl0ZUxlbmd0aDogYXV0b0FsbG9jYXRlQ2h1bmtTaXplLFxuICAgICAgICAgICAgICAgIGJ5dGVPZmZzZXQ6IDAsXG4gICAgICAgICAgICAgICAgYnl0ZUxlbmd0aDogYXV0b0FsbG9jYXRlQ2h1bmtTaXplLFxuICAgICAgICAgICAgICAgIGJ5dGVzRmlsbGVkOiAwLFxuICAgICAgICAgICAgICAgIGVsZW1lbnRTaXplOiAxLFxuICAgICAgICAgICAgICAgIHZpZXdDb25zdHJ1Y3RvcjogVWludDhBcnJheSxcbiAgICAgICAgICAgICAgICByZWFkZXJUeXBlOiAnZGVmYXVsdCdcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLl9wZW5kaW5nUHVsbEludG9zLnB1c2gocHVsbEludG9EZXNjcmlwdG9yKTtcbiAgICAgICAgfVxuICAgICAgICBSZWFkYWJsZVN0cmVhbUFkZFJlYWRSZXF1ZXN0KHN0cmVhbSwgcmVhZFJlcXVlc3QpO1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZCh0aGlzKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLnByb3RvdHlwZSwge1xuICAgIGNsb3NlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBlbnF1ZXVlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBlcnJvcjogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgYnlvYlJlcXVlc3Q6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGRlc2lyZWRTaXplOiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcsIHtcbiAgICAgICAgdmFsdWU6ICdSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBBYnN0cmFjdCBvcGVyYXRpb25zIGZvciB0aGUgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlci5cbmZ1bmN0aW9uIElzUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcih4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW0nKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcjtcbn1cbmZ1bmN0aW9uIElzUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdCh4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX2Fzc29jaWF0ZWRSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyJykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4geCBpbnN0YW5jZW9mIFJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3Q7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc2hvdWxkUHVsbCA9IFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJTaG91bGRDYWxsUHVsbChjb250cm9sbGVyKTtcbiAgICBpZiAoIXNob3VsZFB1bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY29udHJvbGxlci5fcHVsbGluZykge1xuICAgICAgICBjb250cm9sbGVyLl9wdWxsQWdhaW4gPSB0cnVlO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnRyb2xsZXIuX3B1bGxpbmcgPSB0cnVlO1xuICAgIC8vIFRPRE86IFRlc3QgY29udHJvbGxlciBhcmd1bWVudFxuICAgIGNvbnN0IHB1bGxQcm9taXNlID0gY29udHJvbGxlci5fcHVsbEFsZ29yaXRobSgpO1xuICAgIHVwb25Qcm9taXNlKHB1bGxQcm9taXNlLCAoKSA9PiB7XG4gICAgICAgIGNvbnRyb2xsZXIuX3B1bGxpbmcgPSBmYWxzZTtcbiAgICAgICAgaWYgKGNvbnRyb2xsZXIuX3B1bGxBZ2Fpbikge1xuICAgICAgICAgICAgY29udHJvbGxlci5fcHVsbEFnYWluID0gZmFsc2U7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKTtcbiAgICAgICAgfVxuICAgIH0sIGUgPT4ge1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRXJyb3IoY29udHJvbGxlciwgZSk7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xlYXJQZW5kaW5nUHVsbEludG9zKGNvbnRyb2xsZXIpIHtcbiAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVySW52YWxpZGF0ZUJZT0JSZXF1ZXN0KGNvbnRyb2xsZXIpO1xuICAgIGNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MgPSBuZXcgU2ltcGxlUXVldWUoKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDb21taXRQdWxsSW50b0Rlc2NyaXB0b3Ioc3RyZWFtLCBwdWxsSW50b0Rlc2NyaXB0b3IpIHtcbiAgICBsZXQgZG9uZSA9IGZhbHNlO1xuICAgIGlmIChzdHJlYW0uX3N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICBkb25lID0gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgZmlsbGVkVmlldyA9IFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDb252ZXJ0UHVsbEludG9EZXNjcmlwdG9yKHB1bGxJbnRvRGVzY3JpcHRvcik7XG4gICAgaWYgKHB1bGxJbnRvRGVzY3JpcHRvci5yZWFkZXJUeXBlID09PSAnZGVmYXVsdCcpIHtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1GdWxmaWxsUmVhZFJlcXVlc3Qoc3RyZWFtLCBmaWxsZWRWaWV3LCBkb25lKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRnVsZmlsbFJlYWRJbnRvUmVxdWVzdChzdHJlYW0sIGZpbGxlZFZpZXcsIGRvbmUpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDb252ZXJ0UHVsbEludG9EZXNjcmlwdG9yKHB1bGxJbnRvRGVzY3JpcHRvcikge1xuICAgIGNvbnN0IGJ5dGVzRmlsbGVkID0gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkO1xuICAgIGNvbnN0IGVsZW1lbnRTaXplID0gcHVsbEludG9EZXNjcmlwdG9yLmVsZW1lbnRTaXplO1xuICAgIHJldHVybiBuZXcgcHVsbEludG9EZXNjcmlwdG9yLnZpZXdDb25zdHJ1Y3RvcihwdWxsSW50b0Rlc2NyaXB0b3IuYnVmZmVyLCBwdWxsSW50b0Rlc2NyaXB0b3IuYnl0ZU9mZnNldCwgYnl0ZXNGaWxsZWQgLyBlbGVtZW50U2l6ZSk7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRW5xdWV1ZUNodW5rVG9RdWV1ZShjb250cm9sbGVyLCBidWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpIHtcbiAgICBjb250cm9sbGVyLl9xdWV1ZS5wdXNoKHsgYnVmZmVyLCBieXRlT2Zmc2V0LCBieXRlTGVuZ3RoIH0pO1xuICAgIGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplICs9IGJ5dGVMZW5ndGg7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRmlsbFB1bGxJbnRvRGVzY3JpcHRvckZyb21RdWV1ZShjb250cm9sbGVyLCBwdWxsSW50b0Rlc2NyaXB0b3IpIHtcbiAgICBjb25zdCBlbGVtZW50U2l6ZSA9IHB1bGxJbnRvRGVzY3JpcHRvci5lbGVtZW50U2l6ZTtcbiAgICBjb25zdCBjdXJyZW50QWxpZ25lZEJ5dGVzID0gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkIC0gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkICUgZWxlbWVudFNpemU7XG4gICAgY29uc3QgbWF4Qnl0ZXNUb0NvcHkgPSBNYXRoLm1pbihjb250cm9sbGVyLl9xdWV1ZVRvdGFsU2l6ZSwgcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVMZW5ndGggLSBwdWxsSW50b0Rlc2NyaXB0b3IuYnl0ZXNGaWxsZWQpO1xuICAgIGNvbnN0IG1heEJ5dGVzRmlsbGVkID0gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkICsgbWF4Qnl0ZXNUb0NvcHk7XG4gICAgY29uc3QgbWF4QWxpZ25lZEJ5dGVzID0gbWF4Qnl0ZXNGaWxsZWQgLSBtYXhCeXRlc0ZpbGxlZCAlIGVsZW1lbnRTaXplO1xuICAgIGxldCB0b3RhbEJ5dGVzVG9Db3B5UmVtYWluaW5nID0gbWF4Qnl0ZXNUb0NvcHk7XG4gICAgbGV0IHJlYWR5ID0gZmFsc2U7XG4gICAgaWYgKG1heEFsaWduZWRCeXRlcyA+IGN1cnJlbnRBbGlnbmVkQnl0ZXMpIHtcbiAgICAgICAgdG90YWxCeXRlc1RvQ29weVJlbWFpbmluZyA9IG1heEFsaWduZWRCeXRlcyAtIHB1bGxJbnRvRGVzY3JpcHRvci5ieXRlc0ZpbGxlZDtcbiAgICAgICAgcmVhZHkgPSB0cnVlO1xuICAgIH1cbiAgICBjb25zdCBxdWV1ZSA9IGNvbnRyb2xsZXIuX3F1ZXVlO1xuICAgIHdoaWxlICh0b3RhbEJ5dGVzVG9Db3B5UmVtYWluaW5nID4gMCkge1xuICAgICAgICBjb25zdCBoZWFkT2ZRdWV1ZSA9IHF1ZXVlLnBlZWsoKTtcbiAgICAgICAgY29uc3QgYnl0ZXNUb0NvcHkgPSBNYXRoLm1pbih0b3RhbEJ5dGVzVG9Db3B5UmVtYWluaW5nLCBoZWFkT2ZRdWV1ZS5ieXRlTGVuZ3RoKTtcbiAgICAgICAgY29uc3QgZGVzdFN0YXJ0ID0gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVPZmZzZXQgKyBwdWxsSW50b0Rlc2NyaXB0b3IuYnl0ZXNGaWxsZWQ7XG4gICAgICAgIENvcHlEYXRhQmxvY2tCeXRlcyhwdWxsSW50b0Rlc2NyaXB0b3IuYnVmZmVyLCBkZXN0U3RhcnQsIGhlYWRPZlF1ZXVlLmJ1ZmZlciwgaGVhZE9mUXVldWUuYnl0ZU9mZnNldCwgYnl0ZXNUb0NvcHkpO1xuICAgICAgICBpZiAoaGVhZE9mUXVldWUuYnl0ZUxlbmd0aCA9PT0gYnl0ZXNUb0NvcHkpIHtcbiAgICAgICAgICAgIHF1ZXVlLnNoaWZ0KCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBoZWFkT2ZRdWV1ZS5ieXRlT2Zmc2V0ICs9IGJ5dGVzVG9Db3B5O1xuICAgICAgICAgICAgaGVhZE9mUXVldWUuYnl0ZUxlbmd0aCAtPSBieXRlc1RvQ29weTtcbiAgICAgICAgfVxuICAgICAgICBjb250cm9sbGVyLl9xdWV1ZVRvdGFsU2l6ZSAtPSBieXRlc1RvQ29weTtcbiAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckZpbGxIZWFkUHVsbEludG9EZXNjcmlwdG9yKGNvbnRyb2xsZXIsIGJ5dGVzVG9Db3B5LCBwdWxsSW50b0Rlc2NyaXB0b3IpO1xuICAgICAgICB0b3RhbEJ5dGVzVG9Db3B5UmVtYWluaW5nIC09IGJ5dGVzVG9Db3B5O1xuICAgIH1cbiAgICByZXR1cm4gcmVhZHk7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRmlsbEhlYWRQdWxsSW50b0Rlc2NyaXB0b3IoY29udHJvbGxlciwgc2l6ZSwgcHVsbEludG9EZXNjcmlwdG9yKSB7XG4gICAgcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkICs9IHNpemU7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVySGFuZGxlUXVldWVEcmFpbihjb250cm9sbGVyKSB7XG4gICAgaWYgKGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplID09PSAwICYmIGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkKSB7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcik7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtQ2xvc2UoY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKTtcbiAgICB9XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVySW52YWxpZGF0ZUJZT0JSZXF1ZXN0KGNvbnRyb2xsZXIpIHtcbiAgICBpZiAoY29udHJvbGxlci5fYnlvYlJlcXVlc3QgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb250cm9sbGVyLl9ieW9iUmVxdWVzdC5fYXNzb2NpYXRlZFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIgPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fYnlvYlJlcXVlc3QuX3ZpZXcgPSBudWxsO1xuICAgIGNvbnRyb2xsZXIuX2J5b2JSZXF1ZXN0ID0gbnVsbDtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJQcm9jZXNzUHVsbEludG9EZXNjcmlwdG9yc1VzaW5nUXVldWUoY29udHJvbGxlcikge1xuICAgIHdoaWxlIChjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgaWYgKGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHVsbEludG9EZXNjcmlwdG9yID0gY29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcy5wZWVrKCk7XG4gICAgICAgIGlmIChSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRmlsbFB1bGxJbnRvRGVzY3JpcHRvckZyb21RdWV1ZShjb250cm9sbGVyLCBwdWxsSW50b0Rlc2NyaXB0b3IpKSB7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyU2hpZnRQZW5kaW5nUHVsbEludG8oY29udHJvbGxlcik7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ29tbWl0UHVsbEludG9EZXNjcmlwdG9yKGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW0sIHB1bGxJbnRvRGVzY3JpcHRvcik7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUHVsbEludG8oY29udHJvbGxlciwgdmlldywgcmVhZEludG9SZXF1ZXN0KSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbTtcbiAgICBsZXQgZWxlbWVudFNpemUgPSAxO1xuICAgIGlmICh2aWV3LmNvbnN0cnVjdG9yICE9PSBEYXRhVmlldykge1xuICAgICAgICBlbGVtZW50U2l6ZSA9IHZpZXcuY29uc3RydWN0b3IuQllURVNfUEVSX0VMRU1FTlQ7XG4gICAgfVxuICAgIGNvbnN0IGN0b3IgPSB2aWV3LmNvbnN0cnVjdG9yO1xuICAgIC8vIHRyeSB7XG4gICAgY29uc3QgYnVmZmVyID0gVHJhbnNmZXJBcnJheUJ1ZmZlcih2aWV3LmJ1ZmZlcik7XG4gICAgLy8gfSBjYXRjaCAoZSkge1xuICAgIC8vICAgcmVhZEludG9SZXF1ZXN0Ll9lcnJvclN0ZXBzKGUpO1xuICAgIC8vICAgcmV0dXJuO1xuICAgIC8vIH1cbiAgICBjb25zdCBwdWxsSW50b0Rlc2NyaXB0b3IgPSB7XG4gICAgICAgIGJ1ZmZlcixcbiAgICAgICAgYnVmZmVyQnl0ZUxlbmd0aDogYnVmZmVyLmJ5dGVMZW5ndGgsXG4gICAgICAgIGJ5dGVPZmZzZXQ6IHZpZXcuYnl0ZU9mZnNldCxcbiAgICAgICAgYnl0ZUxlbmd0aDogdmlldy5ieXRlTGVuZ3RoLFxuICAgICAgICBieXRlc0ZpbGxlZDogMCxcbiAgICAgICAgZWxlbWVudFNpemUsXG4gICAgICAgIHZpZXdDb25zdHJ1Y3RvcjogY3RvcixcbiAgICAgICAgcmVhZGVyVHlwZTogJ2J5b2InXG4gICAgfTtcbiAgICBpZiAoY29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MucHVzaChwdWxsSW50b0Rlc2NyaXB0b3IpO1xuICAgICAgICAvLyBObyBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZCgpIGNhbGwgc2luY2U6XG4gICAgICAgIC8vIC0gTm8gY2hhbmdlIGhhcHBlbnMgb24gZGVzaXJlZFNpemVcbiAgICAgICAgLy8gLSBUaGUgc291cmNlIGhhcyBhbHJlYWR5IGJlZW4gbm90aWZpZWQgb2YgdGhhdCB0aGVyZSdzIGF0IGxlYXN0IDEgcGVuZGluZyByZWFkKHZpZXcpXG4gICAgICAgIFJlYWRhYmxlU3RyZWFtQWRkUmVhZEludG9SZXF1ZXN0KHN0cmVhbSwgcmVhZEludG9SZXF1ZXN0KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgY29uc3QgZW1wdHlWaWV3ID0gbmV3IGN0b3IocHVsbEludG9EZXNjcmlwdG9yLmJ1ZmZlciwgcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVPZmZzZXQsIDApO1xuICAgICAgICByZWFkSW50b1JlcXVlc3QuX2Nsb3NlU3RlcHMoZW1wdHlWaWV3KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY29udHJvbGxlci5fcXVldWVUb3RhbFNpemUgPiAwKSB7XG4gICAgICAgIGlmIChSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRmlsbFB1bGxJbnRvRGVzY3JpcHRvckZyb21RdWV1ZShjb250cm9sbGVyLCBwdWxsSW50b0Rlc2NyaXB0b3IpKSB7XG4gICAgICAgICAgICBjb25zdCBmaWxsZWRWaWV3ID0gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNvbnZlcnRQdWxsSW50b0Rlc2NyaXB0b3IocHVsbEludG9EZXNjcmlwdG9yKTtcbiAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJIYW5kbGVRdWV1ZURyYWluKGNvbnRyb2xsZXIpO1xuICAgICAgICAgICAgcmVhZEludG9SZXF1ZXN0Ll9jaHVua1N0ZXBzKGZpbGxlZFZpZXcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb250cm9sbGVyLl9jbG9zZVJlcXVlc3RlZCkge1xuICAgICAgICAgICAgY29uc3QgZSA9IG5ldyBUeXBlRXJyb3IoJ0luc3VmZmljaWVudCBieXRlcyB0byBmaWxsIGVsZW1lbnRzIGluIHRoZSBnaXZlbiBidWZmZXInKTtcbiAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBlKTtcbiAgICAgICAgICAgIHJlYWRJbnRvUmVxdWVzdC5fZXJyb3JTdGVwcyhlKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLnB1c2gocHVsbEludG9EZXNjcmlwdG9yKTtcbiAgICBSZWFkYWJsZVN0cmVhbUFkZFJlYWRJbnRvUmVxdWVzdChzdHJlYW0sIHJlYWRJbnRvUmVxdWVzdCk7XG4gICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNhbGxQdWxsSWZOZWVkZWQoY29udHJvbGxlcik7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZEluQ2xvc2VkU3RhdGUoY29udHJvbGxlciwgZmlyc3REZXNjcmlwdG9yKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbTtcbiAgICBpZiAoUmVhZGFibGVTdHJlYW1IYXNCWU9CUmVhZGVyKHN0cmVhbSkpIHtcbiAgICAgICAgd2hpbGUgKFJlYWRhYmxlU3RyZWFtR2V0TnVtUmVhZEludG9SZXF1ZXN0cyhzdHJlYW0pID4gMCkge1xuICAgICAgICAgICAgY29uc3QgcHVsbEludG9EZXNjcmlwdG9yID0gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclNoaWZ0UGVuZGluZ1B1bGxJbnRvKGNvbnRyb2xsZXIpO1xuICAgICAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNvbW1pdFB1bGxJbnRvRGVzY3JpcHRvcihzdHJlYW0sIHB1bGxJbnRvRGVzY3JpcHRvcik7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZEluUmVhZGFibGVTdGF0ZShjb250cm9sbGVyLCBieXRlc1dyaXR0ZW4sIHB1bGxJbnRvRGVzY3JpcHRvcikge1xuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJGaWxsSGVhZFB1bGxJbnRvRGVzY3JpcHRvcihjb250cm9sbGVyLCBieXRlc1dyaXR0ZW4sIHB1bGxJbnRvRGVzY3JpcHRvcik7XG4gICAgaWYgKHB1bGxJbnRvRGVzY3JpcHRvci5ieXRlc0ZpbGxlZCA8IHB1bGxJbnRvRGVzY3JpcHRvci5lbGVtZW50U2l6ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJTaGlmdFBlbmRpbmdQdWxsSW50byhjb250cm9sbGVyKTtcbiAgICBjb25zdCByZW1haW5kZXJTaXplID0gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkICUgcHVsbEludG9EZXNjcmlwdG9yLmVsZW1lbnRTaXplO1xuICAgIGlmIChyZW1haW5kZXJTaXplID4gMCkge1xuICAgICAgICBjb25zdCBlbmQgPSBwdWxsSW50b0Rlc2NyaXB0b3IuYnl0ZU9mZnNldCArIHB1bGxJbnRvRGVzY3JpcHRvci5ieXRlc0ZpbGxlZDtcbiAgICAgICAgY29uc3QgcmVtYWluZGVyID0gQXJyYXlCdWZmZXJTbGljZShwdWxsSW50b0Rlc2NyaXB0b3IuYnVmZmVyLCBlbmQgLSByZW1haW5kZXJTaXplLCBlbmQpO1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRW5xdWV1ZUNodW5rVG9RdWV1ZShjb250cm9sbGVyLCByZW1haW5kZXIsIDAsIHJlbWFpbmRlci5ieXRlTGVuZ3RoKTtcbiAgICB9XG4gICAgcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkIC09IHJlbWFpbmRlclNpemU7XG4gICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNvbW1pdFB1bGxJbnRvRGVzY3JpcHRvcihjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtLCBwdWxsSW50b0Rlc2NyaXB0b3IpO1xuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJQcm9jZXNzUHVsbEludG9EZXNjcmlwdG9yc1VzaW5nUXVldWUoY29udHJvbGxlcik7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZEludGVybmFsKGNvbnRyb2xsZXIsIGJ5dGVzV3JpdHRlbikge1xuICAgIGNvbnN0IGZpcnN0RGVzY3JpcHRvciA9IGNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MucGVlaygpO1xuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJJbnZhbGlkYXRlQllPQlJlcXVlc3QoY29udHJvbGxlcik7XG4gICAgY29uc3Qgc3RhdGUgPSBjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtLl9zdGF0ZTtcbiAgICBpZiAoc3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kSW5DbG9zZWRTdGF0ZShjb250cm9sbGVyKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kSW5SZWFkYWJsZVN0YXRlKGNvbnRyb2xsZXIsIGJ5dGVzV3JpdHRlbiwgZmlyc3REZXNjcmlwdG9yKTtcbiAgICB9XG4gICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNhbGxQdWxsSWZOZWVkZWQoY29udHJvbGxlcik7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyU2hpZnRQZW5kaW5nUHVsbEludG8oY29udHJvbGxlcikge1xuICAgIGNvbnN0IGRlc2NyaXB0b3IgPSBjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLnNoaWZ0KCk7XG4gICAgcmV0dXJuIGRlc2NyaXB0b3I7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyU2hvdWxkQ2FsbFB1bGwoY29udHJvbGxlcikge1xuICAgIGNvbnN0IHN0cmVhbSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW07XG4gICAgaWYgKHN0cmVhbS5fc3RhdGUgIT09ICdyZWFkYWJsZScpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoY29udHJvbGxlci5fY2xvc2VSZXF1ZXN0ZWQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIWNvbnRyb2xsZXIuX3N0YXJ0ZWQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoUmVhZGFibGVTdHJlYW1IYXNEZWZhdWx0UmVhZGVyKHN0cmVhbSkgJiYgUmVhZGFibGVTdHJlYW1HZXROdW1SZWFkUmVxdWVzdHMoc3RyZWFtKSA+IDApIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmIChSZWFkYWJsZVN0cmVhbUhhc0JZT0JSZWFkZXIoc3RyZWFtKSAmJiBSZWFkYWJsZVN0cmVhbUdldE51bVJlYWRJbnRvUmVxdWVzdHMoc3RyZWFtKSA+IDApIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGNvbnN0IGRlc2lyZWRTaXplID0gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckdldERlc2lyZWRTaXplKGNvbnRyb2xsZXIpO1xuICAgIGlmIChkZXNpcmVkU2l6ZSA+IDApIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcikge1xuICAgIGNvbnRyb2xsZXIuX3B1bGxBbGdvcml0aG0gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fY2FuY2VsQWxnb3JpdGhtID0gdW5kZWZpbmVkO1xufVxuLy8gQSBjbGllbnQgb2YgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlciBtYXkgdXNlIHRoZXNlIGZ1bmN0aW9ucyBkaXJlY3RseSB0byBieXBhc3Mgc3RhdGUgY2hlY2suXG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xvc2UoY29udHJvbGxlcikge1xuICAgIGNvbnN0IHN0cmVhbSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW07XG4gICAgaWYgKGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkIHx8IHN0cmVhbS5fc3RhdGUgIT09ICdyZWFkYWJsZScpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY29udHJvbGxlci5fcXVldWVUb3RhbFNpemUgPiAwKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IGZpcnN0UGVuZGluZ1B1bGxJbnRvID0gY29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcy5wZWVrKCk7XG4gICAgICAgIGlmIChmaXJzdFBlbmRpbmdQdWxsSW50by5ieXRlc0ZpbGxlZCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGUgPSBuZXcgVHlwZUVycm9yKCdJbnN1ZmZpY2llbnQgYnl0ZXMgdG8gZmlsbCBlbGVtZW50cyBpbiB0aGUgZ2l2ZW4gYnVmZmVyJyk7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRXJyb3IoY29udHJvbGxlciwgZSk7XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgfVxuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcik7XG4gICAgUmVhZGFibGVTdHJlYW1DbG9zZShzdHJlYW0pO1xufVxuZnVuY3Rpb24gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVucXVldWUoY29udHJvbGxlciwgY2h1bmspIHtcbiAgICBjb25zdCBzdHJlYW0gPSBjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtO1xuICAgIGlmIChjb250cm9sbGVyLl9jbG9zZVJlcXVlc3RlZCB8fCBzdHJlYW0uX3N0YXRlICE9PSAncmVhZGFibGUnKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgYnVmZmVyID0gY2h1bmsuYnVmZmVyO1xuICAgIGNvbnN0IGJ5dGVPZmZzZXQgPSBjaHVuay5ieXRlT2Zmc2V0O1xuICAgIGNvbnN0IGJ5dGVMZW5ndGggPSBjaHVuay5ieXRlTGVuZ3RoO1xuICAgIGNvbnN0IHRyYW5zZmVycmVkQnVmZmVyID0gVHJhbnNmZXJBcnJheUJ1ZmZlcihidWZmZXIpO1xuICAgIGlmIChjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgZmlyc3RQZW5kaW5nUHVsbEludG8gPSBjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLnBlZWsoKTtcbiAgICAgICAgaWYgKElzRGV0YWNoZWRCdWZmZXIoZmlyc3RQZW5kaW5nUHVsbEludG8uYnVmZmVyKSkgO1xuICAgICAgICBmaXJzdFBlbmRpbmdQdWxsSW50by5idWZmZXIgPSBUcmFuc2ZlckFycmF5QnVmZmVyKGZpcnN0UGVuZGluZ1B1bGxJbnRvLmJ1ZmZlcik7XG4gICAgfVxuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJJbnZhbGlkYXRlQllPQlJlcXVlc3QoY29udHJvbGxlcik7XG4gICAgaWYgKFJlYWRhYmxlU3RyZWFtSGFzRGVmYXVsdFJlYWRlcihzdHJlYW0pKSB7XG4gICAgICAgIGlmIChSZWFkYWJsZVN0cmVhbUdldE51bVJlYWRSZXF1ZXN0cyhzdHJlYW0pID09PSAwKSB7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRW5xdWV1ZUNodW5rVG9RdWV1ZShjb250cm9sbGVyLCB0cmFuc2ZlcnJlZEJ1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2ZlcnJlZFZpZXcgPSBuZXcgVWludDhBcnJheSh0cmFuc2ZlcnJlZEJ1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICBSZWFkYWJsZVN0cmVhbUZ1bGZpbGxSZWFkUmVxdWVzdChzdHJlYW0sIHRyYW5zZmVycmVkVmlldywgZmFsc2UpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKFJlYWRhYmxlU3RyZWFtSGFzQllPQlJlYWRlcihzdHJlYW0pKSB7XG4gICAgICAgIC8vIFRPRE86IElkZWFsbHkgaW4gdGhpcyBicmFuY2ggZGV0YWNoaW5nIHNob3VsZCBoYXBwZW4gb25seSBpZiB0aGUgYnVmZmVyIGlzIG5vdCBjb25zdW1lZCBmdWxseS5cbiAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVucXVldWVDaHVua1RvUXVldWUoY29udHJvbGxlciwgdHJhbnNmZXJyZWRCdWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpO1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUHJvY2Vzc1B1bGxJbnRvRGVzY3JpcHRvcnNVc2luZ1F1ZXVlKGNvbnRyb2xsZXIpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVucXVldWVDaHVua1RvUXVldWUoY29udHJvbGxlciwgdHJhbnNmZXJyZWRCdWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpO1xuICAgIH1cbiAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBlKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbTtcbiAgICBpZiAoc3RyZWFtLl9zdGF0ZSAhPT0gJ3JlYWRhYmxlJykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbGVhclBlbmRpbmdQdWxsSW50b3MoY29udHJvbGxlcik7XG4gICAgUmVzZXRRdWV1ZShjb250cm9sbGVyKTtcbiAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xlYXJBbGdvcml0aG1zKGNvbnRyb2xsZXIpO1xuICAgIFJlYWRhYmxlU3RyZWFtRXJyb3Ioc3RyZWFtLCBlKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJHZXRCWU9CUmVxdWVzdChjb250cm9sbGVyKSB7XG4gICAgaWYgKGNvbnRyb2xsZXIuX2J5b2JSZXF1ZXN0ID09PSBudWxsICYmIGNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBmaXJzdERlc2NyaXB0b3IgPSBjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLnBlZWsoKTtcbiAgICAgICAgY29uc3QgdmlldyA9IG5ldyBVaW50OEFycmF5KGZpcnN0RGVzY3JpcHRvci5idWZmZXIsIGZpcnN0RGVzY3JpcHRvci5ieXRlT2Zmc2V0ICsgZmlyc3REZXNjcmlwdG9yLmJ5dGVzRmlsbGVkLCBmaXJzdERlc2NyaXB0b3IuYnl0ZUxlbmd0aCAtIGZpcnN0RGVzY3JpcHRvci5ieXRlc0ZpbGxlZCk7XG4gICAgICAgIGNvbnN0IGJ5b2JSZXF1ZXN0ID0gT2JqZWN0LmNyZWF0ZShSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0LnByb3RvdHlwZSk7XG4gICAgICAgIFNldFVwUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdChieW9iUmVxdWVzdCwgY29udHJvbGxlciwgdmlldyk7XG4gICAgICAgIGNvbnRyb2xsZXIuX2J5b2JSZXF1ZXN0ID0gYnlvYlJlcXVlc3Q7XG4gICAgfVxuICAgIHJldHVybiBjb250cm9sbGVyLl9ieW9iUmVxdWVzdDtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJHZXREZXNpcmVkU2l6ZShjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc3RhdGUgPSBjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtLl9zdGF0ZTtcbiAgICBpZiAoc3RhdGUgPT09ICdlcnJvcmVkJykge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKHN0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgcmV0dXJuIGNvbnRyb2xsZXIuX3N0cmF0ZWd5SFdNIC0gY29udHJvbGxlci5fcXVldWVUb3RhbFNpemU7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZChjb250cm9sbGVyLCBieXRlc1dyaXR0ZW4pIHtcbiAgICBjb25zdCBmaXJzdERlc2NyaXB0b3IgPSBjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLnBlZWsoKTtcbiAgICBjb25zdCBzdGF0ZSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW0uX3N0YXRlO1xuICAgIGlmIChzdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgaWYgKGJ5dGVzV3JpdHRlbiAhPT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYnl0ZXNXcml0dGVuIG11c3QgYmUgMCB3aGVuIGNhbGxpbmcgcmVzcG9uZCgpIG9uIGEgY2xvc2VkIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBpZiAoYnl0ZXNXcml0dGVuID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdieXRlc1dyaXR0ZW4gbXVzdCBiZSBncmVhdGVyIHRoYW4gMCB3aGVuIGNhbGxpbmcgcmVzcG9uZCgpIG9uIGEgcmVhZGFibGUgc3RyZWFtJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZpcnN0RGVzY3JpcHRvci5ieXRlc0ZpbGxlZCArIGJ5dGVzV3JpdHRlbiA+IGZpcnN0RGVzY3JpcHRvci5ieXRlTGVuZ3RoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignYnl0ZXNXcml0dGVuIG91dCBvZiByYW5nZScpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGZpcnN0RGVzY3JpcHRvci5idWZmZXIgPSBUcmFuc2ZlckFycmF5QnVmZmVyKGZpcnN0RGVzY3JpcHRvci5idWZmZXIpO1xuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kSW50ZXJuYWwoY29udHJvbGxlciwgYnl0ZXNXcml0dGVuKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kV2l0aE5ld1ZpZXcoY29udHJvbGxlciwgdmlldykge1xuICAgIGNvbnN0IGZpcnN0RGVzY3JpcHRvciA9IGNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MucGVlaygpO1xuICAgIGNvbnN0IHN0YXRlID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKHN0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICBpZiAodmlldy5ieXRlTGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgdmlld1xcJ3MgbGVuZ3RoIG11c3QgYmUgMCB3aGVuIGNhbGxpbmcgcmVzcG9uZFdpdGhOZXdWaWV3KCkgb24gYSBjbG9zZWQgc3RyZWFtJyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGlmICh2aWV3LmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSB2aWV3XFwncyBsZW5ndGggbXVzdCBiZSBncmVhdGVyIHRoYW4gMCB3aGVuIGNhbGxpbmcgcmVzcG9uZFdpdGhOZXdWaWV3KCkgb24gYSByZWFkYWJsZSBzdHJlYW0nKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoZmlyc3REZXNjcmlwdG9yLmJ5dGVPZmZzZXQgKyBmaXJzdERlc2NyaXB0b3IuYnl0ZXNGaWxsZWQgIT09IHZpZXcuYnl0ZU9mZnNldCkge1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVGhlIHJlZ2lvbiBzcGVjaWZpZWQgYnkgdmlldyBkb2VzIG5vdCBtYXRjaCBieW9iUmVxdWVzdCcpO1xuICAgIH1cbiAgICBpZiAoZmlyc3REZXNjcmlwdG9yLmJ1ZmZlckJ5dGVMZW5ndGggIT09IHZpZXcuYnVmZmVyLmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSBidWZmZXIgb2YgdmlldyBoYXMgZGlmZmVyZW50IGNhcGFjaXR5IHRoYW4gYnlvYlJlcXVlc3QnKTtcbiAgICB9XG4gICAgaWYgKGZpcnN0RGVzY3JpcHRvci5ieXRlc0ZpbGxlZCArIHZpZXcuYnl0ZUxlbmd0aCA+IGZpcnN0RGVzY3JpcHRvci5ieXRlTGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdUaGUgcmVnaW9uIHNwZWNpZmllZCBieSB2aWV3IGlzIGxhcmdlciB0aGFuIGJ5b2JSZXF1ZXN0Jyk7XG4gICAgfVxuICAgIGZpcnN0RGVzY3JpcHRvci5idWZmZXIgPSBUcmFuc2ZlckFycmF5QnVmZmVyKHZpZXcuYnVmZmVyKTtcbiAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZEludGVybmFsKGNvbnRyb2xsZXIsIHZpZXcuYnl0ZUxlbmd0aCk7XG59XG5mdW5jdGlvbiBTZXRVcFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCBzdGFydEFsZ29yaXRobSwgcHVsbEFsZ29yaXRobSwgY2FuY2VsQWxnb3JpdGhtLCBoaWdoV2F0ZXJNYXJrLCBhdXRvQWxsb2NhdGVDaHVua1NpemUpIHtcbiAgICBjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtID0gc3RyZWFtO1xuICAgIGNvbnRyb2xsZXIuX3B1bGxBZ2FpbiA9IGZhbHNlO1xuICAgIGNvbnRyb2xsZXIuX3B1bGxpbmcgPSBmYWxzZTtcbiAgICBjb250cm9sbGVyLl9ieW9iUmVxdWVzdCA9IG51bGw7XG4gICAgLy8gTmVlZCB0byBzZXQgdGhlIHNsb3RzIHNvIHRoYXQgdGhlIGFzc2VydCBkb2Vzbid0IGZpcmUuIEluIHRoZSBzcGVjIHRoZSBzbG90cyBhbHJlYWR5IGV4aXN0IGltcGxpY2l0bHkuXG4gICAgY29udHJvbGxlci5fcXVldWUgPSBjb250cm9sbGVyLl9xdWV1ZVRvdGFsU2l6ZSA9IHVuZGVmaW5lZDtcbiAgICBSZXNldFF1ZXVlKGNvbnRyb2xsZXIpO1xuICAgIGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkID0gZmFsc2U7XG4gICAgY29udHJvbGxlci5fc3RhcnRlZCA9IGZhbHNlO1xuICAgIGNvbnRyb2xsZXIuX3N0cmF0ZWd5SFdNID0gaGlnaFdhdGVyTWFyaztcbiAgICBjb250cm9sbGVyLl9wdWxsQWxnb3JpdGhtID0gcHVsbEFsZ29yaXRobTtcbiAgICBjb250cm9sbGVyLl9jYW5jZWxBbGdvcml0aG0gPSBjYW5jZWxBbGdvcml0aG07XG4gICAgY29udHJvbGxlci5fYXV0b0FsbG9jYXRlQ2h1bmtTaXplID0gYXV0b0FsbG9jYXRlQ2h1bmtTaXplO1xuICAgIGNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MgPSBuZXcgU2ltcGxlUXVldWUoKTtcbiAgICBzdHJlYW0uX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciA9IGNvbnRyb2xsZXI7XG4gICAgY29uc3Qgc3RhcnRSZXN1bHQgPSBzdGFydEFsZ29yaXRobSgpO1xuICAgIHVwb25Qcm9taXNlKHByb21pc2VSZXNvbHZlZFdpdGgoc3RhcnRSZXN1bHQpLCAoKSA9PiB7XG4gICAgICAgIGNvbnRyb2xsZXIuX3N0YXJ0ZWQgPSB0cnVlO1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKTtcbiAgICB9LCByID0+IHtcbiAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVycm9yKGNvbnRyb2xsZXIsIHIpO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gU2V0VXBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRnJvbVVuZGVybHlpbmdTb3VyY2Uoc3RyZWFtLCB1bmRlcmx5aW5nQnl0ZVNvdXJjZSwgaGlnaFdhdGVyTWFyaykge1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBPYmplY3QuY3JlYXRlKFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIucHJvdG90eXBlKTtcbiAgICBsZXQgc3RhcnRBbGdvcml0aG0gPSAoKSA9PiB1bmRlZmluZWQ7XG4gICAgbGV0IHB1bGxBbGdvcml0aG0gPSAoKSA9PiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgbGV0IGNhbmNlbEFsZ29yaXRobSA9ICgpID0+IHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICBpZiAodW5kZXJseWluZ0J5dGVTb3VyY2Uuc3RhcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzdGFydEFsZ29yaXRobSA9ICgpID0+IHVuZGVybHlpbmdCeXRlU291cmNlLnN0YXJ0KGNvbnRyb2xsZXIpO1xuICAgIH1cbiAgICBpZiAodW5kZXJseWluZ0J5dGVTb3VyY2UucHVsbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHB1bGxBbGdvcml0aG0gPSAoKSA9PiB1bmRlcmx5aW5nQnl0ZVNvdXJjZS5wdWxsKGNvbnRyb2xsZXIpO1xuICAgIH1cbiAgICBpZiAodW5kZXJseWluZ0J5dGVTb3VyY2UuY2FuY2VsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY2FuY2VsQWxnb3JpdGhtID0gcmVhc29uID0+IHVuZGVybHlpbmdCeXRlU291cmNlLmNhbmNlbChyZWFzb24pO1xuICAgIH1cbiAgICBjb25zdCBhdXRvQWxsb2NhdGVDaHVua1NpemUgPSB1bmRlcmx5aW5nQnl0ZVNvdXJjZS5hdXRvQWxsb2NhdGVDaHVua1NpemU7XG4gICAgaWYgKGF1dG9BbGxvY2F0ZUNodW5rU2l6ZSA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdhdXRvQWxsb2NhdGVDaHVua1NpemUgbXVzdCBiZSBncmVhdGVyIHRoYW4gMCcpO1xuICAgIH1cbiAgICBTZXRVcFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCBzdGFydEFsZ29yaXRobSwgcHVsbEFsZ29yaXRobSwgY2FuY2VsQWxnb3JpdGhtLCBoaWdoV2F0ZXJNYXJrLCBhdXRvQWxsb2NhdGVDaHVua1NpemUpO1xufVxuZnVuY3Rpb24gU2V0VXBSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0KHJlcXVlc3QsIGNvbnRyb2xsZXIsIHZpZXcpIHtcbiAgICByZXF1ZXN0Ll9hc3NvY2lhdGVkUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlciA9IGNvbnRyb2xsZXI7XG4gICAgcmVxdWVzdC5fdmlldyA9IHZpZXc7XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdC5cbmZ1bmN0aW9uIGJ5b2JSZXF1ZXN0QnJhbmRDaGVja0V4Y2VwdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoYFJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3QucHJvdG90eXBlLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3RgKTtcbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLlxuZnVuY3Rpb24gYnl0ZVN0cmVhbUNvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlci5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcmApO1xufVxuXG4vLyBBYnN0cmFjdCBvcGVyYXRpb25zIGZvciB0aGUgUmVhZGFibGVTdHJlYW0uXG5mdW5jdGlvbiBBY3F1aXJlUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyKHN0cmVhbSkge1xuICAgIHJldHVybiBuZXcgUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyKHN0cmVhbSk7XG59XG4vLyBSZWFkYWJsZVN0cmVhbSBBUEkgZXhwb3NlZCBmb3IgY29udHJvbGxlcnMuXG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUFkZFJlYWRJbnRvUmVxdWVzdChzdHJlYW0sIHJlYWRJbnRvUmVxdWVzdCkge1xuICAgIHN0cmVhbS5fcmVhZGVyLl9yZWFkSW50b1JlcXVlc3RzLnB1c2gocmVhZEludG9SZXF1ZXN0KTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRnVsZmlsbFJlYWRJbnRvUmVxdWVzdChzdHJlYW0sIGNodW5rLCBkb25lKSB7XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLl9yZWFkZXI7XG4gICAgY29uc3QgcmVhZEludG9SZXF1ZXN0ID0gcmVhZGVyLl9yZWFkSW50b1JlcXVlc3RzLnNoaWZ0KCk7XG4gICAgaWYgKGRvbmUpIHtcbiAgICAgICAgcmVhZEludG9SZXF1ZXN0Ll9jbG9zZVN0ZXBzKGNodW5rKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJlYWRJbnRvUmVxdWVzdC5fY2h1bmtTdGVwcyhjaHVuayk7XG4gICAgfVxufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1HZXROdW1SZWFkSW50b1JlcXVlc3RzKHN0cmVhbSkge1xuICAgIHJldHVybiBzdHJlYW0uX3JlYWRlci5fcmVhZEludG9SZXF1ZXN0cy5sZW5ndGg7XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUhhc0JZT0JSZWFkZXIoc3RyZWFtKSB7XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLl9yZWFkZXI7XG4gICAgaWYgKHJlYWRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtQllPQlJlYWRlcihyZWFkZXIpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG4vKipcbiAqIEEgQllPQiByZWFkZXIgdmVuZGVkIGJ5IGEge0BsaW5rIFJlYWRhYmxlU3RyZWFtfS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIFJlYWRhYmxlU3RyZWFtQllPQlJlYWRlciB7XG4gICAgY29uc3RydWN0b3Ioc3RyZWFtKSB7XG4gICAgICAgIGFzc2VydFJlcXVpcmVkQXJndW1lbnQoc3RyZWFtLCAxLCAnUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyJyk7XG4gICAgICAgIGFzc2VydFJlYWRhYmxlU3RyZWFtKHN0cmVhbSwgJ0ZpcnN0IHBhcmFtZXRlcicpO1xuICAgICAgICBpZiAoSXNSZWFkYWJsZVN0cmVhbUxvY2tlZChzdHJlYW0pKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGlzIHN0cmVhbSBoYXMgYWxyZWFkeSBiZWVuIGxvY2tlZCBmb3IgZXhjbHVzaXZlIHJlYWRpbmcgYnkgYW5vdGhlciByZWFkZXInKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIUlzUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcihzdHJlYW0uX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjb25zdHJ1Y3QgYSBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIgZm9yIGEgc3RyZWFtIG5vdCBjb25zdHJ1Y3RlZCB3aXRoIGEgYnl0ZSAnICtcbiAgICAgICAgICAgICAgICAnc291cmNlJyk7XG4gICAgICAgIH1cbiAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljSW5pdGlhbGl6ZSh0aGlzLCBzdHJlYW0pO1xuICAgICAgICB0aGlzLl9yZWFkSW50b1JlcXVlc3RzID0gbmV3IFNpbXBsZVF1ZXVlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBwcm9taXNlIHRoYXQgd2lsbCBiZSBmdWxmaWxsZWQgd2hlbiB0aGUgc3RyZWFtIGJlY29tZXMgY2xvc2VkLCBvciByZWplY3RlZCBpZiB0aGUgc3RyZWFtIGV2ZXIgZXJyb3JzIG9yXG4gICAgICogdGhlIHJlYWRlcidzIGxvY2sgaXMgcmVsZWFzZWQgYmVmb3JlIHRoZSBzdHJlYW0gZmluaXNoZXMgY2xvc2luZy5cbiAgICAgKi9cbiAgICBnZXQgY2xvc2VkKCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChieW9iUmVhZGVyQnJhbmRDaGVja0V4Y2VwdGlvbignY2xvc2VkJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9jbG9zZWRQcm9taXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgcmVhZGVyIGlzIGFjdGl2ZSwgYmVoYXZlcyB0aGUgc2FtZSBhcyB7QGxpbmsgUmVhZGFibGVTdHJlYW0uY2FuY2VsIHwgc3RyZWFtLmNhbmNlbChyZWFzb24pfS5cbiAgICAgKi9cbiAgICBjYW5jZWwocmVhc29uID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGJ5b2JSZWFkZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdjYW5jZWwnKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX293bmVyUmVhZGFibGVTdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgocmVhZGVyTG9ja0V4Y2VwdGlvbignY2FuY2VsJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNDYW5jZWwodGhpcywgcmVhc29uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXR0ZW1wdHMgdG8gcmVhZHMgYnl0ZXMgaW50byB2aWV3LCBhbmQgcmV0dXJucyBhIHByb21pc2UgcmVzb2x2ZWQgd2l0aCB0aGUgcmVzdWx0LlxuICAgICAqXG4gICAgICogSWYgcmVhZGluZyBhIGNodW5rIGNhdXNlcyB0aGUgcXVldWUgdG8gYmVjb21lIGVtcHR5LCBtb3JlIGRhdGEgd2lsbCBiZSBwdWxsZWQgZnJvbSB0aGUgdW5kZXJseWluZyBzb3VyY2UuXG4gICAgICovXG4gICAgcmVhZCh2aWV3KSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGJ5b2JSZWFkZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdyZWFkJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghQXJyYXlCdWZmZXIuaXNWaWV3KHZpZXcpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCd2aWV3IG11c3QgYmUgYW4gYXJyYXkgYnVmZmVyIHZpZXcnKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZpZXcuYnl0ZUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgobmV3IFR5cGVFcnJvcigndmlldyBtdXN0IGhhdmUgbm9uLXplcm8gYnl0ZUxlbmd0aCcpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmlldy5idWZmZXIuYnl0ZUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgobmV3IFR5cGVFcnJvcihgdmlldydzIGJ1ZmZlciBtdXN0IGhhdmUgbm9uLXplcm8gYnl0ZUxlbmd0aGApKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoSXNEZXRhY2hlZEJ1ZmZlcih2aWV3LmJ1ZmZlcikpIDtcbiAgICAgICAgaWYgKHRoaXMuX293bmVyUmVhZGFibGVTdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgocmVhZGVyTG9ja0V4Y2VwdGlvbigncmVhZCBmcm9tJykpO1xuICAgICAgICB9XG4gICAgICAgIGxldCByZXNvbHZlUHJvbWlzZTtcbiAgICAgICAgbGV0IHJlamVjdFByb21pc2U7XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuZXdQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHJlc29sdmVQcm9taXNlID0gcmVzb2x2ZTtcbiAgICAgICAgICAgIHJlamVjdFByb21pc2UgPSByZWplY3Q7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByZWFkSW50b1JlcXVlc3QgPSB7XG4gICAgICAgICAgICBfY2h1bmtTdGVwczogY2h1bmsgPT4gcmVzb2x2ZVByb21pc2UoeyB2YWx1ZTogY2h1bmssIGRvbmU6IGZhbHNlIH0pLFxuICAgICAgICAgICAgX2Nsb3NlU3RlcHM6IGNodW5rID0+IHJlc29sdmVQcm9taXNlKHsgdmFsdWU6IGNodW5rLCBkb25lOiB0cnVlIH0pLFxuICAgICAgICAgICAgX2Vycm9yU3RlcHM6IGUgPT4gcmVqZWN0UHJvbWlzZShlKVxuICAgICAgICB9O1xuICAgICAgICBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXJSZWFkKHRoaXMsIHZpZXcsIHJlYWRJbnRvUmVxdWVzdCk7XG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWxlYXNlcyB0aGUgcmVhZGVyJ3MgbG9jayBvbiB0aGUgY29ycmVzcG9uZGluZyBzdHJlYW0uIEFmdGVyIHRoZSBsb2NrIGlzIHJlbGVhc2VkLCB0aGUgcmVhZGVyIGlzIG5vIGxvbmdlciBhY3RpdmUuXG4gICAgICogSWYgdGhlIGFzc29jaWF0ZWQgc3RyZWFtIGlzIGVycm9yZWQgd2hlbiB0aGUgbG9jayBpcyByZWxlYXNlZCwgdGhlIHJlYWRlciB3aWxsIGFwcGVhciBlcnJvcmVkIGluIHRoZSBzYW1lIHdheVxuICAgICAqIGZyb20gbm93IG9uOyBvdGhlcndpc2UsIHRoZSByZWFkZXIgd2lsbCBhcHBlYXIgY2xvc2VkLlxuICAgICAqXG4gICAgICogQSByZWFkZXIncyBsb2NrIGNhbm5vdCBiZSByZWxlYXNlZCB3aGlsZSBpdCBzdGlsbCBoYXMgYSBwZW5kaW5nIHJlYWQgcmVxdWVzdCwgaS5lLiwgaWYgYSBwcm9taXNlIHJldHVybmVkIGJ5XG4gICAgICogdGhlIHJlYWRlcidzIHtAbGluayBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIucmVhZCB8IHJlYWQoKX0gbWV0aG9kIGhhcyBub3QgeWV0IGJlZW4gc2V0dGxlZC4gQXR0ZW1wdGluZyB0b1xuICAgICAqIGRvIHNvIHdpbGwgdGhyb3cgYSBgVHlwZUVycm9yYCBhbmQgbGVhdmUgdGhlIHJlYWRlciBsb2NrZWQgdG8gdGhlIHN0cmVhbS5cbiAgICAgKi9cbiAgICByZWxlYXNlTG9jaygpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtQllPQlJlYWRlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgYnlvYlJlYWRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ3JlbGVhc2VMb2NrJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX293bmVyUmVhZGFibGVTdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9yZWFkSW50b1JlcXVlc3RzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RyaWVkIHRvIHJlbGVhc2UgYSByZWFkZXIgbG9jayB3aGVuIHRoYXQgcmVhZGVyIGhhcyBwZW5kaW5nIHJlYWQoKSBjYWxscyB1bi1zZXR0bGVkJyk7XG4gICAgICAgIH1cbiAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljUmVsZWFzZSh0aGlzKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIucHJvdG90eXBlLCB7XG4gICAgY2FuY2VsOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICByZWFkOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICByZWxlYXNlTG9jazogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgY2xvc2VkOiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIucHJvdG90eXBlLCBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZywge1xuICAgICAgICB2YWx1ZTogJ1JlYWRhYmxlU3RyZWFtQllPQlJlYWRlcicsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBmb3IgdGhlIHJlYWRlcnMuXG5mdW5jdGlvbiBJc1JlYWRhYmxlU3RyZWFtQllPQlJlYWRlcih4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX3JlYWRJbnRvUmVxdWVzdHMnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyUmVhZChyZWFkZXIsIHZpZXcsIHJlYWRJbnRvUmVxdWVzdCkge1xuICAgIGNvbnN0IHN0cmVhbSA9IHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbTtcbiAgICBzdHJlYW0uX2Rpc3R1cmJlZCA9IHRydWU7XG4gICAgaWYgKHN0cmVhbS5fc3RhdGUgPT09ICdlcnJvcmVkJykge1xuICAgICAgICByZWFkSW50b1JlcXVlc3QuX2Vycm9yU3RlcHMoc3RyZWFtLl9zdG9yZWRFcnJvcik7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUHVsbEludG8oc3RyZWFtLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIHZpZXcsIHJlYWRJbnRvUmVxdWVzdCk7XG4gICAgfVxufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtQllPQlJlYWRlci5cbmZ1bmN0aW9uIGJ5b2JSZWFkZXJCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyLnByb3RvdHlwZS4ke25hbWV9IGNhbiBvbmx5IGJlIHVzZWQgb24gYSBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXJgKTtcbn1cblxuZnVuY3Rpb24gRXh0cmFjdEhpZ2hXYXRlck1hcmsoc3RyYXRlZ3ksIGRlZmF1bHRIV00pIHtcbiAgICBjb25zdCB7IGhpZ2hXYXRlck1hcmsgfSA9IHN0cmF0ZWd5O1xuICAgIGlmIChoaWdoV2F0ZXJNYXJrID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRIV007XG4gICAgfVxuICAgIGlmIChOdW1iZXJJc05hTihoaWdoV2F0ZXJNYXJrKSB8fCBoaWdoV2F0ZXJNYXJrIDwgMCkge1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW52YWxpZCBoaWdoV2F0ZXJNYXJrJyk7XG4gICAgfVxuICAgIHJldHVybiBoaWdoV2F0ZXJNYXJrO1xufVxuZnVuY3Rpb24gRXh0cmFjdFNpemVBbGdvcml0aG0oc3RyYXRlZ3kpIHtcbiAgICBjb25zdCB7IHNpemUgfSA9IHN0cmF0ZWd5O1xuICAgIGlmICghc2l6ZSkge1xuICAgICAgICByZXR1cm4gKCkgPT4gMTtcbiAgICB9XG4gICAgcmV0dXJuIHNpemU7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRRdWV1aW5nU3RyYXRlZ3koaW5pdCwgY29udGV4dCkge1xuICAgIGFzc2VydERpY3Rpb25hcnkoaW5pdCwgY29udGV4dCk7XG4gICAgY29uc3QgaGlnaFdhdGVyTWFyayA9IGluaXQgPT09IG51bGwgfHwgaW5pdCA9PT0gdm9pZCAwID8gdm9pZCAwIDogaW5pdC5oaWdoV2F0ZXJNYXJrO1xuICAgIGNvbnN0IHNpemUgPSBpbml0ID09PSBudWxsIHx8IGluaXQgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGluaXQuc2l6ZTtcbiAgICByZXR1cm4ge1xuICAgICAgICBoaWdoV2F0ZXJNYXJrOiBoaWdoV2F0ZXJNYXJrID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBjb252ZXJ0VW5yZXN0cmljdGVkRG91YmxlKGhpZ2hXYXRlck1hcmspLFxuICAgICAgICBzaXplOiBzaXplID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBjb252ZXJ0UXVldWluZ1N0cmF0ZWd5U2l6ZShzaXplLCBgJHtjb250ZXh0fSBoYXMgbWVtYmVyICdzaXplJyB0aGF0YClcbiAgICB9O1xufVxuZnVuY3Rpb24gY29udmVydFF1ZXVpbmdTdHJhdGVneVNpemUoZm4sIGNvbnRleHQpIHtcbiAgICBhc3NlcnRGdW5jdGlvbihmbiwgY29udGV4dCk7XG4gICAgcmV0dXJuIGNodW5rID0+IGNvbnZlcnRVbnJlc3RyaWN0ZWREb3VibGUoZm4oY2h1bmspKTtcbn1cblxuZnVuY3Rpb24gY29udmVydFVuZGVybHlpbmdTaW5rKG9yaWdpbmFsLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RGljdGlvbmFyeShvcmlnaW5hbCwgY29udGV4dCk7XG4gICAgY29uc3QgYWJvcnQgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwuYWJvcnQ7XG4gICAgY29uc3QgY2xvc2UgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwuY2xvc2U7XG4gICAgY29uc3Qgc3RhcnQgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwuc3RhcnQ7XG4gICAgY29uc3QgdHlwZSA9IG9yaWdpbmFsID09PSBudWxsIHx8IG9yaWdpbmFsID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcmlnaW5hbC50eXBlO1xuICAgIGNvbnN0IHdyaXRlID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLndyaXRlO1xuICAgIHJldHVybiB7XG4gICAgICAgIGFib3J0OiBhYm9ydCA9PT0gdW5kZWZpbmVkID9cbiAgICAgICAgICAgIHVuZGVmaW5lZCA6XG4gICAgICAgICAgICBjb252ZXJ0VW5kZXJseWluZ1NpbmtBYm9ydENhbGxiYWNrKGFib3J0LCBvcmlnaW5hbCwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnYWJvcnQnIHRoYXRgKSxcbiAgICAgICAgY2xvc2U6IGNsb3NlID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgIGNvbnZlcnRVbmRlcmx5aW5nU2lua0Nsb3NlQ2FsbGJhY2soY2xvc2UsIG9yaWdpbmFsLCBgJHtjb250ZXh0fSBoYXMgbWVtYmVyICdjbG9zZScgdGhhdGApLFxuICAgICAgICBzdGFydDogc3RhcnQgPT09IHVuZGVmaW5lZCA/XG4gICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgY29udmVydFVuZGVybHlpbmdTaW5rU3RhcnRDYWxsYmFjayhzdGFydCwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3N0YXJ0JyB0aGF0YCksXG4gICAgICAgIHdyaXRlOiB3cml0ZSA9PT0gdW5kZWZpbmVkID9cbiAgICAgICAgICAgIHVuZGVmaW5lZCA6XG4gICAgICAgICAgICBjb252ZXJ0VW5kZXJseWluZ1NpbmtXcml0ZUNhbGxiYWNrKHdyaXRlLCBvcmlnaW5hbCwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnd3JpdGUnIHRoYXRgKSxcbiAgICAgICAgdHlwZVxuICAgIH07XG59XG5mdW5jdGlvbiBjb252ZXJ0VW5kZXJseWluZ1NpbmtBYm9ydENhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKHJlYXNvbikgPT4gcHJvbWlzZUNhbGwoZm4sIG9yaWdpbmFsLCBbcmVhc29uXSk7XG59XG5mdW5jdGlvbiBjb252ZXJ0VW5kZXJseWluZ1NpbmtDbG9zZUNhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKCkgPT4gcHJvbWlzZUNhbGwoZm4sIG9yaWdpbmFsLCBbXSk7XG59XG5mdW5jdGlvbiBjb252ZXJ0VW5kZXJseWluZ1NpbmtTdGFydENhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKGNvbnRyb2xsZXIpID0+IHJlZmxlY3RDYWxsKGZuLCBvcmlnaW5hbCwgW2NvbnRyb2xsZXJdKTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nU2lua1dyaXRlQ2FsbGJhY2soZm4sIG9yaWdpbmFsLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RnVuY3Rpb24oZm4sIGNvbnRleHQpO1xuICAgIHJldHVybiAoY2h1bmssIGNvbnRyb2xsZXIpID0+IHByb21pc2VDYWxsKGZuLCBvcmlnaW5hbCwgW2NodW5rLCBjb250cm9sbGVyXSk7XG59XG5cbmZ1bmN0aW9uIGFzc2VydFdyaXRhYmxlU3RyZWFtKHgsIGNvbnRleHQpIHtcbiAgICBpZiAoIUlzV3JpdGFibGVTdHJlYW0oeCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjb250ZXh0fSBpcyBub3QgYSBXcml0YWJsZVN0cmVhbS5gKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGlzQWJvcnRTaWduYWwodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JyB8fCB2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUuYWJvcnRlZCA9PT0gJ2Jvb2xlYW4nO1xuICAgIH1cbiAgICBjYXRjaCAoX2EpIHtcbiAgICAgICAgLy8gQWJvcnRTaWduYWwucHJvdG90eXBlLmFib3J0ZWQgdGhyb3dzIGlmIGl0cyBicmFuZCBjaGVjayBmYWlsc1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuY29uc3Qgc3VwcG9ydHNBYm9ydENvbnRyb2xsZXIgPSB0eXBlb2YgQWJvcnRDb250cm9sbGVyID09PSAnZnVuY3Rpb24nO1xuLyoqXG4gKiBDb25zdHJ1Y3QgYSBuZXcgQWJvcnRDb250cm9sbGVyLCBpZiBzdXBwb3J0ZWQgYnkgdGhlIHBsYXRmb3JtLlxuICpcbiAqIEBpbnRlcm5hbFxuICovXG5mdW5jdGlvbiBjcmVhdGVBYm9ydENvbnRyb2xsZXIoKSB7XG4gICAgaWYgKHN1cHBvcnRzQWJvcnRDb250cm9sbGVyKSB7XG4gICAgICAgIHJldHVybiBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogQSB3cml0YWJsZSBzdHJlYW0gcmVwcmVzZW50cyBhIGRlc3RpbmF0aW9uIGZvciBkYXRhLCBpbnRvIHdoaWNoIHlvdSBjYW4gd3JpdGUuXG4gKlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBXcml0YWJsZVN0cmVhbSB7XG4gICAgY29uc3RydWN0b3IocmF3VW5kZXJseWluZ1NpbmsgPSB7fSwgcmF3U3RyYXRlZ3kgPSB7fSkge1xuICAgICAgICBpZiAocmF3VW5kZXJseWluZ1NpbmsgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmF3VW5kZXJseWluZ1NpbmsgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgYXNzZXJ0T2JqZWN0KHJhd1VuZGVybHlpbmdTaW5rLCAnRmlyc3QgcGFyYW1ldGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RyYXRlZ3kgPSBjb252ZXJ0UXVldWluZ1N0cmF0ZWd5KHJhd1N0cmF0ZWd5LCAnU2Vjb25kIHBhcmFtZXRlcicpO1xuICAgICAgICBjb25zdCB1bmRlcmx5aW5nU2luayA9IGNvbnZlcnRVbmRlcmx5aW5nU2luayhyYXdVbmRlcmx5aW5nU2luaywgJ0ZpcnN0IHBhcmFtZXRlcicpO1xuICAgICAgICBJbml0aWFsaXplV3JpdGFibGVTdHJlYW0odGhpcyk7XG4gICAgICAgIGNvbnN0IHR5cGUgPSB1bmRlcmx5aW5nU2luay50eXBlO1xuICAgICAgICBpZiAodHlwZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW52YWxpZCB0eXBlIGlzIHNwZWNpZmllZCcpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNpemVBbGdvcml0aG0gPSBFeHRyYWN0U2l6ZUFsZ29yaXRobShzdHJhdGVneSk7XG4gICAgICAgIGNvbnN0IGhpZ2hXYXRlck1hcmsgPSBFeHRyYWN0SGlnaFdhdGVyTWFyayhzdHJhdGVneSwgMSk7XG4gICAgICAgIFNldFVwV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckZyb21VbmRlcmx5aW5nU2luayh0aGlzLCB1bmRlcmx5aW5nU2luaywgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIHdyaXRhYmxlIHN0cmVhbSBpcyBsb2NrZWQgdG8gYSB3cml0ZXIuXG4gICAgICovXG4gICAgZ2V0IGxvY2tlZCgpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDIoJ2xvY2tlZCcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBJc1dyaXRhYmxlU3RyZWFtTG9ja2VkKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBYm9ydHMgdGhlIHN0cmVhbSwgc2lnbmFsaW5nIHRoYXQgdGhlIHByb2R1Y2VyIGNhbiBubyBsb25nZXIgc3VjY2Vzc2Z1bGx5IHdyaXRlIHRvIHRoZSBzdHJlYW0gYW5kIGl0IGlzIHRvIGJlXG4gICAgICogaW1tZWRpYXRlbHkgbW92ZWQgdG8gYW4gZXJyb3JlZCBzdGF0ZSwgd2l0aCBhbnkgcXVldWVkLXVwIHdyaXRlcyBkaXNjYXJkZWQuIFRoaXMgd2lsbCBhbHNvIGV4ZWN1dGUgYW55IGFib3J0XG4gICAgICogbWVjaGFuaXNtIG9mIHRoZSB1bmRlcmx5aW5nIHNpbmsuXG4gICAgICpcbiAgICAgKiBUaGUgcmV0dXJuZWQgcHJvbWlzZSB3aWxsIGZ1bGZpbGwgaWYgdGhlIHN0cmVhbSBzaHV0cyBkb3duIHN1Y2Nlc3NmdWxseSwgb3IgcmVqZWN0IGlmIHRoZSB1bmRlcmx5aW5nIHNpbmsgc2lnbmFsZWRcbiAgICAgKiB0aGF0IHRoZXJlIHdhcyBhbiBlcnJvciBkb2luZyBzby4gQWRkaXRpb25hbGx5LCBpdCB3aWxsIHJlamVjdCB3aXRoIGEgYFR5cGVFcnJvcmAgKHdpdGhvdXQgYXR0ZW1wdGluZyB0byBjYW5jZWxcbiAgICAgKiB0aGUgc3RyZWFtKSBpZiB0aGUgc3RyZWFtIGlzIGN1cnJlbnRseSBsb2NrZWQuXG4gICAgICovXG4gICAgYWJvcnQocmVhc29uID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbSh0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbiQyKCdhYm9ydCcpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoSXNXcml0YWJsZVN0cmVhbUxvY2tlZCh0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgobmV3IFR5cGVFcnJvcignQ2Fubm90IGFib3J0IGEgc3RyZWFtIHRoYXQgYWxyZWFkeSBoYXMgYSB3cml0ZXInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFdyaXRhYmxlU3RyZWFtQWJvcnQodGhpcywgcmVhc29uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xvc2VzIHRoZSBzdHJlYW0uIFRoZSB1bmRlcmx5aW5nIHNpbmsgd2lsbCBmaW5pc2ggcHJvY2Vzc2luZyBhbnkgcHJldmlvdXNseS13cml0dGVuIGNodW5rcywgYmVmb3JlIGludm9raW5nIGl0c1xuICAgICAqIGNsb3NlIGJlaGF2aW9yLiBEdXJpbmcgdGhpcyB0aW1lIGFueSBmdXJ0aGVyIGF0dGVtcHRzIHRvIHdyaXRlIHdpbGwgZmFpbCAod2l0aG91dCBlcnJvcmluZyB0aGUgc3RyZWFtKS5cbiAgICAgKlxuICAgICAqIFRoZSBtZXRob2QgcmV0dXJucyBhIHByb21pc2UgdGhhdCB3aWxsIGZ1bGZpbGwgaWYgYWxsIHJlbWFpbmluZyBjaHVua3MgYXJlIHN1Y2Nlc3NmdWxseSB3cml0dGVuIGFuZCB0aGUgc3RyZWFtXG4gICAgICogc3VjY2Vzc2Z1bGx5IGNsb3Nlcywgb3IgcmVqZWN0cyBpZiBhbiBlcnJvciBpcyBlbmNvdW50ZXJlZCBkdXJpbmcgdGhpcyBwcm9jZXNzLiBBZGRpdGlvbmFsbHksIGl0IHdpbGwgcmVqZWN0IHdpdGhcbiAgICAgKiBhIGBUeXBlRXJyb3JgICh3aXRob3V0IGF0dGVtcHRpbmcgdG8gY2FuY2VsIHRoZSBzdHJlYW0pIGlmIHRoZSBzdHJlYW0gaXMgY3VycmVudGx5IGxvY2tlZC5cbiAgICAgKi9cbiAgICBjbG9zZSgpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDIoJ2Nsb3NlJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChJc1dyaXRhYmxlU3RyZWFtTG9ja2VkKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2xvc2UgYSBzdHJlYW0gdGhhdCBhbHJlYWR5IGhhcyBhIHdyaXRlcicpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoV3JpdGFibGVTdHJlYW1DbG9zZVF1ZXVlZE9ySW5GbGlnaHQodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjbG9zZSBhbiBhbHJlYWR5LWNsb3Npbmcgc3RyZWFtJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBXcml0YWJsZVN0cmVhbUNsb3NlKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEge0BsaW5rIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlciB8IHdyaXRlcn0gYW5kIGxvY2tzIHRoZSBzdHJlYW0gdG8gdGhlIG5ldyB3cml0ZXIuIFdoaWxlIHRoZSBzdHJlYW1cbiAgICAgKiBpcyBsb2NrZWQsIG5vIG90aGVyIHdyaXRlciBjYW4gYmUgYWNxdWlyZWQgdW50aWwgdGhpcyBvbmUgaXMgcmVsZWFzZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIGZ1bmN0aW9uYWxpdHkgaXMgZXNwZWNpYWxseSB1c2VmdWwgZm9yIGNyZWF0aW5nIGFic3RyYWN0aW9ucyB0aGF0IGRlc2lyZSB0aGUgYWJpbGl0eSB0byB3cml0ZSB0byBhIHN0cmVhbVxuICAgICAqIHdpdGhvdXQgaW50ZXJydXB0aW9uIG9yIGludGVybGVhdmluZy4gQnkgZ2V0dGluZyBhIHdyaXRlciBmb3IgdGhlIHN0cmVhbSwgeW91IGNhbiBlbnN1cmUgbm9ib2R5IGVsc2UgY2FuIHdyaXRlIGF0XG4gICAgICogdGhlIHNhbWUgdGltZSwgd2hpY2ggd291bGQgY2F1c2UgdGhlIHJlc3VsdGluZyB3cml0dGVuIGRhdGEgdG8gYmUgdW5wcmVkaWN0YWJsZSBhbmQgcHJvYmFibHkgdXNlbGVzcy5cbiAgICAgKi9cbiAgICBnZXRXcml0ZXIoKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbSh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbiQyKCdnZXRXcml0ZXInKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gQWNxdWlyZVdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcih0aGlzKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhXcml0YWJsZVN0cmVhbS5wcm90b3R5cGUsIHtcbiAgICBhYm9ydDogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgY2xvc2U6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGdldFdyaXRlcjogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgbG9ja2VkOiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZVN0cmVhbS5wcm90b3R5cGUsIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIHZhbHVlOiAnV3JpdGFibGVTdHJlYW0nLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbn1cbi8vIEFic3RyYWN0IG9wZXJhdGlvbnMgZm9yIHRoZSBXcml0YWJsZVN0cmVhbS5cbmZ1bmN0aW9uIEFjcXVpcmVXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIoc3RyZWFtKSB7XG4gICAgcmV0dXJuIG5ldyBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIoc3RyZWFtKTtcbn1cbi8vIFRocm93cyBpZiBhbmQgb25seSBpZiBzdGFydEFsZ29yaXRobSB0aHJvd3MuXG5mdW5jdGlvbiBDcmVhdGVXcml0YWJsZVN0cmVhbShzdGFydEFsZ29yaXRobSwgd3JpdGVBbGdvcml0aG0sIGNsb3NlQWxnb3JpdGhtLCBhYm9ydEFsZ29yaXRobSwgaGlnaFdhdGVyTWFyayA9IDEsIHNpemVBbGdvcml0aG0gPSAoKSA9PiAxKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gT2JqZWN0LmNyZWF0ZShXcml0YWJsZVN0cmVhbS5wcm90b3R5cGUpO1xuICAgIEluaXRpYWxpemVXcml0YWJsZVN0cmVhbShzdHJlYW0pO1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBPYmplY3QuY3JlYXRlKFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlKTtcbiAgICBTZXRVcFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCBzdGFydEFsZ29yaXRobSwgd3JpdGVBbGdvcml0aG0sIGNsb3NlQWxnb3JpdGhtLCBhYm9ydEFsZ29yaXRobSwgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSk7XG4gICAgcmV0dXJuIHN0cmVhbTtcbn1cbmZ1bmN0aW9uIEluaXRpYWxpemVXcml0YWJsZVN0cmVhbShzdHJlYW0pIHtcbiAgICBzdHJlYW0uX3N0YXRlID0gJ3dyaXRhYmxlJztcbiAgICAvLyBUaGUgZXJyb3IgdGhhdCB3aWxsIGJlIHJlcG9ydGVkIGJ5IG5ldyBtZXRob2QgY2FsbHMgb25jZSB0aGUgc3RhdGUgYmVjb21lcyBlcnJvcmVkLiBPbmx5IHNldCB3aGVuIFtbc3RhdGVdXSBpc1xuICAgIC8vICdlcnJvcmluZycgb3IgJ2Vycm9yZWQnLiBNYXkgYmUgc2V0IHRvIGFuIHVuZGVmaW5lZCB2YWx1ZS5cbiAgICBzdHJlYW0uX3N0b3JlZEVycm9yID0gdW5kZWZpbmVkO1xuICAgIHN0cmVhbS5fd3JpdGVyID0gdW5kZWZpbmVkO1xuICAgIC8vIEluaXRpYWxpemUgdG8gdW5kZWZpbmVkIGZpcnN0IGJlY2F1c2UgdGhlIGNvbnN0cnVjdG9yIG9mIHRoZSBjb250cm9sbGVyIGNoZWNrcyB0aGlzXG4gICAgLy8gdmFyaWFibGUgdG8gdmFsaWRhdGUgdGhlIGNhbGxlci5cbiAgICBzdHJlYW0uX3dyaXRhYmxlU3RyZWFtQ29udHJvbGxlciA9IHVuZGVmaW5lZDtcbiAgICAvLyBUaGlzIHF1ZXVlIGlzIHBsYWNlZCBoZXJlIGluc3RlYWQgb2YgdGhlIHdyaXRlciBjbGFzcyBpbiBvcmRlciB0byBhbGxvdyBmb3IgcGFzc2luZyBhIHdyaXRlciB0byB0aGUgbmV4dCBkYXRhXG4gICAgLy8gcHJvZHVjZXIgd2l0aG91dCB3YWl0aW5nIGZvciB0aGUgcXVldWVkIHdyaXRlcyB0byBmaW5pc2guXG4gICAgc3RyZWFtLl93cml0ZVJlcXVlc3RzID0gbmV3IFNpbXBsZVF1ZXVlKCk7XG4gICAgLy8gV3JpdGUgcmVxdWVzdHMgYXJlIHJlbW92ZWQgZnJvbSBfd3JpdGVSZXF1ZXN0cyB3aGVuIHdyaXRlKCkgaXMgY2FsbGVkIG9uIHRoZSB1bmRlcmx5aW5nIHNpbmsuIFRoaXMgcHJldmVudHNcbiAgICAvLyB0aGVtIGZyb20gYmVpbmcgZXJyb25lb3VzbHkgcmVqZWN0ZWQgb24gZXJyb3IuIElmIGEgd3JpdGUoKSBjYWxsIGlzIGluLWZsaWdodCwgdGhlIHJlcXVlc3QgaXMgc3RvcmVkIGhlcmUuXG4gICAgc3RyZWFtLl9pbkZsaWdodFdyaXRlUmVxdWVzdCA9IHVuZGVmaW5lZDtcbiAgICAvLyBUaGUgcHJvbWlzZSB0aGF0IHdhcyByZXR1cm5lZCBmcm9tIHdyaXRlci5jbG9zZSgpLiBTdG9yZWQgaGVyZSBiZWNhdXNlIGl0IG1heSBiZSBmdWxmaWxsZWQgYWZ0ZXIgdGhlIHdyaXRlclxuICAgIC8vIGhhcyBiZWVuIGRldGFjaGVkLlxuICAgIHN0cmVhbS5fY2xvc2VSZXF1ZXN0ID0gdW5kZWZpbmVkO1xuICAgIC8vIENsb3NlIHJlcXVlc3QgaXMgcmVtb3ZlZCBmcm9tIF9jbG9zZVJlcXVlc3Qgd2hlbiBjbG9zZSgpIGlzIGNhbGxlZCBvbiB0aGUgdW5kZXJseWluZyBzaW5rLiBUaGlzIHByZXZlbnRzIGl0XG4gICAgLy8gZnJvbSBiZWluZyBlcnJvbmVvdXNseSByZWplY3RlZCBvbiBlcnJvci4gSWYgYSBjbG9zZSgpIGNhbGwgaXMgaW4tZmxpZ2h0LCB0aGUgcmVxdWVzdCBpcyBzdG9yZWQgaGVyZS5cbiAgICBzdHJlYW0uX2luRmxpZ2h0Q2xvc2VSZXF1ZXN0ID0gdW5kZWZpbmVkO1xuICAgIC8vIFRoZSBwcm9taXNlIHRoYXQgd2FzIHJldHVybmVkIGZyb20gd3JpdGVyLmFib3J0KCkuIFRoaXMgbWF5IGFsc28gYmUgZnVsZmlsbGVkIGFmdGVyIHRoZSB3cml0ZXIgaGFzIGRldGFjaGVkLlxuICAgIHN0cmVhbS5fcGVuZGluZ0Fib3J0UmVxdWVzdCA9IHVuZGVmaW5lZDtcbiAgICAvLyBUaGUgYmFja3ByZXNzdXJlIHNpZ25hbCBzZXQgYnkgdGhlIGNvbnRyb2xsZXIuXG4gICAgc3RyZWFtLl9iYWNrcHJlc3N1cmUgPSBmYWxzZTtcbn1cbmZ1bmN0aW9uIElzV3JpdGFibGVTdHJlYW0oeCkge1xuICAgIGlmICghdHlwZUlzT2JqZWN0KHgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoeCwgJ193cml0YWJsZVN0cmVhbUNvbnRyb2xsZXInKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgV3JpdGFibGVTdHJlYW07XG59XG5mdW5jdGlvbiBJc1dyaXRhYmxlU3RyZWFtTG9ja2VkKHN0cmVhbSkge1xuICAgIGlmIChzdHJlYW0uX3dyaXRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbUFib3J0KHN0cmVhbSwgcmVhc29uKSB7XG4gICAgdmFyIF9hO1xuICAgIGlmIChzdHJlYW0uX3N0YXRlID09PSAnY2xvc2VkJyB8fCBzdHJlYW0uX3N0YXRlID09PSAnZXJyb3JlZCcpIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICB9XG4gICAgc3RyZWFtLl93cml0YWJsZVN0cmVhbUNvbnRyb2xsZXIuX2Fib3J0UmVhc29uID0gcmVhc29uO1xuICAgIChfYSA9IHN0cmVhbS5fd3JpdGFibGVTdHJlYW1Db250cm9sbGVyLl9hYm9ydENvbnRyb2xsZXIpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5hYm9ydCgpO1xuICAgIC8vIFR5cGVTY3JpcHQgbmFycm93cyB0aGUgdHlwZSBvZiBgc3RyZWFtLl9zdGF0ZWAgZG93biB0byAnd3JpdGFibGUnIHwgJ2Vycm9yaW5nJyxcbiAgICAvLyBidXQgaXQgZG9lc24ndCBrbm93IHRoYXQgc2lnbmFsaW5nIGFib3J0IHJ1bnMgYXV0aG9yIGNvZGUgdGhhdCBtaWdodCBoYXZlIGNoYW5nZWQgdGhlIHN0YXRlLlxuICAgIC8vIFdpZGVuIHRoZSB0eXBlIGFnYWluIGJ5IGNhc3RpbmcgdG8gV3JpdGFibGVTdHJlYW1TdGF0ZS5cbiAgICBjb25zdCBzdGF0ZSA9IHN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKHN0YXRlID09PSAnY2xvc2VkJyB8fCBzdGF0ZSA9PT0gJ2Vycm9yZWQnKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIGlmIChzdHJlYW0uX3BlbmRpbmdBYm9ydFJlcXVlc3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0Ll9wcm9taXNlO1xuICAgIH1cbiAgICBsZXQgd2FzQWxyZWFkeUVycm9yaW5nID0gZmFsc2U7XG4gICAgaWYgKHN0YXRlID09PSAnZXJyb3JpbmcnKSB7XG4gICAgICAgIHdhc0FscmVhZHlFcnJvcmluZyA9IHRydWU7XG4gICAgICAgIC8vIHJlYXNvbiB3aWxsIG5vdCBiZSB1c2VkLCBzbyBkb24ndCBrZWVwIGEgcmVmZXJlbmNlIHRvIGl0LlxuICAgICAgICByZWFzb24gPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGNvbnN0IHByb21pc2UgPSBuZXdQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0ID0ge1xuICAgICAgICAgICAgX3Byb21pc2U6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIF9yZXNvbHZlOiByZXNvbHZlLFxuICAgICAgICAgICAgX3JlamVjdDogcmVqZWN0LFxuICAgICAgICAgICAgX3JlYXNvbjogcmVhc29uLFxuICAgICAgICAgICAgX3dhc0FscmVhZHlFcnJvcmluZzogd2FzQWxyZWFkeUVycm9yaW5nXG4gICAgICAgIH07XG4gICAgfSk7XG4gICAgc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0Ll9wcm9taXNlID0gcHJvbWlzZTtcbiAgICBpZiAoIXdhc0FscmVhZHlFcnJvcmluZykge1xuICAgICAgICBXcml0YWJsZVN0cmVhbVN0YXJ0RXJyb3Jpbmcoc3RyZWFtLCByZWFzb24pO1xuICAgIH1cbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtQ2xvc2Uoc3RyZWFtKSB7XG4gICAgY29uc3Qgc3RhdGUgPSBzdHJlYW0uX3N0YXRlO1xuICAgIGlmIChzdGF0ZSA9PT0gJ2Nsb3NlZCcgfHwgc3RhdGUgPT09ICdlcnJvcmVkJykge1xuICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKGBUaGUgc3RyZWFtIChpbiAke3N0YXRlfSBzdGF0ZSkgaXMgbm90IGluIHRoZSB3cml0YWJsZSBzdGF0ZSBhbmQgY2Fubm90IGJlIGNsb3NlZGApKTtcbiAgICB9XG4gICAgY29uc3QgcHJvbWlzZSA9IG5ld1Byb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBjb25zdCBjbG9zZVJlcXVlc3QgPSB7XG4gICAgICAgICAgICBfcmVzb2x2ZTogcmVzb2x2ZSxcbiAgICAgICAgICAgIF9yZWplY3Q6IHJlamVjdFxuICAgICAgICB9O1xuICAgICAgICBzdHJlYW0uX2Nsb3NlUmVxdWVzdCA9IGNsb3NlUmVxdWVzdDtcbiAgICB9KTtcbiAgICBjb25zdCB3cml0ZXIgPSBzdHJlYW0uX3dyaXRlcjtcbiAgICBpZiAod3JpdGVyICE9PSB1bmRlZmluZWQgJiYgc3RyZWFtLl9iYWNrcHJlc3N1cmUgJiYgc3RhdGUgPT09ICd3cml0YWJsZScpIHtcbiAgICAgICAgZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc29sdmUod3JpdGVyKTtcbiAgICB9XG4gICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsb3NlKHN0cmVhbS5fd3JpdGFibGVTdHJlYW1Db250cm9sbGVyKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cbi8vIFdyaXRhYmxlU3RyZWFtIEFQSSBleHBvc2VkIGZvciBjb250cm9sbGVycy5cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtQWRkV3JpdGVSZXF1ZXN0KHN0cmVhbSkge1xuICAgIGNvbnN0IHByb21pc2UgPSBuZXdQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgY29uc3Qgd3JpdGVSZXF1ZXN0ID0ge1xuICAgICAgICAgICAgX3Jlc29sdmU6IHJlc29sdmUsXG4gICAgICAgICAgICBfcmVqZWN0OiByZWplY3RcbiAgICAgICAgfTtcbiAgICAgICAgc3RyZWFtLl93cml0ZVJlcXVlc3RzLnB1c2god3JpdGVSZXF1ZXN0KTtcbiAgICB9KTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVhbFdpdGhSZWplY3Rpb24oc3RyZWFtLCBlcnJvcikge1xuICAgIGNvbnN0IHN0YXRlID0gc3RyZWFtLl9zdGF0ZTtcbiAgICBpZiAoc3RhdGUgPT09ICd3cml0YWJsZScpIHtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1TdGFydEVycm9yaW5nKHN0cmVhbSwgZXJyb3IpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIFdyaXRhYmxlU3RyZWFtRmluaXNoRXJyb3Jpbmcoc3RyZWFtKTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtU3RhcnRFcnJvcmluZyhzdHJlYW0sIHJlYXNvbikge1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBzdHJlYW0uX3dyaXRhYmxlU3RyZWFtQ29udHJvbGxlcjtcbiAgICBzdHJlYW0uX3N0YXRlID0gJ2Vycm9yaW5nJztcbiAgICBzdHJlYW0uX3N0b3JlZEVycm9yID0gcmVhc29uO1xuICAgIGNvbnN0IHdyaXRlciA9IHN0cmVhbS5fd3JpdGVyO1xuICAgIGlmICh3cml0ZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJFbnN1cmVSZWFkeVByb21pc2VSZWplY3RlZCh3cml0ZXIsIHJlYXNvbik7XG4gICAgfVxuICAgIGlmICghV3JpdGFibGVTdHJlYW1IYXNPcGVyYXRpb25NYXJrZWRJbkZsaWdodChzdHJlYW0pICYmIGNvbnRyb2xsZXIuX3N0YXJ0ZWQpIHtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1GaW5pc2hFcnJvcmluZyhzdHJlYW0pO1xuICAgIH1cbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRmluaXNoRXJyb3Jpbmcoc3RyZWFtKSB7XG4gICAgc3RyZWFtLl9zdGF0ZSA9ICdlcnJvcmVkJztcbiAgICBzdHJlYW0uX3dyaXRhYmxlU3RyZWFtQ29udHJvbGxlcltFcnJvclN0ZXBzXSgpO1xuICAgIGNvbnN0IHN0b3JlZEVycm9yID0gc3RyZWFtLl9zdG9yZWRFcnJvcjtcbiAgICBzdHJlYW0uX3dyaXRlUmVxdWVzdHMuZm9yRWFjaCh3cml0ZVJlcXVlc3QgPT4ge1xuICAgICAgICB3cml0ZVJlcXVlc3QuX3JlamVjdChzdG9yZWRFcnJvcik7XG4gICAgfSk7XG4gICAgc3RyZWFtLl93cml0ZVJlcXVlc3RzID0gbmV3IFNpbXBsZVF1ZXVlKCk7XG4gICAgaWYgKHN0cmVhbS5fcGVuZGluZ0Fib3J0UmVxdWVzdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtUmVqZWN0Q2xvc2VBbmRDbG9zZWRQcm9taXNlSWZOZWVkZWQoc3RyZWFtKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBhYm9ydFJlcXVlc3QgPSBzdHJlYW0uX3BlbmRpbmdBYm9ydFJlcXVlc3Q7XG4gICAgc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0ID0gdW5kZWZpbmVkO1xuICAgIGlmIChhYm9ydFJlcXVlc3QuX3dhc0FscmVhZHlFcnJvcmluZykge1xuICAgICAgICBhYm9ydFJlcXVlc3QuX3JlamVjdChzdG9yZWRFcnJvcik7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtUmVqZWN0Q2xvc2VBbmRDbG9zZWRQcm9taXNlSWZOZWVkZWQoc3RyZWFtKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBwcm9taXNlID0gc3RyZWFtLl93cml0YWJsZVN0cmVhbUNvbnRyb2xsZXJbQWJvcnRTdGVwc10oYWJvcnRSZXF1ZXN0Ll9yZWFzb24pO1xuICAgIHVwb25Qcm9taXNlKHByb21pc2UsICgpID0+IHtcbiAgICAgICAgYWJvcnRSZXF1ZXN0Ll9yZXNvbHZlKCk7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtUmVqZWN0Q2xvc2VBbmRDbG9zZWRQcm9taXNlSWZOZWVkZWQoc3RyZWFtKTtcbiAgICB9LCAocmVhc29uKSA9PiB7XG4gICAgICAgIGFib3J0UmVxdWVzdC5fcmVqZWN0KHJlYXNvbik7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtUmVqZWN0Q2xvc2VBbmRDbG9zZWRQcm9taXNlSWZOZWVkZWQoc3RyZWFtKTtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRmluaXNoSW5GbGlnaHRXcml0ZShzdHJlYW0pIHtcbiAgICBzdHJlYW0uX2luRmxpZ2h0V3JpdGVSZXF1ZXN0Ll9yZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgc3RyZWFtLl9pbkZsaWdodFdyaXRlUmVxdWVzdCA9IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRmluaXNoSW5GbGlnaHRXcml0ZVdpdGhFcnJvcihzdHJlYW0sIGVycm9yKSB7XG4gICAgc3RyZWFtLl9pbkZsaWdodFdyaXRlUmVxdWVzdC5fcmVqZWN0KGVycm9yKTtcbiAgICBzdHJlYW0uX2luRmxpZ2h0V3JpdGVSZXF1ZXN0ID0gdW5kZWZpbmVkO1xuICAgIFdyaXRhYmxlU3RyZWFtRGVhbFdpdGhSZWplY3Rpb24oc3RyZWFtLCBlcnJvcik7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbUZpbmlzaEluRmxpZ2h0Q2xvc2Uoc3RyZWFtKSB7XG4gICAgc3RyZWFtLl9pbkZsaWdodENsb3NlUmVxdWVzdC5fcmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgIHN0cmVhbS5faW5GbGlnaHRDbG9zZVJlcXVlc3QgPSB1bmRlZmluZWQ7XG4gICAgY29uc3Qgc3RhdGUgPSBzdHJlYW0uX3N0YXRlO1xuICAgIGlmIChzdGF0ZSA9PT0gJ2Vycm9yaW5nJykge1xuICAgICAgICAvLyBUaGUgZXJyb3Igd2FzIHRvbyBsYXRlIHRvIGRvIGFueXRoaW5nLCBzbyBpdCBpcyBpZ25vcmVkLlxuICAgICAgICBzdHJlYW0uX3N0b3JlZEVycm9yID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAoc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHN0cmVhbS5fcGVuZGluZ0Fib3J0UmVxdWVzdC5fcmVzb2x2ZSgpO1xuICAgICAgICAgICAgc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0ID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0cmVhbS5fc3RhdGUgPSAnY2xvc2VkJztcbiAgICBjb25zdCB3cml0ZXIgPSBzdHJlYW0uX3dyaXRlcjtcbiAgICBpZiAod3JpdGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VSZXNvbHZlKHdyaXRlcik7XG4gICAgfVxufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1GaW5pc2hJbkZsaWdodENsb3NlV2l0aEVycm9yKHN0cmVhbSwgZXJyb3IpIHtcbiAgICBzdHJlYW0uX2luRmxpZ2h0Q2xvc2VSZXF1ZXN0Ll9yZWplY3QoZXJyb3IpO1xuICAgIHN0cmVhbS5faW5GbGlnaHRDbG9zZVJlcXVlc3QgPSB1bmRlZmluZWQ7XG4gICAgLy8gTmV2ZXIgZXhlY3V0ZSBzaW5rIGFib3J0KCkgYWZ0ZXIgc2luayBjbG9zZSgpLlxuICAgIGlmIChzdHJlYW0uX3BlbmRpbmdBYm9ydFJlcXVlc3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzdHJlYW0uX3BlbmRpbmdBYm9ydFJlcXVlc3QuX3JlamVjdChlcnJvcik7XG4gICAgICAgIHN0cmVhbS5fcGVuZGluZ0Fib3J0UmVxdWVzdCA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgV3JpdGFibGVTdHJlYW1EZWFsV2l0aFJlamVjdGlvbihzdHJlYW0sIGVycm9yKTtcbn1cbi8vIFRPRE8ocmljZWEpOiBGaXggYWxwaGFiZXRpY2FsIG9yZGVyLlxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1DbG9zZVF1ZXVlZE9ySW5GbGlnaHQoc3RyZWFtKSB7XG4gICAgaWYgKHN0cmVhbS5fY2xvc2VSZXF1ZXN0ID09PSB1bmRlZmluZWQgJiYgc3RyZWFtLl9pbkZsaWdodENsb3NlUmVxdWVzdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbUhhc09wZXJhdGlvbk1hcmtlZEluRmxpZ2h0KHN0cmVhbSkge1xuICAgIGlmIChzdHJlYW0uX2luRmxpZ2h0V3JpdGVSZXF1ZXN0ID09PSB1bmRlZmluZWQgJiYgc3RyZWFtLl9pbkZsaWdodENsb3NlUmVxdWVzdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbU1hcmtDbG9zZVJlcXVlc3RJbkZsaWdodChzdHJlYW0pIHtcbiAgICBzdHJlYW0uX2luRmxpZ2h0Q2xvc2VSZXF1ZXN0ID0gc3RyZWFtLl9jbG9zZVJlcXVlc3Q7XG4gICAgc3RyZWFtLl9jbG9zZVJlcXVlc3QgPSB1bmRlZmluZWQ7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbU1hcmtGaXJzdFdyaXRlUmVxdWVzdEluRmxpZ2h0KHN0cmVhbSkge1xuICAgIHN0cmVhbS5faW5GbGlnaHRXcml0ZVJlcXVlc3QgPSBzdHJlYW0uX3dyaXRlUmVxdWVzdHMuc2hpZnQoKTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtUmVqZWN0Q2xvc2VBbmRDbG9zZWRQcm9taXNlSWZOZWVkZWQoc3RyZWFtKSB7XG4gICAgaWYgKHN0cmVhbS5fY2xvc2VSZXF1ZXN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc3RyZWFtLl9jbG9zZVJlcXVlc3QuX3JlamVjdChzdHJlYW0uX3N0b3JlZEVycm9yKTtcbiAgICAgICAgc3RyZWFtLl9jbG9zZVJlcXVlc3QgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGNvbnN0IHdyaXRlciA9IHN0cmVhbS5fd3JpdGVyO1xuICAgIGlmICh3cml0ZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZVJlamVjdCh3cml0ZXIsIHN0cmVhbS5fc3RvcmVkRXJyb3IpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtVXBkYXRlQmFja3ByZXNzdXJlKHN0cmVhbSwgYmFja3ByZXNzdXJlKSB7XG4gICAgY29uc3Qgd3JpdGVyID0gc3RyZWFtLl93cml0ZXI7XG4gICAgaWYgKHdyaXRlciAhPT0gdW5kZWZpbmVkICYmIGJhY2twcmVzc3VyZSAhPT0gc3RyZWFtLl9iYWNrcHJlc3N1cmUpIHtcbiAgICAgICAgaWYgKGJhY2twcmVzc3VyZSkge1xuICAgICAgICAgICAgZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc2V0KHdyaXRlcik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVzb2x2ZSh3cml0ZXIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0cmVhbS5fYmFja3ByZXNzdXJlID0gYmFja3ByZXNzdXJlO1xufVxuLyoqXG4gKiBBIGRlZmF1bHQgd3JpdGVyIHZlbmRlZCBieSBhIHtAbGluayBXcml0YWJsZVN0cmVhbX0uXG4gKlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIge1xuICAgIGNvbnN0cnVjdG9yKHN0cmVhbSkge1xuICAgICAgICBhc3NlcnRSZXF1aXJlZEFyZ3VtZW50KHN0cmVhbSwgMSwgJ1dyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcicpO1xuICAgICAgICBhc3NlcnRXcml0YWJsZVN0cmVhbShzdHJlYW0sICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgaWYgKElzV3JpdGFibGVTdHJlYW1Mb2NrZWQoc3RyZWFtKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhpcyBzdHJlYW0gaGFzIGFscmVhZHkgYmVlbiBsb2NrZWQgZm9yIGV4Y2x1c2l2ZSB3cml0aW5nIGJ5IGFub3RoZXIgd3JpdGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fb3duZXJXcml0YWJsZVN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgc3RyZWFtLl93cml0ZXIgPSB0aGlzO1xuICAgICAgICBjb25zdCBzdGF0ZSA9IHN0cmVhbS5fc3RhdGU7XG4gICAgICAgIGlmIChzdGF0ZSA9PT0gJ3dyaXRhYmxlJykge1xuICAgICAgICAgICAgaWYgKCFXcml0YWJsZVN0cmVhbUNsb3NlUXVldWVkT3JJbkZsaWdodChzdHJlYW0pICYmIHN0cmVhbS5fYmFja3ByZXNzdXJlKSB7XG4gICAgICAgICAgICAgICAgZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZUluaXRpYWxpemUodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZUFzUmVzb2x2ZWQodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemUodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc3RhdGUgPT09ICdlcnJvcmluZycpIHtcbiAgICAgICAgICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCh0aGlzLCBzdHJlYW0uX3N0b3JlZEVycm9yKTtcbiAgICAgICAgICAgIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZSh0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VJbml0aWFsaXplQXNSZXNvbHZlZCh0aGlzKTtcbiAgICAgICAgICAgIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZUFzUmVzb2x2ZWQodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBzdG9yZWRFcnJvciA9IHN0cmVhbS5fc3RvcmVkRXJyb3I7XG4gICAgICAgICAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZUFzUmVqZWN0ZWQodGhpcywgc3RvcmVkRXJyb3IpO1xuICAgICAgICAgICAgZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCh0aGlzLCBzdG9yZWRFcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHByb21pc2UgdGhhdCB3aWxsIGJlIGZ1bGZpbGxlZCB3aGVuIHRoZSBzdHJlYW0gYmVjb21lcyBjbG9zZWQsIG9yIHJlamVjdGVkIGlmIHRoZSBzdHJlYW0gZXZlciBlcnJvcnMgb3JcbiAgICAgKiB0aGUgd3JpdGVy4oCZcyBsb2NrIGlzIHJlbGVhc2VkIGJlZm9yZSB0aGUgc3RyZWFtIGZpbmlzaGVzIGNsb3NpbmcuXG4gICAgICovXG4gICAgZ2V0IGNsb3NlZCgpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcih0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFdyaXRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2Nsb3NlZCcpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fY2xvc2VkUHJvbWlzZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZGVzaXJlZCBzaXplIHRvIGZpbGwgdGhlIHN0cmVhbeKAmXMgaW50ZXJuYWwgcXVldWUuIEl0IGNhbiBiZSBuZWdhdGl2ZSwgaWYgdGhlIHF1ZXVlIGlzIG92ZXItZnVsbC5cbiAgICAgKiBBIHByb2R1Y2VyIGNhbiB1c2UgdGhpcyBpbmZvcm1hdGlvbiB0byBkZXRlcm1pbmUgdGhlIHJpZ2h0IGFtb3VudCBvZiBkYXRhIHRvIHdyaXRlLlxuICAgICAqXG4gICAgICogSXQgd2lsbCBiZSBgbnVsbGAgaWYgdGhlIHN0cmVhbSBjYW5ub3QgYmUgc3VjY2Vzc2Z1bGx5IHdyaXR0ZW4gdG8gKGR1ZSB0byBlaXRoZXIgYmVpbmcgZXJyb3JlZCwgb3IgaGF2aW5nIGFuIGFib3J0XG4gICAgICogcXVldWVkIHVwKS4gSXQgd2lsbCByZXR1cm4gemVybyBpZiB0aGUgc3RyZWFtIGlzIGNsb3NlZC4gQW5kIHRoZSBnZXR0ZXIgd2lsbCB0aHJvdyBhbiBleGNlcHRpb24gaWYgaW52b2tlZCB3aGVuXG4gICAgICogdGhlIHdyaXRlcuKAmXMgbG9jayBpcyByZWxlYXNlZC5cbiAgICAgKi9cbiAgICBnZXQgZGVzaXJlZFNpemUoKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRXcml0ZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdkZXNpcmVkU2l6ZScpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9vd25lcldyaXRhYmxlU3RyZWFtID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRXcml0ZXJMb2NrRXhjZXB0aW9uKCdkZXNpcmVkU2l6ZScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJHZXREZXNpcmVkU2l6ZSh0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHByb21pc2UgdGhhdCB3aWxsIGJlIGZ1bGZpbGxlZCB3aGVuIHRoZSBkZXNpcmVkIHNpemUgdG8gZmlsbCB0aGUgc3RyZWFt4oCZcyBpbnRlcm5hbCBxdWV1ZSB0cmFuc2l0aW9uc1xuICAgICAqIGZyb20gbm9uLXBvc2l0aXZlIHRvIHBvc2l0aXZlLCBzaWduYWxpbmcgdGhhdCBpdCBpcyBubyBsb25nZXIgYXBwbHlpbmcgYmFja3ByZXNzdXJlLiBPbmNlIHRoZSBkZXNpcmVkIHNpemUgZGlwc1xuICAgICAqIGJhY2sgdG8gemVybyBvciBiZWxvdywgdGhlIGdldHRlciB3aWxsIHJldHVybiBhIG5ldyBwcm9taXNlIHRoYXQgc3RheXMgcGVuZGluZyB1bnRpbCB0aGUgbmV4dCB0cmFuc2l0aW9uLlxuICAgICAqXG4gICAgICogSWYgdGhlIHN0cmVhbSBiZWNvbWVzIGVycm9yZWQgb3IgYWJvcnRlZCwgb3IgdGhlIHdyaXRlcuKAmXMgbG9jayBpcyByZWxlYXNlZCwgdGhlIHJldHVybmVkIHByb21pc2Ugd2lsbCBiZWNvbWVcbiAgICAgKiByZWplY3RlZC5cbiAgICAgKi9cbiAgICBnZXQgcmVhZHkoKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGRlZmF1bHRXcml0ZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdyZWFkeScpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcmVhZHlQcm9taXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgcmVhZGVyIGlzIGFjdGl2ZSwgYmVoYXZlcyB0aGUgc2FtZSBhcyB7QGxpbmsgV3JpdGFibGVTdHJlYW0uYWJvcnQgfCBzdHJlYW0uYWJvcnQocmVhc29uKX0uXG4gICAgICovXG4gICAgYWJvcnQocmVhc29uID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGRlZmF1bHRXcml0ZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdhYm9ydCcpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fb3duZXJXcml0YWJsZVN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChkZWZhdWx0V3JpdGVyTG9ja0V4Y2VwdGlvbignYWJvcnQnKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckFib3J0KHRoaXMsIHJlYXNvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSByZWFkZXIgaXMgYWN0aXZlLCBiZWhhdmVzIHRoZSBzYW1lIGFzIHtAbGluayBXcml0YWJsZVN0cmVhbS5jbG9zZSB8IHN0cmVhbS5jbG9zZSgpfS5cbiAgICAgKi9cbiAgICBjbG9zZSgpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcih0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFdyaXRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2Nsb3NlJykpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHN0cmVhbSA9IHRoaXMuX293bmVyV3JpdGFibGVTdHJlYW07XG4gICAgICAgIGlmIChzdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFdyaXRlckxvY2tFeGNlcHRpb24oJ2Nsb3NlJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChXcml0YWJsZVN0cmVhbUNsb3NlUXVldWVkT3JJbkZsaWdodChzdHJlYW0pKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2xvc2UgYW4gYWxyZWFkeS1jbG9zaW5nIHN0cmVhbScpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQ2xvc2UodGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbGVhc2VzIHRoZSB3cml0ZXLigJlzIGxvY2sgb24gdGhlIGNvcnJlc3BvbmRpbmcgc3RyZWFtLiBBZnRlciB0aGUgbG9jayBpcyByZWxlYXNlZCwgdGhlIHdyaXRlciBpcyBubyBsb25nZXIgYWN0aXZlLlxuICAgICAqIElmIHRoZSBhc3NvY2lhdGVkIHN0cmVhbSBpcyBlcnJvcmVkIHdoZW4gdGhlIGxvY2sgaXMgcmVsZWFzZWQsIHRoZSB3cml0ZXIgd2lsbCBhcHBlYXIgZXJyb3JlZCBpbiB0aGUgc2FtZSB3YXkgZnJvbVxuICAgICAqIG5vdyBvbjsgb3RoZXJ3aXNlLCB0aGUgd3JpdGVyIHdpbGwgYXBwZWFyIGNsb3NlZC5cbiAgICAgKlxuICAgICAqIE5vdGUgdGhhdCB0aGUgbG9jayBjYW4gc3RpbGwgYmUgcmVsZWFzZWQgZXZlbiBpZiBzb21lIG9uZ29pbmcgd3JpdGVzIGhhdmUgbm90IHlldCBmaW5pc2hlZCAoaS5lLiBldmVuIGlmIHRoZVxuICAgICAqIHByb21pc2VzIHJldHVybmVkIGZyb20gcHJldmlvdXMgY2FsbHMgdG8ge0BsaW5rIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlci53cml0ZSB8IHdyaXRlKCl9IGhhdmUgbm90IHlldCBzZXR0bGVkKS5cbiAgICAgKiBJdOKAmXMgbm90IG5lY2Vzc2FyeSB0byBob2xkIHRoZSBsb2NrIG9uIHRoZSB3cml0ZXIgZm9yIHRoZSBkdXJhdGlvbiBvZiB0aGUgd3JpdGU7IHRoZSBsb2NrIGluc3RlYWQgc2ltcGx5IHByZXZlbnRzXG4gICAgICogb3RoZXIgcHJvZHVjZXJzIGZyb20gd3JpdGluZyBpbiBhbiBpbnRlcmxlYXZlZCBtYW5uZXIuXG4gICAgICovXG4gICAgcmVsZWFzZUxvY2soKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRXcml0ZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdyZWxlYXNlTG9jaycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHN0cmVhbSA9IHRoaXMuX293bmVyV3JpdGFibGVTdHJlYW07XG4gICAgICAgIGlmIChzdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlclJlbGVhc2UodGhpcyk7XG4gICAgfVxuICAgIHdyaXRlKGNodW5rID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGRlZmF1bHRXcml0ZXJCcmFuZENoZWNrRXhjZXB0aW9uKCd3cml0ZScpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fb3duZXJXcml0YWJsZVN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChkZWZhdWx0V3JpdGVyTG9ja0V4Y2VwdGlvbignd3JpdGUgdG8nKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcldyaXRlKHRoaXMsIGNodW5rKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIucHJvdG90eXBlLCB7XG4gICAgYWJvcnQ6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGNsb3NlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICByZWxlYXNlTG9jazogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgd3JpdGU6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGNsb3NlZDogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgZGVzaXJlZFNpemU6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIHJlYWR5OiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIucHJvdG90eXBlLCBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZywge1xuICAgICAgICB2YWx1ZTogJ1dyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcicsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBmb3IgdGhlIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlci5cbmZ1bmN0aW9uIElzV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyKHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfb3duZXJXcml0YWJsZVN0cmVhbScpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXI7XG59XG4vLyBBIGNsaWVudCBvZiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIgbWF5IHVzZSB0aGVzZSBmdW5jdGlvbnMgZGlyZWN0bHkgdG8gYnlwYXNzIHN0YXRlIGNoZWNrLlxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQWJvcnQod3JpdGVyLCByZWFzb24pIHtcbiAgICBjb25zdCBzdHJlYW0gPSB3cml0ZXIuX293bmVyV3JpdGFibGVTdHJlYW07XG4gICAgcmV0dXJuIFdyaXRhYmxlU3RyZWFtQWJvcnQoc3RyZWFtLCByZWFzb24pO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQ2xvc2Uod3JpdGVyKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gd3JpdGVyLl9vd25lcldyaXRhYmxlU3RyZWFtO1xuICAgIHJldHVybiBXcml0YWJsZVN0cmVhbUNsb3NlKHN0cmVhbSk7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJDbG9zZVdpdGhFcnJvclByb3BhZ2F0aW9uKHdyaXRlcikge1xuICAgIGNvbnN0IHN0cmVhbSA9IHdyaXRlci5fb3duZXJXcml0YWJsZVN0cmVhbTtcbiAgICBjb25zdCBzdGF0ZSA9IHN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKFdyaXRhYmxlU3RyZWFtQ2xvc2VRdWV1ZWRPckluRmxpZ2h0KHN0cmVhbSkgfHwgc3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIGlmIChzdGF0ZSA9PT0gJ2Vycm9yZWQnKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHN0cmVhbS5fc3RvcmVkRXJyb3IpO1xuICAgIH1cbiAgICByZXR1cm4gV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQ2xvc2Uod3JpdGVyKTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckVuc3VyZUNsb3NlZFByb21pc2VSZWplY3RlZCh3cml0ZXIsIGVycm9yKSB7XG4gICAgaWYgKHdyaXRlci5fY2xvc2VkUHJvbWlzZVN0YXRlID09PSAncGVuZGluZycpIHtcbiAgICAgICAgZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VSZWplY3Qod3JpdGVyLCBlcnJvcik7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZVJlc2V0VG9SZWplY3RlZCh3cml0ZXIsIGVycm9yKTtcbiAgICB9XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJFbnN1cmVSZWFkeVByb21pc2VSZWplY3RlZCh3cml0ZXIsIGVycm9yKSB7XG4gICAgaWYgKHdyaXRlci5fcmVhZHlQcm9taXNlU3RhdGUgPT09ICdwZW5kaW5nJykge1xuICAgICAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVqZWN0KHdyaXRlciwgZXJyb3IpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc2V0VG9SZWplY3RlZCh3cml0ZXIsIGVycm9yKTtcbiAgICB9XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJHZXREZXNpcmVkU2l6ZSh3cml0ZXIpIHtcbiAgICBjb25zdCBzdHJlYW0gPSB3cml0ZXIuX293bmVyV3JpdGFibGVTdHJlYW07XG4gICAgY29uc3Qgc3RhdGUgPSBzdHJlYW0uX3N0YXRlO1xuICAgIGlmIChzdGF0ZSA9PT0gJ2Vycm9yZWQnIHx8IHN0YXRlID09PSAnZXJyb3JpbmcnKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAoc3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICByZXR1cm4gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldERlc2lyZWRTaXplKHN0cmVhbS5fd3JpdGFibGVTdHJlYW1Db250cm9sbGVyKTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlclJlbGVhc2Uod3JpdGVyKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gd3JpdGVyLl9vd25lcldyaXRhYmxlU3RyZWFtO1xuICAgIGNvbnN0IHJlbGVhc2VkRXJyb3IgPSBuZXcgVHlwZUVycm9yKGBXcml0ZXIgd2FzIHJlbGVhc2VkIGFuZCBjYW4gbm8gbG9uZ2VyIGJlIHVzZWQgdG8gbW9uaXRvciB0aGUgc3RyZWFtJ3MgY2xvc2VkbmVzc2ApO1xuICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckVuc3VyZVJlYWR5UHJvbWlzZVJlamVjdGVkKHdyaXRlciwgcmVsZWFzZWRFcnJvcik7XG4gICAgLy8gVGhlIHN0YXRlIHRyYW5zaXRpb25zIHRvIFwiZXJyb3JlZFwiIGJlZm9yZSB0aGUgc2luayBhYm9ydCgpIG1ldGhvZCBydW5zLCBidXQgdGhlIHdyaXRlci5jbG9zZWQgcHJvbWlzZSBpcyBub3RcbiAgICAvLyByZWplY3RlZCB1bnRpbCBhZnRlcndhcmRzLiBUaGlzIG1lYW5zIHRoYXQgc2ltcGx5IHRlc3Rpbmcgc3RhdGUgd2lsbCBub3Qgd29yay5cbiAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJFbnN1cmVDbG9zZWRQcm9taXNlUmVqZWN0ZWQod3JpdGVyLCByZWxlYXNlZEVycm9yKTtcbiAgICBzdHJlYW0uX3dyaXRlciA9IHVuZGVmaW5lZDtcbiAgICB3cml0ZXIuX293bmVyV3JpdGFibGVTdHJlYW0gPSB1bmRlZmluZWQ7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJXcml0ZSh3cml0ZXIsIGNodW5rKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gd3JpdGVyLl9vd25lcldyaXRhYmxlU3RyZWFtO1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBzdHJlYW0uX3dyaXRhYmxlU3RyZWFtQ29udHJvbGxlcjtcbiAgICBjb25zdCBjaHVua1NpemUgPSBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0Q2h1bmtTaXplKGNvbnRyb2xsZXIsIGNodW5rKTtcbiAgICBpZiAoc3RyZWFtICE9PSB3cml0ZXIuX293bmVyV3JpdGFibGVTdHJlYW0pIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFdyaXRlckxvY2tFeGNlcHRpb24oJ3dyaXRlIHRvJykpO1xuICAgIH1cbiAgICBjb25zdCBzdGF0ZSA9IHN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKHN0YXRlID09PSAnZXJyb3JlZCcpIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoc3RyZWFtLl9zdG9yZWRFcnJvcik7XG4gICAgfVxuICAgIGlmIChXcml0YWJsZVN0cmVhbUNsb3NlUXVldWVkT3JJbkZsaWdodChzdHJlYW0pIHx8IHN0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCdUaGUgc3RyZWFtIGlzIGNsb3Npbmcgb3IgY2xvc2VkIGFuZCBjYW5ub3QgYmUgd3JpdHRlbiB0bycpKTtcbiAgICB9XG4gICAgaWYgKHN0YXRlID09PSAnZXJyb3JpbmcnKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHN0cmVhbS5fc3RvcmVkRXJyb3IpO1xuICAgIH1cbiAgICBjb25zdCBwcm9taXNlID0gV3JpdGFibGVTdHJlYW1BZGRXcml0ZVJlcXVlc3Qoc3RyZWFtKTtcbiAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyV3JpdGUoY29udHJvbGxlciwgY2h1bmssIGNodW5rU2l6ZSk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5jb25zdCBjbG9zZVNlbnRpbmVsID0ge307XG4vKipcbiAqIEFsbG93cyBjb250cm9sIG9mIGEge0BsaW5rIFdyaXRhYmxlU3RyZWFtIHwgd3JpdGFibGUgc3RyZWFtfSdzIHN0YXRlIGFuZCBpbnRlcm5hbCBxdWV1ZS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbGxlZ2FsIGNvbnN0cnVjdG9yJyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSByZWFzb24gd2hpY2ggd2FzIHBhc3NlZCB0byBgV3JpdGFibGVTdHJlYW0uYWJvcnQocmVhc29uKWAgd2hlbiB0aGUgc3RyZWFtIHdhcyBhYm9ydGVkLlxuICAgICAqL1xuICAgIGdldCBhYm9ydFJlYXNvbigpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQyKCdhYm9ydFJlYXNvbicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9hYm9ydFJlYXNvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQW4gYEFib3J0U2lnbmFsYCB0aGF0IGNhbiBiZSB1c2VkIHRvIGFib3J0IHRoZSBwZW5kaW5nIHdyaXRlIG9yIGNsb3NlIG9wZXJhdGlvbiB3aGVuIHRoZSBzdHJlYW0gaXMgYWJvcnRlZC5cbiAgICAgKi9cbiAgICBnZXQgc2lnbmFsKCkge1xuICAgICAgICBpZiAoIUlzV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uJDIoJ3NpZ25hbCcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9hYm9ydENvbnRyb2xsZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgLy8gT2xkZXIgYnJvd3NlcnMgb3Igb2xkZXIgTm9kZSB2ZXJzaW9ucyBtYXkgbm90IHN1cHBvcnQgYEFib3J0Q29udHJvbGxlcmAgb3IgYEFib3J0U2lnbmFsYC5cbiAgICAgICAgICAgIC8vIFdlIGRvbid0IHdhbnQgdG8gYnVuZGxlIGFuZCBzaGlwIGFuIGBBYm9ydENvbnRyb2xsZXJgIHBvbHlmaWxsIHRvZ2V0aGVyIHdpdGggb3VyIHBvbHlmaWxsLFxuICAgICAgICAgICAgLy8gc28gaW5zdGVhZCB3ZSBvbmx5IGltcGxlbWVudCBzdXBwb3J0IGZvciBgc2lnbmFsYCBpZiB3ZSBmaW5kIGEgZ2xvYmFsIGBBYm9ydENvbnRyb2xsZXJgIGNvbnN0cnVjdG9yLlxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUuc2lnbmFsIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fYWJvcnRDb250cm9sbGVyLnNpZ25hbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xvc2VzIHRoZSBjb250cm9sbGVkIHdyaXRhYmxlIHN0cmVhbSwgbWFraW5nIGFsbCBmdXR1cmUgaW50ZXJhY3Rpb25zIHdpdGggaXQgZmFpbCB3aXRoIHRoZSBnaXZlbiBlcnJvciBgZWAuXG4gICAgICpcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyByYXJlbHkgdXNlZCwgc2luY2UgdXN1YWxseSBpdCBzdWZmaWNlcyB0byByZXR1cm4gYSByZWplY3RlZCBwcm9taXNlIGZyb20gb25lIG9mIHRoZSB1bmRlcmx5aW5nXG4gICAgICogc2luaydzIG1ldGhvZHMuIEhvd2V2ZXIsIGl0IGNhbiBiZSB1c2VmdWwgZm9yIHN1ZGRlbmx5IHNodXR0aW5nIGRvd24gYSBzdHJlYW0gaW4gcmVzcG9uc2UgdG8gYW4gZXZlbnQgb3V0c2lkZSB0aGVcbiAgICAgKiBub3JtYWwgbGlmZWN5Y2xlIG9mIGludGVyYWN0aW9ucyB3aXRoIHRoZSB1bmRlcmx5aW5nIHNpbmsuXG4gICAgICovXG4gICAgZXJyb3IoZSA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uJDIoJ2Vycm9yJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RhdGUgPSB0aGlzLl9jb250cm9sbGVkV3JpdGFibGVTdHJlYW0uX3N0YXRlO1xuICAgICAgICBpZiAoc3RhdGUgIT09ICd3cml0YWJsZScpIHtcbiAgICAgICAgICAgIC8vIFRoZSBzdHJlYW0gaXMgY2xvc2VkLCBlcnJvcmVkIG9yIHdpbGwgYmUgc29vbi4gVGhlIHNpbmsgY2FuJ3QgZG8gYW55dGhpbmcgdXNlZnVsIGlmIGl0IGdldHMgYW4gZXJyb3IgaGVyZSwgc29cbiAgICAgICAgICAgIC8vIGp1c3QgdHJlYXQgaXQgYXMgYSBuby1vcC5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3IodGhpcywgZSk7XG4gICAgfVxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBbQWJvcnRTdGVwc10ocmVhc29uKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX2Fib3J0QWxnb3JpdGhtKHJlYXNvbik7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXModGhpcyk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBbRXJyb3JTdGVwc10oKSB7XG4gICAgICAgIFJlc2V0UXVldWUodGhpcyk7XG4gICAgfVxufVxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUsIHtcbiAgICBlcnJvcjogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUsIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIHZhbHVlOiAnV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcicsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBpbXBsZW1lbnRpbmcgaW50ZXJmYWNlIHJlcXVpcmVkIGJ5IHRoZSBXcml0YWJsZVN0cmVhbS5cbmZ1bmN0aW9uIElzV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcih4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX2NvbnRyb2xsZWRXcml0YWJsZVN0cmVhbScpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyO1xufVxuZnVuY3Rpb24gU2V0VXBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyKHN0cmVhbSwgY29udHJvbGxlciwgc3RhcnRBbGdvcml0aG0sIHdyaXRlQWxnb3JpdGhtLCBjbG9zZUFsZ29yaXRobSwgYWJvcnRBbGdvcml0aG0sIGhpZ2hXYXRlck1hcmssIHNpemVBbGdvcml0aG0pIHtcbiAgICBjb250cm9sbGVyLl9jb250cm9sbGVkV3JpdGFibGVTdHJlYW0gPSBzdHJlYW07XG4gICAgc3RyZWFtLl93cml0YWJsZVN0cmVhbUNvbnRyb2xsZXIgPSBjb250cm9sbGVyO1xuICAgIC8vIE5lZWQgdG8gc2V0IHRoZSBzbG90cyBzbyB0aGF0IHRoZSBhc3NlcnQgZG9lc24ndCBmaXJlLiBJbiB0aGUgc3BlYyB0aGUgc2xvdHMgYWxyZWFkeSBleGlzdCBpbXBsaWNpdGx5LlxuICAgIGNvbnRyb2xsZXIuX3F1ZXVlID0gdW5kZWZpbmVkO1xuICAgIGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplID0gdW5kZWZpbmVkO1xuICAgIFJlc2V0UXVldWUoY29udHJvbGxlcik7XG4gICAgY29udHJvbGxlci5fYWJvcnRSZWFzb24gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fYWJvcnRDb250cm9sbGVyID0gY3JlYXRlQWJvcnRDb250cm9sbGVyKCk7XG4gICAgY29udHJvbGxlci5fc3RhcnRlZCA9IGZhbHNlO1xuICAgIGNvbnRyb2xsZXIuX3N0cmF0ZWd5U2l6ZUFsZ29yaXRobSA9IHNpemVBbGdvcml0aG07XG4gICAgY29udHJvbGxlci5fc3RyYXRlZ3lIV00gPSBoaWdoV2F0ZXJNYXJrO1xuICAgIGNvbnRyb2xsZXIuX3dyaXRlQWxnb3JpdGhtID0gd3JpdGVBbGdvcml0aG07XG4gICAgY29udHJvbGxlci5fY2xvc2VBbGdvcml0aG0gPSBjbG9zZUFsZ29yaXRobTtcbiAgICBjb250cm9sbGVyLl9hYm9ydEFsZ29yaXRobSA9IGFib3J0QWxnb3JpdGhtO1xuICAgIGNvbnN0IGJhY2twcmVzc3VyZSA9IFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJHZXRCYWNrcHJlc3N1cmUoY29udHJvbGxlcik7XG4gICAgV3JpdGFibGVTdHJlYW1VcGRhdGVCYWNrcHJlc3N1cmUoc3RyZWFtLCBiYWNrcHJlc3N1cmUpO1xuICAgIGNvbnN0IHN0YXJ0UmVzdWx0ID0gc3RhcnRBbGdvcml0aG0oKTtcbiAgICBjb25zdCBzdGFydFByb21pc2UgPSBwcm9taXNlUmVzb2x2ZWRXaXRoKHN0YXJ0UmVzdWx0KTtcbiAgICB1cG9uUHJvbWlzZShzdGFydFByb21pc2UsICgpID0+IHtcbiAgICAgICAgY29udHJvbGxlci5fc3RhcnRlZCA9IHRydWU7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJBZHZhbmNlUXVldWVJZk5lZWRlZChjb250cm9sbGVyKTtcbiAgICB9LCByID0+IHtcbiAgICAgICAgY29udHJvbGxlci5fc3RhcnRlZCA9IHRydWU7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVhbFdpdGhSZWplY3Rpb24oc3RyZWFtLCByKTtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIFNldFVwV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckZyb21VbmRlcmx5aW5nU2luayhzdHJlYW0sIHVuZGVybHlpbmdTaW5rLCBoaWdoV2F0ZXJNYXJrLCBzaXplQWxnb3JpdGhtKSB7XG4gICAgY29uc3QgY29udHJvbGxlciA9IE9iamVjdC5jcmVhdGUoV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUpO1xuICAgIGxldCBzdGFydEFsZ29yaXRobSA9ICgpID0+IHVuZGVmaW5lZDtcbiAgICBsZXQgd3JpdGVBbGdvcml0aG0gPSAoKSA9PiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgbGV0IGNsb3NlQWxnb3JpdGhtID0gKCkgPT4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgIGxldCBhYm9ydEFsZ29yaXRobSA9ICgpID0+IHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICBpZiAodW5kZXJseWluZ1Npbmsuc3RhcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzdGFydEFsZ29yaXRobSA9ICgpID0+IHVuZGVybHlpbmdTaW5rLnN0YXJ0KGNvbnRyb2xsZXIpO1xuICAgIH1cbiAgICBpZiAodW5kZXJseWluZ1Npbmsud3JpdGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB3cml0ZUFsZ29yaXRobSA9IGNodW5rID0+IHVuZGVybHlpbmdTaW5rLndyaXRlKGNodW5rLCBjb250cm9sbGVyKTtcbiAgICB9XG4gICAgaWYgKHVuZGVybHlpbmdTaW5rLmNsb3NlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY2xvc2VBbGdvcml0aG0gPSAoKSA9PiB1bmRlcmx5aW5nU2luay5jbG9zZSgpO1xuICAgIH1cbiAgICBpZiAodW5kZXJseWluZ1NpbmsuYWJvcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhYm9ydEFsZ29yaXRobSA9IHJlYXNvbiA9PiB1bmRlcmx5aW5nU2luay5hYm9ydChyZWFzb24pO1xuICAgIH1cbiAgICBTZXRVcFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCBzdGFydEFsZ29yaXRobSwgd3JpdGVBbGdvcml0aG0sIGNsb3NlQWxnb3JpdGhtLCBhYm9ydEFsZ29yaXRobSwgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSk7XG59XG4vLyBDbGVhckFsZ29yaXRobXMgbWF5IGJlIGNhbGxlZCB0d2ljZS4gRXJyb3JpbmcgdGhlIHNhbWUgc3RyZWFtIGluIG11bHRpcGxlIHdheXMgd2lsbCBvZnRlbiByZXN1bHQgaW4gcmVkdW5kYW50IGNhbGxzLlxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyhjb250cm9sbGVyKSB7XG4gICAgY29udHJvbGxlci5fd3JpdGVBbGdvcml0aG0gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fY2xvc2VBbGdvcml0aG0gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fYWJvcnRBbGdvcml0aG0gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fc3RyYXRlZ3lTaXplQWxnb3JpdGhtID0gdW5kZWZpbmVkO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsb3NlKGNvbnRyb2xsZXIpIHtcbiAgICBFbnF1ZXVlVmFsdWVXaXRoU2l6ZShjb250cm9sbGVyLCBjbG9zZVNlbnRpbmVsLCAwKTtcbiAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQWR2YW5jZVF1ZXVlSWZOZWVkZWQoY29udHJvbGxlcik7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0Q2h1bmtTaXplKGNvbnRyb2xsZXIsIGNodW5rKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xsZXIuX3N0cmF0ZWd5U2l6ZUFsZ29yaXRobShjaHVuayk7XG4gICAgfVxuICAgIGNhdGNoIChjaHVua1NpemVFKSB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcklmTmVlZGVkKGNvbnRyb2xsZXIsIGNodW5rU2l6ZUUpO1xuICAgICAgICByZXR1cm4gMTtcbiAgICB9XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0RGVzaXJlZFNpemUoY29udHJvbGxlcikge1xuICAgIHJldHVybiBjb250cm9sbGVyLl9zdHJhdGVneUhXTSAtIGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcldyaXRlKGNvbnRyb2xsZXIsIGNodW5rLCBjaHVua1NpemUpIHtcbiAgICB0cnkge1xuICAgICAgICBFbnF1ZXVlVmFsdWVXaXRoU2l6ZShjb250cm9sbGVyLCBjaHVuaywgY2h1bmtTaXplKTtcbiAgICB9XG4gICAgY2F0Y2ggKGVucXVldWVFKSB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcklmTmVlZGVkKGNvbnRyb2xsZXIsIGVucXVldWVFKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzdHJlYW0gPSBjb250cm9sbGVyLl9jb250cm9sbGVkV3JpdGFibGVTdHJlYW07XG4gICAgaWYgKCFXcml0YWJsZVN0cmVhbUNsb3NlUXVldWVkT3JJbkZsaWdodChzdHJlYW0pICYmIHN0cmVhbS5fc3RhdGUgPT09ICd3cml0YWJsZScpIHtcbiAgICAgICAgY29uc3QgYmFja3ByZXNzdXJlID0gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldEJhY2twcmVzc3VyZShjb250cm9sbGVyKTtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1VcGRhdGVCYWNrcHJlc3N1cmUoc3RyZWFtLCBiYWNrcHJlc3N1cmUpO1xuICAgIH1cbiAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQWR2YW5jZVF1ZXVlSWZOZWVkZWQoY29udHJvbGxlcik7XG59XG4vLyBBYnN0cmFjdCBvcGVyYXRpb25zIGZvciB0aGUgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJBZHZhbmNlUXVldWVJZk5lZWRlZChjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFdyaXRhYmxlU3RyZWFtO1xuICAgIGlmICghY29udHJvbGxlci5fc3RhcnRlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChzdHJlYW0uX2luRmxpZ2h0V3JpdGVSZXF1ZXN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzdGF0ZSA9IHN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKHN0YXRlID09PSAnZXJyb3JpbmcnKSB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRmluaXNoRXJyb3Jpbmcoc3RyZWFtKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY29udHJvbGxlci5fcXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgdmFsdWUgPSBQZWVrUXVldWVWYWx1ZShjb250cm9sbGVyKTtcbiAgICBpZiAodmFsdWUgPT09IGNsb3NlU2VudGluZWwpIHtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlclByb2Nlc3NDbG9zZShjb250cm9sbGVyKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJQcm9jZXNzV3JpdGUoY29udHJvbGxlciwgdmFsdWUpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcklmTmVlZGVkKGNvbnRyb2xsZXIsIGVycm9yKSB7XG4gICAgaWYgKGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRXcml0YWJsZVN0cmVhbS5fc3RhdGUgPT09ICd3cml0YWJsZScpIHtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKGNvbnRyb2xsZXIsIGVycm9yKTtcbiAgICB9XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyUHJvY2Vzc0Nsb3NlKGNvbnRyb2xsZXIpIHtcbiAgICBjb25zdCBzdHJlYW0gPSBjb250cm9sbGVyLl9jb250cm9sbGVkV3JpdGFibGVTdHJlYW07XG4gICAgV3JpdGFibGVTdHJlYW1NYXJrQ2xvc2VSZXF1ZXN0SW5GbGlnaHQoc3RyZWFtKTtcbiAgICBEZXF1ZXVlVmFsdWUoY29udHJvbGxlcik7XG4gICAgY29uc3Qgc2lua0Nsb3NlUHJvbWlzZSA9IGNvbnRyb2xsZXIuX2Nsb3NlQWxnb3JpdGhtKCk7XG4gICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyhjb250cm9sbGVyKTtcbiAgICB1cG9uUHJvbWlzZShzaW5rQ2xvc2VQcm9taXNlLCAoKSA9PiB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRmluaXNoSW5GbGlnaHRDbG9zZShzdHJlYW0pO1xuICAgIH0sIHJlYXNvbiA9PiB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRmluaXNoSW5GbGlnaHRDbG9zZVdpdGhFcnJvcihzdHJlYW0sIHJlYXNvbik7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyUHJvY2Vzc1dyaXRlKGNvbnRyb2xsZXIsIGNodW5rKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFdyaXRhYmxlU3RyZWFtO1xuICAgIFdyaXRhYmxlU3RyZWFtTWFya0ZpcnN0V3JpdGVSZXF1ZXN0SW5GbGlnaHQoc3RyZWFtKTtcbiAgICBjb25zdCBzaW5rV3JpdGVQcm9taXNlID0gY29udHJvbGxlci5fd3JpdGVBbGdvcml0aG0oY2h1bmspO1xuICAgIHVwb25Qcm9taXNlKHNpbmtXcml0ZVByb21pc2UsICgpID0+IHtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1GaW5pc2hJbkZsaWdodFdyaXRlKHN0cmVhbSk7XG4gICAgICAgIGNvbnN0IHN0YXRlID0gc3RyZWFtLl9zdGF0ZTtcbiAgICAgICAgRGVxdWV1ZVZhbHVlKGNvbnRyb2xsZXIpO1xuICAgICAgICBpZiAoIVdyaXRhYmxlU3RyZWFtQ2xvc2VRdWV1ZWRPckluRmxpZ2h0KHN0cmVhbSkgJiYgc3RhdGUgPT09ICd3cml0YWJsZScpIHtcbiAgICAgICAgICAgIGNvbnN0IGJhY2twcmVzc3VyZSA9IFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJHZXRCYWNrcHJlc3N1cmUoY29udHJvbGxlcik7XG4gICAgICAgICAgICBXcml0YWJsZVN0cmVhbVVwZGF0ZUJhY2twcmVzc3VyZShzdHJlYW0sIGJhY2twcmVzc3VyZSk7XG4gICAgICAgIH1cbiAgICAgICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckFkdmFuY2VRdWV1ZUlmTmVlZGVkKGNvbnRyb2xsZXIpO1xuICAgIH0sIHJlYXNvbiA9PiB7XG4gICAgICAgIGlmIChzdHJlYW0uX3N0YXRlID09PSAnd3JpdGFibGUnKSB7XG4gICAgICAgICAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zKGNvbnRyb2xsZXIpO1xuICAgICAgICB9XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRmluaXNoSW5GbGlnaHRXcml0ZVdpdGhFcnJvcihzdHJlYW0sIHJlYXNvbik7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0QmFja3ByZXNzdXJlKGNvbnRyb2xsZXIpIHtcbiAgICBjb25zdCBkZXNpcmVkU2l6ZSA9IFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJHZXREZXNpcmVkU2l6ZShjb250cm9sbGVyKTtcbiAgICByZXR1cm4gZGVzaXJlZFNpemUgPD0gMDtcbn1cbi8vIEEgY2xpZW50IG9mIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIgbWF5IHVzZSB0aGVzZSBmdW5jdGlvbnMgZGlyZWN0bHkgdG8gYnlwYXNzIHN0YXRlIGNoZWNrLlxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKGNvbnRyb2xsZXIsIGVycm9yKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFdyaXRhYmxlU3RyZWFtO1xuICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcik7XG4gICAgV3JpdGFibGVTdHJlYW1TdGFydEVycm9yaW5nKHN0cmVhbSwgZXJyb3IpO1xufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIFdyaXRhYmxlU3RyZWFtLlxuZnVuY3Rpb24gc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbiQyKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgV3JpdGFibGVTdHJlYW0ucHJvdG90eXBlLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFdyaXRhYmxlU3RyZWFtYCk7XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5cbmZ1bmN0aW9uIGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQyKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcmApO1xufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlci5cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyLnByb3RvdHlwZS4ke25hbWV9IGNhbiBvbmx5IGJlIHVzZWQgb24gYSBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJgKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJMb2NrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcignQ2Fubm90ICcgKyBuYW1lICsgJyBhIHN0cmVhbSB1c2luZyBhIHJlbGVhc2VkIHdyaXRlcicpO1xufVxuZnVuY3Rpb24gZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplKHdyaXRlcikge1xuICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZSA9IG5ld1Byb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICB3cml0ZXIuX2Nsb3NlZFByb21pc2VfcmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZV9yZWplY3QgPSByZWplY3Q7XG4gICAgICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZVN0YXRlID0gJ3BlbmRpbmcnO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCh3cml0ZXIsIHJlYXNvbikge1xuICAgIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZSh3cml0ZXIpO1xuICAgIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlUmVqZWN0KHdyaXRlciwgcmVhc29uKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZUFzUmVzb2x2ZWQod3JpdGVyKSB7XG4gICAgZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplKHdyaXRlcik7XG4gICAgZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VSZXNvbHZlKHdyaXRlcik7XG59XG5mdW5jdGlvbiBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZVJlamVjdCh3cml0ZXIsIHJlYXNvbikge1xuICAgIGlmICh3cml0ZXIuX2Nsb3NlZFByb21pc2VfcmVqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZXRQcm9taXNlSXNIYW5kbGVkVG9UcnVlKHdyaXRlci5fY2xvc2VkUHJvbWlzZSk7XG4gICAgd3JpdGVyLl9jbG9zZWRQcm9taXNlX3JlamVjdChyZWFzb24pO1xuICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZV9yZXNvbHZlID0gdW5kZWZpbmVkO1xuICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZV9yZWplY3QgPSB1bmRlZmluZWQ7XG4gICAgd3JpdGVyLl9jbG9zZWRQcm9taXNlU3RhdGUgPSAncmVqZWN0ZWQnO1xufVxuZnVuY3Rpb24gZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VSZXNldFRvUmVqZWN0ZWQod3JpdGVyLCByZWFzb24pIHtcbiAgICBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemVBc1JlamVjdGVkKHdyaXRlciwgcmVhc29uKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlUmVzb2x2ZSh3cml0ZXIpIHtcbiAgICBpZiAod3JpdGVyLl9jbG9zZWRQcm9taXNlX3Jlc29sdmUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZV9yZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgd3JpdGVyLl9jbG9zZWRQcm9taXNlX3Jlc29sdmUgPSB1bmRlZmluZWQ7XG4gICAgd3JpdGVyLl9jbG9zZWRQcm9taXNlX3JlamVjdCA9IHVuZGVmaW5lZDtcbiAgICB3cml0ZXIuX2Nsb3NlZFByb21pc2VTdGF0ZSA9ICdyZXNvbHZlZCc7XG59XG5mdW5jdGlvbiBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZSh3cml0ZXIpIHtcbiAgICB3cml0ZXIuX3JlYWR5UHJvbWlzZSA9IG5ld1Byb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICB3cml0ZXIuX3JlYWR5UHJvbWlzZV9yZXNvbHZlID0gcmVzb2x2ZTtcbiAgICAgICAgd3JpdGVyLl9yZWFkeVByb21pc2VfcmVqZWN0ID0gcmVqZWN0O1xuICAgIH0pO1xuICAgIHdyaXRlci5fcmVhZHlQcm9taXNlU3RhdGUgPSAncGVuZGluZyc7XG59XG5mdW5jdGlvbiBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZUFzUmVqZWN0ZWQod3JpdGVyLCByZWFzb24pIHtcbiAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZSh3cml0ZXIpO1xuICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VSZWplY3Qod3JpdGVyLCByZWFzb24pO1xufVxuZnVuY3Rpb24gZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZUluaXRpYWxpemVBc1Jlc29sdmVkKHdyaXRlcikge1xuICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VJbml0aWFsaXplKHdyaXRlcik7XG4gICAgZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc29sdmUod3JpdGVyKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VSZWplY3Qod3JpdGVyLCByZWFzb24pIHtcbiAgICBpZiAod3JpdGVyLl9yZWFkeVByb21pc2VfcmVqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZXRQcm9taXNlSXNIYW5kbGVkVG9UcnVlKHdyaXRlci5fcmVhZHlQcm9taXNlKTtcbiAgICB3cml0ZXIuX3JlYWR5UHJvbWlzZV9yZWplY3QocmVhc29uKTtcbiAgICB3cml0ZXIuX3JlYWR5UHJvbWlzZV9yZXNvbHZlID0gdW5kZWZpbmVkO1xuICAgIHdyaXRlci5fcmVhZHlQcm9taXNlX3JlamVjdCA9IHVuZGVmaW5lZDtcbiAgICB3cml0ZXIuX3JlYWR5UHJvbWlzZVN0YXRlID0gJ3JlamVjdGVkJztcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VSZXNldCh3cml0ZXIpIHtcbiAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZSh3cml0ZXIpO1xufVxuZnVuY3Rpb24gZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc2V0VG9SZWplY3RlZCh3cml0ZXIsIHJlYXNvbikge1xuICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCh3cml0ZXIsIHJlYXNvbik7XG59XG5mdW5jdGlvbiBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVzb2x2ZSh3cml0ZXIpIHtcbiAgICBpZiAod3JpdGVyLl9yZWFkeVByb21pc2VfcmVzb2x2ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgd3JpdGVyLl9yZWFkeVByb21pc2VfcmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgIHdyaXRlci5fcmVhZHlQcm9taXNlX3Jlc29sdmUgPSB1bmRlZmluZWQ7XG4gICAgd3JpdGVyLl9yZWFkeVByb21pc2VfcmVqZWN0ID0gdW5kZWZpbmVkO1xuICAgIHdyaXRlci5fcmVhZHlQcm9taXNlU3RhdGUgPSAnZnVsZmlsbGVkJztcbn1cblxuLy8vIDxyZWZlcmVuY2UgbGliPVwiZG9tXCIgLz5cbmNvbnN0IE5hdGl2ZURPTUV4Y2VwdGlvbiA9IHR5cGVvZiBET01FeGNlcHRpb24gIT09ICd1bmRlZmluZWQnID8gRE9NRXhjZXB0aW9uIDogdW5kZWZpbmVkO1xuXG4vLy8gPHJlZmVyZW5jZSB0eXBlcz1cIm5vZGVcIiAvPlxuZnVuY3Rpb24gaXNET01FeGNlcHRpb25Db25zdHJ1Y3RvcihjdG9yKSB7XG4gICAgaWYgKCEodHlwZW9mIGN0b3IgPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIGN0b3IgPT09ICdvYmplY3QnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIG5ldyBjdG9yKCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjYXRjaCAoX2EpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGNyZWF0ZURPTUV4Y2VwdGlvblBvbHlmaWxsKCkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zaGFkb3dcbiAgICBjb25zdCBjdG9yID0gZnVuY3Rpb24gRE9NRXhjZXB0aW9uKG1lc3NhZ2UsIG5hbWUpIHtcbiAgICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZSB8fCAnJztcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZSB8fCAnRXJyb3InO1xuICAgICAgICBpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIHtcbiAgICAgICAgICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIHRoaXMuY29uc3RydWN0b3IpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoRXJyb3IucHJvdG90eXBlKTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3Rvci5wcm90b3R5cGUsICdjb25zdHJ1Y3RvcicsIHsgdmFsdWU6IGN0b3IsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSk7XG4gICAgcmV0dXJuIGN0b3I7XG59XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVkZWNsYXJlXG5jb25zdCBET01FeGNlcHRpb24kMSA9IGlzRE9NRXhjZXB0aW9uQ29uc3RydWN0b3IoTmF0aXZlRE9NRXhjZXB0aW9uKSA/IE5hdGl2ZURPTUV4Y2VwdGlvbiA6IGNyZWF0ZURPTUV4Y2VwdGlvblBvbHlmaWxsKCk7XG5cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtUGlwZVRvKHNvdXJjZSwgZGVzdCwgcHJldmVudENsb3NlLCBwcmV2ZW50QWJvcnQsIHByZXZlbnRDYW5jZWwsIHNpZ25hbCkge1xuICAgIGNvbnN0IHJlYWRlciA9IEFjcXVpcmVSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIoc291cmNlKTtcbiAgICBjb25zdCB3cml0ZXIgPSBBY3F1aXJlV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyKGRlc3QpO1xuICAgIHNvdXJjZS5fZGlzdHVyYmVkID0gdHJ1ZTtcbiAgICBsZXQgc2h1dHRpbmdEb3duID0gZmFsc2U7XG4gICAgLy8gVGhpcyBpcyB1c2VkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIHNwZWMncyByZXF1aXJlbWVudCB0aGF0IHdlIHdhaXQgZm9yIG9uZ29pbmcgd3JpdGVzIGR1cmluZyBzaHV0ZG93bi5cbiAgICBsZXQgY3VycmVudFdyaXRlID0gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgIHJldHVybiBuZXdQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgbGV0IGFib3J0QWxnb3JpdGhtO1xuICAgICAgICBpZiAoc2lnbmFsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGFib3J0QWxnb3JpdGhtID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IERPTUV4Y2VwdGlvbiQxKCdBYm9ydGVkJywgJ0Fib3J0RXJyb3InKTtcbiAgICAgICAgICAgICAgICBjb25zdCBhY3Rpb25zID0gW107XG4gICAgICAgICAgICAgICAgaWYgKCFwcmV2ZW50QWJvcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9ucy5wdXNoKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZXN0Ll9zdGF0ZSA9PT0gJ3dyaXRhYmxlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBXcml0YWJsZVN0cmVhbUFib3J0KGRlc3QsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIXByZXZlbnRDYW5jZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9ucy5wdXNoKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuX3N0YXRlID09PSAncmVhZGFibGUnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHNvdXJjZSwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNodXRkb3duV2l0aEFjdGlvbigoKSA9PiBQcm9taXNlLmFsbChhY3Rpb25zLm1hcChhY3Rpb24gPT4gYWN0aW9uKCkpKSwgdHJ1ZSwgZXJyb3IpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChzaWduYWwuYWJvcnRlZCkge1xuICAgICAgICAgICAgICAgIGFib3J0QWxnb3JpdGhtKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgYWJvcnRBbGdvcml0aG0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIFVzaW5nIHJlYWRlciBhbmQgd3JpdGVyLCByZWFkIGFsbCBjaHVua3MgZnJvbSB0aGlzIGFuZCB3cml0ZSB0aGVtIHRvIGRlc3RcbiAgICAgICAgLy8gLSBCYWNrcHJlc3N1cmUgbXVzdCBiZSBlbmZvcmNlZFxuICAgICAgICAvLyAtIFNodXRkb3duIG11c3Qgc3RvcCBhbGwgYWN0aXZpdHlcbiAgICAgICAgZnVuY3Rpb24gcGlwZUxvb3AoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3UHJvbWlzZSgocmVzb2x2ZUxvb3AsIHJlamVjdExvb3ApID0+IHtcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBuZXh0KGRvbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmVMb29wKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBVc2UgYFBlcmZvcm1Qcm9taXNlVGhlbmAgaW5zdGVhZCBvZiBgdXBvblByb21pc2VgIHRvIGF2b2lkXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhZGRpbmcgdW5uZWNlc3NhcnkgYC5jYXRjaChyZXRocm93QXNzZXJ0aW9uRXJyb3JSZWplY3Rpb24pYCBoYW5kbGVyc1xuICAgICAgICAgICAgICAgICAgICAgICAgUGVyZm9ybVByb21pc2VUaGVuKHBpcGVTdGVwKCksIG5leHQsIHJlamVjdExvb3ApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG5leHQoZmFsc2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gcGlwZVN0ZXAoKSB7XG4gICAgICAgICAgICBpZiAoc2h1dHRpbmdEb3duKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gUGVyZm9ybVByb21pc2VUaGVuKHdyaXRlci5fcmVhZHlQcm9taXNlLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ld1Byb21pc2UoKHJlc29sdmVSZWFkLCByZWplY3RSZWFkKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlclJlYWQocmVhZGVyLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfY2h1bmtTdGVwczogY2h1bmsgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRXcml0ZSA9IFBlcmZvcm1Qcm9taXNlVGhlbihXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJXcml0ZSh3cml0ZXIsIGNodW5rKSwgdW5kZWZpbmVkLCBub29wKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlUmVhZChmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgX2Nsb3NlU3RlcHM6ICgpID0+IHJlc29sdmVSZWFkKHRydWUpLFxuICAgICAgICAgICAgICAgICAgICAgICAgX2Vycm9yU3RlcHM6IHJlamVjdFJlYWRcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBFcnJvcnMgbXVzdCBiZSBwcm9wYWdhdGVkIGZvcndhcmRcbiAgICAgICAgaXNPckJlY29tZXNFcnJvcmVkKHNvdXJjZSwgcmVhZGVyLl9jbG9zZWRQcm9taXNlLCBzdG9yZWRFcnJvciA9PiB7XG4gICAgICAgICAgICBpZiAoIXByZXZlbnRBYm9ydCkge1xuICAgICAgICAgICAgICAgIHNodXRkb3duV2l0aEFjdGlvbigoKSA9PiBXcml0YWJsZVN0cmVhbUFib3J0KGRlc3QsIHN0b3JlZEVycm9yKSwgdHJ1ZSwgc3RvcmVkRXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc2h1dGRvd24odHJ1ZSwgc3RvcmVkRXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgLy8gRXJyb3JzIG11c3QgYmUgcHJvcGFnYXRlZCBiYWNrd2FyZFxuICAgICAgICBpc09yQmVjb21lc0Vycm9yZWQoZGVzdCwgd3JpdGVyLl9jbG9zZWRQcm9taXNlLCBzdG9yZWRFcnJvciA9PiB7XG4gICAgICAgICAgICBpZiAoIXByZXZlbnRDYW5jZWwpIHtcbiAgICAgICAgICAgICAgICBzaHV0ZG93bldpdGhBY3Rpb24oKCkgPT4gUmVhZGFibGVTdHJlYW1DYW5jZWwoc291cmNlLCBzdG9yZWRFcnJvciksIHRydWUsIHN0b3JlZEVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHNodXRkb3duKHRydWUsIHN0b3JlZEVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIC8vIENsb3NpbmcgbXVzdCBiZSBwcm9wYWdhdGVkIGZvcndhcmRcbiAgICAgICAgaXNPckJlY29tZXNDbG9zZWQoc291cmNlLCByZWFkZXIuX2Nsb3NlZFByb21pc2UsICgpID0+IHtcbiAgICAgICAgICAgIGlmICghcHJldmVudENsb3NlKSB7XG4gICAgICAgICAgICAgICAgc2h1dGRvd25XaXRoQWN0aW9uKCgpID0+IFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckNsb3NlV2l0aEVycm9yUHJvcGFnYXRpb24od3JpdGVyKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaHV0ZG93bigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgLy8gQ2xvc2luZyBtdXN0IGJlIHByb3BhZ2F0ZWQgYmFja3dhcmRcbiAgICAgICAgaWYgKFdyaXRhYmxlU3RyZWFtQ2xvc2VRdWV1ZWRPckluRmxpZ2h0KGRlc3QpIHx8IGRlc3QuX3N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgY29uc3QgZGVzdENsb3NlZCA9IG5ldyBUeXBlRXJyb3IoJ3RoZSBkZXN0aW5hdGlvbiB3cml0YWJsZSBzdHJlYW0gY2xvc2VkIGJlZm9yZSBhbGwgZGF0YSBjb3VsZCBiZSBwaXBlZCB0byBpdCcpO1xuICAgICAgICAgICAgaWYgKCFwcmV2ZW50Q2FuY2VsKSB7XG4gICAgICAgICAgICAgICAgc2h1dGRvd25XaXRoQWN0aW9uKCgpID0+IFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHNvdXJjZSwgZGVzdENsb3NlZCksIHRydWUsIGRlc3RDbG9zZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc2h1dGRvd24odHJ1ZSwgZGVzdENsb3NlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc2V0UHJvbWlzZUlzSGFuZGxlZFRvVHJ1ZShwaXBlTG9vcCgpKTtcbiAgICAgICAgZnVuY3Rpb24gd2FpdEZvcldyaXRlc1RvRmluaXNoKCkge1xuICAgICAgICAgICAgLy8gQW5vdGhlciB3cml0ZSBtYXkgaGF2ZSBzdGFydGVkIHdoaWxlIHdlIHdlcmUgd2FpdGluZyBvbiB0aGlzIGN1cnJlbnRXcml0ZSwgc28gd2UgaGF2ZSB0byBiZSBzdXJlIHRvIHdhaXRcbiAgICAgICAgICAgIC8vIGZvciB0aGF0IHRvby5cbiAgICAgICAgICAgIGNvbnN0IG9sZEN1cnJlbnRXcml0ZSA9IGN1cnJlbnRXcml0ZTtcbiAgICAgICAgICAgIHJldHVybiBQZXJmb3JtUHJvbWlzZVRoZW4oY3VycmVudFdyaXRlLCAoKSA9PiBvbGRDdXJyZW50V3JpdGUgIT09IGN1cnJlbnRXcml0ZSA/IHdhaXRGb3JXcml0ZXNUb0ZpbmlzaCgpIDogdW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBpc09yQmVjb21lc0Vycm9yZWQoc3RyZWFtLCBwcm9taXNlLCBhY3Rpb24pIHtcbiAgICAgICAgICAgIGlmIChzdHJlYW0uX3N0YXRlID09PSAnZXJyb3JlZCcpIHtcbiAgICAgICAgICAgICAgICBhY3Rpb24oc3RyZWFtLl9zdG9yZWRFcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB1cG9uUmVqZWN0aW9uKHByb21pc2UsIGFjdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gaXNPckJlY29tZXNDbG9zZWQoc3RyZWFtLCBwcm9taXNlLCBhY3Rpb24pIHtcbiAgICAgICAgICAgIGlmIChzdHJlYW0uX3N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIGFjdGlvbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdXBvbkZ1bGZpbGxtZW50KHByb21pc2UsIGFjdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gc2h1dGRvd25XaXRoQWN0aW9uKGFjdGlvbiwgb3JpZ2luYWxJc0Vycm9yLCBvcmlnaW5hbEVycm9yKSB7XG4gICAgICAgICAgICBpZiAoc2h1dHRpbmdEb3duKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2h1dHRpbmdEb3duID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChkZXN0Ll9zdGF0ZSA9PT0gJ3dyaXRhYmxlJyAmJiAhV3JpdGFibGVTdHJlYW1DbG9zZVF1ZXVlZE9ySW5GbGlnaHQoZGVzdCkpIHtcbiAgICAgICAgICAgICAgICB1cG9uRnVsZmlsbG1lbnQod2FpdEZvcldyaXRlc1RvRmluaXNoKCksIGRvVGhlUmVzdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkb1RoZVJlc3QoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZ1bmN0aW9uIGRvVGhlUmVzdCgpIHtcbiAgICAgICAgICAgICAgICB1cG9uUHJvbWlzZShhY3Rpb24oKSwgKCkgPT4gZmluYWxpemUob3JpZ2luYWxJc0Vycm9yLCBvcmlnaW5hbEVycm9yKSwgbmV3RXJyb3IgPT4gZmluYWxpemUodHJ1ZSwgbmV3RXJyb3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBzaHV0ZG93bihpc0Vycm9yLCBlcnJvcikge1xuICAgICAgICAgICAgaWYgKHNodXR0aW5nRG93bikge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNodXR0aW5nRG93biA9IHRydWU7XG4gICAgICAgICAgICBpZiAoZGVzdC5fc3RhdGUgPT09ICd3cml0YWJsZScgJiYgIVdyaXRhYmxlU3RyZWFtQ2xvc2VRdWV1ZWRPckluRmxpZ2h0KGRlc3QpKSB7XG4gICAgICAgICAgICAgICAgdXBvbkZ1bGZpbGxtZW50KHdhaXRGb3JXcml0ZXNUb0ZpbmlzaCgpLCAoKSA9PiBmaW5hbGl6ZShpc0Vycm9yLCBlcnJvcikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZmluYWxpemUoaXNFcnJvciwgZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGZpbmFsaXplKGlzRXJyb3IsIGVycm9yKSB7XG4gICAgICAgICAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJSZWxlYXNlKHdyaXRlcik7XG4gICAgICAgICAgICBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNSZWxlYXNlKHJlYWRlcik7XG4gICAgICAgICAgICBpZiAoc2lnbmFsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBzaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBhYm9ydEFsZ29yaXRobSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNFcnJvcikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbn1cblxuLyoqXG4gKiBBbGxvd3MgY29udHJvbCBvZiBhIHtAbGluayBSZWFkYWJsZVN0cmVhbSB8IHJlYWRhYmxlIHN0cmVhbX0ncyBzdGF0ZSBhbmQgaW50ZXJuYWwgcXVldWUuXG4gKlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSWxsZWdhbCBjb25zdHJ1Y3RvcicpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBkZXNpcmVkIHNpemUgdG8gZmlsbCB0aGUgY29udHJvbGxlZCBzdHJlYW0ncyBpbnRlcm5hbCBxdWV1ZS4gSXQgY2FuIGJlIG5lZ2F0aXZlLCBpZiB0aGUgcXVldWUgaXNcbiAgICAgKiBvdmVyLWZ1bGwuIEFuIHVuZGVybHlpbmcgc291cmNlIG91Z2h0IHRvIHVzZSB0aGlzIGluZm9ybWF0aW9uIHRvIGRldGVybWluZSB3aGVuIGFuZCBob3cgdG8gYXBwbHkgYmFja3ByZXNzdXJlLlxuICAgICAqL1xuICAgIGdldCBkZXNpcmVkU2l6ZSgpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQxKCdkZXNpcmVkU2l6ZScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0RGVzaXJlZFNpemUodGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlcyB0aGUgY29udHJvbGxlZCByZWFkYWJsZSBzdHJlYW0uIENvbnN1bWVycyB3aWxsIHN0aWxsIGJlIGFibGUgdG8gcmVhZCBhbnkgcHJldmlvdXNseS1lbnF1ZXVlZCBjaHVua3MgZnJvbVxuICAgICAqIHRoZSBzdHJlYW0sIGJ1dCBvbmNlIHRob3NlIGFyZSByZWFkLCB0aGUgc3RyZWFtIHdpbGwgYmVjb21lIGNsb3NlZC5cbiAgICAgKi9cbiAgICBjbG9zZSgpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQxKCdjbG9zZScpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgc3RyZWFtIGlzIG5vdCBpbiBhIHN0YXRlIHRoYXQgcGVybWl0cyBjbG9zZScpO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbG9zZSh0aGlzKTtcbiAgICB9XG4gICAgZW5xdWV1ZShjaHVuayA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uJDEoJ2VucXVldWUnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIVJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYW5DbG9zZU9yRW5xdWV1ZSh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIHN0cmVhbSBpcyBub3QgaW4gYSBzdGF0ZSB0aGF0IHBlcm1pdHMgZW5xdWV1ZScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZSh0aGlzLCBjaHVuayk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEVycm9ycyB0aGUgY29udHJvbGxlZCByZWFkYWJsZSBzdHJlYW0sIG1ha2luZyBhbGwgZnV0dXJlIGludGVyYWN0aW9ucyB3aXRoIGl0IGZhaWwgd2l0aCB0aGUgZ2l2ZW4gZXJyb3IgYGVgLlxuICAgICAqL1xuICAgIGVycm9yKGUgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQxKCdlcnJvcicpO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcih0aGlzLCBlKTtcbiAgICB9XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIFtDYW5jZWxTdGVwc10ocmVhc29uKSB7XG4gICAgICAgIFJlc2V0UXVldWUodGhpcyk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX2NhbmNlbEFsZ29yaXRobShyZWFzb24pO1xuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zKHRoaXMpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICAvKiogQGludGVybmFsICovXG4gICAgW1B1bGxTdGVwc10ocmVhZFJlcXVlc3QpIHtcbiAgICAgICAgY29uc3Qgc3RyZWFtID0gdGhpcy5fY29udHJvbGxlZFJlYWRhYmxlU3RyZWFtO1xuICAgICAgICBpZiAodGhpcy5fcXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgY2h1bmsgPSBEZXF1ZXVlVmFsdWUodGhpcyk7XG4gICAgICAgICAgICBpZiAodGhpcy5fY2xvc2VSZXF1ZXN0ZWQgJiYgdGhpcy5fcXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyh0aGlzKTtcbiAgICAgICAgICAgICAgICBSZWFkYWJsZVN0cmVhbUNsb3NlKHN0cmVhbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZCh0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlYWRSZXF1ZXN0Ll9jaHVua1N0ZXBzKGNodW5rKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtQWRkUmVhZFJlcXVlc3Qoc3RyZWFtLCByZWFkUmVxdWVzdCk7XG4gICAgICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZCh0aGlzKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlLCB7XG4gICAgY2xvc2U6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGVucXVldWU6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGVycm9yOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBkZXNpcmVkU2l6ZTogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUsIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIHZhbHVlOiAnUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcicsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIuXG5mdW5jdGlvbiBJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIoeCkge1xuICAgIGlmICghdHlwZUlzT2JqZWN0KHgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoeCwgJ19jb250cm9sbGVkUmVhZGFibGVTdHJlYW0nKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcjtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYWxsUHVsbElmTmVlZGVkKGNvbnRyb2xsZXIpIHtcbiAgICBjb25zdCBzaG91bGRQdWxsID0gUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlclNob3VsZENhbGxQdWxsKGNvbnRyb2xsZXIpO1xuICAgIGlmICghc2hvdWxkUHVsbCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChjb250cm9sbGVyLl9wdWxsaW5nKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuX3B1bGxBZ2FpbiA9IHRydWU7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29udHJvbGxlci5fcHVsbGluZyA9IHRydWU7XG4gICAgY29uc3QgcHVsbFByb21pc2UgPSBjb250cm9sbGVyLl9wdWxsQWxnb3JpdGhtKCk7XG4gICAgdXBvblByb21pc2UocHVsbFByb21pc2UsICgpID0+IHtcbiAgICAgICAgY29udHJvbGxlci5fcHVsbGluZyA9IGZhbHNlO1xuICAgICAgICBpZiAoY29udHJvbGxlci5fcHVsbEFnYWluKSB7XG4gICAgICAgICAgICBjb250cm9sbGVyLl9wdWxsQWdhaW4gPSBmYWxzZTtcbiAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYWxsUHVsbElmTmVlZGVkKGNvbnRyb2xsZXIpO1xuICAgICAgICB9XG4gICAgfSwgZSA9PiB7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBlKTtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJTaG91bGRDYWxsUHVsbChjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlU3RyZWFtO1xuICAgIGlmICghUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlKGNvbnRyb2xsZXIpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFjb250cm9sbGVyLl9zdGFydGVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKElzUmVhZGFibGVTdHJlYW1Mb2NrZWQoc3RyZWFtKSAmJiBSZWFkYWJsZVN0cmVhbUdldE51bVJlYWRSZXF1ZXN0cyhzdHJlYW0pID4gMCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgZGVzaXJlZFNpemUgPSBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0RGVzaXJlZFNpemUoY29udHJvbGxlcik7XG4gICAgaWYgKGRlc2lyZWRTaXplID4gMCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyhjb250cm9sbGVyKSB7XG4gICAgY29udHJvbGxlci5fcHVsbEFsZ29yaXRobSA9IHVuZGVmaW5lZDtcbiAgICBjb250cm9sbGVyLl9jYW5jZWxBbGdvcml0aG0gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fc3RyYXRlZ3lTaXplQWxnb3JpdGhtID0gdW5kZWZpbmVkO1xufVxuLy8gQSBjbGllbnQgb2YgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciBtYXkgdXNlIHRoZXNlIGZ1bmN0aW9ucyBkaXJlY3RseSB0byBieXBhc3Mgc3RhdGUgY2hlY2suXG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xvc2UoY29udHJvbGxlcikge1xuICAgIGlmICghUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlKGNvbnRyb2xsZXIpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlU3RyZWFtO1xuICAgIGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkID0gdHJ1ZTtcbiAgICBpZiAoY29udHJvbGxlci5fcXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcik7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtQ2xvc2Uoc3RyZWFtKTtcbiAgICB9XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZShjb250cm9sbGVyLCBjaHVuaykge1xuICAgIGlmICghUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlKGNvbnRyb2xsZXIpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlU3RyZWFtO1xuICAgIGlmIChJc1JlYWRhYmxlU3RyZWFtTG9ja2VkKHN0cmVhbSkgJiYgUmVhZGFibGVTdHJlYW1HZXROdW1SZWFkUmVxdWVzdHMoc3RyZWFtKSA+IDApIHtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1GdWxmaWxsUmVhZFJlcXVlc3Qoc3RyZWFtLCBjaHVuaywgZmFsc2UpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgbGV0IGNodW5rU2l6ZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNodW5rU2l6ZSA9IGNvbnRyb2xsZXIuX3N0cmF0ZWd5U2l6ZUFsZ29yaXRobShjaHVuayk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGNodW5rU2l6ZUUpIHtcbiAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBjaHVua1NpemVFKTtcbiAgICAgICAgICAgIHRocm93IGNodW5rU2l6ZUU7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIEVucXVldWVWYWx1ZVdpdGhTaXplKGNvbnRyb2xsZXIsIGNodW5rLCBjaHVua1NpemUpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlbnF1ZXVlRSkge1xuICAgICAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKGNvbnRyb2xsZXIsIGVucXVldWVFKTtcbiAgICAgICAgICAgIHRocm93IGVucXVldWVFO1xuICAgICAgICB9XG4gICAgfVxuICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYWxsUHVsbElmTmVlZGVkKGNvbnRyb2xsZXIpO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKGNvbnRyb2xsZXIsIGUpIHtcbiAgICBjb25zdCBzdHJlYW0gPSBjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVTdHJlYW07XG4gICAgaWYgKHN0cmVhbS5fc3RhdGUgIT09ICdyZWFkYWJsZScpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBSZXNldFF1ZXVlKGNvbnRyb2xsZXIpO1xuICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcik7XG4gICAgUmVhZGFibGVTdHJlYW1FcnJvcihzdHJlYW0sIGUpO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldERlc2lyZWRTaXplKGNvbnRyb2xsZXIpIHtcbiAgICBjb25zdCBzdGF0ZSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZVN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKHN0YXRlID09PSAnZXJyb3JlZCcpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmIChzdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIHJldHVybiBjb250cm9sbGVyLl9zdHJhdGVneUhXTSAtIGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplO1xufVxuLy8gVGhpcyBpcyB1c2VkIGluIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBUcmFuc2Zvcm1TdHJlYW0uXG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVySGFzQmFja3ByZXNzdXJlKGNvbnRyb2xsZXIpIHtcbiAgICBpZiAoUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlclNob3VsZENhbGxQdWxsKGNvbnRyb2xsZXIpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2FuQ2xvc2VPckVucXVldWUoY29udHJvbGxlcikge1xuICAgIGNvbnN0IHN0YXRlID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlU3RyZWFtLl9zdGF0ZTtcbiAgICBpZiAoIWNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkICYmIHN0YXRlID09PSAncmVhZGFibGUnKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBTZXRVcFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCBzdGFydEFsZ29yaXRobSwgcHVsbEFsZ29yaXRobSwgY2FuY2VsQWxnb3JpdGhtLCBoaWdoV2F0ZXJNYXJrLCBzaXplQWxnb3JpdGhtKSB7XG4gICAgY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlU3RyZWFtID0gc3RyZWFtO1xuICAgIGNvbnRyb2xsZXIuX3F1ZXVlID0gdW5kZWZpbmVkO1xuICAgIGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplID0gdW5kZWZpbmVkO1xuICAgIFJlc2V0UXVldWUoY29udHJvbGxlcik7XG4gICAgY29udHJvbGxlci5fc3RhcnRlZCA9IGZhbHNlO1xuICAgIGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkID0gZmFsc2U7XG4gICAgY29udHJvbGxlci5fcHVsbEFnYWluID0gZmFsc2U7XG4gICAgY29udHJvbGxlci5fcHVsbGluZyA9IGZhbHNlO1xuICAgIGNvbnRyb2xsZXIuX3N0cmF0ZWd5U2l6ZUFsZ29yaXRobSA9IHNpemVBbGdvcml0aG07XG4gICAgY29udHJvbGxlci5fc3RyYXRlZ3lIV00gPSBoaWdoV2F0ZXJNYXJrO1xuICAgIGNvbnRyb2xsZXIuX3B1bGxBbGdvcml0aG0gPSBwdWxsQWxnb3JpdGhtO1xuICAgIGNvbnRyb2xsZXIuX2NhbmNlbEFsZ29yaXRobSA9IGNhbmNlbEFsZ29yaXRobTtcbiAgICBzdHJlYW0uX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciA9IGNvbnRyb2xsZXI7XG4gICAgY29uc3Qgc3RhcnRSZXN1bHQgPSBzdGFydEFsZ29yaXRobSgpO1xuICAgIHVwb25Qcm9taXNlKHByb21pc2VSZXNvbHZlZFdpdGgoc3RhcnRSZXN1bHQpLCAoKSA9PiB7XG4gICAgICAgIGNvbnRyb2xsZXIuX3N0YXJ0ZWQgPSB0cnVlO1xuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKTtcbiAgICB9LCByID0+IHtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKGNvbnRyb2xsZXIsIHIpO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gU2V0VXBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRnJvbVVuZGVybHlpbmdTb3VyY2Uoc3RyZWFtLCB1bmRlcmx5aW5nU291cmNlLCBoaWdoV2F0ZXJNYXJrLCBzaXplQWxnb3JpdGhtKSB7XG4gICAgY29uc3QgY29udHJvbGxlciA9IE9iamVjdC5jcmVhdGUoUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUpO1xuICAgIGxldCBzdGFydEFsZ29yaXRobSA9ICgpID0+IHVuZGVmaW5lZDtcbiAgICBsZXQgcHVsbEFsZ29yaXRobSA9ICgpID0+IHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICBsZXQgY2FuY2VsQWxnb3JpdGhtID0gKCkgPT4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgIGlmICh1bmRlcmx5aW5nU291cmNlLnN0YXJ0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc3RhcnRBbGdvcml0aG0gPSAoKSA9PiB1bmRlcmx5aW5nU291cmNlLnN0YXJ0KGNvbnRyb2xsZXIpO1xuICAgIH1cbiAgICBpZiAodW5kZXJseWluZ1NvdXJjZS5wdWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcHVsbEFsZ29yaXRobSA9ICgpID0+IHVuZGVybHlpbmdTb3VyY2UucHVsbChjb250cm9sbGVyKTtcbiAgICB9XG4gICAgaWYgKHVuZGVybHlpbmdTb3VyY2UuY2FuY2VsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY2FuY2VsQWxnb3JpdGhtID0gcmVhc29uID0+IHVuZGVybHlpbmdTb3VyY2UuY2FuY2VsKHJlYXNvbik7XG4gICAgfVxuICAgIFNldFVwUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcihzdHJlYW0sIGNvbnRyb2xsZXIsIHN0YXJ0QWxnb3JpdGhtLCBwdWxsQWxnb3JpdGhtLCBjYW5jZWxBbGdvcml0aG0sIGhpZ2hXYXRlck1hcmssIHNpemVBbGdvcml0aG0pO1xufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIuXG5mdW5jdGlvbiBkZWZhdWx0Q29udHJvbGxlckJyYW5kQ2hlY2tFeGNlcHRpb24kMShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoYFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJgKTtcbn1cblxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1UZWUoc3RyZWFtLCBjbG9uZUZvckJyYW5jaDIpIHtcbiAgICBpZiAoSXNSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyKHN0cmVhbS5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyKSkge1xuICAgICAgICByZXR1cm4gUmVhZGFibGVCeXRlU3RyZWFtVGVlKHN0cmVhbSk7XG4gICAgfVxuICAgIHJldHVybiBSZWFkYWJsZVN0cmVhbURlZmF1bHRUZWUoc3RyZWFtKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFRlZShzdHJlYW0sIGNsb25lRm9yQnJhbmNoMikge1xuICAgIGNvbnN0IHJlYWRlciA9IEFjcXVpcmVSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIoc3RyZWFtKTtcbiAgICBsZXQgcmVhZGluZyA9IGZhbHNlO1xuICAgIGxldCBjYW5jZWxlZDEgPSBmYWxzZTtcbiAgICBsZXQgY2FuY2VsZWQyID0gZmFsc2U7XG4gICAgbGV0IHJlYXNvbjE7XG4gICAgbGV0IHJlYXNvbjI7XG4gICAgbGV0IGJyYW5jaDE7XG4gICAgbGV0IGJyYW5jaDI7XG4gICAgbGV0IHJlc29sdmVDYW5jZWxQcm9taXNlO1xuICAgIGNvbnN0IGNhbmNlbFByb21pc2UgPSBuZXdQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICByZXNvbHZlQ2FuY2VsUHJvbWlzZSA9IHJlc29sdmU7XG4gICAgfSk7XG4gICAgZnVuY3Rpb24gcHVsbEFsZ29yaXRobSgpIHtcbiAgICAgICAgaWYgKHJlYWRpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVhZGluZyA9IHRydWU7XG4gICAgICAgIGNvbnN0IHJlYWRSZXF1ZXN0ID0ge1xuICAgICAgICAgICAgX2NodW5rU3RlcHM6IGNodW5rID0+IHtcbiAgICAgICAgICAgICAgICAvLyBUaGlzIG5lZWRzIHRvIGJlIGRlbGF5ZWQgYSBtaWNyb3Rhc2sgYmVjYXVzZSBpdCB0YWtlcyBhdCBsZWFzdCBhIG1pY3JvdGFzayB0byBkZXRlY3QgZXJyb3JzICh1c2luZ1xuICAgICAgICAgICAgICAgIC8vIHJlYWRlci5fY2xvc2VkUHJvbWlzZSBiZWxvdyksIGFuZCB3ZSB3YW50IGVycm9ycyBpbiBzdHJlYW0gdG8gZXJyb3IgYm90aCBicmFuY2hlcyBpbW1lZGlhdGVseS4gV2UgY2Fubm90IGxldFxuICAgICAgICAgICAgICAgIC8vIHN1Y2Nlc3NmdWwgc3luY2hyb25vdXNseS1hdmFpbGFibGUgcmVhZHMgZ2V0IGFoZWFkIG9mIGFzeW5jaHJvbm91c2x5LWF2YWlsYWJsZSBlcnJvcnMuXG4gICAgICAgICAgICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWFkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNodW5rMSA9IGNodW5rO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaHVuazIgPSBjaHVuaztcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlcmUgaXMgbm8gd2F5IHRvIGFjY2VzcyB0aGUgY2xvbmluZyBjb2RlIHJpZ2h0IG5vdyBpbiB0aGUgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uLlxuICAgICAgICAgICAgICAgICAgICAvLyBJZiB3ZSBhZGQgb25lIHRoZW4gd2UnbGwgbmVlZCBhbiBpbXBsZW1lbnRhdGlvbiBmb3Igc2VyaWFsaXphYmxlIG9iamVjdHMuXG4gICAgICAgICAgICAgICAgICAgIC8vIGlmICghY2FuY2VsZWQyICYmIGNsb25lRm9yQnJhbmNoMikge1xuICAgICAgICAgICAgICAgICAgICAvLyAgIGNodW5rMiA9IFN0cnVjdHVyZWREZXNlcmlhbGl6ZShTdHJ1Y3R1cmVkU2VyaWFsaXplKGNodW5rMikpO1xuICAgICAgICAgICAgICAgICAgICAvLyB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghY2FuY2VsZWQxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZShicmFuY2gxLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIGNodW5rMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjYW5jZWxlZDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFbnF1ZXVlKGJyYW5jaDIuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgY2h1bmsyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF9jbG9zZVN0ZXBzOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGlmICghY2FuY2VsZWQxKSB7XG4gICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbG9zZShicmFuY2gxLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIWNhbmNlbGVkMikge1xuICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xvc2UoYnJhbmNoMi5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFjYW5jZWxlZDEgfHwgIWNhbmNlbGVkMikge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlQ2FuY2VsUHJvbWlzZSh1bmRlZmluZWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBfZXJyb3JTdGVwczogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyUmVhZChyZWFkZXIsIHJlYWRSZXF1ZXN0KTtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gY2FuY2VsMUFsZ29yaXRobShyZWFzb24pIHtcbiAgICAgICAgY2FuY2VsZWQxID0gdHJ1ZTtcbiAgICAgICAgcmVhc29uMSA9IHJlYXNvbjtcbiAgICAgICAgaWYgKGNhbmNlbGVkMikge1xuICAgICAgICAgICAgY29uc3QgY29tcG9zaXRlUmVhc29uID0gQ3JlYXRlQXJyYXlGcm9tTGlzdChbcmVhc29uMSwgcmVhc29uMl0pO1xuICAgICAgICAgICAgY29uc3QgY2FuY2VsUmVzdWx0ID0gUmVhZGFibGVTdHJlYW1DYW5jZWwoc3RyZWFtLCBjb21wb3NpdGVSZWFzb24pO1xuICAgICAgICAgICAgcmVzb2x2ZUNhbmNlbFByb21pc2UoY2FuY2VsUmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FuY2VsUHJvbWlzZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gY2FuY2VsMkFsZ29yaXRobShyZWFzb24pIHtcbiAgICAgICAgY2FuY2VsZWQyID0gdHJ1ZTtcbiAgICAgICAgcmVhc29uMiA9IHJlYXNvbjtcbiAgICAgICAgaWYgKGNhbmNlbGVkMSkge1xuICAgICAgICAgICAgY29uc3QgY29tcG9zaXRlUmVhc29uID0gQ3JlYXRlQXJyYXlGcm9tTGlzdChbcmVhc29uMSwgcmVhc29uMl0pO1xuICAgICAgICAgICAgY29uc3QgY2FuY2VsUmVzdWx0ID0gUmVhZGFibGVTdHJlYW1DYW5jZWwoc3RyZWFtLCBjb21wb3NpdGVSZWFzb24pO1xuICAgICAgICAgICAgcmVzb2x2ZUNhbmNlbFByb21pc2UoY2FuY2VsUmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FuY2VsUHJvbWlzZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gc3RhcnRBbGdvcml0aG0oKSB7XG4gICAgICAgIC8vIGRvIG5vdGhpbmdcbiAgICB9XG4gICAgYnJhbmNoMSA9IENyZWF0ZVJlYWRhYmxlU3RyZWFtKHN0YXJ0QWxnb3JpdGhtLCBwdWxsQWxnb3JpdGhtLCBjYW5jZWwxQWxnb3JpdGhtKTtcbiAgICBicmFuY2gyID0gQ3JlYXRlUmVhZGFibGVTdHJlYW0oc3RhcnRBbGdvcml0aG0sIHB1bGxBbGdvcml0aG0sIGNhbmNlbDJBbGdvcml0aG0pO1xuICAgIHVwb25SZWplY3Rpb24ocmVhZGVyLl9jbG9zZWRQcm9taXNlLCAocikgPT4ge1xuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3IoYnJhbmNoMS5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyLCByKTtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKGJyYW5jaDIuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgcik7XG4gICAgICAgIGlmICghY2FuY2VsZWQxIHx8ICFjYW5jZWxlZDIpIHtcbiAgICAgICAgICAgIHJlc29sdmVDYW5jZWxQcm9taXNlKHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gW2JyYW5jaDEsIGJyYW5jaDJdO1xufVxuZnVuY3Rpb24gUmVhZGFibGVCeXRlU3RyZWFtVGVlKHN0cmVhbSkge1xuICAgIGxldCByZWFkZXIgPSBBY3F1aXJlUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyKHN0cmVhbSk7XG4gICAgbGV0IHJlYWRpbmcgPSBmYWxzZTtcbiAgICBsZXQgY2FuY2VsZWQxID0gZmFsc2U7XG4gICAgbGV0IGNhbmNlbGVkMiA9IGZhbHNlO1xuICAgIGxldCByZWFzb24xO1xuICAgIGxldCByZWFzb24yO1xuICAgIGxldCBicmFuY2gxO1xuICAgIGxldCBicmFuY2gyO1xuICAgIGxldCByZXNvbHZlQ2FuY2VsUHJvbWlzZTtcbiAgICBjb25zdCBjYW5jZWxQcm9taXNlID0gbmV3UHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgICAgcmVzb2x2ZUNhbmNlbFByb21pc2UgPSByZXNvbHZlO1xuICAgIH0pO1xuICAgIGZ1bmN0aW9uIGZvcndhcmRSZWFkZXJFcnJvcih0aGlzUmVhZGVyKSB7XG4gICAgICAgIHVwb25SZWplY3Rpb24odGhpc1JlYWRlci5fY2xvc2VkUHJvbWlzZSwgciA9PiB7XG4gICAgICAgICAgICBpZiAodGhpc1JlYWRlciAhPT0gcmVhZGVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVycm9yKGJyYW5jaDEuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgcik7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRXJyb3IoYnJhbmNoMi5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyLCByKTtcbiAgICAgICAgICAgIGlmICghY2FuY2VsZWQxIHx8ICFjYW5jZWxlZDIpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlQ2FuY2VsUHJvbWlzZSh1bmRlZmluZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcHVsbFdpdGhEZWZhdWx0UmVhZGVyKCkge1xuICAgICAgICBpZiAoSXNSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIocmVhZGVyKSkge1xuICAgICAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljUmVsZWFzZShyZWFkZXIpO1xuICAgICAgICAgICAgcmVhZGVyID0gQWNxdWlyZVJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcihzdHJlYW0pO1xuICAgICAgICAgICAgZm9yd2FyZFJlYWRlckVycm9yKHJlYWRlcik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVhZFJlcXVlc3QgPSB7XG4gICAgICAgICAgICBfY2h1bmtTdGVwczogY2h1bmsgPT4ge1xuICAgICAgICAgICAgICAgIC8vIFRoaXMgbmVlZHMgdG8gYmUgZGVsYXllZCBhIG1pY3JvdGFzayBiZWNhdXNlIGl0IHRha2VzIGF0IGxlYXN0IGEgbWljcm90YXNrIHRvIGRldGVjdCBlcnJvcnMgKHVzaW5nXG4gICAgICAgICAgICAgICAgLy8gcmVhZGVyLl9jbG9zZWRQcm9taXNlIGJlbG93KSwgYW5kIHdlIHdhbnQgZXJyb3JzIGluIHN0cmVhbSB0byBlcnJvciBib3RoIGJyYW5jaGVzIGltbWVkaWF0ZWx5LiBXZSBjYW5ub3QgbGV0XG4gICAgICAgICAgICAgICAgLy8gc3VjY2Vzc2Z1bCBzeW5jaHJvbm91c2x5LWF2YWlsYWJsZSByZWFkcyBnZXQgYWhlYWQgb2YgYXN5bmNocm9ub3VzbHktYXZhaWxhYmxlIGVycm9ycy5cbiAgICAgICAgICAgICAgICBxdWV1ZU1pY3JvdGFzaygoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2h1bmsxID0gY2h1bms7XG4gICAgICAgICAgICAgICAgICAgIGxldCBjaHVuazIgPSBjaHVuaztcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjYW5jZWxlZDEgJiYgIWNhbmNlbGVkMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaHVuazIgPSBDbG9uZUFzVWludDhBcnJheShjaHVuayk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAoY2xvbmVFKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVycm9yKGJyYW5jaDEuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgY2xvbmVFKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRXJyb3IoYnJhbmNoMi5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyLCBjbG9uZUUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmVDYW5jZWxQcm9taXNlKFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHN0cmVhbSwgY2xvbmVFKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghY2FuY2VsZWQxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRW5xdWV1ZShicmFuY2gxLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIGNodW5rMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjYW5jZWxlZDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFbnF1ZXVlKGJyYW5jaDIuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgY2h1bmsyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF9jbG9zZVN0ZXBzOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGlmICghY2FuY2VsZWQxKSB7XG4gICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbG9zZShicmFuY2gxLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIWNhbmNlbGVkMikge1xuICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xvc2UoYnJhbmNoMi5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGJyYW5jaDEuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kKGJyYW5jaDEuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgMCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChicmFuY2gyLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZChicmFuY2gyLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIDApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIWNhbmNlbGVkMSB8fCAhY2FuY2VsZWQyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmVDYW5jZWxQcm9taXNlKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF9lcnJvclN0ZXBzOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXJSZWFkKHJlYWRlciwgcmVhZFJlcXVlc3QpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBwdWxsV2l0aEJZT0JSZWFkZXIodmlldywgZm9yQnJhbmNoMikge1xuICAgICAgICBpZiAoSXNSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIocmVhZGVyKSkge1xuICAgICAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljUmVsZWFzZShyZWFkZXIpO1xuICAgICAgICAgICAgcmVhZGVyID0gQWNxdWlyZVJlYWRhYmxlU3RyZWFtQllPQlJlYWRlcihzdHJlYW0pO1xuICAgICAgICAgICAgZm9yd2FyZFJlYWRlckVycm9yKHJlYWRlcik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYnlvYkJyYW5jaCA9IGZvckJyYW5jaDIgPyBicmFuY2gyIDogYnJhbmNoMTtcbiAgICAgICAgY29uc3Qgb3RoZXJCcmFuY2ggPSBmb3JCcmFuY2gyID8gYnJhbmNoMSA6IGJyYW5jaDI7XG4gICAgICAgIGNvbnN0IHJlYWRJbnRvUmVxdWVzdCA9IHtcbiAgICAgICAgICAgIF9jaHVua1N0ZXBzOiBjaHVuayA9PiB7XG4gICAgICAgICAgICAgICAgLy8gVGhpcyBuZWVkcyB0byBiZSBkZWxheWVkIGEgbWljcm90YXNrIGJlY2F1c2UgaXQgdGFrZXMgYXQgbGVhc3QgYSBtaWNyb3Rhc2sgdG8gZGV0ZWN0IGVycm9ycyAodXNpbmdcbiAgICAgICAgICAgICAgICAvLyByZWFkZXIuX2Nsb3NlZFByb21pc2UgYmVsb3cpLCBhbmQgd2Ugd2FudCBlcnJvcnMgaW4gc3RyZWFtIHRvIGVycm9yIGJvdGggYnJhbmNoZXMgaW1tZWRpYXRlbHkuIFdlIGNhbm5vdCBsZXRcbiAgICAgICAgICAgICAgICAvLyBzdWNjZXNzZnVsIHN5bmNocm9ub3VzbHktYXZhaWxhYmxlIHJlYWRzIGdldCBhaGVhZCBvZiBhc3luY2hyb25vdXNseS1hdmFpbGFibGUgZXJyb3JzLlxuICAgICAgICAgICAgICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmVhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBieW9iQ2FuY2VsZWQgPSBmb3JCcmFuY2gyID8gY2FuY2VsZWQyIDogY2FuY2VsZWQxO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvdGhlckNhbmNlbGVkID0gZm9yQnJhbmNoMiA/IGNhbmNlbGVkMSA6IGNhbmNlbGVkMjtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFvdGhlckNhbmNlbGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgY2xvbmVkQ2h1bms7XG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb25lZENodW5rID0gQ2xvbmVBc1VpbnQ4QXJyYXkoY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGNsb25lRSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFcnJvcihieW9iQnJhbmNoLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIGNsb25lRSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVycm9yKG90aGVyQnJhbmNoLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIGNsb25lRSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZUNhbmNlbFByb21pc2UoUmVhZGFibGVTdHJlYW1DYW5jZWwoc3RyZWFtLCBjbG9uZUUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWJ5b2JDYW5jZWxlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kV2l0aE5ld1ZpZXcoYnlvYkJyYW5jaC5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyLCBjaHVuayk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRW5xdWV1ZShvdGhlckJyYW5jaC5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyLCBjbG9uZWRDaHVuayk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoIWJ5b2JDYW5jZWxlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclJlc3BvbmRXaXRoTmV3VmlldyhieW9iQnJhbmNoLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIGNodW5rKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF9jbG9zZVN0ZXBzOiBjaHVuayA9PiB7XG4gICAgICAgICAgICAgICAgcmVhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJ5b2JDYW5jZWxlZCA9IGZvckJyYW5jaDIgPyBjYW5jZWxlZDIgOiBjYW5jZWxlZDE7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3RoZXJDYW5jZWxlZCA9IGZvckJyYW5jaDIgPyBjYW5jZWxlZDEgOiBjYW5jZWxlZDI7XG4gICAgICAgICAgICAgICAgaWYgKCFieW9iQ2FuY2VsZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNsb3NlKGJ5b2JCcmFuY2guX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghb3RoZXJDYW5jZWxlZCkge1xuICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xvc2Uob3RoZXJCcmFuY2guX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChjaHVuayAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghYnlvYkNhbmNlbGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZFdpdGhOZXdWaWV3KGJ5b2JCcmFuY2guX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghb3RoZXJDYW5jZWxlZCAmJiBvdGhlckJyYW5jaC5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kKG90aGVyQnJhbmNoLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIDApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghYnlvYkNhbmNlbGVkIHx8ICFvdGhlckNhbmNlbGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmVDYW5jZWxQcm9taXNlKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF9lcnJvclN0ZXBzOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXJSZWFkKHJlYWRlciwgdmlldywgcmVhZEludG9SZXF1ZXN0KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcHVsbDFBbGdvcml0aG0oKSB7XG4gICAgICAgIGlmIChyZWFkaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHJlYWRpbmcgPSB0cnVlO1xuICAgICAgICBjb25zdCBieW9iUmVxdWVzdCA9IFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJHZXRCWU9CUmVxdWVzdChicmFuY2gxLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIpO1xuICAgICAgICBpZiAoYnlvYlJlcXVlc3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHB1bGxXaXRoRGVmYXVsdFJlYWRlcigpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcHVsbFdpdGhCWU9CUmVhZGVyKGJ5b2JSZXF1ZXN0Ll92aWV3LCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcHVsbDJBbGdvcml0aG0oKSB7XG4gICAgICAgIGlmIChyZWFkaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHJlYWRpbmcgPSB0cnVlO1xuICAgICAgICBjb25zdCBieW9iUmVxdWVzdCA9IFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJHZXRCWU9CUmVxdWVzdChicmFuY2gyLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIpO1xuICAgICAgICBpZiAoYnlvYlJlcXVlc3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHB1bGxXaXRoRGVmYXVsdFJlYWRlcigpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcHVsbFdpdGhCWU9CUmVhZGVyKGJ5b2JSZXF1ZXN0Ll92aWV3LCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBjYW5jZWwxQWxnb3JpdGhtKHJlYXNvbikge1xuICAgICAgICBjYW5jZWxlZDEgPSB0cnVlO1xuICAgICAgICByZWFzb24xID0gcmVhc29uO1xuICAgICAgICBpZiAoY2FuY2VsZWQyKSB7XG4gICAgICAgICAgICBjb25zdCBjb21wb3NpdGVSZWFzb24gPSBDcmVhdGVBcnJheUZyb21MaXN0KFtyZWFzb24xLCByZWFzb24yXSk7XG4gICAgICAgICAgICBjb25zdCBjYW5jZWxSZXN1bHQgPSBSZWFkYWJsZVN0cmVhbUNhbmNlbChzdHJlYW0sIGNvbXBvc2l0ZVJlYXNvbik7XG4gICAgICAgICAgICByZXNvbHZlQ2FuY2VsUHJvbWlzZShjYW5jZWxSZXN1bHQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYW5jZWxQcm9taXNlO1xuICAgIH1cbiAgICBmdW5jdGlvbiBjYW5jZWwyQWxnb3JpdGhtKHJlYXNvbikge1xuICAgICAgICBjYW5jZWxlZDIgPSB0cnVlO1xuICAgICAgICByZWFzb24yID0gcmVhc29uO1xuICAgICAgICBpZiAoY2FuY2VsZWQxKSB7XG4gICAgICAgICAgICBjb25zdCBjb21wb3NpdGVSZWFzb24gPSBDcmVhdGVBcnJheUZyb21MaXN0KFtyZWFzb24xLCByZWFzb24yXSk7XG4gICAgICAgICAgICBjb25zdCBjYW5jZWxSZXN1bHQgPSBSZWFkYWJsZVN0cmVhbUNhbmNlbChzdHJlYW0sIGNvbXBvc2l0ZVJlYXNvbik7XG4gICAgICAgICAgICByZXNvbHZlQ2FuY2VsUHJvbWlzZShjYW5jZWxSZXN1bHQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYW5jZWxQcm9taXNlO1xuICAgIH1cbiAgICBmdW5jdGlvbiBzdGFydEFsZ29yaXRobSgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBicmFuY2gxID0gQ3JlYXRlUmVhZGFibGVCeXRlU3RyZWFtKHN0YXJ0QWxnb3JpdGhtLCBwdWxsMUFsZ29yaXRobSwgY2FuY2VsMUFsZ29yaXRobSk7XG4gICAgYnJhbmNoMiA9IENyZWF0ZVJlYWRhYmxlQnl0ZVN0cmVhbShzdGFydEFsZ29yaXRobSwgcHVsbDJBbGdvcml0aG0sIGNhbmNlbDJBbGdvcml0aG0pO1xuICAgIGZvcndhcmRSZWFkZXJFcnJvcihyZWFkZXIpO1xuICAgIHJldHVybiBbYnJhbmNoMSwgYnJhbmNoMl07XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nRGVmYXVsdE9yQnl0ZVNvdXJjZShzb3VyY2UsIGNvbnRleHQpIHtcbiAgICBhc3NlcnREaWN0aW9uYXJ5KHNvdXJjZSwgY29udGV4dCk7XG4gICAgY29uc3Qgb3JpZ2luYWwgPSBzb3VyY2U7XG4gICAgY29uc3QgYXV0b0FsbG9jYXRlQ2h1bmtTaXplID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLmF1dG9BbGxvY2F0ZUNodW5rU2l6ZTtcbiAgICBjb25zdCBjYW5jZWwgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwuY2FuY2VsO1xuICAgIGNvbnN0IHB1bGwgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwucHVsbDtcbiAgICBjb25zdCBzdGFydCA9IG9yaWdpbmFsID09PSBudWxsIHx8IG9yaWdpbmFsID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcmlnaW5hbC5zdGFydDtcbiAgICBjb25zdCB0eXBlID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLnR5cGU7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgYXV0b0FsbG9jYXRlQ2h1bmtTaXplOiBhdXRvQWxsb2NhdGVDaHVua1NpemUgPT09IHVuZGVmaW5lZCA/XG4gICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgY29udmVydFVuc2lnbmVkTG9uZ0xvbmdXaXRoRW5mb3JjZVJhbmdlKGF1dG9BbGxvY2F0ZUNodW5rU2l6ZSwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnYXV0b0FsbG9jYXRlQ2h1bmtTaXplJyB0aGF0YCksXG4gICAgICAgIGNhbmNlbDogY2FuY2VsID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlQ2FuY2VsQ2FsbGJhY2soY2FuY2VsLCBvcmlnaW5hbCwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnY2FuY2VsJyB0aGF0YCksXG4gICAgICAgIHB1bGw6IHB1bGwgPT09IHVuZGVmaW5lZCA/XG4gICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgY29udmVydFVuZGVybHlpbmdTb3VyY2VQdWxsQ2FsbGJhY2socHVsbCwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3B1bGwnIHRoYXRgKSxcbiAgICAgICAgc3RhcnQ6IHN0YXJ0ID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlU3RhcnRDYWxsYmFjayhzdGFydCwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3N0YXJ0JyB0aGF0YCksXG4gICAgICAgIHR5cGU6IHR5cGUgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGNvbnZlcnRSZWFkYWJsZVN0cmVhbVR5cGUodHlwZSwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAndHlwZScgdGhhdGApXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlQ2FuY2VsQ2FsbGJhY2soZm4sIG9yaWdpbmFsLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RnVuY3Rpb24oZm4sIGNvbnRleHQpO1xuICAgIHJldHVybiAocmVhc29uKSA9PiBwcm9taXNlQ2FsbChmbiwgb3JpZ2luYWwsIFtyZWFzb25dKTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlUHVsbENhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKGNvbnRyb2xsZXIpID0+IHByb21pc2VDYWxsKGZuLCBvcmlnaW5hbCwgW2NvbnRyb2xsZXJdKTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlU3RhcnRDYWxsYmFjayhmbiwgb3JpZ2luYWwsIGNvbnRleHQpIHtcbiAgICBhc3NlcnRGdW5jdGlvbihmbiwgY29udGV4dCk7XG4gICAgcmV0dXJuIChjb250cm9sbGVyKSA9PiByZWZsZWN0Q2FsbChmbiwgb3JpZ2luYWwsIFtjb250cm9sbGVyXSk7XG59XG5mdW5jdGlvbiBjb252ZXJ0UmVhZGFibGVTdHJlYW1UeXBlKHR5cGUsIGNvbnRleHQpIHtcbiAgICB0eXBlID0gYCR7dHlwZX1gO1xuICAgIGlmICh0eXBlICE9PSAnYnl0ZXMnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y29udGV4dH0gJyR7dHlwZX0nIGlzIG5vdCBhIHZhbGlkIGVudW1lcmF0aW9uIHZhbHVlIGZvciBSZWFkYWJsZVN0cmVhbVR5cGVgKTtcbiAgICB9XG4gICAgcmV0dXJuIHR5cGU7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRSZWFkZXJPcHRpb25zKG9wdGlvbnMsIGNvbnRleHQpIHtcbiAgICBhc3NlcnREaWN0aW9uYXJ5KG9wdGlvbnMsIGNvbnRleHQpO1xuICAgIGNvbnN0IG1vZGUgPSBvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9wdGlvbnMubW9kZTtcbiAgICByZXR1cm4ge1xuICAgICAgICBtb2RlOiBtb2RlID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBjb252ZXJ0UmVhZGFibGVTdHJlYW1SZWFkZXJNb2RlKG1vZGUsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ21vZGUnIHRoYXRgKVxuICAgIH07XG59XG5mdW5jdGlvbiBjb252ZXJ0UmVhZGFibGVTdHJlYW1SZWFkZXJNb2RlKG1vZGUsIGNvbnRleHQpIHtcbiAgICBtb2RlID0gYCR7bW9kZX1gO1xuICAgIGlmIChtb2RlICE9PSAnYnlvYicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjb250ZXh0fSAnJHttb2RlfScgaXMgbm90IGEgdmFsaWQgZW51bWVyYXRpb24gdmFsdWUgZm9yIFJlYWRhYmxlU3RyZWFtUmVhZGVyTW9kZWApO1xuICAgIH1cbiAgICByZXR1cm4gbW9kZTtcbn1cblxuZnVuY3Rpb24gY29udmVydEl0ZXJhdG9yT3B0aW9ucyhvcHRpb25zLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RGljdGlvbmFyeShvcHRpb25zLCBjb250ZXh0KTtcbiAgICBjb25zdCBwcmV2ZW50Q2FuY2VsID0gb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZXZlbnRDYW5jZWw7XG4gICAgcmV0dXJuIHsgcHJldmVudENhbmNlbDogQm9vbGVhbihwcmV2ZW50Q2FuY2VsKSB9O1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0UGlwZU9wdGlvbnMob3B0aW9ucywgY29udGV4dCkge1xuICAgIGFzc2VydERpY3Rpb25hcnkob3B0aW9ucywgY29udGV4dCk7XG4gICAgY29uc3QgcHJldmVudEFib3J0ID0gb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZXZlbnRBYm9ydDtcbiAgICBjb25zdCBwcmV2ZW50Q2FuY2VsID0gb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZXZlbnRDYW5jZWw7XG4gICAgY29uc3QgcHJldmVudENsb3NlID0gb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZXZlbnRDbG9zZTtcbiAgICBjb25zdCBzaWduYWwgPSBvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9wdGlvbnMuc2lnbmFsO1xuICAgIGlmIChzaWduYWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhc3NlcnRBYm9ydFNpZ25hbChzaWduYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3NpZ25hbCcgdGhhdGApO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBwcmV2ZW50QWJvcnQ6IEJvb2xlYW4ocHJldmVudEFib3J0KSxcbiAgICAgICAgcHJldmVudENhbmNlbDogQm9vbGVhbihwcmV2ZW50Q2FuY2VsKSxcbiAgICAgICAgcHJldmVudENsb3NlOiBCb29sZWFuKHByZXZlbnRDbG9zZSksXG4gICAgICAgIHNpZ25hbFxuICAgIH07XG59XG5mdW5jdGlvbiBhc3NlcnRBYm9ydFNpZ25hbChzaWduYWwsIGNvbnRleHQpIHtcbiAgICBpZiAoIWlzQWJvcnRTaWduYWwoc2lnbmFsKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke2NvbnRleHR9IGlzIG5vdCBhbiBBYm9ydFNpZ25hbC5gKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRSZWFkYWJsZVdyaXRhYmxlUGFpcihwYWlyLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RGljdGlvbmFyeShwYWlyLCBjb250ZXh0KTtcbiAgICBjb25zdCByZWFkYWJsZSA9IHBhaXIgPT09IG51bGwgfHwgcGFpciA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFpci5yZWFkYWJsZTtcbiAgICBhc3NlcnRSZXF1aXJlZEZpZWxkKHJlYWRhYmxlLCAncmVhZGFibGUnLCAnUmVhZGFibGVXcml0YWJsZVBhaXInKTtcbiAgICBhc3NlcnRSZWFkYWJsZVN0cmVhbShyZWFkYWJsZSwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAncmVhZGFibGUnIHRoYXRgKTtcbiAgICBjb25zdCB3cml0YWJsZSA9IHBhaXIgPT09IG51bGwgfHwgcGFpciA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFpci53cml0YWJsZTtcbiAgICBhc3NlcnRSZXF1aXJlZEZpZWxkKHdyaXRhYmxlLCAnd3JpdGFibGUnLCAnUmVhZGFibGVXcml0YWJsZVBhaXInKTtcbiAgICBhc3NlcnRXcml0YWJsZVN0cmVhbSh3cml0YWJsZSwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnd3JpdGFibGUnIHRoYXRgKTtcbiAgICByZXR1cm4geyByZWFkYWJsZSwgd3JpdGFibGUgfTtcbn1cblxuLyoqXG4gKiBBIHJlYWRhYmxlIHN0cmVhbSByZXByZXNlbnRzIGEgc291cmNlIG9mIGRhdGEsIGZyb20gd2hpY2ggeW91IGNhbiByZWFkLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuY2xhc3MgUmVhZGFibGVTdHJlYW0ge1xuICAgIGNvbnN0cnVjdG9yKHJhd1VuZGVybHlpbmdTb3VyY2UgPSB7fSwgcmF3U3RyYXRlZ3kgPSB7fSkge1xuICAgICAgICBpZiAocmF3VW5kZXJseWluZ1NvdXJjZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByYXdVbmRlcmx5aW5nU291cmNlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGFzc2VydE9iamVjdChyYXdVbmRlcmx5aW5nU291cmNlLCAnRmlyc3QgcGFyYW1ldGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RyYXRlZ3kgPSBjb252ZXJ0UXVldWluZ1N0cmF0ZWd5KHJhd1N0cmF0ZWd5LCAnU2Vjb25kIHBhcmFtZXRlcicpO1xuICAgICAgICBjb25zdCB1bmRlcmx5aW5nU291cmNlID0gY29udmVydFVuZGVybHlpbmdEZWZhdWx0T3JCeXRlU291cmNlKHJhd1VuZGVybHlpbmdTb3VyY2UsICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgSW5pdGlhbGl6ZVJlYWRhYmxlU3RyZWFtKHRoaXMpO1xuICAgICAgICBpZiAodW5kZXJseWluZ1NvdXJjZS50eXBlID09PSAnYnl0ZXMnKSB7XG4gICAgICAgICAgICBpZiAoc3RyYXRlZ3kuc2l6ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSBzdHJhdGVneSBmb3IgYSBieXRlIHN0cmVhbSBjYW5ub3QgaGF2ZSBhIHNpemUgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGhpZ2hXYXRlck1hcmsgPSBFeHRyYWN0SGlnaFdhdGVyTWFyayhzdHJhdGVneSwgMCk7XG4gICAgICAgICAgICBTZXRVcFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJGcm9tVW5kZXJseWluZ1NvdXJjZSh0aGlzLCB1bmRlcmx5aW5nU291cmNlLCBoaWdoV2F0ZXJNYXJrKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHNpemVBbGdvcml0aG0gPSBFeHRyYWN0U2l6ZUFsZ29yaXRobShzdHJhdGVneSk7XG4gICAgICAgICAgICBjb25zdCBoaWdoV2F0ZXJNYXJrID0gRXh0cmFjdEhpZ2hXYXRlck1hcmsoc3RyYXRlZ3ksIDEpO1xuICAgICAgICAgICAgU2V0VXBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRnJvbVVuZGVybHlpbmdTb3VyY2UodGhpcywgdW5kZXJseWluZ1NvdXJjZSwgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogV2hldGhlciBvciBub3QgdGhlIHJlYWRhYmxlIHN0cmVhbSBpcyBsb2NrZWQgdG8gYSB7QGxpbmsgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyIHwgcmVhZGVyfS5cbiAgICAgKi9cbiAgICBnZXQgbG9ja2VkKCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW0odGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IHN0cmVhbUJyYW5kQ2hlY2tFeGNlcHRpb24kMSgnbG9ja2VkJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIElzUmVhZGFibGVTdHJlYW1Mb2NrZWQodGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbHMgdGhlIHN0cmVhbSwgc2lnbmFsaW5nIGEgbG9zcyBvZiBpbnRlcmVzdCBpbiB0aGUgc3RyZWFtIGJ5IGEgY29uc3VtZXIuXG4gICAgICpcbiAgICAgKiBUaGUgc3VwcGxpZWQgYHJlYXNvbmAgYXJndW1lbnQgd2lsbCBiZSBnaXZlbiB0byB0aGUgdW5kZXJseWluZyBzb3VyY2UncyB7QGxpbmsgVW5kZXJseWluZ1NvdXJjZS5jYW5jZWwgfCBjYW5jZWwoKX1cbiAgICAgKiBtZXRob2QsIHdoaWNoIG1pZ2h0IG9yIG1pZ2h0IG5vdCB1c2UgaXQuXG4gICAgICovXG4gICAgY2FuY2VsKHJlYXNvbiA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW0odGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHN0cmVhbUJyYW5kQ2hlY2tFeGNlcHRpb24kMSgnY2FuY2VsJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChJc1JlYWRhYmxlU3RyZWFtTG9ja2VkKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FuY2VsIGEgc3RyZWFtIHRoYXQgYWxyZWFkeSBoYXMgYSByZWFkZXInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHRoaXMsIHJlYXNvbik7XG4gICAgfVxuICAgIGdldFJlYWRlcihyYXdPcHRpb25zID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbSh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbiQxKCdnZXRSZWFkZXInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvcHRpb25zID0gY29udmVydFJlYWRlck9wdGlvbnMocmF3T3B0aW9ucywgJ0ZpcnN0IHBhcmFtZXRlcicpO1xuICAgICAgICBpZiAob3B0aW9ucy5tb2RlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBBY3F1aXJlUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBBY3F1aXJlUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyKHRoaXMpO1xuICAgIH1cbiAgICBwaXBlVGhyb3VnaChyYXdUcmFuc2Zvcm0sIHJhd09wdGlvbnMgPSB7fSkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW0odGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IHN0cmVhbUJyYW5kQ2hlY2tFeGNlcHRpb24kMSgncGlwZVRocm91Z2gnKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NlcnRSZXF1aXJlZEFyZ3VtZW50KHJhd1RyYW5zZm9ybSwgMSwgJ3BpcGVUaHJvdWdoJyk7XG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IGNvbnZlcnRSZWFkYWJsZVdyaXRhYmxlUGFpcihyYXdUcmFuc2Zvcm0sICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IGNvbnZlcnRQaXBlT3B0aW9ucyhyYXdPcHRpb25zLCAnU2Vjb25kIHBhcmFtZXRlcicpO1xuICAgICAgICBpZiAoSXNSZWFkYWJsZVN0cmVhbUxvY2tlZCh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLnBpcGVUaHJvdWdoIGNhbm5vdCBiZSB1c2VkIG9uIGEgbG9ja2VkIFJlYWRhYmxlU3RyZWFtJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKElzV3JpdGFibGVTdHJlYW1Mb2NrZWQodHJhbnNmb3JtLndyaXRhYmxlKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLnBpcGVUaHJvdWdoIGNhbm5vdCBiZSB1c2VkIG9uIGEgbG9ja2VkIFdyaXRhYmxlU3RyZWFtJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHJvbWlzZSA9IFJlYWRhYmxlU3RyZWFtUGlwZVRvKHRoaXMsIHRyYW5zZm9ybS53cml0YWJsZSwgb3B0aW9ucy5wcmV2ZW50Q2xvc2UsIG9wdGlvbnMucHJldmVudEFib3J0LCBvcHRpb25zLnByZXZlbnRDYW5jZWwsIG9wdGlvbnMuc2lnbmFsKTtcbiAgICAgICAgc2V0UHJvbWlzZUlzSGFuZGxlZFRvVHJ1ZShwcm9taXNlKTtcbiAgICAgICAgcmV0dXJuIHRyYW5zZm9ybS5yZWFkYWJsZTtcbiAgICB9XG4gICAgcGlwZVRvKGRlc3RpbmF0aW9uLCByYXdPcHRpb25zID0ge30pIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDEoJ3BpcGVUbycpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVzdGluYXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoYFBhcmFtZXRlciAxIGlzIHJlcXVpcmVkIGluICdwaXBlVG8nLmApO1xuICAgICAgICB9XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKG5ldyBUeXBlRXJyb3IoYFJlYWRhYmxlU3RyZWFtLnByb3RvdHlwZS5waXBlVG8ncyBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgV3JpdGFibGVTdHJlYW1gKSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG9wdGlvbnM7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBvcHRpb25zID0gY29udmVydFBpcGVPcHRpb25zKHJhd09wdGlvbnMsICdTZWNvbmQgcGFyYW1ldGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChJc1JlYWRhYmxlU3RyZWFtTG9ja2VkKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCdSZWFkYWJsZVN0cmVhbS5wcm90b3R5cGUucGlwZVRvIGNhbm5vdCBiZSB1c2VkIG9uIGEgbG9ja2VkIFJlYWRhYmxlU3RyZWFtJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChJc1dyaXRhYmxlU3RyZWFtTG9ja2VkKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgobmV3IFR5cGVFcnJvcignUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLnBpcGVUbyBjYW5ub3QgYmUgdXNlZCBvbiBhIGxvY2tlZCBXcml0YWJsZVN0cmVhbScpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhZGFibGVTdHJlYW1QaXBlVG8odGhpcywgZGVzdGluYXRpb24sIG9wdGlvbnMucHJldmVudENsb3NlLCBvcHRpb25zLnByZXZlbnRBYm9ydCwgb3B0aW9ucy5wcmV2ZW50Q2FuY2VsLCBvcHRpb25zLnNpZ25hbCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRlZXMgdGhpcyByZWFkYWJsZSBzdHJlYW0sIHJldHVybmluZyBhIHR3by1lbGVtZW50IGFycmF5IGNvbnRhaW5pbmcgdGhlIHR3byByZXN1bHRpbmcgYnJhbmNoZXMgYXNcbiAgICAgKiBuZXcge0BsaW5rIFJlYWRhYmxlU3RyZWFtfSBpbnN0YW5jZXMuXG4gICAgICpcbiAgICAgKiBUZWVpbmcgYSBzdHJlYW0gd2lsbCBsb2NrIGl0LCBwcmV2ZW50aW5nIGFueSBvdGhlciBjb25zdW1lciBmcm9tIGFjcXVpcmluZyBhIHJlYWRlci5cbiAgICAgKiBUbyBjYW5jZWwgdGhlIHN0cmVhbSwgY2FuY2VsIGJvdGggb2YgdGhlIHJlc3VsdGluZyBicmFuY2hlczsgYSBjb21wb3NpdGUgY2FuY2VsbGF0aW9uIHJlYXNvbiB3aWxsIHRoZW4gYmVcbiAgICAgKiBwcm9wYWdhdGVkIHRvIHRoZSBzdHJlYW0ncyB1bmRlcmx5aW5nIHNvdXJjZS5cbiAgICAgKlxuICAgICAqIE5vdGUgdGhhdCB0aGUgY2h1bmtzIHNlZW4gaW4gZWFjaCBicmFuY2ggd2lsbCBiZSB0aGUgc2FtZSBvYmplY3QuIElmIHRoZSBjaHVua3MgYXJlIG5vdCBpbW11dGFibGUsXG4gICAgICogdGhpcyBjb3VsZCBhbGxvdyBpbnRlcmZlcmVuY2UgYmV0d2VlbiB0aGUgdHdvIGJyYW5jaGVzLlxuICAgICAqL1xuICAgIHRlZSgpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDEoJ3RlZScpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJyYW5jaGVzID0gUmVhZGFibGVTdHJlYW1UZWUodGhpcyk7XG4gICAgICAgIHJldHVybiBDcmVhdGVBcnJheUZyb21MaXN0KGJyYW5jaGVzKTtcbiAgICB9XG4gICAgdmFsdWVzKHJhd09wdGlvbnMgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDEoJ3ZhbHVlcycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBjb252ZXJ0SXRlcmF0b3JPcHRpb25zKHJhd09wdGlvbnMsICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgcmV0dXJuIEFjcXVpcmVSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3IodGhpcywgb3B0aW9ucy5wcmV2ZW50Q2FuY2VsKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhSZWFkYWJsZVN0cmVhbS5wcm90b3R5cGUsIHtcbiAgICBjYW5jZWw6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGdldFJlYWRlcjogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgcGlwZVRocm91Z2g6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIHBpcGVUbzogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgdGVlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICB2YWx1ZXM6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGxvY2tlZDogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLCBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZywge1xuICAgICAgICB2YWx1ZTogJ1JlYWRhYmxlU3RyZWFtJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLmFzeW5jSXRlcmF0b3IgPT09ICdzeW1ib2wnKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlU3RyZWFtLnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwuYXN5bmNJdGVyYXRvciwge1xuICAgICAgICB2YWx1ZTogUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLnZhbHVlcyxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtLlxuLy8gVGhyb3dzIGlmIGFuZCBvbmx5IGlmIHN0YXJ0QWxnb3JpdGhtIHRocm93cy5cbmZ1bmN0aW9uIENyZWF0ZVJlYWRhYmxlU3RyZWFtKHN0YXJ0QWxnb3JpdGhtLCBwdWxsQWxnb3JpdGhtLCBjYW5jZWxBbGdvcml0aG0sIGhpZ2hXYXRlck1hcmsgPSAxLCBzaXplQWxnb3JpdGhtID0gKCkgPT4gMSkge1xuICAgIGNvbnN0IHN0cmVhbSA9IE9iamVjdC5jcmVhdGUoUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlKTtcbiAgICBJbml0aWFsaXplUmVhZGFibGVTdHJlYW0oc3RyZWFtKTtcbiAgICBjb25zdCBjb250cm9sbGVyID0gT2JqZWN0LmNyZWF0ZShSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyLnByb3RvdHlwZSk7XG4gICAgU2V0VXBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyKHN0cmVhbSwgY29udHJvbGxlciwgc3RhcnRBbGdvcml0aG0sIHB1bGxBbGdvcml0aG0sIGNhbmNlbEFsZ29yaXRobSwgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSk7XG4gICAgcmV0dXJuIHN0cmVhbTtcbn1cbi8vIFRocm93cyBpZiBhbmQgb25seSBpZiBzdGFydEFsZ29yaXRobSB0aHJvd3MuXG5mdW5jdGlvbiBDcmVhdGVSZWFkYWJsZUJ5dGVTdHJlYW0oc3RhcnRBbGdvcml0aG0sIHB1bGxBbGdvcml0aG0sIGNhbmNlbEFsZ29yaXRobSkge1xuICAgIGNvbnN0IHN0cmVhbSA9IE9iamVjdC5jcmVhdGUoUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlKTtcbiAgICBJbml0aWFsaXplUmVhZGFibGVTdHJlYW0oc3RyZWFtKTtcbiAgICBjb25zdCBjb250cm9sbGVyID0gT2JqZWN0LmNyZWF0ZShSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLnByb3RvdHlwZSk7XG4gICAgU2V0VXBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyKHN0cmVhbSwgY29udHJvbGxlciwgc3RhcnRBbGdvcml0aG0sIHB1bGxBbGdvcml0aG0sIGNhbmNlbEFsZ29yaXRobSwgMCwgdW5kZWZpbmVkKTtcbiAgICByZXR1cm4gc3RyZWFtO1xufVxuZnVuY3Rpb24gSW5pdGlhbGl6ZVJlYWRhYmxlU3RyZWFtKHN0cmVhbSkge1xuICAgIHN0cmVhbS5fc3RhdGUgPSAncmVhZGFibGUnO1xuICAgIHN0cmVhbS5fcmVhZGVyID0gdW5kZWZpbmVkO1xuICAgIHN0cmVhbS5fc3RvcmVkRXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgc3RyZWFtLl9kaXN0dXJiZWQgPSBmYWxzZTtcbn1cbmZ1bmN0aW9uIElzUmVhZGFibGVTdHJlYW0oeCkge1xuICAgIGlmICghdHlwZUlzT2JqZWN0KHgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoeCwgJ19yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXInKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgUmVhZGFibGVTdHJlYW07XG59XG5mdW5jdGlvbiBJc1JlYWRhYmxlU3RyZWFtTG9ja2VkKHN0cmVhbSkge1xuICAgIGlmIChzdHJlYW0uX3JlYWRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG4vLyBSZWFkYWJsZVN0cmVhbSBBUEkgZXhwb3NlZCBmb3IgY29udHJvbGxlcnMuXG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUNhbmNlbChzdHJlYW0sIHJlYXNvbikge1xuICAgIHN0cmVhbS5fZGlzdHVyYmVkID0gdHJ1ZTtcbiAgICBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICB9XG4gICAgaWYgKHN0cmVhbS5fc3RhdGUgPT09ICdlcnJvcmVkJykge1xuICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChzdHJlYW0uX3N0b3JlZEVycm9yKTtcbiAgICB9XG4gICAgUmVhZGFibGVTdHJlYW1DbG9zZShzdHJlYW0pO1xuICAgIGNvbnN0IHJlYWRlciA9IHN0cmVhbS5fcmVhZGVyO1xuICAgIGlmIChyZWFkZXIgIT09IHVuZGVmaW5lZCAmJiBJc1JlYWRhYmxlU3RyZWFtQllPQlJlYWRlcihyZWFkZXIpKSB7XG4gICAgICAgIHJlYWRlci5fcmVhZEludG9SZXF1ZXN0cy5mb3JFYWNoKHJlYWRJbnRvUmVxdWVzdCA9PiB7XG4gICAgICAgICAgICByZWFkSW50b1JlcXVlc3QuX2Nsb3NlU3RlcHModW5kZWZpbmVkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRlci5fcmVhZEludG9SZXF1ZXN0cyA9IG5ldyBTaW1wbGVRdWV1ZSgpO1xuICAgIH1cbiAgICBjb25zdCBzb3VyY2VDYW5jZWxQcm9taXNlID0gc3RyZWFtLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXJbQ2FuY2VsU3RlcHNdKHJlYXNvbik7XG4gICAgcmV0dXJuIHRyYW5zZm9ybVByb21pc2VXaXRoKHNvdXJjZUNhbmNlbFByb21pc2UsIG5vb3ApO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1DbG9zZShzdHJlYW0pIHtcbiAgICBzdHJlYW0uX3N0YXRlID0gJ2Nsb3NlZCc7XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLl9yZWFkZXI7XG4gICAgaWYgKHJlYWRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZXNvbHZlKHJlYWRlcik7XG4gICAgaWYgKElzUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyKHJlYWRlcikpIHtcbiAgICAgICAgcmVhZGVyLl9yZWFkUmVxdWVzdHMuZm9yRWFjaChyZWFkUmVxdWVzdCA9PiB7XG4gICAgICAgICAgICByZWFkUmVxdWVzdC5fY2xvc2VTdGVwcygpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVhZGVyLl9yZWFkUmVxdWVzdHMgPSBuZXcgU2ltcGxlUXVldWUoKTtcbiAgICB9XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUVycm9yKHN0cmVhbSwgZSkge1xuICAgIHN0cmVhbS5fc3RhdGUgPSAnZXJyb3JlZCc7XG4gICAgc3RyZWFtLl9zdG9yZWRFcnJvciA9IGU7XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLl9yZWFkZXI7XG4gICAgaWYgKHJlYWRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZWplY3QocmVhZGVyLCBlKTtcbiAgICBpZiAoSXNSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIocmVhZGVyKSkge1xuICAgICAgICByZWFkZXIuX3JlYWRSZXF1ZXN0cy5mb3JFYWNoKHJlYWRSZXF1ZXN0ID0+IHtcbiAgICAgICAgICAgIHJlYWRSZXF1ZXN0Ll9lcnJvclN0ZXBzKGUpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVhZGVyLl9yZWFkUmVxdWVzdHMgPSBuZXcgU2ltcGxlUXVldWUoKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJlYWRlci5fcmVhZEludG9SZXF1ZXN0cy5mb3JFYWNoKHJlYWRJbnRvUmVxdWVzdCA9PiB7XG4gICAgICAgICAgICByZWFkSW50b1JlcXVlc3QuX2Vycm9yU3RlcHMoZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZWFkZXIuX3JlYWRJbnRvUmVxdWVzdHMgPSBuZXcgU2ltcGxlUXVldWUoKTtcbiAgICB9XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgUmVhZGFibGVTdHJlYW0uXG5mdW5jdGlvbiBzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDEobmFtZSkge1xuICAgIHJldHVybiBuZXcgVHlwZUVycm9yKGBSZWFkYWJsZVN0cmVhbS5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgUmVhZGFibGVTdHJlYW1gKTtcbn1cblxuZnVuY3Rpb24gY29udmVydFF1ZXVpbmdTdHJhdGVneUluaXQoaW5pdCwgY29udGV4dCkge1xuICAgIGFzc2VydERpY3Rpb25hcnkoaW5pdCwgY29udGV4dCk7XG4gICAgY29uc3QgaGlnaFdhdGVyTWFyayA9IGluaXQgPT09IG51bGwgfHwgaW5pdCA9PT0gdm9pZCAwID8gdm9pZCAwIDogaW5pdC5oaWdoV2F0ZXJNYXJrO1xuICAgIGFzc2VydFJlcXVpcmVkRmllbGQoaGlnaFdhdGVyTWFyaywgJ2hpZ2hXYXRlck1hcmsnLCAnUXVldWluZ1N0cmF0ZWd5SW5pdCcpO1xuICAgIHJldHVybiB7XG4gICAgICAgIGhpZ2hXYXRlck1hcms6IGNvbnZlcnRVbnJlc3RyaWN0ZWREb3VibGUoaGlnaFdhdGVyTWFyaylcbiAgICB9O1xufVxuXG4vLyBUaGUgc2l6ZSBmdW5jdGlvbiBtdXN0IG5vdCBoYXZlIGEgcHJvdG90eXBlIHByb3BlcnR5IG5vciBiZSBhIGNvbnN0cnVjdG9yXG5jb25zdCBieXRlTGVuZ3RoU2l6ZUZ1bmN0aW9uID0gKGNodW5rKSA9PiB7XG4gICAgcmV0dXJuIGNodW5rLmJ5dGVMZW5ndGg7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGJ5dGVMZW5ndGhTaXplRnVuY3Rpb24sICduYW1lJywge1xuICAgIHZhbHVlOiAnc2l6ZScsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlXG59KTtcbi8qKlxuICogQSBxdWV1aW5nIHN0cmF0ZWd5IHRoYXQgY291bnRzIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gZWFjaCBjaHVuay5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIEJ5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3kge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgYXNzZXJ0UmVxdWlyZWRBcmd1bWVudChvcHRpb25zLCAxLCAnQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneScpO1xuICAgICAgICBvcHRpb25zID0gY29udmVydFF1ZXVpbmdTdHJhdGVneUluaXQob3B0aW9ucywgJ0ZpcnN0IHBhcmFtZXRlcicpO1xuICAgICAgICB0aGlzLl9ieXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5SGlnaFdhdGVyTWFyayA9IG9wdGlvbnMuaGlnaFdhdGVyTWFyaztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgaGlnaCB3YXRlciBtYXJrIHByb3ZpZGVkIHRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICAgKi9cbiAgICBnZXQgaGlnaFdhdGVyTWFyaygpIHtcbiAgICAgICAgaWYgKCFJc0J5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3kodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGJ5dGVMZW5ndGhCcmFuZENoZWNrRXhjZXB0aW9uKCdoaWdoV2F0ZXJNYXJrJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2J5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3lIaWdoV2F0ZXJNYXJrO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNZWFzdXJlcyB0aGUgc2l6ZSBvZiBgY2h1bmtgIGJ5IHJldHVybmluZyB0aGUgdmFsdWUgb2YgaXRzIGBieXRlTGVuZ3RoYCBwcm9wZXJ0eS5cbiAgICAgKi9cbiAgICBnZXQgc2l6ZSgpIHtcbiAgICAgICAgaWYgKCFJc0J5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3kodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGJ5dGVMZW5ndGhCcmFuZENoZWNrRXhjZXB0aW9uKCdzaXplJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJ5dGVMZW5ndGhTaXplRnVuY3Rpb247XG4gICAgfVxufVxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneS5wcm90b3R5cGUsIHtcbiAgICBoaWdoV2F0ZXJNYXJrOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBzaXplOiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCeXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5LnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcsIHtcbiAgICAgICAgdmFsdWU6ICdCeXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5JyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneS5cbmZ1bmN0aW9uIGJ5dGVMZW5ndGhCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneS5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneWApO1xufVxuZnVuY3Rpb24gSXNCeXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5KHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfYnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneUhpZ2hXYXRlck1hcmsnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneTtcbn1cblxuLy8gVGhlIHNpemUgZnVuY3Rpb24gbXVzdCBub3QgaGF2ZSBhIHByb3RvdHlwZSBwcm9wZXJ0eSBub3IgYmUgYSBjb25zdHJ1Y3RvclxuY29uc3QgY291bnRTaXplRnVuY3Rpb24gPSAoKSA9PiB7XG4gICAgcmV0dXJuIDE7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvdW50U2l6ZUZ1bmN0aW9uLCAnbmFtZScsIHtcbiAgICB2YWx1ZTogJ3NpemUnLFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxufSk7XG4vKipcbiAqIEEgcXVldWluZyBzdHJhdGVneSB0aGF0IGNvdW50cyB0aGUgbnVtYmVyIG9mIGNodW5rcy5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIENvdW50UXVldWluZ1N0cmF0ZWd5IHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIGFzc2VydFJlcXVpcmVkQXJndW1lbnQob3B0aW9ucywgMSwgJ0NvdW50UXVldWluZ1N0cmF0ZWd5Jyk7XG4gICAgICAgIG9wdGlvbnMgPSBjb252ZXJ0UXVldWluZ1N0cmF0ZWd5SW5pdChvcHRpb25zLCAnRmlyc3QgcGFyYW1ldGVyJyk7XG4gICAgICAgIHRoaXMuX2NvdW50UXVldWluZ1N0cmF0ZWd5SGlnaFdhdGVyTWFyayA9IG9wdGlvbnMuaGlnaFdhdGVyTWFyaztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgaGlnaCB3YXRlciBtYXJrIHByb3ZpZGVkIHRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICAgKi9cbiAgICBnZXQgaGlnaFdhdGVyTWFyaygpIHtcbiAgICAgICAgaWYgKCFJc0NvdW50UXVldWluZ1N0cmF0ZWd5KHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBjb3VudEJyYW5kQ2hlY2tFeGNlcHRpb24oJ2hpZ2hXYXRlck1hcmsnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fY291bnRRdWV1aW5nU3RyYXRlZ3lIaWdoV2F0ZXJNYXJrO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNZWFzdXJlcyB0aGUgc2l6ZSBvZiBgY2h1bmtgIGJ5IGFsd2F5cyByZXR1cm5pbmcgMS5cbiAgICAgKiBUaGlzIGVuc3VyZXMgdGhhdCB0aGUgdG90YWwgcXVldWUgc2l6ZSBpcyBhIGNvdW50IG9mIHRoZSBudW1iZXIgb2YgY2h1bmtzIGluIHRoZSBxdWV1ZS5cbiAgICAgKi9cbiAgICBnZXQgc2l6ZSgpIHtcbiAgICAgICAgaWYgKCFJc0NvdW50UXVldWluZ1N0cmF0ZWd5KHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBjb3VudEJyYW5kQ2hlY2tFeGNlcHRpb24oJ3NpemUnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY291bnRTaXplRnVuY3Rpb247XG4gICAgfVxufVxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoQ291bnRRdWV1aW5nU3RyYXRlZ3kucHJvdG90eXBlLCB7XG4gICAgaGlnaFdhdGVyTWFyazogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgc2l6ZTogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQ291bnRRdWV1aW5nU3RyYXRlZ3kucHJvdG90eXBlLCBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZywge1xuICAgICAgICB2YWx1ZTogJ0NvdW50UXVldWluZ1N0cmF0ZWd5JyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgQ291bnRRdWV1aW5nU3RyYXRlZ3kuXG5mdW5jdGlvbiBjb3VudEJyYW5kQ2hlY2tFeGNlcHRpb24obmFtZSkge1xuICAgIHJldHVybiBuZXcgVHlwZUVycm9yKGBDb3VudFF1ZXVpbmdTdHJhdGVneS5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgQ291bnRRdWV1aW5nU3RyYXRlZ3lgKTtcbn1cbmZ1bmN0aW9uIElzQ291bnRRdWV1aW5nU3RyYXRlZ3koeCkge1xuICAgIGlmICghdHlwZUlzT2JqZWN0KHgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoeCwgJ19jb3VudFF1ZXVpbmdTdHJhdGVneUhpZ2hXYXRlck1hcmsnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgQ291bnRRdWV1aW5nU3RyYXRlZ3k7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRUcmFuc2Zvcm1lcihvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydERpY3Rpb25hcnkob3JpZ2luYWwsIGNvbnRleHQpO1xuICAgIGNvbnN0IGZsdXNoID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLmZsdXNoO1xuICAgIGNvbnN0IHJlYWRhYmxlVHlwZSA9IG9yaWdpbmFsID09PSBudWxsIHx8IG9yaWdpbmFsID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcmlnaW5hbC5yZWFkYWJsZVR5cGU7XG4gICAgY29uc3Qgc3RhcnQgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwuc3RhcnQ7XG4gICAgY29uc3QgdHJhbnNmb3JtID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLnRyYW5zZm9ybTtcbiAgICBjb25zdCB3cml0YWJsZVR5cGUgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwud3JpdGFibGVUeXBlO1xuICAgIHJldHVybiB7XG4gICAgICAgIGZsdXNoOiBmbHVzaCA9PT0gdW5kZWZpbmVkID9cbiAgICAgICAgICAgIHVuZGVmaW5lZCA6XG4gICAgICAgICAgICBjb252ZXJ0VHJhbnNmb3JtZXJGbHVzaENhbGxiYWNrKGZsdXNoLCBvcmlnaW5hbCwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnZmx1c2gnIHRoYXRgKSxcbiAgICAgICAgcmVhZGFibGVUeXBlLFxuICAgICAgICBzdGFydDogc3RhcnQgPT09IHVuZGVmaW5lZCA/XG4gICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgY29udmVydFRyYW5zZm9ybWVyU3RhcnRDYWxsYmFjayhzdGFydCwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3N0YXJ0JyB0aGF0YCksXG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNmb3JtID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgIGNvbnZlcnRUcmFuc2Zvcm1lclRyYW5zZm9ybUNhbGxiYWNrKHRyYW5zZm9ybSwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3RyYW5zZm9ybScgdGhhdGApLFxuICAgICAgICB3cml0YWJsZVR5cGVcbiAgICB9O1xufVxuZnVuY3Rpb24gY29udmVydFRyYW5zZm9ybWVyRmx1c2hDYWxsYmFjayhmbiwgb3JpZ2luYWwsIGNvbnRleHQpIHtcbiAgICBhc3NlcnRGdW5jdGlvbihmbiwgY29udGV4dCk7XG4gICAgcmV0dXJuIChjb250cm9sbGVyKSA9PiBwcm9taXNlQ2FsbChmbiwgb3JpZ2luYWwsIFtjb250cm9sbGVyXSk7XG59XG5mdW5jdGlvbiBjb252ZXJ0VHJhbnNmb3JtZXJTdGFydENhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKGNvbnRyb2xsZXIpID0+IHJlZmxlY3RDYWxsKGZuLCBvcmlnaW5hbCwgW2NvbnRyb2xsZXJdKTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRUcmFuc2Zvcm1lclRyYW5zZm9ybUNhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKGNodW5rLCBjb250cm9sbGVyKSA9PiBwcm9taXNlQ2FsbChmbiwgb3JpZ2luYWwsIFtjaHVuaywgY29udHJvbGxlcl0pO1xufVxuXG4vLyBDbGFzcyBUcmFuc2Zvcm1TdHJlYW1cbi8qKlxuICogQSB0cmFuc2Zvcm0gc3RyZWFtIGNvbnNpc3RzIG9mIGEgcGFpciBvZiBzdHJlYW1zOiBhIHtAbGluayBXcml0YWJsZVN0cmVhbSB8IHdyaXRhYmxlIHN0cmVhbX0sXG4gKiBrbm93biBhcyBpdHMgd3JpdGFibGUgc2lkZSwgYW5kIGEge0BsaW5rIFJlYWRhYmxlU3RyZWFtIHwgcmVhZGFibGUgc3RyZWFtfSwga25vd24gYXMgaXRzIHJlYWRhYmxlIHNpZGUuXG4gKiBJbiBhIG1hbm5lciBzcGVjaWZpYyB0byB0aGUgdHJhbnNmb3JtIHN0cmVhbSBpbiBxdWVzdGlvbiwgd3JpdGVzIHRvIHRoZSB3cml0YWJsZSBzaWRlIHJlc3VsdCBpbiBuZXcgZGF0YSBiZWluZ1xuICogbWFkZSBhdmFpbGFibGUgZm9yIHJlYWRpbmcgZnJvbSB0aGUgcmVhZGFibGUgc2lkZS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIFRyYW5zZm9ybVN0cmVhbSB7XG4gICAgY29uc3RydWN0b3IocmF3VHJhbnNmb3JtZXIgPSB7fSwgcmF3V3JpdGFibGVTdHJhdGVneSA9IHt9LCByYXdSZWFkYWJsZVN0cmF0ZWd5ID0ge30pIHtcbiAgICAgICAgaWYgKHJhd1RyYW5zZm9ybWVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJhd1RyYW5zZm9ybWVyID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB3cml0YWJsZVN0cmF0ZWd5ID0gY29udmVydFF1ZXVpbmdTdHJhdGVneShyYXdXcml0YWJsZVN0cmF0ZWd5LCAnU2Vjb25kIHBhcmFtZXRlcicpO1xuICAgICAgICBjb25zdCByZWFkYWJsZVN0cmF0ZWd5ID0gY29udmVydFF1ZXVpbmdTdHJhdGVneShyYXdSZWFkYWJsZVN0cmF0ZWd5LCAnVGhpcmQgcGFyYW1ldGVyJyk7XG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gY29udmVydFRyYW5zZm9ybWVyKHJhd1RyYW5zZm9ybWVyLCAnRmlyc3QgcGFyYW1ldGVyJyk7XG4gICAgICAgIGlmICh0cmFuc2Zvcm1lci5yZWFkYWJsZVR5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgcmVhZGFibGVUeXBlIHNwZWNpZmllZCcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0cmFuc2Zvcm1lci53cml0YWJsZVR5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgd3JpdGFibGVUeXBlIHNwZWNpZmllZCcpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlYWRhYmxlSGlnaFdhdGVyTWFyayA9IEV4dHJhY3RIaWdoV2F0ZXJNYXJrKHJlYWRhYmxlU3RyYXRlZ3ksIDApO1xuICAgICAgICBjb25zdCByZWFkYWJsZVNpemVBbGdvcml0aG0gPSBFeHRyYWN0U2l6ZUFsZ29yaXRobShyZWFkYWJsZVN0cmF0ZWd5KTtcbiAgICAgICAgY29uc3Qgd3JpdGFibGVIaWdoV2F0ZXJNYXJrID0gRXh0cmFjdEhpZ2hXYXRlck1hcmsod3JpdGFibGVTdHJhdGVneSwgMSk7XG4gICAgICAgIGNvbnN0IHdyaXRhYmxlU2l6ZUFsZ29yaXRobSA9IEV4dHJhY3RTaXplQWxnb3JpdGhtKHdyaXRhYmxlU3RyYXRlZ3kpO1xuICAgICAgICBsZXQgc3RhcnRQcm9taXNlX3Jlc29sdmU7XG4gICAgICAgIGNvbnN0IHN0YXJ0UHJvbWlzZSA9IG5ld1Byb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgICBzdGFydFByb21pc2VfcmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICAgIH0pO1xuICAgICAgICBJbml0aWFsaXplVHJhbnNmb3JtU3RyZWFtKHRoaXMsIHN0YXJ0UHJvbWlzZSwgd3JpdGFibGVIaWdoV2F0ZXJNYXJrLCB3cml0YWJsZVNpemVBbGdvcml0aG0sIHJlYWRhYmxlSGlnaFdhdGVyTWFyaywgcmVhZGFibGVTaXplQWxnb3JpdGhtKTtcbiAgICAgICAgU2V0VXBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckZyb21UcmFuc2Zvcm1lcih0aGlzLCB0cmFuc2Zvcm1lcik7XG4gICAgICAgIGlmICh0cmFuc2Zvcm1lci5zdGFydCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBzdGFydFByb21pc2VfcmVzb2x2ZSh0cmFuc2Zvcm1lci5zdGFydCh0aGlzLl90cmFuc2Zvcm1TdHJlYW1Db250cm9sbGVyKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzdGFydFByb21pc2VfcmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSByZWFkYWJsZSBzaWRlIG9mIHRoZSB0cmFuc2Zvcm0gc3RyZWFtLlxuICAgICAqL1xuICAgIGdldCByZWFkYWJsZSgpIHtcbiAgICAgICAgaWYgKCFJc1RyYW5zZm9ybVN0cmVhbSh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbigncmVhZGFibGUnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcmVhZGFibGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB3cml0YWJsZSBzaWRlIG9mIHRoZSB0cmFuc2Zvcm0gc3RyZWFtLlxuICAgICAqL1xuICAgIGdldCB3cml0YWJsZSgpIHtcbiAgICAgICAgaWYgKCFJc1RyYW5zZm9ybVN0cmVhbSh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbignd3JpdGFibGUnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fd3JpdGFibGU7XG4gICAgfVxufVxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoVHJhbnNmb3JtU3RyZWFtLnByb3RvdHlwZSwge1xuICAgIHJlYWRhYmxlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICB3cml0YWJsZTogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVHJhbnNmb3JtU3RyZWFtLnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcsIHtcbiAgICAgICAgdmFsdWU6ICdUcmFuc2Zvcm1TdHJlYW0nLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIEluaXRpYWxpemVUcmFuc2Zvcm1TdHJlYW0oc3RyZWFtLCBzdGFydFByb21pc2UsIHdyaXRhYmxlSGlnaFdhdGVyTWFyaywgd3JpdGFibGVTaXplQWxnb3JpdGhtLCByZWFkYWJsZUhpZ2hXYXRlck1hcmssIHJlYWRhYmxlU2l6ZUFsZ29yaXRobSkge1xuICAgIGZ1bmN0aW9uIHN0YXJ0QWxnb3JpdGhtKCkge1xuICAgICAgICByZXR1cm4gc3RhcnRQcm9taXNlO1xuICAgIH1cbiAgICBmdW5jdGlvbiB3cml0ZUFsZ29yaXRobShjaHVuaykge1xuICAgICAgICByZXR1cm4gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtXcml0ZUFsZ29yaXRobShzdHJlYW0sIGNodW5rKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gYWJvcnRBbGdvcml0aG0ocmVhc29uKSB7XG4gICAgICAgIHJldHVybiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0U2lua0Fib3J0QWxnb3JpdGhtKHN0cmVhbSwgcmVhc29uKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gY2xvc2VBbGdvcml0aG0oKSB7XG4gICAgICAgIHJldHVybiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0U2lua0Nsb3NlQWxnb3JpdGhtKHN0cmVhbSk7XG4gICAgfVxuICAgIHN0cmVhbS5fd3JpdGFibGUgPSBDcmVhdGVXcml0YWJsZVN0cmVhbShzdGFydEFsZ29yaXRobSwgd3JpdGVBbGdvcml0aG0sIGNsb3NlQWxnb3JpdGhtLCBhYm9ydEFsZ29yaXRobSwgd3JpdGFibGVIaWdoV2F0ZXJNYXJrLCB3cml0YWJsZVNpemVBbGdvcml0aG0pO1xuICAgIGZ1bmN0aW9uIHB1bGxBbGdvcml0aG0oKSB7XG4gICAgICAgIHJldHVybiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0U291cmNlUHVsbEFsZ29yaXRobShzdHJlYW0pO1xuICAgIH1cbiAgICBmdW5jdGlvbiBjYW5jZWxBbGdvcml0aG0ocmVhc29uKSB7XG4gICAgICAgIFRyYW5zZm9ybVN0cmVhbUVycm9yV3JpdGFibGVBbmRVbmJsb2NrV3JpdGUoc3RyZWFtLCByZWFzb24pO1xuICAgICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgIH1cbiAgICBzdHJlYW0uX3JlYWRhYmxlID0gQ3JlYXRlUmVhZGFibGVTdHJlYW0oc3RhcnRBbGdvcml0aG0sIHB1bGxBbGdvcml0aG0sIGNhbmNlbEFsZ29yaXRobSwgcmVhZGFibGVIaWdoV2F0ZXJNYXJrLCByZWFkYWJsZVNpemVBbGdvcml0aG0pO1xuICAgIC8vIFRoZSBbW2JhY2twcmVzc3VyZV1dIHNsb3QgaXMgc2V0IHRvIHVuZGVmaW5lZCBzbyB0aGF0IGl0IGNhbiBiZSBpbml0aWFsaXNlZCBieSBUcmFuc2Zvcm1TdHJlYW1TZXRCYWNrcHJlc3N1cmUuXG4gICAgc3RyZWFtLl9iYWNrcHJlc3N1cmUgPSB1bmRlZmluZWQ7XG4gICAgc3RyZWFtLl9iYWNrcHJlc3N1cmVDaGFuZ2VQcm9taXNlID0gdW5kZWZpbmVkO1xuICAgIHN0cmVhbS5fYmFja3ByZXNzdXJlQ2hhbmdlUHJvbWlzZV9yZXNvbHZlID0gdW5kZWZpbmVkO1xuICAgIFRyYW5zZm9ybVN0cmVhbVNldEJhY2twcmVzc3VyZShzdHJlYW0sIHRydWUpO1xuICAgIHN0cmVhbS5fdHJhbnNmb3JtU3RyZWFtQ29udHJvbGxlciA9IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIElzVHJhbnNmb3JtU3RyZWFtKHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfdHJhbnNmb3JtU3RyZWFtQ29udHJvbGxlcicpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHggaW5zdGFuY2VvZiBUcmFuc2Zvcm1TdHJlYW07XG59XG4vLyBUaGlzIGlzIGEgbm8tb3AgaWYgYm90aCBzaWRlcyBhcmUgYWxyZWFkeSBlcnJvcmVkLlxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRXJyb3Ioc3RyZWFtLCBlKSB7XG4gICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKHN0cmVhbS5fcmVhZGFibGUuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgZSk7XG4gICAgVHJhbnNmb3JtU3RyZWFtRXJyb3JXcml0YWJsZUFuZFVuYmxvY2tXcml0ZShzdHJlYW0sIGUpO1xufVxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRXJyb3JXcml0YWJsZUFuZFVuYmxvY2tXcml0ZShzdHJlYW0sIGUpIHtcbiAgICBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyhzdHJlYW0uX3RyYW5zZm9ybVN0cmVhbUNvbnRyb2xsZXIpO1xuICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcklmTmVlZGVkKHN0cmVhbS5fd3JpdGFibGUuX3dyaXRhYmxlU3RyZWFtQ29udHJvbGxlciwgZSk7XG4gICAgaWYgKHN0cmVhbS5fYmFja3ByZXNzdXJlKSB7XG4gICAgICAgIC8vIFByZXRlbmQgdGhhdCBwdWxsKCkgd2FzIGNhbGxlZCB0byBwZXJtaXQgYW55IHBlbmRpbmcgd3JpdGUoKSBjYWxscyB0byBjb21wbGV0ZS4gVHJhbnNmb3JtU3RyZWFtU2V0QmFja3ByZXNzdXJlKClcbiAgICAgICAgLy8gY2Fubm90IGJlIGNhbGxlZCBmcm9tIGVucXVldWUoKSBvciBwdWxsKCkgb25jZSB0aGUgUmVhZGFibGVTdHJlYW0gaXMgZXJyb3JlZCwgc28gdGhpcyB3aWxsIHdpbGwgYmUgdGhlIGZpbmFsIHRpbWVcbiAgICAgICAgLy8gX2JhY2twcmVzc3VyZSBpcyBzZXQuXG4gICAgICAgIFRyYW5zZm9ybVN0cmVhbVNldEJhY2twcmVzc3VyZShzdHJlYW0sIGZhbHNlKTtcbiAgICB9XG59XG5mdW5jdGlvbiBUcmFuc2Zvcm1TdHJlYW1TZXRCYWNrcHJlc3N1cmUoc3RyZWFtLCBiYWNrcHJlc3N1cmUpIHtcbiAgICAvLyBQYXNzZXMgYWxzbyB3aGVuIGNhbGxlZCBkdXJpbmcgY29uc3RydWN0aW9uLlxuICAgIGlmIChzdHJlYW0uX2JhY2twcmVzc3VyZUNoYW5nZVByb21pc2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzdHJlYW0uX2JhY2twcmVzc3VyZUNoYW5nZVByb21pc2VfcmVzb2x2ZSgpO1xuICAgIH1cbiAgICBzdHJlYW0uX2JhY2twcmVzc3VyZUNoYW5nZVByb21pc2UgPSBuZXdQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICBzdHJlYW0uX2JhY2twcmVzc3VyZUNoYW5nZVByb21pc2VfcmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgfSk7XG4gICAgc3RyZWFtLl9iYWNrcHJlc3N1cmUgPSBiYWNrcHJlc3N1cmU7XG59XG4vLyBDbGFzcyBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlclxuLyoqXG4gKiBBbGxvd3MgY29udHJvbCBvZiB0aGUge0BsaW5rIFJlYWRhYmxlU3RyZWFtfSBhbmQge0BsaW5rIFdyaXRhYmxlU3RyZWFtfSBvZiB0aGUgYXNzb2NpYXRlZCB7QGxpbmsgVHJhbnNmb3JtU3RyZWFtfS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSWxsZWdhbCBjb25zdHJ1Y3RvcicpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBkZXNpcmVkIHNpemUgdG8gZmlsbCB0aGUgcmVhZGFibGUgc2lkZeKAmXMgaW50ZXJuYWwgcXVldWUuIEl0IGNhbiBiZSBuZWdhdGl2ZSwgaWYgdGhlIHF1ZXVlIGlzIG92ZXItZnVsbC5cbiAgICAgKi9cbiAgICBnZXQgZGVzaXJlZFNpemUoKSB7XG4gICAgICAgIGlmICghSXNUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdkZXNpcmVkU2l6ZScpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlYWRhYmxlQ29udHJvbGxlciA9IHRoaXMuX2NvbnRyb2xsZWRUcmFuc2Zvcm1TdHJlYW0uX3JlYWRhYmxlLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXI7XG4gICAgICAgIHJldHVybiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0RGVzaXJlZFNpemUocmVhZGFibGVDb250cm9sbGVyKTtcbiAgICB9XG4gICAgZW5xdWV1ZShjaHVuayA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbignZW5xdWV1ZScpO1xuICAgICAgICB9XG4gICAgICAgIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZSh0aGlzLCBjaHVuayk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEVycm9ycyBib3RoIHRoZSByZWFkYWJsZSBzaWRlIGFuZCB0aGUgd3JpdGFibGUgc2lkZSBvZiB0aGUgY29udHJvbGxlZCB0cmFuc2Zvcm0gc3RyZWFtLCBtYWtpbmcgYWxsIGZ1dHVyZVxuICAgICAqIGludGVyYWN0aW9ucyB3aXRoIGl0IGZhaWwgd2l0aCB0aGUgZ2l2ZW4gZXJyb3IgYGVgLiBBbnkgY2h1bmtzIHF1ZXVlZCBmb3IgdHJhbnNmb3JtYXRpb24gd2lsbCBiZSBkaXNjYXJkZWQuXG4gICAgICovXG4gICAgZXJyb3IocmVhc29uID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdlcnJvcicpO1xuICAgICAgICB9XG4gICAgICAgIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3IodGhpcywgcmVhc29uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xvc2VzIHRoZSByZWFkYWJsZSBzaWRlIGFuZCBlcnJvcnMgdGhlIHdyaXRhYmxlIHNpZGUgb2YgdGhlIGNvbnRyb2xsZWQgdHJhbnNmb3JtIHN0cmVhbS4gVGhpcyBpcyB1c2VmdWwgd2hlbiB0aGVcbiAgICAgKiB0cmFuc2Zvcm1lciBvbmx5IG5lZWRzIHRvIGNvbnN1bWUgYSBwb3J0aW9uIG9mIHRoZSBjaHVua3Mgd3JpdHRlbiB0byB0aGUgd3JpdGFibGUgc2lkZS5cbiAgICAgKi9cbiAgICB0ZXJtaW5hdGUoKSB7XG4gICAgICAgIGlmICghSXNUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKCd0ZXJtaW5hdGUnKTtcbiAgICAgICAgfVxuICAgICAgICBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlclRlcm1pbmF0ZSh0aGlzKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUsIHtcbiAgICBlbnF1ZXVlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBlcnJvcjogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgdGVybWluYXRlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBkZXNpcmVkU2l6ZTogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlLCBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZywge1xuICAgICAgICB2YWx1ZTogJ1RyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBUcmFuc2Zvcm0gU3RyZWFtIERlZmF1bHQgQ29udHJvbGxlciBBYnN0cmFjdCBPcGVyYXRpb25zXG5mdW5jdGlvbiBJc1RyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyKHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfY29udHJvbGxlZFRyYW5zZm9ybVN0cmVhbScpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHggaW5zdGFuY2VvZiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcjtcbn1cbmZ1bmN0aW9uIFNldFVwVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCB0cmFuc2Zvcm1BbGdvcml0aG0sIGZsdXNoQWxnb3JpdGhtKSB7XG4gICAgY29udHJvbGxlci5fY29udHJvbGxlZFRyYW5zZm9ybVN0cmVhbSA9IHN0cmVhbTtcbiAgICBzdHJlYW0uX3RyYW5zZm9ybVN0cmVhbUNvbnRyb2xsZXIgPSBjb250cm9sbGVyO1xuICAgIGNvbnRyb2xsZXIuX3RyYW5zZm9ybUFsZ29yaXRobSA9IHRyYW5zZm9ybUFsZ29yaXRobTtcbiAgICBjb250cm9sbGVyLl9mbHVzaEFsZ29yaXRobSA9IGZsdXNoQWxnb3JpdGhtO1xufVxuZnVuY3Rpb24gU2V0VXBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckZyb21UcmFuc2Zvcm1lcihzdHJlYW0sIHRyYW5zZm9ybWVyKSB7XG4gICAgY29uc3QgY29udHJvbGxlciA9IE9iamVjdC5jcmVhdGUoVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlKTtcbiAgICBsZXQgdHJhbnNmb3JtQWxnb3JpdGhtID0gKGNodW5rKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckVucXVldWUoY29udHJvbGxlciwgY2h1bmspO1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAodHJhbnNmb3JtUmVzdWx0RSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgodHJhbnNmb3JtUmVzdWx0RSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGxldCBmbHVzaEFsZ29yaXRobSA9ICgpID0+IHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICBpZiAodHJhbnNmb3JtZXIudHJhbnNmb3JtICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdHJhbnNmb3JtQWxnb3JpdGhtID0gY2h1bmsgPT4gdHJhbnNmb3JtZXIudHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKTtcbiAgICB9XG4gICAgaWYgKHRyYW5zZm9ybWVyLmZsdXNoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZmx1c2hBbGdvcml0aG0gPSAoKSA9PiB0cmFuc2Zvcm1lci5mbHVzaChjb250cm9sbGVyKTtcbiAgICB9XG4gICAgU2V0VXBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcihzdHJlYW0sIGNvbnRyb2xsZXIsIHRyYW5zZm9ybUFsZ29yaXRobSwgZmx1c2hBbGdvcml0aG0pO1xufVxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcikge1xuICAgIGNvbnRyb2xsZXIuX3RyYW5zZm9ybUFsZ29yaXRobSA9IHVuZGVmaW5lZDtcbiAgICBjb250cm9sbGVyLl9mbHVzaEFsZ29yaXRobSA9IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZShjb250cm9sbGVyLCBjaHVuaykge1xuICAgIGNvbnN0IHN0cmVhbSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRUcmFuc2Zvcm1TdHJlYW07XG4gICAgY29uc3QgcmVhZGFibGVDb250cm9sbGVyID0gc3RyZWFtLl9yZWFkYWJsZS5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyO1xuICAgIGlmICghUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlKHJlYWRhYmxlQ29udHJvbGxlcikpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignUmVhZGFibGUgc2lkZSBpcyBub3QgaW4gYSBzdGF0ZSB0aGF0IHBlcm1pdHMgZW5xdWV1ZScpO1xuICAgIH1cbiAgICAvLyBXZSB0aHJvdHRsZSB0cmFuc2Zvcm0gaW52b2NhdGlvbnMgYmFzZWQgb24gdGhlIGJhY2twcmVzc3VyZSBvZiB0aGUgUmVhZGFibGVTdHJlYW0sIGJ1dCB3ZSBzdGlsbFxuICAgIC8vIGFjY2VwdCBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckVucXVldWUoKSBjYWxscy5cbiAgICB0cnkge1xuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZShyZWFkYWJsZUNvbnRyb2xsZXIsIGNodW5rKTtcbiAgICB9XG4gICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gVGhpcyBoYXBwZW5zIHdoZW4gcmVhZGFibGVTdHJhdGVneS5zaXplKCkgdGhyb3dzLlxuICAgICAgICBUcmFuc2Zvcm1TdHJlYW1FcnJvcldyaXRhYmxlQW5kVW5ibG9ja1dyaXRlKHN0cmVhbSwgZSk7XG4gICAgICAgIHRocm93IHN0cmVhbS5fcmVhZGFibGUuX3N0b3JlZEVycm9yO1xuICAgIH1cbiAgICBjb25zdCBiYWNrcHJlc3N1cmUgPSBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVySGFzQmFja3ByZXNzdXJlKHJlYWRhYmxlQ29udHJvbGxlcik7XG4gICAgaWYgKGJhY2twcmVzc3VyZSAhPT0gc3RyZWFtLl9iYWNrcHJlc3N1cmUpIHtcbiAgICAgICAgVHJhbnNmb3JtU3RyZWFtU2V0QmFja3ByZXNzdXJlKHN0cmVhbSwgdHJ1ZSk7XG4gICAgfVxufVxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBlKSB7XG4gICAgVHJhbnNmb3JtU3RyZWFtRXJyb3IoY29udHJvbGxlci5fY29udHJvbGxlZFRyYW5zZm9ybVN0cmVhbSwgZSk7XG59XG5mdW5jdGlvbiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlclBlcmZvcm1UcmFuc2Zvcm0oY29udHJvbGxlciwgY2h1bmspIHtcbiAgICBjb25zdCB0cmFuc2Zvcm1Qcm9taXNlID0gY29udHJvbGxlci5fdHJhbnNmb3JtQWxnb3JpdGhtKGNodW5rKTtcbiAgICByZXR1cm4gdHJhbnNmb3JtUHJvbWlzZVdpdGgodHJhbnNmb3JtUHJvbWlzZSwgdW5kZWZpbmVkLCByID0+IHtcbiAgICAgICAgVHJhbnNmb3JtU3RyZWFtRXJyb3IoY29udHJvbGxlci5fY29udHJvbGxlZFRyYW5zZm9ybVN0cmVhbSwgcik7XG4gICAgICAgIHRocm93IHI7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlclRlcm1pbmF0ZShjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFRyYW5zZm9ybVN0cmVhbTtcbiAgICBjb25zdCByZWFkYWJsZUNvbnRyb2xsZXIgPSBzdHJlYW0uX3JlYWRhYmxlLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXI7XG4gICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsb3NlKHJlYWRhYmxlQ29udHJvbGxlcik7XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgVHlwZUVycm9yKCdUcmFuc2Zvcm1TdHJlYW0gdGVybWluYXRlZCcpO1xuICAgIFRyYW5zZm9ybVN0cmVhbUVycm9yV3JpdGFibGVBbmRVbmJsb2NrV3JpdGUoc3RyZWFtLCBlcnJvcik7XG59XG4vLyBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0U2luayBBbGdvcml0aG1zXG5mdW5jdGlvbiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0U2lua1dyaXRlQWxnb3JpdGhtKHN0cmVhbSwgY2h1bmspIHtcbiAgICBjb25zdCBjb250cm9sbGVyID0gc3RyZWFtLl90cmFuc2Zvcm1TdHJlYW1Db250cm9sbGVyO1xuICAgIGlmIChzdHJlYW0uX2JhY2twcmVzc3VyZSkge1xuICAgICAgICBjb25zdCBiYWNrcHJlc3N1cmVDaGFuZ2VQcm9taXNlID0gc3RyZWFtLl9iYWNrcHJlc3N1cmVDaGFuZ2VQcm9taXNlO1xuICAgICAgICByZXR1cm4gdHJhbnNmb3JtUHJvbWlzZVdpdGgoYmFja3ByZXNzdXJlQ2hhbmdlUHJvbWlzZSwgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgd3JpdGFibGUgPSBzdHJlYW0uX3dyaXRhYmxlO1xuICAgICAgICAgICAgY29uc3Qgc3RhdGUgPSB3cml0YWJsZS5fc3RhdGU7XG4gICAgICAgICAgICBpZiAoc3RhdGUgPT09ICdlcnJvcmluZycpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyB3cml0YWJsZS5fc3RvcmVkRXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJQZXJmb3JtVHJhbnNmb3JtKGNvbnRyb2xsZXIsIGNodW5rKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlclBlcmZvcm1UcmFuc2Zvcm0oY29udHJvbGxlciwgY2h1bmspO1xufVxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtBYm9ydEFsZ29yaXRobShzdHJlYW0sIHJlYXNvbikge1xuICAgIC8vIGFib3J0KCkgaXMgbm90IGNhbGxlZCBzeW5jaHJvbm91c2x5LCBzbyBpdCBpcyBwb3NzaWJsZSBmb3IgYWJvcnQoKSB0byBiZSBjYWxsZWQgd2hlbiB0aGUgc3RyZWFtIGlzIGFscmVhZHlcbiAgICAvLyBlcnJvcmVkLlxuICAgIFRyYW5zZm9ybVN0cmVhbUVycm9yKHN0cmVhbSwgcmVhc29uKTtcbiAgICByZXR1cm4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xufVxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtDbG9zZUFsZ29yaXRobShzdHJlYW0pIHtcbiAgICAvLyBzdHJlYW0uX3JlYWRhYmxlIGNhbm5vdCBjaGFuZ2UgYWZ0ZXIgY29uc3RydWN0aW9uLCBzbyBjYWNoaW5nIGl0IGFjcm9zcyBhIGNhbGwgdG8gdXNlciBjb2RlIGlzIHNhZmUuXG4gICAgY29uc3QgcmVhZGFibGUgPSBzdHJlYW0uX3JlYWRhYmxlO1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBzdHJlYW0uX3RyYW5zZm9ybVN0cmVhbUNvbnRyb2xsZXI7XG4gICAgY29uc3QgZmx1c2hQcm9taXNlID0gY29udHJvbGxlci5fZmx1c2hBbGdvcml0aG0oKTtcbiAgICBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyhjb250cm9sbGVyKTtcbiAgICAvLyBSZXR1cm4gYSBwcm9taXNlIHRoYXQgaXMgZnVsZmlsbGVkIHdpdGggdW5kZWZpbmVkIG9uIHN1Y2Nlc3MuXG4gICAgcmV0dXJuIHRyYW5zZm9ybVByb21pc2VXaXRoKGZsdXNoUHJvbWlzZSwgKCkgPT4ge1xuICAgICAgICBpZiAocmVhZGFibGUuX3N0YXRlID09PSAnZXJyb3JlZCcpIHtcbiAgICAgICAgICAgIHRocm93IHJlYWRhYmxlLl9zdG9yZWRFcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xvc2UocmVhZGFibGUuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlcik7XG4gICAgfSwgciA9PiB7XG4gICAgICAgIFRyYW5zZm9ybVN0cmVhbUVycm9yKHN0cmVhbSwgcik7XG4gICAgICAgIHRocm93IHJlYWRhYmxlLl9zdG9yZWRFcnJvcjtcbiAgICB9KTtcbn1cbi8vIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRTb3VyY2UgQWxnb3JpdGhtc1xuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNvdXJjZVB1bGxBbGdvcml0aG0oc3RyZWFtKSB7XG4gICAgLy8gSW52YXJpYW50LiBFbmZvcmNlZCBieSB0aGUgcHJvbWlzZXMgcmV0dXJuZWQgYnkgc3RhcnQoKSBhbmQgcHVsbCgpLlxuICAgIFRyYW5zZm9ybVN0cmVhbVNldEJhY2twcmVzc3VyZShzdHJlYW0sIGZhbHNlKTtcbiAgICAvLyBQcmV2ZW50IHRoZSBuZXh0IHB1bGwoKSBjYWxsIHVudGlsIHRoZXJlIGlzIGJhY2twcmVzc3VyZS5cbiAgICByZXR1cm4gc3RyZWFtLl9iYWNrcHJlc3N1cmVDaGFuZ2VQcm9taXNlO1xufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyLlxuZnVuY3Rpb24gZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyYCk7XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgVHJhbnNmb3JtU3RyZWFtLlxuZnVuY3Rpb24gc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoYFRyYW5zZm9ybVN0cmVhbS5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgVHJhbnNmb3JtU3RyZWFtYCk7XG59XG5cbmV4cG9ydCB7IEJ5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3ksIENvdW50UXVldWluZ1N0cmF0ZWd5LCBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLCBSZWFkYWJsZVN0cmVhbSwgUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyLCBSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0LCBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyLCBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIsIFRyYW5zZm9ybVN0cmVhbSwgVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIsIFdyaXRhYmxlU3RyZWFtLCBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyLCBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIgfTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBvbnlmaWxsLmVzMjAxOC5tanMubWFwXG4iLCIvLyBUaGUgbW9kdWxlIGNhY2hlXG52YXIgX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fID0ge307XG5cbi8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG5mdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuXHR2YXIgY2FjaGVkTW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXTtcblx0aWYgKGNhY2hlZE1vZHVsZSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuIGNhY2hlZE1vZHVsZS5leHBvcnRzO1xuXHR9XG5cdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG5cdHZhciBtb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdID0ge1xuXHRcdGlkOiBtb2R1bGVJZCxcblx0XHRsb2FkZWQ6IGZhbHNlLFxuXHRcdGV4cG9ydHM6IHt9XG5cdH07XG5cblx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG5cdF9fd2VicGFja19tb2R1bGVzX19bbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG5cdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcblx0bW9kdWxlLmxvYWRlZCA9IHRydWU7XG5cblx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcblx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xufVxuXG4iLCIvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9ucyBmb3IgaGFybW9ueSBleHBvcnRzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSAoZXhwb3J0cywgZGVmaW5pdGlvbikgPT4ge1xuXHRmb3IodmFyIGtleSBpbiBkZWZpbml0aW9uKSB7XG5cdFx0aWYoX193ZWJwYWNrX3JlcXVpcmVfXy5vKGRlZmluaXRpb24sIGtleSkgJiYgIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBrZXkpKSB7XG5cdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywga2V5LCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZGVmaW5pdGlvbltrZXldIH0pO1xuXHRcdH1cblx0fVxufTsiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSAob2JqLCBwcm9wKSA9PiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCkpIiwiLy8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5yID0gKGV4cG9ydHMpID0+IHtcblx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG5cdH1cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5ubWQgPSAobW9kdWxlKSA9PiB7XG5cdG1vZHVsZS5wYXRocyA9IFtdO1xuXHRpZiAoIW1vZHVsZS5jaGlsZHJlbikgbW9kdWxlLmNoaWxkcmVuID0gW107XG5cdHJldHVybiBtb2R1bGU7XG59OyIsIi8vIHN0YXJ0dXBcbi8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuLy8gVGhpcyBlbnRyeSBtb2R1bGUgaXMgcmVmZXJlbmNlZCBieSBvdGhlciBtb2R1bGVzIHNvIGl0IGNhbid0IGJlIGlubGluZWRcbnZhciBfX3dlYnBhY2tfZXhwb3J0c19fID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0OCk7XG4iXSwibmFtZXMiOlsicm9vdCIsImZhY3RvcnkiLCJleHBvcnRzIiwibW9kdWxlIiwiZGVmaW5lIiwiYW1kIiwidGhpcyIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwidmFsdWUiLCJldmVudFRhcmdldFNoaW0iLCJBYm9ydFNpZ25hbCIsIkV2ZW50VGFyZ2V0IiwiY29uc3RydWN0b3IiLCJzdXBlciIsIlR5cGVFcnJvciIsImFib3J0ZWQiLCJhYm9ydGVkRmxhZ3MiLCJnZXQiLCJkZWZpbmVFdmVudEF0dHJpYnV0ZSIsInByb3RvdHlwZSIsIldlYWtNYXAiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiZW51bWVyYWJsZSIsIlN5bWJvbCIsInRvU3RyaW5nVGFnIiwiY29uZmlndXJhYmxlIiwiQWJvcnRDb250cm9sbGVyIiwic2lnbmFscyIsInNldCIsInNpZ25hbCIsImNyZWF0ZSIsImNhbGwiLCJjcmVhdGVBYm9ydFNpZ25hbCIsImdldFNpZ25hbCIsImFib3J0IiwiZGlzcGF0Y2hFdmVudCIsInR5cGUiLCJjb250cm9sbGVyIiwiRm9ybURhdGEiLCJmb3JtRGF0YSIsImNsaWVudCIsIm9wdGlvbnMiLCJNYWlsZ3VuIiwiY29uZmlnIiwidXJsIiwidXNlcm5hbWUiLCJFcnJvciIsImtleSIsInJlcXVlc3QiLCJtYWlsTGlzdHNNZW1iZXJzIiwiZG9tYWlucyIsIndlYmhvb2tzIiwiZXZlbnRzIiwic3RhdHMiLCJzdXBwcmVzc2lvbnMiLCJtZXNzYWdlcyIsInJvdXRlcyIsImlwcyIsImlwX3Bvb2xzIiwibGlzdHMiLCJwdWJsaWNfa2V5IiwicHVibGljX3JlcXVlc3QiLCJ2YWxpZGF0ZSIsInBhcnNlIiwiZGF0YSIsInJlY2VpdmluZyIsInNlbmRpbmciLCJuYW1lIiwicmVxdWlyZV90bHMiLCJza2lwX3ZlcmlmaWNhdGlvbiIsInN0YXRlIiwid2lsZGNhcmQiLCJzcGFtX2FjdGlvbiIsImNyZWF0ZWRfYXQiLCJzbXRwX3Bhc3N3b3JkIiwic210cF9sb2dpbiIsInJlY2VpdmluZ19kbnNfcmVjb3JkcyIsInNlbmRpbmdfZG5zX3JlY29yZHMiLCJfcGFyc2VNZXNzYWdlIiwicmVzcG9uc2UiLCJib2R5IiwiX3BhcnNlRG9tYWluTGlzdCIsIml0ZW1zIiwibWFwIiwiaXRlbSIsIkRvbWFpbiIsIl9wYXJzZURvbWFpbiIsImRvbWFpbiIsIl9wYXJzZVRyYWNraW5nU2V0dGluZ3MiLCJ0cmFja2luZyIsIl9wYXJzZVRyYWNraW5nVXBkYXRlIiwibGlzdCIsInF1ZXJ5IiwidGhlbiIsInJlcyIsInBvc3RXaXRoRkQiLCJkZXN0cm95IiwiZGVsZXRlIiwiZ2V0VHJhY2tpbmciLCJ1cGRhdGVUcmFja2luZyIsImFjdGl2ZSIsInN0YXR1cyIsInN0YXR1c1RleHQiLCJtZXNzYWdlIiwicHV0V2l0aEZEIiwiZ2V0SXBzIiwiYXNzaWduSXAiLCJpcCIsImRlbGV0ZUlwIiwibGlua0lwUG9vbCIsInBvb2xfaWQiLCJ1bmxpbmtJcFBvbGwiLCJib2R5TWVzc2FnZSIsImVycm9yIiwic3RhY2siLCJkZXRhaWxzIiwiX3BhcnNlUGFnZU51bWJlciIsInNwbGl0IiwicG9wIiwiX3BhcnNlUGFnZSIsImlkIiwibnVtYmVyIiwiX3BhcnNlUGFnZUxpbmtzIiwiZW50cmllcyIsInBhZ2luZyIsInJlZHVjZSIsImFjYyIsImVudHJpZSIsIl9wYXJzZUV2ZW50TGlzdCIsInBhZ2VzIiwicXVlcnlDb3B5IiwicGFnZSIsInBhcnNlSXBQb29sc1Jlc3BvbnNlIiwicG9zdCIsInVwZGF0ZSIsInBvb2xJZCIsInBhdGNoIiwicGFyc2VJcHNSZXNwb25zZSIsIm1lbWJlcnMiLCJiYXNlUm91dGUiLCJtYWlsTGlzdEFkZHJlc3MiLCJjaGVja0FuZFVwZGF0ZURhdGEiLCJuZXdEYXRhIiwidmFycyIsIkpTT04iLCJzdHJpbmdpZnkiLCJzdWJzY3JpYmVkIiwibGlzdE1lbWJlcnMiLCJnZXRNZW1iZXIiLCJtYWlsTGlzdE1lbWJlckFkZHJlc3MiLCJjcmVhdGVNZW1iZXIiLCJyZXFEYXRhIiwiY3JlYXRlTWVtYmVycyIsIkFycmF5IiwiaXNBcnJheSIsInVwc2VydCIsInVwZGF0ZU1lbWJlciIsImRlc3Ryb3lNZW1iZXIiLCJfcGFyc2VSZXNwb25zZSIsImFkZHJlc3NlcyIsImVuYWJsZURuc0VzcENoZWNrcyIsImpvaW4iLCJzeW50YXhfb25seSIsImlzU3RyZWFtIiwiYXR0YWNobWVudCIsInBpcGUiLCJ0aW1lb3V0IiwiaGVhZGVycyIsIm1ldGhvZCIsImlucHV0T3B0aW9ucyIsImJhc2ljIiwiZW5jb2RlIiwiQXV0aG9yaXphdGlvbiIsInBhcmFtcyIsImdldE93blByb3BlcnR5TmFtZXMiLCJsZW5ndGgiLCJzZWFyY2hQYXJhbXMiLCJ0b0xvY2FsZVVwcGVyQ2FzZSIsInRocm93SHR0cEVycm9ycyIsIm9rIiwic3RyZWFtIiwiY2h1bmtzIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJvbiIsImNodW5rIiwicHVzaCIsIkJ1ZmZlciIsImNvbmNhdCIsInRvU3RyaW5nIiwianNvbiIsImNvbW1hbmQiLCJoZWFkIiwiY3JlYXRlRm9ybURhdGEiLCJhcHBlbmRGaWxlVG9GRCIsIm9iaiIsImZvcm1EYXRhSW5zdGFuY2UiLCJvYmpEYXRhIiwiZmlsZW5hbWUiLCJjb250ZW50VHlwZSIsImtub3duTGVuZ3RoIiwiZ2V0QXR0YWNobWVudE9wdGlvbnMiLCJ1bmRlZmluZWQiLCJnZXRIZWFkZXJzIiwiaXNOb2RlRm9ybURhdGEiLCJhcHBlbmQiLCJrZXlzIiwiZmlsdGVyIiwiZm9ybURhdGFBY2MiLCJmb3JFYWNoIiwicHV0IiwiUmVxdWVzdCIsInN0YXJ0IiwiRGF0ZSIsImVuZCIsInJlc29sdXRpb24iLCJzdGF0IiwidGltZSIsIl9wYXJzZVN0YXRzIiwiU3RhdHMiLCJnZXREb21haW4iLCJnZXRBY2NvdW50IiwiY3JlYXRlT3B0aW9ucyIsImFkZHJlc3MiLCJjb2RlIiwidGFncyIsIm1vZGVscyIsImJvdW5jZXMiLCJCb3VuY2UiLCJjb21wbGFpbnRzIiwiQ29tcGxhaW50IiwidW5zdWJzY3JpYmVzIiwiVW5zdWJzY3JpYmUiLCJwYWdlVXJsIiwiX3BhcnNlTGlzdCIsIk1vZGVsIiwiZCIsIl9wYXJzZUl0ZW0iLCJtb2RlbCIsImVuY29kZVVSSUNvbXBvbmVudCIsInBvc3REYXRhIiwiU3VwcHJlc3Npb25DbGllbnQiLCJfcGFyc2VXZWJob29rTGlzdCIsIl9wYXJzZVdlYmhvb2tXaXRoSUQiLCJ3ZWJob29rUmVzcG9uc2UiLCJ3ZWJob29rIiwidXJscyIsIldlYmhvb2siLCJfcGFyc2VXZWJob29rVGVzdCIsInRlc3QiLCJmcmVlRXhwb3J0cyIsImZyZWVHbG9iYWwiLCJnbG9iYWwiLCJ3aW5kb3ciLCJJbnZhbGlkQ2hhcmFjdGVyRXJyb3IiLCJUQUJMRSIsIlJFR0VYX1NQQUNFX0NIQVJBQ1RFUlMiLCJiYXNlNjQiLCJpbnB1dCIsIlN0cmluZyIsImEiLCJiIiwiYyIsImJ1ZmZlciIsInBhZGRpbmciLCJvdXRwdXQiLCJwb3NpdGlvbiIsImNoYXJDb2RlQXQiLCJjaGFyQXQiLCJyZXBsYWNlIiwiYml0U3RvcmFnZSIsImJpdENvdW50ZXIiLCJpbmRleE9mIiwiZnJvbUNoYXJDb2RlIiwidXJpIiwiZmlyc3RDb21tYSIsIm1ldGEiLCJzdWJzdHJpbmciLCJjaGFyc2V0IiwidHlwZUZ1bGwiLCJpIiwiZW5jb2RpbmciLCJ1bmVzY2FwZSIsImZyb20iLCJwcml2YXRlRGF0YSIsIndyYXBwZXJzIiwicGQiLCJldmVudCIsInJldHYiLCJjb25zb2xlIiwiYXNzZXJ0Iiwic2V0Q2FuY2VsRmxhZyIsInBhc3NpdmVMaXN0ZW5lciIsImNhbmNlbGFibGUiLCJjYW5jZWxlZCIsInByZXZlbnREZWZhdWx0IiwiRXZlbnQiLCJldmVudFRhcmdldCIsImV2ZW50UGhhc2UiLCJjdXJyZW50VGFyZ2V0Iiwic3RvcHBlZCIsImltbWVkaWF0ZVN0b3BwZWQiLCJ0aW1lU3RhbXAiLCJub3ciLCJkZWZpbmVSZWRpcmVjdERlc2NyaXB0b3IiLCJkZWZpbmVDYWxsRGVzY3JpcHRvciIsImFwcGx5IiwiYXJndW1lbnRzIiwiZ2V0V3JhcHBlciIsInByb3RvIiwid3JhcHBlciIsIkJhc2VFdmVudCIsIkN1c3RvbUV2ZW50Iiwid3JpdGFibGUiLCJpc0Z1bmMiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJkZWZpbmVXcmFwcGVyIiwiZ2V0UHJvdG90eXBlT2YiLCJpc1N0b3BwZWQiLCJzZXRQYXNzaXZlTGlzdGVuZXIiLCJ0YXJnZXQiLCJjb21wb3NlZFBhdGgiLCJOT05FIiwiQ0FQVFVSSU5HX1BIQVNFIiwiQVRfVEFSR0VUIiwiQlVCQkxJTkdfUEhBU0UiLCJzdG9wUHJvcGFnYXRpb24iLCJzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24iLCJidWJibGVzIiwiQm9vbGVhbiIsImRlZmF1bHRQcmV2ZW50ZWQiLCJjb21wb3NlZCIsInNyY0VsZW1lbnQiLCJjYW5jZWxCdWJibGUiLCJyZXR1cm5WYWx1ZSIsImluaXRFdmVudCIsInNldFByb3RvdHlwZU9mIiwibGlzdGVuZXJzTWFwIiwiaXNPYmplY3QiLCJ4IiwiZ2V0TGlzdGVuZXJzIiwibGlzdGVuZXJzIiwiZXZlbnRUYXJnZXRQcm90b3R5cGUiLCJldmVudE5hbWUiLCJub2RlIiwibGlzdGVuZXJUeXBlIiwibGlzdGVuZXIiLCJuZXh0IiwicHJldiIsIm5ld05vZGUiLCJwYXNzaXZlIiwib25jZSIsImRlZmluZUV2ZW50QXR0cmlidXRlRGVzY3JpcHRvciIsImRlZmluZUN1c3RvbUV2ZW50VGFyZ2V0IiwiZXZlbnROYW1lcyIsIkN1c3RvbUV2ZW50VGFyZ2V0IiwidHlwZXMiLCJNYXAiLCJhZGRFdmVudExpc3RlbmVyIiwib3B0aW9uc0lzT2JqIiwiY2FwdHVyZSIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJ3cmFwcGVkRXZlbnQiLCJ3cmFwRXZlbnQiLCJlcnIiLCJoYW5kbGVFdmVudCIsInNldEV2ZW50UGhhc2UiLCJzZXRDdXJyZW50VGFyZ2V0IiwiUmVhZGFibGUiLCJ3bSIsIkJsb2IiLCJibG9iUGFydHMiLCJzaXplIiwicGFydHMiLCJlbGVtZW50IiwiQXJyYXlCdWZmZXIiLCJpc1ZpZXciLCJieXRlT2Zmc2V0IiwiYnl0ZUxlbmd0aCIsInRvTG93ZXJDYXNlIiwiYXN5bmMiLCJhcnJheUJ1ZmZlciIsIlVpbnQ4QXJyYXkiLCJvZmZzZXQiLCJwYXJ0IiwicmVhZCIsInNsaWNlIiwicmVsYXRpdmVTdGFydCIsIk1hdGgiLCJtYXgiLCJtaW4iLCJyZWxhdGl2ZUVuZCIsInNwYW4iLCJ2YWx1ZXMiLCJhZGRlZCIsImJsb2IiLCJhc3NpZ24iLCJzdGF0aWMiLCJoYXNJbnN0YW5jZSIsIm9iamVjdCIsImZldGNoIiwiaGlnaFdhdGVyTWFyayIsIkhlYWRlcnMiLCJSZXNwb25zZSIsIlJlYWRhYmxlU3RyZWFtIiwiXyIsImdsb2JhbHMiLCJnZXRHbG9iYWwiLCJwcm9wZXJ0eSIsInNlbGYiLCJnbG9iYWxUaGlzIiwiZ2xvYmFsUHJvcGVydGllcyIsImdsb2JhbE9iamVjdCIsImJpbmQiLCJzdXBwb3J0c0Fib3J0Q29udHJvbGxlciIsInN1cHBvcnRzU3RyZWFtcyIsInN1cHBvcnRzRm9ybURhdGEiLCJtZXJnZUhlYWRlcnMiLCJzb3VyY2UxIiwic291cmNlMiIsInJlc3VsdCIsImlzSGVhZGVyc0luc3RhbmNlIiwic291cmNlIiwiZGVlcE1lcmdlIiwic291cmNlcyIsInJlcXVlc3RNZXRob2RzIiwicmVzcG9uc2VUeXBlcyIsInRleHQiLCJyZXRyeUFmdGVyU3RhdHVzQ29kZXMiLCJzdG9wIiwiSFRUUEVycm9yIiwiVGltZW91dEVycm9yIiwiZGVsYXkiLCJtcyIsInNldFRpbWVvdXQiLCJub3JtYWxpemVSZXF1ZXN0TWV0aG9kIiwiaW5jbHVkZXMiLCJ0b1VwcGVyQ2FzZSIsImRlZmF1bHRSZXRyeU9wdGlvbnMiLCJsaW1pdCIsIm1ldGhvZHMiLCJzdGF0dXNDb2RlcyIsImFmdGVyU3RhdHVzQ29kZXMiLCJub3JtYWxpemVSZXRyeU9wdGlvbnMiLCJyZXRyeSIsIm1heFNhZmVUaW1lb3V0IiwiS3kiLCJfcmV0cnlDb3VudCIsIl9pbnB1dCIsIl9vcHRpb25zIiwiY3JlZGVudGlhbHMiLCJob29rcyIsImJlZm9yZVJlcXVlc3QiLCJiZWZvcmVSZXRyeSIsImFmdGVyUmVzcG9uc2UiLCJwcmVmaXhVcmwiLCJVUkwiLCJzdGFydHNXaXRoIiwiZW5kc1dpdGgiLCJhYm9ydENvbnRyb2xsZXIiLCJVUkxTZWFyY2hQYXJhbXMiLCJmbiIsIlJhbmdlRXJyb3IiLCJfZmV0Y2giLCJob29rIiwibW9kaWZpZWRSZXNwb25zZSIsIl9kZWNvcmF0ZVJlc3BvbnNlIiwiY2xvbmUiLCJvbkRvd25sb2FkUHJvZ3Jlc3MiLCJfc3RyZWFtIiwiX3JldHJ5IiwibWltZVR5cGUiLCJwYXJzZUpzb24iLCJfY2FsY3VsYXRlUmV0cnlEZWxheSIsInJldHJ5QWZ0ZXIiLCJhZnRlciIsIk51bWJlciIsImlzTmFOIiwibWF4UmV0cnlBZnRlciIsInJldHJ5Q291bnQiLCJ0aW1lb3V0SUQiLCJjYXRjaCIsImNsZWFyVGltZW91dCIsInRvdGFsQnl0ZXMiLCJ0cmFuc2ZlcnJlZEJ5dGVzIiwicmVhZGVyIiwiZ2V0UmVhZGVyIiwicGVyY2VudCIsImRvbmUiLCJjbG9zZSIsImVucXVldWUiLCJ2YWxpZGF0ZUFuZE1lcmdlIiwiY3JlYXRlSW5zdGFuY2UiLCJkZWZhdWx0cyIsImt5IiwibmV3RGVmYXVsdHMiLCJleHRlbmQiLCJub3JtYWxpemUiLCJzdHIiLCJqb2luZWQiLCJyZXF1aXJlIiwiaHR0cCIsImh0dHBzIiwiemxpYiIsIlN0cmVhbSIsImRhdGFVcmlUb0J1ZmZlciIsInV0aWwiLCJjcnlwdG8iLCJGZXRjaEJhc2VFcnJvciIsImNhcHR1cmVTdGFja1RyYWNlIiwiRmV0Y2hFcnJvciIsInN5c3RlbUVycm9yIiwiZXJybm8iLCJlcnJvcmVkU3lzQ2FsbCIsInN5c2NhbGwiLCJOQU1FIiwiaXNVUkxTZWFyY2hQYXJhbWV0ZXJzIiwiZ2V0QWxsIiwiaGFzIiwic29ydCIsImlzQmxvYiIsImlzRm9ybURhdGEiLCJjYXJyaWFnZSIsImRhc2hlcyIsInJlcGVhdCIsImNhcnJpYWdlTGVuZ3RoIiwiZ2V0Rm9vdGVyIiwiYm91bmRhcnkiLCJnZXRIZWFkZXIiLCJmaWVsZCIsImhlYWRlciIsIklOVEVSTkFMUyIsIkJvZHkiLCJpc0J1ZmZlciIsImlzQW55QXJyYXlCdWZmZXIiLCJyYW5kb21CeXRlcyIsImZvcm0iLCJmb3JtRGF0YUl0ZXJhdG9yIiwiZGlzdHVyYmVkIiwiYm9keVVzZWQiLCJjb25zdW1lQm9keSIsImN0IiwiYnVmIiwiYWxsb2MiLCJhY2N1bSIsImFjY3VtQnl0ZXMiLCJyZWFkYWJsZUVuZGVkIiwiX3JlYWRhYmxlU3RhdGUiLCJlbmRlZCIsImV2ZXJ5IiwiaW5zdGFuY2UiLCJwMSIsInAyIiwiZ2V0Qm91bmRhcnkiLCJQYXNzVGhyb3VnaCIsImV4dHJhY3RDb250ZW50VHlwZSIsImdldFRvdGFsQnl0ZXMiLCJnZXRMZW5ndGhTeW5jIiwiaGFzS25vd25MZW5ndGgiLCJnZXRGb3JtRGF0YUxlbmd0aCIsInZhbGlkYXRlSGVhZGVyTmFtZSIsInZhbGlkYXRlSGVhZGVyVmFsdWUiLCJpbml0IiwicmF3IiwiaXNCb3hlZFByaW1pdGl2ZSIsIml0ZXJhdG9yIiwicGFpciIsIlByb3h5IiwicCIsInJlY2VpdmVyIiwiU2V0IiwiUmVmbGVjdCIsImNhbGxiYWNrIiwiZm9yIiwicmVkaXJlY3RTdGF0dXMiLCJpc1JlZGlyZWN0IiwiSU5URVJOQUxTJDEiLCJjb3VudGVyIiwicmVkaXJlY3RlZCIsImxvY2F0aW9uIiwiSU5URVJOQUxTJDIiLCJpc1JlcXVlc3QiLCJwYXJzZWRVUkwiLCJpbnB1dEJvZHkiLCJyZWRpcmVjdCIsImZvbGxvdyIsImNvbXByZXNzIiwiYWdlbnQiLCJpbnNlY3VyZUhUVFBQYXJzZXIiLCJmb3JtYXQiLCJBYm9ydEVycm9yIiwic3VwcG9ydGVkU2NoZW1hcyIsIm9wdGlvbnNfIiwiY29udGVudExlbmd0aFZhbHVlIiwic2VhcmNoIiwibGFzdE9mZnNldCIsImhyZWYiLCJoYXNoIiwiZ2V0U2VhcmNoIiwicGF0aCIsInBhdGhuYW1lIiwiaG9zdG5hbWUiLCJwcm90b2NvbCIsInBvcnQiLCJnZXROb2RlUmVxdWVzdE9wdGlvbnMiLCJzZW5kIiwiZW1pdCIsImFib3J0QW5kRmluYWxpemUiLCJmaW5hbGl6ZSIsInJlcXVlc3RfIiwicmVzcG9uc2VfIiwiaW5kZXgiLCJhcnJheSIsImZyb21SYXdIZWFkZXJzIiwicmF3SGVhZGVycyIsInN0YXR1c0NvZGUiLCJsb2NhdGlvblVSTCIsInJlcXVlc3RPcHRpb25zIiwicGlwZWxpbmUiLCJwcm9jZXNzIiwidmVyc2lvbiIsInJlc3BvbnNlT3B0aW9ucyIsInN0YXR1c01lc3NhZ2UiLCJjb2RpbmdzIiwiemxpYk9wdGlvbnMiLCJmbHVzaCIsIlpfU1lOQ19GTFVTSCIsImZpbmlzaEZsdXNoIiwiY3JlYXRlR3VuemlwIiwiY3JlYXRlQnJvdGxpRGVjb21wcmVzcyIsImNyZWF0ZUluZmxhdGUiLCJjcmVhdGVJbmZsYXRlUmF3IiwiZGVzdCIsIndyaXRlIiwid3JpdGVUb1N0cmVhbSIsIlN5bWJvbFBvbHlmaWxsIiwiZGVzY3JpcHRpb24iLCJub29wIiwidHlwZUlzT2JqZWN0IiwicmV0aHJvd0Fzc2VydGlvbkVycm9yUmVqZWN0aW9uIiwib3JpZ2luYWxQcm9taXNlIiwib3JpZ2luYWxQcm9taXNlVGhlbiIsIm9yaWdpbmFsUHJvbWlzZVJlc29sdmUiLCJvcmlnaW5hbFByb21pc2VSZWplY3QiLCJuZXdQcm9taXNlIiwiZXhlY3V0b3IiLCJwcm9taXNlUmVzb2x2ZWRXaXRoIiwicHJvbWlzZVJlamVjdGVkV2l0aCIsInJlYXNvbiIsIlBlcmZvcm1Qcm9taXNlVGhlbiIsInByb21pc2UiLCJvbkZ1bGZpbGxlZCIsIm9uUmVqZWN0ZWQiLCJ1cG9uUHJvbWlzZSIsInVwb25GdWxmaWxsbWVudCIsInVwb25SZWplY3Rpb24iLCJ0cmFuc2Zvcm1Qcm9taXNlV2l0aCIsImZ1bGZpbGxtZW50SGFuZGxlciIsInJlamVjdGlvbkhhbmRsZXIiLCJzZXRQcm9taXNlSXNIYW5kbGVkVG9UcnVlIiwicXVldWVNaWNyb3Rhc2siLCJnbG9iYWxRdWV1ZU1pY3JvdGFzayIsInJlc29sdmVkUHJvbWlzZSIsInJlZmxlY3RDYWxsIiwiRiIsIlYiLCJhcmdzIiwiRnVuY3Rpb24iLCJwcm9taXNlQ2FsbCIsIlNpbXBsZVF1ZXVlIiwiX2N1cnNvciIsIl9zaXplIiwiX2Zyb250IiwiX2VsZW1lbnRzIiwiX25leHQiLCJfYmFjayIsIm9sZEJhY2siLCJuZXdCYWNrIiwiUVVFVUVfTUFYX0FSUkFZX1NJWkUiLCJzaGlmdCIsIm9sZEZyb250IiwibmV3RnJvbnQiLCJvbGRDdXJzb3IiLCJuZXdDdXJzb3IiLCJlbGVtZW50cyIsInBlZWsiLCJmcm9udCIsImN1cnNvciIsIlJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY0luaXRpYWxpemUiLCJfb3duZXJSZWFkYWJsZVN0cmVhbSIsIl9yZWFkZXIiLCJfc3RhdGUiLCJkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemUiLCJkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZVJlc29sdmUiLCJkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemVBc1Jlc29sdmVkIiwiZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCIsIl9zdG9yZWRFcnJvciIsIlJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY0NhbmNlbCIsIlJlYWRhYmxlU3RyZWFtQ2FuY2VsIiwiUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljUmVsZWFzZSIsImRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlUmVqZWN0IiwiZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZXNldFRvUmVqZWN0ZWQiLCJyZWFkZXJMb2NrRXhjZXB0aW9uIiwiX2Nsb3NlZFByb21pc2UiLCJfY2xvc2VkUHJvbWlzZV9yZXNvbHZlIiwiX2Nsb3NlZFByb21pc2VfcmVqZWN0IiwiQWJvcnRTdGVwcyIsIkVycm9yU3RlcHMiLCJDYW5jZWxTdGVwcyIsIlB1bGxTdGVwcyIsIk51bWJlcklzRmluaXRlIiwiaXNGaW5pdGUiLCJNYXRoVHJ1bmMiLCJ0cnVuYyIsInYiLCJjZWlsIiwiZmxvb3IiLCJhc3NlcnREaWN0aW9uYXJ5IiwiY29udGV4dCIsImFzc2VydEZ1bmN0aW9uIiwiYXNzZXJ0T2JqZWN0IiwiYXNzZXJ0UmVxdWlyZWRBcmd1bWVudCIsImFzc2VydFJlcXVpcmVkRmllbGQiLCJjb252ZXJ0VW5yZXN0cmljdGVkRG91YmxlIiwiY2Vuc29yTmVnYXRpdmVaZXJvIiwiY29udmVydFVuc2lnbmVkTG9uZ0xvbmdXaXRoRW5mb3JjZVJhbmdlIiwidXBwZXJCb3VuZCIsIk1BWF9TQUZFX0lOVEVHRVIiLCJpbnRlZ2VyUGFydCIsImFzc2VydFJlYWRhYmxlU3RyZWFtIiwiSXNSZWFkYWJsZVN0cmVhbSIsIkFjcXVpcmVSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIiLCJSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIiLCJSZWFkYWJsZVN0cmVhbUFkZFJlYWRSZXF1ZXN0IiwicmVhZFJlcXVlc3QiLCJfcmVhZFJlcXVlc3RzIiwiUmVhZGFibGVTdHJlYW1GdWxmaWxsUmVhZFJlcXVlc3QiLCJfY2xvc2VTdGVwcyIsIl9jaHVua1N0ZXBzIiwiUmVhZGFibGVTdHJlYW1HZXROdW1SZWFkUmVxdWVzdHMiLCJSZWFkYWJsZVN0cmVhbUhhc0RlZmF1bHRSZWFkZXIiLCJJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlciIsIklzUmVhZGFibGVTdHJlYW1Mb2NrZWQiLCJjbG9zZWQiLCJkZWZhdWx0UmVhZGVyQnJhbmRDaGVja0V4Y2VwdGlvbiIsImNhbmNlbCIsInJlc29sdmVQcm9taXNlIiwicmVqZWN0UHJvbWlzZSIsIlJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlclJlYWQiLCJfZXJyb3JTdGVwcyIsImUiLCJyZWxlYXNlTG9jayIsImhhc093blByb3BlcnR5IiwiX2Rpc3R1cmJlZCIsIl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIiLCJBc3luY0l0ZXJhdG9yUHJvdG90eXBlIiwiUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9ySW1wbCIsInByZXZlbnRDYW5jZWwiLCJfb25nb2luZ1Byb21pc2UiLCJfaXNGaW5pc2hlZCIsIl9wcmV2ZW50Q2FuY2VsIiwibmV4dFN0ZXBzIiwiX25leHRTdGVwcyIsInJldHVybiIsInJldHVyblN0ZXBzIiwiX3JldHVyblN0ZXBzIiwiUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yUHJvdG90eXBlIiwiSXNSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3IiLCJfYXN5bmNJdGVyYXRvckltcGwiLCJzdHJlYW1Bc3luY0l0ZXJhdG9yQnJhbmRDaGVja0V4Y2VwdGlvbiIsIl9hIiwiTnVtYmVySXNOYU4iLCJDcmVhdGVBcnJheUZyb21MaXN0IiwiQ29weURhdGFCbG9ja0J5dGVzIiwiZGVzdE9mZnNldCIsInNyYyIsInNyY09mZnNldCIsIm4iLCJBcnJheUJ1ZmZlclNsaWNlIiwiYmVnaW4iLCJDbG9uZUFzVWludDhBcnJheSIsIk8iLCJEZXF1ZXVlVmFsdWUiLCJjb250YWluZXIiLCJfcXVldWUiLCJfcXVldWVUb3RhbFNpemUiLCJFbnF1ZXVlVmFsdWVXaXRoU2l6ZSIsIkluZmluaXR5IiwiUmVzZXRRdWV1ZSIsIlJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3QiLCJ2aWV3IiwiSXNSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0IiwiYnlvYlJlcXVlc3RCcmFuZENoZWNrRXhjZXB0aW9uIiwiX3ZpZXciLCJyZXNwb25kIiwiYnl0ZXNXcml0dGVuIiwiX2Fzc29jaWF0ZWRSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclJlc3BvbmQiLCJyZXNwb25kV2l0aE5ld1ZpZXciLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZFdpdGhOZXdWaWV3IiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlciIsImJ5b2JSZXF1ZXN0IiwiSXNSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyIiwiYnl0ZVN0cmVhbUNvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckdldEJZT0JSZXF1ZXN0IiwiZGVzaXJlZFNpemUiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyR2V0RGVzaXJlZFNpemUiLCJfY2xvc2VSZXF1ZXN0ZWQiLCJfY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbSIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbG9zZSIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFbnF1ZXVlIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVycm9yIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNsZWFyUGVuZGluZ1B1bGxJbnRvcyIsIl9jYW5jZWxBbGdvcml0aG0iLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xlYXJBbGdvcml0aG1zIiwiZW50cnkiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVySGFuZGxlUXVldWVEcmFpbiIsImF1dG9BbGxvY2F0ZUNodW5rU2l6ZSIsIl9hdXRvQWxsb2NhdGVDaHVua1NpemUiLCJidWZmZXJFIiwicHVsbEludG9EZXNjcmlwdG9yIiwiYnVmZmVyQnl0ZUxlbmd0aCIsImJ5dGVzRmlsbGVkIiwiZWxlbWVudFNpemUiLCJ2aWV3Q29uc3RydWN0b3IiLCJyZWFkZXJUeXBlIiwiX3BlbmRpbmdQdWxsSW50b3MiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZCIsInNob3VsZFB1bGwiLCJfc3RhcnRlZCIsIlJlYWRhYmxlU3RyZWFtSGFzQllPQlJlYWRlciIsIlJlYWRhYmxlU3RyZWFtR2V0TnVtUmVhZEludG9SZXF1ZXN0cyIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJTaG91bGRDYWxsUHVsbCIsIl9wdWxsaW5nIiwiX3B1bGxBZ2FpbiIsIl9wdWxsQWxnb3JpdGhtIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckludmFsaWRhdGVCWU9CUmVxdWVzdCIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDb21taXRQdWxsSW50b0Rlc2NyaXB0b3IiLCJmaWxsZWRWaWV3IiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNvbnZlcnRQdWxsSW50b0Rlc2NyaXB0b3IiLCJyZWFkSW50b1JlcXVlc3QiLCJfcmVhZEludG9SZXF1ZXN0cyIsIlJlYWRhYmxlU3RyZWFtRnVsZmlsbFJlYWRJbnRvUmVxdWVzdCIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFbnF1ZXVlQ2h1bmtUb1F1ZXVlIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckZpbGxQdWxsSW50b0Rlc2NyaXB0b3JGcm9tUXVldWUiLCJjdXJyZW50QWxpZ25lZEJ5dGVzIiwibWF4Qnl0ZXNUb0NvcHkiLCJtYXhCeXRlc0ZpbGxlZCIsIm1heEFsaWduZWRCeXRlcyIsInRvdGFsQnl0ZXNUb0NvcHlSZW1haW5pbmciLCJyZWFkeSIsInF1ZXVlIiwiaGVhZE9mUXVldWUiLCJieXRlc1RvQ29weSIsImRlc3RTdGFydCIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJGaWxsSGVhZFB1bGxJbnRvRGVzY3JpcHRvciIsIlJlYWRhYmxlU3RyZWFtQ2xvc2UiLCJfYnlvYlJlcXVlc3QiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUHJvY2Vzc1B1bGxJbnRvRGVzY3JpcHRvcnNVc2luZ1F1ZXVlIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclNoaWZ0UGVuZGluZ1B1bGxJbnRvIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclJlc3BvbmRJbnRlcm5hbCIsImZpcnN0RGVzY3JpcHRvciIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kSW5DbG9zZWRTdGF0ZSIsInJlbWFpbmRlclNpemUiLCJyZW1haW5kZXIiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZEluUmVhZGFibGVTdGF0ZSIsInRyYW5zZmVycmVkQnVmZmVyIiwiZmlyc3RQZW5kaW5nUHVsbEludG8iLCJSZWFkYWJsZVN0cmVhbUVycm9yIiwiU2V0VXBSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0IiwiX3N0cmF0ZWd5SFdNIiwiU2V0VXBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyIiwic3RhcnRBbGdvcml0aG0iLCJwdWxsQWxnb3JpdGhtIiwiY2FuY2VsQWxnb3JpdGhtIiwiciIsIkFjcXVpcmVSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIiLCJSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIiLCJSZWFkYWJsZVN0cmVhbUFkZFJlYWRJbnRvUmVxdWVzdCIsIklzUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyIiwiYnlvYlJlYWRlckJyYW5kQ2hlY2tFeGNlcHRpb24iLCJSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXJSZWFkIiwiRGF0YVZpZXciLCJCWVRFU19QRVJfRUxFTUVOVCIsImN0b3IiLCJlbXB0eVZpZXciLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUHVsbEludG8iLCJFeHRyYWN0SGlnaFdhdGVyTWFyayIsInN0cmF0ZWd5IiwiZGVmYXVsdEhXTSIsIkV4dHJhY3RTaXplQWxnb3JpdGhtIiwiY29udmVydFF1ZXVpbmdTdHJhdGVneSIsImNvbnZlcnRRdWV1aW5nU3RyYXRlZ3lTaXplIiwiY29udmVydFVuZGVybHlpbmdTaW5rQWJvcnRDYWxsYmFjayIsIm9yaWdpbmFsIiwiY29udmVydFVuZGVybHlpbmdTaW5rQ2xvc2VDYWxsYmFjayIsImNvbnZlcnRVbmRlcmx5aW5nU2lua1N0YXJ0Q2FsbGJhY2siLCJjb252ZXJ0VW5kZXJseWluZ1NpbmtXcml0ZUNhbGxiYWNrIiwiYXNzZXJ0V3JpdGFibGVTdHJlYW0iLCJJc1dyaXRhYmxlU3RyZWFtIiwiV3JpdGFibGVTdHJlYW0iLCJyYXdVbmRlcmx5aW5nU2luayIsInJhd1N0cmF0ZWd5IiwidW5kZXJseWluZ1NpbmsiLCJjb252ZXJ0VW5kZXJseWluZ1NpbmsiLCJJbml0aWFsaXplV3JpdGFibGVTdHJlYW0iLCJzaXplQWxnb3JpdGhtIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsIndyaXRlQWxnb3JpdGhtIiwiY2xvc2VBbGdvcml0aG0iLCJhYm9ydEFsZ29yaXRobSIsIlNldFVwV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsIlNldFVwV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckZyb21VbmRlcmx5aW5nU2luayIsImxvY2tlZCIsInN0cmVhbUJyYW5kQ2hlY2tFeGNlcHRpb24kMiIsIklzV3JpdGFibGVTdHJlYW1Mb2NrZWQiLCJXcml0YWJsZVN0cmVhbUFib3J0IiwiV3JpdGFibGVTdHJlYW1DbG9zZVF1ZXVlZE9ySW5GbGlnaHQiLCJXcml0YWJsZVN0cmVhbUNsb3NlIiwiZ2V0V3JpdGVyIiwiQWNxdWlyZVdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlciIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlciIsIl93cml0ZXIiLCJfd3JpdGFibGVTdHJlYW1Db250cm9sbGVyIiwiX3dyaXRlUmVxdWVzdHMiLCJfaW5GbGlnaHRXcml0ZVJlcXVlc3QiLCJfY2xvc2VSZXF1ZXN0IiwiX2luRmxpZ2h0Q2xvc2VSZXF1ZXN0IiwiX3BlbmRpbmdBYm9ydFJlcXVlc3QiLCJfYmFja3ByZXNzdXJlIiwiX2Fib3J0UmVhc29uIiwiX2Fib3J0Q29udHJvbGxlciIsIl9wcm9taXNlIiwid2FzQWxyZWFkeUVycm9yaW5nIiwiX3Jlc29sdmUiLCJfcmVqZWN0IiwiX3JlYXNvbiIsIl93YXNBbHJlYWR5RXJyb3JpbmciLCJXcml0YWJsZVN0cmVhbVN0YXJ0RXJyb3JpbmciLCJjbG9zZVJlcXVlc3QiLCJ3cml0ZXIiLCJkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVzb2x2ZSIsImNsb3NlU2VudGluZWwiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQWR2YW5jZVF1ZXVlSWZOZWVkZWQiLCJXcml0YWJsZVN0cmVhbURlYWxXaXRoUmVqZWN0aW9uIiwiV3JpdGFibGVTdHJlYW1GaW5pc2hFcnJvcmluZyIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckVuc3VyZVJlYWR5UHJvbWlzZVJlamVjdGVkIiwiV3JpdGFibGVTdHJlYW1IYXNPcGVyYXRpb25NYXJrZWRJbkZsaWdodCIsInN0b3JlZEVycm9yIiwid3JpdGVSZXF1ZXN0IiwiV3JpdGFibGVTdHJlYW1SZWplY3RDbG9zZUFuZENsb3NlZFByb21pc2VJZk5lZWRlZCIsImFib3J0UmVxdWVzdCIsImRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlUmVqZWN0IiwiV3JpdGFibGVTdHJlYW1VcGRhdGVCYWNrcHJlc3N1cmUiLCJiYWNrcHJlc3N1cmUiLCJkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZSIsImRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VSZXNldCIsIl9vd25lcldyaXRhYmxlU3RyZWFtIiwiZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZUluaXRpYWxpemVBc1Jlc29sdmVkIiwiZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplIiwiZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZUluaXRpYWxpemVBc1JlamVjdGVkIiwiZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VSZXNvbHZlIiwiZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCIsIklzV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyIiwiZGVmYXVsdFdyaXRlckJyYW5kQ2hlY2tFeGNlcHRpb24iLCJkZWZhdWx0V3JpdGVyTG9ja0V4Y2VwdGlvbiIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJHZXREZXNpcmVkU2l6ZSIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckdldERlc2lyZWRTaXplIiwiX3JlYWR5UHJvbWlzZSIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckFib3J0IiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQ2xvc2UiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJSZWxlYXNlIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyV3JpdGUiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJFbnN1cmVDbG9zZWRQcm9taXNlUmVqZWN0ZWQiLCJfY2xvc2VkUHJvbWlzZVN0YXRlIiwiZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VSZXNldFRvUmVqZWN0ZWQiLCJfcmVhZHlQcm9taXNlU3RhdGUiLCJkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVqZWN0IiwiZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc2V0VG9SZWplY3RlZCIsInJlbGVhc2VkRXJyb3IiLCJjaHVua1NpemUiLCJfc3RyYXRlZ3lTaXplQWxnb3JpdGhtIiwiY2h1bmtTaXplRSIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcklmTmVlZGVkIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldENodW5rU2l6ZSIsIldyaXRhYmxlU3RyZWFtQWRkV3JpdGVSZXF1ZXN0IiwiZW5xdWV1ZUUiLCJfY29udHJvbGxlZFdyaXRhYmxlU3RyZWFtIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldEJhY2twcmVzc3VyZSIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJXcml0ZSIsImFib3J0UmVhc29uIiwiSXNXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyIiwiZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uJDIiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3IiLCJfYWJvcnRBbGdvcml0aG0iLCJXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zIiwiY3JlYXRlQWJvcnRDb250cm9sbGVyIiwiX3dyaXRlQWxnb3JpdGhtIiwiX2Nsb3NlQWxnb3JpdGhtIiwiV3JpdGFibGVTdHJlYW1NYXJrQ2xvc2VSZXF1ZXN0SW5GbGlnaHQiLCJzaW5rQ2xvc2VQcm9taXNlIiwiV3JpdGFibGVTdHJlYW1GaW5pc2hJbkZsaWdodENsb3NlIiwiV3JpdGFibGVTdHJlYW1GaW5pc2hJbkZsaWdodENsb3NlV2l0aEVycm9yIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlclByb2Nlc3NDbG9zZSIsIldyaXRhYmxlU3RyZWFtTWFya0ZpcnN0V3JpdGVSZXF1ZXN0SW5GbGlnaHQiLCJXcml0YWJsZVN0cmVhbUZpbmlzaEluRmxpZ2h0V3JpdGUiLCJXcml0YWJsZVN0cmVhbUZpbmlzaEluRmxpZ2h0V3JpdGVXaXRoRXJyb3IiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyUHJvY2Vzc1dyaXRlIiwiX3JlYWR5UHJvbWlzZV9yZXNvbHZlIiwiX3JlYWR5UHJvbWlzZV9yZWplY3QiLCJOYXRpdmVET01FeGNlcHRpb24iLCJET01FeGNlcHRpb24iLCJET01FeGNlcHRpb24kMSIsImlzRE9NRXhjZXB0aW9uQ29uc3RydWN0b3IiLCJjcmVhdGVET01FeGNlcHRpb25Qb2x5ZmlsbCIsIlJlYWRhYmxlU3RyZWFtUGlwZVRvIiwicHJldmVudENsb3NlIiwicHJldmVudEFib3J0Iiwic2h1dHRpbmdEb3duIiwiY3VycmVudFdyaXRlIiwiYWN0aW9ucyIsInNodXRkb3duV2l0aEFjdGlvbiIsImFsbCIsImFjdGlvbiIsImlzT3JCZWNvbWVzRXJyb3JlZCIsInNodXRkb3duIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQ2xvc2VXaXRoRXJyb3JQcm9wYWdhdGlvbiIsImRlc3RDbG9zZWQiLCJ3YWl0Rm9yV3JpdGVzVG9GaW5pc2giLCJvbGRDdXJyZW50V3JpdGUiLCJvcmlnaW5hbElzRXJyb3IiLCJvcmlnaW5hbEVycm9yIiwiZG9UaGVSZXN0IiwibmV3RXJyb3IiLCJpc0Vycm9yIiwicmVzb2x2ZUxvb3AiLCJyZWplY3RMb29wIiwicmVzb2x2ZVJlYWQiLCJyZWplY3RSZWFkIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsIklzUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsImRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQxIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldERlc2lyZWRTaXplIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsb3NlIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVucXVldWUiLCJSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3IiLCJSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zIiwiX2NvbnRyb2xsZWRSZWFkYWJsZVN0cmVhbSIsIlJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYWxsUHVsbElmTmVlZGVkIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlclNob3VsZENhbGxQdWxsIiwiU2V0VXBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyIiwiUmVhZGFibGVTdHJlYW1UZWUiLCJjbG9uZUZvckJyYW5jaDIiLCJyZWFzb24xIiwicmVhc29uMiIsImJyYW5jaDEiLCJicmFuY2gyIiwicmVzb2x2ZUNhbmNlbFByb21pc2UiLCJyZWFkaW5nIiwiY2FuY2VsZWQxIiwiY2FuY2VsZWQyIiwiY2FuY2VsUHJvbWlzZSIsImZvcndhcmRSZWFkZXJFcnJvciIsInRoaXNSZWFkZXIiLCJwdWxsV2l0aERlZmF1bHRSZWFkZXIiLCJjaHVuazEiLCJjaHVuazIiLCJjbG9uZUUiLCJwdWxsV2l0aEJZT0JSZWFkZXIiLCJmb3JCcmFuY2gyIiwiYnlvYkJyYW5jaCIsIm90aGVyQnJhbmNoIiwiYnlvYkNhbmNlbGVkIiwiY2xvbmVkQ2h1bmsiLCJvdGhlckNhbmNlbGVkIiwicHVsbDFBbGdvcml0aG0iLCJwdWxsMkFsZ29yaXRobSIsImNhbmNlbDFBbGdvcml0aG0iLCJjb21wb3NpdGVSZWFzb24iLCJjYW5jZWxSZXN1bHQiLCJjYW5jZWwyQWxnb3JpdGhtIiwiQ3JlYXRlUmVhZGFibGVCeXRlU3RyZWFtIiwiUmVhZGFibGVCeXRlU3RyZWFtVGVlIiwiQ3JlYXRlUmVhZGFibGVTdHJlYW0iLCJSZWFkYWJsZVN0cmVhbURlZmF1bHRUZWUiLCJjb252ZXJ0VW5kZXJseWluZ1NvdXJjZUNhbmNlbENhbGxiYWNrIiwiY29udmVydFVuZGVybHlpbmdTb3VyY2VQdWxsQ2FsbGJhY2siLCJjb252ZXJ0VW5kZXJseWluZ1NvdXJjZVN0YXJ0Q2FsbGJhY2siLCJjb252ZXJ0UmVhZGFibGVTdHJlYW1UeXBlIiwiY29udmVydFJlYWRhYmxlU3RyZWFtUmVhZGVyTW9kZSIsIm1vZGUiLCJjb252ZXJ0UGlwZU9wdGlvbnMiLCJpc0Fib3J0U2lnbmFsIiwiYXNzZXJ0QWJvcnRTaWduYWwiLCJyYXdVbmRlcmx5aW5nU291cmNlIiwidW5kZXJseWluZ1NvdXJjZSIsInB1bGwiLCJjb252ZXJ0VW5kZXJseWluZ0RlZmF1bHRPckJ5dGVTb3VyY2UiLCJJbml0aWFsaXplUmVhZGFibGVTdHJlYW0iLCJ1bmRlcmx5aW5nQnl0ZVNvdXJjZSIsIlNldFVwUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckZyb21VbmRlcmx5aW5nU291cmNlIiwiU2V0VXBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRnJvbVVuZGVybHlpbmdTb3VyY2UiLCJzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDEiLCJyYXdPcHRpb25zIiwiY29udmVydFJlYWRlck9wdGlvbnMiLCJwaXBlVGhyb3VnaCIsInJhd1RyYW5zZm9ybSIsInRyYW5zZm9ybSIsInJlYWRhYmxlIiwiY29udmVydFJlYWRhYmxlV3JpdGFibGVQYWlyIiwicGlwZVRvIiwiZGVzdGluYXRpb24iLCJ0ZWUiLCJpbXBsIiwiQWNxdWlyZVJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvciIsImNvbnZlcnRJdGVyYXRvck9wdGlvbnMiLCJjb252ZXJ0UXVldWluZ1N0cmF0ZWd5SW5pdCIsImFzeW5jSXRlcmF0b3IiLCJieXRlTGVuZ3RoU2l6ZUZ1bmN0aW9uIiwiQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneSIsIl9ieXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5SGlnaFdhdGVyTWFyayIsIklzQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneSIsImJ5dGVMZW5ndGhCcmFuZENoZWNrRXhjZXB0aW9uIiwiY291bnRTaXplRnVuY3Rpb24iLCJDb3VudFF1ZXVpbmdTdHJhdGVneSIsIl9jb3VudFF1ZXVpbmdTdHJhdGVneUhpZ2hXYXRlck1hcmsiLCJJc0NvdW50UXVldWluZ1N0cmF0ZWd5IiwiY291bnRCcmFuZENoZWNrRXhjZXB0aW9uIiwiY29udmVydFRyYW5zZm9ybWVyRmx1c2hDYWxsYmFjayIsImNvbnZlcnRUcmFuc2Zvcm1lclN0YXJ0Q2FsbGJhY2siLCJjb252ZXJ0VHJhbnNmb3JtZXJUcmFuc2Zvcm1DYWxsYmFjayIsIlRyYW5zZm9ybVN0cmVhbSIsInJhd1RyYW5zZm9ybWVyIiwicmF3V3JpdGFibGVTdHJhdGVneSIsInJhd1JlYWRhYmxlU3RyYXRlZ3kiLCJ3cml0YWJsZVN0cmF0ZWd5IiwicmVhZGFibGVTdHJhdGVneSIsInRyYW5zZm9ybWVyIiwicmVhZGFibGVUeXBlIiwid3JpdGFibGVUeXBlIiwiY29udmVydFRyYW5zZm9ybWVyIiwicmVhZGFibGVIaWdoV2F0ZXJNYXJrIiwicmVhZGFibGVTaXplQWxnb3JpdGhtIiwid3JpdGFibGVIaWdoV2F0ZXJNYXJrIiwid3JpdGFibGVTaXplQWxnb3JpdGhtIiwic3RhcnRQcm9taXNlX3Jlc29sdmUiLCJzdGFydFByb21pc2UiLCJfdHJhbnNmb3JtU3RyZWFtQ29udHJvbGxlciIsIl9iYWNrcHJlc3N1cmVDaGFuZ2VQcm9taXNlIiwiX3dyaXRhYmxlIiwiVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJQZXJmb3JtVHJhbnNmb3JtIiwiVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtXcml0ZUFsZ29yaXRobSIsIlRyYW5zZm9ybVN0cmVhbUVycm9yIiwiVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtBYm9ydEFsZ29yaXRobSIsIl9yZWFkYWJsZSIsImZsdXNoUHJvbWlzZSIsIl9mbHVzaEFsZ29yaXRobSIsIlRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zIiwiVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtDbG9zZUFsZ29yaXRobSIsIlRyYW5zZm9ybVN0cmVhbVNldEJhY2twcmVzc3VyZSIsIlRyYW5zZm9ybVN0cmVhbURlZmF1bHRTb3VyY2VQdWxsQWxnb3JpdGhtIiwiVHJhbnNmb3JtU3RyZWFtRXJyb3JXcml0YWJsZUFuZFVuYmxvY2tXcml0ZSIsIkNyZWF0ZVdyaXRhYmxlU3RyZWFtIiwiX2JhY2twcmVzc3VyZUNoYW5nZVByb21pc2VfcmVzb2x2ZSIsIkluaXRpYWxpemVUcmFuc2Zvcm1TdHJlYW0iLCJUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsInRyYW5zZm9ybUFsZ29yaXRobSIsIlRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZSIsInRyYW5zZm9ybVJlc3VsdEUiLCJmbHVzaEFsZ29yaXRobSIsIl9jb250cm9sbGVkVHJhbnNmb3JtU3RyZWFtIiwiX3RyYW5zZm9ybUFsZ29yaXRobSIsIlNldFVwVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIiLCJTZXRVcFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyRnJvbVRyYW5zZm9ybWVyIiwiSXNUcmFuc2Zvcm1TdHJlYW0iLCJzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uIiwiSXNUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsImRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiIsInRlcm1pbmF0ZSIsIlRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyVGVybWluYXRlIiwicmVhZGFibGVDb250cm9sbGVyIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckhhc0JhY2twcmVzc3VyZSIsIl9fd2VicGFja19tb2R1bGVfY2FjaGVfXyIsIl9fd2VicGFja19yZXF1aXJlX18iLCJtb2R1bGVJZCIsImNhY2hlZE1vZHVsZSIsImxvYWRlZCIsIl9fd2VicGFja19tb2R1bGVzX18iLCJkZWZpbml0aW9uIiwibyIsInByb3AiLCJubWQiLCJwYXRocyIsImNoaWxkcmVuIl0sInNvdXJjZVJvb3QiOiIifQ== - -/***/ }), - -/***/ 4294: +/***/ 4812: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -module.exports = __nccwpck_require__(4219); +module.exports = +{ + parallel : __nccwpck_require__(8210), + serial : __nccwpck_require__(445), + serialOrdered : __nccwpck_require__(3578) +}; /***/ }), -/***/ 4219: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; +/***/ 1700: +/***/ ((module) => { +// API +module.exports = abort; -var net = __nccwpck_require__(1808); -var tls = __nccwpck_require__(4404); -var http = __nccwpck_require__(3685); -var https = __nccwpck_require__(5687); -var events = __nccwpck_require__(2361); -var assert = __nccwpck_require__(9491); -var util = __nccwpck_require__(3837); +/** + * Aborts leftover active jobs + * + * @param {object} state - current state object + */ +function abort(state) +{ + Object.keys(state.jobs).forEach(clean.bind(state)); + // reset leftover jobs + state.jobs = {}; +} -exports.httpOverHttp = httpOverHttp; -exports.httpsOverHttp = httpsOverHttp; -exports.httpOverHttps = httpOverHttps; -exports.httpsOverHttps = httpsOverHttps; +/** + * Cleans up leftover job by invoking abort function for the provided job id + * + * @this state + * @param {string|number} key - job id to abort + */ +function clean(key) +{ + if (typeof this.jobs[key] == 'function') + { + this.jobs[key](); + } +} -function httpOverHttp(options) { - var agent = new TunnelingAgent(options); - agent.request = http.request; - return agent; -} +/***/ }), -function httpsOverHttp(options) { - var agent = new TunnelingAgent(options); - agent.request = http.request; - agent.createSocket = createSecureSocket; - agent.defaultPort = 443; - return agent; -} +/***/ 2794: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -function httpOverHttps(options) { - var agent = new TunnelingAgent(options); - agent.request = https.request; - return agent; -} +var defer = __nccwpck_require__(5295); -function httpsOverHttps(options) { - var agent = new TunnelingAgent(options); - agent.request = https.request; - agent.createSocket = createSecureSocket; - agent.defaultPort = 443; - return agent; -} +// API +module.exports = async; +/** + * Runs provided callback asynchronously + * even if callback itself is not + * + * @param {function} callback - callback to invoke + * @returns {function} - augmented callback + */ +function async(callback) +{ + var isAsync = false; -function TunnelingAgent(options) { - var self = this; - self.options = options || {}; - self.proxyOptions = self.options.proxy || {}; - self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; - self.requests = []; - self.sockets = []; + // check if async happened + defer(function() { isAsync = true; }); - self.on('free', function onFree(socket, host, port, localAddress) { - var options = toOptions(host, port, localAddress); - for (var i = 0, len = self.requests.length; i < len; ++i) { - var pending = self.requests[i]; - if (pending.host === options.host && pending.port === options.port) { - // Detect the request to connect same origin server, - // reuse the connection. - self.requests.splice(i, 1); - pending.request.onSocket(socket); - return; - } + return function async_callback(err, result) + { + if (isAsync) + { + callback(err, result); } - socket.destroy(); - self.removeSocket(socket); - }); + else + { + defer(function nextTick_callback() + { + callback(err, result); + }); + } + }; } -util.inherits(TunnelingAgent, events.EventEmitter); -TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { - var self = this; - var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); - - if (self.sockets.length >= this.maxSockets) { - // We are over limit so we'll add it to the queue. - self.requests.push(options); - return; - } - // If we are under maxSockets create a new one. - self.createSocket(options, function(socket) { - socket.on('free', onFree); - socket.on('close', onCloseOrRemove); - socket.on('agentRemove', onCloseOrRemove); - req.onSocket(socket); +/***/ }), - function onFree() { - self.emit('free', socket, options); - } +/***/ 5295: +/***/ ((module) => { - function onCloseOrRemove(err) { - self.removeSocket(socket); - socket.removeListener('free', onFree); - socket.removeListener('close', onCloseOrRemove); - socket.removeListener('agentRemove', onCloseOrRemove); - } - }); -}; +module.exports = defer; -TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { - var self = this; - var placeholder = {}; - self.sockets.push(placeholder); +/** + * Runs provided function on next iteration of the event loop + * + * @param {function} fn - function to run + */ +function defer(fn) +{ + var nextTick = typeof setImmediate == 'function' + ? setImmediate + : ( + typeof process == 'object' && typeof process.nextTick == 'function' + ? process.nextTick + : null + ); - var connectOptions = mergeOptions({}, self.proxyOptions, { - method: 'CONNECT', - path: options.host + ':' + options.port, - agent: false, - headers: { - host: options.host + ':' + options.port - } - }); - if (options.localAddress) { - connectOptions.localAddress = options.localAddress; + if (nextTick) + { + nextTick(fn); } - if (connectOptions.proxyAuth) { - connectOptions.headers = connectOptions.headers || {}; - connectOptions.headers['Proxy-Authorization'] = 'Basic ' + - new Buffer(connectOptions.proxyAuth).toString('base64'); + else + { + setTimeout(fn, 0); } +} - debug('making CONNECT request'); - var connectReq = self.request(connectOptions); - connectReq.useChunkedEncodingByDefault = false; // for v0.6 - connectReq.once('response', onResponse); // for v0.6 - connectReq.once('upgrade', onUpgrade); // for v0.6 - connectReq.once('connect', onConnect); // for v0.7 or later - connectReq.once('error', onError); - connectReq.end(); - function onResponse(res) { - // Very hacky. This is necessary to avoid http-parser leaks. - res.upgrade = true; - } +/***/ }), - function onUpgrade(res, socket, head) { - // Hacky. - process.nextTick(function() { - onConnect(res, socket, head); - }); - } +/***/ 9023: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - function onConnect(res, socket, head) { - connectReq.removeAllListeners(); - socket.removeAllListeners(); +var async = __nccwpck_require__(2794) + , abort = __nccwpck_require__(1700) + ; - if (res.statusCode !== 200) { - debug('tunneling socket could not be established, statusCode=%d', - res.statusCode); - socket.destroy(); - var error = new Error('tunneling socket could not be established, ' + - 'statusCode=' + res.statusCode); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); +// API +module.exports = iterate; + +/** + * Iterates over each job object + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {object} state - current job status + * @param {function} callback - invoked when all elements processed + */ +function iterate(list, iterator, state, callback) +{ + // store current index + var key = state['keyedList'] ? state['keyedList'][state.index] : state.index; + + state.jobs[key] = runJob(iterator, key, list[key], function(error, output) + { + // don't repeat yourself + // skip secondary callbacks + if (!(key in state.jobs)) + { return; } - if (head.length > 0) { - debug('got illegal response body from proxy'); - socket.destroy(); - var error = new Error('got illegal response body from proxy'); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); - return; + + // clean up jobs + delete state.jobs[key]; + + if (error) + { + // don't process rest of the results + // stop still active jobs + // and reset the list + abort(state); + } + else + { + state.results[key] = output; } - debug('tunneling connection has established'); - self.sockets[self.sockets.indexOf(placeholder)] = socket; - return cb(socket); - } - function onError(cause) { - connectReq.removeAllListeners(); + // return salvaged results + callback(error, state.results); + }); +} - debug('tunneling socket could not be established, cause=%s\n', - cause.message, cause.stack); - var error = new Error('tunneling socket could not be established, ' + - 'cause=' + cause.message); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); - } -}; +/** + * Runs iterator over provided job element + * + * @param {function} iterator - iterator to invoke + * @param {string|number} key - key/index of the element in the list of jobs + * @param {mixed} item - job description + * @param {function} callback - invoked after iterator is done with the job + * @returns {function|mixed} - job abort function or something else + */ +function runJob(iterator, key, item, callback) +{ + var aborter; -TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { - var pos = this.sockets.indexOf(socket) - if (pos === -1) { - return; + // allow shortcut if iterator expects only two arguments + if (iterator.length == 2) + { + aborter = iterator(item, async(callback)); } - this.sockets.splice(pos, 1); - - var pending = this.requests.shift(); - if (pending) { - // If we have pending requests and a socket gets closed a new one - // needs to be created to take over in the pool for the one that closed. - this.createSocket(pending, function(socket) { - pending.request.onSocket(socket); - }); + // otherwise go with full three arguments + else + { + aborter = iterator(item, key, async(callback)); } -}; - -function createSecureSocket(options, cb) { - var self = this; - TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { - var hostHeader = options.request.getHeader('host'); - var tlsOptions = mergeOptions({}, self.options, { - socket: socket, - servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host - }); - // 0 is dummy port for v0.6 - var secureSocket = tls.connect(0, tlsOptions); - self.sockets[self.sockets.indexOf(socket)] = secureSocket; - cb(secureSocket); - }); + return aborter; } -function toOptions(host, port, localAddress) { - if (typeof host === 'string') { // since v0.10 - return { - host: host, - port: port, - localAddress: localAddress - }; - } - return host; // for v0.11 or later -} +/***/ }), -function mergeOptions(target) { - for (var i = 1, len = arguments.length; i < len; ++i) { - var overrides = arguments[i]; - if (typeof overrides === 'object') { - var keys = Object.keys(overrides); - for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { - var k = keys[j]; - if (overrides[k] !== undefined) { - target[k] = overrides[k]; - } - } - } - } - return target; -} +/***/ 2474: +/***/ ((module) => { +// API +module.exports = state; -var debug; -if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { - debug = function() { - var args = Array.prototype.slice.call(arguments); - if (typeof args[0] === 'string') { - args[0] = 'TUNNEL: ' + args[0]; - } else { - args.unshift('TUNNEL:'); +/** + * Creates initial state object + * for iteration over list + * + * @param {array|object} list - list to iterate over + * @param {function|null} sortMethod - function to use for keys sort, + * or `null` to keep them as is + * @returns {object} - initial state object + */ +function state(list, sortMethod) +{ + var isNamedList = !Array.isArray(list) + , initState = + { + index : 0, + keyedList: isNamedList || sortMethod ? Object.keys(list) : null, + jobs : {}, + results : isNamedList ? {} : [], + size : isNamedList ? Object.keys(list).length : list.length } - console.error.apply(console, args); + ; + + if (sortMethod) + { + // sort array keys based on it's values + // sort object's keys just on own merit + initState.keyedList.sort(isNamedList ? sortMethod : function(a, b) + { + return sortMethod(list[a], list[b]); + }); } -} else { - debug = function() {}; + + return initState; } -exports.debug = debug; // for test /***/ }), -/***/ 1773: +/***/ 7942: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -"use strict"; +var abort = __nccwpck_require__(1700) + , async = __nccwpck_require__(2794) + ; +// API +module.exports = terminator; -const Client = __nccwpck_require__(3598) -const Dispatcher = __nccwpck_require__(412) -const errors = __nccwpck_require__(8045) -const Pool = __nccwpck_require__(4634) -const BalancedPool = __nccwpck_require__(7931) -const Agent = __nccwpck_require__(7890) -const util = __nccwpck_require__(3983) -const { InvalidArgumentError } = errors -const api = __nccwpck_require__(4059) -const buildConnector = __nccwpck_require__(2067) -const MockClient = __nccwpck_require__(8687) -const MockAgent = __nccwpck_require__(6771) -const MockPool = __nccwpck_require__(6193) -const mockErrors = __nccwpck_require__(888) -const ProxyAgent = __nccwpck_require__(7858) -const RetryHandler = __nccwpck_require__(2286) -const { getGlobalDispatcher, setGlobalDispatcher } = __nccwpck_require__(1892) -const DecoratorHandler = __nccwpck_require__(6930) -const RedirectHandler = __nccwpck_require__(2860) -const createRedirectInterceptor = __nccwpck_require__(8861) +/** + * Terminates jobs in the attached state context + * + * @this AsyncKitState# + * @param {function} callback - final callback to invoke after termination + */ +function terminator(callback) +{ + if (!Object.keys(this.jobs).length) + { + return; + } -let hasCrypto -try { - __nccwpck_require__(6113) - hasCrypto = true -} catch { - hasCrypto = false -} + // fast forward iteration index + this.index = this.size; -Object.assign(Dispatcher.prototype, api) + // abort jobs + abort(this); -module.exports.Dispatcher = Dispatcher -module.exports.Client = Client -module.exports.Pool = Pool -module.exports.BalancedPool = BalancedPool -module.exports.Agent = Agent -module.exports.ProxyAgent = ProxyAgent -module.exports.RetryHandler = RetryHandler + // send back results we have so far + async(callback)(null, this.results); +} -module.exports.DecoratorHandler = DecoratorHandler -module.exports.RedirectHandler = RedirectHandler -module.exports.createRedirectInterceptor = createRedirectInterceptor -module.exports.buildConnector = buildConnector -module.exports.errors = errors +/***/ }), -function makeDispatcher (fn) { - return (url, opts, handler) => { - if (typeof opts === 'function') { - handler = opts - opts = null - } +/***/ 8210: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (!url || (typeof url !== 'string' && typeof url !== 'object' && !(url instanceof URL))) { - throw new InvalidArgumentError('invalid url') - } +var iterate = __nccwpck_require__(9023) + , initState = __nccwpck_require__(2474) + , terminator = __nccwpck_require__(7942) + ; - if (opts != null && typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') - } +// Public API +module.exports = parallel; - if (opts && opts.path != null) { - if (typeof opts.path !== 'string') { - throw new InvalidArgumentError('invalid opts.path') - } +/** + * Runs iterator over provided array elements in parallel + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function parallel(list, iterator, callback) +{ + var state = initState(list); - let path = opts.path - if (!opts.path.startsWith('/')) { - path = `/${path}` + while (state.index < (state['keyedList'] || list).length) + { + iterate(list, iterator, state, function(error, result) + { + if (error) + { + callback(error, result); + return; } - url = new URL(util.parseOrigin(url).origin + path) - } else { - if (!opts) { - opts = typeof url === 'object' ? url : {} + // looks like it's the last one + if (Object.keys(state.jobs).length === 0) + { + callback(null, state.results); + return; } + }); - url = util.parseURL(url) - } + state.index++; + } - const { agent, dispatcher = getGlobalDispatcher() } = opts + return terminator.bind(state, callback); +} - if (agent) { - throw new InvalidArgumentError('unsupported opts.agent. Did you mean opts.client?') - } - return fn.call(dispatcher, { - ...opts, - origin: url.origin, - path: url.search ? `${url.pathname}${url.search}` : url.pathname, - method: opts.method || (opts.body ? 'PUT' : 'GET') - }, handler) - } -} +/***/ }), -module.exports.setGlobalDispatcher = setGlobalDispatcher -module.exports.getGlobalDispatcher = getGlobalDispatcher +/***/ 445: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -if (util.nodeMajor > 16 || (util.nodeMajor === 16 && util.nodeMinor >= 8)) { - let fetchImpl = null - module.exports.fetch = async function fetch (resource) { - if (!fetchImpl) { - fetchImpl = (__nccwpck_require__(4881).fetch) - } +var serialOrdered = __nccwpck_require__(3578); - try { - return await fetchImpl(...arguments) - } catch (err) { - if (typeof err === 'object') { - Error.captureStackTrace(err, this) - } +// Public API +module.exports = serial; - throw err - } - } - module.exports.Headers = __nccwpck_require__(554).Headers - module.exports.Response = __nccwpck_require__(7823).Response - module.exports.Request = __nccwpck_require__(8359).Request - module.exports.FormData = __nccwpck_require__(2015).FormData - module.exports.File = __nccwpck_require__(8511).File - module.exports.FileReader = __nccwpck_require__(1446).FileReader +/** + * Runs iterator over provided array elements in series + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function serial(list, iterator, callback) +{ + return serialOrdered(list, iterator, null, callback); +} - const { setGlobalOrigin, getGlobalOrigin } = __nccwpck_require__(1246) - module.exports.setGlobalOrigin = setGlobalOrigin - module.exports.getGlobalOrigin = getGlobalOrigin +/***/ }), - const { CacheStorage } = __nccwpck_require__(7907) - const { kConstruct } = __nccwpck_require__(9174) +/***/ 3578: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // Cache & CacheStorage are tightly coupled with fetch. Even if it may run - // in an older version of Node, it doesn't have any use without fetch. - module.exports.caches = new CacheStorage(kConstruct) -} +var iterate = __nccwpck_require__(9023) + , initState = __nccwpck_require__(2474) + , terminator = __nccwpck_require__(7942) + ; -if (util.nodeMajor >= 16) { - const { deleteCookie, getCookies, getSetCookies, setCookie } = __nccwpck_require__(1724) +// Public API +module.exports = serialOrdered; +// sorting helpers +module.exports.ascending = ascending; +module.exports.descending = descending; - module.exports.deleteCookie = deleteCookie - module.exports.getCookies = getCookies - module.exports.getSetCookies = getSetCookies - module.exports.setCookie = setCookie +/** + * Runs iterator over provided sorted array elements in series + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} sortMethod - custom sort function + * @param {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function serialOrdered(list, iterator, sortMethod, callback) +{ + var state = initState(list, sortMethod); - const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685) + iterate(list, iterator, state, function iteratorHandler(error, result) + { + if (error) + { + callback(error, result); + return; + } - module.exports.parseMIMEType = parseMIMEType - module.exports.serializeAMimeType = serializeAMimeType -} + state.index++; -if (util.nodeMajor >= 18 && hasCrypto) { - const { WebSocket } = __nccwpck_require__(4284) + // are we there yet? + if (state.index < (state['keyedList'] || list).length) + { + iterate(list, iterator, state, iteratorHandler); + return; + } - module.exports.WebSocket = WebSocket + // done here + callback(null, state.results); + }); + + return terminator.bind(state, callback); } -module.exports.request = makeDispatcher(api.request) -module.exports.stream = makeDispatcher(api.stream) -module.exports.pipeline = makeDispatcher(api.pipeline) -module.exports.connect = makeDispatcher(api.connect) -module.exports.upgrade = makeDispatcher(api.upgrade) +/* + * -- Sort methods + */ -module.exports.MockClient = MockClient -module.exports.MockPool = MockPool -module.exports.MockAgent = MockAgent -module.exports.mockErrors = mockErrors +/** + * sort helper to sort array elements in ascending order + * + * @param {mixed} a - an item to compare + * @param {mixed} b - an item to compare + * @returns {number} - comparison result + */ +function ascending(a, b) +{ + return a < b ? -1 : a > b ? 1 : 0; +} + +/** + * sort helper to sort array elements in descending order + * + * @param {mixed} a - an item to compare + * @param {mixed} b - an item to compare + * @returns {number} - comparison result + */ +function descending(a, b) +{ + return -1 * ascending(a, b); +} /***/ }), -/***/ 7890: +/***/ 5443: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -"use strict"; +var util = __nccwpck_require__(3837); +var Stream = (__nccwpck_require__(2781).Stream); +var DelayedStream = __nccwpck_require__(8611); +module.exports = CombinedStream; +function CombinedStream() { + this.writable = false; + this.readable = true; + this.dataSize = 0; + this.maxDataSize = 2 * 1024 * 1024; + this.pauseStreams = true; -const { InvalidArgumentError } = __nccwpck_require__(8045) -const { kClients, kRunning, kClose, kDestroy, kDispatch, kInterceptors } = __nccwpck_require__(2785) -const DispatcherBase = __nccwpck_require__(4839) -const Pool = __nccwpck_require__(4634) -const Client = __nccwpck_require__(3598) -const util = __nccwpck_require__(3983) -const createRedirectInterceptor = __nccwpck_require__(8861) -const { WeakRef, FinalizationRegistry } = __nccwpck_require__(6436)() + this._released = false; + this._streams = []; + this._currentStream = null; + this._insideLoop = false; + this._pendingNext = false; +} +util.inherits(CombinedStream, Stream); -const kOnConnect = Symbol('onConnect') -const kOnDisconnect = Symbol('onDisconnect') -const kOnConnectionError = Symbol('onConnectionError') -const kMaxRedirections = Symbol('maxRedirections') -const kOnDrain = Symbol('onDrain') -const kFactory = Symbol('factory') -const kFinalizer = Symbol('finalizer') -const kOptions = Symbol('options') +CombinedStream.create = function(options) { + var combinedStream = new this(); -function defaultFactory (origin, opts) { - return opts && opts.connections === 1 - ? new Client(origin, opts) - : new Pool(origin, opts) -} + options = options || {}; + for (var option in options) { + combinedStream[option] = options[option]; + } -class Agent extends DispatcherBase { - constructor ({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { - super() + return combinedStream; +}; - if (typeof factory !== 'function') { - throw new InvalidArgumentError('factory must be a function.') - } +CombinedStream.isStreamLike = function(stream) { + return (typeof stream !== 'function') + && (typeof stream !== 'string') + && (typeof stream !== 'boolean') + && (typeof stream !== 'number') + && (!Buffer.isBuffer(stream)); +}; - if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { - throw new InvalidArgumentError('connect must be a function or an object') - } +CombinedStream.prototype.append = function(stream) { + var isStreamLike = CombinedStream.isStreamLike(stream); - if (!Number.isInteger(maxRedirections) || maxRedirections < 0) { - throw new InvalidArgumentError('maxRedirections must be a positive number') + if (isStreamLike) { + if (!(stream instanceof DelayedStream)) { + var newStream = DelayedStream.create(stream, { + maxDataSize: Infinity, + pauseStream: this.pauseStreams, + }); + stream.on('data', this._checkDataSize.bind(this)); + stream = newStream; } - if (connect && typeof connect !== 'function') { - connect = { ...connect } + this._handleErrors(stream); + + if (this.pauseStreams) { + stream.pause(); } + } - this[kInterceptors] = options.interceptors && options.interceptors.Agent && Array.isArray(options.interceptors.Agent) - ? options.interceptors.Agent - : [createRedirectInterceptor({ maxRedirections })] + this._streams.push(stream); + return this; +}; - this[kOptions] = { ...util.deepClone(options), connect } - this[kOptions].interceptors = options.interceptors - ? { ...options.interceptors } - : undefined - this[kMaxRedirections] = maxRedirections - this[kFactory] = factory - this[kClients] = new Map() - this[kFinalizer] = new FinalizationRegistry(/* istanbul ignore next: gc is undeterministic */ key => { - const ref = this[kClients].get(key) - if (ref !== undefined && ref.deref() === undefined) { - this[kClients].delete(key) - } - }) +CombinedStream.prototype.pipe = function(dest, options) { + Stream.prototype.pipe.call(this, dest, options); + this.resume(); + return dest; +}; - const agent = this +CombinedStream.prototype._getNext = function() { + this._currentStream = null; - this[kOnDrain] = (origin, targets) => { - agent.emit('drain', origin, [agent, ...targets]) - } + if (this._insideLoop) { + this._pendingNext = true; + return; // defer call + } - this[kOnConnect] = (origin, targets) => { - agent.emit('connect', origin, [agent, ...targets]) - } + this._insideLoop = true; + try { + do { + this._pendingNext = false; + this._realGetNext(); + } while (this._pendingNext); + } finally { + this._insideLoop = false; + } +}; - this[kOnDisconnect] = (origin, targets, err) => { - agent.emit('disconnect', origin, [agent, ...targets], err) - } +CombinedStream.prototype._realGetNext = function() { + var stream = this._streams.shift(); - this[kOnConnectionError] = (origin, targets, err) => { - agent.emit('connectionError', origin, [agent, ...targets], err) - } + + if (typeof stream == 'undefined') { + this.end(); + return; } - get [kRunning] () { - let ret = 0 - for (const ref of this[kClients].values()) { - const client = ref.deref() - /* istanbul ignore next: gc is undeterministic */ - if (client) { - ret += client[kRunning] - } - } - return ret + if (typeof stream !== 'function') { + this._pipeNext(stream); + return; } - [kDispatch] (opts, handler) { - let key - if (opts.origin && (typeof opts.origin === 'string' || opts.origin instanceof URL)) { - key = String(opts.origin) - } else { - throw new InvalidArgumentError('opts.origin must be a non-empty string or URL.') + var getStream = stream; + getStream(function(stream) { + var isStreamLike = CombinedStream.isStreamLike(stream); + if (isStreamLike) { + stream.on('data', this._checkDataSize.bind(this)); + this._handleErrors(stream); } - const ref = this[kClients].get(key) - - let dispatcher = ref ? ref.deref() : null - if (!dispatcher) { - dispatcher = this[kFactory](opts.origin, this[kOptions]) - .on('drain', this[kOnDrain]) - .on('connect', this[kOnConnect]) - .on('disconnect', this[kOnDisconnect]) - .on('connectionError', this[kOnConnectionError]) + this._pipeNext(stream); + }.bind(this)); +}; - this[kClients].set(key, new WeakRef(dispatcher)) - this[kFinalizer].register(dispatcher, key) - } +CombinedStream.prototype._pipeNext = function(stream) { + this._currentStream = stream; - return dispatcher.dispatch(opts, handler) + var isStreamLike = CombinedStream.isStreamLike(stream); + if (isStreamLike) { + stream.on('end', this._getNext.bind(this)); + stream.pipe(this, {end: false}); + return; } - async [kClose] () { - const closePromises = [] - for (const ref of this[kClients].values()) { - const client = ref.deref() - /* istanbul ignore else: gc is undeterministic */ - if (client) { - closePromises.push(client.close()) - } - } + var value = stream; + this.write(value); + this._getNext(); +}; - await Promise.all(closePromises) - } +CombinedStream.prototype._handleErrors = function(stream) { + var self = this; + stream.on('error', function(err) { + self._emitError(err); + }); +}; - async [kDestroy] (err) { - const destroyPromises = [] - for (const ref of this[kClients].values()) { - const client = ref.deref() - /* istanbul ignore else: gc is undeterministic */ - if (client) { - destroyPromises.push(client.destroy(err)) - } - } +CombinedStream.prototype.write = function(data) { + this.emit('data', data); +}; - await Promise.all(destroyPromises) +CombinedStream.prototype.pause = function() { + if (!this.pauseStreams) { + return; } -} - -module.exports = Agent + if(this.pauseStreams && this._currentStream && typeof(this._currentStream.pause) == 'function') this._currentStream.pause(); + this.emit('pause'); +}; -/***/ }), - -/***/ 7032: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +CombinedStream.prototype.resume = function() { + if (!this._released) { + this._released = true; + this.writable = true; + this._getNext(); + } -const { addAbortListener } = __nccwpck_require__(3983) -const { RequestAbortedError } = __nccwpck_require__(8045) + if(this.pauseStreams && this._currentStream && typeof(this._currentStream.resume) == 'function') this._currentStream.resume(); + this.emit('resume'); +}; -const kListener = Symbol('kListener') -const kSignal = Symbol('kSignal') +CombinedStream.prototype.end = function() { + this._reset(); + this.emit('end'); +}; -function abort (self) { - if (self.abort) { - self.abort() - } else { - self.onError(new RequestAbortedError()) - } -} +CombinedStream.prototype.destroy = function() { + this._reset(); + this.emit('close'); +}; -function addSignal (self, signal) { - self[kSignal] = null - self[kListener] = null +CombinedStream.prototype._reset = function() { + this.writable = false; + this._streams = []; + this._currentStream = null; +}; - if (!signal) { - return +CombinedStream.prototype._checkDataSize = function() { + this._updateDataSize(); + if (this.dataSize <= this.maxDataSize) { + return; } - if (signal.aborted) { - abort(self) - return - } + var message = + 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'; + this._emitError(new Error(message)); +}; - self[kSignal] = signal - self[kListener] = () => { - abort(self) - } +CombinedStream.prototype._updateDataSize = function() { + this.dataSize = 0; - addAbortListener(self[kSignal], self[kListener]) -} + var self = this; + this._streams.forEach(function(stream) { + if (!stream.dataSize) { + return; + } -function removeSignal (self) { - if (!self[kSignal]) { - return - } + self.dataSize += stream.dataSize; + }); - if ('removeEventListener' in self[kSignal]) { - self[kSignal].removeEventListener('abort', self[kListener]) - } else { - self[kSignal].removeListener('abort', self[kListener]) + if (this._currentStream && this._currentStream.dataSize) { + this.dataSize += this._currentStream.dataSize; } +}; - self[kSignal] = null - self[kListener] = null -} - -module.exports = { - addSignal, - removeSignal -} +CombinedStream.prototype._emitError = function(err) { + this._reset(); + this.emit('error', err); +}; /***/ }), -/***/ 9744: +/***/ 8611: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -"use strict"; - +var Stream = (__nccwpck_require__(2781).Stream); +var util = __nccwpck_require__(3837); -const { AsyncResource } = __nccwpck_require__(852) -const { InvalidArgumentError, RequestAbortedError, SocketError } = __nccwpck_require__(8045) -const util = __nccwpck_require__(3983) -const { addSignal, removeSignal } = __nccwpck_require__(7032) +module.exports = DelayedStream; +function DelayedStream() { + this.source = null; + this.dataSize = 0; + this.maxDataSize = 1024 * 1024; + this.pauseStream = true; -class ConnectHandler extends AsyncResource { - constructor (opts, callback) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') - } - - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } + this._maxDataSizeExceeded = false; + this._released = false; + this._bufferedEvents = []; +} +util.inherits(DelayedStream, Stream); - const { signal, opaque, responseHeaders } = opts +DelayedStream.create = function(source, options) { + var delayedStream = new this(); - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') - } + options = options || {}; + for (var option in options) { + delayedStream[option] = options[option]; + } - super('UNDICI_CONNECT') + delayedStream.source = source; - this.opaque = opaque || null - this.responseHeaders = responseHeaders || null - this.callback = callback - this.abort = null + var realEmit = source.emit; + source.emit = function() { + delayedStream._handleEmit(arguments); + return realEmit.apply(source, arguments); + }; - addSignal(this, signal) + source.on('error', function() {}); + if (delayedStream.pauseStream) { + source.pause(); } - onConnect (abort, context) { - if (!this.callback) { - throw new RequestAbortedError() - } + return delayedStream; +}; - this.abort = abort - this.context = context +Object.defineProperty(DelayedStream.prototype, 'readable', { + configurable: true, + enumerable: true, + get: function() { + return this.source.readable; } +}); - onHeaders () { - throw new SocketError('bad connect', null) - } +DelayedStream.prototype.setEncoding = function() { + return this.source.setEncoding.apply(this.source, arguments); +}; - onUpgrade (statusCode, rawHeaders, socket) { - const { callback, opaque, context } = this +DelayedStream.prototype.resume = function() { + if (!this._released) { + this.release(); + } - removeSignal(this) + this.source.resume(); +}; - this.callback = null +DelayedStream.prototype.pause = function() { + this.source.pause(); +}; - let headers = rawHeaders - // Indicates is an HTTP2Session - if (headers != null) { - headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) - } +DelayedStream.prototype.release = function() { + this._released = true; - this.runInAsyncScope(callback, null, null, { - statusCode, - headers, - socket, - opaque, - context - }) - } + this._bufferedEvents.forEach(function(args) { + this.emit.apply(this, args); + }.bind(this)); + this._bufferedEvents = []; +}; - onError (err) { - const { callback, opaque } = this +DelayedStream.prototype.pipe = function() { + var r = Stream.prototype.pipe.apply(this, arguments); + this.resume(); + return r; +}; - removeSignal(this) +DelayedStream.prototype._handleEmit = function(args) { + if (this._released) { + this.emit.apply(this, args); + return; + } - if (callback) { - this.callback = null - queueMicrotask(() => { - this.runInAsyncScope(callback, null, err, { opaque }) - }) - } + if (args[0] === 'data') { + this.dataSize += args[1].length; + this._checkIfMaxDataSizeExceeded(); } -} -function connect (opts, callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - connect.call(this, opts, (err, data) => { - return err ? reject(err) : resolve(data) - }) - }) + this._bufferedEvents.push(args); +}; + +DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() { + if (this._maxDataSizeExceeded) { + return; } - try { - const connectHandler = new ConnectHandler(opts, callback) - this.dispatch({ ...opts, method: 'CONNECT' }, connectHandler) - } catch (err) { - if (typeof callback !== 'function') { - throw err - } - const opaque = opts && opts.opaque - queueMicrotask(() => callback(err, { opaque })) + if (this.dataSize <= this.maxDataSize) { + return; } -} -module.exports = connect + this._maxDataSizeExceeded = true; + var message = + 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.' + this.emit('error', new Error(message)); +}; /***/ }), -/***/ 8752: +/***/ 4334: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -"use strict"; +var CombinedStream = __nccwpck_require__(5443); +var util = __nccwpck_require__(3837); +var path = __nccwpck_require__(1017); +var http = __nccwpck_require__(3685); +var https = __nccwpck_require__(5687); +var parseUrl = (__nccwpck_require__(7310).parse); +var fs = __nccwpck_require__(7147); +var Stream = (__nccwpck_require__(2781).Stream); +var mime = __nccwpck_require__(3583); +var asynckit = __nccwpck_require__(4812); +var populate = __nccwpck_require__(7142); +// Public API +module.exports = FormData; -const { - Readable, - Duplex, - PassThrough -} = __nccwpck_require__(2781) -const { - InvalidArgumentError, - InvalidReturnValueError, - RequestAbortedError -} = __nccwpck_require__(8045) -const util = __nccwpck_require__(3983) -const { AsyncResource } = __nccwpck_require__(852) -const { addSignal, removeSignal } = __nccwpck_require__(7032) -const assert = __nccwpck_require__(9491) +// make it a Stream +util.inherits(FormData, CombinedStream); -const kResume = Symbol('resume') +/** + * Create readable "multipart/form-data" streams. + * Can be used to submit forms + * and file uploads to other web applications. + * + * @constructor + * @param {Object} options - Properties to be added/overriden for FormData and CombinedStream + */ +function FormData(options) { + if (!(this instanceof FormData)) { + return new FormData(options); + } -class PipelineRequest extends Readable { - constructor () { - super({ autoDestroy: true }) + this._overheadLength = 0; + this._valueLength = 0; + this._valuesToMeasure = []; - this[kResume] = null + CombinedStream.call(this); + + options = options || {}; + for (var option in options) { + this[option] = options[option]; } +} - _read () { - const { [kResume]: resume } = this +FormData.LINE_BREAK = '\r\n'; +FormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream'; - if (resume) { - this[kResume] = null - resume() - } - } +FormData.prototype.append = function(field, value, options) { - _destroy (err, callback) { - this._read() + options = options || {}; - callback(err) + // allow filename as single option + if (typeof options == 'string') { + options = {filename: options}; } -} -class PipelineResponse extends Readable { - constructor (resume) { - super({ autoDestroy: true }) - this[kResume] = resume - } + var append = CombinedStream.prototype.append.bind(this); - _read () { - this[kResume]() + // all that streamy business can't handle numbers + if (typeof value == 'number') { + value = '' + value; } - _destroy (err, callback) { - if (!err && !this._readableState.endEmitted) { - err = new RequestAbortedError() - } - - callback(err) + // https://github.com/felixge/node-form-data/issues/38 + if (util.isArray(value)) { + // Please convert your array into string + // the way web server expects it + this._error(new Error('Arrays are not supported.')); + return; } -} -class PipelineHandler extends AsyncResource { - constructor (opts, handler) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') - } + var header = this._multiPartHeader(field, value, options); + var footer = this._multiPartFooter(); - if (typeof handler !== 'function') { - throw new InvalidArgumentError('invalid handler') - } + append(header); + append(value); + append(footer); - const { signal, method, opaque, onInfo, responseHeaders } = opts + // pass along options.knownLength + this._trackLength(header, value, options); +}; - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') - } +FormData.prototype._trackLength = function(header, value, options) { + var valueLength = 0; - if (method === 'CONNECT') { - throw new InvalidArgumentError('invalid method') - } + // used w/ getLengthSync(), when length is known. + // e.g. for streaming directly from a remote server, + // w/ a known file a size, and not wanting to wait for + // incoming file to finish to get its size. + if (options.knownLength != null) { + valueLength += +options.knownLength; + } else if (Buffer.isBuffer(value)) { + valueLength = value.length; + } else if (typeof value === 'string') { + valueLength = Buffer.byteLength(value); + } - if (onInfo && typeof onInfo !== 'function') { - throw new InvalidArgumentError('invalid onInfo callback') - } + this._valueLength += valueLength; - super('UNDICI_PIPELINE') + // @check why add CRLF? does this account for custom/multiple CRLFs? + this._overheadLength += + Buffer.byteLength(header) + + FormData.LINE_BREAK.length; - this.opaque = opaque || null - this.responseHeaders = responseHeaders || null - this.handler = handler - this.abort = null - this.context = null - this.onInfo = onInfo || null + // empty or either doesn't have path or not an http response or not a stream + if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) && !(value instanceof Stream))) { + return; + } - this.req = new PipelineRequest().on('error', util.nop) + // no need to bother with the length + if (!options.knownLength) { + this._valuesToMeasure.push(value); + } +}; - this.ret = new Duplex({ - readableObjectMode: opts.objectMode, - autoDestroy: true, - read: () => { - const { body } = this +FormData.prototype._lengthRetriever = function(value, callback) { - if (body && body.resume) { - body.resume() - } - }, - write: (chunk, encoding, callback) => { - const { req } = this + if (value.hasOwnProperty('fd')) { - if (req.push(chunk, encoding) || req._readableState.destroyed) { - callback() - } else { - req[kResume] = callback - } - }, - destroy: (err, callback) => { - const { body, req, res, ret, abort } = this + // take read range into a account + // `end` = Infinity –> read file till the end + // + // TODO: Looks like there is bug in Node fs.createReadStream + // it doesn't respect `end` options without `start` options + // Fix it when node fixes it. + // https://github.com/joyent/node/issues/7819 + if (value.end != undefined && value.end != Infinity && value.start != undefined) { - if (!err && !ret._readableState.endEmitted) { - err = new RequestAbortedError() - } + // when end specified + // no need to calculate range + // inclusive, starts with 0 + callback(null, value.end + 1 - (value.start ? value.start : 0)); - if (abort && err) { - abort() - } + // not that fast snoopy + } else { + // still need to fetch file size from fs + fs.stat(value.path, function(err, stat) { - util.destroy(body, err) - util.destroy(req, err) - util.destroy(res, err) + var fileSize; - removeSignal(this) + if (err) { + callback(err); + return; + } - callback(err) - } - }).on('prefinish', () => { - const { req } = this + // update final size based on the range options + fileSize = stat.size - (value.start ? value.start : 0); + callback(null, fileSize); + }); + } - // Node < 15 does not call _final in same tick. - req.push(null) - }) + // or http response + } else if (value.hasOwnProperty('httpVersion')) { + callback(null, +value.headers['content-length']); - this.res = null + // or request stream http://github.com/mikeal/request + } else if (value.hasOwnProperty('httpModule')) { + // wait till response come back + value.on('response', function(response) { + value.pause(); + callback(null, +response.headers['content-length']); + }); + value.resume(); - addSignal(this, signal) + // something else + } else { + callback('Unknown stream'); } +}; - onConnect (abort, context) { - const { ret, res } = this +FormData.prototype._multiPartHeader = function(field, value, options) { + // custom header specified (as string)? + // it becomes responsible for boundary + // (e.g. to handle extra CRLFs on .NET servers) + if (typeof options.header == 'string') { + return options.header; + } - assert(!res, 'pipeline cannot be retried') + var contentDisposition = this._getContentDisposition(value, options); + var contentType = this._getContentType(value, options); - if (ret.destroyed) { - throw new RequestAbortedError() - } + var contents = ''; + var headers = { + // add custom disposition as third element or keep it two elements if not + 'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []), + // if no content type. allow it to be empty array + 'Content-Type': [].concat(contentType || []) + }; - this.abort = abort - this.context = context + // allow custom headers. + if (typeof options.header == 'object') { + populate(headers, options.header); } - onHeaders (statusCode, rawHeaders, resume) { - const { opaque, handler, context } = this + var header; + for (var prop in headers) { + if (!headers.hasOwnProperty(prop)) continue; + header = headers[prop]; - if (statusCode < 200) { - if (this.onInfo) { - const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) - this.onInfo({ statusCode, headers }) - } - return + // skip nullish headers. + if (header == null) { + continue; } - this.res = new PipelineResponse(resume) - - let body - try { - this.handler = null - const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) - body = this.runInAsyncScope(handler, null, { - statusCode, - headers, - opaque, - body: this.res, - context - }) - } catch (err) { - this.res.on('error', util.nop) - throw err + // convert all headers to arrays. + if (!Array.isArray(header)) { + header = [header]; } - if (!body || typeof body.on !== 'function') { - throw new InvalidReturnValueError('expected Readable') + // add non-empty headers. + if (header.length) { + contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK; } + } - body - .on('data', (chunk) => { - const { ret, body } = this + return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK; +}; - if (!ret.push(chunk) && body.pause) { - body.pause() - } - }) - .on('error', (err) => { - const { ret } = this +FormData.prototype._getContentDisposition = function(value, options) { - util.destroy(ret, err) - }) - .on('end', () => { - const { ret } = this + var filename + , contentDisposition + ; - ret.push(null) - }) - .on('close', () => { - const { ret } = this + if (typeof options.filepath === 'string') { + // custom filepath for relative paths + filename = path.normalize(options.filepath).replace(/\\/g, '/'); + } else if (options.filename || value.name || value.path) { + // custom filename take precedence + // formidable and the browser add a name property + // fs- and request- streams have path property + filename = path.basename(options.filename || value.name || value.path); + } else if (value.readable && value.hasOwnProperty('httpVersion')) { + // or try http response + filename = path.basename(value.client._httpMessage.path || ''); + } - if (!ret._readableState.ended) { - util.destroy(ret, new RequestAbortedError()) - } - }) + if (filename) { + contentDisposition = 'filename="' + filename + '"'; + } - this.body = body + return contentDisposition; +}; + +FormData.prototype._getContentType = function(value, options) { + + // use custom content-type above all + var contentType = options.contentType; + + // or try `name` from formidable, browser + if (!contentType && value.name) { + contentType = mime.lookup(value.name); } - onData (chunk) { - const { res } = this - return res.push(chunk) + // or try `path` from fs-, request- streams + if (!contentType && value.path) { + contentType = mime.lookup(value.path); } - onComplete (trailers) { - const { res } = this - res.push(null) + // or if it's http-reponse + if (!contentType && value.readable && value.hasOwnProperty('httpVersion')) { + contentType = value.headers['content-type']; } - onError (err) { - const { ret } = this - this.handler = null - util.destroy(ret, err) + // or guess it from the filepath or filename + if (!contentType && (options.filepath || options.filename)) { + contentType = mime.lookup(options.filepath || options.filename); } -} -function pipeline (opts, handler) { - try { - const pipelineHandler = new PipelineHandler(opts, handler) - this.dispatch({ ...opts, body: pipelineHandler.req }, pipelineHandler) - return pipelineHandler.ret - } catch (err) { - return new PassThrough().destroy(err) + // fallback to the default content type if `value` is not simple value + if (!contentType && typeof value == 'object') { + contentType = FormData.DEFAULT_CONTENT_TYPE; } -} - -module.exports = pipeline + return contentType; +}; -/***/ }), +FormData.prototype._multiPartFooter = function() { + return function(next) { + var footer = FormData.LINE_BREAK; -/***/ 5448: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var lastPart = (this._streams.length === 0); + if (lastPart) { + footer += this._lastBoundary(); + } -"use strict"; + next(footer); + }.bind(this); +}; +FormData.prototype._lastBoundary = function() { + return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK; +}; -const Readable = __nccwpck_require__(3858) -const { - InvalidArgumentError, - RequestAbortedError -} = __nccwpck_require__(8045) -const util = __nccwpck_require__(3983) -const { getResolveErrorBodyCallback } = __nccwpck_require__(7474) -const { AsyncResource } = __nccwpck_require__(852) -const { addSignal, removeSignal } = __nccwpck_require__(7032) +FormData.prototype.getHeaders = function(userHeaders) { + var header; + var formHeaders = { + 'content-type': 'multipart/form-data; boundary=' + this.getBoundary() + }; -class RequestHandler extends AsyncResource { - constructor (opts, callback) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') + for (header in userHeaders) { + if (userHeaders.hasOwnProperty(header)) { + formHeaders[header.toLowerCase()] = userHeaders[header]; } + } - const { signal, method, opaque, body, onInfo, responseHeaders, throwOnError, highWaterMark } = opts + return formHeaders; +}; - try { - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } +FormData.prototype.setBoundary = function(boundary) { + this._boundary = boundary; +}; - if (highWaterMark && (typeof highWaterMark !== 'number' || highWaterMark < 0)) { - throw new InvalidArgumentError('invalid highWaterMark') - } +FormData.prototype.getBoundary = function() { + if (!this._boundary) { + this._generateBoundary(); + } - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') - } + return this._boundary; +}; - if (method === 'CONNECT') { - throw new InvalidArgumentError('invalid method') - } +FormData.prototype.getBuffer = function() { + var dataBuffer = new Buffer.alloc( 0 ); + var boundary = this.getBoundary(); - if (onInfo && typeof onInfo !== 'function') { - throw new InvalidArgumentError('invalid onInfo callback') - } + // Create the form content. Add Line breaks to the end of data. + for (var i = 0, len = this._streams.length; i < len; i++) { + if (typeof this._streams[i] !== 'function') { - super('UNDICI_REQUEST') - } catch (err) { - if (util.isStream(body)) { - util.destroy(body.on('error', util.nop), err) + // Add content to the buffer. + if(Buffer.isBuffer(this._streams[i])) { + dataBuffer = Buffer.concat( [dataBuffer, this._streams[i]]); + }else { + dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(this._streams[i])]); } - throw err - } - - this.responseHeaders = responseHeaders || null - this.opaque = opaque || null - this.callback = callback - this.res = null - this.abort = null - this.body = body - this.trailers = {} - this.context = null - this.onInfo = onInfo || null - this.throwOnError = throwOnError - this.highWaterMark = highWaterMark - if (util.isStream(body)) { - body.on('error', (err) => { - this.onError(err) - }) + // Add break after content. + if (typeof this._streams[i] !== 'string' || this._streams[i].substring( 2, boundary.length + 2 ) !== boundary) { + dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(FormData.LINE_BREAK)] ); + } } - - addSignal(this, signal) } - onConnect (abort, context) { - if (!this.callback) { - throw new RequestAbortedError() - } + // Add the footer and return the Buffer object. + return Buffer.concat( [dataBuffer, Buffer.from(this._lastBoundary())] ); +}; - this.abort = abort - this.context = context +FormData.prototype._generateBoundary = function() { + // This generates a 50 character boundary similar to those used by Firefox. + // They are optimized for boyer-moore parsing. + var boundary = '--------------------------'; + for (var i = 0; i < 24; i++) { + boundary += Math.floor(Math.random() * 10).toString(16); } - onHeaders (statusCode, rawHeaders, resume, statusMessage) { - const { callback, opaque, abort, context, responseHeaders, highWaterMark } = this - - const headers = responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) - - if (statusCode < 200) { - if (this.onInfo) { - this.onInfo({ statusCode, headers }) - } - return - } + this._boundary = boundary; +}; - const parsedHeaders = responseHeaders === 'raw' ? util.parseHeaders(rawHeaders) : headers - const contentType = parsedHeaders['content-type'] - const body = new Readable({ resume, abort, contentType, highWaterMark }) +// Note: getLengthSync DOESN'T calculate streams length +// As workaround one can calculate file size manually +// and add it as knownLength option +FormData.prototype.getLengthSync = function() { + var knownLength = this._overheadLength + this._valueLength; - this.callback = null - this.res = body - if (callback !== null) { - if (this.throwOnError && statusCode >= 400) { - this.runInAsyncScope(getResolveErrorBodyCallback, null, - { callback, body, contentType, statusCode, statusMessage, headers } - ) - } else { - this.runInAsyncScope(callback, null, null, { - statusCode, - headers, - trailers: this.trailers, - opaque, - body, - context - }) - } - } + // Don't get confused, there are 3 "internal" streams for each keyval pair + // so it basically checks if there is any value added to the form + if (this._streams.length) { + knownLength += this._lastBoundary().length; } - onData (chunk) { - const { res } = this - return res.push(chunk) + // https://github.com/form-data/form-data/issues/40 + if (!this.hasKnownLength()) { + // Some async length retrievers are present + // therefore synchronous length calculation is false. + // Please use getLength(callback) to get proper length + this._error(new Error('Cannot calculate proper length in synchronous way.')); } - onComplete (trailers) { - const { res } = this - - removeSignal(this) + return knownLength; +}; - util.parseHeaders(trailers, this.trailers) +// Public API to check if length of added values is known +// https://github.com/form-data/form-data/issues/196 +// https://github.com/form-data/form-data/issues/262 +FormData.prototype.hasKnownLength = function() { + var hasKnownLength = true; - res.push(null) + if (this._valuesToMeasure.length) { + hasKnownLength = false; } - onError (err) { - const { res, callback, body, opaque } = this - - removeSignal(this) - - if (callback) { - // TODO: Does this need queueMicrotask? - this.callback = null - queueMicrotask(() => { - this.runInAsyncScope(callback, null, err, { opaque }) - }) - } + return hasKnownLength; +}; - if (res) { - this.res = null - // Ensure all queued handlers are invoked before destroying res. - queueMicrotask(() => { - util.destroy(res, err) - }) - } +FormData.prototype.getLength = function(cb) { + var knownLength = this._overheadLength + this._valueLength; - if (body) { - this.body = null - util.destroy(body, err) - } + if (this._streams.length) { + knownLength += this._lastBoundary().length; } -} -function request (opts, callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - request.call(this, opts, (err, data) => { - return err ? reject(err) : resolve(data) - }) - }) + if (!this._valuesToMeasure.length) { + process.nextTick(cb.bind(this, null, knownLength)); + return; } - try { - this.dispatch(opts, new RequestHandler(opts, callback)) - } catch (err) { - if (typeof callback !== 'function') { - throw err - } - const opaque = opts && opts.opaque - queueMicrotask(() => callback(err, { opaque })) - } -} - -module.exports = request -module.exports.RequestHandler = RequestHandler + asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function(err, values) { + if (err) { + cb(err); + return; + } + values.forEach(function(length) { + knownLength += length; + }); -/***/ }), + cb(null, knownLength); + }); +}; -/***/ 5395: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +FormData.prototype.submit = function(params, cb) { + var request + , options + , defaults = {method: 'post'} + ; -"use strict"; + // parse provided url if it's string + // or treat it as options object + if (typeof params == 'string') { + params = parseUrl(params); + options = populate({ + port: params.port, + path: params.pathname, + host: params.hostname, + protocol: params.protocol + }, defaults); -const { finished, PassThrough } = __nccwpck_require__(2781) -const { - InvalidArgumentError, - InvalidReturnValueError, - RequestAbortedError -} = __nccwpck_require__(8045) -const util = __nccwpck_require__(3983) -const { getResolveErrorBodyCallback } = __nccwpck_require__(7474) -const { AsyncResource } = __nccwpck_require__(852) -const { addSignal, removeSignal } = __nccwpck_require__(7032) + // use custom params + } else { -class StreamHandler extends AsyncResource { - constructor (opts, factory, callback) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') + options = populate(params, defaults); + // if no port provided use default one + if (!options.port) { + options.port = options.protocol == 'https:' ? 443 : 80; } + } - const { signal, method, opaque, body, onInfo, responseHeaders, throwOnError } = opts + // put that good code in getHeaders to some use + options.headers = this.getHeaders(params.headers); - try { - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } + // https if specified, fallback to http in any other case + if (options.protocol == 'https:') { + request = https.request(options); + } else { + request = http.request(options); + } - if (typeof factory !== 'function') { - throw new InvalidArgumentError('invalid factory') - } + // get content length and fire away + this.getLength(function(err, length) { + if (err && err !== 'Unknown stream') { + this._error(err); + return; + } - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') - } + // add content length + if (length) { + request.setHeader('Content-Length', length); + } - if (method === 'CONNECT') { - throw new InvalidArgumentError('invalid method') - } + this.pipe(request); + if (cb) { + var onResponse; - if (onInfo && typeof onInfo !== 'function') { - throw new InvalidArgumentError('invalid onInfo callback') - } + var callback = function (error, responce) { + request.removeListener('error', callback); + request.removeListener('response', onResponse); - super('UNDICI_STREAM') - } catch (err) { - if (util.isStream(body)) { - util.destroy(body.on('error', util.nop), err) - } - throw err - } + return cb.call(this, error, responce); + }; - this.responseHeaders = responseHeaders || null - this.opaque = opaque || null - this.factory = factory - this.callback = callback - this.res = null - this.abort = null - this.context = null - this.trailers = null - this.body = body - this.onInfo = onInfo || null - this.throwOnError = throwOnError || false + onResponse = callback.bind(this, null); - if (util.isStream(body)) { - body.on('error', (err) => { - this.onError(err) - }) + request.on('error', callback); + request.on('response', onResponse); } + }.bind(this)); - addSignal(this, signal) - } - - onConnect (abort, context) { - if (!this.callback) { - throw new RequestAbortedError() - } + return request; +}; - this.abort = abort - this.context = context +FormData.prototype._error = function(err) { + if (!this.error) { + this.error = err; + this.pause(); + this.emit('error', err); } +}; - onHeaders (statusCode, rawHeaders, resume, statusMessage) { - const { factory, opaque, context, callback, responseHeaders } = this - - const headers = responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) +FormData.prototype.toString = function () { + return '[object FormData]'; +}; - if (statusCode < 200) { - if (this.onInfo) { - this.onInfo({ statusCode, headers }) - } - return - } - this.factory = null +/***/ }), - let res +/***/ 7142: +/***/ ((module) => { - if (this.throwOnError && statusCode >= 400) { - const parsedHeaders = responseHeaders === 'raw' ? util.parseHeaders(rawHeaders) : headers - const contentType = parsedHeaders['content-type'] - res = new PassThrough() +// populates missing values +module.exports = function(dst, src) { - this.callback = null - this.runInAsyncScope(getResolveErrorBodyCallback, null, - { callback, body: res, contentType, statusCode, statusMessage, headers } - ) - } else { - if (factory === null) { - return - } + Object.keys(src).forEach(function(prop) + { + dst[prop] = dst[prop] || src[prop]; + }); - res = this.runInAsyncScope(factory, null, { - statusCode, - headers, - opaque, - context - }) + return dst; +}; - if ( - !res || - typeof res.write !== 'function' || - typeof res.end !== 'function' || - typeof res.on !== 'function' - ) { - throw new InvalidReturnValueError('expected Writable') - } - // TODO: Avoid finished. It registers an unnecessary amount of listeners. - finished(res, { readable: false }, (err) => { - const { callback, res, opaque, trailers, abort } = this +/***/ }), - this.res = null - if (err || !res.readable) { - util.destroy(res, err) - } +/***/ 4274: +/***/ (function(module, __unused_webpack_exports, __nccwpck_require__) { - this.callback = null - this.runInAsyncScope(callback, null, err || null, { opaque, trailers }) +/*! For license information please see mailgun.node.js.LICENSE.txt */ +!function(e,t){ true?module.exports=t():0}(this,(()=>(()=>{var e={9118:(e,t,n)=>{e.exports={parallel:n(9162),serial:n(1357),serialOrdered:n(9087)}},7651:e=>{function t(e){"function"==typeof this.jobs[e]&&this.jobs[e]()}e.exports=function(e){Object.keys(e.jobs).forEach(t.bind(e)),e.jobs={}}},5912:(e,t,n)=>{var a=n(9265);e.exports=function(e){var t=!1;return a((function(){t=!0})),function(n,i){t?e(n,i):a((function(){e(n,i)}))}}},9265:e=>{e.exports=function(e){var t="function"==typeof setImmediate?setImmediate:"object"==typeof process&&"function"==typeof process.nextTick?process.nextTick:null;t?t(e):setTimeout(e,0)}},7594:(e,t,n)=>{var a=n(5912),i=n(7651);e.exports=function(e,t,n,o){var s=n.keyedList?n.keyedList[n.index]:n.index;n.jobs[s]=function(e,t,n,i){var o;o=2==e.length?e(n,a(i)):e(n,t,a(i));return o}(t,s,e[s],(function(e,t){s in n.jobs&&(delete n.jobs[s],e?i(n):n.results[s]=t,o(e,n.results))}))}},4528:e=>{e.exports=function(e,t){var n=!Array.isArray(e),a={index:0,keyedList:n||t?Object.keys(e):null,jobs:{},results:n?{}:[],size:n?Object.keys(e).length:e.length};t&&a.keyedList.sort(n?t:function(n,a){return t(e[n],e[a])});return a}},5353:(e,t,n)=>{var a=n(7651),i=n(5912);e.exports=function(e){if(!Object.keys(this.jobs).length)return;this.index=this.size,a(this),i(e)(null,this.results)}},9162:(e,t,n)=>{var a=n(7594),i=n(4528),o=n(5353);e.exports=function(e,t,n){var s=i(e);for(;s.index<(s.keyedList||e).length;)a(e,t,s,(function(e,t){e?n(e,t):0!==Object.keys(s.jobs).length||n(null,s.results)})),s.index++;return o.bind(s,n)}},1357:(e,t,n)=>{var a=n(9087);e.exports=function(e,t,n){return a(e,t,null,n)}},9087:(e,t,n)=>{var a=n(7594),i=n(4528),o=n(5353);function s(e,t){return et?1:0}e.exports=function(e,t,n,s){var r=i(e,n);return a(e,t,r,(function n(i,o){i?s(i,o):(r.index++,r.index<(r.keyedList||e).length?a(e,t,r,n):s(null,r.results))})),o.bind(r,s)},e.exports.ascending=s,e.exports.descending=function(e,t){return-1*s(e,t)}},4106:(e,t,n)=>{var a=n(9779),i=n(3837),o=n(1017),s=n(3685),r=n(5687),c=n(7310).parse,p=n(7147),u=n(2781).Stream,l=n(983),d=n(9118),m=n(5469);function f(e){if(!(this instanceof f))return new f(e);for(var t in this._overheadLength=0,this._valueLength=0,this._valuesToMeasure=[],a.call(this),e=e||{})this[t]=e[t]}e.exports=f,i.inherits(f,a),f.LINE_BREAK="\r\n",f.DEFAULT_CONTENT_TYPE="application/octet-stream",f.prototype.append=function(e,t,n){"string"==typeof(n=n||{})&&(n={filename:n});var o=a.prototype.append.bind(this);if("number"==typeof t&&(t=""+t),i.isArray(t))this._error(new Error("Arrays are not supported."));else{var s=this._multiPartHeader(e,t,n),r=this._multiPartFooter();o(s),o(t),o(r),this._trackLength(s,t,n)}},f.prototype._trackLength=function(e,t,n){var a=0;null!=n.knownLength?a+=+n.knownLength:Buffer.isBuffer(t)?a=t.length:"string"==typeof t&&(a=Buffer.byteLength(t)),this._valueLength+=a,this._overheadLength+=Buffer.byteLength(e)+f.LINE_BREAK.length,t&&(t.path||t.readable&&t.hasOwnProperty("httpVersion")||t instanceof u)&&(n.knownLength||this._valuesToMeasure.push(t))},f.prototype._lengthRetriever=function(e,t){e.hasOwnProperty("fd")?null!=e.end&&e.end!=1/0&&null!=e.start?t(null,e.end+1-(e.start?e.start:0)):p.stat(e.path,(function(n,a){var i;n?t(n):(i=a.size-(e.start?e.start:0),t(null,i))})):e.hasOwnProperty("httpVersion")?t(null,+e.headers["content-length"]):e.hasOwnProperty("httpModule")?(e.on("response",(function(n){e.pause(),t(null,+n.headers["content-length"])})),e.resume()):t("Unknown stream")},f.prototype._multiPartHeader=function(e,t,n){if("string"==typeof n.header)return n.header;var a,i=this._getContentDisposition(t,n),o=this._getContentType(t,n),s="",r={"Content-Disposition":["form-data",'name="'+e+'"'].concat(i||[]),"Content-Type":[].concat(o||[])};for(var c in"object"==typeof n.header&&m(r,n.header),r)r.hasOwnProperty(c)&&null!=(a=r[c])&&(Array.isArray(a)||(a=[a]),a.length&&(s+=c+": "+a.join("; ")+f.LINE_BREAK));return"--"+this.getBoundary()+f.LINE_BREAK+s+f.LINE_BREAK},f.prototype._getContentDisposition=function(e,t){var n,a;return"string"==typeof t.filepath?n=o.normalize(t.filepath).replace(/\\/g,"/"):t.filename||e.name||e.path?n=o.basename(t.filename||e.name||e.path):e.readable&&e.hasOwnProperty("httpVersion")&&(n=o.basename(e.client._httpMessage.path||"")),n&&(a='filename="'+n+'"'),a},f.prototype._getContentType=function(e,t){var n=t.contentType;return!n&&e.name&&(n=l.lookup(e.name)),!n&&e.path&&(n=l.lookup(e.path)),!n&&e.readable&&e.hasOwnProperty("httpVersion")&&(n=e.headers["content-type"]),n||!t.filepath&&!t.filename||(n=l.lookup(t.filepath||t.filename)),n||"object"!=typeof e||(n=f.DEFAULT_CONTENT_TYPE),n},f.prototype._multiPartFooter=function(){return function(e){var t=f.LINE_BREAK;0===this._streams.length&&(t+=this._lastBoundary()),e(t)}.bind(this)},f.prototype._lastBoundary=function(){return"--"+this.getBoundary()+"--"+f.LINE_BREAK},f.prototype.getHeaders=function(e){var t,n={"content-type":"multipart/form-data; boundary="+this.getBoundary()};for(t in e)e.hasOwnProperty(t)&&(n[t.toLowerCase()]=e[t]);return n},f.prototype.setBoundary=function(e){this._boundary=e},f.prototype.getBoundary=function(){return this._boundary||this._generateBoundary(),this._boundary},f.prototype.getBuffer=function(){for(var e=new Buffer.alloc(0),t=this.getBoundary(),n=0,a=this._streams.length;n{e.exports=function(e,t){return Object.keys(t).forEach((function(n){e[n]=e[n]||t[n]})),e}},5205:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(e,t,n){this.name=e.name,this.require_tls=e.require_tls,this.skip_verification=e.skip_verification,this.state=e.state,this.wildcard=e.wildcard,this.spam_action=e.spam_action,this.created_at=e.created_at,this.smtp_password=e.smtp_password,this.smtp_login=e.smtp_login,this.type=e.type,this.receiving_dns_records=t||null,this.sending_dns_records=n||null;var a=["id","is_disabled","web_prefix","web_scheme"].reduce((function(t,n){return n in e&&(t[n]=e[n]),t}),{});Object.assign(this,a)};t.default=n},8127:function(e,t,n){"use strict";var a=this&&this.__assign||function(){return a=Object.assign||function(e){for(var t,n=1,a=arguments.length;n0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(e){this.request=e}return e.prototype.list=function(e){return this.request.get("/v3/routes",e).then((function(e){return e.body.items}))},e.prototype.get=function(e){return this.request.get("/v3/routes/".concat(e)).then((function(e){return e.body.route}))},e.prototype.create=function(e){return this.request.postWithFD("/v3/routes",e).then((function(e){return e.body.route}))},e.prototype.update=function(e,t){return this.request.putWithFD("/v3/routes/".concat(e),t).then((function(e){return e.body}))},e.prototype.destroy=function(e){return this.request.delete("/v3/routes/".concat(e)).then((function(e){return e.body}))},e}();t.default=n},8165:function(e,t,n){"use strict";var a=this&&this.__spreadArray||function(e,t,n){if(n||2===arguments.length)for(var a,i=0,o=t.length;i{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(e){this.request=e}return e.prototype.list=function(e){return this.request.get("/v5/accounts/subaccounts",e).then((function(e){return e.body}))},e.prototype.get=function(e){return this.request.get("/v5/accounts/subaccounts/".concat(e)).then((function(e){return e.body}))},e.prototype.create=function(e){return this.request.postWithFD("/v5/accounts/subaccounts",{name:e}).then((function(e){return e.body}))},e.prototype.enable=function(e){return this.request.post("/v5/accounts/subaccounts/".concat(e,"/enable")).then((function(e){return e.body}))},e.prototype.disable=function(e){return this.request.post("/v5/accounts/subaccounts/".concat(e,"/disable")).then((function(e){return e.body}))},e.SUBACCOUNT_HEADER="X-Mailgun-On-Behalf-Of",e}();t.default=n},7002:function(e,t,n){"use strict";var a,i=this&&this.__extends||(a=function(e,t){return a=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},a(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}a(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var s=n(8089),r=function(e){function t(t){var n=e.call(this,s.SuppressionModels.BOUNCES)||this;return n.address=t.address,n.code=+t.code,n.error=t.error,n.created_at=new Date(t.created_at),n}return i(t,e),t}(o(n(9013)).default);t.default=r},9601:function(e,t,n){"use strict";var a,i=this&&this.__extends||(a=function(e,t){return a=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},a(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}a(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var s=n(8089),r=function(e){function t(t){var n=e.call(this,s.SuppressionModels.COMPLAINTS)||this;return n.address=t.address,n.created_at=new Date(t.created_at),n}return i(t,e),t}(o(n(9013)).default);t.default=r},9013:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(e){this.type=e};t.default=n},1481:function(e,t,n){"use strict";var a,i=this&&this.__extends||(a=function(e,t){return a=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},a(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}a(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),o=this&&this.__awaiter||function(e,t,n,a){return new(n||(n=Promise))((function(i,o){function s(e){try{c(a.next(e))}catch(e){o(e)}}function r(e){try{c(a.throw(e))}catch(e){o(e)}}function c(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,r)}c((a=a.apply(e,t||[])).next())}))},s=this&&this.__generator||function(e,t){var n,a,i,o,s={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:r(0),throw:r(1),return:r(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function r(r){return function(c){return function(r){if(n)throw new TypeError("Generator is already executing.");for(;o&&(o=0,r[0]&&(s=0)),s;)try{if(n=1,a&&(i=2&r[0]?a.return:r[0]?a.throw||((i=a.return)&&i.call(a),0):a.next)&&!(i=i.call(a,r[1])).done)return i;switch(a=0,i&&(r=[2&r[0],i.value]),r[0]){case 0:case 1:i=r;break;case 4:return s.label++,{value:r[1],done:!1};case 5:s.label++,a=r[1],r=[0];continue;case 7:r=s.ops.pop(),s.trys.pop();continue;default:if(!(i=s.trys,(i=i.length>0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&(u.params=new URLSearchParams(r.query),delete u.query),(null==r?void 0:r.body)&&(f=null==r?void 0:r.body,u.data=f,delete u.body),v=(0,l.default)(this.url,t),c.label=1;case 1:return c.trys.push([1,3,,4]),[4,d.default.request(a(a({method:e.toLocaleUpperCase(),timeout:this.timeout,url:v,headers:p},u),{maxBodyLength:this.maxBodyLength,proxy:this.proxy}))];case 2:return h=c.sent(),[3,4];case 3:throw x=c.sent(),b=x,new m.default({status:(null===(i=null==b?void 0:b.response)||void 0===i?void 0:i.status)||400,statusText:(null===(o=null==b?void 0:b.response)||void 0===o?void 0:o.statusText)||b.code,body:(null===(s=null==b?void 0:b.response)||void 0===s?void 0:s.data)||b.message});case 4:return[4,this.getResponseBody(h)];case 5:return[2,c.sent()]}}))}))},e.prototype.getResponseBody=function(e){return r(this,void 0,void 0,(function(){var t;return c(this,(function(n){if(t={body:{},status:null==e?void 0:e.status},"string"==typeof e.data){if("Mailgun Magnificent API"===e.data)throw new m.default({status:400,statusText:"Incorrect url",body:e.data});t.body={message:e.data}}else t.body=e.data;return[2,t]}))}))},e.prototype.joinAndTransformHeaders=function(e){var t=new d.AxiosHeaders,n=u.encode("".concat(this.username,":").concat(this.key));t.setAuthorization("Basic ".concat(n)),t.set(this.headers);var a=e&&e.headers,i=this.makeHeadersFromObject(a);return t.set(i),t},e.prototype.makeHeadersFromObject=function(e){void 0===e&&(e={});var t=new d.AxiosHeaders;return t=Object.entries(e).reduce((function(e,t){var n=t[0],a=t[1];return e.set(n,a),e}),t)},e.prototype.setSubaccountHeader=function(e){var t,n=this.makeHeadersFromObject(a(a({},this.headers),((t={})[h.default.SUBACCOUNT_HEADER]=e,t)));this.headers.set(n)},e.prototype.resetSubaccountHeader=function(){this.headers.delete(h.default.SUBACCOUNT_HEADER)},e.prototype.query=function(e,t,n,i){return this.request(e,t,a({query:n},i))},e.prototype.command=function(e,t,n,i,o){void 0===o&&(o=!0);var s={};o&&(s={"Content-Type":"application/x-www-form-urlencoded"});var r=a(a(a({},s),{body:n}),i);return this.request(e,t,r)},e.prototype.get=function(e,t,n){return this.query("get",e,t,n)},e.prototype.post=function(e,t,n){return this.command("post",e,t,n)},e.prototype.postWithFD=function(e,t){var n=this.formDataBuilder.createFormData(t);return this.command("post",e,n,{headers:{"Content-Type":"multipart/form-data"}},!1)},e.prototype.putWithFD=function(e,t){var n=this.formDataBuilder.createFormData(t);return this.command("put",e,n,{headers:{"Content-Type":"multipart/form-data"}},!1)},e.prototype.patchWithFD=function(e,t){var n=this.formDataBuilder.createFormData(t);return this.command("patch",e,n,{headers:{"Content-Type":"multipart/form-data"}},!1)},e.prototype.put=function(e,t,n){return this.command("put",e,t,n)},e.prototype.delete=function(e,t){return this.command("delete",e,t)},e}();t.default=v},8089:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.YesNo=t.WebhooksIds=t.SuppressionModels=t.Resolution=void 0,function(e){e.HOUR="hour",e.DAY="day",e.MONTH="month"}(t.Resolution||(t.Resolution={})),function(e){e.BOUNCES="bounces",e.COMPLAINTS="complaints",e.UNSUBSCRIBES="unsubscribes",e.WHITELISTS="whitelists"}(t.SuppressionModels||(t.SuppressionModels={})),function(e){e.CLICKED="clicked",e.COMPLAINED="complained",e.DELIVERED="delivered",e.OPENED="opened",e.PERMANENT_FAIL="permanent_fail",e.TEMPORARY_FAIL="temporary_fail",e.UNSUBSCRIBED="unsubscribe"}(t.WebhooksIds||(t.WebhooksIds={})),function(e){e.YES="yes",e.NO="no"}(t.YesNo||(t.YesNo={}))},7471:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},466:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(7471),t)},7647:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},7546:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},1358:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2236:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},9483:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(7647),t),i(n(7546),t),i(n(1358),t),i(n(2236),t)},4251:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},896:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(4251),t)},9798:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},188:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(9798),t)},7677:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2685:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(7677),t)},7913:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},1094:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(7913),t)},3446:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},1225:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2570:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(3446),t),i(n(1225),t)},7104:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},4005:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(7104),t)},6115:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},848:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(6115),t)},4012:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},1574:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},9923:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(4012),t),i(n(1574),t)},3748:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2220:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(3748),t)},5129:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},157:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2818:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},504:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},3740:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2043:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(5129),t),i(n(157),t),i(n(504),t),i(n(3740),t),i(n(2818),t)},6233:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},4826:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},7272:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(6233),t),i(n(4826),t)},1034:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2955:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(1034),t)},799:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(466),t),i(n(9483),t),i(n(1094),t),i(n(2570),t),i(n(9923),t),i(n(2043),t),i(n(7272),t),i(n(896),t),i(n(2955),t),i(n(4005),t),i(n(848),t),i(n(2685),t),i(n(188),t),i(n(2220),t)},4859:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},7843:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2755:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},4994:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},643:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},4886:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(7843),t),i(n(4859),t),i(n(2755),t),i(n(4994),t),i(n(643),t)},8011:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},1409:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},3627:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},970:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2179:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},9543:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(8011),t),i(n(2179),t),i(n(1409),t),i(n(3627),t),i(n(970),t)},8483:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},4385:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(8483),t)},3097:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},720:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(3097),t)},2409:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},5986:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(2409),t)},7666:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},4553:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(7666),t)},5560:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},5810:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},9977:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(5560),t),i(n(5810),t)},9348:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},7313:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(9348),t)},9006:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},5006:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(9006),t)},2144:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},4744:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(2144),t)},9040:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},9700:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(9040),t)},8275:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},5451:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},7935:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},4205:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},4312:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2267:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(8275),t),i(n(5451),t),i(n(7935),t),i(n(4205),t),i(n(4312),t)},4090:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},202:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},7587:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(4090),t),i(n(202),t)},771:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},8042:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(771),t)},8615:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(4886),t),i(n(9543),t),i(n(4385),t),i(n(720),t),i(n(5986),t),i(n(4553),t),i(n(9977),t),i(n(7313),t),i(n(5006),t),i(n(4744),t),i(n(9700),t),i(n(2267),t),i(n(7587),t),i(n(8042),t)},7530:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&a(t,e,n);return i(t,e),t},s=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)},r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.Interfaces=t.Enums=void 0;var c=r(n(5558));t.Enums=o(n(8089)),s(n(8615),t),t.Interfaces=o(n(799));var p=function(){function e(e){this.formData=e}return Object.defineProperty(e,"default",{get:function(){return this},enumerable:!1,configurable:!0}),e.prototype.client=function(e){return new c.default(e,this.formData)},e}();t.default=p},7501:function(e,t,n){var a;e=n.nmd(e),function(i){var o=t,s=(e&&e.exports,"object"==typeof global&&global);s.global!==s&&s.window;var r=function(e){this.message=e};(r.prototype=new Error).name="InvalidCharacterError";var c=function(e){throw new r(e)},p="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",u=/[\t\n\f\r ]/g,l={encode:function(e){e=String(e),/[^\0-\xFF]/.test(e)&&c("The string to be encoded contains characters outside of the Latin1 range.");for(var t,n,a,i,o=e.length%3,s="",r=-1,u=e.length-o;++r>18&63)+p.charAt(i>>12&63)+p.charAt(i>>6&63)+p.charAt(63&i);return 2==o?(t=e.charCodeAt(r)<<8,n=e.charCodeAt(++r),s+=p.charAt((i=t+n)>>10)+p.charAt(i>>4&63)+p.charAt(i<<2&63)+"="):1==o&&(i=e.charCodeAt(r),s+=p.charAt(i>>2)+p.charAt(i<<4&63)+"=="),s},decode:function(e){var t=(e=String(e).replace(u,"")).length;t%4==0&&(t=(e=e.replace(/==?$/,"")).length),(t%4==1||/[^+a-zA-Z0-9/]/.test(e))&&c("Invalid character: the string to be decoded is not correctly encoded.");for(var n,a,i=0,o="",s=-1;++s>(-2*i&6)));return o},version:"1.0.0"};void 0===(a=function(){return l}.call(t,n,t,e))||(e.exports=a)}()},9779:(e,t,n)=>{var a=n(3837),i=n(2781).Stream,o=n(3463);function s(){this.writable=!1,this.readable=!0,this.dataSize=0,this.maxDataSize=2097152,this.pauseStreams=!0,this._released=!1,this._streams=[],this._currentStream=null,this._insideLoop=!1,this._pendingNext=!1}e.exports=s,a.inherits(s,i),s.create=function(e){var t=new this;for(var n in e=e||{})t[n]=e[n];return t},s.isStreamLike=function(e){return"function"!=typeof e&&"string"!=typeof e&&"boolean"!=typeof e&&"number"!=typeof e&&!Buffer.isBuffer(e)},s.prototype.append=function(e){if(s.isStreamLike(e)){if(!(e instanceof o)){var t=o.create(e,{maxDataSize:1/0,pauseStream:this.pauseStreams});e.on("data",this._checkDataSize.bind(this)),e=t}this._handleErrors(e),this.pauseStreams&&e.pause()}return this._streams.push(e),this},s.prototype.pipe=function(e,t){return i.prototype.pipe.call(this,e,t),this.resume(),e},s.prototype._getNext=function(){if(this._currentStream=null,this._insideLoop)this._pendingNext=!0;else{this._insideLoop=!0;try{do{this._pendingNext=!1,this._realGetNext()}while(this._pendingNext)}finally{this._insideLoop=!1}}},s.prototype._realGetNext=function(){var e=this._streams.shift();void 0!==e?"function"==typeof e?e(function(e){s.isStreamLike(e)&&(e.on("data",this._checkDataSize.bind(this)),this._handleErrors(e)),this._pipeNext(e)}.bind(this)):this._pipeNext(e):this.end()},s.prototype._pipeNext=function(e){if(this._currentStream=e,s.isStreamLike(e))return e.on("end",this._getNext.bind(this)),void e.pipe(this,{end:!1});var t=e;this.write(t),this._getNext()},s.prototype._handleErrors=function(e){var t=this;e.on("error",(function(e){t._emitError(e)}))},s.prototype.write=function(e){this.emit("data",e)},s.prototype.pause=function(){this.pauseStreams&&(this.pauseStreams&&this._currentStream&&"function"==typeof this._currentStream.pause&&this._currentStream.pause(),this.emit("pause"))},s.prototype.resume=function(){this._released||(this._released=!0,this.writable=!0,this._getNext()),this.pauseStreams&&this._currentStream&&"function"==typeof this._currentStream.resume&&this._currentStream.resume(),this.emit("resume")},s.prototype.end=function(){this._reset(),this.emit("end")},s.prototype.destroy=function(){this._reset(),this.emit("close")},s.prototype._reset=function(){this.writable=!1,this._streams=[],this._currentStream=null},s.prototype._checkDataSize=function(){if(this._updateDataSize(),!(this.dataSize<=this.maxDataSize)){var e="DelayedStream#maxDataSize of "+this.maxDataSize+" bytes exceeded.";this._emitError(new Error(e))}},s.prototype._updateDataSize=function(){this.dataSize=0;var e=this;this._streams.forEach((function(t){t.dataSize&&(e.dataSize+=t.dataSize)})),this._currentStream&&this._currentStream.dataSize&&(this.dataSize+=this._currentStream.dataSize)},s.prototype._emitError=function(e){this._reset(),this.emit("error",e)}},1227:(e,t,n)=>{t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let a=0,i=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(a++,"%c"===e&&(i=a))})),t.splice(i,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG);return e},t.useColors=function(){if("undefined"!=typeof window&&window.process&&("renderer"===window.process.type||window.process.__nwjs))return!0;if("undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))return!1;return"undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=n(2447)(t);const{formatters:a}=e.exports;a.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}},2447:(e,t,n)=>{e.exports=function(e){function t(e){let n,i,o,s=null;function r(...e){if(!r.enabled)return;const a=r,i=Number(new Date),o=i-(n||i);a.diff=o,a.prev=n,a.curr=i,n=i,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let s=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((n,i)=>{if("%%"===n)return"%";s++;const o=t.formatters[i];if("function"==typeof o){const t=e[s];n=o.call(a,t),e.splice(s,1),s--}return n})),t.formatArgs.call(a,e);(a.log||t.log).apply(a,e)}return r.namespace=e,r.useColors=t.useColors(),r.color=t.selectColor(e),r.extend=a,r.destroy=t.destroy,Object.defineProperty(r,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==s?s:(i!==t.namespaces&&(i=t.namespaces,o=t.enabled(e)),o),set:e=>{s=e}}),"function"==typeof t.init&&t.init(r),r}function a(e,n){const a=t(this.namespace+(void 0===n?":":n)+e);return a.log=this.log,a}function i(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(i),...t.skips.map(i).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const a=("string"==typeof e?e:"").split(/[\s,]+/),i=a.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?e.exports=n(1227):e.exports=n(39)},39:(e,t,n)=>{const a=n(6224),i=n(3837);t.init=function(e){e.inspectOpts={};const n=Object.keys(t.inspectOpts);for(let a=0;a{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=n(2130);e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let a=process.env[t];return a=!!/^(yes|on|true|enabled)$/i.test(a)||!/^(no|off|false|disabled)$/i.test(a)&&("null"===a?null:Number(a)),e[n]=a,e}),{}),e.exports=n(2447)(t);const{formatters:o}=e.exports;o.o=function(e){return this.inspectOpts.colors=this.useColors,i.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},o.O=function(e){return this.inspectOpts.colors=this.useColors,i.inspect(e,this.inspectOpts)}},3463:(e,t,n)=>{var a=n(2781).Stream,i=n(3837);function o(){this.source=null,this.dataSize=0,this.maxDataSize=1048576,this.pauseStream=!0,this._maxDataSizeExceeded=!1,this._released=!1,this._bufferedEvents=[]}e.exports=o,i.inherits(o,a),o.create=function(e,t){var n=new this;for(var a in t=t||{})n[a]=t[a];n.source=e;var i=e.emit;return e.emit=function(){return n._handleEmit(arguments),i.apply(e,arguments)},e.on("error",(function(){})),n.pauseStream&&e.pause(),n},Object.defineProperty(o.prototype,"readable",{configurable:!0,enumerable:!0,get:function(){return this.source.readable}}),o.prototype.setEncoding=function(){return this.source.setEncoding.apply(this.source,arguments)},o.prototype.resume=function(){this._released||this.release(),this.source.resume()},o.prototype.pause=function(){this.source.pause()},o.prototype.release=function(){this._released=!0,this._bufferedEvents.forEach(function(e){this.emit.apply(this,e)}.bind(this)),this._bufferedEvents=[]},o.prototype.pipe=function(){var e=a.prototype.pipe.apply(this,arguments);return this.resume(),e},o.prototype._handleEmit=function(e){this._released?this.emit.apply(this,e):("data"===e[0]&&(this.dataSize+=e[1].length,this._checkIfMaxDataSizeExceeded()),this._bufferedEvents.push(e))},o.prototype._checkIfMaxDataSizeExceeded=function(){if(!(this._maxDataSizeExceeded||this.dataSize<=this.maxDataSize)){this._maxDataSizeExceeded=!0;var e="DelayedStream#maxDataSize of "+this.maxDataSize+" bytes exceeded.";this.emit("error",new Error(e))}}},2261:(e,t,n)=>{var a;e.exports=function(){if(!a){try{a=n(5158)("follow-redirects")}catch(e){}"function"!=typeof a&&(a=function(){})}a.apply(null,arguments)}},938:(e,t,n)=>{var a=n(7310),i=a.URL,o=n(3685),s=n(5687),r=n(2781).Writable,c=n(9491),p=n(2261),u=!1;try{c(new i)}catch(e){u="ERR_INVALID_URL"===e.code}var l=["auth","host","hostname","href","path","pathname","port","protocol","query","search","hash"],d=["abort","aborted","connect","error","socket","timeout"],m=Object.create(null);d.forEach((function(e){m[e]=function(t,n,a){this._redirectable.emit(e,t,n,a)}}));var f=R("ERR_INVALID_URL","Invalid URL",TypeError),h=R("ERR_FR_REDIRECTION_FAILURE","Redirected request failed"),v=R("ERR_FR_TOO_MANY_REDIRECTS","Maximum number of redirects exceeded",h),x=R("ERR_FR_MAX_BODY_LENGTH_EXCEEDED","Request body larger than maxBodyLength limit"),b=R("ERR_STREAM_WRITE_AFTER_END","write after end"),g=r.prototype.destroy||w;function y(e,t){r.call(this),this._sanitizeOptions(e),this._options=e,this._ended=!1,this._ending=!1,this._redirectCount=0,this._redirects=[],this._requestBodyLength=0,this._requestBodyBuffers=[],t&&this.on("response",t);var n=this;this._onNativeResponse=function(e){try{n._processResponse(e)}catch(e){n.emit("error",e instanceof h?e:new h({cause:e}))}},this._performRequest()}function _(e){var t={maxRedirects:21,maxBodyLength:10485760},n={};return Object.keys(e).forEach((function(a){var o=a+":",s=n[o]=e[a],r=t[a]=Object.create(s);Object.defineProperties(r,{request:{value:function(e,a,s){var r;return r=e,i&&r instanceof i?e=k(e):E(e)?e=k(j(e)):(s=a,a=O(e),e={protocol:o}),C(a)&&(s=a,a=null),(a=Object.assign({maxRedirects:t.maxRedirects,maxBodyLength:t.maxBodyLength},e,a)).nativeProtocols=n,E(a.host)||E(a.hostname)||(a.hostname="::1"),c.equal(a.protocol,o,"protocol mismatch"),p("options",a),new y(a,s)},configurable:!0,enumerable:!0,writable:!0},get:{value:function(e,t,n){var a=r.request(e,t,n);return a.end(),a},configurable:!0,enumerable:!0,writable:!0}})})),t}function w(){}function j(e){var t;if(u)t=new i(e);else if(!E((t=O(a.parse(e))).protocol))throw new f({input:e});return t}function O(e){if(/^\[/.test(e.hostname)&&!/^\[[:0-9a-f]+\]$/i.test(e.hostname))throw new f({input:e.href||e});if(/^\[/.test(e.host)&&!/^\[[:0-9a-f]+\](:\d+)?$/i.test(e.host))throw new f({input:e.href||e});return e}function k(e,t){var n=t||{};for(var a of l)n[a]=e[a];return n.hostname.startsWith("[")&&(n.hostname=n.hostname.slice(1,-1)),""!==n.port&&(n.port=Number(n.port)),n.path=n.search?n.pathname+n.search:n.pathname,n}function P(e,t){var n;for(var a in t)e.test(a)&&(n=t[a],delete t[a]);return null==n?void 0:String(n).trim()}function R(e,t,n){function a(n){Error.captureStackTrace(this,this.constructor),Object.assign(this,n||{}),this.code=e,this.message=this.cause?t+": "+this.cause.message:t}return a.prototype=new(n||Error),Object.defineProperties(a.prototype,{constructor:{value:a,enumerable:!1},name:{value:"Error ["+e+"]",enumerable:!1}}),a}function S(e,t){for(var n of d)e.removeListener(n,m[n]);e.on("error",w),e.destroy(t)}function E(e){return"string"==typeof e||e instanceof String}function C(e){return"function"==typeof e}y.prototype=Object.create(r.prototype),y.prototype.abort=function(){S(this._currentRequest),this._currentRequest.abort(),this.emit("abort")},y.prototype.destroy=function(e){return S(this._currentRequest,e),g.call(this,e),this},y.prototype.write=function(e,t,n){if(this._ending)throw new b;if(!E(e)&&("object"!=typeof(a=e)||!("length"in a)))throw new TypeError("data should be a string, Buffer or Uint8Array");var a;C(t)&&(n=t,t=null),0!==e.length?this._requestBodyLength+e.length<=this._options.maxBodyLength?(this._requestBodyLength+=e.length,this._requestBodyBuffers.push({data:e,encoding:t}),this._currentRequest.write(e,t,n)):(this.emit("error",new x),this.abort()):n&&n()},y.prototype.end=function(e,t,n){if(C(e)?(n=e,e=t=null):C(t)&&(n=t,t=null),e){var a=this,i=this._currentRequest;this.write(e,t,(function(){a._ended=!0,i.end(null,null,n)})),this._ending=!0}else this._ended=this._ending=!0,this._currentRequest.end(null,null,n)},y.prototype.setHeader=function(e,t){this._options.headers[e]=t,this._currentRequest.setHeader(e,t)},y.prototype.removeHeader=function(e){delete this._options.headers[e],this._currentRequest.removeHeader(e)},y.prototype.setTimeout=function(e,t){var n=this;function a(t){t.setTimeout(e),t.removeListener("timeout",t.destroy),t.addListener("timeout",t.destroy)}function i(t){n._timeout&&clearTimeout(n._timeout),n._timeout=setTimeout((function(){n.emit("timeout"),o()}),e),a(t)}function o(){n._timeout&&(clearTimeout(n._timeout),n._timeout=null),n.removeListener("abort",o),n.removeListener("error",o),n.removeListener("response",o),n.removeListener("close",o),t&&n.removeListener("timeout",t),n.socket||n._currentRequest.removeListener("socket",i)}return t&&this.on("timeout",t),this.socket?i(this.socket):this._currentRequest.once("socket",i),this.on("socket",a),this.on("abort",o),this.on("error",o),this.on("response",o),this.on("close",o),this},["flushHeaders","getHeader","setNoDelay","setSocketKeepAlive"].forEach((function(e){y.prototype[e]=function(t,n){return this._currentRequest[e](t,n)}})),["aborted","connection","socket"].forEach((function(e){Object.defineProperty(y.prototype,e,{get:function(){return this._currentRequest[e]}})})),y.prototype._sanitizeOptions=function(e){if(e.headers||(e.headers={}),e.host&&(e.hostname||(e.hostname=e.host),delete e.host),!e.pathname&&e.path){var t=e.path.indexOf("?");t<0?e.pathname=e.path:(e.pathname=e.path.substring(0,t),e.search=e.path.substring(t))}},y.prototype._performRequest=function(){var e=this._options.protocol,t=this._options.nativeProtocols[e];if(!t)throw new TypeError("Unsupported protocol "+e);if(this._options.agents){var n=e.slice(0,-1);this._options.agent=this._options.agents[n]}var i=this._currentRequest=t.request(this._options,this._onNativeResponse);for(var o of(i._redirectable=this,d))i.on(o,m[o]);if(this._currentUrl=/^\//.test(this._options.path)?a.format(this._options):this._options.path,this._isRedirect){var s=0,r=this,c=this._requestBodyBuffers;!function e(t){if(i===r._currentRequest)if(t)r.emit("error",t);else if(s=400)return e.responseUrl=this._currentUrl,e.redirects=this._redirects,this.emit("response",e),void(this._requestBodyBuffers=[]);if(S(this._currentRequest),e.destroy(),++this._redirectCount>this._options.maxRedirects)throw new v;var s=this._options.beforeRedirect;s&&(n=Object.assign({Host:e.req.getHeader("host")},this._options.headers));var r=this._options.method;((301===t||302===t)&&"POST"===this._options.method||303===t&&!/^(?:GET|HEAD)$/.test(this._options.method))&&(this._options.method="GET",this._requestBodyBuffers=[],P(/^content-/i,this._options.headers));var l,d,m=P(/^host$/i,this._options.headers),f=j(this._currentUrl),h=m||f.host,x=/^\w+:/.test(o)?this._currentUrl:a.format(Object.assign(f,{host:h})),b=(l=o,d=x,u?new i(l,d):j(a.resolve(d,l)));if(p("redirecting to",b.href),this._isRedirect=!0,k(b,this._options),(b.protocol!==f.protocol&&"https:"!==b.protocol||b.host!==h&&!function(e,t){c(E(e)&&E(t));var n=e.length-t.length-1;return n>0&&"."===e[n]&&e.endsWith(t)}(b.host,h))&&P(/^(?:authorization|cookie)$/i,this._options.headers),C(s)){var g={headers:e.headers,statusCode:t},y={url:x,method:r,headers:n};s(this._options,g,y),this._sanitizeOptions(this._options)}this._performRequest()},e.exports=_({http:o,https:s}),e.exports.wrap=_},6560:e=>{"use strict";e.exports=(e,t)=>{t=t||process.argv;const n=e.startsWith("-")?"":1===e.length?"-":"--",a=t.indexOf(n+e),i=t.indexOf("--");return-1!==a&&(-1===i||a{e.exports=n(3765)},983:(e,t,n)=>{"use strict";var a,i,o,s=n(5234),r=n(1017).extname,c=/^\s*([^;\s]*)(?:;|\s|$)/,p=/^text\//i;function u(e){if(!e||"string"!=typeof e)return!1;var t=c.exec(e),n=t&&s[t[1].toLowerCase()];return n&&n.charset?n.charset:!(!t||!p.test(t[1]))&&"UTF-8"}t.charset=u,t.charsets={lookup:u},t.contentType=function(e){if(!e||"string"!=typeof e)return!1;var n=-1===e.indexOf("/")?t.lookup(e):e;if(!n)return!1;if(-1===n.indexOf("charset")){var a=t.charset(n);a&&(n+="; charset="+a.toLowerCase())}return n},t.extension=function(e){if(!e||"string"!=typeof e)return!1;var n=c.exec(e),a=n&&t.extensions[n[1].toLowerCase()];if(!a||!a.length)return!1;return a[0]},t.extensions=Object.create(null),t.lookup=function(e){if(!e||"string"!=typeof e)return!1;var n=r("x."+e).toLowerCase().substr(1);if(!n)return!1;return t.types[n]||!1},t.types=Object.create(null),a=t.extensions,i=t.types,o=["nginx","apache",void 0,"iana"],Object.keys(s).forEach((function(e){var t=s[e],n=t.extensions;if(n&&n.length){a[e]=n;for(var r=0;ru||p===u&&"application/"===i[c].substr(0,12)))continue}i[c]=e}}}))},7824:e=>{var t=1e3,n=60*t,a=60*n,i=24*a,o=7*i,s=365.25*i;function r(e,t,n,a){var i=t>=1.5*n;return Math.round(e/n)+" "+a+(i?"s":"")}e.exports=function(e,c){c=c||{};var p=typeof e;if("string"===p&&e.length>0)return function(e){if((e=String(e)).length>100)return;var r=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(e);if(!r)return;var c=parseFloat(r[1]);switch((r[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*s;case"weeks":case"week":case"w":return c*o;case"days":case"day":case"d":return c*i;case"hours":case"hour":case"hrs":case"hr":case"h":return c*a;case"minutes":case"minute":case"mins":case"min":case"m":return c*n;case"seconds":case"second":case"secs":case"sec":case"s":return c*t;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(e);if("number"===p&&isFinite(e))return c.long?function(e){var o=Math.abs(e);if(o>=i)return r(e,o,i,"day");if(o>=a)return r(e,o,a,"hour");if(o>=n)return r(e,o,n,"minute");if(o>=t)return r(e,o,t,"second");return e+" ms"}(e):function(e){var o=Math.abs(e);if(o>=i)return Math.round(e/i)+"d";if(o>=a)return Math.round(e/a)+"h";if(o>=n)return Math.round(e/n)+"m";if(o>=t)return Math.round(e/t)+"s";return e+"ms"}(e);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(e))}},1394:(e,t,n)=>{"use strict";var a=n(7310).parse,i={ftp:21,gopher:70,http:80,https:443,ws:80,wss:443},o=String.prototype.endsWith||function(e){return e.length<=this.length&&-1!==this.indexOf(e,this.length-e.length)};function s(e){return process.env[e.toLowerCase()]||process.env[e.toUpperCase()]||""}t.getProxyForUrl=function(e){var t="string"==typeof e?a(e):e||{},n=t.protocol,r=t.host,c=t.port;if("string"!=typeof r||!r||"string"!=typeof n)return"";if(n=n.split(":",1)[0],!function(e,t){var n=(s("npm_config_no_proxy")||s("no_proxy")).toLowerCase();if(!n)return!0;if("*"===n)return!1;return n.split(/[,\s]/).every((function(n){if(!n)return!0;var a=n.match(/^(.+):(\d+)$/),i=a?a[1]:n,s=a?parseInt(a[2]):0;return!(!s||s===t)||(/^[.*]/.test(i)?("*"===i.charAt(0)&&(i=i.slice(1)),!o.call(e,i)):e!==i)}))}(r=r.replace(/:\d*$/,""),c=parseInt(c)||i[n]||0))return"";var p=s("npm_config_"+n+"_proxy")||s(n+"_proxy")||s("npm_config_proxy")||s("all_proxy");return p&&-1===p.indexOf("://")&&(p=n+"://"+p),p}},2130:(e,t,n)=>{"use strict";const a=n(2037),i=n(6560),o=process.env;let s;function r(e){const t=function(e){if(!1===s)return 0;if(i("color=16m")||i("color=full")||i("color=truecolor"))return 3;if(i("color=256"))return 2;if(e&&!e.isTTY&&!0!==s)return 0;const t=s?1:0;if("win32"===process.platform){const e=a.release().split(".");return Number(process.versions.node.split(".")[0])>=8&&Number(e[0])>=10&&Number(e[2])>=10586?Number(e[2])>=14931?3:2:1}if("CI"in o)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI"].some((e=>e in o))||"codeship"===o.CI_NAME?1:t;if("TEAMCITY_VERSION"in o)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(o.TEAMCITY_VERSION)?1:0;if("truecolor"===o.COLORTERM)return 3;if("TERM_PROGRAM"in o){const e=parseInt((o.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(o.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(o.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(o.TERM)||"COLORTERM"in o?1:(o.TERM,t)}(e);return function(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}(t)}i("no-color")||i("no-colors")||i("color=false")?s=!1:(i("color")||i("colors")||i("color=true")||i("color=always"))&&(s=!0),"FORCE_COLOR"in o&&(s=0===o.FORCE_COLOR.length||0!==parseInt(o.FORCE_COLOR,10)),e.exports={supportsColor:r,stdout:r(process.stdout),stderr:r(process.stderr)}},4078:function(e,t,n){var a,i,o;o=function(){function e(e){var t=[];if(0===e.length)return"";if("string"!=typeof e[0])throw new TypeError("Url must be a string. Received "+e[0]);if(e[0].match(/^[^/:]+:\/*$/)&&e.length>1){var n=e.shift();e[0]=n+e[0]}e[0].match(/^file:\/\/\//)?e[0]=e[0].replace(/^([^/:]+):\/*/,"$1:///"):e[0]=e[0].replace(/^([^/:]+):\/*/,"$1://");for(var a=0;a0&&(i=i.replace(/^[\/]+/,"")),i=a0?"?":"")+s.join("&")}return function(){return e("object"==typeof arguments[0]?arguments[0]:[].slice.call(arguments))}},e.exports?e.exports=o():void 0===(i="function"==typeof(a=o)?a.call(t,n,t,e):a)||(e.exports=i)},9491:e=>{"use strict";e.exports=__nccwpck_require__(9491)},2361:e=>{"use strict";e.exports=__nccwpck_require__(2361)},7147:e=>{"use strict";e.exports=__nccwpck_require__(7147)},3685:e=>{"use strict";e.exports=__nccwpck_require__(3685)},5687:e=>{"use strict";e.exports=__nccwpck_require__(5687)},2037:e=>{"use strict";e.exports=__nccwpck_require__(2037)},1017:e=>{"use strict";e.exports=__nccwpck_require__(1017)},2781:e=>{"use strict";e.exports=__nccwpck_require__(2781)},6224:e=>{"use strict";e.exports=__nccwpck_require__(6224)},7310:e=>{"use strict";e.exports=__nccwpck_require__(7310)},3837:e=>{"use strict";e.exports=__nccwpck_require__(3837)},9796:e=>{"use strict";e.exports=__nccwpck_require__(9796)},3306:(e,t,n)=>{"use strict";const a=n(4106),i=n(7310),o=n(1394),s=n(3685),r=n(5687),c=n(3837),p=n(938),u=n(9796),l=n(2781),d=n(2361);function m(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}const f=m(a),h=m(i),v=m(s),x=m(r),b=m(c),g=m(p),y=m(u),_=m(l),w=m(d);function j(e,t){return function(){return e.apply(t,arguments)}}const{toString:O}=Object.prototype,{getPrototypeOf:k}=Object,P=(R=Object.create(null),e=>{const t=O.call(e);return R[t]||(R[t]=t.slice(8,-1).toLowerCase())});var R;const S=e=>(e=e.toLowerCase(),t=>P(t)===e),E=e=>t=>typeof t===e,{isArray:C}=Array,T=E("undefined");const q=S("ArrayBuffer");const A=E("string"),D=E("function"),M=E("number"),F=e=>null!==e&&"object"==typeof e,L=e=>{if("object"!==P(e))return!1;const t=k(e);return!(null!==t&&t!==Object.prototype&&null!==Object.getPrototypeOf(t)||Symbol.toStringTag in e||Symbol.iterator in e)},B=S("Date"),z=S("File"),U=S("Blob"),N=S("FileList"),I=S("URLSearchParams");function W(e,t,{allOwnKeys:n=!1}={}){if(null==e)return;let a,i;if("object"!=typeof e&&(e=[e]),C(e))for(a=0,i=e.length;a0;)if(a=n[i],t===a.toLowerCase())return a;return null}const V="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:global,$=e=>!T(e)&&e!==V;const G=(J="undefined"!=typeof Uint8Array&&k(Uint8Array),e=>J&&e instanceof J);var J;const K=S("HTMLFormElement"),Y=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),Q=S("RegExp"),Z=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),a={};W(n,((n,i)=>{let o;!1!==(o=t(n,i,e))&&(a[i]=o||n)})),Object.defineProperties(e,a)},X="abcdefghijklmnopqrstuvwxyz",ee="0123456789",te={DIGIT:ee,ALPHA:X,ALPHA_DIGIT:X+X.toUpperCase()+ee};const ne=S("AsyncFunction"),ae={isArray:C,isArrayBuffer:q,isBuffer:function(e){return null!==e&&!T(e)&&null!==e.constructor&&!T(e.constructor)&&D(e.constructor.isBuffer)&&e.constructor.isBuffer(e)},isFormData:e=>{let t;return e&&("function"==typeof FormData&&e instanceof FormData||D(e.append)&&("formdata"===(t=P(e))||"object"===t&&D(e.toString)&&"[object FormData]"===e.toString()))},isArrayBufferView:function(e){let t;return t="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&q(e.buffer),t},isString:A,isNumber:M,isBoolean:e=>!0===e||!1===e,isObject:F,isPlainObject:L,isUndefined:T,isDate:B,isFile:z,isBlob:U,isRegExp:Q,isFunction:D,isStream:e=>F(e)&&D(e.pipe),isURLSearchParams:I,isTypedArray:G,isFileList:N,forEach:W,merge:function e(){const{caseless:t}=$(this)&&this||{},n={},a=(a,i)=>{const o=t&&H(n,i)||i;L(n[o])&&L(a)?n[o]=e(n[o],a):L(a)?n[o]=e({},a):C(a)?n[o]=a.slice():n[o]=a};for(let e=0,t=arguments.length;e(W(t,((t,a)=>{n&&D(t)?e[a]=j(t,n):e[a]=t}),{allOwnKeys:a}),e),trim:e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),stripBOM:e=>(65279===e.charCodeAt(0)&&(e=e.slice(1)),e),inherits:(e,t,n,a)=>{e.prototype=Object.create(t.prototype,a),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),n&&Object.assign(e.prototype,n)},toFlatObject:(e,t,n,a)=>{let i,o,s;const r={};if(t=t||{},null==e)return t;do{for(i=Object.getOwnPropertyNames(e),o=i.length;o-- >0;)s=i[o],a&&!a(s,e,t)||r[s]||(t[s]=e[s],r[s]=!0);e=!1!==n&&k(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},kindOf:P,kindOfTest:S,endsWith:(e,t,n)=>{e=String(e),(void 0===n||n>e.length)&&(n=e.length),n-=t.length;const a=e.indexOf(t,n);return-1!==a&&a===n},toArray:e=>{if(!e)return null;if(C(e))return e;let t=e.length;if(!M(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},forEachEntry:(e,t)=>{const n=(e&&e[Symbol.iterator]).call(e);let a;for(;(a=n.next())&&!a.done;){const n=a.value;t.call(e,n[0],n[1])}},matchAll:(e,t)=>{let n;const a=[];for(;null!==(n=e.exec(t));)a.push(n);return a},isHTMLForm:K,hasOwnProperty:Y,hasOwnProp:Y,reduceDescriptors:Z,freezeMethods:e=>{Z(e,((t,n)=>{if(D(e)&&-1!==["arguments","caller","callee"].indexOf(n))return!1;const a=e[n];D(a)&&(t.enumerable=!1,"writable"in t?t.writable=!1:t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")}))}))},toObjectSet:(e,t)=>{const n={},a=e=>{e.forEach((e=>{n[e]=!0}))};return C(e)?a(e):a(String(e).split(t)),n},toCamelCase:e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,(function(e,t,n){return t.toUpperCase()+n})),noop:()=>{},toFiniteNumber:(e,t)=>(e=+e,Number.isFinite(e)?e:t),findKey:H,global:V,isContextDefined:$,ALPHABET:te,generateString:(e=16,t=te.ALPHA_DIGIT)=>{let n="";const{length:a}=t;for(;e--;)n+=t[Math.random()*a|0];return n},isSpecCompliantForm:function(e){return!!(e&&D(e.append)&&"FormData"===e[Symbol.toStringTag]&&e[Symbol.iterator])},toJSONObject:e=>{const t=new Array(10),n=(e,a)=>{if(F(e)){if(t.indexOf(e)>=0)return;if(!("toJSON"in e)){t[a]=e;const i=C(e)?[]:{};return W(e,((e,t)=>{const o=n(e,a+1);!T(o)&&(i[t]=o)})),t[a]=void 0,i}}return e};return n(e,0)},isAsyncFn:ne,isThenable:e=>e&&(F(e)||D(e))&&D(e.then)&&D(e.catch)};function ie(e,t,n,a,i){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack,this.message=e,this.name="AxiosError",t&&(this.code=t),n&&(this.config=n),a&&(this.request=a),i&&(this.response=i)}ae.inherits(ie,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:ae.toJSONObject(this.config),code:this.code,status:this.response&&this.response.status?this.response.status:null}}});const oe=ie.prototype,se={};function re(e){return ae.isPlainObject(e)||ae.isArray(e)}function ce(e){return ae.endsWith(e,"[]")?e.slice(0,-2):e}function pe(e,t,n){return e?e.concat(t).map((function(e,t){return e=ce(e),!n&&t?"["+e+"]":e})).join(n?".":""):t}["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach((e=>{se[e]={value:e}})),Object.defineProperties(ie,se),Object.defineProperty(oe,"isAxiosError",{value:!0}),ie.from=(e,t,n,a,i,o)=>{const s=Object.create(oe);return ae.toFlatObject(e,s,(function(e){return e!==Error.prototype}),(e=>"isAxiosError"!==e)),ie.call(s,e.message,t,n,a,i),s.cause=e,s.name=e.name,o&&Object.assign(s,o),s};const ue=ae.toFlatObject(ae,{},null,(function(e){return/^is[A-Z]/.test(e)}));function le(e,t,n){if(!ae.isObject(e))throw new TypeError("target must be an object");t=t||new(f.default||FormData);const a=(n=ae.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,(function(e,t){return!ae.isUndefined(t[e])}))).metaTokens,i=n.visitor||p,o=n.dots,s=n.indexes,r=(n.Blob||"undefined"!=typeof Blob&&Blob)&&ae.isSpecCompliantForm(t);if(!ae.isFunction(i))throw new TypeError("visitor must be a function");function c(e){if(null===e)return"";if(ae.isDate(e))return e.toISOString();if(!r&&ae.isBlob(e))throw new ie("Blob is not supported. Use a Buffer instead.");return ae.isArrayBuffer(e)||ae.isTypedArray(e)?r&&"function"==typeof Blob?new Blob([e]):Buffer.from(e):e}function p(e,n,i){let r=e;if(e&&!i&&"object"==typeof e)if(ae.endsWith(n,"{}"))n=a?n:n.slice(0,-2),e=JSON.stringify(e);else if(ae.isArray(e)&&function(e){return ae.isArray(e)&&!e.some(re)}(e)||(ae.isFileList(e)||ae.endsWith(n,"[]"))&&(r=ae.toArray(e)))return n=ce(n),r.forEach((function(e,a){!ae.isUndefined(e)&&null!==e&&t.append(!0===s?pe([n],a,o):null===s?n:n+"[]",c(e))})),!1;return!!re(e)||(t.append(pe(i,n,o),c(e)),!1)}const u=[],l=Object.assign(ue,{defaultVisitor:p,convertValue:c,isVisitable:re});if(!ae.isObject(e))throw new TypeError("data must be an object");return function e(n,a){if(!ae.isUndefined(n)){if(-1!==u.indexOf(n))throw Error("Circular reference detected in "+a.join("."));u.push(n),ae.forEach(n,(function(n,o){!0===(!(ae.isUndefined(n)||null===n)&&i.call(t,n,ae.isString(o)?o.trim():o,a,l))&&e(n,a?a.concat(o):[o])})),u.pop()}}(e),t}function de(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,(function(e){return t[e]}))}function me(e,t){this._pairs=[],e&&le(e,this,t)}const fe=me.prototype;function he(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}function ve(e,t,n){if(!t)return e;const a=n&&n.encode||he,i=n&&n.serialize;let o;if(o=i?i(t,n):ae.isURLSearchParams(t)?t.toString():new me(t,n).toString(a),o){const t=e.indexOf("#");-1!==t&&(e=e.slice(0,t)),e+=(-1===e.indexOf("?")?"?":"&")+o}return e}fe.append=function(e,t){this._pairs.push([e,t])},fe.toString=function(e){const t=e?function(t){return e.call(this,t,de)}:de;return this._pairs.map((function(e){return t(e[0])+"="+t(e[1])}),"").join("&")};const xe=class InterceptorManager{constructor(){this.handlers=[]}use(e,t,n){return this.handlers.push({fulfilled:e,rejected:t,synchronous:!!n&&n.synchronous,runWhen:n?n.runWhen:null}),this.handlers.length-1}eject(e){this.handlers[e]&&(this.handlers[e]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(e){ae.forEach(this.handlers,(function(t){null!==t&&e(t)}))}},be={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},ge={isNode:!0,classes:{URLSearchParams:h.default.URLSearchParams,FormData:f.default,Blob:"undefined"!=typeof Blob&&Blob||null},protocols:["http","https","file","data"]};function ye(e){function t(e,n,a,i){let o=e[i++];const s=Number.isFinite(+o),r=i>=e.length;if(o=!o&&ae.isArray(a)?a.length:o,r)return ae.hasOwnProp(a,o)?a[o]=[a[o],n]:a[o]=n,!s;a[o]&&ae.isObject(a[o])||(a[o]=[]);return t(e,n,a[o],i)&&ae.isArray(a[o])&&(a[o]=function(e){const t={},n=Object.keys(e);let a;const i=n.length;let o;for(a=0;a{t(function(e){return ae.matchAll(/\w+|\[(\w*)]/g,e).map((e=>"[]"===e[0]?"":e[1]||e[0]))}(e),a,n,0)})),n}return null}const _e={transitional:be,adapter:["xhr","http"],transformRequest:[function(e,t){const n=t.getContentType()||"",a=n.indexOf("application/json")>-1,i=ae.isObject(e);i&&ae.isHTMLForm(e)&&(e=new FormData(e));if(ae.isFormData(e))return a&&a?JSON.stringify(ye(e)):e;if(ae.isArrayBuffer(e)||ae.isBuffer(e)||ae.isStream(e)||ae.isFile(e)||ae.isBlob(e))return e;if(ae.isArrayBufferView(e))return e.buffer;if(ae.isURLSearchParams(e))return t.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),e.toString();let o;if(i){if(n.indexOf("application/x-www-form-urlencoded")>-1)return function(e,t){return le(e,new ge.classes.URLSearchParams,Object.assign({visitor:function(e,t,n,a){return ae.isBuffer(e)?(this.append(t,e.toString("base64")),!1):a.defaultVisitor.apply(this,arguments)}},t))}(e,this.formSerializer).toString();if((o=ae.isFileList(e))||n.indexOf("multipart/form-data")>-1){const t=this.env&&this.env.FormData;return le(o?{"files[]":e}:e,t&&new t,this.formSerializer)}}return i||a?(t.setContentType("application/json",!1),function(e,t,n){if(ae.isString(e))try{return(t||JSON.parse)(e),ae.trim(e)}catch(e){if("SyntaxError"!==e.name)throw e}return(n||JSON.stringify)(e)}(e)):e}],transformResponse:[function(e){const t=this.transitional||_e.transitional,n=t&&t.forcedJSONParsing,a="json"===this.responseType;if(e&&ae.isString(e)&&(n&&!this.responseType||a)){const n=!(t&&t.silentJSONParsing)&&a;try{return JSON.parse(e)}catch(e){if(n){if("SyntaxError"===e.name)throw ie.from(e,ie.ERR_BAD_RESPONSE,this,null,this.response);throw e}}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:ge.classes.FormData,Blob:ge.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};ae.forEach(["delete","get","head","post","put","patch"],(e=>{_e.headers[e]={}}));const we=_e,je=ae.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),Oe=Symbol("internals");function ke(e){return e&&String(e).trim().toLowerCase()}function Pe(e){return!1===e||null==e?e:ae.isArray(e)?e.map(Pe):String(e)}function Re(e,t,n,a,i){return ae.isFunction(a)?a.call(this,t,n):(i&&(t=n),ae.isString(t)?ae.isString(a)?-1!==t.indexOf(a):ae.isRegExp(a)?a.test(t):void 0:void 0)}class AxiosHeaders{constructor(e){e&&this.set(e)}set(e,t,n){const a=this;function i(e,t,n){const i=ke(t);if(!i)throw new Error("header name must be a non-empty string");const o=ae.findKey(a,i);(!o||void 0===a[o]||!0===n||void 0===n&&!1!==a[o])&&(a[o||t]=Pe(e))}const o=(e,t)=>ae.forEach(e,((e,n)=>i(e,n,t)));return ae.isPlainObject(e)||e instanceof this.constructor?o(e,t):ae.isString(e)&&(e=e.trim())&&!/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim())?o((e=>{const t={};let n,a,i;return e&&e.split("\n").forEach((function(e){i=e.indexOf(":"),n=e.substring(0,i).trim().toLowerCase(),a=e.substring(i+1).trim(),!n||t[n]&&je[n]||("set-cookie"===n?t[n]?t[n].push(a):t[n]=[a]:t[n]=t[n]?t[n]+", "+a:a)})),t})(e),t):null!=e&&i(t,e,n),this}get(e,t){if(e=ke(e)){const n=ae.findKey(this,e);if(n){const e=this[n];if(!t)return e;if(!0===t)return function(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let a;for(;a=n.exec(e);)t[a[1]]=a[2];return t}(e);if(ae.isFunction(t))return t.call(this,e,n);if(ae.isRegExp(t))return t.exec(e);throw new TypeError("parser must be boolean|regexp|function")}}}has(e,t){if(e=ke(e)){const n=ae.findKey(this,e);return!(!n||void 0===this[n]||t&&!Re(0,this[n],n,t))}return!1}delete(e,t){const n=this;let a=!1;function i(e){if(e=ke(e)){const i=ae.findKey(n,e);!i||t&&!Re(0,n[i],i,t)||(delete n[i],a=!0)}}return ae.isArray(e)?e.forEach(i):i(e),a}clear(e){const t=Object.keys(this);let n=t.length,a=!1;for(;n--;){const i=t[n];e&&!Re(0,this[i],i,e,!0)||(delete this[i],a=!0)}return a}normalize(e){const t=this,n={};return ae.forEach(this,((a,i)=>{const o=ae.findKey(n,i);if(o)return t[o]=Pe(a),void delete t[i];const s=e?function(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,((e,t,n)=>t.toUpperCase()+n))}(i):String(i).trim();s!==i&&delete t[i],t[s]=Pe(a),n[s]=!0})),this}concat(...e){return this.constructor.concat(this,...e)}toJSON(e){const t=Object.create(null);return ae.forEach(this,((n,a)=>{null!=n&&!1!==n&&(t[a]=e&&ae.isArray(n)?n.join(", "):n)})),t}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map((([e,t])=>e+": "+t)).join("\n")}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(e){return e instanceof this?e:new this(e)}static concat(e,...t){const n=new this(e);return t.forEach((e=>n.set(e))),n}static accessor(e){const t=(this[Oe]=this[Oe]={accessors:{}}).accessors,n=this.prototype;function a(e){const a=ke(e);t[a]||(!function(e,t){const n=ae.toCamelCase(" "+t);["get","set","has"].forEach((a=>{Object.defineProperty(e,a+n,{value:function(e,n,i){return this[a].call(this,t,e,n,i)},configurable:!0})}))}(n,e),t[a]=!0)}return ae.isArray(e)?e.forEach(a):a(e),this}}AxiosHeaders.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),ae.reduceDescriptors(AxiosHeaders.prototype,(({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(e){this[n]=e}}})),ae.freezeMethods(AxiosHeaders);const Se=AxiosHeaders;function Ee(e,t){const n=this||we,a=t||n,i=Se.from(a.headers);let o=a.data;return ae.forEach(e,(function(e){o=e.call(n,o,i.normalize(),t?t.status:void 0)})),i.normalize(),o}function Ce(e){return!(!e||!e.__CANCEL__)}function Te(e,t,n){ie.call(this,null==e?"canceled":e,ie.ERR_CANCELED,t,n),this.name="CanceledError"}function qe(e,t,n){const a=n.config.validateStatus;n.status&&a&&!a(n.status)?t(new ie("Request failed with status code "+n.status,[ie.ERR_BAD_REQUEST,ie.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n)):e(n)}function Ae(e,t){return e&&!function(e){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(e)}(t)?function(e,t){return t?e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):e}(e,t):t}ae.inherits(Te,ie,{__CANCEL__:!0});const De="1.6.0";function Me(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}const Fe=/^(?:([^;]+);)?(?:[^;]+;)?(base64|),([\s\S]*)$/;function Le(e,t){e=e||10;const n=new Array(e),a=new Array(e);let i,o=0,s=0;return t=void 0!==t?t:1e3,function(r){const c=Date.now(),p=a[s];i||(i=c),n[o]=r,a[o]=c;let u=s,l=0;for(;u!==o;)l+=n[u++],u%=e;if(o=(o+1)%e,o===s&&(s=(s+1)%e),c-i!ae.isUndefined(t[e])))).chunkSize});const t=this,n=this[Be]={length:e.length,timeWindow:e.timeWindow,ticksRate:e.ticksRate,chunkSize:e.chunkSize,maxRate:e.maxRate,minChunkSize:e.minChunkSize,bytesSeen:0,isCaptured:!1,notifiedBytesLoaded:0,ts:Date.now(),bytes:0,onReadCallback:null},a=Le(n.ticksRate*e.samplesCount,n.timeWindow);this.on("newListener",(e=>{"progress"===e&&(n.isCaptured||(n.isCaptured=!0))}));let i=0;n.updateProgress=function(e,t){let n=0;const a=1e3/t;let i=null;return function(t,o){const s=Date.now();if(t||s-n>a)return i&&(clearTimeout(i),i=null),n=s,e.apply(null,o);i||(i=setTimeout((()=>(i=null,n=Date.now(),e.apply(null,o))),a-(s-n)))}}((function(){const e=n.length,o=n.bytesSeen,s=o-i;if(!s||t.destroyed)return;const r=a(s);i=o,process.nextTick((()=>{t.emit("progress",{loaded:o,total:e,progress:e?o/e:void 0,bytes:s,rate:r||void 0,estimated:r&&e&&o<=e?(e-o)/r:void 0})}))}),n.ticksRate);const o=()=>{n.updateProgress(!0)};this.once("end",o),this.once("error",o)}_read(e){const t=this[Be];return t.onReadCallback&&t.onReadCallback(),super._read(e)}_transform(e,t,n){const a=this,i=this[Be],o=i.maxRate,s=this.readableHighWaterMark,r=i.timeWindow,c=o/(1e3/r),p=!1!==i.minChunkSize?Math.max(i.minChunkSize,.01*c):0;const u=(e,t)=>{const n=Buffer.byteLength(e);let u,l=null,d=s,m=0;if(o){const e=Date.now();(!i.ts||(m=e-i.ts)>=r)&&(i.ts=e,u=c-i.bytes,i.bytes=u<0?-u:0,m=0),u=c-i.bytes}if(o){if(u<=0)return setTimeout((()=>{t(null,e)}),r-m);ud&&n-d>p&&(l=e.subarray(d),e=e.subarray(0,d)),function(e,t){const n=Buffer.byteLength(e);i.bytesSeen+=n,i.bytes+=n,i.isCaptured&&i.updateProgress(),a.push(e)?process.nextTick(t):i.onReadCallback=()=>{i.onReadCallback=null,process.nextTick(t)}}(e,l?()=>{process.nextTick(t,null,l)}:t)};u(e,(function e(t,a){if(t)return n(t);a?u(a,e):n(null)}))}setLength(e){return this[Be].length=+e,this}}const ze=AxiosTransformStream,{asyncIterator:Ue}=Symbol,Ne=async function*(e){e.stream?yield*e.stream():e.arrayBuffer?yield await e.arrayBuffer():e[Ue]?yield*e[Ue]():yield e},Ie=ae.ALPHABET.ALPHA_DIGIT+"-_",We=new c.TextEncoder,He="\r\n",Ve=We.encode(He);class FormDataPart{constructor(e,t){const{escapeName:n}=this.constructor,a=ae.isString(t);let i=`Content-Disposition: form-data; name="${n(e)}"${!a&&t.name?`; filename="${n(t.name)}"`:""}\r\n`;a?t=We.encode(String(t).replace(/\r?\n|\r\n?/g,He)):i+=`Content-Type: ${t.type||"application/octet-stream"}\r\n`,this.headers=We.encode(i+He),this.contentLength=a?t.byteLength:t.size,this.size=this.headers.byteLength+this.contentLength+2,this.name=e,this.value=t}async*encode(){yield this.headers;const{value:e}=this;ae.isTypedArray(e)?yield e:yield*Ne(e),yield Ve}static escapeName(e){return String(e).replace(/[\r\n"]/g,(e=>({"\r":"%0D","\n":"%0A",'"':"%22"}[e])))}}const $e=(e,t,n)=>{const{tag:a="form-data-boundary",size:i=25,boundary:o=a+"-"+ae.generateString(i,Ie)}=n||{};if(!ae.isFormData(e))throw TypeError("FormData instance required");if(o.length<1||o.length>70)throw Error("boundary must be 10-70 characters long");const s=We.encode("--"+o+He),r=We.encode("--"+o+"--"+He+He);let c=r.byteLength;const p=Array.from(e.entries()).map((([e,t])=>{const n=new FormDataPart(e,t);return c+=n.size,n}));c+=s.byteLength*p.length,c=ae.toFiniteNumber(c);const u={"Content-Type":`multipart/form-data; boundary=${o}`};return Number.isFinite(c)&&(u["Content-Length"]=c),t&&t(u),l.Readable.from(async function*(){for(const e of p)yield s,yield*e.encode();yield r}())};class ZlibHeaderTransformStream extends _.default.Transform{__transform(e,t,n){this.push(e),n()}_transform(e,t,n){if(0!==e.length&&(this._transform=this.__transform,120!==e[0])){const e=Buffer.alloc(2);e[0]=120,e[1]=156,this.push(e,t)}this.__transform(e,t,n)}}const Ge=ZlibHeaderTransformStream,Je=(e,t)=>ae.isAsyncFn(e)?function(...n){const a=n.pop();e.apply(this,n).then((e=>{try{t?a(null,...t(e)):a(null,e)}catch(e){a(e)}}),a)}:e,Ke={flush:y.default.constants.Z_SYNC_FLUSH,finishFlush:y.default.constants.Z_SYNC_FLUSH},Ye={flush:y.default.constants.BROTLI_OPERATION_FLUSH,finishFlush:y.default.constants.BROTLI_OPERATION_FLUSH},Qe=ae.isFunction(y.default.createBrotliDecompress),{http:Ze,https:Xe}=g.default,et=/https:?/,tt=ge.protocols.map((e=>e+":"));function nt(e){e.beforeRedirects.proxy&&e.beforeRedirects.proxy(e),e.beforeRedirects.config&&e.beforeRedirects.config(e)}function at(e,t,n){let a=t;if(!a&&!1!==a){const e=o.getProxyForUrl(n);e&&(a=new URL(e))}if(a){if(a.username&&(a.auth=(a.username||"")+":"+(a.password||"")),a.auth){(a.auth.username||a.auth.password)&&(a.auth=(a.auth.username||"")+":"+(a.auth.password||""));const t=Buffer.from(a.auth,"utf8").toString("base64");e.headers["Proxy-Authorization"]="Basic "+t}e.headers.host=e.hostname+(e.port?":"+e.port:"");const t=a.hostname||a.host;e.hostname=t,e.host=t,e.port=a.port,e.path=n,a.protocol&&(e.protocol=a.protocol.includes(":")?a.protocol:`${a.protocol}:`)}e.beforeRedirects.proxy=function(e){at(e,t,e.href)}}const it="undefined"!=typeof process&&"process"===ae.kindOf(process),ot=(e,t)=>(({address:e,family:t})=>{if(!ae.isString(e))throw TypeError("address must be a string");return{address:e,family:t||(e.indexOf(".")<0?6:4)}})(ae.isObject(e)?e:{address:e,family:t}),st=it&&function(e){return t=async function(t,n,a){let{data:i,lookup:o,family:s}=e;const{responseType:r,responseEncoding:c}=e,p=e.method.toUpperCase();let u,l,d=!1;if(o){const e=Je(o,(e=>ae.isArray(e)?e:[e]));o=(t,n,a)=>{e(t,n,((e,t,i)=>{const o=ae.isArray(t)?t.map((e=>ot(e))):[ot(t,i)];n.all?a(e,o):a(e,o[0].address,o[0].family)}))}}const m=new w.default,f=()=>{e.cancelToken&&e.cancelToken.unsubscribe(h),e.signal&&e.signal.removeEventListener("abort",h),m.removeAllListeners()};function h(t){m.emit("abort",!t||t.type?new Te(null,e,l):t)}a(((e,t)=>{u=!0,t&&(d=!0,f())})),m.once("abort",n),(e.cancelToken||e.signal)&&(e.cancelToken&&e.cancelToken.subscribe(h),e.signal&&(e.signal.aborted?h():e.signal.addEventListener("abort",h)));const g=Ae(e.baseURL,e.url),j=new URL(g,"http://localhost"),O=j.protocol||tt[0];if("data:"===O){let a;if("GET"!==p)return qe(t,n,{status:405,statusText:"method not allowed",headers:{},config:e});try{a=function(e,t,n){const a=n&&n.Blob||ge.classes.Blob,i=Me(e);if(void 0===t&&a&&(t=!0),"data"===i){e=i.length?e.slice(i.length+1):e;const n=Fe.exec(e);if(!n)throw new ie("Invalid URL",ie.ERR_INVALID_URL);const o=n[1],s=n[2],r=n[3],c=Buffer.from(decodeURIComponent(r),s?"base64":"utf8");if(t){if(!a)throw new ie("Blob is not supported",ie.ERR_NOT_SUPPORT);return new a([c],{type:o})}return c}throw new ie("Unsupported protocol "+i,ie.ERR_NOT_SUPPORT)}(e.url,"blob"===r,{Blob:e.env&&e.env.Blob})}catch(t){throw ie.from(t,ie.ERR_BAD_REQUEST,e)}return"text"===r?(a=a.toString(c),c&&"utf8"!==c||(a=ae.stripBOM(a))):"stream"===r&&(a=_.default.Readable.from(a)),qe(t,n,{data:a,status:200,statusText:"OK",headers:new Se,config:e})}if(-1===tt.indexOf(O))return n(new ie("Unsupported protocol "+O,ie.ERR_BAD_REQUEST,e));const k=Se.from(e.headers).normalize();k.set("User-Agent","axios/1.6.0",!1);const P=e.onDownloadProgress,R=e.onUploadProgress,S=e.maxRate;let E,C;if(ae.isSpecCompliantForm(i)){const e=k.getContentType(/boundary=([-_\w\d]{10,70})/i);i=$e(i,(e=>{k.set(e)}),{tag:"axios-1.6.0-boundary",boundary:e&&e[1]||void 0})}else if(ae.isFormData(i)&&ae.isFunction(i.getHeaders)){if(k.set(i.getHeaders()),!k.hasContentLength())try{const e=await b.default.promisify(i.getLength).call(i);Number.isFinite(e)&&e>=0&&k.setContentLength(e)}catch(e){}}else if(ae.isBlob(i))i.size&&k.setContentType(i.type||"application/octet-stream"),k.setContentLength(i.size||0),i=_.default.Readable.from(Ne(i));else if(i&&!ae.isStream(i)){if(Buffer.isBuffer(i));else if(ae.isArrayBuffer(i))i=Buffer.from(new Uint8Array(i));else{if(!ae.isString(i))return n(new ie("Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream",ie.ERR_BAD_REQUEST,e));i=Buffer.from(i,"utf-8")}if(k.setContentLength(i.length,!1),e.maxBodyLength>-1&&i.length>e.maxBodyLength)return n(new ie("Request body larger than maxBodyLength limit",ie.ERR_BAD_REQUEST,e))}const T=ae.toFiniteNumber(k.getContentLength());let q,A;ae.isArray(S)?(E=S[0],C=S[1]):E=C=S,i&&(R||E)&&(ae.isStream(i)||(i=_.default.Readable.from(i,{objectMode:!1})),i=_.default.pipeline([i,new ze({length:T,maxRate:ae.toFiniteNumber(E)})],ae.noop),R&&i.on("progress",(e=>{R(Object.assign(e,{upload:!0}))}))),e.auth&&(q=(e.auth.username||"")+":"+(e.auth.password||"")),!q&&j.username&&(q=j.username+":"+j.password),q&&k.delete("authorization");try{A=ve(j.pathname+j.search,e.params,e.paramsSerializer).replace(/^\?/,"")}catch(t){const a=new Error(t.message);return a.config=e,a.url=e.url,a.exists=!0,n(a)}k.set("Accept-Encoding","gzip, compress, deflate"+(Qe?", br":""),!1);const D={path:A,method:p,headers:k.toJSON(),agents:{http:e.httpAgent,https:e.httpsAgent},auth:q,protocol:O,family:s,beforeRedirect:nt,beforeRedirects:{}};let M;!ae.isUndefined(o)&&(D.lookup=o),e.socketPath?D.socketPath=e.socketPath:(D.hostname=j.hostname,D.port=j.port,at(D,e.proxy,O+"//"+j.hostname+(j.port?":"+j.port:"")+D.path));const F=et.test(D.protocol);if(D.agent=F?e.httpsAgent:e.httpAgent,e.transport?M=e.transport:0===e.maxRedirects?M=F?x.default:v.default:(e.maxRedirects&&(D.maxRedirects=e.maxRedirects),e.beforeRedirect&&(D.beforeRedirects.config=e.beforeRedirect),M=F?Xe:Ze),e.maxBodyLength>-1?D.maxBodyLength=e.maxBodyLength:D.maxBodyLength=1/0,e.insecureHTTPParser&&(D.insecureHTTPParser=e.insecureHTTPParser),l=M.request(D,(function(a){if(l.destroyed)return;const i=[a],o=+a.headers["content-length"];if(P){const e=new ze({length:ae.toFiniteNumber(o),maxRate:ae.toFiniteNumber(C)});P&&e.on("progress",(e=>{P(Object.assign(e,{download:!0}))})),i.push(e)}let s=a;const u=a.req||l;if(!1!==e.decompress&&a.headers["content-encoding"])switch("HEAD"!==p&&204!==a.statusCode||delete a.headers["content-encoding"],(a.headers["content-encoding"]||"").toLowerCase()){case"gzip":case"x-gzip":case"compress":case"x-compress":i.push(y.default.createUnzip(Ke)),delete a.headers["content-encoding"];break;case"deflate":i.push(new Ge),i.push(y.default.createUnzip(Ke)),delete a.headers["content-encoding"];break;case"br":Qe&&(i.push(y.default.createBrotliDecompress(Ye)),delete a.headers["content-encoding"])}s=i.length>1?_.default.pipeline(i,ae.noop):i[0];const h=_.default.finished(s,(()=>{h(),f()})),v={status:a.statusCode,statusText:a.statusMessage,headers:new Se(a.headers),config:e,request:u};if("stream"===r)v.data=s,qe(t,n,v);else{const a=[];let i=0;s.on("data",(function(t){a.push(t),i+=t.length,e.maxContentLength>-1&&i>e.maxContentLength&&(d=!0,s.destroy(),n(new ie("maxContentLength size of "+e.maxContentLength+" exceeded",ie.ERR_BAD_RESPONSE,e,u)))})),s.on("aborted",(function(){if(d)return;const t=new ie("maxContentLength size of "+e.maxContentLength+" exceeded",ie.ERR_BAD_RESPONSE,e,u);s.destroy(t),n(t)})),s.on("error",(function(t){l.destroyed||n(ie.from(t,null,e,u))})),s.on("end",(function(){try{let e=1===a.length?a[0]:Buffer.concat(a);"arraybuffer"!==r&&(e=e.toString(c),c&&"utf8"!==c||(e=ae.stripBOM(e))),v.data=e}catch(t){return n(ie.from(t,null,e,v.request,v))}qe(t,n,v)}))}m.once("abort",(e=>{s.destroyed||(s.emit("error",e),s.destroy())}))})),m.once("abort",(e=>{n(e),l.destroy(e)})),l.on("error",(function(t){n(ie.from(t,null,e,l))})),l.on("socket",(function(e){e.setKeepAlive(!0,6e4)})),e.timeout){const t=parseInt(e.timeout,10);if(Number.isNaN(t))return void n(new ie("error trying to parse `config.timeout` to int",ie.ERR_BAD_OPTION_VALUE,e,l));l.setTimeout(t,(function(){if(u)return;let t=e.timeout?"timeout of "+e.timeout+"ms exceeded":"timeout exceeded";const a=e.transitional||be;e.timeoutErrorMessage&&(t=e.timeoutErrorMessage),n(new ie(t,a.clarifyTimeoutError?ie.ETIMEDOUT:ie.ECONNABORTED,e,l)),h()}))}if(ae.isStream(i)){let t=!1,n=!1;i.on("end",(()=>{t=!0})),i.once("error",(e=>{n=!0,l.destroy(e)})),i.on("close",(()=>{t||n||h(new Te("Request stream has been aborted",e,l))})),i.pipe(l)}else l.end(i)},new Promise(((e,n)=>{let a,i;const o=(e,t)=>{i||(i=!0,a&&a(e,t))},s=e=>{o(e,!0),n(e)};t((t=>{o(t),e(t)}),s,(e=>a=e)).catch(s)}));var t},rt=ge.isStandardBrowserEnv?{write:function(e,t,n,a,i,o){const s=[];s.push(e+"="+encodeURIComponent(t)),ae.isNumber(n)&&s.push("expires="+new Date(n).toGMTString()),ae.isString(a)&&s.push("path="+a),ae.isString(i)&&s.push("domain="+i),!0===o&&s.push("secure"),document.cookie=s.join("; ")},read:function(e){const t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}:{write:function(){},read:function(){return null},remove:function(){}},ct=ge.isStandardBrowserEnv?function(){const e=/(msie|trident)/i.test(navigator.userAgent),t=document.createElement("a");let n;function a(n){let a=n;return e&&(t.setAttribute("href",a),a=t.href),t.setAttribute("href",a),{href:t.href,protocol:t.protocol?t.protocol.replace(/:$/,""):"",host:t.host,search:t.search?t.search.replace(/^\?/,""):"",hash:t.hash?t.hash.replace(/^#/,""):"",hostname:t.hostname,port:t.port,pathname:"/"===t.pathname.charAt(0)?t.pathname:"/"+t.pathname}}return n=a(window.location.href),function(e){const t=ae.isString(e)?a(e):e;return t.protocol===n.protocol&&t.host===n.host}}():function(){return!0};function pt(e,t){let n=0;const a=Le(50,250);return i=>{const o=i.loaded,s=i.lengthComputable?i.total:void 0,r=o-n,c=a(r);n=o;const p={loaded:o,total:s,progress:s?o/s:void 0,bytes:r,rate:c||void 0,estimated:c&&s&&o<=s?(s-o)/c:void 0,event:i};p[t?"download":"upload"]=!0,e(p)}}const ut={http:st,xhr:"undefined"!=typeof XMLHttpRequest&&function(e){return new Promise((function(t,n){let a=e.data;const i=Se.from(e.headers).normalize(),o=e.responseType;let s,r;function c(){e.cancelToken&&e.cancelToken.unsubscribe(s),e.signal&&e.signal.removeEventListener("abort",s)}ae.isFormData(a)&&(ge.isStandardBrowserEnv||ge.isStandardBrowserWebWorkerEnv?i.setContentType(!1):i.getContentType(/^\s*multipart\/form-data/)?ae.isString(r=i.getContentType())&&i.setContentType(r.replace(/^\s*(multipart\/form-data);+/,"$1")):i.setContentType("multipart/form-data"));let p=new XMLHttpRequest;if(e.auth){const t=e.auth.username||"",n=e.auth.password?unescape(encodeURIComponent(e.auth.password)):"";i.set("Authorization","Basic "+btoa(t+":"+n))}const u=Ae(e.baseURL,e.url);function l(){if(!p)return;const a=Se.from("getAllResponseHeaders"in p&&p.getAllResponseHeaders());qe((function(e){t(e),c()}),(function(e){n(e),c()}),{data:o&&"text"!==o&&"json"!==o?p.response:p.responseText,status:p.status,statusText:p.statusText,headers:a,config:e,request:p}),p=null}if(p.open(e.method.toUpperCase(),ve(u,e.params,e.paramsSerializer),!0),p.timeout=e.timeout,"onloadend"in p?p.onloadend=l:p.onreadystatechange=function(){p&&4===p.readyState&&(0!==p.status||p.responseURL&&0===p.responseURL.indexOf("file:"))&&setTimeout(l)},p.onabort=function(){p&&(n(new ie("Request aborted",ie.ECONNABORTED,e,p)),p=null)},p.onerror=function(){n(new ie("Network Error",ie.ERR_NETWORK,e,p)),p=null},p.ontimeout=function(){let t=e.timeout?"timeout of "+e.timeout+"ms exceeded":"timeout exceeded";const a=e.transitional||be;e.timeoutErrorMessage&&(t=e.timeoutErrorMessage),n(new ie(t,a.clarifyTimeoutError?ie.ETIMEDOUT:ie.ECONNABORTED,e,p)),p=null},ge.isStandardBrowserEnv){const t=ct(u)&&e.xsrfCookieName&&rt.read(e.xsrfCookieName);t&&i.set(e.xsrfHeaderName,t)}void 0===a&&i.setContentType(null),"setRequestHeader"in p&&ae.forEach(i.toJSON(),(function(e,t){p.setRequestHeader(t,e)})),ae.isUndefined(e.withCredentials)||(p.withCredentials=!!e.withCredentials),o&&"json"!==o&&(p.responseType=e.responseType),"function"==typeof e.onDownloadProgress&&p.addEventListener("progress",pt(e.onDownloadProgress,!0)),"function"==typeof e.onUploadProgress&&p.upload&&p.upload.addEventListener("progress",pt(e.onUploadProgress)),(e.cancelToken||e.signal)&&(s=t=>{p&&(n(!t||t.type?new Te(null,e,p):t),p.abort(),p=null)},e.cancelToken&&e.cancelToken.subscribe(s),e.signal&&(e.signal.aborted?s():e.signal.addEventListener("abort",s)));const d=Me(u);d&&-1===ge.protocols.indexOf(d)?n(new ie("Unsupported protocol "+d+":",ie.ERR_BAD_REQUEST,e)):p.send(a||null)}))}};ae.forEach(ut,((e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch(e){}Object.defineProperty(e,"adapterName",{value:t})}}));const lt=e=>`- ${e}`,dt=e=>ae.isFunction(e)||null===e||!1===e,mt=e=>{e=ae.isArray(e)?e:[e];const{length:t}=e;let n,a;const i={};for(let o=0;o`adapter ${e} `+(!1===t?"is not supported by the environment":"is not available in the build")));throw new ie("There is no suitable adapter to dispatch the request "+(t?e.length>1?"since :\n"+e.map(lt).join("\n"):" "+lt(e[0]):"as no adapter specified"),"ERR_NOT_SUPPORT")}return a};function ft(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new Te(null,e)}function ht(e){ft(e),e.headers=Se.from(e.headers),e.data=Ee.call(e,e.transformRequest),-1!==["post","put","patch"].indexOf(e.method)&&e.headers.setContentType("application/x-www-form-urlencoded",!1);return mt(e.adapter||we.adapter)(e).then((function(t){return ft(e),t.data=Ee.call(e,e.transformResponse,t),t.headers=Se.from(t.headers),t}),(function(t){return Ce(t)||(ft(e),t&&t.response&&(t.response.data=Ee.call(e,e.transformResponse,t.response),t.response.headers=Se.from(t.response.headers))),Promise.reject(t)}))}const vt=e=>e instanceof Se?e.toJSON():e;function xt(e,t){t=t||{};const n={};function a(e,t,n){return ae.isPlainObject(e)&&ae.isPlainObject(t)?ae.merge.call({caseless:n},e,t):ae.isPlainObject(t)?ae.merge({},t):ae.isArray(t)?t.slice():t}function i(e,t,n){return ae.isUndefined(t)?ae.isUndefined(e)?void 0:a(void 0,e,n):a(e,t,n)}function o(e,t){if(!ae.isUndefined(t))return a(void 0,t)}function s(e,t){return ae.isUndefined(t)?ae.isUndefined(e)?void 0:a(void 0,e):a(void 0,t)}function r(n,i,o){return o in t?a(n,i):o in e?a(void 0,n):void 0}const c={url:o,method:o,data:o,baseURL:s,transformRequest:s,transformResponse:s,paramsSerializer:s,timeout:s,timeoutMessage:s,withCredentials:s,adapter:s,responseType:s,xsrfCookieName:s,xsrfHeaderName:s,onUploadProgress:s,onDownloadProgress:s,decompress:s,maxContentLength:s,maxBodyLength:s,beforeRedirect:s,transport:s,httpAgent:s,httpsAgent:s,cancelToken:s,socketPath:s,responseEncoding:s,validateStatus:r,headers:(e,t)=>i(vt(e),vt(t),!0)};return ae.forEach(Object.keys(Object.assign({},e,t)),(function(a){const o=c[a]||i,s=o(e[a],t[a],a);ae.isUndefined(s)&&o!==r||(n[a]=s)})),n}const bt={};["object","boolean","number","function","string","symbol"].forEach(((e,t)=>{bt[e]=function(n){return typeof n===e||"a"+(t<1?"n ":" ")+e}}));const gt={};bt.transitional=function(e,t,n){function a(e,t){return"[Axios v1.6.0] Transitional option '"+e+"'"+t+(n?". "+n:"")}return(n,i,o)=>{if(!1===e)throw new ie(a(i," has been removed"+(t?" in "+t:"")),ie.ERR_DEPRECATED);return t&&!gt[i]&&(gt[i]=!0,console.warn(a(i," has been deprecated since v"+t+" and will be removed in the near future"))),!e||e(n,i,o)}};const yt={assertOptions:function(e,t,n){if("object"!=typeof e)throw new ie("options must be an object",ie.ERR_BAD_OPTION_VALUE);const a=Object.keys(e);let i=a.length;for(;i-- >0;){const o=a[i],s=t[o];if(s){const t=e[o],n=void 0===t||s(t,o,e);if(!0!==n)throw new ie("option "+o+" must be "+n,ie.ERR_BAD_OPTION_VALUE)}else if(!0!==n)throw new ie("Unknown option "+o,ie.ERR_BAD_OPTION)}},validators:bt},_t=yt.validators;class Axios{constructor(e){this.defaults=e,this.interceptors={request:new xe,response:new xe}}request(e,t){"string"==typeof e?(t=t||{}).url=e:t=e||{},t=xt(this.defaults,t);const{transitional:n,paramsSerializer:a,headers:i}=t;void 0!==n&&yt.assertOptions(n,{silentJSONParsing:_t.transitional(_t.boolean),forcedJSONParsing:_t.transitional(_t.boolean),clarifyTimeoutError:_t.transitional(_t.boolean)},!1),null!=a&&(ae.isFunction(a)?t.paramsSerializer={serialize:a}:yt.assertOptions(a,{encode:_t.function,serialize:_t.function},!0)),t.method=(t.method||this.defaults.method||"get").toLowerCase();let o=i&&ae.merge(i.common,i[t.method]);i&&ae.forEach(["delete","get","head","post","put","patch","common"],(e=>{delete i[e]})),t.headers=Se.concat(o,i);const s=[];let r=!0;this.interceptors.request.forEach((function(e){"function"==typeof e.runWhen&&!1===e.runWhen(t)||(r=r&&e.synchronous,s.unshift(e.fulfilled,e.rejected))}));const c=[];let p;this.interceptors.response.forEach((function(e){c.push(e.fulfilled,e.rejected)}));let u,l=0;if(!r){const e=[ht.bind(this),void 0];for(e.unshift.apply(e,s),e.push.apply(e,c),u=e.length,p=Promise.resolve(t);l{if(!n._listeners)return;let t=n._listeners.length;for(;t-- >0;)n._listeners[t](e);n._listeners=null})),this.promise.then=e=>{let t;const a=new Promise((e=>{n.subscribe(e),t=e})).then(e);return a.cancel=function(){n.unsubscribe(t)},a},e((function(e,a,i){n.reason||(n.reason=new Te(e,a,i),t(n.reason))}))}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){this.reason?e(this.reason):this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const t=this._listeners.indexOf(e);-1!==t&&this._listeners.splice(t,1)}static source(){let e;return{token:new CancelToken((function(t){e=t})),cancel:e}}}const jt=CancelToken;const Ot={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(Ot).forEach((([e,t])=>{Ot[t]=e}));const kt=Ot;const Pt=function e(t){const n=new wt(t),a=j(wt.prototype.request,n);return ae.extend(a,wt.prototype,n,{allOwnKeys:!0}),ae.extend(a,n,null,{allOwnKeys:!0}),a.create=function(n){return e(xt(t,n))},a}(we);Pt.Axios=wt,Pt.CanceledError=Te,Pt.CancelToken=jt,Pt.isCancel=Ce,Pt.VERSION=De,Pt.toFormData=le,Pt.AxiosError=ie,Pt.Cancel=Pt.CanceledError,Pt.all=function(e){return Promise.all(e)},Pt.spread=function(e){return function(t){return e.apply(null,t)}},Pt.isAxiosError=function(e){return ae.isObject(e)&&!0===e.isAxiosError},Pt.mergeConfig=xt,Pt.AxiosHeaders=Se,Pt.formToJSON=e=>ye(ae.isHTMLForm(e)?new FormData(e):e),Pt.getAdapter=mt,Pt.HttpStatusCode=kt,Pt.default=Pt,e.exports=Pt},3765:e=>{"use strict";e.exports=JSON.parse('{"application/1d-interleaved-parityfec":{"source":"iana"},"application/3gpdash-qoe-report+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/3gpp-ims+xml":{"source":"iana","compressible":true},"application/3gpphal+json":{"source":"iana","compressible":true},"application/3gpphalforms+json":{"source":"iana","compressible":true},"application/a2l":{"source":"iana"},"application/ace+cbor":{"source":"iana"},"application/activemessage":{"source":"iana"},"application/activity+json":{"source":"iana","compressible":true},"application/alto-costmap+json":{"source":"iana","compressible":true},"application/alto-costmapfilter+json":{"source":"iana","compressible":true},"application/alto-directory+json":{"source":"iana","compressible":true},"application/alto-endpointcost+json":{"source":"iana","compressible":true},"application/alto-endpointcostparams+json":{"source":"iana","compressible":true},"application/alto-endpointprop+json":{"source":"iana","compressible":true},"application/alto-endpointpropparams+json":{"source":"iana","compressible":true},"application/alto-error+json":{"source":"iana","compressible":true},"application/alto-networkmap+json":{"source":"iana","compressible":true},"application/alto-networkmapfilter+json":{"source":"iana","compressible":true},"application/alto-updatestreamcontrol+json":{"source":"iana","compressible":true},"application/alto-updatestreamparams+json":{"source":"iana","compressible":true},"application/aml":{"source":"iana"},"application/andrew-inset":{"source":"iana","extensions":["ez"]},"application/applefile":{"source":"iana"},"application/applixware":{"source":"apache","extensions":["aw"]},"application/at+jwt":{"source":"iana"},"application/atf":{"source":"iana"},"application/atfx":{"source":"iana"},"application/atom+xml":{"source":"iana","compressible":true,"extensions":["atom"]},"application/atomcat+xml":{"source":"iana","compressible":true,"extensions":["atomcat"]},"application/atomdeleted+xml":{"source":"iana","compressible":true,"extensions":["atomdeleted"]},"application/atomicmail":{"source":"iana"},"application/atomsvc+xml":{"source":"iana","compressible":true,"extensions":["atomsvc"]},"application/atsc-dwd+xml":{"source":"iana","compressible":true,"extensions":["dwd"]},"application/atsc-dynamic-event-message":{"source":"iana"},"application/atsc-held+xml":{"source":"iana","compressible":true,"extensions":["held"]},"application/atsc-rdt+json":{"source":"iana","compressible":true},"application/atsc-rsat+xml":{"source":"iana","compressible":true,"extensions":["rsat"]},"application/atxml":{"source":"iana"},"application/auth-policy+xml":{"source":"iana","compressible":true},"application/bacnet-xdd+zip":{"source":"iana","compressible":false},"application/batch-smtp":{"source":"iana"},"application/bdoc":{"compressible":false,"extensions":["bdoc"]},"application/beep+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/calendar+json":{"source":"iana","compressible":true},"application/calendar+xml":{"source":"iana","compressible":true,"extensions":["xcs"]},"application/call-completion":{"source":"iana"},"application/cals-1840":{"source":"iana"},"application/captive+json":{"source":"iana","compressible":true},"application/cbor":{"source":"iana"},"application/cbor-seq":{"source":"iana"},"application/cccex":{"source":"iana"},"application/ccmp+xml":{"source":"iana","compressible":true},"application/ccxml+xml":{"source":"iana","compressible":true,"extensions":["ccxml"]},"application/cdfx+xml":{"source":"iana","compressible":true,"extensions":["cdfx"]},"application/cdmi-capability":{"source":"iana","extensions":["cdmia"]},"application/cdmi-container":{"source":"iana","extensions":["cdmic"]},"application/cdmi-domain":{"source":"iana","extensions":["cdmid"]},"application/cdmi-object":{"source":"iana","extensions":["cdmio"]},"application/cdmi-queue":{"source":"iana","extensions":["cdmiq"]},"application/cdni":{"source":"iana"},"application/cea":{"source":"iana"},"application/cea-2018+xml":{"source":"iana","compressible":true},"application/cellml+xml":{"source":"iana","compressible":true},"application/cfw":{"source":"iana"},"application/city+json":{"source":"iana","compressible":true},"application/clr":{"source":"iana"},"application/clue+xml":{"source":"iana","compressible":true},"application/clue_info+xml":{"source":"iana","compressible":true},"application/cms":{"source":"iana"},"application/cnrp+xml":{"source":"iana","compressible":true},"application/coap-group+json":{"source":"iana","compressible":true},"application/coap-payload":{"source":"iana"},"application/commonground":{"source":"iana"},"application/conference-info+xml":{"source":"iana","compressible":true},"application/cose":{"source":"iana"},"application/cose-key":{"source":"iana"},"application/cose-key-set":{"source":"iana"},"application/cpl+xml":{"source":"iana","compressible":true,"extensions":["cpl"]},"application/csrattrs":{"source":"iana"},"application/csta+xml":{"source":"iana","compressible":true},"application/cstadata+xml":{"source":"iana","compressible":true},"application/csvm+json":{"source":"iana","compressible":true},"application/cu-seeme":{"source":"apache","extensions":["cu"]},"application/cwt":{"source":"iana"},"application/cybercash":{"source":"iana"},"application/dart":{"compressible":true},"application/dash+xml":{"source":"iana","compressible":true,"extensions":["mpd"]},"application/dash-patch+xml":{"source":"iana","compressible":true,"extensions":["mpp"]},"application/dashdelta":{"source":"iana"},"application/davmount+xml":{"source":"iana","compressible":true,"extensions":["davmount"]},"application/dca-rft":{"source":"iana"},"application/dcd":{"source":"iana"},"application/dec-dx":{"source":"iana"},"application/dialog-info+xml":{"source":"iana","compressible":true},"application/dicom":{"source":"iana"},"application/dicom+json":{"source":"iana","compressible":true},"application/dicom+xml":{"source":"iana","compressible":true},"application/dii":{"source":"iana"},"application/dit":{"source":"iana"},"application/dns":{"source":"iana"},"application/dns+json":{"source":"iana","compressible":true},"application/dns-message":{"source":"iana"},"application/docbook+xml":{"source":"apache","compressible":true,"extensions":["dbk"]},"application/dots+cbor":{"source":"iana"},"application/dskpp+xml":{"source":"iana","compressible":true},"application/dssc+der":{"source":"iana","extensions":["dssc"]},"application/dssc+xml":{"source":"iana","compressible":true,"extensions":["xdssc"]},"application/dvcs":{"source":"iana"},"application/ecmascript":{"source":"iana","compressible":true,"extensions":["es","ecma"]},"application/edi-consent":{"source":"iana"},"application/edi-x12":{"source":"iana","compressible":false},"application/edifact":{"source":"iana","compressible":false},"application/efi":{"source":"iana"},"application/elm+json":{"source":"iana","charset":"UTF-8","compressible":true},"application/elm+xml":{"source":"iana","compressible":true},"application/emergencycalldata.cap+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/emergencycalldata.comment+xml":{"source":"iana","compressible":true},"application/emergencycalldata.control+xml":{"source":"iana","compressible":true},"application/emergencycalldata.deviceinfo+xml":{"source":"iana","compressible":true},"application/emergencycalldata.ecall.msd":{"source":"iana"},"application/emergencycalldata.providerinfo+xml":{"source":"iana","compressible":true},"application/emergencycalldata.serviceinfo+xml":{"source":"iana","compressible":true},"application/emergencycalldata.subscriberinfo+xml":{"source":"iana","compressible":true},"application/emergencycalldata.veds+xml":{"source":"iana","compressible":true},"application/emma+xml":{"source":"iana","compressible":true,"extensions":["emma"]},"application/emotionml+xml":{"source":"iana","compressible":true,"extensions":["emotionml"]},"application/encaprtp":{"source":"iana"},"application/epp+xml":{"source":"iana","compressible":true},"application/epub+zip":{"source":"iana","compressible":false,"extensions":["epub"]},"application/eshop":{"source":"iana"},"application/exi":{"source":"iana","extensions":["exi"]},"application/expect-ct-report+json":{"source":"iana","compressible":true},"application/express":{"source":"iana","extensions":["exp"]},"application/fastinfoset":{"source":"iana"},"application/fastsoap":{"source":"iana"},"application/fdt+xml":{"source":"iana","compressible":true,"extensions":["fdt"]},"application/fhir+json":{"source":"iana","charset":"UTF-8","compressible":true},"application/fhir+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/fido.trusted-apps+json":{"compressible":true},"application/fits":{"source":"iana"},"application/flexfec":{"source":"iana"},"application/font-sfnt":{"source":"iana"},"application/font-tdpfr":{"source":"iana","extensions":["pfr"]},"application/font-woff":{"source":"iana","compressible":false},"application/framework-attributes+xml":{"source":"iana","compressible":true},"application/geo+json":{"source":"iana","compressible":true,"extensions":["geojson"]},"application/geo+json-seq":{"source":"iana"},"application/geopackage+sqlite3":{"source":"iana"},"application/geoxacml+xml":{"source":"iana","compressible":true},"application/gltf-buffer":{"source":"iana"},"application/gml+xml":{"source":"iana","compressible":true,"extensions":["gml"]},"application/gpx+xml":{"source":"apache","compressible":true,"extensions":["gpx"]},"application/gxf":{"source":"apache","extensions":["gxf"]},"application/gzip":{"source":"iana","compressible":false,"extensions":["gz"]},"application/h224":{"source":"iana"},"application/held+xml":{"source":"iana","compressible":true},"application/hjson":{"extensions":["hjson"]},"application/http":{"source":"iana"},"application/hyperstudio":{"source":"iana","extensions":["stk"]},"application/ibe-key-request+xml":{"source":"iana","compressible":true},"application/ibe-pkg-reply+xml":{"source":"iana","compressible":true},"application/ibe-pp-data":{"source":"iana"},"application/iges":{"source":"iana"},"application/im-iscomposing+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/index":{"source":"iana"},"application/index.cmd":{"source":"iana"},"application/index.obj":{"source":"iana"},"application/index.response":{"source":"iana"},"application/index.vnd":{"source":"iana"},"application/inkml+xml":{"source":"iana","compressible":true,"extensions":["ink","inkml"]},"application/iotp":{"source":"iana"},"application/ipfix":{"source":"iana","extensions":["ipfix"]},"application/ipp":{"source":"iana"},"application/isup":{"source":"iana"},"application/its+xml":{"source":"iana","compressible":true,"extensions":["its"]},"application/java-archive":{"source":"apache","compressible":false,"extensions":["jar","war","ear"]},"application/java-serialized-object":{"source":"apache","compressible":false,"extensions":["ser"]},"application/java-vm":{"source":"apache","compressible":false,"extensions":["class"]},"application/javascript":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["js","mjs"]},"application/jf2feed+json":{"source":"iana","compressible":true},"application/jose":{"source":"iana"},"application/jose+json":{"source":"iana","compressible":true},"application/jrd+json":{"source":"iana","compressible":true},"application/jscalendar+json":{"source":"iana","compressible":true},"application/json":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["json","map"]},"application/json-patch+json":{"source":"iana","compressible":true},"application/json-seq":{"source":"iana"},"application/json5":{"extensions":["json5"]},"application/jsonml+json":{"source":"apache","compressible":true,"extensions":["jsonml"]},"application/jwk+json":{"source":"iana","compressible":true},"application/jwk-set+json":{"source":"iana","compressible":true},"application/jwt":{"source":"iana"},"application/kpml-request+xml":{"source":"iana","compressible":true},"application/kpml-response+xml":{"source":"iana","compressible":true},"application/ld+json":{"source":"iana","compressible":true,"extensions":["jsonld"]},"application/lgr+xml":{"source":"iana","compressible":true,"extensions":["lgr"]},"application/link-format":{"source":"iana"},"application/load-control+xml":{"source":"iana","compressible":true},"application/lost+xml":{"source":"iana","compressible":true,"extensions":["lostxml"]},"application/lostsync+xml":{"source":"iana","compressible":true},"application/lpf+zip":{"source":"iana","compressible":false},"application/lxf":{"source":"iana"},"application/mac-binhex40":{"source":"iana","extensions":["hqx"]},"application/mac-compactpro":{"source":"apache","extensions":["cpt"]},"application/macwriteii":{"source":"iana"},"application/mads+xml":{"source":"iana","compressible":true,"extensions":["mads"]},"application/manifest+json":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["webmanifest"]},"application/marc":{"source":"iana","extensions":["mrc"]},"application/marcxml+xml":{"source":"iana","compressible":true,"extensions":["mrcx"]},"application/mathematica":{"source":"iana","extensions":["ma","nb","mb"]},"application/mathml+xml":{"source":"iana","compressible":true,"extensions":["mathml"]},"application/mathml-content+xml":{"source":"iana","compressible":true},"application/mathml-presentation+xml":{"source":"iana","compressible":true},"application/mbms-associated-procedure-description+xml":{"source":"iana","compressible":true},"application/mbms-deregister+xml":{"source":"iana","compressible":true},"application/mbms-envelope+xml":{"source":"iana","compressible":true},"application/mbms-msk+xml":{"source":"iana","compressible":true},"application/mbms-msk-response+xml":{"source":"iana","compressible":true},"application/mbms-protection-description+xml":{"source":"iana","compressible":true},"application/mbms-reception-report+xml":{"source":"iana","compressible":true},"application/mbms-register+xml":{"source":"iana","compressible":true},"application/mbms-register-response+xml":{"source":"iana","compressible":true},"application/mbms-schedule+xml":{"source":"iana","compressible":true},"application/mbms-user-service-description+xml":{"source":"iana","compressible":true},"application/mbox":{"source":"iana","extensions":["mbox"]},"application/media-policy-dataset+xml":{"source":"iana","compressible":true,"extensions":["mpf"]},"application/media_control+xml":{"source":"iana","compressible":true},"application/mediaservercontrol+xml":{"source":"iana","compressible":true,"extensions":["mscml"]},"application/merge-patch+json":{"source":"iana","compressible":true},"application/metalink+xml":{"source":"apache","compressible":true,"extensions":["metalink"]},"application/metalink4+xml":{"source":"iana","compressible":true,"extensions":["meta4"]},"application/mets+xml":{"source":"iana","compressible":true,"extensions":["mets"]},"application/mf4":{"source":"iana"},"application/mikey":{"source":"iana"},"application/mipc":{"source":"iana"},"application/missing-blocks+cbor-seq":{"source":"iana"},"application/mmt-aei+xml":{"source":"iana","compressible":true,"extensions":["maei"]},"application/mmt-usd+xml":{"source":"iana","compressible":true,"extensions":["musd"]},"application/mods+xml":{"source":"iana","compressible":true,"extensions":["mods"]},"application/moss-keys":{"source":"iana"},"application/moss-signature":{"source":"iana"},"application/mosskey-data":{"source":"iana"},"application/mosskey-request":{"source":"iana"},"application/mp21":{"source":"iana","extensions":["m21","mp21"]},"application/mp4":{"source":"iana","extensions":["mp4s","m4p"]},"application/mpeg4-generic":{"source":"iana"},"application/mpeg4-iod":{"source":"iana"},"application/mpeg4-iod-xmt":{"source":"iana"},"application/mrb-consumer+xml":{"source":"iana","compressible":true},"application/mrb-publish+xml":{"source":"iana","compressible":true},"application/msc-ivr+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/msc-mixer+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/msword":{"source":"iana","compressible":false,"extensions":["doc","dot"]},"application/mud+json":{"source":"iana","compressible":true},"application/multipart-core":{"source":"iana"},"application/mxf":{"source":"iana","extensions":["mxf"]},"application/n-quads":{"source":"iana","extensions":["nq"]},"application/n-triples":{"source":"iana","extensions":["nt"]},"application/nasdata":{"source":"iana"},"application/news-checkgroups":{"source":"iana","charset":"US-ASCII"},"application/news-groupinfo":{"source":"iana","charset":"US-ASCII"},"application/news-transmission":{"source":"iana"},"application/nlsml+xml":{"source":"iana","compressible":true},"application/node":{"source":"iana","extensions":["cjs"]},"application/nss":{"source":"iana"},"application/oauth-authz-req+jwt":{"source":"iana"},"application/oblivious-dns-message":{"source":"iana"},"application/ocsp-request":{"source":"iana"},"application/ocsp-response":{"source":"iana"},"application/octet-stream":{"source":"iana","compressible":false,"extensions":["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"]},"application/oda":{"source":"iana","extensions":["oda"]},"application/odm+xml":{"source":"iana","compressible":true},"application/odx":{"source":"iana"},"application/oebps-package+xml":{"source":"iana","compressible":true,"extensions":["opf"]},"application/ogg":{"source":"iana","compressible":false,"extensions":["ogx"]},"application/omdoc+xml":{"source":"apache","compressible":true,"extensions":["omdoc"]},"application/onenote":{"source":"apache","extensions":["onetoc","onetoc2","onetmp","onepkg"]},"application/opc-nodeset+xml":{"source":"iana","compressible":true},"application/oscore":{"source":"iana"},"application/oxps":{"source":"iana","extensions":["oxps"]},"application/p21":{"source":"iana"},"application/p21+zip":{"source":"iana","compressible":false},"application/p2p-overlay+xml":{"source":"iana","compressible":true,"extensions":["relo"]},"application/parityfec":{"source":"iana"},"application/passport":{"source":"iana"},"application/patch-ops-error+xml":{"source":"iana","compressible":true,"extensions":["xer"]},"application/pdf":{"source":"iana","compressible":false,"extensions":["pdf"]},"application/pdx":{"source":"iana"},"application/pem-certificate-chain":{"source":"iana"},"application/pgp-encrypted":{"source":"iana","compressible":false,"extensions":["pgp"]},"application/pgp-keys":{"source":"iana","extensions":["asc"]},"application/pgp-signature":{"source":"iana","extensions":["asc","sig"]},"application/pics-rules":{"source":"apache","extensions":["prf"]},"application/pidf+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/pidf-diff+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/pkcs10":{"source":"iana","extensions":["p10"]},"application/pkcs12":{"source":"iana"},"application/pkcs7-mime":{"source":"iana","extensions":["p7m","p7c"]},"application/pkcs7-signature":{"source":"iana","extensions":["p7s"]},"application/pkcs8":{"source":"iana","extensions":["p8"]},"application/pkcs8-encrypted":{"source":"iana"},"application/pkix-attr-cert":{"source":"iana","extensions":["ac"]},"application/pkix-cert":{"source":"iana","extensions":["cer"]},"application/pkix-crl":{"source":"iana","extensions":["crl"]},"application/pkix-pkipath":{"source":"iana","extensions":["pkipath"]},"application/pkixcmp":{"source":"iana","extensions":["pki"]},"application/pls+xml":{"source":"iana","compressible":true,"extensions":["pls"]},"application/poc-settings+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/postscript":{"source":"iana","compressible":true,"extensions":["ai","eps","ps"]},"application/ppsp-tracker+json":{"source":"iana","compressible":true},"application/problem+json":{"source":"iana","compressible":true},"application/problem+xml":{"source":"iana","compressible":true},"application/provenance+xml":{"source":"iana","compressible":true,"extensions":["provx"]},"application/prs.alvestrand.titrax-sheet":{"source":"iana"},"application/prs.cww":{"source":"iana","extensions":["cww"]},"application/prs.cyn":{"source":"iana","charset":"7-BIT"},"application/prs.hpub+zip":{"source":"iana","compressible":false},"application/prs.nprend":{"source":"iana"},"application/prs.plucker":{"source":"iana"},"application/prs.rdf-xml-crypt":{"source":"iana"},"application/prs.xsf+xml":{"source":"iana","compressible":true},"application/pskc+xml":{"source":"iana","compressible":true,"extensions":["pskcxml"]},"application/pvd+json":{"source":"iana","compressible":true},"application/qsig":{"source":"iana"},"application/raml+yaml":{"compressible":true,"extensions":["raml"]},"application/raptorfec":{"source":"iana"},"application/rdap+json":{"source":"iana","compressible":true},"application/rdf+xml":{"source":"iana","compressible":true,"extensions":["rdf","owl"]},"application/reginfo+xml":{"source":"iana","compressible":true,"extensions":["rif"]},"application/relax-ng-compact-syntax":{"source":"iana","extensions":["rnc"]},"application/remote-printing":{"source":"iana"},"application/reputon+json":{"source":"iana","compressible":true},"application/resource-lists+xml":{"source":"iana","compressible":true,"extensions":["rl"]},"application/resource-lists-diff+xml":{"source":"iana","compressible":true,"extensions":["rld"]},"application/rfc+xml":{"source":"iana","compressible":true},"application/riscos":{"source":"iana"},"application/rlmi+xml":{"source":"iana","compressible":true},"application/rls-services+xml":{"source":"iana","compressible":true,"extensions":["rs"]},"application/route-apd+xml":{"source":"iana","compressible":true,"extensions":["rapd"]},"application/route-s-tsid+xml":{"source":"iana","compressible":true,"extensions":["sls"]},"application/route-usd+xml":{"source":"iana","compressible":true,"extensions":["rusd"]},"application/rpki-ghostbusters":{"source":"iana","extensions":["gbr"]},"application/rpki-manifest":{"source":"iana","extensions":["mft"]},"application/rpki-publication":{"source":"iana"},"application/rpki-roa":{"source":"iana","extensions":["roa"]},"application/rpki-updown":{"source":"iana"},"application/rsd+xml":{"source":"apache","compressible":true,"extensions":["rsd"]},"application/rss+xml":{"source":"apache","compressible":true,"extensions":["rss"]},"application/rtf":{"source":"iana","compressible":true,"extensions":["rtf"]},"application/rtploopback":{"source":"iana"},"application/rtx":{"source":"iana"},"application/samlassertion+xml":{"source":"iana","compressible":true},"application/samlmetadata+xml":{"source":"iana","compressible":true},"application/sarif+json":{"source":"iana","compressible":true},"application/sarif-external-properties+json":{"source":"iana","compressible":true},"application/sbe":{"source":"iana"},"application/sbml+xml":{"source":"iana","compressible":true,"extensions":["sbml"]},"application/scaip+xml":{"source":"iana","compressible":true},"application/scim+json":{"source":"iana","compressible":true},"application/scvp-cv-request":{"source":"iana","extensions":["scq"]},"application/scvp-cv-response":{"source":"iana","extensions":["scs"]},"application/scvp-vp-request":{"source":"iana","extensions":["spq"]},"application/scvp-vp-response":{"source":"iana","extensions":["spp"]},"application/sdp":{"source":"iana","extensions":["sdp"]},"application/secevent+jwt":{"source":"iana"},"application/senml+cbor":{"source":"iana"},"application/senml+json":{"source":"iana","compressible":true},"application/senml+xml":{"source":"iana","compressible":true,"extensions":["senmlx"]},"application/senml-etch+cbor":{"source":"iana"},"application/senml-etch+json":{"source":"iana","compressible":true},"application/senml-exi":{"source":"iana"},"application/sensml+cbor":{"source":"iana"},"application/sensml+json":{"source":"iana","compressible":true},"application/sensml+xml":{"source":"iana","compressible":true,"extensions":["sensmlx"]},"application/sensml-exi":{"source":"iana"},"application/sep+xml":{"source":"iana","compressible":true},"application/sep-exi":{"source":"iana"},"application/session-info":{"source":"iana"},"application/set-payment":{"source":"iana"},"application/set-payment-initiation":{"source":"iana","extensions":["setpay"]},"application/set-registration":{"source":"iana"},"application/set-registration-initiation":{"source":"iana","extensions":["setreg"]},"application/sgml":{"source":"iana"},"application/sgml-open-catalog":{"source":"iana"},"application/shf+xml":{"source":"iana","compressible":true,"extensions":["shf"]},"application/sieve":{"source":"iana","extensions":["siv","sieve"]},"application/simple-filter+xml":{"source":"iana","compressible":true},"application/simple-message-summary":{"source":"iana"},"application/simplesymbolcontainer":{"source":"iana"},"application/sipc":{"source":"iana"},"application/slate":{"source":"iana"},"application/smil":{"source":"iana"},"application/smil+xml":{"source":"iana","compressible":true,"extensions":["smi","smil"]},"application/smpte336m":{"source":"iana"},"application/soap+fastinfoset":{"source":"iana"},"application/soap+xml":{"source":"iana","compressible":true},"application/sparql-query":{"source":"iana","extensions":["rq"]},"application/sparql-results+xml":{"source":"iana","compressible":true,"extensions":["srx"]},"application/spdx+json":{"source":"iana","compressible":true},"application/spirits-event+xml":{"source":"iana","compressible":true},"application/sql":{"source":"iana"},"application/srgs":{"source":"iana","extensions":["gram"]},"application/srgs+xml":{"source":"iana","compressible":true,"extensions":["grxml"]},"application/sru+xml":{"source":"iana","compressible":true,"extensions":["sru"]},"application/ssdl+xml":{"source":"apache","compressible":true,"extensions":["ssdl"]},"application/ssml+xml":{"source":"iana","compressible":true,"extensions":["ssml"]},"application/stix+json":{"source":"iana","compressible":true},"application/swid+xml":{"source":"iana","compressible":true,"extensions":["swidtag"]},"application/tamp-apex-update":{"source":"iana"},"application/tamp-apex-update-confirm":{"source":"iana"},"application/tamp-community-update":{"source":"iana"},"application/tamp-community-update-confirm":{"source":"iana"},"application/tamp-error":{"source":"iana"},"application/tamp-sequence-adjust":{"source":"iana"},"application/tamp-sequence-adjust-confirm":{"source":"iana"},"application/tamp-status-query":{"source":"iana"},"application/tamp-status-response":{"source":"iana"},"application/tamp-update":{"source":"iana"},"application/tamp-update-confirm":{"source":"iana"},"application/tar":{"compressible":true},"application/taxii+json":{"source":"iana","compressible":true},"application/td+json":{"source":"iana","compressible":true},"application/tei+xml":{"source":"iana","compressible":true,"extensions":["tei","teicorpus"]},"application/tetra_isi":{"source":"iana"},"application/thraud+xml":{"source":"iana","compressible":true,"extensions":["tfi"]},"application/timestamp-query":{"source":"iana"},"application/timestamp-reply":{"source":"iana"},"application/timestamped-data":{"source":"iana","extensions":["tsd"]},"application/tlsrpt+gzip":{"source":"iana"},"application/tlsrpt+json":{"source":"iana","compressible":true},"application/tnauthlist":{"source":"iana"},"application/token-introspection+jwt":{"source":"iana"},"application/toml":{"compressible":true,"extensions":["toml"]},"application/trickle-ice-sdpfrag":{"source":"iana"},"application/trig":{"source":"iana","extensions":["trig"]},"application/ttml+xml":{"source":"iana","compressible":true,"extensions":["ttml"]},"application/tve-trigger":{"source":"iana"},"application/tzif":{"source":"iana"},"application/tzif-leap":{"source":"iana"},"application/ubjson":{"compressible":false,"extensions":["ubj"]},"application/ulpfec":{"source":"iana"},"application/urc-grpsheet+xml":{"source":"iana","compressible":true},"application/urc-ressheet+xml":{"source":"iana","compressible":true,"extensions":["rsheet"]},"application/urc-targetdesc+xml":{"source":"iana","compressible":true,"extensions":["td"]},"application/urc-uisocketdesc+xml":{"source":"iana","compressible":true},"application/vcard+json":{"source":"iana","compressible":true},"application/vcard+xml":{"source":"iana","compressible":true},"application/vemmi":{"source":"iana"},"application/vividence.scriptfile":{"source":"apache"},"application/vnd.1000minds.decision-model+xml":{"source":"iana","compressible":true,"extensions":["1km"]},"application/vnd.3gpp-prose+xml":{"source":"iana","compressible":true},"application/vnd.3gpp-prose-pc3ch+xml":{"source":"iana","compressible":true},"application/vnd.3gpp-v2x-local-service-information":{"source":"iana"},"application/vnd.3gpp.5gnas":{"source":"iana"},"application/vnd.3gpp.access-transfer-events+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.bsf+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.gmop+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.gtpc":{"source":"iana"},"application/vnd.3gpp.interworking-data":{"source":"iana"},"application/vnd.3gpp.lpp":{"source":"iana"},"application/vnd.3gpp.mc-signalling-ear":{"source":"iana"},"application/vnd.3gpp.mcdata-affiliation-command+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcdata-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcdata-payload":{"source":"iana"},"application/vnd.3gpp.mcdata-service-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcdata-signalling":{"source":"iana"},"application/vnd.3gpp.mcdata-ue-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcdata-user-profile+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-affiliation-command+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-floor-request+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-location-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-mbms-usage-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-service-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-signed+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-ue-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-ue-init-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-user-profile+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-affiliation-command+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-affiliation-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-location-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-mbms-usage-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-service-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-transmission-request+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-ue-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-user-profile+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mid-call+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.ngap":{"source":"iana"},"application/vnd.3gpp.pfcp":{"source":"iana"},"application/vnd.3gpp.pic-bw-large":{"source":"iana","extensions":["plb"]},"application/vnd.3gpp.pic-bw-small":{"source":"iana","extensions":["psb"]},"application/vnd.3gpp.pic-bw-var":{"source":"iana","extensions":["pvb"]},"application/vnd.3gpp.s1ap":{"source":"iana"},"application/vnd.3gpp.sms":{"source":"iana"},"application/vnd.3gpp.sms+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.srvcc-ext+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.srvcc-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.state-and-event-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.ussd+xml":{"source":"iana","compressible":true},"application/vnd.3gpp2.bcmcsinfo+xml":{"source":"iana","compressible":true},"application/vnd.3gpp2.sms":{"source":"iana"},"application/vnd.3gpp2.tcap":{"source":"iana","extensions":["tcap"]},"application/vnd.3lightssoftware.imagescal":{"source":"iana"},"application/vnd.3m.post-it-notes":{"source":"iana","extensions":["pwn"]},"application/vnd.accpac.simply.aso":{"source":"iana","extensions":["aso"]},"application/vnd.accpac.simply.imp":{"source":"iana","extensions":["imp"]},"application/vnd.acucobol":{"source":"iana","extensions":["acu"]},"application/vnd.acucorp":{"source":"iana","extensions":["atc","acutc"]},"application/vnd.adobe.air-application-installer-package+zip":{"source":"apache","compressible":false,"extensions":["air"]},"application/vnd.adobe.flash.movie":{"source":"iana"},"application/vnd.adobe.formscentral.fcdt":{"source":"iana","extensions":["fcdt"]},"application/vnd.adobe.fxp":{"source":"iana","extensions":["fxp","fxpl"]},"application/vnd.adobe.partial-upload":{"source":"iana"},"application/vnd.adobe.xdp+xml":{"source":"iana","compressible":true,"extensions":["xdp"]},"application/vnd.adobe.xfdf":{"source":"iana","extensions":["xfdf"]},"application/vnd.aether.imp":{"source":"iana"},"application/vnd.afpc.afplinedata":{"source":"iana"},"application/vnd.afpc.afplinedata-pagedef":{"source":"iana"},"application/vnd.afpc.cmoca-cmresource":{"source":"iana"},"application/vnd.afpc.foca-charset":{"source":"iana"},"application/vnd.afpc.foca-codedfont":{"source":"iana"},"application/vnd.afpc.foca-codepage":{"source":"iana"},"application/vnd.afpc.modca":{"source":"iana"},"application/vnd.afpc.modca-cmtable":{"source":"iana"},"application/vnd.afpc.modca-formdef":{"source":"iana"},"application/vnd.afpc.modca-mediummap":{"source":"iana"},"application/vnd.afpc.modca-objectcontainer":{"source":"iana"},"application/vnd.afpc.modca-overlay":{"source":"iana"},"application/vnd.afpc.modca-pagesegment":{"source":"iana"},"application/vnd.age":{"source":"iana","extensions":["age"]},"application/vnd.ah-barcode":{"source":"iana"},"application/vnd.ahead.space":{"source":"iana","extensions":["ahead"]},"application/vnd.airzip.filesecure.azf":{"source":"iana","extensions":["azf"]},"application/vnd.airzip.filesecure.azs":{"source":"iana","extensions":["azs"]},"application/vnd.amadeus+json":{"source":"iana","compressible":true},"application/vnd.amazon.ebook":{"source":"apache","extensions":["azw"]},"application/vnd.amazon.mobi8-ebook":{"source":"iana"},"application/vnd.americandynamics.acc":{"source":"iana","extensions":["acc"]},"application/vnd.amiga.ami":{"source":"iana","extensions":["ami"]},"application/vnd.amundsen.maze+xml":{"source":"iana","compressible":true},"application/vnd.android.ota":{"source":"iana"},"application/vnd.android.package-archive":{"source":"apache","compressible":false,"extensions":["apk"]},"application/vnd.anki":{"source":"iana"},"application/vnd.anser-web-certificate-issue-initiation":{"source":"iana","extensions":["cii"]},"application/vnd.anser-web-funds-transfer-initiation":{"source":"apache","extensions":["fti"]},"application/vnd.antix.game-component":{"source":"iana","extensions":["atx"]},"application/vnd.apache.arrow.file":{"source":"iana"},"application/vnd.apache.arrow.stream":{"source":"iana"},"application/vnd.apache.thrift.binary":{"source":"iana"},"application/vnd.apache.thrift.compact":{"source":"iana"},"application/vnd.apache.thrift.json":{"source":"iana"},"application/vnd.api+json":{"source":"iana","compressible":true},"application/vnd.aplextor.warrp+json":{"source":"iana","compressible":true},"application/vnd.apothekende.reservation+json":{"source":"iana","compressible":true},"application/vnd.apple.installer+xml":{"source":"iana","compressible":true,"extensions":["mpkg"]},"application/vnd.apple.keynote":{"source":"iana","extensions":["key"]},"application/vnd.apple.mpegurl":{"source":"iana","extensions":["m3u8"]},"application/vnd.apple.numbers":{"source":"iana","extensions":["numbers"]},"application/vnd.apple.pages":{"source":"iana","extensions":["pages"]},"application/vnd.apple.pkpass":{"compressible":false,"extensions":["pkpass"]},"application/vnd.arastra.swi":{"source":"iana"},"application/vnd.aristanetworks.swi":{"source":"iana","extensions":["swi"]},"application/vnd.artisan+json":{"source":"iana","compressible":true},"application/vnd.artsquare":{"source":"iana"},"application/vnd.astraea-software.iota":{"source":"iana","extensions":["iota"]},"application/vnd.audiograph":{"source":"iana","extensions":["aep"]},"application/vnd.autopackage":{"source":"iana"},"application/vnd.avalon+json":{"source":"iana","compressible":true},"application/vnd.avistar+xml":{"source":"iana","compressible":true},"application/vnd.balsamiq.bmml+xml":{"source":"iana","compressible":true,"extensions":["bmml"]},"application/vnd.balsamiq.bmpr":{"source":"iana"},"application/vnd.banana-accounting":{"source":"iana"},"application/vnd.bbf.usp.error":{"source":"iana"},"application/vnd.bbf.usp.msg":{"source":"iana"},"application/vnd.bbf.usp.msg+json":{"source":"iana","compressible":true},"application/vnd.bekitzur-stech+json":{"source":"iana","compressible":true},"application/vnd.bint.med-content":{"source":"iana"},"application/vnd.biopax.rdf+xml":{"source":"iana","compressible":true},"application/vnd.blink-idb-value-wrapper":{"source":"iana"},"application/vnd.blueice.multipass":{"source":"iana","extensions":["mpm"]},"application/vnd.bluetooth.ep.oob":{"source":"iana"},"application/vnd.bluetooth.le.oob":{"source":"iana"},"application/vnd.bmi":{"source":"iana","extensions":["bmi"]},"application/vnd.bpf":{"source":"iana"},"application/vnd.bpf3":{"source":"iana"},"application/vnd.businessobjects":{"source":"iana","extensions":["rep"]},"application/vnd.byu.uapi+json":{"source":"iana","compressible":true},"application/vnd.cab-jscript":{"source":"iana"},"application/vnd.canon-cpdl":{"source":"iana"},"application/vnd.canon-lips":{"source":"iana"},"application/vnd.capasystems-pg+json":{"source":"iana","compressible":true},"application/vnd.cendio.thinlinc.clientconf":{"source":"iana"},"application/vnd.century-systems.tcp_stream":{"source":"iana"},"application/vnd.chemdraw+xml":{"source":"iana","compressible":true,"extensions":["cdxml"]},"application/vnd.chess-pgn":{"source":"iana"},"application/vnd.chipnuts.karaoke-mmd":{"source":"iana","extensions":["mmd"]},"application/vnd.ciedi":{"source":"iana"},"application/vnd.cinderella":{"source":"iana","extensions":["cdy"]},"application/vnd.cirpack.isdn-ext":{"source":"iana"},"application/vnd.citationstyles.style+xml":{"source":"iana","compressible":true,"extensions":["csl"]},"application/vnd.claymore":{"source":"iana","extensions":["cla"]},"application/vnd.cloanto.rp9":{"source":"iana","extensions":["rp9"]},"application/vnd.clonk.c4group":{"source":"iana","extensions":["c4g","c4d","c4f","c4p","c4u"]},"application/vnd.cluetrust.cartomobile-config":{"source":"iana","extensions":["c11amc"]},"application/vnd.cluetrust.cartomobile-config-pkg":{"source":"iana","extensions":["c11amz"]},"application/vnd.coffeescript":{"source":"iana"},"application/vnd.collabio.xodocuments.document":{"source":"iana"},"application/vnd.collabio.xodocuments.document-template":{"source":"iana"},"application/vnd.collabio.xodocuments.presentation":{"source":"iana"},"application/vnd.collabio.xodocuments.presentation-template":{"source":"iana"},"application/vnd.collabio.xodocuments.spreadsheet":{"source":"iana"},"application/vnd.collabio.xodocuments.spreadsheet-template":{"source":"iana"},"application/vnd.collection+json":{"source":"iana","compressible":true},"application/vnd.collection.doc+json":{"source":"iana","compressible":true},"application/vnd.collection.next+json":{"source":"iana","compressible":true},"application/vnd.comicbook+zip":{"source":"iana","compressible":false},"application/vnd.comicbook-rar":{"source":"iana"},"application/vnd.commerce-battelle":{"source":"iana"},"application/vnd.commonspace":{"source":"iana","extensions":["csp"]},"application/vnd.contact.cmsg":{"source":"iana","extensions":["cdbcmsg"]},"application/vnd.coreos.ignition+json":{"source":"iana","compressible":true},"application/vnd.cosmocaller":{"source":"iana","extensions":["cmc"]},"application/vnd.crick.clicker":{"source":"iana","extensions":["clkx"]},"application/vnd.crick.clicker.keyboard":{"source":"iana","extensions":["clkk"]},"application/vnd.crick.clicker.palette":{"source":"iana","extensions":["clkp"]},"application/vnd.crick.clicker.template":{"source":"iana","extensions":["clkt"]},"application/vnd.crick.clicker.wordbank":{"source":"iana","extensions":["clkw"]},"application/vnd.criticaltools.wbs+xml":{"source":"iana","compressible":true,"extensions":["wbs"]},"application/vnd.cryptii.pipe+json":{"source":"iana","compressible":true},"application/vnd.crypto-shade-file":{"source":"iana"},"application/vnd.cryptomator.encrypted":{"source":"iana"},"application/vnd.cryptomator.vault":{"source":"iana"},"application/vnd.ctc-posml":{"source":"iana","extensions":["pml"]},"application/vnd.ctct.ws+xml":{"source":"iana","compressible":true},"application/vnd.cups-pdf":{"source":"iana"},"application/vnd.cups-postscript":{"source":"iana"},"application/vnd.cups-ppd":{"source":"iana","extensions":["ppd"]},"application/vnd.cups-raster":{"source":"iana"},"application/vnd.cups-raw":{"source":"iana"},"application/vnd.curl":{"source":"iana"},"application/vnd.curl.car":{"source":"apache","extensions":["car"]},"application/vnd.curl.pcurl":{"source":"apache","extensions":["pcurl"]},"application/vnd.cyan.dean.root+xml":{"source":"iana","compressible":true},"application/vnd.cybank":{"source":"iana"},"application/vnd.cyclonedx+json":{"source":"iana","compressible":true},"application/vnd.cyclonedx+xml":{"source":"iana","compressible":true},"application/vnd.d2l.coursepackage1p0+zip":{"source":"iana","compressible":false},"application/vnd.d3m-dataset":{"source":"iana"},"application/vnd.d3m-problem":{"source":"iana"},"application/vnd.dart":{"source":"iana","compressible":true,"extensions":["dart"]},"application/vnd.data-vision.rdz":{"source":"iana","extensions":["rdz"]},"application/vnd.datapackage+json":{"source":"iana","compressible":true},"application/vnd.dataresource+json":{"source":"iana","compressible":true},"application/vnd.dbf":{"source":"iana","extensions":["dbf"]},"application/vnd.debian.binary-package":{"source":"iana"},"application/vnd.dece.data":{"source":"iana","extensions":["uvf","uvvf","uvd","uvvd"]},"application/vnd.dece.ttml+xml":{"source":"iana","compressible":true,"extensions":["uvt","uvvt"]},"application/vnd.dece.unspecified":{"source":"iana","extensions":["uvx","uvvx"]},"application/vnd.dece.zip":{"source":"iana","extensions":["uvz","uvvz"]},"application/vnd.denovo.fcselayout-link":{"source":"iana","extensions":["fe_launch"]},"application/vnd.desmume.movie":{"source":"iana"},"application/vnd.dir-bi.plate-dl-nosuffix":{"source":"iana"},"application/vnd.dm.delegation+xml":{"source":"iana","compressible":true},"application/vnd.dna":{"source":"iana","extensions":["dna"]},"application/vnd.document+json":{"source":"iana","compressible":true},"application/vnd.dolby.mlp":{"source":"apache","extensions":["mlp"]},"application/vnd.dolby.mobile.1":{"source":"iana"},"application/vnd.dolby.mobile.2":{"source":"iana"},"application/vnd.doremir.scorecloud-binary-document":{"source":"iana"},"application/vnd.dpgraph":{"source":"iana","extensions":["dpg"]},"application/vnd.dreamfactory":{"source":"iana","extensions":["dfac"]},"application/vnd.drive+json":{"source":"iana","compressible":true},"application/vnd.ds-keypoint":{"source":"apache","extensions":["kpxx"]},"application/vnd.dtg.local":{"source":"iana"},"application/vnd.dtg.local.flash":{"source":"iana"},"application/vnd.dtg.local.html":{"source":"iana"},"application/vnd.dvb.ait":{"source":"iana","extensions":["ait"]},"application/vnd.dvb.dvbisl+xml":{"source":"iana","compressible":true},"application/vnd.dvb.dvbj":{"source":"iana"},"application/vnd.dvb.esgcontainer":{"source":"iana"},"application/vnd.dvb.ipdcdftnotifaccess":{"source":"iana"},"application/vnd.dvb.ipdcesgaccess":{"source":"iana"},"application/vnd.dvb.ipdcesgaccess2":{"source":"iana"},"application/vnd.dvb.ipdcesgpdd":{"source":"iana"},"application/vnd.dvb.ipdcroaming":{"source":"iana"},"application/vnd.dvb.iptv.alfec-base":{"source":"iana"},"application/vnd.dvb.iptv.alfec-enhancement":{"source":"iana"},"application/vnd.dvb.notif-aggregate-root+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-container+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-generic+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-ia-msglist+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-ia-registration-request+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-ia-registration-response+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-init+xml":{"source":"iana","compressible":true},"application/vnd.dvb.pfr":{"source":"iana"},"application/vnd.dvb.service":{"source":"iana","extensions":["svc"]},"application/vnd.dxr":{"source":"iana"},"application/vnd.dynageo":{"source":"iana","extensions":["geo"]},"application/vnd.dzr":{"source":"iana"},"application/vnd.easykaraoke.cdgdownload":{"source":"iana"},"application/vnd.ecdis-update":{"source":"iana"},"application/vnd.ecip.rlp":{"source":"iana"},"application/vnd.eclipse.ditto+json":{"source":"iana","compressible":true},"application/vnd.ecowin.chart":{"source":"iana","extensions":["mag"]},"application/vnd.ecowin.filerequest":{"source":"iana"},"application/vnd.ecowin.fileupdate":{"source":"iana"},"application/vnd.ecowin.series":{"source":"iana"},"application/vnd.ecowin.seriesrequest":{"source":"iana"},"application/vnd.ecowin.seriesupdate":{"source":"iana"},"application/vnd.efi.img":{"source":"iana"},"application/vnd.efi.iso":{"source":"iana"},"application/vnd.emclient.accessrequest+xml":{"source":"iana","compressible":true},"application/vnd.enliven":{"source":"iana","extensions":["nml"]},"application/vnd.enphase.envoy":{"source":"iana"},"application/vnd.eprints.data+xml":{"source":"iana","compressible":true},"application/vnd.epson.esf":{"source":"iana","extensions":["esf"]},"application/vnd.epson.msf":{"source":"iana","extensions":["msf"]},"application/vnd.epson.quickanime":{"source":"iana","extensions":["qam"]},"application/vnd.epson.salt":{"source":"iana","extensions":["slt"]},"application/vnd.epson.ssf":{"source":"iana","extensions":["ssf"]},"application/vnd.ericsson.quickcall":{"source":"iana"},"application/vnd.espass-espass+zip":{"source":"iana","compressible":false},"application/vnd.eszigno3+xml":{"source":"iana","compressible":true,"extensions":["es3","et3"]},"application/vnd.etsi.aoc+xml":{"source":"iana","compressible":true},"application/vnd.etsi.asic-e+zip":{"source":"iana","compressible":false},"application/vnd.etsi.asic-s+zip":{"source":"iana","compressible":false},"application/vnd.etsi.cug+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvcommand+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvdiscovery+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvprofile+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvsad-bc+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvsad-cod+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvsad-npvr+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvservice+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvsync+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvueprofile+xml":{"source":"iana","compressible":true},"application/vnd.etsi.mcid+xml":{"source":"iana","compressible":true},"application/vnd.etsi.mheg5":{"source":"iana"},"application/vnd.etsi.overload-control-policy-dataset+xml":{"source":"iana","compressible":true},"application/vnd.etsi.pstn+xml":{"source":"iana","compressible":true},"application/vnd.etsi.sci+xml":{"source":"iana","compressible":true},"application/vnd.etsi.simservs+xml":{"source":"iana","compressible":true},"application/vnd.etsi.timestamp-token":{"source":"iana"},"application/vnd.etsi.tsl+xml":{"source":"iana","compressible":true},"application/vnd.etsi.tsl.der":{"source":"iana"},"application/vnd.eu.kasparian.car+json":{"source":"iana","compressible":true},"application/vnd.eudora.data":{"source":"iana"},"application/vnd.evolv.ecig.profile":{"source":"iana"},"application/vnd.evolv.ecig.settings":{"source":"iana"},"application/vnd.evolv.ecig.theme":{"source":"iana"},"application/vnd.exstream-empower+zip":{"source":"iana","compressible":false},"application/vnd.exstream-package":{"source":"iana"},"application/vnd.ezpix-album":{"source":"iana","extensions":["ez2"]},"application/vnd.ezpix-package":{"source":"iana","extensions":["ez3"]},"application/vnd.f-secure.mobile":{"source":"iana"},"application/vnd.familysearch.gedcom+zip":{"source":"iana","compressible":false},"application/vnd.fastcopy-disk-image":{"source":"iana"},"application/vnd.fdf":{"source":"iana","extensions":["fdf"]},"application/vnd.fdsn.mseed":{"source":"iana","extensions":["mseed"]},"application/vnd.fdsn.seed":{"source":"iana","extensions":["seed","dataless"]},"application/vnd.ffsns":{"source":"iana"},"application/vnd.ficlab.flb+zip":{"source":"iana","compressible":false},"application/vnd.filmit.zfc":{"source":"iana"},"application/vnd.fints":{"source":"iana"},"application/vnd.firemonkeys.cloudcell":{"source":"iana"},"application/vnd.flographit":{"source":"iana","extensions":["gph"]},"application/vnd.fluxtime.clip":{"source":"iana","extensions":["ftc"]},"application/vnd.font-fontforge-sfd":{"source":"iana"},"application/vnd.framemaker":{"source":"iana","extensions":["fm","frame","maker","book"]},"application/vnd.frogans.fnc":{"source":"iana","extensions":["fnc"]},"application/vnd.frogans.ltf":{"source":"iana","extensions":["ltf"]},"application/vnd.fsc.weblaunch":{"source":"iana","extensions":["fsc"]},"application/vnd.fujifilm.fb.docuworks":{"source":"iana"},"application/vnd.fujifilm.fb.docuworks.binder":{"source":"iana"},"application/vnd.fujifilm.fb.docuworks.container":{"source":"iana"},"application/vnd.fujifilm.fb.jfi+xml":{"source":"iana","compressible":true},"application/vnd.fujitsu.oasys":{"source":"iana","extensions":["oas"]},"application/vnd.fujitsu.oasys2":{"source":"iana","extensions":["oa2"]},"application/vnd.fujitsu.oasys3":{"source":"iana","extensions":["oa3"]},"application/vnd.fujitsu.oasysgp":{"source":"iana","extensions":["fg5"]},"application/vnd.fujitsu.oasysprs":{"source":"iana","extensions":["bh2"]},"application/vnd.fujixerox.art-ex":{"source":"iana"},"application/vnd.fujixerox.art4":{"source":"iana"},"application/vnd.fujixerox.ddd":{"source":"iana","extensions":["ddd"]},"application/vnd.fujixerox.docuworks":{"source":"iana","extensions":["xdw"]},"application/vnd.fujixerox.docuworks.binder":{"source":"iana","extensions":["xbd"]},"application/vnd.fujixerox.docuworks.container":{"source":"iana"},"application/vnd.fujixerox.hbpl":{"source":"iana"},"application/vnd.fut-misnet":{"source":"iana"},"application/vnd.futoin+cbor":{"source":"iana"},"application/vnd.futoin+json":{"source":"iana","compressible":true},"application/vnd.fuzzysheet":{"source":"iana","extensions":["fzs"]},"application/vnd.genomatix.tuxedo":{"source":"iana","extensions":["txd"]},"application/vnd.gentics.grd+json":{"source":"iana","compressible":true},"application/vnd.geo+json":{"source":"iana","compressible":true},"application/vnd.geocube+xml":{"source":"iana","compressible":true},"application/vnd.geogebra.file":{"source":"iana","extensions":["ggb"]},"application/vnd.geogebra.slides":{"source":"iana"},"application/vnd.geogebra.tool":{"source":"iana","extensions":["ggt"]},"application/vnd.geometry-explorer":{"source":"iana","extensions":["gex","gre"]},"application/vnd.geonext":{"source":"iana","extensions":["gxt"]},"application/vnd.geoplan":{"source":"iana","extensions":["g2w"]},"application/vnd.geospace":{"source":"iana","extensions":["g3w"]},"application/vnd.gerber":{"source":"iana"},"application/vnd.globalplatform.card-content-mgt":{"source":"iana"},"application/vnd.globalplatform.card-content-mgt-response":{"source":"iana"},"application/vnd.gmx":{"source":"iana","extensions":["gmx"]},"application/vnd.google-apps.document":{"compressible":false,"extensions":["gdoc"]},"application/vnd.google-apps.presentation":{"compressible":false,"extensions":["gslides"]},"application/vnd.google-apps.spreadsheet":{"compressible":false,"extensions":["gsheet"]},"application/vnd.google-earth.kml+xml":{"source":"iana","compressible":true,"extensions":["kml"]},"application/vnd.google-earth.kmz":{"source":"iana","compressible":false,"extensions":["kmz"]},"application/vnd.gov.sk.e-form+xml":{"source":"iana","compressible":true},"application/vnd.gov.sk.e-form+zip":{"source":"iana","compressible":false},"application/vnd.gov.sk.xmldatacontainer+xml":{"source":"iana","compressible":true},"application/vnd.grafeq":{"source":"iana","extensions":["gqf","gqs"]},"application/vnd.gridmp":{"source":"iana"},"application/vnd.groove-account":{"source":"iana","extensions":["gac"]},"application/vnd.groove-help":{"source":"iana","extensions":["ghf"]},"application/vnd.groove-identity-message":{"source":"iana","extensions":["gim"]},"application/vnd.groove-injector":{"source":"iana","extensions":["grv"]},"application/vnd.groove-tool-message":{"source":"iana","extensions":["gtm"]},"application/vnd.groove-tool-template":{"source":"iana","extensions":["tpl"]},"application/vnd.groove-vcard":{"source":"iana","extensions":["vcg"]},"application/vnd.hal+json":{"source":"iana","compressible":true},"application/vnd.hal+xml":{"source":"iana","compressible":true,"extensions":["hal"]},"application/vnd.handheld-entertainment+xml":{"source":"iana","compressible":true,"extensions":["zmm"]},"application/vnd.hbci":{"source":"iana","extensions":["hbci"]},"application/vnd.hc+json":{"source":"iana","compressible":true},"application/vnd.hcl-bireports":{"source":"iana"},"application/vnd.hdt":{"source":"iana"},"application/vnd.heroku+json":{"source":"iana","compressible":true},"application/vnd.hhe.lesson-player":{"source":"iana","extensions":["les"]},"application/vnd.hl7cda+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.hl7v2+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.hp-hpgl":{"source":"iana","extensions":["hpgl"]},"application/vnd.hp-hpid":{"source":"iana","extensions":["hpid"]},"application/vnd.hp-hps":{"source":"iana","extensions":["hps"]},"application/vnd.hp-jlyt":{"source":"iana","extensions":["jlt"]},"application/vnd.hp-pcl":{"source":"iana","extensions":["pcl"]},"application/vnd.hp-pclxl":{"source":"iana","extensions":["pclxl"]},"application/vnd.httphone":{"source":"iana"},"application/vnd.hydrostatix.sof-data":{"source":"iana","extensions":["sfd-hdstx"]},"application/vnd.hyper+json":{"source":"iana","compressible":true},"application/vnd.hyper-item+json":{"source":"iana","compressible":true},"application/vnd.hyperdrive+json":{"source":"iana","compressible":true},"application/vnd.hzn-3d-crossword":{"source":"iana"},"application/vnd.ibm.afplinedata":{"source":"iana"},"application/vnd.ibm.electronic-media":{"source":"iana"},"application/vnd.ibm.minipay":{"source":"iana","extensions":["mpy"]},"application/vnd.ibm.modcap":{"source":"iana","extensions":["afp","listafp","list3820"]},"application/vnd.ibm.rights-management":{"source":"iana","extensions":["irm"]},"application/vnd.ibm.secure-container":{"source":"iana","extensions":["sc"]},"application/vnd.iccprofile":{"source":"iana","extensions":["icc","icm"]},"application/vnd.ieee.1905":{"source":"iana"},"application/vnd.igloader":{"source":"iana","extensions":["igl"]},"application/vnd.imagemeter.folder+zip":{"source":"iana","compressible":false},"application/vnd.imagemeter.image+zip":{"source":"iana","compressible":false},"application/vnd.immervision-ivp":{"source":"iana","extensions":["ivp"]},"application/vnd.immervision-ivu":{"source":"iana","extensions":["ivu"]},"application/vnd.ims.imsccv1p1":{"source":"iana"},"application/vnd.ims.imsccv1p2":{"source":"iana"},"application/vnd.ims.imsccv1p3":{"source":"iana"},"application/vnd.ims.lis.v2.result+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolconsumerprofile+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolproxy+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolproxy.id+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolsettings+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolsettings.simple+json":{"source":"iana","compressible":true},"application/vnd.informedcontrol.rms+xml":{"source":"iana","compressible":true},"application/vnd.informix-visionary":{"source":"iana"},"application/vnd.infotech.project":{"source":"iana"},"application/vnd.infotech.project+xml":{"source":"iana","compressible":true},"application/vnd.innopath.wamp.notification":{"source":"iana"},"application/vnd.insors.igm":{"source":"iana","extensions":["igm"]},"application/vnd.intercon.formnet":{"source":"iana","extensions":["xpw","xpx"]},"application/vnd.intergeo":{"source":"iana","extensions":["i2g"]},"application/vnd.intertrust.digibox":{"source":"iana"},"application/vnd.intertrust.nncp":{"source":"iana"},"application/vnd.intu.qbo":{"source":"iana","extensions":["qbo"]},"application/vnd.intu.qfx":{"source":"iana","extensions":["qfx"]},"application/vnd.iptc.g2.catalogitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.conceptitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.knowledgeitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.newsitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.newsmessage+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.packageitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.planningitem+xml":{"source":"iana","compressible":true},"application/vnd.ipunplugged.rcprofile":{"source":"iana","extensions":["rcprofile"]},"application/vnd.irepository.package+xml":{"source":"iana","compressible":true,"extensions":["irp"]},"application/vnd.is-xpr":{"source":"iana","extensions":["xpr"]},"application/vnd.isac.fcs":{"source":"iana","extensions":["fcs"]},"application/vnd.iso11783-10+zip":{"source":"iana","compressible":false},"application/vnd.jam":{"source":"iana","extensions":["jam"]},"application/vnd.japannet-directory-service":{"source":"iana"},"application/vnd.japannet-jpnstore-wakeup":{"source":"iana"},"application/vnd.japannet-payment-wakeup":{"source":"iana"},"application/vnd.japannet-registration":{"source":"iana"},"application/vnd.japannet-registration-wakeup":{"source":"iana"},"application/vnd.japannet-setstore-wakeup":{"source":"iana"},"application/vnd.japannet-verification":{"source":"iana"},"application/vnd.japannet-verification-wakeup":{"source":"iana"},"application/vnd.jcp.javame.midlet-rms":{"source":"iana","extensions":["rms"]},"application/vnd.jisp":{"source":"iana","extensions":["jisp"]},"application/vnd.joost.joda-archive":{"source":"iana","extensions":["joda"]},"application/vnd.jsk.isdn-ngn":{"source":"iana"},"application/vnd.kahootz":{"source":"iana","extensions":["ktz","ktr"]},"application/vnd.kde.karbon":{"source":"iana","extensions":["karbon"]},"application/vnd.kde.kchart":{"source":"iana","extensions":["chrt"]},"application/vnd.kde.kformula":{"source":"iana","extensions":["kfo"]},"application/vnd.kde.kivio":{"source":"iana","extensions":["flw"]},"application/vnd.kde.kontour":{"source":"iana","extensions":["kon"]},"application/vnd.kde.kpresenter":{"source":"iana","extensions":["kpr","kpt"]},"application/vnd.kde.kspread":{"source":"iana","extensions":["ksp"]},"application/vnd.kde.kword":{"source":"iana","extensions":["kwd","kwt"]},"application/vnd.kenameaapp":{"source":"iana","extensions":["htke"]},"application/vnd.kidspiration":{"source":"iana","extensions":["kia"]},"application/vnd.kinar":{"source":"iana","extensions":["kne","knp"]},"application/vnd.koan":{"source":"iana","extensions":["skp","skd","skt","skm"]},"application/vnd.kodak-descriptor":{"source":"iana","extensions":["sse"]},"application/vnd.las":{"source":"iana"},"application/vnd.las.las+json":{"source":"iana","compressible":true},"application/vnd.las.las+xml":{"source":"iana","compressible":true,"extensions":["lasxml"]},"application/vnd.laszip":{"source":"iana"},"application/vnd.leap+json":{"source":"iana","compressible":true},"application/vnd.liberty-request+xml":{"source":"iana","compressible":true},"application/vnd.llamagraphics.life-balance.desktop":{"source":"iana","extensions":["lbd"]},"application/vnd.llamagraphics.life-balance.exchange+xml":{"source":"iana","compressible":true,"extensions":["lbe"]},"application/vnd.logipipe.circuit+zip":{"source":"iana","compressible":false},"application/vnd.loom":{"source":"iana"},"application/vnd.lotus-1-2-3":{"source":"iana","extensions":["123"]},"application/vnd.lotus-approach":{"source":"iana","extensions":["apr"]},"application/vnd.lotus-freelance":{"source":"iana","extensions":["pre"]},"application/vnd.lotus-notes":{"source":"iana","extensions":["nsf"]},"application/vnd.lotus-organizer":{"source":"iana","extensions":["org"]},"application/vnd.lotus-screencam":{"source":"iana","extensions":["scm"]},"application/vnd.lotus-wordpro":{"source":"iana","extensions":["lwp"]},"application/vnd.macports.portpkg":{"source":"iana","extensions":["portpkg"]},"application/vnd.mapbox-vector-tile":{"source":"iana","extensions":["mvt"]},"application/vnd.marlin.drm.actiontoken+xml":{"source":"iana","compressible":true},"application/vnd.marlin.drm.conftoken+xml":{"source":"iana","compressible":true},"application/vnd.marlin.drm.license+xml":{"source":"iana","compressible":true},"application/vnd.marlin.drm.mdcf":{"source":"iana"},"application/vnd.mason+json":{"source":"iana","compressible":true},"application/vnd.maxar.archive.3tz+zip":{"source":"iana","compressible":false},"application/vnd.maxmind.maxmind-db":{"source":"iana"},"application/vnd.mcd":{"source":"iana","extensions":["mcd"]},"application/vnd.medcalcdata":{"source":"iana","extensions":["mc1"]},"application/vnd.mediastation.cdkey":{"source":"iana","extensions":["cdkey"]},"application/vnd.meridian-slingshot":{"source":"iana"},"application/vnd.mfer":{"source":"iana","extensions":["mwf"]},"application/vnd.mfmp":{"source":"iana","extensions":["mfm"]},"application/vnd.micro+json":{"source":"iana","compressible":true},"application/vnd.micrografx.flo":{"source":"iana","extensions":["flo"]},"application/vnd.micrografx.igx":{"source":"iana","extensions":["igx"]},"application/vnd.microsoft.portable-executable":{"source":"iana"},"application/vnd.microsoft.windows.thumbnail-cache":{"source":"iana"},"application/vnd.miele+json":{"source":"iana","compressible":true},"application/vnd.mif":{"source":"iana","extensions":["mif"]},"application/vnd.minisoft-hp3000-save":{"source":"iana"},"application/vnd.mitsubishi.misty-guard.trustweb":{"source":"iana"},"application/vnd.mobius.daf":{"source":"iana","extensions":["daf"]},"application/vnd.mobius.dis":{"source":"iana","extensions":["dis"]},"application/vnd.mobius.mbk":{"source":"iana","extensions":["mbk"]},"application/vnd.mobius.mqy":{"source":"iana","extensions":["mqy"]},"application/vnd.mobius.msl":{"source":"iana","extensions":["msl"]},"application/vnd.mobius.plc":{"source":"iana","extensions":["plc"]},"application/vnd.mobius.txf":{"source":"iana","extensions":["txf"]},"application/vnd.mophun.application":{"source":"iana","extensions":["mpn"]},"application/vnd.mophun.certificate":{"source":"iana","extensions":["mpc"]},"application/vnd.motorola.flexsuite":{"source":"iana"},"application/vnd.motorola.flexsuite.adsi":{"source":"iana"},"application/vnd.motorola.flexsuite.fis":{"source":"iana"},"application/vnd.motorola.flexsuite.gotap":{"source":"iana"},"application/vnd.motorola.flexsuite.kmr":{"source":"iana"},"application/vnd.motorola.flexsuite.ttc":{"source":"iana"},"application/vnd.motorola.flexsuite.wem":{"source":"iana"},"application/vnd.motorola.iprm":{"source":"iana"},"application/vnd.mozilla.xul+xml":{"source":"iana","compressible":true,"extensions":["xul"]},"application/vnd.ms-3mfdocument":{"source":"iana"},"application/vnd.ms-artgalry":{"source":"iana","extensions":["cil"]},"application/vnd.ms-asf":{"source":"iana"},"application/vnd.ms-cab-compressed":{"source":"iana","extensions":["cab"]},"application/vnd.ms-color.iccprofile":{"source":"apache"},"application/vnd.ms-excel":{"source":"iana","compressible":false,"extensions":["xls","xlm","xla","xlc","xlt","xlw"]},"application/vnd.ms-excel.addin.macroenabled.12":{"source":"iana","extensions":["xlam"]},"application/vnd.ms-excel.sheet.binary.macroenabled.12":{"source":"iana","extensions":["xlsb"]},"application/vnd.ms-excel.sheet.macroenabled.12":{"source":"iana","extensions":["xlsm"]},"application/vnd.ms-excel.template.macroenabled.12":{"source":"iana","extensions":["xltm"]},"application/vnd.ms-fontobject":{"source":"iana","compressible":true,"extensions":["eot"]},"application/vnd.ms-htmlhelp":{"source":"iana","extensions":["chm"]},"application/vnd.ms-ims":{"source":"iana","extensions":["ims"]},"application/vnd.ms-lrm":{"source":"iana","extensions":["lrm"]},"application/vnd.ms-office.activex+xml":{"source":"iana","compressible":true},"application/vnd.ms-officetheme":{"source":"iana","extensions":["thmx"]},"application/vnd.ms-opentype":{"source":"apache","compressible":true},"application/vnd.ms-outlook":{"compressible":false,"extensions":["msg"]},"application/vnd.ms-package.obfuscated-opentype":{"source":"apache"},"application/vnd.ms-pki.seccat":{"source":"apache","extensions":["cat"]},"application/vnd.ms-pki.stl":{"source":"apache","extensions":["stl"]},"application/vnd.ms-playready.initiator+xml":{"source":"iana","compressible":true},"application/vnd.ms-powerpoint":{"source":"iana","compressible":false,"extensions":["ppt","pps","pot"]},"application/vnd.ms-powerpoint.addin.macroenabled.12":{"source":"iana","extensions":["ppam"]},"application/vnd.ms-powerpoint.presentation.macroenabled.12":{"source":"iana","extensions":["pptm"]},"application/vnd.ms-powerpoint.slide.macroenabled.12":{"source":"iana","extensions":["sldm"]},"application/vnd.ms-powerpoint.slideshow.macroenabled.12":{"source":"iana","extensions":["ppsm"]},"application/vnd.ms-powerpoint.template.macroenabled.12":{"source":"iana","extensions":["potm"]},"application/vnd.ms-printdevicecapabilities+xml":{"source":"iana","compressible":true},"application/vnd.ms-printing.printticket+xml":{"source":"apache","compressible":true},"application/vnd.ms-printschematicket+xml":{"source":"iana","compressible":true},"application/vnd.ms-project":{"source":"iana","extensions":["mpp","mpt"]},"application/vnd.ms-tnef":{"source":"iana"},"application/vnd.ms-windows.devicepairing":{"source":"iana"},"application/vnd.ms-windows.nwprinting.oob":{"source":"iana"},"application/vnd.ms-windows.printerpairing":{"source":"iana"},"application/vnd.ms-windows.wsd.oob":{"source":"iana"},"application/vnd.ms-wmdrm.lic-chlg-req":{"source":"iana"},"application/vnd.ms-wmdrm.lic-resp":{"source":"iana"},"application/vnd.ms-wmdrm.meter-chlg-req":{"source":"iana"},"application/vnd.ms-wmdrm.meter-resp":{"source":"iana"},"application/vnd.ms-word.document.macroenabled.12":{"source":"iana","extensions":["docm"]},"application/vnd.ms-word.template.macroenabled.12":{"source":"iana","extensions":["dotm"]},"application/vnd.ms-works":{"source":"iana","extensions":["wps","wks","wcm","wdb"]},"application/vnd.ms-wpl":{"source":"iana","extensions":["wpl"]},"application/vnd.ms-xpsdocument":{"source":"iana","compressible":false,"extensions":["xps"]},"application/vnd.msa-disk-image":{"source":"iana"},"application/vnd.mseq":{"source":"iana","extensions":["mseq"]},"application/vnd.msign":{"source":"iana"},"application/vnd.multiad.creator":{"source":"iana"},"application/vnd.multiad.creator.cif":{"source":"iana"},"application/vnd.music-niff":{"source":"iana"},"application/vnd.musician":{"source":"iana","extensions":["mus"]},"application/vnd.muvee.style":{"source":"iana","extensions":["msty"]},"application/vnd.mynfc":{"source":"iana","extensions":["taglet"]},"application/vnd.nacamar.ybrid+json":{"source":"iana","compressible":true},"application/vnd.ncd.control":{"source":"iana"},"application/vnd.ncd.reference":{"source":"iana"},"application/vnd.nearst.inv+json":{"source":"iana","compressible":true},"application/vnd.nebumind.line":{"source":"iana"},"application/vnd.nervana":{"source":"iana"},"application/vnd.netfpx":{"source":"iana"},"application/vnd.neurolanguage.nlu":{"source":"iana","extensions":["nlu"]},"application/vnd.nimn":{"source":"iana"},"application/vnd.nintendo.nitro.rom":{"source":"iana"},"application/vnd.nintendo.snes.rom":{"source":"iana"},"application/vnd.nitf":{"source":"iana","extensions":["ntf","nitf"]},"application/vnd.noblenet-directory":{"source":"iana","extensions":["nnd"]},"application/vnd.noblenet-sealer":{"source":"iana","extensions":["nns"]},"application/vnd.noblenet-web":{"source":"iana","extensions":["nnw"]},"application/vnd.nokia.catalogs":{"source":"iana"},"application/vnd.nokia.conml+wbxml":{"source":"iana"},"application/vnd.nokia.conml+xml":{"source":"iana","compressible":true},"application/vnd.nokia.iptv.config+xml":{"source":"iana","compressible":true},"application/vnd.nokia.isds-radio-presets":{"source":"iana"},"application/vnd.nokia.landmark+wbxml":{"source":"iana"},"application/vnd.nokia.landmark+xml":{"source":"iana","compressible":true},"application/vnd.nokia.landmarkcollection+xml":{"source":"iana","compressible":true},"application/vnd.nokia.n-gage.ac+xml":{"source":"iana","compressible":true,"extensions":["ac"]},"application/vnd.nokia.n-gage.data":{"source":"iana","extensions":["ngdat"]},"application/vnd.nokia.n-gage.symbian.install":{"source":"iana","extensions":["n-gage"]},"application/vnd.nokia.ncd":{"source":"iana"},"application/vnd.nokia.pcd+wbxml":{"source":"iana"},"application/vnd.nokia.pcd+xml":{"source":"iana","compressible":true},"application/vnd.nokia.radio-preset":{"source":"iana","extensions":["rpst"]},"application/vnd.nokia.radio-presets":{"source":"iana","extensions":["rpss"]},"application/vnd.novadigm.edm":{"source":"iana","extensions":["edm"]},"application/vnd.novadigm.edx":{"source":"iana","extensions":["edx"]},"application/vnd.novadigm.ext":{"source":"iana","extensions":["ext"]},"application/vnd.ntt-local.content-share":{"source":"iana"},"application/vnd.ntt-local.file-transfer":{"source":"iana"},"application/vnd.ntt-local.ogw_remote-access":{"source":"iana"},"application/vnd.ntt-local.sip-ta_remote":{"source":"iana"},"application/vnd.ntt-local.sip-ta_tcp_stream":{"source":"iana"},"application/vnd.oasis.opendocument.chart":{"source":"iana","extensions":["odc"]},"application/vnd.oasis.opendocument.chart-template":{"source":"iana","extensions":["otc"]},"application/vnd.oasis.opendocument.database":{"source":"iana","extensions":["odb"]},"application/vnd.oasis.opendocument.formula":{"source":"iana","extensions":["odf"]},"application/vnd.oasis.opendocument.formula-template":{"source":"iana","extensions":["odft"]},"application/vnd.oasis.opendocument.graphics":{"source":"iana","compressible":false,"extensions":["odg"]},"application/vnd.oasis.opendocument.graphics-template":{"source":"iana","extensions":["otg"]},"application/vnd.oasis.opendocument.image":{"source":"iana","extensions":["odi"]},"application/vnd.oasis.opendocument.image-template":{"source":"iana","extensions":["oti"]},"application/vnd.oasis.opendocument.presentation":{"source":"iana","compressible":false,"extensions":["odp"]},"application/vnd.oasis.opendocument.presentation-template":{"source":"iana","extensions":["otp"]},"application/vnd.oasis.opendocument.spreadsheet":{"source":"iana","compressible":false,"extensions":["ods"]},"application/vnd.oasis.opendocument.spreadsheet-template":{"source":"iana","extensions":["ots"]},"application/vnd.oasis.opendocument.text":{"source":"iana","compressible":false,"extensions":["odt"]},"application/vnd.oasis.opendocument.text-master":{"source":"iana","extensions":["odm"]},"application/vnd.oasis.opendocument.text-template":{"source":"iana","extensions":["ott"]},"application/vnd.oasis.opendocument.text-web":{"source":"iana","extensions":["oth"]},"application/vnd.obn":{"source":"iana"},"application/vnd.ocf+cbor":{"source":"iana"},"application/vnd.oci.image.manifest.v1+json":{"source":"iana","compressible":true},"application/vnd.oftn.l10n+json":{"source":"iana","compressible":true},"application/vnd.oipf.contentaccessdownload+xml":{"source":"iana","compressible":true},"application/vnd.oipf.contentaccessstreaming+xml":{"source":"iana","compressible":true},"application/vnd.oipf.cspg-hexbinary":{"source":"iana"},"application/vnd.oipf.dae.svg+xml":{"source":"iana","compressible":true},"application/vnd.oipf.dae.xhtml+xml":{"source":"iana","compressible":true},"application/vnd.oipf.mippvcontrolmessage+xml":{"source":"iana","compressible":true},"application/vnd.oipf.pae.gem":{"source":"iana"},"application/vnd.oipf.spdiscovery+xml":{"source":"iana","compressible":true},"application/vnd.oipf.spdlist+xml":{"source":"iana","compressible":true},"application/vnd.oipf.ueprofile+xml":{"source":"iana","compressible":true},"application/vnd.oipf.userprofile+xml":{"source":"iana","compressible":true},"application/vnd.olpc-sugar":{"source":"iana","extensions":["xo"]},"application/vnd.oma-scws-config":{"source":"iana"},"application/vnd.oma-scws-http-request":{"source":"iana"},"application/vnd.oma-scws-http-response":{"source":"iana"},"application/vnd.oma.bcast.associated-procedure-parameter+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.drm-trigger+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.imd+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.ltkm":{"source":"iana"},"application/vnd.oma.bcast.notification+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.provisioningtrigger":{"source":"iana"},"application/vnd.oma.bcast.sgboot":{"source":"iana"},"application/vnd.oma.bcast.sgdd+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.sgdu":{"source":"iana"},"application/vnd.oma.bcast.simple-symbol-container":{"source":"iana"},"application/vnd.oma.bcast.smartcard-trigger+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.sprov+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.stkm":{"source":"iana"},"application/vnd.oma.cab-address-book+xml":{"source":"iana","compressible":true},"application/vnd.oma.cab-feature-handler+xml":{"source":"iana","compressible":true},"application/vnd.oma.cab-pcc+xml":{"source":"iana","compressible":true},"application/vnd.oma.cab-subs-invite+xml":{"source":"iana","compressible":true},"application/vnd.oma.cab-user-prefs+xml":{"source":"iana","compressible":true},"application/vnd.oma.dcd":{"source":"iana"},"application/vnd.oma.dcdc":{"source":"iana"},"application/vnd.oma.dd2+xml":{"source":"iana","compressible":true,"extensions":["dd2"]},"application/vnd.oma.drm.risd+xml":{"source":"iana","compressible":true},"application/vnd.oma.group-usage-list+xml":{"source":"iana","compressible":true},"application/vnd.oma.lwm2m+cbor":{"source":"iana"},"application/vnd.oma.lwm2m+json":{"source":"iana","compressible":true},"application/vnd.oma.lwm2m+tlv":{"source":"iana"},"application/vnd.oma.pal+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.detailed-progress-report+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.final-report+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.groups+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.invocation-descriptor+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.optimized-progress-report+xml":{"source":"iana","compressible":true},"application/vnd.oma.push":{"source":"iana"},"application/vnd.oma.scidm.messages+xml":{"source":"iana","compressible":true},"application/vnd.oma.xcap-directory+xml":{"source":"iana","compressible":true},"application/vnd.omads-email+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.omads-file+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.omads-folder+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.omaloc-supl-init":{"source":"iana"},"application/vnd.onepager":{"source":"iana"},"application/vnd.onepagertamp":{"source":"iana"},"application/vnd.onepagertamx":{"source":"iana"},"application/vnd.onepagertat":{"source":"iana"},"application/vnd.onepagertatp":{"source":"iana"},"application/vnd.onepagertatx":{"source":"iana"},"application/vnd.openblox.game+xml":{"source":"iana","compressible":true,"extensions":["obgx"]},"application/vnd.openblox.game-binary":{"source":"iana"},"application/vnd.openeye.oeb":{"source":"iana"},"application/vnd.openofficeorg.extension":{"source":"apache","extensions":["oxt"]},"application/vnd.openstreetmap.data+xml":{"source":"iana","compressible":true,"extensions":["osm"]},"application/vnd.opentimestamps.ots":{"source":"iana"},"application/vnd.openxmlformats-officedocument.custom-properties+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.customxmlproperties+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawing+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.chart+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.extended-properties+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.comments+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.presentation":{"source":"iana","compressible":false,"extensions":["pptx"]},"application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.presprops+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slide":{"source":"iana","extensions":["sldx"]},"application/vnd.openxmlformats-officedocument.presentationml.slide+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slideshow":{"source":"iana","extensions":["ppsx"]},"application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.tags+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.template":{"source":"iana","extensions":["potx"]},"application/vnd.openxmlformats-officedocument.presentationml.template.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"source":"iana","compressible":false,"extensions":["xlsx"]},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.template":{"source":"iana","extensions":["xltx"]},"application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.theme+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.themeoverride+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.vmldrawing":{"source":"iana"},"application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.document":{"source":"iana","compressible":false,"extensions":["docx"]},"application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.template":{"source":"iana","extensions":["dotx"]},"application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-package.core-properties+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-package.relationships+xml":{"source":"iana","compressible":true},"application/vnd.oracle.resource+json":{"source":"iana","compressible":true},"application/vnd.orange.indata":{"source":"iana"},"application/vnd.osa.netdeploy":{"source":"iana"},"application/vnd.osgeo.mapguide.package":{"source":"iana","extensions":["mgp"]},"application/vnd.osgi.bundle":{"source":"iana"},"application/vnd.osgi.dp":{"source":"iana","extensions":["dp"]},"application/vnd.osgi.subsystem":{"source":"iana","extensions":["esa"]},"application/vnd.otps.ct-kip+xml":{"source":"iana","compressible":true},"application/vnd.oxli.countgraph":{"source":"iana"},"application/vnd.pagerduty+json":{"source":"iana","compressible":true},"application/vnd.palm":{"source":"iana","extensions":["pdb","pqa","oprc"]},"application/vnd.panoply":{"source":"iana"},"application/vnd.paos.xml":{"source":"iana"},"application/vnd.patentdive":{"source":"iana"},"application/vnd.patientecommsdoc":{"source":"iana"},"application/vnd.pawaafile":{"source":"iana","extensions":["paw"]},"application/vnd.pcos":{"source":"iana"},"application/vnd.pg.format":{"source":"iana","extensions":["str"]},"application/vnd.pg.osasli":{"source":"iana","extensions":["ei6"]},"application/vnd.piaccess.application-licence":{"source":"iana"},"application/vnd.picsel":{"source":"iana","extensions":["efif"]},"application/vnd.pmi.widget":{"source":"iana","extensions":["wg"]},"application/vnd.poc.group-advertisement+xml":{"source":"iana","compressible":true},"application/vnd.pocketlearn":{"source":"iana","extensions":["plf"]},"application/vnd.powerbuilder6":{"source":"iana","extensions":["pbd"]},"application/vnd.powerbuilder6-s":{"source":"iana"},"application/vnd.powerbuilder7":{"source":"iana"},"application/vnd.powerbuilder7-s":{"source":"iana"},"application/vnd.powerbuilder75":{"source":"iana"},"application/vnd.powerbuilder75-s":{"source":"iana"},"application/vnd.preminet":{"source":"iana"},"application/vnd.previewsystems.box":{"source":"iana","extensions":["box"]},"application/vnd.proteus.magazine":{"source":"iana","extensions":["mgz"]},"application/vnd.psfs":{"source":"iana"},"application/vnd.publishare-delta-tree":{"source":"iana","extensions":["qps"]},"application/vnd.pvi.ptid1":{"source":"iana","extensions":["ptid"]},"application/vnd.pwg-multiplexed":{"source":"iana"},"application/vnd.pwg-xhtml-print+xml":{"source":"iana","compressible":true},"application/vnd.qualcomm.brew-app-res":{"source":"iana"},"application/vnd.quarantainenet":{"source":"iana"},"application/vnd.quark.quarkxpress":{"source":"iana","extensions":["qxd","qxt","qwd","qwt","qxl","qxb"]},"application/vnd.quobject-quoxdocument":{"source":"iana"},"application/vnd.radisys.moml+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit-conf+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit-conn+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit-dialog+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit-stream+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-conf+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-base+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-fax-detect+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-fax-sendrecv+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-group+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-speech+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-transform+xml":{"source":"iana","compressible":true},"application/vnd.rainstor.data":{"source":"iana"},"application/vnd.rapid":{"source":"iana"},"application/vnd.rar":{"source":"iana","extensions":["rar"]},"application/vnd.realvnc.bed":{"source":"iana","extensions":["bed"]},"application/vnd.recordare.musicxml":{"source":"iana","extensions":["mxl"]},"application/vnd.recordare.musicxml+xml":{"source":"iana","compressible":true,"extensions":["musicxml"]},"application/vnd.renlearn.rlprint":{"source":"iana"},"application/vnd.resilient.logic":{"source":"iana"},"application/vnd.restful+json":{"source":"iana","compressible":true},"application/vnd.rig.cryptonote":{"source":"iana","extensions":["cryptonote"]},"application/vnd.rim.cod":{"source":"apache","extensions":["cod"]},"application/vnd.rn-realmedia":{"source":"apache","extensions":["rm"]},"application/vnd.rn-realmedia-vbr":{"source":"apache","extensions":["rmvb"]},"application/vnd.route66.link66+xml":{"source":"iana","compressible":true,"extensions":["link66"]},"application/vnd.rs-274x":{"source":"iana"},"application/vnd.ruckus.download":{"source":"iana"},"application/vnd.s3sms":{"source":"iana"},"application/vnd.sailingtracker.track":{"source":"iana","extensions":["st"]},"application/vnd.sar":{"source":"iana"},"application/vnd.sbm.cid":{"source":"iana"},"application/vnd.sbm.mid2":{"source":"iana"},"application/vnd.scribus":{"source":"iana"},"application/vnd.sealed.3df":{"source":"iana"},"application/vnd.sealed.csf":{"source":"iana"},"application/vnd.sealed.doc":{"source":"iana"},"application/vnd.sealed.eml":{"source":"iana"},"application/vnd.sealed.mht":{"source":"iana"},"application/vnd.sealed.net":{"source":"iana"},"application/vnd.sealed.ppt":{"source":"iana"},"application/vnd.sealed.tiff":{"source":"iana"},"application/vnd.sealed.xls":{"source":"iana"},"application/vnd.sealedmedia.softseal.html":{"source":"iana"},"application/vnd.sealedmedia.softseal.pdf":{"source":"iana"},"application/vnd.seemail":{"source":"iana","extensions":["see"]},"application/vnd.seis+json":{"source":"iana","compressible":true},"application/vnd.sema":{"source":"iana","extensions":["sema"]},"application/vnd.semd":{"source":"iana","extensions":["semd"]},"application/vnd.semf":{"source":"iana","extensions":["semf"]},"application/vnd.shade-save-file":{"source":"iana"},"application/vnd.shana.informed.formdata":{"source":"iana","extensions":["ifm"]},"application/vnd.shana.informed.formtemplate":{"source":"iana","extensions":["itp"]},"application/vnd.shana.informed.interchange":{"source":"iana","extensions":["iif"]},"application/vnd.shana.informed.package":{"source":"iana","extensions":["ipk"]},"application/vnd.shootproof+json":{"source":"iana","compressible":true},"application/vnd.shopkick+json":{"source":"iana","compressible":true},"application/vnd.shp":{"source":"iana"},"application/vnd.shx":{"source":"iana"},"application/vnd.sigrok.session":{"source":"iana"},"application/vnd.simtech-mindmapper":{"source":"iana","extensions":["twd","twds"]},"application/vnd.siren+json":{"source":"iana","compressible":true},"application/vnd.smaf":{"source":"iana","extensions":["mmf"]},"application/vnd.smart.notebook":{"source":"iana"},"application/vnd.smart.teacher":{"source":"iana","extensions":["teacher"]},"application/vnd.snesdev-page-table":{"source":"iana"},"application/vnd.software602.filler.form+xml":{"source":"iana","compressible":true,"extensions":["fo"]},"application/vnd.software602.filler.form-xml-zip":{"source":"iana"},"application/vnd.solent.sdkm+xml":{"source":"iana","compressible":true,"extensions":["sdkm","sdkd"]},"application/vnd.spotfire.dxp":{"source":"iana","extensions":["dxp"]},"application/vnd.spotfire.sfs":{"source":"iana","extensions":["sfs"]},"application/vnd.sqlite3":{"source":"iana"},"application/vnd.sss-cod":{"source":"iana"},"application/vnd.sss-dtf":{"source":"iana"},"application/vnd.sss-ntf":{"source":"iana"},"application/vnd.stardivision.calc":{"source":"apache","extensions":["sdc"]},"application/vnd.stardivision.draw":{"source":"apache","extensions":["sda"]},"application/vnd.stardivision.impress":{"source":"apache","extensions":["sdd"]},"application/vnd.stardivision.math":{"source":"apache","extensions":["smf"]},"application/vnd.stardivision.writer":{"source":"apache","extensions":["sdw","vor"]},"application/vnd.stardivision.writer-global":{"source":"apache","extensions":["sgl"]},"application/vnd.stepmania.package":{"source":"iana","extensions":["smzip"]},"application/vnd.stepmania.stepchart":{"source":"iana","extensions":["sm"]},"application/vnd.street-stream":{"source":"iana"},"application/vnd.sun.wadl+xml":{"source":"iana","compressible":true,"extensions":["wadl"]},"application/vnd.sun.xml.calc":{"source":"apache","extensions":["sxc"]},"application/vnd.sun.xml.calc.template":{"source":"apache","extensions":["stc"]},"application/vnd.sun.xml.draw":{"source":"apache","extensions":["sxd"]},"application/vnd.sun.xml.draw.template":{"source":"apache","extensions":["std"]},"application/vnd.sun.xml.impress":{"source":"apache","extensions":["sxi"]},"application/vnd.sun.xml.impress.template":{"source":"apache","extensions":["sti"]},"application/vnd.sun.xml.math":{"source":"apache","extensions":["sxm"]},"application/vnd.sun.xml.writer":{"source":"apache","extensions":["sxw"]},"application/vnd.sun.xml.writer.global":{"source":"apache","extensions":["sxg"]},"application/vnd.sun.xml.writer.template":{"source":"apache","extensions":["stw"]},"application/vnd.sus-calendar":{"source":"iana","extensions":["sus","susp"]},"application/vnd.svd":{"source":"iana","extensions":["svd"]},"application/vnd.swiftview-ics":{"source":"iana"},"application/vnd.sycle+xml":{"source":"iana","compressible":true},"application/vnd.syft+json":{"source":"iana","compressible":true},"application/vnd.symbian.install":{"source":"apache","extensions":["sis","sisx"]},"application/vnd.syncml+xml":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["xsm"]},"application/vnd.syncml.dm+wbxml":{"source":"iana","charset":"UTF-8","extensions":["bdm"]},"application/vnd.syncml.dm+xml":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["xdm"]},"application/vnd.syncml.dm.notification":{"source":"iana"},"application/vnd.syncml.dmddf+wbxml":{"source":"iana"},"application/vnd.syncml.dmddf+xml":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["ddf"]},"application/vnd.syncml.dmtnds+wbxml":{"source":"iana"},"application/vnd.syncml.dmtnds+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.syncml.ds.notification":{"source":"iana"},"application/vnd.tableschema+json":{"source":"iana","compressible":true},"application/vnd.tao.intent-module-archive":{"source":"iana","extensions":["tao"]},"application/vnd.tcpdump.pcap":{"source":"iana","extensions":["pcap","cap","dmp"]},"application/vnd.think-cell.ppttc+json":{"source":"iana","compressible":true},"application/vnd.tmd.mediaflex.api+xml":{"source":"iana","compressible":true},"application/vnd.tml":{"source":"iana"},"application/vnd.tmobile-livetv":{"source":"iana","extensions":["tmo"]},"application/vnd.tri.onesource":{"source":"iana"},"application/vnd.trid.tpt":{"source":"iana","extensions":["tpt"]},"application/vnd.triscape.mxs":{"source":"iana","extensions":["mxs"]},"application/vnd.trueapp":{"source":"iana","extensions":["tra"]},"application/vnd.truedoc":{"source":"iana"},"application/vnd.ubisoft.webplayer":{"source":"iana"},"application/vnd.ufdl":{"source":"iana","extensions":["ufd","ufdl"]},"application/vnd.uiq.theme":{"source":"iana","extensions":["utz"]},"application/vnd.umajin":{"source":"iana","extensions":["umj"]},"application/vnd.unity":{"source":"iana","extensions":["unityweb"]},"application/vnd.uoml+xml":{"source":"iana","compressible":true,"extensions":["uoml"]},"application/vnd.uplanet.alert":{"source":"iana"},"application/vnd.uplanet.alert-wbxml":{"source":"iana"},"application/vnd.uplanet.bearer-choice":{"source":"iana"},"application/vnd.uplanet.bearer-choice-wbxml":{"source":"iana"},"application/vnd.uplanet.cacheop":{"source":"iana"},"application/vnd.uplanet.cacheop-wbxml":{"source":"iana"},"application/vnd.uplanet.channel":{"source":"iana"},"application/vnd.uplanet.channel-wbxml":{"source":"iana"},"application/vnd.uplanet.list":{"source":"iana"},"application/vnd.uplanet.list-wbxml":{"source":"iana"},"application/vnd.uplanet.listcmd":{"source":"iana"},"application/vnd.uplanet.listcmd-wbxml":{"source":"iana"},"application/vnd.uplanet.signal":{"source":"iana"},"application/vnd.uri-map":{"source":"iana"},"application/vnd.valve.source.material":{"source":"iana"},"application/vnd.vcx":{"source":"iana","extensions":["vcx"]},"application/vnd.vd-study":{"source":"iana"},"application/vnd.vectorworks":{"source":"iana"},"application/vnd.vel+json":{"source":"iana","compressible":true},"application/vnd.verimatrix.vcas":{"source":"iana"},"application/vnd.veritone.aion+json":{"source":"iana","compressible":true},"application/vnd.veryant.thin":{"source":"iana"},"application/vnd.ves.encrypted":{"source":"iana"},"application/vnd.vidsoft.vidconference":{"source":"iana"},"application/vnd.visio":{"source":"iana","extensions":["vsd","vst","vss","vsw"]},"application/vnd.visionary":{"source":"iana","extensions":["vis"]},"application/vnd.vividence.scriptfile":{"source":"iana"},"application/vnd.vsf":{"source":"iana","extensions":["vsf"]},"application/vnd.wap.sic":{"source":"iana"},"application/vnd.wap.slc":{"source":"iana"},"application/vnd.wap.wbxml":{"source":"iana","charset":"UTF-8","extensions":["wbxml"]},"application/vnd.wap.wmlc":{"source":"iana","extensions":["wmlc"]},"application/vnd.wap.wmlscriptc":{"source":"iana","extensions":["wmlsc"]},"application/vnd.webturbo":{"source":"iana","extensions":["wtb"]},"application/vnd.wfa.dpp":{"source":"iana"},"application/vnd.wfa.p2p":{"source":"iana"},"application/vnd.wfa.wsc":{"source":"iana"},"application/vnd.windows.devicepairing":{"source":"iana"},"application/vnd.wmc":{"source":"iana"},"application/vnd.wmf.bootstrap":{"source":"iana"},"application/vnd.wolfram.mathematica":{"source":"iana"},"application/vnd.wolfram.mathematica.package":{"source":"iana"},"application/vnd.wolfram.player":{"source":"iana","extensions":["nbp"]},"application/vnd.wordperfect":{"source":"iana","extensions":["wpd"]},"application/vnd.wqd":{"source":"iana","extensions":["wqd"]},"application/vnd.wrq-hp3000-labelled":{"source":"iana"},"application/vnd.wt.stf":{"source":"iana","extensions":["stf"]},"application/vnd.wv.csp+wbxml":{"source":"iana"},"application/vnd.wv.csp+xml":{"source":"iana","compressible":true},"application/vnd.wv.ssp+xml":{"source":"iana","compressible":true},"application/vnd.xacml+json":{"source":"iana","compressible":true},"application/vnd.xara":{"source":"iana","extensions":["xar"]},"application/vnd.xfdl":{"source":"iana","extensions":["xfdl"]},"application/vnd.xfdl.webform":{"source":"iana"},"application/vnd.xmi+xml":{"source":"iana","compressible":true},"application/vnd.xmpie.cpkg":{"source":"iana"},"application/vnd.xmpie.dpkg":{"source":"iana"},"application/vnd.xmpie.plan":{"source":"iana"},"application/vnd.xmpie.ppkg":{"source":"iana"},"application/vnd.xmpie.xlim":{"source":"iana"},"application/vnd.yamaha.hv-dic":{"source":"iana","extensions":["hvd"]},"application/vnd.yamaha.hv-script":{"source":"iana","extensions":["hvs"]},"application/vnd.yamaha.hv-voice":{"source":"iana","extensions":["hvp"]},"application/vnd.yamaha.openscoreformat":{"source":"iana","extensions":["osf"]},"application/vnd.yamaha.openscoreformat.osfpvg+xml":{"source":"iana","compressible":true,"extensions":["osfpvg"]},"application/vnd.yamaha.remote-setup":{"source":"iana"},"application/vnd.yamaha.smaf-audio":{"source":"iana","extensions":["saf"]},"application/vnd.yamaha.smaf-phrase":{"source":"iana","extensions":["spf"]},"application/vnd.yamaha.through-ngn":{"source":"iana"},"application/vnd.yamaha.tunnel-udpencap":{"source":"iana"},"application/vnd.yaoweme":{"source":"iana"},"application/vnd.yellowriver-custom-menu":{"source":"iana","extensions":["cmp"]},"application/vnd.youtube.yt":{"source":"iana"},"application/vnd.zul":{"source":"iana","extensions":["zir","zirz"]},"application/vnd.zzazz.deck+xml":{"source":"iana","compressible":true,"extensions":["zaz"]},"application/voicexml+xml":{"source":"iana","compressible":true,"extensions":["vxml"]},"application/voucher-cms+json":{"source":"iana","compressible":true},"application/vq-rtcpxr":{"source":"iana"},"application/wasm":{"source":"iana","compressible":true,"extensions":["wasm"]},"application/watcherinfo+xml":{"source":"iana","compressible":true,"extensions":["wif"]},"application/webpush-options+json":{"source":"iana","compressible":true},"application/whoispp-query":{"source":"iana"},"application/whoispp-response":{"source":"iana"},"application/widget":{"source":"iana","extensions":["wgt"]},"application/winhlp":{"source":"apache","extensions":["hlp"]},"application/wita":{"source":"iana"},"application/wordperfect5.1":{"source":"iana"},"application/wsdl+xml":{"source":"iana","compressible":true,"extensions":["wsdl"]},"application/wspolicy+xml":{"source":"iana","compressible":true,"extensions":["wspolicy"]},"application/x-7z-compressed":{"source":"apache","compressible":false,"extensions":["7z"]},"application/x-abiword":{"source":"apache","extensions":["abw"]},"application/x-ace-compressed":{"source":"apache","extensions":["ace"]},"application/x-amf":{"source":"apache"},"application/x-apple-diskimage":{"source":"apache","extensions":["dmg"]},"application/x-arj":{"compressible":false,"extensions":["arj"]},"application/x-authorware-bin":{"source":"apache","extensions":["aab","x32","u32","vox"]},"application/x-authorware-map":{"source":"apache","extensions":["aam"]},"application/x-authorware-seg":{"source":"apache","extensions":["aas"]},"application/x-bcpio":{"source":"apache","extensions":["bcpio"]},"application/x-bdoc":{"compressible":false,"extensions":["bdoc"]},"application/x-bittorrent":{"source":"apache","extensions":["torrent"]},"application/x-blorb":{"source":"apache","extensions":["blb","blorb"]},"application/x-bzip":{"source":"apache","compressible":false,"extensions":["bz"]},"application/x-bzip2":{"source":"apache","compressible":false,"extensions":["bz2","boz"]},"application/x-cbr":{"source":"apache","extensions":["cbr","cba","cbt","cbz","cb7"]},"application/x-cdlink":{"source":"apache","extensions":["vcd"]},"application/x-cfs-compressed":{"source":"apache","extensions":["cfs"]},"application/x-chat":{"source":"apache","extensions":["chat"]},"application/x-chess-pgn":{"source":"apache","extensions":["pgn"]},"application/x-chrome-extension":{"extensions":["crx"]},"application/x-cocoa":{"source":"nginx","extensions":["cco"]},"application/x-compress":{"source":"apache"},"application/x-conference":{"source":"apache","extensions":["nsc"]},"application/x-cpio":{"source":"apache","extensions":["cpio"]},"application/x-csh":{"source":"apache","extensions":["csh"]},"application/x-deb":{"compressible":false},"application/x-debian-package":{"source":"apache","extensions":["deb","udeb"]},"application/x-dgc-compressed":{"source":"apache","extensions":["dgc"]},"application/x-director":{"source":"apache","extensions":["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"]},"application/x-doom":{"source":"apache","extensions":["wad"]},"application/x-dtbncx+xml":{"source":"apache","compressible":true,"extensions":["ncx"]},"application/x-dtbook+xml":{"source":"apache","compressible":true,"extensions":["dtb"]},"application/x-dtbresource+xml":{"source":"apache","compressible":true,"extensions":["res"]},"application/x-dvi":{"source":"apache","compressible":false,"extensions":["dvi"]},"application/x-envoy":{"source":"apache","extensions":["evy"]},"application/x-eva":{"source":"apache","extensions":["eva"]},"application/x-font-bdf":{"source":"apache","extensions":["bdf"]},"application/x-font-dos":{"source":"apache"},"application/x-font-framemaker":{"source":"apache"},"application/x-font-ghostscript":{"source":"apache","extensions":["gsf"]},"application/x-font-libgrx":{"source":"apache"},"application/x-font-linux-psf":{"source":"apache","extensions":["psf"]},"application/x-font-pcf":{"source":"apache","extensions":["pcf"]},"application/x-font-snf":{"source":"apache","extensions":["snf"]},"application/x-font-speedo":{"source":"apache"},"application/x-font-sunos-news":{"source":"apache"},"application/x-font-type1":{"source":"apache","extensions":["pfa","pfb","pfm","afm"]},"application/x-font-vfont":{"source":"apache"},"application/x-freearc":{"source":"apache","extensions":["arc"]},"application/x-futuresplash":{"source":"apache","extensions":["spl"]},"application/x-gca-compressed":{"source":"apache","extensions":["gca"]},"application/x-glulx":{"source":"apache","extensions":["ulx"]},"application/x-gnumeric":{"source":"apache","extensions":["gnumeric"]},"application/x-gramps-xml":{"source":"apache","extensions":["gramps"]},"application/x-gtar":{"source":"apache","extensions":["gtar"]},"application/x-gzip":{"source":"apache"},"application/x-hdf":{"source":"apache","extensions":["hdf"]},"application/x-httpd-php":{"compressible":true,"extensions":["php"]},"application/x-install-instructions":{"source":"apache","extensions":["install"]},"application/x-iso9660-image":{"source":"apache","extensions":["iso"]},"application/x-iwork-keynote-sffkey":{"extensions":["key"]},"application/x-iwork-numbers-sffnumbers":{"extensions":["numbers"]},"application/x-iwork-pages-sffpages":{"extensions":["pages"]},"application/x-java-archive-diff":{"source":"nginx","extensions":["jardiff"]},"application/x-java-jnlp-file":{"source":"apache","compressible":false,"extensions":["jnlp"]},"application/x-javascript":{"compressible":true},"application/x-keepass2":{"extensions":["kdbx"]},"application/x-latex":{"source":"apache","compressible":false,"extensions":["latex"]},"application/x-lua-bytecode":{"extensions":["luac"]},"application/x-lzh-compressed":{"source":"apache","extensions":["lzh","lha"]},"application/x-makeself":{"source":"nginx","extensions":["run"]},"application/x-mie":{"source":"apache","extensions":["mie"]},"application/x-mobipocket-ebook":{"source":"apache","extensions":["prc","mobi"]},"application/x-mpegurl":{"compressible":false},"application/x-ms-application":{"source":"apache","extensions":["application"]},"application/x-ms-shortcut":{"source":"apache","extensions":["lnk"]},"application/x-ms-wmd":{"source":"apache","extensions":["wmd"]},"application/x-ms-wmz":{"source":"apache","extensions":["wmz"]},"application/x-ms-xbap":{"source":"apache","extensions":["xbap"]},"application/x-msaccess":{"source":"apache","extensions":["mdb"]},"application/x-msbinder":{"source":"apache","extensions":["obd"]},"application/x-mscardfile":{"source":"apache","extensions":["crd"]},"application/x-msclip":{"source":"apache","extensions":["clp"]},"application/x-msdos-program":{"extensions":["exe"]},"application/x-msdownload":{"source":"apache","extensions":["exe","dll","com","bat","msi"]},"application/x-msmediaview":{"source":"apache","extensions":["mvb","m13","m14"]},"application/x-msmetafile":{"source":"apache","extensions":["wmf","wmz","emf","emz"]},"application/x-msmoney":{"source":"apache","extensions":["mny"]},"application/x-mspublisher":{"source":"apache","extensions":["pub"]},"application/x-msschedule":{"source":"apache","extensions":["scd"]},"application/x-msterminal":{"source":"apache","extensions":["trm"]},"application/x-mswrite":{"source":"apache","extensions":["wri"]},"application/x-netcdf":{"source":"apache","extensions":["nc","cdf"]},"application/x-ns-proxy-autoconfig":{"compressible":true,"extensions":["pac"]},"application/x-nzb":{"source":"apache","extensions":["nzb"]},"application/x-perl":{"source":"nginx","extensions":["pl","pm"]},"application/x-pilot":{"source":"nginx","extensions":["prc","pdb"]},"application/x-pkcs12":{"source":"apache","compressible":false,"extensions":["p12","pfx"]},"application/x-pkcs7-certificates":{"source":"apache","extensions":["p7b","spc"]},"application/x-pkcs7-certreqresp":{"source":"apache","extensions":["p7r"]},"application/x-pki-message":{"source":"iana"},"application/x-rar-compressed":{"source":"apache","compressible":false,"extensions":["rar"]},"application/x-redhat-package-manager":{"source":"nginx","extensions":["rpm"]},"application/x-research-info-systems":{"source":"apache","extensions":["ris"]},"application/x-sea":{"source":"nginx","extensions":["sea"]},"application/x-sh":{"source":"apache","compressible":true,"extensions":["sh"]},"application/x-shar":{"source":"apache","extensions":["shar"]},"application/x-shockwave-flash":{"source":"apache","compressible":false,"extensions":["swf"]},"application/x-silverlight-app":{"source":"apache","extensions":["xap"]},"application/x-sql":{"source":"apache","extensions":["sql"]},"application/x-stuffit":{"source":"apache","compressible":false,"extensions":["sit"]},"application/x-stuffitx":{"source":"apache","extensions":["sitx"]},"application/x-subrip":{"source":"apache","extensions":["srt"]},"application/x-sv4cpio":{"source":"apache","extensions":["sv4cpio"]},"application/x-sv4crc":{"source":"apache","extensions":["sv4crc"]},"application/x-t3vm-image":{"source":"apache","extensions":["t3"]},"application/x-tads":{"source":"apache","extensions":["gam"]},"application/x-tar":{"source":"apache","compressible":true,"extensions":["tar"]},"application/x-tcl":{"source":"apache","extensions":["tcl","tk"]},"application/x-tex":{"source":"apache","extensions":["tex"]},"application/x-tex-tfm":{"source":"apache","extensions":["tfm"]},"application/x-texinfo":{"source":"apache","extensions":["texinfo","texi"]},"application/x-tgif":{"source":"apache","extensions":["obj"]},"application/x-ustar":{"source":"apache","extensions":["ustar"]},"application/x-virtualbox-hdd":{"compressible":true,"extensions":["hdd"]},"application/x-virtualbox-ova":{"compressible":true,"extensions":["ova"]},"application/x-virtualbox-ovf":{"compressible":true,"extensions":["ovf"]},"application/x-virtualbox-vbox":{"compressible":true,"extensions":["vbox"]},"application/x-virtualbox-vbox-extpack":{"compressible":false,"extensions":["vbox-extpack"]},"application/x-virtualbox-vdi":{"compressible":true,"extensions":["vdi"]},"application/x-virtualbox-vhd":{"compressible":true,"extensions":["vhd"]},"application/x-virtualbox-vmdk":{"compressible":true,"extensions":["vmdk"]},"application/x-wais-source":{"source":"apache","extensions":["src"]},"application/x-web-app-manifest+json":{"compressible":true,"extensions":["webapp"]},"application/x-www-form-urlencoded":{"source":"iana","compressible":true},"application/x-x509-ca-cert":{"source":"iana","extensions":["der","crt","pem"]},"application/x-x509-ca-ra-cert":{"source":"iana"},"application/x-x509-next-ca-cert":{"source":"iana"},"application/x-xfig":{"source":"apache","extensions":["fig"]},"application/x-xliff+xml":{"source":"apache","compressible":true,"extensions":["xlf"]},"application/x-xpinstall":{"source":"apache","compressible":false,"extensions":["xpi"]},"application/x-xz":{"source":"apache","extensions":["xz"]},"application/x-zmachine":{"source":"apache","extensions":["z1","z2","z3","z4","z5","z6","z7","z8"]},"application/x400-bp":{"source":"iana"},"application/xacml+xml":{"source":"iana","compressible":true},"application/xaml+xml":{"source":"apache","compressible":true,"extensions":["xaml"]},"application/xcap-att+xml":{"source":"iana","compressible":true,"extensions":["xav"]},"application/xcap-caps+xml":{"source":"iana","compressible":true,"extensions":["xca"]},"application/xcap-diff+xml":{"source":"iana","compressible":true,"extensions":["xdf"]},"application/xcap-el+xml":{"source":"iana","compressible":true,"extensions":["xel"]},"application/xcap-error+xml":{"source":"iana","compressible":true},"application/xcap-ns+xml":{"source":"iana","compressible":true,"extensions":["xns"]},"application/xcon-conference-info+xml":{"source":"iana","compressible":true},"application/xcon-conference-info-diff+xml":{"source":"iana","compressible":true},"application/xenc+xml":{"source":"iana","compressible":true,"extensions":["xenc"]},"application/xhtml+xml":{"source":"iana","compressible":true,"extensions":["xhtml","xht"]},"application/xhtml-voice+xml":{"source":"apache","compressible":true},"application/xliff+xml":{"source":"iana","compressible":true,"extensions":["xlf"]},"application/xml":{"source":"iana","compressible":true,"extensions":["xml","xsl","xsd","rng"]},"application/xml-dtd":{"source":"iana","compressible":true,"extensions":["dtd"]},"application/xml-external-parsed-entity":{"source":"iana"},"application/xml-patch+xml":{"source":"iana","compressible":true},"application/xmpp+xml":{"source":"iana","compressible":true},"application/xop+xml":{"source":"iana","compressible":true,"extensions":["xop"]},"application/xproc+xml":{"source":"apache","compressible":true,"extensions":["xpl"]},"application/xslt+xml":{"source":"iana","compressible":true,"extensions":["xsl","xslt"]},"application/xspf+xml":{"source":"apache","compressible":true,"extensions":["xspf"]},"application/xv+xml":{"source":"iana","compressible":true,"extensions":["mxml","xhvml","xvml","xvm"]},"application/yang":{"source":"iana","extensions":["yang"]},"application/yang-data+json":{"source":"iana","compressible":true},"application/yang-data+xml":{"source":"iana","compressible":true},"application/yang-patch+json":{"source":"iana","compressible":true},"application/yang-patch+xml":{"source":"iana","compressible":true},"application/yin+xml":{"source":"iana","compressible":true,"extensions":["yin"]},"application/zip":{"source":"iana","compressible":false,"extensions":["zip"]},"application/zlib":{"source":"iana"},"application/zstd":{"source":"iana"},"audio/1d-interleaved-parityfec":{"source":"iana"},"audio/32kadpcm":{"source":"iana"},"audio/3gpp":{"source":"iana","compressible":false,"extensions":["3gpp"]},"audio/3gpp2":{"source":"iana"},"audio/aac":{"source":"iana"},"audio/ac3":{"source":"iana"},"audio/adpcm":{"source":"apache","extensions":["adp"]},"audio/amr":{"source":"iana","extensions":["amr"]},"audio/amr-wb":{"source":"iana"},"audio/amr-wb+":{"source":"iana"},"audio/aptx":{"source":"iana"},"audio/asc":{"source":"iana"},"audio/atrac-advanced-lossless":{"source":"iana"},"audio/atrac-x":{"source":"iana"},"audio/atrac3":{"source":"iana"},"audio/basic":{"source":"iana","compressible":false,"extensions":["au","snd"]},"audio/bv16":{"source":"iana"},"audio/bv32":{"source":"iana"},"audio/clearmode":{"source":"iana"},"audio/cn":{"source":"iana"},"audio/dat12":{"source":"iana"},"audio/dls":{"source":"iana"},"audio/dsr-es201108":{"source":"iana"},"audio/dsr-es202050":{"source":"iana"},"audio/dsr-es202211":{"source":"iana"},"audio/dsr-es202212":{"source":"iana"},"audio/dv":{"source":"iana"},"audio/dvi4":{"source":"iana"},"audio/eac3":{"source":"iana"},"audio/encaprtp":{"source":"iana"},"audio/evrc":{"source":"iana"},"audio/evrc-qcp":{"source":"iana"},"audio/evrc0":{"source":"iana"},"audio/evrc1":{"source":"iana"},"audio/evrcb":{"source":"iana"},"audio/evrcb0":{"source":"iana"},"audio/evrcb1":{"source":"iana"},"audio/evrcnw":{"source":"iana"},"audio/evrcnw0":{"source":"iana"},"audio/evrcnw1":{"source":"iana"},"audio/evrcwb":{"source":"iana"},"audio/evrcwb0":{"source":"iana"},"audio/evrcwb1":{"source":"iana"},"audio/evs":{"source":"iana"},"audio/flexfec":{"source":"iana"},"audio/fwdred":{"source":"iana"},"audio/g711-0":{"source":"iana"},"audio/g719":{"source":"iana"},"audio/g722":{"source":"iana"},"audio/g7221":{"source":"iana"},"audio/g723":{"source":"iana"},"audio/g726-16":{"source":"iana"},"audio/g726-24":{"source":"iana"},"audio/g726-32":{"source":"iana"},"audio/g726-40":{"source":"iana"},"audio/g728":{"source":"iana"},"audio/g729":{"source":"iana"},"audio/g7291":{"source":"iana"},"audio/g729d":{"source":"iana"},"audio/g729e":{"source":"iana"},"audio/gsm":{"source":"iana"},"audio/gsm-efr":{"source":"iana"},"audio/gsm-hr-08":{"source":"iana"},"audio/ilbc":{"source":"iana"},"audio/ip-mr_v2.5":{"source":"iana"},"audio/isac":{"source":"apache"},"audio/l16":{"source":"iana"},"audio/l20":{"source":"iana"},"audio/l24":{"source":"iana","compressible":false},"audio/l8":{"source":"iana"},"audio/lpc":{"source":"iana"},"audio/melp":{"source":"iana"},"audio/melp1200":{"source":"iana"},"audio/melp2400":{"source":"iana"},"audio/melp600":{"source":"iana"},"audio/mhas":{"source":"iana"},"audio/midi":{"source":"apache","extensions":["mid","midi","kar","rmi"]},"audio/mobile-xmf":{"source":"iana","extensions":["mxmf"]},"audio/mp3":{"compressible":false,"extensions":["mp3"]},"audio/mp4":{"source":"iana","compressible":false,"extensions":["m4a","mp4a"]},"audio/mp4a-latm":{"source":"iana"},"audio/mpa":{"source":"iana"},"audio/mpa-robust":{"source":"iana"},"audio/mpeg":{"source":"iana","compressible":false,"extensions":["mpga","mp2","mp2a","mp3","m2a","m3a"]},"audio/mpeg4-generic":{"source":"iana"},"audio/musepack":{"source":"apache"},"audio/ogg":{"source":"iana","compressible":false,"extensions":["oga","ogg","spx","opus"]},"audio/opus":{"source":"iana"},"audio/parityfec":{"source":"iana"},"audio/pcma":{"source":"iana"},"audio/pcma-wb":{"source":"iana"},"audio/pcmu":{"source":"iana"},"audio/pcmu-wb":{"source":"iana"},"audio/prs.sid":{"source":"iana"},"audio/qcelp":{"source":"iana"},"audio/raptorfec":{"source":"iana"},"audio/red":{"source":"iana"},"audio/rtp-enc-aescm128":{"source":"iana"},"audio/rtp-midi":{"source":"iana"},"audio/rtploopback":{"source":"iana"},"audio/rtx":{"source":"iana"},"audio/s3m":{"source":"apache","extensions":["s3m"]},"audio/scip":{"source":"iana"},"audio/silk":{"source":"apache","extensions":["sil"]},"audio/smv":{"source":"iana"},"audio/smv-qcp":{"source":"iana"},"audio/smv0":{"source":"iana"},"audio/sofa":{"source":"iana"},"audio/sp-midi":{"source":"iana"},"audio/speex":{"source":"iana"},"audio/t140c":{"source":"iana"},"audio/t38":{"source":"iana"},"audio/telephone-event":{"source":"iana"},"audio/tetra_acelp":{"source":"iana"},"audio/tetra_acelp_bb":{"source":"iana"},"audio/tone":{"source":"iana"},"audio/tsvcis":{"source":"iana"},"audio/uemclip":{"source":"iana"},"audio/ulpfec":{"source":"iana"},"audio/usac":{"source":"iana"},"audio/vdvi":{"source":"iana"},"audio/vmr-wb":{"source":"iana"},"audio/vnd.3gpp.iufp":{"source":"iana"},"audio/vnd.4sb":{"source":"iana"},"audio/vnd.audiokoz":{"source":"iana"},"audio/vnd.celp":{"source":"iana"},"audio/vnd.cisco.nse":{"source":"iana"},"audio/vnd.cmles.radio-events":{"source":"iana"},"audio/vnd.cns.anp1":{"source":"iana"},"audio/vnd.cns.inf1":{"source":"iana"},"audio/vnd.dece.audio":{"source":"iana","extensions":["uva","uvva"]},"audio/vnd.digital-winds":{"source":"iana","extensions":["eol"]},"audio/vnd.dlna.adts":{"source":"iana"},"audio/vnd.dolby.heaac.1":{"source":"iana"},"audio/vnd.dolby.heaac.2":{"source":"iana"},"audio/vnd.dolby.mlp":{"source":"iana"},"audio/vnd.dolby.mps":{"source":"iana"},"audio/vnd.dolby.pl2":{"source":"iana"},"audio/vnd.dolby.pl2x":{"source":"iana"},"audio/vnd.dolby.pl2z":{"source":"iana"},"audio/vnd.dolby.pulse.1":{"source":"iana"},"audio/vnd.dra":{"source":"iana","extensions":["dra"]},"audio/vnd.dts":{"source":"iana","extensions":["dts"]},"audio/vnd.dts.hd":{"source":"iana","extensions":["dtshd"]},"audio/vnd.dts.uhd":{"source":"iana"},"audio/vnd.dvb.file":{"source":"iana"},"audio/vnd.everad.plj":{"source":"iana"},"audio/vnd.hns.audio":{"source":"iana"},"audio/vnd.lucent.voice":{"source":"iana","extensions":["lvp"]},"audio/vnd.ms-playready.media.pya":{"source":"iana","extensions":["pya"]},"audio/vnd.nokia.mobile-xmf":{"source":"iana"},"audio/vnd.nortel.vbk":{"source":"iana"},"audio/vnd.nuera.ecelp4800":{"source":"iana","extensions":["ecelp4800"]},"audio/vnd.nuera.ecelp7470":{"source":"iana","extensions":["ecelp7470"]},"audio/vnd.nuera.ecelp9600":{"source":"iana","extensions":["ecelp9600"]},"audio/vnd.octel.sbc":{"source":"iana"},"audio/vnd.presonus.multitrack":{"source":"iana"},"audio/vnd.qcelp":{"source":"iana"},"audio/vnd.rhetorex.32kadpcm":{"source":"iana"},"audio/vnd.rip":{"source":"iana","extensions":["rip"]},"audio/vnd.rn-realaudio":{"compressible":false},"audio/vnd.sealedmedia.softseal.mpeg":{"source":"iana"},"audio/vnd.vmx.cvsd":{"source":"iana"},"audio/vnd.wave":{"compressible":false},"audio/vorbis":{"source":"iana","compressible":false},"audio/vorbis-config":{"source":"iana"},"audio/wav":{"compressible":false,"extensions":["wav"]},"audio/wave":{"compressible":false,"extensions":["wav"]},"audio/webm":{"source":"apache","compressible":false,"extensions":["weba"]},"audio/x-aac":{"source":"apache","compressible":false,"extensions":["aac"]},"audio/x-aiff":{"source":"apache","extensions":["aif","aiff","aifc"]},"audio/x-caf":{"source":"apache","compressible":false,"extensions":["caf"]},"audio/x-flac":{"source":"apache","extensions":["flac"]},"audio/x-m4a":{"source":"nginx","extensions":["m4a"]},"audio/x-matroska":{"source":"apache","extensions":["mka"]},"audio/x-mpegurl":{"source":"apache","extensions":["m3u"]},"audio/x-ms-wax":{"source":"apache","extensions":["wax"]},"audio/x-ms-wma":{"source":"apache","extensions":["wma"]},"audio/x-pn-realaudio":{"source":"apache","extensions":["ram","ra"]},"audio/x-pn-realaudio-plugin":{"source":"apache","extensions":["rmp"]},"audio/x-realaudio":{"source":"nginx","extensions":["ra"]},"audio/x-tta":{"source":"apache"},"audio/x-wav":{"source":"apache","extensions":["wav"]},"audio/xm":{"source":"apache","extensions":["xm"]},"chemical/x-cdx":{"source":"apache","extensions":["cdx"]},"chemical/x-cif":{"source":"apache","extensions":["cif"]},"chemical/x-cmdf":{"source":"apache","extensions":["cmdf"]},"chemical/x-cml":{"source":"apache","extensions":["cml"]},"chemical/x-csml":{"source":"apache","extensions":["csml"]},"chemical/x-pdb":{"source":"apache"},"chemical/x-xyz":{"source":"apache","extensions":["xyz"]},"font/collection":{"source":"iana","extensions":["ttc"]},"font/otf":{"source":"iana","compressible":true,"extensions":["otf"]},"font/sfnt":{"source":"iana"},"font/ttf":{"source":"iana","compressible":true,"extensions":["ttf"]},"font/woff":{"source":"iana","extensions":["woff"]},"font/woff2":{"source":"iana","extensions":["woff2"]},"image/aces":{"source":"iana","extensions":["exr"]},"image/apng":{"compressible":false,"extensions":["apng"]},"image/avci":{"source":"iana","extensions":["avci"]},"image/avcs":{"source":"iana","extensions":["avcs"]},"image/avif":{"source":"iana","compressible":false,"extensions":["avif"]},"image/bmp":{"source":"iana","compressible":true,"extensions":["bmp"]},"image/cgm":{"source":"iana","extensions":["cgm"]},"image/dicom-rle":{"source":"iana","extensions":["drle"]},"image/emf":{"source":"iana","extensions":["emf"]},"image/fits":{"source":"iana","extensions":["fits"]},"image/g3fax":{"source":"iana","extensions":["g3"]},"image/gif":{"source":"iana","compressible":false,"extensions":["gif"]},"image/heic":{"source":"iana","extensions":["heic"]},"image/heic-sequence":{"source":"iana","extensions":["heics"]},"image/heif":{"source":"iana","extensions":["heif"]},"image/heif-sequence":{"source":"iana","extensions":["heifs"]},"image/hej2k":{"source":"iana","extensions":["hej2"]},"image/hsj2":{"source":"iana","extensions":["hsj2"]},"image/ief":{"source":"iana","extensions":["ief"]},"image/jls":{"source":"iana","extensions":["jls"]},"image/jp2":{"source":"iana","compressible":false,"extensions":["jp2","jpg2"]},"image/jpeg":{"source":"iana","compressible":false,"extensions":["jpeg","jpg","jpe"]},"image/jph":{"source":"iana","extensions":["jph"]},"image/jphc":{"source":"iana","extensions":["jhc"]},"image/jpm":{"source":"iana","compressible":false,"extensions":["jpm"]},"image/jpx":{"source":"iana","compressible":false,"extensions":["jpx","jpf"]},"image/jxr":{"source":"iana","extensions":["jxr"]},"image/jxra":{"source":"iana","extensions":["jxra"]},"image/jxrs":{"source":"iana","extensions":["jxrs"]},"image/jxs":{"source":"iana","extensions":["jxs"]},"image/jxsc":{"source":"iana","extensions":["jxsc"]},"image/jxsi":{"source":"iana","extensions":["jxsi"]},"image/jxss":{"source":"iana","extensions":["jxss"]},"image/ktx":{"source":"iana","extensions":["ktx"]},"image/ktx2":{"source":"iana","extensions":["ktx2"]},"image/naplps":{"source":"iana"},"image/pjpeg":{"compressible":false},"image/png":{"source":"iana","compressible":false,"extensions":["png"]},"image/prs.btif":{"source":"iana","extensions":["btif"]},"image/prs.pti":{"source":"iana","extensions":["pti"]},"image/pwg-raster":{"source":"iana"},"image/sgi":{"source":"apache","extensions":["sgi"]},"image/svg+xml":{"source":"iana","compressible":true,"extensions":["svg","svgz"]},"image/t38":{"source":"iana","extensions":["t38"]},"image/tiff":{"source":"iana","compressible":false,"extensions":["tif","tiff"]},"image/tiff-fx":{"source":"iana","extensions":["tfx"]},"image/vnd.adobe.photoshop":{"source":"iana","compressible":true,"extensions":["psd"]},"image/vnd.airzip.accelerator.azv":{"source":"iana","extensions":["azv"]},"image/vnd.cns.inf2":{"source":"iana"},"image/vnd.dece.graphic":{"source":"iana","extensions":["uvi","uvvi","uvg","uvvg"]},"image/vnd.djvu":{"source":"iana","extensions":["djvu","djv"]},"image/vnd.dvb.subtitle":{"source":"iana","extensions":["sub"]},"image/vnd.dwg":{"source":"iana","extensions":["dwg"]},"image/vnd.dxf":{"source":"iana","extensions":["dxf"]},"image/vnd.fastbidsheet":{"source":"iana","extensions":["fbs"]},"image/vnd.fpx":{"source":"iana","extensions":["fpx"]},"image/vnd.fst":{"source":"iana","extensions":["fst"]},"image/vnd.fujixerox.edmics-mmr":{"source":"iana","extensions":["mmr"]},"image/vnd.fujixerox.edmics-rlc":{"source":"iana","extensions":["rlc"]},"image/vnd.globalgraphics.pgb":{"source":"iana"},"image/vnd.microsoft.icon":{"source":"iana","compressible":true,"extensions":["ico"]},"image/vnd.mix":{"source":"iana"},"image/vnd.mozilla.apng":{"source":"iana"},"image/vnd.ms-dds":{"compressible":true,"extensions":["dds"]},"image/vnd.ms-modi":{"source":"iana","extensions":["mdi"]},"image/vnd.ms-photo":{"source":"apache","extensions":["wdp"]},"image/vnd.net-fpx":{"source":"iana","extensions":["npx"]},"image/vnd.pco.b16":{"source":"iana","extensions":["b16"]},"image/vnd.radiance":{"source":"iana"},"image/vnd.sealed.png":{"source":"iana"},"image/vnd.sealedmedia.softseal.gif":{"source":"iana"},"image/vnd.sealedmedia.softseal.jpg":{"source":"iana"},"image/vnd.svf":{"source":"iana"},"image/vnd.tencent.tap":{"source":"iana","extensions":["tap"]},"image/vnd.valve.source.texture":{"source":"iana","extensions":["vtf"]},"image/vnd.wap.wbmp":{"source":"iana","extensions":["wbmp"]},"image/vnd.xiff":{"source":"iana","extensions":["xif"]},"image/vnd.zbrush.pcx":{"source":"iana","extensions":["pcx"]},"image/webp":{"source":"apache","extensions":["webp"]},"image/wmf":{"source":"iana","extensions":["wmf"]},"image/x-3ds":{"source":"apache","extensions":["3ds"]},"image/x-cmu-raster":{"source":"apache","extensions":["ras"]},"image/x-cmx":{"source":"apache","extensions":["cmx"]},"image/x-freehand":{"source":"apache","extensions":["fh","fhc","fh4","fh5","fh7"]},"image/x-icon":{"source":"apache","compressible":true,"extensions":["ico"]},"image/x-jng":{"source":"nginx","extensions":["jng"]},"image/x-mrsid-image":{"source":"apache","extensions":["sid"]},"image/x-ms-bmp":{"source":"nginx","compressible":true,"extensions":["bmp"]},"image/x-pcx":{"source":"apache","extensions":["pcx"]},"image/x-pict":{"source":"apache","extensions":["pic","pct"]},"image/x-portable-anymap":{"source":"apache","extensions":["pnm"]},"image/x-portable-bitmap":{"source":"apache","extensions":["pbm"]},"image/x-portable-graymap":{"source":"apache","extensions":["pgm"]},"image/x-portable-pixmap":{"source":"apache","extensions":["ppm"]},"image/x-rgb":{"source":"apache","extensions":["rgb"]},"image/x-tga":{"source":"apache","extensions":["tga"]},"image/x-xbitmap":{"source":"apache","extensions":["xbm"]},"image/x-xcf":{"compressible":false},"image/x-xpixmap":{"source":"apache","extensions":["xpm"]},"image/x-xwindowdump":{"source":"apache","extensions":["xwd"]},"message/cpim":{"source":"iana"},"message/delivery-status":{"source":"iana"},"message/disposition-notification":{"source":"iana","extensions":["disposition-notification"]},"message/external-body":{"source":"iana"},"message/feedback-report":{"source":"iana"},"message/global":{"source":"iana","extensions":["u8msg"]},"message/global-delivery-status":{"source":"iana","extensions":["u8dsn"]},"message/global-disposition-notification":{"source":"iana","extensions":["u8mdn"]},"message/global-headers":{"source":"iana","extensions":["u8hdr"]},"message/http":{"source":"iana","compressible":false},"message/imdn+xml":{"source":"iana","compressible":true},"message/news":{"source":"iana"},"message/partial":{"source":"iana","compressible":false},"message/rfc822":{"source":"iana","compressible":true,"extensions":["eml","mime"]},"message/s-http":{"source":"iana"},"message/sip":{"source":"iana"},"message/sipfrag":{"source":"iana"},"message/tracking-status":{"source":"iana"},"message/vnd.si.simp":{"source":"iana"},"message/vnd.wfa.wsc":{"source":"iana","extensions":["wsc"]},"model/3mf":{"source":"iana","extensions":["3mf"]},"model/e57":{"source":"iana"},"model/gltf+json":{"source":"iana","compressible":true,"extensions":["gltf"]},"model/gltf-binary":{"source":"iana","compressible":true,"extensions":["glb"]},"model/iges":{"source":"iana","compressible":false,"extensions":["igs","iges"]},"model/mesh":{"source":"iana","compressible":false,"extensions":["msh","mesh","silo"]},"model/mtl":{"source":"iana","extensions":["mtl"]},"model/obj":{"source":"iana","extensions":["obj"]},"model/step":{"source":"iana"},"model/step+xml":{"source":"iana","compressible":true,"extensions":["stpx"]},"model/step+zip":{"source":"iana","compressible":false,"extensions":["stpz"]},"model/step-xml+zip":{"source":"iana","compressible":false,"extensions":["stpxz"]},"model/stl":{"source":"iana","extensions":["stl"]},"model/vnd.collada+xml":{"source":"iana","compressible":true,"extensions":["dae"]},"model/vnd.dwf":{"source":"iana","extensions":["dwf"]},"model/vnd.flatland.3dml":{"source":"iana"},"model/vnd.gdl":{"source":"iana","extensions":["gdl"]},"model/vnd.gs-gdl":{"source":"apache"},"model/vnd.gs.gdl":{"source":"iana"},"model/vnd.gtw":{"source":"iana","extensions":["gtw"]},"model/vnd.moml+xml":{"source":"iana","compressible":true},"model/vnd.mts":{"source":"iana","extensions":["mts"]},"model/vnd.opengex":{"source":"iana","extensions":["ogex"]},"model/vnd.parasolid.transmit.binary":{"source":"iana","extensions":["x_b"]},"model/vnd.parasolid.transmit.text":{"source":"iana","extensions":["x_t"]},"model/vnd.pytha.pyox":{"source":"iana"},"model/vnd.rosette.annotated-data-model":{"source":"iana"},"model/vnd.sap.vds":{"source":"iana","extensions":["vds"]},"model/vnd.usdz+zip":{"source":"iana","compressible":false,"extensions":["usdz"]},"model/vnd.valve.source.compiled-map":{"source":"iana","extensions":["bsp"]},"model/vnd.vtu":{"source":"iana","extensions":["vtu"]},"model/vrml":{"source":"iana","compressible":false,"extensions":["wrl","vrml"]},"model/x3d+binary":{"source":"apache","compressible":false,"extensions":["x3db","x3dbz"]},"model/x3d+fastinfoset":{"source":"iana","extensions":["x3db"]},"model/x3d+vrml":{"source":"apache","compressible":false,"extensions":["x3dv","x3dvz"]},"model/x3d+xml":{"source":"iana","compressible":true,"extensions":["x3d","x3dz"]},"model/x3d-vrml":{"source":"iana","extensions":["x3dv"]},"multipart/alternative":{"source":"iana","compressible":false},"multipart/appledouble":{"source":"iana"},"multipart/byteranges":{"source":"iana"},"multipart/digest":{"source":"iana"},"multipart/encrypted":{"source":"iana","compressible":false},"multipart/form-data":{"source":"iana","compressible":false},"multipart/header-set":{"source":"iana"},"multipart/mixed":{"source":"iana"},"multipart/multilingual":{"source":"iana"},"multipart/parallel":{"source":"iana"},"multipart/related":{"source":"iana","compressible":false},"multipart/report":{"source":"iana"},"multipart/signed":{"source":"iana","compressible":false},"multipart/vnd.bint.med-plus":{"source":"iana"},"multipart/voice-message":{"source":"iana"},"multipart/x-mixed-replace":{"source":"iana"},"text/1d-interleaved-parityfec":{"source":"iana"},"text/cache-manifest":{"source":"iana","compressible":true,"extensions":["appcache","manifest"]},"text/calendar":{"source":"iana","extensions":["ics","ifb"]},"text/calender":{"compressible":true},"text/cmd":{"compressible":true},"text/coffeescript":{"extensions":["coffee","litcoffee"]},"text/cql":{"source":"iana"},"text/cql-expression":{"source":"iana"},"text/cql-identifier":{"source":"iana"},"text/css":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["css"]},"text/csv":{"source":"iana","compressible":true,"extensions":["csv"]},"text/csv-schema":{"source":"iana"},"text/directory":{"source":"iana"},"text/dns":{"source":"iana"},"text/ecmascript":{"source":"iana"},"text/encaprtp":{"source":"iana"},"text/enriched":{"source":"iana"},"text/fhirpath":{"source":"iana"},"text/flexfec":{"source":"iana"},"text/fwdred":{"source":"iana"},"text/gff3":{"source":"iana"},"text/grammar-ref-list":{"source":"iana"},"text/html":{"source":"iana","compressible":true,"extensions":["html","htm","shtml"]},"text/jade":{"extensions":["jade"]},"text/javascript":{"source":"iana","compressible":true},"text/jcr-cnd":{"source":"iana"},"text/jsx":{"compressible":true,"extensions":["jsx"]},"text/less":{"compressible":true,"extensions":["less"]},"text/markdown":{"source":"iana","compressible":true,"extensions":["markdown","md"]},"text/mathml":{"source":"nginx","extensions":["mml"]},"text/mdx":{"compressible":true,"extensions":["mdx"]},"text/mizar":{"source":"iana"},"text/n3":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["n3"]},"text/parameters":{"source":"iana","charset":"UTF-8"},"text/parityfec":{"source":"iana"},"text/plain":{"source":"iana","compressible":true,"extensions":["txt","text","conf","def","list","log","in","ini"]},"text/provenance-notation":{"source":"iana","charset":"UTF-8"},"text/prs.fallenstein.rst":{"source":"iana"},"text/prs.lines.tag":{"source":"iana","extensions":["dsc"]},"text/prs.prop.logic":{"source":"iana"},"text/raptorfec":{"source":"iana"},"text/red":{"source":"iana"},"text/rfc822-headers":{"source":"iana"},"text/richtext":{"source":"iana","compressible":true,"extensions":["rtx"]},"text/rtf":{"source":"iana","compressible":true,"extensions":["rtf"]},"text/rtp-enc-aescm128":{"source":"iana"},"text/rtploopback":{"source":"iana"},"text/rtx":{"source":"iana"},"text/sgml":{"source":"iana","extensions":["sgml","sgm"]},"text/shaclc":{"source":"iana"},"text/shex":{"source":"iana","extensions":["shex"]},"text/slim":{"extensions":["slim","slm"]},"text/spdx":{"source":"iana","extensions":["spdx"]},"text/strings":{"source":"iana"},"text/stylus":{"extensions":["stylus","styl"]},"text/t140":{"source":"iana"},"text/tab-separated-values":{"source":"iana","compressible":true,"extensions":["tsv"]},"text/troff":{"source":"iana","extensions":["t","tr","roff","man","me","ms"]},"text/turtle":{"source":"iana","charset":"UTF-8","extensions":["ttl"]},"text/ulpfec":{"source":"iana"},"text/uri-list":{"source":"iana","compressible":true,"extensions":["uri","uris","urls"]},"text/vcard":{"source":"iana","compressible":true,"extensions":["vcard"]},"text/vnd.a":{"source":"iana"},"text/vnd.abc":{"source":"iana"},"text/vnd.ascii-art":{"source":"iana"},"text/vnd.curl":{"source":"iana","extensions":["curl"]},"text/vnd.curl.dcurl":{"source":"apache","extensions":["dcurl"]},"text/vnd.curl.mcurl":{"source":"apache","extensions":["mcurl"]},"text/vnd.curl.scurl":{"source":"apache","extensions":["scurl"]},"text/vnd.debian.copyright":{"source":"iana","charset":"UTF-8"},"text/vnd.dmclientscript":{"source":"iana"},"text/vnd.dvb.subtitle":{"source":"iana","extensions":["sub"]},"text/vnd.esmertec.theme-descriptor":{"source":"iana","charset":"UTF-8"},"text/vnd.familysearch.gedcom":{"source":"iana","extensions":["ged"]},"text/vnd.ficlab.flt":{"source":"iana"},"text/vnd.fly":{"source":"iana","extensions":["fly"]},"text/vnd.fmi.flexstor":{"source":"iana","extensions":["flx"]},"text/vnd.gml":{"source":"iana"},"text/vnd.graphviz":{"source":"iana","extensions":["gv"]},"text/vnd.hans":{"source":"iana"},"text/vnd.hgl":{"source":"iana"},"text/vnd.in3d.3dml":{"source":"iana","extensions":["3dml"]},"text/vnd.in3d.spot":{"source":"iana","extensions":["spot"]},"text/vnd.iptc.newsml":{"source":"iana"},"text/vnd.iptc.nitf":{"source":"iana"},"text/vnd.latex-z":{"source":"iana"},"text/vnd.motorola.reflex":{"source":"iana"},"text/vnd.ms-mediapackage":{"source":"iana"},"text/vnd.net2phone.commcenter.command":{"source":"iana"},"text/vnd.radisys.msml-basic-layout":{"source":"iana"},"text/vnd.senx.warpscript":{"source":"iana"},"text/vnd.si.uricatalogue":{"source":"iana"},"text/vnd.sosi":{"source":"iana"},"text/vnd.sun.j2me.app-descriptor":{"source":"iana","charset":"UTF-8","extensions":["jad"]},"text/vnd.trolltech.linguist":{"source":"iana","charset":"UTF-8"},"text/vnd.wap.si":{"source":"iana"},"text/vnd.wap.sl":{"source":"iana"},"text/vnd.wap.wml":{"source":"iana","extensions":["wml"]},"text/vnd.wap.wmlscript":{"source":"iana","extensions":["wmls"]},"text/vtt":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["vtt"]},"text/x-asm":{"source":"apache","extensions":["s","asm"]},"text/x-c":{"source":"apache","extensions":["c","cc","cxx","cpp","h","hh","dic"]},"text/x-component":{"source":"nginx","extensions":["htc"]},"text/x-fortran":{"source":"apache","extensions":["f","for","f77","f90"]},"text/x-gwt-rpc":{"compressible":true},"text/x-handlebars-template":{"extensions":["hbs"]},"text/x-java-source":{"source":"apache","extensions":["java"]},"text/x-jquery-tmpl":{"compressible":true},"text/x-lua":{"extensions":["lua"]},"text/x-markdown":{"compressible":true,"extensions":["mkd"]},"text/x-nfo":{"source":"apache","extensions":["nfo"]},"text/x-opml":{"source":"apache","extensions":["opml"]},"text/x-org":{"compressible":true,"extensions":["org"]},"text/x-pascal":{"source":"apache","extensions":["p","pas"]},"text/x-processing":{"compressible":true,"extensions":["pde"]},"text/x-sass":{"extensions":["sass"]},"text/x-scss":{"extensions":["scss"]},"text/x-setext":{"source":"apache","extensions":["etx"]},"text/x-sfv":{"source":"apache","extensions":["sfv"]},"text/x-suse-ymp":{"compressible":true,"extensions":["ymp"]},"text/x-uuencode":{"source":"apache","extensions":["uu"]},"text/x-vcalendar":{"source":"apache","extensions":["vcs"]},"text/x-vcard":{"source":"apache","extensions":["vcf"]},"text/xml":{"source":"iana","compressible":true,"extensions":["xml"]},"text/xml-external-parsed-entity":{"source":"iana"},"text/yaml":{"compressible":true,"extensions":["yaml","yml"]},"video/1d-interleaved-parityfec":{"source":"iana"},"video/3gpp":{"source":"iana","extensions":["3gp","3gpp"]},"video/3gpp-tt":{"source":"iana"},"video/3gpp2":{"source":"iana","extensions":["3g2"]},"video/av1":{"source":"iana"},"video/bmpeg":{"source":"iana"},"video/bt656":{"source":"iana"},"video/celb":{"source":"iana"},"video/dv":{"source":"iana"},"video/encaprtp":{"source":"iana"},"video/ffv1":{"source":"iana"},"video/flexfec":{"source":"iana"},"video/h261":{"source":"iana","extensions":["h261"]},"video/h263":{"source":"iana","extensions":["h263"]},"video/h263-1998":{"source":"iana"},"video/h263-2000":{"source":"iana"},"video/h264":{"source":"iana","extensions":["h264"]},"video/h264-rcdo":{"source":"iana"},"video/h264-svc":{"source":"iana"},"video/h265":{"source":"iana"},"video/iso.segment":{"source":"iana","extensions":["m4s"]},"video/jpeg":{"source":"iana","extensions":["jpgv"]},"video/jpeg2000":{"source":"iana"},"video/jpm":{"source":"apache","extensions":["jpm","jpgm"]},"video/jxsv":{"source":"iana"},"video/mj2":{"source":"iana","extensions":["mj2","mjp2"]},"video/mp1s":{"source":"iana"},"video/mp2p":{"source":"iana"},"video/mp2t":{"source":"iana","extensions":["ts"]},"video/mp4":{"source":"iana","compressible":false,"extensions":["mp4","mp4v","mpg4"]},"video/mp4v-es":{"source":"iana"},"video/mpeg":{"source":"iana","compressible":false,"extensions":["mpeg","mpg","mpe","m1v","m2v"]},"video/mpeg4-generic":{"source":"iana"},"video/mpv":{"source":"iana"},"video/nv":{"source":"iana"},"video/ogg":{"source":"iana","compressible":false,"extensions":["ogv"]},"video/parityfec":{"source":"iana"},"video/pointer":{"source":"iana"},"video/quicktime":{"source":"iana","compressible":false,"extensions":["qt","mov"]},"video/raptorfec":{"source":"iana"},"video/raw":{"source":"iana"},"video/rtp-enc-aescm128":{"source":"iana"},"video/rtploopback":{"source":"iana"},"video/rtx":{"source":"iana"},"video/scip":{"source":"iana"},"video/smpte291":{"source":"iana"},"video/smpte292m":{"source":"iana"},"video/ulpfec":{"source":"iana"},"video/vc1":{"source":"iana"},"video/vc2":{"source":"iana"},"video/vnd.cctv":{"source":"iana"},"video/vnd.dece.hd":{"source":"iana","extensions":["uvh","uvvh"]},"video/vnd.dece.mobile":{"source":"iana","extensions":["uvm","uvvm"]},"video/vnd.dece.mp4":{"source":"iana"},"video/vnd.dece.pd":{"source":"iana","extensions":["uvp","uvvp"]},"video/vnd.dece.sd":{"source":"iana","extensions":["uvs","uvvs"]},"video/vnd.dece.video":{"source":"iana","extensions":["uvv","uvvv"]},"video/vnd.directv.mpeg":{"source":"iana"},"video/vnd.directv.mpeg-tts":{"source":"iana"},"video/vnd.dlna.mpeg-tts":{"source":"iana"},"video/vnd.dvb.file":{"source":"iana","extensions":["dvb"]},"video/vnd.fvt":{"source":"iana","extensions":["fvt"]},"video/vnd.hns.video":{"source":"iana"},"video/vnd.iptvforum.1dparityfec-1010":{"source":"iana"},"video/vnd.iptvforum.1dparityfec-2005":{"source":"iana"},"video/vnd.iptvforum.2dparityfec-1010":{"source":"iana"},"video/vnd.iptvforum.2dparityfec-2005":{"source":"iana"},"video/vnd.iptvforum.ttsavc":{"source":"iana"},"video/vnd.iptvforum.ttsmpeg2":{"source":"iana"},"video/vnd.motorola.video":{"source":"iana"},"video/vnd.motorola.videop":{"source":"iana"},"video/vnd.mpegurl":{"source":"iana","extensions":["mxu","m4u"]},"video/vnd.ms-playready.media.pyv":{"source":"iana","extensions":["pyv"]},"video/vnd.nokia.interleaved-multimedia":{"source":"iana"},"video/vnd.nokia.mp4vr":{"source":"iana"},"video/vnd.nokia.videovoip":{"source":"iana"},"video/vnd.objectvideo":{"source":"iana"},"video/vnd.radgamettools.bink":{"source":"iana"},"video/vnd.radgamettools.smacker":{"source":"iana"},"video/vnd.sealed.mpeg1":{"source":"iana"},"video/vnd.sealed.mpeg4":{"source":"iana"},"video/vnd.sealed.swf":{"source":"iana"},"video/vnd.sealedmedia.softseal.mov":{"source":"iana"},"video/vnd.uvvu.mp4":{"source":"iana","extensions":["uvu","uvvu"]},"video/vnd.vivo":{"source":"iana","extensions":["viv"]},"video/vnd.youtube.yt":{"source":"iana"},"video/vp8":{"source":"iana"},"video/vp9":{"source":"iana"},"video/webm":{"source":"apache","compressible":false,"extensions":["webm"]},"video/x-f4v":{"source":"apache","extensions":["f4v"]},"video/x-fli":{"source":"apache","extensions":["fli"]},"video/x-flv":{"source":"apache","compressible":false,"extensions":["flv"]},"video/x-m4v":{"source":"apache","extensions":["m4v"]},"video/x-matroska":{"source":"apache","compressible":false,"extensions":["mkv","mk3d","mks"]},"video/x-mng":{"source":"apache","extensions":["mng"]},"video/x-ms-asf":{"source":"apache","extensions":["asf","asx"]},"video/x-ms-vob":{"source":"apache","extensions":["vob"]},"video/x-ms-wm":{"source":"apache","extensions":["wm"]},"video/x-ms-wmv":{"source":"apache","compressible":false,"extensions":["wmv"]},"video/x-ms-wmx":{"source":"apache","extensions":["wmx"]},"video/x-ms-wvx":{"source":"apache","extensions":["wvx"]},"video/x-msvideo":{"source":"apache","extensions":["avi"]},"video/x-sgi-movie":{"source":"apache","extensions":["movie"]},"video/x-smv":{"source":"apache","extensions":["smv"]},"x-conference/x-cooltalk":{"source":"apache","extensions":["ice"]},"x-shader/x-fragment":{"compressible":true},"x-shader/x-vertex":{"compressible":true}}')}},t={};function n(a){var i=t[a];if(void 0!==i)return i.exports;var o=t[a]={id:a,loaded:!1,exports:{}};return e[a].call(o.exports,o,o.exports,n),o.loaded=!0,o.exports}n.nmd=e=>(e.paths=[],e.children||(e.children=[]),e);var a=n(7530);return a=a.default})())); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLEtBQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLEtBQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLEtBQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxzNEJDYkE0akIsRUFBQS9YLEVBQUEsTUFBQTdMLEdBQ0E0akIsRUFBQS9YLEVBQUEsTUFBQTdMLEdBQ0E0akIsRUFBQS9YLEVBQUEsTUFBQTdMLEdBQ0E0akIsRUFBQS9YLEVBQUEsTUFBQTdMLEdBQ0E0akIsRUFBQS9YLEVBQUEsS0FBQTdMLHM0QkNKQTRqQixFQUFBL1gsRUFBQSxNQUFBN0wsR0FDQTRqQixFQUFBL1gsRUFBQSxNQUFBN0wsR0FDQTRqQixFQUFBL1gsRUFBQSxNQUFBN0wsR0FDQTRqQixFQUFBL1gsRUFBQSxNQUFBN0wsR0FDQTRqQixFQUFBL1gsRUFBQSxLQUFBN0wsdWxCQ0pBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxzbEJDQUE0akIsRUFBQS9YLEVBQUEsTUFBQTdMLHVsQkNBQTRqQixFQUFBL1gsRUFBQSxNQUFBN0wsdWxCQ0FBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxtcUJDQUE0akIsRUFBQS9YLEVBQUEsTUFBQTdMLEdBQ0E0akIsRUFBQS9YLEVBQUEsTUFBQTdMLHVsQkNEQTRqQixFQUFBL1gsRUFBQSxNQUFBN0wsdWxCQ0FBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCx1bEJDQUE0akIsRUFBQS9YLEVBQUEsTUFBQTdMLHVsQkNBQTRqQixFQUFBL1gsRUFBQSxNQUFBN0wsdTRC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LEVBQWVILEVBQXlCRSxHQUM1QyxRQUFxQng1QyxJQUFqQnk1QyxFQUNILE9BQU9BLEVBQWF4L0MsUUFHckIsSUFBSUMsRUFBU28vQyxFQUF5QkUsR0FBWSxDQUNqRHB0QyxHQUFJb3RDLEVBQ0pySyxRQUFRLEVBQ1JsMUMsUUFBUyxDQUFDLEdBVVgsT0FOQXkvQyxFQUFvQkYsR0FBVWo3QyxLQUFLckUsRUFBT0QsUUFBU0MsRUFBUUEsRUFBT0QsUUFBU3MvQyxHQUczRXIvQyxFQUFPaTFDLFFBQVMsRUFHVGoxQyxFQUFPRCxPQUNmLENDekJBcy9DLEVBQW9CSSxJQUFPei9DLElBQzFCQSxFQUFPMC9DLE1BQVEsR0FDVjEvQyxFQUFPMi9DLFdBQVUzL0MsRUFBTzIvQyxTQUFXLElBQ2pDMy9DLEdDQVIsSUFBSTQvQyxFQUFzQlAsRUFBb0IsMEJ6R085QyIsInNvdXJjZXMiOlsid2VicGFjazovL21haWxndW4vd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvYXN5bmNraXQvaW5kZXguanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9hc3luY2tpdC9saWIvYWJvcnQuanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9hc3luY2tpdC9saWIvYXN5bmMuanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9hc3luY2tpdC9saWIvZGVmZXIuanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9hc3luY2tpdC9saWIvaXRlcmF0ZS5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2FzeW5ja2l0L2xpYi9zdGF0ZS5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2FzeW5ja2l0L2xpYi90ZXJtaW5hdG9yLmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvYXN5bmNraXQvcGFyYWxsZWwuanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9hc3luY2tpdC9zZXJpYWwuanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9hc3luY2tpdC9zZXJpYWxPcmRlcmVkLmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvYXhpb3Mvbm9kZV9tb2R1bGVzL2Zvcm0tZGF0YS9saWIvZm9ybV9kYXRhLmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvYXhpb3Mvbm9kZV9tb2R1bGVzL2Zvcm0tZGF0YS9saWIvcG9wdWxhdGUuanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9DbGFzc2VzL0RvbWFpbnMvZG9tYWluLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9Eb21haW5zL2RvbWFpbnNDbGllbnQudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9DbGFzc2VzL0RvbWFpbnMvZG9tYWluc0NyZWRlbnRpYWxzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9Eb21haW5zL2RvbWFpbnNUYWdzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9Eb21haW5zL2RvbWFpbnNUZW1wbGF0ZXMudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9DbGFzc2VzL0V2ZW50cy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0NsYXNzZXMvSVBQb29scy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0NsYXNzZXMvSVBzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9NYWlsZ3VuQ2xpZW50LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9NYWlsaW5nTGlzdHMvbWFpbExpc3RNZW1iZXJzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9NYWlsaW5nTGlzdHMvbWFpbGluZ0xpc3RzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9NZXNzYWdlcy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0NsYXNzZXMvUm91dGVzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9TdGF0cy9TdGF0c0NsaWVudC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0NsYXNzZXMvU3RhdHMvU3RhdHNDb250YWluZXIudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9DbGFzc2VzL1N1YmFjY291bnRzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9TdXBwcmVzc2lvbnMvQm91bmNlLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9TdXBwcmVzc2lvbnMvQ29tcGxhaW50LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9TdXBwcmVzc2lvbnMvU3VwcHJlc3Npb24udHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9DbGFzc2VzL1N1cHByZXNzaW9ucy9TdXBwcmVzc2lvbnNDbGllbnQudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9DbGFzc2VzL1N1cHByZXNzaW9ucy9VbnN1YnNjcmliZS50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0NsYXNzZXMvU3VwcHJlc3Npb25zL1doaXRlTGlzdC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0NsYXNzZXMvVmFsaWRhdGlvbnMvbXVsdGlwbGVWYWxpZGF0aW9uLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9WYWxpZGF0aW9ucy92YWxpZGF0ZS50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0NsYXNzZXMvV2ViaG9va3MudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9DbGFzc2VzL2NvbW1vbi9FcnJvci50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0NsYXNzZXMvY29tbW9uL0Zvcm1EYXRhQnVpbGRlci50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0NsYXNzZXMvY29tbW9uL05hdmlnYXRpb25UaHJ1UGFnZXMudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9DbGFzc2VzL2NvbW1vbi9SZXF1ZXN0LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvRW51bXMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9JbnRlcmZhY2VzL0NvbW1vbi9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0ludGVyZmFjZXMvRG9tYWlucy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0ludGVyZmFjZXMvRXZlbnRDbGllbnQvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9JbnRlcmZhY2VzL0lQUG9vbHMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9JbnRlcmZhY2VzL0lQcy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0ludGVyZmFjZXMvTWFpbGd1bkNsaWVudC9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0ludGVyZmFjZXMvTWFpbGluZ0xpc3RzL2luZGV4LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvSW50ZXJmYWNlcy9NZXNzYWdlcy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0ludGVyZmFjZXMvUm91dGVzL2luZGV4LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvSW50ZXJmYWNlcy9TdGF0cy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0ludGVyZmFjZXMvU3ViYWNjb3VudHMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9JbnRlcmZhY2VzL1N1cHByZXNzaW9ucy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0ludGVyZmFjZXMvVmFsaWRhdGlvbnMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9JbnRlcmZhY2VzL1dlYmhvb2tzL2luZGV4LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvSW50ZXJmYWNlcy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL1R5cGVzL0NvbW1vbi9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL1R5cGVzL0RvbWFpbnMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9UeXBlcy9FdmVudHMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9UeXBlcy9JUFBvb2xzL2luZGV4LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvVHlwZXMvSVBzL2luZGV4LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvVHlwZXMvTWFpbGd1bkNsaWVudC9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL1R5cGVzL01haWxpbmdMaXN0cy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL1R5cGVzL01lc3NhZ2VzL2luZGV4LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvVHlwZXMvUm91dGVzL2luZGV4LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvVHlwZXMvU3RhdHMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9UeXBlcy9TdWJhY2NvdW50cy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL1R5cGVzL1N1cHByZXNzaW9ucy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL1R5cGVzL1ZhbGlkYXRpb25zL2luZGV4LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvVHlwZXMvV2ViaG9va3MvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9UeXBlcy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL2luZGV4LnRzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvYmFzZS02NC9iYXNlNjQuanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9jb21iaW5lZC1zdHJlYW0vbGliL2NvbWJpbmVkX3N0cmVhbS5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2RlYnVnL3NyYy9icm93c2VyLmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvZGVidWcvc3JjL2NvbW1vbi5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2RlYnVnL3NyYy9pbmRleC5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2RlYnVnL3NyYy9ub2RlLmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvZGVsYXllZC1zdHJlYW0vbGliL2RlbGF5ZWRfc3RyZWFtLmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvZm9sbG93LXJlZGlyZWN0cy9kZWJ1Zy5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2ZvbGxvdy1yZWRpcmVjdHMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9oYXMtZmxhZy9pbmRleC5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL21pbWUtZGIvaW5kZXguanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9taW1lLXR5cGVzL2luZGV4LmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvbXMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9wcm94eS1mcm9tLWVudi9pbmRleC5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL3N1cHBvcnRzLWNvbG9yL2luZGV4LmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvdXJsLWpvaW4vbGliL3VybC1qb2luLmpzIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcImFzc2VydFwiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcImV2ZW50c1wiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcImZzXCIiLCJ3ZWJwYWNrOi8vbWFpbGd1bi9leHRlcm5hbCBub2RlLWNvbW1vbmpzIFwiaHR0cFwiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcImh0dHBzXCIiLCJ3ZWJwYWNrOi8vbWFpbGd1bi9leHRlcm5hbCBub2RlLWNvbW1vbmpzIFwib3NcIiIsIndlYnBhY2s6Ly9tYWlsZ3VuL2V4dGVybmFsIG5vZGUtY29tbW9uanMgXCJwYXRoXCIiLCJ3ZWJwYWNrOi8vbWFpbGd1bi9leHRlcm5hbCBub2RlLWNvbW1vbmpzIFwic3RyZWFtXCIiLCJ3ZWJwYWNrOi8vbWFpbGd1bi9leHRlcm5hbCBub2RlLWNvbW1vbmpzIFwidHR5XCIiLCJ3ZWJwYWNrOi8vbWFpbGd1bi9leHRlcm5hbCBub2RlLWNvbW1vbmpzIFwidXJsXCIiLCJ3ZWJwYWNrOi8vbWFpbGd1bi9leHRlcm5hbCBub2RlLWNvbW1vbmpzIFwidXRpbFwiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcInpsaWJcIiIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2F4aW9zL2Rpc3Qvbm9kZS9heGlvcy5janMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly9tYWlsZ3VuL3dlYnBhY2svcnVudGltZS9ub2RlIG1vZHVsZSBkZWNvcmF0b3IiLCJ3ZWJwYWNrOi8vbWFpbGd1bi93ZWJwYWNrL3N0YXJ0dXAiXSwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKVxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuXHRlbHNlIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZClcblx0XHRkZWZpbmUoW10sIGZhY3RvcnkpO1xuXHRlbHNlIGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jylcblx0XHRleHBvcnRzW1wibWFpbGd1blwiXSA9IGZhY3RvcnkoKTtcblx0ZWxzZVxuXHRcdHJvb3RbXCJtYWlsZ3VuXCJdID0gZmFjdG9yeSgpO1xufSkodGhpcywgKCkgPT4ge1xucmV0dXJuICIsIm1vZHVsZS5leHBvcnRzID1cbntcbiAgcGFyYWxsZWwgICAgICA6IHJlcXVpcmUoJy4vcGFyYWxsZWwuanMnKSxcbiAgc2VyaWFsICAgICAgICA6IHJlcXVpcmUoJy4vc2VyaWFsLmpzJyksXG4gIHNlcmlhbE9yZGVyZWQgOiByZXF1aXJlKCcuL3NlcmlhbE9yZGVyZWQuanMnKVxufTtcbiIsIi8vIEFQSVxubW9kdWxlLmV4cG9ydHMgPSBhYm9ydDtcblxuLyoqXG4gKiBBYm9ydHMgbGVmdG92ZXIgYWN0aXZlIGpvYnNcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gc3RhdGUgLSBjdXJyZW50IHN0YXRlIG9iamVjdFxuICovXG5mdW5jdGlvbiBhYm9ydChzdGF0ZSlcbntcbiAgT2JqZWN0LmtleXMoc3RhdGUuam9icykuZm9yRWFjaChjbGVhbi5iaW5kKHN0YXRlKSk7XG5cbiAgLy8gcmVzZXQgbGVmdG92ZXIgam9ic1xuICBzdGF0ZS5qb2JzID0ge307XG59XG5cbi8qKlxuICogQ2xlYW5zIHVwIGxlZnRvdmVyIGpvYiBieSBpbnZva2luZyBhYm9ydCBmdW5jdGlvbiBmb3IgdGhlIHByb3ZpZGVkIGpvYiBpZFxuICpcbiAqIEB0aGlzICBzdGF0ZVxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBrZXkgLSBqb2IgaWQgdG8gYWJvcnRcbiAqL1xuZnVuY3Rpb24gY2xlYW4oa2V5KVxue1xuICBpZiAodHlwZW9mIHRoaXMuam9ic1trZXldID09ICdmdW5jdGlvbicpXG4gIHtcbiAgICB0aGlzLmpvYnNba2V5XSgpO1xuICB9XG59XG4iLCJ2YXIgZGVmZXIgPSByZXF1aXJlKCcuL2RlZmVyLmpzJyk7XG5cbi8vIEFQSVxubW9kdWxlLmV4cG9ydHMgPSBhc3luYztcblxuLyoqXG4gKiBSdW5zIHByb3ZpZGVkIGNhbGxiYWNrIGFzeW5jaHJvbm91c2x5XG4gKiBldmVuIGlmIGNhbGxiYWNrIGl0c2VsZiBpcyBub3RcbiAqXG4gKiBAcGFyYW0gICB7ZnVuY3Rpb259IGNhbGxiYWNrIC0gY2FsbGJhY2sgdG8gaW52b2tlXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259IC0gYXVnbWVudGVkIGNhbGxiYWNrXG4gKi9cbmZ1bmN0aW9uIGFzeW5jKGNhbGxiYWNrKVxue1xuICB2YXIgaXNBc3luYyA9IGZhbHNlO1xuXG4gIC8vIGNoZWNrIGlmIGFzeW5jIGhhcHBlbmVkXG4gIGRlZmVyKGZ1bmN0aW9uKCkgeyBpc0FzeW5jID0gdHJ1ZTsgfSk7XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIGFzeW5jX2NhbGxiYWNrKGVyciwgcmVzdWx0KVxuICB7XG4gICAgaWYgKGlzQXN5bmMpXG4gICAge1xuICAgICAgY2FsbGJhY2soZXJyLCByZXN1bHQpO1xuICAgIH1cbiAgICBlbHNlXG4gICAge1xuICAgICAgZGVmZXIoZnVuY3Rpb24gbmV4dFRpY2tfY2FsbGJhY2soKVxuICAgICAge1xuICAgICAgICBjYWxsYmFjayhlcnIsIHJlc3VsdCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH07XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGRlZmVyO1xuXG4vKipcbiAqIFJ1bnMgcHJvdmlkZWQgZnVuY3Rpb24gb24gbmV4dCBpdGVyYXRpb24gb2YgdGhlIGV2ZW50IGxvb3BcbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBmbiAtIGZ1bmN0aW9uIHRvIHJ1blxuICovXG5mdW5jdGlvbiBkZWZlcihmbilcbntcbiAgdmFyIG5leHRUaWNrID0gdHlwZW9mIHNldEltbWVkaWF0ZSA9PSAnZnVuY3Rpb24nXG4gICAgPyBzZXRJbW1lZGlhdGVcbiAgICA6IChcbiAgICAgIHR5cGVvZiBwcm9jZXNzID09ICdvYmplY3QnICYmIHR5cGVvZiBwcm9jZXNzLm5leHRUaWNrID09ICdmdW5jdGlvbidcbiAgICAgID8gcHJvY2Vzcy5uZXh0VGlja1xuICAgICAgOiBudWxsXG4gICAgKTtcblxuICBpZiAobmV4dFRpY2spXG4gIHtcbiAgICBuZXh0VGljayhmbik7XG4gIH1cbiAgZWxzZVxuICB7XG4gICAgc2V0VGltZW91dChmbiwgMCk7XG4gIH1cbn1cbiIsInZhciBhc3luYyA9IHJlcXVpcmUoJy4vYXN5bmMuanMnKVxuICAsIGFib3J0ID0gcmVxdWlyZSgnLi9hYm9ydC5qcycpXG4gIDtcblxuLy8gQVBJXG5tb2R1bGUuZXhwb3J0cyA9IGl0ZXJhdGU7XG5cbi8qKlxuICogSXRlcmF0ZXMgb3ZlciBlYWNoIGpvYiBvYmplY3RcbiAqXG4gKiBAcGFyYW0ge2FycmF5fG9iamVjdH0gbGlzdCAtIGFycmF5IG9yIG9iamVjdCAobmFtZWQgbGlzdCkgdG8gaXRlcmF0ZSBvdmVyXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBpdGVyYXRvciAtIGl0ZXJhdG9yIHRvIHJ1blxuICogQHBhcmFtIHtvYmplY3R9IHN0YXRlIC0gY3VycmVudCBqb2Igc3RhdHVzXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFjayAtIGludm9rZWQgd2hlbiBhbGwgZWxlbWVudHMgcHJvY2Vzc2VkXG4gKi9cbmZ1bmN0aW9uIGl0ZXJhdGUobGlzdCwgaXRlcmF0b3IsIHN0YXRlLCBjYWxsYmFjaylcbntcbiAgLy8gc3RvcmUgY3VycmVudCBpbmRleFxuICB2YXIga2V5ID0gc3RhdGVbJ2tleWVkTGlzdCddID8gc3RhdGVbJ2tleWVkTGlzdCddW3N0YXRlLmluZGV4XSA6IHN0YXRlLmluZGV4O1xuXG4gIHN0YXRlLmpvYnNba2V5XSA9IHJ1bkpvYihpdGVyYXRvciwga2V5LCBsaXN0W2tleV0sIGZ1bmN0aW9uKGVycm9yLCBvdXRwdXQpXG4gIHtcbiAgICAvLyBkb24ndCByZXBlYXQgeW91cnNlbGZcbiAgICAvLyBza2lwIHNlY29uZGFyeSBjYWxsYmFja3NcbiAgICBpZiAoIShrZXkgaW4gc3RhdGUuam9icykpXG4gICAge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGNsZWFuIHVwIGpvYnNcbiAgICBkZWxldGUgc3RhdGUuam9ic1trZXldO1xuXG4gICAgaWYgKGVycm9yKVxuICAgIHtcbiAgICAgIC8vIGRvbid0IHByb2Nlc3MgcmVzdCBvZiB0aGUgcmVzdWx0c1xuICAgICAgLy8gc3RvcCBzdGlsbCBhY3RpdmUgam9ic1xuICAgICAgLy8gYW5kIHJlc2V0IHRoZSBsaXN0XG4gICAgICBhYm9ydChzdGF0ZSk7XG4gICAgfVxuICAgIGVsc2VcbiAgICB7XG4gICAgICBzdGF0ZS5yZXN1bHRzW2tleV0gPSBvdXRwdXQ7XG4gICAgfVxuXG4gICAgLy8gcmV0dXJuIHNhbHZhZ2VkIHJlc3VsdHNcbiAgICBjYWxsYmFjayhlcnJvciwgc3RhdGUucmVzdWx0cyk7XG4gIH0pO1xufVxuXG4vKipcbiAqIFJ1bnMgaXRlcmF0b3Igb3ZlciBwcm92aWRlZCBqb2IgZWxlbWVudFxuICpcbiAqIEBwYXJhbSAgIHtmdW5jdGlvbn0gaXRlcmF0b3IgLSBpdGVyYXRvciB0byBpbnZva2VcbiAqIEBwYXJhbSAgIHtzdHJpbmd8bnVtYmVyfSBrZXkgLSBrZXkvaW5kZXggb2YgdGhlIGVsZW1lbnQgaW4gdGhlIGxpc3Qgb2Ygam9ic1xuICogQHBhcmFtICAge21peGVkfSBpdGVtIC0gam9iIGRlc2NyaXB0aW9uXG4gKiBAcGFyYW0gICB7ZnVuY3Rpb259IGNhbGxiYWNrIC0gaW52b2tlZCBhZnRlciBpdGVyYXRvciBpcyBkb25lIHdpdGggdGhlIGpvYlxuICogQHJldHVybnMge2Z1bmN0aW9ufG1peGVkfSAtIGpvYiBhYm9ydCBmdW5jdGlvbiBvciBzb21ldGhpbmcgZWxzZVxuICovXG5mdW5jdGlvbiBydW5Kb2IoaXRlcmF0b3IsIGtleSwgaXRlbSwgY2FsbGJhY2spXG57XG4gIHZhciBhYm9ydGVyO1xuXG4gIC8vIGFsbG93IHNob3J0Y3V0IGlmIGl0ZXJhdG9yIGV4cGVjdHMgb25seSB0d28gYXJndW1lbnRzXG4gIGlmIChpdGVyYXRvci5sZW5ndGggPT0gMilcbiAge1xuICAgIGFib3J0ZXIgPSBpdGVyYXRvcihpdGVtLCBhc3luYyhjYWxsYmFjaykpO1xuICB9XG4gIC8vIG90aGVyd2lzZSBnbyB3aXRoIGZ1bGwgdGhyZWUgYXJndW1lbnRzXG4gIGVsc2VcbiAge1xuICAgIGFib3J0ZXIgPSBpdGVyYXRvcihpdGVtLCBrZXksIGFzeW5jKGNhbGxiYWNrKSk7XG4gIH1cblxuICByZXR1cm4gYWJvcnRlcjtcbn1cbiIsIi8vIEFQSVxubW9kdWxlLmV4cG9ydHMgPSBzdGF0ZTtcblxuLyoqXG4gKiBDcmVhdGVzIGluaXRpYWwgc3RhdGUgb2JqZWN0XG4gKiBmb3IgaXRlcmF0aW9uIG92ZXIgbGlzdFxuICpcbiAqIEBwYXJhbSAgIHthcnJheXxvYmplY3R9IGxpc3QgLSBsaXN0IHRvIGl0ZXJhdGUgb3ZlclxuICogQHBhcmFtICAge2Z1bmN0aW9ufG51bGx9IHNvcnRNZXRob2QgLSBmdW5jdGlvbiB0byB1c2UgZm9yIGtleXMgc29ydCxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yIGBudWxsYCB0byBrZWVwIHRoZW0gYXMgaXNcbiAqIEByZXR1cm5zIHtvYmplY3R9IC0gaW5pdGlhbCBzdGF0ZSBvYmplY3RcbiAqL1xuZnVuY3Rpb24gc3RhdGUobGlzdCwgc29ydE1ldGhvZClcbntcbiAgdmFyIGlzTmFtZWRMaXN0ID0gIUFycmF5LmlzQXJyYXkobGlzdClcbiAgICAsIGluaXRTdGF0ZSA9XG4gICAge1xuICAgICAgaW5kZXggICAgOiAwLFxuICAgICAga2V5ZWRMaXN0OiBpc05hbWVkTGlzdCB8fCBzb3J0TWV0aG9kID8gT2JqZWN0LmtleXMobGlzdCkgOiBudWxsLFxuICAgICAgam9icyAgICAgOiB7fSxcbiAgICAgIHJlc3VsdHMgIDogaXNOYW1lZExpc3QgPyB7fSA6IFtdLFxuICAgICAgc2l6ZSAgICAgOiBpc05hbWVkTGlzdCA/IE9iamVjdC5rZXlzKGxpc3QpLmxlbmd0aCA6IGxpc3QubGVuZ3RoXG4gICAgfVxuICAgIDtcblxuICBpZiAoc29ydE1ldGhvZClcbiAge1xuICAgIC8vIHNvcnQgYXJyYXkga2V5cyBiYXNlZCBvbiBpdCdzIHZhbHVlc1xuICAgIC8vIHNvcnQgb2JqZWN0J3Mga2V5cyBqdXN0IG9uIG93biBtZXJpdFxuICAgIGluaXRTdGF0ZS5rZXllZExpc3Quc29ydChpc05hbWVkTGlzdCA/IHNvcnRNZXRob2QgOiBmdW5jdGlvbihhLCBiKVxuICAgIHtcbiAgICAgIHJldHVybiBzb3J0TWV0aG9kKGxpc3RbYV0sIGxpc3RbYl0pO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGluaXRTdGF0ZTtcbn1cbiIsInZhciBhYm9ydCA9IHJlcXVpcmUoJy4vYWJvcnQuanMnKVxuICAsIGFzeW5jID0gcmVxdWlyZSgnLi9hc3luYy5qcycpXG4gIDtcblxuLy8gQVBJXG5tb2R1bGUuZXhwb3J0cyA9IHRlcm1pbmF0b3I7XG5cbi8qKlxuICogVGVybWluYXRlcyBqb2JzIGluIHRoZSBhdHRhY2hlZCBzdGF0ZSBjb250ZXh0XG4gKlxuICogQHRoaXMgIEFzeW5jS2l0U3RhdGUjXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFjayAtIGZpbmFsIGNhbGxiYWNrIHRvIGludm9rZSBhZnRlciB0ZXJtaW5hdGlvblxuICovXG5mdW5jdGlvbiB0ZXJtaW5hdG9yKGNhbGxiYWNrKVxue1xuICBpZiAoIU9iamVjdC5rZXlzKHRoaXMuam9icykubGVuZ3RoKVxuICB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gZmFzdCBmb3J3YXJkIGl0ZXJhdGlvbiBpbmRleFxuICB0aGlzLmluZGV4ID0gdGhpcy5zaXplO1xuXG4gIC8vIGFib3J0IGpvYnNcbiAgYWJvcnQodGhpcyk7XG5cbiAgLy8gc2VuZCBiYWNrIHJlc3VsdHMgd2UgaGF2ZSBzbyBmYXJcbiAgYXN5bmMoY2FsbGJhY2spKG51bGwsIHRoaXMucmVzdWx0cyk7XG59XG4iLCJ2YXIgaXRlcmF0ZSAgICA9IHJlcXVpcmUoJy4vbGliL2l0ZXJhdGUuanMnKVxuICAsIGluaXRTdGF0ZSAgPSByZXF1aXJlKCcuL2xpYi9zdGF0ZS5qcycpXG4gICwgdGVybWluYXRvciA9IHJlcXVpcmUoJy4vbGliL3Rlcm1pbmF0b3IuanMnKVxuICA7XG5cbi8vIFB1YmxpYyBBUElcbm1vZHVsZS5leHBvcnRzID0gcGFyYWxsZWw7XG5cbi8qKlxuICogUnVucyBpdGVyYXRvciBvdmVyIHByb3ZpZGVkIGFycmF5IGVsZW1lbnRzIGluIHBhcmFsbGVsXG4gKlxuICogQHBhcmFtICAge2FycmF5fG9iamVjdH0gbGlzdCAtIGFycmF5IG9yIG9iamVjdCAobmFtZWQgbGlzdCkgdG8gaXRlcmF0ZSBvdmVyXG4gKiBAcGFyYW0gICB7ZnVuY3Rpb259IGl0ZXJhdG9yIC0gaXRlcmF0b3IgdG8gcnVuXG4gKiBAcGFyYW0gICB7ZnVuY3Rpb259IGNhbGxiYWNrIC0gaW52b2tlZCB3aGVuIGFsbCBlbGVtZW50cyBwcm9jZXNzZWRcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gLSBqb2JzIHRlcm1pbmF0b3JcbiAqL1xuZnVuY3Rpb24gcGFyYWxsZWwobGlzdCwgaXRlcmF0b3IsIGNhbGxiYWNrKVxue1xuICB2YXIgc3RhdGUgPSBpbml0U3RhdGUobGlzdCk7XG5cbiAgd2hpbGUgKHN0YXRlLmluZGV4IDwgKHN0YXRlWydrZXllZExpc3QnXSB8fCBsaXN0KS5sZW5ndGgpXG4gIHtcbiAgICBpdGVyYXRlKGxpc3QsIGl0ZXJhdG9yLCBzdGF0ZSwgZnVuY3Rpb24oZXJyb3IsIHJlc3VsdClcbiAgICB7XG4gICAgICBpZiAoZXJyb3IpXG4gICAgICB7XG4gICAgICAgIGNhbGxiYWNrKGVycm9yLCByZXN1bHQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIGxvb2tzIGxpa2UgaXQncyB0aGUgbGFzdCBvbmVcbiAgICAgIGlmIChPYmplY3Qua2V5cyhzdGF0ZS5qb2JzKS5sZW5ndGggPT09IDApXG4gICAgICB7XG4gICAgICAgIGNhbGxiYWNrKG51bGwsIHN0YXRlLnJlc3VsdHMpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBzdGF0ZS5pbmRleCsrO1xuICB9XG5cbiAgcmV0dXJuIHRlcm1pbmF0b3IuYmluZChzdGF0ZSwgY2FsbGJhY2spO1xufVxuIiwidmFyIHNlcmlhbE9yZGVyZWQgPSByZXF1aXJlKCcuL3NlcmlhbE9yZGVyZWQuanMnKTtcblxuLy8gUHVibGljIEFQSVxubW9kdWxlLmV4cG9ydHMgPSBzZXJpYWw7XG5cbi8qKlxuICogUnVucyBpdGVyYXRvciBvdmVyIHByb3ZpZGVkIGFycmF5IGVsZW1lbnRzIGluIHNlcmllc1xuICpcbiAqIEBwYXJhbSAgIHthcnJheXxvYmplY3R9IGxpc3QgLSBhcnJheSBvciBvYmplY3QgKG5hbWVkIGxpc3QpIHRvIGl0ZXJhdGUgb3ZlclxuICogQHBhcmFtICAge2Z1bmN0aW9ufSBpdGVyYXRvciAtIGl0ZXJhdG9yIHRvIHJ1blxuICogQHBhcmFtICAge2Z1bmN0aW9ufSBjYWxsYmFjayAtIGludm9rZWQgd2hlbiBhbGwgZWxlbWVudHMgcHJvY2Vzc2VkXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259IC0gam9icyB0ZXJtaW5hdG9yXG4gKi9cbmZ1bmN0aW9uIHNlcmlhbChsaXN0LCBpdGVyYXRvciwgY2FsbGJhY2spXG57XG4gIHJldHVybiBzZXJpYWxPcmRlcmVkKGxpc3QsIGl0ZXJhdG9yLCBudWxsLCBjYWxsYmFjayk7XG59XG4iLCJ2YXIgaXRlcmF0ZSAgICA9IHJlcXVpcmUoJy4vbGliL2l0ZXJhdGUuanMnKVxuICAsIGluaXRTdGF0ZSAgPSByZXF1aXJlKCcuL2xpYi9zdGF0ZS5qcycpXG4gICwgdGVybWluYXRvciA9IHJlcXVpcmUoJy4vbGliL3Rlcm1pbmF0b3IuanMnKVxuICA7XG5cbi8vIFB1YmxpYyBBUElcbm1vZHVsZS5leHBvcnRzID0gc2VyaWFsT3JkZXJlZDtcbi8vIHNvcnRpbmcgaGVscGVyc1xubW9kdWxlLmV4cG9ydHMuYXNjZW5kaW5nICA9IGFzY2VuZGluZztcbm1vZHVsZS5leHBvcnRzLmRlc2NlbmRpbmcgPSBkZXNjZW5kaW5nO1xuXG4vKipcbiAqIFJ1bnMgaXRlcmF0b3Igb3ZlciBwcm92aWRlZCBzb3J0ZWQgYXJyYXkgZWxlbWVudHMgaW4gc2VyaWVzXG4gKlxuICogQHBhcmFtICAge2FycmF5fG9iamVjdH0gbGlzdCAtIGFycmF5IG9yIG9iamVjdCAobmFtZWQgbGlzdCkgdG8gaXRlcmF0ZSBvdmVyXG4gKiBAcGFyYW0gICB7ZnVuY3Rpb259IGl0ZXJhdG9yIC0gaXRlcmF0b3IgdG8gcnVuXG4gKiBAcGFyYW0gICB7ZnVuY3Rpb259IHNvcnRNZXRob2QgLSBjdXN0b20gc29ydCBmdW5jdGlvblxuICogQHBhcmFtICAge2Z1bmN0aW9ufSBjYWxsYmFjayAtIGludm9rZWQgd2hlbiBhbGwgZWxlbWVudHMgcHJvY2Vzc2VkXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259IC0gam9icyB0ZXJtaW5hdG9yXG4gKi9cbmZ1bmN0aW9uIHNlcmlhbE9yZGVyZWQobGlzdCwgaXRlcmF0b3IsIHNvcnRNZXRob2QsIGNhbGxiYWNrKVxue1xuICB2YXIgc3RhdGUgPSBpbml0U3RhdGUobGlzdCwgc29ydE1ldGhvZCk7XG5cbiAgaXRlcmF0ZShsaXN0LCBpdGVyYXRvciwgc3RhdGUsIGZ1bmN0aW9uIGl0ZXJhdG9ySGFuZGxlcihlcnJvciwgcmVzdWx0KVxuICB7XG4gICAgaWYgKGVycm9yKVxuICAgIHtcbiAgICAgIGNhbGxiYWNrKGVycm9yLCByZXN1bHQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHN0YXRlLmluZGV4Kys7XG5cbiAgICAvLyBhcmUgd2UgdGhlcmUgeWV0P1xuICAgIGlmIChzdGF0ZS5pbmRleCA8IChzdGF0ZVsna2V5ZWRMaXN0J10gfHwgbGlzdCkubGVuZ3RoKVxuICAgIHtcbiAgICAgIGl0ZXJhdGUobGlzdCwgaXRlcmF0b3IsIHN0YXRlLCBpdGVyYXRvckhhbmRsZXIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGRvbmUgaGVyZVxuICAgIGNhbGxiYWNrKG51bGwsIHN0YXRlLnJlc3VsdHMpO1xuICB9KTtcblxuICByZXR1cm4gdGVybWluYXRvci5iaW5kKHN0YXRlLCBjYWxsYmFjayk7XG59XG5cbi8qXG4gKiAtLSBTb3J0IG1ldGhvZHNcbiAqL1xuXG4vKipcbiAqIHNvcnQgaGVscGVyIHRvIHNvcnQgYXJyYXkgZWxlbWVudHMgaW4gYXNjZW5kaW5nIG9yZGVyXG4gKlxuICogQHBhcmFtICAge21peGVkfSBhIC0gYW4gaXRlbSB0byBjb21wYXJlXG4gKiBAcGFyYW0gICB7bWl4ZWR9IGIgLSBhbiBpdGVtIHRvIGNvbXBhcmVcbiAqIEByZXR1cm5zIHtudW1iZXJ9IC0gY29tcGFyaXNvbiByZXN1bHRcbiAqL1xuZnVuY3Rpb24gYXNjZW5kaW5nKGEsIGIpXG57XG4gIHJldHVybiBhIDwgYiA/IC0xIDogYSA+IGIgPyAxIDogMDtcbn1cblxuLyoqXG4gKiBzb3J0IGhlbHBlciB0byBzb3J0IGFycmF5IGVsZW1lbnRzIGluIGRlc2NlbmRpbmcgb3JkZXJcbiAqXG4gKiBAcGFyYW0gICB7bWl4ZWR9IGEgLSBhbiBpdGVtIHRvIGNvbXBhcmVcbiAqIEBwYXJhbSAgIHttaXhlZH0gYiAtIGFuIGl0ZW0gdG8gY29tcGFyZVxuICogQHJldHVybnMge251bWJlcn0gLSBjb21wYXJpc29uIHJlc3VsdFxuICovXG5mdW5jdGlvbiBkZXNjZW5kaW5nKGEsIGIpXG57XG4gIHJldHVybiAtMSAqIGFzY2VuZGluZyhhLCBiKTtcbn1cbiIsInZhciBDb21iaW5lZFN0cmVhbSA9IHJlcXVpcmUoJ2NvbWJpbmVkLXN0cmVhbScpO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG52YXIgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcbnZhciBodHRwID0gcmVxdWlyZSgnaHR0cCcpO1xudmFyIGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKTtcbnZhciBwYXJzZVVybCA9IHJlcXVpcmUoJ3VybCcpLnBhcnNlO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcbnZhciBTdHJlYW0gPSByZXF1aXJlKCdzdHJlYW0nKS5TdHJlYW07XG52YXIgbWltZSA9IHJlcXVpcmUoJ21pbWUtdHlwZXMnKTtcbnZhciBhc3luY2tpdCA9IHJlcXVpcmUoJ2FzeW5ja2l0Jyk7XG52YXIgcG9wdWxhdGUgPSByZXF1aXJlKCcuL3BvcHVsYXRlLmpzJyk7XG5cbi8vIFB1YmxpYyBBUElcbm1vZHVsZS5leHBvcnRzID0gRm9ybURhdGE7XG5cbi8vIG1ha2UgaXQgYSBTdHJlYW1cbnV0aWwuaW5oZXJpdHMoRm9ybURhdGEsIENvbWJpbmVkU3RyZWFtKTtcblxuLyoqXG4gKiBDcmVhdGUgcmVhZGFibGUgXCJtdWx0aXBhcnQvZm9ybS1kYXRhXCIgc3RyZWFtcy5cbiAqIENhbiBiZSB1c2VkIHRvIHN1Ym1pdCBmb3Jtc1xuICogYW5kIGZpbGUgdXBsb2FkcyB0byBvdGhlciB3ZWIgYXBwbGljYXRpb25zLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBQcm9wZXJ0aWVzIHRvIGJlIGFkZGVkL292ZXJyaWRlbiBmb3IgRm9ybURhdGEgYW5kIENvbWJpbmVkU3RyZWFtXG4gKi9cbmZ1bmN0aW9uIEZvcm1EYXRhKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEZvcm1EYXRhKSkge1xuICAgIHJldHVybiBuZXcgRm9ybURhdGEob3B0aW9ucyk7XG4gIH1cblxuICB0aGlzLl9vdmVyaGVhZExlbmd0aCA9IDA7XG4gIHRoaXMuX3ZhbHVlTGVuZ3RoID0gMDtcbiAgdGhpcy5fdmFsdWVzVG9NZWFzdXJlID0gW107XG5cbiAgQ29tYmluZWRTdHJlYW0uY2FsbCh0aGlzKTtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgZm9yICh2YXIgb3B0aW9uIGluIG9wdGlvbnMpIHtcbiAgICB0aGlzW29wdGlvbl0gPSBvcHRpb25zW29wdGlvbl07XG4gIH1cbn1cblxuRm9ybURhdGEuTElORV9CUkVBSyA9ICdcXHJcXG4nO1xuRm9ybURhdGEuREVGQVVMVF9DT05URU5UX1RZUEUgPSAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJztcblxuRm9ybURhdGEucHJvdG90eXBlLmFwcGVuZCA9IGZ1bmN0aW9uKGZpZWxkLCB2YWx1ZSwgb3B0aW9ucykge1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIGFsbG93IGZpbGVuYW1lIGFzIHNpbmdsZSBvcHRpb25cbiAgaWYgKHR5cGVvZiBvcHRpb25zID09ICdzdHJpbmcnKSB7XG4gICAgb3B0aW9ucyA9IHtmaWxlbmFtZTogb3B0aW9uc307XG4gIH1cblxuICB2YXIgYXBwZW5kID0gQ29tYmluZWRTdHJlYW0ucHJvdG90eXBlLmFwcGVuZC5iaW5kKHRoaXMpO1xuXG4gIC8vIGFsbCB0aGF0IHN0cmVhbXkgYnVzaW5lc3MgY2FuJ3QgaGFuZGxlIG51bWJlcnNcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJykge1xuICAgIHZhbHVlID0gJycgKyB2YWx1ZTtcbiAgfVxuXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mZWxpeGdlL25vZGUtZm9ybS1kYXRhL2lzc3Vlcy8zOFxuICBpZiAodXRpbC5pc0FycmF5KHZhbHVlKSkge1xuICAgIC8vIFBsZWFzZSBjb252ZXJ0IHlvdXIgYXJyYXkgaW50byBzdHJpbmdcbiAgICAvLyB0aGUgd2F5IHdlYiBzZXJ2ZXIgZXhwZWN0cyBpdFxuICAgIHRoaXMuX2Vycm9yKG5ldyBFcnJvcignQXJyYXlzIGFyZSBub3Qgc3VwcG9ydGVkLicpKTtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgaGVhZGVyID0gdGhpcy5fbXVsdGlQYXJ0SGVhZGVyKGZpZWxkLCB2YWx1ZSwgb3B0aW9ucyk7XG4gIHZhciBmb290ZXIgPSB0aGlzLl9tdWx0aVBhcnRGb290ZXIoKTtcblxuICBhcHBlbmQoaGVhZGVyKTtcbiAgYXBwZW5kKHZhbHVlKTtcbiAgYXBwZW5kKGZvb3Rlcik7XG5cbiAgLy8gcGFzcyBhbG9uZyBvcHRpb25zLmtub3duTGVuZ3RoXG4gIHRoaXMuX3RyYWNrTGVuZ3RoKGhlYWRlciwgdmFsdWUsIG9wdGlvbnMpO1xufTtcblxuRm9ybURhdGEucHJvdG90eXBlLl90cmFja0xlbmd0aCA9IGZ1bmN0aW9uKGhlYWRlciwgdmFsdWUsIG9wdGlvbnMpIHtcbiAgdmFyIHZhbHVlTGVuZ3RoID0gMDtcblxuICAvLyB1c2VkIHcvIGdldExlbmd0aFN5bmMoKSwgd2hlbiBsZW5ndGggaXMga25vd24uXG4gIC8vIGUuZy4gZm9yIHN0cmVhbWluZyBkaXJlY3RseSBmcm9tIGEgcmVtb3RlIHNlcnZlcixcbiAgLy8gdy8gYSBrbm93biBmaWxlIGEgc2l6ZSwgYW5kIG5vdCB3YW50aW5nIHRvIHdhaXQgZm9yXG4gIC8vIGluY29taW5nIGZpbGUgdG8gZmluaXNoIHRvIGdldCBpdHMgc2l6ZS5cbiAgaWYgKG9wdGlvbnMua25vd25MZW5ndGggIT0gbnVsbCkge1xuICAgIHZhbHVlTGVuZ3RoICs9ICtvcHRpb25zLmtub3duTGVuZ3RoO1xuICB9IGVsc2UgaWYgKEJ1ZmZlci5pc0J1ZmZlcih2YWx1ZSkpIHtcbiAgICB2YWx1ZUxlbmd0aCA9IHZhbHVlLmxlbmd0aDtcbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFsdWVMZW5ndGggPSBCdWZmZXIuYnl0ZUxlbmd0aCh2YWx1ZSk7XG4gIH1cblxuICB0aGlzLl92YWx1ZUxlbmd0aCArPSB2YWx1ZUxlbmd0aDtcblxuICAvLyBAY2hlY2sgd2h5IGFkZCBDUkxGPyBkb2VzIHRoaXMgYWNjb3VudCBmb3IgY3VzdG9tL211bHRpcGxlIENSTEZzP1xuICB0aGlzLl9vdmVyaGVhZExlbmd0aCArPVxuICAgIEJ1ZmZlci5ieXRlTGVuZ3RoKGhlYWRlcikgK1xuICAgIEZvcm1EYXRhLkxJTkVfQlJFQUsubGVuZ3RoO1xuXG4gIC8vIGVtcHR5IG9yIGVpdGhlciBkb2Vzbid0IGhhdmUgcGF0aCBvciBub3QgYW4gaHR0cCByZXNwb25zZSBvciBub3QgYSBzdHJlYW1cbiAgaWYgKCF2YWx1ZSB8fCAoICF2YWx1ZS5wYXRoICYmICEodmFsdWUucmVhZGFibGUgJiYgdmFsdWUuaGFzT3duUHJvcGVydHkoJ2h0dHBWZXJzaW9uJykpICYmICEodmFsdWUgaW5zdGFuY2VvZiBTdHJlYW0pKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIG5vIG5lZWQgdG8gYm90aGVyIHdpdGggdGhlIGxlbmd0aFxuICBpZiAoIW9wdGlvbnMua25vd25MZW5ndGgpIHtcbiAgICB0aGlzLl92YWx1ZXNUb01lYXN1cmUucHVzaCh2YWx1ZSk7XG4gIH1cbn07XG5cbkZvcm1EYXRhLnByb3RvdHlwZS5fbGVuZ3RoUmV0cmlldmVyID0gZnVuY3Rpb24odmFsdWUsIGNhbGxiYWNrKSB7XG5cbiAgaWYgKHZhbHVlLmhhc093blByb3BlcnR5KCdmZCcpKSB7XG5cbiAgICAvLyB0YWtlIHJlYWQgcmFuZ2UgaW50byBhIGFjY291bnRcbiAgICAvLyBgZW5kYCA9IEluZmluaXR5IOKAkz4gcmVhZCBmaWxlIHRpbGwgdGhlIGVuZFxuICAgIC8vXG4gICAgLy8gVE9ETzogTG9va3MgbGlrZSB0aGVyZSBpcyBidWcgaW4gTm9kZSBmcy5jcmVhdGVSZWFkU3RyZWFtXG4gICAgLy8gaXQgZG9lc24ndCByZXNwZWN0IGBlbmRgIG9wdGlvbnMgd2l0aG91dCBgc3RhcnRgIG9wdGlvbnNcbiAgICAvLyBGaXggaXQgd2hlbiBub2RlIGZpeGVzIGl0LlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9qb3llbnQvbm9kZS9pc3N1ZXMvNzgxOVxuICAgIGlmICh2YWx1ZS5lbmQgIT0gdW5kZWZpbmVkICYmIHZhbHVlLmVuZCAhPSBJbmZpbml0eSAmJiB2YWx1ZS5zdGFydCAhPSB1bmRlZmluZWQpIHtcblxuICAgICAgLy8gd2hlbiBlbmQgc3BlY2lmaWVkXG4gICAgICAvLyBubyBuZWVkIHRvIGNhbGN1bGF0ZSByYW5nZVxuICAgICAgLy8gaW5jbHVzaXZlLCBzdGFydHMgd2l0aCAwXG4gICAgICBjYWxsYmFjayhudWxsLCB2YWx1ZS5lbmQgKyAxIC0gKHZhbHVlLnN0YXJ0ID8gdmFsdWUuc3RhcnQgOiAwKSk7XG5cbiAgICAvLyBub3QgdGhhdCBmYXN0IHNub29weVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBzdGlsbCBuZWVkIHRvIGZldGNoIGZpbGUgc2l6ZSBmcm9tIGZzXG4gICAgICBmcy5zdGF0KHZhbHVlLnBhdGgsIGZ1bmN0aW9uKGVyciwgc3RhdCkge1xuXG4gICAgICAgIHZhciBmaWxlU2l6ZTtcblxuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgY2FsbGJhY2soZXJyKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyB1cGRhdGUgZmluYWwgc2l6ZSBiYXNlZCBvbiB0aGUgcmFuZ2Ugb3B0aW9uc1xuICAgICAgICBmaWxlU2l6ZSA9IHN0YXQuc2l6ZSAtICh2YWx1ZS5zdGFydCA/IHZhbHVlLnN0YXJ0IDogMCk7XG4gICAgICAgIGNhbGxiYWNrKG51bGwsIGZpbGVTaXplKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAvLyBvciBodHRwIHJlc3BvbnNlXG4gIH0gZWxzZSBpZiAodmFsdWUuaGFzT3duUHJvcGVydHkoJ2h0dHBWZXJzaW9uJykpIHtcbiAgICBjYWxsYmFjayhudWxsLCArdmFsdWUuaGVhZGVyc1snY29udGVudC1sZW5ndGgnXSk7XG5cbiAgLy8gb3IgcmVxdWVzdCBzdHJlYW0gaHR0cDovL2dpdGh1Yi5jb20vbWlrZWFsL3JlcXVlc3RcbiAgfSBlbHNlIGlmICh2YWx1ZS5oYXNPd25Qcm9wZXJ0eSgnaHR0cE1vZHVsZScpKSB7XG4gICAgLy8gd2FpdCB0aWxsIHJlc3BvbnNlIGNvbWUgYmFja1xuICAgIHZhbHVlLm9uKCdyZXNwb25zZScsIGZ1bmN0aW9uKHJlc3BvbnNlKSB7XG4gICAgICB2YWx1ZS5wYXVzZSgpO1xuICAgICAgY2FsbGJhY2sobnVsbCwgK3Jlc3BvbnNlLmhlYWRlcnNbJ2NvbnRlbnQtbGVuZ3RoJ10pO1xuICAgIH0pO1xuICAgIHZhbHVlLnJlc3VtZSgpO1xuXG4gIC8vIHNvbWV0aGluZyBlbHNlXG4gIH0gZWxzZSB7XG4gICAgY2FsbGJhY2soJ1Vua25vd24gc3RyZWFtJyk7XG4gIH1cbn07XG5cbkZvcm1EYXRhLnByb3RvdHlwZS5fbXVsdGlQYXJ0SGVhZGVyID0gZnVuY3Rpb24oZmllbGQsIHZhbHVlLCBvcHRpb25zKSB7XG4gIC8vIGN1c3RvbSBoZWFkZXIgc3BlY2lmaWVkIChhcyBzdHJpbmcpP1xuICAvLyBpdCBiZWNvbWVzIHJlc3BvbnNpYmxlIGZvciBib3VuZGFyeVxuICAvLyAoZS5nLiB0byBoYW5kbGUgZXh0cmEgQ1JMRnMgb24gLk5FVCBzZXJ2ZXJzKVxuICBpZiAodHlwZW9mIG9wdGlvbnMuaGVhZGVyID09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIG9wdGlvbnMuaGVhZGVyO1xuICB9XG5cbiAgdmFyIGNvbnRlbnREaXNwb3NpdGlvbiA9IHRoaXMuX2dldENvbnRlbnREaXNwb3NpdGlvbih2YWx1ZSwgb3B0aW9ucyk7XG4gIHZhciBjb250ZW50VHlwZSA9IHRoaXMuX2dldENvbnRlbnRUeXBlKHZhbHVlLCBvcHRpb25zKTtcblxuICB2YXIgY29udGVudHMgPSAnJztcbiAgdmFyIGhlYWRlcnMgID0ge1xuICAgIC8vIGFkZCBjdXN0b20gZGlzcG9zaXRpb24gYXMgdGhpcmQgZWxlbWVudCBvciBrZWVwIGl0IHR3byBlbGVtZW50cyBpZiBub3RcbiAgICAnQ29udGVudC1EaXNwb3NpdGlvbic6IFsnZm9ybS1kYXRhJywgJ25hbWU9XCInICsgZmllbGQgKyAnXCInXS5jb25jYXQoY29udGVudERpc3Bvc2l0aW9uIHx8IFtdKSxcbiAgICAvLyBpZiBubyBjb250ZW50IHR5cGUuIGFsbG93IGl0IHRvIGJlIGVtcHR5IGFycmF5XG4gICAgJ0NvbnRlbnQtVHlwZSc6IFtdLmNvbmNhdChjb250ZW50VHlwZSB8fCBbXSlcbiAgfTtcblxuICAvLyBhbGxvdyBjdXN0b20gaGVhZGVycy5cbiAgaWYgKHR5cGVvZiBvcHRpb25zLmhlYWRlciA9PSAnb2JqZWN0Jykge1xuICAgIHBvcHVsYXRlKGhlYWRlcnMsIG9wdGlvbnMuaGVhZGVyKTtcbiAgfVxuXG4gIHZhciBoZWFkZXI7XG4gIGZvciAodmFyIHByb3AgaW4gaGVhZGVycykge1xuICAgIGlmICghaGVhZGVycy5oYXNPd25Qcm9wZXJ0eShwcm9wKSkgY29udGludWU7XG4gICAgaGVhZGVyID0gaGVhZGVyc1twcm9wXTtcblxuICAgIC8vIHNraXAgbnVsbGlzaCBoZWFkZXJzLlxuICAgIGlmIChoZWFkZXIgPT0gbnVsbCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gY29udmVydCBhbGwgaGVhZGVycyB0byBhcnJheXMuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGhlYWRlcikpIHtcbiAgICAgIGhlYWRlciA9IFtoZWFkZXJdO1xuICAgIH1cblxuICAgIC8vIGFkZCBub24tZW1wdHkgaGVhZGVycy5cbiAgICBpZiAoaGVhZGVyLmxlbmd0aCkge1xuICAgICAgY29udGVudHMgKz0gcHJvcCArICc6ICcgKyBoZWFkZXIuam9pbignOyAnKSArIEZvcm1EYXRhLkxJTkVfQlJFQUs7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuICctLScgKyB0aGlzLmdldEJvdW5kYXJ5KCkgKyBGb3JtRGF0YS5MSU5FX0JSRUFLICsgY29udGVudHMgKyBGb3JtRGF0YS5MSU5FX0JSRUFLO1xufTtcblxuRm9ybURhdGEucHJvdG90eXBlLl9nZXRDb250ZW50RGlzcG9zaXRpb24gPSBmdW5jdGlvbih2YWx1ZSwgb3B0aW9ucykge1xuXG4gIHZhciBmaWxlbmFtZVxuICAgICwgY29udGVudERpc3Bvc2l0aW9uXG4gICAgO1xuXG4gIGlmICh0eXBlb2Ygb3B0aW9ucy5maWxlcGF0aCA9PT0gJ3N0cmluZycpIHtcbiAgICAvLyBjdXN0b20gZmlsZXBhdGggZm9yIHJlbGF0aXZlIHBhdGhzXG4gICAgZmlsZW5hbWUgPSBwYXRoLm5vcm1hbGl6ZShvcHRpb25zLmZpbGVwYXRoKS5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG4gIH0gZWxzZSBpZiAob3B0aW9ucy5maWxlbmFtZSB8fCB2YWx1ZS5uYW1lIHx8IHZhbHVlLnBhdGgpIHtcbiAgICAvLyBjdXN0b20gZmlsZW5hbWUgdGFrZSBwcmVjZWRlbmNlXG4gICAgLy8gZm9ybWlkYWJsZSBhbmQgdGhlIGJyb3dzZXIgYWRkIGEgbmFtZSBwcm9wZXJ0eVxuICAgIC8vIGZzLSBhbmQgcmVxdWVzdC0gc3RyZWFtcyBoYXZlIHBhdGggcHJvcGVydHlcbiAgICBmaWxlbmFtZSA9IHBhdGguYmFzZW5hbWUob3B0aW9ucy5maWxlbmFtZSB8fCB2YWx1ZS5uYW1lIHx8IHZhbHVlLnBhdGgpO1xuICB9IGVsc2UgaWYgKHZhbHVlLnJlYWRhYmxlICYmIHZhbHVlLmhhc093blByb3BlcnR5KCdodHRwVmVyc2lvbicpKSB7XG4gICAgLy8gb3IgdHJ5IGh0dHAgcmVzcG9uc2VcbiAgICBmaWxlbmFtZSA9IHBhdGguYmFzZW5hbWUodmFsdWUuY2xpZW50Ll9odHRwTWVzc2FnZS5wYXRoIHx8ICcnKTtcbiAgfVxuXG4gIGlmIChmaWxlbmFtZSkge1xuICAgIGNvbnRlbnREaXNwb3NpdGlvbiA9ICdmaWxlbmFtZT1cIicgKyBmaWxlbmFtZSArICdcIic7XG4gIH1cblxuICByZXR1cm4gY29udGVudERpc3Bvc2l0aW9uO1xufTtcblxuRm9ybURhdGEucHJvdG90eXBlLl9nZXRDb250ZW50VHlwZSA9IGZ1bmN0aW9uKHZhbHVlLCBvcHRpb25zKSB7XG5cbiAgLy8gdXNlIGN1c3RvbSBjb250ZW50LXR5cGUgYWJvdmUgYWxsXG4gIHZhciBjb250ZW50VHlwZSA9IG9wdGlvbnMuY29udGVudFR5cGU7XG5cbiAgLy8gb3IgdHJ5IGBuYW1lYCBmcm9tIGZvcm1pZGFibGUsIGJyb3dzZXJcbiAgaWYgKCFjb250ZW50VHlwZSAmJiB2YWx1ZS5uYW1lKSB7XG4gICAgY29udGVudFR5cGUgPSBtaW1lLmxvb2t1cCh2YWx1ZS5uYW1lKTtcbiAgfVxuXG4gIC8vIG9yIHRyeSBgcGF0aGAgZnJvbSBmcy0sIHJlcXVlc3QtIHN0cmVhbXNcbiAgaWYgKCFjb250ZW50VHlwZSAmJiB2YWx1ZS5wYXRoKSB7XG4gICAgY29udGVudFR5cGUgPSBtaW1lLmxvb2t1cCh2YWx1ZS5wYXRoKTtcbiAgfVxuXG4gIC8vIG9yIGlmIGl0J3MgaHR0cC1yZXBvbnNlXG4gIGlmICghY29udGVudFR5cGUgJiYgdmFsdWUucmVhZGFibGUgJiYgdmFsdWUuaGFzT3duUHJvcGVydHkoJ2h0dHBWZXJzaW9uJykpIHtcbiAgICBjb250ZW50VHlwZSA9IHZhbHVlLmhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddO1xuICB9XG5cbiAgLy8gb3IgZ3Vlc3MgaXQgZnJvbSB0aGUgZmlsZXBhdGggb3IgZmlsZW5hbWVcbiAgaWYgKCFjb250ZW50VHlwZSAmJiAob3B0aW9ucy5maWxlcGF0aCB8fCBvcHRpb25zLmZpbGVuYW1lKSkge1xuICAgIGNvbnRlbnRUeXBlID0gbWltZS5sb29rdXAob3B0aW9ucy5maWxlcGF0aCB8fCBvcHRpb25zLmZpbGVuYW1lKTtcbiAgfVxuXG4gIC8vIGZhbGxiYWNrIHRvIHRoZSBkZWZhdWx0IGNvbnRlbnQgdHlwZSBpZiBgdmFsdWVgIGlzIG5vdCBzaW1wbGUgdmFsdWVcbiAgaWYgKCFjb250ZW50VHlwZSAmJiB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcpIHtcbiAgICBjb250ZW50VHlwZSA9IEZvcm1EYXRhLkRFRkFVTFRfQ09OVEVOVF9UWVBFO1xuICB9XG5cbiAgcmV0dXJuIGNvbnRlbnRUeXBlO1xufTtcblxuRm9ybURhdGEucHJvdG90eXBlLl9tdWx0aVBhcnRGb290ZXIgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG5leHQpIHtcbiAgICB2YXIgZm9vdGVyID0gRm9ybURhdGEuTElORV9CUkVBSztcblxuICAgIHZhciBsYXN0UGFydCA9ICh0aGlzLl9zdHJlYW1zLmxlbmd0aCA9PT0gMCk7XG4gICAgaWYgKGxhc3RQYXJ0KSB7XG4gICAgICBmb290ZXIgKz0gdGhpcy5fbGFzdEJvdW5kYXJ5KCk7XG4gICAgfVxuXG4gICAgbmV4dChmb290ZXIpO1xuICB9LmJpbmQodGhpcyk7XG59O1xuXG5Gb3JtRGF0YS5wcm90b3R5cGUuX2xhc3RCb3VuZGFyeSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gJy0tJyArIHRoaXMuZ2V0Qm91bmRhcnkoKSArICctLScgKyBGb3JtRGF0YS5MSU5FX0JSRUFLO1xufTtcblxuRm9ybURhdGEucHJvdG90eXBlLmdldEhlYWRlcnMgPSBmdW5jdGlvbih1c2VySGVhZGVycykge1xuICB2YXIgaGVhZGVyO1xuICB2YXIgZm9ybUhlYWRlcnMgPSB7XG4gICAgJ2NvbnRlbnQtdHlwZSc6ICdtdWx0aXBhcnQvZm9ybS1kYXRhOyBib3VuZGFyeT0nICsgdGhpcy5nZXRCb3VuZGFyeSgpXG4gIH07XG5cbiAgZm9yIChoZWFkZXIgaW4gdXNlckhlYWRlcnMpIHtcbiAgICBpZiAodXNlckhlYWRlcnMuaGFzT3duUHJvcGVydHkoaGVhZGVyKSkge1xuICAgICAgZm9ybUhlYWRlcnNbaGVhZGVyLnRvTG93ZXJDYXNlKCldID0gdXNlckhlYWRlcnNbaGVhZGVyXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZm9ybUhlYWRlcnM7XG59O1xuXG5Gb3JtRGF0YS5wcm90b3R5cGUuc2V0Qm91bmRhcnkgPSBmdW5jdGlvbihib3VuZGFyeSkge1xuICB0aGlzLl9ib3VuZGFyeSA9IGJvdW5kYXJ5O1xufTtcblxuRm9ybURhdGEucHJvdG90eXBlLmdldEJvdW5kYXJ5ID0gZnVuY3Rpb24oKSB7XG4gIGlmICghdGhpcy5fYm91bmRhcnkpIHtcbiAgICB0aGlzLl9nZW5lcmF0ZUJvdW5kYXJ5KCk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5fYm91bmRhcnk7XG59O1xuXG5Gb3JtRGF0YS5wcm90b3R5cGUuZ2V0QnVmZmVyID0gZnVuY3Rpb24oKSB7XG4gIHZhciBkYXRhQnVmZmVyID0gbmV3IEJ1ZmZlci5hbGxvYyggMCApO1xuICB2YXIgYm91bmRhcnkgPSB0aGlzLmdldEJvdW5kYXJ5KCk7XG5cbiAgLy8gQ3JlYXRlIHRoZSBmb3JtIGNvbnRlbnQuIEFkZCBMaW5lIGJyZWFrcyB0byB0aGUgZW5kIG9mIGRhdGEuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSB0aGlzLl9zdHJlYW1zLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLl9zdHJlYW1zW2ldICE9PSAnZnVuY3Rpb24nKSB7XG5cbiAgICAgIC8vIEFkZCBjb250ZW50IHRvIHRoZSBidWZmZXIuXG4gICAgICBpZihCdWZmZXIuaXNCdWZmZXIodGhpcy5fc3RyZWFtc1tpXSkpIHtcbiAgICAgICAgZGF0YUJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoIFtkYXRhQnVmZmVyLCB0aGlzLl9zdHJlYW1zW2ldXSk7XG4gICAgICB9ZWxzZSB7XG4gICAgICAgIGRhdGFCdWZmZXIgPSBCdWZmZXIuY29uY2F0KCBbZGF0YUJ1ZmZlciwgQnVmZmVyLmZyb20odGhpcy5fc3RyZWFtc1tpXSldKTtcbiAgICAgIH1cblxuICAgICAgLy8gQWRkIGJyZWFrIGFmdGVyIGNvbnRlbnQuXG4gICAgICBpZiAodHlwZW9mIHRoaXMuX3N0cmVhbXNbaV0gIT09ICdzdHJpbmcnIHx8IHRoaXMuX3N0cmVhbXNbaV0uc3Vic3RyaW5nKCAyLCBib3VuZGFyeS5sZW5ndGggKyAyICkgIT09IGJvdW5kYXJ5KSB7XG4gICAgICAgIGRhdGFCdWZmZXIgPSBCdWZmZXIuY29uY2F0KCBbZGF0YUJ1ZmZlciwgQnVmZmVyLmZyb20oRm9ybURhdGEuTElORV9CUkVBSyldICk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gQWRkIHRoZSBmb290ZXIgYW5kIHJldHVybiB0aGUgQnVmZmVyIG9iamVjdC5cbiAgcmV0dXJuIEJ1ZmZlci5jb25jYXQoIFtkYXRhQnVmZmVyLCBCdWZmZXIuZnJvbSh0aGlzLl9sYXN0Qm91bmRhcnkoKSldICk7XG59O1xuXG5Gb3JtRGF0YS5wcm90b3R5cGUuX2dlbmVyYXRlQm91bmRhcnkgPSBmdW5jdGlvbigpIHtcbiAgLy8gVGhpcyBnZW5lcmF0ZXMgYSA1MCBjaGFyYWN0ZXIgYm91bmRhcnkgc2ltaWxhciB0byB0aG9zZSB1c2VkIGJ5IEZpcmVmb3guXG4gIC8vIFRoZXkgYXJlIG9wdGltaXplZCBmb3IgYm95ZXItbW9vcmUgcGFyc2luZy5cbiAgdmFyIGJvdW5kYXJ5ID0gJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJztcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNDsgaSsrKSB7XG4gICAgYm91bmRhcnkgKz0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMTApLnRvU3RyaW5nKDE2KTtcbiAgfVxuXG4gIHRoaXMuX2JvdW5kYXJ5ID0gYm91bmRhcnk7XG59O1xuXG4vLyBOb3RlOiBnZXRMZW5ndGhTeW5jIERPRVNOJ1QgY2FsY3VsYXRlIHN0cmVhbXMgbGVuZ3RoXG4vLyBBcyB3b3JrYXJvdW5kIG9uZSBjYW4gY2FsY3VsYXRlIGZpbGUgc2l6ZSBtYW51YWxseVxuLy8gYW5kIGFkZCBpdCBhcyBrbm93bkxlbmd0aCBvcHRpb25cbkZvcm1EYXRhLnByb3RvdHlwZS5nZXRMZW5ndGhTeW5jID0gZnVuY3Rpb24oKSB7XG4gIHZhciBrbm93bkxlbmd0aCA9IHRoaXMuX292ZXJoZWFkTGVuZ3RoICsgdGhpcy5fdmFsdWVMZW5ndGg7XG5cbiAgLy8gRG9uJ3QgZ2V0IGNvbmZ1c2VkLCB0aGVyZSBhcmUgMyBcImludGVybmFsXCIgc3RyZWFtcyBmb3IgZWFjaCBrZXl2YWwgcGFpclxuICAvLyBzbyBpdCBiYXNpY2FsbHkgY2hlY2tzIGlmIHRoZXJlIGlzIGFueSB2YWx1ZSBhZGRlZCB0byB0aGUgZm9ybVxuICBpZiAodGhpcy5fc3RyZWFtcy5sZW5ndGgpIHtcbiAgICBrbm93bkxlbmd0aCArPSB0aGlzLl9sYXN0Qm91bmRhcnkoKS5sZW5ndGg7XG4gIH1cblxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vZm9ybS1kYXRhL2Zvcm0tZGF0YS9pc3N1ZXMvNDBcbiAgaWYgKCF0aGlzLmhhc0tub3duTGVuZ3RoKCkpIHtcbiAgICAvLyBTb21lIGFzeW5jIGxlbmd0aCByZXRyaWV2ZXJzIGFyZSBwcmVzZW50XG4gICAgLy8gdGhlcmVmb3JlIHN5bmNocm9ub3VzIGxlbmd0aCBjYWxjdWxhdGlvbiBpcyBmYWxzZS5cbiAgICAvLyBQbGVhc2UgdXNlIGdldExlbmd0aChjYWxsYmFjaykgdG8gZ2V0IHByb3BlciBsZW5ndGhcbiAgICB0aGlzLl9lcnJvcihuZXcgRXJyb3IoJ0Nhbm5vdCBjYWxjdWxhdGUgcHJvcGVyIGxlbmd0aCBpbiBzeW5jaHJvbm91cyB3YXkuJykpO1xuICB9XG5cbiAgcmV0dXJuIGtub3duTGVuZ3RoO1xufTtcblxuLy8gUHVibGljIEFQSSB0byBjaGVjayBpZiBsZW5ndGggb2YgYWRkZWQgdmFsdWVzIGlzIGtub3duXG4vLyBodHRwczovL2dpdGh1Yi5jb20vZm9ybS1kYXRhL2Zvcm0tZGF0YS9pc3N1ZXMvMTk2XG4vLyBodHRwczovL2dpdGh1Yi5jb20vZm9ybS1kYXRhL2Zvcm0tZGF0YS9pc3N1ZXMvMjYyXG5Gb3JtRGF0YS5wcm90b3R5cGUuaGFzS25vd25MZW5ndGggPSBmdW5jdGlvbigpIHtcbiAgdmFyIGhhc0tub3duTGVuZ3RoID0gdHJ1ZTtcblxuICBpZiAodGhpcy5fdmFsdWVzVG9NZWFzdXJlLmxlbmd0aCkge1xuICAgIGhhc0tub3duTGVuZ3RoID0gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gaGFzS25vd25MZW5ndGg7XG59O1xuXG5Gb3JtRGF0YS5wcm90b3R5cGUuZ2V0TGVuZ3RoID0gZnVuY3Rpb24oY2IpIHtcbiAgdmFyIGtub3duTGVuZ3RoID0gdGhpcy5fb3ZlcmhlYWRMZW5ndGggKyB0aGlzLl92YWx1ZUxlbmd0aDtcblxuICBpZiAodGhpcy5fc3RyZWFtcy5sZW5ndGgpIHtcbiAgICBrbm93bkxlbmd0aCArPSB0aGlzLl9sYXN0Qm91bmRhcnkoKS5sZW5ndGg7XG4gIH1cblxuICBpZiAoIXRoaXMuX3ZhbHVlc1RvTWVhc3VyZS5sZW5ndGgpIHtcbiAgICBwcm9jZXNzLm5leHRUaWNrKGNiLmJpbmQodGhpcywgbnVsbCwga25vd25MZW5ndGgpKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBhc3luY2tpdC5wYXJhbGxlbCh0aGlzLl92YWx1ZXNUb01lYXN1cmUsIHRoaXMuX2xlbmd0aFJldHJpZXZlciwgZnVuY3Rpb24oZXJyLCB2YWx1ZXMpIHtcbiAgICBpZiAoZXJyKSB7XG4gICAgICBjYihlcnIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhbHVlcy5mb3JFYWNoKGZ1bmN0aW9uKGxlbmd0aCkge1xuICAgICAga25vd25MZW5ndGggKz0gbGVuZ3RoO1xuICAgIH0pO1xuXG4gICAgY2IobnVsbCwga25vd25MZW5ndGgpO1xuICB9KTtcbn07XG5cbkZvcm1EYXRhLnByb3RvdHlwZS5zdWJtaXQgPSBmdW5jdGlvbihwYXJhbXMsIGNiKSB7XG4gIHZhciByZXF1ZXN0XG4gICAgLCBvcHRpb25zXG4gICAgLCBkZWZhdWx0cyA9IHttZXRob2Q6ICdwb3N0J31cbiAgICA7XG5cbiAgLy8gcGFyc2UgcHJvdmlkZWQgdXJsIGlmIGl0J3Mgc3RyaW5nXG4gIC8vIG9yIHRyZWF0IGl0IGFzIG9wdGlvbnMgb2JqZWN0XG4gIGlmICh0eXBlb2YgcGFyYW1zID09ICdzdHJpbmcnKSB7XG5cbiAgICBwYXJhbXMgPSBwYXJzZVVybChwYXJhbXMpO1xuICAgIG9wdGlvbnMgPSBwb3B1bGF0ZSh7XG4gICAgICBwb3J0OiBwYXJhbXMucG9ydCxcbiAgICAgIHBhdGg6IHBhcmFtcy5wYXRobmFtZSxcbiAgICAgIGhvc3Q6IHBhcmFtcy5ob3N0bmFtZSxcbiAgICAgIHByb3RvY29sOiBwYXJhbXMucHJvdG9jb2xcbiAgICB9LCBkZWZhdWx0cyk7XG5cbiAgLy8gdXNlIGN1c3RvbSBwYXJhbXNcbiAgfSBlbHNlIHtcblxuICAgIG9wdGlvbnMgPSBwb3B1bGF0ZShwYXJhbXMsIGRlZmF1bHRzKTtcbiAgICAvLyBpZiBubyBwb3J0IHByb3ZpZGVkIHVzZSBkZWZhdWx0IG9uZVxuICAgIGlmICghb3B0aW9ucy5wb3J0KSB7XG4gICAgICBvcHRpb25zLnBvcnQgPSBvcHRpb25zLnByb3RvY29sID09ICdodHRwczonID8gNDQzIDogODA7XG4gICAgfVxuICB9XG5cbiAgLy8gcHV0IHRoYXQgZ29vZCBjb2RlIGluIGdldEhlYWRlcnMgdG8gc29tZSB1c2VcbiAgb3B0aW9ucy5oZWFkZXJzID0gdGhpcy5nZXRIZWFkZXJzKHBhcmFtcy5oZWFkZXJzKTtcblxuICAvLyBodHRwcyBpZiBzcGVjaWZpZWQsIGZhbGxiYWNrIHRvIGh0dHAgaW4gYW55IG90aGVyIGNhc2VcbiAgaWYgKG9wdGlvbnMucHJvdG9jb2wgPT0gJ2h0dHBzOicpIHtcbiAgICByZXF1ZXN0ID0gaHR0cHMucmVxdWVzdChvcHRpb25zKTtcbiAgfSBlbHNlIHtcbiAgICByZXF1ZXN0ID0gaHR0cC5yZXF1ZXN0KG9wdGlvbnMpO1xuICB9XG5cbiAgLy8gZ2V0IGNvbnRlbnQgbGVuZ3RoIGFuZCBmaXJlIGF3YXlcbiAgdGhpcy5nZXRMZW5ndGgoZnVuY3Rpb24oZXJyLCBsZW5ndGgpIHtcbiAgICBpZiAoZXJyICYmIGVyciAhPT0gJ1Vua25vd24gc3RyZWFtJykge1xuICAgICAgdGhpcy5fZXJyb3IoZXJyKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBhZGQgY29udGVudCBsZW5ndGhcbiAgICBpZiAobGVuZ3RoKSB7XG4gICAgICByZXF1ZXN0LnNldEhlYWRlcignQ29udGVudC1MZW5ndGgnLCBsZW5ndGgpO1xuICAgIH1cblxuICAgIHRoaXMucGlwZShyZXF1ZXN0KTtcbiAgICBpZiAoY2IpIHtcbiAgICAgIHZhciBvblJlc3BvbnNlO1xuXG4gICAgICB2YXIgY2FsbGJhY2sgPSBmdW5jdGlvbiAoZXJyb3IsIHJlc3BvbmNlKSB7XG4gICAgICAgIHJlcXVlc3QucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgY2FsbGJhY2spO1xuICAgICAgICByZXF1ZXN0LnJlbW92ZUxpc3RlbmVyKCdyZXNwb25zZScsIG9uUmVzcG9uc2UpO1xuXG4gICAgICAgIHJldHVybiBjYi5jYWxsKHRoaXMsIGVycm9yLCByZXNwb25jZSk7XG4gICAgICB9O1xuXG4gICAgICBvblJlc3BvbnNlID0gY2FsbGJhY2suYmluZCh0aGlzLCBudWxsKTtcblxuICAgICAgcmVxdWVzdC5vbignZXJyb3InLCBjYWxsYmFjayk7XG4gICAgICByZXF1ZXN0Lm9uKCdyZXNwb25zZScsIG9uUmVzcG9uc2UpO1xuICAgIH1cbiAgfS5iaW5kKHRoaXMpKTtcblxuICByZXR1cm4gcmVxdWVzdDtcbn07XG5cbkZvcm1EYXRhLnByb3RvdHlwZS5fZXJyb3IgPSBmdW5jdGlvbihlcnIpIHtcbiAgaWYgKCF0aGlzLmVycm9yKSB7XG4gICAgdGhpcy5lcnJvciA9IGVycjtcbiAgICB0aGlzLnBhdXNlKCk7XG4gICAgdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gIH1cbn07XG5cbkZvcm1EYXRhLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuICdbb2JqZWN0IEZvcm1EYXRhXSc7XG59O1xuIiwiLy8gcG9wdWxhdGVzIG1pc3NpbmcgdmFsdWVzXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGRzdCwgc3JjKSB7XG5cbiAgT2JqZWN0LmtleXMoc3JjKS5mb3JFYWNoKGZ1bmN0aW9uKHByb3ApXG4gIHtcbiAgICBkc3RbcHJvcF0gPSBkc3RbcHJvcF0gfHwgc3JjW3Byb3BdO1xuICB9KTtcblxuICByZXR1cm4gZHN0O1xufTtcbiIsImltcG9ydCB7XG4gIEROU1JlY29yZCxcbiAgRG9tYWluRGF0YSxcbiAgRG9tYWluU2hvcnREYXRhLFxuICBURG9tYWluXG59IGZyb20gJy4uLy4uL1R5cGVzL0RvbWFpbnMnO1xuXG4vKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERvbWFpbiBpbXBsZW1lbnRzIFREb21haW4ge1xuICBuYW1lOiBzdHJpbmc7XG4gIHJlcXVpcmVfdGxzOiBib29sZWFuO1xuICBza2lwX3ZlcmlmaWNhdGlvbjogYm9vbGVhbjtcbiAgc3RhdGU6IHN0cmluZztcbiAgd2lsZGNhcmQ6IGJvb2xlYW47XG4gIHNwYW1fYWN0aW9uOiBzdHJpbmc7XG4gIGNyZWF0ZWRfYXQ6IHN0cmluZztcbiAgc210cF9wYXNzd29yZDogc3RyaW5nO1xuICBzbXRwX2xvZ2luOiBzdHJpbmc7XG4gIHR5cGU6IHN0cmluZztcbiAgcmVjZWl2aW5nX2Ruc19yZWNvcmRzOiBETlNSZWNvcmRbXSB8IG51bGw7XG4gIHNlbmRpbmdfZG5zX3JlY29yZHM6IEROU1JlY29yZFtdIHwgbnVsbDtcbiAgaWQ/OiBzdHJpbmc7XG4gIGlzX2Rpc2FibGVkPzogYm9vbGVhbjtcbiAgd2ViX3ByZWZpeD86IHN0cmluZztcbiAgd2ViX3NjaGVtZT86IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBkYXRhOiBEb21haW5TaG9ydERhdGEgfCBEb21haW5EYXRhLFxuICAgIHJlY2VpdmluZz86IEROU1JlY29yZFtdIHwgbnVsbCxcbiAgICBzZW5kaW5nPzogRE5TUmVjb3JkW10gfCBudWxsXG4gICkge1xuICAgIHRoaXMubmFtZSA9IGRhdGEubmFtZTtcbiAgICB0aGlzLnJlcXVpcmVfdGxzID0gZGF0YS5yZXF1aXJlX3RscztcbiAgICB0aGlzLnNraXBfdmVyaWZpY2F0aW9uID0gZGF0YS5za2lwX3ZlcmlmaWNhdGlvbjtcbiAgICB0aGlzLnN0YXRlID0gZGF0YS5zdGF0ZTtcbiAgICB0aGlzLndpbGRjYXJkID0gZGF0YS53aWxkY2FyZDtcbiAgICB0aGlzLnNwYW1fYWN0aW9uID0gZGF0YS5zcGFtX2FjdGlvbjtcbiAgICB0aGlzLmNyZWF0ZWRfYXQgPSBkYXRhLmNyZWF0ZWRfYXQ7XG4gICAgdGhpcy5zbXRwX3Bhc3N3b3JkID0gZGF0YS5zbXRwX3Bhc3N3b3JkO1xuICAgIHRoaXMuc210cF9sb2dpbiA9IGRhdGEuc210cF9sb2dpbjtcbiAgICB0aGlzLnR5cGUgPSBkYXRhLnR5cGU7XG4gICAgdGhpcy5yZWNlaXZpbmdfZG5zX3JlY29yZHMgPSByZWNlaXZpbmcgfHwgbnVsbDtcbiAgICB0aGlzLnNlbmRpbmdfZG5zX3JlY29yZHMgPSBzZW5kaW5nIHx8IG51bGw7XG4gICAgLypcbiAgICAgIGRvbWFpbiBsaXN0IGhhcyBzaG9ydGVyIHJlc3BvbnNlIHRoZW4gZ2V0LCBjcmVhdGUsIGFuZCB1cGRhdGUgbWV0aG9kcy5cbiAgICAqL1xuXG4gICAgY29uc3QgZHluYW1pY0tleXM6IChrZXlvZiBEb21haW5EYXRhKVtdID0gWydpZCcsICdpc19kaXNhYmxlZCcsICd3ZWJfcHJlZml4JywgJ3dlYl9zY2hlbWUnXTtcblxuICAgIGNvbnN0IGR5bmFtaWNQcm9wZXJ0aWVzID0gZHluYW1pY0tleXMucmVkdWNlKChhY2MsIHByb3BlcnR5TmFtZSkgPT4ge1xuICAgICAgaWYgKHByb3BlcnR5TmFtZSBpbiBkYXRhKSB7XG4gICAgICAgIGNvbnN0IHByb3AgPSBwcm9wZXJ0eU5hbWUgYXMga2V5b2YgRG9tYWluO1xuICAgICAgICBhY2NbcHJvcF0gPSAoZGF0YSBhcyBEb21haW5EYXRhKVtwcm9wZXJ0eU5hbWVdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSBhcyBSZWNvcmQ8a2V5b2YgRG9tYWluLCBzdHJpbmcgfCBib29sZWFuPik7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLCBkeW5hbWljUHJvcGVydGllcyk7XG4gIH1cbn1cbiIsImltcG9ydCB1cmxqb2luIGZyb20gJ3VybC1qb2luJztcbmltcG9ydCB7XG4gIElEb21haW5UZW1wbGF0ZXNDbGllbnQsXG4gIElEb21haW5UYWdzQ2xpZW50LFxuICBJRG9tYWluQ3JlZGVudGlhbHMsXG4gIElEb21haW5zQ2xpZW50XG59IGZyb20gJy4uLy4uL0ludGVyZmFjZXMvRG9tYWlucyc7XG5cbmltcG9ydCB7IEFQSVJlc3BvbnNlIH0gZnJvbSAnLi4vLi4vVHlwZXMvQ29tbW9uL0FwaVJlc3BvbnNlJztcbmltcG9ydCBBUElFcnJvciBmcm9tICcuLi9jb21tb24vRXJyb3InO1xuaW1wb3J0IHsgQVBJRXJyb3JPcHRpb25zIH0gZnJvbSAnLi4vLi4vVHlwZXMvQ29tbW9uJztcblxuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi4vY29tbW9uL1JlcXVlc3QnO1xuXG5pbXBvcnQgRG9tYWluQ3JlZGVudGlhbHNDbGllbnQgZnJvbSAnLi9kb21haW5zQ3JlZGVudGlhbHMnO1xuaW1wb3J0IERvbWFpblRlbXBsYXRlc0NsaWVudCBmcm9tICcuL2RvbWFpbnNUZW1wbGF0ZXMnO1xuaW1wb3J0IERvbWFpblRhZ3NDbGllbnQgZnJvbSAnLi9kb21haW5zVGFncyc7XG5pbXBvcnQge1xuICBEZXN0cm95ZWREb21haW5SZXNwb25zZSxcbiAgTWVzc2FnZVJlc3BvbnNlLFxuICBEb21haW5MaXN0UmVzcG9uc2VEYXRhLFxuICBEb21haW5SZXNwb25zZURhdGEsXG4gIERvbWFpblRyYWNraW5nUmVzcG9uc2UsXG4gIERvbWFpblRyYWNraW5nRGF0YSxcbiAgVXBkYXRlRG9tYWluVHJhY2tpbmdSZXNwb25zZSxcbiAgVXBkYXRlZE9wZW5UcmFja2luZyxcbiAgRG9tYWluc1F1ZXJ5LFxuICBEb21haW5JbmZvLFxuICBDb25uZWN0aW9uU2V0dGluZ3MsXG4gIENvbm5lY3Rpb25TZXR0aW5nc1Jlc3BvbnNlLFxuICBVcGRhdGVkQ29ubmVjdGlvblNldHRpbmdzLFxuICBVcGRhdGVkQ29ubmVjdGlvblNldHRpbmdzUmVzLFxuICBPcGVuVHJhY2tpbmdJbmZvLFxuICBDbGlja1RyYWNraW5nSW5mbyxcbiAgVW5zdWJzY3JpYmVUcmFja2luZ0luZm8sXG4gIFJlcGxhY2VtZW50Rm9yUG9vbCxcbiAgREtJTUF1dGhvcml0eUluZm8sXG4gIFVwZGF0ZWRES0lNQXV0aG9yaXR5LFxuICBVcGRhdGVkREtJTUF1dGhvcml0eVJlc3BvbnNlLFxuICBES0lNU2VsZWN0b3JJbmZvLFxuICBVcGRhdGVkREtJTVNlbGVjdG9yUmVzcG9uc2UsXG4gIFdlYlByZWZpeEluZm8sXG4gIFVwZGF0ZWRXZWJQcmVmaXhSZXNwb25zZSxcbiAgVERvbWFpbixcbiAgRG9tYWluVXBkYXRlSW5mbyxcbiAgRG9tYWluVXBkYXRlSW5mb1JlcSxcbiAgRG9tYWluSW5mb1JlcSxcbiAgQm9vbFRvU3RyaW5nLFxufSBmcm9tICcuLi8uLi9UeXBlcy9Eb21haW5zJztcbmltcG9ydCBEb21haW4gZnJvbSAnLi9kb21haW4nO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEb21haW5zQ2xpZW50IGltcGxlbWVudHMgSURvbWFpbnNDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuICBwdWJsaWMgZG9tYWluQ3JlZGVudGlhbHM6IElEb21haW5DcmVkZW50aWFscztcbiAgcHVibGljIGRvbWFpblRlbXBsYXRlczogSURvbWFpblRlbXBsYXRlc0NsaWVudDtcbiAgcHVibGljIGRvbWFpblRhZ3M6IElEb21haW5UYWdzQ2xpZW50O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHJlcXVlc3Q6IFJlcXVlc3QsXG4gICAgZG9tYWluQ3JlZGVudGlhbHNDbGllbnQ6IERvbWFpbkNyZWRlbnRpYWxzQ2xpZW50LFxuICAgIGRvbWFpblRlbXBsYXRlc0NsaWVudDogRG9tYWluVGVtcGxhdGVzQ2xpZW50LFxuICAgIGRvbWFpblRhZ3NDbGllbnQ6IERvbWFpblRhZ3NDbGllbnRcbiAgKSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgICB0aGlzLmRvbWFpbkNyZWRlbnRpYWxzID0gZG9tYWluQ3JlZGVudGlhbHNDbGllbnQ7XG4gICAgdGhpcy5kb21haW5UZW1wbGF0ZXMgPSBkb21haW5UZW1wbGF0ZXNDbGllbnQ7XG4gICAgdGhpcy5kb21haW5UYWdzID0gZG9tYWluVGFnc0NsaWVudDtcbiAgfVxuXG4gIHByaXZhdGUgX2hhbmRsZUJvb2xWYWx1ZXMoXG4gICAgZGF0YTogRG9tYWluSW5mbyB8IERvbWFpblVwZGF0ZUluZm9cbiAgKTogRG9tYWluSW5mb1JlcSB8IERvbWFpblVwZGF0ZUluZm9SZXEge1xuICAgIGNvbnN0IHByb3BzRm9yUmVwbGFjZW1lbnQgPSBkYXRhIGFzIEJvb2xUb1N0cmluZztcbiAgICBjb25zdCByZXBsYWNlZFByb3BzID0gT2JqZWN0LmtleXMocHJvcHNGb3JSZXBsYWNlbWVudCkucmVkdWNlKChhY2MsIGtleSkgPT4ge1xuICAgICAgY29uc3QgcHJvcCA9IGtleSBhcyBrZXlvZiBCb29sVG9TdHJpbmc7XG4gICAgICBpZiAodHlwZW9mIHByb3BzRm9yUmVwbGFjZW1lbnRbcHJvcF0gPT09ICdib29sZWFuJykge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHByb3BzRm9yUmVwbGFjZW1lbnRbcHJvcF0gYXMgYm9vbGVhbjtcbiAgICAgICAgYWNjW3Byb3BdID0gKHZhbHVlLnRvU3RyaW5nKCkgPT09ICd0cnVlJykgPyAndHJ1ZScgOiAnZmFsc2UnO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSBhcyBSZWNvcmQ8a2V5b2YgQm9vbFRvU3RyaW5nLCAndHJ1ZSd8ICdmYWxzZSc+KTtcbiAgICByZXR1cm4geyAuLi5kYXRhLCAuLi5yZXBsYWNlZFByb3BzIH0gYXMgRG9tYWluVXBkYXRlSW5mb1JlcSB8IERvbWFpbkluZm9SZXE7XG4gIH1cblxuICBwcml2YXRlIF9wYXJzZU1lc3NhZ2UocmVzcG9uc2U6IERlc3Ryb3llZERvbWFpblJlc3BvbnNlKSA6IE1lc3NhZ2VSZXNwb25zZSB7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmJvZHk7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlRG9tYWluTGlzdChyZXNwb25zZTogRG9tYWluTGlzdFJlc3BvbnNlRGF0YSk6IFREb21haW5bXSB7XG4gICAgaWYgKHJlc3BvbnNlLmJvZHkgJiYgcmVzcG9uc2UuYm9keS5pdGVtcykge1xuICAgICAgcmV0dXJuIHJlc3BvbnNlLmJvZHkuaXRlbXMubWFwKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgIHJldHVybiBuZXcgRG9tYWluKGl0ZW0pO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHByaXZhdGUgX3BhcnNlRG9tYWluKHJlc3BvbnNlOiBEb21haW5SZXNwb25zZURhdGEpOiBURG9tYWluIHtcbiAgICByZXR1cm4gbmV3IERvbWFpbihcbiAgICAgIHJlc3BvbnNlLmJvZHkuZG9tYWluLFxuICAgICAgcmVzcG9uc2UuYm9keS5yZWNlaXZpbmdfZG5zX3JlY29yZHMsXG4gICAgICByZXNwb25zZS5ib2R5LnNlbmRpbmdfZG5zX3JlY29yZHNcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBfcGFyc2VUcmFja2luZ1NldHRpbmdzKHJlc3BvbnNlOiBEb21haW5UcmFja2luZ1Jlc3BvbnNlKSA6IERvbWFpblRyYWNraW5nRGF0YSB7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmJvZHkudHJhY2tpbmc7XG4gIH1cblxuICBwcml2YXRlIF9wYXJzZVRyYWNraW5nVXBkYXRlKHJlc3BvbnNlOiBVcGRhdGVEb21haW5UcmFja2luZ1Jlc3BvbnNlKSA6VXBkYXRlZE9wZW5UcmFja2luZyB7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmJvZHk7XG4gIH1cblxuICBsaXN0KHF1ZXJ5PzogRG9tYWluc1F1ZXJ5KTogUHJvbWlzZTxURG9tYWluW10+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCgnL3YzL2RvbWFpbnMnLCBxdWVyeSlcbiAgICAgIC50aGVuKChyZXMgOiBBUElSZXNwb25zZSkgPT4gdGhpcy5wYXJzZURvbWFpbkxpc3QocmVzIGFzIERvbWFpbkxpc3RSZXNwb25zZURhdGEpKTtcbiAgfVxuXG4gIGdldChkb21haW46IHN0cmluZykgOiBQcm9taXNlPFREb21haW4+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldChgL3YzL2RvbWFpbnMvJHtkb21haW59YClcbiAgICAgIC50aGVuKChyZXMgOiBBUElSZXNwb25zZSkgPT4gdGhpcy5fcGFyc2VEb21haW4ocmVzIGFzIERvbWFpblJlc3BvbnNlRGF0YSkpO1xuICB9XG5cbiAgY3JlYXRlKGRhdGE6IERvbWFpbkluZm8pIDogUHJvbWlzZTxURG9tYWluPiB7XG4gICAgY29uc3QgcG9zdE9iaiA9IHRoaXMuX2hhbmRsZUJvb2xWYWx1ZXMoZGF0YSk7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wb3N0V2l0aEZEKCcvdjMvZG9tYWlucycsIHBvc3RPYmopXG4gICAgICAudGhlbigocmVzIDogQVBJUmVzcG9uc2UpID0+IHRoaXMuX3BhcnNlRG9tYWluKHJlcyBhcyBEb21haW5SZXNwb25zZURhdGEpKTtcbiAgfVxuXG4gIHVwZGF0ZShkb21haW46IHN0cmluZywgZGF0YTogRG9tYWluVXBkYXRlSW5mbykgOiBQcm9taXNlPFREb21haW4+IHtcbiAgICBjb25zdCBwdXREYXRhID0gdGhpcy5faGFuZGxlQm9vbFZhbHVlcyhkYXRhKTtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnB1dFdpdGhGRChgL3YzL2RvbWFpbnMvJHtkb21haW59YCwgcHV0RGF0YSlcbiAgICAgIC50aGVuKChyZXMgOiBBUElSZXNwb25zZSkgPT4gdGhpcy5fcGFyc2VEb21haW4ocmVzIGFzIERvbWFpblJlc3BvbnNlRGF0YSkpO1xuICB9XG5cbiAgdmVyaWZ5KGRvbWFpbjogc3RyaW5nKTogUHJvbWlzZTxURG9tYWluPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXQoYC92My9kb21haW5zLyR7ZG9tYWlufS92ZXJpZnlgKVxuICAgICAgLnRoZW4oKHJlcyA6IEFQSVJlc3BvbnNlKSA9PiB0aGlzLl9wYXJzZURvbWFpbihyZXMgYXMgRG9tYWluUmVzcG9uc2VEYXRhKSk7XG4gIH1cblxuICBkZXN0cm95KGRvbWFpbjogc3RyaW5nKTogUHJvbWlzZTxNZXNzYWdlUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZShgL3YzL2RvbWFpbnMvJHtkb21haW59YClcbiAgICAgIC50aGVuKChyZXMgOiBBUElSZXNwb25zZSkgPT4gdGhpcy5fcGFyc2VNZXNzYWdlKHJlcyBhcyBEZXN0cm95ZWREb21haW5SZXNwb25zZSkpO1xuICB9XG5cbiAgZ2V0Q29ubmVjdGlvbihkb21haW46IHN0cmluZyk6IFByb21pc2U8Q29ubmVjdGlvblNldHRpbmdzPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoYC92My9kb21haW5zLyR7ZG9tYWlufS9jb25uZWN0aW9uYClcbiAgICAgIC50aGVuKChyZXMgOiBBUElSZXNwb25zZSkgPT4gcmVzIGFzIENvbm5lY3Rpb25TZXR0aW5nc1Jlc3BvbnNlKVxuICAgICAgLnRoZW4oKHJlczpDb25uZWN0aW9uU2V0dGluZ3NSZXNwb25zZSkgPT4gcmVzLmJvZHkuY29ubmVjdGlvbiBhcyBDb25uZWN0aW9uU2V0dGluZ3MpO1xuICB9XG5cbiAgdXBkYXRlQ29ubmVjdGlvbihkb21haW46IHN0cmluZywgZGF0YTogQ29ubmVjdGlvblNldHRpbmdzKTogUHJvbWlzZTxVcGRhdGVkQ29ubmVjdGlvblNldHRpbmdzPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXQoYC92My9kb21haW5zLyR7ZG9tYWlufS9jb25uZWN0aW9uYCwgZGF0YSlcbiAgICAgIC50aGVuKChyZXMgOiBBUElSZXNwb25zZSkgPT4gcmVzIGFzIFVwZGF0ZWRDb25uZWN0aW9uU2V0dGluZ3NSZXMpXG4gICAgICAudGhlbigocmVzOlVwZGF0ZWRDb25uZWN0aW9uU2V0dGluZ3NSZXMpID0+IHJlcy5ib2R5IGFzIFVwZGF0ZWRDb25uZWN0aW9uU2V0dGluZ3MpO1xuICB9XG5cbiAgLy8gVHJhY2tpbmdcblxuICBnZXRUcmFja2luZyhkb21haW46IHN0cmluZykgOiBQcm9taXNlPERvbWFpblRyYWNraW5nRGF0YT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybGpvaW4oJy92My9kb21haW5zJywgZG9tYWluLCAndHJhY2tpbmcnKSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlVHJhY2tpbmdTZXR0aW5ncyk7XG4gIH1cblxuICB1cGRhdGVUcmFja2luZyhcbiAgICBkb21haW46IHN0cmluZyxcbiAgICB0eXBlOiBzdHJpbmcsXG4gICAgZGF0YTogT3BlblRyYWNraW5nSW5mbyB8IENsaWNrVHJhY2tpbmdJbmZvIHwgVW5zdWJzY3JpYmVUcmFja2luZ0luZm9cbiAgKTogUHJvbWlzZTxVcGRhdGVkT3BlblRyYWNraW5nPiB7XG4gICAgaWYgKHR5cGVvZiBkYXRhPy5hY3RpdmUgPT09ICdib29sZWFuJykge1xuICAgICAgdGhyb3cgbmV3IEFQSUVycm9yKHsgc3RhdHVzOiA0MDAsIHN0YXR1c1RleHQ6ICdSZWNlaXZlZCBib29sZWFuIHZhbHVlIGZvciBhY3RpdmUgcHJvcGVydHknLCBib2R5OiB7IG1lc3NhZ2U6ICdQcm9wZXJ0eSBcImFjdGl2ZVwiIG11c3QgY29udGFpbiBzdHJpbmcgdmFsdWUuJyB9IH0gYXMgQVBJRXJyb3JPcHRpb25zKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXRXaXRoRkQodXJsam9pbignL3YzL2RvbWFpbnMnLCBkb21haW4sICd0cmFja2luZycsIHR5cGUpLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlcyA6IEFQSVJlc3BvbnNlKSA9PiB0aGlzLl9wYXJzZVRyYWNraW5nVXBkYXRlKHJlcyBhcyBVcGRhdGVEb21haW5UcmFja2luZ1Jlc3BvbnNlKSk7XG4gIH1cblxuICAvLyBJUHNcblxuICBnZXRJcHMoZG9tYWluOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQodXJsam9pbignL3YzL2RvbWFpbnMnLCBkb21haW4sICdpcHMnKSlcbiAgICAgIC50aGVuKChyZXNwb25zZTogQVBJUmVzcG9uc2UpID0+IHJlc3BvbnNlPy5ib2R5Py5pdGVtcyk7XG4gIH1cblxuICBhc3NpZ25JcChkb21haW46IHN0cmluZywgaXA6IHN0cmluZyk6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQodXJsam9pbignL3YzL2RvbWFpbnMnLCBkb21haW4sICdpcHMnKSwgeyBpcCB9KTtcbiAgfVxuXG4gIGRlbGV0ZUlwKGRvbWFpbjogc3RyaW5nLCBpcDogc3RyaW5nKTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZGVsZXRlKHVybGpvaW4oJy92My9kb21haW5zJywgZG9tYWluLCAnaXBzJywgaXApKTtcbiAgfVxuXG4gIGxpbmtJcFBvb2woZG9tYWluOiBzdHJpbmcsIHBvb2xJZDogc3RyaW5nKTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRCh1cmxqb2luKCcvdjMvZG9tYWlucycsIGRvbWFpbiwgJ2lwcycpLCB7IHBvb2xfaWQ6IHBvb2xJZCB9KTtcbiAgfVxuXG4gIHVubGlua0lwUG9sbChkb21haW46IHN0cmluZywgcmVwbGFjZW1lbnQ6IFJlcGxhY2VtZW50Rm9yUG9vbCk6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICBsZXQgc2VhcmNoUGFyYW1zID0gJyc7XG4gICAgaWYgKHJlcGxhY2VtZW50LnBvb2xfaWQgJiYgcmVwbGFjZW1lbnQuaXApIHtcbiAgICAgIHRocm93IG5ldyBBUElFcnJvcihcbiAgICAgICAge1xuICAgICAgICAgIHN0YXR1czogNDAwLFxuICAgICAgICAgIHN0YXR1c1RleHQ6ICdUb28gbXVjaCBkYXRhIGZvciByZXBsYWNlbWVudCcsXG4gICAgICAgICAgYm9keTogeyBtZXNzYWdlOiAnUGxlYXNlIHNwZWNpZnkgZWl0aGVyIHBvb2xfaWQgb3IgaXAgKG5vdCBib3RoKScgfVxuICAgICAgICB9IGFzIEFQSUVycm9yT3B0aW9uc1xuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKHJlcGxhY2VtZW50LnBvb2xfaWQpIHtcbiAgICAgIHNlYXJjaFBhcmFtcyA9IGA/cG9vbF9pZD0ke3JlcGxhY2VtZW50LnBvb2xfaWR9YDtcbiAgICB9IGVsc2UgaWYgKHJlcGxhY2VtZW50LmlwKSB7XG4gICAgICBzZWFyY2hQYXJhbXMgPSBgP2lwPSR7cmVwbGFjZW1lbnQuaXB9YDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUodXJsam9pbignL3YzL2RvbWFpbnMnLCBkb21haW4sICdpcHMnLCAnaXBfcG9vbCcsIHNlYXJjaFBhcmFtcykpO1xuICB9XG5cbiAgdXBkYXRlREtJTUF1dGhvcml0eShkb21haW46IHN0cmluZywgZGF0YTogREtJTUF1dGhvcml0eUluZm8pOiBQcm9taXNlPFVwZGF0ZWRES0lNQXV0aG9yaXR5PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXQoYC92My9kb21haW5zLyR7ZG9tYWlufS9ka2ltX2F1dGhvcml0eWAsIHt9LCB7IHF1ZXJ5OiBgc2VsZj0ke2RhdGEuc2VsZn1gIH0pXG4gICAgICAudGhlbigocmVzIDogQVBJUmVzcG9uc2UpID0+IHJlcyBhcyBVcGRhdGVkREtJTUF1dGhvcml0eVJlc3BvbnNlKVxuICAgICAgLnRoZW4oKHJlcyA6IFVwZGF0ZWRES0lNQXV0aG9yaXR5UmVzcG9uc2UpID0+IHJlcy5ib2R5IGFzIFVwZGF0ZWRES0lNQXV0aG9yaXR5KTtcbiAgfVxuXG4gIHVwZGF0ZURLSU1TZWxlY3Rvcihkb21haW46IHN0cmluZywgZGF0YTogREtJTVNlbGVjdG9ySW5mbyk6IFByb21pc2U8VXBkYXRlZERLSU1TZWxlY3RvclJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXQoYC92My9kb21haW5zLyR7ZG9tYWlufS9ka2ltX3NlbGVjdG9yYCwge30sIHsgcXVlcnk6IGBka2ltX3NlbGVjdG9yPSR7ZGF0YS5ka2ltU2VsZWN0b3J9YCB9KVxuICAgICAgLnRoZW4oKHJlcyA6IEFQSVJlc3BvbnNlKSA9PiByZXMgYXMgVXBkYXRlZERLSU1TZWxlY3RvclJlc3BvbnNlKTtcbiAgfVxuXG4gIHVwZGF0ZVdlYlByZWZpeChkb21haW46IHN0cmluZywgZGF0YTogV2ViUHJlZml4SW5mbyk6IFByb21pc2U8VXBkYXRlZFdlYlByZWZpeFJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXQoYC92My9kb21haW5zLyR7ZG9tYWlufS93ZWJfcHJlZml4YCwge30sIHsgcXVlcnk6IGB3ZWJfcHJlZml4PSR7ZGF0YS53ZWJQcmVmaXh9YCB9KVxuICAgICAgLnRoZW4oKHJlcyA6IEFQSVJlc3BvbnNlKSA9PiByZXMgYXMgVXBkYXRlZFdlYlByZWZpeFJlc3BvbnNlKTtcbiAgfVxufVxuIiwiaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuaW1wb3J0IHsgQVBJUmVzcG9uc2UgfSBmcm9tICcuLi8uLi9UeXBlcy9Db21tb24vQXBpUmVzcG9uc2UnO1xuaW1wb3J0IHsgSURvbWFpbkNyZWRlbnRpYWxzIH0gZnJvbSAnLi4vLi4vSW50ZXJmYWNlcy9Eb21haW5zJztcbmltcG9ydCB7XG4gIERvbWFpbkNyZWRlbnRpYWxzUmVzcG9uc2VEYXRhLFxuICBEb21haW5DcmVkZW50aWFsc0xpc3QsXG4gIENyZWF0ZWRVcGRhdGVkRG9tYWluQ3JlZGVudGlhbHNSZXNwb25zZSxcbiAgRG9tYWluQ3JlZGVudGlhbHNSZXN1bHQsXG4gIERlbGV0ZWREb21haW5DcmVkZW50aWFsc1Jlc3BvbnNlLFxuICBEb21haW5DcmVkZW50aWFsc1F1ZXJ5LFxuICBEb21haW5DcmVkZW50aWFscyxcbiAgVXBkYXRlRG9tYWluQ3JlZGVudGlhbHNEYXRhXG59IGZyb20gJy4uLy4uL1R5cGVzL0RvbWFpbnMnO1xuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi4vY29tbW9uL1JlcXVlc3QnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEb21haW5DcmVkZW50aWFsc0NsaWVudCBpbXBsZW1lbnRzIElEb21haW5DcmVkZW50aWFscyB7XG4gIGJhc2VSb3V0ZTogc3RyaW5nO1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICAgIHRoaXMuYmFzZVJvdXRlID0gJy92My9kb21haW5zLyc7XG4gIH1cblxuICBwcml2YXRlIF9wYXJzZURvbWFpbkNyZWRlbnRpYWxzTGlzdChcbiAgICByZXNwb25zZTogRG9tYWluQ3JlZGVudGlhbHNSZXNwb25zZURhdGFcbiAgKTogRG9tYWluQ3JlZGVudGlhbHNMaXN0IHtcbiAgICByZXR1cm4ge1xuICAgICAgaXRlbXM6IHJlc3BvbnNlLmJvZHkuaXRlbXMsXG4gICAgICB0b3RhbENvdW50OiByZXNwb25zZS5ib2R5LnRvdGFsX2NvdW50XG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgX3BhcnNlTWVzc2FnZVJlc3BvbnNlKFxuICAgIHJlc3BvbnNlOiBDcmVhdGVkVXBkYXRlZERvbWFpbkNyZWRlbnRpYWxzUmVzcG9uc2VcbiAgKTogRG9tYWluQ3JlZGVudGlhbHNSZXN1bHQge1xuICAgIGNvbnN0IHJlc3VsdCA9IHtcbiAgICAgIHN0YXR1czogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgbWVzc2FnZTogcmVzcG9uc2UuYm9keS5tZXNzYWdlXG4gICAgfSBhcyBEb21haW5DcmVkZW50aWFsc1Jlc3VsdDtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBfcGFyc2VEZWxldGVkUmVzcG9uc2UoXG4gICAgcmVzcG9uc2U6RGVsZXRlZERvbWFpbkNyZWRlbnRpYWxzUmVzcG9uc2VcbiAgKTogRG9tYWluQ3JlZGVudGlhbHNSZXN1bHQge1xuICAgIGNvbnN0IHJlc3VsdCA9IHtcbiAgICAgIHN0YXR1czogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgbWVzc2FnZTogcmVzcG9uc2UuYm9keS5tZXNzYWdlLFxuICAgICAgc3BlYzogcmVzcG9uc2UuYm9keS5zcGVjXG4gICAgfSBhcyBEb21haW5DcmVkZW50aWFsc1Jlc3VsdDtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBsaXN0KGRvbWFpbjogc3RyaW5nLCBxdWVyeT86IERvbWFpbkNyZWRlbnRpYWxzUXVlcnkpOiBQcm9taXNlPERvbWFpbkNyZWRlbnRpYWxzTGlzdD4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybGpvaW4odGhpcy5iYXNlUm91dGUsIGRvbWFpbiwgJy9jcmVkZW50aWFscycpLCBxdWVyeSlcbiAgICAgIC50aGVuKFxuICAgICAgICAocmVzOiBBUElSZXNwb25zZSkgPT4gdGhpcy5fcGFyc2VEb21haW5DcmVkZW50aWFsc0xpc3QocmVzIGFzIERvbWFpbkNyZWRlbnRpYWxzUmVzcG9uc2VEYXRhKVxuICAgICAgKTtcbiAgfVxuXG4gIGNyZWF0ZShcbiAgICBkb21haW46IHN0cmluZyxcbiAgICBkYXRhOiBEb21haW5DcmVkZW50aWFsc1xuICApOiBQcm9taXNlPERvbWFpbkNyZWRlbnRpYWxzUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wb3N0V2l0aEZEKGAke3RoaXMuYmFzZVJvdXRlfSR7ZG9tYWlufS9jcmVkZW50aWFsc2AsIGRhdGEpXG4gICAgICAudGhlbigocmVzOiBBUElSZXNwb25zZSkgPT4gdGhpcy5fcGFyc2VNZXNzYWdlUmVzcG9uc2UocmVzKSk7XG4gIH1cblxuICB1cGRhdGUoXG4gICAgZG9tYWluOiBzdHJpbmcsXG4gICAgY3JlZGVudGlhbHNMb2dpbjogc3RyaW5nLFxuICAgIGRhdGE6IFVwZGF0ZURvbWFpbkNyZWRlbnRpYWxzRGF0YVxuICApOiBQcm9taXNlPERvbWFpbkNyZWRlbnRpYWxzUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXRXaXRoRkQoYCR7dGhpcy5iYXNlUm91dGV9JHtkb21haW59L2NyZWRlbnRpYWxzLyR7Y3JlZGVudGlhbHNMb2dpbn1gLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlczogQVBJUmVzcG9uc2UpID0+IHRoaXMuX3BhcnNlTWVzc2FnZVJlc3BvbnNlKHJlcykpO1xuICB9XG5cbiAgZGVzdHJveShcbiAgICBkb21haW46IHN0cmluZyxcbiAgICBjcmVkZW50aWFsc0xvZ2luOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxEb21haW5DcmVkZW50aWFsc1Jlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZGVsZXRlKGAke3RoaXMuYmFzZVJvdXRlfSR7ZG9tYWlufS9jcmVkZW50aWFscy8ke2NyZWRlbnRpYWxzTG9naW59YClcbiAgICAgIC50aGVuKChyZXM6IEFQSVJlc3BvbnNlKSA9PiB0aGlzLl9wYXJzZURlbGV0ZWRSZXNwb25zZShyZXMpKTtcbiAgfVxufVxuIiwiaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuaW1wb3J0IHsgQVBJUmVzcG9uc2UgfSBmcm9tICcuLi8uLi9UeXBlcy9Db21tb24vQXBpUmVzcG9uc2UnO1xuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi4vY29tbW9uL1JlcXVlc3QnO1xuXG5pbXBvcnQge1xuICBJRG9tYWluVGFnU3RhdGlzdGljUmVzdWx0LFxuICBJRG9tYWluVGFnc0NsaWVudFxufSBmcm9tICcuLi8uLi9JbnRlcmZhY2VzL0RvbWFpbnMnO1xuaW1wb3J0IE5hdmlnYXRpb25UaHJ1UGFnZXMgZnJvbSAnLi4vY29tbW9uL05hdmlnYXRpb25UaHJ1UGFnZXMnO1xuaW1wb3J0IHsgUmVzb2x1dGlvbiB9IGZyb20gJy4uLy4uL0VudW1zJztcbmltcG9ydCB7XG4gIERvbWFpblRhZ3NJdGVtLFxuICBEb21haW5UYWdzSXRlbUluZm8sXG4gIERvbWFpblRhZ1N0YXRpc3RpY0l0ZW0sXG4gIERvbWFpblRhZ1N0YXRBUElSZXNwb25zZSxcbiAgRG9tYWluVGFnQVBJUmVzcG9uc2VTdGF0c0l0ZW0sXG4gIERvbWFpblRhZ3NMaXN0LFxuICBEb21haW5UYWdzUmVzcG9uc2VEYXRhLFxuICBEb21haW5UYWdzUXVlcnksXG4gIERvbWFpblRhZ3NNZXNzYWdlUmVzLFxuICBEb21haW5UYWdzU3RhdGlzdGljUXVlcnksXG4gIERvbWFpblRhZ0NvdW50cmllc0FnZ3JlZ2F0aW9uLFxuICBEb21haW5UYWdDb3VudHJpZXNBUElSZXNwb25zZSxcbiAgRG9tYWluVGFnUHJvdmlkZXJzQWdncmVnYXRpb24sXG4gIERvbWFpblRhZ1Byb3ZpZGVyc0FQSVJlc3BvbnNlLFxuICBEb21haW5UYWdEZXZpY2VzQWdncmVnYXRpb24sXG4gIERvbWFpblRhZ0RldmljZXNBUElSZXNwb25zZVxufSBmcm9tICcuLi8uLi9UeXBlcy9Eb21haW5zJztcblxuZXhwb3J0IGNsYXNzIERvbWFpblRhZyBpbXBsZW1lbnRzIERvbWFpblRhZ3NJdGVtIHtcbiAgdGFnOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gICdmaXJzdC1zZWVuJzogRGF0ZTtcbiAgJ2xhc3Qtc2Vlbic6IERhdGU7XG5cbiAgY29uc3RydWN0b3IodGFnSW5mbzogRG9tYWluVGFnc0l0ZW1JbmZvKSB7XG4gICAgdGhpcy50YWcgPSB0YWdJbmZvLnRhZztcbiAgICB0aGlzLmRlc2NyaXB0aW9uID0gdGFnSW5mby5kZXNjcmlwdGlvbjtcbiAgICB0aGlzWydmaXJzdC1zZWVuJ10gPSBuZXcgRGF0ZSh0YWdJbmZvWydmaXJzdC1zZWVuJ10pO1xuICAgIHRoaXNbJ2xhc3Qtc2VlbiddID0gbmV3IERhdGUodGFnSW5mb1snbGFzdC1zZWVuJ10pO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBEb21haW5UYWdTdGF0aXN0aWMgaW1wbGVtZW50cyBJRG9tYWluVGFnU3RhdGlzdGljUmVzdWx0IHtcbiAgdGFnOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIHN0YXJ0OiBEYXRlO1xuICBlbmQ6IERhdGU7XG4gIHJlc29sdXRpb246IFJlc29sdXRpb247XG4gIHN0YXRzOiBEb21haW5UYWdTdGF0aXN0aWNJdGVtW107XG5cbiAgY29uc3RydWN0b3IodGFnU3RhdGlzdGljSW5mbzogRG9tYWluVGFnU3RhdEFQSVJlc3BvbnNlKSB7XG4gICAgdGhpcy50YWcgPSB0YWdTdGF0aXN0aWNJbmZvLmJvZHkudGFnO1xuICAgIHRoaXMuZGVzY3JpcHRpb24gPSB0YWdTdGF0aXN0aWNJbmZvLmJvZHkuZGVzY3JpcHRpb247XG4gICAgdGhpcy5zdGFydCA9IG5ldyBEYXRlKHRhZ1N0YXRpc3RpY0luZm8uYm9keS5zdGFydCk7XG4gICAgdGhpcy5lbmQgPSBuZXcgRGF0ZSh0YWdTdGF0aXN0aWNJbmZvLmJvZHkuZW5kKTtcbiAgICB0aGlzLnJlc29sdXRpb24gPSB0YWdTdGF0aXN0aWNJbmZvLmJvZHkucmVzb2x1dGlvbjtcbiAgICB0aGlzLnN0YXRzID0gdGFnU3RhdGlzdGljSW5mby5ib2R5LnN0YXRzLm1hcChmdW5jdGlvbiAoc3RhdDogRG9tYWluVGFnQVBJUmVzcG9uc2VTdGF0c0l0ZW0pIHtcbiAgICAgIGNvbnN0IHJlcyA9IHsgLi4uc3RhdCwgdGltZTogbmV3IERhdGUoc3RhdC50aW1lKSB9O1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEb21haW5UYWdzQ2xpZW50XG4gIGV4dGVuZHMgTmF2aWdhdGlvblRocnVQYWdlczxEb21haW5UYWdzTGlzdD5cbiAgaW1wbGVtZW50cyBJRG9tYWluVGFnc0NsaWVudCB7XG4gIGJhc2VSb3V0ZTogc3RyaW5nO1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICBzdXBlcihyZXF1ZXN0KTtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICAgIHRoaXMuYmFzZVJvdXRlID0gJy92My8nO1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlTGlzdChcbiAgICByZXNwb25zZTogRG9tYWluVGFnc1Jlc3BvbnNlRGF0YSxcbiAgKTogRG9tYWluVGFnc0xpc3Qge1xuICAgIGNvbnN0IGRhdGEgPSB7fSBhcyBEb21haW5UYWdzTGlzdDtcbiAgICBkYXRhLml0ZW1zID0gcmVzcG9uc2UuYm9keS5pdGVtcy5tYXAoKHRhZ0luZm86IERvbWFpblRhZ3NJdGVtSW5mbykgPT4gbmV3IERvbWFpblRhZyh0YWdJbmZvKSk7XG5cbiAgICBkYXRhLnBhZ2VzID0gdGhpcy5wYXJzZVBhZ2VMaW5rcyhyZXNwb25zZSwgJz8nLCAndGFnJyk7XG4gICAgZGF0YS5zdGF0dXMgPSByZXNwb25zZS5zdGF0dXM7XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBwcml2YXRlIF9wYXJzZVRhZ1N0YXRpc3RpYyhcbiAgICByZXNwb25zZTogRG9tYWluVGFnU3RhdEFQSVJlc3BvbnNlXG4gICk6IElEb21haW5UYWdTdGF0aXN0aWNSZXN1bHQge1xuICAgIHJldHVybiBuZXcgRG9tYWluVGFnU3RhdGlzdGljKHJlc3BvbnNlKTtcbiAgfVxuXG4gIGFzeW5jIGxpc3QoZG9tYWluOiBzdHJpbmcsIHF1ZXJ5PzogRG9tYWluVGFnc1F1ZXJ5KTogUHJvbWlzZTxEb21haW5UYWdzTGlzdD4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3RMaXN0V2l0aFBhZ2VzKHVybGpvaW4odGhpcy5iYXNlUm91dGUsIGRvbWFpbiwgJy90YWdzJyksIHF1ZXJ5KTtcbiAgfVxuXG4gIGdldChkb21haW46IHN0cmluZywgdGFnOiBzdHJpbmcpOiBQcm9taXNlPERvbWFpblRhZ3NJdGVtPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQodXJsam9pbih0aGlzLmJhc2VSb3V0ZSwgZG9tYWluLCAnL3RhZ3MnLCB0YWcpKVxuICAgICAgLnRoZW4oXG4gICAgICAgIChyZXM6IEFQSVJlc3BvbnNlKSA9PiBuZXcgRG9tYWluVGFnKHJlcy5ib2R5KVxuICAgICAgKTtcbiAgfVxuXG4gIHVwZGF0ZShkb21haW46IHN0cmluZywgdGFnOiBzdHJpbmcsIGRlc2NyaXB0aW9uOiBzdHJpbmcpOiBQcm9taXNlPERvbWFpblRhZ3NNZXNzYWdlUmVzPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXQodXJsam9pbih0aGlzLmJhc2VSb3V0ZSwgZG9tYWluLCAnL3RhZ3MnLCB0YWcpLCBkZXNjcmlwdGlvbilcbiAgICAgIC50aGVuKFxuICAgICAgICAocmVzOiBBUElSZXNwb25zZSkgPT4gcmVzLmJvZHkgYXMgRG9tYWluVGFnc01lc3NhZ2VSZXNcbiAgICAgICk7XG4gIH1cblxuICBkZXN0cm95KFxuICAgIGRvbWFpbjogc3RyaW5nLFxuICAgIHRhZzogc3RyaW5nXG4gICk6IFByb21pc2U8RG9tYWluVGFnc01lc3NhZ2VSZXM+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZShgJHt0aGlzLmJhc2VSb3V0ZX0ke2RvbWFpbn0vdGFncy8ke3RhZ31gKVxuICAgICAgLnRoZW4oKHJlczogQVBJUmVzcG9uc2UpID0+IChcbiAgICAgICAge1xuICAgICAgICAgIG1lc3NhZ2U6IHJlcy5ib2R5Lm1lc3NhZ2UsXG4gICAgICAgICAgc3RhdHVzOiByZXMuc3RhdHVzXG4gICAgICAgIH0gYXMgRG9tYWluVGFnc01lc3NhZ2VSZXMpKTtcbiAgfVxuXG4gIHN0YXRpc3RpYyhkb21haW46IHN0cmluZywgdGFnOiBzdHJpbmcsIHF1ZXJ5OiBEb21haW5UYWdzU3RhdGlzdGljUXVlcnkpXG4gICAgOiBQcm9taXNlPERvbWFpblRhZ1N0YXRpc3RpYz4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybGpvaW4odGhpcy5iYXNlUm91dGUsIGRvbWFpbiwgJy90YWdzJywgdGFnLCAnc3RhdHMnKSwgcXVlcnkpXG4gICAgICAudGhlbihcbiAgICAgICAgKHJlczogQVBJUmVzcG9uc2UpID0+IHRoaXMuX3BhcnNlVGFnU3RhdGlzdGljKHJlcylcbiAgICAgICk7XG4gIH1cblxuICBjb3VudHJpZXMoZG9tYWluOiBzdHJpbmcsIHRhZzogc3RyaW5nKTogUHJvbWlzZTxEb21haW5UYWdDb3VudHJpZXNBZ2dyZWdhdGlvbj4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybGpvaW4odGhpcy5iYXNlUm91dGUsIGRvbWFpbiwgJy90YWdzJywgdGFnLCAnc3RhdHMvYWdncmVnYXRlcy9jb3VudHJpZXMnKSlcbiAgICAgIC50aGVuKFxuICAgICAgICAocmVzOiBEb21haW5UYWdDb3VudHJpZXNBUElSZXNwb25zZSkgPT4gcmVzLmJvZHkgYXMgRG9tYWluVGFnQ291bnRyaWVzQWdncmVnYXRpb25cbiAgICAgICk7XG4gIH1cblxuICBwcm92aWRlcnMoZG9tYWluOiBzdHJpbmcsIHRhZzogc3RyaW5nKTogUHJvbWlzZTxEb21haW5UYWdQcm92aWRlcnNBZ2dyZWdhdGlvbj4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybGpvaW4odGhpcy5iYXNlUm91dGUsIGRvbWFpbiwgJy90YWdzJywgdGFnLCAnc3RhdHMvYWdncmVnYXRlcy9wcm92aWRlcnMnKSlcbiAgICAgIC50aGVuKFxuICAgICAgICAocmVzOiBEb21haW5UYWdQcm92aWRlcnNBUElSZXNwb25zZSkgPT4gcmVzLmJvZHkgYXMgRG9tYWluVGFnUHJvdmlkZXJzQWdncmVnYXRpb25cbiAgICAgICk7XG4gIH1cblxuICBkZXZpY2VzKGRvbWFpbjogc3RyaW5nLCB0YWc6IHN0cmluZyk6IFByb21pc2U8RG9tYWluVGFnRGV2aWNlc0FnZ3JlZ2F0aW9uPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQodXJsam9pbih0aGlzLmJhc2VSb3V0ZSwgZG9tYWluLCAnL3RhZ3MnLCB0YWcsICdzdGF0cy9hZ2dyZWdhdGVzL2RldmljZXMnKSlcbiAgICAgIC50aGVuKFxuICAgICAgICAocmVzOiBEb21haW5UYWdEZXZpY2VzQVBJUmVzcG9uc2UpID0+IHJlcy5ib2R5IGFzIERvbWFpblRhZ0RldmljZXNBZ2dyZWdhdGlvblxuICAgICAgKTtcbiAgfVxufVxuIiwiaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi4vY29tbW9uL1JlcXVlc3QnO1xuXG5pbXBvcnQge1xuICBDcmVhdGVEb21haW5UZW1wbGF0ZUFQSVJlc3BvbnNlLFxuICBDcmVhdGVEb21haW5UZW1wbGF0ZVZlcnNpb25BUElSZXNwb25zZSxcbiAgQ3JlYXRlRG9tYWluVGVtcGxhdGVWZXJzaW9uUmVzdWx0LFxuICBEb21haW5UZW1wbGF0ZURhdGEsXG4gIERvbWFpblRlbXBsYXRlc1F1ZXJ5LFxuICBEb21haW5UZW1wbGF0ZVVwZGF0ZURhdGEsXG4gIERvbWFpblRlbXBsYXRlVXBkYXRlVmVyc2lvbkRhdGEsXG4gIERvbWFpblRlbXBsYXRlVmVyc2lvbkRhdGEsXG4gIEdldERvbWFpblRlbXBsYXRlQVBJUmVzcG9uc2UsXG4gIExpc3REb21haW5UZW1wbGF0ZXNBUElSZXNwb25zZSxcbiAgTGlzdERvbWFpblRlbXBsYXRlc1Jlc3VsdCxcbiAgTGlzdERvbWFpblRlbXBsYXRlVmVyc2lvbnNBUElSZXNwb25zZSxcbiAgTGlzdERvbWFpblRlbXBsYXRlVmVyc2lvbnNSZXN1bHQsXG4gIE11dGF0ZURvbWFpblRlbXBsYXRlVmVyc2lvbkFQSVJlc3BvbnNlLFxuICBNdXRhdGVEb21haW5UZW1wbGF0ZVZlcnNpb25SZXN1bHQsXG4gIE5vdGlmaWNhdGlvbkFQSVJlc3BvbnNlLFxuICBOb3RpZmljYXRpb25SZXN1bHQsXG4gIFNob3J0VGVtcGxhdGVWZXJzaW9uLFxuICBUZW1wbGF0ZVF1ZXJ5LFxuICBUZW1wbGF0ZVZlcnNpb24sXG4gIFVwZGF0ZU9yRGVsZXRlRG9tYWluVGVtcGxhdGVBUElSZXNwb25zZSxcbiAgVXBkYXRlT3JEZWxldGVEb21haW5UZW1wbGF0ZVJlc3VsdFxufSBmcm9tICcuLi8uLi9UeXBlcy9Eb21haW5zJztcbmltcG9ydCBOYXZpZ2F0aW9uVGhydVBhZ2VzIGZyb20gJy4uL2NvbW1vbi9OYXZpZ2F0aW9uVGhydVBhZ2VzJztcbmltcG9ydCB7IElEb21haW5UZW1wbGF0ZSwgSURvbWFpblRlbXBsYXRlc0NsaWVudCB9IGZyb20gJy4uLy4uL0ludGVyZmFjZXMvRG9tYWlucyc7XG5cbmV4cG9ydCBjbGFzcyBEb21haW5UZW1wbGF0ZUl0ZW0gaW1wbGVtZW50cyBJRG9tYWluVGVtcGxhdGUge1xuICBuYW1lIDogc3RyaW5nO1xuICBkZXNjcmlwdGlvbiA6IHN0cmluZztcbiAgY3JlYXRlZEF0IDogRGF0ZSB8ICcnO1xuICBjcmVhdGVkQnkgOiBzdHJpbmc7XG4gIGlkIDogc3RyaW5nO1xuICB2ZXJzaW9uPzogVGVtcGxhdGVWZXJzaW9uO1xuICB2ZXJzaW9ucz86IFNob3J0VGVtcGxhdGVWZXJzaW9uW107XG5cbiAgY29uc3RydWN0b3IoZG9tYWluVGVtcGxhdGVGcm9tQVBJOiBJRG9tYWluVGVtcGxhdGUpIHtcbiAgICB0aGlzLm5hbWUgPSBkb21haW5UZW1wbGF0ZUZyb21BUEkubmFtZTtcbiAgICB0aGlzLmRlc2NyaXB0aW9uID0gZG9tYWluVGVtcGxhdGVGcm9tQVBJLmRlc2NyaXB0aW9uO1xuICAgIHRoaXMuY3JlYXRlZEF0ID0gZG9tYWluVGVtcGxhdGVGcm9tQVBJLmNyZWF0ZWRBdCA/IG5ldyBEYXRlKGRvbWFpblRlbXBsYXRlRnJvbUFQSS5jcmVhdGVkQXQpIDogJyc7XG4gICAgdGhpcy5jcmVhdGVkQnkgPSBkb21haW5UZW1wbGF0ZUZyb21BUEkuY3JlYXRlZEJ5O1xuICAgIHRoaXMuaWQgPSBkb21haW5UZW1wbGF0ZUZyb21BUEkuaWQ7XG5cbiAgICBpZiAoZG9tYWluVGVtcGxhdGVGcm9tQVBJLnZlcnNpb24pIHtcbiAgICAgIHRoaXMudmVyc2lvbiA9IGRvbWFpblRlbXBsYXRlRnJvbUFQSS52ZXJzaW9uO1xuICAgICAgaWYgKGRvbWFpblRlbXBsYXRlRnJvbUFQSS52ZXJzaW9uLmNyZWF0ZWRBdCkge1xuICAgICAgICB0aGlzLnZlcnNpb24uY3JlYXRlZEF0ID0gbmV3IERhdGUoZG9tYWluVGVtcGxhdGVGcm9tQVBJLnZlcnNpb24uY3JlYXRlZEF0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZG9tYWluVGVtcGxhdGVGcm9tQVBJLnZlcnNpb25zICYmIGRvbWFpblRlbXBsYXRlRnJvbUFQSS52ZXJzaW9ucy5sZW5ndGgpIHtcbiAgICAgIHRoaXMudmVyc2lvbnMgPSBkb21haW5UZW1wbGF0ZUZyb21BUEkudmVyc2lvbnMubWFwKCh2ZXJzaW9uKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHsgLi4udmVyc2lvbiB9O1xuICAgICAgICByZXN1bHQuY3JlYXRlZEF0ID0gbmV3IERhdGUodmVyc2lvbi5jcmVhdGVkQXQpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERvbWFpblRlbXBsYXRlc0NsaWVudFxuICBleHRlbmRzIE5hdmlnYXRpb25UaHJ1UGFnZXM8TGlzdERvbWFpblRlbXBsYXRlc1Jlc3VsdD5cbiAgaW1wbGVtZW50cyBJRG9tYWluVGVtcGxhdGVzQ2xpZW50IHtcbiAgYmFzZVJvdXRlOiBzdHJpbmc7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHN1cGVyKHJlcXVlc3QpO1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gICAgdGhpcy5iYXNlUm91dGUgPSAnL3YzLyc7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlQ3JlYXRpb25SZXNwb25zZShkYXRhOiBDcmVhdGVEb21haW5UZW1wbGF0ZUFQSVJlc3BvbnNlKTogSURvbWFpblRlbXBsYXRlIHtcbiAgICByZXR1cm4gbmV3IERvbWFpblRlbXBsYXRlSXRlbShkYXRhLmJvZHkudGVtcGxhdGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUNyZWF0aW9uVmVyc2lvblJlc3BvbnNlKFxuICAgIGRhdGE6IENyZWF0ZURvbWFpblRlbXBsYXRlVmVyc2lvbkFQSVJlc3BvbnNlXG4gICk6IENyZWF0ZURvbWFpblRlbXBsYXRlVmVyc2lvblJlc3VsdCB7XG4gICAgY29uc3QgcmVzdWx0OiBDcmVhdGVEb21haW5UZW1wbGF0ZVZlcnNpb25SZXN1bHQgPSB7fSBhcyBDcmVhdGVEb21haW5UZW1wbGF0ZVZlcnNpb25SZXN1bHQ7XG4gICAgcmVzdWx0LnN0YXR1cyA9IGRhdGEuc3RhdHVzO1xuICAgIHJlc3VsdC5tZXNzYWdlID0gZGF0YS5ib2R5Lm1lc3NhZ2U7XG4gICAgaWYgKGRhdGEuYm9keSAmJiBkYXRhLmJvZHkudGVtcGxhdGUpIHtcbiAgICAgIHJlc3VsdC50ZW1wbGF0ZSA9IG5ldyBEb21haW5UZW1wbGF0ZUl0ZW0oZGF0YS5ib2R5LnRlbXBsYXRlKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VNdXRhdGlvblJlc3BvbnNlKFxuICAgIGRhdGE6IFVwZGF0ZU9yRGVsZXRlRG9tYWluVGVtcGxhdGVBUElSZXNwb25zZVxuICApOiBVcGRhdGVPckRlbGV0ZURvbWFpblRlbXBsYXRlUmVzdWx0IHtcbiAgICBjb25zdCByZXN1bHQ6IFVwZGF0ZU9yRGVsZXRlRG9tYWluVGVtcGxhdGVSZXN1bHQgPSB7fSBhcyBVcGRhdGVPckRlbGV0ZURvbWFpblRlbXBsYXRlUmVzdWx0O1xuICAgIHJlc3VsdC5zdGF0dXMgPSBkYXRhLnN0YXR1cztcbiAgICByZXN1bHQubWVzc2FnZSA9IGRhdGEuYm9keS5tZXNzYWdlO1xuICAgIGlmIChkYXRhLmJvZHkgJiYgZGF0YS5ib2R5LnRlbXBsYXRlKSB7XG4gICAgICByZXN1bHQudGVtcGxhdGVOYW1lID0gZGF0YS5ib2R5LnRlbXBsYXRlLm5hbWU7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlTm90aWZpY2F0aW9uUmVzcG9uc2UoZGF0YTogTm90aWZpY2F0aW9uQVBJUmVzcG9uc2UpOiBOb3RpZmljYXRpb25SZXN1bHQge1xuICAgIGNvbnN0IHJlc3VsdDogTm90aWZpY2F0aW9uUmVzdWx0ID0ge30gYXMgTm90aWZpY2F0aW9uUmVzdWx0O1xuICAgIHJlc3VsdC5zdGF0dXMgPSBkYXRhLnN0YXR1cztcbiAgICByZXN1bHQubWVzc2FnZSA9IGRhdGEuYm9keS5tZXNzYWdlO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlTXV0YXRlVGVtcGxhdGVWZXJzaW9uUmVzcG9uc2UoXG4gICAgZGF0YTogTXV0YXRlRG9tYWluVGVtcGxhdGVWZXJzaW9uQVBJUmVzcG9uc2VcbiAgKTogTXV0YXRlRG9tYWluVGVtcGxhdGVWZXJzaW9uUmVzdWx0IHtcbiAgICBjb25zdCByZXN1bHQ6IE11dGF0ZURvbWFpblRlbXBsYXRlVmVyc2lvblJlc3VsdCA9IHt9IGFzIE11dGF0ZURvbWFpblRlbXBsYXRlVmVyc2lvblJlc3VsdDtcbiAgICByZXN1bHQuc3RhdHVzID0gZGF0YS5zdGF0dXM7XG4gICAgcmVzdWx0Lm1lc3NhZ2UgPSBkYXRhLmJvZHkubWVzc2FnZTtcbiAgICBpZiAoZGF0YS5ib2R5LnRlbXBsYXRlKSB7XG4gICAgICByZXN1bHQudGVtcGxhdGVOYW1lID0gZGF0YS5ib2R5LnRlbXBsYXRlLm5hbWU7XG4gICAgICByZXN1bHQudGVtcGxhdGVWZXJzaW9uID0geyB0YWc6IGRhdGEuYm9keS50ZW1wbGF0ZS52ZXJzaW9uLnRhZyB9O1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlTGlzdChyZXNwb25zZTogTGlzdERvbWFpblRlbXBsYXRlc0FQSVJlc3BvbnNlKTogTGlzdERvbWFpblRlbXBsYXRlc1Jlc3VsdCB7XG4gICAgY29uc3QgZGF0YSA9IHt9IGFzIExpc3REb21haW5UZW1wbGF0ZXNSZXN1bHQ7XG5cbiAgICBkYXRhLml0ZW1zID0gcmVzcG9uc2UuYm9keS5pdGVtcy5tYXAoKGQ6IElEb21haW5UZW1wbGF0ZSkgPT4gbmV3IERvbWFpblRlbXBsYXRlSXRlbShkKSk7XG5cbiAgICBkYXRhLnBhZ2VzID0gdGhpcy5wYXJzZVBhZ2VMaW5rcyhyZXNwb25zZSwgJz8nLCAncCcpO1xuICAgIGRhdGEuc3RhdHVzID0gcmVzcG9uc2Uuc3RhdHVzO1xuXG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlTGlzdFRlbXBsYXRlVmVyc2lvbnMoXG4gICAgcmVzcG9uc2U6IExpc3REb21haW5UZW1wbGF0ZVZlcnNpb25zQVBJUmVzcG9uc2VcbiAgKTogTGlzdERvbWFpblRlbXBsYXRlVmVyc2lvbnNSZXN1bHQge1xuICAgIGNvbnN0IGRhdGEgPSB7fSBhcyBMaXN0RG9tYWluVGVtcGxhdGVWZXJzaW9uc1Jlc3VsdDtcblxuICAgIGRhdGEudGVtcGxhdGUgPSBuZXcgRG9tYWluVGVtcGxhdGVJdGVtKHJlc3BvbnNlLmJvZHkudGVtcGxhdGUpO1xuXG4gICAgZGF0YS5wYWdlcyA9IHRoaXMucGFyc2VQYWdlTGlua3MocmVzcG9uc2UsICc/JywgJ3AnKTtcblxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgYXN5bmMgbGlzdChkb21haW46IHN0cmluZywgcXVlcnk/OiBEb21haW5UZW1wbGF0ZXNRdWVyeSk6IFByb21pc2U8TGlzdERvbWFpblRlbXBsYXRlc1Jlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3RMaXN0V2l0aFBhZ2VzKHVybGpvaW4odGhpcy5iYXNlUm91dGUsIGRvbWFpbiwgJy90ZW1wbGF0ZXMnKSwgcXVlcnkpO1xuICB9XG5cbiAgZ2V0KGRvbWFpbjogc3RyaW5nLCB0ZW1wbGF0ZU5hbWU6IHN0cmluZywgcXVlcnk/OiBUZW1wbGF0ZVF1ZXJ5KTogUHJvbWlzZTxJRG9tYWluVGVtcGxhdGU+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCh1cmxqb2luKHRoaXMuYmFzZVJvdXRlLCBkb21haW4sICcvdGVtcGxhdGVzLycsIHRlbXBsYXRlTmFtZSksIHF1ZXJ5KVxuICAgICAgLnRoZW4oXG4gICAgICAgIChyZXM6IEdldERvbWFpblRlbXBsYXRlQVBJUmVzcG9uc2UpID0+IG5ldyBEb21haW5UZW1wbGF0ZUl0ZW0ocmVzLmJvZHkudGVtcGxhdGUpXG4gICAgICApO1xuICB9XG5cbiAgY3JlYXRlKFxuICAgIGRvbWFpbjogc3RyaW5nLFxuICAgIGRhdGE6IERvbWFpblRlbXBsYXRlRGF0YVxuICApOiBQcm9taXNlPElEb21haW5UZW1wbGF0ZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRCh1cmxqb2luKHRoaXMuYmFzZVJvdXRlLCBkb21haW4sICcvdGVtcGxhdGVzJyksIGRhdGEpXG4gICAgICAudGhlbigocmVzOiBDcmVhdGVEb21haW5UZW1wbGF0ZUFQSVJlc3BvbnNlKSA9PiB0aGlzLnBhcnNlQ3JlYXRpb25SZXNwb25zZShyZXMpKTtcbiAgfVxuXG4gIHVwZGF0ZShcbiAgICBkb21haW46IHN0cmluZyxcbiAgICB0ZW1wbGF0ZU5hbWU6IHN0cmluZyxcbiAgICBkYXRhOiBEb21haW5UZW1wbGF0ZVVwZGF0ZURhdGFcbiAgKTogUHJvbWlzZTxVcGRhdGVPckRlbGV0ZURvbWFpblRlbXBsYXRlUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXRXaXRoRkQodXJsam9pbih0aGlzLmJhc2VSb3V0ZSwgZG9tYWluLCAnL3RlbXBsYXRlcy8nLCB0ZW1wbGF0ZU5hbWUpLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlczogVXBkYXRlT3JEZWxldGVEb21haW5UZW1wbGF0ZUFQSVJlc3BvbnNlKSA9PiB0aGlzLnBhcnNlTXV0YXRpb25SZXNwb25zZShyZXMpKTtcbiAgfVxuXG4gIGRlc3Ryb3koZG9tYWluOiBzdHJpbmcsIHRlbXBsYXRlTmFtZTogc3RyaW5nKTogUHJvbWlzZTxVcGRhdGVPckRlbGV0ZURvbWFpblRlbXBsYXRlUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUodXJsam9pbih0aGlzLmJhc2VSb3V0ZSwgZG9tYWluLCAnL3RlbXBsYXRlcy8nLCB0ZW1wbGF0ZU5hbWUpKVxuICAgICAgLnRoZW4oKHJlczogVXBkYXRlT3JEZWxldGVEb21haW5UZW1wbGF0ZUFQSVJlc3BvbnNlKSA9PiB0aGlzLnBhcnNlTXV0YXRpb25SZXNwb25zZShyZXMpKTtcbiAgfVxuXG4gIGRlc3Ryb3lBbGwoZG9tYWluOiBzdHJpbmcpOiBQcm9taXNlPE5vdGlmaWNhdGlvblJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZGVsZXRlKHVybGpvaW4odGhpcy5iYXNlUm91dGUsIGRvbWFpbiwgJy90ZW1wbGF0ZXMnKSlcbiAgICAgIC50aGVuKChyZXM6IE5vdGlmaWNhdGlvbkFQSVJlc3BvbnNlKSA9PiB0aGlzLnBhcnNlTm90aWZpY2F0aW9uUmVzcG9uc2UocmVzKSk7XG4gIH1cblxuICBjcmVhdGVWZXJzaW9uKFxuICAgIGRvbWFpbjogc3RyaW5nLFxuICAgIHRlbXBsYXRlTmFtZTogc3RyaW5nLFxuICAgIGRhdGE6IERvbWFpblRlbXBsYXRlVmVyc2lvbkRhdGFcbiAgKTogUHJvbWlzZTxDcmVhdGVEb21haW5UZW1wbGF0ZVZlcnNpb25SZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQodXJsam9pbih0aGlzLmJhc2VSb3V0ZSwgZG9tYWluLCAnL3RlbXBsYXRlcy8nLCB0ZW1wbGF0ZU5hbWUsICcvdmVyc2lvbnMnKSwgZGF0YSlcbiAgICAgIC50aGVuKFxuICAgICAgICAocmVzOiBDcmVhdGVEb21haW5UZW1wbGF0ZVZlcnNpb25BUElSZXNwb25zZSkgPT4gdGhpcy5wYXJzZUNyZWF0aW9uVmVyc2lvblJlc3BvbnNlKHJlcylcbiAgICAgICk7XG4gIH1cblxuICBnZXRWZXJzaW9uKGRvbWFpbjogc3RyaW5nLCB0ZW1wbGF0ZU5hbWU6IHN0cmluZywgdGFnOiBzdHJpbmcpOiBQcm9taXNlPElEb21haW5UZW1wbGF0ZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybGpvaW4odGhpcy5iYXNlUm91dGUsIGRvbWFpbiwgJy90ZW1wbGF0ZXMvJywgdGVtcGxhdGVOYW1lLCAnL3ZlcnNpb25zLycsIHRhZykpXG4gICAgICAudGhlbihcbiAgICAgICAgKHJlczogR2V0RG9tYWluVGVtcGxhdGVBUElSZXNwb25zZSkgPT4gbmV3IERvbWFpblRlbXBsYXRlSXRlbShyZXMuYm9keS50ZW1wbGF0ZSlcbiAgICAgICk7XG4gIH1cblxuICB1cGRhdGVWZXJzaW9uKFxuICAgIGRvbWFpbjogc3RyaW5nLFxuICAgIHRlbXBsYXRlTmFtZTogc3RyaW5nLFxuICAgIHRhZzogc3RyaW5nLFxuICAgIGRhdGE6IERvbWFpblRlbXBsYXRlVXBkYXRlVmVyc2lvbkRhdGFcbiAgKTogUHJvbWlzZTxNdXRhdGVEb21haW5UZW1wbGF0ZVZlcnNpb25SZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnB1dFdpdGhGRCh1cmxqb2luKHRoaXMuYmFzZVJvdXRlLCBkb21haW4sICcvdGVtcGxhdGVzLycsIHRlbXBsYXRlTmFtZSwgJy92ZXJzaW9ucy8nLCB0YWcpLCBkYXRhKVxuICAgICAgLnRoZW4oXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgICAgIChyZXM6IE11dGF0ZURvbWFpblRlbXBsYXRlVmVyc2lvbkFQSVJlc3BvbnNlKSA9PiB0aGlzLnBhcnNlTXV0YXRlVGVtcGxhdGVWZXJzaW9uUmVzcG9uc2UocmVzKVxuICAgICAgKTtcbiAgfVxuXG4gIGRlc3Ryb3lWZXJzaW9uKFxuICAgIGRvbWFpbjogc3RyaW5nLFxuICAgIHRlbXBsYXRlTmFtZTogc3RyaW5nLFxuICAgIHRhZzogc3RyaW5nXG4gICk6IFByb21pc2U8TXV0YXRlRG9tYWluVGVtcGxhdGVWZXJzaW9uUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUodXJsam9pbih0aGlzLmJhc2VSb3V0ZSwgZG9tYWluLCAnL3RlbXBsYXRlcy8nLCB0ZW1wbGF0ZU5hbWUsICcvdmVyc2lvbnMvJywgdGFnKSlcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgICAudGhlbigocmVzOiBNdXRhdGVEb21haW5UZW1wbGF0ZVZlcnNpb25BUElSZXNwb25zZSkgPT4gdGhpcy5wYXJzZU11dGF0ZVRlbXBsYXRlVmVyc2lvblJlc3BvbnNlKHJlcykpO1xuICB9XG5cbiAgbGlzdFZlcnNpb25zKFxuICAgIGRvbWFpbjogc3RyaW5nLFxuICAgIHRlbXBsYXRlTmFtZTogc3RyaW5nLFxuICAgIHF1ZXJ5PzogRG9tYWluVGVtcGxhdGVzUXVlcnlcbiAgKTogUHJvbWlzZTxMaXN0RG9tYWluVGVtcGxhdGVWZXJzaW9uc1Jlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybGpvaW4odGhpcy5iYXNlUm91dGUsIGRvbWFpbiwgJy90ZW1wbGF0ZXMnLCB0ZW1wbGF0ZU5hbWUsICcvdmVyc2lvbnMnKSwgcXVlcnkpXG4gICAgICAudGhlbihcbiAgICAgICAgKHJlczogTGlzdERvbWFpblRlbXBsYXRlVmVyc2lvbnNBUElSZXNwb25zZSkgPT4gdGhpcy5wYXJzZUxpc3RUZW1wbGF0ZVZlcnNpb25zKHJlcylcbiAgICAgICk7XG4gIH1cbn1cbiIsImltcG9ydCB1cmxqb2luIGZyb20gJ3VybC1qb2luJztcbmltcG9ydCBOYXZpZ2F0aW9uVGhydVBhZ2VzIGZyb20gJy4vY29tbW9uL05hdmlnYXRpb25UaHJ1UGFnZXMnO1xuaW1wb3J0IHtcbiAgRXZlbnRzTGlzdCxcbiAgRXZlbnRzUXVlcnksXG4gIEV2ZW50c1Jlc3BvbnNlLFxufSBmcm9tICcuLi9UeXBlcy9FdmVudHMnO1xuXG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL2NvbW1vbi9SZXF1ZXN0JztcbmltcG9ydCB7IElFdmVudENsaWVudCB9IGZyb20gJy4uL0ludGVyZmFjZXMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBFdmVudENsaWVudFxuICBleHRlbmRzIE5hdmlnYXRpb25UaHJ1UGFnZXM8RXZlbnRzTGlzdD5cbiAgaW1wbGVtZW50cyBJRXZlbnRDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICBzdXBlcihyZXF1ZXN0KTtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlTGlzdChcbiAgICByZXNwb25zZTogRXZlbnRzUmVzcG9uc2UsXG4gICk6IEV2ZW50c0xpc3Qge1xuICAgIGNvbnN0IGRhdGEgPSB7fSBhcyBFdmVudHNMaXN0O1xuICAgIGRhdGEuaXRlbXMgPSByZXNwb25zZS5ib2R5Lml0ZW1zO1xuXG4gICAgZGF0YS5wYWdlcyA9IHRoaXMucGFyc2VQYWdlTGlua3MocmVzcG9uc2UsICcvJyk7XG4gICAgZGF0YS5zdGF0dXMgPSByZXNwb25zZS5zdGF0dXM7XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBhc3luYyBnZXQoZG9tYWluOiBzdHJpbmcsIHF1ZXJ5PzogRXZlbnRzUXVlcnkpIDogUHJvbWlzZTxFdmVudHNMaXN0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdExpc3RXaXRoUGFnZXModXJsam9pbignL3YzJywgZG9tYWluLCAnZXZlbnRzJyksIHF1ZXJ5KTtcbiAgfVxufVxuIiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL2NvbW1vbi9SZXF1ZXN0JztcblxuaW1wb3J0IHtcbiAgSXBQb29sQ3JlYXRlRGF0YSxcbiAgSXBQb29sQ3JlYXRlUmVzcG9uc2UsXG4gIElwUG9vbENyZWF0ZVJlc3VsdCxcbiAgSXBQb29sRGVsZXRlRGF0YSxcbiAgSXBQb29sTGlzdFJlc3BvbnNlLFxuICBJcFBvb2xMaXN0UmVzdWx0LFxuICBJcFBvb2xNZXNzYWdlUmVzcG9uc2UsXG4gIElwUG9vbE1lc3NhZ2VSZXN1bHQsXG4gIElwUG9vbFVwZGF0ZURhdGEsXG59IGZyb20gJy4uL1R5cGVzL0lQUG9vbHMnO1xuaW1wb3J0IHsgSUlQUG9vbHNDbGllbnQgfSBmcm9tICcuLi9JbnRlcmZhY2VzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSXBQb29sc0NsaWVudCBpbXBsZW1lbnRzIElJUFBvb2xzQ2xpZW50IHtcbiAgcmVxdWVzdDogUmVxdWVzdDtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0KSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgfVxuXG4gIGxpc3QoKTogUHJvbWlzZTxJcFBvb2xMaXN0UmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92MS9pcF9wb29scycpXG4gICAgICAudGhlbigocmVzcG9uc2U6IElwUG9vbExpc3RSZXNwb25zZSkgPT4gdGhpcy5wYXJzZUlwUG9vbHNSZXNwb25zZShyZXNwb25zZSkpO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlKGRhdGE6IElwUG9vbENyZWF0ZURhdGEpOiBQcm9taXNlPElwUG9vbENyZWF0ZVJlc3VsdD4ge1xuICAgIGNvbnN0IHJlc3BvbnNlOiBJcFBvb2xDcmVhdGVSZXNwb25zZSA9IGF3YWl0IHRoaXMucmVxdWVzdC5wb3N0V2l0aEZEKCcvdjEvaXBfcG9vbHMnLCBkYXRhKTtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICAuLi5yZXNwb25zZS5ib2R5XG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIHVwZGF0ZShwb29sSWQ6IHN0cmluZywgZGF0YTogSXBQb29sVXBkYXRlRGF0YSk6IFByb21pc2U8SXBQb29sTWVzc2FnZVJlc3VsdD4ge1xuICAgIGNvbnN0IHJlc3BvbnNlOiBJcFBvb2xNZXNzYWdlUmVzcG9uc2UgPSBhd2FpdCB0aGlzLnJlcXVlc3QucGF0Y2hXaXRoRkQoYC92MS9pcF9wb29scy8ke3Bvb2xJZH1gLCBkYXRhKTtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICAuLi5yZXNwb25zZS5ib2R5XG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZShwb29sSWQ6IHN0cmluZywgZGF0YTogSXBQb29sRGVsZXRlRGF0YSk6IFByb21pc2U8SXBQb29sTWVzc2FnZVJlc3VsdD4ge1xuICAgIGNvbnN0IHJlc3BvbnNlOklwUG9vbE1lc3NhZ2VSZXNwb25zZSA9IGF3YWl0IHRoaXMucmVxdWVzdC5kZWxldGUoYC92MS9pcF9wb29scy8ke3Bvb2xJZH1gLCBkYXRhKTtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICAuLi5yZXNwb25zZS5ib2R5XG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VJcFBvb2xzUmVzcG9uc2UocmVzcG9uc2U6IElwUG9vbExpc3RSZXNwb25zZSk6IElwUG9vbExpc3RSZXN1bHQge1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgIC4uLnJlc3BvbnNlLmJvZHlcbiAgICB9O1xuICB9XG59XG4iLCJpbXBvcnQgTWdSZXF1ZXN0IGZyb20gJy4vY29tbW9uL1JlcXVlc3QnO1xuaW1wb3J0IHsgSXBEYXRhLCBJUHNMaXN0UXVlcnksIElwc0xpc3RSZXNwb25zZUJvZHkgfSBmcm9tICcuLi9UeXBlcy9JUHMnO1xuaW1wb3J0IHsgSUlQc0NsaWVudCB9IGZyb20gJy4uL0ludGVyZmFjZXMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJcHNDbGllbnQgaW1wbGVtZW50cyBJSVBzQ2xpZW50IHtcbiAgcmVxdWVzdDogTWdSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IE1nUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBhc3luYyBsaXN0KHF1ZXJ5PzogSVBzTGlzdFF1ZXJ5KTogUHJvbWlzZTxJcHNMaXN0UmVzcG9uc2VCb2R5PiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnJlcXVlc3QuZ2V0KCcvdjMvaXBzJywgcXVlcnkpO1xuICAgIHJldHVybiB0aGlzLnBhcnNlSXBzUmVzcG9uc2U8SXBzTGlzdFJlc3BvbnNlQm9keT4ocmVzcG9uc2UpO1xuICB9XG5cbiAgYXN5bmMgZ2V0KGlwOiBzdHJpbmcpOiBQcm9taXNlPElwRGF0YT4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5yZXF1ZXN0LmdldChgL3YzL2lwcy8ke2lwfWApO1xuICAgIHJldHVybiB0aGlzLnBhcnNlSXBzUmVzcG9uc2U8SXBEYXRhPihyZXNwb25zZSk7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlSXBzUmVzcG9uc2U8VD4ocmVzcG9uc2U6IHsgYm9keTogVCB9KTogVCB7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmJvZHk7XG4gIH1cbn1cbiIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi9jb21tb24vUmVxdWVzdCc7XG5pbXBvcnQgeyBNYWlsZ3VuQ2xpZW50T3B0aW9ucywgSW5wdXRGb3JtRGF0YSwgUmVxdWVzdE9wdGlvbnMgfSBmcm9tICcuLi9UeXBlcyc7XG5cbmltcG9ydCBEb21haW5zQ2xpZW50IGZyb20gJy4vRG9tYWlucy9kb21haW5zQ2xpZW50JztcbmltcG9ydCBFdmVudENsaWVudCBmcm9tICcuL0V2ZW50cyc7XG5pbXBvcnQgU3RhdHNDbGllbnQgZnJvbSAnLi9TdGF0cy9TdGF0c0NsaWVudCc7XG5pbXBvcnQgU3VwcHJlc3Npb25DbGllbnQgZnJvbSAnLi9TdXBwcmVzc2lvbnMvU3VwcHJlc3Npb25zQ2xpZW50JztcbmltcG9ydCBXZWJob29rc0NsaWVudCBmcm9tICcuL1dlYmhvb2tzJztcbmltcG9ydCBNZXNzYWdlc0NsaWVudCBmcm9tICcuL01lc3NhZ2VzJztcbmltcG9ydCBSb3V0ZXNDbGllbnQgZnJvbSAnLi9Sb3V0ZXMnO1xuaW1wb3J0IFZhbGlkYXRlQ2xpZW50IGZyb20gJy4vVmFsaWRhdGlvbnMvdmFsaWRhdGUnO1xuaW1wb3J0IElwc0NsaWVudCBmcm9tICcuL0lQcyc7XG5pbXBvcnQgSXBQb29sc0NsaWVudCBmcm9tICcuL0lQUG9vbHMnO1xuaW1wb3J0IE1haWxpbmdMaXN0c0NsaWVudCBmcm9tICcuL01haWxpbmdMaXN0cy9tYWlsaW5nTGlzdHMnO1xuaW1wb3J0IE1haWxMaXN0c01lbWJlcnMgZnJvbSAnLi9NYWlsaW5nTGlzdHMvbWFpbExpc3RNZW1iZXJzJztcbmltcG9ydCBEb21haW5DcmVkZW50aWFsc0NsaWVudCBmcm9tICcuL0RvbWFpbnMvZG9tYWluc0NyZWRlbnRpYWxzJztcbmltcG9ydCBNdWx0aXBsZVZhbGlkYXRpb25DbGllbnQgZnJvbSAnLi9WYWxpZGF0aW9ucy9tdWx0aXBsZVZhbGlkYXRpb24nO1xuaW1wb3J0IERvbWFpblRlbXBsYXRlc0NsaWVudCBmcm9tICcuL0RvbWFpbnMvZG9tYWluc1RlbXBsYXRlcyc7XG5pbXBvcnQgRG9tYWluVGFnc0NsaWVudCBmcm9tICcuL0RvbWFpbnMvZG9tYWluc1RhZ3MnO1xuaW1wb3J0IFN1YmFjY291bnRzQ2xpZW50IGZyb20gJy4vU3ViYWNjb3VudHMnO1xuXG5pbXBvcnQge1xuICBJRG9tYWluc0NsaWVudCxcbiAgSVdlYkhvb2tzQ2xpZW50LFxuICBJTWFpbGd1bkNsaWVudCxcbiAgSU1haWxpbmdMaXN0c0NsaWVudCxcbiAgSUV2ZW50Q2xpZW50LFxuICBJU3RhdHNDbGllbnQsXG4gIElTdXBwcmVzc2lvbkNsaWVudCxcbiAgSU1lc3NhZ2VzQ2xpZW50LFxuICBJUm91dGVzQ2xpZW50LFxuICBJVmFsaWRhdGlvbkNsaWVudCxcbiAgSUlQc0NsaWVudCxcbiAgSUlQUG9vbHNDbGllbnQsXG4gIElTdWJhY2NvdW50c0NsaWVudCxcbn0gZnJvbSAnLi4vSW50ZXJmYWNlcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1haWxndW5DbGllbnQgaW1wbGVtZW50cyBJTWFpbGd1bkNsaWVudCB7XG4gIHByaXZhdGUgcmVxdWVzdDtcblxuICBwdWJsaWMgZG9tYWluczogSURvbWFpbnNDbGllbnQ7XG4gIHB1YmxpYyB3ZWJob29rczogSVdlYkhvb2tzQ2xpZW50O1xuICBwdWJsaWMgZXZlbnRzOiBJRXZlbnRDbGllbnQ7XG4gIHB1YmxpYyBzdGF0czogSVN0YXRzQ2xpZW50O1xuICBwdWJsaWMgc3VwcHJlc3Npb25zOiBJU3VwcHJlc3Npb25DbGllbnQ7XG4gIHB1YmxpYyBtZXNzYWdlczogSU1lc3NhZ2VzQ2xpZW50O1xuICBwdWJsaWMgcm91dGVzOiBJUm91dGVzQ2xpZW50O1xuICBwdWJsaWMgdmFsaWRhdGU6IElWYWxpZGF0aW9uQ2xpZW50O1xuICBwdWJsaWMgaXBzOiBJSVBzQ2xpZW50O1xuICBwdWJsaWMgaXBfcG9vbHM6IElJUFBvb2xzQ2xpZW50O1xuICBwdWJsaWMgbGlzdHM6IElNYWlsaW5nTGlzdHNDbGllbnQ7XG4gIHB1YmxpYyBzdWJhY2NvdW50czogSVN1YmFjY291bnRzQ2xpZW50O1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IE1haWxndW5DbGllbnRPcHRpb25zLCBmb3JtRGF0YTogSW5wdXRGb3JtRGF0YSkge1xuICAgIGNvbnN0IGNvbmZpZzogUmVxdWVzdE9wdGlvbnMgPSB7IC4uLm9wdGlvbnMgfSBhcyBSZXF1ZXN0T3B0aW9ucztcblxuICAgIGlmICghY29uZmlnLnVybCkge1xuICAgICAgY29uZmlnLnVybCA9ICdodHRwczovL2FwaS5tYWlsZ3VuLm5ldCc7XG4gICAgfVxuXG4gICAgaWYgKCFjb25maWcudXNlcm5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGFyYW1ldGVyIFwidXNlcm5hbWVcIiBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIGlmICghY29uZmlnLmtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQYXJhbWV0ZXIgXCJrZXlcIiBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICB0aGlzLnJlcXVlc3QgPSBuZXcgUmVxdWVzdChjb25maWcsIGZvcm1EYXRhKTtcbiAgICBjb25zdCBtYWlsTGlzdHNNZW1iZXJzID0gbmV3IE1haWxMaXN0c01lbWJlcnModGhpcy5yZXF1ZXN0KTtcbiAgICBjb25zdCBkb21haW5DcmVkZW50aWFsc0NsaWVudCA9IG5ldyBEb21haW5DcmVkZW50aWFsc0NsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIGNvbnN0IGRvbWFpblRlbXBsYXRlc0NsaWVudCA9IG5ldyBEb21haW5UZW1wbGF0ZXNDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICBjb25zdCBkb21haW5UYWdzQ2xpZW50ID0gbmV3IERvbWFpblRhZ3NDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICBjb25zdCBtdWx0aXBsZVZhbGlkYXRpb25DbGllbnQgPSBuZXcgTXVsdGlwbGVWYWxpZGF0aW9uQ2xpZW50KHRoaXMucmVxdWVzdCk7XG5cbiAgICB0aGlzLmRvbWFpbnMgPSBuZXcgRG9tYWluc0NsaWVudChcbiAgICAgIHRoaXMucmVxdWVzdCxcbiAgICAgIGRvbWFpbkNyZWRlbnRpYWxzQ2xpZW50LFxuICAgICAgZG9tYWluVGVtcGxhdGVzQ2xpZW50LFxuICAgICAgZG9tYWluVGFnc0NsaWVudFxuICAgICk7XG4gICAgdGhpcy53ZWJob29rcyA9IG5ldyBXZWJob29rc0NsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIHRoaXMuZXZlbnRzID0gbmV3IEV2ZW50Q2xpZW50KHRoaXMucmVxdWVzdCk7XG4gICAgdGhpcy5zdGF0cyA9IG5ldyBTdGF0c0NsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIHRoaXMuc3VwcHJlc3Npb25zID0gbmV3IFN1cHByZXNzaW9uQ2xpZW50KHRoaXMucmVxdWVzdCk7XG4gICAgdGhpcy5tZXNzYWdlcyA9IG5ldyBNZXNzYWdlc0NsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIHRoaXMucm91dGVzID0gbmV3IFJvdXRlc0NsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIHRoaXMuaXBzID0gbmV3IElwc0NsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIHRoaXMuaXBfcG9vbHMgPSBuZXcgSXBQb29sc0NsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIHRoaXMubGlzdHMgPSBuZXcgTWFpbGluZ0xpc3RzQ2xpZW50KHRoaXMucmVxdWVzdCwgbWFpbExpc3RzTWVtYmVycyk7XG4gICAgdGhpcy52YWxpZGF0ZSA9IG5ldyBWYWxpZGF0ZUNsaWVudCh0aGlzLnJlcXVlc3QsIG11bHRpcGxlVmFsaWRhdGlvbkNsaWVudCk7XG4gICAgdGhpcy5zdWJhY2NvdW50cyA9IG5ldyBTdWJhY2NvdW50c0NsaWVudCh0aGlzLnJlcXVlc3QpO1xuICB9XG5cbiAgc2V0U3ViYWNjb3VudChzdWJhY2NvdW50SWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMucmVxdWVzdD8uc2V0U3ViYWNjb3VudEhlYWRlcihzdWJhY2NvdW50SWQpO1xuICB9XG5cbiAgcmVzZXRTdWJhY2NvdW50KCk6IHZvaWQge1xuICAgIHRoaXMucmVxdWVzdD8ucmVzZXRTdWJhY2NvdW50SGVhZGVyKCk7XG4gIH1cbn1cbiIsImltcG9ydCBSZXF1ZXN0IGZyb20gJy4uL2NvbW1vbi9SZXF1ZXN0JztcbmltcG9ydCB7XG4gIE1haWxMaXN0TWVtYmVyc1F1ZXJ5LFxuICBDcmVhdGVVcGRhdGVNYWlsTGlzdE1lbWJlcnMsXG4gIE1haWxMaXN0TWVtYmVyLFxuICBNdWx0aXBsZU1lbWJlcnNEYXRhLFxuICBNdWx0aXBsZU1lbWJlcnNSZXFEYXRhLFxuICBEZWxldGVkTWVtYmVyLFxuICBDcmVhdGVVcGRhdGVNYWlsTGlzdE1lbWJlcnNSZXEsXG4gIE5ld011bHRpcGxlTWVtYmVyc1Jlc3BvbnNlLFxuICBNYWlsTGlzdE1lbWJlcnNSZXN1bHQsXG4gIE1haWxMaXN0TWVtYmVyc1Jlc3BvbnNlXG59IGZyb20gJy4uLy4uL1R5cGVzL01haWxpbmdMaXN0cyc7XG5pbXBvcnQgTmF2aWdhdGlvblRocnVQYWdlcyBmcm9tICcuLi9jb21tb24vTmF2aWdhdGlvblRocnVQYWdlcyc7XG5pbXBvcnQgeyBJTWFpbExpc3RzTWVtYmVycyB9IGZyb20gJy4uLy4uL0ludGVyZmFjZXMvTWFpbGluZ0xpc3RzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWFpbExpc3RzTWVtYmVyc1xuICBleHRlbmRzIE5hdmlnYXRpb25UaHJ1UGFnZXM8TWFpbExpc3RNZW1iZXJzUmVzdWx0PlxuICBpbXBsZW1lbnRzIElNYWlsTGlzdHNNZW1iZXJzIHtcbiAgYmFzZVJvdXRlOiBzdHJpbmc7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHN1cGVyKHJlcXVlc3QpO1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gICAgdGhpcy5iYXNlUm91dGUgPSAnL3YzL2xpc3RzJztcbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tBbmRVcGRhdGVEYXRhKGRhdGE6IENyZWF0ZVVwZGF0ZU1haWxMaXN0TWVtYmVycykge1xuICAgIGNvbnN0IG5ld0RhdGEgPSB7IC4uLmRhdGEgfTtcblxuICAgIGlmICh0eXBlb2YgZGF0YS52YXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgbmV3RGF0YS52YXJzID0gSlNPTi5zdHJpbmdpZnkobmV3RGF0YS52YXJzKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGRhdGEuc3Vic2NyaWJlZCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICBuZXdEYXRhLnN1YnNjcmliZWQgPSBkYXRhLnN1YnNjcmliZWQgPyAneWVzJyA6ICdubyc7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ld0RhdGEgYXMgQ3JlYXRlVXBkYXRlTWFpbExpc3RNZW1iZXJzUmVxO1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlTGlzdChcbiAgICByZXNwb25zZTogTWFpbExpc3RNZW1iZXJzUmVzcG9uc2UsXG4gICk6IE1haWxMaXN0TWVtYmVyc1Jlc3VsdCB7XG4gICAgY29uc3QgZGF0YSA9IHt9IGFzIE1haWxMaXN0TWVtYmVyc1Jlc3VsdDtcbiAgICBkYXRhLml0ZW1zID0gcmVzcG9uc2UuYm9keS5pdGVtcztcblxuICAgIGRhdGEucGFnZXMgPSB0aGlzLnBhcnNlUGFnZUxpbmtzKHJlc3BvbnNlLCAnPycsICdhZGRyZXNzJyk7XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBhc3luYyBsaXN0TWVtYmVycyhcbiAgICBtYWlsTGlzdEFkZHJlc3M6IHN0cmluZyxcbiAgICBxdWVyeT86IE1haWxMaXN0TWVtYmVyc1F1ZXJ5XG4gICk6IFByb21pc2U8TWFpbExpc3RNZW1iZXJzUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdExpc3RXaXRoUGFnZXMoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfS9tZW1iZXJzL3BhZ2VzYCwgcXVlcnkpO1xuICB9XG5cbiAgZ2V0TWVtYmVyKG1haWxMaXN0QWRkcmVzczogc3RyaW5nLCBtYWlsTGlzdE1lbWJlckFkZHJlc3M6IHN0cmluZyk6IFByb21pc2U8TWFpbExpc3RNZW1iZXI+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldChgJHt0aGlzLmJhc2VSb3V0ZX0vJHttYWlsTGlzdEFkZHJlc3N9L21lbWJlcnMvJHttYWlsTGlzdE1lbWJlckFkZHJlc3N9YClcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuYm9keS5tZW1iZXIgYXMgTWFpbExpc3RNZW1iZXIpO1xuICB9XG5cbiAgY3JlYXRlTWVtYmVyKFxuICAgIG1haWxMaXN0QWRkcmVzczogc3RyaW5nLFxuICAgIGRhdGE6IENyZWF0ZVVwZGF0ZU1haWxMaXN0TWVtYmVyc1xuICApOiBQcm9taXNlPE1haWxMaXN0TWVtYmVyPiB7XG4gICAgY29uc3QgcmVxRGF0YSA9IHRoaXMuY2hlY2tBbmRVcGRhdGVEYXRhKGRhdGEpO1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRChgJHt0aGlzLmJhc2VSb3V0ZX0vJHttYWlsTGlzdEFkZHJlc3N9L21lbWJlcnNgLCByZXFEYXRhKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5Lm1lbWJlciBhcyBNYWlsTGlzdE1lbWJlcik7XG4gIH1cblxuICBjcmVhdGVNZW1iZXJzKFxuICAgIG1haWxMaXN0QWRkcmVzczogc3RyaW5nLFxuICAgIGRhdGE6IE11bHRpcGxlTWVtYmVyc0RhdGFcbiAgKTogUHJvbWlzZTxOZXdNdWx0aXBsZU1lbWJlcnNSZXNwb25zZT4ge1xuICAgIGNvbnN0IG5ld0RhdGE6IE11bHRpcGxlTWVtYmVyc1JlcURhdGEgPSB7XG4gICAgICBtZW1iZXJzOiBBcnJheS5pc0FycmF5KGRhdGEubWVtYmVycykgPyBKU09OLnN0cmluZ2lmeShkYXRhLm1lbWJlcnMpIDogZGF0YS5tZW1iZXJzLFxuICAgICAgdXBzZXJ0OiBkYXRhLnVwc2VydFxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfS9tZW1iZXJzLmpzb25gLCBuZXdEYXRhKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5IGFzIE5ld011bHRpcGxlTWVtYmVyc1Jlc3BvbnNlKTtcbiAgfVxuXG4gIHVwZGF0ZU1lbWJlcihcbiAgICBtYWlsTGlzdEFkZHJlc3M6IHN0cmluZyxcbiAgICBtYWlsTGlzdE1lbWJlckFkZHJlc3M6IHN0cmluZyxcbiAgICBkYXRhOiBDcmVhdGVVcGRhdGVNYWlsTGlzdE1lbWJlcnNcbiAgKTogUHJvbWlzZTxNYWlsTGlzdE1lbWJlcj4ge1xuICAgIGNvbnN0IHJlcURhdGEgPSB0aGlzLmNoZWNrQW5kVXBkYXRlRGF0YShkYXRhKTtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnB1dFdpdGhGRChgJHt0aGlzLmJhc2VSb3V0ZX0vJHttYWlsTGlzdEFkZHJlc3N9L21lbWJlcnMvJHttYWlsTGlzdE1lbWJlckFkZHJlc3N9YCwgcmVxRGF0YSlcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuYm9keS5tZW1iZXIgYXMgTWFpbExpc3RNZW1iZXIpO1xuICB9XG5cbiAgZGVzdHJveU1lbWJlcihtYWlsTGlzdEFkZHJlc3M6IHN0cmluZywgbWFpbExpc3RNZW1iZXJBZGRyZXNzOiBzdHJpbmcpIDogUHJvbWlzZTxEZWxldGVkTWVtYmVyPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfS9tZW1iZXJzLyR7bWFpbExpc3RNZW1iZXJBZGRyZXNzfWApXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkgYXMgRGVsZXRlZE1lbWJlcik7XG4gIH1cbn1cbiIsImltcG9ydCBSZXF1ZXN0IGZyb20gJy4uL2NvbW1vbi9SZXF1ZXN0JztcbmltcG9ydCB7XG4gIExpc3RzUXVlcnksXG4gIENyZWF0ZVVwZGF0ZUxpc3QsXG4gIERlc3Ryb3llZExpc3QsXG4gIE1haWxpbmdMaXN0LFxuICBNYWlsaW5nTGlzdFZhbGlkYXRpb25BcGlSZXNwb25zZSxcbiAgU3RhcnRWYWxpZGF0aW9uUmVzdWx0LFxuICBNYWlsaW5nTGlzdFZhbGlkYXRpb25SZXN1bHQsXG4gIE1haWxpbmdMaXN0Q2FuY2VsVmFsaWRhdGlvblJlc3VsdCxcbiAgTWFpbGluZ0xpc3RSZXN1bHQsXG4gIE1haWxpbmdMaXN0QXBpUmVzcG9uc2Vcbn0gZnJvbSAnLi4vLi4vVHlwZXMvTWFpbGluZ0xpc3RzJztcbmltcG9ydCB7IElNYWlsTGlzdHNNZW1iZXJzIH0gZnJvbSAnLi4vLi4vSW50ZXJmYWNlcy9NYWlsaW5nTGlzdHMvTWFpbGluZ0xpc3RNZW1iZXJzJztcbmltcG9ydCBOYXZpZ2F0aW9uVGhydVBhZ2VzIGZyb20gJy4uL2NvbW1vbi9OYXZpZ2F0aW9uVGhydVBhZ2VzJztcbmltcG9ydCB7IElNYWlsaW5nTGlzdHNDbGllbnQgfSBmcm9tICcuLi8uLi9JbnRlcmZhY2VzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWFpbGluZ0xpc3RzQ2xpZW50XG4gIGV4dGVuZHMgTmF2aWdhdGlvblRocnVQYWdlczxNYWlsaW5nTGlzdFJlc3VsdD5cbiAgaW1wbGVtZW50cyBJTWFpbGluZ0xpc3RzQ2xpZW50IHtcbiAgYmFzZVJvdXRlOiBzdHJpbmc7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG4gIHB1YmxpYyBtZW1iZXJzOiBJTWFpbExpc3RzTWVtYmVycztcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0LCBtZW1iZXJzOiBJTWFpbExpc3RzTWVtYmVycykge1xuICAgIHN1cGVyKHJlcXVlc3QpO1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gICAgdGhpcy5iYXNlUm91dGUgPSAnL3YzL2xpc3RzJztcbiAgICB0aGlzLm1lbWJlcnMgPSBtZW1iZXJzO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZVZhbGlkYXRpb25SZXN1bHQoXG4gICAgc3RhdHVzOiBudW1iZXIsXG4gICAgZGF0YTogTWFpbGluZ0xpc3RWYWxpZGF0aW9uQXBpUmVzcG9uc2VcbiAgKTogTWFpbGluZ0xpc3RWYWxpZGF0aW9uUmVzdWx0IHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzLFxuICAgICAgdmFsaWRhdGlvblJlc3VsdDoge1xuICAgICAgICAuLi5kYXRhLFxuICAgICAgICBjcmVhdGVkX2F0OiBuZXcgRGF0ZShkYXRhLmNyZWF0ZWRfYXQgKiAxMDAwKSAvLyBhZGQgbWlsbGlzZWNvbmQgdG8gVW5peCB0aW1lc3RhbXBcbiAgICAgIH1cbiAgICB9IGFzIE1haWxpbmdMaXN0VmFsaWRhdGlvblJlc3VsdDtcbiAgfVxuXG4gIHByb3RlY3RlZCBwYXJzZUxpc3QocmVzcG9uc2U6IE1haWxpbmdMaXN0QXBpUmVzcG9uc2UpOiBNYWlsaW5nTGlzdFJlc3VsdCB7XG4gICAgY29uc3QgZGF0YSA9IHt9IGFzIE1haWxpbmdMaXN0UmVzdWx0O1xuXG4gICAgZGF0YS5pdGVtcyA9IHJlc3BvbnNlLmJvZHkuaXRlbXM7XG5cbiAgICBkYXRhLnBhZ2VzID0gdGhpcy5wYXJzZVBhZ2VMaW5rcyhyZXNwb25zZSwgJz8nLCAnYWRkcmVzcycpO1xuICAgIGRhdGEuc3RhdHVzID0gcmVzcG9uc2Uuc3RhdHVzO1xuXG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBhc3luYyBsaXN0KHF1ZXJ5PzogTGlzdHNRdWVyeSk6IFByb21pc2U8TWFpbGluZ0xpc3RSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0TGlzdFdpdGhQYWdlcyhgJHt0aGlzLmJhc2VSb3V0ZX0vcGFnZXNgLCBxdWVyeSk7XG4gIH1cblxuICBnZXQobWFpbExpc3RBZGRyZXNzOiBzdHJpbmcpOiBQcm9taXNlPE1haWxpbmdMaXN0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfWApXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkubGlzdCBhcyBNYWlsaW5nTGlzdCk7XG4gIH1cblxuICBjcmVhdGUoZGF0YTogQ3JlYXRlVXBkYXRlTGlzdCk6IFByb21pc2U8TWFpbGluZ0xpc3Q+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQodGhpcy5iYXNlUm91dGUsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkubGlzdCBhcyBNYWlsaW5nTGlzdCk7XG4gIH1cblxuICB1cGRhdGUobWFpbExpc3RBZGRyZXNzOiBzdHJpbmcsIGRhdGE6IENyZWF0ZVVwZGF0ZUxpc3QpOiBQcm9taXNlPE1haWxpbmdMaXN0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXRXaXRoRkQoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfWAsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkubGlzdCBhcyBNYWlsaW5nTGlzdCk7XG4gIH1cblxuICBkZXN0cm95KG1haWxMaXN0QWRkcmVzczogc3RyaW5nKTogUHJvbWlzZTxEZXN0cm95ZWRMaXN0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfWApXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkgYXMgRGVzdHJveWVkTGlzdCk7XG4gIH1cblxuICB2YWxpZGF0ZShtYWlsTGlzdEFkZHJlc3M6IHN0cmluZyk6IFByb21pc2U8U3RhcnRWYWxpZGF0aW9uUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wb3N0KGAke3RoaXMuYmFzZVJvdXRlfS8ke21haWxMaXN0QWRkcmVzc30vdmFsaWRhdGVgLCB7fSlcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gKHtcbiAgICAgICAgc3RhdHVzOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICAgIC4uLnJlc3BvbnNlLmJvZHlcbiAgICAgIH0pIGFzIFN0YXJ0VmFsaWRhdGlvblJlc3VsdCk7XG4gIH1cblxuICB2YWxpZGF0aW9uUmVzdWx0KG1haWxMaXN0QWRkcmVzczogc3RyaW5nKTogUHJvbWlzZTxNYWlsaW5nTGlzdFZhbGlkYXRpb25SZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldChgJHt0aGlzLmJhc2VSb3V0ZX0vJHttYWlsTGlzdEFkZHJlc3N9L3ZhbGlkYXRlYClcbiAgICAgIC50aGVuKFxuICAgICAgICAocmVzcG9uc2UpID0+IHRoaXMucGFyc2VWYWxpZGF0aW9uUmVzdWx0KFxuICAgICAgICAgIHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgICAgICAgcmVzcG9uc2UuYm9keSBhcyBNYWlsaW5nTGlzdFZhbGlkYXRpb25BcGlSZXNwb25zZVxuICAgICAgICApXG4gICAgICApO1xuICB9XG5cbiAgY2FuY2VsVmFsaWRhdGlvbihtYWlsTGlzdEFkZHJlc3M6IHN0cmluZyk6IFByb21pc2U8TWFpbGluZ0xpc3RDYW5jZWxWYWxpZGF0aW9uUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfS92YWxpZGF0ZWApXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+ICh7XG4gICAgICAgIHN0YXR1czogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgICBtZXNzYWdlOiByZXNwb25zZS5ib2R5Lm1lc3NhZ2VcbiAgICAgIH0gYXMgTWFpbGluZ0xpc3RDYW5jZWxWYWxpZGF0aW9uUmVzdWx0KSk7XG4gIH1cbn1cbiIsImltcG9ydCBBUElFcnJvciBmcm9tICcuL2NvbW1vbi9FcnJvcic7XG5pbXBvcnQge1xuICBBUElFcnJvck9wdGlvbnMsXG4gIE1haWxndW5NZXNzYWdlRGF0YSxcbiAgTWVzc2FnZXNTZW5kQVBJUmVzcG9uc2UsXG4gIE1lc3NhZ2VzU2VuZFJlc3VsdFxufSBmcm9tICcuLi9UeXBlcyc7XG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL2NvbW1vbi9SZXF1ZXN0JztcbmltcG9ydCB7IElNZXNzYWdlc0NsaWVudCB9IGZyb20gJy4uL0ludGVyZmFjZXMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNZXNzYWdlc0NsaWVudCBpbXBsZW1lbnRzIElNZXNzYWdlc0NsaWVudCB7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBwcml2YXRlIHByZXBhcmVCb29sZWFuVmFsdWVzKGRhdGE6IE1haWxndW5NZXNzYWdlRGF0YSk6IE1haWxndW5NZXNzYWdlRGF0YSB7XG4gICAgY29uc3QgeWVzTm9Qcm9wZXJ0aWVzID0gbmV3IFNldChbXG4gICAgICAnbzp0ZXN0bW9kZScsXG4gICAgICAndDp0ZXh0JyxcbiAgICAgICdvOmRraW0nLFxuICAgICAgJ286dHJhY2tpbmcnLFxuICAgICAgJ286dHJhY2tpbmctY2xpY2tzJyxcbiAgICAgICdvOnRyYWNraW5nLW9wZW5zJyxcbiAgICAgICdvOnJlcXVpcmUtdGxzJyxcbiAgICAgICdvOnNraXAtdmVyaWZpY2F0aW9uJ1xuICAgIF0pO1xuXG4gICAgaWYgKCFkYXRhIHx8IE9iamVjdC5rZXlzKGRhdGEpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEFQSUVycm9yKHtcbiAgICAgICAgc3RhdHVzOiA0MDAsXG4gICAgICAgIG1lc3NhZ2U6ICdNZXNzYWdlIGRhdGEgb2JqZWN0IGNhbiBub3QgYmUgZW1wdHknXG4gICAgICB9IGFzIEFQSUVycm9yT3B0aW9ucyk7XG4gICAgfVxuICAgIHJldHVybiBPYmplY3Qua2V5cyhkYXRhKS5yZWR1Y2UoKGFjYywga2V5KSA9PiB7XG4gICAgICBpZiAoeWVzTm9Qcm9wZXJ0aWVzLmhhcyhrZXkpICYmIHR5cGVvZiBkYXRhW2tleV0gPT09ICdib29sZWFuJykge1xuICAgICAgICBhY2Nba2V5XSA9IGRhdGFba2V5XSA/ICd5ZXMnIDogJ25vJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFjY1trZXldID0gZGF0YVtrZXldO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSBhcyBNYWlsZ3VuTWVzc2FnZURhdGEpO1xuICB9XG5cbiAgX3BhcnNlUmVzcG9uc2UocmVzcG9uc2U6IE1lc3NhZ2VzU2VuZEFQSVJlc3BvbnNlKTogTWVzc2FnZXNTZW5kUmVzdWx0IHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICAuLi5yZXNwb25zZS5ib2R5XG4gICAgfTtcbiAgfVxuXG4gIGNyZWF0ZShkb21haW46IHN0cmluZywgZGF0YTogTWFpbGd1bk1lc3NhZ2VEYXRhKTogUHJvbWlzZTxNZXNzYWdlc1NlbmRSZXN1bHQ+IHtcbiAgICBpZiAoZGF0YS5tZXNzYWdlKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQoYC92My8ke2RvbWFpbn0vbWVzc2FnZXMubWltZWAsIGRhdGEpXG4gICAgICAgIC50aGVuKHRoaXMuX3BhcnNlUmVzcG9uc2UpO1xuICAgIH1cblxuICAgIGNvbnN0IG1vZGlmaWVkRGF0YSA9IHRoaXMucHJlcGFyZUJvb2xlYW5WYWx1ZXMoZGF0YSk7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wb3N0V2l0aEZEKGAvdjMvJHtkb21haW59L21lc3NhZ2VzYCwgbW9kaWZpZWREYXRhKVxuICAgICAgLnRoZW4odGhpcy5fcGFyc2VSZXNwb25zZSk7XG4gIH1cbn1cbiIsImltcG9ydCB7IElSb3V0ZXNDbGllbnQgfSBmcm9tICcuLi9JbnRlcmZhY2VzJztcbmltcG9ydCB7XG4gIENyZWF0ZVVwZGF0ZVJvdXRlRGF0YSwgRGVzdHJveVJvdXRlUmVzcG9uc2UsIFJvdXRlLCBSb3V0ZXNMaXN0UXVlcnksIFVwZGF0ZVJvdXRlUmVzcG9uc2Vcbn0gZnJvbSAnLi4vVHlwZXMvUm91dGVzJztcbmltcG9ydCBSZXF1ZXN0IGZyb20gJy4vY29tbW9uL1JlcXVlc3QnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSb3V0ZXNDbGllbnQgaW1wbGVtZW50cyBJUm91dGVzQ2xpZW50IHtcbiAgcmVxdWVzdDogUmVxdWVzdDtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0KSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgfVxuXG4gIGxpc3QocXVlcnk6IFJvdXRlc0xpc3RRdWVyeSk6IFByb21pc2U8Um91dGVbXT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KCcvdjMvcm91dGVzJywgcXVlcnkpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkuaXRlbXMpO1xuICB9XG5cbiAgZ2V0KGlkOiBzdHJpbmcpOiBQcm9taXNlPFJvdXRlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoYC92My9yb3V0ZXMvJHtpZH1gKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5LnJvdXRlKTtcbiAgfVxuXG4gIGNyZWF0ZShkYXRhOiBDcmVhdGVVcGRhdGVSb3V0ZURhdGEpOiBQcm9taXNlPFJvdXRlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wb3N0V2l0aEZEKCcvdjMvcm91dGVzJywgZGF0YSlcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuYm9keS5yb3V0ZSk7XG4gIH1cblxuICB1cGRhdGUoaWQ6IHN0cmluZywgZGF0YTogQ3JlYXRlVXBkYXRlUm91dGVEYXRhKTogUHJvbWlzZTxVcGRhdGVSb3V0ZVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXRXaXRoRkQoYC92My9yb3V0ZXMvJHtpZH1gLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5KTtcbiAgfVxuXG4gIGRlc3Ryb3koaWQ6IHN0cmluZyk6IFByb21pc2U8RGVzdHJveVJvdXRlUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZShgL3YzL3JvdXRlcy8ke2lkfWApXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkpO1xuICB9XG59XG4iLCJpbXBvcnQgdXJsam9pbiBmcm9tICd1cmwtam9pbic7XG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuLi9jb21tb24vUmVxdWVzdCc7XG5pbXBvcnQgeyBTdGF0c1F1ZXJ5LCBTdGF0c09wdGlvbnMgfSBmcm9tICcuLi8uLi9UeXBlcy9TdGF0cyc7XG5pbXBvcnQgeyBJTG9nZ2VyIH0gZnJvbSAnLi4vLi4vSW50ZXJmYWNlcy9Db21tb24nO1xuaW1wb3J0IFN0YXRzQ29udGFpbmVyIGZyb20gJy4vU3RhdHNDb250YWluZXInO1xuaW1wb3J0IHsgSVN0YXRzQ2xpZW50LCBJU3RhdHNDb250YWluZXIgfSBmcm9tICcuLi8uLi9JbnRlcmZhY2VzL1N0YXRzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3RhdHNDbGllbnQgaW1wbGVtZW50cyBJU3RhdHNDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuICBwcml2YXRlIGxvZ2dlcjogSUxvZ2dlcjtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0LCBsb2dnZXI6IElMb2dnZXIgPSBjb25zb2xlKSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgICB0aGlzLmxvZ2dlciA9IGxvZ2dlcjtcbiAgfVxuXG4gIHByaXZhdGUgY29udmVydERhdGVUb1VUQyhrZXk6c3RyaW5nLCBpbnB1dERhdGU6IERhdGUpOiBBcnJheTxzdHJpbmc+IHtcbiAgICAvKlxuICAgICAgQmVjYXVzZSBcIm5ldyBEYXRlKCcyMDIyLTEyLTI1VDAwOjAwOjAwLjAwMFonKVwiIGJlY29tZXMgXCJTdW4gRGVjIDI1IDIwMjIgMDI6MDA6MDAgR01UKzAyMDBcIlxuICAgICAgKHBsdXMgMiBob3VycyBmcm9tIHRoZSB0aW1lem9uZSlcbiAgICAgIGFuZCBiZWNhdXNlIGZvciBBUEksIHdlIG5lZWQgdG8gcHJvdmlkZSB0aGUgZGF0ZSBpbiB0aGUgZXhwZWN0ZWQgZm9ybWF0XG4gICAgICBleDogJ1RodSwgMTMgT2N0IDIwMTEgMTg6MDI6MDAgKzAwMDAnLlxuICAgICAgSGVyZSB3ZSB0cnkgYXV0by1jb252ZXJ0IHRoZW0gdG8gVVRDXG4gICAgKi9cbiAgICB0aGlzLmxvZ2dlci53YXJuKGBEYXRlOlwiJHtpbnB1dERhdGV9XCIgd2FzIGF1dG8tY29udmVydGVkIHRvIFVUQyB0aW1lIHpvbmUuXG5WYWx1ZSBcIiR7aW5wdXREYXRlLnRvVVRDU3RyaW5nKCl9XCIgd2lsbCBiZSB1c2VkIGZvciByZXF1ZXN0LlxuQ29uc2lkZXIgdXNpbmcgc3RpbmcgdHlwZSBmb3IgcHJvcGVydHkgXCIke2tleX1cIiB0byBhdm9pZCBhdXRvLWNvbnZlcnRpbmdgKTtcbiAgICByZXR1cm4gW2tleSwgaW5wdXREYXRlLnRvVVRDU3RyaW5nKCldO1xuICB9XG5cbiAgcHJpdmF0ZSBwcmVwYXJlU2VhcmNoUGFyYW1zKHF1ZXJ5OiBTdGF0c1F1ZXJ5IHwgdW5kZWZpbmVkKTogQXJyYXk8QXJyYXk8c3RyaW5nPj4ge1xuICAgIGxldCBzZWFyY2hQYXJhbXMgPSBbXSBhcyBBcnJheTxBcnJheTxzdHJpbmc+PjtcbiAgICBpZiAodHlwZW9mIHF1ZXJ5ID09PSAnb2JqZWN0JyAmJiBPYmplY3Qua2V5cyhxdWVyeSkubGVuZ3RoKSB7XG4gICAgICBzZWFyY2hQYXJhbXMgPSBPYmplY3QuZW50cmllcyhxdWVyeSkucmVkdWNlKChhcnJheVdpdGhQYWlycywgY3VycmVudFBhaXIpID0+IHtcbiAgICAgICAgY29uc3QgW2tleSwgdmFsdWVdID0gY3VycmVudFBhaXI7XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpICYmIHZhbHVlLmxlbmd0aCkgeyAvLyBldmVudDogWydkZWxpdmVyZWQnLCAnYWNjZXB0ZWQnXVxuICAgICAgICAgIGNvbnN0IHJlcGVhdGVkUHJvcGVydHkgPSB2YWx1ZS5tYXAoKGl0ZW0pID0+IFtrZXksIGl0ZW1dKTtcbiAgICAgICAgICByZXR1cm4gWy4uLmFycmF5V2l0aFBhaXJzLCAuLi5yZXBlYXRlZFByb3BlcnR5XTsgLy8gW1tldmVudCxkZWxpdmVyZWRdLCBbZXZlbnQsYWNjZXB0ZWRdXVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICAgIGFycmF5V2l0aFBhaXJzLnB1c2godGhpcy5jb252ZXJ0RGF0ZVRvVVRDKGtleSwgdmFsdWUpKTtcbiAgICAgICAgICByZXR1cm4gYXJyYXlXaXRoUGFpcnM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGFycmF5V2l0aFBhaXJzLnB1c2goW2tleSwgdmFsdWVdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhcnJheVdpdGhQYWlycztcbiAgICAgIH0sIFtdIGFzIEFycmF5PEFycmF5PHN0cmluZz4+KTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2VhcmNoUGFyYW1zO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZVN0YXRzKHJlc3BvbnNlOiB7IGJvZHk6IFN0YXRzT3B0aW9ucyB9KTogSVN0YXRzQ29udGFpbmVyIHtcbiAgICByZXR1cm4gbmV3IFN0YXRzQ29udGFpbmVyKHJlc3BvbnNlLmJvZHkpO1xuICB9XG5cbiAgZ2V0RG9tYWluKGRvbWFpbjogc3RyaW5nLCBxdWVyeT86IFN0YXRzUXVlcnkpOiBQcm9taXNlPElTdGF0c0NvbnRhaW5lcj4ge1xuICAgIGNvbnN0IHNlYXJjaFBhcmFtcyA9IHRoaXMucHJlcGFyZVNlYXJjaFBhcmFtcyhxdWVyeSk7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQodXJsam9pbignL3YzJywgZG9tYWluLCAnc3RhdHMvdG90YWwnKSwgc2VhcmNoUGFyYW1zKVxuICAgICAgLnRoZW4odGhpcy5wYXJzZVN0YXRzKTtcbiAgfVxuXG4gIGdldEFjY291bnQocXVlcnk/OiBTdGF0c1F1ZXJ5KTogUHJvbWlzZTxJU3RhdHNDb250YWluZXI+IHtcbiAgICBjb25zdCBzZWFyY2hQYXJhbXMgPSB0aGlzLnByZXBhcmVTZWFyY2hQYXJhbXMocXVlcnkpO1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KCcvdjMvc3RhdHMvdG90YWwnLCBzZWFyY2hQYXJhbXMpXG4gICAgICAudGhlbih0aGlzLnBhcnNlU3RhdHMpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBJU3RhdHNDb250YWluZXIgfSBmcm9tICcuLi8uLi9JbnRlcmZhY2VzL1N0YXRzJztcbmltcG9ydCB7IFN0YXQsIFN0YXRzT3B0aW9ucyB9IGZyb20gJy4uLy4uL1R5cGVzL1N0YXRzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3RhdHNDb250YWluZXIgaW1wbGVtZW50cyBJU3RhdHNDb250YWluZXIge1xuICAgIHN0YXJ0OiBEYXRlO1xuICAgIGVuZDogRGF0ZTtcbiAgICByZXNvbHV0aW9uOiBzdHJpbmc7XG4gICAgc3RhdHM6IFN0YXRbXTtcbiAgICBjb25zdHJ1Y3RvcihkYXRhOiBTdGF0c09wdGlvbnMpIHtcbiAgICAgIHRoaXMuc3RhcnQgPSBuZXcgRGF0ZShkYXRhLnN0YXJ0KTtcbiAgICAgIHRoaXMuZW5kID0gbmV3IERhdGUoZGF0YS5lbmQpO1xuICAgICAgdGhpcy5yZXNvbHV0aW9uID0gZGF0YS5yZXNvbHV0aW9uO1xuICAgICAgdGhpcy5zdGF0cyA9IGRhdGEuc3RhdHMubWFwKGZ1bmN0aW9uIChzdGF0OiBTdGF0KSB7XG4gICAgICAgIGNvbnN0IHJlcyA9IHsgLi4uc3RhdCB9O1xuICAgICAgICByZXMudGltZSA9IG5ldyBEYXRlKHN0YXQudGltZSk7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgICB9KTtcbiAgICB9XG59XG4iLCJpbXBvcnQgUmVxdWVzdCBmcm9tICcuL2NvbW1vbi9SZXF1ZXN0JztcbmltcG9ydCB7IElTdWJhY2NvdW50c0NsaWVudCB9IGZyb20gJy4uL0ludGVyZmFjZXMnO1xuaW1wb3J0IHtcbiAgU3ViYWNjb3VudExpc3RSZXNwb25zZURhdGEsXG4gIFN1YmFjY291bnRSZXNwb25zZURhdGEsXG4gIFN1YmFjY291bnRzUXVlcnksXG59IGZyb20gJy4uL1R5cGVzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3ViYWNjb3VudHNDbGllbnQgaW1wbGVtZW50cyBJU3ViYWNjb3VudHNDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuICBzdGF0aWMgU1VCQUNDT1VOVF9IRUFERVIgPSAnWC1NYWlsZ3VuLU9uLUJlaGFsZi1PZic7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBsaXN0KHF1ZXJ5PzogU3ViYWNjb3VudHNRdWVyeSk6IFByb21pc2U8U3ViYWNjb3VudExpc3RSZXNwb25zZURhdGE+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCgnL3Y1L2FjY291bnRzL3N1YmFjY291bnRzJywgcXVlcnkpXG4gICAgICAudGhlbigocmVzKSA9PiByZXMuYm9keSk7XG4gIH1cblxuICBnZXQoaWQ6c3RyaW5nKTogUHJvbWlzZTxTdWJhY2NvdW50UmVzcG9uc2VEYXRhPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoYC92NS9hY2NvdW50cy9zdWJhY2NvdW50cy8ke2lkfWApXG4gICAgICAudGhlbigocmVzKSA9PiByZXMuYm9keSk7XG4gIH1cblxuICBjcmVhdGUobmFtZTpzdHJpbmcpOiBQcm9taXNlPFN1YmFjY291bnRSZXNwb25zZURhdGE+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQoJy92NS9hY2NvdW50cy9zdWJhY2NvdW50cycsIHsgbmFtZSB9KVxuICAgICAgLnRoZW4oKHJlcykgPT4gcmVzLmJvZHkpO1xuICB9XG5cbiAgZW5hYmxlKGlkOnN0cmluZyk6IFByb21pc2U8U3ViYWNjb3VudFJlc3BvbnNlRGF0YT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdChgL3Y1L2FjY291bnRzL3N1YmFjY291bnRzLyR7aWR9L2VuYWJsZWApXG4gICAgICAudGhlbigocmVzKSA9PiByZXMuYm9keSk7XG4gIH1cblxuICBkaXNhYmxlKGlkOnN0cmluZyk6IFByb21pc2U8U3ViYWNjb3VudFJlc3BvbnNlRGF0YT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdChgL3Y1L2FjY291bnRzL3N1YmFjY291bnRzLyR7aWR9L2Rpc2FibGVgKVxuICAgICAgLnRoZW4oKHJlcykgPT4gcmVzLmJvZHkpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBTdXBwcmVzc2lvbk1vZGVscyB9IGZyb20gJy4uLy4uL0VudW1zJztcbmltcG9ydCB7IElCb3VuY2UgfSBmcm9tICcuLi8uLi9JbnRlcmZhY2VzL1N1cHByZXNzaW9ucyc7XG5pbXBvcnQgeyBCb3VuY2VEYXRhIH0gZnJvbSAnLi4vLi4vVHlwZXMvU3VwcHJlc3Npb25zJztcbmltcG9ydCBTdXBwcmVzc2lvbiBmcm9tICcuL1N1cHByZXNzaW9uJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQm91bmNlIGV4dGVuZHMgU3VwcHJlc3Npb24gaW1wbGVtZW50cyBJQm91bmNlIHtcbiAgICBhZGRyZXNzOiBzdHJpbmc7XG4gICAgY29kZTogbnVtYmVyO1xuICAgIGVycm9yOiBzdHJpbmc7XG4gICAgLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4gICAgY3JlYXRlZF9hdDogRGF0ZTtcblxuICAgIGNvbnN0cnVjdG9yKGRhdGE6IEJvdW5jZURhdGEpIHtcbiAgICAgIHN1cGVyKFN1cHByZXNzaW9uTW9kZWxzLkJPVU5DRVMpO1xuICAgICAgdGhpcy5hZGRyZXNzID0gZGF0YS5hZGRyZXNzO1xuICAgICAgdGhpcy5jb2RlID0gK2RhdGEuY29kZTtcbiAgICAgIHRoaXMuZXJyb3IgPSBkYXRhLmVycm9yO1xuICAgICAgdGhpcy5jcmVhdGVkX2F0ID0gbmV3IERhdGUoZGF0YS5jcmVhdGVkX2F0KTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBTdXBwcmVzc2lvbk1vZGVscyB9IGZyb20gJy4uLy4uL0VudW1zJztcbmltcG9ydCB7IElDb21wbGFpbnQgfSBmcm9tICcuLi8uLi9JbnRlcmZhY2VzL1N1cHByZXNzaW9ucyc7XG5pbXBvcnQgeyBDb21wbGFpbnREYXRhIH0gZnJvbSAnLi4vLi4vVHlwZXMvU3VwcHJlc3Npb25zJztcbmltcG9ydCBTdXBwcmVzc2lvbiBmcm9tICcuL1N1cHByZXNzaW9uJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ29tcGxhaW50IGV4dGVuZHMgU3VwcHJlc3Npb24gaW1wbGVtZW50cyBJQ29tcGxhaW50IHtcbiAgICBhZGRyZXNzOiBzdHJpbmc7XG4gICAgLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4gICAgY3JlYXRlZF9hdDogRGF0ZTtcbiAgICBjb25zdHJ1Y3RvcihkYXRhOiBDb21wbGFpbnREYXRhKSB7XG4gICAgICBzdXBlcihTdXBwcmVzc2lvbk1vZGVscy5DT01QTEFJTlRTKTtcbiAgICAgIHRoaXMuYWRkcmVzcyA9IGRhdGEuYWRkcmVzcztcbiAgICAgIHRoaXMuY3JlYXRlZF9hdCA9IG5ldyBEYXRlKGRhdGEuY3JlYXRlZF9hdCk7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgU3VwcHJlc3Npb25Nb2RlbHMgfSBmcm9tICcuLi8uLi9FbnVtcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFN1cHByZXNzaW9uIHtcbiAgICB0eXBlOiBzdHJpbmc7XG4gICAgY29uc3RydWN0b3IodHlwZTogU3VwcHJlc3Npb25Nb2RlbHMpIHtcbiAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgfVxufVxuIiwiaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuXG4vKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cblxuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi4vY29tbW9uL1JlcXVlc3QnO1xuXG5pbXBvcnQgQVBJRXJyb3IgZnJvbSAnLi4vY29tbW9uL0Vycm9yJztcbmltcG9ydCBOYXZpZ2F0aW9uVGhydVBhZ2VzIGZyb20gJy4uL2NvbW1vbi9OYXZpZ2F0aW9uVGhydVBhZ2VzJztcbmltcG9ydCBCb3VuY2UgZnJvbSAnLi9Cb3VuY2UnO1xuaW1wb3J0IENvbXBsYWludCBmcm9tICcuL0NvbXBsYWludCc7XG5pbXBvcnQgVW5zdWJzY3JpYmUgZnJvbSAnLi9VbnN1YnNjcmliZSc7XG5pbXBvcnQgV2hpdGVMaXN0IGZyb20gJy4vV2hpdGVMaXN0JztcbmltcG9ydCBTdXBwcmVzc2lvbiBmcm9tICcuL1N1cHByZXNzaW9uJztcbmltcG9ydCB7XG4gIElCb3VuY2UsXG4gIElDb21wbGFpbnQsXG4gIElTdXBwcmVzc2lvbkNsaWVudCxcbiAgSVVuc3Vic2NyaWJlLFxuICBJV2hpdGVMaXN0XG59IGZyb20gJy4uLy4uL0ludGVyZmFjZXMvU3VwcHJlc3Npb25zJztcbmltcG9ydCB7XG4gIFN1cHByZXNzaW9uTGlzdCxcbiAgU3VwcHJlc3Npb25MaXN0UmVzcG9uc2UsXG4gIFN1cHByZXNzaW9uRGF0YVR5cGUsXG4gIFN1cHByZXNzaW9uQ3JlYXRpb25EYXRhLFxuICBTdXBwcmVzc2lvbkNyZWF0aW9uUmVzdWx0LFxuICBTdXBwcmVzc2lvbkNyZWF0aW9uUmVzcG9uc2UsXG4gIFN1cHByZXNzaW9uTGlzdFF1ZXJ5LFxuICBTdXBwcmVzc2lvblJlc3BvbnNlLFxuICBTdXBwcmVzc2lvbkRlc3Ryb3lSZXN1bHQsXG4gIFN1cHByZXNzaW9uRGVzdHJveVJlc3BvbnNlXG59IGZyb20gJy4uLy4uL1R5cGVzL1N1cHByZXNzaW9ucyc7XG5pbXBvcnQgeyBBUElFcnJvck9wdGlvbnMgfSBmcm9tICcuLi8uLi9UeXBlcy9Db21tb24nO1xuXG5jb25zdCBjcmVhdGVPcHRpb25zID0ge1xuICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3VwcHJlc3Npb25DbGllbnRcbiAgZXh0ZW5kcyBOYXZpZ2F0aW9uVGhydVBhZ2VzPFN1cHByZXNzaW9uTGlzdD5cbiAgaW1wbGVtZW50cyBJU3VwcHJlc3Npb25DbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuICBtb2RlbHM6IG9iamVjdDtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0KSB7XG4gICAgc3VwZXIocmVxdWVzdCk7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgICB0aGlzLm1vZGVscyA9IHtcbiAgICAgIGJvdW5jZXM6IEJvdW5jZSxcbiAgICAgIGNvbXBsYWludHM6IENvbXBsYWludCxcbiAgICAgIHVuc3Vic2NyaWJlczogVW5zdWJzY3JpYmUsXG4gICAgICB3aGl0ZWxpc3RzOiBXaGl0ZUxpc3QsXG4gICAgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwYXJzZUxpc3QoXG4gICAgcmVzcG9uc2U6IFN1cHByZXNzaW9uTGlzdFJlc3BvbnNlLFxuICAgIE1vZGVsOiB7XG4gICAgICBuZXcoZGF0YTogU3VwcHJlc3Npb25EYXRhVHlwZSk6XG4gICAgICBJQm91bmNlIHwgSUNvbXBsYWludCB8IElVbnN1YnNjcmliZSB8IElXaGl0ZUxpc3RcbiAgICB9XG4gICk6IFN1cHByZXNzaW9uTGlzdCB7XG4gICAgY29uc3QgZGF0YSA9IHt9IGFzIFN1cHByZXNzaW9uTGlzdDtcbiAgICBkYXRhLml0ZW1zID0gcmVzcG9uc2UuYm9keS5pdGVtcz8ubWFwKChpdGVtKSA9PiBuZXcgTW9kZWwoaXRlbSkpIHx8IFtdO1xuXG4gICAgZGF0YS5wYWdlcyA9IHRoaXMucGFyc2VQYWdlTGlua3MocmVzcG9uc2UsICc/JywgJ2FkZHJlc3MnKTtcbiAgICBkYXRhLnN0YXR1cyA9IHJlc3BvbnNlLnN0YXR1cztcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIF9wYXJzZUl0ZW08VCBleHRlbmRzIFN1cHByZXNzaW9uPihcbiAgICBkYXRhIDogU3VwcHJlc3Npb25EYXRhVHlwZSxcbiAgICBNb2RlbDoge1xuICAgICAgbmV3KGRhdGFUeXBlOiBTdXBwcmVzc2lvbkRhdGFUeXBlKTpUXG4gICAgfVxuICApOiBUIHtcbiAgICByZXR1cm4gbmV3IE1vZGVsKGRhdGEpO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVXaGl0ZUxpc3QoXG4gICAgZG9tYWluOiBzdHJpbmcsXG4gICAgZGF0YTogU3VwcHJlc3Npb25DcmVhdGlvbkRhdGEgfCBTdXBwcmVzc2lvbkNyZWF0aW9uRGF0YVtdLFxuICAgIGlzRGF0YUFycmF5OiBib29sZWFuXG4gICk6IFByb21pc2U8U3VwcHJlc3Npb25DcmVhdGlvblJlc3VsdD4ge1xuICAgIGlmIChpc0RhdGFBcnJheSkge1xuICAgICAgdGhyb3cgbmV3IEFQSUVycm9yKHtcbiAgICAgICAgc3RhdHVzOiA0MDAsXG4gICAgICAgIHN0YXR1c1RleHQ6ICdEYXRhIHByb3BlcnR5IHNob3VsZCBiZSBhbiBvYmplY3QnLFxuICAgICAgICBib2R5OiB7XG4gICAgICAgICAgbWVzc2FnZTogJ1doaXRlbGlzdFxcJ3MgY3JlYXRpb24gcHJvY2VzcyBkb2VzIG5vdCBzdXBwb3J0IG11bHRpcGxlIGNyZWF0aW9ucy4gRGF0YSBwcm9wZXJ0eSBzaG91bGQgYmUgYW4gb2JqZWN0J1xuICAgICAgICB9XG4gICAgICB9IGFzIEFQSUVycm9yT3B0aW9ucyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnJlcXVlc3RcbiAgICAgIC5wb3N0V2l0aEZEKHVybGpvaW4oJ3YzJywgZG9tYWluLCAnd2hpdGVsaXN0cycpLCBkYXRhKVxuICAgICAgLnRoZW4odGhpcy5wcmVwYXJlUmVzcG9uc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVVbnN1YnNjcmliZShcbiAgICBkb21haW46IHN0cmluZyxcbiAgICBkYXRhOiBTdXBwcmVzc2lvbkNyZWF0aW9uRGF0YSB8IFN1cHByZXNzaW9uQ3JlYXRpb25EYXRhW11cbiAgKTogUHJvbWlzZTxTdXBwcmVzc2lvbkNyZWF0aW9uUmVzdWx0PiB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHsgLy8gVXNlciBwcm92aWRlZCBhbiBhcnJheVxuICAgICAgY29uc3QgaXNDb250YWluc1RhZyA9IGRhdGEuc29tZSgodW5zdWJzY3JpYmU6IFN1cHByZXNzaW9uQ3JlYXRpb25EYXRhKSA9PiB1bnN1YnNjcmliZS50YWcpO1xuICAgICAgaWYgKGlzQ29udGFpbnNUYWcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEFQSUVycm9yKHtcbiAgICAgICAgICBzdGF0dXM6IDQwMCxcbiAgICAgICAgICBzdGF0dXNUZXh0OiAnVGFnIHByb3BlcnR5IHNob3VsZCBub3QgYmUgdXNlZCBmb3IgY3JlYXRpbmcgbXVsdGlwbGUgdW5zdWJzY3JpYmVzLicsXG4gICAgICAgICAgYm9keToge1xuICAgICAgICAgICAgbWVzc2FnZTogJ1RhZyBwcm9wZXJ0eSBjYW4gYmUgdXNlZCBvbmx5IGlmIG9uZSB1bnN1YnNjcmliZSBwcm92aWRlZCBhcyBzZWNvbmQgYXJndW1lbnQgb2YgY3JlYXRlIG1ldGhvZC4gUGxlYXNlIHVzZSB0YWdzIGluc3RlYWQuJ1xuICAgICAgICAgIH1cbiAgICAgICAgfSBhcyBBUElFcnJvck9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdFxuICAgICAgICAucG9zdCh1cmxqb2luKCd2MycsIGRvbWFpbiwgJ3Vuc3Vic2NyaWJlcycpLCBKU09OLnN0cmluZ2lmeShkYXRhKSwgY3JlYXRlT3B0aW9ucylcbiAgICAgICAgLnRoZW4odGhpcy5wcmVwYXJlUmVzcG9uc2UpO1xuICAgIH1cblxuICAgIGlmIChkYXRhPy50YWdzKSB7XG4gICAgICB0aHJvdyBuZXcgQVBJRXJyb3Ioe1xuICAgICAgICBzdGF0dXM6IDQwMCxcbiAgICAgICAgc3RhdHVzVGV4dDogJ1RhZ3MgcHJvcGVydHkgc2hvdWxkIG5vdCBiZSB1c2VkIGZvciBjcmVhdGluZyBvbmUgdW5zdWJzY3JpYmUuJyxcbiAgICAgICAgYm9keToge1xuICAgICAgICAgIG1lc3NhZ2U6ICdUYWdzIHByb3BlcnR5IGNhbiBiZSB1c2VkIGlmIHlvdSBwcm92aWRlcyBhbiBhcnJheSBvZiB1bnN1YnNjcmliZXMgYXMgc2Vjb25kIGFyZ3VtZW50IG9mIGNyZWF0ZSBtZXRob2QuIFBsZWFzZSB1c2UgdGFnIGluc3RlYWQnXG4gICAgICAgIH1cbiAgICAgIH0gYXMgQVBJRXJyb3JPcHRpb25zKTtcbiAgICB9XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YS50YWcpKSB7XG4gICAgICB0aHJvdyBuZXcgQVBJRXJyb3Ioe1xuICAgICAgICBzdGF0dXM6IDQwMCxcbiAgICAgICAgc3RhdHVzVGV4dDogJ1RhZyBwcm9wZXJ0eSBjYW4gbm90IGJlIGFuIGFycmF5JyxcbiAgICAgICAgYm9keToge1xuICAgICAgICAgIG1lc3NhZ2U6ICdQbGVhc2UgdXNlIGFycmF5IG9mIHVuc3Vic2NyaWJlcyBhcyBzZWNvbmQgYXJndW1lbnQgb2YgY3JlYXRlIG1ldGhvZCB0byBiZSBhYmxlIHRvIHByb3ZpZGUgZmV3IHRhZ3MnXG4gICAgICAgIH1cbiAgICAgIH0gYXMgQVBJRXJyb3JPcHRpb25zKTtcbiAgICB9XG4gICAgLyogV2UgbmVlZCBGb3JtIERhdGEgZm9yIHVuc3Vic2NyaWJlcyBpZiB3ZSB3YW50IHRvIHN1cHBvcnQgdGhlIFwidGFnXCIgcHJvcGVydHkgKi9cbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0XG4gICAgICAucG9zdFdpdGhGRCh1cmxqb2luKCd2MycsIGRvbWFpbiwgJ3Vuc3Vic2NyaWJlcycpLCBkYXRhKVxuICAgICAgLnRoZW4odGhpcy5wcmVwYXJlUmVzcG9uc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRNb2RlbCh0eXBlOiBzdHJpbmcpIHtcbiAgICBpZiAodHlwZSBpbiB0aGlzLm1vZGVscykge1xuICAgICAgcmV0dXJuIHRoaXMubW9kZWxzW3R5cGUgYXMga2V5b2YgdHlwZW9mIHRoaXMubW9kZWxzXTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEFQSUVycm9yKHtcbiAgICAgIHN0YXR1czogNDAwLFxuICAgICAgc3RhdHVzVGV4dDogJ1Vua25vd24gdHlwZSB2YWx1ZScsXG4gICAgICBib2R5OiB7IG1lc3NhZ2U6ICdUeXBlIG1heSBiZSBvbmx5IG9uZSBvZiBbYm91bmNlcywgY29tcGxhaW50cywgdW5zdWJzY3JpYmVzLCB3aGl0ZWxpc3RzXScgfVxuICAgIH0gYXMgQVBJRXJyb3JPcHRpb25zKTtcbiAgfVxuXG4gIHByaXZhdGUgcHJlcGFyZVJlc3BvbnNlKHJlc3BvbnNlOiBTdXBwcmVzc2lvbkNyZWF0aW9uUmVzcG9uc2UpOiBTdXBwcmVzc2lvbkNyZWF0aW9uUmVzdWx0IHtcbiAgICByZXR1cm4ge1xuICAgICAgbWVzc2FnZTogcmVzcG9uc2UuYm9keS5tZXNzYWdlLFxuICAgICAgdHlwZTogcmVzcG9uc2UuYm9keS50eXBlIHx8ICcnLFxuICAgICAgdmFsdWU6IHJlc3BvbnNlLmJvZHkudmFsdWUgfHwgJycsXG4gICAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1c1xuICAgIH07XG4gIH1cblxuICBhc3luYyBsaXN0KFxuICAgIGRvbWFpbjogc3RyaW5nLFxuICAgIHR5cGU6IHN0cmluZyxcbiAgICBxdWVyeT86IFN1cHByZXNzaW9uTGlzdFF1ZXJ5XG4gICk6IFByb21pc2U8U3VwcHJlc3Npb25MaXN0PiB7XG4gICAgY29uc3QgbW9kZWwgPSB0aGlzLmdldE1vZGVsKHR5cGUpO1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3RMaXN0V2l0aFBhZ2VzKHVybGpvaW4oJ3YzJywgZG9tYWluLCB0eXBlKSwgcXVlcnksIG1vZGVsKTtcbiAgfVxuXG4gIGdldChcbiAgICBkb21haW46IHN0cmluZyxcbiAgICB0eXBlOiBzdHJpbmcsXG4gICAgYWRkcmVzczogc3RyaW5nXG4gICk6IFByb21pc2U8SUJvdW5jZSB8IElDb21wbGFpbnQgfCBJVW5zdWJzY3JpYmUgfCBJV2hpdGVMaXN0PiB7XG4gICAgY29uc3QgbW9kZWwgPSB0aGlzLmdldE1vZGVsKHR5cGUpO1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3RcbiAgICAgIC5nZXQodXJsam9pbigndjMnLCBkb21haW4sIHR5cGUsIGVuY29kZVVSSUNvbXBvbmVudChhZGRyZXNzKSkpXG4gICAgICAudGhlbigocmVzcG9uc2U6IFN1cHByZXNzaW9uUmVzcG9uc2UpID0+IHRoaXMuX3BhcnNlSXRlbTx0eXBlb2YgbW9kZWw+KHJlc3BvbnNlLmJvZHksIG1vZGVsKSk7XG4gIH1cblxuICBjcmVhdGUoXG4gICAgZG9tYWluOiBzdHJpbmcsXG4gICAgdHlwZTogc3RyaW5nLFxuICAgIGRhdGE6IFN1cHByZXNzaW9uQ3JlYXRpb25EYXRhIHwgU3VwcHJlc3Npb25DcmVhdGlvbkRhdGFbXVxuICApOiBQcm9taXNlPFN1cHByZXNzaW9uQ3JlYXRpb25SZXN1bHQ+IHtcbiAgICB0aGlzLmdldE1vZGVsKHR5cGUpO1xuICAgIC8vIHN1cHBvcnRzIGFkZGluZyBtdWx0aXBsZSBzdXBwcmVzc2lvbnMgYnkgZGVmYXVsdFxuICAgIGxldCBwb3N0RGF0YTtcbiAgICBjb25zdCBpc0RhdGFBcnJheSA9IEFycmF5LmlzQXJyYXkoZGF0YSk7XG5cbiAgICBpZiAodHlwZSA9PT0gJ3doaXRlbGlzdHMnKSB7XG4gICAgICByZXR1cm4gdGhpcy5jcmVhdGVXaGl0ZUxpc3QoZG9tYWluLCBkYXRhLCBpc0RhdGFBcnJheSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGUgPT09ICd1bnN1YnNjcmliZXMnKSB7XG4gICAgICByZXR1cm4gdGhpcy5jcmVhdGVVbnN1YnNjcmliZShkb21haW4sIGRhdGEpO1xuICAgIH1cblxuICAgIGlmICghaXNEYXRhQXJyYXkpIHtcbiAgICAgIHBvc3REYXRhID0gW2RhdGFdO1xuICAgIH0gZWxzZSB7XG4gICAgICBwb3N0RGF0YSA9IFsuLi5kYXRhXTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0XG4gICAgICAucG9zdCh1cmxqb2luKCd2MycsIGRvbWFpbiwgdHlwZSksIEpTT04uc3RyaW5naWZ5KHBvc3REYXRhKSwgY3JlYXRlT3B0aW9ucylcbiAgICAgIC50aGVuKHRoaXMucHJlcGFyZVJlc3BvbnNlKTtcbiAgfVxuXG4gIGRlc3Ryb3koXG4gICAgZG9tYWluOiBzdHJpbmcsXG4gICAgdHlwZTogc3RyaW5nLFxuICAgIGFkZHJlc3M6IHN0cmluZ1xuICApOiBQcm9taXNlPFN1cHByZXNzaW9uRGVzdHJveVJlc3VsdD4ge1xuICAgIHRoaXMuZ2V0TW9kZWwodHlwZSk7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdFxuICAgICAgLmRlbGV0ZSh1cmxqb2luKCd2MycsIGRvbWFpbiwgdHlwZSwgZW5jb2RlVVJJQ29tcG9uZW50KGFkZHJlc3MpKSlcbiAgICAgIC50aGVuKChyZXNwb25zZTogU3VwcHJlc3Npb25EZXN0cm95UmVzcG9uc2UpID0+ICh7XG4gICAgICAgIG1lc3NhZ2U6IHJlc3BvbnNlLmJvZHkubWVzc2FnZSxcbiAgICAgICAgdmFsdWU6IHJlc3BvbnNlLmJvZHkudmFsdWUgfHwgJycsXG4gICAgICAgIGFkZHJlc3M6IHJlc3BvbnNlLmJvZHkuYWRkcmVzcyB8fCAnJyxcbiAgICAgICAgc3RhdHVzOiByZXNwb25zZS5zdGF0dXNcbiAgICAgIH0pKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFN1cHByZXNzaW9uQ2xpZW50O1xuIiwiaW1wb3J0IHsgU3VwcHJlc3Npb25Nb2RlbHMgfSBmcm9tICcuLi8uLi9FbnVtcyc7XG5pbXBvcnQgeyBJVW5zdWJzY3JpYmUgfSBmcm9tICcuLi8uLi9JbnRlcmZhY2VzL1N1cHByZXNzaW9ucyc7XG5pbXBvcnQgeyBVbnN1YnNjcmliZURhdGEgfSBmcm9tICcuLi8uLi9UeXBlcy9TdXBwcmVzc2lvbnMnO1xuXG5pbXBvcnQgU3VwcHJlc3Npb24gZnJvbSAnLi9TdXBwcmVzc2lvbic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFVuc3Vic2NyaWJlIGV4dGVuZHMgU3VwcHJlc3Npb24gaW1wbGVtZW50cyBJVW5zdWJzY3JpYmUge1xuICAgIGFkZHJlc3M6IHN0cmluZztcbiAgICB0YWdzOiBzdHJpbmdbXTtcbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbiAgICBjcmVhdGVkX2F0OiBEYXRlO1xuXG4gICAgY29uc3RydWN0b3IoZGF0YTogVW5zdWJzY3JpYmVEYXRhKSB7XG4gICAgICBzdXBlcihTdXBwcmVzc2lvbk1vZGVscy5VTlNVQlNDUklCRVMpO1xuICAgICAgdGhpcy5hZGRyZXNzID0gZGF0YS5hZGRyZXNzO1xuICAgICAgdGhpcy50YWdzID0gZGF0YS50YWdzO1xuICAgICAgdGhpcy5jcmVhdGVkX2F0ID0gbmV3IERhdGUoZGF0YS5jcmVhdGVkX2F0KTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBTdXBwcmVzc2lvbk1vZGVscyB9IGZyb20gJy4uLy4uL0VudW1zJztcbmltcG9ydCB7IElXaGl0ZUxpc3QgfSBmcm9tICcuLi8uLi9JbnRlcmZhY2VzL1N1cHByZXNzaW9ucyc7XG5pbXBvcnQgeyBXaGl0ZUxpc3REYXRhIH0gZnJvbSAnLi4vLi4vVHlwZXMvU3VwcHJlc3Npb25zJztcbmltcG9ydCBTdXBwcmVzc2lvbiBmcm9tICcuL1N1cHByZXNzaW9uJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgV2hpdGVMaXN0IGV4dGVuZHMgU3VwcHJlc3Npb24gaW1wbGVtZW50cyBJV2hpdGVMaXN0IHtcbiAgICB2YWx1ZTogc3RyaW5nO1xuICAgIHJlYXNvbjogc3RyaW5nO1xuICAgIGNyZWF0ZWRBdDogRGF0ZTtcblxuICAgIGNvbnN0cnVjdG9yKGRhdGE6IFdoaXRlTGlzdERhdGEpIHtcbiAgICAgIHN1cGVyKFN1cHByZXNzaW9uTW9kZWxzLldISVRFTElTVFMpO1xuICAgICAgdGhpcy52YWx1ZSA9IGRhdGEudmFsdWU7XG4gICAgICB0aGlzLnJlYXNvbiA9IGRhdGEucmVhc29uO1xuICAgICAgdGhpcy5jcmVhdGVkQXQgPSBuZXcgRGF0ZShkYXRhLmNyZWF0ZWRBdCk7XG4gICAgfVxufVxuIiwiaW1wb3J0IE5hdmlnYXRpb25UaHJ1UGFnZXMgZnJvbSAnLi4vY29tbW9uL05hdmlnYXRpb25UaHJ1UGFnZXMnO1xuaW1wb3J0IHsgQVBJUmVzcG9uc2UgfSBmcm9tICcuLi8uLi9UeXBlcy9Db21tb24vQXBpUmVzcG9uc2UnO1xuXG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuLi9jb21tb24vUmVxdWVzdCc7XG5pbXBvcnQgeyBJTXVsdGlwbGVWYWxpZGF0aW9uQ2xpZW50IH0gZnJvbSAnLi4vLi4vSW50ZXJmYWNlcy9WYWxpZGF0aW9ucyc7XG5pbXBvcnQge1xuICBNdWx0aXBsZVZhbGlkYXRpb25Kb2JSZXN1bHQsXG4gIE11bHRpcGxlVmFsaWRhdGlvbkpvYkRhdGEsXG4gIE11bHRpcGxlVmFsaWRhdGlvbkpvYnNMaXN0UmVzdWx0LFxuICBNdWx0aXBsZVZhbGlkYXRpb25Kb2JzTGlzdFJlc3BvbnNlLFxuICBNdWx0aXBsZVZhbGlkYXRpb25Kb2JzTGlzdFF1ZXJ5LFxuICBNdWx0aXBsZVZhbGlkYXRpb25DcmVhdGlvbkRhdGEsXG4gIENyZWF0ZWRNdWx0aXBsZVZhbGlkYXRpb25Kb2IsXG4gIE11bHRpcGxlVmFsaWRhdGlvbkNyZWF0aW9uRGF0YVVwZGF0ZWQsXG4gIENhbmNlbGVkTXVsdGlwbGVWYWxpZGF0aW9uSm9iXG59IGZyb20gJy4uLy4uL1R5cGVzL1ZhbGlkYXRpb25zL011bHRpcGxlVmFsaWRhdGlvbic7XG5cbmV4cG9ydCBjbGFzcyBNdWx0aXBsZVZhbGlkYXRpb25Kb2IgaW1wbGVtZW50cyBNdWx0aXBsZVZhbGlkYXRpb25Kb2JSZXN1bHQge1xuICBjcmVhdGVkQXQ6IERhdGU7XG4gIGlkOiBzdHJpbmc7XG4gIHF1YW50aXR5OiBudW1iZXJcbiAgcmVjb3Jkc1Byb2Nlc3NlZDogbnVtYmVyIHwgbnVsbDtcbiAgc3RhdHVzOiBzdHJpbmc7XG4gIGRvd25sb2FkVXJsPzoge1xuICAgIGNzdjogc3RyaW5nO1xuICAgIGpzb246IHN0cmluZztcbiAgfTtcblxuICByZXNwb25zZVN0YXR1c0NvZGU6IG51bWJlcjtcbiAgc3VtbWFyeT86IHtcbiAgICAgIHJlc3VsdDoge1xuICAgICAgICAgIGNhdGNoQWxsOiBudW1iZXI7XG4gICAgICAgICAgZGVsaXZlcmFibGU6IG51bWJlcjtcbiAgICAgICAgICBkb05vdFNlbmQ6IG51bWJlcjtcbiAgICAgICAgICB1bmRlbGl2ZXJhYmxlOiBudW1iZXI7XG4gICAgICAgICAgdW5rbm93bjogbnVtYmVyO1xuICAgICAgfTtcbiAgICAgIHJpc2s6IHtcbiAgICAgICAgICBoaWdoOiBudW1iZXI7XG4gICAgICAgICAgbG93OiBudW1iZXI7XG4gICAgICAgICAgbWVkaXVtOiBudW1iZXI7XG4gICAgICAgICAgdW5rbm93bjogbnVtYmVyO1xuICAgICAgfVxuICB9XG5cbiAgY29uc3RydWN0b3IoZGF0YTogTXVsdGlwbGVWYWxpZGF0aW9uSm9iRGF0YSwgcmVzcG9uc2VTdGF0dXNDb2RlOiBudW1iZXIpIHtcbiAgICB0aGlzLmNyZWF0ZWRBdCA9IG5ldyBEYXRlKGRhdGEuY3JlYXRlZF9hdCk7XG4gICAgdGhpcy5pZCA9IGRhdGEuaWQ7XG4gICAgdGhpcy5xdWFudGl0eSA9IGRhdGEucXVhbnRpdHk7XG4gICAgdGhpcy5yZWNvcmRzUHJvY2Vzc2VkID0gZGF0YS5yZWNvcmRzX3Byb2Nlc3NlZDtcbiAgICB0aGlzLnN0YXR1cyA9IGRhdGEuc3RhdHVzO1xuICAgIHRoaXMucmVzcG9uc2VTdGF0dXNDb2RlID0gcmVzcG9uc2VTdGF0dXNDb2RlO1xuICAgIGlmIChkYXRhLmRvd25sb2FkX3VybCkge1xuICAgICAgdGhpcy5kb3dubG9hZFVybCA9IHtcbiAgICAgICAgY3N2OiBkYXRhLmRvd25sb2FkX3VybD8uY3N2LFxuICAgICAgICBqc29uOiBkYXRhLmRvd25sb2FkX3VybD8uanNvblxuICAgICAgfTtcbiAgICB9XG4gICAgaWYgKGRhdGEuc3VtbWFyeSkge1xuICAgICAgdGhpcy5zdW1tYXJ5ID0ge1xuICAgICAgICByZXN1bHQ6IHtcbiAgICAgICAgICBjYXRjaEFsbDogZGF0YS5zdW1tYXJ5LnJlc3VsdC5jYXRjaF9hbGwsXG4gICAgICAgICAgZGVsaXZlcmFibGU6IGRhdGEuc3VtbWFyeS5yZXN1bHQuZGVsaXZlcmFibGUsXG4gICAgICAgICAgZG9Ob3RTZW5kOiBkYXRhLnN1bW1hcnkucmVzdWx0LmRvX25vdF9zZW5kLFxuICAgICAgICAgIHVuZGVsaXZlcmFibGU6IGRhdGEuc3VtbWFyeS5yZXN1bHQudW5kZWxpdmVyYWJsZSxcbiAgICAgICAgICB1bmtub3duOiBkYXRhLnN1bW1hcnkucmVzdWx0LnVua25vd25cbiAgICAgICAgfSxcbiAgICAgICAgcmlzazoge1xuICAgICAgICAgIGhpZ2g6IGRhdGEuc3VtbWFyeS5yaXNrLmhpZ2gsXG4gICAgICAgICAgbG93OiBkYXRhLnN1bW1hcnkucmlzay5sb3csXG4gICAgICAgICAgbWVkaXVtOiBkYXRhLnN1bW1hcnkucmlzay5tZWRpdW0sXG4gICAgICAgICAgdW5rbm93bjogZGF0YS5zdW1tYXJ5LnJpc2sudW5rbm93blxuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNdWx0aXBsZVZhbGlkYXRpb25DbGllbnRcbiAgZXh0ZW5kcyBOYXZpZ2F0aW9uVGhydVBhZ2VzPE11bHRpcGxlVmFsaWRhdGlvbkpvYnNMaXN0UmVzdWx0PlxuICBpbXBsZW1lbnRzIElNdWx0aXBsZVZhbGlkYXRpb25DbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVJlc3BvbnNlPFQ+KHJlc3BvbnNlOiBBUElSZXNwb25zZSk6IFQge1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgIC4uLnJlc3BvbnNlPy5ib2R5XG4gICAgfSBhcyBUO1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlTGlzdChyZXNwb25zZTogTXVsdGlwbGVWYWxpZGF0aW9uSm9ic0xpc3RSZXNwb25zZSlcbiAgICA6IE11bHRpcGxlVmFsaWRhdGlvbkpvYnNMaXN0UmVzdWx0IHtcbiAgICBjb25zdCBkYXRhID0ge30gYXMgTXVsdGlwbGVWYWxpZGF0aW9uSm9ic0xpc3RSZXN1bHQ7XG5cbiAgICBkYXRhLmpvYnMgPSByZXNwb25zZS5ib2R5LmpvYnMubWFwKChqb2IpID0+IG5ldyBNdWx0aXBsZVZhbGlkYXRpb25Kb2Ioam9iLCByZXNwb25zZS5zdGF0dXMpKTtcblxuICAgIGRhdGEucGFnZXMgPSB0aGlzLnBhcnNlUGFnZUxpbmtzKHJlc3BvbnNlLCAnPycsICdwaXZvdCcpO1xuICAgIGRhdGEudG90YWwgPSByZXNwb25zZS5ib2R5LnRvdGFsO1xuICAgIGRhdGEuc3RhdHVzID0gcmVzcG9uc2Uuc3RhdHVzO1xuXG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBhc3luYyBsaXN0KHF1ZXJ5PzogTXVsdGlwbGVWYWxpZGF0aW9uSm9ic0xpc3RRdWVyeSk6IFByb21pc2U8TXVsdGlwbGVWYWxpZGF0aW9uSm9ic0xpc3RSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0TGlzdFdpdGhQYWdlcygnL3Y0L2FkZHJlc3MvdmFsaWRhdGUvYnVsaycsIHF1ZXJ5KTtcbiAgfVxuXG4gIGFzeW5jIGdldChsaXN0SWQ6IHN0cmluZyk6IFByb21pc2U8TXVsdGlwbGVWYWxpZGF0aW9uSm9iPiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnJlcXVlc3QuZ2V0KGAvdjQvYWRkcmVzcy92YWxpZGF0ZS9idWxrLyR7bGlzdElkfWApO1xuICAgIHJldHVybiBuZXcgTXVsdGlwbGVWYWxpZGF0aW9uSm9iKHJlc3BvbnNlLmJvZHksIHJlc3BvbnNlLnN0YXR1cyk7XG4gIH1cblxuICBhc3luYyBjcmVhdGUoXG4gICAgbGlzdElkOiBzdHJpbmcsXG4gICAgZGF0YTogTXVsdGlwbGVWYWxpZGF0aW9uQ3JlYXRpb25EYXRhXG4gICk6IFByb21pc2U8Q3JlYXRlZE11bHRpcGxlVmFsaWRhdGlvbkpvYj4ge1xuICAgIGNvbnN0IG11bHRpcGxlVmFsaWRhdGlvbkRhdGE6IE11bHRpcGxlVmFsaWRhdGlvbkNyZWF0aW9uRGF0YVVwZGF0ZWQgPSB7XG4gICAgICBtdWx0aXBsZVZhbGlkYXRpb25GaWxlOiB7XG4gICAgICAgIC4uLmRhdGE/LmZpbGVcbiAgICAgIH0sXG4gICAgICAuLi5kYXRhXG4gICAgfTtcbiAgICBkZWxldGUgbXVsdGlwbGVWYWxpZGF0aW9uRGF0YS5maWxlO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQoYC92NC9hZGRyZXNzL3ZhbGlkYXRlL2J1bGsvJHtsaXN0SWR9YCwgbXVsdGlwbGVWYWxpZGF0aW9uRGF0YSk7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlUmVzcG9uc2U8Q3JlYXRlZE11bHRpcGxlVmFsaWRhdGlvbkpvYj4ocmVzcG9uc2UpO1xuICB9XG5cbiAgYXN5bmMgZGVzdHJveShsaXN0SWQ6IHN0cmluZyk6IFByb21pc2U8Q2FuY2VsZWRNdWx0aXBsZVZhbGlkYXRpb25Kb2I+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucmVxdWVzdC5kZWxldGUoYC92NC9hZGRyZXNzL3ZhbGlkYXRlL2J1bGsvJHtsaXN0SWR9YCk7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlUmVzcG9uc2U8Q2FuY2VsZWRNdWx0aXBsZVZhbGlkYXRpb25Kb2I+KHJlc3BvbnNlKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgSVZhbGlkYXRpb25DbGllbnQsIElNdWx0aXBsZVZhbGlkYXRpb25DbGllbnQgfSBmcm9tICcuLi8uLi9JbnRlcmZhY2VzL1ZhbGlkYXRpb25zJztcbmltcG9ydCB7IFZhbGlkYXRpb25RdWVyeSwgVmFsaWRhdGlvblJlc3VsdCwgVmFsaWRhdGlvblJlc3BvbnNlIH0gZnJvbSAnLi4vLi4vVHlwZXMvVmFsaWRhdGlvbnMnO1xuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi4vY29tbW9uL1JlcXVlc3QnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWYWxpZGF0ZUNsaWVudCBpbXBsZW1lbnRzIElWYWxpZGF0aW9uQ2xpZW50IHtcbiAgcHVibGljIG11bHRpcGxlVmFsaWRhdGlvbjtcbiAgcmVxdWVzdDogUmVxdWVzdDtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0LCBtdWx0aXBsZVZhbGlkYXRpb25DbGllbnQ6IElNdWx0aXBsZVZhbGlkYXRpb25DbGllbnQpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICAgIHRoaXMubXVsdGlwbGVWYWxpZGF0aW9uID0gbXVsdGlwbGVWYWxpZGF0aW9uQ2xpZW50O1xuICB9XG5cbiAgYXN5bmMgZ2V0KGFkZHJlc3M6IHN0cmluZyk6IFByb21pc2U8VmFsaWRhdGlvblJlc3VsdD4ge1xuICAgIGNvbnN0IHF1ZXJ5OiBWYWxpZGF0aW9uUXVlcnkgPSB7IGFkZHJlc3MgfTtcbiAgICBjb25zdCByZXN1bHQ6IFZhbGlkYXRpb25SZXNwb25zZSA9IGF3YWl0IHRoaXMucmVxdWVzdC5nZXQoJy92NC9hZGRyZXNzL3ZhbGlkYXRlJywgcXVlcnkpO1xuICAgIHJldHVybiByZXN1bHQuYm9keSBhcyBWYWxpZGF0aW9uUmVzdWx0O1xuICB9XG59XG4iLCJpbXBvcnQgdXJsam9pbiBmcm9tICd1cmwtam9pbic7XG5pbXBvcnQgeyBXZWJob29rc0lkcyB9IGZyb20gJy4uL0VudW1zJztcbmltcG9ydCB7IElXZWJIb29rc0NsaWVudCB9IGZyb20gJy4uL0ludGVyZmFjZXMvV2ViaG9va3MnO1xuXG5pbXBvcnQge1xuICBXZWJob29rVmFsaWRhdGlvblJlc3BvbnNlLFxuICBXZWJob29rTGlzdCxcbiAgV2ViaG9va1Jlc3BvbnNlLFxuICBXZWJob29rc1F1ZXJ5LFxuICBXZWJob29rUmVzdWx0XG59IGZyb20gJy4uL1R5cGVzL1dlYmhvb2tzJztcbmltcG9ydCBSZXF1ZXN0IGZyb20gJy4vY29tbW9uL1JlcXVlc3QnO1xuXG5leHBvcnQgY2xhc3MgV2ViaG9vayBpbXBsZW1lbnRzIFdlYmhvb2tSZXN1bHQge1xuICBpZDogc3RyaW5nO1xuICB1cmw6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgdXJsczogc3RyaW5nW107XG5cbiAgY29uc3RydWN0b3IoaWQ6IHN0cmluZywgdXJsOiBzdHJpbmcgfCB1bmRlZmluZWQsIHVybHM6IHN0cmluZ1tdKSB7XG4gICAgdGhpcy5pZCA9IGlkO1xuICAgIHRoaXMudXJsID0gdXJsO1xuICAgIHRoaXMudXJscyA9IHVybHM7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgV2ViaG9va3NDbGllbnQgaW1wbGVtZW50cyBJV2ViSG9va3NDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICB9XG5cbiAgcHJpdmF0ZSBfcGFyc2VXZWJob29rTGlzdChyZXNwb25zZTogeyBib2R5OiB7IHdlYmhvb2tzOiBXZWJob29rTGlzdCB9IH0pOiBXZWJob29rTGlzdCB7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmJvZHkud2ViaG9va3M7XG4gIH1cblxuICBfcGFyc2VXZWJob29rV2l0aElEKGlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHJlc3BvbnNlOiBXZWJob29rUmVzcG9uc2UpOiBXZWJob29rUmVzdWx0IHtcbiAgICAgIGNvbnN0IHdlYmhvb2tSZXNwb25zZSA9IHJlc3BvbnNlPy5ib2R5Py53ZWJob29rO1xuICAgICAgbGV0IHVybCA9IHdlYmhvb2tSZXNwb25zZT8udXJsO1xuICAgICAgbGV0IHVybHMgPSB3ZWJob29rUmVzcG9uc2U/LnVybHM7XG4gICAgICBpZiAoIXVybCkge1xuICAgICAgICB1cmwgPSB1cmxzICYmIHVybHMubGVuZ3RoXG4gICAgICAgICAgPyB1cmxzWzBdXG4gICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBpZiAoKCF1cmxzIHx8IHVybHMubGVuZ3RoID09PSAwKSAmJiB1cmwpIHtcbiAgICAgICAgdXJscyA9IFt1cmxdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBXZWJob29rKGlkLCB1cmwsIHVybHMgYXMgc3RyaW5nW10pO1xuICAgIH07XG4gIH1cblxuICBwcml2YXRlIF9wYXJzZVdlYmhvb2tUZXN0KHJlc3BvbnNlOiB7IGJvZHk6IHsgY29kZTogbnVtYmVyLCBtZXNzYWdlOiBzdHJpbmcgfSB9KVxuICA6IHtjb2RlOiBudW1iZXIsIG1lc3NhZ2U6c3RyaW5nfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvZGU6IHJlc3BvbnNlLmJvZHkuY29kZSxcbiAgICAgIG1lc3NhZ2U6IHJlc3BvbnNlLmJvZHkubWVzc2FnZVxuICAgIH0gYXMgV2ViaG9va1ZhbGlkYXRpb25SZXNwb25zZTtcbiAgfVxuXG4gIGxpc3QoZG9tYWluOiBzdHJpbmcsIHF1ZXJ5OiBXZWJob29rc1F1ZXJ5KTogUHJvbWlzZTxXZWJob29rTGlzdD4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybGpvaW4oJy92My9kb21haW5zJywgZG9tYWluLCAnd2ViaG9va3MnKSwgcXVlcnkpXG4gICAgICAudGhlbih0aGlzLl9wYXJzZVdlYmhvb2tMaXN0KTtcbiAgfVxuXG4gIGdldChkb21haW46IHN0cmluZywgaWQ6IFdlYmhvb2tzSWRzKTogUHJvbWlzZTxXZWJob29rUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQodXJsam9pbignL3YzL2RvbWFpbnMnLCBkb21haW4sICd3ZWJob29rcycsIGlkKSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlV2ViaG9va1dpdGhJRChpZCkpO1xuICB9XG5cbiAgY3JlYXRlKGRvbWFpbjogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcsXG4gICAgdXJsOiBzdHJpbmcsXG4gICAgdGVzdCA9IGZhbHNlKTogUHJvbWlzZTxXZWJob29rUmVzdWx0IHwgV2ViaG9va1ZhbGlkYXRpb25SZXNwb25zZT4ge1xuICAgIGlmICh0ZXN0KSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnB1dFdpdGhGRCh1cmxqb2luKCcvdjMvZG9tYWlucycsIGRvbWFpbiwgJ3dlYmhvb2tzJywgaWQsICd0ZXN0JyksIHsgdXJsIH0pXG4gICAgICAgIC50aGVuKHRoaXMuX3BhcnNlV2ViaG9va1Rlc3QpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRCh1cmxqb2luKCcvdjMvZG9tYWlucycsIGRvbWFpbiwgJ3dlYmhvb2tzJyksIHsgaWQsIHVybCB9KVxuICAgICAgLnRoZW4odGhpcy5fcGFyc2VXZWJob29rV2l0aElEKGlkKSk7XG4gIH1cblxuICB1cGRhdGUoZG9tYWluOiBzdHJpbmcsIGlkOiBzdHJpbmcsIHVybFZhbHVlczogc3RyaW5nIHwgc3RyaW5nW10pOiBQcm9taXNlPFdlYmhvb2tSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnB1dFdpdGhGRCh1cmxqb2luKCcvdjMvZG9tYWlucycsIGRvbWFpbiwgJ3dlYmhvb2tzJywgaWQpLCB7IHVybDogdXJsVmFsdWVzIH0pXG4gICAgICAudGhlbih0aGlzLl9wYXJzZVdlYmhvb2tXaXRoSUQoaWQpKTtcbiAgfVxuXG4gIGRlc3Ryb3koZG9tYWluOiBzdHJpbmcsIGlkOiBzdHJpbmcpIDogUHJvbWlzZTxXZWJob29rUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUodXJsam9pbignL3YzL2RvbWFpbnMnLCBkb21haW4sICd3ZWJob29rcycsIGlkKSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlV2ViaG9va1dpdGhJRChpZCkpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBBUElFcnJvck9wdGlvbnMsIEFQSUVycm9yVHlwZSB9IGZyb20gJy4uLy4uL1R5cGVzL0NvbW1vbic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFQSUVycm9yIGV4dGVuZHMgRXJyb3IgaW1wbGVtZW50cyBBUElFcnJvclR5cGUge1xuICBwdWJsaWMgc3RhdHVzOiBudW1iZXIgO1xuICBwdWJsaWMgc3RhY2s6IHN0cmluZztcbiAgcHVibGljIGRldGFpbHM6IHN0cmluZztcbiAgcHVibGljIHR5cGU6IHN0cmluZztcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgc3RhdHVzLFxuICAgIHN0YXR1c1RleHQsXG4gICAgbWVzc2FnZSxcbiAgICBib2R5ID0ge31cbiAgfTogQVBJRXJyb3JPcHRpb25zKSB7XG4gICAgbGV0IGJvZHlNZXNzYWdlID0gJyc7XG4gICAgbGV0IGVycm9yID0gJyc7XG4gICAgaWYgKHR5cGVvZiBib2R5ID09PSAnc3RyaW5nJykge1xuICAgICAgYm9keU1lc3NhZ2UgPSBib2R5O1xuICAgIH0gZWxzZSB7XG4gICAgICBib2R5TWVzc2FnZSA9IGJvZHk/Lm1lc3NhZ2UgfHwgJyc7XG4gICAgICBlcnJvciA9IGJvZHk/LmVycm9yIHx8ICcnO1xuICAgIH1cbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5zdGFjayA9ICcnO1xuICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzO1xuICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2UgfHwgZXJyb3IgfHwgc3RhdHVzVGV4dCB8fCAnJztcbiAgICB0aGlzLmRldGFpbHMgPSBib2R5TWVzc2FnZTtcbiAgICB0aGlzLnR5cGUgPSAnTWFpbGd1bkFQSUVycm9yJztcbiAgfVxufVxuIiwiaW1wb3J0ICogYXMgTm9kZUZvcm1EYXRhIGZyb20gJ2Zvcm0tZGF0YSc7XG5pbXBvcnQgeyBBUElFcnJvck9wdGlvbnMsIElucHV0Rm9ybURhdGEgfSBmcm9tICcuLi8uLi9UeXBlcy9Db21tb24nO1xuaW1wb3J0IEFQSUVycm9yIGZyb20gJy4vRXJyb3InO1xuXG5jbGFzcyBGb3JtRGF0YUJ1aWxkZXIge1xuICBwcml2YXRlIEZvcm1EYXRhQ29uc3RydWN0b3I6IElucHV0Rm9ybURhdGE7XG4gIGNvbnN0cnVjdG9yKEZvcm1EYXRhQ29uc3RydWN0b3I6IElucHV0Rm9ybURhdGEpIHtcbiAgICB0aGlzLkZvcm1EYXRhQ29uc3RydWN0b3IgPSBGb3JtRGF0YUNvbnN0cnVjdG9yO1xuICB9XG5cbiAgcHVibGljIGNyZWF0ZUZvcm1EYXRhKGRhdGE6IGFueSk6IE5vZGVGb3JtRGF0YSB8IEZvcm1EYXRhIHtcbiAgICBpZiAoIWRhdGEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGxlYXNlIHByb3ZpZGUgZGF0YSBvYmplY3QnKTtcbiAgICB9XG4gICAgY29uc3QgZm9ybURhdGE6IE5vZGVGb3JtRGF0YSB8IEZvcm1EYXRhID0gT2JqZWN0LmtleXMoZGF0YSlcbiAgICAgIC5maWx0ZXIoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gZGF0YVtrZXldOyB9KVxuICAgICAgLnJlZHVjZSgoZm9ybURhdGFBY2M6IE5vZGVGb3JtRGF0YSB8IEZvcm1EYXRhLCBrZXkpID0+IHtcbiAgICAgICAgY29uc3QgZmlsZUtleXMgPSBbJ2F0dGFjaG1lbnQnLCAnaW5saW5lJywgJ211bHRpcGxlVmFsaWRhdGlvbkZpbGUnXTtcbiAgICAgICAgaWYgKGZpbGVLZXlzLmluY2x1ZGVzKGtleSkpIHtcbiAgICAgICAgICB0aGlzLmFkZEZpbGVzVG9GRChrZXksIGRhdGFba2V5XSwgZm9ybURhdGFBY2MpO1xuICAgICAgICAgIHJldHVybiBmb3JtRGF0YUFjYztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChrZXkgPT09ICdtZXNzYWdlJykgeyAvLyBtaW1lIG1lc3NhZ2VcbiAgICAgICAgICB0aGlzLmFkZE1pbWVEYXRhVG9GRChrZXksIGRhdGFba2V5XSwgZm9ybURhdGFBY2MpO1xuICAgICAgICAgIHJldHVybiBmb3JtRGF0YUFjYztcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuYWRkQ29tbW9uUHJvcGVydHlUb0ZEKGtleSwgZGF0YVtrZXldLCBmb3JtRGF0YUFjYyk7XG4gICAgICAgIHJldHVybiBmb3JtRGF0YUFjYztcbiAgICAgIH0sIG5ldyB0aGlzLkZvcm1EYXRhQ29uc3RydWN0b3IoKSk7XG4gICAgcmV0dXJuIGZvcm1EYXRhO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0Zvcm1EYXRhUGFja2FnZShmb3JtRGF0YUluc3RhbmNlOiBOb2RlRm9ybURhdGEgfCBGb3JtRGF0YSlcbiAgOiBib29sZWFuIHtcbiAgICByZXR1cm4gKDxOb2RlRm9ybURhdGE+Zm9ybURhdGFJbnN0YW5jZSkuZ2V0SGVhZGVycyAhPT0gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRBdHRhY2htZW50T3B0aW9ucyhpdGVtOiB7XG4gICAgZmlsZW5hbWU/OiBzdHJpbmc7XG4gICAgY29udGVudFR5cGU/IDogc3RyaW5nO1xuICAgIGtub3duTGVuZ3RoPzogbnVtYmVyO1xuICB9KToge1xuICAgIGZpbGVuYW1lPzogc3RyaW5nLFxuICAgIGNvbnRlbnRUeXBlPzogc3RyaW5nLFxuICAgIGtub3duTGVuZ3RoPzogbnVtYmVyXG4gIH0ge1xuICAgIGlmICh0eXBlb2YgaXRlbSAhPT0gJ29iamVjdCcgfHwgdGhpcy5pc1N0cmVhbShpdGVtKSkgcmV0dXJuIHt9O1xuICAgIGNvbnN0IHtcbiAgICAgIGZpbGVuYW1lLFxuICAgICAgY29udGVudFR5cGUsXG4gICAgICBrbm93bkxlbmd0aFxuICAgIH0gPSBpdGVtO1xuICAgIHJldHVybiB7XG4gICAgICAuLi4oZmlsZW5hbWUgPyB7IGZpbGVuYW1lIH0gOiB7IGZpbGVuYW1lOiAnZmlsZScgfSksXG4gICAgICAuLi4oY29udGVudFR5cGUgJiYgeyBjb250ZW50VHlwZSB9KSxcbiAgICAgIC4uLihrbm93bkxlbmd0aCAmJiB7IGtub3duTGVuZ3RoIH0pXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkTWltZURhdGFUb0ZEKFxuICAgIGtleTogc3RyaW5nLFxuICAgIGRhdGE6IEJ1ZmZlciB8IEJsb2IgfCBzdHJpbmcsXG4gICAgZm9ybURhdGFJbnN0YW5jZTogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGFcbiAgKTogdm9pZCB7XG4gICAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykgeyAvLyBpZiBzdHJpbmcgb25seSB0d28gcGFyYW1ldGVycyBzaG91bGQgYmUgdXNlZC5cbiAgICAgIGZvcm1EYXRhSW5zdGFuY2UuYXBwZW5kKGtleSwgZGF0YSBhcyBzdHJpbmcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzRm9ybURhdGFQYWNrYWdlKGZvcm1EYXRhSW5zdGFuY2UpKSB7IC8vIGZvcm0tZGF0YSBwYWNrYWdlIGlzIHVzZWRcbiAgICAgIGNvbnN0IG5vZGVGb3JtRGF0YSA9IGZvcm1EYXRhSW5zdGFuY2UgYXMgTm9kZUZvcm1EYXRhO1xuICAgICAgbm9kZUZvcm1EYXRhLmFwcGVuZChrZXksIGRhdGEsIHsgZmlsZW5hbWU6ICdNaW1lTWVzc2FnZScgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBCbG9iICE9PSB1bmRlZmluZWQpIHsgLy8gZWl0aGVyIG5vZGUgPiAxOCBvciBicm93c2VyXG4gICAgICBjb25zdCBicm93c2VyRm9ybURhdGEgPSBmb3JtRGF0YUluc3RhbmNlIGFzIEZvcm1EYXRhOyAvLyBCcm93c2VyIGNvbXBsaWFudCBGb3JtRGF0YVxuICAgICAgaWYgKGRhdGEgaW5zdGFuY2VvZiBCbG9iKSB7XG4gICAgICAgIGJyb3dzZXJGb3JtRGF0YS5hcHBlbmQoa2V5LCBkYXRhLCAnTWltZU1lc3NhZ2UnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBCdWZmZXIgIT09ICd1bmRlZmluZWQnKSB7IC8vIG5vZGUgZW52aXJvbm1lbnRcbiAgICAgICAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihkYXRhKSkge1xuICAgICAgICAgIGNvbnN0IGJsb2JJbnN0YW5jZSA9IG5ldyBCbG9iKFtkYXRhXSk7XG4gICAgICAgICAgYnJvd3NlckZvcm1EYXRhLmFwcGVuZChrZXksIGJsb2JJbnN0YW5jZSwgJ01pbWVNZXNzYWdlJyk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEFQSUVycm9yKHtcbiAgICAgIHN0YXR1czogNDAwLFxuICAgICAgc3RhdHVzVGV4dDogYFVua25vd24gZGF0YSB0eXBlIGZvciAke2tleX0gcHJvcGVydHlgLFxuICAgICAgYm9keTogJ1RoZSBtaW1lIGRhdGEgc2hvdWxkIGhhdmUgdHlwZSBvZiBCdWZmZXIsIFN0cmluZyBvciBCbG9iJ1xuICAgIH0gYXMgQVBJRXJyb3JPcHRpb25zKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkRmlsZXNUb0ZEKFxuICAgIHByb3BlcnR5TmFtZTogc3RyaW5nLFxuICAgIHZhbHVlOiBhbnksXG4gICAgZm9ybURhdGFJbnN0YW5jZTogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGFcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgYXBwZW5kRmlsZVRvRkQgPSAoXG4gICAgICBvcmlnaW5hbEtleTogc3RyaW5nLFxuICAgICAgb2JqOiBhbnksXG4gICAgICBmb3JtRGF0YTogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGFcbiAgICApOiB2b2lkID0+IHtcbiAgICAgIGNvbnN0IGtleSA9IG9yaWdpbmFsS2V5ID09PSAnbXVsdGlwbGVWYWxpZGF0aW9uRmlsZScgPyAnZmlsZScgOiBvcmlnaW5hbEtleTtcbiAgICAgIGNvbnN0IGlzU3RyZWFtRGF0YSA9IHRoaXMuaXNTdHJlYW0ob2JqKTtcbiAgICAgIGNvbnN0IG9iakRhdGEgPSBpc1N0cmVhbURhdGEgPyBvYmogOiBvYmouZGF0YTtcbiAgICAgIC8vIGdldEF0dGFjaG1lbnRPcHRpb25zIHNob3VsZCBiZSBjYWxsZWQgd2l0aCBvYmogcGFyYW1ldGVyIHRvIHByZXZlbnQgbG9vc2luZyBmaWxlbmFtZVxuICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuZ2V0QXR0YWNobWVudE9wdGlvbnMob2JqKTtcblxuICAgICAgaWYgKHRoaXMuaXNGb3JtRGF0YVBhY2thZ2UoZm9ybURhdGEpKSB7XG4gICAgICAgIGNvbnN0IGZkID0gZm9ybURhdGEgYXMgTm9kZUZvcm1EYXRhO1xuICAgICAgICBjb25zdCBkYXRhID0gdHlwZW9mIG9iakRhdGEgPT09ICdzdHJpbmcnID8gQnVmZmVyLmZyb20ob2JqRGF0YSkgOiBvYmpEYXRhO1xuICAgICAgICBmZC5hcHBlbmQoa2V5LCBkYXRhLCBvcHRpb25zKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIEJsb2IgIT09IHVuZGVmaW5lZCkgeyAvLyBlaXRoZXIgbm9kZSA+IDE4IG9yIGJyb3dzZXJcbiAgICAgICAgY29uc3QgYnJvd3NlckZvcm1EYXRhID0gZm9ybURhdGFJbnN0YW5jZSBhcyBGb3JtRGF0YTsgLy8gQnJvd3NlciBjb21wbGlhbnQgRm9ybURhdGFcbiAgICAgICAgaWYgKHR5cGVvZiBvYmpEYXRhID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGNvbnN0IGJsb2JJbnN0YW5jZSA9IG5ldyBCbG9iKFtvYmpEYXRhXSk7XG4gICAgICAgICAgYnJvd3NlckZvcm1EYXRhLmFwcGVuZChrZXksIGJsb2JJbnN0YW5jZSwgb3B0aW9ucy5maWxlbmFtZSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvYmpEYXRhIGluc3RhbmNlb2YgQmxvYikge1xuICAgICAgICAgIGJyb3dzZXJGb3JtRGF0YS5hcHBlbmQoa2V5LCBvYmpEYXRhLCBvcHRpb25zLmZpbGVuYW1lKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBCdWZmZXIgIT09ICd1bmRlZmluZWQnKSB7IC8vIG5vZGUgZW52aXJvbm1lbnRcbiAgICAgICAgICBpZiAoQnVmZmVyLmlzQnVmZmVyKG9iakRhdGEpKSB7XG4gICAgICAgICAgICBjb25zdCBibG9iSW5zdGFuY2UgPSBuZXcgQmxvYihbb2JqRGF0YV0pO1xuICAgICAgICAgICAgYnJvd3NlckZvcm1EYXRhLmFwcGVuZChrZXksIGJsb2JJbnN0YW5jZSwgb3B0aW9ucy5maWxlbmFtZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgdmFsdWUuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICBhcHBlbmRGaWxlVG9GRChwcm9wZXJ0eU5hbWUsIGl0ZW0sIGZvcm1EYXRhSW5zdGFuY2UpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFwcGVuZEZpbGVUb0ZEKHByb3BlcnR5TmFtZSwgdmFsdWUsIGZvcm1EYXRhSW5zdGFuY2UpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaXNTdHJlYW0oZGF0YTogYW55KSB7XG4gICAgcmV0dXJuIHR5cGVvZiBkYXRhID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgZGF0YS5waXBlID09PSAnZnVuY3Rpb24nO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRDb21tb25Qcm9wZXJ0eVRvRkQoXG4gICAga2V5OiBzdHJpbmcsXG4gICAgdmFsdWU6IGFueSxcbiAgICBmb3JtRGF0YUFjYzogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGFcbiAgKTogdm9pZCB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICB2YWx1ZS5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtOiBhbnkpIHtcbiAgICAgICAgZm9ybURhdGFBY2MuYXBwZW5kKGtleSwgaXRlbSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlICE9IG51bGwpIHtcbiAgICAgIGZvcm1EYXRhQWNjLmFwcGVuZChrZXksIHZhbHVlKTtcbiAgICB9XG4gIH1cbn1cbmV4cG9ydCBkZWZhdWx0IEZvcm1EYXRhQnVpbGRlcjtcbiIsImltcG9ydCB1cmxqb2luIGZyb20gJ3VybC1qb2luJztcbmltcG9ydCBBUElFcnJvciBmcm9tICcuL0Vycm9yJztcblxuaW1wb3J0IHtcbiAgUGFnZXNMaXN0QWNjdW11bGF0b3IsXG4gIFBhcnNlZFBhZ2UsXG4gIFBhcnNlZFBhZ2VzTGlzdCxcbiAgUXVlcnlXaXRoUGFnZSxcbiAgUmVzcG9uc2VXaXRoUGFnaW5nLFxuICBVcGRhdGVkVXJsQW5kUXVlcnksXG4gIEFQSUVycm9yT3B0aW9uc1xufSBmcm9tICcuLi8uLi9UeXBlcy9Db21tb24nO1xuaW1wb3J0IHtcbiAgSUJvdW5jZSxcbiAgSUNvbXBsYWludCxcbiAgSVVuc3Vic2NyaWJlLFxuICBJV2hpdGVMaXN0XG59IGZyb20gJy4uLy4uL0ludGVyZmFjZXMvU3VwcHJlc3Npb25zJztcbmltcG9ydCBSZXF1ZXN0IGZyb20gJy4vUmVxdWVzdCc7XG5pbXBvcnQge1xuICBTdXBwcmVzc2lvbkRhdGFUeXBlXG59IGZyb20gJy4uLy4uL1R5cGVzL1N1cHByZXNzaW9ucyc7XG5cbmV4cG9ydCBkZWZhdWx0IGFic3RyYWN0IGNsYXNzIE5hdmlnYXRpb25UaHJ1UGFnZXMgPFQ+IHtcbiAgcmVxdWVzdD86IFJlcXVlc3Q7XG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q/OiBSZXF1ZXN0KSB7XG4gICAgaWYgKHJlcXVlc3QpIHtcbiAgICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlUGFnZShcbiAgICBpZDogc3RyaW5nLFxuICAgIHBhZ2VVcmw6IHN0cmluZyxcbiAgICB1cmxTZXBhcmF0b3I6IHN0cmluZyxcbiAgICBpdGVyYXRvck5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZFxuICApIDogUGFyc2VkUGFnZSB7XG4gICAgY29uc3QgcGFyc2VkVXJsID0gbmV3IFVSTChwYWdlVXJsKTtcbiAgICBjb25zdCB7IHNlYXJjaFBhcmFtcyB9ID0gcGFyc2VkVXJsO1xuXG4gICAgY29uc3QgcGFnZVZhbHVlID0gcGFnZVVybCAmJiB0eXBlb2YgcGFnZVVybCA9PT0gJ3N0cmluZycgPyBwYWdlVXJsLnNwbGl0KHVybFNlcGFyYXRvcikucG9wKCkgfHwgJycgOiAnJztcbiAgICBsZXQgaXRlcmF0b3JQb3NpdGlvbiA9IG51bGw7XG4gICAgaWYgKGl0ZXJhdG9yTmFtZSkge1xuICAgICAgaXRlcmF0b3JQb3NpdGlvbiA9IHNlYXJjaFBhcmFtcy5oYXMoaXRlcmF0b3JOYW1lKVxuICAgICAgICA/IHNlYXJjaFBhcmFtcy5nZXQoaXRlcmF0b3JOYW1lKVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkLFxuICAgICAgcGFnZTogdXJsU2VwYXJhdG9yID09PSAnPycgPyBgPyR7cGFnZVZhbHVlfWAgOiBwYWdlVmFsdWUsXG4gICAgICBpdGVyYXRvclBvc2l0aW9uLFxuICAgICAgdXJsOiBwYWdlVXJsXG4gICAgfSBhcyBQYXJzZWRQYWdlO1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlUGFnZUxpbmtzKFxuICAgIHJlc3BvbnNlOiBSZXNwb25zZVdpdGhQYWdpbmcsXG4gICAgdXJsU2VwYXJhdG9yOiBzdHJpbmcsXG4gICAgaXRlcmF0b3JOYW1lPzogc3RyaW5nXG4gICk6IFBhcnNlZFBhZ2VzTGlzdCB7XG4gICAgY29uc3QgcGFnZXMgPSBPYmplY3QuZW50cmllcyhyZXNwb25zZS5ib2R5LnBhZ2luZyk7XG4gICAgcmV0dXJuIHBhZ2VzLnJlZHVjZShcbiAgICAgIChhY2M6IFBhZ2VzTGlzdEFjY3VtdWxhdG9yLCBbaWQsIHBhZ2VVcmxdOiBbIGlkOiBzdHJpbmcsIHBhZ2VVcmw6IHN0cmluZ10pID0+IHtcbiAgICAgICAgYWNjW2lkXSA9IHRoaXMucGFyc2VQYWdlKGlkLCBwYWdlVXJsLCB1cmxTZXBhcmF0b3IsIGl0ZXJhdG9yTmFtZSk7XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LCB7fVxuICAgICkgYXMgdW5rbm93biBhcyBQYXJzZWRQYWdlc0xpc3Q7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVVybEFuZFF1ZXJ5KGNsaWVudFVybDogc3RyaW5nLCBxdWVyeT86IFF1ZXJ5V2l0aFBhZ2UpOiBVcGRhdGVkVXJsQW5kUXVlcnkge1xuICAgIGxldCB1cmwgPSBjbGllbnRVcmw7XG4gICAgY29uc3QgcXVlcnlDb3B5ID0geyAuLi5xdWVyeSB9O1xuICAgIGlmIChxdWVyeUNvcHkucGFnZSkge1xuICAgICAgdXJsID0gdXJsam9pbihjbGllbnRVcmwsIHF1ZXJ5Q29weS5wYWdlKTtcbiAgICAgIGRlbGV0ZSBxdWVyeUNvcHkucGFnZTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHVybCxcbiAgICAgIHVwZGF0ZWRRdWVyeTogcXVlcnlDb3B5XG4gICAgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyByZXF1ZXN0TGlzdFdpdGhQYWdlcyhjbGllbnRVcmw6c3RyaW5nLCBxdWVyeT86IFF1ZXJ5V2l0aFBhZ2UsIE1vZGVsPzoge1xuICAgIG5ldyhkYXRhOiBTdXBwcmVzc2lvbkRhdGFUeXBlKTpcbiAgICBJQm91bmNlIHwgSUNvbXBsYWludCB8IElVbnN1YnNjcmliZSB8IElXaGl0ZUxpc3RcbiAgfSk6IFByb21pc2U8VD4ge1xuICAgIGNvbnN0IHsgdXJsLCB1cGRhdGVkUXVlcnkgfSA9IHRoaXMudXBkYXRlVXJsQW5kUXVlcnkoY2xpZW50VXJsLCBxdWVyeSk7XG4gICAgaWYgKHRoaXMucmVxdWVzdCkge1xuICAgICAgY29uc3QgcmVzcG9uc2U6IFJlc3BvbnNlV2l0aFBhZ2luZyA9IGF3YWl0IHRoaXMucmVxdWVzdC5nZXQodXJsLCB1cGRhdGVkUXVlcnkpO1xuICAgICAgLy8gTW9kZWwgaGVyZSBpcyB1c3VhbGx5IHVuZGVmaW5lZCBleGNlcHQgZm9yIFN1cHByZXNzaW9uIENsaWVudFxuICAgICAgcmV0dXJuIHRoaXMucGFyc2VMaXN0KHJlc3BvbnNlLCBNb2RlbCk7XG4gICAgfVxuICAgIHRocm93IG5ldyBBUElFcnJvcih7XG4gICAgICBzdGF0dXM6IDUwMCxcbiAgICAgIHN0YXR1c1RleHQ6ICdSZXF1ZXN0IHByb3BlcnR5IGlzIGVtcHR5JyxcbiAgICAgIGJvZHk6IHsgbWVzc2FnZTogJycgfVxuICAgIH0gYXMgQVBJRXJyb3JPcHRpb25zKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBwYXJzZUxpc3QocmVzcG9uc2U6IFJlc3BvbnNlV2l0aFBhZ2luZywgTW9kZWw/OiB7XG4gICAgbmV3KGRhdGE6IFN1cHByZXNzaW9uRGF0YVR5cGUpOlxuICAgIElCb3VuY2UgfCBJQ29tcGxhaW50IHwgSVVuc3Vic2NyaWJlIHwgSVdoaXRlTGlzdFxuICB9KTogVDtcbn1cbiIsImltcG9ydCAqIGFzIGJhc2U2NCBmcm9tICdiYXNlLTY0JztcbmltcG9ydCB1cmxqb2luIGZyb20gJ3VybC1qb2luJztcbmltcG9ydCBheGlvcywge1xuICBBeGlvc0Vycm9yLFxuICBBeGlvc1Jlc3BvbnNlLFxuICBBeGlvc0hlYWRlcnMsXG4gIFJhd0F4aW9zUmVxdWVzdEhlYWRlcnMsXG4gIEF4aW9zUHJveHlDb25maWcsXG59IGZyb20gJ2F4aW9zJztcbmltcG9ydCAqIGFzIE5vZGVGb3JtRGF0YSBmcm9tICdmb3JtLWRhdGEnO1xuaW1wb3J0IEFQSUVycm9yIGZyb20gJy4vRXJyb3InO1xuaW1wb3J0IHtcbiAgT25DYWxsUmVxdWVzdE9wdGlvbnMsXG4gIFJlcXVlc3RPcHRpb25zLFxuICBBUElFcnJvck9wdGlvbnMsXG4gIElucHV0Rm9ybURhdGEsXG4gIEFQSVJlc3BvbnNlLFxuICBJcFBvb2xEZWxldGVEYXRhXG59IGZyb20gJy4uLy4uL1R5cGVzJztcblxuaW1wb3J0IEZvcm1EYXRhQnVpbGRlciBmcm9tICcuL0Zvcm1EYXRhQnVpbGRlcic7XG5pbXBvcnQgU3ViYWNjb3VudHNDbGllbnQgZnJvbSAnLi4vU3ViYWNjb3VudHMnO1xuXG5jbGFzcyBSZXF1ZXN0IHtcbiAgcHJpdmF0ZSB1c2VybmFtZTogc3RyaW5nO1xuICBwcml2YXRlIGtleTogc3RyaW5nO1xuICBwcml2YXRlIHVybDogc3RyaW5nO1xuICBwcml2YXRlIHRpbWVvdXQ6IG51bWJlcjtcbiAgcHJpdmF0ZSBoZWFkZXJzOiBBeGlvc0hlYWRlcnM7XG4gIHByaXZhdGUgZm9ybURhdGFCdWlsZGVyOiBGb3JtRGF0YUJ1aWxkZXI7XG4gIHByaXZhdGUgbWF4Qm9keUxlbmd0aDogbnVtYmVyO1xuICBwcml2YXRlIHByb3h5OiBBeGlvc1Byb3h5Q29uZmlnIHwgdW5kZWZpbmVkO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFJlcXVlc3RPcHRpb25zLCBmb3JtRGF0YTogSW5wdXRGb3JtRGF0YSkge1xuICAgIHRoaXMudXNlcm5hbWUgPSBvcHRpb25zLnVzZXJuYW1lO1xuICAgIHRoaXMua2V5ID0gb3B0aW9ucy5rZXk7XG4gICAgdGhpcy51cmwgPSBvcHRpb25zLnVybCBhcyBzdHJpbmc7XG4gICAgdGhpcy50aW1lb3V0ID0gb3B0aW9ucy50aW1lb3V0O1xuICAgIHRoaXMuaGVhZGVycyA9IHRoaXMubWFrZUhlYWRlcnNGcm9tT2JqZWN0KG9wdGlvbnMuaGVhZGVycyk7XG4gICAgdGhpcy5mb3JtRGF0YUJ1aWxkZXIgPSBuZXcgRm9ybURhdGFCdWlsZGVyKGZvcm1EYXRhKTtcbiAgICB0aGlzLm1heEJvZHlMZW5ndGggPSA1MjQyODgwMDsgLy8gNTAgTUJcbiAgICB0aGlzLnByb3h5ID0gb3B0aW9ucz8ucHJveHk7XG4gIH1cblxuICBhc3luYyByZXF1ZXN0KFxuICAgIG1ldGhvZDogc3RyaW5nLFxuICAgIHVybDogc3RyaW5nLFxuICAgIG9uQ2FsbE9wdGlvbnM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duIHwgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPlxuICApOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgY29uc3Qgb3B0aW9uczogT25DYWxsUmVxdWVzdE9wdGlvbnMgPSB7IC4uLm9uQ2FsbE9wdGlvbnMgfTtcbiAgICBkZWxldGUgb3B0aW9ucz8uaGVhZGVycztcbiAgICBjb25zdCByZXF1ZXN0SGVhZGVycyA9IHRoaXMuam9pbkFuZFRyYW5zZm9ybUhlYWRlcnMob25DYWxsT3B0aW9ucyk7XG4gICAgY29uc3QgcGFyYW1zID0geyAuLi5vcHRpb25zIH07XG5cbiAgICBpZiAob3B0aW9ucz8ucXVlcnkgJiYgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMob3B0aW9ucz8ucXVlcnkpLmxlbmd0aCA+IDApIHtcbiAgICAgIHBhcmFtcy5wYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKG9wdGlvbnMucXVlcnkpO1xuICAgICAgZGVsZXRlIHBhcmFtcy5xdWVyeTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucz8uYm9keSkge1xuICAgICAgY29uc3QgYm9keSA9IG9wdGlvbnM/LmJvZHk7XG4gICAgICBwYXJhbXMuZGF0YSA9IGJvZHk7XG4gICAgICBkZWxldGUgcGFyYW1zLmJvZHk7XG4gICAgfVxuICAgIGxldCByZXNwb25zZTogQXhpb3NSZXNwb25zZTtcbiAgICBjb25zdCB1cmxWYWx1ZSA9IHVybGpvaW4odGhpcy51cmwsIHVybCk7XG5cbiAgICB0cnkge1xuICAgICAgcmVzcG9uc2UgPSBhd2FpdCBheGlvcy5yZXF1ZXN0KHtcbiAgICAgICAgbWV0aG9kOiBtZXRob2QudG9Mb2NhbGVVcHBlckNhc2UoKSxcbiAgICAgICAgdGltZW91dDogdGhpcy50aW1lb3V0LFxuICAgICAgICB1cmw6IHVybFZhbHVlLFxuICAgICAgICBoZWFkZXJzOiByZXF1ZXN0SGVhZGVycyxcbiAgICAgICAgLi4ucGFyYW1zLFxuICAgICAgICBtYXhCb2R5TGVuZ3RoOiB0aGlzLm1heEJvZHlMZW5ndGgsXG4gICAgICAgIHByb3h5OiB0aGlzLnByb3h5LFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG4gICAgICBjb25zdCBlcnJvclJlc3BvbnNlID0gZXJyIGFzIEF4aW9zRXJyb3I7XG5cbiAgICAgIHRocm93IG5ldyBBUElFcnJvcih7XG4gICAgICAgIHN0YXR1czogZXJyb3JSZXNwb25zZT8ucmVzcG9uc2U/LnN0YXR1cyB8fCA0MDAsXG4gICAgICAgIHN0YXR1c1RleHQ6IGVycm9yUmVzcG9uc2U/LnJlc3BvbnNlPy5zdGF0dXNUZXh0IHx8IGVycm9yUmVzcG9uc2UuY29kZSxcbiAgICAgICAgYm9keTogZXJyb3JSZXNwb25zZT8ucmVzcG9uc2U/LmRhdGEgfHwgZXJyb3JSZXNwb25zZS5tZXNzYWdlXG4gICAgICB9IGFzIEFQSUVycm9yT3B0aW9ucyk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5nZXRSZXNwb25zZUJvZHkocmVzcG9uc2UpO1xuICAgIHJldHVybiByZXMgYXMgQVBJUmVzcG9uc2U7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdldFJlc3BvbnNlQm9keShyZXNwb25zZTogQXhpb3NSZXNwb25zZSk6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXMgPSB7XG4gICAgICBib2R5OiB7fSxcbiAgICAgIHN0YXR1czogcmVzcG9uc2U/LnN0YXR1c1xuICAgIH0gYXMgQVBJUmVzcG9uc2U7XG5cbiAgICBpZiAodHlwZW9mIHJlc3BvbnNlLmRhdGEgPT09ICdzdHJpbmcnKSB7XG4gICAgICBpZiAocmVzcG9uc2UuZGF0YSA9PT0gJ01haWxndW4gTWFnbmlmaWNlbnQgQVBJJykge1xuICAgICAgICB0aHJvdyBuZXcgQVBJRXJyb3Ioe1xuICAgICAgICAgIHN0YXR1czogNDAwLFxuICAgICAgICAgIHN0YXR1c1RleHQ6ICdJbmNvcnJlY3QgdXJsJyxcbiAgICAgICAgICBib2R5OiByZXNwb25zZS5kYXRhXG4gICAgICAgIH0gYXMgQVBJRXJyb3JPcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIHJlcy5ib2R5ID0ge1xuICAgICAgICBtZXNzYWdlOiByZXNwb25zZS5kYXRhXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXMuYm9keSA9IHJlc3BvbnNlLmRhdGE7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH1cblxuICBwcml2YXRlIGpvaW5BbmRUcmFuc2Zvcm1IZWFkZXJzKFxuICAgIG9uQ2FsbE9wdGlvbnM/OiBPbkNhbGxSZXF1ZXN0T3B0aW9uc1xuICApOiBBeGlvc0hlYWRlcnMge1xuICAgIGNvbnN0IHJlcXVlc3RIZWFkZXJzID0gbmV3IEF4aW9zSGVhZGVycygpO1xuXG4gICAgY29uc3QgYmFzaWMgPSBiYXNlNjQuZW5jb2RlKGAke3RoaXMudXNlcm5hbWV9OiR7dGhpcy5rZXl9YCk7XG4gICAgcmVxdWVzdEhlYWRlcnMuc2V0QXV0aG9yaXphdGlvbihgQmFzaWMgJHtiYXNpY31gKTtcbiAgICByZXF1ZXN0SGVhZGVycy5zZXQodGhpcy5oZWFkZXJzKTtcblxuICAgIGNvbnN0IHJlY2VpdmVkT25DYWxsSGVhZGVycyA9IG9uQ2FsbE9wdGlvbnMgJiYgb25DYWxsT3B0aW9ucy5oZWFkZXJzO1xuICAgIGNvbnN0IG9uQ2FsbEhlYWRlcnMgPSB0aGlzLm1ha2VIZWFkZXJzRnJvbU9iamVjdChyZWNlaXZlZE9uQ2FsbEhlYWRlcnMpO1xuICAgIHJlcXVlc3RIZWFkZXJzLnNldChvbkNhbGxIZWFkZXJzKTtcbiAgICByZXR1cm4gcmVxdWVzdEhlYWRlcnM7XG4gIH1cblxuICBwcml2YXRlIG1ha2VIZWFkZXJzRnJvbU9iamVjdChcbiAgICBoZWFkZXJzT2JqZWN0OiBSYXdBeGlvc1JlcXVlc3RIZWFkZXJzID0ge31cbiAgKTogQXhpb3NIZWFkZXJzIHtcbiAgICBsZXQgcmVxdWVzdEhlYWRlcnMgPSBuZXcgQXhpb3NIZWFkZXJzKCk7XG4gICAgcmVxdWVzdEhlYWRlcnMgPSBPYmplY3QuZW50cmllcyhoZWFkZXJzT2JqZWN0KS5yZWR1Y2UoXG4gICAgICAoaGVhZGVyc0FjY3VtdWxhdG9yOiBBeGlvc0hlYWRlcnMsIGN1cnJlbnRQYWlyKSA9PiB7XG4gICAgICAgIGNvbnN0IFtrZXksIHZhbHVlXSA9IGN1cnJlbnRQYWlyO1xuICAgICAgICBoZWFkZXJzQWNjdW11bGF0b3Iuc2V0KGtleSwgdmFsdWUpO1xuICAgICAgICByZXR1cm4gaGVhZGVyc0FjY3VtdWxhdG9yO1xuICAgICAgfSwgcmVxdWVzdEhlYWRlcnNcbiAgICApO1xuICAgIHJldHVybiByZXF1ZXN0SGVhZGVycztcbiAgfVxuXG4gIHNldFN1YmFjY291bnRIZWFkZXIoc3ViYWNjb3VudElkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBoZWFkZXJzID0gdGhpcy5tYWtlSGVhZGVyc0Zyb21PYmplY3Qoe1xuICAgICAgLi4udGhpcy5oZWFkZXJzLFxuICAgICAgW1N1YmFjY291bnRzQ2xpZW50LlNVQkFDQ09VTlRfSEVBREVSXTogc3ViYWNjb3VudElkXG4gICAgfSk7XG4gICAgdGhpcy5oZWFkZXJzLnNldChoZWFkZXJzKTtcbiAgfVxuXG4gIHJlc2V0U3ViYWNjb3VudEhlYWRlcigpOiB2b2lkIHtcbiAgICB0aGlzLmhlYWRlcnMuZGVsZXRlKFN1YmFjY291bnRzQ2xpZW50LlNVQkFDQ09VTlRfSEVBREVSKTtcbiAgfVxuXG4gIHF1ZXJ5KFxuICAgIG1ldGhvZDogc3RyaW5nLFxuICAgIHVybDogc3RyaW5nLFxuICAgIHF1ZXJ5PzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBBcnJheTxBcnJheTxzdHJpbmc+PixcbiAgICBvcHRpb25zPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbiAgKTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QobWV0aG9kLCB1cmwsIHsgcXVlcnksIC4uLm9wdGlvbnMgfSk7XG4gIH1cblxuICBjb21tYW5kKFxuICAgIG1ldGhvZDogc3RyaW5nLFxuICAgIHVybDogc3RyaW5nLFxuICAgIGRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IFJlY29yZDxzdHJpbmcsIHVua25vd24+W10gfCBzdHJpbmcgfCBOb2RlRm9ybURhdGEgfCBGb3JtRGF0YSxcbiAgICBvcHRpb25zPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gICAgYWRkRGVmYXVsdEhlYWRlcnMgPSB0cnVlXG4gICk6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICBsZXQgaGVhZGVycyA9IHt9O1xuICAgIGlmIChhZGREZWZhdWx0SGVhZGVycykge1xuICAgICAgaGVhZGVycyA9IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnIH07XG4gICAgfVxuICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zID0ge1xuICAgICAgLi4uaGVhZGVycyxcbiAgICAgIGJvZHk6IGRhdGEsXG4gICAgICAuLi5vcHRpb25zXG4gICAgfTtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KFxuICAgICAgbWV0aG9kLFxuICAgICAgdXJsLFxuICAgICAgcmVxdWVzdE9wdGlvbnNcbiAgICApO1xuICB9XG5cbiAgZ2V0KFxuICAgIHVybDogc3RyaW5nLFxuICAgIHF1ZXJ5PzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBBcnJheTxBcnJheTxzdHJpbmc+PixcbiAgICBvcHRpb25zPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbiAgKTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5KCdnZXQnLCB1cmwsIHF1ZXJ5LCBvcHRpb25zKTtcbiAgfVxuXG4gIHBvc3QoXG4gICAgdXJsOiBzdHJpbmcsXG4gICAgZGF0YT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgc3RyaW5nLFxuICAgIG9wdGlvbnM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxuICApOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZCgncG9zdCcsIHVybCwgZGF0YSwgb3B0aW9ucyk7XG4gIH1cblxuICBwb3N0V2l0aEZEKFxuICAgIHVybDogc3RyaW5nLFxuICAgIGRhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXVxuICApOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgY29uc3QgZm9ybURhdGEgPSB0aGlzLmZvcm1EYXRhQnVpbGRlci5jcmVhdGVGb3JtRGF0YShkYXRhKTtcbiAgICByZXR1cm4gdGhpcy5jb21tYW5kKCdwb3N0JywgdXJsLCBmb3JtRGF0YSwge1xuICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ211bHRpcGFydC9mb3JtLWRhdGEnIH1cbiAgICB9LCBmYWxzZSk7XG4gIH1cblxuICBwdXRXaXRoRkQodXJsOiBzdHJpbmcsIGRhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIGNvbnN0IGZvcm1EYXRhID0gdGhpcy5mb3JtRGF0YUJ1aWxkZXIuY3JlYXRlRm9ybURhdGEoZGF0YSk7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZCgncHV0JywgdXJsLCBmb3JtRGF0YSwge1xuICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ211bHRpcGFydC9mb3JtLWRhdGEnIH1cbiAgICB9LCBmYWxzZSk7XG4gIH1cblxuICBwYXRjaFdpdGhGRCh1cmw6IHN0cmluZywgZGF0YTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgY29uc3QgZm9ybURhdGEgPSB0aGlzLmZvcm1EYXRhQnVpbGRlci5jcmVhdGVGb3JtRGF0YShkYXRhKTtcbiAgICByZXR1cm4gdGhpcy5jb21tYW5kKCdwYXRjaCcsIHVybCwgZm9ybURhdGEsIHtcbiAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdtdWx0aXBhcnQvZm9ybS1kYXRhJyB9XG4gICAgfSwgZmFsc2UpO1xuICB9XG5cbiAgcHV0KHVybDogc3RyaW5nLCBkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBzdHJpbmcsIG9wdGlvbnM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilcbiAgOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZCgncHV0JywgdXJsLCBkYXRhLCBvcHRpb25zKTtcbiAgfVxuXG4gIGRlbGV0ZSh1cmw6IHN0cmluZywgZGF0YT86IElwUG9vbERlbGV0ZURhdGEpOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZCgnZGVsZXRlJywgdXJsLCBkYXRhKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBSZXF1ZXN0O1xuIiwiZXhwb3J0IGVudW0gUmVzb2x1dGlvbiB7XG4gICAgSE9VUiA9ICdob3VyJyxcbiAgICBEQVkgPSAnZGF5JyxcbiAgICBNT05USCA9ICdtb250aCdcbn1cblxuZXhwb3J0IGVudW0gU3VwcHJlc3Npb25Nb2RlbHMge1xuICAgIEJPVU5DRVMgPSAnYm91bmNlcycsXG4gICAgQ09NUExBSU5UUyA9ICdjb21wbGFpbnRzJyxcbiAgICBVTlNVQlNDUklCRVMgPSAndW5zdWJzY3JpYmVzJyxcbiAgICBXSElURUxJU1RTID0gJ3doaXRlbGlzdHMnXG59XG5cbmV4cG9ydCBlbnVtIFdlYmhvb2tzSWRzIHtcbiAgICBDTElDS0VEID0gJ2NsaWNrZWQnLFxuICAgIENPTVBMQUlORUQgPSAnY29tcGxhaW5lZCcsXG4gICAgREVMSVZFUkVEID0gJ2RlbGl2ZXJlZCcsXG4gICAgT1BFTkVEID0gJ29wZW5lZCcsXG4gICAgUEVSTUFORU5UX0ZBSUwgPSAncGVybWFuZW50X2ZhaWwnLFxuICAgIFRFTVBPUkFSWV9GQUlMID0gJ3RlbXBvcmFyeV9mYWlsJyxcbiAgICBVTlNVQlNDUklCRUQgPSAndW5zdWJzY3JpYmUnLFxufVxuXG5leHBvcnQgZW51bSBZZXNObyB7XG4gICAgWUVTID0gJ3llcycsXG4gICAgTk8gPSAnbm8nXG59XG4iLCJleHBvcnQgKiBmcm9tICcuL0xvZ2dlcic7XG4iLCJleHBvcnQgKiBmcm9tICcuL0RvbWFpbkNyZWRlbnRpYWxzJztcbmV4cG9ydCAqIGZyb20gJy4vRG9tYWluVGFncyc7XG5leHBvcnQgKiBmcm9tICcuL0RvbWFpblRlbXBsYXRlcyc7XG5leHBvcnQgKiBmcm9tICcuL0RvbWFpbnNDbGllbnQnO1xuIiwiZXhwb3J0ICogZnJvbSAnLi9JRXZlbnRDbGllbnQnO1xuIiwiZXhwb3J0ICogZnJvbSAnLi9JSVBQb29sc0NsaWVudCc7XG4iLCJleHBvcnQgKiBmcm9tICcuL0lJUHNDbGllbnQnO1xuIiwiZXhwb3J0ICogZnJvbSAnLi9JTWFpbGd1bkNsaWVudCc7XG4iLCJleHBvcnQgKiBmcm9tICcuL01haWxpbmdMaXN0TWVtYmVycyc7XG5leHBvcnQgKiBmcm9tICcuL01haWxpbmdMaXN0c0NsaWVudCc7XG4iLCJleHBvcnQgKiBmcm9tICcuL0lNZXNzYWdlc0NsaWVudCc7XG4iLCJleHBvcnQgKiBmcm9tICcuL0lSb3V0ZXNDbGllbnQnO1xuIiwiZXhwb3J0ICogZnJvbSAnLi9TdGF0c0NsaWVudCc7XG5leHBvcnQgKiBmcm9tICcuL1N0YXRzQ29udGFpbmVyJztcbiIsImV4cG9ydCAqIGZyb20gJy4vSVN1YmFjY291bnRzQ2xpZW50JztcbiIsImV4cG9ydCAqIGZyb20gJy4vQm91bmNlJztcbmV4cG9ydCAqIGZyb20gJy4vQ29tcGxhaW50JztcbmV4cG9ydCAqIGZyb20gJy4vVW5zdWJzY3JpYmUnO1xuZXhwb3J0ICogZnJvbSAnLi9XaGl0ZUxpc3QnO1xuZXhwb3J0ICogZnJvbSAnLi9JU3VwcHJlc3Npb25zQ2xpZW50JztcbiIsImV4cG9ydCAqIGZyb20gJy4vTXVsdGlwbGVWYWxpZGF0aW9uJztcbmV4cG9ydCAqIGZyb20gJy4vVmFsaWRhdGlvbic7XG4iLCJleHBvcnQgKiBmcm9tICcuL0lXZWJIb29rc0NsaWVudCc7XG4iLCJleHBvcnQgKiBmcm9tICcuL0NvbW1vbic7XG5leHBvcnQgKiBmcm9tICcuL0RvbWFpbnMnO1xuZXhwb3J0ICogZnJvbSAnLi9NYWlsZ3VuQ2xpZW50JztcbmV4cG9ydCAqIGZyb20gJy4vTWFpbGluZ0xpc3RzJztcbmV4cG9ydCAqIGZyb20gJy4vU3RhdHMnO1xuZXhwb3J0ICogZnJvbSAnLi9TdXBwcmVzc2lvbnMnO1xuZXhwb3J0ICogZnJvbSAnLi9WYWxpZGF0aW9ucyc7XG5leHBvcnQgKiBmcm9tICcuL0V2ZW50Q2xpZW50JztcbmV4cG9ydCAqIGZyb20gJy4vV2ViaG9va3MnO1xuZXhwb3J0ICogZnJvbSAnLi9NZXNzYWdlcyc7XG5leHBvcnQgKiBmcm9tICcuL1JvdXRlcyc7XG5leHBvcnQgKiBmcm9tICcuL0lQcyc7XG5leHBvcnQgKiBmcm9tICcuL0lQUG9vbHMnO1xuZXhwb3J0ICogZnJvbSAnLi9TdWJhY2NvdW50cyc7XG4iLCJleHBvcnQgKiBmcm9tICcuL0Vycm9yJztcbmV4cG9ydCAqIGZyb20gJy4vQXBpUmVzcG9uc2UnO1xuZXhwb3J0ICogZnJvbSAnLi9Gb3JtRGF0YSc7XG5leHBvcnQgKiBmcm9tICcuL05hdmlnYXRpb25UaHJ1UGFnZXMnO1xuZXhwb3J0ICogZnJvbSAnLi9SZXF1ZXN0T3B0aW9ucyc7XG4iLCJleHBvcnQgKiBmcm9tICcuL0RvbWFpbkNyZWRlbnRpYWxzJztcbmV4cG9ydCAqIGZyb20gJy4vRG9tYWlucyc7XG5leHBvcnQgKiBmcm9tICcuL0RvbWFpblRhZ3MnO1xuZXhwb3J0ICogZnJvbSAnLi9Eb21haW5UZW1wbGF0ZXMnO1xuZXhwb3J0ICogZnJvbSAnLi9Eb21haW5UcmFja2luZyc7XG4iLCJleHBvcnQgKiBmcm9tICcuL0V2ZW50cyc7XG4iLCJleHBvcnQgKiBmcm9tICcuL0lwUG9vbHMnO1xuIiwiZXhwb3J0ICogZnJvbSAnLi9JUHMnO1xuIiwiZXhwb3J0ICogZnJvbSAnLi9NYWlsZ3VuQ2xpZW50T3B0aW9ucyc7XG4iLCJleHBvcnQgKiBmcm9tICcuL01haWxpbmdMaXN0TWVtYmVycyc7XG5leHBvcnQgKiBmcm9tICcuL01haWxpbmdMaXN0cyc7XG4iLCJleHBvcnQgKiBmcm9tICcuL01lc3NhZ2VzJztcbiIsImV4cG9ydCAqIGZyb20gJy4vUm91dGVzJztcbiIsImV4cG9ydCAqIGZyb20gJy4vU3RhdHMnO1xuIiwiZXhwb3J0ICogZnJvbSAnLi9TdWJhY2NvdW50cyc7XG4iLCJleHBvcnQgKiBmcm9tICcuL0JvdW5jZSc7XG5leHBvcnQgKiBmcm9tICcuL0NvbXBsYWludCc7XG5leHBvcnQgKiBmcm9tICcuL1N1cHByZXNzaW9ucyc7XG5leHBvcnQgKiBmcm9tICcuL1Vuc3Vic2NyaWJlJztcbmV4cG9ydCAqIGZyb20gJy4vV2hpdGVMaXN0JztcbiIsImV4cG9ydCAqIGZyb20gJy4vTXVsdGlwbGVWYWxpZGF0aW9uJztcbmV4cG9ydCAqIGZyb20gJy4vVmFsaWRhdGlvbic7XG4iLCJleHBvcnQgKiBmcm9tICcuL1dlYmhvb2tzJztcbiIsImV4cG9ydCAqIGZyb20gJy4vQ29tbW9uJztcbmV4cG9ydCAqIGZyb20gJy4vRG9tYWlucyc7XG5leHBvcnQgKiBmcm9tICcuL0V2ZW50cyc7XG5leHBvcnQgKiBmcm9tICcuL0lQUG9vbHMnO1xuZXhwb3J0ICogZnJvbSAnLi9JUHMnO1xuZXhwb3J0ICogZnJvbSAnLi9NYWlsZ3VuQ2xpZW50JztcbmV4cG9ydCAqIGZyb20gJy4vTWFpbGluZ0xpc3RzJztcbmV4cG9ydCAqIGZyb20gJy4vTWVzc2FnZXMnO1xuZXhwb3J0ICogZnJvbSAnLi9Sb3V0ZXMnO1xuZXhwb3J0ICogZnJvbSAnLi9TdGF0cyc7XG5leHBvcnQgKiBmcm9tICcuL1N1YmFjY291bnRzJztcbmV4cG9ydCAqIGZyb20gJy4vU3VwcHJlc3Npb25zJztcbmV4cG9ydCAqIGZyb20gJy4vVmFsaWRhdGlvbnMnO1xuZXhwb3J0ICogZnJvbSAnLi9XZWJob29rcyc7XG4iLCJpbXBvcnQgTWFpbGd1bkNsaWVudCBmcm9tICcuL0NsYXNzZXMvTWFpbGd1bkNsaWVudCc7XG5pbXBvcnQgeyBJTWFpbGd1bkNsaWVudCB9IGZyb20gJy4vSW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBJbnB1dEZvcm1EYXRhLCBNYWlsZ3VuQ2xpZW50T3B0aW9ucyB9IGZyb20gJy4vVHlwZXMnO1xuXG5leHBvcnQgKiBhcyBFbnVtcyBmcm9tICcuL0VudW1zJztcbmV4cG9ydCAqIGZyb20gJy4vVHlwZXMnO1xuZXhwb3J0ICogYXMgSW50ZXJmYWNlcyBmcm9tICcuL0ludGVyZmFjZXMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNYWlsZ3VuIHtcbiAgc3RhdGljIGdldCBkZWZhdWx0KCk6IHR5cGVvZiBNYWlsZ3VuIHsgcmV0dXJuIHRoaXM7IH1cbiAgcHJpdmF0ZSBmb3JtRGF0YTogSW5wdXRGb3JtRGF0YVxuXG4gIGNvbnN0cnVjdG9yKEZvcm1EYXRhOiBJbnB1dEZvcm1EYXRhKSB7XG4gICAgdGhpcy5mb3JtRGF0YSA9IEZvcm1EYXRhO1xuICB9XG5cbiAgY2xpZW50KG9wdGlvbnM6IE1haWxndW5DbGllbnRPcHRpb25zKSA6IElNYWlsZ3VuQ2xpZW50IHtcbiAgICByZXR1cm4gbmV3IE1haWxndW5DbGllbnQob3B0aW9ucywgdGhpcy5mb3JtRGF0YSk7XG4gIH1cbn1cbiIsIi8qISBodHRwczovL210aHMuYmUvYmFzZTY0IHYxLjAuMCBieSBAbWF0aGlhcyB8IE1JVCBsaWNlbnNlICovXG47KGZ1bmN0aW9uKHJvb3QpIHtcblxuXHQvLyBEZXRlY3QgZnJlZSB2YXJpYWJsZXMgYGV4cG9ydHNgLlxuXHR2YXIgZnJlZUV4cG9ydHMgPSB0eXBlb2YgZXhwb3J0cyA9PSAnb2JqZWN0JyAmJiBleHBvcnRzO1xuXG5cdC8vIERldGVjdCBmcmVlIHZhcmlhYmxlIGBtb2R1bGVgLlxuXHR2YXIgZnJlZU1vZHVsZSA9IHR5cGVvZiBtb2R1bGUgPT0gJ29iamVjdCcgJiYgbW9kdWxlICYmXG5cdFx0bW9kdWxlLmV4cG9ydHMgPT0gZnJlZUV4cG9ydHMgJiYgbW9kdWxlO1xuXG5cdC8vIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgLCBmcm9tIE5vZGUuanMgb3IgQnJvd3NlcmlmaWVkIGNvZGUsIGFuZCB1c2Vcblx0Ly8gaXQgYXMgYHJvb3RgLlxuXHR2YXIgZnJlZUdsb2JhbCA9IHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuXHRpZiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwpIHtcblx0XHRyb290ID0gZnJlZUdsb2JhbDtcblx0fVxuXG5cdC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5cdHZhciBJbnZhbGlkQ2hhcmFjdGVyRXJyb3IgPSBmdW5jdGlvbihtZXNzYWdlKSB7XG5cdFx0dGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcblx0fTtcblx0SW52YWxpZENoYXJhY3RlckVycm9yLnByb3RvdHlwZSA9IG5ldyBFcnJvcjtcblx0SW52YWxpZENoYXJhY3RlckVycm9yLnByb3RvdHlwZS5uYW1lID0gJ0ludmFsaWRDaGFyYWN0ZXJFcnJvcic7XG5cblx0dmFyIGVycm9yID0gZnVuY3Rpb24obWVzc2FnZSkge1xuXHRcdC8vIE5vdGU6IHRoZSBlcnJvciBtZXNzYWdlcyB1c2VkIHRocm91Z2hvdXQgdGhpcyBmaWxlIG1hdGNoIHRob3NlIHVzZWQgYnlcblx0XHQvLyB0aGUgbmF0aXZlIGBhdG9iYC9gYnRvYWAgaW1wbGVtZW50YXRpb24gaW4gQ2hyb21pdW0uXG5cdFx0dGhyb3cgbmV3IEludmFsaWRDaGFyYWN0ZXJFcnJvcihtZXNzYWdlKTtcblx0fTtcblxuXHR2YXIgVEFCTEUgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyc7XG5cdC8vIGh0dHA6Ly93aGF0d2cub3JnL2h0bWwvY29tbW9uLW1pY3Jvc3ludGF4ZXMuaHRtbCNzcGFjZS1jaGFyYWN0ZXJcblx0dmFyIFJFR0VYX1NQQUNFX0NIQVJBQ1RFUlMgPSAvW1xcdFxcblxcZlxcciBdL2c7XG5cblx0Ly8gYGRlY29kZWAgaXMgZGVzaWduZWQgdG8gYmUgZnVsbHkgY29tcGF0aWJsZSB3aXRoIGBhdG9iYCBhcyBkZXNjcmliZWQgaW4gdGhlXG5cdC8vIEhUTUwgU3RhbmRhcmQuIGh0dHA6Ly93aGF0d2cub3JnL2h0bWwvd2ViYXBwYXBpcy5odG1sI2RvbS13aW5kb3diYXNlNjQtYXRvYlxuXHQvLyBUaGUgb3B0aW1pemVkIGJhc2U2NC1kZWNvZGluZyBhbGdvcml0aG0gdXNlZCBpcyBiYXNlZCBvbiBAYXRr4oCZcyBleGNlbGxlbnRcblx0Ly8gaW1wbGVtZW50YXRpb24uIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL2F0ay8xMDIwMzk2XG5cdHZhciBkZWNvZGUgPSBmdW5jdGlvbihpbnB1dCkge1xuXHRcdGlucHV0ID0gU3RyaW5nKGlucHV0KVxuXHRcdFx0LnJlcGxhY2UoUkVHRVhfU1BBQ0VfQ0hBUkFDVEVSUywgJycpO1xuXHRcdHZhciBsZW5ndGggPSBpbnB1dC5sZW5ndGg7XG5cdFx0aWYgKGxlbmd0aCAlIDQgPT0gMCkge1xuXHRcdFx0aW5wdXQgPSBpbnB1dC5yZXBsYWNlKC89PT8kLywgJycpO1xuXHRcdFx0bGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuXHRcdH1cblx0XHRpZiAoXG5cdFx0XHRsZW5ndGggJSA0ID09IDEgfHxcblx0XHRcdC8vIGh0dHA6Ly93aGF0d2cub3JnL0MjYWxwaGFudW1lcmljLWFzY2lpLWNoYXJhY3RlcnNcblx0XHRcdC9bXithLXpBLVowLTkvXS8udGVzdChpbnB1dClcblx0XHQpIHtcblx0XHRcdGVycm9yKFxuXHRcdFx0XHQnSW52YWxpZCBjaGFyYWN0ZXI6IHRoZSBzdHJpbmcgdG8gYmUgZGVjb2RlZCBpcyBub3QgY29ycmVjdGx5IGVuY29kZWQuJ1xuXHRcdFx0KTtcblx0XHR9XG5cdFx0dmFyIGJpdENvdW50ZXIgPSAwO1xuXHRcdHZhciBiaXRTdG9yYWdlO1xuXHRcdHZhciBidWZmZXI7XG5cdFx0dmFyIG91dHB1dCA9ICcnO1xuXHRcdHZhciBwb3NpdGlvbiA9IC0xO1xuXHRcdHdoaWxlICgrK3Bvc2l0aW9uIDwgbGVuZ3RoKSB7XG5cdFx0XHRidWZmZXIgPSBUQUJMRS5pbmRleE9mKGlucHV0LmNoYXJBdChwb3NpdGlvbikpO1xuXHRcdFx0Yml0U3RvcmFnZSA9IGJpdENvdW50ZXIgJSA0ID8gYml0U3RvcmFnZSAqIDY0ICsgYnVmZmVyIDogYnVmZmVyO1xuXHRcdFx0Ly8gVW5sZXNzIHRoaXMgaXMgdGhlIGZpcnN0IG9mIGEgZ3JvdXAgb2YgNCBjaGFyYWN0ZXJz4oCmXG5cdFx0XHRpZiAoYml0Q291bnRlcisrICUgNCkge1xuXHRcdFx0XHQvLyDigKZjb252ZXJ0IHRoZSBmaXJzdCA4IGJpdHMgdG8gYSBzaW5nbGUgQVNDSUkgY2hhcmFjdGVyLlxuXHRcdFx0XHRvdXRwdXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShcblx0XHRcdFx0XHQweEZGICYgYml0U3RvcmFnZSA+PiAoLTIgKiBiaXRDb3VudGVyICYgNilcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIG91dHB1dDtcblx0fTtcblxuXHQvLyBgZW5jb2RlYCBpcyBkZXNpZ25lZCB0byBiZSBmdWxseSBjb21wYXRpYmxlIHdpdGggYGJ0b2FgIGFzIGRlc2NyaWJlZCBpbiB0aGVcblx0Ly8gSFRNTCBTdGFuZGFyZDogaHR0cDovL3doYXR3Zy5vcmcvaHRtbC93ZWJhcHBhcGlzLmh0bWwjZG9tLXdpbmRvd2Jhc2U2NC1idG9hXG5cdHZhciBlbmNvZGUgPSBmdW5jdGlvbihpbnB1dCkge1xuXHRcdGlucHV0ID0gU3RyaW5nKGlucHV0KTtcblx0XHRpZiAoL1teXFwwLVxceEZGXS8udGVzdChpbnB1dCkpIHtcblx0XHRcdC8vIE5vdGU6IG5vIG5lZWQgdG8gc3BlY2lhbC1jYXNlIGFzdHJhbCBzeW1ib2xzIGhlcmUsIGFzIHN1cnJvZ2F0ZXMgYXJlXG5cdFx0XHQvLyBtYXRjaGVkLCBhbmQgdGhlIGlucHV0IGlzIHN1cHBvc2VkIHRvIG9ubHkgY29udGFpbiBBU0NJSSBhbnl3YXkuXG5cdFx0XHRlcnJvcihcblx0XHRcdFx0J1RoZSBzdHJpbmcgdG8gYmUgZW5jb2RlZCBjb250YWlucyBjaGFyYWN0ZXJzIG91dHNpZGUgb2YgdGhlICcgK1xuXHRcdFx0XHQnTGF0aW4xIHJhbmdlLidcblx0XHRcdCk7XG5cdFx0fVxuXHRcdHZhciBwYWRkaW5nID0gaW5wdXQubGVuZ3RoICUgMztcblx0XHR2YXIgb3V0cHV0ID0gJyc7XG5cdFx0dmFyIHBvc2l0aW9uID0gLTE7XG5cdFx0dmFyIGE7XG5cdFx0dmFyIGI7XG5cdFx0dmFyIGM7XG5cdFx0dmFyIGJ1ZmZlcjtcblx0XHQvLyBNYWtlIHN1cmUgYW55IHBhZGRpbmcgaXMgaGFuZGxlZCBvdXRzaWRlIG9mIHRoZSBsb29wLlxuXHRcdHZhciBsZW5ndGggPSBpbnB1dC5sZW5ndGggLSBwYWRkaW5nO1xuXG5cdFx0d2hpbGUgKCsrcG9zaXRpb24gPCBsZW5ndGgpIHtcblx0XHRcdC8vIFJlYWQgdGhyZWUgYnl0ZXMsIGkuZS4gMjQgYml0cy5cblx0XHRcdGEgPSBpbnB1dC5jaGFyQ29kZUF0KHBvc2l0aW9uKSA8PCAxNjtcblx0XHRcdGIgPSBpbnB1dC5jaGFyQ29kZUF0KCsrcG9zaXRpb24pIDw8IDg7XG5cdFx0XHRjID0gaW5wdXQuY2hhckNvZGVBdCgrK3Bvc2l0aW9uKTtcblx0XHRcdGJ1ZmZlciA9IGEgKyBiICsgYztcblx0XHRcdC8vIFR1cm4gdGhlIDI0IGJpdHMgaW50byBmb3VyIGNodW5rcyBvZiA2IGJpdHMgZWFjaCwgYW5kIGFwcGVuZCB0aGVcblx0XHRcdC8vIG1hdGNoaW5nIGNoYXJhY3RlciBmb3IgZWFjaCBvZiB0aGVtIHRvIHRoZSBvdXRwdXQuXG5cdFx0XHRvdXRwdXQgKz0gKFxuXHRcdFx0XHRUQUJMRS5jaGFyQXQoYnVmZmVyID4+IDE4ICYgMHgzRikgK1xuXHRcdFx0XHRUQUJMRS5jaGFyQXQoYnVmZmVyID4+IDEyICYgMHgzRikgK1xuXHRcdFx0XHRUQUJMRS5jaGFyQXQoYnVmZmVyID4+IDYgJiAweDNGKSArXG5cdFx0XHRcdFRBQkxFLmNoYXJBdChidWZmZXIgJiAweDNGKVxuXHRcdFx0KTtcblx0XHR9XG5cblx0XHRpZiAocGFkZGluZyA9PSAyKSB7XG5cdFx0XHRhID0gaW5wdXQuY2hhckNvZGVBdChwb3NpdGlvbikgPDwgODtcblx0XHRcdGIgPSBpbnB1dC5jaGFyQ29kZUF0KCsrcG9zaXRpb24pO1xuXHRcdFx0YnVmZmVyID0gYSArIGI7XG5cdFx0XHRvdXRwdXQgKz0gKFxuXHRcdFx0XHRUQUJMRS5jaGFyQXQoYnVmZmVyID4+IDEwKSArXG5cdFx0XHRcdFRBQkxFLmNoYXJBdCgoYnVmZmVyID4+IDQpICYgMHgzRikgK1xuXHRcdFx0XHRUQUJMRS5jaGFyQXQoKGJ1ZmZlciA8PCAyKSAmIDB4M0YpICtcblx0XHRcdFx0Jz0nXG5cdFx0XHQpO1xuXHRcdH0gZWxzZSBpZiAocGFkZGluZyA9PSAxKSB7XG5cdFx0XHRidWZmZXIgPSBpbnB1dC5jaGFyQ29kZUF0KHBvc2l0aW9uKTtcblx0XHRcdG91dHB1dCArPSAoXG5cdFx0XHRcdFRBQkxFLmNoYXJBdChidWZmZXIgPj4gMikgK1xuXHRcdFx0XHRUQUJMRS5jaGFyQXQoKGJ1ZmZlciA8PCA0KSAmIDB4M0YpICtcblx0XHRcdFx0Jz09J1xuXHRcdFx0KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gb3V0cHV0O1xuXHR9O1xuXG5cdHZhciBiYXNlNjQgPSB7XG5cdFx0J2VuY29kZSc6IGVuY29kZSxcblx0XHQnZGVjb2RlJzogZGVjb2RlLFxuXHRcdCd2ZXJzaW9uJzogJzEuMC4wJ1xuXHR9O1xuXG5cdC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIHNwZWNpZmljIGNvbmRpdGlvbiBwYXR0ZXJuc1xuXHQvLyBsaWtlIHRoZSBmb2xsb3dpbmc6XG5cdGlmIChcblx0XHR0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2YgZGVmaW5lLmFtZCA9PSAnb2JqZWN0JyAmJlxuXHRcdGRlZmluZS5hbWRcblx0KSB7XG5cdFx0ZGVmaW5lKGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIGJhc2U2NDtcblx0XHR9KTtcblx0fVx0ZWxzZSBpZiAoZnJlZUV4cG9ydHMgJiYgIWZyZWVFeHBvcnRzLm5vZGVUeXBlKSB7XG5cdFx0aWYgKGZyZWVNb2R1bGUpIHsgLy8gaW4gTm9kZS5qcyBvciBSaW5nb0pTIHYwLjguMCtcblx0XHRcdGZyZWVNb2R1bGUuZXhwb3J0cyA9IGJhc2U2NDtcblx0XHR9IGVsc2UgeyAvLyBpbiBOYXJ3aGFsIG9yIFJpbmdvSlMgdjAuNy4wLVxuXHRcdFx0Zm9yICh2YXIga2V5IGluIGJhc2U2NCkge1xuXHRcdFx0XHRiYXNlNjQuaGFzT3duUHJvcGVydHkoa2V5KSAmJiAoZnJlZUV4cG9ydHNba2V5XSA9IGJhc2U2NFtrZXldKTtcblx0XHRcdH1cblx0XHR9XG5cdH0gZWxzZSB7IC8vIGluIFJoaW5vIG9yIGEgd2ViIGJyb3dzZXJcblx0XHRyb290LmJhc2U2NCA9IGJhc2U2NDtcblx0fVxuXG59KHRoaXMpKTtcbiIsInZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xudmFyIFN0cmVhbSA9IHJlcXVpcmUoJ3N0cmVhbScpLlN0cmVhbTtcbnZhciBEZWxheWVkU3RyZWFtID0gcmVxdWlyZSgnZGVsYXllZC1zdHJlYW0nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBDb21iaW5lZFN0cmVhbTtcbmZ1bmN0aW9uIENvbWJpbmVkU3RyZWFtKCkge1xuICB0aGlzLndyaXRhYmxlID0gZmFsc2U7XG4gIHRoaXMucmVhZGFibGUgPSB0cnVlO1xuICB0aGlzLmRhdGFTaXplID0gMDtcbiAgdGhpcy5tYXhEYXRhU2l6ZSA9IDIgKiAxMDI0ICogMTAyNDtcbiAgdGhpcy5wYXVzZVN0cmVhbXMgPSB0cnVlO1xuXG4gIHRoaXMuX3JlbGVhc2VkID0gZmFsc2U7XG4gIHRoaXMuX3N0cmVhbXMgPSBbXTtcbiAgdGhpcy5fY3VycmVudFN0cmVhbSA9IG51bGw7XG4gIHRoaXMuX2luc2lkZUxvb3AgPSBmYWxzZTtcbiAgdGhpcy5fcGVuZGluZ05leHQgPSBmYWxzZTtcbn1cbnV0aWwuaW5oZXJpdHMoQ29tYmluZWRTdHJlYW0sIFN0cmVhbSk7XG5cbkNvbWJpbmVkU3RyZWFtLmNyZWF0ZSA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgdmFyIGNvbWJpbmVkU3RyZWFtID0gbmV3IHRoaXMoKTtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgZm9yICh2YXIgb3B0aW9uIGluIG9wdGlvbnMpIHtcbiAgICBjb21iaW5lZFN0cmVhbVtvcHRpb25dID0gb3B0aW9uc1tvcHRpb25dO1xuICB9XG5cbiAgcmV0dXJuIGNvbWJpbmVkU3RyZWFtO1xufTtcblxuQ29tYmluZWRTdHJlYW0uaXNTdHJlYW1MaWtlID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gIHJldHVybiAodHlwZW9mIHN0cmVhbSAhPT0gJ2Z1bmN0aW9uJylcbiAgICAmJiAodHlwZW9mIHN0cmVhbSAhPT0gJ3N0cmluZycpXG4gICAgJiYgKHR5cGVvZiBzdHJlYW0gIT09ICdib29sZWFuJylcbiAgICAmJiAodHlwZW9mIHN0cmVhbSAhPT0gJ251bWJlcicpXG4gICAgJiYgKCFCdWZmZXIuaXNCdWZmZXIoc3RyZWFtKSk7XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUuYXBwZW5kID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gIHZhciBpc1N0cmVhbUxpa2UgPSBDb21iaW5lZFN0cmVhbS5pc1N0cmVhbUxpa2Uoc3RyZWFtKTtcblxuICBpZiAoaXNTdHJlYW1MaWtlKSB7XG4gICAgaWYgKCEoc3RyZWFtIGluc3RhbmNlb2YgRGVsYXllZFN0cmVhbSkpIHtcbiAgICAgIHZhciBuZXdTdHJlYW0gPSBEZWxheWVkU3RyZWFtLmNyZWF0ZShzdHJlYW0sIHtcbiAgICAgICAgbWF4RGF0YVNpemU6IEluZmluaXR5LFxuICAgICAgICBwYXVzZVN0cmVhbTogdGhpcy5wYXVzZVN0cmVhbXMsXG4gICAgICB9KTtcbiAgICAgIHN0cmVhbS5vbignZGF0YScsIHRoaXMuX2NoZWNrRGF0YVNpemUuYmluZCh0aGlzKSk7XG4gICAgICBzdHJlYW0gPSBuZXdTdHJlYW07XG4gICAgfVxuXG4gICAgdGhpcy5faGFuZGxlRXJyb3JzKHN0cmVhbSk7XG5cbiAgICBpZiAodGhpcy5wYXVzZVN0cmVhbXMpIHtcbiAgICAgIHN0cmVhbS5wYXVzZSgpO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMuX3N0cmVhbXMucHVzaChzdHJlYW0pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24oZGVzdCwgb3B0aW9ucykge1xuICBTdHJlYW0ucHJvdG90eXBlLnBpcGUuY2FsbCh0aGlzLCBkZXN0LCBvcHRpb25zKTtcbiAgdGhpcy5yZXN1bWUoKTtcbiAgcmV0dXJuIGRlc3Q7XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUuX2dldE5leHQgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5fY3VycmVudFN0cmVhbSA9IG51bGw7XG5cbiAgaWYgKHRoaXMuX2luc2lkZUxvb3ApIHtcbiAgICB0aGlzLl9wZW5kaW5nTmV4dCA9IHRydWU7XG4gICAgcmV0dXJuOyAvLyBkZWZlciBjYWxsXG4gIH1cblxuICB0aGlzLl9pbnNpZGVMb29wID0gdHJ1ZTtcbiAgdHJ5IHtcbiAgICBkbyB7XG4gICAgICB0aGlzLl9wZW5kaW5nTmV4dCA9IGZhbHNlO1xuICAgICAgdGhpcy5fcmVhbEdldE5leHQoKTtcbiAgICB9IHdoaWxlICh0aGlzLl9wZW5kaW5nTmV4dCk7XG4gIH0gZmluYWxseSB7XG4gICAgdGhpcy5faW5zaWRlTG9vcCA9IGZhbHNlO1xuICB9XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUuX3JlYWxHZXROZXh0ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBzdHJlYW0gPSB0aGlzLl9zdHJlYW1zLnNoaWZ0KCk7XG5cblxuICBpZiAodHlwZW9mIHN0cmVhbSA9PSAndW5kZWZpbmVkJykge1xuICAgIHRoaXMuZW5kKCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBzdHJlYW0gIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aGlzLl9waXBlTmV4dChzdHJlYW0pO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBnZXRTdHJlYW0gPSBzdHJlYW07XG4gIGdldFN0cmVhbShmdW5jdGlvbihzdHJlYW0pIHtcbiAgICB2YXIgaXNTdHJlYW1MaWtlID0gQ29tYmluZWRTdHJlYW0uaXNTdHJlYW1MaWtlKHN0cmVhbSk7XG4gICAgaWYgKGlzU3RyZWFtTGlrZSkge1xuICAgICAgc3RyZWFtLm9uKCdkYXRhJywgdGhpcy5fY2hlY2tEYXRhU2l6ZS5iaW5kKHRoaXMpKTtcbiAgICAgIHRoaXMuX2hhbmRsZUVycm9ycyhzdHJlYW0pO1xuICAgIH1cblxuICAgIHRoaXMuX3BpcGVOZXh0KHN0cmVhbSk7XG4gIH0uYmluZCh0aGlzKSk7XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUuX3BpcGVOZXh0ID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gIHRoaXMuX2N1cnJlbnRTdHJlYW0gPSBzdHJlYW07XG5cbiAgdmFyIGlzU3RyZWFtTGlrZSA9IENvbWJpbmVkU3RyZWFtLmlzU3RyZWFtTGlrZShzdHJlYW0pO1xuICBpZiAoaXNTdHJlYW1MaWtlKSB7XG4gICAgc3RyZWFtLm9uKCdlbmQnLCB0aGlzLl9nZXROZXh0LmJpbmQodGhpcykpO1xuICAgIHN0cmVhbS5waXBlKHRoaXMsIHtlbmQ6IGZhbHNlfSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHZhbHVlID0gc3RyZWFtO1xuICB0aGlzLndyaXRlKHZhbHVlKTtcbiAgdGhpcy5fZ2V0TmV4dCgpO1xufTtcblxuQ29tYmluZWRTdHJlYW0ucHJvdG90eXBlLl9oYW5kbGVFcnJvcnMgPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBzdHJlYW0ub24oJ2Vycm9yJywgZnVuY3Rpb24oZXJyKSB7XG4gICAgc2VsZi5fZW1pdEVycm9yKGVycik7XG4gIH0pO1xufTtcblxuQ29tYmluZWRTdHJlYW0ucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oZGF0YSkge1xuICB0aGlzLmVtaXQoJ2RhdGEnLCBkYXRhKTtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMucGF1c2VTdHJlYW1zKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYodGhpcy5wYXVzZVN0cmVhbXMgJiYgdGhpcy5fY3VycmVudFN0cmVhbSAmJiB0eXBlb2YodGhpcy5fY3VycmVudFN0cmVhbS5wYXVzZSkgPT0gJ2Z1bmN0aW9uJykgdGhpcy5fY3VycmVudFN0cmVhbS5wYXVzZSgpO1xuICB0aGlzLmVtaXQoJ3BhdXNlJyk7XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUucmVzdW1lID0gZnVuY3Rpb24oKSB7XG4gIGlmICghdGhpcy5fcmVsZWFzZWQpIHtcbiAgICB0aGlzLl9yZWxlYXNlZCA9IHRydWU7XG4gICAgdGhpcy53cml0YWJsZSA9IHRydWU7XG4gICAgdGhpcy5fZ2V0TmV4dCgpO1xuICB9XG5cbiAgaWYodGhpcy5wYXVzZVN0cmVhbXMgJiYgdGhpcy5fY3VycmVudFN0cmVhbSAmJiB0eXBlb2YodGhpcy5fY3VycmVudFN0cmVhbS5yZXN1bWUpID09ICdmdW5jdGlvbicpIHRoaXMuX2N1cnJlbnRTdHJlYW0ucmVzdW1lKCk7XG4gIHRoaXMuZW1pdCgncmVzdW1lJyk7XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX3Jlc2V0KCk7XG4gIHRoaXMuZW1pdCgnZW5kJyk7XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9yZXNldCgpO1xuICB0aGlzLmVtaXQoJ2Nsb3NlJyk7XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUuX3Jlc2V0ID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMud3JpdGFibGUgPSBmYWxzZTtcbiAgdGhpcy5fc3RyZWFtcyA9IFtdO1xuICB0aGlzLl9jdXJyZW50U3RyZWFtID0gbnVsbDtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5fY2hlY2tEYXRhU2l6ZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl91cGRhdGVEYXRhU2l6ZSgpO1xuICBpZiAodGhpcy5kYXRhU2l6ZSA8PSB0aGlzLm1heERhdGFTaXplKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIG1lc3NhZ2UgPVxuICAgICdEZWxheWVkU3RyZWFtI21heERhdGFTaXplIG9mICcgKyB0aGlzLm1heERhdGFTaXplICsgJyBieXRlcyBleGNlZWRlZC4nO1xuICB0aGlzLl9lbWl0RXJyb3IobmV3IEVycm9yKG1lc3NhZ2UpKTtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5fdXBkYXRlRGF0YVNpemUgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5kYXRhU2l6ZSA9IDA7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLl9zdHJlYW1zLmZvckVhY2goZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgaWYgKCFzdHJlYW0uZGF0YVNpemUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZWxmLmRhdGFTaXplICs9IHN0cmVhbS5kYXRhU2l6ZTtcbiAgfSk7XG5cbiAgaWYgKHRoaXMuX2N1cnJlbnRTdHJlYW0gJiYgdGhpcy5fY3VycmVudFN0cmVhbS5kYXRhU2l6ZSkge1xuICAgIHRoaXMuZGF0YVNpemUgKz0gdGhpcy5fY3VycmVudFN0cmVhbS5kYXRhU2l6ZTtcbiAgfVxufTtcblxuQ29tYmluZWRTdHJlYW0ucHJvdG90eXBlLl9lbWl0RXJyb3IgPSBmdW5jdGlvbihlcnIpIHtcbiAgdGhpcy5fcmVzZXQoKTtcbiAgdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG59O1xuIiwiLyogZXNsaW50LWVudiBicm93c2VyICovXG5cbi8qKlxuICogVGhpcyBpcyB0aGUgd2ViIGJyb3dzZXIgaW1wbGVtZW50YXRpb24gb2YgYGRlYnVnKClgLlxuICovXG5cbmV4cG9ydHMuZm9ybWF0QXJncyA9IGZvcm1hdEFyZ3M7XG5leHBvcnRzLnNhdmUgPSBzYXZlO1xuZXhwb3J0cy5sb2FkID0gbG9hZDtcbmV4cG9ydHMudXNlQ29sb3JzID0gdXNlQ29sb3JzO1xuZXhwb3J0cy5zdG9yYWdlID0gbG9jYWxzdG9yYWdlKCk7XG5leHBvcnRzLmRlc3Ryb3kgPSAoKCkgPT4ge1xuXHRsZXQgd2FybmVkID0gZmFsc2U7XG5cblx0cmV0dXJuICgpID0+IHtcblx0XHRpZiAoIXdhcm5lZCkge1xuXHRcdFx0d2FybmVkID0gdHJ1ZTtcblx0XHRcdGNvbnNvbGUud2FybignSW5zdGFuY2UgbWV0aG9kIGBkZWJ1Zy5kZXN0cm95KClgIGlzIGRlcHJlY2F0ZWQgYW5kIG5vIGxvbmdlciBkb2VzIGFueXRoaW5nLiBJdCB3aWxsIGJlIHJlbW92ZWQgaW4gdGhlIG5leHQgbWFqb3IgdmVyc2lvbiBvZiBgZGVidWdgLicpO1xuXHRcdH1cblx0fTtcbn0pKCk7XG5cbi8qKlxuICogQ29sb3JzLlxuICovXG5cbmV4cG9ydHMuY29sb3JzID0gW1xuXHQnIzAwMDBDQycsXG5cdCcjMDAwMEZGJyxcblx0JyMwMDMzQ0MnLFxuXHQnIzAwMzNGRicsXG5cdCcjMDA2NkNDJyxcblx0JyMwMDY2RkYnLFxuXHQnIzAwOTlDQycsXG5cdCcjMDA5OUZGJyxcblx0JyMwMENDMDAnLFxuXHQnIzAwQ0MzMycsXG5cdCcjMDBDQzY2Jyxcblx0JyMwMENDOTknLFxuXHQnIzAwQ0NDQycsXG5cdCcjMDBDQ0ZGJyxcblx0JyMzMzAwQ0MnLFxuXHQnIzMzMDBGRicsXG5cdCcjMzMzM0NDJyxcblx0JyMzMzMzRkYnLFxuXHQnIzMzNjZDQycsXG5cdCcjMzM2NkZGJyxcblx0JyMzMzk5Q0MnLFxuXHQnIzMzOTlGRicsXG5cdCcjMzNDQzAwJyxcblx0JyMzM0NDMzMnLFxuXHQnIzMzQ0M2NicsXG5cdCcjMzNDQzk5Jyxcblx0JyMzM0NDQ0MnLFxuXHQnIzMzQ0NGRicsXG5cdCcjNjYwMENDJyxcblx0JyM2NjAwRkYnLFxuXHQnIzY2MzNDQycsXG5cdCcjNjYzM0ZGJyxcblx0JyM2NkNDMDAnLFxuXHQnIzY2Q0MzMycsXG5cdCcjOTkwMENDJyxcblx0JyM5OTAwRkYnLFxuXHQnIzk5MzNDQycsXG5cdCcjOTkzM0ZGJyxcblx0JyM5OUNDMDAnLFxuXHQnIzk5Q0MzMycsXG5cdCcjQ0MwMDAwJyxcblx0JyNDQzAwMzMnLFxuXHQnI0NDMDA2NicsXG5cdCcjQ0MwMDk5Jyxcblx0JyNDQzAwQ0MnLFxuXHQnI0NDMDBGRicsXG5cdCcjQ0MzMzAwJyxcblx0JyNDQzMzMzMnLFxuXHQnI0NDMzM2NicsXG5cdCcjQ0MzMzk5Jyxcblx0JyNDQzMzQ0MnLFxuXHQnI0NDMzNGRicsXG5cdCcjQ0M2NjAwJyxcblx0JyNDQzY2MzMnLFxuXHQnI0NDOTkwMCcsXG5cdCcjQ0M5OTMzJyxcblx0JyNDQ0NDMDAnLFxuXHQnI0NDQ0MzMycsXG5cdCcjRkYwMDAwJyxcblx0JyNGRjAwMzMnLFxuXHQnI0ZGMDA2NicsXG5cdCcjRkYwMDk5Jyxcblx0JyNGRjAwQ0MnLFxuXHQnI0ZGMDBGRicsXG5cdCcjRkYzMzAwJyxcblx0JyNGRjMzMzMnLFxuXHQnI0ZGMzM2NicsXG5cdCcjRkYzMzk5Jyxcblx0JyNGRjMzQ0MnLFxuXHQnI0ZGMzNGRicsXG5cdCcjRkY2NjAwJyxcblx0JyNGRjY2MzMnLFxuXHQnI0ZGOTkwMCcsXG5cdCcjRkY5OTMzJyxcblx0JyNGRkNDMDAnLFxuXHQnI0ZGQ0MzMydcbl07XG5cbi8qKlxuICogQ3VycmVudGx5IG9ubHkgV2ViS2l0LWJhc2VkIFdlYiBJbnNwZWN0b3JzLCBGaXJlZm94ID49IHYzMSxcbiAqIGFuZCB0aGUgRmlyZWJ1ZyBleHRlbnNpb24gKGFueSBGaXJlZm94IHZlcnNpb24pIGFyZSBrbm93blxuICogdG8gc3VwcG9ydCBcIiVjXCIgQ1NTIGN1c3RvbWl6YXRpb25zLlxuICpcbiAqIFRPRE86IGFkZCBhIGBsb2NhbFN0b3JhZ2VgIHZhcmlhYmxlIHRvIGV4cGxpY2l0bHkgZW5hYmxlL2Rpc2FibGUgY29sb3JzXG4gKi9cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNvbXBsZXhpdHlcbmZ1bmN0aW9uIHVzZUNvbG9ycygpIHtcblx0Ly8gTkI6IEluIGFuIEVsZWN0cm9uIHByZWxvYWQgc2NyaXB0LCBkb2N1bWVudCB3aWxsIGJlIGRlZmluZWQgYnV0IG5vdCBmdWxseVxuXHQvLyBpbml0aWFsaXplZC4gU2luY2Ugd2Uga25vdyB3ZSdyZSBpbiBDaHJvbWUsIHdlJ2xsIGp1c3QgZGV0ZWN0IHRoaXMgY2FzZVxuXHQvLyBleHBsaWNpdGx5XG5cdGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cucHJvY2VzcyAmJiAod2luZG93LnByb2Nlc3MudHlwZSA9PT0gJ3JlbmRlcmVyJyB8fCB3aW5kb3cucHJvY2Vzcy5fX253anMpKSB7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHQvLyBJbnRlcm5ldCBFeHBsb3JlciBhbmQgRWRnZSBkbyBub3Qgc3VwcG9ydCBjb2xvcnMuXG5cdGlmICh0eXBlb2YgbmF2aWdhdG9yICE9PSAndW5kZWZpbmVkJyAmJiBuYXZpZ2F0b3IudXNlckFnZW50ICYmIG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKS5tYXRjaCgvKGVkZ2V8dHJpZGVudClcXC8oXFxkKykvKSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdC8vIElzIHdlYmtpdD8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMTY0NTk2MDYvMzc2NzczXG5cdC8vIGRvY3VtZW50IGlzIHVuZGVmaW5lZCBpbiByZWFjdC1uYXRpdmU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC1uYXRpdmUvcHVsbC8xNjMyXG5cdHJldHVybiAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyAmJiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZS5XZWJraXRBcHBlYXJhbmNlKSB8fFxuXHRcdC8vIElzIGZpcmVidWc/IGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzM5ODEyMC8zNzY3NzNcblx0XHQodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93LmNvbnNvbGUgJiYgKHdpbmRvdy5jb25zb2xlLmZpcmVidWcgfHwgKHdpbmRvdy5jb25zb2xlLmV4Y2VwdGlvbiAmJiB3aW5kb3cuY29uc29sZS50YWJsZSkpKSB8fFxuXHRcdC8vIElzIGZpcmVmb3ggPj0gdjMxP1xuXHRcdC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvVG9vbHMvV2ViX0NvbnNvbGUjU3R5bGluZ19tZXNzYWdlc1xuXHRcdCh0eXBlb2YgbmF2aWdhdG9yICE9PSAndW5kZWZpbmVkJyAmJiBuYXZpZ2F0b3IudXNlckFnZW50ICYmIG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKS5tYXRjaCgvZmlyZWZveFxcLyhcXGQrKS8pICYmIHBhcnNlSW50KFJlZ0V4cC4kMSwgMTApID49IDMxKSB8fFxuXHRcdC8vIERvdWJsZSBjaGVjayB3ZWJraXQgaW4gdXNlckFnZW50IGp1c3QgaW4gY2FzZSB3ZSBhcmUgaW4gYSB3b3JrZXJcblx0XHQodHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgbmF2aWdhdG9yLnVzZXJBZ2VudCAmJiBuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkubWF0Y2goL2FwcGxld2Via2l0XFwvKFxcZCspLykpO1xufVxuXG4vKipcbiAqIENvbG9yaXplIGxvZyBhcmd1bWVudHMgaWYgZW5hYmxlZC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGZvcm1hdEFyZ3MoYXJncykge1xuXHRhcmdzWzBdID0gKHRoaXMudXNlQ29sb3JzID8gJyVjJyA6ICcnKSArXG5cdFx0dGhpcy5uYW1lc3BhY2UgK1xuXHRcdCh0aGlzLnVzZUNvbG9ycyA/ICcgJWMnIDogJyAnKSArXG5cdFx0YXJnc1swXSArXG5cdFx0KHRoaXMudXNlQ29sb3JzID8gJyVjICcgOiAnICcpICtcblx0XHQnKycgKyBtb2R1bGUuZXhwb3J0cy5odW1hbml6ZSh0aGlzLmRpZmYpO1xuXG5cdGlmICghdGhpcy51c2VDb2xvcnMpIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHRjb25zdCBjID0gJ2NvbG9yOiAnICsgdGhpcy5jb2xvcjtcblx0YXJncy5zcGxpY2UoMSwgMCwgYywgJ2NvbG9yOiBpbmhlcml0Jyk7XG5cblx0Ly8gVGhlIGZpbmFsIFwiJWNcIiBpcyBzb21ld2hhdCB0cmlja3ksIGJlY2F1c2UgdGhlcmUgY291bGQgYmUgb3RoZXJcblx0Ly8gYXJndW1lbnRzIHBhc3NlZCBlaXRoZXIgYmVmb3JlIG9yIGFmdGVyIHRoZSAlYywgc28gd2UgbmVlZCB0b1xuXHQvLyBmaWd1cmUgb3V0IHRoZSBjb3JyZWN0IGluZGV4IHRvIGluc2VydCB0aGUgQ1NTIGludG9cblx0bGV0IGluZGV4ID0gMDtcblx0bGV0IGxhc3RDID0gMDtcblx0YXJnc1swXS5yZXBsYWNlKC8lW2EtekEtWiVdL2csIG1hdGNoID0+IHtcblx0XHRpZiAobWF0Y2ggPT09ICclJScpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0aW5kZXgrKztcblx0XHRpZiAobWF0Y2ggPT09ICclYycpIHtcblx0XHRcdC8vIFdlIG9ubHkgYXJlIGludGVyZXN0ZWQgaW4gdGhlICpsYXN0KiAlY1xuXHRcdFx0Ly8gKHRoZSB1c2VyIG1heSBoYXZlIHByb3ZpZGVkIHRoZWlyIG93bilcblx0XHRcdGxhc3RDID0gaW5kZXg7XG5cdFx0fVxuXHR9KTtcblxuXHRhcmdzLnNwbGljZShsYXN0QywgMCwgYyk7XG59XG5cbi8qKlxuICogSW52b2tlcyBgY29uc29sZS5kZWJ1ZygpYCB3aGVuIGF2YWlsYWJsZS5cbiAqIE5vLW9wIHdoZW4gYGNvbnNvbGUuZGVidWdgIGlzIG5vdCBhIFwiZnVuY3Rpb25cIi5cbiAqIElmIGBjb25zb2xlLmRlYnVnYCBpcyBub3QgYXZhaWxhYmxlLCBmYWxscyBiYWNrXG4gKiB0byBgY29uc29sZS5sb2dgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cbmV4cG9ydHMubG9nID0gY29uc29sZS5kZWJ1ZyB8fCBjb25zb2xlLmxvZyB8fCAoKCkgPT4ge30pO1xuXG4vKipcbiAqIFNhdmUgYG5hbWVzcGFjZXNgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lc3BhY2VzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gc2F2ZShuYW1lc3BhY2VzKSB7XG5cdHRyeSB7XG5cdFx0aWYgKG5hbWVzcGFjZXMpIHtcblx0XHRcdGV4cG9ydHMuc3RvcmFnZS5zZXRJdGVtKCdkZWJ1ZycsIG5hbWVzcGFjZXMpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRleHBvcnRzLnN0b3JhZ2UucmVtb3ZlSXRlbSgnZGVidWcnKTtcblx0XHR9XG5cdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0Ly8gU3dhbGxvd1xuXHRcdC8vIFhYWCAoQFFpeC0pIHNob3VsZCB3ZSBiZSBsb2dnaW5nIHRoZXNlP1xuXHR9XG59XG5cbi8qKlxuICogTG9hZCBgbmFtZXNwYWNlc2AuXG4gKlxuICogQHJldHVybiB7U3RyaW5nfSByZXR1cm5zIHRoZSBwcmV2aW91c2x5IHBlcnNpc3RlZCBkZWJ1ZyBtb2Rlc1xuICogQGFwaSBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGxvYWQoKSB7XG5cdGxldCByO1xuXHR0cnkge1xuXHRcdHIgPSBleHBvcnRzLnN0b3JhZ2UuZ2V0SXRlbSgnZGVidWcnKTtcblx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHQvLyBTd2FsbG93XG5cdFx0Ly8gWFhYIChAUWl4LSkgc2hvdWxkIHdlIGJlIGxvZ2dpbmcgdGhlc2U/XG5cdH1cblxuXHQvLyBJZiBkZWJ1ZyBpc24ndCBzZXQgaW4gTFMsIGFuZCB3ZSdyZSBpbiBFbGVjdHJvbiwgdHJ5IHRvIGxvYWQgJERFQlVHXG5cdGlmICghciAmJiB0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgJ2VudicgaW4gcHJvY2Vzcykge1xuXHRcdHIgPSBwcm9jZXNzLmVudi5ERUJVRztcblx0fVxuXG5cdHJldHVybiByO1xufVxuXG4vKipcbiAqIExvY2Fsc3RvcmFnZSBhdHRlbXB0cyB0byByZXR1cm4gdGhlIGxvY2Fsc3RvcmFnZS5cbiAqXG4gKiBUaGlzIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHNhZmFyaSB0aHJvd3NcbiAqIHdoZW4gYSB1c2VyIGRpc2FibGVzIGNvb2tpZXMvbG9jYWxzdG9yYWdlXG4gKiBhbmQgeW91IGF0dGVtcHQgdG8gYWNjZXNzIGl0LlxuICpcbiAqIEByZXR1cm4ge0xvY2FsU3RvcmFnZX1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGxvY2Fsc3RvcmFnZSgpIHtcblx0dHJ5IHtcblx0XHQvLyBUVk1MS2l0IChBcHBsZSBUViBKUyBSdW50aW1lKSBkb2VzIG5vdCBoYXZlIGEgd2luZG93IG9iamVjdCwganVzdCBsb2NhbFN0b3JhZ2UgaW4gdGhlIGdsb2JhbCBjb250ZXh0XG5cdFx0Ly8gVGhlIEJyb3dzZXIgYWxzbyBoYXMgbG9jYWxTdG9yYWdlIGluIHRoZSBnbG9iYWwgY29udGV4dC5cblx0XHRyZXR1cm4gbG9jYWxTdG9yYWdlO1xuXHR9IGNhdGNoIChlcnJvcikge1xuXHRcdC8vIFN3YWxsb3dcblx0XHQvLyBYWFggKEBRaXgtKSBzaG91bGQgd2UgYmUgbG9nZ2luZyB0aGVzZT9cblx0fVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vY29tbW9uJykoZXhwb3J0cyk7XG5cbmNvbnN0IHtmb3JtYXR0ZXJzfSA9IG1vZHVsZS5leHBvcnRzO1xuXG4vKipcbiAqIE1hcCAlaiB0byBgSlNPTi5zdHJpbmdpZnkoKWAsIHNpbmNlIG5vIFdlYiBJbnNwZWN0b3JzIGRvIHRoYXQgYnkgZGVmYXVsdC5cbiAqL1xuXG5mb3JtYXR0ZXJzLmogPSBmdW5jdGlvbiAodikge1xuXHR0cnkge1xuXHRcdHJldHVybiBKU09OLnN0cmluZ2lmeSh2KTtcblx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRyZXR1cm4gJ1tVbmV4cGVjdGVkSlNPTlBhcnNlRXJyb3JdOiAnICsgZXJyb3IubWVzc2FnZTtcblx0fVxufTtcbiIsIlxuLyoqXG4gKiBUaGlzIGlzIHRoZSBjb21tb24gbG9naWMgZm9yIGJvdGggdGhlIE5vZGUuanMgYW5kIHdlYiBicm93c2VyXG4gKiBpbXBsZW1lbnRhdGlvbnMgb2YgYGRlYnVnKClgLlxuICovXG5cbmZ1bmN0aW9uIHNldHVwKGVudikge1xuXHRjcmVhdGVEZWJ1Zy5kZWJ1ZyA9IGNyZWF0ZURlYnVnO1xuXHRjcmVhdGVEZWJ1Zy5kZWZhdWx0ID0gY3JlYXRlRGVidWc7XG5cdGNyZWF0ZURlYnVnLmNvZXJjZSA9IGNvZXJjZTtcblx0Y3JlYXRlRGVidWcuZGlzYWJsZSA9IGRpc2FibGU7XG5cdGNyZWF0ZURlYnVnLmVuYWJsZSA9IGVuYWJsZTtcblx0Y3JlYXRlRGVidWcuZW5hYmxlZCA9IGVuYWJsZWQ7XG5cdGNyZWF0ZURlYnVnLmh1bWFuaXplID0gcmVxdWlyZSgnbXMnKTtcblx0Y3JlYXRlRGVidWcuZGVzdHJveSA9IGRlc3Ryb3k7XG5cblx0T2JqZWN0LmtleXMoZW52KS5mb3JFYWNoKGtleSA9PiB7XG5cdFx0Y3JlYXRlRGVidWdba2V5XSA9IGVudltrZXldO1xuXHR9KTtcblxuXHQvKipcblx0KiBUaGUgY3VycmVudGx5IGFjdGl2ZSBkZWJ1ZyBtb2RlIG5hbWVzLCBhbmQgbmFtZXMgdG8gc2tpcC5cblx0Ki9cblxuXHRjcmVhdGVEZWJ1Zy5uYW1lcyA9IFtdO1xuXHRjcmVhdGVEZWJ1Zy5za2lwcyA9IFtdO1xuXG5cdC8qKlxuXHQqIE1hcCBvZiBzcGVjaWFsIFwiJW5cIiBoYW5kbGluZyBmdW5jdGlvbnMsIGZvciB0aGUgZGVidWcgXCJmb3JtYXRcIiBhcmd1bWVudC5cblx0KlxuXHQqIFZhbGlkIGtleSBuYW1lcyBhcmUgYSBzaW5nbGUsIGxvd2VyIG9yIHVwcGVyLWNhc2UgbGV0dGVyLCBpLmUuIFwiblwiIGFuZCBcIk5cIi5cblx0Ki9cblx0Y3JlYXRlRGVidWcuZm9ybWF0dGVycyA9IHt9O1xuXG5cdC8qKlxuXHQqIFNlbGVjdHMgYSBjb2xvciBmb3IgYSBkZWJ1ZyBuYW1lc3BhY2Vcblx0KiBAcGFyYW0ge1N0cmluZ30gbmFtZXNwYWNlIFRoZSBuYW1lc3BhY2Ugc3RyaW5nIGZvciB0aGUgZGVidWcgaW5zdGFuY2UgdG8gYmUgY29sb3JlZFxuXHQqIEByZXR1cm4ge051bWJlcnxTdHJpbmd9IEFuIEFOU0kgY29sb3IgY29kZSBmb3IgdGhlIGdpdmVuIG5hbWVzcGFjZVxuXHQqIEBhcGkgcHJpdmF0ZVxuXHQqL1xuXHRmdW5jdGlvbiBzZWxlY3RDb2xvcihuYW1lc3BhY2UpIHtcblx0XHRsZXQgaGFzaCA9IDA7XG5cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IG5hbWVzcGFjZS5sZW5ndGg7IGkrKykge1xuXHRcdFx0aGFzaCA9ICgoaGFzaCA8PCA1KSAtIGhhc2gpICsgbmFtZXNwYWNlLmNoYXJDb2RlQXQoaSk7XG5cdFx0XHRoYXNoIHw9IDA7IC8vIENvbnZlcnQgdG8gMzJiaXQgaW50ZWdlclxuXHRcdH1cblxuXHRcdHJldHVybiBjcmVhdGVEZWJ1Zy5jb2xvcnNbTWF0aC5hYnMoaGFzaCkgJSBjcmVhdGVEZWJ1Zy5jb2xvcnMubGVuZ3RoXTtcblx0fVxuXHRjcmVhdGVEZWJ1Zy5zZWxlY3RDb2xvciA9IHNlbGVjdENvbG9yO1xuXG5cdC8qKlxuXHQqIENyZWF0ZSBhIGRlYnVnZ2VyIHdpdGggdGhlIGdpdmVuIGBuYW1lc3BhY2VgLlxuXHQqXG5cdCogQHBhcmFtIHtTdHJpbmd9IG5hbWVzcGFjZVxuXHQqIEByZXR1cm4ge0Z1bmN0aW9ufVxuXHQqIEBhcGkgcHVibGljXG5cdCovXG5cdGZ1bmN0aW9uIGNyZWF0ZURlYnVnKG5hbWVzcGFjZSkge1xuXHRcdGxldCBwcmV2VGltZTtcblx0XHRsZXQgZW5hYmxlT3ZlcnJpZGUgPSBudWxsO1xuXHRcdGxldCBuYW1lc3BhY2VzQ2FjaGU7XG5cdFx0bGV0IGVuYWJsZWRDYWNoZTtcblxuXHRcdGZ1bmN0aW9uIGRlYnVnKC4uLmFyZ3MpIHtcblx0XHRcdC8vIERpc2FibGVkP1xuXHRcdFx0aWYgKCFkZWJ1Zy5lbmFibGVkKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Y29uc3Qgc2VsZiA9IGRlYnVnO1xuXG5cdFx0XHQvLyBTZXQgYGRpZmZgIHRpbWVzdGFtcFxuXHRcdFx0Y29uc3QgY3VyciA9IE51bWJlcihuZXcgRGF0ZSgpKTtcblx0XHRcdGNvbnN0IG1zID0gY3VyciAtIChwcmV2VGltZSB8fCBjdXJyKTtcblx0XHRcdHNlbGYuZGlmZiA9IG1zO1xuXHRcdFx0c2VsZi5wcmV2ID0gcHJldlRpbWU7XG5cdFx0XHRzZWxmLmN1cnIgPSBjdXJyO1xuXHRcdFx0cHJldlRpbWUgPSBjdXJyO1xuXG5cdFx0XHRhcmdzWzBdID0gY3JlYXRlRGVidWcuY29lcmNlKGFyZ3NbMF0pO1xuXG5cdFx0XHRpZiAodHlwZW9mIGFyZ3NbMF0gIT09ICdzdHJpbmcnKSB7XG5cdFx0XHRcdC8vIEFueXRoaW5nIGVsc2UgbGV0J3MgaW5zcGVjdCB3aXRoICVPXG5cdFx0XHRcdGFyZ3MudW5zaGlmdCgnJU8nKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQXBwbHkgYW55IGBmb3JtYXR0ZXJzYCB0cmFuc2Zvcm1hdGlvbnNcblx0XHRcdGxldCBpbmRleCA9IDA7XG5cdFx0XHRhcmdzWzBdID0gYXJnc1swXS5yZXBsYWNlKC8lKFthLXpBLVolXSkvZywgKG1hdGNoLCBmb3JtYXQpID0+IHtcblx0XHRcdFx0Ly8gSWYgd2UgZW5jb3VudGVyIGFuIGVzY2FwZWQgJSB0aGVuIGRvbid0IGluY3JlYXNlIHRoZSBhcnJheSBpbmRleFxuXHRcdFx0XHRpZiAobWF0Y2ggPT09ICclJScpIHtcblx0XHRcdFx0XHRyZXR1cm4gJyUnO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGluZGV4Kys7XG5cdFx0XHRcdGNvbnN0IGZvcm1hdHRlciA9IGNyZWF0ZURlYnVnLmZvcm1hdHRlcnNbZm9ybWF0XTtcblx0XHRcdFx0aWYgKHR5cGVvZiBmb3JtYXR0ZXIgPT09ICdmdW5jdGlvbicpIHtcblx0XHRcdFx0XHRjb25zdCB2YWwgPSBhcmdzW2luZGV4XTtcblx0XHRcdFx0XHRtYXRjaCA9IGZvcm1hdHRlci5jYWxsKHNlbGYsIHZhbCk7XG5cblx0XHRcdFx0XHQvLyBOb3cgd2UgbmVlZCB0byByZW1vdmUgYGFyZ3NbaW5kZXhdYCBzaW5jZSBpdCdzIGlubGluZWQgaW4gdGhlIGBmb3JtYXRgXG5cdFx0XHRcdFx0YXJncy5zcGxpY2UoaW5kZXgsIDEpO1xuXHRcdFx0XHRcdGluZGV4LS07XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIG1hdGNoO1xuXHRcdFx0fSk7XG5cblx0XHRcdC8vIEFwcGx5IGVudi1zcGVjaWZpYyBmb3JtYXR0aW5nIChjb2xvcnMsIGV0Yy4pXG5cdFx0XHRjcmVhdGVEZWJ1Zy5mb3JtYXRBcmdzLmNhbGwoc2VsZiwgYXJncyk7XG5cblx0XHRcdGNvbnN0IGxvZ0ZuID0gc2VsZi5sb2cgfHwgY3JlYXRlRGVidWcubG9nO1xuXHRcdFx0bG9nRm4uYXBwbHkoc2VsZiwgYXJncyk7XG5cdFx0fVxuXG5cdFx0ZGVidWcubmFtZXNwYWNlID0gbmFtZXNwYWNlO1xuXHRcdGRlYnVnLnVzZUNvbG9ycyA9IGNyZWF0ZURlYnVnLnVzZUNvbG9ycygpO1xuXHRcdGRlYnVnLmNvbG9yID0gY3JlYXRlRGVidWcuc2VsZWN0Q29sb3IobmFtZXNwYWNlKTtcblx0XHRkZWJ1Zy5leHRlbmQgPSBleHRlbmQ7XG5cdFx0ZGVidWcuZGVzdHJveSA9IGNyZWF0ZURlYnVnLmRlc3Ryb3k7IC8vIFhYWCBUZW1wb3JhcnkuIFdpbGwgYmUgcmVtb3ZlZCBpbiB0aGUgbmV4dCBtYWpvciByZWxlYXNlLlxuXG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGRlYnVnLCAnZW5hYmxlZCcsIHtcblx0XHRcdGVudW1lcmFibGU6IHRydWUsXG5cdFx0XHRjb25maWd1cmFibGU6IGZhbHNlLFxuXHRcdFx0Z2V0OiAoKSA9PiB7XG5cdFx0XHRcdGlmIChlbmFibGVPdmVycmlkZSAhPT0gbnVsbCkge1xuXHRcdFx0XHRcdHJldHVybiBlbmFibGVPdmVycmlkZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAobmFtZXNwYWNlc0NhY2hlICE9PSBjcmVhdGVEZWJ1Zy5uYW1lc3BhY2VzKSB7XG5cdFx0XHRcdFx0bmFtZXNwYWNlc0NhY2hlID0gY3JlYXRlRGVidWcubmFtZXNwYWNlcztcblx0XHRcdFx0XHRlbmFibGVkQ2FjaGUgPSBjcmVhdGVEZWJ1Zy5lbmFibGVkKG5hbWVzcGFjZSk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gZW5hYmxlZENhY2hlO1xuXHRcdFx0fSxcblx0XHRcdHNldDogdiA9PiB7XG5cdFx0XHRcdGVuYWJsZU92ZXJyaWRlID0gdjtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIEVudi1zcGVjaWZpYyBpbml0aWFsaXphdGlvbiBsb2dpYyBmb3IgZGVidWcgaW5zdGFuY2VzXG5cdFx0aWYgKHR5cGVvZiBjcmVhdGVEZWJ1Zy5pbml0ID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHRjcmVhdGVEZWJ1Zy5pbml0KGRlYnVnKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZGVidWc7XG5cdH1cblxuXHRmdW5jdGlvbiBleHRlbmQobmFtZXNwYWNlLCBkZWxpbWl0ZXIpIHtcblx0XHRjb25zdCBuZXdEZWJ1ZyA9IGNyZWF0ZURlYnVnKHRoaXMubmFtZXNwYWNlICsgKHR5cGVvZiBkZWxpbWl0ZXIgPT09ICd1bmRlZmluZWQnID8gJzonIDogZGVsaW1pdGVyKSArIG5hbWVzcGFjZSk7XG5cdFx0bmV3RGVidWcubG9nID0gdGhpcy5sb2c7XG5cdFx0cmV0dXJuIG5ld0RlYnVnO1xuXHR9XG5cblx0LyoqXG5cdCogRW5hYmxlcyBhIGRlYnVnIG1vZGUgYnkgbmFtZXNwYWNlcy4gVGhpcyBjYW4gaW5jbHVkZSBtb2Rlc1xuXHQqIHNlcGFyYXRlZCBieSBhIGNvbG9uIGFuZCB3aWxkY2FyZHMuXG5cdCpcblx0KiBAcGFyYW0ge1N0cmluZ30gbmFtZXNwYWNlc1xuXHQqIEBhcGkgcHVibGljXG5cdCovXG5cdGZ1bmN0aW9uIGVuYWJsZShuYW1lc3BhY2VzKSB7XG5cdFx0Y3JlYXRlRGVidWcuc2F2ZShuYW1lc3BhY2VzKTtcblx0XHRjcmVhdGVEZWJ1Zy5uYW1lc3BhY2VzID0gbmFtZXNwYWNlcztcblxuXHRcdGNyZWF0ZURlYnVnLm5hbWVzID0gW107XG5cdFx0Y3JlYXRlRGVidWcuc2tpcHMgPSBbXTtcblxuXHRcdGxldCBpO1xuXHRcdGNvbnN0IHNwbGl0ID0gKHR5cGVvZiBuYW1lc3BhY2VzID09PSAnc3RyaW5nJyA/IG5hbWVzcGFjZXMgOiAnJykuc3BsaXQoL1tcXHMsXSsvKTtcblx0XHRjb25zdCBsZW4gPSBzcGxpdC5sZW5ndGg7XG5cblx0XHRmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcblx0XHRcdGlmICghc3BsaXRbaV0pIHtcblx0XHRcdFx0Ly8gaWdub3JlIGVtcHR5IHN0cmluZ3Ncblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdG5hbWVzcGFjZXMgPSBzcGxpdFtpXS5yZXBsYWNlKC9cXCovZywgJy4qPycpO1xuXG5cdFx0XHRpZiAobmFtZXNwYWNlc1swXSA9PT0gJy0nKSB7XG5cdFx0XHRcdGNyZWF0ZURlYnVnLnNraXBzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzLnNsaWNlKDEpICsgJyQnKSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjcmVhdGVEZWJ1Zy5uYW1lcy5wdXNoKG5ldyBSZWdFeHAoJ14nICsgbmFtZXNwYWNlcyArICckJykpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQqIERpc2FibGUgZGVidWcgb3V0cHV0LlxuXHQqXG5cdCogQHJldHVybiB7U3RyaW5nfSBuYW1lc3BhY2VzXG5cdCogQGFwaSBwdWJsaWNcblx0Ki9cblx0ZnVuY3Rpb24gZGlzYWJsZSgpIHtcblx0XHRjb25zdCBuYW1lc3BhY2VzID0gW1xuXHRcdFx0Li4uY3JlYXRlRGVidWcubmFtZXMubWFwKHRvTmFtZXNwYWNlKSxcblx0XHRcdC4uLmNyZWF0ZURlYnVnLnNraXBzLm1hcCh0b05hbWVzcGFjZSkubWFwKG5hbWVzcGFjZSA9PiAnLScgKyBuYW1lc3BhY2UpXG5cdFx0XS5qb2luKCcsJyk7XG5cdFx0Y3JlYXRlRGVidWcuZW5hYmxlKCcnKTtcblx0XHRyZXR1cm4gbmFtZXNwYWNlcztcblx0fVxuXG5cdC8qKlxuXHQqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gbW9kZSBuYW1lIGlzIGVuYWJsZWQsIGZhbHNlIG90aGVyd2lzZS5cblx0KlxuXHQqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG5cdCogQHJldHVybiB7Qm9vbGVhbn1cblx0KiBAYXBpIHB1YmxpY1xuXHQqL1xuXHRmdW5jdGlvbiBlbmFibGVkKG5hbWUpIHtcblx0XHRpZiAobmFtZVtuYW1lLmxlbmd0aCAtIDFdID09PSAnKicpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdGxldCBpO1xuXHRcdGxldCBsZW47XG5cblx0XHRmb3IgKGkgPSAwLCBsZW4gPSBjcmVhdGVEZWJ1Zy5za2lwcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuXHRcdFx0aWYgKGNyZWF0ZURlYnVnLnNraXBzW2ldLnRlc3QobmFtZSkpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGZvciAoaSA9IDAsIGxlbiA9IGNyZWF0ZURlYnVnLm5hbWVzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG5cdFx0XHRpZiAoY3JlYXRlRGVidWcubmFtZXNbaV0udGVzdChuYW1lKSkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0KiBDb252ZXJ0IHJlZ2V4cCB0byBuYW1lc3BhY2Vcblx0KlxuXHQqIEBwYXJhbSB7UmVnRXhwfSByZWd4ZXBcblx0KiBAcmV0dXJuIHtTdHJpbmd9IG5hbWVzcGFjZVxuXHQqIEBhcGkgcHJpdmF0ZVxuXHQqL1xuXHRmdW5jdGlvbiB0b05hbWVzcGFjZShyZWdleHApIHtcblx0XHRyZXR1cm4gcmVnZXhwLnRvU3RyaW5nKClcblx0XHRcdC5zdWJzdHJpbmcoMiwgcmVnZXhwLnRvU3RyaW5nKCkubGVuZ3RoIC0gMilcblx0XHRcdC5yZXBsYWNlKC9cXC5cXCpcXD8kLywgJyonKTtcblx0fVxuXG5cdC8qKlxuXHQqIENvZXJjZSBgdmFsYC5cblx0KlxuXHQqIEBwYXJhbSB7TWl4ZWR9IHZhbFxuXHQqIEByZXR1cm4ge01peGVkfVxuXHQqIEBhcGkgcHJpdmF0ZVxuXHQqL1xuXHRmdW5jdGlvbiBjb2VyY2UodmFsKSB7XG5cdFx0aWYgKHZhbCBpbnN0YW5jZW9mIEVycm9yKSB7XG5cdFx0XHRyZXR1cm4gdmFsLnN0YWNrIHx8IHZhbC5tZXNzYWdlO1xuXHRcdH1cblx0XHRyZXR1cm4gdmFsO1xuXHR9XG5cblx0LyoqXG5cdCogWFhYIERPIE5PVCBVU0UuIFRoaXMgaXMgYSB0ZW1wb3Jhcnkgc3R1YiBmdW5jdGlvbi5cblx0KiBYWFggSXQgV0lMTCBiZSByZW1vdmVkIGluIHRoZSBuZXh0IG1ham9yIHJlbGVhc2UuXG5cdCovXG5cdGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG5cdFx0Y29uc29sZS53YXJuKCdJbnN0YW5jZSBtZXRob2QgYGRlYnVnLmRlc3Ryb3koKWAgaXMgZGVwcmVjYXRlZCBhbmQgbm8gbG9uZ2VyIGRvZXMgYW55dGhpbmcuIEl0IHdpbGwgYmUgcmVtb3ZlZCBpbiB0aGUgbmV4dCBtYWpvciB2ZXJzaW9uIG9mIGBkZWJ1Z2AuJyk7XG5cdH1cblxuXHRjcmVhdGVEZWJ1Zy5lbmFibGUoY3JlYXRlRGVidWcubG9hZCgpKTtcblxuXHRyZXR1cm4gY3JlYXRlRGVidWc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2V0dXA7XG4iLCIvKipcbiAqIERldGVjdCBFbGVjdHJvbiByZW5kZXJlciAvIG53anMgcHJvY2Vzcywgd2hpY2ggaXMgbm9kZSwgYnV0IHdlIHNob3VsZFxuICogdHJlYXQgYXMgYSBicm93c2VyLlxuICovXG5cbmlmICh0eXBlb2YgcHJvY2VzcyA9PT0gJ3VuZGVmaW5lZCcgfHwgcHJvY2Vzcy50eXBlID09PSAncmVuZGVyZXInIHx8IHByb2Nlc3MuYnJvd3NlciA9PT0gdHJ1ZSB8fCBwcm9jZXNzLl9fbndqcykge1xuXHRtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vYnJvd3Nlci5qcycpO1xufSBlbHNlIHtcblx0bW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL25vZGUuanMnKTtcbn1cbiIsIi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG5jb25zdCB0dHkgPSByZXF1aXJlKCd0dHknKTtcbmNvbnN0IHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5cbi8qKlxuICogVGhpcyBpcyB0aGUgTm9kZS5qcyBpbXBsZW1lbnRhdGlvbiBvZiBgZGVidWcoKWAuXG4gKi9cblxuZXhwb3J0cy5pbml0ID0gaW5pdDtcbmV4cG9ydHMubG9nID0gbG9nO1xuZXhwb3J0cy5mb3JtYXRBcmdzID0gZm9ybWF0QXJncztcbmV4cG9ydHMuc2F2ZSA9IHNhdmU7XG5leHBvcnRzLmxvYWQgPSBsb2FkO1xuZXhwb3J0cy51c2VDb2xvcnMgPSB1c2VDb2xvcnM7XG5leHBvcnRzLmRlc3Ryb3kgPSB1dGlsLmRlcHJlY2F0ZShcblx0KCkgPT4ge30sXG5cdCdJbnN0YW5jZSBtZXRob2QgYGRlYnVnLmRlc3Ryb3koKWAgaXMgZGVwcmVjYXRlZCBhbmQgbm8gbG9uZ2VyIGRvZXMgYW55dGhpbmcuIEl0IHdpbGwgYmUgcmVtb3ZlZCBpbiB0aGUgbmV4dCBtYWpvciB2ZXJzaW9uIG9mIGBkZWJ1Z2AuJ1xuKTtcblxuLyoqXG4gKiBDb2xvcnMuXG4gKi9cblxuZXhwb3J0cy5jb2xvcnMgPSBbNiwgMiwgMywgNCwgNSwgMV07XG5cbnRyeSB7XG5cdC8vIE9wdGlvbmFsIGRlcGVuZGVuY3kgKGFzIGluLCBkb2Vzbid0IG5lZWQgdG8gYmUgaW5zdGFsbGVkLCBOT1QgbGlrZSBvcHRpb25hbERlcGVuZGVuY2llcyBpbiBwYWNrYWdlLmpzb24pXG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXNcblx0Y29uc3Qgc3VwcG9ydHNDb2xvciA9IHJlcXVpcmUoJ3N1cHBvcnRzLWNvbG9yJyk7XG5cblx0aWYgKHN1cHBvcnRzQ29sb3IgJiYgKHN1cHBvcnRzQ29sb3Iuc3RkZXJyIHx8IHN1cHBvcnRzQ29sb3IpLmxldmVsID49IDIpIHtcblx0XHRleHBvcnRzLmNvbG9ycyA9IFtcblx0XHRcdDIwLFxuXHRcdFx0MjEsXG5cdFx0XHQyNixcblx0XHRcdDI3LFxuXHRcdFx0MzIsXG5cdFx0XHQzMyxcblx0XHRcdDM4LFxuXHRcdFx0MzksXG5cdFx0XHQ0MCxcblx0XHRcdDQxLFxuXHRcdFx0NDIsXG5cdFx0XHQ0Myxcblx0XHRcdDQ0LFxuXHRcdFx0NDUsXG5cdFx0XHQ1Nixcblx0XHRcdDU3LFxuXHRcdFx0NjIsXG5cdFx0XHQ2Myxcblx0XHRcdDY4LFxuXHRcdFx0NjksXG5cdFx0XHQ3NCxcblx0XHRcdDc1LFxuXHRcdFx0NzYsXG5cdFx0XHQ3Nyxcblx0XHRcdDc4LFxuXHRcdFx0NzksXG5cdFx0XHQ4MCxcblx0XHRcdDgxLFxuXHRcdFx0OTIsXG5cdFx0XHQ5Myxcblx0XHRcdDk4LFxuXHRcdFx0OTksXG5cdFx0XHQxMTIsXG5cdFx0XHQxMTMsXG5cdFx0XHQxMjgsXG5cdFx0XHQxMjksXG5cdFx0XHQxMzQsXG5cdFx0XHQxMzUsXG5cdFx0XHQxNDgsXG5cdFx0XHQxNDksXG5cdFx0XHQxNjAsXG5cdFx0XHQxNjEsXG5cdFx0XHQxNjIsXG5cdFx0XHQxNjMsXG5cdFx0XHQxNjQsXG5cdFx0XHQxNjUsXG5cdFx0XHQxNjYsXG5cdFx0XHQxNjcsXG5cdFx0XHQxNjgsXG5cdFx0XHQxNjksXG5cdFx0XHQxNzAsXG5cdFx0XHQxNzEsXG5cdFx0XHQxNzIsXG5cdFx0XHQxNzMsXG5cdFx0XHQxNzgsXG5cdFx0XHQxNzksXG5cdFx0XHQxODQsXG5cdFx0XHQxODUsXG5cdFx0XHQxOTYsXG5cdFx0XHQxOTcsXG5cdFx0XHQxOTgsXG5cdFx0XHQxOTksXG5cdFx0XHQyMDAsXG5cdFx0XHQyMDEsXG5cdFx0XHQyMDIsXG5cdFx0XHQyMDMsXG5cdFx0XHQyMDQsXG5cdFx0XHQyMDUsXG5cdFx0XHQyMDYsXG5cdFx0XHQyMDcsXG5cdFx0XHQyMDgsXG5cdFx0XHQyMDksXG5cdFx0XHQyMTQsXG5cdFx0XHQyMTUsXG5cdFx0XHQyMjAsXG5cdFx0XHQyMjFcblx0XHRdO1xuXHR9XG59IGNhdGNoIChlcnJvcikge1xuXHQvLyBTd2FsbG93IC0gd2Ugb25seSBjYXJlIGlmIGBzdXBwb3J0cy1jb2xvcmAgaXMgYXZhaWxhYmxlOyBpdCBkb2Vzbid0IGhhdmUgdG8gYmUuXG59XG5cbi8qKlxuICogQnVpbGQgdXAgdGhlIGRlZmF1bHQgYGluc3BlY3RPcHRzYCBvYmplY3QgZnJvbSB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGVzLlxuICpcbiAqICAgJCBERUJVR19DT0xPUlM9bm8gREVCVUdfREVQVEg9MTAgREVCVUdfU0hPV19ISURERU49ZW5hYmxlZCBub2RlIHNjcmlwdC5qc1xuICovXG5cbmV4cG9ydHMuaW5zcGVjdE9wdHMgPSBPYmplY3Qua2V5cyhwcm9jZXNzLmVudikuZmlsdGVyKGtleSA9PiB7XG5cdHJldHVybiAvXmRlYnVnXy9pLnRlc3Qoa2V5KTtcbn0pLnJlZHVjZSgob2JqLCBrZXkpID0+IHtcblx0Ly8gQ2FtZWwtY2FzZVxuXHRjb25zdCBwcm9wID0ga2V5XG5cdFx0LnN1YnN0cmluZyg2KVxuXHRcdC50b0xvd2VyQ2FzZSgpXG5cdFx0LnJlcGxhY2UoL18oW2Etel0pL2csIChfLCBrKSA9PiB7XG5cdFx0XHRyZXR1cm4gay50b1VwcGVyQ2FzZSgpO1xuXHRcdH0pO1xuXG5cdC8vIENvZXJjZSBzdHJpbmcgdmFsdWUgaW50byBKUyB2YWx1ZVxuXHRsZXQgdmFsID0gcHJvY2Vzcy5lbnZba2V5XTtcblx0aWYgKC9eKHllc3xvbnx0cnVlfGVuYWJsZWQpJC9pLnRlc3QodmFsKSkge1xuXHRcdHZhbCA9IHRydWU7XG5cdH0gZWxzZSBpZiAoL14obm98b2ZmfGZhbHNlfGRpc2FibGVkKSQvaS50ZXN0KHZhbCkpIHtcblx0XHR2YWwgPSBmYWxzZTtcblx0fSBlbHNlIGlmICh2YWwgPT09ICdudWxsJykge1xuXHRcdHZhbCA9IG51bGw7XG5cdH0gZWxzZSB7XG5cdFx0dmFsID0gTnVtYmVyKHZhbCk7XG5cdH1cblxuXHRvYmpbcHJvcF0gPSB2YWw7XG5cdHJldHVybiBvYmo7XG59LCB7fSk7XG5cbi8qKlxuICogSXMgc3Rkb3V0IGEgVFRZPyBDb2xvcmVkIG91dHB1dCBpcyBlbmFibGVkIHdoZW4gYHRydWVgLlxuICovXG5cbmZ1bmN0aW9uIHVzZUNvbG9ycygpIHtcblx0cmV0dXJuICdjb2xvcnMnIGluIGV4cG9ydHMuaW5zcGVjdE9wdHMgP1xuXHRcdEJvb2xlYW4oZXhwb3J0cy5pbnNwZWN0T3B0cy5jb2xvcnMpIDpcblx0XHR0dHkuaXNhdHR5KHByb2Nlc3Muc3RkZXJyLmZkKTtcbn1cblxuLyoqXG4gKiBBZGRzIEFOU0kgY29sb3IgZXNjYXBlIGNvZGVzIGlmIGVuYWJsZWQuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBmb3JtYXRBcmdzKGFyZ3MpIHtcblx0Y29uc3Qge25hbWVzcGFjZTogbmFtZSwgdXNlQ29sb3JzfSA9IHRoaXM7XG5cblx0aWYgKHVzZUNvbG9ycykge1xuXHRcdGNvbnN0IGMgPSB0aGlzLmNvbG9yO1xuXHRcdGNvbnN0IGNvbG9yQ29kZSA9ICdcXHUwMDFCWzMnICsgKGMgPCA4ID8gYyA6ICc4OzU7JyArIGMpO1xuXHRcdGNvbnN0IHByZWZpeCA9IGAgICR7Y29sb3JDb2RlfTsxbSR7bmFtZX0gXFx1MDAxQlswbWA7XG5cblx0XHRhcmdzWzBdID0gcHJlZml4ICsgYXJnc1swXS5zcGxpdCgnXFxuJykuam9pbignXFxuJyArIHByZWZpeCk7XG5cdFx0YXJncy5wdXNoKGNvbG9yQ29kZSArICdtKycgKyBtb2R1bGUuZXhwb3J0cy5odW1hbml6ZSh0aGlzLmRpZmYpICsgJ1xcdTAwMUJbMG0nKTtcblx0fSBlbHNlIHtcblx0XHRhcmdzWzBdID0gZ2V0RGF0ZSgpICsgbmFtZSArICcgJyArIGFyZ3NbMF07XG5cdH1cbn1cblxuZnVuY3Rpb24gZ2V0RGF0ZSgpIHtcblx0aWYgKGV4cG9ydHMuaW5zcGVjdE9wdHMuaGlkZURhdGUpIHtcblx0XHRyZXR1cm4gJyc7XG5cdH1cblx0cmV0dXJuIG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSArICcgJztcbn1cblxuLyoqXG4gKiBJbnZva2VzIGB1dGlsLmZvcm1hdCgpYCB3aXRoIHRoZSBzcGVjaWZpZWQgYXJndW1lbnRzIGFuZCB3cml0ZXMgdG8gc3RkZXJyLlxuICovXG5cbmZ1bmN0aW9uIGxvZyguLi5hcmdzKSB7XG5cdHJldHVybiBwcm9jZXNzLnN0ZGVyci53cml0ZSh1dGlsLmZvcm1hdCguLi5hcmdzKSArICdcXG4nKTtcbn1cblxuLyoqXG4gKiBTYXZlIGBuYW1lc3BhY2VzYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZXNwYWNlc1xuICogQGFwaSBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHNhdmUobmFtZXNwYWNlcykge1xuXHRpZiAobmFtZXNwYWNlcykge1xuXHRcdHByb2Nlc3MuZW52LkRFQlVHID0gbmFtZXNwYWNlcztcblx0fSBlbHNlIHtcblx0XHQvLyBJZiB5b3Ugc2V0IGEgcHJvY2Vzcy5lbnYgZmllbGQgdG8gbnVsbCBvciB1bmRlZmluZWQsIGl0IGdldHMgY2FzdCB0byB0aGVcblx0XHQvLyBzdHJpbmcgJ251bGwnIG9yICd1bmRlZmluZWQnLiBKdXN0IGRlbGV0ZSBpbnN0ZWFkLlxuXHRcdGRlbGV0ZSBwcm9jZXNzLmVudi5ERUJVRztcblx0fVxufVxuXG4vKipcbiAqIExvYWQgYG5hbWVzcGFjZXNgLlxuICpcbiAqIEByZXR1cm4ge1N0cmluZ30gcmV0dXJucyB0aGUgcHJldmlvdXNseSBwZXJzaXN0ZWQgZGVidWcgbW9kZXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGxvYWQoKSB7XG5cdHJldHVybiBwcm9jZXNzLmVudi5ERUJVRztcbn1cblxuLyoqXG4gKiBJbml0IGxvZ2ljIGZvciBgZGVidWdgIGluc3RhbmNlcy5cbiAqXG4gKiBDcmVhdGUgYSBuZXcgYGluc3BlY3RPcHRzYCBvYmplY3QgaW4gY2FzZSBgdXNlQ29sb3JzYCBpcyBzZXRcbiAqIGRpZmZlcmVudGx5IGZvciBhIHBhcnRpY3VsYXIgYGRlYnVnYCBpbnN0YW5jZS5cbiAqL1xuXG5mdW5jdGlvbiBpbml0KGRlYnVnKSB7XG5cdGRlYnVnLmluc3BlY3RPcHRzID0ge307XG5cblx0Y29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGV4cG9ydHMuaW5zcGVjdE9wdHMpO1xuXHRmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcblx0XHRkZWJ1Zy5pbnNwZWN0T3B0c1trZXlzW2ldXSA9IGV4cG9ydHMuaW5zcGVjdE9wdHNba2V5c1tpXV07XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2NvbW1vbicpKGV4cG9ydHMpO1xuXG5jb25zdCB7Zm9ybWF0dGVyc30gPSBtb2R1bGUuZXhwb3J0cztcblxuLyoqXG4gKiBNYXAgJW8gdG8gYHV0aWwuaW5zcGVjdCgpYCwgYWxsIG9uIGEgc2luZ2xlIGxpbmUuXG4gKi9cblxuZm9ybWF0dGVycy5vID0gZnVuY3Rpb24gKHYpIHtcblx0dGhpcy5pbnNwZWN0T3B0cy5jb2xvcnMgPSB0aGlzLnVzZUNvbG9ycztcblx0cmV0dXJuIHV0aWwuaW5zcGVjdCh2LCB0aGlzLmluc3BlY3RPcHRzKVxuXHRcdC5zcGxpdCgnXFxuJylcblx0XHQubWFwKHN0ciA9PiBzdHIudHJpbSgpKVxuXHRcdC5qb2luKCcgJyk7XG59O1xuXG4vKipcbiAqIE1hcCAlTyB0byBgdXRpbC5pbnNwZWN0KClgLCBhbGxvd2luZyBtdWx0aXBsZSBsaW5lcyBpZiBuZWVkZWQuXG4gKi9cblxuZm9ybWF0dGVycy5PID0gZnVuY3Rpb24gKHYpIHtcblx0dGhpcy5pbnNwZWN0T3B0cy5jb2xvcnMgPSB0aGlzLnVzZUNvbG9ycztcblx0cmV0dXJuIHV0aWwuaW5zcGVjdCh2LCB0aGlzLmluc3BlY3RPcHRzKTtcbn07XG4iLCJ2YXIgU3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJykuU3RyZWFtO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gRGVsYXllZFN0cmVhbTtcbmZ1bmN0aW9uIERlbGF5ZWRTdHJlYW0oKSB7XG4gIHRoaXMuc291cmNlID0gbnVsbDtcbiAgdGhpcy5kYXRhU2l6ZSA9IDA7XG4gIHRoaXMubWF4RGF0YVNpemUgPSAxMDI0ICogMTAyNDtcbiAgdGhpcy5wYXVzZVN0cmVhbSA9IHRydWU7XG5cbiAgdGhpcy5fbWF4RGF0YVNpemVFeGNlZWRlZCA9IGZhbHNlO1xuICB0aGlzLl9yZWxlYXNlZCA9IGZhbHNlO1xuICB0aGlzLl9idWZmZXJlZEV2ZW50cyA9IFtdO1xufVxudXRpbC5pbmhlcml0cyhEZWxheWVkU3RyZWFtLCBTdHJlYW0pO1xuXG5EZWxheWVkU3RyZWFtLmNyZWF0ZSA9IGZ1bmN0aW9uKHNvdXJjZSwgb3B0aW9ucykge1xuICB2YXIgZGVsYXllZFN0cmVhbSA9IG5ldyB0aGlzKCk7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGZvciAodmFyIG9wdGlvbiBpbiBvcHRpb25zKSB7XG4gICAgZGVsYXllZFN0cmVhbVtvcHRpb25dID0gb3B0aW9uc1tvcHRpb25dO1xuICB9XG5cbiAgZGVsYXllZFN0cmVhbS5zb3VyY2UgPSBzb3VyY2U7XG5cbiAgdmFyIHJlYWxFbWl0ID0gc291cmNlLmVtaXQ7XG4gIHNvdXJjZS5lbWl0ID0gZnVuY3Rpb24oKSB7XG4gICAgZGVsYXllZFN0cmVhbS5faGFuZGxlRW1pdChhcmd1bWVudHMpO1xuICAgIHJldHVybiByZWFsRW1pdC5hcHBseShzb3VyY2UsIGFyZ3VtZW50cyk7XG4gIH07XG5cbiAgc291cmNlLm9uKCdlcnJvcicsIGZ1bmN0aW9uKCkge30pO1xuICBpZiAoZGVsYXllZFN0cmVhbS5wYXVzZVN0cmVhbSkge1xuICAgIHNvdXJjZS5wYXVzZSgpO1xuICB9XG5cbiAgcmV0dXJuIGRlbGF5ZWRTdHJlYW07XG59O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRGVsYXllZFN0cmVhbS5wcm90b3R5cGUsICdyZWFkYWJsZScsIHtcbiAgY29uZmlndXJhYmxlOiB0cnVlLFxuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnNvdXJjZS5yZWFkYWJsZTtcbiAgfVxufSk7XG5cbkRlbGF5ZWRTdHJlYW0ucHJvdG90eXBlLnNldEVuY29kaW5nID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnNvdXJjZS5zZXRFbmNvZGluZy5hcHBseSh0aGlzLnNvdXJjZSwgYXJndW1lbnRzKTtcbn07XG5cbkRlbGF5ZWRTdHJlYW0ucHJvdG90eXBlLnJlc3VtZSA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMuX3JlbGVhc2VkKSB7XG4gICAgdGhpcy5yZWxlYXNlKCk7XG4gIH1cblxuICB0aGlzLnNvdXJjZS5yZXN1bWUoKTtcbn07XG5cbkRlbGF5ZWRTdHJlYW0ucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuc291cmNlLnBhdXNlKCk7XG59O1xuXG5EZWxheWVkU3RyZWFtLnByb3RvdHlwZS5yZWxlYXNlID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX3JlbGVhc2VkID0gdHJ1ZTtcblxuICB0aGlzLl9idWZmZXJlZEV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICB0aGlzLmVtaXQuYXBwbHkodGhpcywgYXJncyk7XG4gIH0uYmluZCh0aGlzKSk7XG4gIHRoaXMuX2J1ZmZlcmVkRXZlbnRzID0gW107XG59O1xuXG5EZWxheWVkU3RyZWFtLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24oKSB7XG4gIHZhciByID0gU3RyZWFtLnByb3RvdHlwZS5waXBlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIHRoaXMucmVzdW1lKCk7XG4gIHJldHVybiByO1xufTtcblxuRGVsYXllZFN0cmVhbS5wcm90b3R5cGUuX2hhbmRsZUVtaXQgPSBmdW5jdGlvbihhcmdzKSB7XG4gIGlmICh0aGlzLl9yZWxlYXNlZCkge1xuICAgIHRoaXMuZW1pdC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoYXJnc1swXSA9PT0gJ2RhdGEnKSB7XG4gICAgdGhpcy5kYXRhU2l6ZSArPSBhcmdzWzFdLmxlbmd0aDtcbiAgICB0aGlzLl9jaGVja0lmTWF4RGF0YVNpemVFeGNlZWRlZCgpO1xuICB9XG5cbiAgdGhpcy5fYnVmZmVyZWRFdmVudHMucHVzaChhcmdzKTtcbn07XG5cbkRlbGF5ZWRTdHJlYW0ucHJvdG90eXBlLl9jaGVja0lmTWF4RGF0YVNpemVFeGNlZWRlZCA9IGZ1bmN0aW9uKCkge1xuICBpZiAodGhpcy5fbWF4RGF0YVNpemVFeGNlZWRlZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICh0aGlzLmRhdGFTaXplIDw9IHRoaXMubWF4RGF0YVNpemUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB0aGlzLl9tYXhEYXRhU2l6ZUV4Y2VlZGVkID0gdHJ1ZTtcbiAgdmFyIG1lc3NhZ2UgPVxuICAgICdEZWxheWVkU3RyZWFtI21heERhdGFTaXplIG9mICcgKyB0aGlzLm1heERhdGFTaXplICsgJyBieXRlcyBleGNlZWRlZC4nXG4gIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IobWVzc2FnZSkpO1xufTtcbiIsInZhciBkZWJ1ZztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghZGVidWcpIHtcbiAgICB0cnkge1xuICAgICAgLyogZXNsaW50IGdsb2JhbC1yZXF1aXJlOiBvZmYgKi9cbiAgICAgIGRlYnVnID0gcmVxdWlyZShcImRlYnVnXCIpKFwiZm9sbG93LXJlZGlyZWN0c1wiKTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycm9yKSB7IC8qICovIH1cbiAgICBpZiAodHlwZW9mIGRlYnVnICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIGRlYnVnID0gZnVuY3Rpb24gKCkgeyAvKiAqLyB9O1xuICAgIH1cbiAgfVxuICBkZWJ1Zy5hcHBseShudWxsLCBhcmd1bWVudHMpO1xufTtcbiIsInZhciB1cmwgPSByZXF1aXJlKFwidXJsXCIpO1xudmFyIFVSTCA9IHVybC5VUkw7XG52YXIgaHR0cCA9IHJlcXVpcmUoXCJodHRwXCIpO1xudmFyIGh0dHBzID0gcmVxdWlyZShcImh0dHBzXCIpO1xudmFyIFdyaXRhYmxlID0gcmVxdWlyZShcInN0cmVhbVwiKS5Xcml0YWJsZTtcbnZhciBhc3NlcnQgPSByZXF1aXJlKFwiYXNzZXJ0XCIpO1xudmFyIGRlYnVnID0gcmVxdWlyZShcIi4vZGVidWdcIik7XG5cbi8vIFdoZXRoZXIgdG8gdXNlIHRoZSBuYXRpdmUgVVJMIG9iamVjdCBvciB0aGUgbGVnYWN5IHVybCBtb2R1bGVcbnZhciB1c2VOYXRpdmVVUkwgPSBmYWxzZTtcbnRyeSB7XG4gIGFzc2VydChuZXcgVVJMKCkpO1xufVxuY2F0Y2ggKGVycm9yKSB7XG4gIHVzZU5hdGl2ZVVSTCA9IGVycm9yLmNvZGUgPT09IFwiRVJSX0lOVkFMSURfVVJMXCI7XG59XG5cbi8vIFVSTCBmaWVsZHMgdG8gcHJlc2VydmUgaW4gY29weSBvcGVyYXRpb25zXG52YXIgcHJlc2VydmVkVXJsRmllbGRzID0gW1xuICBcImF1dGhcIixcbiAgXCJob3N0XCIsXG4gIFwiaG9zdG5hbWVcIixcbiAgXCJocmVmXCIsXG4gIFwicGF0aFwiLFxuICBcInBhdGhuYW1lXCIsXG4gIFwicG9ydFwiLFxuICBcInByb3RvY29sXCIsXG4gIFwicXVlcnlcIixcbiAgXCJzZWFyY2hcIixcbiAgXCJoYXNoXCIsXG5dO1xuXG4vLyBDcmVhdGUgaGFuZGxlcnMgdGhhdCBwYXNzIGV2ZW50cyBmcm9tIG5hdGl2ZSByZXF1ZXN0c1xudmFyIGV2ZW50cyA9IFtcImFib3J0XCIsIFwiYWJvcnRlZFwiLCBcImNvbm5lY3RcIiwgXCJlcnJvclwiLCBcInNvY2tldFwiLCBcInRpbWVvdXRcIl07XG52YXIgZXZlbnRIYW5kbGVycyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5ldmVudHMuZm9yRWFjaChmdW5jdGlvbiAoZXZlbnQpIHtcbiAgZXZlbnRIYW5kbGVyc1tldmVudF0gPSBmdW5jdGlvbiAoYXJnMSwgYXJnMiwgYXJnMykge1xuICAgIHRoaXMuX3JlZGlyZWN0YWJsZS5lbWl0KGV2ZW50LCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgfTtcbn0pO1xuXG4vLyBFcnJvciB0eXBlcyB3aXRoIGNvZGVzXG52YXIgSW52YWxpZFVybEVycm9yID0gY3JlYXRlRXJyb3JUeXBlKFxuICBcIkVSUl9JTlZBTElEX1VSTFwiLFxuICBcIkludmFsaWQgVVJMXCIsXG4gIFR5cGVFcnJvclxuKTtcbnZhciBSZWRpcmVjdGlvbkVycm9yID0gY3JlYXRlRXJyb3JUeXBlKFxuICBcIkVSUl9GUl9SRURJUkVDVElPTl9GQUlMVVJFXCIsXG4gIFwiUmVkaXJlY3RlZCByZXF1ZXN0IGZhaWxlZFwiXG4pO1xudmFyIFRvb01hbnlSZWRpcmVjdHNFcnJvciA9IGNyZWF0ZUVycm9yVHlwZShcbiAgXCJFUlJfRlJfVE9PX01BTllfUkVESVJFQ1RTXCIsXG4gIFwiTWF4aW11bSBudW1iZXIgb2YgcmVkaXJlY3RzIGV4Y2VlZGVkXCIsXG4gIFJlZGlyZWN0aW9uRXJyb3Jcbik7XG52YXIgTWF4Qm9keUxlbmd0aEV4Y2VlZGVkRXJyb3IgPSBjcmVhdGVFcnJvclR5cGUoXG4gIFwiRVJSX0ZSX01BWF9CT0RZX0xFTkdUSF9FWENFRURFRFwiLFxuICBcIlJlcXVlc3QgYm9keSBsYXJnZXIgdGhhbiBtYXhCb2R5TGVuZ3RoIGxpbWl0XCJcbik7XG52YXIgV3JpdGVBZnRlckVuZEVycm9yID0gY3JlYXRlRXJyb3JUeXBlKFxuICBcIkVSUl9TVFJFQU1fV1JJVEVfQUZURVJfRU5EXCIsXG4gIFwid3JpdGUgYWZ0ZXIgZW5kXCJcbik7XG5cbi8vIGlzdGFuYnVsIGlnbm9yZSBuZXh0XG52YXIgZGVzdHJveSA9IFdyaXRhYmxlLnByb3RvdHlwZS5kZXN0cm95IHx8IG5vb3A7XG5cbi8vIEFuIEhUVFAoUykgcmVxdWVzdCB0aGF0IGNhbiBiZSByZWRpcmVjdGVkXG5mdW5jdGlvbiBSZWRpcmVjdGFibGVSZXF1ZXN0KG9wdGlvbnMsIHJlc3BvbnNlQ2FsbGJhY2spIHtcbiAgLy8gSW5pdGlhbGl6ZSB0aGUgcmVxdWVzdFxuICBXcml0YWJsZS5jYWxsKHRoaXMpO1xuICB0aGlzLl9zYW5pdGl6ZU9wdGlvbnMob3B0aW9ucyk7XG4gIHRoaXMuX29wdGlvbnMgPSBvcHRpb25zO1xuICB0aGlzLl9lbmRlZCA9IGZhbHNlO1xuICB0aGlzLl9lbmRpbmcgPSBmYWxzZTtcbiAgdGhpcy5fcmVkaXJlY3RDb3VudCA9IDA7XG4gIHRoaXMuX3JlZGlyZWN0cyA9IFtdO1xuICB0aGlzLl9yZXF1ZXN0Qm9keUxlbmd0aCA9IDA7XG4gIHRoaXMuX3JlcXVlc3RCb2R5QnVmZmVycyA9IFtdO1xuXG4gIC8vIEF0dGFjaCBhIGNhbGxiYWNrIGlmIHBhc3NlZFxuICBpZiAocmVzcG9uc2VDYWxsYmFjaykge1xuICAgIHRoaXMub24oXCJyZXNwb25zZVwiLCByZXNwb25zZUNhbGxiYWNrKTtcbiAgfVxuXG4gIC8vIFJlYWN0IHRvIHJlc3BvbnNlcyBvZiBuYXRpdmUgcmVxdWVzdHNcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLl9vbk5hdGl2ZVJlc3BvbnNlID0gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgdHJ5IHtcbiAgICAgIHNlbGYuX3Byb2Nlc3NSZXNwb25zZShyZXNwb25zZSk7XG4gICAgfVxuICAgIGNhdGNoIChjYXVzZSkge1xuICAgICAgc2VsZi5lbWl0KFwiZXJyb3JcIiwgY2F1c2UgaW5zdGFuY2VvZiBSZWRpcmVjdGlvbkVycm9yID9cbiAgICAgICAgY2F1c2UgOiBuZXcgUmVkaXJlY3Rpb25FcnJvcih7IGNhdXNlOiBjYXVzZSB9KSk7XG4gICAgfVxuICB9O1xuXG4gIC8vIFBlcmZvcm0gdGhlIGZpcnN0IHJlcXVlc3RcbiAgdGhpcy5fcGVyZm9ybVJlcXVlc3QoKTtcbn1cblJlZGlyZWN0YWJsZVJlcXVlc3QucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShXcml0YWJsZS5wcm90b3R5cGUpO1xuXG5SZWRpcmVjdGFibGVSZXF1ZXN0LnByb3RvdHlwZS5hYm9ydCA9IGZ1bmN0aW9uICgpIHtcbiAgZGVzdHJveVJlcXVlc3QodGhpcy5fY3VycmVudFJlcXVlc3QpO1xuICB0aGlzLl9jdXJyZW50UmVxdWVzdC5hYm9ydCgpO1xuICB0aGlzLmVtaXQoXCJhYm9ydFwiKTtcbn07XG5cblJlZGlyZWN0YWJsZVJlcXVlc3QucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgZGVzdHJveVJlcXVlc3QodGhpcy5fY3VycmVudFJlcXVlc3QsIGVycm9yKTtcbiAgZGVzdHJveS5jYWxsKHRoaXMsIGVycm9yKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBXcml0ZXMgYnVmZmVyZWQgZGF0YSB0byB0aGUgY3VycmVudCBuYXRpdmUgcmVxdWVzdFxuUmVkaXJlY3RhYmxlUmVxdWVzdC5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAoZGF0YSwgZW5jb2RpbmcsIGNhbGxiYWNrKSB7XG4gIC8vIFdyaXRpbmcgaXMgbm90IGFsbG93ZWQgaWYgZW5kIGhhcyBiZWVuIGNhbGxlZFxuICBpZiAodGhpcy5fZW5kaW5nKSB7XG4gICAgdGhyb3cgbmV3IFdyaXRlQWZ0ZXJFbmRFcnJvcigpO1xuICB9XG5cbiAgLy8gVmFsaWRhdGUgaW5wdXQgYW5kIHNoaWZ0IHBhcmFtZXRlcnMgaWYgbmVjZXNzYXJ5XG4gIGlmICghaXNTdHJpbmcoZGF0YSkgJiYgIWlzQnVmZmVyKGRhdGEpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImRhdGEgc2hvdWxkIGJlIGEgc3RyaW5nLCBCdWZmZXIgb3IgVWludDhBcnJheVwiKTtcbiAgfVxuICBpZiAoaXNGdW5jdGlvbihlbmNvZGluZykpIHtcbiAgICBjYWxsYmFjayA9IGVuY29kaW5nO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfVxuXG4gIC8vIElnbm9yZSBlbXB0eSBidWZmZXJzLCBzaW5jZSB3cml0aW5nIHRoZW0gZG9lc24ndCBpbnZva2UgdGhlIGNhbGxiYWNrXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlanMvbm9kZS9pc3N1ZXMvMjIwNjZcbiAgaWYgKGRhdGEubGVuZ3RoID09PSAwKSB7XG4gICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICBjYWxsYmFjaygpO1xuICAgIH1cbiAgICByZXR1cm47XG4gIH1cbiAgLy8gT25seSB3cml0ZSB3aGVuIHdlIGRvbid0IGV4Y2VlZCB0aGUgbWF4aW11bSBib2R5IGxlbmd0aFxuICBpZiAodGhpcy5fcmVxdWVzdEJvZHlMZW5ndGggKyBkYXRhLmxlbmd0aCA8PSB0aGlzLl9vcHRpb25zLm1heEJvZHlMZW5ndGgpIHtcbiAgICB0aGlzLl9yZXF1ZXN0Qm9keUxlbmd0aCArPSBkYXRhLmxlbmd0aDtcbiAgICB0aGlzLl9yZXF1ZXN0Qm9keUJ1ZmZlcnMucHVzaCh7IGRhdGE6IGRhdGEsIGVuY29kaW5nOiBlbmNvZGluZyB9KTtcbiAgICB0aGlzLl9jdXJyZW50UmVxdWVzdC53cml0ZShkYXRhLCBlbmNvZGluZywgY2FsbGJhY2spO1xuICB9XG4gIC8vIEVycm9yIHdoZW4gd2UgZXhjZWVkIHRoZSBtYXhpbXVtIGJvZHkgbGVuZ3RoXG4gIGVsc2Uge1xuICAgIHRoaXMuZW1pdChcImVycm9yXCIsIG5ldyBNYXhCb2R5TGVuZ3RoRXhjZWVkZWRFcnJvcigpKTtcbiAgICB0aGlzLmFib3J0KCk7XG4gIH1cbn07XG5cbi8vIEVuZHMgdGhlIGN1cnJlbnQgbmF0aXZlIHJlcXVlc3RcblJlZGlyZWN0YWJsZVJlcXVlc3QucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uIChkYXRhLCBlbmNvZGluZywgY2FsbGJhY2spIHtcbiAgLy8gU2hpZnQgcGFyYW1ldGVycyBpZiBuZWNlc3NhcnlcbiAgaWYgKGlzRnVuY3Rpb24oZGF0YSkpIHtcbiAgICBjYWxsYmFjayA9IGRhdGE7XG4gICAgZGF0YSA9IGVuY29kaW5nID0gbnVsbDtcbiAgfVxuICBlbHNlIGlmIChpc0Z1bmN0aW9uKGVuY29kaW5nKSkge1xuICAgIGNhbGxiYWNrID0gZW5jb2Rpbmc7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9XG5cbiAgLy8gV3JpdGUgZGF0YSBpZiBuZWVkZWQgYW5kIGVuZFxuICBpZiAoIWRhdGEpIHtcbiAgICB0aGlzLl9lbmRlZCA9IHRoaXMuX2VuZGluZyA9IHRydWU7XG4gICAgdGhpcy5fY3VycmVudFJlcXVlc3QuZW5kKG51bGwsIG51bGwsIGNhbGxiYWNrKTtcbiAgfVxuICBlbHNlIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGN1cnJlbnRSZXF1ZXN0ID0gdGhpcy5fY3VycmVudFJlcXVlc3Q7XG4gICAgdGhpcy53cml0ZShkYXRhLCBlbmNvZGluZywgZnVuY3Rpb24gKCkge1xuICAgICAgc2VsZi5fZW5kZWQgPSB0cnVlO1xuICAgICAgY3VycmVudFJlcXVlc3QuZW5kKG51bGwsIG51bGwsIGNhbGxiYWNrKTtcbiAgICB9KTtcbiAgICB0aGlzLl9lbmRpbmcgPSB0cnVlO1xuICB9XG59O1xuXG4vLyBTZXRzIGEgaGVhZGVyIHZhbHVlIG9uIHRoZSBjdXJyZW50IG5hdGl2ZSByZXF1ZXN0XG5SZWRpcmVjdGFibGVSZXF1ZXN0LnByb3RvdHlwZS5zZXRIZWFkZXIgPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUpIHtcbiAgdGhpcy5fb3B0aW9ucy5oZWFkZXJzW25hbWVdID0gdmFsdWU7XG4gIHRoaXMuX2N1cnJlbnRSZXF1ZXN0LnNldEhlYWRlcihuYW1lLCB2YWx1ZSk7XG59O1xuXG4vLyBDbGVhcnMgYSBoZWFkZXIgdmFsdWUgb24gdGhlIGN1cnJlbnQgbmF0aXZlIHJlcXVlc3RcblJlZGlyZWN0YWJsZVJlcXVlc3QucHJvdG90eXBlLnJlbW92ZUhlYWRlciA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIGRlbGV0ZSB0aGlzLl9vcHRpb25zLmhlYWRlcnNbbmFtZV07XG4gIHRoaXMuX2N1cnJlbnRSZXF1ZXN0LnJlbW92ZUhlYWRlcihuYW1lKTtcbn07XG5cbi8vIEdsb2JhbCB0aW1lb3V0IGZvciBhbGwgdW5kZXJseWluZyByZXF1ZXN0c1xuUmVkaXJlY3RhYmxlUmVxdWVzdC5wcm90b3R5cGUuc2V0VGltZW91dCA9IGZ1bmN0aW9uIChtc2VjcywgY2FsbGJhY2spIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIC8vIERlc3Ryb3lzIHRoZSBzb2NrZXQgb24gdGltZW91dFxuICBmdW5jdGlvbiBkZXN0cm95T25UaW1lb3V0KHNvY2tldCkge1xuICAgIHNvY2tldC5zZXRUaW1lb3V0KG1zZWNzKTtcbiAgICBzb2NrZXQucmVtb3ZlTGlzdGVuZXIoXCJ0aW1lb3V0XCIsIHNvY2tldC5kZXN0cm95KTtcbiAgICBzb2NrZXQuYWRkTGlzdGVuZXIoXCJ0aW1lb3V0XCIsIHNvY2tldC5kZXN0cm95KTtcbiAgfVxuXG4gIC8vIFNldHMgdXAgYSB0aW1lciB0byB0cmlnZ2VyIGEgdGltZW91dCBldmVudFxuICBmdW5jdGlvbiBzdGFydFRpbWVyKHNvY2tldCkge1xuICAgIGlmIChzZWxmLl90aW1lb3V0KSB7XG4gICAgICBjbGVhclRpbWVvdXQoc2VsZi5fdGltZW91dCk7XG4gICAgfVxuICAgIHNlbGYuX3RpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHNlbGYuZW1pdChcInRpbWVvdXRcIik7XG4gICAgICBjbGVhclRpbWVyKCk7XG4gICAgfSwgbXNlY3MpO1xuICAgIGRlc3Ryb3lPblRpbWVvdXQoc29ja2V0KTtcbiAgfVxuXG4gIC8vIFN0b3BzIGEgdGltZW91dCBmcm9tIHRyaWdnZXJpbmdcbiAgZnVuY3Rpb24gY2xlYXJUaW1lcigpIHtcbiAgICAvLyBDbGVhciB0aGUgdGltZW91dFxuICAgIGlmIChzZWxmLl90aW1lb3V0KSB7XG4gICAgICBjbGVhclRpbWVvdXQoc2VsZi5fdGltZW91dCk7XG4gICAgICBzZWxmLl90aW1lb3V0ID0gbnVsbDtcbiAgICB9XG5cbiAgICAvLyBDbGVhbiB1cCBhbGwgYXR0YWNoZWQgbGlzdGVuZXJzXG4gICAgc2VsZi5yZW1vdmVMaXN0ZW5lcihcImFib3J0XCIsIGNsZWFyVGltZXIpO1xuICAgIHNlbGYucmVtb3ZlTGlzdGVuZXIoXCJlcnJvclwiLCBjbGVhclRpbWVyKTtcbiAgICBzZWxmLnJlbW92ZUxpc3RlbmVyKFwicmVzcG9uc2VcIiwgY2xlYXJUaW1lcik7XG4gICAgc2VsZi5yZW1vdmVMaXN0ZW5lcihcImNsb3NlXCIsIGNsZWFyVGltZXIpO1xuICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgc2VsZi5yZW1vdmVMaXN0ZW5lcihcInRpbWVvdXRcIiwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBpZiAoIXNlbGYuc29ja2V0KSB7XG4gICAgICBzZWxmLl9jdXJyZW50UmVxdWVzdC5yZW1vdmVMaXN0ZW5lcihcInNvY2tldFwiLCBzdGFydFRpbWVyKTtcbiAgICB9XG4gIH1cblxuICAvLyBBdHRhY2ggY2FsbGJhY2sgaWYgcGFzc2VkXG4gIGlmIChjYWxsYmFjaykge1xuICAgIHRoaXMub24oXCJ0aW1lb3V0XCIsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIC8vIFN0YXJ0IHRoZSB0aW1lciBpZiBvciB3aGVuIHRoZSBzb2NrZXQgaXMgb3BlbmVkXG4gIGlmICh0aGlzLnNvY2tldCkge1xuICAgIHN0YXJ0VGltZXIodGhpcy5zb2NrZXQpO1xuICB9XG4gIGVsc2Uge1xuICAgIHRoaXMuX2N1cnJlbnRSZXF1ZXN0Lm9uY2UoXCJzb2NrZXRcIiwgc3RhcnRUaW1lcik7XG4gIH1cblxuICAvLyBDbGVhbiB1cCBvbiBldmVudHNcbiAgdGhpcy5vbihcInNvY2tldFwiLCBkZXN0cm95T25UaW1lb3V0KTtcbiAgdGhpcy5vbihcImFib3J0XCIsIGNsZWFyVGltZXIpO1xuICB0aGlzLm9uKFwiZXJyb3JcIiwgY2xlYXJUaW1lcik7XG4gIHRoaXMub24oXCJyZXNwb25zZVwiLCBjbGVhclRpbWVyKTtcbiAgdGhpcy5vbihcImNsb3NlXCIsIGNsZWFyVGltZXIpO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gUHJveHkgYWxsIG90aGVyIHB1YmxpYyBDbGllbnRSZXF1ZXN0IG1ldGhvZHNcbltcbiAgXCJmbHVzaEhlYWRlcnNcIiwgXCJnZXRIZWFkZXJcIixcbiAgXCJzZXROb0RlbGF5XCIsIFwic2V0U29ja2V0S2VlcEFsaXZlXCIsXG5dLmZvckVhY2goZnVuY3Rpb24gKG1ldGhvZCkge1xuICBSZWRpcmVjdGFibGVSZXF1ZXN0LnByb3RvdHlwZVttZXRob2RdID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICByZXR1cm4gdGhpcy5fY3VycmVudFJlcXVlc3RbbWV0aG9kXShhLCBiKTtcbiAgfTtcbn0pO1xuXG4vLyBQcm94eSBhbGwgcHVibGljIENsaWVudFJlcXVlc3QgcHJvcGVydGllc1xuW1wiYWJvcnRlZFwiLCBcImNvbm5lY3Rpb25cIiwgXCJzb2NrZXRcIl0uZm9yRWFjaChmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlZGlyZWN0YWJsZVJlcXVlc3QucHJvdG90eXBlLCBwcm9wZXJ0eSwge1xuICAgIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5fY3VycmVudFJlcXVlc3RbcHJvcGVydHldOyB9LFxuICB9KTtcbn0pO1xuXG5SZWRpcmVjdGFibGVSZXF1ZXN0LnByb3RvdHlwZS5fc2FuaXRpemVPcHRpb25zID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgLy8gRW5zdXJlIGhlYWRlcnMgYXJlIGFsd2F5cyBwcmVzZW50XG4gIGlmICghb3B0aW9ucy5oZWFkZXJzKSB7XG4gICAgb3B0aW9ucy5oZWFkZXJzID0ge307XG4gIH1cblxuICAvLyBTaW5jZSBodHRwLnJlcXVlc3QgdHJlYXRzIGhvc3QgYXMgYW4gYWxpYXMgb2YgaG9zdG5hbWUsXG4gIC8vIGJ1dCB0aGUgdXJsIG1vZHVsZSBpbnRlcnByZXRzIGhvc3QgYXMgaG9zdG5hbWUgcGx1cyBwb3J0LFxuICAvLyBlbGltaW5hdGUgdGhlIGhvc3QgcHJvcGVydHkgdG8gYXZvaWQgY29uZnVzaW9uLlxuICBpZiAob3B0aW9ucy5ob3N0KSB7XG4gICAgLy8gVXNlIGhvc3RuYW1lIGlmIHNldCwgYmVjYXVzZSBpdCBoYXMgcHJlY2VkZW5jZVxuICAgIGlmICghb3B0aW9ucy5ob3N0bmFtZSkge1xuICAgICAgb3B0aW9ucy5ob3N0bmFtZSA9IG9wdGlvbnMuaG9zdDtcbiAgICB9XG4gICAgZGVsZXRlIG9wdGlvbnMuaG9zdDtcbiAgfVxuXG4gIC8vIENvbXBsZXRlIHRoZSBVUkwgb2JqZWN0IHdoZW4gbmVjZXNzYXJ5XG4gIGlmICghb3B0aW9ucy5wYXRobmFtZSAmJiBvcHRpb25zLnBhdGgpIHtcbiAgICB2YXIgc2VhcmNoUG9zID0gb3B0aW9ucy5wYXRoLmluZGV4T2YoXCI/XCIpO1xuICAgIGlmIChzZWFyY2hQb3MgPCAwKSB7XG4gICAgICBvcHRpb25zLnBhdGhuYW1lID0gb3B0aW9ucy5wYXRoO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIG9wdGlvbnMucGF0aG5hbWUgPSBvcHRpb25zLnBhdGguc3Vic3RyaW5nKDAsIHNlYXJjaFBvcyk7XG4gICAgICBvcHRpb25zLnNlYXJjaCA9IG9wdGlvbnMucGF0aC5zdWJzdHJpbmcoc2VhcmNoUG9zKTtcbiAgICB9XG4gIH1cbn07XG5cblxuLy8gRXhlY3V0ZXMgdGhlIG5leHQgbmF0aXZlIHJlcXVlc3QgKGluaXRpYWwgb3IgcmVkaXJlY3QpXG5SZWRpcmVjdGFibGVSZXF1ZXN0LnByb3RvdHlwZS5fcGVyZm9ybVJlcXVlc3QgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIExvYWQgdGhlIG5hdGl2ZSBwcm90b2NvbFxuICB2YXIgcHJvdG9jb2wgPSB0aGlzLl9vcHRpb25zLnByb3RvY29sO1xuICB2YXIgbmF0aXZlUHJvdG9jb2wgPSB0aGlzLl9vcHRpb25zLm5hdGl2ZVByb3RvY29sc1twcm90b2NvbF07XG4gIGlmICghbmF0aXZlUHJvdG9jb2wpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiVW5zdXBwb3J0ZWQgcHJvdG9jb2wgXCIgKyBwcm90b2NvbCk7XG4gIH1cblxuICAvLyBJZiBzcGVjaWZpZWQsIHVzZSB0aGUgYWdlbnQgY29ycmVzcG9uZGluZyB0byB0aGUgcHJvdG9jb2xcbiAgLy8gKEhUVFAgYW5kIEhUVFBTIHVzZSBkaWZmZXJlbnQgdHlwZXMgb2YgYWdlbnRzKVxuICBpZiAodGhpcy5fb3B0aW9ucy5hZ2VudHMpIHtcbiAgICB2YXIgc2NoZW1lID0gcHJvdG9jb2wuc2xpY2UoMCwgLTEpO1xuICAgIHRoaXMuX29wdGlvbnMuYWdlbnQgPSB0aGlzLl9vcHRpb25zLmFnZW50c1tzY2hlbWVdO1xuICB9XG5cbiAgLy8gQ3JlYXRlIHRoZSBuYXRpdmUgcmVxdWVzdCBhbmQgc2V0IHVwIGl0cyBldmVudCBoYW5kbGVyc1xuICB2YXIgcmVxdWVzdCA9IHRoaXMuX2N1cnJlbnRSZXF1ZXN0ID1cbiAgICAgICAgbmF0aXZlUHJvdG9jb2wucmVxdWVzdCh0aGlzLl9vcHRpb25zLCB0aGlzLl9vbk5hdGl2ZVJlc3BvbnNlKTtcbiAgcmVxdWVzdC5fcmVkaXJlY3RhYmxlID0gdGhpcztcbiAgZm9yICh2YXIgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgcmVxdWVzdC5vbihldmVudCwgZXZlbnRIYW5kbGVyc1tldmVudF0pO1xuICB9XG5cbiAgLy8gUkZDNzIzMMKnNS4zLjE6IFdoZW4gbWFraW5nIGEgcmVxdWVzdCBkaXJlY3RseSB0byBhbiBvcmlnaW4gc2VydmVyLCBb4oCmXVxuICAvLyBhIGNsaWVudCBNVVNUIHNlbmQgb25seSB0aGUgYWJzb2x1dGUgcGF0aCBb4oCmXSBhcyB0aGUgcmVxdWVzdC10YXJnZXQuXG4gIHRoaXMuX2N1cnJlbnRVcmwgPSAvXlxcLy8udGVzdCh0aGlzLl9vcHRpb25zLnBhdGgpID9cbiAgICB1cmwuZm9ybWF0KHRoaXMuX29wdGlvbnMpIDpcbiAgICAvLyBXaGVuIG1ha2luZyBhIHJlcXVlc3QgdG8gYSBwcm94eSwgW+KApl1cbiAgICAvLyBhIGNsaWVudCBNVVNUIHNlbmQgdGhlIHRhcmdldCBVUkkgaW4gYWJzb2x1dGUtZm9ybSBb4oCmXS5cbiAgICB0aGlzLl9vcHRpb25zLnBhdGg7XG5cbiAgLy8gRW5kIGEgcmVkaXJlY3RlZCByZXF1ZXN0XG4gIC8vIChUaGUgZmlyc3QgcmVxdWVzdCBtdXN0IGJlIGVuZGVkIGV4cGxpY2l0bHkgd2l0aCBSZWRpcmVjdGFibGVSZXF1ZXN0I2VuZClcbiAgaWYgKHRoaXMuX2lzUmVkaXJlY3QpIHtcbiAgICAvLyBXcml0ZSB0aGUgcmVxdWVzdCBlbnRpdHkgYW5kIGVuZFxuICAgIHZhciBpID0gMDtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGJ1ZmZlcnMgPSB0aGlzLl9yZXF1ZXN0Qm9keUJ1ZmZlcnM7XG4gICAgKGZ1bmN0aW9uIHdyaXRlTmV4dChlcnJvcikge1xuICAgICAgLy8gT25seSB3cml0ZSBpZiB0aGlzIHJlcXVlc3QgaGFzIG5vdCBiZWVuIHJlZGlyZWN0ZWQgeWV0XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgaWYgKHJlcXVlc3QgPT09IHNlbGYuX2N1cnJlbnRSZXF1ZXN0KSB7XG4gICAgICAgIC8vIFJlcG9ydCBhbnkgd3JpdGUgZXJyb3JzXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICBzZWxmLmVtaXQoXCJlcnJvclwiLCBlcnJvcik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gV3JpdGUgdGhlIG5leHQgYnVmZmVyIGlmIHRoZXJlIGFyZSBzdGlsbCBsZWZ0XG4gICAgICAgIGVsc2UgaWYgKGkgPCBidWZmZXJzLmxlbmd0aCkge1xuICAgICAgICAgIHZhciBidWZmZXIgPSBidWZmZXJzW2krK107XG4gICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgICAgICBpZiAoIXJlcXVlc3QuZmluaXNoZWQpIHtcbiAgICAgICAgICAgIHJlcXVlc3Qud3JpdGUoYnVmZmVyLmRhdGEsIGJ1ZmZlci5lbmNvZGluZywgd3JpdGVOZXh0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gRW5kIHRoZSByZXF1ZXN0IGlmIGBlbmRgIGhhcyBiZWVuIGNhbGxlZCBvbiB1c1xuICAgICAgICBlbHNlIGlmIChzZWxmLl9lbmRlZCkge1xuICAgICAgICAgIHJlcXVlc3QuZW5kKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KCkpO1xuICB9XG59O1xuXG4vLyBQcm9jZXNzZXMgYSByZXNwb25zZSBmcm9tIHRoZSBjdXJyZW50IG5hdGl2ZSByZXF1ZXN0XG5SZWRpcmVjdGFibGVSZXF1ZXN0LnByb3RvdHlwZS5fcHJvY2Vzc1Jlc3BvbnNlID0gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gIC8vIFN0b3JlIHRoZSByZWRpcmVjdGVkIHJlc3BvbnNlXG4gIHZhciBzdGF0dXNDb2RlID0gcmVzcG9uc2Uuc3RhdHVzQ29kZTtcbiAgaWYgKHRoaXMuX29wdGlvbnMudHJhY2tSZWRpcmVjdHMpIHtcbiAgICB0aGlzLl9yZWRpcmVjdHMucHVzaCh7XG4gICAgICB1cmw6IHRoaXMuX2N1cnJlbnRVcmwsXG4gICAgICBoZWFkZXJzOiByZXNwb25zZS5oZWFkZXJzLFxuICAgICAgc3RhdHVzQ29kZTogc3RhdHVzQ29kZSxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFJGQzcyMzHCpzYuNDogVGhlIDN4eCAoUmVkaXJlY3Rpb24pIGNsYXNzIG9mIHN0YXR1cyBjb2RlIGluZGljYXRlc1xuICAvLyB0aGF0IGZ1cnRoZXIgYWN0aW9uIG5lZWRzIHRvIGJlIHRha2VuIGJ5IHRoZSB1c2VyIGFnZW50IGluIG9yZGVyIHRvXG4gIC8vIGZ1bGZpbGwgdGhlIHJlcXVlc3QuIElmIGEgTG9jYXRpb24gaGVhZGVyIGZpZWxkIGlzIHByb3ZpZGVkLFxuICAvLyB0aGUgdXNlciBhZ2VudCBNQVkgYXV0b21hdGljYWxseSByZWRpcmVjdCBpdHMgcmVxdWVzdCB0byB0aGUgVVJJXG4gIC8vIHJlZmVyZW5jZWQgYnkgdGhlIExvY2F0aW9uIGZpZWxkIHZhbHVlLFxuICAvLyBldmVuIGlmIHRoZSBzcGVjaWZpYyBzdGF0dXMgY29kZSBpcyBub3QgdW5kZXJzdG9vZC5cblxuICAvLyBJZiB0aGUgcmVzcG9uc2UgaXMgbm90IGEgcmVkaXJlY3Q7IHJldHVybiBpdCBhcy1pc1xuICB2YXIgbG9jYXRpb24gPSByZXNwb25zZS5oZWFkZXJzLmxvY2F0aW9uO1xuICBpZiAoIWxvY2F0aW9uIHx8IHRoaXMuX29wdGlvbnMuZm9sbG93UmVkaXJlY3RzID09PSBmYWxzZSB8fFxuICAgICAgc3RhdHVzQ29kZSA8IDMwMCB8fCBzdGF0dXNDb2RlID49IDQwMCkge1xuICAgIHJlc3BvbnNlLnJlc3BvbnNlVXJsID0gdGhpcy5fY3VycmVudFVybDtcbiAgICByZXNwb25zZS5yZWRpcmVjdHMgPSB0aGlzLl9yZWRpcmVjdHM7XG4gICAgdGhpcy5lbWl0KFwicmVzcG9uc2VcIiwgcmVzcG9uc2UpO1xuXG4gICAgLy8gQ2xlYW4gdXBcbiAgICB0aGlzLl9yZXF1ZXN0Qm9keUJ1ZmZlcnMgPSBbXTtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBUaGUgcmVzcG9uc2UgaXMgYSByZWRpcmVjdCwgc28gYWJvcnQgdGhlIGN1cnJlbnQgcmVxdWVzdFxuICBkZXN0cm95UmVxdWVzdCh0aGlzLl9jdXJyZW50UmVxdWVzdCk7XG4gIC8vIERpc2NhcmQgdGhlIHJlbWFpbmRlciBvZiB0aGUgcmVzcG9uc2UgdG8gYXZvaWQgd2FpdGluZyBmb3IgZGF0YVxuICByZXNwb25zZS5kZXN0cm95KCk7XG5cbiAgLy8gUkZDNzIzMcKnNi40OiBBIGNsaWVudCBTSE9VTEQgZGV0ZWN0IGFuZCBpbnRlcnZlbmVcbiAgLy8gaW4gY3ljbGljYWwgcmVkaXJlY3Rpb25zIChpLmUuLCBcImluZmluaXRlXCIgcmVkaXJlY3Rpb24gbG9vcHMpLlxuICBpZiAoKyt0aGlzLl9yZWRpcmVjdENvdW50ID4gdGhpcy5fb3B0aW9ucy5tYXhSZWRpcmVjdHMpIHtcbiAgICB0aHJvdyBuZXcgVG9vTWFueVJlZGlyZWN0c0Vycm9yKCk7XG4gIH1cblxuICAvLyBTdG9yZSB0aGUgcmVxdWVzdCBoZWFkZXJzIGlmIGFwcGxpY2FibGVcbiAgdmFyIHJlcXVlc3RIZWFkZXJzO1xuICB2YXIgYmVmb3JlUmVkaXJlY3QgPSB0aGlzLl9vcHRpb25zLmJlZm9yZVJlZGlyZWN0O1xuICBpZiAoYmVmb3JlUmVkaXJlY3QpIHtcbiAgICByZXF1ZXN0SGVhZGVycyA9IE9iamVjdC5hc3NpZ24oe1xuICAgICAgLy8gVGhlIEhvc3QgaGVhZGVyIHdhcyBzZXQgYnkgbmF0aXZlUHJvdG9jb2wucmVxdWVzdFxuICAgICAgSG9zdDogcmVzcG9uc2UucmVxLmdldEhlYWRlcihcImhvc3RcIiksXG4gICAgfSwgdGhpcy5fb3B0aW9ucy5oZWFkZXJzKTtcbiAgfVxuXG4gIC8vIFJGQzcyMzHCpzYuNDogQXV0b21hdGljIHJlZGlyZWN0aW9uIG5lZWRzIHRvIGRvbmUgd2l0aFxuICAvLyBjYXJlIGZvciBtZXRob2RzIG5vdCBrbm93biB0byBiZSBzYWZlLCBb4oCmXVxuICAvLyBSRkM3MjMxwqc2LjQuMuKAkzM6IEZvciBoaXN0b3JpY2FsIHJlYXNvbnMsIGEgdXNlciBhZ2VudCBNQVkgY2hhbmdlXG4gIC8vIHRoZSByZXF1ZXN0IG1ldGhvZCBmcm9tIFBPU1QgdG8gR0VUIGZvciB0aGUgc3Vic2VxdWVudCByZXF1ZXN0LlxuICB2YXIgbWV0aG9kID0gdGhpcy5fb3B0aW9ucy5tZXRob2Q7XG4gIGlmICgoc3RhdHVzQ29kZSA9PT0gMzAxIHx8IHN0YXR1c0NvZGUgPT09IDMwMikgJiYgdGhpcy5fb3B0aW9ucy5tZXRob2QgPT09IFwiUE9TVFwiIHx8XG4gICAgICAvLyBSRkM3MjMxwqc2LjQuNDogVGhlIDMwMyAoU2VlIE90aGVyKSBzdGF0dXMgY29kZSBpbmRpY2F0ZXMgdGhhdFxuICAgICAgLy8gdGhlIHNlcnZlciBpcyByZWRpcmVjdGluZyB0aGUgdXNlciBhZ2VudCB0byBhIGRpZmZlcmVudCByZXNvdXJjZSBb4oCmXVxuICAgICAgLy8gQSB1c2VyIGFnZW50IGNhbiBwZXJmb3JtIGEgcmV0cmlldmFsIHJlcXVlc3QgdGFyZ2V0aW5nIHRoYXQgVVJJXG4gICAgICAvLyAoYSBHRVQgb3IgSEVBRCByZXF1ZXN0IGlmIHVzaW5nIEhUVFApIFvigKZdXG4gICAgICAoc3RhdHVzQ29kZSA9PT0gMzAzKSAmJiAhL14oPzpHRVR8SEVBRCkkLy50ZXN0KHRoaXMuX29wdGlvbnMubWV0aG9kKSkge1xuICAgIHRoaXMuX29wdGlvbnMubWV0aG9kID0gXCJHRVRcIjtcbiAgICAvLyBEcm9wIGEgcG9zc2libGUgZW50aXR5IGFuZCBoZWFkZXJzIHJlbGF0ZWQgdG8gaXRcbiAgICB0aGlzLl9yZXF1ZXN0Qm9keUJ1ZmZlcnMgPSBbXTtcbiAgICByZW1vdmVNYXRjaGluZ0hlYWRlcnMoL15jb250ZW50LS9pLCB0aGlzLl9vcHRpb25zLmhlYWRlcnMpO1xuICB9XG5cbiAgLy8gRHJvcCB0aGUgSG9zdCBoZWFkZXIsIGFzIHRoZSByZWRpcmVjdCBtaWdodCBsZWFkIHRvIGEgZGlmZmVyZW50IGhvc3RcbiAgdmFyIGN1cnJlbnRIb3N0SGVhZGVyID0gcmVtb3ZlTWF0Y2hpbmdIZWFkZXJzKC9eaG9zdCQvaSwgdGhpcy5fb3B0aW9ucy5oZWFkZXJzKTtcblxuICAvLyBJZiB0aGUgcmVkaXJlY3QgaXMgcmVsYXRpdmUsIGNhcnJ5IG92ZXIgdGhlIGhvc3Qgb2YgdGhlIGxhc3QgcmVxdWVzdFxuICB2YXIgY3VycmVudFVybFBhcnRzID0gcGFyc2VVcmwodGhpcy5fY3VycmVudFVybCk7XG4gIHZhciBjdXJyZW50SG9zdCA9IGN1cnJlbnRIb3N0SGVhZGVyIHx8IGN1cnJlbnRVcmxQYXJ0cy5ob3N0O1xuICB2YXIgY3VycmVudFVybCA9IC9eXFx3KzovLnRlc3QobG9jYXRpb24pID8gdGhpcy5fY3VycmVudFVybCA6XG4gICAgdXJsLmZvcm1hdChPYmplY3QuYXNzaWduKGN1cnJlbnRVcmxQYXJ0cywgeyBob3N0OiBjdXJyZW50SG9zdCB9KSk7XG5cbiAgLy8gQ3JlYXRlIHRoZSByZWRpcmVjdGVkIHJlcXVlc3RcbiAgdmFyIHJlZGlyZWN0VXJsID0gcmVzb2x2ZVVybChsb2NhdGlvbiwgY3VycmVudFVybCk7XG4gIGRlYnVnKFwicmVkaXJlY3RpbmcgdG9cIiwgcmVkaXJlY3RVcmwuaHJlZik7XG4gIHRoaXMuX2lzUmVkaXJlY3QgPSB0cnVlO1xuICBzcHJlYWRVcmxPYmplY3QocmVkaXJlY3RVcmwsIHRoaXMuX29wdGlvbnMpO1xuXG4gIC8vIERyb3AgY29uZmlkZW50aWFsIGhlYWRlcnMgd2hlbiByZWRpcmVjdGluZyB0byBhIGxlc3Mgc2VjdXJlIHByb3RvY29sXG4gIC8vIG9yIHRvIGEgZGlmZmVyZW50IGRvbWFpbiB0aGF0IGlzIG5vdCBhIHN1cGVyZG9tYWluXG4gIGlmIChyZWRpcmVjdFVybC5wcm90b2NvbCAhPT0gY3VycmVudFVybFBhcnRzLnByb3RvY29sICYmXG4gICAgIHJlZGlyZWN0VXJsLnByb3RvY29sICE9PSBcImh0dHBzOlwiIHx8XG4gICAgIHJlZGlyZWN0VXJsLmhvc3QgIT09IGN1cnJlbnRIb3N0ICYmXG4gICAgICFpc1N1YmRvbWFpbihyZWRpcmVjdFVybC5ob3N0LCBjdXJyZW50SG9zdCkpIHtcbiAgICByZW1vdmVNYXRjaGluZ0hlYWRlcnMoL14oPzphdXRob3JpemF0aW9ufGNvb2tpZSkkL2ksIHRoaXMuX29wdGlvbnMuaGVhZGVycyk7XG4gIH1cblxuICAvLyBFdmFsdWF0ZSB0aGUgYmVmb3JlUmVkaXJlY3QgY2FsbGJhY2tcbiAgaWYgKGlzRnVuY3Rpb24oYmVmb3JlUmVkaXJlY3QpKSB7XG4gICAgdmFyIHJlc3BvbnNlRGV0YWlscyA9IHtcbiAgICAgIGhlYWRlcnM6IHJlc3BvbnNlLmhlYWRlcnMsXG4gICAgICBzdGF0dXNDb2RlOiBzdGF0dXNDb2RlLFxuICAgIH07XG4gICAgdmFyIHJlcXVlc3REZXRhaWxzID0ge1xuICAgICAgdXJsOiBjdXJyZW50VXJsLFxuICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICBoZWFkZXJzOiByZXF1ZXN0SGVhZGVycyxcbiAgICB9O1xuICAgIGJlZm9yZVJlZGlyZWN0KHRoaXMuX29wdGlvbnMsIHJlc3BvbnNlRGV0YWlscywgcmVxdWVzdERldGFpbHMpO1xuICAgIHRoaXMuX3Nhbml0aXplT3B0aW9ucyh0aGlzLl9vcHRpb25zKTtcbiAgfVxuXG4gIC8vIFBlcmZvcm0gdGhlIHJlZGlyZWN0ZWQgcmVxdWVzdFxuICB0aGlzLl9wZXJmb3JtUmVxdWVzdCgpO1xufTtcblxuLy8gV3JhcHMgdGhlIGtleS92YWx1ZSBvYmplY3Qgb2YgcHJvdG9jb2xzIHdpdGggcmVkaXJlY3QgZnVuY3Rpb25hbGl0eVxuZnVuY3Rpb24gd3JhcChwcm90b2NvbHMpIHtcbiAgLy8gRGVmYXVsdCBzZXR0aW5nc1xuICB2YXIgZXhwb3J0cyA9IHtcbiAgICBtYXhSZWRpcmVjdHM6IDIxLFxuICAgIG1heEJvZHlMZW5ndGg6IDEwICogMTAyNCAqIDEwMjQsXG4gIH07XG5cbiAgLy8gV3JhcCBlYWNoIHByb3RvY29sXG4gIHZhciBuYXRpdmVQcm90b2NvbHMgPSB7fTtcbiAgT2JqZWN0LmtleXMocHJvdG9jb2xzKS5mb3JFYWNoKGZ1bmN0aW9uIChzY2hlbWUpIHtcbiAgICB2YXIgcHJvdG9jb2wgPSBzY2hlbWUgKyBcIjpcIjtcbiAgICB2YXIgbmF0aXZlUHJvdG9jb2wgPSBuYXRpdmVQcm90b2NvbHNbcHJvdG9jb2xdID0gcHJvdG9jb2xzW3NjaGVtZV07XG4gICAgdmFyIHdyYXBwZWRQcm90b2NvbCA9IGV4cG9ydHNbc2NoZW1lXSA9IE9iamVjdC5jcmVhdGUobmF0aXZlUHJvdG9jb2wpO1xuXG4gICAgLy8gRXhlY3V0ZXMgYSByZXF1ZXN0LCBmb2xsb3dpbmcgcmVkaXJlY3RzXG4gICAgZnVuY3Rpb24gcmVxdWVzdChpbnB1dCwgb3B0aW9ucywgY2FsbGJhY2spIHtcbiAgICAgIC8vIFBhcnNlIHBhcmFtZXRlcnMsIGVuc3VyaW5nIHRoYXQgaW5wdXQgaXMgYW4gb2JqZWN0XG4gICAgICBpZiAoaXNVUkwoaW5wdXQpKSB7XG4gICAgICAgIGlucHV0ID0gc3ByZWFkVXJsT2JqZWN0KGlucHV0KTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGlzU3RyaW5nKGlucHV0KSkge1xuICAgICAgICBpbnB1dCA9IHNwcmVhZFVybE9iamVjdChwYXJzZVVybChpbnB1dCkpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGNhbGxiYWNrID0gb3B0aW9ucztcbiAgICAgICAgb3B0aW9ucyA9IHZhbGlkYXRlVXJsKGlucHV0KTtcbiAgICAgICAgaW5wdXQgPSB7IHByb3RvY29sOiBwcm90b2NvbCB9O1xuICAgICAgfVxuICAgICAgaWYgKGlzRnVuY3Rpb24ob3B0aW9ucykpIHtcbiAgICAgICAgY2FsbGJhY2sgPSBvcHRpb25zO1xuICAgICAgICBvcHRpb25zID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgLy8gU2V0IGRlZmF1bHRzXG4gICAgICBvcHRpb25zID0gT2JqZWN0LmFzc2lnbih7XG4gICAgICAgIG1heFJlZGlyZWN0czogZXhwb3J0cy5tYXhSZWRpcmVjdHMsXG4gICAgICAgIG1heEJvZHlMZW5ndGg6IGV4cG9ydHMubWF4Qm9keUxlbmd0aCxcbiAgICAgIH0sIGlucHV0LCBvcHRpb25zKTtcbiAgICAgIG9wdGlvbnMubmF0aXZlUHJvdG9jb2xzID0gbmF0aXZlUHJvdG9jb2xzO1xuICAgICAgaWYgKCFpc1N0cmluZyhvcHRpb25zLmhvc3QpICYmICFpc1N0cmluZyhvcHRpb25zLmhvc3RuYW1lKSkge1xuICAgICAgICBvcHRpb25zLmhvc3RuYW1lID0gXCI6OjFcIjtcbiAgICAgIH1cblxuICAgICAgYXNzZXJ0LmVxdWFsKG9wdGlvbnMucHJvdG9jb2wsIHByb3RvY29sLCBcInByb3RvY29sIG1pc21hdGNoXCIpO1xuICAgICAgZGVidWcoXCJvcHRpb25zXCIsIG9wdGlvbnMpO1xuICAgICAgcmV0dXJuIG5ldyBSZWRpcmVjdGFibGVSZXF1ZXN0KG9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICAvLyBFeGVjdXRlcyBhIEdFVCByZXF1ZXN0LCBmb2xsb3dpbmcgcmVkaXJlY3RzXG4gICAgZnVuY3Rpb24gZ2V0KGlucHV0LCBvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgdmFyIHdyYXBwZWRSZXF1ZXN0ID0gd3JhcHBlZFByb3RvY29sLnJlcXVlc3QoaW5wdXQsIG9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgICAgIHdyYXBwZWRSZXF1ZXN0LmVuZCgpO1xuICAgICAgcmV0dXJuIHdyYXBwZWRSZXF1ZXN0O1xuICAgIH1cblxuICAgIC8vIEV4cG9zZSB0aGUgcHJvcGVydGllcyBvbiB0aGUgd3JhcHBlZCBwcm90b2NvbFxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHdyYXBwZWRQcm90b2NvbCwge1xuICAgICAgcmVxdWVzdDogeyB2YWx1ZTogcmVxdWVzdCwgY29uZmlndXJhYmxlOiB0cnVlLCBlbnVtZXJhYmxlOiB0cnVlLCB3cml0YWJsZTogdHJ1ZSB9LFxuICAgICAgZ2V0OiB7IHZhbHVlOiBnZXQsIGNvbmZpZ3VyYWJsZTogdHJ1ZSwgZW51bWVyYWJsZTogdHJ1ZSwgd3JpdGFibGU6IHRydWUgfSxcbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiBleHBvcnRzO1xufVxuXG5mdW5jdGlvbiBub29wKCkgeyAvKiBlbXB0eSAqLyB9XG5cbmZ1bmN0aW9uIHBhcnNlVXJsKGlucHV0KSB7XG4gIHZhciBwYXJzZWQ7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gIGlmICh1c2VOYXRpdmVVUkwpIHtcbiAgICBwYXJzZWQgPSBuZXcgVVJMKGlucHV0KTtcbiAgfVxuICBlbHNlIHtcbiAgICAvLyBFbnN1cmUgdGhlIFVSTCBpcyB2YWxpZCBhbmQgYWJzb2x1dGVcbiAgICBwYXJzZWQgPSB2YWxpZGF0ZVVybCh1cmwucGFyc2UoaW5wdXQpKTtcbiAgICBpZiAoIWlzU3RyaW5nKHBhcnNlZC5wcm90b2NvbCkpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkVXJsRXJyb3IoeyBpbnB1dCB9KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHBhcnNlZDtcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZVVybChyZWxhdGl2ZSwgYmFzZSkge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICByZXR1cm4gdXNlTmF0aXZlVVJMID8gbmV3IFVSTChyZWxhdGl2ZSwgYmFzZSkgOiBwYXJzZVVybCh1cmwucmVzb2x2ZShiYXNlLCByZWxhdGl2ZSkpO1xufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZVVybChpbnB1dCkge1xuICBpZiAoL15cXFsvLnRlc3QoaW5wdXQuaG9zdG5hbWUpICYmICEvXlxcW1s6MC05YS1mXStcXF0kL2kudGVzdChpbnB1dC5ob3N0bmFtZSkpIHtcbiAgICB0aHJvdyBuZXcgSW52YWxpZFVybEVycm9yKHsgaW5wdXQ6IGlucHV0LmhyZWYgfHwgaW5wdXQgfSk7XG4gIH1cbiAgaWYgKC9eXFxbLy50ZXN0KGlucHV0Lmhvc3QpICYmICEvXlxcW1s6MC05YS1mXStcXF0oOlxcZCspPyQvaS50ZXN0KGlucHV0Lmhvc3QpKSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRVcmxFcnJvcih7IGlucHV0OiBpbnB1dC5ocmVmIHx8IGlucHV0IH0pO1xuICB9XG4gIHJldHVybiBpbnB1dDtcbn1cblxuZnVuY3Rpb24gc3ByZWFkVXJsT2JqZWN0KHVybE9iamVjdCwgdGFyZ2V0KSB7XG4gIHZhciBzcHJlYWQgPSB0YXJnZXQgfHwge307XG4gIGZvciAodmFyIGtleSBvZiBwcmVzZXJ2ZWRVcmxGaWVsZHMpIHtcbiAgICBzcHJlYWRba2V5XSA9IHVybE9iamVjdFtrZXldO1xuICB9XG5cbiAgLy8gRml4IElQdjYgaG9zdG5hbWVcbiAgaWYgKHNwcmVhZC5ob3N0bmFtZS5zdGFydHNXaXRoKFwiW1wiKSkge1xuICAgIHNwcmVhZC5ob3N0bmFtZSA9IHNwcmVhZC5ob3N0bmFtZS5zbGljZSgxLCAtMSk7XG4gIH1cbiAgLy8gRW5zdXJlIHBvcnQgaXMgYSBudW1iZXJcbiAgaWYgKHNwcmVhZC5wb3J0ICE9PSBcIlwiKSB7XG4gICAgc3ByZWFkLnBvcnQgPSBOdW1iZXIoc3ByZWFkLnBvcnQpO1xuICB9XG4gIC8vIENvbmNhdGVuYXRlIHBhdGhcbiAgc3ByZWFkLnBhdGggPSBzcHJlYWQuc2VhcmNoID8gc3ByZWFkLnBhdGhuYW1lICsgc3ByZWFkLnNlYXJjaCA6IHNwcmVhZC5wYXRobmFtZTtcblxuICByZXR1cm4gc3ByZWFkO1xufVxuXG5mdW5jdGlvbiByZW1vdmVNYXRjaGluZ0hlYWRlcnMocmVnZXgsIGhlYWRlcnMpIHtcbiAgdmFyIGxhc3RWYWx1ZTtcbiAgZm9yICh2YXIgaGVhZGVyIGluIGhlYWRlcnMpIHtcbiAgICBpZiAocmVnZXgudGVzdChoZWFkZXIpKSB7XG4gICAgICBsYXN0VmFsdWUgPSBoZWFkZXJzW2hlYWRlcl07XG4gICAgICBkZWxldGUgaGVhZGVyc1toZWFkZXJdO1xuICAgIH1cbiAgfVxuICByZXR1cm4gKGxhc3RWYWx1ZSA9PT0gbnVsbCB8fCB0eXBlb2YgbGFzdFZhbHVlID09PSBcInVuZGVmaW5lZFwiKSA/XG4gICAgdW5kZWZpbmVkIDogU3RyaW5nKGxhc3RWYWx1ZSkudHJpbSgpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVFcnJvclR5cGUoY29kZSwgbWVzc2FnZSwgYmFzZUNsYXNzKSB7XG4gIC8vIENyZWF0ZSBjb25zdHJ1Y3RvclxuICBmdW5jdGlvbiBDdXN0b21FcnJvcihwcm9wZXJ0aWVzKSB7XG4gICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgdGhpcy5jb25zdHJ1Y3Rvcik7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLCBwcm9wZXJ0aWVzIHx8IHt9KTtcbiAgICB0aGlzLmNvZGUgPSBjb2RlO1xuICAgIHRoaXMubWVzc2FnZSA9IHRoaXMuY2F1c2UgPyBtZXNzYWdlICsgXCI6IFwiICsgdGhpcy5jYXVzZS5tZXNzYWdlIDogbWVzc2FnZTtcbiAgfVxuXG4gIC8vIEF0dGFjaCBjb25zdHJ1Y3RvciBhbmQgc2V0IGRlZmF1bHQgcHJvcGVydGllc1xuICBDdXN0b21FcnJvci5wcm90b3R5cGUgPSBuZXcgKGJhc2VDbGFzcyB8fCBFcnJvcikoKTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoQ3VzdG9tRXJyb3IucHJvdG90eXBlLCB7XG4gICAgY29uc3RydWN0b3I6IHtcbiAgICAgIHZhbHVlOiBDdXN0b21FcnJvcixcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIH0sXG4gICAgbmFtZToge1xuICAgICAgdmFsdWU6IFwiRXJyb3IgW1wiICsgY29kZSArIFwiXVwiLFxuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgfSxcbiAgfSk7XG4gIHJldHVybiBDdXN0b21FcnJvcjtcbn1cblxuZnVuY3Rpb24gZGVzdHJveVJlcXVlc3QocmVxdWVzdCwgZXJyb3IpIHtcbiAgZm9yICh2YXIgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgcmVxdWVzdC5yZW1vdmVMaXN0ZW5lcihldmVudCwgZXZlbnRIYW5kbGVyc1tldmVudF0pO1xuICB9XG4gIHJlcXVlc3Qub24oXCJlcnJvclwiLCBub29wKTtcbiAgcmVxdWVzdC5kZXN0cm95KGVycm9yKTtcbn1cblxuZnVuY3Rpb24gaXNTdWJkb21haW4oc3ViZG9tYWluLCBkb21haW4pIHtcbiAgYXNzZXJ0KGlzU3RyaW5nKHN1YmRvbWFpbikgJiYgaXNTdHJpbmcoZG9tYWluKSk7XG4gIHZhciBkb3QgPSBzdWJkb21haW4ubGVuZ3RoIC0gZG9tYWluLmxlbmd0aCAtIDE7XG4gIHJldHVybiBkb3QgPiAwICYmIHN1YmRvbWFpbltkb3RdID09PSBcIi5cIiAmJiBzdWJkb21haW4uZW5kc1dpdGgoZG9tYWluKTtcbn1cblxuZnVuY3Rpb24gaXNTdHJpbmcodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiB8fCB2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZztcbn1cblxuZnVuY3Rpb24gaXNGdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCI7XG59XG5cbmZ1bmN0aW9uIGlzQnVmZmVyKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgKFwibGVuZ3RoXCIgaW4gdmFsdWUpO1xufVxuXG5mdW5jdGlvbiBpc1VSTCh2YWx1ZSkge1xuICByZXR1cm4gVVJMICYmIHZhbHVlIGluc3RhbmNlb2YgVVJMO1xufVxuXG4vLyBFeHBvcnRzXG5tb2R1bGUuZXhwb3J0cyA9IHdyYXAoeyBodHRwOiBodHRwLCBodHRwczogaHR0cHMgfSk7XG5tb2R1bGUuZXhwb3J0cy53cmFwID0gd3JhcDtcbiIsIid1c2Ugc3RyaWN0Jztcbm1vZHVsZS5leHBvcnRzID0gKGZsYWcsIGFyZ3YpID0+IHtcblx0YXJndiA9IGFyZ3YgfHwgcHJvY2Vzcy5hcmd2O1xuXHRjb25zdCBwcmVmaXggPSBmbGFnLnN0YXJ0c1dpdGgoJy0nKSA/ICcnIDogKGZsYWcubGVuZ3RoID09PSAxID8gJy0nIDogJy0tJyk7XG5cdGNvbnN0IHBvcyA9IGFyZ3YuaW5kZXhPZihwcmVmaXggKyBmbGFnKTtcblx0Y29uc3QgdGVybWluYXRvclBvcyA9IGFyZ3YuaW5kZXhPZignLS0nKTtcblx0cmV0dXJuIHBvcyAhPT0gLTEgJiYgKHRlcm1pbmF0b3JQb3MgPT09IC0xID8gdHJ1ZSA6IHBvcyA8IHRlcm1pbmF0b3JQb3MpO1xufTtcbiIsIi8qIVxuICogbWltZS1kYlxuICogQ29weXJpZ2h0KGMpIDIwMTQgSm9uYXRoYW4gT25nXG4gKiBDb3B5cmlnaHQoYykgMjAxNS0yMDIyIERvdWdsYXMgQ2hyaXN0b3BoZXIgV2lsc29uXG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9kYi5qc29uJylcbiIsIi8qIVxuICogbWltZS10eXBlc1xuICogQ29weXJpZ2h0KGMpIDIwMTQgSm9uYXRoYW4gT25nXG4gKiBDb3B5cmlnaHQoYykgMjAxNSBEb3VnbGFzIENocmlzdG9waGVyIFdpbHNvblxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuJ3VzZSBzdHJpY3QnXG5cbi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqIEBwcml2YXRlXG4gKi9cblxudmFyIGRiID0gcmVxdWlyZSgnbWltZS1kYicpXG52YXIgZXh0bmFtZSA9IHJlcXVpcmUoJ3BhdGgnKS5leHRuYW1lXG5cbi8qKlxuICogTW9kdWxlIHZhcmlhYmxlcy5cbiAqIEBwcml2YXRlXG4gKi9cblxudmFyIEVYVFJBQ1RfVFlQRV9SRUdFWFAgPSAvXlxccyooW147XFxzXSopKD86O3xcXHN8JCkvXG52YXIgVEVYVF9UWVBFX1JFR0VYUCA9IC9edGV4dFxcLy9pXG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKiBAcHVibGljXG4gKi9cblxuZXhwb3J0cy5jaGFyc2V0ID0gY2hhcnNldFxuZXhwb3J0cy5jaGFyc2V0cyA9IHsgbG9va3VwOiBjaGFyc2V0IH1cbmV4cG9ydHMuY29udGVudFR5cGUgPSBjb250ZW50VHlwZVxuZXhwb3J0cy5leHRlbnNpb24gPSBleHRlbnNpb25cbmV4cG9ydHMuZXh0ZW5zaW9ucyA9IE9iamVjdC5jcmVhdGUobnVsbClcbmV4cG9ydHMubG9va3VwID0gbG9va3VwXG5leHBvcnRzLnR5cGVzID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuXG4vLyBQb3B1bGF0ZSB0aGUgZXh0ZW5zaW9ucy90eXBlcyBtYXBzXG5wb3B1bGF0ZU1hcHMoZXhwb3J0cy5leHRlbnNpb25zLCBleHBvcnRzLnR5cGVzKVxuXG4vKipcbiAqIEdldCB0aGUgZGVmYXVsdCBjaGFyc2V0IGZvciBhIE1JTUUgdHlwZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdHlwZVxuICogQHJldHVybiB7Ym9vbGVhbnxzdHJpbmd9XG4gKi9cblxuZnVuY3Rpb24gY2hhcnNldCAodHlwZSkge1xuICBpZiAoIXR5cGUgfHwgdHlwZW9mIHR5cGUgIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvLyBUT0RPOiB1c2UgbWVkaWEtdHlwZXJcbiAgdmFyIG1hdGNoID0gRVhUUkFDVF9UWVBFX1JFR0VYUC5leGVjKHR5cGUpXG4gIHZhciBtaW1lID0gbWF0Y2ggJiYgZGJbbWF0Y2hbMV0udG9Mb3dlckNhc2UoKV1cblxuICBpZiAobWltZSAmJiBtaW1lLmNoYXJzZXQpIHtcbiAgICByZXR1cm4gbWltZS5jaGFyc2V0XG4gIH1cblxuICAvLyBkZWZhdWx0IHRleHQvKiB0byB1dGYtOFxuICBpZiAobWF0Y2ggJiYgVEVYVF9UWVBFX1JFR0VYUC50ZXN0KG1hdGNoWzFdKSkge1xuICAgIHJldHVybiAnVVRGLTgnXG4gIH1cblxuICByZXR1cm4gZmFsc2Vcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBmdWxsIENvbnRlbnQtVHlwZSBoZWFkZXIgZ2l2ZW4gYSBNSU1FIHR5cGUgb3IgZXh0ZW5zaW9uLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge2Jvb2xlYW58c3RyaW5nfVxuICovXG5cbmZ1bmN0aW9uIGNvbnRlbnRUeXBlIChzdHIpIHtcbiAgLy8gVE9ETzogc2hvdWxkIHRoaXMgZXZlbiBiZSBpbiB0aGlzIG1vZHVsZT9cbiAgaWYgKCFzdHIgfHwgdHlwZW9mIHN0ciAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHZhciBtaW1lID0gc3RyLmluZGV4T2YoJy8nKSA9PT0gLTFcbiAgICA/IGV4cG9ydHMubG9va3VwKHN0cilcbiAgICA6IHN0clxuXG4gIGlmICghbWltZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLy8gVE9ETzogdXNlIGNvbnRlbnQtdHlwZSBvciBvdGhlciBtb2R1bGVcbiAgaWYgKG1pbWUuaW5kZXhPZignY2hhcnNldCcpID09PSAtMSkge1xuICAgIHZhciBjaGFyc2V0ID0gZXhwb3J0cy5jaGFyc2V0KG1pbWUpXG4gICAgaWYgKGNoYXJzZXQpIG1pbWUgKz0gJzsgY2hhcnNldD0nICsgY2hhcnNldC50b0xvd2VyQ2FzZSgpXG4gIH1cblxuICByZXR1cm4gbWltZVxufVxuXG4vKipcbiAqIEdldCB0aGUgZGVmYXVsdCBleHRlbnNpb24gZm9yIGEgTUlNRSB0eXBlLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlXG4gKiBAcmV0dXJuIHtib29sZWFufHN0cmluZ31cbiAqL1xuXG5mdW5jdGlvbiBleHRlbnNpb24gKHR5cGUpIHtcbiAgaWYgKCF0eXBlIHx8IHR5cGVvZiB0eXBlICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLy8gVE9ETzogdXNlIG1lZGlhLXR5cGVyXG4gIHZhciBtYXRjaCA9IEVYVFJBQ1RfVFlQRV9SRUdFWFAuZXhlYyh0eXBlKVxuXG4gIC8vIGdldCBleHRlbnNpb25zXG4gIHZhciBleHRzID0gbWF0Y2ggJiYgZXhwb3J0cy5leHRlbnNpb25zW21hdGNoWzFdLnRvTG93ZXJDYXNlKCldXG5cbiAgaWYgKCFleHRzIHx8ICFleHRzLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgcmV0dXJuIGV4dHNbMF1cbn1cblxuLyoqXG4gKiBMb29rdXAgdGhlIE1JTUUgdHlwZSBmb3IgYSBmaWxlIHBhdGgvZXh0ZW5zaW9uLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoXG4gKiBAcmV0dXJuIHtib29sZWFufHN0cmluZ31cbiAqL1xuXG5mdW5jdGlvbiBsb29rdXAgKHBhdGgpIHtcbiAgaWYgKCFwYXRoIHx8IHR5cGVvZiBwYXRoICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLy8gZ2V0IHRoZSBleHRlbnNpb24gKFwiZXh0XCIgb3IgXCIuZXh0XCIgb3IgZnVsbCBwYXRoKVxuICB2YXIgZXh0ZW5zaW9uID0gZXh0bmFtZSgneC4nICsgcGF0aClcbiAgICAudG9Mb3dlckNhc2UoKVxuICAgIC5zdWJzdHIoMSlcblxuICBpZiAoIWV4dGVuc2lvbikge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgcmV0dXJuIGV4cG9ydHMudHlwZXNbZXh0ZW5zaW9uXSB8fCBmYWxzZVxufVxuXG4vKipcbiAqIFBvcHVsYXRlIHRoZSBleHRlbnNpb25zIGFuZCB0eXBlcyBtYXBzLlxuICogQHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBwb3B1bGF0ZU1hcHMgKGV4dGVuc2lvbnMsIHR5cGVzKSB7XG4gIC8vIHNvdXJjZSBwcmVmZXJlbmNlIChsZWFzdCAtPiBtb3N0KVxuICB2YXIgcHJlZmVyZW5jZSA9IFsnbmdpbngnLCAnYXBhY2hlJywgdW5kZWZpbmVkLCAnaWFuYSddXG5cbiAgT2JqZWN0LmtleXMoZGIpLmZvckVhY2goZnVuY3Rpb24gZm9yRWFjaE1pbWVUeXBlICh0eXBlKSB7XG4gICAgdmFyIG1pbWUgPSBkYlt0eXBlXVxuICAgIHZhciBleHRzID0gbWltZS5leHRlbnNpb25zXG5cbiAgICBpZiAoIWV4dHMgfHwgIWV4dHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBtaW1lIC0+IGV4dGVuc2lvbnNcbiAgICBleHRlbnNpb25zW3R5cGVdID0gZXh0c1xuXG4gICAgLy8gZXh0ZW5zaW9uIC0+IG1pbWVcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGV4dHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBleHRlbnNpb24gPSBleHRzW2ldXG5cbiAgICAgIGlmICh0eXBlc1tleHRlbnNpb25dKSB7XG4gICAgICAgIHZhciBmcm9tID0gcHJlZmVyZW5jZS5pbmRleE9mKGRiW3R5cGVzW2V4dGVuc2lvbl1dLnNvdXJjZSlcbiAgICAgICAgdmFyIHRvID0gcHJlZmVyZW5jZS5pbmRleE9mKG1pbWUuc291cmNlKVxuXG4gICAgICAgIGlmICh0eXBlc1tleHRlbnNpb25dICE9PSAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJyAmJlxuICAgICAgICAgIChmcm9tID4gdG8gfHwgKGZyb20gPT09IHRvICYmIHR5cGVzW2V4dGVuc2lvbl0uc3Vic3RyKDAsIDEyKSA9PT0gJ2FwcGxpY2F0aW9uLycpKSkge1xuICAgICAgICAgIC8vIHNraXAgdGhlIHJlbWFwcGluZ1xuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gc2V0IHRoZSBleHRlbnNpb24gLT4gbWltZVxuICAgICAgdHlwZXNbZXh0ZW5zaW9uXSA9IHR5cGVcbiAgICB9XG4gIH0pXG59XG4iLCIvKipcbiAqIEhlbHBlcnMuXG4gKi9cblxudmFyIHMgPSAxMDAwO1xudmFyIG0gPSBzICogNjA7XG52YXIgaCA9IG0gKiA2MDtcbnZhciBkID0gaCAqIDI0O1xudmFyIHcgPSBkICogNztcbnZhciB5ID0gZCAqIDM2NS4yNTtcblxuLyoqXG4gKiBQYXJzZSBvciBmb3JtYXQgdGhlIGdpdmVuIGB2YWxgLlxuICpcbiAqIE9wdGlvbnM6XG4gKlxuICogIC0gYGxvbmdgIHZlcmJvc2UgZm9ybWF0dGluZyBbZmFsc2VdXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8TnVtYmVyfSB2YWxcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAqIEB0aHJvd3Mge0Vycm9yfSB0aHJvdyBhbiBlcnJvciBpZiB2YWwgaXMgbm90IGEgbm9uLWVtcHR5IHN0cmluZyBvciBhIG51bWJlclxuICogQHJldHVybiB7U3RyaW5nfE51bWJlcn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih2YWwsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHZhciB0eXBlID0gdHlwZW9mIHZhbDtcbiAgaWYgKHR5cGUgPT09ICdzdHJpbmcnICYmIHZhbC5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIHBhcnNlKHZhbCk7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgaXNGaW5pdGUodmFsKSkge1xuICAgIHJldHVybiBvcHRpb25zLmxvbmcgPyBmbXRMb25nKHZhbCkgOiBmbXRTaG9ydCh2YWwpO1xuICB9XG4gIHRocm93IG5ldyBFcnJvcihcbiAgICAndmFsIGlzIG5vdCBhIG5vbi1lbXB0eSBzdHJpbmcgb3IgYSB2YWxpZCBudW1iZXIuIHZhbD0nICtcbiAgICAgIEpTT04uc3RyaW5naWZ5KHZhbClcbiAgKTtcbn07XG5cbi8qKlxuICogUGFyc2UgdGhlIGdpdmVuIGBzdHJgIGFuZCByZXR1cm4gbWlsbGlzZWNvbmRzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge051bWJlcn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcnNlKHN0cikge1xuICBzdHIgPSBTdHJpbmcoc3RyKTtcbiAgaWYgKHN0ci5sZW5ndGggPiAxMDApIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIG1hdGNoID0gL14oLT8oPzpcXGQrKT9cXC4/XFxkKykgKihtaWxsaXNlY29uZHM/fG1zZWNzP3xtc3xzZWNvbmRzP3xzZWNzP3xzfG1pbnV0ZXM/fG1pbnM/fG18aG91cnM/fGhycz98aHxkYXlzP3xkfHdlZWtzP3x3fHllYXJzP3x5cnM/fHkpPyQvaS5leGVjKFxuICAgIHN0clxuICApO1xuICBpZiAoIW1hdGNoKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBuID0gcGFyc2VGbG9hdChtYXRjaFsxXSk7XG4gIHZhciB0eXBlID0gKG1hdGNoWzJdIHx8ICdtcycpLnRvTG93ZXJDYXNlKCk7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ3llYXJzJzpcbiAgICBjYXNlICd5ZWFyJzpcbiAgICBjYXNlICd5cnMnOlxuICAgIGNhc2UgJ3lyJzpcbiAgICBjYXNlICd5JzpcbiAgICAgIHJldHVybiBuICogeTtcbiAgICBjYXNlICd3ZWVrcyc6XG4gICAgY2FzZSAnd2Vlayc6XG4gICAgY2FzZSAndyc6XG4gICAgICByZXR1cm4gbiAqIHc7XG4gICAgY2FzZSAnZGF5cyc6XG4gICAgY2FzZSAnZGF5JzpcbiAgICBjYXNlICdkJzpcbiAgICAgIHJldHVybiBuICogZDtcbiAgICBjYXNlICdob3Vycyc6XG4gICAgY2FzZSAnaG91cic6XG4gICAgY2FzZSAnaHJzJzpcbiAgICBjYXNlICdocic6XG4gICAgY2FzZSAnaCc6XG4gICAgICByZXR1cm4gbiAqIGg7XG4gICAgY2FzZSAnbWludXRlcyc6XG4gICAgY2FzZSAnbWludXRlJzpcbiAgICBjYXNlICdtaW5zJzpcbiAgICBjYXNlICdtaW4nOlxuICAgIGNhc2UgJ20nOlxuICAgICAgcmV0dXJuIG4gKiBtO1xuICAgIGNhc2UgJ3NlY29uZHMnOlxuICAgIGNhc2UgJ3NlY29uZCc6XG4gICAgY2FzZSAnc2Vjcyc6XG4gICAgY2FzZSAnc2VjJzpcbiAgICBjYXNlICdzJzpcbiAgICAgIHJldHVybiBuICogcztcbiAgICBjYXNlICdtaWxsaXNlY29uZHMnOlxuICAgIGNhc2UgJ21pbGxpc2Vjb25kJzpcbiAgICBjYXNlICdtc2Vjcyc6XG4gICAgY2FzZSAnbXNlYyc6XG4gICAgY2FzZSAnbXMnOlxuICAgICAgcmV0dXJuIG47XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBTaG9ydCBmb3JtYXQgZm9yIGBtc2AuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBmbXRTaG9ydChtcykge1xuICB2YXIgbXNBYnMgPSBNYXRoLmFicyhtcyk7XG4gIGlmIChtc0FicyA+PSBkKSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQobXMgLyBkKSArICdkJztcbiAgfVxuICBpZiAobXNBYnMgPj0gaCkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gaCkgKyAnaCc7XG4gIH1cbiAgaWYgKG1zQWJzID49IG0pIHtcbiAgICByZXR1cm4gTWF0aC5yb3VuZChtcyAvIG0pICsgJ20nO1xuICB9XG4gIGlmIChtc0FicyA+PSBzKSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQobXMgLyBzKSArICdzJztcbiAgfVxuICByZXR1cm4gbXMgKyAnbXMnO1xufVxuXG4vKipcbiAqIExvbmcgZm9ybWF0IGZvciBgbXNgLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBtc1xuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gZm10TG9uZyhtcykge1xuICB2YXIgbXNBYnMgPSBNYXRoLmFicyhtcyk7XG4gIGlmIChtc0FicyA+PSBkKSB7XG4gICAgcmV0dXJuIHBsdXJhbChtcywgbXNBYnMsIGQsICdkYXknKTtcbiAgfVxuICBpZiAobXNBYnMgPj0gaCkge1xuICAgIHJldHVybiBwbHVyYWwobXMsIG1zQWJzLCBoLCAnaG91cicpO1xuICB9XG4gIGlmIChtc0FicyA+PSBtKSB7XG4gICAgcmV0dXJuIHBsdXJhbChtcywgbXNBYnMsIG0sICdtaW51dGUnKTtcbiAgfVxuICBpZiAobXNBYnMgPj0gcykge1xuICAgIHJldHVybiBwbHVyYWwobXMsIG1zQWJzLCBzLCAnc2Vjb25kJyk7XG4gIH1cbiAgcmV0dXJuIG1zICsgJyBtcyc7XG59XG5cbi8qKlxuICogUGx1cmFsaXphdGlvbiBoZWxwZXIuXG4gKi9cblxuZnVuY3Rpb24gcGx1cmFsKG1zLCBtc0FicywgbiwgbmFtZSkge1xuICB2YXIgaXNQbHVyYWwgPSBtc0FicyA+PSBuICogMS41O1xuICByZXR1cm4gTWF0aC5yb3VuZChtcyAvIG4pICsgJyAnICsgbmFtZSArIChpc1BsdXJhbCA/ICdzJyA6ICcnKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHBhcnNlVXJsID0gcmVxdWlyZSgndXJsJykucGFyc2U7XG5cbnZhciBERUZBVUxUX1BPUlRTID0ge1xuICBmdHA6IDIxLFxuICBnb3BoZXI6IDcwLFxuICBodHRwOiA4MCxcbiAgaHR0cHM6IDQ0MyxcbiAgd3M6IDgwLFxuICB3c3M6IDQ0Myxcbn07XG5cbnZhciBzdHJpbmdFbmRzV2l0aCA9IFN0cmluZy5wcm90b3R5cGUuZW5kc1dpdGggfHwgZnVuY3Rpb24ocykge1xuICByZXR1cm4gcy5sZW5ndGggPD0gdGhpcy5sZW5ndGggJiZcbiAgICB0aGlzLmluZGV4T2YocywgdGhpcy5sZW5ndGggLSBzLmxlbmd0aCkgIT09IC0xO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ3xvYmplY3R9IHVybCAtIFRoZSBVUkwsIG9yIHRoZSByZXN1bHQgZnJvbSB1cmwucGFyc2UuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBVUkwgb2YgdGhlIHByb3h5IHRoYXQgc2hvdWxkIGhhbmRsZSB0aGUgcmVxdWVzdCB0byB0aGVcbiAqICBnaXZlbiBVUkwuIElmIG5vIHByb3h5IGlzIHNldCwgdGhpcyB3aWxsIGJlIGFuIGVtcHR5IHN0cmluZy5cbiAqL1xuZnVuY3Rpb24gZ2V0UHJveHlGb3JVcmwodXJsKSB7XG4gIHZhciBwYXJzZWRVcmwgPSB0eXBlb2YgdXJsID09PSAnc3RyaW5nJyA/IHBhcnNlVXJsKHVybCkgOiB1cmwgfHwge307XG4gIHZhciBwcm90byA9IHBhcnNlZFVybC5wcm90b2NvbDtcbiAgdmFyIGhvc3RuYW1lID0gcGFyc2VkVXJsLmhvc3Q7XG4gIHZhciBwb3J0ID0gcGFyc2VkVXJsLnBvcnQ7XG4gIGlmICh0eXBlb2YgaG9zdG5hbWUgIT09ICdzdHJpbmcnIHx8ICFob3N0bmFtZSB8fCB0eXBlb2YgcHJvdG8gIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuICcnOyAgLy8gRG9uJ3QgcHJveHkgVVJMcyB3aXRob3V0IGEgdmFsaWQgc2NoZW1lIG9yIGhvc3QuXG4gIH1cblxuICBwcm90byA9IHByb3RvLnNwbGl0KCc6JywgMSlbMF07XG4gIC8vIFN0cmlwcGluZyBwb3J0cyBpbiB0aGlzIHdheSBpbnN0ZWFkIG9mIHVzaW5nIHBhcnNlZFVybC5ob3N0bmFtZSB0byBtYWtlXG4gIC8vIHN1cmUgdGhhdCB0aGUgYnJhY2tldHMgYXJvdW5kIElQdjYgYWRkcmVzc2VzIGFyZSBrZXB0LlxuICBob3N0bmFtZSA9IGhvc3RuYW1lLnJlcGxhY2UoLzpcXGQqJC8sICcnKTtcbiAgcG9ydCA9IHBhcnNlSW50KHBvcnQpIHx8IERFRkFVTFRfUE9SVFNbcHJvdG9dIHx8IDA7XG4gIGlmICghc2hvdWxkUHJveHkoaG9zdG5hbWUsIHBvcnQpKSB7XG4gICAgcmV0dXJuICcnOyAgLy8gRG9uJ3QgcHJveHkgVVJMcyB0aGF0IG1hdGNoIE5PX1BST1hZLlxuICB9XG5cbiAgdmFyIHByb3h5ID1cbiAgICBnZXRFbnYoJ25wbV9jb25maWdfJyArIHByb3RvICsgJ19wcm94eScpIHx8XG4gICAgZ2V0RW52KHByb3RvICsgJ19wcm94eScpIHx8XG4gICAgZ2V0RW52KCducG1fY29uZmlnX3Byb3h5JykgfHxcbiAgICBnZXRFbnYoJ2FsbF9wcm94eScpO1xuICBpZiAocHJveHkgJiYgcHJveHkuaW5kZXhPZignOi8vJykgPT09IC0xKSB7XG4gICAgLy8gTWlzc2luZyBzY2hlbWUgaW4gcHJveHksIGRlZmF1bHQgdG8gdGhlIHJlcXVlc3RlZCBVUkwncyBzY2hlbWUuXG4gICAgcHJveHkgPSBwcm90byArICc6Ly8nICsgcHJveHk7XG4gIH1cbiAgcmV0dXJuIHByb3h5O1xufVxuXG4vKipcbiAqIERldGVybWluZXMgd2hldGhlciBhIGdpdmVuIFVSTCBzaG91bGQgYmUgcHJveGllZC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaG9zdG5hbWUgLSBUaGUgaG9zdCBuYW1lIG9mIHRoZSBVUkwuXG4gKiBAcGFyYW0ge251bWJlcn0gcG9ydCAtIFRoZSBlZmZlY3RpdmUgcG9ydCBvZiB0aGUgVVJMLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIGdpdmVuIFVSTCBzaG91bGQgYmUgcHJveGllZC5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHNob3VsZFByb3h5KGhvc3RuYW1lLCBwb3J0KSB7XG4gIHZhciBOT19QUk9YWSA9XG4gICAgKGdldEVudignbnBtX2NvbmZpZ19ub19wcm94eScpIHx8IGdldEVudignbm9fcHJveHknKSkudG9Mb3dlckNhc2UoKTtcbiAgaWYgKCFOT19QUk9YWSkge1xuICAgIHJldHVybiB0cnVlOyAgLy8gQWx3YXlzIHByb3h5IGlmIE5PX1BST1hZIGlzIG5vdCBzZXQuXG4gIH1cbiAgaWYgKE5PX1BST1hZID09PSAnKicpIHtcbiAgICByZXR1cm4gZmFsc2U7ICAvLyBOZXZlciBwcm94eSBpZiB3aWxkY2FyZCBpcyBzZXQuXG4gIH1cblxuICByZXR1cm4gTk9fUFJPWFkuc3BsaXQoL1ssXFxzXS8pLmV2ZXJ5KGZ1bmN0aW9uKHByb3h5KSB7XG4gICAgaWYgKCFwcm94eSkge1xuICAgICAgcmV0dXJuIHRydWU7ICAvLyBTa2lwIHplcm8tbGVuZ3RoIGhvc3RzLlxuICAgIH1cbiAgICB2YXIgcGFyc2VkUHJveHkgPSBwcm94eS5tYXRjaCgvXiguKyk6KFxcZCspJC8pO1xuICAgIHZhciBwYXJzZWRQcm94eUhvc3RuYW1lID0gcGFyc2VkUHJveHkgPyBwYXJzZWRQcm94eVsxXSA6IHByb3h5O1xuICAgIHZhciBwYXJzZWRQcm94eVBvcnQgPSBwYXJzZWRQcm94eSA/IHBhcnNlSW50KHBhcnNlZFByb3h5WzJdKSA6IDA7XG4gICAgaWYgKHBhcnNlZFByb3h5UG9ydCAmJiBwYXJzZWRQcm94eVBvcnQgIT09IHBvcnQpIHtcbiAgICAgIHJldHVybiB0cnVlOyAgLy8gU2tpcCBpZiBwb3J0cyBkb24ndCBtYXRjaC5cbiAgICB9XG5cbiAgICBpZiAoIS9eWy4qXS8udGVzdChwYXJzZWRQcm94eUhvc3RuYW1lKSkge1xuICAgICAgLy8gTm8gd2lsZGNhcmRzLCBzbyBzdG9wIHByb3h5aW5nIGlmIHRoZXJlIGlzIGFuIGV4YWN0IG1hdGNoLlxuICAgICAgcmV0dXJuIGhvc3RuYW1lICE9PSBwYXJzZWRQcm94eUhvc3RuYW1lO1xuICAgIH1cblxuICAgIGlmIChwYXJzZWRQcm94eUhvc3RuYW1lLmNoYXJBdCgwKSA9PT0gJyonKSB7XG4gICAgICAvLyBSZW1vdmUgbGVhZGluZyB3aWxkY2FyZC5cbiAgICAgIHBhcnNlZFByb3h5SG9zdG5hbWUgPSBwYXJzZWRQcm94eUhvc3RuYW1lLnNsaWNlKDEpO1xuICAgIH1cbiAgICAvLyBTdG9wIHByb3h5aW5nIGlmIHRoZSBob3N0bmFtZSBlbmRzIHdpdGggdGhlIG5vX3Byb3h5IGhvc3QuXG4gICAgcmV0dXJuICFzdHJpbmdFbmRzV2l0aC5jYWxsKGhvc3RuYW1lLCBwYXJzZWRQcm94eUhvc3RuYW1lKTtcbiAgfSk7XG59XG5cbi8qKlxuICogR2V0IHRoZSB2YWx1ZSBmb3IgYW4gZW52aXJvbm1lbnQgdmFyaWFibGUuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIFRoZSBuYW1lIG9mIHRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZS5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHZhbHVlIG9mIHRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGdldEVudihrZXkpIHtcbiAgcmV0dXJuIHByb2Nlc3MuZW52W2tleS50b0xvd2VyQ2FzZSgpXSB8fCBwcm9jZXNzLmVudltrZXkudG9VcHBlckNhc2UoKV0gfHwgJyc7XG59XG5cbmV4cG9ydHMuZ2V0UHJveHlGb3JVcmwgPSBnZXRQcm94eUZvclVybDtcbiIsIid1c2Ugc3RyaWN0JztcbmNvbnN0IG9zID0gcmVxdWlyZSgnb3MnKTtcbmNvbnN0IGhhc0ZsYWcgPSByZXF1aXJlKCdoYXMtZmxhZycpO1xuXG5jb25zdCBlbnYgPSBwcm9jZXNzLmVudjtcblxubGV0IGZvcmNlQ29sb3I7XG5pZiAoaGFzRmxhZygnbm8tY29sb3InKSB8fFxuXHRoYXNGbGFnKCduby1jb2xvcnMnKSB8fFxuXHRoYXNGbGFnKCdjb2xvcj1mYWxzZScpKSB7XG5cdGZvcmNlQ29sb3IgPSBmYWxzZTtcbn0gZWxzZSBpZiAoaGFzRmxhZygnY29sb3InKSB8fFxuXHRoYXNGbGFnKCdjb2xvcnMnKSB8fFxuXHRoYXNGbGFnKCdjb2xvcj10cnVlJykgfHxcblx0aGFzRmxhZygnY29sb3I9YWx3YXlzJykpIHtcblx0Zm9yY2VDb2xvciA9IHRydWU7XG59XG5pZiAoJ0ZPUkNFX0NPTE9SJyBpbiBlbnYpIHtcblx0Zm9yY2VDb2xvciA9IGVudi5GT1JDRV9DT0xPUi5sZW5ndGggPT09IDAgfHwgcGFyc2VJbnQoZW52LkZPUkNFX0NPTE9SLCAxMCkgIT09IDA7XG59XG5cbmZ1bmN0aW9uIHRyYW5zbGF0ZUxldmVsKGxldmVsKSB7XG5cdGlmIChsZXZlbCA9PT0gMCkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHJldHVybiB7XG5cdFx0bGV2ZWwsXG5cdFx0aGFzQmFzaWM6IHRydWUsXG5cdFx0aGFzMjU2OiBsZXZlbCA+PSAyLFxuXHRcdGhhczE2bTogbGV2ZWwgPj0gM1xuXHR9O1xufVxuXG5mdW5jdGlvbiBzdXBwb3J0c0NvbG9yKHN0cmVhbSkge1xuXHRpZiAoZm9yY2VDb2xvciA9PT0gZmFsc2UpIHtcblx0XHRyZXR1cm4gMDtcblx0fVxuXG5cdGlmIChoYXNGbGFnKCdjb2xvcj0xNm0nKSB8fFxuXHRcdGhhc0ZsYWcoJ2NvbG9yPWZ1bGwnKSB8fFxuXHRcdGhhc0ZsYWcoJ2NvbG9yPXRydWVjb2xvcicpKSB7XG5cdFx0cmV0dXJuIDM7XG5cdH1cblxuXHRpZiAoaGFzRmxhZygnY29sb3I9MjU2JykpIHtcblx0XHRyZXR1cm4gMjtcblx0fVxuXG5cdGlmIChzdHJlYW0gJiYgIXN0cmVhbS5pc1RUWSAmJiBmb3JjZUNvbG9yICE9PSB0cnVlKSB7XG5cdFx0cmV0dXJuIDA7XG5cdH1cblxuXHRjb25zdCBtaW4gPSBmb3JjZUNvbG9yID8gMSA6IDA7XG5cblx0aWYgKHByb2Nlc3MucGxhdGZvcm0gPT09ICd3aW4zMicpIHtcblx0XHQvLyBOb2RlLmpzIDcuNS4wIGlzIHRoZSBmaXJzdCB2ZXJzaW9uIG9mIE5vZGUuanMgdG8gaW5jbHVkZSBhIHBhdGNoIHRvXG5cdFx0Ly8gbGlidXYgdGhhdCBlbmFibGVzIDI1NiBjb2xvciBvdXRwdXQgb24gV2luZG93cy4gQW55dGhpbmcgZWFybGllciBhbmQgaXRcblx0XHQvLyB3b24ndCB3b3JrLiBIb3dldmVyLCBoZXJlIHdlIHRhcmdldCBOb2RlLmpzIDggYXQgbWluaW11bSBhcyBpdCBpcyBhbiBMVFNcblx0XHQvLyByZWxlYXNlLCBhbmQgTm9kZS5qcyA3IGlzIG5vdC4gV2luZG93cyAxMCBidWlsZCAxMDU4NiBpcyB0aGUgZmlyc3QgV2luZG93c1xuXHRcdC8vIHJlbGVhc2UgdGhhdCBzdXBwb3J0cyAyNTYgY29sb3JzLiBXaW5kb3dzIDEwIGJ1aWxkIDE0OTMxIGlzIHRoZSBmaXJzdCByZWxlYXNlXG5cdFx0Ly8gdGhhdCBzdXBwb3J0cyAxNm0vVHJ1ZUNvbG9yLlxuXHRcdGNvbnN0IG9zUmVsZWFzZSA9IG9zLnJlbGVhc2UoKS5zcGxpdCgnLicpO1xuXHRcdGlmIChcblx0XHRcdE51bWJlcihwcm9jZXNzLnZlcnNpb25zLm5vZGUuc3BsaXQoJy4nKVswXSkgPj0gOCAmJlxuXHRcdFx0TnVtYmVyKG9zUmVsZWFzZVswXSkgPj0gMTAgJiZcblx0XHRcdE51bWJlcihvc1JlbGVhc2VbMl0pID49IDEwNTg2XG5cdFx0KSB7XG5cdFx0XHRyZXR1cm4gTnVtYmVyKG9zUmVsZWFzZVsyXSkgPj0gMTQ5MzEgPyAzIDogMjtcblx0XHR9XG5cblx0XHRyZXR1cm4gMTtcblx0fVxuXG5cdGlmICgnQ0knIGluIGVudikge1xuXHRcdGlmIChbJ1RSQVZJUycsICdDSVJDTEVDSScsICdBUFBWRVlPUicsICdHSVRMQUJfQ0knXS5zb21lKHNpZ24gPT4gc2lnbiBpbiBlbnYpIHx8IGVudi5DSV9OQU1FID09PSAnY29kZXNoaXAnKSB7XG5cdFx0XHRyZXR1cm4gMTtcblx0XHR9XG5cblx0XHRyZXR1cm4gbWluO1xuXHR9XG5cblx0aWYgKCdURUFNQ0lUWV9WRVJTSU9OJyBpbiBlbnYpIHtcblx0XHRyZXR1cm4gL14oOVxcLigwKlsxLTldXFxkKilcXC58XFxkezIsfVxcLikvLnRlc3QoZW52LlRFQU1DSVRZX1ZFUlNJT04pID8gMSA6IDA7XG5cdH1cblxuXHRpZiAoZW52LkNPTE9SVEVSTSA9PT0gJ3RydWVjb2xvcicpIHtcblx0XHRyZXR1cm4gMztcblx0fVxuXG5cdGlmICgnVEVSTV9QUk9HUkFNJyBpbiBlbnYpIHtcblx0XHRjb25zdCB2ZXJzaW9uID0gcGFyc2VJbnQoKGVudi5URVJNX1BST0dSQU1fVkVSU0lPTiB8fCAnJykuc3BsaXQoJy4nKVswXSwgMTApO1xuXG5cdFx0c3dpdGNoIChlbnYuVEVSTV9QUk9HUkFNKSB7XG5cdFx0XHRjYXNlICdpVGVybS5hcHAnOlxuXHRcdFx0XHRyZXR1cm4gdmVyc2lvbiA+PSAzID8gMyA6IDI7XG5cdFx0XHRjYXNlICdBcHBsZV9UZXJtaW5hbCc6XG5cdFx0XHRcdHJldHVybiAyO1xuXHRcdFx0Ly8gTm8gZGVmYXVsdFxuXHRcdH1cblx0fVxuXG5cdGlmICgvLTI1Nihjb2xvcik/JC9pLnRlc3QoZW52LlRFUk0pKSB7XG5cdFx0cmV0dXJuIDI7XG5cdH1cblxuXHRpZiAoL15zY3JlZW58Xnh0ZXJtfF52dDEwMHxednQyMjB8XnJ4dnR8Y29sb3J8YW5zaXxjeWd3aW58bGludXgvaS50ZXN0KGVudi5URVJNKSkge1xuXHRcdHJldHVybiAxO1xuXHR9XG5cblx0aWYgKCdDT0xPUlRFUk0nIGluIGVudikge1xuXHRcdHJldHVybiAxO1xuXHR9XG5cblx0aWYgKGVudi5URVJNID09PSAnZHVtYicpIHtcblx0XHRyZXR1cm4gbWluO1xuXHR9XG5cblx0cmV0dXJuIG1pbjtcbn1cblxuZnVuY3Rpb24gZ2V0U3VwcG9ydExldmVsKHN0cmVhbSkge1xuXHRjb25zdCBsZXZlbCA9IHN1cHBvcnRzQ29sb3Ioc3RyZWFtKTtcblx0cmV0dXJuIHRyYW5zbGF0ZUxldmVsKGxldmVsKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdHN1cHBvcnRzQ29sb3I6IGdldFN1cHBvcnRMZXZlbCxcblx0c3Rkb3V0OiBnZXRTdXBwb3J0TGV2ZWwocHJvY2Vzcy5zdGRvdXQpLFxuXHRzdGRlcnI6IGdldFN1cHBvcnRMZXZlbChwcm9jZXNzLnN0ZGVycilcbn07XG4iLCIoZnVuY3Rpb24gKG5hbWUsIGNvbnRleHQsIGRlZmluaXRpb24pIHtcbiAgaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSBtb2R1bGUuZXhwb3J0cyA9IGRlZmluaXRpb24oKTtcbiAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSBkZWZpbmUoZGVmaW5pdGlvbik7XG4gIGVsc2UgY29udGV4dFtuYW1lXSA9IGRlZmluaXRpb24oKTtcbn0pKCd1cmxqb2luJywgdGhpcywgZnVuY3Rpb24gKCkge1xuXG4gIGZ1bmN0aW9uIG5vcm1hbGl6ZSAoc3RyQXJyYXkpIHtcbiAgICB2YXIgcmVzdWx0QXJyYXkgPSBbXTtcbiAgICBpZiAoc3RyQXJyYXkubGVuZ3RoID09PSAwKSB7IHJldHVybiAnJzsgfVxuXG4gICAgaWYgKHR5cGVvZiBzdHJBcnJheVswXSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1VybCBtdXN0IGJlIGEgc3RyaW5nLiBSZWNlaXZlZCAnICsgc3RyQXJyYXlbMF0pO1xuICAgIH1cblxuICAgIC8vIElmIHRoZSBmaXJzdCBwYXJ0IGlzIGEgcGxhaW4gcHJvdG9jb2wsIHdlIGNvbWJpbmUgaXQgd2l0aCB0aGUgbmV4dCBwYXJ0LlxuICAgIGlmIChzdHJBcnJheVswXS5tYXRjaCgvXlteLzpdKzpcXC8qJC8pICYmIHN0ckFycmF5Lmxlbmd0aCA+IDEpIHtcbiAgICAgIHZhciBmaXJzdCA9IHN0ckFycmF5LnNoaWZ0KCk7XG4gICAgICBzdHJBcnJheVswXSA9IGZpcnN0ICsgc3RyQXJyYXlbMF07XG4gICAgfVxuXG4gICAgLy8gVGhlcmUgbXVzdCBiZSB0d28gb3IgdGhyZWUgc2xhc2hlcyBpbiB0aGUgZmlsZSBwcm90b2NvbCwgdHdvIHNsYXNoZXMgaW4gYW55dGhpbmcgZWxzZS5cbiAgICBpZiAoc3RyQXJyYXlbMF0ubWF0Y2goL15maWxlOlxcL1xcL1xcLy8pKSB7XG4gICAgICBzdHJBcnJheVswXSA9IHN0ckFycmF5WzBdLnJlcGxhY2UoL14oW14vOl0rKTpcXC8qLywgJyQxOi8vLycpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHJBcnJheVswXSA9IHN0ckFycmF5WzBdLnJlcGxhY2UoL14oW14vOl0rKTpcXC8qLywgJyQxOi8vJyk7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHJBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGNvbXBvbmVudCA9IHN0ckFycmF5W2ldO1xuXG4gICAgICBpZiAodHlwZW9mIGNvbXBvbmVudCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVXJsIG11c3QgYmUgYSBzdHJpbmcuIFJlY2VpdmVkICcgKyBjb21wb25lbnQpO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29tcG9uZW50ID09PSAnJykgeyBjb250aW51ZTsgfVxuXG4gICAgICBpZiAoaSA+IDApIHtcbiAgICAgICAgLy8gUmVtb3ZpbmcgdGhlIHN0YXJ0aW5nIHNsYXNoZXMgZm9yIGVhY2ggY29tcG9uZW50IGJ1dCB0aGUgZmlyc3QuXG4gICAgICAgIGNvbXBvbmVudCA9IGNvbXBvbmVudC5yZXBsYWNlKC9eW1xcL10rLywgJycpO1xuICAgICAgfVxuICAgICAgaWYgKGkgPCBzdHJBcnJheS5sZW5ndGggLSAxKSB7XG4gICAgICAgIC8vIFJlbW92aW5nIHRoZSBlbmRpbmcgc2xhc2hlcyBmb3IgZWFjaCBjb21wb25lbnQgYnV0IHRoZSBsYXN0LlxuICAgICAgICBjb21wb25lbnQgPSBjb21wb25lbnQucmVwbGFjZSgvW1xcL10rJC8sICcnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEZvciB0aGUgbGFzdCBjb21wb25lbnQgd2Ugd2lsbCBjb21iaW5lIG11bHRpcGxlIHNsYXNoZXMgdG8gYSBzaW5nbGUgb25lLlxuICAgICAgICBjb21wb25lbnQgPSBjb21wb25lbnQucmVwbGFjZSgvW1xcL10rJC8sICcvJyk7XG4gICAgICB9XG5cbiAgICAgIHJlc3VsdEFycmF5LnB1c2goY29tcG9uZW50KTtcblxuICAgIH1cblxuICAgIHZhciBzdHIgPSByZXN1bHRBcnJheS5qb2luKCcvJyk7XG4gICAgLy8gRWFjaCBpbnB1dCBjb21wb25lbnQgaXMgbm93IHNlcGFyYXRlZCBieSBhIHNpbmdsZSBzbGFzaCBleGNlcHQgdGhlIHBvc3NpYmxlIGZpcnN0IHBsYWluIHByb3RvY29sIHBhcnQuXG5cbiAgICAvLyByZW1vdmUgdHJhaWxpbmcgc2xhc2ggYmVmb3JlIHBhcmFtZXRlcnMgb3IgaGFzaFxuICAgIHN0ciA9IHN0ci5yZXBsYWNlKC9cXC8oXFw/fCZ8I1teIV0pL2csICckMScpO1xuXG4gICAgLy8gcmVwbGFjZSA/IGluIHBhcmFtZXRlcnMgd2l0aCAmXG4gICAgdmFyIHBhcnRzID0gc3RyLnNwbGl0KCc/Jyk7XG4gICAgc3RyID0gcGFydHMuc2hpZnQoKSArIChwYXJ0cy5sZW5ndGggPiAwID8gJz8nOiAnJykgKyBwYXJ0cy5qb2luKCcmJyk7XG5cbiAgICByZXR1cm4gc3RyO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaW5wdXQ7XG5cbiAgICBpZiAodHlwZW9mIGFyZ3VtZW50c1swXSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlucHV0ID0gYXJndW1lbnRzWzBdO1xuICAgIH0gZWxzZSB7XG4gICAgICBpbnB1dCA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbm9ybWFsaXplKGlucHV0KTtcbiAgfTtcblxufSk7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJhc3NlcnRcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiZXZlbnRzXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImZzXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImh0dHBcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiaHR0cHNcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwib3NcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicGF0aFwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJzdHJlYW1cIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwidHR5XCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInVybFwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ1dGlsXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInpsaWJcIik7IiwiLy8gQXhpb3MgdjEuNi4wIENvcHlyaWdodCAoYykgMjAyMyBNYXR0IFphYnJpc2tpZSBhbmQgY29udHJpYnV0b3JzXG4ndXNlIHN0cmljdCc7XG5cbmNvbnN0IEZvcm1EYXRhJDEgPSByZXF1aXJlKCdmb3JtLWRhdGEnKTtcbmNvbnN0IHVybCA9IHJlcXVpcmUoJ3VybCcpO1xuY29uc3QgcHJveHlGcm9tRW52ID0gcmVxdWlyZSgncHJveHktZnJvbS1lbnYnKTtcbmNvbnN0IGh0dHAgPSByZXF1aXJlKCdodHRwJyk7XG5jb25zdCBodHRwcyA9IHJlcXVpcmUoJ2h0dHBzJyk7XG5jb25zdCB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuY29uc3QgZm9sbG93UmVkaXJlY3RzID0gcmVxdWlyZSgnZm9sbG93LXJlZGlyZWN0cycpO1xuY29uc3QgemxpYiA9IHJlcXVpcmUoJ3psaWInKTtcbmNvbnN0IHN0cmVhbSA9IHJlcXVpcmUoJ3N0cmVhbScpO1xuY29uc3QgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnZXZlbnRzJyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wRGVmYXVsdExlZ2FjeSAoZSkgeyByZXR1cm4gZSAmJiB0eXBlb2YgZSA9PT0gJ29iamVjdCcgJiYgJ2RlZmF1bHQnIGluIGUgPyBlIDogeyAnZGVmYXVsdCc6IGUgfTsgfVxuXG5jb25zdCBGb3JtRGF0YV9fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9faW50ZXJvcERlZmF1bHRMZWdhY3koRm9ybURhdGEkMSk7XG5jb25zdCB1cmxfX2RlZmF1bHQgPSAvKiNfX1BVUkVfXyovX2ludGVyb3BEZWZhdWx0TGVnYWN5KHVybCk7XG5jb25zdCBodHRwX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19pbnRlcm9wRGVmYXVsdExlZ2FjeShodHRwKTtcbmNvbnN0IGh0dHBzX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19pbnRlcm9wRGVmYXVsdExlZ2FjeShodHRwcyk7XG5jb25zdCB1dGlsX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19pbnRlcm9wRGVmYXVsdExlZ2FjeSh1dGlsKTtcbmNvbnN0IGZvbGxvd1JlZGlyZWN0c19fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9faW50ZXJvcERlZmF1bHRMZWdhY3koZm9sbG93UmVkaXJlY3RzKTtcbmNvbnN0IHpsaWJfX2RlZmF1bHQgPSAvKiNfX1BVUkVfXyovX2ludGVyb3BEZWZhdWx0TGVnYWN5KHpsaWIpO1xuY29uc3Qgc3RyZWFtX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19pbnRlcm9wRGVmYXVsdExlZ2FjeShzdHJlYW0pO1xuY29uc3QgRXZlbnRFbWl0dGVyX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19pbnRlcm9wRGVmYXVsdExlZ2FjeShFdmVudEVtaXR0ZXIpO1xuXG5mdW5jdGlvbiBiaW5kKGZuLCB0aGlzQXJnKSB7XG4gIHJldHVybiBmdW5jdGlvbiB3cmFwKCkge1xuICAgIHJldHVybiBmbi5hcHBseSh0aGlzQXJnLCBhcmd1bWVudHMpO1xuICB9O1xufVxuXG4vLyB1dGlscyBpcyBhIGxpYnJhcnkgb2YgZ2VuZXJpYyBoZWxwZXIgZnVuY3Rpb25zIG5vbi1zcGVjaWZpYyB0byBheGlvc1xuXG5jb25zdCB7dG9TdHJpbmd9ID0gT2JqZWN0LnByb3RvdHlwZTtcbmNvbnN0IHtnZXRQcm90b3R5cGVPZn0gPSBPYmplY3Q7XG5cbmNvbnN0IGtpbmRPZiA9IChjYWNoZSA9PiB0aGluZyA9PiB7XG4gICAgY29uc3Qgc3RyID0gdG9TdHJpbmcuY2FsbCh0aGluZyk7XG4gICAgcmV0dXJuIGNhY2hlW3N0cl0gfHwgKGNhY2hlW3N0cl0gPSBzdHIuc2xpY2UoOCwgLTEpLnRvTG93ZXJDYXNlKCkpO1xufSkoT2JqZWN0LmNyZWF0ZShudWxsKSk7XG5cbmNvbnN0IGtpbmRPZlRlc3QgPSAodHlwZSkgPT4ge1xuICB0eXBlID0gdHlwZS50b0xvd2VyQ2FzZSgpO1xuICByZXR1cm4gKHRoaW5nKSA9PiBraW5kT2YodGhpbmcpID09PSB0eXBlXG59O1xuXG5jb25zdCB0eXBlT2ZUZXN0ID0gdHlwZSA9PiB0aGluZyA9PiB0eXBlb2YgdGhpbmcgPT09IHR5cGU7XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYW4gQXJyYXlcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYW4gQXJyYXksIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCB7aXNBcnJheX0gPSBBcnJheTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyB1bmRlZmluZWRcbiAqXG4gKiBAcGFyYW0geyp9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB2YWx1ZSBpcyB1bmRlZmluZWQsIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc1VuZGVmaW5lZCA9IHR5cGVPZlRlc3QoJ3VuZGVmaW5lZCcpO1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgQnVmZmVyXG4gKlxuICogQHBhcmFtIHsqfSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIEJ1ZmZlciwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQnVmZmVyKHZhbCkge1xuICByZXR1cm4gdmFsICE9PSBudWxsICYmICFpc1VuZGVmaW5lZCh2YWwpICYmIHZhbC5jb25zdHJ1Y3RvciAhPT0gbnVsbCAmJiAhaXNVbmRlZmluZWQodmFsLmNvbnN0cnVjdG9yKVxuICAgICYmIGlzRnVuY3Rpb24odmFsLmNvbnN0cnVjdG9yLmlzQnVmZmVyKSAmJiB2YWwuY29uc3RydWN0b3IuaXNCdWZmZXIodmFsKTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhbiBBcnJheUJ1ZmZlclxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYW4gQXJyYXlCdWZmZXIsIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc0FycmF5QnVmZmVyID0ga2luZE9mVGVzdCgnQXJyYXlCdWZmZXInKTtcblxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgdmlldyBvbiBhbiBBcnJheUJ1ZmZlclxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSB2aWV3IG9uIGFuIEFycmF5QnVmZmVyLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNBcnJheUJ1ZmZlclZpZXcodmFsKSB7XG4gIGxldCByZXN1bHQ7XG4gIGlmICgodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJykgJiYgKEFycmF5QnVmZmVyLmlzVmlldykpIHtcbiAgICByZXN1bHQgPSBBcnJheUJ1ZmZlci5pc1ZpZXcodmFsKTtcbiAgfSBlbHNlIHtcbiAgICByZXN1bHQgPSAodmFsKSAmJiAodmFsLmJ1ZmZlcikgJiYgKGlzQXJyYXlCdWZmZXIodmFsLmJ1ZmZlcikpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYSBTdHJpbmdcbiAqXG4gKiBAcGFyYW0geyp9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgU3RyaW5nLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuY29uc3QgaXNTdHJpbmcgPSB0eXBlT2ZUZXN0KCdzdHJpbmcnKTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIEZ1bmN0aW9uXG4gKlxuICogQHBhcmFtIHsqfSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgRnVuY3Rpb24sIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc0Z1bmN0aW9uID0gdHlwZU9mVGVzdCgnZnVuY3Rpb24nKTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIE51bWJlclxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBOdW1iZXIsIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc051bWJlciA9IHR5cGVPZlRlc3QoJ251bWJlcicpO1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGFuIE9iamVjdFxuICpcbiAqIEBwYXJhbSB7Kn0gdGhpbmcgVGhlIHZhbHVlIHRvIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhbiBPYmplY3QsIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc09iamVjdCA9ICh0aGluZykgPT4gdGhpbmcgIT09IG51bGwgJiYgdHlwZW9mIHRoaW5nID09PSAnb2JqZWN0JztcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIEJvb2xlYW5cbiAqXG4gKiBAcGFyYW0geyp9IHRoaW5nIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIEJvb2xlYW4sIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc0Jvb2xlYW4gPSB0aGluZyA9PiB0aGluZyA9PT0gdHJ1ZSB8fCB0aGluZyA9PT0gZmFsc2U7XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYSBwbGFpbiBPYmplY3RcbiAqXG4gKiBAcGFyYW0geyp9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgcGxhaW4gT2JqZWN0LCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuY29uc3QgaXNQbGFpbk9iamVjdCA9ICh2YWwpID0+IHtcbiAgaWYgKGtpbmRPZih2YWwpICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IHByb3RvdHlwZSA9IGdldFByb3RvdHlwZU9mKHZhbCk7XG4gIHJldHVybiAocHJvdG90eXBlID09PSBudWxsIHx8IHByb3RvdHlwZSA9PT0gT2JqZWN0LnByb3RvdHlwZSB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG90eXBlKSA9PT0gbnVsbCkgJiYgIShTeW1ib2wudG9TdHJpbmdUYWcgaW4gdmFsKSAmJiAhKFN5bWJvbC5pdGVyYXRvciBpbiB2YWwpO1xufTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIERhdGVcbiAqXG4gKiBAcGFyYW0geyp9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgRGF0ZSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmNvbnN0IGlzRGF0ZSA9IGtpbmRPZlRlc3QoJ0RhdGUnKTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIEZpbGVcbiAqXG4gKiBAcGFyYW0geyp9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgRmlsZSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmNvbnN0IGlzRmlsZSA9IGtpbmRPZlRlc3QoJ0ZpbGUnKTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIEJsb2JcbiAqXG4gKiBAcGFyYW0geyp9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgQmxvYiwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmNvbnN0IGlzQmxvYiA9IGtpbmRPZlRlc3QoJ0Jsb2InKTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIEZpbGVMaXN0XG4gKlxuICogQHBhcmFtIHsqfSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIEZpbGUsIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc0ZpbGVMaXN0ID0ga2luZE9mVGVzdCgnRmlsZUxpc3QnKTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIFN0cmVhbVxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBTdHJlYW0sIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc1N0cmVhbSA9ICh2YWwpID0+IGlzT2JqZWN0KHZhbCkgJiYgaXNGdW5jdGlvbih2YWwucGlwZSk7XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYSBGb3JtRGF0YVxuICpcbiAqIEBwYXJhbSB7Kn0gdGhpbmcgVGhlIHZhbHVlIHRvIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhbiBGb3JtRGF0YSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmNvbnN0IGlzRm9ybURhdGEgPSAodGhpbmcpID0+IHtcbiAgbGV0IGtpbmQ7XG4gIHJldHVybiB0aGluZyAmJiAoXG4gICAgKHR5cGVvZiBGb3JtRGF0YSA9PT0gJ2Z1bmN0aW9uJyAmJiB0aGluZyBpbnN0YW5jZW9mIEZvcm1EYXRhKSB8fCAoXG4gICAgICBpc0Z1bmN0aW9uKHRoaW5nLmFwcGVuZCkgJiYgKFxuICAgICAgICAoa2luZCA9IGtpbmRPZih0aGluZykpID09PSAnZm9ybWRhdGEnIHx8XG4gICAgICAgIC8vIGRldGVjdCBmb3JtLWRhdGEgaW5zdGFuY2VcbiAgICAgICAgKGtpbmQgPT09ICdvYmplY3QnICYmIGlzRnVuY3Rpb24odGhpbmcudG9TdHJpbmcpICYmIHRoaW5nLnRvU3RyaW5nKCkgPT09ICdbb2JqZWN0IEZvcm1EYXRhXScpXG4gICAgICApXG4gICAgKVxuICApXG59O1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgVVJMU2VhcmNoUGFyYW1zIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBVUkxTZWFyY2hQYXJhbXMgb2JqZWN0LCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuY29uc3QgaXNVUkxTZWFyY2hQYXJhbXMgPSBraW5kT2ZUZXN0KCdVUkxTZWFyY2hQYXJhbXMnKTtcblxuLyoqXG4gKiBUcmltIGV4Y2VzcyB3aGl0ZXNwYWNlIG9mZiB0aGUgYmVnaW5uaW5nIGFuZCBlbmQgb2YgYSBzdHJpbmdcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyIFRoZSBTdHJpbmcgdG8gdHJpbVxuICpcbiAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSBTdHJpbmcgZnJlZWQgb2YgZXhjZXNzIHdoaXRlc3BhY2VcbiAqL1xuY29uc3QgdHJpbSA9IChzdHIpID0+IHN0ci50cmltID9cbiAgc3RyLnRyaW0oKSA6IHN0ci5yZXBsYWNlKC9eW1xcc1xcdUZFRkZcXHhBMF0rfFtcXHNcXHVGRUZGXFx4QTBdKyQvZywgJycpO1xuXG4vKipcbiAqIEl0ZXJhdGUgb3ZlciBhbiBBcnJheSBvciBhbiBPYmplY3QgaW52b2tpbmcgYSBmdW5jdGlvbiBmb3IgZWFjaCBpdGVtLlxuICpcbiAqIElmIGBvYmpgIGlzIGFuIEFycmF5IGNhbGxiYWNrIHdpbGwgYmUgY2FsbGVkIHBhc3NpbmdcbiAqIHRoZSB2YWx1ZSwgaW5kZXgsIGFuZCBjb21wbGV0ZSBhcnJheSBmb3IgZWFjaCBpdGVtLlxuICpcbiAqIElmICdvYmonIGlzIGFuIE9iamVjdCBjYWxsYmFjayB3aWxsIGJlIGNhbGxlZCBwYXNzaW5nXG4gKiB0aGUgdmFsdWUsIGtleSwgYW5kIGNvbXBsZXRlIG9iamVjdCBmb3IgZWFjaCBwcm9wZXJ0eS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdHxBcnJheX0gb2JqIFRoZSBvYmplY3QgdG8gaXRlcmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGNhbGxiYWNrIHRvIGludm9rZSBmb3IgZWFjaCBpdGVtXG4gKlxuICogQHBhcmFtIHtCb29sZWFufSBbYWxsT3duS2V5cyA9IGZhbHNlXVxuICogQHJldHVybnMge2FueX1cbiAqL1xuZnVuY3Rpb24gZm9yRWFjaChvYmosIGZuLCB7YWxsT3duS2V5cyA9IGZhbHNlfSA9IHt9KSB7XG4gIC8vIERvbid0IGJvdGhlciBpZiBubyB2YWx1ZSBwcm92aWRlZFxuICBpZiAob2JqID09PSBudWxsIHx8IHR5cGVvZiBvYmogPT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgbGV0IGk7XG4gIGxldCBsO1xuXG4gIC8vIEZvcmNlIGFuIGFycmF5IGlmIG5vdCBhbHJlYWR5IHNvbWV0aGluZyBpdGVyYWJsZVxuICBpZiAodHlwZW9mIG9iaiAhPT0gJ29iamVjdCcpIHtcbiAgICAvKmVzbGludCBuby1wYXJhbS1yZWFzc2lnbjowKi9cbiAgICBvYmogPSBbb2JqXTtcbiAgfVxuXG4gIGlmIChpc0FycmF5KG9iaikpIHtcbiAgICAvLyBJdGVyYXRlIG92ZXIgYXJyYXkgdmFsdWVzXG4gICAgZm9yIChpID0gMCwgbCA9IG9iai5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIGZuLmNhbGwobnVsbCwgb2JqW2ldLCBpLCBvYmopO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBJdGVyYXRlIG92ZXIgb2JqZWN0IGtleXNcbiAgICBjb25zdCBrZXlzID0gYWxsT3duS2V5cyA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG9iaikgOiBPYmplY3Qua2V5cyhvYmopO1xuICAgIGNvbnN0IGxlbiA9IGtleXMubGVuZ3RoO1xuICAgIGxldCBrZXk7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGtleSA9IGtleXNbaV07XG4gICAgICBmbi5jYWxsKG51bGwsIG9ialtrZXldLCBrZXksIG9iaik7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGZpbmRLZXkob2JqLCBrZXkpIHtcbiAga2V5ID0ga2V5LnRvTG93ZXJDYXNlKCk7XG4gIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhvYmopO1xuICBsZXQgaSA9IGtleXMubGVuZ3RoO1xuICBsZXQgX2tleTtcbiAgd2hpbGUgKGktLSA+IDApIHtcbiAgICBfa2V5ID0ga2V5c1tpXTtcbiAgICBpZiAoa2V5ID09PSBfa2V5LnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgIHJldHVybiBfa2V5O1xuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuY29uc3QgX2dsb2JhbCA9ICgoKSA9PiB7XG4gIC8qZXNsaW50IG5vLXVuZGVmOjAqL1xuICBpZiAodHlwZW9mIGdsb2JhbFRoaXMgIT09IFwidW5kZWZpbmVkXCIpIHJldHVybiBnbG9iYWxUaGlzO1xuICByZXR1cm4gdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogZ2xvYmFsKVxufSkoKTtcblxuY29uc3QgaXNDb250ZXh0RGVmaW5lZCA9IChjb250ZXh0KSA9PiAhaXNVbmRlZmluZWQoY29udGV4dCkgJiYgY29udGV4dCAhPT0gX2dsb2JhbDtcblxuLyoqXG4gKiBBY2NlcHRzIHZhcmFyZ3MgZXhwZWN0aW5nIGVhY2ggYXJndW1lbnQgdG8gYmUgYW4gb2JqZWN0LCB0aGVuXG4gKiBpbW11dGFibHkgbWVyZ2VzIHRoZSBwcm9wZXJ0aWVzIG9mIGVhY2ggb2JqZWN0IGFuZCByZXR1cm5zIHJlc3VsdC5cbiAqXG4gKiBXaGVuIG11bHRpcGxlIG9iamVjdHMgY29udGFpbiB0aGUgc2FtZSBrZXkgdGhlIGxhdGVyIG9iamVjdCBpblxuICogdGhlIGFyZ3VtZW50cyBsaXN0IHdpbGwgdGFrZSBwcmVjZWRlbmNlLlxuICpcbiAqIEV4YW1wbGU6XG4gKlxuICogYGBganNcbiAqIHZhciByZXN1bHQgPSBtZXJnZSh7Zm9vOiAxMjN9LCB7Zm9vOiA0NTZ9KTtcbiAqIGNvbnNvbGUubG9nKHJlc3VsdC5mb28pOyAvLyBvdXRwdXRzIDQ1NlxuICogYGBgXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iajEgT2JqZWN0IHRvIG1lcmdlXG4gKlxuICogQHJldHVybnMge09iamVjdH0gUmVzdWx0IG9mIGFsbCBtZXJnZSBwcm9wZXJ0aWVzXG4gKi9cbmZ1bmN0aW9uIG1lcmdlKC8qIG9iajEsIG9iajIsIG9iajMsIC4uLiAqLykge1xuICBjb25zdCB7Y2FzZWxlc3N9ID0gaXNDb250ZXh0RGVmaW5lZCh0aGlzKSAmJiB0aGlzIHx8IHt9O1xuICBjb25zdCByZXN1bHQgPSB7fTtcbiAgY29uc3QgYXNzaWduVmFsdWUgPSAodmFsLCBrZXkpID0+IHtcbiAgICBjb25zdCB0YXJnZXRLZXkgPSBjYXNlbGVzcyAmJiBmaW5kS2V5KHJlc3VsdCwga2V5KSB8fCBrZXk7XG4gICAgaWYgKGlzUGxhaW5PYmplY3QocmVzdWx0W3RhcmdldEtleV0pICYmIGlzUGxhaW5PYmplY3QodmFsKSkge1xuICAgICAgcmVzdWx0W3RhcmdldEtleV0gPSBtZXJnZShyZXN1bHRbdGFyZ2V0S2V5XSwgdmFsKTtcbiAgICB9IGVsc2UgaWYgKGlzUGxhaW5PYmplY3QodmFsKSkge1xuICAgICAgcmVzdWx0W3RhcmdldEtleV0gPSBtZXJnZSh7fSwgdmFsKTtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkodmFsKSkge1xuICAgICAgcmVzdWx0W3RhcmdldEtleV0gPSB2YWwuc2xpY2UoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0W3RhcmdldEtleV0gPSB2YWw7XG4gICAgfVxuICB9O1xuXG4gIGZvciAobGV0IGkgPSAwLCBsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGFyZ3VtZW50c1tpXSAmJiBmb3JFYWNoKGFyZ3VtZW50c1tpXSwgYXNzaWduVmFsdWUpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogRXh0ZW5kcyBvYmplY3QgYSBieSBtdXRhYmx5IGFkZGluZyB0byBpdCB0aGUgcHJvcGVydGllcyBvZiBvYmplY3QgYi5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gYSBUaGUgb2JqZWN0IHRvIGJlIGV4dGVuZGVkXG4gKiBAcGFyYW0ge09iamVjdH0gYiBUaGUgb2JqZWN0IHRvIGNvcHkgcHJvcGVydGllcyBmcm9tXG4gKiBAcGFyYW0ge09iamVjdH0gdGhpc0FyZyBUaGUgb2JqZWN0IHRvIGJpbmQgZnVuY3Rpb24gdG9cbiAqXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFthbGxPd25LZXlzXVxuICogQHJldHVybnMge09iamVjdH0gVGhlIHJlc3VsdGluZyB2YWx1ZSBvZiBvYmplY3QgYVxuICovXG5jb25zdCBleHRlbmQgPSAoYSwgYiwgdGhpc0FyZywge2FsbE93bktleXN9PSB7fSkgPT4ge1xuICBmb3JFYWNoKGIsICh2YWwsIGtleSkgPT4ge1xuICAgIGlmICh0aGlzQXJnICYmIGlzRnVuY3Rpb24odmFsKSkge1xuICAgICAgYVtrZXldID0gYmluZCh2YWwsIHRoaXNBcmcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhW2tleV0gPSB2YWw7XG4gICAgfVxuICB9LCB7YWxsT3duS2V5c30pO1xuICByZXR1cm4gYTtcbn07XG5cbi8qKlxuICogUmVtb3ZlIGJ5dGUgb3JkZXIgbWFya2VyLiBUaGlzIGNhdGNoZXMgRUYgQkIgQkYgKHRoZSBVVEYtOCBCT00pXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGNvbnRlbnQgd2l0aCBCT01cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBjb250ZW50IHZhbHVlIHdpdGhvdXQgQk9NXG4gKi9cbmNvbnN0IHN0cmlwQk9NID0gKGNvbnRlbnQpID0+IHtcbiAgaWYgKGNvbnRlbnQuY2hhckNvZGVBdCgwKSA9PT0gMHhGRUZGKSB7XG4gICAgY29udGVudCA9IGNvbnRlbnQuc2xpY2UoMSk7XG4gIH1cbiAgcmV0dXJuIGNvbnRlbnQ7XG59O1xuXG4vKipcbiAqIEluaGVyaXQgdGhlIHByb3RvdHlwZSBtZXRob2RzIGZyb20gb25lIGNvbnN0cnVjdG9yIGludG8gYW5vdGhlclxuICogQHBhcmFtIHtmdW5jdGlvbn0gY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IHN1cGVyQ29uc3RydWN0b3JcbiAqIEBwYXJhbSB7b2JqZWN0fSBbcHJvcHNdXG4gKiBAcGFyYW0ge29iamVjdH0gW2Rlc2NyaXB0b3JzXVxuICpcbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5jb25zdCBpbmhlcml0cyA9IChjb25zdHJ1Y3Rvciwgc3VwZXJDb25zdHJ1Y3RvciwgcHJvcHMsIGRlc2NyaXB0b3JzKSA9PiB7XG4gIGNvbnN0cnVjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIGRlc2NyaXB0b3JzKTtcbiAgY29uc3RydWN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY29uc3RydWN0b3I7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb25zdHJ1Y3RvciwgJ3N1cGVyJywge1xuICAgIHZhbHVlOiBzdXBlckNvbnN0cnVjdG9yLnByb3RvdHlwZVxuICB9KTtcbiAgcHJvcHMgJiYgT2JqZWN0LmFzc2lnbihjb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3BzKTtcbn07XG5cbi8qKlxuICogUmVzb2x2ZSBvYmplY3Qgd2l0aCBkZWVwIHByb3RvdHlwZSBjaGFpbiB0byBhIGZsYXQgb2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gc291cmNlT2JqIHNvdXJjZSBvYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBbZGVzdE9ial1cbiAqIEBwYXJhbSB7RnVuY3Rpb258Qm9vbGVhbn0gW2ZpbHRlcl1cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcm9wRmlsdGVyXVxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9XG4gKi9cbmNvbnN0IHRvRmxhdE9iamVjdCA9IChzb3VyY2VPYmosIGRlc3RPYmosIGZpbHRlciwgcHJvcEZpbHRlcikgPT4ge1xuICBsZXQgcHJvcHM7XG4gIGxldCBpO1xuICBsZXQgcHJvcDtcbiAgY29uc3QgbWVyZ2VkID0ge307XG5cbiAgZGVzdE9iaiA9IGRlc3RPYmogfHwge307XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1lcS1udWxsLGVxZXFlcVxuICBpZiAoc291cmNlT2JqID09IG51bGwpIHJldHVybiBkZXN0T2JqO1xuXG4gIGRvIHtcbiAgICBwcm9wcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHNvdXJjZU9iaik7XG4gICAgaSA9IHByb3BzLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tID4gMCkge1xuICAgICAgcHJvcCA9IHByb3BzW2ldO1xuICAgICAgaWYgKCghcHJvcEZpbHRlciB8fCBwcm9wRmlsdGVyKHByb3AsIHNvdXJjZU9iaiwgZGVzdE9iaikpICYmICFtZXJnZWRbcHJvcF0pIHtcbiAgICAgICAgZGVzdE9ialtwcm9wXSA9IHNvdXJjZU9ialtwcm9wXTtcbiAgICAgICAgbWVyZ2VkW3Byb3BdID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgc291cmNlT2JqID0gZmlsdGVyICE9PSBmYWxzZSAmJiBnZXRQcm90b3R5cGVPZihzb3VyY2VPYmopO1xuICB9IHdoaWxlIChzb3VyY2VPYmogJiYgKCFmaWx0ZXIgfHwgZmlsdGVyKHNvdXJjZU9iaiwgZGVzdE9iaikpICYmIHNvdXJjZU9iaiAhPT0gT2JqZWN0LnByb3RvdHlwZSk7XG5cbiAgcmV0dXJuIGRlc3RPYmo7XG59O1xuXG4vKipcbiAqIERldGVybWluZXMgd2hldGhlciBhIHN0cmluZyBlbmRzIHdpdGggdGhlIGNoYXJhY3RlcnMgb2YgYSBzcGVjaWZpZWQgc3RyaW5nXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHBhcmFtIHtTdHJpbmd9IHNlYXJjaFN0cmluZ1xuICogQHBhcmFtIHtOdW1iZXJ9IFtwb3NpdGlvbj0gMF1cbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuY29uc3QgZW5kc1dpdGggPSAoc3RyLCBzZWFyY2hTdHJpbmcsIHBvc2l0aW9uKSA9PiB7XG4gIHN0ciA9IFN0cmluZyhzdHIpO1xuICBpZiAocG9zaXRpb24gPT09IHVuZGVmaW5lZCB8fCBwb3NpdGlvbiA+IHN0ci5sZW5ndGgpIHtcbiAgICBwb3NpdGlvbiA9IHN0ci5sZW5ndGg7XG4gIH1cbiAgcG9zaXRpb24gLT0gc2VhcmNoU3RyaW5nLmxlbmd0aDtcbiAgY29uc3QgbGFzdEluZGV4ID0gc3RyLmluZGV4T2Yoc2VhcmNoU3RyaW5nLCBwb3NpdGlvbik7XG4gIHJldHVybiBsYXN0SW5kZXggIT09IC0xICYmIGxhc3RJbmRleCA9PT0gcG9zaXRpb247XG59O1xuXG5cbi8qKlxuICogUmV0dXJucyBuZXcgYXJyYXkgZnJvbSBhcnJheSBsaWtlIG9iamVjdCBvciBudWxsIGlmIGZhaWxlZFxuICpcbiAqIEBwYXJhbSB7Kn0gW3RoaW5nXVxuICpcbiAqIEByZXR1cm5zIHs/QXJyYXl9XG4gKi9cbmNvbnN0IHRvQXJyYXkgPSAodGhpbmcpID0+IHtcbiAgaWYgKCF0aGluZykgcmV0dXJuIG51bGw7XG4gIGlmIChpc0FycmF5KHRoaW5nKSkgcmV0dXJuIHRoaW5nO1xuICBsZXQgaSA9IHRoaW5nLmxlbmd0aDtcbiAgaWYgKCFpc051bWJlcihpKSkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IGFyciA9IG5ldyBBcnJheShpKTtcbiAgd2hpbGUgKGktLSA+IDApIHtcbiAgICBhcnJbaV0gPSB0aGluZ1tpXTtcbiAgfVxuICByZXR1cm4gYXJyO1xufTtcblxuLyoqXG4gKiBDaGVja2luZyBpZiB0aGUgVWludDhBcnJheSBleGlzdHMgYW5kIGlmIGl0IGRvZXMsIGl0IHJldHVybnMgYSBmdW5jdGlvbiB0aGF0IGNoZWNrcyBpZiB0aGVcbiAqIHRoaW5nIHBhc3NlZCBpbiBpcyBhbiBpbnN0YW5jZSBvZiBVaW50OEFycmF5XG4gKlxuICogQHBhcmFtIHtUeXBlZEFycmF5fVxuICpcbiAqIEByZXR1cm5zIHtBcnJheX1cbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGZ1bmMtbmFtZXNcbmNvbnN0IGlzVHlwZWRBcnJheSA9IChUeXBlZEFycmF5ID0+IHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGZ1bmMtbmFtZXNcbiAgcmV0dXJuIHRoaW5nID0+IHtcbiAgICByZXR1cm4gVHlwZWRBcnJheSAmJiB0aGluZyBpbnN0YW5jZW9mIFR5cGVkQXJyYXk7XG4gIH07XG59KSh0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcgJiYgZ2V0UHJvdG90eXBlT2YoVWludDhBcnJheSkpO1xuXG4vKipcbiAqIEZvciBlYWNoIGVudHJ5IGluIHRoZSBvYmplY3QsIGNhbGwgdGhlIGZ1bmN0aW9uIHdpdGggdGhlIGtleSBhbmQgdmFsdWUuXG4gKlxuICogQHBhcmFtIHtPYmplY3Q8YW55LCBhbnk+fSBvYmogLSBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gVGhlIGZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggZW50cnkuXG4gKlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmNvbnN0IGZvckVhY2hFbnRyeSA9IChvYmosIGZuKSA9PiB7XG4gIGNvbnN0IGdlbmVyYXRvciA9IG9iaiAmJiBvYmpbU3ltYm9sLml0ZXJhdG9yXTtcblxuICBjb25zdCBpdGVyYXRvciA9IGdlbmVyYXRvci5jYWxsKG9iaik7XG5cbiAgbGV0IHJlc3VsdDtcblxuICB3aGlsZSAoKHJlc3VsdCA9IGl0ZXJhdG9yLm5leHQoKSkgJiYgIXJlc3VsdC5kb25lKSB7XG4gICAgY29uc3QgcGFpciA9IHJlc3VsdC52YWx1ZTtcbiAgICBmbi5jYWxsKG9iaiwgcGFpclswXSwgcGFpclsxXSk7XG4gIH1cbn07XG5cbi8qKlxuICogSXQgdGFrZXMgYSByZWd1bGFyIGV4cHJlc3Npb24gYW5kIGEgc3RyaW5nLCBhbmQgcmV0dXJucyBhbiBhcnJheSBvZiBhbGwgdGhlIG1hdGNoZXNcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVnRXhwIC0gVGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBtYXRjaCBhZ2FpbnN0LlxuICogQHBhcmFtIHtzdHJpbmd9IHN0ciAtIFRoZSBzdHJpbmcgdG8gc2VhcmNoLlxuICpcbiAqIEByZXR1cm5zIHtBcnJheTxib29sZWFuPn1cbiAqL1xuY29uc3QgbWF0Y2hBbGwgPSAocmVnRXhwLCBzdHIpID0+IHtcbiAgbGV0IG1hdGNoZXM7XG4gIGNvbnN0IGFyciA9IFtdO1xuXG4gIHdoaWxlICgobWF0Y2hlcyA9IHJlZ0V4cC5leGVjKHN0cikpICE9PSBudWxsKSB7XG4gICAgYXJyLnB1c2gobWF0Y2hlcyk7XG4gIH1cblxuICByZXR1cm4gYXJyO1xufTtcblxuLyogQ2hlY2tpbmcgaWYgdGhlIGtpbmRPZlRlc3QgZnVuY3Rpb24gcmV0dXJucyB0cnVlIHdoZW4gcGFzc2VkIGFuIEhUTUxGb3JtRWxlbWVudC4gKi9cbmNvbnN0IGlzSFRNTEZvcm0gPSBraW5kT2ZUZXN0KCdIVE1MRm9ybUVsZW1lbnQnKTtcblxuY29uc3QgdG9DYW1lbENhc2UgPSBzdHIgPT4ge1xuICByZXR1cm4gc3RyLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvWy1fXFxzXShbYS16XFxkXSkoXFx3KikvZyxcbiAgICBmdW5jdGlvbiByZXBsYWNlcihtLCBwMSwgcDIpIHtcbiAgICAgIHJldHVybiBwMS50b1VwcGVyQ2FzZSgpICsgcDI7XG4gICAgfVxuICApO1xufTtcblxuLyogQ3JlYXRpbmcgYSBmdW5jdGlvbiB0aGF0IHdpbGwgY2hlY2sgaWYgYW4gb2JqZWN0IGhhcyBhIHByb3BlcnR5LiAqL1xuY29uc3QgaGFzT3duUHJvcGVydHkgPSAoKHtoYXNPd25Qcm9wZXJ0eX0pID0+IChvYmosIHByb3ApID0+IGhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKSkoT2JqZWN0LnByb3RvdHlwZSk7XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYSBSZWdFeHAgb2JqZWN0XG4gKlxuICogQHBhcmFtIHsqfSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIFJlZ0V4cCBvYmplY3QsIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc1JlZ0V4cCA9IGtpbmRPZlRlc3QoJ1JlZ0V4cCcpO1xuXG5jb25zdCByZWR1Y2VEZXNjcmlwdG9ycyA9IChvYmosIHJlZHVjZXIpID0+IHtcbiAgY29uc3QgZGVzY3JpcHRvcnMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhvYmopO1xuICBjb25zdCByZWR1Y2VkRGVzY3JpcHRvcnMgPSB7fTtcblxuICBmb3JFYWNoKGRlc2NyaXB0b3JzLCAoZGVzY3JpcHRvciwgbmFtZSkgPT4ge1xuICAgIGxldCByZXQ7XG4gICAgaWYgKChyZXQgPSByZWR1Y2VyKGRlc2NyaXB0b3IsIG5hbWUsIG9iaikpICE9PSBmYWxzZSkge1xuICAgICAgcmVkdWNlZERlc2NyaXB0b3JzW25hbWVdID0gcmV0IHx8IGRlc2NyaXB0b3I7XG4gICAgfVxuICB9KTtcblxuICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhvYmosIHJlZHVjZWREZXNjcmlwdG9ycyk7XG59O1xuXG4vKipcbiAqIE1ha2VzIGFsbCBtZXRob2RzIHJlYWQtb25seVxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICovXG5cbmNvbnN0IGZyZWV6ZU1ldGhvZHMgPSAob2JqKSA9PiB7XG4gIHJlZHVjZURlc2NyaXB0b3JzKG9iaiwgKGRlc2NyaXB0b3IsIG5hbWUpID0+IHtcbiAgICAvLyBza2lwIHJlc3RyaWN0ZWQgcHJvcHMgaW4gc3RyaWN0IG1vZGVcbiAgICBpZiAoaXNGdW5jdGlvbihvYmopICYmIFsnYXJndW1lbnRzJywgJ2NhbGxlcicsICdjYWxsZWUnXS5pbmRleE9mKG5hbWUpICE9PSAtMSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbHVlID0gb2JqW25hbWVdO1xuXG4gICAgaWYgKCFpc0Z1bmN0aW9uKHZhbHVlKSkgcmV0dXJuO1xuXG4gICAgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZmFsc2U7XG5cbiAgICBpZiAoJ3dyaXRhYmxlJyBpbiBkZXNjcmlwdG9yKSB7XG4gICAgICBkZXNjcmlwdG9yLndyaXRhYmxlID0gZmFsc2U7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFkZXNjcmlwdG9yLnNldCkge1xuICAgICAgZGVzY3JpcHRvci5zZXQgPSAoKSA9PiB7XG4gICAgICAgIHRocm93IEVycm9yKCdDYW4gbm90IHJld3JpdGUgcmVhZC1vbmx5IG1ldGhvZCBcXCcnICsgbmFtZSArICdcXCcnKTtcbiAgICAgIH07XG4gICAgfVxuICB9KTtcbn07XG5cbmNvbnN0IHRvT2JqZWN0U2V0ID0gKGFycmF5T3JTdHJpbmcsIGRlbGltaXRlcikgPT4ge1xuICBjb25zdCBvYmogPSB7fTtcblxuICBjb25zdCBkZWZpbmUgPSAoYXJyKSA9PiB7XG4gICAgYXJyLmZvckVhY2godmFsdWUgPT4ge1xuICAgICAgb2JqW3ZhbHVlXSA9IHRydWU7XG4gICAgfSk7XG4gIH07XG5cbiAgaXNBcnJheShhcnJheU9yU3RyaW5nKSA/IGRlZmluZShhcnJheU9yU3RyaW5nKSA6IGRlZmluZShTdHJpbmcoYXJyYXlPclN0cmluZykuc3BsaXQoZGVsaW1pdGVyKSk7XG5cbiAgcmV0dXJuIG9iajtcbn07XG5cbmNvbnN0IG5vb3AgPSAoKSA9PiB7fTtcblxuY29uc3QgdG9GaW5pdGVOdW1iZXIgPSAodmFsdWUsIGRlZmF1bHRWYWx1ZSkgPT4ge1xuICB2YWx1ZSA9ICt2YWx1ZTtcbiAgcmV0dXJuIE51bWJlci5pc0Zpbml0ZSh2YWx1ZSkgPyB2YWx1ZSA6IGRlZmF1bHRWYWx1ZTtcbn07XG5cbmNvbnN0IEFMUEhBID0gJ2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6JztcblxuY29uc3QgRElHSVQgPSAnMDEyMzQ1Njc4OSc7XG5cbmNvbnN0IEFMUEhBQkVUID0ge1xuICBESUdJVCxcbiAgQUxQSEEsXG4gIEFMUEhBX0RJR0lUOiBBTFBIQSArIEFMUEhBLnRvVXBwZXJDYXNlKCkgKyBESUdJVFxufTtcblxuY29uc3QgZ2VuZXJhdGVTdHJpbmcgPSAoc2l6ZSA9IDE2LCBhbHBoYWJldCA9IEFMUEhBQkVULkFMUEhBX0RJR0lUKSA9PiB7XG4gIGxldCBzdHIgPSAnJztcbiAgY29uc3Qge2xlbmd0aH0gPSBhbHBoYWJldDtcbiAgd2hpbGUgKHNpemUtLSkge1xuICAgIHN0ciArPSBhbHBoYWJldFtNYXRoLnJhbmRvbSgpICogbGVuZ3RofDBdO1xuICB9XG5cbiAgcmV0dXJuIHN0cjtcbn07XG5cbi8qKlxuICogSWYgdGhlIHRoaW5nIGlzIGEgRm9ybURhdGEgb2JqZWN0LCByZXR1cm4gdHJ1ZSwgb3RoZXJ3aXNlIHJldHVybiBmYWxzZS5cbiAqXG4gKiBAcGFyYW0ge3Vua25vd259IHRoaW5nIC0gVGhlIHRoaW5nIHRvIGNoZWNrLlxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBpc1NwZWNDb21wbGlhbnRGb3JtKHRoaW5nKSB7XG4gIHJldHVybiAhISh0aGluZyAmJiBpc0Z1bmN0aW9uKHRoaW5nLmFwcGVuZCkgJiYgdGhpbmdbU3ltYm9sLnRvU3RyaW5nVGFnXSA9PT0gJ0Zvcm1EYXRhJyAmJiB0aGluZ1tTeW1ib2wuaXRlcmF0b3JdKTtcbn1cblxuY29uc3QgdG9KU09OT2JqZWN0ID0gKG9iaikgPT4ge1xuICBjb25zdCBzdGFjayA9IG5ldyBBcnJheSgxMCk7XG5cbiAgY29uc3QgdmlzaXQgPSAoc291cmNlLCBpKSA9PiB7XG5cbiAgICBpZiAoaXNPYmplY3Qoc291cmNlKSkge1xuICAgICAgaWYgKHN0YWNrLmluZGV4T2Yoc291cmNlKSA+PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYoISgndG9KU09OJyBpbiBzb3VyY2UpKSB7XG4gICAgICAgIHN0YWNrW2ldID0gc291cmNlO1xuICAgICAgICBjb25zdCB0YXJnZXQgPSBpc0FycmF5KHNvdXJjZSkgPyBbXSA6IHt9O1xuXG4gICAgICAgIGZvckVhY2goc291cmNlLCAodmFsdWUsIGtleSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHJlZHVjZWRWYWx1ZSA9IHZpc2l0KHZhbHVlLCBpICsgMSk7XG4gICAgICAgICAgIWlzVW5kZWZpbmVkKHJlZHVjZWRWYWx1ZSkgJiYgKHRhcmdldFtrZXldID0gcmVkdWNlZFZhbHVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc3RhY2tbaV0gPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc291cmNlO1xuICB9O1xuXG4gIHJldHVybiB2aXNpdChvYmosIDApO1xufTtcblxuY29uc3QgaXNBc3luY0ZuID0ga2luZE9mVGVzdCgnQXN5bmNGdW5jdGlvbicpO1xuXG5jb25zdCBpc1RoZW5hYmxlID0gKHRoaW5nKSA9PlxuICB0aGluZyAmJiAoaXNPYmplY3QodGhpbmcpIHx8IGlzRnVuY3Rpb24odGhpbmcpKSAmJiBpc0Z1bmN0aW9uKHRoaW5nLnRoZW4pICYmIGlzRnVuY3Rpb24odGhpbmcuY2F0Y2gpO1xuXG5jb25zdCB1dGlscyA9IHtcbiAgaXNBcnJheSxcbiAgaXNBcnJheUJ1ZmZlcixcbiAgaXNCdWZmZXIsXG4gIGlzRm9ybURhdGEsXG4gIGlzQXJyYXlCdWZmZXJWaWV3LFxuICBpc1N0cmluZyxcbiAgaXNOdW1iZXIsXG4gIGlzQm9vbGVhbixcbiAgaXNPYmplY3QsXG4gIGlzUGxhaW5PYmplY3QsXG4gIGlzVW5kZWZpbmVkLFxuICBpc0RhdGUsXG4gIGlzRmlsZSxcbiAgaXNCbG9iLFxuICBpc1JlZ0V4cCxcbiAgaXNGdW5jdGlvbixcbiAgaXNTdHJlYW0sXG4gIGlzVVJMU2VhcmNoUGFyYW1zLFxuICBpc1R5cGVkQXJyYXksXG4gIGlzRmlsZUxpc3QsXG4gIGZvckVhY2gsXG4gIG1lcmdlLFxuICBleHRlbmQsXG4gIHRyaW0sXG4gIHN0cmlwQk9NLFxuICBpbmhlcml0cyxcbiAgdG9GbGF0T2JqZWN0LFxuICBraW5kT2YsXG4gIGtpbmRPZlRlc3QsXG4gIGVuZHNXaXRoLFxuICB0b0FycmF5LFxuICBmb3JFYWNoRW50cnksXG4gIG1hdGNoQWxsLFxuICBpc0hUTUxGb3JtLFxuICBoYXNPd25Qcm9wZXJ0eSxcbiAgaGFzT3duUHJvcDogaGFzT3duUHJvcGVydHksIC8vIGFuIGFsaWFzIHRvIGF2b2lkIEVTTGludCBuby1wcm90b3R5cGUtYnVpbHRpbnMgZGV0ZWN0aW9uXG4gIHJlZHVjZURlc2NyaXB0b3JzLFxuICBmcmVlemVNZXRob2RzLFxuICB0b09iamVjdFNldCxcbiAgdG9DYW1lbENhc2UsXG4gIG5vb3AsXG4gIHRvRmluaXRlTnVtYmVyLFxuICBmaW5kS2V5LFxuICBnbG9iYWw6IF9nbG9iYWwsXG4gIGlzQ29udGV4dERlZmluZWQsXG4gIEFMUEhBQkVULFxuICBnZW5lcmF0ZVN0cmluZyxcbiAgaXNTcGVjQ29tcGxpYW50Rm9ybSxcbiAgdG9KU09OT2JqZWN0LFxuICBpc0FzeW5jRm4sXG4gIGlzVGhlbmFibGVcbn07XG5cbi8qKlxuICogQ3JlYXRlIGFuIEVycm9yIHdpdGggdGhlIHNwZWNpZmllZCBtZXNzYWdlLCBjb25maWcsIGVycm9yIGNvZGUsIHJlcXVlc3QgYW5kIHJlc3BvbnNlLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIFRoZSBlcnJvciBtZXNzYWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IFtjb2RlXSBUaGUgZXJyb3IgY29kZSAoZm9yIGV4YW1wbGUsICdFQ09OTkFCT1JURUQnKS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbY29uZmlnXSBUaGUgY29uZmlnLlxuICogQHBhcmFtIHtPYmplY3R9IFtyZXF1ZXN0XSBUaGUgcmVxdWVzdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbcmVzcG9uc2VdIFRoZSByZXNwb25zZS5cbiAqXG4gKiBAcmV0dXJucyB7RXJyb3J9IFRoZSBjcmVhdGVkIGVycm9yLlxuICovXG5mdW5jdGlvbiBBeGlvc0Vycm9yKG1lc3NhZ2UsIGNvZGUsIGNvbmZpZywgcmVxdWVzdCwgcmVzcG9uc2UpIHtcbiAgRXJyb3IuY2FsbCh0aGlzKTtcblxuICBpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIHtcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCB0aGlzLmNvbnN0cnVjdG9yKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnN0YWNrID0gKG5ldyBFcnJvcigpKS5zdGFjaztcbiAgfVxuXG4gIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG4gIHRoaXMubmFtZSA9ICdBeGlvc0Vycm9yJztcbiAgY29kZSAmJiAodGhpcy5jb2RlID0gY29kZSk7XG4gIGNvbmZpZyAmJiAodGhpcy5jb25maWcgPSBjb25maWcpO1xuICByZXF1ZXN0ICYmICh0aGlzLnJlcXVlc3QgPSByZXF1ZXN0KTtcbiAgcmVzcG9uc2UgJiYgKHRoaXMucmVzcG9uc2UgPSByZXNwb25zZSk7XG59XG5cbnV0aWxzLmluaGVyaXRzKEF4aW9zRXJyb3IsIEVycm9yLCB7XG4gIHRvSlNPTjogZnVuY3Rpb24gdG9KU09OKCkge1xuICAgIHJldHVybiB7XG4gICAgICAvLyBTdGFuZGFyZFxuICAgICAgbWVzc2FnZTogdGhpcy5tZXNzYWdlLFxuICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgLy8gTWljcm9zb2Z0XG4gICAgICBkZXNjcmlwdGlvbjogdGhpcy5kZXNjcmlwdGlvbixcbiAgICAgIG51bWJlcjogdGhpcy5udW1iZXIsXG4gICAgICAvLyBNb3ppbGxhXG4gICAgICBmaWxlTmFtZTogdGhpcy5maWxlTmFtZSxcbiAgICAgIGxpbmVOdW1iZXI6IHRoaXMubGluZU51bWJlcixcbiAgICAgIGNvbHVtbk51bWJlcjogdGhpcy5jb2x1bW5OdW1iZXIsXG4gICAgICBzdGFjazogdGhpcy5zdGFjayxcbiAgICAgIC8vIEF4aW9zXG4gICAgICBjb25maWc6IHV0aWxzLnRvSlNPTk9iamVjdCh0aGlzLmNvbmZpZyksXG4gICAgICBjb2RlOiB0aGlzLmNvZGUsXG4gICAgICBzdGF0dXM6IHRoaXMucmVzcG9uc2UgJiYgdGhpcy5yZXNwb25zZS5zdGF0dXMgPyB0aGlzLnJlc3BvbnNlLnN0YXR1cyA6IG51bGxcbiAgICB9O1xuICB9XG59KTtcblxuY29uc3QgcHJvdG90eXBlJDEgPSBBeGlvc0Vycm9yLnByb3RvdHlwZTtcbmNvbnN0IGRlc2NyaXB0b3JzID0ge307XG5cbltcbiAgJ0VSUl9CQURfT1BUSU9OX1ZBTFVFJyxcbiAgJ0VSUl9CQURfT1BUSU9OJyxcbiAgJ0VDT05OQUJPUlRFRCcsXG4gICdFVElNRURPVVQnLFxuICAnRVJSX05FVFdPUksnLFxuICAnRVJSX0ZSX1RPT19NQU5ZX1JFRElSRUNUUycsXG4gICdFUlJfREVQUkVDQVRFRCcsXG4gICdFUlJfQkFEX1JFU1BPTlNFJyxcbiAgJ0VSUl9CQURfUkVRVUVTVCcsXG4gICdFUlJfQ0FOQ0VMRUQnLFxuICAnRVJSX05PVF9TVVBQT1JUJyxcbiAgJ0VSUl9JTlZBTElEX1VSTCdcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBmdW5jLW5hbWVzXG5dLmZvckVhY2goY29kZSA9PiB7XG4gIGRlc2NyaXB0b3JzW2NvZGVdID0ge3ZhbHVlOiBjb2RlfTtcbn0pO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhBeGlvc0Vycm9yLCBkZXNjcmlwdG9ycyk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkocHJvdG90eXBlJDEsICdpc0F4aW9zRXJyb3InLCB7dmFsdWU6IHRydWV9KTtcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGZ1bmMtbmFtZXNcbkF4aW9zRXJyb3IuZnJvbSA9IChlcnJvciwgY29kZSwgY29uZmlnLCByZXF1ZXN0LCByZXNwb25zZSwgY3VzdG9tUHJvcHMpID0+IHtcbiAgY29uc3QgYXhpb3NFcnJvciA9IE9iamVjdC5jcmVhdGUocHJvdG90eXBlJDEpO1xuXG4gIHV0aWxzLnRvRmxhdE9iamVjdChlcnJvciwgYXhpb3NFcnJvciwgZnVuY3Rpb24gZmlsdGVyKG9iaikge1xuICAgIHJldHVybiBvYmogIT09IEVycm9yLnByb3RvdHlwZTtcbiAgfSwgcHJvcCA9PiB7XG4gICAgcmV0dXJuIHByb3AgIT09ICdpc0F4aW9zRXJyb3InO1xuICB9KTtcblxuICBBeGlvc0Vycm9yLmNhbGwoYXhpb3NFcnJvciwgZXJyb3IubWVzc2FnZSwgY29kZSwgY29uZmlnLCByZXF1ZXN0LCByZXNwb25zZSk7XG5cbiAgYXhpb3NFcnJvci5jYXVzZSA9IGVycm9yO1xuXG4gIGF4aW9zRXJyb3IubmFtZSA9IGVycm9yLm5hbWU7XG5cbiAgY3VzdG9tUHJvcHMgJiYgT2JqZWN0LmFzc2lnbihheGlvc0Vycm9yLCBjdXN0b21Qcm9wcyk7XG5cbiAgcmV0dXJuIGF4aW9zRXJyb3I7XG59O1xuXG4vKipcbiAqIERldGVybWluZXMgaWYgdGhlIGdpdmVuIHRoaW5nIGlzIGEgYXJyYXkgb3IganMgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0aGluZyAtIFRoZSBvYmplY3Qgb3IgYXJyYXkgdG8gYmUgdmlzaXRlZC5cbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaXNWaXNpdGFibGUodGhpbmcpIHtcbiAgcmV0dXJuIHV0aWxzLmlzUGxhaW5PYmplY3QodGhpbmcpIHx8IHV0aWxzLmlzQXJyYXkodGhpbmcpO1xufVxuXG4vKipcbiAqIEl0IHJlbW92ZXMgdGhlIGJyYWNrZXRzIGZyb20gdGhlIGVuZCBvZiBhIHN0cmluZ1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBUaGUga2V5IG9mIHRoZSBwYXJhbWV0ZXIuXG4gKlxuICogQHJldHVybnMge3N0cmluZ30gdGhlIGtleSB3aXRob3V0IHRoZSBicmFja2V0cy5cbiAqL1xuZnVuY3Rpb24gcmVtb3ZlQnJhY2tldHMoa2V5KSB7XG4gIHJldHVybiB1dGlscy5lbmRzV2l0aChrZXksICdbXScpID8ga2V5LnNsaWNlKDAsIC0yKSA6IGtleTtcbn1cblxuLyoqXG4gKiBJdCB0YWtlcyBhIHBhdGgsIGEga2V5LCBhbmQgYSBib29sZWFuLCBhbmQgcmV0dXJucyBhIHN0cmluZ1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gVGhlIHBhdGggdG8gdGhlIGN1cnJlbnQga2V5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIFRoZSBrZXkgb2YgdGhlIGN1cnJlbnQgb2JqZWN0IGJlaW5nIGl0ZXJhdGVkIG92ZXIuXG4gKiBAcGFyYW0ge3N0cmluZ30gZG90cyAtIElmIHRydWUsIHRoZSBrZXkgd2lsbCBiZSByZW5kZXJlZCB3aXRoIGRvdHMgaW5zdGVhZCBvZiBicmFja2V0cy5cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgcGF0aCB0byB0aGUgY3VycmVudCBrZXkuXG4gKi9cbmZ1bmN0aW9uIHJlbmRlcktleShwYXRoLCBrZXksIGRvdHMpIHtcbiAgaWYgKCFwYXRoKSByZXR1cm4ga2V5O1xuICByZXR1cm4gcGF0aC5jb25jYXQoa2V5KS5tYXAoZnVuY3Rpb24gZWFjaCh0b2tlbiwgaSkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuICAgIHRva2VuID0gcmVtb3ZlQnJhY2tldHModG9rZW4pO1xuICAgIHJldHVybiAhZG90cyAmJiBpID8gJ1snICsgdG9rZW4gKyAnXScgOiB0b2tlbjtcbiAgfSkuam9pbihkb3RzID8gJy4nIDogJycpO1xufVxuXG4vKipcbiAqIElmIHRoZSBhcnJheSBpcyBhbiBhcnJheSBhbmQgbm9uZSBvZiBpdHMgZWxlbWVudHMgYXJlIHZpc2l0YWJsZSwgdGhlbiBpdCdzIGEgZmxhdCBhcnJheS5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PGFueT59IGFyciAtIFRoZSBhcnJheSB0byBjaGVja1xuICpcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBpc0ZsYXRBcnJheShhcnIpIHtcbiAgcmV0dXJuIHV0aWxzLmlzQXJyYXkoYXJyKSAmJiAhYXJyLnNvbWUoaXNWaXNpdGFibGUpO1xufVxuXG5jb25zdCBwcmVkaWNhdGVzID0gdXRpbHMudG9GbGF0T2JqZWN0KHV0aWxzLCB7fSwgbnVsbCwgZnVuY3Rpb24gZmlsdGVyKHByb3ApIHtcbiAgcmV0dXJuIC9eaXNbQS1aXS8udGVzdChwcm9wKTtcbn0pO1xuXG4vKipcbiAqIENvbnZlcnQgYSBkYXRhIG9iamVjdCB0byBGb3JtRGF0YVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEBwYXJhbSB7P09iamVjdH0gW2Zvcm1EYXRhXVxuICogQHBhcmFtIHs/T2JqZWN0fSBbb3B0aW9uc11cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLnZpc2l0b3JdXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLm1ldGFUb2tlbnMgPSB0cnVlXVxuICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5kb3RzID0gZmFsc2VdXG4gKiBAcGFyYW0gez9Cb29sZWFufSBbb3B0aW9ucy5pbmRleGVzID0gZmFsc2VdXG4gKlxuICogQHJldHVybnMge09iamVjdH1cbiAqKi9cblxuLyoqXG4gKiBJdCBjb252ZXJ0cyBhbiBvYmplY3QgaW50byBhIEZvcm1EYXRhIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0PGFueSwgYW55Pn0gb2JqIC0gVGhlIG9iamVjdCB0byBjb252ZXJ0IHRvIGZvcm0gZGF0YS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmb3JtRGF0YSAtIFRoZSBGb3JtRGF0YSBvYmplY3QgdG8gYXBwZW5kIHRvLlxuICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLCBhbnk+fSBvcHRpb25zXG4gKlxuICogQHJldHVybnNcbiAqL1xuZnVuY3Rpb24gdG9Gb3JtRGF0YShvYmosIGZvcm1EYXRhLCBvcHRpb25zKSB7XG4gIGlmICghdXRpbHMuaXNPYmplY3Qob2JqKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3RhcmdldCBtdXN0IGJlIGFuIG9iamVjdCcpO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG4gIGZvcm1EYXRhID0gZm9ybURhdGEgfHwgbmV3IChGb3JtRGF0YV9fZGVmYXVsdFtcImRlZmF1bHRcIl0gfHwgRm9ybURhdGEpKCk7XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG4gIG9wdGlvbnMgPSB1dGlscy50b0ZsYXRPYmplY3Qob3B0aW9ucywge1xuICAgIG1ldGFUb2tlbnM6IHRydWUsXG4gICAgZG90czogZmFsc2UsXG4gICAgaW5kZXhlczogZmFsc2VcbiAgfSwgZmFsc2UsIGZ1bmN0aW9uIGRlZmluZWQob3B0aW9uLCBzb3VyY2UpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZXEtbnVsbCxlcWVxZXFcbiAgICByZXR1cm4gIXV0aWxzLmlzVW5kZWZpbmVkKHNvdXJjZVtvcHRpb25dKTtcbiAgfSk7XG5cbiAgY29uc3QgbWV0YVRva2VucyA9IG9wdGlvbnMubWV0YVRva2VucztcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVzZS1iZWZvcmUtZGVmaW5lXG4gIGNvbnN0IHZpc2l0b3IgPSBvcHRpb25zLnZpc2l0b3IgfHwgZGVmYXVsdFZpc2l0b3I7XG4gIGNvbnN0IGRvdHMgPSBvcHRpb25zLmRvdHM7XG4gIGNvbnN0IGluZGV4ZXMgPSBvcHRpb25zLmluZGV4ZXM7XG4gIGNvbnN0IF9CbG9iID0gb3B0aW9ucy5CbG9iIHx8IHR5cGVvZiBCbG9iICE9PSAndW5kZWZpbmVkJyAmJiBCbG9iO1xuICBjb25zdCB1c2VCbG9iID0gX0Jsb2IgJiYgdXRpbHMuaXNTcGVjQ29tcGxpYW50Rm9ybShmb3JtRGF0YSk7XG5cbiAgaWYgKCF1dGlscy5pc0Z1bmN0aW9uKHZpc2l0b3IpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmlzaXRvciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNvbnZlcnRWYWx1ZSh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkgcmV0dXJuICcnO1xuXG4gICAgaWYgKHV0aWxzLmlzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZS50b0lTT1N0cmluZygpO1xuICAgIH1cblxuICAgIGlmICghdXNlQmxvYiAmJiB1dGlscy5pc0Jsb2IodmFsdWUpKSB7XG4gICAgICB0aHJvdyBuZXcgQXhpb3NFcnJvcignQmxvYiBpcyBub3Qgc3VwcG9ydGVkLiBVc2UgYSBCdWZmZXIgaW5zdGVhZC4nKTtcbiAgICB9XG5cbiAgICBpZiAodXRpbHMuaXNBcnJheUJ1ZmZlcih2YWx1ZSkgfHwgdXRpbHMuaXNUeXBlZEFycmF5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHVzZUJsb2IgJiYgdHlwZW9mIEJsb2IgPT09ICdmdW5jdGlvbicgPyBuZXcgQmxvYihbdmFsdWVdKSA6IEJ1ZmZlci5mcm9tKHZhbHVlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogRGVmYXVsdCB2aXNpdG9yLlxuICAgKlxuICAgKiBAcGFyYW0geyp9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfE51bWJlcn0ga2V5XG4gICAqIEBwYXJhbSB7QXJyYXk8U3RyaW5nfE51bWJlcj59IHBhdGhcbiAgICogQHRoaXMge0Zvcm1EYXRhfVxuICAgKlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gcmV0dXJuIHRydWUgdG8gdmlzaXQgdGhlIGVhY2ggcHJvcCBvZiB0aGUgdmFsdWUgcmVjdXJzaXZlbHlcbiAgICovXG4gIGZ1bmN0aW9uIGRlZmF1bHRWaXNpdG9yKHZhbHVlLCBrZXksIHBhdGgpIHtcbiAgICBsZXQgYXJyID0gdmFsdWU7XG5cbiAgICBpZiAodmFsdWUgJiYgIXBhdGggJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKHV0aWxzLmVuZHNXaXRoKGtleSwgJ3t9JykpIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG4gICAgICAgIGtleSA9IG1ldGFUb2tlbnMgPyBrZXkgOiBrZXkuc2xpY2UoMCwgLTIpO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cbiAgICAgICAgdmFsdWUgPSBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAodXRpbHMuaXNBcnJheSh2YWx1ZSkgJiYgaXNGbGF0QXJyYXkodmFsdWUpKSB8fFxuICAgICAgICAoKHV0aWxzLmlzRmlsZUxpc3QodmFsdWUpIHx8IHV0aWxzLmVuZHNXaXRoKGtleSwgJ1tdJykpICYmIChhcnIgPSB1dGlscy50b0FycmF5KHZhbHVlKSlcbiAgICAgICAgKSkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cbiAgICAgICAga2V5ID0gcmVtb3ZlQnJhY2tldHMoa2V5KTtcblxuICAgICAgICBhcnIuZm9yRWFjaChmdW5jdGlvbiBlYWNoKGVsLCBpbmRleCkge1xuICAgICAgICAgICEodXRpbHMuaXNVbmRlZmluZWQoZWwpIHx8IGVsID09PSBudWxsKSAmJiBmb3JtRGF0YS5hcHBlbmQoXG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbmVzdGVkLXRlcm5hcnlcbiAgICAgICAgICAgIGluZGV4ZXMgPT09IHRydWUgPyByZW5kZXJLZXkoW2tleV0sIGluZGV4LCBkb3RzKSA6IChpbmRleGVzID09PSBudWxsID8ga2V5IDoga2V5ICsgJ1tdJyksXG4gICAgICAgICAgICBjb252ZXJ0VmFsdWUoZWwpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNWaXNpdGFibGUodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBmb3JtRGF0YS5hcHBlbmQocmVuZGVyS2V5KHBhdGgsIGtleSwgZG90cyksIGNvbnZlcnRWYWx1ZSh2YWx1ZSkpO1xuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3Qgc3RhY2sgPSBbXTtcblxuICBjb25zdCBleHBvc2VkSGVscGVycyA9IE9iamVjdC5hc3NpZ24ocHJlZGljYXRlcywge1xuICAgIGRlZmF1bHRWaXNpdG9yLFxuICAgIGNvbnZlcnRWYWx1ZSxcbiAgICBpc1Zpc2l0YWJsZVxuICB9KTtcblxuICBmdW5jdGlvbiBidWlsZCh2YWx1ZSwgcGF0aCkge1xuICAgIGlmICh1dGlscy5pc1VuZGVmaW5lZCh2YWx1ZSkpIHJldHVybjtcblxuICAgIGlmIChzdGFjay5pbmRleE9mKHZhbHVlKSAhPT0gLTEpIHtcbiAgICAgIHRocm93IEVycm9yKCdDaXJjdWxhciByZWZlcmVuY2UgZGV0ZWN0ZWQgaW4gJyArIHBhdGguam9pbignLicpKTtcbiAgICB9XG5cbiAgICBzdGFjay5wdXNoKHZhbHVlKTtcblxuICAgIHV0aWxzLmZvckVhY2godmFsdWUsIGZ1bmN0aW9uIGVhY2goZWwsIGtleSkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gISh1dGlscy5pc1VuZGVmaW5lZChlbCkgfHwgZWwgPT09IG51bGwpICYmIHZpc2l0b3IuY2FsbChcbiAgICAgICAgZm9ybURhdGEsIGVsLCB1dGlscy5pc1N0cmluZyhrZXkpID8ga2V5LnRyaW0oKSA6IGtleSwgcGF0aCwgZXhwb3NlZEhlbHBlcnNcbiAgICAgICk7XG5cbiAgICAgIGlmIChyZXN1bHQgPT09IHRydWUpIHtcbiAgICAgICAgYnVpbGQoZWwsIHBhdGggPyBwYXRoLmNvbmNhdChrZXkpIDogW2tleV0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgc3RhY2sucG9wKCk7XG4gIH1cblxuICBpZiAoIXV0aWxzLmlzT2JqZWN0KG9iaikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdkYXRhIG11c3QgYmUgYW4gb2JqZWN0Jyk7XG4gIH1cblxuICBidWlsZChvYmopO1xuXG4gIHJldHVybiBmb3JtRGF0YTtcbn1cblxuLyoqXG4gKiBJdCBlbmNvZGVzIGEgc3RyaW5nIGJ5IHJlcGxhY2luZyBhbGwgY2hhcmFjdGVycyB0aGF0IGFyZSBub3QgaW4gdGhlIHVucmVzZXJ2ZWQgc2V0IHdpdGhcbiAqIHRoZWlyIHBlcmNlbnQtZW5jb2RlZCBlcXVpdmFsZW50c1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgLSBUaGUgc3RyaW5nIHRvIGVuY29kZS5cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZW5jb2RlZCBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGVuY29kZSQxKHN0cikge1xuICBjb25zdCBjaGFyTWFwID0ge1xuICAgICchJzogJyUyMScsXG4gICAgXCInXCI6ICclMjcnLFxuICAgICcoJzogJyUyOCcsXG4gICAgJyknOiAnJTI5JyxcbiAgICAnfic6ICclN0UnLFxuICAgICclMjAnOiAnKycsXG4gICAgJyUwMCc6ICdcXHgwMCdcbiAgfTtcbiAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChzdHIpLnJlcGxhY2UoL1shJygpfl18JTIwfCUwMC9nLCBmdW5jdGlvbiByZXBsYWNlcihtYXRjaCkge1xuICAgIHJldHVybiBjaGFyTWFwW21hdGNoXTtcbiAgfSk7XG59XG5cbi8qKlxuICogSXQgdGFrZXMgYSBwYXJhbXMgb2JqZWN0IGFuZCBjb252ZXJ0cyBpdCB0byBhIEZvcm1EYXRhIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0PHN0cmluZywgYW55Pn0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgdG8gYmUgY29udmVydGVkIHRvIGEgRm9ybURhdGEgb2JqZWN0LlxuICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLCBhbnk+fSBvcHRpb25zIC0gVGhlIG9wdGlvbnMgb2JqZWN0IHBhc3NlZCB0byB0aGUgQXhpb3MgY29uc3RydWN0b3IuXG4gKlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIEF4aW9zVVJMU2VhcmNoUGFyYW1zKHBhcmFtcywgb3B0aW9ucykge1xuICB0aGlzLl9wYWlycyA9IFtdO1xuXG4gIHBhcmFtcyAmJiB0b0Zvcm1EYXRhKHBhcmFtcywgdGhpcywgb3B0aW9ucyk7XG59XG5cbmNvbnN0IHByb3RvdHlwZSA9IEF4aW9zVVJMU2VhcmNoUGFyYW1zLnByb3RvdHlwZTtcblxucHJvdG90eXBlLmFwcGVuZCA9IGZ1bmN0aW9uIGFwcGVuZChuYW1lLCB2YWx1ZSkge1xuICB0aGlzLl9wYWlycy5wdXNoKFtuYW1lLCB2YWx1ZV0pO1xufTtcblxucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoZW5jb2Rlcikge1xuICBjb25zdCBfZW5jb2RlID0gZW5jb2RlciA/IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgcmV0dXJuIGVuY29kZXIuY2FsbCh0aGlzLCB2YWx1ZSwgZW5jb2RlJDEpO1xuICB9IDogZW5jb2RlJDE7XG5cbiAgcmV0dXJuIHRoaXMuX3BhaXJzLm1hcChmdW5jdGlvbiBlYWNoKHBhaXIpIHtcbiAgICByZXR1cm4gX2VuY29kZShwYWlyWzBdKSArICc9JyArIF9lbmNvZGUocGFpclsxXSk7XG4gIH0sICcnKS5qb2luKCcmJyk7XG59O1xuXG4vKipcbiAqIEl0IHJlcGxhY2VzIGFsbCBpbnN0YW5jZXMgb2YgdGhlIGNoYXJhY3RlcnMgYDpgLCBgJGAsIGAsYCwgYCtgLCBgW2AsIGFuZCBgXWAgd2l0aCB0aGVpclxuICogVVJJIGVuY29kZWQgY291bnRlcnBhcnRzXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHZhbCBUaGUgdmFsdWUgdG8gYmUgZW5jb2RlZC5cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZW5jb2RlZCB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gZW5jb2RlKHZhbCkge1xuICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KHZhbCkuXG4gICAgcmVwbGFjZSgvJTNBL2dpLCAnOicpLlxuICAgIHJlcGxhY2UoLyUyNC9nLCAnJCcpLlxuICAgIHJlcGxhY2UoLyUyQy9naSwgJywnKS5cbiAgICByZXBsYWNlKC8lMjAvZywgJysnKS5cbiAgICByZXBsYWNlKC8lNUIvZ2ksICdbJykuXG4gICAgcmVwbGFjZSgvJTVEL2dpLCAnXScpO1xufVxuXG4vKipcbiAqIEJ1aWxkIGEgVVJMIGJ5IGFwcGVuZGluZyBwYXJhbXMgdG8gdGhlIGVuZFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgVGhlIGJhc2Ugb2YgdGhlIHVybCAoZS5nLiwgaHR0cDovL3d3dy5nb29nbGUuY29tKVxuICogQHBhcmFtIHtvYmplY3R9IFtwYXJhbXNdIFRoZSBwYXJhbXMgdG8gYmUgYXBwZW5kZWRcbiAqIEBwYXJhbSB7P29iamVjdH0gb3B0aW9uc1xuICpcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBmb3JtYXR0ZWQgdXJsXG4gKi9cbmZ1bmN0aW9uIGJ1aWxkVVJMKHVybCwgcGFyYW1zLCBvcHRpb25zKSB7XG4gIC8qZXNsaW50IG5vLXBhcmFtLXJlYXNzaWduOjAqL1xuICBpZiAoIXBhcmFtcykge1xuICAgIHJldHVybiB1cmw7XG4gIH1cbiAgXG4gIGNvbnN0IF9lbmNvZGUgPSBvcHRpb25zICYmIG9wdGlvbnMuZW5jb2RlIHx8IGVuY29kZTtcblxuICBjb25zdCBzZXJpYWxpemVGbiA9IG9wdGlvbnMgJiYgb3B0aW9ucy5zZXJpYWxpemU7XG5cbiAgbGV0IHNlcmlhbGl6ZWRQYXJhbXM7XG5cbiAgaWYgKHNlcmlhbGl6ZUZuKSB7XG4gICAgc2VyaWFsaXplZFBhcmFtcyA9IHNlcmlhbGl6ZUZuKHBhcmFtcywgb3B0aW9ucyk7XG4gIH0gZWxzZSB7XG4gICAgc2VyaWFsaXplZFBhcmFtcyA9IHV0aWxzLmlzVVJMU2VhcmNoUGFyYW1zKHBhcmFtcykgP1xuICAgICAgcGFyYW1zLnRvU3RyaW5nKCkgOlxuICAgICAgbmV3IEF4aW9zVVJMU2VhcmNoUGFyYW1zKHBhcmFtcywgb3B0aW9ucykudG9TdHJpbmcoX2VuY29kZSk7XG4gIH1cblxuICBpZiAoc2VyaWFsaXplZFBhcmFtcykge1xuICAgIGNvbnN0IGhhc2htYXJrSW5kZXggPSB1cmwuaW5kZXhPZihcIiNcIik7XG5cbiAgICBpZiAoaGFzaG1hcmtJbmRleCAhPT0gLTEpIHtcbiAgICAgIHVybCA9IHVybC5zbGljZSgwLCBoYXNobWFya0luZGV4KTtcbiAgICB9XG4gICAgdXJsICs9ICh1cmwuaW5kZXhPZignPycpID09PSAtMSA/ICc/JyA6ICcmJykgKyBzZXJpYWxpemVkUGFyYW1zO1xuICB9XG5cbiAgcmV0dXJuIHVybDtcbn1cblxuY2xhc3MgSW50ZXJjZXB0b3JNYW5hZ2VyIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5oYW5kbGVycyA9IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhIG5ldyBpbnRlcmNlcHRvciB0byB0aGUgc3RhY2tcbiAgICpcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVsZmlsbGVkIFRoZSBmdW5jdGlvbiB0byBoYW5kbGUgYHRoZW5gIGZvciBhIGBQcm9taXNlYFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSByZWplY3RlZCBUaGUgZnVuY3Rpb24gdG8gaGFuZGxlIGByZWplY3RgIGZvciBhIGBQcm9taXNlYFxuICAgKlxuICAgKiBAcmV0dXJuIHtOdW1iZXJ9IEFuIElEIHVzZWQgdG8gcmVtb3ZlIGludGVyY2VwdG9yIGxhdGVyXG4gICAqL1xuICB1c2UoZnVsZmlsbGVkLCByZWplY3RlZCwgb3B0aW9ucykge1xuICAgIHRoaXMuaGFuZGxlcnMucHVzaCh7XG4gICAgICBmdWxmaWxsZWQsXG4gICAgICByZWplY3RlZCxcbiAgICAgIHN5bmNocm9ub3VzOiBvcHRpb25zID8gb3B0aW9ucy5zeW5jaHJvbm91cyA6IGZhbHNlLFxuICAgICAgcnVuV2hlbjogb3B0aW9ucyA/IG9wdGlvbnMucnVuV2hlbiA6IG51bGxcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcy5oYW5kbGVycy5sZW5ndGggLSAxO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBhbiBpbnRlcmNlcHRvciBmcm9tIHRoZSBzdGFja1xuICAgKlxuICAgKiBAcGFyYW0ge051bWJlcn0gaWQgVGhlIElEIHRoYXQgd2FzIHJldHVybmVkIGJ5IGB1c2VgXG4gICAqXG4gICAqIEByZXR1cm5zIHtCb29sZWFufSBgdHJ1ZWAgaWYgdGhlIGludGVyY2VwdG9yIHdhcyByZW1vdmVkLCBgZmFsc2VgIG90aGVyd2lzZVxuICAgKi9cbiAgZWplY3QoaWQpIHtcbiAgICBpZiAodGhpcy5oYW5kbGVyc1tpZF0pIHtcbiAgICAgIHRoaXMuaGFuZGxlcnNbaWRdID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXIgYWxsIGludGVyY2VwdG9ycyBmcm9tIHRoZSBzdGFja1xuICAgKlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGNsZWFyKCkge1xuICAgIGlmICh0aGlzLmhhbmRsZXJzKSB7XG4gICAgICB0aGlzLmhhbmRsZXJzID0gW107XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEl0ZXJhdGUgb3ZlciBhbGwgdGhlIHJlZ2lzdGVyZWQgaW50ZXJjZXB0b3JzXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGlzIHBhcnRpY3VsYXJseSB1c2VmdWwgZm9yIHNraXBwaW5nIG92ZXIgYW55XG4gICAqIGludGVyY2VwdG9ycyB0aGF0IG1heSBoYXZlIGJlY29tZSBgbnVsbGAgY2FsbGluZyBgZWplY3RgLlxuICAgKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gY2FsbCBmb3IgZWFjaCBpbnRlcmNlcHRvclxuICAgKlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGZvckVhY2goZm4pIHtcbiAgICB1dGlscy5mb3JFYWNoKHRoaXMuaGFuZGxlcnMsIGZ1bmN0aW9uIGZvckVhY2hIYW5kbGVyKGgpIHtcbiAgICAgIGlmIChoICE9PSBudWxsKSB7XG4gICAgICAgIGZuKGgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59XG5cbmNvbnN0IEludGVyY2VwdG9yTWFuYWdlciQxID0gSW50ZXJjZXB0b3JNYW5hZ2VyO1xuXG5jb25zdCB0cmFuc2l0aW9uYWxEZWZhdWx0cyA9IHtcbiAgc2lsZW50SlNPTlBhcnNpbmc6IHRydWUsXG4gIGZvcmNlZEpTT05QYXJzaW5nOiB0cnVlLFxuICBjbGFyaWZ5VGltZW91dEVycm9yOiBmYWxzZVxufTtcblxuY29uc3QgVVJMU2VhcmNoUGFyYW1zID0gdXJsX19kZWZhdWx0W1wiZGVmYXVsdFwiXS5VUkxTZWFyY2hQYXJhbXM7XG5cbmNvbnN0IHBsYXRmb3JtID0ge1xuICBpc05vZGU6IHRydWUsXG4gIGNsYXNzZXM6IHtcbiAgICBVUkxTZWFyY2hQYXJhbXMsXG4gICAgRm9ybURhdGE6IEZvcm1EYXRhX19kZWZhdWx0W1wiZGVmYXVsdFwiXSxcbiAgICBCbG9iOiB0eXBlb2YgQmxvYiAhPT0gJ3VuZGVmaW5lZCcgJiYgQmxvYiB8fCBudWxsXG4gIH0sXG4gIHByb3RvY29sczogWyAnaHR0cCcsICdodHRwcycsICdmaWxlJywgJ2RhdGEnIF1cbn07XG5cbmZ1bmN0aW9uIHRvVVJMRW5jb2RlZEZvcm0oZGF0YSwgb3B0aW9ucykge1xuICByZXR1cm4gdG9Gb3JtRGF0YShkYXRhLCBuZXcgcGxhdGZvcm0uY2xhc3Nlcy5VUkxTZWFyY2hQYXJhbXMoKSwgT2JqZWN0LmFzc2lnbih7XG4gICAgdmlzaXRvcjogZnVuY3Rpb24odmFsdWUsIGtleSwgcGF0aCwgaGVscGVycykge1xuICAgICAgaWYgKHV0aWxzLmlzQnVmZmVyKHZhbHVlKSkge1xuICAgICAgICB0aGlzLmFwcGVuZChrZXksIHZhbHVlLnRvU3RyaW5nKCdiYXNlNjQnKSk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGhlbHBlcnMuZGVmYXVsdFZpc2l0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH0sIG9wdGlvbnMpKTtcbn1cblxuLyoqXG4gKiBJdCB0YWtlcyBhIHN0cmluZyBsaWtlIGBmb29beF1beV1bel1gIGFuZCByZXR1cm5zIGFuIGFycmF5IGxpa2UgYFsnZm9vJywgJ3gnLCAneScsICd6J11cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKlxuICogQHJldHVybnMgQW4gYXJyYXkgb2Ygc3RyaW5ncy5cbiAqL1xuZnVuY3Rpb24gcGFyc2VQcm9wUGF0aChuYW1lKSB7XG4gIC8vIGZvb1t4XVt5XVt6XVxuICAvLyBmb28ueC55LnpcbiAgLy8gZm9vLXgteS16XG4gIC8vIGZvbyB4IHkgelxuICByZXR1cm4gdXRpbHMubWF0Y2hBbGwoL1xcdyt8XFxbKFxcdyopXS9nLCBuYW1lKS5tYXAobWF0Y2ggPT4ge1xuICAgIHJldHVybiBtYXRjaFswXSA9PT0gJ1tdJyA/ICcnIDogbWF0Y2hbMV0gfHwgbWF0Y2hbMF07XG4gIH0pO1xufVxuXG4vKipcbiAqIENvbnZlcnQgYW4gYXJyYXkgdG8gYW4gb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8YW55Pn0gYXJyIC0gVGhlIGFycmF5IHRvIGNvbnZlcnQgdG8gYW4gb2JqZWN0LlxuICpcbiAqIEByZXR1cm5zIEFuIG9iamVjdCB3aXRoIHRoZSBzYW1lIGtleXMgYW5kIHZhbHVlcyBhcyB0aGUgYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIGFycmF5VG9PYmplY3QoYXJyKSB7XG4gIGNvbnN0IG9iaiA9IHt9O1xuICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoYXJyKTtcbiAgbGV0IGk7XG4gIGNvbnN0IGxlbiA9IGtleXMubGVuZ3RoO1xuICBsZXQga2V5O1xuICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICBrZXkgPSBrZXlzW2ldO1xuICAgIG9ialtrZXldID0gYXJyW2tleV07XG4gIH1cbiAgcmV0dXJuIG9iajtcbn1cblxuLyoqXG4gKiBJdCB0YWtlcyBhIEZvcm1EYXRhIG9iamVjdCBhbmQgcmV0dXJucyBhIEphdmFTY3JpcHQgb2JqZWN0XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGZvcm1EYXRhIFRoZSBGb3JtRGF0YSBvYmplY3QgdG8gY29udmVydCB0byBKU09OLlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3Q8c3RyaW5nLCBhbnk+IHwgbnVsbH0gVGhlIGNvbnZlcnRlZCBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGZvcm1EYXRhVG9KU09OKGZvcm1EYXRhKSB7XG4gIGZ1bmN0aW9uIGJ1aWxkUGF0aChwYXRoLCB2YWx1ZSwgdGFyZ2V0LCBpbmRleCkge1xuICAgIGxldCBuYW1lID0gcGF0aFtpbmRleCsrXTtcbiAgICBjb25zdCBpc051bWVyaWNLZXkgPSBOdW1iZXIuaXNGaW5pdGUoK25hbWUpO1xuICAgIGNvbnN0IGlzTGFzdCA9IGluZGV4ID49IHBhdGgubGVuZ3RoO1xuICAgIG5hbWUgPSAhbmFtZSAmJiB1dGlscy5pc0FycmF5KHRhcmdldCkgPyB0YXJnZXQubGVuZ3RoIDogbmFtZTtcblxuICAgIGlmIChpc0xhc3QpIHtcbiAgICAgIGlmICh1dGlscy5oYXNPd25Qcm9wKHRhcmdldCwgbmFtZSkpIHtcbiAgICAgICAgdGFyZ2V0W25hbWVdID0gW3RhcmdldFtuYW1lXSwgdmFsdWVdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGFyZ2V0W25hbWVdID0gdmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiAhaXNOdW1lcmljS2V5O1xuICAgIH1cblxuICAgIGlmICghdGFyZ2V0W25hbWVdIHx8ICF1dGlscy5pc09iamVjdCh0YXJnZXRbbmFtZV0pKSB7XG4gICAgICB0YXJnZXRbbmFtZV0gPSBbXTtcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBidWlsZFBhdGgocGF0aCwgdmFsdWUsIHRhcmdldFtuYW1lXSwgaW5kZXgpO1xuXG4gICAgaWYgKHJlc3VsdCAmJiB1dGlscy5pc0FycmF5KHRhcmdldFtuYW1lXSkpIHtcbiAgICAgIHRhcmdldFtuYW1lXSA9IGFycmF5VG9PYmplY3QodGFyZ2V0W25hbWVdKTtcbiAgICB9XG5cbiAgICByZXR1cm4gIWlzTnVtZXJpY0tleTtcbiAgfVxuXG4gIGlmICh1dGlscy5pc0Zvcm1EYXRhKGZvcm1EYXRhKSAmJiB1dGlscy5pc0Z1bmN0aW9uKGZvcm1EYXRhLmVudHJpZXMpKSB7XG4gICAgY29uc3Qgb2JqID0ge307XG5cbiAgICB1dGlscy5mb3JFYWNoRW50cnkoZm9ybURhdGEsIChuYW1lLCB2YWx1ZSkgPT4ge1xuICAgICAgYnVpbGRQYXRoKHBhcnNlUHJvcFBhdGgobmFtZSksIHZhbHVlLCBvYmosIDApO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIG9iajtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIEl0IHRha2VzIGEgc3RyaW5nLCB0cmllcyB0byBwYXJzZSBpdCwgYW5kIGlmIGl0IGZhaWxzLCBpdCByZXR1cm5zIHRoZSBzdHJpbmdpZmllZCB2ZXJzaW9uXG4gKiBvZiB0aGUgaW5wdXRcbiAqXG4gKiBAcGFyYW0ge2FueX0gcmF3VmFsdWUgLSBUaGUgdmFsdWUgdG8gYmUgc3RyaW5naWZpZWQuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwYXJzZXIgLSBBIGZ1bmN0aW9uIHRoYXQgcGFyc2VzIGEgc3RyaW5nIGludG8gYSBKYXZhU2NyaXB0IG9iamVjdC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVuY29kZXIgLSBBIGZ1bmN0aW9uIHRoYXQgdGFrZXMgYSB2YWx1ZSBhbmQgcmV0dXJucyBhIHN0cmluZy5cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBBIHN0cmluZ2lmaWVkIHZlcnNpb24gb2YgdGhlIHJhd1ZhbHVlLlxuICovXG5mdW5jdGlvbiBzdHJpbmdpZnlTYWZlbHkocmF3VmFsdWUsIHBhcnNlciwgZW5jb2Rlcikge1xuICBpZiAodXRpbHMuaXNTdHJpbmcocmF3VmFsdWUpKSB7XG4gICAgdHJ5IHtcbiAgICAgIChwYXJzZXIgfHwgSlNPTi5wYXJzZSkocmF3VmFsdWUpO1xuICAgICAgcmV0dXJuIHV0aWxzLnRyaW0ocmF3VmFsdWUpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChlLm5hbWUgIT09ICdTeW50YXhFcnJvcicpIHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gKGVuY29kZXIgfHwgSlNPTi5zdHJpbmdpZnkpKHJhd1ZhbHVlKTtcbn1cblxuY29uc3QgZGVmYXVsdHMgPSB7XG5cbiAgdHJhbnNpdGlvbmFsOiB0cmFuc2l0aW9uYWxEZWZhdWx0cyxcblxuICBhZGFwdGVyOiBbJ3hocicsICdodHRwJ10sXG5cbiAgdHJhbnNmb3JtUmVxdWVzdDogW2Z1bmN0aW9uIHRyYW5zZm9ybVJlcXVlc3QoZGF0YSwgaGVhZGVycykge1xuICAgIGNvbnN0IGNvbnRlbnRUeXBlID0gaGVhZGVycy5nZXRDb250ZW50VHlwZSgpIHx8ICcnO1xuICAgIGNvbnN0IGhhc0pTT05Db250ZW50VHlwZSA9IGNvbnRlbnRUeXBlLmluZGV4T2YoJ2FwcGxpY2F0aW9uL2pzb24nKSA+IC0xO1xuICAgIGNvbnN0IGlzT2JqZWN0UGF5bG9hZCA9IHV0aWxzLmlzT2JqZWN0KGRhdGEpO1xuXG4gICAgaWYgKGlzT2JqZWN0UGF5bG9hZCAmJiB1dGlscy5pc0hUTUxGb3JtKGRhdGEpKSB7XG4gICAgICBkYXRhID0gbmV3IEZvcm1EYXRhKGRhdGEpO1xuICAgIH1cblxuICAgIGNvbnN0IGlzRm9ybURhdGEgPSB1dGlscy5pc0Zvcm1EYXRhKGRhdGEpO1xuXG4gICAgaWYgKGlzRm9ybURhdGEpIHtcbiAgICAgIGlmICghaGFzSlNPTkNvbnRlbnRUeXBlKSB7XG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhc0pTT05Db250ZW50VHlwZSA/IEpTT04uc3RyaW5naWZ5KGZvcm1EYXRhVG9KU09OKGRhdGEpKSA6IGRhdGE7XG4gICAgfVxuXG4gICAgaWYgKHV0aWxzLmlzQXJyYXlCdWZmZXIoZGF0YSkgfHxcbiAgICAgIHV0aWxzLmlzQnVmZmVyKGRhdGEpIHx8XG4gICAgICB1dGlscy5pc1N0cmVhbShkYXRhKSB8fFxuICAgICAgdXRpbHMuaXNGaWxlKGRhdGEpIHx8XG4gICAgICB1dGlscy5pc0Jsb2IoZGF0YSlcbiAgICApIHtcbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbiAgICBpZiAodXRpbHMuaXNBcnJheUJ1ZmZlclZpZXcoZGF0YSkpIHtcbiAgICAgIHJldHVybiBkYXRhLmJ1ZmZlcjtcbiAgICB9XG4gICAgaWYgKHV0aWxzLmlzVVJMU2VhcmNoUGFyYW1zKGRhdGEpKSB7XG4gICAgICBoZWFkZXJzLnNldENvbnRlbnRUeXBlKCdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQ7Y2hhcnNldD11dGYtOCcsIGZhbHNlKTtcbiAgICAgIHJldHVybiBkYXRhLnRvU3RyaW5nKCk7XG4gICAgfVxuXG4gICAgbGV0IGlzRmlsZUxpc3Q7XG5cbiAgICBpZiAoaXNPYmplY3RQYXlsb2FkKSB7XG4gICAgICBpZiAoY29udGVudFR5cGUuaW5kZXhPZignYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJykgPiAtMSkge1xuICAgICAgICByZXR1cm4gdG9VUkxFbmNvZGVkRm9ybShkYXRhLCB0aGlzLmZvcm1TZXJpYWxpemVyKS50b1N0cmluZygpO1xuICAgICAgfVxuXG4gICAgICBpZiAoKGlzRmlsZUxpc3QgPSB1dGlscy5pc0ZpbGVMaXN0KGRhdGEpKSB8fCBjb250ZW50VHlwZS5pbmRleE9mKCdtdWx0aXBhcnQvZm9ybS1kYXRhJykgPiAtMSkge1xuICAgICAgICBjb25zdCBfRm9ybURhdGEgPSB0aGlzLmVudiAmJiB0aGlzLmVudi5Gb3JtRGF0YTtcblxuICAgICAgICByZXR1cm4gdG9Gb3JtRGF0YShcbiAgICAgICAgICBpc0ZpbGVMaXN0ID8geydmaWxlc1tdJzogZGF0YX0gOiBkYXRhLFxuICAgICAgICAgIF9Gb3JtRGF0YSAmJiBuZXcgX0Zvcm1EYXRhKCksXG4gICAgICAgICAgdGhpcy5mb3JtU2VyaWFsaXplclxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpc09iamVjdFBheWxvYWQgfHwgaGFzSlNPTkNvbnRlbnRUeXBlICkge1xuICAgICAgaGVhZGVycy5zZXRDb250ZW50VHlwZSgnYXBwbGljYXRpb24vanNvbicsIGZhbHNlKTtcbiAgICAgIHJldHVybiBzdHJpbmdpZnlTYWZlbHkoZGF0YSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRhdGE7XG4gIH1dLFxuXG4gIHRyYW5zZm9ybVJlc3BvbnNlOiBbZnVuY3Rpb24gdHJhbnNmb3JtUmVzcG9uc2UoZGF0YSkge1xuICAgIGNvbnN0IHRyYW5zaXRpb25hbCA9IHRoaXMudHJhbnNpdGlvbmFsIHx8IGRlZmF1bHRzLnRyYW5zaXRpb25hbDtcbiAgICBjb25zdCBmb3JjZWRKU09OUGFyc2luZyA9IHRyYW5zaXRpb25hbCAmJiB0cmFuc2l0aW9uYWwuZm9yY2VkSlNPTlBhcnNpbmc7XG4gICAgY29uc3QgSlNPTlJlcXVlc3RlZCA9IHRoaXMucmVzcG9uc2VUeXBlID09PSAnanNvbic7XG5cbiAgICBpZiAoZGF0YSAmJiB1dGlscy5pc1N0cmluZyhkYXRhKSAmJiAoKGZvcmNlZEpTT05QYXJzaW5nICYmICF0aGlzLnJlc3BvbnNlVHlwZSkgfHwgSlNPTlJlcXVlc3RlZCkpIHtcbiAgICAgIGNvbnN0IHNpbGVudEpTT05QYXJzaW5nID0gdHJhbnNpdGlvbmFsICYmIHRyYW5zaXRpb25hbC5zaWxlbnRKU09OUGFyc2luZztcbiAgICAgIGNvbnN0IHN0cmljdEpTT05QYXJzaW5nID0gIXNpbGVudEpTT05QYXJzaW5nICYmIEpTT05SZXF1ZXN0ZWQ7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBKU09OLnBhcnNlKGRhdGEpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoc3RyaWN0SlNPTlBhcnNpbmcpIHtcbiAgICAgICAgICBpZiAoZS5uYW1lID09PSAnU3ludGF4RXJyb3InKSB7XG4gICAgICAgICAgICB0aHJvdyBBeGlvc0Vycm9yLmZyb20oZSwgQXhpb3NFcnJvci5FUlJfQkFEX1JFU1BPTlNFLCB0aGlzLCBudWxsLCB0aGlzLnJlc3BvbnNlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBkYXRhO1xuICB9XSxcblxuICAvKipcbiAgICogQSB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyB0byBhYm9ydCBhIHJlcXVlc3QuIElmIHNldCB0byAwIChkZWZhdWx0KSBhXG4gICAqIHRpbWVvdXQgaXMgbm90IGNyZWF0ZWQuXG4gICAqL1xuICB0aW1lb3V0OiAwLFxuXG4gIHhzcmZDb29raWVOYW1lOiAnWFNSRi1UT0tFTicsXG4gIHhzcmZIZWFkZXJOYW1lOiAnWC1YU1JGLVRPS0VOJyxcblxuICBtYXhDb250ZW50TGVuZ3RoOiAtMSxcbiAgbWF4Qm9keUxlbmd0aDogLTEsXG5cbiAgZW52OiB7XG4gICAgRm9ybURhdGE6IHBsYXRmb3JtLmNsYXNzZXMuRm9ybURhdGEsXG4gICAgQmxvYjogcGxhdGZvcm0uY2xhc3Nlcy5CbG9iXG4gIH0sXG5cbiAgdmFsaWRhdGVTdGF0dXM6IGZ1bmN0aW9uIHZhbGlkYXRlU3RhdHVzKHN0YXR1cykge1xuICAgIHJldHVybiBzdGF0dXMgPj0gMjAwICYmIHN0YXR1cyA8IDMwMDtcbiAgfSxcblxuICBoZWFkZXJzOiB7XG4gICAgY29tbW9uOiB7XG4gICAgICAnQWNjZXB0JzogJ2FwcGxpY2F0aW9uL2pzb24sIHRleHQvcGxhaW4sICovKicsXG4gICAgICAnQ29udGVudC1UeXBlJzogdW5kZWZpbmVkXG4gICAgfVxuICB9XG59O1xuXG51dGlscy5mb3JFYWNoKFsnZGVsZXRlJywgJ2dldCcsICdoZWFkJywgJ3Bvc3QnLCAncHV0JywgJ3BhdGNoJ10sIChtZXRob2QpID0+IHtcbiAgZGVmYXVsdHMuaGVhZGVyc1ttZXRob2RdID0ge307XG59KTtcblxuY29uc3QgZGVmYXVsdHMkMSA9IGRlZmF1bHRzO1xuXG4vLyBSYXdBeGlvc0hlYWRlcnMgd2hvc2UgZHVwbGljYXRlcyBhcmUgaWdub3JlZCBieSBub2RlXG4vLyBjLmYuIGh0dHBzOi8vbm9kZWpzLm9yZy9hcGkvaHR0cC5odG1sI2h0dHBfbWVzc2FnZV9oZWFkZXJzXG5jb25zdCBpZ25vcmVEdXBsaWNhdGVPZiA9IHV0aWxzLnRvT2JqZWN0U2V0KFtcbiAgJ2FnZScsICdhdXRob3JpemF0aW9uJywgJ2NvbnRlbnQtbGVuZ3RoJywgJ2NvbnRlbnQtdHlwZScsICdldGFnJyxcbiAgJ2V4cGlyZXMnLCAnZnJvbScsICdob3N0JywgJ2lmLW1vZGlmaWVkLXNpbmNlJywgJ2lmLXVubW9kaWZpZWQtc2luY2UnLFxuICAnbGFzdC1tb2RpZmllZCcsICdsb2NhdGlvbicsICdtYXgtZm9yd2FyZHMnLCAncHJveHktYXV0aG9yaXphdGlvbicsXG4gICdyZWZlcmVyJywgJ3JldHJ5LWFmdGVyJywgJ3VzZXItYWdlbnQnXG5dKTtcblxuLyoqXG4gKiBQYXJzZSBoZWFkZXJzIGludG8gYW4gb2JqZWN0XG4gKlxuICogYGBgXG4gKiBEYXRlOiBXZWQsIDI3IEF1ZyAyMDE0IDA4OjU4OjQ5IEdNVFxuICogQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9qc29uXG4gKiBDb25uZWN0aW9uOiBrZWVwLWFsaXZlXG4gKiBUcmFuc2Zlci1FbmNvZGluZzogY2h1bmtlZFxuICogYGBgXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHJhd0hlYWRlcnMgSGVhZGVycyBuZWVkaW5nIHRvIGJlIHBhcnNlZFxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IEhlYWRlcnMgcGFyc2VkIGludG8gYW4gb2JqZWN0XG4gKi9cbmNvbnN0IHBhcnNlSGVhZGVycyA9IHJhd0hlYWRlcnMgPT4ge1xuICBjb25zdCBwYXJzZWQgPSB7fTtcbiAgbGV0IGtleTtcbiAgbGV0IHZhbDtcbiAgbGV0IGk7XG5cbiAgcmF3SGVhZGVycyAmJiByYXdIZWFkZXJzLnNwbGl0KCdcXG4nKS5mb3JFYWNoKGZ1bmN0aW9uIHBhcnNlcihsaW5lKSB7XG4gICAgaSA9IGxpbmUuaW5kZXhPZignOicpO1xuICAgIGtleSA9IGxpbmUuc3Vic3RyaW5nKDAsIGkpLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgIHZhbCA9IGxpbmUuc3Vic3RyaW5nKGkgKyAxKS50cmltKCk7XG5cbiAgICBpZiAoIWtleSB8fCAocGFyc2VkW2tleV0gJiYgaWdub3JlRHVwbGljYXRlT2Zba2V5XSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoa2V5ID09PSAnc2V0LWNvb2tpZScpIHtcbiAgICAgIGlmIChwYXJzZWRba2V5XSkge1xuICAgICAgICBwYXJzZWRba2V5XS5wdXNoKHZhbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYXJzZWRba2V5XSA9IFt2YWxdO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBwYXJzZWRba2V5XSA9IHBhcnNlZFtrZXldID8gcGFyc2VkW2tleV0gKyAnLCAnICsgdmFsIDogdmFsO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHBhcnNlZDtcbn07XG5cbmNvbnN0ICRpbnRlcm5hbHMgPSBTeW1ib2woJ2ludGVybmFscycpO1xuXG5mdW5jdGlvbiBub3JtYWxpemVIZWFkZXIoaGVhZGVyKSB7XG4gIHJldHVybiBoZWFkZXIgJiYgU3RyaW5nKGhlYWRlcikudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVZhbHVlKHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PT0gZmFsc2UgfHwgdmFsdWUgPT0gbnVsbCkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIHJldHVybiB1dGlscy5pc0FycmF5KHZhbHVlKSA/IHZhbHVlLm1hcChub3JtYWxpemVWYWx1ZSkgOiBTdHJpbmcodmFsdWUpO1xufVxuXG5mdW5jdGlvbiBwYXJzZVRva2VucyhzdHIpIHtcbiAgY29uc3QgdG9rZW5zID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgY29uc3QgdG9rZW5zUkUgPSAvKFteXFxzLDs9XSspXFxzKig/Oj1cXHMqKFteLDtdKykpPy9nO1xuICBsZXQgbWF0Y2g7XG5cbiAgd2hpbGUgKChtYXRjaCA9IHRva2Vuc1JFLmV4ZWMoc3RyKSkpIHtcbiAgICB0b2tlbnNbbWF0Y2hbMV1dID0gbWF0Y2hbMl07XG4gIH1cblxuICByZXR1cm4gdG9rZW5zO1xufVxuXG5jb25zdCBpc1ZhbGlkSGVhZGVyTmFtZSA9IChzdHIpID0+IC9eWy1fYS16QS1aMC05XmB8fiwhIyQlJicqKy5dKyQvLnRlc3Qoc3RyLnRyaW0oKSk7XG5cbmZ1bmN0aW9uIG1hdGNoSGVhZGVyVmFsdWUoY29udGV4dCwgdmFsdWUsIGhlYWRlciwgZmlsdGVyLCBpc0hlYWRlck5hbWVGaWx0ZXIpIHtcbiAgaWYgKHV0aWxzLmlzRnVuY3Rpb24oZmlsdGVyKSkge1xuICAgIHJldHVybiBmaWx0ZXIuY2FsbCh0aGlzLCB2YWx1ZSwgaGVhZGVyKTtcbiAgfVxuXG4gIGlmIChpc0hlYWRlck5hbWVGaWx0ZXIpIHtcbiAgICB2YWx1ZSA9IGhlYWRlcjtcbiAgfVxuXG4gIGlmICghdXRpbHMuaXNTdHJpbmcodmFsdWUpKSByZXR1cm47XG5cbiAgaWYgKHV0aWxzLmlzU3RyaW5nKGZpbHRlcikpIHtcbiAgICByZXR1cm4gdmFsdWUuaW5kZXhPZihmaWx0ZXIpICE9PSAtMTtcbiAgfVxuXG4gIGlmICh1dGlscy5pc1JlZ0V4cChmaWx0ZXIpKSB7XG4gICAgcmV0dXJuIGZpbHRlci50ZXN0KHZhbHVlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBmb3JtYXRIZWFkZXIoaGVhZGVyKSB7XG4gIHJldHVybiBoZWFkZXIudHJpbSgpXG4gICAgLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvKFthLXpcXGRdKShcXHcqKS9nLCAodywgY2hhciwgc3RyKSA9PiB7XG4gICAgICByZXR1cm4gY2hhci50b1VwcGVyQ2FzZSgpICsgc3RyO1xuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBidWlsZEFjY2Vzc29ycyhvYmosIGhlYWRlcikge1xuICBjb25zdCBhY2Nlc3Nvck5hbWUgPSB1dGlscy50b0NhbWVsQ2FzZSgnICcgKyBoZWFkZXIpO1xuXG4gIFsnZ2V0JywgJ3NldCcsICdoYXMnXS5mb3JFYWNoKG1ldGhvZE5hbWUgPT4ge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIG1ldGhvZE5hbWUgKyBhY2Nlc3Nvck5hbWUsIHtcbiAgICAgIHZhbHVlOiBmdW5jdGlvbihhcmcxLCBhcmcyLCBhcmczKSB7XG4gICAgICAgIHJldHVybiB0aGlzW21ldGhvZE5hbWVdLmNhbGwodGhpcywgaGVhZGVyLCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgICAgIH0sXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbiAgfSk7XG59XG5cbmNsYXNzIEF4aW9zSGVhZGVycyB7XG4gIGNvbnN0cnVjdG9yKGhlYWRlcnMpIHtcbiAgICBoZWFkZXJzICYmIHRoaXMuc2V0KGhlYWRlcnMpO1xuICB9XG5cbiAgc2V0KGhlYWRlciwgdmFsdWVPclJld3JpdGUsIHJld3JpdGUpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGZ1bmN0aW9uIHNldEhlYWRlcihfdmFsdWUsIF9oZWFkZXIsIF9yZXdyaXRlKSB7XG4gICAgICBjb25zdCBsSGVhZGVyID0gbm9ybWFsaXplSGVhZGVyKF9oZWFkZXIpO1xuXG4gICAgICBpZiAoIWxIZWFkZXIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdoZWFkZXIgbmFtZSBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBrZXkgPSB1dGlscy5maW5kS2V5KHNlbGYsIGxIZWFkZXIpO1xuXG4gICAgICBpZigha2V5IHx8IHNlbGZba2V5XSA9PT0gdW5kZWZpbmVkIHx8IF9yZXdyaXRlID09PSB0cnVlIHx8IChfcmV3cml0ZSA9PT0gdW5kZWZpbmVkICYmIHNlbGZba2V5XSAhPT0gZmFsc2UpKSB7XG4gICAgICAgIHNlbGZba2V5IHx8IF9oZWFkZXJdID0gbm9ybWFsaXplVmFsdWUoX3ZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzZXRIZWFkZXJzID0gKGhlYWRlcnMsIF9yZXdyaXRlKSA9PlxuICAgICAgdXRpbHMuZm9yRWFjaChoZWFkZXJzLCAoX3ZhbHVlLCBfaGVhZGVyKSA9PiBzZXRIZWFkZXIoX3ZhbHVlLCBfaGVhZGVyLCBfcmV3cml0ZSkpO1xuXG4gICAgaWYgKHV0aWxzLmlzUGxhaW5PYmplY3QoaGVhZGVyKSB8fCBoZWFkZXIgaW5zdGFuY2VvZiB0aGlzLmNvbnN0cnVjdG9yKSB7XG4gICAgICBzZXRIZWFkZXJzKGhlYWRlciwgdmFsdWVPclJld3JpdGUpO1xuICAgIH0gZWxzZSBpZih1dGlscy5pc1N0cmluZyhoZWFkZXIpICYmIChoZWFkZXIgPSBoZWFkZXIudHJpbSgpKSAmJiAhaXNWYWxpZEhlYWRlck5hbWUoaGVhZGVyKSkge1xuICAgICAgc2V0SGVhZGVycyhwYXJzZUhlYWRlcnMoaGVhZGVyKSwgdmFsdWVPclJld3JpdGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBoZWFkZXIgIT0gbnVsbCAmJiBzZXRIZWFkZXIodmFsdWVPclJld3JpdGUsIGhlYWRlciwgcmV3cml0ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBnZXQoaGVhZGVyLCBwYXJzZXIpIHtcbiAgICBoZWFkZXIgPSBub3JtYWxpemVIZWFkZXIoaGVhZGVyKTtcblxuICAgIGlmIChoZWFkZXIpIHtcbiAgICAgIGNvbnN0IGtleSA9IHV0aWxzLmZpbmRLZXkodGhpcywgaGVhZGVyKTtcblxuICAgICAgaWYgKGtleSkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXNba2V5XTtcblxuICAgICAgICBpZiAoIXBhcnNlcikge1xuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJzZXIgPT09IHRydWUpIHtcbiAgICAgICAgICByZXR1cm4gcGFyc2VUb2tlbnModmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHV0aWxzLmlzRnVuY3Rpb24ocGFyc2VyKSkge1xuICAgICAgICAgIHJldHVybiBwYXJzZXIuY2FsbCh0aGlzLCB2YWx1ZSwga2V5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh1dGlscy5pc1JlZ0V4cChwYXJzZXIpKSB7XG4gICAgICAgICAgcmV0dXJuIHBhcnNlci5leGVjKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3BhcnNlciBtdXN0IGJlIGJvb2xlYW58cmVnZXhwfGZ1bmN0aW9uJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaGFzKGhlYWRlciwgbWF0Y2hlcikge1xuICAgIGhlYWRlciA9IG5vcm1hbGl6ZUhlYWRlcihoZWFkZXIpO1xuXG4gICAgaWYgKGhlYWRlcikge1xuICAgICAgY29uc3Qga2V5ID0gdXRpbHMuZmluZEtleSh0aGlzLCBoZWFkZXIpO1xuXG4gICAgICByZXR1cm4gISEoa2V5ICYmIHRoaXNba2V5XSAhPT0gdW5kZWZpbmVkICYmICghbWF0Y2hlciB8fCBtYXRjaEhlYWRlclZhbHVlKHRoaXMsIHRoaXNba2V5XSwga2V5LCBtYXRjaGVyKSkpO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGRlbGV0ZShoZWFkZXIsIG1hdGNoZXIpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBsZXQgZGVsZXRlZCA9IGZhbHNlO1xuXG4gICAgZnVuY3Rpb24gZGVsZXRlSGVhZGVyKF9oZWFkZXIpIHtcbiAgICAgIF9oZWFkZXIgPSBub3JtYWxpemVIZWFkZXIoX2hlYWRlcik7XG5cbiAgICAgIGlmIChfaGVhZGVyKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IHV0aWxzLmZpbmRLZXkoc2VsZiwgX2hlYWRlcik7XG5cbiAgICAgICAgaWYgKGtleSAmJiAoIW1hdGNoZXIgfHwgbWF0Y2hIZWFkZXJWYWx1ZShzZWxmLCBzZWxmW2tleV0sIGtleSwgbWF0Y2hlcikpKSB7XG4gICAgICAgICAgZGVsZXRlIHNlbGZba2V5XTtcblxuICAgICAgICAgIGRlbGV0ZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHV0aWxzLmlzQXJyYXkoaGVhZGVyKSkge1xuICAgICAgaGVhZGVyLmZvckVhY2goZGVsZXRlSGVhZGVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVsZXRlSGVhZGVyKGhlYWRlcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRlbGV0ZWQ7XG4gIH1cblxuICBjbGVhcihtYXRjaGVyKSB7XG4gICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHRoaXMpO1xuICAgIGxldCBpID0ga2V5cy5sZW5ndGg7XG4gICAgbGV0IGRlbGV0ZWQgPSBmYWxzZTtcblxuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIGNvbnN0IGtleSA9IGtleXNbaV07XG4gICAgICBpZighbWF0Y2hlciB8fCBtYXRjaEhlYWRlclZhbHVlKHRoaXMsIHRoaXNba2V5XSwga2V5LCBtYXRjaGVyLCB0cnVlKSkge1xuICAgICAgICBkZWxldGUgdGhpc1trZXldO1xuICAgICAgICBkZWxldGVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZGVsZXRlZDtcbiAgfVxuXG4gIG5vcm1hbGl6ZShmb3JtYXQpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBjb25zdCBoZWFkZXJzID0ge307XG5cbiAgICB1dGlscy5mb3JFYWNoKHRoaXMsICh2YWx1ZSwgaGVhZGVyKSA9PiB7XG4gICAgICBjb25zdCBrZXkgPSB1dGlscy5maW5kS2V5KGhlYWRlcnMsIGhlYWRlcik7XG5cbiAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgc2VsZltrZXldID0gbm9ybWFsaXplVmFsdWUodmFsdWUpO1xuICAgICAgICBkZWxldGUgc2VsZltoZWFkZXJdO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBmb3JtYXQgPyBmb3JtYXRIZWFkZXIoaGVhZGVyKSA6IFN0cmluZyhoZWFkZXIpLnRyaW0oKTtcblxuICAgICAgaWYgKG5vcm1hbGl6ZWQgIT09IGhlYWRlcikge1xuICAgICAgICBkZWxldGUgc2VsZltoZWFkZXJdO1xuICAgICAgfVxuXG4gICAgICBzZWxmW25vcm1hbGl6ZWRdID0gbm9ybWFsaXplVmFsdWUodmFsdWUpO1xuXG4gICAgICBoZWFkZXJzW25vcm1hbGl6ZWRdID0gdHJ1ZTtcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgY29uY2F0KC4uLnRhcmdldHMpIHtcbiAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci5jb25jYXQodGhpcywgLi4udGFyZ2V0cyk7XG4gIH1cblxuICB0b0pTT04oYXNTdHJpbmdzKSB7XG4gICAgY29uc3Qgb2JqID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuICAgIHV0aWxzLmZvckVhY2godGhpcywgKHZhbHVlLCBoZWFkZXIpID0+IHtcbiAgICAgIHZhbHVlICE9IG51bGwgJiYgdmFsdWUgIT09IGZhbHNlICYmIChvYmpbaGVhZGVyXSA9IGFzU3RyaW5ncyAmJiB1dGlscy5pc0FycmF5KHZhbHVlKSA/IHZhbHVlLmpvaW4oJywgJykgOiB2YWx1ZSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gb2JqO1xuICB9XG5cbiAgW1N5bWJvbC5pdGVyYXRvcl0oKSB7XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKHRoaXMudG9KU09OKCkpW1N5bWJvbC5pdGVyYXRvcl0oKTtcbiAgfVxuXG4gIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyh0aGlzLnRvSlNPTigpKS5tYXAoKFtoZWFkZXIsIHZhbHVlXSkgPT4gaGVhZGVyICsgJzogJyArIHZhbHVlKS5qb2luKCdcXG4nKTtcbiAgfVxuXG4gIGdldCBbU3ltYm9sLnRvU3RyaW5nVGFnXSgpIHtcbiAgICByZXR1cm4gJ0F4aW9zSGVhZGVycyc7XG4gIH1cblxuICBzdGF0aWMgZnJvbSh0aGluZykge1xuICAgIHJldHVybiB0aGluZyBpbnN0YW5jZW9mIHRoaXMgPyB0aGluZyA6IG5ldyB0aGlzKHRoaW5nKTtcbiAgfVxuXG4gIHN0YXRpYyBjb25jYXQoZmlyc3QsIC4uLnRhcmdldHMpIHtcbiAgICBjb25zdCBjb21wdXRlZCA9IG5ldyB0aGlzKGZpcnN0KTtcblxuICAgIHRhcmdldHMuZm9yRWFjaCgodGFyZ2V0KSA9PiBjb21wdXRlZC5zZXQodGFyZ2V0KSk7XG5cbiAgICByZXR1cm4gY29tcHV0ZWQ7XG4gIH1cblxuICBzdGF0aWMgYWNjZXNzb3IoaGVhZGVyKSB7XG4gICAgY29uc3QgaW50ZXJuYWxzID0gdGhpc1skaW50ZXJuYWxzXSA9ICh0aGlzWyRpbnRlcm5hbHNdID0ge1xuICAgICAgYWNjZXNzb3JzOiB7fVxuICAgIH0pO1xuXG4gICAgY29uc3QgYWNjZXNzb3JzID0gaW50ZXJuYWxzLmFjY2Vzc29ycztcbiAgICBjb25zdCBwcm90b3R5cGUgPSB0aGlzLnByb3RvdHlwZTtcblxuICAgIGZ1bmN0aW9uIGRlZmluZUFjY2Vzc29yKF9oZWFkZXIpIHtcbiAgICAgIGNvbnN0IGxIZWFkZXIgPSBub3JtYWxpemVIZWFkZXIoX2hlYWRlcik7XG5cbiAgICAgIGlmICghYWNjZXNzb3JzW2xIZWFkZXJdKSB7XG4gICAgICAgIGJ1aWxkQWNjZXNzb3JzKHByb3RvdHlwZSwgX2hlYWRlcik7XG4gICAgICAgIGFjY2Vzc29yc1tsSGVhZGVyXSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdXRpbHMuaXNBcnJheShoZWFkZXIpID8gaGVhZGVyLmZvckVhY2goZGVmaW5lQWNjZXNzb3IpIDogZGVmaW5lQWNjZXNzb3IoaGVhZGVyKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG59XG5cbkF4aW9zSGVhZGVycy5hY2Nlc3NvcihbJ0NvbnRlbnQtVHlwZScsICdDb250ZW50LUxlbmd0aCcsICdBY2NlcHQnLCAnQWNjZXB0LUVuY29kaW5nJywgJ1VzZXItQWdlbnQnLCAnQXV0aG9yaXphdGlvbiddKTtcblxuLy8gcmVzZXJ2ZWQgbmFtZXMgaG90Zml4XG51dGlscy5yZWR1Y2VEZXNjcmlwdG9ycyhBeGlvc0hlYWRlcnMucHJvdG90eXBlLCAoe3ZhbHVlfSwga2V5KSA9PiB7XG4gIGxldCBtYXBwZWQgPSBrZXlbMF0udG9VcHBlckNhc2UoKSArIGtleS5zbGljZSgxKTsgLy8gbWFwIGBzZXRgID0+IGBTZXRgXG4gIHJldHVybiB7XG4gICAgZ2V0OiAoKSA9PiB2YWx1ZSxcbiAgICBzZXQoaGVhZGVyVmFsdWUpIHtcbiAgICAgIHRoaXNbbWFwcGVkXSA9IGhlYWRlclZhbHVlO1xuICAgIH1cbiAgfVxufSk7XG5cbnV0aWxzLmZyZWV6ZU1ldGhvZHMoQXhpb3NIZWFkZXJzKTtcblxuY29uc3QgQXhpb3NIZWFkZXJzJDEgPSBBeGlvc0hlYWRlcnM7XG5cbi8qKlxuICogVHJhbnNmb3JtIHRoZSBkYXRhIGZvciBhIHJlcXVlc3Qgb3IgYSByZXNwb25zZVxuICpcbiAqIEBwYXJhbSB7QXJyYXl8RnVuY3Rpb259IGZucyBBIHNpbmdsZSBmdW5jdGlvbiBvciBBcnJheSBvZiBmdW5jdGlvbnNcbiAqIEBwYXJhbSB7P09iamVjdH0gcmVzcG9uc2UgVGhlIHJlc3BvbnNlIG9iamVjdFxuICpcbiAqIEByZXR1cm5zIHsqfSBUaGUgcmVzdWx0aW5nIHRyYW5zZm9ybWVkIGRhdGFcbiAqL1xuZnVuY3Rpb24gdHJhbnNmb3JtRGF0YShmbnMsIHJlc3BvbnNlKSB7XG4gIGNvbnN0IGNvbmZpZyA9IHRoaXMgfHwgZGVmYXVsdHMkMTtcbiAgY29uc3QgY29udGV4dCA9IHJlc3BvbnNlIHx8IGNvbmZpZztcbiAgY29uc3QgaGVhZGVycyA9IEF4aW9zSGVhZGVycyQxLmZyb20oY29udGV4dC5oZWFkZXJzKTtcbiAgbGV0IGRhdGEgPSBjb250ZXh0LmRhdGE7XG5cbiAgdXRpbHMuZm9yRWFjaChmbnMsIGZ1bmN0aW9uIHRyYW5zZm9ybShmbikge1xuICAgIGRhdGEgPSBmbi5jYWxsKGNvbmZpZywgZGF0YSwgaGVhZGVycy5ub3JtYWxpemUoKSwgcmVzcG9uc2UgPyByZXNwb25zZS5zdGF0dXMgOiB1bmRlZmluZWQpO1xuICB9KTtcblxuICBoZWFkZXJzLm5vcm1hbGl6ZSgpO1xuXG4gIHJldHVybiBkYXRhO1xufVxuXG5mdW5jdGlvbiBpc0NhbmNlbCh2YWx1ZSkge1xuICByZXR1cm4gISEodmFsdWUgJiYgdmFsdWUuX19DQU5DRUxfXyk7XG59XG5cbi8qKlxuICogQSBgQ2FuY2VsZWRFcnJvcmAgaXMgYW4gb2JqZWN0IHRoYXQgaXMgdGhyb3duIHdoZW4gYW4gb3BlcmF0aW9uIGlzIGNhbmNlbGVkLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nPX0gbWVzc2FnZSBUaGUgbWVzc2FnZS5cbiAqIEBwYXJhbSB7T2JqZWN0PX0gY29uZmlnIFRoZSBjb25maWcuXG4gKiBAcGFyYW0ge09iamVjdD19IHJlcXVlc3QgVGhlIHJlcXVlc3QuXG4gKlxuICogQHJldHVybnMge0NhbmNlbGVkRXJyb3J9IFRoZSBjcmVhdGVkIGVycm9yLlxuICovXG5mdW5jdGlvbiBDYW5jZWxlZEVycm9yKG1lc3NhZ2UsIGNvbmZpZywgcmVxdWVzdCkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZXEtbnVsbCxlcWVxZXFcbiAgQXhpb3NFcnJvci5jYWxsKHRoaXMsIG1lc3NhZ2UgPT0gbnVsbCA/ICdjYW5jZWxlZCcgOiBtZXNzYWdlLCBBeGlvc0Vycm9yLkVSUl9DQU5DRUxFRCwgY29uZmlnLCByZXF1ZXN0KTtcbiAgdGhpcy5uYW1lID0gJ0NhbmNlbGVkRXJyb3InO1xufVxuXG51dGlscy5pbmhlcml0cyhDYW5jZWxlZEVycm9yLCBBeGlvc0Vycm9yLCB7XG4gIF9fQ0FOQ0VMX186IHRydWVcbn0pO1xuXG4vKipcbiAqIFJlc29sdmUgb3IgcmVqZWN0IGEgUHJvbWlzZSBiYXNlZCBvbiByZXNwb25zZSBzdGF0dXMuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gcmVzb2x2ZSBBIGZ1bmN0aW9uIHRoYXQgcmVzb2x2ZXMgdGhlIHByb21pc2UuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSByZWplY3QgQSBmdW5jdGlvbiB0aGF0IHJlamVjdHMgdGhlIHByb21pc2UuXG4gKiBAcGFyYW0ge29iamVjdH0gcmVzcG9uc2UgVGhlIHJlc3BvbnNlLlxuICpcbiAqIEByZXR1cm5zIHtvYmplY3R9IFRoZSByZXNwb25zZS5cbiAqL1xuZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgcmVzcG9uc2UpIHtcbiAgY29uc3QgdmFsaWRhdGVTdGF0dXMgPSByZXNwb25zZS5jb25maWcudmFsaWRhdGVTdGF0dXM7XG4gIGlmICghcmVzcG9uc2Uuc3RhdHVzIHx8ICF2YWxpZGF0ZVN0YXR1cyB8fCB2YWxpZGF0ZVN0YXR1cyhyZXNwb25zZS5zdGF0dXMpKSB7XG4gICAgcmVzb2x2ZShyZXNwb25zZSk7XG4gIH0gZWxzZSB7XG4gICAgcmVqZWN0KG5ldyBBeGlvc0Vycm9yKFxuICAgICAgJ1JlcXVlc3QgZmFpbGVkIHdpdGggc3RhdHVzIGNvZGUgJyArIHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgIFtBeGlvc0Vycm9yLkVSUl9CQURfUkVRVUVTVCwgQXhpb3NFcnJvci5FUlJfQkFEX1JFU1BPTlNFXVtNYXRoLmZsb29yKHJlc3BvbnNlLnN0YXR1cyAvIDEwMCkgLSA0XSxcbiAgICAgIHJlc3BvbnNlLmNvbmZpZyxcbiAgICAgIHJlc3BvbnNlLnJlcXVlc3QsXG4gICAgICByZXNwb25zZVxuICAgICkpO1xuICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgVVJMIGlzIGFic29sdXRlXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHVybCBUaGUgVVJMIHRvIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIFVSTCBpcyBhYnNvbHV0ZSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQWJzb2x1dGVVUkwodXJsKSB7XG4gIC8vIEEgVVJMIGlzIGNvbnNpZGVyZWQgYWJzb2x1dGUgaWYgaXQgYmVnaW5zIHdpdGggXCI8c2NoZW1lPjovL1wiIG9yIFwiLy9cIiAocHJvdG9jb2wtcmVsYXRpdmUgVVJMKS5cbiAgLy8gUkZDIDM5ODYgZGVmaW5lcyBzY2hlbWUgbmFtZSBhcyBhIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgYmVnaW5uaW5nIHdpdGggYSBsZXR0ZXIgYW5kIGZvbGxvd2VkXG4gIC8vIGJ5IGFueSBjb21iaW5hdGlvbiBvZiBsZXR0ZXJzLCBkaWdpdHMsIHBsdXMsIHBlcmlvZCwgb3IgaHlwaGVuLlxuICByZXR1cm4gL14oW2Etel1bYS16XFxkK1xcLS5dKjopP1xcL1xcLy9pLnRlc3QodXJsKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IFVSTCBieSBjb21iaW5pbmcgdGhlIHNwZWNpZmllZCBVUkxzXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGJhc2VVUkwgVGhlIGJhc2UgVVJMXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVsYXRpdmVVUkwgVGhlIHJlbGF0aXZlIFVSTFxuICpcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjb21iaW5lZCBVUkxcbiAqL1xuZnVuY3Rpb24gY29tYmluZVVSTHMoYmFzZVVSTCwgcmVsYXRpdmVVUkwpIHtcbiAgcmV0dXJuIHJlbGF0aXZlVVJMXG4gICAgPyBiYXNlVVJMLnJlcGxhY2UoL1xcLyskLywgJycpICsgJy8nICsgcmVsYXRpdmVVUkwucmVwbGFjZSgvXlxcLysvLCAnJylcbiAgICA6IGJhc2VVUkw7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBVUkwgYnkgY29tYmluaW5nIHRoZSBiYXNlVVJMIHdpdGggdGhlIHJlcXVlc3RlZFVSTCxcbiAqIG9ubHkgd2hlbiB0aGUgcmVxdWVzdGVkVVJMIGlzIG5vdCBhbHJlYWR5IGFuIGFic29sdXRlIFVSTC5cbiAqIElmIHRoZSByZXF1ZXN0VVJMIGlzIGFic29sdXRlLCB0aGlzIGZ1bmN0aW9uIHJldHVybnMgdGhlIHJlcXVlc3RlZFVSTCB1bnRvdWNoZWQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGJhc2VVUkwgVGhlIGJhc2UgVVJMXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVxdWVzdGVkVVJMIEFic29sdXRlIG9yIHJlbGF0aXZlIFVSTCB0byBjb21iaW5lXG4gKlxuICogQHJldHVybnMge3N0cmluZ30gVGhlIGNvbWJpbmVkIGZ1bGwgcGF0aFxuICovXG5mdW5jdGlvbiBidWlsZEZ1bGxQYXRoKGJhc2VVUkwsIHJlcXVlc3RlZFVSTCkge1xuICBpZiAoYmFzZVVSTCAmJiAhaXNBYnNvbHV0ZVVSTChyZXF1ZXN0ZWRVUkwpKSB7XG4gICAgcmV0dXJuIGNvbWJpbmVVUkxzKGJhc2VVUkwsIHJlcXVlc3RlZFVSTCk7XG4gIH1cbiAgcmV0dXJuIHJlcXVlc3RlZFVSTDtcbn1cblxuY29uc3QgVkVSU0lPTiA9IFwiMS42LjBcIjtcblxuZnVuY3Rpb24gcGFyc2VQcm90b2NvbCh1cmwpIHtcbiAgY29uc3QgbWF0Y2ggPSAvXihbLStcXHddezEsMjV9KSg6P1xcL1xcL3w6KS8uZXhlYyh1cmwpO1xuICByZXR1cm4gbWF0Y2ggJiYgbWF0Y2hbMV0gfHwgJyc7XG59XG5cbmNvbnN0IERBVEFfVVJMX1BBVFRFUk4gPSAvXig/OihbXjtdKyk7KT8oPzpbXjtdKzspPyhiYXNlNjR8KSwoW1xcc1xcU10qKSQvO1xuXG4vKipcbiAqIFBhcnNlIGRhdGEgdXJpIHRvIGEgQnVmZmVyIG9yIEJsb2JcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJpXG4gKiBAcGFyYW0gez9Cb29sZWFufSBhc0Jsb2JcbiAqIEBwYXJhbSB7P09iamVjdH0gb3B0aW9uc1xuICogQHBhcmFtIHs/RnVuY3Rpb259IG9wdGlvbnMuQmxvYlxuICpcbiAqIEByZXR1cm5zIHtCdWZmZXJ8QmxvYn1cbiAqL1xuZnVuY3Rpb24gZnJvbURhdGFVUkkodXJpLCBhc0Jsb2IsIG9wdGlvbnMpIHtcbiAgY29uc3QgX0Jsb2IgPSBvcHRpb25zICYmIG9wdGlvbnMuQmxvYiB8fCBwbGF0Zm9ybS5jbGFzc2VzLkJsb2I7XG4gIGNvbnN0IHByb3RvY29sID0gcGFyc2VQcm90b2NvbCh1cmkpO1xuXG4gIGlmIChhc0Jsb2IgPT09IHVuZGVmaW5lZCAmJiBfQmxvYikge1xuICAgIGFzQmxvYiA9IHRydWU7XG4gIH1cblxuICBpZiAocHJvdG9jb2wgPT09ICdkYXRhJykge1xuICAgIHVyaSA9IHByb3RvY29sLmxlbmd0aCA/IHVyaS5zbGljZShwcm90b2NvbC5sZW5ndGggKyAxKSA6IHVyaTtcblxuICAgIGNvbnN0IG1hdGNoID0gREFUQV9VUkxfUEFUVEVSTi5leGVjKHVyaSk7XG5cbiAgICBpZiAoIW1hdGNoKSB7XG4gICAgICB0aHJvdyBuZXcgQXhpb3NFcnJvcignSW52YWxpZCBVUkwnLCBBeGlvc0Vycm9yLkVSUl9JTlZBTElEX1VSTCk7XG4gICAgfVxuXG4gICAgY29uc3QgbWltZSA9IG1hdGNoWzFdO1xuICAgIGNvbnN0IGlzQmFzZTY0ID0gbWF0Y2hbMl07XG4gICAgY29uc3QgYm9keSA9IG1hdGNoWzNdO1xuICAgIGNvbnN0IGJ1ZmZlciA9IEJ1ZmZlci5mcm9tKGRlY29kZVVSSUNvbXBvbmVudChib2R5KSwgaXNCYXNlNjQgPyAnYmFzZTY0JyA6ICd1dGY4Jyk7XG5cbiAgICBpZiAoYXNCbG9iKSB7XG4gICAgICBpZiAoIV9CbG9iKSB7XG4gICAgICAgIHRocm93IG5ldyBBeGlvc0Vycm9yKCdCbG9iIGlzIG5vdCBzdXBwb3J0ZWQnLCBBeGlvc0Vycm9yLkVSUl9OT1RfU1VQUE9SVCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuZXcgX0Jsb2IoW2J1ZmZlcl0sIHt0eXBlOiBtaW1lfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ1ZmZlcjtcbiAgfVxuXG4gIHRocm93IG5ldyBBeGlvc0Vycm9yKCdVbnN1cHBvcnRlZCBwcm90b2NvbCAnICsgcHJvdG9jb2wsIEF4aW9zRXJyb3IuRVJSX05PVF9TVVBQT1JUKTtcbn1cblxuLyoqXG4gKiBUaHJvdHRsZSBkZWNvcmF0b3JcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcGFyYW0ge051bWJlcn0gZnJlcVxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cbmZ1bmN0aW9uIHRocm90dGxlKGZuLCBmcmVxKSB7XG4gIGxldCB0aW1lc3RhbXAgPSAwO1xuICBjb25zdCB0aHJlc2hvbGQgPSAxMDAwIC8gZnJlcTtcbiAgbGV0IHRpbWVyID0gbnVsbDtcbiAgcmV0dXJuIGZ1bmN0aW9uIHRocm90dGxlZChmb3JjZSwgYXJncykge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgaWYgKGZvcmNlIHx8IG5vdyAtIHRpbWVzdGFtcCA+IHRocmVzaG9sZCkge1xuICAgICAgaWYgKHRpbWVyKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICAgIHRpbWVyID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIHRpbWVzdGFtcCA9IG5vdztcbiAgICAgIHJldHVybiBmbi5hcHBseShudWxsLCBhcmdzKTtcbiAgICB9XG4gICAgaWYgKCF0aW1lcikge1xuICAgICAgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGltZXIgPSBudWxsO1xuICAgICAgICB0aW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuICAgICAgICByZXR1cm4gZm4uYXBwbHkobnVsbCwgYXJncyk7XG4gICAgICB9LCB0aHJlc2hvbGQgLSAobm93IC0gdGltZXN0YW1wKSk7XG4gICAgfVxuICB9O1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSBkYXRhIG1heFJhdGVcbiAqIEBwYXJhbSB7TnVtYmVyfSBbc2FtcGxlc0NvdW50PSAxMF1cbiAqIEBwYXJhbSB7TnVtYmVyfSBbbWluPSAxMDAwXVxuICogQHJldHVybnMge0Z1bmN0aW9ufVxuICovXG5mdW5jdGlvbiBzcGVlZG9tZXRlcihzYW1wbGVzQ291bnQsIG1pbikge1xuICBzYW1wbGVzQ291bnQgPSBzYW1wbGVzQ291bnQgfHwgMTA7XG4gIGNvbnN0IGJ5dGVzID0gbmV3IEFycmF5KHNhbXBsZXNDb3VudCk7XG4gIGNvbnN0IHRpbWVzdGFtcHMgPSBuZXcgQXJyYXkoc2FtcGxlc0NvdW50KTtcbiAgbGV0IGhlYWQgPSAwO1xuICBsZXQgdGFpbCA9IDA7XG4gIGxldCBmaXJzdFNhbXBsZVRTO1xuXG4gIG1pbiA9IG1pbiAhPT0gdW5kZWZpbmVkID8gbWluIDogMTAwMDtcblxuICByZXR1cm4gZnVuY3Rpb24gcHVzaChjaHVua0xlbmd0aCkge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG5cbiAgICBjb25zdCBzdGFydGVkQXQgPSB0aW1lc3RhbXBzW3RhaWxdO1xuXG4gICAgaWYgKCFmaXJzdFNhbXBsZVRTKSB7XG4gICAgICBmaXJzdFNhbXBsZVRTID0gbm93O1xuICAgIH1cblxuICAgIGJ5dGVzW2hlYWRdID0gY2h1bmtMZW5ndGg7XG4gICAgdGltZXN0YW1wc1toZWFkXSA9IG5vdztcblxuICAgIGxldCBpID0gdGFpbDtcbiAgICBsZXQgYnl0ZXNDb3VudCA9IDA7XG5cbiAgICB3aGlsZSAoaSAhPT0gaGVhZCkge1xuICAgICAgYnl0ZXNDb3VudCArPSBieXRlc1tpKytdO1xuICAgICAgaSA9IGkgJSBzYW1wbGVzQ291bnQ7XG4gICAgfVxuXG4gICAgaGVhZCA9IChoZWFkICsgMSkgJSBzYW1wbGVzQ291bnQ7XG5cbiAgICBpZiAoaGVhZCA9PT0gdGFpbCkge1xuICAgICAgdGFpbCA9ICh0YWlsICsgMSkgJSBzYW1wbGVzQ291bnQ7XG4gICAgfVxuXG4gICAgaWYgKG5vdyAtIGZpcnN0U2FtcGxlVFMgPCBtaW4pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwYXNzZWQgPSBzdGFydGVkQXQgJiYgbm93IC0gc3RhcnRlZEF0O1xuXG4gICAgcmV0dXJuIHBhc3NlZCA/IE1hdGgucm91bmQoYnl0ZXNDb3VudCAqIDEwMDAgLyBwYXNzZWQpIDogdW5kZWZpbmVkO1xuICB9O1xufVxuXG5jb25zdCBrSW50ZXJuYWxzID0gU3ltYm9sKCdpbnRlcm5hbHMnKTtcblxuY2xhc3MgQXhpb3NUcmFuc2Zvcm1TdHJlYW0gZXh0ZW5kcyBzdHJlYW1fX2RlZmF1bHRbXCJkZWZhdWx0XCJdLlRyYW5zZm9ybXtcbiAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSB1dGlscy50b0ZsYXRPYmplY3Qob3B0aW9ucywge1xuICAgICAgbWF4UmF0ZTogMCxcbiAgICAgIGNodW5rU2l6ZTogNjQgKiAxMDI0LFxuICAgICAgbWluQ2h1bmtTaXplOiAxMDAsXG4gICAgICB0aW1lV2luZG93OiA1MDAsXG4gICAgICB0aWNrc1JhdGU6IDIsXG4gICAgICBzYW1wbGVzQ291bnQ6IDE1XG4gICAgfSwgbnVsbCwgKHByb3AsIHNvdXJjZSkgPT4ge1xuICAgICAgcmV0dXJuICF1dGlscy5pc1VuZGVmaW5lZChzb3VyY2VbcHJvcF0pO1xuICAgIH0pO1xuXG4gICAgc3VwZXIoe1xuICAgICAgcmVhZGFibGVIaWdoV2F0ZXJNYXJrOiBvcHRpb25zLmNodW5rU2l6ZVxuICAgIH0pO1xuXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBjb25zdCBpbnRlcm5hbHMgPSB0aGlzW2tJbnRlcm5hbHNdID0ge1xuICAgICAgbGVuZ3RoOiBvcHRpb25zLmxlbmd0aCxcbiAgICAgIHRpbWVXaW5kb3c6IG9wdGlvbnMudGltZVdpbmRvdyxcbiAgICAgIHRpY2tzUmF0ZTogb3B0aW9ucy50aWNrc1JhdGUsXG4gICAgICBjaHVua1NpemU6IG9wdGlvbnMuY2h1bmtTaXplLFxuICAgICAgbWF4UmF0ZTogb3B0aW9ucy5tYXhSYXRlLFxuICAgICAgbWluQ2h1bmtTaXplOiBvcHRpb25zLm1pbkNodW5rU2l6ZSxcbiAgICAgIGJ5dGVzU2VlbjogMCxcbiAgICAgIGlzQ2FwdHVyZWQ6IGZhbHNlLFxuICAgICAgbm90aWZpZWRCeXRlc0xvYWRlZDogMCxcbiAgICAgIHRzOiBEYXRlLm5vdygpLFxuICAgICAgYnl0ZXM6IDAsXG4gICAgICBvblJlYWRDYWxsYmFjazogbnVsbFxuICAgIH07XG5cbiAgICBjb25zdCBfc3BlZWRvbWV0ZXIgPSBzcGVlZG9tZXRlcihpbnRlcm5hbHMudGlja3NSYXRlICogb3B0aW9ucy5zYW1wbGVzQ291bnQsIGludGVybmFscy50aW1lV2luZG93KTtcblxuICAgIHRoaXMub24oJ25ld0xpc3RlbmVyJywgZXZlbnQgPT4ge1xuICAgICAgaWYgKGV2ZW50ID09PSAncHJvZ3Jlc3MnKSB7XG4gICAgICAgIGlmICghaW50ZXJuYWxzLmlzQ2FwdHVyZWQpIHtcbiAgICAgICAgICBpbnRlcm5hbHMuaXNDYXB0dXJlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGxldCBieXRlc05vdGlmaWVkID0gMDtcblxuICAgIGludGVybmFscy51cGRhdGVQcm9ncmVzcyA9IHRocm90dGxlKGZ1bmN0aW9uIHRocm90dGxlZEhhbmRsZXIoKSB7XG4gICAgICBjb25zdCB0b3RhbEJ5dGVzID0gaW50ZXJuYWxzLmxlbmd0aDtcbiAgICAgIGNvbnN0IGJ5dGVzVHJhbnNmZXJyZWQgPSBpbnRlcm5hbHMuYnl0ZXNTZWVuO1xuICAgICAgY29uc3QgcHJvZ3Jlc3NCeXRlcyA9IGJ5dGVzVHJhbnNmZXJyZWQgLSBieXRlc05vdGlmaWVkO1xuICAgICAgaWYgKCFwcm9ncmVzc0J5dGVzIHx8IHNlbGYuZGVzdHJveWVkKSByZXR1cm47XG5cbiAgICAgIGNvbnN0IHJhdGUgPSBfc3BlZWRvbWV0ZXIocHJvZ3Jlc3NCeXRlcyk7XG5cbiAgICAgIGJ5dGVzTm90aWZpZWQgPSBieXRlc1RyYW5zZmVycmVkO1xuXG4gICAgICBwcm9jZXNzLm5leHRUaWNrKCgpID0+IHtcbiAgICAgICAgc2VsZi5lbWl0KCdwcm9ncmVzcycsIHtcbiAgICAgICAgICAnbG9hZGVkJzogYnl0ZXNUcmFuc2ZlcnJlZCxcbiAgICAgICAgICAndG90YWwnOiB0b3RhbEJ5dGVzLFxuICAgICAgICAgICdwcm9ncmVzcyc6IHRvdGFsQnl0ZXMgPyAoYnl0ZXNUcmFuc2ZlcnJlZCAvIHRvdGFsQnl0ZXMpIDogdW5kZWZpbmVkLFxuICAgICAgICAgICdieXRlcyc6IHByb2dyZXNzQnl0ZXMsXG4gICAgICAgICAgJ3JhdGUnOiByYXRlID8gcmF0ZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAnZXN0aW1hdGVkJzogcmF0ZSAmJiB0b3RhbEJ5dGVzICYmIGJ5dGVzVHJhbnNmZXJyZWQgPD0gdG90YWxCeXRlcyA/XG4gICAgICAgICAgICAodG90YWxCeXRlcyAtIGJ5dGVzVHJhbnNmZXJyZWQpIC8gcmF0ZSA6IHVuZGVmaW5lZFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0sIGludGVybmFscy50aWNrc1JhdGUpO1xuXG4gICAgY29uc3Qgb25GaW5pc2ggPSAoKSA9PiB7XG4gICAgICBpbnRlcm5hbHMudXBkYXRlUHJvZ3Jlc3ModHJ1ZSk7XG4gICAgfTtcblxuICAgIHRoaXMub25jZSgnZW5kJywgb25GaW5pc2gpO1xuICAgIHRoaXMub25jZSgnZXJyb3InLCBvbkZpbmlzaCk7XG4gIH1cblxuICBfcmVhZChzaXplKSB7XG4gICAgY29uc3QgaW50ZXJuYWxzID0gdGhpc1trSW50ZXJuYWxzXTtcblxuICAgIGlmIChpbnRlcm5hbHMub25SZWFkQ2FsbGJhY2spIHtcbiAgICAgIGludGVybmFscy5vblJlYWRDYWxsYmFjaygpO1xuICAgIH1cblxuICAgIHJldHVybiBzdXBlci5fcmVhZChzaXplKTtcbiAgfVxuXG4gIF90cmFuc2Zvcm0oY2h1bmssIGVuY29kaW5nLCBjYWxsYmFjaykge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGNvbnN0IGludGVybmFscyA9IHRoaXNba0ludGVybmFsc107XG4gICAgY29uc3QgbWF4UmF0ZSA9IGludGVybmFscy5tYXhSYXRlO1xuXG4gICAgY29uc3QgcmVhZGFibGVIaWdoV2F0ZXJNYXJrID0gdGhpcy5yZWFkYWJsZUhpZ2hXYXRlck1hcms7XG5cbiAgICBjb25zdCB0aW1lV2luZG93ID0gaW50ZXJuYWxzLnRpbWVXaW5kb3c7XG5cbiAgICBjb25zdCBkaXZpZGVyID0gMTAwMCAvIHRpbWVXaW5kb3c7XG4gICAgY29uc3QgYnl0ZXNUaHJlc2hvbGQgPSAobWF4UmF0ZSAvIGRpdmlkZXIpO1xuICAgIGNvbnN0IG1pbkNodW5rU2l6ZSA9IGludGVybmFscy5taW5DaHVua1NpemUgIT09IGZhbHNlID8gTWF0aC5tYXgoaW50ZXJuYWxzLm1pbkNodW5rU2l6ZSwgYnl0ZXNUaHJlc2hvbGQgKiAwLjAxKSA6IDA7XG5cbiAgICBmdW5jdGlvbiBwdXNoQ2h1bmsoX2NodW5rLCBfY2FsbGJhY2spIHtcbiAgICAgIGNvbnN0IGJ5dGVzID0gQnVmZmVyLmJ5dGVMZW5ndGgoX2NodW5rKTtcbiAgICAgIGludGVybmFscy5ieXRlc1NlZW4gKz0gYnl0ZXM7XG4gICAgICBpbnRlcm5hbHMuYnl0ZXMgKz0gYnl0ZXM7XG5cbiAgICAgIGlmIChpbnRlcm5hbHMuaXNDYXB0dXJlZCkge1xuICAgICAgICBpbnRlcm5hbHMudXBkYXRlUHJvZ3Jlc3MoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNlbGYucHVzaChfY2h1bmspKSB7XG4gICAgICAgIHByb2Nlc3MubmV4dFRpY2soX2NhbGxiYWNrKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGludGVybmFscy5vblJlYWRDYWxsYmFjayA9ICgpID0+IHtcbiAgICAgICAgICBpbnRlcm5hbHMub25SZWFkQ2FsbGJhY2sgPSBudWxsO1xuICAgICAgICAgIHByb2Nlc3MubmV4dFRpY2soX2NhbGxiYWNrKTtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB0cmFuc2Zvcm1DaHVuayA9IChfY2h1bmssIF9jYWxsYmFjaykgPT4ge1xuICAgICAgY29uc3QgY2h1bmtTaXplID0gQnVmZmVyLmJ5dGVMZW5ndGgoX2NodW5rKTtcbiAgICAgIGxldCBjaHVua1JlbWFpbmRlciA9IG51bGw7XG4gICAgICBsZXQgbWF4Q2h1bmtTaXplID0gcmVhZGFibGVIaWdoV2F0ZXJNYXJrO1xuICAgICAgbGV0IGJ5dGVzTGVmdDtcbiAgICAgIGxldCBwYXNzZWQgPSAwO1xuXG4gICAgICBpZiAobWF4UmF0ZSkge1xuICAgICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuXG4gICAgICAgIGlmICghaW50ZXJuYWxzLnRzIHx8IChwYXNzZWQgPSAobm93IC0gaW50ZXJuYWxzLnRzKSkgPj0gdGltZVdpbmRvdykge1xuICAgICAgICAgIGludGVybmFscy50cyA9IG5vdztcbiAgICAgICAgICBieXRlc0xlZnQgPSBieXRlc1RocmVzaG9sZCAtIGludGVybmFscy5ieXRlcztcbiAgICAgICAgICBpbnRlcm5hbHMuYnl0ZXMgPSBieXRlc0xlZnQgPCAwID8gLWJ5dGVzTGVmdCA6IDA7XG4gICAgICAgICAgcGFzc2VkID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGJ5dGVzTGVmdCA9IGJ5dGVzVGhyZXNob2xkIC0gaW50ZXJuYWxzLmJ5dGVzO1xuICAgICAgfVxuXG4gICAgICBpZiAobWF4UmF0ZSkge1xuICAgICAgICBpZiAoYnl0ZXNMZWZ0IDw9IDApIHtcbiAgICAgICAgICAvLyBuZXh0IHRpbWUgd2luZG93XG4gICAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgX2NhbGxiYWNrKG51bGwsIF9jaHVuayk7XG4gICAgICAgICAgfSwgdGltZVdpbmRvdyAtIHBhc3NlZCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYnl0ZXNMZWZ0IDwgbWF4Q2h1bmtTaXplKSB7XG4gICAgICAgICAgbWF4Q2h1bmtTaXplID0gYnl0ZXNMZWZ0O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChtYXhDaHVua1NpemUgJiYgY2h1bmtTaXplID4gbWF4Q2h1bmtTaXplICYmIChjaHVua1NpemUgLSBtYXhDaHVua1NpemUpID4gbWluQ2h1bmtTaXplKSB7XG4gICAgICAgIGNodW5rUmVtYWluZGVyID0gX2NodW5rLnN1YmFycmF5KG1heENodW5rU2l6ZSk7XG4gICAgICAgIF9jaHVuayA9IF9jaHVuay5zdWJhcnJheSgwLCBtYXhDaHVua1NpemUpO1xuICAgICAgfVxuXG4gICAgICBwdXNoQ2h1bmsoX2NodW5rLCBjaHVua1JlbWFpbmRlciA/ICgpID0+IHtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhfY2FsbGJhY2ssIG51bGwsIGNodW5rUmVtYWluZGVyKTtcbiAgICAgIH0gOiBfY2FsbGJhY2spO1xuICAgIH07XG5cbiAgICB0cmFuc2Zvcm1DaHVuayhjaHVuaywgZnVuY3Rpb24gdHJhbnNmb3JtTmV4dENodW5rKGVyciwgX2NodW5rKSB7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgfVxuXG4gICAgICBpZiAoX2NodW5rKSB7XG4gICAgICAgIHRyYW5zZm9ybUNodW5rKF9jaHVuaywgdHJhbnNmb3JtTmV4dENodW5rKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNhbGxiYWNrKG51bGwpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgc2V0TGVuZ3RoKGxlbmd0aCkge1xuICAgIHRoaXNba0ludGVybmFsc10ubGVuZ3RoID0gK2xlbmd0aDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufVxuXG5jb25zdCBBeGlvc1RyYW5zZm9ybVN0cmVhbSQxID0gQXhpb3NUcmFuc2Zvcm1TdHJlYW07XG5cbmNvbnN0IHthc3luY0l0ZXJhdG9yfSA9IFN5bWJvbDtcblxuY29uc3QgcmVhZEJsb2IgPSBhc3luYyBmdW5jdGlvbiogKGJsb2IpIHtcbiAgaWYgKGJsb2Iuc3RyZWFtKSB7XG4gICAgeWllbGQqIGJsb2Iuc3RyZWFtKCk7XG4gIH0gZWxzZSBpZiAoYmxvYi5hcnJheUJ1ZmZlcikge1xuICAgIHlpZWxkIGF3YWl0IGJsb2IuYXJyYXlCdWZmZXIoKTtcbiAgfSBlbHNlIGlmIChibG9iW2FzeW5jSXRlcmF0b3JdKSB7XG4gICAgeWllbGQqIGJsb2JbYXN5bmNJdGVyYXRvcl0oKTtcbiAgfSBlbHNlIHtcbiAgICB5aWVsZCBibG9iO1xuICB9XG59O1xuXG5jb25zdCByZWFkQmxvYiQxID0gcmVhZEJsb2I7XG5cbmNvbnN0IEJPVU5EQVJZX0FMUEhBQkVUID0gdXRpbHMuQUxQSEFCRVQuQUxQSEFfRElHSVQgKyAnLV8nO1xuXG5jb25zdCB0ZXh0RW5jb2RlciA9IG5ldyB1dGlsLlRleHRFbmNvZGVyKCk7XG5cbmNvbnN0IENSTEYgPSAnXFxyXFxuJztcbmNvbnN0IENSTEZfQllURVMgPSB0ZXh0RW5jb2Rlci5lbmNvZGUoQ1JMRik7XG5jb25zdCBDUkxGX0JZVEVTX0NPVU5UID0gMjtcblxuY2xhc3MgRm9ybURhdGFQYXJ0IHtcbiAgY29uc3RydWN0b3IobmFtZSwgdmFsdWUpIHtcbiAgICBjb25zdCB7ZXNjYXBlTmFtZX0gPSB0aGlzLmNvbnN0cnVjdG9yO1xuICAgIGNvbnN0IGlzU3RyaW5nVmFsdWUgPSB1dGlscy5pc1N0cmluZyh2YWx1ZSk7XG5cbiAgICBsZXQgaGVhZGVycyA9IGBDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9XCIke2VzY2FwZU5hbWUobmFtZSl9XCIke1xuICAgICAgIWlzU3RyaW5nVmFsdWUgJiYgdmFsdWUubmFtZSA/IGA7IGZpbGVuYW1lPVwiJHtlc2NhcGVOYW1lKHZhbHVlLm5hbWUpfVwiYCA6ICcnXG4gICAgfSR7Q1JMRn1gO1xuXG4gICAgaWYgKGlzU3RyaW5nVmFsdWUpIHtcbiAgICAgIHZhbHVlID0gdGV4dEVuY29kZXIuZW5jb2RlKFN0cmluZyh2YWx1ZSkucmVwbGFjZSgvXFxyP1xcbnxcXHJcXG4/L2csIENSTEYpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaGVhZGVycyArPSBgQ29udGVudC1UeXBlOiAke3ZhbHVlLnR5cGUgfHwgXCJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW1cIn0ke0NSTEZ9YDtcbiAgICB9XG5cbiAgICB0aGlzLmhlYWRlcnMgPSB0ZXh0RW5jb2Rlci5lbmNvZGUoaGVhZGVycyArIENSTEYpO1xuXG4gICAgdGhpcy5jb250ZW50TGVuZ3RoID0gaXNTdHJpbmdWYWx1ZSA/IHZhbHVlLmJ5dGVMZW5ndGggOiB2YWx1ZS5zaXplO1xuXG4gICAgdGhpcy5zaXplID0gdGhpcy5oZWFkZXJzLmJ5dGVMZW5ndGggKyB0aGlzLmNvbnRlbnRMZW5ndGggKyBDUkxGX0JZVEVTX0NPVU5UO1xuXG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gIH1cblxuICBhc3luYyAqZW5jb2RlKCl7XG4gICAgeWllbGQgdGhpcy5oZWFkZXJzO1xuXG4gICAgY29uc3Qge3ZhbHVlfSA9IHRoaXM7XG5cbiAgICBpZih1dGlscy5pc1R5cGVkQXJyYXkodmFsdWUpKSB7XG4gICAgICB5aWVsZCB2YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgeWllbGQqIHJlYWRCbG9iJDEodmFsdWUpO1xuICAgIH1cblxuICAgIHlpZWxkIENSTEZfQllURVM7XG4gIH1cblxuICBzdGF0aWMgZXNjYXBlTmFtZShuYW1lKSB7XG4gICAgICByZXR1cm4gU3RyaW5nKG5hbWUpLnJlcGxhY2UoL1tcXHJcXG5cIl0vZywgKG1hdGNoKSA9PiAoe1xuICAgICAgICAnXFxyJyA6ICclMEQnLFxuICAgICAgICAnXFxuJyA6ICclMEEnLFxuICAgICAgICAnXCInIDogJyUyMicsXG4gICAgICB9W21hdGNoXSkpO1xuICB9XG59XG5cbmNvbnN0IGZvcm1EYXRhVG9TdHJlYW0gPSAoZm9ybSwgaGVhZGVyc0hhbmRsZXIsIG9wdGlvbnMpID0+IHtcbiAgY29uc3Qge1xuICAgIHRhZyA9ICdmb3JtLWRhdGEtYm91bmRhcnknLFxuICAgIHNpemUgPSAyNSxcbiAgICBib3VuZGFyeSA9IHRhZyArICctJyArIHV0aWxzLmdlbmVyYXRlU3RyaW5nKHNpemUsIEJPVU5EQVJZX0FMUEhBQkVUKVxuICB9ID0gb3B0aW9ucyB8fCB7fTtcblxuICBpZighdXRpbHMuaXNGb3JtRGF0YShmb3JtKSkge1xuICAgIHRocm93IFR5cGVFcnJvcignRm9ybURhdGEgaW5zdGFuY2UgcmVxdWlyZWQnKTtcbiAgfVxuXG4gIGlmIChib3VuZGFyeS5sZW5ndGggPCAxIHx8IGJvdW5kYXJ5Lmxlbmd0aCA+IDcwKSB7XG4gICAgdGhyb3cgRXJyb3IoJ2JvdW5kYXJ5IG11c3QgYmUgMTAtNzAgY2hhcmFjdGVycyBsb25nJylcbiAgfVxuXG4gIGNvbnN0IGJvdW5kYXJ5Qnl0ZXMgPSB0ZXh0RW5jb2Rlci5lbmNvZGUoJy0tJyArIGJvdW5kYXJ5ICsgQ1JMRik7XG4gIGNvbnN0IGZvb3RlckJ5dGVzID0gdGV4dEVuY29kZXIuZW5jb2RlKCctLScgKyBib3VuZGFyeSArICctLScgKyBDUkxGICsgQ1JMRik7XG4gIGxldCBjb250ZW50TGVuZ3RoID0gZm9vdGVyQnl0ZXMuYnl0ZUxlbmd0aDtcblxuICBjb25zdCBwYXJ0cyA9IEFycmF5LmZyb20oZm9ybS5lbnRyaWVzKCkpLm1hcCgoW25hbWUsIHZhbHVlXSkgPT4ge1xuICAgIGNvbnN0IHBhcnQgPSBuZXcgRm9ybURhdGFQYXJ0KG5hbWUsIHZhbHVlKTtcbiAgICBjb250ZW50TGVuZ3RoICs9IHBhcnQuc2l6ZTtcbiAgICByZXR1cm4gcGFydDtcbiAgfSk7XG5cbiAgY29udGVudExlbmd0aCArPSBib3VuZGFyeUJ5dGVzLmJ5dGVMZW5ndGggKiBwYXJ0cy5sZW5ndGg7XG5cbiAgY29udGVudExlbmd0aCA9IHV0aWxzLnRvRmluaXRlTnVtYmVyKGNvbnRlbnRMZW5ndGgpO1xuXG4gIGNvbnN0IGNvbXB1dGVkSGVhZGVycyA9IHtcbiAgICAnQ29udGVudC1UeXBlJzogYG11bHRpcGFydC9mb3JtLWRhdGE7IGJvdW5kYXJ5PSR7Ym91bmRhcnl9YFxuICB9O1xuXG4gIGlmIChOdW1iZXIuaXNGaW5pdGUoY29udGVudExlbmd0aCkpIHtcbiAgICBjb21wdXRlZEhlYWRlcnNbJ0NvbnRlbnQtTGVuZ3RoJ10gPSBjb250ZW50TGVuZ3RoO1xuICB9XG5cbiAgaGVhZGVyc0hhbmRsZXIgJiYgaGVhZGVyc0hhbmRsZXIoY29tcHV0ZWRIZWFkZXJzKTtcblxuICByZXR1cm4gc3RyZWFtLlJlYWRhYmxlLmZyb20oKGFzeW5jIGZ1bmN0aW9uICooKSB7XG4gICAgZm9yKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcbiAgICAgIHlpZWxkIGJvdW5kYXJ5Qnl0ZXM7XG4gICAgICB5aWVsZCogcGFydC5lbmNvZGUoKTtcbiAgICB9XG5cbiAgICB5aWVsZCBmb290ZXJCeXRlcztcbiAgfSkoKSk7XG59O1xuXG5jb25zdCBmb3JtRGF0YVRvU3RyZWFtJDEgPSBmb3JtRGF0YVRvU3RyZWFtO1xuXG5jbGFzcyBabGliSGVhZGVyVHJhbnNmb3JtU3RyZWFtIGV4dGVuZHMgc3RyZWFtX19kZWZhdWx0W1wiZGVmYXVsdFwiXS5UcmFuc2Zvcm0ge1xuICBfX3RyYW5zZm9ybShjaHVuaywgZW5jb2RpbmcsIGNhbGxiYWNrKSB7XG4gICAgdGhpcy5wdXNoKGNodW5rKTtcbiAgICBjYWxsYmFjaygpO1xuICB9XG5cbiAgX3RyYW5zZm9ybShjaHVuaywgZW5jb2RpbmcsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGNodW5rLmxlbmd0aCAhPT0gMCkge1xuICAgICAgdGhpcy5fdHJhbnNmb3JtID0gdGhpcy5fX3RyYW5zZm9ybTtcblxuICAgICAgLy8gQWRkIERlZmF1bHQgQ29tcHJlc3Npb24gaGVhZGVycyBpZiBubyB6bGliIGhlYWRlcnMgYXJlIHByZXNlbnRcbiAgICAgIGlmIChjaHVua1swXSAhPT0gMTIwKSB7IC8vIEhleDogNzhcbiAgICAgICAgY29uc3QgaGVhZGVyID0gQnVmZmVyLmFsbG9jKDIpO1xuICAgICAgICBoZWFkZXJbMF0gPSAxMjA7IC8vIEhleDogNzhcbiAgICAgICAgaGVhZGVyWzFdID0gMTU2OyAvLyBIZXg6IDlDIFxuICAgICAgICB0aGlzLnB1c2goaGVhZGVyLCBlbmNvZGluZyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5fX3RyYW5zZm9ybShjaHVuaywgZW5jb2RpbmcsIGNhbGxiYWNrKTtcbiAgfVxufVxuXG5jb25zdCBabGliSGVhZGVyVHJhbnNmb3JtU3RyZWFtJDEgPSBabGliSGVhZGVyVHJhbnNmb3JtU3RyZWFtO1xuXG5jb25zdCBjYWxsYmFja2lmeSA9IChmbiwgcmVkdWNlcikgPT4ge1xuICByZXR1cm4gdXRpbHMuaXNBc3luY0ZuKGZuKSA/IGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgY29uc3QgY2IgPSBhcmdzLnBvcCgpO1xuICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3MpLnRoZW4oKHZhbHVlKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICByZWR1Y2VyID8gY2IobnVsbCwgLi4ucmVkdWNlcih2YWx1ZSkpIDogY2IobnVsbCwgdmFsdWUpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNiKGVycik7XG4gICAgICB9XG4gICAgfSwgY2IpO1xuICB9IDogZm47XG59O1xuXG5jb25zdCBjYWxsYmFja2lmeSQxID0gY2FsbGJhY2tpZnk7XG5cbmNvbnN0IHpsaWJPcHRpb25zID0ge1xuICBmbHVzaDogemxpYl9fZGVmYXVsdFtcImRlZmF1bHRcIl0uY29uc3RhbnRzLlpfU1lOQ19GTFVTSCxcbiAgZmluaXNoRmx1c2g6IHpsaWJfX2RlZmF1bHRbXCJkZWZhdWx0XCJdLmNvbnN0YW50cy5aX1NZTkNfRkxVU0hcbn07XG5cbmNvbnN0IGJyb3RsaU9wdGlvbnMgPSB7XG4gIGZsdXNoOiB6bGliX19kZWZhdWx0W1wiZGVmYXVsdFwiXS5jb25zdGFudHMuQlJPVExJX09QRVJBVElPTl9GTFVTSCxcbiAgZmluaXNoRmx1c2g6IHpsaWJfX2RlZmF1bHRbXCJkZWZhdWx0XCJdLmNvbnN0YW50cy5CUk9UTElfT1BFUkFUSU9OX0ZMVVNIXG59O1xuXG5jb25zdCBpc0Jyb3RsaVN1cHBvcnRlZCA9IHV0aWxzLmlzRnVuY3Rpb24oemxpYl9fZGVmYXVsdFtcImRlZmF1bHRcIl0uY3JlYXRlQnJvdGxpRGVjb21wcmVzcyk7XG5cbmNvbnN0IHtodHRwOiBodHRwRm9sbG93LCBodHRwczogaHR0cHNGb2xsb3d9ID0gZm9sbG93UmVkaXJlY3RzX19kZWZhdWx0W1wiZGVmYXVsdFwiXTtcblxuY29uc3QgaXNIdHRwcyA9IC9odHRwczo/LztcblxuY29uc3Qgc3VwcG9ydGVkUHJvdG9jb2xzID0gcGxhdGZvcm0ucHJvdG9jb2xzLm1hcChwcm90b2NvbCA9PiB7XG4gIHJldHVybiBwcm90b2NvbCArICc6Jztcbn0pO1xuXG4vKipcbiAqIElmIHRoZSBwcm94eSBvciBjb25maWcgYmVmb3JlUmVkaXJlY3RzIGZ1bmN0aW9ucyBhcmUgZGVmaW5lZCwgY2FsbCB0aGVtIHdpdGggdGhlIG9wdGlvbnNcbiAqIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdDxzdHJpbmcsIGFueT59IG9wdGlvbnMgLSBUaGUgb3B0aW9ucyBvYmplY3QgdGhhdCB3YXMgcGFzc2VkIHRvIHRoZSByZXF1ZXN0LlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3Q8c3RyaW5nLCBhbnk+fVxuICovXG5mdW5jdGlvbiBkaXNwYXRjaEJlZm9yZVJlZGlyZWN0KG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMuYmVmb3JlUmVkaXJlY3RzLnByb3h5KSB7XG4gICAgb3B0aW9ucy5iZWZvcmVSZWRpcmVjdHMucHJveHkob3B0aW9ucyk7XG4gIH1cbiAgaWYgKG9wdGlvbnMuYmVmb3JlUmVkaXJlY3RzLmNvbmZpZykge1xuICAgIG9wdGlvbnMuYmVmb3JlUmVkaXJlY3RzLmNvbmZpZyhvcHRpb25zKTtcbiAgfVxufVxuXG4vKipcbiAqIElmIHRoZSBwcm94eSBvciBjb25maWcgYWZ0ZXJSZWRpcmVjdHMgZnVuY3Rpb25zIGFyZSBkZWZpbmVkLCBjYWxsIHRoZW0gd2l0aCB0aGUgb3B0aW9uc1xuICpcbiAqIEBwYXJhbSB7aHR0cC5DbGllbnRSZXF1ZXN0QXJnc30gb3B0aW9uc1xuICogQHBhcmFtIHtBeGlvc1Byb3h5Q29uZmlnfSBjb25maWdQcm94eSBjb25maWd1cmF0aW9uIGZyb20gQXhpb3Mgb3B0aW9ucyBvYmplY3RcbiAqIEBwYXJhbSB7c3RyaW5nfSBsb2NhdGlvblxuICpcbiAqIEByZXR1cm5zIHtodHRwLkNsaWVudFJlcXVlc3RBcmdzfVxuICovXG5mdW5jdGlvbiBzZXRQcm94eShvcHRpb25zLCBjb25maWdQcm94eSwgbG9jYXRpb24pIHtcbiAgbGV0IHByb3h5ID0gY29uZmlnUHJveHk7XG4gIGlmICghcHJveHkgJiYgcHJveHkgIT09IGZhbHNlKSB7XG4gICAgY29uc3QgcHJveHlVcmwgPSBwcm94eUZyb21FbnYuZ2V0UHJveHlGb3JVcmwobG9jYXRpb24pO1xuICAgIGlmIChwcm94eVVybCkge1xuICAgICAgcHJveHkgPSBuZXcgVVJMKHByb3h5VXJsKTtcbiAgICB9XG4gIH1cbiAgaWYgKHByb3h5KSB7XG4gICAgLy8gQmFzaWMgcHJveHkgYXV0aG9yaXphdGlvblxuICAgIGlmIChwcm94eS51c2VybmFtZSkge1xuICAgICAgcHJveHkuYXV0aCA9IChwcm94eS51c2VybmFtZSB8fCAnJykgKyAnOicgKyAocHJveHkucGFzc3dvcmQgfHwgJycpO1xuICAgIH1cblxuICAgIGlmIChwcm94eS5hdXRoKSB7XG4gICAgICAvLyBTdXBwb3J0IHByb3h5IGF1dGggb2JqZWN0IGZvcm1cbiAgICAgIGlmIChwcm94eS5hdXRoLnVzZXJuYW1lIHx8IHByb3h5LmF1dGgucGFzc3dvcmQpIHtcbiAgICAgICAgcHJveHkuYXV0aCA9IChwcm94eS5hdXRoLnVzZXJuYW1lIHx8ICcnKSArICc6JyArIChwcm94eS5hdXRoLnBhc3N3b3JkIHx8ICcnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGJhc2U2NCA9IEJ1ZmZlclxuICAgICAgICAuZnJvbShwcm94eS5hdXRoLCAndXRmOCcpXG4gICAgICAgIC50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgICBvcHRpb25zLmhlYWRlcnNbJ1Byb3h5LUF1dGhvcml6YXRpb24nXSA9ICdCYXNpYyAnICsgYmFzZTY0O1xuICAgIH1cblxuICAgIG9wdGlvbnMuaGVhZGVycy5ob3N0ID0gb3B0aW9ucy5ob3N0bmFtZSArIChvcHRpb25zLnBvcnQgPyAnOicgKyBvcHRpb25zLnBvcnQgOiAnJyk7XG4gICAgY29uc3QgcHJveHlIb3N0ID0gcHJveHkuaG9zdG5hbWUgfHwgcHJveHkuaG9zdDtcbiAgICBvcHRpb25zLmhvc3RuYW1lID0gcHJveHlIb3N0O1xuICAgIC8vIFJlcGxhY2UgJ2hvc3QnIHNpbmNlIG9wdGlvbnMgaXMgbm90IGEgVVJMIG9iamVjdFxuICAgIG9wdGlvbnMuaG9zdCA9IHByb3h5SG9zdDtcbiAgICBvcHRpb25zLnBvcnQgPSBwcm94eS5wb3J0O1xuICAgIG9wdGlvbnMucGF0aCA9IGxvY2F0aW9uO1xuICAgIGlmIChwcm94eS5wcm90b2NvbCkge1xuICAgICAgb3B0aW9ucy5wcm90b2NvbCA9IHByb3h5LnByb3RvY29sLmluY2x1ZGVzKCc6JykgPyBwcm94eS5wcm90b2NvbCA6IGAke3Byb3h5LnByb3RvY29sfTpgO1xuICAgIH1cbiAgfVxuXG4gIG9wdGlvbnMuYmVmb3JlUmVkaXJlY3RzLnByb3h5ID0gZnVuY3Rpb24gYmVmb3JlUmVkaXJlY3QocmVkaXJlY3RPcHRpb25zKSB7XG4gICAgLy8gQ29uZmlndXJlIHByb3h5IGZvciByZWRpcmVjdGVkIHJlcXVlc3QsIHBhc3NpbmcgdGhlIG9yaWdpbmFsIGNvbmZpZyBwcm94eSB0byBhcHBseVxuICAgIC8vIHRoZSBleGFjdCBzYW1lIGxvZ2ljIGFzIGlmIHRoZSByZWRpcmVjdGVkIHJlcXVlc3Qgd2FzIHBlcmZvcm1lZCBieSBheGlvcyBkaXJlY3RseS5cbiAgICBzZXRQcm94eShyZWRpcmVjdE9wdGlvbnMsIGNvbmZpZ1Byb3h5LCByZWRpcmVjdE9wdGlvbnMuaHJlZik7XG4gIH07XG59XG5cbmNvbnN0IGlzSHR0cEFkYXB0ZXJTdXBwb3J0ZWQgPSB0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgdXRpbHMua2luZE9mKHByb2Nlc3MpID09PSAncHJvY2Vzcyc7XG5cbi8vIHRlbXBvcmFyeSBob3RmaXhcblxuY29uc3Qgd3JhcEFzeW5jID0gKGFzeW5jRXhlY3V0b3IpID0+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBsZXQgb25Eb25lO1xuICAgIGxldCBpc0RvbmU7XG5cbiAgICBjb25zdCBkb25lID0gKHZhbHVlLCBpc1JlamVjdGVkKSA9PiB7XG4gICAgICBpZiAoaXNEb25lKSByZXR1cm47XG4gICAgICBpc0RvbmUgPSB0cnVlO1xuICAgICAgb25Eb25lICYmIG9uRG9uZSh2YWx1ZSwgaXNSZWplY3RlZCk7XG4gICAgfTtcblxuICAgIGNvbnN0IF9yZXNvbHZlID0gKHZhbHVlKSA9PiB7XG4gICAgICBkb25lKHZhbHVlKTtcbiAgICAgIHJlc29sdmUodmFsdWUpO1xuICAgIH07XG5cbiAgICBjb25zdCBfcmVqZWN0ID0gKHJlYXNvbikgPT4ge1xuICAgICAgZG9uZShyZWFzb24sIHRydWUpO1xuICAgICAgcmVqZWN0KHJlYXNvbik7XG4gICAgfTtcblxuICAgIGFzeW5jRXhlY3V0b3IoX3Jlc29sdmUsIF9yZWplY3QsIChvbkRvbmVIYW5kbGVyKSA9PiAob25Eb25lID0gb25Eb25lSGFuZGxlcikpLmNhdGNoKF9yZWplY3QpO1xuICB9KVxufTtcblxuY29uc3QgcmVzb2x2ZUZhbWlseSA9ICh7YWRkcmVzcywgZmFtaWx5fSkgPT4ge1xuICBpZiAoIXV0aWxzLmlzU3RyaW5nKGFkZHJlc3MpKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKCdhZGRyZXNzIG11c3QgYmUgYSBzdHJpbmcnKTtcbiAgfVxuICByZXR1cm4gKHtcbiAgICBhZGRyZXNzLFxuICAgIGZhbWlseTogZmFtaWx5IHx8IChhZGRyZXNzLmluZGV4T2YoJy4nKSA8IDAgPyA2IDogNClcbiAgfSk7XG59O1xuXG5jb25zdCBidWlsZEFkZHJlc3NFbnRyeSA9IChhZGRyZXNzLCBmYW1pbHkpID0+IHJlc29sdmVGYW1pbHkodXRpbHMuaXNPYmplY3QoYWRkcmVzcykgPyBhZGRyZXNzIDoge2FkZHJlc3MsIGZhbWlseX0pO1xuXG4vKmVzbGludCBjb25zaXN0ZW50LXJldHVybjowKi9cbmNvbnN0IGh0dHBBZGFwdGVyID0gaXNIdHRwQWRhcHRlclN1cHBvcnRlZCAmJiBmdW5jdGlvbiBodHRwQWRhcHRlcihjb25maWcpIHtcbiAgcmV0dXJuIHdyYXBBc3luYyhhc3luYyBmdW5jdGlvbiBkaXNwYXRjaEh0dHBSZXF1ZXN0KHJlc29sdmUsIHJlamVjdCwgb25Eb25lKSB7XG4gICAgbGV0IHtkYXRhLCBsb29rdXAsIGZhbWlseX0gPSBjb25maWc7XG4gICAgY29uc3Qge3Jlc3BvbnNlVHlwZSwgcmVzcG9uc2VFbmNvZGluZ30gPSBjb25maWc7XG4gICAgY29uc3QgbWV0aG9kID0gY29uZmlnLm1ldGhvZC50b1VwcGVyQ2FzZSgpO1xuICAgIGxldCBpc0RvbmU7XG4gICAgbGV0IHJlamVjdGVkID0gZmFsc2U7XG4gICAgbGV0IHJlcTtcblxuICAgIGlmIChsb29rdXApIHtcbiAgICAgIGNvbnN0IF9sb29rdXAgPSBjYWxsYmFja2lmeSQxKGxvb2t1cCwgKHZhbHVlKSA9PiB1dGlscy5pc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW3ZhbHVlXSk7XG4gICAgICAvLyBob3RmaXggdG8gc3VwcG9ydCBvcHQuYWxsIG9wdGlvbiB3aGljaCBpcyByZXF1aXJlZCBmb3Igbm9kZSAyMC54XG4gICAgICBsb29rdXAgPSAoaG9zdG5hbWUsIG9wdCwgY2IpID0+IHtcbiAgICAgICAgX2xvb2t1cChob3N0bmFtZSwgb3B0LCAoZXJyLCBhcmcwLCBhcmcxKSA9PiB7XG4gICAgICAgICAgY29uc3QgYWRkcmVzc2VzID0gdXRpbHMuaXNBcnJheShhcmcwKSA/IGFyZzAubWFwKGFkZHIgPT4gYnVpbGRBZGRyZXNzRW50cnkoYWRkcikpIDogW2J1aWxkQWRkcmVzc0VudHJ5KGFyZzAsIGFyZzEpXTtcblxuICAgICAgICAgIG9wdC5hbGwgPyBjYihlcnIsIGFkZHJlc3NlcykgOiBjYihlcnIsIGFkZHJlc3Nlc1swXS5hZGRyZXNzLCBhZGRyZXNzZXNbMF0uZmFtaWx5KTtcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIHRlbXBvcmFyeSBpbnRlcm5hbCBlbWl0dGVyIHVudGlsIHRoZSBBeGlvc1JlcXVlc3QgY2xhc3Mgd2lsbCBiZSBpbXBsZW1lbnRlZFxuICAgIGNvbnN0IGVtaXR0ZXIgPSBuZXcgRXZlbnRFbWl0dGVyX19kZWZhdWx0W1wiZGVmYXVsdFwiXSgpO1xuXG4gICAgY29uc3Qgb25GaW5pc2hlZCA9ICgpID0+IHtcbiAgICAgIGlmIChjb25maWcuY2FuY2VsVG9rZW4pIHtcbiAgICAgICAgY29uZmlnLmNhbmNlbFRva2VuLnVuc3Vic2NyaWJlKGFib3J0KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5zaWduYWwpIHtcbiAgICAgICAgY29uZmlnLnNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIGFib3J0KTtcbiAgICAgIH1cblxuICAgICAgZW1pdHRlci5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcbiAgICB9O1xuXG4gICAgb25Eb25lKCh2YWx1ZSwgaXNSZWplY3RlZCkgPT4ge1xuICAgICAgaXNEb25lID0gdHJ1ZTtcbiAgICAgIGlmIChpc1JlamVjdGVkKSB7XG4gICAgICAgIHJlamVjdGVkID0gdHJ1ZTtcbiAgICAgICAgb25GaW5pc2hlZCgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gYWJvcnQocmVhc29uKSB7XG4gICAgICBlbWl0dGVyLmVtaXQoJ2Fib3J0JywgIXJlYXNvbiB8fCByZWFzb24udHlwZSA/IG5ldyBDYW5jZWxlZEVycm9yKG51bGwsIGNvbmZpZywgcmVxKSA6IHJlYXNvbik7XG4gICAgfVxuXG4gICAgZW1pdHRlci5vbmNlKCdhYm9ydCcsIHJlamVjdCk7XG5cbiAgICBpZiAoY29uZmlnLmNhbmNlbFRva2VuIHx8IGNvbmZpZy5zaWduYWwpIHtcbiAgICAgIGNvbmZpZy5jYW5jZWxUb2tlbiAmJiBjb25maWcuY2FuY2VsVG9rZW4uc3Vic2NyaWJlKGFib3J0KTtcbiAgICAgIGlmIChjb25maWcuc2lnbmFsKSB7XG4gICAgICAgIGNvbmZpZy5zaWduYWwuYWJvcnRlZCA/IGFib3J0KCkgOiBjb25maWcuc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgYWJvcnQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFBhcnNlIHVybFxuICAgIGNvbnN0IGZ1bGxQYXRoID0gYnVpbGRGdWxsUGF0aChjb25maWcuYmFzZVVSTCwgY29uZmlnLnVybCk7XG4gICAgY29uc3QgcGFyc2VkID0gbmV3IFVSTChmdWxsUGF0aCwgJ2h0dHA6Ly9sb2NhbGhvc3QnKTtcbiAgICBjb25zdCBwcm90b2NvbCA9IHBhcnNlZC5wcm90b2NvbCB8fCBzdXBwb3J0ZWRQcm90b2NvbHNbMF07XG5cbiAgICBpZiAocHJvdG9jb2wgPT09ICdkYXRhOicpIHtcbiAgICAgIGxldCBjb252ZXJ0ZWREYXRhO1xuXG4gICAgICBpZiAobWV0aG9kICE9PSAnR0VUJykge1xuICAgICAgICByZXR1cm4gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwge1xuICAgICAgICAgIHN0YXR1czogNDA1LFxuICAgICAgICAgIHN0YXR1c1RleHQ6ICdtZXRob2Qgbm90IGFsbG93ZWQnLFxuICAgICAgICAgIGhlYWRlcnM6IHt9LFxuICAgICAgICAgIGNvbmZpZ1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29udmVydGVkRGF0YSA9IGZyb21EYXRhVVJJKGNvbmZpZy51cmwsIHJlc3BvbnNlVHlwZSA9PT0gJ2Jsb2InLCB7XG4gICAgICAgICAgQmxvYjogY29uZmlnLmVudiAmJiBjb25maWcuZW52LkJsb2JcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgdGhyb3cgQXhpb3NFcnJvci5mcm9tKGVyciwgQXhpb3NFcnJvci5FUlJfQkFEX1JFUVVFU1QsIGNvbmZpZyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXNwb25zZVR5cGUgPT09ICd0ZXh0Jykge1xuICAgICAgICBjb252ZXJ0ZWREYXRhID0gY29udmVydGVkRGF0YS50b1N0cmluZyhyZXNwb25zZUVuY29kaW5nKTtcblxuICAgICAgICBpZiAoIXJlc3BvbnNlRW5jb2RpbmcgfHwgcmVzcG9uc2VFbmNvZGluZyA9PT0gJ3V0ZjgnKSB7XG4gICAgICAgICAgY29udmVydGVkRGF0YSA9IHV0aWxzLnN0cmlwQk9NKGNvbnZlcnRlZERhdGEpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHJlc3BvbnNlVHlwZSA9PT0gJ3N0cmVhbScpIHtcbiAgICAgICAgY29udmVydGVkRGF0YSA9IHN0cmVhbV9fZGVmYXVsdFtcImRlZmF1bHRcIl0uUmVhZGFibGUuZnJvbShjb252ZXJ0ZWREYXRhKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHtcbiAgICAgICAgZGF0YTogY29udmVydGVkRGF0YSxcbiAgICAgICAgc3RhdHVzOiAyMDAsXG4gICAgICAgIHN0YXR1c1RleHQ6ICdPSycsXG4gICAgICAgIGhlYWRlcnM6IG5ldyBBeGlvc0hlYWRlcnMkMSgpLFxuICAgICAgICBjb25maWdcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChzdXBwb3J0ZWRQcm90b2NvbHMuaW5kZXhPZihwcm90b2NvbCkgPT09IC0xKSB7XG4gICAgICByZXR1cm4gcmVqZWN0KG5ldyBBeGlvc0Vycm9yKFxuICAgICAgICAnVW5zdXBwb3J0ZWQgcHJvdG9jb2wgJyArIHByb3RvY29sLFxuICAgICAgICBBeGlvc0Vycm9yLkVSUl9CQURfUkVRVUVTVCxcbiAgICAgICAgY29uZmlnXG4gICAgICApKTtcbiAgICB9XG5cbiAgICBjb25zdCBoZWFkZXJzID0gQXhpb3NIZWFkZXJzJDEuZnJvbShjb25maWcuaGVhZGVycykubm9ybWFsaXplKCk7XG5cbiAgICAvLyBTZXQgVXNlci1BZ2VudCAocmVxdWlyZWQgYnkgc29tZSBzZXJ2ZXJzKVxuICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vYXhpb3MvYXhpb3MvaXNzdWVzLzY5XG4gICAgLy8gVXNlci1BZ2VudCBpcyBzcGVjaWZpZWQ7IGhhbmRsZSBjYXNlIHdoZXJlIG5vIFVBIGhlYWRlciBpcyBkZXNpcmVkXG4gICAgLy8gT25seSBzZXQgaGVhZGVyIGlmIGl0IGhhc24ndCBiZWVuIHNldCBpbiBjb25maWdcbiAgICBoZWFkZXJzLnNldCgnVXNlci1BZ2VudCcsICdheGlvcy8nICsgVkVSU0lPTiwgZmFsc2UpO1xuXG4gICAgY29uc3Qgb25Eb3dubG9hZFByb2dyZXNzID0gY29uZmlnLm9uRG93bmxvYWRQcm9ncmVzcztcbiAgICBjb25zdCBvblVwbG9hZFByb2dyZXNzID0gY29uZmlnLm9uVXBsb2FkUHJvZ3Jlc3M7XG4gICAgY29uc3QgbWF4UmF0ZSA9IGNvbmZpZy5tYXhSYXRlO1xuICAgIGxldCBtYXhVcGxvYWRSYXRlID0gdW5kZWZpbmVkO1xuICAgIGxldCBtYXhEb3dubG9hZFJhdGUgPSB1bmRlZmluZWQ7XG5cbiAgICAvLyBzdXBwb3J0IGZvciBzcGVjIGNvbXBsaWFudCBGb3JtRGF0YSBvYmplY3RzXG4gICAgaWYgKHV0aWxzLmlzU3BlY0NvbXBsaWFudEZvcm0oZGF0YSkpIHtcbiAgICAgIGNvbnN0IHVzZXJCb3VuZGFyeSA9IGhlYWRlcnMuZ2V0Q29udGVudFR5cGUoL2JvdW5kYXJ5PShbLV9cXHdcXGRdezEwLDcwfSkvaSk7XG5cbiAgICAgIGRhdGEgPSBmb3JtRGF0YVRvU3RyZWFtJDEoZGF0YSwgKGZvcm1IZWFkZXJzKSA9PiB7XG4gICAgICAgIGhlYWRlcnMuc2V0KGZvcm1IZWFkZXJzKTtcbiAgICAgIH0sIHtcbiAgICAgICAgdGFnOiBgYXhpb3MtJHtWRVJTSU9OfS1ib3VuZGFyeWAsXG4gICAgICAgIGJvdW5kYXJ5OiB1c2VyQm91bmRhcnkgJiYgdXNlckJvdW5kYXJ5WzFdIHx8IHVuZGVmaW5lZFxuICAgICAgfSk7XG4gICAgICAvLyBzdXBwb3J0IGZvciBodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9mb3JtLWRhdGEgYXBpXG4gICAgfSBlbHNlIGlmICh1dGlscy5pc0Zvcm1EYXRhKGRhdGEpICYmIHV0aWxzLmlzRnVuY3Rpb24oZGF0YS5nZXRIZWFkZXJzKSkge1xuICAgICAgaGVhZGVycy5zZXQoZGF0YS5nZXRIZWFkZXJzKCkpO1xuXG4gICAgICBpZiAoIWhlYWRlcnMuaGFzQ29udGVudExlbmd0aCgpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3Qga25vd25MZW5ndGggPSBhd2FpdCB1dGlsX19kZWZhdWx0W1wiZGVmYXVsdFwiXS5wcm9taXNpZnkoZGF0YS5nZXRMZW5ndGgpLmNhbGwoZGF0YSk7XG4gICAgICAgICAgTnVtYmVyLmlzRmluaXRlKGtub3duTGVuZ3RoKSAmJiBrbm93bkxlbmd0aCA+PSAwICYmIGhlYWRlcnMuc2V0Q29udGVudExlbmd0aChrbm93bkxlbmd0aCk7XG4gICAgICAgICAgLyplc2xpbnQgbm8tZW1wdHk6MCovXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodXRpbHMuaXNCbG9iKGRhdGEpKSB7XG4gICAgICBkYXRhLnNpemUgJiYgaGVhZGVycy5zZXRDb250ZW50VHlwZShkYXRhLnR5cGUgfHwgJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScpO1xuICAgICAgaGVhZGVycy5zZXRDb250ZW50TGVuZ3RoKGRhdGEuc2l6ZSB8fCAwKTtcbiAgICAgIGRhdGEgPSBzdHJlYW1fX2RlZmF1bHRbXCJkZWZhdWx0XCJdLlJlYWRhYmxlLmZyb20ocmVhZEJsb2IkMShkYXRhKSk7XG4gICAgfSBlbHNlIGlmIChkYXRhICYmICF1dGlscy5pc1N0cmVhbShkYXRhKSkge1xuICAgICAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihkYXRhKSkgOyBlbHNlIGlmICh1dGlscy5pc0FycmF5QnVmZmVyKGRhdGEpKSB7XG4gICAgICAgIGRhdGEgPSBCdWZmZXIuZnJvbShuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgICB9IGVsc2UgaWYgKHV0aWxzLmlzU3RyaW5nKGRhdGEpKSB7XG4gICAgICAgIGRhdGEgPSBCdWZmZXIuZnJvbShkYXRhLCAndXRmLTgnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiByZWplY3QobmV3IEF4aW9zRXJyb3IoXG4gICAgICAgICAgJ0RhdGEgYWZ0ZXIgdHJhbnNmb3JtYXRpb24gbXVzdCBiZSBhIHN0cmluZywgYW4gQXJyYXlCdWZmZXIsIGEgQnVmZmVyLCBvciBhIFN0cmVhbScsXG4gICAgICAgICAgQXhpb3NFcnJvci5FUlJfQkFEX1JFUVVFU1QsXG4gICAgICAgICAgY29uZmlnXG4gICAgICAgICkpO1xuICAgICAgfVxuXG4gICAgICAvLyBBZGQgQ29udGVudC1MZW5ndGggaGVhZGVyIGlmIGRhdGEgZXhpc3RzXG4gICAgICBoZWFkZXJzLnNldENvbnRlbnRMZW5ndGgoZGF0YS5sZW5ndGgsIGZhbHNlKTtcblxuICAgICAgaWYgKGNvbmZpZy5tYXhCb2R5TGVuZ3RoID4gLTEgJiYgZGF0YS5sZW5ndGggPiBjb25maWcubWF4Qm9keUxlbmd0aCkge1xuICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBBeGlvc0Vycm9yKFxuICAgICAgICAgICdSZXF1ZXN0IGJvZHkgbGFyZ2VyIHRoYW4gbWF4Qm9keUxlbmd0aCBsaW1pdCcsXG4gICAgICAgICAgQXhpb3NFcnJvci5FUlJfQkFEX1JFUVVFU1QsXG4gICAgICAgICAgY29uZmlnXG4gICAgICAgICkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGNvbnRlbnRMZW5ndGggPSB1dGlscy50b0Zpbml0ZU51bWJlcihoZWFkZXJzLmdldENvbnRlbnRMZW5ndGgoKSk7XG5cbiAgICBpZiAodXRpbHMuaXNBcnJheShtYXhSYXRlKSkge1xuICAgICAgbWF4VXBsb2FkUmF0ZSA9IG1heFJhdGVbMF07XG4gICAgICBtYXhEb3dubG9hZFJhdGUgPSBtYXhSYXRlWzFdO1xuICAgIH0gZWxzZSB7XG4gICAgICBtYXhVcGxvYWRSYXRlID0gbWF4RG93bmxvYWRSYXRlID0gbWF4UmF0ZTtcbiAgICB9XG5cbiAgICBpZiAoZGF0YSAmJiAob25VcGxvYWRQcm9ncmVzcyB8fCBtYXhVcGxvYWRSYXRlKSkge1xuICAgICAgaWYgKCF1dGlscy5pc1N0cmVhbShkYXRhKSkge1xuICAgICAgICBkYXRhID0gc3RyZWFtX19kZWZhdWx0W1wiZGVmYXVsdFwiXS5SZWFkYWJsZS5mcm9tKGRhdGEsIHtvYmplY3RNb2RlOiBmYWxzZX0pO1xuICAgICAgfVxuXG4gICAgICBkYXRhID0gc3RyZWFtX19kZWZhdWx0W1wiZGVmYXVsdFwiXS5waXBlbGluZShbZGF0YSwgbmV3IEF4aW9zVHJhbnNmb3JtU3RyZWFtJDEoe1xuICAgICAgICBsZW5ndGg6IGNvbnRlbnRMZW5ndGgsXG4gICAgICAgIG1heFJhdGU6IHV0aWxzLnRvRmluaXRlTnVtYmVyKG1heFVwbG9hZFJhdGUpXG4gICAgICB9KV0sIHV0aWxzLm5vb3ApO1xuXG4gICAgICBvblVwbG9hZFByb2dyZXNzICYmIGRhdGEub24oJ3Byb2dyZXNzJywgcHJvZ3Jlc3MgPT4ge1xuICAgICAgICBvblVwbG9hZFByb2dyZXNzKE9iamVjdC5hc3NpZ24ocHJvZ3Jlc3MsIHtcbiAgICAgICAgICB1cGxvYWQ6IHRydWVcbiAgICAgICAgfSkpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gSFRUUCBiYXNpYyBhdXRoZW50aWNhdGlvblxuICAgIGxldCBhdXRoID0gdW5kZWZpbmVkO1xuICAgIGlmIChjb25maWcuYXV0aCkge1xuICAgICAgY29uc3QgdXNlcm5hbWUgPSBjb25maWcuYXV0aC51c2VybmFtZSB8fCAnJztcbiAgICAgIGNvbnN0IHBhc3N3b3JkID0gY29uZmlnLmF1dGgucGFzc3dvcmQgfHwgJyc7XG4gICAgICBhdXRoID0gdXNlcm5hbWUgKyAnOicgKyBwYXNzd29yZDtcbiAgICB9XG5cbiAgICBpZiAoIWF1dGggJiYgcGFyc2VkLnVzZXJuYW1lKSB7XG4gICAgICBjb25zdCB1cmxVc2VybmFtZSA9IHBhcnNlZC51c2VybmFtZTtcbiAgICAgIGNvbnN0IHVybFBhc3N3b3JkID0gcGFyc2VkLnBhc3N3b3JkO1xuICAgICAgYXV0aCA9IHVybFVzZXJuYW1lICsgJzonICsgdXJsUGFzc3dvcmQ7XG4gICAgfVxuXG4gICAgYXV0aCAmJiBoZWFkZXJzLmRlbGV0ZSgnYXV0aG9yaXphdGlvbicpO1xuXG4gICAgbGV0IHBhdGg7XG5cbiAgICB0cnkge1xuICAgICAgcGF0aCA9IGJ1aWxkVVJMKFxuICAgICAgICBwYXJzZWQucGF0aG5hbWUgKyBwYXJzZWQuc2VhcmNoLFxuICAgICAgICBjb25maWcucGFyYW1zLFxuICAgICAgICBjb25maWcucGFyYW1zU2VyaWFsaXplclxuICAgICAgKS5yZXBsYWNlKC9eXFw/LywgJycpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc3QgY3VzdG9tRXJyID0gbmV3IEVycm9yKGVyci5tZXNzYWdlKTtcbiAgICAgIGN1c3RvbUVyci5jb25maWcgPSBjb25maWc7XG4gICAgICBjdXN0b21FcnIudXJsID0gY29uZmlnLnVybDtcbiAgICAgIGN1c3RvbUVyci5leGlzdHMgPSB0cnVlO1xuICAgICAgcmV0dXJuIHJlamVjdChjdXN0b21FcnIpO1xuICAgIH1cblxuICAgIGhlYWRlcnMuc2V0KFxuICAgICAgJ0FjY2VwdC1FbmNvZGluZycsXG4gICAgICAnZ3ppcCwgY29tcHJlc3MsIGRlZmxhdGUnICsgKGlzQnJvdGxpU3VwcG9ydGVkID8gJywgYnInIDogJycpLCBmYWxzZVxuICAgICAgKTtcblxuICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICBwYXRoLFxuICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICBoZWFkZXJzOiBoZWFkZXJzLnRvSlNPTigpLFxuICAgICAgYWdlbnRzOiB7IGh0dHA6IGNvbmZpZy5odHRwQWdlbnQsIGh0dHBzOiBjb25maWcuaHR0cHNBZ2VudCB9LFxuICAgICAgYXV0aCxcbiAgICAgIHByb3RvY29sLFxuICAgICAgZmFtaWx5LFxuICAgICAgYmVmb3JlUmVkaXJlY3Q6IGRpc3BhdGNoQmVmb3JlUmVkaXJlY3QsXG4gICAgICBiZWZvcmVSZWRpcmVjdHM6IHt9XG4gICAgfTtcblxuICAgIC8vIGNhY2hlYWJsZS1sb29rdXAgaW50ZWdyYXRpb24gaG90Zml4XG4gICAgIXV0aWxzLmlzVW5kZWZpbmVkKGxvb2t1cCkgJiYgKG9wdGlvbnMubG9va3VwID0gbG9va3VwKTtcblxuICAgIGlmIChjb25maWcuc29ja2V0UGF0aCkge1xuICAgICAgb3B0aW9ucy5zb2NrZXRQYXRoID0gY29uZmlnLnNvY2tldFBhdGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9wdGlvbnMuaG9zdG5hbWUgPSBwYXJzZWQuaG9zdG5hbWU7XG4gICAgICBvcHRpb25zLnBvcnQgPSBwYXJzZWQucG9ydDtcbiAgICAgIHNldFByb3h5KG9wdGlvbnMsIGNvbmZpZy5wcm94eSwgcHJvdG9jb2wgKyAnLy8nICsgcGFyc2VkLmhvc3RuYW1lICsgKHBhcnNlZC5wb3J0ID8gJzonICsgcGFyc2VkLnBvcnQgOiAnJykgKyBvcHRpb25zLnBhdGgpO1xuICAgIH1cblxuICAgIGxldCB0cmFuc3BvcnQ7XG4gICAgY29uc3QgaXNIdHRwc1JlcXVlc3QgPSBpc0h0dHBzLnRlc3Qob3B0aW9ucy5wcm90b2NvbCk7XG4gICAgb3B0aW9ucy5hZ2VudCA9IGlzSHR0cHNSZXF1ZXN0ID8gY29uZmlnLmh0dHBzQWdlbnQgOiBjb25maWcuaHR0cEFnZW50O1xuICAgIGlmIChjb25maWcudHJhbnNwb3J0KSB7XG4gICAgICB0cmFuc3BvcnQgPSBjb25maWcudHJhbnNwb3J0O1xuICAgIH0gZWxzZSBpZiAoY29uZmlnLm1heFJlZGlyZWN0cyA9PT0gMCkge1xuICAgICAgdHJhbnNwb3J0ID0gaXNIdHRwc1JlcXVlc3QgPyBodHRwc19fZGVmYXVsdFtcImRlZmF1bHRcIl0gOiBodHRwX19kZWZhdWx0W1wiZGVmYXVsdFwiXTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGNvbmZpZy5tYXhSZWRpcmVjdHMpIHtcbiAgICAgICAgb3B0aW9ucy5tYXhSZWRpcmVjdHMgPSBjb25maWcubWF4UmVkaXJlY3RzO1xuICAgICAgfVxuICAgICAgaWYgKGNvbmZpZy5iZWZvcmVSZWRpcmVjdCkge1xuICAgICAgICBvcHRpb25zLmJlZm9yZVJlZGlyZWN0cy5jb25maWcgPSBjb25maWcuYmVmb3JlUmVkaXJlY3Q7XG4gICAgICB9XG4gICAgICB0cmFuc3BvcnQgPSBpc0h0dHBzUmVxdWVzdCA/IGh0dHBzRm9sbG93IDogaHR0cEZvbGxvdztcbiAgICB9XG5cbiAgICBpZiAoY29uZmlnLm1heEJvZHlMZW5ndGggPiAtMSkge1xuICAgICAgb3B0aW9ucy5tYXhCb2R5TGVuZ3RoID0gY29uZmlnLm1heEJvZHlMZW5ndGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGZvbGxvdy1yZWRpcmVjdHMgZG9lcyBub3Qgc2tpcCBjb21wYXJpc29uLCBzbyBpdCBzaG91bGQgYWx3YXlzIHN1Y2NlZWQgZm9yIGF4aW9zIC0xIHVubGltaXRlZFxuICAgICAgb3B0aW9ucy5tYXhCb2R5TGVuZ3RoID0gSW5maW5pdHk7XG4gICAgfVxuXG4gICAgaWYgKGNvbmZpZy5pbnNlY3VyZUhUVFBQYXJzZXIpIHtcbiAgICAgIG9wdGlvbnMuaW5zZWN1cmVIVFRQUGFyc2VyID0gY29uZmlnLmluc2VjdXJlSFRUUFBhcnNlcjtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgdGhlIHJlcXVlc3RcbiAgICByZXEgPSB0cmFuc3BvcnQucmVxdWVzdChvcHRpb25zLCBmdW5jdGlvbiBoYW5kbGVSZXNwb25zZShyZXMpIHtcbiAgICAgIGlmIChyZXEuZGVzdHJveWVkKSByZXR1cm47XG5cbiAgICAgIGNvbnN0IHN0cmVhbXMgPSBbcmVzXTtcblxuICAgICAgY29uc3QgcmVzcG9uc2VMZW5ndGggPSArcmVzLmhlYWRlcnNbJ2NvbnRlbnQtbGVuZ3RoJ107XG5cbiAgICAgIGlmIChvbkRvd25sb2FkUHJvZ3Jlc3MpIHtcbiAgICAgICAgY29uc3QgdHJhbnNmb3JtU3RyZWFtID0gbmV3IEF4aW9zVHJhbnNmb3JtU3RyZWFtJDEoe1xuICAgICAgICAgIGxlbmd0aDogdXRpbHMudG9GaW5pdGVOdW1iZXIocmVzcG9uc2VMZW5ndGgpLFxuICAgICAgICAgIG1heFJhdGU6IHV0aWxzLnRvRmluaXRlTnVtYmVyKG1heERvd25sb2FkUmF0ZSlcbiAgICAgICAgfSk7XG5cbiAgICAgICAgb25Eb3dubG9hZFByb2dyZXNzICYmIHRyYW5zZm9ybVN0cmVhbS5vbigncHJvZ3Jlc3MnLCBwcm9ncmVzcyA9PiB7XG4gICAgICAgICAgb25Eb3dubG9hZFByb2dyZXNzKE9iamVjdC5hc3NpZ24ocHJvZ3Jlc3MsIHtcbiAgICAgICAgICAgIGRvd25sb2FkOiB0cnVlXG4gICAgICAgICAgfSkpO1xuICAgICAgICB9KTtcblxuICAgICAgICBzdHJlYW1zLnB1c2godHJhbnNmb3JtU3RyZWFtKTtcbiAgICAgIH1cblxuICAgICAgLy8gZGVjb21wcmVzcyB0aGUgcmVzcG9uc2UgYm9keSB0cmFuc3BhcmVudGx5IGlmIHJlcXVpcmVkXG4gICAgICBsZXQgcmVzcG9uc2VTdHJlYW0gPSByZXM7XG5cbiAgICAgIC8vIHJldHVybiB0aGUgbGFzdCByZXF1ZXN0IGluIGNhc2Ugb2YgcmVkaXJlY3RzXG4gICAgICBjb25zdCBsYXN0UmVxdWVzdCA9IHJlcy5yZXEgfHwgcmVxO1xuXG4gICAgICAvLyBpZiBkZWNvbXByZXNzIGRpc2FibGVkIHdlIHNob3VsZCBub3QgZGVjb21wcmVzc1xuICAgICAgaWYgKGNvbmZpZy5kZWNvbXByZXNzICE9PSBmYWxzZSAmJiByZXMuaGVhZGVyc1snY29udGVudC1lbmNvZGluZyddKSB7XG4gICAgICAgIC8vIGlmIG5vIGNvbnRlbnQsIGJ1dCBoZWFkZXJzIHN0aWxsIHNheSB0aGF0IGl0IGlzIGVuY29kZWQsXG4gICAgICAgIC8vIHJlbW92ZSB0aGUgaGVhZGVyIG5vdCBjb25mdXNlIGRvd25zdHJlYW0gb3BlcmF0aW9uc1xuICAgICAgICBpZiAobWV0aG9kID09PSAnSEVBRCcgfHwgcmVzLnN0YXR1c0NvZGUgPT09IDIwNCkge1xuICAgICAgICAgIGRlbGV0ZSByZXMuaGVhZGVyc1snY29udGVudC1lbmNvZGluZyddO1xuICAgICAgICB9XG5cbiAgICAgICAgc3dpdGNoICgocmVzLmhlYWRlcnNbJ2NvbnRlbnQtZW5jb2RpbmcnXSB8fCAnJykudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAvKmVzbGludCBkZWZhdWx0LWNhc2U6MCovXG4gICAgICAgIGNhc2UgJ2d6aXAnOlxuICAgICAgICBjYXNlICd4LWd6aXAnOlxuICAgICAgICBjYXNlICdjb21wcmVzcyc6XG4gICAgICAgIGNhc2UgJ3gtY29tcHJlc3MnOlxuICAgICAgICAgIC8vIGFkZCB0aGUgdW56aXBwZXIgdG8gdGhlIGJvZHkgc3RyZWFtIHByb2Nlc3NpbmcgcGlwZWxpbmVcbiAgICAgICAgICBzdHJlYW1zLnB1c2goemxpYl9fZGVmYXVsdFtcImRlZmF1bHRcIl0uY3JlYXRlVW56aXAoemxpYk9wdGlvbnMpKTtcblxuICAgICAgICAgIC8vIHJlbW92ZSB0aGUgY29udGVudC1lbmNvZGluZyBpbiBvcmRlciB0byBub3QgY29uZnVzZSBkb3duc3RyZWFtIG9wZXJhdGlvbnNcbiAgICAgICAgICBkZWxldGUgcmVzLmhlYWRlcnNbJ2NvbnRlbnQtZW5jb2RpbmcnXTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnZGVmbGF0ZSc6XG4gICAgICAgICAgc3RyZWFtcy5wdXNoKG5ldyBabGliSGVhZGVyVHJhbnNmb3JtU3RyZWFtJDEoKSk7XG5cbiAgICAgICAgICAvLyBhZGQgdGhlIHVuemlwcGVyIHRvIHRoZSBib2R5IHN0cmVhbSBwcm9jZXNzaW5nIHBpcGVsaW5lXG4gICAgICAgICAgc3RyZWFtcy5wdXNoKHpsaWJfX2RlZmF1bHRbXCJkZWZhdWx0XCJdLmNyZWF0ZVVuemlwKHpsaWJPcHRpb25zKSk7XG5cbiAgICAgICAgICAvLyByZW1vdmUgdGhlIGNvbnRlbnQtZW5jb2RpbmcgaW4gb3JkZXIgdG8gbm90IGNvbmZ1c2UgZG93bnN0cmVhbSBvcGVyYXRpb25zXG4gICAgICAgICAgZGVsZXRlIHJlcy5oZWFkZXJzWydjb250ZW50LWVuY29kaW5nJ107XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2JyJzpcbiAgICAgICAgICBpZiAoaXNCcm90bGlTdXBwb3J0ZWQpIHtcbiAgICAgICAgICAgIHN0cmVhbXMucHVzaCh6bGliX19kZWZhdWx0W1wiZGVmYXVsdFwiXS5jcmVhdGVCcm90bGlEZWNvbXByZXNzKGJyb3RsaU9wdGlvbnMpKTtcbiAgICAgICAgICAgIGRlbGV0ZSByZXMuaGVhZGVyc1snY29udGVudC1lbmNvZGluZyddO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXNwb25zZVN0cmVhbSA9IHN0cmVhbXMubGVuZ3RoID4gMSA/IHN0cmVhbV9fZGVmYXVsdFtcImRlZmF1bHRcIl0ucGlwZWxpbmUoc3RyZWFtcywgdXRpbHMubm9vcCkgOiBzdHJlYW1zWzBdO1xuXG4gICAgICBjb25zdCBvZmZMaXN0ZW5lcnMgPSBzdHJlYW1fX2RlZmF1bHRbXCJkZWZhdWx0XCJdLmZpbmlzaGVkKHJlc3BvbnNlU3RyZWFtLCAoKSA9PiB7XG4gICAgICAgIG9mZkxpc3RlbmVycygpO1xuICAgICAgICBvbkZpbmlzaGVkKCk7XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSB7XG4gICAgICAgIHN0YXR1czogcmVzLnN0YXR1c0NvZGUsXG4gICAgICAgIHN0YXR1c1RleHQ6IHJlcy5zdGF0dXNNZXNzYWdlLFxuICAgICAgICBoZWFkZXJzOiBuZXcgQXhpb3NIZWFkZXJzJDEocmVzLmhlYWRlcnMpLFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHJlcXVlc3Q6IGxhc3RSZXF1ZXN0XG4gICAgICB9O1xuXG4gICAgICBpZiAocmVzcG9uc2VUeXBlID09PSAnc3RyZWFtJykge1xuICAgICAgICByZXNwb25zZS5kYXRhID0gcmVzcG9uc2VTdHJlYW07XG4gICAgICAgIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHJlc3BvbnNlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlQnVmZmVyID0gW107XG4gICAgICAgIGxldCB0b3RhbFJlc3BvbnNlQnl0ZXMgPSAwO1xuXG4gICAgICAgIHJlc3BvbnNlU3RyZWFtLm9uKCdkYXRhJywgZnVuY3Rpb24gaGFuZGxlU3RyZWFtRGF0YShjaHVuaykge1xuICAgICAgICAgIHJlc3BvbnNlQnVmZmVyLnB1c2goY2h1bmspO1xuICAgICAgICAgIHRvdGFsUmVzcG9uc2VCeXRlcyArPSBjaHVuay5sZW5ndGg7XG5cbiAgICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIGNvbnRlbnQgbGVuZ3RoIGlzIG5vdCBvdmVyIHRoZSBtYXhDb250ZW50TGVuZ3RoIGlmIHNwZWNpZmllZFxuICAgICAgICAgIGlmIChjb25maWcubWF4Q29udGVudExlbmd0aCA+IC0xICYmIHRvdGFsUmVzcG9uc2VCeXRlcyA+IGNvbmZpZy5tYXhDb250ZW50TGVuZ3RoKSB7XG4gICAgICAgICAgICAvLyBzdHJlYW0uZGVzdHJveSgpIGVtaXQgYWJvcnRlZCBldmVudCBiZWZvcmUgY2FsbGluZyByZWplY3QoKSBvbiBOb2RlLmpzIHYxNlxuICAgICAgICAgICAgcmVqZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgcmVzcG9uc2VTdHJlYW0uZGVzdHJveSgpO1xuICAgICAgICAgICAgcmVqZWN0KG5ldyBBeGlvc0Vycm9yKCdtYXhDb250ZW50TGVuZ3RoIHNpemUgb2YgJyArIGNvbmZpZy5tYXhDb250ZW50TGVuZ3RoICsgJyBleGNlZWRlZCcsXG4gICAgICAgICAgICAgIEF4aW9zRXJyb3IuRVJSX0JBRF9SRVNQT05TRSwgY29uZmlnLCBsYXN0UmVxdWVzdCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmVzcG9uc2VTdHJlYW0ub24oJ2Fib3J0ZWQnLCBmdW5jdGlvbiBoYW5kbGVyU3RyZWFtQWJvcnRlZCgpIHtcbiAgICAgICAgICBpZiAocmVqZWN0ZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBlcnIgPSBuZXcgQXhpb3NFcnJvcihcbiAgICAgICAgICAgICdtYXhDb250ZW50TGVuZ3RoIHNpemUgb2YgJyArIGNvbmZpZy5tYXhDb250ZW50TGVuZ3RoICsgJyBleGNlZWRlZCcsXG4gICAgICAgICAgICBBeGlvc0Vycm9yLkVSUl9CQURfUkVTUE9OU0UsXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBsYXN0UmVxdWVzdFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmVzcG9uc2VTdHJlYW0uZGVzdHJveShlcnIpO1xuICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXNwb25zZVN0cmVhbS5vbignZXJyb3InLCBmdW5jdGlvbiBoYW5kbGVTdHJlYW1FcnJvcihlcnIpIHtcbiAgICAgICAgICBpZiAocmVxLmRlc3Ryb3llZCkgcmV0dXJuO1xuICAgICAgICAgIHJlamVjdChBeGlvc0Vycm9yLmZyb20oZXJyLCBudWxsLCBjb25maWcsIGxhc3RSZXF1ZXN0KSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJlc3BvbnNlU3RyZWFtLm9uKCdlbmQnLCBmdW5jdGlvbiBoYW5kbGVTdHJlYW1FbmQoKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGxldCByZXNwb25zZURhdGEgPSByZXNwb25zZUJ1ZmZlci5sZW5ndGggPT09IDEgPyByZXNwb25zZUJ1ZmZlclswXSA6IEJ1ZmZlci5jb25jYXQocmVzcG9uc2VCdWZmZXIpO1xuICAgICAgICAgICAgaWYgKHJlc3BvbnNlVHlwZSAhPT0gJ2FycmF5YnVmZmVyJykge1xuICAgICAgICAgICAgICByZXNwb25zZURhdGEgPSByZXNwb25zZURhdGEudG9TdHJpbmcocmVzcG9uc2VFbmNvZGluZyk7XG4gICAgICAgICAgICAgIGlmICghcmVzcG9uc2VFbmNvZGluZyB8fCByZXNwb25zZUVuY29kaW5nID09PSAndXRmOCcpIHtcbiAgICAgICAgICAgICAgICByZXNwb25zZURhdGEgPSB1dGlscy5zdHJpcEJPTShyZXNwb25zZURhdGEpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXNwb25zZS5kYXRhID0gcmVzcG9uc2VEYXRhO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgcmV0dXJuIHJlamVjdChBeGlvc0Vycm9yLmZyb20oZXJyLCBudWxsLCBjb25maWcsIHJlc3BvbnNlLnJlcXVlc3QsIHJlc3BvbnNlKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHJlc3BvbnNlKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGVtaXR0ZXIub25jZSgnYWJvcnQnLCBlcnIgPT4ge1xuICAgICAgICBpZiAoIXJlc3BvbnNlU3RyZWFtLmRlc3Ryb3llZCkge1xuICAgICAgICAgIHJlc3BvbnNlU3RyZWFtLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICAgICAgICByZXNwb25zZVN0cmVhbS5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZW1pdHRlci5vbmNlKCdhYm9ydCcsIGVyciA9PiB7XG4gICAgICByZWplY3QoZXJyKTtcbiAgICAgIHJlcS5kZXN0cm95KGVycik7XG4gICAgfSk7XG5cbiAgICAvLyBIYW5kbGUgZXJyb3JzXG4gICAgcmVxLm9uKCdlcnJvcicsIGZ1bmN0aW9uIGhhbmRsZVJlcXVlc3RFcnJvcihlcnIpIHtcbiAgICAgIC8vIEB0b2RvIHJlbW92ZVxuICAgICAgLy8gaWYgKHJlcS5hYm9ydGVkICYmIGVyci5jb2RlICE9PSBBeGlvc0Vycm9yLkVSUl9GUl9UT09fTUFOWV9SRURJUkVDVFMpIHJldHVybjtcbiAgICAgIHJlamVjdChBeGlvc0Vycm9yLmZyb20oZXJyLCBudWxsLCBjb25maWcsIHJlcSkpO1xuICAgIH0pO1xuXG4gICAgLy8gc2V0IHRjcCBrZWVwIGFsaXZlIHRvIHByZXZlbnQgZHJvcCBjb25uZWN0aW9uIGJ5IHBlZXJcbiAgICByZXEub24oJ3NvY2tldCcsIGZ1bmN0aW9uIGhhbmRsZVJlcXVlc3RTb2NrZXQoc29ja2V0KSB7XG4gICAgICAvLyBkZWZhdWx0IGludGVydmFsIG9mIHNlbmRpbmcgYWNrIHBhY2tldCBpcyAxIG1pbnV0ZVxuICAgICAgc29ja2V0LnNldEtlZXBBbGl2ZSh0cnVlLCAxMDAwICogNjApO1xuICAgIH0pO1xuXG4gICAgLy8gSGFuZGxlIHJlcXVlc3QgdGltZW91dFxuICAgIGlmIChjb25maWcudGltZW91dCkge1xuICAgICAgLy8gVGhpcyBpcyBmb3JjaW5nIGEgaW50IHRpbWVvdXQgdG8gYXZvaWQgcHJvYmxlbXMgaWYgdGhlIGByZXFgIGludGVyZmFjZSBkb2Vzbid0IGhhbmRsZSBvdGhlciB0eXBlcy5cbiAgICAgIGNvbnN0IHRpbWVvdXQgPSBwYXJzZUludChjb25maWcudGltZW91dCwgMTApO1xuXG4gICAgICBpZiAoTnVtYmVyLmlzTmFOKHRpbWVvdXQpKSB7XG4gICAgICAgIHJlamVjdChuZXcgQXhpb3NFcnJvcihcbiAgICAgICAgICAnZXJyb3IgdHJ5aW5nIHRvIHBhcnNlIGBjb25maWcudGltZW91dGAgdG8gaW50JyxcbiAgICAgICAgICBBeGlvc0Vycm9yLkVSUl9CQURfT1BUSU9OX1ZBTFVFLFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICByZXFcbiAgICAgICAgKSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBTb21ldGltZSwgdGhlIHJlc3BvbnNlIHdpbGwgYmUgdmVyeSBzbG93LCBhbmQgZG9lcyBub3QgcmVzcG9uZCwgdGhlIGNvbm5lY3QgZXZlbnQgd2lsbCBiZSBibG9jayBieSBldmVudCBsb29wIHN5c3RlbS5cbiAgICAgIC8vIEFuZCB0aW1lciBjYWxsYmFjayB3aWxsIGJlIGZpcmVkLCBhbmQgYWJvcnQoKSB3aWxsIGJlIGludm9rZWQgYmVmb3JlIGNvbm5lY3Rpb24sIHRoZW4gZ2V0IFwic29ja2V0IGhhbmcgdXBcIiBhbmQgY29kZSBFQ09OTlJFU0VULlxuICAgICAgLy8gQXQgdGhpcyB0aW1lLCBpZiB3ZSBoYXZlIGEgbGFyZ2UgbnVtYmVyIG9mIHJlcXVlc3QsIG5vZGVqcyB3aWxsIGhhbmcgdXAgc29tZSBzb2NrZXQgb24gYmFja2dyb3VuZC4gYW5kIHRoZSBudW1iZXIgd2lsbCB1cCBhbmQgdXAuXG4gICAgICAvLyBBbmQgdGhlbiB0aGVzZSBzb2NrZXQgd2hpY2ggYmUgaGFuZyB1cCB3aWxsIGRldm91cmluZyBDUFUgbGl0dGxlIGJ5IGxpdHRsZS5cbiAgICAgIC8vIENsaWVudFJlcXVlc3Quc2V0VGltZW91dCB3aWxsIGJlIGZpcmVkIG9uIHRoZSBzcGVjaWZ5IG1pbGxpc2Vjb25kcywgYW5kIGNhbiBtYWtlIHN1cmUgdGhhdCBhYm9ydCgpIHdpbGwgYmUgZmlyZWQgYWZ0ZXIgY29ubmVjdC5cbiAgICAgIHJlcS5zZXRUaW1lb3V0KHRpbWVvdXQsIGZ1bmN0aW9uIGhhbmRsZVJlcXVlc3RUaW1lb3V0KCkge1xuICAgICAgICBpZiAoaXNEb25lKSByZXR1cm47XG4gICAgICAgIGxldCB0aW1lb3V0RXJyb3JNZXNzYWdlID0gY29uZmlnLnRpbWVvdXQgPyAndGltZW91dCBvZiAnICsgY29uZmlnLnRpbWVvdXQgKyAnbXMgZXhjZWVkZWQnIDogJ3RpbWVvdXQgZXhjZWVkZWQnO1xuICAgICAgICBjb25zdCB0cmFuc2l0aW9uYWwgPSBjb25maWcudHJhbnNpdGlvbmFsIHx8IHRyYW5zaXRpb25hbERlZmF1bHRzO1xuICAgICAgICBpZiAoY29uZmlnLnRpbWVvdXRFcnJvck1lc3NhZ2UpIHtcbiAgICAgICAgICB0aW1lb3V0RXJyb3JNZXNzYWdlID0gY29uZmlnLnRpbWVvdXRFcnJvck1lc3NhZ2U7XG4gICAgICAgIH1cbiAgICAgICAgcmVqZWN0KG5ldyBBeGlvc0Vycm9yKFxuICAgICAgICAgIHRpbWVvdXRFcnJvck1lc3NhZ2UsXG4gICAgICAgICAgdHJhbnNpdGlvbmFsLmNsYXJpZnlUaW1lb3V0RXJyb3IgPyBBeGlvc0Vycm9yLkVUSU1FRE9VVCA6IEF4aW9zRXJyb3IuRUNPTk5BQk9SVEVELFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICByZXFcbiAgICAgICAgKSk7XG4gICAgICAgIGFib3J0KCk7XG4gICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8vIFNlbmQgdGhlIHJlcXVlc3RcbiAgICBpZiAodXRpbHMuaXNTdHJlYW0oZGF0YSkpIHtcbiAgICAgIGxldCBlbmRlZCA9IGZhbHNlO1xuICAgICAgbGV0IGVycm9yZWQgPSBmYWxzZTtcblxuICAgICAgZGF0YS5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICBlbmRlZCA9IHRydWU7XG4gICAgICB9KTtcblxuICAgICAgZGF0YS5vbmNlKCdlcnJvcicsIGVyciA9PiB7XG4gICAgICAgIGVycm9yZWQgPSB0cnVlO1xuICAgICAgICByZXEuZGVzdHJveShlcnIpO1xuICAgICAgfSk7XG5cbiAgICAgIGRhdGEub24oJ2Nsb3NlJywgKCkgPT4ge1xuICAgICAgICBpZiAoIWVuZGVkICYmICFlcnJvcmVkKSB7XG4gICAgICAgICAgYWJvcnQobmV3IENhbmNlbGVkRXJyb3IoJ1JlcXVlc3Qgc3RyZWFtIGhhcyBiZWVuIGFib3J0ZWQnLCBjb25maWcsIHJlcSkpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgZGF0YS5waXBlKHJlcSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlcS5lbmQoZGF0YSk7XG4gICAgfVxuICB9KTtcbn07XG5cbmNvbnN0IGNvb2tpZXMgPSBwbGF0Zm9ybS5pc1N0YW5kYXJkQnJvd3NlckVudiA/XG5cbi8vIFN0YW5kYXJkIGJyb3dzZXIgZW52cyBzdXBwb3J0IGRvY3VtZW50LmNvb2tpZVxuICAoZnVuY3Rpb24gc3RhbmRhcmRCcm93c2VyRW52KCkge1xuICAgIHJldHVybiB7XG4gICAgICB3cml0ZTogZnVuY3Rpb24gd3JpdGUobmFtZSwgdmFsdWUsIGV4cGlyZXMsIHBhdGgsIGRvbWFpbiwgc2VjdXJlKSB7XG4gICAgICAgIGNvbnN0IGNvb2tpZSA9IFtdO1xuICAgICAgICBjb29raWUucHVzaChuYW1lICsgJz0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKSk7XG5cbiAgICAgICAgaWYgKHV0aWxzLmlzTnVtYmVyKGV4cGlyZXMpKSB7XG4gICAgICAgICAgY29va2llLnB1c2goJ2V4cGlyZXM9JyArIG5ldyBEYXRlKGV4cGlyZXMpLnRvR01UU3RyaW5nKCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHV0aWxzLmlzU3RyaW5nKHBhdGgpKSB7XG4gICAgICAgICAgY29va2llLnB1c2goJ3BhdGg9JyArIHBhdGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHV0aWxzLmlzU3RyaW5nKGRvbWFpbikpIHtcbiAgICAgICAgICBjb29raWUucHVzaCgnZG9tYWluPScgKyBkb21haW4pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNlY3VyZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgIGNvb2tpZS5wdXNoKCdzZWN1cmUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRvY3VtZW50LmNvb2tpZSA9IGNvb2tpZS5qb2luKCc7ICcpO1xuICAgICAgfSxcblxuICAgICAgcmVhZDogZnVuY3Rpb24gcmVhZChuYW1lKSB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gZG9jdW1lbnQuY29va2llLm1hdGNoKG5ldyBSZWdFeHAoJyhefDtcXFxccyopKCcgKyBuYW1lICsgJyk9KFteO10qKScpKTtcbiAgICAgICAgcmV0dXJuIChtYXRjaCA/IGRlY29kZVVSSUNvbXBvbmVudChtYXRjaFszXSkgOiBudWxsKTtcbiAgICAgIH0sXG5cbiAgICAgIHJlbW92ZTogZnVuY3Rpb24gcmVtb3ZlKG5hbWUpIHtcbiAgICAgICAgdGhpcy53cml0ZShuYW1lLCAnJywgRGF0ZS5ub3coKSAtIDg2NDAwMDAwKTtcbiAgICAgIH1cbiAgICB9O1xuICB9KSgpIDpcblxuLy8gTm9uIHN0YW5kYXJkIGJyb3dzZXIgZW52ICh3ZWIgd29ya2VycywgcmVhY3QtbmF0aXZlKSBsYWNrIG5lZWRlZCBzdXBwb3J0LlxuICAoZnVuY3Rpb24gbm9uU3RhbmRhcmRCcm93c2VyRW52KCkge1xuICAgIHJldHVybiB7XG4gICAgICB3cml0ZTogZnVuY3Rpb24gd3JpdGUoKSB7fSxcbiAgICAgIHJlYWQ6IGZ1bmN0aW9uIHJlYWQoKSB7IHJldHVybiBudWxsOyB9LFxuICAgICAgcmVtb3ZlOiBmdW5jdGlvbiByZW1vdmUoKSB7fVxuICAgIH07XG4gIH0pKCk7XG5cbmNvbnN0IGlzVVJMU2FtZU9yaWdpbiA9IHBsYXRmb3JtLmlzU3RhbmRhcmRCcm93c2VyRW52ID9cblxuLy8gU3RhbmRhcmQgYnJvd3NlciBlbnZzIGhhdmUgZnVsbCBzdXBwb3J0IG9mIHRoZSBBUElzIG5lZWRlZCB0byB0ZXN0XG4vLyB3aGV0aGVyIHRoZSByZXF1ZXN0IFVSTCBpcyBvZiB0aGUgc2FtZSBvcmlnaW4gYXMgY3VycmVudCBsb2NhdGlvbi5cbiAgKGZ1bmN0aW9uIHN0YW5kYXJkQnJvd3NlckVudigpIHtcbiAgICBjb25zdCBtc2llID0gLyhtc2llfHRyaWRlbnQpL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgICBjb25zdCB1cmxQYXJzaW5nTm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICBsZXQgb3JpZ2luVVJMO1xuXG4gICAgLyoqXG4gICAgKiBQYXJzZSBhIFVSTCB0byBkaXNjb3ZlciBpdCdzIGNvbXBvbmVudHNcbiAgICAqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gdXJsIFRoZSBVUkwgdG8gYmUgcGFyc2VkXG4gICAgKiBAcmV0dXJucyB7T2JqZWN0fVxuICAgICovXG4gICAgZnVuY3Rpb24gcmVzb2x2ZVVSTCh1cmwpIHtcbiAgICAgIGxldCBocmVmID0gdXJsO1xuXG4gICAgICBpZiAobXNpZSkge1xuICAgICAgICAvLyBJRSBuZWVkcyBhdHRyaWJ1dGUgc2V0IHR3aWNlIHRvIG5vcm1hbGl6ZSBwcm9wZXJ0aWVzXG4gICAgICAgIHVybFBhcnNpbmdOb2RlLnNldEF0dHJpYnV0ZSgnaHJlZicsIGhyZWYpO1xuICAgICAgICBocmVmID0gdXJsUGFyc2luZ05vZGUuaHJlZjtcbiAgICAgIH1cblxuICAgICAgdXJsUGFyc2luZ05vZGUuc2V0QXR0cmlidXRlKCdocmVmJywgaHJlZik7XG5cbiAgICAgIC8vIHVybFBhcnNpbmdOb2RlIHByb3ZpZGVzIHRoZSBVcmxVdGlscyBpbnRlcmZhY2UgLSBodHRwOi8vdXJsLnNwZWMud2hhdHdnLm9yZy8jdXJsdXRpbHNcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGhyZWY6IHVybFBhcnNpbmdOb2RlLmhyZWYsXG4gICAgICAgIHByb3RvY29sOiB1cmxQYXJzaW5nTm9kZS5wcm90b2NvbCA/IHVybFBhcnNpbmdOb2RlLnByb3RvY29sLnJlcGxhY2UoLzokLywgJycpIDogJycsXG4gICAgICAgIGhvc3Q6IHVybFBhcnNpbmdOb2RlLmhvc3QsXG4gICAgICAgIHNlYXJjaDogdXJsUGFyc2luZ05vZGUuc2VhcmNoID8gdXJsUGFyc2luZ05vZGUuc2VhcmNoLnJlcGxhY2UoL15cXD8vLCAnJykgOiAnJyxcbiAgICAgICAgaGFzaDogdXJsUGFyc2luZ05vZGUuaGFzaCA/IHVybFBhcnNpbmdOb2RlLmhhc2gucmVwbGFjZSgvXiMvLCAnJykgOiAnJyxcbiAgICAgICAgaG9zdG5hbWU6IHVybFBhcnNpbmdOb2RlLmhvc3RuYW1lLFxuICAgICAgICBwb3J0OiB1cmxQYXJzaW5nTm9kZS5wb3J0LFxuICAgICAgICBwYXRobmFtZTogKHVybFBhcnNpbmdOb2RlLnBhdGhuYW1lLmNoYXJBdCgwKSA9PT0gJy8nKSA/XG4gICAgICAgICAgdXJsUGFyc2luZ05vZGUucGF0aG5hbWUgOlxuICAgICAgICAgICcvJyArIHVybFBhcnNpbmdOb2RlLnBhdGhuYW1lXG4gICAgICB9O1xuICAgIH1cblxuICAgIG9yaWdpblVSTCA9IHJlc29sdmVVUkwod2luZG93LmxvY2F0aW9uLmhyZWYpO1xuXG4gICAgLyoqXG4gICAgKiBEZXRlcm1pbmUgaWYgYSBVUkwgc2hhcmVzIHRoZSBzYW1lIG9yaWdpbiBhcyB0aGUgY3VycmVudCBsb2NhdGlvblxuICAgICpcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSByZXF1ZXN0VVJMIFRoZSBVUkwgdG8gdGVzdFxuICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgVVJMIHNoYXJlcyB0aGUgc2FtZSBvcmlnaW4sIG90aGVyd2lzZSBmYWxzZVxuICAgICovXG4gICAgcmV0dXJuIGZ1bmN0aW9uIGlzVVJMU2FtZU9yaWdpbihyZXF1ZXN0VVJMKSB7XG4gICAgICBjb25zdCBwYXJzZWQgPSAodXRpbHMuaXNTdHJpbmcocmVxdWVzdFVSTCkpID8gcmVzb2x2ZVVSTChyZXF1ZXN0VVJMKSA6IHJlcXVlc3RVUkw7XG4gICAgICByZXR1cm4gKHBhcnNlZC5wcm90b2NvbCA9PT0gb3JpZ2luVVJMLnByb3RvY29sICYmXG4gICAgICAgICAgcGFyc2VkLmhvc3QgPT09IG9yaWdpblVSTC5ob3N0KTtcbiAgICB9O1xuICB9KSgpIDpcblxuICAvLyBOb24gc3RhbmRhcmQgYnJvd3NlciBlbnZzICh3ZWIgd29ya2VycywgcmVhY3QtbmF0aXZlKSBsYWNrIG5lZWRlZCBzdXBwb3J0LlxuICAoZnVuY3Rpb24gbm9uU3RhbmRhcmRCcm93c2VyRW52KCkge1xuICAgIHJldHVybiBmdW5jdGlvbiBpc1VSTFNhbWVPcmlnaW4oKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuICB9KSgpO1xuXG5mdW5jdGlvbiBwcm9ncmVzc0V2ZW50UmVkdWNlcihsaXN0ZW5lciwgaXNEb3dubG9hZFN0cmVhbSkge1xuICBsZXQgYnl0ZXNOb3RpZmllZCA9IDA7XG4gIGNvbnN0IF9zcGVlZG9tZXRlciA9IHNwZWVkb21ldGVyKDUwLCAyNTApO1xuXG4gIHJldHVybiBlID0+IHtcbiAgICBjb25zdCBsb2FkZWQgPSBlLmxvYWRlZDtcbiAgICBjb25zdCB0b3RhbCA9IGUubGVuZ3RoQ29tcHV0YWJsZSA/IGUudG90YWwgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgcHJvZ3Jlc3NCeXRlcyA9IGxvYWRlZCAtIGJ5dGVzTm90aWZpZWQ7XG4gICAgY29uc3QgcmF0ZSA9IF9zcGVlZG9tZXRlcihwcm9ncmVzc0J5dGVzKTtcbiAgICBjb25zdCBpblJhbmdlID0gbG9hZGVkIDw9IHRvdGFsO1xuXG4gICAgYnl0ZXNOb3RpZmllZCA9IGxvYWRlZDtcblxuICAgIGNvbnN0IGRhdGEgPSB7XG4gICAgICBsb2FkZWQsXG4gICAgICB0b3RhbCxcbiAgICAgIHByb2dyZXNzOiB0b3RhbCA/IChsb2FkZWQgLyB0b3RhbCkgOiB1bmRlZmluZWQsXG4gICAgICBieXRlczogcHJvZ3Jlc3NCeXRlcyxcbiAgICAgIHJhdGU6IHJhdGUgPyByYXRlIDogdW5kZWZpbmVkLFxuICAgICAgZXN0aW1hdGVkOiByYXRlICYmIHRvdGFsICYmIGluUmFuZ2UgPyAodG90YWwgLSBsb2FkZWQpIC8gcmF0ZSA6IHVuZGVmaW5lZCxcbiAgICAgIGV2ZW50OiBlXG4gICAgfTtcblxuICAgIGRhdGFbaXNEb3dubG9hZFN0cmVhbSA/ICdkb3dubG9hZCcgOiAndXBsb2FkJ10gPSB0cnVlO1xuXG4gICAgbGlzdGVuZXIoZGF0YSk7XG4gIH07XG59XG5cbmNvbnN0IGlzWEhSQWRhcHRlclN1cHBvcnRlZCA9IHR5cGVvZiBYTUxIdHRwUmVxdWVzdCAhPT0gJ3VuZGVmaW5lZCc7XG5cbmNvbnN0IHhockFkYXB0ZXIgPSBpc1hIUkFkYXB0ZXJTdXBwb3J0ZWQgJiYgZnVuY3Rpb24gKGNvbmZpZykge1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gZGlzcGF0Y2hYaHJSZXF1ZXN0KHJlc29sdmUsIHJlamVjdCkge1xuICAgIGxldCByZXF1ZXN0RGF0YSA9IGNvbmZpZy5kYXRhO1xuICAgIGNvbnN0IHJlcXVlc3RIZWFkZXJzID0gQXhpb3NIZWFkZXJzJDEuZnJvbShjb25maWcuaGVhZGVycykubm9ybWFsaXplKCk7XG4gICAgY29uc3QgcmVzcG9uc2VUeXBlID0gY29uZmlnLnJlc3BvbnNlVHlwZTtcbiAgICBsZXQgb25DYW5jZWxlZDtcbiAgICBmdW5jdGlvbiBkb25lKCkge1xuICAgICAgaWYgKGNvbmZpZy5jYW5jZWxUb2tlbikge1xuICAgICAgICBjb25maWcuY2FuY2VsVG9rZW4udW5zdWJzY3JpYmUob25DYW5jZWxlZCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcuc2lnbmFsKSB7XG4gICAgICAgIGNvbmZpZy5zaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkNhbmNlbGVkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgY29udGVudFR5cGU7XG5cbiAgICBpZiAodXRpbHMuaXNGb3JtRGF0YShyZXF1ZXN0RGF0YSkpIHtcbiAgICAgIGlmIChwbGF0Zm9ybS5pc1N0YW5kYXJkQnJvd3NlckVudiB8fCBwbGF0Zm9ybS5pc1N0YW5kYXJkQnJvd3NlcldlYldvcmtlckVudikge1xuICAgICAgICByZXF1ZXN0SGVhZGVycy5zZXRDb250ZW50VHlwZShmYWxzZSk7IC8vIExldCB0aGUgYnJvd3NlciBzZXQgaXRcbiAgICAgIH0gZWxzZSBpZighcmVxdWVzdEhlYWRlcnMuZ2V0Q29udGVudFR5cGUoL15cXHMqbXVsdGlwYXJ0XFwvZm9ybS1kYXRhLykpe1xuICAgICAgICByZXF1ZXN0SGVhZGVycy5zZXRDb250ZW50VHlwZSgnbXVsdGlwYXJ0L2Zvcm0tZGF0YScpOyAvLyBtb2JpbGUvZGVza3RvcCBhcHAgZnJhbWV3b3Jrc1xuICAgICAgfSBlbHNlIGlmKHV0aWxzLmlzU3RyaW5nKGNvbnRlbnRUeXBlID0gcmVxdWVzdEhlYWRlcnMuZ2V0Q29udGVudFR5cGUoKSkpe1xuICAgICAgICAvLyBmaXggc2VtaWNvbG9uIGR1cGxpY2F0aW9uIGlzc3VlIGZvciBSZWFjdE5hdGl2ZSBGb3JtRGF0YSBpbXBsZW1lbnRhdGlvblxuICAgICAgICByZXF1ZXN0SGVhZGVycy5zZXRDb250ZW50VHlwZShjb250ZW50VHlwZS5yZXBsYWNlKC9eXFxzKihtdWx0aXBhcnRcXC9mb3JtLWRhdGEpOysvLCAnJDEnKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGV0IHJlcXVlc3QgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcblxuICAgIC8vIEhUVFAgYmFzaWMgYXV0aGVudGljYXRpb25cbiAgICBpZiAoY29uZmlnLmF1dGgpIHtcbiAgICAgIGNvbnN0IHVzZXJuYW1lID0gY29uZmlnLmF1dGgudXNlcm5hbWUgfHwgJyc7XG4gICAgICBjb25zdCBwYXNzd29yZCA9IGNvbmZpZy5hdXRoLnBhc3N3b3JkID8gdW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KGNvbmZpZy5hdXRoLnBhc3N3b3JkKSkgOiAnJztcbiAgICAgIHJlcXVlc3RIZWFkZXJzLnNldCgnQXV0aG9yaXphdGlvbicsICdCYXNpYyAnICsgYnRvYSh1c2VybmFtZSArICc6JyArIHBhc3N3b3JkKSk7XG4gICAgfVxuXG4gICAgY29uc3QgZnVsbFBhdGggPSBidWlsZEZ1bGxQYXRoKGNvbmZpZy5iYXNlVVJMLCBjb25maWcudXJsKTtcblxuICAgIHJlcXVlc3Qub3Blbihjb25maWcubWV0aG9kLnRvVXBwZXJDYXNlKCksIGJ1aWxkVVJMKGZ1bGxQYXRoLCBjb25maWcucGFyYW1zLCBjb25maWcucGFyYW1zU2VyaWFsaXplciksIHRydWUpO1xuXG4gICAgLy8gU2V0IHRoZSByZXF1ZXN0IHRpbWVvdXQgaW4gTVNcbiAgICByZXF1ZXN0LnRpbWVvdXQgPSBjb25maWcudGltZW91dDtcblxuICAgIGZ1bmN0aW9uIG9ubG9hZGVuZCgpIHtcbiAgICAgIGlmICghcmVxdWVzdCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICAvLyBQcmVwYXJlIHRoZSByZXNwb25zZVxuICAgICAgY29uc3QgcmVzcG9uc2VIZWFkZXJzID0gQXhpb3NIZWFkZXJzJDEuZnJvbShcbiAgICAgICAgJ2dldEFsbFJlc3BvbnNlSGVhZGVycycgaW4gcmVxdWVzdCAmJiByZXF1ZXN0LmdldEFsbFJlc3BvbnNlSGVhZGVycygpXG4gICAgICApO1xuICAgICAgY29uc3QgcmVzcG9uc2VEYXRhID0gIXJlc3BvbnNlVHlwZSB8fCByZXNwb25zZVR5cGUgPT09ICd0ZXh0JyB8fCByZXNwb25zZVR5cGUgPT09ICdqc29uJyA/XG4gICAgICAgIHJlcXVlc3QucmVzcG9uc2VUZXh0IDogcmVxdWVzdC5yZXNwb25zZTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0ge1xuICAgICAgICBkYXRhOiByZXNwb25zZURhdGEsXG4gICAgICAgIHN0YXR1czogcmVxdWVzdC5zdGF0dXMsXG4gICAgICAgIHN0YXR1c1RleHQ6IHJlcXVlc3Quc3RhdHVzVGV4dCxcbiAgICAgICAgaGVhZGVyczogcmVzcG9uc2VIZWFkZXJzLFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHJlcXVlc3RcbiAgICAgIH07XG5cbiAgICAgIHNldHRsZShmdW5jdGlvbiBfcmVzb2x2ZSh2YWx1ZSkge1xuICAgICAgICByZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgZG9uZSgpO1xuICAgICAgfSwgZnVuY3Rpb24gX3JlamVjdChlcnIpIHtcbiAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgIGRvbmUoKTtcbiAgICAgIH0sIHJlc3BvbnNlKTtcblxuICAgICAgLy8gQ2xlYW4gdXAgcmVxdWVzdFxuICAgICAgcmVxdWVzdCA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKCdvbmxvYWRlbmQnIGluIHJlcXVlc3QpIHtcbiAgICAgIC8vIFVzZSBvbmxvYWRlbmQgaWYgYXZhaWxhYmxlXG4gICAgICByZXF1ZXN0Lm9ubG9hZGVuZCA9IG9ubG9hZGVuZDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTGlzdGVuIGZvciByZWFkeSBzdGF0ZSB0byBlbXVsYXRlIG9ubG9hZGVuZFxuICAgICAgcmVxdWVzdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiBoYW5kbGVMb2FkKCkge1xuICAgICAgICBpZiAoIXJlcXVlc3QgfHwgcmVxdWVzdC5yZWFkeVN0YXRlICE9PSA0KSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVGhlIHJlcXVlc3QgZXJyb3JlZCBvdXQgYW5kIHdlIGRpZG4ndCBnZXQgYSByZXNwb25zZSwgdGhpcyB3aWxsIGJlXG4gICAgICAgIC8vIGhhbmRsZWQgYnkgb25lcnJvciBpbnN0ZWFkXG4gICAgICAgIC8vIFdpdGggb25lIGV4Y2VwdGlvbjogcmVxdWVzdCB0aGF0IHVzaW5nIGZpbGU6IHByb3RvY29sLCBtb3N0IGJyb3dzZXJzXG4gICAgICAgIC8vIHdpbGwgcmV0dXJuIHN0YXR1cyBhcyAwIGV2ZW4gdGhvdWdoIGl0J3MgYSBzdWNjZXNzZnVsIHJlcXVlc3RcbiAgICAgICAgaWYgKHJlcXVlc3Quc3RhdHVzID09PSAwICYmICEocmVxdWVzdC5yZXNwb25zZVVSTCAmJiByZXF1ZXN0LnJlc3BvbnNlVVJMLmluZGV4T2YoJ2ZpbGU6JykgPT09IDApKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIHJlYWR5c3RhdGUgaGFuZGxlciBpcyBjYWxsaW5nIGJlZm9yZSBvbmVycm9yIG9yIG9udGltZW91dCBoYW5kbGVycyxcbiAgICAgICAgLy8gc28gd2Ugc2hvdWxkIGNhbGwgb25sb2FkZW5kIG9uIHRoZSBuZXh0ICd0aWNrJ1xuICAgICAgICBzZXRUaW1lb3V0KG9ubG9hZGVuZCk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSBicm93c2VyIHJlcXVlc3QgY2FuY2VsbGF0aW9uIChhcyBvcHBvc2VkIHRvIGEgbWFudWFsIGNhbmNlbGxhdGlvbilcbiAgICByZXF1ZXN0Lm9uYWJvcnQgPSBmdW5jdGlvbiBoYW5kbGVBYm9ydCgpIHtcbiAgICAgIGlmICghcmVxdWVzdCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHJlamVjdChuZXcgQXhpb3NFcnJvcignUmVxdWVzdCBhYm9ydGVkJywgQXhpb3NFcnJvci5FQ09OTkFCT1JURUQsIGNvbmZpZywgcmVxdWVzdCkpO1xuXG4gICAgICAvLyBDbGVhbiB1cCByZXF1ZXN0XG4gICAgICByZXF1ZXN0ID0gbnVsbDtcbiAgICB9O1xuXG4gICAgLy8gSGFuZGxlIGxvdyBsZXZlbCBuZXR3b3JrIGVycm9yc1xuICAgIHJlcXVlc3Qub25lcnJvciA9IGZ1bmN0aW9uIGhhbmRsZUVycm9yKCkge1xuICAgICAgLy8gUmVhbCBlcnJvcnMgYXJlIGhpZGRlbiBmcm9tIHVzIGJ5IHRoZSBicm93c2VyXG4gICAgICAvLyBvbmVycm9yIHNob3VsZCBvbmx5IGZpcmUgaWYgaXQncyBhIG5ldHdvcmsgZXJyb3JcbiAgICAgIHJlamVjdChuZXcgQXhpb3NFcnJvcignTmV0d29yayBFcnJvcicsIEF4aW9zRXJyb3IuRVJSX05FVFdPUkssIGNvbmZpZywgcmVxdWVzdCkpO1xuXG4gICAgICAvLyBDbGVhbiB1cCByZXF1ZXN0XG4gICAgICByZXF1ZXN0ID0gbnVsbDtcbiAgICB9O1xuXG4gICAgLy8gSGFuZGxlIHRpbWVvdXRcbiAgICByZXF1ZXN0Lm9udGltZW91dCA9IGZ1bmN0aW9uIGhhbmRsZVRpbWVvdXQoKSB7XG4gICAgICBsZXQgdGltZW91dEVycm9yTWVzc2FnZSA9IGNvbmZpZy50aW1lb3V0ID8gJ3RpbWVvdXQgb2YgJyArIGNvbmZpZy50aW1lb3V0ICsgJ21zIGV4Y2VlZGVkJyA6ICd0aW1lb3V0IGV4Y2VlZGVkJztcbiAgICAgIGNvbnN0IHRyYW5zaXRpb25hbCA9IGNvbmZpZy50cmFuc2l0aW9uYWwgfHwgdHJhbnNpdGlvbmFsRGVmYXVsdHM7XG4gICAgICBpZiAoY29uZmlnLnRpbWVvdXRFcnJvck1lc3NhZ2UpIHtcbiAgICAgICAgdGltZW91dEVycm9yTWVzc2FnZSA9IGNvbmZpZy50aW1lb3V0RXJyb3JNZXNzYWdlO1xuICAgICAgfVxuICAgICAgcmVqZWN0KG5ldyBBeGlvc0Vycm9yKFxuICAgICAgICB0aW1lb3V0RXJyb3JNZXNzYWdlLFxuICAgICAgICB0cmFuc2l0aW9uYWwuY2xhcmlmeVRpbWVvdXRFcnJvciA/IEF4aW9zRXJyb3IuRVRJTUVET1VUIDogQXhpb3NFcnJvci5FQ09OTkFCT1JURUQsXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgcmVxdWVzdCkpO1xuXG4gICAgICAvLyBDbGVhbiB1cCByZXF1ZXN0XG4gICAgICByZXF1ZXN0ID0gbnVsbDtcbiAgICB9O1xuXG4gICAgLy8gQWRkIHhzcmYgaGVhZGVyXG4gICAgLy8gVGhpcyBpcyBvbmx5IGRvbmUgaWYgcnVubmluZyBpbiBhIHN0YW5kYXJkIGJyb3dzZXIgZW52aXJvbm1lbnQuXG4gICAgLy8gU3BlY2lmaWNhbGx5IG5vdCBpZiB3ZSdyZSBpbiBhIHdlYiB3b3JrZXIsIG9yIHJlYWN0LW5hdGl2ZS5cbiAgICBpZiAocGxhdGZvcm0uaXNTdGFuZGFyZEJyb3dzZXJFbnYpIHtcbiAgICAgIC8vIEFkZCB4c3JmIGhlYWRlclxuICAgICAgLy8gcmVnYXJkaW5nIENWRS0yMDIzLTQ1ODU3IGNvbmZpZy53aXRoQ3JlZGVudGlhbHMgY29uZGl0aW9uIHdhcyByZW1vdmVkIHRlbXBvcmFyaWx5XG4gICAgICBjb25zdCB4c3JmVmFsdWUgPSBpc1VSTFNhbWVPcmlnaW4oZnVsbFBhdGgpICYmIGNvbmZpZy54c3JmQ29va2llTmFtZSAmJiBjb29raWVzLnJlYWQoY29uZmlnLnhzcmZDb29raWVOYW1lKTtcblxuICAgICAgaWYgKHhzcmZWYWx1ZSkge1xuICAgICAgICByZXF1ZXN0SGVhZGVycy5zZXQoY29uZmlnLnhzcmZIZWFkZXJOYW1lLCB4c3JmVmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJlbW92ZSBDb250ZW50LVR5cGUgaWYgZGF0YSBpcyB1bmRlZmluZWRcbiAgICByZXF1ZXN0RGF0YSA9PT0gdW5kZWZpbmVkICYmIHJlcXVlc3RIZWFkZXJzLnNldENvbnRlbnRUeXBlKG51bGwpO1xuXG4gICAgLy8gQWRkIGhlYWRlcnMgdG8gdGhlIHJlcXVlc3RcbiAgICBpZiAoJ3NldFJlcXVlc3RIZWFkZXInIGluIHJlcXVlc3QpIHtcbiAgICAgIHV0aWxzLmZvckVhY2gocmVxdWVzdEhlYWRlcnMudG9KU09OKCksIGZ1bmN0aW9uIHNldFJlcXVlc3RIZWFkZXIodmFsLCBrZXkpIHtcbiAgICAgICAgcmVxdWVzdC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgdmFsKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIEFkZCB3aXRoQ3JlZGVudGlhbHMgdG8gcmVxdWVzdCBpZiBuZWVkZWRcbiAgICBpZiAoIXV0aWxzLmlzVW5kZWZpbmVkKGNvbmZpZy53aXRoQ3JlZGVudGlhbHMpKSB7XG4gICAgICByZXF1ZXN0LndpdGhDcmVkZW50aWFscyA9ICEhY29uZmlnLndpdGhDcmVkZW50aWFscztcbiAgICB9XG5cbiAgICAvLyBBZGQgcmVzcG9uc2VUeXBlIHRvIHJlcXVlc3QgaWYgbmVlZGVkXG4gICAgaWYgKHJlc3BvbnNlVHlwZSAmJiByZXNwb25zZVR5cGUgIT09ICdqc29uJykge1xuICAgICAgcmVxdWVzdC5yZXNwb25zZVR5cGUgPSBjb25maWcucmVzcG9uc2VUeXBlO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSBwcm9ncmVzcyBpZiBuZWVkZWRcbiAgICBpZiAodHlwZW9mIGNvbmZpZy5vbkRvd25sb2FkUHJvZ3Jlc3MgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJlcXVlc3QuYWRkRXZlbnRMaXN0ZW5lcigncHJvZ3Jlc3MnLCBwcm9ncmVzc0V2ZW50UmVkdWNlcihjb25maWcub25Eb3dubG9hZFByb2dyZXNzLCB0cnVlKSk7XG4gICAgfVxuXG4gICAgLy8gTm90IGFsbCBicm93c2VycyBzdXBwb3J0IHVwbG9hZCBldmVudHNcbiAgICBpZiAodHlwZW9mIGNvbmZpZy5vblVwbG9hZFByb2dyZXNzID09PSAnZnVuY3Rpb24nICYmIHJlcXVlc3QudXBsb2FkKSB7XG4gICAgICByZXF1ZXN0LnVwbG9hZC5hZGRFdmVudExpc3RlbmVyKCdwcm9ncmVzcycsIHByb2dyZXNzRXZlbnRSZWR1Y2VyKGNvbmZpZy5vblVwbG9hZFByb2dyZXNzKSk7XG4gICAgfVxuXG4gICAgaWYgKGNvbmZpZy5jYW5jZWxUb2tlbiB8fCBjb25maWcuc2lnbmFsKSB7XG4gICAgICAvLyBIYW5kbGUgY2FuY2VsbGF0aW9uXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZnVuYy1uYW1lc1xuICAgICAgb25DYW5jZWxlZCA9IGNhbmNlbCA9PiB7XG4gICAgICAgIGlmICghcmVxdWVzdCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICByZWplY3QoIWNhbmNlbCB8fCBjYW5jZWwudHlwZSA/IG5ldyBDYW5jZWxlZEVycm9yKG51bGwsIGNvbmZpZywgcmVxdWVzdCkgOiBjYW5jZWwpO1xuICAgICAgICByZXF1ZXN0LmFib3J0KCk7XG4gICAgICAgIHJlcXVlc3QgPSBudWxsO1xuICAgICAgfTtcblxuICAgICAgY29uZmlnLmNhbmNlbFRva2VuICYmIGNvbmZpZy5jYW5jZWxUb2tlbi5zdWJzY3JpYmUob25DYW5jZWxlZCk7XG4gICAgICBpZiAoY29uZmlnLnNpZ25hbCkge1xuICAgICAgICBjb25maWcuc2lnbmFsLmFib3J0ZWQgPyBvbkNhbmNlbGVkKCkgOiBjb25maWcuc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0Jywgb25DYW5jZWxlZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgcHJvdG9jb2wgPSBwYXJzZVByb3RvY29sKGZ1bGxQYXRoKTtcblxuICAgIGlmIChwcm90b2NvbCAmJiBwbGF0Zm9ybS5wcm90b2NvbHMuaW5kZXhPZihwcm90b2NvbCkgPT09IC0xKSB7XG4gICAgICByZWplY3QobmV3IEF4aW9zRXJyb3IoJ1Vuc3VwcG9ydGVkIHByb3RvY29sICcgKyBwcm90b2NvbCArICc6JywgQXhpb3NFcnJvci5FUlJfQkFEX1JFUVVFU1QsIGNvbmZpZykpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuXG4gICAgLy8gU2VuZCB0aGUgcmVxdWVzdFxuICAgIHJlcXVlc3Quc2VuZChyZXF1ZXN0RGF0YSB8fCBudWxsKTtcbiAgfSk7XG59O1xuXG5jb25zdCBrbm93bkFkYXB0ZXJzID0ge1xuICBodHRwOiBodHRwQWRhcHRlcixcbiAgeGhyOiB4aHJBZGFwdGVyXG59O1xuXG51dGlscy5mb3JFYWNoKGtub3duQWRhcHRlcnMsIChmbiwgdmFsdWUpID0+IHtcbiAgaWYgKGZuKSB7XG4gICAgdHJ5IHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmbiwgJ25hbWUnLCB7dmFsdWV9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZW1wdHlcbiAgICB9XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGZuLCAnYWRhcHRlck5hbWUnLCB7dmFsdWV9KTtcbiAgfVxufSk7XG5cbmNvbnN0IHJlbmRlclJlYXNvbiA9IChyZWFzb24pID0+IGAtICR7cmVhc29ufWA7XG5cbmNvbnN0IGlzUmVzb2x2ZWRIYW5kbGUgPSAoYWRhcHRlcikgPT4gdXRpbHMuaXNGdW5jdGlvbihhZGFwdGVyKSB8fCBhZGFwdGVyID09PSBudWxsIHx8IGFkYXB0ZXIgPT09IGZhbHNlO1xuXG5jb25zdCBhZGFwdGVycyA9IHtcbiAgZ2V0QWRhcHRlcjogKGFkYXB0ZXJzKSA9PiB7XG4gICAgYWRhcHRlcnMgPSB1dGlscy5pc0FycmF5KGFkYXB0ZXJzKSA/IGFkYXB0ZXJzIDogW2FkYXB0ZXJzXTtcblxuICAgIGNvbnN0IHtsZW5ndGh9ID0gYWRhcHRlcnM7XG4gICAgbGV0IG5hbWVPckFkYXB0ZXI7XG4gICAgbGV0IGFkYXB0ZXI7XG5cbiAgICBjb25zdCByZWplY3RlZFJlYXNvbnMgPSB7fTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIG5hbWVPckFkYXB0ZXIgPSBhZGFwdGVyc1tpXTtcbiAgICAgIGxldCBpZDtcblxuICAgICAgYWRhcHRlciA9IG5hbWVPckFkYXB0ZXI7XG5cbiAgICAgIGlmICghaXNSZXNvbHZlZEhhbmRsZShuYW1lT3JBZGFwdGVyKSkge1xuICAgICAgICBhZGFwdGVyID0ga25vd25BZGFwdGVyc1soaWQgPSBTdHJpbmcobmFtZU9yQWRhcHRlcikpLnRvTG93ZXJDYXNlKCldO1xuXG4gICAgICAgIGlmIChhZGFwdGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgQXhpb3NFcnJvcihgVW5rbm93biBhZGFwdGVyICcke2lkfSdgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoYWRhcHRlcikge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgcmVqZWN0ZWRSZWFzb25zW2lkIHx8ICcjJyArIGldID0gYWRhcHRlcjtcbiAgICB9XG5cbiAgICBpZiAoIWFkYXB0ZXIpIHtcblxuICAgICAgY29uc3QgcmVhc29ucyA9IE9iamVjdC5lbnRyaWVzKHJlamVjdGVkUmVhc29ucylcbiAgICAgICAgLm1hcCgoW2lkLCBzdGF0ZV0pID0+IGBhZGFwdGVyICR7aWR9IGAgK1xuICAgICAgICAgIChzdGF0ZSA9PT0gZmFsc2UgPyAnaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgZW52aXJvbm1lbnQnIDogJ2lzIG5vdCBhdmFpbGFibGUgaW4gdGhlIGJ1aWxkJylcbiAgICAgICAgKTtcblxuICAgICAgbGV0IHMgPSBsZW5ndGggP1xuICAgICAgICAocmVhc29ucy5sZW5ndGggPiAxID8gJ3NpbmNlIDpcXG4nICsgcmVhc29ucy5tYXAocmVuZGVyUmVhc29uKS5qb2luKCdcXG4nKSA6ICcgJyArIHJlbmRlclJlYXNvbihyZWFzb25zWzBdKSkgOlxuICAgICAgICAnYXMgbm8gYWRhcHRlciBzcGVjaWZpZWQnO1xuXG4gICAgICB0aHJvdyBuZXcgQXhpb3NFcnJvcihcbiAgICAgICAgYFRoZXJlIGlzIG5vIHN1aXRhYmxlIGFkYXB0ZXIgdG8gZGlzcGF0Y2ggdGhlIHJlcXVlc3QgYCArIHMsXG4gICAgICAgICdFUlJfTk9UX1NVUFBPUlQnXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhZGFwdGVyO1xuICB9LFxuICBhZGFwdGVyczoga25vd25BZGFwdGVyc1xufTtcblxuLyoqXG4gKiBUaHJvd3MgYSBgQ2FuY2VsZWRFcnJvcmAgaWYgY2FuY2VsbGF0aW9uIGhhcyBiZWVuIHJlcXVlc3RlZC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIFRoZSBjb25maWcgdGhhdCBpcyB0byBiZSB1c2VkIGZvciB0aGUgcmVxdWVzdFxuICpcbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB0aHJvd0lmQ2FuY2VsbGF0aW9uUmVxdWVzdGVkKGNvbmZpZykge1xuICBpZiAoY29uZmlnLmNhbmNlbFRva2VuKSB7XG4gICAgY29uZmlnLmNhbmNlbFRva2VuLnRocm93SWZSZXF1ZXN0ZWQoKTtcbiAgfVxuXG4gIGlmIChjb25maWcuc2lnbmFsICYmIGNvbmZpZy5zaWduYWwuYWJvcnRlZCkge1xuICAgIHRocm93IG5ldyBDYW5jZWxlZEVycm9yKG51bGwsIGNvbmZpZyk7XG4gIH1cbn1cblxuLyoqXG4gKiBEaXNwYXRjaCBhIHJlcXVlc3QgdG8gdGhlIHNlcnZlciB1c2luZyB0aGUgY29uZmlndXJlZCBhZGFwdGVyLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBjb25maWcgVGhlIGNvbmZpZyB0aGF0IGlzIHRvIGJlIHVzZWQgZm9yIHRoZSByZXF1ZXN0XG4gKlxuICogQHJldHVybnMge1Byb21pc2V9IFRoZSBQcm9taXNlIHRvIGJlIGZ1bGZpbGxlZFxuICovXG5mdW5jdGlvbiBkaXNwYXRjaFJlcXVlc3QoY29uZmlnKSB7XG4gIHRocm93SWZDYW5jZWxsYXRpb25SZXF1ZXN0ZWQoY29uZmlnKTtcblxuICBjb25maWcuaGVhZGVycyA9IEF4aW9zSGVhZGVycyQxLmZyb20oY29uZmlnLmhlYWRlcnMpO1xuXG4gIC8vIFRyYW5zZm9ybSByZXF1ZXN0IGRhdGFcbiAgY29uZmlnLmRhdGEgPSB0cmFuc2Zvcm1EYXRhLmNhbGwoXG4gICAgY29uZmlnLFxuICAgIGNvbmZpZy50cmFuc2Zvcm1SZXF1ZXN0XG4gICk7XG5cbiAgaWYgKFsncG9zdCcsICdwdXQnLCAncGF0Y2gnXS5pbmRleE9mKGNvbmZpZy5tZXRob2QpICE9PSAtMSkge1xuICAgIGNvbmZpZy5oZWFkZXJzLnNldENvbnRlbnRUeXBlKCdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLCBmYWxzZSk7XG4gIH1cblxuICBjb25zdCBhZGFwdGVyID0gYWRhcHRlcnMuZ2V0QWRhcHRlcihjb25maWcuYWRhcHRlciB8fCBkZWZhdWx0cyQxLmFkYXB0ZXIpO1xuXG4gIHJldHVybiBhZGFwdGVyKGNvbmZpZykudGhlbihmdW5jdGlvbiBvbkFkYXB0ZXJSZXNvbHV0aW9uKHJlc3BvbnNlKSB7XG4gICAgdGhyb3dJZkNhbmNlbGxhdGlvblJlcXVlc3RlZChjb25maWcpO1xuXG4gICAgLy8gVHJhbnNmb3JtIHJlc3BvbnNlIGRhdGFcbiAgICByZXNwb25zZS5kYXRhID0gdHJhbnNmb3JtRGF0YS5jYWxsKFxuICAgICAgY29uZmlnLFxuICAgICAgY29uZmlnLnRyYW5zZm9ybVJlc3BvbnNlLFxuICAgICAgcmVzcG9uc2VcbiAgICApO1xuXG4gICAgcmVzcG9uc2UuaGVhZGVycyA9IEF4aW9zSGVhZGVycyQxLmZyb20ocmVzcG9uc2UuaGVhZGVycyk7XG5cbiAgICByZXR1cm4gcmVzcG9uc2U7XG4gIH0sIGZ1bmN0aW9uIG9uQWRhcHRlclJlamVjdGlvbihyZWFzb24pIHtcbiAgICBpZiAoIWlzQ2FuY2VsKHJlYXNvbikpIHtcbiAgICAgIHRocm93SWZDYW5jZWxsYXRpb25SZXF1ZXN0ZWQoY29uZmlnKTtcblxuICAgICAgLy8gVHJhbnNmb3JtIHJlc3BvbnNlIGRhdGFcbiAgICAgIGlmIChyZWFzb24gJiYgcmVhc29uLnJlc3BvbnNlKSB7XG4gICAgICAgIHJlYXNvbi5yZXNwb25zZS5kYXRhID0gdHJhbnNmb3JtRGF0YS5jYWxsKFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICBjb25maWcudHJhbnNmb3JtUmVzcG9uc2UsXG4gICAgICAgICAgcmVhc29uLnJlc3BvbnNlXG4gICAgICAgICk7XG4gICAgICAgIHJlYXNvbi5yZXNwb25zZS5oZWFkZXJzID0gQXhpb3NIZWFkZXJzJDEuZnJvbShyZWFzb24ucmVzcG9uc2UuaGVhZGVycyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHJlYXNvbik7XG4gIH0pO1xufVxuXG5jb25zdCBoZWFkZXJzVG9PYmplY3QgPSAodGhpbmcpID0+IHRoaW5nIGluc3RhbmNlb2YgQXhpb3NIZWFkZXJzJDEgPyB0aGluZy50b0pTT04oKSA6IHRoaW5nO1xuXG4vKipcbiAqIENvbmZpZy1zcGVjaWZpYyBtZXJnZS1mdW5jdGlvbiB3aGljaCBjcmVhdGVzIGEgbmV3IGNvbmZpZy1vYmplY3RcbiAqIGJ5IG1lcmdpbmcgdHdvIGNvbmZpZ3VyYXRpb24gb2JqZWN0cyB0b2dldGhlci5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnMVxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZzJcbiAqXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBOZXcgb2JqZWN0IHJlc3VsdGluZyBmcm9tIG1lcmdpbmcgY29uZmlnMiB0byBjb25maWcxXG4gKi9cbmZ1bmN0aW9uIG1lcmdlQ29uZmlnKGNvbmZpZzEsIGNvbmZpZzIpIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG4gIGNvbmZpZzIgPSBjb25maWcyIHx8IHt9O1xuICBjb25zdCBjb25maWcgPSB7fTtcblxuICBmdW5jdGlvbiBnZXRNZXJnZWRWYWx1ZSh0YXJnZXQsIHNvdXJjZSwgY2FzZWxlc3MpIHtcbiAgICBpZiAodXRpbHMuaXNQbGFpbk9iamVjdCh0YXJnZXQpICYmIHV0aWxzLmlzUGxhaW5PYmplY3Qoc291cmNlKSkge1xuICAgICAgcmV0dXJuIHV0aWxzLm1lcmdlLmNhbGwoe2Nhc2VsZXNzfSwgdGFyZ2V0LCBzb3VyY2UpO1xuICAgIH0gZWxzZSBpZiAodXRpbHMuaXNQbGFpbk9iamVjdChzb3VyY2UpKSB7XG4gICAgICByZXR1cm4gdXRpbHMubWVyZ2Uoe30sIHNvdXJjZSk7XG4gICAgfSBlbHNlIGlmICh1dGlscy5pc0FycmF5KHNvdXJjZSkpIHtcbiAgICAgIHJldHVybiBzb3VyY2Uuc2xpY2UoKTtcbiAgICB9XG4gICAgcmV0dXJuIHNvdXJjZTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb25zaXN0ZW50LXJldHVyblxuICBmdW5jdGlvbiBtZXJnZURlZXBQcm9wZXJ0aWVzKGEsIGIsIGNhc2VsZXNzKSB7XG4gICAgaWYgKCF1dGlscy5pc1VuZGVmaW5lZChiKSkge1xuICAgICAgcmV0dXJuIGdldE1lcmdlZFZhbHVlKGEsIGIsIGNhc2VsZXNzKTtcbiAgICB9IGVsc2UgaWYgKCF1dGlscy5pc1VuZGVmaW5lZChhKSkge1xuICAgICAgcmV0dXJuIGdldE1lcmdlZFZhbHVlKHVuZGVmaW5lZCwgYSwgY2FzZWxlc3MpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb25zaXN0ZW50LXJldHVyblxuICBmdW5jdGlvbiB2YWx1ZUZyb21Db25maWcyKGEsIGIpIHtcbiAgICBpZiAoIXV0aWxzLmlzVW5kZWZpbmVkKGIpKSB7XG4gICAgICByZXR1cm4gZ2V0TWVyZ2VkVmFsdWUodW5kZWZpbmVkLCBiKTtcbiAgICB9XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cbiAgZnVuY3Rpb24gZGVmYXVsdFRvQ29uZmlnMihhLCBiKSB7XG4gICAgaWYgKCF1dGlscy5pc1VuZGVmaW5lZChiKSkge1xuICAgICAgcmV0dXJuIGdldE1lcmdlZFZhbHVlKHVuZGVmaW5lZCwgYik7XG4gICAgfSBlbHNlIGlmICghdXRpbHMuaXNVbmRlZmluZWQoYSkpIHtcbiAgICAgIHJldHVybiBnZXRNZXJnZWRWYWx1ZSh1bmRlZmluZWQsIGEpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb25zaXN0ZW50LXJldHVyblxuICBmdW5jdGlvbiBtZXJnZURpcmVjdEtleXMoYSwgYiwgcHJvcCkge1xuICAgIGlmIChwcm9wIGluIGNvbmZpZzIpIHtcbiAgICAgIHJldHVybiBnZXRNZXJnZWRWYWx1ZShhLCBiKTtcbiAgICB9IGVsc2UgaWYgKHByb3AgaW4gY29uZmlnMSkge1xuICAgICAgcmV0dXJuIGdldE1lcmdlZFZhbHVlKHVuZGVmaW5lZCwgYSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgbWVyZ2VNYXAgPSB7XG4gICAgdXJsOiB2YWx1ZUZyb21Db25maWcyLFxuICAgIG1ldGhvZDogdmFsdWVGcm9tQ29uZmlnMixcbiAgICBkYXRhOiB2YWx1ZUZyb21Db25maWcyLFxuICAgIGJhc2VVUkw6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgdHJhbnNmb3JtUmVxdWVzdDogZGVmYXVsdFRvQ29uZmlnMixcbiAgICB0cmFuc2Zvcm1SZXNwb25zZTogZGVmYXVsdFRvQ29uZmlnMixcbiAgICBwYXJhbXNTZXJpYWxpemVyOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIHRpbWVvdXQ6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgdGltZW91dE1lc3NhZ2U6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgd2l0aENyZWRlbnRpYWxzOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIGFkYXB0ZXI6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgcmVzcG9uc2VUeXBlOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIHhzcmZDb29raWVOYW1lOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIHhzcmZIZWFkZXJOYW1lOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIG9uVXBsb2FkUHJvZ3Jlc3M6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgb25Eb3dubG9hZFByb2dyZXNzOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIGRlY29tcHJlc3M6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgbWF4Q29udGVudExlbmd0aDogZGVmYXVsdFRvQ29uZmlnMixcbiAgICBtYXhCb2R5TGVuZ3RoOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIGJlZm9yZVJlZGlyZWN0OiBkZWZhdWx0VG9Db25maWcyLFxuICAgIHRyYW5zcG9ydDogZGVmYXVsdFRvQ29uZmlnMixcbiAgICBodHRwQWdlbnQ6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgaHR0cHNBZ2VudDogZGVmYXVsdFRvQ29uZmlnMixcbiAgICBjYW5jZWxUb2tlbjogZGVmYXVsdFRvQ29uZmlnMixcbiAgICBzb2NrZXRQYXRoOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIHJlc3BvbnNlRW5jb2Rpbmc6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgdmFsaWRhdGVTdGF0dXM6IG1lcmdlRGlyZWN0S2V5cyxcbiAgICBoZWFkZXJzOiAoYSwgYikgPT4gbWVyZ2VEZWVwUHJvcGVydGllcyhoZWFkZXJzVG9PYmplY3QoYSksIGhlYWRlcnNUb09iamVjdChiKSwgdHJ1ZSlcbiAgfTtcblxuICB1dGlscy5mb3JFYWNoKE9iamVjdC5rZXlzKE9iamVjdC5hc3NpZ24oe30sIGNvbmZpZzEsIGNvbmZpZzIpKSwgZnVuY3Rpb24gY29tcHV0ZUNvbmZpZ1ZhbHVlKHByb3ApIHtcbiAgICBjb25zdCBtZXJnZSA9IG1lcmdlTWFwW3Byb3BdIHx8IG1lcmdlRGVlcFByb3BlcnRpZXM7XG4gICAgY29uc3QgY29uZmlnVmFsdWUgPSBtZXJnZShjb25maWcxW3Byb3BdLCBjb25maWcyW3Byb3BdLCBwcm9wKTtcbiAgICAodXRpbHMuaXNVbmRlZmluZWQoY29uZmlnVmFsdWUpICYmIG1lcmdlICE9PSBtZXJnZURpcmVjdEtleXMpIHx8IChjb25maWdbcHJvcF0gPSBjb25maWdWYWx1ZSk7XG4gIH0pO1xuXG4gIHJldHVybiBjb25maWc7XG59XG5cbmNvbnN0IHZhbGlkYXRvcnMkMSA9IHt9O1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZnVuYy1uYW1lc1xuWydvYmplY3QnLCAnYm9vbGVhbicsICdudW1iZXInLCAnZnVuY3Rpb24nLCAnc3RyaW5nJywgJ3N5bWJvbCddLmZvckVhY2goKHR5cGUsIGkpID0+IHtcbiAgdmFsaWRhdG9ycyQxW3R5cGVdID0gZnVuY3Rpb24gdmFsaWRhdG9yKHRoaW5nKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB0aGluZyA9PT0gdHlwZSB8fCAnYScgKyAoaSA8IDEgPyAnbiAnIDogJyAnKSArIHR5cGU7XG4gIH07XG59KTtcblxuY29uc3QgZGVwcmVjYXRlZFdhcm5pbmdzID0ge307XG5cbi8qKlxuICogVHJhbnNpdGlvbmFsIG9wdGlvbiB2YWxpZGF0b3JcbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufGJvb2xlYW4/fSB2YWxpZGF0b3IgLSBzZXQgdG8gZmFsc2UgaWYgdGhlIHRyYW5zaXRpb25hbCBvcHRpb24gaGFzIGJlZW4gcmVtb3ZlZFxuICogQHBhcmFtIHtzdHJpbmc/fSB2ZXJzaW9uIC0gZGVwcmVjYXRlZCB2ZXJzaW9uIC8gcmVtb3ZlZCBzaW5jZSB2ZXJzaW9uXG4gKiBAcGFyYW0ge3N0cmluZz99IG1lc3NhZ2UgLSBzb21lIG1lc3NhZ2Ugd2l0aCBhZGRpdGlvbmFsIGluZm9cbiAqXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259XG4gKi9cbnZhbGlkYXRvcnMkMS50cmFuc2l0aW9uYWwgPSBmdW5jdGlvbiB0cmFuc2l0aW9uYWwodmFsaWRhdG9yLCB2ZXJzaW9uLCBtZXNzYWdlKSB7XG4gIGZ1bmN0aW9uIGZvcm1hdE1lc3NhZ2Uob3B0LCBkZXNjKSB7XG4gICAgcmV0dXJuICdbQXhpb3MgdicgKyBWRVJTSU9OICsgJ10gVHJhbnNpdGlvbmFsIG9wdGlvbiBcXCcnICsgb3B0ICsgJ1xcJycgKyBkZXNjICsgKG1lc3NhZ2UgPyAnLiAnICsgbWVzc2FnZSA6ICcnKTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBmdW5jLW5hbWVzXG4gIHJldHVybiAodmFsdWUsIG9wdCwgb3B0cykgPT4ge1xuICAgIGlmICh2YWxpZGF0b3IgPT09IGZhbHNlKSB7XG4gICAgICB0aHJvdyBuZXcgQXhpb3NFcnJvcihcbiAgICAgICAgZm9ybWF0TWVzc2FnZShvcHQsICcgaGFzIGJlZW4gcmVtb3ZlZCcgKyAodmVyc2lvbiA/ICcgaW4gJyArIHZlcnNpb24gOiAnJykpLFxuICAgICAgICBBeGlvc0Vycm9yLkVSUl9ERVBSRUNBVEVEXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICh2ZXJzaW9uICYmICFkZXByZWNhdGVkV2FybmluZ3Nbb3B0XSkge1xuICAgICAgZGVwcmVjYXRlZFdhcm5pbmdzW29wdF0gPSB0cnVlO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgZm9ybWF0TWVzc2FnZShcbiAgICAgICAgICBvcHQsXG4gICAgICAgICAgJyBoYXMgYmVlbiBkZXByZWNhdGVkIHNpbmNlIHYnICsgdmVyc2lvbiArICcgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiB0aGUgbmVhciBmdXR1cmUnXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbGlkYXRvciA/IHZhbGlkYXRvcih2YWx1ZSwgb3B0LCBvcHRzKSA6IHRydWU7XG4gIH07XG59O1xuXG4vKipcbiAqIEFzc2VydCBvYmplY3QncyBwcm9wZXJ0aWVzIHR5cGVcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gb3B0aW9uc1xuICogQHBhcmFtIHtvYmplY3R9IHNjaGVtYVxuICogQHBhcmFtIHtib29sZWFuP30gYWxsb3dVbmtub3duXG4gKlxuICogQHJldHVybnMge29iamVjdH1cbiAqL1xuXG5mdW5jdGlvbiBhc3NlcnRPcHRpb25zKG9wdGlvbnMsIHNjaGVtYSwgYWxsb3dVbmtub3duKSB7XG4gIGlmICh0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIHtcbiAgICB0aHJvdyBuZXcgQXhpb3NFcnJvcignb3B0aW9ucyBtdXN0IGJlIGFuIG9iamVjdCcsIEF4aW9zRXJyb3IuRVJSX0JBRF9PUFRJT05fVkFMVUUpO1xuICB9XG4gIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhvcHRpb25zKTtcbiAgbGV0IGkgPSBrZXlzLmxlbmd0aDtcbiAgd2hpbGUgKGktLSA+IDApIHtcbiAgICBjb25zdCBvcHQgPSBrZXlzW2ldO1xuICAgIGNvbnN0IHZhbGlkYXRvciA9IHNjaGVtYVtvcHRdO1xuICAgIGlmICh2YWxpZGF0b3IpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gb3B0aW9uc1tvcHRdO1xuICAgICAgY29uc3QgcmVzdWx0ID0gdmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWxpZGF0b3IodmFsdWUsIG9wdCwgb3B0aW9ucyk7XG4gICAgICBpZiAocmVzdWx0ICE9PSB0cnVlKSB7XG4gICAgICAgIHRocm93IG5ldyBBeGlvc0Vycm9yKCdvcHRpb24gJyArIG9wdCArICcgbXVzdCBiZSAnICsgcmVzdWx0LCBBeGlvc0Vycm9yLkVSUl9CQURfT1BUSU9OX1ZBTFVFKTtcbiAgICAgIH1cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBpZiAoYWxsb3dVbmtub3duICE9PSB0cnVlKSB7XG4gICAgICB0aHJvdyBuZXcgQXhpb3NFcnJvcignVW5rbm93biBvcHRpb24gJyArIG9wdCwgQXhpb3NFcnJvci5FUlJfQkFEX09QVElPTik7XG4gICAgfVxuICB9XG59XG5cbmNvbnN0IHZhbGlkYXRvciA9IHtcbiAgYXNzZXJ0T3B0aW9ucyxcbiAgdmFsaWRhdG9yczogdmFsaWRhdG9ycyQxXG59O1xuXG5jb25zdCB2YWxpZGF0b3JzID0gdmFsaWRhdG9yLnZhbGlkYXRvcnM7XG5cbi8qKlxuICogQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIEF4aW9zXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGluc3RhbmNlQ29uZmlnIFRoZSBkZWZhdWx0IGNvbmZpZyBmb3IgdGhlIGluc3RhbmNlXG4gKlxuICogQHJldHVybiB7QXhpb3N9IEEgbmV3IGluc3RhbmNlIG9mIEF4aW9zXG4gKi9cbmNsYXNzIEF4aW9zIHtcbiAgY29uc3RydWN0b3IoaW5zdGFuY2VDb25maWcpIHtcbiAgICB0aGlzLmRlZmF1bHRzID0gaW5zdGFuY2VDb25maWc7XG4gICAgdGhpcy5pbnRlcmNlcHRvcnMgPSB7XG4gICAgICByZXF1ZXN0OiBuZXcgSW50ZXJjZXB0b3JNYW5hZ2VyJDEoKSxcbiAgICAgIHJlc3BvbnNlOiBuZXcgSW50ZXJjZXB0b3JNYW5hZ2VyJDEoKVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogRGlzcGF0Y2ggYSByZXF1ZXN0XG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdH0gY29uZmlnT3JVcmwgVGhlIGNvbmZpZyBzcGVjaWZpYyBmb3IgdGhpcyByZXF1ZXN0IChtZXJnZWQgd2l0aCB0aGlzLmRlZmF1bHRzKVxuICAgKiBAcGFyYW0gez9PYmplY3R9IGNvbmZpZ1xuICAgKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gVGhlIFByb21pc2UgdG8gYmUgZnVsZmlsbGVkXG4gICAqL1xuICByZXF1ZXN0KGNvbmZpZ09yVXJsLCBjb25maWcpIHtcbiAgICAvKmVzbGludCBuby1wYXJhbS1yZWFzc2lnbjowKi9cbiAgICAvLyBBbGxvdyBmb3IgYXhpb3MoJ2V4YW1wbGUvdXJsJ1ssIGNvbmZpZ10pIGEgbGEgZmV0Y2ggQVBJXG4gICAgaWYgKHR5cGVvZiBjb25maWdPclVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbmZpZyA9IGNvbmZpZyB8fCB7fTtcbiAgICAgIGNvbmZpZy51cmwgPSBjb25maWdPclVybDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uZmlnID0gY29uZmlnT3JVcmwgfHwge307XG4gICAgfVxuXG4gICAgY29uZmlnID0gbWVyZ2VDb25maWcodGhpcy5kZWZhdWx0cywgY29uZmlnKTtcblxuICAgIGNvbnN0IHt0cmFuc2l0aW9uYWwsIHBhcmFtc1NlcmlhbGl6ZXIsIGhlYWRlcnN9ID0gY29uZmlnO1xuXG4gICAgaWYgKHRyYW5zaXRpb25hbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB2YWxpZGF0b3IuYXNzZXJ0T3B0aW9ucyh0cmFuc2l0aW9uYWwsIHtcbiAgICAgICAgc2lsZW50SlNPTlBhcnNpbmc6IHZhbGlkYXRvcnMudHJhbnNpdGlvbmFsKHZhbGlkYXRvcnMuYm9vbGVhbiksXG4gICAgICAgIGZvcmNlZEpTT05QYXJzaW5nOiB2YWxpZGF0b3JzLnRyYW5zaXRpb25hbCh2YWxpZGF0b3JzLmJvb2xlYW4pLFxuICAgICAgICBjbGFyaWZ5VGltZW91dEVycm9yOiB2YWxpZGF0b3JzLnRyYW5zaXRpb25hbCh2YWxpZGF0b3JzLmJvb2xlYW4pXG4gICAgICB9LCBmYWxzZSk7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtc1NlcmlhbGl6ZXIgIT0gbnVsbCkge1xuICAgICAgaWYgKHV0aWxzLmlzRnVuY3Rpb24ocGFyYW1zU2VyaWFsaXplcikpIHtcbiAgICAgICAgY29uZmlnLnBhcmFtc1NlcmlhbGl6ZXIgPSB7XG4gICAgICAgICAgc2VyaWFsaXplOiBwYXJhbXNTZXJpYWxpemVyXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YWxpZGF0b3IuYXNzZXJ0T3B0aW9ucyhwYXJhbXNTZXJpYWxpemVyLCB7XG4gICAgICAgICAgZW5jb2RlOiB2YWxpZGF0b3JzLmZ1bmN0aW9uLFxuICAgICAgICAgIHNlcmlhbGl6ZTogdmFsaWRhdG9ycy5mdW5jdGlvblxuICAgICAgICB9LCB0cnVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTZXQgY29uZmlnLm1ldGhvZFxuICAgIGNvbmZpZy5tZXRob2QgPSAoY29uZmlnLm1ldGhvZCB8fCB0aGlzLmRlZmF1bHRzLm1ldGhvZCB8fCAnZ2V0JykudG9Mb3dlckNhc2UoKTtcblxuICAgIC8vIEZsYXR0ZW4gaGVhZGVyc1xuICAgIGxldCBjb250ZXh0SGVhZGVycyA9IGhlYWRlcnMgJiYgdXRpbHMubWVyZ2UoXG4gICAgICBoZWFkZXJzLmNvbW1vbixcbiAgICAgIGhlYWRlcnNbY29uZmlnLm1ldGhvZF1cbiAgICApO1xuXG4gICAgaGVhZGVycyAmJiB1dGlscy5mb3JFYWNoKFxuICAgICAgWydkZWxldGUnLCAnZ2V0JywgJ2hlYWQnLCAncG9zdCcsICdwdXQnLCAncGF0Y2gnLCAnY29tbW9uJ10sXG4gICAgICAobWV0aG9kKSA9PiB7XG4gICAgICAgIGRlbGV0ZSBoZWFkZXJzW21ldGhvZF07XG4gICAgICB9XG4gICAgKTtcblxuICAgIGNvbmZpZy5oZWFkZXJzID0gQXhpb3NIZWFkZXJzJDEuY29uY2F0KGNvbnRleHRIZWFkZXJzLCBoZWFkZXJzKTtcblxuICAgIC8vIGZpbHRlciBvdXQgc2tpcHBlZCBpbnRlcmNlcHRvcnNcbiAgICBjb25zdCByZXF1ZXN0SW50ZXJjZXB0b3JDaGFpbiA9IFtdO1xuICAgIGxldCBzeW5jaHJvbm91c1JlcXVlc3RJbnRlcmNlcHRvcnMgPSB0cnVlO1xuICAgIHRoaXMuaW50ZXJjZXB0b3JzLnJlcXVlc3QuZm9yRWFjaChmdW5jdGlvbiB1bnNoaWZ0UmVxdWVzdEludGVyY2VwdG9ycyhpbnRlcmNlcHRvcikge1xuICAgICAgaWYgKHR5cGVvZiBpbnRlcmNlcHRvci5ydW5XaGVuID09PSAnZnVuY3Rpb24nICYmIGludGVyY2VwdG9yLnJ1bldoZW4oY29uZmlnKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBzeW5jaHJvbm91c1JlcXVlc3RJbnRlcmNlcHRvcnMgPSBzeW5jaHJvbm91c1JlcXVlc3RJbnRlcmNlcHRvcnMgJiYgaW50ZXJjZXB0b3Iuc3luY2hyb25vdXM7XG5cbiAgICAgIHJlcXVlc3RJbnRlcmNlcHRvckNoYWluLnVuc2hpZnQoaW50ZXJjZXB0b3IuZnVsZmlsbGVkLCBpbnRlcmNlcHRvci5yZWplY3RlZCk7XG4gICAgfSk7XG5cbiAgICBjb25zdCByZXNwb25zZUludGVyY2VwdG9yQ2hhaW4gPSBbXTtcbiAgICB0aGlzLmludGVyY2VwdG9ycy5yZXNwb25zZS5mb3JFYWNoKGZ1bmN0aW9uIHB1c2hSZXNwb25zZUludGVyY2VwdG9ycyhpbnRlcmNlcHRvcikge1xuICAgICAgcmVzcG9uc2VJbnRlcmNlcHRvckNoYWluLnB1c2goaW50ZXJjZXB0b3IuZnVsZmlsbGVkLCBpbnRlcmNlcHRvci5yZWplY3RlZCk7XG4gICAgfSk7XG5cbiAgICBsZXQgcHJvbWlzZTtcbiAgICBsZXQgaSA9IDA7XG4gICAgbGV0IGxlbjtcblxuICAgIGlmICghc3luY2hyb25vdXNSZXF1ZXN0SW50ZXJjZXB0b3JzKSB7XG4gICAgICBjb25zdCBjaGFpbiA9IFtkaXNwYXRjaFJlcXVlc3QuYmluZCh0aGlzKSwgdW5kZWZpbmVkXTtcbiAgICAgIGNoYWluLnVuc2hpZnQuYXBwbHkoY2hhaW4sIHJlcXVlc3RJbnRlcmNlcHRvckNoYWluKTtcbiAgICAgIGNoYWluLnB1c2guYXBwbHkoY2hhaW4sIHJlc3BvbnNlSW50ZXJjZXB0b3JDaGFpbik7XG4gICAgICBsZW4gPSBjaGFpbi5sZW5ndGg7XG5cbiAgICAgIHByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoY29uZmlnKTtcblxuICAgICAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICAgICAgcHJvbWlzZSA9IHByb21pc2UudGhlbihjaGFpbltpKytdLCBjaGFpbltpKytdKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgfVxuXG4gICAgbGVuID0gcmVxdWVzdEludGVyY2VwdG9yQ2hhaW4ubGVuZ3RoO1xuXG4gICAgbGV0IG5ld0NvbmZpZyA9IGNvbmZpZztcblxuICAgIGkgPSAwO1xuXG4gICAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICAgIGNvbnN0IG9uRnVsZmlsbGVkID0gcmVxdWVzdEludGVyY2VwdG9yQ2hhaW5baSsrXTtcbiAgICAgIGNvbnN0IG9uUmVqZWN0ZWQgPSByZXF1ZXN0SW50ZXJjZXB0b3JDaGFpbltpKytdO1xuICAgICAgdHJ5IHtcbiAgICAgICAgbmV3Q29uZmlnID0gb25GdWxmaWxsZWQobmV3Q29uZmlnKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIG9uUmVqZWN0ZWQuY2FsbCh0aGlzLCBlcnJvcik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBwcm9taXNlID0gZGlzcGF0Y2hSZXF1ZXN0LmNhbGwodGhpcywgbmV3Q29uZmlnKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycm9yKTtcbiAgICB9XG5cbiAgICBpID0gMDtcbiAgICBsZW4gPSByZXNwb25zZUludGVyY2VwdG9yQ2hhaW4ubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICAgIHByb21pc2UgPSBwcm9taXNlLnRoZW4ocmVzcG9uc2VJbnRlcmNlcHRvckNoYWluW2krK10sIHJlc3BvbnNlSW50ZXJjZXB0b3JDaGFpbltpKytdKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcHJvbWlzZTtcbiAgfVxuXG4gIGdldFVyaShjb25maWcpIHtcbiAgICBjb25maWcgPSBtZXJnZUNvbmZpZyh0aGlzLmRlZmF1bHRzLCBjb25maWcpO1xuICAgIGNvbnN0IGZ1bGxQYXRoID0gYnVpbGRGdWxsUGF0aChjb25maWcuYmFzZVVSTCwgY29uZmlnLnVybCk7XG4gICAgcmV0dXJuIGJ1aWxkVVJMKGZ1bGxQYXRoLCBjb25maWcucGFyYW1zLCBjb25maWcucGFyYW1zU2VyaWFsaXplcik7XG4gIH1cbn1cblxuLy8gUHJvdmlkZSBhbGlhc2VzIGZvciBzdXBwb3J0ZWQgcmVxdWVzdCBtZXRob2RzXG51dGlscy5mb3JFYWNoKFsnZGVsZXRlJywgJ2dldCcsICdoZWFkJywgJ29wdGlvbnMnXSwgZnVuY3Rpb24gZm9yRWFjaE1ldGhvZE5vRGF0YShtZXRob2QpIHtcbiAgLyplc2xpbnQgZnVuYy1uYW1lczowKi9cbiAgQXhpb3MucHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbih1cmwsIGNvbmZpZykge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QobWVyZ2VDb25maWcoY29uZmlnIHx8IHt9LCB7XG4gICAgICBtZXRob2QsXG4gICAgICB1cmwsXG4gICAgICBkYXRhOiAoY29uZmlnIHx8IHt9KS5kYXRhXG4gICAgfSkpO1xuICB9O1xufSk7XG5cbnV0aWxzLmZvckVhY2goWydwb3N0JywgJ3B1dCcsICdwYXRjaCddLCBmdW5jdGlvbiBmb3JFYWNoTWV0aG9kV2l0aERhdGEobWV0aG9kKSB7XG4gIC8qZXNsaW50IGZ1bmMtbmFtZXM6MCovXG5cbiAgZnVuY3Rpb24gZ2VuZXJhdGVIVFRQTWV0aG9kKGlzRm9ybSkge1xuICAgIHJldHVybiBmdW5jdGlvbiBodHRwTWV0aG9kKHVybCwgZGF0YSwgY29uZmlnKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KG1lcmdlQ29uZmlnKGNvbmZpZyB8fCB7fSwge1xuICAgICAgICBtZXRob2QsXG4gICAgICAgIGhlYWRlcnM6IGlzRm9ybSA/IHtcbiAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ211bHRpcGFydC9mb3JtLWRhdGEnXG4gICAgICAgIH0gOiB7fSxcbiAgICAgICAgdXJsLFxuICAgICAgICBkYXRhXG4gICAgICB9KSk7XG4gICAgfTtcbiAgfVxuXG4gIEF4aW9zLnByb3RvdHlwZVttZXRob2RdID0gZ2VuZXJhdGVIVFRQTWV0aG9kKCk7XG5cbiAgQXhpb3MucHJvdG90eXBlW21ldGhvZCArICdGb3JtJ10gPSBnZW5lcmF0ZUhUVFBNZXRob2QodHJ1ZSk7XG59KTtcblxuY29uc3QgQXhpb3MkMSA9IEF4aW9zO1xuXG4vKipcbiAqIEEgYENhbmNlbFRva2VuYCBpcyBhbiBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCB0byByZXF1ZXN0IGNhbmNlbGxhdGlvbiBvZiBhbiBvcGVyYXRpb24uXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXhlY3V0b3IgVGhlIGV4ZWN1dG9yIGZ1bmN0aW9uLlxuICpcbiAqIEByZXR1cm5zIHtDYW5jZWxUb2tlbn1cbiAqL1xuY2xhc3MgQ2FuY2VsVG9rZW4ge1xuICBjb25zdHJ1Y3RvcihleGVjdXRvcikge1xuICAgIGlmICh0eXBlb2YgZXhlY3V0b3IgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2V4ZWN1dG9yIG11c3QgYmUgYSBmdW5jdGlvbi4nKTtcbiAgICB9XG5cbiAgICBsZXQgcmVzb2x2ZVByb21pc2U7XG5cbiAgICB0aGlzLnByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbiBwcm9taXNlRXhlY3V0b3IocmVzb2x2ZSkge1xuICAgICAgcmVzb2x2ZVByb21pc2UgPSByZXNvbHZlO1xuICAgIH0pO1xuXG4gICAgY29uc3QgdG9rZW4gPSB0aGlzO1xuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGZ1bmMtbmFtZXNcbiAgICB0aGlzLnByb21pc2UudGhlbihjYW5jZWwgPT4ge1xuICAgICAgaWYgKCF0b2tlbi5fbGlzdGVuZXJzKSByZXR1cm47XG5cbiAgICAgIGxldCBpID0gdG9rZW4uX2xpc3RlbmVycy5sZW5ndGg7XG5cbiAgICAgIHdoaWxlIChpLS0gPiAwKSB7XG4gICAgICAgIHRva2VuLl9saXN0ZW5lcnNbaV0oY2FuY2VsKTtcbiAgICAgIH1cbiAgICAgIHRva2VuLl9saXN0ZW5lcnMgPSBudWxsO1xuICAgIH0pO1xuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGZ1bmMtbmFtZXNcbiAgICB0aGlzLnByb21pc2UudGhlbiA9IG9uZnVsZmlsbGVkID0+IHtcbiAgICAgIGxldCBfcmVzb2x2ZTtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBmdW5jLW5hbWVzXG4gICAgICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgIHRva2VuLnN1YnNjcmliZShyZXNvbHZlKTtcbiAgICAgICAgX3Jlc29sdmUgPSByZXNvbHZlO1xuICAgICAgfSkudGhlbihvbmZ1bGZpbGxlZCk7XG5cbiAgICAgIHByb21pc2UuY2FuY2VsID0gZnVuY3Rpb24gcmVqZWN0KCkge1xuICAgICAgICB0b2tlbi51bnN1YnNjcmliZShfcmVzb2x2ZSk7XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9O1xuXG4gICAgZXhlY3V0b3IoZnVuY3Rpb24gY2FuY2VsKG1lc3NhZ2UsIGNvbmZpZywgcmVxdWVzdCkge1xuICAgICAgaWYgKHRva2VuLnJlYXNvbikge1xuICAgICAgICAvLyBDYW5jZWxsYXRpb24gaGFzIGFscmVhZHkgYmVlbiByZXF1ZXN0ZWRcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0b2tlbi5yZWFzb24gPSBuZXcgQ2FuY2VsZWRFcnJvcihtZXNzYWdlLCBjb25maWcsIHJlcXVlc3QpO1xuICAgICAgcmVzb2x2ZVByb21pc2UodG9rZW4ucmVhc29uKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaHJvd3MgYSBgQ2FuY2VsZWRFcnJvcmAgaWYgY2FuY2VsbGF0aW9uIGhhcyBiZWVuIHJlcXVlc3RlZC5cbiAgICovXG4gIHRocm93SWZSZXF1ZXN0ZWQoKSB7XG4gICAgaWYgKHRoaXMucmVhc29uKSB7XG4gICAgICB0aHJvdyB0aGlzLnJlYXNvbjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU3Vic2NyaWJlIHRvIHRoZSBjYW5jZWwgc2lnbmFsXG4gICAqL1xuXG4gIHN1YnNjcmliZShsaXN0ZW5lcikge1xuICAgIGlmICh0aGlzLnJlYXNvbikge1xuICAgICAgbGlzdGVuZXIodGhpcy5yZWFzb24pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9saXN0ZW5lcnMpIHtcbiAgICAgIHRoaXMuX2xpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fbGlzdGVuZXJzID0gW2xpc3RlbmVyXTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVW5zdWJzY3JpYmUgZnJvbSB0aGUgY2FuY2VsIHNpZ25hbFxuICAgKi9cblxuICB1bnN1YnNjcmliZShsaXN0ZW5lcikge1xuICAgIGlmICghdGhpcy5fbGlzdGVuZXJzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fbGlzdGVuZXJzLmluZGV4T2YobGlzdGVuZXIpO1xuICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgIHRoaXMuX2xpc3RlbmVycy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGEgbmV3IGBDYW5jZWxUb2tlbmAgYW5kIGEgZnVuY3Rpb24gdGhhdCwgd2hlbiBjYWxsZWQsXG4gICAqIGNhbmNlbHMgdGhlIGBDYW5jZWxUb2tlbmAuXG4gICAqL1xuICBzdGF0aWMgc291cmNlKCkge1xuICAgIGxldCBjYW5jZWw7XG4gICAgY29uc3QgdG9rZW4gPSBuZXcgQ2FuY2VsVG9rZW4oZnVuY3Rpb24gZXhlY3V0b3IoYykge1xuICAgICAgY2FuY2VsID0gYztcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgdG9rZW4sXG4gICAgICBjYW5jZWxcbiAgICB9O1xuICB9XG59XG5cbmNvbnN0IENhbmNlbFRva2VuJDEgPSBDYW5jZWxUb2tlbjtcblxuLyoqXG4gKiBTeW50YWN0aWMgc3VnYXIgZm9yIGludm9raW5nIGEgZnVuY3Rpb24gYW5kIGV4cGFuZGluZyBhbiBhcnJheSBmb3IgYXJndW1lbnRzLlxuICpcbiAqIENvbW1vbiB1c2UgY2FzZSB3b3VsZCBiZSB0byB1c2UgYEZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseWAuXG4gKlxuICogIGBgYGpzXG4gKiAgZnVuY3Rpb24gZih4LCB5LCB6KSB7fVxuICogIHZhciBhcmdzID0gWzEsIDIsIDNdO1xuICogIGYuYXBwbHkobnVsbCwgYXJncyk7XG4gKiAgYGBgXG4gKlxuICogV2l0aCBgc3ByZWFkYCB0aGlzIGV4YW1wbGUgY2FuIGJlIHJlLXdyaXR0ZW4uXG4gKlxuICogIGBgYGpzXG4gKiAgc3ByZWFkKGZ1bmN0aW9uKHgsIHksIHopIHt9KShbMSwgMiwgM10pO1xuICogIGBgYFxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKlxuICogQHJldHVybnMge0Z1bmN0aW9ufVxuICovXG5mdW5jdGlvbiBzcHJlYWQoY2FsbGJhY2spIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHdyYXAoYXJyKSB7XG4gICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KG51bGwsIGFycik7XG4gIH07XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBwYXlsb2FkIGlzIGFuIGVycm9yIHRocm93biBieSBBeGlvc1xuICpcbiAqIEBwYXJhbSB7Kn0gcGF5bG9hZCBUaGUgdmFsdWUgdG8gdGVzdFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBwYXlsb2FkIGlzIGFuIGVycm9yIHRocm93biBieSBBeGlvcywgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQXhpb3NFcnJvcihwYXlsb2FkKSB7XG4gIHJldHVybiB1dGlscy5pc09iamVjdChwYXlsb2FkKSAmJiAocGF5bG9hZC5pc0F4aW9zRXJyb3IgPT09IHRydWUpO1xufVxuXG5jb25zdCBIdHRwU3RhdHVzQ29kZSA9IHtcbiAgQ29udGludWU6IDEwMCxcbiAgU3dpdGNoaW5nUHJvdG9jb2xzOiAxMDEsXG4gIFByb2Nlc3Npbmc6IDEwMixcbiAgRWFybHlIaW50czogMTAzLFxuICBPazogMjAwLFxuICBDcmVhdGVkOiAyMDEsXG4gIEFjY2VwdGVkOiAyMDIsXG4gIE5vbkF1dGhvcml0YXRpdmVJbmZvcm1hdGlvbjogMjAzLFxuICBOb0NvbnRlbnQ6IDIwNCxcbiAgUmVzZXRDb250ZW50OiAyMDUsXG4gIFBhcnRpYWxDb250ZW50OiAyMDYsXG4gIE11bHRpU3RhdHVzOiAyMDcsXG4gIEFscmVhZHlSZXBvcnRlZDogMjA4LFxuICBJbVVzZWQ6IDIyNixcbiAgTXVsdGlwbGVDaG9pY2VzOiAzMDAsXG4gIE1vdmVkUGVybWFuZW50bHk6IDMwMSxcbiAgRm91bmQ6IDMwMixcbiAgU2VlT3RoZXI6IDMwMyxcbiAgTm90TW9kaWZpZWQ6IDMwNCxcbiAgVXNlUHJveHk6IDMwNSxcbiAgVW51c2VkOiAzMDYsXG4gIFRlbXBvcmFyeVJlZGlyZWN0OiAzMDcsXG4gIFBlcm1hbmVudFJlZGlyZWN0OiAzMDgsXG4gIEJhZFJlcXVlc3Q6IDQwMCxcbiAgVW5hdXRob3JpemVkOiA0MDEsXG4gIFBheW1lbnRSZXF1aXJlZDogNDAyLFxuICBGb3JiaWRkZW46IDQwMyxcbiAgTm90Rm91bmQ6IDQwNCxcbiAgTWV0aG9kTm90QWxsb3dlZDogNDA1LFxuICBOb3RBY2NlcHRhYmxlOiA0MDYsXG4gIFByb3h5QXV0aGVudGljYXRpb25SZXF1aXJlZDogNDA3LFxuICBSZXF1ZXN0VGltZW91dDogNDA4LFxuICBDb25mbGljdDogNDA5LFxuICBHb25lOiA0MTAsXG4gIExlbmd0aFJlcXVpcmVkOiA0MTEsXG4gIFByZWNvbmRpdGlvbkZhaWxlZDogNDEyLFxuICBQYXlsb2FkVG9vTGFyZ2U6IDQxMyxcbiAgVXJpVG9vTG9uZzogNDE0LFxuICBVbnN1cHBvcnRlZE1lZGlhVHlwZTogNDE1LFxuICBSYW5nZU5vdFNhdGlzZmlhYmxlOiA0MTYsXG4gIEV4cGVjdGF0aW9uRmFpbGVkOiA0MTcsXG4gIEltQVRlYXBvdDogNDE4LFxuICBNaXNkaXJlY3RlZFJlcXVlc3Q6IDQyMSxcbiAgVW5wcm9jZXNzYWJsZUVudGl0eTogNDIyLFxuICBMb2NrZWQ6IDQyMyxcbiAgRmFpbGVkRGVwZW5kZW5jeTogNDI0LFxuICBUb29FYXJseTogNDI1LFxuICBVcGdyYWRlUmVxdWlyZWQ6IDQyNixcbiAgUHJlY29uZGl0aW9uUmVxdWlyZWQ6IDQyOCxcbiAgVG9vTWFueVJlcXVlc3RzOiA0MjksXG4gIFJlcXVlc3RIZWFkZXJGaWVsZHNUb29MYXJnZTogNDMxLFxuICBVbmF2YWlsYWJsZUZvckxlZ2FsUmVhc29uczogNDUxLFxuICBJbnRlcm5hbFNlcnZlckVycm9yOiA1MDAsXG4gIE5vdEltcGxlbWVudGVkOiA1MDEsXG4gIEJhZEdhdGV3YXk6IDUwMixcbiAgU2VydmljZVVuYXZhaWxhYmxlOiA1MDMsXG4gIEdhdGV3YXlUaW1lb3V0OiA1MDQsXG4gIEh0dHBWZXJzaW9uTm90U3VwcG9ydGVkOiA1MDUsXG4gIFZhcmlhbnRBbHNvTmVnb3RpYXRlczogNTA2LFxuICBJbnN1ZmZpY2llbnRTdG9yYWdlOiA1MDcsXG4gIExvb3BEZXRlY3RlZDogNTA4LFxuICBOb3RFeHRlbmRlZDogNTEwLFxuICBOZXR3b3JrQXV0aGVudGljYXRpb25SZXF1aXJlZDogNTExLFxufTtcblxuT2JqZWN0LmVudHJpZXMoSHR0cFN0YXR1c0NvZGUpLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICBIdHRwU3RhdHVzQ29kZVt2YWx1ZV0gPSBrZXk7XG59KTtcblxuY29uc3QgSHR0cFN0YXR1c0NvZGUkMSA9IEh0dHBTdGF0dXNDb2RlO1xuXG4vKipcbiAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiBBeGlvc1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBkZWZhdWx0Q29uZmlnIFRoZSBkZWZhdWx0IGNvbmZpZyBmb3IgdGhlIGluc3RhbmNlXG4gKlxuICogQHJldHVybnMge0F4aW9zfSBBIG5ldyBpbnN0YW5jZSBvZiBBeGlvc1xuICovXG5mdW5jdGlvbiBjcmVhdGVJbnN0YW5jZShkZWZhdWx0Q29uZmlnKSB7XG4gIGNvbnN0IGNvbnRleHQgPSBuZXcgQXhpb3MkMShkZWZhdWx0Q29uZmlnKTtcbiAgY29uc3QgaW5zdGFuY2UgPSBiaW5kKEF4aW9zJDEucHJvdG90eXBlLnJlcXVlc3QsIGNvbnRleHQpO1xuXG4gIC8vIENvcHkgYXhpb3MucHJvdG90eXBlIHRvIGluc3RhbmNlXG4gIHV0aWxzLmV4dGVuZChpbnN0YW5jZSwgQXhpb3MkMS5wcm90b3R5cGUsIGNvbnRleHQsIHthbGxPd25LZXlzOiB0cnVlfSk7XG5cbiAgLy8gQ29weSBjb250ZXh0IHRvIGluc3RhbmNlXG4gIHV0aWxzLmV4dGVuZChpbnN0YW5jZSwgY29udGV4dCwgbnVsbCwge2FsbE93bktleXM6IHRydWV9KTtcblxuICAvLyBGYWN0b3J5IGZvciBjcmVhdGluZyBuZXcgaW5zdGFuY2VzXG4gIGluc3RhbmNlLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShpbnN0YW5jZUNvbmZpZykge1xuICAgIHJldHVybiBjcmVhdGVJbnN0YW5jZShtZXJnZUNvbmZpZyhkZWZhdWx0Q29uZmlnLCBpbnN0YW5jZUNvbmZpZykpO1xuICB9O1xuXG4gIHJldHVybiBpbnN0YW5jZTtcbn1cblxuLy8gQ3JlYXRlIHRoZSBkZWZhdWx0IGluc3RhbmNlIHRvIGJlIGV4cG9ydGVkXG5jb25zdCBheGlvcyA9IGNyZWF0ZUluc3RhbmNlKGRlZmF1bHRzJDEpO1xuXG4vLyBFeHBvc2UgQXhpb3MgY2xhc3MgdG8gYWxsb3cgY2xhc3MgaW5oZXJpdGFuY2VcbmF4aW9zLkF4aW9zID0gQXhpb3MkMTtcblxuLy8gRXhwb3NlIENhbmNlbCAmIENhbmNlbFRva2VuXG5heGlvcy5DYW5jZWxlZEVycm9yID0gQ2FuY2VsZWRFcnJvcjtcbmF4aW9zLkNhbmNlbFRva2VuID0gQ2FuY2VsVG9rZW4kMTtcbmF4aW9zLmlzQ2FuY2VsID0gaXNDYW5jZWw7XG5heGlvcy5WRVJTSU9OID0gVkVSU0lPTjtcbmF4aW9zLnRvRm9ybURhdGEgPSB0b0Zvcm1EYXRhO1xuXG4vLyBFeHBvc2UgQXhpb3NFcnJvciBjbGFzc1xuYXhpb3MuQXhpb3NFcnJvciA9IEF4aW9zRXJyb3I7XG5cbi8vIGFsaWFzIGZvciBDYW5jZWxlZEVycm9yIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5XG5heGlvcy5DYW5jZWwgPSBheGlvcy5DYW5jZWxlZEVycm9yO1xuXG4vLyBFeHBvc2UgYWxsL3NwcmVhZFxuYXhpb3MuYWxsID0gZnVuY3Rpb24gYWxsKHByb21pc2VzKSB7XG4gIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XG59O1xuXG5heGlvcy5zcHJlYWQgPSBzcHJlYWQ7XG5cbi8vIEV4cG9zZSBpc0F4aW9zRXJyb3JcbmF4aW9zLmlzQXhpb3NFcnJvciA9IGlzQXhpb3NFcnJvcjtcblxuLy8gRXhwb3NlIG1lcmdlQ29uZmlnXG5heGlvcy5tZXJnZUNvbmZpZyA9IG1lcmdlQ29uZmlnO1xuXG5heGlvcy5BeGlvc0hlYWRlcnMgPSBBeGlvc0hlYWRlcnMkMTtcblxuYXhpb3MuZm9ybVRvSlNPTiA9IHRoaW5nID0+IGZvcm1EYXRhVG9KU09OKHV0aWxzLmlzSFRNTEZvcm0odGhpbmcpID8gbmV3IEZvcm1EYXRhKHRoaW5nKSA6IHRoaW5nKTtcblxuYXhpb3MuZ2V0QWRhcHRlciA9IGFkYXB0ZXJzLmdldEFkYXB0ZXI7XG5cbmF4aW9zLkh0dHBTdGF0dXNDb2RlID0gSHR0cFN0YXR1c0NvZGUkMTtcblxuYXhpb3MuZGVmYXVsdCA9IGF4aW9zO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGF4aW9zO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXhpb3MuY2pzLm1hcFxuIiwiLy8gVGhlIG1vZHVsZSBjYWNoZVxudmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuXG4vLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcblx0dmFyIGNhY2hlZE1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF07XG5cdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBjYWNoZWRNb2R1bGUuZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHRpZDogbW9kdWxlSWQsXG5cdFx0bG9hZGVkOiBmYWxzZSxcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRfX3dlYnBhY2tfbW9kdWxlc19fW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuXHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG5cdG1vZHVsZS5sb2FkZWQgPSB0cnVlO1xuXG5cdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG5cdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbn1cblxuIiwiX193ZWJwYWNrX3JlcXVpcmVfXy5ubWQgPSAobW9kdWxlKSA9PiB7XG5cdG1vZHVsZS5wYXRocyA9IFtdO1xuXHRpZiAoIW1vZHVsZS5jaGlsZHJlbikgbW9kdWxlLmNoaWxkcmVuID0gW107XG5cdHJldHVybiBtb2R1bGU7XG59OyIsIi8vIHN0YXJ0dXBcbi8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuLy8gVGhpcyBlbnRyeSBtb2R1bGUgaXMgcmVmZXJlbmNlZCBieSBvdGhlciBtb2R1bGVzIHNvIGl0IGNhbid0IGJlIGlubGluZWRcbnZhciBfX3dlYnBhY2tfZXhwb3J0c19fID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3NTMwKTtcbiJdLCJuYW1lcyI6WyJyb290IiwiZmFjdG9yeSIsImV4cG9ydHMiLCJtb2R1bGUiLCJkZWZpbmUiLCJhbWQiLCJ0aGlzIiwicGFyYWxsZWwiLCJzZXJpYWwiLCJzZXJpYWxPcmRlcmVkIiwiY2xlYW4iLCJrZXkiLCJqb2JzIiwic3RhdGUiLCJPYmplY3QiLCJrZXlzIiwiZm9yRWFjaCIsImJpbmQiLCJkZWZlciIsImNhbGxiYWNrIiwiaXNBc3luYyIsImVyciIsInJlc3VsdCIsImZuIiwibmV4dFRpY2siLCJzZXRJbW1lZGlhdGUiLCJwcm9jZXNzIiwic2V0VGltZW91dCIsImFzeW5jIiwiYWJvcnQiLCJsaXN0IiwiaXRlcmF0b3IiLCJpbmRleCIsIml0ZW0iLCJhYm9ydGVyIiwibGVuZ3RoIiwicnVuSm9iIiwiZXJyb3IiLCJvdXRwdXQiLCJyZXN1bHRzIiwic29ydE1ldGhvZCIsImlzTmFtZWRMaXN0IiwiQXJyYXkiLCJpc0FycmF5IiwiaW5pdFN0YXRlIiwia2V5ZWRMaXN0Iiwic2l6ZSIsInNvcnQiLCJhIiwiYiIsIml0ZXJhdGUiLCJ0ZXJtaW5hdG9yIiwiYXNjZW5kaW5nIiwiaXRlcmF0b3JIYW5kbGVyIiwiZGVzY2VuZGluZyIsIkNvbWJpbmVkU3RyZWFtIiwidXRpbCIsInBhdGgiLCJodHRwIiwiaHR0cHMiLCJwYXJzZVVybCIsImZzIiwiU3RyZWFtIiwibWltZSIsImFzeW5ja2l0IiwicG9wdWxhdGUiLCJGb3JtRGF0YSIsIm9wdGlvbnMiLCJvcHRpb24iLCJfb3ZlcmhlYWRMZW5ndGgiLCJfdmFsdWVMZW5ndGgiLCJfdmFsdWVzVG9NZWFzdXJlIiwiY2FsbCIsImluaGVyaXRzIiwiTElORV9CUkVBSyIsIkRFRkFVTFRfQ09OVEVOVF9UWVBFIiwicHJvdG90eXBlIiwiYXBwZW5kIiwiZmllbGQiLCJ2YWx1ZSIsImZpbGVuYW1lIiwiX2Vycm9yIiwiRXJyb3IiLCJoZWFkZXIiLCJfbXVsdGlQYXJ0SGVhZGVyIiwiZm9vdGVyIiwiX211bHRpUGFydEZvb3RlciIsIl90cmFja0xlbmd0aCIsInZhbHVlTGVuZ3RoIiwia25vd25MZW5ndGgiLCJCdWZmZXIiLCJpc0J1ZmZlciIsImJ5dGVMZW5ndGgiLCJyZWFkYWJsZSIsImhhc093blByb3BlcnR5IiwicHVzaCIsIl9sZW5ndGhSZXRyaWV2ZXIiLCJ1bmRlZmluZWQiLCJlbmQiLCJJbmZpbml0eSIsInN0YXJ0Iiwic3RhdCIsImZpbGVTaXplIiwiaGVhZGVycyIsIm9uIiwicmVzcG9uc2UiLCJwYXVzZSIsInJlc3VtZSIsImNvbnRlbnREaXNwb3NpdGlvbiIsIl9nZXRDb250ZW50RGlzcG9zaXRpb24iLCJjb250ZW50VHlwZSIsIl9nZXRDb250ZW50VHlwZSIsImNvbnRlbnRzIiwiY29uY2F0IiwicHJvcCIsImpvaW4iLCJnZXRCb3VuZGFyeSIsImZpbGVwYXRoIiwibm9ybWFsaXplIiwicmVwbGFjZSIsIm5hbWUiLCJiYXNlbmFtZSIsImNsaWVudCIsIl9odHRwTWVzc2FnZSIsImxvb2t1cCIsIm5leHQiLCJfc3RyZWFtcyIsIl9sYXN0Qm91bmRhcnkiLCJnZXRIZWFkZXJzIiwidXNlckhlYWRlcnMiLCJmb3JtSGVhZGVycyIsInRvTG93ZXJDYXNlIiwic2V0Qm91bmRhcnkiLCJib3VuZGFyeSIsIl9ib3VuZGFyeSIsIl9nZW5lcmF0ZUJvdW5kYXJ5IiwiZ2V0QnVmZmVyIiwiZGF0YUJ1ZmZlciIsImFsbG9jIiwiaSIsImxlbiIsImZyb20iLCJzdWJzdHJpbmciLCJNYXRoIiwiZmxvb3IiLCJyYW5kb20iLCJ0b1N0cmluZyIsImdldExlbmd0aFN5bmMiLCJoYXNLbm93bkxlbmd0aCIsImdldExlbmd0aCIsImNiIiwidmFsdWVzIiwic3VibWl0IiwicGFyYW1zIiwicmVxdWVzdCIsImRlZmF1bHRzIiwibWV0aG9kIiwicG9ydCIsInBhdGhuYW1lIiwiaG9zdCIsImhvc3RuYW1lIiwicHJvdG9jb2wiLCJzZXRIZWFkZXIiLCJwaXBlIiwib25SZXNwb25zZSIsInJlc3BvbmNlIiwicmVtb3ZlTGlzdGVuZXIiLCJlbWl0IiwiZHN0Iiwic3JjIiwiRG9tYWluIiwiZGF0YSIsInJlY2VpdmluZyIsInNlbmRpbmciLCJyZXF1aXJlX3RscyIsInNraXBfdmVyaWZpY2F0aW9uIiwid2lsZGNhcmQiLCJzcGFtX2FjdGlvbiIsImNyZWF0ZWRfYXQiLCJzbXRwX3Bhc3N3b3JkIiwic210cF9sb2dpbiIsInR5cGUiLCJyZWNlaXZpbmdfZG5zX3JlY29yZHMiLCJzZW5kaW5nX2Ruc19yZWNvcmRzIiwiZHluYW1pY1Byb3BlcnRpZXMiLCJyZWR1Y2UiLCJhY2MiLCJwcm9wZXJ0eU5hbWUiLCJhc3NpZ24iLCJ1cmxfam9pbl8xIiwiX19pbXBvcnREZWZhdWx0IiwicmVxdWlyZSIsIkVycm9yXzEiLCJkb21haW5fMSIsIkRvbWFpbnNDbGllbnQiLCJkb21haW5DcmVkZW50aWFsc0NsaWVudCIsImRvbWFpblRlbXBsYXRlc0NsaWVudCIsImRvbWFpblRhZ3NDbGllbnQiLCJkb21haW5DcmVkZW50aWFscyIsImRvbWFpblRlbXBsYXRlcyIsImRvbWFpblRhZ3MiLCJfaGFuZGxlQm9vbFZhbHVlcyIsInByb3BzRm9yUmVwbGFjZW1lbnQiLCJyZXBsYWNlZFByb3BzIiwiX19hc3NpZ24iLCJfcGFyc2VNZXNzYWdlIiwiYm9keSIsInBhcnNlRG9tYWluTGlzdCIsIml0ZW1zIiwibWFwIiwiZGVmYXVsdCIsIl9wYXJzZURvbWFpbiIsImRvbWFpbiIsIl9wYXJzZVRyYWNraW5nU2V0dGluZ3MiLCJ0cmFja2luZyIsIl9wYXJzZVRyYWNraW5nVXBkYXRlIiwicXVlcnkiLCJfdGhpcyIsImdldCIsInRoZW4iLCJyZXMiLCJjcmVhdGUiLCJwb3N0T2JqIiwicG9zdFdpdGhGRCIsInVwZGF0ZSIsInB1dERhdGEiLCJwdXRXaXRoRkQiLCJ2ZXJpZnkiLCJwdXQiLCJkZXN0cm95IiwiZGVsZXRlIiwiZ2V0Q29ubmVjdGlvbiIsImNvbm5lY3Rpb24iLCJ1cGRhdGVDb25uZWN0aW9uIiwiZ2V0VHJhY2tpbmciLCJ1cGRhdGVUcmFja2luZyIsImFjdGl2ZSIsInN0YXR1cyIsInN0YXR1c1RleHQiLCJtZXNzYWdlIiwiZ2V0SXBzIiwiX2EiLCJhc3NpZ25JcCIsImlwIiwiZGVsZXRlSXAiLCJsaW5rSXBQb29sIiwicG9vbElkIiwicG9vbF9pZCIsInVubGlua0lwUG9sbCIsInJlcGxhY2VtZW50Iiwic2VhcmNoUGFyYW1zIiwidXBkYXRlREtJTUF1dGhvcml0eSIsInNlbGYiLCJ1cGRhdGVES0lNU2VsZWN0b3IiLCJka2ltU2VsZWN0b3IiLCJ1cGRhdGVXZWJQcmVmaXgiLCJ3ZWJQcmVmaXgiLCJEb21haW5DcmVkZW50aWFsc0NsaWVudCIsImJhc2VSb3V0ZSIsIl9wYXJzZURvbWFpbkNyZWRlbnRpYWxzTGlzdCIsInRvdGFsQ291bnQiLCJ0b3RhbF9jb3VudCIsIl9wYXJzZU1lc3NhZ2VSZXNwb25zZSIsIl9wYXJzZURlbGV0ZWRSZXNwb25zZSIsInNwZWMiLCJjcmVkZW50aWFsc0xvZ2luIiwiTmF2aWdhdGlvblRocnVQYWdlc18xIiwiRG9tYWluVGFnIiwidGFnSW5mbyIsInRhZyIsImRlc2NyaXB0aW9uIiwiRGF0ZSIsIkRvbWFpblRhZ1N0YXRpc3RpYyIsInRhZ1N0YXRpc3RpY0luZm8iLCJyZXNvbHV0aW9uIiwic3RhdHMiLCJ0aW1lIiwiRG9tYWluVGFnc0NsaWVudCIsIl9zdXBlciIsIl9fZXh0ZW5kcyIsInBhcnNlTGlzdCIsInBhZ2VzIiwicGFyc2VQYWdlTGlua3MiLCJfcGFyc2VUYWdTdGF0aXN0aWMiLCJyZXF1ZXN0TGlzdFdpdGhQYWdlcyIsInN0YXRpc3RpYyIsImNvdW50cmllcyIsInByb3ZpZGVycyIsImRldmljZXMiLCJEb21haW5UZW1wbGF0ZUl0ZW0iLCJkb21haW5UZW1wbGF0ZUZyb21BUEkiLCJjcmVhdGVkQXQiLCJjcmVhdGVkQnkiLCJpZCIsInZlcnNpb24iLCJ2ZXJzaW9ucyIsIkRvbWFpblRlbXBsYXRlc0NsaWVudCIsInBhcnNlQ3JlYXRpb25SZXNwb25zZSIsInRlbXBsYXRlIiwicGFyc2VDcmVhdGlvblZlcnNpb25SZXNwb25zZSIsInBhcnNlTXV0YXRpb25SZXNwb25zZSIsInRlbXBsYXRlTmFtZSIsInBhcnNlTm90aWZpY2F0aW9uUmVzcG9uc2UiLCJwYXJzZU11dGF0ZVRlbXBsYXRlVmVyc2lvblJlc3BvbnNlIiwidGVtcGxhdGVWZXJzaW9uIiwiZCIsInBhcnNlTGlzdFRlbXBsYXRlVmVyc2lvbnMiLCJkZXN0cm95QWxsIiwiY3JlYXRlVmVyc2lvbiIsImdldFZlcnNpb24iLCJ1cGRhdGVWZXJzaW9uIiwiZGVzdHJveVZlcnNpb24iLCJsaXN0VmVyc2lvbnMiLCJFdmVudENsaWVudCIsIklwUG9vbHNDbGllbnQiLCJwYXJzZUlwUG9vbHNSZXNwb25zZSIsInNlbnQiLCJwYXRjaFdpdGhGRCIsIklwc0NsaWVudCIsInBhcnNlSXBzUmVzcG9uc2UiLCJSZXF1ZXN0XzEiLCJkb21haW5zQ2xpZW50XzEiLCJFdmVudHNfMSIsIlN0YXRzQ2xpZW50XzEiLCJTdXBwcmVzc2lvbnNDbGllbnRfMSIsIldlYmhvb2tzXzEiLCJNZXNzYWdlc18xIiwiUm91dGVzXzEiLCJ2YWxpZGF0ZV8xIiwiSVBzXzEiLCJJUFBvb2xzXzEiLCJtYWlsaW5nTGlzdHNfMSIsIm1haWxMaXN0TWVtYmVyc18xIiwiZG9tYWluc0NyZWRlbnRpYWxzXzEiLCJtdWx0aXBsZVZhbGlkYXRpb25fMSIsImRvbWFpbnNUZW1wbGF0ZXNfMSIsImRvbWFpbnNUYWdzXzEiLCJTdWJhY2NvdW50c18xIiwiTWFpbGd1bkNsaWVudCIsImZvcm1EYXRhIiwiY29uZmlnIiwidXJsIiwidXNlcm5hbWUiLCJtYWlsTGlzdHNNZW1iZXJzIiwibXVsdGlwbGVWYWxpZGF0aW9uQ2xpZW50IiwiZG9tYWlucyIsIndlYmhvb2tzIiwiZXZlbnRzIiwic3VwcHJlc3Npb25zIiwibWVzc2FnZXMiLCJyb3V0ZXMiLCJpcHMiLCJpcF9wb29scyIsImxpc3RzIiwidmFsaWRhdGUiLCJzdWJhY2NvdW50cyIsInNldFN1YmFjY291bnQiLCJzdWJhY2NvdW50SWQiLCJzZXRTdWJhY2NvdW50SGVhZGVyIiwicmVzZXRTdWJhY2NvdW50IiwicmVzZXRTdWJhY2NvdW50SGVhZGVyIiwiTWFpbExpc3RzTWVtYmVycyIsImNoZWNrQW5kVXBkYXRlRGF0YSIsIm5ld0RhdGEiLCJ2YXJzIiwiSlNPTiIsInN0cmluZ2lmeSIsInN1YnNjcmliZWQiLCJsaXN0TWVtYmVycyIsIm1haWxMaXN0QWRkcmVzcyIsImdldE1lbWJlciIsIm1haWxMaXN0TWVtYmVyQWRkcmVzcyIsIm1lbWJlciIsImNyZWF0ZU1lbWJlciIsInJlcURhdGEiLCJjcmVhdGVNZW1iZXJzIiwibWVtYmVycyIsInVwc2VydCIsInVwZGF0ZU1lbWJlciIsImRlc3Ryb3lNZW1iZXIiLCJNYWlsaW5nTGlzdHNDbGllbnQiLCJwYXJzZVZhbGlkYXRpb25SZXN1bHQiLCJ2YWxpZGF0aW9uUmVzdWx0IiwicG9zdCIsImNhbmNlbFZhbGlkYXRpb24iLCJNZXNzYWdlc0NsaWVudCIsInByZXBhcmVCb29sZWFuVmFsdWVzIiwieWVzTm9Qcm9wZXJ0aWVzIiwiU2V0IiwiaGFzIiwiX3BhcnNlUmVzcG9uc2UiLCJtb2RpZmllZERhdGEiLCJSb3V0ZXNDbGllbnQiLCJyb3V0ZSIsIlN0YXRzQ29udGFpbmVyXzEiLCJTdGF0c0NsaWVudCIsImxvZ2dlciIsImNvbnNvbGUiLCJjb252ZXJ0RGF0ZVRvVVRDIiwiaW5wdXREYXRlIiwid2FybiIsInRvVVRDU3RyaW5nIiwicHJlcGFyZVNlYXJjaFBhcmFtcyIsImVudHJpZXMiLCJhcnJheVdpdGhQYWlycyIsImN1cnJlbnRQYWlyIiwicmVwZWF0ZWRQcm9wZXJ0eSIsIl9fc3ByZWFkQXJyYXkiLCJwYXJzZVN0YXRzIiwiZ2V0RG9tYWluIiwiZ2V0QWNjb3VudCIsIlN0YXRzQ29udGFpbmVyIiwiU3ViYWNjb3VudHNDbGllbnQiLCJlbmFibGUiLCJkaXNhYmxlIiwiU1VCQUNDT1VOVF9IRUFERVIiLCJFbnVtc18xIiwiQm91bmNlIiwiU3VwcHJlc3Npb25Nb2RlbHMiLCJCT1VOQ0VTIiwiYWRkcmVzcyIsImNvZGUiLCJDb21wbGFpbnQiLCJDT01QTEFJTlRTIiwiU3VwcHJlc3Npb24iLCJCb3VuY2VfMSIsIkNvbXBsYWludF8xIiwiVW5zdWJzY3JpYmVfMSIsIldoaXRlTGlzdF8xIiwiY3JlYXRlT3B0aW9ucyIsIlN1cHByZXNzaW9uQ2xpZW50IiwibW9kZWxzIiwiYm91bmNlcyIsImNvbXBsYWludHMiLCJ1bnN1YnNjcmliZXMiLCJ3aGl0ZWxpc3RzIiwiTW9kZWwiLCJfcGFyc2VJdGVtIiwiY3JlYXRlV2hpdGVMaXN0IiwiaXNEYXRhQXJyYXkiLCJwcmVwYXJlUmVzcG9uc2UiLCJjcmVhdGVVbnN1YnNjcmliZSIsInNvbWUiLCJ1bnN1YnNjcmliZSIsInRhZ3MiLCJnZXRNb2RlbCIsIm1vZGVsIiwiZW5jb2RlVVJJQ29tcG9uZW50IiwicG9zdERhdGEiLCJVbnN1YnNjcmliZSIsIlVOU1VCU0NSSUJFUyIsIldoaXRlTGlzdCIsIldISVRFTElTVFMiLCJyZWFzb24iLCJNdWx0aXBsZVZhbGlkYXRpb25Kb2IiLCJyZXNwb25zZVN0YXR1c0NvZGUiLCJxdWFudGl0eSIsInJlY29yZHNQcm9jZXNzZWQiLCJyZWNvcmRzX3Byb2Nlc3NlZCIsImRvd25sb2FkX3VybCIsImRvd25sb2FkVXJsIiwiY3N2IiwianNvbiIsIl9iIiwic3VtbWFyeSIsImNhdGNoQWxsIiwiY2F0Y2hfYWxsIiwiZGVsaXZlcmFibGUiLCJkb05vdFNlbmQiLCJkb19ub3Rfc2VuZCIsInVuZGVsaXZlcmFibGUiLCJ1bmtub3duIiwicmlzayIsImhpZ2giLCJsb3ciLCJtZWRpdW0iLCJNdWx0aXBsZVZhbGlkYXRpb25DbGllbnQiLCJoYW5kbGVSZXNwb25zZSIsImpvYiIsInRvdGFsIiwibGlzdElkIiwibXVsdGlwbGVWYWxpZGF0aW9uRGF0YSIsIm11bHRpcGxlVmFsaWRhdGlvbkZpbGUiLCJmaWxlIiwiVmFsaWRhdGVDbGllbnQiLCJtdWx0aXBsZVZhbGlkYXRpb24iLCJXZWJob29rIiwidXJscyIsIldlYmhvb2tzQ2xpZW50IiwiX3BhcnNlV2ViaG9va0xpc3QiLCJfcGFyc2VXZWJob29rV2l0aElEIiwid2ViaG9va1Jlc3BvbnNlIiwid2ViaG9vayIsIl9wYXJzZVdlYmhvb2tUZXN0IiwidGVzdCIsInVybFZhbHVlcyIsIkFQSUVycm9yIiwiYm9keU1lc3NhZ2UiLCJzdGFjayIsImRldGFpbHMiLCJGb3JtRGF0YUJ1aWxkZXIiLCJGb3JtRGF0YUNvbnN0cnVjdG9yIiwiY3JlYXRlRm9ybURhdGEiLCJmaWx0ZXIiLCJmb3JtRGF0YUFjYyIsImluY2x1ZGVzIiwiYWRkRmlsZXNUb0ZEIiwiYWRkTWltZURhdGFUb0ZEIiwiYWRkQ29tbW9uUHJvcGVydHlUb0ZEIiwiaXNGb3JtRGF0YVBhY2thZ2UiLCJmb3JtRGF0YUluc3RhbmNlIiwiZ2V0QXR0YWNobWVudE9wdGlvbnMiLCJpc1N0cmVhbSIsIkJsb2IiLCJicm93c2VyRm9ybURhdGEiLCJibG9iSW5zdGFuY2UiLCJhcHBlbmRGaWxlVG9GRCIsIm9yaWdpbmFsS2V5Iiwib2JqIiwib2JqRGF0YSIsImZkIiwiTmF2aWdhdGlvblRocnVQYWdlcyIsInBhcnNlUGFnZSIsInBhZ2VVcmwiLCJ1cmxTZXBhcmF0b3IiLCJpdGVyYXRvck5hbWUiLCJVUkwiLCJwYWdlVmFsdWUiLCJzcGxpdCIsInBvcCIsIml0ZXJhdG9yUG9zaXRpb24iLCJwYWdlIiwicGFnaW5nIiwidXBkYXRlVXJsQW5kUXVlcnkiLCJjbGllbnRVcmwiLCJxdWVyeUNvcHkiLCJ1cGRhdGVkUXVlcnkiLCJiYXNlNjQiLCJfX2ltcG9ydFN0YXIiLCJheGlvc18xIiwiRm9ybURhdGFCdWlsZGVyXzEiLCJSZXF1ZXN0IiwidGltZW91dCIsIm1ha2VIZWFkZXJzRnJvbU9iamVjdCIsImZvcm1EYXRhQnVpbGRlciIsIm1heEJvZHlMZW5ndGgiLCJwcm94eSIsIm9uQ2FsbE9wdGlvbnMiLCJyZXF1ZXN0SGVhZGVycyIsImpvaW5BbmRUcmFuc2Zvcm1IZWFkZXJzIiwiZ2V0T3duUHJvcGVydHlOYW1lcyIsIlVSTFNlYXJjaFBhcmFtcyIsInVybFZhbHVlIiwidG9Mb2NhbGVVcHBlckNhc2UiLCJfZCIsImVycm9yUmVzcG9uc2UiLCJlcnJfMSIsIl9jIiwiZ2V0UmVzcG9uc2VCb2R5IiwiQXhpb3NIZWFkZXJzIiwiYmFzaWMiLCJlbmNvZGUiLCJzZXRBdXRob3JpemF0aW9uIiwic2V0IiwicmVjZWl2ZWRPbkNhbGxIZWFkZXJzIiwib25DYWxsSGVhZGVycyIsImhlYWRlcnNPYmplY3QiLCJoZWFkZXJzQWNjdW11bGF0b3IiLCJjb21tYW5kIiwiYWRkRGVmYXVsdEhlYWRlcnMiLCJyZXF1ZXN0T3B0aW9ucyIsIlJlc29sdXRpb24iLCJXZWJob29rc0lkcyIsIlllc05vIiwiX19leHBvcnRTdGFyIiwiTWFpbGd1bkNsaWVudF8xIiwiTWFpbGd1biIsImRlZmluZVByb3BlcnR5IiwiZnJlZUV4cG9ydHMiLCJmcmVlR2xvYmFsIiwiZ2xvYmFsIiwid2luZG93IiwiSW52YWxpZENoYXJhY3RlckVycm9yIiwiVEFCTEUiLCJSRUdFWF9TUEFDRV9DSEFSQUNURVJTIiwiaW5wdXQiLCJTdHJpbmciLCJjIiwiYnVmZmVyIiwicGFkZGluZyIsInBvc2l0aW9uIiwiY2hhckNvZGVBdCIsImNoYXJBdCIsImJpdFN0b3JhZ2UiLCJiaXRDb3VudGVyIiwiaW5kZXhPZiIsImZyb21DaGFyQ29kZSIsIkRlbGF5ZWRTdHJlYW0iLCJ3cml0YWJsZSIsImRhdGFTaXplIiwibWF4RGF0YVNpemUiLCJwYXVzZVN0cmVhbXMiLCJfcmVsZWFzZWQiLCJfY3VycmVudFN0cmVhbSIsIl9pbnNpZGVMb29wIiwiX3BlbmRpbmdOZXh0IiwiY29tYmluZWRTdHJlYW0iLCJpc1N0cmVhbUxpa2UiLCJzdHJlYW0iLCJuZXdTdHJlYW0iLCJwYXVzZVN0cmVhbSIsIl9jaGVja0RhdGFTaXplIiwiX2hhbmRsZUVycm9ycyIsImRlc3QiLCJfZ2V0TmV4dCIsIl9yZWFsR2V0TmV4dCIsInNoaWZ0IiwiX3BpcGVOZXh0Iiwid3JpdGUiLCJfZW1pdEVycm9yIiwiX3Jlc2V0IiwiX3VwZGF0ZURhdGFTaXplIiwiZm9ybWF0QXJncyIsImFyZ3MiLCJ1c2VDb2xvcnMiLCJuYW1lc3BhY2UiLCJodW1hbml6ZSIsImRpZmYiLCJjb2xvciIsInNwbGljZSIsImxhc3RDIiwibWF0Y2giLCJzYXZlIiwibmFtZXNwYWNlcyIsInN0b3JhZ2UiLCJzZXRJdGVtIiwicmVtb3ZlSXRlbSIsImxvYWQiLCJyIiwiZ2V0SXRlbSIsImVudiIsIkRFQlVHIiwiX19ud2pzIiwibmF2aWdhdG9yIiwidXNlckFnZW50IiwiZG9jdW1lbnQiLCJkb2N1bWVudEVsZW1lbnQiLCJzdHlsZSIsIldlYmtpdEFwcGVhcmFuY2UiLCJmaXJlYnVnIiwiZXhjZXB0aW9uIiwidGFibGUiLCJwYXJzZUludCIsIlJlZ0V4cCIsIiQxIiwibG9jYWxTdG9yYWdlIiwibG9jYWxzdG9yYWdlIiwid2FybmVkIiwiY29sb3JzIiwibG9nIiwiZGVidWciLCJmb3JtYXR0ZXJzIiwiaiIsInYiLCJjcmVhdGVEZWJ1ZyIsInByZXZUaW1lIiwibmFtZXNwYWNlc0NhY2hlIiwiZW5hYmxlZENhY2hlIiwiZW5hYmxlT3ZlcnJpZGUiLCJlbmFibGVkIiwiY3VyciIsIk51bWJlciIsIm1zIiwicHJldiIsImNvZXJjZSIsInVuc2hpZnQiLCJmb3JtYXQiLCJmb3JtYXR0ZXIiLCJ2YWwiLCJhcHBseSIsInNlbGVjdENvbG9yIiwiZXh0ZW5kIiwiZW51bWVyYWJsZSIsImNvbmZpZ3VyYWJsZSIsImluaXQiLCJkZWxpbWl0ZXIiLCJuZXdEZWJ1ZyIsInRvTmFtZXNwYWNlIiwicmVnZXhwIiwibmFtZXMiLCJza2lwcyIsInNsaWNlIiwiaGFzaCIsImFicyIsImJyb3dzZXIiLCJ0dHkiLCJpbnNwZWN0T3B0cyIsInN0ZGVyciIsImNvbG9yQ29kZSIsInByZWZpeCIsImhpZGVEYXRlIiwidG9JU09TdHJpbmciLCJnZXREYXRlIiwiQm9vbGVhbiIsImlzYXR0eSIsImRlcHJlY2F0ZSIsInN1cHBvcnRzQ29sb3IiLCJsZXZlbCIsIl8iLCJrIiwidG9VcHBlckNhc2UiLCJvIiwiaW5zcGVjdCIsInN0ciIsInRyaW0iLCJPIiwic291cmNlIiwiX21heERhdGFTaXplRXhjZWVkZWQiLCJfYnVmZmVyZWRFdmVudHMiLCJkZWxheWVkU3RyZWFtIiwicmVhbEVtaXQiLCJfaGFuZGxlRW1pdCIsImFyZ3VtZW50cyIsInNldEVuY29kaW5nIiwicmVsZWFzZSIsIl9jaGVja0lmTWF4RGF0YVNpemVFeGNlZWRlZCIsIldyaXRhYmxlIiwiYXNzZXJ0IiwidXNlTmF0aXZlVVJMIiwicHJlc2VydmVkVXJsRmllbGRzIiwiZXZlbnRIYW5kbGVycyIsImV2ZW50IiwiYXJnMSIsImFyZzIiLCJhcmczIiwiX3JlZGlyZWN0YWJsZSIsIkludmFsaWRVcmxFcnJvciIsImNyZWF0ZUVycm9yVHlwZSIsIlR5cGVFcnJvciIsIlJlZGlyZWN0aW9uRXJyb3IiLCJUb29NYW55UmVkaXJlY3RzRXJyb3IiLCJNYXhCb2R5TGVuZ3RoRXhjZWVkZWRFcnJvciIsIldyaXRlQWZ0ZXJFbmRFcnJvciIsIm5vb3AiLCJSZWRpcmVjdGFibGVSZXF1ZXN0IiwicmVzcG9uc2VDYWxsYmFjayIsIl9zYW5pdGl6ZU9wdGlvbnMiLCJfb3B0aW9ucyIsIl9lbmRlZCIsIl9lbmRpbmciLCJfcmVkaXJlY3RDb3VudCIsIl9yZWRpcmVjdHMiLCJfcmVxdWVzdEJvZHlMZW5ndGgiLCJfcmVxdWVzdEJvZHlCdWZmZXJzIiwiX29uTmF0aXZlUmVzcG9uc2UiLCJfcHJvY2Vzc1Jlc3BvbnNlIiwiY2F1c2UiLCJfcGVyZm9ybVJlcXVlc3QiLCJ3cmFwIiwicHJvdG9jb2xzIiwibWF4UmVkaXJlY3RzIiwibmF0aXZlUHJvdG9jb2xzIiwic2NoZW1lIiwibmF0aXZlUHJvdG9jb2wiLCJ3cmFwcGVkUHJvdG9jb2wiLCJkZWZpbmVQcm9wZXJ0aWVzIiwic3ByZWFkVXJsT2JqZWN0IiwiaXNTdHJpbmciLCJ2YWxpZGF0ZVVybCIsImlzRnVuY3Rpb24iLCJlcXVhbCIsIndyYXBwZWRSZXF1ZXN0IiwicGFyc2VkIiwicGFyc2UiLCJocmVmIiwidXJsT2JqZWN0IiwidGFyZ2V0Iiwic3ByZWFkIiwic3RhcnRzV2l0aCIsInNlYXJjaCIsInJlbW92ZU1hdGNoaW5nSGVhZGVycyIsInJlZ2V4IiwibGFzdFZhbHVlIiwiYmFzZUNsYXNzIiwiQ3VzdG9tRXJyb3IiLCJwcm9wZXJ0aWVzIiwiY2FwdHVyZVN0YWNrVHJhY2UiLCJjb25zdHJ1Y3RvciIsImRlc3Ryb3lSZXF1ZXN0IiwiX2N1cnJlbnRSZXF1ZXN0IiwiZW5jb2RpbmciLCJjdXJyZW50UmVxdWVzdCIsInJlbW92ZUhlYWRlciIsIm1zZWNzIiwiZGVzdHJveU9uVGltZW91dCIsInNvY2tldCIsImFkZExpc3RlbmVyIiwic3RhcnRUaW1lciIsIl90aW1lb3V0IiwiY2xlYXJUaW1lb3V0IiwiY2xlYXJUaW1lciIsIm9uY2UiLCJwcm9wZXJ0eSIsInNlYXJjaFBvcyIsImFnZW50cyIsImFnZW50IiwiX2N1cnJlbnRVcmwiLCJfaXNSZWRpcmVjdCIsImJ1ZmZlcnMiLCJ3cml0ZU5leHQiLCJmaW5pc2hlZCIsInN0YXR1c0NvZGUiLCJ0cmFja1JlZGlyZWN0cyIsImxvY2F0aW9uIiwiZm9sbG93UmVkaXJlY3RzIiwicmVzcG9uc2VVcmwiLCJyZWRpcmVjdHMiLCJiZWZvcmVSZWRpcmVjdCIsIkhvc3QiLCJyZXEiLCJnZXRIZWFkZXIiLCJyZWxhdGl2ZSIsImJhc2UiLCJjdXJyZW50SG9zdEhlYWRlciIsImN1cnJlbnRVcmxQYXJ0cyIsImN1cnJlbnRIb3N0IiwiY3VycmVudFVybCIsInJlZGlyZWN0VXJsIiwicmVzb2x2ZSIsInN1YmRvbWFpbiIsImRvdCIsImVuZHNXaXRoIiwiaXNTdWJkb21haW4iLCJyZXNwb25zZURldGFpbHMiLCJyZXF1ZXN0RGV0YWlscyIsImZsYWciLCJhcmd2IiwicG9zIiwidGVybWluYXRvclBvcyIsImV4dGVuc2lvbnMiLCJ0eXBlcyIsInByZWZlcmVuY2UiLCJkYiIsImV4dG5hbWUiLCJFWFRSQUNUX1RZUEVfUkVHRVhQIiwiVEVYVF9UWVBFX1JFR0VYUCIsImNoYXJzZXQiLCJleGVjIiwiY2hhcnNldHMiLCJleHRlbnNpb24iLCJleHRzIiwic3Vic3RyIiwidG8iLCJzIiwibSIsImgiLCJ3IiwieSIsInBsdXJhbCIsIm1zQWJzIiwibiIsImlzUGx1cmFsIiwicm91bmQiLCJwYXJzZUZsb2F0IiwiaXNGaW5pdGUiLCJsb25nIiwiZm10TG9uZyIsImZtdFNob3J0IiwiREVGQVVMVF9QT1JUUyIsImZ0cCIsImdvcGhlciIsIndzIiwid3NzIiwic3RyaW5nRW5kc1dpdGgiLCJnZXRFbnYiLCJnZXRQcm94eUZvclVybCIsInBhcnNlZFVybCIsInByb3RvIiwiTk9fUFJPWFkiLCJldmVyeSIsInBhcnNlZFByb3h5IiwicGFyc2VkUHJveHlIb3N0bmFtZSIsInBhcnNlZFByb3h5UG9ydCIsInNob3VsZFByb3h5Iiwib3MiLCJoYXNGbGFnIiwiZm9yY2VDb2xvciIsImdldFN1cHBvcnRMZXZlbCIsImlzVFRZIiwibWluIiwicGxhdGZvcm0iLCJvc1JlbGVhc2UiLCJub2RlIiwic2lnbiIsIkNJX05BTUUiLCJURUFNQ0lUWV9WRVJTSU9OIiwiQ09MT1JURVJNIiwiVEVSTV9QUk9HUkFNX1ZFUlNJT04iLCJURVJNX1BST0dSQU0iLCJURVJNIiwiaGFzQmFzaWMiLCJoYXMyNTYiLCJoYXMxNm0iLCJ0cmFuc2xhdGVMZXZlbCIsIkZPUkNFX0NPTE9SIiwic3Rkb3V0Iiwic3RyQXJyYXkiLCJyZXN1bHRBcnJheSIsImZpcnN0IiwiY29tcG9uZW50IiwicGFydHMiLCJkZWZpbml0aW9uIiwiRm9ybURhdGEkMSIsInByb3h5RnJvbUVudiIsInpsaWIiLCJFdmVudEVtaXR0ZXIiLCJfaW50ZXJvcERlZmF1bHRMZWdhY3kiLCJlIiwiRm9ybURhdGFfX2RlZmF1bHQiLCJ1cmxfX2RlZmF1bHQiLCJodHRwX19kZWZhdWx0IiwiaHR0cHNfX2RlZmF1bHQiLCJ1dGlsX19kZWZhdWx0IiwiZm9sbG93UmVkaXJlY3RzX19kZWZhdWx0IiwiemxpYl9fZGVmYXVsdCIsInN0cmVhbV9fZGVmYXVsdCIsIkV2ZW50RW1pdHRlcl9fZGVmYXVsdCIsInRoaXNBcmciLCJnZXRQcm90b3R5cGVPZiIsImtpbmRPZiIsImNhY2hlIiwidGhpbmciLCJraW5kT2ZUZXN0IiwidHlwZU9mVGVzdCIsImlzVW5kZWZpbmVkIiwiaXNBcnJheUJ1ZmZlciIsImlzTnVtYmVyIiwiaXNPYmplY3QiLCJpc1BsYWluT2JqZWN0IiwiU3ltYm9sIiwidG9TdHJpbmdUYWciLCJpc0RhdGUiLCJpc0ZpbGUiLCJpc0Jsb2IiLCJpc0ZpbGVMaXN0IiwiaXNVUkxTZWFyY2hQYXJhbXMiLCJhbGxPd25LZXlzIiwibCIsImZpbmRLZXkiLCJfa2V5IiwiX2dsb2JhbCIsImdsb2JhbFRoaXMiLCJpc0NvbnRleHREZWZpbmVkIiwiY29udGV4dCIsImlzVHlwZWRBcnJheSIsIlR5cGVkQXJyYXkiLCJVaW50OEFycmF5IiwiaXNIVE1MRm9ybSIsImlzUmVnRXhwIiwicmVkdWNlRGVzY3JpcHRvcnMiLCJyZWR1Y2VyIiwiZGVzY3JpcHRvcnMiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwicmVkdWNlZERlc2NyaXB0b3JzIiwiZGVzY3JpcHRvciIsInJldCIsIkFMUEhBIiwiRElHSVQiLCJBTFBIQUJFVCIsIkFMUEhBX0RJR0lUIiwiaXNBc3luY0ZuIiwidXRpbHMiLCJpc0Zvcm1EYXRhIiwia2luZCIsImlzQXJyYXlCdWZmZXJWaWV3IiwiQXJyYXlCdWZmZXIiLCJpc1ZpZXciLCJpc0Jvb2xlYW4iLCJtZXJnZSIsImNhc2VsZXNzIiwiYXNzaWduVmFsdWUiLCJ0YXJnZXRLZXkiLCJzdHJpcEJPTSIsImNvbnRlbnQiLCJzdXBlckNvbnN0cnVjdG9yIiwicHJvcHMiLCJ0b0ZsYXRPYmplY3QiLCJzb3VyY2VPYmoiLCJkZXN0T2JqIiwicHJvcEZpbHRlciIsIm1lcmdlZCIsInNlYXJjaFN0cmluZyIsImxhc3RJbmRleCIsInRvQXJyYXkiLCJhcnIiLCJmb3JFYWNoRW50cnkiLCJkb25lIiwicGFpciIsIm1hdGNoQWxsIiwicmVnRXhwIiwibWF0Y2hlcyIsImhhc093blByb3AiLCJmcmVlemVNZXRob2RzIiwidG9PYmplY3RTZXQiLCJhcnJheU9yU3RyaW5nIiwidG9DYW1lbENhc2UiLCJwMSIsInAyIiwidG9GaW5pdGVOdW1iZXIiLCJkZWZhdWx0VmFsdWUiLCJnZW5lcmF0ZVN0cmluZyIsImFscGhhYmV0IiwiaXNTcGVjQ29tcGxpYW50Rm9ybSIsInRvSlNPTk9iamVjdCIsInZpc2l0IiwicmVkdWNlZFZhbHVlIiwiaXNUaGVuYWJsZSIsImNhdGNoIiwiQXhpb3NFcnJvciIsInRvSlNPTiIsIm51bWJlciIsImZpbGVOYW1lIiwibGluZU51bWJlciIsImNvbHVtbk51bWJlciIsInByb3RvdHlwZSQxIiwiaXNWaXNpdGFibGUiLCJyZW1vdmVCcmFja2V0cyIsInJlbmRlcktleSIsImRvdHMiLCJ0b2tlbiIsImN1c3RvbVByb3BzIiwiYXhpb3NFcnJvciIsInByZWRpY2F0ZXMiLCJ0b0Zvcm1EYXRhIiwibWV0YVRva2VucyIsImluZGV4ZXMiLCJ2aXNpdG9yIiwiZGVmYXVsdFZpc2l0b3IiLCJ1c2VCbG9iIiwiY29udmVydFZhbHVlIiwiaXNGbGF0QXJyYXkiLCJlbCIsImV4cG9zZWRIZWxwZXJzIiwiYnVpbGQiLCJlbmNvZGUkMSIsImNoYXJNYXAiLCJBeGlvc1VSTFNlYXJjaFBhcmFtcyIsIl9wYWlycyIsImJ1aWxkVVJMIiwiX2VuY29kZSIsInNlcmlhbGl6ZUZuIiwic2VyaWFsaXplIiwic2VyaWFsaXplZFBhcmFtcyIsImhhc2htYXJrSW5kZXgiLCJlbmNvZGVyIiwiSW50ZXJjZXB0b3JNYW5hZ2VyJDEiLCJJbnRlcmNlcHRvck1hbmFnZXIiLCJoYW5kbGVycyIsInVzZSIsImZ1bGZpbGxlZCIsInJlamVjdGVkIiwic3luY2hyb25vdXMiLCJydW5XaGVuIiwiZWplY3QiLCJjbGVhciIsInRyYW5zaXRpb25hbERlZmF1bHRzIiwic2lsZW50SlNPTlBhcnNpbmciLCJmb3JjZWRKU09OUGFyc2luZyIsImNsYXJpZnlUaW1lb3V0RXJyb3IiLCJpc05vZGUiLCJjbGFzc2VzIiwiZm9ybURhdGFUb0pTT04iLCJidWlsZFBhdGgiLCJpc051bWVyaWNLZXkiLCJpc0xhc3QiLCJhcnJheVRvT2JqZWN0IiwicGFyc2VQcm9wUGF0aCIsInRyYW5zaXRpb25hbCIsImFkYXB0ZXIiLCJ0cmFuc2Zvcm1SZXF1ZXN0IiwiZ2V0Q29udGVudFR5cGUiLCJoYXNKU09OQ29udGVudFR5cGUiLCJpc09iamVjdFBheWxvYWQiLCJzZXRDb250ZW50VHlwZSIsImhlbHBlcnMiLCJ0b1VSTEVuY29kZWRGb3JtIiwiZm9ybVNlcmlhbGl6ZXIiLCJfRm9ybURhdGEiLCJyYXdWYWx1ZSIsInBhcnNlciIsInN0cmluZ2lmeVNhZmVseSIsInRyYW5zZm9ybVJlc3BvbnNlIiwiSlNPTlJlcXVlc3RlZCIsInJlc3BvbnNlVHlwZSIsInN0cmljdEpTT05QYXJzaW5nIiwiRVJSX0JBRF9SRVNQT05TRSIsInhzcmZDb29raWVOYW1lIiwieHNyZkhlYWRlck5hbWUiLCJtYXhDb250ZW50TGVuZ3RoIiwidmFsaWRhdGVTdGF0dXMiLCJjb21tb24iLCJkZWZhdWx0cyQxIiwiaWdub3JlRHVwbGljYXRlT2YiLCIkaW50ZXJuYWxzIiwibm9ybWFsaXplSGVhZGVyIiwibm9ybWFsaXplVmFsdWUiLCJtYXRjaEhlYWRlclZhbHVlIiwiaXNIZWFkZXJOYW1lRmlsdGVyIiwidmFsdWVPclJld3JpdGUiLCJyZXdyaXRlIiwiX3ZhbHVlIiwiX2hlYWRlciIsIl9yZXdyaXRlIiwibEhlYWRlciIsInNldEhlYWRlcnMiLCJyYXdIZWFkZXJzIiwibGluZSIsInBhcnNlSGVhZGVycyIsInRva2VucyIsInRva2Vuc1JFIiwicGFyc2VUb2tlbnMiLCJtYXRjaGVyIiwiZGVsZXRlZCIsImRlbGV0ZUhlYWRlciIsIm5vcm1hbGl6ZWQiLCJjaGFyIiwiZm9ybWF0SGVhZGVyIiwidGFyZ2V0cyIsImFzU3RyaW5ncyIsInN0YXRpYyIsImNvbXB1dGVkIiwiYWNjZXNzb3JzIiwiZGVmaW5lQWNjZXNzb3IiLCJhY2Nlc3Nvck5hbWUiLCJtZXRob2ROYW1lIiwiYnVpbGRBY2Nlc3NvcnMiLCJhY2Nlc3NvciIsIm1hcHBlZCIsImhlYWRlclZhbHVlIiwiQXhpb3NIZWFkZXJzJDEiLCJ0cmFuc2Zvcm1EYXRhIiwiZm5zIiwiaXNDYW5jZWwiLCJfX0NBTkNFTF9fIiwiQ2FuY2VsZWRFcnJvciIsIkVSUl9DQU5DRUxFRCIsInNldHRsZSIsInJlamVjdCIsIkVSUl9CQURfUkVRVUVTVCIsImJ1aWxkRnVsbFBhdGgiLCJiYXNlVVJMIiwicmVxdWVzdGVkVVJMIiwiaXNBYnNvbHV0ZVVSTCIsInJlbGF0aXZlVVJMIiwiY29tYmluZVVSTHMiLCJWRVJTSU9OIiwicGFyc2VQcm90b2NvbCIsIkRBVEFfVVJMX1BBVFRFUk4iLCJzcGVlZG9tZXRlciIsInNhbXBsZXNDb3VudCIsImJ5dGVzIiwidGltZXN0YW1wcyIsImZpcnN0U2FtcGxlVFMiLCJoZWFkIiwidGFpbCIsImNodW5rTGVuZ3RoIiwibm93Iiwic3RhcnRlZEF0IiwiYnl0ZXNDb3VudCIsInBhc3NlZCIsImtJbnRlcm5hbHMiLCJBeGlvc1RyYW5zZm9ybVN0cmVhbSIsIlRyYW5zZm9ybSIsInN1cGVyIiwicmVhZGFibGVIaWdoV2F0ZXJNYXJrIiwibWF4UmF0ZSIsImNodW5rU2l6ZSIsIm1pbkNodW5rU2l6ZSIsInRpbWVXaW5kb3ciLCJ0aWNrc1JhdGUiLCJpbnRlcm5hbHMiLCJieXRlc1NlZW4iLCJpc0NhcHR1cmVkIiwibm90aWZpZWRCeXRlc0xvYWRlZCIsInRzIiwib25SZWFkQ2FsbGJhY2siLCJfc3BlZWRvbWV0ZXIiLCJieXRlc05vdGlmaWVkIiwidXBkYXRlUHJvZ3Jlc3MiLCJmcmVxIiwidGltZXN0YW1wIiwidGhyZXNob2xkIiwidGltZXIiLCJmb3JjZSIsInRocm90dGxlIiwidG90YWxCeXRlcyIsImJ5dGVzVHJhbnNmZXJyZWQiLCJwcm9ncmVzc0J5dGVzIiwiZGVzdHJveWVkIiwicmF0ZSIsIm9uRmluaXNoIiwiX3JlYWQiLCJfdHJhbnNmb3JtIiwiY2h1bmsiLCJieXRlc1RocmVzaG9sZCIsIm1heCIsInRyYW5zZm9ybUNodW5rIiwiX2NodW5rIiwiX2NhbGxiYWNrIiwiYnl0ZXNMZWZ0IiwiY2h1bmtSZW1haW5kZXIiLCJtYXhDaHVua1NpemUiLCJzdWJhcnJheSIsInB1c2hDaHVuayIsInRyYW5zZm9ybU5leHRDaHVuayIsInNldExlbmd0aCIsIkF4aW9zVHJhbnNmb3JtU3RyZWFtJDEiLCJhc3luY0l0ZXJhdG9yIiwicmVhZEJsb2IkMSIsImJsb2IiLCJhcnJheUJ1ZmZlciIsIkJPVU5EQVJZX0FMUEhBQkVUIiwidGV4dEVuY29kZXIiLCJUZXh0RW5jb2RlciIsIkNSTEYiLCJDUkxGX0JZVEVTIiwiRm9ybURhdGFQYXJ0IiwiZXNjYXBlTmFtZSIsImlzU3RyaW5nVmFsdWUiLCJjb250ZW50TGVuZ3RoIiwiZm9ybURhdGFUb1N0cmVhbSQxIiwiZm9ybSIsImhlYWRlcnNIYW5kbGVyIiwiYm91bmRhcnlCeXRlcyIsImZvb3RlckJ5dGVzIiwicGFydCIsImNvbXB1dGVkSGVhZGVycyIsIlJlYWRhYmxlIiwiWmxpYkhlYWRlclRyYW5zZm9ybVN0cmVhbSIsIl9fdHJhbnNmb3JtIiwiWmxpYkhlYWRlclRyYW5zZm9ybVN0cmVhbSQxIiwiY2FsbGJhY2tpZnkkMSIsInpsaWJPcHRpb25zIiwiZmx1c2giLCJjb25zdGFudHMiLCJaX1NZTkNfRkxVU0giLCJmaW5pc2hGbHVzaCIsImJyb3RsaU9wdGlvbnMiLCJCUk9UTElfT1BFUkFUSU9OX0ZMVVNIIiwiaXNCcm90bGlTdXBwb3J0ZWQiLCJjcmVhdGVCcm90bGlEZWNvbXByZXNzIiwiaHR0cEZvbGxvdyIsImh0dHBzRm9sbG93IiwiaXNIdHRwcyIsInN1cHBvcnRlZFByb3RvY29scyIsImRpc3BhdGNoQmVmb3JlUmVkaXJlY3QiLCJiZWZvcmVSZWRpcmVjdHMiLCJzZXRQcm94eSIsImNvbmZpZ1Byb3h5IiwicHJveHlVcmwiLCJhdXRoIiwicGFzc3dvcmQiLCJwcm94eUhvc3QiLCJyZWRpcmVjdE9wdGlvbnMiLCJpc0h0dHBBZGFwdGVyU3VwcG9ydGVkIiwiYnVpbGRBZGRyZXNzRW50cnkiLCJmYW1pbHkiLCJyZXNvbHZlRmFtaWx5IiwiaHR0cEFkYXB0ZXIiLCJhc3luY0V4ZWN1dG9yIiwib25Eb25lIiwicmVzcG9uc2VFbmNvZGluZyIsImlzRG9uZSIsIl9sb29rdXAiLCJvcHQiLCJhcmcwIiwiYWRkcmVzc2VzIiwiYWRkciIsImFsbCIsImVtaXR0ZXIiLCJvbkZpbmlzaGVkIiwiY2FuY2VsVG9rZW4iLCJzaWduYWwiLCJyZW1vdmVFdmVudExpc3RlbmVyIiwicmVtb3ZlQWxsTGlzdGVuZXJzIiwiaXNSZWplY3RlZCIsInN1YnNjcmliZSIsImFib3J0ZWQiLCJhZGRFdmVudExpc3RlbmVyIiwiZnVsbFBhdGgiLCJjb252ZXJ0ZWREYXRhIiwidXJpIiwiYXNCbG9iIiwiX0Jsb2IiLCJFUlJfSU5WQUxJRF9VUkwiLCJpc0Jhc2U2NCIsImRlY29kZVVSSUNvbXBvbmVudCIsIkVSUl9OT1RfU1VQUE9SVCIsImZyb21EYXRhVVJJIiwib25Eb3dubG9hZFByb2dyZXNzIiwib25VcGxvYWRQcm9ncmVzcyIsIm1heFVwbG9hZFJhdGUiLCJtYXhEb3dubG9hZFJhdGUiLCJ1c2VyQm91bmRhcnkiLCJoYXNDb250ZW50TGVuZ3RoIiwicHJvbWlzaWZ5Iiwic2V0Q29udGVudExlbmd0aCIsImdldENvbnRlbnRMZW5ndGgiLCJvYmplY3RNb2RlIiwicGlwZWxpbmUiLCJwcm9ncmVzcyIsInVwbG9hZCIsInBhcmFtc1NlcmlhbGl6ZXIiLCJjdXN0b21FcnIiLCJleGlzdHMiLCJodHRwQWdlbnQiLCJodHRwc0FnZW50IiwidHJhbnNwb3J0Iiwic29ja2V0UGF0aCIsImlzSHR0cHNSZXF1ZXN0IiwiaW5zZWN1cmVIVFRQUGFyc2VyIiwic3RyZWFtcyIsInJlc3BvbnNlTGVuZ3RoIiwidHJhbnNmb3JtU3RyZWFtIiwiZG93bmxvYWQiLCJyZXNwb25zZVN0cmVhbSIsImxhc3RSZXF1ZXN0IiwiZGVjb21wcmVzcyIsImNyZWF0ZVVuemlwIiwib2ZmTGlzdGVuZXJzIiwic3RhdHVzTWVzc2FnZSIsInJlc3BvbnNlQnVmZmVyIiwidG90YWxSZXNwb25zZUJ5dGVzIiwicmVzcG9uc2VEYXRhIiwic2V0S2VlcEFsaXZlIiwiaXNOYU4iLCJFUlJfQkFEX09QVElPTl9WQUxVRSIsInRpbWVvdXRFcnJvck1lc3NhZ2UiLCJFVElNRURPVVQiLCJFQ09OTkFCT1JURUQiLCJlbmRlZCIsImVycm9yZWQiLCJQcm9taXNlIiwiX3JlamVjdCIsIm9uRG9uZUhhbmRsZXIiLCJjb29raWVzIiwiaXNTdGFuZGFyZEJyb3dzZXJFbnYiLCJleHBpcmVzIiwic2VjdXJlIiwiY29va2llIiwidG9HTVRTdHJpbmciLCJyZWFkIiwicmVtb3ZlIiwiaXNVUkxTYW1lT3JpZ2luIiwibXNpZSIsInVybFBhcnNpbmdOb2RlIiwiY3JlYXRlRWxlbWVudCIsIm9yaWdpblVSTCIsInJlc29sdmVVUkwiLCJzZXRBdHRyaWJ1dGUiLCJyZXF1ZXN0VVJMIiwicHJvZ3Jlc3NFdmVudFJlZHVjZXIiLCJsaXN0ZW5lciIsImlzRG93bmxvYWRTdHJlYW0iLCJsb2FkZWQiLCJsZW5ndGhDb21wdXRhYmxlIiwiZXN0aW1hdGVkIiwia25vd25BZGFwdGVycyIsInhociIsIlhNTEh0dHBSZXF1ZXN0IiwicmVxdWVzdERhdGEiLCJvbkNhbmNlbGVkIiwiaXNTdGFuZGFyZEJyb3dzZXJXZWJXb3JrZXJFbnYiLCJ1bmVzY2FwZSIsImJ0b2EiLCJvbmxvYWRlbmQiLCJyZXNwb25zZUhlYWRlcnMiLCJnZXRBbGxSZXNwb25zZUhlYWRlcnMiLCJyZXNwb25zZVRleHQiLCJvcGVuIiwib25yZWFkeXN0YXRlY2hhbmdlIiwicmVhZHlTdGF0ZSIsInJlc3BvbnNlVVJMIiwib25hYm9ydCIsIm9uZXJyb3IiLCJFUlJfTkVUV09SSyIsIm9udGltZW91dCIsInhzcmZWYWx1ZSIsInNldFJlcXVlc3RIZWFkZXIiLCJ3aXRoQ3JlZGVudGlhbHMiLCJjYW5jZWwiLCJzZW5kIiwicmVuZGVyUmVhc29uIiwiaXNSZXNvbHZlZEhhbmRsZSIsImFkYXB0ZXJzIiwibmFtZU9yQWRhcHRlciIsInJlamVjdGVkUmVhc29ucyIsInJlYXNvbnMiLCJ0aHJvd0lmQ2FuY2VsbGF0aW9uUmVxdWVzdGVkIiwidGhyb3dJZlJlcXVlc3RlZCIsImRpc3BhdGNoUmVxdWVzdCIsImhlYWRlcnNUb09iamVjdCIsIm1lcmdlQ29uZmlnIiwiY29uZmlnMSIsImNvbmZpZzIiLCJnZXRNZXJnZWRWYWx1ZSIsIm1lcmdlRGVlcFByb3BlcnRpZXMiLCJ2YWx1ZUZyb21Db25maWcyIiwiZGVmYXVsdFRvQ29uZmlnMiIsIm1lcmdlRGlyZWN0S2V5cyIsIm1lcmdlTWFwIiwidGltZW91dE1lc3NhZ2UiLCJjb25maWdWYWx1ZSIsInZhbGlkYXRvcnMkMSIsImRlcHJlY2F0ZWRXYXJuaW5ncyIsInZhbGlkYXRvciIsImZvcm1hdE1lc3NhZ2UiLCJkZXNjIiwib3B0cyIsIkVSUl9ERVBSRUNBVEVEIiwiYXNzZXJ0T3B0aW9ucyIsInNjaGVtYSIsImFsbG93VW5rbm93biIsIkVSUl9CQURfT1BUSU9OIiwidmFsaWRhdG9ycyIsIkF4aW9zIiwiaW5zdGFuY2VDb25maWciLCJpbnRlcmNlcHRvcnMiLCJjb25maWdPclVybCIsImJvb2xlYW4iLCJmdW5jdGlvbiIsImNvbnRleHRIZWFkZXJzIiwicmVxdWVzdEludGVyY2VwdG9yQ2hhaW4iLCJzeW5jaHJvbm91c1JlcXVlc3RJbnRlcmNlcHRvcnMiLCJpbnRlcmNlcHRvciIsInJlc3BvbnNlSW50ZXJjZXB0b3JDaGFpbiIsInByb21pc2UiLCJjaGFpbiIsIm5ld0NvbmZpZyIsIm9uRnVsZmlsbGVkIiwib25SZWplY3RlZCIsImdldFVyaSIsImdlbmVyYXRlSFRUUE1ldGhvZCIsImlzRm9ybSIsIkF4aW9zJDEiLCJDYW5jZWxUb2tlbiIsImV4ZWN1dG9yIiwicmVzb2x2ZVByb21pc2UiLCJfbGlzdGVuZXJzIiwib25mdWxmaWxsZWQiLCJfcmVzb2x2ZSIsIkNhbmNlbFRva2VuJDEiLCJIdHRwU3RhdHVzQ29kZSIsIkNvbnRpbnVlIiwiU3dpdGNoaW5nUHJvdG9jb2xzIiwiUHJvY2Vzc2luZyIsIkVhcmx5SGludHMiLCJPayIsIkNyZWF0ZWQiLCJBY2NlcHRlZCIsIk5vbkF1dGhvcml0YXRpdmVJbmZvcm1hdGlvbiIsIk5vQ29udGVudCIsIlJlc2V0Q29udGVudCIsIlBhcnRpYWxDb250ZW50IiwiTXVsdGlTdGF0dXMiLCJBbHJlYWR5UmVwb3J0ZWQiLCJJbVVzZWQiLCJNdWx0aXBsZUNob2ljZXMiLCJNb3ZlZFBlcm1hbmVudGx5IiwiRm91bmQiLCJTZWVPdGhlciIsIk5vdE1vZGlmaWVkIiwiVXNlUHJveHkiLCJVbnVzZWQiLCJUZW1wb3JhcnlSZWRpcmVjdCIsIlBlcm1hbmVudFJlZGlyZWN0IiwiQmFkUmVxdWVzdCIsIlVuYXV0aG9yaXplZCIsIlBheW1lbnRSZXF1aXJlZCIsIkZvcmJpZGRlbiIsIk5vdEZvdW5kIiwiTWV0aG9kTm90QWxsb3dlZCIsIk5vdEFjY2VwdGFibGUiLCJQcm94eUF1dGhlbnRpY2F0aW9uUmVxdWlyZWQiLCJSZXF1ZXN0VGltZW91dCIsIkNvbmZsaWN0IiwiR29uZSIsIkxlbmd0aFJlcXVpcmVkIiwiUHJlY29uZGl0aW9uRmFpbGVkIiwiUGF5bG9hZFRvb0xhcmdlIiwiVXJpVG9vTG9uZyIsIlVuc3VwcG9ydGVkTWVkaWFUeXBlIiwiUmFuZ2VOb3RTYXRpc2ZpYWJsZSIsIkV4cGVjdGF0aW9uRmFpbGVkIiwiSW1BVGVhcG90IiwiTWlzZGlyZWN0ZWRSZXF1ZXN0IiwiVW5wcm9jZXNzYWJsZUVudGl0eSIsIkxvY2tlZCIsIkZhaWxlZERlcGVuZGVuY3kiLCJUb29FYXJseSIsIlVwZ3JhZGVSZXF1aXJlZCIsIlByZWNvbmRpdGlvblJlcXVpcmVkIiwiVG9vTWFueVJlcXVlc3RzIiwiUmVxdWVzdEhlYWRlckZpZWxkc1Rvb0xhcmdlIiwiVW5hdmFpbGFibGVGb3JMZWdhbFJlYXNvbnMiLCJJbnRlcm5hbFNlcnZlckVycm9yIiwiTm90SW1wbGVtZW50ZWQiLCJCYWRHYXRld2F5IiwiU2VydmljZVVuYXZhaWxhYmxlIiwiR2F0ZXdheVRpbWVvdXQiLCJIdHRwVmVyc2lvbk5vdFN1cHBvcnRlZCIsIlZhcmlhbnRBbHNvTmVnb3RpYXRlcyIsIkluc3VmZmljaWVudFN0b3JhZ2UiLCJMb29wRGV0ZWN0ZWQiLCJOb3RFeHRlbmRlZCIsIk5ldHdvcmtBdXRoZW50aWNhdGlvblJlcXVpcmVkIiwiSHR0cFN0YXR1c0NvZGUkMSIsImF4aW9zIiwiY3JlYXRlSW5zdGFuY2UiLCJkZWZhdWx0Q29uZmlnIiwiaW5zdGFuY2UiLCJDYW5jZWwiLCJwcm9taXNlcyIsImlzQXhpb3NFcnJvciIsInBheWxvYWQiLCJmb3JtVG9KU09OIiwiZ2V0QWRhcHRlciIsIl9fd2VicGFja19tb2R1bGVfY2FjaGVfXyIsIl9fd2VicGFja19yZXF1aXJlX18iLCJtb2R1bGVJZCIsImNhY2hlZE1vZHVsZSIsIl9fd2VicGFja19tb2R1bGVzX18iLCJubWQiLCJwYXRocyIsImNoaWxkcmVuIiwiX193ZWJwYWNrX2V4cG9ydHNfXyJdLCJzb3VyY2VSb290IjoiIn0= - if (err) { - abort() - } - }) - } +/***/ }), - res.on('drain', resume) +/***/ 7426: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - this.res = res +/*! + * mime-db + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015-2022 Douglas Christopher Wilson + * MIT Licensed + */ - const needDrain = res.writableNeedDrain !== undefined - ? res.writableNeedDrain - : res._writableState && res._writableState.needDrain +/** + * Module exports. + */ - return needDrain !== true - } +module.exports = __nccwpck_require__(3765) - onData (chunk) { - const { res } = this - return res ? res.write(chunk) : true - } +/***/ }), - onComplete (trailers) { - const { res } = this +/***/ 3583: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - removeSignal(this) +"use strict"; +/*! + * mime-types + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ - if (!res) { - return - } - this.trailers = util.parseHeaders(trailers) - res.end() - } +/** + * Module dependencies. + * @private + */ - onError (err) { - const { res, callback, opaque, body } = this +var db = __nccwpck_require__(7426) +var extname = (__nccwpck_require__(1017).extname) - removeSignal(this) +/** + * Module variables. + * @private + */ - this.factory = null +var EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/ +var TEXT_TYPE_REGEXP = /^text\//i - if (res) { - this.res = null - util.destroy(res, err) - } else if (callback) { - this.callback = null - queueMicrotask(() => { - this.runInAsyncScope(callback, null, err, { opaque }) - }) - } +/** + * Module exports. + * @public + */ - if (body) { - this.body = null - util.destroy(body, err) - } +exports.charset = charset +exports.charsets = { lookup: charset } +exports.contentType = contentType +exports.extension = extension +exports.extensions = Object.create(null) +exports.lookup = lookup +exports.types = Object.create(null) + +// Populate the extensions/types maps +populateMaps(exports.extensions, exports.types) + +/** + * Get the default charset for a MIME type. + * + * @param {string} type + * @return {boolean|string} + */ + +function charset (type) { + if (!type || typeof type !== 'string') { + return false } -} -function stream (opts, factory, callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - stream.call(this, opts, factory, (err, data) => { - return err ? reject(err) : resolve(data) - }) - }) + // TODO: use media-typer + var match = EXTRACT_TYPE_REGEXP.exec(type) + var mime = match && db[match[1].toLowerCase()] + + if (mime && mime.charset) { + return mime.charset } - try { - this.dispatch(opts, new StreamHandler(opts, factory, callback)) - } catch (err) { - if (typeof callback !== 'function') { - throw err - } - const opaque = opts && opts.opaque - queueMicrotask(() => callback(err, { opaque })) + // default text/* to utf-8 + if (match && TEXT_TYPE_REGEXP.test(match[1])) { + return 'UTF-8' } + + return false } -module.exports = stream +/** + * Create a full Content-Type header given a MIME type or extension. + * + * @param {string} str + * @return {boolean|string} + */ +function contentType (str) { + // TODO: should this even be in this module? + if (!str || typeof str !== 'string') { + return false + } -/***/ }), + var mime = str.indexOf('/') === -1 + ? exports.lookup(str) + : str -/***/ 6923: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (!mime) { + return false + } -"use strict"; + // TODO: use content-type or other module + if (mime.indexOf('charset') === -1) { + var charset = exports.charset(mime) + if (charset) mime += '; charset=' + charset.toLowerCase() + } + return mime +} -const { InvalidArgumentError, RequestAbortedError, SocketError } = __nccwpck_require__(8045) -const { AsyncResource } = __nccwpck_require__(852) -const util = __nccwpck_require__(3983) -const { addSignal, removeSignal } = __nccwpck_require__(7032) -const assert = __nccwpck_require__(9491) +/** + * Get the default extension for a MIME type. + * + * @param {string} type + * @return {boolean|string} + */ -class UpgradeHandler extends AsyncResource { - constructor (opts, callback) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') - } +function extension (type) { + if (!type || typeof type !== 'string') { + return false + } - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } + // TODO: use media-typer + var match = EXTRACT_TYPE_REGEXP.exec(type) - const { signal, opaque, responseHeaders } = opts + // get extensions + var exts = match && exports.extensions[match[1].toLowerCase()] - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') - } + if (!exts || !exts.length) { + return false + } - super('UNDICI_UPGRADE') + return exts[0] +} - this.responseHeaders = responseHeaders || null - this.opaque = opaque || null - this.callback = callback - this.abort = null - this.context = null +/** + * Lookup the MIME type for a file path/extension. + * + * @param {string} path + * @return {boolean|string} + */ - addSignal(this, signal) +function lookup (path) { + if (!path || typeof path !== 'string') { + return false } - onConnect (abort, context) { - if (!this.callback) { - throw new RequestAbortedError() - } + // get the extension ("ext" or ".ext" or full path) + var extension = extname('x.' + path) + .toLowerCase() + .substr(1) - this.abort = abort - this.context = null + if (!extension) { + return false } - onHeaders () { - throw new SocketError('bad upgrade', null) - } + return exports.types[extension] || false +} - onUpgrade (statusCode, rawHeaders, socket) { - const { callback, opaque, context } = this +/** + * Populate the extensions and types maps. + * @private + */ - assert.strictEqual(statusCode, 101) +function populateMaps (extensions, types) { + // source preference (least -> most) + var preference = ['nginx', 'apache', undefined, 'iana'] - removeSignal(this) + Object.keys(db).forEach(function forEachMimeType (type) { + var mime = db[type] + var exts = mime.extensions - this.callback = null - const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) - this.runInAsyncScope(callback, null, null, { - headers, - socket, - opaque, - context - }) - } + if (!exts || !exts.length) { + return + } - onError (err) { - const { callback, opaque } = this + // mime -> extensions + extensions[type] = exts - removeSignal(this) + // extension -> mime + for (var i = 0; i < exts.length; i++) { + var extension = exts[i] - if (callback) { - this.callback = null - queueMicrotask(() => { - this.runInAsyncScope(callback, null, err, { opaque }) - }) - } - } -} + if (types[extension]) { + var from = preference.indexOf(db[types[extension]].source) + var to = preference.indexOf(mime.source) -function upgrade (opts, callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - upgrade.call(this, opts, (err, data) => { - return err ? reject(err) : resolve(data) - }) - }) - } + if (types[extension] !== 'application/octet-stream' && + (from > to || (from === to && types[extension].substr(0, 12) === 'application/'))) { + // skip the remapping + continue + } + } - try { - const upgradeHandler = new UpgradeHandler(opts, callback) - this.dispatch({ - ...opts, - method: opts.method || 'GET', - upgrade: opts.protocol || 'Websocket' - }, upgradeHandler) - } catch (err) { - if (typeof callback !== 'function') { - throw err + // set the extension -> mime + types[extension] = type } - const opaque = opts && opts.opaque - queueMicrotask(() => callback(err, { opaque })) - } + }) } -module.exports = upgrade - /***/ }), -/***/ 4059: +/***/ 4294: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -"use strict"; - - -module.exports.request = __nccwpck_require__(5448) -module.exports.stream = __nccwpck_require__(5395) -module.exports.pipeline = __nccwpck_require__(8752) -module.exports.upgrade = __nccwpck_require__(6923) -module.exports.connect = __nccwpck_require__(9744) +module.exports = __nccwpck_require__(4219); /***/ }), -/***/ 3858: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 4219: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -// Ported from https://github.com/nodejs/undici/pull/907 +var net = __nccwpck_require__(1808); +var tls = __nccwpck_require__(4404); +var http = __nccwpck_require__(3685); +var https = __nccwpck_require__(5687); +var events = __nccwpck_require__(2361); +var assert = __nccwpck_require__(9491); +var util = __nccwpck_require__(3837); -const assert = __nccwpck_require__(9491) -const { Readable } = __nccwpck_require__(2781) -const { RequestAbortedError, NotSupportedError, InvalidArgumentError } = __nccwpck_require__(8045) -const util = __nccwpck_require__(3983) -const { ReadableStreamFrom, toUSVString } = __nccwpck_require__(3983) - -let Blob -const kConsume = Symbol('kConsume') -const kReading = Symbol('kReading') -const kBody = Symbol('kBody') -const kAbort = Symbol('abort') -const kContentType = Symbol('kContentType') +exports.httpOverHttp = httpOverHttp; +exports.httpsOverHttp = httpsOverHttp; +exports.httpOverHttps = httpOverHttps; +exports.httpsOverHttps = httpsOverHttps; -const noop = () => {} -module.exports = class BodyReadable extends Readable { - constructor ({ - resume, - abort, - contentType = '', - highWaterMark = 64 * 1024 // Same as nodejs fs streams. - }) { - super({ - autoDestroy: true, - read: resume, - highWaterMark - }) +function httpOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + return agent; +} - this._readableState.dataEmitted = false +function httpsOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} - this[kAbort] = abort - this[kConsume] = null - this[kBody] = null - this[kContentType] = contentType +function httpOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + return agent; +} - // Is stream being consumed through Readable API? - // This is an optimization so that we avoid checking - // for 'data' and 'readable' listeners in the hot path - // inside push(). - this[kReading] = false - } +function httpsOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} - destroy (err) { - if (this.destroyed) { - // Node < 16 - return this - } - if (!err && !this._readableState.endEmitted) { - err = new RequestAbortedError() - } +function TunnelingAgent(options) { + var self = this; + self.options = options || {}; + self.proxyOptions = self.options.proxy || {}; + self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; + self.requests = []; + self.sockets = []; - if (err) { - this[kAbort]() + self.on('free', function onFree(socket, host, port, localAddress) { + var options = toOptions(host, port, localAddress); + for (var i = 0, len = self.requests.length; i < len; ++i) { + var pending = self.requests[i]; + if (pending.host === options.host && pending.port === options.port) { + // Detect the request to connect same origin server, + // reuse the connection. + self.requests.splice(i, 1); + pending.request.onSocket(socket); + return; + } } + socket.destroy(); + self.removeSocket(socket); + }); +} +util.inherits(TunnelingAgent, events.EventEmitter); - return super.destroy(err) +TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { + var self = this; + var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); + + if (self.sockets.length >= this.maxSockets) { + // We are over limit so we'll add it to the queue. + self.requests.push(options); + return; } - emit (ev, ...args) { - if (ev === 'data') { - // Node < 16.7 - this._readableState.dataEmitted = true - } else if (ev === 'error') { - // Node < 16 - this._readableState.errorEmitted = true + // If we are under maxSockets create a new one. + self.createSocket(options, function(socket) { + socket.on('free', onFree); + socket.on('close', onCloseOrRemove); + socket.on('agentRemove', onCloseOrRemove); + req.onSocket(socket); + + function onFree() { + self.emit('free', socket, options); } - return super.emit(ev, ...args) - } - on (ev, ...args) { - if (ev === 'data' || ev === 'readable') { - this[kReading] = true + function onCloseOrRemove(err) { + self.removeSocket(socket); + socket.removeListener('free', onFree); + socket.removeListener('close', onCloseOrRemove); + socket.removeListener('agentRemove', onCloseOrRemove); } - return super.on(ev, ...args) - } + }); +}; - addListener (ev, ...args) { - return this.on(ev, ...args) - } +TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { + var self = this; + var placeholder = {}; + self.sockets.push(placeholder); - off (ev, ...args) { - const ret = super.off(ev, ...args) - if (ev === 'data' || ev === 'readable') { - this[kReading] = ( - this.listenerCount('data') > 0 || - this.listenerCount('readable') > 0 - ) + var connectOptions = mergeOptions({}, self.proxyOptions, { + method: 'CONNECT', + path: options.host + ':' + options.port, + agent: false, + headers: { + host: options.host + ':' + options.port } - return ret + }); + if (options.localAddress) { + connectOptions.localAddress = options.localAddress; } - - removeListener (ev, ...args) { - return this.off(ev, ...args) + if (connectOptions.proxyAuth) { + connectOptions.headers = connectOptions.headers || {}; + connectOptions.headers['Proxy-Authorization'] = 'Basic ' + + new Buffer(connectOptions.proxyAuth).toString('base64'); } - push (chunk) { - if (this[kConsume] && chunk !== null && this.readableLength === 0) { - consumePush(this[kConsume], chunk) - return this[kReading] ? super.push(chunk) : true - } - return super.push(chunk) - } + debug('making CONNECT request'); + var connectReq = self.request(connectOptions); + connectReq.useChunkedEncodingByDefault = false; // for v0.6 + connectReq.once('response', onResponse); // for v0.6 + connectReq.once('upgrade', onUpgrade); // for v0.6 + connectReq.once('connect', onConnect); // for v0.7 or later + connectReq.once('error', onError); + connectReq.end(); - // https://fetch.spec.whatwg.org/#dom-body-text - async text () { - return consume(this, 'text') + function onResponse(res) { + // Very hacky. This is necessary to avoid http-parser leaks. + res.upgrade = true; } - // https://fetch.spec.whatwg.org/#dom-body-json - async json () { - return consume(this, 'json') + function onUpgrade(res, socket, head) { + // Hacky. + process.nextTick(function() { + onConnect(res, socket, head); + }); } - // https://fetch.spec.whatwg.org/#dom-body-blob - async blob () { - return consume(this, 'blob') - } + function onConnect(res, socket, head) { + connectReq.removeAllListeners(); + socket.removeAllListeners(); - // https://fetch.spec.whatwg.org/#dom-body-arraybuffer - async arrayBuffer () { - return consume(this, 'arrayBuffer') + if (res.statusCode !== 200) { + debug('tunneling socket could not be established, statusCode=%d', + res.statusCode); + socket.destroy(); + var error = new Error('tunneling socket could not be established, ' + + 'statusCode=' + res.statusCode); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + if (head.length > 0) { + debug('got illegal response body from proxy'); + socket.destroy(); + var error = new Error('got illegal response body from proxy'); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + debug('tunneling connection has established'); + self.sockets[self.sockets.indexOf(placeholder)] = socket; + return cb(socket); } - // https://fetch.spec.whatwg.org/#dom-body-formdata - async formData () { - // TODO: Implement. - throw new NotSupportedError() - } + function onError(cause) { + connectReq.removeAllListeners(); - // https://fetch.spec.whatwg.org/#dom-body-bodyused - get bodyUsed () { - return util.isDisturbed(this) + debug('tunneling socket could not be established, cause=%s\n', + cause.message, cause.stack); + var error = new Error('tunneling socket could not be established, ' + + 'cause=' + cause.message); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); } +}; - // https://fetch.spec.whatwg.org/#dom-body-body - get body () { - if (!this[kBody]) { - this[kBody] = ReadableStreamFrom(this) - if (this[kConsume]) { - // TODO: Is this the best way to force a lock? - this[kBody].getReader() // Ensure stream is locked. - assert(this[kBody].locked) - } - } - return this[kBody] +TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { + var pos = this.sockets.indexOf(socket) + if (pos === -1) { + return; } + this.sockets.splice(pos, 1); - dump (opts) { - let limit = opts && Number.isFinite(opts.limit) ? opts.limit : 262144 - const signal = opts && opts.signal + var pending = this.requests.shift(); + if (pending) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createSocket(pending, function(socket) { + pending.request.onSocket(socket); + }); + } +}; - if (signal) { - try { - if (typeof signal !== 'object' || !('aborted' in signal)) { - throw new InvalidArgumentError('signal must be an AbortSignal') - } - util.throwIfAborted(signal) - } catch (err) { - return Promise.reject(err) - } - } +function createSecureSocket(options, cb) { + var self = this; + TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { + var hostHeader = options.request.getHeader('host'); + var tlsOptions = mergeOptions({}, self.options, { + socket: socket, + servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host + }); - if (this.closed) { - return Promise.resolve(null) - } + // 0 is dummy port for v0.6 + var secureSocket = tls.connect(0, tlsOptions); + self.sockets[self.sockets.indexOf(socket)] = secureSocket; + cb(secureSocket); + }); +} - return new Promise((resolve, reject) => { - const signalListenerCleanup = signal - ? util.addAbortListener(signal, () => { - this.destroy() - }) - : noop - this - .on('close', function () { - signalListenerCleanup() - if (signal && signal.aborted) { - reject(signal.reason || Object.assign(new Error('The operation was aborted'), { name: 'AbortError' })) - } else { - resolve(null) - } - }) - .on('error', noop) - .on('data', function (chunk) { - limit -= chunk.length - if (limit <= 0) { - this.destroy() - } - }) - .resume() - }) +function toOptions(host, port, localAddress) { + if (typeof host === 'string') { // since v0.10 + return { + host: host, + port: port, + localAddress: localAddress + }; } + return host; // for v0.11 or later } -// https://streams.spec.whatwg.org/#readablestream-locked -function isLocked (self) { - // Consume is an implicit lock. - return (self[kBody] && self[kBody].locked === true) || self[kConsume] +function mergeOptions(target) { + for (var i = 1, len = arguments.length; i < len; ++i) { + var overrides = arguments[i]; + if (typeof overrides === 'object') { + var keys = Object.keys(overrides); + for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { + var k = keys[j]; + if (overrides[k] !== undefined) { + target[k] = overrides[k]; + } + } + } + } + return target; } -// https://fetch.spec.whatwg.org/#body-unusable -function isUnusable (self) { - return util.isDisturbed(self) || isLocked(self) -} -async function consume (stream, type) { - if (isUnusable(stream)) { - throw new TypeError('unusable') +var debug; +if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { + debug = function() { + var args = Array.prototype.slice.call(arguments); + if (typeof args[0] === 'string') { + args[0] = 'TUNNEL: ' + args[0]; + } else { + args.unshift('TUNNEL:'); + } + console.error.apply(console, args); } +} else { + debug = function() {}; +} +exports.debug = debug; // for test - assert(!stream[kConsume]) - return new Promise((resolve, reject) => { - stream[kConsume] = { - type, - stream, - resolve, - reject, - length: 0, - body: [] - } +/***/ }), - stream - .on('error', function (err) { - consumeFinish(this[kConsume], err) - }) - .on('close', function () { - if (this[kConsume].body !== null) { - consumeFinish(this[kConsume], new RequestAbortedError()) - } - }) +/***/ 1773: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - process.nextTick(consumeStart, stream[kConsume]) - }) +"use strict"; + + +const Client = __nccwpck_require__(3598) +const Dispatcher = __nccwpck_require__(412) +const errors = __nccwpck_require__(8045) +const Pool = __nccwpck_require__(4634) +const BalancedPool = __nccwpck_require__(7931) +const Agent = __nccwpck_require__(7890) +const util = __nccwpck_require__(3983) +const { InvalidArgumentError } = errors +const api = __nccwpck_require__(4059) +const buildConnector = __nccwpck_require__(2067) +const MockClient = __nccwpck_require__(8687) +const MockAgent = __nccwpck_require__(6771) +const MockPool = __nccwpck_require__(6193) +const mockErrors = __nccwpck_require__(888) +const ProxyAgent = __nccwpck_require__(7858) +const RetryHandler = __nccwpck_require__(2286) +const { getGlobalDispatcher, setGlobalDispatcher } = __nccwpck_require__(1892) +const DecoratorHandler = __nccwpck_require__(6930) +const RedirectHandler = __nccwpck_require__(2860) +const createRedirectInterceptor = __nccwpck_require__(8861) + +let hasCrypto +try { + __nccwpck_require__(6113) + hasCrypto = true +} catch { + hasCrypto = false } -function consumeStart (consume) { - if (consume.body === null) { - return - } +Object.assign(Dispatcher.prototype, api) - const { _readableState: state } = consume.stream +module.exports.Dispatcher = Dispatcher +module.exports.Client = Client +module.exports.Pool = Pool +module.exports.BalancedPool = BalancedPool +module.exports.Agent = Agent +module.exports.ProxyAgent = ProxyAgent +module.exports.RetryHandler = RetryHandler - for (const chunk of state.buffer) { - consumePush(consume, chunk) - } +module.exports.DecoratorHandler = DecoratorHandler +module.exports.RedirectHandler = RedirectHandler +module.exports.createRedirectInterceptor = createRedirectInterceptor - if (state.endEmitted) { - consumeEnd(this[kConsume]) - } else { - consume.stream.on('end', function () { - consumeEnd(this[kConsume]) - }) - } +module.exports.buildConnector = buildConnector +module.exports.errors = errors - consume.stream.resume() +function makeDispatcher (fn) { + return (url, opts, handler) => { + if (typeof opts === 'function') { + handler = opts + opts = null + } - while (consume.stream.read() != null) { - // Loop - } -} + if (!url || (typeof url !== 'string' && typeof url !== 'object' && !(url instanceof URL))) { + throw new InvalidArgumentError('invalid url') + } -function consumeEnd (consume) { - const { type, body, resolve, stream, length } = consume + if (opts != null && typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } - try { - if (type === 'text') { - resolve(toUSVString(Buffer.concat(body))) - } else if (type === 'json') { - resolve(JSON.parse(Buffer.concat(body))) - } else if (type === 'arrayBuffer') { - const dst = new Uint8Array(length) + if (opts && opts.path != null) { + if (typeof opts.path !== 'string') { + throw new InvalidArgumentError('invalid opts.path') + } - let pos = 0 - for (const buf of body) { - dst.set(buf, pos) - pos += buf.byteLength + let path = opts.path + if (!opts.path.startsWith('/')) { + path = `/${path}` } - resolve(dst.buffer) - } else if (type === 'blob') { - if (!Blob) { - Blob = (__nccwpck_require__(4300).Blob) + url = new URL(util.parseOrigin(url).origin + path) + } else { + if (!opts) { + opts = typeof url === 'object' ? url : {} } - resolve(new Blob(body, { type: stream[kContentType] })) + + url = util.parseURL(url) } - consumeFinish(consume) - } catch (err) { - stream.destroy(err) - } -} + const { agent, dispatcher = getGlobalDispatcher() } = opts -function consumePush (consume, chunk) { - consume.length += chunk.length - consume.body.push(chunk) -} + if (agent) { + throw new InvalidArgumentError('unsupported opts.agent. Did you mean opts.client?') + } -function consumeFinish (consume, err) { - if (consume.body === null) { - return + return fn.call(dispatcher, { + ...opts, + origin: url.origin, + path: url.search ? `${url.pathname}${url.search}` : url.pathname, + method: opts.method || (opts.body ? 'PUT' : 'GET') + }, handler) } +} - if (err) { - consume.reject(err) - } else { - consume.resolve() - } +module.exports.setGlobalDispatcher = setGlobalDispatcher +module.exports.getGlobalDispatcher = getGlobalDispatcher - consume.type = null - consume.stream = null - consume.resolve = null - consume.reject = null - consume.length = 0 - consume.body = null -} +if (util.nodeMajor > 16 || (util.nodeMajor === 16 && util.nodeMinor >= 8)) { + let fetchImpl = null + module.exports.fetch = async function fetch (resource) { + if (!fetchImpl) { + fetchImpl = (__nccwpck_require__(4881).fetch) + } + try { + return await fetchImpl(...arguments) + } catch (err) { + if (typeof err === 'object') { + Error.captureStackTrace(err, this) + } -/***/ }), + throw err + } + } + module.exports.Headers = __nccwpck_require__(554).Headers + module.exports.Response = __nccwpck_require__(7823).Response + module.exports.Request = __nccwpck_require__(8359).Request + module.exports.FormData = __nccwpck_require__(2015).FormData + module.exports.File = __nccwpck_require__(8511).File + module.exports.FileReader = __nccwpck_require__(1446).FileReader -/***/ 7474: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const { setGlobalOrigin, getGlobalOrigin } = __nccwpck_require__(1246) -const assert = __nccwpck_require__(9491) -const { - ResponseStatusCodeError -} = __nccwpck_require__(8045) -const { toUSVString } = __nccwpck_require__(3983) + module.exports.setGlobalOrigin = setGlobalOrigin + module.exports.getGlobalOrigin = getGlobalOrigin -async function getResolveErrorBodyCallback ({ callback, body, contentType, statusCode, statusMessage, headers }) { - assert(body) + const { CacheStorage } = __nccwpck_require__(7907) + const { kConstruct } = __nccwpck_require__(9174) - let chunks = [] - let limit = 0 + // Cache & CacheStorage are tightly coupled with fetch. Even if it may run + // in an older version of Node, it doesn't have any use without fetch. + module.exports.caches = new CacheStorage(kConstruct) +} - for await (const chunk of body) { - chunks.push(chunk) - limit += chunk.length - if (limit > 128 * 1024) { - chunks = null - break - } - } +if (util.nodeMajor >= 16) { + const { deleteCookie, getCookies, getSetCookies, setCookie } = __nccwpck_require__(1724) - if (statusCode === 204 || !contentType || !chunks) { - process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers)) - return - } + module.exports.deleteCookie = deleteCookie + module.exports.getCookies = getCookies + module.exports.getSetCookies = getSetCookies + module.exports.setCookie = setCookie - try { - if (contentType.startsWith('application/json')) { - const payload = JSON.parse(toUSVString(Buffer.concat(chunks))) - process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers, payload)) - return - } + const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685) - if (contentType.startsWith('text/')) { - const payload = toUSVString(Buffer.concat(chunks)) - process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers, payload)) - return - } - } catch (err) { - // Process in a fallback if error - } + module.exports.parseMIMEType = parseMIMEType + module.exports.serializeAMimeType = serializeAMimeType +} - process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers)) +if (util.nodeMajor >= 18 && hasCrypto) { + const { WebSocket } = __nccwpck_require__(4284) + + module.exports.WebSocket = WebSocket } -module.exports = { getResolveErrorBodyCallback } +module.exports.request = makeDispatcher(api.request) +module.exports.stream = makeDispatcher(api.stream) +module.exports.pipeline = makeDispatcher(api.pipeline) +module.exports.connect = makeDispatcher(api.connect) +module.exports.upgrade = makeDispatcher(api.upgrade) + +module.exports.MockClient = MockClient +module.exports.MockPool = MockPool +module.exports.MockAgent = MockAgent +module.exports.mockErrors = mockErrors /***/ }), -/***/ 7931: +/***/ 7890: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { - BalancedPoolMissingUpstreamError, - InvalidArgumentError -} = __nccwpck_require__(8045) -const { - PoolBase, - kClients, - kNeedDrain, - kAddClient, - kRemoveClient, - kGetDispatcher -} = __nccwpck_require__(3198) +const { InvalidArgumentError } = __nccwpck_require__(8045) +const { kClients, kRunning, kClose, kDestroy, kDispatch, kInterceptors } = __nccwpck_require__(2785) +const DispatcherBase = __nccwpck_require__(4839) const Pool = __nccwpck_require__(4634) -const { kUrl, kInterceptors } = __nccwpck_require__(2785) -const { parseOrigin } = __nccwpck_require__(3983) -const kFactory = Symbol('factory') +const Client = __nccwpck_require__(3598) +const util = __nccwpck_require__(3983) +const createRedirectInterceptor = __nccwpck_require__(8861) +const { WeakRef, FinalizationRegistry } = __nccwpck_require__(6436)() +const kOnConnect = Symbol('onConnect') +const kOnDisconnect = Symbol('onDisconnect') +const kOnConnectionError = Symbol('onConnectionError') +const kMaxRedirections = Symbol('maxRedirections') +const kOnDrain = Symbol('onDrain') +const kFactory = Symbol('factory') +const kFinalizer = Symbol('finalizer') const kOptions = Symbol('options') -const kGreatestCommonDivisor = Symbol('kGreatestCommonDivisor') -const kCurrentWeight = Symbol('kCurrentWeight') -const kIndex = Symbol('kIndex') -const kWeight = Symbol('kWeight') -const kMaxWeightPerServer = Symbol('kMaxWeightPerServer') -const kErrorPenalty = Symbol('kErrorPenalty') - -function getGreatestCommonDivisor (a, b) { - if (b === 0) return a - return getGreatestCommonDivisor(b, a % b) -} function defaultFactory (origin, opts) { - return new Pool(origin, opts) + return opts && opts.connections === 1 + ? new Client(origin, opts) + : new Pool(origin, opts) } -class BalancedPool extends PoolBase { - constructor (upstreams = [], { factory = defaultFactory, ...opts } = {}) { +class Agent extends DispatcherBase { + constructor ({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { super() - this[kOptions] = opts - this[kIndex] = -1 - this[kCurrentWeight] = 0 - - this[kMaxWeightPerServer] = this[kOptions].maxWeightPerServer || 100 - this[kErrorPenalty] = this[kOptions].errorPenalty || 15 - - if (!Array.isArray(upstreams)) { - upstreams = [upstreams] - } - if (typeof factory !== 'function') { throw new InvalidArgumentError('factory must be a function.') } - this[kInterceptors] = opts.interceptors && opts.interceptors.BalancedPool && Array.isArray(opts.interceptors.BalancedPool) - ? opts.interceptors.BalancedPool - : [] - this[kFactory] = factory - - for (const upstream of upstreams) { - this.addUpstream(upstream) + if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { + throw new InvalidArgumentError('connect must be a function or an object') } - this._updateBalancedPoolStats() - } - - addUpstream (upstream) { - const upstreamOrigin = parseOrigin(upstream).origin - if (this[kClients].find((pool) => ( - pool[kUrl].origin === upstreamOrigin && - pool.closed !== true && - pool.destroyed !== true - ))) { - return this + if (!Number.isInteger(maxRedirections) || maxRedirections < 0) { + throw new InvalidArgumentError('maxRedirections must be a positive number') } - const pool = this[kFactory](upstreamOrigin, Object.assign({}, this[kOptions])) - this[kAddClient](pool) - pool.on('connect', () => { - pool[kWeight] = Math.min(this[kMaxWeightPerServer], pool[kWeight] + this[kErrorPenalty]) - }) + if (connect && typeof connect !== 'function') { + connect = { ...connect } + } - pool.on('connectionError', () => { - pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]) - this._updateBalancedPoolStats() - }) + this[kInterceptors] = options.interceptors && options.interceptors.Agent && Array.isArray(options.interceptors.Agent) + ? options.interceptors.Agent + : [createRedirectInterceptor({ maxRedirections })] - pool.on('disconnect', (...args) => { - const err = args[2] - if (err && err.code === 'UND_ERR_SOCKET') { - // decrease the weight of the pool. - pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]) - this._updateBalancedPoolStats() + this[kOptions] = { ...util.deepClone(options), connect } + this[kOptions].interceptors = options.interceptors + ? { ...options.interceptors } + : undefined + this[kMaxRedirections] = maxRedirections + this[kFactory] = factory + this[kClients] = new Map() + this[kFinalizer] = new FinalizationRegistry(/* istanbul ignore next: gc is undeterministic */ key => { + const ref = this[kClients].get(key) + if (ref !== undefined && ref.deref() === undefined) { + this[kClients].delete(key) } }) - for (const client of this[kClients]) { - client[kWeight] = this[kMaxWeightPerServer] - } + const agent = this - this._updateBalancedPoolStats() + this[kOnDrain] = (origin, targets) => { + agent.emit('drain', origin, [agent, ...targets]) + } - return this - } + this[kOnConnect] = (origin, targets) => { + agent.emit('connect', origin, [agent, ...targets]) + } - _updateBalancedPoolStats () { - this[kGreatestCommonDivisor] = this[kClients].map(p => p[kWeight]).reduce(getGreatestCommonDivisor, 0) - } - - removeUpstream (upstream) { - const upstreamOrigin = parseOrigin(upstream).origin - - const pool = this[kClients].find((pool) => ( - pool[kUrl].origin === upstreamOrigin && - pool.closed !== true && - pool.destroyed !== true - )) - - if (pool) { - this[kRemoveClient](pool) + this[kOnDisconnect] = (origin, targets, err) => { + agent.emit('disconnect', origin, [agent, ...targets], err) } - return this + this[kOnConnectionError] = (origin, targets, err) => { + agent.emit('connectionError', origin, [agent, ...targets], err) + } } - get upstreams () { - return this[kClients] - .filter(dispatcher => dispatcher.closed !== true && dispatcher.destroyed !== true) - .map((p) => p[kUrl].origin) + get [kRunning] () { + let ret = 0 + for (const ref of this[kClients].values()) { + const client = ref.deref() + /* istanbul ignore next: gc is undeterministic */ + if (client) { + ret += client[kRunning] + } + } + return ret } - [kGetDispatcher] () { - // We validate that pools is greater than 0, - // otherwise we would have to wait until an upstream - // is added, which might never happen. - if (this[kClients].length === 0) { - throw new BalancedPoolMissingUpstreamError() + [kDispatch] (opts, handler) { + let key + if (opts.origin && (typeof opts.origin === 'string' || opts.origin instanceof URL)) { + key = String(opts.origin) + } else { + throw new InvalidArgumentError('opts.origin must be a non-empty string or URL.') } - const dispatcher = this[kClients].find(dispatcher => ( - !dispatcher[kNeedDrain] && - dispatcher.closed !== true && - dispatcher.destroyed !== true - )) + const ref = this[kClients].get(key) + let dispatcher = ref ? ref.deref() : null if (!dispatcher) { - return - } - - const allClientsBusy = this[kClients].map(pool => pool[kNeedDrain]).reduce((a, b) => a && b, true) + dispatcher = this[kFactory](opts.origin, this[kOptions]) + .on('drain', this[kOnDrain]) + .on('connect', this[kOnConnect]) + .on('disconnect', this[kOnDisconnect]) + .on('connectionError', this[kOnConnectionError]) - if (allClientsBusy) { - return + this[kClients].set(key, new WeakRef(dispatcher)) + this[kFinalizer].register(dispatcher, key) } - let counter = 0 - - let maxWeightIndex = this[kClients].findIndex(pool => !pool[kNeedDrain]) - - while (counter++ < this[kClients].length) { - this[kIndex] = (this[kIndex] + 1) % this[kClients].length - const pool = this[kClients][this[kIndex]] + return dispatcher.dispatch(opts, handler) + } - // find pool index with the largest weight - if (pool[kWeight] > this[kClients][maxWeightIndex][kWeight] && !pool[kNeedDrain]) { - maxWeightIndex = this[kIndex] + async [kClose] () { + const closePromises = [] + for (const ref of this[kClients].values()) { + const client = ref.deref() + /* istanbul ignore else: gc is undeterministic */ + if (client) { + closePromises.push(client.close()) } + } - // decrease the current weight every `this[kClients].length`. - if (this[kIndex] === 0) { - // Set the current weight to the next lower weight. - this[kCurrentWeight] = this[kCurrentWeight] - this[kGreatestCommonDivisor] + await Promise.all(closePromises) + } - if (this[kCurrentWeight] <= 0) { - this[kCurrentWeight] = this[kMaxWeightPerServer] - } - } - if (pool[kWeight] >= this[kCurrentWeight] && (!pool[kNeedDrain])) { - return pool + async [kDestroy] (err) { + const destroyPromises = [] + for (const ref of this[kClients].values()) { + const client = ref.deref() + /* istanbul ignore else: gc is undeterministic */ + if (client) { + destroyPromises.push(client.destroy(err)) } } - this[kCurrentWeight] = this[kClients][maxWeightIndex][kWeight] - this[kIndex] = maxWeightIndex - return this[kClients][maxWeightIndex] + await Promise.all(destroyPromises) } } -module.exports = BalancedPool +module.exports = Agent /***/ }), -/***/ 6101: +/***/ 7032: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -"use strict"; +const { addAbortListener } = __nccwpck_require__(3983) +const { RequestAbortedError } = __nccwpck_require__(8045) +const kListener = Symbol('kListener') +const kSignal = Symbol('kSignal') -const { kConstruct } = __nccwpck_require__(9174) -const { urlEquals, fieldValues: getFieldValues } = __nccwpck_require__(2396) -const { kEnumerableProperty, isDisturbed } = __nccwpck_require__(3983) -const { kHeadersList } = __nccwpck_require__(2785) -const { webidl } = __nccwpck_require__(1744) -const { Response, cloneResponse } = __nccwpck_require__(7823) -const { Request } = __nccwpck_require__(8359) -const { kState, kHeaders, kGuard, kRealm } = __nccwpck_require__(5861) -const { fetching } = __nccwpck_require__(4881) -const { urlIsHttpHttpsScheme, createDeferredPromise, readAllBytes } = __nccwpck_require__(2538) -const assert = __nccwpck_require__(9491) -const { getGlobalDispatcher } = __nccwpck_require__(1892) +function abort (self) { + if (self.abort) { + self.abort() + } else { + self.onError(new RequestAbortedError()) + } +} -/** - * @see https://w3c.github.io/ServiceWorker/#dfn-cache-batch-operation - * @typedef {Object} CacheBatchOperation - * @property {'delete' | 'put'} type - * @property {any} request - * @property {any} response - * @property {import('../../types/cache').CacheQueryOptions} options - */ +function addSignal (self, signal) { + self[kSignal] = null + self[kListener] = null -/** - * @see https://w3c.github.io/ServiceWorker/#dfn-request-response-list - * @typedef {[any, any][]} requestResponseList - */ + if (!signal) { + return + } -class Cache { - /** - * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-request-response-list - * @type {requestResponseList} - */ - #relevantRequestResponseList + if (signal.aborted) { + abort(self) + return + } - constructor () { - if (arguments[0] !== kConstruct) { - webidl.illegalConstructor() - } + self[kSignal] = signal + self[kListener] = () => { + abort(self) + } - this.#relevantRequestResponseList = arguments[1] + addAbortListener(self[kSignal], self[kListener]) +} + +function removeSignal (self) { + if (!self[kSignal]) { + return } - async match (request, options = {}) { - webidl.brandCheck(this, Cache) - webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.match' }) + if ('removeEventListener' in self[kSignal]) { + self[kSignal].removeEventListener('abort', self[kListener]) + } else { + self[kSignal].removeListener('abort', self[kListener]) + } - request = webidl.converters.RequestInfo(request) - options = webidl.converters.CacheQueryOptions(options) + self[kSignal] = null + self[kListener] = null +} - const p = await this.matchAll(request, options) +module.exports = { + addSignal, + removeSignal +} - if (p.length === 0) { - return - } - return p[0] - } +/***/ }), - async matchAll (request = undefined, options = {}) { - webidl.brandCheck(this, Cache) +/***/ 9744: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (request !== undefined) request = webidl.converters.RequestInfo(request) - options = webidl.converters.CacheQueryOptions(options) +"use strict"; - // 1. - let r = null - // 2. - if (request !== undefined) { - if (request instanceof Request) { - // 2.1.1 - r = request[kState] +const { AsyncResource } = __nccwpck_require__(852) +const { InvalidArgumentError, RequestAbortedError, SocketError } = __nccwpck_require__(8045) +const util = __nccwpck_require__(3983) +const { addSignal, removeSignal } = __nccwpck_require__(7032) - // 2.1.2 - if (r.method !== 'GET' && !options.ignoreMethod) { - return [] - } - } else if (typeof request === 'string') { - // 2.2.1 - r = new Request(request)[kState] - } +class ConnectHandler extends AsyncResource { + constructor (opts, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') } - // 5. - // 5.1 - const responses = [] + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } - // 5.2 - if (request === undefined) { - // 5.2.1 - for (const requestResponse of this.#relevantRequestResponseList) { - responses.push(requestResponse[1]) - } - } else { // 5.3 - // 5.3.1 - const requestResponses = this.#queryCache(r, options) + const { signal, opaque, responseHeaders } = opts - // 5.3.2 - for (const requestResponse of requestResponses) { - responses.push(requestResponse[1]) - } + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') } - // 5.4 - // We don't implement CORs so we don't need to loop over the responses, yay! + super('UNDICI_CONNECT') - // 5.5.1 - const responseList = [] + this.opaque = opaque || null + this.responseHeaders = responseHeaders || null + this.callback = callback + this.abort = null - // 5.5.2 - for (const response of responses) { - // 5.5.2.1 - const responseObject = new Response(response.body?.source ?? null) - const body = responseObject[kState].body - responseObject[kState] = response - responseObject[kState].body = body - responseObject[kHeaders][kHeadersList] = response.headersList - responseObject[kHeaders][kGuard] = 'immutable' + addSignal(this, signal) + } - responseList.push(responseObject) + onConnect (abort, context) { + if (!this.callback) { + throw new RequestAbortedError() } - // 6. - return Object.freeze(responseList) + this.abort = abort + this.context = context } - async add (request) { - webidl.brandCheck(this, Cache) - webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.add' }) - - request = webidl.converters.RequestInfo(request) + onHeaders () { + throw new SocketError('bad connect', null) + } - // 1. - const requests = [request] + onUpgrade (statusCode, rawHeaders, socket) { + const { callback, opaque, context } = this - // 2. - const responseArrayPromise = this.addAll(requests) + removeSignal(this) - // 3. - return await responseArrayPromise - } + this.callback = null - async addAll (requests) { - webidl.brandCheck(this, Cache) - webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.addAll' }) + let headers = rawHeaders + // Indicates is an HTTP2Session + if (headers != null) { + headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + } - requests = webidl.converters['sequence'](requests) + this.runInAsyncScope(callback, null, null, { + statusCode, + headers, + socket, + opaque, + context + }) + } - // 1. - const responsePromises = [] + onError (err) { + const { callback, opaque } = this - // 2. - const requestList = [] + removeSignal(this) - // 3. - for (const request of requests) { - if (typeof request === 'string') { - continue - } + if (callback) { + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) + } + } +} - // 3.1 - const r = request[kState] +function connect (opts, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + connect.call(this, opts, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } - // 3.2 - if (!urlIsHttpHttpsScheme(r.url) || r.method !== 'GET') { - throw webidl.errors.exception({ - header: 'Cache.addAll', - message: 'Expected http/s scheme when method is not GET.' - }) - } + try { + const connectHandler = new ConnectHandler(opts, callback) + this.dispatch({ ...opts, method: 'CONNECT' }, connectHandler) + } catch (err) { + if (typeof callback !== 'function') { + throw err } + const opaque = opts && opts.opaque + queueMicrotask(() => callback(err, { opaque })) + } +} - // 4. - /** @type {ReturnType[]} */ - const fetchControllers = [] +module.exports = connect - // 5. - for (const request of requests) { - // 5.1 - const r = new Request(request)[kState] - // 5.2 - if (!urlIsHttpHttpsScheme(r.url)) { - throw webidl.errors.exception({ - header: 'Cache.addAll', - message: 'Expected http/s scheme.' - }) - } +/***/ }), - // 5.4 - r.initiator = 'fetch' - r.destination = 'subresource' +/***/ 8752: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // 5.5 - requestList.push(r) +"use strict"; - // 5.6 - const responsePromise = createDeferredPromise() - // 5.7 - fetchControllers.push(fetching({ - request: r, - dispatcher: getGlobalDispatcher(), - processResponse (response) { - // 1. - if (response.type === 'error' || response.status === 206 || response.status < 200 || response.status > 299) { - responsePromise.reject(webidl.errors.exception({ - header: 'Cache.addAll', - message: 'Received an invalid status code or the request failed.' - })) - } else if (response.headersList.contains('vary')) { // 2. - // 2.1 - const fieldValues = getFieldValues(response.headersList.get('vary')) +const { + Readable, + Duplex, + PassThrough +} = __nccwpck_require__(2781) +const { + InvalidArgumentError, + InvalidReturnValueError, + RequestAbortedError +} = __nccwpck_require__(8045) +const util = __nccwpck_require__(3983) +const { AsyncResource } = __nccwpck_require__(852) +const { addSignal, removeSignal } = __nccwpck_require__(7032) +const assert = __nccwpck_require__(9491) - // 2.2 - for (const fieldValue of fieldValues) { - // 2.2.1 - if (fieldValue === '*') { - responsePromise.reject(webidl.errors.exception({ - header: 'Cache.addAll', - message: 'invalid vary field value' - })) +const kResume = Symbol('resume') - for (const controller of fetchControllers) { - controller.abort() - } +class PipelineRequest extends Readable { + constructor () { + super({ autoDestroy: true }) - return - } - } - } - }, - processResponseEndOfBody (response) { - // 1. - if (response.aborted) { - responsePromise.reject(new DOMException('aborted', 'AbortError')) - return - } + this[kResume] = null + } - // 2. - responsePromise.resolve(response) - } - })) + _read () { + const { [kResume]: resume } = this - // 5.8 - responsePromises.push(responsePromise.promise) + if (resume) { + this[kResume] = null + resume() } + } - // 6. - const p = Promise.all(responsePromises) + _destroy (err, callback) { + this._read() - // 7. - const responses = await p + callback(err) + } +} - // 7.1 - const operations = [] +class PipelineResponse extends Readable { + constructor (resume) { + super({ autoDestroy: true }) + this[kResume] = resume + } - // 7.2 - let index = 0 + _read () { + this[kResume]() + } - // 7.3 - for (const response of responses) { - // 7.3.1 - /** @type {CacheBatchOperation} */ - const operation = { - type: 'put', // 7.3.2 - request: requestList[index], // 7.3.3 - response // 7.3.4 - } + _destroy (err, callback) { + if (!err && !this._readableState.endEmitted) { + err = new RequestAbortedError() + } - operations.push(operation) // 7.3.5 + callback(err) + } +} - index++ // 7.3.6 +class PipelineHandler extends AsyncResource { + constructor (opts, handler) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') } - // 7.5 - const cacheJobPromise = createDeferredPromise() + if (typeof handler !== 'function') { + throw new InvalidArgumentError('invalid handler') + } - // 7.6.1 - let errorData = null + const { signal, method, opaque, onInfo, responseHeaders } = opts - // 7.6.2 - try { - this.#batchCacheOperations(operations) - } catch (e) { - errorData = e + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') } - // 7.6.3 - queueMicrotask(() => { - // 7.6.3.1 - if (errorData === null) { - cacheJobPromise.resolve(undefined) - } else { - // 7.6.3.2 - cacheJobPromise.reject(errorData) - } - }) - - // 7.7 - return cacheJobPromise.promise - } + if (method === 'CONNECT') { + throw new InvalidArgumentError('invalid method') + } - async put (request, response) { - webidl.brandCheck(this, Cache) - webidl.argumentLengthCheck(arguments, 2, { header: 'Cache.put' }) + if (onInfo && typeof onInfo !== 'function') { + throw new InvalidArgumentError('invalid onInfo callback') + } - request = webidl.converters.RequestInfo(request) - response = webidl.converters.Response(response) + super('UNDICI_PIPELINE') - // 1. - let innerRequest = null + this.opaque = opaque || null + this.responseHeaders = responseHeaders || null + this.handler = handler + this.abort = null + this.context = null + this.onInfo = onInfo || null - // 2. - if (request instanceof Request) { - innerRequest = request[kState] - } else { // 3. - innerRequest = new Request(request)[kState] - } + this.req = new PipelineRequest().on('error', util.nop) - // 4. - if (!urlIsHttpHttpsScheme(innerRequest.url) || innerRequest.method !== 'GET') { - throw webidl.errors.exception({ - header: 'Cache.put', - message: 'Expected an http/s scheme when method is not GET' - }) - } + this.ret = new Duplex({ + readableObjectMode: opts.objectMode, + autoDestroy: true, + read: () => { + const { body } = this - // 5. - const innerResponse = response[kState] + if (body && body.resume) { + body.resume() + } + }, + write: (chunk, encoding, callback) => { + const { req } = this - // 6. - if (innerResponse.status === 206) { - throw webidl.errors.exception({ - header: 'Cache.put', - message: 'Got 206 status' - }) - } + if (req.push(chunk, encoding) || req._readableState.destroyed) { + callback() + } else { + req[kResume] = callback + } + }, + destroy: (err, callback) => { + const { body, req, res, ret, abort } = this - // 7. - if (innerResponse.headersList.contains('vary')) { - // 7.1. - const fieldValues = getFieldValues(innerResponse.headersList.get('vary')) + if (!err && !ret._readableState.endEmitted) { + err = new RequestAbortedError() + } - // 7.2. - for (const fieldValue of fieldValues) { - // 7.2.1 - if (fieldValue === '*') { - throw webidl.errors.exception({ - header: 'Cache.put', - message: 'Got * vary field value' - }) + if (abort && err) { + abort() } - } - } - // 8. - if (innerResponse.body && (isDisturbed(innerResponse.body.stream) || innerResponse.body.stream.locked)) { - throw webidl.errors.exception({ - header: 'Cache.put', - message: 'Response body is locked or disturbed' - }) - } + util.destroy(body, err) + util.destroy(req, err) + util.destroy(res, err) - // 9. - const clonedResponse = cloneResponse(innerResponse) + removeSignal(this) - // 10. - const bodyReadPromise = createDeferredPromise() + callback(err) + } + }).on('prefinish', () => { + const { req } = this - // 11. - if (innerResponse.body != null) { - // 11.1 - const stream = innerResponse.body.stream + // Node < 15 does not call _final in same tick. + req.push(null) + }) - // 11.2 - const reader = stream.getReader() + this.res = null - // 11.3 - readAllBytes(reader).then(bodyReadPromise.resolve, bodyReadPromise.reject) - } else { - bodyReadPromise.resolve(undefined) - } + addSignal(this, signal) + } - // 12. - /** @type {CacheBatchOperation[]} */ - const operations = [] + onConnect (abort, context) { + const { ret, res } = this - // 13. - /** @type {CacheBatchOperation} */ - const operation = { - type: 'put', // 14. - request: innerRequest, // 15. - response: clonedResponse // 16. + assert(!res, 'pipeline cannot be retried') + + if (ret.destroyed) { + throw new RequestAbortedError() } - // 17. - operations.push(operation) + this.abort = abort + this.context = context + } - // 19. - const bytes = await bodyReadPromise.promise + onHeaders (statusCode, rawHeaders, resume) { + const { opaque, handler, context } = this - if (clonedResponse.body != null) { - clonedResponse.body.source = bytes + if (statusCode < 200) { + if (this.onInfo) { + const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + this.onInfo({ statusCode, headers }) + } + return } - // 19.1 - const cacheJobPromise = createDeferredPromise() - - // 19.2.1 - let errorData = null + this.res = new PipelineResponse(resume) - // 19.2.2 + let body try { - this.#batchCacheOperations(operations) - } catch (e) { - errorData = e + this.handler = null + const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + body = this.runInAsyncScope(handler, null, { + statusCode, + headers, + opaque, + body: this.res, + context + }) + } catch (err) { + this.res.on('error', util.nop) + throw err } - // 19.2.3 - queueMicrotask(() => { - // 19.2.3.1 - if (errorData === null) { - cacheJobPromise.resolve() - } else { // 19.2.3.2 - cacheJobPromise.reject(errorData) - } - }) - - return cacheJobPromise.promise - } + if (!body || typeof body.on !== 'function') { + throw new InvalidReturnValueError('expected Readable') + } - async delete (request, options = {}) { - webidl.brandCheck(this, Cache) - webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.delete' }) + body + .on('data', (chunk) => { + const { ret, body } = this - request = webidl.converters.RequestInfo(request) - options = webidl.converters.CacheQueryOptions(options) + if (!ret.push(chunk) && body.pause) { + body.pause() + } + }) + .on('error', (err) => { + const { ret } = this - /** - * @type {Request} - */ - let r = null + util.destroy(ret, err) + }) + .on('end', () => { + const { ret } = this - if (request instanceof Request) { - r = request[kState] + ret.push(null) + }) + .on('close', () => { + const { ret } = this - if (r.method !== 'GET' && !options.ignoreMethod) { - return false - } - } else { - assert(typeof request === 'string') + if (!ret._readableState.ended) { + util.destroy(ret, new RequestAbortedError()) + } + }) - r = new Request(request)[kState] - } + this.body = body + } - /** @type {CacheBatchOperation[]} */ - const operations = [] + onData (chunk) { + const { res } = this + return res.push(chunk) + } - /** @type {CacheBatchOperation} */ - const operation = { - type: 'delete', - request: r, - options - } - - operations.push(operation) + onComplete (trailers) { + const { res } = this + res.push(null) + } - const cacheJobPromise = createDeferredPromise() + onError (err) { + const { ret } = this + this.handler = null + util.destroy(ret, err) + } +} - let errorData = null - let requestResponses +function pipeline (opts, handler) { + try { + const pipelineHandler = new PipelineHandler(opts, handler) + this.dispatch({ ...opts, body: pipelineHandler.req }, pipelineHandler) + return pipelineHandler.ret + } catch (err) { + return new PassThrough().destroy(err) + } +} - try { - requestResponses = this.#batchCacheOperations(operations) - } catch (e) { - errorData = e - } +module.exports = pipeline - queueMicrotask(() => { - if (errorData === null) { - cacheJobPromise.resolve(!!requestResponses?.length) - } else { - cacheJobPromise.reject(errorData) - } - }) - return cacheJobPromise.promise - } +/***/ }), - /** - * @see https://w3c.github.io/ServiceWorker/#dom-cache-keys - * @param {any} request - * @param {import('../../types/cache').CacheQueryOptions} options - * @returns {readonly Request[]} - */ - async keys (request = undefined, options = {}) { - webidl.brandCheck(this, Cache) +/***/ 5448: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (request !== undefined) request = webidl.converters.RequestInfo(request) - options = webidl.converters.CacheQueryOptions(options) +"use strict"; - // 1. - let r = null - // 2. - if (request !== undefined) { - // 2.1 - if (request instanceof Request) { - // 2.1.1 - r = request[kState] +const Readable = __nccwpck_require__(3858) +const { + InvalidArgumentError, + RequestAbortedError +} = __nccwpck_require__(8045) +const util = __nccwpck_require__(3983) +const { getResolveErrorBodyCallback } = __nccwpck_require__(7474) +const { AsyncResource } = __nccwpck_require__(852) +const { addSignal, removeSignal } = __nccwpck_require__(7032) - // 2.1.2 - if (r.method !== 'GET' && !options.ignoreMethod) { - return [] - } - } else if (typeof request === 'string') { // 2.2 - r = new Request(request)[kState] - } +class RequestHandler extends AsyncResource { + constructor (opts, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') } - // 4. - const promise = createDeferredPromise() + const { signal, method, opaque, body, onInfo, responseHeaders, throwOnError, highWaterMark } = opts - // 5. - // 5.1 - const requests = [] + try { + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } - // 5.2 - if (request === undefined) { - // 5.2.1 - for (const requestResponse of this.#relevantRequestResponseList) { - // 5.2.1.1 - requests.push(requestResponse[0]) + if (highWaterMark && (typeof highWaterMark !== 'number' || highWaterMark < 0)) { + throw new InvalidArgumentError('invalid highWaterMark') } - } else { // 5.3 - // 5.3.1 - const requestResponses = this.#queryCache(r, options) - // 5.3.2 - for (const requestResponse of requestResponses) { - // 5.3.2.1 - requests.push(requestResponse[0]) + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') } - } - // 5.4 - queueMicrotask(() => { - // 5.4.1 - const requestList = [] + if (method === 'CONNECT') { + throw new InvalidArgumentError('invalid method') + } - // 5.4.2 - for (const request of requests) { - const requestObject = new Request('https://a') - requestObject[kState] = request - requestObject[kHeaders][kHeadersList] = request.headersList - requestObject[kHeaders][kGuard] = 'immutable' - requestObject[kRealm] = request.client + if (onInfo && typeof onInfo !== 'function') { + throw new InvalidArgumentError('invalid onInfo callback') + } - // 5.4.2.1 - requestList.push(requestObject) + super('UNDICI_REQUEST') + } catch (err) { + if (util.isStream(body)) { + util.destroy(body.on('error', util.nop), err) } + throw err + } - // 5.4.3 - promise.resolve(Object.freeze(requestList)) - }) + this.responseHeaders = responseHeaders || null + this.opaque = opaque || null + this.callback = callback + this.res = null + this.abort = null + this.body = body + this.trailers = {} + this.context = null + this.onInfo = onInfo || null + this.throwOnError = throwOnError + this.highWaterMark = highWaterMark - return promise.promise + if (util.isStream(body)) { + body.on('error', (err) => { + this.onError(err) + }) + } + + addSignal(this, signal) } - /** - * @see https://w3c.github.io/ServiceWorker/#batch-cache-operations-algorithm - * @param {CacheBatchOperation[]} operations - * @returns {requestResponseList} - */ - #batchCacheOperations (operations) { - // 1. - const cache = this.#relevantRequestResponseList + onConnect (abort, context) { + if (!this.callback) { + throw new RequestAbortedError() + } - // 2. - const backupCache = [...cache] + this.abort = abort + this.context = context + } - // 3. - const addedItems = [] + onHeaders (statusCode, rawHeaders, resume, statusMessage) { + const { callback, opaque, abort, context, responseHeaders, highWaterMark } = this - // 4.1 - const resultList = [] + const headers = responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) - try { - // 4.2 - for (const operation of operations) { - // 4.2.1 - if (operation.type !== 'delete' && operation.type !== 'put') { - throw webidl.errors.exception({ - header: 'Cache.#batchCacheOperations', - message: 'operation type does not match "delete" or "put"' - }) - } + if (statusCode < 200) { + if (this.onInfo) { + this.onInfo({ statusCode, headers }) + } + return + } - // 4.2.2 - if (operation.type === 'delete' && operation.response != null) { - throw webidl.errors.exception({ - header: 'Cache.#batchCacheOperations', - message: 'delete operation should not have an associated response' - }) - } + const parsedHeaders = responseHeaders === 'raw' ? util.parseHeaders(rawHeaders) : headers + const contentType = parsedHeaders['content-type'] + const body = new Readable({ resume, abort, contentType, highWaterMark }) - // 4.2.3 - if (this.#queryCache(operation.request, operation.options, addedItems).length) { - throw new DOMException('???', 'InvalidStateError') - } + this.callback = null + this.res = body + if (callback !== null) { + if (this.throwOnError && statusCode >= 400) { + this.runInAsyncScope(getResolveErrorBodyCallback, null, + { callback, body, contentType, statusCode, statusMessage, headers } + ) + } else { + this.runInAsyncScope(callback, null, null, { + statusCode, + headers, + trailers: this.trailers, + opaque, + body, + context + }) + } + } + } - // 4.2.4 - let requestResponses + onData (chunk) { + const { res } = this + return res.push(chunk) + } - // 4.2.5 - if (operation.type === 'delete') { - // 4.2.5.1 - requestResponses = this.#queryCache(operation.request, operation.options) + onComplete (trailers) { + const { res } = this - // TODO: the spec is wrong, this is needed to pass WPTs - if (requestResponses.length === 0) { - return [] - } + removeSignal(this) - // 4.2.5.2 - for (const requestResponse of requestResponses) { - const idx = cache.indexOf(requestResponse) - assert(idx !== -1) + util.parseHeaders(trailers, this.trailers) - // 4.2.5.2.1 - cache.splice(idx, 1) - } - } else if (operation.type === 'put') { // 4.2.6 - // 4.2.6.1 - if (operation.response == null) { - throw webidl.errors.exception({ - header: 'Cache.#batchCacheOperations', - message: 'put operation should have an associated response' - }) - } + res.push(null) + } - // 4.2.6.2 - const r = operation.request + onError (err) { + const { res, callback, body, opaque } = this - // 4.2.6.3 - if (!urlIsHttpHttpsScheme(r.url)) { - throw webidl.errors.exception({ - header: 'Cache.#batchCacheOperations', - message: 'expected http or https scheme' - }) - } + removeSignal(this) - // 4.2.6.4 - if (r.method !== 'GET') { - throw webidl.errors.exception({ - header: 'Cache.#batchCacheOperations', - message: 'not get method' - }) - } + if (callback) { + // TODO: Does this need queueMicrotask? + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) + } - // 4.2.6.5 - if (operation.options != null) { - throw webidl.errors.exception({ - header: 'Cache.#batchCacheOperations', - message: 'options must not be defined' - }) - } + if (res) { + this.res = null + // Ensure all queued handlers are invoked before destroying res. + queueMicrotask(() => { + util.destroy(res, err) + }) + } - // 4.2.6.6 - requestResponses = this.#queryCache(operation.request) + if (body) { + this.body = null + util.destroy(body, err) + } + } +} - // 4.2.6.7 - for (const requestResponse of requestResponses) { - const idx = cache.indexOf(requestResponse) - assert(idx !== -1) +function request (opts, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + request.call(this, opts, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } - // 4.2.6.7.1 - cache.splice(idx, 1) - } + try { + this.dispatch(opts, new RequestHandler(opts, callback)) + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts && opts.opaque + queueMicrotask(() => callback(err, { opaque })) + } +} - // 4.2.6.8 - cache.push([operation.request, operation.response]) +module.exports = request +module.exports.RequestHandler = RequestHandler - // 4.2.6.10 - addedItems.push([operation.request, operation.response]) - } - // 4.2.7 - resultList.push([operation.request, operation.response]) - } +/***/ }), - // 4.3 - return resultList - } catch (e) { // 5. - // 5.1 - this.#relevantRequestResponseList.length = 0 +/***/ 5395: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // 5.2 - this.#relevantRequestResponseList = backupCache +"use strict"; - // 5.3 - throw e + +const { finished, PassThrough } = __nccwpck_require__(2781) +const { + InvalidArgumentError, + InvalidReturnValueError, + RequestAbortedError +} = __nccwpck_require__(8045) +const util = __nccwpck_require__(3983) +const { getResolveErrorBodyCallback } = __nccwpck_require__(7474) +const { AsyncResource } = __nccwpck_require__(852) +const { addSignal, removeSignal } = __nccwpck_require__(7032) + +class StreamHandler extends AsyncResource { + constructor (opts, factory, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') } - } - /** - * @see https://w3c.github.io/ServiceWorker/#query-cache - * @param {any} requestQuery - * @param {import('../../types/cache').CacheQueryOptions} options - * @param {requestResponseList} targetStorage - * @returns {requestResponseList} - */ - #queryCache (requestQuery, options, targetStorage) { - /** @type {requestResponseList} */ - const resultList = [] + const { signal, method, opaque, body, onInfo, responseHeaders, throwOnError } = opts - const storage = targetStorage ?? this.#relevantRequestResponseList + try { + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } - for (const requestResponse of storage) { - const [cachedRequest, cachedResponse] = requestResponse - if (this.#requestMatchesCachedItem(requestQuery, cachedRequest, cachedResponse, options)) { - resultList.push(requestResponse) + if (typeof factory !== 'function') { + throw new InvalidArgumentError('invalid factory') } - } - return resultList - } + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + } - /** - * @see https://w3c.github.io/ServiceWorker/#request-matches-cached-item-algorithm - * @param {any} requestQuery - * @param {any} request - * @param {any | null} response - * @param {import('../../types/cache').CacheQueryOptions | undefined} options - * @returns {boolean} - */ - #requestMatchesCachedItem (requestQuery, request, response = null, options) { - // if (options?.ignoreMethod === false && request.method === 'GET') { - // return false - // } + if (method === 'CONNECT') { + throw new InvalidArgumentError('invalid method') + } - const queryURL = new URL(requestQuery.url) + if (onInfo && typeof onInfo !== 'function') { + throw new InvalidArgumentError('invalid onInfo callback') + } - const cachedURL = new URL(request.url) + super('UNDICI_STREAM') + } catch (err) { + if (util.isStream(body)) { + util.destroy(body.on('error', util.nop), err) + } + throw err + } - if (options?.ignoreSearch) { - cachedURL.search = '' + this.responseHeaders = responseHeaders || null + this.opaque = opaque || null + this.factory = factory + this.callback = callback + this.res = null + this.abort = null + this.context = null + this.trailers = null + this.body = body + this.onInfo = onInfo || null + this.throwOnError = throwOnError || false - queryURL.search = '' + if (util.isStream(body)) { + body.on('error', (err) => { + this.onError(err) + }) } - if (!urlEquals(queryURL, cachedURL, true)) { - return false - } + addSignal(this, signal) + } - if ( - response == null || - options?.ignoreVary || - !response.headersList.contains('vary') - ) { - return true + onConnect (abort, context) { + if (!this.callback) { + throw new RequestAbortedError() } - const fieldValues = getFieldValues(response.headersList.get('vary')) + this.abort = abort + this.context = context + } - for (const fieldValue of fieldValues) { - if (fieldValue === '*') { - return false - } + onHeaders (statusCode, rawHeaders, resume, statusMessage) { + const { factory, opaque, context, callback, responseHeaders } = this - const requestValue = request.headersList.get(fieldValue) - const queryValue = requestQuery.headersList.get(fieldValue) + const headers = responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) - // If one has the header and the other doesn't, or one has - // a different value than the other, return false - if (requestValue !== queryValue) { - return false + if (statusCode < 200) { + if (this.onInfo) { + this.onInfo({ statusCode, headers }) } + return } - return true - } -} + this.factory = null -Object.defineProperties(Cache.prototype, { - [Symbol.toStringTag]: { - value: 'Cache', - configurable: true - }, - match: kEnumerableProperty, - matchAll: kEnumerableProperty, - add: kEnumerableProperty, - addAll: kEnumerableProperty, - put: kEnumerableProperty, - delete: kEnumerableProperty, - keys: kEnumerableProperty -}) + let res -const cacheQueryOptionConverters = [ - { - key: 'ignoreSearch', - converter: webidl.converters.boolean, - defaultValue: false - }, - { - key: 'ignoreMethod', - converter: webidl.converters.boolean, - defaultValue: false - }, - { - key: 'ignoreVary', - converter: webidl.converters.boolean, - defaultValue: false - } -] - -webidl.converters.CacheQueryOptions = webidl.dictionaryConverter(cacheQueryOptionConverters) - -webidl.converters.MultiCacheQueryOptions = webidl.dictionaryConverter([ - ...cacheQueryOptionConverters, - { - key: 'cacheName', - converter: webidl.converters.DOMString - } -]) + if (this.throwOnError && statusCode >= 400) { + const parsedHeaders = responseHeaders === 'raw' ? util.parseHeaders(rawHeaders) : headers + const contentType = parsedHeaders['content-type'] + res = new PassThrough() -webidl.converters.Response = webidl.interfaceConverter(Response) + this.callback = null + this.runInAsyncScope(getResolveErrorBodyCallback, null, + { callback, body: res, contentType, statusCode, statusMessage, headers } + ) + } else { + if (factory === null) { + return + } -webidl.converters['sequence'] = webidl.sequenceConverter( - webidl.converters.RequestInfo -) + res = this.runInAsyncScope(factory, null, { + statusCode, + headers, + opaque, + context + }) -module.exports = { - Cache -} + if ( + !res || + typeof res.write !== 'function' || + typeof res.end !== 'function' || + typeof res.on !== 'function' + ) { + throw new InvalidReturnValueError('expected Writable') + } + // TODO: Avoid finished. It registers an unnecessary amount of listeners. + finished(res, { readable: false }, (err) => { + const { callback, res, opaque, trailers, abort } = this -/***/ }), + this.res = null + if (err || !res.readable) { + util.destroy(res, err) + } -/***/ 7907: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this.callback = null + this.runInAsyncScope(callback, null, err || null, { opaque, trailers }) -"use strict"; + if (err) { + abort() + } + }) + } + res.on('drain', resume) -const { kConstruct } = __nccwpck_require__(9174) -const { Cache } = __nccwpck_require__(6101) -const { webidl } = __nccwpck_require__(1744) -const { kEnumerableProperty } = __nccwpck_require__(3983) + this.res = res -class CacheStorage { - /** - * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-name-to-cache-map - * @type {Map} - */ - async has (cacheName) { - webidl.brandCheck(this, CacheStorage) - webidl.argumentLengthCheck(arguments, 1, { header: 'CacheStorage.has' }) - cacheName = webidl.converters.DOMString(cacheName) + this.trailers = util.parseHeaders(trailers) - // 2.1.1 - // 2.2 - return this.#caches.has(cacheName) + res.end() } - /** - * @see https://w3c.github.io/ServiceWorker/#dom-cachestorage-open - * @param {string} cacheName - * @returns {Promise} - */ - async open (cacheName) { - webidl.brandCheck(this, CacheStorage) - webidl.argumentLengthCheck(arguments, 1, { header: 'CacheStorage.open' }) - - cacheName = webidl.converters.DOMString(cacheName) + onError (err) { + const { res, callback, opaque, body } = this - // 2.1 - if (this.#caches.has(cacheName)) { - // await caches.open('v1') !== await caches.open('v1') + removeSignal(this) - // 2.1.1 - const cache = this.#caches.get(cacheName) + this.factory = null - // 2.1.1.1 - return new Cache(kConstruct, cache) + if (res) { + this.res = null + util.destroy(res, err) + } else if (callback) { + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) } - // 2.2 - const cache = [] - - // 2.3 - this.#caches.set(cacheName, cache) - - // 2.4 - return new Cache(kConstruct, cache) + if (body) { + this.body = null + util.destroy(body, err) + } } +} - /** - * @see https://w3c.github.io/ServiceWorker/#cache-storage-delete - * @param {string} cacheName - * @returns {Promise} - */ - async delete (cacheName) { - webidl.brandCheck(this, CacheStorage) - webidl.argumentLengthCheck(arguments, 1, { header: 'CacheStorage.delete' }) - - cacheName = webidl.converters.DOMString(cacheName) - - return this.#caches.delete(cacheName) +function stream (opts, factory, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + stream.call(this, opts, factory, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) } - /** - * @see https://w3c.github.io/ServiceWorker/#cache-storage-keys - * @returns {string[]} - */ - async keys () { - webidl.brandCheck(this, CacheStorage) - - // 2.1 - const keys = this.#caches.keys() - - // 2.2 - return [...keys] + try { + this.dispatch(opts, new StreamHandler(opts, factory, callback)) + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts && opts.opaque + queueMicrotask(() => callback(err, { opaque })) } } -Object.defineProperties(CacheStorage.prototype, { - [Symbol.toStringTag]: { - value: 'CacheStorage', - configurable: true - }, - match: kEnumerableProperty, - has: kEnumerableProperty, - open: kEnumerableProperty, - delete: kEnumerableProperty, - keys: kEnumerableProperty -}) - -module.exports = { - CacheStorage -} +module.exports = stream /***/ }), -/***/ 9174: +/***/ 6923: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -module.exports = { - kConstruct: (__nccwpck_require__(2785).kConstruct) -} +const { InvalidArgumentError, RequestAbortedError, SocketError } = __nccwpck_require__(8045) +const { AsyncResource } = __nccwpck_require__(852) +const util = __nccwpck_require__(3983) +const { addSignal, removeSignal } = __nccwpck_require__(7032) +const assert = __nccwpck_require__(9491) +class UpgradeHandler extends AsyncResource { + constructor (opts, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } -/***/ }), + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } -/***/ 2396: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const { signal, opaque, responseHeaders } = opts -"use strict"; + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + } + super('UNDICI_UPGRADE') -const assert = __nccwpck_require__(9491) -const { URLSerializer } = __nccwpck_require__(685) -const { isValidHeaderName } = __nccwpck_require__(2538) + this.responseHeaders = responseHeaders || null + this.opaque = opaque || null + this.callback = callback + this.abort = null + this.context = null -/** - * @see https://url.spec.whatwg.org/#concept-url-equals - * @param {URL} A - * @param {URL} B - * @param {boolean | undefined} excludeFragment - * @returns {boolean} - */ -function urlEquals (A, B, excludeFragment = false) { - const serializedA = URLSerializer(A, excludeFragment) + addSignal(this, signal) + } - const serializedB = URLSerializer(B, excludeFragment) + onConnect (abort, context) { + if (!this.callback) { + throw new RequestAbortedError() + } - return serializedA === serializedB -} + this.abort = abort + this.context = null + } -/** - * @see https://github.com/chromium/chromium/blob/694d20d134cb553d8d89e5500b9148012b1ba299/content/browser/cache_storage/cache_storage_cache.cc#L260-L262 - * @param {string} header - */ -function fieldValues (header) { - assert(header !== null) + onHeaders () { + throw new SocketError('bad upgrade', null) + } - const values = [] + onUpgrade (statusCode, rawHeaders, socket) { + const { callback, opaque, context } = this - for (let value of header.split(',')) { - value = value.trim() + assert.strictEqual(statusCode, 101) - if (!value.length) { - continue - } else if (!isValidHeaderName(value)) { - continue - } + removeSignal(this) - values.push(value) + this.callback = null + const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + this.runInAsyncScope(callback, null, null, { + headers, + socket, + opaque, + context + }) } - return values + onError (err) { + const { callback, opaque } = this + + removeSignal(this) + + if (callback) { + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) + } + } } -module.exports = { - urlEquals, - fieldValues +function upgrade (opts, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + upgrade.call(this, opts, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } + + try { + const upgradeHandler = new UpgradeHandler(opts, callback) + this.dispatch({ + ...opts, + method: opts.method || 'GET', + upgrade: opts.protocol || 'Websocket' + }, upgradeHandler) + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts && opts.opaque + queueMicrotask(() => callback(err, { opaque })) + } } +module.exports = upgrade + /***/ }), -/***/ 3598: +/***/ 4059: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -// @ts-check +module.exports.request = __nccwpck_require__(5448) +module.exports.stream = __nccwpck_require__(5395) +module.exports.pipeline = __nccwpck_require__(8752) +module.exports.upgrade = __nccwpck_require__(6923) +module.exports.connect = __nccwpck_require__(9744) + + +/***/ }), + +/***/ 3858: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; +// Ported from https://github.com/nodejs/undici/pull/907 + -/* global WebAssembly */ const assert = __nccwpck_require__(9491) -const net = __nccwpck_require__(1808) -const http = __nccwpck_require__(3685) -const { pipeline } = __nccwpck_require__(2781) +const { Readable } = __nccwpck_require__(2781) +const { RequestAbortedError, NotSupportedError, InvalidArgumentError } = __nccwpck_require__(8045) const util = __nccwpck_require__(3983) -const timers = __nccwpck_require__(9459) -const Request = __nccwpck_require__(2905) -const DispatcherBase = __nccwpck_require__(4839) -const { - RequestContentLengthMismatchError, - ResponseContentLengthMismatchError, - InvalidArgumentError, - RequestAbortedError, - HeadersTimeoutError, - HeadersOverflowError, - SocketError, - InformationalError, - BodyTimeoutError, - HTTPParserError, - ResponseExceededMaxSizeError, - ClientDestroyedError -} = __nccwpck_require__(8045) -const buildConnector = __nccwpck_require__(2067) -const { - kUrl, - kReset, - kServerName, - kClient, - kBusy, - kParser, - kConnect, - kBlocking, - kResuming, - kRunning, - kPending, - kSize, - kWriting, - kQueue, - kConnected, - kConnecting, - kNeedDrain, - kNoRef, - kKeepAliveDefaultTimeout, - kHostHeader, - kPendingIdx, - kRunningIdx, - kError, - kPipelining, - kSocket, - kKeepAliveTimeoutValue, - kMaxHeadersSize, - kKeepAliveMaxTimeout, - kKeepAliveTimeoutThreshold, - kHeadersTimeout, - kBodyTimeout, - kStrictContentLength, - kConnector, - kMaxRedirections, - kMaxRequests, - kCounter, - kClose, - kDestroy, - kDispatch, - kInterceptors, - kLocalAddress, - kMaxResponseSize, - kHTTPConnVersion, - // HTTP2 - kHost, - kHTTP2Session, - kHTTP2SessionState, - kHTTP2BuildRequest, - kHTTP2CopyHeaders, - kHTTP1BuildRequest -} = __nccwpck_require__(2785) +const { ReadableStreamFrom, toUSVString } = __nccwpck_require__(3983) -/** @type {import('http2')} */ -let http2 -try { - http2 = __nccwpck_require__(5158) -} catch { - // @ts-ignore - http2 = { constants: {} } -} +let Blob -const { - constants: { - HTTP2_HEADER_AUTHORITY, - HTTP2_HEADER_METHOD, - HTTP2_HEADER_PATH, - HTTP2_HEADER_SCHEME, - HTTP2_HEADER_CONTENT_LENGTH, - HTTP2_HEADER_EXPECT, - HTTP2_HEADER_STATUS - } -} = http2 +const kConsume = Symbol('kConsume') +const kReading = Symbol('kReading') +const kBody = Symbol('kBody') +const kAbort = Symbol('abort') +const kContentType = Symbol('kContentType') -// Experimental -let h2ExperimentalWarned = false +const noop = () => {} -const FastBuffer = Buffer[Symbol.species] +module.exports = class BodyReadable extends Readable { + constructor ({ + resume, + abort, + contentType = '', + highWaterMark = 64 * 1024 // Same as nodejs fs streams. + }) { + super({ + autoDestroy: true, + read: resume, + highWaterMark + }) -const kClosedResolve = Symbol('kClosedResolve') + this._readableState.dataEmitted = false -const channels = {} + this[kAbort] = abort + this[kConsume] = null + this[kBody] = null + this[kContentType] = contentType -try { - const diagnosticsChannel = __nccwpck_require__(7643) - channels.sendHeaders = diagnosticsChannel.channel('undici:client:sendHeaders') - channels.beforeConnect = diagnosticsChannel.channel('undici:client:beforeConnect') - channels.connectError = diagnosticsChannel.channel('undici:client:connectError') - channels.connected = diagnosticsChannel.channel('undici:client:connected') -} catch { - channels.sendHeaders = { hasSubscribers: false } - channels.beforeConnect = { hasSubscribers: false } - channels.connectError = { hasSubscribers: false } - channels.connected = { hasSubscribers: false } -} - -/** - * @type {import('../types/client').default} - */ -class Client extends DispatcherBase { - /** - * - * @param {string|URL} url - * @param {import('../types/client').Client.Options} options - */ - constructor (url, { - interceptors, - maxHeaderSize, - headersTimeout, - socketTimeout, - requestTimeout, - connectTimeout, - bodyTimeout, - idleTimeout, - keepAlive, - keepAliveTimeout, - maxKeepAliveTimeout, - keepAliveMaxTimeout, - keepAliveTimeoutThreshold, - socketPath, - pipelining, - tls, - strictContentLength, - maxCachedSessions, - maxRedirections, - connect, - maxRequestsPerClient, - localAddress, - maxResponseSize, - autoSelectFamily, - autoSelectFamilyAttemptTimeout, - // h2 - allowH2, - maxConcurrentStreams - } = {}) { - super() + // Is stream being consumed through Readable API? + // This is an optimization so that we avoid checking + // for 'data' and 'readable' listeners in the hot path + // inside push(). + this[kReading] = false + } - if (keepAlive !== undefined) { - throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead') + destroy (err) { + if (this.destroyed) { + // Node < 16 + return this } - if (socketTimeout !== undefined) { - throw new InvalidArgumentError('unsupported socketTimeout, use headersTimeout & bodyTimeout instead') + if (!err && !this._readableState.endEmitted) { + err = new RequestAbortedError() } - if (requestTimeout !== undefined) { - throw new InvalidArgumentError('unsupported requestTimeout, use headersTimeout & bodyTimeout instead') + if (err) { + this[kAbort]() } - if (idleTimeout !== undefined) { - throw new InvalidArgumentError('unsupported idleTimeout, use keepAliveTimeout instead') - } + return super.destroy(err) + } - if (maxKeepAliveTimeout !== undefined) { - throw new InvalidArgumentError('unsupported maxKeepAliveTimeout, use keepAliveMaxTimeout instead') + emit (ev, ...args) { + if (ev === 'data') { + // Node < 16.7 + this._readableState.dataEmitted = true + } else if (ev === 'error') { + // Node < 16 + this._readableState.errorEmitted = true } + return super.emit(ev, ...args) + } - if (maxHeaderSize != null && !Number.isFinite(maxHeaderSize)) { - throw new InvalidArgumentError('invalid maxHeaderSize') + on (ev, ...args) { + if (ev === 'data' || ev === 'readable') { + this[kReading] = true } + return super.on(ev, ...args) + } - if (socketPath != null && typeof socketPath !== 'string') { - throw new InvalidArgumentError('invalid socketPath') - } + addListener (ev, ...args) { + return this.on(ev, ...args) + } - if (connectTimeout != null && (!Number.isFinite(connectTimeout) || connectTimeout < 0)) { - throw new InvalidArgumentError('invalid connectTimeout') + off (ev, ...args) { + const ret = super.off(ev, ...args) + if (ev === 'data' || ev === 'readable') { + this[kReading] = ( + this.listenerCount('data') > 0 || + this.listenerCount('readable') > 0 + ) } + return ret + } - if (keepAliveTimeout != null && (!Number.isFinite(keepAliveTimeout) || keepAliveTimeout <= 0)) { - throw new InvalidArgumentError('invalid keepAliveTimeout') - } + removeListener (ev, ...args) { + return this.off(ev, ...args) + } - if (keepAliveMaxTimeout != null && (!Number.isFinite(keepAliveMaxTimeout) || keepAliveMaxTimeout <= 0)) { - throw new InvalidArgumentError('invalid keepAliveMaxTimeout') + push (chunk) { + if (this[kConsume] && chunk !== null && this.readableLength === 0) { + consumePush(this[kConsume], chunk) + return this[kReading] ? super.push(chunk) : true } + return super.push(chunk) + } - if (keepAliveTimeoutThreshold != null && !Number.isFinite(keepAliveTimeoutThreshold)) { - throw new InvalidArgumentError('invalid keepAliveTimeoutThreshold') - } + // https://fetch.spec.whatwg.org/#dom-body-text + async text () { + return consume(this, 'text') + } - if (headersTimeout != null && (!Number.isInteger(headersTimeout) || headersTimeout < 0)) { - throw new InvalidArgumentError('headersTimeout must be a positive integer or zero') - } + // https://fetch.spec.whatwg.org/#dom-body-json + async json () { + return consume(this, 'json') + } - if (bodyTimeout != null && (!Number.isInteger(bodyTimeout) || bodyTimeout < 0)) { - throw new InvalidArgumentError('bodyTimeout must be a positive integer or zero') - } + // https://fetch.spec.whatwg.org/#dom-body-blob + async blob () { + return consume(this, 'blob') + } - if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { - throw new InvalidArgumentError('connect must be a function or an object') - } + // https://fetch.spec.whatwg.org/#dom-body-arraybuffer + async arrayBuffer () { + return consume(this, 'arrayBuffer') + } - if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { - throw new InvalidArgumentError('maxRedirections must be a positive number') - } + // https://fetch.spec.whatwg.org/#dom-body-formdata + async formData () { + // TODO: Implement. + throw new NotSupportedError() + } - if (maxRequestsPerClient != null && (!Number.isInteger(maxRequestsPerClient) || maxRequestsPerClient < 0)) { - throw new InvalidArgumentError('maxRequestsPerClient must be a positive number') - } + // https://fetch.spec.whatwg.org/#dom-body-bodyused + get bodyUsed () { + return util.isDisturbed(this) + } - if (localAddress != null && (typeof localAddress !== 'string' || net.isIP(localAddress) === 0)) { - throw new InvalidArgumentError('localAddress must be valid string IP address') + // https://fetch.spec.whatwg.org/#dom-body-body + get body () { + if (!this[kBody]) { + this[kBody] = ReadableStreamFrom(this) + if (this[kConsume]) { + // TODO: Is this the best way to force a lock? + this[kBody].getReader() // Ensure stream is locked. + assert(this[kBody].locked) + } } + return this[kBody] + } - if (maxResponseSize != null && (!Number.isInteger(maxResponseSize) || maxResponseSize < -1)) { - throw new InvalidArgumentError('maxResponseSize must be a positive number') - } + dump (opts) { + let limit = opts && Number.isFinite(opts.limit) ? opts.limit : 262144 + const signal = opts && opts.signal - if ( - autoSelectFamilyAttemptTimeout != null && - (!Number.isInteger(autoSelectFamilyAttemptTimeout) || autoSelectFamilyAttemptTimeout < -1) - ) { - throw new InvalidArgumentError('autoSelectFamilyAttemptTimeout must be a positive number') + if (signal) { + try { + if (typeof signal !== 'object' || !('aborted' in signal)) { + throw new InvalidArgumentError('signal must be an AbortSignal') + } + util.throwIfAborted(signal) + } catch (err) { + return Promise.reject(err) + } } - // h2 - if (allowH2 != null && typeof allowH2 !== 'boolean') { - throw new InvalidArgumentError('allowH2 must be a valid boolean value') + if (this.closed) { + return Promise.resolve(null) } - if (maxConcurrentStreams != null && (typeof maxConcurrentStreams !== 'number' || maxConcurrentStreams < 1)) { - throw new InvalidArgumentError('maxConcurrentStreams must be a possitive integer, greater than 0') - } + return new Promise((resolve, reject) => { + const signalListenerCleanup = signal + ? util.addAbortListener(signal, () => { + this.destroy() + }) + : noop - if (typeof connect !== 'function') { - connect = buildConnector({ - ...tls, - maxCachedSessions, - allowH2, - socketPath, - timeout: connectTimeout, - ...(util.nodeHasAutoSelectFamily && autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), - ...connect - }) - } + this + .on('close', function () { + signalListenerCleanup() + if (signal && signal.aborted) { + reject(signal.reason || Object.assign(new Error('The operation was aborted'), { name: 'AbortError' })) + } else { + resolve(null) + } + }) + .on('error', noop) + .on('data', function (chunk) { + limit -= chunk.length + if (limit <= 0) { + this.destroy() + } + }) + .resume() + }) + } +} - this[kInterceptors] = interceptors && interceptors.Client && Array.isArray(interceptors.Client) - ? interceptors.Client - : [createRedirectInterceptor({ maxRedirections })] - this[kUrl] = util.parseOrigin(url) - this[kConnector] = connect - this[kSocket] = null - this[kPipelining] = pipelining != null ? pipelining : 1 - this[kMaxHeadersSize] = maxHeaderSize || http.maxHeaderSize - this[kKeepAliveDefaultTimeout] = keepAliveTimeout == null ? 4e3 : keepAliveTimeout - this[kKeepAliveMaxTimeout] = keepAliveMaxTimeout == null ? 600e3 : keepAliveMaxTimeout - this[kKeepAliveTimeoutThreshold] = keepAliveTimeoutThreshold == null ? 1e3 : keepAliveTimeoutThreshold - this[kKeepAliveTimeoutValue] = this[kKeepAliveDefaultTimeout] - this[kServerName] = null - this[kLocalAddress] = localAddress != null ? localAddress : null - this[kResuming] = 0 // 0, idle, 1, scheduled, 2 resuming - this[kNeedDrain] = 0 // 0, idle, 1, scheduled, 2 resuming - this[kHostHeader] = `host: ${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}\r\n` - this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 300e3 - this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 300e3 - this[kStrictContentLength] = strictContentLength == null ? true : strictContentLength - this[kMaxRedirections] = maxRedirections - this[kMaxRequests] = maxRequestsPerClient - this[kClosedResolve] = null - this[kMaxResponseSize] = maxResponseSize > -1 ? maxResponseSize : -1 - this[kHTTPConnVersion] = 'h1' - - // HTTP/2 - this[kHTTP2Session] = null - this[kHTTP2SessionState] = !allowH2 - ? null - : { - // streams: null, // Fixed queue of streams - For future support of `push` - openStreams: 0, // Keep track of them to decide wether or not unref the session - maxConcurrentStreams: maxConcurrentStreams != null ? maxConcurrentStreams : 100 // Max peerConcurrentStreams for a Node h2 server - } - this[kHost] = `${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}` +// https://streams.spec.whatwg.org/#readablestream-locked +function isLocked (self) { + // Consume is an implicit lock. + return (self[kBody] && self[kBody].locked === true) || self[kConsume] +} - // kQueue is built up of 3 sections separated by - // the kRunningIdx and kPendingIdx indices. - // | complete | running | pending | - // ^ kRunningIdx ^ kPendingIdx ^ kQueue.length - // kRunningIdx points to the first running element. - // kPendingIdx points to the first pending element. - // This implements a fast queue with an amortized - // time of O(1). +// https://fetch.spec.whatwg.org/#body-unusable +function isUnusable (self) { + return util.isDisturbed(self) || isLocked(self) +} - this[kQueue] = [] - this[kRunningIdx] = 0 - this[kPendingIdx] = 0 +async function consume (stream, type) { + if (isUnusable(stream)) { + throw new TypeError('unusable') } - get pipelining () { - return this[kPipelining] - } + assert(!stream[kConsume]) - set pipelining (value) { - this[kPipelining] = value - resume(this, true) - } + return new Promise((resolve, reject) => { + stream[kConsume] = { + type, + stream, + resolve, + reject, + length: 0, + body: [] + } - get [kPending] () { - return this[kQueue].length - this[kPendingIdx] - } + stream + .on('error', function (err) { + consumeFinish(this[kConsume], err) + }) + .on('close', function () { + if (this[kConsume].body !== null) { + consumeFinish(this[kConsume], new RequestAbortedError()) + } + }) - get [kRunning] () { - return this[kPendingIdx] - this[kRunningIdx] - } + process.nextTick(consumeStart, stream[kConsume]) + }) +} - get [kSize] () { - return this[kQueue].length - this[kRunningIdx] +function consumeStart (consume) { + if (consume.body === null) { + return } - get [kConnected] () { - return !!this[kSocket] && !this[kConnecting] && !this[kSocket].destroyed - } + const { _readableState: state } = consume.stream - get [kBusy] () { - const socket = this[kSocket] - return ( - (socket && (socket[kReset] || socket[kWriting] || socket[kBlocking])) || - (this[kSize] >= (this[kPipelining] || 1)) || - this[kPending] > 0 - ) + for (const chunk of state.buffer) { + consumePush(consume, chunk) } - /* istanbul ignore: only used for test */ - [kConnect] (cb) { - connect(this) - this.once('connect', cb) + if (state.endEmitted) { + consumeEnd(this[kConsume]) + } else { + consume.stream.on('end', function () { + consumeEnd(this[kConsume]) + }) } - [kDispatch] (opts, handler) { - const origin = opts.origin || this[kUrl].origin - - const request = this[kHTTPConnVersion] === 'h2' - ? Request[kHTTP2BuildRequest](origin, opts, handler) - : Request[kHTTP1BuildRequest](origin, opts, handler) - - this[kQueue].push(request) - if (this[kResuming]) { - // Do nothing. - } else if (util.bodyLength(request.body) == null && util.isIterable(request.body)) { - // Wait a tick in case stream/iterator is ended in the same tick. - this[kResuming] = 1 - process.nextTick(resume, this) - } else { - resume(this, true) - } - - if (this[kResuming] && this[kNeedDrain] !== 2 && this[kBusy]) { - this[kNeedDrain] = 2 - } - - return this[kNeedDrain] < 2 - } + consume.stream.resume() - async [kClose] () { - // TODO: for H2 we need to gracefully flush the remaining enqueued - // request and close each stream. - return new Promise((resolve) => { - if (!this[kSize]) { - resolve(null) - } else { - this[kClosedResolve] = resolve - } - }) + while (consume.stream.read() != null) { + // Loop } +} - async [kDestroy] (err) { - return new Promise((resolve) => { - const requests = this[kQueue].splice(this[kPendingIdx]) - for (let i = 0; i < requests.length; i++) { - const request = requests[i] - errorRequest(this, request, err) - } +function consumeEnd (consume) { + const { type, body, resolve, stream, length } = consume - const callback = () => { - if (this[kClosedResolve]) { - // TODO (fix): Should we error here with ClientDestroyedError? - this[kClosedResolve]() - this[kClosedResolve] = null - } - resolve() - } + try { + if (type === 'text') { + resolve(toUSVString(Buffer.concat(body))) + } else if (type === 'json') { + resolve(JSON.parse(Buffer.concat(body))) + } else if (type === 'arrayBuffer') { + const dst = new Uint8Array(length) - if (this[kHTTP2Session] != null) { - util.destroy(this[kHTTP2Session], err) - this[kHTTP2Session] = null - this[kHTTP2SessionState] = null + let pos = 0 + for (const buf of body) { + dst.set(buf, pos) + pos += buf.byteLength } - if (!this[kSocket]) { - queueMicrotask(callback) - } else { - util.destroy(this[kSocket].on('close', callback), err) + resolve(dst.buffer) + } else if (type === 'blob') { + if (!Blob) { + Blob = (__nccwpck_require__(4300).Blob) } + resolve(new Blob(body, { type: stream[kContentType] })) + } - resume(this) - }) + consumeFinish(consume) + } catch (err) { + stream.destroy(err) } } -function onHttp2SessionError (err) { - assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') - - this[kSocket][kError] = err - - onError(this[kClient], err) +function consumePush (consume, chunk) { + consume.length += chunk.length + consume.body.push(chunk) } -function onHttp2FrameError (type, code, id) { - const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`) +function consumeFinish (consume, err) { + if (consume.body === null) { + return + } - if (id === 0) { - this[kSocket][kError] = err - onError(this[kClient], err) + if (err) { + consume.reject(err) + } else { + consume.resolve() } -} -function onHttp2SessionEnd () { - util.destroy(this, new SocketError('other side closed')) - util.destroy(this[kSocket], new SocketError('other side closed')) + consume.type = null + consume.stream = null + consume.resolve = null + consume.reject = null + consume.length = 0 + consume.body = null } -function onHTTP2GoAway (code) { - const client = this[kClient] - const err = new InformationalError(`HTTP/2: "GOAWAY" frame received with code ${code}`) - client[kSocket] = null - client[kHTTP2Session] = null - - if (client.destroyed) { - assert(this[kPending] === 0) - - // Fail entire queue. - const requests = client[kQueue].splice(client[kRunningIdx]) - for (let i = 0; i < requests.length; i++) { - const request = requests[i] - errorRequest(this, request, err) - } - } else if (client[kRunning] > 0) { - // Fail head of pipeline. - const request = client[kQueue][client[kRunningIdx]] - client[kQueue][client[kRunningIdx]++] = null - errorRequest(client, request, err) - } +/***/ }), - client[kPendingIdx] = client[kRunningIdx] +/***/ 7474: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - assert(client[kRunning] === 0) +const assert = __nccwpck_require__(9491) +const { + ResponseStatusCodeError +} = __nccwpck_require__(8045) +const { toUSVString } = __nccwpck_require__(3983) - client.emit('disconnect', - client[kUrl], - [client], - err - ) +async function getResolveErrorBodyCallback ({ callback, body, contentType, statusCode, statusMessage, headers }) { + assert(body) - resume(client) -} + let chunks = [] + let limit = 0 -const constants = __nccwpck_require__(953) -const createRedirectInterceptor = __nccwpck_require__(8861) -const EMPTY_BUF = Buffer.alloc(0) + for await (const chunk of body) { + chunks.push(chunk) + limit += chunk.length + if (limit > 128 * 1024) { + chunks = null + break + } + } -async function lazyllhttp () { - const llhttpWasmData = process.env.JEST_WORKER_ID ? __nccwpck_require__(1145) : undefined + if (statusCode === 204 || !contentType || !chunks) { + process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers)) + return + } - let mod try { - mod = await WebAssembly.compile(Buffer.from(__nccwpck_require__(5627), 'base64')) - } catch (e) { - /* istanbul ignore next */ + if (contentType.startsWith('application/json')) { + const payload = JSON.parse(toUSVString(Buffer.concat(chunks))) + process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers, payload)) + return + } - // We could check if the error was caused by the simd option not - // being enabled, but the occurring of this other error - // * https://github.com/emscripten-core/emscripten/issues/11495 - // got me to remove that check to avoid breaking Node 12. - mod = await WebAssembly.compile(Buffer.from(llhttpWasmData || __nccwpck_require__(1145), 'base64')) + if (contentType.startsWith('text/')) { + const payload = toUSVString(Buffer.concat(chunks)) + process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers, payload)) + return + } + } catch (err) { + // Process in a fallback if error } - return await WebAssembly.instantiate(mod, { - env: { - /* eslint-disable camelcase */ + process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers)) +} - wasm_on_url: (p, at, len) => { - /* istanbul ignore next */ - return 0 - }, - wasm_on_status: (p, at, len) => { - assert.strictEqual(currentParser.ptr, p) - const start = at - currentBufferPtr + currentBufferRef.byteOffset - return currentParser.onStatus(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 - }, - wasm_on_message_begin: (p) => { - assert.strictEqual(currentParser.ptr, p) - return currentParser.onMessageBegin() || 0 - }, - wasm_on_header_field: (p, at, len) => { - assert.strictEqual(currentParser.ptr, p) - const start = at - currentBufferPtr + currentBufferRef.byteOffset - return currentParser.onHeaderField(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 - }, - wasm_on_header_value: (p, at, len) => { - assert.strictEqual(currentParser.ptr, p) - const start = at - currentBufferPtr + currentBufferRef.byteOffset - return currentParser.onHeaderValue(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 - }, - wasm_on_headers_complete: (p, statusCode, upgrade, shouldKeepAlive) => { - assert.strictEqual(currentParser.ptr, p) - return currentParser.onHeadersComplete(statusCode, Boolean(upgrade), Boolean(shouldKeepAlive)) || 0 - }, - wasm_on_body: (p, at, len) => { - assert.strictEqual(currentParser.ptr, p) - const start = at - currentBufferPtr + currentBufferRef.byteOffset - return currentParser.onBody(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 - }, - wasm_on_message_complete: (p) => { - assert.strictEqual(currentParser.ptr, p) - return currentParser.onMessageComplete() || 0 - } +module.exports = { getResolveErrorBodyCallback } - /* eslint-enable camelcase */ - } - }) -} -let llhttpInstance = null -let llhttpPromise = lazyllhttp() -llhttpPromise.catch() +/***/ }), -let currentParser = null -let currentBufferRef = null -let currentBufferSize = 0 -let currentBufferPtr = null +/***/ 7931: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -const TIMEOUT_HEADERS = 1 -const TIMEOUT_BODY = 2 -const TIMEOUT_IDLE = 3 +"use strict"; -class Parser { - constructor (client, socket, { exports }) { - assert(Number.isFinite(client[kMaxHeadersSize]) && client[kMaxHeadersSize] > 0) - this.llhttp = exports - this.ptr = this.llhttp.llhttp_alloc(constants.TYPE.RESPONSE) - this.client = client - this.socket = socket - this.timeout = null - this.timeoutValue = null - this.timeoutType = null - this.statusCode = null - this.statusText = '' - this.upgrade = false - this.headers = [] - this.headersSize = 0 - this.headersMaxSize = client[kMaxHeadersSize] - this.shouldKeepAlive = false - this.paused = false - this.resume = this.resume.bind(this) +const { + BalancedPoolMissingUpstreamError, + InvalidArgumentError +} = __nccwpck_require__(8045) +const { + PoolBase, + kClients, + kNeedDrain, + kAddClient, + kRemoveClient, + kGetDispatcher +} = __nccwpck_require__(3198) +const Pool = __nccwpck_require__(4634) +const { kUrl, kInterceptors } = __nccwpck_require__(2785) +const { parseOrigin } = __nccwpck_require__(3983) +const kFactory = Symbol('factory') - this.bytesRead = 0 +const kOptions = Symbol('options') +const kGreatestCommonDivisor = Symbol('kGreatestCommonDivisor') +const kCurrentWeight = Symbol('kCurrentWeight') +const kIndex = Symbol('kIndex') +const kWeight = Symbol('kWeight') +const kMaxWeightPerServer = Symbol('kMaxWeightPerServer') +const kErrorPenalty = Symbol('kErrorPenalty') - this.keepAlive = '' - this.contentLength = '' - this.connection = '' - this.maxResponseSize = client[kMaxResponseSize] - } +function getGreatestCommonDivisor (a, b) { + if (b === 0) return a + return getGreatestCommonDivisor(b, a % b) +} - setTimeout (value, type) { - this.timeoutType = type - if (value !== this.timeoutValue) { - timers.clearTimeout(this.timeout) - if (value) { - this.timeout = timers.setTimeout(onParserTimeout, value, this) - // istanbul ignore else: only for jest - if (this.timeout.unref) { - this.timeout.unref() - } - } else { - this.timeout = null - } - this.timeoutValue = value - } else if (this.timeout) { - // istanbul ignore else: only for jest - if (this.timeout.refresh) { - this.timeout.refresh() - } - } - } +function defaultFactory (origin, opts) { + return new Pool(origin, opts) +} - resume () { - if (this.socket.destroyed || !this.paused) { - return - } +class BalancedPool extends PoolBase { + constructor (upstreams = [], { factory = defaultFactory, ...opts } = {}) { + super() - assert(this.ptr != null) - assert(currentParser == null) + this[kOptions] = opts + this[kIndex] = -1 + this[kCurrentWeight] = 0 - this.llhttp.llhttp_resume(this.ptr) + this[kMaxWeightPerServer] = this[kOptions].maxWeightPerServer || 100 + this[kErrorPenalty] = this[kOptions].errorPenalty || 15 - assert(this.timeoutType === TIMEOUT_BODY) - if (this.timeout) { - // istanbul ignore else: only for jest - if (this.timeout.refresh) { - this.timeout.refresh() - } + if (!Array.isArray(upstreams)) { + upstreams = [upstreams] } - this.paused = false - this.execute(this.socket.read() || EMPTY_BUF) // Flush parser. - this.readMore() - } + if (typeof factory !== 'function') { + throw new InvalidArgumentError('factory must be a function.') + } - readMore () { - while (!this.paused && this.ptr) { - const chunk = this.socket.read() - if (chunk === null) { - break - } - this.execute(chunk) + this[kInterceptors] = opts.interceptors && opts.interceptors.BalancedPool && Array.isArray(opts.interceptors.BalancedPool) + ? opts.interceptors.BalancedPool + : [] + this[kFactory] = factory + + for (const upstream of upstreams) { + this.addUpstream(upstream) } + this._updateBalancedPoolStats() } - execute (data) { - assert(this.ptr != null) - assert(currentParser == null) - assert(!this.paused) - - const { socket, llhttp } = this + addUpstream (upstream) { + const upstreamOrigin = parseOrigin(upstream).origin - if (data.length > currentBufferSize) { - if (currentBufferPtr) { - llhttp.free(currentBufferPtr) - } - currentBufferSize = Math.ceil(data.length / 4096) * 4096 - currentBufferPtr = llhttp.malloc(currentBufferSize) + if (this[kClients].find((pool) => ( + pool[kUrl].origin === upstreamOrigin && + pool.closed !== true && + pool.destroyed !== true + ))) { + return this } + const pool = this[kFactory](upstreamOrigin, Object.assign({}, this[kOptions])) - new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize).set(data) + this[kAddClient](pool) + pool.on('connect', () => { + pool[kWeight] = Math.min(this[kMaxWeightPerServer], pool[kWeight] + this[kErrorPenalty]) + }) - // Call `execute` on the wasm parser. - // We pass the `llhttp_parser` pointer address, the pointer address of buffer view data, - // and finally the length of bytes to parse. - // The return value is an error code or `constants.ERROR.OK`. - try { - let ret + pool.on('connectionError', () => { + pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]) + this._updateBalancedPoolStats() + }) - try { - currentBufferRef = data - currentParser = this - ret = llhttp.llhttp_execute(this.ptr, currentBufferPtr, data.length) - /* eslint-disable-next-line no-useless-catch */ - } catch (err) { - /* istanbul ignore next: difficult to make a test case for */ - throw err - } finally { - currentParser = null - currentBufferRef = null + pool.on('disconnect', (...args) => { + const err = args[2] + if (err && err.code === 'UND_ERR_SOCKET') { + // decrease the weight of the pool. + pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]) + this._updateBalancedPoolStats() } + }) - const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr - - if (ret === constants.ERROR.PAUSED_UPGRADE) { - this.onUpgrade(data.slice(offset)) - } else if (ret === constants.ERROR.PAUSED) { - this.paused = true - socket.unshift(data.slice(offset)) - } else if (ret !== constants.ERROR.OK) { - const ptr = llhttp.llhttp_get_error_reason(this.ptr) - let message = '' - /* istanbul ignore else: difficult to make a test case for */ - if (ptr) { - const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0) - message = - 'Response does not match the HTTP/1.1 protocol (' + - Buffer.from(llhttp.memory.buffer, ptr, len).toString() + - ')' - } - throw new HTTPParserError(message, constants.ERROR[ret], data.slice(offset)) - } - } catch (err) { - util.destroy(socket, err) + for (const client of this[kClients]) { + client[kWeight] = this[kMaxWeightPerServer] } + + this._updateBalancedPoolStats() + + return this } - destroy () { - assert(this.ptr != null) - assert(currentParser == null) + _updateBalancedPoolStats () { + this[kGreatestCommonDivisor] = this[kClients].map(p => p[kWeight]).reduce(getGreatestCommonDivisor, 0) + } - this.llhttp.llhttp_free(this.ptr) - this.ptr = null + removeUpstream (upstream) { + const upstreamOrigin = parseOrigin(upstream).origin - timers.clearTimeout(this.timeout) - this.timeout = null - this.timeoutValue = null - this.timeoutType = null + const pool = this[kClients].find((pool) => ( + pool[kUrl].origin === upstreamOrigin && + pool.closed !== true && + pool.destroyed !== true + )) - this.paused = false - } + if (pool) { + this[kRemoveClient](pool) + } - onStatus (buf) { - this.statusText = buf.toString() + return this } - onMessageBegin () { - const { socket, client } = this + get upstreams () { + return this[kClients] + .filter(dispatcher => dispatcher.closed !== true && dispatcher.destroyed !== true) + .map((p) => p[kUrl].origin) + } - /* istanbul ignore next: difficult to make a test case for */ - if (socket.destroyed) { - return -1 + [kGetDispatcher] () { + // We validate that pools is greater than 0, + // otherwise we would have to wait until an upstream + // is added, which might never happen. + if (this[kClients].length === 0) { + throw new BalancedPoolMissingUpstreamError() } - const request = client[kQueue][client[kRunningIdx]] - if (!request) { - return -1 + const dispatcher = this[kClients].find(dispatcher => ( + !dispatcher[kNeedDrain] && + dispatcher.closed !== true && + dispatcher.destroyed !== true + )) + + if (!dispatcher) { + return } - } - onHeaderField (buf) { - const len = this.headers.length + const allClientsBusy = this[kClients].map(pool => pool[kNeedDrain]).reduce((a, b) => a && b, true) - if ((len & 1) === 0) { - this.headers.push(buf) - } else { - this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]) + if (allClientsBusy) { + return } - this.trackHeader(buf.length) - } + let counter = 0 - onHeaderValue (buf) { - let len = this.headers.length + let maxWeightIndex = this[kClients].findIndex(pool => !pool[kNeedDrain]) - if ((len & 1) === 1) { - this.headers.push(buf) - len += 1 - } else { - this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]) - } + while (counter++ < this[kClients].length) { + this[kIndex] = (this[kIndex] + 1) % this[kClients].length + const pool = this[kClients][this[kIndex]] - const key = this.headers[len - 2] - if (key.length === 10 && key.toString().toLowerCase() === 'keep-alive') { - this.keepAlive += buf.toString() - } else if (key.length === 10 && key.toString().toLowerCase() === 'connection') { - this.connection += buf.toString() - } else if (key.length === 14 && key.toString().toLowerCase() === 'content-length') { - this.contentLength += buf.toString() - } + // find pool index with the largest weight + if (pool[kWeight] > this[kClients][maxWeightIndex][kWeight] && !pool[kNeedDrain]) { + maxWeightIndex = this[kIndex] + } - this.trackHeader(buf.length) - } + // decrease the current weight every `this[kClients].length`. + if (this[kIndex] === 0) { + // Set the current weight to the next lower weight. + this[kCurrentWeight] = this[kCurrentWeight] - this[kGreatestCommonDivisor] - trackHeader (len) { - this.headersSize += len - if (this.headersSize >= this.headersMaxSize) { - util.destroy(this.socket, new HeadersOverflowError()) + if (this[kCurrentWeight] <= 0) { + this[kCurrentWeight] = this[kMaxWeightPerServer] + } + } + if (pool[kWeight] >= this[kCurrentWeight] && (!pool[kNeedDrain])) { + return pool + } } + + this[kCurrentWeight] = this[kClients][maxWeightIndex][kWeight] + this[kIndex] = maxWeightIndex + return this[kClients][maxWeightIndex] } +} - onUpgrade (head) { - const { upgrade, client, socket, headers, statusCode } = this +module.exports = BalancedPool - assert(upgrade) - const request = client[kQueue][client[kRunningIdx]] - assert(request) +/***/ }), - assert(!socket.destroyed) - assert(socket === client[kSocket]) - assert(!this.paused) - assert(request.upgrade || request.method === 'CONNECT') +/***/ 6101: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - this.statusCode = null - this.statusText = '' - this.shouldKeepAlive = null +"use strict"; - assert(this.headers.length % 2 === 0) - this.headers = [] - this.headersSize = 0 - socket.unshift(head) +const { kConstruct } = __nccwpck_require__(9174) +const { urlEquals, fieldValues: getFieldValues } = __nccwpck_require__(2396) +const { kEnumerableProperty, isDisturbed } = __nccwpck_require__(3983) +const { kHeadersList } = __nccwpck_require__(2785) +const { webidl } = __nccwpck_require__(1744) +const { Response, cloneResponse } = __nccwpck_require__(7823) +const { Request } = __nccwpck_require__(8359) +const { kState, kHeaders, kGuard, kRealm } = __nccwpck_require__(5861) +const { fetching } = __nccwpck_require__(4881) +const { urlIsHttpHttpsScheme, createDeferredPromise, readAllBytes } = __nccwpck_require__(2538) +const assert = __nccwpck_require__(9491) +const { getGlobalDispatcher } = __nccwpck_require__(1892) - socket[kParser].destroy() - socket[kParser] = null +/** + * @see https://w3c.github.io/ServiceWorker/#dfn-cache-batch-operation + * @typedef {Object} CacheBatchOperation + * @property {'delete' | 'put'} type + * @property {any} request + * @property {any} response + * @property {import('../../types/cache').CacheQueryOptions} options + */ - socket[kClient] = null - socket[kError] = null - socket - .removeListener('error', onSocketError) - .removeListener('readable', onSocketReadable) - .removeListener('end', onSocketEnd) - .removeListener('close', onSocketClose) +/** + * @see https://w3c.github.io/ServiceWorker/#dfn-request-response-list + * @typedef {[any, any][]} requestResponseList + */ - client[kSocket] = null - client[kQueue][client[kRunningIdx]++] = null - client.emit('disconnect', client[kUrl], [client], new InformationalError('upgrade')) +class Cache { + /** + * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-request-response-list + * @type {requestResponseList} + */ + #relevantRequestResponseList - try { - request.onUpgrade(statusCode, headers, socket) - } catch (err) { - util.destroy(socket, err) + constructor () { + if (arguments[0] !== kConstruct) { + webidl.illegalConstructor() } - resume(client) + this.#relevantRequestResponseList = arguments[1] } - onHeadersComplete (statusCode, upgrade, shouldKeepAlive) { - const { client, socket, headers, statusText } = this - - /* istanbul ignore next: difficult to make a test case for */ - if (socket.destroyed) { - return -1 - } + async match (request, options = {}) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.match' }) - const request = client[kQueue][client[kRunningIdx]] - - /* istanbul ignore next: difficult to make a test case for */ - if (!request) { - return -1 - } + request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options) - assert(!this.upgrade) - assert(this.statusCode < 200) + const p = await this.matchAll(request, options) - if (statusCode === 100) { - util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket))) - return -1 + if (p.length === 0) { + return } - /* this can only happen if server is misbehaving */ - if (upgrade && !request.upgrade) { - util.destroy(socket, new SocketError('bad upgrade', util.getSocketInfo(socket))) - return -1 - } + return p[0] + } - assert.strictEqual(this.timeoutType, TIMEOUT_HEADERS) + async matchAll (request = undefined, options = {}) { + webidl.brandCheck(this, Cache) - this.statusCode = statusCode - this.shouldKeepAlive = ( - shouldKeepAlive || - // Override llhttp value which does not allow keepAlive for HEAD. - (request.method === 'HEAD' && !socket[kReset] && this.connection.toLowerCase() === 'keep-alive') - ) + if (request !== undefined) request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options) - if (this.statusCode >= 200) { - const bodyTimeout = request.bodyTimeout != null - ? request.bodyTimeout - : client[kBodyTimeout] - this.setTimeout(bodyTimeout, TIMEOUT_BODY) - } else if (this.timeout) { - // istanbul ignore else: only for jest - if (this.timeout.refresh) { - this.timeout.refresh() - } - } + // 1. + let r = null - if (request.method === 'CONNECT') { - assert(client[kRunning] === 1) - this.upgrade = true - return 2 - } + // 2. + if (request !== undefined) { + if (request instanceof Request) { + // 2.1.1 + r = request[kState] - if (upgrade) { - assert(client[kRunning] === 1) - this.upgrade = true - return 2 + // 2.1.2 + if (r.method !== 'GET' && !options.ignoreMethod) { + return [] + } + } else if (typeof request === 'string') { + // 2.2.1 + r = new Request(request)[kState] + } } - assert(this.headers.length % 2 === 0) - this.headers = [] - this.headersSize = 0 + // 5. + // 5.1 + const responses = [] - if (this.shouldKeepAlive && client[kPipelining]) { - const keepAliveTimeout = this.keepAlive ? util.parseKeepAliveTimeout(this.keepAlive) : null + // 5.2 + if (request === undefined) { + // 5.2.1 + for (const requestResponse of this.#relevantRequestResponseList) { + responses.push(requestResponse[1]) + } + } else { // 5.3 + // 5.3.1 + const requestResponses = this.#queryCache(r, options) - if (keepAliveTimeout != null) { - const timeout = Math.min( - keepAliveTimeout - client[kKeepAliveTimeoutThreshold], - client[kKeepAliveMaxTimeout] - ) - if (timeout <= 0) { - socket[kReset] = true - } else { - client[kKeepAliveTimeoutValue] = timeout - } - } else { - client[kKeepAliveTimeoutValue] = client[kKeepAliveDefaultTimeout] + // 5.3.2 + for (const requestResponse of requestResponses) { + responses.push(requestResponse[1]) } - } else { - // Stop more requests from being dispatched. - socket[kReset] = true } - const pause = request.onHeaders(statusCode, headers, this.resume, statusText) === false - - if (request.aborted) { - return -1 - } + // 5.4 + // We don't implement CORs so we don't need to loop over the responses, yay! - if (request.method === 'HEAD') { - return 1 - } + // 5.5.1 + const responseList = [] - if (statusCode < 200) { - return 1 - } + // 5.5.2 + for (const response of responses) { + // 5.5.2.1 + const responseObject = new Response(response.body?.source ?? null) + const body = responseObject[kState].body + responseObject[kState] = response + responseObject[kState].body = body + responseObject[kHeaders][kHeadersList] = response.headersList + responseObject[kHeaders][kGuard] = 'immutable' - if (socket[kBlocking]) { - socket[kBlocking] = false - resume(client) + responseList.push(responseObject) } - return pause ? constants.ERROR.PAUSED : 0 + // 6. + return Object.freeze(responseList) } - onBody (buf) { - const { client, socket, statusCode, maxResponseSize } = this + async add (request) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.add' }) - if (socket.destroyed) { - return -1 - } + request = webidl.converters.RequestInfo(request) - const request = client[kQueue][client[kRunningIdx]] - assert(request) + // 1. + const requests = [request] - assert.strictEqual(this.timeoutType, TIMEOUT_BODY) - if (this.timeout) { - // istanbul ignore else: only for jest - if (this.timeout.refresh) { - this.timeout.refresh() - } - } + // 2. + const responseArrayPromise = this.addAll(requests) - assert(statusCode >= 200) + // 3. + return await responseArrayPromise + } - if (maxResponseSize > -1 && this.bytesRead + buf.length > maxResponseSize) { - util.destroy(socket, new ResponseExceededMaxSizeError()) - return -1 - } + async addAll (requests) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.addAll' }) - this.bytesRead += buf.length + requests = webidl.converters['sequence'](requests) - if (request.onData(buf) === false) { - return constants.ERROR.PAUSED - } - } + // 1. + const responsePromises = [] - onMessageComplete () { - const { client, socket, statusCode, upgrade, headers, contentLength, bytesRead, shouldKeepAlive } = this + // 2. + const requestList = [] - if (socket.destroyed && (!statusCode || shouldKeepAlive)) { - return -1 - } + // 3. + for (const request of requests) { + if (typeof request === 'string') { + continue + } - if (upgrade) { - return + // 3.1 + const r = request[kState] + + // 3.2 + if (!urlIsHttpHttpsScheme(r.url) || r.method !== 'GET') { + throw webidl.errors.exception({ + header: 'Cache.addAll', + message: 'Expected http/s scheme when method is not GET.' + }) + } } - const request = client[kQueue][client[kRunningIdx]] - assert(request) + // 4. + /** @type {ReturnType[]} */ + const fetchControllers = [] - assert(statusCode >= 100) + // 5. + for (const request of requests) { + // 5.1 + const r = new Request(request)[kState] - this.statusCode = null - this.statusText = '' - this.bytesRead = 0 - this.contentLength = '' - this.keepAlive = '' - this.connection = '' + // 5.2 + if (!urlIsHttpHttpsScheme(r.url)) { + throw webidl.errors.exception({ + header: 'Cache.addAll', + message: 'Expected http/s scheme.' + }) + } - assert(this.headers.length % 2 === 0) - this.headers = [] - this.headersSize = 0 + // 5.4 + r.initiator = 'fetch' + r.destination = 'subresource' - if (statusCode < 200) { - return - } + // 5.5 + requestList.push(r) - /* istanbul ignore next: should be handled by llhttp? */ - if (request.method !== 'HEAD' && contentLength && bytesRead !== parseInt(contentLength, 10)) { - util.destroy(socket, new ResponseContentLengthMismatchError()) - return -1 - } + // 5.6 + const responsePromise = createDeferredPromise() - request.onComplete(headers) + // 5.7 + fetchControllers.push(fetching({ + request: r, + dispatcher: getGlobalDispatcher(), + processResponse (response) { + // 1. + if (response.type === 'error' || response.status === 206 || response.status < 200 || response.status > 299) { + responsePromise.reject(webidl.errors.exception({ + header: 'Cache.addAll', + message: 'Received an invalid status code or the request failed.' + })) + } else if (response.headersList.contains('vary')) { // 2. + // 2.1 + const fieldValues = getFieldValues(response.headersList.get('vary')) - client[kQueue][client[kRunningIdx]++] = null - - if (socket[kWriting]) { - assert.strictEqual(client[kRunning], 0) - // Response completed before request. - util.destroy(socket, new InformationalError('reset')) - return constants.ERROR.PAUSED - } else if (!shouldKeepAlive) { - util.destroy(socket, new InformationalError('reset')) - return constants.ERROR.PAUSED - } else if (socket[kReset] && client[kRunning] === 0) { - // Destroy socket once all requests have completed. - // The request at the tail of the pipeline is the one - // that requested reset and no further requests should - // have been queued since then. - util.destroy(socket, new InformationalError('reset')) - return constants.ERROR.PAUSED - } else if (client[kPipelining] === 1) { - // We must wait a full event loop cycle to reuse this socket to make sure - // that non-spec compliant servers are not closing the connection even if they - // said they won't. - setImmediate(resume, client) - } else { - resume(client) - } - } -} - -function onParserTimeout (parser) { - const { socket, timeoutType, client } = parser - - /* istanbul ignore else */ - if (timeoutType === TIMEOUT_HEADERS) { - if (!socket[kWriting] || socket.writableNeedDrain || client[kRunning] > 1) { - assert(!parser.paused, 'cannot be paused while waiting for headers') - util.destroy(socket, new HeadersTimeoutError()) - } - } else if (timeoutType === TIMEOUT_BODY) { - if (!parser.paused) { - util.destroy(socket, new BodyTimeoutError()) - } - } else if (timeoutType === TIMEOUT_IDLE) { - assert(client[kRunning] === 0 && client[kKeepAliveTimeoutValue]) - util.destroy(socket, new InformationalError('socket idle timeout')) - } -} + // 2.2 + for (const fieldValue of fieldValues) { + // 2.2.1 + if (fieldValue === '*') { + responsePromise.reject(webidl.errors.exception({ + header: 'Cache.addAll', + message: 'invalid vary field value' + })) -function onSocketReadable () { - const { [kParser]: parser } = this - if (parser) { - parser.readMore() - } -} + for (const controller of fetchControllers) { + controller.abort() + } -function onSocketError (err) { - const { [kClient]: client, [kParser]: parser } = this + return + } + } + } + }, + processResponseEndOfBody (response) { + // 1. + if (response.aborted) { + responsePromise.reject(new DOMException('aborted', 'AbortError')) + return + } - assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') + // 2. + responsePromise.resolve(response) + } + })) - if (client[kHTTPConnVersion] !== 'h2') { - // On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded - // to the user. - if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) { - // We treat all incoming data so for as a valid response. - parser.onMessageComplete() - return + // 5.8 + responsePromises.push(responsePromise.promise) } - } - this[kError] = err + // 6. + const p = Promise.all(responsePromises) - onError(this[kClient], err) -} + // 7. + const responses = await p -function onError (client, err) { - if ( - client[kRunning] === 0 && - err.code !== 'UND_ERR_INFO' && - err.code !== 'UND_ERR_SOCKET' - ) { - // Error is not caused by running request and not a recoverable - // socket error. + // 7.1 + const operations = [] - assert(client[kPendingIdx] === client[kRunningIdx]) + // 7.2 + let index = 0 - const requests = client[kQueue].splice(client[kRunningIdx]) - for (let i = 0; i < requests.length; i++) { - const request = requests[i] - errorRequest(client, request, err) - } - assert(client[kSize] === 0) - } -} + // 7.3 + for (const response of responses) { + // 7.3.1 + /** @type {CacheBatchOperation} */ + const operation = { + type: 'put', // 7.3.2 + request: requestList[index], // 7.3.3 + response // 7.3.4 + } -function onSocketEnd () { - const { [kParser]: parser, [kClient]: client } = this + operations.push(operation) // 7.3.5 - if (client[kHTTPConnVersion] !== 'h2') { - if (parser.statusCode && !parser.shouldKeepAlive) { - // We treat all incoming data so far as a valid response. - parser.onMessageComplete() - return + index++ // 7.3.6 } - } - util.destroy(this, new SocketError('other side closed', util.getSocketInfo(this))) -} + // 7.5 + const cacheJobPromise = createDeferredPromise() -function onSocketClose () { - const { [kClient]: client, [kParser]: parser } = this + // 7.6.1 + let errorData = null - if (client[kHTTPConnVersion] === 'h1' && parser) { - if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) { - // We treat all incoming data so far as a valid response. - parser.onMessageComplete() + // 7.6.2 + try { + this.#batchCacheOperations(operations) + } catch (e) { + errorData = e } - this[kParser].destroy() - this[kParser] = null + // 7.6.3 + queueMicrotask(() => { + // 7.6.3.1 + if (errorData === null) { + cacheJobPromise.resolve(undefined) + } else { + // 7.6.3.2 + cacheJobPromise.reject(errorData) + } + }) + + // 7.7 + return cacheJobPromise.promise } - const err = this[kError] || new SocketError('closed', util.getSocketInfo(this)) + async put (request, response) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 2, { header: 'Cache.put' }) - client[kSocket] = null + request = webidl.converters.RequestInfo(request) + response = webidl.converters.Response(response) - if (client.destroyed) { - assert(client[kPending] === 0) + // 1. + let innerRequest = null - // Fail entire queue. - const requests = client[kQueue].splice(client[kRunningIdx]) - for (let i = 0; i < requests.length; i++) { - const request = requests[i] - errorRequest(client, request, err) + // 2. + if (request instanceof Request) { + innerRequest = request[kState] + } else { // 3. + innerRequest = new Request(request)[kState] } - } else if (client[kRunning] > 0 && err.code !== 'UND_ERR_INFO') { - // Fail head of pipeline. - const request = client[kQueue][client[kRunningIdx]] - client[kQueue][client[kRunningIdx]++] = null - - errorRequest(client, request, err) - } - client[kPendingIdx] = client[kRunningIdx] + // 4. + if (!urlIsHttpHttpsScheme(innerRequest.url) || innerRequest.method !== 'GET') { + throw webidl.errors.exception({ + header: 'Cache.put', + message: 'Expected an http/s scheme when method is not GET' + }) + } - assert(client[kRunning] === 0) + // 5. + const innerResponse = response[kState] - client.emit('disconnect', client[kUrl], [client], err) + // 6. + if (innerResponse.status === 206) { + throw webidl.errors.exception({ + header: 'Cache.put', + message: 'Got 206 status' + }) + } - resume(client) -} + // 7. + if (innerResponse.headersList.contains('vary')) { + // 7.1. + const fieldValues = getFieldValues(innerResponse.headersList.get('vary')) -async function connect (client) { - assert(!client[kConnecting]) - assert(!client[kSocket]) + // 7.2. + for (const fieldValue of fieldValues) { + // 7.2.1 + if (fieldValue === '*') { + throw webidl.errors.exception({ + header: 'Cache.put', + message: 'Got * vary field value' + }) + } + } + } - let { host, hostname, protocol, port } = client[kUrl] + // 8. + if (innerResponse.body && (isDisturbed(innerResponse.body.stream) || innerResponse.body.stream.locked)) { + throw webidl.errors.exception({ + header: 'Cache.put', + message: 'Response body is locked or disturbed' + }) + } - // Resolve ipv6 - if (hostname[0] === '[') { - const idx = hostname.indexOf(']') + // 9. + const clonedResponse = cloneResponse(innerResponse) - assert(idx !== -1) - const ip = hostname.substring(1, idx) + // 10. + const bodyReadPromise = createDeferredPromise() - assert(net.isIP(ip)) - hostname = ip - } + // 11. + if (innerResponse.body != null) { + // 11.1 + const stream = innerResponse.body.stream - client[kConnecting] = true + // 11.2 + const reader = stream.getReader() - if (channels.beforeConnect.hasSubscribers) { - channels.beforeConnect.publish({ - connectParams: { - host, - hostname, - protocol, - port, - servername: client[kServerName], - localAddress: client[kLocalAddress] - }, - connector: client[kConnector] - }) - } + // 11.3 + readAllBytes(reader).then(bodyReadPromise.resolve, bodyReadPromise.reject) + } else { + bodyReadPromise.resolve(undefined) + } - try { - const socket = await new Promise((resolve, reject) => { - client[kConnector]({ - host, - hostname, - protocol, - port, - servername: client[kServerName], - localAddress: client[kLocalAddress] - }, (err, socket) => { - if (err) { - reject(err) - } else { - resolve(socket) - } - }) - }) + // 12. + /** @type {CacheBatchOperation[]} */ + const operations = [] - if (client.destroyed) { - util.destroy(socket.on('error', () => {}), new ClientDestroyedError()) - return + // 13. + /** @type {CacheBatchOperation} */ + const operation = { + type: 'put', // 14. + request: innerRequest, // 15. + response: clonedResponse // 16. } - client[kConnecting] = false - - assert(socket) + // 17. + operations.push(operation) - const isH2 = socket.alpnProtocol === 'h2' - if (isH2) { - if (!h2ExperimentalWarned) { - h2ExperimentalWarned = true - process.emitWarning('H2 support is experimental, expect them to change at any time.', { - code: 'UNDICI-H2' - }) - } + // 19. + const bytes = await bodyReadPromise.promise - const session = http2.connect(client[kUrl], { - createConnection: () => socket, - peerMaxConcurrentStreams: client[kHTTP2SessionState].maxConcurrentStreams - }) + if (clonedResponse.body != null) { + clonedResponse.body.source = bytes + } - client[kHTTPConnVersion] = 'h2' - session[kClient] = client - session[kSocket] = socket - session.on('error', onHttp2SessionError) - session.on('frameError', onHttp2FrameError) - session.on('end', onHttp2SessionEnd) - session.on('goaway', onHTTP2GoAway) - session.on('close', onSocketClose) - session.unref() + // 19.1 + const cacheJobPromise = createDeferredPromise() - client[kHTTP2Session] = session - socket[kHTTP2Session] = session - } else { - if (!llhttpInstance) { - llhttpInstance = await llhttpPromise - llhttpPromise = null - } + // 19.2.1 + let errorData = null - socket[kNoRef] = false - socket[kWriting] = false - socket[kReset] = false - socket[kBlocking] = false - socket[kParser] = new Parser(client, socket, llhttpInstance) + // 19.2.2 + try { + this.#batchCacheOperations(operations) + } catch (e) { + errorData = e } - socket[kCounter] = 0 - socket[kMaxRequests] = client[kMaxRequests] - socket[kClient] = client - socket[kError] = null + // 19.2.3 + queueMicrotask(() => { + // 19.2.3.1 + if (errorData === null) { + cacheJobPromise.resolve() + } else { // 19.2.3.2 + cacheJobPromise.reject(errorData) + } + }) - socket - .on('error', onSocketError) - .on('readable', onSocketReadable) - .on('end', onSocketEnd) - .on('close', onSocketClose) + return cacheJobPromise.promise + } - client[kSocket] = socket + async delete (request, options = {}) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.delete' }) - if (channels.connected.hasSubscribers) { - channels.connected.publish({ - connectParams: { - host, - hostname, - protocol, - port, - servername: client[kServerName], - localAddress: client[kLocalAddress] - }, - connector: client[kConnector], - socket - }) - } - client.emit('connect', client[kUrl], [client]) - } catch (err) { - if (client.destroyed) { - return - } + request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options) - client[kConnecting] = false + /** + * @type {Request} + */ + let r = null - if (channels.connectError.hasSubscribers) { - channels.connectError.publish({ - connectParams: { - host, - hostname, - protocol, - port, - servername: client[kServerName], - localAddress: client[kLocalAddress] - }, - connector: client[kConnector], - error: err - }) - } + if (request instanceof Request) { + r = request[kState] - if (err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') { - assert(client[kRunning] === 0) - while (client[kPending] > 0 && client[kQueue][client[kPendingIdx]].servername === client[kServerName]) { - const request = client[kQueue][client[kPendingIdx]++] - errorRequest(client, request, err) + if (r.method !== 'GET' && !options.ignoreMethod) { + return false } } else { - onError(client, err) + assert(typeof request === 'string') + + r = new Request(request)[kState] } - client.emit('connectionError', client[kUrl], [client], err) - } + /** @type {CacheBatchOperation[]} */ + const operations = [] - resume(client) -} + /** @type {CacheBatchOperation} */ + const operation = { + type: 'delete', + request: r, + options + } -function emitDrain (client) { - client[kNeedDrain] = 0 - client.emit('drain', client[kUrl], [client]) -} + operations.push(operation) -function resume (client, sync) { - if (client[kResuming] === 2) { - return - } + const cacheJobPromise = createDeferredPromise() - client[kResuming] = 2 + let errorData = null + let requestResponses - _resume(client, sync) - client[kResuming] = 0 + try { + requestResponses = this.#batchCacheOperations(operations) + } catch (e) { + errorData = e + } - if (client[kRunningIdx] > 256) { - client[kQueue].splice(0, client[kRunningIdx]) - client[kPendingIdx] -= client[kRunningIdx] - client[kRunningIdx] = 0 + queueMicrotask(() => { + if (errorData === null) { + cacheJobPromise.resolve(!!requestResponses?.length) + } else { + cacheJobPromise.reject(errorData) + } + }) + + return cacheJobPromise.promise } -} -function _resume (client, sync) { - while (true) { - if (client.destroyed) { - assert(client[kPending] === 0) - return - } + /** + * @see https://w3c.github.io/ServiceWorker/#dom-cache-keys + * @param {any} request + * @param {import('../../types/cache').CacheQueryOptions} options + * @returns {readonly Request[]} + */ + async keys (request = undefined, options = {}) { + webidl.brandCheck(this, Cache) - if (client[kClosedResolve] && !client[kSize]) { - client[kClosedResolve]() - client[kClosedResolve] = null - return - } + if (request !== undefined) request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options) - const socket = client[kSocket] + // 1. + let r = null - if (socket && !socket.destroyed && socket.alpnProtocol !== 'h2') { - if (client[kSize] === 0) { - if (!socket[kNoRef] && socket.unref) { - socket.unref() - socket[kNoRef] = true - } - } else if (socket[kNoRef] && socket.ref) { - socket.ref() - socket[kNoRef] = false - } + // 2. + if (request !== undefined) { + // 2.1 + if (request instanceof Request) { + // 2.1.1 + r = request[kState] - if (client[kSize] === 0) { - if (socket[kParser].timeoutType !== TIMEOUT_IDLE) { - socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_IDLE) - } - } else if (client[kRunning] > 0 && socket[kParser].statusCode < 200) { - if (socket[kParser].timeoutType !== TIMEOUT_HEADERS) { - const request = client[kQueue][client[kRunningIdx]] - const headersTimeout = request.headersTimeout != null - ? request.headersTimeout - : client[kHeadersTimeout] - socket[kParser].setTimeout(headersTimeout, TIMEOUT_HEADERS) + // 2.1.2 + if (r.method !== 'GET' && !options.ignoreMethod) { + return [] } + } else if (typeof request === 'string') { // 2.2 + r = new Request(request)[kState] } } - if (client[kBusy]) { - client[kNeedDrain] = 2 - } else if (client[kNeedDrain] === 2) { - if (sync) { - client[kNeedDrain] = 1 - process.nextTick(emitDrain, client) - } else { - emitDrain(client) + // 4. + const promise = createDeferredPromise() + + // 5. + // 5.1 + const requests = [] + + // 5.2 + if (request === undefined) { + // 5.2.1 + for (const requestResponse of this.#relevantRequestResponseList) { + // 5.2.1.1 + requests.push(requestResponse[0]) } - continue - } + } else { // 5.3 + // 5.3.1 + const requestResponses = this.#queryCache(r, options) - if (client[kPending] === 0) { - return + // 5.3.2 + for (const requestResponse of requestResponses) { + // 5.3.2.1 + requests.push(requestResponse[0]) + } } - if (client[kRunning] >= (client[kPipelining] || 1)) { - return - } + // 5.4 + queueMicrotask(() => { + // 5.4.1 + const requestList = [] - const request = client[kQueue][client[kPendingIdx]] + // 5.4.2 + for (const request of requests) { + const requestObject = new Request('https://a') + requestObject[kState] = request + requestObject[kHeaders][kHeadersList] = request.headersList + requestObject[kHeaders][kGuard] = 'immutable' + requestObject[kRealm] = request.client - if (client[kUrl].protocol === 'https:' && client[kServerName] !== request.servername) { - if (client[kRunning] > 0) { - return + // 5.4.2.1 + requestList.push(requestObject) } - client[kServerName] = request.servername + // 5.4.3 + promise.resolve(Object.freeze(requestList)) + }) - if (socket && socket.servername !== request.servername) { - util.destroy(socket, new InformationalError('servername changed')) - return - } - } + return promise.promise + } - if (client[kConnecting]) { - return - } + /** + * @see https://w3c.github.io/ServiceWorker/#batch-cache-operations-algorithm + * @param {CacheBatchOperation[]} operations + * @returns {requestResponseList} + */ + #batchCacheOperations (operations) { + // 1. + const cache = this.#relevantRequestResponseList - if (!socket && !client[kHTTP2Session]) { - connect(client) - return - } + // 2. + const backupCache = [...cache] - if (socket.destroyed || socket[kWriting] || socket[kReset] || socket[kBlocking]) { - return - } + // 3. + const addedItems = [] - if (client[kRunning] > 0 && !request.idempotent) { - // Non-idempotent request cannot be retried. - // Ensure that no other requests are inflight and - // could cause failure. - return - } + // 4.1 + const resultList = [] - if (client[kRunning] > 0 && (request.upgrade || request.method === 'CONNECT')) { - // Don't dispatch an upgrade until all preceding requests have completed. - // A misbehaving server might upgrade the connection before all pipelined - // request has completed. - return - } + try { + // 4.2 + for (const operation of operations) { + // 4.2.1 + if (operation.type !== 'delete' && operation.type !== 'put') { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'operation type does not match "delete" or "put"' + }) + } - if (client[kRunning] > 0 && util.bodyLength(request.body) !== 0 && - (util.isStream(request.body) || util.isAsyncIterable(request.body))) { - // Request with stream or iterator body can error while other requests - // are inflight and indirectly error those as well. - // Ensure this doesn't happen by waiting for inflight - // to complete before dispatching. + // 4.2.2 + if (operation.type === 'delete' && operation.response != null) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'delete operation should not have an associated response' + }) + } - // Request with stream or iterator body cannot be retried. - // Ensure that no other requests are inflight and - // could cause failure. - return - } + // 4.2.3 + if (this.#queryCache(operation.request, operation.options, addedItems).length) { + throw new DOMException('???', 'InvalidStateError') + } - if (!request.aborted && write(client, request)) { - client[kPendingIdx]++ - } else { - client[kQueue].splice(client[kPendingIdx], 1) - } - } -} + // 4.2.4 + let requestResponses -// https://www.rfc-editor.org/rfc/rfc7230#section-3.3.2 -function shouldSendContentLength (method) { - return method !== 'GET' && method !== 'HEAD' && method !== 'OPTIONS' && method !== 'TRACE' && method !== 'CONNECT' -} + // 4.2.5 + if (operation.type === 'delete') { + // 4.2.5.1 + requestResponses = this.#queryCache(operation.request, operation.options) -function write (client, request) { - if (client[kHTTPConnVersion] === 'h2') { - writeH2(client, client[kHTTP2Session], request) - return - } + // TODO: the spec is wrong, this is needed to pass WPTs + if (requestResponses.length === 0) { + return [] + } - const { body, method, path, host, upgrade, headers, blocking, reset } = request + // 4.2.5.2 + for (const requestResponse of requestResponses) { + const idx = cache.indexOf(requestResponse) + assert(idx !== -1) - // https://tools.ietf.org/html/rfc7231#section-4.3.1 - // https://tools.ietf.org/html/rfc7231#section-4.3.2 - // https://tools.ietf.org/html/rfc7231#section-4.3.5 + // 4.2.5.2.1 + cache.splice(idx, 1) + } + } else if (operation.type === 'put') { // 4.2.6 + // 4.2.6.1 + if (operation.response == null) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'put operation should have an associated response' + }) + } - // Sending a payload body on a request that does not - // expect it can cause undefined behavior on some - // servers and corrupt connection state. Do not - // re-use the connection for further requests. + // 4.2.6.2 + const r = operation.request - const expectsPayload = ( - method === 'PUT' || - method === 'POST' || - method === 'PATCH' - ) + // 4.2.6.3 + if (!urlIsHttpHttpsScheme(r.url)) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'expected http or https scheme' + }) + } - if (body && typeof body.read === 'function') { - // Try to read EOF in order to get length. - body.read(0) - } + // 4.2.6.4 + if (r.method !== 'GET') { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'not get method' + }) + } - const bodyLength = util.bodyLength(body) + // 4.2.6.5 + if (operation.options != null) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'options must not be defined' + }) + } - let contentLength = bodyLength + // 4.2.6.6 + requestResponses = this.#queryCache(operation.request) - if (contentLength === null) { - contentLength = request.contentLength - } + // 4.2.6.7 + for (const requestResponse of requestResponses) { + const idx = cache.indexOf(requestResponse) + assert(idx !== -1) - if (contentLength === 0 && !expectsPayload) { - // https://tools.ietf.org/html/rfc7230#section-3.3.2 - // A user agent SHOULD NOT send a Content-Length header field when - // the request message does not contain a payload body and the method - // semantics do not anticipate such a body. - - contentLength = null - } - - // https://github.com/nodejs/undici/issues/2046 - // A user agent may send a Content-Length header with 0 value, this should be allowed. - if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength !== null && request.contentLength !== contentLength) { - if (client[kStrictContentLength]) { - errorRequest(client, request, new RequestContentLengthMismatchError()) - return false - } + // 4.2.6.7.1 + cache.splice(idx, 1) + } - process.emitWarning(new RequestContentLengthMismatchError()) - } + // 4.2.6.8 + cache.push([operation.request, operation.response]) - const socket = client[kSocket] + // 4.2.6.10 + addedItems.push([operation.request, operation.response]) + } - try { - request.onConnect((err) => { - if (request.aborted || request.completed) { - return + // 4.2.7 + resultList.push([operation.request, operation.response]) } - errorRequest(client, request, err || new RequestAbortedError()) + // 4.3 + return resultList + } catch (e) { // 5. + // 5.1 + this.#relevantRequestResponseList.length = 0 - util.destroy(socket, new InformationalError('aborted')) - }) - } catch (err) { - errorRequest(client, request, err) - } + // 5.2 + this.#relevantRequestResponseList = backupCache - if (request.aborted) { - return false + // 5.3 + throw e + } } - if (method === 'HEAD') { - // https://github.com/mcollina/undici/issues/258 - // Close after a HEAD request to interop with misbehaving servers - // that may send a body in the response. + /** + * @see https://w3c.github.io/ServiceWorker/#query-cache + * @param {any} requestQuery + * @param {import('../../types/cache').CacheQueryOptions} options + * @param {requestResponseList} targetStorage + * @returns {requestResponseList} + */ + #queryCache (requestQuery, options, targetStorage) { + /** @type {requestResponseList} */ + const resultList = [] - socket[kReset] = true - } + const storage = targetStorage ?? this.#relevantRequestResponseList - if (upgrade || method === 'CONNECT') { - // On CONNECT or upgrade, block pipeline from dispatching further - // requests on this connection. + for (const requestResponse of storage) { + const [cachedRequest, cachedResponse] = requestResponse + if (this.#requestMatchesCachedItem(requestQuery, cachedRequest, cachedResponse, options)) { + resultList.push(requestResponse) + } + } - socket[kReset] = true + return resultList } - if (reset != null) { - socket[kReset] = reset - } + /** + * @see https://w3c.github.io/ServiceWorker/#request-matches-cached-item-algorithm + * @param {any} requestQuery + * @param {any} request + * @param {any | null} response + * @param {import('../../types/cache').CacheQueryOptions | undefined} options + * @returns {boolean} + */ + #requestMatchesCachedItem (requestQuery, request, response = null, options) { + // if (options?.ignoreMethod === false && request.method === 'GET') { + // return false + // } - if (client[kMaxRequests] && socket[kCounter]++ >= client[kMaxRequests]) { - socket[kReset] = true - } + const queryURL = new URL(requestQuery.url) - if (blocking) { - socket[kBlocking] = true - } + const cachedURL = new URL(request.url) - let header = `${method} ${path} HTTP/1.1\r\n` + if (options?.ignoreSearch) { + cachedURL.search = '' - if (typeof host === 'string') { - header += `host: ${host}\r\n` - } else { - header += client[kHostHeader] - } + queryURL.search = '' + } - if (upgrade) { - header += `connection: upgrade\r\nupgrade: ${upgrade}\r\n` - } else if (client[kPipelining] && !socket[kReset]) { - header += 'connection: keep-alive\r\n' - } else { - header += 'connection: close\r\n' - } + if (!urlEquals(queryURL, cachedURL, true)) { + return false + } - if (headers) { - header += headers - } + if ( + response == null || + options?.ignoreVary || + !response.headersList.contains('vary') + ) { + return true + } - if (channels.sendHeaders.hasSubscribers) { - channels.sendHeaders.publish({ request, headers: header, socket }) - } + const fieldValues = getFieldValues(response.headersList.get('vary')) - /* istanbul ignore else: assertion */ - if (!body || bodyLength === 0) { - if (contentLength === 0) { - socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1') - } else { - assert(contentLength === null, 'no body must not have content length') - socket.write(`${header}\r\n`, 'latin1') - } - request.onRequestSent() - } else if (util.isBuffer(body)) { - assert(contentLength === body.byteLength, 'buffer body must have content length') + for (const fieldValue of fieldValues) { + if (fieldValue === '*') { + return false + } - socket.cork() - socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') - socket.write(body) - socket.uncork() - request.onBodySent(body) - request.onRequestSent() - if (!expectsPayload) { - socket[kReset] = true - } - } else if (util.isBlobLike(body)) { - if (typeof body.stream === 'function') { - writeIterable({ body: body.stream(), client, request, socket, contentLength, header, expectsPayload }) - } else { - writeBlob({ body, client, request, socket, contentLength, header, expectsPayload }) + const requestValue = request.headersList.get(fieldValue) + const queryValue = requestQuery.headersList.get(fieldValue) + + // If one has the header and the other doesn't, or one has + // a different value than the other, return false + if (requestValue !== queryValue) { + return false + } } - } else if (util.isStream(body)) { - writeStream({ body, client, request, socket, contentLength, header, expectsPayload }) - } else if (util.isIterable(body)) { - writeIterable({ body, client, request, socket, contentLength, header, expectsPayload }) - } else { - assert(false) - } - return true + return true + } } -function writeH2 (client, session, request) { - const { body, method, path, host, upgrade, expectContinue, signal, headers: reqHeaders } = request - - let headers - if (typeof reqHeaders === 'string') headers = Request[kHTTP2CopyHeaders](reqHeaders.trim()) - else headers = reqHeaders +Object.defineProperties(Cache.prototype, { + [Symbol.toStringTag]: { + value: 'Cache', + configurable: true + }, + match: kEnumerableProperty, + matchAll: kEnumerableProperty, + add: kEnumerableProperty, + addAll: kEnumerableProperty, + put: kEnumerableProperty, + delete: kEnumerableProperty, + keys: kEnumerableProperty +}) - if (upgrade) { - errorRequest(client, request, new Error('Upgrade not supported for H2')) - return false +const cacheQueryOptionConverters = [ + { + key: 'ignoreSearch', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'ignoreMethod', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'ignoreVary', + converter: webidl.converters.boolean, + defaultValue: false } +] - try { - // TODO(HTTP/2): Should we call onConnect immediately or on stream ready event? - request.onConnect((err) => { - if (request.aborted || request.completed) { - return - } +webidl.converters.CacheQueryOptions = webidl.dictionaryConverter(cacheQueryOptionConverters) - errorRequest(client, request, err || new RequestAbortedError()) - }) - } catch (err) { - errorRequest(client, request, err) +webidl.converters.MultiCacheQueryOptions = webidl.dictionaryConverter([ + ...cacheQueryOptionConverters, + { + key: 'cacheName', + converter: webidl.converters.DOMString } +]) - if (request.aborted) { - return false - } +webidl.converters.Response = webidl.interfaceConverter(Response) - /** @type {import('node:http2').ClientHttp2Stream} */ - let stream - const h2State = client[kHTTP2SessionState] +webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.RequestInfo +) - headers[HTTP2_HEADER_AUTHORITY] = host || client[kHost] - headers[HTTP2_HEADER_METHOD] = method +module.exports = { + Cache +} - if (method === 'CONNECT') { - session.ref() - // we are already connected, streams are pending, first request - // will create a new stream. We trigger a request to create the stream and wait until - // `ready` event is triggered - // We disabled endStream to allow the user to write to the stream - stream = session.request(headers, { endStream: false, signal }) - if (stream.id && !stream.pending) { - request.onUpgrade(null, null, stream) - ++h2State.openStreams - } else { - stream.once('ready', () => { - request.onUpgrade(null, null, stream) - ++h2State.openStreams - }) - } +/***/ }), - stream.once('close', () => { - h2State.openStreams -= 1 - // TODO(HTTP/2): unref only if current streams count is 0 - if (h2State.openStreams === 0) session.unref() - }) +/***/ 7907: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - return true +"use strict"; + + +const { kConstruct } = __nccwpck_require__(9174) +const { Cache } = __nccwpck_require__(6101) +const { webidl } = __nccwpck_require__(1744) +const { kEnumerableProperty } = __nccwpck_require__(3983) + +class CacheStorage { + /** + * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-name-to-cache-map + * @type {Map} + */ + async has (cacheName) { + webidl.brandCheck(this, CacheStorage) + webidl.argumentLengthCheck(arguments, 1, { header: 'CacheStorage.has' }) - if (contentLength == null) { - contentLength = request.contentLength + cacheName = webidl.converters.DOMString(cacheName) + + // 2.1.1 + // 2.2 + return this.#caches.has(cacheName) } - if (contentLength === 0 || !expectsPayload) { - // https://tools.ietf.org/html/rfc7230#section-3.3.2 - // A user agent SHOULD NOT send a Content-Length header field when - // the request message does not contain a payload body and the method - // semantics do not anticipate such a body. + /** + * @see https://w3c.github.io/ServiceWorker/#dom-cachestorage-open + * @param {string} cacheName + * @returns {Promise} + */ + async open (cacheName) { + webidl.brandCheck(this, CacheStorage) + webidl.argumentLengthCheck(arguments, 1, { header: 'CacheStorage.open' }) - contentLength = null - } + cacheName = webidl.converters.DOMString(cacheName) - // https://github.com/nodejs/undici/issues/2046 - // A user agent may send a Content-Length header with 0 value, this should be allowed. - if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength != null && request.contentLength !== contentLength) { - if (client[kStrictContentLength]) { - errorRequest(client, request, new RequestContentLengthMismatchError()) - return false + // 2.1 + if (this.#caches.has(cacheName)) { + // await caches.open('v1') !== await caches.open('v1') + + // 2.1.1 + const cache = this.#caches.get(cacheName) + + // 2.1.1.1 + return new Cache(kConstruct, cache) } - process.emitWarning(new RequestContentLengthMismatchError()) + // 2.2 + const cache = [] + + // 2.3 + this.#caches.set(cacheName, cache) + + // 2.4 + return new Cache(kConstruct, cache) } - if (contentLength != null) { - assert(body, 'no body must not have content length') - headers[HTTP2_HEADER_CONTENT_LENGTH] = `${contentLength}` + /** + * @see https://w3c.github.io/ServiceWorker/#cache-storage-delete + * @param {string} cacheName + * @returns {Promise} + */ + async delete (cacheName) { + webidl.brandCheck(this, CacheStorage) + webidl.argumentLengthCheck(arguments, 1, { header: 'CacheStorage.delete' }) + + cacheName = webidl.converters.DOMString(cacheName) + + return this.#caches.delete(cacheName) } - session.ref() + /** + * @see https://w3c.github.io/ServiceWorker/#cache-storage-keys + * @returns {string[]} + */ + async keys () { + webidl.brandCheck(this, CacheStorage) - const shouldEndStream = method === 'GET' || method === 'HEAD' - if (expectContinue) { - headers[HTTP2_HEADER_EXPECT] = '100-continue' - stream = session.request(headers, { endStream: shouldEndStream, signal }) + // 2.1 + const keys = this.#caches.keys() - stream.once('continue', writeBodyH2) - } else { - stream = session.request(headers, { - endStream: shouldEndStream, - signal - }) - writeBodyH2() + // 2.2 + return [...keys] } +} - // Increment counter as we have new several streams open - ++h2State.openStreams +Object.defineProperties(CacheStorage.prototype, { + [Symbol.toStringTag]: { + value: 'CacheStorage', + configurable: true + }, + match: kEnumerableProperty, + has: kEnumerableProperty, + open: kEnumerableProperty, + delete: kEnumerableProperty, + keys: kEnumerableProperty +}) - stream.once('response', headers => { - const { [HTTP2_HEADER_STATUS]: statusCode, ...realHeaders } = headers +module.exports = { + CacheStorage +} - if (request.onHeaders(Number(statusCode), realHeaders, stream.resume.bind(stream), '') === false) { - stream.pause() - } - }) - stream.once('end', () => { - request.onComplete([]) - }) +/***/ }), - stream.on('data', (chunk) => { - if (request.onData(chunk) === false) { - stream.pause() - } - }) +/***/ 9174: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - stream.once('close', () => { - h2State.openStreams -= 1 - // TODO(HTTP/2): unref only if current streams count is 0 - if (h2State.openStreams === 0) { - session.unref() - } - }) +"use strict"; - stream.once('error', function (err) { - if (client[kHTTP2Session] && !client[kHTTP2Session].destroyed && !this.closed && !this.destroyed) { - h2State.streams -= 1 - util.destroy(stream, err) - } - }) - stream.once('frameError', (type, code) => { - const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`) - errorRequest(client, request, err) +module.exports = { + kConstruct: (__nccwpck_require__(2785).kConstruct) +} - if (client[kHTTP2Session] && !client[kHTTP2Session].destroyed && !this.closed && !this.destroyed) { - h2State.streams -= 1 - util.destroy(stream, err) - } - }) - // stream.on('aborted', () => { - // // TODO(HTTP/2): Support aborted - // }) +/***/ }), - // stream.on('timeout', () => { - // // TODO(HTTP/2): Support timeout - // }) +/***/ 2396: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // stream.on('push', headers => { - // // TODO(HTTP/2): Suppor push - // }) +"use strict"; - // stream.on('trailers', headers => { - // // TODO(HTTP/2): Support trailers - // }) - return true +const assert = __nccwpck_require__(9491) +const { URLSerializer } = __nccwpck_require__(685) +const { isValidHeaderName } = __nccwpck_require__(2538) - function writeBodyH2 () { - /* istanbul ignore else: assertion */ - if (!body) { - request.onRequestSent() - } else if (util.isBuffer(body)) { - assert(contentLength === body.byteLength, 'buffer body must have content length') - stream.cork() - stream.write(body) - stream.uncork() - stream.end() - request.onBodySent(body) - request.onRequestSent() - } else if (util.isBlobLike(body)) { - if (typeof body.stream === 'function') { - writeIterable({ - client, - request, - contentLength, - h2stream: stream, - expectsPayload, - body: body.stream(), - socket: client[kSocket], - header: '' - }) - } else { - writeBlob({ - body, - client, - request, - contentLength, - expectsPayload, - h2stream: stream, - header: '', - socket: client[kSocket] - }) - } - } else if (util.isStream(body)) { - writeStream({ - body, - client, - request, - contentLength, - expectsPayload, - socket: client[kSocket], - h2stream: stream, - header: '' - }) - } else if (util.isIterable(body)) { - writeIterable({ - body, - client, - request, - contentLength, - expectsPayload, - header: '', - h2stream: stream, - socket: client[kSocket] - }) - } else { - assert(false) - } - } -} - -function writeStream ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { - assert(contentLength !== 0 || client[kRunning] === 0, 'stream body cannot be pipelined') - - if (client[kHTTPConnVersion] === 'h2') { - // For HTTP/2, is enough to pipe the stream - const pipe = pipeline( - body, - h2stream, - (err) => { - if (err) { - util.destroy(body, err) - util.destroy(h2stream, err) - } else { - request.onRequestSent() - } - } - ) - - pipe.on('data', onPipeData) - pipe.once('end', () => { - pipe.removeListener('data', onPipeData) - util.destroy(pipe) - }) - - function onPipeData (chunk) { - request.onBodySent(chunk) - } - - return - } - - let finished = false - - const writer = new AsyncWriter({ socket, request, contentLength, client, expectsPayload, header }) - - const onData = function (chunk) { - if (finished) { - return - } - - try { - if (!writer.write(chunk) && this.pause) { - this.pause() - } - } catch (err) { - util.destroy(this, err) - } - } - const onDrain = function () { - if (finished) { - return - } - - if (body.resume) { - body.resume() - } - } - const onAbort = function () { - if (finished) { - return - } - const err = new RequestAbortedError() - queueMicrotask(() => onFinished(err)) - } - const onFinished = function (err) { - if (finished) { - return - } - - finished = true +/** + * @see https://url.spec.whatwg.org/#concept-url-equals + * @param {URL} A + * @param {URL} B + * @param {boolean | undefined} excludeFragment + * @returns {boolean} + */ +function urlEquals (A, B, excludeFragment = false) { + const serializedA = URLSerializer(A, excludeFragment) - assert(socket.destroyed || (socket[kWriting] && client[kRunning] <= 1)) + const serializedB = URLSerializer(B, excludeFragment) - socket - .off('drain', onDrain) - .off('error', onFinished) + return serializedA === serializedB +} - body - .removeListener('data', onData) - .removeListener('end', onFinished) - .removeListener('error', onFinished) - .removeListener('close', onAbort) +/** + * @see https://github.com/chromium/chromium/blob/694d20d134cb553d8d89e5500b9148012b1ba299/content/browser/cache_storage/cache_storage_cache.cc#L260-L262 + * @param {string} header + */ +function fieldValues (header) { + assert(header !== null) - if (!err) { - try { - writer.end() - } catch (er) { - err = er - } - } + const values = [] - writer.destroy(err) + for (let value of header.split(',')) { + value = value.trim() - if (err && (err.code !== 'UND_ERR_INFO' || err.message !== 'reset')) { - util.destroy(body, err) - } else { - util.destroy(body) + if (!value.length) { + continue + } else if (!isValidHeaderName(value)) { + continue } - } - - body - .on('data', onData) - .on('end', onFinished) - .on('error', onFinished) - .on('close', onAbort) - if (body.resume) { - body.resume() + values.push(value) } - socket - .on('drain', onDrain) - .on('error', onFinished) + return values } -async function writeBlob ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { - assert(contentLength === body.size, 'blob body must have content length') - - const isH2 = client[kHTTPConnVersion] === 'h2' - try { - if (contentLength != null && contentLength !== body.size) { - throw new RequestContentLengthMismatchError() - } - - const buffer = Buffer.from(await body.arrayBuffer()) - - if (isH2) { - h2stream.cork() - h2stream.write(buffer) - h2stream.uncork() - } else { - socket.cork() - socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') - socket.write(buffer) - socket.uncork() - } +module.exports = { + urlEquals, + fieldValues +} - request.onBodySent(buffer) - request.onRequestSent() - if (!expectsPayload) { - socket[kReset] = true - } +/***/ }), - resume(client) - } catch (err) { - util.destroy(isH2 ? h2stream : socket, err) - } -} +/***/ 3598: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -async function writeIterable ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { - assert(contentLength !== 0 || client[kRunning] === 0, 'iterator body cannot be pipelined') +"use strict"; +// @ts-check - let callback = null - function onDrain () { - if (callback) { - const cb = callback - callback = null - cb() - } - } - const waitForDrain = () => new Promise((resolve, reject) => { - assert(callback === null) - if (socket[kError]) { - reject(socket[kError]) - } else { - callback = resolve - } - }) +/* global WebAssembly */ - if (client[kHTTPConnVersion] === 'h2') { - h2stream - .on('close', onDrain) - .on('drain', onDrain) - - try { - // It's up to the user to somehow abort the async iterable. - for await (const chunk of body) { - if (socket[kError]) { - throw socket[kError] - } +const assert = __nccwpck_require__(9491) +const net = __nccwpck_require__(1808) +const http = __nccwpck_require__(3685) +const { pipeline } = __nccwpck_require__(2781) +const util = __nccwpck_require__(3983) +const timers = __nccwpck_require__(9459) +const Request = __nccwpck_require__(2905) +const DispatcherBase = __nccwpck_require__(4839) +const { + RequestContentLengthMismatchError, + ResponseContentLengthMismatchError, + InvalidArgumentError, + RequestAbortedError, + HeadersTimeoutError, + HeadersOverflowError, + SocketError, + InformationalError, + BodyTimeoutError, + HTTPParserError, + ResponseExceededMaxSizeError, + ClientDestroyedError +} = __nccwpck_require__(8045) +const buildConnector = __nccwpck_require__(2067) +const { + kUrl, + kReset, + kServerName, + kClient, + kBusy, + kParser, + kConnect, + kBlocking, + kResuming, + kRunning, + kPending, + kSize, + kWriting, + kQueue, + kConnected, + kConnecting, + kNeedDrain, + kNoRef, + kKeepAliveDefaultTimeout, + kHostHeader, + kPendingIdx, + kRunningIdx, + kError, + kPipelining, + kSocket, + kKeepAliveTimeoutValue, + kMaxHeadersSize, + kKeepAliveMaxTimeout, + kKeepAliveTimeoutThreshold, + kHeadersTimeout, + kBodyTimeout, + kStrictContentLength, + kConnector, + kMaxRedirections, + kMaxRequests, + kCounter, + kClose, + kDestroy, + kDispatch, + kInterceptors, + kLocalAddress, + kMaxResponseSize, + kHTTPConnVersion, + // HTTP2 + kHost, + kHTTP2Session, + kHTTP2SessionState, + kHTTP2BuildRequest, + kHTTP2CopyHeaders, + kHTTP1BuildRequest +} = __nccwpck_require__(2785) - const res = h2stream.write(chunk) - request.onBodySent(chunk) - if (!res) { - await waitForDrain() - } - } - } catch (err) { - h2stream.destroy(err) - } finally { - request.onRequestSent() - h2stream.end() - h2stream - .off('close', onDrain) - .off('drain', onDrain) - } +/** @type {import('http2')} */ +let http2 +try { + http2 = __nccwpck_require__(5158) +} catch { + // @ts-ignore + http2 = { constants: {} } +} - return +const { + constants: { + HTTP2_HEADER_AUTHORITY, + HTTP2_HEADER_METHOD, + HTTP2_HEADER_PATH, + HTTP2_HEADER_SCHEME, + HTTP2_HEADER_CONTENT_LENGTH, + HTTP2_HEADER_EXPECT, + HTTP2_HEADER_STATUS } +} = http2 - socket - .on('close', onDrain) - .on('drain', onDrain) - - const writer = new AsyncWriter({ socket, request, contentLength, client, expectsPayload, header }) - try { - // It's up to the user to somehow abort the async iterable. - for await (const chunk of body) { - if (socket[kError]) { - throw socket[kError] - } +// Experimental +let h2ExperimentalWarned = false - if (!writer.write(chunk)) { - await waitForDrain() - } - } +const FastBuffer = Buffer[Symbol.species] - writer.end() - } catch (err) { - writer.destroy(err) - } finally { - socket - .off('close', onDrain) - .off('drain', onDrain) - } -} +const kClosedResolve = Symbol('kClosedResolve') -class AsyncWriter { - constructor ({ socket, request, contentLength, client, expectsPayload, header }) { - this.socket = socket - this.request = request - this.contentLength = contentLength - this.client = client - this.bytesWritten = 0 - this.expectsPayload = expectsPayload - this.header = header +const channels = {} - socket[kWriting] = true - } +try { + const diagnosticsChannel = __nccwpck_require__(7643) + channels.sendHeaders = diagnosticsChannel.channel('undici:client:sendHeaders') + channels.beforeConnect = diagnosticsChannel.channel('undici:client:beforeConnect') + channels.connectError = diagnosticsChannel.channel('undici:client:connectError') + channels.connected = diagnosticsChannel.channel('undici:client:connected') +} catch { + channels.sendHeaders = { hasSubscribers: false } + channels.beforeConnect = { hasSubscribers: false } + channels.connectError = { hasSubscribers: false } + channels.connected = { hasSubscribers: false } +} - write (chunk) { - const { socket, request, contentLength, client, bytesWritten, expectsPayload, header } = this +/** + * @type {import('../types/client').default} + */ +class Client extends DispatcherBase { + /** + * + * @param {string|URL} url + * @param {import('../types/client').Client.Options} options + */ + constructor (url, { + interceptors, + maxHeaderSize, + headersTimeout, + socketTimeout, + requestTimeout, + connectTimeout, + bodyTimeout, + idleTimeout, + keepAlive, + keepAliveTimeout, + maxKeepAliveTimeout, + keepAliveMaxTimeout, + keepAliveTimeoutThreshold, + socketPath, + pipelining, + tls, + strictContentLength, + maxCachedSessions, + maxRedirections, + connect, + maxRequestsPerClient, + localAddress, + maxResponseSize, + autoSelectFamily, + autoSelectFamilyAttemptTimeout, + // h2 + allowH2, + maxConcurrentStreams + } = {}) { + super() - if (socket[kError]) { - throw socket[kError] + if (keepAlive !== undefined) { + throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead') } - if (socket.destroyed) { - return false + if (socketTimeout !== undefined) { + throw new InvalidArgumentError('unsupported socketTimeout, use headersTimeout & bodyTimeout instead') } - const len = Buffer.byteLength(chunk) - if (!len) { - return true + if (requestTimeout !== undefined) { + throw new InvalidArgumentError('unsupported requestTimeout, use headersTimeout & bodyTimeout instead') } - // We should defer writing chunks. - if (contentLength !== null && bytesWritten + len > contentLength) { - if (client[kStrictContentLength]) { - throw new RequestContentLengthMismatchError() - } + if (idleTimeout !== undefined) { + throw new InvalidArgumentError('unsupported idleTimeout, use keepAliveTimeout instead') + } - process.emitWarning(new RequestContentLengthMismatchError()) + if (maxKeepAliveTimeout !== undefined) { + throw new InvalidArgumentError('unsupported maxKeepAliveTimeout, use keepAliveMaxTimeout instead') } - socket.cork() + if (maxHeaderSize != null && !Number.isFinite(maxHeaderSize)) { + throw new InvalidArgumentError('invalid maxHeaderSize') + } - if (bytesWritten === 0) { - if (!expectsPayload) { - socket[kReset] = true - } + if (socketPath != null && typeof socketPath !== 'string') { + throw new InvalidArgumentError('invalid socketPath') + } - if (contentLength === null) { - socket.write(`${header}transfer-encoding: chunked\r\n`, 'latin1') - } else { - socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') - } + if (connectTimeout != null && (!Number.isFinite(connectTimeout) || connectTimeout < 0)) { + throw new InvalidArgumentError('invalid connectTimeout') } - if (contentLength === null) { - socket.write(`\r\n${len.toString(16)}\r\n`, 'latin1') + if (keepAliveTimeout != null && (!Number.isFinite(keepAliveTimeout) || keepAliveTimeout <= 0)) { + throw new InvalidArgumentError('invalid keepAliveTimeout') } - this.bytesWritten += len - - const ret = socket.write(chunk) + if (keepAliveMaxTimeout != null && (!Number.isFinite(keepAliveMaxTimeout) || keepAliveMaxTimeout <= 0)) { + throw new InvalidArgumentError('invalid keepAliveMaxTimeout') + } - socket.uncork() + if (keepAliveTimeoutThreshold != null && !Number.isFinite(keepAliveTimeoutThreshold)) { + throw new InvalidArgumentError('invalid keepAliveTimeoutThreshold') + } - request.onBodySent(chunk) + if (headersTimeout != null && (!Number.isInteger(headersTimeout) || headersTimeout < 0)) { + throw new InvalidArgumentError('headersTimeout must be a positive integer or zero') + } - if (!ret) { - if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { - // istanbul ignore else: only for jest - if (socket[kParser].timeout.refresh) { - socket[kParser].timeout.refresh() - } - } + if (bodyTimeout != null && (!Number.isInteger(bodyTimeout) || bodyTimeout < 0)) { + throw new InvalidArgumentError('bodyTimeout must be a positive integer or zero') } - return ret - } + if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { + throw new InvalidArgumentError('connect must be a function or an object') + } - end () { - const { socket, contentLength, client, bytesWritten, expectsPayload, header, request } = this - request.onRequestSent() + if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { + throw new InvalidArgumentError('maxRedirections must be a positive number') + } - socket[kWriting] = false + if (maxRequestsPerClient != null && (!Number.isInteger(maxRequestsPerClient) || maxRequestsPerClient < 0)) { + throw new InvalidArgumentError('maxRequestsPerClient must be a positive number') + } - if (socket[kError]) { - throw socket[kError] + if (localAddress != null && (typeof localAddress !== 'string' || net.isIP(localAddress) === 0)) { + throw new InvalidArgumentError('localAddress must be valid string IP address') } - if (socket.destroyed) { - return + if (maxResponseSize != null && (!Number.isInteger(maxResponseSize) || maxResponseSize < -1)) { + throw new InvalidArgumentError('maxResponseSize must be a positive number') } - if (bytesWritten === 0) { - if (expectsPayload) { - // https://tools.ietf.org/html/rfc7230#section-3.3.2 - // A user agent SHOULD send a Content-Length in a request message when - // no Transfer-Encoding is sent and the request method defines a meaning - // for an enclosed payload body. + if ( + autoSelectFamilyAttemptTimeout != null && + (!Number.isInteger(autoSelectFamilyAttemptTimeout) || autoSelectFamilyAttemptTimeout < -1) + ) { + throw new InvalidArgumentError('autoSelectFamilyAttemptTimeout must be a positive number') + } - socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1') - } else { - socket.write(`${header}\r\n`, 'latin1') - } - } else if (contentLength === null) { - socket.write('\r\n0\r\n\r\n', 'latin1') + // h2 + if (allowH2 != null && typeof allowH2 !== 'boolean') { + throw new InvalidArgumentError('allowH2 must be a valid boolean value') } - if (contentLength !== null && bytesWritten !== contentLength) { - if (client[kStrictContentLength]) { - throw new RequestContentLengthMismatchError() - } else { - process.emitWarning(new RequestContentLengthMismatchError()) - } + if (maxConcurrentStreams != null && (typeof maxConcurrentStreams !== 'number' || maxConcurrentStreams < 1)) { + throw new InvalidArgumentError('maxConcurrentStreams must be a possitive integer, greater than 0') } - if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { - // istanbul ignore else: only for jest - if (socket[kParser].timeout.refresh) { - socket[kParser].timeout.refresh() - } + if (typeof connect !== 'function') { + connect = buildConnector({ + ...tls, + maxCachedSessions, + allowH2, + socketPath, + timeout: connectTimeout, + ...(util.nodeHasAutoSelectFamily && autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), + ...connect + }) } - resume(client) - } + this[kInterceptors] = interceptors && interceptors.Client && Array.isArray(interceptors.Client) + ? interceptors.Client + : [createRedirectInterceptor({ maxRedirections })] + this[kUrl] = util.parseOrigin(url) + this[kConnector] = connect + this[kSocket] = null + this[kPipelining] = pipelining != null ? pipelining : 1 + this[kMaxHeadersSize] = maxHeaderSize || http.maxHeaderSize + this[kKeepAliveDefaultTimeout] = keepAliveTimeout == null ? 4e3 : keepAliveTimeout + this[kKeepAliveMaxTimeout] = keepAliveMaxTimeout == null ? 600e3 : keepAliveMaxTimeout + this[kKeepAliveTimeoutThreshold] = keepAliveTimeoutThreshold == null ? 1e3 : keepAliveTimeoutThreshold + this[kKeepAliveTimeoutValue] = this[kKeepAliveDefaultTimeout] + this[kServerName] = null + this[kLocalAddress] = localAddress != null ? localAddress : null + this[kResuming] = 0 // 0, idle, 1, scheduled, 2 resuming + this[kNeedDrain] = 0 // 0, idle, 1, scheduled, 2 resuming + this[kHostHeader] = `host: ${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}\r\n` + this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 300e3 + this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 300e3 + this[kStrictContentLength] = strictContentLength == null ? true : strictContentLength + this[kMaxRedirections] = maxRedirections + this[kMaxRequests] = maxRequestsPerClient + this[kClosedResolve] = null + this[kMaxResponseSize] = maxResponseSize > -1 ? maxResponseSize : -1 + this[kHTTPConnVersion] = 'h1' - destroy (err) { - const { socket, client } = this + // HTTP/2 + this[kHTTP2Session] = null + this[kHTTP2SessionState] = !allowH2 + ? null + : { + // streams: null, // Fixed queue of streams - For future support of `push` + openStreams: 0, // Keep track of them to decide wether or not unref the session + maxConcurrentStreams: maxConcurrentStreams != null ? maxConcurrentStreams : 100 // Max peerConcurrentStreams for a Node h2 server + } + this[kHost] = `${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}` - socket[kWriting] = false + // kQueue is built up of 3 sections separated by + // the kRunningIdx and kPendingIdx indices. + // | complete | running | pending | + // ^ kRunningIdx ^ kPendingIdx ^ kQueue.length + // kRunningIdx points to the first running element. + // kPendingIdx points to the first pending element. + // This implements a fast queue with an amortized + // time of O(1). - if (err) { - assert(client[kRunning] <= 1, 'pipeline should only contain this request') - util.destroy(socket, err) - } + this[kQueue] = [] + this[kRunningIdx] = 0 + this[kPendingIdx] = 0 } -} -function errorRequest (client, request, err) { - try { - request.onError(err) - assert(request.aborted) - } catch (err) { - client.emit('error', err) + get pipelining () { + return this[kPipelining] } -} - -module.exports = Client - - -/***/ }), -/***/ 6436: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - - -/* istanbul ignore file: only for Node 12 */ - -const { kConnected, kSize } = __nccwpck_require__(2785) - -class CompatWeakRef { - constructor (value) { - this.value = value + set pipelining (value) { + this[kPipelining] = value + resume(this, true) } - deref () { - return this.value[kConnected] === 0 && this.value[kSize] === 0 - ? undefined - : this.value + get [kPending] () { + return this[kQueue].length - this[kPendingIdx] } -} -class CompatFinalizer { - constructor (finalizer) { - this.finalizer = finalizer + get [kRunning] () { + return this[kPendingIdx] - this[kRunningIdx] } - register (dispatcher, key) { - if (dispatcher.on) { - dispatcher.on('disconnect', () => { - if (dispatcher[kConnected] === 0 && dispatcher[kSize] === 0) { - this.finalizer(key) - } - }) - } + get [kSize] () { + return this[kQueue].length - this[kRunningIdx] } -} -module.exports = function () { - // FIXME: remove workaround when the Node bug is fixed - // https://github.com/nodejs/node/issues/49344#issuecomment-1741776308 - if (process.env.NODE_V8_COVERAGE) { - return { - WeakRef: CompatWeakRef, - FinalizationRegistry: CompatFinalizer - } - } - return { - WeakRef: global.WeakRef || CompatWeakRef, - FinalizationRegistry: global.FinalizationRegistry || CompatFinalizer + get [kConnected] () { + return !!this[kSocket] && !this[kConnecting] && !this[kSocket].destroyed } -} + get [kBusy] () { + const socket = this[kSocket] + return ( + (socket && (socket[kReset] || socket[kWriting] || socket[kBlocking])) || + (this[kSize] >= (this[kPipelining] || 1)) || + this[kPending] > 0 + ) + } -/***/ }), + /* istanbul ignore: only used for test */ + [kConnect] (cb) { + connect(this) + this.once('connect', cb) + } -/***/ 663: -/***/ ((module) => { + [kDispatch] (opts, handler) { + const origin = opts.origin || this[kUrl].origin -"use strict"; + const request = this[kHTTPConnVersion] === 'h2' + ? Request[kHTTP2BuildRequest](origin, opts, handler) + : Request[kHTTP1BuildRequest](origin, opts, handler) + this[kQueue].push(request) + if (this[kResuming]) { + // Do nothing. + } else if (util.bodyLength(request.body) == null && util.isIterable(request.body)) { + // Wait a tick in case stream/iterator is ended in the same tick. + this[kResuming] = 1 + process.nextTick(resume, this) + } else { + resume(this, true) + } -// https://wicg.github.io/cookie-store/#cookie-maximum-attribute-value-size -const maxAttributeValueSize = 1024 + if (this[kResuming] && this[kNeedDrain] !== 2 && this[kBusy]) { + this[kNeedDrain] = 2 + } -// https://wicg.github.io/cookie-store/#cookie-maximum-name-value-pair-size -const maxNameValuePairSize = 4096 - -module.exports = { - maxAttributeValueSize, - maxNameValuePairSize -} + return this[kNeedDrain] < 2 + } + async [kClose] () { + // TODO: for H2 we need to gracefully flush the remaining enqueued + // request and close each stream. + return new Promise((resolve) => { + if (!this[kSize]) { + resolve(null) + } else { + this[kClosedResolve] = resolve + } + }) + } -/***/ }), + async [kDestroy] (err) { + return new Promise((resolve) => { + const requests = this[kQueue].splice(this[kPendingIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + errorRequest(this, request, err) + } -/***/ 1724: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const callback = () => { + if (this[kClosedResolve]) { + // TODO (fix): Should we error here with ClientDestroyedError? + this[kClosedResolve]() + this[kClosedResolve] = null + } + resolve() + } -"use strict"; + if (this[kHTTP2Session] != null) { + util.destroy(this[kHTTP2Session], err) + this[kHTTP2Session] = null + this[kHTTP2SessionState] = null + } + if (!this[kSocket]) { + queueMicrotask(callback) + } else { + util.destroy(this[kSocket].on('close', callback), err) + } -const { parseSetCookie } = __nccwpck_require__(4408) -const { stringify, getHeadersList } = __nccwpck_require__(3121) -const { webidl } = __nccwpck_require__(1744) -const { Headers } = __nccwpck_require__(554) + resume(this) + }) + } +} -/** - * @typedef {Object} Cookie - * @property {string} name - * @property {string} value - * @property {Date|number|undefined} expires - * @property {number|undefined} maxAge - * @property {string|undefined} domain - * @property {string|undefined} path - * @property {boolean|undefined} secure - * @property {boolean|undefined} httpOnly - * @property {'Strict'|'Lax'|'None'} sameSite - * @property {string[]} unparsed - */ +function onHttp2SessionError (err) { + assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') -/** - * @param {Headers} headers - * @returns {Record} - */ -function getCookies (headers) { - webidl.argumentLengthCheck(arguments, 1, { header: 'getCookies' }) + this[kSocket][kError] = err - webidl.brandCheck(headers, Headers, { strict: false }) + onError(this[kClient], err) +} - const cookie = headers.get('cookie') - const out = {} +function onHttp2FrameError (type, code, id) { + const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`) - if (!cookie) { - return out + if (id === 0) { + this[kSocket][kError] = err + onError(this[kClient], err) } +} - for (const piece of cookie.split(';')) { - const [name, ...value] = piece.split('=') +function onHttp2SessionEnd () { + util.destroy(this, new SocketError('other side closed')) + util.destroy(this[kSocket], new SocketError('other side closed')) +} - out[name.trim()] = value.join('=') - } +function onHTTP2GoAway (code) { + const client = this[kClient] + const err = new InformationalError(`HTTP/2: "GOAWAY" frame received with code ${code}`) + client[kSocket] = null + client[kHTTP2Session] = null - return out -} + if (client.destroyed) { + assert(this[kPending] === 0) -/** - * @param {Headers} headers - * @param {string} name - * @param {{ path?: string, domain?: string }|undefined} attributes - * @returns {void} - */ -function deleteCookie (headers, name, attributes) { - webidl.argumentLengthCheck(arguments, 2, { header: 'deleteCookie' }) + // Fail entire queue. + const requests = client[kQueue].splice(client[kRunningIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + errorRequest(this, request, err) + } + } else if (client[kRunning] > 0) { + // Fail head of pipeline. + const request = client[kQueue][client[kRunningIdx]] + client[kQueue][client[kRunningIdx]++] = null - webidl.brandCheck(headers, Headers, { strict: false }) + errorRequest(client, request, err) + } - name = webidl.converters.DOMString(name) - attributes = webidl.converters.DeleteCookieAttributes(attributes) + client[kPendingIdx] = client[kRunningIdx] - // Matches behavior of - // https://github.com/denoland/deno_std/blob/63827b16330b82489a04614027c33b7904e08be5/http/cookie.ts#L278 - setCookie(headers, { - name, - value: '', - expires: new Date(0), - ...attributes - }) + assert(client[kRunning] === 0) + + client.emit('disconnect', + client[kUrl], + [client], + err + ) + + resume(client) } -/** - * @param {Headers} headers - * @returns {Cookie[]} - */ -function getSetCookies (headers) { - webidl.argumentLengthCheck(arguments, 1, { header: 'getSetCookies' }) +const constants = __nccwpck_require__(953) +const createRedirectInterceptor = __nccwpck_require__(8861) +const EMPTY_BUF = Buffer.alloc(0) - webidl.brandCheck(headers, Headers, { strict: false }) +async function lazyllhttp () { + const llhttpWasmData = process.env.JEST_WORKER_ID ? __nccwpck_require__(1145) : undefined - const cookies = getHeadersList(headers).cookies + let mod + try { + mod = await WebAssembly.compile(Buffer.from(__nccwpck_require__(5627), 'base64')) + } catch (e) { + /* istanbul ignore next */ - if (!cookies) { - return [] + // We could check if the error was caused by the simd option not + // being enabled, but the occurring of this other error + // * https://github.com/emscripten-core/emscripten/issues/11495 + // got me to remove that check to avoid breaking Node 12. + mod = await WebAssembly.compile(Buffer.from(llhttpWasmData || __nccwpck_require__(1145), 'base64')) } - // In older versions of undici, cookies is a list of name:value. - return cookies.map((pair) => parseSetCookie(Array.isArray(pair) ? pair[1] : pair)) -} + return await WebAssembly.instantiate(mod, { + env: { + /* eslint-disable camelcase */ -/** - * @param {Headers} headers - * @param {Cookie} cookie - * @returns {void} - */ -function setCookie (headers, cookie) { - webidl.argumentLengthCheck(arguments, 2, { header: 'setCookie' }) + wasm_on_url: (p, at, len) => { + /* istanbul ignore next */ + return 0 + }, + wasm_on_status: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return currentParser.onStatus(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 + }, + wasm_on_message_begin: (p) => { + assert.strictEqual(currentParser.ptr, p) + return currentParser.onMessageBegin() || 0 + }, + wasm_on_header_field: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return currentParser.onHeaderField(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 + }, + wasm_on_header_value: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return currentParser.onHeaderValue(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 + }, + wasm_on_headers_complete: (p, statusCode, upgrade, shouldKeepAlive) => { + assert.strictEqual(currentParser.ptr, p) + return currentParser.onHeadersComplete(statusCode, Boolean(upgrade), Boolean(shouldKeepAlive)) || 0 + }, + wasm_on_body: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return currentParser.onBody(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 + }, + wasm_on_message_complete: (p) => { + assert.strictEqual(currentParser.ptr, p) + return currentParser.onMessageComplete() || 0 + } - webidl.brandCheck(headers, Headers, { strict: false }) + /* eslint-enable camelcase */ + } + }) +} - cookie = webidl.converters.Cookie(cookie) +let llhttpInstance = null +let llhttpPromise = lazyllhttp() +llhttpPromise.catch() - const str = stringify(cookie) +let currentParser = null +let currentBufferRef = null +let currentBufferSize = 0 +let currentBufferPtr = null - if (str) { - headers.append('Set-Cookie', stringify(cookie)) - } -} +const TIMEOUT_HEADERS = 1 +const TIMEOUT_BODY = 2 +const TIMEOUT_IDLE = 3 -webidl.converters.DeleteCookieAttributes = webidl.dictionaryConverter([ - { - converter: webidl.nullableConverter(webidl.converters.DOMString), - key: 'path', - defaultValue: null - }, - { - converter: webidl.nullableConverter(webidl.converters.DOMString), - key: 'domain', - defaultValue: null - } -]) +class Parser { + constructor (client, socket, { exports }) { + assert(Number.isFinite(client[kMaxHeadersSize]) && client[kMaxHeadersSize] > 0) -webidl.converters.Cookie = webidl.dictionaryConverter([ - { - converter: webidl.converters.DOMString, - key: 'name' - }, - { - converter: webidl.converters.DOMString, - key: 'value' - }, - { - converter: webidl.nullableConverter((value) => { - if (typeof value === 'number') { - return webidl.converters['unsigned long long'](value) - } + this.llhttp = exports + this.ptr = this.llhttp.llhttp_alloc(constants.TYPE.RESPONSE) + this.client = client + this.socket = socket + this.timeout = null + this.timeoutValue = null + this.timeoutType = null + this.statusCode = null + this.statusText = '' + this.upgrade = false + this.headers = [] + this.headersSize = 0 + this.headersMaxSize = client[kMaxHeadersSize] + this.shouldKeepAlive = false + this.paused = false + this.resume = this.resume.bind(this) - return new Date(value) - }), - key: 'expires', - defaultValue: null - }, - { - converter: webidl.nullableConverter(webidl.converters['long long']), - key: 'maxAge', - defaultValue: null - }, - { - converter: webidl.nullableConverter(webidl.converters.DOMString), - key: 'domain', - defaultValue: null - }, - { - converter: webidl.nullableConverter(webidl.converters.DOMString), - key: 'path', - defaultValue: null - }, - { - converter: webidl.nullableConverter(webidl.converters.boolean), - key: 'secure', - defaultValue: null - }, - { - converter: webidl.nullableConverter(webidl.converters.boolean), - key: 'httpOnly', - defaultValue: null - }, - { - converter: webidl.converters.USVString, - key: 'sameSite', - allowedValues: ['Strict', 'Lax', 'None'] - }, - { - converter: webidl.sequenceConverter(webidl.converters.DOMString), - key: 'unparsed', - defaultValue: [] - } -]) + this.bytesRead = 0 -module.exports = { - getCookies, - deleteCookie, - getSetCookies, - setCookie -} + this.keepAlive = '' + this.contentLength = '' + this.connection = '' + this.maxResponseSize = client[kMaxResponseSize] + } + setTimeout (value, type) { + this.timeoutType = type + if (value !== this.timeoutValue) { + timers.clearTimeout(this.timeout) + if (value) { + this.timeout = timers.setTimeout(onParserTimeout, value, this) + // istanbul ignore else: only for jest + if (this.timeout.unref) { + this.timeout.unref() + } + } else { + this.timeout = null + } + this.timeoutValue = value + } else if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh() + } + } + } -/***/ }), + resume () { + if (this.socket.destroyed || !this.paused) { + return + } -/***/ 4408: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + assert(this.ptr != null) + assert(currentParser == null) -"use strict"; + this.llhttp.llhttp_resume(this.ptr) + assert(this.timeoutType === TIMEOUT_BODY) + if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh() + } + } -const { maxNameValuePairSize, maxAttributeValueSize } = __nccwpck_require__(663) -const { isCTLExcludingHtab } = __nccwpck_require__(3121) -const { collectASequenceOfCodePointsFast } = __nccwpck_require__(685) -const assert = __nccwpck_require__(9491) + this.paused = false + this.execute(this.socket.read() || EMPTY_BUF) // Flush parser. + this.readMore() + } -/** - * @description Parses the field-value attributes of a set-cookie header string. - * @see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4 - * @param {string} header - * @returns if the header is invalid, null will be returned - */ -function parseSetCookie (header) { - // 1. If the set-cookie-string contains a %x00-08 / %x0A-1F / %x7F - // character (CTL characters excluding HTAB): Abort these steps and - // ignore the set-cookie-string entirely. - if (isCTLExcludingHtab(header)) { - return null + readMore () { + while (!this.paused && this.ptr) { + const chunk = this.socket.read() + if (chunk === null) { + break + } + this.execute(chunk) + } } - let nameValuePair = '' - let unparsedAttributes = '' - let name = '' - let value = '' + execute (data) { + assert(this.ptr != null) + assert(currentParser == null) + assert(!this.paused) - // 2. If the set-cookie-string contains a %x3B (";") character: - if (header.includes(';')) { - // 1. The name-value-pair string consists of the characters up to, - // but not including, the first %x3B (";"), and the unparsed- - // attributes consist of the remainder of the set-cookie-string - // (including the %x3B (";") in question). - const position = { position: 0 } + const { socket, llhttp } = this - nameValuePair = collectASequenceOfCodePointsFast(';', header, position) - unparsedAttributes = header.slice(position.position) - } else { - // Otherwise: + if (data.length > currentBufferSize) { + if (currentBufferPtr) { + llhttp.free(currentBufferPtr) + } + currentBufferSize = Math.ceil(data.length / 4096) * 4096 + currentBufferPtr = llhttp.malloc(currentBufferSize) + } - // 1. The name-value-pair string consists of all the characters - // contained in the set-cookie-string, and the unparsed- - // attributes is the empty string. - nameValuePair = header - } + new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize).set(data) - // 3. If the name-value-pair string lacks a %x3D ("=") character, then - // the name string is empty, and the value string is the value of - // name-value-pair. - if (!nameValuePair.includes('=')) { - value = nameValuePair - } else { - // Otherwise, the name string consists of the characters up to, but - // not including, the first %x3D ("=") character, and the (possibly - // empty) value string consists of the characters after the first - // %x3D ("=") character. - const position = { position: 0 } - name = collectASequenceOfCodePointsFast( - '=', - nameValuePair, - position - ) - value = nameValuePair.slice(position.position + 1) - } + // Call `execute` on the wasm parser. + // We pass the `llhttp_parser` pointer address, the pointer address of buffer view data, + // and finally the length of bytes to parse. + // The return value is an error code or `constants.ERROR.OK`. + try { + let ret - // 4. Remove any leading or trailing WSP characters from the name - // string and the value string. - name = name.trim() - value = value.trim() + try { + currentBufferRef = data + currentParser = this + ret = llhttp.llhttp_execute(this.ptr, currentBufferPtr, data.length) + /* eslint-disable-next-line no-useless-catch */ + } catch (err) { + /* istanbul ignore next: difficult to make a test case for */ + throw err + } finally { + currentParser = null + currentBufferRef = null + } - // 5. If the sum of the lengths of the name string and the value string - // is more than 4096 octets, abort these steps and ignore the set- - // cookie-string entirely. - if (name.length + value.length > maxNameValuePairSize) { - return null - } + const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr - // 6. The cookie-name is the name string, and the cookie-value is the - // value string. - return { - name, value, ...parseUnparsedAttributes(unparsedAttributes) + if (ret === constants.ERROR.PAUSED_UPGRADE) { + this.onUpgrade(data.slice(offset)) + } else if (ret === constants.ERROR.PAUSED) { + this.paused = true + socket.unshift(data.slice(offset)) + } else if (ret !== constants.ERROR.OK) { + const ptr = llhttp.llhttp_get_error_reason(this.ptr) + let message = '' + /* istanbul ignore else: difficult to make a test case for */ + if (ptr) { + const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0) + message = + 'Response does not match the HTTP/1.1 protocol (' + + Buffer.from(llhttp.memory.buffer, ptr, len).toString() + + ')' + } + throw new HTTPParserError(message, constants.ERROR[ret], data.slice(offset)) + } + } catch (err) { + util.destroy(socket, err) + } } -} -/** - * Parses the remaining attributes of a set-cookie header - * @see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4 - * @param {string} unparsedAttributes - * @param {[Object.]={}} cookieAttributeList - */ -function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {}) { - // 1. If the unparsed-attributes string is empty, skip the rest of - // these steps. - if (unparsedAttributes.length === 0) { - return cookieAttributeList - } + destroy () { + assert(this.ptr != null) + assert(currentParser == null) - // 2. Discard the first character of the unparsed-attributes (which - // will be a %x3B (";") character). - assert(unparsedAttributes[0] === ';') - unparsedAttributes = unparsedAttributes.slice(1) + this.llhttp.llhttp_free(this.ptr) + this.ptr = null - let cookieAv = '' + timers.clearTimeout(this.timeout) + this.timeout = null + this.timeoutValue = null + this.timeoutType = null - // 3. If the remaining unparsed-attributes contains a %x3B (";") - // character: - if (unparsedAttributes.includes(';')) { - // 1. Consume the characters of the unparsed-attributes up to, but - // not including, the first %x3B (";") character. - cookieAv = collectASequenceOfCodePointsFast( - ';', - unparsedAttributes, - { position: 0 } - ) - unparsedAttributes = unparsedAttributes.slice(cookieAv.length) - } else { - // Otherwise: + this.paused = false + } - // 1. Consume the remainder of the unparsed-attributes. - cookieAv = unparsedAttributes - unparsedAttributes = '' + onStatus (buf) { + this.statusText = buf.toString() } - // Let the cookie-av string be the characters consumed in this step. + onMessageBegin () { + const { socket, client } = this - let attributeName = '' - let attributeValue = '' + /* istanbul ignore next: difficult to make a test case for */ + if (socket.destroyed) { + return -1 + } - // 4. If the cookie-av string contains a %x3D ("=") character: - if (cookieAv.includes('=')) { - // 1. The (possibly empty) attribute-name string consists of the - // characters up to, but not including, the first %x3D ("=") - // character, and the (possibly empty) attribute-value string - // consists of the characters after the first %x3D ("=") - // character. - const position = { position: 0 } + const request = client[kQueue][client[kRunningIdx]] + if (!request) { + return -1 + } + } - attributeName = collectASequenceOfCodePointsFast( - '=', - cookieAv, - position - ) - attributeValue = cookieAv.slice(position.position + 1) - } else { - // Otherwise: + onHeaderField (buf) { + const len = this.headers.length - // 1. The attribute-name string consists of the entire cookie-av - // string, and the attribute-value string is empty. - attributeName = cookieAv + if ((len & 1) === 0) { + this.headers.push(buf) + } else { + this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]) + } + + this.trackHeader(buf.length) } - // 5. Remove any leading or trailing WSP characters from the attribute- - // name string and the attribute-value string. - attributeName = attributeName.trim() - attributeValue = attributeValue.trim() + onHeaderValue (buf) { + let len = this.headers.length - // 6. If the attribute-value is longer than 1024 octets, ignore the - // cookie-av string and return to Step 1 of this algorithm. - if (attributeValue.length > maxAttributeValueSize) { - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) - } + if ((len & 1) === 1) { + this.headers.push(buf) + len += 1 + } else { + this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]) + } - // 7. Process the attribute-name and attribute-value according to the - // requirements in the following subsections. (Notice that - // attributes with unrecognized attribute-names are ignored.) - const attributeNameLowercase = attributeName.toLowerCase() + const key = this.headers[len - 2] + if (key.length === 10 && key.toString().toLowerCase() === 'keep-alive') { + this.keepAlive += buf.toString() + } else if (key.length === 10 && key.toString().toLowerCase() === 'connection') { + this.connection += buf.toString() + } else if (key.length === 14 && key.toString().toLowerCase() === 'content-length') { + this.contentLength += buf.toString() + } - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.1 - // If the attribute-name case-insensitively matches the string - // "Expires", the user agent MUST process the cookie-av as follows. - if (attributeNameLowercase === 'expires') { - // 1. Let the expiry-time be the result of parsing the attribute-value - // as cookie-date (see Section 5.1.1). - const expiryTime = new Date(attributeValue) + this.trackHeader(buf.length) + } - // 2. If the attribute-value failed to parse as a cookie date, ignore - // the cookie-av. + trackHeader (len) { + this.headersSize += len + if (this.headersSize >= this.headersMaxSize) { + util.destroy(this.socket, new HeadersOverflowError()) + } + } - cookieAttributeList.expires = expiryTime - } else if (attributeNameLowercase === 'max-age') { - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.2 - // If the attribute-name case-insensitively matches the string "Max- - // Age", the user agent MUST process the cookie-av as follows. + onUpgrade (head) { + const { upgrade, client, socket, headers, statusCode } = this - // 1. If the first character of the attribute-value is not a DIGIT or a - // "-" character, ignore the cookie-av. - const charCode = attributeValue.charCodeAt(0) + assert(upgrade) - if ((charCode < 48 || charCode > 57) && attributeValue[0] !== '-') { - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) - } + const request = client[kQueue][client[kRunningIdx]] + assert(request) - // 2. If the remainder of attribute-value contains a non-DIGIT - // character, ignore the cookie-av. - if (!/^\d+$/.test(attributeValue)) { - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) - } + assert(!socket.destroyed) + assert(socket === client[kSocket]) + assert(!this.paused) + assert(request.upgrade || request.method === 'CONNECT') - // 3. Let delta-seconds be the attribute-value converted to an integer. - const deltaSeconds = Number(attributeValue) + this.statusCode = null + this.statusText = '' + this.shouldKeepAlive = null - // 4. Let cookie-age-limit be the maximum age of the cookie (which - // SHOULD be 400 days or less, see Section 4.1.2.2). + assert(this.headers.length % 2 === 0) + this.headers = [] + this.headersSize = 0 - // 5. Set delta-seconds to the smaller of its present value and cookie- - // age-limit. - // deltaSeconds = Math.min(deltaSeconds * 1000, maxExpiresMs) + socket.unshift(head) - // 6. If delta-seconds is less than or equal to zero (0), let expiry- - // time be the earliest representable date and time. Otherwise, let - // the expiry-time be the current date and time plus delta-seconds - // seconds. - // const expiryTime = deltaSeconds <= 0 ? Date.now() : Date.now() + deltaSeconds + socket[kParser].destroy() + socket[kParser] = null - // 7. Append an attribute to the cookie-attribute-list with an - // attribute-name of Max-Age and an attribute-value of expiry-time. - cookieAttributeList.maxAge = deltaSeconds - } else if (attributeNameLowercase === 'domain') { - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.3 - // If the attribute-name case-insensitively matches the string "Domain", - // the user agent MUST process the cookie-av as follows. + socket[kClient] = null + socket[kError] = null + socket + .removeListener('error', onSocketError) + .removeListener('readable', onSocketReadable) + .removeListener('end', onSocketEnd) + .removeListener('close', onSocketClose) - // 1. Let cookie-domain be the attribute-value. - let cookieDomain = attributeValue + client[kSocket] = null + client[kQueue][client[kRunningIdx]++] = null + client.emit('disconnect', client[kUrl], [client], new InformationalError('upgrade')) - // 2. If cookie-domain starts with %x2E ("."), let cookie-domain be - // cookie-domain without its leading %x2E ("."). - if (cookieDomain[0] === '.') { - cookieDomain = cookieDomain.slice(1) + try { + request.onUpgrade(statusCode, headers, socket) + } catch (err) { + util.destroy(socket, err) } - // 3. Convert the cookie-domain to lower case. - cookieDomain = cookieDomain.toLowerCase() - - // 4. Append an attribute to the cookie-attribute-list with an - // attribute-name of Domain and an attribute-value of cookie-domain. - cookieAttributeList.domain = cookieDomain - } else if (attributeNameLowercase === 'path') { - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.4 - // If the attribute-name case-insensitively matches the string "Path", - // the user agent MUST process the cookie-av as follows. + resume(client) + } - // 1. If the attribute-value is empty or if the first character of the - // attribute-value is not %x2F ("/"): - let cookiePath = '' - if (attributeValue.length === 0 || attributeValue[0] !== '/') { - // 1. Let cookie-path be the default-path. - cookiePath = '/' - } else { - // Otherwise: + onHeadersComplete (statusCode, upgrade, shouldKeepAlive) { + const { client, socket, headers, statusText } = this - // 1. Let cookie-path be the attribute-value. - cookiePath = attributeValue + /* istanbul ignore next: difficult to make a test case for */ + if (socket.destroyed) { + return -1 } - // 2. Append an attribute to the cookie-attribute-list with an - // attribute-name of Path and an attribute-value of cookie-path. - cookieAttributeList.path = cookiePath - } else if (attributeNameLowercase === 'secure') { - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.5 - // If the attribute-name case-insensitively matches the string "Secure", - // the user agent MUST append an attribute to the cookie-attribute-list - // with an attribute-name of Secure and an empty attribute-value. + const request = client[kQueue][client[kRunningIdx]] - cookieAttributeList.secure = true - } else if (attributeNameLowercase === 'httponly') { - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.6 - // If the attribute-name case-insensitively matches the string - // "HttpOnly", the user agent MUST append an attribute to the cookie- - // attribute-list with an attribute-name of HttpOnly and an empty - // attribute-value. + /* istanbul ignore next: difficult to make a test case for */ + if (!request) { + return -1 + } - cookieAttributeList.httpOnly = true - } else if (attributeNameLowercase === 'samesite') { - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.7 - // If the attribute-name case-insensitively matches the string - // "SameSite", the user agent MUST process the cookie-av as follows: - - // 1. Let enforcement be "Default". - let enforcement = 'Default' + assert(!this.upgrade) + assert(this.statusCode < 200) - const attributeValueLowercase = attributeValue.toLowerCase() - // 2. If cookie-av's attribute-value is a case-insensitive match for - // "None", set enforcement to "None". - if (attributeValueLowercase.includes('none')) { - enforcement = 'None' + if (statusCode === 100) { + util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket))) + return -1 } - // 3. If cookie-av's attribute-value is a case-insensitive match for - // "Strict", set enforcement to "Strict". - if (attributeValueLowercase.includes('strict')) { - enforcement = 'Strict' + /* this can only happen if server is misbehaving */ + if (upgrade && !request.upgrade) { + util.destroy(socket, new SocketError('bad upgrade', util.getSocketInfo(socket))) + return -1 } - // 4. If cookie-av's attribute-value is a case-insensitive match for - // "Lax", set enforcement to "Lax". - if (attributeValueLowercase.includes('lax')) { - enforcement = 'Lax' + assert.strictEqual(this.timeoutType, TIMEOUT_HEADERS) + + this.statusCode = statusCode + this.shouldKeepAlive = ( + shouldKeepAlive || + // Override llhttp value which does not allow keepAlive for HEAD. + (request.method === 'HEAD' && !socket[kReset] && this.connection.toLowerCase() === 'keep-alive') + ) + + if (this.statusCode >= 200) { + const bodyTimeout = request.bodyTimeout != null + ? request.bodyTimeout + : client[kBodyTimeout] + this.setTimeout(bodyTimeout, TIMEOUT_BODY) + } else if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh() + } } - // 5. Append an attribute to the cookie-attribute-list with an - // attribute-name of "SameSite" and an attribute-value of - // enforcement. - cookieAttributeList.sameSite = enforcement - } else { - cookieAttributeList.unparsed ??= [] + if (request.method === 'CONNECT') { + assert(client[kRunning] === 1) + this.upgrade = true + return 2 + } - cookieAttributeList.unparsed.push(`${attributeName}=${attributeValue}`) - } + if (upgrade) { + assert(client[kRunning] === 1) + this.upgrade = true + return 2 + } - // 8. Return to Step 1 of this algorithm. - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) -} + assert(this.headers.length % 2 === 0) + this.headers = [] + this.headersSize = 0 -module.exports = { - parseSetCookie, - parseUnparsedAttributes -} + if (this.shouldKeepAlive && client[kPipelining]) { + const keepAliveTimeout = this.keepAlive ? util.parseKeepAliveTimeout(this.keepAlive) : null + if (keepAliveTimeout != null) { + const timeout = Math.min( + keepAliveTimeout - client[kKeepAliveTimeoutThreshold], + client[kKeepAliveMaxTimeout] + ) + if (timeout <= 0) { + socket[kReset] = true + } else { + client[kKeepAliveTimeoutValue] = timeout + } + } else { + client[kKeepAliveTimeoutValue] = client[kKeepAliveDefaultTimeout] + } + } else { + // Stop more requests from being dispatched. + socket[kReset] = true + } -/***/ }), + const pause = request.onHeaders(statusCode, headers, this.resume, statusText) === false -/***/ 3121: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (request.aborted) { + return -1 + } -"use strict"; + if (request.method === 'HEAD') { + return 1 + } + if (statusCode < 200) { + return 1 + } -const assert = __nccwpck_require__(9491) -const { kHeadersList } = __nccwpck_require__(2785) + if (socket[kBlocking]) { + socket[kBlocking] = false + resume(client) + } -function isCTLExcludingHtab (value) { - if (value.length === 0) { - return false + return pause ? constants.ERROR.PAUSED : 0 } - for (const char of value) { - const code = char.charCodeAt(0) + onBody (buf) { + const { client, socket, statusCode, maxResponseSize } = this - if ( - (code >= 0x00 || code <= 0x08) || - (code >= 0x0A || code <= 0x1F) || - code === 0x7F - ) { - return false + if (socket.destroyed) { + return -1 } - } -} -/** - CHAR = - token = 1* - separators = "(" | ")" | "<" | ">" | "@" - | "," | ";" | ":" | "\" | <"> - | "/" | "[" | "]" | "?" | "=" - | "{" | "}" | SP | HT - * @param {string} name - */ -function validateCookieName (name) { - for (const char of name) { - const code = char.charCodeAt(0) + const request = client[kQueue][client[kRunningIdx]] + assert(request) - if ( - (code <= 0x20 || code > 0x7F) || - char === '(' || - char === ')' || - char === '>' || - char === '<' || - char === '@' || - char === ',' || - char === ';' || - char === ':' || - char === '\\' || - char === '"' || - char === '/' || - char === '[' || - char === ']' || - char === '?' || - char === '=' || - char === '{' || - char === '}' - ) { - throw new Error('Invalid cookie name') + assert.strictEqual(this.timeoutType, TIMEOUT_BODY) + if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh() + } } - } -} -/** - cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) - cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E - ; US-ASCII characters excluding CTLs, - ; whitespace DQUOTE, comma, semicolon, - ; and backslash - * @param {string} value - */ -function validateCookieValue (value) { - for (const char of value) { - const code = char.charCodeAt(0) + assert(statusCode >= 200) - if ( - code < 0x21 || // exclude CTLs (0-31) - code === 0x22 || - code === 0x2C || - code === 0x3B || - code === 0x5C || - code > 0x7E // non-ascii - ) { - throw new Error('Invalid header value') + if (maxResponseSize > -1 && this.bytesRead + buf.length > maxResponseSize) { + util.destroy(socket, new ResponseExceededMaxSizeError()) + return -1 } - } -} -/** - * path-value = - * @param {string} path - */ -function validateCookiePath (path) { - for (const char of path) { - const code = char.charCodeAt(0) + this.bytesRead += buf.length - if (code < 0x21 || char === ';') { - throw new Error('Invalid cookie path') + if (request.onData(buf) === false) { + return constants.ERROR.PAUSED } } -} -/** - * I have no idea why these values aren't allowed to be honest, - * but Deno tests these. - Khafra - * @param {string} domain - */ -function validateCookieDomain (domain) { - if ( - domain.startsWith('-') || - domain.endsWith('.') || - domain.endsWith('-') - ) { - throw new Error('Invalid cookie domain') - } -} + onMessageComplete () { + const { client, socket, statusCode, upgrade, headers, contentLength, bytesRead, shouldKeepAlive } = this -/** - * @see https://www.rfc-editor.org/rfc/rfc7231#section-7.1.1.1 - * @param {number|Date} date - IMF-fixdate = day-name "," SP date1 SP time-of-day SP GMT - ; fixed length/zone/capitalization subset of the format - ; see Section 3.3 of [RFC5322] + if (socket.destroyed && (!statusCode || shouldKeepAlive)) { + return -1 + } - day-name = %x4D.6F.6E ; "Mon", case-sensitive - / %x54.75.65 ; "Tue", case-sensitive - / %x57.65.64 ; "Wed", case-sensitive - / %x54.68.75 ; "Thu", case-sensitive - / %x46.72.69 ; "Fri", case-sensitive - / %x53.61.74 ; "Sat", case-sensitive - / %x53.75.6E ; "Sun", case-sensitive - date1 = day SP month SP year - ; e.g., 02 Jun 1982 + if (upgrade) { + return + } - day = 2DIGIT - month = %x4A.61.6E ; "Jan", case-sensitive - / %x46.65.62 ; "Feb", case-sensitive - / %x4D.61.72 ; "Mar", case-sensitive - / %x41.70.72 ; "Apr", case-sensitive - / %x4D.61.79 ; "May", case-sensitive - / %x4A.75.6E ; "Jun", case-sensitive - / %x4A.75.6C ; "Jul", case-sensitive - / %x41.75.67 ; "Aug", case-sensitive - / %x53.65.70 ; "Sep", case-sensitive - / %x4F.63.74 ; "Oct", case-sensitive - / %x4E.6F.76 ; "Nov", case-sensitive - / %x44.65.63 ; "Dec", case-sensitive - year = 4DIGIT + const request = client[kQueue][client[kRunningIdx]] + assert(request) - GMT = %x47.4D.54 ; "GMT", case-sensitive + assert(statusCode >= 100) - time-of-day = hour ":" minute ":" second - ; 00:00:00 - 23:59:60 (leap second) + this.statusCode = null + this.statusText = '' + this.bytesRead = 0 + this.contentLength = '' + this.keepAlive = '' + this.connection = '' - hour = 2DIGIT - minute = 2DIGIT - second = 2DIGIT - */ -function toIMFDate (date) { - if (typeof date === 'number') { - date = new Date(date) - } + assert(this.headers.length % 2 === 0) + this.headers = [] + this.headersSize = 0 - const days = [ - 'Sun', 'Mon', 'Tue', 'Wed', - 'Thu', 'Fri', 'Sat' - ] + if (statusCode < 200) { + return + } - const months = [ - 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' - ] + /* istanbul ignore next: should be handled by llhttp? */ + if (request.method !== 'HEAD' && contentLength && bytesRead !== parseInt(contentLength, 10)) { + util.destroy(socket, new ResponseContentLengthMismatchError()) + return -1 + } - const dayName = days[date.getUTCDay()] - const day = date.getUTCDate().toString().padStart(2, '0') - const month = months[date.getUTCMonth()] - const year = date.getUTCFullYear() - const hour = date.getUTCHours().toString().padStart(2, '0') - const minute = date.getUTCMinutes().toString().padStart(2, '0') - const second = date.getUTCSeconds().toString().padStart(2, '0') + request.onComplete(headers) - return `${dayName}, ${day} ${month} ${year} ${hour}:${minute}:${second} GMT` + client[kQueue][client[kRunningIdx]++] = null + + if (socket[kWriting]) { + assert.strictEqual(client[kRunning], 0) + // Response completed before request. + util.destroy(socket, new InformationalError('reset')) + return constants.ERROR.PAUSED + } else if (!shouldKeepAlive) { + util.destroy(socket, new InformationalError('reset')) + return constants.ERROR.PAUSED + } else if (socket[kReset] && client[kRunning] === 0) { + // Destroy socket once all requests have completed. + // The request at the tail of the pipeline is the one + // that requested reset and no further requests should + // have been queued since then. + util.destroy(socket, new InformationalError('reset')) + return constants.ERROR.PAUSED + } else if (client[kPipelining] === 1) { + // We must wait a full event loop cycle to reuse this socket to make sure + // that non-spec compliant servers are not closing the connection even if they + // said they won't. + setImmediate(resume, client) + } else { + resume(client) + } + } } -/** - max-age-av = "Max-Age=" non-zero-digit *DIGIT - ; In practice, both expires-av and max-age-av - ; are limited to dates representable by the - ; user agent. - * @param {number} maxAge - */ -function validateCookieMaxAge (maxAge) { - if (maxAge < 0) { - throw new Error('Invalid cookie max-age') +function onParserTimeout (parser) { + const { socket, timeoutType, client } = parser + + /* istanbul ignore else */ + if (timeoutType === TIMEOUT_HEADERS) { + if (!socket[kWriting] || socket.writableNeedDrain || client[kRunning] > 1) { + assert(!parser.paused, 'cannot be paused while waiting for headers') + util.destroy(socket, new HeadersTimeoutError()) + } + } else if (timeoutType === TIMEOUT_BODY) { + if (!parser.paused) { + util.destroy(socket, new BodyTimeoutError()) + } + } else if (timeoutType === TIMEOUT_IDLE) { + assert(client[kRunning] === 0 && client[kKeepAliveTimeoutValue]) + util.destroy(socket, new InformationalError('socket idle timeout')) } } -/** - * @see https://www.rfc-editor.org/rfc/rfc6265#section-4.1.1 - * @param {import('./index').Cookie} cookie - */ -function stringify (cookie) { - if (cookie.name.length === 0) { - return null +function onSocketReadable () { + const { [kParser]: parser } = this + if (parser) { + parser.readMore() } +} - validateCookieName(cookie.name) - validateCookieValue(cookie.value) +function onSocketError (err) { + const { [kClient]: client, [kParser]: parser } = this - const out = [`${cookie.name}=${cookie.value}`] + assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.1 - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.2 - if (cookie.name.startsWith('__Secure-')) { - cookie.secure = true + if (client[kHTTPConnVersion] !== 'h2') { + // On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded + // to the user. + if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) { + // We treat all incoming data so for as a valid response. + parser.onMessageComplete() + return + } } - if (cookie.name.startsWith('__Host-')) { - cookie.secure = true - cookie.domain = null - cookie.path = '/' - } + this[kError] = err - if (cookie.secure) { - out.push('Secure') - } + onError(this[kClient], err) +} - if (cookie.httpOnly) { - out.push('HttpOnly') - } +function onError (client, err) { + if ( + client[kRunning] === 0 && + err.code !== 'UND_ERR_INFO' && + err.code !== 'UND_ERR_SOCKET' + ) { + // Error is not caused by running request and not a recoverable + // socket error. - if (typeof cookie.maxAge === 'number') { - validateCookieMaxAge(cookie.maxAge) - out.push(`Max-Age=${cookie.maxAge}`) - } + assert(client[kPendingIdx] === client[kRunningIdx]) - if (cookie.domain) { - validateCookieDomain(cookie.domain) - out.push(`Domain=${cookie.domain}`) + const requests = client[kQueue].splice(client[kRunningIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + errorRequest(client, request, err) + } + assert(client[kSize] === 0) } +} - if (cookie.path) { - validateCookiePath(cookie.path) - out.push(`Path=${cookie.path}`) - } +function onSocketEnd () { + const { [kParser]: parser, [kClient]: client } = this - if (cookie.expires && cookie.expires.toString() !== 'Invalid Date') { - out.push(`Expires=${toIMFDate(cookie.expires)}`) + if (client[kHTTPConnVersion] !== 'h2') { + if (parser.statusCode && !parser.shouldKeepAlive) { + // We treat all incoming data so far as a valid response. + parser.onMessageComplete() + return + } } - if (cookie.sameSite) { - out.push(`SameSite=${cookie.sameSite}`) - } + util.destroy(this, new SocketError('other side closed', util.getSocketInfo(this))) +} - for (const part of cookie.unparsed) { - if (!part.includes('=')) { - throw new Error('Invalid unparsed') - } +function onSocketClose () { + const { [kClient]: client, [kParser]: parser } = this - const [key, ...value] = part.split('=') + if (client[kHTTPConnVersion] === 'h1' && parser) { + if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) { + // We treat all incoming data so far as a valid response. + parser.onMessageComplete() + } - out.push(`${key.trim()}=${value.join('=')}`) + this[kParser].destroy() + this[kParser] = null } - return out.join('; ') -} + const err = this[kError] || new SocketError('closed', util.getSocketInfo(this)) -let kHeadersListNode + client[kSocket] = null -function getHeadersList (headers) { - if (headers[kHeadersList]) { - return headers[kHeadersList] - } + if (client.destroyed) { + assert(client[kPending] === 0) - if (!kHeadersListNode) { - kHeadersListNode = Object.getOwnPropertySymbols(headers).find( - (symbol) => symbol.description === 'headers list' - ) + // Fail entire queue. + const requests = client[kQueue].splice(client[kRunningIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + errorRequest(client, request, err) + } + } else if (client[kRunning] > 0 && err.code !== 'UND_ERR_INFO') { + // Fail head of pipeline. + const request = client[kQueue][client[kRunningIdx]] + client[kQueue][client[kRunningIdx]++] = null - assert(kHeadersListNode, 'Headers cannot be parsed') + errorRequest(client, request, err) } - const headersList = headers[kHeadersListNode] - assert(headersList) + client[kPendingIdx] = client[kRunningIdx] - return headersList -} + assert(client[kRunning] === 0) -module.exports = { - isCTLExcludingHtab, - stringify, - getHeadersList + client.emit('disconnect', client[kUrl], [client], err) + + resume(client) } +async function connect (client) { + assert(!client[kConnecting]) + assert(!client[kSocket]) -/***/ }), - -/***/ 2067: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; + let { host, hostname, protocol, port } = client[kUrl] + // Resolve ipv6 + if (hostname[0] === '[') { + const idx = hostname.indexOf(']') -const net = __nccwpck_require__(1808) -const assert = __nccwpck_require__(9491) -const util = __nccwpck_require__(3983) -const { InvalidArgumentError, ConnectTimeoutError } = __nccwpck_require__(8045) + assert(idx !== -1) + const ip = hostname.substring(1, idx) -let tls // include tls conditionally since it is not always available + assert(net.isIP(ip)) + hostname = ip + } -// TODO: session re-use does not wait for the first -// connection to resolve the session and might therefore -// resolve the same servername multiple times even when -// re-use is enabled. + client[kConnecting] = true -let SessionCache -// FIXME: remove workaround when the Node bug is fixed -// https://github.com/nodejs/node/issues/49344#issuecomment-1741776308 -if (global.FinalizationRegistry && !process.env.NODE_V8_COVERAGE) { - SessionCache = class WeakSessionCache { - constructor (maxCachedSessions) { - this._maxCachedSessions = maxCachedSessions - this._sessionCache = new Map() - this._sessionRegistry = new global.FinalizationRegistry((key) => { - if (this._sessionCache.size < this._maxCachedSessions) { - return - } + if (channels.beforeConnect.hasSubscribers) { + channels.beforeConnect.publish({ + connectParams: { + host, + hostname, + protocol, + port, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, + connector: client[kConnector] + }) + } - const ref = this._sessionCache.get(key) - if (ref !== undefined && ref.deref() === undefined) { - this._sessionCache.delete(key) + try { + const socket = await new Promise((resolve, reject) => { + client[kConnector]({ + host, + hostname, + protocol, + port, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, (err, socket) => { + if (err) { + reject(err) + } else { + resolve(socket) } }) - } - - get (sessionKey) { - const ref = this._sessionCache.get(sessionKey) - return ref ? ref.deref() : null - } - - set (sessionKey, session) { - if (this._maxCachedSessions === 0) { - return - } + }) - this._sessionCache.set(sessionKey, new WeakRef(session)) - this._sessionRegistry.register(session, sessionKey) - } - } -} else { - SessionCache = class SimpleSessionCache { - constructor (maxCachedSessions) { - this._maxCachedSessions = maxCachedSessions - this._sessionCache = new Map() + if (client.destroyed) { + util.destroy(socket.on('error', () => {}), new ClientDestroyedError()) + return } - get (sessionKey) { - return this._sessionCache.get(sessionKey) - } + client[kConnecting] = false - set (sessionKey, session) { - if (this._maxCachedSessions === 0) { - return - } + assert(socket) - if (this._sessionCache.size >= this._maxCachedSessions) { - // remove the oldest session - const { value: oldestKey } = this._sessionCache.keys().next() - this._sessionCache.delete(oldestKey) + const isH2 = socket.alpnProtocol === 'h2' + if (isH2) { + if (!h2ExperimentalWarned) { + h2ExperimentalWarned = true + process.emitWarning('H2 support is experimental, expect them to change at any time.', { + code: 'UNDICI-H2' + }) } - this._sessionCache.set(sessionKey, session) - } - } -} + const session = http2.connect(client[kUrl], { + createConnection: () => socket, + peerMaxConcurrentStreams: client[kHTTP2SessionState].maxConcurrentStreams + }) -function buildConnector ({ allowH2, maxCachedSessions, socketPath, timeout, ...opts }) { - if (maxCachedSessions != null && (!Number.isInteger(maxCachedSessions) || maxCachedSessions < 0)) { - throw new InvalidArgumentError('maxCachedSessions must be a positive integer or zero') - } + client[kHTTPConnVersion] = 'h2' + session[kClient] = client + session[kSocket] = socket + session.on('error', onHttp2SessionError) + session.on('frameError', onHttp2FrameError) + session.on('end', onHttp2SessionEnd) + session.on('goaway', onHTTP2GoAway) + session.on('close', onSocketClose) + session.unref() - const options = { path: socketPath, ...opts } - const sessionCache = new SessionCache(maxCachedSessions == null ? 100 : maxCachedSessions) - timeout = timeout == null ? 10e3 : timeout - allowH2 = allowH2 != null ? allowH2 : false - return function connect ({ hostname, host, protocol, port, servername, localAddress, httpSocket }, callback) { - let socket - if (protocol === 'https:') { - if (!tls) { - tls = __nccwpck_require__(4404) + client[kHTTP2Session] = session + socket[kHTTP2Session] = session + } else { + if (!llhttpInstance) { + llhttpInstance = await llhttpPromise + llhttpPromise = null } - servername = servername || options.servername || util.getServerName(host) || null - const sessionKey = servername || hostname - const session = sessionCache.get(sessionKey) || null + socket[kNoRef] = false + socket[kWriting] = false + socket[kReset] = false + socket[kBlocking] = false + socket[kParser] = new Parser(client, socket, llhttpInstance) + } - assert(sessionKey) + socket[kCounter] = 0 + socket[kMaxRequests] = client[kMaxRequests] + socket[kClient] = client + socket[kError] = null - socket = tls.connect({ - highWaterMark: 16384, // TLS in node can't have bigger HWM anyway... - ...options, - servername, - session, - localAddress, - // TODO(HTTP/2): Add support for h2c - ALPNProtocols: allowH2 ? ['http/1.1', 'h2'] : ['http/1.1'], - socket: httpSocket, // upgrade socket connection - port: port || 443, - host: hostname - }) + socket + .on('error', onSocketError) + .on('readable', onSocketReadable) + .on('end', onSocketEnd) + .on('close', onSocketClose) - socket - .on('session', function (session) { - // TODO (fix): Can a session become invalid once established? Don't think so? - sessionCache.set(sessionKey, session) - }) - } else { - assert(!httpSocket, 'httpSocket can only be sent on TLS update') - socket = net.connect({ - highWaterMark: 64 * 1024, // Same as nodejs fs streams. - ...options, - localAddress, - port: port || 80, - host: hostname + client[kSocket] = socket + + if (channels.connected.hasSubscribers) { + channels.connected.publish({ + connectParams: { + host, + hostname, + protocol, + port, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, + connector: client[kConnector], + socket }) } - - // Set TCP keep alive options on the socket here instead of in connect() for the case of assigning the socket - if (options.keepAlive == null || options.keepAlive) { - const keepAliveInitialDelay = options.keepAliveInitialDelay === undefined ? 60e3 : options.keepAliveInitialDelay - socket.setKeepAlive(true, keepAliveInitialDelay) + client.emit('connect', client[kUrl], [client]) + } catch (err) { + if (client.destroyed) { + return } - const cancelTimeout = setupTimeout(() => onConnectTimeout(socket), timeout) - - socket - .setNoDelay(true) - .once(protocol === 'https:' ? 'secureConnect' : 'connect', function () { - cancelTimeout() + client[kConnecting] = false - if (callback) { - const cb = callback - callback = null - cb(null, this) - } + if (channels.connectError.hasSubscribers) { + channels.connectError.publish({ + connectParams: { + host, + hostname, + protocol, + port, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, + connector: client[kConnector], + error: err }) - .on('error', function (err) { - cancelTimeout() + } - if (callback) { - const cb = callback - callback = null - cb(err) - } - }) + if (err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') { + assert(client[kRunning] === 0) + while (client[kPending] > 0 && client[kQueue][client[kPendingIdx]].servername === client[kServerName]) { + const request = client[kQueue][client[kPendingIdx]++] + errorRequest(client, request, err) + } + } else { + onError(client, err) + } - return socket + client.emit('connectionError', client[kUrl], [client], err) } + + resume(client) } -function setupTimeout (onConnectTimeout, timeout) { - if (!timeout) { - return () => {} +function emitDrain (client) { + client[kNeedDrain] = 0 + client.emit('drain', client[kUrl], [client]) +} + +function resume (client, sync) { + if (client[kResuming] === 2) { + return } - let s1 = null - let s2 = null - const timeoutId = setTimeout(() => { - // setImmediate is added to make sure that we priotorise socket error events over timeouts - s1 = setImmediate(() => { - if (process.platform === 'win32') { - // Windows needs an extra setImmediate probably due to implementation differences in the socket logic - s2 = setImmediate(() => onConnectTimeout()) - } else { - onConnectTimeout() - } - }) - }, timeout) - return () => { - clearTimeout(timeoutId) - clearImmediate(s1) - clearImmediate(s2) + client[kResuming] = 2 + + _resume(client, sync) + client[kResuming] = 0 + + if (client[kRunningIdx] > 256) { + client[kQueue].splice(0, client[kRunningIdx]) + client[kPendingIdx] -= client[kRunningIdx] + client[kRunningIdx] = 0 } } -function onConnectTimeout (socket) { - util.destroy(socket, new ConnectTimeoutError()) -} +function _resume (client, sync) { + while (true) { + if (client.destroyed) { + assert(client[kPending] === 0) + return + } -module.exports = buildConnector + if (client[kClosedResolve] && !client[kSize]) { + client[kClosedResolve]() + client[kClosedResolve] = null + return + } + const socket = client[kSocket] -/***/ }), + if (socket && !socket.destroyed && socket.alpnProtocol !== 'h2') { + if (client[kSize] === 0) { + if (!socket[kNoRef] && socket.unref) { + socket.unref() + socket[kNoRef] = true + } + } else if (socket[kNoRef] && socket.ref) { + socket.ref() + socket[kNoRef] = false + } -/***/ 8045: -/***/ ((module) => { + if (client[kSize] === 0) { + if (socket[kParser].timeoutType !== TIMEOUT_IDLE) { + socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_IDLE) + } + } else if (client[kRunning] > 0 && socket[kParser].statusCode < 200) { + if (socket[kParser].timeoutType !== TIMEOUT_HEADERS) { + const request = client[kQueue][client[kRunningIdx]] + const headersTimeout = request.headersTimeout != null + ? request.headersTimeout + : client[kHeadersTimeout] + socket[kParser].setTimeout(headersTimeout, TIMEOUT_HEADERS) + } + } + } -"use strict"; + if (client[kBusy]) { + client[kNeedDrain] = 2 + } else if (client[kNeedDrain] === 2) { + if (sync) { + client[kNeedDrain] = 1 + process.nextTick(emitDrain, client) + } else { + emitDrain(client) + } + continue + } + if (client[kPending] === 0) { + return + } -class UndiciError extends Error { - constructor (message) { - super(message) - this.name = 'UndiciError' - this.code = 'UND_ERR' - } -} + if (client[kRunning] >= (client[kPipelining] || 1)) { + return + } -class ConnectTimeoutError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, ConnectTimeoutError) - this.name = 'ConnectTimeoutError' - this.message = message || 'Connect Timeout Error' - this.code = 'UND_ERR_CONNECT_TIMEOUT' - } -} + const request = client[kQueue][client[kPendingIdx]] -class HeadersTimeoutError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, HeadersTimeoutError) - this.name = 'HeadersTimeoutError' - this.message = message || 'Headers Timeout Error' - this.code = 'UND_ERR_HEADERS_TIMEOUT' - } -} + if (client[kUrl].protocol === 'https:' && client[kServerName] !== request.servername) { + if (client[kRunning] > 0) { + return + } -class HeadersOverflowError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, HeadersOverflowError) - this.name = 'HeadersOverflowError' - this.message = message || 'Headers Overflow Error' - this.code = 'UND_ERR_HEADERS_OVERFLOW' - } -} + client[kServerName] = request.servername -class BodyTimeoutError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, BodyTimeoutError) - this.name = 'BodyTimeoutError' - this.message = message || 'Body Timeout Error' - this.code = 'UND_ERR_BODY_TIMEOUT' - } -} + if (socket && socket.servername !== request.servername) { + util.destroy(socket, new InformationalError('servername changed')) + return + } + } -class ResponseStatusCodeError extends UndiciError { - constructor (message, statusCode, headers, body) { - super(message) - Error.captureStackTrace(this, ResponseStatusCodeError) - this.name = 'ResponseStatusCodeError' - this.message = message || 'Response Status Code Error' - this.code = 'UND_ERR_RESPONSE_STATUS_CODE' - this.body = body - this.status = statusCode - this.statusCode = statusCode - this.headers = headers - } -} + if (client[kConnecting]) { + return + } -class InvalidArgumentError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, InvalidArgumentError) - this.name = 'InvalidArgumentError' - this.message = message || 'Invalid Argument Error' - this.code = 'UND_ERR_INVALID_ARG' - } -} + if (!socket && !client[kHTTP2Session]) { + connect(client) + return + } -class InvalidReturnValueError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, InvalidReturnValueError) - this.name = 'InvalidReturnValueError' - this.message = message || 'Invalid Return Value Error' - this.code = 'UND_ERR_INVALID_RETURN_VALUE' - } -} + if (socket.destroyed || socket[kWriting] || socket[kReset] || socket[kBlocking]) { + return + } -class RequestAbortedError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, RequestAbortedError) - this.name = 'AbortError' - this.message = message || 'Request aborted' - this.code = 'UND_ERR_ABORTED' + if (client[kRunning] > 0 && !request.idempotent) { + // Non-idempotent request cannot be retried. + // Ensure that no other requests are inflight and + // could cause failure. + return + } + + if (client[kRunning] > 0 && (request.upgrade || request.method === 'CONNECT')) { + // Don't dispatch an upgrade until all preceding requests have completed. + // A misbehaving server might upgrade the connection before all pipelined + // request has completed. + return + } + + if (client[kRunning] > 0 && util.bodyLength(request.body) !== 0 && + (util.isStream(request.body) || util.isAsyncIterable(request.body))) { + // Request with stream or iterator body can error while other requests + // are inflight and indirectly error those as well. + // Ensure this doesn't happen by waiting for inflight + // to complete before dispatching. + + // Request with stream or iterator body cannot be retried. + // Ensure that no other requests are inflight and + // could cause failure. + return + } + + if (!request.aborted && write(client, request)) { + client[kPendingIdx]++ + } else { + client[kQueue].splice(client[kPendingIdx], 1) + } } } -class InformationalError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, InformationalError) - this.name = 'InformationalError' - this.message = message || 'Request information' - this.code = 'UND_ERR_INFO' - } +// https://www.rfc-editor.org/rfc/rfc7230#section-3.3.2 +function shouldSendContentLength (method) { + return method !== 'GET' && method !== 'HEAD' && method !== 'OPTIONS' && method !== 'TRACE' && method !== 'CONNECT' } -class RequestContentLengthMismatchError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, RequestContentLengthMismatchError) - this.name = 'RequestContentLengthMismatchError' - this.message = message || 'Request body length does not match content-length header' - this.code = 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH' +function write (client, request) { + if (client[kHTTPConnVersion] === 'h2') { + writeH2(client, client[kHTTP2Session], request) + return } -} -class ResponseContentLengthMismatchError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, ResponseContentLengthMismatchError) - this.name = 'ResponseContentLengthMismatchError' - this.message = message || 'Response body length does not match content-length header' - this.code = 'UND_ERR_RES_CONTENT_LENGTH_MISMATCH' - } -} + const { body, method, path, host, upgrade, headers, blocking, reset } = request -class ClientDestroyedError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, ClientDestroyedError) - this.name = 'ClientDestroyedError' - this.message = message || 'The client is destroyed' - this.code = 'UND_ERR_DESTROYED' - } -} + // https://tools.ietf.org/html/rfc7231#section-4.3.1 + // https://tools.ietf.org/html/rfc7231#section-4.3.2 + // https://tools.ietf.org/html/rfc7231#section-4.3.5 -class ClientClosedError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, ClientClosedError) - this.name = 'ClientClosedError' - this.message = message || 'The client is closed' - this.code = 'UND_ERR_CLOSED' - } -} + // Sending a payload body on a request that does not + // expect it can cause undefined behavior on some + // servers and corrupt connection state. Do not + // re-use the connection for further requests. -class SocketError extends UndiciError { - constructor (message, socket) { - super(message) - Error.captureStackTrace(this, SocketError) - this.name = 'SocketError' - this.message = message || 'Socket error' - this.code = 'UND_ERR_SOCKET' - this.socket = socket - } -} + const expectsPayload = ( + method === 'PUT' || + method === 'POST' || + method === 'PATCH' + ) -class NotSupportedError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, NotSupportedError) - this.name = 'NotSupportedError' - this.message = message || 'Not supported error' - this.code = 'UND_ERR_NOT_SUPPORTED' + if (body && typeof body.read === 'function') { + // Try to read EOF in order to get length. + body.read(0) } -} -class BalancedPoolMissingUpstreamError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, NotSupportedError) - this.name = 'MissingUpstreamError' - this.message = message || 'No upstream has been added to the BalancedPool' - this.code = 'UND_ERR_BPL_MISSING_UPSTREAM' - } -} + const bodyLength = util.bodyLength(body) -class HTTPParserError extends Error { - constructor (message, code, data) { - super(message) - Error.captureStackTrace(this, HTTPParserError) - this.name = 'HTTPParserError' - this.code = code ? `HPE_${code}` : undefined - this.data = data ? data.toString() : undefined - } -} + let contentLength = bodyLength -class ResponseExceededMaxSizeError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, ResponseExceededMaxSizeError) - this.name = 'ResponseExceededMaxSizeError' - this.message = message || 'Response content exceeded max size' - this.code = 'UND_ERR_RES_EXCEEDED_MAX_SIZE' + if (contentLength === null) { + contentLength = request.contentLength } -} -class RequestRetryError extends UndiciError { - constructor (message, code, { headers, data }) { - super(message) - Error.captureStackTrace(this, RequestRetryError) - this.name = 'RequestRetryError' - this.message = message || 'Request retry error' - this.code = 'UND_ERR_REQ_RETRY' - this.statusCode = code - this.data = data - this.headers = headers + if (contentLength === 0 && !expectsPayload) { + // https://tools.ietf.org/html/rfc7230#section-3.3.2 + // A user agent SHOULD NOT send a Content-Length header field when + // the request message does not contain a payload body and the method + // semantics do not anticipate such a body. + + contentLength = null } -} -module.exports = { - HTTPParserError, - UndiciError, - HeadersTimeoutError, - HeadersOverflowError, - BodyTimeoutError, - RequestContentLengthMismatchError, - ConnectTimeoutError, - ResponseStatusCodeError, - InvalidArgumentError, - InvalidReturnValueError, - RequestAbortedError, - ClientDestroyedError, - ClientClosedError, - InformationalError, - SocketError, - NotSupportedError, - ResponseContentLengthMismatchError, - BalancedPoolMissingUpstreamError, - ResponseExceededMaxSizeError, - RequestRetryError -} + // https://github.com/nodejs/undici/issues/2046 + // A user agent may send a Content-Length header with 0 value, this should be allowed. + if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength !== null && request.contentLength !== contentLength) { + if (client[kStrictContentLength]) { + errorRequest(client, request, new RequestContentLengthMismatchError()) + return false + } + process.emitWarning(new RequestContentLengthMismatchError()) + } -/***/ }), + const socket = client[kSocket] -/***/ 2905: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + try { + request.onConnect((err) => { + if (request.aborted || request.completed) { + return + } -"use strict"; + errorRequest(client, request, err || new RequestAbortedError()) + util.destroy(socket, new InformationalError('aborted')) + }) + } catch (err) { + errorRequest(client, request, err) + } -const { - InvalidArgumentError, - NotSupportedError -} = __nccwpck_require__(8045) -const assert = __nccwpck_require__(9491) -const { kHTTP2BuildRequest, kHTTP2CopyHeaders, kHTTP1BuildRequest } = __nccwpck_require__(2785) -const util = __nccwpck_require__(3983) + if (request.aborted) { + return false + } -// tokenRegExp and headerCharRegex have been lifted from -// https://github.com/nodejs/node/blob/main/lib/_http_common.js + if (method === 'HEAD') { + // https://github.com/mcollina/undici/issues/258 + // Close after a HEAD request to interop with misbehaving servers + // that may send a body in the response. -/** - * Verifies that the given val is a valid HTTP token - * per the rules defined in RFC 7230 - * See https://tools.ietf.org/html/rfc7230#section-3.2.6 - */ -const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/ + socket[kReset] = true + } -/** - * Matches if val contains an invalid field-vchar - * field-value = *( field-content / obs-fold ) - * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] - * field-vchar = VCHAR / obs-text - */ -const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/ + if (upgrade || method === 'CONNECT') { + // On CONNECT or upgrade, block pipeline from dispatching further + // requests on this connection. -// Verifies that a given path is valid does not contain control chars \x00 to \x20 -const invalidPathRegex = /[^\u0021-\u00ff]/ + socket[kReset] = true + } -const kHandler = Symbol('handler') + if (reset != null) { + socket[kReset] = reset + } -const channels = {} + if (client[kMaxRequests] && socket[kCounter]++ >= client[kMaxRequests]) { + socket[kReset] = true + } -let extractBody + if (blocking) { + socket[kBlocking] = true + } -try { - const diagnosticsChannel = __nccwpck_require__(7643) - channels.create = diagnosticsChannel.channel('undici:request:create') - channels.bodySent = diagnosticsChannel.channel('undici:request:bodySent') - channels.headers = diagnosticsChannel.channel('undici:request:headers') - channels.trailers = diagnosticsChannel.channel('undici:request:trailers') - channels.error = diagnosticsChannel.channel('undici:request:error') -} catch { - channels.create = { hasSubscribers: false } - channels.bodySent = { hasSubscribers: false } - channels.headers = { hasSubscribers: false } - channels.trailers = { hasSubscribers: false } - channels.error = { hasSubscribers: false } -} + let header = `${method} ${path} HTTP/1.1\r\n` -class Request { - constructor (origin, { - path, - method, - body, - headers, - query, - idempotent, - blocking, - upgrade, - headersTimeout, - bodyTimeout, - reset, - throwOnError, - expectContinue - }, handler) { - if (typeof path !== 'string') { - throw new InvalidArgumentError('path must be a string') - } else if ( - path[0] !== '/' && - !(path.startsWith('http://') || path.startsWith('https://')) && - method !== 'CONNECT' - ) { - throw new InvalidArgumentError('path must be an absolute URL or start with a slash') - } else if (invalidPathRegex.exec(path) !== null) { - throw new InvalidArgumentError('invalid request path') - } + if (typeof host === 'string') { + header += `host: ${host}\r\n` + } else { + header += client[kHostHeader] + } - if (typeof method !== 'string') { - throw new InvalidArgumentError('method must be a string') - } else if (tokenRegExp.exec(method) === null) { - throw new InvalidArgumentError('invalid request method') - } + if (upgrade) { + header += `connection: upgrade\r\nupgrade: ${upgrade}\r\n` + } else if (client[kPipelining] && !socket[kReset]) { + header += 'connection: keep-alive\r\n' + } else { + header += 'connection: close\r\n' + } - if (upgrade && typeof upgrade !== 'string') { - throw new InvalidArgumentError('upgrade must be a string') - } + if (headers) { + header += headers + } - if (headersTimeout != null && (!Number.isFinite(headersTimeout) || headersTimeout < 0)) { - throw new InvalidArgumentError('invalid headersTimeout') - } + if (channels.sendHeaders.hasSubscribers) { + channels.sendHeaders.publish({ request, headers: header, socket }) + } - if (bodyTimeout != null && (!Number.isFinite(bodyTimeout) || bodyTimeout < 0)) { - throw new InvalidArgumentError('invalid bodyTimeout') + /* istanbul ignore else: assertion */ + if (!body || bodyLength === 0) { + if (contentLength === 0) { + socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1') + } else { + assert(contentLength === null, 'no body must not have content length') + socket.write(`${header}\r\n`, 'latin1') } + request.onRequestSent() + } else if (util.isBuffer(body)) { + assert(contentLength === body.byteLength, 'buffer body must have content length') - if (reset != null && typeof reset !== 'boolean') { - throw new InvalidArgumentError('invalid reset') + socket.cork() + socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') + socket.write(body) + socket.uncork() + request.onBodySent(body) + request.onRequestSent() + if (!expectsPayload) { + socket[kReset] = true } - - if (expectContinue != null && typeof expectContinue !== 'boolean') { - throw new InvalidArgumentError('invalid expectContinue') + } else if (util.isBlobLike(body)) { + if (typeof body.stream === 'function') { + writeIterable({ body: body.stream(), client, request, socket, contentLength, header, expectsPayload }) + } else { + writeBlob({ body, client, request, socket, contentLength, header, expectsPayload }) } + } else if (util.isStream(body)) { + writeStream({ body, client, request, socket, contentLength, header, expectsPayload }) + } else if (util.isIterable(body)) { + writeIterable({ body, client, request, socket, contentLength, header, expectsPayload }) + } else { + assert(false) + } - this.headersTimeout = headersTimeout - - this.bodyTimeout = bodyTimeout - - this.throwOnError = throwOnError === true - - this.method = method + return true +} - this.abort = null +function writeH2 (client, session, request) { + const { body, method, path, host, upgrade, expectContinue, signal, headers: reqHeaders } = request - if (body == null) { - this.body = null - } else if (util.isStream(body)) { - this.body = body + let headers + if (typeof reqHeaders === 'string') headers = Request[kHTTP2CopyHeaders](reqHeaders.trim()) + else headers = reqHeaders - const rState = this.body._readableState - if (!rState || !rState.autoDestroy) { - this.endHandler = function autoDestroy () { - util.destroy(this) - } - this.body.on('end', this.endHandler) - } + if (upgrade) { + errorRequest(client, request, new Error('Upgrade not supported for H2')) + return false + } - this.errorHandler = err => { - if (this.abort) { - this.abort(err) - } else { - this.error = err - } + try { + // TODO(HTTP/2): Should we call onConnect immediately or on stream ready event? + request.onConnect((err) => { + if (request.aborted || request.completed) { + return } - this.body.on('error', this.errorHandler) - } else if (util.isBuffer(body)) { - this.body = body.byteLength ? body : null - } else if (ArrayBuffer.isView(body)) { - this.body = body.buffer.byteLength ? Buffer.from(body.buffer, body.byteOffset, body.byteLength) : null - } else if (body instanceof ArrayBuffer) { - this.body = body.byteLength ? Buffer.from(body) : null - } else if (typeof body === 'string') { - this.body = body.length ? Buffer.from(body) : null - } else if (util.isFormDataLike(body) || util.isIterable(body) || util.isBlobLike(body)) { - this.body = body - } else { - throw new InvalidArgumentError('body must be a string, a Buffer, a Readable stream, an iterable, or an async iterable') - } - this.completed = false - - this.aborted = false - - this.upgrade = upgrade || null + errorRequest(client, request, err || new RequestAbortedError()) + }) + } catch (err) { + errorRequest(client, request, err) + } - this.path = query ? util.buildURL(path, query) : path + if (request.aborted) { + return false + } - this.origin = origin + /** @type {import('node:http2').ClientHttp2Stream} */ + let stream + const h2State = client[kHTTP2SessionState] - this.idempotent = idempotent == null - ? method === 'HEAD' || method === 'GET' - : idempotent + headers[HTTP2_HEADER_AUTHORITY] = host || client[kHost] + headers[HTTP2_HEADER_METHOD] = method - this.blocking = blocking == null ? false : blocking + if (method === 'CONNECT') { + session.ref() + // we are already connected, streams are pending, first request + // will create a new stream. We trigger a request to create the stream and wait until + // `ready` event is triggered + // We disabled endStream to allow the user to write to the stream + stream = session.request(headers, { endStream: false, signal }) - this.reset = reset == null ? null : reset + if (stream.id && !stream.pending) { + request.onUpgrade(null, null, stream) + ++h2State.openStreams + } else { + stream.once('ready', () => { + request.onUpgrade(null, null, stream) + ++h2State.openStreams + }) + } - this.host = null + stream.once('close', () => { + h2State.openStreams -= 1 + // TODO(HTTP/2): unref only if current streams count is 0 + if (h2State.openStreams === 0) session.unref() + }) - this.contentLength = null + return true + } - this.contentType = null + // https://tools.ietf.org/html/rfc7540#section-8.3 + // :path and :scheme headers must be omited when sending CONNECT - this.headers = '' + headers[HTTP2_HEADER_PATH] = path + headers[HTTP2_HEADER_SCHEME] = 'https' - // Only for H2 - this.expectContinue = expectContinue != null ? expectContinue : false + // https://tools.ietf.org/html/rfc7231#section-4.3.1 + // https://tools.ietf.org/html/rfc7231#section-4.3.2 + // https://tools.ietf.org/html/rfc7231#section-4.3.5 - if (Array.isArray(headers)) { - if (headers.length % 2 !== 0) { - throw new InvalidArgumentError('headers array must be even') - } - for (let i = 0; i < headers.length; i += 2) { - processHeader(this, headers[i], headers[i + 1]) - } - } else if (headers && typeof headers === 'object') { - const keys = Object.keys(headers) - for (let i = 0; i < keys.length; i++) { - const key = keys[i] - processHeader(this, key, headers[key]) - } - } else if (headers != null) { - throw new InvalidArgumentError('headers must be an object or an array') - } + // Sending a payload body on a request that does not + // expect it can cause undefined behavior on some + // servers and corrupt connection state. Do not + // re-use the connection for further requests. - if (util.isFormDataLike(this.body)) { - if (util.nodeMajor < 16 || (util.nodeMajor === 16 && util.nodeMinor < 8)) { - throw new InvalidArgumentError('Form-Data bodies are only supported in node v16.8 and newer.') - } + const expectsPayload = ( + method === 'PUT' || + method === 'POST' || + method === 'PATCH' + ) - if (!extractBody) { - extractBody = (__nccwpck_require__(1472).extractBody) - } + if (body && typeof body.read === 'function') { + // Try to read EOF in order to get length. + body.read(0) + } - const [bodyStream, contentType] = extractBody(body) - if (this.contentType == null) { - this.contentType = contentType - this.headers += `content-type: ${contentType}\r\n` - } - this.body = bodyStream.stream - this.contentLength = bodyStream.length - } else if (util.isBlobLike(body) && this.contentType == null && body.type) { - this.contentType = body.type - this.headers += `content-type: ${body.type}\r\n` - } + let contentLength = util.bodyLength(body) - util.validateHandler(handler, method, upgrade) + if (contentLength == null) { + contentLength = request.contentLength + } - this.servername = util.getServerName(this.host) + if (contentLength === 0 || !expectsPayload) { + // https://tools.ietf.org/html/rfc7230#section-3.3.2 + // A user agent SHOULD NOT send a Content-Length header field when + // the request message does not contain a payload body and the method + // semantics do not anticipate such a body. - this[kHandler] = handler + contentLength = null + } - if (channels.create.hasSubscribers) { - channels.create.publish({ request: this }) + // https://github.com/nodejs/undici/issues/2046 + // A user agent may send a Content-Length header with 0 value, this should be allowed. + if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength != null && request.contentLength !== contentLength) { + if (client[kStrictContentLength]) { + errorRequest(client, request, new RequestContentLengthMismatchError()) + return false } + + process.emitWarning(new RequestContentLengthMismatchError()) } - onBodySent (chunk) { - if (this[kHandler].onBodySent) { - try { - return this[kHandler].onBodySent(chunk) - } catch (err) { - this.abort(err) - } - } + if (contentLength != null) { + assert(body, 'no body must not have content length') + headers[HTTP2_HEADER_CONTENT_LENGTH] = `${contentLength}` } - onRequestSent () { - if (channels.bodySent.hasSubscribers) { - channels.bodySent.publish({ request: this }) - } + session.ref() - if (this[kHandler].onRequestSent) { - try { - return this[kHandler].onRequestSent() - } catch (err) { - this.abort(err) - } - } + const shouldEndStream = method === 'GET' || method === 'HEAD' + if (expectContinue) { + headers[HTTP2_HEADER_EXPECT] = '100-continue' + stream = session.request(headers, { endStream: shouldEndStream, signal }) + + stream.once('continue', writeBodyH2) + } else { + stream = session.request(headers, { + endStream: shouldEndStream, + signal + }) + writeBodyH2() } - onConnect (abort) { - assert(!this.aborted) - assert(!this.completed) + // Increment counter as we have new several streams open + ++h2State.openStreams - if (this.error) { - abort(this.error) - } else { - this.abort = abort - return this[kHandler].onConnect(abort) + stream.once('response', headers => { + const { [HTTP2_HEADER_STATUS]: statusCode, ...realHeaders } = headers + + if (request.onHeaders(Number(statusCode), realHeaders, stream.resume.bind(stream), '') === false) { + stream.pause() } - } + }) - onHeaders (statusCode, headers, resume, statusText) { - assert(!this.aborted) - assert(!this.completed) + stream.once('end', () => { + request.onComplete([]) + }) - if (channels.headers.hasSubscribers) { - channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }) + stream.on('data', (chunk) => { + if (request.onData(chunk) === false) { + stream.pause() } + }) - try { - return this[kHandler].onHeaders(statusCode, headers, resume, statusText) - } catch (err) { - this.abort(err) + stream.once('close', () => { + h2State.openStreams -= 1 + // TODO(HTTP/2): unref only if current streams count is 0 + if (h2State.openStreams === 0) { + session.unref() } - } + }) - onData (chunk) { - assert(!this.aborted) - assert(!this.completed) + stream.once('error', function (err) { + if (client[kHTTP2Session] && !client[kHTTP2Session].destroyed && !this.closed && !this.destroyed) { + h2State.streams -= 1 + util.destroy(stream, err) + } + }) - try { - return this[kHandler].onData(chunk) - } catch (err) { - this.abort(err) - return false + stream.once('frameError', (type, code) => { + const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`) + errorRequest(client, request, err) + + if (client[kHTTP2Session] && !client[kHTTP2Session].destroyed && !this.closed && !this.destroyed) { + h2State.streams -= 1 + util.destroy(stream, err) } - } + }) - onUpgrade (statusCode, headers, socket) { - assert(!this.aborted) - assert(!this.completed) + // stream.on('aborted', () => { + // // TODO(HTTP/2): Support aborted + // }) - return this[kHandler].onUpgrade(statusCode, headers, socket) - } + // stream.on('timeout', () => { + // // TODO(HTTP/2): Support timeout + // }) - onComplete (trailers) { - this.onFinally() + // stream.on('push', headers => { + // // TODO(HTTP/2): Suppor push + // }) - assert(!this.aborted) + // stream.on('trailers', headers => { + // // TODO(HTTP/2): Support trailers + // }) - this.completed = true - if (channels.trailers.hasSubscribers) { - channels.trailers.publish({ request: this, trailers }) - } + return true - try { - return this[kHandler].onComplete(trailers) - } catch (err) { - // TODO (fix): This might be a bad idea? - this.onError(err) + function writeBodyH2 () { + /* istanbul ignore else: assertion */ + if (!body) { + request.onRequestSent() + } else if (util.isBuffer(body)) { + assert(contentLength === body.byteLength, 'buffer body must have content length') + stream.cork() + stream.write(body) + stream.uncork() + stream.end() + request.onBodySent(body) + request.onRequestSent() + } else if (util.isBlobLike(body)) { + if (typeof body.stream === 'function') { + writeIterable({ + client, + request, + contentLength, + h2stream: stream, + expectsPayload, + body: body.stream(), + socket: client[kSocket], + header: '' + }) + } else { + writeBlob({ + body, + client, + request, + contentLength, + expectsPayload, + h2stream: stream, + header: '', + socket: client[kSocket] + }) + } + } else if (util.isStream(body)) { + writeStream({ + body, + client, + request, + contentLength, + expectsPayload, + socket: client[kSocket], + h2stream: stream, + header: '' + }) + } else if (util.isIterable(body)) { + writeIterable({ + body, + client, + request, + contentLength, + expectsPayload, + header: '', + h2stream: stream, + socket: client[kSocket] + }) + } else { + assert(false) } } +} - onError (error) { - this.onFinally() +function writeStream ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { + assert(contentLength !== 0 || client[kRunning] === 0, 'stream body cannot be pipelined') - if (channels.error.hasSubscribers) { - channels.error.publish({ request: this, error }) - } + if (client[kHTTPConnVersion] === 'h2') { + // For HTTP/2, is enough to pipe the stream + const pipe = pipeline( + body, + h2stream, + (err) => { + if (err) { + util.destroy(body, err) + util.destroy(h2stream, err) + } else { + request.onRequestSent() + } + } + ) - if (this.aborted) { - return + pipe.on('data', onPipeData) + pipe.once('end', () => { + pipe.removeListener('data', onPipeData) + util.destroy(pipe) + }) + + function onPipeData (chunk) { + request.onBodySent(chunk) } - this.aborted = true - return this[kHandler].onError(error) + return } - onFinally () { - if (this.errorHandler) { - this.body.off('error', this.errorHandler) - this.errorHandler = null + let finished = false + + const writer = new AsyncWriter({ socket, request, contentLength, client, expectsPayload, header }) + + const onData = function (chunk) { + if (finished) { + return } - if (this.endHandler) { - this.body.off('end', this.endHandler) - this.endHandler = null + try { + if (!writer.write(chunk) && this.pause) { + this.pause() + } + } catch (err) { + util.destroy(this, err) } } + const onDrain = function () { + if (finished) { + return + } - // TODO: adjust to support H2 - addHeader (key, value) { - processHeader(this, key, value) - return this + if (body.resume) { + body.resume() + } } - - static [kHTTP1BuildRequest] (origin, opts, handler) { - // TODO: Migrate header parsing here, to make Requests - // HTTP agnostic - return new Request(origin, opts, handler) + const onAbort = function () { + if (finished) { + return + } + const err = new RequestAbortedError() + queueMicrotask(() => onFinished(err)) } + const onFinished = function (err) { + if (finished) { + return + } - static [kHTTP2BuildRequest] (origin, opts, handler) { - const headers = opts.headers - opts = { ...opts, headers: null } - - const request = new Request(origin, opts, handler) + finished = true - request.headers = {} + assert(socket.destroyed || (socket[kWriting] && client[kRunning] <= 1)) - if (Array.isArray(headers)) { - if (headers.length % 2 !== 0) { - throw new InvalidArgumentError('headers array must be even') - } - for (let i = 0; i < headers.length; i += 2) { - processHeader(request, headers[i], headers[i + 1], true) - } - } else if (headers && typeof headers === 'object') { - const keys = Object.keys(headers) - for (let i = 0; i < keys.length; i++) { - const key = keys[i] - processHeader(request, key, headers[key], true) + socket + .off('drain', onDrain) + .off('error', onFinished) + + body + .removeListener('data', onData) + .removeListener('end', onFinished) + .removeListener('error', onFinished) + .removeListener('close', onAbort) + + if (!err) { + try { + writer.end() + } catch (er) { + err = er } - } else if (headers != null) { - throw new InvalidArgumentError('headers must be an object or an array') } - return request + writer.destroy(err) + + if (err && (err.code !== 'UND_ERR_INFO' || err.message !== 'reset')) { + util.destroy(body, err) + } else { + util.destroy(body) + } } - static [kHTTP2CopyHeaders] (raw) { - const rawHeaders = raw.split('\r\n') - const headers = {} + body + .on('data', onData) + .on('end', onFinished) + .on('error', onFinished) + .on('close', onAbort) - for (const header of rawHeaders) { - const [key, value] = header.split(': ') + if (body.resume) { + body.resume() + } - if (value == null || value.length === 0) continue + socket + .on('drain', onDrain) + .on('error', onFinished) +} - if (headers[key]) headers[key] += `,${value}` - else headers[key] = value +async function writeBlob ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { + assert(contentLength === body.size, 'blob body must have content length') + + const isH2 = client[kHTTPConnVersion] === 'h2' + try { + if (contentLength != null && contentLength !== body.size) { + throw new RequestContentLengthMismatchError() } - return headers - } -} + const buffer = Buffer.from(await body.arrayBuffer()) -function processHeaderValue (key, val, skipAppend) { - if (val && typeof val === 'object') { - throw new InvalidArgumentError(`invalid ${key} header`) - } + if (isH2) { + h2stream.cork() + h2stream.write(buffer) + h2stream.uncork() + } else { + socket.cork() + socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') + socket.write(buffer) + socket.uncork() + } - val = val != null ? `${val}` : '' + request.onBodySent(buffer) + request.onRequestSent() - if (headerCharRegex.exec(val) !== null) { - throw new InvalidArgumentError(`invalid ${key} header`) - } + if (!expectsPayload) { + socket[kReset] = true + } - return skipAppend ? val : `${key}: ${val}\r\n` + resume(client) + } catch (err) { + util.destroy(isH2 ? h2stream : socket, err) + } } -function processHeader (request, key, val, skipAppend = false) { - if (val && (typeof val === 'object' && !Array.isArray(val))) { - throw new InvalidArgumentError(`invalid ${key} header`) - } else if (val === undefined) { - return - } +async function writeIterable ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { + assert(contentLength !== 0 || client[kRunning] === 0, 'iterator body cannot be pipelined') - if ( - request.host === null && - key.length === 4 && - key.toLowerCase() === 'host' - ) { - if (headerCharRegex.exec(val) !== null) { - throw new InvalidArgumentError(`invalid ${key} header`) - } - // Consumed by Client - request.host = val - } else if ( - request.contentLength === null && - key.length === 14 && - key.toLowerCase() === 'content-length' - ) { - request.contentLength = parseInt(val, 10) - if (!Number.isFinite(request.contentLength)) { - throw new InvalidArgumentError('invalid content-length header') + let callback = null + function onDrain () { + if (callback) { + const cb = callback + callback = null + cb() } - } else if ( - request.contentType === null && - key.length === 12 && - key.toLowerCase() === 'content-type' - ) { - request.contentType = val - if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend) - else request.headers += processHeaderValue(key, val) - } else if ( - key.length === 17 && - key.toLowerCase() === 'transfer-encoding' - ) { - throw new InvalidArgumentError('invalid transfer-encoding header') - } else if ( - key.length === 10 && - key.toLowerCase() === 'connection' - ) { - const value = typeof val === 'string' ? val.toLowerCase() : null - if (value !== 'close' && value !== 'keep-alive') { - throw new InvalidArgumentError('invalid connection header') - } else if (value === 'close') { - request.reset = true + } + + const waitForDrain = () => new Promise((resolve, reject) => { + assert(callback === null) + + if (socket[kError]) { + reject(socket[kError]) + } else { + callback = resolve } - } else if ( - key.length === 10 && - key.toLowerCase() === 'keep-alive' - ) { - throw new InvalidArgumentError('invalid keep-alive header') - } else if ( - key.length === 7 && - key.toLowerCase() === 'upgrade' - ) { - throw new InvalidArgumentError('invalid upgrade header') - } else if ( - key.length === 6 && - key.toLowerCase() === 'expect' - ) { - throw new NotSupportedError('expect header not supported') - } else if (tokenRegExp.exec(key) === null) { - throw new InvalidArgumentError('invalid header key') - } else { - if (Array.isArray(val)) { - for (let i = 0; i < val.length; i++) { - if (skipAppend) { - if (request.headers[key]) request.headers[key] += `,${processHeaderValue(key, val[i], skipAppend)}` - else request.headers[key] = processHeaderValue(key, val[i], skipAppend) - } else { - request.headers += processHeaderValue(key, val[i]) + }) + + if (client[kHTTPConnVersion] === 'h2') { + h2stream + .on('close', onDrain) + .on('drain', onDrain) + + try { + // It's up to the user to somehow abort the async iterable. + for await (const chunk of body) { + if (socket[kError]) { + throw socket[kError] + } + + const res = h2stream.write(chunk) + request.onBodySent(chunk) + if (!res) { + await waitForDrain() } } - } else { - if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend) - else request.headers += processHeaderValue(key, val) + } catch (err) { + h2stream.destroy(err) + } finally { + request.onRequestSent() + h2stream.end() + h2stream + .off('close', onDrain) + .off('drain', onDrain) } + + return } -} -module.exports = Request + socket + .on('close', onDrain) + .on('drain', onDrain) + const writer = new AsyncWriter({ socket, request, contentLength, client, expectsPayload, header }) + try { + // It's up to the user to somehow abort the async iterable. + for await (const chunk of body) { + if (socket[kError]) { + throw socket[kError] + } -/***/ }), + if (!writer.write(chunk)) { + await waitForDrain() + } + } -/***/ 2785: -/***/ ((module) => { + writer.end() + } catch (err) { + writer.destroy(err) + } finally { + socket + .off('close', onDrain) + .off('drain', onDrain) + } +} -module.exports = { - kClose: Symbol('close'), - kDestroy: Symbol('destroy'), - kDispatch: Symbol('dispatch'), - kUrl: Symbol('url'), - kWriting: Symbol('writing'), - kResuming: Symbol('resuming'), - kQueue: Symbol('queue'), - kConnect: Symbol('connect'), - kConnecting: Symbol('connecting'), - kHeadersList: Symbol('headers list'), - kKeepAliveDefaultTimeout: Symbol('default keep alive timeout'), - kKeepAliveMaxTimeout: Symbol('max keep alive timeout'), - kKeepAliveTimeoutThreshold: Symbol('keep alive timeout threshold'), - kKeepAliveTimeoutValue: Symbol('keep alive timeout'), - kKeepAlive: Symbol('keep alive'), - kHeadersTimeout: Symbol('headers timeout'), - kBodyTimeout: Symbol('body timeout'), - kServerName: Symbol('server name'), - kLocalAddress: Symbol('local address'), - kHost: Symbol('host'), - kNoRef: Symbol('no ref'), - kBodyUsed: Symbol('used'), - kRunning: Symbol('running'), - kBlocking: Symbol('blocking'), - kPending: Symbol('pending'), - kSize: Symbol('size'), - kBusy: Symbol('busy'), - kQueued: Symbol('queued'), - kFree: Symbol('free'), - kConnected: Symbol('connected'), - kClosed: Symbol('closed'), - kNeedDrain: Symbol('need drain'), - kReset: Symbol('reset'), - kDestroyed: Symbol.for('nodejs.stream.destroyed'), - kMaxHeadersSize: Symbol('max headers size'), - kRunningIdx: Symbol('running index'), - kPendingIdx: Symbol('pending index'), - kError: Symbol('error'), - kClients: Symbol('clients'), - kClient: Symbol('client'), - kParser: Symbol('parser'), - kOnDestroyed: Symbol('destroy callbacks'), - kPipelining: Symbol('pipelining'), - kSocket: Symbol('socket'), - kHostHeader: Symbol('host header'), - kConnector: Symbol('connector'), - kStrictContentLength: Symbol('strict content length'), - kMaxRedirections: Symbol('maxRedirections'), - kMaxRequests: Symbol('maxRequestsPerClient'), - kProxy: Symbol('proxy agent options'), - kCounter: Symbol('socket request counter'), - kInterceptors: Symbol('dispatch interceptors'), - kMaxResponseSize: Symbol('max response size'), - kHTTP2Session: Symbol('http2Session'), - kHTTP2SessionState: Symbol('http2Session state'), - kHTTP2BuildRequest: Symbol('http2 build request'), - kHTTP1BuildRequest: Symbol('http1 build request'), - kHTTP2CopyHeaders: Symbol('http2 copy headers'), - kHTTPConnVersion: Symbol('http connection version'), - kRetryHandlerDefaultRetry: Symbol('retry agent default retry'), - kConstruct: Symbol('constructable') -} +class AsyncWriter { + constructor ({ socket, request, contentLength, client, expectsPayload, header }) { + this.socket = socket + this.request = request + this.contentLength = contentLength + this.client = client + this.bytesWritten = 0 + this.expectsPayload = expectsPayload + this.header = header + socket[kWriting] = true + } -/***/ }), + write (chunk) { + const { socket, request, contentLength, client, bytesWritten, expectsPayload, header } = this -/***/ 3983: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (socket[kError]) { + throw socket[kError] + } -"use strict"; + if (socket.destroyed) { + return false + } + const len = Buffer.byteLength(chunk) + if (!len) { + return true + } -const assert = __nccwpck_require__(9491) -const { kDestroyed, kBodyUsed } = __nccwpck_require__(2785) -const { IncomingMessage } = __nccwpck_require__(3685) -const stream = __nccwpck_require__(2781) -const net = __nccwpck_require__(1808) -const { InvalidArgumentError } = __nccwpck_require__(8045) -const { Blob } = __nccwpck_require__(4300) -const nodeUtil = __nccwpck_require__(3837) -const { stringify } = __nccwpck_require__(3477) + // We should defer writing chunks. + if (contentLength !== null && bytesWritten + len > contentLength) { + if (client[kStrictContentLength]) { + throw new RequestContentLengthMismatchError() + } -const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(v => Number(v)) + process.emitWarning(new RequestContentLengthMismatchError()) + } -function nop () {} + socket.cork() -function isStream (obj) { - return obj && typeof obj === 'object' && typeof obj.pipe === 'function' && typeof obj.on === 'function' -} + if (bytesWritten === 0) { + if (!expectsPayload) { + socket[kReset] = true + } -// based on https://github.com/node-fetch/fetch-blob/blob/8ab587d34080de94140b54f07168451e7d0b655e/index.js#L229-L241 (MIT License) -function isBlobLike (object) { - return (Blob && object instanceof Blob) || ( - object && - typeof object === 'object' && - (typeof object.stream === 'function' || - typeof object.arrayBuffer === 'function') && - /^(Blob|File)$/.test(object[Symbol.toStringTag]) - ) -} + if (contentLength === null) { + socket.write(`${header}transfer-encoding: chunked\r\n`, 'latin1') + } else { + socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') + } + } -function buildURL (url, queryParams) { - if (url.includes('?') || url.includes('#')) { - throw new Error('Query params cannot be passed when url already contains "?" or "#".') - } + if (contentLength === null) { + socket.write(`\r\n${len.toString(16)}\r\n`, 'latin1') + } - const stringified = stringify(queryParams) + this.bytesWritten += len - if (stringified) { - url += '?' + stringified - } + const ret = socket.write(chunk) - return url -} + socket.uncork() -function parseURL (url) { - if (typeof url === 'string') { - url = new URL(url) + request.onBodySent(chunk) - if (!/^https?:/.test(url.origin || url.protocol)) { - throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') + if (!ret) { + if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { + // istanbul ignore else: only for jest + if (socket[kParser].timeout.refresh) { + socket[kParser].timeout.refresh() + } + } } - return url + return ret } - if (!url || typeof url !== 'object') { - throw new InvalidArgumentError('Invalid URL: The URL argument must be a non-null object.') - } + end () { + const { socket, contentLength, client, bytesWritten, expectsPayload, header, request } = this + request.onRequestSent() - if (!/^https?:/.test(url.origin || url.protocol)) { - throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') - } + socket[kWriting] = false - if (!(url instanceof URL)) { - if (url.port != null && url.port !== '' && !Number.isFinite(parseInt(url.port))) { - throw new InvalidArgumentError('Invalid URL: port must be a valid integer or a string representation of an integer.') + if (socket[kError]) { + throw socket[kError] } - if (url.path != null && typeof url.path !== 'string') { - throw new InvalidArgumentError('Invalid URL path: the path must be a string or null/undefined.') + if (socket.destroyed) { + return } - if (url.pathname != null && typeof url.pathname !== 'string') { - throw new InvalidArgumentError('Invalid URL pathname: the pathname must be a string or null/undefined.') - } + if (bytesWritten === 0) { + if (expectsPayload) { + // https://tools.ietf.org/html/rfc7230#section-3.3.2 + // A user agent SHOULD send a Content-Length in a request message when + // no Transfer-Encoding is sent and the request method defines a meaning + // for an enclosed payload body. - if (url.hostname != null && typeof url.hostname !== 'string') { - throw new InvalidArgumentError('Invalid URL hostname: the hostname must be a string or null/undefined.') + socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1') + } else { + socket.write(`${header}\r\n`, 'latin1') + } + } else if (contentLength === null) { + socket.write('\r\n0\r\n\r\n', 'latin1') } - if (url.origin != null && typeof url.origin !== 'string') { - throw new InvalidArgumentError('Invalid URL origin: the origin must be a string or null/undefined.') + if (contentLength !== null && bytesWritten !== contentLength) { + if (client[kStrictContentLength]) { + throw new RequestContentLengthMismatchError() + } else { + process.emitWarning(new RequestContentLengthMismatchError()) + } } - const port = url.port != null - ? url.port - : (url.protocol === 'https:' ? 443 : 80) - let origin = url.origin != null - ? url.origin - : `${url.protocol}//${url.hostname}:${port}` - let path = url.path != null - ? url.path - : `${url.pathname || ''}${url.search || ''}` - - if (origin.endsWith('/')) { - origin = origin.substring(0, origin.length - 1) + if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { + // istanbul ignore else: only for jest + if (socket[kParser].timeout.refresh) { + socket[kParser].timeout.refresh() + } } - if (path && !path.startsWith('/')) { - path = `/${path}` - } - // new URL(path, origin) is unsafe when `path` contains an absolute URL - // From https://developer.mozilla.org/en-US/docs/Web/API/URL/URL: - // If first parameter is a relative URL, second param is required, and will be used as the base URL. - // If first parameter is an absolute URL, a given second param will be ignored. - url = new URL(origin + path) + resume(client) } - return url -} + destroy (err) { + const { socket, client } = this -function parseOrigin (url) { - url = parseURL(url) + socket[kWriting] = false - if (url.pathname !== '/' || url.search || url.hash) { - throw new InvalidArgumentError('invalid url') + if (err) { + assert(client[kRunning] <= 1, 'pipeline should only contain this request') + util.destroy(socket, err) + } } +} - return url +function errorRequest (client, request, err) { + try { + request.onError(err) + assert(request.aborted) + } catch (err) { + client.emit('error', err) + } } -function getHostname (host) { - if (host[0] === '[') { - const idx = host.indexOf(']') +module.exports = Client - assert(idx !== -1) - return host.substring(1, idx) - } - const idx = host.indexOf(':') - if (idx === -1) return host +/***/ }), - return host.substring(0, idx) -} +/***/ 6436: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -// IP addresses are not valid server names per RFC6066 -// > Currently, the only server names supported are DNS hostnames -function getServerName (host) { - if (!host) { - return null - } +"use strict"; - assert.strictEqual(typeof host, 'string') - const servername = getHostname(host) - if (net.isIP(servername)) { - return '' +/* istanbul ignore file: only for Node 12 */ + +const { kConnected, kSize } = __nccwpck_require__(2785) + +class CompatWeakRef { + constructor (value) { + this.value = value } - return servername + deref () { + return this.value[kConnected] === 0 && this.value[kSize] === 0 + ? undefined + : this.value + } } -function deepClone (obj) { - return JSON.parse(JSON.stringify(obj)) -} +class CompatFinalizer { + constructor (finalizer) { + this.finalizer = finalizer + } -function isAsyncIterable (obj) { - return !!(obj != null && typeof obj[Symbol.asyncIterator] === 'function') + register (dispatcher, key) { + if (dispatcher.on) { + dispatcher.on('disconnect', () => { + if (dispatcher[kConnected] === 0 && dispatcher[kSize] === 0) { + this.finalizer(key) + } + }) + } + } } -function isIterable (obj) { - return !!(obj != null && (typeof obj[Symbol.iterator] === 'function' || typeof obj[Symbol.asyncIterator] === 'function')) +module.exports = function () { + // FIXME: remove workaround when the Node bug is fixed + // https://github.com/nodejs/node/issues/49344#issuecomment-1741776308 + if (process.env.NODE_V8_COVERAGE) { + return { + WeakRef: CompatWeakRef, + FinalizationRegistry: CompatFinalizer + } + } + return { + WeakRef: global.WeakRef || CompatWeakRef, + FinalizationRegistry: global.FinalizationRegistry || CompatFinalizer + } } -function bodyLength (body) { - if (body == null) { - return 0 - } else if (isStream(body)) { - const state = body._readableState - return state && state.objectMode === false && state.ended === true && Number.isFinite(state.length) - ? state.length - : null - } else if (isBlobLike(body)) { - return body.size != null ? body.size : null - } else if (isBuffer(body)) { - return body.byteLength - } - return null -} +/***/ }), -function isDestroyed (stream) { - return !stream || !!(stream.destroyed || stream[kDestroyed]) -} +/***/ 663: +/***/ ((module) => { -function isReadableAborted (stream) { - const state = stream && stream._readableState - return isDestroyed(stream) && state && !state.endEmitted -} +"use strict"; -function destroy (stream, err) { - if (stream == null || !isStream(stream) || isDestroyed(stream)) { - return - } - if (typeof stream.destroy === 'function') { - if (Object.getPrototypeOf(stream).constructor === IncomingMessage) { - // See: https://github.com/nodejs/node/pull/38505/files - stream.socket = null - } +// https://wicg.github.io/cookie-store/#cookie-maximum-attribute-value-size +const maxAttributeValueSize = 1024 - stream.destroy(err) - } else if (err) { - process.nextTick((stream, err) => { - stream.emit('error', err) - }, stream, err) - } +// https://wicg.github.io/cookie-store/#cookie-maximum-name-value-pair-size +const maxNameValuePairSize = 4096 - if (stream.destroyed !== true) { - stream[kDestroyed] = true - } +module.exports = { + maxAttributeValueSize, + maxNameValuePairSize } -const KEEPALIVE_TIMEOUT_EXPR = /timeout=(\d+)/ -function parseKeepAliveTimeout (val) { - const m = val.toString().match(KEEPALIVE_TIMEOUT_EXPR) - return m ? parseInt(m[1], 10) * 1000 : null -} -function parseHeaders (headers, obj = {}) { - // For H2 support - if (!Array.isArray(headers)) return headers +/***/ }), - for (let i = 0; i < headers.length; i += 2) { - const key = headers[i].toString().toLowerCase() - let val = obj[key] +/***/ 1724: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (!val) { - if (Array.isArray(headers[i + 1])) { - obj[key] = headers[i + 1].map(x => x.toString('utf8')) - } else { - obj[key] = headers[i + 1].toString('utf8') - } - } else { - if (!Array.isArray(val)) { - val = [val] - obj[key] = val - } - val.push(headers[i + 1].toString('utf8')) - } - } +"use strict"; - // See https://github.com/nodejs/node/pull/46528 - if ('content-length' in obj && 'content-disposition' in obj) { - obj['content-disposition'] = Buffer.from(obj['content-disposition']).toString('latin1') - } - return obj -} +const { parseSetCookie } = __nccwpck_require__(4408) +const { stringify, getHeadersList } = __nccwpck_require__(3121) +const { webidl } = __nccwpck_require__(1744) +const { Headers } = __nccwpck_require__(554) -function parseRawHeaders (headers) { - const ret = [] - let hasContentLength = false - let contentDispositionIdx = -1 +/** + * @typedef {Object} Cookie + * @property {string} name + * @property {string} value + * @property {Date|number|undefined} expires + * @property {number|undefined} maxAge + * @property {string|undefined} domain + * @property {string|undefined} path + * @property {boolean|undefined} secure + * @property {boolean|undefined} httpOnly + * @property {'Strict'|'Lax'|'None'} sameSite + * @property {string[]} unparsed + */ - for (let n = 0; n < headers.length; n += 2) { - const key = headers[n + 0].toString() - const val = headers[n + 1].toString('utf8') +/** + * @param {Headers} headers + * @returns {Record} + */ +function getCookies (headers) { + webidl.argumentLengthCheck(arguments, 1, { header: 'getCookies' }) - if (key.length === 14 && (key === 'content-length' || key.toLowerCase() === 'content-length')) { - ret.push(key, val) - hasContentLength = true - } else if (key.length === 19 && (key === 'content-disposition' || key.toLowerCase() === 'content-disposition')) { - contentDispositionIdx = ret.push(key, val) - 1 - } else { - ret.push(key, val) - } + webidl.brandCheck(headers, Headers, { strict: false }) + + const cookie = headers.get('cookie') + const out = {} + + if (!cookie) { + return out } - // See https://github.com/nodejs/node/pull/46528 - if (hasContentLength && contentDispositionIdx !== -1) { - ret[contentDispositionIdx] = Buffer.from(ret[contentDispositionIdx]).toString('latin1') + for (const piece of cookie.split(';')) { + const [name, ...value] = piece.split('=') + + out[name.trim()] = value.join('=') } - return ret + return out } -function isBuffer (buffer) { - // See, https://github.com/mcollina/undici/pull/319 - return buffer instanceof Uint8Array || Buffer.isBuffer(buffer) +/** + * @param {Headers} headers + * @param {string} name + * @param {{ path?: string, domain?: string }|undefined} attributes + * @returns {void} + */ +function deleteCookie (headers, name, attributes) { + webidl.argumentLengthCheck(arguments, 2, { header: 'deleteCookie' }) + + webidl.brandCheck(headers, Headers, { strict: false }) + + name = webidl.converters.DOMString(name) + attributes = webidl.converters.DeleteCookieAttributes(attributes) + + // Matches behavior of + // https://github.com/denoland/deno_std/blob/63827b16330b82489a04614027c33b7904e08be5/http/cookie.ts#L278 + setCookie(headers, { + name, + value: '', + expires: new Date(0), + ...attributes + }) } -function validateHandler (handler, method, upgrade) { - if (!handler || typeof handler !== 'object') { - throw new InvalidArgumentError('handler must be an object') - } +/** + * @param {Headers} headers + * @returns {Cookie[]} + */ +function getSetCookies (headers) { + webidl.argumentLengthCheck(arguments, 1, { header: 'getSetCookies' }) - if (typeof handler.onConnect !== 'function') { - throw new InvalidArgumentError('invalid onConnect method') - } + webidl.brandCheck(headers, Headers, { strict: false }) - if (typeof handler.onError !== 'function') { - throw new InvalidArgumentError('invalid onError method') - } + const cookies = getHeadersList(headers).cookies - if (typeof handler.onBodySent !== 'function' && handler.onBodySent !== undefined) { - throw new InvalidArgumentError('invalid onBodySent method') + if (!cookies) { + return [] } - if (upgrade || method === 'CONNECT') { - if (typeof handler.onUpgrade !== 'function') { - throw new InvalidArgumentError('invalid onUpgrade method') - } - } else { - if (typeof handler.onHeaders !== 'function') { - throw new InvalidArgumentError('invalid onHeaders method') - } - - if (typeof handler.onData !== 'function') { - throw new InvalidArgumentError('invalid onData method') - } - - if (typeof handler.onComplete !== 'function') { - throw new InvalidArgumentError('invalid onComplete method') - } - } + // In older versions of undici, cookies is a list of name:value. + return cookies.map((pair) => parseSetCookie(Array.isArray(pair) ? pair[1] : pair)) } -// A body is disturbed if it has been read from and it cannot -// be re-used without losing state or data. -function isDisturbed (body) { - return !!(body && ( - stream.isDisturbed - ? stream.isDisturbed(body) || body[kBodyUsed] // TODO (fix): Why is body[kBodyUsed] needed? - : body[kBodyUsed] || - body.readableDidRead || - (body._readableState && body._readableState.dataEmitted) || - isReadableAborted(body) - )) -} +/** + * @param {Headers} headers + * @param {Cookie} cookie + * @returns {void} + */ +function setCookie (headers, cookie) { + webidl.argumentLengthCheck(arguments, 2, { header: 'setCookie' }) -function isErrored (body) { - return !!(body && ( - stream.isErrored - ? stream.isErrored(body) - : /state: 'errored'/.test(nodeUtil.inspect(body) - ))) -} + webidl.brandCheck(headers, Headers, { strict: false }) -function isReadable (body) { - return !!(body && ( - stream.isReadable - ? stream.isReadable(body) - : /state: 'readable'/.test(nodeUtil.inspect(body) - ))) -} + cookie = webidl.converters.Cookie(cookie) -function getSocketInfo (socket) { - return { - localAddress: socket.localAddress, - localPort: socket.localPort, - remoteAddress: socket.remoteAddress, - remotePort: socket.remotePort, - remoteFamily: socket.remoteFamily, - timeout: socket.timeout, - bytesWritten: socket.bytesWritten, - bytesRead: socket.bytesRead - } -} + const str = stringify(cookie) -async function * convertIterableToBuffer (iterable) { - for await (const chunk of iterable) { - yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk) + if (str) { + headers.append('Set-Cookie', stringify(cookie)) } } -let ReadableStream -function ReadableStreamFrom (iterable) { - if (!ReadableStream) { - ReadableStream = (__nccwpck_require__(5356).ReadableStream) +webidl.converters.DeleteCookieAttributes = webidl.dictionaryConverter([ + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'path', + defaultValue: null + }, + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'domain', + defaultValue: null } +]) - if (ReadableStream.from) { - return ReadableStream.from(convertIterableToBuffer(iterable)) +webidl.converters.Cookie = webidl.dictionaryConverter([ + { + converter: webidl.converters.DOMString, + key: 'name' + }, + { + converter: webidl.converters.DOMString, + key: 'value' + }, + { + converter: webidl.nullableConverter((value) => { + if (typeof value === 'number') { + return webidl.converters['unsigned long long'](value) + } + + return new Date(value) + }), + key: 'expires', + defaultValue: null + }, + { + converter: webidl.nullableConverter(webidl.converters['long long']), + key: 'maxAge', + defaultValue: null + }, + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'domain', + defaultValue: null + }, + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'path', + defaultValue: null + }, + { + converter: webidl.nullableConverter(webidl.converters.boolean), + key: 'secure', + defaultValue: null + }, + { + converter: webidl.nullableConverter(webidl.converters.boolean), + key: 'httpOnly', + defaultValue: null + }, + { + converter: webidl.converters.USVString, + key: 'sameSite', + allowedValues: ['Strict', 'Lax', 'None'] + }, + { + converter: webidl.sequenceConverter(webidl.converters.DOMString), + key: 'unparsed', + defaultValue: [] } +]) - let iterator - return new ReadableStream( - { - async start () { - iterator = iterable[Symbol.asyncIterator]() - }, - async pull (controller) { - const { done, value } = await iterator.next() - if (done) { - queueMicrotask(() => { - controller.close() - }) - } else { - const buf = Buffer.isBuffer(value) ? value : Buffer.from(value) - controller.enqueue(new Uint8Array(buf)) - } - return controller.desiredSize > 0 - }, - async cancel (reason) { - await iterator.return() - } - }, - 0 - ) +module.exports = { + getCookies, + deleteCookie, + getSetCookies, + setCookie } -// The chunk should be a FormData instance and contains -// all the required methods. -function isFormDataLike (object) { - return ( - object && - typeof object === 'object' && - typeof object.append === 'function' && - typeof object.delete === 'function' && - typeof object.get === 'function' && - typeof object.getAll === 'function' && - typeof object.has === 'function' && - typeof object.set === 'function' && - object[Symbol.toStringTag] === 'FormData' - ) -} -function throwIfAborted (signal) { - if (!signal) { return } - if (typeof signal.throwIfAborted === 'function') { - signal.throwIfAborted() - } else { - if (signal.aborted) { - // DOMException not available < v17.0.0 - const err = new Error('The operation was aborted') - err.name = 'AbortError' - throw err - } - } -} +/***/ }), -function addAbortListener (signal, listener) { - if ('addEventListener' in signal) { - signal.addEventListener('abort', listener, { once: true }) - return () => signal.removeEventListener('abort', listener) - } - signal.addListener('abort', listener) - return () => signal.removeListener('abort', listener) -} +/***/ 4408: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -const hasToWellFormed = !!String.prototype.toWellFormed +"use strict"; + + +const { maxNameValuePairSize, maxAttributeValueSize } = __nccwpck_require__(663) +const { isCTLExcludingHtab } = __nccwpck_require__(3121) +const { collectASequenceOfCodePointsFast } = __nccwpck_require__(685) +const assert = __nccwpck_require__(9491) /** - * @param {string} val + * @description Parses the field-value attributes of a set-cookie header string. + * @see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4 + * @param {string} header + * @returns if the header is invalid, null will be returned */ -function toUSVString (val) { - if (hasToWellFormed) { - return `${val}`.toWellFormed() - } else if (nodeUtil.toUSVString) { - return nodeUtil.toUSVString(val) +function parseSetCookie (header) { + // 1. If the set-cookie-string contains a %x00-08 / %x0A-1F / %x7F + // character (CTL characters excluding HTAB): Abort these steps and + // ignore the set-cookie-string entirely. + if (isCTLExcludingHtab(header)) { + return null } - return `${val}` -} + let nameValuePair = '' + let unparsedAttributes = '' + let name = '' + let value = '' -// Parsed accordingly to RFC 9110 -// https://www.rfc-editor.org/rfc/rfc9110#field.content-range -function parseRangeHeader (range) { - if (range == null || range === '') return { start: 0, end: null, size: null } + // 2. If the set-cookie-string contains a %x3B (";") character: + if (header.includes(';')) { + // 1. The name-value-pair string consists of the characters up to, + // but not including, the first %x3B (";"), and the unparsed- + // attributes consist of the remainder of the set-cookie-string + // (including the %x3B (";") in question). + const position = { position: 0 } - const m = range ? range.match(/^bytes (\d+)-(\d+)\/(\d+)?$/) : null - return m - ? { - start: parseInt(m[1]), - end: m[2] ? parseInt(m[2]) : null, - size: m[3] ? parseInt(m[3]) : null - } - : null -} + nameValuePair = collectASequenceOfCodePointsFast(';', header, position) + unparsedAttributes = header.slice(position.position) + } else { + // Otherwise: -const kEnumerableProperty = Object.create(null) -kEnumerableProperty.enumerable = true + // 1. The name-value-pair string consists of all the characters + // contained in the set-cookie-string, and the unparsed- + // attributes is the empty string. + nameValuePair = header + } -module.exports = { - kEnumerableProperty, - nop, - isDisturbed, - isErrored, - isReadable, - toUSVString, - isReadableAborted, - isBlobLike, - parseOrigin, - parseURL, - getServerName, - isStream, - isIterable, - isAsyncIterable, - isDestroyed, - parseRawHeaders, - parseHeaders, - parseKeepAliveTimeout, - destroy, - bodyLength, - deepClone, - ReadableStreamFrom, - isBuffer, - validateHandler, - getSocketInfo, - isFormDataLike, - buildURL, - throwIfAborted, - addAbortListener, - parseRangeHeader, - nodeMajor, - nodeMinor, - nodeHasAutoSelectFamily: nodeMajor > 18 || (nodeMajor === 18 && nodeMinor >= 13), - safeHTTPMethods: ['GET', 'HEAD', 'OPTIONS', 'TRACE'] + // 3. If the name-value-pair string lacks a %x3D ("=") character, then + // the name string is empty, and the value string is the value of + // name-value-pair. + if (!nameValuePair.includes('=')) { + value = nameValuePair + } else { + // Otherwise, the name string consists of the characters up to, but + // not including, the first %x3D ("=") character, and the (possibly + // empty) value string consists of the characters after the first + // %x3D ("=") character. + const position = { position: 0 } + name = collectASequenceOfCodePointsFast( + '=', + nameValuePair, + position + ) + value = nameValuePair.slice(position.position + 1) + } + + // 4. Remove any leading or trailing WSP characters from the name + // string and the value string. + name = name.trim() + value = value.trim() + + // 5. If the sum of the lengths of the name string and the value string + // is more than 4096 octets, abort these steps and ignore the set- + // cookie-string entirely. + if (name.length + value.length > maxNameValuePairSize) { + return null + } + + // 6. The cookie-name is the name string, and the cookie-value is the + // value string. + return { + name, value, ...parseUnparsedAttributes(unparsedAttributes) + } } +/** + * Parses the remaining attributes of a set-cookie header + * @see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4 + * @param {string} unparsedAttributes + * @param {[Object.]={}} cookieAttributeList + */ +function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {}) { + // 1. If the unparsed-attributes string is empty, skip the rest of + // these steps. + if (unparsedAttributes.length === 0) { + return cookieAttributeList + } -/***/ }), + // 2. Discard the first character of the unparsed-attributes (which + // will be a %x3B (";") character). + assert(unparsedAttributes[0] === ';') + unparsedAttributes = unparsedAttributes.slice(1) -/***/ 4839: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + let cookieAv = '' -"use strict"; + // 3. If the remaining unparsed-attributes contains a %x3B (";") + // character: + if (unparsedAttributes.includes(';')) { + // 1. Consume the characters of the unparsed-attributes up to, but + // not including, the first %x3B (";") character. + cookieAv = collectASequenceOfCodePointsFast( + ';', + unparsedAttributes, + { position: 0 } + ) + unparsedAttributes = unparsedAttributes.slice(cookieAv.length) + } else { + // Otherwise: + // 1. Consume the remainder of the unparsed-attributes. + cookieAv = unparsedAttributes + unparsedAttributes = '' + } -const Dispatcher = __nccwpck_require__(412) -const { - ClientDestroyedError, - ClientClosedError, - InvalidArgumentError -} = __nccwpck_require__(8045) -const { kDestroy, kClose, kDispatch, kInterceptors } = __nccwpck_require__(2785) + // Let the cookie-av string be the characters consumed in this step. -const kDestroyed = Symbol('destroyed') -const kClosed = Symbol('closed') -const kOnDestroyed = Symbol('onDestroyed') -const kOnClosed = Symbol('onClosed') -const kInterceptedDispatch = Symbol('Intercepted Dispatch') + let attributeName = '' + let attributeValue = '' -class DispatcherBase extends Dispatcher { - constructor () { - super() + // 4. If the cookie-av string contains a %x3D ("=") character: + if (cookieAv.includes('=')) { + // 1. The (possibly empty) attribute-name string consists of the + // characters up to, but not including, the first %x3D ("=") + // character, and the (possibly empty) attribute-value string + // consists of the characters after the first %x3D ("=") + // character. + const position = { position: 0 } - this[kDestroyed] = false - this[kOnDestroyed] = null - this[kClosed] = false - this[kOnClosed] = [] - } + attributeName = collectASequenceOfCodePointsFast( + '=', + cookieAv, + position + ) + attributeValue = cookieAv.slice(position.position + 1) + } else { + // Otherwise: - get destroyed () { - return this[kDestroyed] + // 1. The attribute-name string consists of the entire cookie-av + // string, and the attribute-value string is empty. + attributeName = cookieAv } - get closed () { - return this[kClosed] - } + // 5. Remove any leading or trailing WSP characters from the attribute- + // name string and the attribute-value string. + attributeName = attributeName.trim() + attributeValue = attributeValue.trim() - get interceptors () { - return this[kInterceptors] + // 6. If the attribute-value is longer than 1024 octets, ignore the + // cookie-av string and return to Step 1 of this algorithm. + if (attributeValue.length > maxAttributeValueSize) { + return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) } - set interceptors (newInterceptors) { - if (newInterceptors) { - for (let i = newInterceptors.length - 1; i >= 0; i--) { - const interceptor = this[kInterceptors][i] - if (typeof interceptor !== 'function') { - throw new InvalidArgumentError('interceptor must be an function') - } - } - } + // 7. Process the attribute-name and attribute-value according to the + // requirements in the following subsections. (Notice that + // attributes with unrecognized attribute-names are ignored.) + const attributeNameLowercase = attributeName.toLowerCase() - this[kInterceptors] = newInterceptors - } + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.1 + // If the attribute-name case-insensitively matches the string + // "Expires", the user agent MUST process the cookie-av as follows. + if (attributeNameLowercase === 'expires') { + // 1. Let the expiry-time be the result of parsing the attribute-value + // as cookie-date (see Section 5.1.1). + const expiryTime = new Date(attributeValue) - close (callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - this.close((err, data) => { - return err ? reject(err) : resolve(data) - }) - }) - } + // 2. If the attribute-value failed to parse as a cookie date, ignore + // the cookie-av. - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } + cookieAttributeList.expires = expiryTime + } else if (attributeNameLowercase === 'max-age') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.2 + // If the attribute-name case-insensitively matches the string "Max- + // Age", the user agent MUST process the cookie-av as follows. - if (this[kDestroyed]) { - queueMicrotask(() => callback(new ClientDestroyedError(), null)) - return + // 1. If the first character of the attribute-value is not a DIGIT or a + // "-" character, ignore the cookie-av. + const charCode = attributeValue.charCodeAt(0) + + if ((charCode < 48 || charCode > 57) && attributeValue[0] !== '-') { + return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) } - if (this[kClosed]) { - if (this[kOnClosed]) { - this[kOnClosed].push(callback) - } else { - queueMicrotask(() => callback(null, null)) - } - return + // 2. If the remainder of attribute-value contains a non-DIGIT + // character, ignore the cookie-av. + if (!/^\d+$/.test(attributeValue)) { + return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) } - this[kClosed] = true - this[kOnClosed].push(callback) + // 3. Let delta-seconds be the attribute-value converted to an integer. + const deltaSeconds = Number(attributeValue) - const onClosed = () => { - const callbacks = this[kOnClosed] - this[kOnClosed] = null - for (let i = 0; i < callbacks.length; i++) { - callbacks[i](null, null) - } - } + // 4. Let cookie-age-limit be the maximum age of the cookie (which + // SHOULD be 400 days or less, see Section 4.1.2.2). - // Should not error. - this[kClose]() - .then(() => this.destroy()) - .then(() => { - queueMicrotask(onClosed) - }) - } - - destroy (err, callback) { - if (typeof err === 'function') { - callback = err - err = null - } - - if (callback === undefined) { - return new Promise((resolve, reject) => { - this.destroy(err, (err, data) => { - return err ? /* istanbul ignore next: should never error */ reject(err) : resolve(data) - }) - }) - } - - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } + // 5. Set delta-seconds to the smaller of its present value and cookie- + // age-limit. + // deltaSeconds = Math.min(deltaSeconds * 1000, maxExpiresMs) - if (this[kDestroyed]) { - if (this[kOnDestroyed]) { - this[kOnDestroyed].push(callback) - } else { - queueMicrotask(() => callback(null, null)) - } - return - } + // 6. If delta-seconds is less than or equal to zero (0), let expiry- + // time be the earliest representable date and time. Otherwise, let + // the expiry-time be the current date and time plus delta-seconds + // seconds. + // const expiryTime = deltaSeconds <= 0 ? Date.now() : Date.now() + deltaSeconds - if (!err) { - err = new ClientDestroyedError() - } + // 7. Append an attribute to the cookie-attribute-list with an + // attribute-name of Max-Age and an attribute-value of expiry-time. + cookieAttributeList.maxAge = deltaSeconds + } else if (attributeNameLowercase === 'domain') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.3 + // If the attribute-name case-insensitively matches the string "Domain", + // the user agent MUST process the cookie-av as follows. - this[kDestroyed] = true - this[kOnDestroyed] = this[kOnDestroyed] || [] - this[kOnDestroyed].push(callback) + // 1. Let cookie-domain be the attribute-value. + let cookieDomain = attributeValue - const onDestroyed = () => { - const callbacks = this[kOnDestroyed] - this[kOnDestroyed] = null - for (let i = 0; i < callbacks.length; i++) { - callbacks[i](null, null) - } + // 2. If cookie-domain starts with %x2E ("."), let cookie-domain be + // cookie-domain without its leading %x2E ("."). + if (cookieDomain[0] === '.') { + cookieDomain = cookieDomain.slice(1) } - // Should not error. - this[kDestroy](err).then(() => { - queueMicrotask(onDestroyed) - }) - } + // 3. Convert the cookie-domain to lower case. + cookieDomain = cookieDomain.toLowerCase() - [kInterceptedDispatch] (opts, handler) { - if (!this[kInterceptors] || this[kInterceptors].length === 0) { - this[kInterceptedDispatch] = this[kDispatch] - return this[kDispatch](opts, handler) - } + // 4. Append an attribute to the cookie-attribute-list with an + // attribute-name of Domain and an attribute-value of cookie-domain. + cookieAttributeList.domain = cookieDomain + } else if (attributeNameLowercase === 'path') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.4 + // If the attribute-name case-insensitively matches the string "Path", + // the user agent MUST process the cookie-av as follows. - let dispatch = this[kDispatch].bind(this) - for (let i = this[kInterceptors].length - 1; i >= 0; i--) { - dispatch = this[kInterceptors][i](dispatch) - } - this[kInterceptedDispatch] = dispatch - return dispatch(opts, handler) - } + // 1. If the attribute-value is empty or if the first character of the + // attribute-value is not %x2F ("/"): + let cookiePath = '' + if (attributeValue.length === 0 || attributeValue[0] !== '/') { + // 1. Let cookie-path be the default-path. + cookiePath = '/' + } else { + // Otherwise: - dispatch (opts, handler) { - if (!handler || typeof handler !== 'object') { - throw new InvalidArgumentError('handler must be an object') + // 1. Let cookie-path be the attribute-value. + cookiePath = attributeValue } - try { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('opts must be an object.') - } - - if (this[kDestroyed] || this[kOnDestroyed]) { - throw new ClientDestroyedError() - } + // 2. Append an attribute to the cookie-attribute-list with an + // attribute-name of Path and an attribute-value of cookie-path. + cookieAttributeList.path = cookiePath + } else if (attributeNameLowercase === 'secure') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.5 + // If the attribute-name case-insensitively matches the string "Secure", + // the user agent MUST append an attribute to the cookie-attribute-list + // with an attribute-name of Secure and an empty attribute-value. - if (this[kClosed]) { - throw new ClientClosedError() - } + cookieAttributeList.secure = true + } else if (attributeNameLowercase === 'httponly') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.6 + // If the attribute-name case-insensitively matches the string + // "HttpOnly", the user agent MUST append an attribute to the cookie- + // attribute-list with an attribute-name of HttpOnly and an empty + // attribute-value. - return this[kInterceptedDispatch](opts, handler) - } catch (err) { - if (typeof handler.onError !== 'function') { - throw new InvalidArgumentError('invalid onError method') - } + cookieAttributeList.httpOnly = true + } else if (attributeNameLowercase === 'samesite') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.7 + // If the attribute-name case-insensitively matches the string + // "SameSite", the user agent MUST process the cookie-av as follows: - handler.onError(err) + // 1. Let enforcement be "Default". + let enforcement = 'Default' - return false + const attributeValueLowercase = attributeValue.toLowerCase() + // 2. If cookie-av's attribute-value is a case-insensitive match for + // "None", set enforcement to "None". + if (attributeValueLowercase.includes('none')) { + enforcement = 'None' } - } -} - -module.exports = DispatcherBase - - -/***/ }), - -/***/ 412: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; + // 3. If cookie-av's attribute-value is a case-insensitive match for + // "Strict", set enforcement to "Strict". + if (attributeValueLowercase.includes('strict')) { + enforcement = 'Strict' + } -const EventEmitter = __nccwpck_require__(2361) + // 4. If cookie-av's attribute-value is a case-insensitive match for + // "Lax", set enforcement to "Lax". + if (attributeValueLowercase.includes('lax')) { + enforcement = 'Lax' + } -class Dispatcher extends EventEmitter { - dispatch () { - throw new Error('not implemented') - } + // 5. Append an attribute to the cookie-attribute-list with an + // attribute-name of "SameSite" and an attribute-value of + // enforcement. + cookieAttributeList.sameSite = enforcement + } else { + cookieAttributeList.unparsed ??= [] - close () { - throw new Error('not implemented') + cookieAttributeList.unparsed.push(`${attributeName}=${attributeValue}`) } - destroy () { - throw new Error('not implemented') - } + // 8. Return to Step 1 of this algorithm. + return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) } -module.exports = Dispatcher +module.exports = { + parseSetCookie, + parseUnparsedAttributes +} /***/ }), -/***/ 1472: +/***/ 3121: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const Busboy = __nccwpck_require__(727) -const util = __nccwpck_require__(3983) -const { - ReadableStreamFrom, - isBlobLike, - isReadableStreamLike, - readableStreamClose, - createDeferredPromise, - fullyReadBody -} = __nccwpck_require__(2538) -const { FormData } = __nccwpck_require__(2015) -const { kState } = __nccwpck_require__(5861) -const { webidl } = __nccwpck_require__(1744) -const { DOMException, structuredClone } = __nccwpck_require__(1037) -const { Blob, File: NativeFile } = __nccwpck_require__(4300) -const { kBodyUsed } = __nccwpck_require__(2785) const assert = __nccwpck_require__(9491) -const { isErrored } = __nccwpck_require__(3983) -const { isUint8Array, isArrayBuffer } = __nccwpck_require__(9830) -const { File: UndiciFile } = __nccwpck_require__(8511) -const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685) +const { kHeadersList } = __nccwpck_require__(2785) -let ReadableStream = globalThis.ReadableStream +function isCTLExcludingHtab (value) { + if (value.length === 0) { + return false + } -/** @type {globalThis['File']} */ -const File = NativeFile ?? UndiciFile -const textEncoder = new TextEncoder() -const textDecoder = new TextDecoder() + for (const char of value) { + const code = char.charCodeAt(0) -// https://fetch.spec.whatwg.org/#concept-bodyinit-extract -function extractBody (object, keepalive = false) { - if (!ReadableStream) { - ReadableStream = (__nccwpck_require__(5356).ReadableStream) + if ( + (code >= 0x00 || code <= 0x08) || + (code >= 0x0A || code <= 0x1F) || + code === 0x7F + ) { + return false + } } +} - // 1. Let stream be null. - let stream = null +/** + CHAR = + token = 1* + separators = "(" | ")" | "<" | ">" | "@" + | "," | ";" | ":" | "\" | <"> + | "/" | "[" | "]" | "?" | "=" + | "{" | "}" | SP | HT + * @param {string} name + */ +function validateCookieName (name) { + for (const char of name) { + const code = char.charCodeAt(0) - // 2. If object is a ReadableStream object, then set stream to object. - if (object instanceof ReadableStream) { - stream = object - } else if (isBlobLike(object)) { - // 3. Otherwise, if object is a Blob object, set stream to the - // result of running object’s get stream. - stream = object.stream() - } else { - // 4. Otherwise, set stream to a new ReadableStream object, and set - // up stream. - stream = new ReadableStream({ - async pull (controller) { - controller.enqueue( - typeof source === 'string' ? textEncoder.encode(source) : source - ) - queueMicrotask(() => readableStreamClose(controller)) - }, - start () {}, - type: undefined - }) + if ( + (code <= 0x20 || code > 0x7F) || + char === '(' || + char === ')' || + char === '>' || + char === '<' || + char === '@' || + char === ',' || + char === ';' || + char === ':' || + char === '\\' || + char === '"' || + char === '/' || + char === '[' || + char === ']' || + char === '?' || + char === '=' || + char === '{' || + char === '}' + ) { + throw new Error('Invalid cookie name') + } } +} - // 5. Assert: stream is a ReadableStream object. - assert(isReadableStreamLike(stream)) +/** + cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) + cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E + ; US-ASCII characters excluding CTLs, + ; whitespace DQUOTE, comma, semicolon, + ; and backslash + * @param {string} value + */ +function validateCookieValue (value) { + for (const char of value) { + const code = char.charCodeAt(0) - // 6. Let action be null. - let action = null + if ( + code < 0x21 || // exclude CTLs (0-31) + code === 0x22 || + code === 0x2C || + code === 0x3B || + code === 0x5C || + code > 0x7E // non-ascii + ) { + throw new Error('Invalid header value') + } + } +} - // 7. Let source be null. - let source = null +/** + * path-value = + * @param {string} path + */ +function validateCookiePath (path) { + for (const char of path) { + const code = char.charCodeAt(0) - // 8. Let length be null. - let length = null + if (code < 0x21 || char === ';') { + throw new Error('Invalid cookie path') + } + } +} - // 9. Let type be null. - let type = null +/** + * I have no idea why these values aren't allowed to be honest, + * but Deno tests these. - Khafra + * @param {string} domain + */ +function validateCookieDomain (domain) { + if ( + domain.startsWith('-') || + domain.endsWith('.') || + domain.endsWith('-') + ) { + throw new Error('Invalid cookie domain') + } +} - // 10. Switch on object: - if (typeof object === 'string') { - // Set source to the UTF-8 encoding of object. - // Note: setting source to a Uint8Array here breaks some mocking assumptions. - source = object +/** + * @see https://www.rfc-editor.org/rfc/rfc7231#section-7.1.1.1 + * @param {number|Date} date + IMF-fixdate = day-name "," SP date1 SP time-of-day SP GMT + ; fixed length/zone/capitalization subset of the format + ; see Section 3.3 of [RFC5322] - // Set type to `text/plain;charset=UTF-8`. - type = 'text/plain;charset=UTF-8' - } else if (object instanceof URLSearchParams) { - // URLSearchParams + day-name = %x4D.6F.6E ; "Mon", case-sensitive + / %x54.75.65 ; "Tue", case-sensitive + / %x57.65.64 ; "Wed", case-sensitive + / %x54.68.75 ; "Thu", case-sensitive + / %x46.72.69 ; "Fri", case-sensitive + / %x53.61.74 ; "Sat", case-sensitive + / %x53.75.6E ; "Sun", case-sensitive + date1 = day SP month SP year + ; e.g., 02 Jun 1982 - // spec says to run application/x-www-form-urlencoded on body.list - // this is implemented in Node.js as apart of an URLSearchParams instance toString method - // See: https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/lib/internal/url.js#L490 - // and https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/lib/internal/url.js#L1100 + day = 2DIGIT + month = %x4A.61.6E ; "Jan", case-sensitive + / %x46.65.62 ; "Feb", case-sensitive + / %x4D.61.72 ; "Mar", case-sensitive + / %x41.70.72 ; "Apr", case-sensitive + / %x4D.61.79 ; "May", case-sensitive + / %x4A.75.6E ; "Jun", case-sensitive + / %x4A.75.6C ; "Jul", case-sensitive + / %x41.75.67 ; "Aug", case-sensitive + / %x53.65.70 ; "Sep", case-sensitive + / %x4F.63.74 ; "Oct", case-sensitive + / %x4E.6F.76 ; "Nov", case-sensitive + / %x44.65.63 ; "Dec", case-sensitive + year = 4DIGIT - // Set source to the result of running the application/x-www-form-urlencoded serializer with object’s list. - source = object.toString() + GMT = %x47.4D.54 ; "GMT", case-sensitive - // Set type to `application/x-www-form-urlencoded;charset=UTF-8`. - type = 'application/x-www-form-urlencoded;charset=UTF-8' - } else if (isArrayBuffer(object)) { - // BufferSource/ArrayBuffer + time-of-day = hour ":" minute ":" second + ; 00:00:00 - 23:59:60 (leap second) - // Set source to a copy of the bytes held by object. - source = new Uint8Array(object.slice()) - } else if (ArrayBuffer.isView(object)) { - // BufferSource/ArrayBufferView + hour = 2DIGIT + minute = 2DIGIT + second = 2DIGIT + */ +function toIMFDate (date) { + if (typeof date === 'number') { + date = new Date(date) + } - // Set source to a copy of the bytes held by object. - source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength)) - } else if (util.isFormDataLike(object)) { - const boundary = `----formdata-undici-0${`${Math.floor(Math.random() * 1e11)}`.padStart(11, '0')}` - const prefix = `--${boundary}\r\nContent-Disposition: form-data` + const days = [ + 'Sun', 'Mon', 'Tue', 'Wed', + 'Thu', 'Fri', 'Sat' + ] - /*! formdata-polyfill. MIT License. Jimmy Wärting */ - const escape = (str) => - str.replace(/\n/g, '%0A').replace(/\r/g, '%0D').replace(/"/g, '%22') - const normalizeLinefeeds = (value) => value.replace(/\r?\n|\r/g, '\r\n') + const months = [ + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' + ] - // Set action to this step: run the multipart/form-data - // encoding algorithm, with object’s entry list and UTF-8. - // - This ensures that the body is immutable and can't be changed afterwords - // - That the content-length is calculated in advance. - // - And that all parts are pre-encoded and ready to be sent. + const dayName = days[date.getUTCDay()] + const day = date.getUTCDate().toString().padStart(2, '0') + const month = months[date.getUTCMonth()] + const year = date.getUTCFullYear() + const hour = date.getUTCHours().toString().padStart(2, '0') + const minute = date.getUTCMinutes().toString().padStart(2, '0') + const second = date.getUTCSeconds().toString().padStart(2, '0') - const blobParts = [] - const rn = new Uint8Array([13, 10]) // '\r\n' - length = 0 - let hasUnknownSizeValue = false + return `${dayName}, ${day} ${month} ${year} ${hour}:${minute}:${second} GMT` +} - for (const [name, value] of object) { - if (typeof value === 'string') { - const chunk = textEncoder.encode(prefix + - `; name="${escape(normalizeLinefeeds(name))}"` + - `\r\n\r\n${normalizeLinefeeds(value)}\r\n`) - blobParts.push(chunk) - length += chunk.byteLength - } else { - const chunk = textEncoder.encode(`${prefix}; name="${escape(normalizeLinefeeds(name))}"` + - (value.name ? `; filename="${escape(value.name)}"` : '') + '\r\n' + - `Content-Type: ${ - value.type || 'application/octet-stream' - }\r\n\r\n`) - blobParts.push(chunk, value, rn) - if (typeof value.size === 'number') { - length += chunk.byteLength + value.size + rn.byteLength - } else { - hasUnknownSizeValue = true - } - } - } +/** + max-age-av = "Max-Age=" non-zero-digit *DIGIT + ; In practice, both expires-av and max-age-av + ; are limited to dates representable by the + ; user agent. + * @param {number} maxAge + */ +function validateCookieMaxAge (maxAge) { + if (maxAge < 0) { + throw new Error('Invalid cookie max-age') + } +} - const chunk = textEncoder.encode(`--${boundary}--`) - blobParts.push(chunk) - length += chunk.byteLength - if (hasUnknownSizeValue) { - length = null - } +/** + * @see https://www.rfc-editor.org/rfc/rfc6265#section-4.1.1 + * @param {import('./index').Cookie} cookie + */ +function stringify (cookie) { + if (cookie.name.length === 0) { + return null + } - // Set source to object. - source = object + validateCookieName(cookie.name) + validateCookieValue(cookie.value) - action = async function * () { - for (const part of blobParts) { - if (part.stream) { - yield * part.stream() - } else { - yield part - } - } - } + const out = [`${cookie.name}=${cookie.value}`] - // Set type to `multipart/form-data; boundary=`, - // followed by the multipart/form-data boundary string generated - // by the multipart/form-data encoding algorithm. - type = 'multipart/form-data; boundary=' + boundary - } else if (isBlobLike(object)) { - // Blob + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.1 + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.2 + if (cookie.name.startsWith('__Secure-')) { + cookie.secure = true + } - // Set source to object. - source = object + if (cookie.name.startsWith('__Host-')) { + cookie.secure = true + cookie.domain = null + cookie.path = '/' + } - // Set length to object’s size. - length = object.size + if (cookie.secure) { + out.push('Secure') + } - // If object’s type attribute is not the empty byte sequence, set - // type to its value. - if (object.type) { - type = object.type - } - } else if (typeof object[Symbol.asyncIterator] === 'function') { - // If keepalive is true, then throw a TypeError. - if (keepalive) { - throw new TypeError('keepalive') - } + if (cookie.httpOnly) { + out.push('HttpOnly') + } - // If object is disturbed or locked, then throw a TypeError. - if (util.isDisturbed(object) || object.locked) { - throw new TypeError( - 'Response body object should not be disturbed or locked' - ) - } + if (typeof cookie.maxAge === 'number') { + validateCookieMaxAge(cookie.maxAge) + out.push(`Max-Age=${cookie.maxAge}`) + } - stream = - object instanceof ReadableStream ? object : ReadableStreamFrom(object) + if (cookie.domain) { + validateCookieDomain(cookie.domain) + out.push(`Domain=${cookie.domain}`) } - // 11. If source is a byte sequence, then set action to a - // step that returns source and length to source’s length. - if (typeof source === 'string' || util.isBuffer(source)) { - length = Buffer.byteLength(source) + if (cookie.path) { + validateCookiePath(cookie.path) + out.push(`Path=${cookie.path}`) } - // 12. If action is non-null, then run these steps in in parallel: - if (action != null) { - // Run action. - let iterator - stream = new ReadableStream({ - async start () { - iterator = action(object)[Symbol.asyncIterator]() - }, - async pull (controller) { - const { value, done } = await iterator.next() - if (done) { - // When running action is done, close stream. - queueMicrotask(() => { - controller.close() - }) - } else { - // Whenever one or more bytes are available and stream is not errored, - // enqueue a Uint8Array wrapping an ArrayBuffer containing the available - // bytes into stream. - if (!isErrored(stream)) { - controller.enqueue(new Uint8Array(value)) - } - } - return controller.desiredSize > 0 - }, - async cancel (reason) { - await iterator.return() - }, - type: undefined - }) + if (cookie.expires && cookie.expires.toString() !== 'Invalid Date') { + out.push(`Expires=${toIMFDate(cookie.expires)}`) } - // 13. Let body be a body whose stream is stream, source is source, - // and length is length. - const body = { stream, source, length } + if (cookie.sameSite) { + out.push(`SameSite=${cookie.sameSite}`) + } - // 14. Return (body, type). - return [body, type] + for (const part of cookie.unparsed) { + if (!part.includes('=')) { + throw new Error('Invalid unparsed') + } + + const [key, ...value] = part.split('=') + + out.push(`${key.trim()}=${value.join('=')}`) + } + + return out.join('; ') } -// https://fetch.spec.whatwg.org/#bodyinit-safely-extract -function safelyExtractBody (object, keepalive = false) { - if (!ReadableStream) { - // istanbul ignore next - ReadableStream = (__nccwpck_require__(5356).ReadableStream) +let kHeadersListNode + +function getHeadersList (headers) { + if (headers[kHeadersList]) { + return headers[kHeadersList] } - // To safely extract a body and a `Content-Type` value from - // a byte sequence or BodyInit object object, run these steps: + if (!kHeadersListNode) { + kHeadersListNode = Object.getOwnPropertySymbols(headers).find( + (symbol) => symbol.description === 'headers list' + ) - // 1. If object is a ReadableStream object, then: - if (object instanceof ReadableStream) { - // Assert: object is neither disturbed nor locked. - // istanbul ignore next - assert(!util.isDisturbed(object), 'The body has already been consumed.') - // istanbul ignore next - assert(!object.locked, 'The stream is locked.') + assert(kHeadersListNode, 'Headers cannot be parsed') } - // 2. Return the results of extracting object. - return extractBody(object, keepalive) + const headersList = headers[kHeadersListNode] + assert(headersList) + + return headersList } -function cloneBody (body) { - // To clone a body body, run these steps: +module.exports = { + isCTLExcludingHtab, + stringify, + getHeadersList +} - // https://fetch.spec.whatwg.org/#concept-body-clone - // 1. Let « out1, out2 » be the result of teeing body’s stream. - const [out1, out2] = body.stream.tee() - const out2Clone = structuredClone(out2, { transfer: [out2] }) - // This, for whatever reasons, unrefs out2Clone which allows - // the process to exit by itself. - const [, finalClone] = out2Clone.tee() +/***/ }), - // 2. Set body’s stream to out1. - body.stream = out1 +/***/ 2067: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // 3. Return a body whose stream is out2 and other members are copied from body. - return { - stream: finalClone, - length: body.length, - source: body.source - } -} +"use strict"; -async function * consumeBody (body) { - if (body) { - if (isUint8Array(body)) { - yield body - } else { - const stream = body.stream - if (util.isDisturbed(stream)) { - throw new TypeError('The body has already been consumed.') +const net = __nccwpck_require__(1808) +const assert = __nccwpck_require__(9491) +const util = __nccwpck_require__(3983) +const { InvalidArgumentError, ConnectTimeoutError } = __nccwpck_require__(8045) + +let tls // include tls conditionally since it is not always available + +// TODO: session re-use does not wait for the first +// connection to resolve the session and might therefore +// resolve the same servername multiple times even when +// re-use is enabled. + +let SessionCache +// FIXME: remove workaround when the Node bug is fixed +// https://github.com/nodejs/node/issues/49344#issuecomment-1741776308 +if (global.FinalizationRegistry && !process.env.NODE_V8_COVERAGE) { + SessionCache = class WeakSessionCache { + constructor (maxCachedSessions) { + this._maxCachedSessions = maxCachedSessions + this._sessionCache = new Map() + this._sessionRegistry = new global.FinalizationRegistry((key) => { + if (this._sessionCache.size < this._maxCachedSessions) { + return + } + + const ref = this._sessionCache.get(key) + if (ref !== undefined && ref.deref() === undefined) { + this._sessionCache.delete(key) + } + }) + } + + get (sessionKey) { + const ref = this._sessionCache.get(sessionKey) + return ref ? ref.deref() : null + } + + set (sessionKey, session) { + if (this._maxCachedSessions === 0) { + return } - if (stream.locked) { - throw new TypeError('The stream is locked.') + this._sessionCache.set(sessionKey, new WeakRef(session)) + this._sessionRegistry.register(session, sessionKey) + } + } +} else { + SessionCache = class SimpleSessionCache { + constructor (maxCachedSessions) { + this._maxCachedSessions = maxCachedSessions + this._sessionCache = new Map() + } + + get (sessionKey) { + return this._sessionCache.get(sessionKey) + } + + set (sessionKey, session) { + if (this._maxCachedSessions === 0) { + return } - // Compat. - stream[kBodyUsed] = true + if (this._sessionCache.size >= this._maxCachedSessions) { + // remove the oldest session + const { value: oldestKey } = this._sessionCache.keys().next() + this._sessionCache.delete(oldestKey) + } - yield * stream + this._sessionCache.set(sessionKey, session) } } } -function throwIfAborted (state) { - if (state.aborted) { - throw new DOMException('The operation was aborted.', 'AbortError') +function buildConnector ({ allowH2, maxCachedSessions, socketPath, timeout, ...opts }) { + if (maxCachedSessions != null && (!Number.isInteger(maxCachedSessions) || maxCachedSessions < 0)) { + throw new InvalidArgumentError('maxCachedSessions must be a positive integer or zero') } -} -function bodyMixinMethods (instance) { - const methods = { - blob () { - // The blob() method steps are to return the result of - // running consume body with this and the following step - // given a byte sequence bytes: return a Blob whose - // contents are bytes and whose type attribute is this’s - // MIME type. - return specConsumeBody(this, (bytes) => { - let mimeType = bodyMimeType(this) - - if (mimeType === 'failure') { - mimeType = '' - } else if (mimeType) { - mimeType = serializeAMimeType(mimeType) - } - - // Return a Blob whose contents are bytes and type attribute - // is mimeType. - return new Blob([bytes], { type: mimeType }) - }, instance) - }, - - arrayBuffer () { - // The arrayBuffer() method steps are to return the result - // of running consume body with this and the following step - // given a byte sequence bytes: return a new ArrayBuffer - // whose contents are bytes. - return specConsumeBody(this, (bytes) => { - return new Uint8Array(bytes).buffer - }, instance) - }, - - text () { - // The text() method steps are to return the result of running - // consume body with this and UTF-8 decode. - return specConsumeBody(this, utf8DecodeBytes, instance) - }, + const options = { path: socketPath, ...opts } + const sessionCache = new SessionCache(maxCachedSessions == null ? 100 : maxCachedSessions) + timeout = timeout == null ? 10e3 : timeout + allowH2 = allowH2 != null ? allowH2 : false + return function connect ({ hostname, host, protocol, port, servername, localAddress, httpSocket }, callback) { + let socket + if (protocol === 'https:') { + if (!tls) { + tls = __nccwpck_require__(4404) + } + servername = servername || options.servername || util.getServerName(host) || null - json () { - // The json() method steps are to return the result of running - // consume body with this and parse JSON from bytes. - return specConsumeBody(this, parseJSONFromBytes, instance) - }, + const sessionKey = servername || hostname + const session = sessionCache.get(sessionKey) || null - async formData () { - webidl.brandCheck(this, instance) + assert(sessionKey) - throwIfAborted(this[kState]) + socket = tls.connect({ + highWaterMark: 16384, // TLS in node can't have bigger HWM anyway... + ...options, + servername, + session, + localAddress, + // TODO(HTTP/2): Add support for h2c + ALPNProtocols: allowH2 ? ['http/1.1', 'h2'] : ['http/1.1'], + socket: httpSocket, // upgrade socket connection + port: port || 443, + host: hostname + }) - const contentType = this.headers.get('Content-Type') + socket + .on('session', function (session) { + // TODO (fix): Can a session become invalid once established? Don't think so? + sessionCache.set(sessionKey, session) + }) + } else { + assert(!httpSocket, 'httpSocket can only be sent on TLS update') + socket = net.connect({ + highWaterMark: 64 * 1024, // Same as nodejs fs streams. + ...options, + localAddress, + port: port || 80, + host: hostname + }) + } - // If mimeType’s essence is "multipart/form-data", then: - if (/multipart\/form-data/.test(contentType)) { - const headers = {} - for (const [key, value] of this.headers) headers[key.toLowerCase()] = value + // Set TCP keep alive options on the socket here instead of in connect() for the case of assigning the socket + if (options.keepAlive == null || options.keepAlive) { + const keepAliveInitialDelay = options.keepAliveInitialDelay === undefined ? 60e3 : options.keepAliveInitialDelay + socket.setKeepAlive(true, keepAliveInitialDelay) + } - const responseFormData = new FormData() + const cancelTimeout = setupTimeout(() => onConnectTimeout(socket), timeout) - let busboy + socket + .setNoDelay(true) + .once(protocol === 'https:' ? 'secureConnect' : 'connect', function () { + cancelTimeout() - try { - busboy = new Busboy({ - headers, - preservePath: true - }) - } catch (err) { - throw new DOMException(`${err}`, 'AbortError') + if (callback) { + const cb = callback + callback = null + cb(null, this) } + }) + .on('error', function (err) { + cancelTimeout() - busboy.on('field', (name, value) => { - responseFormData.append(name, value) - }) - busboy.on('file', (name, value, filename, encoding, mimeType) => { - const chunks = [] - - if (encoding === 'base64' || encoding.toLowerCase() === 'base64') { - let base64chunk = '' + if (callback) { + const cb = callback + callback = null + cb(err) + } + }) - value.on('data', (chunk) => { - base64chunk += chunk.toString().replace(/[\r\n]/gm, '') + return socket + } +} - const end = base64chunk.length - base64chunk.length % 4 - chunks.push(Buffer.from(base64chunk.slice(0, end), 'base64')) +function setupTimeout (onConnectTimeout, timeout) { + if (!timeout) { + return () => {} + } - base64chunk = base64chunk.slice(end) - }) - value.on('end', () => { - chunks.push(Buffer.from(base64chunk, 'base64')) - responseFormData.append(name, new File(chunks, filename, { type: mimeType })) - }) - } else { - value.on('data', (chunk) => { - chunks.push(chunk) - }) - value.on('end', () => { - responseFormData.append(name, new File(chunks, filename, { type: mimeType })) - }) - } - }) + let s1 = null + let s2 = null + const timeoutId = setTimeout(() => { + // setImmediate is added to make sure that we priotorise socket error events over timeouts + s1 = setImmediate(() => { + if (process.platform === 'win32') { + // Windows needs an extra setImmediate probably due to implementation differences in the socket logic + s2 = setImmediate(() => onConnectTimeout()) + } else { + onConnectTimeout() + } + }) + }, timeout) + return () => { + clearTimeout(timeoutId) + clearImmediate(s1) + clearImmediate(s2) + } +} - const busboyResolve = new Promise((resolve, reject) => { - busboy.on('finish', resolve) - busboy.on('error', (err) => reject(new TypeError(err))) - }) +function onConnectTimeout (socket) { + util.destroy(socket, new ConnectTimeoutError()) +} - if (this.body !== null) for await (const chunk of consumeBody(this[kState].body)) busboy.write(chunk) - busboy.end() - await busboyResolve +module.exports = buildConnector - return responseFormData - } else if (/application\/x-www-form-urlencoded/.test(contentType)) { - // Otherwise, if mimeType’s essence is "application/x-www-form-urlencoded", then: - // 1. Let entries be the result of parsing bytes. - let entries - try { - let text = '' - // application/x-www-form-urlencoded parser will keep the BOM. - // https://url.spec.whatwg.org/#concept-urlencoded-parser - // Note that streaming decoder is stateful and cannot be reused - const streamingDecoder = new TextDecoder('utf-8', { ignoreBOM: true }) +/***/ }), - for await (const chunk of consumeBody(this[kState].body)) { - if (!isUint8Array(chunk)) { - throw new TypeError('Expected Uint8Array chunk') - } - text += streamingDecoder.decode(chunk, { stream: true }) - } - text += streamingDecoder.decode() - entries = new URLSearchParams(text) - } catch (err) { - // istanbul ignore next: Unclear when new URLSearchParams can fail on a string. - // 2. If entries is failure, then throw a TypeError. - throw Object.assign(new TypeError(), { cause: err }) - } +/***/ 8045: +/***/ ((module) => { - // 3. Return a new FormData object whose entries are entries. - const formData = new FormData() - for (const [name, value] of entries) { - formData.append(name, value) - } - return formData - } else { - // Wait a tick before checking if the request has been aborted. - // Otherwise, a TypeError can be thrown when an AbortError should. - await Promise.resolve() +"use strict"; - throwIfAborted(this[kState]) - // Otherwise, throw a TypeError. - throw webidl.errors.exception({ - header: `${instance.name}.formData`, - message: 'Could not parse content as FormData.' - }) - } - } +class UndiciError extends Error { + constructor (message) { + super(message) + this.name = 'UndiciError' + this.code = 'UND_ERR' } +} - return methods +class ConnectTimeoutError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, ConnectTimeoutError) + this.name = 'ConnectTimeoutError' + this.message = message || 'Connect Timeout Error' + this.code = 'UND_ERR_CONNECT_TIMEOUT' + } } -function mixinBody (prototype) { - Object.assign(prototype.prototype, bodyMixinMethods(prototype)) +class HeadersTimeoutError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, HeadersTimeoutError) + this.name = 'HeadersTimeoutError' + this.message = message || 'Headers Timeout Error' + this.code = 'UND_ERR_HEADERS_TIMEOUT' + } } -/** - * @see https://fetch.spec.whatwg.org/#concept-body-consume-body - * @param {Response|Request} object - * @param {(value: unknown) => unknown} convertBytesToJSValue - * @param {Response|Request} instance - */ -async function specConsumeBody (object, convertBytesToJSValue, instance) { - webidl.brandCheck(object, instance) - - throwIfAborted(object[kState]) - - // 1. If object is unusable, then return a promise rejected - // with a TypeError. - if (bodyUnusable(object[kState].body)) { - throw new TypeError('Body is unusable') +class HeadersOverflowError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, HeadersOverflowError) + this.name = 'HeadersOverflowError' + this.message = message || 'Headers Overflow Error' + this.code = 'UND_ERR_HEADERS_OVERFLOW' } +} - // 2. Let promise be a new promise. - const promise = createDeferredPromise() +class BodyTimeoutError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, BodyTimeoutError) + this.name = 'BodyTimeoutError' + this.message = message || 'Body Timeout Error' + this.code = 'UND_ERR_BODY_TIMEOUT' + } +} - // 3. Let errorSteps given error be to reject promise with error. - const errorSteps = (error) => promise.reject(error) +class ResponseStatusCodeError extends UndiciError { + constructor (message, statusCode, headers, body) { + super(message) + Error.captureStackTrace(this, ResponseStatusCodeError) + this.name = 'ResponseStatusCodeError' + this.message = message || 'Response Status Code Error' + this.code = 'UND_ERR_RESPONSE_STATUS_CODE' + this.body = body + this.status = statusCode + this.statusCode = statusCode + this.headers = headers + } +} - // 4. Let successSteps given a byte sequence data be to resolve - // promise with the result of running convertBytesToJSValue - // with data. If that threw an exception, then run errorSteps - // with that exception. - const successSteps = (data) => { - try { - promise.resolve(convertBytesToJSValue(data)) - } catch (e) { - errorSteps(e) - } +class InvalidArgumentError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, InvalidArgumentError) + this.name = 'InvalidArgumentError' + this.message = message || 'Invalid Argument Error' + this.code = 'UND_ERR_INVALID_ARG' } +} - // 5. If object’s body is null, then run successSteps with an - // empty byte sequence. - if (object[kState].body == null) { - successSteps(new Uint8Array()) - return promise.promise +class InvalidReturnValueError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, InvalidReturnValueError) + this.name = 'InvalidReturnValueError' + this.message = message || 'Invalid Return Value Error' + this.code = 'UND_ERR_INVALID_RETURN_VALUE' } +} - // 6. Otherwise, fully read object’s body given successSteps, - // errorSteps, and object’s relevant global object. - await fullyReadBody(object[kState].body, successSteps, errorSteps) +class RequestAbortedError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, RequestAbortedError) + this.name = 'AbortError' + this.message = message || 'Request aborted' + this.code = 'UND_ERR_ABORTED' + } +} - // 7. Return promise. - return promise.promise +class InformationalError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, InformationalError) + this.name = 'InformationalError' + this.message = message || 'Request information' + this.code = 'UND_ERR_INFO' + } } -// https://fetch.spec.whatwg.org/#body-unusable -function bodyUnusable (body) { - // An object including the Body interface mixin is - // said to be unusable if its body is non-null and - // its body’s stream is disturbed or locked. - return body != null && (body.stream.locked || util.isDisturbed(body.stream)) +class RequestContentLengthMismatchError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, RequestContentLengthMismatchError) + this.name = 'RequestContentLengthMismatchError' + this.message = message || 'Request body length does not match content-length header' + this.code = 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH' + } } -/** - * @see https://encoding.spec.whatwg.org/#utf-8-decode - * @param {Buffer} buffer - */ -function utf8DecodeBytes (buffer) { - if (buffer.length === 0) { - return '' +class ResponseContentLengthMismatchError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, ResponseContentLengthMismatchError) + this.name = 'ResponseContentLengthMismatchError' + this.message = message || 'Response body length does not match content-length header' + this.code = 'UND_ERR_RES_CONTENT_LENGTH_MISMATCH' } +} - // 1. Let buffer be the result of peeking three bytes from - // ioQueue, converted to a byte sequence. +class ClientDestroyedError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, ClientDestroyedError) + this.name = 'ClientDestroyedError' + this.message = message || 'The client is destroyed' + this.code = 'UND_ERR_DESTROYED' + } +} - // 2. If buffer is 0xEF 0xBB 0xBF, then read three - // bytes from ioQueue. (Do nothing with those bytes.) - if (buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) { - buffer = buffer.subarray(3) +class ClientClosedError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, ClientClosedError) + this.name = 'ClientClosedError' + this.message = message || 'The client is closed' + this.code = 'UND_ERR_CLOSED' } +} - // 3. Process a queue with an instance of UTF-8’s - // decoder, ioQueue, output, and "replacement". - const output = textDecoder.decode(buffer) +class SocketError extends UndiciError { + constructor (message, socket) { + super(message) + Error.captureStackTrace(this, SocketError) + this.name = 'SocketError' + this.message = message || 'Socket error' + this.code = 'UND_ERR_SOCKET' + this.socket = socket + } +} - // 4. Return output. - return output +class NotSupportedError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, NotSupportedError) + this.name = 'NotSupportedError' + this.message = message || 'Not supported error' + this.code = 'UND_ERR_NOT_SUPPORTED' + } } -/** - * @see https://infra.spec.whatwg.org/#parse-json-bytes-to-a-javascript-value - * @param {Uint8Array} bytes - */ -function parseJSONFromBytes (bytes) { - return JSON.parse(utf8DecodeBytes(bytes)) +class BalancedPoolMissingUpstreamError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, NotSupportedError) + this.name = 'MissingUpstreamError' + this.message = message || 'No upstream has been added to the BalancedPool' + this.code = 'UND_ERR_BPL_MISSING_UPSTREAM' + } } -/** - * @see https://fetch.spec.whatwg.org/#concept-body-mime-type - * @param {import('./response').Response|import('./request').Request} object - */ -function bodyMimeType (object) { - const { headersList } = object[kState] - const contentType = headersList.get('content-type') +class HTTPParserError extends Error { + constructor (message, code, data) { + super(message) + Error.captureStackTrace(this, HTTPParserError) + this.name = 'HTTPParserError' + this.code = code ? `HPE_${code}` : undefined + this.data = data ? data.toString() : undefined + } +} - if (contentType === null) { - return 'failure' +class ResponseExceededMaxSizeError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, ResponseExceededMaxSizeError) + this.name = 'ResponseExceededMaxSizeError' + this.message = message || 'Response content exceeded max size' + this.code = 'UND_ERR_RES_EXCEEDED_MAX_SIZE' } +} - return parseMIMEType(contentType) +class RequestRetryError extends UndiciError { + constructor (message, code, { headers, data }) { + super(message) + Error.captureStackTrace(this, RequestRetryError) + this.name = 'RequestRetryError' + this.message = message || 'Request retry error' + this.code = 'UND_ERR_REQ_RETRY' + this.statusCode = code + this.data = data + this.headers = headers + } } module.exports = { - extractBody, - safelyExtractBody, - cloneBody, - mixinBody + HTTPParserError, + UndiciError, + HeadersTimeoutError, + HeadersOverflowError, + BodyTimeoutError, + RequestContentLengthMismatchError, + ConnectTimeoutError, + ResponseStatusCodeError, + InvalidArgumentError, + InvalidReturnValueError, + RequestAbortedError, + ClientDestroyedError, + ClientClosedError, + InformationalError, + SocketError, + NotSupportedError, + ResponseContentLengthMismatchError, + BalancedPoolMissingUpstreamError, + ResponseExceededMaxSizeError, + RequestRetryError } /***/ }), -/***/ 1037: +/***/ 2905: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { MessageChannel, receiveMessageOnPort } = __nccwpck_require__(1267) - -const corsSafeListedMethods = ['GET', 'HEAD', 'POST'] -const corsSafeListedMethodsSet = new Set(corsSafeListedMethods) - -const nullBodyStatus = [101, 204, 205, 304] - -const redirectStatus = [301, 302, 303, 307, 308] -const redirectStatusSet = new Set(redirectStatus) - -// https://fetch.spec.whatwg.org/#block-bad-port -const badPorts = [ - '1', '7', '9', '11', '13', '15', '17', '19', '20', '21', '22', '23', '25', '37', '42', '43', '53', '69', '77', '79', - '87', '95', '101', '102', '103', '104', '109', '110', '111', '113', '115', '117', '119', '123', '135', '137', - '139', '143', '161', '179', '389', '427', '465', '512', '513', '514', '515', '526', '530', '531', '532', - '540', '548', '554', '556', '563', '587', '601', '636', '989', '990', '993', '995', '1719', '1720', '1723', - '2049', '3659', '4045', '5060', '5061', '6000', '6566', '6665', '6666', '6667', '6668', '6669', '6697', - '10080' -] - -const badPortsSet = new Set(badPorts) +const { + InvalidArgumentError, + NotSupportedError +} = __nccwpck_require__(8045) +const assert = __nccwpck_require__(9491) +const { kHTTP2BuildRequest, kHTTP2CopyHeaders, kHTTP1BuildRequest } = __nccwpck_require__(2785) +const util = __nccwpck_require__(3983) -// https://w3c.github.io/webappsec-referrer-policy/#referrer-policies -const referrerPolicy = [ - '', - 'no-referrer', - 'no-referrer-when-downgrade', - 'same-origin', - 'origin', - 'strict-origin', - 'origin-when-cross-origin', - 'strict-origin-when-cross-origin', - 'unsafe-url' -] -const referrerPolicySet = new Set(referrerPolicy) +// tokenRegExp and headerCharRegex have been lifted from +// https://github.com/nodejs/node/blob/main/lib/_http_common.js -const requestRedirect = ['follow', 'manual', 'error'] +/** + * Verifies that the given val is a valid HTTP token + * per the rules defined in RFC 7230 + * See https://tools.ietf.org/html/rfc7230#section-3.2.6 + */ +const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/ -const safeMethods = ['GET', 'HEAD', 'OPTIONS', 'TRACE'] -const safeMethodsSet = new Set(safeMethods) +/** + * Matches if val contains an invalid field-vchar + * field-value = *( field-content / obs-fold ) + * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] + * field-vchar = VCHAR / obs-text + */ +const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/ -const requestMode = ['navigate', 'same-origin', 'no-cors', 'cors'] +// Verifies that a given path is valid does not contain control chars \x00 to \x20 +const invalidPathRegex = /[^\u0021-\u00ff]/ -const requestCredentials = ['omit', 'same-origin', 'include'] +const kHandler = Symbol('handler') -const requestCache = [ - 'default', - 'no-store', - 'reload', - 'no-cache', - 'force-cache', - 'only-if-cached' -] +const channels = {} -// https://fetch.spec.whatwg.org/#request-body-header-name -const requestBodyHeader = [ - 'content-encoding', - 'content-language', - 'content-location', - 'content-type', - // See https://github.com/nodejs/undici/issues/2021 - // 'Content-Length' is a forbidden header name, which is typically - // removed in the Headers implementation. However, undici doesn't - // filter out headers, so we add it here. - 'content-length' -] +let extractBody -// https://fetch.spec.whatwg.org/#enumdef-requestduplex -const requestDuplex = [ - 'half' -] +try { + const diagnosticsChannel = __nccwpck_require__(7643) + channels.create = diagnosticsChannel.channel('undici:request:create') + channels.bodySent = diagnosticsChannel.channel('undici:request:bodySent') + channels.headers = diagnosticsChannel.channel('undici:request:headers') + channels.trailers = diagnosticsChannel.channel('undici:request:trailers') + channels.error = diagnosticsChannel.channel('undici:request:error') +} catch { + channels.create = { hasSubscribers: false } + channels.bodySent = { hasSubscribers: false } + channels.headers = { hasSubscribers: false } + channels.trailers = { hasSubscribers: false } + channels.error = { hasSubscribers: false } +} -// http://fetch.spec.whatwg.org/#forbidden-method -const forbiddenMethods = ['CONNECT', 'TRACE', 'TRACK'] -const forbiddenMethodsSet = new Set(forbiddenMethods) +class Request { + constructor (origin, { + path, + method, + body, + headers, + query, + idempotent, + blocking, + upgrade, + headersTimeout, + bodyTimeout, + reset, + throwOnError, + expectContinue + }, handler) { + if (typeof path !== 'string') { + throw new InvalidArgumentError('path must be a string') + } else if ( + path[0] !== '/' && + !(path.startsWith('http://') || path.startsWith('https://')) && + method !== 'CONNECT' + ) { + throw new InvalidArgumentError('path must be an absolute URL or start with a slash') + } else if (invalidPathRegex.exec(path) !== null) { + throw new InvalidArgumentError('invalid request path') + } -const subresource = [ - 'audio', - 'audioworklet', - 'font', - 'image', - 'manifest', - 'paintworklet', - 'script', - 'style', - 'track', - 'video', - 'xslt', - '' -] -const subresourceSet = new Set(subresource) + if (typeof method !== 'string') { + throw new InvalidArgumentError('method must be a string') + } else if (tokenRegExp.exec(method) === null) { + throw new InvalidArgumentError('invalid request method') + } -/** @type {globalThis['DOMException']} */ -const DOMException = globalThis.DOMException ?? (() => { - // DOMException was only made a global in Node v17.0.0, - // but fetch supports >= v16.8. - try { - atob('~') - } catch (err) { - return Object.getPrototypeOf(err).constructor - } -})() + if (upgrade && typeof upgrade !== 'string') { + throw new InvalidArgumentError('upgrade must be a string') + } -let channel + if (headersTimeout != null && (!Number.isFinite(headersTimeout) || headersTimeout < 0)) { + throw new InvalidArgumentError('invalid headersTimeout') + } -/** @type {globalThis['structuredClone']} */ -const structuredClone = - globalThis.structuredClone ?? - // https://github.com/nodejs/node/blob/b27ae24dcc4251bad726d9d84baf678d1f707fed/lib/internal/structured_clone.js - // structuredClone was added in v17.0.0, but fetch supports v16.8 - function structuredClone (value, options = undefined) { - if (arguments.length === 0) { - throw new TypeError('missing argument') + if (bodyTimeout != null && (!Number.isFinite(bodyTimeout) || bodyTimeout < 0)) { + throw new InvalidArgumentError('invalid bodyTimeout') } - if (!channel) { - channel = new MessageChannel() + if (reset != null && typeof reset !== 'boolean') { + throw new InvalidArgumentError('invalid reset') } - channel.port1.unref() - channel.port2.unref() - channel.port1.postMessage(value, options?.transfer) - return receiveMessageOnPort(channel.port2).message - } -module.exports = { - DOMException, - structuredClone, - subresource, - forbiddenMethods, - requestBodyHeader, - referrerPolicy, - requestRedirect, - requestMode, - requestCredentials, - requestCache, - redirectStatus, - corsSafeListedMethods, - nullBodyStatus, - safeMethods, - badPorts, - requestDuplex, - subresourceSet, - badPortsSet, - redirectStatusSet, - corsSafeListedMethodsSet, - safeMethodsSet, - forbiddenMethodsSet, - referrerPolicySet -} + if (expectContinue != null && typeof expectContinue !== 'boolean') { + throw new InvalidArgumentError('invalid expectContinue') + } + this.headersTimeout = headersTimeout -/***/ }), + this.bodyTimeout = bodyTimeout -/***/ 685: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this.throwOnError = throwOnError === true -const assert = __nccwpck_require__(9491) -const { atob } = __nccwpck_require__(4300) -const { isomorphicDecode } = __nccwpck_require__(2538) + this.method = method -const encoder = new TextEncoder() + this.abort = null -/** - * @see https://mimesniff.spec.whatwg.org/#http-token-code-point - */ -const HTTP_TOKEN_CODEPOINTS = /^[!#$%&'*+-.^_|~A-Za-z0-9]+$/ -const HTTP_WHITESPACE_REGEX = /(\u000A|\u000D|\u0009|\u0020)/ // eslint-disable-line -/** - * @see https://mimesniff.spec.whatwg.org/#http-quoted-string-token-code-point - */ -const HTTP_QUOTED_STRING_TOKENS = /[\u0009|\u0020-\u007E|\u0080-\u00FF]/ // eslint-disable-line + if (body == null) { + this.body = null + } else if (util.isStream(body)) { + this.body = body -// https://fetch.spec.whatwg.org/#data-url-processor -/** @param {URL} dataURL */ -function dataURLProcessor (dataURL) { - // 1. Assert: dataURL’s scheme is "data". - assert(dataURL.protocol === 'data:') + const rState = this.body._readableState + if (!rState || !rState.autoDestroy) { + this.endHandler = function autoDestroy () { + util.destroy(this) + } + this.body.on('end', this.endHandler) + } - // 2. Let input be the result of running the URL - // serializer on dataURL with exclude fragment - // set to true. - let input = URLSerializer(dataURL, true) + this.errorHandler = err => { + if (this.abort) { + this.abort(err) + } else { + this.error = err + } + } + this.body.on('error', this.errorHandler) + } else if (util.isBuffer(body)) { + this.body = body.byteLength ? body : null + } else if (ArrayBuffer.isView(body)) { + this.body = body.buffer.byteLength ? Buffer.from(body.buffer, body.byteOffset, body.byteLength) : null + } else if (body instanceof ArrayBuffer) { + this.body = body.byteLength ? Buffer.from(body) : null + } else if (typeof body === 'string') { + this.body = body.length ? Buffer.from(body) : null + } else if (util.isFormDataLike(body) || util.isIterable(body) || util.isBlobLike(body)) { + this.body = body + } else { + throw new InvalidArgumentError('body must be a string, a Buffer, a Readable stream, an iterable, or an async iterable') + } - // 3. Remove the leading "data:" string from input. - input = input.slice(5) + this.completed = false - // 4. Let position point at the start of input. - const position = { position: 0 } + this.aborted = false - // 5. Let mimeType be the result of collecting a - // sequence of code points that are not equal - // to U+002C (,), given position. - let mimeType = collectASequenceOfCodePointsFast( - ',', - input, - position - ) + this.upgrade = upgrade || null - // 6. Strip leading and trailing ASCII whitespace - // from mimeType. - // Undici implementation note: we need to store the - // length because if the mimetype has spaces removed, - // the wrong amount will be sliced from the input in - // step #9 - const mimeTypeLength = mimeType.length - mimeType = removeASCIIWhitespace(mimeType, true, true) + this.path = query ? util.buildURL(path, query) : path - // 7. If position is past the end of input, then - // return failure - if (position.position >= input.length) { - return 'failure' - } + this.origin = origin - // 8. Advance position by 1. - position.position++ + this.idempotent = idempotent == null + ? method === 'HEAD' || method === 'GET' + : idempotent - // 9. Let encodedBody be the remainder of input. - const encodedBody = input.slice(mimeTypeLength + 1) + this.blocking = blocking == null ? false : blocking - // 10. Let body be the percent-decoding of encodedBody. - let body = stringPercentDecode(encodedBody) + this.reset = reset == null ? null : reset - // 11. If mimeType ends with U+003B (;), followed by - // zero or more U+0020 SPACE, followed by an ASCII - // case-insensitive match for "base64", then: - if (/;(\u0020){0,}base64$/i.test(mimeType)) { - // 1. Let stringBody be the isomorphic decode of body. - const stringBody = isomorphicDecode(body) + this.host = null - // 2. Set body to the forgiving-base64 decode of - // stringBody. - body = forgivingBase64(stringBody) + this.contentLength = null - // 3. If body is failure, then return failure. - if (body === 'failure') { - return 'failure' + this.contentType = null + + this.headers = '' + + // Only for H2 + this.expectContinue = expectContinue != null ? expectContinue : false + + if (Array.isArray(headers)) { + if (headers.length % 2 !== 0) { + throw new InvalidArgumentError('headers array must be even') + } + for (let i = 0; i < headers.length; i += 2) { + processHeader(this, headers[i], headers[i + 1]) + } + } else if (headers && typeof headers === 'object') { + const keys = Object.keys(headers) + for (let i = 0; i < keys.length; i++) { + const key = keys[i] + processHeader(this, key, headers[key]) + } + } else if (headers != null) { + throw new InvalidArgumentError('headers must be an object or an array') } - // 4. Remove the last 6 code points from mimeType. - mimeType = mimeType.slice(0, -6) + if (util.isFormDataLike(this.body)) { + if (util.nodeMajor < 16 || (util.nodeMajor === 16 && util.nodeMinor < 8)) { + throw new InvalidArgumentError('Form-Data bodies are only supported in node v16.8 and newer.') + } - // 5. Remove trailing U+0020 SPACE code points from mimeType, - // if any. - mimeType = mimeType.replace(/(\u0020)+$/, '') + if (!extractBody) { + extractBody = (__nccwpck_require__(1472).extractBody) + } - // 6. Remove the last U+003B (;) code point from mimeType. - mimeType = mimeType.slice(0, -1) + const [bodyStream, contentType] = extractBody(body) + if (this.contentType == null) { + this.contentType = contentType + this.headers += `content-type: ${contentType}\r\n` + } + this.body = bodyStream.stream + this.contentLength = bodyStream.length + } else if (util.isBlobLike(body) && this.contentType == null && body.type) { + this.contentType = body.type + this.headers += `content-type: ${body.type}\r\n` + } + + util.validateHandler(handler, method, upgrade) + + this.servername = util.getServerName(this.host) + + this[kHandler] = handler + + if (channels.create.hasSubscribers) { + channels.create.publish({ request: this }) + } } - // 12. If mimeType starts with U+003B (;), then prepend - // "text/plain" to mimeType. - if (mimeType.startsWith(';')) { - mimeType = 'text/plain' + mimeType + onBodySent (chunk) { + if (this[kHandler].onBodySent) { + try { + return this[kHandler].onBodySent(chunk) + } catch (err) { + this.abort(err) + } + } } - // 13. Let mimeTypeRecord be the result of parsing - // mimeType. - let mimeTypeRecord = parseMIMEType(mimeType) + onRequestSent () { + if (channels.bodySent.hasSubscribers) { + channels.bodySent.publish({ request: this }) + } - // 14. If mimeTypeRecord is failure, then set - // mimeTypeRecord to text/plain;charset=US-ASCII. - if (mimeTypeRecord === 'failure') { - mimeTypeRecord = parseMIMEType('text/plain;charset=US-ASCII') + if (this[kHandler].onRequestSent) { + try { + return this[kHandler].onRequestSent() + } catch (err) { + this.abort(err) + } + } } - // 15. Return a new data: URL struct whose MIME - // type is mimeTypeRecord and body is body. - // https://fetch.spec.whatwg.org/#data-url-struct - return { mimeType: mimeTypeRecord, body } -} + onConnect (abort) { + assert(!this.aborted) + assert(!this.completed) -// https://url.spec.whatwg.org/#concept-url-serializer -/** - * @param {URL} url - * @param {boolean} excludeFragment - */ -function URLSerializer (url, excludeFragment = false) { - if (!excludeFragment) { - return url.href + if (this.error) { + abort(this.error) + } else { + this.abort = abort + return this[kHandler].onConnect(abort) + } } - const href = url.href - const hashLength = url.hash.length + onHeaders (statusCode, headers, resume, statusText) { + assert(!this.aborted) + assert(!this.completed) - return hashLength === 0 ? href : href.substring(0, href.length - hashLength) -} + if (channels.headers.hasSubscribers) { + channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }) + } -// https://infra.spec.whatwg.org/#collect-a-sequence-of-code-points -/** - * @param {(char: string) => boolean} condition - * @param {string} input - * @param {{ position: number }} position - */ -function collectASequenceOfCodePoints (condition, input, position) { - // 1. Let result be the empty string. - let result = '' + try { + return this[kHandler].onHeaders(statusCode, headers, resume, statusText) + } catch (err) { + this.abort(err) + } + } - // 2. While position doesn’t point past the end of input and the - // code point at position within input meets the condition condition: - while (position.position < input.length && condition(input[position.position])) { - // 1. Append that code point to the end of result. - result += input[position.position] + onData (chunk) { + assert(!this.aborted) + assert(!this.completed) - // 2. Advance position by 1. - position.position++ + try { + return this[kHandler].onData(chunk) + } catch (err) { + this.abort(err) + return false + } } - // 3. Return result. - return result -} - -/** - * A faster collectASequenceOfCodePoints that only works when comparing a single character. - * @param {string} char - * @param {string} input - * @param {{ position: number }} position - */ -function collectASequenceOfCodePointsFast (char, input, position) { - const idx = input.indexOf(char, position.position) - const start = position.position + onUpgrade (statusCode, headers, socket) { + assert(!this.aborted) + assert(!this.completed) - if (idx === -1) { - position.position = input.length - return input.slice(start) + return this[kHandler].onUpgrade(statusCode, headers, socket) } - position.position = idx - return input.slice(start, position.position) -} + onComplete (trailers) { + this.onFinally() -// https://url.spec.whatwg.org/#string-percent-decode -/** @param {string} input */ -function stringPercentDecode (input) { - // 1. Let bytes be the UTF-8 encoding of input. - const bytes = encoder.encode(input) + assert(!this.aborted) - // 2. Return the percent-decoding of bytes. - return percentDecode(bytes) -} + this.completed = true + if (channels.trailers.hasSubscribers) { + channels.trailers.publish({ request: this, trailers }) + } -// https://url.spec.whatwg.org/#percent-decode -/** @param {Uint8Array} input */ -function percentDecode (input) { - // 1. Let output be an empty byte sequence. - /** @type {number[]} */ - const output = [] + try { + return this[kHandler].onComplete(trailers) + } catch (err) { + // TODO (fix): This might be a bad idea? + this.onError(err) + } + } - // 2. For each byte byte in input: - for (let i = 0; i < input.length; i++) { - const byte = input[i] + onError (error) { + this.onFinally() - // 1. If byte is not 0x25 (%), then append byte to output. - if (byte !== 0x25) { - output.push(byte) + if (channels.error.hasSubscribers) { + channels.error.publish({ request: this, error }) + } - // 2. Otherwise, if byte is 0x25 (%) and the next two bytes - // after byte in input are not in the ranges - // 0x30 (0) to 0x39 (9), 0x41 (A) to 0x46 (F), - // and 0x61 (a) to 0x66 (f), all inclusive, append byte - // to output. - } else if ( - byte === 0x25 && - !/^[0-9A-Fa-f]{2}$/i.test(String.fromCharCode(input[i + 1], input[i + 2])) - ) { - output.push(0x25) + if (this.aborted) { + return + } + this.aborted = true - // 3. Otherwise: - } else { - // 1. Let bytePoint be the two bytes after byte in input, - // decoded, and then interpreted as hexadecimal number. - const nextTwoBytes = String.fromCharCode(input[i + 1], input[i + 2]) - const bytePoint = Number.parseInt(nextTwoBytes, 16) + return this[kHandler].onError(error) + } - // 2. Append a byte whose value is bytePoint to output. - output.push(bytePoint) + onFinally () { + if (this.errorHandler) { + this.body.off('error', this.errorHandler) + this.errorHandler = null + } - // 3. Skip the next two bytes in input. - i += 2 + if (this.endHandler) { + this.body.off('end', this.endHandler) + this.endHandler = null } } - // 3. Return output. - return Uint8Array.from(output) -} - -// https://mimesniff.spec.whatwg.org/#parse-a-mime-type -/** @param {string} input */ -function parseMIMEType (input) { - // 1. Remove any leading and trailing HTTP whitespace - // from input. - input = removeHTTPWhitespace(input, true, true) - - // 2. Let position be a position variable for input, - // initially pointing at the start of input. - const position = { position: 0 } - - // 3. Let type be the result of collecting a sequence - // of code points that are not U+002F (/) from - // input, given position. - const type = collectASequenceOfCodePointsFast( - '/', - input, - position - ) - - // 4. If type is the empty string or does not solely - // contain HTTP token code points, then return failure. - // https://mimesniff.spec.whatwg.org/#http-token-code-point - if (type.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(type)) { - return 'failure' + // TODO: adjust to support H2 + addHeader (key, value) { + processHeader(this, key, value) + return this } - // 5. If position is past the end of input, then return - // failure - if (position.position > input.length) { - return 'failure' + static [kHTTP1BuildRequest] (origin, opts, handler) { + // TODO: Migrate header parsing here, to make Requests + // HTTP agnostic + return new Request(origin, opts, handler) } - // 6. Advance position by 1. (This skips past U+002F (/).) - position.position++ - - // 7. Let subtype be the result of collecting a sequence of - // code points that are not U+003B (;) from input, given - // position. - let subtype = collectASequenceOfCodePointsFast( - ';', - input, - position - ) + static [kHTTP2BuildRequest] (origin, opts, handler) { + const headers = opts.headers + opts = { ...opts, headers: null } - // 8. Remove any trailing HTTP whitespace from subtype. - subtype = removeHTTPWhitespace(subtype, false, true) + const request = new Request(origin, opts, handler) - // 9. If subtype is the empty string or does not solely - // contain HTTP token code points, then return failure. - if (subtype.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(subtype)) { - return 'failure' - } + request.headers = {} - const typeLowercase = type.toLowerCase() - const subtypeLowercase = subtype.toLowerCase() + if (Array.isArray(headers)) { + if (headers.length % 2 !== 0) { + throw new InvalidArgumentError('headers array must be even') + } + for (let i = 0; i < headers.length; i += 2) { + processHeader(request, headers[i], headers[i + 1], true) + } + } else if (headers && typeof headers === 'object') { + const keys = Object.keys(headers) + for (let i = 0; i < keys.length; i++) { + const key = keys[i] + processHeader(request, key, headers[key], true) + } + } else if (headers != null) { + throw new InvalidArgumentError('headers must be an object or an array') + } - // 10. Let mimeType be a new MIME type record whose type - // is type, in ASCII lowercase, and subtype is subtype, - // in ASCII lowercase. - // https://mimesniff.spec.whatwg.org/#mime-type - const mimeType = { - type: typeLowercase, - subtype: subtypeLowercase, - /** @type {Map} */ - parameters: new Map(), - // https://mimesniff.spec.whatwg.org/#mime-type-essence - essence: `${typeLowercase}/${subtypeLowercase}` + return request } - // 11. While position is not past the end of input: - while (position.position < input.length) { - // 1. Advance position by 1. (This skips past U+003B (;).) - position.position++ - - // 2. Collect a sequence of code points that are HTTP - // whitespace from input given position. - collectASequenceOfCodePoints( - // https://fetch.spec.whatwg.org/#http-whitespace - char => HTTP_WHITESPACE_REGEX.test(char), - input, - position - ) - - // 3. Let parameterName be the result of collecting a - // sequence of code points that are not U+003B (;) - // or U+003D (=) from input, given position. - let parameterName = collectASequenceOfCodePoints( - (char) => char !== ';' && char !== '=', - input, - position - ) + static [kHTTP2CopyHeaders] (raw) { + const rawHeaders = raw.split('\r\n') + const headers = {} - // 4. Set parameterName to parameterName, in ASCII - // lowercase. - parameterName = parameterName.toLowerCase() + for (const header of rawHeaders) { + const [key, value] = header.split(': ') - // 5. If position is not past the end of input, then: - if (position.position < input.length) { - // 1. If the code point at position within input is - // U+003B (;), then continue. - if (input[position.position] === ';') { - continue - } + if (value == null || value.length === 0) continue - // 2. Advance position by 1. (This skips past U+003D (=).) - position.position++ + if (headers[key]) headers[key] += `,${value}` + else headers[key] = value } - // 6. If position is past the end of input, then break. - if (position.position > input.length) { - break - } + return headers + } +} - // 7. Let parameterValue be null. - let parameterValue = null +function processHeaderValue (key, val, skipAppend) { + if (val && typeof val === 'object') { + throw new InvalidArgumentError(`invalid ${key} header`) + } - // 8. If the code point at position within input is - // U+0022 ("), then: - if (input[position.position] === '"') { - // 1. Set parameterValue to the result of collecting - // an HTTP quoted string from input, given position - // and the extract-value flag. - parameterValue = collectAnHTTPQuotedString(input, position, true) + val = val != null ? `${val}` : '' - // 2. Collect a sequence of code points that are not - // U+003B (;) from input, given position. - collectASequenceOfCodePointsFast( - ';', - input, - position - ) + if (headerCharRegex.exec(val) !== null) { + throw new InvalidArgumentError(`invalid ${key} header`) + } - // 9. Otherwise: - } else { - // 1. Set parameterValue to the result of collecting - // a sequence of code points that are not U+003B (;) - // from input, given position. - parameterValue = collectASequenceOfCodePointsFast( - ';', - input, - position - ) + return skipAppend ? val : `${key}: ${val}\r\n` +} - // 2. Remove any trailing HTTP whitespace from parameterValue. - parameterValue = removeHTTPWhitespace(parameterValue, false, true) +function processHeader (request, key, val, skipAppend = false) { + if (val && (typeof val === 'object' && !Array.isArray(val))) { + throw new InvalidArgumentError(`invalid ${key} header`) + } else if (val === undefined) { + return + } - // 3. If parameterValue is the empty string, then continue. - if (parameterValue.length === 0) { - continue - } + if ( + request.host === null && + key.length === 4 && + key.toLowerCase() === 'host' + ) { + if (headerCharRegex.exec(val) !== null) { + throw new InvalidArgumentError(`invalid ${key} header`) } - - // 10. If all of the following are true - // - parameterName is not the empty string - // - parameterName solely contains HTTP token code points - // - parameterValue solely contains HTTP quoted-string token code points - // - mimeType’s parameters[parameterName] does not exist - // then set mimeType’s parameters[parameterName] to parameterValue. - if ( - parameterName.length !== 0 && - HTTP_TOKEN_CODEPOINTS.test(parameterName) && - (parameterValue.length === 0 || HTTP_QUOTED_STRING_TOKENS.test(parameterValue)) && - !mimeType.parameters.has(parameterName) - ) { - mimeType.parameters.set(parameterName, parameterValue) + // Consumed by Client + request.host = val + } else if ( + request.contentLength === null && + key.length === 14 && + key.toLowerCase() === 'content-length' + ) { + request.contentLength = parseInt(val, 10) + if (!Number.isFinite(request.contentLength)) { + throw new InvalidArgumentError('invalid content-length header') + } + } else if ( + request.contentType === null && + key.length === 12 && + key.toLowerCase() === 'content-type' + ) { + request.contentType = val + if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend) + else request.headers += processHeaderValue(key, val) + } else if ( + key.length === 17 && + key.toLowerCase() === 'transfer-encoding' + ) { + throw new InvalidArgumentError('invalid transfer-encoding header') + } else if ( + key.length === 10 && + key.toLowerCase() === 'connection' + ) { + const value = typeof val === 'string' ? val.toLowerCase() : null + if (value !== 'close' && value !== 'keep-alive') { + throw new InvalidArgumentError('invalid connection header') + } else if (value === 'close') { + request.reset = true + } + } else if ( + key.length === 10 && + key.toLowerCase() === 'keep-alive' + ) { + throw new InvalidArgumentError('invalid keep-alive header') + } else if ( + key.length === 7 && + key.toLowerCase() === 'upgrade' + ) { + throw new InvalidArgumentError('invalid upgrade header') + } else if ( + key.length === 6 && + key.toLowerCase() === 'expect' + ) { + throw new NotSupportedError('expect header not supported') + } else if (tokenRegExp.exec(key) === null) { + throw new InvalidArgumentError('invalid header key') + } else { + if (Array.isArray(val)) { + for (let i = 0; i < val.length; i++) { + if (skipAppend) { + if (request.headers[key]) request.headers[key] += `,${processHeaderValue(key, val[i], skipAppend)}` + else request.headers[key] = processHeaderValue(key, val[i], skipAppend) + } else { + request.headers += processHeaderValue(key, val[i]) + } + } + } else { + if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend) + else request.headers += processHeaderValue(key, val) } } - - // 12. Return mimeType. - return mimeType } -// https://infra.spec.whatwg.org/#forgiving-base64-decode -/** @param {string} data */ -function forgivingBase64 (data) { - // 1. Remove all ASCII whitespace from data. - data = data.replace(/[\u0009\u000A\u000C\u000D\u0020]/g, '') // eslint-disable-line - - // 2. If data’s code point length divides by 4 leaving - // no remainder, then: - if (data.length % 4 === 0) { - // 1. If data ends with one or two U+003D (=) code points, - // then remove them from data. - data = data.replace(/=?=$/, '') - } - - // 3. If data’s code point length divides by 4 leaving - // a remainder of 1, then return failure. - if (data.length % 4 === 1) { - return 'failure' - } +module.exports = Request - // 4. If data contains a code point that is not one of - // U+002B (+) - // U+002F (/) - // ASCII alphanumeric - // then return failure. - if (/[^+/0-9A-Za-z]/.test(data)) { - return 'failure' - } - const binary = atob(data) - const bytes = new Uint8Array(binary.length) +/***/ }), - for (let byte = 0; byte < binary.length; byte++) { - bytes[byte] = binary.charCodeAt(byte) - } +/***/ 2785: +/***/ ((module) => { - return bytes +module.exports = { + kClose: Symbol('close'), + kDestroy: Symbol('destroy'), + kDispatch: Symbol('dispatch'), + kUrl: Symbol('url'), + kWriting: Symbol('writing'), + kResuming: Symbol('resuming'), + kQueue: Symbol('queue'), + kConnect: Symbol('connect'), + kConnecting: Symbol('connecting'), + kHeadersList: Symbol('headers list'), + kKeepAliveDefaultTimeout: Symbol('default keep alive timeout'), + kKeepAliveMaxTimeout: Symbol('max keep alive timeout'), + kKeepAliveTimeoutThreshold: Symbol('keep alive timeout threshold'), + kKeepAliveTimeoutValue: Symbol('keep alive timeout'), + kKeepAlive: Symbol('keep alive'), + kHeadersTimeout: Symbol('headers timeout'), + kBodyTimeout: Symbol('body timeout'), + kServerName: Symbol('server name'), + kLocalAddress: Symbol('local address'), + kHost: Symbol('host'), + kNoRef: Symbol('no ref'), + kBodyUsed: Symbol('used'), + kRunning: Symbol('running'), + kBlocking: Symbol('blocking'), + kPending: Symbol('pending'), + kSize: Symbol('size'), + kBusy: Symbol('busy'), + kQueued: Symbol('queued'), + kFree: Symbol('free'), + kConnected: Symbol('connected'), + kClosed: Symbol('closed'), + kNeedDrain: Symbol('need drain'), + kReset: Symbol('reset'), + kDestroyed: Symbol.for('nodejs.stream.destroyed'), + kMaxHeadersSize: Symbol('max headers size'), + kRunningIdx: Symbol('running index'), + kPendingIdx: Symbol('pending index'), + kError: Symbol('error'), + kClients: Symbol('clients'), + kClient: Symbol('client'), + kParser: Symbol('parser'), + kOnDestroyed: Symbol('destroy callbacks'), + kPipelining: Symbol('pipelining'), + kSocket: Symbol('socket'), + kHostHeader: Symbol('host header'), + kConnector: Symbol('connector'), + kStrictContentLength: Symbol('strict content length'), + kMaxRedirections: Symbol('maxRedirections'), + kMaxRequests: Symbol('maxRequestsPerClient'), + kProxy: Symbol('proxy agent options'), + kCounter: Symbol('socket request counter'), + kInterceptors: Symbol('dispatch interceptors'), + kMaxResponseSize: Symbol('max response size'), + kHTTP2Session: Symbol('http2Session'), + kHTTP2SessionState: Symbol('http2Session state'), + kHTTP2BuildRequest: Symbol('http2 build request'), + kHTTP1BuildRequest: Symbol('http1 build request'), + kHTTP2CopyHeaders: Symbol('http2 copy headers'), + kHTTPConnVersion: Symbol('http connection version'), + kRetryHandlerDefaultRetry: Symbol('retry agent default retry'), + kConstruct: Symbol('constructable') } -// https://fetch.spec.whatwg.org/#collect-an-http-quoted-string -// tests: https://fetch.spec.whatwg.org/#example-http-quoted-string -/** - * @param {string} input - * @param {{ position: number }} position - * @param {boolean?} extractValue - */ -function collectAnHTTPQuotedString (input, position, extractValue) { - // 1. Let positionStart be position. - const positionStart = position.position - - // 2. Let value be the empty string. - let value = '' - // 3. Assert: the code point at position within input - // is U+0022 ("). - assert(input[position.position] === '"') +/***/ }), - // 4. Advance position by 1. - position.position++ +/***/ 3983: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // 5. While true: - while (true) { - // 1. Append the result of collecting a sequence of code points - // that are not U+0022 (") or U+005C (\) from input, given - // position, to value. - value += collectASequenceOfCodePoints( - (char) => char !== '"' && char !== '\\', - input, - position - ) +"use strict"; - // 2. If position is past the end of input, then break. - if (position.position >= input.length) { - break - } - // 3. Let quoteOrBackslash be the code point at position within - // input. - const quoteOrBackslash = input[position.position] +const assert = __nccwpck_require__(9491) +const { kDestroyed, kBodyUsed } = __nccwpck_require__(2785) +const { IncomingMessage } = __nccwpck_require__(3685) +const stream = __nccwpck_require__(2781) +const net = __nccwpck_require__(1808) +const { InvalidArgumentError } = __nccwpck_require__(8045) +const { Blob } = __nccwpck_require__(4300) +const nodeUtil = __nccwpck_require__(3837) +const { stringify } = __nccwpck_require__(3477) - // 4. Advance position by 1. - position.position++ +const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(v => Number(v)) - // 5. If quoteOrBackslash is U+005C (\), then: - if (quoteOrBackslash === '\\') { - // 1. If position is past the end of input, then append - // U+005C (\) to value and break. - if (position.position >= input.length) { - value += '\\' - break - } +function nop () {} - // 2. Append the code point at position within input to value. - value += input[position.position] +function isStream (obj) { + return obj && typeof obj === 'object' && typeof obj.pipe === 'function' && typeof obj.on === 'function' +} - // 3. Advance position by 1. - position.position++ - - // 6. Otherwise: - } else { - // 1. Assert: quoteOrBackslash is U+0022 ("). - assert(quoteOrBackslash === '"') +// based on https://github.com/node-fetch/fetch-blob/blob/8ab587d34080de94140b54f07168451e7d0b655e/index.js#L229-L241 (MIT License) +function isBlobLike (object) { + return (Blob && object instanceof Blob) || ( + object && + typeof object === 'object' && + (typeof object.stream === 'function' || + typeof object.arrayBuffer === 'function') && + /^(Blob|File)$/.test(object[Symbol.toStringTag]) + ) +} - // 2. Break. - break - } +function buildURL (url, queryParams) { + if (url.includes('?') || url.includes('#')) { + throw new Error('Query params cannot be passed when url already contains "?" or "#".') } - // 6. If the extract-value flag is set, then return value. - if (extractValue) { - return value + const stringified = stringify(queryParams) + + if (stringified) { + url += '?' + stringified } - // 7. Return the code points from positionStart to position, - // inclusive, within input. - return input.slice(positionStart, position.position) + return url } -/** - * @see https://mimesniff.spec.whatwg.org/#serialize-a-mime-type - */ -function serializeAMimeType (mimeType) { - assert(mimeType !== 'failure') - const { parameters, essence } = mimeType - - // 1. Let serialization be the concatenation of mimeType’s - // type, U+002F (/), and mimeType’s subtype. - let serialization = essence +function parseURL (url) { + if (typeof url === 'string') { + url = new URL(url) - // 2. For each name → value of mimeType’s parameters: - for (let [name, value] of parameters.entries()) { - // 1. Append U+003B (;) to serialization. - serialization += ';' + if (!/^https?:/.test(url.origin || url.protocol)) { + throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') + } - // 2. Append name to serialization. - serialization += name + return url + } - // 3. Append U+003D (=) to serialization. - serialization += '=' + if (!url || typeof url !== 'object') { + throw new InvalidArgumentError('Invalid URL: The URL argument must be a non-null object.') + } - // 4. If value does not solely contain HTTP token code - // points or value is the empty string, then: - if (!HTTP_TOKEN_CODEPOINTS.test(value)) { - // 1. Precede each occurence of U+0022 (") or - // U+005C (\) in value with U+005C (\). - value = value.replace(/(\\|")/g, '\\$1') + if (!/^https?:/.test(url.origin || url.protocol)) { + throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') + } - // 2. Prepend U+0022 (") to value. - value = '"' + value + if (!(url instanceof URL)) { + if (url.port != null && url.port !== '' && !Number.isFinite(parseInt(url.port))) { + throw new InvalidArgumentError('Invalid URL: port must be a valid integer or a string representation of an integer.') + } - // 3. Append U+0022 (") to value. - value += '"' + if (url.path != null && typeof url.path !== 'string') { + throw new InvalidArgumentError('Invalid URL path: the path must be a string or null/undefined.') } - // 5. Append value to serialization. - serialization += value - } + if (url.pathname != null && typeof url.pathname !== 'string') { + throw new InvalidArgumentError('Invalid URL pathname: the pathname must be a string or null/undefined.') + } - // 3. Return serialization. - return serialization -} + if (url.hostname != null && typeof url.hostname !== 'string') { + throw new InvalidArgumentError('Invalid URL hostname: the hostname must be a string or null/undefined.') + } -/** - * @see https://fetch.spec.whatwg.org/#http-whitespace - * @param {string} char - */ -function isHTTPWhiteSpace (char) { - return char === '\r' || char === '\n' || char === '\t' || char === ' ' -} + if (url.origin != null && typeof url.origin !== 'string') { + throw new InvalidArgumentError('Invalid URL origin: the origin must be a string or null/undefined.') + } -/** - * @see https://fetch.spec.whatwg.org/#http-whitespace - * @param {string} str - */ -function removeHTTPWhitespace (str, leading = true, trailing = true) { - let lead = 0 - let trail = str.length - 1 + const port = url.port != null + ? url.port + : (url.protocol === 'https:' ? 443 : 80) + let origin = url.origin != null + ? url.origin + : `${url.protocol}//${url.hostname}:${port}` + let path = url.path != null + ? url.path + : `${url.pathname || ''}${url.search || ''}` - if (leading) { - for (; lead < str.length && isHTTPWhiteSpace(str[lead]); lead++); - } + if (origin.endsWith('/')) { + origin = origin.substring(0, origin.length - 1) + } - if (trailing) { - for (; trail > 0 && isHTTPWhiteSpace(str[trail]); trail--); + if (path && !path.startsWith('/')) { + path = `/${path}` + } + // new URL(path, origin) is unsafe when `path` contains an absolute URL + // From https://developer.mozilla.org/en-US/docs/Web/API/URL/URL: + // If first parameter is a relative URL, second param is required, and will be used as the base URL. + // If first parameter is an absolute URL, a given second param will be ignored. + url = new URL(origin + path) } - return str.slice(lead, trail + 1) + return url } -/** - * @see https://infra.spec.whatwg.org/#ascii-whitespace - * @param {string} char - */ -function isASCIIWhitespace (char) { - return char === '\r' || char === '\n' || char === '\t' || char === '\f' || char === ' ' +function parseOrigin (url) { + url = parseURL(url) + + if (url.pathname !== '/' || url.search || url.hash) { + throw new InvalidArgumentError('invalid url') + } + + return url } -/** - * @see https://infra.spec.whatwg.org/#strip-leading-and-trailing-ascii-whitespace - */ -function removeASCIIWhitespace (str, leading = true, trailing = true) { - let lead = 0 - let trail = str.length - 1 +function getHostname (host) { + if (host[0] === '[') { + const idx = host.indexOf(']') - if (leading) { - for (; lead < str.length && isASCIIWhitespace(str[lead]); lead++); + assert(idx !== -1) + return host.substring(1, idx) } - if (trailing) { - for (; trail > 0 && isASCIIWhitespace(str[trail]); trail--); - } + const idx = host.indexOf(':') + if (idx === -1) return host - return str.slice(lead, trail + 1) + return host.substring(0, idx) } -module.exports = { - dataURLProcessor, - URLSerializer, - collectASequenceOfCodePoints, - collectASequenceOfCodePointsFast, - stringPercentDecode, - parseMIMEType, - collectAnHTTPQuotedString, - serializeAMimeType -} +// IP addresses are not valid server names per RFC6066 +// > Currently, the only server names supported are DNS hostnames +function getServerName (host) { + if (!host) { + return null + } + assert.strictEqual(typeof host, 'string') -/***/ }), + const servername = getHostname(host) + if (net.isIP(servername)) { + return '' + } -/***/ 8511: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + return servername +} -"use strict"; +function deepClone (obj) { + return JSON.parse(JSON.stringify(obj)) +} +function isAsyncIterable (obj) { + return !!(obj != null && typeof obj[Symbol.asyncIterator] === 'function') +} -const { Blob, File: NativeFile } = __nccwpck_require__(4300) -const { types } = __nccwpck_require__(3837) -const { kState } = __nccwpck_require__(5861) -const { isBlobLike } = __nccwpck_require__(2538) -const { webidl } = __nccwpck_require__(1744) -const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685) -const { kEnumerableProperty } = __nccwpck_require__(3983) -const encoder = new TextEncoder() +function isIterable (obj) { + return !!(obj != null && (typeof obj[Symbol.iterator] === 'function' || typeof obj[Symbol.asyncIterator] === 'function')) +} -class File extends Blob { - constructor (fileBits, fileName, options = {}) { - // The File constructor is invoked with two or three parameters, depending - // on whether the optional dictionary parameter is used. When the File() - // constructor is invoked, user agents must run the following steps: - webidl.argumentLengthCheck(arguments, 2, { header: 'File constructor' }) +function bodyLength (body) { + if (body == null) { + return 0 + } else if (isStream(body)) { + const state = body._readableState + return state && state.objectMode === false && state.ended === true && Number.isFinite(state.length) + ? state.length + : null + } else if (isBlobLike(body)) { + return body.size != null ? body.size : null + } else if (isBuffer(body)) { + return body.byteLength + } - fileBits = webidl.converters['sequence'](fileBits) - fileName = webidl.converters.USVString(fileName) - options = webidl.converters.FilePropertyBag(options) + return null +} - // 1. Let bytes be the result of processing blob parts given fileBits and - // options. - // Note: Blob handles this for us +function isDestroyed (stream) { + return !stream || !!(stream.destroyed || stream[kDestroyed]) +} - // 2. Let n be the fileName argument to the constructor. - const n = fileName +function isReadableAborted (stream) { + const state = stream && stream._readableState + return isDestroyed(stream) && state && !state.endEmitted +} - // 3. Process FilePropertyBag dictionary argument by running the following - // substeps: +function destroy (stream, err) { + if (stream == null || !isStream(stream) || isDestroyed(stream)) { + return + } - // 1. If the type member is provided and is not the empty string, let t - // be set to the type dictionary member. If t contains any characters - // outside the range U+0020 to U+007E, then set t to the empty string - // and return from these substeps. - // 2. Convert every character in t to ASCII lowercase. - let t = options.type - let d - - // eslint-disable-next-line no-labels - substep: { - if (t) { - t = parseMIMEType(t) - - if (t === 'failure') { - t = '' - // eslint-disable-next-line no-labels - break substep - } - - t = serializeAMimeType(t).toLowerCase() - } - - // 3. If the lastModified member is provided, let d be set to the - // lastModified dictionary member. If it is not provided, set d to the - // current date and time represented as the number of milliseconds since - // the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]). - d = options.lastModified - } - - // 4. Return a new File object F such that: - // F refers to the bytes byte sequence. - // F.size is set to the number of total bytes in bytes. - // F.name is set to n. - // F.type is set to t. - // F.lastModified is set to d. - - super(processBlobParts(fileBits, options), { type: t }) - this[kState] = { - name: n, - lastModified: d, - type: t + if (typeof stream.destroy === 'function') { + if (Object.getPrototypeOf(stream).constructor === IncomingMessage) { + // See: https://github.com/nodejs/node/pull/38505/files + stream.socket = null } - } - - get name () { - webidl.brandCheck(this, File) - - return this[kState].name - } - get lastModified () { - webidl.brandCheck(this, File) - - return this[kState].lastModified + stream.destroy(err) + } else if (err) { + process.nextTick((stream, err) => { + stream.emit('error', err) + }, stream, err) } - get type () { - webidl.brandCheck(this, File) - - return this[kState].type + if (stream.destroyed !== true) { + stream[kDestroyed] = true } } -class FileLike { - constructor (blobLike, fileName, options = {}) { - // TODO: argument idl type check - - // The File constructor is invoked with two or three parameters, depending - // on whether the optional dictionary parameter is used. When the File() - // constructor is invoked, user agents must run the following steps: - - // 1. Let bytes be the result of processing blob parts given fileBits and - // options. - - // 2. Let n be the fileName argument to the constructor. - const n = fileName - - // 3. Process FilePropertyBag dictionary argument by running the following - // substeps: - - // 1. If the type member is provided and is not the empty string, let t - // be set to the type dictionary member. If t contains any characters - // outside the range U+0020 to U+007E, then set t to the empty string - // and return from these substeps. - // TODO - const t = options.type - - // 2. Convert every character in t to ASCII lowercase. - // TODO +const KEEPALIVE_TIMEOUT_EXPR = /timeout=(\d+)/ +function parseKeepAliveTimeout (val) { + const m = val.toString().match(KEEPALIVE_TIMEOUT_EXPR) + return m ? parseInt(m[1], 10) * 1000 : null +} - // 3. If the lastModified member is provided, let d be set to the - // lastModified dictionary member. If it is not provided, set d to the - // current date and time represented as the number of milliseconds since - // the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]). - const d = options.lastModified ?? Date.now() +function parseHeaders (headers, obj = {}) { + // For H2 support + if (!Array.isArray(headers)) return headers - // 4. Return a new File object F such that: - // F refers to the bytes byte sequence. - // F.size is set to the number of total bytes in bytes. - // F.name is set to n. - // F.type is set to t. - // F.lastModified is set to d. + for (let i = 0; i < headers.length; i += 2) { + const key = headers[i].toString().toLowerCase() + let val = obj[key] - this[kState] = { - blobLike, - name: n, - type: t, - lastModified: d + if (!val) { + if (Array.isArray(headers[i + 1])) { + obj[key] = headers[i + 1].map(x => x.toString('utf8')) + } else { + obj[key] = headers[i + 1].toString('utf8') + } + } else { + if (!Array.isArray(val)) { + val = [val] + obj[key] = val + } + val.push(headers[i + 1].toString('utf8')) } } - stream (...args) { - webidl.brandCheck(this, FileLike) - - return this[kState].blobLike.stream(...args) + // See https://github.com/nodejs/node/pull/46528 + if ('content-length' in obj && 'content-disposition' in obj) { + obj['content-disposition'] = Buffer.from(obj['content-disposition']).toString('latin1') } - arrayBuffer (...args) { - webidl.brandCheck(this, FileLike) + return obj +} - return this[kState].blobLike.arrayBuffer(...args) - } +function parseRawHeaders (headers) { + const ret = [] + let hasContentLength = false + let contentDispositionIdx = -1 - slice (...args) { - webidl.brandCheck(this, FileLike) + for (let n = 0; n < headers.length; n += 2) { + const key = headers[n + 0].toString() + const val = headers[n + 1].toString('utf8') - return this[kState].blobLike.slice(...args) + if (key.length === 14 && (key === 'content-length' || key.toLowerCase() === 'content-length')) { + ret.push(key, val) + hasContentLength = true + } else if (key.length === 19 && (key === 'content-disposition' || key.toLowerCase() === 'content-disposition')) { + contentDispositionIdx = ret.push(key, val) - 1 + } else { + ret.push(key, val) + } } - text (...args) { - webidl.brandCheck(this, FileLike) - - return this[kState].blobLike.text(...args) + // See https://github.com/nodejs/node/pull/46528 + if (hasContentLength && contentDispositionIdx !== -1) { + ret[contentDispositionIdx] = Buffer.from(ret[contentDispositionIdx]).toString('latin1') } - get size () { - webidl.brandCheck(this, FileLike) - - return this[kState].blobLike.size - } + return ret +} - get type () { - webidl.brandCheck(this, FileLike) +function isBuffer (buffer) { + // See, https://github.com/mcollina/undici/pull/319 + return buffer instanceof Uint8Array || Buffer.isBuffer(buffer) +} - return this[kState].blobLike.type +function validateHandler (handler, method, upgrade) { + if (!handler || typeof handler !== 'object') { + throw new InvalidArgumentError('handler must be an object') } - get name () { - webidl.brandCheck(this, FileLike) - - return this[kState].name + if (typeof handler.onConnect !== 'function') { + throw new InvalidArgumentError('invalid onConnect method') } - get lastModified () { - webidl.brandCheck(this, FileLike) - - return this[kState].lastModified + if (typeof handler.onError !== 'function') { + throw new InvalidArgumentError('invalid onError method') } - get [Symbol.toStringTag] () { - return 'File' + if (typeof handler.onBodySent !== 'function' && handler.onBodySent !== undefined) { + throw new InvalidArgumentError('invalid onBodySent method') } -} - -Object.defineProperties(File.prototype, { - [Symbol.toStringTag]: { - value: 'File', - configurable: true - }, - name: kEnumerableProperty, - lastModified: kEnumerableProperty -}) -webidl.converters.Blob = webidl.interfaceConverter(Blob) + if (upgrade || method === 'CONNECT') { + if (typeof handler.onUpgrade !== 'function') { + throw new InvalidArgumentError('invalid onUpgrade method') + } + } else { + if (typeof handler.onHeaders !== 'function') { + throw new InvalidArgumentError('invalid onHeaders method') + } -webidl.converters.BlobPart = function (V, opts) { - if (webidl.util.Type(V) === 'Object') { - if (isBlobLike(V)) { - return webidl.converters.Blob(V, { strict: false }) + if (typeof handler.onData !== 'function') { + throw new InvalidArgumentError('invalid onData method') } - if ( - ArrayBuffer.isView(V) || - types.isAnyArrayBuffer(V) - ) { - return webidl.converters.BufferSource(V, opts) + if (typeof handler.onComplete !== 'function') { + throw new InvalidArgumentError('invalid onComplete method') } } - - return webidl.converters.USVString(V, opts) } -webidl.converters['sequence'] = webidl.sequenceConverter( - webidl.converters.BlobPart -) +// A body is disturbed if it has been read from and it cannot +// be re-used without losing state or data. +function isDisturbed (body) { + return !!(body && ( + stream.isDisturbed + ? stream.isDisturbed(body) || body[kBodyUsed] // TODO (fix): Why is body[kBodyUsed] needed? + : body[kBodyUsed] || + body.readableDidRead || + (body._readableState && body._readableState.dataEmitted) || + isReadableAborted(body) + )) +} -// https://www.w3.org/TR/FileAPI/#dfn-FilePropertyBag -webidl.converters.FilePropertyBag = webidl.dictionaryConverter([ - { - key: 'lastModified', - converter: webidl.converters['long long'], - get defaultValue () { - return Date.now() - } - }, - { - key: 'type', - converter: webidl.converters.DOMString, - defaultValue: '' - }, - { - key: 'endings', - converter: (value) => { - value = webidl.converters.DOMString(value) - value = value.toLowerCase() +function isErrored (body) { + return !!(body && ( + stream.isErrored + ? stream.isErrored(body) + : /state: 'errored'/.test(nodeUtil.inspect(body) + ))) +} - if (value !== 'native') { - value = 'transparent' - } +function isReadable (body) { + return !!(body && ( + stream.isReadable + ? stream.isReadable(body) + : /state: 'readable'/.test(nodeUtil.inspect(body) + ))) +} - return value - }, - defaultValue: 'transparent' +function getSocketInfo (socket) { + return { + localAddress: socket.localAddress, + localPort: socket.localPort, + remoteAddress: socket.remoteAddress, + remotePort: socket.remotePort, + remoteFamily: socket.remoteFamily, + timeout: socket.timeout, + bytesWritten: socket.bytesWritten, + bytesRead: socket.bytesRead } -]) +} -/** - * @see https://www.w3.org/TR/FileAPI/#process-blob-parts - * @param {(NodeJS.TypedArray|Blob|string)[]} parts - * @param {{ type: string, endings: string }} options - */ -function processBlobParts (parts, options) { - // 1. Let bytes be an empty sequence of bytes. - /** @type {NodeJS.TypedArray[]} */ - const bytes = [] +async function * convertIterableToBuffer (iterable) { + for await (const chunk of iterable) { + yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk) + } +} - // 2. For each element in parts: - for (const element of parts) { - // 1. If element is a USVString, run the following substeps: - if (typeof element === 'string') { - // 1. Let s be element. - let s = element +let ReadableStream +function ReadableStreamFrom (iterable) { + if (!ReadableStream) { + ReadableStream = (__nccwpck_require__(5356).ReadableStream) + } - // 2. If the endings member of options is "native", set s - // to the result of converting line endings to native - // of element. - if (options.endings === 'native') { - s = convertLineEndingsNative(s) - } + if (ReadableStream.from) { + return ReadableStream.from(convertIterableToBuffer(iterable)) + } - // 3. Append the result of UTF-8 encoding s to bytes. - bytes.push(encoder.encode(s)) - } else if ( - types.isAnyArrayBuffer(element) || - types.isTypedArray(element) - ) { - // 2. If element is a BufferSource, get a copy of the - // bytes held by the buffer source, and append those - // bytes to bytes. - if (!element.buffer) { // ArrayBuffer - bytes.push(new Uint8Array(element)) - } else { - bytes.push( - new Uint8Array(element.buffer, element.byteOffset, element.byteLength) - ) + let iterator + return new ReadableStream( + { + async start () { + iterator = iterable[Symbol.asyncIterator]() + }, + async pull (controller) { + const { done, value } = await iterator.next() + if (done) { + queueMicrotask(() => { + controller.close() + }) + } else { + const buf = Buffer.isBuffer(value) ? value : Buffer.from(value) + controller.enqueue(new Uint8Array(buf)) + } + return controller.desiredSize > 0 + }, + async cancel (reason) { + await iterator.return() } - } else if (isBlobLike(element)) { - // 3. If element is a Blob, append the bytes it represents - // to bytes. - bytes.push(element) + }, + 0 + ) +} + +// The chunk should be a FormData instance and contains +// all the required methods. +function isFormDataLike (object) { + return ( + object && + typeof object === 'object' && + typeof object.append === 'function' && + typeof object.delete === 'function' && + typeof object.get === 'function' && + typeof object.getAll === 'function' && + typeof object.has === 'function' && + typeof object.set === 'function' && + object[Symbol.toStringTag] === 'FormData' + ) +} + +function throwIfAborted (signal) { + if (!signal) { return } + if (typeof signal.throwIfAborted === 'function') { + signal.throwIfAborted() + } else { + if (signal.aborted) { + // DOMException not available < v17.0.0 + const err = new Error('The operation was aborted') + err.name = 'AbortError' + throw err } } +} - // 3. Return bytes. - return bytes +function addAbortListener (signal, listener) { + if ('addEventListener' in signal) { + signal.addEventListener('abort', listener, { once: true }) + return () => signal.removeEventListener('abort', listener) + } + signal.addListener('abort', listener) + return () => signal.removeListener('abort', listener) } +const hasToWellFormed = !!String.prototype.toWellFormed + /** - * @see https://www.w3.org/TR/FileAPI/#convert-line-endings-to-native - * @param {string} s + * @param {string} val */ -function convertLineEndingsNative (s) { - // 1. Let native line ending be be the code point U+000A LF. - let nativeLineEnding = '\n' - - // 2. If the underlying platform’s conventions are to - // represent newlines as a carriage return and line feed - // sequence, set native line ending to the code point - // U+000D CR followed by the code point U+000A LF. - if (process.platform === 'win32') { - nativeLineEnding = '\r\n' +function toUSVString (val) { + if (hasToWellFormed) { + return `${val}`.toWellFormed() + } else if (nodeUtil.toUSVString) { + return nodeUtil.toUSVString(val) } - return s.replace(/\r?\n/g, nativeLineEnding) + return `${val}` } -// If this function is moved to ./util.js, some tools (such as -// rollup) will warn about circular dependencies. See: -// https://github.com/nodejs/undici/issues/1629 -function isFileLike (object) { - return ( - (NativeFile && object instanceof NativeFile) || - object instanceof File || ( - object && - (typeof object.stream === 'function' || - typeof object.arrayBuffer === 'function') && - object[Symbol.toStringTag] === 'File' - ) - ) +// Parsed accordingly to RFC 9110 +// https://www.rfc-editor.org/rfc/rfc9110#field.content-range +function parseRangeHeader (range) { + if (range == null || range === '') return { start: 0, end: null, size: null } + + const m = range ? range.match(/^bytes (\d+)-(\d+)\/(\d+)?$/) : null + return m + ? { + start: parseInt(m[1]), + end: m[2] ? parseInt(m[2]) : null, + size: m[3] ? parseInt(m[3]) : null + } + : null } -module.exports = { File, FileLike, isFileLike } +const kEnumerableProperty = Object.create(null) +kEnumerableProperty.enumerable = true + +module.exports = { + kEnumerableProperty, + nop, + isDisturbed, + isErrored, + isReadable, + toUSVString, + isReadableAborted, + isBlobLike, + parseOrigin, + parseURL, + getServerName, + isStream, + isIterable, + isAsyncIterable, + isDestroyed, + parseRawHeaders, + parseHeaders, + parseKeepAliveTimeout, + destroy, + bodyLength, + deepClone, + ReadableStreamFrom, + isBuffer, + validateHandler, + getSocketInfo, + isFormDataLike, + buildURL, + throwIfAborted, + addAbortListener, + parseRangeHeader, + nodeMajor, + nodeMinor, + nodeHasAutoSelectFamily: nodeMajor > 18 || (nodeMajor === 18 && nodeMinor >= 13), + safeHTTPMethods: ['GET', 'HEAD', 'OPTIONS', 'TRACE'] +} /***/ }), -/***/ 2015: +/***/ 4839: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { isBlobLike, toUSVString, makeIterator } = __nccwpck_require__(2538) -const { kState } = __nccwpck_require__(5861) -const { File: UndiciFile, FileLike, isFileLike } = __nccwpck_require__(8511) -const { webidl } = __nccwpck_require__(1744) -const { Blob, File: NativeFile } = __nccwpck_require__(4300) +const Dispatcher = __nccwpck_require__(412) +const { + ClientDestroyedError, + ClientClosedError, + InvalidArgumentError +} = __nccwpck_require__(8045) +const { kDestroy, kClose, kDispatch, kInterceptors } = __nccwpck_require__(2785) -/** @type {globalThis['File']} */ -const File = NativeFile ?? UndiciFile +const kDestroyed = Symbol('destroyed') +const kClosed = Symbol('closed') +const kOnDestroyed = Symbol('onDestroyed') +const kOnClosed = Symbol('onClosed') +const kInterceptedDispatch = Symbol('Intercepted Dispatch') -// https://xhr.spec.whatwg.org/#formdata -class FormData { - constructor (form) { - if (form !== undefined) { - throw webidl.errors.conversionFailed({ - prefix: 'FormData constructor', - argument: 'Argument 1', - types: ['undefined'] - }) - } +class DispatcherBase extends Dispatcher { + constructor () { + super() - this[kState] = [] + this[kDestroyed] = false + this[kOnDestroyed] = null + this[kClosed] = false + this[kOnClosed] = [] } - append (name, value, filename = undefined) { - webidl.brandCheck(this, FormData) + get destroyed () { + return this[kDestroyed] + } - webidl.argumentLengthCheck(arguments, 2, { header: 'FormData.append' }) + get closed () { + return this[kClosed] + } - if (arguments.length === 3 && !isBlobLike(value)) { - throw new TypeError( - "Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'" - ) + get interceptors () { + return this[kInterceptors] + } + + set interceptors (newInterceptors) { + if (newInterceptors) { + for (let i = newInterceptors.length - 1; i >= 0; i--) { + const interceptor = this[kInterceptors][i] + if (typeof interceptor !== 'function') { + throw new InvalidArgumentError('interceptor must be an function') + } + } } - // 1. Let value be value if given; otherwise blobValue. + this[kInterceptors] = newInterceptors + } - name = webidl.converters.USVString(name) - value = isBlobLike(value) - ? webidl.converters.Blob(value, { strict: false }) - : webidl.converters.USVString(value) - filename = arguments.length === 3 - ? webidl.converters.USVString(filename) - : undefined + close (callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + this.close((err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } - // 2. Let entry be the result of creating an entry with - // name, value, and filename if given. - const entry = makeEntry(name, value, filename) + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } - // 3. Append entry to this’s entry list. - this[kState].push(entry) - } + if (this[kDestroyed]) { + queueMicrotask(() => callback(new ClientDestroyedError(), null)) + return + } - delete (name) { - webidl.brandCheck(this, FormData) + if (this[kClosed]) { + if (this[kOnClosed]) { + this[kOnClosed].push(callback) + } else { + queueMicrotask(() => callback(null, null)) + } + return + } - webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.delete' }) + this[kClosed] = true + this[kOnClosed].push(callback) - name = webidl.converters.USVString(name) + const onClosed = () => { + const callbacks = this[kOnClosed] + this[kOnClosed] = null + for (let i = 0; i < callbacks.length; i++) { + callbacks[i](null, null) + } + } - // The delete(name) method steps are to remove all entries whose name - // is name from this’s entry list. - this[kState] = this[kState].filter(entry => entry.name !== name) + // Should not error. + this[kClose]() + .then(() => this.destroy()) + .then(() => { + queueMicrotask(onClosed) + }) } - get (name) { - webidl.brandCheck(this, FormData) + destroy (err, callback) { + if (typeof err === 'function') { + callback = err + err = null + } - webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.get' }) + if (callback === undefined) { + return new Promise((resolve, reject) => { + this.destroy(err, (err, data) => { + return err ? /* istanbul ignore next: should never error */ reject(err) : resolve(data) + }) + }) + } - name = webidl.converters.USVString(name) + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } - // 1. If there is no entry whose name is name in this’s entry list, - // then return null. - const idx = this[kState].findIndex((entry) => entry.name === name) - if (idx === -1) { - return null + if (this[kDestroyed]) { + if (this[kOnDestroyed]) { + this[kOnDestroyed].push(callback) + } else { + queueMicrotask(() => callback(null, null)) + } + return } - // 2. Return the value of the first entry whose name is name from - // this’s entry list. - return this[kState][idx].value - } + if (!err) { + err = new ClientDestroyedError() + } - getAll (name) { - webidl.brandCheck(this, FormData) + this[kDestroyed] = true + this[kOnDestroyed] = this[kOnDestroyed] || [] + this[kOnDestroyed].push(callback) - webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.getAll' }) + const onDestroyed = () => { + const callbacks = this[kOnDestroyed] + this[kOnDestroyed] = null + for (let i = 0; i < callbacks.length; i++) { + callbacks[i](null, null) + } + } - name = webidl.converters.USVString(name) + // Should not error. + this[kDestroy](err).then(() => { + queueMicrotask(onDestroyed) + }) + } - // 1. If there is no entry whose name is name in this’s entry list, - // then return the empty list. - // 2. Return the values of all entries whose name is name, in order, - // from this’s entry list. - return this[kState] - .filter((entry) => entry.name === name) - .map((entry) => entry.value) + [kInterceptedDispatch] (opts, handler) { + if (!this[kInterceptors] || this[kInterceptors].length === 0) { + this[kInterceptedDispatch] = this[kDispatch] + return this[kDispatch](opts, handler) + } + + let dispatch = this[kDispatch].bind(this) + for (let i = this[kInterceptors].length - 1; i >= 0; i--) { + dispatch = this[kInterceptors][i](dispatch) + } + this[kInterceptedDispatch] = dispatch + return dispatch(opts, handler) } - has (name) { - webidl.brandCheck(this, FormData) + dispatch (opts, handler) { + if (!handler || typeof handler !== 'object') { + throw new InvalidArgumentError('handler must be an object') + } - webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.has' }) + try { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('opts must be an object.') + } - name = webidl.converters.USVString(name) + if (this[kDestroyed] || this[kOnDestroyed]) { + throw new ClientDestroyedError() + } - // The has(name) method steps are to return true if there is an entry - // whose name is name in this’s entry list; otherwise false. - return this[kState].findIndex((entry) => entry.name === name) !== -1 - } + if (this[kClosed]) { + throw new ClientClosedError() + } - set (name, value, filename = undefined) { - webidl.brandCheck(this, FormData) + return this[kInterceptedDispatch](opts, handler) + } catch (err) { + if (typeof handler.onError !== 'function') { + throw new InvalidArgumentError('invalid onError method') + } - webidl.argumentLengthCheck(arguments, 2, { header: 'FormData.set' }) + handler.onError(err) - if (arguments.length === 3 && !isBlobLike(value)) { - throw new TypeError( - "Failed to execute 'set' on 'FormData': parameter 2 is not of type 'Blob'" - ) + return false } + } +} - // The set(name, value) and set(name, blobValue, filename) method steps - // are: +module.exports = DispatcherBase - // 1. Let value be value if given; otherwise blobValue. - name = webidl.converters.USVString(name) - value = isBlobLike(value) - ? webidl.converters.Blob(value, { strict: false }) - : webidl.converters.USVString(value) - filename = arguments.length === 3 - ? toUSVString(filename) - : undefined +/***/ }), - // 2. Let entry be the result of creating an entry with name, value, and - // filename if given. - const entry = makeEntry(name, value, filename) +/***/ 412: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // 3. If there are entries in this’s entry list whose name is name, then - // replace the first such entry with entry and remove the others. - const idx = this[kState].findIndex((entry) => entry.name === name) - if (idx !== -1) { - this[kState] = [ - ...this[kState].slice(0, idx), - entry, - ...this[kState].slice(idx + 1).filter((entry) => entry.name !== name) - ] - } else { - // 4. Otherwise, append entry to this’s entry list. - this[kState].push(entry) - } - } - - entries () { - webidl.brandCheck(this, FormData) - - return makeIterator( - () => this[kState].map(pair => [pair.name, pair.value]), - 'FormData', - 'key+value' - ) - } - - keys () { - webidl.brandCheck(this, FormData) - - return makeIterator( - () => this[kState].map(pair => [pair.name, pair.value]), - 'FormData', - 'key' - ) - } - - values () { - webidl.brandCheck(this, FormData) - - return makeIterator( - () => this[kState].map(pair => [pair.name, pair.value]), - 'FormData', - 'value' - ) - } - - /** - * @param {(value: string, key: string, self: FormData) => void} callbackFn - * @param {unknown} thisArg - */ - forEach (callbackFn, thisArg = globalThis) { - webidl.brandCheck(this, FormData) +"use strict"; - webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.forEach' }) - if (typeof callbackFn !== 'function') { - throw new TypeError( - "Failed to execute 'forEach' on 'FormData': parameter 1 is not of type 'Function'." - ) - } +const EventEmitter = __nccwpck_require__(2361) - for (const [key, value] of this) { - callbackFn.apply(thisArg, [value, key, this]) - } +class Dispatcher extends EventEmitter { + dispatch () { + throw new Error('not implemented') } -} - -FormData.prototype[Symbol.iterator] = FormData.prototype.entries -Object.defineProperties(FormData.prototype, { - [Symbol.toStringTag]: { - value: 'FormData', - configurable: true + close () { + throw new Error('not implemented') } -}) - -/** - * @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#create-an-entry - * @param {string} name - * @param {string|Blob} value - * @param {?string} filename - * @returns - */ -function makeEntry (name, value, filename) { - // 1. Set name to the result of converting name into a scalar value string. - // "To convert a string into a scalar value string, replace any surrogates - // with U+FFFD." - // see: https://nodejs.org/dist/latest-v18.x/docs/api/buffer.html#buftostringencoding-start-end - name = Buffer.from(name).toString('utf8') - - // 2. If value is a string, then set value to the result of converting - // value into a scalar value string. - if (typeof value === 'string') { - value = Buffer.from(value).toString('utf8') - } else { - // 3. Otherwise: - - // 1. If value is not a File object, then set value to a new File object, - // representing the same bytes, whose name attribute value is "blob" - if (!isFileLike(value)) { - value = value instanceof Blob - ? new File([value], 'blob', { type: value.type }) - : new FileLike(value, 'blob', { type: value.type }) - } - - // 2. If filename is given, then set value to a new File object, - // representing the same bytes, whose name attribute is filename. - if (filename !== undefined) { - /** @type {FilePropertyBag} */ - const options = { - type: value.type, - lastModified: value.lastModified - } - value = (NativeFile && value instanceof NativeFile) || value instanceof UndiciFile - ? new File([value], filename, options) - : new FileLike(value, filename, options) - } + destroy () { + throw new Error('not implemented') } - - // 4. Return an entry whose name is name and whose value is value. - return { name, value } } -module.exports = { FormData } +module.exports = Dispatcher /***/ }), -/***/ 1246: -/***/ ((module) => { +/***/ 1472: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -// In case of breaking changes, increase the version -// number to avoid conflicts. -const globalOrigin = Symbol.for('undici.globalOrigin.1') +const Busboy = __nccwpck_require__(727) +const util = __nccwpck_require__(3983) +const { + ReadableStreamFrom, + isBlobLike, + isReadableStreamLike, + readableStreamClose, + createDeferredPromise, + fullyReadBody +} = __nccwpck_require__(2538) +const { FormData } = __nccwpck_require__(2015) +const { kState } = __nccwpck_require__(5861) +const { webidl } = __nccwpck_require__(1744) +const { DOMException, structuredClone } = __nccwpck_require__(1037) +const { Blob, File: NativeFile } = __nccwpck_require__(4300) +const { kBodyUsed } = __nccwpck_require__(2785) +const assert = __nccwpck_require__(9491) +const { isErrored } = __nccwpck_require__(3983) +const { isUint8Array, isArrayBuffer } = __nccwpck_require__(9830) +const { File: UndiciFile } = __nccwpck_require__(8511) +const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685) -function getGlobalOrigin () { - return globalThis[globalOrigin] -} +let ReadableStream = globalThis.ReadableStream -function setGlobalOrigin (newOrigin) { - if (newOrigin === undefined) { - Object.defineProperty(globalThis, globalOrigin, { - value: undefined, - writable: true, - enumerable: false, - configurable: false - }) +/** @type {globalThis['File']} */ +const File = NativeFile ?? UndiciFile +const textEncoder = new TextEncoder() +const textDecoder = new TextDecoder() - return +// https://fetch.spec.whatwg.org/#concept-bodyinit-extract +function extractBody (object, keepalive = false) { + if (!ReadableStream) { + ReadableStream = (__nccwpck_require__(5356).ReadableStream) } - const parsedURL = new URL(newOrigin) + // 1. Let stream be null. + let stream = null - if (parsedURL.protocol !== 'http:' && parsedURL.protocol !== 'https:') { - throw new TypeError(`Only http & https urls are allowed, received ${parsedURL.protocol}`) + // 2. If object is a ReadableStream object, then set stream to object. + if (object instanceof ReadableStream) { + stream = object + } else if (isBlobLike(object)) { + // 3. Otherwise, if object is a Blob object, set stream to the + // result of running object’s get stream. + stream = object.stream() + } else { + // 4. Otherwise, set stream to a new ReadableStream object, and set + // up stream. + stream = new ReadableStream({ + async pull (controller) { + controller.enqueue( + typeof source === 'string' ? textEncoder.encode(source) : source + ) + queueMicrotask(() => readableStreamClose(controller)) + }, + start () {}, + type: undefined + }) } - Object.defineProperty(globalThis, globalOrigin, { - value: parsedURL, - writable: true, - enumerable: false, - configurable: false - }) -} - -module.exports = { - getGlobalOrigin, - setGlobalOrigin -} + // 5. Assert: stream is a ReadableStream object. + assert(isReadableStreamLike(stream)) + // 6. Let action be null. + let action = null -/***/ }), + // 7. Let source be null. + let source = null -/***/ 554: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // 8. Let length be null. + let length = null -"use strict"; -// https://github.com/Ethan-Arrowood/undici-fetch + // 9. Let type be null. + let type = null + // 10. Switch on object: + if (typeof object === 'string') { + // Set source to the UTF-8 encoding of object. + // Note: setting source to a Uint8Array here breaks some mocking assumptions. + source = object + // Set type to `text/plain;charset=UTF-8`. + type = 'text/plain;charset=UTF-8' + } else if (object instanceof URLSearchParams) { + // URLSearchParams -const { kHeadersList, kConstruct } = __nccwpck_require__(2785) -const { kGuard } = __nccwpck_require__(5861) -const { kEnumerableProperty } = __nccwpck_require__(3983) -const { - makeIterator, - isValidHeaderName, - isValidHeaderValue -} = __nccwpck_require__(2538) -const { webidl } = __nccwpck_require__(1744) -const assert = __nccwpck_require__(9491) + // spec says to run application/x-www-form-urlencoded on body.list + // this is implemented in Node.js as apart of an URLSearchParams instance toString method + // See: https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/lib/internal/url.js#L490 + // and https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/lib/internal/url.js#L1100 -const kHeadersMap = Symbol('headers map') -const kHeadersSortedMap = Symbol('headers map sorted') + // Set source to the result of running the application/x-www-form-urlencoded serializer with object’s list. + source = object.toString() -/** - * @param {number} code - */ -function isHTTPWhiteSpaceCharCode (code) { - return code === 0x00a || code === 0x00d || code === 0x009 || code === 0x020 -} + // Set type to `application/x-www-form-urlencoded;charset=UTF-8`. + type = 'application/x-www-form-urlencoded;charset=UTF-8' + } else if (isArrayBuffer(object)) { + // BufferSource/ArrayBuffer -/** - * @see https://fetch.spec.whatwg.org/#concept-header-value-normalize - * @param {string} potentialValue - */ -function headerValueNormalize (potentialValue) { - // To normalize a byte sequence potentialValue, remove - // any leading and trailing HTTP whitespace bytes from - // potentialValue. - let i = 0; let j = potentialValue.length + // Set source to a copy of the bytes held by object. + source = new Uint8Array(object.slice()) + } else if (ArrayBuffer.isView(object)) { + // BufferSource/ArrayBufferView - while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(j - 1))) --j - while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(i))) ++i + // Set source to a copy of the bytes held by object. + source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength)) + } else if (util.isFormDataLike(object)) { + const boundary = `----formdata-undici-0${`${Math.floor(Math.random() * 1e11)}`.padStart(11, '0')}` + const prefix = `--${boundary}\r\nContent-Disposition: form-data` - return i === 0 && j === potentialValue.length ? potentialValue : potentialValue.substring(i, j) -} + /*! formdata-polyfill. MIT License. Jimmy Wärting */ + const escape = (str) => + str.replace(/\n/g, '%0A').replace(/\r/g, '%0D').replace(/"/g, '%22') + const normalizeLinefeeds = (value) => value.replace(/\r?\n|\r/g, '\r\n') -function fill (headers, object) { - // To fill a Headers object headers with a given object object, run these steps: + // Set action to this step: run the multipart/form-data + // encoding algorithm, with object’s entry list and UTF-8. + // - This ensures that the body is immutable and can't be changed afterwords + // - That the content-length is calculated in advance. + // - And that all parts are pre-encoded and ready to be sent. - // 1. If object is a sequence, then for each header in object: - // Note: webidl conversion to array has already been done. - if (Array.isArray(object)) { - for (let i = 0; i < object.length; ++i) { - const header = object[i] - // 1. If header does not contain exactly two items, then throw a TypeError. - if (header.length !== 2) { - throw webidl.errors.exception({ - header: 'Headers constructor', - message: `expected name/value pair to be length 2, found ${header.length}.` - }) + const blobParts = [] + const rn = new Uint8Array([13, 10]) // '\r\n' + length = 0 + let hasUnknownSizeValue = false + + for (const [name, value] of object) { + if (typeof value === 'string') { + const chunk = textEncoder.encode(prefix + + `; name="${escape(normalizeLinefeeds(name))}"` + + `\r\n\r\n${normalizeLinefeeds(value)}\r\n`) + blobParts.push(chunk) + length += chunk.byteLength + } else { + const chunk = textEncoder.encode(`${prefix}; name="${escape(normalizeLinefeeds(name))}"` + + (value.name ? `; filename="${escape(value.name)}"` : '') + '\r\n' + + `Content-Type: ${ + value.type || 'application/octet-stream' + }\r\n\r\n`) + blobParts.push(chunk, value, rn) + if (typeof value.size === 'number') { + length += chunk.byteLength + value.size + rn.byteLength + } else { + hasUnknownSizeValue = true + } } + } - // 2. Append (header’s first item, header’s second item) to headers. - appendHeader(headers, header[0], header[1]) + const chunk = textEncoder.encode(`--${boundary}--`) + blobParts.push(chunk) + length += chunk.byteLength + if (hasUnknownSizeValue) { + length = null } - } else if (typeof object === 'object' && object !== null) { - // Note: null should throw - // 2. Otherwise, object is a record, then for each key → value in object, - // append (key, value) to headers - const keys = Object.keys(object) - for (let i = 0; i < keys.length; ++i) { - appendHeader(headers, keys[i], object[keys[i]]) + // Set source to object. + source = object + + action = async function * () { + for (const part of blobParts) { + if (part.stream) { + yield * part.stream() + } else { + yield part + } + } } - } else { - throw webidl.errors.conversionFailed({ - prefix: 'Headers constructor', - argument: 'Argument 1', - types: ['sequence>', 'record'] - }) - } -} -/** - * @see https://fetch.spec.whatwg.org/#concept-headers-append - */ -function appendHeader (headers, name, value) { - // 1. Normalize value. - value = headerValueNormalize(value) + // Set type to `multipart/form-data; boundary=`, + // followed by the multipart/form-data boundary string generated + // by the multipart/form-data encoding algorithm. + type = 'multipart/form-data; boundary=' + boundary + } else if (isBlobLike(object)) { + // Blob - // 2. If name is not a header name or value is not a - // header value, then throw a TypeError. - if (!isValidHeaderName(name)) { - throw webidl.errors.invalidArgument({ - prefix: 'Headers.append', - value: name, - type: 'header name' - }) - } else if (!isValidHeaderValue(value)) { - throw webidl.errors.invalidArgument({ - prefix: 'Headers.append', - value, - type: 'header value' - }) + // Set source to object. + source = object + + // Set length to object’s size. + length = object.size + + // If object’s type attribute is not the empty byte sequence, set + // type to its value. + if (object.type) { + type = object.type + } + } else if (typeof object[Symbol.asyncIterator] === 'function') { + // If keepalive is true, then throw a TypeError. + if (keepalive) { + throw new TypeError('keepalive') + } + + // If object is disturbed or locked, then throw a TypeError. + if (util.isDisturbed(object) || object.locked) { + throw new TypeError( + 'Response body object should not be disturbed or locked' + ) + } + + stream = + object instanceof ReadableStream ? object : ReadableStreamFrom(object) } - // 3. If headers’s guard is "immutable", then throw a TypeError. - // 4. Otherwise, if headers’s guard is "request" and name is a - // forbidden header name, return. - // Note: undici does not implement forbidden header names - if (headers[kGuard] === 'immutable') { - throw new TypeError('immutable') - } else if (headers[kGuard] === 'request-no-cors') { - // 5. Otherwise, if headers’s guard is "request-no-cors": - // TODO + // 11. If source is a byte sequence, then set action to a + // step that returns source and length to source’s length. + if (typeof source === 'string' || util.isBuffer(source)) { + length = Buffer.byteLength(source) } - // 6. Otherwise, if headers’s guard is "response" and name is a - // forbidden response-header name, return. + // 12. If action is non-null, then run these steps in in parallel: + if (action != null) { + // Run action. + let iterator + stream = new ReadableStream({ + async start () { + iterator = action(object)[Symbol.asyncIterator]() + }, + async pull (controller) { + const { value, done } = await iterator.next() + if (done) { + // When running action is done, close stream. + queueMicrotask(() => { + controller.close() + }) + } else { + // Whenever one or more bytes are available and stream is not errored, + // enqueue a Uint8Array wrapping an ArrayBuffer containing the available + // bytes into stream. + if (!isErrored(stream)) { + controller.enqueue(new Uint8Array(value)) + } + } + return controller.desiredSize > 0 + }, + async cancel (reason) { + await iterator.return() + }, + type: undefined + }) + } - // 7. Append (name, value) to headers’s header list. - return headers[kHeadersList].append(name, value) + // 13. Let body be a body whose stream is stream, source is source, + // and length is length. + const body = { stream, source, length } - // 8. If headers’s guard is "request-no-cors", then remove - // privileged no-CORS request headers from headers + // 14. Return (body, type). + return [body, type] } -class HeadersList { - /** @type {[string, string][]|null} */ - cookies = null - - constructor (init) { - if (init instanceof HeadersList) { - this[kHeadersMap] = new Map(init[kHeadersMap]) - this[kHeadersSortedMap] = init[kHeadersSortedMap] - this.cookies = init.cookies === null ? null : [...init.cookies] - } else { - this[kHeadersMap] = new Map(init) - this[kHeadersSortedMap] = null - } +// https://fetch.spec.whatwg.org/#bodyinit-safely-extract +function safelyExtractBody (object, keepalive = false) { + if (!ReadableStream) { + // istanbul ignore next + ReadableStream = (__nccwpck_require__(5356).ReadableStream) } - // https://fetch.spec.whatwg.org/#header-list-contains - contains (name) { - // A header list list contains a header name name if list - // contains a header whose name is a byte-case-insensitive - // match for name. - name = name.toLowerCase() + // To safely extract a body and a `Content-Type` value from + // a byte sequence or BodyInit object object, run these steps: - return this[kHeadersMap].has(name) + // 1. If object is a ReadableStream object, then: + if (object instanceof ReadableStream) { + // Assert: object is neither disturbed nor locked. + // istanbul ignore next + assert(!util.isDisturbed(object), 'The body has already been consumed.') + // istanbul ignore next + assert(!object.locked, 'The stream is locked.') } - clear () { - this[kHeadersMap].clear() - this[kHeadersSortedMap] = null - this.cookies = null - } + // 2. Return the results of extracting object. + return extractBody(object, keepalive) +} - // https://fetch.spec.whatwg.org/#concept-header-list-append - append (name, value) { - this[kHeadersSortedMap] = null +function cloneBody (body) { + // To clone a body body, run these steps: - // 1. If list contains name, then set name to the first such - // header’s name. - const lowercaseName = name.toLowerCase() - const exists = this[kHeadersMap].get(lowercaseName) - - // 2. Append (name, value) to list. - if (exists) { - const delimiter = lowercaseName === 'cookie' ? '; ' : ', ' - this[kHeadersMap].set(lowercaseName, { - name: exists.name, - value: `${exists.value}${delimiter}${value}` - }) - } else { - this[kHeadersMap].set(lowercaseName, { name, value }) - } - - if (lowercaseName === 'set-cookie') { - this.cookies ??= [] - this.cookies.push(value) - } - } + // https://fetch.spec.whatwg.org/#concept-body-clone - // https://fetch.spec.whatwg.org/#concept-header-list-set - set (name, value) { - this[kHeadersSortedMap] = null - const lowercaseName = name.toLowerCase() + // 1. Let « out1, out2 » be the result of teeing body’s stream. + const [out1, out2] = body.stream.tee() + const out2Clone = structuredClone(out2, { transfer: [out2] }) + // This, for whatever reasons, unrefs out2Clone which allows + // the process to exit by itself. + const [, finalClone] = out2Clone.tee() - if (lowercaseName === 'set-cookie') { - this.cookies = [value] - } + // 2. Set body’s stream to out1. + body.stream = out1 - // 1. If list contains name, then set the value of - // the first such header to value and remove the - // others. - // 2. Otherwise, append header (name, value) to list. - this[kHeadersMap].set(lowercaseName, { name, value }) + // 3. Return a body whose stream is out2 and other members are copied from body. + return { + stream: finalClone, + length: body.length, + source: body.source } +} - // https://fetch.spec.whatwg.org/#concept-header-list-delete - delete (name) { - this[kHeadersSortedMap] = null - - name = name.toLowerCase() - - if (name === 'set-cookie') { - this.cookies = null - } +async function * consumeBody (body) { + if (body) { + if (isUint8Array(body)) { + yield body + } else { + const stream = body.stream - this[kHeadersMap].delete(name) - } + if (util.isDisturbed(stream)) { + throw new TypeError('The body has already been consumed.') + } - // https://fetch.spec.whatwg.org/#concept-header-list-get - get (name) { - const value = this[kHeadersMap].get(name.toLowerCase()) + if (stream.locked) { + throw new TypeError('The stream is locked.') + } - // 1. If list does not contain name, then return null. - // 2. Return the values of all headers in list whose name - // is a byte-case-insensitive match for name, - // separated from each other by 0x2C 0x20, in order. - return value === undefined ? null : value.value - } + // Compat. + stream[kBodyUsed] = true - * [Symbol.iterator] () { - // use the lowercased name - for (const [name, { value }] of this[kHeadersMap]) { - yield [name, value] + yield * stream } } +} - get entries () { - const headers = {} - - if (this[kHeadersMap].size) { - for (const { name, value } of this[kHeadersMap].values()) { - headers[name] = value - } - } - - return headers +function throwIfAborted (state) { + if (state.aborted) { + throw new DOMException('The operation was aborted.', 'AbortError') } } -// https://fetch.spec.whatwg.org/#headers-class -class Headers { - constructor (init = undefined) { - if (init === kConstruct) { - return - } - this[kHeadersList] = new HeadersList() +function bodyMixinMethods (instance) { + const methods = { + blob () { + // The blob() method steps are to return the result of + // running consume body with this and the following step + // given a byte sequence bytes: return a Blob whose + // contents are bytes and whose type attribute is this’s + // MIME type. + return specConsumeBody(this, (bytes) => { + let mimeType = bodyMimeType(this) - // The new Headers(init) constructor steps are: + if (mimeType === 'failure') { + mimeType = '' + } else if (mimeType) { + mimeType = serializeAMimeType(mimeType) + } - // 1. Set this’s guard to "none". - this[kGuard] = 'none' + // Return a Blob whose contents are bytes and type attribute + // is mimeType. + return new Blob([bytes], { type: mimeType }) + }, instance) + }, - // 2. If init is given, then fill this with init. - if (init !== undefined) { - init = webidl.converters.HeadersInit(init) - fill(this, init) - } - } + arrayBuffer () { + // The arrayBuffer() method steps are to return the result + // of running consume body with this and the following step + // given a byte sequence bytes: return a new ArrayBuffer + // whose contents are bytes. + return specConsumeBody(this, (bytes) => { + return new Uint8Array(bytes).buffer + }, instance) + }, - // https://fetch.spec.whatwg.org/#dom-headers-append - append (name, value) { - webidl.brandCheck(this, Headers) + text () { + // The text() method steps are to return the result of running + // consume body with this and UTF-8 decode. + return specConsumeBody(this, utf8DecodeBytes, instance) + }, - webidl.argumentLengthCheck(arguments, 2, { header: 'Headers.append' }) + json () { + // The json() method steps are to return the result of running + // consume body with this and parse JSON from bytes. + return specConsumeBody(this, parseJSONFromBytes, instance) + }, - name = webidl.converters.ByteString(name) - value = webidl.converters.ByteString(value) + async formData () { + webidl.brandCheck(this, instance) - return appendHeader(this, name, value) - } + throwIfAborted(this[kState]) - // https://fetch.spec.whatwg.org/#dom-headers-delete - delete (name) { - webidl.brandCheck(this, Headers) + const contentType = this.headers.get('Content-Type') - webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.delete' }) + // If mimeType’s essence is "multipart/form-data", then: + if (/multipart\/form-data/.test(contentType)) { + const headers = {} + for (const [key, value] of this.headers) headers[key.toLowerCase()] = value - name = webidl.converters.ByteString(name) + const responseFormData = new FormData() - // 1. If name is not a header name, then throw a TypeError. - if (!isValidHeaderName(name)) { - throw webidl.errors.invalidArgument({ - prefix: 'Headers.delete', - value: name, - type: 'header name' - }) - } + let busboy - // 2. If this’s guard is "immutable", then throw a TypeError. - // 3. Otherwise, if this’s guard is "request" and name is a - // forbidden header name, return. - // 4. Otherwise, if this’s guard is "request-no-cors", name - // is not a no-CORS-safelisted request-header name, and - // name is not a privileged no-CORS request-header name, - // return. - // 5. Otherwise, if this’s guard is "response" and name is - // a forbidden response-header name, return. - // Note: undici does not implement forbidden header names - if (this[kGuard] === 'immutable') { - throw new TypeError('immutable') - } else if (this[kGuard] === 'request-no-cors') { - // TODO - } + try { + busboy = new Busboy({ + headers, + preservePath: true + }) + } catch (err) { + throw new DOMException(`${err}`, 'AbortError') + } - // 6. If this’s header list does not contain name, then - // return. - if (!this[kHeadersList].contains(name)) { - return - } + busboy.on('field', (name, value) => { + responseFormData.append(name, value) + }) + busboy.on('file', (name, value, filename, encoding, mimeType) => { + const chunks = [] - // 7. Delete name from this’s header list. - // 8. If this’s guard is "request-no-cors", then remove - // privileged no-CORS request headers from this. - this[kHeadersList].delete(name) - } + if (encoding === 'base64' || encoding.toLowerCase() === 'base64') { + let base64chunk = '' - // https://fetch.spec.whatwg.org/#dom-headers-get - get (name) { - webidl.brandCheck(this, Headers) + value.on('data', (chunk) => { + base64chunk += chunk.toString().replace(/[\r\n]/gm, '') - webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.get' }) + const end = base64chunk.length - base64chunk.length % 4 + chunks.push(Buffer.from(base64chunk.slice(0, end), 'base64')) - name = webidl.converters.ByteString(name) + base64chunk = base64chunk.slice(end) + }) + value.on('end', () => { + chunks.push(Buffer.from(base64chunk, 'base64')) + responseFormData.append(name, new File(chunks, filename, { type: mimeType })) + }) + } else { + value.on('data', (chunk) => { + chunks.push(chunk) + }) + value.on('end', () => { + responseFormData.append(name, new File(chunks, filename, { type: mimeType })) + }) + } + }) - // 1. If name is not a header name, then throw a TypeError. - if (!isValidHeaderName(name)) { - throw webidl.errors.invalidArgument({ - prefix: 'Headers.get', - value: name, - type: 'header name' - }) - } - - // 2. Return the result of getting name from this’s header - // list. - return this[kHeadersList].get(name) - } + const busboyResolve = new Promise((resolve, reject) => { + busboy.on('finish', resolve) + busboy.on('error', (err) => reject(new TypeError(err))) + }) - // https://fetch.spec.whatwg.org/#dom-headers-has - has (name) { - webidl.brandCheck(this, Headers) + if (this.body !== null) for await (const chunk of consumeBody(this[kState].body)) busboy.write(chunk) + busboy.end() + await busboyResolve - webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.has' }) + return responseFormData + } else if (/application\/x-www-form-urlencoded/.test(contentType)) { + // Otherwise, if mimeType’s essence is "application/x-www-form-urlencoded", then: - name = webidl.converters.ByteString(name) + // 1. Let entries be the result of parsing bytes. + let entries + try { + let text = '' + // application/x-www-form-urlencoded parser will keep the BOM. + // https://url.spec.whatwg.org/#concept-urlencoded-parser + // Note that streaming decoder is stateful and cannot be reused + const streamingDecoder = new TextDecoder('utf-8', { ignoreBOM: true }) - // 1. If name is not a header name, then throw a TypeError. - if (!isValidHeaderName(name)) { - throw webidl.errors.invalidArgument({ - prefix: 'Headers.has', - value: name, - type: 'header name' - }) - } + for await (const chunk of consumeBody(this[kState].body)) { + if (!isUint8Array(chunk)) { + throw new TypeError('Expected Uint8Array chunk') + } + text += streamingDecoder.decode(chunk, { stream: true }) + } + text += streamingDecoder.decode() + entries = new URLSearchParams(text) + } catch (err) { + // istanbul ignore next: Unclear when new URLSearchParams can fail on a string. + // 2. If entries is failure, then throw a TypeError. + throw Object.assign(new TypeError(), { cause: err }) + } - // 2. Return true if this’s header list contains name; - // otherwise false. - return this[kHeadersList].contains(name) - } + // 3. Return a new FormData object whose entries are entries. + const formData = new FormData() + for (const [name, value] of entries) { + formData.append(name, value) + } + return formData + } else { + // Wait a tick before checking if the request has been aborted. + // Otherwise, a TypeError can be thrown when an AbortError should. + await Promise.resolve() - // https://fetch.spec.whatwg.org/#dom-headers-set - set (name, value) { - webidl.brandCheck(this, Headers) + throwIfAborted(this[kState]) - webidl.argumentLengthCheck(arguments, 2, { header: 'Headers.set' }) + // Otherwise, throw a TypeError. + throw webidl.errors.exception({ + header: `${instance.name}.formData`, + message: 'Could not parse content as FormData.' + }) + } + } + } - name = webidl.converters.ByteString(name) - value = webidl.converters.ByteString(value) + return methods +} - // 1. Normalize value. - value = headerValueNormalize(value) +function mixinBody (prototype) { + Object.assign(prototype.prototype, bodyMixinMethods(prototype)) +} - // 2. If name is not a header name or value is not a - // header value, then throw a TypeError. - if (!isValidHeaderName(name)) { - throw webidl.errors.invalidArgument({ - prefix: 'Headers.set', - value: name, - type: 'header name' - }) - } else if (!isValidHeaderValue(value)) { - throw webidl.errors.invalidArgument({ - prefix: 'Headers.set', - value, - type: 'header value' - }) - } +/** + * @see https://fetch.spec.whatwg.org/#concept-body-consume-body + * @param {Response|Request} object + * @param {(value: unknown) => unknown} convertBytesToJSValue + * @param {Response|Request} instance + */ +async function specConsumeBody (object, convertBytesToJSValue, instance) { + webidl.brandCheck(object, instance) - // 3. If this’s guard is "immutable", then throw a TypeError. - // 4. Otherwise, if this’s guard is "request" and name is a - // forbidden header name, return. - // 5. Otherwise, if this’s guard is "request-no-cors" and - // name/value is not a no-CORS-safelisted request-header, - // return. - // 6. Otherwise, if this’s guard is "response" and name is a - // forbidden response-header name, return. - // Note: undici does not implement forbidden header names - if (this[kGuard] === 'immutable') { - throw new TypeError('immutable') - } else if (this[kGuard] === 'request-no-cors') { - // TODO - } + throwIfAborted(object[kState]) - // 7. Set (name, value) in this’s header list. - // 8. If this’s guard is "request-no-cors", then remove - // privileged no-CORS request headers from this - this[kHeadersList].set(name, value) + // 1. If object is unusable, then return a promise rejected + // with a TypeError. + if (bodyUnusable(object[kState].body)) { + throw new TypeError('Body is unusable') } - // https://fetch.spec.whatwg.org/#dom-headers-getsetcookie - getSetCookie () { - webidl.brandCheck(this, Headers) - - // 1. If this’s header list does not contain `Set-Cookie`, then return « ». - // 2. Return the values of all headers in this’s header list whose name is - // a byte-case-insensitive match for `Set-Cookie`, in order. + // 2. Let promise be a new promise. + const promise = createDeferredPromise() - const list = this[kHeadersList].cookies + // 3. Let errorSteps given error be to reject promise with error. + const errorSteps = (error) => promise.reject(error) - if (list) { - return [...list] + // 4. Let successSteps given a byte sequence data be to resolve + // promise with the result of running convertBytesToJSValue + // with data. If that threw an exception, then run errorSteps + // with that exception. + const successSteps = (data) => { + try { + promise.resolve(convertBytesToJSValue(data)) + } catch (e) { + errorSteps(e) } + } - return [] + // 5. If object’s body is null, then run successSteps with an + // empty byte sequence. + if (object[kState].body == null) { + successSteps(new Uint8Array()) + return promise.promise } - // https://fetch.spec.whatwg.org/#concept-header-list-sort-and-combine - get [kHeadersSortedMap] () { - if (this[kHeadersList][kHeadersSortedMap]) { - return this[kHeadersList][kHeadersSortedMap] - } + // 6. Otherwise, fully read object’s body given successSteps, + // errorSteps, and object’s relevant global object. + await fullyReadBody(object[kState].body, successSteps, errorSteps) - // 1. Let headers be an empty list of headers with the key being the name - // and value the value. - const headers = [] + // 7. Return promise. + return promise.promise +} - // 2. Let names be the result of convert header names to a sorted-lowercase - // set with all the names of the headers in list. - const names = [...this[kHeadersList]].sort((a, b) => a[0] < b[0] ? -1 : 1) - const cookies = this[kHeadersList].cookies +// https://fetch.spec.whatwg.org/#body-unusable +function bodyUnusable (body) { + // An object including the Body interface mixin is + // said to be unusable if its body is non-null and + // its body’s stream is disturbed or locked. + return body != null && (body.stream.locked || util.isDisturbed(body.stream)) +} - // 3. For each name of names: - for (let i = 0; i < names.length; ++i) { - const [name, value] = names[i] - // 1. If name is `set-cookie`, then: - if (name === 'set-cookie') { - // 1. Let values be a list of all values of headers in list whose name - // is a byte-case-insensitive match for name, in order. +/** + * @see https://encoding.spec.whatwg.org/#utf-8-decode + * @param {Buffer} buffer + */ +function utf8DecodeBytes (buffer) { + if (buffer.length === 0) { + return '' + } - // 2. For each value of values: - // 1. Append (name, value) to headers. - for (let j = 0; j < cookies.length; ++j) { - headers.push([name, cookies[j]]) - } - } else { - // 2. Otherwise: + // 1. Let buffer be the result of peeking three bytes from + // ioQueue, converted to a byte sequence. - // 1. Let value be the result of getting name from list. + // 2. If buffer is 0xEF 0xBB 0xBF, then read three + // bytes from ioQueue. (Do nothing with those bytes.) + if (buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) { + buffer = buffer.subarray(3) + } - // 2. Assert: value is non-null. - assert(value !== null) + // 3. Process a queue with an instance of UTF-8’s + // decoder, ioQueue, output, and "replacement". + const output = textDecoder.decode(buffer) - // 3. Append (name, value) to headers. - headers.push([name, value]) - } - } + // 4. Return output. + return output +} - this[kHeadersList][kHeadersSortedMap] = headers +/** + * @see https://infra.spec.whatwg.org/#parse-json-bytes-to-a-javascript-value + * @param {Uint8Array} bytes + */ +function parseJSONFromBytes (bytes) { + return JSON.parse(utf8DecodeBytes(bytes)) +} - // 4. Return headers. - return headers +/** + * @see https://fetch.spec.whatwg.org/#concept-body-mime-type + * @param {import('./response').Response|import('./request').Request} object + */ +function bodyMimeType (object) { + const { headersList } = object[kState] + const contentType = headersList.get('content-type') + + if (contentType === null) { + return 'failure' } - keys () { - webidl.brandCheck(this, Headers) + return parseMIMEType(contentType) +} - if (this[kGuard] === 'immutable') { - const value = this[kHeadersSortedMap] - return makeIterator(() => value, 'Headers', - 'key') - } +module.exports = { + extractBody, + safelyExtractBody, + cloneBody, + mixinBody +} - return makeIterator( - () => [...this[kHeadersSortedMap].values()], - 'Headers', - 'key' - ) - } - values () { - webidl.brandCheck(this, Headers) +/***/ }), - if (this[kGuard] === 'immutable') { - const value = this[kHeadersSortedMap] - return makeIterator(() => value, 'Headers', - 'value') - } +/***/ 1037: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - return makeIterator( - () => [...this[kHeadersSortedMap].values()], - 'Headers', - 'value' - ) - } +"use strict"; - entries () { - webidl.brandCheck(this, Headers) - if (this[kGuard] === 'immutable') { - const value = this[kHeadersSortedMap] - return makeIterator(() => value, 'Headers', - 'key+value') - } +const { MessageChannel, receiveMessageOnPort } = __nccwpck_require__(1267) - return makeIterator( - () => [...this[kHeadersSortedMap].values()], - 'Headers', - 'key+value' - ) - } +const corsSafeListedMethods = ['GET', 'HEAD', 'POST'] +const corsSafeListedMethodsSet = new Set(corsSafeListedMethods) - /** - * @param {(value: string, key: string, self: Headers) => void} callbackFn - * @param {unknown} thisArg - */ - forEach (callbackFn, thisArg = globalThis) { - webidl.brandCheck(this, Headers) +const nullBodyStatus = [101, 204, 205, 304] - webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.forEach' }) +const redirectStatus = [301, 302, 303, 307, 308] +const redirectStatusSet = new Set(redirectStatus) - if (typeof callbackFn !== 'function') { - throw new TypeError( - "Failed to execute 'forEach' on 'Headers': parameter 1 is not of type 'Function'." - ) - } +// https://fetch.spec.whatwg.org/#block-bad-port +const badPorts = [ + '1', '7', '9', '11', '13', '15', '17', '19', '20', '21', '22', '23', '25', '37', '42', '43', '53', '69', '77', '79', + '87', '95', '101', '102', '103', '104', '109', '110', '111', '113', '115', '117', '119', '123', '135', '137', + '139', '143', '161', '179', '389', '427', '465', '512', '513', '514', '515', '526', '530', '531', '532', + '540', '548', '554', '556', '563', '587', '601', '636', '989', '990', '993', '995', '1719', '1720', '1723', + '2049', '3659', '4045', '5060', '5061', '6000', '6566', '6665', '6666', '6667', '6668', '6669', '6697', + '10080' +] - for (const [key, value] of this) { - callbackFn.apply(thisArg, [value, key, this]) - } - } +const badPortsSet = new Set(badPorts) - [Symbol.for('nodejs.util.inspect.custom')] () { - webidl.brandCheck(this, Headers) +// https://w3c.github.io/webappsec-referrer-policy/#referrer-policies +const referrerPolicy = [ + '', + 'no-referrer', + 'no-referrer-when-downgrade', + 'same-origin', + 'origin', + 'strict-origin', + 'origin-when-cross-origin', + 'strict-origin-when-cross-origin', + 'unsafe-url' +] +const referrerPolicySet = new Set(referrerPolicy) - return this[kHeadersList] - } -} +const requestRedirect = ['follow', 'manual', 'error'] -Headers.prototype[Symbol.iterator] = Headers.prototype.entries +const safeMethods = ['GET', 'HEAD', 'OPTIONS', 'TRACE'] +const safeMethodsSet = new Set(safeMethods) -Object.defineProperties(Headers.prototype, { - append: kEnumerableProperty, - delete: kEnumerableProperty, - get: kEnumerableProperty, - has: kEnumerableProperty, - set: kEnumerableProperty, - getSetCookie: kEnumerableProperty, - keys: kEnumerableProperty, - values: kEnumerableProperty, - entries: kEnumerableProperty, - forEach: kEnumerableProperty, - [Symbol.iterator]: { enumerable: false }, - [Symbol.toStringTag]: { - value: 'Headers', - configurable: true +const requestMode = ['navigate', 'same-origin', 'no-cors', 'cors'] + +const requestCredentials = ['omit', 'same-origin', 'include'] + +const requestCache = [ + 'default', + 'no-store', + 'reload', + 'no-cache', + 'force-cache', + 'only-if-cached' +] + +// https://fetch.spec.whatwg.org/#request-body-header-name +const requestBodyHeader = [ + 'content-encoding', + 'content-language', + 'content-location', + 'content-type', + // See https://github.com/nodejs/undici/issues/2021 + // 'Content-Length' is a forbidden header name, which is typically + // removed in the Headers implementation. However, undici doesn't + // filter out headers, so we add it here. + 'content-length' +] + +// https://fetch.spec.whatwg.org/#enumdef-requestduplex +const requestDuplex = [ + 'half' +] + +// http://fetch.spec.whatwg.org/#forbidden-method +const forbiddenMethods = ['CONNECT', 'TRACE', 'TRACK'] +const forbiddenMethodsSet = new Set(forbiddenMethods) + +const subresource = [ + 'audio', + 'audioworklet', + 'font', + 'image', + 'manifest', + 'paintworklet', + 'script', + 'style', + 'track', + 'video', + 'xslt', + '' +] +const subresourceSet = new Set(subresource) + +/** @type {globalThis['DOMException']} */ +const DOMException = globalThis.DOMException ?? (() => { + // DOMException was only made a global in Node v17.0.0, + // but fetch supports >= v16.8. + try { + atob('~') + } catch (err) { + return Object.getPrototypeOf(err).constructor } -}) +})() -webidl.converters.HeadersInit = function (V) { - if (webidl.util.Type(V) === 'Object') { - if (V[Symbol.iterator]) { - return webidl.converters['sequence>'](V) +let channel + +/** @type {globalThis['structuredClone']} */ +const structuredClone = + globalThis.structuredClone ?? + // https://github.com/nodejs/node/blob/b27ae24dcc4251bad726d9d84baf678d1f707fed/lib/internal/structured_clone.js + // structuredClone was added in v17.0.0, but fetch supports v16.8 + function structuredClone (value, options = undefined) { + if (arguments.length === 0) { + throw new TypeError('missing argument') } - return webidl.converters['record'](V) + if (!channel) { + channel = new MessageChannel() + } + channel.port1.unref() + channel.port2.unref() + channel.port1.postMessage(value, options?.transfer) + return receiveMessageOnPort(channel.port2).message } - throw webidl.errors.conversionFailed({ - prefix: 'Headers constructor', - argument: 'Argument 1', - types: ['sequence>', 'record'] - }) -} - module.exports = { - fill, - Headers, - HeadersList + DOMException, + structuredClone, + subresource, + forbiddenMethods, + requestBodyHeader, + referrerPolicy, + requestRedirect, + requestMode, + requestCredentials, + requestCache, + redirectStatus, + corsSafeListedMethods, + nullBodyStatus, + safeMethods, + badPorts, + requestDuplex, + subresourceSet, + badPortsSet, + redirectStatusSet, + corsSafeListedMethodsSet, + safeMethodsSet, + forbiddenMethodsSet, + referrerPolicySet } /***/ }), -/***/ 4881: +/***/ 685: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -"use strict"; -// https://github.com/Ethan-Arrowood/undici-fetch +const assert = __nccwpck_require__(9491) +const { atob } = __nccwpck_require__(4300) +const { isomorphicDecode } = __nccwpck_require__(2538) +const encoder = new TextEncoder() +/** + * @see https://mimesniff.spec.whatwg.org/#http-token-code-point + */ +const HTTP_TOKEN_CODEPOINTS = /^[!#$%&'*+-.^_|~A-Za-z0-9]+$/ +const HTTP_WHITESPACE_REGEX = /(\u000A|\u000D|\u0009|\u0020)/ // eslint-disable-line +/** + * @see https://mimesniff.spec.whatwg.org/#http-quoted-string-token-code-point + */ +const HTTP_QUOTED_STRING_TOKENS = /[\u0009|\u0020-\u007E|\u0080-\u00FF]/ // eslint-disable-line -const { - Response, - makeNetworkError, - makeAppropriateNetworkError, - filterResponse, - makeResponse -} = __nccwpck_require__(7823) -const { Headers } = __nccwpck_require__(554) -const { Request, makeRequest } = __nccwpck_require__(8359) -const zlib = __nccwpck_require__(9796) -const { - bytesMatch, - makePolicyContainer, - clonePolicyContainer, - requestBadPort, - TAOCheck, - appendRequestOriginHeader, - responseLocationURL, - requestCurrentURL, - setRequestReferrerPolicyOnRedirect, - tryUpgradeRequestToAPotentiallyTrustworthyURL, - createOpaqueTimingInfo, - appendFetchMetadata, - corsCheck, - crossOriginResourcePolicyCheck, - determineRequestsReferrer, - coarsenedSharedCurrentTime, - createDeferredPromise, - isBlobLike, - sameOrigin, - isCancelled, - isAborted, - isErrorLike, - fullyReadBody, - readableStreamClose, - isomorphicEncode, - urlIsLocal, - urlIsHttpHttpsScheme, - urlHasHttpsScheme -} = __nccwpck_require__(2538) -const { kState, kHeaders, kGuard, kRealm } = __nccwpck_require__(5861) -const assert = __nccwpck_require__(9491) -const { safelyExtractBody } = __nccwpck_require__(1472) -const { - redirectStatusSet, - nullBodyStatus, - safeMethodsSet, - requestBodyHeader, - subresourceSet, - DOMException -} = __nccwpck_require__(1037) -const { kHeadersList } = __nccwpck_require__(2785) -const EE = __nccwpck_require__(2361) -const { Readable, pipeline } = __nccwpck_require__(2781) -const { addAbortListener, isErrored, isReadable, nodeMajor, nodeMinor } = __nccwpck_require__(3983) -const { dataURLProcessor, serializeAMimeType } = __nccwpck_require__(685) -const { TransformStream } = __nccwpck_require__(5356) -const { getGlobalDispatcher } = __nccwpck_require__(1892) -const { webidl } = __nccwpck_require__(1744) -const { STATUS_CODES } = __nccwpck_require__(3685) -const GET_OR_HEAD = ['GET', 'HEAD'] +// https://fetch.spec.whatwg.org/#data-url-processor +/** @param {URL} dataURL */ +function dataURLProcessor (dataURL) { + // 1. Assert: dataURL’s scheme is "data". + assert(dataURL.protocol === 'data:') -/** @type {import('buffer').resolveObjectURL} */ -let resolveObjectURL -let ReadableStream = globalThis.ReadableStream + // 2. Let input be the result of running the URL + // serializer on dataURL with exclude fragment + // set to true. + let input = URLSerializer(dataURL, true) -class Fetch extends EE { - constructor (dispatcher) { - super() + // 3. Remove the leading "data:" string from input. + input = input.slice(5) - this.dispatcher = dispatcher - this.connection = null - this.dump = false - this.state = 'ongoing' - // 2 terminated listeners get added per request, - // but only 1 gets removed. If there are 20 redirects, - // 21 listeners will be added. - // See https://github.com/nodejs/undici/issues/1711 - // TODO (fix): Find and fix root cause for leaked listener. - this.setMaxListeners(21) - } + // 4. Let position point at the start of input. + const position = { position: 0 } - terminate (reason) { - if (this.state !== 'ongoing') { - return - } + // 5. Let mimeType be the result of collecting a + // sequence of code points that are not equal + // to U+002C (,), given position. + let mimeType = collectASequenceOfCodePointsFast( + ',', + input, + position + ) - this.state = 'terminated' - this.connection?.destroy(reason) - this.emit('terminated', reason) - } + // 6. Strip leading and trailing ASCII whitespace + // from mimeType. + // Undici implementation note: we need to store the + // length because if the mimetype has spaces removed, + // the wrong amount will be sliced from the input in + // step #9 + const mimeTypeLength = mimeType.length + mimeType = removeASCIIWhitespace(mimeType, true, true) - // https://fetch.spec.whatwg.org/#fetch-controller-abort - abort (error) { - if (this.state !== 'ongoing') { - return - } + // 7. If position is past the end of input, then + // return failure + if (position.position >= input.length) { + return 'failure' + } - // 1. Set controller’s state to "aborted". - this.state = 'aborted' + // 8. Advance position by 1. + position.position++ - // 2. Let fallbackError be an "AbortError" DOMException. - // 3. Set error to fallbackError if it is not given. - if (!error) { - error = new DOMException('The operation was aborted.', 'AbortError') - } + // 9. Let encodedBody be the remainder of input. + const encodedBody = input.slice(mimeTypeLength + 1) - // 4. Let serializedError be StructuredSerialize(error). - // If that threw an exception, catch it, and let - // serializedError be StructuredSerialize(fallbackError). + // 10. Let body be the percent-decoding of encodedBody. + let body = stringPercentDecode(encodedBody) - // 5. Set controller’s serialized abort reason to serializedError. - this.serializedAbortReason = error + // 11. If mimeType ends with U+003B (;), followed by + // zero or more U+0020 SPACE, followed by an ASCII + // case-insensitive match for "base64", then: + if (/;(\u0020){0,}base64$/i.test(mimeType)) { + // 1. Let stringBody be the isomorphic decode of body. + const stringBody = isomorphicDecode(body) - this.connection?.destroy(error) - this.emit('terminated', error) - } -} + // 2. Set body to the forgiving-base64 decode of + // stringBody. + body = forgivingBase64(stringBody) -// https://fetch.spec.whatwg.org/#fetch-method -function fetch (input, init = {}) { - webidl.argumentLengthCheck(arguments, 1, { header: 'globalThis.fetch' }) + // 3. If body is failure, then return failure. + if (body === 'failure') { + return 'failure' + } - // 1. Let p be a new promise. - const p = createDeferredPromise() + // 4. Remove the last 6 code points from mimeType. + mimeType = mimeType.slice(0, -6) - // 2. Let requestObject be the result of invoking the initial value of - // Request as constructor with input and init as arguments. If this throws - // an exception, reject p with it and return p. - let requestObject + // 5. Remove trailing U+0020 SPACE code points from mimeType, + // if any. + mimeType = mimeType.replace(/(\u0020)+$/, '') - try { - requestObject = new Request(input, init) - } catch (e) { - p.reject(e) - return p.promise + // 6. Remove the last U+003B (;) code point from mimeType. + mimeType = mimeType.slice(0, -1) } - // 3. Let request be requestObject’s request. - const request = requestObject[kState] + // 12. If mimeType starts with U+003B (;), then prepend + // "text/plain" to mimeType. + if (mimeType.startsWith(';')) { + mimeType = 'text/plain' + mimeType + } - // 4. If requestObject’s signal’s aborted flag is set, then: - if (requestObject.signal.aborted) { - // 1. Abort the fetch() call with p, request, null, and - // requestObject’s signal’s abort reason. - abortFetch(p, request, null, requestObject.signal.reason) + // 13. Let mimeTypeRecord be the result of parsing + // mimeType. + let mimeTypeRecord = parseMIMEType(mimeType) - // 2. Return p. - return p.promise + // 14. If mimeTypeRecord is failure, then set + // mimeTypeRecord to text/plain;charset=US-ASCII. + if (mimeTypeRecord === 'failure') { + mimeTypeRecord = parseMIMEType('text/plain;charset=US-ASCII') } - // 5. Let globalObject be request’s client’s global object. - const globalObject = request.client.globalObject + // 15. Return a new data: URL struct whose MIME + // type is mimeTypeRecord and body is body. + // https://fetch.spec.whatwg.org/#data-url-struct + return { mimeType: mimeTypeRecord, body } +} - // 6. If globalObject is a ServiceWorkerGlobalScope object, then set - // request’s service-workers mode to "none". - if (globalObject?.constructor?.name === 'ServiceWorkerGlobalScope') { - request.serviceWorkers = 'none' +// https://url.spec.whatwg.org/#concept-url-serializer +/** + * @param {URL} url + * @param {boolean} excludeFragment + */ +function URLSerializer (url, excludeFragment = false) { + if (!excludeFragment) { + return url.href } - // 7. Let responseObject be null. - let responseObject = null - - // 8. Let relevantRealm be this’s relevant Realm. - const relevantRealm = null + const href = url.href + const hashLength = url.hash.length - // 9. Let locallyAborted be false. - let locallyAborted = false + return hashLength === 0 ? href : href.substring(0, href.length - hashLength) +} - // 10. Let controller be null. - let controller = null +// https://infra.spec.whatwg.org/#collect-a-sequence-of-code-points +/** + * @param {(char: string) => boolean} condition + * @param {string} input + * @param {{ position: number }} position + */ +function collectASequenceOfCodePoints (condition, input, position) { + // 1. Let result be the empty string. + let result = '' - // 11. Add the following abort steps to requestObject’s signal: - addAbortListener( - requestObject.signal, - () => { - // 1. Set locallyAborted to true. - locallyAborted = true + // 2. While position doesn’t point past the end of input and the + // code point at position within input meets the condition condition: + while (position.position < input.length && condition(input[position.position])) { + // 1. Append that code point to the end of result. + result += input[position.position] - // 2. Assert: controller is non-null. - assert(controller != null) + // 2. Advance position by 1. + position.position++ + } - // 3. Abort controller with requestObject’s signal’s abort reason. - controller.abort(requestObject.signal.reason) + // 3. Return result. + return result +} - // 4. Abort the fetch() call with p, request, responseObject, - // and requestObject’s signal’s abort reason. - abortFetch(p, request, responseObject, requestObject.signal.reason) - } - ) - - // 12. Let handleFetchDone given response response be to finalize and - // report timing with response, globalObject, and "fetch". - const handleFetchDone = (response) => - finalizeAndReportTiming(response, 'fetch') - - // 13. Set controller to the result of calling fetch given request, - // with processResponseEndOfBody set to handleFetchDone, and processResponse - // given response being these substeps: +/** + * A faster collectASequenceOfCodePoints that only works when comparing a single character. + * @param {string} char + * @param {string} input + * @param {{ position: number }} position + */ +function collectASequenceOfCodePointsFast (char, input, position) { + const idx = input.indexOf(char, position.position) + const start = position.position - const processResponse = (response) => { - // 1. If locallyAborted is true, terminate these substeps. - if (locallyAborted) { - return Promise.resolve() - } + if (idx === -1) { + position.position = input.length + return input.slice(start) + } - // 2. If response’s aborted flag is set, then: - if (response.aborted) { - // 1. Let deserializedError be the result of deserialize a serialized - // abort reason given controller’s serialized abort reason and - // relevantRealm. + position.position = idx + return input.slice(start, position.position) +} - // 2. Abort the fetch() call with p, request, responseObject, and - // deserializedError. +// https://url.spec.whatwg.org/#string-percent-decode +/** @param {string} input */ +function stringPercentDecode (input) { + // 1. Let bytes be the UTF-8 encoding of input. + const bytes = encoder.encode(input) - abortFetch(p, request, responseObject, controller.serializedAbortReason) - return Promise.resolve() - } + // 2. Return the percent-decoding of bytes. + return percentDecode(bytes) +} - // 3. If response is a network error, then reject p with a TypeError - // and terminate these substeps. - if (response.type === 'error') { - p.reject( - Object.assign(new TypeError('fetch failed'), { cause: response.error }) - ) - return Promise.resolve() - } +// https://url.spec.whatwg.org/#percent-decode +/** @param {Uint8Array} input */ +function percentDecode (input) { + // 1. Let output be an empty byte sequence. + /** @type {number[]} */ + const output = [] - // 4. Set responseObject to the result of creating a Response object, - // given response, "immutable", and relevantRealm. - responseObject = new Response() - responseObject[kState] = response - responseObject[kRealm] = relevantRealm - responseObject[kHeaders][kHeadersList] = response.headersList - responseObject[kHeaders][kGuard] = 'immutable' - responseObject[kHeaders][kRealm] = relevantRealm + // 2. For each byte byte in input: + for (let i = 0; i < input.length; i++) { + const byte = input[i] - // 5. Resolve p with responseObject. - p.resolve(responseObject) - } + // 1. If byte is not 0x25 (%), then append byte to output. + if (byte !== 0x25) { + output.push(byte) - controller = fetching({ - request, - processResponseEndOfBody: handleFetchDone, - processResponse, - dispatcher: init.dispatcher ?? getGlobalDispatcher() // undici - }) + // 2. Otherwise, if byte is 0x25 (%) and the next two bytes + // after byte in input are not in the ranges + // 0x30 (0) to 0x39 (9), 0x41 (A) to 0x46 (F), + // and 0x61 (a) to 0x66 (f), all inclusive, append byte + // to output. + } else if ( + byte === 0x25 && + !/^[0-9A-Fa-f]{2}$/i.test(String.fromCharCode(input[i + 1], input[i + 2])) + ) { + output.push(0x25) - // 14. Return p. - return p.promise -} + // 3. Otherwise: + } else { + // 1. Let bytePoint be the two bytes after byte in input, + // decoded, and then interpreted as hexadecimal number. + const nextTwoBytes = String.fromCharCode(input[i + 1], input[i + 2]) + const bytePoint = Number.parseInt(nextTwoBytes, 16) -// https://fetch.spec.whatwg.org/#finalize-and-report-timing -function finalizeAndReportTiming (response, initiatorType = 'other') { - // 1. If response is an aborted network error, then return. - if (response.type === 'error' && response.aborted) { - return - } + // 2. Append a byte whose value is bytePoint to output. + output.push(bytePoint) - // 2. If response’s URL list is null or empty, then return. - if (!response.urlList?.length) { - return + // 3. Skip the next two bytes in input. + i += 2 + } } - // 3. Let originalURL be response’s URL list[0]. - const originalURL = response.urlList[0] + // 3. Return output. + return Uint8Array.from(output) +} - // 4. Let timingInfo be response’s timing info. - let timingInfo = response.timingInfo +// https://mimesniff.spec.whatwg.org/#parse-a-mime-type +/** @param {string} input */ +function parseMIMEType (input) { + // 1. Remove any leading and trailing HTTP whitespace + // from input. + input = removeHTTPWhitespace(input, true, true) - // 5. Let cacheState be response’s cache state. - let cacheState = response.cacheState + // 2. Let position be a position variable for input, + // initially pointing at the start of input. + const position = { position: 0 } - // 6. If originalURL’s scheme is not an HTTP(S) scheme, then return. - if (!urlIsHttpHttpsScheme(originalURL)) { - return - } + // 3. Let type be the result of collecting a sequence + // of code points that are not U+002F (/) from + // input, given position. + const type = collectASequenceOfCodePointsFast( + '/', + input, + position + ) - // 7. If timingInfo is null, then return. - if (timingInfo === null) { - return + // 4. If type is the empty string or does not solely + // contain HTTP token code points, then return failure. + // https://mimesniff.spec.whatwg.org/#http-token-code-point + if (type.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(type)) { + return 'failure' } - // 8. If response’s timing allow passed flag is not set, then: - if (!response.timingAllowPassed) { - // 1. Set timingInfo to a the result of creating an opaque timing info for timingInfo. - timingInfo = createOpaqueTimingInfo({ - startTime: timingInfo.startTime - }) - - // 2. Set cacheState to the empty string. - cacheState = '' + // 5. If position is past the end of input, then return + // failure + if (position.position > input.length) { + return 'failure' } - // 9. Set timingInfo’s end time to the coarsened shared current time - // given global’s relevant settings object’s cross-origin isolated - // capability. - // TODO: given global’s relevant settings object’s cross-origin isolated - // capability? - timingInfo.endTime = coarsenedSharedCurrentTime() - - // 10. Set response’s timing info to timingInfo. - response.timingInfo = timingInfo + // 6. Advance position by 1. (This skips past U+002F (/).) + position.position++ - // 11. Mark resource timing for timingInfo, originalURL, initiatorType, - // global, and cacheState. - markResourceTiming( - timingInfo, - originalURL, - initiatorType, - globalThis, - cacheState + // 7. Let subtype be the result of collecting a sequence of + // code points that are not U+003B (;) from input, given + // position. + let subtype = collectASequenceOfCodePointsFast( + ';', + input, + position ) -} -// https://w3c.github.io/resource-timing/#dfn-mark-resource-timing -function markResourceTiming (timingInfo, originalURL, initiatorType, globalThis, cacheState) { - if (nodeMajor > 18 || (nodeMajor === 18 && nodeMinor >= 2)) { - performance.markResourceTiming(timingInfo, originalURL.href, initiatorType, globalThis, cacheState) - } -} + // 8. Remove any trailing HTTP whitespace from subtype. + subtype = removeHTTPWhitespace(subtype, false, true) -// https://fetch.spec.whatwg.org/#abort-fetch -function abortFetch (p, request, responseObject, error) { - // Note: AbortSignal.reason was added in node v17.2.0 - // which would give us an undefined error to reject with. - // Remove this once node v16 is no longer supported. - if (!error) { - error = new DOMException('The operation was aborted.', 'AbortError') + // 9. If subtype is the empty string or does not solely + // contain HTTP token code points, then return failure. + if (subtype.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(subtype)) { + return 'failure' } - // 1. Reject promise with error. - p.reject(error) - - // 2. If request’s body is not null and is readable, then cancel request’s - // body with error. - if (request.body != null && isReadable(request.body?.stream)) { - request.body.stream.cancel(error).catch((err) => { - if (err.code === 'ERR_INVALID_STATE') { - // Node bug? - return - } - throw err - }) - } + const typeLowercase = type.toLowerCase() + const subtypeLowercase = subtype.toLowerCase() - // 3. If responseObject is null, then return. - if (responseObject == null) { - return + // 10. Let mimeType be a new MIME type record whose type + // is type, in ASCII lowercase, and subtype is subtype, + // in ASCII lowercase. + // https://mimesniff.spec.whatwg.org/#mime-type + const mimeType = { + type: typeLowercase, + subtype: subtypeLowercase, + /** @type {Map} */ + parameters: new Map(), + // https://mimesniff.spec.whatwg.org/#mime-type-essence + essence: `${typeLowercase}/${subtypeLowercase}` } - // 4. Let response be responseObject’s response. - const response = responseObject[kState] + // 11. While position is not past the end of input: + while (position.position < input.length) { + // 1. Advance position by 1. (This skips past U+003B (;).) + position.position++ - // 5. If response’s body is not null and is readable, then error response’s - // body with error. - if (response.body != null && isReadable(response.body?.stream)) { - response.body.stream.cancel(error).catch((err) => { - if (err.code === 'ERR_INVALID_STATE') { - // Node bug? - return - } - throw err - }) - } -} + // 2. Collect a sequence of code points that are HTTP + // whitespace from input given position. + collectASequenceOfCodePoints( + // https://fetch.spec.whatwg.org/#http-whitespace + char => HTTP_WHITESPACE_REGEX.test(char), + input, + position + ) -// https://fetch.spec.whatwg.org/#fetching -function fetching ({ - request, - processRequestBodyChunkLength, - processRequestEndOfBody, - processResponse, - processResponseEndOfBody, - processResponseConsumeBody, - useParallelQueue = false, - dispatcher // undici -}) { - // 1. Let taskDestination be null. - let taskDestination = null + // 3. Let parameterName be the result of collecting a + // sequence of code points that are not U+003B (;) + // or U+003D (=) from input, given position. + let parameterName = collectASequenceOfCodePoints( + (char) => char !== ';' && char !== '=', + input, + position + ) - // 2. Let crossOriginIsolatedCapability be false. - let crossOriginIsolatedCapability = false + // 4. Set parameterName to parameterName, in ASCII + // lowercase. + parameterName = parameterName.toLowerCase() - // 3. If request’s client is non-null, then: - if (request.client != null) { - // 1. Set taskDestination to request’s client’s global object. - taskDestination = request.client.globalObject + // 5. If position is not past the end of input, then: + if (position.position < input.length) { + // 1. If the code point at position within input is + // U+003B (;), then continue. + if (input[position.position] === ';') { + continue + } - // 2. Set crossOriginIsolatedCapability to request’s client’s cross-origin - // isolated capability. - crossOriginIsolatedCapability = - request.client.crossOriginIsolatedCapability - } + // 2. Advance position by 1. (This skips past U+003D (=).) + position.position++ + } - // 4. If useParallelQueue is true, then set taskDestination to the result of - // starting a new parallel queue. - // TODO + // 6. If position is past the end of input, then break. + if (position.position > input.length) { + break + } - // 5. Let timingInfo be a new fetch timing info whose start time and - // post-redirect start time are the coarsened shared current time given - // crossOriginIsolatedCapability. - const currenTime = coarsenedSharedCurrentTime(crossOriginIsolatedCapability) - const timingInfo = createOpaqueTimingInfo({ - startTime: currenTime - }) + // 7. Let parameterValue be null. + let parameterValue = null - // 6. Let fetchParams be a new fetch params whose - // request is request, - // timing info is timingInfo, - // process request body chunk length is processRequestBodyChunkLength, - // process request end-of-body is processRequestEndOfBody, - // process response is processResponse, - // process response consume body is processResponseConsumeBody, - // process response end-of-body is processResponseEndOfBody, - // task destination is taskDestination, - // and cross-origin isolated capability is crossOriginIsolatedCapability. - const fetchParams = { - controller: new Fetch(dispatcher), - request, - timingInfo, - processRequestBodyChunkLength, - processRequestEndOfBody, - processResponse, - processResponseConsumeBody, - processResponseEndOfBody, - taskDestination, - crossOriginIsolatedCapability - } + // 8. If the code point at position within input is + // U+0022 ("), then: + if (input[position.position] === '"') { + // 1. Set parameterValue to the result of collecting + // an HTTP quoted string from input, given position + // and the extract-value flag. + parameterValue = collectAnHTTPQuotedString(input, position, true) - // 7. If request’s body is a byte sequence, then set request’s body to - // request’s body as a body. - // NOTE: Since fetching is only called from fetch, body should already be - // extracted. - assert(!request.body || request.body.stream) + // 2. Collect a sequence of code points that are not + // U+003B (;) from input, given position. + collectASequenceOfCodePointsFast( + ';', + input, + position + ) - // 8. If request’s window is "client", then set request’s window to request’s - // client, if request’s client’s global object is a Window object; otherwise - // "no-window". - if (request.window === 'client') { - // TODO: What if request.client is null? - request.window = - request.client?.globalObject?.constructor?.name === 'Window' - ? request.client - : 'no-window' - } + // 9. Otherwise: + } else { + // 1. Set parameterValue to the result of collecting + // a sequence of code points that are not U+003B (;) + // from input, given position. + parameterValue = collectASequenceOfCodePointsFast( + ';', + input, + position + ) - // 9. If request’s origin is "client", then set request’s origin to request’s - // client’s origin. - if (request.origin === 'client') { - // TODO: What if request.client is null? - request.origin = request.client?.origin - } + // 2. Remove any trailing HTTP whitespace from parameterValue. + parameterValue = removeHTTPWhitespace(parameterValue, false, true) - // 10. If all of the following conditions are true: - // TODO + // 3. If parameterValue is the empty string, then continue. + if (parameterValue.length === 0) { + continue + } + } - // 11. If request’s policy container is "client", then: - if (request.policyContainer === 'client') { - // 1. If request’s client is non-null, then set request’s policy - // container to a clone of request’s client’s policy container. [HTML] - if (request.client != null) { - request.policyContainer = clonePolicyContainer( - request.client.policyContainer - ) - } else { - // 2. Otherwise, set request’s policy container to a new policy - // container. - request.policyContainer = makePolicyContainer() + // 10. If all of the following are true + // - parameterName is not the empty string + // - parameterName solely contains HTTP token code points + // - parameterValue solely contains HTTP quoted-string token code points + // - mimeType’s parameters[parameterName] does not exist + // then set mimeType’s parameters[parameterName] to parameterValue. + if ( + parameterName.length !== 0 && + HTTP_TOKEN_CODEPOINTS.test(parameterName) && + (parameterValue.length === 0 || HTTP_QUOTED_STRING_TOKENS.test(parameterValue)) && + !mimeType.parameters.has(parameterName) + ) { + mimeType.parameters.set(parameterName, parameterValue) } } - // 12. If request’s header list does not contain `Accept`, then: - if (!request.headersList.contains('accept')) { - // 1. Let value be `*/*`. - const value = '*/*' + // 12. Return mimeType. + return mimeType +} - // 2. A user agent should set value to the first matching statement, if - // any, switching on request’s destination: - // "document" - // "frame" - // "iframe" - // `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8` - // "image" - // `image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5` - // "style" - // `text/css,*/*;q=0.1` - // TODO +// https://infra.spec.whatwg.org/#forgiving-base64-decode +/** @param {string} data */ +function forgivingBase64 (data) { + // 1. Remove all ASCII whitespace from data. + data = data.replace(/[\u0009\u000A\u000C\u000D\u0020]/g, '') // eslint-disable-line - // 3. Append `Accept`/value to request’s header list. - request.headersList.append('accept', value) + // 2. If data’s code point length divides by 4 leaving + // no remainder, then: + if (data.length % 4 === 0) { + // 1. If data ends with one or two U+003D (=) code points, + // then remove them from data. + data = data.replace(/=?=$/, '') } - // 13. If request’s header list does not contain `Accept-Language`, then - // user agents should append `Accept-Language`/an appropriate value to - // request’s header list. - if (!request.headersList.contains('accept-language')) { - request.headersList.append('accept-language', '*') + // 3. If data’s code point length divides by 4 leaving + // a remainder of 1, then return failure. + if (data.length % 4 === 1) { + return 'failure' } - // 14. If request’s priority is null, then use request’s initiator and - // destination appropriately in setting request’s priority to a - // user-agent-defined object. - if (request.priority === null) { - // TODO + // 4. If data contains a code point that is not one of + // U+002B (+) + // U+002F (/) + // ASCII alphanumeric + // then return failure. + if (/[^+/0-9A-Za-z]/.test(data)) { + return 'failure' } - // 15. If request is a subresource request, then: - if (subresourceSet.has(request.destination)) { - // TODO - } + const binary = atob(data) + const bytes = new Uint8Array(binary.length) - // 16. Run main fetch given fetchParams. - mainFetch(fetchParams) - .catch(err => { - fetchParams.controller.terminate(err) - }) + for (let byte = 0; byte < binary.length; byte++) { + bytes[byte] = binary.charCodeAt(byte) + } - // 17. Return fetchParam's controller - return fetchParams.controller + return bytes } -// https://fetch.spec.whatwg.org/#concept-main-fetch -async function mainFetch (fetchParams, recursive = false) { - // 1. Let request be fetchParams’s request. - const request = fetchParams.request - - // 2. Let response be null. - let response = null +// https://fetch.spec.whatwg.org/#collect-an-http-quoted-string +// tests: https://fetch.spec.whatwg.org/#example-http-quoted-string +/** + * @param {string} input + * @param {{ position: number }} position + * @param {boolean?} extractValue + */ +function collectAnHTTPQuotedString (input, position, extractValue) { + // 1. Let positionStart be position. + const positionStart = position.position - // 3. If request’s local-URLs-only flag is set and request’s current URL is - // not local, then set response to a network error. - if (request.localURLsOnly && !urlIsLocal(requestCurrentURL(request))) { - response = makeNetworkError('local URLs only') - } + // 2. Let value be the empty string. + let value = '' - // 4. Run report Content Security Policy violations for request. - // TODO + // 3. Assert: the code point at position within input + // is U+0022 ("). + assert(input[position.position] === '"') - // 5. Upgrade request to a potentially trustworthy URL, if appropriate. - tryUpgradeRequestToAPotentiallyTrustworthyURL(request) + // 4. Advance position by 1. + position.position++ - // 6. If should request be blocked due to a bad port, should fetching request - // be blocked as mixed content, or should request be blocked by Content - // Security Policy returns blocked, then set response to a network error. - if (requestBadPort(request) === 'blocked') { - response = makeNetworkError('bad port') - } - // TODO: should fetching request be blocked as mixed content? - // TODO: should request be blocked by Content Security Policy? + // 5. While true: + while (true) { + // 1. Append the result of collecting a sequence of code points + // that are not U+0022 (") or U+005C (\) from input, given + // position, to value. + value += collectASequenceOfCodePoints( + (char) => char !== '"' && char !== '\\', + input, + position + ) - // 7. If request’s referrer policy is the empty string, then set request’s - // referrer policy to request’s policy container’s referrer policy. - if (request.referrerPolicy === '') { - request.referrerPolicy = request.policyContainer.referrerPolicy - } + // 2. If position is past the end of input, then break. + if (position.position >= input.length) { + break + } - // 8. If request’s referrer is not "no-referrer", then set request’s - // referrer to the result of invoking determine request’s referrer. - if (request.referrer !== 'no-referrer') { - request.referrer = determineRequestsReferrer(request) - } + // 3. Let quoteOrBackslash be the code point at position within + // input. + const quoteOrBackslash = input[position.position] - // 9. Set request’s current URL’s scheme to "https" if all of the following - // conditions are true: - // - request’s current URL’s scheme is "http" - // - request’s current URL’s host is a domain - // - Matching request’s current URL’s host per Known HSTS Host Domain Name - // Matching results in either a superdomain match with an asserted - // includeSubDomains directive or a congruent match (with or without an - // asserted includeSubDomains directive). [HSTS] - // TODO + // 4. Advance position by 1. + position.position++ - // 10. If recursive is false, then run the remaining steps in parallel. - // TODO + // 5. If quoteOrBackslash is U+005C (\), then: + if (quoteOrBackslash === '\\') { + // 1. If position is past the end of input, then append + // U+005C (\) to value and break. + if (position.position >= input.length) { + value += '\\' + break + } - // 11. If response is null, then set response to the result of running - // the steps corresponding to the first matching statement: - if (response === null) { - response = await (async () => { - const currentURL = requestCurrentURL(request) + // 2. Append the code point at position within input to value. + value += input[position.position] - if ( - // - request’s current URL’s origin is same origin with request’s origin, - // and request’s response tainting is "basic" - (sameOrigin(currentURL, request.url) && request.responseTainting === 'basic') || - // request’s current URL’s scheme is "data" - (currentURL.protocol === 'data:') || - // - request’s mode is "navigate" or "websocket" - (request.mode === 'navigate' || request.mode === 'websocket') - ) { - // 1. Set request’s response tainting to "basic". - request.responseTainting = 'basic' + // 3. Advance position by 1. + position.position++ - // 2. Return the result of running scheme fetch given fetchParams. - return await schemeFetch(fetchParams) - } + // 6. Otherwise: + } else { + // 1. Assert: quoteOrBackslash is U+0022 ("). + assert(quoteOrBackslash === '"') - // request’s mode is "same-origin" - if (request.mode === 'same-origin') { - // 1. Return a network error. - return makeNetworkError('request mode cannot be "same-origin"') - } + // 2. Break. + break + } + } - // request’s mode is "no-cors" - if (request.mode === 'no-cors') { - // 1. If request’s redirect mode is not "follow", then return a network - // error. - if (request.redirect !== 'follow') { - return makeNetworkError( - 'redirect mode cannot be "follow" for "no-cors" request' - ) - } + // 6. If the extract-value flag is set, then return value. + if (extractValue) { + return value + } - // 2. Set request’s response tainting to "opaque". - request.responseTainting = 'opaque' + // 7. Return the code points from positionStart to position, + // inclusive, within input. + return input.slice(positionStart, position.position) +} - // 3. Return the result of running scheme fetch given fetchParams. - return await schemeFetch(fetchParams) - } +/** + * @see https://mimesniff.spec.whatwg.org/#serialize-a-mime-type + */ +function serializeAMimeType (mimeType) { + assert(mimeType !== 'failure') + const { parameters, essence } = mimeType - // request’s current URL’s scheme is not an HTTP(S) scheme - if (!urlIsHttpHttpsScheme(requestCurrentURL(request))) { - // Return a network error. - return makeNetworkError('URL scheme must be a HTTP(S) scheme') - } + // 1. Let serialization be the concatenation of mimeType’s + // type, U+002F (/), and mimeType’s subtype. + let serialization = essence - // - request’s use-CORS-preflight flag is set - // - request’s unsafe-request flag is set and either request’s method is - // not a CORS-safelisted method or CORS-unsafe request-header names with - // request’s header list is not empty - // 1. Set request’s response tainting to "cors". - // 2. Let corsWithPreflightResponse be the result of running HTTP fetch - // given fetchParams and true. - // 3. If corsWithPreflightResponse is a network error, then clear cache - // entries using request. - // 4. Return corsWithPreflightResponse. - // TODO + // 2. For each name → value of mimeType’s parameters: + for (let [name, value] of parameters.entries()) { + // 1. Append U+003B (;) to serialization. + serialization += ';' - // Otherwise - // 1. Set request’s response tainting to "cors". - request.responseTainting = 'cors' + // 2. Append name to serialization. + serialization += name - // 2. Return the result of running HTTP fetch given fetchParams. - return await httpFetch(fetchParams) - })() - } + // 3. Append U+003D (=) to serialization. + serialization += '=' - // 12. If recursive is true, then return response. - if (recursive) { - return response - } + // 4. If value does not solely contain HTTP token code + // points or value is the empty string, then: + if (!HTTP_TOKEN_CODEPOINTS.test(value)) { + // 1. Precede each occurence of U+0022 (") or + // U+005C (\) in value with U+005C (\). + value = value.replace(/(\\|")/g, '\\$1') - // 13. If response is not a network error and response is not a filtered - // response, then: - if (response.status !== 0 && !response.internalResponse) { - // If request’s response tainting is "cors", then: - if (request.responseTainting === 'cors') { - // 1. Let headerNames be the result of extracting header list values - // given `Access-Control-Expose-Headers` and response’s header list. - // TODO - // 2. If request’s credentials mode is not "include" and headerNames - // contains `*`, then set response’s CORS-exposed header-name list to - // all unique header names in response’s header list. - // TODO - // 3. Otherwise, if headerNames is not null or failure, then set - // response’s CORS-exposed header-name list to headerNames. - // TODO - } + // 2. Prepend U+0022 (") to value. + value = '"' + value - // Set response to the following filtered response with response as its - // internal response, depending on request’s response tainting: - if (request.responseTainting === 'basic') { - response = filterResponse(response, 'basic') - } else if (request.responseTainting === 'cors') { - response = filterResponse(response, 'cors') - } else if (request.responseTainting === 'opaque') { - response = filterResponse(response, 'opaque') - } else { - assert(false) + // 3. Append U+0022 (") to value. + value += '"' } - } - - // 14. Let internalResponse be response, if response is a network error, - // and response’s internal response otherwise. - let internalResponse = - response.status === 0 ? response : response.internalResponse - // 15. If internalResponse’s URL list is empty, then set it to a clone of - // request’s URL list. - if (internalResponse.urlList.length === 0) { - internalResponse.urlList.push(...request.urlList) + // 5. Append value to serialization. + serialization += value } - // 16. If request’s timing allow failed flag is unset, then set - // internalResponse’s timing allow passed flag. - if (!request.timingAllowFailed) { - response.timingAllowPassed = true - } + // 3. Return serialization. + return serialization +} - // 17. If response is not a network error and any of the following returns - // blocked - // - should internalResponse to request be blocked as mixed content - // - should internalResponse to request be blocked by Content Security Policy - // - should internalResponse to request be blocked due to its MIME type - // - should internalResponse to request be blocked due to nosniff - // TODO +/** + * @see https://fetch.spec.whatwg.org/#http-whitespace + * @param {string} char + */ +function isHTTPWhiteSpace (char) { + return char === '\r' || char === '\n' || char === '\t' || char === ' ' +} - // 18. If response’s type is "opaque", internalResponse’s status is 206, - // internalResponse’s range-requested flag is set, and request’s header - // list does not contain `Range`, then set response and internalResponse - // to a network error. - if ( - response.type === 'opaque' && - internalResponse.status === 206 && - internalResponse.rangeRequested && - !request.headers.contains('range') - ) { - response = internalResponse = makeNetworkError() - } +/** + * @see https://fetch.spec.whatwg.org/#http-whitespace + * @param {string} str + */ +function removeHTTPWhitespace (str, leading = true, trailing = true) { + let lead = 0 + let trail = str.length - 1 - // 19. If response is not a network error and either request’s method is - // `HEAD` or `CONNECT`, or internalResponse’s status is a null body status, - // set internalResponse’s body to null and disregard any enqueuing toward - // it (if any). - if ( - response.status !== 0 && - (request.method === 'HEAD' || - request.method === 'CONNECT' || - nullBodyStatus.includes(internalResponse.status)) - ) { - internalResponse.body = null - fetchParams.controller.dump = true + if (leading) { + for (; lead < str.length && isHTTPWhiteSpace(str[lead]); lead++); } - // 20. If request’s integrity metadata is not the empty string, then: - if (request.integrity) { - // 1. Let processBodyError be this step: run fetch finale given fetchParams - // and a network error. - const processBodyError = (reason) => - fetchFinale(fetchParams, makeNetworkError(reason)) - - // 2. If request’s response tainting is "opaque", or response’s body is null, - // then run processBodyError and abort these steps. - if (request.responseTainting === 'opaque' || response.body == null) { - processBodyError(response.error) - return - } + if (trailing) { + for (; trail > 0 && isHTTPWhiteSpace(str[trail]); trail--); + } - // 3. Let processBody given bytes be these steps: - const processBody = (bytes) => { - // 1. If bytes do not match request’s integrity metadata, - // then run processBodyError and abort these steps. [SRI] - if (!bytesMatch(bytes, request.integrity)) { - processBodyError('integrity mismatch') - return - } + return str.slice(lead, trail + 1) +} - // 2. Set response’s body to bytes as a body. - response.body = safelyExtractBody(bytes)[0] +/** + * @see https://infra.spec.whatwg.org/#ascii-whitespace + * @param {string} char + */ +function isASCIIWhitespace (char) { + return char === '\r' || char === '\n' || char === '\t' || char === '\f' || char === ' ' +} - // 3. Run fetch finale given fetchParams and response. - fetchFinale(fetchParams, response) - } +/** + * @see https://infra.spec.whatwg.org/#strip-leading-and-trailing-ascii-whitespace + */ +function removeASCIIWhitespace (str, leading = true, trailing = true) { + let lead = 0 + let trail = str.length - 1 - // 4. Fully read response’s body given processBody and processBodyError. - await fullyReadBody(response.body, processBody, processBodyError) - } else { - // 21. Otherwise, run fetch finale given fetchParams and response. - fetchFinale(fetchParams, response) + if (leading) { + for (; lead < str.length && isASCIIWhitespace(str[lead]); lead++); } -} -// https://fetch.spec.whatwg.org/#concept-scheme-fetch -// given a fetch params fetchParams -function schemeFetch (fetchParams) { - // Note: since the connection is destroyed on redirect, which sets fetchParams to a - // cancelled state, we do not want this condition to trigger *unless* there have been - // no redirects. See https://github.com/nodejs/undici/issues/1776 - // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams. - if (isCancelled(fetchParams) && fetchParams.request.redirectCount === 0) { - return Promise.resolve(makeAppropriateNetworkError(fetchParams)) + if (trailing) { + for (; trail > 0 && isASCIIWhitespace(str[trail]); trail--); } - // 2. Let request be fetchParams’s request. - const { request } = fetchParams + return str.slice(lead, trail + 1) +} - const { protocol: scheme } = requestCurrentURL(request) +module.exports = { + dataURLProcessor, + URLSerializer, + collectASequenceOfCodePoints, + collectASequenceOfCodePointsFast, + stringPercentDecode, + parseMIMEType, + collectAnHTTPQuotedString, + serializeAMimeType +} - // 3. Switch on request’s current URL’s scheme and run the associated steps: - switch (scheme) { - case 'about:': { - // If request’s current URL’s path is the string "blank", then return a new response - // whose status message is `OK`, header list is « (`Content-Type`, `text/html;charset=utf-8`) », - // and body is the empty byte sequence as a body. - // Otherwise, return a network error. - return Promise.resolve(makeNetworkError('about scheme is not supported')) - } - case 'blob:': { - if (!resolveObjectURL) { - resolveObjectURL = (__nccwpck_require__(4300).resolveObjectURL) - } +/***/ }), - // 1. Let blobURLEntry be request’s current URL’s blob URL entry. - const blobURLEntry = requestCurrentURL(request) +/***/ 8511: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // https://github.com/web-platform-tests/wpt/blob/7b0ebaccc62b566a1965396e5be7bb2bc06f841f/FileAPI/url/resources/fetch-tests.js#L52-L56 - // Buffer.resolveObjectURL does not ignore URL queries. - if (blobURLEntry.search.length !== 0) { - return Promise.resolve(makeNetworkError('NetworkError when attempting to fetch resource.')) - } +"use strict"; - const blobURLEntryObject = resolveObjectURL(blobURLEntry.toString()) - // 2. If request’s method is not `GET`, blobURLEntry is null, or blobURLEntry’s - // object is not a Blob object, then return a network error. - if (request.method !== 'GET' || !isBlobLike(blobURLEntryObject)) { - return Promise.resolve(makeNetworkError('invalid method')) - } +const { Blob, File: NativeFile } = __nccwpck_require__(4300) +const { types } = __nccwpck_require__(3837) +const { kState } = __nccwpck_require__(5861) +const { isBlobLike } = __nccwpck_require__(2538) +const { webidl } = __nccwpck_require__(1744) +const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685) +const { kEnumerableProperty } = __nccwpck_require__(3983) +const encoder = new TextEncoder() - // 3. Let bodyWithType be the result of safely extracting blobURLEntry’s object. - const bodyWithType = safelyExtractBody(blobURLEntryObject) +class File extends Blob { + constructor (fileBits, fileName, options = {}) { + // The File constructor is invoked with two or three parameters, depending + // on whether the optional dictionary parameter is used. When the File() + // constructor is invoked, user agents must run the following steps: + webidl.argumentLengthCheck(arguments, 2, { header: 'File constructor' }) - // 4. Let body be bodyWithType’s body. - const body = bodyWithType[0] + fileBits = webidl.converters['sequence'](fileBits) + fileName = webidl.converters.USVString(fileName) + options = webidl.converters.FilePropertyBag(options) - // 5. Let length be body’s length, serialized and isomorphic encoded. - const length = isomorphicEncode(`${body.length}`) + // 1. Let bytes be the result of processing blob parts given fileBits and + // options. + // Note: Blob handles this for us - // 6. Let type be bodyWithType’s type if it is non-null; otherwise the empty byte sequence. - const type = bodyWithType[1] ?? '' + // 2. Let n be the fileName argument to the constructor. + const n = fileName - // 7. Return a new response whose status message is `OK`, header list is - // « (`Content-Length`, length), (`Content-Type`, type) », and body is body. - const response = makeResponse({ - statusText: 'OK', - headersList: [ - ['content-length', { name: 'Content-Length', value: length }], - ['content-type', { name: 'Content-Type', value: type }] - ] - }) + // 3. Process FilePropertyBag dictionary argument by running the following + // substeps: - response.body = body + // 1. If the type member is provided and is not the empty string, let t + // be set to the type dictionary member. If t contains any characters + // outside the range U+0020 to U+007E, then set t to the empty string + // and return from these substeps. + // 2. Convert every character in t to ASCII lowercase. + let t = options.type + let d - return Promise.resolve(response) - } - case 'data:': { - // 1. Let dataURLStruct be the result of running the - // data: URL processor on request’s current URL. - const currentURL = requestCurrentURL(request) - const dataURLStruct = dataURLProcessor(currentURL) + // eslint-disable-next-line no-labels + substep: { + if (t) { + t = parseMIMEType(t) - // 2. If dataURLStruct is failure, then return a - // network error. - if (dataURLStruct === 'failure') { - return Promise.resolve(makeNetworkError('failed to fetch the data URL')) - } + if (t === 'failure') { + t = '' + // eslint-disable-next-line no-labels + break substep + } - // 3. Let mimeType be dataURLStruct’s MIME type, serialized. - const mimeType = serializeAMimeType(dataURLStruct.mimeType) + t = serializeAMimeType(t).toLowerCase() + } - // 4. Return a response whose status message is `OK`, - // header list is « (`Content-Type`, mimeType) », - // and body is dataURLStruct’s body as a body. - return Promise.resolve(makeResponse({ - statusText: 'OK', - headersList: [ - ['content-type', { name: 'Content-Type', value: mimeType }] - ], - body: safelyExtractBody(dataURLStruct.body)[0] - })) - } - case 'file:': { - // For now, unfortunate as it is, file URLs are left as an exercise for the reader. - // When in doubt, return a network error. - return Promise.resolve(makeNetworkError('not implemented... yet...')) + // 3. If the lastModified member is provided, let d be set to the + // lastModified dictionary member. If it is not provided, set d to the + // current date and time represented as the number of milliseconds since + // the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]). + d = options.lastModified } - case 'http:': - case 'https:': { - // Return the result of running HTTP fetch given fetchParams. - return httpFetch(fetchParams) - .catch((err) => makeNetworkError(err)) - } - default: { - return Promise.resolve(makeNetworkError('unknown scheme')) + // 4. Return a new File object F such that: + // F refers to the bytes byte sequence. + // F.size is set to the number of total bytes in bytes. + // F.name is set to n. + // F.type is set to t. + // F.lastModified is set to d. + + super(processBlobParts(fileBits, options), { type: t }) + this[kState] = { + name: n, + lastModified: d, + type: t } } -} -// https://fetch.spec.whatwg.org/#finalize-response -function finalizeResponse (fetchParams, response) { - // 1. Set fetchParams’s request’s done flag. - fetchParams.request.done = true + get name () { + webidl.brandCheck(this, File) - // 2, If fetchParams’s process response done is not null, then queue a fetch - // task to run fetchParams’s process response done given response, with - // fetchParams’s task destination. - if (fetchParams.processResponseDone != null) { - queueMicrotask(() => fetchParams.processResponseDone(response)) + return this[kState].name } -} -// https://fetch.spec.whatwg.org/#fetch-finale -function fetchFinale (fetchParams, response) { - // 1. If response is a network error, then: - if (response.type === 'error') { - // 1. Set response’s URL list to « fetchParams’s request’s URL list[0] ». - response.urlList = [fetchParams.request.urlList[0]] + get lastModified () { + webidl.brandCheck(this, File) - // 2. Set response’s timing info to the result of creating an opaque timing - // info for fetchParams’s timing info. - response.timingInfo = createOpaqueTimingInfo({ - startTime: fetchParams.timingInfo.startTime - }) + return this[kState].lastModified } - // 2. Let processResponseEndOfBody be the following steps: - const processResponseEndOfBody = () => { - // 1. Set fetchParams’s request’s done flag. - fetchParams.request.done = true + get type () { + webidl.brandCheck(this, File) - // If fetchParams’s process response end-of-body is not null, - // then queue a fetch task to run fetchParams’s process response - // end-of-body given response with fetchParams’s task destination. - if (fetchParams.processResponseEndOfBody != null) { - queueMicrotask(() => fetchParams.processResponseEndOfBody(response)) - } + return this[kState].type } +} - // 3. If fetchParams’s process response is non-null, then queue a fetch task - // to run fetchParams’s process response given response, with fetchParams’s - // task destination. - if (fetchParams.processResponse != null) { - queueMicrotask(() => fetchParams.processResponse(response)) - } +class FileLike { + constructor (blobLike, fileName, options = {}) { + // TODO: argument idl type check - // 4. If response’s body is null, then run processResponseEndOfBody. - if (response.body == null) { - processResponseEndOfBody() - } else { - // 5. Otherwise: + // The File constructor is invoked with two or three parameters, depending + // on whether the optional dictionary parameter is used. When the File() + // constructor is invoked, user agents must run the following steps: - // 1. Let transformStream be a new a TransformStream. + // 1. Let bytes be the result of processing blob parts given fileBits and + // options. - // 2. Let identityTransformAlgorithm be an algorithm which, given chunk, - // enqueues chunk in transformStream. - const identityTransformAlgorithm = (chunk, controller) => { - controller.enqueue(chunk) - } + // 2. Let n be the fileName argument to the constructor. + const n = fileName - // 3. Set up transformStream with transformAlgorithm set to identityTransformAlgorithm - // and flushAlgorithm set to processResponseEndOfBody. - const transformStream = new TransformStream({ - start () {}, - transform: identityTransformAlgorithm, - flush: processResponseEndOfBody - }, { - size () { - return 1 - } - }, { - size () { - return 1 - } - }) + // 3. Process FilePropertyBag dictionary argument by running the following + // substeps: - // 4. Set response’s body to the result of piping response’s body through transformStream. - response.body = { stream: response.body.stream.pipeThrough(transformStream) } - } + // 1. If the type member is provided and is not the empty string, let t + // be set to the type dictionary member. If t contains any characters + // outside the range U+0020 to U+007E, then set t to the empty string + // and return from these substeps. + // TODO + const t = options.type - // 6. If fetchParams’s process response consume body is non-null, then: - if (fetchParams.processResponseConsumeBody != null) { - // 1. Let processBody given nullOrBytes be this step: run fetchParams’s - // process response consume body given response and nullOrBytes. - const processBody = (nullOrBytes) => fetchParams.processResponseConsumeBody(response, nullOrBytes) + // 2. Convert every character in t to ASCII lowercase. + // TODO - // 2. Let processBodyError be this step: run fetchParams’s process - // response consume body given response and failure. - const processBodyError = (failure) => fetchParams.processResponseConsumeBody(response, failure) + // 3. If the lastModified member is provided, let d be set to the + // lastModified dictionary member. If it is not provided, set d to the + // current date and time represented as the number of milliseconds since + // the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]). + const d = options.lastModified ?? Date.now() - // 3. If response’s body is null, then queue a fetch task to run processBody - // given null, with fetchParams’s task destination. - if (response.body == null) { - queueMicrotask(() => processBody(null)) - } else { - // 4. Otherwise, fully read response’s body given processBody, processBodyError, - // and fetchParams’s task destination. - return fullyReadBody(response.body, processBody, processBodyError) + // 4. Return a new File object F such that: + // F refers to the bytes byte sequence. + // F.size is set to the number of total bytes in bytes. + // F.name is set to n. + // F.type is set to t. + // F.lastModified is set to d. + + this[kState] = { + blobLike, + name: n, + type: t, + lastModified: d } - return Promise.resolve() } -} - -// https://fetch.spec.whatwg.org/#http-fetch -async function httpFetch (fetchParams) { - // 1. Let request be fetchParams’s request. - const request = fetchParams.request - // 2. Let response be null. - let response = null + stream (...args) { + webidl.brandCheck(this, FileLike) - // 3. Let actualResponse be null. - let actualResponse = null + return this[kState].blobLike.stream(...args) + } - // 4. Let timingInfo be fetchParams’s timing info. - const timingInfo = fetchParams.timingInfo + arrayBuffer (...args) { + webidl.brandCheck(this, FileLike) - // 5. If request’s service-workers mode is "all", then: - if (request.serviceWorkers === 'all') { - // TODO + return this[kState].blobLike.arrayBuffer(...args) } - // 6. If response is null, then: - if (response === null) { - // 1. If makeCORSPreflight is true and one of these conditions is true: - // TODO - - // 2. If request’s redirect mode is "follow", then set request’s - // service-workers mode to "none". - if (request.redirect === 'follow') { - request.serviceWorkers = 'none' - } + slice (...args) { + webidl.brandCheck(this, FileLike) - // 3. Set response and actualResponse to the result of running - // HTTP-network-or-cache fetch given fetchParams. - actualResponse = response = await httpNetworkOrCacheFetch(fetchParams) + return this[kState].blobLike.slice(...args) + } - // 4. If request’s response tainting is "cors" and a CORS check - // for request and response returns failure, then return a network error. - if ( - request.responseTainting === 'cors' && - corsCheck(request, response) === 'failure' - ) { - return makeNetworkError('cors failure') - } + text (...args) { + webidl.brandCheck(this, FileLike) - // 5. If the TAO check for request and response returns failure, then set - // request’s timing allow failed flag. - if (TAOCheck(request, response) === 'failure') { - request.timingAllowFailed = true - } + return this[kState].blobLike.text(...args) } - // 7. If either request’s response tainting or response’s type - // is "opaque", and the cross-origin resource policy check with - // request’s origin, request’s client, request’s destination, - // and actualResponse returns blocked, then return a network error. - if ( - (request.responseTainting === 'opaque' || response.type === 'opaque') && - crossOriginResourcePolicyCheck( - request.origin, - request.client, - request.destination, - actualResponse - ) === 'blocked' - ) { - return makeNetworkError('blocked') + get size () { + webidl.brandCheck(this, FileLike) + + return this[kState].blobLike.size } - // 8. If actualResponse’s status is a redirect status, then: - if (redirectStatusSet.has(actualResponse.status)) { - // 1. If actualResponse’s status is not 303, request’s body is not null, - // and the connection uses HTTP/2, then user agents may, and are even - // encouraged to, transmit an RST_STREAM frame. - // See, https://github.com/whatwg/fetch/issues/1288 - if (request.redirect !== 'manual') { - fetchParams.controller.connection.destroy() - } + get type () { + webidl.brandCheck(this, FileLike) - // 2. Switch on request’s redirect mode: - if (request.redirect === 'error') { - // Set response to a network error. - response = makeNetworkError('unexpected redirect') - } else if (request.redirect === 'manual') { - // Set response to an opaque-redirect filtered response whose internal - // response is actualResponse. - // NOTE(spec): On the web this would return an `opaqueredirect` response, - // but that doesn't make sense server side. - // See https://github.com/nodejs/undici/issues/1193. - response = actualResponse - } else if (request.redirect === 'follow') { - // Set response to the result of running HTTP-redirect fetch given - // fetchParams and response. - response = await httpRedirectFetch(fetchParams, response) - } else { - assert(false) - } + return this[kState].blobLike.type } - // 9. Set response’s timing info to timingInfo. - response.timingInfo = timingInfo + get name () { + webidl.brandCheck(this, FileLike) - // 10. Return response. - return response -} + return this[kState].name + } -// https://fetch.spec.whatwg.org/#http-redirect-fetch -function httpRedirectFetch (fetchParams, response) { - // 1. Let request be fetchParams’s request. - const request = fetchParams.request + get lastModified () { + webidl.brandCheck(this, FileLike) - // 2. Let actualResponse be response, if response is not a filtered response, - // and response’s internal response otherwise. - const actualResponse = response.internalResponse - ? response.internalResponse - : response + return this[kState].lastModified + } - // 3. Let locationURL be actualResponse’s location URL given request’s current - // URL’s fragment. - let locationURL + get [Symbol.toStringTag] () { + return 'File' + } +} - try { - locationURL = responseLocationURL( - actualResponse, - requestCurrentURL(request).hash - ) +Object.defineProperties(File.prototype, { + [Symbol.toStringTag]: { + value: 'File', + configurable: true + }, + name: kEnumerableProperty, + lastModified: kEnumerableProperty +}) - // 4. If locationURL is null, then return response. - if (locationURL == null) { - return response +webidl.converters.Blob = webidl.interfaceConverter(Blob) + +webidl.converters.BlobPart = function (V, opts) { + if (webidl.util.Type(V) === 'Object') { + if (isBlobLike(V)) { + return webidl.converters.Blob(V, { strict: false }) } - } catch (err) { - // 5. If locationURL is failure, then return a network error. - return Promise.resolve(makeNetworkError(err)) - } - // 6. If locationURL’s scheme is not an HTTP(S) scheme, then return a network - // error. - if (!urlIsHttpHttpsScheme(locationURL)) { - return Promise.resolve(makeNetworkError('URL scheme must be a HTTP(S) scheme')) + if ( + ArrayBuffer.isView(V) || + types.isAnyArrayBuffer(V) + ) { + return webidl.converters.BufferSource(V, opts) + } } - // 7. If request’s redirect count is 20, then return a network error. - if (request.redirectCount === 20) { - return Promise.resolve(makeNetworkError('redirect count exceeded')) - } + return webidl.converters.USVString(V, opts) +} - // 8. Increase request’s redirect count by 1. - request.redirectCount += 1 +webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.BlobPart +) - // 9. If request’s mode is "cors", locationURL includes credentials, and - // request’s origin is not same origin with locationURL’s origin, then return - // a network error. - if ( - request.mode === 'cors' && - (locationURL.username || locationURL.password) && - !sameOrigin(request, locationURL) - ) { - return Promise.resolve(makeNetworkError('cross origin not allowed for request mode "cors"')) - } +// https://www.w3.org/TR/FileAPI/#dfn-FilePropertyBag +webidl.converters.FilePropertyBag = webidl.dictionaryConverter([ + { + key: 'lastModified', + converter: webidl.converters['long long'], + get defaultValue () { + return Date.now() + } + }, + { + key: 'type', + converter: webidl.converters.DOMString, + defaultValue: '' + }, + { + key: 'endings', + converter: (value) => { + value = webidl.converters.DOMString(value) + value = value.toLowerCase() - // 10. If request’s response tainting is "cors" and locationURL includes - // credentials, then return a network error. - if ( - request.responseTainting === 'cors' && - (locationURL.username || locationURL.password) - ) { - return Promise.resolve(makeNetworkError( - 'URL cannot contain credentials for request mode "cors"' - )) - } + if (value !== 'native') { + value = 'transparent' + } - // 11. If actualResponse’s status is not 303, request’s body is non-null, - // and request’s body’s source is null, then return a network error. - if ( - actualResponse.status !== 303 && - request.body != null && - request.body.source == null - ) { - return Promise.resolve(makeNetworkError()) + return value + }, + defaultValue: 'transparent' } +]) - // 12. If one of the following is true - // - actualResponse’s status is 301 or 302 and request’s method is `POST` - // - actualResponse’s status is 303 and request’s method is not `GET` or `HEAD` - if ( - ([301, 302].includes(actualResponse.status) && request.method === 'POST') || - (actualResponse.status === 303 && - !GET_OR_HEAD.includes(request.method)) - ) { - // then: - // 1. Set request’s method to `GET` and request’s body to null. - request.method = 'GET' - request.body = null - - // 2. For each headerName of request-body-header name, delete headerName from - // request’s header list. - for (const headerName of requestBodyHeader) { - request.headersList.delete(headerName) - } - } +/** + * @see https://www.w3.org/TR/FileAPI/#process-blob-parts + * @param {(NodeJS.TypedArray|Blob|string)[]} parts + * @param {{ type: string, endings: string }} options + */ +function processBlobParts (parts, options) { + // 1. Let bytes be an empty sequence of bytes. + /** @type {NodeJS.TypedArray[]} */ + const bytes = [] - // 13. If request’s current URL’s origin is not same origin with locationURL’s - // origin, then for each headerName of CORS non-wildcard request-header name, - // delete headerName from request’s header list. - if (!sameOrigin(requestCurrentURL(request), locationURL)) { - // https://fetch.spec.whatwg.org/#cors-non-wildcard-request-header-name - request.headersList.delete('authorization') + // 2. For each element in parts: + for (const element of parts) { + // 1. If element is a USVString, run the following substeps: + if (typeof element === 'string') { + // 1. Let s be element. + let s = element - // "Cookie" and "Host" are forbidden request-headers, which undici doesn't implement. - request.headersList.delete('cookie') - request.headersList.delete('host') - } + // 2. If the endings member of options is "native", set s + // to the result of converting line endings to native + // of element. + if (options.endings === 'native') { + s = convertLineEndingsNative(s) + } - // 14. If request’s body is non-null, then set request’s body to the first return - // value of safely extracting request’s body’s source. - if (request.body != null) { - assert(request.body.source != null) - request.body = safelyExtractBody(request.body.source)[0] + // 3. Append the result of UTF-8 encoding s to bytes. + bytes.push(encoder.encode(s)) + } else if ( + types.isAnyArrayBuffer(element) || + types.isTypedArray(element) + ) { + // 2. If element is a BufferSource, get a copy of the + // bytes held by the buffer source, and append those + // bytes to bytes. + if (!element.buffer) { // ArrayBuffer + bytes.push(new Uint8Array(element)) + } else { + bytes.push( + new Uint8Array(element.buffer, element.byteOffset, element.byteLength) + ) + } + } else if (isBlobLike(element)) { + // 3. If element is a Blob, append the bytes it represents + // to bytes. + bytes.push(element) + } } - // 15. Let timingInfo be fetchParams’s timing info. - const timingInfo = fetchParams.timingInfo + // 3. Return bytes. + return bytes +} - // 16. Set timingInfo’s redirect end time and post-redirect start time to the - // coarsened shared current time given fetchParams’s cross-origin isolated - // capability. - timingInfo.redirectEndTime = timingInfo.postRedirectStartTime = - coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability) +/** + * @see https://www.w3.org/TR/FileAPI/#convert-line-endings-to-native + * @param {string} s + */ +function convertLineEndingsNative (s) { + // 1. Let native line ending be be the code point U+000A LF. + let nativeLineEnding = '\n' - // 17. If timingInfo’s redirect start time is 0, then set timingInfo’s - // redirect start time to timingInfo’s start time. - if (timingInfo.redirectStartTime === 0) { - timingInfo.redirectStartTime = timingInfo.startTime + // 2. If the underlying platform’s conventions are to + // represent newlines as a carriage return and line feed + // sequence, set native line ending to the code point + // U+000D CR followed by the code point U+000A LF. + if (process.platform === 'win32') { + nativeLineEnding = '\r\n' } - // 18. Append locationURL to request’s URL list. - request.urlList.push(locationURL) - - // 19. Invoke set request’s referrer policy on redirect on request and - // actualResponse. - setRequestReferrerPolicyOnRedirect(request, actualResponse) + return s.replace(/\r?\n/g, nativeLineEnding) +} - // 20. Return the result of running main fetch given fetchParams and true. - return mainFetch(fetchParams, true) +// If this function is moved to ./util.js, some tools (such as +// rollup) will warn about circular dependencies. See: +// https://github.com/nodejs/undici/issues/1629 +function isFileLike (object) { + return ( + (NativeFile && object instanceof NativeFile) || + object instanceof File || ( + object && + (typeof object.stream === 'function' || + typeof object.arrayBuffer === 'function') && + object[Symbol.toStringTag] === 'File' + ) + ) } -// https://fetch.spec.whatwg.org/#http-network-or-cache-fetch -async function httpNetworkOrCacheFetch ( - fetchParams, - isAuthenticationFetch = false, - isNewConnectionFetch = false -) { - // 1. Let request be fetchParams’s request. - const request = fetchParams.request +module.exports = { File, FileLike, isFileLike } - // 2. Let httpFetchParams be null. - let httpFetchParams = null - // 3. Let httpRequest be null. - let httpRequest = null +/***/ }), - // 4. Let response be null. - let response = null +/***/ 2015: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // 5. Let storedResponse be null. - // TODO: cache +"use strict"; - // 6. Let httpCache be null. - const httpCache = null - // 7. Let the revalidatingFlag be unset. - const revalidatingFlag = false - - // 8. Run these steps, but abort when the ongoing fetch is terminated: - - // 1. If request’s window is "no-window" and request’s redirect mode is - // "error", then set httpFetchParams to fetchParams and httpRequest to - // request. - if (request.window === 'no-window' && request.redirect === 'error') { - httpFetchParams = fetchParams - httpRequest = request - } else { - // Otherwise: +const { isBlobLike, toUSVString, makeIterator } = __nccwpck_require__(2538) +const { kState } = __nccwpck_require__(5861) +const { File: UndiciFile, FileLike, isFileLike } = __nccwpck_require__(8511) +const { webidl } = __nccwpck_require__(1744) +const { Blob, File: NativeFile } = __nccwpck_require__(4300) - // 1. Set httpRequest to a clone of request. - httpRequest = makeRequest(request) +/** @type {globalThis['File']} */ +const File = NativeFile ?? UndiciFile - // 2. Set httpFetchParams to a copy of fetchParams. - httpFetchParams = { ...fetchParams } +// https://xhr.spec.whatwg.org/#formdata +class FormData { + constructor (form) { + if (form !== undefined) { + throw webidl.errors.conversionFailed({ + prefix: 'FormData constructor', + argument: 'Argument 1', + types: ['undefined'] + }) + } - // 3. Set httpFetchParams’s request to httpRequest. - httpFetchParams.request = httpRequest + this[kState] = [] } - // 3. Let includeCredentials be true if one of - const includeCredentials = - request.credentials === 'include' || - (request.credentials === 'same-origin' && - request.responseTainting === 'basic') - - // 4. Let contentLength be httpRequest’s body’s length, if httpRequest’s - // body is non-null; otherwise null. - const contentLength = httpRequest.body ? httpRequest.body.length : null + append (name, value, filename = undefined) { + webidl.brandCheck(this, FormData) - // 5. Let contentLengthHeaderValue be null. - let contentLengthHeaderValue = null + webidl.argumentLengthCheck(arguments, 2, { header: 'FormData.append' }) - // 6. If httpRequest’s body is null and httpRequest’s method is `POST` or - // `PUT`, then set contentLengthHeaderValue to `0`. - if ( - httpRequest.body == null && - ['POST', 'PUT'].includes(httpRequest.method) - ) { - contentLengthHeaderValue = '0' - } + if (arguments.length === 3 && !isBlobLike(value)) { + throw new TypeError( + "Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'" + ) + } - // 7. If contentLength is non-null, then set contentLengthHeaderValue to - // contentLength, serialized and isomorphic encoded. - if (contentLength != null) { - contentLengthHeaderValue = isomorphicEncode(`${contentLength}`) - } + // 1. Let value be value if given; otherwise blobValue. - // 8. If contentLengthHeaderValue is non-null, then append - // `Content-Length`/contentLengthHeaderValue to httpRequest’s header - // list. - if (contentLengthHeaderValue != null) { - httpRequest.headersList.append('content-length', contentLengthHeaderValue) - } + name = webidl.converters.USVString(name) + value = isBlobLike(value) + ? webidl.converters.Blob(value, { strict: false }) + : webidl.converters.USVString(value) + filename = arguments.length === 3 + ? webidl.converters.USVString(filename) + : undefined - // 9. If contentLengthHeaderValue is non-null, then append (`Content-Length`, - // contentLengthHeaderValue) to httpRequest’s header list. + // 2. Let entry be the result of creating an entry with + // name, value, and filename if given. + const entry = makeEntry(name, value, filename) - // 10. If contentLength is non-null and httpRequest’s keepalive is true, - // then: - if (contentLength != null && httpRequest.keepalive) { - // NOTE: keepalive is a noop outside of browser context. + // 3. Append entry to this’s entry list. + this[kState].push(entry) } - // 11. If httpRequest’s referrer is a URL, then append - // `Referer`/httpRequest’s referrer, serialized and isomorphic encoded, - // to httpRequest’s header list. - if (httpRequest.referrer instanceof URL) { - httpRequest.headersList.append('referer', isomorphicEncode(httpRequest.referrer.href)) - } + delete (name) { + webidl.brandCheck(this, FormData) - // 12. Append a request `Origin` header for httpRequest. - appendRequestOriginHeader(httpRequest) + webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.delete' }) - // 13. Append the Fetch metadata headers for httpRequest. [FETCH-METADATA] - appendFetchMetadata(httpRequest) + name = webidl.converters.USVString(name) - // 14. If httpRequest’s header list does not contain `User-Agent`, then - // user agents should append `User-Agent`/default `User-Agent` value to - // httpRequest’s header list. - if (!httpRequest.headersList.contains('user-agent')) { - httpRequest.headersList.append('user-agent', typeof esbuildDetection === 'undefined' ? 'undici' : 'node') + // The delete(name) method steps are to remove all entries whose name + // is name from this’s entry list. + this[kState] = this[kState].filter(entry => entry.name !== name) } - // 15. If httpRequest’s cache mode is "default" and httpRequest’s header - // list contains `If-Modified-Since`, `If-None-Match`, - // `If-Unmodified-Since`, `If-Match`, or `If-Range`, then set - // httpRequest’s cache mode to "no-store". - if ( - httpRequest.cache === 'default' && - (httpRequest.headersList.contains('if-modified-since') || - httpRequest.headersList.contains('if-none-match') || - httpRequest.headersList.contains('if-unmodified-since') || - httpRequest.headersList.contains('if-match') || - httpRequest.headersList.contains('if-range')) - ) { - httpRequest.cache = 'no-store' - } + get (name) { + webidl.brandCheck(this, FormData) - // 16. If httpRequest’s cache mode is "no-cache", httpRequest’s prevent - // no-cache cache-control header modification flag is unset, and - // httpRequest’s header list does not contain `Cache-Control`, then append - // `Cache-Control`/`max-age=0` to httpRequest’s header list. - if ( - httpRequest.cache === 'no-cache' && - !httpRequest.preventNoCacheCacheControlHeaderModification && - !httpRequest.headersList.contains('cache-control') - ) { - httpRequest.headersList.append('cache-control', 'max-age=0') - } + webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.get' }) - // 17. If httpRequest’s cache mode is "no-store" or "reload", then: - if (httpRequest.cache === 'no-store' || httpRequest.cache === 'reload') { - // 1. If httpRequest’s header list does not contain `Pragma`, then append - // `Pragma`/`no-cache` to httpRequest’s header list. - if (!httpRequest.headersList.contains('pragma')) { - httpRequest.headersList.append('pragma', 'no-cache') - } + name = webidl.converters.USVString(name) - // 2. If httpRequest’s header list does not contain `Cache-Control`, - // then append `Cache-Control`/`no-cache` to httpRequest’s header list. - if (!httpRequest.headersList.contains('cache-control')) { - httpRequest.headersList.append('cache-control', 'no-cache') + // 1. If there is no entry whose name is name in this’s entry list, + // then return null. + const idx = this[kState].findIndex((entry) => entry.name === name) + if (idx === -1) { + return null } - } - // 18. If httpRequest’s header list contains `Range`, then append - // `Accept-Encoding`/`identity` to httpRequest’s header list. - if (httpRequest.headersList.contains('range')) { - httpRequest.headersList.append('accept-encoding', 'identity') + // 2. Return the value of the first entry whose name is name from + // this’s entry list. + return this[kState][idx].value } - // 19. Modify httpRequest’s header list per HTTP. Do not append a given - // header if httpRequest’s header list contains that header’s name. - // TODO: https://github.com/whatwg/fetch/issues/1285#issuecomment-896560129 - if (!httpRequest.headersList.contains('accept-encoding')) { - if (urlHasHttpsScheme(requestCurrentURL(httpRequest))) { - httpRequest.headersList.append('accept-encoding', 'br, gzip, deflate') - } else { - httpRequest.headersList.append('accept-encoding', 'gzip, deflate') - } - } + getAll (name) { + webidl.brandCheck(this, FormData) - httpRequest.headersList.delete('host') + webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.getAll' }) - // 20. If includeCredentials is true, then: - if (includeCredentials) { - // 1. If the user agent is not configured to block cookies for httpRequest - // (see section 7 of [COOKIES]), then: - // TODO: credentials - // 2. If httpRequest’s header list does not contain `Authorization`, then: - // TODO: credentials + name = webidl.converters.USVString(name) + + // 1. If there is no entry whose name is name in this’s entry list, + // then return the empty list. + // 2. Return the values of all entries whose name is name, in order, + // from this’s entry list. + return this[kState] + .filter((entry) => entry.name === name) + .map((entry) => entry.value) } - // 21. If there’s a proxy-authentication entry, use it as appropriate. - // TODO: proxy-authentication + has (name) { + webidl.brandCheck(this, FormData) - // 22. Set httpCache to the result of determining the HTTP cache - // partition, given httpRequest. - // TODO: cache + webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.has' }) - // 23. If httpCache is null, then set httpRequest’s cache mode to - // "no-store". - if (httpCache == null) { - httpRequest.cache = 'no-store' - } + name = webidl.converters.USVString(name) - // 24. If httpRequest’s cache mode is neither "no-store" nor "reload", - // then: - if (httpRequest.mode !== 'no-store' && httpRequest.mode !== 'reload') { - // TODO: cache + // The has(name) method steps are to return true if there is an entry + // whose name is name in this’s entry list; otherwise false. + return this[kState].findIndex((entry) => entry.name === name) !== -1 } - // 9. If aborted, then return the appropriate network error for fetchParams. - // TODO + set (name, value, filename = undefined) { + webidl.brandCheck(this, FormData) - // 10. If response is null, then: - if (response == null) { - // 1. If httpRequest’s cache mode is "only-if-cached", then return a - // network error. - if (httpRequest.mode === 'only-if-cached') { - return makeNetworkError('only if cached') + webidl.argumentLengthCheck(arguments, 2, { header: 'FormData.set' }) + + if (arguments.length === 3 && !isBlobLike(value)) { + throw new TypeError( + "Failed to execute 'set' on 'FormData': parameter 2 is not of type 'Blob'" + ) } - // 2. Let forwardResponse be the result of running HTTP-network fetch - // given httpFetchParams, includeCredentials, and isNewConnectionFetch. - const forwardResponse = await httpNetworkFetch( - httpFetchParams, - includeCredentials, - isNewConnectionFetch - ) + // The set(name, value) and set(name, blobValue, filename) method steps + // are: - // 3. If httpRequest’s method is unsafe and forwardResponse’s status is - // in the range 200 to 399, inclusive, invalidate appropriate stored - // responses in httpCache, as per the "Invalidation" chapter of HTTP - // Caching, and set storedResponse to null. [HTTP-CACHING] - if ( - !safeMethodsSet.has(httpRequest.method) && - forwardResponse.status >= 200 && - forwardResponse.status <= 399 - ) { - // TODO: cache - } + // 1. Let value be value if given; otherwise blobValue. - // 4. If the revalidatingFlag is set and forwardResponse’s status is 304, - // then: - if (revalidatingFlag && forwardResponse.status === 304) { - // TODO: cache - } + name = webidl.converters.USVString(name) + value = isBlobLike(value) + ? webidl.converters.Blob(value, { strict: false }) + : webidl.converters.USVString(value) + filename = arguments.length === 3 + ? toUSVString(filename) + : undefined - // 5. If response is null, then: - if (response == null) { - // 1. Set response to forwardResponse. - response = forwardResponse + // 2. Let entry be the result of creating an entry with name, value, and + // filename if given. + const entry = makeEntry(name, value, filename) - // 2. Store httpRequest and forwardResponse in httpCache, as per the - // "Storing Responses in Caches" chapter of HTTP Caching. [HTTP-CACHING] - // TODO: cache + // 3. If there are entries in this’s entry list whose name is name, then + // replace the first such entry with entry and remove the others. + const idx = this[kState].findIndex((entry) => entry.name === name) + if (idx !== -1) { + this[kState] = [ + ...this[kState].slice(0, idx), + entry, + ...this[kState].slice(idx + 1).filter((entry) => entry.name !== name) + ] + } else { + // 4. Otherwise, append entry to this’s entry list. + this[kState].push(entry) } } - // 11. Set response’s URL list to a clone of httpRequest’s URL list. - response.urlList = [...httpRequest.urlList] + entries () { + webidl.brandCheck(this, FormData) - // 12. If httpRequest’s header list contains `Range`, then set response’s - // range-requested flag. - if (httpRequest.headersList.contains('range')) { - response.rangeRequested = true + return makeIterator( + () => this[kState].map(pair => [pair.name, pair.value]), + 'FormData', + 'key+value' + ) } - // 13. Set response’s request-includes-credentials to includeCredentials. - response.requestIncludesCredentials = includeCredentials - - // 14. If response’s status is 401, httpRequest’s response tainting is not - // "cors", includeCredentials is true, and request’s window is an environment - // settings object, then: - // TODO - - // 15. If response’s status is 407, then: - if (response.status === 407) { - // 1. If request’s window is "no-window", then return a network error. - if (request.window === 'no-window') { - return makeNetworkError() - } - - // 2. ??? + keys () { + webidl.brandCheck(this, FormData) - // 3. If fetchParams is canceled, then return the appropriate network error for fetchParams. - if (isCancelled(fetchParams)) { - return makeAppropriateNetworkError(fetchParams) - } + return makeIterator( + () => this[kState].map(pair => [pair.name, pair.value]), + 'FormData', + 'key' + ) + } - // 4. Prompt the end user as appropriate in request’s window and store - // the result as a proxy-authentication entry. [HTTP-AUTH] - // TODO: Invoke some kind of callback? + values () { + webidl.brandCheck(this, FormData) - // 5. Set response to the result of running HTTP-network-or-cache fetch given - // fetchParams. - // TODO - return makeNetworkError('proxy authentication required') + return makeIterator( + () => this[kState].map(pair => [pair.name, pair.value]), + 'FormData', + 'value' + ) } - // 16. If all of the following are true - if ( - // response’s status is 421 - response.status === 421 && - // isNewConnectionFetch is false - !isNewConnectionFetch && - // request’s body is null, or request’s body is non-null and request’s body’s source is non-null - (request.body == null || request.body.source != null) - ) { - // then: + /** + * @param {(value: string, key: string, self: FormData) => void} callbackFn + * @param {unknown} thisArg + */ + forEach (callbackFn, thisArg = globalThis) { + webidl.brandCheck(this, FormData) - // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams. - if (isCancelled(fetchParams)) { - return makeAppropriateNetworkError(fetchParams) + webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.forEach' }) + + if (typeof callbackFn !== 'function') { + throw new TypeError( + "Failed to execute 'forEach' on 'FormData': parameter 1 is not of type 'Function'." + ) } - // 2. Set response to the result of running HTTP-network-or-cache - // fetch given fetchParams, isAuthenticationFetch, and true. + for (const [key, value] of this) { + callbackFn.apply(thisArg, [value, key, this]) + } + } +} - // TODO (spec): The spec doesn't specify this but we need to cancel - // the active response before we can start a new one. - // https://github.com/whatwg/fetch/issues/1293 - fetchParams.controller.connection.destroy() +FormData.prototype[Symbol.iterator] = FormData.prototype.entries - response = await httpNetworkOrCacheFetch( - fetchParams, - isAuthenticationFetch, - true - ) +Object.defineProperties(FormData.prototype, { + [Symbol.toStringTag]: { + value: 'FormData', + configurable: true } +}) - // 17. If isAuthenticationFetch is true, then create an authentication entry - if (isAuthenticationFetch) { - // TODO - } +/** + * @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#create-an-entry + * @param {string} name + * @param {string|Blob} value + * @param {?string} filename + * @returns + */ +function makeEntry (name, value, filename) { + // 1. Set name to the result of converting name into a scalar value string. + // "To convert a string into a scalar value string, replace any surrogates + // with U+FFFD." + // see: https://nodejs.org/dist/latest-v18.x/docs/api/buffer.html#buftostringencoding-start-end + name = Buffer.from(name).toString('utf8') - // 18. Return response. - return response -} + // 2. If value is a string, then set value to the result of converting + // value into a scalar value string. + if (typeof value === 'string') { + value = Buffer.from(value).toString('utf8') + } else { + // 3. Otherwise: -// https://fetch.spec.whatwg.org/#http-network-fetch -async function httpNetworkFetch ( - fetchParams, - includeCredentials = false, - forceNewConnection = false -) { - assert(!fetchParams.controller.connection || fetchParams.controller.connection.destroyed) + // 1. If value is not a File object, then set value to a new File object, + // representing the same bytes, whose name attribute value is "blob" + if (!isFileLike(value)) { + value = value instanceof Blob + ? new File([value], 'blob', { type: value.type }) + : new FileLike(value, 'blob', { type: value.type }) + } - fetchParams.controller.connection = { - abort: null, - destroyed: false, - destroy (err) { - if (!this.destroyed) { - this.destroyed = true - this.abort?.(err ?? new DOMException('The operation was aborted.', 'AbortError')) + // 2. If filename is given, then set value to a new File object, + // representing the same bytes, whose name attribute is filename. + if (filename !== undefined) { + /** @type {FilePropertyBag} */ + const options = { + type: value.type, + lastModified: value.lastModified } + + value = (NativeFile && value instanceof NativeFile) || value instanceof UndiciFile + ? new File([value], filename, options) + : new FileLike(value, filename, options) } } - // 1. Let request be fetchParams’s request. - const request = fetchParams.request + // 4. Return an entry whose name is name and whose value is value. + return { name, value } +} - // 2. Let response be null. - let response = null +module.exports = { FormData } - // 3. Let timingInfo be fetchParams’s timing info. - const timingInfo = fetchParams.timingInfo - // 4. Let httpCache be the result of determining the HTTP cache partition, - // given request. - // TODO: cache - const httpCache = null +/***/ }), - // 5. If httpCache is null, then set request’s cache mode to "no-store". - if (httpCache == null) { - request.cache = 'no-store' - } +/***/ 1246: +/***/ ((module) => { - // 6. Let networkPartitionKey be the result of determining the network - // partition key given request. - // TODO +"use strict"; - // 7. Let newConnection be "yes" if forceNewConnection is true; otherwise - // "no". - const newConnection = forceNewConnection ? 'yes' : 'no' // eslint-disable-line no-unused-vars - // 8. Switch on request’s mode: - if (request.mode === 'websocket') { - // Let connection be the result of obtaining a WebSocket connection, - // given request’s current URL. - // TODO - } else { - // Let connection be the result of obtaining a connection, given - // networkPartitionKey, request’s current URL’s origin, - // includeCredentials, and forceNewConnection. - // TODO - } +// In case of breaking changes, increase the version +// number to avoid conflicts. +const globalOrigin = Symbol.for('undici.globalOrigin.1') - // 9. Run these steps, but abort when the ongoing fetch is terminated: +function getGlobalOrigin () { + return globalThis[globalOrigin] +} - // 1. If connection is failure, then return a network error. +function setGlobalOrigin (newOrigin) { + if (newOrigin === undefined) { + Object.defineProperty(globalThis, globalOrigin, { + value: undefined, + writable: true, + enumerable: false, + configurable: false + }) - // 2. Set timingInfo’s final connection timing info to the result of - // calling clamp and coarsen connection timing info with connection’s - // timing info, timingInfo’s post-redirect start time, and fetchParams’s - // cross-origin isolated capability. + return + } - // 3. If connection is not an HTTP/2 connection, request’s body is non-null, - // and request’s body’s source is null, then append (`Transfer-Encoding`, - // `chunked`) to request’s header list. + const parsedURL = new URL(newOrigin) - // 4. Set timingInfo’s final network-request start time to the coarsened - // shared current time given fetchParams’s cross-origin isolated - // capability. + if (parsedURL.protocol !== 'http:' && parsedURL.protocol !== 'https:') { + throw new TypeError(`Only http & https urls are allowed, received ${parsedURL.protocol}`) + } - // 5. Set response to the result of making an HTTP request over connection - // using request with the following caveats: + Object.defineProperty(globalThis, globalOrigin, { + value: parsedURL, + writable: true, + enumerable: false, + configurable: false + }) +} - // - Follow the relevant requirements from HTTP. [HTTP] [HTTP-SEMANTICS] - // [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH] +module.exports = { + getGlobalOrigin, + setGlobalOrigin +} - // - If request’s body is non-null, and request’s body’s source is null, - // then the user agent may have a buffer of up to 64 kibibytes and store - // a part of request’s body in that buffer. If the user agent reads from - // request’s body beyond that buffer’s size and the user agent needs to - // resend request, then instead return a network error. - // - Set timingInfo’s final network-response start time to the coarsened - // shared current time given fetchParams’s cross-origin isolated capability, - // immediately after the user agent’s HTTP parser receives the first byte - // of the response (e.g., frame header bytes for HTTP/2 or response status - // line for HTTP/1.x). +/***/ }), - // - Wait until all the headers are transmitted. +/***/ 554: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // - Any responses whose status is in the range 100 to 199, inclusive, - // and is not 101, are to be ignored, except for the purposes of setting - // timingInfo’s final network-response start time above. +"use strict"; +// https://github.com/Ethan-Arrowood/undici-fetch - // - If request’s header list contains `Transfer-Encoding`/`chunked` and - // response is transferred via HTTP/1.0 or older, then return a network - // error. - // - If the HTTP request results in a TLS client certificate dialog, then: - // 1. If request’s window is an environment settings object, make the - // dialog available in request’s window. +const { kHeadersList, kConstruct } = __nccwpck_require__(2785) +const { kGuard } = __nccwpck_require__(5861) +const { kEnumerableProperty } = __nccwpck_require__(3983) +const { + makeIterator, + isValidHeaderName, + isValidHeaderValue +} = __nccwpck_require__(2538) +const { webidl } = __nccwpck_require__(1744) +const assert = __nccwpck_require__(9491) - // 2. Otherwise, return a network error. +const kHeadersMap = Symbol('headers map') +const kHeadersSortedMap = Symbol('headers map sorted') - // To transmit request’s body body, run these steps: - let requestBody = null - // 1. If body is null and fetchParams’s process request end-of-body is - // non-null, then queue a fetch task given fetchParams’s process request - // end-of-body and fetchParams’s task destination. - if (request.body == null && fetchParams.processRequestEndOfBody) { - queueMicrotask(() => fetchParams.processRequestEndOfBody()) - } else if (request.body != null) { - // 2. Otherwise, if body is non-null: +/** + * @param {number} code + */ +function isHTTPWhiteSpaceCharCode (code) { + return code === 0x00a || code === 0x00d || code === 0x009 || code === 0x020 +} - // 1. Let processBodyChunk given bytes be these steps: - const processBodyChunk = async function * (bytes) { - // 1. If the ongoing fetch is terminated, then abort these steps. - if (isCancelled(fetchParams)) { - return - } +/** + * @see https://fetch.spec.whatwg.org/#concept-header-value-normalize + * @param {string} potentialValue + */ +function headerValueNormalize (potentialValue) { + // To normalize a byte sequence potentialValue, remove + // any leading and trailing HTTP whitespace bytes from + // potentialValue. + let i = 0; let j = potentialValue.length - // 2. Run this step in parallel: transmit bytes. - yield bytes + while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(j - 1))) --j + while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(i))) ++i - // 3. If fetchParams’s process request body is non-null, then run - // fetchParams’s process request body given bytes’s length. - fetchParams.processRequestBodyChunkLength?.(bytes.byteLength) - } + return i === 0 && j === potentialValue.length ? potentialValue : potentialValue.substring(i, j) +} - // 2. Let processEndOfBody be these steps: - const processEndOfBody = () => { - // 1. If fetchParams is canceled, then abort these steps. - if (isCancelled(fetchParams)) { - return - } +function fill (headers, object) { + // To fill a Headers object headers with a given object object, run these steps: - // 2. If fetchParams’s process request end-of-body is non-null, - // then run fetchParams’s process request end-of-body. - if (fetchParams.processRequestEndOfBody) { - fetchParams.processRequestEndOfBody() + // 1. If object is a sequence, then for each header in object: + // Note: webidl conversion to array has already been done. + if (Array.isArray(object)) { + for (let i = 0; i < object.length; ++i) { + const header = object[i] + // 1. If header does not contain exactly two items, then throw a TypeError. + if (header.length !== 2) { + throw webidl.errors.exception({ + header: 'Headers constructor', + message: `expected name/value pair to be length 2, found ${header.length}.` + }) } - } - // 3. Let processBodyError given e be these steps: - const processBodyError = (e) => { - // 1. If fetchParams is canceled, then abort these steps. - if (isCancelled(fetchParams)) { - return - } + // 2. Append (header’s first item, header’s second item) to headers. + appendHeader(headers, header[0], header[1]) + } + } else if (typeof object === 'object' && object !== null) { + // Note: null should throw - // 2. If e is an "AbortError" DOMException, then abort fetchParams’s controller. - if (e.name === 'AbortError') { - fetchParams.controller.abort() - } else { - fetchParams.controller.terminate(e) - } + // 2. Otherwise, object is a record, then for each key → value in object, + // append (key, value) to headers + const keys = Object.keys(object) + for (let i = 0; i < keys.length; ++i) { + appendHeader(headers, keys[i], object[keys[i]]) } + } else { + throw webidl.errors.conversionFailed({ + prefix: 'Headers constructor', + argument: 'Argument 1', + types: ['sequence>', 'record'] + }) + } +} - // 4. Incrementally read request’s body given processBodyChunk, processEndOfBody, - // processBodyError, and fetchParams’s task destination. - requestBody = (async function * () { - try { - for await (const bytes of request.body.stream) { - yield * processBodyChunk(bytes) - } - processEndOfBody() - } catch (err) { - processBodyError(err) - } - })() +/** + * @see https://fetch.spec.whatwg.org/#concept-headers-append + */ +function appendHeader (headers, name, value) { + // 1. Normalize value. + value = headerValueNormalize(value) + + // 2. If name is not a header name or value is not a + // header value, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.append', + value: name, + type: 'header name' + }) + } else if (!isValidHeaderValue(value)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.append', + value, + type: 'header value' + }) } - try { - // socket is only provided for websockets - const { body, status, statusText, headersList, socket } = await dispatch({ body: requestBody }) + // 3. If headers’s guard is "immutable", then throw a TypeError. + // 4. Otherwise, if headers’s guard is "request" and name is a + // forbidden header name, return. + // Note: undici does not implement forbidden header names + if (headers[kGuard] === 'immutable') { + throw new TypeError('immutable') + } else if (headers[kGuard] === 'request-no-cors') { + // 5. Otherwise, if headers’s guard is "request-no-cors": + // TODO + } - if (socket) { - response = makeResponse({ status, statusText, headersList, socket }) - } else { - const iterator = body[Symbol.asyncIterator]() - fetchParams.controller.next = () => iterator.next() + // 6. Otherwise, if headers’s guard is "response" and name is a + // forbidden response-header name, return. - response = makeResponse({ status, statusText, headersList }) - } - } catch (err) { - // 10. If aborted, then: - if (err.name === 'AbortError') { - // 1. If connection uses HTTP/2, then transmit an RST_STREAM frame. - fetchParams.controller.connection.destroy() + // 7. Append (name, value) to headers’s header list. + return headers[kHeadersList].append(name, value) - // 2. Return the appropriate network error for fetchParams. - return makeAppropriateNetworkError(fetchParams, err) - } + // 8. If headers’s guard is "request-no-cors", then remove + // privileged no-CORS request headers from headers +} - return makeNetworkError(err) - } +class HeadersList { + /** @type {[string, string][]|null} */ + cookies = null - // 11. Let pullAlgorithm be an action that resumes the ongoing fetch - // if it is suspended. - const pullAlgorithm = () => { - fetchParams.controller.resume() + constructor (init) { + if (init instanceof HeadersList) { + this[kHeadersMap] = new Map(init[kHeadersMap]) + this[kHeadersSortedMap] = init[kHeadersSortedMap] + this.cookies = init.cookies === null ? null : [...init.cookies] + } else { + this[kHeadersMap] = new Map(init) + this[kHeadersSortedMap] = null + } } - // 12. Let cancelAlgorithm be an algorithm that aborts fetchParams’s - // controller with reason, given reason. - const cancelAlgorithm = (reason) => { - fetchParams.controller.abort(reason) + // https://fetch.spec.whatwg.org/#header-list-contains + contains (name) { + // A header list list contains a header name name if list + // contains a header whose name is a byte-case-insensitive + // match for name. + name = name.toLowerCase() + + return this[kHeadersMap].has(name) } - // 13. Let highWaterMark be a non-negative, non-NaN number, chosen by - // the user agent. - // TODO + clear () { + this[kHeadersMap].clear() + this[kHeadersSortedMap] = null + this.cookies = null + } - // 14. Let sizeAlgorithm be an algorithm that accepts a chunk object - // and returns a non-negative, non-NaN, non-infinite number, chosen by the user agent. - // TODO + // https://fetch.spec.whatwg.org/#concept-header-list-append + append (name, value) { + this[kHeadersSortedMap] = null - // 15. Let stream be a new ReadableStream. - // 16. Set up stream with pullAlgorithm set to pullAlgorithm, - // cancelAlgorithm set to cancelAlgorithm, highWaterMark set to - // highWaterMark, and sizeAlgorithm set to sizeAlgorithm. - if (!ReadableStream) { - ReadableStream = (__nccwpck_require__(5356).ReadableStream) - } + // 1. If list contains name, then set name to the first such + // header’s name. + const lowercaseName = name.toLowerCase() + const exists = this[kHeadersMap].get(lowercaseName) - const stream = new ReadableStream( - { - async start (controller) { - fetchParams.controller.controller = controller - }, - async pull (controller) { - await pullAlgorithm(controller) - }, - async cancel (reason) { - await cancelAlgorithm(reason) - } - }, - { - highWaterMark: 0, - size () { - return 1 - } + // 2. Append (name, value) to list. + if (exists) { + const delimiter = lowercaseName === 'cookie' ? '; ' : ', ' + this[kHeadersMap].set(lowercaseName, { + name: exists.name, + value: `${exists.value}${delimiter}${value}` + }) + } else { + this[kHeadersMap].set(lowercaseName, { name, value }) } - ) - - // 17. Run these steps, but abort when the ongoing fetch is terminated: - // 1. Set response’s body to a new body whose stream is stream. - response.body = { stream } + if (lowercaseName === 'set-cookie') { + this.cookies ??= [] + this.cookies.push(value) + } + } - // 2. If response is not a network error and request’s cache mode is - // not "no-store", then update response in httpCache for request. - // TODO + // https://fetch.spec.whatwg.org/#concept-header-list-set + set (name, value) { + this[kHeadersSortedMap] = null + const lowercaseName = name.toLowerCase() - // 3. If includeCredentials is true and the user agent is not configured - // to block cookies for request (see section 7 of [COOKIES]), then run the - // "set-cookie-string" parsing algorithm (see section 5.2 of [COOKIES]) on - // the value of each header whose name is a byte-case-insensitive match for - // `Set-Cookie` in response’s header list, if any, and request’s current URL. - // TODO + if (lowercaseName === 'set-cookie') { + this.cookies = [value] + } - // 18. If aborted, then: - // TODO + // 1. If list contains name, then set the value of + // the first such header to value and remove the + // others. + // 2. Otherwise, append header (name, value) to list. + this[kHeadersMap].set(lowercaseName, { name, value }) + } - // 19. Run these steps in parallel: + // https://fetch.spec.whatwg.org/#concept-header-list-delete + delete (name) { + this[kHeadersSortedMap] = null - // 1. Run these steps, but abort when fetchParams is canceled: - fetchParams.controller.on('terminated', onAborted) - fetchParams.controller.resume = async () => { - // 1. While true - while (true) { - // 1-3. See onData... + name = name.toLowerCase() - // 4. Set bytes to the result of handling content codings given - // codings and bytes. - let bytes - let isFailure - try { - const { done, value } = await fetchParams.controller.next() + if (name === 'set-cookie') { + this.cookies = null + } - if (isAborted(fetchParams)) { - break - } + this[kHeadersMap].delete(name) + } - bytes = done ? undefined : value - } catch (err) { - if (fetchParams.controller.ended && !timingInfo.encodedBodySize) { - // zlib doesn't like empty streams. - bytes = undefined - } else { - bytes = err + // https://fetch.spec.whatwg.org/#concept-header-list-get + get (name) { + const value = this[kHeadersMap].get(name.toLowerCase()) - // err may be propagated from the result of calling readablestream.cancel, - // which might not be an error. https://github.com/nodejs/undici/issues/2009 - isFailure = true - } - } + // 1. If list does not contain name, then return null. + // 2. Return the values of all headers in list whose name + // is a byte-case-insensitive match for name, + // separated from each other by 0x2C 0x20, in order. + return value === undefined ? null : value.value + } - if (bytes === undefined) { - // 2. Otherwise, if the bytes transmission for response’s message - // body is done normally and stream is readable, then close - // stream, finalize response for fetchParams and response, and - // abort these in-parallel steps. - readableStreamClose(fetchParams.controller.controller) + * [Symbol.iterator] () { + // use the lowercased name + for (const [name, { value }] of this[kHeadersMap]) { + yield [name, value] + } + } - finalizeResponse(fetchParams, response) + get entries () { + const headers = {} - return + if (this[kHeadersMap].size) { + for (const { name, value } of this[kHeadersMap].values()) { + headers[name] = value } + } - // 5. Increase timingInfo’s decoded body size by bytes’s length. - timingInfo.decodedBodySize += bytes?.byteLength ?? 0 + return headers + } +} - // 6. If bytes is failure, then terminate fetchParams’s controller. - if (isFailure) { - fetchParams.controller.terminate(bytes) - return - } +// https://fetch.spec.whatwg.org/#headers-class +class Headers { + constructor (init = undefined) { + if (init === kConstruct) { + return + } + this[kHeadersList] = new HeadersList() - // 7. Enqueue a Uint8Array wrapping an ArrayBuffer containing bytes - // into stream. - fetchParams.controller.controller.enqueue(new Uint8Array(bytes)) + // The new Headers(init) constructor steps are: - // 8. If stream is errored, then terminate the ongoing fetch. - if (isErrored(stream)) { - fetchParams.controller.terminate() - return - } + // 1. Set this’s guard to "none". + this[kGuard] = 'none' - // 9. If stream doesn’t need more data ask the user agent to suspend - // the ongoing fetch. - if (!fetchParams.controller.controller.desiredSize) { - return - } + // 2. If init is given, then fill this with init. + if (init !== undefined) { + init = webidl.converters.HeadersInit(init) + fill(this, init) } } - // 2. If aborted, then: - function onAborted (reason) { - // 2. If fetchParams is aborted, then: - if (isAborted(fetchParams)) { - // 1. Set response’s aborted flag. - response.aborted = true + // https://fetch.spec.whatwg.org/#dom-headers-append + append (name, value) { + webidl.brandCheck(this, Headers) - // 2. If stream is readable, then error stream with the result of - // deserialize a serialized abort reason given fetchParams’s - // controller’s serialized abort reason and an - // implementation-defined realm. - if (isReadable(stream)) { - fetchParams.controller.controller.error( - fetchParams.controller.serializedAbortReason - ) - } - } else { - // 3. Otherwise, if stream is readable, error stream with a TypeError. - if (isReadable(stream)) { - fetchParams.controller.controller.error(new TypeError('terminated', { - cause: isErrorLike(reason) ? reason : undefined - })) - } - } + webidl.argumentLengthCheck(arguments, 2, { header: 'Headers.append' }) - // 4. If connection uses HTTP/2, then transmit an RST_STREAM frame. - // 5. Otherwise, the user agent should close connection unless it would be bad for performance to do so. - fetchParams.controller.connection.destroy() + name = webidl.converters.ByteString(name) + value = webidl.converters.ByteString(value) + + return appendHeader(this, name, value) } - // 20. Return response. - return response + // https://fetch.spec.whatwg.org/#dom-headers-delete + delete (name) { + webidl.brandCheck(this, Headers) - async function dispatch ({ body }) { - const url = requestCurrentURL(request) - /** @type {import('../..').Agent} */ - const agent = fetchParams.controller.dispatcher + webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.delete' }) - return new Promise((resolve, reject) => agent.dispatch( - { - path: url.pathname + url.search, - origin: url.origin, - method: request.method, - body: fetchParams.controller.dispatcher.isMockActive ? request.body && (request.body.source || request.body.stream) : body, - headers: request.headersList.entries, - maxRedirections: 0, - upgrade: request.mode === 'websocket' ? 'websocket' : undefined - }, - { - body: null, - abort: null, + name = webidl.converters.ByteString(name) - onConnect (abort) { - // TODO (fix): Do we need connection here? - const { connection } = fetchParams.controller + // 1. If name is not a header name, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.delete', + value: name, + type: 'header name' + }) + } - if (connection.destroyed) { - abort(new DOMException('The operation was aborted.', 'AbortError')) - } else { - fetchParams.controller.on('terminated', abort) - this.abort = connection.abort = abort - } - }, - - onHeaders (status, headersList, resume, statusText) { - if (status < 200) { - return - } - - let codings = [] - let location = '' + // 2. If this’s guard is "immutable", then throw a TypeError. + // 3. Otherwise, if this’s guard is "request" and name is a + // forbidden header name, return. + // 4. Otherwise, if this’s guard is "request-no-cors", name + // is not a no-CORS-safelisted request-header name, and + // name is not a privileged no-CORS request-header name, + // return. + // 5. Otherwise, if this’s guard is "response" and name is + // a forbidden response-header name, return. + // Note: undici does not implement forbidden header names + if (this[kGuard] === 'immutable') { + throw new TypeError('immutable') + } else if (this[kGuard] === 'request-no-cors') { + // TODO + } - const headers = new Headers() + // 6. If this’s header list does not contain name, then + // return. + if (!this[kHeadersList].contains(name)) { + return + } - // For H2, the headers are a plain JS object - // We distinguish between them and iterate accordingly - if (Array.isArray(headersList)) { - for (let n = 0; n < headersList.length; n += 2) { - const key = headersList[n + 0].toString('latin1') - const val = headersList[n + 1].toString('latin1') - if (key.toLowerCase() === 'content-encoding') { - // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 - // "All content-coding values are case-insensitive..." - codings = val.toLowerCase().split(',').map((x) => x.trim()) - } else if (key.toLowerCase() === 'location') { - location = val - } + // 7. Delete name from this’s header list. + // 8. If this’s guard is "request-no-cors", then remove + // privileged no-CORS request headers from this. + this[kHeadersList].delete(name) + } - headers[kHeadersList].append(key, val) - } - } else { - const keys = Object.keys(headersList) - for (const key of keys) { - const val = headersList[key] - if (key.toLowerCase() === 'content-encoding') { - // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 - // "All content-coding values are case-insensitive..." - codings = val.toLowerCase().split(',').map((x) => x.trim()).reverse() - } else if (key.toLowerCase() === 'location') { - location = val - } + // https://fetch.spec.whatwg.org/#dom-headers-get + get (name) { + webidl.brandCheck(this, Headers) - headers[kHeadersList].append(key, val) - } - } + webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.get' }) - this.body = new Readable({ read: resume }) + name = webidl.converters.ByteString(name) - const decoders = [] + // 1. If name is not a header name, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.get', + value: name, + type: 'header name' + }) + } - const willFollow = request.redirect === 'follow' && - location && - redirectStatusSet.has(status) + // 2. Return the result of getting name from this’s header + // list. + return this[kHeadersList].get(name) + } - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding - if (request.method !== 'HEAD' && request.method !== 'CONNECT' && !nullBodyStatus.includes(status) && !willFollow) { - for (const coding of codings) { - // https://www.rfc-editor.org/rfc/rfc9112.html#section-7.2 - if (coding === 'x-gzip' || coding === 'gzip') { - decoders.push(zlib.createGunzip({ - // Be less strict when decoding compressed responses, since sometimes - // servers send slightly invalid responses that are still accepted - // by common browsers. - // Always using Z_SYNC_FLUSH is what cURL does. - flush: zlib.constants.Z_SYNC_FLUSH, - finishFlush: zlib.constants.Z_SYNC_FLUSH - })) - } else if (coding === 'deflate') { - decoders.push(zlib.createInflate()) - } else if (coding === 'br') { - decoders.push(zlib.createBrotliDecompress()) - } else { - decoders.length = 0 - break - } - } - } + // https://fetch.spec.whatwg.org/#dom-headers-has + has (name) { + webidl.brandCheck(this, Headers) - resolve({ - status, - statusText, - headersList: headers[kHeadersList], - body: decoders.length - ? pipeline(this.body, ...decoders, () => { }) - : this.body.on('error', () => {}) - }) + webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.has' }) - return true - }, + name = webidl.converters.ByteString(name) - onData (chunk) { - if (fetchParams.controller.dump) { - return - } + // 1. If name is not a header name, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.has', + value: name, + type: 'header name' + }) + } - // 1. If one or more bytes have been transmitted from response’s - // message body, then: + // 2. Return true if this’s header list contains name; + // otherwise false. + return this[kHeadersList].contains(name) + } - // 1. Let bytes be the transmitted bytes. - const bytes = chunk + // https://fetch.spec.whatwg.org/#dom-headers-set + set (name, value) { + webidl.brandCheck(this, Headers) - // 2. Let codings be the result of extracting header list values - // given `Content-Encoding` and response’s header list. - // See pullAlgorithm. + webidl.argumentLengthCheck(arguments, 2, { header: 'Headers.set' }) - // 3. Increase timingInfo’s encoded body size by bytes’s length. - timingInfo.encodedBodySize += bytes.byteLength + name = webidl.converters.ByteString(name) + value = webidl.converters.ByteString(value) - // 4. See pullAlgorithm... + // 1. Normalize value. + value = headerValueNormalize(value) - return this.body.push(bytes) - }, + // 2. If name is not a header name or value is not a + // header value, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.set', + value: name, + type: 'header name' + }) + } else if (!isValidHeaderValue(value)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.set', + value, + type: 'header value' + }) + } - onComplete () { - if (this.abort) { - fetchParams.controller.off('terminated', this.abort) - } + // 3. If this’s guard is "immutable", then throw a TypeError. + // 4. Otherwise, if this’s guard is "request" and name is a + // forbidden header name, return. + // 5. Otherwise, if this’s guard is "request-no-cors" and + // name/value is not a no-CORS-safelisted request-header, + // return. + // 6. Otherwise, if this’s guard is "response" and name is a + // forbidden response-header name, return. + // Note: undici does not implement forbidden header names + if (this[kGuard] === 'immutable') { + throw new TypeError('immutable') + } else if (this[kGuard] === 'request-no-cors') { + // TODO + } - fetchParams.controller.ended = true + // 7. Set (name, value) in this’s header list. + // 8. If this’s guard is "request-no-cors", then remove + // privileged no-CORS request headers from this + this[kHeadersList].set(name, value) + } - this.body.push(null) - }, + // https://fetch.spec.whatwg.org/#dom-headers-getsetcookie + getSetCookie () { + webidl.brandCheck(this, Headers) - onError (error) { - if (this.abort) { - fetchParams.controller.off('terminated', this.abort) - } + // 1. If this’s header list does not contain `Set-Cookie`, then return « ». + // 2. Return the values of all headers in this’s header list whose name is + // a byte-case-insensitive match for `Set-Cookie`, in order. - this.body?.destroy(error) + const list = this[kHeadersList].cookies - fetchParams.controller.terminate(error) + if (list) { + return [...list] + } - reject(error) - }, + return [] + } - onUpgrade (status, headersList, socket) { - if (status !== 101) { - return - } + // https://fetch.spec.whatwg.org/#concept-header-list-sort-and-combine + get [kHeadersSortedMap] () { + if (this[kHeadersList][kHeadersSortedMap]) { + return this[kHeadersList][kHeadersSortedMap] + } - const headers = new Headers() + // 1. Let headers be an empty list of headers with the key being the name + // and value the value. + const headers = [] - for (let n = 0; n < headersList.length; n += 2) { - const key = headersList[n + 0].toString('latin1') - const val = headersList[n + 1].toString('latin1') + // 2. Let names be the result of convert header names to a sorted-lowercase + // set with all the names of the headers in list. + const names = [...this[kHeadersList]].sort((a, b) => a[0] < b[0] ? -1 : 1) + const cookies = this[kHeadersList].cookies - headers[kHeadersList].append(key, val) - } + // 3. For each name of names: + for (let i = 0; i < names.length; ++i) { + const [name, value] = names[i] + // 1. If name is `set-cookie`, then: + if (name === 'set-cookie') { + // 1. Let values be a list of all values of headers in list whose name + // is a byte-case-insensitive match for name, in order. - resolve({ - status, - statusText: STATUS_CODES[status], - headersList: headers[kHeadersList], - socket - }) - - return true + // 2. For each value of values: + // 1. Append (name, value) to headers. + for (let j = 0; j < cookies.length; ++j) { + headers.push([name, cookies[j]]) } - } - )) - } -} + } else { + // 2. Otherwise: -module.exports = { - fetch, - Fetch, - fetching, - finalizeAndReportTiming -} + // 1. Let value be the result of getting name from list. + // 2. Assert: value is non-null. + assert(value !== null) -/***/ }), + // 3. Append (name, value) to headers. + headers.push([name, value]) + } + } -/***/ 8359: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this[kHeadersList][kHeadersSortedMap] = headers -"use strict"; -/* globals AbortController */ + // 4. Return headers. + return headers + } + keys () { + webidl.brandCheck(this, Headers) + if (this[kGuard] === 'immutable') { + const value = this[kHeadersSortedMap] + return makeIterator(() => value, 'Headers', + 'key') + } -const { extractBody, mixinBody, cloneBody } = __nccwpck_require__(1472) -const { Headers, fill: fillHeaders, HeadersList } = __nccwpck_require__(554) -const { FinalizationRegistry } = __nccwpck_require__(6436)() -const util = __nccwpck_require__(3983) -const { - isValidHTTPToken, - sameOrigin, - normalizeMethod, - makePolicyContainer, - normalizeMethodRecord -} = __nccwpck_require__(2538) -const { - forbiddenMethodsSet, - corsSafeListedMethodsSet, - referrerPolicy, - requestRedirect, - requestMode, - requestCredentials, - requestCache, - requestDuplex -} = __nccwpck_require__(1037) -const { kEnumerableProperty } = util -const { kHeaders, kSignal, kState, kGuard, kRealm } = __nccwpck_require__(5861) -const { webidl } = __nccwpck_require__(1744) -const { getGlobalOrigin } = __nccwpck_require__(1246) -const { URLSerializer } = __nccwpck_require__(685) -const { kHeadersList, kConstruct } = __nccwpck_require__(2785) -const assert = __nccwpck_require__(9491) -const { getMaxListeners, setMaxListeners, getEventListeners, defaultMaxListeners } = __nccwpck_require__(2361) + return makeIterator( + () => [...this[kHeadersSortedMap].values()], + 'Headers', + 'key' + ) + } -let TransformStream = globalThis.TransformStream + values () { + webidl.brandCheck(this, Headers) -const kAbortController = Symbol('abortController') + if (this[kGuard] === 'immutable') { + const value = this[kHeadersSortedMap] + return makeIterator(() => value, 'Headers', + 'value') + } -const requestFinalizer = new FinalizationRegistry(({ signal, abort }) => { - signal.removeEventListener('abort', abort) -}) + return makeIterator( + () => [...this[kHeadersSortedMap].values()], + 'Headers', + 'value' + ) + } -// https://fetch.spec.whatwg.org/#request-class -class Request { - // https://fetch.spec.whatwg.org/#dom-request - constructor (input, init = {}) { - if (input === kConstruct) { - return + entries () { + webidl.brandCheck(this, Headers) + + if (this[kGuard] === 'immutable') { + const value = this[kHeadersSortedMap] + return makeIterator(() => value, 'Headers', + 'key+value') } - webidl.argumentLengthCheck(arguments, 1, { header: 'Request constructor' }) + return makeIterator( + () => [...this[kHeadersSortedMap].values()], + 'Headers', + 'key+value' + ) + } - input = webidl.converters.RequestInfo(input) - init = webidl.converters.RequestInit(init) + /** + * @param {(value: string, key: string, self: Headers) => void} callbackFn + * @param {unknown} thisArg + */ + forEach (callbackFn, thisArg = globalThis) { + webidl.brandCheck(this, Headers) - // https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object - this[kRealm] = { - settingsObject: { - baseUrl: getGlobalOrigin(), - get origin () { - return this.baseUrl?.origin - }, - policyContainer: makePolicyContainer() - } - } + webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.forEach' }) - // 1. Let request be null. - let request = null + if (typeof callbackFn !== 'function') { + throw new TypeError( + "Failed to execute 'forEach' on 'Headers': parameter 1 is not of type 'Function'." + ) + } - // 2. Let fallbackMode be null. - let fallbackMode = null + for (const [key, value] of this) { + callbackFn.apply(thisArg, [value, key, this]) + } + } - // 3. Let baseURL be this’s relevant settings object’s API base URL. - const baseUrl = this[kRealm].settingsObject.baseUrl + [Symbol.for('nodejs.util.inspect.custom')] () { + webidl.brandCheck(this, Headers) - // 4. Let signal be null. - let signal = null + return this[kHeadersList] + } +} - // 5. If input is a string, then: - if (typeof input === 'string') { - // 1. Let parsedURL be the result of parsing input with baseURL. - // 2. If parsedURL is failure, then throw a TypeError. - let parsedURL - try { - parsedURL = new URL(input, baseUrl) - } catch (err) { - throw new TypeError('Failed to parse URL from ' + input, { cause: err }) - } +Headers.prototype[Symbol.iterator] = Headers.prototype.entries - // 3. If parsedURL includes credentials, then throw a TypeError. - if (parsedURL.username || parsedURL.password) { - throw new TypeError( - 'Request cannot be constructed from a URL that includes credentials: ' + - input - ) - } +Object.defineProperties(Headers.prototype, { + append: kEnumerableProperty, + delete: kEnumerableProperty, + get: kEnumerableProperty, + has: kEnumerableProperty, + set: kEnumerableProperty, + getSetCookie: kEnumerableProperty, + keys: kEnumerableProperty, + values: kEnumerableProperty, + entries: kEnumerableProperty, + forEach: kEnumerableProperty, + [Symbol.iterator]: { enumerable: false }, + [Symbol.toStringTag]: { + value: 'Headers', + configurable: true + } +}) - // 4. Set request to a new request whose URL is parsedURL. - request = makeRequest({ urlList: [parsedURL] }) +webidl.converters.HeadersInit = function (V) { + if (webidl.util.Type(V) === 'Object') { + if (V[Symbol.iterator]) { + return webidl.converters['sequence>'](V) + } - // 5. Set fallbackMode to "cors". - fallbackMode = 'cors' - } else { - // 6. Otherwise: + return webidl.converters['record'](V) + } - // 7. Assert: input is a Request object. - assert(input instanceof Request) + throw webidl.errors.conversionFailed({ + prefix: 'Headers constructor', + argument: 'Argument 1', + types: ['sequence>', 'record'] + }) +} - // 8. Set request to input’s request. - request = input[kState] +module.exports = { + fill, + Headers, + HeadersList +} - // 9. Set signal to input’s signal. - signal = input[kSignal] - } - // 7. Let origin be this’s relevant settings object’s origin. - const origin = this[kRealm].settingsObject.origin +/***/ }), - // 8. Let window be "client". - let window = 'client' +/***/ 4881: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // 9. If request’s window is an environment settings object and its origin - // is same origin with origin, then set window to request’s window. - if ( - request.window?.constructor?.name === 'EnvironmentSettingsObject' && - sameOrigin(request.window, origin) - ) { - window = request.window - } +"use strict"; +// https://github.com/Ethan-Arrowood/undici-fetch - // 10. If init["window"] exists and is non-null, then throw a TypeError. - if (init.window != null) { - throw new TypeError(`'window' option '${window}' must be null`) - } - // 11. If init["window"] exists, then set window to "no-window". - if ('window' in init) { - window = 'no-window' - } - // 12. Set request to a new request with the following properties: - request = makeRequest({ - // URL request’s URL. - // undici implementation note: this is set as the first item in request's urlList in makeRequest - // method request’s method. - method: request.method, - // header list A copy of request’s header list. - // undici implementation note: headersList is cloned in makeRequest - headersList: request.headersList, - // unsafe-request flag Set. - unsafeRequest: request.unsafeRequest, - // client This’s relevant settings object. - client: this[kRealm].settingsObject, - // window window. - window, - // priority request’s priority. - priority: request.priority, - // origin request’s origin. The propagation of the origin is only significant for navigation requests - // being handled by a service worker. In this scenario a request can have an origin that is different - // from the current client. - origin: request.origin, - // referrer request’s referrer. - referrer: request.referrer, - // referrer policy request’s referrer policy. - referrerPolicy: request.referrerPolicy, - // mode request’s mode. - mode: request.mode, - // credentials mode request’s credentials mode. - credentials: request.credentials, - // cache mode request’s cache mode. - cache: request.cache, - // redirect mode request’s redirect mode. - redirect: request.redirect, - // integrity metadata request’s integrity metadata. - integrity: request.integrity, - // keepalive request’s keepalive. - keepalive: request.keepalive, - // reload-navigation flag request’s reload-navigation flag. - reloadNavigation: request.reloadNavigation, - // history-navigation flag request’s history-navigation flag. - historyNavigation: request.historyNavigation, - // URL list A clone of request’s URL list. - urlList: [...request.urlList] - }) - - const initHasKey = Object.keys(init).length !== 0 +const { + Response, + makeNetworkError, + makeAppropriateNetworkError, + filterResponse, + makeResponse +} = __nccwpck_require__(7823) +const { Headers } = __nccwpck_require__(554) +const { Request, makeRequest } = __nccwpck_require__(8359) +const zlib = __nccwpck_require__(9796) +const { + bytesMatch, + makePolicyContainer, + clonePolicyContainer, + requestBadPort, + TAOCheck, + appendRequestOriginHeader, + responseLocationURL, + requestCurrentURL, + setRequestReferrerPolicyOnRedirect, + tryUpgradeRequestToAPotentiallyTrustworthyURL, + createOpaqueTimingInfo, + appendFetchMetadata, + corsCheck, + crossOriginResourcePolicyCheck, + determineRequestsReferrer, + coarsenedSharedCurrentTime, + createDeferredPromise, + isBlobLike, + sameOrigin, + isCancelled, + isAborted, + isErrorLike, + fullyReadBody, + readableStreamClose, + isomorphicEncode, + urlIsLocal, + urlIsHttpHttpsScheme, + urlHasHttpsScheme +} = __nccwpck_require__(2538) +const { kState, kHeaders, kGuard, kRealm } = __nccwpck_require__(5861) +const assert = __nccwpck_require__(9491) +const { safelyExtractBody } = __nccwpck_require__(1472) +const { + redirectStatusSet, + nullBodyStatus, + safeMethodsSet, + requestBodyHeader, + subresourceSet, + DOMException +} = __nccwpck_require__(1037) +const { kHeadersList } = __nccwpck_require__(2785) +const EE = __nccwpck_require__(2361) +const { Readable, pipeline } = __nccwpck_require__(2781) +const { addAbortListener, isErrored, isReadable, nodeMajor, nodeMinor } = __nccwpck_require__(3983) +const { dataURLProcessor, serializeAMimeType } = __nccwpck_require__(685) +const { TransformStream } = __nccwpck_require__(5356) +const { getGlobalDispatcher } = __nccwpck_require__(1892) +const { webidl } = __nccwpck_require__(1744) +const { STATUS_CODES } = __nccwpck_require__(3685) +const GET_OR_HEAD = ['GET', 'HEAD'] - // 13. If init is not empty, then: - if (initHasKey) { - // 1. If request’s mode is "navigate", then set it to "same-origin". - if (request.mode === 'navigate') { - request.mode = 'same-origin' - } +/** @type {import('buffer').resolveObjectURL} */ +let resolveObjectURL +let ReadableStream = globalThis.ReadableStream - // 2. Unset request’s reload-navigation flag. - request.reloadNavigation = false +class Fetch extends EE { + constructor (dispatcher) { + super() - // 3. Unset request’s history-navigation flag. - request.historyNavigation = false + this.dispatcher = dispatcher + this.connection = null + this.dump = false + this.state = 'ongoing' + // 2 terminated listeners get added per request, + // but only 1 gets removed. If there are 20 redirects, + // 21 listeners will be added. + // See https://github.com/nodejs/undici/issues/1711 + // TODO (fix): Find and fix root cause for leaked listener. + this.setMaxListeners(21) + } - // 4. Set request’s origin to "client". - request.origin = 'client' + terminate (reason) { + if (this.state !== 'ongoing') { + return + } - // 5. Set request’s referrer to "client" - request.referrer = 'client' + this.state = 'terminated' + this.connection?.destroy(reason) + this.emit('terminated', reason) + } - // 6. Set request’s referrer policy to the empty string. - request.referrerPolicy = '' + // https://fetch.spec.whatwg.org/#fetch-controller-abort + abort (error) { + if (this.state !== 'ongoing') { + return + } - // 7. Set request’s URL to request’s current URL. - request.url = request.urlList[request.urlList.length - 1] + // 1. Set controller’s state to "aborted". + this.state = 'aborted' - // 8. Set request’s URL list to « request’s URL ». - request.urlList = [request.url] + // 2. Let fallbackError be an "AbortError" DOMException. + // 3. Set error to fallbackError if it is not given. + if (!error) { + error = new DOMException('The operation was aborted.', 'AbortError') } - // 14. If init["referrer"] exists, then: - if (init.referrer !== undefined) { - // 1. Let referrer be init["referrer"]. - const referrer = init.referrer + // 4. Let serializedError be StructuredSerialize(error). + // If that threw an exception, catch it, and let + // serializedError be StructuredSerialize(fallbackError). - // 2. If referrer is the empty string, then set request’s referrer to "no-referrer". - if (referrer === '') { - request.referrer = 'no-referrer' - } else { - // 1. Let parsedReferrer be the result of parsing referrer with - // baseURL. - // 2. If parsedReferrer is failure, then throw a TypeError. - let parsedReferrer - try { - parsedReferrer = new URL(referrer, baseUrl) - } catch (err) { - throw new TypeError(`Referrer "${referrer}" is not a valid URL.`, { cause: err }) - } + // 5. Set controller’s serialized abort reason to serializedError. + this.serializedAbortReason = error - // 3. If one of the following is true - // - parsedReferrer’s scheme is "about" and path is the string "client" - // - parsedReferrer’s origin is not same origin with origin - // then set request’s referrer to "client". - if ( - (parsedReferrer.protocol === 'about:' && parsedReferrer.hostname === 'client') || - (origin && !sameOrigin(parsedReferrer, this[kRealm].settingsObject.baseUrl)) - ) { - request.referrer = 'client' - } else { - // 4. Otherwise, set request’s referrer to parsedReferrer. - request.referrer = parsedReferrer - } - } - } + this.connection?.destroy(error) + this.emit('terminated', error) + } +} - // 15. If init["referrerPolicy"] exists, then set request’s referrer policy - // to it. - if (init.referrerPolicy !== undefined) { - request.referrerPolicy = init.referrerPolicy - } +// https://fetch.spec.whatwg.org/#fetch-method +function fetch (input, init = {}) { + webidl.argumentLengthCheck(arguments, 1, { header: 'globalThis.fetch' }) - // 16. Let mode be init["mode"] if it exists, and fallbackMode otherwise. - let mode - if (init.mode !== undefined) { - mode = init.mode - } else { - mode = fallbackMode - } + // 1. Let p be a new promise. + const p = createDeferredPromise() - // 17. If mode is "navigate", then throw a TypeError. - if (mode === 'navigate') { - throw webidl.errors.exception({ - header: 'Request constructor', - message: 'invalid request mode navigate.' - }) - } + // 2. Let requestObject be the result of invoking the initial value of + // Request as constructor with input and init as arguments. If this throws + // an exception, reject p with it and return p. + let requestObject - // 18. If mode is non-null, set request’s mode to mode. - if (mode != null) { - request.mode = mode - } + try { + requestObject = new Request(input, init) + } catch (e) { + p.reject(e) + return p.promise + } - // 19. If init["credentials"] exists, then set request’s credentials mode - // to it. - if (init.credentials !== undefined) { - request.credentials = init.credentials - } + // 3. Let request be requestObject’s request. + const request = requestObject[kState] - // 18. If init["cache"] exists, then set request’s cache mode to it. - if (init.cache !== undefined) { - request.cache = init.cache - } + // 4. If requestObject’s signal’s aborted flag is set, then: + if (requestObject.signal.aborted) { + // 1. Abort the fetch() call with p, request, null, and + // requestObject’s signal’s abort reason. + abortFetch(p, request, null, requestObject.signal.reason) - // 21. If request’s cache mode is "only-if-cached" and request’s mode is - // not "same-origin", then throw a TypeError. - if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { - throw new TypeError( - "'only-if-cached' can be set only with 'same-origin' mode" - ) - } + // 2. Return p. + return p.promise + } - // 22. If init["redirect"] exists, then set request’s redirect mode to it. - if (init.redirect !== undefined) { - request.redirect = init.redirect - } + // 5. Let globalObject be request’s client’s global object. + const globalObject = request.client.globalObject - // 23. If init["integrity"] exists, then set request’s integrity metadata to it. - if (init.integrity != null) { - request.integrity = String(init.integrity) - } + // 6. If globalObject is a ServiceWorkerGlobalScope object, then set + // request’s service-workers mode to "none". + if (globalObject?.constructor?.name === 'ServiceWorkerGlobalScope') { + request.serviceWorkers = 'none' + } - // 24. If init["keepalive"] exists, then set request’s keepalive to it. - if (init.keepalive !== undefined) { - request.keepalive = Boolean(init.keepalive) - } + // 7. Let responseObject be null. + let responseObject = null - // 25. If init["method"] exists, then: - if (init.method !== undefined) { - // 1. Let method be init["method"]. - let method = init.method + // 8. Let relevantRealm be this’s relevant Realm. + const relevantRealm = null - // 2. If method is not a method or method is a forbidden method, then - // throw a TypeError. - if (!isValidHTTPToken(method)) { - throw new TypeError(`'${method}' is not a valid HTTP method.`) - } + // 9. Let locallyAborted be false. + let locallyAborted = false - if (forbiddenMethodsSet.has(method.toUpperCase())) { - throw new TypeError(`'${method}' HTTP method is unsupported.`) - } + // 10. Let controller be null. + let controller = null - // 3. Normalize method. - method = normalizeMethodRecord[method] ?? normalizeMethod(method) + // 11. Add the following abort steps to requestObject’s signal: + addAbortListener( + requestObject.signal, + () => { + // 1. Set locallyAborted to true. + locallyAborted = true - // 4. Set request’s method to method. - request.method = method - } + // 2. Assert: controller is non-null. + assert(controller != null) - // 26. If init["signal"] exists, then set signal to it. - if (init.signal !== undefined) { - signal = init.signal + // 3. Abort controller with requestObject’s signal’s abort reason. + controller.abort(requestObject.signal.reason) + + // 4. Abort the fetch() call with p, request, responseObject, + // and requestObject’s signal’s abort reason. + abortFetch(p, request, responseObject, requestObject.signal.reason) } + ) - // 27. Set this’s request to request. - this[kState] = request + // 12. Let handleFetchDone given response response be to finalize and + // report timing with response, globalObject, and "fetch". + const handleFetchDone = (response) => + finalizeAndReportTiming(response, 'fetch') - // 28. Set this’s signal to a new AbortSignal object with this’s relevant - // Realm. - // TODO: could this be simplified with AbortSignal.any - // (https://dom.spec.whatwg.org/#dom-abortsignal-any) - const ac = new AbortController() - this[kSignal] = ac.signal - this[kSignal][kRealm] = this[kRealm] + // 13. Set controller to the result of calling fetch given request, + // with processResponseEndOfBody set to handleFetchDone, and processResponse + // given response being these substeps: - // 29. If signal is not null, then make this’s signal follow signal. - if (signal != null) { - if ( - !signal || - typeof signal.aborted !== 'boolean' || - typeof signal.addEventListener !== 'function' - ) { - throw new TypeError( - "Failed to construct 'Request': member signal is not of type AbortSignal." - ) - } + const processResponse = (response) => { + // 1. If locallyAborted is true, terminate these substeps. + if (locallyAborted) { + return Promise.resolve() + } - if (signal.aborted) { - ac.abort(signal.reason) - } else { - // Keep a strong ref to ac while request object - // is alive. This is needed to prevent AbortController - // from being prematurely garbage collected. - // See, https://github.com/nodejs/undici/issues/1926. - this[kAbortController] = ac + // 2. If response’s aborted flag is set, then: + if (response.aborted) { + // 1. Let deserializedError be the result of deserialize a serialized + // abort reason given controller’s serialized abort reason and + // relevantRealm. - const acRef = new WeakRef(ac) - const abort = function () { - const ac = acRef.deref() - if (ac !== undefined) { - ac.abort(this.reason) - } - } + // 2. Abort the fetch() call with p, request, responseObject, and + // deserializedError. - // Third-party AbortControllers may not work with these. - // See, https://github.com/nodejs/undici/pull/1910#issuecomment-1464495619. - try { - // If the max amount of listeners is equal to the default, increase it - // This is only available in node >= v19.9.0 - if (typeof getMaxListeners === 'function' && getMaxListeners(signal) === defaultMaxListeners) { - setMaxListeners(100, signal) - } else if (getEventListeners(signal, 'abort').length >= defaultMaxListeners) { - setMaxListeners(100, signal) - } - } catch {} + abortFetch(p, request, responseObject, controller.serializedAbortReason) + return Promise.resolve() + } - util.addAbortListener(signal, abort) - requestFinalizer.register(ac, { signal, abort }) - } + // 3. If response is a network error, then reject p with a TypeError + // and terminate these substeps. + if (response.type === 'error') { + p.reject( + Object.assign(new TypeError('fetch failed'), { cause: response.error }) + ) + return Promise.resolve() } - // 30. Set this’s headers to a new Headers object with this’s relevant - // Realm, whose header list is request’s header list and guard is - // "request". - this[kHeaders] = new Headers(kConstruct) - this[kHeaders][kHeadersList] = request.headersList - this[kHeaders][kGuard] = 'request' - this[kHeaders][kRealm] = this[kRealm] + // 4. Set responseObject to the result of creating a Response object, + // given response, "immutable", and relevantRealm. + responseObject = new Response() + responseObject[kState] = response + responseObject[kRealm] = relevantRealm + responseObject[kHeaders][kHeadersList] = response.headersList + responseObject[kHeaders][kGuard] = 'immutable' + responseObject[kHeaders][kRealm] = relevantRealm - // 31. If this’s request’s mode is "no-cors", then: - if (mode === 'no-cors') { - // 1. If this’s request’s method is not a CORS-safelisted method, - // then throw a TypeError. - if (!corsSafeListedMethodsSet.has(request.method)) { - throw new TypeError( - `'${request.method} is unsupported in no-cors mode.` - ) - } + // 5. Resolve p with responseObject. + p.resolve(responseObject) + } - // 2. Set this’s headers’s guard to "request-no-cors". - this[kHeaders][kGuard] = 'request-no-cors' - } + controller = fetching({ + request, + processResponseEndOfBody: handleFetchDone, + processResponse, + dispatcher: init.dispatcher ?? getGlobalDispatcher() // undici + }) - // 32. If init is not empty, then: - if (initHasKey) { - /** @type {HeadersList} */ - const headersList = this[kHeaders][kHeadersList] - // 1. Let headers be a copy of this’s headers and its associated header - // list. - // 2. If init["headers"] exists, then set headers to init["headers"]. - const headers = init.headers !== undefined ? init.headers : new HeadersList(headersList) + // 14. Return p. + return p.promise +} - // 3. Empty this’s headers’s header list. - headersList.clear() +// https://fetch.spec.whatwg.org/#finalize-and-report-timing +function finalizeAndReportTiming (response, initiatorType = 'other') { + // 1. If response is an aborted network error, then return. + if (response.type === 'error' && response.aborted) { + return + } - // 4. If headers is a Headers object, then for each header in its header - // list, append header’s name/header’s value to this’s headers. - if (headers instanceof HeadersList) { - for (const [key, val] of headers) { - headersList.append(key, val) - } - // Note: Copy the `set-cookie` meta-data. - headersList.cookies = headers.cookies - } else { - // 5. Otherwise, fill this’s headers with headers. - fillHeaders(this[kHeaders], headers) - } - } + // 2. If response’s URL list is null or empty, then return. + if (!response.urlList?.length) { + return + } - // 33. Let inputBody be input’s request’s body if input is a Request - // object; otherwise null. - const inputBody = input instanceof Request ? input[kState].body : null + // 3. Let originalURL be response’s URL list[0]. + const originalURL = response.urlList[0] - // 34. If either init["body"] exists and is non-null or inputBody is - // non-null, and request’s method is `GET` or `HEAD`, then throw a - // TypeError. - if ( - (init.body != null || inputBody != null) && - (request.method === 'GET' || request.method === 'HEAD') - ) { - throw new TypeError('Request with GET/HEAD method cannot have body.') - } + // 4. Let timingInfo be response’s timing info. + let timingInfo = response.timingInfo - // 35. Let initBody be null. - let initBody = null + // 5. Let cacheState be response’s cache state. + let cacheState = response.cacheState - // 36. If init["body"] exists and is non-null, then: - if (init.body != null) { - // 1. Let Content-Type be null. - // 2. Set initBody and Content-Type to the result of extracting - // init["body"], with keepalive set to request’s keepalive. - const [extractedBody, contentType] = extractBody( - init.body, - request.keepalive - ) - initBody = extractedBody + // 6. If originalURL’s scheme is not an HTTP(S) scheme, then return. + if (!urlIsHttpHttpsScheme(originalURL)) { + return + } - // 3, If Content-Type is non-null and this’s headers’s header list does - // not contain `Content-Type`, then append `Content-Type`/Content-Type to - // this’s headers. - if (contentType && !this[kHeaders][kHeadersList].contains('content-type')) { - this[kHeaders].append('content-type', contentType) - } - } + // 7. If timingInfo is null, then return. + if (timingInfo === null) { + return + } - // 37. Let inputOrInitBody be initBody if it is non-null; otherwise - // inputBody. - const inputOrInitBody = initBody ?? inputBody + // 8. If response’s timing allow passed flag is not set, then: + if (!response.timingAllowPassed) { + // 1. Set timingInfo to a the result of creating an opaque timing info for timingInfo. + timingInfo = createOpaqueTimingInfo({ + startTime: timingInfo.startTime + }) - // 38. If inputOrInitBody is non-null and inputOrInitBody’s source is - // null, then: - if (inputOrInitBody != null && inputOrInitBody.source == null) { - // 1. If initBody is non-null and init["duplex"] does not exist, - // then throw a TypeError. - if (initBody != null && init.duplex == null) { - throw new TypeError('RequestInit: duplex option is required when sending a body.') - } + // 2. Set cacheState to the empty string. + cacheState = '' + } - // 2. If this’s request’s mode is neither "same-origin" nor "cors", - // then throw a TypeError. - if (request.mode !== 'same-origin' && request.mode !== 'cors') { - throw new TypeError( - 'If request is made from ReadableStream, mode should be "same-origin" or "cors"' - ) - } + // 9. Set timingInfo’s end time to the coarsened shared current time + // given global’s relevant settings object’s cross-origin isolated + // capability. + // TODO: given global’s relevant settings object’s cross-origin isolated + // capability? + timingInfo.endTime = coarsenedSharedCurrentTime() - // 3. Set this’s request’s use-CORS-preflight flag. - request.useCORSPreflightFlag = true - } + // 10. Set response’s timing info to timingInfo. + response.timingInfo = timingInfo - // 39. Let finalBody be inputOrInitBody. - let finalBody = inputOrInitBody + // 11. Mark resource timing for timingInfo, originalURL, initiatorType, + // global, and cacheState. + markResourceTiming( + timingInfo, + originalURL, + initiatorType, + globalThis, + cacheState + ) +} - // 40. If initBody is null and inputBody is non-null, then: - if (initBody == null && inputBody != null) { - // 1. If input is unusable, then throw a TypeError. - if (util.isDisturbed(inputBody.stream) || inputBody.stream.locked) { - throw new TypeError( - 'Cannot construct a Request with a Request object that has already been used.' - ) - } +// https://w3c.github.io/resource-timing/#dfn-mark-resource-timing +function markResourceTiming (timingInfo, originalURL, initiatorType, globalThis, cacheState) { + if (nodeMajor > 18 || (nodeMajor === 18 && nodeMinor >= 2)) { + performance.markResourceTiming(timingInfo, originalURL.href, initiatorType, globalThis, cacheState) + } +} - // 2. Set finalBody to the result of creating a proxy for inputBody. - if (!TransformStream) { - TransformStream = (__nccwpck_require__(5356).TransformStream) - } +// https://fetch.spec.whatwg.org/#abort-fetch +function abortFetch (p, request, responseObject, error) { + // Note: AbortSignal.reason was added in node v17.2.0 + // which would give us an undefined error to reject with. + // Remove this once node v16 is no longer supported. + if (!error) { + error = new DOMException('The operation was aborted.', 'AbortError') + } - // https://streams.spec.whatwg.org/#readablestream-create-a-proxy - const identityTransform = new TransformStream() - inputBody.stream.pipeThrough(identityTransform) - finalBody = { - source: inputBody.source, - length: inputBody.length, - stream: identityTransform.readable - } - } + // 1. Reject promise with error. + p.reject(error) - // 41. Set this’s request’s body to finalBody. - this[kState].body = finalBody + // 2. If request’s body is not null and is readable, then cancel request’s + // body with error. + if (request.body != null && isReadable(request.body?.stream)) { + request.body.stream.cancel(error).catch((err) => { + if (err.code === 'ERR_INVALID_STATE') { + // Node bug? + return + } + throw err + }) } - // Returns request’s HTTP method, which is "GET" by default. - get method () { - webidl.brandCheck(this, Request) - - // The method getter steps are to return this’s request’s method. - return this[kState].method + // 3. If responseObject is null, then return. + if (responseObject == null) { + return } - // Returns the URL of request as a string. - get url () { - webidl.brandCheck(this, Request) + // 4. Let response be responseObject’s response. + const response = responseObject[kState] - // The url getter steps are to return this’s request’s URL, serialized. - return URLSerializer(this[kState].url) + // 5. If response’s body is not null and is readable, then error response’s + // body with error. + if (response.body != null && isReadable(response.body?.stream)) { + response.body.stream.cancel(error).catch((err) => { + if (err.code === 'ERR_INVALID_STATE') { + // Node bug? + return + } + throw err + }) } +} - // Returns a Headers object consisting of the headers associated with request. - // Note that headers added in the network layer by the user agent will not - // be accounted for in this object, e.g., the "Host" header. - get headers () { - webidl.brandCheck(this, Request) +// https://fetch.spec.whatwg.org/#fetching +function fetching ({ + request, + processRequestBodyChunkLength, + processRequestEndOfBody, + processResponse, + processResponseEndOfBody, + processResponseConsumeBody, + useParallelQueue = false, + dispatcher // undici +}) { + // 1. Let taskDestination be null. + let taskDestination = null - // The headers getter steps are to return this’s headers. - return this[kHeaders] - } + // 2. Let crossOriginIsolatedCapability be false. + let crossOriginIsolatedCapability = false - // Returns the kind of resource requested by request, e.g., "document" - // or "script". - get destination () { - webidl.brandCheck(this, Request) + // 3. If request’s client is non-null, then: + if (request.client != null) { + // 1. Set taskDestination to request’s client’s global object. + taskDestination = request.client.globalObject - // The destination getter are to return this’s request’s destination. - return this[kState].destination + // 2. Set crossOriginIsolatedCapability to request’s client’s cross-origin + // isolated capability. + crossOriginIsolatedCapability = + request.client.crossOriginIsolatedCapability } - // Returns the referrer of request. Its value can be a same-origin URL if - // explicitly set in init, the empty string to indicate no referrer, and - // "about:client" when defaulting to the global’s default. This is used - // during fetching to determine the value of the `Referer` header of the - // request being made. - get referrer () { - webidl.brandCheck(this, Request) - - // 1. If this’s request’s referrer is "no-referrer", then return the - // empty string. - if (this[kState].referrer === 'no-referrer') { - return '' - } + // 4. If useParallelQueue is true, then set taskDestination to the result of + // starting a new parallel queue. + // TODO - // 2. If this’s request’s referrer is "client", then return - // "about:client". - if (this[kState].referrer === 'client') { - return 'about:client' - } + // 5. Let timingInfo be a new fetch timing info whose start time and + // post-redirect start time are the coarsened shared current time given + // crossOriginIsolatedCapability. + const currenTime = coarsenedSharedCurrentTime(crossOriginIsolatedCapability) + const timingInfo = createOpaqueTimingInfo({ + startTime: currenTime + }) - // Return this’s request’s referrer, serialized. - return this[kState].referrer.toString() + // 6. Let fetchParams be a new fetch params whose + // request is request, + // timing info is timingInfo, + // process request body chunk length is processRequestBodyChunkLength, + // process request end-of-body is processRequestEndOfBody, + // process response is processResponse, + // process response consume body is processResponseConsumeBody, + // process response end-of-body is processResponseEndOfBody, + // task destination is taskDestination, + // and cross-origin isolated capability is crossOriginIsolatedCapability. + const fetchParams = { + controller: new Fetch(dispatcher), + request, + timingInfo, + processRequestBodyChunkLength, + processRequestEndOfBody, + processResponse, + processResponseConsumeBody, + processResponseEndOfBody, + taskDestination, + crossOriginIsolatedCapability } - // Returns the referrer policy associated with request. - // This is used during fetching to compute the value of the request’s - // referrer. - get referrerPolicy () { - webidl.brandCheck(this, Request) + // 7. If request’s body is a byte sequence, then set request’s body to + // request’s body as a body. + // NOTE: Since fetching is only called from fetch, body should already be + // extracted. + assert(!request.body || request.body.stream) - // The referrerPolicy getter steps are to return this’s request’s referrer policy. - return this[kState].referrerPolicy + // 8. If request’s window is "client", then set request’s window to request’s + // client, if request’s client’s global object is a Window object; otherwise + // "no-window". + if (request.window === 'client') { + // TODO: What if request.client is null? + request.window = + request.client?.globalObject?.constructor?.name === 'Window' + ? request.client + : 'no-window' } - // Returns the mode associated with request, which is a string indicating - // whether the request will use CORS, or will be restricted to same-origin - // URLs. - get mode () { - webidl.brandCheck(this, Request) - - // The mode getter steps are to return this’s request’s mode. - return this[kState].mode + // 9. If request’s origin is "client", then set request’s origin to request’s + // client’s origin. + if (request.origin === 'client') { + // TODO: What if request.client is null? + request.origin = request.client?.origin } - // Returns the credentials mode associated with request, - // which is a string indicating whether credentials will be sent with the - // request always, never, or only when sent to a same-origin URL. - get credentials () { - // The credentials getter steps are to return this’s request’s credentials mode. - return this[kState].credentials - } - - // Returns the cache mode associated with request, - // which is a string indicating how the request will - // interact with the browser’s cache when fetching. - get cache () { - webidl.brandCheck(this, Request) + // 10. If all of the following conditions are true: + // TODO - // The cache getter steps are to return this’s request’s cache mode. - return this[kState].cache + // 11. If request’s policy container is "client", then: + if (request.policyContainer === 'client') { + // 1. If request’s client is non-null, then set request’s policy + // container to a clone of request’s client’s policy container. [HTML] + if (request.client != null) { + request.policyContainer = clonePolicyContainer( + request.client.policyContainer + ) + } else { + // 2. Otherwise, set request’s policy container to a new policy + // container. + request.policyContainer = makePolicyContainer() + } } - // Returns the redirect mode associated with request, - // which is a string indicating how redirects for the - // request will be handled during fetching. A request - // will follow redirects by default. - get redirect () { - webidl.brandCheck(this, Request) - - // The redirect getter steps are to return this’s request’s redirect mode. - return this[kState].redirect - } + // 12. If request’s header list does not contain `Accept`, then: + if (!request.headersList.contains('accept')) { + // 1. Let value be `*/*`. + const value = '*/*' - // Returns request’s subresource integrity metadata, which is a - // cryptographic hash of the resource being fetched. Its value - // consists of multiple hashes separated by whitespace. [SRI] - get integrity () { - webidl.brandCheck(this, Request) + // 2. A user agent should set value to the first matching statement, if + // any, switching on request’s destination: + // "document" + // "frame" + // "iframe" + // `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8` + // "image" + // `image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5` + // "style" + // `text/css,*/*;q=0.1` + // TODO - // The integrity getter steps are to return this’s request’s integrity - // metadata. - return this[kState].integrity + // 3. Append `Accept`/value to request’s header list. + request.headersList.append('accept', value) } - // Returns a boolean indicating whether or not request can outlive the - // global in which it was created. - get keepalive () { - webidl.brandCheck(this, Request) - - // The keepalive getter steps are to return this’s request’s keepalive. - return this[kState].keepalive + // 13. If request’s header list does not contain `Accept-Language`, then + // user agents should append `Accept-Language`/an appropriate value to + // request’s header list. + if (!request.headersList.contains('accept-language')) { + request.headersList.append('accept-language', '*') } - // Returns a boolean indicating whether or not request is for a reload - // navigation. - get isReloadNavigation () { - webidl.brandCheck(this, Request) + // 14. If request’s priority is null, then use request’s initiator and + // destination appropriately in setting request’s priority to a + // user-agent-defined object. + if (request.priority === null) { + // TODO + } - // The isReloadNavigation getter steps are to return true if this’s - // request’s reload-navigation flag is set; otherwise false. - return this[kState].reloadNavigation + // 15. If request is a subresource request, then: + if (subresourceSet.has(request.destination)) { + // TODO } - // Returns a boolean indicating whether or not request is for a history - // navigation (a.k.a. back-foward navigation). - get isHistoryNavigation () { - webidl.brandCheck(this, Request) + // 16. Run main fetch given fetchParams. + mainFetch(fetchParams) + .catch(err => { + fetchParams.controller.terminate(err) + }) - // The isHistoryNavigation getter steps are to return true if this’s request’s - // history-navigation flag is set; otherwise false. - return this[kState].historyNavigation - } + // 17. Return fetchParam's controller + return fetchParams.controller +} - // Returns the signal associated with request, which is an AbortSignal - // object indicating whether or not request has been aborted, and its - // abort event handler. - get signal () { - webidl.brandCheck(this, Request) +// https://fetch.spec.whatwg.org/#concept-main-fetch +async function mainFetch (fetchParams, recursive = false) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request - // The signal getter steps are to return this’s signal. - return this[kSignal] + // 2. Let response be null. + let response = null + + // 3. If request’s local-URLs-only flag is set and request’s current URL is + // not local, then set response to a network error. + if (request.localURLsOnly && !urlIsLocal(requestCurrentURL(request))) { + response = makeNetworkError('local URLs only') } - get body () { - webidl.brandCheck(this, Request) + // 4. Run report Content Security Policy violations for request. + // TODO - return this[kState].body ? this[kState].body.stream : null + // 5. Upgrade request to a potentially trustworthy URL, if appropriate. + tryUpgradeRequestToAPotentiallyTrustworthyURL(request) + + // 6. If should request be blocked due to a bad port, should fetching request + // be blocked as mixed content, or should request be blocked by Content + // Security Policy returns blocked, then set response to a network error. + if (requestBadPort(request) === 'blocked') { + response = makeNetworkError('bad port') } + // TODO: should fetching request be blocked as mixed content? + // TODO: should request be blocked by Content Security Policy? - get bodyUsed () { - webidl.brandCheck(this, Request) + // 7. If request’s referrer policy is the empty string, then set request’s + // referrer policy to request’s policy container’s referrer policy. + if (request.referrerPolicy === '') { + request.referrerPolicy = request.policyContainer.referrerPolicy + } - return !!this[kState].body && util.isDisturbed(this[kState].body.stream) + // 8. If request’s referrer is not "no-referrer", then set request’s + // referrer to the result of invoking determine request’s referrer. + if (request.referrer !== 'no-referrer') { + request.referrer = determineRequestsReferrer(request) } - get duplex () { - webidl.brandCheck(this, Request) + // 9. Set request’s current URL’s scheme to "https" if all of the following + // conditions are true: + // - request’s current URL’s scheme is "http" + // - request’s current URL’s host is a domain + // - Matching request’s current URL’s host per Known HSTS Host Domain Name + // Matching results in either a superdomain match with an asserted + // includeSubDomains directive or a congruent match (with or without an + // asserted includeSubDomains directive). [HSTS] + // TODO - return 'half' - } + // 10. If recursive is false, then run the remaining steps in parallel. + // TODO - // Returns a clone of request. - clone () { - webidl.brandCheck(this, Request) + // 11. If response is null, then set response to the result of running + // the steps corresponding to the first matching statement: + if (response === null) { + response = await (async () => { + const currentURL = requestCurrentURL(request) - // 1. If this is unusable, then throw a TypeError. - if (this.bodyUsed || this.body?.locked) { - throw new TypeError('unusable') - } + if ( + // - request’s current URL’s origin is same origin with request’s origin, + // and request’s response tainting is "basic" + (sameOrigin(currentURL, request.url) && request.responseTainting === 'basic') || + // request’s current URL’s scheme is "data" + (currentURL.protocol === 'data:') || + // - request’s mode is "navigate" or "websocket" + (request.mode === 'navigate' || request.mode === 'websocket') + ) { + // 1. Set request’s response tainting to "basic". + request.responseTainting = 'basic' - // 2. Let clonedRequest be the result of cloning this’s request. - const clonedRequest = cloneRequest(this[kState]) + // 2. Return the result of running scheme fetch given fetchParams. + return await schemeFetch(fetchParams) + } - // 3. Let clonedRequestObject be the result of creating a Request object, - // given clonedRequest, this’s headers’s guard, and this’s relevant Realm. - const clonedRequestObject = new Request(kConstruct) - clonedRequestObject[kState] = clonedRequest - clonedRequestObject[kRealm] = this[kRealm] - clonedRequestObject[kHeaders] = new Headers(kConstruct) - clonedRequestObject[kHeaders][kHeadersList] = clonedRequest.headersList - clonedRequestObject[kHeaders][kGuard] = this[kHeaders][kGuard] - clonedRequestObject[kHeaders][kRealm] = this[kHeaders][kRealm] + // request’s mode is "same-origin" + if (request.mode === 'same-origin') { + // 1. Return a network error. + return makeNetworkError('request mode cannot be "same-origin"') + } - // 4. Make clonedRequestObject’s signal follow this’s signal. - const ac = new AbortController() - if (this.signal.aborted) { - ac.abort(this.signal.reason) - } else { - util.addAbortListener( - this.signal, - () => { - ac.abort(this.signal.reason) + // request’s mode is "no-cors" + if (request.mode === 'no-cors') { + // 1. If request’s redirect mode is not "follow", then return a network + // error. + if (request.redirect !== 'follow') { + return makeNetworkError( + 'redirect mode cannot be "follow" for "no-cors" request' + ) } - ) - } - clonedRequestObject[kSignal] = ac.signal - // 4. Return clonedRequestObject. - return clonedRequestObject - } -} + // 2. Set request’s response tainting to "opaque". + request.responseTainting = 'opaque' -mixinBody(Request) + // 3. Return the result of running scheme fetch given fetchParams. + return await schemeFetch(fetchParams) + } -function makeRequest (init) { - // https://fetch.spec.whatwg.org/#requests - const request = { - method: 'GET', - localURLsOnly: false, - unsafeRequest: false, - body: null, - client: null, - reservedClient: null, - replacesClientId: '', - window: 'client', - keepalive: false, - serviceWorkers: 'all', - initiator: '', - destination: '', - priority: null, - origin: 'client', - policyContainer: 'client', - referrer: 'client', - referrerPolicy: '', - mode: 'no-cors', - useCORSPreflightFlag: false, - credentials: 'same-origin', - useCredentials: false, - cache: 'default', - redirect: 'follow', - integrity: '', - cryptoGraphicsNonceMetadata: '', - parserMetadata: '', - reloadNavigation: false, - historyNavigation: false, - userActivation: false, - taintedOrigin: false, - redirectCount: 0, - responseTainting: 'basic', - preventNoCacheCacheControlHeaderModification: false, - done: false, - timingAllowFailed: false, - ...init, - headersList: init.headersList - ? new HeadersList(init.headersList) - : new HeadersList() - } - request.url = request.urlList[0] - return request -} + // request’s current URL’s scheme is not an HTTP(S) scheme + if (!urlIsHttpHttpsScheme(requestCurrentURL(request))) { + // Return a network error. + return makeNetworkError('URL scheme must be a HTTP(S) scheme') + } -// https://fetch.spec.whatwg.org/#concept-request-clone -function cloneRequest (request) { - // To clone a request request, run these steps: + // - request’s use-CORS-preflight flag is set + // - request’s unsafe-request flag is set and either request’s method is + // not a CORS-safelisted method or CORS-unsafe request-header names with + // request’s header list is not empty + // 1. Set request’s response tainting to "cors". + // 2. Let corsWithPreflightResponse be the result of running HTTP fetch + // given fetchParams and true. + // 3. If corsWithPreflightResponse is a network error, then clear cache + // entries using request. + // 4. Return corsWithPreflightResponse. + // TODO - // 1. Let newRequest be a copy of request, except for its body. - const newRequest = makeRequest({ ...request, body: null }) + // Otherwise + // 1. Set request’s response tainting to "cors". + request.responseTainting = 'cors' - // 2. If request’s body is non-null, set newRequest’s body to the - // result of cloning request’s body. - if (request.body != null) { - newRequest.body = cloneBody(request.body) + // 2. Return the result of running HTTP fetch given fetchParams. + return await httpFetch(fetchParams) + })() } - // 3. Return newRequest. - return newRequest -} + // 12. If recursive is true, then return response. + if (recursive) { + return response + } -Object.defineProperties(Request.prototype, { - method: kEnumerableProperty, - url: kEnumerableProperty, - headers: kEnumerableProperty, - redirect: kEnumerableProperty, - clone: kEnumerableProperty, - signal: kEnumerableProperty, - duplex: kEnumerableProperty, - destination: kEnumerableProperty, - body: kEnumerableProperty, - bodyUsed: kEnumerableProperty, - isHistoryNavigation: kEnumerableProperty, - isReloadNavigation: kEnumerableProperty, - keepalive: kEnumerableProperty, - integrity: kEnumerableProperty, - cache: kEnumerableProperty, - credentials: kEnumerableProperty, - attribute: kEnumerableProperty, - referrerPolicy: kEnumerableProperty, - referrer: kEnumerableProperty, - mode: kEnumerableProperty, - [Symbol.toStringTag]: { - value: 'Request', - configurable: true + // 13. If response is not a network error and response is not a filtered + // response, then: + if (response.status !== 0 && !response.internalResponse) { + // If request’s response tainting is "cors", then: + if (request.responseTainting === 'cors') { + // 1. Let headerNames be the result of extracting header list values + // given `Access-Control-Expose-Headers` and response’s header list. + // TODO + // 2. If request’s credentials mode is not "include" and headerNames + // contains `*`, then set response’s CORS-exposed header-name list to + // all unique header names in response’s header list. + // TODO + // 3. Otherwise, if headerNames is not null or failure, then set + // response’s CORS-exposed header-name list to headerNames. + // TODO + } + + // Set response to the following filtered response with response as its + // internal response, depending on request’s response tainting: + if (request.responseTainting === 'basic') { + response = filterResponse(response, 'basic') + } else if (request.responseTainting === 'cors') { + response = filterResponse(response, 'cors') + } else if (request.responseTainting === 'opaque') { + response = filterResponse(response, 'opaque') + } else { + assert(false) + } } -}) -webidl.converters.Request = webidl.interfaceConverter( - Request -) + // 14. Let internalResponse be response, if response is a network error, + // and response’s internal response otherwise. + let internalResponse = + response.status === 0 ? response : response.internalResponse -// https://fetch.spec.whatwg.org/#requestinfo -webidl.converters.RequestInfo = function (V) { - if (typeof V === 'string') { - return webidl.converters.USVString(V) + // 15. If internalResponse’s URL list is empty, then set it to a clone of + // request’s URL list. + if (internalResponse.urlList.length === 0) { + internalResponse.urlList.push(...request.urlList) } - if (V instanceof Request) { - return webidl.converters.Request(V) + // 16. If request’s timing allow failed flag is unset, then set + // internalResponse’s timing allow passed flag. + if (!request.timingAllowFailed) { + response.timingAllowPassed = true } - return webidl.converters.USVString(V) -} + // 17. If response is not a network error and any of the following returns + // blocked + // - should internalResponse to request be blocked as mixed content + // - should internalResponse to request be blocked by Content Security Policy + // - should internalResponse to request be blocked due to its MIME type + // - should internalResponse to request be blocked due to nosniff + // TODO -webidl.converters.AbortSignal = webidl.interfaceConverter( - AbortSignal -) + // 18. If response’s type is "opaque", internalResponse’s status is 206, + // internalResponse’s range-requested flag is set, and request’s header + // list does not contain `Range`, then set response and internalResponse + // to a network error. + if ( + response.type === 'opaque' && + internalResponse.status === 206 && + internalResponse.rangeRequested && + !request.headers.contains('range') + ) { + response = internalResponse = makeNetworkError() + } -// https://fetch.spec.whatwg.org/#requestinit -webidl.converters.RequestInit = webidl.dictionaryConverter([ - { - key: 'method', - converter: webidl.converters.ByteString - }, - { - key: 'headers', - converter: webidl.converters.HeadersInit - }, - { - key: 'body', - converter: webidl.nullableConverter( - webidl.converters.BodyInit - ) - }, - { - key: 'referrer', - converter: webidl.converters.USVString - }, - { - key: 'referrerPolicy', - converter: webidl.converters.DOMString, - // https://w3c.github.io/webappsec-referrer-policy/#referrer-policy - allowedValues: referrerPolicy - }, - { - key: 'mode', - converter: webidl.converters.DOMString, - // https://fetch.spec.whatwg.org/#concept-request-mode - allowedValues: requestMode - }, - { - key: 'credentials', - converter: webidl.converters.DOMString, - // https://fetch.spec.whatwg.org/#requestcredentials - allowedValues: requestCredentials - }, - { - key: 'cache', - converter: webidl.converters.DOMString, - // https://fetch.spec.whatwg.org/#requestcache - allowedValues: requestCache - }, - { - key: 'redirect', - converter: webidl.converters.DOMString, - // https://fetch.spec.whatwg.org/#requestredirect - allowedValues: requestRedirect - }, - { - key: 'integrity', - converter: webidl.converters.DOMString - }, - { - key: 'keepalive', - converter: webidl.converters.boolean - }, - { - key: 'signal', - converter: webidl.nullableConverter( - (signal) => webidl.converters.AbortSignal( - signal, - { strict: false } - ) - ) - }, - { - key: 'window', - converter: webidl.converters.any - }, - { - key: 'duplex', - converter: webidl.converters.DOMString, - allowedValues: requestDuplex + // 19. If response is not a network error and either request’s method is + // `HEAD` or `CONNECT`, or internalResponse’s status is a null body status, + // set internalResponse’s body to null and disregard any enqueuing toward + // it (if any). + if ( + response.status !== 0 && + (request.method === 'HEAD' || + request.method === 'CONNECT' || + nullBodyStatus.includes(internalResponse.status)) + ) { + internalResponse.body = null + fetchParams.controller.dump = true } -]) - -module.exports = { Request, makeRequest } + // 20. If request’s integrity metadata is not the empty string, then: + if (request.integrity) { + // 1. Let processBodyError be this step: run fetch finale given fetchParams + // and a network error. + const processBodyError = (reason) => + fetchFinale(fetchParams, makeNetworkError(reason)) -/***/ }), + // 2. If request’s response tainting is "opaque", or response’s body is null, + // then run processBodyError and abort these steps. + if (request.responseTainting === 'opaque' || response.body == null) { + processBodyError(response.error) + return + } -/***/ 7823: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // 3. Let processBody given bytes be these steps: + const processBody = (bytes) => { + // 1. If bytes do not match request’s integrity metadata, + // then run processBodyError and abort these steps. [SRI] + if (!bytesMatch(bytes, request.integrity)) { + processBodyError('integrity mismatch') + return + } -"use strict"; + // 2. Set response’s body to bytes as a body. + response.body = safelyExtractBody(bytes)[0] + // 3. Run fetch finale given fetchParams and response. + fetchFinale(fetchParams, response) + } -const { Headers, HeadersList, fill } = __nccwpck_require__(554) -const { extractBody, cloneBody, mixinBody } = __nccwpck_require__(1472) -const util = __nccwpck_require__(3983) -const { kEnumerableProperty } = util -const { - isValidReasonPhrase, - isCancelled, - isAborted, - isBlobLike, - serializeJavascriptValueToJSONString, - isErrorLike, - isomorphicEncode -} = __nccwpck_require__(2538) -const { - redirectStatusSet, - nullBodyStatus, - DOMException -} = __nccwpck_require__(1037) -const { kState, kHeaders, kGuard, kRealm } = __nccwpck_require__(5861) -const { webidl } = __nccwpck_require__(1744) -const { FormData } = __nccwpck_require__(2015) -const { getGlobalOrigin } = __nccwpck_require__(1246) -const { URLSerializer } = __nccwpck_require__(685) -const { kHeadersList, kConstruct } = __nccwpck_require__(2785) -const assert = __nccwpck_require__(9491) -const { types } = __nccwpck_require__(3837) + // 4. Fully read response’s body given processBody and processBodyError. + await fullyReadBody(response.body, processBody, processBodyError) + } else { + // 21. Otherwise, run fetch finale given fetchParams and response. + fetchFinale(fetchParams, response) + } +} -const ReadableStream = globalThis.ReadableStream || (__nccwpck_require__(5356).ReadableStream) -const textEncoder = new TextEncoder('utf-8') +// https://fetch.spec.whatwg.org/#concept-scheme-fetch +// given a fetch params fetchParams +function schemeFetch (fetchParams) { + // Note: since the connection is destroyed on redirect, which sets fetchParams to a + // cancelled state, we do not want this condition to trigger *unless* there have been + // no redirects. See https://github.com/nodejs/undici/issues/1776 + // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams. + if (isCancelled(fetchParams) && fetchParams.request.redirectCount === 0) { + return Promise.resolve(makeAppropriateNetworkError(fetchParams)) + } -// https://fetch.spec.whatwg.org/#response-class -class Response { - // Creates network error Response. - static error () { - // TODO - const relevantRealm = { settingsObject: {} } + // 2. Let request be fetchParams’s request. + const { request } = fetchParams - // The static error() method steps are to return the result of creating a - // Response object, given a new network error, "immutable", and this’s - // relevant Realm. - const responseObject = new Response() - responseObject[kState] = makeNetworkError() - responseObject[kRealm] = relevantRealm - responseObject[kHeaders][kHeadersList] = responseObject[kState].headersList - responseObject[kHeaders][kGuard] = 'immutable' - responseObject[kHeaders][kRealm] = relevantRealm - return responseObject - } + const { protocol: scheme } = requestCurrentURL(request) - // https://fetch.spec.whatwg.org/#dom-response-json - static json (data, init = {}) { - webidl.argumentLengthCheck(arguments, 1, { header: 'Response.json' }) + // 3. Switch on request’s current URL’s scheme and run the associated steps: + switch (scheme) { + case 'about:': { + // If request’s current URL’s path is the string "blank", then return a new response + // whose status message is `OK`, header list is « (`Content-Type`, `text/html;charset=utf-8`) », + // and body is the empty byte sequence as a body. - if (init !== null) { - init = webidl.converters.ResponseInit(init) + // Otherwise, return a network error. + return Promise.resolve(makeNetworkError('about scheme is not supported')) } + case 'blob:': { + if (!resolveObjectURL) { + resolveObjectURL = (__nccwpck_require__(4300).resolveObjectURL) + } - // 1. Let bytes the result of running serialize a JavaScript value to JSON bytes on data. - const bytes = textEncoder.encode( - serializeJavascriptValueToJSONString(data) - ) + // 1. Let blobURLEntry be request’s current URL’s blob URL entry. + const blobURLEntry = requestCurrentURL(request) - // 2. Let body be the result of extracting bytes. - const body = extractBody(bytes) + // https://github.com/web-platform-tests/wpt/blob/7b0ebaccc62b566a1965396e5be7bb2bc06f841f/FileAPI/url/resources/fetch-tests.js#L52-L56 + // Buffer.resolveObjectURL does not ignore URL queries. + if (blobURLEntry.search.length !== 0) { + return Promise.resolve(makeNetworkError('NetworkError when attempting to fetch resource.')) + } - // 3. Let responseObject be the result of creating a Response object, given a new response, - // "response", and this’s relevant Realm. - const relevantRealm = { settingsObject: {} } - const responseObject = new Response() - responseObject[kRealm] = relevantRealm - responseObject[kHeaders][kGuard] = 'response' - responseObject[kHeaders][kRealm] = relevantRealm + const blobURLEntryObject = resolveObjectURL(blobURLEntry.toString()) - // 4. Perform initialize a response given responseObject, init, and (body, "application/json"). - initializeResponse(responseObject, init, { body: body[0], type: 'application/json' }) + // 2. If request’s method is not `GET`, blobURLEntry is null, or blobURLEntry’s + // object is not a Blob object, then return a network error. + if (request.method !== 'GET' || !isBlobLike(blobURLEntryObject)) { + return Promise.resolve(makeNetworkError('invalid method')) + } - // 5. Return responseObject. - return responseObject - } + // 3. Let bodyWithType be the result of safely extracting blobURLEntry’s object. + const bodyWithType = safelyExtractBody(blobURLEntryObject) - // Creates a redirect Response that redirects to url with status status. - static redirect (url, status = 302) { - const relevantRealm = { settingsObject: {} } + // 4. Let body be bodyWithType’s body. + const body = bodyWithType[0] - webidl.argumentLengthCheck(arguments, 1, { header: 'Response.redirect' }) + // 5. Let length be body’s length, serialized and isomorphic encoded. + const length = isomorphicEncode(`${body.length}`) - url = webidl.converters.USVString(url) - status = webidl.converters['unsigned short'](status) + // 6. Let type be bodyWithType’s type if it is non-null; otherwise the empty byte sequence. + const type = bodyWithType[1] ?? '' - // 1. Let parsedURL be the result of parsing url with current settings - // object’s API base URL. - // 2. If parsedURL is failure, then throw a TypeError. - // TODO: base-URL? - let parsedURL - try { - parsedURL = new URL(url, getGlobalOrigin()) - } catch (err) { - throw Object.assign(new TypeError('Failed to parse URL from ' + url), { - cause: err + // 7. Return a new response whose status message is `OK`, header list is + // « (`Content-Length`, length), (`Content-Type`, type) », and body is body. + const response = makeResponse({ + statusText: 'OK', + headersList: [ + ['content-length', { name: 'Content-Length', value: length }], + ['content-type', { name: 'Content-Type', value: type }] + ] }) - } - // 3. If status is not a redirect status, then throw a RangeError. - if (!redirectStatusSet.has(status)) { - throw new RangeError('Invalid status code ' + status) - } - - // 4. Let responseObject be the result of creating a Response object, - // given a new response, "immutable", and this’s relevant Realm. - const responseObject = new Response() - responseObject[kRealm] = relevantRealm - responseObject[kHeaders][kGuard] = 'immutable' - responseObject[kHeaders][kRealm] = relevantRealm + response.body = body - // 5. Set responseObject’s response’s status to status. - responseObject[kState].status = status + return Promise.resolve(response) + } + case 'data:': { + // 1. Let dataURLStruct be the result of running the + // data: URL processor on request’s current URL. + const currentURL = requestCurrentURL(request) + const dataURLStruct = dataURLProcessor(currentURL) - // 6. Let value be parsedURL, serialized and isomorphic encoded. - const value = isomorphicEncode(URLSerializer(parsedURL)) + // 2. If dataURLStruct is failure, then return a + // network error. + if (dataURLStruct === 'failure') { + return Promise.resolve(makeNetworkError('failed to fetch the data URL')) + } - // 7. Append `Location`/value to responseObject’s response’s header list. - responseObject[kState].headersList.append('location', value) + // 3. Let mimeType be dataURLStruct’s MIME type, serialized. + const mimeType = serializeAMimeType(dataURLStruct.mimeType) - // 8. Return responseObject. - return responseObject - } + // 4. Return a response whose status message is `OK`, + // header list is « (`Content-Type`, mimeType) », + // and body is dataURLStruct’s body as a body. + return Promise.resolve(makeResponse({ + statusText: 'OK', + headersList: [ + ['content-type', { name: 'Content-Type', value: mimeType }] + ], + body: safelyExtractBody(dataURLStruct.body)[0] + })) + } + case 'file:': { + // For now, unfortunate as it is, file URLs are left as an exercise for the reader. + // When in doubt, return a network error. + return Promise.resolve(makeNetworkError('not implemented... yet...')) + } + case 'http:': + case 'https:': { + // Return the result of running HTTP fetch given fetchParams. - // https://fetch.spec.whatwg.org/#dom-response - constructor (body = null, init = {}) { - if (body !== null) { - body = webidl.converters.BodyInit(body) + return httpFetch(fetchParams) + .catch((err) => makeNetworkError(err)) } + default: { + return Promise.resolve(makeNetworkError('unknown scheme')) + } + } +} - init = webidl.converters.ResponseInit(init) +// https://fetch.spec.whatwg.org/#finalize-response +function finalizeResponse (fetchParams, response) { + // 1. Set fetchParams’s request’s done flag. + fetchParams.request.done = true - // TODO - this[kRealm] = { settingsObject: {} } + // 2, If fetchParams’s process response done is not null, then queue a fetch + // task to run fetchParams’s process response done given response, with + // fetchParams’s task destination. + if (fetchParams.processResponseDone != null) { + queueMicrotask(() => fetchParams.processResponseDone(response)) + } +} - // 1. Set this’s response to a new response. - this[kState] = makeResponse({}) +// https://fetch.spec.whatwg.org/#fetch-finale +function fetchFinale (fetchParams, response) { + // 1. If response is a network error, then: + if (response.type === 'error') { + // 1. Set response’s URL list to « fetchParams’s request’s URL list[0] ». + response.urlList = [fetchParams.request.urlList[0]] - // 2. Set this’s headers to a new Headers object with this’s relevant - // Realm, whose header list is this’s response’s header list and guard - // is "response". - this[kHeaders] = new Headers(kConstruct) - this[kHeaders][kGuard] = 'response' - this[kHeaders][kHeadersList] = this[kState].headersList - this[kHeaders][kRealm] = this[kRealm] + // 2. Set response’s timing info to the result of creating an opaque timing + // info for fetchParams’s timing info. + response.timingInfo = createOpaqueTimingInfo({ + startTime: fetchParams.timingInfo.startTime + }) + } - // 3. Let bodyWithType be null. - let bodyWithType = null + // 2. Let processResponseEndOfBody be the following steps: + const processResponseEndOfBody = () => { + // 1. Set fetchParams’s request’s done flag. + fetchParams.request.done = true - // 4. If body is non-null, then set bodyWithType to the result of extracting body. - if (body != null) { - const [extractedBody, type] = extractBody(body) - bodyWithType = { body: extractedBody, type } + // If fetchParams’s process response end-of-body is not null, + // then queue a fetch task to run fetchParams’s process response + // end-of-body given response with fetchParams’s task destination. + if (fetchParams.processResponseEndOfBody != null) { + queueMicrotask(() => fetchParams.processResponseEndOfBody(response)) } - - // 5. Perform initialize a response given this, init, and bodyWithType. - initializeResponse(this, init, bodyWithType) } - // Returns response’s type, e.g., "cors". - get type () { - webidl.brandCheck(this, Response) - - // The type getter steps are to return this’s response’s type. - return this[kState].type + // 3. If fetchParams’s process response is non-null, then queue a fetch task + // to run fetchParams’s process response given response, with fetchParams’s + // task destination. + if (fetchParams.processResponse != null) { + queueMicrotask(() => fetchParams.processResponse(response)) } - // Returns response’s URL, if it has one; otherwise the empty string. - get url () { - webidl.brandCheck(this, Response) - - const urlList = this[kState].urlList + // 4. If response’s body is null, then run processResponseEndOfBody. + if (response.body == null) { + processResponseEndOfBody() + } else { + // 5. Otherwise: - // The url getter steps are to return the empty string if this’s - // response’s URL is null; otherwise this’s response’s URL, - // serialized with exclude fragment set to true. - const url = urlList[urlList.length - 1] ?? null + // 1. Let transformStream be a new a TransformStream. - if (url === null) { - return '' + // 2. Let identityTransformAlgorithm be an algorithm which, given chunk, + // enqueues chunk in transformStream. + const identityTransformAlgorithm = (chunk, controller) => { + controller.enqueue(chunk) } - return URLSerializer(url, true) - } - - // Returns whether response was obtained through a redirect. - get redirected () { - webidl.brandCheck(this, Response) + // 3. Set up transformStream with transformAlgorithm set to identityTransformAlgorithm + // and flushAlgorithm set to processResponseEndOfBody. + const transformStream = new TransformStream({ + start () {}, + transform: identityTransformAlgorithm, + flush: processResponseEndOfBody + }, { + size () { + return 1 + } + }, { + size () { + return 1 + } + }) - // The redirected getter steps are to return true if this’s response’s URL - // list has more than one item; otherwise false. - return this[kState].urlList.length > 1 + // 4. Set response’s body to the result of piping response’s body through transformStream. + response.body = { stream: response.body.stream.pipeThrough(transformStream) } } - // Returns response’s status. - get status () { - webidl.brandCheck(this, Response) - - // The status getter steps are to return this’s response’s status. - return this[kState].status - } + // 6. If fetchParams’s process response consume body is non-null, then: + if (fetchParams.processResponseConsumeBody != null) { + // 1. Let processBody given nullOrBytes be this step: run fetchParams’s + // process response consume body given response and nullOrBytes. + const processBody = (nullOrBytes) => fetchParams.processResponseConsumeBody(response, nullOrBytes) - // Returns whether response’s status is an ok status. - get ok () { - webidl.brandCheck(this, Response) + // 2. Let processBodyError be this step: run fetchParams’s process + // response consume body given response and failure. + const processBodyError = (failure) => fetchParams.processResponseConsumeBody(response, failure) - // The ok getter steps are to return true if this’s response’s status is an - // ok status; otherwise false. - return this[kState].status >= 200 && this[kState].status <= 299 + // 3. If response’s body is null, then queue a fetch task to run processBody + // given null, with fetchParams’s task destination. + if (response.body == null) { + queueMicrotask(() => processBody(null)) + } else { + // 4. Otherwise, fully read response’s body given processBody, processBodyError, + // and fetchParams’s task destination. + return fullyReadBody(response.body, processBody, processBodyError) + } + return Promise.resolve() } +} - // Returns response’s status message. - get statusText () { - webidl.brandCheck(this, Response) +// https://fetch.spec.whatwg.org/#http-fetch +async function httpFetch (fetchParams) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request - // The statusText getter steps are to return this’s response’s status - // message. - return this[kState].statusText - } + // 2. Let response be null. + let response = null - // Returns response’s headers as Headers. - get headers () { - webidl.brandCheck(this, Response) + // 3. Let actualResponse be null. + let actualResponse = null - // The headers getter steps are to return this’s headers. - return this[kHeaders] + // 4. Let timingInfo be fetchParams’s timing info. + const timingInfo = fetchParams.timingInfo + + // 5. If request’s service-workers mode is "all", then: + if (request.serviceWorkers === 'all') { + // TODO } - get body () { - webidl.brandCheck(this, Response) + // 6. If response is null, then: + if (response === null) { + // 1. If makeCORSPreflight is true and one of these conditions is true: + // TODO - return this[kState].body ? this[kState].body.stream : null - } + // 2. If request’s redirect mode is "follow", then set request’s + // service-workers mode to "none". + if (request.redirect === 'follow') { + request.serviceWorkers = 'none' + } - get bodyUsed () { - webidl.brandCheck(this, Response) + // 3. Set response and actualResponse to the result of running + // HTTP-network-or-cache fetch given fetchParams. + actualResponse = response = await httpNetworkOrCacheFetch(fetchParams) - return !!this[kState].body && util.isDisturbed(this[kState].body.stream) + // 4. If request’s response tainting is "cors" and a CORS check + // for request and response returns failure, then return a network error. + if ( + request.responseTainting === 'cors' && + corsCheck(request, response) === 'failure' + ) { + return makeNetworkError('cors failure') + } + + // 5. If the TAO check for request and response returns failure, then set + // request’s timing allow failed flag. + if (TAOCheck(request, response) === 'failure') { + request.timingAllowFailed = true + } } - // Returns a clone of response. - clone () { - webidl.brandCheck(this, Response) + // 7. If either request’s response tainting or response’s type + // is "opaque", and the cross-origin resource policy check with + // request’s origin, request’s client, request’s destination, + // and actualResponse returns blocked, then return a network error. + if ( + (request.responseTainting === 'opaque' || response.type === 'opaque') && + crossOriginResourcePolicyCheck( + request.origin, + request.client, + request.destination, + actualResponse + ) === 'blocked' + ) { + return makeNetworkError('blocked') + } - // 1. If this is unusable, then throw a TypeError. - if (this.bodyUsed || (this.body && this.body.locked)) { - throw webidl.errors.exception({ - header: 'Response.clone', - message: 'Body has already been consumed.' - }) + // 8. If actualResponse’s status is a redirect status, then: + if (redirectStatusSet.has(actualResponse.status)) { + // 1. If actualResponse’s status is not 303, request’s body is not null, + // and the connection uses HTTP/2, then user agents may, and are even + // encouraged to, transmit an RST_STREAM frame. + // See, https://github.com/whatwg/fetch/issues/1288 + if (request.redirect !== 'manual') { + fetchParams.controller.connection.destroy() } - // 2. Let clonedResponse be the result of cloning this’s response. - const clonedResponse = cloneResponse(this[kState]) + // 2. Switch on request’s redirect mode: + if (request.redirect === 'error') { + // Set response to a network error. + response = makeNetworkError('unexpected redirect') + } else if (request.redirect === 'manual') { + // Set response to an opaque-redirect filtered response whose internal + // response is actualResponse. + // NOTE(spec): On the web this would return an `opaqueredirect` response, + // but that doesn't make sense server side. + // See https://github.com/nodejs/undici/issues/1193. + response = actualResponse + } else if (request.redirect === 'follow') { + // Set response to the result of running HTTP-redirect fetch given + // fetchParams and response. + response = await httpRedirectFetch(fetchParams, response) + } else { + assert(false) + } + } - // 3. Return the result of creating a Response object, given - // clonedResponse, this’s headers’s guard, and this’s relevant Realm. - const clonedResponseObject = new Response() - clonedResponseObject[kState] = clonedResponse - clonedResponseObject[kRealm] = this[kRealm] - clonedResponseObject[kHeaders][kHeadersList] = clonedResponse.headersList - clonedResponseObject[kHeaders][kGuard] = this[kHeaders][kGuard] - clonedResponseObject[kHeaders][kRealm] = this[kHeaders][kRealm] + // 9. Set response’s timing info to timingInfo. + response.timingInfo = timingInfo - return clonedResponseObject - } + // 10. Return response. + return response } -mixinBody(Response) - -Object.defineProperties(Response.prototype, { - type: kEnumerableProperty, - url: kEnumerableProperty, - status: kEnumerableProperty, - ok: kEnumerableProperty, - redirected: kEnumerableProperty, - statusText: kEnumerableProperty, - headers: kEnumerableProperty, - clone: kEnumerableProperty, - body: kEnumerableProperty, - bodyUsed: kEnumerableProperty, - [Symbol.toStringTag]: { - value: 'Response', - configurable: true - } -}) +// https://fetch.spec.whatwg.org/#http-redirect-fetch +function httpRedirectFetch (fetchParams, response) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request -Object.defineProperties(Response, { - json: kEnumerableProperty, - redirect: kEnumerableProperty, - error: kEnumerableProperty -}) + // 2. Let actualResponse be response, if response is not a filtered response, + // and response’s internal response otherwise. + const actualResponse = response.internalResponse + ? response.internalResponse + : response -// https://fetch.spec.whatwg.org/#concept-response-clone -function cloneResponse (response) { - // To clone a response response, run these steps: + // 3. Let locationURL be actualResponse’s location URL given request’s current + // URL’s fragment. + let locationURL - // 1. If response is a filtered response, then return a new identical - // filtered response whose internal response is a clone of response’s - // internal response. - if (response.internalResponse) { - return filterResponse( - cloneResponse(response.internalResponse), - response.type + try { + locationURL = responseLocationURL( + actualResponse, + requestCurrentURL(request).hash ) + + // 4. If locationURL is null, then return response. + if (locationURL == null) { + return response + } + } catch (err) { + // 5. If locationURL is failure, then return a network error. + return Promise.resolve(makeNetworkError(err)) } - // 2. Let newResponse be a copy of response, except for its body. - const newResponse = makeResponse({ ...response, body: null }) + // 6. If locationURL’s scheme is not an HTTP(S) scheme, then return a network + // error. + if (!urlIsHttpHttpsScheme(locationURL)) { + return Promise.resolve(makeNetworkError('URL scheme must be a HTTP(S) scheme')) + } - // 3. If response’s body is non-null, then set newResponse’s body to the - // result of cloning response’s body. - if (response.body != null) { - newResponse.body = cloneBody(response.body) + // 7. If request’s redirect count is 20, then return a network error. + if (request.redirectCount === 20) { + return Promise.resolve(makeNetworkError('redirect count exceeded')) } - // 4. Return newResponse. - return newResponse -} + // 8. Increase request’s redirect count by 1. + request.redirectCount += 1 -function makeResponse (init) { - return { - aborted: false, - rangeRequested: false, - timingAllowPassed: false, - requestIncludesCredentials: false, - type: 'default', - status: 200, - timingInfo: null, - cacheState: '', - statusText: '', - ...init, - headersList: init.headersList - ? new HeadersList(init.headersList) - : new HeadersList(), - urlList: init.urlList ? [...init.urlList] : [] + // 9. If request’s mode is "cors", locationURL includes credentials, and + // request’s origin is not same origin with locationURL’s origin, then return + // a network error. + if ( + request.mode === 'cors' && + (locationURL.username || locationURL.password) && + !sameOrigin(request, locationURL) + ) { + return Promise.resolve(makeNetworkError('cross origin not allowed for request mode "cors"')) } -} -function makeNetworkError (reason) { - const isError = isErrorLike(reason) - return makeResponse({ - type: 'error', - status: 0, - error: isError - ? reason - : new Error(reason ? String(reason) : reason), - aborted: reason && reason.name === 'AbortError' - }) -} + // 10. If request’s response tainting is "cors" and locationURL includes + // credentials, then return a network error. + if ( + request.responseTainting === 'cors' && + (locationURL.username || locationURL.password) + ) { + return Promise.resolve(makeNetworkError( + 'URL cannot contain credentials for request mode "cors"' + )) + } -function makeFilteredResponse (response, state) { - state = { - internalResponse: response, - ...state + // 11. If actualResponse’s status is not 303, request’s body is non-null, + // and request’s body’s source is null, then return a network error. + if ( + actualResponse.status !== 303 && + request.body != null && + request.body.source == null + ) { + return Promise.resolve(makeNetworkError()) } - return new Proxy(response, { - get (target, p) { - return p in state ? state[p] : target[p] - }, - set (target, p, value) { - assert(!(p in state)) - target[p] = value - return true + // 12. If one of the following is true + // - actualResponse’s status is 301 or 302 and request’s method is `POST` + // - actualResponse’s status is 303 and request’s method is not `GET` or `HEAD` + if ( + ([301, 302].includes(actualResponse.status) && request.method === 'POST') || + (actualResponse.status === 303 && + !GET_OR_HEAD.includes(request.method)) + ) { + // then: + // 1. Set request’s method to `GET` and request’s body to null. + request.method = 'GET' + request.body = null + + // 2. For each headerName of request-body-header name, delete headerName from + // request’s header list. + for (const headerName of requestBodyHeader) { + request.headersList.delete(headerName) } - }) -} + } -// https://fetch.spec.whatwg.org/#concept-filtered-response -function filterResponse (response, type) { - // Set response to the following filtered response with response as its - // internal response, depending on request’s response tainting: - if (type === 'basic') { - // A basic filtered response is a filtered response whose type is "basic" - // and header list excludes any headers in internal response’s header list - // whose name is a forbidden response-header name. + // 13. If request’s current URL’s origin is not same origin with locationURL’s + // origin, then for each headerName of CORS non-wildcard request-header name, + // delete headerName from request’s header list. + if (!sameOrigin(requestCurrentURL(request), locationURL)) { + // https://fetch.spec.whatwg.org/#cors-non-wildcard-request-header-name + request.headersList.delete('authorization') - // Note: undici does not implement forbidden response-header names - return makeFilteredResponse(response, { - type: 'basic', - headersList: response.headersList - }) - } else if (type === 'cors') { - // A CORS filtered response is a filtered response whose type is "cors" - // and header list excludes any headers in internal response’s header - // list whose name is not a CORS-safelisted response-header name, given - // internal response’s CORS-exposed header-name list. + // "Cookie" and "Host" are forbidden request-headers, which undici doesn't implement. + request.headersList.delete('cookie') + request.headersList.delete('host') + } - // Note: undici does not implement CORS-safelisted response-header names - return makeFilteredResponse(response, { - type: 'cors', - headersList: response.headersList - }) - } else if (type === 'opaque') { - // An opaque filtered response is a filtered response whose type is - // "opaque", URL list is the empty list, status is 0, status message - // is the empty byte sequence, header list is empty, and body is null. + // 14. If request’s body is non-null, then set request’s body to the first return + // value of safely extracting request’s body’s source. + if (request.body != null) { + assert(request.body.source != null) + request.body = safelyExtractBody(request.body.source)[0] + } - return makeFilteredResponse(response, { - type: 'opaque', - urlList: Object.freeze([]), - status: 0, - statusText: '', - body: null - }) - } else if (type === 'opaqueredirect') { - // An opaque-redirect filtered response is a filtered response whose type - // is "opaqueredirect", status is 0, status message is the empty byte - // sequence, header list is empty, and body is null. + // 15. Let timingInfo be fetchParams’s timing info. + const timingInfo = fetchParams.timingInfo - return makeFilteredResponse(response, { - type: 'opaqueredirect', - status: 0, - statusText: '', - headersList: [], - body: null - }) - } else { - assert(false) + // 16. Set timingInfo’s redirect end time and post-redirect start time to the + // coarsened shared current time given fetchParams’s cross-origin isolated + // capability. + timingInfo.redirectEndTime = timingInfo.postRedirectStartTime = + coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability) + + // 17. If timingInfo’s redirect start time is 0, then set timingInfo’s + // redirect start time to timingInfo’s start time. + if (timingInfo.redirectStartTime === 0) { + timingInfo.redirectStartTime = timingInfo.startTime } -} -// https://fetch.spec.whatwg.org/#appropriate-network-error -function makeAppropriateNetworkError (fetchParams, err = null) { - // 1. Assert: fetchParams is canceled. - assert(isCancelled(fetchParams)) + // 18. Append locationURL to request’s URL list. + request.urlList.push(locationURL) - // 2. Return an aborted network error if fetchParams is aborted; - // otherwise return a network error. - return isAborted(fetchParams) - ? makeNetworkError(Object.assign(new DOMException('The operation was aborted.', 'AbortError'), { cause: err })) - : makeNetworkError(Object.assign(new DOMException('Request was cancelled.'), { cause: err })) + // 19. Invoke set request’s referrer policy on redirect on request and + // actualResponse. + setRequestReferrerPolicyOnRedirect(request, actualResponse) + + // 20. Return the result of running main fetch given fetchParams and true. + return mainFetch(fetchParams, true) } -// https://whatpr.org/fetch/1392.html#initialize-a-response -function initializeResponse (response, init, body) { - // 1. If init["status"] is not in the range 200 to 599, inclusive, then - // throw a RangeError. - if (init.status !== null && (init.status < 200 || init.status > 599)) { - throw new RangeError('init["status"] must be in the range of 200 to 599, inclusive.') - } +// https://fetch.spec.whatwg.org/#http-network-or-cache-fetch +async function httpNetworkOrCacheFetch ( + fetchParams, + isAuthenticationFetch = false, + isNewConnectionFetch = false +) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request - // 2. If init["statusText"] does not match the reason-phrase token production, - // then throw a TypeError. - if ('statusText' in init && init.statusText != null) { - // See, https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2: - // reason-phrase = *( HTAB / SP / VCHAR / obs-text ) - if (!isValidReasonPhrase(String(init.statusText))) { - throw new TypeError('Invalid statusText') - } - } + // 2. Let httpFetchParams be null. + let httpFetchParams = null - // 3. Set response’s response’s status to init["status"]. - if ('status' in init && init.status != null) { - response[kState].status = init.status - } + // 3. Let httpRequest be null. + let httpRequest = null - // 4. Set response’s response’s status message to init["statusText"]. - if ('statusText' in init && init.statusText != null) { - response[kState].statusText = init.statusText - } + // 4. Let response be null. + let response = null - // 5. If init["headers"] exists, then fill response’s headers with init["headers"]. - if ('headers' in init && init.headers != null) { - fill(response[kHeaders], init.headers) - } + // 5. Let storedResponse be null. + // TODO: cache - // 6. If body was given, then: - if (body) { - // 1. If response's status is a null body status, then throw a TypeError. - if (nullBodyStatus.includes(response.status)) { - throw webidl.errors.exception({ - header: 'Response constructor', - message: 'Invalid response status code ' + response.status - }) - } + // 6. Let httpCache be null. + const httpCache = null - // 2. Set response's body to body's body. - response[kState].body = body.body + // 7. Let the revalidatingFlag be unset. + const revalidatingFlag = false - // 3. If body's type is non-null and response's header list does not contain - // `Content-Type`, then append (`Content-Type`, body's type) to response's header list. - if (body.type != null && !response[kState].headersList.contains('Content-Type')) { - response[kState].headersList.append('content-type', body.type) - } + // 8. Run these steps, but abort when the ongoing fetch is terminated: + + // 1. If request’s window is "no-window" and request’s redirect mode is + // "error", then set httpFetchParams to fetchParams and httpRequest to + // request. + if (request.window === 'no-window' && request.redirect === 'error') { + httpFetchParams = fetchParams + httpRequest = request + } else { + // Otherwise: + + // 1. Set httpRequest to a clone of request. + httpRequest = makeRequest(request) + + // 2. Set httpFetchParams to a copy of fetchParams. + httpFetchParams = { ...fetchParams } + + // 3. Set httpFetchParams’s request to httpRequest. + httpFetchParams.request = httpRequest } -} -webidl.converters.ReadableStream = webidl.interfaceConverter( - ReadableStream -) + // 3. Let includeCredentials be true if one of + const includeCredentials = + request.credentials === 'include' || + (request.credentials === 'same-origin' && + request.responseTainting === 'basic') -webidl.converters.FormData = webidl.interfaceConverter( - FormData -) + // 4. Let contentLength be httpRequest’s body’s length, if httpRequest’s + // body is non-null; otherwise null. + const contentLength = httpRequest.body ? httpRequest.body.length : null -webidl.converters.URLSearchParams = webidl.interfaceConverter( - URLSearchParams -) + // 5. Let contentLengthHeaderValue be null. + let contentLengthHeaderValue = null -// https://fetch.spec.whatwg.org/#typedefdef-xmlhttprequestbodyinit -webidl.converters.XMLHttpRequestBodyInit = function (V) { - if (typeof V === 'string') { - return webidl.converters.USVString(V) + // 6. If httpRequest’s body is null and httpRequest’s method is `POST` or + // `PUT`, then set contentLengthHeaderValue to `0`. + if ( + httpRequest.body == null && + ['POST', 'PUT'].includes(httpRequest.method) + ) { + contentLengthHeaderValue = '0' } - if (isBlobLike(V)) { - return webidl.converters.Blob(V, { strict: false }) + // 7. If contentLength is non-null, then set contentLengthHeaderValue to + // contentLength, serialized and isomorphic encoded. + if (contentLength != null) { + contentLengthHeaderValue = isomorphicEncode(`${contentLength}`) } - if (types.isArrayBuffer(V) || types.isTypedArray(V) || types.isDataView(V)) { - return webidl.converters.BufferSource(V) + // 8. If contentLengthHeaderValue is non-null, then append + // `Content-Length`/contentLengthHeaderValue to httpRequest’s header + // list. + if (contentLengthHeaderValue != null) { + httpRequest.headersList.append('content-length', contentLengthHeaderValue) } - if (util.isFormDataLike(V)) { - return webidl.converters.FormData(V, { strict: false }) + // 9. If contentLengthHeaderValue is non-null, then append (`Content-Length`, + // contentLengthHeaderValue) to httpRequest’s header list. + + // 10. If contentLength is non-null and httpRequest’s keepalive is true, + // then: + if (contentLength != null && httpRequest.keepalive) { + // NOTE: keepalive is a noop outside of browser context. } - if (V instanceof URLSearchParams) { - return webidl.converters.URLSearchParams(V) + // 11. If httpRequest’s referrer is a URL, then append + // `Referer`/httpRequest’s referrer, serialized and isomorphic encoded, + // to httpRequest’s header list. + if (httpRequest.referrer instanceof URL) { + httpRequest.headersList.append('referer', isomorphicEncode(httpRequest.referrer.href)) } - return webidl.converters.DOMString(V) -} + // 12. Append a request `Origin` header for httpRequest. + appendRequestOriginHeader(httpRequest) -// https://fetch.spec.whatwg.org/#bodyinit -webidl.converters.BodyInit = function (V) { - if (V instanceof ReadableStream) { - return webidl.converters.ReadableStream(V) + // 13. Append the Fetch metadata headers for httpRequest. [FETCH-METADATA] + appendFetchMetadata(httpRequest) + + // 14. If httpRequest’s header list does not contain `User-Agent`, then + // user agents should append `User-Agent`/default `User-Agent` value to + // httpRequest’s header list. + if (!httpRequest.headersList.contains('user-agent')) { + httpRequest.headersList.append('user-agent', typeof esbuildDetection === 'undefined' ? 'undici' : 'node') } - // Note: the spec doesn't include async iterables, - // this is an undici extension. - if (V?.[Symbol.asyncIterator]) { - return V + // 15. If httpRequest’s cache mode is "default" and httpRequest’s header + // list contains `If-Modified-Since`, `If-None-Match`, + // `If-Unmodified-Since`, `If-Match`, or `If-Range`, then set + // httpRequest’s cache mode to "no-store". + if ( + httpRequest.cache === 'default' && + (httpRequest.headersList.contains('if-modified-since') || + httpRequest.headersList.contains('if-none-match') || + httpRequest.headersList.contains('if-unmodified-since') || + httpRequest.headersList.contains('if-match') || + httpRequest.headersList.contains('if-range')) + ) { + httpRequest.cache = 'no-store' } - return webidl.converters.XMLHttpRequestBodyInit(V) -} + // 16. If httpRequest’s cache mode is "no-cache", httpRequest’s prevent + // no-cache cache-control header modification flag is unset, and + // httpRequest’s header list does not contain `Cache-Control`, then append + // `Cache-Control`/`max-age=0` to httpRequest’s header list. + if ( + httpRequest.cache === 'no-cache' && + !httpRequest.preventNoCacheCacheControlHeaderModification && + !httpRequest.headersList.contains('cache-control') + ) { + httpRequest.headersList.append('cache-control', 'max-age=0') + } -webidl.converters.ResponseInit = webidl.dictionaryConverter([ - { - key: 'status', - converter: webidl.converters['unsigned short'], - defaultValue: 200 - }, - { - key: 'statusText', - converter: webidl.converters.ByteString, - defaultValue: '' - }, - { - key: 'headers', - converter: webidl.converters.HeadersInit + // 17. If httpRequest’s cache mode is "no-store" or "reload", then: + if (httpRequest.cache === 'no-store' || httpRequest.cache === 'reload') { + // 1. If httpRequest’s header list does not contain `Pragma`, then append + // `Pragma`/`no-cache` to httpRequest’s header list. + if (!httpRequest.headersList.contains('pragma')) { + httpRequest.headersList.append('pragma', 'no-cache') + } + + // 2. If httpRequest’s header list does not contain `Cache-Control`, + // then append `Cache-Control`/`no-cache` to httpRequest’s header list. + if (!httpRequest.headersList.contains('cache-control')) { + httpRequest.headersList.append('cache-control', 'no-cache') + } } -]) -module.exports = { - makeNetworkError, - makeResponse, - makeAppropriateNetworkError, - filterResponse, - Response, - cloneResponse -} + // 18. If httpRequest’s header list contains `Range`, then append + // `Accept-Encoding`/`identity` to httpRequest’s header list. + if (httpRequest.headersList.contains('range')) { + httpRequest.headersList.append('accept-encoding', 'identity') + } + // 19. Modify httpRequest’s header list per HTTP. Do not append a given + // header if httpRequest’s header list contains that header’s name. + // TODO: https://github.com/whatwg/fetch/issues/1285#issuecomment-896560129 + if (!httpRequest.headersList.contains('accept-encoding')) { + if (urlHasHttpsScheme(requestCurrentURL(httpRequest))) { + httpRequest.headersList.append('accept-encoding', 'br, gzip, deflate') + } else { + httpRequest.headersList.append('accept-encoding', 'gzip, deflate') + } + } -/***/ }), + httpRequest.headersList.delete('host') -/***/ 5861: -/***/ ((module) => { + // 20. If includeCredentials is true, then: + if (includeCredentials) { + // 1. If the user agent is not configured to block cookies for httpRequest + // (see section 7 of [COOKIES]), then: + // TODO: credentials + // 2. If httpRequest’s header list does not contain `Authorization`, then: + // TODO: credentials + } -"use strict"; + // 21. If there’s a proxy-authentication entry, use it as appropriate. + // TODO: proxy-authentication + // 22. Set httpCache to the result of determining the HTTP cache + // partition, given httpRequest. + // TODO: cache -module.exports = { - kUrl: Symbol('url'), - kHeaders: Symbol('headers'), - kSignal: Symbol('signal'), - kState: Symbol('state'), - kGuard: Symbol('guard'), - kRealm: Symbol('realm') -} - + // 23. If httpCache is null, then set httpRequest’s cache mode to + // "no-store". + if (httpCache == null) { + httpRequest.cache = 'no-store' + } -/***/ }), + // 24. If httpRequest’s cache mode is neither "no-store" nor "reload", + // then: + if (httpRequest.mode !== 'no-store' && httpRequest.mode !== 'reload') { + // TODO: cache + } -/***/ 2538: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // 9. If aborted, then return the appropriate network error for fetchParams. + // TODO -"use strict"; + // 10. If response is null, then: + if (response == null) { + // 1. If httpRequest’s cache mode is "only-if-cached", then return a + // network error. + if (httpRequest.mode === 'only-if-cached') { + return makeNetworkError('only if cached') + } + // 2. Let forwardResponse be the result of running HTTP-network fetch + // given httpFetchParams, includeCredentials, and isNewConnectionFetch. + const forwardResponse = await httpNetworkFetch( + httpFetchParams, + includeCredentials, + isNewConnectionFetch + ) -const { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = __nccwpck_require__(1037) -const { getGlobalOrigin } = __nccwpck_require__(1246) -const { performance } = __nccwpck_require__(4074) -const { isBlobLike, toUSVString, ReadableStreamFrom } = __nccwpck_require__(3983) -const assert = __nccwpck_require__(9491) -const { isUint8Array } = __nccwpck_require__(9830) + // 3. If httpRequest’s method is unsafe and forwardResponse’s status is + // in the range 200 to 399, inclusive, invalidate appropriate stored + // responses in httpCache, as per the "Invalidation" chapter of HTTP + // Caching, and set storedResponse to null. [HTTP-CACHING] + if ( + !safeMethodsSet.has(httpRequest.method) && + forwardResponse.status >= 200 && + forwardResponse.status <= 399 + ) { + // TODO: cache + } -// https://nodejs.org/api/crypto.html#determining-if-crypto-support-is-unavailable -/** @type {import('crypto')|undefined} */ -let crypto + // 4. If the revalidatingFlag is set and forwardResponse’s status is 304, + // then: + if (revalidatingFlag && forwardResponse.status === 304) { + // TODO: cache + } -try { - crypto = __nccwpck_require__(6113) -} catch { + // 5. If response is null, then: + if (response == null) { + // 1. Set response to forwardResponse. + response = forwardResponse -} + // 2. Store httpRequest and forwardResponse in httpCache, as per the + // "Storing Responses in Caches" chapter of HTTP Caching. [HTTP-CACHING] + // TODO: cache + } + } -function responseURL (response) { - // https://fetch.spec.whatwg.org/#responses - // A response has an associated URL. It is a pointer to the last URL - // in response’s URL list and null if response’s URL list is empty. - const urlList = response.urlList - const length = urlList.length - return length === 0 ? null : urlList[length - 1].toString() -} + // 11. Set response’s URL list to a clone of httpRequest’s URL list. + response.urlList = [...httpRequest.urlList] -// https://fetch.spec.whatwg.org/#concept-response-location-url -function responseLocationURL (response, requestFragment) { - // 1. If response’s status is not a redirect status, then return null. - if (!redirectStatusSet.has(response.status)) { - return null + // 12. If httpRequest’s header list contains `Range`, then set response’s + // range-requested flag. + if (httpRequest.headersList.contains('range')) { + response.rangeRequested = true } - // 2. Let location be the result of extracting header list values given - // `Location` and response’s header list. - let location = response.headersList.get('location') + // 13. Set response’s request-includes-credentials to includeCredentials. + response.requestIncludesCredentials = includeCredentials - // 3. If location is a header value, then set location to the result of - // parsing location with response’s URL. - if (location !== null && isValidHeaderValue(location)) { - location = new URL(location, responseURL(response)) - } + // 14. If response’s status is 401, httpRequest’s response tainting is not + // "cors", includeCredentials is true, and request’s window is an environment + // settings object, then: + // TODO - // 4. If location is a URL whose fragment is null, then set location’s - // fragment to requestFragment. - if (location && !location.hash) { - location.hash = requestFragment - } + // 15. If response’s status is 407, then: + if (response.status === 407) { + // 1. If request’s window is "no-window", then return a network error. + if (request.window === 'no-window') { + return makeNetworkError() + } - // 5. Return location. - return location -} + // 2. ??? -/** @returns {URL} */ -function requestCurrentURL (request) { - return request.urlList[request.urlList.length - 1] -} + // 3. If fetchParams is canceled, then return the appropriate network error for fetchParams. + if (isCancelled(fetchParams)) { + return makeAppropriateNetworkError(fetchParams) + } -function requestBadPort (request) { - // 1. Let url be request’s current URL. - const url = requestCurrentURL(request) + // 4. Prompt the end user as appropriate in request’s window and store + // the result as a proxy-authentication entry. [HTTP-AUTH] + // TODO: Invoke some kind of callback? - // 2. If url’s scheme is an HTTP(S) scheme and url’s port is a bad port, - // then return blocked. - if (urlIsHttpHttpsScheme(url) && badPortsSet.has(url.port)) { - return 'blocked' + // 5. Set response to the result of running HTTP-network-or-cache fetch given + // fetchParams. + // TODO + return makeNetworkError('proxy authentication required') } - // 3. Return allowed. - return 'allowed' -} - -function isErrorLike (object) { - return object instanceof Error || ( - object?.constructor?.name === 'Error' || - object?.constructor?.name === 'DOMException' - ) -} + // 16. If all of the following are true + if ( + // response’s status is 421 + response.status === 421 && + // isNewConnectionFetch is false + !isNewConnectionFetch && + // request’s body is null, or request’s body is non-null and request’s body’s source is non-null + (request.body == null || request.body.source != null) + ) { + // then: -// Check whether |statusText| is a ByteString and -// matches the Reason-Phrase token production. -// RFC 2616: https://tools.ietf.org/html/rfc2616 -// RFC 7230: https://tools.ietf.org/html/rfc7230 -// "reason-phrase = *( HTAB / SP / VCHAR / obs-text )" -// https://github.com/chromium/chromium/blob/94.0.4604.1/third_party/blink/renderer/core/fetch/response.cc#L116 -function isValidReasonPhrase (statusText) { - for (let i = 0; i < statusText.length; ++i) { - const c = statusText.charCodeAt(i) - if ( - !( - ( - c === 0x09 || // HTAB - (c >= 0x20 && c <= 0x7e) || // SP / VCHAR - (c >= 0x80 && c <= 0xff) - ) // obs-text - ) - ) { - return false + // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams. + if (isCancelled(fetchParams)) { + return makeAppropriateNetworkError(fetchParams) } - } - return true -} -/** - * @see https://tools.ietf.org/html/rfc7230#section-3.2.6 - * @param {number} c - */ -function isTokenCharCode (c) { - switch (c) { - case 0x22: - case 0x28: - case 0x29: - case 0x2c: - case 0x2f: - case 0x3a: - case 0x3b: - case 0x3c: - case 0x3d: - case 0x3e: - case 0x3f: - case 0x40: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x7b: - case 0x7d: - // DQUOTE and "(),/:;<=>?@[\]{}" - return false - default: - // VCHAR %x21-7E - return c >= 0x21 && c <= 0x7e - } -} + // 2. Set response to the result of running HTTP-network-or-cache + // fetch given fetchParams, isAuthenticationFetch, and true. -/** - * @param {string} characters - */ -function isValidHTTPToken (characters) { - if (characters.length === 0) { - return false + // TODO (spec): The spec doesn't specify this but we need to cancel + // the active response before we can start a new one. + // https://github.com/whatwg/fetch/issues/1293 + fetchParams.controller.connection.destroy() + + response = await httpNetworkOrCacheFetch( + fetchParams, + isAuthenticationFetch, + true + ) } - for (let i = 0; i < characters.length; ++i) { - if (!isTokenCharCode(characters.charCodeAt(i))) { - return false - } + + // 17. If isAuthenticationFetch is true, then create an authentication entry + if (isAuthenticationFetch) { + // TODO } - return true + + // 18. Return response. + return response } -/** - * @see https://fetch.spec.whatwg.org/#header-name - * @param {string} potentialValue - */ -function isValidHeaderName (potentialValue) { - return isValidHTTPToken(potentialValue) -} - -/** - * @see https://fetch.spec.whatwg.org/#header-value - * @param {string} potentialValue - */ -function isValidHeaderValue (potentialValue) { - // - Has no leading or trailing HTTP tab or space bytes. - // - Contains no 0x00 (NUL) or HTTP newline bytes. - if ( - potentialValue.startsWith('\t') || - potentialValue.startsWith(' ') || - potentialValue.endsWith('\t') || - potentialValue.endsWith(' ') - ) { - return false - } +// https://fetch.spec.whatwg.org/#http-network-fetch +async function httpNetworkFetch ( + fetchParams, + includeCredentials = false, + forceNewConnection = false +) { + assert(!fetchParams.controller.connection || fetchParams.controller.connection.destroyed) - if ( - potentialValue.includes('\0') || - potentialValue.includes('\r') || - potentialValue.includes('\n') - ) { - return false + fetchParams.controller.connection = { + abort: null, + destroyed: false, + destroy (err) { + if (!this.destroyed) { + this.destroyed = true + this.abort?.(err ?? new DOMException('The operation was aborted.', 'AbortError')) + } + } } - return true -} - -// https://w3c.github.io/webappsec-referrer-policy/#set-requests-referrer-policy-on-redirect -function setRequestReferrerPolicyOnRedirect (request, actualResponse) { - // Given a request request and a response actualResponse, this algorithm - // updates request’s referrer policy according to the Referrer-Policy - // header (if any) in actualResponse. + // 1. Let request be fetchParams’s request. + const request = fetchParams.request - // 1. Let policy be the result of executing § 8.1 Parse a referrer policy - // from a Referrer-Policy header on actualResponse. + // 2. Let response be null. + let response = null - // 8.1 Parse a referrer policy from a Referrer-Policy header - // 1. Let policy-tokens be the result of extracting header list values given `Referrer-Policy` and response’s header list. - const { headersList } = actualResponse - // 2. Let policy be the empty string. - // 3. For each token in policy-tokens, if token is a referrer policy and token is not the empty string, then set policy to token. - // 4. Return policy. - const policyHeader = (headersList.get('referrer-policy') ?? '').split(',') + // 3. Let timingInfo be fetchParams’s timing info. + const timingInfo = fetchParams.timingInfo - // Note: As the referrer-policy can contain multiple policies - // separated by comma, we need to loop through all of them - // and pick the first valid one. - // Ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy#specify_a_fallback_policy - let policy = '' - if (policyHeader.length > 0) { - // The right-most policy takes precedence. - // The left-most policy is the fallback. - for (let i = policyHeader.length; i !== 0; i--) { - const token = policyHeader[i - 1].trim() - if (referrerPolicyTokens.has(token)) { - policy = token - break - } - } - } + // 4. Let httpCache be the result of determining the HTTP cache partition, + // given request. + // TODO: cache + const httpCache = null - // 2. If policy is not the empty string, then set request’s referrer policy to policy. - if (policy !== '') { - request.referrerPolicy = policy + // 5. If httpCache is null, then set request’s cache mode to "no-store". + if (httpCache == null) { + request.cache = 'no-store' } -} - -// https://fetch.spec.whatwg.org/#cross-origin-resource-policy-check -function crossOriginResourcePolicyCheck () { - // TODO - return 'allowed' -} - -// https://fetch.spec.whatwg.org/#concept-cors-check -function corsCheck () { - // TODO - return 'success' -} -// https://fetch.spec.whatwg.org/#concept-tao-check -function TAOCheck () { + // 6. Let networkPartitionKey be the result of determining the network + // partition key given request. // TODO - return 'success' -} -function appendFetchMetadata (httpRequest) { - // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-dest-header - // TODO + // 7. Let newConnection be "yes" if forceNewConnection is true; otherwise + // "no". + const newConnection = forceNewConnection ? 'yes' : 'no' // eslint-disable-line no-unused-vars - // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-mode-header + // 8. Switch on request’s mode: + if (request.mode === 'websocket') { + // Let connection be the result of obtaining a WebSocket connection, + // given request’s current URL. + // TODO + } else { + // Let connection be the result of obtaining a connection, given + // networkPartitionKey, request’s current URL’s origin, + // includeCredentials, and forceNewConnection. + // TODO + } - // 1. Assert: r’s url is a potentially trustworthy URL. - // TODO + // 9. Run these steps, but abort when the ongoing fetch is terminated: - // 2. Let header be a Structured Header whose value is a token. - let header = null + // 1. If connection is failure, then return a network error. - // 3. Set header’s value to r’s mode. - header = httpRequest.mode + // 2. Set timingInfo’s final connection timing info to the result of + // calling clamp and coarsen connection timing info with connection’s + // timing info, timingInfo’s post-redirect start time, and fetchParams’s + // cross-origin isolated capability. - // 4. Set a structured field value `Sec-Fetch-Mode`/header in r’s header list. - httpRequest.headersList.set('sec-fetch-mode', header) + // 3. If connection is not an HTTP/2 connection, request’s body is non-null, + // and request’s body’s source is null, then append (`Transfer-Encoding`, + // `chunked`) to request’s header list. - // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-site-header - // TODO + // 4. Set timingInfo’s final network-request start time to the coarsened + // shared current time given fetchParams’s cross-origin isolated + // capability. - // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-user-header - // TODO -} + // 5. Set response to the result of making an HTTP request over connection + // using request with the following caveats: -// https://fetch.spec.whatwg.org/#append-a-request-origin-header -function appendRequestOriginHeader (request) { - // 1. Let serializedOrigin be the result of byte-serializing a request origin with request. - let serializedOrigin = request.origin + // - Follow the relevant requirements from HTTP. [HTTP] [HTTP-SEMANTICS] + // [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH] - // 2. If request’s response tainting is "cors" or request’s mode is "websocket", then append (`Origin`, serializedOrigin) to request’s header list. - if (request.responseTainting === 'cors' || request.mode === 'websocket') { - if (serializedOrigin) { - request.headersList.append('origin', serializedOrigin) - } + // - If request’s body is non-null, and request’s body’s source is null, + // then the user agent may have a buffer of up to 64 kibibytes and store + // a part of request’s body in that buffer. If the user agent reads from + // request’s body beyond that buffer’s size and the user agent needs to + // resend request, then instead return a network error. - // 3. Otherwise, if request’s method is neither `GET` nor `HEAD`, then: - } else if (request.method !== 'GET' && request.method !== 'HEAD') { - // 1. Switch on request’s referrer policy: - switch (request.referrerPolicy) { - case 'no-referrer': - // Set serializedOrigin to `null`. - serializedOrigin = null - break - case 'no-referrer-when-downgrade': - case 'strict-origin': - case 'strict-origin-when-cross-origin': - // If request’s origin is a tuple origin, its scheme is "https", and request’s current URL’s scheme is not "https", then set serializedOrigin to `null`. - if (request.origin && urlHasHttpsScheme(request.origin) && !urlHasHttpsScheme(requestCurrentURL(request))) { - serializedOrigin = null - } - break - case 'same-origin': - // If request’s origin is not same origin with request’s current URL’s origin, then set serializedOrigin to `null`. - if (!sameOrigin(request, requestCurrentURL(request))) { - serializedOrigin = null - } - break - default: - // Do nothing. - } + // - Set timingInfo’s final network-response start time to the coarsened + // shared current time given fetchParams’s cross-origin isolated capability, + // immediately after the user agent’s HTTP parser receives the first byte + // of the response (e.g., frame header bytes for HTTP/2 or response status + // line for HTTP/1.x). - if (serializedOrigin) { - // 2. Append (`Origin`, serializedOrigin) to request’s header list. - request.headersList.append('origin', serializedOrigin) - } - } -} + // - Wait until all the headers are transmitted. -function coarsenedSharedCurrentTime (crossOriginIsolatedCapability) { - // TODO - return performance.now() -} + // - Any responses whose status is in the range 100 to 199, inclusive, + // and is not 101, are to be ignored, except for the purposes of setting + // timingInfo’s final network-response start time above. -// https://fetch.spec.whatwg.org/#create-an-opaque-timing-info -function createOpaqueTimingInfo (timingInfo) { - return { - startTime: timingInfo.startTime ?? 0, - redirectStartTime: 0, - redirectEndTime: 0, - postRedirectStartTime: timingInfo.startTime ?? 0, - finalServiceWorkerStartTime: 0, - finalNetworkResponseStartTime: 0, - finalNetworkRequestStartTime: 0, - endTime: 0, - encodedBodySize: 0, - decodedBodySize: 0, - finalConnectionTimingInfo: null - } -} + // - If request’s header list contains `Transfer-Encoding`/`chunked` and + // response is transferred via HTTP/1.0 or older, then return a network + // error. -// https://html.spec.whatwg.org/multipage/origin.html#policy-container -function makePolicyContainer () { - // Note: the fetch spec doesn't make use of embedder policy or CSP list - return { - referrerPolicy: 'strict-origin-when-cross-origin' - } -} + // - If the HTTP request results in a TLS client certificate dialog, then: -// https://html.spec.whatwg.org/multipage/origin.html#clone-a-policy-container -function clonePolicyContainer (policyContainer) { - return { - referrerPolicy: policyContainer.referrerPolicy - } -} + // 1. If request’s window is an environment settings object, make the + // dialog available in request’s window. -// https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer -function determineRequestsReferrer (request) { - // 1. Let policy be request's referrer policy. - const policy = request.referrerPolicy + // 2. Otherwise, return a network error. - // Note: policy cannot (shouldn't) be null or an empty string. - assert(policy) - - // 2. Let environment be request’s client. - - let referrerSource = null + // To transmit request’s body body, run these steps: + let requestBody = null + // 1. If body is null and fetchParams’s process request end-of-body is + // non-null, then queue a fetch task given fetchParams’s process request + // end-of-body and fetchParams’s task destination. + if (request.body == null && fetchParams.processRequestEndOfBody) { + queueMicrotask(() => fetchParams.processRequestEndOfBody()) + } else if (request.body != null) { + // 2. Otherwise, if body is non-null: - // 3. Switch on request’s referrer: - if (request.referrer === 'client') { - // Note: node isn't a browser and doesn't implement document/iframes, - // so we bypass this step and replace it with our own. + // 1. Let processBodyChunk given bytes be these steps: + const processBodyChunk = async function * (bytes) { + // 1. If the ongoing fetch is terminated, then abort these steps. + if (isCancelled(fetchParams)) { + return + } - const globalOrigin = getGlobalOrigin() + // 2. Run this step in parallel: transmit bytes. + yield bytes - if (!globalOrigin || globalOrigin.origin === 'null') { - return 'no-referrer' + // 3. If fetchParams’s process request body is non-null, then run + // fetchParams’s process request body given bytes’s length. + fetchParams.processRequestBodyChunkLength?.(bytes.byteLength) } - // note: we need to clone it as it's mutated - referrerSource = new URL(globalOrigin) - } else if (request.referrer instanceof URL) { - // Let referrerSource be request’s referrer. - referrerSource = request.referrer - } - - // 4. Let request’s referrerURL be the result of stripping referrerSource for - // use as a referrer. - let referrerURL = stripURLForReferrer(referrerSource) - - // 5. Let referrerOrigin be the result of stripping referrerSource for use as - // a referrer, with the origin-only flag set to true. - const referrerOrigin = stripURLForReferrer(referrerSource, true) - - // 6. If the result of serializing referrerURL is a string whose length is - // greater than 4096, set referrerURL to referrerOrigin. - if (referrerURL.toString().length > 4096) { - referrerURL = referrerOrigin - } - - const areSameOrigin = sameOrigin(request, referrerURL) - const isNonPotentiallyTrustWorthy = isURLPotentiallyTrustworthy(referrerURL) && - !isURLPotentiallyTrustworthy(request.url) - - // 8. Execute the switch statements corresponding to the value of policy: - switch (policy) { - case 'origin': return referrerOrigin != null ? referrerOrigin : stripURLForReferrer(referrerSource, true) - case 'unsafe-url': return referrerURL - case 'same-origin': - return areSameOrigin ? referrerOrigin : 'no-referrer' - case 'origin-when-cross-origin': - return areSameOrigin ? referrerURL : referrerOrigin - case 'strict-origin-when-cross-origin': { - const currentURL = requestCurrentURL(request) + // 2. Let processEndOfBody be these steps: + const processEndOfBody = () => { + // 1. If fetchParams is canceled, then abort these steps. + if (isCancelled(fetchParams)) { + return + } - // 1. If the origin of referrerURL and the origin of request’s current - // URL are the same, then return referrerURL. - if (sameOrigin(referrerURL, currentURL)) { - return referrerURL + // 2. If fetchParams’s process request end-of-body is non-null, + // then run fetchParams’s process request end-of-body. + if (fetchParams.processRequestEndOfBody) { + fetchParams.processRequestEndOfBody() } + } - // 2. If referrerURL is a potentially trustworthy URL and request’s - // current URL is not a potentially trustworthy URL, then return no - // referrer. - if (isURLPotentiallyTrustworthy(referrerURL) && !isURLPotentiallyTrustworthy(currentURL)) { - return 'no-referrer' + // 3. Let processBodyError given e be these steps: + const processBodyError = (e) => { + // 1. If fetchParams is canceled, then abort these steps. + if (isCancelled(fetchParams)) { + return } - // 3. Return referrerOrigin. - return referrerOrigin + // 2. If e is an "AbortError" DOMException, then abort fetchParams’s controller. + if (e.name === 'AbortError') { + fetchParams.controller.abort() + } else { + fetchParams.controller.terminate(e) + } } - case 'strict-origin': // eslint-disable-line - /** - * 1. If referrerURL is a potentially trustworthy URL and - * request’s current URL is not a potentially trustworthy URL, - * then return no referrer. - * 2. Return referrerOrigin - */ - case 'no-referrer-when-downgrade': // eslint-disable-line - /** - * 1. If referrerURL is a potentially trustworthy URL and - * request’s current URL is not a potentially trustworthy URL, - * then return no referrer. - * 2. Return referrerOrigin - */ - default: // eslint-disable-line - return isNonPotentiallyTrustWorthy ? 'no-referrer' : referrerOrigin + // 4. Incrementally read request’s body given processBodyChunk, processEndOfBody, + // processBodyError, and fetchParams’s task destination. + requestBody = (async function * () { + try { + for await (const bytes of request.body.stream) { + yield * processBodyChunk(bytes) + } + processEndOfBody() + } catch (err) { + processBodyError(err) + } + })() } -} -/** - * @see https://w3c.github.io/webappsec-referrer-policy/#strip-url - * @param {URL} url - * @param {boolean|undefined} originOnly - */ -function stripURLForReferrer (url, originOnly) { - // 1. Assert: url is a URL. - assert(url instanceof URL) + try { + // socket is only provided for websockets + const { body, status, statusText, headersList, socket } = await dispatch({ body: requestBody }) - // 2. If url’s scheme is a local scheme, then return no referrer. - if (url.protocol === 'file:' || url.protocol === 'about:' || url.protocol === 'blank:') { - return 'no-referrer' - } + if (socket) { + response = makeResponse({ status, statusText, headersList, socket }) + } else { + const iterator = body[Symbol.asyncIterator]() + fetchParams.controller.next = () => iterator.next() - // 3. Set url’s username to the empty string. - url.username = '' + response = makeResponse({ status, statusText, headersList }) + } + } catch (err) { + // 10. If aborted, then: + if (err.name === 'AbortError') { + // 1. If connection uses HTTP/2, then transmit an RST_STREAM frame. + fetchParams.controller.connection.destroy() - // 4. Set url’s password to the empty string. - url.password = '' + // 2. Return the appropriate network error for fetchParams. + return makeAppropriateNetworkError(fetchParams, err) + } - // 5. Set url’s fragment to null. - url.hash = '' + return makeNetworkError(err) + } - // 6. If the origin-only flag is true, then: - if (originOnly) { - // 1. Set url’s path to « the empty string ». - url.pathname = '' + // 11. Let pullAlgorithm be an action that resumes the ongoing fetch + // if it is suspended. + const pullAlgorithm = () => { + fetchParams.controller.resume() + } - // 2. Set url’s query to null. - url.search = '' + // 12. Let cancelAlgorithm be an algorithm that aborts fetchParams’s + // controller with reason, given reason. + const cancelAlgorithm = (reason) => { + fetchParams.controller.abort(reason) } - // 7. Return url. - return url -} + // 13. Let highWaterMark be a non-negative, non-NaN number, chosen by + // the user agent. + // TODO -function isURLPotentiallyTrustworthy (url) { - if (!(url instanceof URL)) { - return false - } + // 14. Let sizeAlgorithm be an algorithm that accepts a chunk object + // and returns a non-negative, non-NaN, non-infinite number, chosen by the user agent. + // TODO - // If child of about, return true - if (url.href === 'about:blank' || url.href === 'about:srcdoc') { - return true + // 15. Let stream be a new ReadableStream. + // 16. Set up stream with pullAlgorithm set to pullAlgorithm, + // cancelAlgorithm set to cancelAlgorithm, highWaterMark set to + // highWaterMark, and sizeAlgorithm set to sizeAlgorithm. + if (!ReadableStream) { + ReadableStream = (__nccwpck_require__(5356).ReadableStream) } - // If scheme is data, return true - if (url.protocol === 'data:') return true + const stream = new ReadableStream( + { + async start (controller) { + fetchParams.controller.controller = controller + }, + async pull (controller) { + await pullAlgorithm(controller) + }, + async cancel (reason) { + await cancelAlgorithm(reason) + } + }, + { + highWaterMark: 0, + size () { + return 1 + } + } + ) - // If file, return true - if (url.protocol === 'file:') return true + // 17. Run these steps, but abort when the ongoing fetch is terminated: - return isOriginPotentiallyTrustworthy(url.origin) + // 1. Set response’s body to a new body whose stream is stream. + response.body = { stream } - function isOriginPotentiallyTrustworthy (origin) { - // If origin is explicitly null, return false - if (origin == null || origin === 'null') return false + // 2. If response is not a network error and request’s cache mode is + // not "no-store", then update response in httpCache for request. + // TODO - const originAsURL = new URL(origin) + // 3. If includeCredentials is true and the user agent is not configured + // to block cookies for request (see section 7 of [COOKIES]), then run the + // "set-cookie-string" parsing algorithm (see section 5.2 of [COOKIES]) on + // the value of each header whose name is a byte-case-insensitive match for + // `Set-Cookie` in response’s header list, if any, and request’s current URL. + // TODO - // If secure, return true - if (originAsURL.protocol === 'https:' || originAsURL.protocol === 'wss:') { - return true - } + // 18. If aborted, then: + // TODO - // If localhost or variants, return true - if (/^127(?:\.[0-9]+){0,2}\.[0-9]+$|^\[(?:0*:)*?:?0*1\]$/.test(originAsURL.hostname) || - (originAsURL.hostname === 'localhost' || originAsURL.hostname.includes('localhost.')) || - (originAsURL.hostname.endsWith('.localhost'))) { - return true - } + // 19. Run these steps in parallel: - // If any other, return false - return false - } -} + // 1. Run these steps, but abort when fetchParams is canceled: + fetchParams.controller.on('terminated', onAborted) + fetchParams.controller.resume = async () => { + // 1. While true + while (true) { + // 1-3. See onData... -/** - * @see https://w3c.github.io/webappsec-subresource-integrity/#does-response-match-metadatalist - * @param {Uint8Array} bytes - * @param {string} metadataList - */ -function bytesMatch (bytes, metadataList) { - // If node is not built with OpenSSL support, we cannot check - // a request's integrity, so allow it by default (the spec will - // allow requests if an invalid hash is given, as precedence). - /* istanbul ignore if: only if node is built with --without-ssl */ - if (crypto === undefined) { - return true - } + // 4. Set bytes to the result of handling content codings given + // codings and bytes. + let bytes + let isFailure + try { + const { done, value } = await fetchParams.controller.next() - // 1. Let parsedMetadata be the result of parsing metadataList. - const parsedMetadata = parseMetadata(metadataList) + if (isAborted(fetchParams)) { + break + } - // 2. If parsedMetadata is no metadata, return true. - if (parsedMetadata === 'no metadata') { - return true - } + bytes = done ? undefined : value + } catch (err) { + if (fetchParams.controller.ended && !timingInfo.encodedBodySize) { + // zlib doesn't like empty streams. + bytes = undefined + } else { + bytes = err - // 3. If parsedMetadata is the empty set, return true. - if (parsedMetadata.length === 0) { - return true - } + // err may be propagated from the result of calling readablestream.cancel, + // which might not be an error. https://github.com/nodejs/undici/issues/2009 + isFailure = true + } + } - // 4. Let metadata be the result of getting the strongest - // metadata from parsedMetadata. - const list = parsedMetadata.sort((c, d) => d.algo.localeCompare(c.algo)) - // get the strongest algorithm - const strongest = list[0].algo - // get all entries that use the strongest algorithm; ignore weaker - const metadata = list.filter((item) => item.algo === strongest) + if (bytes === undefined) { + // 2. Otherwise, if the bytes transmission for response’s message + // body is done normally and stream is readable, then close + // stream, finalize response for fetchParams and response, and + // abort these in-parallel steps. + readableStreamClose(fetchParams.controller.controller) - // 5. For each item in metadata: - for (const item of metadata) { - // 1. Let algorithm be the alg component of item. - const algorithm = item.algo + finalizeResponse(fetchParams, response) - // 2. Let expectedValue be the val component of item. - let expectedValue = item.hash + return + } - // See https://github.com/web-platform-tests/wpt/commit/e4c5cc7a5e48093220528dfdd1c4012dc3837a0e - // "be liberal with padding". This is annoying, and it's not even in the spec. + // 5. Increase timingInfo’s decoded body size by bytes’s length. + timingInfo.decodedBodySize += bytes?.byteLength ?? 0 - if (expectedValue.endsWith('==')) { - expectedValue = expectedValue.slice(0, -2) - } + // 6. If bytes is failure, then terminate fetchParams’s controller. + if (isFailure) { + fetchParams.controller.terminate(bytes) + return + } - // 3. Let actualValue be the result of applying algorithm to bytes. - let actualValue = crypto.createHash(algorithm).update(bytes).digest('base64') + // 7. Enqueue a Uint8Array wrapping an ArrayBuffer containing bytes + // into stream. + fetchParams.controller.controller.enqueue(new Uint8Array(bytes)) - if (actualValue.endsWith('==')) { - actualValue = actualValue.slice(0, -2) - } + // 8. If stream is errored, then terminate the ongoing fetch. + if (isErrored(stream)) { + fetchParams.controller.terminate() + return + } - // 4. If actualValue is a case-sensitive match for expectedValue, - // return true. - if (actualValue === expectedValue) { - return true + // 9. If stream doesn’t need more data ask the user agent to suspend + // the ongoing fetch. + if (!fetchParams.controller.controller.desiredSize) { + return + } } + } - let actualBase64URL = crypto.createHash(algorithm).update(bytes).digest('base64url') + // 2. If aborted, then: + function onAborted (reason) { + // 2. If fetchParams is aborted, then: + if (isAborted(fetchParams)) { + // 1. Set response’s aborted flag. + response.aborted = true - if (actualBase64URL.endsWith('==')) { - actualBase64URL = actualBase64URL.slice(0, -2) + // 2. If stream is readable, then error stream with the result of + // deserialize a serialized abort reason given fetchParams’s + // controller’s serialized abort reason and an + // implementation-defined realm. + if (isReadable(stream)) { + fetchParams.controller.controller.error( + fetchParams.controller.serializedAbortReason + ) + } + } else { + // 3. Otherwise, if stream is readable, error stream with a TypeError. + if (isReadable(stream)) { + fetchParams.controller.controller.error(new TypeError('terminated', { + cause: isErrorLike(reason) ? reason : undefined + })) + } } - if (actualBase64URL === expectedValue) { - return true - } + // 4. If connection uses HTTP/2, then transmit an RST_STREAM frame. + // 5. Otherwise, the user agent should close connection unless it would be bad for performance to do so. + fetchParams.controller.connection.destroy() } - // 6. Return false. - return false -} + // 20. Return response. + return response -// https://w3c.github.io/webappsec-subresource-integrity/#grammardef-hash-with-options -// https://www.w3.org/TR/CSP2/#source-list-syntax -// https://www.rfc-editor.org/rfc/rfc5234#appendix-B.1 -const parseHashWithOptions = /((?sha256|sha384|sha512)-(?[A-z0-9+/]{1}.*={0,2}))( +[\x21-\x7e]?)?/i + async function dispatch ({ body }) { + const url = requestCurrentURL(request) + /** @type {import('../..').Agent} */ + const agent = fetchParams.controller.dispatcher -/** - * @see https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata - * @param {string} metadata - */ -function parseMetadata (metadata) { - // 1. Let result be the empty set. - /** @type {{ algo: string, hash: string }[]} */ - const result = [] + return new Promise((resolve, reject) => agent.dispatch( + { + path: url.pathname + url.search, + origin: url.origin, + method: request.method, + body: fetchParams.controller.dispatcher.isMockActive ? request.body && (request.body.source || request.body.stream) : body, + headers: request.headersList.entries, + maxRedirections: 0, + upgrade: request.mode === 'websocket' ? 'websocket' : undefined + }, + { + body: null, + abort: null, - // 2. Let empty be equal to true. - let empty = true + onConnect (abort) { + // TODO (fix): Do we need connection here? + const { connection } = fetchParams.controller - const supportedHashes = crypto.getHashes() + if (connection.destroyed) { + abort(new DOMException('The operation was aborted.', 'AbortError')) + } else { + fetchParams.controller.on('terminated', abort) + this.abort = connection.abort = abort + } + }, - // 3. For each token returned by splitting metadata on spaces: - for (const token of metadata.split(' ')) { - // 1. Set empty to false. - empty = false + onHeaders (status, headersList, resume, statusText) { + if (status < 200) { + return + } - // 2. Parse token as a hash-with-options. - const parsedToken = parseHashWithOptions.exec(token) + let codings = [] + let location = '' - // 3. If token does not parse, continue to the next token. - if (parsedToken === null || parsedToken.groups === undefined) { - // Note: Chromium blocks the request at this point, but Firefox - // gives a warning that an invalid integrity was given. The - // correct behavior is to ignore these, and subsequently not - // check the integrity of the resource. - continue - } + const headers = new Headers() - // 4. Let algorithm be the hash-algo component of token. - const algorithm = parsedToken.groups.algo + // For H2, the headers are a plain JS object + // We distinguish between them and iterate accordingly + if (Array.isArray(headersList)) { + for (let n = 0; n < headersList.length; n += 2) { + const key = headersList[n + 0].toString('latin1') + const val = headersList[n + 1].toString('latin1') + if (key.toLowerCase() === 'content-encoding') { + // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 + // "All content-coding values are case-insensitive..." + codings = val.toLowerCase().split(',').map((x) => x.trim()) + } else if (key.toLowerCase() === 'location') { + location = val + } - // 5. If algorithm is a hash function recognized by the user - // agent, add the parsed token to result. - if (supportedHashes.includes(algorithm.toLowerCase())) { - result.push(parsedToken.groups) - } - } + headers[kHeadersList].append(key, val) + } + } else { + const keys = Object.keys(headersList) + for (const key of keys) { + const val = headersList[key] + if (key.toLowerCase() === 'content-encoding') { + // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 + // "All content-coding values are case-insensitive..." + codings = val.toLowerCase().split(',').map((x) => x.trim()).reverse() + } else if (key.toLowerCase() === 'location') { + location = val + } - // 4. Return no metadata if empty is true, otherwise return result. - if (empty === true) { - return 'no metadata' - } + headers[kHeadersList].append(key, val) + } + } - return result -} + this.body = new Readable({ read: resume }) -// https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request -function tryUpgradeRequestToAPotentiallyTrustworthyURL (request) { - // TODO -} + const decoders = [] -/** - * @link {https://html.spec.whatwg.org/multipage/origin.html#same-origin} - * @param {URL} A - * @param {URL} B - */ -function sameOrigin (A, B) { - // 1. If A and B are the same opaque origin, then return true. - if (A.origin === B.origin && A.origin === 'null') { - return true - } + const willFollow = request.redirect === 'follow' && + location && + redirectStatusSet.has(status) - // 2. If A and B are both tuple origins and their schemes, - // hosts, and port are identical, then return true. - if (A.protocol === B.protocol && A.hostname === B.hostname && A.port === B.port) { - return true - } + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding + if (request.method !== 'HEAD' && request.method !== 'CONNECT' && !nullBodyStatus.includes(status) && !willFollow) { + for (const coding of codings) { + // https://www.rfc-editor.org/rfc/rfc9112.html#section-7.2 + if (coding === 'x-gzip' || coding === 'gzip') { + decoders.push(zlib.createGunzip({ + // Be less strict when decoding compressed responses, since sometimes + // servers send slightly invalid responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + flush: zlib.constants.Z_SYNC_FLUSH, + finishFlush: zlib.constants.Z_SYNC_FLUSH + })) + } else if (coding === 'deflate') { + decoders.push(zlib.createInflate()) + } else if (coding === 'br') { + decoders.push(zlib.createBrotliDecompress()) + } else { + decoders.length = 0 + break + } + } + } - // 3. Return false. - return false -} + resolve({ + status, + statusText, + headersList: headers[kHeadersList], + body: decoders.length + ? pipeline(this.body, ...decoders, () => { }) + : this.body.on('error', () => {}) + }) -function createDeferredPromise () { - let res - let rej - const promise = new Promise((resolve, reject) => { - res = resolve - rej = reject - }) + return true + }, - return { promise, resolve: res, reject: rej } -} + onData (chunk) { + if (fetchParams.controller.dump) { + return + } -function isAborted (fetchParams) { - return fetchParams.controller.state === 'aborted' -} + // 1. If one or more bytes have been transmitted from response’s + // message body, then: -function isCancelled (fetchParams) { - return fetchParams.controller.state === 'aborted' || - fetchParams.controller.state === 'terminated' -} + // 1. Let bytes be the transmitted bytes. + const bytes = chunk -const normalizeMethodRecord = { - delete: 'DELETE', - DELETE: 'DELETE', - get: 'GET', - GET: 'GET', - head: 'HEAD', - HEAD: 'HEAD', - options: 'OPTIONS', - OPTIONS: 'OPTIONS', - post: 'POST', - POST: 'POST', - put: 'PUT', - PUT: 'PUT' -} + // 2. Let codings be the result of extracting header list values + // given `Content-Encoding` and response’s header list. + // See pullAlgorithm. -// Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`. -Object.setPrototypeOf(normalizeMethodRecord, null) + // 3. Increase timingInfo’s encoded body size by bytes’s length. + timingInfo.encodedBodySize += bytes.byteLength -/** - * @see https://fetch.spec.whatwg.org/#concept-method-normalize - * @param {string} method - */ -function normalizeMethod (method) { - return normalizeMethodRecord[method.toLowerCase()] ?? method -} + // 4. See pullAlgorithm... -// https://infra.spec.whatwg.org/#serialize-a-javascript-value-to-a-json-string -function serializeJavascriptValueToJSONString (value) { - // 1. Let result be ? Call(%JSON.stringify%, undefined, « value »). - const result = JSON.stringify(value) + return this.body.push(bytes) + }, - // 2. If result is undefined, then throw a TypeError. - if (result === undefined) { - throw new TypeError('Value is not JSON serializable') - } + onComplete () { + if (this.abort) { + fetchParams.controller.off('terminated', this.abort) + } - // 3. Assert: result is a string. - assert(typeof result === 'string') + fetchParams.controller.ended = true - // 4. Return result. - return result -} + this.body.push(null) + }, -// https://tc39.es/ecma262/#sec-%25iteratorprototype%25-object -const esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())) + onError (error) { + if (this.abort) { + fetchParams.controller.off('terminated', this.abort) + } -/** - * @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object - * @param {() => unknown[]} iterator - * @param {string} name name of the instance - * @param {'key'|'value'|'key+value'} kind - */ -function makeIterator (iterator, name, kind) { - const object = { - index: 0, - kind, - target: iterator - } + this.body?.destroy(error) - const i = { - next () { - // 1. Let interface be the interface for which the iterator prototype object exists. + fetchParams.controller.terminate(error) - // 2. Let thisValue be the this value. + reject(error) + }, - // 3. Let object be ? ToObject(thisValue). + onUpgrade (status, headersList, socket) { + if (status !== 101) { + return + } - // 4. If object is a platform object, then perform a security - // check, passing: + const headers = new Headers() - // 5. If object is not a default iterator object for interface, - // then throw a TypeError. - if (Object.getPrototypeOf(this) !== i) { - throw new TypeError( - `'next' called on an object that does not implement interface ${name} Iterator.` - ) - } + for (let n = 0; n < headersList.length; n += 2) { + const key = headersList[n + 0].toString('latin1') + const val = headersList[n + 1].toString('latin1') - // 6. Let index be object’s index. - // 7. Let kind be object’s kind. - // 8. Let values be object’s target's value pairs to iterate over. - const { index, kind, target } = object - const values = target() + headers[kHeadersList].append(key, val) + } - // 9. Let len be the length of values. - const len = values.length + resolve({ + status, + statusText: STATUS_CODES[status], + headersList: headers[kHeadersList], + socket + }) - // 10. If index is greater than or equal to len, then return - // CreateIterResultObject(undefined, true). - if (index >= len) { - return { value: undefined, done: true } + return true + } } + )) + } +} - // 11. Let pair be the entry in values at index index. - const pair = values[index] +module.exports = { + fetch, + Fetch, + fetching, + finalizeAndReportTiming +} - // 12. Set object’s index to index + 1. - object.index = index + 1 - // 13. Return the iterator result for pair and kind. - return iteratorResult(pair, kind) - }, - // The class string of an iterator prototype object for a given interface is the - // result of concatenating the identifier of the interface and the string " Iterator". - [Symbol.toStringTag]: `${name} Iterator` - } +/***/ }), - // The [[Prototype]] internal slot of an iterator prototype object must be %IteratorPrototype%. - Object.setPrototypeOf(i, esIteratorPrototype) - // esIteratorPrototype needs to be the prototype of i - // which is the prototype of an empty object. Yes, it's confusing. - return Object.setPrototypeOf({}, i) -} +/***/ 8359: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -// https://webidl.spec.whatwg.org/#iterator-result -function iteratorResult (pair, kind) { - let result +"use strict"; +/* globals AbortController */ - // 1. Let result be a value determined by the value of kind: - switch (kind) { - case 'key': { - // 1. Let idlKey be pair’s key. - // 2. Let key be the result of converting idlKey to an - // ECMAScript value. - // 3. result is key. - result = pair[0] - break - } - case 'value': { - // 1. Let idlValue be pair’s value. - // 2. Let value be the result of converting idlValue to - // an ECMAScript value. - // 3. result is value. - result = pair[1] - break - } - case 'key+value': { - // 1. Let idlKey be pair’s key. - // 2. Let idlValue be pair’s value. - // 3. Let key be the result of converting idlKey to an - // ECMAScript value. - // 4. Let value be the result of converting idlValue to - // an ECMAScript value. - // 5. Let array be ! ArrayCreate(2). - // 6. Call ! CreateDataProperty(array, "0", key). - // 7. Call ! CreateDataProperty(array, "1", value). - // 8. result is array. - result = pair - break - } - } - // 2. Return CreateIterResultObject(result, false). - return { value: result, done: false } -} - -/** - * @see https://fetch.spec.whatwg.org/#body-fully-read - */ -async function fullyReadBody (body, processBody, processBodyError) { - // 1. If taskDestination is null, then set taskDestination to - // the result of starting a new parallel queue. - // 2. Let successSteps given a byte sequence bytes be to queue a - // fetch task to run processBody given bytes, with taskDestination. - const successSteps = processBody +const { extractBody, mixinBody, cloneBody } = __nccwpck_require__(1472) +const { Headers, fill: fillHeaders, HeadersList } = __nccwpck_require__(554) +const { FinalizationRegistry } = __nccwpck_require__(6436)() +const util = __nccwpck_require__(3983) +const { + isValidHTTPToken, + sameOrigin, + normalizeMethod, + makePolicyContainer, + normalizeMethodRecord +} = __nccwpck_require__(2538) +const { + forbiddenMethodsSet, + corsSafeListedMethodsSet, + referrerPolicy, + requestRedirect, + requestMode, + requestCredentials, + requestCache, + requestDuplex +} = __nccwpck_require__(1037) +const { kEnumerableProperty } = util +const { kHeaders, kSignal, kState, kGuard, kRealm } = __nccwpck_require__(5861) +const { webidl } = __nccwpck_require__(1744) +const { getGlobalOrigin } = __nccwpck_require__(1246) +const { URLSerializer } = __nccwpck_require__(685) +const { kHeadersList, kConstruct } = __nccwpck_require__(2785) +const assert = __nccwpck_require__(9491) +const { getMaxListeners, setMaxListeners, getEventListeners, defaultMaxListeners } = __nccwpck_require__(2361) - // 3. Let errorSteps be to queue a fetch task to run processBodyError, - // with taskDestination. - const errorSteps = processBodyError +let TransformStream = globalThis.TransformStream - // 4. Let reader be the result of getting a reader for body’s stream. - // If that threw an exception, then run errorSteps with that - // exception and return. - let reader +const kAbortController = Symbol('abortController') - try { - reader = body.stream.getReader() - } catch (e) { - errorSteps(e) - return - } +const requestFinalizer = new FinalizationRegistry(({ signal, abort }) => { + signal.removeEventListener('abort', abort) +}) - // 5. Read all bytes from reader, given successSteps and errorSteps. - try { - const result = await readAllBytes(reader) - successSteps(result) - } catch (e) { - errorSteps(e) - } -} +// https://fetch.spec.whatwg.org/#request-class +class Request { + // https://fetch.spec.whatwg.org/#dom-request + constructor (input, init = {}) { + if (input === kConstruct) { + return + } -/** @type {ReadableStream} */ -let ReadableStream = globalThis.ReadableStream + webidl.argumentLengthCheck(arguments, 1, { header: 'Request constructor' }) -function isReadableStreamLike (stream) { - if (!ReadableStream) { - ReadableStream = (__nccwpck_require__(5356).ReadableStream) - } + input = webidl.converters.RequestInfo(input) + init = webidl.converters.RequestInit(init) - return stream instanceof ReadableStream || ( - stream[Symbol.toStringTag] === 'ReadableStream' && - typeof stream.tee === 'function' - ) -} + // https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object + this[kRealm] = { + settingsObject: { + baseUrl: getGlobalOrigin(), + get origin () { + return this.baseUrl?.origin + }, + policyContainer: makePolicyContainer() + } + } -const MAXIMUM_ARGUMENT_LENGTH = 65535 + // 1. Let request be null. + let request = null -/** - * @see https://infra.spec.whatwg.org/#isomorphic-decode - * @param {number[]|Uint8Array} input - */ -function isomorphicDecode (input) { - // 1. To isomorphic decode a byte sequence input, return a string whose code point - // length is equal to input’s length and whose code points have the same values - // as the values of input’s bytes, in the same order. + // 2. Let fallbackMode be null. + let fallbackMode = null - if (input.length < MAXIMUM_ARGUMENT_LENGTH) { - return String.fromCharCode(...input) - } + // 3. Let baseURL be this’s relevant settings object’s API base URL. + const baseUrl = this[kRealm].settingsObject.baseUrl - return input.reduce((previous, current) => previous + String.fromCharCode(current), '') -} + // 4. Let signal be null. + let signal = null -/** - * @param {ReadableStreamController} controller - */ -function readableStreamClose (controller) { - try { - controller.close() - } catch (err) { - // TODO: add comment explaining why this error occurs. - if (!err.message.includes('Controller is already closed')) { - throw err - } - } -} + // 5. If input is a string, then: + if (typeof input === 'string') { + // 1. Let parsedURL be the result of parsing input with baseURL. + // 2. If parsedURL is failure, then throw a TypeError. + let parsedURL + try { + parsedURL = new URL(input, baseUrl) + } catch (err) { + throw new TypeError('Failed to parse URL from ' + input, { cause: err }) + } -/** - * @see https://infra.spec.whatwg.org/#isomorphic-encode - * @param {string} input - */ -function isomorphicEncode (input) { - // 1. Assert: input contains no code points greater than U+00FF. - for (let i = 0; i < input.length; i++) { - assert(input.charCodeAt(i) <= 0xFF) - } + // 3. If parsedURL includes credentials, then throw a TypeError. + if (parsedURL.username || parsedURL.password) { + throw new TypeError( + 'Request cannot be constructed from a URL that includes credentials: ' + + input + ) + } - // 2. Return a byte sequence whose length is equal to input’s code - // point length and whose bytes have the same values as the - // values of input’s code points, in the same order - return input -} + // 4. Set request to a new request whose URL is parsedURL. + request = makeRequest({ urlList: [parsedURL] }) -/** - * @see https://streams.spec.whatwg.org/#readablestreamdefaultreader-read-all-bytes - * @see https://streams.spec.whatwg.org/#read-loop - * @param {ReadableStreamDefaultReader} reader - */ -async function readAllBytes (reader) { - const bytes = [] - let byteLength = 0 + // 5. Set fallbackMode to "cors". + fallbackMode = 'cors' + } else { + // 6. Otherwise: - while (true) { - const { done, value: chunk } = await reader.read() + // 7. Assert: input is a Request object. + assert(input instanceof Request) - if (done) { - // 1. Call successSteps with bytes. - return Buffer.concat(bytes, byteLength) - } + // 8. Set request to input’s request. + request = input[kState] - // 1. If chunk is not a Uint8Array object, call failureSteps - // with a TypeError and abort these steps. - if (!isUint8Array(chunk)) { - throw new TypeError('Received non-Uint8Array chunk') + // 9. Set signal to input’s signal. + signal = input[kSignal] } - // 2. Append the bytes represented by chunk to bytes. - bytes.push(chunk) - byteLength += chunk.length - - // 3. Read-loop given reader, bytes, successSteps, and failureSteps. - } -} - -/** - * @see https://fetch.spec.whatwg.org/#is-local - * @param {URL} url - */ -function urlIsLocal (url) { - assert('protocol' in url) // ensure it's a url object - - const protocol = url.protocol + // 7. Let origin be this’s relevant settings object’s origin. + const origin = this[kRealm].settingsObject.origin - return protocol === 'about:' || protocol === 'blob:' || protocol === 'data:' -} + // 8. Let window be "client". + let window = 'client' -/** - * @param {string|URL} url - */ -function urlHasHttpsScheme (url) { - if (typeof url === 'string') { - return url.startsWith('https:') - } + // 9. If request’s window is an environment settings object and its origin + // is same origin with origin, then set window to request’s window. + if ( + request.window?.constructor?.name === 'EnvironmentSettingsObject' && + sameOrigin(request.window, origin) + ) { + window = request.window + } - return url.protocol === 'https:' -} + // 10. If init["window"] exists and is non-null, then throw a TypeError. + if (init.window != null) { + throw new TypeError(`'window' option '${window}' must be null`) + } -/** - * @see https://fetch.spec.whatwg.org/#http-scheme - * @param {URL} url - */ -function urlIsHttpHttpsScheme (url) { - assert('protocol' in url) // ensure it's a url object + // 11. If init["window"] exists, then set window to "no-window". + if ('window' in init) { + window = 'no-window' + } - const protocol = url.protocol - - return protocol === 'http:' || protocol === 'https:' -} + // 12. Set request to a new request with the following properties: + request = makeRequest({ + // URL request’s URL. + // undici implementation note: this is set as the first item in request's urlList in makeRequest + // method request’s method. + method: request.method, + // header list A copy of request’s header list. + // undici implementation note: headersList is cloned in makeRequest + headersList: request.headersList, + // unsafe-request flag Set. + unsafeRequest: request.unsafeRequest, + // client This’s relevant settings object. + client: this[kRealm].settingsObject, + // window window. + window, + // priority request’s priority. + priority: request.priority, + // origin request’s origin. The propagation of the origin is only significant for navigation requests + // being handled by a service worker. In this scenario a request can have an origin that is different + // from the current client. + origin: request.origin, + // referrer request’s referrer. + referrer: request.referrer, + // referrer policy request’s referrer policy. + referrerPolicy: request.referrerPolicy, + // mode request’s mode. + mode: request.mode, + // credentials mode request’s credentials mode. + credentials: request.credentials, + // cache mode request’s cache mode. + cache: request.cache, + // redirect mode request’s redirect mode. + redirect: request.redirect, + // integrity metadata request’s integrity metadata. + integrity: request.integrity, + // keepalive request’s keepalive. + keepalive: request.keepalive, + // reload-navigation flag request’s reload-navigation flag. + reloadNavigation: request.reloadNavigation, + // history-navigation flag request’s history-navigation flag. + historyNavigation: request.historyNavigation, + // URL list A clone of request’s URL list. + urlList: [...request.urlList] + }) -/** - * Fetch supports node >= 16.8.0, but Object.hasOwn was added in v16.9.0. - */ -const hasOwn = Object.hasOwn || ((dict, key) => Object.prototype.hasOwnProperty.call(dict, key)) + const initHasKey = Object.keys(init).length !== 0 -module.exports = { - isAborted, - isCancelled, - createDeferredPromise, - ReadableStreamFrom, - toUSVString, - tryUpgradeRequestToAPotentiallyTrustworthyURL, - coarsenedSharedCurrentTime, - determineRequestsReferrer, - makePolicyContainer, - clonePolicyContainer, - appendFetchMetadata, - appendRequestOriginHeader, - TAOCheck, - corsCheck, - crossOriginResourcePolicyCheck, - createOpaqueTimingInfo, - setRequestReferrerPolicyOnRedirect, - isValidHTTPToken, - requestBadPort, - requestCurrentURL, - responseURL, - responseLocationURL, - isBlobLike, - isURLPotentiallyTrustworthy, - isValidReasonPhrase, - sameOrigin, - normalizeMethod, - serializeJavascriptValueToJSONString, - makeIterator, - isValidHeaderName, - isValidHeaderValue, - hasOwn, - isErrorLike, - fullyReadBody, - bytesMatch, - isReadableStreamLike, - readableStreamClose, - isomorphicEncode, - isomorphicDecode, - urlIsLocal, - urlHasHttpsScheme, - urlIsHttpHttpsScheme, - readAllBytes, - normalizeMethodRecord -} + // 13. If init is not empty, then: + if (initHasKey) { + // 1. If request’s mode is "navigate", then set it to "same-origin". + if (request.mode === 'navigate') { + request.mode = 'same-origin' + } + // 2. Unset request’s reload-navigation flag. + request.reloadNavigation = false -/***/ }), + // 3. Unset request’s history-navigation flag. + request.historyNavigation = false -/***/ 1744: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // 4. Set request’s origin to "client". + request.origin = 'client' -"use strict"; + // 5. Set request’s referrer to "client" + request.referrer = 'client' + // 6. Set request’s referrer policy to the empty string. + request.referrerPolicy = '' -const { types } = __nccwpck_require__(3837) -const { hasOwn, toUSVString } = __nccwpck_require__(2538) + // 7. Set request’s URL to request’s current URL. + request.url = request.urlList[request.urlList.length - 1] -/** @type {import('../../types/webidl').Webidl} */ -const webidl = {} -webidl.converters = {} -webidl.util = {} -webidl.errors = {} + // 8. Set request’s URL list to « request’s URL ». + request.urlList = [request.url] + } -webidl.errors.exception = function (message) { - return new TypeError(`${message.header}: ${message.message}`) -} + // 14. If init["referrer"] exists, then: + if (init.referrer !== undefined) { + // 1. Let referrer be init["referrer"]. + const referrer = init.referrer -webidl.errors.conversionFailed = function (context) { - const plural = context.types.length === 1 ? '' : ' one of' - const message = - `${context.argument} could not be converted to` + - `${plural}: ${context.types.join(', ')}.` + // 2. If referrer is the empty string, then set request’s referrer to "no-referrer". + if (referrer === '') { + request.referrer = 'no-referrer' + } else { + // 1. Let parsedReferrer be the result of parsing referrer with + // baseURL. + // 2. If parsedReferrer is failure, then throw a TypeError. + let parsedReferrer + try { + parsedReferrer = new URL(referrer, baseUrl) + } catch (err) { + throw new TypeError(`Referrer "${referrer}" is not a valid URL.`, { cause: err }) + } - return webidl.errors.exception({ - header: context.prefix, - message - }) -} + // 3. If one of the following is true + // - parsedReferrer’s scheme is "about" and path is the string "client" + // - parsedReferrer’s origin is not same origin with origin + // then set request’s referrer to "client". + if ( + (parsedReferrer.protocol === 'about:' && parsedReferrer.hostname === 'client') || + (origin && !sameOrigin(parsedReferrer, this[kRealm].settingsObject.baseUrl)) + ) { + request.referrer = 'client' + } else { + // 4. Otherwise, set request’s referrer to parsedReferrer. + request.referrer = parsedReferrer + } + } + } -webidl.errors.invalidArgument = function (context) { - return webidl.errors.exception({ - header: context.prefix, - message: `"${context.value}" is an invalid ${context.type}.` - }) -} + // 15. If init["referrerPolicy"] exists, then set request’s referrer policy + // to it. + if (init.referrerPolicy !== undefined) { + request.referrerPolicy = init.referrerPolicy + } -// https://webidl.spec.whatwg.org/#implements -webidl.brandCheck = function (V, I, opts = undefined) { - if (opts?.strict !== false && !(V instanceof I)) { - throw new TypeError('Illegal invocation') - } else { - return V?.[Symbol.toStringTag] === I.prototype[Symbol.toStringTag] - } -} + // 16. Let mode be init["mode"] if it exists, and fallbackMode otherwise. + let mode + if (init.mode !== undefined) { + mode = init.mode + } else { + mode = fallbackMode + } -webidl.argumentLengthCheck = function ({ length }, min, ctx) { - if (length < min) { - throw webidl.errors.exception({ - message: `${min} argument${min !== 1 ? 's' : ''} required, ` + - `but${length ? ' only' : ''} ${length} found.`, - ...ctx - }) - } -} + // 17. If mode is "navigate", then throw a TypeError. + if (mode === 'navigate') { + throw webidl.errors.exception({ + header: 'Request constructor', + message: 'invalid request mode navigate.' + }) + } -webidl.illegalConstructor = function () { - throw webidl.errors.exception({ - header: 'TypeError', - message: 'Illegal constructor' - }) -} + // 18. If mode is non-null, set request’s mode to mode. + if (mode != null) { + request.mode = mode + } -// https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values -webidl.util.Type = function (V) { - switch (typeof V) { - case 'undefined': return 'Undefined' - case 'boolean': return 'Boolean' - case 'string': return 'String' - case 'symbol': return 'Symbol' - case 'number': return 'Number' - case 'bigint': return 'BigInt' - case 'function': - case 'object': { - if (V === null) { - return 'Null' - } + // 19. If init["credentials"] exists, then set request’s credentials mode + // to it. + if (init.credentials !== undefined) { + request.credentials = init.credentials + } - return 'Object' + // 18. If init["cache"] exists, then set request’s cache mode to it. + if (init.cache !== undefined) { + request.cache = init.cache } - } -} -// https://webidl.spec.whatwg.org/#abstract-opdef-converttoint -webidl.util.ConvertToInt = function (V, bitLength, signedness, opts = {}) { - let upperBound - let lowerBound - - // 1. If bitLength is 64, then: - if (bitLength === 64) { - // 1. Let upperBound be 2^53 − 1. - upperBound = Math.pow(2, 53) - 1 + // 21. If request’s cache mode is "only-if-cached" and request’s mode is + // not "same-origin", then throw a TypeError. + if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { + throw new TypeError( + "'only-if-cached' can be set only with 'same-origin' mode" + ) + } - // 2. If signedness is "unsigned", then let lowerBound be 0. - if (signedness === 'unsigned') { - lowerBound = 0 - } else { - // 3. Otherwise let lowerBound be −2^53 + 1. - lowerBound = Math.pow(-2, 53) + 1 + // 22. If init["redirect"] exists, then set request’s redirect mode to it. + if (init.redirect !== undefined) { + request.redirect = init.redirect } - } else if (signedness === 'unsigned') { - // 2. Otherwise, if signedness is "unsigned", then: - // 1. Let lowerBound be 0. - lowerBound = 0 + // 23. If init["integrity"] exists, then set request’s integrity metadata to it. + if (init.integrity != null) { + request.integrity = String(init.integrity) + } - // 2. Let upperBound be 2^bitLength − 1. - upperBound = Math.pow(2, bitLength) - 1 - } else { - // 3. Otherwise: + // 24. If init["keepalive"] exists, then set request’s keepalive to it. + if (init.keepalive !== undefined) { + request.keepalive = Boolean(init.keepalive) + } - // 1. Let lowerBound be -2^bitLength − 1. - lowerBound = Math.pow(-2, bitLength) - 1 + // 25. If init["method"] exists, then: + if (init.method !== undefined) { + // 1. Let method be init["method"]. + let method = init.method - // 2. Let upperBound be 2^bitLength − 1 − 1. - upperBound = Math.pow(2, bitLength - 1) - 1 - } + // 2. If method is not a method or method is a forbidden method, then + // throw a TypeError. + if (!isValidHTTPToken(method)) { + throw new TypeError(`'${method}' is not a valid HTTP method.`) + } - // 4. Let x be ? ToNumber(V). - let x = Number(V) + if (forbiddenMethodsSet.has(method.toUpperCase())) { + throw new TypeError(`'${method}' HTTP method is unsupported.`) + } - // 5. If x is −0, then set x to +0. - if (x === 0) { - x = 0 - } + // 3. Normalize method. + method = normalizeMethodRecord[method] ?? normalizeMethod(method) - // 6. If the conversion is to an IDL type associated - // with the [EnforceRange] extended attribute, then: - if (opts.enforceRange === true) { - // 1. If x is NaN, +∞, or −∞, then throw a TypeError. - if ( - Number.isNaN(x) || - x === Number.POSITIVE_INFINITY || - x === Number.NEGATIVE_INFINITY - ) { - throw webidl.errors.exception({ - header: 'Integer conversion', - message: `Could not convert ${V} to an integer.` - }) + // 4. Set request’s method to method. + request.method = method } - // 2. Set x to IntegerPart(x). - x = webidl.util.IntegerPart(x) - - // 3. If x < lowerBound or x > upperBound, then - // throw a TypeError. - if (x < lowerBound || x > upperBound) { - throw webidl.errors.exception({ - header: 'Integer conversion', - message: `Value must be between ${lowerBound}-${upperBound}, got ${x}.` - }) + // 26. If init["signal"] exists, then set signal to it. + if (init.signal !== undefined) { + signal = init.signal } - // 4. Return x. - return x - } + // 27. Set this’s request to request. + this[kState] = request - // 7. If x is not NaN and the conversion is to an IDL - // type associated with the [Clamp] extended - // attribute, then: - if (!Number.isNaN(x) && opts.clamp === true) { - // 1. Set x to min(max(x, lowerBound), upperBound). - x = Math.min(Math.max(x, lowerBound), upperBound) + // 28. Set this’s signal to a new AbortSignal object with this’s relevant + // Realm. + // TODO: could this be simplified with AbortSignal.any + // (https://dom.spec.whatwg.org/#dom-abortsignal-any) + const ac = new AbortController() + this[kSignal] = ac.signal + this[kSignal][kRealm] = this[kRealm] - // 2. Round x to the nearest integer, choosing the - // even integer if it lies halfway between two, - // and choosing +0 rather than −0. - if (Math.floor(x) % 2 === 0) { - x = Math.floor(x) - } else { - x = Math.ceil(x) - } + // 29. If signal is not null, then make this’s signal follow signal. + if (signal != null) { + if ( + !signal || + typeof signal.aborted !== 'boolean' || + typeof signal.addEventListener !== 'function' + ) { + throw new TypeError( + "Failed to construct 'Request': member signal is not of type AbortSignal." + ) + } - // 3. Return x. - return x - } + if (signal.aborted) { + ac.abort(signal.reason) + } else { + // Keep a strong ref to ac while request object + // is alive. This is needed to prevent AbortController + // from being prematurely garbage collected. + // See, https://github.com/nodejs/undici/issues/1926. + this[kAbortController] = ac - // 8. If x is NaN, +0, +∞, or −∞, then return +0. - if ( - Number.isNaN(x) || - (x === 0 && Object.is(0, x)) || - x === Number.POSITIVE_INFINITY || - x === Number.NEGATIVE_INFINITY - ) { - return 0 - } + const acRef = new WeakRef(ac) + const abort = function () { + const ac = acRef.deref() + if (ac !== undefined) { + ac.abort(this.reason) + } + } - // 9. Set x to IntegerPart(x). - x = webidl.util.IntegerPart(x) + // Third-party AbortControllers may not work with these. + // See, https://github.com/nodejs/undici/pull/1910#issuecomment-1464495619. + try { + // If the max amount of listeners is equal to the default, increase it + // This is only available in node >= v19.9.0 + if (typeof getMaxListeners === 'function' && getMaxListeners(signal) === defaultMaxListeners) { + setMaxListeners(100, signal) + } else if (getEventListeners(signal, 'abort').length >= defaultMaxListeners) { + setMaxListeners(100, signal) + } + } catch {} - // 10. Set x to x modulo 2^bitLength. - x = x % Math.pow(2, bitLength) + util.addAbortListener(signal, abort) + requestFinalizer.register(ac, { signal, abort }) + } + } - // 11. If signedness is "signed" and x ≥ 2^bitLength − 1, - // then return x − 2^bitLength. - if (signedness === 'signed' && x >= Math.pow(2, bitLength) - 1) { - return x - Math.pow(2, bitLength) - } + // 30. Set this’s headers to a new Headers object with this’s relevant + // Realm, whose header list is request’s header list and guard is + // "request". + this[kHeaders] = new Headers(kConstruct) + this[kHeaders][kHeadersList] = request.headersList + this[kHeaders][kGuard] = 'request' + this[kHeaders][kRealm] = this[kRealm] - // 12. Otherwise, return x. - return x -} + // 31. If this’s request’s mode is "no-cors", then: + if (mode === 'no-cors') { + // 1. If this’s request’s method is not a CORS-safelisted method, + // then throw a TypeError. + if (!corsSafeListedMethodsSet.has(request.method)) { + throw new TypeError( + `'${request.method} is unsupported in no-cors mode.` + ) + } -// https://webidl.spec.whatwg.org/#abstract-opdef-integerpart -webidl.util.IntegerPart = function (n) { - // 1. Let r be floor(abs(n)). - const r = Math.floor(Math.abs(n)) + // 2. Set this’s headers’s guard to "request-no-cors". + this[kHeaders][kGuard] = 'request-no-cors' + } - // 2. If n < 0, then return -1 × r. - if (n < 0) { - return -1 * r - } + // 32. If init is not empty, then: + if (initHasKey) { + /** @type {HeadersList} */ + const headersList = this[kHeaders][kHeadersList] + // 1. Let headers be a copy of this’s headers and its associated header + // list. + // 2. If init["headers"] exists, then set headers to init["headers"]. + const headers = init.headers !== undefined ? init.headers : new HeadersList(headersList) - // 3. Otherwise, return r. - return r -} + // 3. Empty this’s headers’s header list. + headersList.clear() -// https://webidl.spec.whatwg.org/#es-sequence -webidl.sequenceConverter = function (converter) { - return (V) => { - // 1. If Type(V) is not Object, throw a TypeError. - if (webidl.util.Type(V) !== 'Object') { - throw webidl.errors.exception({ - header: 'Sequence', - message: `Value of type ${webidl.util.Type(V)} is not an Object.` - }) + // 4. If headers is a Headers object, then for each header in its header + // list, append header’s name/header’s value to this’s headers. + if (headers instanceof HeadersList) { + for (const [key, val] of headers) { + headersList.append(key, val) + } + // Note: Copy the `set-cookie` meta-data. + headersList.cookies = headers.cookies + } else { + // 5. Otherwise, fill this’s headers with headers. + fillHeaders(this[kHeaders], headers) + } } - // 2. Let method be ? GetMethod(V, @@iterator). - /** @type {Generator} */ - const method = V?.[Symbol.iterator]?.() - const seq = [] + // 33. Let inputBody be input’s request’s body if input is a Request + // object; otherwise null. + const inputBody = input instanceof Request ? input[kState].body : null - // 3. If method is undefined, throw a TypeError. + // 34. If either init["body"] exists and is non-null or inputBody is + // non-null, and request’s method is `GET` or `HEAD`, then throw a + // TypeError. if ( - method === undefined || - typeof method.next !== 'function' + (init.body != null || inputBody != null) && + (request.method === 'GET' || request.method === 'HEAD') ) { - throw webidl.errors.exception({ - header: 'Sequence', - message: 'Object is not an iterator.' - }) + throw new TypeError('Request with GET/HEAD method cannot have body.') } - // https://webidl.spec.whatwg.org/#create-sequence-from-iterable - while (true) { - const { done, value } = method.next() - - if (done) { - break - } - - seq.push(converter(value)) - } + // 35. Let initBody be null. + let initBody = null - return seq - } -} + // 36. If init["body"] exists and is non-null, then: + if (init.body != null) { + // 1. Let Content-Type be null. + // 2. Set initBody and Content-Type to the result of extracting + // init["body"], with keepalive set to request’s keepalive. + const [extractedBody, contentType] = extractBody( + init.body, + request.keepalive + ) + initBody = extractedBody -// https://webidl.spec.whatwg.org/#es-to-record -webidl.recordConverter = function (keyConverter, valueConverter) { - return (O) => { - // 1. If Type(O) is not Object, throw a TypeError. - if (webidl.util.Type(O) !== 'Object') { - throw webidl.errors.exception({ - header: 'Record', - message: `Value of type ${webidl.util.Type(O)} is not an Object.` - }) + // 3, If Content-Type is non-null and this’s headers’s header list does + // not contain `Content-Type`, then append `Content-Type`/Content-Type to + // this’s headers. + if (contentType && !this[kHeaders][kHeadersList].contains('content-type')) { + this[kHeaders].append('content-type', contentType) + } } - // 2. Let result be a new empty instance of record. - const result = {} - - if (!types.isProxy(O)) { - // Object.keys only returns enumerable properties - const keys = Object.keys(O) - - for (const key of keys) { - // 1. Let typedKey be key converted to an IDL value of type K. - const typedKey = keyConverter(key) + // 37. Let inputOrInitBody be initBody if it is non-null; otherwise + // inputBody. + const inputOrInitBody = initBody ?? inputBody - // 2. Let value be ? Get(O, key). - // 3. Let typedValue be value converted to an IDL value of type V. - const typedValue = valueConverter(O[key]) + // 38. If inputOrInitBody is non-null and inputOrInitBody’s source is + // null, then: + if (inputOrInitBody != null && inputOrInitBody.source == null) { + // 1. If initBody is non-null and init["duplex"] does not exist, + // then throw a TypeError. + if (initBody != null && init.duplex == null) { + throw new TypeError('RequestInit: duplex option is required when sending a body.') + } - // 4. Set result[typedKey] to typedValue. - result[typedKey] = typedValue + // 2. If this’s request’s mode is neither "same-origin" nor "cors", + // then throw a TypeError. + if (request.mode !== 'same-origin' && request.mode !== 'cors') { + throw new TypeError( + 'If request is made from ReadableStream, mode should be "same-origin" or "cors"' + ) } - // 5. Return result. - return result + // 3. Set this’s request’s use-CORS-preflight flag. + request.useCORSPreflightFlag = true } - // 3. Let keys be ? O.[[OwnPropertyKeys]](). - const keys = Reflect.ownKeys(O) - - // 4. For each key of keys. - for (const key of keys) { - // 1. Let desc be ? O.[[GetOwnProperty]](key). - const desc = Reflect.getOwnPropertyDescriptor(O, key) + // 39. Let finalBody be inputOrInitBody. + let finalBody = inputOrInitBody - // 2. If desc is not undefined and desc.[[Enumerable]] is true: - if (desc?.enumerable) { - // 1. Let typedKey be key converted to an IDL value of type K. - const typedKey = keyConverter(key) + // 40. If initBody is null and inputBody is non-null, then: + if (initBody == null && inputBody != null) { + // 1. If input is unusable, then throw a TypeError. + if (util.isDisturbed(inputBody.stream) || inputBody.stream.locked) { + throw new TypeError( + 'Cannot construct a Request with a Request object that has already been used.' + ) + } - // 2. Let value be ? Get(O, key). - // 3. Let typedValue be value converted to an IDL value of type V. - const typedValue = valueConverter(O[key]) + // 2. Set finalBody to the result of creating a proxy for inputBody. + if (!TransformStream) { + TransformStream = (__nccwpck_require__(5356).TransformStream) + } - // 4. Set result[typedKey] to typedValue. - result[typedKey] = typedValue + // https://streams.spec.whatwg.org/#readablestream-create-a-proxy + const identityTransform = new TransformStream() + inputBody.stream.pipeThrough(identityTransform) + finalBody = { + source: inputBody.source, + length: inputBody.length, + stream: identityTransform.readable } } - // 5. Return result. - return result + // 41. Set this’s request’s body to finalBody. + this[kState].body = finalBody } -} -webidl.interfaceConverter = function (i) { - return (V, opts = {}) => { - if (opts.strict !== false && !(V instanceof i)) { - throw webidl.errors.exception({ - header: i.name, - message: `Expected ${V} to be an instance of ${i.name}.` - }) - } + // Returns request’s HTTP method, which is "GET" by default. + get method () { + webidl.brandCheck(this, Request) - return V + // The method getter steps are to return this’s request’s method. + return this[kState].method } -} -webidl.dictionaryConverter = function (converters) { - return (dictionary) => { - const type = webidl.util.Type(dictionary) - const dict = {} + // Returns the URL of request as a string. + get url () { + webidl.brandCheck(this, Request) - if (type === 'Null' || type === 'Undefined') { - return dict - } else if (type !== 'Object') { - throw webidl.errors.exception({ - header: 'Dictionary', - message: `Expected ${dictionary} to be one of: Null, Undefined, Object.` - }) - } + // The url getter steps are to return this’s request’s URL, serialized. + return URLSerializer(this[kState].url) + } - for (const options of converters) { - const { key, defaultValue, required, converter } = options + // Returns a Headers object consisting of the headers associated with request. + // Note that headers added in the network layer by the user agent will not + // be accounted for in this object, e.g., the "Host" header. + get headers () { + webidl.brandCheck(this, Request) - if (required === true) { - if (!hasOwn(dictionary, key)) { - throw webidl.errors.exception({ - header: 'Dictionary', - message: `Missing required key "${key}".` - }) - } - } + // The headers getter steps are to return this’s headers. + return this[kHeaders] + } - let value = dictionary[key] - const hasDefault = hasOwn(options, 'defaultValue') + // Returns the kind of resource requested by request, e.g., "document" + // or "script". + get destination () { + webidl.brandCheck(this, Request) - // Only use defaultValue if value is undefined and - // a defaultValue options was provided. - if (hasDefault && value !== null) { - value = value ?? defaultValue - } + // The destination getter are to return this’s request’s destination. + return this[kState].destination + } - // A key can be optional and have no default value. - // When this happens, do not perform a conversion, - // and do not assign the key a value. - if (required || hasDefault || value !== undefined) { - value = converter(value) + // Returns the referrer of request. Its value can be a same-origin URL if + // explicitly set in init, the empty string to indicate no referrer, and + // "about:client" when defaulting to the global’s default. This is used + // during fetching to determine the value of the `Referer` header of the + // request being made. + get referrer () { + webidl.brandCheck(this, Request) - if ( - options.allowedValues && - !options.allowedValues.includes(value) - ) { - throw webidl.errors.exception({ - header: 'Dictionary', - message: `${value} is not an accepted type. Expected one of ${options.allowedValues.join(', ')}.` - }) - } + // 1. If this’s request’s referrer is "no-referrer", then return the + // empty string. + if (this[kState].referrer === 'no-referrer') { + return '' + } - dict[key] = value - } + // 2. If this’s request’s referrer is "client", then return + // "about:client". + if (this[kState].referrer === 'client') { + return 'about:client' } - return dict + // Return this’s request’s referrer, serialized. + return this[kState].referrer.toString() } -} -webidl.nullableConverter = function (converter) { - return (V) => { - if (V === null) { - return V - } + // Returns the referrer policy associated with request. + // This is used during fetching to compute the value of the request’s + // referrer. + get referrerPolicy () { + webidl.brandCheck(this, Request) - return converter(V) + // The referrerPolicy getter steps are to return this’s request’s referrer policy. + return this[kState].referrerPolicy } -} -// https://webidl.spec.whatwg.org/#es-DOMString -webidl.converters.DOMString = function (V, opts = {}) { - // 1. If V is null and the conversion is to an IDL type - // associated with the [LegacyNullToEmptyString] - // extended attribute, then return the DOMString value - // that represents the empty string. - if (V === null && opts.legacyNullToEmptyString) { - return '' + // Returns the mode associated with request, which is a string indicating + // whether the request will use CORS, or will be restricted to same-origin + // URLs. + get mode () { + webidl.brandCheck(this, Request) + + // The mode getter steps are to return this’s request’s mode. + return this[kState].mode } - // 2. Let x be ? ToString(V). - if (typeof V === 'symbol') { - throw new TypeError('Could not convert argument of type symbol to string.') + // Returns the credentials mode associated with request, + // which is a string indicating whether credentials will be sent with the + // request always, never, or only when sent to a same-origin URL. + get credentials () { + // The credentials getter steps are to return this’s request’s credentials mode. + return this[kState].credentials } - // 3. Return the IDL DOMString value that represents the - // same sequence of code units as the one the - // ECMAScript String value x represents. - return String(V) -} - -// https://webidl.spec.whatwg.org/#es-ByteString -webidl.converters.ByteString = function (V) { - // 1. Let x be ? ToString(V). - // Note: DOMString converter perform ? ToString(V) - const x = webidl.converters.DOMString(V) + // Returns the cache mode associated with request, + // which is a string indicating how the request will + // interact with the browser’s cache when fetching. + get cache () { + webidl.brandCheck(this, Request) - // 2. If the value of any element of x is greater than - // 255, then throw a TypeError. - for (let index = 0; index < x.length; index++) { - if (x.charCodeAt(index) > 255) { - throw new TypeError( - 'Cannot convert argument to a ByteString because the character at ' + - `index ${index} has a value of ${x.charCodeAt(index)} which is greater than 255.` - ) - } + // The cache getter steps are to return this’s request’s cache mode. + return this[kState].cache } - // 3. Return an IDL ByteString value whose length is the - // length of x, and where the value of each element is - // the value of the corresponding element of x. - return x -} + // Returns the redirect mode associated with request, + // which is a string indicating how redirects for the + // request will be handled during fetching. A request + // will follow redirects by default. + get redirect () { + webidl.brandCheck(this, Request) -// https://webidl.spec.whatwg.org/#es-USVString -webidl.converters.USVString = toUSVString + // The redirect getter steps are to return this’s request’s redirect mode. + return this[kState].redirect + } -// https://webidl.spec.whatwg.org/#es-boolean -webidl.converters.boolean = function (V) { - // 1. Let x be the result of computing ToBoolean(V). - const x = Boolean(V) + // Returns request’s subresource integrity metadata, which is a + // cryptographic hash of the resource being fetched. Its value + // consists of multiple hashes separated by whitespace. [SRI] + get integrity () { + webidl.brandCheck(this, Request) - // 2. Return the IDL boolean value that is the one that represents - // the same truth value as the ECMAScript Boolean value x. - return x -} + // The integrity getter steps are to return this’s request’s integrity + // metadata. + return this[kState].integrity + } -// https://webidl.spec.whatwg.org/#es-any -webidl.converters.any = function (V) { - return V -} + // Returns a boolean indicating whether or not request can outlive the + // global in which it was created. + get keepalive () { + webidl.brandCheck(this, Request) -// https://webidl.spec.whatwg.org/#es-long-long -webidl.converters['long long'] = function (V) { - // 1. Let x be ? ConvertToInt(V, 64, "signed"). - const x = webidl.util.ConvertToInt(V, 64, 'signed') + // The keepalive getter steps are to return this’s request’s keepalive. + return this[kState].keepalive + } - // 2. Return the IDL long long value that represents - // the same numeric value as x. - return x -} + // Returns a boolean indicating whether or not request is for a reload + // navigation. + get isReloadNavigation () { + webidl.brandCheck(this, Request) -// https://webidl.spec.whatwg.org/#es-unsigned-long-long -webidl.converters['unsigned long long'] = function (V) { - // 1. Let x be ? ConvertToInt(V, 64, "unsigned"). - const x = webidl.util.ConvertToInt(V, 64, 'unsigned') + // The isReloadNavigation getter steps are to return true if this’s + // request’s reload-navigation flag is set; otherwise false. + return this[kState].reloadNavigation + } - // 2. Return the IDL unsigned long long value that - // represents the same numeric value as x. - return x -} + // Returns a boolean indicating whether or not request is for a history + // navigation (a.k.a. back-foward navigation). + get isHistoryNavigation () { + webidl.brandCheck(this, Request) -// https://webidl.spec.whatwg.org/#es-unsigned-long -webidl.converters['unsigned long'] = function (V) { - // 1. Let x be ? ConvertToInt(V, 32, "unsigned"). - const x = webidl.util.ConvertToInt(V, 32, 'unsigned') + // The isHistoryNavigation getter steps are to return true if this’s request’s + // history-navigation flag is set; otherwise false. + return this[kState].historyNavigation + } - // 2. Return the IDL unsigned long value that - // represents the same numeric value as x. - return x -} + // Returns the signal associated with request, which is an AbortSignal + // object indicating whether or not request has been aborted, and its + // abort event handler. + get signal () { + webidl.brandCheck(this, Request) -// https://webidl.spec.whatwg.org/#es-unsigned-short -webidl.converters['unsigned short'] = function (V, opts) { - // 1. Let x be ? ConvertToInt(V, 16, "unsigned"). - const x = webidl.util.ConvertToInt(V, 16, 'unsigned', opts) + // The signal getter steps are to return this’s signal. + return this[kSignal] + } - // 2. Return the IDL unsigned short value that represents - // the same numeric value as x. - return x -} + get body () { + webidl.brandCheck(this, Request) -// https://webidl.spec.whatwg.org/#idl-ArrayBuffer -webidl.converters.ArrayBuffer = function (V, opts = {}) { - // 1. If Type(V) is not Object, or V does not have an - // [[ArrayBufferData]] internal slot, then throw a - // TypeError. - // see: https://tc39.es/ecma262/#sec-properties-of-the-arraybuffer-instances - // see: https://tc39.es/ecma262/#sec-properties-of-the-sharedarraybuffer-instances - if ( - webidl.util.Type(V) !== 'Object' || - !types.isAnyArrayBuffer(V) - ) { - throw webidl.errors.conversionFailed({ - prefix: `${V}`, - argument: `${V}`, - types: ['ArrayBuffer'] - }) + return this[kState].body ? this[kState].body.stream : null } - // 2. If the conversion is not to an IDL type associated - // with the [AllowShared] extended attribute, and - // IsSharedArrayBuffer(V) is true, then throw a - // TypeError. - if (opts.allowShared === false && types.isSharedArrayBuffer(V)) { - throw webidl.errors.exception({ - header: 'ArrayBuffer', - message: 'SharedArrayBuffer is not allowed.' - }) + get bodyUsed () { + webidl.brandCheck(this, Request) + + return !!this[kState].body && util.isDisturbed(this[kState].body.stream) } - // 3. If the conversion is not to an IDL type associated - // with the [AllowResizable] extended attribute, and - // IsResizableArrayBuffer(V) is true, then throw a - // TypeError. - // Note: resizable ArrayBuffers are currently a proposal. + get duplex () { + webidl.brandCheck(this, Request) - // 4. Return the IDL ArrayBuffer value that is a - // reference to the same object as V. - return V -} + return 'half' + } -webidl.converters.TypedArray = function (V, T, opts = {}) { - // 1. Let T be the IDL type V is being converted to. + // Returns a clone of request. + clone () { + webidl.brandCheck(this, Request) - // 2. If Type(V) is not Object, or V does not have a - // [[TypedArrayName]] internal slot with a value - // equal to T’s name, then throw a TypeError. - if ( - webidl.util.Type(V) !== 'Object' || - !types.isTypedArray(V) || - V.constructor.name !== T.name - ) { - throw webidl.errors.conversionFailed({ - prefix: `${T.name}`, - argument: `${V}`, - types: [T.name] - }) - } + // 1. If this is unusable, then throw a TypeError. + if (this.bodyUsed || this.body?.locked) { + throw new TypeError('unusable') + } - // 3. If the conversion is not to an IDL type associated - // with the [AllowShared] extended attribute, and - // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is - // true, then throw a TypeError. - if (opts.allowShared === false && types.isSharedArrayBuffer(V.buffer)) { - throw webidl.errors.exception({ - header: 'ArrayBuffer', - message: 'SharedArrayBuffer is not allowed.' - }) - } + // 2. Let clonedRequest be the result of cloning this’s request. + const clonedRequest = cloneRequest(this[kState]) - // 4. If the conversion is not to an IDL type associated - // with the [AllowResizable] extended attribute, and - // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is - // true, then throw a TypeError. - // Note: resizable array buffers are currently a proposal + // 3. Let clonedRequestObject be the result of creating a Request object, + // given clonedRequest, this’s headers’s guard, and this’s relevant Realm. + const clonedRequestObject = new Request(kConstruct) + clonedRequestObject[kState] = clonedRequest + clonedRequestObject[kRealm] = this[kRealm] + clonedRequestObject[kHeaders] = new Headers(kConstruct) + clonedRequestObject[kHeaders][kHeadersList] = clonedRequest.headersList + clonedRequestObject[kHeaders][kGuard] = this[kHeaders][kGuard] + clonedRequestObject[kHeaders][kRealm] = this[kHeaders][kRealm] - // 5. Return the IDL value of type T that is a reference - // to the same object as V. - return V + // 4. Make clonedRequestObject’s signal follow this’s signal. + const ac = new AbortController() + if (this.signal.aborted) { + ac.abort(this.signal.reason) + } else { + util.addAbortListener( + this.signal, + () => { + ac.abort(this.signal.reason) + } + ) + } + clonedRequestObject[kSignal] = ac.signal + + // 4. Return clonedRequestObject. + return clonedRequestObject + } } -webidl.converters.DataView = function (V, opts = {}) { - // 1. If Type(V) is not Object, or V does not have a - // [[DataView]] internal slot, then throw a TypeError. - if (webidl.util.Type(V) !== 'Object' || !types.isDataView(V)) { - throw webidl.errors.exception({ - header: 'DataView', - message: 'Object is not a DataView.' - }) - } +mixinBody(Request) - // 2. If the conversion is not to an IDL type associated - // with the [AllowShared] extended attribute, and - // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, - // then throw a TypeError. - if (opts.allowShared === false && types.isSharedArrayBuffer(V.buffer)) { - throw webidl.errors.exception({ - header: 'ArrayBuffer', - message: 'SharedArrayBuffer is not allowed.' - }) +function makeRequest (init) { + // https://fetch.spec.whatwg.org/#requests + const request = { + method: 'GET', + localURLsOnly: false, + unsafeRequest: false, + body: null, + client: null, + reservedClient: null, + replacesClientId: '', + window: 'client', + keepalive: false, + serviceWorkers: 'all', + initiator: '', + destination: '', + priority: null, + origin: 'client', + policyContainer: 'client', + referrer: 'client', + referrerPolicy: '', + mode: 'no-cors', + useCORSPreflightFlag: false, + credentials: 'same-origin', + useCredentials: false, + cache: 'default', + redirect: 'follow', + integrity: '', + cryptoGraphicsNonceMetadata: '', + parserMetadata: '', + reloadNavigation: false, + historyNavigation: false, + userActivation: false, + taintedOrigin: false, + redirectCount: 0, + responseTainting: 'basic', + preventNoCacheCacheControlHeaderModification: false, + done: false, + timingAllowFailed: false, + ...init, + headersList: init.headersList + ? new HeadersList(init.headersList) + : new HeadersList() } + request.url = request.urlList[0] + return request +} - // 3. If the conversion is not to an IDL type associated - // with the [AllowResizable] extended attribute, and - // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is - // true, then throw a TypeError. - // Note: resizable ArrayBuffers are currently a proposal +// https://fetch.spec.whatwg.org/#concept-request-clone +function cloneRequest (request) { + // To clone a request request, run these steps: - // 4. Return the IDL DataView value that is a reference - // to the same object as V. - return V + // 1. Let newRequest be a copy of request, except for its body. + const newRequest = makeRequest({ ...request, body: null }) + + // 2. If request’s body is non-null, set newRequest’s body to the + // result of cloning request’s body. + if (request.body != null) { + newRequest.body = cloneBody(request.body) + } + + // 3. Return newRequest. + return newRequest } -// https://webidl.spec.whatwg.org/#BufferSource -webidl.converters.BufferSource = function (V, opts = {}) { - if (types.isAnyArrayBuffer(V)) { - return webidl.converters.ArrayBuffer(V, opts) +Object.defineProperties(Request.prototype, { + method: kEnumerableProperty, + url: kEnumerableProperty, + headers: kEnumerableProperty, + redirect: kEnumerableProperty, + clone: kEnumerableProperty, + signal: kEnumerableProperty, + duplex: kEnumerableProperty, + destination: kEnumerableProperty, + body: kEnumerableProperty, + bodyUsed: kEnumerableProperty, + isHistoryNavigation: kEnumerableProperty, + isReloadNavigation: kEnumerableProperty, + keepalive: kEnumerableProperty, + integrity: kEnumerableProperty, + cache: kEnumerableProperty, + credentials: kEnumerableProperty, + attribute: kEnumerableProperty, + referrerPolicy: kEnumerableProperty, + referrer: kEnumerableProperty, + mode: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'Request', + configurable: true } +}) - if (types.isTypedArray(V)) { - return webidl.converters.TypedArray(V, V.constructor) +webidl.converters.Request = webidl.interfaceConverter( + Request +) + +// https://fetch.spec.whatwg.org/#requestinfo +webidl.converters.RequestInfo = function (V) { + if (typeof V === 'string') { + return webidl.converters.USVString(V) } - if (types.isDataView(V)) { - return webidl.converters.DataView(V, opts) + if (V instanceof Request) { + return webidl.converters.Request(V) } - throw new TypeError(`Could not convert ${V} to a BufferSource.`) + return webidl.converters.USVString(V) } -webidl.converters['sequence'] = webidl.sequenceConverter( - webidl.converters.ByteString -) - -webidl.converters['sequence>'] = webidl.sequenceConverter( - webidl.converters['sequence'] +webidl.converters.AbortSignal = webidl.interfaceConverter( + AbortSignal ) -webidl.converters['record'] = webidl.recordConverter( - webidl.converters.ByteString, - webidl.converters.ByteString -) +// https://fetch.spec.whatwg.org/#requestinit +webidl.converters.RequestInit = webidl.dictionaryConverter([ + { + key: 'method', + converter: webidl.converters.ByteString + }, + { + key: 'headers', + converter: webidl.converters.HeadersInit + }, + { + key: 'body', + converter: webidl.nullableConverter( + webidl.converters.BodyInit + ) + }, + { + key: 'referrer', + converter: webidl.converters.USVString + }, + { + key: 'referrerPolicy', + converter: webidl.converters.DOMString, + // https://w3c.github.io/webappsec-referrer-policy/#referrer-policy + allowedValues: referrerPolicy + }, + { + key: 'mode', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#concept-request-mode + allowedValues: requestMode + }, + { + key: 'credentials', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#requestcredentials + allowedValues: requestCredentials + }, + { + key: 'cache', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#requestcache + allowedValues: requestCache + }, + { + key: 'redirect', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#requestredirect + allowedValues: requestRedirect + }, + { + key: 'integrity', + converter: webidl.converters.DOMString + }, + { + key: 'keepalive', + converter: webidl.converters.boolean + }, + { + key: 'signal', + converter: webidl.nullableConverter( + (signal) => webidl.converters.AbortSignal( + signal, + { strict: false } + ) + ) + }, + { + key: 'window', + converter: webidl.converters.any + }, + { + key: 'duplex', + converter: webidl.converters.DOMString, + allowedValues: requestDuplex + } +]) -module.exports = { - webidl -} +module.exports = { Request, makeRequest } /***/ }), -/***/ 4854: -/***/ ((module) => { +/***/ 7823: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -/** - * @see https://encoding.spec.whatwg.org/#concept-encoding-get - * @param {string|undefined} label - */ -function getEncoding (label) { - if (!label) { - return 'failure' - } +const { Headers, HeadersList, fill } = __nccwpck_require__(554) +const { extractBody, cloneBody, mixinBody } = __nccwpck_require__(1472) +const util = __nccwpck_require__(3983) +const { kEnumerableProperty } = util +const { + isValidReasonPhrase, + isCancelled, + isAborted, + isBlobLike, + serializeJavascriptValueToJSONString, + isErrorLike, + isomorphicEncode +} = __nccwpck_require__(2538) +const { + redirectStatusSet, + nullBodyStatus, + DOMException +} = __nccwpck_require__(1037) +const { kState, kHeaders, kGuard, kRealm } = __nccwpck_require__(5861) +const { webidl } = __nccwpck_require__(1744) +const { FormData } = __nccwpck_require__(2015) +const { getGlobalOrigin } = __nccwpck_require__(1246) +const { URLSerializer } = __nccwpck_require__(685) +const { kHeadersList, kConstruct } = __nccwpck_require__(2785) +const assert = __nccwpck_require__(9491) +const { types } = __nccwpck_require__(3837) - // 1. Remove any leading and trailing ASCII whitespace from label. - // 2. If label is an ASCII case-insensitive match for any of the - // labels listed in the table below, then return the - // corresponding encoding; otherwise return failure. - switch (label.trim().toLowerCase()) { - case 'unicode-1-1-utf-8': - case 'unicode11utf8': - case 'unicode20utf8': - case 'utf-8': - case 'utf8': - case 'x-unicode20utf8': - return 'UTF-8' - case '866': - case 'cp866': - case 'csibm866': - case 'ibm866': - return 'IBM866' - case 'csisolatin2': - case 'iso-8859-2': - case 'iso-ir-101': - case 'iso8859-2': - case 'iso88592': - case 'iso_8859-2': - case 'iso_8859-2:1987': - case 'l2': - case 'latin2': - return 'ISO-8859-2' - case 'csisolatin3': - case 'iso-8859-3': - case 'iso-ir-109': - case 'iso8859-3': - case 'iso88593': - case 'iso_8859-3': - case 'iso_8859-3:1988': - case 'l3': - case 'latin3': - return 'ISO-8859-3' - case 'csisolatin4': - case 'iso-8859-4': - case 'iso-ir-110': - case 'iso8859-4': - case 'iso88594': - case 'iso_8859-4': - case 'iso_8859-4:1988': - case 'l4': - case 'latin4': - return 'ISO-8859-4' - case 'csisolatincyrillic': - case 'cyrillic': - case 'iso-8859-5': - case 'iso-ir-144': - case 'iso8859-5': - case 'iso88595': - case 'iso_8859-5': - case 'iso_8859-5:1988': - return 'ISO-8859-5' - case 'arabic': - case 'asmo-708': - case 'csiso88596e': - case 'csiso88596i': - case 'csisolatinarabic': - case 'ecma-114': - case 'iso-8859-6': - case 'iso-8859-6-e': - case 'iso-8859-6-i': - case 'iso-ir-127': - case 'iso8859-6': - case 'iso88596': - case 'iso_8859-6': - case 'iso_8859-6:1987': - return 'ISO-8859-6' - case 'csisolatingreek': - case 'ecma-118': - case 'elot_928': - case 'greek': - case 'greek8': - case 'iso-8859-7': - case 'iso-ir-126': - case 'iso8859-7': - case 'iso88597': - case 'iso_8859-7': - case 'iso_8859-7:1987': - case 'sun_eu_greek': - return 'ISO-8859-7' - case 'csiso88598e': - case 'csisolatinhebrew': - case 'hebrew': - case 'iso-8859-8': - case 'iso-8859-8-e': - case 'iso-ir-138': - case 'iso8859-8': - case 'iso88598': - case 'iso_8859-8': - case 'iso_8859-8:1988': - case 'visual': - return 'ISO-8859-8' - case 'csiso88598i': - case 'iso-8859-8-i': - case 'logical': - return 'ISO-8859-8-I' - case 'csisolatin6': - case 'iso-8859-10': - case 'iso-ir-157': - case 'iso8859-10': - case 'iso885910': - case 'l6': - case 'latin6': - return 'ISO-8859-10' - case 'iso-8859-13': - case 'iso8859-13': - case 'iso885913': - return 'ISO-8859-13' - case 'iso-8859-14': - case 'iso8859-14': - case 'iso885914': - return 'ISO-8859-14' - case 'csisolatin9': - case 'iso-8859-15': - case 'iso8859-15': - case 'iso885915': - case 'iso_8859-15': - case 'l9': - return 'ISO-8859-15' - case 'iso-8859-16': - return 'ISO-8859-16' - case 'cskoi8r': - case 'koi': - case 'koi8': - case 'koi8-r': - case 'koi8_r': - return 'KOI8-R' - case 'koi8-ru': - case 'koi8-u': - return 'KOI8-U' - case 'csmacintosh': - case 'mac': - case 'macintosh': - case 'x-mac-roman': - return 'macintosh' - case 'iso-8859-11': - case 'iso8859-11': - case 'iso885911': - case 'tis-620': - case 'windows-874': - return 'windows-874' - case 'cp1250': - case 'windows-1250': - case 'x-cp1250': - return 'windows-1250' - case 'cp1251': - case 'windows-1251': - case 'x-cp1251': - return 'windows-1251' - case 'ansi_x3.4-1968': - case 'ascii': - case 'cp1252': - case 'cp819': - case 'csisolatin1': - case 'ibm819': - case 'iso-8859-1': - case 'iso-ir-100': - case 'iso8859-1': - case 'iso88591': - case 'iso_8859-1': - case 'iso_8859-1:1987': - case 'l1': - case 'latin1': - case 'us-ascii': - case 'windows-1252': - case 'x-cp1252': - return 'windows-1252' - case 'cp1253': - case 'windows-1253': - case 'x-cp1253': - return 'windows-1253' - case 'cp1254': - case 'csisolatin5': - case 'iso-8859-9': - case 'iso-ir-148': - case 'iso8859-9': - case 'iso88599': - case 'iso_8859-9': - case 'iso_8859-9:1989': - case 'l5': - case 'latin5': - case 'windows-1254': - case 'x-cp1254': - return 'windows-1254' - case 'cp1255': - case 'windows-1255': - case 'x-cp1255': - return 'windows-1255' - case 'cp1256': - case 'windows-1256': - case 'x-cp1256': - return 'windows-1256' - case 'cp1257': - case 'windows-1257': - case 'x-cp1257': - return 'windows-1257' - case 'cp1258': - case 'windows-1258': - case 'x-cp1258': - return 'windows-1258' - case 'x-mac-cyrillic': - case 'x-mac-ukrainian': - return 'x-mac-cyrillic' - case 'chinese': - case 'csgb2312': - case 'csiso58gb231280': - case 'gb2312': - case 'gb_2312': - case 'gb_2312-80': - case 'gbk': - case 'iso-ir-58': - case 'x-gbk': - return 'GBK' - case 'gb18030': - return 'gb18030' - case 'big5': - case 'big5-hkscs': - case 'cn-big5': - case 'csbig5': - case 'x-x-big5': - return 'Big5' - case 'cseucpkdfmtjapanese': - case 'euc-jp': - case 'x-euc-jp': - return 'EUC-JP' - case 'csiso2022jp': - case 'iso-2022-jp': - return 'ISO-2022-JP' - case 'csshiftjis': - case 'ms932': - case 'ms_kanji': - case 'shift-jis': - case 'shift_jis': - case 'sjis': - case 'windows-31j': - case 'x-sjis': - return 'Shift_JIS' - case 'cseuckr': - case 'csksc56011987': - case 'euc-kr': - case 'iso-ir-149': - case 'korean': - case 'ks_c_5601-1987': - case 'ks_c_5601-1989': - case 'ksc5601': - case 'ksc_5601': - case 'windows-949': - return 'EUC-KR' - case 'csiso2022kr': - case 'hz-gb-2312': - case 'iso-2022-cn': - case 'iso-2022-cn-ext': - case 'iso-2022-kr': - case 'replacement': - return 'replacement' - case 'unicodefffe': - case 'utf-16be': - return 'UTF-16BE' - case 'csunicode': - case 'iso-10646-ucs-2': - case 'ucs-2': - case 'unicode': - case 'unicodefeff': - case 'utf-16': - case 'utf-16le': - return 'UTF-16LE' - case 'x-user-defined': - return 'x-user-defined' - default: return 'failure' +const ReadableStream = globalThis.ReadableStream || (__nccwpck_require__(5356).ReadableStream) +const textEncoder = new TextEncoder('utf-8') + +// https://fetch.spec.whatwg.org/#response-class +class Response { + // Creates network error Response. + static error () { + // TODO + const relevantRealm = { settingsObject: {} } + + // The static error() method steps are to return the result of creating a + // Response object, given a new network error, "immutable", and this’s + // relevant Realm. + const responseObject = new Response() + responseObject[kState] = makeNetworkError() + responseObject[kRealm] = relevantRealm + responseObject[kHeaders][kHeadersList] = responseObject[kState].headersList + responseObject[kHeaders][kGuard] = 'immutable' + responseObject[kHeaders][kRealm] = relevantRealm + return responseObject + } + + // https://fetch.spec.whatwg.org/#dom-response-json + static json (data, init = {}) { + webidl.argumentLengthCheck(arguments, 1, { header: 'Response.json' }) + + if (init !== null) { + init = webidl.converters.ResponseInit(init) + } + + // 1. Let bytes the result of running serialize a JavaScript value to JSON bytes on data. + const bytes = textEncoder.encode( + serializeJavascriptValueToJSONString(data) + ) + + // 2. Let body be the result of extracting bytes. + const body = extractBody(bytes) + + // 3. Let responseObject be the result of creating a Response object, given a new response, + // "response", and this’s relevant Realm. + const relevantRealm = { settingsObject: {} } + const responseObject = new Response() + responseObject[kRealm] = relevantRealm + responseObject[kHeaders][kGuard] = 'response' + responseObject[kHeaders][kRealm] = relevantRealm + + // 4. Perform initialize a response given responseObject, init, and (body, "application/json"). + initializeResponse(responseObject, init, { body: body[0], type: 'application/json' }) + + // 5. Return responseObject. + return responseObject + } + + // Creates a redirect Response that redirects to url with status status. + static redirect (url, status = 302) { + const relevantRealm = { settingsObject: {} } + + webidl.argumentLengthCheck(arguments, 1, { header: 'Response.redirect' }) + + url = webidl.converters.USVString(url) + status = webidl.converters['unsigned short'](status) + + // 1. Let parsedURL be the result of parsing url with current settings + // object’s API base URL. + // 2. If parsedURL is failure, then throw a TypeError. + // TODO: base-URL? + let parsedURL + try { + parsedURL = new URL(url, getGlobalOrigin()) + } catch (err) { + throw Object.assign(new TypeError('Failed to parse URL from ' + url), { + cause: err + }) + } + + // 3. If status is not a redirect status, then throw a RangeError. + if (!redirectStatusSet.has(status)) { + throw new RangeError('Invalid status code ' + status) + } + + // 4. Let responseObject be the result of creating a Response object, + // given a new response, "immutable", and this’s relevant Realm. + const responseObject = new Response() + responseObject[kRealm] = relevantRealm + responseObject[kHeaders][kGuard] = 'immutable' + responseObject[kHeaders][kRealm] = relevantRealm + + // 5. Set responseObject’s response’s status to status. + responseObject[kState].status = status + + // 6. Let value be parsedURL, serialized and isomorphic encoded. + const value = isomorphicEncode(URLSerializer(parsedURL)) + + // 7. Append `Location`/value to responseObject’s response’s header list. + responseObject[kState].headersList.append('location', value) + + // 8. Return responseObject. + return responseObject + } + + // https://fetch.spec.whatwg.org/#dom-response + constructor (body = null, init = {}) { + if (body !== null) { + body = webidl.converters.BodyInit(body) + } + + init = webidl.converters.ResponseInit(init) + + // TODO + this[kRealm] = { settingsObject: {} } + + // 1. Set this’s response to a new response. + this[kState] = makeResponse({}) + + // 2. Set this’s headers to a new Headers object with this’s relevant + // Realm, whose header list is this’s response’s header list and guard + // is "response". + this[kHeaders] = new Headers(kConstruct) + this[kHeaders][kGuard] = 'response' + this[kHeaders][kHeadersList] = this[kState].headersList + this[kHeaders][kRealm] = this[kRealm] + + // 3. Let bodyWithType be null. + let bodyWithType = null + + // 4. If body is non-null, then set bodyWithType to the result of extracting body. + if (body != null) { + const [extractedBody, type] = extractBody(body) + bodyWithType = { body: extractedBody, type } + } + + // 5. Perform initialize a response given this, init, and bodyWithType. + initializeResponse(this, init, bodyWithType) + } + + // Returns response’s type, e.g., "cors". + get type () { + webidl.brandCheck(this, Response) + + // The type getter steps are to return this’s response’s type. + return this[kState].type + } + + // Returns response’s URL, if it has one; otherwise the empty string. + get url () { + webidl.brandCheck(this, Response) + + const urlList = this[kState].urlList + + // The url getter steps are to return the empty string if this’s + // response’s URL is null; otherwise this’s response’s URL, + // serialized with exclude fragment set to true. + const url = urlList[urlList.length - 1] ?? null + + if (url === null) { + return '' + } + + return URLSerializer(url, true) + } + + // Returns whether response was obtained through a redirect. + get redirected () { + webidl.brandCheck(this, Response) + + // The redirected getter steps are to return true if this’s response’s URL + // list has more than one item; otherwise false. + return this[kState].urlList.length > 1 + } + + // Returns response’s status. + get status () { + webidl.brandCheck(this, Response) + + // The status getter steps are to return this’s response’s status. + return this[kState].status + } + + // Returns whether response’s status is an ok status. + get ok () { + webidl.brandCheck(this, Response) + + // The ok getter steps are to return true if this’s response’s status is an + // ok status; otherwise false. + return this[kState].status >= 200 && this[kState].status <= 299 + } + + // Returns response’s status message. + get statusText () { + webidl.brandCheck(this, Response) + + // The statusText getter steps are to return this’s response’s status + // message. + return this[kState].statusText + } + + // Returns response’s headers as Headers. + get headers () { + webidl.brandCheck(this, Response) + + // The headers getter steps are to return this’s headers. + return this[kHeaders] + } + + get body () { + webidl.brandCheck(this, Response) + + return this[kState].body ? this[kState].body.stream : null + } + + get bodyUsed () { + webidl.brandCheck(this, Response) + + return !!this[kState].body && util.isDisturbed(this[kState].body.stream) + } + + // Returns a clone of response. + clone () { + webidl.brandCheck(this, Response) + + // 1. If this is unusable, then throw a TypeError. + if (this.bodyUsed || (this.body && this.body.locked)) { + throw webidl.errors.exception({ + header: 'Response.clone', + message: 'Body has already been consumed.' + }) + } + + // 2. Let clonedResponse be the result of cloning this’s response. + const clonedResponse = cloneResponse(this[kState]) + + // 3. Return the result of creating a Response object, given + // clonedResponse, this’s headers’s guard, and this’s relevant Realm. + const clonedResponseObject = new Response() + clonedResponseObject[kState] = clonedResponse + clonedResponseObject[kRealm] = this[kRealm] + clonedResponseObject[kHeaders][kHeadersList] = clonedResponse.headersList + clonedResponseObject[kHeaders][kGuard] = this[kHeaders][kGuard] + clonedResponseObject[kHeaders][kRealm] = this[kHeaders][kRealm] + + return clonedResponseObject } } -module.exports = { - getEncoding +mixinBody(Response) + +Object.defineProperties(Response.prototype, { + type: kEnumerableProperty, + url: kEnumerableProperty, + status: kEnumerableProperty, + ok: kEnumerableProperty, + redirected: kEnumerableProperty, + statusText: kEnumerableProperty, + headers: kEnumerableProperty, + clone: kEnumerableProperty, + body: kEnumerableProperty, + bodyUsed: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'Response', + configurable: true + } +}) + +Object.defineProperties(Response, { + json: kEnumerableProperty, + redirect: kEnumerableProperty, + error: kEnumerableProperty +}) + +// https://fetch.spec.whatwg.org/#concept-response-clone +function cloneResponse (response) { + // To clone a response response, run these steps: + + // 1. If response is a filtered response, then return a new identical + // filtered response whose internal response is a clone of response’s + // internal response. + if (response.internalResponse) { + return filterResponse( + cloneResponse(response.internalResponse), + response.type + ) + } + + // 2. Let newResponse be a copy of response, except for its body. + const newResponse = makeResponse({ ...response, body: null }) + + // 3. If response’s body is non-null, then set newResponse’s body to the + // result of cloning response’s body. + if (response.body != null) { + newResponse.body = cloneBody(response.body) + } + + // 4. Return newResponse. + return newResponse +} + +function makeResponse (init) { + return { + aborted: false, + rangeRequested: false, + timingAllowPassed: false, + requestIncludesCredentials: false, + type: 'default', + status: 200, + timingInfo: null, + cacheState: '', + statusText: '', + ...init, + headersList: init.headersList + ? new HeadersList(init.headersList) + : new HeadersList(), + urlList: init.urlList ? [...init.urlList] : [] + } +} + +function makeNetworkError (reason) { + const isError = isErrorLike(reason) + return makeResponse({ + type: 'error', + status: 0, + error: isError + ? reason + : new Error(reason ? String(reason) : reason), + aborted: reason && reason.name === 'AbortError' + }) } +function makeFilteredResponse (response, state) { + state = { + internalResponse: response, + ...state + } -/***/ }), - -/***/ 1446: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + return new Proxy(response, { + get (target, p) { + return p in state ? state[p] : target[p] + }, + set (target, p, value) { + assert(!(p in state)) + target[p] = value + return true + } + }) +} -"use strict"; +// https://fetch.spec.whatwg.org/#concept-filtered-response +function filterResponse (response, type) { + // Set response to the following filtered response with response as its + // internal response, depending on request’s response tainting: + if (type === 'basic') { + // A basic filtered response is a filtered response whose type is "basic" + // and header list excludes any headers in internal response’s header list + // whose name is a forbidden response-header name. + // Note: undici does not implement forbidden response-header names + return makeFilteredResponse(response, { + type: 'basic', + headersList: response.headersList + }) + } else if (type === 'cors') { + // A CORS filtered response is a filtered response whose type is "cors" + // and header list excludes any headers in internal response’s header + // list whose name is not a CORS-safelisted response-header name, given + // internal response’s CORS-exposed header-name list. -const { - staticPropertyDescriptors, - readOperation, - fireAProgressEvent -} = __nccwpck_require__(7530) -const { - kState, - kError, - kResult, - kEvents, - kAborted -} = __nccwpck_require__(9054) -const { webidl } = __nccwpck_require__(1744) -const { kEnumerableProperty } = __nccwpck_require__(3983) + // Note: undici does not implement CORS-safelisted response-header names + return makeFilteredResponse(response, { + type: 'cors', + headersList: response.headersList + }) + } else if (type === 'opaque') { + // An opaque filtered response is a filtered response whose type is + // "opaque", URL list is the empty list, status is 0, status message + // is the empty byte sequence, header list is empty, and body is null. -class FileReader extends EventTarget { - constructor () { - super() + return makeFilteredResponse(response, { + type: 'opaque', + urlList: Object.freeze([]), + status: 0, + statusText: '', + body: null + }) + } else if (type === 'opaqueredirect') { + // An opaque-redirect filtered response is a filtered response whose type + // is "opaqueredirect", status is 0, status message is the empty byte + // sequence, header list is empty, and body is null. - this[kState] = 'empty' - this[kResult] = null - this[kError] = null - this[kEvents] = { - loadend: null, - error: null, - abort: null, - load: null, - progress: null, - loadstart: null - } + return makeFilteredResponse(response, { + type: 'opaqueredirect', + status: 0, + statusText: '', + headersList: [], + body: null + }) + } else { + assert(false) } +} - /** - * @see https://w3c.github.io/FileAPI/#dfn-readAsArrayBuffer - * @param {import('buffer').Blob} blob - */ - readAsArrayBuffer (blob) { - webidl.brandCheck(this, FileReader) - - webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsArrayBuffer' }) +// https://fetch.spec.whatwg.org/#appropriate-network-error +function makeAppropriateNetworkError (fetchParams, err = null) { + // 1. Assert: fetchParams is canceled. + assert(isCancelled(fetchParams)) - blob = webidl.converters.Blob(blob, { strict: false }) + // 2. Return an aborted network error if fetchParams is aborted; + // otherwise return a network error. + return isAborted(fetchParams) + ? makeNetworkError(Object.assign(new DOMException('The operation was aborted.', 'AbortError'), { cause: err })) + : makeNetworkError(Object.assign(new DOMException('Request was cancelled.'), { cause: err })) +} - // The readAsArrayBuffer(blob) method, when invoked, - // must initiate a read operation for blob with ArrayBuffer. - readOperation(this, blob, 'ArrayBuffer') +// https://whatpr.org/fetch/1392.html#initialize-a-response +function initializeResponse (response, init, body) { + // 1. If init["status"] is not in the range 200 to 599, inclusive, then + // throw a RangeError. + if (init.status !== null && (init.status < 200 || init.status > 599)) { + throw new RangeError('init["status"] must be in the range of 200 to 599, inclusive.') } - /** - * @see https://w3c.github.io/FileAPI/#readAsBinaryString - * @param {import('buffer').Blob} blob - */ - readAsBinaryString (blob) { - webidl.brandCheck(this, FileReader) - - webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsBinaryString' }) + // 2. If init["statusText"] does not match the reason-phrase token production, + // then throw a TypeError. + if ('statusText' in init && init.statusText != null) { + // See, https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2: + // reason-phrase = *( HTAB / SP / VCHAR / obs-text ) + if (!isValidReasonPhrase(String(init.statusText))) { + throw new TypeError('Invalid statusText') + } + } - blob = webidl.converters.Blob(blob, { strict: false }) + // 3. Set response’s response’s status to init["status"]. + if ('status' in init && init.status != null) { + response[kState].status = init.status + } - // The readAsBinaryString(blob) method, when invoked, - // must initiate a read operation for blob with BinaryString. - readOperation(this, blob, 'BinaryString') + // 4. Set response’s response’s status message to init["statusText"]. + if ('statusText' in init && init.statusText != null) { + response[kState].statusText = init.statusText } - /** - * @see https://w3c.github.io/FileAPI/#readAsDataText - * @param {import('buffer').Blob} blob - * @param {string?} encoding - */ - readAsText (blob, encoding = undefined) { - webidl.brandCheck(this, FileReader) + // 5. If init["headers"] exists, then fill response’s headers with init["headers"]. + if ('headers' in init && init.headers != null) { + fill(response[kHeaders], init.headers) + } - webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsText' }) + // 6. If body was given, then: + if (body) { + // 1. If response's status is a null body status, then throw a TypeError. + if (nullBodyStatus.includes(response.status)) { + throw webidl.errors.exception({ + header: 'Response constructor', + message: 'Invalid response status code ' + response.status + }) + } - blob = webidl.converters.Blob(blob, { strict: false }) + // 2. Set response's body to body's body. + response[kState].body = body.body - if (encoding !== undefined) { - encoding = webidl.converters.DOMString(encoding) + // 3. If body's type is non-null and response's header list does not contain + // `Content-Type`, then append (`Content-Type`, body's type) to response's header list. + if (body.type != null && !response[kState].headersList.contains('Content-Type')) { + response[kState].headersList.append('content-type', body.type) } - - // The readAsText(blob, encoding) method, when invoked, - // must initiate a read operation for blob with Text and encoding. - readOperation(this, blob, 'Text', encoding) } +} - /** - * @see https://w3c.github.io/FileAPI/#dfn-readAsDataURL - * @param {import('buffer').Blob} blob - */ - readAsDataURL (blob) { - webidl.brandCheck(this, FileReader) +webidl.converters.ReadableStream = webidl.interfaceConverter( + ReadableStream +) - webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsDataURL' }) +webidl.converters.FormData = webidl.interfaceConverter( + FormData +) - blob = webidl.converters.Blob(blob, { strict: false }) +webidl.converters.URLSearchParams = webidl.interfaceConverter( + URLSearchParams +) - // The readAsDataURL(blob) method, when invoked, must - // initiate a read operation for blob with DataURL. - readOperation(this, blob, 'DataURL') +// https://fetch.spec.whatwg.org/#typedefdef-xmlhttprequestbodyinit +webidl.converters.XMLHttpRequestBodyInit = function (V) { + if (typeof V === 'string') { + return webidl.converters.USVString(V) } - /** - * @see https://w3c.github.io/FileAPI/#dfn-abort - */ - abort () { - // 1. If this's state is "empty" or if this's state is - // "done" set this's result to null and terminate - // this algorithm. - if (this[kState] === 'empty' || this[kState] === 'done') { - this[kResult] = null - return - } - - // 2. If this's state is "loading" set this's state to - // "done" and set this's result to null. - if (this[kState] === 'loading') { - this[kState] = 'done' - this[kResult] = null - } - - // 3. If there are any tasks from this on the file reading - // task source in an affiliated task queue, then remove - // those tasks from that task queue. - this[kAborted] = true - - // 4. Terminate the algorithm for the read method being processed. - // TODO - - // 5. Fire a progress event called abort at this. - fireAProgressEvent('abort', this) + if (isBlobLike(V)) { + return webidl.converters.Blob(V, { strict: false }) + } - // 6. If this's state is not "loading", fire a progress - // event called loadend at this. - if (this[kState] !== 'loading') { - fireAProgressEvent('loadend', this) - } + if (types.isArrayBuffer(V) || types.isTypedArray(V) || types.isDataView(V)) { + return webidl.converters.BufferSource(V) } - /** - * @see https://w3c.github.io/FileAPI/#dom-filereader-readystate - */ - get readyState () { - webidl.brandCheck(this, FileReader) + if (util.isFormDataLike(V)) { + return webidl.converters.FormData(V, { strict: false }) + } - switch (this[kState]) { - case 'empty': return this.EMPTY - case 'loading': return this.LOADING - case 'done': return this.DONE - } + if (V instanceof URLSearchParams) { + return webidl.converters.URLSearchParams(V) } - /** - * @see https://w3c.github.io/FileAPI/#dom-filereader-result - */ - get result () { - webidl.brandCheck(this, FileReader) + return webidl.converters.DOMString(V) +} - // The result attribute’s getter, when invoked, must return - // this's result. - return this[kResult] +// https://fetch.spec.whatwg.org/#bodyinit +webidl.converters.BodyInit = function (V) { + if (V instanceof ReadableStream) { + return webidl.converters.ReadableStream(V) } - /** - * @see https://w3c.github.io/FileAPI/#dom-filereader-error - */ - get error () { - webidl.brandCheck(this, FileReader) - - // The error attribute’s getter, when invoked, must return - // this's error. - return this[kError] + // Note: the spec doesn't include async iterables, + // this is an undici extension. + if (V?.[Symbol.asyncIterator]) { + return V } - get onloadend () { - webidl.brandCheck(this, FileReader) + return webidl.converters.XMLHttpRequestBodyInit(V) +} - return this[kEvents].loadend +webidl.converters.ResponseInit = webidl.dictionaryConverter([ + { + key: 'status', + converter: webidl.converters['unsigned short'], + defaultValue: 200 + }, + { + key: 'statusText', + converter: webidl.converters.ByteString, + defaultValue: '' + }, + { + key: 'headers', + converter: webidl.converters.HeadersInit } +]) - set onloadend (fn) { - webidl.brandCheck(this, FileReader) +module.exports = { + makeNetworkError, + makeResponse, + makeAppropriateNetworkError, + filterResponse, + Response, + cloneResponse +} - if (this[kEvents].loadend) { - this.removeEventListener('loadend', this[kEvents].loadend) - } - if (typeof fn === 'function') { - this[kEvents].loadend = fn - this.addEventListener('loadend', fn) - } else { - this[kEvents].loadend = null - } - } +/***/ }), - get onerror () { - webidl.brandCheck(this, FileReader) +/***/ 5861: +/***/ ((module) => { - return this[kEvents].error - } +"use strict"; - set onerror (fn) { - webidl.brandCheck(this, FileReader) - if (this[kEvents].error) { - this.removeEventListener('error', this[kEvents].error) - } +module.exports = { + kUrl: Symbol('url'), + kHeaders: Symbol('headers'), + kSignal: Symbol('signal'), + kState: Symbol('state'), + kGuard: Symbol('guard'), + kRealm: Symbol('realm') +} - if (typeof fn === 'function') { - this[kEvents].error = fn - this.addEventListener('error', fn) - } else { - this[kEvents].error = null - } - } - get onloadstart () { - webidl.brandCheck(this, FileReader) +/***/ }), - return this[kEvents].loadstart - } +/***/ 2538: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - set onloadstart (fn) { - webidl.brandCheck(this, FileReader) +"use strict"; - if (this[kEvents].loadstart) { - this.removeEventListener('loadstart', this[kEvents].loadstart) - } - if (typeof fn === 'function') { - this[kEvents].loadstart = fn - this.addEventListener('loadstart', fn) - } else { - this[kEvents].loadstart = null - } - } +const { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = __nccwpck_require__(1037) +const { getGlobalOrigin } = __nccwpck_require__(1246) +const { performance } = __nccwpck_require__(4074) +const { isBlobLike, toUSVString, ReadableStreamFrom } = __nccwpck_require__(3983) +const assert = __nccwpck_require__(9491) +const { isUint8Array } = __nccwpck_require__(9830) - get onprogress () { - webidl.brandCheck(this, FileReader) +// https://nodejs.org/api/crypto.html#determining-if-crypto-support-is-unavailable +/** @type {import('crypto')|undefined} */ +let crypto - return this[kEvents].progress +try { + crypto = __nccwpck_require__(6113) +} catch { + +} + +function responseURL (response) { + // https://fetch.spec.whatwg.org/#responses + // A response has an associated URL. It is a pointer to the last URL + // in response’s URL list and null if response’s URL list is empty. + const urlList = response.urlList + const length = urlList.length + return length === 0 ? null : urlList[length - 1].toString() +} + +// https://fetch.spec.whatwg.org/#concept-response-location-url +function responseLocationURL (response, requestFragment) { + // 1. If response’s status is not a redirect status, then return null. + if (!redirectStatusSet.has(response.status)) { + return null } - set onprogress (fn) { - webidl.brandCheck(this, FileReader) + // 2. Let location be the result of extracting header list values given + // `Location` and response’s header list. + let location = response.headersList.get('location') - if (this[kEvents].progress) { - this.removeEventListener('progress', this[kEvents].progress) - } + // 3. If location is a header value, then set location to the result of + // parsing location with response’s URL. + if (location !== null && isValidHeaderValue(location)) { + location = new URL(location, responseURL(response)) + } - if (typeof fn === 'function') { - this[kEvents].progress = fn - this.addEventListener('progress', fn) - } else { - this[kEvents].progress = null - } + // 4. If location is a URL whose fragment is null, then set location’s + // fragment to requestFragment. + if (location && !location.hash) { + location.hash = requestFragment } - get onload () { - webidl.brandCheck(this, FileReader) + // 5. Return location. + return location +} - return this[kEvents].load +/** @returns {URL} */ +function requestCurrentURL (request) { + return request.urlList[request.urlList.length - 1] +} + +function requestBadPort (request) { + // 1. Let url be request’s current URL. + const url = requestCurrentURL(request) + + // 2. If url’s scheme is an HTTP(S) scheme and url’s port is a bad port, + // then return blocked. + if (urlIsHttpHttpsScheme(url) && badPortsSet.has(url.port)) { + return 'blocked' } - set onload (fn) { - webidl.brandCheck(this, FileReader) + // 3. Return allowed. + return 'allowed' +} - if (this[kEvents].load) { - this.removeEventListener('load', this[kEvents].load) - } +function isErrorLike (object) { + return object instanceof Error || ( + object?.constructor?.name === 'Error' || + object?.constructor?.name === 'DOMException' + ) +} - if (typeof fn === 'function') { - this[kEvents].load = fn - this.addEventListener('load', fn) - } else { - this[kEvents].load = null +// Check whether |statusText| is a ByteString and +// matches the Reason-Phrase token production. +// RFC 2616: https://tools.ietf.org/html/rfc2616 +// RFC 7230: https://tools.ietf.org/html/rfc7230 +// "reason-phrase = *( HTAB / SP / VCHAR / obs-text )" +// https://github.com/chromium/chromium/blob/94.0.4604.1/third_party/blink/renderer/core/fetch/response.cc#L116 +function isValidReasonPhrase (statusText) { + for (let i = 0; i < statusText.length; ++i) { + const c = statusText.charCodeAt(i) + if ( + !( + ( + c === 0x09 || // HTAB + (c >= 0x20 && c <= 0x7e) || // SP / VCHAR + (c >= 0x80 && c <= 0xff) + ) // obs-text + ) + ) { + return false } } + return true +} + +/** + * @see https://tools.ietf.org/html/rfc7230#section-3.2.6 + * @param {number} c + */ +function isTokenCharCode (c) { + switch (c) { + case 0x22: + case 0x28: + case 0x29: + case 0x2c: + case 0x2f: + case 0x3a: + case 0x3b: + case 0x3c: + case 0x3d: + case 0x3e: + case 0x3f: + case 0x40: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x7b: + case 0x7d: + // DQUOTE and "(),/:;<=>?@[\]{}" + return false + default: + // VCHAR %x21-7E + return c >= 0x21 && c <= 0x7e + } +} - get onabort () { - webidl.brandCheck(this, FileReader) - - return this[kEvents].abort +/** + * @param {string} characters + */ +function isValidHTTPToken (characters) { + if (characters.length === 0) { + return false } - - set onabort (fn) { - webidl.brandCheck(this, FileReader) - - if (this[kEvents].abort) { - this.removeEventListener('abort', this[kEvents].abort) - } - - if (typeof fn === 'function') { - this[kEvents].abort = fn - this.addEventListener('abort', fn) - } else { - this[kEvents].abort = null + for (let i = 0; i < characters.length; ++i) { + if (!isTokenCharCode(characters.charCodeAt(i))) { + return false } } + return true } -// https://w3c.github.io/FileAPI/#dom-filereader-empty -FileReader.EMPTY = FileReader.prototype.EMPTY = 0 -// https://w3c.github.io/FileAPI/#dom-filereader-loading -FileReader.LOADING = FileReader.prototype.LOADING = 1 -// https://w3c.github.io/FileAPI/#dom-filereader-done -FileReader.DONE = FileReader.prototype.DONE = 2 +/** + * @see https://fetch.spec.whatwg.org/#header-name + * @param {string} potentialValue + */ +function isValidHeaderName (potentialValue) { + return isValidHTTPToken(potentialValue) +} -Object.defineProperties(FileReader.prototype, { - EMPTY: staticPropertyDescriptors, - LOADING: staticPropertyDescriptors, - DONE: staticPropertyDescriptors, - readAsArrayBuffer: kEnumerableProperty, - readAsBinaryString: kEnumerableProperty, - readAsText: kEnumerableProperty, - readAsDataURL: kEnumerableProperty, - abort: kEnumerableProperty, - readyState: kEnumerableProperty, - result: kEnumerableProperty, - error: kEnumerableProperty, - onloadstart: kEnumerableProperty, - onprogress: kEnumerableProperty, - onload: kEnumerableProperty, - onabort: kEnumerableProperty, - onerror: kEnumerableProperty, - onloadend: kEnumerableProperty, - [Symbol.toStringTag]: { - value: 'FileReader', - writable: false, - enumerable: false, - configurable: true +/** + * @see https://fetch.spec.whatwg.org/#header-value + * @param {string} potentialValue + */ +function isValidHeaderValue (potentialValue) { + // - Has no leading or trailing HTTP tab or space bytes. + // - Contains no 0x00 (NUL) or HTTP newline bytes. + if ( + potentialValue.startsWith('\t') || + potentialValue.startsWith(' ') || + potentialValue.endsWith('\t') || + potentialValue.endsWith(' ') + ) { + return false } -}) -Object.defineProperties(FileReader, { - EMPTY: staticPropertyDescriptors, - LOADING: staticPropertyDescriptors, - DONE: staticPropertyDescriptors -}) + if ( + potentialValue.includes('\0') || + potentialValue.includes('\r') || + potentialValue.includes('\n') + ) { + return false + } -module.exports = { - FileReader + return true } +// https://w3c.github.io/webappsec-referrer-policy/#set-requests-referrer-policy-on-redirect +function setRequestReferrerPolicyOnRedirect (request, actualResponse) { + // Given a request request and a response actualResponse, this algorithm + // updates request’s referrer policy according to the Referrer-Policy + // header (if any) in actualResponse. -/***/ }), - -/***/ 5504: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; + // 1. Let policy be the result of executing § 8.1 Parse a referrer policy + // from a Referrer-Policy header on actualResponse. + // 8.1 Parse a referrer policy from a Referrer-Policy header + // 1. Let policy-tokens be the result of extracting header list values given `Referrer-Policy` and response’s header list. + const { headersList } = actualResponse + // 2. Let policy be the empty string. + // 3. For each token in policy-tokens, if token is a referrer policy and token is not the empty string, then set policy to token. + // 4. Return policy. + const policyHeader = (headersList.get('referrer-policy') ?? '').split(',') -const { webidl } = __nccwpck_require__(1744) + // Note: As the referrer-policy can contain multiple policies + // separated by comma, we need to loop through all of them + // and pick the first valid one. + // Ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy#specify_a_fallback_policy + let policy = '' + if (policyHeader.length > 0) { + // The right-most policy takes precedence. + // The left-most policy is the fallback. + for (let i = policyHeader.length; i !== 0; i--) { + const token = policyHeader[i - 1].trim() + if (referrerPolicyTokens.has(token)) { + policy = token + break + } + } + } -const kState = Symbol('ProgressEvent state') + // 2. If policy is not the empty string, then set request’s referrer policy to policy. + if (policy !== '') { + request.referrerPolicy = policy + } +} -/** - * @see https://xhr.spec.whatwg.org/#progressevent - */ -class ProgressEvent extends Event { - constructor (type, eventInitDict = {}) { - type = webidl.converters.DOMString(type) - eventInitDict = webidl.converters.ProgressEventInit(eventInitDict ?? {}) +// https://fetch.spec.whatwg.org/#cross-origin-resource-policy-check +function crossOriginResourcePolicyCheck () { + // TODO + return 'allowed' +} - super(type, eventInitDict) +// https://fetch.spec.whatwg.org/#concept-cors-check +function corsCheck () { + // TODO + return 'success' +} - this[kState] = { - lengthComputable: eventInitDict.lengthComputable, - loaded: eventInitDict.loaded, - total: eventInitDict.total - } - } +// https://fetch.spec.whatwg.org/#concept-tao-check +function TAOCheck () { + // TODO + return 'success' +} - get lengthComputable () { - webidl.brandCheck(this, ProgressEvent) +function appendFetchMetadata (httpRequest) { + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-dest-header + // TODO - return this[kState].lengthComputable - } + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-mode-header - get loaded () { - webidl.brandCheck(this, ProgressEvent) + // 1. Assert: r’s url is a potentially trustworthy URL. + // TODO - return this[kState].loaded - } + // 2. Let header be a Structured Header whose value is a token. + let header = null - get total () { - webidl.brandCheck(this, ProgressEvent) + // 3. Set header’s value to r’s mode. + header = httpRequest.mode - return this[kState].total - } -} + // 4. Set a structured field value `Sec-Fetch-Mode`/header in r’s header list. + httpRequest.headersList.set('sec-fetch-mode', header) -webidl.converters.ProgressEventInit = webidl.dictionaryConverter([ - { - key: 'lengthComputable', - converter: webidl.converters.boolean, - defaultValue: false - }, - { - key: 'loaded', - converter: webidl.converters['unsigned long long'], - defaultValue: 0 - }, - { - key: 'total', - converter: webidl.converters['unsigned long long'], - defaultValue: 0 - }, - { - key: 'bubbles', - converter: webidl.converters.boolean, - defaultValue: false - }, - { - key: 'cancelable', - converter: webidl.converters.boolean, - defaultValue: false - }, - { - key: 'composed', - converter: webidl.converters.boolean, - defaultValue: false - } -]) + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-site-header + // TODO -module.exports = { - ProgressEvent + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-user-header + // TODO } +// https://fetch.spec.whatwg.org/#append-a-request-origin-header +function appendRequestOriginHeader (request) { + // 1. Let serializedOrigin be the result of byte-serializing a request origin with request. + let serializedOrigin = request.origin -/***/ }), - -/***/ 9054: -/***/ ((module) => { - -"use strict"; + // 2. If request’s response tainting is "cors" or request’s mode is "websocket", then append (`Origin`, serializedOrigin) to request’s header list. + if (request.responseTainting === 'cors' || request.mode === 'websocket') { + if (serializedOrigin) { + request.headersList.append('origin', serializedOrigin) + } + // 3. Otherwise, if request’s method is neither `GET` nor `HEAD`, then: + } else if (request.method !== 'GET' && request.method !== 'HEAD') { + // 1. Switch on request’s referrer policy: + switch (request.referrerPolicy) { + case 'no-referrer': + // Set serializedOrigin to `null`. + serializedOrigin = null + break + case 'no-referrer-when-downgrade': + case 'strict-origin': + case 'strict-origin-when-cross-origin': + // If request’s origin is a tuple origin, its scheme is "https", and request’s current URL’s scheme is not "https", then set serializedOrigin to `null`. + if (request.origin && urlHasHttpsScheme(request.origin) && !urlHasHttpsScheme(requestCurrentURL(request))) { + serializedOrigin = null + } + break + case 'same-origin': + // If request’s origin is not same origin with request’s current URL’s origin, then set serializedOrigin to `null`. + if (!sameOrigin(request, requestCurrentURL(request))) { + serializedOrigin = null + } + break + default: + // Do nothing. + } -module.exports = { - kState: Symbol('FileReader state'), - kResult: Symbol('FileReader result'), - kError: Symbol('FileReader error'), - kLastProgressEventFired: Symbol('FileReader last progress event fired timestamp'), - kEvents: Symbol('FileReader events'), - kAborted: Symbol('FileReader aborted') + if (serializedOrigin) { + // 2. Append (`Origin`, serializedOrigin) to request’s header list. + request.headersList.append('origin', serializedOrigin) + } + } } +function coarsenedSharedCurrentTime (crossOriginIsolatedCapability) { + // TODO + return performance.now() +} -/***/ }), +// https://fetch.spec.whatwg.org/#create-an-opaque-timing-info +function createOpaqueTimingInfo (timingInfo) { + return { + startTime: timingInfo.startTime ?? 0, + redirectStartTime: 0, + redirectEndTime: 0, + postRedirectStartTime: timingInfo.startTime ?? 0, + finalServiceWorkerStartTime: 0, + finalNetworkResponseStartTime: 0, + finalNetworkRequestStartTime: 0, + endTime: 0, + encodedBodySize: 0, + decodedBodySize: 0, + finalConnectionTimingInfo: null + } +} -/***/ 7530: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +// https://html.spec.whatwg.org/multipage/origin.html#policy-container +function makePolicyContainer () { + // Note: the fetch spec doesn't make use of embedder policy or CSP list + return { + referrerPolicy: 'strict-origin-when-cross-origin' + } +} -"use strict"; +// https://html.spec.whatwg.org/multipage/origin.html#clone-a-policy-container +function clonePolicyContainer (policyContainer) { + return { + referrerPolicy: policyContainer.referrerPolicy + } +} +// https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer +function determineRequestsReferrer (request) { + // 1. Let policy be request's referrer policy. + const policy = request.referrerPolicy -const { - kState, - kError, - kResult, - kAborted, - kLastProgressEventFired -} = __nccwpck_require__(9054) -const { ProgressEvent } = __nccwpck_require__(5504) -const { getEncoding } = __nccwpck_require__(4854) -const { DOMException } = __nccwpck_require__(1037) -const { serializeAMimeType, parseMIMEType } = __nccwpck_require__(685) -const { types } = __nccwpck_require__(3837) -const { StringDecoder } = __nccwpck_require__(1576) -const { btoa } = __nccwpck_require__(4300) + // Note: policy cannot (shouldn't) be null or an empty string. + assert(policy) -/** @type {PropertyDescriptor} */ -const staticPropertyDescriptors = { - enumerable: true, - writable: false, - configurable: false -} + // 2. Let environment be request’s client. -/** - * @see https://w3c.github.io/FileAPI/#readOperation - * @param {import('./filereader').FileReader} fr - * @param {import('buffer').Blob} blob - * @param {string} type - * @param {string?} encodingName - */ -function readOperation (fr, blob, type, encodingName) { - // 1. If fr’s state is "loading", throw an InvalidStateError - // DOMException. - if (fr[kState] === 'loading') { - throw new DOMException('Invalid state', 'InvalidStateError') - } + let referrerSource = null - // 2. Set fr’s state to "loading". - fr[kState] = 'loading' + // 3. Switch on request’s referrer: + if (request.referrer === 'client') { + // Note: node isn't a browser and doesn't implement document/iframes, + // so we bypass this step and replace it with our own. - // 3. Set fr’s result to null. - fr[kResult] = null + const globalOrigin = getGlobalOrigin() - // 4. Set fr’s error to null. - fr[kError] = null + if (!globalOrigin || globalOrigin.origin === 'null') { + return 'no-referrer' + } - // 5. Let stream be the result of calling get stream on blob. - /** @type {import('stream/web').ReadableStream} */ - const stream = blob.stream() + // note: we need to clone it as it's mutated + referrerSource = new URL(globalOrigin) + } else if (request.referrer instanceof URL) { + // Let referrerSource be request’s referrer. + referrerSource = request.referrer + } - // 6. Let reader be the result of getting a reader from stream. - const reader = stream.getReader() + // 4. Let request’s referrerURL be the result of stripping referrerSource for + // use as a referrer. + let referrerURL = stripURLForReferrer(referrerSource) - // 7. Let bytes be an empty byte sequence. - /** @type {Uint8Array[]} */ - const bytes = [] + // 5. Let referrerOrigin be the result of stripping referrerSource for use as + // a referrer, with the origin-only flag set to true. + const referrerOrigin = stripURLForReferrer(referrerSource, true) - // 8. Let chunkPromise be the result of reading a chunk from - // stream with reader. - let chunkPromise = reader.read() + // 6. If the result of serializing referrerURL is a string whose length is + // greater than 4096, set referrerURL to referrerOrigin. + if (referrerURL.toString().length > 4096) { + referrerURL = referrerOrigin + } - // 9. Let isFirstChunk be true. - let isFirstChunk = true + const areSameOrigin = sameOrigin(request, referrerURL) + const isNonPotentiallyTrustWorthy = isURLPotentiallyTrustworthy(referrerURL) && + !isURLPotentiallyTrustworthy(request.url) - // 10. In parallel, while true: - // Note: "In parallel" just means non-blocking - // Note 2: readOperation itself cannot be async as double - // reading the body would then reject the promise, instead - // of throwing an error. - ;(async () => { - while (!fr[kAborted]) { - // 1. Wait for chunkPromise to be fulfilled or rejected. - try { - const { done, value } = await chunkPromise + // 8. Execute the switch statements corresponding to the value of policy: + switch (policy) { + case 'origin': return referrerOrigin != null ? referrerOrigin : stripURLForReferrer(referrerSource, true) + case 'unsafe-url': return referrerURL + case 'same-origin': + return areSameOrigin ? referrerOrigin : 'no-referrer' + case 'origin-when-cross-origin': + return areSameOrigin ? referrerURL : referrerOrigin + case 'strict-origin-when-cross-origin': { + const currentURL = requestCurrentURL(request) - // 2. If chunkPromise is fulfilled, and isFirstChunk is - // true, queue a task to fire a progress event called - // loadstart at fr. - if (isFirstChunk && !fr[kAborted]) { - queueMicrotask(() => { - fireAProgressEvent('loadstart', fr) - }) - } + // 1. If the origin of referrerURL and the origin of request’s current + // URL are the same, then return referrerURL. + if (sameOrigin(referrerURL, currentURL)) { + return referrerURL + } - // 3. Set isFirstChunk to false. - isFirstChunk = false + // 2. If referrerURL is a potentially trustworthy URL and request’s + // current URL is not a potentially trustworthy URL, then return no + // referrer. + if (isURLPotentiallyTrustworthy(referrerURL) && !isURLPotentiallyTrustworthy(currentURL)) { + return 'no-referrer' + } - // 4. If chunkPromise is fulfilled with an object whose - // done property is false and whose value property is - // a Uint8Array object, run these steps: - if (!done && types.isUint8Array(value)) { - // 1. Let bs be the byte sequence represented by the - // Uint8Array object. + // 3. Return referrerOrigin. + return referrerOrigin + } + case 'strict-origin': // eslint-disable-line + /** + * 1. If referrerURL is a potentially trustworthy URL and + * request’s current URL is not a potentially trustworthy URL, + * then return no referrer. + * 2. Return referrerOrigin + */ + case 'no-referrer-when-downgrade': // eslint-disable-line + /** + * 1. If referrerURL is a potentially trustworthy URL and + * request’s current URL is not a potentially trustworthy URL, + * then return no referrer. + * 2. Return referrerOrigin + */ - // 2. Append bs to bytes. - bytes.push(value) + default: // eslint-disable-line + return isNonPotentiallyTrustWorthy ? 'no-referrer' : referrerOrigin + } +} - // 3. If roughly 50ms have passed since these steps - // were last invoked, queue a task to fire a - // progress event called progress at fr. - if ( - ( - fr[kLastProgressEventFired] === undefined || - Date.now() - fr[kLastProgressEventFired] >= 50 - ) && - !fr[kAborted] - ) { - fr[kLastProgressEventFired] = Date.now() - queueMicrotask(() => { - fireAProgressEvent('progress', fr) - }) - } +/** + * @see https://w3c.github.io/webappsec-referrer-policy/#strip-url + * @param {URL} url + * @param {boolean|undefined} originOnly + */ +function stripURLForReferrer (url, originOnly) { + // 1. Assert: url is a URL. + assert(url instanceof URL) - // 4. Set chunkPromise to the result of reading a - // chunk from stream with reader. - chunkPromise = reader.read() - } else if (done) { - // 5. Otherwise, if chunkPromise is fulfilled with an - // object whose done property is true, queue a task - // to run the following steps and abort this algorithm: - queueMicrotask(() => { - // 1. Set fr’s state to "done". - fr[kState] = 'done' + // 2. If url’s scheme is a local scheme, then return no referrer. + if (url.protocol === 'file:' || url.protocol === 'about:' || url.protocol === 'blank:') { + return 'no-referrer' + } - // 2. Let result be the result of package data given - // bytes, type, blob’s type, and encodingName. - try { - const result = packageData(bytes, type, blob.type, encodingName) + // 3. Set url’s username to the empty string. + url.username = '' - // 4. Else: + // 4. Set url’s password to the empty string. + url.password = '' - if (fr[kAborted]) { - return - } + // 5. Set url’s fragment to null. + url.hash = '' - // 1. Set fr’s result to result. - fr[kResult] = result + // 6. If the origin-only flag is true, then: + if (originOnly) { + // 1. Set url’s path to « the empty string ». + url.pathname = '' - // 2. Fire a progress event called load at the fr. - fireAProgressEvent('load', fr) - } catch (error) { - // 3. If package data threw an exception error: + // 2. Set url’s query to null. + url.search = '' + } - // 1. Set fr’s error to error. - fr[kError] = error + // 7. Return url. + return url +} - // 2. Fire a progress event called error at fr. - fireAProgressEvent('error', fr) - } +function isURLPotentiallyTrustworthy (url) { + if (!(url instanceof URL)) { + return false + } - // 5. If fr’s state is not "loading", fire a progress - // event called loadend at the fr. - if (fr[kState] !== 'loading') { - fireAProgressEvent('loadend', fr) - } - }) + // If child of about, return true + if (url.href === 'about:blank' || url.href === 'about:srcdoc') { + return true + } - break - } - } catch (error) { - if (fr[kAborted]) { - return - } + // If scheme is data, return true + if (url.protocol === 'data:') return true - // 6. Otherwise, if chunkPromise is rejected with an - // error error, queue a task to run the following - // steps and abort this algorithm: - queueMicrotask(() => { - // 1. Set fr’s state to "done". - fr[kState] = 'done' + // If file, return true + if (url.protocol === 'file:') return true - // 2. Set fr’s error to error. - fr[kError] = error + return isOriginPotentiallyTrustworthy(url.origin) - // 3. Fire a progress event called error at fr. - fireAProgressEvent('error', fr) + function isOriginPotentiallyTrustworthy (origin) { + // If origin is explicitly null, return false + if (origin == null || origin === 'null') return false - // 4. If fr’s state is not "loading", fire a progress - // event called loadend at fr. - if (fr[kState] !== 'loading') { - fireAProgressEvent('loadend', fr) - } - }) + const originAsURL = new URL(origin) - break - } + // If secure, return true + if (originAsURL.protocol === 'https:' || originAsURL.protocol === 'wss:') { + return true } - })() -} -/** - * @see https://w3c.github.io/FileAPI/#fire-a-progress-event - * @see https://dom.spec.whatwg.org/#concept-event-fire - * @param {string} e The name of the event - * @param {import('./filereader').FileReader} reader - */ -function fireAProgressEvent (e, reader) { - // The progress event e does not bubble. e.bubbles must be false - // The progress event e is NOT cancelable. e.cancelable must be false - const event = new ProgressEvent(e, { - bubbles: false, - cancelable: false - }) + // If localhost or variants, return true + if (/^127(?:\.[0-9]+){0,2}\.[0-9]+$|^\[(?:0*:)*?:?0*1\]$/.test(originAsURL.hostname) || + (originAsURL.hostname === 'localhost' || originAsURL.hostname.includes('localhost.')) || + (originAsURL.hostname.endsWith('.localhost'))) { + return true + } - reader.dispatchEvent(event) + // If any other, return false + return false + } } /** - * @see https://w3c.github.io/FileAPI/#blob-package-data - * @param {Uint8Array[]} bytes - * @param {string} type - * @param {string?} mimeType - * @param {string?} encodingName + * @see https://w3c.github.io/webappsec-subresource-integrity/#does-response-match-metadatalist + * @param {Uint8Array} bytes + * @param {string} metadataList */ -function packageData (bytes, type, mimeType, encodingName) { - // 1. A Blob has an associated package data algorithm, given - // bytes, a type, a optional mimeType, and a optional - // encodingName, which switches on type and runs the - // associated steps: - - switch (type) { - case 'DataURL': { - // 1. Return bytes as a DataURL [RFC2397] subject to - // the considerations below: - // * Use mimeType as part of the Data URL if it is - // available in keeping with the Data URL - // specification [RFC2397]. - // * If mimeType is not available return a Data URL - // without a media-type. [RFC2397]. +function bytesMatch (bytes, metadataList) { + // If node is not built with OpenSSL support, we cannot check + // a request's integrity, so allow it by default (the spec will + // allow requests if an invalid hash is given, as precedence). + /* istanbul ignore if: only if node is built with --without-ssl */ + if (crypto === undefined) { + return true + } - // https://datatracker.ietf.org/doc/html/rfc2397#section-3 - // dataurl := "data:" [ mediatype ] [ ";base64" ] "," data - // mediatype := [ type "/" subtype ] *( ";" parameter ) - // data := *urlchar - // parameter := attribute "=" value - let dataURL = 'data:' + // 1. Let parsedMetadata be the result of parsing metadataList. + const parsedMetadata = parseMetadata(metadataList) - const parsed = parseMIMEType(mimeType || 'application/octet-stream') + // 2. If parsedMetadata is no metadata, return true. + if (parsedMetadata === 'no metadata') { + return true + } - if (parsed !== 'failure') { - dataURL += serializeAMimeType(parsed) - } + // 3. If parsedMetadata is the empty set, return true. + if (parsedMetadata.length === 0) { + return true + } - dataURL += ';base64,' + // 4. Let metadata be the result of getting the strongest + // metadata from parsedMetadata. + const list = parsedMetadata.sort((c, d) => d.algo.localeCompare(c.algo)) + // get the strongest algorithm + const strongest = list[0].algo + // get all entries that use the strongest algorithm; ignore weaker + const metadata = list.filter((item) => item.algo === strongest) - const decoder = new StringDecoder('latin1') + // 5. For each item in metadata: + for (const item of metadata) { + // 1. Let algorithm be the alg component of item. + const algorithm = item.algo - for (const chunk of bytes) { - dataURL += btoa(decoder.write(chunk)) - } + // 2. Let expectedValue be the val component of item. + let expectedValue = item.hash - dataURL += btoa(decoder.end()) + // See https://github.com/web-platform-tests/wpt/commit/e4c5cc7a5e48093220528dfdd1c4012dc3837a0e + // "be liberal with padding". This is annoying, and it's not even in the spec. - return dataURL + if (expectedValue.endsWith('==')) { + expectedValue = expectedValue.slice(0, -2) } - case 'Text': { - // 1. Let encoding be failure - let encoding = 'failure' - - // 2. If the encodingName is present, set encoding to the - // result of getting an encoding from encodingName. - if (encodingName) { - encoding = getEncoding(encodingName) - } - - // 3. If encoding is failure, and mimeType is present: - if (encoding === 'failure' && mimeType) { - // 1. Let type be the result of parse a MIME type - // given mimeType. - const type = parseMIMEType(mimeType) - - // 2. If type is not failure, set encoding to the result - // of getting an encoding from type’s parameters["charset"]. - if (type !== 'failure') { - encoding = getEncoding(type.parameters.get('charset')) - } - } - // 4. If encoding is failure, then set encoding to UTF-8. - if (encoding === 'failure') { - encoding = 'UTF-8' - } + // 3. Let actualValue be the result of applying algorithm to bytes. + let actualValue = crypto.createHash(algorithm).update(bytes).digest('base64') - // 5. Decode bytes using fallback encoding encoding, and - // return the result. - return decode(bytes, encoding) + if (actualValue.endsWith('==')) { + actualValue = actualValue.slice(0, -2) } - case 'ArrayBuffer': { - // Return a new ArrayBuffer whose contents are bytes. - const sequence = combineByteSequences(bytes) - return sequence.buffer + // 4. If actualValue is a case-sensitive match for expectedValue, + // return true. + if (actualValue === expectedValue) { + return true } - case 'BinaryString': { - // Return bytes as a binary string, in which every byte - // is represented by a code unit of equal value [0..255]. - let binaryString = '' - - const decoder = new StringDecoder('latin1') - for (const chunk of bytes) { - binaryString += decoder.write(chunk) - } + let actualBase64URL = crypto.createHash(algorithm).update(bytes).digest('base64url') - binaryString += decoder.end() + if (actualBase64URL.endsWith('==')) { + actualBase64URL = actualBase64URL.slice(0, -2) + } - return binaryString + if (actualBase64URL === expectedValue) { + return true } } + + // 6. Return false. + return false } +// https://w3c.github.io/webappsec-subresource-integrity/#grammardef-hash-with-options +// https://www.w3.org/TR/CSP2/#source-list-syntax +// https://www.rfc-editor.org/rfc/rfc5234#appendix-B.1 +const parseHashWithOptions = /((?sha256|sha384|sha512)-(?[A-z0-9+/]{1}.*={0,2}))( +[\x21-\x7e]?)?/i + /** - * @see https://encoding.spec.whatwg.org/#decode - * @param {Uint8Array[]} ioQueue - * @param {string} encoding + * @see https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata + * @param {string} metadata */ -function decode (ioQueue, encoding) { - const bytes = combineByteSequences(ioQueue) - - // 1. Let BOMEncoding be the result of BOM sniffing ioQueue. - const BOMEncoding = BOMSniffing(bytes) +function parseMetadata (metadata) { + // 1. Let result be the empty set. + /** @type {{ algo: string, hash: string }[]} */ + const result = [] - let slice = 0 + // 2. Let empty be equal to true. + let empty = true - // 2. If BOMEncoding is non-null: - if (BOMEncoding !== null) { - // 1. Set encoding to BOMEncoding. - encoding = BOMEncoding + const supportedHashes = crypto.getHashes() - // 2. Read three bytes from ioQueue, if BOMEncoding is - // UTF-8; otherwise read two bytes. - // (Do nothing with those bytes.) - slice = BOMEncoding === 'UTF-8' ? 3 : 2 - } + // 3. For each token returned by splitting metadata on spaces: + for (const token of metadata.split(' ')) { + // 1. Set empty to false. + empty = false - // 3. Process a queue with an instance of encoding’s - // decoder, ioQueue, output, and "replacement". + // 2. Parse token as a hash-with-options. + const parsedToken = parseHashWithOptions.exec(token) - // 4. Return output. + // 3. If token does not parse, continue to the next token. + if (parsedToken === null || parsedToken.groups === undefined) { + // Note: Chromium blocks the request at this point, but Firefox + // gives a warning that an invalid integrity was given. The + // correct behavior is to ignore these, and subsequently not + // check the integrity of the resource. + continue + } - const sliced = bytes.slice(slice) - return new TextDecoder(encoding).decode(sliced) -} + // 4. Let algorithm be the hash-algo component of token. + const algorithm = parsedToken.groups.algo -/** - * @see https://encoding.spec.whatwg.org/#bom-sniff - * @param {Uint8Array} ioQueue - */ -function BOMSniffing (ioQueue) { - // 1. Let BOM be the result of peeking 3 bytes from ioQueue, - // converted to a byte sequence. - const [a, b, c] = ioQueue + // 5. If algorithm is a hash function recognized by the user + // agent, add the parsed token to result. + if (supportedHashes.includes(algorithm.toLowerCase())) { + result.push(parsedToken.groups) + } + } - // 2. For each of the rows in the table below, starting with - // the first one and going down, if BOM starts with the - // bytes given in the first column, then return the - // encoding given in the cell in the second column of that - // row. Otherwise, return null. - if (a === 0xEF && b === 0xBB && c === 0xBF) { - return 'UTF-8' - } else if (a === 0xFE && b === 0xFF) { - return 'UTF-16BE' - } else if (a === 0xFF && b === 0xFE) { - return 'UTF-16LE' + // 4. Return no metadata if empty is true, otherwise return result. + if (empty === true) { + return 'no metadata' } - return null + return result +} + +// https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request +function tryUpgradeRequestToAPotentiallyTrustworthyURL (request) { + // TODO } /** - * @param {Uint8Array[]} sequences + * @link {https://html.spec.whatwg.org/multipage/origin.html#same-origin} + * @param {URL} A + * @param {URL} B */ -function combineByteSequences (sequences) { - const size = sequences.reduce((a, b) => { - return a + b.byteLength - }, 0) - - let offset = 0 +function sameOrigin (A, B) { + // 1. If A and B are the same opaque origin, then return true. + if (A.origin === B.origin && A.origin === 'null') { + return true + } - return sequences.reduce((a, b) => { - a.set(b, offset) - offset += b.byteLength - return a - }, new Uint8Array(size)) -} + // 2. If A and B are both tuple origins and their schemes, + // hosts, and port are identical, then return true. + if (A.protocol === B.protocol && A.hostname === B.hostname && A.port === B.port) { + return true + } -module.exports = { - staticPropertyDescriptors, - readOperation, - fireAProgressEvent + // 3. Return false. + return false } +function createDeferredPromise () { + let res + let rej + const promise = new Promise((resolve, reject) => { + res = resolve + rej = reject + }) -/***/ }), - -/***/ 1892: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - - -// We include a version number for the Dispatcher API. In case of breaking changes, -// this version number must be increased to avoid conflicts. -const globalDispatcher = Symbol.for('undici.globalDispatcher.1') -const { InvalidArgumentError } = __nccwpck_require__(8045) -const Agent = __nccwpck_require__(7890) - -if (getGlobalDispatcher() === undefined) { - setGlobalDispatcher(new Agent()) + return { promise, resolve: res, reject: rej } } -function setGlobalDispatcher (agent) { - if (!agent || typeof agent.dispatch !== 'function') { - throw new InvalidArgumentError('Argument agent must implement Agent') - } - Object.defineProperty(globalThis, globalDispatcher, { - value: agent, - writable: true, - enumerable: false, - configurable: false - }) +function isAborted (fetchParams) { + return fetchParams.controller.state === 'aborted' } -function getGlobalDispatcher () { - return globalThis[globalDispatcher] +function isCancelled (fetchParams) { + return fetchParams.controller.state === 'aborted' || + fetchParams.controller.state === 'terminated' } -module.exports = { - setGlobalDispatcher, - getGlobalDispatcher +const normalizeMethodRecord = { + delete: 'DELETE', + DELETE: 'DELETE', + get: 'GET', + GET: 'GET', + head: 'HEAD', + HEAD: 'HEAD', + options: 'OPTIONS', + OPTIONS: 'OPTIONS', + post: 'POST', + POST: 'POST', + put: 'PUT', + PUT: 'PUT' } +// Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`. +Object.setPrototypeOf(normalizeMethodRecord, null) -/***/ }), - -/***/ 6930: -/***/ ((module) => { - -"use strict"; - +/** + * @see https://fetch.spec.whatwg.org/#concept-method-normalize + * @param {string} method + */ +function normalizeMethod (method) { + return normalizeMethodRecord[method.toLowerCase()] ?? method +} -module.exports = class DecoratorHandler { - constructor (handler) { - this.handler = handler - } +// https://infra.spec.whatwg.org/#serialize-a-javascript-value-to-a-json-string +function serializeJavascriptValueToJSONString (value) { + // 1. Let result be ? Call(%JSON.stringify%, undefined, « value »). + const result = JSON.stringify(value) - onConnect (...args) { - return this.handler.onConnect(...args) + // 2. If result is undefined, then throw a TypeError. + if (result === undefined) { + throw new TypeError('Value is not JSON serializable') } - onError (...args) { - return this.handler.onError(...args) - } + // 3. Assert: result is a string. + assert(typeof result === 'string') - onUpgrade (...args) { - return this.handler.onUpgrade(...args) - } + // 4. Return result. + return result +} - onHeaders (...args) { - return this.handler.onHeaders(...args) - } +// https://tc39.es/ecma262/#sec-%25iteratorprototype%25-object +const esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())) - onData (...args) { - return this.handler.onData(...args) +/** + * @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object + * @param {() => unknown[]} iterator + * @param {string} name name of the instance + * @param {'key'|'value'|'key+value'} kind + */ +function makeIterator (iterator, name, kind) { + const object = { + index: 0, + kind, + target: iterator } - onComplete (...args) { - return this.handler.onComplete(...args) - } + const i = { + next () { + // 1. Let interface be the interface for which the iterator prototype object exists. - onBodySent (...args) { - return this.handler.onBodySent(...args) - } -} + // 2. Let thisValue be the this value. + // 3. Let object be ? ToObject(thisValue). -/***/ }), + // 4. If object is a platform object, then perform a security + // check, passing: -/***/ 2860: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // 5. If object is not a default iterator object for interface, + // then throw a TypeError. + if (Object.getPrototypeOf(this) !== i) { + throw new TypeError( + `'next' called on an object that does not implement interface ${name} Iterator.` + ) + } -"use strict"; + // 6. Let index be object’s index. + // 7. Let kind be object’s kind. + // 8. Let values be object’s target's value pairs to iterate over. + const { index, kind, target } = object + const values = target() + // 9. Let len be the length of values. + const len = values.length -const util = __nccwpck_require__(3983) -const { kBodyUsed } = __nccwpck_require__(2785) -const assert = __nccwpck_require__(9491) -const { InvalidArgumentError } = __nccwpck_require__(8045) -const EE = __nccwpck_require__(2361) + // 10. If index is greater than or equal to len, then return + // CreateIterResultObject(undefined, true). + if (index >= len) { + return { value: undefined, done: true } + } -const redirectableStatusCodes = [300, 301, 302, 303, 307, 308] + // 11. Let pair be the entry in values at index index. + const pair = values[index] -const kBody = Symbol('body') + // 12. Set object’s index to index + 1. + object.index = index + 1 -class BodyAsyncIterable { - constructor (body) { - this[kBody] = body - this[kBodyUsed] = false + // 13. Return the iterator result for pair and kind. + return iteratorResult(pair, kind) + }, + // The class string of an iterator prototype object for a given interface is the + // result of concatenating the identifier of the interface and the string " Iterator". + [Symbol.toStringTag]: `${name} Iterator` } - async * [Symbol.asyncIterator] () { - assert(!this[kBodyUsed], 'disturbed') - this[kBodyUsed] = true - yield * this[kBody] - } + // The [[Prototype]] internal slot of an iterator prototype object must be %IteratorPrototype%. + Object.setPrototypeOf(i, esIteratorPrototype) + // esIteratorPrototype needs to be the prototype of i + // which is the prototype of an empty object. Yes, it's confusing. + return Object.setPrototypeOf({}, i) } -class RedirectHandler { - constructor (dispatch, maxRedirections, opts, handler) { - if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { - throw new InvalidArgumentError('maxRedirections must be a positive number') +// https://webidl.spec.whatwg.org/#iterator-result +function iteratorResult (pair, kind) { + let result + + // 1. Let result be a value determined by the value of kind: + switch (kind) { + case 'key': { + // 1. Let idlKey be pair’s key. + // 2. Let key be the result of converting idlKey to an + // ECMAScript value. + // 3. result is key. + result = pair[0] + break + } + case 'value': { + // 1. Let idlValue be pair’s value. + // 2. Let value be the result of converting idlValue to + // an ECMAScript value. + // 3. result is value. + result = pair[1] + break + } + case 'key+value': { + // 1. Let idlKey be pair’s key. + // 2. Let idlValue be pair’s value. + // 3. Let key be the result of converting idlKey to an + // ECMAScript value. + // 4. Let value be the result of converting idlValue to + // an ECMAScript value. + // 5. Let array be ! ArrayCreate(2). + // 6. Call ! CreateDataProperty(array, "0", key). + // 7. Call ! CreateDataProperty(array, "1", value). + // 8. result is array. + result = pair + break } + } - util.validateHandler(handler, opts.method, opts.upgrade) + // 2. Return CreateIterResultObject(result, false). + return { value: result, done: false } +} - this.dispatch = dispatch - this.location = null - this.abort = null - this.opts = { ...opts, maxRedirections: 0 } // opts must be a copy - this.maxRedirections = maxRedirections - this.handler = handler - this.history = [] +/** + * @see https://fetch.spec.whatwg.org/#body-fully-read + */ +async function fullyReadBody (body, processBody, processBodyError) { + // 1. If taskDestination is null, then set taskDestination to + // the result of starting a new parallel queue. - if (util.isStream(this.opts.body)) { - // TODO (fix): Provide some way for the user to cache the file to e.g. /tmp - // so that it can be dispatched again? - // TODO (fix): Do we need 100-expect support to provide a way to do this properly? - if (util.bodyLength(this.opts.body) === 0) { - this.opts.body - .on('data', function () { - assert(false) - }) - } + // 2. Let successSteps given a byte sequence bytes be to queue a + // fetch task to run processBody given bytes, with taskDestination. + const successSteps = processBody - if (typeof this.opts.body.readableDidRead !== 'boolean') { - this.opts.body[kBodyUsed] = false - EE.prototype.on.call(this.opts.body, 'data', function () { - this[kBodyUsed] = true - }) - } - } else if (this.opts.body && typeof this.opts.body.pipeTo === 'function') { - // TODO (fix): We can't access ReadableStream internal state - // to determine whether or not it has been disturbed. This is just - // a workaround. - this.opts.body = new BodyAsyncIterable(this.opts.body) - } else if ( - this.opts.body && - typeof this.opts.body !== 'string' && - !ArrayBuffer.isView(this.opts.body) && - util.isIterable(this.opts.body) - ) { - // TODO: Should we allow re-using iterable if !this.opts.idempotent - // or through some other flag? - this.opts.body = new BodyAsyncIterable(this.opts.body) - } - } + // 3. Let errorSteps be to queue a fetch task to run processBodyError, + // with taskDestination. + const errorSteps = processBodyError - onConnect (abort) { - this.abort = abort - this.handler.onConnect(abort, { history: this.history }) - } + // 4. Let reader be the result of getting a reader for body’s stream. + // If that threw an exception, then run errorSteps with that + // exception and return. + let reader - onUpgrade (statusCode, headers, socket) { - this.handler.onUpgrade(statusCode, headers, socket) + try { + reader = body.stream.getReader() + } catch (e) { + errorSteps(e) + return } - onError (error) { - this.handler.onError(error) + // 5. Read all bytes from reader, given successSteps and errorSteps. + try { + const result = await readAllBytes(reader) + successSteps(result) + } catch (e) { + errorSteps(e) } +} - onHeaders (statusCode, headers, resume, statusText) { - this.location = this.history.length >= this.maxRedirections || util.isDisturbed(this.opts.body) - ? null - : parseLocation(statusCode, headers) +/** @type {ReadableStream} */ +let ReadableStream = globalThis.ReadableStream - if (this.opts.origin) { - this.history.push(new URL(this.opts.path, this.opts.origin)) - } +function isReadableStreamLike (stream) { + if (!ReadableStream) { + ReadableStream = (__nccwpck_require__(5356).ReadableStream) + } - if (!this.location) { - return this.handler.onHeaders(statusCode, headers, resume, statusText) - } + return stream instanceof ReadableStream || ( + stream[Symbol.toStringTag] === 'ReadableStream' && + typeof stream.tee === 'function' + ) +} - const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin))) - const path = search ? `${pathname}${search}` : pathname +const MAXIMUM_ARGUMENT_LENGTH = 65535 - // Remove headers referring to the original URL. - // By default it is Host only, unless it's a 303 (see below), which removes also all Content-* headers. - // https://tools.ietf.org/html/rfc7231#section-6.4 - this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin) - this.opts.path = path - this.opts.origin = origin - this.opts.maxRedirections = 0 - this.opts.query = null +/** + * @see https://infra.spec.whatwg.org/#isomorphic-decode + * @param {number[]|Uint8Array} input + */ +function isomorphicDecode (input) { + // 1. To isomorphic decode a byte sequence input, return a string whose code point + // length is equal to input’s length and whose code points have the same values + // as the values of input’s bytes, in the same order. - // https://tools.ietf.org/html/rfc7231#section-6.4.4 - // In case of HTTP 303, always replace method to be either HEAD or GET - if (statusCode === 303 && this.opts.method !== 'HEAD') { - this.opts.method = 'GET' - this.opts.body = null - } + if (input.length < MAXIMUM_ARGUMENT_LENGTH) { + return String.fromCharCode(...input) } - onData (chunk) { - if (this.location) { - /* - https://tools.ietf.org/html/rfc7231#section-6.4 - - TLDR: undici always ignores 3xx response bodies. - - Redirection is used to serve the requested resource from another URL, so it is assumes that - no body is generated (and thus can be ignored). Even though generating a body is not prohibited. - - For status 301, 302, 303, 307 and 308 (the latter from RFC 7238), the specs mention that the body usually - (which means it's optional and not mandated) contain just an hyperlink to the value of - the Location response header, so the body can be ignored safely. + return input.reduce((previous, current) => previous + String.fromCharCode(current), '') +} - For status 300, which is "Multiple Choices", the spec mentions both generating a Location - response header AND a response body with the other possible location to follow. - Since the spec explicitily chooses not to specify a format for such body and leave it to - servers and browsers implementors, we ignore the body as there is no specified way to eventually parse it. - */ - } else { - return this.handler.onData(chunk) +/** + * @param {ReadableStreamController} controller + */ +function readableStreamClose (controller) { + try { + controller.close() + } catch (err) { + // TODO: add comment explaining why this error occurs. + if (!err.message.includes('Controller is already closed')) { + throw err } } +} - onComplete (trailers) { - if (this.location) { - /* - https://tools.ietf.org/html/rfc7231#section-6.4 +/** + * @see https://infra.spec.whatwg.org/#isomorphic-encode + * @param {string} input + */ +function isomorphicEncode (input) { + // 1. Assert: input contains no code points greater than U+00FF. + for (let i = 0; i < input.length; i++) { + assert(input.charCodeAt(i) <= 0xFF) + } - TLDR: undici always ignores 3xx response trailers as they are not expected in case of redirections - and neither are useful if present. + // 2. Return a byte sequence whose length is equal to input’s code + // point length and whose bytes have the same values as the + // values of input’s code points, in the same order + return input +} - See comment on onData method above for more detailed informations. - */ +/** + * @see https://streams.spec.whatwg.org/#readablestreamdefaultreader-read-all-bytes + * @see https://streams.spec.whatwg.org/#read-loop + * @param {ReadableStreamDefaultReader} reader + */ +async function readAllBytes (reader) { + const bytes = [] + let byteLength = 0 - this.location = null - this.abort = null + while (true) { + const { done, value: chunk } = await reader.read() - this.dispatch(this.opts, this) - } else { - this.handler.onComplete(trailers) + if (done) { + // 1. Call successSteps with bytes. + return Buffer.concat(bytes, byteLength) } - } - onBodySent (chunk) { - if (this.handler.onBodySent) { - this.handler.onBodySent(chunk) + // 1. If chunk is not a Uint8Array object, call failureSteps + // with a TypeError and abort these steps. + if (!isUint8Array(chunk)) { + throw new TypeError('Received non-Uint8Array chunk') } - } -} -function parseLocation (statusCode, headers) { - if (redirectableStatusCodes.indexOf(statusCode) === -1) { - return null - } + // 2. Append the bytes represented by chunk to bytes. + bytes.push(chunk) + byteLength += chunk.length - for (let i = 0; i < headers.length; i += 2) { - if (headers[i].toString().toLowerCase() === 'location') { - return headers[i + 1] - } + // 3. Read-loop given reader, bytes, successSteps, and failureSteps. } } -// https://tools.ietf.org/html/rfc7231#section-6.4.4 -function shouldRemoveHeader (header, removeContent, unknownOrigin) { - return ( - (header.length === 4 && header.toString().toLowerCase() === 'host') || - (removeContent && header.toString().toLowerCase().indexOf('content-') === 0) || - (unknownOrigin && header.length === 13 && header.toString().toLowerCase() === 'authorization') || - (unknownOrigin && header.length === 6 && header.toString().toLowerCase() === 'cookie') - ) +/** + * @see https://fetch.spec.whatwg.org/#is-local + * @param {URL} url + */ +function urlIsLocal (url) { + assert('protocol' in url) // ensure it's a url object + + const protocol = url.protocol + + return protocol === 'about:' || protocol === 'blob:' || protocol === 'data:' } -// https://tools.ietf.org/html/rfc7231#section-6.4 -function cleanRequestHeaders (headers, removeContent, unknownOrigin) { - const ret = [] - if (Array.isArray(headers)) { - for (let i = 0; i < headers.length; i += 2) { - if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin)) { - ret.push(headers[i], headers[i + 1]) - } - } - } else if (headers && typeof headers === 'object') { - for (const key of Object.keys(headers)) { - if (!shouldRemoveHeader(key, removeContent, unknownOrigin)) { - ret.push(key, headers[key]) - } - } - } else { - assert(headers == null, 'headers must be an object or an array') +/** + * @param {string|URL} url + */ +function urlHasHttpsScheme (url) { + if (typeof url === 'string') { + return url.startsWith('https:') } - return ret + + return url.protocol === 'https:' } -module.exports = RedirectHandler +/** + * @see https://fetch.spec.whatwg.org/#http-scheme + * @param {URL} url + */ +function urlIsHttpHttpsScheme (url) { + assert('protocol' in url) // ensure it's a url object + + const protocol = url.protocol + + return protocol === 'http:' || protocol === 'https:' +} + +/** + * Fetch supports node >= 16.8.0, but Object.hasOwn was added in v16.9.0. + */ +const hasOwn = Object.hasOwn || ((dict, key) => Object.prototype.hasOwnProperty.call(dict, key)) + +module.exports = { + isAborted, + isCancelled, + createDeferredPromise, + ReadableStreamFrom, + toUSVString, + tryUpgradeRequestToAPotentiallyTrustworthyURL, + coarsenedSharedCurrentTime, + determineRequestsReferrer, + makePolicyContainer, + clonePolicyContainer, + appendFetchMetadata, + appendRequestOriginHeader, + TAOCheck, + corsCheck, + crossOriginResourcePolicyCheck, + createOpaqueTimingInfo, + setRequestReferrerPolicyOnRedirect, + isValidHTTPToken, + requestBadPort, + requestCurrentURL, + responseURL, + responseLocationURL, + isBlobLike, + isURLPotentiallyTrustworthy, + isValidReasonPhrase, + sameOrigin, + normalizeMethod, + serializeJavascriptValueToJSONString, + makeIterator, + isValidHeaderName, + isValidHeaderValue, + hasOwn, + isErrorLike, + fullyReadBody, + bytesMatch, + isReadableStreamLike, + readableStreamClose, + isomorphicEncode, + isomorphicDecode, + urlIsLocal, + urlHasHttpsScheme, + urlIsHttpHttpsScheme, + readAllBytes, + normalizeMethodRecord +} /***/ }), -/***/ 2286: +/***/ 1744: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -const assert = __nccwpck_require__(9491) +"use strict"; -const { kRetryHandlerDefaultRetry } = __nccwpck_require__(2785) -const { RequestRetryError } = __nccwpck_require__(8045) -const { isDisturbed, parseHeaders, parseRangeHeader } = __nccwpck_require__(3983) -function calculateRetryAfterHeader (retryAfter) { - const current = Date.now() - const diff = new Date(retryAfter).getTime() - current +const { types } = __nccwpck_require__(3837) +const { hasOwn, toUSVString } = __nccwpck_require__(2538) - return diff +/** @type {import('../../types/webidl').Webidl} */ +const webidl = {} +webidl.converters = {} +webidl.util = {} +webidl.errors = {} + +webidl.errors.exception = function (message) { + return new TypeError(`${message.header}: ${message.message}`) } -class RetryHandler { - constructor (opts, handlers) { - const { retryOptions, ...dispatchOpts } = opts - const { - // Retry scoped - retry: retryFn, - maxRetries, - maxTimeout, - minTimeout, - timeoutFactor, - // Response scoped - methods, - errorCodes, - retryAfter, - statusCodes - } = retryOptions ?? {} +webidl.errors.conversionFailed = function (context) { + const plural = context.types.length === 1 ? '' : ' one of' + const message = + `${context.argument} could not be converted to` + + `${plural}: ${context.types.join(', ')}.` - this.dispatch = handlers.dispatch - this.handler = handlers.handler - this.opts = dispatchOpts - this.abort = null - this.aborted = false - this.retryOpts = { - retry: retryFn ?? RetryHandler[kRetryHandlerDefaultRetry], - retryAfter: retryAfter ?? true, - maxTimeout: maxTimeout ?? 30 * 1000, // 30s, - timeout: minTimeout ?? 500, // .5s - timeoutFactor: timeoutFactor ?? 2, - maxRetries: maxRetries ?? 5, - // What errors we should retry - methods: methods ?? ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE'], - // Indicates which errors to retry - statusCodes: statusCodes ?? [500, 502, 503, 504, 429], - // List of errors to retry - errorCodes: errorCodes ?? [ - 'ECONNRESET', - 'ECONNREFUSED', - 'ENOTFOUND', - 'ENETDOWN', - 'ENETUNREACH', - 'EHOSTDOWN', - 'EHOSTUNREACH', - 'EPIPE' - ] - } + return webidl.errors.exception({ + header: context.prefix, + message + }) +} - this.retryCount = 0 - this.start = 0 - this.end = null - this.etag = null - this.resume = null +webidl.errors.invalidArgument = function (context) { + return webidl.errors.exception({ + header: context.prefix, + message: `"${context.value}" is an invalid ${context.type}.` + }) +} - // Handle possible onConnect duplication - this.handler.onConnect(reason => { - this.aborted = true - if (this.abort) { - this.abort(reason) - } else { - this.reason = reason - } - }) +// https://webidl.spec.whatwg.org/#implements +webidl.brandCheck = function (V, I, opts = undefined) { + if (opts?.strict !== false && !(V instanceof I)) { + throw new TypeError('Illegal invocation') + } else { + return V?.[Symbol.toStringTag] === I.prototype[Symbol.toStringTag] } +} - onRequestSent () { - if (this.handler.onRequestSent) { - this.handler.onRequestSent() - } +webidl.argumentLengthCheck = function ({ length }, min, ctx) { + if (length < min) { + throw webidl.errors.exception({ + message: `${min} argument${min !== 1 ? 's' : ''} required, ` + + `but${length ? ' only' : ''} ${length} found.`, + ...ctx + }) } +} - onUpgrade (statusCode, headers, socket) { - if (this.handler.onUpgrade) { - this.handler.onUpgrade(statusCode, headers, socket) +webidl.illegalConstructor = function () { + throw webidl.errors.exception({ + header: 'TypeError', + message: 'Illegal constructor' + }) +} + +// https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values +webidl.util.Type = function (V) { + switch (typeof V) { + case 'undefined': return 'Undefined' + case 'boolean': return 'Boolean' + case 'string': return 'String' + case 'symbol': return 'Symbol' + case 'number': return 'Number' + case 'bigint': return 'BigInt' + case 'function': + case 'object': { + if (V === null) { + return 'Null' + } + + return 'Object' } } +} - onConnect (abort) { - if (this.aborted) { - abort(this.reason) +// https://webidl.spec.whatwg.org/#abstract-opdef-converttoint +webidl.util.ConvertToInt = function (V, bitLength, signedness, opts = {}) { + let upperBound + let lowerBound + + // 1. If bitLength is 64, then: + if (bitLength === 64) { + // 1. Let upperBound be 2^53 − 1. + upperBound = Math.pow(2, 53) - 1 + + // 2. If signedness is "unsigned", then let lowerBound be 0. + if (signedness === 'unsigned') { + lowerBound = 0 } else { - this.abort = abort + // 3. Otherwise let lowerBound be −2^53 + 1. + lowerBound = Math.pow(-2, 53) + 1 } - } + } else if (signedness === 'unsigned') { + // 2. Otherwise, if signedness is "unsigned", then: - onBodySent (chunk) { - if (this.handler.onBodySent) return this.handler.onBodySent(chunk) - } + // 1. Let lowerBound be 0. + lowerBound = 0 - static [kRetryHandlerDefaultRetry] (err, { state, opts }, cb) { - const { statusCode, code, headers } = err - const { method, retryOptions } = opts - const { - maxRetries, - timeout, - maxTimeout, - timeoutFactor, - statusCodes, - errorCodes, - methods - } = retryOptions - let { counter, currentTimeout } = state + // 2. Let upperBound be 2^bitLength − 1. + upperBound = Math.pow(2, bitLength) - 1 + } else { + // 3. Otherwise: - currentTimeout = - currentTimeout != null && currentTimeout > 0 ? currentTimeout : timeout + // 1. Let lowerBound be -2^bitLength − 1. + lowerBound = Math.pow(-2, bitLength) - 1 - // Any code that is not a Undici's originated and allowed to retry - if ( - code && - code !== 'UND_ERR_REQ_RETRY' && - code !== 'UND_ERR_SOCKET' && - !errorCodes.includes(code) - ) { - cb(err) - return - } + // 2. Let upperBound be 2^bitLength − 1 − 1. + upperBound = Math.pow(2, bitLength - 1) - 1 + } - // If a set of method are provided and the current method is not in the list - if (Array.isArray(methods) && !methods.includes(method)) { - cb(err) - return - } + // 4. Let x be ? ToNumber(V). + let x = Number(V) - // If a set of status code are provided and the current status code is not in the list + // 5. If x is −0, then set x to +0. + if (x === 0) { + x = 0 + } + + // 6. If the conversion is to an IDL type associated + // with the [EnforceRange] extended attribute, then: + if (opts.enforceRange === true) { + // 1. If x is NaN, +∞, or −∞, then throw a TypeError. if ( - statusCode != null && - Array.isArray(statusCodes) && - !statusCodes.includes(statusCode) + Number.isNaN(x) || + x === Number.POSITIVE_INFINITY || + x === Number.NEGATIVE_INFINITY ) { - cb(err) - return + throw webidl.errors.exception({ + header: 'Integer conversion', + message: `Could not convert ${V} to an integer.` + }) } - // If we reached the max number of retries - if (counter > maxRetries) { - cb(err) - return - } + // 2. Set x to IntegerPart(x). + x = webidl.util.IntegerPart(x) - let retryAfterHeader = headers != null && headers['retry-after'] - if (retryAfterHeader) { - retryAfterHeader = Number(retryAfterHeader) - retryAfterHeader = isNaN(retryAfterHeader) - ? calculateRetryAfterHeader(retryAfterHeader) - : retryAfterHeader * 1e3 // Retry-After is in seconds + // 3. If x < lowerBound or x > upperBound, then + // throw a TypeError. + if (x < lowerBound || x > upperBound) { + throw webidl.errors.exception({ + header: 'Integer conversion', + message: `Value must be between ${lowerBound}-${upperBound}, got ${x}.` + }) } - const retryTimeout = - retryAfterHeader > 0 - ? Math.min(retryAfterHeader, maxTimeout) - : Math.min(currentTimeout * timeoutFactor ** counter, maxTimeout) + // 4. Return x. + return x + } - state.currentTimeout = retryTimeout + // 7. If x is not NaN and the conversion is to an IDL + // type associated with the [Clamp] extended + // attribute, then: + if (!Number.isNaN(x) && opts.clamp === true) { + // 1. Set x to min(max(x, lowerBound), upperBound). + x = Math.min(Math.max(x, lowerBound), upperBound) - setTimeout(() => cb(null), retryTimeout) - } + // 2. Round x to the nearest integer, choosing the + // even integer if it lies halfway between two, + // and choosing +0 rather than −0. + if (Math.floor(x) % 2 === 0) { + x = Math.floor(x) + } else { + x = Math.ceil(x) + } - onHeaders (statusCode, rawHeaders, resume, statusMessage) { - const headers = parseHeaders(rawHeaders) + // 3. Return x. + return x + } - this.retryCount += 1 + // 8. If x is NaN, +0, +∞, or −∞, then return +0. + if ( + Number.isNaN(x) || + (x === 0 && Object.is(0, x)) || + x === Number.POSITIVE_INFINITY || + x === Number.NEGATIVE_INFINITY + ) { + return 0 + } - if (statusCode >= 300) { - this.abort( - new RequestRetryError('Request failed', statusCode, { - headers, - count: this.retryCount - }) - ) - return false - } + // 9. Set x to IntegerPart(x). + x = webidl.util.IntegerPart(x) - // Checkpoint for resume from where we left it - if (this.resume != null) { - this.resume = null + // 10. Set x to x modulo 2^bitLength. + x = x % Math.pow(2, bitLength) - if (statusCode !== 206) { - return true - } + // 11. If signedness is "signed" and x ≥ 2^bitLength − 1, + // then return x − 2^bitLength. + if (signedness === 'signed' && x >= Math.pow(2, bitLength) - 1) { + return x - Math.pow(2, bitLength) + } - const contentRange = parseRangeHeader(headers['content-range']) - // If no content range - if (!contentRange) { - this.abort( - new RequestRetryError('Content-Range mismatch', statusCode, { - headers, - count: this.retryCount - }) - ) - return false - } + // 12. Otherwise, return x. + return x +} - // Let's start with a weak etag check - if (this.etag != null && this.etag !== headers.etag) { - this.abort( - new RequestRetryError('ETag mismatch', statusCode, { - headers, - count: this.retryCount - }) - ) - return false - } +// https://webidl.spec.whatwg.org/#abstract-opdef-integerpart +webidl.util.IntegerPart = function (n) { + // 1. Let r be floor(abs(n)). + const r = Math.floor(Math.abs(n)) - const { start, size, end = size } = contentRange + // 2. If n < 0, then return -1 × r. + if (n < 0) { + return -1 * r + } - assert(this.start === start, 'content-range mismatch') - assert(this.end == null || this.end === end, 'content-range mismatch') + // 3. Otherwise, return r. + return r +} - this.resume = resume - return true +// https://webidl.spec.whatwg.org/#es-sequence +webidl.sequenceConverter = function (converter) { + return (V) => { + // 1. If Type(V) is not Object, throw a TypeError. + if (webidl.util.Type(V) !== 'Object') { + throw webidl.errors.exception({ + header: 'Sequence', + message: `Value of type ${webidl.util.Type(V)} is not an Object.` + }) } - if (this.end == null) { - if (statusCode === 206) { - // First time we receive 206 - const range = parseRangeHeader(headers['content-range']) - - if (range == null) { - return this.handler.onHeaders( - statusCode, - rawHeaders, - resume, - statusMessage - ) - } - - const { start, size, end = size } = range + // 2. Let method be ? GetMethod(V, @@iterator). + /** @type {Generator} */ + const method = V?.[Symbol.iterator]?.() + const seq = [] - assert( - start != null && Number.isFinite(start) && this.start !== start, - 'content-range mismatch' - ) - assert(Number.isFinite(start)) - assert( - end != null && Number.isFinite(end) && this.end !== end, - 'invalid content-length' - ) + // 3. If method is undefined, throw a TypeError. + if ( + method === undefined || + typeof method.next !== 'function' + ) { + throw webidl.errors.exception({ + header: 'Sequence', + message: 'Object is not an iterator.' + }) + } - this.start = start - this.end = end - } + // https://webidl.spec.whatwg.org/#create-sequence-from-iterable + while (true) { + const { done, value } = method.next() - // We make our best to checkpoint the body for further range headers - if (this.end == null) { - const contentLength = headers['content-length'] - this.end = contentLength != null ? Number(contentLength) : null + if (done) { + break } - assert(Number.isFinite(this.start)) - assert( - this.end == null || Number.isFinite(this.end), - 'invalid content-length' - ) + seq.push(converter(value)) + } - this.resume = resume - this.etag = headers.etag != null ? headers.etag : null + return seq + } +} - return this.handler.onHeaders( - statusCode, - rawHeaders, - resume, - statusMessage - ) +// https://webidl.spec.whatwg.org/#es-to-record +webidl.recordConverter = function (keyConverter, valueConverter) { + return (O) => { + // 1. If Type(O) is not Object, throw a TypeError. + if (webidl.util.Type(O) !== 'Object') { + throw webidl.errors.exception({ + header: 'Record', + message: `Value of type ${webidl.util.Type(O)} is not an Object.` + }) } - const err = new RequestRetryError('Request failed', statusCode, { - headers, - count: this.retryCount - }) - - this.abort(err) + // 2. Let result be a new empty instance of record. + const result = {} - return false - } + if (!types.isProxy(O)) { + // Object.keys only returns enumerable properties + const keys = Object.keys(O) - onData (chunk) { - this.start += chunk.length + for (const key of keys) { + // 1. Let typedKey be key converted to an IDL value of type K. + const typedKey = keyConverter(key) - return this.handler.onData(chunk) - } + // 2. Let value be ? Get(O, key). + // 3. Let typedValue be value converted to an IDL value of type V. + const typedValue = valueConverter(O[key]) - onComplete (rawTrailers) { - this.retryCount = 0 - return this.handler.onComplete(rawTrailers) - } + // 4. Set result[typedKey] to typedValue. + result[typedKey] = typedValue + } - onError (err) { - if (this.aborted || isDisturbed(this.opts.body)) { - return this.handler.onError(err) + // 5. Return result. + return result } - this.retryOpts.retry( - err, - { - state: { counter: this.retryCount++, currentTimeout: this.retryAfter }, - opts: { retryOptions: this.retryOpts, ...this.opts } - }, - onRetry.bind(this) - ) + // 3. Let keys be ? O.[[OwnPropertyKeys]](). + const keys = Reflect.ownKeys(O) - function onRetry (err) { - if (err != null || this.aborted || isDisturbed(this.opts.body)) { - return this.handler.onError(err) - } + // 4. For each key of keys. + for (const key of keys) { + // 1. Let desc be ? O.[[GetOwnProperty]](key). + const desc = Reflect.getOwnPropertyDescriptor(O, key) - if (this.start !== 0) { - this.opts = { - ...this.opts, - headers: { - ...this.opts.headers, - range: `bytes=${this.start}-${this.end ?? ''}` - } - } - } + // 2. If desc is not undefined and desc.[[Enumerable]] is true: + if (desc?.enumerable) { + // 1. Let typedKey be key converted to an IDL value of type K. + const typedKey = keyConverter(key) - try { - this.dispatch(this.opts, this) - } catch (err) { - this.handler.onError(err) + // 2. Let value be ? Get(O, key). + // 3. Let typedValue be value converted to an IDL value of type V. + const typedValue = valueConverter(O[key]) + + // 4. Set result[typedKey] to typedValue. + result[typedKey] = typedValue } } + + // 5. Return result. + return result } } -module.exports = RetryHandler +webidl.interfaceConverter = function (i) { + return (V, opts = {}) => { + if (opts.strict !== false && !(V instanceof i)) { + throw webidl.errors.exception({ + header: i.name, + message: `Expected ${V} to be an instance of ${i.name}.` + }) + } + return V + } +} -/***/ }), +webidl.dictionaryConverter = function (converters) { + return (dictionary) => { + const type = webidl.util.Type(dictionary) + const dict = {} -/***/ 8861: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (type === 'Null' || type === 'Undefined') { + return dict + } else if (type !== 'Object') { + throw webidl.errors.exception({ + header: 'Dictionary', + message: `Expected ${dictionary} to be one of: Null, Undefined, Object.` + }) + } -"use strict"; + for (const options of converters) { + const { key, defaultValue, required, converter } = options + if (required === true) { + if (!hasOwn(dictionary, key)) { + throw webidl.errors.exception({ + header: 'Dictionary', + message: `Missing required key "${key}".` + }) + } + } -const RedirectHandler = __nccwpck_require__(2860) + let value = dictionary[key] + const hasDefault = hasOwn(options, 'defaultValue') -function createRedirectInterceptor ({ maxRedirections: defaultMaxRedirections }) { - return (dispatch) => { - return function Intercept (opts, handler) { - const { maxRedirections = defaultMaxRedirections } = opts + // Only use defaultValue if value is undefined and + // a defaultValue options was provided. + if (hasDefault && value !== null) { + value = value ?? defaultValue + } - if (!maxRedirections) { - return dispatch(opts, handler) + // A key can be optional and have no default value. + // When this happens, do not perform a conversion, + // and do not assign the key a value. + if (required || hasDefault || value !== undefined) { + value = converter(value) + + if ( + options.allowedValues && + !options.allowedValues.includes(value) + ) { + throw webidl.errors.exception({ + header: 'Dictionary', + message: `${value} is not an accepted type. Expected one of ${options.allowedValues.join(', ')}.` + }) + } + + dict[key] = value } + } - const redirectHandler = new RedirectHandler(dispatch, maxRedirections, opts, handler) - opts = { ...opts, maxRedirections: 0 } // Stop sub dispatcher from also redirecting. - return dispatch(opts, redirectHandler) + return dict + } +} + +webidl.nullableConverter = function (converter) { + return (V) => { + if (V === null) { + return V } + + return converter(V) } } -module.exports = createRedirectInterceptor - - -/***/ }), - -/***/ 953: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +// https://webidl.spec.whatwg.org/#es-DOMString +webidl.converters.DOMString = function (V, opts = {}) { + // 1. If V is null and the conversion is to an IDL type + // associated with the [LegacyNullToEmptyString] + // extended attribute, then return the DOMString value + // that represents the empty string. + if (V === null && opts.legacyNullToEmptyString) { + return '' + } -"use strict"; + // 2. Let x be ? ToString(V). + if (typeof V === 'symbol') { + throw new TypeError('Could not convert argument of type symbol to string.') + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.SPECIAL_HEADERS = exports.HEADER_STATE = exports.MINOR = exports.MAJOR = exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS = exports.TOKEN = exports.STRICT_TOKEN = exports.HEX = exports.URL_CHAR = exports.STRICT_URL_CHAR = exports.USERINFO_CHARS = exports.MARK = exports.ALPHANUM = exports.NUM = exports.HEX_MAP = exports.NUM_MAP = exports.ALPHA = exports.FINISH = exports.H_METHOD_MAP = exports.METHOD_MAP = exports.METHODS_RTSP = exports.METHODS_ICE = exports.METHODS_HTTP = exports.METHODS = exports.LENIENT_FLAGS = exports.FLAGS = exports.TYPE = exports.ERROR = void 0; -const utils_1 = __nccwpck_require__(1891); -// C headers -var ERROR; -(function (ERROR) { - ERROR[ERROR["OK"] = 0] = "OK"; - ERROR[ERROR["INTERNAL"] = 1] = "INTERNAL"; - ERROR[ERROR["STRICT"] = 2] = "STRICT"; - ERROR[ERROR["LF_EXPECTED"] = 3] = "LF_EXPECTED"; - ERROR[ERROR["UNEXPECTED_CONTENT_LENGTH"] = 4] = "UNEXPECTED_CONTENT_LENGTH"; - ERROR[ERROR["CLOSED_CONNECTION"] = 5] = "CLOSED_CONNECTION"; - ERROR[ERROR["INVALID_METHOD"] = 6] = "INVALID_METHOD"; - ERROR[ERROR["INVALID_URL"] = 7] = "INVALID_URL"; - ERROR[ERROR["INVALID_CONSTANT"] = 8] = "INVALID_CONSTANT"; - ERROR[ERROR["INVALID_VERSION"] = 9] = "INVALID_VERSION"; - ERROR[ERROR["INVALID_HEADER_TOKEN"] = 10] = "INVALID_HEADER_TOKEN"; - ERROR[ERROR["INVALID_CONTENT_LENGTH"] = 11] = "INVALID_CONTENT_LENGTH"; - ERROR[ERROR["INVALID_CHUNK_SIZE"] = 12] = "INVALID_CHUNK_SIZE"; - ERROR[ERROR["INVALID_STATUS"] = 13] = "INVALID_STATUS"; - ERROR[ERROR["INVALID_EOF_STATE"] = 14] = "INVALID_EOF_STATE"; - ERROR[ERROR["INVALID_TRANSFER_ENCODING"] = 15] = "INVALID_TRANSFER_ENCODING"; - ERROR[ERROR["CB_MESSAGE_BEGIN"] = 16] = "CB_MESSAGE_BEGIN"; - ERROR[ERROR["CB_HEADERS_COMPLETE"] = 17] = "CB_HEADERS_COMPLETE"; - ERROR[ERROR["CB_MESSAGE_COMPLETE"] = 18] = "CB_MESSAGE_COMPLETE"; - ERROR[ERROR["CB_CHUNK_HEADER"] = 19] = "CB_CHUNK_HEADER"; - ERROR[ERROR["CB_CHUNK_COMPLETE"] = 20] = "CB_CHUNK_COMPLETE"; - ERROR[ERROR["PAUSED"] = 21] = "PAUSED"; - ERROR[ERROR["PAUSED_UPGRADE"] = 22] = "PAUSED_UPGRADE"; - ERROR[ERROR["PAUSED_H2_UPGRADE"] = 23] = "PAUSED_H2_UPGRADE"; - ERROR[ERROR["USER"] = 24] = "USER"; -})(ERROR = exports.ERROR || (exports.ERROR = {})); -var TYPE; -(function (TYPE) { - TYPE[TYPE["BOTH"] = 0] = "BOTH"; - TYPE[TYPE["REQUEST"] = 1] = "REQUEST"; - TYPE[TYPE["RESPONSE"] = 2] = "RESPONSE"; -})(TYPE = exports.TYPE || (exports.TYPE = {})); -var FLAGS; -(function (FLAGS) { - FLAGS[FLAGS["CONNECTION_KEEP_ALIVE"] = 1] = "CONNECTION_KEEP_ALIVE"; - FLAGS[FLAGS["CONNECTION_CLOSE"] = 2] = "CONNECTION_CLOSE"; - FLAGS[FLAGS["CONNECTION_UPGRADE"] = 4] = "CONNECTION_UPGRADE"; - FLAGS[FLAGS["CHUNKED"] = 8] = "CHUNKED"; - FLAGS[FLAGS["UPGRADE"] = 16] = "UPGRADE"; - FLAGS[FLAGS["CONTENT_LENGTH"] = 32] = "CONTENT_LENGTH"; - FLAGS[FLAGS["SKIPBODY"] = 64] = "SKIPBODY"; - FLAGS[FLAGS["TRAILING"] = 128] = "TRAILING"; - // 1 << 8 is unused - FLAGS[FLAGS["TRANSFER_ENCODING"] = 512] = "TRANSFER_ENCODING"; -})(FLAGS = exports.FLAGS || (exports.FLAGS = {})); -var LENIENT_FLAGS; -(function (LENIENT_FLAGS) { - LENIENT_FLAGS[LENIENT_FLAGS["HEADERS"] = 1] = "HEADERS"; - LENIENT_FLAGS[LENIENT_FLAGS["CHUNKED_LENGTH"] = 2] = "CHUNKED_LENGTH"; - LENIENT_FLAGS[LENIENT_FLAGS["KEEP_ALIVE"] = 4] = "KEEP_ALIVE"; -})(LENIENT_FLAGS = exports.LENIENT_FLAGS || (exports.LENIENT_FLAGS = {})); -var METHODS; -(function (METHODS) { - METHODS[METHODS["DELETE"] = 0] = "DELETE"; - METHODS[METHODS["GET"] = 1] = "GET"; - METHODS[METHODS["HEAD"] = 2] = "HEAD"; - METHODS[METHODS["POST"] = 3] = "POST"; - METHODS[METHODS["PUT"] = 4] = "PUT"; - /* pathological */ - METHODS[METHODS["CONNECT"] = 5] = "CONNECT"; - METHODS[METHODS["OPTIONS"] = 6] = "OPTIONS"; - METHODS[METHODS["TRACE"] = 7] = "TRACE"; - /* WebDAV */ - METHODS[METHODS["COPY"] = 8] = "COPY"; - METHODS[METHODS["LOCK"] = 9] = "LOCK"; - METHODS[METHODS["MKCOL"] = 10] = "MKCOL"; - METHODS[METHODS["MOVE"] = 11] = "MOVE"; - METHODS[METHODS["PROPFIND"] = 12] = "PROPFIND"; - METHODS[METHODS["PROPPATCH"] = 13] = "PROPPATCH"; - METHODS[METHODS["SEARCH"] = 14] = "SEARCH"; - METHODS[METHODS["UNLOCK"] = 15] = "UNLOCK"; - METHODS[METHODS["BIND"] = 16] = "BIND"; - METHODS[METHODS["REBIND"] = 17] = "REBIND"; - METHODS[METHODS["UNBIND"] = 18] = "UNBIND"; - METHODS[METHODS["ACL"] = 19] = "ACL"; - /* subversion */ - METHODS[METHODS["REPORT"] = 20] = "REPORT"; - METHODS[METHODS["MKACTIVITY"] = 21] = "MKACTIVITY"; - METHODS[METHODS["CHECKOUT"] = 22] = "CHECKOUT"; - METHODS[METHODS["MERGE"] = 23] = "MERGE"; - /* upnp */ - METHODS[METHODS["M-SEARCH"] = 24] = "M-SEARCH"; - METHODS[METHODS["NOTIFY"] = 25] = "NOTIFY"; - METHODS[METHODS["SUBSCRIBE"] = 26] = "SUBSCRIBE"; - METHODS[METHODS["UNSUBSCRIBE"] = 27] = "UNSUBSCRIBE"; - /* RFC-5789 */ - METHODS[METHODS["PATCH"] = 28] = "PATCH"; - METHODS[METHODS["PURGE"] = 29] = "PURGE"; - /* CalDAV */ - METHODS[METHODS["MKCALENDAR"] = 30] = "MKCALENDAR"; - /* RFC-2068, section 19.6.1.2 */ - METHODS[METHODS["LINK"] = 31] = "LINK"; - METHODS[METHODS["UNLINK"] = 32] = "UNLINK"; - /* icecast */ - METHODS[METHODS["SOURCE"] = 33] = "SOURCE"; - /* RFC-7540, section 11.6 */ - METHODS[METHODS["PRI"] = 34] = "PRI"; - /* RFC-2326 RTSP */ - METHODS[METHODS["DESCRIBE"] = 35] = "DESCRIBE"; - METHODS[METHODS["ANNOUNCE"] = 36] = "ANNOUNCE"; - METHODS[METHODS["SETUP"] = 37] = "SETUP"; - METHODS[METHODS["PLAY"] = 38] = "PLAY"; - METHODS[METHODS["PAUSE"] = 39] = "PAUSE"; - METHODS[METHODS["TEARDOWN"] = 40] = "TEARDOWN"; - METHODS[METHODS["GET_PARAMETER"] = 41] = "GET_PARAMETER"; - METHODS[METHODS["SET_PARAMETER"] = 42] = "SET_PARAMETER"; - METHODS[METHODS["REDIRECT"] = 43] = "REDIRECT"; - METHODS[METHODS["RECORD"] = 44] = "RECORD"; - /* RAOP */ - METHODS[METHODS["FLUSH"] = 45] = "FLUSH"; -})(METHODS = exports.METHODS || (exports.METHODS = {})); -exports.METHODS_HTTP = [ - METHODS.DELETE, - METHODS.GET, - METHODS.HEAD, - METHODS.POST, - METHODS.PUT, - METHODS.CONNECT, - METHODS.OPTIONS, - METHODS.TRACE, - METHODS.COPY, - METHODS.LOCK, - METHODS.MKCOL, - METHODS.MOVE, - METHODS.PROPFIND, - METHODS.PROPPATCH, - METHODS.SEARCH, - METHODS.UNLOCK, - METHODS.BIND, - METHODS.REBIND, - METHODS.UNBIND, - METHODS.ACL, - METHODS.REPORT, - METHODS.MKACTIVITY, - METHODS.CHECKOUT, - METHODS.MERGE, - METHODS['M-SEARCH'], - METHODS.NOTIFY, - METHODS.SUBSCRIBE, - METHODS.UNSUBSCRIBE, - METHODS.PATCH, - METHODS.PURGE, - METHODS.MKCALENDAR, - METHODS.LINK, - METHODS.UNLINK, - METHODS.PRI, - // TODO(indutny): should we allow it with HTTP? - METHODS.SOURCE, -]; -exports.METHODS_ICE = [ - METHODS.SOURCE, -]; -exports.METHODS_RTSP = [ - METHODS.OPTIONS, - METHODS.DESCRIBE, - METHODS.ANNOUNCE, - METHODS.SETUP, - METHODS.PLAY, - METHODS.PAUSE, - METHODS.TEARDOWN, - METHODS.GET_PARAMETER, - METHODS.SET_PARAMETER, - METHODS.REDIRECT, - METHODS.RECORD, - METHODS.FLUSH, - // For AirPlay - METHODS.GET, - METHODS.POST, -]; -exports.METHOD_MAP = utils_1.enumToMap(METHODS); -exports.H_METHOD_MAP = {}; -Object.keys(exports.METHOD_MAP).forEach((key) => { - if (/^H/.test(key)) { - exports.H_METHOD_MAP[key] = exports.METHOD_MAP[key]; - } -}); -var FINISH; -(function (FINISH) { - FINISH[FINISH["SAFE"] = 0] = "SAFE"; - FINISH[FINISH["SAFE_WITH_CB"] = 1] = "SAFE_WITH_CB"; - FINISH[FINISH["UNSAFE"] = 2] = "UNSAFE"; -})(FINISH = exports.FINISH || (exports.FINISH = {})); -exports.ALPHA = []; -for (let i = 'A'.charCodeAt(0); i <= 'Z'.charCodeAt(0); i++) { - // Upper case - exports.ALPHA.push(String.fromCharCode(i)); - // Lower case - exports.ALPHA.push(String.fromCharCode(i + 0x20)); -} -exports.NUM_MAP = { - 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, - 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, -}; -exports.HEX_MAP = { - 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, - 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, - A: 0XA, B: 0XB, C: 0XC, D: 0XD, E: 0XE, F: 0XF, - a: 0xa, b: 0xb, c: 0xc, d: 0xd, e: 0xe, f: 0xf, -}; -exports.NUM = [ - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', -]; -exports.ALPHANUM = exports.ALPHA.concat(exports.NUM); -exports.MARK = ['-', '_', '.', '!', '~', '*', '\'', '(', ')']; -exports.USERINFO_CHARS = exports.ALPHANUM - .concat(exports.MARK) - .concat(['%', ';', ':', '&', '=', '+', '$', ',']); -// TODO(indutny): use RFC -exports.STRICT_URL_CHAR = [ - '!', '"', '$', '%', '&', '\'', - '(', ')', '*', '+', ',', '-', '.', '/', - ':', ';', '<', '=', '>', - '@', '[', '\\', ']', '^', '_', - '`', - '{', '|', '}', '~', -].concat(exports.ALPHANUM); -exports.URL_CHAR = exports.STRICT_URL_CHAR - .concat(['\t', '\f']); -// All characters with 0x80 bit set to 1 -for (let i = 0x80; i <= 0xff; i++) { - exports.URL_CHAR.push(i); + // 3. Return the IDL DOMString value that represents the + // same sequence of code units as the one the + // ECMAScript String value x represents. + return String(V) } -exports.HEX = exports.NUM.concat(['a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F']); -/* Tokens as defined by rfc 2616. Also lowercases them. - * token = 1* - * separators = "(" | ")" | "<" | ">" | "@" - * | "," | ";" | ":" | "\" | <"> - * | "/" | "[" | "]" | "?" | "=" - * | "{" | "}" | SP | HT - */ -exports.STRICT_TOKEN = [ - '!', '#', '$', '%', '&', '\'', - '*', '+', '-', '.', - '^', '_', '`', - '|', '~', -].concat(exports.ALPHANUM); -exports.TOKEN = exports.STRICT_TOKEN.concat([' ']); -/* - * Verify that a char is a valid visible (printable) US-ASCII - * character or %x80-FF - */ -exports.HEADER_CHARS = ['\t']; -for (let i = 32; i <= 255; i++) { - if (i !== 127) { - exports.HEADER_CHARS.push(i); + +// https://webidl.spec.whatwg.org/#es-ByteString +webidl.converters.ByteString = function (V) { + // 1. Let x be ? ToString(V). + // Note: DOMString converter perform ? ToString(V) + const x = webidl.converters.DOMString(V) + + // 2. If the value of any element of x is greater than + // 255, then throw a TypeError. + for (let index = 0; index < x.length; index++) { + if (x.charCodeAt(index) > 255) { + throw new TypeError( + 'Cannot convert argument to a ByteString because the character at ' + + `index ${index} has a value of ${x.charCodeAt(index)} which is greater than 255.` + ) } + } + + // 3. Return an IDL ByteString value whose length is the + // length of x, and where the value of each element is + // the value of the corresponding element of x. + return x } -// ',' = \x44 -exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS.filter((c) => c !== 44); -exports.MAJOR = exports.NUM_MAP; -exports.MINOR = exports.MAJOR; -var HEADER_STATE; -(function (HEADER_STATE) { - HEADER_STATE[HEADER_STATE["GENERAL"] = 0] = "GENERAL"; - HEADER_STATE[HEADER_STATE["CONNECTION"] = 1] = "CONNECTION"; - HEADER_STATE[HEADER_STATE["CONTENT_LENGTH"] = 2] = "CONTENT_LENGTH"; - HEADER_STATE[HEADER_STATE["TRANSFER_ENCODING"] = 3] = "TRANSFER_ENCODING"; - HEADER_STATE[HEADER_STATE["UPGRADE"] = 4] = "UPGRADE"; - HEADER_STATE[HEADER_STATE["CONNECTION_KEEP_ALIVE"] = 5] = "CONNECTION_KEEP_ALIVE"; - HEADER_STATE[HEADER_STATE["CONNECTION_CLOSE"] = 6] = "CONNECTION_CLOSE"; - HEADER_STATE[HEADER_STATE["CONNECTION_UPGRADE"] = 7] = "CONNECTION_UPGRADE"; - HEADER_STATE[HEADER_STATE["TRANSFER_ENCODING_CHUNKED"] = 8] = "TRANSFER_ENCODING_CHUNKED"; -})(HEADER_STATE = exports.HEADER_STATE || (exports.HEADER_STATE = {})); -exports.SPECIAL_HEADERS = { - 'connection': HEADER_STATE.CONNECTION, - 'content-length': HEADER_STATE.CONTENT_LENGTH, - 'proxy-connection': HEADER_STATE.CONNECTION, - 'transfer-encoding': HEADER_STATE.TRANSFER_ENCODING, - 'upgrade': HEADER_STATE.UPGRADE, -}; -//# sourceMappingURL=constants.js.map -/***/ }), +// https://webidl.spec.whatwg.org/#es-USVString +webidl.converters.USVString = toUSVString -/***/ 1145: -/***/ ((module) => { +// https://webidl.spec.whatwg.org/#es-boolean +webidl.converters.boolean = function (V) { + // 1. Let x be the result of computing ToBoolean(V). + const x = Boolean(V) -module.exports = 'AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAwABBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJs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ADcDACAAQShqQgA3AwAgAEEgakIANwMAIABBEGpCADcDACAAQQhqQgA3AwAgAEHdATYCHEEAC3sBAX8CQCAAKAIMIgMNAAJAIAAoAgRFDQAgACABNgIECwJAIAAgASACEMSAgIAAIgMNACAAKAIMDwsgACADNgIcQQAhAyAAKAIEIgFFDQAgACABIAIgACgCCBGBgICAAAAiAUUNACAAIAI2AhQgACABNgIMIAEhAwsgAwvk8wEDDn8DfgR/I4CAgIAAQRBrIgMkgICAgAAgASEEIAEhBSABIQYgASEHIAEhCCABIQkgASEKIAEhCyABIQwgASENIAEhDiABIQ8CQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgACgCHCIQQX9qDt0B2gEB2QECAwQFBgcICQoLDA0O2AEPENcBERLWARMUFRYXGBkaG+AB3wEcHR7VAR8gISIjJCXUASYnKCkqKyzTAdIBLS7RAdABLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVG2wFHSElKzwHOAUvNAUzMAU1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+f4ABgQGCAYMBhAGFAYYBhwGIAYkB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QAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAC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FCAAIBA2AgxBACEQDLIBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxNCyAAQdMANgIcIAAgATYCFCAAIBA2AgxBACEQDLEBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxRCyAAQeUANgIcIAAgATYCFCAAIBA2AgxBACEQDLABCyAAQQA2AhwgACABNgIUIABBxoqAgAA2AhAgAEEHNgIMQQAhEAyvAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMSQsgAEHSADYCHCAAIAE2AhQgACAQNgIMQQAhEAyuAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMSQsgAEHTADYCHCAAIAE2AhQgACAQNgIMQQAhEAytAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMTQsgAEHlADYCHCAAIAE2AhQgACAQNgIMQQAhEAysAQsgAEEANgIcIAAgATYCFCAAQdyIgIAANgIQIABBBzYCDEEAIRAMqwELIBBBP0cNASABQQFqIQELQQUhEAyQAQtBACEQIABBADYCHCAAIAE2AhQgAEH9koCAADYCECAAQQc2AgwMqAELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEILIABB0gA2AhwgACABNgIUIAAgEDYCDEEAIRAMpwELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEILIABB0wA2AhwgACABNgIUIAAgEDYCDEEAIRAMpgELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEYLIABB5QA2AhwgACABNgIUIAAgEDYCDEEAIRAMpQELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDD8LIABB0gA2AhwgACAUNgIUIAAgATYCDEEAIRAMpAELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDD8LIABB0wA2AhwgACAUNgIUIAAgATYCDEEAIRAMowELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDEMLIABB5QA2AhwgACAU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YWdlX2JlZ2luYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlYCBjYWxsYmFjayBlcnJvcgBgb25fc3RhdHVzX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdmVyc2lvbl9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3VybF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWVzc2FnZV9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX21ldGhvZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lYCBjYWxsYmFjayBlcnJvcgBVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNlcnZlcgBJbnZhbGlkIGhlYWRlciB2YWx1ZSBjaGFyAEludmFsaWQgaGVhZGVyIGZpZWxkIGNoYXIAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl92ZXJzaW9uAEludmFsaWQgbWlub3IgdmVyc2lvbgBJbnZhbGlkIG1ham9yIHZlcnNpb24ARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgdmVyc2lvbgBFeHBlY3RlZCBDUkxGIGFmdGVyIHZlcnNpb24ASW52YWxpZCBIVFRQIHZlcnNpb24ASW52YWxpZCBoZWFkZXIgdG9rZW4AU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl91cmwASW52YWxpZCBjaGFyYWN0ZXJzIGluIHVybABVbmV4cGVjdGVkIHN0YXJ0IGNoYXIgaW4gdXJsAERvdWJsZSBAIGluIHVybABFbXB0eSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXJhY3RlciBpbiBDb250ZW50LUxlbmd0aABEdXBsaWNhdGUgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyIGluIHVybCBwYXRoAENvbnRlbnQtTGVuZ3RoIGNhbid0IGJlIHByZXNlbnQgd2l0aCBUcmFuc2Zlci1FbmNvZGluZwBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBzaXplAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX3ZhbHVlAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgdmFsdWUATWlzc2luZyBleHBlY3RlZCBMRiBhZnRlciBoZWFkZXIgdmFsdWUASW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHF1b3RlIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGVkIHZhbHVlAFBhdXNlZCBieSBvbl9oZWFkZXJzX2NvbXBsZXRlAEludmFsaWQgRU9GIHN0YXRlAG9uX3Jlc2V0IHBhdXNlAG9uX2NodW5rX2hlYWRlciBwYXVzZQBvbl9tZXNzYWdlX2JlZ2luIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZSBwYXVzZQBvbl9zdGF0dXNfY29tcGxldGUgcGF1c2UAb25fdmVyc2lvbl9jb21wbGV0ZSBwYXVzZQBvbl91cmxfY29tcGxldGUgcGF1c2UAb25fY2h1bmtfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlIHBhdXNlAG9uX21lc3NhZ2VfY29tcGxldGUgcGF1c2UAb25fbWV0aG9kX2NvbXBsZXRlIHBhdXNlAG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19leHRlbnNpb25fbmFtZSBwYXVzZQBVbmV4cGVjdGVkIHNwYWNlIGFmdGVyIHN0YXJ0IGxpbmUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fbmFtZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIG5hbWUAUGF1c2Ugb24gQ09OTkVDVC9VcGdyYWRlAFBhdXNlIG9uIFBSSS9VcGdyYWRlAEV4cGVjdGVkIEhUVFAvMiBDb25uZWN0aW9uIFByZWZhY2UAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9tZXRob2QARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgbWV0aG9kAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX2ZpZWxkAFBhdXNlZABJbnZhbGlkIHdvcmQgZW5jb3VudGVyZWQASW52YWxpZCBtZXRob2QgZW5jb3VudGVyZWQAVW5leHBlY3RlZCBjaGFyIGluIHVybCBzY2hlbWEAUmVxdWVzdCBoYXMgaW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgAFNXSVRDSF9QUk9YWQBVU0VfUFJPWFkATUtBQ1RJVklUWQBVTlBST0NFU1NBQkxFX0VOVElUWQBDT1BZAE1PVkVEX1BFUk1BTkVOVExZAFRPT19FQVJMWQBOT1RJRlkARkFJTEVEX0RFUEVOREVOQ1kAQkFEX0dBVEVXQVkAUExBWQBQVVQAQ0hFQ0tPVVQAR0FURVdBWV9USU1FT1VUAFJFUVVFU1RfVElNRU9VVABORVRXT1JLX0NPTk5FQ1RfVElNRU9VVABDT05ORUNUSU9OX1RJTUVPVVQATE9HSU5fVElNRU9VVABORVRXT1JLX1JFQURfVElNRU9VVABQT1NUAE1JU0RJUkVDVEVEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9SRVFVRVNUAENMSUVOVF9DTE9TRURfTE9BRF9CQUxBTkNFRF9SRVFVRVNUAEJBRF9SRVFVRVNUAEhUVFBfUkVRVUVTVF9TRU5UX1RPX0hUVFBTX1BPUlQAUkVQT1JUAElNX0FfVEVBUE9UAFJFU0VUX0NPTlRFTlQATk9fQ09OVEVOVABQQVJUSUFMX0NPTlRFTlQASFBFX0lOVkFMSURfQ09OU1RBTlQASFBFX0NCX1JFU0VUAEdFVABIUEVfU1RSSUNUAENPTkZMSUNUAFRFTVBPUkFSWV9SRURJUkVDVABQRVJNQU5FTlRfUkVESVJFQ1QAQ09OTkVDVABNVUxUSV9TVEFUVVMASFBFX0lOVkFMSURfU1RBVFVTAFRPT19NQU5ZX1JFUVVFU1RTAEVBUkxZX0hJTlRTAFVOQVZBSUxBQkxFX0ZPUl9MRUdBTF9SRUFTT05TAE9QVElPTlMAU1dJVENISU5HX1BST1RPQ09MUwBWQVJJQU5UX0FMU09fTkVHT1RJQVRFUwBNVUxUSVBMRV9DSE9JQ0VTAElOVEVSTkFMX1NFUlZFUl9FUlJPUgBXRUJfU0VSVkVSX1VOS05PV05fRVJST1IAUkFJTEdVTl9FUlJPUgBJREVOVElUWV9QUk9WSURFUl9BVVRIRU5USUNBVElPTl9FUlJPUgBTU0xfQ0VSVElGSUNBVEVfRVJST1IASU5WQUxJRF9YX0ZPUldBUkRFRF9GT1IAU0VUX1BBUkFNRVRFUgBHRVRfUEFSQU1FVEVSAEhQRV9VU0VSAFNFRV9PVEhFUgBIUEVfQ0JfQ0hVTktfSEVBREVSAE1LQ0FMRU5EQVIAU0VUVVAAV0VCX1NFUlZFUl9JU19ET1dOAFRFQVJET1dOAEhQRV9DTE9TRURfQ09OTkVDVElPTgBIRVVSSVNUSUNfRVhQSVJBVElPTgBESVNDT05ORUNURURfT1BFUkFUSU9OAE5PTl9BVVRIT1JJVEFUSVZFX0lORk9STUFUSU9OAEhQRV9JTlZBTElEX1ZFUlNJT04ASFBFX0NCX01FU1NBR0VfQkVHSU4AU0lURV9JU19GUk9aRU4ASFBFX0lOVkFMSURfSEVBREVSX1RPS0VOAElOVkFMSURfVE9LRU4ARk9SQklEREVOAEVOSEFOQ0VfWU9VUl9DQUxNAEhQRV9JTlZBTElEX1VSTABCTE9DS0VEX0JZX1BBUkVOVEFMX0NPTlRST0wATUtDT0wAQUNMAEhQRV9JTlRFUk5BTABSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFX1VOT0ZGSUNJQUwASFBFX09LAFVOTElOSwBVTkxPQ0sAUFJJAFJFVFJZX1dJVEgASFBFX0lOVkFMSURfQ09OVEVOVF9MRU5HVEgASFBFX1VORVhQRUNURURfQ09OVEVOVF9MRU5HVEgARkxVU0gAUFJPUFBBVENIAE0tU0VBUkNIAFVSSV9UT09fTE9ORwBQUk9DRVNTSU5HAE1JU0NFTExBTkVPVVNfUEVSU0lTVEVOVF9XQVJOSU5HAE1JU0NFTExBTkVPVVNfV0FSTklORwBIUEVfSU5WQUxJRF9UUkFOU0ZFUl9FTkNPRElORwBFeHBlY3RlZCBDUkxGAEhQRV9JTlZBTElEX0NIVU5LX1NJWkUATU9WRQBDT05USU5VRQBIUEVfQ0JfU1RBVFVTX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJTX0NPTVBMRVRFAEhQRV9DQl9WRVJTSU9OX0NPTVBMRVRFAEhQRV9DQl9VUkxfQ09NUExFVEUASFBFX0NCX0NIVU5LX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfVkFMVUVfQ09NUExFVEUASFBFX0NCX0NIVU5LX0VYVEVOU0lPTl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX05BTUVfQ09NUExFVEUASFBFX0NCX01FU1NBR0VfQ09NUExFVEUASFBFX0NCX01FVEhPRF9DT01QTEVURQBIUEVfQ0JfSEVBREVSX0ZJRUxEX0NPTVBMRVRFAERFTEVURQBIUEVfSU5WQUxJRF9FT0ZfU1RBVEUASU5WQUxJRF9TU0xfQ0VSVElGSUNBVEUAUEFVU0UATk9fUkVTUE9OU0UAVU5TVVBQT1JURURfTUVESUFfVFlQRQBHT05FAE5PVF9BQ0NFUFRBQkxFAFNFUlZJQ0VfVU5BVkFJTEFCTEUAUkFOR0VfTk9UX1NBVElTRklBQkxFAE9SSUdJTl9JU19VTlJFQUNIQUJMRQBSRVNQT05TRV9JU19TVEFMRQBQVVJHRQBNRVJHRQBSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFAFJFUVVFU1RfSEVBREVSX1RPT19MQVJHRQBQQVlMT0FEX1RPT19MQVJHRQBJTlNVRkZJQ0lFTlRfU1RPUkFHRQBIUEVfUEFVU0VEX1VQR1JBREUASFBFX1BBVVNFRF9IMl9VUEdSQURFAFNPVVJDRQBBTk5PVU5DRQBUUkFDRQBIUEVfVU5FWFBFQ1RFRF9TUEFDRQBERVNDUklCRQBVTlNVQlNDUklCRQBSRUNPUkQASFBFX0lOVkFMSURfTUVUSE9EAE5PVF9GT1VORABQUk9QRklORABVTkJJTkQAUkVCSU5EAFVOQVVUSE9SSVpFRABNRVRIT0RfTk9UX0FMTE9XRUQASFRUUF9WRVJTSU9OX05PVF9TVVBQT1JURUQAQUxSRUFEWV9SRVBPUlRFRABBQ0NFUFRFRABOT1RfSU1QTEVNRU5URUQATE9PUF9ERVRFQ1RFRABIUEVfQ1JfRVhQRUNURUQASFBFX0xGX0VYUEVDVEVEAENSRUFURUQASU1fVVNFRABIUEVfUEFVU0VEAFRJTUVPVVRfT0NDVVJFRABQQVlNRU5UX1JFUVVJUkVEAFBSRUNPTkRJVElPTl9SRVFVSVJFRABQUk9YWV9BVVRIRU5USUNBVElPTl9SRVFVSVJFRABORVRXT1JLX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAExFTkdUSF9SRVFVSVJFRABTU0xfQ0VSVElGSUNBVEVfUkVRVUlSRUQAVVBHUkFERV9SRVFVSVJFRABQQUdFX0VYUElSRUQAUFJFQ09ORElUSU9OX0ZBSUxFRABFWFBFQ1RBVElPTl9GQUlMRUQAUkVWQUxJREFUSU9OX0ZBSUxFRABTU0xfSEFORFNIQUtFX0ZBSUxFRABMT0NLRUQAVFJBTlNGT1JNQVRJT05fQVBQTElFRABOT1RfTU9ESUZJRUQATk9UX0VYVEVOREVEAEJBTkRXSURUSF9MSU1JVF9FWENFRURFRABTSVRFX0lTX09WRVJMT0FERUQASEVBRABFeHBlY3RlZCBIVFRQLwAAXhMAACYTAAAwEAAA8BcAAJ0TAAAVEgAAORcAAPASAAAKEAAAdRIAAK0SAACCEwAATxQAAH8QAACgFQAAIxQAAIkSAACLFAAATRUAANQRAADPFAAAEBgAAMkWAADcFgAAwREAAOAXAAC7FAAAdBQAAHwVAADlFAAACBcAAB8QAABlFQAAoxQAACgVAAACFQAAmRUAACwQAACLGQAATw8AANQOAABqEAAAzhAAAAIXAACJDgAAbhMAABwTAABmFAAAVhcAAMETAADNEwAAbBMAAGgXAABmFwAAXxcAACITAADODwAAaQ4AANgOAABjFgAAyxMAAKoOAAAoFwAAJhcAAMUTAABdFgAA6BEAAGcTAABlEwAA8hYAAHMTAAAdFwAA+RYAAPMRAADPDgAAzhUAAAwSAACzEQAApREAAGEQAAAyFwAAuxMAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIDAgICAgIAAAICAAICAAICAgICAgICAgIABAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAICAgICAAACAgACAgACAgICAgICAgICAAMABAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbG9zZWVlcC1hbGl2ZQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBY2h1bmtlZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAQEBAQEAAAEBAAEBAAEBAQEBAQEBAQEAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABlY3Rpb25lbnQtbGVuZ3Rob25yb3h5LWNvbm5lY3Rpb24AAAAAAAAAAAAAAAAAAAByYW5zZmVyLWVuY29kaW5ncGdyYWRlDQoNCg0KU00NCg0KVFRQL0NFL1RTUC8AAAAAAAAAAAAAAAABAgABAwAAAAAAAAAAAAAAAAAAAAAAAAQBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQIAAQMAAAAAAAAAAAAAAAAAAAAAAAAEAQEFAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAQAAAgAAAAAAAAAAAAAAAAAAAAAAAAMEAAAEBAQEBAQEBAQEBAUEBAQEBAQEBAQEBAQABAAGBwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAABAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAIAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABOT1VOQ0VFQ0tPVVRORUNURVRFQ1JJQkVMVVNIRVRFQURTRUFSQ0hSR0VDVElWSVRZTEVOREFSVkVPVElGWVBUSU9OU0NIU0VBWVNUQVRDSEdFT1JESVJFQ1RPUlRSQ0hQQVJBTUVURVJVUkNFQlNDUklCRUFSRE9XTkFDRUlORE5LQ0tVQlNDUklCRUhUVFAvQURUUC8=' + // 2. Return the IDL boolean value that is the one that represents + // the same truth value as the ECMAScript Boolean value x. + return x +} +// https://webidl.spec.whatwg.org/#es-any +webidl.converters.any = function (V) { + return V +} -/***/ }), +// https://webidl.spec.whatwg.org/#es-long-long +webidl.converters['long long'] = function (V) { + // 1. Let x be ? ConvertToInt(V, 64, "signed"). + const x = webidl.util.ConvertToInt(V, 64, 'signed') -/***/ 5627: -/***/ ((module) => { + // 2. Return the IDL long long value that represents + // the same numeric value as x. + return x +} -module.exports = 'AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAwABBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJs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IAH9CwMAIABBMGogAf0LAwAgAEEgaiAB/QsDACAAQd0BNgIcQQALewEBfwJAIAAoAgwiAw0AAkAgACgCBEUNACAAIAE2AgQLAkAgACABIAIQxICAgAAiAw0AIAAoAgwPCyAAIAM2AhxBACEDIAAoAgQiAUUNACAAIAEgAiAAKAIIEYGAgIAAACIBRQ0AIAAgAjYCFCAAIAE2AgwgASEDCyADC+TzAQMOfwN+BH8jgICAgABBEGsiAySAgICAACABIQQgASEFIAEhBiABIQcgASEIIAEhCSABIQogASELIAEhDCABIQ0gASEOIAEhDwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAAKAIcIhBBf2oO3QHaAQHZAQIDBAUGBwgJCgsMDQ7YAQ8Q1wEREtYBExQVFhcYGRob4AHfARwdHtUBHyAhIiMkJdQBJicoKSorLNMB0gEtLtEB0AEvMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUbbAUdISUrPAc4BS80BTMwBTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gAGBAYIBgwGEAYUBhgGHAYgBiQGKAYsBjAGNAY4BjwGQAZEB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QAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIBAOxwEAAQID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YWNrIGVycm9yAGBvbl9jaHVua19leHRlbnNpb25fdmFsdWVgIGNhbGxiYWNrIGVycm9yAGBvbl9zdGF0dXNfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl92ZXJzaW9uX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdXJsX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWV0aG9kX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX25hbWVgIGNhbGxiYWNrIGVycm9yAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2VydmVyAEludmFsaWQgaGVhZGVyIHZhbHVlIGNoYXIASW52YWxpZCBoZWFkZXIgZmllbGQgY2hhcgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3ZlcnNpb24ASW52YWxpZCBtaW5vciB2ZXJzaW9uAEludmFsaWQgbWFqb3IgdmVyc2lvbgBFeHBlY3RlZCBzcGFjZSBhZnRlciB2ZXJzaW9uAEV4cGVjdGVkIENSTEYgYWZ0ZXIgdmVyc2lvbgBJbnZhbGlkIEhUVFAgdmVyc2lvbgBJbnZhbGlkIGhlYWRlciB0b2tlbgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3VybABJbnZhbGlkIGNoYXJhY3RlcnMgaW4gdXJsAFVuZXhwZWN0ZWQgc3RhcnQgY2hhciBpbiB1cmwARG91YmxlIEAgaW4gdXJsAEVtcHR5IENvbnRlbnQtTGVuZ3RoAEludmFsaWQgY2hhcmFjdGVyIGluIENvbnRlbnQtTGVuZ3RoAER1cGxpY2F0ZSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXIgaW4gdXJsIHBhdGgAQ29udGVudC1MZW5ndGggY2FuJ3QgYmUgcHJlc2VudCB3aXRoIFRyYW5zZmVyLUVuY29kaW5nAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIHNpemUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfdmFsdWUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyB2YWx1ZQBNaXNzaW5nIGV4cGVjdGVkIExGIGFmdGVyIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AgaGVhZGVyIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGUgdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZWQgdmFsdWUAUGF1c2VkIGJ5IG9uX2hlYWRlcnNfY29tcGxldGUASW52YWxpZCBFT0Ygc3RhdGUAb25fcmVzZXQgcGF1c2UAb25fY2h1bmtfaGVhZGVyIHBhdXNlAG9uX21lc3NhZ2VfYmVnaW4gcGF1c2UAb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlIHBhdXNlAG9uX3N0YXR1c19jb21wbGV0ZSBwYXVzZQBvbl92ZXJzaW9uX2NvbXBsZXRlIHBhdXNlAG9uX3VybF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19jb21wbGV0ZSBwYXVzZQBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGUgcGF1c2UAb25fbWVzc2FnZV9jb21wbGV0ZSBwYXVzZQBvbl9tZXRob2RfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lIHBhdXNlAFVuZXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgc3RhcnQgbGluZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgbmFtZQBQYXVzZSBvbiBDT05ORUNUL1VwZ3JhZGUAUGF1c2Ugb24gUFJJL1VwZ3JhZGUARXhwZWN0ZWQgSFRUUC8yIENvbm5lY3Rpb24gUHJlZmFjZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX21ldGhvZABFeHBlY3RlZCBzcGFjZSBhZnRlciBtZXRob2QAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfZmllbGQAUGF1c2VkAEludmFsaWQgd29yZCBlbmNvdW50ZXJlZABJbnZhbGlkIG1ldGhvZCBlbmNvdW50ZXJlZABVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNjaGVtYQBSZXF1ZXN0IGhhcyBpbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AAU1dJVENIX1BST1hZAFVTRV9QUk9YWQBNS0FDVElWSVRZAFVOUFJPQ0VTU0FCTEVfRU5USVRZAENPUFkATU9WRURfUEVSTUFORU5UTFkAVE9PX0VBUkxZAE5PVElGWQBGQUlMRURfREVQRU5ERU5DWQBCQURfR0FURVdBWQBQTEFZAFBVVABDSEVDS09VVABHQVRFV0FZX1RJTUVPVVQAUkVRVUVTVF9USU1FT1VUAE5FVFdPUktfQ09OTkVDVF9USU1FT1VUAENPTk5FQ1RJT05fVElNRU9VVABMT0dJTl9USU1FT1VUAE5FVFdPUktfUkVBRF9USU1FT1VUAFBPU1QATUlTRElSRUNURURfUkVRVUVTVABDTElFTlRfQ0xPU0VEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9MT0FEX0JBTEFOQ0VEX1JFUVVFU1QAQkFEX1JFUVVFU1QASFRUUF9SRVFVRVNUX1NFTlRfVE9fSFRUUFNfUE9SVABSRVBPUlQASU1fQV9URUFQT1QAUkVTRVRfQ09OVEVOVABOT19DT05URU5UAFBBUlRJQUxfQ09OVEVOVABIUEVfSU5WQUxJRF9DT05TVEFOVABIUEVfQ0JfUkVTRVQAR0VUAEhQRV9TVFJJQ1QAQ09ORkxJQ1QAVEVNUE9SQVJZX1JFRElSRUNUAFBFUk1BTkVOVF9SRURJUkVDVABDT05ORUNUAE1VTFRJX1NUQVRVUwBIUEVfSU5WQUxJRF9TVEFUVVMAVE9PX01BTllfUkVRVUVTVFMARUFSTFlfSElOVFMAVU5BVkFJTEFCTEVfRk9SX0xFR0FMX1JFQVNPTlMAT1BUSU9OUwBTV0lUQ0hJTkdfUFJPVE9DT0xTAFZBUklBTlRfQUxTT19ORUdPVElBVEVTAE1VTFRJUExFX0NIT0lDRVMASU5URVJOQUxfU0VSVkVSX0VSUk9SAFdFQl9TRVJWRVJfVU5LTk9XTl9FUlJPUgBSQUlMR1VOX0VSUk9SAElERU5USVRZX1BST1ZJREVSX0FVVEhFTlRJQ0FUSU9OX0VSUk9SAFNTTF9DRVJUSUZJQ0FURV9FUlJPUgBJTlZBTElEX1hfRk9SV0FSREVEX0ZPUgBTRVRfUEFSQU1FVEVSAEdFVF9QQVJBTUVURVIASFBFX1VTRVIAU0VFX09USEVSAEhQRV9DQl9DSFVOS19IRUFERVIATUtDQUxFTkRBUgBTRVRVUABXRUJfU0VSVkVSX0lTX0RPV04AVEVBUkRPV04ASFBFX0NMT1NFRF9DT05ORUNUSU9OAEhFVVJJU1RJQ19FWFBJUkFUSU9OAERJU0NPTk5FQ1RFRF9PUEVSQVRJT04ATk9OX0FVVEhPUklUQVRJVkVfSU5GT1JNQVRJT04ASFBFX0lOVkFMSURfVkVSU0lPTgBIUEVfQ0JfTUVTU0FHRV9CRUdJTgBTSVRFX0lTX0ZST1pFTgBIUEVfSU5WQUxJRF9IRUFERVJfVE9LRU4ASU5WQUxJRF9UT0tFTgBGT1JCSURERU4ARU5IQU5DRV9ZT1VSX0NBTE0ASFBFX0lOVkFMSURfVVJMAEJMT0NLRURfQllfUEFSRU5UQUxfQ09OVFJPTABNS0NPTABBQ0wASFBFX0lOVEVSTkFMAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0VfVU5PRkZJQ0lBTABIUEVfT0sAVU5MSU5LAFVOTE9DSwBQUkkAUkVUUllfV0lUSABIUEVfSU5WQUxJRF9DT05URU5UX0xFTkdUSABIUEVfVU5FWFBFQ1RFRF9DT05URU5UX0xFTkdUSABGTFVTSABQUk9QUEFUQ0gATS1TRUFSQ0gAVVJJX1RPT19MT05HAFBST0NFU1NJTkcATUlTQ0VMTEFORU9VU19QRVJTSVNURU5UX1dBUk5JTkcATUlTQ0VMTEFORU9VU19XQVJOSU5HAEhQRV9JTlZBTElEX1RSQU5TRkVSX0VOQ09ESU5HAEV4cGVjdGVkIENSTEYASFBFX0lOVkFMSURfQ0hVTktfU0laRQBNT1ZFAENPTlRJTlVFAEhQRV9DQl9TVEFUVVNfQ09NUExFVEUASFBFX0NCX0hFQURFUlNfQ09NUExFVEUASFBFX0NCX1ZFUlNJT05fQ09NUExFVEUASFBFX0NCX1VSTF9DT01QTEVURQBIUEVfQ0JfQ0hVTktfQ09NUExFVEUASFBFX0NCX0hFQURFUl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fTkFNRV9DT01QTEVURQBIUEVfQ0JfTUVTU0FHRV9DT01QTEVURQBIUEVfQ0JfTUVUSE9EX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfRklFTERfQ09NUExFVEUAREVMRVRFAEhQRV9JTlZBTElEX0VPRl9TVEFURQBJTlZBTElEX1NTTF9DRVJUSUZJQ0FURQBQQVVTRQBOT19SRVNQT05TRQBVTlNVUFBPUlRFRF9NRURJQV9UWVBFAEdPTkUATk9UX0FDQ0VQVEFCTEUAU0VSVklDRV9VTkFWQUlMQUJMRQBSQU5HRV9OT1RfU0FUSVNGSUFCTEUAT1JJR0lOX0lTX1VOUkVBQ0hBQkxFAFJFU1BPTlNFX0lTX1NUQUxFAFBVUkdFAE1FUkdFAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0UAUkVRVUVTVF9IRUFERVJfVE9PX0xBUkdFAFBBWUxPQURfVE9PX0xBUkdFAElOU1VGRklDSUVOVF9TVE9SQUdFAEhQRV9QQVVTRURfVVBHUkFERQBIUEVfUEFVU0VEX0gyX1VQR1JBREUAU09VUkNFAEFOTk9VTkNFAFRSQUNFAEhQRV9VTkVYUEVDVEVEX1NQQUNFAERFU0NSSUJFAFVOU1VCU0NSSUJFAFJFQ09SRABIUEVfSU5WQUxJRF9NRVRIT0QATk9UX0ZPVU5EAFBST1BGSU5EAFVOQklORABSRUJJTkQAVU5BVVRIT1JJWkVEAE1FVEhPRF9OT1RfQUxMT1dFRABIVFRQX1ZFUlNJT05fTk9UX1NVUFBPUlRFRABBTFJFQURZX1JFUE9SVEVEAEFDQ0VQVEVEAE5PVF9JTVBMRU1FTlRFRABMT09QX0RFVEVDVEVEAEhQRV9DUl9FWFBFQ1RFRABIUEVfTEZfRVhQRUNURUQAQ1JFQVRFRABJTV9VU0VEAEhQRV9QQVVTRUQAVElNRU9VVF9PQ0NVUkVEAFBBWU1FTlRfUkVRVUlSRUQAUFJFQ09ORElUSU9OX1JFUVVJUkVEAFBST1hZX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAE5FVFdPUktfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATEVOR1RIX1JFUVVJUkVEAFNTTF9DRVJUSUZJQ0FURV9SRVFVSVJFRABVUEdSQURFX1JFUVVJUkVEAFBBR0VfRVhQSVJFRABQUkVDT05ESVRJT05fRkFJTEVEAEVYUEVDVEFUSU9OX0ZBSUxFRABSRVZBTElEQVRJT05fRkFJTEVEAFNTTF9IQU5EU0hBS0VfRkFJTEVEAExPQ0tFRABUUkFOU0ZPUk1BVElPTl9BUFBMSUVEAE5PVF9NT0RJRklFRABOT1RfRVhURU5ERUQAQkFORFdJRFRIX0xJTUlUX0VYQ0VFREVEAFNJVEVfSVNfT1ZFUkxPQURFRABIRUFEAEV4cGVjdGVkIEhUVFAvAABeEwAAJhMAADAQAADwFwAAnRMAABUSAAA5FwAA8BIAAAoQAAB1EgAArRIAAIITAABPFAAAfxAAAKAVAAAjFAAAiRIAAIsUAABNFQAA1BEAAM8UAAAQGAAAyRYAANwWAADBEQAA4BcAALsUAAB0FAAAfBUAAOUUAAAIFwAAHxAAAGUVAACjFAAAKBUAAAIVAACZFQAALBAAAIsZAABPDwAA1A4AAGoQAADOEAAAAhcAAIkOAABuEwAAHBMAAGYUAABWFwAAwRMAAM0TAABsEwAAaBcAAGYXAABfFwAAIhMAAM4PAABpDgAA2A4AAGMWAADLEwAAqg4AACgXAAAmFwAAxRMAAF0WAADoEQAAZxMAAGUTAADyFgAAcxMAAB0XAAD5FgAA8xEAAM8OAADOFQAADBIAALMRAAClEQAAYRAAADIXAAC7EwAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgMCAgICAgAAAgIAAgIAAgICAgICAgICAgAEAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAAIAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAgICAgIAAAICAAICAAICAgICAgICAgIAAwAEAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsb3NlZWVwLWFsaXZlAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQFjaHVua2VkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQABAQEBAQAAAQEAAQEAAQEBAQEBAQEBAQAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGVjdGlvbmVudC1sZW5ndGhvbnJveHktY29ubmVjdGlvbgAAAAAAAAAAAAAAAAAAAHJhbnNmZXItZW5jb2RpbmdwZ3JhZGUNCg0KDQpTTQ0KDQpUVFAvQ0UvVFNQLwAAAAAAAAAAAAAAAAECAAEDAAAAAAAAAAAAAAAAAAAAAAAABAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAgABAwAAAAAAAAAAAAAAAAAAAAAAAAQBAQUBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAABAAACAAAAAAAAAAAAAAAAAAAAAAAAAwQAAAQEBAQEBAQEBAQEBQQEBAQEBAQEBAQEBAAEAAYHBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAgAAAAACAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE5PVU5DRUVDS09VVE5FQ1RFVEVDUklCRUxVU0hFVEVBRFNFQVJDSFJHRUNUSVZJVFlMRU5EQVJWRU9USUZZUFRJT05TQ0hTRUFZU1RBVENIR0VPUkRJUkVDVE9SVFJDSFBBUkFNRVRFUlVSQ0VCU0NSSUJFQVJET1dOQUNFSU5ETktDS1VCU0NSSUJFSFRUUC9BRFRQLw==' +// https://webidl.spec.whatwg.org/#es-unsigned-long-long +webidl.converters['unsigned long long'] = function (V) { + // 1. Let x be ? ConvertToInt(V, 64, "unsigned"). + const x = webidl.util.ConvertToInt(V, 64, 'unsigned') + + // 2. Return the IDL unsigned long long value that + // represents the same numeric value as x. + return x +} + +// https://webidl.spec.whatwg.org/#es-unsigned-long +webidl.converters['unsigned long'] = function (V) { + // 1. Let x be ? ConvertToInt(V, 32, "unsigned"). + const x = webidl.util.ConvertToInt(V, 32, 'unsigned') + + // 2. Return the IDL unsigned long value that + // represents the same numeric value as x. + return x +} + +// https://webidl.spec.whatwg.org/#es-unsigned-short +webidl.converters['unsigned short'] = function (V, opts) { + // 1. Let x be ? ConvertToInt(V, 16, "unsigned"). + const x = webidl.util.ConvertToInt(V, 16, 'unsigned', opts) + + // 2. Return the IDL unsigned short value that represents + // the same numeric value as x. + return x +} +// https://webidl.spec.whatwg.org/#idl-ArrayBuffer +webidl.converters.ArrayBuffer = function (V, opts = {}) { + // 1. If Type(V) is not Object, or V does not have an + // [[ArrayBufferData]] internal slot, then throw a + // TypeError. + // see: https://tc39.es/ecma262/#sec-properties-of-the-arraybuffer-instances + // see: https://tc39.es/ecma262/#sec-properties-of-the-sharedarraybuffer-instances + if ( + webidl.util.Type(V) !== 'Object' || + !types.isAnyArrayBuffer(V) + ) { + throw webidl.errors.conversionFailed({ + prefix: `${V}`, + argument: `${V}`, + types: ['ArrayBuffer'] + }) + } + + // 2. If the conversion is not to an IDL type associated + // with the [AllowShared] extended attribute, and + // IsSharedArrayBuffer(V) is true, then throw a + // TypeError. + if (opts.allowShared === false && types.isSharedArrayBuffer(V)) { + throw webidl.errors.exception({ + header: 'ArrayBuffer', + message: 'SharedArrayBuffer is not allowed.' + }) + } + + // 3. If the conversion is not to an IDL type associated + // with the [AllowResizable] extended attribute, and + // IsResizableArrayBuffer(V) is true, then throw a + // TypeError. + // Note: resizable ArrayBuffers are currently a proposal. + + // 4. Return the IDL ArrayBuffer value that is a + // reference to the same object as V. + return V +} + +webidl.converters.TypedArray = function (V, T, opts = {}) { + // 1. Let T be the IDL type V is being converted to. + + // 2. If Type(V) is not Object, or V does not have a + // [[TypedArrayName]] internal slot with a value + // equal to T’s name, then throw a TypeError. + if ( + webidl.util.Type(V) !== 'Object' || + !types.isTypedArray(V) || + V.constructor.name !== T.name + ) { + throw webidl.errors.conversionFailed({ + prefix: `${T.name}`, + argument: `${V}`, + types: [T.name] + }) + } + + // 3. If the conversion is not to an IDL type associated + // with the [AllowShared] extended attribute, and + // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is + // true, then throw a TypeError. + if (opts.allowShared === false && types.isSharedArrayBuffer(V.buffer)) { + throw webidl.errors.exception({ + header: 'ArrayBuffer', + message: 'SharedArrayBuffer is not allowed.' + }) + } + + // 4. If the conversion is not to an IDL type associated + // with the [AllowResizable] extended attribute, and + // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is + // true, then throw a TypeError. + // Note: resizable array buffers are currently a proposal + + // 5. Return the IDL value of type T that is a reference + // to the same object as V. + return V +} + +webidl.converters.DataView = function (V, opts = {}) { + // 1. If Type(V) is not Object, or V does not have a + // [[DataView]] internal slot, then throw a TypeError. + if (webidl.util.Type(V) !== 'Object' || !types.isDataView(V)) { + throw webidl.errors.exception({ + header: 'DataView', + message: 'Object is not a DataView.' + }) + } + + // 2. If the conversion is not to an IDL type associated + // with the [AllowShared] extended attribute, and + // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, + // then throw a TypeError. + if (opts.allowShared === false && types.isSharedArrayBuffer(V.buffer)) { + throw webidl.errors.exception({ + header: 'ArrayBuffer', + message: 'SharedArrayBuffer is not allowed.' + }) + } + + // 3. If the conversion is not to an IDL type associated + // with the [AllowResizable] extended attribute, and + // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is + // true, then throw a TypeError. + // Note: resizable ArrayBuffers are currently a proposal + + // 4. Return the IDL DataView value that is a reference + // to the same object as V. + return V +} + +// https://webidl.spec.whatwg.org/#BufferSource +webidl.converters.BufferSource = function (V, opts = {}) { + if (types.isAnyArrayBuffer(V)) { + return webidl.converters.ArrayBuffer(V, opts) + } + + if (types.isTypedArray(V)) { + return webidl.converters.TypedArray(V, V.constructor) + } + + if (types.isDataView(V)) { + return webidl.converters.DataView(V, opts) + } + + throw new TypeError(`Could not convert ${V} to a BufferSource.`) +} -/***/ }), +webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.ByteString +) -/***/ 1891: -/***/ ((__unused_webpack_module, exports) => { +webidl.converters['sequence>'] = webidl.sequenceConverter( + webidl.converters['sequence'] +) -"use strict"; +webidl.converters['record'] = webidl.recordConverter( + webidl.converters.ByteString, + webidl.converters.ByteString +) -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.enumToMap = void 0; -function enumToMap(obj) { - const res = {}; - Object.keys(obj).forEach((key) => { - const value = obj[key]; - if (typeof value === 'number') { - res[key] = value; - } - }); - return res; +module.exports = { + webidl } -exports.enumToMap = enumToMap; -//# sourceMappingURL=utils.js.map + /***/ }), -/***/ 6771: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 4854: +/***/ ((module) => { "use strict"; -const { kClients } = __nccwpck_require__(2785) -const Agent = __nccwpck_require__(7890) -const { - kAgent, - kMockAgentSet, - kMockAgentGet, - kDispatches, - kIsMockActive, - kNetConnect, - kGetNetConnect, - kOptions, - kFactory -} = __nccwpck_require__(4347) -const MockClient = __nccwpck_require__(8687) -const MockPool = __nccwpck_require__(6193) -const { matchValue, buildMockOptions } = __nccwpck_require__(9323) -const { InvalidArgumentError, UndiciError } = __nccwpck_require__(8045) -const Dispatcher = __nccwpck_require__(412) -const Pluralizer = __nccwpck_require__(8891) -const PendingInterceptorsFormatter = __nccwpck_require__(6823) - -class FakeWeakRef { - constructor (value) { - this.value = value +/** + * @see https://encoding.spec.whatwg.org/#concept-encoding-get + * @param {string|undefined} label + */ +function getEncoding (label) { + if (!label) { + return 'failure' } - deref () { - return this.value + // 1. Remove any leading and trailing ASCII whitespace from label. + // 2. If label is an ASCII case-insensitive match for any of the + // labels listed in the table below, then return the + // corresponding encoding; otherwise return failure. + switch (label.trim().toLowerCase()) { + case 'unicode-1-1-utf-8': + case 'unicode11utf8': + case 'unicode20utf8': + case 'utf-8': + case 'utf8': + case 'x-unicode20utf8': + return 'UTF-8' + case '866': + case 'cp866': + case 'csibm866': + case 'ibm866': + return 'IBM866' + case 'csisolatin2': + case 'iso-8859-2': + case 'iso-ir-101': + case 'iso8859-2': + case 'iso88592': + case 'iso_8859-2': + case 'iso_8859-2:1987': + case 'l2': + case 'latin2': + return 'ISO-8859-2' + case 'csisolatin3': + case 'iso-8859-3': + case 'iso-ir-109': + case 'iso8859-3': + case 'iso88593': + case 'iso_8859-3': + case 'iso_8859-3:1988': + case 'l3': + case 'latin3': + return 'ISO-8859-3' + case 'csisolatin4': + case 'iso-8859-4': + case 'iso-ir-110': + case 'iso8859-4': + case 'iso88594': + case 'iso_8859-4': + case 'iso_8859-4:1988': + case 'l4': + case 'latin4': + return 'ISO-8859-4' + case 'csisolatincyrillic': + case 'cyrillic': + case 'iso-8859-5': + case 'iso-ir-144': + case 'iso8859-5': + case 'iso88595': + case 'iso_8859-5': + case 'iso_8859-5:1988': + return 'ISO-8859-5' + case 'arabic': + case 'asmo-708': + case 'csiso88596e': + case 'csiso88596i': + case 'csisolatinarabic': + case 'ecma-114': + case 'iso-8859-6': + case 'iso-8859-6-e': + case 'iso-8859-6-i': + case 'iso-ir-127': + case 'iso8859-6': + case 'iso88596': + case 'iso_8859-6': + case 'iso_8859-6:1987': + return 'ISO-8859-6' + case 'csisolatingreek': + case 'ecma-118': + case 'elot_928': + case 'greek': + case 'greek8': + case 'iso-8859-7': + case 'iso-ir-126': + case 'iso8859-7': + case 'iso88597': + case 'iso_8859-7': + case 'iso_8859-7:1987': + case 'sun_eu_greek': + return 'ISO-8859-7' + case 'csiso88598e': + case 'csisolatinhebrew': + case 'hebrew': + case 'iso-8859-8': + case 'iso-8859-8-e': + case 'iso-ir-138': + case 'iso8859-8': + case 'iso88598': + case 'iso_8859-8': + case 'iso_8859-8:1988': + case 'visual': + return 'ISO-8859-8' + case 'csiso88598i': + case 'iso-8859-8-i': + case 'logical': + return 'ISO-8859-8-I' + case 'csisolatin6': + case 'iso-8859-10': + case 'iso-ir-157': + case 'iso8859-10': + case 'iso885910': + case 'l6': + case 'latin6': + return 'ISO-8859-10' + case 'iso-8859-13': + case 'iso8859-13': + case 'iso885913': + return 'ISO-8859-13' + case 'iso-8859-14': + case 'iso8859-14': + case 'iso885914': + return 'ISO-8859-14' + case 'csisolatin9': + case 'iso-8859-15': + case 'iso8859-15': + case 'iso885915': + case 'iso_8859-15': + case 'l9': + return 'ISO-8859-15' + case 'iso-8859-16': + return 'ISO-8859-16' + case 'cskoi8r': + case 'koi': + case 'koi8': + case 'koi8-r': + case 'koi8_r': + return 'KOI8-R' + case 'koi8-ru': + case 'koi8-u': + return 'KOI8-U' + case 'csmacintosh': + case 'mac': + case 'macintosh': + case 'x-mac-roman': + return 'macintosh' + case 'iso-8859-11': + case 'iso8859-11': + case 'iso885911': + case 'tis-620': + case 'windows-874': + return 'windows-874' + case 'cp1250': + case 'windows-1250': + case 'x-cp1250': + return 'windows-1250' + case 'cp1251': + case 'windows-1251': + case 'x-cp1251': + return 'windows-1251' + case 'ansi_x3.4-1968': + case 'ascii': + case 'cp1252': + case 'cp819': + case 'csisolatin1': + case 'ibm819': + case 'iso-8859-1': + case 'iso-ir-100': + case 'iso8859-1': + case 'iso88591': + case 'iso_8859-1': + case 'iso_8859-1:1987': + case 'l1': + case 'latin1': + case 'us-ascii': + case 'windows-1252': + case 'x-cp1252': + return 'windows-1252' + case 'cp1253': + case 'windows-1253': + case 'x-cp1253': + return 'windows-1253' + case 'cp1254': + case 'csisolatin5': + case 'iso-8859-9': + case 'iso-ir-148': + case 'iso8859-9': + case 'iso88599': + case 'iso_8859-9': + case 'iso_8859-9:1989': + case 'l5': + case 'latin5': + case 'windows-1254': + case 'x-cp1254': + return 'windows-1254' + case 'cp1255': + case 'windows-1255': + case 'x-cp1255': + return 'windows-1255' + case 'cp1256': + case 'windows-1256': + case 'x-cp1256': + return 'windows-1256' + case 'cp1257': + case 'windows-1257': + case 'x-cp1257': + return 'windows-1257' + case 'cp1258': + case 'windows-1258': + case 'x-cp1258': + return 'windows-1258' + case 'x-mac-cyrillic': + case 'x-mac-ukrainian': + return 'x-mac-cyrillic' + case 'chinese': + case 'csgb2312': + case 'csiso58gb231280': + case 'gb2312': + case 'gb_2312': + case 'gb_2312-80': + case 'gbk': + case 'iso-ir-58': + case 'x-gbk': + return 'GBK' + case 'gb18030': + return 'gb18030' + case 'big5': + case 'big5-hkscs': + case 'cn-big5': + case 'csbig5': + case 'x-x-big5': + return 'Big5' + case 'cseucpkdfmtjapanese': + case 'euc-jp': + case 'x-euc-jp': + return 'EUC-JP' + case 'csiso2022jp': + case 'iso-2022-jp': + return 'ISO-2022-JP' + case 'csshiftjis': + case 'ms932': + case 'ms_kanji': + case 'shift-jis': + case 'shift_jis': + case 'sjis': + case 'windows-31j': + case 'x-sjis': + return 'Shift_JIS' + case 'cseuckr': + case 'csksc56011987': + case 'euc-kr': + case 'iso-ir-149': + case 'korean': + case 'ks_c_5601-1987': + case 'ks_c_5601-1989': + case 'ksc5601': + case 'ksc_5601': + case 'windows-949': + return 'EUC-KR' + case 'csiso2022kr': + case 'hz-gb-2312': + case 'iso-2022-cn': + case 'iso-2022-cn-ext': + case 'iso-2022-kr': + case 'replacement': + return 'replacement' + case 'unicodefffe': + case 'utf-16be': + return 'UTF-16BE' + case 'csunicode': + case 'iso-10646-ucs-2': + case 'ucs-2': + case 'unicode': + case 'unicodefeff': + case 'utf-16': + case 'utf-16le': + return 'UTF-16LE' + case 'x-user-defined': + return 'x-user-defined' + default: return 'failure' } } -class MockAgent extends Dispatcher { - constructor (opts) { - super(opts) - - this[kNetConnect] = true - this[kIsMockActive] = true - - // Instantiate Agent and encapsulate - if ((opts && opts.agent && typeof opts.agent.dispatch !== 'function')) { - throw new InvalidArgumentError('Argument opts.agent must implement Agent') - } - const agent = opts && opts.agent ? opts.agent : new Agent(opts) - this[kAgent] = agent - - this[kClients] = agent[kClients] - this[kOptions] = buildMockOptions(opts) - } - - get (origin) { - let dispatcher = this[kMockAgentGet](origin) - - if (!dispatcher) { - dispatcher = this[kFactory](origin) - this[kMockAgentSet](origin, dispatcher) - } - return dispatcher - } - - dispatch (opts, handler) { - // Call MockAgent.get to perform additional setup before dispatching as normal - this.get(opts.origin) - return this[kAgent].dispatch(opts, handler) - } - - async close () { - await this[kAgent].close() - this[kClients].clear() - } - - deactivate () { - this[kIsMockActive] = false - } - - activate () { - this[kIsMockActive] = true - } - - enableNetConnect (matcher) { - if (typeof matcher === 'string' || typeof matcher === 'function' || matcher instanceof RegExp) { - if (Array.isArray(this[kNetConnect])) { - this[kNetConnect].push(matcher) - } else { - this[kNetConnect] = [matcher] - } - } else if (typeof matcher === 'undefined') { - this[kNetConnect] = true - } else { - throw new InvalidArgumentError('Unsupported matcher. Must be one of String|Function|RegExp.') - } - } - - disableNetConnect () { - this[kNetConnect] = false - } - - // This is required to bypass issues caused by using global symbols - see: - // https://github.com/nodejs/undici/issues/1447 - get isMockActive () { - return this[kIsMockActive] - } - - [kMockAgentSet] (origin, dispatcher) { - this[kClients].set(origin, new FakeWeakRef(dispatcher)) - } - - [kFactory] (origin) { - const mockOptions = Object.assign({ agent: this }, this[kOptions]) - return this[kOptions] && this[kOptions].connections === 1 - ? new MockClient(origin, mockOptions) - : new MockPool(origin, mockOptions) - } - - [kMockAgentGet] (origin) { - // First check if we can immediately find it - const ref = this[kClients].get(origin) - if (ref) { - return ref.deref() - } - - // If the origin is not a string create a dummy parent pool and return to user - if (typeof origin !== 'string') { - const dispatcher = this[kFactory]('http://localhost:9999') - this[kMockAgentSet](origin, dispatcher) - return dispatcher - } - - // If we match, create a pool and assign the same dispatches - for (const [keyMatcher, nonExplicitRef] of Array.from(this[kClients])) { - const nonExplicitDispatcher = nonExplicitRef.deref() - if (nonExplicitDispatcher && typeof keyMatcher !== 'string' && matchValue(keyMatcher, origin)) { - const dispatcher = this[kFactory](origin) - this[kMockAgentSet](origin, dispatcher) - dispatcher[kDispatches] = nonExplicitDispatcher[kDispatches] - return dispatcher - } - } - } - - [kGetNetConnect] () { - return this[kNetConnect] - } - - pendingInterceptors () { - const mockAgentClients = this[kClients] - - return Array.from(mockAgentClients.entries()) - .flatMap(([origin, scope]) => scope.deref()[kDispatches].map(dispatch => ({ ...dispatch, origin }))) - .filter(({ pending }) => pending) - } - - assertNoPendingInterceptors ({ pendingInterceptorsFormatter = new PendingInterceptorsFormatter() } = {}) { - const pending = this.pendingInterceptors() - - if (pending.length === 0) { - return - } - - const pluralizer = new Pluralizer('interceptor', 'interceptors').pluralize(pending.length) - - throw new UndiciError(` -${pluralizer.count} ${pluralizer.noun} ${pluralizer.is} pending: - -${pendingInterceptorsFormatter.format(pending)} -`.trim()) - } +module.exports = { + getEncoding } -module.exports = MockAgent - /***/ }), -/***/ 8687: +/***/ 1446: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { promisify } = __nccwpck_require__(3837) -const Client = __nccwpck_require__(3598) -const { buildMockDispatch } = __nccwpck_require__(9323) const { - kDispatches, - kMockAgent, - kClose, - kOriginalClose, - kOrigin, - kOriginalDispatch, - kConnected -} = __nccwpck_require__(4347) -const { MockInterceptor } = __nccwpck_require__(410) -const Symbols = __nccwpck_require__(2785) -const { InvalidArgumentError } = __nccwpck_require__(8045) - -/** - * MockClient provides an API that extends the Client to influence the mockDispatches. - */ -class MockClient extends Client { - constructor (origin, opts) { - super(origin, opts) + staticPropertyDescriptors, + readOperation, + fireAProgressEvent +} = __nccwpck_require__(7530) +const { + kState, + kError, + kResult, + kEvents, + kAborted +} = __nccwpck_require__(9054) +const { webidl } = __nccwpck_require__(1744) +const { kEnumerableProperty } = __nccwpck_require__(3983) - if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') { - throw new InvalidArgumentError('Argument opts.agent must implement Agent') +class FileReader extends EventTarget { + constructor () { + super() + + this[kState] = 'empty' + this[kResult] = null + this[kError] = null + this[kEvents] = { + loadend: null, + error: null, + abort: null, + load: null, + progress: null, + loadstart: null } + } - this[kMockAgent] = opts.agent - this[kOrigin] = origin - this[kDispatches] = [] - this[kConnected] = 1 - this[kOriginalDispatch] = this.dispatch - this[kOriginalClose] = this.close.bind(this) + /** + * @see https://w3c.github.io/FileAPI/#dfn-readAsArrayBuffer + * @param {import('buffer').Blob} blob + */ + readAsArrayBuffer (blob) { + webidl.brandCheck(this, FileReader) - this.dispatch = buildMockDispatch.call(this) - this.close = this[kClose] - } + webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsArrayBuffer' }) - get [Symbols.kConnected] () { - return this[kConnected] + blob = webidl.converters.Blob(blob, { strict: false }) + + // The readAsArrayBuffer(blob) method, when invoked, + // must initiate a read operation for blob with ArrayBuffer. + readOperation(this, blob, 'ArrayBuffer') } /** - * Sets up the base interceptor for mocking replies from undici. + * @see https://w3c.github.io/FileAPI/#readAsBinaryString + * @param {import('buffer').Blob} blob */ - intercept (opts) { - return new MockInterceptor(opts, this[kDispatches]) - } - - async [kClose] () { - await promisify(this[kOriginalClose])() - this[kConnected] = 0 - this[kMockAgent][Symbols.kClients].delete(this[kOrigin]) - } -} + readAsBinaryString (blob) { + webidl.brandCheck(this, FileReader) -module.exports = MockClient + webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsBinaryString' }) + blob = webidl.converters.Blob(blob, { strict: false }) -/***/ }), + // The readAsBinaryString(blob) method, when invoked, + // must initiate a read operation for blob with BinaryString. + readOperation(this, blob, 'BinaryString') + } -/***/ 888: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /** + * @see https://w3c.github.io/FileAPI/#readAsDataText + * @param {import('buffer').Blob} blob + * @param {string?} encoding + */ + readAsText (blob, encoding = undefined) { + webidl.brandCheck(this, FileReader) -"use strict"; + webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsText' }) + blob = webidl.converters.Blob(blob, { strict: false }) -const { UndiciError } = __nccwpck_require__(8045) + if (encoding !== undefined) { + encoding = webidl.converters.DOMString(encoding) + } -class MockNotMatchedError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, MockNotMatchedError) - this.name = 'MockNotMatchedError' - this.message = message || 'The request does not match any registered mock dispatches' - this.code = 'UND_MOCK_ERR_MOCK_NOT_MATCHED' + // The readAsText(blob, encoding) method, when invoked, + // must initiate a read operation for blob with Text and encoding. + readOperation(this, blob, 'Text', encoding) } -} -module.exports = { - MockNotMatchedError -} + /** + * @see https://w3c.github.io/FileAPI/#dfn-readAsDataURL + * @param {import('buffer').Blob} blob + */ + readAsDataURL (blob) { + webidl.brandCheck(this, FileReader) + webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsDataURL' }) -/***/ }), + blob = webidl.converters.Blob(blob, { strict: false }) -/***/ 410: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // The readAsDataURL(blob) method, when invoked, must + // initiate a read operation for blob with DataURL. + readOperation(this, blob, 'DataURL') + } -"use strict"; + /** + * @see https://w3c.github.io/FileAPI/#dfn-abort + */ + abort () { + // 1. If this's state is "empty" or if this's state is + // "done" set this's result to null and terminate + // this algorithm. + if (this[kState] === 'empty' || this[kState] === 'done') { + this[kResult] = null + return + } + + // 2. If this's state is "loading" set this's state to + // "done" and set this's result to null. + if (this[kState] === 'loading') { + this[kState] = 'done' + this[kResult] = null + } + // 3. If there are any tasks from this on the file reading + // task source in an affiliated task queue, then remove + // those tasks from that task queue. + this[kAborted] = true -const { getResponseData, buildKey, addMockDispatch } = __nccwpck_require__(9323) -const { - kDispatches, - kDispatchKey, - kDefaultHeaders, - kDefaultTrailers, - kContentLength, - kMockDispatch -} = __nccwpck_require__(4347) -const { InvalidArgumentError } = __nccwpck_require__(8045) -const { buildURL } = __nccwpck_require__(3983) + // 4. Terminate the algorithm for the read method being processed. + // TODO -/** - * Defines the scope API for an interceptor reply - */ -class MockScope { - constructor (mockDispatch) { - this[kMockDispatch] = mockDispatch + // 5. Fire a progress event called abort at this. + fireAProgressEvent('abort', this) + + // 6. If this's state is not "loading", fire a progress + // event called loadend at this. + if (this[kState] !== 'loading') { + fireAProgressEvent('loadend', this) + } } /** - * Delay a reply by a set amount in ms. + * @see https://w3c.github.io/FileAPI/#dom-filereader-readystate */ - delay (waitInMs) { - if (typeof waitInMs !== 'number' || !Number.isInteger(waitInMs) || waitInMs <= 0) { - throw new InvalidArgumentError('waitInMs must be a valid integer > 0') - } + get readyState () { + webidl.brandCheck(this, FileReader) - this[kMockDispatch].delay = waitInMs - return this + switch (this[kState]) { + case 'empty': return this.EMPTY + case 'loading': return this.LOADING + case 'done': return this.DONE + } } /** - * For a defined reply, never mark as consumed. + * @see https://w3c.github.io/FileAPI/#dom-filereader-result */ - persist () { - this[kMockDispatch].persist = true - return this + get result () { + webidl.brandCheck(this, FileReader) + + // The result attribute’s getter, when invoked, must return + // this's result. + return this[kResult] } /** - * Allow one to define a reply for a set amount of matching requests. + * @see https://w3c.github.io/FileAPI/#dom-filereader-error */ - times (repeatTimes) { - if (typeof repeatTimes !== 'number' || !Number.isInteger(repeatTimes) || repeatTimes <= 0) { - throw new InvalidArgumentError('repeatTimes must be a valid integer > 0') - } + get error () { + webidl.brandCheck(this, FileReader) - this[kMockDispatch].times = repeatTimes - return this + // The error attribute’s getter, when invoked, must return + // this's error. + return this[kError] } -} -/** - * Defines an interceptor for a Mock - */ -class MockInterceptor { - constructor (opts, mockDispatches) { - if (typeof opts !== 'object') { - throw new InvalidArgumentError('opts must be an object') - } - if (typeof opts.path === 'undefined') { - throw new InvalidArgumentError('opts.path must be defined') - } - if (typeof opts.method === 'undefined') { - opts.method = 'GET' + get onloadend () { + webidl.brandCheck(this, FileReader) + + return this[kEvents].loadend + } + + set onloadend (fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].loadend) { + this.removeEventListener('loadend', this[kEvents].loadend) } - // See https://github.com/nodejs/undici/issues/1245 - // As per RFC 3986, clients are not supposed to send URI - // fragments to servers when they retrieve a document, - if (typeof opts.path === 'string') { - if (opts.query) { - opts.path = buildURL(opts.path, opts.query) - } else { - // Matches https://github.com/nodejs/undici/blob/main/lib/fetch/index.js#L1811 - const parsedURL = new URL(opts.path, 'data://') - opts.path = parsedURL.pathname + parsedURL.search - } + + if (typeof fn === 'function') { + this[kEvents].loadend = fn + this.addEventListener('loadend', fn) + } else { + this[kEvents].loadend = null } - if (typeof opts.method === 'string') { - opts.method = opts.method.toUpperCase() + } + + get onerror () { + webidl.brandCheck(this, FileReader) + + return this[kEvents].error + } + + set onerror (fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].error) { + this.removeEventListener('error', this[kEvents].error) } - this[kDispatchKey] = buildKey(opts) - this[kDispatches] = mockDispatches - this[kDefaultHeaders] = {} - this[kDefaultTrailers] = {} - this[kContentLength] = false + if (typeof fn === 'function') { + this[kEvents].error = fn + this.addEventListener('error', fn) + } else { + this[kEvents].error = null + } } - createMockScopeDispatchData (statusCode, data, responseOptions = {}) { - const responseData = getResponseData(data) - const contentLength = this[kContentLength] ? { 'content-length': responseData.length } : {} - const headers = { ...this[kDefaultHeaders], ...contentLength, ...responseOptions.headers } - const trailers = { ...this[kDefaultTrailers], ...responseOptions.trailers } + get onloadstart () { + webidl.brandCheck(this, FileReader) - return { statusCode, data, headers, trailers } + return this[kEvents].loadstart } - validateReplyParameters (statusCode, data, responseOptions) { - if (typeof statusCode === 'undefined') { - throw new InvalidArgumentError('statusCode must be defined') - } - if (typeof data === 'undefined') { - throw new InvalidArgumentError('data must be defined') + set onloadstart (fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].loadstart) { + this.removeEventListener('loadstart', this[kEvents].loadstart) } - if (typeof responseOptions !== 'object') { - throw new InvalidArgumentError('responseOptions must be an object') + + if (typeof fn === 'function') { + this[kEvents].loadstart = fn + this.addEventListener('loadstart', fn) + } else { + this[kEvents].loadstart = null } } - /** - * Mock an undici request with a defined reply. - */ - reply (replyData) { - // Values of reply aren't available right now as they - // can only be available when the reply callback is invoked. - if (typeof replyData === 'function') { - // We'll first wrap the provided callback in another function, - // this function will properly resolve the data from the callback - // when invoked. - const wrappedDefaultsCallback = (opts) => { - // Our reply options callback contains the parameter for statusCode, data and options. - const resolvedData = replyData(opts) + get onprogress () { + webidl.brandCheck(this, FileReader) - // Check if it is in the right format - if (typeof resolvedData !== 'object') { - throw new InvalidArgumentError('reply options callback must return an object') - } + return this[kEvents].progress + } - const { statusCode, data = '', responseOptions = {} } = resolvedData - this.validateReplyParameters(statusCode, data, responseOptions) - // Since the values can be obtained immediately we return them - // from this higher order function that will be resolved later. - return { - ...this.createMockScopeDispatchData(statusCode, data, responseOptions) - } - } + set onprogress (fn) { + webidl.brandCheck(this, FileReader) - // Add usual dispatch data, but this time set the data parameter to function that will eventually provide data. - const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], wrappedDefaultsCallback) - return new MockScope(newMockDispatch) + if (this[kEvents].progress) { + this.removeEventListener('progress', this[kEvents].progress) } - // We can have either one or three parameters, if we get here, - // we should have 1-3 parameters. So we spread the arguments of - // this function to obtain the parameters, since replyData will always - // just be the statusCode. - const [statusCode, data = '', responseOptions = {}] = [...arguments] - this.validateReplyParameters(statusCode, data, responseOptions) + if (typeof fn === 'function') { + this[kEvents].progress = fn + this.addEventListener('progress', fn) + } else { + this[kEvents].progress = null + } + } - // Send in-already provided data like usual - const dispatchData = this.createMockScopeDispatchData(statusCode, data, responseOptions) - const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], dispatchData) - return new MockScope(newMockDispatch) + get onload () { + webidl.brandCheck(this, FileReader) + + return this[kEvents].load } - /** - * Mock an undici request with a defined error. - */ - replyWithError (error) { - if (typeof error === 'undefined') { - throw new InvalidArgumentError('error must be defined') + set onload (fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].load) { + this.removeEventListener('load', this[kEvents].load) } - const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], { error }) - return new MockScope(newMockDispatch) + if (typeof fn === 'function') { + this[kEvents].load = fn + this.addEventListener('load', fn) + } else { + this[kEvents].load = null + } } - /** - * Set default reply headers on the interceptor for subsequent replies - */ - defaultReplyHeaders (headers) { - if (typeof headers === 'undefined') { - throw new InvalidArgumentError('headers must be defined') - } + get onabort () { + webidl.brandCheck(this, FileReader) - this[kDefaultHeaders] = headers - return this + return this[kEvents].abort } - /** - * Set default reply trailers on the interceptor for subsequent replies - */ - defaultReplyTrailers (trailers) { - if (typeof trailers === 'undefined') { - throw new InvalidArgumentError('trailers must be defined') + set onabort (fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].abort) { + this.removeEventListener('abort', this[kEvents].abort) } - this[kDefaultTrailers] = trailers - return this + if (typeof fn === 'function') { + this[kEvents].abort = fn + this.addEventListener('abort', fn) + } else { + this[kEvents].abort = null + } } +} - /** - * Set reply content length header for replies on the interceptor - */ - replyContentLength () { - this[kContentLength] = true - return this +// https://w3c.github.io/FileAPI/#dom-filereader-empty +FileReader.EMPTY = FileReader.prototype.EMPTY = 0 +// https://w3c.github.io/FileAPI/#dom-filereader-loading +FileReader.LOADING = FileReader.prototype.LOADING = 1 +// https://w3c.github.io/FileAPI/#dom-filereader-done +FileReader.DONE = FileReader.prototype.DONE = 2 + +Object.defineProperties(FileReader.prototype, { + EMPTY: staticPropertyDescriptors, + LOADING: staticPropertyDescriptors, + DONE: staticPropertyDescriptors, + readAsArrayBuffer: kEnumerableProperty, + readAsBinaryString: kEnumerableProperty, + readAsText: kEnumerableProperty, + readAsDataURL: kEnumerableProperty, + abort: kEnumerableProperty, + readyState: kEnumerableProperty, + result: kEnumerableProperty, + error: kEnumerableProperty, + onloadstart: kEnumerableProperty, + onprogress: kEnumerableProperty, + onload: kEnumerableProperty, + onabort: kEnumerableProperty, + onerror: kEnumerableProperty, + onloadend: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'FileReader', + writable: false, + enumerable: false, + configurable: true } -} +}) -module.exports.MockInterceptor = MockInterceptor -module.exports.MockScope = MockScope +Object.defineProperties(FileReader, { + EMPTY: staticPropertyDescriptors, + LOADING: staticPropertyDescriptors, + DONE: staticPropertyDescriptors +}) + +module.exports = { + FileReader +} /***/ }), -/***/ 6193: +/***/ 5504: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { promisify } = __nccwpck_require__(3837) -const Pool = __nccwpck_require__(4634) -const { buildMockDispatch } = __nccwpck_require__(9323) -const { - kDispatches, - kMockAgent, - kClose, - kOriginalClose, - kOrigin, - kOriginalDispatch, - kConnected -} = __nccwpck_require__(4347) -const { MockInterceptor } = __nccwpck_require__(410) -const Symbols = __nccwpck_require__(2785) -const { InvalidArgumentError } = __nccwpck_require__(8045) +const { webidl } = __nccwpck_require__(1744) + +const kState = Symbol('ProgressEvent state') /** - * MockPool provides an API that extends the Pool to influence the mockDispatches. + * @see https://xhr.spec.whatwg.org/#progressevent */ -class MockPool extends Pool { - constructor (origin, opts) { - super(origin, opts) - - if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') { - throw new InvalidArgumentError('Argument opts.agent must implement Agent') - } +class ProgressEvent extends Event { + constructor (type, eventInitDict = {}) { + type = webidl.converters.DOMString(type) + eventInitDict = webidl.converters.ProgressEventInit(eventInitDict ?? {}) - this[kMockAgent] = opts.agent - this[kOrigin] = origin - this[kDispatches] = [] - this[kConnected] = 1 - this[kOriginalDispatch] = this.dispatch - this[kOriginalClose] = this.close.bind(this) + super(type, eventInitDict) - this.dispatch = buildMockDispatch.call(this) - this.close = this[kClose] + this[kState] = { + lengthComputable: eventInitDict.lengthComputable, + loaded: eventInitDict.loaded, + total: eventInitDict.total + } } - get [Symbols.kConnected] () { - return this[kConnected] + get lengthComputable () { + webidl.brandCheck(this, ProgressEvent) + + return this[kState].lengthComputable } - /** - * Sets up the base interceptor for mocking replies from undici. - */ - intercept (opts) { - return new MockInterceptor(opts, this[kDispatches]) + get loaded () { + webidl.brandCheck(this, ProgressEvent) + + return this[kState].loaded } - async [kClose] () { - await promisify(this[kOriginalClose])() - this[kConnected] = 0 - this[kMockAgent][Symbols.kClients].delete(this[kOrigin]) + get total () { + webidl.brandCheck(this, ProgressEvent) + + return this[kState].total } } -module.exports = MockPool +webidl.converters.ProgressEventInit = webidl.dictionaryConverter([ + { + key: 'lengthComputable', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'loaded', + converter: webidl.converters['unsigned long long'], + defaultValue: 0 + }, + { + key: 'total', + converter: webidl.converters['unsigned long long'], + defaultValue: 0 + }, + { + key: 'bubbles', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'cancelable', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'composed', + converter: webidl.converters.boolean, + defaultValue: false + } +]) + +module.exports = { + ProgressEvent +} /***/ }), -/***/ 4347: +/***/ 9054: /***/ ((module) => { "use strict"; module.exports = { - kAgent: Symbol('agent'), - kOptions: Symbol('options'), - kFactory: Symbol('factory'), - kDispatches: Symbol('dispatches'), - kDispatchKey: Symbol('dispatch key'), - kDefaultHeaders: Symbol('default headers'), - kDefaultTrailers: Symbol('default trailers'), - kContentLength: Symbol('content length'), - kMockAgent: Symbol('mock agent'), - kMockAgentSet: Symbol('mock agent set'), - kMockAgentGet: Symbol('mock agent get'), - kMockDispatch: Symbol('mock dispatch'), - kClose: Symbol('close'), - kOriginalClose: Symbol('original agent close'), - kOrigin: Symbol('origin'), - kIsMockActive: Symbol('is mock active'), - kNetConnect: Symbol('net connect'), - kGetNetConnect: Symbol('get net connect'), - kConnected: Symbol('connected') + kState: Symbol('FileReader state'), + kResult: Symbol('FileReader result'), + kError: Symbol('FileReader error'), + kLastProgressEventFired: Symbol('FileReader last progress event fired timestamp'), + kEvents: Symbol('FileReader events'), + kAborted: Symbol('FileReader aborted') } /***/ }), -/***/ 9323: +/***/ 7530: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { MockNotMatchedError } = __nccwpck_require__(888) -const { - kDispatches, - kMockAgent, - kOriginalDispatch, - kOrigin, - kGetNetConnect -} = __nccwpck_require__(4347) -const { buildURL, nop } = __nccwpck_require__(3983) -const { STATUS_CODES } = __nccwpck_require__(3685) const { - types: { - isPromise - } -} = __nccwpck_require__(3837) - -function matchValue (match, value) { - if (typeof match === 'string') { - return match === value - } - if (match instanceof RegExp) { - return match.test(value) - } - if (typeof match === 'function') { - return match(value) === true - } - return false -} + kState, + kError, + kResult, + kAborted, + kLastProgressEventFired +} = __nccwpck_require__(9054) +const { ProgressEvent } = __nccwpck_require__(5504) +const { getEncoding } = __nccwpck_require__(4854) +const { DOMException } = __nccwpck_require__(1037) +const { serializeAMimeType, parseMIMEType } = __nccwpck_require__(685) +const { types } = __nccwpck_require__(3837) +const { StringDecoder } = __nccwpck_require__(1576) +const { btoa } = __nccwpck_require__(4300) -function lowerCaseEntries (headers) { - return Object.fromEntries( - Object.entries(headers).map(([headerName, headerValue]) => { - return [headerName.toLocaleLowerCase(), headerValue] - }) - ) +/** @type {PropertyDescriptor} */ +const staticPropertyDescriptors = { + enumerable: true, + writable: false, + configurable: false } /** - * @param {import('../../index').Headers|string[]|Record} headers - * @param {string} key + * @see https://w3c.github.io/FileAPI/#readOperation + * @param {import('./filereader').FileReader} fr + * @param {import('buffer').Blob} blob + * @param {string} type + * @param {string?} encodingName */ -function getHeaderByName (headers, key) { - if (Array.isArray(headers)) { - for (let i = 0; i < headers.length; i += 2) { - if (headers[i].toLocaleLowerCase() === key.toLocaleLowerCase()) { - return headers[i + 1] - } - } - - return undefined - } else if (typeof headers.get === 'function') { - return headers.get(key) - } else { - return lowerCaseEntries(headers)[key.toLocaleLowerCase()] +function readOperation (fr, blob, type, encodingName) { + // 1. If fr’s state is "loading", throw an InvalidStateError + // DOMException. + if (fr[kState] === 'loading') { + throw new DOMException('Invalid state', 'InvalidStateError') } -} -/** @param {string[]} headers */ -function buildHeadersFromArray (headers) { // fetch HeadersList - const clone = headers.slice() - const entries = [] - for (let index = 0; index < clone.length; index += 2) { - entries.push([clone[index], clone[index + 1]]) - } - return Object.fromEntries(entries) -} + // 2. Set fr’s state to "loading". + fr[kState] = 'loading' -function matchHeaders (mockDispatch, headers) { - if (typeof mockDispatch.headers === 'function') { - if (Array.isArray(headers)) { // fetch HeadersList - headers = buildHeadersFromArray(headers) - } - return mockDispatch.headers(headers ? lowerCaseEntries(headers) : {}) - } - if (typeof mockDispatch.headers === 'undefined') { - return true - } - if (typeof headers !== 'object' || typeof mockDispatch.headers !== 'object') { - return false - } + // 3. Set fr’s result to null. + fr[kResult] = null - for (const [matchHeaderName, matchHeaderValue] of Object.entries(mockDispatch.headers)) { - const headerValue = getHeaderByName(headers, matchHeaderName) + // 4. Set fr’s error to null. + fr[kError] = null - if (!matchValue(matchHeaderValue, headerValue)) { - return false - } - } - return true -} + // 5. Let stream be the result of calling get stream on blob. + /** @type {import('stream/web').ReadableStream} */ + const stream = blob.stream() -function safeUrl (path) { - if (typeof path !== 'string') { - return path - } + // 6. Let reader be the result of getting a reader from stream. + const reader = stream.getReader() + + // 7. Let bytes be an empty byte sequence. + /** @type {Uint8Array[]} */ + const bytes = [] + + // 8. Let chunkPromise be the result of reading a chunk from + // stream with reader. + let chunkPromise = reader.read() + + // 9. Let isFirstChunk be true. + let isFirstChunk = true + + // 10. In parallel, while true: + // Note: "In parallel" just means non-blocking + // Note 2: readOperation itself cannot be async as double + // reading the body would then reject the promise, instead + // of throwing an error. + ;(async () => { + while (!fr[kAborted]) { + // 1. Wait for chunkPromise to be fulfilled or rejected. + try { + const { done, value } = await chunkPromise + + // 2. If chunkPromise is fulfilled, and isFirstChunk is + // true, queue a task to fire a progress event called + // loadstart at fr. + if (isFirstChunk && !fr[kAborted]) { + queueMicrotask(() => { + fireAProgressEvent('loadstart', fr) + }) + } + + // 3. Set isFirstChunk to false. + isFirstChunk = false + + // 4. If chunkPromise is fulfilled with an object whose + // done property is false and whose value property is + // a Uint8Array object, run these steps: + if (!done && types.isUint8Array(value)) { + // 1. Let bs be the byte sequence represented by the + // Uint8Array object. + + // 2. Append bs to bytes. + bytes.push(value) + + // 3. If roughly 50ms have passed since these steps + // were last invoked, queue a task to fire a + // progress event called progress at fr. + if ( + ( + fr[kLastProgressEventFired] === undefined || + Date.now() - fr[kLastProgressEventFired] >= 50 + ) && + !fr[kAborted] + ) { + fr[kLastProgressEventFired] = Date.now() + queueMicrotask(() => { + fireAProgressEvent('progress', fr) + }) + } - const pathSegments = path.split('?') + // 4. Set chunkPromise to the result of reading a + // chunk from stream with reader. + chunkPromise = reader.read() + } else if (done) { + // 5. Otherwise, if chunkPromise is fulfilled with an + // object whose done property is true, queue a task + // to run the following steps and abort this algorithm: + queueMicrotask(() => { + // 1. Set fr’s state to "done". + fr[kState] = 'done' - if (pathSegments.length !== 2) { - return path - } + // 2. Let result be the result of package data given + // bytes, type, blob’s type, and encodingName. + try { + const result = packageData(bytes, type, blob.type, encodingName) - const qp = new URLSearchParams(pathSegments.pop()) - qp.sort() - return [...pathSegments, qp.toString()].join('?') -} + // 4. Else: -function matchKey (mockDispatch, { path, method, body, headers }) { - const pathMatch = matchValue(mockDispatch.path, path) - const methodMatch = matchValue(mockDispatch.method, method) - const bodyMatch = typeof mockDispatch.body !== 'undefined' ? matchValue(mockDispatch.body, body) : true - const headersMatch = matchHeaders(mockDispatch, headers) - return pathMatch && methodMatch && bodyMatch && headersMatch -} + if (fr[kAborted]) { + return + } -function getResponseData (data) { - if (Buffer.isBuffer(data)) { - return data - } else if (typeof data === 'object') { - return JSON.stringify(data) - } else { - return data.toString() - } -} + // 1. Set fr’s result to result. + fr[kResult] = result -function getMockDispatch (mockDispatches, key) { - const basePath = key.query ? buildURL(key.path, key.query) : key.path - const resolvedPath = typeof basePath === 'string' ? safeUrl(basePath) : basePath + // 2. Fire a progress event called load at the fr. + fireAProgressEvent('load', fr) + } catch (error) { + // 3. If package data threw an exception error: - // Match path - let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path }) => matchValue(safeUrl(path), resolvedPath)) - if (matchedMockDispatches.length === 0) { - throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`) - } + // 1. Set fr’s error to error. + fr[kError] = error - // Match method - matchedMockDispatches = matchedMockDispatches.filter(({ method }) => matchValue(method, key.method)) - if (matchedMockDispatches.length === 0) { - throw new MockNotMatchedError(`Mock dispatch not matched for method '${key.method}'`) - } + // 2. Fire a progress event called error at fr. + fireAProgressEvent('error', fr) + } - // Match body - matchedMockDispatches = matchedMockDispatches.filter(({ body }) => typeof body !== 'undefined' ? matchValue(body, key.body) : true) - if (matchedMockDispatches.length === 0) { - throw new MockNotMatchedError(`Mock dispatch not matched for body '${key.body}'`) - } + // 5. If fr’s state is not "loading", fire a progress + // event called loadend at the fr. + if (fr[kState] !== 'loading') { + fireAProgressEvent('loadend', fr) + } + }) - // Match headers - matchedMockDispatches = matchedMockDispatches.filter((mockDispatch) => matchHeaders(mockDispatch, key.headers)) - if (matchedMockDispatches.length === 0) { - throw new MockNotMatchedError(`Mock dispatch not matched for headers '${typeof key.headers === 'object' ? JSON.stringify(key.headers) : key.headers}'`) - } + break + } + } catch (error) { + if (fr[kAborted]) { + return + } - return matchedMockDispatches[0] -} + // 6. Otherwise, if chunkPromise is rejected with an + // error error, queue a task to run the following + // steps and abort this algorithm: + queueMicrotask(() => { + // 1. Set fr’s state to "done". + fr[kState] = 'done' -function addMockDispatch (mockDispatches, key, data) { - const baseData = { timesInvoked: 0, times: 1, persist: false, consumed: false } - const replyData = typeof data === 'function' ? { callback: data } : { ...data } - const newMockDispatch = { ...baseData, ...key, pending: true, data: { error: null, ...replyData } } - mockDispatches.push(newMockDispatch) - return newMockDispatch -} + // 2. Set fr’s error to error. + fr[kError] = error -function deleteMockDispatch (mockDispatches, key) { - const index = mockDispatches.findIndex(dispatch => { - if (!dispatch.consumed) { - return false - } - return matchKey(dispatch, key) - }) - if (index !== -1) { - mockDispatches.splice(index, 1) - } -} + // 3. Fire a progress event called error at fr. + fireAProgressEvent('error', fr) -function buildKey (opts) { - const { path, method, body, headers, query } = opts - return { - path, - method, - body, - headers, - query - } -} + // 4. If fr’s state is not "loading", fire a progress + // event called loadend at fr. + if (fr[kState] !== 'loading') { + fireAProgressEvent('loadend', fr) + } + }) -function generateKeyValues (data) { - return Object.entries(data).reduce((keyValuePairs, [key, value]) => [ - ...keyValuePairs, - Buffer.from(`${key}`), - Array.isArray(value) ? value.map(x => Buffer.from(`${x}`)) : Buffer.from(`${value}`) - ], []) + break + } + } + })() } /** - * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status - * @param {number} statusCode + * @see https://w3c.github.io/FileAPI/#fire-a-progress-event + * @see https://dom.spec.whatwg.org/#concept-event-fire + * @param {string} e The name of the event + * @param {import('./filereader').FileReader} reader */ -function getStatusText (statusCode) { - return STATUS_CODES[statusCode] || 'unknown' -} +function fireAProgressEvent (e, reader) { + // The progress event e does not bubble. e.bubbles must be false + // The progress event e is NOT cancelable. e.cancelable must be false + const event = new ProgressEvent(e, { + bubbles: false, + cancelable: false + }) -async function getResponse (body) { - const buffers = [] - for await (const data of body) { - buffers.push(data) - } - return Buffer.concat(buffers).toString('utf8') + reader.dispatchEvent(event) } /** - * Mock dispatch function used to simulate undici dispatches + * @see https://w3c.github.io/FileAPI/#blob-package-data + * @param {Uint8Array[]} bytes + * @param {string} type + * @param {string?} mimeType + * @param {string?} encodingName */ -function mockDispatch (opts, handler) { - // Get mock dispatch from built key - const key = buildKey(opts) - const mockDispatch = getMockDispatch(this[kDispatches], key) - - mockDispatch.timesInvoked++ - - // Here's where we resolve a callback if a callback is present for the dispatch data. - if (mockDispatch.data.callback) { - mockDispatch.data = { ...mockDispatch.data, ...mockDispatch.data.callback(opts) } - } +function packageData (bytes, type, mimeType, encodingName) { + // 1. A Blob has an associated package data algorithm, given + // bytes, a type, a optional mimeType, and a optional + // encodingName, which switches on type and runs the + // associated steps: - // Parse mockDispatch data - const { data: { statusCode, data, headers, trailers, error }, delay, persist } = mockDispatch - const { timesInvoked, times } = mockDispatch + switch (type) { + case 'DataURL': { + // 1. Return bytes as a DataURL [RFC2397] subject to + // the considerations below: + // * Use mimeType as part of the Data URL if it is + // available in keeping with the Data URL + // specification [RFC2397]. + // * If mimeType is not available return a Data URL + // without a media-type. [RFC2397]. - // If it's used up and not persistent, mark as consumed - mockDispatch.consumed = !persist && timesInvoked >= times - mockDispatch.pending = timesInvoked < times + // https://datatracker.ietf.org/doc/html/rfc2397#section-3 + // dataurl := "data:" [ mediatype ] [ ";base64" ] "," data + // mediatype := [ type "/" subtype ] *( ";" parameter ) + // data := *urlchar + // parameter := attribute "=" value + let dataURL = 'data:' - // If specified, trigger dispatch error - if (error !== null) { - deleteMockDispatch(this[kDispatches], key) - handler.onError(error) - return true - } + const parsed = parseMIMEType(mimeType || 'application/octet-stream') - // Handle the request with a delay if necessary - if (typeof delay === 'number' && delay > 0) { - setTimeout(() => { - handleReply(this[kDispatches]) - }, delay) - } else { - handleReply(this[kDispatches]) - } + if (parsed !== 'failure') { + dataURL += serializeAMimeType(parsed) + } - function handleReply (mockDispatches, _data = data) { - // fetch's HeadersList is a 1D string array - const optsHeaders = Array.isArray(opts.headers) - ? buildHeadersFromArray(opts.headers) - : opts.headers - const body = typeof _data === 'function' - ? _data({ ...opts, headers: optsHeaders }) - : _data + dataURL += ';base64,' - // util.types.isPromise is likely needed for jest. - if (isPromise(body)) { - // If handleReply is asynchronous, throwing an error - // in the callback will reject the promise, rather than - // synchronously throw the error, which breaks some tests. - // Rather, we wait for the callback to resolve if it is a - // promise, and then re-run handleReply with the new body. - body.then((newData) => handleReply(mockDispatches, newData)) - return - } + const decoder = new StringDecoder('latin1') - const responseData = getResponseData(body) - const responseHeaders = generateKeyValues(headers) - const responseTrailers = generateKeyValues(trailers) + for (const chunk of bytes) { + dataURL += btoa(decoder.write(chunk)) + } - handler.abort = nop - handler.onHeaders(statusCode, responseHeaders, resume, getStatusText(statusCode)) - handler.onData(Buffer.from(responseData)) - handler.onComplete(responseTrailers) - deleteMockDispatch(mockDispatches, key) - } + dataURL += btoa(decoder.end()) - function resume () {} + return dataURL + } + case 'Text': { + // 1. Let encoding be failure + let encoding = 'failure' - return true -} + // 2. If the encodingName is present, set encoding to the + // result of getting an encoding from encodingName. + if (encodingName) { + encoding = getEncoding(encodingName) + } -function buildMockDispatch () { - const agent = this[kMockAgent] - const origin = this[kOrigin] - const originalDispatch = this[kOriginalDispatch] + // 3. If encoding is failure, and mimeType is present: + if (encoding === 'failure' && mimeType) { + // 1. Let type be the result of parse a MIME type + // given mimeType. + const type = parseMIMEType(mimeType) - return function dispatch (opts, handler) { - if (agent.isMockActive) { - try { - mockDispatch.call(this, opts, handler) - } catch (error) { - if (error instanceof MockNotMatchedError) { - const netConnect = agent[kGetNetConnect]() - if (netConnect === false) { - throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect disabled)`) - } - if (checkNetConnect(netConnect, origin)) { - originalDispatch.call(this, opts, handler) - } else { - throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect is not enabled for this origin)`) - } - } else { - throw error + // 2. If type is not failure, set encoding to the result + // of getting an encoding from type’s parameters["charset"]. + if (type !== 'failure') { + encoding = getEncoding(type.parameters.get('charset')) } } - } else { - originalDispatch.call(this, opts, handler) + + // 4. If encoding is failure, then set encoding to UTF-8. + if (encoding === 'failure') { + encoding = 'UTF-8' + } + + // 5. Decode bytes using fallback encoding encoding, and + // return the result. + return decode(bytes, encoding) } - } -} + case 'ArrayBuffer': { + // Return a new ArrayBuffer whose contents are bytes. + const sequence = combineByteSequences(bytes) -function checkNetConnect (netConnect, origin) { - const url = new URL(origin) - if (netConnect === true) { - return true - } else if (Array.isArray(netConnect) && netConnect.some((matcher) => matchValue(matcher, url.host))) { - return true - } - return false -} + return sequence.buffer + } + case 'BinaryString': { + // Return bytes as a binary string, in which every byte + // is represented by a code unit of equal value [0..255]. + let binaryString = '' -function buildMockOptions (opts) { - if (opts) { - const { agent, ...mockOptions } = opts - return mockOptions + const decoder = new StringDecoder('latin1') + + for (const chunk of bytes) { + binaryString += decoder.write(chunk) + } + + binaryString += decoder.end() + + return binaryString + } } } -module.exports = { - getResponseData, - getMockDispatch, - addMockDispatch, - deleteMockDispatch, - buildKey, - generateKeyValues, - matchValue, - getResponse, - getStatusText, - mockDispatch, - buildMockDispatch, - checkNetConnect, - buildMockOptions, - getHeaderByName -} +/** + * @see https://encoding.spec.whatwg.org/#decode + * @param {Uint8Array[]} ioQueue + * @param {string} encoding + */ +function decode (ioQueue, encoding) { + const bytes = combineByteSequences(ioQueue) + // 1. Let BOMEncoding be the result of BOM sniffing ioQueue. + const BOMEncoding = BOMSniffing(bytes) -/***/ }), + let slice = 0 -/***/ 6823: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // 2. If BOMEncoding is non-null: + if (BOMEncoding !== null) { + // 1. Set encoding to BOMEncoding. + encoding = BOMEncoding -"use strict"; + // 2. Read three bytes from ioQueue, if BOMEncoding is + // UTF-8; otherwise read two bytes. + // (Do nothing with those bytes.) + slice = BOMEncoding === 'UTF-8' ? 3 : 2 + } + + // 3. Process a queue with an instance of encoding’s + // decoder, ioQueue, output, and "replacement". + // 4. Return output. -const { Transform } = __nccwpck_require__(2781) -const { Console } = __nccwpck_require__(6206) + const sliced = bytes.slice(slice) + return new TextDecoder(encoding).decode(sliced) +} /** - * Gets the output of `console.table(…)` as a string. + * @see https://encoding.spec.whatwg.org/#bom-sniff + * @param {Uint8Array} ioQueue */ -module.exports = class PendingInterceptorsFormatter { - constructor ({ disableColors } = {}) { - this.transform = new Transform({ - transform (chunk, _enc, cb) { - cb(null, chunk) - } - }) +function BOMSniffing (ioQueue) { + // 1. Let BOM be the result of peeking 3 bytes from ioQueue, + // converted to a byte sequence. + const [a, b, c] = ioQueue - this.logger = new Console({ - stdout: this.transform, - inspectOptions: { - colors: !disableColors && !process.env.CI - } - }) + // 2. For each of the rows in the table below, starting with + // the first one and going down, if BOM starts with the + // bytes given in the first column, then return the + // encoding given in the cell in the second column of that + // row. Otherwise, return null. + if (a === 0xEF && b === 0xBB && c === 0xBF) { + return 'UTF-8' + } else if (a === 0xFE && b === 0xFF) { + return 'UTF-16BE' + } else if (a === 0xFF && b === 0xFE) { + return 'UTF-16LE' } - format (pendingInterceptors) { - const withPrettyHeaders = pendingInterceptors.map( - ({ method, path, data: { statusCode }, persist, times, timesInvoked, origin }) => ({ - Method: method, - Origin: origin, - Path: path, - 'Status code': statusCode, - Persistent: persist ? '✅' : '❌', - Invocations: timesInvoked, - Remaining: persist ? Infinity : times - timesInvoked - })) + return null +} - this.logger.table(withPrettyHeaders) - return this.transform.read().toString() - } +/** + * @param {Uint8Array[]} sequences + */ +function combineByteSequences (sequences) { + const size = sequences.reduce((a, b) => { + return a + b.byteLength + }, 0) + + let offset = 0 + + return sequences.reduce((a, b) => { + a.set(b, offset) + offset += b.byteLength + return a + }, new Uint8Array(size)) +} + +module.exports = { + staticPropertyDescriptors, + readOperation, + fireAProgressEvent } /***/ }), -/***/ 8891: -/***/ ((module) => { +/***/ 1892: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const singulars = { - pronoun: 'it', - is: 'is', - was: 'was', - this: 'this' -} +// We include a version number for the Dispatcher API. In case of breaking changes, +// this version number must be increased to avoid conflicts. +const globalDispatcher = Symbol.for('undici.globalDispatcher.1') +const { InvalidArgumentError } = __nccwpck_require__(8045) +const Agent = __nccwpck_require__(7890) -const plurals = { - pronoun: 'they', - is: 'are', - was: 'were', - this: 'these' +if (getGlobalDispatcher() === undefined) { + setGlobalDispatcher(new Agent()) } -module.exports = class Pluralizer { - constructor (singular, plural) { - this.singular = singular - this.plural = plural +function setGlobalDispatcher (agent) { + if (!agent || typeof agent.dispatch !== 'function') { + throw new InvalidArgumentError('Argument agent must implement Agent') } + Object.defineProperty(globalThis, globalDispatcher, { + value: agent, + writable: true, + enumerable: false, + configurable: false + }) +} - pluralize (count) { - const one = count === 1 - const keys = one ? singulars : plurals - const noun = one ? this.singular : this.plural - return { ...keys, count, noun } - } +function getGlobalDispatcher () { + return globalThis[globalDispatcher] +} + +module.exports = { + setGlobalDispatcher, + getGlobalDispatcher } /***/ }), -/***/ 8266: +/***/ 6930: /***/ ((module) => { "use strict"; -/* eslint-disable */ - - - -// Extracted from node/lib/internal/fixed_queue.js - -// Currently optimal queue size, tested on V8 6.0 - 6.6. Must be power of two. -const kSize = 2048; -const kMask = kSize - 1; - -// The FixedQueue is implemented as a singly-linked list of fixed-size -// circular buffers. It looks something like this: -// -// head tail -// | | -// v v -// +-----------+ <-----\ +-----------+ <------\ +-----------+ -// | [null] | \----- | next | \------- | next | -// +-----------+ +-----------+ +-----------+ -// | item | <-- bottom | item | <-- bottom | [empty] | -// | item | | item | | [empty] | -// | item | | item | | [empty] | -// | item | | item | | [empty] | -// | item | | item | bottom --> | item | -// | item | | item | | item | -// | ... | | ... | | ... | -// | item | | item | | item | -// | item | | item | | item | -// | [empty] | <-- top | item | | item | -// | [empty] | | item | | item | -// | [empty] | | [empty] | <-- top top --> | [empty] | -// +-----------+ +-----------+ +-----------+ -// -// Or, if there is only one circular buffer, it looks something -// like either of these: -// -// head tail head tail -// | | | | -// v v v v -// +-----------+ +-----------+ -// | [null] | | [null] | -// +-----------+ +-----------+ -// | [empty] | | item | -// | [empty] | | item | -// | item | <-- bottom top --> | [empty] | -// | item | | [empty] | -// | [empty] | <-- top bottom --> | item | -// | [empty] | | item | -// +-----------+ +-----------+ -// -// Adding a value means moving `top` forward by one, removing means -// moving `bottom` forward by one. After reaching the end, the queue -// wraps around. -// -// When `top === bottom` the current queue is empty and when -// `top + 1 === bottom` it's full. This wastes a single space of storage -// but allows much quicker checks. -class FixedCircularBuffer { - constructor() { - this.bottom = 0; - this.top = 0; - this.list = new Array(kSize); - this.next = null; - } - isEmpty() { - return this.top === this.bottom; +module.exports = class DecoratorHandler { + constructor (handler) { + this.handler = handler } - isFull() { - return ((this.top + 1) & kMask) === this.bottom; + onConnect (...args) { + return this.handler.onConnect(...args) } - push(data) { - this.list[this.top] = data; - this.top = (this.top + 1) & kMask; + onError (...args) { + return this.handler.onError(...args) } - shift() { - const nextItem = this.list[this.bottom]; - if (nextItem === undefined) - return null; - this.list[this.bottom] = undefined; - this.bottom = (this.bottom + 1) & kMask; - return nextItem; + onUpgrade (...args) { + return this.handler.onUpgrade(...args) } -} -module.exports = class FixedQueue { - constructor() { - this.head = this.tail = new FixedCircularBuffer(); + onHeaders (...args) { + return this.handler.onHeaders(...args) } - isEmpty() { - return this.head.isEmpty(); + onData (...args) { + return this.handler.onData(...args) } - push(data) { - if (this.head.isFull()) { - // Head is full: Creates a new queue, sets the old queue's `.next` to it, - // and sets it as the new main queue. - this.head = this.head.next = new FixedCircularBuffer(); - } - this.head.push(data); + onComplete (...args) { + return this.handler.onComplete(...args) } - shift() { - const tail = this.tail; - const next = tail.shift(); - if (tail.isEmpty() && tail.next !== null) { - // If there is another queue, it forms the new tail. - this.tail = tail.next; - } - return next; + onBodySent (...args) { + return this.handler.onBodySent(...args) } -}; +} /***/ }), -/***/ 3198: +/***/ 2860: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const DispatcherBase = __nccwpck_require__(4839) -const FixedQueue = __nccwpck_require__(8266) -const { kConnected, kSize, kRunning, kPending, kQueued, kBusy, kFree, kUrl, kClose, kDestroy, kDispatch } = __nccwpck_require__(2785) -const PoolStats = __nccwpck_require__(9689) - -const kClients = Symbol('clients') -const kNeedDrain = Symbol('needDrain') -const kQueue = Symbol('queue') -const kClosedResolve = Symbol('closed resolve') -const kOnDrain = Symbol('onDrain') -const kOnConnect = Symbol('onConnect') -const kOnDisconnect = Symbol('onDisconnect') -const kOnConnectionError = Symbol('onConnectionError') -const kGetDispatcher = Symbol('get dispatcher') -const kAddClient = Symbol('add client') -const kRemoveClient = Symbol('remove client') -const kStats = Symbol('stats') +const util = __nccwpck_require__(3983) +const { kBodyUsed } = __nccwpck_require__(2785) +const assert = __nccwpck_require__(9491) +const { InvalidArgumentError } = __nccwpck_require__(8045) +const EE = __nccwpck_require__(2361) -class PoolBase extends DispatcherBase { - constructor () { - super() +const redirectableStatusCodes = [300, 301, 302, 303, 307, 308] - this[kQueue] = new FixedQueue() - this[kClients] = [] - this[kQueued] = 0 +const kBody = Symbol('body') - const pool = this +class BodyAsyncIterable { + constructor (body) { + this[kBody] = body + this[kBodyUsed] = false + } - this[kOnDrain] = function onDrain (origin, targets) { - const queue = pool[kQueue] + async * [Symbol.asyncIterator] () { + assert(!this[kBodyUsed], 'disturbed') + this[kBodyUsed] = true + yield * this[kBody] + } +} - let needDrain = false +class RedirectHandler { + constructor (dispatch, maxRedirections, opts, handler) { + if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { + throw new InvalidArgumentError('maxRedirections must be a positive number') + } - while (!needDrain) { - const item = queue.shift() - if (!item) { - break - } - pool[kQueued]-- - needDrain = !this.dispatch(item.opts, item.handler) - } + util.validateHandler(handler, opts.method, opts.upgrade) - this[kNeedDrain] = needDrain + this.dispatch = dispatch + this.location = null + this.abort = null + this.opts = { ...opts, maxRedirections: 0 } // opts must be a copy + this.maxRedirections = maxRedirections + this.handler = handler + this.history = [] - if (!this[kNeedDrain] && pool[kNeedDrain]) { - pool[kNeedDrain] = false - pool.emit('drain', origin, [pool, ...targets]) + if (util.isStream(this.opts.body)) { + // TODO (fix): Provide some way for the user to cache the file to e.g. /tmp + // so that it can be dispatched again? + // TODO (fix): Do we need 100-expect support to provide a way to do this properly? + if (util.bodyLength(this.opts.body) === 0) { + this.opts.body + .on('data', function () { + assert(false) + }) } - if (pool[kClosedResolve] && queue.isEmpty()) { - Promise - .all(pool[kClients].map(c => c.close())) - .then(pool[kClosedResolve]) + if (typeof this.opts.body.readableDidRead !== 'boolean') { + this.opts.body[kBodyUsed] = false + EE.prototype.on.call(this.opts.body, 'data', function () { + this[kBodyUsed] = true + }) } + } else if (this.opts.body && typeof this.opts.body.pipeTo === 'function') { + // TODO (fix): We can't access ReadableStream internal state + // to determine whether or not it has been disturbed. This is just + // a workaround. + this.opts.body = new BodyAsyncIterable(this.opts.body) + } else if ( + this.opts.body && + typeof this.opts.body !== 'string' && + !ArrayBuffer.isView(this.opts.body) && + util.isIterable(this.opts.body) + ) { + // TODO: Should we allow re-using iterable if !this.opts.idempotent + // or through some other flag? + this.opts.body = new BodyAsyncIterable(this.opts.body) } + } - this[kOnConnect] = (origin, targets) => { - pool.emit('connect', origin, [pool, ...targets]) + onConnect (abort) { + this.abort = abort + this.handler.onConnect(abort, { history: this.history }) + } + + onUpgrade (statusCode, headers, socket) { + this.handler.onUpgrade(statusCode, headers, socket) + } + + onError (error) { + this.handler.onError(error) + } + + onHeaders (statusCode, headers, resume, statusText) { + this.location = this.history.length >= this.maxRedirections || util.isDisturbed(this.opts.body) + ? null + : parseLocation(statusCode, headers) + + if (this.opts.origin) { + this.history.push(new URL(this.opts.path, this.opts.origin)) } - this[kOnDisconnect] = (origin, targets, err) => { - pool.emit('disconnect', origin, [pool, ...targets], err) + if (!this.location) { + return this.handler.onHeaders(statusCode, headers, resume, statusText) } - this[kOnConnectionError] = (origin, targets, err) => { - pool.emit('connectionError', origin, [pool, ...targets], err) - } + const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin))) + const path = search ? `${pathname}${search}` : pathname - this[kStats] = new PoolStats(this) - } + // Remove headers referring to the original URL. + // By default it is Host only, unless it's a 303 (see below), which removes also all Content-* headers. + // https://tools.ietf.org/html/rfc7231#section-6.4 + this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin) + this.opts.path = path + this.opts.origin = origin + this.opts.maxRedirections = 0 + this.opts.query = null - get [kBusy] () { - return this[kNeedDrain] + // https://tools.ietf.org/html/rfc7231#section-6.4.4 + // In case of HTTP 303, always replace method to be either HEAD or GET + if (statusCode === 303 && this.opts.method !== 'HEAD') { + this.opts.method = 'GET' + this.opts.body = null + } } - get [kConnected] () { - return this[kClients].filter(client => client[kConnected]).length - } + onData (chunk) { + if (this.location) { + /* + https://tools.ietf.org/html/rfc7231#section-6.4 - get [kFree] () { - return this[kClients].filter(client => client[kConnected] && !client[kNeedDrain]).length - } + TLDR: undici always ignores 3xx response bodies. - get [kPending] () { - let ret = this[kQueued] - for (const { [kPending]: pending } of this[kClients]) { - ret += pending - } - return ret - } + Redirection is used to serve the requested resource from another URL, so it is assumes that + no body is generated (and thus can be ignored). Even though generating a body is not prohibited. - get [kRunning] () { - let ret = 0 - for (const { [kRunning]: running } of this[kClients]) { - ret += running - } - return ret - } + For status 301, 302, 303, 307 and 308 (the latter from RFC 7238), the specs mention that the body usually + (which means it's optional and not mandated) contain just an hyperlink to the value of + the Location response header, so the body can be ignored safely. - get [kSize] () { - let ret = this[kQueued] - for (const { [kSize]: size } of this[kClients]) { - ret += size + For status 300, which is "Multiple Choices", the spec mentions both generating a Location + response header AND a response body with the other possible location to follow. + Since the spec explicitily chooses not to specify a format for such body and leave it to + servers and browsers implementors, we ignore the body as there is no specified way to eventually parse it. + */ + } else { + return this.handler.onData(chunk) } - return ret } - get stats () { - return this[kStats] - } + onComplete (trailers) { + if (this.location) { + /* + https://tools.ietf.org/html/rfc7231#section-6.4 - async [kClose] () { - if (this[kQueue].isEmpty()) { - return Promise.all(this[kClients].map(c => c.close())) + TLDR: undici always ignores 3xx response trailers as they are not expected in case of redirections + and neither are useful if present. + + See comment on onData method above for more detailed informations. + */ + + this.location = null + this.abort = null + + this.dispatch(this.opts, this) } else { - return new Promise((resolve) => { - this[kClosedResolve] = resolve - }) + this.handler.onComplete(trailers) } } - async [kDestroy] (err) { - while (true) { - const item = this[kQueue].shift() - if (!item) { - break - } - item.handler.onError(err) + onBodySent (chunk) { + if (this.handler.onBodySent) { + this.handler.onBodySent(chunk) } - - return Promise.all(this[kClients].map(c => c.destroy(err))) } +} - [kDispatch] (opts, handler) { - const dispatcher = this[kGetDispatcher]() +function parseLocation (statusCode, headers) { + if (redirectableStatusCodes.indexOf(statusCode) === -1) { + return null + } - if (!dispatcher) { - this[kNeedDrain] = true - this[kQueue].push({ opts, handler }) - this[kQueued]++ - } else if (!dispatcher.dispatch(opts, handler)) { - dispatcher[kNeedDrain] = true - this[kNeedDrain] = !this[kGetDispatcher]() + for (let i = 0; i < headers.length; i += 2) { + if (headers[i].toString().toLowerCase() === 'location') { + return headers[i + 1] } - - return !this[kNeedDrain] } +} - [kAddClient] (client) { - client - .on('drain', this[kOnDrain]) - .on('connect', this[kOnConnect]) - .on('disconnect', this[kOnDisconnect]) - .on('connectionError', this[kOnConnectionError]) - - this[kClients].push(client) +// https://tools.ietf.org/html/rfc7231#section-6.4.4 +function shouldRemoveHeader (header, removeContent, unknownOrigin) { + return ( + (header.length === 4 && header.toString().toLowerCase() === 'host') || + (removeContent && header.toString().toLowerCase().indexOf('content-') === 0) || + (unknownOrigin && header.length === 13 && header.toString().toLowerCase() === 'authorization') || + (unknownOrigin && header.length === 6 && header.toString().toLowerCase() === 'cookie') + ) +} - if (this[kNeedDrain]) { - process.nextTick(() => { - if (this[kNeedDrain]) { - this[kOnDrain](client[kUrl], [this, client]) - } - }) +// https://tools.ietf.org/html/rfc7231#section-6.4 +function cleanRequestHeaders (headers, removeContent, unknownOrigin) { + const ret = [] + if (Array.isArray(headers)) { + for (let i = 0; i < headers.length; i += 2) { + if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin)) { + ret.push(headers[i], headers[i + 1]) + } } - - return this - } - - [kRemoveClient] (client) { - client.close(() => { - const idx = this[kClients].indexOf(client) - if (idx !== -1) { - this[kClients].splice(idx, 1) + } else if (headers && typeof headers === 'object') { + for (const key of Object.keys(headers)) { + if (!shouldRemoveHeader(key, removeContent, unknownOrigin)) { + ret.push(key, headers[key]) } - }) - - this[kNeedDrain] = this[kClients].some(dispatcher => ( - !dispatcher[kNeedDrain] && - dispatcher.closed !== true && - dispatcher.destroyed !== true - )) + } + } else { + assert(headers == null, 'headers must be an object or an array') } + return ret } -module.exports = { - PoolBase, - kClients, - kNeedDrain, - kAddClient, - kRemoveClient, - kGetDispatcher -} +module.exports = RedirectHandler /***/ }), -/***/ 9689: +/***/ 2286: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -const { kFree, kConnected, kPending, kQueued, kRunning, kSize } = __nccwpck_require__(2785) -const kPool = Symbol('pool') +const assert = __nccwpck_require__(9491) -class PoolStats { - constructor (pool) { - this[kPool] = pool - } +const { kRetryHandlerDefaultRetry } = __nccwpck_require__(2785) +const { RequestRetryError } = __nccwpck_require__(8045) +const { isDisturbed, parseHeaders, parseRangeHeader } = __nccwpck_require__(3983) - get connected () { - return this[kPool][kConnected] - } +function calculateRetryAfterHeader (retryAfter) { + const current = Date.now() + const diff = new Date(retryAfter).getTime() - current + + return diff +} + +class RetryHandler { + constructor (opts, handlers) { + const { retryOptions, ...dispatchOpts } = opts + const { + // Retry scoped + retry: retryFn, + maxRetries, + maxTimeout, + minTimeout, + timeoutFactor, + // Response scoped + methods, + errorCodes, + retryAfter, + statusCodes + } = retryOptions ?? {} + + this.dispatch = handlers.dispatch + this.handler = handlers.handler + this.opts = dispatchOpts + this.abort = null + this.aborted = false + this.retryOpts = { + retry: retryFn ?? RetryHandler[kRetryHandlerDefaultRetry], + retryAfter: retryAfter ?? true, + maxTimeout: maxTimeout ?? 30 * 1000, // 30s, + timeout: minTimeout ?? 500, // .5s + timeoutFactor: timeoutFactor ?? 2, + maxRetries: maxRetries ?? 5, + // What errors we should retry + methods: methods ?? ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE'], + // Indicates which errors to retry + statusCodes: statusCodes ?? [500, 502, 503, 504, 429], + // List of errors to retry + errorCodes: errorCodes ?? [ + 'ECONNRESET', + 'ECONNREFUSED', + 'ENOTFOUND', + 'ENETDOWN', + 'ENETUNREACH', + 'EHOSTDOWN', + 'EHOSTUNREACH', + 'EPIPE' + ] + } + + this.retryCount = 0 + this.start = 0 + this.end = null + this.etag = null + this.resume = null - get free () { - return this[kPool][kFree] + // Handle possible onConnect duplication + this.handler.onConnect(reason => { + this.aborted = true + if (this.abort) { + this.abort(reason) + } else { + this.reason = reason + } + }) } - get pending () { - return this[kPool][kPending] + onRequestSent () { + if (this.handler.onRequestSent) { + this.handler.onRequestSent() + } } - get queued () { - return this[kPool][kQueued] + onUpgrade (statusCode, headers, socket) { + if (this.handler.onUpgrade) { + this.handler.onUpgrade(statusCode, headers, socket) + } } - get running () { - return this[kPool][kRunning] + onConnect (abort) { + if (this.aborted) { + abort(this.reason) + } else { + this.abort = abort + } } - get size () { - return this[kPool][kSize] + onBodySent (chunk) { + if (this.handler.onBodySent) return this.handler.onBodySent(chunk) } -} - -module.exports = PoolStats - - -/***/ }), - -/***/ 4634: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - - -const { - PoolBase, - kClients, - kNeedDrain, - kAddClient, - kGetDispatcher -} = __nccwpck_require__(3198) -const Client = __nccwpck_require__(3598) -const { - InvalidArgumentError -} = __nccwpck_require__(8045) -const util = __nccwpck_require__(3983) -const { kUrl, kInterceptors } = __nccwpck_require__(2785) -const buildConnector = __nccwpck_require__(2067) -const kOptions = Symbol('options') -const kConnections = Symbol('connections') -const kFactory = Symbol('factory') - -function defaultFactory (origin, opts) { - return new Client(origin, opts) -} - -class Pool extends PoolBase { - constructor (origin, { - connections, - factory = defaultFactory, - connect, - connectTimeout, - tls, - maxCachedSessions, - socketPath, - autoSelectFamily, - autoSelectFamilyAttemptTimeout, - allowH2, - ...options - } = {}) { - super() + static [kRetryHandlerDefaultRetry] (err, { state, opts }, cb) { + const { statusCode, code, headers } = err + const { method, retryOptions } = opts + const { + maxRetries, + timeout, + maxTimeout, + timeoutFactor, + statusCodes, + errorCodes, + methods + } = retryOptions + let { counter, currentTimeout } = state - if (connections != null && (!Number.isFinite(connections) || connections < 0)) { - throw new InvalidArgumentError('invalid connections') - } + currentTimeout = + currentTimeout != null && currentTimeout > 0 ? currentTimeout : timeout - if (typeof factory !== 'function') { - throw new InvalidArgumentError('factory must be a function.') + // Any code that is not a Undici's originated and allowed to retry + if ( + code && + code !== 'UND_ERR_REQ_RETRY' && + code !== 'UND_ERR_SOCKET' && + !errorCodes.includes(code) + ) { + cb(err) + return } - if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { - throw new InvalidArgumentError('connect must be a function or an object') + // If a set of method are provided and the current method is not in the list + if (Array.isArray(methods) && !methods.includes(method)) { + cb(err) + return } - if (typeof connect !== 'function') { - connect = buildConnector({ - ...tls, - maxCachedSessions, - allowH2, - socketPath, - timeout: connectTimeout, - ...(util.nodeHasAutoSelectFamily && autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), - ...connect - }) + // If a set of status code are provided and the current status code is not in the list + if ( + statusCode != null && + Array.isArray(statusCodes) && + !statusCodes.includes(statusCode) + ) { + cb(err) + return } - this[kInterceptors] = options.interceptors && options.interceptors.Pool && Array.isArray(options.interceptors.Pool) - ? options.interceptors.Pool - : [] - this[kConnections] = connections || null - this[kUrl] = util.parseOrigin(origin) - this[kOptions] = { ...util.deepClone(options), connect, allowH2 } - this[kOptions].interceptors = options.interceptors - ? { ...options.interceptors } - : undefined - this[kFactory] = factory - } - - [kGetDispatcher] () { - let dispatcher = this[kClients].find(dispatcher => !dispatcher[kNeedDrain]) - - if (dispatcher) { - return dispatcher + // If we reached the max number of retries + if (counter > maxRetries) { + cb(err) + return } - if (!this[kConnections] || this[kClients].length < this[kConnections]) { - dispatcher = this[kFactory](this[kUrl], this[kOptions]) - this[kAddClient](dispatcher) + let retryAfterHeader = headers != null && headers['retry-after'] + if (retryAfterHeader) { + retryAfterHeader = Number(retryAfterHeader) + retryAfterHeader = isNaN(retryAfterHeader) + ? calculateRetryAfterHeader(retryAfterHeader) + : retryAfterHeader * 1e3 // Retry-After is in seconds } - return dispatcher - } -} + const retryTimeout = + retryAfterHeader > 0 + ? Math.min(retryAfterHeader, maxTimeout) + : Math.min(currentTimeout * timeoutFactor ** counter, maxTimeout) -module.exports = Pool + state.currentTimeout = retryTimeout + setTimeout(() => cb(null), retryTimeout) + } -/***/ }), + onHeaders (statusCode, rawHeaders, resume, statusMessage) { + const headers = parseHeaders(rawHeaders) -/***/ 7858: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this.retryCount += 1 -"use strict"; + if (statusCode >= 300) { + this.abort( + new RequestRetryError('Request failed', statusCode, { + headers, + count: this.retryCount + }) + ) + return false + } + // Checkpoint for resume from where we left it + if (this.resume != null) { + this.resume = null -const { kProxy, kClose, kDestroy, kInterceptors } = __nccwpck_require__(2785) -const { URL } = __nccwpck_require__(7310) -const Agent = __nccwpck_require__(7890) -const Pool = __nccwpck_require__(4634) -const DispatcherBase = __nccwpck_require__(4839) -const { InvalidArgumentError, RequestAbortedError } = __nccwpck_require__(8045) -const buildConnector = __nccwpck_require__(2067) + if (statusCode !== 206) { + return true + } -const kAgent = Symbol('proxy agent') -const kClient = Symbol('proxy client') -const kProxyHeaders = Symbol('proxy headers') -const kRequestTls = Symbol('request tls settings') -const kProxyTls = Symbol('proxy tls settings') -const kConnectEndpoint = Symbol('connect endpoint function') + const contentRange = parseRangeHeader(headers['content-range']) + // If no content range + if (!contentRange) { + this.abort( + new RequestRetryError('Content-Range mismatch', statusCode, { + headers, + count: this.retryCount + }) + ) + return false + } -function defaultProtocolPort (protocol) { - return protocol === 'https:' ? 443 : 80 -} + // Let's start with a weak etag check + if (this.etag != null && this.etag !== headers.etag) { + this.abort( + new RequestRetryError('ETag mismatch', statusCode, { + headers, + count: this.retryCount + }) + ) + return false + } -function buildProxyOptions (opts) { - if (typeof opts === 'string') { - opts = { uri: opts } - } + const { start, size, end = size } = contentRange - if (!opts || !opts.uri) { - throw new InvalidArgumentError('Proxy opts.uri is mandatory') - } + assert(this.start === start, 'content-range mismatch') + assert(this.end == null || this.end === end, 'content-range mismatch') - return { - uri: opts.uri, - protocol: opts.protocol || 'https' - } -} + this.resume = resume + return true + } -function defaultFactory (origin, opts) { - return new Pool(origin, opts) -} + if (this.end == null) { + if (statusCode === 206) { + // First time we receive 206 + const range = parseRangeHeader(headers['content-range']) -class ProxyAgent extends DispatcherBase { - constructor (opts) { - super(opts) - this[kProxy] = buildProxyOptions(opts) - this[kAgent] = new Agent(opts) - this[kInterceptors] = opts.interceptors && opts.interceptors.ProxyAgent && Array.isArray(opts.interceptors.ProxyAgent) - ? opts.interceptors.ProxyAgent - : [] + if (range == null) { + return this.handler.onHeaders( + statusCode, + rawHeaders, + resume, + statusMessage + ) + } - if (typeof opts === 'string') { - opts = { uri: opts } - } + const { start, size, end = size } = range - if (!opts || !opts.uri) { - throw new InvalidArgumentError('Proxy opts.uri is mandatory') - } + assert( + start != null && Number.isFinite(start) && this.start !== start, + 'content-range mismatch' + ) + assert(Number.isFinite(start)) + assert( + end != null && Number.isFinite(end) && this.end !== end, + 'invalid content-length' + ) - const { clientFactory = defaultFactory } = opts + this.start = start + this.end = end + } - if (typeof clientFactory !== 'function') { - throw new InvalidArgumentError('Proxy opts.clientFactory must be a function.') - } + // We make our best to checkpoint the body for further range headers + if (this.end == null) { + const contentLength = headers['content-length'] + this.end = contentLength != null ? Number(contentLength) : null + } - this[kRequestTls] = opts.requestTls - this[kProxyTls] = opts.proxyTls - this[kProxyHeaders] = opts.headers || {} + assert(Number.isFinite(this.start)) + assert( + this.end == null || Number.isFinite(this.end), + 'invalid content-length' + ) - const resolvedUrl = new URL(opts.uri) - const { origin, port, host, username, password } = resolvedUrl + this.resume = resume + this.etag = headers.etag != null ? headers.etag : null - if (opts.auth && opts.token) { - throw new InvalidArgumentError('opts.auth cannot be used in combination with opts.token') - } else if (opts.auth) { - /* @deprecated in favour of opts.token */ - this[kProxyHeaders]['proxy-authorization'] = `Basic ${opts.auth}` - } else if (opts.token) { - this[kProxyHeaders]['proxy-authorization'] = opts.token - } else if (username && password) { - this[kProxyHeaders]['proxy-authorization'] = `Basic ${Buffer.from(`${decodeURIComponent(username)}:${decodeURIComponent(password)}`).toString('base64')}` + return this.handler.onHeaders( + statusCode, + rawHeaders, + resume, + statusMessage + ) } - const connect = buildConnector({ ...opts.proxyTls }) - this[kConnectEndpoint] = buildConnector({ ...opts.requestTls }) - this[kClient] = clientFactory(resolvedUrl, { connect }) - this[kAgent] = new Agent({ - ...opts, - connect: async (opts, callback) => { - let requestedHost = opts.host - if (!opts.port) { - requestedHost += `:${defaultProtocolPort(opts.protocol)}` - } - try { - const { socket, statusCode } = await this[kClient].connect({ - origin, - port, - path: requestedHost, - signal: opts.signal, - headers: { - ...this[kProxyHeaders], - host - } - }) - if (statusCode !== 200) { - socket.on('error', () => {}).destroy() - callback(new RequestAbortedError(`Proxy response (${statusCode}) !== 200 when HTTP Tunneling`)) - } - if (opts.protocol !== 'https:') { - callback(null, socket) - return - } - let servername - if (this[kRequestTls]) { - servername = this[kRequestTls].servername - } else { - servername = opts.servername - } - this[kConnectEndpoint]({ ...opts, servername, httpSocket: socket }, callback) - } catch (err) { - callback(err) - } - } + const err = new RequestRetryError('Request failed', statusCode, { + headers, + count: this.retryCount }) - } - dispatch (opts, handler) { - const { host } = new URL(opts.origin) - const headers = buildHeaders(opts.headers) - throwIfProxyAuthIsSent(headers) - return this[kAgent].dispatch( - { - ...opts, - headers: { - ...headers, - host - } - }, - handler - ) - } + this.abort(err) - async [kClose] () { - await this[kAgent].close() - await this[kClient].close() + return false } - async [kDestroy] () { - await this[kAgent].destroy() - await this[kClient].destroy() + onData (chunk) { + this.start += chunk.length + + return this.handler.onData(chunk) } -} -/** - * @param {string[] | Record} headers - * @returns {Record} - */ -function buildHeaders (headers) { - // When using undici.fetch, the headers list is stored - // as an array. - if (Array.isArray(headers)) { - /** @type {Record} */ - const headersPair = {} + onComplete (rawTrailers) { + this.retryCount = 0 + return this.handler.onComplete(rawTrailers) + } - for (let i = 0; i < headers.length; i += 2) { - headersPair[headers[i]] = headers[i + 1] + onError (err) { + if (this.aborted || isDisturbed(this.opts.body)) { + return this.handler.onError(err) } - return headersPair - } + this.retryOpts.retry( + err, + { + state: { counter: this.retryCount++, currentTimeout: this.retryAfter }, + opts: { retryOptions: this.retryOpts, ...this.opts } + }, + onRetry.bind(this) + ) - return headers -} + function onRetry (err) { + if (err != null || this.aborted || isDisturbed(this.opts.body)) { + return this.handler.onError(err) + } -/** - * @param {Record} headers - * - * Previous versions of ProxyAgent suggests the Proxy-Authorization in request headers - * Nevertheless, it was changed and to avoid a security vulnerability by end users - * this check was created. - * It should be removed in the next major version for performance reasons - */ -function throwIfProxyAuthIsSent (headers) { - const existProxyAuth = headers && Object.keys(headers) - .find((key) => key.toLowerCase() === 'proxy-authorization') - if (existProxyAuth) { - throw new InvalidArgumentError('Proxy-Authorization should be sent in ProxyAgent constructor') + if (this.start !== 0) { + this.opts = { + ...this.opts, + headers: { + ...this.opts.headers, + range: `bytes=${this.start}-${this.end ?? ''}` + } + } + } + + try { + this.dispatch(this.opts, this) + } catch (err) { + this.handler.onError(err) + } + } } } -module.exports = ProxyAgent +module.exports = RetryHandler /***/ }), -/***/ 9459: -/***/ ((module) => { +/***/ 8861: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -let fastNow = Date.now() -let fastNowTimeout - -const fastTimers = [] - -function onTimeout () { - fastNow = Date.now() - - let len = fastTimers.length - let idx = 0 - while (idx < len) { - const timer = fastTimers[idx] - - if (timer.state === 0) { - timer.state = fastNow + timer.delay - } else if (timer.state > 0 && fastNow >= timer.state) { - timer.state = -1 - timer.callback(timer.opaque) - } +const RedirectHandler = __nccwpck_require__(2860) - if (timer.state === -1) { - timer.state = -2 - if (idx !== len - 1) { - fastTimers[idx] = fastTimers.pop() - } else { - fastTimers.pop() - } - len -= 1 - } else { - idx += 1 - } - } +function createRedirectInterceptor ({ maxRedirections: defaultMaxRedirections }) { + return (dispatch) => { + return function Intercept (opts, handler) { + const { maxRedirections = defaultMaxRedirections } = opts - if (fastTimers.length > 0) { - refreshTimeout() - } -} + if (!maxRedirections) { + return dispatch(opts, handler) + } -function refreshTimeout () { - if (fastNowTimeout && fastNowTimeout.refresh) { - fastNowTimeout.refresh() - } else { - clearTimeout(fastNowTimeout) - fastNowTimeout = setTimeout(onTimeout, 1e3) - if (fastNowTimeout.unref) { - fastNowTimeout.unref() + const redirectHandler = new RedirectHandler(dispatch, maxRedirections, opts, handler) + opts = { ...opts, maxRedirections: 0 } // Stop sub dispatcher from also redirecting. + return dispatch(opts, redirectHandler) } } } -class Timeout { - constructor (callback, delay, opaque) { - this.callback = callback - this.delay = delay - this.opaque = opaque +module.exports = createRedirectInterceptor - // -2 not in timer list - // -1 in timer list but inactive - // 0 in timer list waiting for time - // > 0 in timer list waiting for time to expire - this.state = -2 - this.refresh() - } +/***/ }), - refresh () { - if (this.state === -2) { - fastTimers.push(this) - if (!fastNowTimeout || fastTimers.length === 1) { - refreshTimeout() - } - } +/***/ 953: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - this.state = 0 - } +"use strict"; - clear () { - this.state = -1 - } +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.SPECIAL_HEADERS = exports.HEADER_STATE = exports.MINOR = exports.MAJOR = exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS = exports.TOKEN = exports.STRICT_TOKEN = exports.HEX = exports.URL_CHAR = exports.STRICT_URL_CHAR = exports.USERINFO_CHARS = exports.MARK = exports.ALPHANUM = exports.NUM = exports.HEX_MAP = exports.NUM_MAP = exports.ALPHA = exports.FINISH = exports.H_METHOD_MAP = exports.METHOD_MAP = exports.METHODS_RTSP = exports.METHODS_ICE = exports.METHODS_HTTP = exports.METHODS = exports.LENIENT_FLAGS = exports.FLAGS = exports.TYPE = exports.ERROR = void 0; +const utils_1 = __nccwpck_require__(1891); +// C headers +var ERROR; +(function (ERROR) { + ERROR[ERROR["OK"] = 0] = "OK"; + ERROR[ERROR["INTERNAL"] = 1] = "INTERNAL"; + ERROR[ERROR["STRICT"] = 2] = "STRICT"; + ERROR[ERROR["LF_EXPECTED"] = 3] = "LF_EXPECTED"; + ERROR[ERROR["UNEXPECTED_CONTENT_LENGTH"] = 4] = "UNEXPECTED_CONTENT_LENGTH"; + ERROR[ERROR["CLOSED_CONNECTION"] = 5] = "CLOSED_CONNECTION"; + ERROR[ERROR["INVALID_METHOD"] = 6] = "INVALID_METHOD"; + ERROR[ERROR["INVALID_URL"] = 7] = "INVALID_URL"; + ERROR[ERROR["INVALID_CONSTANT"] = 8] = "INVALID_CONSTANT"; + ERROR[ERROR["INVALID_VERSION"] = 9] = "INVALID_VERSION"; + ERROR[ERROR["INVALID_HEADER_TOKEN"] = 10] = "INVALID_HEADER_TOKEN"; + ERROR[ERROR["INVALID_CONTENT_LENGTH"] = 11] = "INVALID_CONTENT_LENGTH"; + ERROR[ERROR["INVALID_CHUNK_SIZE"] = 12] = "INVALID_CHUNK_SIZE"; + ERROR[ERROR["INVALID_STATUS"] = 13] = "INVALID_STATUS"; + ERROR[ERROR["INVALID_EOF_STATE"] = 14] = "INVALID_EOF_STATE"; + ERROR[ERROR["INVALID_TRANSFER_ENCODING"] = 15] = "INVALID_TRANSFER_ENCODING"; + ERROR[ERROR["CB_MESSAGE_BEGIN"] = 16] = "CB_MESSAGE_BEGIN"; + ERROR[ERROR["CB_HEADERS_COMPLETE"] = 17] = "CB_HEADERS_COMPLETE"; + ERROR[ERROR["CB_MESSAGE_COMPLETE"] = 18] = "CB_MESSAGE_COMPLETE"; + ERROR[ERROR["CB_CHUNK_HEADER"] = 19] = "CB_CHUNK_HEADER"; + ERROR[ERROR["CB_CHUNK_COMPLETE"] = 20] = "CB_CHUNK_COMPLETE"; + ERROR[ERROR["PAUSED"] = 21] = "PAUSED"; + ERROR[ERROR["PAUSED_UPGRADE"] = 22] = "PAUSED_UPGRADE"; + ERROR[ERROR["PAUSED_H2_UPGRADE"] = 23] = "PAUSED_H2_UPGRADE"; + ERROR[ERROR["USER"] = 24] = "USER"; +})(ERROR = exports.ERROR || (exports.ERROR = {})); +var TYPE; +(function (TYPE) { + TYPE[TYPE["BOTH"] = 0] = "BOTH"; + TYPE[TYPE["REQUEST"] = 1] = "REQUEST"; + TYPE[TYPE["RESPONSE"] = 2] = "RESPONSE"; +})(TYPE = exports.TYPE || (exports.TYPE = {})); +var FLAGS; +(function (FLAGS) { + FLAGS[FLAGS["CONNECTION_KEEP_ALIVE"] = 1] = "CONNECTION_KEEP_ALIVE"; + FLAGS[FLAGS["CONNECTION_CLOSE"] = 2] = "CONNECTION_CLOSE"; + FLAGS[FLAGS["CONNECTION_UPGRADE"] = 4] = "CONNECTION_UPGRADE"; + FLAGS[FLAGS["CHUNKED"] = 8] = "CHUNKED"; + FLAGS[FLAGS["UPGRADE"] = 16] = "UPGRADE"; + FLAGS[FLAGS["CONTENT_LENGTH"] = 32] = "CONTENT_LENGTH"; + FLAGS[FLAGS["SKIPBODY"] = 64] = "SKIPBODY"; + FLAGS[FLAGS["TRAILING"] = 128] = "TRAILING"; + // 1 << 8 is unused + FLAGS[FLAGS["TRANSFER_ENCODING"] = 512] = "TRANSFER_ENCODING"; +})(FLAGS = exports.FLAGS || (exports.FLAGS = {})); +var LENIENT_FLAGS; +(function (LENIENT_FLAGS) { + LENIENT_FLAGS[LENIENT_FLAGS["HEADERS"] = 1] = "HEADERS"; + LENIENT_FLAGS[LENIENT_FLAGS["CHUNKED_LENGTH"] = 2] = "CHUNKED_LENGTH"; + LENIENT_FLAGS[LENIENT_FLAGS["KEEP_ALIVE"] = 4] = "KEEP_ALIVE"; +})(LENIENT_FLAGS = exports.LENIENT_FLAGS || (exports.LENIENT_FLAGS = {})); +var METHODS; +(function (METHODS) { + METHODS[METHODS["DELETE"] = 0] = "DELETE"; + METHODS[METHODS["GET"] = 1] = "GET"; + METHODS[METHODS["HEAD"] = 2] = "HEAD"; + METHODS[METHODS["POST"] = 3] = "POST"; + METHODS[METHODS["PUT"] = 4] = "PUT"; + /* pathological */ + METHODS[METHODS["CONNECT"] = 5] = "CONNECT"; + METHODS[METHODS["OPTIONS"] = 6] = "OPTIONS"; + METHODS[METHODS["TRACE"] = 7] = "TRACE"; + /* WebDAV */ + METHODS[METHODS["COPY"] = 8] = "COPY"; + METHODS[METHODS["LOCK"] = 9] = "LOCK"; + METHODS[METHODS["MKCOL"] = 10] = "MKCOL"; + METHODS[METHODS["MOVE"] = 11] = "MOVE"; + METHODS[METHODS["PROPFIND"] = 12] = "PROPFIND"; + METHODS[METHODS["PROPPATCH"] = 13] = "PROPPATCH"; + METHODS[METHODS["SEARCH"] = 14] = "SEARCH"; + METHODS[METHODS["UNLOCK"] = 15] = "UNLOCK"; + METHODS[METHODS["BIND"] = 16] = "BIND"; + METHODS[METHODS["REBIND"] = 17] = "REBIND"; + METHODS[METHODS["UNBIND"] = 18] = "UNBIND"; + METHODS[METHODS["ACL"] = 19] = "ACL"; + /* subversion */ + METHODS[METHODS["REPORT"] = 20] = "REPORT"; + METHODS[METHODS["MKACTIVITY"] = 21] = "MKACTIVITY"; + METHODS[METHODS["CHECKOUT"] = 22] = "CHECKOUT"; + METHODS[METHODS["MERGE"] = 23] = "MERGE"; + /* upnp */ + METHODS[METHODS["M-SEARCH"] = 24] = "M-SEARCH"; + METHODS[METHODS["NOTIFY"] = 25] = "NOTIFY"; + METHODS[METHODS["SUBSCRIBE"] = 26] = "SUBSCRIBE"; + METHODS[METHODS["UNSUBSCRIBE"] = 27] = "UNSUBSCRIBE"; + /* RFC-5789 */ + METHODS[METHODS["PATCH"] = 28] = "PATCH"; + METHODS[METHODS["PURGE"] = 29] = "PURGE"; + /* CalDAV */ + METHODS[METHODS["MKCALENDAR"] = 30] = "MKCALENDAR"; + /* RFC-2068, section 19.6.1.2 */ + METHODS[METHODS["LINK"] = 31] = "LINK"; + METHODS[METHODS["UNLINK"] = 32] = "UNLINK"; + /* icecast */ + METHODS[METHODS["SOURCE"] = 33] = "SOURCE"; + /* RFC-7540, section 11.6 */ + METHODS[METHODS["PRI"] = 34] = "PRI"; + /* RFC-2326 RTSP */ + METHODS[METHODS["DESCRIBE"] = 35] = "DESCRIBE"; + METHODS[METHODS["ANNOUNCE"] = 36] = "ANNOUNCE"; + METHODS[METHODS["SETUP"] = 37] = "SETUP"; + METHODS[METHODS["PLAY"] = 38] = "PLAY"; + METHODS[METHODS["PAUSE"] = 39] = "PAUSE"; + METHODS[METHODS["TEARDOWN"] = 40] = "TEARDOWN"; + METHODS[METHODS["GET_PARAMETER"] = 41] = "GET_PARAMETER"; + METHODS[METHODS["SET_PARAMETER"] = 42] = "SET_PARAMETER"; + METHODS[METHODS["REDIRECT"] = 43] = "REDIRECT"; + METHODS[METHODS["RECORD"] = 44] = "RECORD"; + /* RAOP */ + METHODS[METHODS["FLUSH"] = 45] = "FLUSH"; +})(METHODS = exports.METHODS || (exports.METHODS = {})); +exports.METHODS_HTTP = [ + METHODS.DELETE, + METHODS.GET, + METHODS.HEAD, + METHODS.POST, + METHODS.PUT, + METHODS.CONNECT, + METHODS.OPTIONS, + METHODS.TRACE, + METHODS.COPY, + METHODS.LOCK, + METHODS.MKCOL, + METHODS.MOVE, + METHODS.PROPFIND, + METHODS.PROPPATCH, + METHODS.SEARCH, + METHODS.UNLOCK, + METHODS.BIND, + METHODS.REBIND, + METHODS.UNBIND, + METHODS.ACL, + METHODS.REPORT, + METHODS.MKACTIVITY, + METHODS.CHECKOUT, + METHODS.MERGE, + METHODS['M-SEARCH'], + METHODS.NOTIFY, + METHODS.SUBSCRIBE, + METHODS.UNSUBSCRIBE, + METHODS.PATCH, + METHODS.PURGE, + METHODS.MKCALENDAR, + METHODS.LINK, + METHODS.UNLINK, + METHODS.PRI, + // TODO(indutny): should we allow it with HTTP? + METHODS.SOURCE, +]; +exports.METHODS_ICE = [ + METHODS.SOURCE, +]; +exports.METHODS_RTSP = [ + METHODS.OPTIONS, + METHODS.DESCRIBE, + METHODS.ANNOUNCE, + METHODS.SETUP, + METHODS.PLAY, + METHODS.PAUSE, + METHODS.TEARDOWN, + METHODS.GET_PARAMETER, + METHODS.SET_PARAMETER, + METHODS.REDIRECT, + METHODS.RECORD, + METHODS.FLUSH, + // For AirPlay + METHODS.GET, + METHODS.POST, +]; +exports.METHOD_MAP = utils_1.enumToMap(METHODS); +exports.H_METHOD_MAP = {}; +Object.keys(exports.METHOD_MAP).forEach((key) => { + if (/^H/.test(key)) { + exports.H_METHOD_MAP[key] = exports.METHOD_MAP[key]; + } +}); +var FINISH; +(function (FINISH) { + FINISH[FINISH["SAFE"] = 0] = "SAFE"; + FINISH[FINISH["SAFE_WITH_CB"] = 1] = "SAFE_WITH_CB"; + FINISH[FINISH["UNSAFE"] = 2] = "UNSAFE"; +})(FINISH = exports.FINISH || (exports.FINISH = {})); +exports.ALPHA = []; +for (let i = 'A'.charCodeAt(0); i <= 'Z'.charCodeAt(0); i++) { + // Upper case + exports.ALPHA.push(String.fromCharCode(i)); + // Lower case + exports.ALPHA.push(String.fromCharCode(i + 0x20)); +} +exports.NUM_MAP = { + 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, + 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, +}; +exports.HEX_MAP = { + 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, + 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, + A: 0XA, B: 0XB, C: 0XC, D: 0XD, E: 0XE, F: 0XF, + a: 0xa, b: 0xb, c: 0xc, d: 0xd, e: 0xe, f: 0xf, +}; +exports.NUM = [ + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', +]; +exports.ALPHANUM = exports.ALPHA.concat(exports.NUM); +exports.MARK = ['-', '_', '.', '!', '~', '*', '\'', '(', ')']; +exports.USERINFO_CHARS = exports.ALPHANUM + .concat(exports.MARK) + .concat(['%', ';', ':', '&', '=', '+', '$', ',']); +// TODO(indutny): use RFC +exports.STRICT_URL_CHAR = [ + '!', '"', '$', '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + ':', ';', '<', '=', '>', + '@', '[', '\\', ']', '^', '_', + '`', + '{', '|', '}', '~', +].concat(exports.ALPHANUM); +exports.URL_CHAR = exports.STRICT_URL_CHAR + .concat(['\t', '\f']); +// All characters with 0x80 bit set to 1 +for (let i = 0x80; i <= 0xff; i++) { + exports.URL_CHAR.push(i); } - -module.exports = { - setTimeout (callback, delay, opaque) { - return delay < 1e3 - ? setTimeout(callback, delay, opaque) - : new Timeout(callback, delay, opaque) - }, - clearTimeout (timeout) { - if (timeout instanceof Timeout) { - timeout.clear() - } else { - clearTimeout(timeout) +exports.HEX = exports.NUM.concat(['a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F']); +/* Tokens as defined by rfc 2616. Also lowercases them. + * token = 1* + * separators = "(" | ")" | "<" | ">" | "@" + * | "," | ";" | ":" | "\" | <"> + * | "/" | "[" | "]" | "?" | "=" + * | "{" | "}" | SP | HT + */ +exports.STRICT_TOKEN = [ + '!', '#', '$', '%', '&', '\'', + '*', '+', '-', '.', + '^', '_', '`', + '|', '~', +].concat(exports.ALPHANUM); +exports.TOKEN = exports.STRICT_TOKEN.concat([' ']); +/* + * Verify that a char is a valid visible (printable) US-ASCII + * character or %x80-FF + */ +exports.HEADER_CHARS = ['\t']; +for (let i = 32; i <= 255; i++) { + if (i !== 127) { + exports.HEADER_CHARS.push(i); } - } } - +// ',' = \x44 +exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS.filter((c) => c !== 44); +exports.MAJOR = exports.NUM_MAP; +exports.MINOR = exports.MAJOR; +var HEADER_STATE; +(function (HEADER_STATE) { + HEADER_STATE[HEADER_STATE["GENERAL"] = 0] = "GENERAL"; + HEADER_STATE[HEADER_STATE["CONNECTION"] = 1] = "CONNECTION"; + HEADER_STATE[HEADER_STATE["CONTENT_LENGTH"] = 2] = "CONTENT_LENGTH"; + HEADER_STATE[HEADER_STATE["TRANSFER_ENCODING"] = 3] = "TRANSFER_ENCODING"; + HEADER_STATE[HEADER_STATE["UPGRADE"] = 4] = "UPGRADE"; + HEADER_STATE[HEADER_STATE["CONNECTION_KEEP_ALIVE"] = 5] = "CONNECTION_KEEP_ALIVE"; + HEADER_STATE[HEADER_STATE["CONNECTION_CLOSE"] = 6] = "CONNECTION_CLOSE"; + HEADER_STATE[HEADER_STATE["CONNECTION_UPGRADE"] = 7] = "CONNECTION_UPGRADE"; + HEADER_STATE[HEADER_STATE["TRANSFER_ENCODING_CHUNKED"] = 8] = "TRANSFER_ENCODING_CHUNKED"; +})(HEADER_STATE = exports.HEADER_STATE || (exports.HEADER_STATE = {})); +exports.SPECIAL_HEADERS = { + 'connection': HEADER_STATE.CONNECTION, + 'content-length': HEADER_STATE.CONTENT_LENGTH, + 'proxy-connection': HEADER_STATE.CONNECTION, + 'transfer-encoding': HEADER_STATE.TRANSFER_ENCODING, + 'upgrade': HEADER_STATE.UPGRADE, +}; +//# sourceMappingURL=constants.js.map /***/ }), -/***/ 5354: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - - -const diagnosticsChannel = __nccwpck_require__(7643) -const { uid, states } = __nccwpck_require__(9188) -const { - kReadyState, - kSentClose, - kByteParser, - kReceivedClose -} = __nccwpck_require__(7578) -const { fireEvent, failWebsocketConnection } = __nccwpck_require__(5515) -const { CloseEvent } = __nccwpck_require__(2611) -const { makeRequest } = __nccwpck_require__(8359) -const { fetching } = __nccwpck_require__(4881) -const { Headers } = __nccwpck_require__(554) -const { getGlobalDispatcher } = __nccwpck_require__(1892) -const { kHeadersList } = __nccwpck_require__(2785) - -const channels = {} -channels.open = diagnosticsChannel.channel('undici:websocket:open') -channels.close = diagnosticsChannel.channel('undici:websocket:close') -channels.socketError = diagnosticsChannel.channel('undici:websocket:socket_error') - -/** @type {import('crypto')} */ -let crypto -try { - crypto = __nccwpck_require__(6113) -} catch { - -} - -/** - * @see https://websockets.spec.whatwg.org/#concept-websocket-establish - * @param {URL} url - * @param {string|string[]} protocols - * @param {import('./websocket').WebSocket} ws - * @param {(response: any) => void} onEstablish - * @param {Partial} options - */ -function establishWebSocketConnection (url, protocols, ws, onEstablish, options) { - // 1. Let requestURL be a copy of url, with its scheme set to "http", if url’s - // scheme is "ws", and to "https" otherwise. - const requestURL = url - - requestURL.protocol = url.protocol === 'ws:' ? 'http:' : 'https:' - - // 2. Let request be a new request, whose URL is requestURL, client is client, - // service-workers mode is "none", referrer is "no-referrer", mode is - // "websocket", credentials mode is "include", cache mode is "no-store" , - // and redirect mode is "error". - const request = makeRequest({ - urlList: [requestURL], - serviceWorkers: 'none', - referrer: 'no-referrer', - mode: 'websocket', - credentials: 'include', - cache: 'no-store', - redirect: 'error' - }) - - // Note: undici extension, allow setting custom headers. - if (options.headers) { - const headersList = new Headers(options.headers)[kHeadersList] - - request.headersList = headersList - } - - // 3. Append (`Upgrade`, `websocket`) to request’s header list. - // 4. Append (`Connection`, `Upgrade`) to request’s header list. - // Note: both of these are handled by undici currently. - // https://github.com/nodejs/undici/blob/68c269c4144c446f3f1220951338daef4a6b5ec4/lib/client.js#L1397 - - // 5. Let keyValue be a nonce consisting of a randomly selected - // 16-byte value that has been forgiving-base64-encoded and - // isomorphic encoded. - const keyValue = crypto.randomBytes(16).toString('base64') - - // 6. Append (`Sec-WebSocket-Key`, keyValue) to request’s - // header list. - request.headersList.append('sec-websocket-key', keyValue) - - // 7. Append (`Sec-WebSocket-Version`, `13`) to request’s - // header list. - request.headersList.append('sec-websocket-version', '13') - - // 8. For each protocol in protocols, combine - // (`Sec-WebSocket-Protocol`, protocol) in request’s header - // list. - for (const protocol of protocols) { - request.headersList.append('sec-websocket-protocol', protocol) - } - - // 9. Let permessageDeflate be a user-agent defined - // "permessage-deflate" extension header value. - // https://github.com/mozilla/gecko-dev/blob/ce78234f5e653a5d3916813ff990f053510227bc/netwerk/protocol/websocket/WebSocketChannel.cpp#L2673 - // TODO: enable once permessage-deflate is supported - const permessageDeflate = '' // 'permessage-deflate; 15' +/***/ 1145: +/***/ ((module) => { - // 10. Append (`Sec-WebSocket-Extensions`, permessageDeflate) to - // request’s header list. - // request.headersList.append('sec-websocket-extensions', permessageDeflate) +module.exports = 'AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAwABBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJs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ADcDACAAQShqQgA3AwAgAEEgakIANwMAIABBEGpCADcDACAAQQhqQgA3AwAgAEHdATYCHEEAC3sBAX8CQCAAKAIMIgMNAAJAIAAoAgRFDQAgACABNgIECwJAIAAgASACEMSAgIAAIgMNACAAKAIMDwsgACADNgIcQQAhAyAAKAIEIgFFDQAgACABIAIgACgCCBGBgICAAAAiAUUNACAAIAI2AhQgACABNgIMIAEhAwsgAwvk8wEDDn8DfgR/I4CAgIAAQRBrIgMkgICAgAAgASEEIAEhBSABIQYgASEHIAEhCCABIQkgASEKIAEhCyABIQwgASENIAEhDiABIQ8CQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgACgCHCIQQX9qDt0B2gEB2QECAwQFBgcICQoLDA0O2AEPENcBERLWARMUFRYXGBkaG+AB3wEcHR7VAR8gISIjJCXUASYnKCkqKyzTAdIBLS7RAdABLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVG2wFHSElKzwHOAUvNAUzMAU1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+f4ABgQGCAYMBhAGFAYYBhwGIAYkB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QAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAC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FCAAIBA2AgxBACEQDLIBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxNCyAAQdMANgIcIAAgATYCFCAAIBA2AgxBACEQDLEBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxRCyAAQeUANgIcIAAgATYCFCAAIBA2AgxBACEQDLABCyAAQQA2AhwgACABNgIUIABBxoqAgAA2AhAgAEEHNgIMQQAhEAyvAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMSQsgAEHSADYCHCAAIAE2AhQgACAQNgIMQQAhEAyuAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMSQsgAEHTADYCHCAAIAE2AhQgACAQNgIMQQAhEAytAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMTQsgAEHlADYCHCAAIAE2AhQgACAQNgIMQQAhEAysAQsgAEEANgIcIAAgATYCFCAAQdyIgIAANgIQIABBBzYCDEEAIRAMqwELIBBBP0cNASABQQFqIQELQQUhEAyQAQtBACEQIABBADYCHCAAIAE2AhQgAEH9koCAADYCECAAQQc2AgwMqAELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEILIABB0gA2AhwgACABNgIUIAAgEDYCDEEAIRAMpwELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEILIABB0wA2AhwgACABNgIUIAAgEDYCDEEAIRAMpgELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEYLIABB5QA2AhwgACABNgIUIAAgEDYCDEEAIRAMpQELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDD8LIABB0gA2AhwgACAUNgIUIAAgATYCDEEAIRAMpAELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDD8LIABB0wA2AhwgACAUNgIUIAAgATYCDEEAIRAMowELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDEMLIABB5QA2AhwgACAU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YWdlX2JlZ2luYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlYCBjYWxsYmFjayBlcnJvcgBgb25fc3RhdHVzX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdmVyc2lvbl9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3VybF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWVzc2FnZV9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX21ldGhvZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lYCBjYWxsYmFjayBlcnJvcgBVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNlcnZlcgBJbnZhbGlkIGhlYWRlciB2YWx1ZSBjaGFyAEludmFsaWQgaGVhZGVyIGZpZWxkIGNoYXIAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl92ZXJzaW9uAEludmFsaWQgbWlub3IgdmVyc2lvbgBJbnZhbGlkIG1ham9yIHZlcnNpb24ARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgdmVyc2lvbgBFeHBlY3RlZCBDUkxGIGFmdGVyIHZlcnNpb24ASW52YWxpZCBIVFRQIHZlcnNpb24ASW52YWxpZCBoZWFkZXIgdG9rZW4AU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl91cmwASW52YWxpZCBjaGFyYWN0ZXJzIGluIHVybABVbmV4cGVjdGVkIHN0YXJ0IGNoYXIgaW4gdXJsAERvdWJsZSBAIGluIHVybABFbXB0eSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXJhY3RlciBpbiBDb250ZW50LUxlbmd0aABEdXBsaWNhdGUgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyIGluIHVybCBwYXRoAENvbnRlbnQtTGVuZ3RoIGNhbid0IGJlIHByZXNlbnQgd2l0aCBUcmFuc2Zlci1FbmNvZGluZwBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBzaXplAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX3ZhbHVlAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgdmFsdWUATWlzc2luZyBleHBlY3RlZCBMRiBhZnRlciBoZWFkZXIgdmFsdWUASW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHF1b3RlIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGVkIHZhbHVlAFBhdXNlZCBieSBvbl9oZWFkZXJzX2NvbXBsZXRlAEludmFsaWQgRU9GIHN0YXRlAG9uX3Jlc2V0IHBhdXNlAG9uX2NodW5rX2hlYWRlciBwYXVzZQBvbl9tZXNzYWdlX2JlZ2luIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZSBwYXVzZQBvbl9zdGF0dXNfY29tcGxldGUgcGF1c2UAb25fdmVyc2lvbl9jb21wbGV0ZSBwYXVzZQBvbl91cmxfY29tcGxldGUgcGF1c2UAb25fY2h1bmtfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlIHBhdXNlAG9uX21lc3NhZ2VfY29tcGxldGUgcGF1c2UAb25fbWV0aG9kX2NvbXBsZXRlIHBhdXNlAG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19leHRlbnNpb25fbmFtZSBwYXVzZQBVbmV4cGVjdGVkIHNwYWNlIGFmdGVyIHN0YXJ0IGxpbmUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fbmFtZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIG5hbWUAUGF1c2Ugb24gQ09OTkVDVC9VcGdyYWRlAFBhdXNlIG9uIFBSSS9VcGdyYWRlAEV4cGVjdGVkIEhUVFAvMiBDb25uZWN0aW9uIFByZWZhY2UAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9tZXRob2QARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgbWV0aG9kAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX2ZpZWxkAFBhdXNlZABJbnZhbGlkIHdvcmQgZW5jb3VudGVyZWQASW52YWxpZCBtZXRob2QgZW5jb3VudGVyZWQAVW5leHBlY3RlZCBjaGFyIGluIHVybCBzY2hlbWEAUmVxdWVzdCBoYXMgaW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgAFNXSVRDSF9QUk9YWQBVU0VfUFJPWFkATUtBQ1RJVklUWQBVTlBST0NFU1NBQkxFX0VOVElUWQBDT1BZAE1PVkVEX1BFUk1BTkVOVExZAFRPT19FQVJMWQBOT1RJRlkARkFJTEVEX0RFUEVOREVOQ1kAQkFEX0dBVEVXQVkAUExBWQBQVVQAQ0hFQ0tPVVQAR0FURVdBWV9USU1FT1VUAFJFUVVFU1RfVElNRU9VVABORVRXT1JLX0NPTk5FQ1RfVElNRU9VVABDT05ORUNUSU9OX1RJTUVPVVQATE9HSU5fVElNRU9VVABORVRXT1JLX1JFQURfVElNRU9VVABQT1NUAE1JU0RJUkVDVEVEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9SRVFVRVNUAENMSUVOVF9DTE9TRURfTE9BRF9CQUxBTkNFRF9SRVFVRVNUAEJBRF9SRVFVRVNUAEhUVFBfUkVRVUVTVF9TRU5UX1RPX0hUVFBTX1BPUlQAUkVQT1JUAElNX0FfVEVBUE9UAFJFU0VUX0NPTlRFTlQATk9fQ09OVEVOVABQQVJUSUFMX0NPTlRFTlQASFBFX0lOVkFMSURfQ09OU1RBTlQASFBFX0NCX1JFU0VUAEdFVABIUEVfU1RSSUNUAENPTkZMSUNUAFRFTVBPUkFSWV9SRURJUkVDVABQRVJNQU5FTlRfUkVESVJFQ1QAQ09OTkVDVABNVUxUSV9TVEFUVVMASFBFX0lOVkFMSURfU1RBVFVTAFRPT19NQU5ZX1JFUVVFU1RTAEVBUkxZX0hJTlRTAFVOQVZBSUxBQkxFX0ZPUl9MRUdBTF9SRUFTT05TAE9QVElPTlMAU1dJVENISU5HX1BST1RPQ09MUwBWQVJJQU5UX0FMU09fTkVHT1RJQVRFUwBNVUxUSVBMRV9DSE9JQ0VTAElOVEVSTkFMX1NFUlZFUl9FUlJPUgBXRUJfU0VSVkVSX1VOS05PV05fRVJST1IAUkFJTEdVTl9FUlJPUgBJREVOVElUWV9QUk9WSURFUl9BVVRIRU5USUNBVElPTl9FUlJPUgBTU0xfQ0VSVElGSUNBVEVfRVJST1IASU5WQUxJRF9YX0ZPUldBUkRFRF9GT1IAU0VUX1BBUkFNRVRFUgBHRVRfUEFSQU1FVEVSAEhQRV9VU0VSAFNFRV9PVEhFUgBIUEVfQ0JfQ0hVTktfSEVBREVSAE1LQ0FMRU5EQVIAU0VUVVAAV0VCX1NFUlZFUl9JU19ET1dOAFRFQVJET1dOAEhQRV9DTE9TRURfQ09OTkVDVElPTgBIRVVSSVNUSUNfRVhQSVJBVElPTgBESVNDT05ORUNURURfT1BFUkFUSU9OAE5PTl9BVVRIT1JJVEFUSVZFX0lORk9STUFUSU9OAEhQRV9JTlZBTElEX1ZFUlNJT04ASFBFX0NCX01FU1NBR0VfQkVHSU4AU0lURV9JU19GUk9aRU4ASFBFX0lOVkFMSURfSEVBREVSX1RPS0VOAElOVkFMSURfVE9LRU4ARk9SQklEREVOAEVOSEFOQ0VfWU9VUl9DQUxNAEhQRV9JTlZBTElEX1VSTABCTE9DS0VEX0JZX1BBUkVOVEFMX0NPTlRST0wATUtDT0wAQUNMAEhQRV9JTlRFUk5BTABSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFX1VOT0ZGSUNJQUwASFBFX09LAFVOTElOSwBVTkxPQ0sAUFJJAFJFVFJZX1dJVEgASFBFX0lOVkFMSURfQ09OVEVOVF9MRU5HVEgASFBFX1VORVhQRUNURURfQ09OVEVOVF9MRU5HVEgARkxVU0gAUFJPUFBBVENIAE0tU0VBUkNIAFVSSV9UT09fTE9ORwBQUk9DRVNTSU5HAE1JU0NFTExBTkVPVVNfUEVSU0lTVEVOVF9XQVJOSU5HAE1JU0NFTExBTkVPVVNfV0FSTklORwBIUEVfSU5WQUxJRF9UUkFOU0ZFUl9FTkNPRElORwBFeHBlY3RlZCBDUkxGAEhQRV9JTlZBTElEX0NIVU5LX1NJWkUATU9WRQBDT05USU5VRQBIUEVfQ0JfU1RBVFVTX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJTX0NPTVBMRVRFAEhQRV9DQl9WRVJTSU9OX0NPTVBMRVRFAEhQRV9DQl9VUkxfQ09NUExFVEUASFBFX0NCX0NIVU5LX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfVkFMVUVfQ09NUExFVEUASFBFX0NCX0NIVU5LX0VYVEVOU0lPTl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX05BTUVfQ09NUExFVEUASFBFX0NCX01FU1NBR0VfQ09NUExFVEUASFBFX0NCX01FVEhPRF9DT01QTEVURQBIUEVfQ0JfSEVBREVSX0ZJRUxEX0NPTVBMRVRFAERFTEVURQBIUEVfSU5WQUxJRF9FT0ZfU1RBVEUASU5WQUxJRF9TU0xfQ0VSVElGSUNBVEUAUEFVU0UATk9fUkVTUE9OU0UAVU5TVVBQT1JURURfTUVESUFfVFlQRQBHT05FAE5PVF9BQ0NFUFRBQkxFAFNFUlZJQ0VfVU5BVkFJTEFCTEUAUkFOR0VfTk9UX1NBVElTRklBQkxFAE9SSUdJTl9JU19VTlJFQUNIQUJMRQBSRVNQT05TRV9JU19TVEFMRQBQVVJHRQBNRVJHRQBSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFAFJFUVVFU1RfSEVBREVSX1RPT19MQVJHRQBQQVlMT0FEX1RPT19MQVJHRQBJTlNVRkZJQ0lFTlRfU1RPUkFHRQBIUEVfUEFVU0VEX1VQR1JBREUASFBFX1BBVVNFRF9IMl9VUEdSQURFAFNPVVJDRQBBTk5PVU5DRQBUUkFDRQBIUEVfVU5FWFBFQ1RFRF9TUEFDRQBERVNDUklCRQBVTlNVQlNDUklCRQBSRUNPUkQASFBFX0lOVkFMSURfTUVUSE9EAE5PVF9GT1VORABQUk9QRklORABVTkJJTkQAUkVCSU5EAFVOQVVUSE9SSVpFRABNRVRIT0RfTk9UX0FMTE9XRUQASFRUUF9WRVJTSU9OX05PVF9TVVBQT1JURUQAQUxSRUFEWV9SRVBPUlRFRABBQ0NFUFRFRABOT1RfSU1QTEVNRU5URUQATE9PUF9ERVRFQ1RFRABIUEVfQ1JfRVhQRUNURUQASFBFX0xGX0VYUEVDVEVEAENSRUFURUQASU1fVVNFRABIUEVfUEFVU0VEAFRJTUVPVVRfT0NDVVJFRABQQVlNRU5UX1JFUVVJUkVEAFBSRUNPTkRJVElPTl9SRVFVSVJFRABQUk9YWV9BVVRIRU5USUNBVElPTl9SRVFVSVJFRABORVRXT1JLX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAExFTkdUSF9SRVFVSVJFRABTU0xfQ0VSVElGSUNBVEVfUkVRVUlSRUQAVVBHUkFERV9SRVFVSVJFRABQQUdFX0VYUElSRUQAUFJFQ09ORElUSU9OX0ZBSUxFRABFWFBFQ1RBVElPTl9GQUlMRUQAUkVWQUxJREFUSU9OX0ZBSUxFRABTU0xfSEFORFNIQUtFX0ZBSUxFRABMT0NLRUQAVFJBTlNGT1JNQVRJT05fQVBQTElFRABOT1RfTU9ESUZJRUQATk9UX0VYVEVOREVEAEJBTkRXSURUSF9MSU1JVF9FWENFRURFRABTSVRFX0lTX09WRVJMT0FERUQASEVBRABFeHBlY3RlZCBIVFRQLwAAXhMAACYTAAAwEAAA8BcAAJ0TAAAVEgAAORcAAPASAAAKEAAAdRIAAK0SAACCEwAATxQAAH8QAACgFQAAIxQAAIkSAACLFAAATRUAANQRAADPFAAAEBgAAMkWAADcFgAAwREAAOAXAAC7FAAAdBQAAHwVAADlFAAACBcAAB8QAABlFQAAoxQAACgVAAACFQAAmRUAACwQAACLGQAATw8AANQOAABqEAAAzhAAAAIXAACJDgAAbhMAABwTAABmFAAAVhcAAMETAADNEwAAbBMAAGgXAABmFwAAXxcAACITAADODwAAaQ4AANgOAABjFgAAyxMAAKoOAAAoFwAAJhcAAMUTAABdFgAA6BEAAGcTAABlEwAA8hYAAHMTAAAdFwAA+RYAAPMRAADPDgAAzhUAAAwSAACzEQAApREAAGEQAAAyFwAAuxMAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIDAgICAgIAAAICAAICAAICAgICAgICAgIABAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAICAgICAAACAgACAgACAgICAgICAgICAAMABAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbG9zZWVlcC1hbGl2ZQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBY2h1bmtlZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAQEBAQEAAAEBAAEBAAEBAQEBAQEBAQEAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABlY3Rpb25lbnQtbGVuZ3Rob25yb3h5LWNvbm5lY3Rpb24AAAAAAAAAAAAAAAAAAAByYW5zZmVyLWVuY29kaW5ncGdyYWRlDQoNCg0KU00NCg0KVFRQL0NFL1RTUC8AAAAAAAAAAAAAAAABAgABAwAAAAAAAAAAAAAAAAAAAAAAAAQBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQIAAQMAAAAAAAAAAAAAAAAAAAAAAAAEAQEFAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAQAAAgAAAAAAAAAAAAAAAAAAAAAAAAMEAAAEBAQEBAQEBAQEBAUEBAQEBAQEBAQEBAQABAAGBwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAABAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAIAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABOT1VOQ0VFQ0tPVVRORUNURVRFQ1JJQkVMVVNIRVRFQURTRUFSQ0hSR0VDVElWSVRZTEVOREFSVkVPVElGWVBUSU9OU0NIU0VBWVNUQVRDSEdFT1JESVJFQ1RPUlRSQ0hQQVJBTUVURVJVUkNFQlNDUklCRUFSRE9XTkFDRUlORE5LQ0tVQlNDUklCRUhUVFAvQURUUC8=' - // 11. Fetch request with useParallelQueue set to true, and - // processResponse given response being these steps: - const controller = fetching({ - request, - useParallelQueue: true, - dispatcher: options.dispatcher ?? getGlobalDispatcher(), - processResponse (response) { - // 1. If response is a network error or its status is not 101, - // fail the WebSocket connection. - if (response.type === 'error' || response.status !== 101) { - failWebsocketConnection(ws, 'Received network error or non-101 status code.') - return - } - // 2. If protocols is not the empty list and extracting header - // list values given `Sec-WebSocket-Protocol` and response’s - // header list results in null, failure, or the empty byte - // sequence, then fail the WebSocket connection. - if (protocols.length !== 0 && !response.headersList.get('Sec-WebSocket-Protocol')) { - failWebsocketConnection(ws, 'Server did not respond with sent protocols.') - return - } +/***/ }), - // 3. Follow the requirements stated step 2 to step 6, inclusive, - // of the last set of steps in section 4.1 of The WebSocket - // Protocol to validate response. This either results in fail - // the WebSocket connection or the WebSocket connection is - // established. +/***/ 5627: +/***/ ((module) => { - // 2. If the response lacks an |Upgrade| header field or the |Upgrade| - // header field contains a value that is not an ASCII case- - // insensitive match for the value "websocket", the client MUST - // _Fail the WebSocket Connection_. - if (response.headersList.get('Upgrade')?.toLowerCase() !== 'websocket') { - failWebsocketConnection(ws, 'Server did not set Upgrade header to "websocket".') - return - } +module.exports = 'AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAwABBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJs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IAH9CwMAIABBMGogAf0LAwAgAEEgaiAB/QsDACAAQd0BNgIcQQALewEBfwJAIAAoAgwiAw0AAkAgACgCBEUNACAAIAE2AgQLAkAgACABIAIQxICAgAAiAw0AIAAoAgwPCyAAIAM2AhxBACEDIAAoAgQiAUUNACAAIAEgAiAAKAIIEYGAgIAAACIBRQ0AIAAgAjYCFCAAIAE2AgwgASEDCyADC+TzAQMOfwN+BH8jgICAgABBEGsiAySAgICAACABIQQgASEFIAEhBiABIQcgASEIIAEhCSABIQogASELIAEhDCABIQ0gASEOIAEhDwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAAKAIcIhBBf2oO3QHaAQHZAQIDBAUGBwgJCgsMDQ7YAQ8Q1wEREtYBExQVFhcYGRob4AHfARwdHtUBHyAhIiMkJdQBJicoKSorLNMB0gEtLtEB0AEvMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUbbAUdISUrPAc4BS80BTMwBTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gAGBAYIBgwGEAYUBhgGHAYgBiQGKAYsBjAGNAY4BjwGQAZEB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QAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIBAOxwEAAQID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YWNrIGVycm9yAGBvbl9jaHVua19leHRlbnNpb25fdmFsdWVgIGNhbGxiYWNrIGVycm9yAGBvbl9zdGF0dXNfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl92ZXJzaW9uX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdXJsX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWV0aG9kX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX25hbWVgIGNhbGxiYWNrIGVycm9yAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2VydmVyAEludmFsaWQgaGVhZGVyIHZhbHVlIGNoYXIASW52YWxpZCBoZWFkZXIgZmllbGQgY2hhcgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3ZlcnNpb24ASW52YWxpZCBtaW5vciB2ZXJzaW9uAEludmFsaWQgbWFqb3IgdmVyc2lvbgBFeHBlY3RlZCBzcGFjZSBhZnRlciB2ZXJzaW9uAEV4cGVjdGVkIENSTEYgYWZ0ZXIgdmVyc2lvbgBJbnZhbGlkIEhUVFAgdmVyc2lvbgBJbnZhbGlkIGhlYWRlciB0b2tlbgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3VybABJbnZhbGlkIGNoYXJhY3RlcnMgaW4gdXJsAFVuZXhwZWN0ZWQgc3RhcnQgY2hhciBpbiB1cmwARG91YmxlIEAgaW4gdXJsAEVtcHR5IENvbnRlbnQtTGVuZ3RoAEludmFsaWQgY2hhcmFjdGVyIGluIENvbnRlbnQtTGVuZ3RoAER1cGxpY2F0ZSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXIgaW4gdXJsIHBhdGgAQ29udGVudC1MZW5ndGggY2FuJ3QgYmUgcHJlc2VudCB3aXRoIFRyYW5zZmVyLUVuY29kaW5nAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIHNpemUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfdmFsdWUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyB2YWx1ZQBNaXNzaW5nIGV4cGVjdGVkIExGIGFmdGVyIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AgaGVhZGVyIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGUgdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZWQgdmFsdWUAUGF1c2VkIGJ5IG9uX2hlYWRlcnNfY29tcGxldGUASW52YWxpZCBFT0Ygc3RhdGUAb25fcmVzZXQgcGF1c2UAb25fY2h1bmtfaGVhZGVyIHBhdXNlAG9uX21lc3NhZ2VfYmVnaW4gcGF1c2UAb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlIHBhdXNlAG9uX3N0YXR1c19jb21wbGV0ZSBwYXVzZQBvbl92ZXJzaW9uX2NvbXBsZXRlIHBhdXNlAG9uX3VybF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19jb21wbGV0ZSBwYXVzZQBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGUgcGF1c2UAb25fbWVzc2FnZV9jb21wbGV0ZSBwYXVzZQBvbl9tZXRob2RfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lIHBhdXNlAFVuZXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgc3RhcnQgbGluZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgbmFtZQBQYXVzZSBvbiBDT05ORUNUL1VwZ3JhZGUAUGF1c2Ugb24gUFJJL1VwZ3JhZGUARXhwZWN0ZWQgSFRUUC8yIENvbm5lY3Rpb24gUHJlZmFjZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX21ldGhvZABFeHBlY3RlZCBzcGFjZSBhZnRlciBtZXRob2QAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfZmllbGQAUGF1c2VkAEludmFsaWQgd29yZCBlbmNvdW50ZXJlZABJbnZhbGlkIG1ldGhvZCBlbmNvdW50ZXJlZABVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNjaGVtYQBSZXF1ZXN0IGhhcyBpbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AAU1dJVENIX1BST1hZAFVTRV9QUk9YWQBNS0FDVElWSVRZAFVOUFJPQ0VTU0FCTEVfRU5USVRZAENPUFkATU9WRURfUEVSTUFORU5UTFkAVE9PX0VBUkxZAE5PVElGWQBGQUlMRURfREVQRU5ERU5DWQBCQURfR0FURVdBWQBQTEFZAFBVVABDSEVDS09VVABHQVRFV0FZX1RJTUVPVVQAUkVRVUVTVF9USU1FT1VUAE5FVFdPUktfQ09OTkVDVF9USU1FT1VUAENPTk5FQ1RJT05fVElNRU9VVABMT0dJTl9USU1FT1VUAE5FVFdPUktfUkVBRF9USU1FT1VUAFBPU1QATUlTRElSRUNURURfUkVRVUVTVABDTElFTlRfQ0xPU0VEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9MT0FEX0JBTEFOQ0VEX1JFUVVFU1QAQkFEX1JFUVVFU1QASFRUUF9SRVFVRVNUX1NFTlRfVE9fSFRUUFNfUE9SVABSRVBPUlQASU1fQV9URUFQT1QAUkVTRVRfQ09OVEVOVABOT19DT05URU5UAFBBUlRJQUxfQ09OVEVOVABIUEVfSU5WQUxJRF9DT05TVEFOVABIUEVfQ0JfUkVTRVQAR0VUAEhQRV9TVFJJQ1QAQ09ORkxJQ1QAVEVNUE9SQVJZX1JFRElSRUNUAFBFUk1BTkVOVF9SRURJUkVDVABDT05ORUNUAE1VTFRJX1NUQVRVUwBIUEVfSU5WQUxJRF9TVEFUVVMAVE9PX01BTllfUkVRVUVTVFMARUFSTFlfSElOVFMAVU5BVkFJTEFCTEVfRk9SX0xFR0FMX1JFQVNPTlMAT1BUSU9OUwBTV0lUQ0hJTkdfUFJPVE9DT0xTAFZBUklBTlRfQUxTT19ORUdPVElBVEVTAE1VTFRJUExFX0NIT0lDRVMASU5URVJOQUxfU0VSVkVSX0VSUk9SAFdFQl9TRVJWRVJfVU5LTk9XTl9FUlJPUgBSQUlMR1VOX0VSUk9SAElERU5USVRZX1BST1ZJREVSX0FVVEhFTlRJQ0FUSU9OX0VSUk9SAFNTTF9DRVJUSUZJQ0FURV9FUlJPUgBJTlZBTElEX1hfRk9SV0FSREVEX0ZPUgBTRVRfUEFSQU1FVEVSAEdFVF9QQVJBTUVURVIASFBFX1VTRVIAU0VFX09USEVSAEhQRV9DQl9DSFVOS19IRUFERVIATUtDQUxFTkRBUgBTRVRVUABXRUJfU0VSVkVSX0lTX0RPV04AVEVBUkRPV04ASFBFX0NMT1NFRF9DT05ORUNUSU9OAEhFVVJJU1RJQ19FWFBJUkFUSU9OAERJU0NPTk5FQ1RFRF9PUEVSQVRJT04ATk9OX0FVVEhPUklUQVRJVkVfSU5GT1JNQVRJT04ASFBFX0lOVkFMSURfVkVSU0lPTgBIUEVfQ0JfTUVTU0FHRV9CRUdJTgBTSVRFX0lTX0ZST1pFTgBIUEVfSU5WQUxJRF9IRUFERVJfVE9LRU4ASU5WQUxJRF9UT0tFTgBGT1JCSURERU4ARU5IQU5DRV9ZT1VSX0NBTE0ASFBFX0lOVkFMSURfVVJMAEJMT0NLRURfQllfUEFSRU5UQUxfQ09OVFJPTABNS0NPTABBQ0wASFBFX0lOVEVSTkFMAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0VfVU5PRkZJQ0lBTABIUEVfT0sAVU5MSU5LAFVOTE9DSwBQUkkAUkVUUllfV0lUSABIUEVfSU5WQUxJRF9DT05URU5UX0xFTkdUSABIUEVfVU5FWFBFQ1RFRF9DT05URU5UX0xFTkdUSABGTFVTSABQUk9QUEFUQ0gATS1TRUFSQ0gAVVJJX1RPT19MT05HAFBST0NFU1NJTkcATUlTQ0VMTEFORU9VU19QRVJTSVNURU5UX1dBUk5JTkcATUlTQ0VMTEFORU9VU19XQVJOSU5HAEhQRV9JTlZBTElEX1RSQU5TRkVSX0VOQ09ESU5HAEV4cGVjdGVkIENSTEYASFBFX0lOVkFMSURfQ0hVTktfU0laRQBNT1ZFAENPTlRJTlVFAEhQRV9DQl9TVEFUVVNfQ09NUExFVEUASFBFX0NCX0hFQURFUlNfQ09NUExFVEUASFBFX0NCX1ZFUlNJT05fQ09NUExFVEUASFBFX0NCX1VSTF9DT01QTEVURQBIUEVfQ0JfQ0hVTktfQ09NUExFVEUASFBFX0NCX0hFQURFUl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fTkFNRV9DT01QTEVURQBIUEVfQ0JfTUVTU0FHRV9DT01QTEVURQBIUEVfQ0JfTUVUSE9EX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfRklFTERfQ09NUExFVEUAREVMRVRFAEhQRV9JTlZBTElEX0VPRl9TVEFURQBJTlZBTElEX1NTTF9DRVJUSUZJQ0FURQBQQVVTRQBOT19SRVNQT05TRQBVTlNVUFBPUlRFRF9NRURJQV9UWVBFAEdPTkUATk9UX0FDQ0VQVEFCTEUAU0VSVklDRV9VTkFWQUlMQUJMRQBSQU5HRV9OT1RfU0FUSVNGSUFCTEUAT1JJR0lOX0lTX1VOUkVBQ0hBQkxFAFJFU1BPTlNFX0lTX1NUQUxFAFBVUkdFAE1FUkdFAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0UAUkVRVUVTVF9IRUFERVJfVE9PX0xBUkdFAFBBWUxPQURfVE9PX0xBUkdFAElOU1VGRklDSUVOVF9TVE9SQUdFAEhQRV9QQVVTRURfVVBHUkFERQBIUEVfUEFVU0VEX0gyX1VQR1JBREUAU09VUkNFAEFOTk9VTkNFAFRSQUNFAEhQRV9VTkVYUEVDVEVEX1NQQUNFAERFU0NSSUJFAFVOU1VCU0NSSUJFAFJFQ09SRABIUEVfSU5WQUxJRF9NRVRIT0QATk9UX0ZPVU5EAFBST1BGSU5EAFVOQklORABSRUJJTkQAVU5BVVRIT1JJWkVEAE1FVEhPRF9OT1RfQUxMT1dFRABIVFRQX1ZFUlNJT05fTk9UX1NVUFBPUlRFRABBTFJFQURZX1JFUE9SVEVEAEFDQ0VQVEVEAE5PVF9JTVBMRU1FTlRFRABMT09QX0RFVEVDVEVEAEhQRV9DUl9FWFBFQ1RFRABIUEVfTEZfRVhQRUNURUQAQ1JFQVRFRABJTV9VU0VEAEhQRV9QQVVTRUQAVElNRU9VVF9PQ0NVUkVEAFBBWU1FTlRfUkVRVUlSRUQAUFJFQ09ORElUSU9OX1JFUVVJUkVEAFBST1hZX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAE5FVFdPUktfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATEVOR1RIX1JFUVVJUkVEAFNTTF9DRVJUSUZJQ0FURV9SRVFVSVJFRABVUEdSQURFX1JFUVVJUkVEAFBBR0VfRVhQSVJFRABQUkVDT05ESVRJT05fRkFJTEVEAEVYUEVDVEFUSU9OX0ZBSUxFRABSRVZBTElEQVRJT05fRkFJTEVEAFNTTF9IQU5EU0hBS0VfRkFJTEVEAExPQ0tFRABUUkFOU0ZPUk1BVElPTl9BUFBMSUVEAE5PVF9NT0RJRklFRABOT1RfRVhURU5ERUQAQkFORFdJRFRIX0xJTUlUX0VYQ0VFREVEAFNJVEVfSVNfT1ZFUkxPQURFRABIRUFEAEV4cGVjdGVkIEhUVFAvAABeEwAAJhMAADAQAADwFwAAnRMAABUSAAA5FwAA8BIAAAoQAAB1EgAArRIAAIITAABPFAAAfxAAAKAVAAAjFAAAiRIAAIsUAABNFQAA1BEAAM8UAAAQGAAAyRYAANwWAADBEQAA4BcAALsUAAB0FAAAfBUAAOUUAAAIFwAAHxAAAGUVAACjFAAAKBUAAAIVAACZFQAALBAAAIsZAABPDwAA1A4AAGoQAADOEAAAAhcAAIkOAABuEwAAHBMAAGYUAABWFwAAwRMAAM0TAABsEwAAaBcAAGYXAABfFwAAIhMAAM4PAABpDgAA2A4AAGMWAADLEwAAqg4AACgXAAAmFwAAxRMAAF0WAADoEQAAZxMAAGUTAADyFgAAcxMAAB0XAAD5FgAA8xEAAM8OAADOFQAADBIAALMRAAClEQAAYRAAADIXAAC7EwAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgMCAgICAgAAAgIAAgIAAgICAgICAgICAgAEAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAAIAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAgICAgIAAAICAAICAAICAgICAgICAgIAAwAEAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsb3NlZWVwLWFsaXZlAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQFjaHVua2VkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQABAQEBAQAAAQEAAQEAAQEBAQEBAQEBAQAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGVjdGlvbmVudC1sZW5ndGhvbnJveHktY29ubmVjdGlvbgAAAAAAAAAAAAAAAAAAAHJhbnNmZXItZW5jb2RpbmdwZ3JhZGUNCg0KDQpTTQ0KDQpUVFAvQ0UvVFNQLwAAAAAAAAAAAAAAAAECAAEDAAAAAAAAAAAAAAAAAAAAAAAABAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAgABAwAAAAAAAAAAAAAAAAAAAAAAAAQBAQUBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAABAAACAAAAAAAAAAAAAAAAAAAAAAAAAwQAAAQEBAQEBAQEBAQEBQQEBAQEBAQEBAQEBAAEAAYHBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAgAAAAACAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE5PVU5DRUVDS09VVE5FQ1RFVEVDUklCRUxVU0hFVEVBRFNFQVJDSFJHRUNUSVZJVFlMRU5EQVJWRU9USUZZUFRJT05TQ0hTRUFZU1RBVENIR0VPUkRJUkVDVE9SVFJDSFBBUkFNRVRFUlVSQ0VCU0NSSUJFQVJET1dOQUNFSU5ETktDS1VCU0NSSUJFSFRUUC9BRFRQLw==' - // 3. If the response lacks a |Connection| header field or the - // |Connection| header field doesn't contain a token that is an - // ASCII case-insensitive match for the value "Upgrade", the client - // MUST _Fail the WebSocket Connection_. - if (response.headersList.get('Connection')?.toLowerCase() !== 'upgrade') { - failWebsocketConnection(ws, 'Server did not set Connection header to "upgrade".') - return - } - // 4. If the response lacks a |Sec-WebSocket-Accept| header field or - // the |Sec-WebSocket-Accept| contains a value other than the - // base64-encoded SHA-1 of the concatenation of the |Sec-WebSocket- - // Key| (as a string, not base64-decoded) with the string "258EAFA5- - // E914-47DA-95CA-C5AB0DC85B11" but ignoring any leading and - // trailing whitespace, the client MUST _Fail the WebSocket - // Connection_. - const secWSAccept = response.headersList.get('Sec-WebSocket-Accept') - const digest = crypto.createHash('sha1').update(keyValue + uid).digest('base64') - if (secWSAccept !== digest) { - failWebsocketConnection(ws, 'Incorrect hash received in Sec-WebSocket-Accept header.') - return - } +/***/ }), - // 5. If the response includes a |Sec-WebSocket-Extensions| header - // field and this header field indicates the use of an extension - // that was not present in the client's handshake (the server has - // indicated an extension not requested by the client), the client - // MUST _Fail the WebSocket Connection_. (The parsing of this - // header field to determine which extensions are requested is - // discussed in Section 9.1.) - const secExtension = response.headersList.get('Sec-WebSocket-Extensions') +/***/ 1891: +/***/ ((__unused_webpack_module, exports) => { - if (secExtension !== null && secExtension !== permessageDeflate) { - failWebsocketConnection(ws, 'Received different permessage-deflate than the one set.') - return - } +"use strict"; - // 6. If the response includes a |Sec-WebSocket-Protocol| header field - // and this header field indicates the use of a subprotocol that was - // not present in the client's handshake (the server has indicated a - // subprotocol not requested by the client), the client MUST _Fail - // the WebSocket Connection_. - const secProtocol = response.headersList.get('Sec-WebSocket-Protocol') +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.enumToMap = void 0; +function enumToMap(obj) { + const res = {}; + Object.keys(obj).forEach((key) => { + const value = obj[key]; + if (typeof value === 'number') { + res[key] = value; + } + }); + return res; +} +exports.enumToMap = enumToMap; +//# sourceMappingURL=utils.js.map - if (secProtocol !== null && secProtocol !== request.headersList.get('Sec-WebSocket-Protocol')) { - failWebsocketConnection(ws, 'Protocol was not set in the opening handshake.') - return - } +/***/ }), - response.socket.on('data', onSocketData) - response.socket.on('close', onSocketClose) - response.socket.on('error', onSocketError) +/***/ 6771: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (channels.open.hasSubscribers) { - channels.open.publish({ - address: response.socket.address(), - protocol: secProtocol, - extensions: secExtension - }) - } +"use strict"; - onEstablish(response) - } - }) - return controller -} +const { kClients } = __nccwpck_require__(2785) +const Agent = __nccwpck_require__(7890) +const { + kAgent, + kMockAgentSet, + kMockAgentGet, + kDispatches, + kIsMockActive, + kNetConnect, + kGetNetConnect, + kOptions, + kFactory +} = __nccwpck_require__(4347) +const MockClient = __nccwpck_require__(8687) +const MockPool = __nccwpck_require__(6193) +const { matchValue, buildMockOptions } = __nccwpck_require__(9323) +const { InvalidArgumentError, UndiciError } = __nccwpck_require__(8045) +const Dispatcher = __nccwpck_require__(412) +const Pluralizer = __nccwpck_require__(8891) +const PendingInterceptorsFormatter = __nccwpck_require__(6823) -/** - * @param {Buffer} chunk - */ -function onSocketData (chunk) { - if (!this.ws[kByteParser].write(chunk)) { - this.pause() +class FakeWeakRef { + constructor (value) { + this.value = value } -} -/** - * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol - * @see https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4 - */ -function onSocketClose () { - const { ws } = this + deref () { + return this.value + } +} - // If the TCP connection was closed after the - // WebSocket closing handshake was completed, the WebSocket connection - // is said to have been closed _cleanly_. - const wasClean = ws[kSentClose] && ws[kReceivedClose] +class MockAgent extends Dispatcher { + constructor (opts) { + super(opts) - let code = 1005 - let reason = '' + this[kNetConnect] = true + this[kIsMockActive] = true - const result = ws[kByteParser].closingInfo + // Instantiate Agent and encapsulate + if ((opts && opts.agent && typeof opts.agent.dispatch !== 'function')) { + throw new InvalidArgumentError('Argument opts.agent must implement Agent') + } + const agent = opts && opts.agent ? opts.agent : new Agent(opts) + this[kAgent] = agent - if (result) { - code = result.code ?? 1005 - reason = result.reason - } else if (!ws[kSentClose]) { - // If _The WebSocket - // Connection is Closed_ and no Close control frame was received by the - // endpoint (such as could occur if the underlying transport connection - // is lost), _The WebSocket Connection Close Code_ is considered to be - // 1006. - code = 1006 + this[kClients] = agent[kClients] + this[kOptions] = buildMockOptions(opts) } - // 1. Change the ready state to CLOSED (3). - ws[kReadyState] = states.CLOSED + get (origin) { + let dispatcher = this[kMockAgentGet](origin) - // 2. If the user agent was required to fail the WebSocket - // connection, or if the WebSocket connection was closed - // after being flagged as full, fire an event named error - // at the WebSocket object. - // TODO + if (!dispatcher) { + dispatcher = this[kFactory](origin) + this[kMockAgentSet](origin, dispatcher) + } + return dispatcher + } - // 3. Fire an event named close at the WebSocket object, - // using CloseEvent, with the wasClean attribute - // initialized to true if the connection closed cleanly - // and false otherwise, the code attribute initialized to - // the WebSocket connection close code, and the reason - // attribute initialized to the result of applying UTF-8 - // decode without BOM to the WebSocket connection close - // reason. - fireEvent('close', ws, CloseEvent, { - wasClean, code, reason - }) + dispatch (opts, handler) { + // Call MockAgent.get to perform additional setup before dispatching as normal + this.get(opts.origin) + return this[kAgent].dispatch(opts, handler) + } - if (channels.close.hasSubscribers) { - channels.close.publish({ - websocket: ws, - code, - reason - }) + async close () { + await this[kAgent].close() + this[kClients].clear() } -} -function onSocketError (error) { - const { ws } = this + deactivate () { + this[kIsMockActive] = false + } - ws[kReadyState] = states.CLOSING + activate () { + this[kIsMockActive] = true + } - if (channels.socketError.hasSubscribers) { - channels.socketError.publish(error) + enableNetConnect (matcher) { + if (typeof matcher === 'string' || typeof matcher === 'function' || matcher instanceof RegExp) { + if (Array.isArray(this[kNetConnect])) { + this[kNetConnect].push(matcher) + } else { + this[kNetConnect] = [matcher] + } + } else if (typeof matcher === 'undefined') { + this[kNetConnect] = true + } else { + throw new InvalidArgumentError('Unsupported matcher. Must be one of String|Function|RegExp.') + } } - this.destroy() -} + disableNetConnect () { + this[kNetConnect] = false + } -module.exports = { - establishWebSocketConnection -} + // This is required to bypass issues caused by using global symbols - see: + // https://github.com/nodejs/undici/issues/1447 + get isMockActive () { + return this[kIsMockActive] + } + [kMockAgentSet] (origin, dispatcher) { + this[kClients].set(origin, new FakeWeakRef(dispatcher)) + } -/***/ }), + [kFactory] (origin) { + const mockOptions = Object.assign({ agent: this }, this[kOptions]) + return this[kOptions] && this[kOptions].connections === 1 + ? new MockClient(origin, mockOptions) + : new MockPool(origin, mockOptions) + } -/***/ 9188: -/***/ ((module) => { + [kMockAgentGet] (origin) { + // First check if we can immediately find it + const ref = this[kClients].get(origin) + if (ref) { + return ref.deref() + } -"use strict"; + // If the origin is not a string create a dummy parent pool and return to user + if (typeof origin !== 'string') { + const dispatcher = this[kFactory]('http://localhost:9999') + this[kMockAgentSet](origin, dispatcher) + return dispatcher + } + // If we match, create a pool and assign the same dispatches + for (const [keyMatcher, nonExplicitRef] of Array.from(this[kClients])) { + const nonExplicitDispatcher = nonExplicitRef.deref() + if (nonExplicitDispatcher && typeof keyMatcher !== 'string' && matchValue(keyMatcher, origin)) { + const dispatcher = this[kFactory](origin) + this[kMockAgentSet](origin, dispatcher) + dispatcher[kDispatches] = nonExplicitDispatcher[kDispatches] + return dispatcher + } + } + } -// This is a Globally Unique Identifier unique used -// to validate that the endpoint accepts websocket -// connections. -// See https://www.rfc-editor.org/rfc/rfc6455.html#section-1.3 -const uid = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11' + [kGetNetConnect] () { + return this[kNetConnect] + } -/** @type {PropertyDescriptor} */ -const staticPropertyDescriptors = { - enumerable: true, - writable: false, - configurable: false -} + pendingInterceptors () { + const mockAgentClients = this[kClients] -const states = { - CONNECTING: 0, - OPEN: 1, - CLOSING: 2, - CLOSED: 3 -} + return Array.from(mockAgentClients.entries()) + .flatMap(([origin, scope]) => scope.deref()[kDispatches].map(dispatch => ({ ...dispatch, origin }))) + .filter(({ pending }) => pending) + } -const opcodes = { - CONTINUATION: 0x0, - TEXT: 0x1, - BINARY: 0x2, - CLOSE: 0x8, - PING: 0x9, - PONG: 0xA -} + assertNoPendingInterceptors ({ pendingInterceptorsFormatter = new PendingInterceptorsFormatter() } = {}) { + const pending = this.pendingInterceptors() -const maxUnsigned16Bit = 2 ** 16 - 1 // 65535 + if (pending.length === 0) { + return + } -const parserStates = { - INFO: 0, - PAYLOADLENGTH_16: 2, - PAYLOADLENGTH_64: 3, - READ_DATA: 4 -} + const pluralizer = new Pluralizer('interceptor', 'interceptors').pluralize(pending.length) -const emptyBuffer = Buffer.allocUnsafe(0) + throw new UndiciError(` +${pluralizer.count} ${pluralizer.noun} ${pluralizer.is} pending: -module.exports = { - uid, - staticPropertyDescriptors, - states, - opcodes, - maxUnsigned16Bit, - parserStates, - emptyBuffer +${pendingInterceptorsFormatter.format(pending)} +`.trim()) + } } +module.exports = MockAgent + /***/ }), -/***/ 2611: +/***/ 8687: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { webidl } = __nccwpck_require__(1744) -const { kEnumerableProperty } = __nccwpck_require__(3983) -const { MessagePort } = __nccwpck_require__(1267) +const { promisify } = __nccwpck_require__(3837) +const Client = __nccwpck_require__(3598) +const { buildMockDispatch } = __nccwpck_require__(9323) +const { + kDispatches, + kMockAgent, + kClose, + kOriginalClose, + kOrigin, + kOriginalDispatch, + kConnected +} = __nccwpck_require__(4347) +const { MockInterceptor } = __nccwpck_require__(410) +const Symbols = __nccwpck_require__(2785) +const { InvalidArgumentError } = __nccwpck_require__(8045) /** - * @see https://html.spec.whatwg.org/multipage/comms.html#messageevent + * MockClient provides an API that extends the Client to influence the mockDispatches. */ -class MessageEvent extends Event { - #eventInit +class MockClient extends Client { + constructor (origin, opts) { + super(origin, opts) - constructor (type, eventInitDict = {}) { - webidl.argumentLengthCheck(arguments, 1, { header: 'MessageEvent constructor' }) + if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') { + throw new InvalidArgumentError('Argument opts.agent must implement Agent') + } - type = webidl.converters.DOMString(type) - eventInitDict = webidl.converters.MessageEventInit(eventInitDict) + this[kMockAgent] = opts.agent + this[kOrigin] = origin + this[kDispatches] = [] + this[kConnected] = 1 + this[kOriginalDispatch] = this.dispatch + this[kOriginalClose] = this.close.bind(this) - super(type, eventInitDict) + this.dispatch = buildMockDispatch.call(this) + this.close = this[kClose] + } - this.#eventInit = eventInitDict + get [Symbols.kConnected] () { + return this[kConnected] } - get data () { - webidl.brandCheck(this, MessageEvent) + /** + * Sets up the base interceptor for mocking replies from undici. + */ + intercept (opts) { + return new MockInterceptor(opts, this[kDispatches]) + } - return this.#eventInit.data + async [kClose] () { + await promisify(this[kOriginalClose])() + this[kConnected] = 0 + this[kMockAgent][Symbols.kClients].delete(this[kOrigin]) } +} - get origin () { - webidl.brandCheck(this, MessageEvent) +module.exports = MockClient - return this.#eventInit.origin - } - get lastEventId () { - webidl.brandCheck(this, MessageEvent) +/***/ }), - return this.#eventInit.lastEventId - } +/***/ 888: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - get source () { - webidl.brandCheck(this, MessageEvent) +"use strict"; - return this.#eventInit.source + +const { UndiciError } = __nccwpck_require__(8045) + +class MockNotMatchedError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, MockNotMatchedError) + this.name = 'MockNotMatchedError' + this.message = message || 'The request does not match any registered mock dispatches' + this.code = 'UND_MOCK_ERR_MOCK_NOT_MATCHED' } +} - get ports () { - webidl.brandCheck(this, MessageEvent) +module.exports = { + MockNotMatchedError +} - if (!Object.isFrozen(this.#eventInit.ports)) { - Object.freeze(this.#eventInit.ports) - } - return this.#eventInit.ports - } +/***/ }), - initMessageEvent ( - type, - bubbles = false, - cancelable = false, - data = null, - origin = '', - lastEventId = '', - source = null, - ports = [] - ) { - webidl.brandCheck(this, MessageEvent) +/***/ 410: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - webidl.argumentLengthCheck(arguments, 1, { header: 'MessageEvent.initMessageEvent' }) +"use strict"; - return new MessageEvent(type, { - bubbles, cancelable, data, origin, lastEventId, source, ports - }) - } -} + +const { getResponseData, buildKey, addMockDispatch } = __nccwpck_require__(9323) +const { + kDispatches, + kDispatchKey, + kDefaultHeaders, + kDefaultTrailers, + kContentLength, + kMockDispatch +} = __nccwpck_require__(4347) +const { InvalidArgumentError } = __nccwpck_require__(8045) +const { buildURL } = __nccwpck_require__(3983) /** - * @see https://websockets.spec.whatwg.org/#the-closeevent-interface + * Defines the scope API for an interceptor reply */ -class CloseEvent extends Event { - #eventInit - - constructor (type, eventInitDict = {}) { - webidl.argumentLengthCheck(arguments, 1, { header: 'CloseEvent constructor' }) +class MockScope { + constructor (mockDispatch) { + this[kMockDispatch] = mockDispatch + } - type = webidl.converters.DOMString(type) - eventInitDict = webidl.converters.CloseEventInit(eventInitDict) + /** + * Delay a reply by a set amount in ms. + */ + delay (waitInMs) { + if (typeof waitInMs !== 'number' || !Number.isInteger(waitInMs) || waitInMs <= 0) { + throw new InvalidArgumentError('waitInMs must be a valid integer > 0') + } - super(type, eventInitDict) + this[kMockDispatch].delay = waitInMs + return this + } - this.#eventInit = eventInitDict + /** + * For a defined reply, never mark as consumed. + */ + persist () { + this[kMockDispatch].persist = true + return this } - get wasClean () { - webidl.brandCheck(this, CloseEvent) + /** + * Allow one to define a reply for a set amount of matching requests. + */ + times (repeatTimes) { + if (typeof repeatTimes !== 'number' || !Number.isInteger(repeatTimes) || repeatTimes <= 0) { + throw new InvalidArgumentError('repeatTimes must be a valid integer > 0') + } - return this.#eventInit.wasClean + this[kMockDispatch].times = repeatTimes + return this } +} - get code () { - webidl.brandCheck(this, CloseEvent) +/** + * Defines an interceptor for a Mock + */ +class MockInterceptor { + constructor (opts, mockDispatches) { + if (typeof opts !== 'object') { + throw new InvalidArgumentError('opts must be an object') + } + if (typeof opts.path === 'undefined') { + throw new InvalidArgumentError('opts.path must be defined') + } + if (typeof opts.method === 'undefined') { + opts.method = 'GET' + } + // See https://github.com/nodejs/undici/issues/1245 + // As per RFC 3986, clients are not supposed to send URI + // fragments to servers when they retrieve a document, + if (typeof opts.path === 'string') { + if (opts.query) { + opts.path = buildURL(opts.path, opts.query) + } else { + // Matches https://github.com/nodejs/undici/blob/main/lib/fetch/index.js#L1811 + const parsedURL = new URL(opts.path, 'data://') + opts.path = parsedURL.pathname + parsedURL.search + } + } + if (typeof opts.method === 'string') { + opts.method = opts.method.toUpperCase() + } - return this.#eventInit.code + this[kDispatchKey] = buildKey(opts) + this[kDispatches] = mockDispatches + this[kDefaultHeaders] = {} + this[kDefaultTrailers] = {} + this[kContentLength] = false } - get reason () { - webidl.brandCheck(this, CloseEvent) + createMockScopeDispatchData (statusCode, data, responseOptions = {}) { + const responseData = getResponseData(data) + const contentLength = this[kContentLength] ? { 'content-length': responseData.length } : {} + const headers = { ...this[kDefaultHeaders], ...contentLength, ...responseOptions.headers } + const trailers = { ...this[kDefaultTrailers], ...responseOptions.trailers } - return this.#eventInit.reason + return { statusCode, data, headers, trailers } } -} -// https://html.spec.whatwg.org/multipage/webappapis.html#the-errorevent-interface -class ErrorEvent extends Event { - #eventInit + validateReplyParameters (statusCode, data, responseOptions) { + if (typeof statusCode === 'undefined') { + throw new InvalidArgumentError('statusCode must be defined') + } + if (typeof data === 'undefined') { + throw new InvalidArgumentError('data must be defined') + } + if (typeof responseOptions !== 'object') { + throw new InvalidArgumentError('responseOptions must be an object') + } + } - constructor (type, eventInitDict) { - webidl.argumentLengthCheck(arguments, 1, { header: 'ErrorEvent constructor' }) + /** + * Mock an undici request with a defined reply. + */ + reply (replyData) { + // Values of reply aren't available right now as they + // can only be available when the reply callback is invoked. + if (typeof replyData === 'function') { + // We'll first wrap the provided callback in another function, + // this function will properly resolve the data from the callback + // when invoked. + const wrappedDefaultsCallback = (opts) => { + // Our reply options callback contains the parameter for statusCode, data and options. + const resolvedData = replyData(opts) - super(type, eventInitDict) + // Check if it is in the right format + if (typeof resolvedData !== 'object') { + throw new InvalidArgumentError('reply options callback must return an object') + } - type = webidl.converters.DOMString(type) - eventInitDict = webidl.converters.ErrorEventInit(eventInitDict ?? {}) + const { statusCode, data = '', responseOptions = {} } = resolvedData + this.validateReplyParameters(statusCode, data, responseOptions) + // Since the values can be obtained immediately we return them + // from this higher order function that will be resolved later. + return { + ...this.createMockScopeDispatchData(statusCode, data, responseOptions) + } + } - this.#eventInit = eventInitDict - } + // Add usual dispatch data, but this time set the data parameter to function that will eventually provide data. + const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], wrappedDefaultsCallback) + return new MockScope(newMockDispatch) + } - get message () { - webidl.brandCheck(this, ErrorEvent) + // We can have either one or three parameters, if we get here, + // we should have 1-3 parameters. So we spread the arguments of + // this function to obtain the parameters, since replyData will always + // just be the statusCode. + const [statusCode, data = '', responseOptions = {}] = [...arguments] + this.validateReplyParameters(statusCode, data, responseOptions) - return this.#eventInit.message + // Send in-already provided data like usual + const dispatchData = this.createMockScopeDispatchData(statusCode, data, responseOptions) + const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], dispatchData) + return new MockScope(newMockDispatch) } - get filename () { - webidl.brandCheck(this, ErrorEvent) + /** + * Mock an undici request with a defined error. + */ + replyWithError (error) { + if (typeof error === 'undefined') { + throw new InvalidArgumentError('error must be defined') + } - return this.#eventInit.filename + const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], { error }) + return new MockScope(newMockDispatch) } - get lineno () { - webidl.brandCheck(this, ErrorEvent) + /** + * Set default reply headers on the interceptor for subsequent replies + */ + defaultReplyHeaders (headers) { + if (typeof headers === 'undefined') { + throw new InvalidArgumentError('headers must be defined') + } - return this.#eventInit.lineno + this[kDefaultHeaders] = headers + return this } - get colno () { - webidl.brandCheck(this, ErrorEvent) + /** + * Set default reply trailers on the interceptor for subsequent replies + */ + defaultReplyTrailers (trailers) { + if (typeof trailers === 'undefined') { + throw new InvalidArgumentError('trailers must be defined') + } - return this.#eventInit.colno + this[kDefaultTrailers] = trailers + return this } - get error () { - webidl.brandCheck(this, ErrorEvent) - - return this.#eventInit.error + /** + * Set reply content length header for replies on the interceptor + */ + replyContentLength () { + this[kContentLength] = true + return this } } -Object.defineProperties(MessageEvent.prototype, { - [Symbol.toStringTag]: { - value: 'MessageEvent', - configurable: true - }, - data: kEnumerableProperty, - origin: kEnumerableProperty, - lastEventId: kEnumerableProperty, - source: kEnumerableProperty, - ports: kEnumerableProperty, - initMessageEvent: kEnumerableProperty -}) +module.exports.MockInterceptor = MockInterceptor +module.exports.MockScope = MockScope -Object.defineProperties(CloseEvent.prototype, { - [Symbol.toStringTag]: { - value: 'CloseEvent', - configurable: true - }, - reason: kEnumerableProperty, - code: kEnumerableProperty, - wasClean: kEnumerableProperty -}) -Object.defineProperties(ErrorEvent.prototype, { - [Symbol.toStringTag]: { - value: 'ErrorEvent', - configurable: true - }, - message: kEnumerableProperty, - filename: kEnumerableProperty, - lineno: kEnumerableProperty, - colno: kEnumerableProperty, - error: kEnumerableProperty -}) +/***/ }), -webidl.converters.MessagePort = webidl.interfaceConverter(MessagePort) +/***/ 6193: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -webidl.converters['sequence'] = webidl.sequenceConverter( - webidl.converters.MessagePort -) +"use strict"; -const eventInit = [ - { - key: 'bubbles', - converter: webidl.converters.boolean, - defaultValue: false - }, - { - key: 'cancelable', - converter: webidl.converters.boolean, - defaultValue: false - }, - { - key: 'composed', - converter: webidl.converters.boolean, - defaultValue: false - } -] -webidl.converters.MessageEventInit = webidl.dictionaryConverter([ - ...eventInit, - { - key: 'data', - converter: webidl.converters.any, - defaultValue: null - }, - { - key: 'origin', - converter: webidl.converters.USVString, - defaultValue: '' - }, - { - key: 'lastEventId', - converter: webidl.converters.DOMString, - defaultValue: '' - }, - { - key: 'source', - // Node doesn't implement WindowProxy or ServiceWorker, so the only - // valid value for source is a MessagePort. - converter: webidl.nullableConverter(webidl.converters.MessagePort), - defaultValue: null - }, - { - key: 'ports', - converter: webidl.converters['sequence'], - get defaultValue () { - return [] +const { promisify } = __nccwpck_require__(3837) +const Pool = __nccwpck_require__(4634) +const { buildMockDispatch } = __nccwpck_require__(9323) +const { + kDispatches, + kMockAgent, + kClose, + kOriginalClose, + kOrigin, + kOriginalDispatch, + kConnected +} = __nccwpck_require__(4347) +const { MockInterceptor } = __nccwpck_require__(410) +const Symbols = __nccwpck_require__(2785) +const { InvalidArgumentError } = __nccwpck_require__(8045) + +/** + * MockPool provides an API that extends the Pool to influence the mockDispatches. + */ +class MockPool extends Pool { + constructor (origin, opts) { + super(origin, opts) + + if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') { + throw new InvalidArgumentError('Argument opts.agent must implement Agent') } + + this[kMockAgent] = opts.agent + this[kOrigin] = origin + this[kDispatches] = [] + this[kConnected] = 1 + this[kOriginalDispatch] = this.dispatch + this[kOriginalClose] = this.close.bind(this) + + this.dispatch = buildMockDispatch.call(this) + this.close = this[kClose] } -]) -webidl.converters.CloseEventInit = webidl.dictionaryConverter([ - ...eventInit, - { - key: 'wasClean', - converter: webidl.converters.boolean, - defaultValue: false - }, - { - key: 'code', - converter: webidl.converters['unsigned short'], - defaultValue: 0 - }, - { - key: 'reason', - converter: webidl.converters.USVString, - defaultValue: '' + get [Symbols.kConnected] () { + return this[kConnected] } -]) -webidl.converters.ErrorEventInit = webidl.dictionaryConverter([ - ...eventInit, - { - key: 'message', - converter: webidl.converters.DOMString, - defaultValue: '' - }, - { - key: 'filename', - converter: webidl.converters.USVString, - defaultValue: '' - }, - { - key: 'lineno', - converter: webidl.converters['unsigned long'], - defaultValue: 0 - }, - { - key: 'colno', - converter: webidl.converters['unsigned long'], - defaultValue: 0 - }, - { - key: 'error', - converter: webidl.converters.any + /** + * Sets up the base interceptor for mocking replies from undici. + */ + intercept (opts) { + return new MockInterceptor(opts, this[kDispatches]) } -]) + + async [kClose] () { + await promisify(this[kOriginalClose])() + this[kConnected] = 0 + this[kMockAgent][Symbols.kClients].delete(this[kOrigin]) + } +} + +module.exports = MockPool + + +/***/ }), + +/***/ 4347: +/***/ ((module) => { + +"use strict"; + module.exports = { - MessageEvent, - CloseEvent, - ErrorEvent + kAgent: Symbol('agent'), + kOptions: Symbol('options'), + kFactory: Symbol('factory'), + kDispatches: Symbol('dispatches'), + kDispatchKey: Symbol('dispatch key'), + kDefaultHeaders: Symbol('default headers'), + kDefaultTrailers: Symbol('default trailers'), + kContentLength: Symbol('content length'), + kMockAgent: Symbol('mock agent'), + kMockAgentSet: Symbol('mock agent set'), + kMockAgentGet: Symbol('mock agent get'), + kMockDispatch: Symbol('mock dispatch'), + kClose: Symbol('close'), + kOriginalClose: Symbol('original agent close'), + kOrigin: Symbol('origin'), + kIsMockActive: Symbol('is mock active'), + kNetConnect: Symbol('net connect'), + kGetNetConnect: Symbol('get net connect'), + kConnected: Symbol('connected') } /***/ }), -/***/ 5444: +/***/ 9323: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { maxUnsigned16Bit } = __nccwpck_require__(9188) +const { MockNotMatchedError } = __nccwpck_require__(888) +const { + kDispatches, + kMockAgent, + kOriginalDispatch, + kOrigin, + kGetNetConnect +} = __nccwpck_require__(4347) +const { buildURL, nop } = __nccwpck_require__(3983) +const { STATUS_CODES } = __nccwpck_require__(3685) +const { + types: { + isPromise + } +} = __nccwpck_require__(3837) -/** @type {import('crypto')} */ -let crypto -try { - crypto = __nccwpck_require__(6113) -} catch { +function matchValue (match, value) { + if (typeof match === 'string') { + return match === value + } + if (match instanceof RegExp) { + return match.test(value) + } + if (typeof match === 'function') { + return match(value) === true + } + return false +} +function lowerCaseEntries (headers) { + return Object.fromEntries( + Object.entries(headers).map(([headerName, headerValue]) => { + return [headerName.toLocaleLowerCase(), headerValue] + }) + ) } -class WebsocketFrameSend { - /** - * @param {Buffer|undefined} data - */ - constructor (data) { - this.frameData = data - this.maskKey = crypto.randomBytes(4) +/** + * @param {import('../../index').Headers|string[]|Record} headers + * @param {string} key + */ +function getHeaderByName (headers, key) { + if (Array.isArray(headers)) { + for (let i = 0; i < headers.length; i += 2) { + if (headers[i].toLocaleLowerCase() === key.toLocaleLowerCase()) { + return headers[i + 1] + } + } + + return undefined + } else if (typeof headers.get === 'function') { + return headers.get(key) + } else { + return lowerCaseEntries(headers)[key.toLocaleLowerCase()] } +} - createFrame (opcode) { - const bodyLength = this.frameData?.byteLength ?? 0 +/** @param {string[]} headers */ +function buildHeadersFromArray (headers) { // fetch HeadersList + const clone = headers.slice() + const entries = [] + for (let index = 0; index < clone.length; index += 2) { + entries.push([clone[index], clone[index + 1]]) + } + return Object.fromEntries(entries) +} - /** @type {number} */ - let payloadLength = bodyLength // 0-125 - let offset = 6 +function matchHeaders (mockDispatch, headers) { + if (typeof mockDispatch.headers === 'function') { + if (Array.isArray(headers)) { // fetch HeadersList + headers = buildHeadersFromArray(headers) + } + return mockDispatch.headers(headers ? lowerCaseEntries(headers) : {}) + } + if (typeof mockDispatch.headers === 'undefined') { + return true + } + if (typeof headers !== 'object' || typeof mockDispatch.headers !== 'object') { + return false + } - if (bodyLength > maxUnsigned16Bit) { - offset += 8 // payload length is next 8 bytes - payloadLength = 127 - } else if (bodyLength > 125) { - offset += 2 // payload length is next 2 bytes - payloadLength = 126 + for (const [matchHeaderName, matchHeaderValue] of Object.entries(mockDispatch.headers)) { + const headerValue = getHeaderByName(headers, matchHeaderName) + + if (!matchValue(matchHeaderValue, headerValue)) { + return false } + } + return true +} - const buffer = Buffer.allocUnsafe(bodyLength + offset) +function safeUrl (path) { + if (typeof path !== 'string') { + return path + } - // Clear first 2 bytes, everything else is overwritten - buffer[0] = buffer[1] = 0 - buffer[0] |= 0x80 // FIN - buffer[0] = (buffer[0] & 0xF0) + opcode // opcode + const pathSegments = path.split('?') - /*! ws. MIT License. Einar Otto Stangvik */ - buffer[offset - 4] = this.maskKey[0] - buffer[offset - 3] = this.maskKey[1] - buffer[offset - 2] = this.maskKey[2] - buffer[offset - 1] = this.maskKey[3] + if (pathSegments.length !== 2) { + return path + } - buffer[1] = payloadLength + const qp = new URLSearchParams(pathSegments.pop()) + qp.sort() + return [...pathSegments, qp.toString()].join('?') +} - if (payloadLength === 126) { - buffer.writeUInt16BE(bodyLength, 2) - } else if (payloadLength === 127) { - // Clear extended payload length - buffer[2] = buffer[3] = 0 - buffer.writeUIntBE(bodyLength, 4, 6) - } +function matchKey (mockDispatch, { path, method, body, headers }) { + const pathMatch = matchValue(mockDispatch.path, path) + const methodMatch = matchValue(mockDispatch.method, method) + const bodyMatch = typeof mockDispatch.body !== 'undefined' ? matchValue(mockDispatch.body, body) : true + const headersMatch = matchHeaders(mockDispatch, headers) + return pathMatch && methodMatch && bodyMatch && headersMatch +} - buffer[1] |= 0x80 // MASK +function getResponseData (data) { + if (Buffer.isBuffer(data)) { + return data + } else if (typeof data === 'object') { + return JSON.stringify(data) + } else { + return data.toString() + } +} - // mask body - for (let i = 0; i < bodyLength; i++) { - buffer[offset + i] = this.frameData[i] ^ this.maskKey[i % 4] - } +function getMockDispatch (mockDispatches, key) { + const basePath = key.query ? buildURL(key.path, key.query) : key.path + const resolvedPath = typeof basePath === 'string' ? safeUrl(basePath) : basePath - return buffer + // Match path + let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path }) => matchValue(safeUrl(path), resolvedPath)) + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`) + } + + // Match method + matchedMockDispatches = matchedMockDispatches.filter(({ method }) => matchValue(method, key.method)) + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError(`Mock dispatch not matched for method '${key.method}'`) + } + + // Match body + matchedMockDispatches = matchedMockDispatches.filter(({ body }) => typeof body !== 'undefined' ? matchValue(body, key.body) : true) + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError(`Mock dispatch not matched for body '${key.body}'`) + } + + // Match headers + matchedMockDispatches = matchedMockDispatches.filter((mockDispatch) => matchHeaders(mockDispatch, key.headers)) + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError(`Mock dispatch not matched for headers '${typeof key.headers === 'object' ? JSON.stringify(key.headers) : key.headers}'`) } -} -module.exports = { - WebsocketFrameSend + return matchedMockDispatches[0] } +function addMockDispatch (mockDispatches, key, data) { + const baseData = { timesInvoked: 0, times: 1, persist: false, consumed: false } + const replyData = typeof data === 'function' ? { callback: data } : { ...data } + const newMockDispatch = { ...baseData, ...key, pending: true, data: { error: null, ...replyData } } + mockDispatches.push(newMockDispatch) + return newMockDispatch +} -/***/ }), - -/***/ 1688: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function deleteMockDispatch (mockDispatches, key) { + const index = mockDispatches.findIndex(dispatch => { + if (!dispatch.consumed) { + return false + } + return matchKey(dispatch, key) + }) + if (index !== -1) { + mockDispatches.splice(index, 1) + } +} -"use strict"; +function buildKey (opts) { + const { path, method, body, headers, query } = opts + return { + path, + method, + body, + headers, + query + } +} +function generateKeyValues (data) { + return Object.entries(data).reduce((keyValuePairs, [key, value]) => [ + ...keyValuePairs, + Buffer.from(`${key}`), + Array.isArray(value) ? value.map(x => Buffer.from(`${x}`)) : Buffer.from(`${value}`) + ], []) +} -const { Writable } = __nccwpck_require__(2781) -const diagnosticsChannel = __nccwpck_require__(7643) -const { parserStates, opcodes, states, emptyBuffer } = __nccwpck_require__(9188) -const { kReadyState, kSentClose, kResponse, kReceivedClose } = __nccwpck_require__(7578) -const { isValidStatusCode, failWebsocketConnection, websocketMessageReceived } = __nccwpck_require__(5515) -const { WebsocketFrameSend } = __nccwpck_require__(5444) +/** + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status + * @param {number} statusCode + */ +function getStatusText (statusCode) { + return STATUS_CODES[statusCode] || 'unknown' +} -// This code was influenced by ws released under the MIT license. -// Copyright (c) 2011 Einar Otto Stangvik -// Copyright (c) 2013 Arnout Kazemier and contributors -// Copyright (c) 2016 Luigi Pinca and contributors +async function getResponse (body) { + const buffers = [] + for await (const data of body) { + buffers.push(data) + } + return Buffer.concat(buffers).toString('utf8') +} -const channels = {} -channels.ping = diagnosticsChannel.channel('undici:websocket:ping') -channels.pong = diagnosticsChannel.channel('undici:websocket:pong') +/** + * Mock dispatch function used to simulate undici dispatches + */ +function mockDispatch (opts, handler) { + // Get mock dispatch from built key + const key = buildKey(opts) + const mockDispatch = getMockDispatch(this[kDispatches], key) -class ByteParser extends Writable { - #buffers = [] - #byteOffset = 0 + mockDispatch.timesInvoked++ - #state = parserStates.INFO + // Here's where we resolve a callback if a callback is present for the dispatch data. + if (mockDispatch.data.callback) { + mockDispatch.data = { ...mockDispatch.data, ...mockDispatch.data.callback(opts) } + } - #info = {} - #fragments = [] + // Parse mockDispatch data + const { data: { statusCode, data, headers, trailers, error }, delay, persist } = mockDispatch + const { timesInvoked, times } = mockDispatch - constructor (ws) { - super() + // If it's used up and not persistent, mark as consumed + mockDispatch.consumed = !persist && timesInvoked >= times + mockDispatch.pending = timesInvoked < times - this.ws = ws + // If specified, trigger dispatch error + if (error !== null) { + deleteMockDispatch(this[kDispatches], key) + handler.onError(error) + return true } - /** - * @param {Buffer} chunk - * @param {() => void} callback - */ - _write (chunk, _, callback) { - this.#buffers.push(chunk) - this.#byteOffset += chunk.length - - this.run(callback) + // Handle the request with a delay if necessary + if (typeof delay === 'number' && delay > 0) { + setTimeout(() => { + handleReply(this[kDispatches]) + }, delay) + } else { + handleReply(this[kDispatches]) } - /** - * Runs whenever a new chunk is received. - * Callback is called whenever there are no more chunks buffering, - * or not enough bytes are buffered to parse. - */ - run (callback) { - while (true) { - if (this.#state === parserStates.INFO) { - // If there aren't enough bytes to parse the payload length, etc. - if (this.#byteOffset < 2) { - return callback() - } - - const buffer = this.consume(2) + function handleReply (mockDispatches, _data = data) { + // fetch's HeadersList is a 1D string array + const optsHeaders = Array.isArray(opts.headers) + ? buildHeadersFromArray(opts.headers) + : opts.headers + const body = typeof _data === 'function' + ? _data({ ...opts, headers: optsHeaders }) + : _data - this.#info.fin = (buffer[0] & 0x80) !== 0 - this.#info.opcode = buffer[0] & 0x0F + // util.types.isPromise is likely needed for jest. + if (isPromise(body)) { + // If handleReply is asynchronous, throwing an error + // in the callback will reject the promise, rather than + // synchronously throw the error, which breaks some tests. + // Rather, we wait for the callback to resolve if it is a + // promise, and then re-run handleReply with the new body. + body.then((newData) => handleReply(mockDispatches, newData)) + return + } - // If we receive a fragmented message, we use the type of the first - // frame to parse the full message as binary/text, when it's terminated - this.#info.originalOpcode ??= this.#info.opcode + const responseData = getResponseData(body) + const responseHeaders = generateKeyValues(headers) + const responseTrailers = generateKeyValues(trailers) - this.#info.fragmented = !this.#info.fin && this.#info.opcode !== opcodes.CONTINUATION + handler.abort = nop + handler.onHeaders(statusCode, responseHeaders, resume, getStatusText(statusCode)) + handler.onData(Buffer.from(responseData)) + handler.onComplete(responseTrailers) + deleteMockDispatch(mockDispatches, key) + } - if (this.#info.fragmented && this.#info.opcode !== opcodes.BINARY && this.#info.opcode !== opcodes.TEXT) { - // Only text and binary frames can be fragmented - failWebsocketConnection(this.ws, 'Invalid frame type was fragmented.') - return - } + function resume () {} - const payloadLength = buffer[1] & 0x7F + return true +} - if (payloadLength <= 125) { - this.#info.payloadLength = payloadLength - this.#state = parserStates.READ_DATA - } else if (payloadLength === 126) { - this.#state = parserStates.PAYLOADLENGTH_16 - } else if (payloadLength === 127) { - this.#state = parserStates.PAYLOADLENGTH_64 - } +function buildMockDispatch () { + const agent = this[kMockAgent] + const origin = this[kOrigin] + const originalDispatch = this[kOriginalDispatch] - if (this.#info.fragmented && payloadLength > 125) { - // A fragmented frame can't be fragmented itself - failWebsocketConnection(this.ws, 'Fragmented frame exceeded 125 bytes.') - return - } else if ( - (this.#info.opcode === opcodes.PING || - this.#info.opcode === opcodes.PONG || - this.#info.opcode === opcodes.CLOSE) && - payloadLength > 125 - ) { - // Control frames can have a payload length of 125 bytes MAX - failWebsocketConnection(this.ws, 'Payload length for control frame exceeded 125 bytes.') - return - } else if (this.#info.opcode === opcodes.CLOSE) { - if (payloadLength === 1) { - failWebsocketConnection(this.ws, 'Received close frame with a 1-byte body.') - return + return function dispatch (opts, handler) { + if (agent.isMockActive) { + try { + mockDispatch.call(this, opts, handler) + } catch (error) { + if (error instanceof MockNotMatchedError) { + const netConnect = agent[kGetNetConnect]() + if (netConnect === false) { + throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect disabled)`) } - - const body = this.consume(payloadLength) - - this.#info.closeInfo = this.parseCloseBody(false, body) - - if (!this.ws[kSentClose]) { - // If an endpoint receives a Close frame and did not previously send a - // Close frame, the endpoint MUST send a Close frame in response. (When - // sending a Close frame in response, the endpoint typically echos the - // status code it received.) - const body = Buffer.allocUnsafe(2) - body.writeUInt16BE(this.#info.closeInfo.code, 0) - const closeFrame = new WebsocketFrameSend(body) - - this.ws[kResponse].socket.write( - closeFrame.createFrame(opcodes.CLOSE), - (err) => { - if (!err) { - this.ws[kSentClose] = true - } - } - ) + if (checkNetConnect(netConnect, origin)) { + originalDispatch.call(this, opts, handler) + } else { + throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect is not enabled for this origin)`) } + } else { + throw error + } + } + } else { + originalDispatch.call(this, opts, handler) + } + } +} - // Upon either sending or receiving a Close control frame, it is said - // that _The WebSocket Closing Handshake is Started_ and that the - // WebSocket connection is in the CLOSING state. - this.ws[kReadyState] = states.CLOSING - this.ws[kReceivedClose] = true +function checkNetConnect (netConnect, origin) { + const url = new URL(origin) + if (netConnect === true) { + return true + } else if (Array.isArray(netConnect) && netConnect.some((matcher) => matchValue(matcher, url.host))) { + return true + } + return false +} - this.end() +function buildMockOptions (opts) { + if (opts) { + const { agent, ...mockOptions } = opts + return mockOptions + } +} - return - } else if (this.#info.opcode === opcodes.PING) { - // Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in - // response, unless it already received a Close frame. - // A Pong frame sent in response to a Ping frame must have identical - // "Application data" +module.exports = { + getResponseData, + getMockDispatch, + addMockDispatch, + deleteMockDispatch, + buildKey, + generateKeyValues, + matchValue, + getResponse, + getStatusText, + mockDispatch, + buildMockDispatch, + checkNetConnect, + buildMockOptions, + getHeaderByName +} - const body = this.consume(payloadLength) - if (!this.ws[kReceivedClose]) { - const frame = new WebsocketFrameSend(body) +/***/ }), - this.ws[kResponse].socket.write(frame.createFrame(opcodes.PONG)) +/***/ 6823: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (channels.ping.hasSubscribers) { - channels.ping.publish({ - payload: body - }) - } - } +"use strict"; - this.#state = parserStates.INFO - if (this.#byteOffset > 0) { - continue - } else { - callback() - return - } - } else if (this.#info.opcode === opcodes.PONG) { - // A Pong frame MAY be sent unsolicited. This serves as a - // unidirectional heartbeat. A response to an unsolicited Pong frame is - // not expected. +const { Transform } = __nccwpck_require__(2781) +const { Console } = __nccwpck_require__(6206) - const body = this.consume(payloadLength) +/** + * Gets the output of `console.table(…)` as a string. + */ +module.exports = class PendingInterceptorsFormatter { + constructor ({ disableColors } = {}) { + this.transform = new Transform({ + transform (chunk, _enc, cb) { + cb(null, chunk) + } + }) - if (channels.pong.hasSubscribers) { - channels.pong.publish({ - payload: body - }) - } + this.logger = new Console({ + stdout: this.transform, + inspectOptions: { + colors: !disableColors && !process.env.CI + } + }) + } - if (this.#byteOffset > 0) { - continue - } else { - callback() - return - } - } - } else if (this.#state === parserStates.PAYLOADLENGTH_16) { - if (this.#byteOffset < 2) { - return callback() - } + format (pendingInterceptors) { + const withPrettyHeaders = pendingInterceptors.map( + ({ method, path, data: { statusCode }, persist, times, timesInvoked, origin }) => ({ + Method: method, + Origin: origin, + Path: path, + 'Status code': statusCode, + Persistent: persist ? '✅' : '❌', + Invocations: timesInvoked, + Remaining: persist ? Infinity : times - timesInvoked + })) - const buffer = this.consume(2) + this.logger.table(withPrettyHeaders) + return this.transform.read().toString() + } +} - this.#info.payloadLength = buffer.readUInt16BE(0) - this.#state = parserStates.READ_DATA - } else if (this.#state === parserStates.PAYLOADLENGTH_64) { - if (this.#byteOffset < 8) { - return callback() - } - const buffer = this.consume(8) - const upper = buffer.readUInt32BE(0) +/***/ }), - // 2^31 is the maxinimum bytes an arraybuffer can contain - // on 32-bit systems. Although, on 64-bit systems, this is - // 2^53-1 bytes. - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_array_length - // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/common/globals.h;drc=1946212ac0100668f14eb9e2843bdd846e510a1e;bpv=1;bpt=1;l=1275 - // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/objects/js-array-buffer.h;l=34;drc=1946212ac0100668f14eb9e2843bdd846e510a1e - if (upper > 2 ** 31 - 1) { - failWebsocketConnection(this.ws, 'Received payload length > 2^31 bytes.') - return - } +/***/ 8891: +/***/ ((module) => { - const lower = buffer.readUInt32BE(4) +"use strict"; - this.#info.payloadLength = (upper << 8) + lower - this.#state = parserStates.READ_DATA - } else if (this.#state === parserStates.READ_DATA) { - if (this.#byteOffset < this.#info.payloadLength) { - // If there is still more data in this chunk that needs to be read - return callback() - } else if (this.#byteOffset >= this.#info.payloadLength) { - // If the server sent multiple frames in a single chunk - const body = this.consume(this.#info.payloadLength) +const singulars = { + pronoun: 'it', + is: 'is', + was: 'was', + this: 'this' +} - this.#fragments.push(body) +const plurals = { + pronoun: 'they', + is: 'are', + was: 'were', + this: 'these' +} - // If the frame is unfragmented, or a fragmented frame was terminated, - // a message was received - if (!this.#info.fragmented || (this.#info.fin && this.#info.opcode === opcodes.CONTINUATION)) { - const fullMessage = Buffer.concat(this.#fragments) +module.exports = class Pluralizer { + constructor (singular, plural) { + this.singular = singular + this.plural = plural + } - websocketMessageReceived(this.ws, this.#info.originalOpcode, fullMessage) + pluralize (count) { + const one = count === 1 + const keys = one ? singulars : plurals + const noun = one ? this.singular : this.plural + return { ...keys, count, noun } + } +} - this.#info = {} - this.#fragments.length = 0 - } - this.#state = parserStates.INFO - } - } +/***/ }), - if (this.#byteOffset > 0) { - continue - } else { - callback() - break - } - } - } +/***/ 8266: +/***/ ((module) => { - /** - * Take n bytes from the buffered Buffers - * @param {number} n - * @returns {Buffer|null} - */ - consume (n) { - if (n > this.#byteOffset) { - return null - } else if (n === 0) { - return emptyBuffer - } +"use strict"; +/* eslint-disable */ - if (this.#buffers[0].length === n) { - this.#byteOffset -= this.#buffers[0].length - return this.#buffers.shift() - } - const buffer = Buffer.allocUnsafe(n) - let offset = 0 - while (offset !== n) { - const next = this.#buffers[0] - const { length } = next +// Extracted from node/lib/internal/fixed_queue.js - if (length + offset === n) { - buffer.set(this.#buffers.shift(), offset) - break - } else if (length + offset > n) { - buffer.set(next.subarray(0, n - offset), offset) - this.#buffers[0] = next.subarray(n - offset) - break - } else { - buffer.set(this.#buffers.shift(), offset) - offset += next.length - } - } +// Currently optimal queue size, tested on V8 6.0 - 6.6. Must be power of two. +const kSize = 2048; +const kMask = kSize - 1; - this.#byteOffset -= n +// The FixedQueue is implemented as a singly-linked list of fixed-size +// circular buffers. It looks something like this: +// +// head tail +// | | +// v v +// +-----------+ <-----\ +-----------+ <------\ +-----------+ +// | [null] | \----- | next | \------- | next | +// +-----------+ +-----------+ +-----------+ +// | item | <-- bottom | item | <-- bottom | [empty] | +// | item | | item | | [empty] | +// | item | | item | | [empty] | +// | item | | item | | [empty] | +// | item | | item | bottom --> | item | +// | item | | item | | item | +// | ... | | ... | | ... | +// | item | | item | | item | +// | item | | item | | item | +// | [empty] | <-- top | item | | item | +// | [empty] | | item | | item | +// | [empty] | | [empty] | <-- top top --> | [empty] | +// +-----------+ +-----------+ +-----------+ +// +// Or, if there is only one circular buffer, it looks something +// like either of these: +// +// head tail head tail +// | | | | +// v v v v +// +-----------+ +-----------+ +// | [null] | | [null] | +// +-----------+ +-----------+ +// | [empty] | | item | +// | [empty] | | item | +// | item | <-- bottom top --> | [empty] | +// | item | | [empty] | +// | [empty] | <-- top bottom --> | item | +// | [empty] | | item | +// +-----------+ +-----------+ +// +// Adding a value means moving `top` forward by one, removing means +// moving `bottom` forward by one. After reaching the end, the queue +// wraps around. +// +// When `top === bottom` the current queue is empty and when +// `top + 1 === bottom` it's full. This wastes a single space of storage +// but allows much quicker checks. - return buffer +class FixedCircularBuffer { + constructor() { + this.bottom = 0; + this.top = 0; + this.list = new Array(kSize); + this.next = null; } - parseCloseBody (onlyCode, data) { - // https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5 - /** @type {number|undefined} */ - let code - - if (data.length >= 2) { - // _The WebSocket Connection Close Code_ is - // defined as the status code (Section 7.4) contained in the first Close - // control frame received by the application - code = data.readUInt16BE(0) - } + isEmpty() { + return this.top === this.bottom; + } - if (onlyCode) { - if (!isValidStatusCode(code)) { - return null - } + isFull() { + return ((this.top + 1) & kMask) === this.bottom; + } - return { code } - } + push(data) { + this.list[this.top] = data; + this.top = (this.top + 1) & kMask; + } - // https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6 - /** @type {Buffer} */ - let reason = data.subarray(2) + shift() { + const nextItem = this.list[this.bottom]; + if (nextItem === undefined) + return null; + this.list[this.bottom] = undefined; + this.bottom = (this.bottom + 1) & kMask; + return nextItem; + } +} - // Remove BOM - if (reason[0] === 0xEF && reason[1] === 0xBB && reason[2] === 0xBF) { - reason = reason.subarray(3) - } +module.exports = class FixedQueue { + constructor() { + this.head = this.tail = new FixedCircularBuffer(); + } - if (code !== undefined && !isValidStatusCode(code)) { - return null - } + isEmpty() { + return this.head.isEmpty(); + } - try { - // TODO: optimize this - reason = new TextDecoder('utf-8', { fatal: true }).decode(reason) - } catch { - return null + push(data) { + if (this.head.isFull()) { + // Head is full: Creates a new queue, sets the old queue's `.next` to it, + // and sets it as the new main queue. + this.head = this.head.next = new FixedCircularBuffer(); } - - return { code, reason } + this.head.push(data); } - get closingInfo () { - return this.#info.closeInfo + shift() { + const tail = this.tail; + const next = tail.shift(); + if (tail.isEmpty() && tail.next !== null) { + // If there is another queue, it forms the new tail. + this.tail = tail.next; + } + return next; } -} - -module.exports = { - ByteParser -} +}; /***/ }), -/***/ 7578: -/***/ ((module) => { +/***/ 3198: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -module.exports = { - kWebSocketURL: Symbol('url'), - kReadyState: Symbol('ready state'), - kController: Symbol('controller'), - kResponse: Symbol('response'), - kBinaryType: Symbol('binary type'), - kSentClose: Symbol('sent close'), - kReceivedClose: Symbol('received close'), - kByteParser: Symbol('byte parser') -} +const DispatcherBase = __nccwpck_require__(4839) +const FixedQueue = __nccwpck_require__(8266) +const { kConnected, kSize, kRunning, kPending, kQueued, kBusy, kFree, kUrl, kClose, kDestroy, kDispatch } = __nccwpck_require__(2785) +const PoolStats = __nccwpck_require__(9689) +const kClients = Symbol('clients') +const kNeedDrain = Symbol('needDrain') +const kQueue = Symbol('queue') +const kClosedResolve = Symbol('closed resolve') +const kOnDrain = Symbol('onDrain') +const kOnConnect = Symbol('onConnect') +const kOnDisconnect = Symbol('onDisconnect') +const kOnConnectionError = Symbol('onConnectionError') +const kGetDispatcher = Symbol('get dispatcher') +const kAddClient = Symbol('add client') +const kRemoveClient = Symbol('remove client') +const kStats = Symbol('stats') -/***/ }), +class PoolBase extends DispatcherBase { + constructor () { + super() -/***/ 5515: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this[kQueue] = new FixedQueue() + this[kClients] = [] + this[kQueued] = 0 -"use strict"; + const pool = this + this[kOnDrain] = function onDrain (origin, targets) { + const queue = pool[kQueue] -const { kReadyState, kController, kResponse, kBinaryType, kWebSocketURL } = __nccwpck_require__(7578) -const { states, opcodes } = __nccwpck_require__(9188) -const { MessageEvent, ErrorEvent } = __nccwpck_require__(2611) + let needDrain = false -/* globals Blob */ + while (!needDrain) { + const item = queue.shift() + if (!item) { + break + } + pool[kQueued]-- + needDrain = !this.dispatch(item.opts, item.handler) + } -/** - * @param {import('./websocket').WebSocket} ws - */ -function isEstablished (ws) { - // If the server's response is validated as provided for above, it is - // said that _The WebSocket Connection is Established_ and that the - // WebSocket Connection is in the OPEN state. - return ws[kReadyState] === states.OPEN -} + this[kNeedDrain] = needDrain -/** - * @param {import('./websocket').WebSocket} ws - */ -function isClosing (ws) { - // Upon either sending or receiving a Close control frame, it is said - // that _The WebSocket Closing Handshake is Started_ and that the - // WebSocket connection is in the CLOSING state. - return ws[kReadyState] === states.CLOSING -} + if (!this[kNeedDrain] && pool[kNeedDrain]) { + pool[kNeedDrain] = false + pool.emit('drain', origin, [pool, ...targets]) + } -/** - * @param {import('./websocket').WebSocket} ws - */ -function isClosed (ws) { - return ws[kReadyState] === states.CLOSED -} + if (pool[kClosedResolve] && queue.isEmpty()) { + Promise + .all(pool[kClients].map(c => c.close())) + .then(pool[kClosedResolve]) + } + } -/** - * @see https://dom.spec.whatwg.org/#concept-event-fire - * @param {string} e - * @param {EventTarget} target - * @param {EventInit | undefined} eventInitDict - */ -function fireEvent (e, target, eventConstructor = Event, eventInitDict) { - // 1. If eventConstructor is not given, then let eventConstructor be Event. + this[kOnConnect] = (origin, targets) => { + pool.emit('connect', origin, [pool, ...targets]) + } - // 2. Let event be the result of creating an event given eventConstructor, - // in the relevant realm of target. - // 3. Initialize event’s type attribute to e. - const event = new eventConstructor(e, eventInitDict) // eslint-disable-line new-cap + this[kOnDisconnect] = (origin, targets, err) => { + pool.emit('disconnect', origin, [pool, ...targets], err) + } - // 4. Initialize any other IDL attributes of event as described in the - // invocation of this algorithm. + this[kOnConnectionError] = (origin, targets, err) => { + pool.emit('connectionError', origin, [pool, ...targets], err) + } - // 5. Return the result of dispatching event at target, with legacy target - // override flag set if set. - target.dispatchEvent(event) -} + this[kStats] = new PoolStats(this) + } -/** - * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol - * @param {import('./websocket').WebSocket} ws - * @param {number} type Opcode - * @param {Buffer} data application data - */ -function websocketMessageReceived (ws, type, data) { - // 1. If ready state is not OPEN (1), then return. - if (ws[kReadyState] !== states.OPEN) { - return + get [kBusy] () { + return this[kNeedDrain] + } + + get [kConnected] () { + return this[kClients].filter(client => client[kConnected]).length + } + + get [kFree] () { + return this[kClients].filter(client => client[kConnected] && !client[kNeedDrain]).length + } + + get [kPending] () { + let ret = this[kQueued] + for (const { [kPending]: pending } of this[kClients]) { + ret += pending + } + return ret } - // 2. Let dataForEvent be determined by switching on type and binary type: - let dataForEvent + get [kRunning] () { + let ret = 0 + for (const { [kRunning]: running } of this[kClients]) { + ret += running + } + return ret + } - if (type === opcodes.TEXT) { - // -> type indicates that the data is Text - // a new DOMString containing data - try { - dataForEvent = new TextDecoder('utf-8', { fatal: true }).decode(data) - } catch { - failWebsocketConnection(ws, 'Received invalid UTF-8 in text frame.') - return + get [kSize] () { + let ret = this[kQueued] + for (const { [kSize]: size } of this[kClients]) { + ret += size } - } else if (type === opcodes.BINARY) { - if (ws[kBinaryType] === 'blob') { - // -> type indicates that the data is Binary and binary type is "blob" - // a new Blob object, created in the relevant Realm of the WebSocket - // object, that represents data as its raw data - dataForEvent = new Blob([data]) + return ret + } + + get stats () { + return this[kStats] + } + + async [kClose] () { + if (this[kQueue].isEmpty()) { + return Promise.all(this[kClients].map(c => c.close())) } else { - // -> type indicates that the data is Binary and binary type is "arraybuffer" - // a new ArrayBuffer object, created in the relevant Realm of the - // WebSocket object, whose contents are data - dataForEvent = new Uint8Array(data).buffer + return new Promise((resolve) => { + this[kClosedResolve] = resolve + }) } } - // 3. Fire an event named message at the WebSocket object, using MessageEvent, - // with the origin attribute initialized to the serialization of the WebSocket - // object’s url's origin, and the data attribute initialized to dataForEvent. - fireEvent('message', ws, MessageEvent, { - origin: ws[kWebSocketURL].origin, - data: dataForEvent - }) -} + async [kDestroy] (err) { + while (true) { + const item = this[kQueue].shift() + if (!item) { + break + } + item.handler.onError(err) + } -/** - * @see https://datatracker.ietf.org/doc/html/rfc6455 - * @see https://datatracker.ietf.org/doc/html/rfc2616 - * @see https://bugs.chromium.org/p/chromium/issues/detail?id=398407 - * @param {string} protocol - */ -function isValidSubprotocol (protocol) { - // If present, this value indicates one - // or more comma-separated subprotocol the client wishes to speak, - // ordered by preference. The elements that comprise this value - // MUST be non-empty strings with characters in the range U+0021 to - // U+007E not including separator characters as defined in - // [RFC2616] and MUST all be unique strings. - if (protocol.length === 0) { - return false + return Promise.all(this[kClients].map(c => c.destroy(err))) } - for (const char of protocol) { - const code = char.charCodeAt(0) + [kDispatch] (opts, handler) { + const dispatcher = this[kGetDispatcher]() - if ( - code < 0x21 || - code > 0x7E || - char === '(' || - char === ')' || - char === '<' || - char === '>' || - char === '@' || - char === ',' || - char === ';' || - char === ':' || - char === '\\' || - char === '"' || - char === '/' || - char === '[' || - char === ']' || - char === '?' || - char === '=' || - char === '{' || - char === '}' || - code === 32 || // SP - code === 9 // HT - ) { - return false + if (!dispatcher) { + this[kNeedDrain] = true + this[kQueue].push({ opts, handler }) + this[kQueued]++ + } else if (!dispatcher.dispatch(opts, handler)) { + dispatcher[kNeedDrain] = true + this[kNeedDrain] = !this[kGetDispatcher]() } - } - - return true -} -/** - * @see https://datatracker.ietf.org/doc/html/rfc6455#section-7-4 - * @param {number} code - */ -function isValidStatusCode (code) { - if (code >= 1000 && code < 1015) { - return ( - code !== 1004 && // reserved - code !== 1005 && // "MUST NOT be set as a status code" - code !== 1006 // "MUST NOT be set as a status code" - ) + return !this[kNeedDrain] } - return code >= 3000 && code <= 4999 -} + [kAddClient] (client) { + client + .on('drain', this[kOnDrain]) + .on('connect', this[kOnConnect]) + .on('disconnect', this[kOnDisconnect]) + .on('connectionError', this[kOnConnectionError]) -/** - * @param {import('./websocket').WebSocket} ws - * @param {string|undefined} reason - */ -function failWebsocketConnection (ws, reason) { - const { [kController]: controller, [kResponse]: response } = ws + this[kClients].push(client) - controller.abort() + if (this[kNeedDrain]) { + process.nextTick(() => { + if (this[kNeedDrain]) { + this[kOnDrain](client[kUrl], [this, client]) + } + }) + } - if (response?.socket && !response.socket.destroyed) { - response.socket.destroy() + return this } - if (reason) { - fireEvent('error', ws, ErrorEvent, { - error: new Error(reason) + [kRemoveClient] (client) { + client.close(() => { + const idx = this[kClients].indexOf(client) + if (idx !== -1) { + this[kClients].splice(idx, 1) + } }) + + this[kNeedDrain] = this[kClients].some(dispatcher => ( + !dispatcher[kNeedDrain] && + dispatcher.closed !== true && + dispatcher.destroyed !== true + )) } } module.exports = { - isEstablished, - isClosing, - isClosed, - fireEvent, - isValidSubprotocol, - isValidStatusCode, - failWebsocketConnection, - websocketMessageReceived + PoolBase, + kClients, + kNeedDrain, + kAddClient, + kRemoveClient, + kGetDispatcher } /***/ }), -/***/ 4284: +/***/ 9689: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -"use strict"; +const { kFree, kConnected, kPending, kQueued, kRunning, kSize } = __nccwpck_require__(2785) +const kPool = Symbol('pool') + +class PoolStats { + constructor (pool) { + this[kPool] = pool + } + get connected () { + return this[kPool][kConnected] + } -const { webidl } = __nccwpck_require__(1744) -const { DOMException } = __nccwpck_require__(1037) -const { URLSerializer } = __nccwpck_require__(685) -const { getGlobalOrigin } = __nccwpck_require__(1246) -const { staticPropertyDescriptors, states, opcodes, emptyBuffer } = __nccwpck_require__(9188) -const { - kWebSocketURL, - kReadyState, - kController, - kBinaryType, - kResponse, - kSentClose, - kByteParser -} = __nccwpck_require__(7578) -const { isEstablished, isClosing, isValidSubprotocol, failWebsocketConnection, fireEvent } = __nccwpck_require__(5515) -const { establishWebSocketConnection } = __nccwpck_require__(5354) -const { WebsocketFrameSend } = __nccwpck_require__(5444) -const { ByteParser } = __nccwpck_require__(1688) -const { kEnumerableProperty, isBlobLike } = __nccwpck_require__(3983) -const { getGlobalDispatcher } = __nccwpck_require__(1892) -const { types } = __nccwpck_require__(3837) + get free () { + return this[kPool][kFree] + } -let experimentalWarned = false + get pending () { + return this[kPool][kPending] + } -// https://websockets.spec.whatwg.org/#interface-definition -class WebSocket extends EventTarget { - #events = { - open: null, - error: null, - close: null, - message: null + get queued () { + return this[kPool][kQueued] } - #bufferedAmount = 0 - #protocol = '' - #extensions = '' + get running () { + return this[kPool][kRunning] + } - /** - * @param {string} url - * @param {string|string[]} protocols - */ - constructor (url, protocols = []) { - super() + get size () { + return this[kPool][kSize] + } +} + +module.exports = PoolStats + + +/***/ }), - webidl.argumentLengthCheck(arguments, 1, { header: 'WebSocket constructor' }) +/***/ 4634: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (!experimentalWarned) { - experimentalWarned = true - process.emitWarning('WebSockets are experimental, expect them to change at any time.', { - code: 'UNDICI-WS' - }) - } +"use strict"; - const options = webidl.converters['DOMString or sequence or WebSocketInit'](protocols) - url = webidl.converters.USVString(url) - protocols = options.protocols +const { + PoolBase, + kClients, + kNeedDrain, + kAddClient, + kGetDispatcher +} = __nccwpck_require__(3198) +const Client = __nccwpck_require__(3598) +const { + InvalidArgumentError +} = __nccwpck_require__(8045) +const util = __nccwpck_require__(3983) +const { kUrl, kInterceptors } = __nccwpck_require__(2785) +const buildConnector = __nccwpck_require__(2067) - // 1. Let baseURL be this's relevant settings object's API base URL. - const baseURL = getGlobalOrigin() +const kOptions = Symbol('options') +const kConnections = Symbol('connections') +const kFactory = Symbol('factory') - // 1. Let urlRecord be the result of applying the URL parser to url with baseURL. - let urlRecord +function defaultFactory (origin, opts) { + return new Client(origin, opts) +} - try { - urlRecord = new URL(url, baseURL) - } catch (e) { - // 3. If urlRecord is failure, then throw a "SyntaxError" DOMException. - throw new DOMException(e, 'SyntaxError') - } +class Pool extends PoolBase { + constructor (origin, { + connections, + factory = defaultFactory, + connect, + connectTimeout, + tls, + maxCachedSessions, + socketPath, + autoSelectFamily, + autoSelectFamilyAttemptTimeout, + allowH2, + ...options + } = {}) { + super() - // 4. If urlRecord’s scheme is "http", then set urlRecord’s scheme to "ws". - if (urlRecord.protocol === 'http:') { - urlRecord.protocol = 'ws:' - } else if (urlRecord.protocol === 'https:') { - // 5. Otherwise, if urlRecord’s scheme is "https", set urlRecord’s scheme to "wss". - urlRecord.protocol = 'wss:' + if (connections != null && (!Number.isFinite(connections) || connections < 0)) { + throw new InvalidArgumentError('invalid connections') } - // 6. If urlRecord’s scheme is not "ws" or "wss", then throw a "SyntaxError" DOMException. - if (urlRecord.protocol !== 'ws:' && urlRecord.protocol !== 'wss:') { - throw new DOMException( - `Expected a ws: or wss: protocol, got ${urlRecord.protocol}`, - 'SyntaxError' - ) + if (typeof factory !== 'function') { + throw new InvalidArgumentError('factory must be a function.') } - // 7. If urlRecord’s fragment is non-null, then throw a "SyntaxError" - // DOMException. - if (urlRecord.hash || urlRecord.href.endsWith('#')) { - throw new DOMException('Got fragment', 'SyntaxError') + if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { + throw new InvalidArgumentError('connect must be a function or an object') } - // 8. If protocols is a string, set protocols to a sequence consisting - // of just that string. - if (typeof protocols === 'string') { - protocols = [protocols] + if (typeof connect !== 'function') { + connect = buildConnector({ + ...tls, + maxCachedSessions, + allowH2, + socketPath, + timeout: connectTimeout, + ...(util.nodeHasAutoSelectFamily && autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), + ...connect + }) } - // 9. If any of the values in protocols occur more than once or otherwise - // fail to match the requirements for elements that comprise the value - // of `Sec-WebSocket-Protocol` fields as defined by The WebSocket - // protocol, then throw a "SyntaxError" DOMException. - if (protocols.length !== new Set(protocols.map(p => p.toLowerCase())).size) { - throw new DOMException('Invalid Sec-WebSocket-Protocol value', 'SyntaxError') + this[kInterceptors] = options.interceptors && options.interceptors.Pool && Array.isArray(options.interceptors.Pool) + ? options.interceptors.Pool + : [] + this[kConnections] = connections || null + this[kUrl] = util.parseOrigin(origin) + this[kOptions] = { ...util.deepClone(options), connect, allowH2 } + this[kOptions].interceptors = options.interceptors + ? { ...options.interceptors } + : undefined + this[kFactory] = factory + } + + [kGetDispatcher] () { + let dispatcher = this[kClients].find(dispatcher => !dispatcher[kNeedDrain]) + + if (dispatcher) { + return dispatcher } - if (protocols.length > 0 && !protocols.every(p => isValidSubprotocol(p))) { - throw new DOMException('Invalid Sec-WebSocket-Protocol value', 'SyntaxError') + if (!this[kConnections] || this[kClients].length < this[kConnections]) { + dispatcher = this[kFactory](this[kUrl], this[kOptions]) + this[kAddClient](dispatcher) } - // 10. Set this's url to urlRecord. - this[kWebSocketURL] = new URL(urlRecord.href) + return dispatcher + } +} - // 11. Let client be this's relevant settings object. +module.exports = Pool - // 12. Run this step in parallel: - // 1. Establish a WebSocket connection given urlRecord, protocols, - // and client. - this[kController] = establishWebSocketConnection( - urlRecord, - protocols, - this, - (response) => this.#onConnectionEstablished(response), - options - ) +/***/ }), - // Each WebSocket object has an associated ready state, which is a - // number representing the state of the connection. Initially it must - // be CONNECTING (0). - this[kReadyState] = WebSocket.CONNECTING +/***/ 7858: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // The extensions attribute must initially return the empty string. +"use strict"; - // The protocol attribute must initially return the empty string. - // Each WebSocket object has an associated binary type, which is a - // BinaryType. Initially it must be "blob". - this[kBinaryType] = 'blob' - } +const { kProxy, kClose, kDestroy, kInterceptors } = __nccwpck_require__(2785) +const { URL } = __nccwpck_require__(7310) +const Agent = __nccwpck_require__(7890) +const Pool = __nccwpck_require__(4634) +const DispatcherBase = __nccwpck_require__(4839) +const { InvalidArgumentError, RequestAbortedError } = __nccwpck_require__(8045) +const buildConnector = __nccwpck_require__(2067) - /** - * @see https://websockets.spec.whatwg.org/#dom-websocket-close - * @param {number|undefined} code - * @param {string|undefined} reason - */ - close (code = undefined, reason = undefined) { - webidl.brandCheck(this, WebSocket) +const kAgent = Symbol('proxy agent') +const kClient = Symbol('proxy client') +const kProxyHeaders = Symbol('proxy headers') +const kRequestTls = Symbol('request tls settings') +const kProxyTls = Symbol('proxy tls settings') +const kConnectEndpoint = Symbol('connect endpoint function') - if (code !== undefined) { - code = webidl.converters['unsigned short'](code, { clamp: true }) - } +function defaultProtocolPort (protocol) { + return protocol === 'https:' ? 443 : 80 +} - if (reason !== undefined) { - reason = webidl.converters.USVString(reason) - } +function buildProxyOptions (opts) { + if (typeof opts === 'string') { + opts = { uri: opts } + } - // 1. If code is present, but is neither an integer equal to 1000 nor an - // integer in the range 3000 to 4999, inclusive, throw an - // "InvalidAccessError" DOMException. - if (code !== undefined) { - if (code !== 1000 && (code < 3000 || code > 4999)) { - throw new DOMException('invalid code', 'InvalidAccessError') - } - } + if (!opts || !opts.uri) { + throw new InvalidArgumentError('Proxy opts.uri is mandatory') + } - let reasonByteLength = 0 + return { + uri: opts.uri, + protocol: opts.protocol || 'https' + } +} - // 2. If reason is present, then run these substeps: - if (reason !== undefined) { - // 1. Let reasonBytes be the result of encoding reason. - // 2. If reasonBytes is longer than 123 bytes, then throw a - // "SyntaxError" DOMException. - reasonByteLength = Buffer.byteLength(reason) +function defaultFactory (origin, opts) { + return new Pool(origin, opts) +} - if (reasonByteLength > 123) { - throw new DOMException( - `Reason must be less than 123 bytes; received ${reasonByteLength}`, - 'SyntaxError' - ) - } +class ProxyAgent extends DispatcherBase { + constructor (opts) { + super(opts) + this[kProxy] = buildProxyOptions(opts) + this[kAgent] = new Agent(opts) + this[kInterceptors] = opts.interceptors && opts.interceptors.ProxyAgent && Array.isArray(opts.interceptors.ProxyAgent) + ? opts.interceptors.ProxyAgent + : [] + + if (typeof opts === 'string') { + opts = { uri: opts } } - // 3. Run the first matching steps from the following list: - if (this[kReadyState] === WebSocket.CLOSING || this[kReadyState] === WebSocket.CLOSED) { - // If this's ready state is CLOSING (2) or CLOSED (3) - // Do nothing. - } else if (!isEstablished(this)) { - // If the WebSocket connection is not yet established - // Fail the WebSocket connection and set this's ready state - // to CLOSING (2). - failWebsocketConnection(this, 'Connection was closed before it was established.') - this[kReadyState] = WebSocket.CLOSING - } else if (!isClosing(this)) { - // If the WebSocket closing handshake has not yet been started - // Start the WebSocket closing handshake and set this's ready - // state to CLOSING (2). - // - If neither code nor reason is present, the WebSocket Close - // message must not have a body. - // - If code is present, then the status code to use in the - // WebSocket Close message must be the integer given by code. - // - If reason is also present, then reasonBytes must be - // provided in the Close message after the status code. + if (!opts || !opts.uri) { + throw new InvalidArgumentError('Proxy opts.uri is mandatory') + } - const frame = new WebsocketFrameSend() + const { clientFactory = defaultFactory } = opts + + if (typeof clientFactory !== 'function') { + throw new InvalidArgumentError('Proxy opts.clientFactory must be a function.') + } - // If neither code nor reason is present, the WebSocket Close - // message must not have a body. + this[kRequestTls] = opts.requestTls + this[kProxyTls] = opts.proxyTls + this[kProxyHeaders] = opts.headers || {} - // If code is present, then the status code to use in the - // WebSocket Close message must be the integer given by code. - if (code !== undefined && reason === undefined) { - frame.frameData = Buffer.allocUnsafe(2) - frame.frameData.writeUInt16BE(code, 0) - } else if (code !== undefined && reason !== undefined) { - // If reason is also present, then reasonBytes must be - // provided in the Close message after the status code. - frame.frameData = Buffer.allocUnsafe(2 + reasonByteLength) - frame.frameData.writeUInt16BE(code, 0) - // the body MAY contain UTF-8-encoded data with value /reason/ - frame.frameData.write(reason, 2, 'utf-8') - } else { - frame.frameData = emptyBuffer - } + const resolvedUrl = new URL(opts.uri) + const { origin, port, host, username, password } = resolvedUrl - /** @type {import('stream').Duplex} */ - const socket = this[kResponse].socket + if (opts.auth && opts.token) { + throw new InvalidArgumentError('opts.auth cannot be used in combination with opts.token') + } else if (opts.auth) { + /* @deprecated in favour of opts.token */ + this[kProxyHeaders]['proxy-authorization'] = `Basic ${opts.auth}` + } else if (opts.token) { + this[kProxyHeaders]['proxy-authorization'] = opts.token + } else if (username && password) { + this[kProxyHeaders]['proxy-authorization'] = `Basic ${Buffer.from(`${decodeURIComponent(username)}:${decodeURIComponent(password)}`).toString('base64')}` + } - socket.write(frame.createFrame(opcodes.CLOSE), (err) => { - if (!err) { - this[kSentClose] = true + const connect = buildConnector({ ...opts.proxyTls }) + this[kConnectEndpoint] = buildConnector({ ...opts.requestTls }) + this[kClient] = clientFactory(resolvedUrl, { connect }) + this[kAgent] = new Agent({ + ...opts, + connect: async (opts, callback) => { + let requestedHost = opts.host + if (!opts.port) { + requestedHost += `:${defaultProtocolPort(opts.protocol)}` } - }) + try { + const { socket, statusCode } = await this[kClient].connect({ + origin, + port, + path: requestedHost, + signal: opts.signal, + headers: { + ...this[kProxyHeaders], + host + } + }) + if (statusCode !== 200) { + socket.on('error', () => {}).destroy() + callback(new RequestAbortedError(`Proxy response (${statusCode}) !== 200 when HTTP Tunneling`)) + } + if (opts.protocol !== 'https:') { + callback(null, socket) + return + } + let servername + if (this[kRequestTls]) { + servername = this[kRequestTls].servername + } else { + servername = opts.servername + } + this[kConnectEndpoint]({ ...opts, servername, httpSocket: socket }, callback) + } catch (err) { + callback(err) + } + } + }) + } - // Upon either sending or receiving a Close control frame, it is said - // that _The WebSocket Closing Handshake is Started_ and that the - // WebSocket connection is in the CLOSING state. - this[kReadyState] = states.CLOSING - } else { - // Otherwise - // Set this's ready state to CLOSING (2). - this[kReadyState] = WebSocket.CLOSING - } + dispatch (opts, handler) { + const { host } = new URL(opts.origin) + const headers = buildHeaders(opts.headers) + throwIfProxyAuthIsSent(headers) + return this[kAgent].dispatch( + { + ...opts, + headers: { + ...headers, + host + } + }, + handler + ) } - /** - * @see https://websockets.spec.whatwg.org/#dom-websocket-send - * @param {NodeJS.TypedArray|ArrayBuffer|Blob|string} data - */ - send (data) { - webidl.brandCheck(this, WebSocket) + async [kClose] () { + await this[kAgent].close() + await this[kClient].close() + } - webidl.argumentLengthCheck(arguments, 1, { header: 'WebSocket.send' }) + async [kDestroy] () { + await this[kAgent].destroy() + await this[kClient].destroy() + } +} - data = webidl.converters.WebSocketSendData(data) +/** + * @param {string[] | Record} headers + * @returns {Record} + */ +function buildHeaders (headers) { + // When using undici.fetch, the headers list is stored + // as an array. + if (Array.isArray(headers)) { + /** @type {Record} */ + const headersPair = {} - // 1. If this's ready state is CONNECTING, then throw an - // "InvalidStateError" DOMException. - if (this[kReadyState] === WebSocket.CONNECTING) { - throw new DOMException('Sent before connected.', 'InvalidStateError') + for (let i = 0; i < headers.length; i += 2) { + headersPair[headers[i]] = headers[i + 1] } - // 2. Run the appropriate set of steps from the following list: - // https://datatracker.ietf.org/doc/html/rfc6455#section-6.1 - // https://datatracker.ietf.org/doc/html/rfc6455#section-5.2 + return headersPair + } - if (!isEstablished(this) || isClosing(this)) { - return - } + return headers +} - /** @type {import('stream').Duplex} */ - const socket = this[kResponse].socket +/** + * @param {Record} headers + * + * Previous versions of ProxyAgent suggests the Proxy-Authorization in request headers + * Nevertheless, it was changed and to avoid a security vulnerability by end users + * this check was created. + * It should be removed in the next major version for performance reasons + */ +function throwIfProxyAuthIsSent (headers) { + const existProxyAuth = headers && Object.keys(headers) + .find((key) => key.toLowerCase() === 'proxy-authorization') + if (existProxyAuth) { + throw new InvalidArgumentError('Proxy-Authorization should be sent in ProxyAgent constructor') + } +} - // If data is a string - if (typeof data === 'string') { - // If the WebSocket connection is established and the WebSocket - // closing handshake has not yet started, then the user agent - // must send a WebSocket Message comprised of the data argument - // using a text frame opcode; if the data cannot be sent, e.g. - // because it would need to be buffered but the buffer is full, - // the user agent must flag the WebSocket as full and then close - // the WebSocket connection. Any invocation of this method with a - // string argument that does not throw an exception must increase - // the bufferedAmount attribute by the number of bytes needed to - // express the argument as UTF-8. +module.exports = ProxyAgent - const value = Buffer.from(data) - const frame = new WebsocketFrameSend(value) - const buffer = frame.createFrame(opcodes.TEXT) - this.#bufferedAmount += value.byteLength - socket.write(buffer, () => { - this.#bufferedAmount -= value.byteLength - }) - } else if (types.isArrayBuffer(data)) { - // If the WebSocket connection is established, and the WebSocket - // closing handshake has not yet started, then the user agent must - // send a WebSocket Message comprised of data using a binary frame - // opcode; if the data cannot be sent, e.g. because it would need - // to be buffered but the buffer is full, the user agent must flag - // the WebSocket as full and then close the WebSocket connection. - // The data to be sent is the data stored in the buffer described - // by the ArrayBuffer object. Any invocation of this method with an - // ArrayBuffer argument that does not throw an exception must - // increase the bufferedAmount attribute by the length of the - // ArrayBuffer in bytes. +/***/ }), - const value = Buffer.from(data) - const frame = new WebsocketFrameSend(value) - const buffer = frame.createFrame(opcodes.BINARY) +/***/ 9459: +/***/ ((module) => { - this.#bufferedAmount += value.byteLength - socket.write(buffer, () => { - this.#bufferedAmount -= value.byteLength - }) - } else if (ArrayBuffer.isView(data)) { - // If the WebSocket connection is established, and the WebSocket - // closing handshake has not yet started, then the user agent must - // send a WebSocket Message comprised of data using a binary frame - // opcode; if the data cannot be sent, e.g. because it would need to - // be buffered but the buffer is full, the user agent must flag the - // WebSocket as full and then close the WebSocket connection. The - // data to be sent is the data stored in the section of the buffer - // described by the ArrayBuffer object that data references. Any - // invocation of this method with this kind of argument that does - // not throw an exception must increase the bufferedAmount attribute - // by the length of data’s buffer in bytes. +"use strict"; - const ab = Buffer.from(data, data.byteOffset, data.byteLength) - const frame = new WebsocketFrameSend(ab) - const buffer = frame.createFrame(opcodes.BINARY) +let fastNow = Date.now() +let fastNowTimeout - this.#bufferedAmount += ab.byteLength - socket.write(buffer, () => { - this.#bufferedAmount -= ab.byteLength - }) - } else if (isBlobLike(data)) { - // If the WebSocket connection is established, and the WebSocket - // closing handshake has not yet started, then the user agent must - // send a WebSocket Message comprised of data using a binary frame - // opcode; if the data cannot be sent, e.g. because it would need to - // be buffered but the buffer is full, the user agent must flag the - // WebSocket as full and then close the WebSocket connection. The data - // to be sent is the raw data represented by the Blob object. Any - // invocation of this method with a Blob argument that does not throw - // an exception must increase the bufferedAmount attribute by the size - // of the Blob object’s raw data, in bytes. +const fastTimers = [] - const frame = new WebsocketFrameSend() +function onTimeout () { + fastNow = Date.now() - data.arrayBuffer().then((ab) => { - const value = Buffer.from(ab) - frame.frameData = value - const buffer = frame.createFrame(opcodes.BINARY) + let len = fastTimers.length + let idx = 0 + while (idx < len) { + const timer = fastTimers[idx] + + if (timer.state === 0) { + timer.state = fastNow + timer.delay + } else if (timer.state > 0 && fastNow >= timer.state) { + timer.state = -1 + timer.callback(timer.opaque) + } - this.#bufferedAmount += value.byteLength - socket.write(buffer, () => { - this.#bufferedAmount -= value.byteLength - }) - }) + if (timer.state === -1) { + timer.state = -2 + if (idx !== len - 1) { + fastTimers[idx] = fastTimers.pop() + } else { + fastTimers.pop() + } + len -= 1 + } else { + idx += 1 } } - get readyState () { - webidl.brandCheck(this, WebSocket) + if (fastTimers.length > 0) { + refreshTimeout() + } +} - // The readyState getter steps are to return this's ready state. - return this[kReadyState] +function refreshTimeout () { + if (fastNowTimeout && fastNowTimeout.refresh) { + fastNowTimeout.refresh() + } else { + clearTimeout(fastNowTimeout) + fastNowTimeout = setTimeout(onTimeout, 1e3) + if (fastNowTimeout.unref) { + fastNowTimeout.unref() + } } +} - get bufferedAmount () { - webidl.brandCheck(this, WebSocket) +class Timeout { + constructor (callback, delay, opaque) { + this.callback = callback + this.delay = delay + this.opaque = opaque - return this.#bufferedAmount + // -2 not in timer list + // -1 in timer list but inactive + // 0 in timer list waiting for time + // > 0 in timer list waiting for time to expire + this.state = -2 + + this.refresh() } - get url () { - webidl.brandCheck(this, WebSocket) + refresh () { + if (this.state === -2) { + fastTimers.push(this) + if (!fastNowTimeout || fastTimers.length === 1) { + refreshTimeout() + } + } - // The url getter steps are to return this's url, serialized. - return URLSerializer(this[kWebSocketURL]) + this.state = 0 } - get extensions () { - webidl.brandCheck(this, WebSocket) + clear () { + this.state = -1 + } +} - return this.#extensions +module.exports = { + setTimeout (callback, delay, opaque) { + return delay < 1e3 + ? setTimeout(callback, delay, opaque) + : new Timeout(callback, delay, opaque) + }, + clearTimeout (timeout) { + if (timeout instanceof Timeout) { + timeout.clear() + } else { + clearTimeout(timeout) + } } +} - get protocol () { - webidl.brandCheck(this, WebSocket) - return this.#protocol - } +/***/ }), - get onopen () { - webidl.brandCheck(this, WebSocket) +/***/ 5354: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - return this.#events.open - } +"use strict"; - set onopen (fn) { - webidl.brandCheck(this, WebSocket) - if (this.#events.open) { - this.removeEventListener('open', this.#events.open) - } +const diagnosticsChannel = __nccwpck_require__(7643) +const { uid, states } = __nccwpck_require__(9188) +const { + kReadyState, + kSentClose, + kByteParser, + kReceivedClose +} = __nccwpck_require__(7578) +const { fireEvent, failWebsocketConnection } = __nccwpck_require__(5515) +const { CloseEvent } = __nccwpck_require__(2611) +const { makeRequest } = __nccwpck_require__(8359) +const { fetching } = __nccwpck_require__(4881) +const { Headers } = __nccwpck_require__(554) +const { getGlobalDispatcher } = __nccwpck_require__(1892) +const { kHeadersList } = __nccwpck_require__(2785) - if (typeof fn === 'function') { - this.#events.open = fn - this.addEventListener('open', fn) - } else { - this.#events.open = null - } - } +const channels = {} +channels.open = diagnosticsChannel.channel('undici:websocket:open') +channels.close = diagnosticsChannel.channel('undici:websocket:close') +channels.socketError = diagnosticsChannel.channel('undici:websocket:socket_error') - get onerror () { - webidl.brandCheck(this, WebSocket) +/** @type {import('crypto')} */ +let crypto +try { + crypto = __nccwpck_require__(6113) +} catch { - return this.#events.error - } +} - set onerror (fn) { - webidl.brandCheck(this, WebSocket) +/** + * @see https://websockets.spec.whatwg.org/#concept-websocket-establish + * @param {URL} url + * @param {string|string[]} protocols + * @param {import('./websocket').WebSocket} ws + * @param {(response: any) => void} onEstablish + * @param {Partial} options + */ +function establishWebSocketConnection (url, protocols, ws, onEstablish, options) { + // 1. Let requestURL be a copy of url, with its scheme set to "http", if url’s + // scheme is "ws", and to "https" otherwise. + const requestURL = url - if (this.#events.error) { - this.removeEventListener('error', this.#events.error) - } + requestURL.protocol = url.protocol === 'ws:' ? 'http:' : 'https:' - if (typeof fn === 'function') { - this.#events.error = fn - this.addEventListener('error', fn) - } else { - this.#events.error = null - } - } + // 2. Let request be a new request, whose URL is requestURL, client is client, + // service-workers mode is "none", referrer is "no-referrer", mode is + // "websocket", credentials mode is "include", cache mode is "no-store" , + // and redirect mode is "error". + const request = makeRequest({ + urlList: [requestURL], + serviceWorkers: 'none', + referrer: 'no-referrer', + mode: 'websocket', + credentials: 'include', + cache: 'no-store', + redirect: 'error' + }) - get onclose () { - webidl.brandCheck(this, WebSocket) + // Note: undici extension, allow setting custom headers. + if (options.headers) { + const headersList = new Headers(options.headers)[kHeadersList] - return this.#events.close + request.headersList = headersList } - set onclose (fn) { - webidl.brandCheck(this, WebSocket) + // 3. Append (`Upgrade`, `websocket`) to request’s header list. + // 4. Append (`Connection`, `Upgrade`) to request’s header list. + // Note: both of these are handled by undici currently. + // https://github.com/nodejs/undici/blob/68c269c4144c446f3f1220951338daef4a6b5ec4/lib/client.js#L1397 - if (this.#events.close) { - this.removeEventListener('close', this.#events.close) - } + // 5. Let keyValue be a nonce consisting of a randomly selected + // 16-byte value that has been forgiving-base64-encoded and + // isomorphic encoded. + const keyValue = crypto.randomBytes(16).toString('base64') - if (typeof fn === 'function') { - this.#events.close = fn - this.addEventListener('close', fn) - } else { - this.#events.close = null - } - } + // 6. Append (`Sec-WebSocket-Key`, keyValue) to request’s + // header list. + request.headersList.append('sec-websocket-key', keyValue) - get onmessage () { - webidl.brandCheck(this, WebSocket) + // 7. Append (`Sec-WebSocket-Version`, `13`) to request’s + // header list. + request.headersList.append('sec-websocket-version', '13') - return this.#events.message + // 8. For each protocol in protocols, combine + // (`Sec-WebSocket-Protocol`, protocol) in request’s header + // list. + for (const protocol of protocols) { + request.headersList.append('sec-websocket-protocol', protocol) } - set onmessage (fn) { - webidl.brandCheck(this, WebSocket) + // 9. Let permessageDeflate be a user-agent defined + // "permessage-deflate" extension header value. + // https://github.com/mozilla/gecko-dev/blob/ce78234f5e653a5d3916813ff990f053510227bc/netwerk/protocol/websocket/WebSocketChannel.cpp#L2673 + // TODO: enable once permessage-deflate is supported + const permessageDeflate = '' // 'permessage-deflate; 15' - if (this.#events.message) { - this.removeEventListener('message', this.#events.message) - } + // 10. Append (`Sec-WebSocket-Extensions`, permessageDeflate) to + // request’s header list. + // request.headersList.append('sec-websocket-extensions', permessageDeflate) - if (typeof fn === 'function') { - this.#events.message = fn - this.addEventListener('message', fn) - } else { - this.#events.message = null - } - } + // 11. Fetch request with useParallelQueue set to true, and + // processResponse given response being these steps: + const controller = fetching({ + request, + useParallelQueue: true, + dispatcher: options.dispatcher ?? getGlobalDispatcher(), + processResponse (response) { + // 1. If response is a network error or its status is not 101, + // fail the WebSocket connection. + if (response.type === 'error' || response.status !== 101) { + failWebsocketConnection(ws, 'Received network error or non-101 status code.') + return + } - get binaryType () { - webidl.brandCheck(this, WebSocket) + // 2. If protocols is not the empty list and extracting header + // list values given `Sec-WebSocket-Protocol` and response’s + // header list results in null, failure, or the empty byte + // sequence, then fail the WebSocket connection. + if (protocols.length !== 0 && !response.headersList.get('Sec-WebSocket-Protocol')) { + failWebsocketConnection(ws, 'Server did not respond with sent protocols.') + return + } - return this[kBinaryType] - } + // 3. Follow the requirements stated step 2 to step 6, inclusive, + // of the last set of steps in section 4.1 of The WebSocket + // Protocol to validate response. This either results in fail + // the WebSocket connection or the WebSocket connection is + // established. - set binaryType (type) { - webidl.brandCheck(this, WebSocket) + // 2. If the response lacks an |Upgrade| header field or the |Upgrade| + // header field contains a value that is not an ASCII case- + // insensitive match for the value "websocket", the client MUST + // _Fail the WebSocket Connection_. + if (response.headersList.get('Upgrade')?.toLowerCase() !== 'websocket') { + failWebsocketConnection(ws, 'Server did not set Upgrade header to "websocket".') + return + } - if (type !== 'blob' && type !== 'arraybuffer') { - this[kBinaryType] = 'blob' - } else { - this[kBinaryType] = type - } - } + // 3. If the response lacks a |Connection| header field or the + // |Connection| header field doesn't contain a token that is an + // ASCII case-insensitive match for the value "Upgrade", the client + // MUST _Fail the WebSocket Connection_. + if (response.headersList.get('Connection')?.toLowerCase() !== 'upgrade') { + failWebsocketConnection(ws, 'Server did not set Connection header to "upgrade".') + return + } - /** - * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol - */ - #onConnectionEstablished (response) { - // processResponse is called when the "response’s header list has been received and initialized." - // once this happens, the connection is open - this[kResponse] = response + // 4. If the response lacks a |Sec-WebSocket-Accept| header field or + // the |Sec-WebSocket-Accept| contains a value other than the + // base64-encoded SHA-1 of the concatenation of the |Sec-WebSocket- + // Key| (as a string, not base64-decoded) with the string "258EAFA5- + // E914-47DA-95CA-C5AB0DC85B11" but ignoring any leading and + // trailing whitespace, the client MUST _Fail the WebSocket + // Connection_. + const secWSAccept = response.headersList.get('Sec-WebSocket-Accept') + const digest = crypto.createHash('sha1').update(keyValue + uid).digest('base64') + if (secWSAccept !== digest) { + failWebsocketConnection(ws, 'Incorrect hash received in Sec-WebSocket-Accept header.') + return + } - const parser = new ByteParser(this) - parser.on('drain', function onParserDrain () { - this.ws[kResponse].socket.resume() - }) + // 5. If the response includes a |Sec-WebSocket-Extensions| header + // field and this header field indicates the use of an extension + // that was not present in the client's handshake (the server has + // indicated an extension not requested by the client), the client + // MUST _Fail the WebSocket Connection_. (The parsing of this + // header field to determine which extensions are requested is + // discussed in Section 9.1.) + const secExtension = response.headersList.get('Sec-WebSocket-Extensions') - response.socket.ws = this - this[kByteParser] = parser + if (secExtension !== null && secExtension !== permessageDeflate) { + failWebsocketConnection(ws, 'Received different permessage-deflate than the one set.') + return + } - // 1. Change the ready state to OPEN (1). - this[kReadyState] = states.OPEN + // 6. If the response includes a |Sec-WebSocket-Protocol| header field + // and this header field indicates the use of a subprotocol that was + // not present in the client's handshake (the server has indicated a + // subprotocol not requested by the client), the client MUST _Fail + // the WebSocket Connection_. + const secProtocol = response.headersList.get('Sec-WebSocket-Protocol') - // 2. Change the extensions attribute’s value to the extensions in use, if - // it is not the null value. - // https://datatracker.ietf.org/doc/html/rfc6455#section-9.1 - const extensions = response.headersList.get('sec-websocket-extensions') + if (secProtocol !== null && secProtocol !== request.headersList.get('Sec-WebSocket-Protocol')) { + failWebsocketConnection(ws, 'Protocol was not set in the opening handshake.') + return + } - if (extensions !== null) { - this.#extensions = extensions - } + response.socket.on('data', onSocketData) + response.socket.on('close', onSocketClose) + response.socket.on('error', onSocketError) - // 3. Change the protocol attribute’s value to the subprotocol in use, if - // it is not the null value. - // https://datatracker.ietf.org/doc/html/rfc6455#section-1.9 - const protocol = response.headersList.get('sec-websocket-protocol') + if (channels.open.hasSubscribers) { + channels.open.publish({ + address: response.socket.address(), + protocol: secProtocol, + extensions: secExtension + }) + } - if (protocol !== null) { - this.#protocol = protocol + onEstablish(response) } + }) - // 4. Fire an event named open at the WebSocket object. - fireEvent('open', this) + return controller +} + +/** + * @param {Buffer} chunk + */ +function onSocketData (chunk) { + if (!this.ws[kByteParser].write(chunk)) { + this.pause() } } -// https://websockets.spec.whatwg.org/#dom-websocket-connecting -WebSocket.CONNECTING = WebSocket.prototype.CONNECTING = states.CONNECTING -// https://websockets.spec.whatwg.org/#dom-websocket-open -WebSocket.OPEN = WebSocket.prototype.OPEN = states.OPEN -// https://websockets.spec.whatwg.org/#dom-websocket-closing -WebSocket.CLOSING = WebSocket.prototype.CLOSING = states.CLOSING -// https://websockets.spec.whatwg.org/#dom-websocket-closed -WebSocket.CLOSED = WebSocket.prototype.CLOSED = states.CLOSED +/** + * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol + * @see https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4 + */ +function onSocketClose () { + const { ws } = this -Object.defineProperties(WebSocket.prototype, { - CONNECTING: staticPropertyDescriptors, - OPEN: staticPropertyDescriptors, - CLOSING: staticPropertyDescriptors, - CLOSED: staticPropertyDescriptors, - url: kEnumerableProperty, - readyState: kEnumerableProperty, - bufferedAmount: kEnumerableProperty, - onopen: kEnumerableProperty, - onerror: kEnumerableProperty, - onclose: kEnumerableProperty, - close: kEnumerableProperty, - onmessage: kEnumerableProperty, - binaryType: kEnumerableProperty, - send: kEnumerableProperty, - extensions: kEnumerableProperty, - protocol: kEnumerableProperty, - [Symbol.toStringTag]: { - value: 'WebSocket', - writable: false, - enumerable: false, - configurable: true - } -}) + // If the TCP connection was closed after the + // WebSocket closing handshake was completed, the WebSocket connection + // is said to have been closed _cleanly_. + const wasClean = ws[kSentClose] && ws[kReceivedClose] -Object.defineProperties(WebSocket, { - CONNECTING: staticPropertyDescriptors, - OPEN: staticPropertyDescriptors, - CLOSING: staticPropertyDescriptors, - CLOSED: staticPropertyDescriptors -}) + let code = 1005 + let reason = '' -webidl.converters['sequence'] = webidl.sequenceConverter( - webidl.converters.DOMString -) + const result = ws[kByteParser].closingInfo -webidl.converters['DOMString or sequence'] = function (V) { - if (webidl.util.Type(V) === 'Object' && Symbol.iterator in V) { - return webidl.converters['sequence'](V) + if (result) { + code = result.code ?? 1005 + reason = result.reason + } else if (!ws[kSentClose]) { + // If _The WebSocket + // Connection is Closed_ and no Close control frame was received by the + // endpoint (such as could occur if the underlying transport connection + // is lost), _The WebSocket Connection Close Code_ is considered to be + // 1006. + code = 1006 } - return webidl.converters.DOMString(V) -} + // 1. Change the ready state to CLOSED (3). + ws[kReadyState] = states.CLOSED -// This implements the propsal made in https://github.com/whatwg/websockets/issues/42 -webidl.converters.WebSocketInit = webidl.dictionaryConverter([ - { - key: 'protocols', - converter: webidl.converters['DOMString or sequence'], - get defaultValue () { - return [] - } - }, - { - key: 'dispatcher', - converter: (V) => V, - get defaultValue () { - return getGlobalDispatcher() - } - }, - { - key: 'headers', - converter: webidl.nullableConverter(webidl.converters.HeadersInit) - } -]) + // 2. If the user agent was required to fail the WebSocket + // connection, or if the WebSocket connection was closed + // after being flagged as full, fire an event named error + // at the WebSocket object. + // TODO -webidl.converters['DOMString or sequence or WebSocketInit'] = function (V) { - if (webidl.util.Type(V) === 'Object' && !(Symbol.iterator in V)) { - return webidl.converters.WebSocketInit(V) - } + // 3. Fire an event named close at the WebSocket object, + // using CloseEvent, with the wasClean attribute + // initialized to true if the connection closed cleanly + // and false otherwise, the code attribute initialized to + // the WebSocket connection close code, and the reason + // attribute initialized to the result of applying UTF-8 + // decode without BOM to the WebSocket connection close + // reason. + fireEvent('close', ws, CloseEvent, { + wasClean, code, reason + }) - return { protocols: webidl.converters['DOMString or sequence'](V) } + if (channels.close.hasSubscribers) { + channels.close.publish({ + websocket: ws, + code, + reason + }) + } } -webidl.converters.WebSocketSendData = function (V) { - if (webidl.util.Type(V) === 'Object') { - if (isBlobLike(V)) { - return webidl.converters.Blob(V, { strict: false }) - } +function onSocketError (error) { + const { ws } = this - if (ArrayBuffer.isView(V) || types.isAnyArrayBuffer(V)) { - return webidl.converters.BufferSource(V) - } + ws[kReadyState] = states.CLOSING + + if (channels.socketError.hasSubscribers) { + channels.socketError.publish(error) } - return webidl.converters.USVString(V) + this.destroy() } module.exports = { - WebSocket + establishWebSocketConnection } /***/ }), -/***/ 5840: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 9188: +/***/ ((module) => { "use strict"; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -Object.defineProperty(exports, "v1", ({ - enumerable: true, - get: function () { - return _v.default; - } -})); -Object.defineProperty(exports, "v3", ({ - enumerable: true, - get: function () { - return _v2.default; - } -})); -Object.defineProperty(exports, "v4", ({ - enumerable: true, - get: function () { - return _v3.default; - } -})); -Object.defineProperty(exports, "v5", ({ - enumerable: true, - get: function () { - return _v4.default; - } -})); -Object.defineProperty(exports, "NIL", ({ - enumerable: true, - get: function () { - return _nil.default; - } -})); -Object.defineProperty(exports, "version", ({ - enumerable: true, - get: function () { - return _version.default; - } -})); -Object.defineProperty(exports, "validate", ({ - enumerable: true, - get: function () { - return _validate.default; - } -})); -Object.defineProperty(exports, "stringify", ({ - enumerable: true, - get: function () { - return _stringify.default; - } -})); -Object.defineProperty(exports, "parse", ({ - enumerable: true, - get: function () { - return _parse.default; - } -})); - -var _v = _interopRequireDefault(__nccwpck_require__(8628)); - -var _v2 = _interopRequireDefault(__nccwpck_require__(6409)); +// This is a Globally Unique Identifier unique used +// to validate that the endpoint accepts websocket +// connections. +// See https://www.rfc-editor.org/rfc/rfc6455.html#section-1.3 +const uid = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11' -var _v3 = _interopRequireDefault(__nccwpck_require__(5122)); +/** @type {PropertyDescriptor} */ +const staticPropertyDescriptors = { + enumerable: true, + writable: false, + configurable: false +} -var _v4 = _interopRequireDefault(__nccwpck_require__(9120)); +const states = { + CONNECTING: 0, + OPEN: 1, + CLOSING: 2, + CLOSED: 3 +} -var _nil = _interopRequireDefault(__nccwpck_require__(5332)); +const opcodes = { + CONTINUATION: 0x0, + TEXT: 0x1, + BINARY: 0x2, + CLOSE: 0x8, + PING: 0x9, + PONG: 0xA +} -var _version = _interopRequireDefault(__nccwpck_require__(1595)); +const maxUnsigned16Bit = 2 ** 16 - 1 // 65535 -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); +const parserStates = { + INFO: 0, + PAYLOADLENGTH_16: 2, + PAYLOADLENGTH_64: 3, + READ_DATA: 4 +} -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); +const emptyBuffer = Buffer.allocUnsafe(0) -var _parse = _interopRequireDefault(__nccwpck_require__(2746)); +module.exports = { + uid, + staticPropertyDescriptors, + states, + opcodes, + maxUnsigned16Bit, + parserStates, + emptyBuffer +} -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /***/ }), -/***/ 4569: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 2611: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; +const { webidl } = __nccwpck_require__(1744) +const { kEnumerableProperty } = __nccwpck_require__(3983) +const { MessagePort } = __nccwpck_require__(1267) -var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); +/** + * @see https://html.spec.whatwg.org/multipage/comms.html#messageevent + */ +class MessageEvent extends Event { + #eventInit -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + constructor (type, eventInitDict = {}) { + webidl.argumentLengthCheck(arguments, 1, { header: 'MessageEvent constructor' }) -function md5(bytes) { - if (Array.isArray(bytes)) { - bytes = Buffer.from(bytes); - } else if (typeof bytes === 'string') { - bytes = Buffer.from(bytes, 'utf8'); - } + type = webidl.converters.DOMString(type) + eventInitDict = webidl.converters.MessageEventInit(eventInitDict) - return _crypto.default.createHash('md5').update(bytes).digest(); -} + super(type, eventInitDict) -var _default = md5; -exports["default"] = _default; + this.#eventInit = eventInitDict + } -/***/ }), + get data () { + webidl.brandCheck(this, MessageEvent) -/***/ 5332: -/***/ ((__unused_webpack_module, exports) => { + return this.#eventInit.data + } -"use strict"; + get origin () { + webidl.brandCheck(this, MessageEvent) + return this.#eventInit.origin + } -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; -var _default = '00000000-0000-0000-0000-000000000000'; -exports["default"] = _default; + get lastEventId () { + webidl.brandCheck(this, MessageEvent) -/***/ }), + return this.#eventInit.lastEventId + } -/***/ 2746: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + get source () { + webidl.brandCheck(this, MessageEvent) -"use strict"; + return this.#eventInit.source + } + get ports () { + webidl.brandCheck(this, MessageEvent) -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; + if (!Object.isFrozen(this.#eventInit.ports)) { + Object.freeze(this.#eventInit.ports) + } -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + return this.#eventInit.ports + } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + initMessageEvent ( + type, + bubbles = false, + cancelable = false, + data = null, + origin = '', + lastEventId = '', + source = null, + ports = [] + ) { + webidl.brandCheck(this, MessageEvent) -function parse(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID'); + webidl.argumentLengthCheck(arguments, 1, { header: 'MessageEvent.initMessageEvent' }) + + return new MessageEvent(type, { + bubbles, cancelable, data, origin, lastEventId, source, ports + }) } +} - let v; - const arr = new Uint8Array(16); // Parse ########-....-....-....-............ +/** + * @see https://websockets.spec.whatwg.org/#the-closeevent-interface + */ +class CloseEvent extends Event { + #eventInit - arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; - arr[1] = v >>> 16 & 0xff; - arr[2] = v >>> 8 & 0xff; - arr[3] = v & 0xff; // Parse ........-####-....-....-............ + constructor (type, eventInitDict = {}) { + webidl.argumentLengthCheck(arguments, 1, { header: 'CloseEvent constructor' }) - arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; - arr[5] = v & 0xff; // Parse ........-....-####-....-............ + type = webidl.converters.DOMString(type) + eventInitDict = webidl.converters.CloseEventInit(eventInitDict) - arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; - arr[7] = v & 0xff; // Parse ........-....-....-####-............ + super(type, eventInitDict) - arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; - arr[9] = v & 0xff; // Parse ........-....-....-....-############ - // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) + this.#eventInit = eventInitDict + } - arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff; - arr[11] = v / 0x100000000 & 0xff; - arr[12] = v >>> 24 & 0xff; - arr[13] = v >>> 16 & 0xff; - arr[14] = v >>> 8 & 0xff; - arr[15] = v & 0xff; - return arr; -} + get wasClean () { + webidl.brandCheck(this, CloseEvent) -var _default = parse; -exports["default"] = _default; + return this.#eventInit.wasClean + } -/***/ }), + get code () { + webidl.brandCheck(this, CloseEvent) + + return this.#eventInit.code + } -/***/ 814: -/***/ ((__unused_webpack_module, exports) => { + get reason () { + webidl.brandCheck(this, CloseEvent) -"use strict"; + return this.#eventInit.reason + } +} +// https://html.spec.whatwg.org/multipage/webappapis.html#the-errorevent-interface +class ErrorEvent extends Event { + #eventInit -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; -var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; -exports["default"] = _default; + constructor (type, eventInitDict) { + webidl.argumentLengthCheck(arguments, 1, { header: 'ErrorEvent constructor' }) -/***/ }), + super(type, eventInitDict) -/***/ 807: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + type = webidl.converters.DOMString(type) + eventInitDict = webidl.converters.ErrorEventInit(eventInitDict ?? {}) -"use strict"; + this.#eventInit = eventInitDict + } + get message () { + webidl.brandCheck(this, ErrorEvent) -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = rng; + return this.#eventInit.message + } -var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); + get filename () { + webidl.brandCheck(this, ErrorEvent) -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + return this.#eventInit.filename + } -const rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate + get lineno () { + webidl.brandCheck(this, ErrorEvent) -let poolPtr = rnds8Pool.length; + return this.#eventInit.lineno + } -function rng() { - if (poolPtr > rnds8Pool.length - 16) { - _crypto.default.randomFillSync(rnds8Pool); + get colno () { + webidl.brandCheck(this, ErrorEvent) - poolPtr = 0; + return this.#eventInit.colno } - return rnds8Pool.slice(poolPtr, poolPtr += 16); + get error () { + webidl.brandCheck(this, ErrorEvent) + + return this.#eventInit.error + } } -/***/ }), +Object.defineProperties(MessageEvent.prototype, { + [Symbol.toStringTag]: { + value: 'MessageEvent', + configurable: true + }, + data: kEnumerableProperty, + origin: kEnumerableProperty, + lastEventId: kEnumerableProperty, + source: kEnumerableProperty, + ports: kEnumerableProperty, + initMessageEvent: kEnumerableProperty +}) -/***/ 5274: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +Object.defineProperties(CloseEvent.prototype, { + [Symbol.toStringTag]: { + value: 'CloseEvent', + configurable: true + }, + reason: kEnumerableProperty, + code: kEnumerableProperty, + wasClean: kEnumerableProperty +}) -"use strict"; +Object.defineProperties(ErrorEvent.prototype, { + [Symbol.toStringTag]: { + value: 'ErrorEvent', + configurable: true + }, + message: kEnumerableProperty, + filename: kEnumerableProperty, + lineno: kEnumerableProperty, + colno: kEnumerableProperty, + error: kEnumerableProperty +}) +webidl.converters.MessagePort = webidl.interfaceConverter(MessagePort) -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; +webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.MessagePort +) -var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); +const eventInit = [ + { + key: 'bubbles', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'cancelable', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'composed', + converter: webidl.converters.boolean, + defaultValue: false + } +] -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +webidl.converters.MessageEventInit = webidl.dictionaryConverter([ + ...eventInit, + { + key: 'data', + converter: webidl.converters.any, + defaultValue: null + }, + { + key: 'origin', + converter: webidl.converters.USVString, + defaultValue: '' + }, + { + key: 'lastEventId', + converter: webidl.converters.DOMString, + defaultValue: '' + }, + { + key: 'source', + // Node doesn't implement WindowProxy or ServiceWorker, so the only + // valid value for source is a MessagePort. + converter: webidl.nullableConverter(webidl.converters.MessagePort), + defaultValue: null + }, + { + key: 'ports', + converter: webidl.converters['sequence'], + get defaultValue () { + return [] + } + } +]) -function sha1(bytes) { - if (Array.isArray(bytes)) { - bytes = Buffer.from(bytes); - } else if (typeof bytes === 'string') { - bytes = Buffer.from(bytes, 'utf8'); +webidl.converters.CloseEventInit = webidl.dictionaryConverter([ + ...eventInit, + { + key: 'wasClean', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'code', + converter: webidl.converters['unsigned short'], + defaultValue: 0 + }, + { + key: 'reason', + converter: webidl.converters.USVString, + defaultValue: '' } +]) - return _crypto.default.createHash('sha1').update(bytes).digest(); +webidl.converters.ErrorEventInit = webidl.dictionaryConverter([ + ...eventInit, + { + key: 'message', + converter: webidl.converters.DOMString, + defaultValue: '' + }, + { + key: 'filename', + converter: webidl.converters.USVString, + defaultValue: '' + }, + { + key: 'lineno', + converter: webidl.converters['unsigned long'], + defaultValue: 0 + }, + { + key: 'colno', + converter: webidl.converters['unsigned long'], + defaultValue: 0 + }, + { + key: 'error', + converter: webidl.converters.any + } +]) + +module.exports = { + MessageEvent, + CloseEvent, + ErrorEvent } -var _default = sha1; -exports["default"] = _default; /***/ }), -/***/ 8950: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 5444: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; +const { maxUnsigned16Bit } = __nccwpck_require__(9188) + +/** @type {import('crypto')} */ +let crypto +try { + crypto = __nccwpck_require__(6113) +} catch { + +} + +class WebsocketFrameSend { + /** + * @param {Buffer|undefined} data + */ + constructor (data) { + this.frameData = data + this.maskKey = crypto.randomBytes(4) + } + + createFrame (opcode) { + const bodyLength = this.frameData?.byteLength ?? 0 + + /** @type {number} */ + let payloadLength = bodyLength // 0-125 + let offset = 6 + + if (bodyLength > maxUnsigned16Bit) { + offset += 8 // payload length is next 8 bytes + payloadLength = 127 + } else if (bodyLength > 125) { + offset += 2 // payload length is next 2 bytes + payloadLength = 126 + } -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + const buffer = Buffer.allocUnsafe(bodyLength + offset) -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + // Clear first 2 bytes, everything else is overwritten + buffer[0] = buffer[1] = 0 + buffer[0] |= 0x80 // FIN + buffer[0] = (buffer[0] & 0xF0) + opcode // opcode -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ -const byteToHex = []; + /*! ws. MIT License. Einar Otto Stangvik */ + buffer[offset - 4] = this.maskKey[0] + buffer[offset - 3] = this.maskKey[1] + buffer[offset - 2] = this.maskKey[2] + buffer[offset - 1] = this.maskKey[3] -for (let i = 0; i < 256; ++i) { - byteToHex.push((i + 0x100).toString(16).substr(1)); -} + buffer[1] = payloadLength -function stringify(arr, offset = 0) { - // Note: Be careful editing this code! It's been tuned for performance - // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 - const uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one - // of the following: - // - One or more input array values don't map to a hex octet (leading to - // "undefined" in the uuid) - // - Invalid input values for the RFC `version` or `variant` fields + if (payloadLength === 126) { + buffer.writeUInt16BE(bodyLength, 2) + } else if (payloadLength === 127) { + // Clear extended payload length + buffer[2] = buffer[3] = 0 + buffer.writeUIntBE(bodyLength, 4, 6) + } - if (!(0, _validate.default)(uuid)) { - throw TypeError('Stringified UUID is invalid'); + buffer[1] |= 0x80 // MASK + + // mask body + for (let i = 0; i < bodyLength; i++) { + buffer[offset + i] = this.frameData[i] ^ this.maskKey[i % 4] + } + + return buffer } +} - return uuid; +module.exports = { + WebsocketFrameSend } -var _default = stringify; -exports["default"] = _default; /***/ }), -/***/ 8628: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 1688: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _rng = _interopRequireDefault(__nccwpck_require__(807)); - -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// **`v1()` - Generate time-based UUID** -// -// Inspired by https://github.com/LiosK/UUID.js -// and http://docs.python.org/library/uuid.html -let _nodeId; - -let _clockseq; // Previous uuid creation time - - -let _lastMSecs = 0; -let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details +const { Writable } = __nccwpck_require__(2781) +const diagnosticsChannel = __nccwpck_require__(7643) +const { parserStates, opcodes, states, emptyBuffer } = __nccwpck_require__(9188) +const { kReadyState, kSentClose, kResponse, kReceivedClose } = __nccwpck_require__(7578) +const { isValidStatusCode, failWebsocketConnection, websocketMessageReceived } = __nccwpck_require__(5515) +const { WebsocketFrameSend } = __nccwpck_require__(5444) -function v1(options, buf, offset) { - let i = buf && offset || 0; - const b = buf || new Array(16); - options = options || {}; - let node = options.node || _nodeId; - let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not - // specified. We do this lazily to minimize issues related to insufficient - // system entropy. See #189 +// This code was influenced by ws released under the MIT license. +// Copyright (c) 2011 Einar Otto Stangvik +// Copyright (c) 2013 Arnout Kazemier and contributors +// Copyright (c) 2016 Luigi Pinca and contributors - if (node == null || clockseq == null) { - const seedBytes = options.random || (options.rng || _rng.default)(); +const channels = {} +channels.ping = diagnosticsChannel.channel('undici:websocket:ping') +channels.pong = diagnosticsChannel.channel('undici:websocket:pong') - if (node == null) { - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; - } +class ByteParser extends Writable { + #buffers = [] + #byteOffset = 0 - if (clockseq == null) { - // Per 4.2.2, randomize (14 bit) clockseq - clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; - } - } // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + #state = parserStates.INFO + #info = {} + #fragments = [] - let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock + constructor (ws) { + super() - let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) + this.ws = ws + } - const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression + /** + * @param {Buffer} chunk + * @param {() => void} callback + */ + _write (chunk, _, callback) { + this.#buffers.push(chunk) + this.#byteOffset += chunk.length - if (dt < 0 && options.clockseq === undefined) { - clockseq = clockseq + 1 & 0x3fff; - } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval + this.run(callback) + } + /** + * Runs whenever a new chunk is received. + * Callback is called whenever there are no more chunks buffering, + * or not enough bytes are buffered to parse. + */ + run (callback) { + while (true) { + if (this.#state === parserStates.INFO) { + // If there aren't enough bytes to parse the payload length, etc. + if (this.#byteOffset < 2) { + return callback() + } - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { - nsecs = 0; - } // Per 4.2.1.2 Throw error if too many uuids are requested + const buffer = this.consume(2) + this.#info.fin = (buffer[0] & 0x80) !== 0 + this.#info.opcode = buffer[0] & 0x0F - if (nsecs >= 10000) { - throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); - } + // If we receive a fragmented message, we use the type of the first + // frame to parse the full message as binary/text, when it's terminated + this.#info.originalOpcode ??= this.#info.opcode - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + this.#info.fragmented = !this.#info.fin && this.#info.opcode !== opcodes.CONTINUATION - msecs += 12219292800000; // `time_low` + if (this.#info.fragmented && this.#info.opcode !== opcodes.BINARY && this.#info.opcode !== opcodes.TEXT) { + // Only text and binary frames can be fragmented + failWebsocketConnection(this.ws, 'Invalid frame type was fragmented.') + return + } - const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; // `time_mid` + const payloadLength = buffer[1] & 0x7F - const tmh = msecs / 0x100000000 * 10000 & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; // `time_high_and_version` + if (payloadLength <= 125) { + this.#info.payloadLength = payloadLength + this.#state = parserStates.READ_DATA + } else if (payloadLength === 126) { + this.#state = parserStates.PAYLOADLENGTH_16 + } else if (payloadLength === 127) { + this.#state = parserStates.PAYLOADLENGTH_64 + } - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + if (this.#info.fragmented && payloadLength > 125) { + // A fragmented frame can't be fragmented itself + failWebsocketConnection(this.ws, 'Fragmented frame exceeded 125 bytes.') + return + } else if ( + (this.#info.opcode === opcodes.PING || + this.#info.opcode === opcodes.PONG || + this.#info.opcode === opcodes.CLOSE) && + payloadLength > 125 + ) { + // Control frames can have a payload length of 125 bytes MAX + failWebsocketConnection(this.ws, 'Payload length for control frame exceeded 125 bytes.') + return + } else if (this.#info.opcode === opcodes.CLOSE) { + if (payloadLength === 1) { + failWebsocketConnection(this.ws, 'Received close frame with a 1-byte body.') + return + } - b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + const body = this.consume(payloadLength) - b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` + this.#info.closeInfo = this.parseCloseBody(false, body) - b[i++] = clockseq & 0xff; // `node` + if (!this.ws[kSentClose]) { + // If an endpoint receives a Close frame and did not previously send a + // Close frame, the endpoint MUST send a Close frame in response. (When + // sending a Close frame in response, the endpoint typically echos the + // status code it received.) + const body = Buffer.allocUnsafe(2) + body.writeUInt16BE(this.#info.closeInfo.code, 0) + const closeFrame = new WebsocketFrameSend(body) - for (let n = 0; n < 6; ++n) { - b[i + n] = node[n]; - } + this.ws[kResponse].socket.write( + closeFrame.createFrame(opcodes.CLOSE), + (err) => { + if (!err) { + this.ws[kSentClose] = true + } + } + ) + } - return buf || (0, _stringify.default)(b); -} + // Upon either sending or receiving a Close control frame, it is said + // that _The WebSocket Closing Handshake is Started_ and that the + // WebSocket connection is in the CLOSING state. + this.ws[kReadyState] = states.CLOSING + this.ws[kReceivedClose] = true -var _default = v1; -exports["default"] = _default; + this.end() -/***/ }), + return + } else if (this.#info.opcode === opcodes.PING) { + // Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in + // response, unless it already received a Close frame. + // A Pong frame sent in response to a Ping frame must have identical + // "Application data" -/***/ 6409: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + const body = this.consume(payloadLength) -"use strict"; + if (!this.ws[kReceivedClose]) { + const frame = new WebsocketFrameSend(body) + this.ws[kResponse].socket.write(frame.createFrame(opcodes.PONG)) -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; + if (channels.ping.hasSubscribers) { + channels.ping.publish({ + payload: body + }) + } + } -var _v = _interopRequireDefault(__nccwpck_require__(5998)); + this.#state = parserStates.INFO -var _md = _interopRequireDefault(__nccwpck_require__(4569)); + if (this.#byteOffset > 0) { + continue + } else { + callback() + return + } + } else if (this.#info.opcode === opcodes.PONG) { + // A Pong frame MAY be sent unsolicited. This serves as a + // unidirectional heartbeat. A response to an unsolicited Pong frame is + // not expected. -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + const body = this.consume(payloadLength) -const v3 = (0, _v.default)('v3', 0x30, _md.default); -var _default = v3; -exports["default"] = _default; + if (channels.pong.hasSubscribers) { + channels.pong.publish({ + payload: body + }) + } -/***/ }), + if (this.#byteOffset > 0) { + continue + } else { + callback() + return + } + } + } else if (this.#state === parserStates.PAYLOADLENGTH_16) { + if (this.#byteOffset < 2) { + return callback() + } -/***/ 5998: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + const buffer = this.consume(2) -"use strict"; + this.#info.payloadLength = buffer.readUInt16BE(0) + this.#state = parserStates.READ_DATA + } else if (this.#state === parserStates.PAYLOADLENGTH_64) { + if (this.#byteOffset < 8) { + return callback() + } + const buffer = this.consume(8) + const upper = buffer.readUInt32BE(0) -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = _default; -exports.URL = exports.DNS = void 0; + // 2^31 is the maxinimum bytes an arraybuffer can contain + // on 32-bit systems. Although, on 64-bit systems, this is + // 2^53-1 bytes. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_array_length + // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/common/globals.h;drc=1946212ac0100668f14eb9e2843bdd846e510a1e;bpv=1;bpt=1;l=1275 + // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/objects/js-array-buffer.h;l=34;drc=1946212ac0100668f14eb9e2843bdd846e510a1e + if (upper > 2 ** 31 - 1) { + failWebsocketConnection(this.ws, 'Received payload length > 2^31 bytes.') + return + } -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + const lower = buffer.readUInt32BE(4) -var _parse = _interopRequireDefault(__nccwpck_require__(2746)); + this.#info.payloadLength = (upper << 8) + lower + this.#state = parserStates.READ_DATA + } else if (this.#state === parserStates.READ_DATA) { + if (this.#byteOffset < this.#info.payloadLength) { + // If there is still more data in this chunk that needs to be read + return callback() + } else if (this.#byteOffset >= this.#info.payloadLength) { + // If the server sent multiple frames in a single chunk -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + const body = this.consume(this.#info.payloadLength) -function stringToBytes(str) { - str = unescape(encodeURIComponent(str)); // UTF8 escape + this.#fragments.push(body) - const bytes = []; + // If the frame is unfragmented, or a fragmented frame was terminated, + // a message was received + if (!this.#info.fragmented || (this.#info.fin && this.#info.opcode === opcodes.CONTINUATION)) { + const fullMessage = Buffer.concat(this.#fragments) - for (let i = 0; i < str.length; ++i) { - bytes.push(str.charCodeAt(i)); - } + websocketMessageReceived(this.ws, this.#info.originalOpcode, fullMessage) - return bytes; -} + this.#info = {} + this.#fragments.length = 0 + } -const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; -exports.DNS = DNS; -const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; -exports.URL = URL; + this.#state = parserStates.INFO + } + } -function _default(name, version, hashfunc) { - function generateUUID(value, namespace, buf, offset) { - if (typeof value === 'string') { - value = stringToBytes(value); + if (this.#byteOffset > 0) { + continue + } else { + callback() + break + } } + } - if (typeof namespace === 'string') { - namespace = (0, _parse.default)(namespace); + /** + * Take n bytes from the buffered Buffers + * @param {number} n + * @returns {Buffer|null} + */ + consume (n) { + if (n > this.#byteOffset) { + return null + } else if (n === 0) { + return emptyBuffer } - if (namespace.length !== 16) { - throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); - } // Compute hash of namespace and value, Per 4.3 - // Future: Use spread syntax when supported on all platforms, e.g. `bytes = - // hashfunc([...namespace, ... value])` - + if (this.#buffers[0].length === n) { + this.#byteOffset -= this.#buffers[0].length + return this.#buffers.shift() + } - let bytes = new Uint8Array(16 + value.length); - bytes.set(namespace); - bytes.set(value, namespace.length); - bytes = hashfunc(bytes); - bytes[6] = bytes[6] & 0x0f | version; - bytes[8] = bytes[8] & 0x3f | 0x80; + const buffer = Buffer.allocUnsafe(n) + let offset = 0 - if (buf) { - offset = offset || 0; + while (offset !== n) { + const next = this.#buffers[0] + const { length } = next - for (let i = 0; i < 16; ++i) { - buf[offset + i] = bytes[i]; + if (length + offset === n) { + buffer.set(this.#buffers.shift(), offset) + break + } else if (length + offset > n) { + buffer.set(next.subarray(0, n - offset), offset) + this.#buffers[0] = next.subarray(n - offset) + break + } else { + buffer.set(this.#buffers.shift(), offset) + offset += next.length } - - return buf; } - return (0, _stringify.default)(bytes); - } // Function#name is not settable on some platforms (#270) - - - try { - generateUUID.name = name; // eslint-disable-next-line no-empty - } catch (err) {} // For CommonJS default export support + this.#byteOffset -= n + return buffer + } - generateUUID.DNS = DNS; - generateUUID.URL = URL; - return generateUUID; -} + parseCloseBody (onlyCode, data) { + // https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5 + /** @type {number|undefined} */ + let code -/***/ }), + if (data.length >= 2) { + // _The WebSocket Connection Close Code_ is + // defined as the status code (Section 7.4) contained in the first Close + // control frame received by the application + code = data.readUInt16BE(0) + } -/***/ 5122: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + if (onlyCode) { + if (!isValidStatusCode(code)) { + return null + } -"use strict"; + return { code } + } + // https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6 + /** @type {Buffer} */ + let reason = data.subarray(2) -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; + // Remove BOM + if (reason[0] === 0xEF && reason[1] === 0xBB && reason[2] === 0xBF) { + reason = reason.subarray(3) + } -var _rng = _interopRequireDefault(__nccwpck_require__(807)); + if (code !== undefined && !isValidStatusCode(code)) { + return null + } -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + try { + // TODO: optimize this + reason = new TextDecoder('utf-8', { fatal: true }).decode(reason) + } catch { + return null + } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + return { code, reason } + } -function v4(options, buf, offset) { - options = options || {}; + get closingInfo () { + return this.#info.closeInfo + } +} - const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` +module.exports = { + ByteParser +} - rnds[6] = rnds[6] & 0x0f | 0x40; - rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided +/***/ }), - if (buf) { - offset = offset || 0; +/***/ 7578: +/***/ ((module) => { - for (let i = 0; i < 16; ++i) { - buf[offset + i] = rnds[i]; - } +"use strict"; - return buf; - } - return (0, _stringify.default)(rnds); +module.exports = { + kWebSocketURL: Symbol('url'), + kReadyState: Symbol('ready state'), + kController: Symbol('controller'), + kResponse: Symbol('response'), + kBinaryType: Symbol('binary type'), + kSentClose: Symbol('sent close'), + kReceivedClose: Symbol('received close'), + kByteParser: Symbol('byte parser') } -var _default = v4; -exports["default"] = _default; /***/ }), -/***/ 9120: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 5515: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; +const { kReadyState, kController, kResponse, kBinaryType, kWebSocketURL } = __nccwpck_require__(7578) +const { states, opcodes } = __nccwpck_require__(9188) +const { MessageEvent, ErrorEvent } = __nccwpck_require__(2611) -var _v = _interopRequireDefault(__nccwpck_require__(5998)); +/* globals Blob */ -var _sha = _interopRequireDefault(__nccwpck_require__(5274)); +/** + * @param {import('./websocket').WebSocket} ws + */ +function isEstablished (ws) { + // If the server's response is validated as provided for above, it is + // said that _The WebSocket Connection is Established_ and that the + // WebSocket Connection is in the OPEN state. + return ws[kReadyState] === states.OPEN +} -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +/** + * @param {import('./websocket').WebSocket} ws + */ +function isClosing (ws) { + // Upon either sending or receiving a Close control frame, it is said + // that _The WebSocket Closing Handshake is Started_ and that the + // WebSocket connection is in the CLOSING state. + return ws[kReadyState] === states.CLOSING +} -const v5 = (0, _v.default)('v5', 0x50, _sha.default); -var _default = v5; -exports["default"] = _default; +/** + * @param {import('./websocket').WebSocket} ws + */ +function isClosed (ws) { + return ws[kReadyState] === states.CLOSED +} -/***/ }), +/** + * @see https://dom.spec.whatwg.org/#concept-event-fire + * @param {string} e + * @param {EventTarget} target + * @param {EventInit | undefined} eventInitDict + */ +function fireEvent (e, target, eventConstructor = Event, eventInitDict) { + // 1. If eventConstructor is not given, then let eventConstructor be Event. -/***/ 6900: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + // 2. Let event be the result of creating an event given eventConstructor, + // in the relevant realm of target. + // 3. Initialize event’s type attribute to e. + const event = new eventConstructor(e, eventInitDict) // eslint-disable-line new-cap -"use strict"; + // 4. Initialize any other IDL attributes of event as described in the + // invocation of this algorithm. + // 5. Return the result of dispatching event at target, with legacy target + // override flag set if set. + target.dispatchEvent(event) +} -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; +/** + * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol + * @param {import('./websocket').WebSocket} ws + * @param {number} type Opcode + * @param {Buffer} data application data + */ +function websocketMessageReceived (ws, type, data) { + // 1. If ready state is not OPEN (1), then return. + if (ws[kReadyState] !== states.OPEN) { + return + } -var _regex = _interopRequireDefault(__nccwpck_require__(814)); + // 2. Let dataForEvent be determined by switching on type and binary type: + let dataForEvent -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + if (type === opcodes.TEXT) { + // -> type indicates that the data is Text + // a new DOMString containing data + try { + dataForEvent = new TextDecoder('utf-8', { fatal: true }).decode(data) + } catch { + failWebsocketConnection(ws, 'Received invalid UTF-8 in text frame.') + return + } + } else if (type === opcodes.BINARY) { + if (ws[kBinaryType] === 'blob') { + // -> type indicates that the data is Binary and binary type is "blob" + // a new Blob object, created in the relevant Realm of the WebSocket + // object, that represents data as its raw data + dataForEvent = new Blob([data]) + } else { + // -> type indicates that the data is Binary and binary type is "arraybuffer" + // a new ArrayBuffer object, created in the relevant Realm of the + // WebSocket object, whose contents are data + dataForEvent = new Uint8Array(data).buffer + } + } -function validate(uuid) { - return typeof uuid === 'string' && _regex.default.test(uuid); + // 3. Fire an event named message at the WebSocket object, using MessageEvent, + // with the origin attribute initialized to the serialization of the WebSocket + // object’s url's origin, and the data attribute initialized to dataForEvent. + fireEvent('message', ws, MessageEvent, { + origin: ws[kWebSocketURL].origin, + data: dataForEvent + }) } -var _default = validate; -exports["default"] = _default; +/** + * @see https://datatracker.ietf.org/doc/html/rfc6455 + * @see https://datatracker.ietf.org/doc/html/rfc2616 + * @see https://bugs.chromium.org/p/chromium/issues/detail?id=398407 + * @param {string} protocol + */ +function isValidSubprotocol (protocol) { + // If present, this value indicates one + // or more comma-separated subprotocol the client wishes to speak, + // ordered by preference. The elements that comprise this value + // MUST be non-empty strings with characters in the range U+0021 to + // U+007E not including separator characters as defined in + // [RFC2616] and MUST all be unique strings. + if (protocol.length === 0) { + return false + } -/***/ }), + for (const char of protocol) { + const code = char.charCodeAt(0) -/***/ 1595: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + if ( + code < 0x21 || + code > 0x7E || + char === '(' || + char === ')' || + char === '<' || + char === '>' || + char === '@' || + char === ',' || + char === ';' || + char === ':' || + char === '\\' || + char === '"' || + char === '/' || + char === '[' || + char === ']' || + char === '?' || + char === '=' || + char === '{' || + char === '}' || + code === 32 || // SP + code === 9 // HT + ) { + return false + } + } -"use strict"; + return true +} +/** + * @see https://datatracker.ietf.org/doc/html/rfc6455#section-7-4 + * @param {number} code + */ +function isValidStatusCode (code) { + if (code >= 1000 && code < 1015) { + return ( + code !== 1004 && // reserved + code !== 1005 && // "MUST NOT be set as a status code" + code !== 1006 // "MUST NOT be set as a status code" + ) + } -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; + return code >= 3000 && code <= 4999 +} -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); +/** + * @param {import('./websocket').WebSocket} ws + * @param {string|undefined} reason + */ +function failWebsocketConnection (ws, reason) { + const { [kController]: controller, [kResponse]: response } = ws -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + controller.abort() -function version(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID'); + if (response?.socket && !response.socket.destroyed) { + response.socket.destroy() } - return parseInt(uuid.substr(14, 1), 16); + if (reason) { + fireEvent('error', ws, ErrorEvent, { + error: new Error(reason) + }) + } +} + +module.exports = { + isEstablished, + isClosing, + isClosed, + fireEvent, + isValidSubprotocol, + isValidStatusCode, + failWebsocketConnection, + websocketMessageReceived } -var _default = version; -exports["default"] = _default; /***/ }), -/***/ 3922: +/***/ 4284: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -module.exports = -{ - parallel : __nccwpck_require__(3085), - serial : __nccwpck_require__(7380), - serialOrdered : __nccwpck_require__(7704) -}; +"use strict"; -/***/ }), +const { webidl } = __nccwpck_require__(1744) +const { DOMException } = __nccwpck_require__(1037) +const { URLSerializer } = __nccwpck_require__(685) +const { getGlobalOrigin } = __nccwpck_require__(1246) +const { staticPropertyDescriptors, states, opcodes, emptyBuffer } = __nccwpck_require__(9188) +const { + kWebSocketURL, + kReadyState, + kController, + kBinaryType, + kResponse, + kSentClose, + kByteParser +} = __nccwpck_require__(7578) +const { isEstablished, isClosing, isValidSubprotocol, failWebsocketConnection, fireEvent } = __nccwpck_require__(5515) +const { establishWebSocketConnection } = __nccwpck_require__(5354) +const { WebsocketFrameSend } = __nccwpck_require__(5444) +const { ByteParser } = __nccwpck_require__(1688) +const { kEnumerableProperty, isBlobLike } = __nccwpck_require__(3983) +const { getGlobalDispatcher } = __nccwpck_require__(1892) +const { types } = __nccwpck_require__(3837) -/***/ 94: -/***/ ((module) => { +let experimentalWarned = false -// API -module.exports = abort; +// https://websockets.spec.whatwg.org/#interface-definition +class WebSocket extends EventTarget { + #events = { + open: null, + error: null, + close: null, + message: null + } -/** - * Aborts leftover active jobs - * - * @param {object} state - current state object - */ -function abort(state) -{ - Object.keys(state.jobs).forEach(clean.bind(state)); + #bufferedAmount = 0 + #protocol = '' + #extensions = '' - // reset leftover jobs - state.jobs = {}; -} + /** + * @param {string} url + * @param {string|string[]} protocols + */ + constructor (url, protocols = []) { + super() -/** - * Cleans up leftover job by invoking abort function for the provided job id - * - * @this state - * @param {string|number} key - job id to abort - */ -function clean(key) -{ - if (typeof this.jobs[key] == 'function') - { - this.jobs[key](); - } -} + webidl.argumentLengthCheck(arguments, 1, { header: 'WebSocket constructor' }) + if (!experimentalWarned) { + experimentalWarned = true + process.emitWarning('WebSockets are experimental, expect them to change at any time.', { + code: 'UNDICI-WS' + }) + } -/***/ }), + const options = webidl.converters['DOMString or sequence or WebSocketInit'](protocols) -/***/ 2824: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + url = webidl.converters.USVString(url) + protocols = options.protocols -var defer = __nccwpck_require__(4237); + // 1. Let baseURL be this's relevant settings object's API base URL. + const baseURL = getGlobalOrigin() -// API -module.exports = async; + // 1. Let urlRecord be the result of applying the URL parser to url with baseURL. + let urlRecord -/** - * Runs provided callback asynchronously - * even if callback itself is not - * - * @param {function} callback - callback to invoke - * @returns {function} - augmented callback - */ -function async(callback) -{ - var isAsync = false; + try { + urlRecord = new URL(url, baseURL) + } catch (e) { + // 3. If urlRecord is failure, then throw a "SyntaxError" DOMException. + throw new DOMException(e, 'SyntaxError') + } - // check if async happened - defer(function() { isAsync = true; }); + // 4. If urlRecord’s scheme is "http", then set urlRecord’s scheme to "ws". + if (urlRecord.protocol === 'http:') { + urlRecord.protocol = 'ws:' + } else if (urlRecord.protocol === 'https:') { + // 5. Otherwise, if urlRecord’s scheme is "https", set urlRecord’s scheme to "wss". + urlRecord.protocol = 'wss:' + } - return function async_callback(err, result) - { - if (isAsync) - { - callback(err, result); + // 6. If urlRecord’s scheme is not "ws" or "wss", then throw a "SyntaxError" DOMException. + if (urlRecord.protocol !== 'ws:' && urlRecord.protocol !== 'wss:') { + throw new DOMException( + `Expected a ws: or wss: protocol, got ${urlRecord.protocol}`, + 'SyntaxError' + ) } - else - { - defer(function nextTick_callback() - { - callback(err, result); - }); + + // 7. If urlRecord’s fragment is non-null, then throw a "SyntaxError" + // DOMException. + if (urlRecord.hash || urlRecord.href.endsWith('#')) { + throw new DOMException('Got fragment', 'SyntaxError') } - }; -} + // 8. If protocols is a string, set protocols to a sequence consisting + // of just that string. + if (typeof protocols === 'string') { + protocols = [protocols] + } -/***/ }), + // 9. If any of the values in protocols occur more than once or otherwise + // fail to match the requirements for elements that comprise the value + // of `Sec-WebSocket-Protocol` fields as defined by The WebSocket + // protocol, then throw a "SyntaxError" DOMException. + if (protocols.length !== new Set(protocols.map(p => p.toLowerCase())).size) { + throw new DOMException('Invalid Sec-WebSocket-Protocol value', 'SyntaxError') + } -/***/ 4237: -/***/ ((module) => { + if (protocols.length > 0 && !protocols.every(p => isValidSubprotocol(p))) { + throw new DOMException('Invalid Sec-WebSocket-Protocol value', 'SyntaxError') + } -module.exports = defer; + // 10. Set this's url to urlRecord. + this[kWebSocketURL] = new URL(urlRecord.href) -/** - * Runs provided function on next iteration of the event loop - * - * @param {function} fn - function to run - */ -function defer(fn) -{ - var nextTick = typeof setImmediate == 'function' - ? setImmediate - : ( - typeof process == 'object' && typeof process.nextTick == 'function' - ? process.nextTick - : null - ); + // 11. Let client be this's relevant settings object. - if (nextTick) - { - nextTick(fn); - } - else - { - setTimeout(fn, 0); - } -} + // 12. Run this step in parallel: + // 1. Establish a WebSocket connection given urlRecord, protocols, + // and client. + this[kController] = establishWebSocketConnection( + urlRecord, + protocols, + this, + (response) => this.#onConnectionEstablished(response), + options + ) -/***/ }), + // Each WebSocket object has an associated ready state, which is a + // number representing the state of the connection. Initially it must + // be CONNECTING (0). + this[kReadyState] = WebSocket.CONNECTING -/***/ 6600: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // The extensions attribute must initially return the empty string. -var async = __nccwpck_require__(2824) - , abort = __nccwpck_require__(94) - ; + // The protocol attribute must initially return the empty string. -// API -module.exports = iterate; + // Each WebSocket object has an associated binary type, which is a + // BinaryType. Initially it must be "blob". + this[kBinaryType] = 'blob' + } -/** - * Iterates over each job object - * - * @param {array|object} list - array or object (named list) to iterate over - * @param {function} iterator - iterator to run - * @param {object} state - current job status - * @param {function} callback - invoked when all elements processed - */ -function iterate(list, iterator, state, callback) -{ - // store current index - var key = state['keyedList'] ? state['keyedList'][state.index] : state.index; + /** + * @see https://websockets.spec.whatwg.org/#dom-websocket-close + * @param {number|undefined} code + * @param {string|undefined} reason + */ + close (code = undefined, reason = undefined) { + webidl.brandCheck(this, WebSocket) - state.jobs[key] = runJob(iterator, key, list[key], function(error, output) - { - // don't repeat yourself - // skip secondary callbacks - if (!(key in state.jobs)) - { - return; + if (code !== undefined) { + code = webidl.converters['unsigned short'](code, { clamp: true }) } - // clean up jobs - delete state.jobs[key]; - - if (error) - { - // don't process rest of the results - // stop still active jobs - // and reset the list - abort(state); + if (reason !== undefined) { + reason = webidl.converters.USVString(reason) } - else - { - state.results[key] = output; + + // 1. If code is present, but is neither an integer equal to 1000 nor an + // integer in the range 3000 to 4999, inclusive, throw an + // "InvalidAccessError" DOMException. + if (code !== undefined) { + if (code !== 1000 && (code < 3000 || code > 4999)) { + throw new DOMException('invalid code', 'InvalidAccessError') + } } - // return salvaged results - callback(error, state.results); - }); -} + let reasonByteLength = 0 -/** - * Runs iterator over provided job element - * - * @param {function} iterator - iterator to invoke - * @param {string|number} key - key/index of the element in the list of jobs - * @param {mixed} item - job description - * @param {function} callback - invoked after iterator is done with the job - * @returns {function|mixed} - job abort function or something else - */ -function runJob(iterator, key, item, callback) -{ - var aborter; + // 2. If reason is present, then run these substeps: + if (reason !== undefined) { + // 1. Let reasonBytes be the result of encoding reason. + // 2. If reasonBytes is longer than 123 bytes, then throw a + // "SyntaxError" DOMException. + reasonByteLength = Buffer.byteLength(reason) + + if (reasonByteLength > 123) { + throw new DOMException( + `Reason must be less than 123 bytes; received ${reasonByteLength}`, + 'SyntaxError' + ) + } + } - // allow shortcut if iterator expects only two arguments - if (iterator.length == 2) - { - aborter = iterator(item, async(callback)); - } - // otherwise go with full three arguments - else - { - aborter = iterator(item, key, async(callback)); - } + // 3. Run the first matching steps from the following list: + if (this[kReadyState] === WebSocket.CLOSING || this[kReadyState] === WebSocket.CLOSED) { + // If this's ready state is CLOSING (2) or CLOSED (3) + // Do nothing. + } else if (!isEstablished(this)) { + // If the WebSocket connection is not yet established + // Fail the WebSocket connection and set this's ready state + // to CLOSING (2). + failWebsocketConnection(this, 'Connection was closed before it was established.') + this[kReadyState] = WebSocket.CLOSING + } else if (!isClosing(this)) { + // If the WebSocket closing handshake has not yet been started + // Start the WebSocket closing handshake and set this's ready + // state to CLOSING (2). + // - If neither code nor reason is present, the WebSocket Close + // message must not have a body. + // - If code is present, then the status code to use in the + // WebSocket Close message must be the integer given by code. + // - If reason is also present, then reasonBytes must be + // provided in the Close message after the status code. - return aborter; -} + const frame = new WebsocketFrameSend() + // If neither code nor reason is present, the WebSocket Close + // message must not have a body. -/***/ }), + // If code is present, then the status code to use in the + // WebSocket Close message must be the integer given by code. + if (code !== undefined && reason === undefined) { + frame.frameData = Buffer.allocUnsafe(2) + frame.frameData.writeUInt16BE(code, 0) + } else if (code !== undefined && reason !== undefined) { + // If reason is also present, then reasonBytes must be + // provided in the Close message after the status code. + frame.frameData = Buffer.allocUnsafe(2 + reasonByteLength) + frame.frameData.writeUInt16BE(code, 0) + // the body MAY contain UTF-8-encoded data with value /reason/ + frame.frameData.write(reason, 2, 'utf-8') + } else { + frame.frameData = emptyBuffer + } -/***/ 1077: -/***/ ((module) => { + /** @type {import('stream').Duplex} */ + const socket = this[kResponse].socket -// API -module.exports = state; + socket.write(frame.createFrame(opcodes.CLOSE), (err) => { + if (!err) { + this[kSentClose] = true + } + }) -/** - * Creates initial state object - * for iteration over list - * - * @param {array|object} list - list to iterate over - * @param {function|null} sortMethod - function to use for keys sort, - * or `null` to keep them as is - * @returns {object} - initial state object - */ -function state(list, sortMethod) -{ - var isNamedList = !Array.isArray(list) - , initState = - { - index : 0, - keyedList: isNamedList || sortMethod ? Object.keys(list) : null, - jobs : {}, - results : isNamedList ? {} : [], - size : isNamedList ? Object.keys(list).length : list.length + // Upon either sending or receiving a Close control frame, it is said + // that _The WebSocket Closing Handshake is Started_ and that the + // WebSocket connection is in the CLOSING state. + this[kReadyState] = states.CLOSING + } else { + // Otherwise + // Set this's ready state to CLOSING (2). + this[kReadyState] = WebSocket.CLOSING } - ; - - if (sortMethod) - { - // sort array keys based on it's values - // sort object's keys just on own merit - initState.keyedList.sort(isNamedList ? sortMethod : function(a, b) - { - return sortMethod(list[a], list[b]); - }); } - return initState; -} - + /** + * @see https://websockets.spec.whatwg.org/#dom-websocket-send + * @param {NodeJS.TypedArray|ArrayBuffer|Blob|string} data + */ + send (data) { + webidl.brandCheck(this, WebSocket) -/***/ }), + webidl.argumentLengthCheck(arguments, 1, { header: 'WebSocket.send' }) -/***/ 4506: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + data = webidl.converters.WebSocketSendData(data) -var abort = __nccwpck_require__(94) - , async = __nccwpck_require__(2824) - ; + // 1. If this's ready state is CONNECTING, then throw an + // "InvalidStateError" DOMException. + if (this[kReadyState] === WebSocket.CONNECTING) { + throw new DOMException('Sent before connected.', 'InvalidStateError') + } -// API -module.exports = terminator; + // 2. Run the appropriate set of steps from the following list: + // https://datatracker.ietf.org/doc/html/rfc6455#section-6.1 + // https://datatracker.ietf.org/doc/html/rfc6455#section-5.2 -/** - * Terminates jobs in the attached state context - * - * @this AsyncKitState# - * @param {function} callback - final callback to invoke after termination - */ -function terminator(callback) -{ - if (!Object.keys(this.jobs).length) - { - return; - } + if (!isEstablished(this) || isClosing(this)) { + return + } - // fast forward iteration index - this.index = this.size; + /** @type {import('stream').Duplex} */ + const socket = this[kResponse].socket - // abort jobs - abort(this); + // If data is a string + if (typeof data === 'string') { + // If the WebSocket connection is established and the WebSocket + // closing handshake has not yet started, then the user agent + // must send a WebSocket Message comprised of the data argument + // using a text frame opcode; if the data cannot be sent, e.g. + // because it would need to be buffered but the buffer is full, + // the user agent must flag the WebSocket as full and then close + // the WebSocket connection. Any invocation of this method with a + // string argument that does not throw an exception must increase + // the bufferedAmount attribute by the number of bytes needed to + // express the argument as UTF-8. - // send back results we have so far - async(callback)(null, this.results); -} + const value = Buffer.from(data) + const frame = new WebsocketFrameSend(value) + const buffer = frame.createFrame(opcodes.TEXT) + this.#bufferedAmount += value.byteLength + socket.write(buffer, () => { + this.#bufferedAmount -= value.byteLength + }) + } else if (types.isArrayBuffer(data)) { + // If the WebSocket connection is established, and the WebSocket + // closing handshake has not yet started, then the user agent must + // send a WebSocket Message comprised of data using a binary frame + // opcode; if the data cannot be sent, e.g. because it would need + // to be buffered but the buffer is full, the user agent must flag + // the WebSocket as full and then close the WebSocket connection. + // The data to be sent is the data stored in the buffer described + // by the ArrayBuffer object. Any invocation of this method with an + // ArrayBuffer argument that does not throw an exception must + // increase the bufferedAmount attribute by the length of the + // ArrayBuffer in bytes. -/***/ }), + const value = Buffer.from(data) + const frame = new WebsocketFrameSend(value) + const buffer = frame.createFrame(opcodes.BINARY) -/***/ 3085: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this.#bufferedAmount += value.byteLength + socket.write(buffer, () => { + this.#bufferedAmount -= value.byteLength + }) + } else if (ArrayBuffer.isView(data)) { + // If the WebSocket connection is established, and the WebSocket + // closing handshake has not yet started, then the user agent must + // send a WebSocket Message comprised of data using a binary frame + // opcode; if the data cannot be sent, e.g. because it would need to + // be buffered but the buffer is full, the user agent must flag the + // WebSocket as full and then close the WebSocket connection. The + // data to be sent is the data stored in the section of the buffer + // described by the ArrayBuffer object that data references. Any + // invocation of this method with this kind of argument that does + // not throw an exception must increase the bufferedAmount attribute + // by the length of data’s buffer in bytes. -var iterate = __nccwpck_require__(6600) - , initState = __nccwpck_require__(1077) - , terminator = __nccwpck_require__(4506) - ; + const ab = Buffer.from(data, data.byteOffset, data.byteLength) -// Public API -module.exports = parallel; + const frame = new WebsocketFrameSend(ab) + const buffer = frame.createFrame(opcodes.BINARY) -/** - * Runs iterator over provided array elements in parallel - * - * @param {array|object} list - array or object (named list) to iterate over - * @param {function} iterator - iterator to run - * @param {function} callback - invoked when all elements processed - * @returns {function} - jobs terminator - */ -function parallel(list, iterator, callback) -{ - var state = initState(list); + this.#bufferedAmount += ab.byteLength + socket.write(buffer, () => { + this.#bufferedAmount -= ab.byteLength + }) + } else if (isBlobLike(data)) { + // If the WebSocket connection is established, and the WebSocket + // closing handshake has not yet started, then the user agent must + // send a WebSocket Message comprised of data using a binary frame + // opcode; if the data cannot be sent, e.g. because it would need to + // be buffered but the buffer is full, the user agent must flag the + // WebSocket as full and then close the WebSocket connection. The data + // to be sent is the raw data represented by the Blob object. Any + // invocation of this method with a Blob argument that does not throw + // an exception must increase the bufferedAmount attribute by the size + // of the Blob object’s raw data, in bytes. - while (state.index < (state['keyedList'] || list).length) - { - iterate(list, iterator, state, function(error, result) - { - if (error) - { - callback(error, result); - return; - } + const frame = new WebsocketFrameSend() - // looks like it's the last one - if (Object.keys(state.jobs).length === 0) - { - callback(null, state.results); - return; - } - }); + data.arrayBuffer().then((ab) => { + const value = Buffer.from(ab) + frame.frameData = value + const buffer = frame.createFrame(opcodes.BINARY) - state.index++; + this.#bufferedAmount += value.byteLength + socket.write(buffer, () => { + this.#bufferedAmount -= value.byteLength + }) + }) + } } - return terminator.bind(state, callback); -} + get readyState () { + webidl.brandCheck(this, WebSocket) + // The readyState getter steps are to return this's ready state. + return this[kReadyState] + } -/***/ }), + get bufferedAmount () { + webidl.brandCheck(this, WebSocket) -/***/ 7380: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + return this.#bufferedAmount + } -var serialOrdered = __nccwpck_require__(7704); + get url () { + webidl.brandCheck(this, WebSocket) -// Public API -module.exports = serial; + // The url getter steps are to return this's url, serialized. + return URLSerializer(this[kWebSocketURL]) + } -/** - * Runs iterator over provided array elements in series - * - * @param {array|object} list - array or object (named list) to iterate over - * @param {function} iterator - iterator to run - * @param {function} callback - invoked when all elements processed - * @returns {function} - jobs terminator - */ -function serial(list, iterator, callback) -{ - return serialOrdered(list, iterator, null, callback); -} + get extensions () { + webidl.brandCheck(this, WebSocket) + return this.#extensions + } -/***/ }), + get protocol () { + webidl.brandCheck(this, WebSocket) -/***/ 7704: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + return this.#protocol + } -var iterate = __nccwpck_require__(6600) - , initState = __nccwpck_require__(1077) - , terminator = __nccwpck_require__(4506) - ; + get onopen () { + webidl.brandCheck(this, WebSocket) -// Public API -module.exports = serialOrdered; -// sorting helpers -module.exports.ascending = ascending; -module.exports.descending = descending; + return this.#events.open + } -/** - * Runs iterator over provided sorted array elements in series - * - * @param {array|object} list - array or object (named list) to iterate over - * @param {function} iterator - iterator to run - * @param {function} sortMethod - custom sort function - * @param {function} callback - invoked when all elements processed - * @returns {function} - jobs terminator - */ -function serialOrdered(list, iterator, sortMethod, callback) -{ - var state = initState(list, sortMethod); + set onopen (fn) { + webidl.brandCheck(this, WebSocket) - iterate(list, iterator, state, function iteratorHandler(error, result) - { - if (error) - { - callback(error, result); - return; + if (this.#events.open) { + this.removeEventListener('open', this.#events.open) } - state.index++; - - // are we there yet? - if (state.index < (state['keyedList'] || list).length) - { - iterate(list, iterator, state, iteratorHandler); - return; + if (typeof fn === 'function') { + this.#events.open = fn + this.addEventListener('open', fn) + } else { + this.#events.open = null } + } - // done here - callback(null, state.results); - }); - - return terminator.bind(state, callback); -} - -/* - * -- Sort methods - */ - -/** - * sort helper to sort array elements in ascending order - * - * @param {mixed} a - an item to compare - * @param {mixed} b - an item to compare - * @returns {number} - comparison result - */ -function ascending(a, b) -{ - return a < b ? -1 : a > b ? 1 : 0; -} + get onerror () { + webidl.brandCheck(this, WebSocket) -/** - * sort helper to sort array elements in descending order - * - * @param {mixed} a - an item to compare - * @param {mixed} b - an item to compare - * @returns {number} - comparison result - */ -function descending(a, b) -{ - return -1 * ascending(a, b); -} + return this.#events.error + } + set onerror (fn) { + webidl.brandCheck(this, WebSocket) -/***/ }), + if (this.#events.error) { + this.removeEventListener('error', this.#events.error) + } -/***/ 3141: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (typeof fn === 'function') { + this.#events.error = fn + this.addEventListener('error', fn) + } else { + this.#events.error = null + } + } -var util = __nccwpck_require__(3837); -var Stream = (__nccwpck_require__(2781).Stream); -var DelayedStream = __nccwpck_require__(2959); + get onclose () { + webidl.brandCheck(this, WebSocket) -module.exports = CombinedStream; -function CombinedStream() { - this.writable = false; - this.readable = true; - this.dataSize = 0; - this.maxDataSize = 2 * 1024 * 1024; - this.pauseStreams = true; + return this.#events.close + } - this._released = false; - this._streams = []; - this._currentStream = null; - this._insideLoop = false; - this._pendingNext = false; -} -util.inherits(CombinedStream, Stream); + set onclose (fn) { + webidl.brandCheck(this, WebSocket) -CombinedStream.create = function(options) { - var combinedStream = new this(); + if (this.#events.close) { + this.removeEventListener('close', this.#events.close) + } - options = options || {}; - for (var option in options) { - combinedStream[option] = options[option]; + if (typeof fn === 'function') { + this.#events.close = fn + this.addEventListener('close', fn) + } else { + this.#events.close = null + } } - return combinedStream; -}; + get onmessage () { + webidl.brandCheck(this, WebSocket) -CombinedStream.isStreamLike = function(stream) { - return (typeof stream !== 'function') - && (typeof stream !== 'string') - && (typeof stream !== 'boolean') - && (typeof stream !== 'number') - && (!Buffer.isBuffer(stream)); -}; + return this.#events.message + } -CombinedStream.prototype.append = function(stream) { - var isStreamLike = CombinedStream.isStreamLike(stream); + set onmessage (fn) { + webidl.brandCheck(this, WebSocket) - if (isStreamLike) { - if (!(stream instanceof DelayedStream)) { - var newStream = DelayedStream.create(stream, { - maxDataSize: Infinity, - pauseStream: this.pauseStreams, - }); - stream.on('data', this._checkDataSize.bind(this)); - stream = newStream; + if (this.#events.message) { + this.removeEventListener('message', this.#events.message) } - this._handleErrors(stream); - - if (this.pauseStreams) { - stream.pause(); + if (typeof fn === 'function') { + this.#events.message = fn + this.addEventListener('message', fn) + } else { + this.#events.message = null } } - this._streams.push(stream); - return this; -}; + get binaryType () { + webidl.brandCheck(this, WebSocket) -CombinedStream.prototype.pipe = function(dest, options) { - Stream.prototype.pipe.call(this, dest, options); - this.resume(); - return dest; -}; + return this[kBinaryType] + } -CombinedStream.prototype._getNext = function() { - this._currentStream = null; + set binaryType (type) { + webidl.brandCheck(this, WebSocket) - if (this._insideLoop) { - this._pendingNext = true; - return; // defer call + if (type !== 'blob' && type !== 'arraybuffer') { + this[kBinaryType] = 'blob' + } else { + this[kBinaryType] = type + } } - this._insideLoop = true; - try { - do { - this._pendingNext = false; - this._realGetNext(); - } while (this._pendingNext); - } finally { - this._insideLoop = false; - } -}; + /** + * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol + */ + #onConnectionEstablished (response) { + // processResponse is called when the "response’s header list has been received and initialized." + // once this happens, the connection is open + this[kResponse] = response -CombinedStream.prototype._realGetNext = function() { - var stream = this._streams.shift(); + const parser = new ByteParser(this) + parser.on('drain', function onParserDrain () { + this.ws[kResponse].socket.resume() + }) + response.socket.ws = this + this[kByteParser] = parser - if (typeof stream == 'undefined') { - this.end(); - return; - } + // 1. Change the ready state to OPEN (1). + this[kReadyState] = states.OPEN - if (typeof stream !== 'function') { - this._pipeNext(stream); - return; - } + // 2. Change the extensions attribute’s value to the extensions in use, if + // it is not the null value. + // https://datatracker.ietf.org/doc/html/rfc6455#section-9.1 + const extensions = response.headersList.get('sec-websocket-extensions') - var getStream = stream; - getStream(function(stream) { - var isStreamLike = CombinedStream.isStreamLike(stream); - if (isStreamLike) { - stream.on('data', this._checkDataSize.bind(this)); - this._handleErrors(stream); + if (extensions !== null) { + this.#extensions = extensions } - this._pipeNext(stream); - }.bind(this)); -}; + // 3. Change the protocol attribute’s value to the subprotocol in use, if + // it is not the null value. + // https://datatracker.ietf.org/doc/html/rfc6455#section-1.9 + const protocol = response.headersList.get('sec-websocket-protocol') -CombinedStream.prototype._pipeNext = function(stream) { - this._currentStream = stream; + if (protocol !== null) { + this.#protocol = protocol + } - var isStreamLike = CombinedStream.isStreamLike(stream); - if (isStreamLike) { - stream.on('end', this._getNext.bind(this)); - stream.pipe(this, {end: false}); - return; + // 4. Fire an event named open at the WebSocket object. + fireEvent('open', this) } +} - var value = stream; - this.write(value); - this._getNext(); -}; +// https://websockets.spec.whatwg.org/#dom-websocket-connecting +WebSocket.CONNECTING = WebSocket.prototype.CONNECTING = states.CONNECTING +// https://websockets.spec.whatwg.org/#dom-websocket-open +WebSocket.OPEN = WebSocket.prototype.OPEN = states.OPEN +// https://websockets.spec.whatwg.org/#dom-websocket-closing +WebSocket.CLOSING = WebSocket.prototype.CLOSING = states.CLOSING +// https://websockets.spec.whatwg.org/#dom-websocket-closed +WebSocket.CLOSED = WebSocket.prototype.CLOSED = states.CLOSED -CombinedStream.prototype._handleErrors = function(stream) { - var self = this; - stream.on('error', function(err) { - self._emitError(err); - }); -}; +Object.defineProperties(WebSocket.prototype, { + CONNECTING: staticPropertyDescriptors, + OPEN: staticPropertyDescriptors, + CLOSING: staticPropertyDescriptors, + CLOSED: staticPropertyDescriptors, + url: kEnumerableProperty, + readyState: kEnumerableProperty, + bufferedAmount: kEnumerableProperty, + onopen: kEnumerableProperty, + onerror: kEnumerableProperty, + onclose: kEnumerableProperty, + close: kEnumerableProperty, + onmessage: kEnumerableProperty, + binaryType: kEnumerableProperty, + send: kEnumerableProperty, + extensions: kEnumerableProperty, + protocol: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'WebSocket', + writable: false, + enumerable: false, + configurable: true + } +}) -CombinedStream.prototype.write = function(data) { - this.emit('data', data); -}; +Object.defineProperties(WebSocket, { + CONNECTING: staticPropertyDescriptors, + OPEN: staticPropertyDescriptors, + CLOSING: staticPropertyDescriptors, + CLOSED: staticPropertyDescriptors +}) -CombinedStream.prototype.pause = function() { - if (!this.pauseStreams) { - return; +webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.DOMString +) + +webidl.converters['DOMString or sequence'] = function (V) { + if (webidl.util.Type(V) === 'Object' && Symbol.iterator in V) { + return webidl.converters['sequence'](V) } - if(this.pauseStreams && this._currentStream && typeof(this._currentStream.pause) == 'function') this._currentStream.pause(); - this.emit('pause'); -}; + return webidl.converters.DOMString(V) +} -CombinedStream.prototype.resume = function() { - if (!this._released) { - this._released = true; - this.writable = true; - this._getNext(); +// This implements the propsal made in https://github.com/whatwg/websockets/issues/42 +webidl.converters.WebSocketInit = webidl.dictionaryConverter([ + { + key: 'protocols', + converter: webidl.converters['DOMString or sequence'], + get defaultValue () { + return [] + } + }, + { + key: 'dispatcher', + converter: (V) => V, + get defaultValue () { + return getGlobalDispatcher() + } + }, + { + key: 'headers', + converter: webidl.nullableConverter(webidl.converters.HeadersInit) } +]) - if(this.pauseStreams && this._currentStream && typeof(this._currentStream.resume) == 'function') this._currentStream.resume(); - this.emit('resume'); -}; - -CombinedStream.prototype.end = function() { - this._reset(); - this.emit('end'); -}; +webidl.converters['DOMString or sequence or WebSocketInit'] = function (V) { + if (webidl.util.Type(V) === 'Object' && !(Symbol.iterator in V)) { + return webidl.converters.WebSocketInit(V) + } -CombinedStream.prototype.destroy = function() { - this._reset(); - this.emit('close'); -}; + return { protocols: webidl.converters['DOMString or sequence'](V) } +} -CombinedStream.prototype._reset = function() { - this.writable = false; - this._streams = []; - this._currentStream = null; -}; +webidl.converters.WebSocketSendData = function (V) { + if (webidl.util.Type(V) === 'Object') { + if (isBlobLike(V)) { + return webidl.converters.Blob(V, { strict: false }) + } -CombinedStream.prototype._checkDataSize = function() { - this._updateDataSize(); - if (this.dataSize <= this.maxDataSize) { - return; + if (ArrayBuffer.isView(V) || types.isAnyArrayBuffer(V)) { + return webidl.converters.BufferSource(V) + } } - var message = - 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'; - this._emitError(new Error(message)); -}; + return webidl.converters.USVString(V) +} -CombinedStream.prototype._updateDataSize = function() { - this.dataSize = 0; +module.exports = { + WebSocket +} - var self = this; - this._streams.forEach(function(stream) { - if (!stream.dataSize) { - return; - } - self.dataSize += stream.dataSize; - }); +/***/ }), + +/***/ 5840: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "v1", ({ + enumerable: true, + get: function () { + return _v.default; + } +})); +Object.defineProperty(exports, "v3", ({ + enumerable: true, + get: function () { + return _v2.default; + } +})); +Object.defineProperty(exports, "v4", ({ + enumerable: true, + get: function () { + return _v3.default; + } +})); +Object.defineProperty(exports, "v5", ({ + enumerable: true, + get: function () { + return _v4.default; + } +})); +Object.defineProperty(exports, "NIL", ({ + enumerable: true, + get: function () { + return _nil.default; + } +})); +Object.defineProperty(exports, "version", ({ + enumerable: true, + get: function () { + return _version.default; + } +})); +Object.defineProperty(exports, "validate", ({ + enumerable: true, + get: function () { + return _validate.default; + } +})); +Object.defineProperty(exports, "stringify", ({ + enumerable: true, + get: function () { + return _stringify.default; + } +})); +Object.defineProperty(exports, "parse", ({ + enumerable: true, + get: function () { + return _parse.default; + } +})); + +var _v = _interopRequireDefault(__nccwpck_require__(8628)); - if (this._currentStream && this._currentStream.dataSize) { - this.dataSize += this._currentStream.dataSize; - } -}; +var _v2 = _interopRequireDefault(__nccwpck_require__(6409)); -CombinedStream.prototype._emitError = function(err) { - this._reset(); - this.emit('error', err); -}; +var _v3 = _interopRequireDefault(__nccwpck_require__(5122)); +var _v4 = _interopRequireDefault(__nccwpck_require__(9120)); -/***/ }), +var _nil = _interopRequireDefault(__nccwpck_require__(5332)); -/***/ 2959: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +var _version = _interopRequireDefault(__nccwpck_require__(1595)); -var Stream = (__nccwpck_require__(2781).Stream); -var util = __nccwpck_require__(3837); +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); -module.exports = DelayedStream; -function DelayedStream() { - this.source = null; - this.dataSize = 0; - this.maxDataSize = 1024 * 1024; - this.pauseStream = true; +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); - this._maxDataSizeExceeded = false; - this._released = false; - this._bufferedEvents = []; -} -util.inherits(DelayedStream, Stream); +var _parse = _interopRequireDefault(__nccwpck_require__(2746)); -DelayedStream.create = function(source, options) { - var delayedStream = new this(); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - options = options || {}; - for (var option in options) { - delayedStream[option] = options[option]; - } +/***/ }), - delayedStream.source = source; +/***/ 4569: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - var realEmit = source.emit; - source.emit = function() { - delayedStream._handleEmit(arguments); - return realEmit.apply(source, arguments); - }; +"use strict"; - source.on('error', function() {}); - if (delayedStream.pauseStream) { - source.pause(); - } - return delayedStream; -}; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; -Object.defineProperty(DelayedStream.prototype, 'readable', { - configurable: true, - enumerable: true, - get: function() { - return this.source.readable; - } -}); +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); -DelayedStream.prototype.setEncoding = function() { - return this.source.setEncoding.apply(this.source, arguments); -}; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -DelayedStream.prototype.resume = function() { - if (!this._released) { - this.release(); +function md5(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); } - this.source.resume(); -}; + return _crypto.default.createHash('md5').update(bytes).digest(); +} -DelayedStream.prototype.pause = function() { - this.source.pause(); -}; +var _default = md5; +exports["default"] = _default; -DelayedStream.prototype.release = function() { - this._released = true; +/***/ }), - this._bufferedEvents.forEach(function(args) { - this.emit.apply(this, args); - }.bind(this)); - this._bufferedEvents = []; -}; +/***/ 5332: +/***/ ((__unused_webpack_module, exports) => { -DelayedStream.prototype.pipe = function() { - var r = Stream.prototype.pipe.apply(this, arguments); - this.resume(); - return r; -}; +"use strict"; -DelayedStream.prototype._handleEmit = function(args) { - if (this._released) { - this.emit.apply(this, args); - return; - } - if (args[0] === 'data') { - this.dataSize += args[1].length; - this._checkIfMaxDataSizeExceeded(); - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _default = '00000000-0000-0000-0000-000000000000'; +exports["default"] = _default; - this._bufferedEvents.push(args); -}; +/***/ }), -DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() { - if (this._maxDataSizeExceeded) { - return; - } +/***/ 2746: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (this.dataSize <= this.maxDataSize) { - return; - } +"use strict"; - this._maxDataSizeExceeded = true; - var message = - 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.' - this.emit('error', new Error(message)); -}; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; -/***/ }), +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); -/***/ 5685: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var CombinedStream = __nccwpck_require__(3141); -var util = __nccwpck_require__(3837); -var path = __nccwpck_require__(1017); -var http = __nccwpck_require__(3685); -var https = __nccwpck_require__(5687); -var parseUrl = (__nccwpck_require__(7310).parse); -var fs = __nccwpck_require__(7147); -var mime = __nccwpck_require__(4991); -var asynckit = __nccwpck_require__(3922); -var populate = __nccwpck_require__(3061); +function parse(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } -// Public API -module.exports = FormData; + let v; + const arr = new Uint8Array(16); // Parse ########-....-....-....-............ -// make it a Stream -util.inherits(FormData, CombinedStream); + arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; + arr[1] = v >>> 16 & 0xff; + arr[2] = v >>> 8 & 0xff; + arr[3] = v & 0xff; // Parse ........-####-....-....-............ -/** - * Create readable "multipart/form-data" streams. - * Can be used to submit forms - * and file uploads to other web applications. - * - * @constructor - * @param {Object} options - Properties to be added/overriden for FormData and CombinedStream - */ -function FormData(options) { - if (!(this instanceof FormData)) { - return new FormData(); - } + arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; + arr[5] = v & 0xff; // Parse ........-....-####-....-............ - this._overheadLength = 0; - this._valueLength = 0; - this._valuesToMeasure = []; + arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; + arr[7] = v & 0xff; // Parse ........-....-....-####-............ - CombinedStream.call(this); + arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; + arr[9] = v & 0xff; // Parse ........-....-....-....-############ + // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) - options = options || {}; - for (var option in options) { - this[option] = options[option]; - } + arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff; + arr[11] = v / 0x100000000 & 0xff; + arr[12] = v >>> 24 & 0xff; + arr[13] = v >>> 16 & 0xff; + arr[14] = v >>> 8 & 0xff; + arr[15] = v & 0xff; + return arr; } -FormData.LINE_BREAK = '\r\n'; -FormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream'; +var _default = parse; +exports["default"] = _default; -FormData.prototype.append = function(field, value, options) { +/***/ }), - options = options || {}; +/***/ 814: +/***/ ((__unused_webpack_module, exports) => { - // allow filename as single option - if (typeof options == 'string') { - options = {filename: options}; - } +"use strict"; - var append = CombinedStream.prototype.append.bind(this); - // all that streamy business can't handle numbers - if (typeof value == 'number') { - value = '' + value; - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; +exports["default"] = _default; - // https://github.com/felixge/node-form-data/issues/38 - if (util.isArray(value)) { - // Please convert your array into string - // the way web server expects it - this._error(new Error('Arrays are not supported.')); - return; - } +/***/ }), - var header = this._multiPartHeader(field, value, options); - var footer = this._multiPartFooter(); +/***/ 807: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - append(header); - append(value); - append(footer); +"use strict"; - // pass along options.knownLength - this._trackLength(header, value, options); -}; -FormData.prototype._trackLength = function(header, value, options) { - var valueLength = 0; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = rng; + +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - // used w/ getLengthSync(), when length is known. - // e.g. for streaming directly from a remote server, - // w/ a known file a size, and not wanting to wait for - // incoming file to finish to get its size. - if (options.knownLength != null) { - valueLength += +options.knownLength; - } else if (Buffer.isBuffer(value)) { - valueLength = value.length; - } else if (typeof value === 'string') { - valueLength = Buffer.byteLength(value); - } +const rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate - this._valueLength += valueLength; +let poolPtr = rnds8Pool.length; - // @check why add CRLF? does this account for custom/multiple CRLFs? - this._overheadLength += - Buffer.byteLength(header) + - FormData.LINE_BREAK.length; +function rng() { + if (poolPtr > rnds8Pool.length - 16) { + _crypto.default.randomFillSync(rnds8Pool); - // empty or either doesn't have path or not an http response - if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) )) { - return; + poolPtr = 0; } - // no need to bother with the length - if (!options.knownLength) { - this._valuesToMeasure.push(value); - } -}; + return rnds8Pool.slice(poolPtr, poolPtr += 16); +} -FormData.prototype._lengthRetriever = function(value, callback) { +/***/ }), - if (value.hasOwnProperty('fd')) { +/***/ 5274: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - // take read range into a account - // `end` = Infinity –> read file till the end - // - // TODO: Looks like there is bug in Node fs.createReadStream - // it doesn't respect `end` options without `start` options - // Fix it when node fixes it. - // https://github.com/joyent/node/issues/7819 - if (value.end != undefined && value.end != Infinity && value.start != undefined) { +"use strict"; - // when end specified - // no need to calculate range - // inclusive, starts with 0 - callback(null, value.end + 1 - (value.start ? value.start : 0)); - // not that fast snoopy - } else { - // still need to fetch file size from fs - fs.stat(value.path, function(err, stat) { +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - var fileSize; +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); - if (err) { - callback(err); - return; - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - // update final size based on the range options - fileSize = stat.size - (value.start ? value.start : 0); - callback(null, fileSize); - }); - } +function sha1(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); + } - // or http response - } else if (value.hasOwnProperty('httpVersion')) { - callback(null, +value.headers['content-length']); + return _crypto.default.createHash('sha1').update(bytes).digest(); +} - // or request stream http://github.com/mikeal/request - } else if (value.hasOwnProperty('httpModule')) { - // wait till response come back - value.on('response', function(response) { - value.pause(); - callback(null, +response.headers['content-length']); - }); - value.resume(); +var _default = sha1; +exports["default"] = _default; - // something else - } else { - callback('Unknown stream'); - } -}; +/***/ }), -FormData.prototype._multiPartHeader = function(field, value, options) { - // custom header specified (as string)? - // it becomes responsible for boundary - // (e.g. to handle extra CRLFs on .NET servers) - if (typeof options.header == 'string') { - return options.header; - } +/***/ 8950: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - var contentDisposition = this._getContentDisposition(value, options); - var contentType = this._getContentType(value, options); +"use strict"; - var contents = ''; - var headers = { - // add custom disposition as third element or keep it two elements if not - 'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []), - // if no content type. allow it to be empty array - 'Content-Type': [].concat(contentType || []) - }; - // allow custom headers. - if (typeof options.header == 'object') { - populate(headers, options.header); - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - var header; - for (var prop in headers) { - if (!headers.hasOwnProperty(prop)) continue; - header = headers[prop]; +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); - // skip nullish headers. - if (header == null) { - continue; - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - // convert all headers to arrays. - if (!Array.isArray(header)) { - header = [header]; - } +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +const byteToHex = []; - // add non-empty headers. - if (header.length) { - contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK; - } +for (let i = 0; i < 256; ++i) { + byteToHex.push((i + 0x100).toString(16).substr(1)); +} + +function stringify(arr, offset = 0) { + // Note: Be careful editing this code! It's been tuned for performance + // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 + const uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one + // of the following: + // - One or more input array values don't map to a hex octet (leading to + // "undefined" in the uuid) + // - Invalid input values for the RFC `version` or `variant` fields + + if (!(0, _validate.default)(uuid)) { + throw TypeError('Stringified UUID is invalid'); } - return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK; -}; + return uuid; +} -FormData.prototype._getContentDisposition = function(value, options) { +var _default = stringify; +exports["default"] = _default; - var filename - , contentDisposition - ; +/***/ }), - if (typeof options.filepath === 'string') { - // custom filepath for relative paths - filename = path.normalize(options.filepath).replace(/\\/g, '/'); - } else if (options.filename || value.name || value.path) { - // custom filename take precedence - // formidable and the browser add a name property - // fs- and request- streams have path property - filename = path.basename(options.filename || value.name || value.path); - } else if (value.readable && value.hasOwnProperty('httpVersion')) { - // or try http response - filename = path.basename(value.client._httpMessage.path || ''); - } +/***/ 8628: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (filename) { - contentDisposition = 'filename="' + filename + '"'; - } +"use strict"; - return contentDisposition; -}; -FormData.prototype._getContentType = function(value, options) { +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - // use custom content-type above all - var contentType = options.contentType; +var _rng = _interopRequireDefault(__nccwpck_require__(807)); - // or try `name` from formidable, browser - if (!contentType && value.name) { - contentType = mime.lookup(value.name); - } +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); - // or try `path` from fs-, request- streams - if (!contentType && value.path) { - contentType = mime.lookup(value.path); - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - // or if it's http-reponse - if (!contentType && value.readable && value.hasOwnProperty('httpVersion')) { - contentType = value.headers['content-type']; - } +// **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html +let _nodeId; - // or guess it from the filepath or filename - if (!contentType && (options.filepath || options.filename)) { - contentType = mime.lookup(options.filepath || options.filename); - } +let _clockseq; // Previous uuid creation time - // fallback to the default content type if `value` is not simple value - if (!contentType && typeof value == 'object') { - contentType = FormData.DEFAULT_CONTENT_TYPE; - } - return contentType; -}; +let _lastMSecs = 0; +let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details -FormData.prototype._multiPartFooter = function() { - return function(next) { - var footer = FormData.LINE_BREAK; +function v1(options, buf, offset) { + let i = buf && offset || 0; + const b = buf || new Array(16); + options = options || {}; + let node = options.node || _nodeId; + let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 - var lastPart = (this._streams.length === 0); - if (lastPart) { - footer += this._lastBoundary(); + if (node == null || clockseq == null) { + const seedBytes = options.random || (options.rng || _rng.default)(); + + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; + } + + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; } + } // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - next(footer); - }.bind(this); -}; -FormData.prototype._lastBoundary = function() { - return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK; -}; + let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock -FormData.prototype.getHeaders = function(userHeaders) { - var header; - var formHeaders = { - 'content-type': 'multipart/form-data; boundary=' + this.getBoundary() - }; + let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) - for (header in userHeaders) { - if (userHeaders.hasOwnProperty(header)) { - formHeaders[header.toLowerCase()] = userHeaders[header]; - } - } + const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression - return formHeaders; -}; + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval -FormData.prototype.getBoundary = function() { - if (!this._boundary) { - this._generateBoundary(); - } - return this._boundary; -}; + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } // Per 4.2.1.2 Throw error if too many uuids are requested -FormData.prototype.getBuffer = function() { - var dataBuffer = new Buffer.alloc( 0 ); - var boundary = this.getBoundary(); - // Create the form content. Add Line breaks to the end of data. - for (var i = 0, len = this._streams.length; i < len; i++) { - if (typeof this._streams[i] !== 'function') { + if (nsecs >= 10000) { + throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); + } - // Add content to the buffer. - if(Buffer.isBuffer(this._streams[i])) { - dataBuffer = Buffer.concat( [dataBuffer, this._streams[i]]); - }else { - dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(this._streams[i])]); - } + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - // Add break after content. - if (typeof this._streams[i] !== 'string' || this._streams[i].substring( 2, boundary.length + 2 ) !== boundary) { - dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(FormData.LINE_BREAK)] ); - } - } - } + msecs += 12219292800000; // `time_low` - // Add the footer and return the Buffer object. - return Buffer.concat( [dataBuffer, Buffer.from(this._lastBoundary())] ); -}; + const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; // `time_mid` -FormData.prototype._generateBoundary = function() { - // This generates a 50 character boundary similar to those used by Firefox. - // They are optimized for boyer-moore parsing. - var boundary = '--------------------------'; - for (var i = 0; i < 24; i++) { - boundary += Math.floor(Math.random() * 10).toString(16); - } + const tmh = msecs / 0x100000000 * 10000 & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; // `time_high_and_version` - this._boundary = boundary; -}; + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version -// Note: getLengthSync DOESN'T calculate streams length -// As workaround one can calculate file size manually -// and add it as knownLength option -FormData.prototype.getLengthSync = function() { - var knownLength = this._overheadLength + this._valueLength; + b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - // Don't get confused, there are 3 "internal" streams for each keyval pair - // so it basically checks if there is any value added to the form - if (this._streams.length) { - knownLength += this._lastBoundary().length; - } + b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` - // https://github.com/form-data/form-data/issues/40 - if (!this.hasKnownLength()) { - // Some async length retrievers are present - // therefore synchronous length calculation is false. - // Please use getLength(callback) to get proper length - this._error(new Error('Cannot calculate proper length in synchronous way.')); + b[i++] = clockseq & 0xff; // `node` + + for (let n = 0; n < 6; ++n) { + b[i + n] = node[n]; } - return knownLength; -}; + return buf || (0, _stringify.default)(b); +} -// Public API to check if length of added values is known -// https://github.com/form-data/form-data/issues/196 -// https://github.com/form-data/form-data/issues/262 -FormData.prototype.hasKnownLength = function() { - var hasKnownLength = true; +var _default = v1; +exports["default"] = _default; - if (this._valuesToMeasure.length) { - hasKnownLength = false; - } +/***/ }), - return hasKnownLength; -}; +/***/ 6409: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -FormData.prototype.getLength = function(cb) { - var knownLength = this._overheadLength + this._valueLength; +"use strict"; - if (this._streams.length) { - knownLength += this._lastBoundary().length; - } - if (!this._valuesToMeasure.length) { - process.nextTick(cb.bind(this, null, knownLength)); - return; - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function(err, values) { - if (err) { - cb(err); - return; - } +var _v = _interopRequireDefault(__nccwpck_require__(5998)); - values.forEach(function(length) { - knownLength += length; - }); +var _md = _interopRequireDefault(__nccwpck_require__(4569)); - cb(null, knownLength); - }); -}; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -FormData.prototype.submit = function(params, cb) { - var request - , options - , defaults = {method: 'post'} - ; +const v3 = (0, _v.default)('v3', 0x30, _md.default); +var _default = v3; +exports["default"] = _default; - // parse provided url if it's string - // or treat it as options object - if (typeof params == 'string') { +/***/ }), - params = parseUrl(params); - options = populate({ - port: params.port, - path: params.pathname, - host: params.hostname, - protocol: params.protocol - }, defaults); +/***/ 5998: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - // use custom params - } else { +"use strict"; - options = populate(params, defaults); - // if no port provided use default one - if (!options.port) { - options.port = options.protocol == 'https:' ? 443 : 80; - } - } - // put that good code in getHeaders to some use - options.headers = this.getHeaders(params.headers); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = _default; +exports.URL = exports.DNS = void 0; - // https if specified, fallback to http in any other case - if (options.protocol == 'https:') { - request = https.request(options); - } else { - request = http.request(options); - } +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); - // get content length and fire away - this.getLength(function(err, length) { - if (err) { - this._error(err); - return; - } +var _parse = _interopRequireDefault(__nccwpck_require__(2746)); - // add content length - request.setHeader('Content-Length', length); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - this.pipe(request); - if (cb) { - request.on('error', cb); - request.on('response', cb.bind(this, null)); - } - }.bind(this)); +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape - return request; -}; + const bytes = []; -FormData.prototype._error = function(err) { - if (!this.error) { - this.error = err; - this.pause(); - this.emit('error', err); + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); } -}; - -FormData.prototype.toString = function () { - return '[object FormData]'; -}; + return bytes; +} -/***/ }), +const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +exports.DNS = DNS; +const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +exports.URL = URL; -/***/ 3061: -/***/ ((module) => { +function _default(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + if (typeof value === 'string') { + value = stringToBytes(value); + } -// populates missing values -module.exports = function(dst, src) { + if (typeof namespace === 'string') { + namespace = (0, _parse.default)(namespace); + } - Object.keys(src).forEach(function(prop) - { - dst[prop] = dst[prop] || src[prop]; - }); + if (namespace.length !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` - return dst; -}; + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; -/***/ }), + if (buf) { + offset = offset || 0; -/***/ 3118: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } -/*! - * mime-db - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2015-2022 Douglas Christopher Wilson - * MIT Licensed - */ + return buf; + } -/** - * Module exports. - */ + return (0, _stringify.default)(bytes); + } // Function#name is not settable on some platforms (#270) + + + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support -module.exports = __nccwpck_require__(9857) + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} /***/ }), -/***/ 4991: +/***/ 5122: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -/*! - * mime-types - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2015 Douglas Christopher Wilson - * MIT Licensed - */ +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; -/** - * Module dependencies. - * @private - */ - -var db = __nccwpck_require__(3118) -var extname = (__nccwpck_require__(1017).extname) - -/** - * Module variables. - * @private - */ +var _rng = _interopRequireDefault(__nccwpck_require__(807)); -var EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/ -var TEXT_TYPE_REGEXP = /^text\//i +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); -/** - * Module exports. - * @public - */ +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -exports.charset = charset -exports.charsets = { lookup: charset } -exports.contentType = contentType -exports.extension = extension -exports.extensions = Object.create(null) -exports.lookup = lookup -exports.types = Object.create(null) +function v4(options, buf, offset) { + options = options || {}; -// Populate the extensions/types maps -populateMaps(exports.extensions, exports.types) + const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` -/** - * Get the default charset for a MIME type. - * - * @param {string} type - * @return {boolean|string} - */ -function charset (type) { - if (!type || typeof type !== 'string') { - return false - } + rnds[6] = rnds[6] & 0x0f | 0x40; + rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided - // TODO: use media-typer - var match = EXTRACT_TYPE_REGEXP.exec(type) - var mime = match && db[match[1].toLowerCase()] + if (buf) { + offset = offset || 0; - if (mime && mime.charset) { - return mime.charset - } + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } - // default text/* to utf-8 - if (match && TEXT_TYPE_REGEXP.test(match[1])) { - return 'UTF-8' + return buf; } - return false + return (0, _stringify.default)(rnds); } -/** - * Create a full Content-Type header given a MIME type or extension. - * - * @param {string} str - * @return {boolean|string} - */ +var _default = v4; +exports["default"] = _default; -function contentType (str) { - // TODO: should this even be in this module? - if (!str || typeof str !== 'string') { - return false - } +/***/ }), - var mime = str.indexOf('/') === -1 - ? exports.lookup(str) - : str +/***/ 9120: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (!mime) { - return false - } +"use strict"; - // TODO: use content-type or other module - if (mime.indexOf('charset') === -1) { - var charset = exports.charset(mime) - if (charset) mime += '; charset=' + charset.toLowerCase() - } - return mime -} +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; -/** - * Get the default extension for a MIME type. - * - * @param {string} type - * @return {boolean|string} - */ +var _v = _interopRequireDefault(__nccwpck_require__(5998)); -function extension (type) { - if (!type || typeof type !== 'string') { - return false - } +var _sha = _interopRequireDefault(__nccwpck_require__(5274)); - // TODO: use media-typer - var match = EXTRACT_TYPE_REGEXP.exec(type) +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - // get extensions - var exts = match && exports.extensions[match[1].toLowerCase()] +const v5 = (0, _v.default)('v5', 0x50, _sha.default); +var _default = v5; +exports["default"] = _default; - if (!exts || !exts.length) { - return false - } +/***/ }), - return exts[0] -} +/***/ 6900: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -/** - * Lookup the MIME type for a file path/extension. - * - * @param {string} path - * @return {boolean|string} - */ +"use strict"; -function lookup (path) { - if (!path || typeof path !== 'string') { - return false - } - // get the extension ("ext" or ".ext" or full path) - var extension = extname('x.' + path) - .toLowerCase() - .substr(1) +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - if (!extension) { - return false - } +var _regex = _interopRequireDefault(__nccwpck_require__(814)); - return exports.types[extension] || false +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function validate(uuid) { + return typeof uuid === 'string' && _regex.default.test(uuid); } -/** - * Populate the extensions and types maps. - * @private - */ +var _default = validate; +exports["default"] = _default; -function populateMaps (extensions, types) { - // source preference (least -> most) - var preference = ['nginx', 'apache', undefined, 'iana'] +/***/ }), - Object.keys(db).forEach(function forEachMimeType (type) { - var mime = db[type] - var exts = mime.extensions +/***/ 1595: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (!exts || !exts.length) { - return - } +"use strict"; - // mime -> extensions - extensions[type] = exts - // extension -> mime - for (var i = 0; i < exts.length; i++) { - var extension = exts[i] +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - if (types[extension]) { - var from = preference.indexOf(db[types[extension]].source) - var to = preference.indexOf(mime.source) +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); - if (types[extension] !== 'application/octet-stream' && - (from > to || (from === to && types[extension].substr(0, 12) === 'application/'))) { - // skip the remapping - continue - } - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - // set the extension -> mime - types[extension] = type - } - }) +function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + + return parseInt(uuid.substr(14, 1), 16); } +var _default = version; +exports["default"] = _default; /***/ }), @@ -26387,6 +26405,14 @@ module.exports = require("tls"); /***/ }), +/***/ 6224: +/***/ ((module) => { + +"use strict"; +module.exports = require("tty"); + +/***/ }), + /***/ 7310: /***/ ((module) => { @@ -28046,7 +28072,7 @@ module.exports = parseParams /***/ }), -/***/ 9857: +/***/ 3765: /***/ ((module) => { "use strict"; @@ -28112,8 +28138,8 @@ var __webpack_exports__ = {}; */ const core = __nccwpck_require__(2186); -const formData = __nccwpck_require__(5685); -const Mailgun = __nccwpck_require__(5046); +const formData = __nccwpck_require__(4334); +const Mailgun = __nccwpck_require__(4274); const mailgun = new Mailgun(formData); const optionalFields = ['cc', 'text', 'html']; diff --git a/.github/actions/send-email/package-lock.json b/.github/actions/send-email/package-lock.json index 3efe8ace25..b00842b705 100644 --- a/.github/actions/send-email/package-lock.json +++ b/.github/actions/send-email/package-lock.json @@ -10,7 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@actions/core": "^1.10.1", - "mailgun.js": "^3.3.0" + "mailgun.js": "^10.1.0" }, "devDependencies": { "@vercel/ncc": "^0.38.1" @@ -51,15 +51,19 @@ "ncc": "dist/ncc/cli.js" } }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" + "follow-redirects": "^1.15.4", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, "node_modules/base-64": { @@ -67,321 +71,93 @@ "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==" }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", - "dependencies": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" + "delayed-stream": "~1.0.0" }, "engines": { - "node": ">=6" + "node": ">= 0.8" } }, - "node_modules/data-uri-to-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", - "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", - "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { - "node": ">=6" + "node": ">=0.4.0" } }, - "node_modules/fetch-blob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-2.1.2.tgz", - "integrity": "sha512-YKqtUDwqLyfyMnmbw8XD6Q8j9i/HggKtPEI+pZ1+8bvheBu78biSmNaXWusx1TauGqtUUGx/cBb1mKdq2rLYow==", + "node_modules/follow-redirects": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], "engines": { - "node": "^10.17.0 || >=12.3.0" + "node": ">=4.0" }, "peerDependenciesMeta": { - "domexception": { + "debug": { "optional": true } } }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", - "dependencies": { - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", - "dependencies": { - "get-intrinsic": "^1.2.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dependencies": { - "isobject": "^3.0.1" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ky": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/ky/-/ky-0.25.1.tgz", - "integrity": "sha512-PjpCEWlIU7VpiMVrTwssahkYXX1by6NCT0fhTUX34F3DTinARlgMpriuroolugFPcMgpPWrOW4mTb984Qm1RXA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/ky?sponsor=1" - } - }, - "node_modules/ky-universal": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/ky-universal/-/ky-universal-0.8.2.tgz", - "integrity": "sha512-xe0JaOH9QeYxdyGLnzUOVGK4Z6FGvDVzcXFTdrYA1f33MZdEa45sUDaMBy98xQMcsd2XIBrTXRrRYnegcSdgVQ==", - "dependencies": { - "abort-controller": "^3.0.0", - "node-fetch": "3.0.0-beta.9" - }, - "engines": { - "node": ">=10.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/ky-universal?sponsor=1" - }, - "peerDependencies": { - "ky": ">=0.17.0", - "web-streams-polyfill": ">=2.0.0" - }, - "peerDependenciesMeta": { - "web-streams-polyfill": { - "optional": true - } + "node": ">= 6" } }, "node_modules/mailgun.js": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/mailgun.js/-/mailgun.js-3.7.3.tgz", - "integrity": "sha512-DHP9v6dNPRM2puOx4HVJVjQKWzgzpQ5Fh1ICW632qaDVgd/QqGRhOjCoHe12JJqrFkhgDvXBhENYeZDHYdkJHQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/mailgun.js/-/mailgun.js-10.1.0.tgz", + "integrity": "sha512-j2yP5HGT14xwobySPA+y5IZtKW+XxavNySmFt8A/ztXTCmmgd2OEJMX293femA579iXyphjfymXyTQ/DCP9aAg==", "dependencies": { + "axios": "^1.6.0", "base-64": "^1.0.0", - "bluebird": "^3.7.2", - "ky": "^0.25.1", - "ky-universal": "^0.8.2", - "url": "^0.11.0", - "url-join": "0.0.1", - "web-streams-polyfill": "^3.0.1", - "webpack-merge": "^5.4.0" - } - }, - "node_modules/node-fetch": { - "version": "3.0.0-beta.9", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.0.0-beta.9.tgz", - "integrity": "sha512-RdbZCEynH2tH46+tj0ua9caUHVWrd/RHnRfvly2EVdqGmI3ndS1Vn/xjm5KuGejDt2RNDQsVRLPNd2QPwcewVg==", - "dependencies": { - "data-uri-to-buffer": "^3.0.1", - "fetch-blob": "^2.1.1" + "url-join": "^4.0.1" }, "engines": { - "node": "^10.17 || >=12.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" + "node": ">=18.0.0" } }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" - }, - "node_modules/qs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", - "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", - "dependencies": { - "side-channel": "^1.0.4" - }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.6" } }, - "node_modules/set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "mime-db": "1.52.0" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.6" } }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "node_modules/tunnel": { "version": "0.0.6", @@ -402,19 +178,10 @@ "node": ">=14.0" } }, - "node_modules/url": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", - "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", - "dependencies": { - "punycode": "^1.4.1", - "qs": "^6.11.2" - } - }, "node_modules/url-join": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-0.0.1.tgz", - "integrity": "sha512-H6dnQ/yPAAVzMQRvEvyz01hhfQL5qRWSEt7BX8t9DqnPw9BjMb64fjIRq76Uvf1hkHp+mTZvEVJ5guXOT0Xqaw==" + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" }, "node_modules/uuid": { "version": "8.3.2", @@ -423,32 +190,6 @@ "bin": { "uuid": "dist/bin/uuid" } - }, - "node_modules/web-streams-polyfill": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.2.tgz", - "integrity": "sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" } } } diff --git a/.github/actions/send-email/package.json b/.github/actions/send-email/package.json index 088f74f9ea..69ee369e50 100644 --- a/.github/actions/send-email/package.json +++ b/.github/actions/send-email/package.json @@ -15,7 +15,7 @@ "license": "Apache-2.0", "dependencies": { "@actions/core": "^1.10.1", - "mailgun.js": "^3.3.0" + "mailgun.js": "^10.1.0" }, "devDependencies": { "@vercel/ncc": "^0.38.1" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 68fd5e2cd1..6bec9a5575 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,25 +9,39 @@ jobs: strategy: matrix: - node-version: [14.x, 16.x] + node-version: [14.x] steps: - uses: actions/checkout@v1 + + - name: Send email + uses: ./.github/actions/send-email + with: + api-key: ${{ secrets.OSS_BOT_MAILGUN_KEY }} + domain: ${{ secrets.OSS_BOT_MAILGUN_DOMAIN }} + from: 'GitHub ' + to: ${{ secrets.FIREBASE_ADMIN_GITHUB_EMAIL }} + subject: 'Test email notification' + html: > +

Navigate to the + test workflow. + continue-on-error: true + - name: Set up Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - - name: Install and build - run: | - npm ci - npm run build - npm run build:tests - - name: Lint and run unit tests - run: npm test - - name: Run api-extractor - run: npm run api-extractor - - name: Run emulator-based integration tests - run: | - npm install -g firebase-tools@11.30.0 - firebase emulators:exec --project fake-project-id --only auth,database,firestore \ - 'npx mocha \"test/integration/{auth,database,firestore}.spec.ts\" --slow 5000 --timeout 20000 --require ts-node/register' + # - name: Install and build + # run: | + # npm ci + # npm run build + # npm run build:tests + # - name: Lint and run unit tests + # run: npm test + # - name: Run api-extractor + # run: npm run api-extractor + # - name: Run emulator-based integration tests + # run: | + # npm install -g firebase-tools@11.30.0 + # firebase emulators:exec --project fake-project-id --only auth,database,firestore \ + # 'npx mocha \"test/integration/{auth,database,firestore}.spec.ts\" --slow 5000 --timeout 20000 --require ts-node/register' From 332b04ae6c26d696d06f40efd6319ca41c4c4726 Mon Sep 17 00:00:00 2001 From: Jonathan Edey Date: Wed, 7 Feb 2024 16:36:35 -0500 Subject: [PATCH 2/2] remove send-email, used for verifying, from ci --- .github/workflows/ci.yml | 44 ++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 29 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6bec9a5575..68fd5e2cd1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,39 +9,25 @@ jobs: strategy: matrix: - node-version: [14.x] + node-version: [14.x, 16.x] steps: - uses: actions/checkout@v1 - - - name: Send email - uses: ./.github/actions/send-email - with: - api-key: ${{ secrets.OSS_BOT_MAILGUN_KEY }} - domain: ${{ secrets.OSS_BOT_MAILGUN_DOMAIN }} - from: 'GitHub ' - to: ${{ secrets.FIREBASE_ADMIN_GITHUB_EMAIL }} - subject: 'Test email notification' - html: > -

Navigate to the - test workflow. - continue-on-error: true - - name: Set up Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - # - name: Install and build - # run: | - # npm ci - # npm run build - # npm run build:tests - # - name: Lint and run unit tests - # run: npm test - # - name: Run api-extractor - # run: npm run api-extractor - # - name: Run emulator-based integration tests - # run: | - # npm install -g firebase-tools@11.30.0 - # firebase emulators:exec --project fake-project-id --only auth,database,firestore \ - # 'npx mocha \"test/integration/{auth,database,firestore}.spec.ts\" --slow 5000 --timeout 20000 --require ts-node/register' + - name: Install and build + run: | + npm ci + npm run build + npm run build:tests + - name: Lint and run unit tests + run: npm test + - name: Run api-extractor + run: npm run api-extractor + - name: Run emulator-based integration tests + run: | + npm install -g firebase-tools@11.30.0 + firebase emulators:exec --project fake-project-id --only auth,database,firestore \ + 'npx mocha \"test/integration/{auth,database,firestore}.spec.ts\" --slow 5000 --timeout 20000 --require ts-node/register'