From b616adddba77b36e640be027a5b86cfb1b8a40dd Mon Sep 17 00:00:00 2001 From: huytr1995 Date: Thu, 25 Aug 2022 12:09:41 -0700 Subject: [PATCH] Fix Blurry issue by forcing rebuild ObjectUrl in PageRenderContext --- ui/library/dist/index.d.ts | 2 ++ ui/library/dist/pdf-components.js | 2 +- ui/library/src/components/ZoomInButton.tsx | 3 ++- ui/library/src/components/ZoomOutButton.tsx | 3 ++- ui/library/src/context/PageRenderContext.ts | 12 ++++++++---- ui/library/src/context/TransformContext.ts | 9 +++++++++ 6 files changed, 24 insertions(+), 7 deletions(-) diff --git a/ui/library/dist/index.d.ts b/ui/library/dist/index.d.ts index 736bd859..2158f870 100644 --- a/ui/library/dist/index.d.ts +++ b/ui/library/dist/index.d.ts @@ -331,9 +331,11 @@ declare module '@allenai/pdf-components/src/context/TransformContext' { rotation: PageRotation; scale: number; zoomMultiplier: number; + isScaleChanged: boolean; setRotation: (rotation: PageRotation) => void; setScale: (scale: number) => void; setZoomMultiplier: (zoom: number) => void; + setIsScaleChanged: (isScaleChange: boolean) => void; } export const TransformContext: React.Context; export function useTransformContextProps(): ITransformContext; diff --git a/ui/library/dist/pdf-components.js b/ui/library/dist/pdf-components.js index bd015828..2244770b 100644 --- a/ui/library/dist/pdf-components.js +++ b/ui/library/dist/pdf-components.js @@ -1 +1 @@ -!function(n,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react")):"function"==typeof define&&define.amd?define(["react"],t):"object"==typeof exports?exports["@allenai/pdf-components"]=t(require("react")):n["@allenai/pdf-components"]=t(n.React)}(this,(function(__WEBPACK_EXTERNAL_MODULE__888__){return(()=>{var __webpack_modules__={822:module=>{"use strict";eval("/*\nobject-assign\n(c) Sindre Sorhus\n@license MIT\n*/\n\n\n/* eslint-disable no-unused-vars */\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\nfunction toObject(val) {\n\tif (val === null || val === undefined) {\n\t\tthrow new TypeError('Object.assign cannot be called with null or undefined');\n\t}\n\n\treturn Object(val);\n}\n\nfunction shouldUseNative() {\n\ttry {\n\t\tif (!Object.assign) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Detect buggy property enumeration order in older V8 versions.\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=4118\n\t\tvar test1 = new String('abc'); // eslint-disable-line no-new-wrappers\n\t\ttest1[5] = 'de';\n\t\tif (Object.getOwnPropertyNames(test1)[0] === '5') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test2 = {};\n\t\tfor (var i = 0; i < 10; i++) {\n\t\t\ttest2['_' + String.fromCharCode(i)] = i;\n\t\t}\n\t\tvar order2 = Object.getOwnPropertyNames(test2).map(function (n) {\n\t\t\treturn test2[n];\n\t\t});\n\t\tif (order2.join('') !== '0123456789') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test3 = {};\n\t\t'abcdefghijklmnopqrst'.split('').forEach(function (letter) {\n\t\t\ttest3[letter] = letter;\n\t\t});\n\t\tif (Object.keys(Object.assign({}, test3)).join('') !==\n\t\t\t\t'abcdefghijklmnopqrst') {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} catch (err) {\n\t\t// We don't expect any of the above to throw, but better to be safe.\n\t\treturn false;\n\t}\n}\n\nmodule.exports = shouldUseNative() ? Object.assign : function (target, source) {\n\tvar from;\n\tvar to = toObject(target);\n\tvar symbols;\n\n\tfor (var s = 1; s < arguments.length; s++) {\n\t\tfrom = Object(arguments[s]);\n\n\t\tfor (var key in from) {\n\t\t\tif (hasOwnProperty.call(from, key)) {\n\t\t\t\tto[key] = from[key];\n\t\t\t}\n\t\t}\n\n\t\tif (getOwnPropertySymbols) {\n\t\t\tsymbols = getOwnPropertySymbols(from);\n\t\t\tfor (var i = 0; i < symbols.length; i++) {\n\t\t\t\tif (propIsEnumerable.call(from, symbols[i])) {\n\t\t\t\t\tto[symbols[i]] = from[symbols[i]];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn to;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uLi9kZW1vL25vZGVfbW9kdWxlcy9vYmplY3QtYXNzaWduL2luZGV4LmpzPzYyMTIiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFYTtBQUNiO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLGdDQUFnQztBQUNoQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILGtDQUFrQztBQUNsQztBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZ0JBQWdCLHNCQUFzQjtBQUN0Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxrQkFBa0Isb0JBQW9CO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBIiwiZmlsZSI6IjgyMi5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG5vYmplY3QtYXNzaWduXG4oYykgU2luZHJlIFNvcmh1c1xuQGxpY2Vuc2UgTUlUXG4qL1xuXG4ndXNlIHN0cmljdCc7XG4vKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtdmFycyAqL1xudmFyIGdldE93blByb3BlcnR5U3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xudmFyIHByb3BJc0VudW1lcmFibGUgPSBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlO1xuXG5mdW5jdGlvbiB0b09iamVjdCh2YWwpIHtcblx0aWYgKHZhbCA9PT0gbnVsbCB8fCB2YWwgPT09IHVuZGVmaW5lZCkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ09iamVjdC5hc3NpZ24gY2Fubm90IGJlIGNhbGxlZCB3aXRoIG51bGwgb3IgdW5kZWZpbmVkJyk7XG5cdH1cblxuXHRyZXR1cm4gT2JqZWN0KHZhbCk7XG59XG5cbmZ1bmN0aW9uIHNob3VsZFVzZU5hdGl2ZSgpIHtcblx0dHJ5IHtcblx0XHRpZiAoIU9iamVjdC5hc3NpZ24pIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBEZXRlY3QgYnVnZ3kgcHJvcGVydHkgZW51bWVyYXRpb24gb3JkZXIgaW4gb2xkZXIgVjggdmVyc2lvbnMuXG5cblx0XHQvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD00MTE4XG5cdFx0dmFyIHRlc3QxID0gbmV3IFN0cmluZygnYWJjJyk7ICAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ldy13cmFwcGVyc1xuXHRcdHRlc3QxWzVdID0gJ2RlJztcblx0XHRpZiAoT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGVzdDEpWzBdID09PSAnNScpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0zMDU2XG5cdFx0dmFyIHRlc3QyID0ge307XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCAxMDsgaSsrKSB7XG5cdFx0XHR0ZXN0MlsnXycgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKGkpXSA9IGk7XG5cdFx0fVxuXHRcdHZhciBvcmRlcjIgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0ZXN0MikubWFwKGZ1bmN0aW9uIChuKSB7XG5cdFx0XHRyZXR1cm4gdGVzdDJbbl07XG5cdFx0fSk7XG5cdFx0aWYgKG9yZGVyMi5qb2luKCcnKSAhPT0gJzAxMjM0NTY3ODknKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzA1NlxuXHRcdHZhciB0ZXN0MyA9IHt9O1xuXHRcdCdhYmNkZWZnaGlqa2xtbm9wcXJzdCcuc3BsaXQoJycpLmZvckVhY2goZnVuY3Rpb24gKGxldHRlcikge1xuXHRcdFx0dGVzdDNbbGV0dGVyXSA9IGxldHRlcjtcblx0XHR9KTtcblx0XHRpZiAoT2JqZWN0LmtleXMoT2JqZWN0LmFzc2lnbih7fSwgdGVzdDMpKS5qb2luKCcnKSAhPT1cblx0XHRcdFx0J2FiY2RlZmdoaWprbG1ub3BxcnN0Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHJldHVybiB0cnVlO1xuXHR9IGNhdGNoIChlcnIpIHtcblx0XHQvLyBXZSBkb24ndCBleHBlY3QgYW55IG9mIHRoZSBhYm92ZSB0byB0aHJvdywgYnV0IGJldHRlciB0byBiZSBzYWZlLlxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNob3VsZFVzZU5hdGl2ZSgpID8gT2JqZWN0LmFzc2lnbiA6IGZ1bmN0aW9uICh0YXJnZXQsIHNvdXJjZSkge1xuXHR2YXIgZnJvbTtcblx0dmFyIHRvID0gdG9PYmplY3QodGFyZ2V0KTtcblx0dmFyIHN5bWJvbHM7XG5cblx0Zm9yICh2YXIgcyA9IDE7IHMgPCBhcmd1bWVudHMubGVuZ3RoOyBzKyspIHtcblx0XHRmcm9tID0gT2JqZWN0KGFyZ3VtZW50c1tzXSk7XG5cblx0XHRmb3IgKHZhciBrZXkgaW4gZnJvbSkge1xuXHRcdFx0aWYgKGhhc093blByb3BlcnR5LmNhbGwoZnJvbSwga2V5KSkge1xuXHRcdFx0XHR0b1trZXldID0gZnJvbVtrZXldO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChnZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHtcblx0XHRcdHN5bWJvbHMgPSBnZXRPd25Qcm9wZXJ0eVN5bWJvbHMoZnJvbSk7XG5cdFx0XHRmb3IgKHZhciBpID0gMDsgaSA8IHN5bWJvbHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0aWYgKHByb3BJc0VudW1lcmFibGUuY2FsbChmcm9tLCBzeW1ib2xzW2ldKSkge1xuXHRcdFx0XHRcdHRvW3N5bWJvbHNbaV1dID0gZnJvbVtzeW1ib2xzW2ldXTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiB0bztcbn07XG4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///822\n")},692:(__unused_webpack_module,exports,__webpack_require__)=>{"use strict";eval('var __webpack_unused_export__;\n/** @license React v17.0.2\n * react-dom-server.browser.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nvar l=__webpack_require__(822),m=__webpack_require__(888);function p(a){for(var b="https://reactjs.org/docs/error-decoder.html?invariant="+a,c=1;cK;K++)J[K]=K+1;J[15]=0;var oa=/^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD][:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$/,pa=Object.prototype.hasOwnProperty,qa={},ra={};\nfunction sa(a){if(pa.call(ra,a))return!0;if(pa.call(qa,a))return!1;if(oa.test(a))return ra[a]=!0;qa[a]=!0;return!1}function ta(a,b,c,d){if(null!==c&&0===c.type)return!1;switch(typeof b){case "function":case "symbol":return!0;case "boolean":if(d)return!1;if(null!==c)return!c.acceptsBooleans;a=a.toLowerCase().slice(0,5);return"data-"!==a&&"aria-"!==a;default:return!1}}\nfunction ua(a,b,c,d){if(null===b||"undefined"===typeof b||ta(a,b,c,d))return!0;if(d)return!1;if(null!==c)switch(c.type){case 3:return!b;case 4:return!1===b;case 5:return isNaN(b);case 6:return isNaN(b)||1>b}return!1}function M(a,b,c,d,f,h,t){this.acceptsBooleans=2===b||3===b||4===b;this.attributeName=d;this.attributeNamespace=f;this.mustUseProperty=c;this.propertyName=a;this.type=b;this.sanitizeURL=h;this.removeEmptyString=t}var N={};\n"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(a){N[a]=new M(a,0,!1,a,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(a){var b=a[0];N[b]=new M(b,1,!1,a[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(a){N[a]=new M(a,2,!1,a.toLowerCase(),null,!1,!1)});\n["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(a){N[a]=new M(a,2,!1,a,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(a){N[a]=new M(a,3,!1,a.toLowerCase(),null,!1,!1)});\n["checked","multiple","muted","selected"].forEach(function(a){N[a]=new M(a,3,!0,a,null,!1,!1)});["capture","download"].forEach(function(a){N[a]=new M(a,4,!1,a,null,!1,!1)});["cols","rows","size","span"].forEach(function(a){N[a]=new M(a,6,!1,a,null,!1,!1)});["rowSpan","start"].forEach(function(a){N[a]=new M(a,5,!1,a.toLowerCase(),null,!1,!1)});var va=/[\\-:]([a-z])/g;function wa(a){return a[1].toUpperCase()}\n"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(a){var b=a.replace(va,\nwa);N[b]=new M(b,1,!1,a,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(a){var b=a.replace(va,wa);N[b]=new M(b,1,!1,a,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(a){var b=a.replace(va,wa);N[b]=new M(b,1,!1,a,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(a){N[a]=new M(a,1,!1,a.toLowerCase(),null,!1,!1)});\nN.xlinkHref=new M("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(a){N[a]=new M(a,1,!1,a.toLowerCase(),null,!0,!0)});var xa=/["\'&<>]/;\nfunction O(a){if("boolean"===typeof a||"number"===typeof a)return""+a;a=""+a;var b=xa.exec(a);if(b){var c="",d,f=0;for(d=b.index;dV))throw Error(p(301));if(a===P)if(T=!0,a={action:c,next:null},null===U&&(U=new Map),c=U.get(b),void 0===c)U.set(b,a);else{for(b=c;null!==b.next;)b=b.next;b.next=a}}function Ja(){}\nvar X=null,Ka={readContext:function(a){var b=X.threadID;I(a,b);return a[b]},useContext:function(a){W();var b=X.threadID;I(a,b);return a[b]},useMemo:Ia,useReducer:Ga,useRef:function(a){P=W();R=Ca();var b=R.memoizedState;return null===b?(a={current:a},R.memoizedState=a):b},useState:function(a){return Ga(Fa,a)},useLayoutEffect:function(){},useCallback:function(a,b){return Ia(function(){return a},b)},useImperativeHandle:Ja,useEffect:Ja,useDebugValue:Ja,useDeferredValue:function(a){W();return a},useTransition:function(){W();\nreturn[function(a){a()},!1]},useOpaqueIdentifier:function(){return(X.identifierPrefix||"")+"R:"+(X.uniqueID++).toString(36)},useMutableSource:function(a,b){W();return b(a._source)}},La={html:"http://www.w3.org/1999/xhtml",mathml:"http://www.w3.org/1998/Math/MathML",svg:"http://www.w3.org/2000/svg"};function Ma(a){switch(a){case "svg":return"http://www.w3.org/2000/svg";case "math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}\nvar Na={area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},Oa=l({menuitem:!0},Na),Y={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,\ngridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Pa=["Webkit","ms","Moz","O"];Object.keys(Y).forEach(function(a){Pa.forEach(function(b){b=b+a.charAt(0).toUpperCase()+a.substring(1);Y[b]=Y[a]})});\nvar Qa=/([A-Z])/g,Ra=/^ms-/,Z=m.Children.toArray,Sa=la.ReactCurrentDispatcher,Ta={listing:!0,pre:!0,textarea:!0},Ua=/^[a-zA-Z][a-zA-Z:_\\.\\-\\d]*$/,Va={},Wa={};function Xa(a){if(void 0===a||null===a)return a;var b="";m.Children.forEach(a,function(a){null!=a&&(b+=a)});return b}var Ya=Object.prototype.hasOwnProperty,Za={children:null,dangerouslySetInnerHTML:null,suppressContentEditableWarning:null,suppressHydrationWarning:null};function $a(a,b){if(void 0===a)throw Error(p(152,F(b)||"Component"));}\nfunction ab(a,b,c){function d(d,h){var e=h.prototype&&h.prototype.isReactComponent,f=na(h,b,c,e),t=[],g=!1,n={isMounted:function(){return!1},enqueueForceUpdate:function(){if(null===t)return null},enqueueReplaceState:function(a,c){g=!0;t=[c]},enqueueSetState:function(a,c){if(null===t)return null;t.push(c)}};if(e){if(e=new h(d.props,f,n),"function"===typeof h.getDerivedStateFromProps){var k=h.getDerivedStateFromProps.call(null,d.props,e.state);null!=k&&(e.state=l({},e.state,k))}}else if(P={},e=h(d.props,\nf,n),e=Da(h,d.props,e,f),null==e||null==e.render){a=e;$a(a,h);return}e.props=d.props;e.context=f;e.updater=n;n=e.state;void 0===n&&(e.state=n=null);if("function"===typeof e.UNSAFE_componentWillMount||"function"===typeof e.componentWillMount)if("function"===typeof e.componentWillMount&&"function"!==typeof h.getDerivedStateFromProps&&e.componentWillMount(),"function"===typeof e.UNSAFE_componentWillMount&&"function"!==typeof h.getDerivedStateFromProps&&e.UNSAFE_componentWillMount(),t.length){n=t;var v=\ng;t=null;g=!1;if(v&&1===n.length)e.state=n[0];else{k=v?n[0]:e.state;var H=!0;for(v=v?1:0;v=g))throw Error(p(304));var e=new Uint16Array(g);e.set(d);J=e;J[0]=c+1;for(d=c;d=e.children.length){var L=e.footer;""!==L&&(this.previousWasTextNode=!1);this.stack.pop();if("select"===e.type)this.currentSelectValue=null;else if(null!=e.type&&null!=e.type.type&&e.type.type.$$typeof===B)this.popProvider(e.type);else if(e.type===D){this.suspenseDepth--;var G=h.pop();if(t){t=!1;var C=e.fallbackFrame;if(!C)throw Error(p(303));this.stack.push(C);h[this.suspenseDepth]+="\\x3c!--$!--\\x3e";continue}else h[this.suspenseDepth]+=\nG}h[this.suspenseDepth]+=L}else{var n=e.children[e.childIndex++],k="";try{k+=this.render(n,e.context,e.domNamespace)}catch(v){if(null!=v&&"function"===typeof v.then)throw Error(p(294));throw v;}finally{}h.length<=this.suspenseDepth&&h.push("");h[this.suspenseDepth]+=k}}return h[0]}finally{Sa.current=c,X=b,Ea()}};b.render=function(a,b,f){if("string"===typeof a||"number"===typeof a){f=""+a;if(""===f)return"";if(this.makeStaticMarkup)return O(f);if(this.previousWasTextNode)return"\\x3c!-- --\\x3e"+O(f);\nthis.previousWasTextNode=!0;return O(f)}b=ab(a,b,this.threadID);a=b.child;b=b.context;if(null===a||!1===a)return"";if(!m.isValidElement(a)){if(null!=a&&null!=a.$$typeof){f=a.$$typeof;if(f===q)throw Error(p(257));throw Error(p(258,f.toString()));}a=Z(a);this.stack.push({type:null,domNamespace:f,children:a,childIndex:0,context:b,footer:""});return""}var c=a.type;if("string"===typeof c)return this.renderDOM(a,b,f);switch(c){case ka:case ja:case u:case z:case ca:case r:return a=Z(a.props.children),this.stack.push({type:null,\ndomNamespace:f,children:a,childIndex:0,context:b,footer:""}),"";case D:throw Error(p(294));case ia:throw Error(p(343));}if("object"===typeof c&&null!==c)switch(c.$$typeof){case ba:P={};var d=c.render(a.props,a.ref);d=Da(c.render,a.props,d,a.ref);d=Z(d);this.stack.push({type:null,domNamespace:f,children:d,childIndex:0,context:b,footer:""});return"";case da:return a=[m.createElement(c.type,l({ref:a.ref},a.props))],this.stack.push({type:null,domNamespace:f,children:a,childIndex:0,context:b,footer:""}),\n"";case B:return c=Z(a.props.children),f={type:a,domNamespace:f,children:c,childIndex:0,context:b,footer:""},this.pushProvider(a),this.stack.push(f),"";case aa:c=a.type;d=a.props;var g=this.threadID;I(c,g);c=Z(d.children(c[g]));this.stack.push({type:a,domNamespace:f,children:c,childIndex:0,context:b,footer:""});return"";case ha:throw Error(p(338));case ea:return c=a.type,d=c._init,c=d(c._payload),a=[m.createElement(c,l({ref:a.ref},a.props))],this.stack.push({type:null,domNamespace:f,children:a,childIndex:0,\ncontext:b,footer:""}),""}throw Error(p(130,null==c?c:typeof c,""));};b.renderDOM=function(a,b,f){var c=a.type.toLowerCase();f===La.html&&Ma(c);if(!Va.hasOwnProperty(c)){if(!Ua.test(c))throw Error(p(65,c));Va[c]=!0}var d=a.props;if("input"===c)d=l({type:void 0},d,{defaultChecked:void 0,defaultValue:void 0,value:null!=d.value?d.value:d.defaultValue,checked:null!=d.checked?d.checked:d.defaultChecked});else if("textarea"===c){var g=d.value;if(null==g){g=d.defaultValue;var e=d.children;if(null!=e){if(null!=\ng)throw Error(p(92));if(Array.isArray(e)){if(!(1>=e.length))throw Error(p(93));e=e[0]}g=""+e}null==g&&(g="")}d=l({},d,{value:void 0,children:""+g})}else if("select"===c)this.currentSelectValue=null!=d.value?d.value:d.defaultValue,d=l({},d,{value:void 0});else if("option"===c){e=this.currentSelectValue;var L=Xa(d.children);if(null!=e){var G=null!=d.value?d.value+"":L;g=!1;if(Array.isArray(e))for(var C=0;C":(w+=">",g="");a:{e=d.dangerouslySetInnerHTML;if(null!=e){if(null!=e.__html){e=e.__html;break a}}else if(e=d.children,"string"===typeof e||"number"===typeof e){e=O(e);break a}e=null}null!=e?(d=[],Ta.hasOwnProperty(c)&&"\\n"===e.charAt(0)&&(w+="\\n"),w+=e):d=Z(d.children);a=a.type;f=null==f||"http://www.w3.org/1999/xhtml"===f?Ma(a):"http://www.w3.org/2000/svg"===\nf&&"foreignObject"===a?"http://www.w3.org/1999/xhtml":f;this.stack.push({domNamespace:f,type:c,children:d,childIndex:0,context:b,footer:g});this.previousWasTextNode=!1;return w};return a}();__webpack_unused_export__=function(){throw Error(p(207));};exports.renderToStaticMarkup=function(a,b){a=new bb(a,!0,b);try{return a.read(Infinity)}finally{a.destroy()}};__webpack_unused_export__=function(){throw Error(p(208));};__webpack_unused_export__=function(a,b){a=new bb(a,!1,b);try{return a.read(Infinity)}finally{a.destroy()}};\n__webpack_unused_export__="17.0.2";\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uLi9kZW1vL25vZGVfbW9kdWxlcy9yZWFjdC1kb20vY2pzL3JlYWN0LWRvbS1zZXJ2ZXIuYnJvd3Nlci5wcm9kdWN0aW9uLm1pbi5qcz9iNzQyIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2EsTUFBTSxtQkFBTyxDQUFDLEdBQWUsSUFBSSxtQkFBTyxDQUFDLEdBQU8sRUFBRSxjQUFjLHlFQUF5RSxtQkFBbUIsbURBQW1ELG1DQUFtQztBQUMvUDtBQUNBLDJDQUEyQyxpQkFBaUIsb0JBQW9CLHNCQUFzQix5QkFBeUIsc0JBQXNCLHNCQUFzQixzQkFBc0IsMEJBQTBCLHNCQUFzQiw0QkFBNEIsbUJBQW1CLG1CQUFtQixvQkFBb0IsMEJBQTBCLG9CQUFvQiwrQkFBK0I7QUFDcFosY0FBYyx1QkFBdUIsNERBQTRELGdDQUFnQyxVQUFVLHdCQUF3QixzQkFBc0Isd0JBQXdCLDBCQUEwQix3QkFBd0IsNkJBQTZCLDBDQUEwQyxxREFBcUQsNkRBQTZELHVCQUF1Qiw0QkFBNEI7QUFDL2UsMENBQTBDLHlCQUF5Qiw0QkFBNEIscUJBQXFCLFVBQVUsSUFBSSxlQUFlLFdBQVcsWUFBWSxrRUFBa0UsZ0JBQWdCLDJCQUEyQixLQUFLLDZDQUE2QyxxQkFBcUIseUVBQXlFLHFCQUFxQixLQUFLLHlCQUF5QixJQUFJLFVBQVU7QUFDdGUsa0NBQWtDLEtBQUssYUFBYSxRQUFRLDZZQUE2WTtBQUN6YyxlQUFlLDBCQUEwQiwwQkFBMEIsOEJBQThCLFNBQVMsU0FBUyxxQkFBcUIsaUNBQWlDLGlCQUFpQix1Q0FBdUMsNkJBQTZCLHFDQUFxQyw2QkFBNkIsK0JBQStCO0FBQy9WLHFCQUFxQiwwREFBMEQsY0FBYywyQkFBMkIsZ0JBQWdCLG9CQUFvQix1QkFBdUIsNEJBQTRCLFNBQVMsMEJBQTBCLHlDQUF5QyxxQkFBcUIsMEJBQTBCLHVC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USxPQUFPLHdGQUF3RixTQUFTO0FBQ2xiLHdEQUF3RCxpQkFBaUIsaUVBQWlFLEVBQUUsNEJBQTRCLFVBQVUsU0FBUyxHQUFHLHlCQUEwQixZQUFZLHNCQUFzQiw0QkFBNEIsZUFBZSxpQkFBaUIsSUFBSSx3QkFBd0IsUUFBUSxjQUFjLHlCQUFnQyxZQUFZLHNCQUFzQix5QkFBc0IsZUFBZSxpQkFBaUIsSUFBSSx3QkFBd0IsUUFBUTtBQUNwZ0IseUJBQWUiLCJmaWxlIjoiNjkyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoqIEBsaWNlbnNlIFJlYWN0IHYxNy4wLjJcbiAqIHJlYWN0LWRvbS1zZXJ2ZXIuYnJvd3Nlci5wcm9kdWN0aW9uLm1pbi5qc1xuICpcbiAqIENvcHlyaWdodCAoYykgRmFjZWJvb2ssIEluYy4gYW5kIGl0cyBhZmZpbGlhdGVzLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICovXG4ndXNlIHN0cmljdCc7dmFyIGw9cmVxdWlyZShcIm9iamVjdC1hc3NpZ25cIiksbT1yZXF1aXJlKFwicmVhY3RcIik7ZnVuY3Rpb24gcChhKXtmb3IodmFyIGI9XCJodHRwczovL3JlYWN0anMub3JnL2RvY3MvZXJyb3ItZGVjb2Rlci5odG1sP2ludmFyaWFudD1cIithLGM9MTtjPGFyZ3VtZW50cy5sZW5ndGg7YysrKWIrPVwiJmFyZ3NbXT1cIitlbmNvZGVVUklDb21wb25lbnQoYXJndW1lbnRzW2NdKTtyZXR1cm5cIk1pbmlmaWVkIFJlYWN0IGVycm9yICNcIithK1wiOyB2aXNpdCBcIitiK1wiIGZvciB0aGUgZnVsbCBtZXNzYWdlIG9yIHVzZSB0aGUgbm9uLW1pbmlmaWVkIGRldiBlbnZpcm9ubWVudCBmb3IgZnVsbCBlcnJvcnMgYW5kIGFkZGl0aW9uYWwgaGVscGZ1bCB3YXJuaW5ncy5cIn1cbnZhciBxPTYwMTA2LHI9NjAxMDcsdT02MDEwOCx6PTYwMTE0LEI9NjAxMDksYWE9NjAxMTAsYmE9NjAxMTIsRD02MDExMyxjYT02MDEyMCxkYT02MDExNSxlYT02MDExNixmYT02MDEyMSxoYT02MDExNyxpYT02MDExOSxqYT02MDEyOSxrYT02MDEzMTtcbmlmKFwiZnVuY3Rpb25cIj09PXR5cGVvZiBTeW1ib2wmJlN5bWJvbC5mb3Ipe3ZhciBFPVN5bWJvbC5mb3I7cT1FKFwicmVhY3QucG9ydGFsXCIpO3I9RShcInJlYWN0LmZyYWdtZW50XCIpO3U9RShcInJlYWN0LnN0cmljdF9tb2RlXCIpO3o9RShcInJlYWN0LnByb2ZpbGVyXCIpO0I9RShcInJlYWN0LnByb3ZpZGVyXCIpO2FhPUUoXCJyZWFjdC5jb250ZXh0XCIpO2JhPUUoXCJyZWFjdC5mb3J3YXJkX3JlZlwiKTtEPUUoXCJyZWFjdC5zdXNwZW5zZVwiKTtjYT1FKFwicmVhY3Quc3VzcGVuc2VfbGlzdFwiKTtkYT1FKFwicmVhY3QubWVtb1wiKTtlYT1FKFwicmVhY3QubGF6eVwiKTtmYT1FKFwicmVhY3QuYmxvY2tcIik7aGE9RShcInJlYWN0LmZ1bmRhbWVudGFsXCIpO2lhPUUoXCJyZWFjdC5zY29wZVwiKTtqYT1FKFwicmVhY3QuZGVidWdfdHJhY2VfbW9kZVwiKTtrYT1FKFwicmVhY3QubGVnYWN5X2hpZGRlblwiKX1cbmZ1bmN0aW9uIEYoYSl7aWYobnVsbD09YSlyZXR1cm4gbnVsbDtpZihcImZ1bmN0aW9uXCI9PT10eXBlb2YgYSlyZXR1cm4gYS5kaXNwbGF5TmFtZXx8YS5uYW1lfHxudWxsO2lmKFwic3RyaW5nXCI9PT10eXBlb2YgYSlyZXR1cm4gYTtzd2l0Y2goYSl7Y2FzZSByOnJldHVyblwiRnJhZ21lbnRcIjtjYXNlIHE6cmV0dXJuXCJQb3J0YWxcIjtjYXNlIHo6cmV0dXJuXCJQcm9maWxlclwiO2Nhc2UgdTpyZXR1cm5cIlN0cmljdE1vZGVcIjtjYXNlIEQ6cmV0dXJuXCJTdXNwZW5zZVwiO2Nhc2UgY2E6cmV0dXJuXCJTdXNwZW5zZUxpc3RcIn1pZihcIm9iamVjdFwiPT09dHlwZW9mIGEpc3dpdGNoKGEuJCR0eXBlb2Ype2Nhc2UgYWE6cmV0dXJuKGEuZGlzcGxheU5hbWV8fFwiQ29udGV4dFwiKStcIi5Db25zdW1lclwiO2Nhc2UgQjpyZXR1cm4oYS5fY29udGV4dC5kaXNwbGF5TmFtZXx8XCJDb250ZXh0XCIpK1wiLlByb3ZpZGVyXCI7Y2FzZSBiYTp2YXIgYj1hLnJlbmRlcjtiPWIuZGlzcGxheU5hbWV8fGIubmFtZXx8XCJcIjtyZXR1cm4gYS5kaXNwbGF5TmFtZXx8XG4oXCJcIiE9PWI/XCJGb3J3YXJkUmVmKFwiK2IrXCIpXCI6XCJGb3J3YXJkUmVmXCIpO2Nhc2UgZGE6cmV0dXJuIEYoYS50eXBlKTtjYXNlIGZhOnJldHVybiBGKGEuX3JlbmRlcik7Y2FzZSBlYTpiPWEuX3BheWxvYWQ7YT1hLl9pbml0O3RyeXtyZXR1cm4gRihhKGIpKX1jYXRjaChjKXt9fXJldHVybiBudWxsfXZhciBsYT1tLl9fU0VDUkVUX0lOVEVSTkFMU19ET19OT1RfVVNFX09SX1lPVV9XSUxMX0JFX0ZJUkVELG1hPXt9O2Z1bmN0aW9uIEkoYSxiKXtmb3IodmFyIGM9YS5fdGhyZWFkQ291bnR8MDtjPD1iO2MrKylhW2NdPWEuX2N1cnJlbnRWYWx1ZTIsYS5fdGhyZWFkQ291bnQ9YysxfWZ1bmN0aW9uIG5hKGEsYixjLGQpe2lmKGQmJihkPWEuY29udGV4dFR5cGUsXCJvYmplY3RcIj09PXR5cGVvZiBkJiZudWxsIT09ZCkpcmV0dXJuIEkoZCxjKSxkW2NdO2lmKGE9YS5jb250ZXh0VHlwZXMpe2M9e307Zm9yKHZhciBmIGluIGEpY1tmXT1iW2ZdO2I9Y31lbHNlIGI9bWE7cmV0dXJuIGJ9XG5mb3IodmFyIEo9bmV3IFVpbnQxNkFycmF5KDE2KSxLPTA7MTU+SztLKyspSltLXT1LKzE7SlsxNV09MDt2YXIgb2E9L15bOkEtWl9hLXpcXHUwMEMwLVxcdTAwRDZcXHUwMEQ4LVxcdTAwRjZcXHUwMEY4LVxcdTAyRkZcXHUwMzcwLVxcdTAzN0RcXHUwMzdGLVxcdTFGRkZcXHUyMDBDLVxcdTIwMERcXHUyMDcwLVxcdTIxOEZcXHUyQzAwLVxcdTJGRUZcXHUzMDAxLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRkRdWzpBLVpfYS16XFx1MDBDMC1cXHUwMEQ2XFx1MDBEOC1cXHUwMEY2XFx1MDBGOC1cXHUwMkZGXFx1MDM3MC1cXHUwMzdEXFx1MDM3Ri1cXHUxRkZGXFx1MjAwQy1cXHUyMDBEXFx1MjA3MC1cXHUyMThGXFx1MkMwMC1cXHUyRkVGXFx1MzAwMS1cXHVEN0ZGXFx1RjkwMC1cXHVGRENGXFx1RkRGMC1cXHVGRkZEXFwtLjAtOVxcdTAwQjdcXHUwMzAwLVxcdTAzNkZcXHUyMDNGLVxcdTIwNDBdKiQvLHBhPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkscWE9e30scmE9e307XG5mdW5jdGlvbiBzYShhKXtpZihwYS5jYWxsKHJhLGEpKXJldHVybiEwO2lmKHBhLmNhbGwocWEsYSkpcmV0dXJuITE7aWYob2EudGVzdChhKSlyZXR1cm4gcmFbYV09ITA7cWFbYV09ITA7cmV0dXJuITF9ZnVuY3Rpb24gdGEoYSxiLGMsZCl7aWYobnVsbCE9PWMmJjA9PT1jLnR5cGUpcmV0dXJuITE7c3dpdGNoKHR5cGVvZiBiKXtjYXNlIFwiZnVuY3Rpb25cIjpjYXNlIFwic3ltYm9sXCI6cmV0dXJuITA7Y2FzZSBcImJvb2xlYW5cIjppZihkKXJldHVybiExO2lmKG51bGwhPT1jKXJldHVybiFjLmFjY2VwdHNCb29sZWFuczthPWEudG9Mb3dlckNhc2UoKS5zbGljZSgwLDUpO3JldHVyblwiZGF0YS1cIiE9PWEmJlwiYXJpYS1cIiE9PWE7ZGVmYXVsdDpyZXR1cm4hMX19XG5mdW5jdGlvbiB1YShhLGIsYyxkKXtpZihudWxsPT09Ynx8XCJ1bmRlZmluZWRcIj09PXR5cGVvZiBifHx0YShhLGIsYyxkKSlyZXR1cm4hMDtpZihkKXJldHVybiExO2lmKG51bGwhPT1jKXN3aXRjaChjLnR5cGUpe2Nhc2UgMzpyZXR1cm4hYjtjYXNlIDQ6cmV0dXJuITE9PT1iO2Nhc2UgNTpyZXR1cm4gaXNOYU4oYik7Y2FzZSA2OnJldHVybiBpc05hTihiKXx8MT5ifXJldHVybiExfWZ1bmN0aW9uIE0oYSxiLGMsZCxmLGgsdCl7dGhpcy5hY2NlcHRzQm9vbGVhbnM9Mj09PWJ8fDM9PT1ifHw0PT09Yjt0aGlzLmF0dHJpYnV0ZU5hbWU9ZDt0aGlzLmF0dHJpYnV0ZU5hbWVzcGFjZT1mO3RoaXMubXVzdFVzZVByb3BlcnR5PWM7dGhpcy5wcm9wZXJ0eU5hbWU9YTt0aGlzLnR5cGU9Yjt0aGlzLnNhbml0aXplVVJMPWg7dGhpcy5yZW1vdmVFbXB0eVN0cmluZz10fXZhciBOPXt9O1xuXCJjaGlsZHJlbiBkYW5nZXJvdXNseVNldElubmVySFRNTCBkZWZhdWx0VmFsdWUgZGVmYXVsdENoZWNrZWQgaW5uZXJIVE1MIHN1cHByZXNzQ29udGVudEVkaXRhYmxlV2FybmluZyBzdXBwcmVzc0h5ZHJhdGlvbldhcm5pbmcgc3R5bGVcIi5zcGxpdChcIiBcIikuZm9yRWFjaChmdW5jdGlvbihhKXtOW2FdPW5ldyBNKGEsMCwhMSxhLG51bGwsITEsITEpfSk7W1tcImFjY2VwdENoYXJzZXRcIixcImFjY2VwdC1jaGFyc2V0XCJdLFtcImNsYXNzTmFtZVwiLFwiY2xhc3NcIl0sW1wiaHRtbEZvclwiLFwiZm9yXCJdLFtcImh0dHBFcXVpdlwiLFwiaHR0cC1lcXVpdlwiXV0uZm9yRWFjaChmdW5jdGlvbihhKXt2YXIgYj1hWzBdO05bYl09bmV3IE0oYiwxLCExLGFbMV0sbnVsbCwhMSwhMSl9KTtbXCJjb250ZW50RWRpdGFibGVcIixcImRyYWdnYWJsZVwiLFwic3BlbGxDaGVja1wiLFwidmFsdWVcIl0uZm9yRWFjaChmdW5jdGlvbihhKXtOW2FdPW5ldyBNKGEsMiwhMSxhLnRvTG93ZXJDYXNlKCksbnVsbCwhMSwhMSl9KTtcbltcImF1dG9SZXZlcnNlXCIsXCJleHRlcm5hbFJlc291cmNlc1JlcXVpcmVkXCIsXCJmb2N1c2FibGVcIixcInByZXNlcnZlQWxwaGFcIl0uZm9yRWFjaChmdW5jdGlvbihhKXtOW2FdPW5ldyBNKGEsMiwhMSxhLG51bGwsITEsITEpfSk7XCJhbGxvd0Z1bGxTY3JlZW4gYXN5bmMgYXV0b0ZvY3VzIGF1dG9QbGF5IGNvbnRyb2xzIGRlZmF1bHQgZGVmZXIgZGlzYWJsZWQgZGlzYWJsZVBpY3R1cmVJblBpY3R1cmUgZGlzYWJsZVJlbW90ZVBsYXliYWNrIGZvcm1Ob1ZhbGlkYXRlIGhpZGRlbiBsb29wIG5vTW9kdWxlIG5vVmFsaWRhdGUgb3BlbiBwbGF5c0lubGluZSByZWFkT25seSByZXF1aXJlZCByZXZlcnNlZCBzY29wZWQgc2VhbWxlc3MgaXRlbVNjb3BlXCIuc3BsaXQoXCIgXCIpLmZvckVhY2goZnVuY3Rpb24oYSl7TlthXT1uZXcgTShhLDMsITEsYS50b0xvd2VyQ2FzZSgpLG51bGwsITEsITEpfSk7XG5bXCJjaGVja2VkXCIsXCJtdWx0aXBsZVwiLFwibXV0ZWRcIixcInNlbGVjdGVkXCJdLmZvckVhY2goZnVuY3Rpb24oYSl7TlthXT1uZXcgTShhLDMsITAsYSxudWxsLCExLCExKX0pO1tcImNhcHR1cmVcIixcImRvd25sb2FkXCJdLmZvckVhY2goZnVuY3Rpb24oYSl7TlthXT1uZXcgTShhLDQsITEsYSxudWxsLCExLCExKX0pO1tcImNvbHNcIixcInJvd3NcIixcInNpemVcIixcInNwYW5cIl0uZm9yRWFjaChmdW5jdGlvbihhKXtOW2FdPW5ldyBNKGEsNiwhMSxhLG51bGwsITEsITEpfSk7W1wicm93U3BhblwiLFwic3RhcnRcIl0uZm9yRWFjaChmdW5jdGlvbihhKXtOW2FdPW5ldyBNKGEsNSwhMSxhLnRvTG93ZXJDYXNlKCksbnVsbCwhMSwhMSl9KTt2YXIgdmE9L1tcXC06XShbYS16XSkvZztmdW5jdGlvbiB3YShhKXtyZXR1cm4gYVsxXS50b1VwcGVyQ2FzZSgpfVxuXCJhY2NlbnQtaGVpZ2h0IGFsaWdubWVudC1iYXNlbGluZSBhcmFiaWMtZm9ybSBiYXNlbGluZS1zaGlmdCBjYXAtaGVpZ2h0IGNsaXAtcGF0aCBjbGlwLXJ1bGUgY29sb3ItaW50ZXJwb2xhdGlvbiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnMgY29sb3ItcHJvZmlsZSBjb2xvci1yZW5kZXJpbmcgZG9taW5hbnQtYmFzZWxpbmUgZW5hYmxlLWJhY2tncm91bmQgZmlsbC1vcGFjaXR5IGZpbGwtcnVsZSBmbG9vZC1jb2xvciBmbG9vZC1vcGFjaXR5IGZvbnQtZmFtaWx5IGZvbnQtc2l6ZSBmb250LXNpemUtYWRqdXN0IGZvbnQtc3RyZXRjaCBmb250LXN0eWxlIGZvbnQtdmFyaWFudCBmb250LXdlaWdodCBnbHlwaC1uYW1lIGdseXBoLW9yaWVudGF0aW9uLWhvcml6b250YWwgZ2x5cGgtb3JpZW50YXRpb24tdmVydGljYWwgaG9yaXotYWR2LXggaG9yaXotb3JpZ2luLXggaW1hZ2UtcmVuZGVyaW5nIGxldHRlci1zcGFjaW5nIGxpZ2h0aW5nLWNvbG9yIG1hcmtlci1lbmQgbWFya2VyLW1pZCBtYXJrZXItc3RhcnQgb3ZlcmxpbmUtcG9zaXRpb24gb3ZlcmxpbmUtdGhpY2tuZXNzIHBhaW50LW9yZGVyIHBhbm9zZS0xIHBvaW50ZXItZXZlbnRzIHJlbmRlcmluZy1pbnRlbnQgc2hhcGUtcmVuZGVyaW5nIHN0b3AtY29sb3Igc3RvcC1vcGFjaXR5IHN0cmlrZXRocm91Z2gtcG9zaXRpb24gc3RyaWtldGhyb3VnaC10aGlja25lc3Mgc3Ryb2tlLWRhc2hhcnJheSBzdHJva2UtZGFzaG9mZnNldCBzdHJva2UtbGluZWNhcCBzdHJva2UtbGluZWpvaW4gc3Ryb2tlLW1pdGVybGltaXQgc3Ryb2tlLW9wYWNpdHkgc3Ryb2tlLXdpZHRoIHRleHQtYW5jaG9yIHRleHQtZGVjb3JhdGlvbiB0ZXh0LXJlbmRlcmluZyB1bmRlcmxpbmUtcG9zaXRpb24gdW5kZXJsaW5lLXRoaWNrbmVzcyB1bmljb2RlLWJpZGkgdW5pY29kZS1yYW5nZSB1bml0cy1wZXItZW0gdi1hbHBoYWJldGljIHYtaGFuZ2luZyB2LWlkZW9ncmFwaGljIHYtbWF0aGVtYXRpY2FsIHZlY3Rvci1lZmZlY3QgdmVydC1hZHYteSB2ZXJ0LW9yaWdpbi14IHZlcnQtb3JpZ2luLXkgd29yZC1zcGFjaW5nIHdyaXRpbmctbW9kZSB4bWxuczp4bGluayB4LWhlaWdodFwiLnNwbGl0KFwiIFwiKS5mb3JFYWNoKGZ1bmN0aW9uKGEpe3ZhciBiPWEucmVwbGFjZSh2YSxcbndhKTtOW2JdPW5ldyBNKGIsMSwhMSxhLG51bGwsITEsITEpfSk7XCJ4bGluazphY3R1YXRlIHhsaW5rOmFyY3JvbGUgeGxpbms6cm9sZSB4bGluazpzaG93IHhsaW5rOnRpdGxlIHhsaW5rOnR5cGVcIi5zcGxpdChcIiBcIikuZm9yRWFjaChmdW5jdGlvbihhKXt2YXIgYj1hLnJlcGxhY2UodmEsd2EpO05bYl09bmV3IE0oYiwxLCExLGEsXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIsITEsITEpfSk7W1wieG1sOmJhc2VcIixcInhtbDpsYW5nXCIsXCJ4bWw6c3BhY2VcIl0uZm9yRWFjaChmdW5jdGlvbihhKXt2YXIgYj1hLnJlcGxhY2UodmEsd2EpO05bYl09bmV3IE0oYiwxLCExLGEsXCJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2VcIiwhMSwhMSl9KTtbXCJ0YWJJbmRleFwiLFwiY3Jvc3NPcmlnaW5cIl0uZm9yRWFjaChmdW5jdGlvbihhKXtOW2FdPW5ldyBNKGEsMSwhMSxhLnRvTG93ZXJDYXNlKCksbnVsbCwhMSwhMSl9KTtcbk4ueGxpbmtIcmVmPW5ldyBNKFwieGxpbmtIcmVmXCIsMSwhMSxcInhsaW5rOmhyZWZcIixcImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiwhMCwhMSk7W1wic3JjXCIsXCJocmVmXCIsXCJhY3Rpb25cIixcImZvcm1BY3Rpb25cIl0uZm9yRWFjaChmdW5jdGlvbihhKXtOW2FdPW5ldyBNKGEsMSwhMSxhLnRvTG93ZXJDYXNlKCksbnVsbCwhMCwhMCl9KTt2YXIgeGE9L1tcIicmPD5dLztcbmZ1bmN0aW9uIE8oYSl7aWYoXCJib29sZWFuXCI9PT10eXBlb2YgYXx8XCJudW1iZXJcIj09PXR5cGVvZiBhKXJldHVyblwiXCIrYTthPVwiXCIrYTt2YXIgYj14YS5leGVjKGEpO2lmKGIpe3ZhciBjPVwiXCIsZCxmPTA7Zm9yKGQ9Yi5pbmRleDtkPGEubGVuZ3RoO2QrKyl7c3dpdGNoKGEuY2hhckNvZGVBdChkKSl7Y2FzZSAzNDpiPVwiJnF1b3Q7XCI7YnJlYWs7Y2FzZSAzODpiPVwiJmFtcDtcIjticmVhaztjYXNlIDM5OmI9XCImI3gyNztcIjticmVhaztjYXNlIDYwOmI9XCImbHQ7XCI7YnJlYWs7Y2FzZSA2MjpiPVwiJmd0O1wiO2JyZWFrO2RlZmF1bHQ6Y29udGludWV9ZiE9PWQmJihjKz1hLnN1YnN0cmluZyhmLGQpKTtmPWQrMTtjKz1ifWE9ZiE9PWQ/YythLnN1YnN0cmluZyhmLGQpOmN9cmV0dXJuIGF9XG5mdW5jdGlvbiB5YShhLGIpe3ZhciBjPU4uaGFzT3duUHJvcGVydHkoYSk/TlthXTpudWxsO3ZhciBkO2lmKGQ9XCJzdHlsZVwiIT09YSlkPW51bGwhPT1jPzA9PT1jLnR5cGU6ISgyPGEubGVuZ3RoKXx8XCJvXCIhPT1hWzBdJiZcIk9cIiE9PWFbMF18fFwiblwiIT09YVsxXSYmXCJOXCIhPT1hWzFdPyExOiEwO2lmKGR8fHVhKGEsYixjLCExKSlyZXR1cm5cIlwiO2lmKG51bGwhPT1jKXthPWMuYXR0cmlidXRlTmFtZTtkPWMudHlwZTtpZigzPT09ZHx8ND09PWQmJiEwPT09YilyZXR1cm4gYSsnPVwiXCInO2Muc2FuaXRpemVVUkwmJihiPVwiXCIrYik7cmV0dXJuIGErJz1cIicrKE8oYikrJ1wiJyl9cmV0dXJuIHNhKGEpP2ErJz1cIicrKE8oYikrJ1wiJyk6XCJcIn1mdW5jdGlvbiB6YShhLGIpe3JldHVybiBhPT09YiYmKDAhPT1hfHwxL2E9PT0xL2IpfHxhIT09YSYmYiE9PWJ9XG52YXIgQWE9XCJmdW5jdGlvblwiPT09dHlwZW9mIE9iamVjdC5pcz9PYmplY3QuaXM6emEsUD1udWxsLFE9bnVsbCxSPW51bGwsUz0hMSxUPSExLFU9bnVsbCxWPTA7ZnVuY3Rpb24gVygpe2lmKG51bGw9PT1QKXRocm93IEVycm9yKHAoMzIxKSk7cmV0dXJuIFB9ZnVuY3Rpb24gQmEoKXtpZigwPFYpdGhyb3cgRXJyb3IocCgzMTIpKTtyZXR1cm57bWVtb2l6ZWRTdGF0ZTpudWxsLHF1ZXVlOm51bGwsbmV4dDpudWxsfX1mdW5jdGlvbiBDYSgpe251bGw9PT1SP251bGw9PT1RPyhTPSExLFE9Uj1CYSgpKTooUz0hMCxSPVEpOm51bGw9PT1SLm5leHQ/KFM9ITEsUj1SLm5leHQ9QmEoKSk6KFM9ITAsUj1SLm5leHQpO3JldHVybiBSfWZ1bmN0aW9uIERhKGEsYixjLGQpe2Zvcig7VDspVD0hMSxWKz0xLFI9bnVsbCxjPWEoYixkKTtFYSgpO3JldHVybiBjfWZ1bmN0aW9uIEVhKCl7UD1udWxsO1Q9ITE7UT1udWxsO1Y9MDtSPVU9bnVsbH1cbmZ1bmN0aW9uIEZhKGEsYil7cmV0dXJuXCJmdW5jdGlvblwiPT09dHlwZW9mIGI/YihhKTpifWZ1bmN0aW9uIEdhKGEsYixjKXtQPVcoKTtSPUNhKCk7aWYoUyl7dmFyIGQ9Ui5xdWV1ZTtiPWQuZGlzcGF0Y2g7aWYobnVsbCE9PVUmJihjPVUuZ2V0KGQpLHZvaWQgMCE9PWMpKXtVLmRlbGV0ZShkKTtkPVIubWVtb2l6ZWRTdGF0ZTtkbyBkPWEoZCxjLmFjdGlvbiksYz1jLm5leHQ7d2hpbGUobnVsbCE9PWMpO1IubWVtb2l6ZWRTdGF0ZT1kO3JldHVybltkLGJdfXJldHVybltSLm1lbW9pemVkU3RhdGUsYl19YT1hPT09RmE/XCJmdW5jdGlvblwiPT09dHlwZW9mIGI/YigpOmI6dm9pZCAwIT09Yz9jKGIpOmI7Ui5tZW1vaXplZFN0YXRlPWE7YT1SLnF1ZXVlPXtsYXN0Om51bGwsZGlzcGF0Y2g6bnVsbH07YT1hLmRpc3BhdGNoPUhhLmJpbmQobnVsbCxQLGEpO3JldHVybltSLm1lbW9pemVkU3RhdGUsYV19XG5mdW5jdGlvbiBJYShhLGIpe1A9VygpO1I9Q2EoKTtiPXZvaWQgMD09PWI/bnVsbDpiO2lmKG51bGwhPT1SKXt2YXIgYz1SLm1lbW9pemVkU3RhdGU7aWYobnVsbCE9PWMmJm51bGwhPT1iKXt2YXIgZD1jWzFdO2E6aWYobnVsbD09PWQpZD0hMTtlbHNle2Zvcih2YXIgZj0wO2Y8ZC5sZW5ndGgmJmY8Yi5sZW5ndGg7ZisrKWlmKCFBYShiW2ZdLGRbZl0pKXtkPSExO2JyZWFrIGF9ZD0hMH1pZihkKXJldHVybiBjWzBdfX1hPWEoKTtSLm1lbW9pemVkU3RhdGU9W2EsYl07cmV0dXJuIGF9ZnVuY3Rpb24gSGEoYSxiLGMpe2lmKCEoMjU+VikpdGhyb3cgRXJyb3IocCgzMDEpKTtpZihhPT09UClpZihUPSEwLGE9e2FjdGlvbjpjLG5leHQ6bnVsbH0sbnVsbD09PVUmJihVPW5ldyBNYXApLGM9VS5nZXQoYiksdm9pZCAwPT09YylVLnNldChiLGEpO2Vsc2V7Zm9yKGI9YztudWxsIT09Yi5uZXh0OyliPWIubmV4dDtiLm5leHQ9YX19ZnVuY3Rpb24gSmEoKXt9XG52YXIgWD1udWxsLEthPXtyZWFkQ29udGV4dDpmdW5jdGlvbihhKXt2YXIgYj1YLnRocmVhZElEO0koYSxiKTtyZXR1cm4gYVtiXX0sdXNlQ29udGV4dDpmdW5jdGlvbihhKXtXKCk7dmFyIGI9WC50aHJlYWRJRDtJKGEsYik7cmV0dXJuIGFbYl19LHVzZU1lbW86SWEsdXNlUmVkdWNlcjpHYSx1c2VSZWY6ZnVuY3Rpb24oYSl7UD1XKCk7Uj1DYSgpO3ZhciBiPVIubWVtb2l6ZWRTdGF0ZTtyZXR1cm4gbnVsbD09PWI/KGE9e2N1cnJlbnQ6YX0sUi5tZW1vaXplZFN0YXRlPWEpOmJ9LHVzZVN0YXRlOmZ1bmN0aW9uKGEpe3JldHVybiBHYShGYSxhKX0sdXNlTGF5b3V0RWZmZWN0OmZ1bmN0aW9uKCl7fSx1c2VDYWxsYmFjazpmdW5jdGlvbihhLGIpe3JldHVybiBJYShmdW5jdGlvbigpe3JldHVybiBhfSxiKX0sdXNlSW1wZXJhdGl2ZUhhbmRsZTpKYSx1c2VFZmZlY3Q6SmEsdXNlRGVidWdWYWx1ZTpKYSx1c2VEZWZlcnJlZFZhbHVlOmZ1bmN0aW9uKGEpe1coKTtyZXR1cm4gYX0sdXNlVHJhbnNpdGlvbjpmdW5jdGlvbigpe1coKTtcbnJldHVybltmdW5jdGlvbihhKXthKCl9LCExXX0sdXNlT3BhcXVlSWRlbnRpZmllcjpmdW5jdGlvbigpe3JldHVybihYLmlkZW50aWZpZXJQcmVmaXh8fFwiXCIpK1wiUjpcIisoWC51bmlxdWVJRCsrKS50b1N0cmluZygzNil9LHVzZU11dGFibGVTb3VyY2U6ZnVuY3Rpb24oYSxiKXtXKCk7cmV0dXJuIGIoYS5fc291cmNlKX19LExhPXtodG1sOlwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiLG1hdGhtbDpcImh0dHA6Ly93d3cudzMub3JnLzE5OTgvTWF0aC9NYXRoTUxcIixzdmc6XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wifTtmdW5jdGlvbiBNYShhKXtzd2l0Y2goYSl7Y2FzZSBcInN2Z1wiOnJldHVyblwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIjtjYXNlIFwibWF0aFwiOnJldHVyblwiaHR0cDovL3d3dy53My5vcmcvMTk5OC9NYXRoL01hdGhNTFwiO2RlZmF1bHQ6cmV0dXJuXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCJ9fVxudmFyIE5hPXthcmVhOiEwLGJhc2U6ITAsYnI6ITAsY29sOiEwLGVtYmVkOiEwLGhyOiEwLGltZzohMCxpbnB1dDohMCxrZXlnZW46ITAsbGluazohMCxtZXRhOiEwLHBhcmFtOiEwLHNvdXJjZTohMCx0cmFjazohMCx3YnI6ITB9LE9hPWwoe21lbnVpdGVtOiEwfSxOYSksWT17YW5pbWF0aW9uSXRlcmF0aW9uQ291bnQ6ITAsYm9yZGVySW1hZ2VPdXRzZXQ6ITAsYm9yZGVySW1hZ2VTbGljZTohMCxib3JkZXJJbWFnZVdpZHRoOiEwLGJveEZsZXg6ITAsYm94RmxleEdyb3VwOiEwLGJveE9yZGluYWxHcm91cDohMCxjb2x1bW5Db3VudDohMCxjb2x1bW5zOiEwLGZsZXg6ITAsZmxleEdyb3c6ITAsZmxleFBvc2l0aXZlOiEwLGZsZXhTaHJpbms6ITAsZmxleE5lZ2F0aXZlOiEwLGZsZXhPcmRlcjohMCxncmlkQXJlYTohMCxncmlkUm93OiEwLGdyaWRSb3dFbmQ6ITAsZ3JpZFJvd1NwYW46ITAsZ3JpZFJvd1N0YXJ0OiEwLGdyaWRDb2x1bW46ITAsZ3JpZENvbHVtbkVuZDohMCxncmlkQ29sdW1uU3BhbjohMCxcbmdyaWRDb2x1bW5TdGFydDohMCxmb250V2VpZ2h0OiEwLGxpbmVDbGFtcDohMCxsaW5lSGVpZ2h0OiEwLG9wYWNpdHk6ITAsb3JkZXI6ITAsb3JwaGFuczohMCx0YWJTaXplOiEwLHdpZG93czohMCx6SW5kZXg6ITAsem9vbTohMCxmaWxsT3BhY2l0eTohMCxmbG9vZE9wYWNpdHk6ITAsc3RvcE9wYWNpdHk6ITAsc3Ryb2tlRGFzaGFycmF5OiEwLHN0cm9rZURhc2hvZmZzZXQ6ITAsc3Ryb2tlTWl0ZXJsaW1pdDohMCxzdHJva2VPcGFjaXR5OiEwLHN0cm9rZVdpZHRoOiEwfSxQYT1bXCJXZWJraXRcIixcIm1zXCIsXCJNb3pcIixcIk9cIl07T2JqZWN0LmtleXMoWSkuZm9yRWFjaChmdW5jdGlvbihhKXtQYS5mb3JFYWNoKGZ1bmN0aW9uKGIpe2I9YithLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpK2Euc3Vic3RyaW5nKDEpO1lbYl09WVthXX0pfSk7XG52YXIgUWE9LyhbQS1aXSkvZyxSYT0vXm1zLS8sWj1tLkNoaWxkcmVuLnRvQXJyYXksU2E9bGEuUmVhY3RDdXJyZW50RGlzcGF0Y2hlcixUYT17bGlzdGluZzohMCxwcmU6ITAsdGV4dGFyZWE6ITB9LFVhPS9eW2EtekEtWl1bYS16QS1aOl9cXC5cXC1cXGRdKiQvLFZhPXt9LFdhPXt9O2Z1bmN0aW9uIFhhKGEpe2lmKHZvaWQgMD09PWF8fG51bGw9PT1hKXJldHVybiBhO3ZhciBiPVwiXCI7bS5DaGlsZHJlbi5mb3JFYWNoKGEsZnVuY3Rpb24oYSl7bnVsbCE9YSYmKGIrPWEpfSk7cmV0dXJuIGJ9dmFyIFlhPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksWmE9e2NoaWxkcmVuOm51bGwsZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUw6bnVsbCxzdXBwcmVzc0NvbnRlbnRFZGl0YWJsZVdhcm5pbmc6bnVsbCxzdXBwcmVzc0h5ZHJhdGlvbldhcm5pbmc6bnVsbH07ZnVuY3Rpb24gJGEoYSxiKXtpZih2b2lkIDA9PT1hKXRocm93IEVycm9yKHAoMTUyLEYoYil8fFwiQ29tcG9uZW50XCIpKTt9XG5mdW5jdGlvbiBhYihhLGIsYyl7ZnVuY3Rpb24gZChkLGgpe3ZhciBlPWgucHJvdG90eXBlJiZoLnByb3RvdHlwZS5pc1JlYWN0Q29tcG9uZW50LGY9bmEoaCxiLGMsZSksdD1bXSxnPSExLG49e2lzTW91bnRlZDpmdW5jdGlvbigpe3JldHVybiExfSxlbnF1ZXVlRm9yY2VVcGRhdGU6ZnVuY3Rpb24oKXtpZihudWxsPT09dClyZXR1cm4gbnVsbH0sZW5xdWV1ZVJlcGxhY2VTdGF0ZTpmdW5jdGlvbihhLGMpe2c9ITA7dD1bY119LGVucXVldWVTZXRTdGF0ZTpmdW5jdGlvbihhLGMpe2lmKG51bGw9PT10KXJldHVybiBudWxsO3QucHVzaChjKX19O2lmKGUpe2lmKGU9bmV3IGgoZC5wcm9wcyxmLG4pLFwiZnVuY3Rpb25cIj09PXR5cGVvZiBoLmdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyl7dmFyIGs9aC5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMuY2FsbChudWxsLGQucHJvcHMsZS5zdGF0ZSk7bnVsbCE9ayYmKGUuc3RhdGU9bCh7fSxlLnN0YXRlLGspKX19ZWxzZSBpZihQPXt9LGU9aChkLnByb3BzLFxuZixuKSxlPURhKGgsZC5wcm9wcyxlLGYpLG51bGw9PWV8fG51bGw9PWUucmVuZGVyKXthPWU7JGEoYSxoKTtyZXR1cm59ZS5wcm9wcz1kLnByb3BzO2UuY29udGV4dD1mO2UudXBkYXRlcj1uO249ZS5zdGF0ZTt2b2lkIDA9PT1uJiYoZS5zdGF0ZT1uPW51bGwpO2lmKFwiZnVuY3Rpb25cIj09PXR5cGVvZiBlLlVOU0FGRV9jb21wb25lbnRXaWxsTW91bnR8fFwiZnVuY3Rpb25cIj09PXR5cGVvZiBlLmNvbXBvbmVudFdpbGxNb3VudClpZihcImZ1bmN0aW9uXCI9PT10eXBlb2YgZS5jb21wb25lbnRXaWxsTW91bnQmJlwiZnVuY3Rpb25cIiE9PXR5cGVvZiBoLmdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyYmZS5jb21wb25lbnRXaWxsTW91bnQoKSxcImZ1bmN0aW9uXCI9PT10eXBlb2YgZS5VTlNBRkVfY29tcG9uZW50V2lsbE1vdW50JiZcImZ1bmN0aW9uXCIhPT10eXBlb2YgaC5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMmJmUuVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudCgpLHQubGVuZ3RoKXtuPXQ7dmFyIHY9XG5nO3Q9bnVsbDtnPSExO2lmKHYmJjE9PT1uLmxlbmd0aCllLnN0YXRlPW5bMF07ZWxzZXtrPXY/blswXTplLnN0YXRlO3ZhciBIPSEwO2Zvcih2PXY/MTowO3Y8bi5sZW5ndGg7disrKXt2YXIgeD1uW3ZdO3g9XCJmdW5jdGlvblwiPT09dHlwZW9mIHg/eC5jYWxsKGUsayxkLnByb3BzLGYpOng7bnVsbCE9eCYmKEg/KEg9ITEsaz1sKHt9LGsseCkpOmwoayx4KSl9ZS5zdGF0ZT1rfX1lbHNlIHQ9bnVsbDthPWUucmVuZGVyKCk7JGEoYSxoKTtpZihcImZ1bmN0aW9uXCI9PT10eXBlb2YgZS5nZXRDaGlsZENvbnRleHQmJihkPWguY2hpbGRDb250ZXh0VHlwZXMsXCJvYmplY3RcIj09PXR5cGVvZiBkKSl7dmFyIHk9ZS5nZXRDaGlsZENvbnRleHQoKTtmb3IodmFyIEEgaW4geSlpZighKEEgaW4gZCkpdGhyb3cgRXJyb3IocCgxMDgsRihoKXx8XCJVbmtub3duXCIsQSkpO315JiYoYj1sKHt9LGIseSkpfWZvcig7bS5pc1ZhbGlkRWxlbWVudChhKTspe3ZhciBmPWEsaD1mLnR5cGU7aWYoXCJmdW5jdGlvblwiIT09XG50eXBlb2YgaClicmVhaztkKGYsaCl9cmV0dXJue2NoaWxkOmEsY29udGV4dDpifX1cbnZhciBiYj1mdW5jdGlvbigpe2Z1bmN0aW9uIGEoYSxiLGYpe20uaXNWYWxpZEVsZW1lbnQoYSk/YS50eXBlIT09cj9hPVthXTooYT1hLnByb3BzLmNoaWxkcmVuLGE9bS5pc1ZhbGlkRWxlbWVudChhKT9bYV06WihhKSk6YT1aKGEpO2E9e3R5cGU6bnVsbCxkb21OYW1lc3BhY2U6TGEuaHRtbCxjaGlsZHJlbjphLGNoaWxkSW5kZXg6MCxjb250ZXh0Om1hLGZvb3RlcjpcIlwifTt2YXIgYz1KWzBdO2lmKDA9PT1jKXt2YXIgZD1KO2M9ZC5sZW5ndGg7dmFyIGc9MipjO2lmKCEoNjU1MzY+PWcpKXRocm93IEVycm9yKHAoMzA0KSk7dmFyIGU9bmV3IFVpbnQxNkFycmF5KGcpO2Uuc2V0KGQpO0o9ZTtKWzBdPWMrMTtmb3IoZD1jO2Q8Zy0xO2QrKylKW2RdPWQrMTtKW2ctMV09MH1lbHNlIEpbMF09SltjXTt0aGlzLnRocmVhZElEPWM7dGhpcy5zdGFjaz1bYV07dGhpcy5leGhhdXN0ZWQ9ITE7dGhpcy5jdXJyZW50U2VsZWN0VmFsdWU9bnVsbDt0aGlzLnByZXZpb3VzV2FzVGV4dE5vZGU9ITE7XG50aGlzLm1ha2VTdGF0aWNNYXJrdXA9Yjt0aGlzLnN1c3BlbnNlRGVwdGg9MDt0aGlzLmNvbnRleHRJbmRleD0tMTt0aGlzLmNvbnRleHRTdGFjaz1bXTt0aGlzLmNvbnRleHRWYWx1ZVN0YWNrPVtdO3RoaXMudW5pcXVlSUQ9MDt0aGlzLmlkZW50aWZpZXJQcmVmaXg9ZiYmZi5pZGVudGlmaWVyUHJlZml4fHxcIlwifXZhciBiPWEucHJvdG90eXBlO2IuZGVzdHJveT1mdW5jdGlvbigpe2lmKCF0aGlzLmV4aGF1c3RlZCl7dGhpcy5leGhhdXN0ZWQ9ITA7dGhpcy5jbGVhclByb3ZpZGVycygpO3ZhciBhPXRoaXMudGhyZWFkSUQ7SlthXT1KWzBdO0pbMF09YX19O2IucHVzaFByb3ZpZGVyPWZ1bmN0aW9uKGEpe3ZhciBiPSsrdGhpcy5jb250ZXh0SW5kZXgsYz1hLnR5cGUuX2NvbnRleHQsaD10aGlzLnRocmVhZElEO0koYyxoKTt2YXIgdD1jW2hdO3RoaXMuY29udGV4dFN0YWNrW2JdPWM7dGhpcy5jb250ZXh0VmFsdWVTdGFja1tiXT10O2NbaF09YS5wcm9wcy52YWx1ZX07Yi5wb3BQcm92aWRlcj1cbmZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5jb250ZXh0SW5kZXgsYj10aGlzLmNvbnRleHRTdGFja1thXSxmPXRoaXMuY29udGV4dFZhbHVlU3RhY2tbYV07dGhpcy5jb250ZXh0U3RhY2tbYV09bnVsbDt0aGlzLmNvbnRleHRWYWx1ZVN0YWNrW2FdPW51bGw7dGhpcy5jb250ZXh0SW5kZXgtLTtiW3RoaXMudGhyZWFkSURdPWZ9O2IuY2xlYXJQcm92aWRlcnM9ZnVuY3Rpb24oKXtmb3IodmFyIGE9dGhpcy5jb250ZXh0SW5kZXg7MDw9YTthLS0pdGhpcy5jb250ZXh0U3RhY2tbYV1bdGhpcy50aHJlYWRJRF09dGhpcy5jb250ZXh0VmFsdWVTdGFja1thXX07Yi5yZWFkPWZ1bmN0aW9uKGEpe2lmKHRoaXMuZXhoYXVzdGVkKXJldHVybiBudWxsO3ZhciBiPVg7WD10aGlzO3ZhciBjPVNhLmN1cnJlbnQ7U2EuY3VycmVudD1LYTt0cnl7Zm9yKHZhciBoPVtcIlwiXSx0PSExO2hbMF0ubGVuZ3RoPGE7KXtpZigwPT09dGhpcy5zdGFjay5sZW5ndGgpe3RoaXMuZXhoYXVzdGVkPSEwO3ZhciBnPXRoaXMudGhyZWFkSUQ7XG5KW2ddPUpbMF07SlswXT1nO2JyZWFrfXZhciBlPXRoaXMuc3RhY2tbdGhpcy5zdGFjay5sZW5ndGgtMV07aWYodHx8ZS5jaGlsZEluZGV4Pj1lLmNoaWxkcmVuLmxlbmd0aCl7dmFyIEw9ZS5mb290ZXI7XCJcIiE9PUwmJih0aGlzLnByZXZpb3VzV2FzVGV4dE5vZGU9ITEpO3RoaXMuc3RhY2sucG9wKCk7aWYoXCJzZWxlY3RcIj09PWUudHlwZSl0aGlzLmN1cnJlbnRTZWxlY3RWYWx1ZT1udWxsO2Vsc2UgaWYobnVsbCE9ZS50eXBlJiZudWxsIT1lLnR5cGUudHlwZSYmZS50eXBlLnR5cGUuJCR0eXBlb2Y9PT1CKXRoaXMucG9wUHJvdmlkZXIoZS50eXBlKTtlbHNlIGlmKGUudHlwZT09PUQpe3RoaXMuc3VzcGVuc2VEZXB0aC0tO3ZhciBHPWgucG9wKCk7aWYodCl7dD0hMTt2YXIgQz1lLmZhbGxiYWNrRnJhbWU7aWYoIUMpdGhyb3cgRXJyb3IocCgzMDMpKTt0aGlzLnN0YWNrLnB1c2goQyk7aFt0aGlzLnN1c3BlbnNlRGVwdGhdKz1cIlxceDNjIS0tJCEtLVxceDNlXCI7Y29udGludWV9ZWxzZSBoW3RoaXMuc3VzcGVuc2VEZXB0aF0rPVxuR31oW3RoaXMuc3VzcGVuc2VEZXB0aF0rPUx9ZWxzZXt2YXIgbj1lLmNoaWxkcmVuW2UuY2hpbGRJbmRleCsrXSxrPVwiXCI7dHJ5e2srPXRoaXMucmVuZGVyKG4sZS5jb250ZXh0LGUuZG9tTmFtZXNwYWNlKX1jYXRjaCh2KXtpZihudWxsIT12JiZcImZ1bmN0aW9uXCI9PT10eXBlb2Ygdi50aGVuKXRocm93IEVycm9yKHAoMjk0KSk7dGhyb3cgdjt9ZmluYWxseXt9aC5sZW5ndGg8PXRoaXMuc3VzcGVuc2VEZXB0aCYmaC5wdXNoKFwiXCIpO2hbdGhpcy5zdXNwZW5zZURlcHRoXSs9a319cmV0dXJuIGhbMF19ZmluYWxseXtTYS5jdXJyZW50PWMsWD1iLEVhKCl9fTtiLnJlbmRlcj1mdW5jdGlvbihhLGIsZil7aWYoXCJzdHJpbmdcIj09PXR5cGVvZiBhfHxcIm51bWJlclwiPT09dHlwZW9mIGEpe2Y9XCJcIithO2lmKFwiXCI9PT1mKXJldHVyblwiXCI7aWYodGhpcy5tYWtlU3RhdGljTWFya3VwKXJldHVybiBPKGYpO2lmKHRoaXMucHJldmlvdXNXYXNUZXh0Tm9kZSlyZXR1cm5cIlxceDNjIS0tIC0tXFx4M2VcIitPKGYpO1xudGhpcy5wcmV2aW91c1dhc1RleHROb2RlPSEwO3JldHVybiBPKGYpfWI9YWIoYSxiLHRoaXMudGhyZWFkSUQpO2E9Yi5jaGlsZDtiPWIuY29udGV4dDtpZihudWxsPT09YXx8ITE9PT1hKXJldHVyblwiXCI7aWYoIW0uaXNWYWxpZEVsZW1lbnQoYSkpe2lmKG51bGwhPWEmJm51bGwhPWEuJCR0eXBlb2Ype2Y9YS4kJHR5cGVvZjtpZihmPT09cSl0aHJvdyBFcnJvcihwKDI1NykpO3Rocm93IEVycm9yKHAoMjU4LGYudG9TdHJpbmcoKSkpO31hPVooYSk7dGhpcy5zdGFjay5wdXNoKHt0eXBlOm51bGwsZG9tTmFtZXNwYWNlOmYsY2hpbGRyZW46YSxjaGlsZEluZGV4OjAsY29udGV4dDpiLGZvb3RlcjpcIlwifSk7cmV0dXJuXCJcIn12YXIgYz1hLnR5cGU7aWYoXCJzdHJpbmdcIj09PXR5cGVvZiBjKXJldHVybiB0aGlzLnJlbmRlckRPTShhLGIsZik7c3dpdGNoKGMpe2Nhc2Uga2E6Y2FzZSBqYTpjYXNlIHU6Y2FzZSB6OmNhc2UgY2E6Y2FzZSByOnJldHVybiBhPVooYS5wcm9wcy5jaGlsZHJlbiksdGhpcy5zdGFjay5wdXNoKHt0eXBlOm51bGwsXG5kb21OYW1lc3BhY2U6ZixjaGlsZHJlbjphLGNoaWxkSW5kZXg6MCxjb250ZXh0OmIsZm9vdGVyOlwiXCJ9KSxcIlwiO2Nhc2UgRDp0aHJvdyBFcnJvcihwKDI5NCkpO2Nhc2UgaWE6dGhyb3cgRXJyb3IocCgzNDMpKTt9aWYoXCJvYmplY3RcIj09PXR5cGVvZiBjJiZudWxsIT09Yylzd2l0Y2goYy4kJHR5cGVvZil7Y2FzZSBiYTpQPXt9O3ZhciBkPWMucmVuZGVyKGEucHJvcHMsYS5yZWYpO2Q9RGEoYy5yZW5kZXIsYS5wcm9wcyxkLGEucmVmKTtkPVooZCk7dGhpcy5zdGFjay5wdXNoKHt0eXBlOm51bGwsZG9tTmFtZXNwYWNlOmYsY2hpbGRyZW46ZCxjaGlsZEluZGV4OjAsY29udGV4dDpiLGZvb3RlcjpcIlwifSk7cmV0dXJuXCJcIjtjYXNlIGRhOnJldHVybiBhPVttLmNyZWF0ZUVsZW1lbnQoYy50eXBlLGwoe3JlZjphLnJlZn0sYS5wcm9wcykpXSx0aGlzLnN0YWNrLnB1c2goe3R5cGU6bnVsbCxkb21OYW1lc3BhY2U6ZixjaGlsZHJlbjphLGNoaWxkSW5kZXg6MCxjb250ZXh0OmIsZm9vdGVyOlwiXCJ9KSxcblwiXCI7Y2FzZSBCOnJldHVybiBjPVooYS5wcm9wcy5jaGlsZHJlbiksZj17dHlwZTphLGRvbU5hbWVzcGFjZTpmLGNoaWxkcmVuOmMsY2hpbGRJbmRleDowLGNvbnRleHQ6Yixmb290ZXI6XCJcIn0sdGhpcy5wdXNoUHJvdmlkZXIoYSksdGhpcy5zdGFjay5wdXNoKGYpLFwiXCI7Y2FzZSBhYTpjPWEudHlwZTtkPWEucHJvcHM7dmFyIGc9dGhpcy50aHJlYWRJRDtJKGMsZyk7Yz1aKGQuY2hpbGRyZW4oY1tnXSkpO3RoaXMuc3RhY2sucHVzaCh7dHlwZTphLGRvbU5hbWVzcGFjZTpmLGNoaWxkcmVuOmMsY2hpbGRJbmRleDowLGNvbnRleHQ6Yixmb290ZXI6XCJcIn0pO3JldHVyblwiXCI7Y2FzZSBoYTp0aHJvdyBFcnJvcihwKDMzOCkpO2Nhc2UgZWE6cmV0dXJuIGM9YS50eXBlLGQ9Yy5faW5pdCxjPWQoYy5fcGF5bG9hZCksYT1bbS5jcmVhdGVFbGVtZW50KGMsbCh7cmVmOmEucmVmfSxhLnByb3BzKSldLHRoaXMuc3RhY2sucHVzaCh7dHlwZTpudWxsLGRvbU5hbWVzcGFjZTpmLGNoaWxkcmVuOmEsY2hpbGRJbmRleDowLFxuY29udGV4dDpiLGZvb3RlcjpcIlwifSksXCJcIn10aHJvdyBFcnJvcihwKDEzMCxudWxsPT1jP2M6dHlwZW9mIGMsXCJcIikpO307Yi5yZW5kZXJET009ZnVuY3Rpb24oYSxiLGYpe3ZhciBjPWEudHlwZS50b0xvd2VyQ2FzZSgpO2Y9PT1MYS5odG1sJiZNYShjKTtpZighVmEuaGFzT3duUHJvcGVydHkoYykpe2lmKCFVYS50ZXN0KGMpKXRocm93IEVycm9yKHAoNjUsYykpO1ZhW2NdPSEwfXZhciBkPWEucHJvcHM7aWYoXCJpbnB1dFwiPT09YylkPWwoe3R5cGU6dm9pZCAwfSxkLHtkZWZhdWx0Q2hlY2tlZDp2b2lkIDAsZGVmYXVsdFZhbHVlOnZvaWQgMCx2YWx1ZTpudWxsIT1kLnZhbHVlP2QudmFsdWU6ZC5kZWZhdWx0VmFsdWUsY2hlY2tlZDpudWxsIT1kLmNoZWNrZWQ/ZC5jaGVja2VkOmQuZGVmYXVsdENoZWNrZWR9KTtlbHNlIGlmKFwidGV4dGFyZWFcIj09PWMpe3ZhciBnPWQudmFsdWU7aWYobnVsbD09Zyl7Zz1kLmRlZmF1bHRWYWx1ZTt2YXIgZT1kLmNoaWxkcmVuO2lmKG51bGwhPWUpe2lmKG51bGwhPVxuZyl0aHJvdyBFcnJvcihwKDkyKSk7aWYoQXJyYXkuaXNBcnJheShlKSl7aWYoISgxPj1lLmxlbmd0aCkpdGhyb3cgRXJyb3IocCg5MykpO2U9ZVswXX1nPVwiXCIrZX1udWxsPT1nJiYoZz1cIlwiKX1kPWwoe30sZCx7dmFsdWU6dm9pZCAwLGNoaWxkcmVuOlwiXCIrZ30pfWVsc2UgaWYoXCJzZWxlY3RcIj09PWMpdGhpcy5jdXJyZW50U2VsZWN0VmFsdWU9bnVsbCE9ZC52YWx1ZT9kLnZhbHVlOmQuZGVmYXVsdFZhbHVlLGQ9bCh7fSxkLHt2YWx1ZTp2b2lkIDB9KTtlbHNlIGlmKFwib3B0aW9uXCI9PT1jKXtlPXRoaXMuY3VycmVudFNlbGVjdFZhbHVlO3ZhciBMPVhhKGQuY2hpbGRyZW4pO2lmKG51bGwhPWUpe3ZhciBHPW51bGwhPWQudmFsdWU/ZC52YWx1ZStcIlwiOkw7Zz0hMTtpZihBcnJheS5pc0FycmF5KGUpKWZvcih2YXIgQz0wO0M8ZS5sZW5ndGg7QysrKXtpZihcIlwiK2VbQ109PT1HKXtnPSEwO2JyZWFrfX1lbHNlIGc9XCJcIitlPT09RztkPWwoe3NlbGVjdGVkOnZvaWQgMCxjaGlsZHJlbjp2b2lkIDB9LFxuZCx7c2VsZWN0ZWQ6ZyxjaGlsZHJlbjpMfSl9fWlmKGc9ZCl7aWYoT2FbY10mJihudWxsIT1nLmNoaWxkcmVufHxudWxsIT1nLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MKSl0aHJvdyBFcnJvcihwKDEzNyxjKSk7aWYobnVsbCE9Zy5kYW5nZXJvdXNseVNldElubmVySFRNTCl7aWYobnVsbCE9Zy5jaGlsZHJlbil0aHJvdyBFcnJvcihwKDYwKSk7aWYoIShcIm9iamVjdFwiPT09dHlwZW9mIGcuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwmJlwiX19odG1sXCJpbiBnLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MKSl0aHJvdyBFcnJvcihwKDYxKSk7fWlmKG51bGwhPWcuc3R5bGUmJlwib2JqZWN0XCIhPT10eXBlb2YgZy5zdHlsZSl0aHJvdyBFcnJvcihwKDYyKSk7fWc9ZDtlPXRoaXMubWFrZVN0YXRpY01hcmt1cDtMPTE9PT10aGlzLnN0YWNrLmxlbmd0aDtHPVwiPFwiK2EudHlwZTtiOmlmKC0xPT09Yy5pbmRleE9mKFwiLVwiKSlDPVwic3RyaW5nXCI9PT10eXBlb2YgZy5pcztlbHNlIHN3aXRjaChjKXtjYXNlIFwiYW5ub3RhdGlvbi14bWxcIjpjYXNlIFwiY29sb3ItcHJvZmlsZVwiOmNhc2UgXCJmb250LWZhY2VcIjpjYXNlIFwiZm9udC1mYWNlLXNyY1wiOmNhc2UgXCJmb250LWZhY2UtdXJpXCI6Y2FzZSBcImZvbnQtZmFjZS1mb3JtYXRcIjpjYXNlIFwiZm9udC1mYWNlLW5hbWVcIjpjYXNlIFwibWlzc2luZy1nbHlwaFwiOkM9XG4hMTticmVhayBiO2RlZmF1bHQ6Qz0hMH1mb3IodyBpbiBnKWlmKFlhLmNhbGwoZyx3KSl7dmFyIG49Z1t3XTtpZihudWxsIT1uKXtpZihcInN0eWxlXCI9PT13KXt2YXIgaz12b2lkIDAsdj1cIlwiLEg9XCJcIjtmb3IoayBpbiBuKWlmKG4uaGFzT3duUHJvcGVydHkoaykpe3ZhciB4PTA9PT1rLmluZGV4T2YoXCItLVwiKSx5PW5ba107aWYobnVsbCE9eSl7aWYoeCl2YXIgQT1rO2Vsc2UgaWYoQT1rLFdhLmhhc093blByb3BlcnR5KEEpKUE9V2FbQV07ZWxzZXt2YXIgY2I9QS5yZXBsYWNlKFFhLFwiLSQxXCIpLnRvTG93ZXJDYXNlKCkucmVwbGFjZShSYSxcIi1tcy1cIik7QT1XYVtBXT1jYn12Kz1IK0ErXCI6XCI7SD1rO3g9bnVsbD09eXx8XCJib29sZWFuXCI9PT10eXBlb2YgeXx8XCJcIj09PXk/XCJcIjp4fHxcIm51bWJlclwiIT09dHlwZW9mIHl8fDA9PT15fHxZLmhhc093blByb3BlcnR5KEgpJiZZW0hdPyhcIlwiK3kpLnRyaW0oKTp5K1wicHhcIjt2Kz14O0g9XCI7XCJ9fW49dnx8bnVsbH1rPW51bGw7Qz9aYS5oYXNPd25Qcm9wZXJ0eSh3KXx8XG4oaz13LGs9c2EoaykmJm51bGwhPW4/aysnPVwiJysoTyhuKSsnXCInKTpcIlwiKTprPXlhKHcsbik7ayYmKEcrPVwiIFwiK2spfX1lfHxMJiYoRys9JyBkYXRhLXJlYWN0cm9vdD1cIlwiJyk7dmFyIHc9RztnPVwiXCI7TmEuaGFzT3duUHJvcGVydHkoYyk/dys9XCIvPlwiOih3Kz1cIj5cIixnPVwiPC9cIithLnR5cGUrXCI+XCIpO2E6e2U9ZC5kYW5nZXJvdXNseVNldElubmVySFRNTDtpZihudWxsIT1lKXtpZihudWxsIT1lLl9faHRtbCl7ZT1lLl9faHRtbDticmVhayBhfX1lbHNlIGlmKGU9ZC5jaGlsZHJlbixcInN0cmluZ1wiPT09dHlwZW9mIGV8fFwibnVtYmVyXCI9PT10eXBlb2YgZSl7ZT1PKGUpO2JyZWFrIGF9ZT1udWxsfW51bGwhPWU/KGQ9W10sVGEuaGFzT3duUHJvcGVydHkoYykmJlwiXFxuXCI9PT1lLmNoYXJBdCgwKSYmKHcrPVwiXFxuXCIpLHcrPWUpOmQ9WihkLmNoaWxkcmVuKTthPWEudHlwZTtmPW51bGw9PWZ8fFwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiPT09Zj9NYShhKTpcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI9PT1cbmYmJlwiZm9yZWlnbk9iamVjdFwiPT09YT9cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIjpmO3RoaXMuc3RhY2sucHVzaCh7ZG9tTmFtZXNwYWNlOmYsdHlwZTpjLGNoaWxkcmVuOmQsY2hpbGRJbmRleDowLGNvbnRleHQ6Yixmb290ZXI6Z30pO3RoaXMucHJldmlvdXNXYXNUZXh0Tm9kZT0hMTtyZXR1cm4gd307cmV0dXJuIGF9KCk7ZXhwb3J0cy5yZW5kZXJUb05vZGVTdHJlYW09ZnVuY3Rpb24oKXt0aHJvdyBFcnJvcihwKDIwNykpO307ZXhwb3J0cy5yZW5kZXJUb1N0YXRpY01hcmt1cD1mdW5jdGlvbihhLGIpe2E9bmV3IGJiKGEsITAsYik7dHJ5e3JldHVybiBhLnJlYWQoSW5maW5pdHkpfWZpbmFsbHl7YS5kZXN0cm95KCl9fTtleHBvcnRzLnJlbmRlclRvU3RhdGljTm9kZVN0cmVhbT1mdW5jdGlvbigpe3Rocm93IEVycm9yKHAoMjA4KSk7fTtleHBvcnRzLnJlbmRlclRvU3RyaW5nPWZ1bmN0aW9uKGEsYil7YT1uZXcgYmIoYSwhMSxiKTt0cnl7cmV0dXJuIGEucmVhZChJbmZpbml0eSl9ZmluYWxseXthLmRlc3Ryb3koKX19O1xuZXhwb3J0cy52ZXJzaW9uPVwiMTcuMC4yXCI7XG4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///692\n')},190:(module,__unused_webpack_exports,__webpack_require__)=>{"use strict";eval("\n\nif (true) {\n module.exports = __webpack_require__(692);\n} else {}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uLi9kZW1vL25vZGVfbW9kdWxlcy9yZWFjdC1kb20vc2VydmVyLmJyb3dzZXIuanM/ODM2NCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixJQUFJLElBQXFDO0FBQ3pDLEVBQUUseUNBQTRFO0FBQzlFLENBQUMsTUFBTSxFQUVOIiwiZmlsZSI6IjE5MC5qcyIsInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbicpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9yZWFjdC1kb20tc2VydmVyLmJyb3dzZXIucHJvZHVjdGlvbi5taW4uanMnKTtcbn0gZWxzZSB7XG4gIG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9janMvcmVhY3QtZG9tLXNlcnZlci5icm93c2VyLmRldmVsb3BtZW50LmpzJyk7XG59XG4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///190\n")},184:(module,exports)=>{eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\n Copyright (c) 2018 Jed Watson.\n Licensed under the MIT License (MIT), see\n http://jedwatson.github.io/classnames\n*/\n/* global define */\n\n(function () {\n\t'use strict';\n\n\tvar hasOwn = {}.hasOwnProperty;\n\n\tfunction classNames() {\n\t\tvar classes = [];\n\n\t\tfor (var i = 0; i < arguments.length; i++) {\n\t\t\tvar arg = arguments[i];\n\t\t\tif (!arg) continue;\n\n\t\t\tvar argType = typeof arg;\n\n\t\t\tif (argType === 'string' || argType === 'number') {\n\t\t\t\tclasses.push(arg);\n\t\t\t} else if (Array.isArray(arg)) {\n\t\t\t\tif (arg.length) {\n\t\t\t\t\tvar inner = classNames.apply(null, arg);\n\t\t\t\t\tif (inner) {\n\t\t\t\t\t\tclasses.push(inner);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (argType === 'object') {\n\t\t\t\tif (arg.toString === Object.prototype.toString) {\n\t\t\t\t\tfor (var key in arg) {\n\t\t\t\t\t\tif (hasOwn.call(arg, key) && arg[key]) {\n\t\t\t\t\t\t\tclasses.push(key);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tclasses.push(arg.toString());\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn classes.join(' ');\n\t}\n\n\tif ( true && module.exports) {\n\t\tclassNames.default = classNames;\n\t\tmodule.exports = classNames;\n\t} else if (true) {\n\t\t// register as 'classnames', consistent with npm package name\n\t\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () {\n\t\t\treturn classNames;\n\t\t}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t} else {}\n}());\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9jbGFzc25hbWVzL2luZGV4LmpzPzRkMjYiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsZ0JBQWdCOztBQUVoQjtBQUNBOztBQUVBLGlCQUFpQixzQkFBc0I7QUFDdkM7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxLQUFLLEtBQTZCO0FBQ2xDO0FBQ0E7QUFDQSxFQUFFLFVBQVUsSUFBNEU7QUFDeEY7QUFDQSxFQUFFLGlDQUFxQixFQUFFLG1DQUFFO0FBQzNCO0FBQ0EsR0FBRztBQUFBLGtHQUFDO0FBQ0osRUFBRSxNQUFNLEVBRU47QUFDRixDQUFDIiwiZmlsZSI6IjE4NC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qIVxuICBDb3B5cmlnaHQgKGMpIDIwMTggSmVkIFdhdHNvbi5cbiAgTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlIChNSVQpLCBzZWVcbiAgaHR0cDovL2plZHdhdHNvbi5naXRodWIuaW8vY2xhc3NuYW1lc1xuKi9cbi8qIGdsb2JhbCBkZWZpbmUgKi9cblxuKGZ1bmN0aW9uICgpIHtcblx0J3VzZSBzdHJpY3QnO1xuXG5cdHZhciBoYXNPd24gPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuXHRmdW5jdGlvbiBjbGFzc05hbWVzKCkge1xuXHRcdHZhciBjbGFzc2VzID0gW107XG5cblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0dmFyIGFyZyA9IGFyZ3VtZW50c1tpXTtcblx0XHRcdGlmICghYXJnKSBjb250aW51ZTtcblxuXHRcdFx0dmFyIGFyZ1R5cGUgPSB0eXBlb2YgYXJnO1xuXG5cdFx0XHRpZiAoYXJnVHlwZSA9PT0gJ3N0cmluZycgfHwgYXJnVHlwZSA9PT0gJ251bWJlcicpIHtcblx0XHRcdFx0Y2xhc3Nlcy5wdXNoKGFyZyk7XG5cdFx0XHR9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoYXJnKSkge1xuXHRcdFx0XHRpZiAoYXJnLmxlbmd0aCkge1xuXHRcdFx0XHRcdHZhciBpbm5lciA9IGNsYXNzTmFtZXMuYXBwbHkobnVsbCwgYXJnKTtcblx0XHRcdFx0XHRpZiAoaW5uZXIpIHtcblx0XHRcdFx0XHRcdGNsYXNzZXMucHVzaChpbm5lcik7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2UgaWYgKGFyZ1R5cGUgPT09ICdvYmplY3QnKSB7XG5cdFx0XHRcdGlmIChhcmcudG9TdHJpbmcgPT09IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcpIHtcblx0XHRcdFx0XHRmb3IgKHZhciBrZXkgaW4gYXJnKSB7XG5cdFx0XHRcdFx0XHRpZiAoaGFzT3duLmNhbGwoYXJnLCBrZXkpICYmIGFyZ1trZXldKSB7XG5cdFx0XHRcdFx0XHRcdGNsYXNzZXMucHVzaChrZXkpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRjbGFzc2VzLnB1c2goYXJnLnRvU3RyaW5nKCkpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGNsYXNzZXMuam9pbignICcpO1xuXHR9XG5cblx0aWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7XG5cdFx0Y2xhc3NOYW1lcy5kZWZhdWx0ID0gY2xhc3NOYW1lcztcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGNsYXNzTmFtZXM7XG5cdH0gZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgZGVmaW5lLmFtZCA9PT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIHJlZ2lzdGVyIGFzICdjbGFzc25hbWVzJywgY29uc2lzdGVudCB3aXRoIG5wbSBwYWNrYWdlIG5hbWVcblx0XHRkZWZpbmUoJ2NsYXNzbmFtZXMnLCBbXSwgZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIGNsYXNzTmFtZXM7XG5cdFx0fSk7XG5cdH0gZWxzZSB7XG5cdFx0d2luZG93LmNsYXNzTmFtZXMgPSBjbGFzc05hbWVzO1xuXHR9XG59KCkpO1xuIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///184\n")},299:function(module,__unused_webpack_exports,__webpack_require__){eval('/**\n * @licstart The following is the entire license notice for the\n * JavaScript code in this page\n *\n * Copyright 2022 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @licend The above is the entire license notice for the\n * JavaScript code in this page\n */\n\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(true)\n\t\tmodule.exports = factory();\n\telse {}\n})(this, () => {\nreturn /******/ (() => { // webpackBootstrap\n/******/ \t"use strict";\n/******/ \tvar __webpack_modules__ = ([\n/* 0 */,\n/* 1 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.VerbosityLevel = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.UNSUPPORTED_FEATURES = exports.TextRenderingMode = exports.StreamType = exports.RenderingIntentFlag = exports.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.PageActionEventType = exports.OPS = exports.MissingPDFException = exports.InvalidPDFException = exports.ImageKind = exports.IDENTITY_MATRIX = exports.FormatError = exports.FontType = exports.FeatureTest = exports.FONT_IDENTITY_MATRIX = exports.DocumentActionEventType = exports.CMapCompressionType = exports.BaseException = exports.AnnotationType = exports.AnnotationStateModelType = exports.AnnotationReviewState = exports.AnnotationReplyType = exports.AnnotationMode = exports.AnnotationMarkedState = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationBorderStyleType = exports.AnnotationActionEventType = exports.AbortException = void 0;\nexports.arrayByteLength = arrayByteLength;\nexports.arraysToBytes = arraysToBytes;\nexports.assert = assert;\nexports.bytesToString = bytesToString;\nexports.createPromiseCapability = createPromiseCapability;\nexports.createValidAbsoluteUrl = createValidAbsoluteUrl;\nexports.escapeString = escapeString;\nexports.getModificationDate = getModificationDate;\nexports.getVerbosityLevel = getVerbosityLevel;\nexports.info = info;\nexports.isArrayBuffer = isArrayBuffer;\nexports.isArrayEqual = isArrayEqual;\nexports.isAscii = isAscii;\nexports.objectFromMap = objectFromMap;\nexports.objectSize = objectSize;\nexports.setVerbosityLevel = setVerbosityLevel;\nexports.shadow = shadow;\nexports.string32 = string32;\nexports.stringToBytes = stringToBytes;\nexports.stringToPDFString = stringToPDFString;\nexports.stringToUTF16BEString = stringToUTF16BEString;\nexports.stringToUTF8String = stringToUTF8String;\nexports.unreachable = unreachable;\nexports.utf8StringToString = utf8StringToString;\nexports.warn = warn;\n\n__w_pdfjs_require__(2);\n\nconst IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];\nexports.IDENTITY_MATRIX = IDENTITY_MATRIX;\nconst FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];\nexports.FONT_IDENTITY_MATRIX = FONT_IDENTITY_MATRIX;\nconst RenderingIntentFlag = {\n ANY: 0x01,\n DISPLAY: 0x02,\n PRINT: 0x04,\n ANNOTATIONS_FORMS: 0x10,\n ANNOTATIONS_STORAGE: 0x20,\n ANNOTATIONS_DISABLE: 0x40,\n OPLIST: 0x100\n};\nexports.RenderingIntentFlag = RenderingIntentFlag;\nconst AnnotationMode = {\n DISABLE: 0,\n ENABLE: 1,\n ENABLE_FORMS: 2,\n ENABLE_STORAGE: 3\n};\nexports.AnnotationMode = AnnotationMode;\nconst PermissionFlag = {\n PRINT: 0x04,\n MODIFY_CONTENTS: 0x08,\n COPY: 0x10,\n MODIFY_ANNOTATIONS: 0x20,\n FILL_INTERACTIVE_FORMS: 0x100,\n COPY_FOR_ACCESSIBILITY: 0x200,\n ASSEMBLE: 0x400,\n PRINT_HIGH_QUALITY: 0x800\n};\nexports.PermissionFlag = PermissionFlag;\nconst TextRenderingMode = {\n FILL: 0,\n STROKE: 1,\n FILL_STROKE: 2,\n INVISIBLE: 3,\n FILL_ADD_TO_PATH: 4,\n STROKE_ADD_TO_PATH: 5,\n FILL_STROKE_ADD_TO_PATH: 6,\n ADD_TO_PATH: 7,\n FILL_STROKE_MASK: 3,\n ADD_TO_PATH_FLAG: 4\n};\nexports.TextRenderingMode = TextRenderingMode;\nconst ImageKind = {\n GRAYSCALE_1BPP: 1,\n RGB_24BPP: 2,\n RGBA_32BPP: 3\n};\nexports.ImageKind = ImageKind;\nconst AnnotationType = {\n TEXT: 1,\n LINK: 2,\n FREETEXT: 3,\n LINE: 4,\n SQUARE: 5,\n CIRCLE: 6,\n POLYGON: 7,\n POLYLINE: 8,\n HIGHLIGHT: 9,\n UNDERLINE: 10,\n SQUIGGLY: 11,\n STRIKEOUT: 12,\n STAMP: 13,\n CARET: 14,\n INK: 15,\n POPUP: 16,\n FILEATTACHMENT: 17,\n SOUND: 18,\n MOVIE: 19,\n WIDGET: 20,\n SCREEN: 21,\n PRINTERMARK: 22,\n TRAPNET: 23,\n WATERMARK: 24,\n THREED: 25,\n REDACT: 26\n};\nexports.AnnotationType = AnnotationType;\nconst AnnotationStateModelType = {\n MARKED: "Marked",\n REVIEW: "Review"\n};\nexports.AnnotationStateModelType = AnnotationStateModelType;\nconst AnnotationMarkedState = {\n MARKED: "Marked",\n UNMARKED: "Unmarked"\n};\nexports.AnnotationMarkedState = AnnotationMarkedState;\nconst AnnotationReviewState = {\n ACCEPTED: "Accepted",\n REJECTED: "Rejected",\n CANCELLED: "Cancelled",\n COMPLETED: "Completed",\n NONE: "None"\n};\nexports.AnnotationReviewState = AnnotationReviewState;\nconst AnnotationReplyType = {\n GROUP: "Group",\n REPLY: "R"\n};\nexports.AnnotationReplyType = AnnotationReplyType;\nconst AnnotationFlag = {\n INVISIBLE: 0x01,\n HIDDEN: 0x02,\n PRINT: 0x04,\n NOZOOM: 0x08,\n NOROTATE: 0x10,\n NOVIEW: 0x20,\n READONLY: 0x40,\n LOCKED: 0x80,\n TOGGLENOVIEW: 0x100,\n LOCKEDCONTENTS: 0x200\n};\nexports.AnnotationFlag = AnnotationFlag;\nconst AnnotationFieldFlag = {\n READONLY: 0x0000001,\n REQUIRED: 0x0000002,\n NOEXPORT: 0x0000004,\n MULTILINE: 0x0001000,\n PASSWORD: 0x0002000,\n NOTOGGLETOOFF: 0x0004000,\n RADIO: 0x0008000,\n PUSHBUTTON: 0x0010000,\n COMBO: 0x0020000,\n EDIT: 0x0040000,\n SORT: 0x0080000,\n FILESELECT: 0x0100000,\n MULTISELECT: 0x0200000,\n DONOTSPELLCHECK: 0x0400000,\n DONOTSCROLL: 0x0800000,\n COMB: 0x1000000,\n RICHTEXT: 0x2000000,\n RADIOSINUNISON: 0x2000000,\n COMMITONSELCHANGE: 0x4000000\n};\nexports.AnnotationFieldFlag = AnnotationFieldFlag;\nconst AnnotationBorderStyleType = {\n SOLID: 1,\n DASHED: 2,\n BEVELED: 3,\n INSET: 4,\n UNDERLINE: 5\n};\nexports.AnnotationBorderStyleType = AnnotationBorderStyleType;\nconst AnnotationActionEventType = {\n E: "Mouse Enter",\n X: "Mouse Exit",\n D: "Mouse Down",\n U: "Mouse Up",\n Fo: "Focus",\n Bl: "Blur",\n PO: "PageOpen",\n PC: "PageClose",\n PV: "PageVisible",\n PI: "PageInvisible",\n K: "Keystroke",\n F: "Format",\n V: "Validate",\n C: "Calculate"\n};\nexports.AnnotationActionEventType = AnnotationActionEventType;\nconst DocumentActionEventType = {\n WC: "WillClose",\n WS: "WillSave",\n DS: "DidSave",\n WP: "WillPrint",\n DP: "DidPrint"\n};\nexports.DocumentActionEventType = DocumentActionEventType;\nconst PageActionEventType = {\n O: "PageOpen",\n C: "PageClose"\n};\nexports.PageActionEventType = PageActionEventType;\nconst StreamType = {\n UNKNOWN: "UNKNOWN",\n FLATE: "FLATE",\n LZW: "LZW",\n DCT: "DCT",\n JPX: "JPX",\n JBIG: "JBIG",\n A85: "A85",\n AHX: "AHX",\n CCF: "CCF",\n RLX: "RLX"\n};\nexports.StreamType = StreamType;\nconst FontType = {\n UNKNOWN: "UNKNOWN",\n TYPE1: "TYPE1",\n TYPE1STANDARD: "TYPE1STANDARD",\n TYPE1C: "TYPE1C",\n CIDFONTTYPE0: "CIDFONTTYPE0",\n CIDFONTTYPE0C: "CIDFONTTYPE0C",\n TRUETYPE: "TRUETYPE",\n CIDFONTTYPE2: "CIDFONTTYPE2",\n TYPE3: "TYPE3",\n OPENTYPE: "OPENTYPE",\n TYPE0: "TYPE0",\n MMTYPE1: "MMTYPE1"\n};\nexports.FontType = FontType;\nconst VerbosityLevel = {\n ERRORS: 0,\n WARNINGS: 1,\n INFOS: 5\n};\nexports.VerbosityLevel = VerbosityLevel;\nconst CMapCompressionType = {\n NONE: 0,\n BINARY: 1,\n STREAM: 2\n};\nexports.CMapCompressionType = CMapCompressionType;\nconst OPS = {\n dependency: 1,\n setLineWidth: 2,\n setLineCap: 3,\n setLineJoin: 4,\n setMiterLimit: 5,\n setDash: 6,\n setRenderingIntent: 7,\n setFlatness: 8,\n setGState: 9,\n save: 10,\n restore: 11,\n transform: 12,\n moveTo: 13,\n lineTo: 14,\n curveTo: 15,\n curveTo2: 16,\n curveTo3: 17,\n closePath: 18,\n rectangle: 19,\n stroke: 20,\n closeStroke: 21,\n fill: 22,\n eoFill: 23,\n fillStroke: 24,\n eoFillStroke: 25,\n closeFillStroke: 26,\n closeEOFillStroke: 27,\n endPath: 28,\n clip: 29,\n eoClip: 30,\n beginText: 31,\n endText: 32,\n setCharSpacing: 33,\n setWordSpacing: 34,\n setHScale: 35,\n setLeading: 36,\n setFont: 37,\n setTextRenderingMode: 38,\n setTextRise: 39,\n moveText: 40,\n setLeadingMoveText: 41,\n setTextMatrix: 42,\n nextLine: 43,\n showText: 44,\n showSpacedText: 45,\n nextLineShowText: 46,\n nextLineSetSpacingShowText: 47,\n setCharWidth: 48,\n setCharWidthAndBounds: 49,\n setStrokeColorSpace: 50,\n setFillColorSpace: 51,\n setStrokeColor: 52,\n setStrokeColorN: 53,\n setFillColor: 54,\n setFillColorN: 55,\n setStrokeGray: 56,\n setFillGray: 57,\n setStrokeRGBColor: 58,\n setFillRGBColor: 59,\n setStrokeCMYKColor: 60,\n setFillCMYKColor: 61,\n shadingFill: 62,\n beginInlineImage: 63,\n beginImageData: 64,\n endInlineImage: 65,\n paintXObject: 66,\n markPoint: 67,\n markPointProps: 68,\n beginMarkedContent: 69,\n beginMarkedContentProps: 70,\n endMarkedContent: 71,\n beginCompat: 72,\n endCompat: 73,\n paintFormXObjectBegin: 74,\n paintFormXObjectEnd: 75,\n beginGroup: 76,\n endGroup: 77,\n beginAnnotations: 78,\n endAnnotations: 79,\n beginAnnotation: 80,\n endAnnotation: 81,\n paintJpegXObject: 82,\n paintImageMaskXObject: 83,\n paintImageMaskXObjectGroup: 84,\n paintImageXObject: 85,\n paintInlineImageXObject: 86,\n paintInlineImageXObjectGroup: 87,\n paintImageXObjectRepeat: 88,\n paintImageMaskXObjectRepeat: 89,\n paintSolidColorImageMask: 90,\n constructPath: 91\n};\nexports.OPS = OPS;\nconst UNSUPPORTED_FEATURES = {\n unknown: "unknown",\n forms: "forms",\n javaScript: "javaScript",\n signatures: "signatures",\n smask: "smask",\n shadingPattern: "shadingPattern",\n font: "font",\n errorTilingPattern: "errorTilingPattern",\n errorExtGState: "errorExtGState",\n errorXObject: "errorXObject",\n errorFontLoadType3: "errorFontLoadType3",\n errorFontState: "errorFontState",\n errorFontMissing: "errorFontMissing",\n errorFontTranslate: "errorFontTranslate",\n errorColorSpace: "errorColorSpace",\n errorOperatorList: "errorOperatorList",\n errorFontToUnicode: "errorFontToUnicode",\n errorFontLoadNative: "errorFontLoadNative",\n errorFontBuildPath: "errorFontBuildPath",\n errorFontGetPath: "errorFontGetPath",\n errorMarkedContent: "errorMarkedContent",\n errorContentSubStream: "errorContentSubStream"\n};\nexports.UNSUPPORTED_FEATURES = UNSUPPORTED_FEATURES;\nconst PasswordResponses = {\n NEED_PASSWORD: 1,\n INCORRECT_PASSWORD: 2\n};\nexports.PasswordResponses = PasswordResponses;\nlet verbosity = VerbosityLevel.WARNINGS;\n\nfunction setVerbosityLevel(level) {\n if (Number.isInteger(level)) {\n verbosity = level;\n }\n}\n\nfunction getVerbosityLevel() {\n return verbosity;\n}\n\nfunction info(msg) {\n if (verbosity >= VerbosityLevel.INFOS) {\n console.log(`Info: ${msg}`);\n }\n}\n\nfunction warn(msg) {\n if (verbosity >= VerbosityLevel.WARNINGS) {\n console.log(`Warning: ${msg}`);\n }\n}\n\nfunction unreachable(msg) {\n throw new Error(msg);\n}\n\nfunction assert(cond, msg) {\n if (!cond) {\n unreachable(msg);\n }\n}\n\nfunction _isValidProtocol(url) {\n if (!url) {\n return false;\n }\n\n switch (url.protocol) {\n case "http:":\n case "https:":\n case "ftp:":\n case "mailto:":\n case "tel:":\n return true;\n\n default:\n return false;\n }\n}\n\nfunction createValidAbsoluteUrl(url, baseUrl = null, options = null) {\n if (!url) {\n return null;\n }\n\n try {\n if (options && typeof url === "string") {\n if (options.addDefaultProtocol && url.startsWith("www.")) {\n const dots = url.match(/\\./g);\n\n if (dots && dots.length >= 2) {\n url = `http://${url}`;\n }\n }\n\n if (options.tryConvertEncoding) {\n try {\n url = stringToUTF8String(url);\n } catch (ex) {}\n }\n }\n\n const absoluteUrl = baseUrl ? new URL(url, baseUrl) : new URL(url);\n\n if (_isValidProtocol(absoluteUrl)) {\n return absoluteUrl;\n }\n } catch (ex) {}\n\n return null;\n}\n\nfunction shadow(obj, prop, value) {\n Object.defineProperty(obj, prop, {\n value,\n enumerable: true,\n configurable: true,\n writable: false\n });\n return value;\n}\n\nconst BaseException = function BaseExceptionClosure() {\n function BaseException(message, name) {\n if (this.constructor === BaseException) {\n unreachable("Cannot initialize BaseException.");\n }\n\n this.message = message;\n this.name = name;\n }\n\n BaseException.prototype = new Error();\n BaseException.constructor = BaseException;\n return BaseException;\n}();\n\nexports.BaseException = BaseException;\n\nclass PasswordException extends BaseException {\n constructor(msg, code) {\n super(msg, "PasswordException");\n this.code = code;\n }\n\n}\n\nexports.PasswordException = PasswordException;\n\nclass UnknownErrorException extends BaseException {\n constructor(msg, details) {\n super(msg, "UnknownErrorException");\n this.details = details;\n }\n\n}\n\nexports.UnknownErrorException = UnknownErrorException;\n\nclass InvalidPDFException extends BaseException {\n constructor(msg) {\n super(msg, "InvalidPDFException");\n }\n\n}\n\nexports.InvalidPDFException = InvalidPDFException;\n\nclass MissingPDFException extends BaseException {\n constructor(msg) {\n super(msg, "MissingPDFException");\n }\n\n}\n\nexports.MissingPDFException = MissingPDFException;\n\nclass UnexpectedResponseException extends BaseException {\n constructor(msg, status) {\n super(msg, "UnexpectedResponseException");\n this.status = status;\n }\n\n}\n\nexports.UnexpectedResponseException = UnexpectedResponseException;\n\nclass FormatError extends BaseException {\n constructor(msg) {\n super(msg, "FormatError");\n }\n\n}\n\nexports.FormatError = FormatError;\n\nclass AbortException extends BaseException {\n constructor(msg) {\n super(msg, "AbortException");\n }\n\n}\n\nexports.AbortException = AbortException;\n\nfunction bytesToString(bytes) {\n if (typeof bytes !== "object" || bytes === null || bytes.length === undefined) {\n unreachable("Invalid argument for bytesToString");\n }\n\n const length = bytes.length;\n const MAX_ARGUMENT_COUNT = 8192;\n\n if (length < MAX_ARGUMENT_COUNT) {\n return String.fromCharCode.apply(null, bytes);\n }\n\n const strBuf = [];\n\n for (let i = 0; i < length; i += MAX_ARGUMENT_COUNT) {\n const chunkEnd = Math.min(i + MAX_ARGUMENT_COUNT, length);\n const chunk = bytes.subarray(i, chunkEnd);\n strBuf.push(String.fromCharCode.apply(null, chunk));\n }\n\n return strBuf.join("");\n}\n\nfunction stringToBytes(str) {\n if (typeof str !== "string") {\n unreachable("Invalid argument for stringToBytes");\n }\n\n const length = str.length;\n const bytes = new Uint8Array(length);\n\n for (let i = 0; i < length; ++i) {\n bytes[i] = str.charCodeAt(i) & 0xff;\n }\n\n return bytes;\n}\n\nfunction arrayByteLength(arr) {\n if (arr.length !== undefined) {\n return arr.length;\n }\n\n if (arr.byteLength !== undefined) {\n return arr.byteLength;\n }\n\n unreachable("Invalid argument for arrayByteLength");\n}\n\nfunction arraysToBytes(arr) {\n const length = arr.length;\n\n if (length === 1 && arr[0] instanceof Uint8Array) {\n return arr[0];\n }\n\n let resultLength = 0;\n\n for (let i = 0; i < length; i++) {\n resultLength += arrayByteLength(arr[i]);\n }\n\n let pos = 0;\n const data = new Uint8Array(resultLength);\n\n for (let i = 0; i < length; i++) {\n let item = arr[i];\n\n if (!(item instanceof Uint8Array)) {\n if (typeof item === "string") {\n item = stringToBytes(item);\n } else {\n item = new Uint8Array(item);\n }\n }\n\n const itemLength = item.byteLength;\n data.set(item, pos);\n pos += itemLength;\n }\n\n return data;\n}\n\nfunction string32(value) {\n return String.fromCharCode(value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff);\n}\n\nfunction objectSize(obj) {\n return Object.keys(obj).length;\n}\n\nfunction objectFromMap(map) {\n const obj = Object.create(null);\n\n for (const [key, value] of map) {\n obj[key] = value;\n }\n\n return obj;\n}\n\nfunction isLittleEndian() {\n const buffer8 = new Uint8Array(4);\n buffer8[0] = 1;\n const view32 = new Uint32Array(buffer8.buffer, 0, 1);\n return view32[0] === 1;\n}\n\nfunction isEvalSupported() {\n try {\n new Function("");\n return true;\n } catch (e) {\n return false;\n }\n}\n\nclass FeatureTest {\n static get isLittleEndian() {\n return shadow(this, "isLittleEndian", isLittleEndian());\n }\n\n static get isEvalSupported() {\n return shadow(this, "isEvalSupported", isEvalSupported());\n }\n\n static get isOffscreenCanvasSupported() {\n return shadow(this, "isOffscreenCanvasSupported", typeof OffscreenCanvas !== "undefined");\n }\n\n}\n\nexports.FeatureTest = FeatureTest;\nconst hexNumbers = [...Array(256).keys()].map(n => n.toString(16).padStart(2, "0"));\n\nclass Util {\n static makeHexColor(r, g, b) {\n return `#${hexNumbers[r]}${hexNumbers[g]}${hexNumbers[b]}`;\n }\n\n static scaleMinMax(transform, minMax) {\n let temp;\n\n if (transform[0]) {\n if (transform[0] < 0) {\n temp = minMax[0];\n minMax[0] = minMax[1];\n minMax[1] = temp;\n }\n\n minMax[0] *= transform[0];\n minMax[1] *= transform[0];\n\n if (transform[3] < 0) {\n temp = minMax[2];\n minMax[2] = minMax[3];\n minMax[3] = temp;\n }\n\n minMax[2] *= transform[3];\n minMax[3] *= transform[3];\n } else {\n temp = minMax[0];\n minMax[0] = minMax[2];\n minMax[2] = temp;\n temp = minMax[1];\n minMax[1] = minMax[3];\n minMax[3] = temp;\n\n if (transform[1] < 0) {\n temp = minMax[2];\n minMax[2] = minMax[3];\n minMax[3] = temp;\n }\n\n minMax[2] *= transform[1];\n minMax[3] *= transform[1];\n\n if (transform[2] < 0) {\n temp = minMax[0];\n minMax[0] = minMax[1];\n minMax[1] = temp;\n }\n\n minMax[0] *= transform[2];\n minMax[1] *= transform[2];\n }\n\n minMax[0] += transform[4];\n minMax[1] += transform[4];\n minMax[2] += transform[5];\n minMax[3] += transform[5];\n }\n\n static transform(m1, m2) {\n return [m1[0] * m2[0] + m1[2] * m2[1], m1[1] * m2[0] + m1[3] * m2[1], m1[0] * m2[2] + m1[2] * m2[3], m1[1] * m2[2] + m1[3] * m2[3], m1[0] * m2[4] + m1[2] * m2[5] + m1[4], m1[1] * m2[4] + m1[3] * m2[5] + m1[5]];\n }\n\n static applyTransform(p, m) {\n const xt = p[0] * m[0] + p[1] * m[2] + m[4];\n const yt = p[0] * m[1] + p[1] * m[3] + m[5];\n return [xt, yt];\n }\n\n static applyInverseTransform(p, m) {\n const d = m[0] * m[3] - m[1] * m[2];\n const xt = (p[0] * m[3] - p[1] * m[2] + m[2] * m[5] - m[4] * m[3]) / d;\n const yt = (-p[0] * m[1] + p[1] * m[0] + m[4] * m[1] - m[5] * m[0]) / d;\n return [xt, yt];\n }\n\n static getAxialAlignedBoundingBox(r, m) {\n const p1 = Util.applyTransform(r, m);\n const p2 = Util.applyTransform(r.slice(2, 4), m);\n const p3 = Util.applyTransform([r[0], r[3]], m);\n const p4 = Util.applyTransform([r[2], r[1]], m);\n return [Math.min(p1[0], p2[0], p3[0], p4[0]), Math.min(p1[1], p2[1], p3[1], p4[1]), Math.max(p1[0], p2[0], p3[0], p4[0]), Math.max(p1[1], p2[1], p3[1], p4[1])];\n }\n\n static inverseTransform(m) {\n const d = m[0] * m[3] - m[1] * m[2];\n return [m[3] / d, -m[1] / d, -m[2] / d, m[0] / d, (m[2] * m[5] - m[4] * m[3]) / d, (m[4] * m[1] - m[5] * m[0]) / d];\n }\n\n static apply3dTransform(m, v) {\n return [m[0] * v[0] + m[1] * v[1] + m[2] * v[2], m[3] * v[0] + m[4] * v[1] + m[5] * v[2], m[6] * v[0] + m[7] * v[1] + m[8] * v[2]];\n }\n\n static singularValueDecompose2dScale(m) {\n const transpose = [m[0], m[2], m[1], m[3]];\n const a = m[0] * transpose[0] + m[1] * transpose[2];\n const b = m[0] * transpose[1] + m[1] * transpose[3];\n const c = m[2] * transpose[0] + m[3] * transpose[2];\n const d = m[2] * transpose[1] + m[3] * transpose[3];\n const first = (a + d) / 2;\n const second = Math.sqrt((a + d) ** 2 - 4 * (a * d - c * b)) / 2;\n const sx = first + second || 1;\n const sy = first - second || 1;\n return [Math.sqrt(sx), Math.sqrt(sy)];\n }\n\n static normalizeRect(rect) {\n const r = rect.slice(0);\n\n if (rect[0] > rect[2]) {\n r[0] = rect[2];\n r[2] = rect[0];\n }\n\n if (rect[1] > rect[3]) {\n r[1] = rect[3];\n r[3] = rect[1];\n }\n\n return r;\n }\n\n static intersect(rect1, rect2) {\n const xLow = Math.max(Math.min(rect1[0], rect1[2]), Math.min(rect2[0], rect2[2]));\n const xHigh = Math.min(Math.max(rect1[0], rect1[2]), Math.max(rect2[0], rect2[2]));\n\n if (xLow > xHigh) {\n return null;\n }\n\n const yLow = Math.max(Math.min(rect1[1], rect1[3]), Math.min(rect2[1], rect2[3]));\n const yHigh = Math.min(Math.max(rect1[1], rect1[3]), Math.max(rect2[1], rect2[3]));\n\n if (yLow > yHigh) {\n return null;\n }\n\n return [xLow, yLow, xHigh, yHigh];\n }\n\n static bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3) {\n const tvalues = [],\n bounds = [[], []];\n let a, b, c, t, t1, t2, b2ac, sqrtb2ac;\n\n for (let i = 0; i < 2; ++i) {\n if (i === 0) {\n b = 6 * x0 - 12 * x1 + 6 * x2;\n a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;\n c = 3 * x1 - 3 * x0;\n } else {\n b = 6 * y0 - 12 * y1 + 6 * y2;\n a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;\n c = 3 * y1 - 3 * y0;\n }\n\n if (Math.abs(a) < 1e-12) {\n if (Math.abs(b) < 1e-12) {\n continue;\n }\n\n t = -c / b;\n\n if (0 < t && t < 1) {\n tvalues.push(t);\n }\n\n continue;\n }\n\n b2ac = b * b - 4 * c * a;\n sqrtb2ac = Math.sqrt(b2ac);\n\n if (b2ac < 0) {\n continue;\n }\n\n t1 = (-b + sqrtb2ac) / (2 * a);\n\n if (0 < t1 && t1 < 1) {\n tvalues.push(t1);\n }\n\n t2 = (-b - sqrtb2ac) / (2 * a);\n\n if (0 < t2 && t2 < 1) {\n tvalues.push(t2);\n }\n }\n\n let j = tvalues.length,\n mt;\n const jlen = j;\n\n while (j--) {\n t = tvalues[j];\n mt = 1 - t;\n bounds[0][j] = mt * mt * mt * x0 + 3 * mt * mt * t * x1 + 3 * mt * t * t * x2 + t * t * t * x3;\n bounds[1][j] = mt * mt * mt * y0 + 3 * mt * mt * t * y1 + 3 * mt * t * t * y2 + t * t * t * y3;\n }\n\n bounds[0][jlen] = x0;\n bounds[1][jlen] = y0;\n bounds[0][jlen + 1] = x3;\n bounds[1][jlen + 1] = y3;\n bounds[0].length = bounds[1].length = jlen + 2;\n return [Math.min(...bounds[0]), Math.min(...bounds[1]), Math.max(...bounds[0]), Math.max(...bounds[1])];\n }\n\n}\n\nexports.Util = Util;\nconst PDFStringTranslateTable = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2d8, 0x2c7, 0x2c6, 0x2d9, 0x2dd, 0x2db, 0x2da, 0x2dc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x192, 0x2044, 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018, 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x141, 0x152, 0x160, 0x178, 0x17d, 0x131, 0x142, 0x153, 0x161, 0x17e, 0, 0x20ac];\n\nfunction stringToPDFString(str) {\n if (str[0] >= "\\xEF") {\n let encoding;\n\n if (str[0] === "\\xFE" && str[1] === "\\xFF") {\n encoding = "utf-16be";\n } else if (str[0] === "\\xFF" && str[1] === "\\xFE") {\n encoding = "utf-16le";\n } else if (str[0] === "\\xEF" && str[1] === "\\xBB" && str[2] === "\\xBF") {\n encoding = "utf-8";\n }\n\n if (encoding) {\n try {\n const decoder = new TextDecoder(encoding, {\n fatal: true\n });\n const buffer = stringToBytes(str);\n return decoder.decode(buffer);\n } catch (ex) {\n warn(`stringToPDFString: "${ex}".`);\n }\n }\n }\n\n const strBuf = [];\n\n for (let i = 0, ii = str.length; i < ii; i++) {\n const code = PDFStringTranslateTable[str.charCodeAt(i)];\n strBuf.push(code ? String.fromCharCode(code) : str.charAt(i));\n }\n\n return strBuf.join("");\n}\n\nfunction escapeString(str) {\n return str.replace(/([()\\\\\\n\\r])/g, match => {\n if (match === "\\n") {\n return "\\\\n";\n } else if (match === "\\r") {\n return "\\\\r";\n }\n\n return `\\\\${match}`;\n });\n}\n\nfunction isAscii(str) {\n return /^[\\x00-\\x7F]*$/.test(str);\n}\n\nfunction stringToUTF16BEString(str) {\n const buf = ["\\xFE\\xFF"];\n\n for (let i = 0, ii = str.length; i < ii; i++) {\n const char = str.charCodeAt(i);\n buf.push(String.fromCharCode(char >> 8 & 0xff), String.fromCharCode(char & 0xff));\n }\n\n return buf.join("");\n}\n\nfunction stringToUTF8String(str) {\n return decodeURIComponent(escape(str));\n}\n\nfunction utf8StringToString(str) {\n return unescape(encodeURIComponent(str));\n}\n\nfunction isArrayBuffer(v) {\n return typeof v === "object" && v !== null && v.byteLength !== undefined;\n}\n\nfunction isArrayEqual(arr1, arr2) {\n if (arr1.length !== arr2.length) {\n return false;\n }\n\n for (let i = 0, ii = arr1.length; i < ii; i++) {\n if (arr1[i] !== arr2[i]) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction getModificationDate(date = new Date()) {\n const buffer = [date.getUTCFullYear().toString(), (date.getUTCMonth() + 1).toString().padStart(2, "0"), date.getUTCDate().toString().padStart(2, "0"), date.getUTCHours().toString().padStart(2, "0"), date.getUTCMinutes().toString().padStart(2, "0"), date.getUTCSeconds().toString().padStart(2, "0")];\n return buffer.join("");\n}\n\nfunction createPromiseCapability() {\n const capability = Object.create(null);\n let isSettled = false;\n Object.defineProperty(capability, "settled", {\n get() {\n return isSettled;\n }\n\n });\n capability.promise = new Promise(function (resolve, reject) {\n capability.resolve = function (data) {\n isSettled = true;\n resolve(data);\n };\n\n capability.reject = function (reason) {\n isSettled = true;\n reject(reason);\n };\n });\n return capability;\n}\n\n/***/ }),\n/* 2 */\n/***/ ((__unused_webpack_module, __unused_webpack_exports, __w_pdfjs_require__) => {\n\n\n\nvar _is_node = __w_pdfjs_require__(3);\n\n;\n\n/***/ }),\n/* 3 */\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.isNodeJS = void 0;\nconst isNodeJS = typeof process === "object" && process + "" === "[object process]" && !process.versions.nw && !(process.versions.electron && process.type && process.type !== "browser");\nexports.isNodeJS = isNodeJS;\n\n/***/ }),\n/* 4 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.build = exports.RenderTask = exports.PDFWorkerUtil = exports.PDFWorker = exports.PDFPageProxy = exports.PDFDocumentProxy = exports.PDFDocumentLoadingTask = exports.PDFDataRangeTransport = exports.LoopbackPort = exports.DefaultStandardFontDataFactory = exports.DefaultCanvasFactory = exports.DefaultCMapReaderFactory = void 0;\nexports.getDocument = getDocument;\nexports.setPDFNetworkStreamFactory = setPDFNetworkStreamFactory;\nexports.version = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _display_utils = __w_pdfjs_require__(5);\n\nvar _font_loader = __w_pdfjs_require__(7);\n\nvar _annotation_storage = __w_pdfjs_require__(8);\n\nvar _canvas = __w_pdfjs_require__(10);\n\nvar _worker_options = __w_pdfjs_require__(13);\n\nvar _is_node = __w_pdfjs_require__(3);\n\nvar _message_handler = __w_pdfjs_require__(14);\n\nvar _metadata = __w_pdfjs_require__(15);\n\nvar _optional_content_config = __w_pdfjs_require__(16);\n\nvar _transport_stream = __w_pdfjs_require__(17);\n\nvar _xfa_text = __w_pdfjs_require__(18);\n\nconst DEFAULT_RANGE_CHUNK_SIZE = 65536;\nconst RENDERING_CANCELLED_TIMEOUT = 100;\nlet DefaultCanvasFactory = _display_utils.DOMCanvasFactory;\nexports.DefaultCanvasFactory = DefaultCanvasFactory;\nlet DefaultCMapReaderFactory = _display_utils.DOMCMapReaderFactory;\nexports.DefaultCMapReaderFactory = DefaultCMapReaderFactory;\nlet DefaultStandardFontDataFactory = _display_utils.DOMStandardFontDataFactory;\nexports.DefaultStandardFontDataFactory = DefaultStandardFontDataFactory;\n\nif (_is_node.isNodeJS) {\n const {\n NodeCanvasFactory,\n NodeCMapReaderFactory,\n NodeStandardFontDataFactory\n } = __w_pdfjs_require__(19);\n\n exports.DefaultCanvasFactory = DefaultCanvasFactory = NodeCanvasFactory;\n exports.DefaultCMapReaderFactory = DefaultCMapReaderFactory = NodeCMapReaderFactory;\n exports.DefaultStandardFontDataFactory = DefaultStandardFontDataFactory = NodeStandardFontDataFactory;\n}\n\nlet createPDFNetworkStream;\n\nfunction setPDFNetworkStreamFactory(pdfNetworkStreamFactory) {\n createPDFNetworkStream = pdfNetworkStreamFactory;\n}\n\nfunction getDocument(src) {\n const task = new PDFDocumentLoadingTask();\n let source;\n\n if (typeof src === "string" || src instanceof URL) {\n source = {\n url: src\n };\n } else if ((0, _util.isArrayBuffer)(src)) {\n source = {\n data: src\n };\n } else if (src instanceof PDFDataRangeTransport) {\n source = {\n range: src\n };\n } else {\n if (typeof src !== "object") {\n throw new Error("Invalid parameter in getDocument, " + "need either string, URL, Uint8Array, or parameter object.");\n }\n\n if (!src.url && !src.data && !src.range) {\n throw new Error("Invalid parameter object: need either .data, .range or .url");\n }\n\n source = src;\n }\n\n const params = Object.create(null);\n let rangeTransport = null,\n worker = null;\n\n for (const key in source) {\n const value = source[key];\n\n switch (key) {\n case "url":\n if (typeof window !== "undefined") {\n try {\n params[key] = new URL(value, window.location).href;\n continue;\n } catch (ex) {\n (0, _util.warn)(`Cannot create valid URL: "${ex}".`);\n }\n } else if (typeof value === "string" || value instanceof URL) {\n params[key] = value.toString();\n continue;\n }\n\n throw new Error("Invalid PDF url data: " + "either string or URL-object is expected in the url property.");\n\n case "range":\n rangeTransport = value;\n continue;\n\n case "worker":\n worker = value;\n continue;\n\n case "data":\n if (_is_node.isNodeJS && typeof Buffer !== "undefined" && value instanceof Buffer) {\n params[key] = new Uint8Array(value);\n } else if (value instanceof Uint8Array) {\n break;\n } else if (typeof value === "string") {\n params[key] = (0, _util.stringToBytes)(value);\n } else if (typeof value === "object" && value !== null && !isNaN(value.length)) {\n params[key] = new Uint8Array(value);\n } else if ((0, _util.isArrayBuffer)(value)) {\n params[key] = new Uint8Array(value);\n } else {\n throw new Error("Invalid PDF binary data: either typed array, " + "string, or array-like object is expected in the data property.");\n }\n\n continue;\n }\n\n params[key] = value;\n }\n\n params.CMapReaderFactory = params.CMapReaderFactory || DefaultCMapReaderFactory;\n params.StandardFontDataFactory = params.StandardFontDataFactory || DefaultStandardFontDataFactory;\n params.ignoreErrors = params.stopAtErrors !== true;\n params.fontExtraProperties = params.fontExtraProperties === true;\n params.pdfBug = params.pdfBug === true;\n params.enableXfa = params.enableXfa === true;\n\n if (!Number.isInteger(params.rangeChunkSize) || params.rangeChunkSize < 1) {\n params.rangeChunkSize = DEFAULT_RANGE_CHUNK_SIZE;\n }\n\n if (typeof params.docBaseUrl !== "string" || (0, _display_utils.isDataScheme)(params.docBaseUrl)) {\n params.docBaseUrl = null;\n }\n\n if (!Number.isInteger(params.maxImageSize) || params.maxImageSize < -1) {\n params.maxImageSize = -1;\n }\n\n if (typeof params.cMapUrl !== "string") {\n params.cMapUrl = null;\n }\n\n if (typeof params.standardFontDataUrl !== "string") {\n params.standardFontDataUrl = null;\n }\n\n if (typeof params.useWorkerFetch !== "boolean") {\n params.useWorkerFetch = params.CMapReaderFactory === _display_utils.DOMCMapReaderFactory && params.StandardFontDataFactory === _display_utils.DOMStandardFontDataFactory;\n }\n\n if (typeof params.isEvalSupported !== "boolean") {\n params.isEvalSupported = true;\n }\n\n if (typeof params.disableFontFace !== "boolean") {\n params.disableFontFace = _is_node.isNodeJS;\n }\n\n if (typeof params.useSystemFonts !== "boolean") {\n params.useSystemFonts = !_is_node.isNodeJS && !params.disableFontFace;\n }\n\n if (typeof params.ownerDocument !== "object" || params.ownerDocument === null) {\n params.ownerDocument = globalThis.document;\n }\n\n if (typeof params.disableRange !== "boolean") {\n params.disableRange = false;\n }\n\n if (typeof params.disableStream !== "boolean") {\n params.disableStream = false;\n }\n\n if (typeof params.disableAutoFetch !== "boolean") {\n params.disableAutoFetch = false;\n }\n\n (0, _util.setVerbosityLevel)(params.verbosity);\n\n if (!worker) {\n const workerParams = {\n verbosity: params.verbosity,\n port: _worker_options.GlobalWorkerOptions.workerPort\n };\n worker = workerParams.port ? PDFWorker.fromPort(workerParams) : new PDFWorker(workerParams);\n task._worker = worker;\n }\n\n const docId = task.docId;\n worker.promise.then(function () {\n if (task.destroyed) {\n throw new Error("Loading aborted");\n }\n\n const workerIdPromise = _fetchDocument(worker, params, rangeTransport, docId);\n\n const networkStreamPromise = new Promise(function (resolve) {\n let networkStream;\n\n if (rangeTransport) {\n networkStream = new _transport_stream.PDFDataTransportStream({\n length: params.length,\n initialData: params.initialData,\n progressiveDone: params.progressiveDone,\n contentDispositionFilename: params.contentDispositionFilename,\n disableRange: params.disableRange,\n disableStream: params.disableStream\n }, rangeTransport);\n } else if (!params.data) {\n networkStream = createPDFNetworkStream({\n url: params.url,\n length: params.length,\n httpHeaders: params.httpHeaders,\n withCredentials: params.withCredentials,\n rangeChunkSize: params.rangeChunkSize,\n disableRange: params.disableRange,\n disableStream: params.disableStream\n });\n }\n\n resolve(networkStream);\n });\n return Promise.all([workerIdPromise, networkStreamPromise]).then(function ([workerId, networkStream]) {\n if (task.destroyed) {\n throw new Error("Loading aborted");\n }\n\n const messageHandler = new _message_handler.MessageHandler(docId, workerId, worker.port);\n const transport = new WorkerTransport(messageHandler, task, networkStream, params);\n task._transport = transport;\n messageHandler.send("Ready", null);\n });\n }).catch(task._capability.reject);\n return task;\n}\n\nasync function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {\n if (worker.destroyed) {\n throw new Error("Worker was destroyed");\n }\n\n if (pdfDataRangeTransport) {\n source.length = pdfDataRangeTransport.length;\n source.initialData = pdfDataRangeTransport.initialData;\n source.progressiveDone = pdfDataRangeTransport.progressiveDone;\n source.contentDispositionFilename = pdfDataRangeTransport.contentDispositionFilename;\n }\n\n const workerId = await worker.messageHandler.sendWithPromise("GetDocRequest", {\n docId,\n apiVersion: \'2.14.305\',\n source: {\n data: source.data,\n url: source.url,\n password: source.password,\n disableAutoFetch: source.disableAutoFetch,\n rangeChunkSize: source.rangeChunkSize,\n length: source.length\n },\n maxImageSize: source.maxImageSize,\n disableFontFace: source.disableFontFace,\n docBaseUrl: source.docBaseUrl,\n ignoreErrors: source.ignoreErrors,\n isEvalSupported: source.isEvalSupported,\n fontExtraProperties: source.fontExtraProperties,\n enableXfa: source.enableXfa,\n useSystemFonts: source.useSystemFonts,\n cMapUrl: source.useWorkerFetch ? source.cMapUrl : null,\n standardFontDataUrl: source.useWorkerFetch ? source.standardFontDataUrl : null\n });\n\n if (worker.destroyed) {\n throw new Error("Worker was destroyed");\n }\n\n return workerId;\n}\n\nclass PDFDocumentLoadingTask {\n static #docId = 0;\n\n constructor() {\n this._capability = (0, _util.createPromiseCapability)();\n this._transport = null;\n this._worker = null;\n this.docId = `d${PDFDocumentLoadingTask.#docId++}`;\n this.destroyed = false;\n this.onPassword = null;\n this.onProgress = null;\n this.onUnsupportedFeature = null;\n }\n\n get promise() {\n return this._capability.promise;\n }\n\n async destroy() {\n this.destroyed = true;\n await this._transport?.destroy();\n this._transport = null;\n\n if (this._worker) {\n this._worker.destroy();\n\n this._worker = null;\n }\n }\n\n}\n\nexports.PDFDocumentLoadingTask = PDFDocumentLoadingTask;\n\nclass PDFDataRangeTransport {\n constructor(length, initialData, progressiveDone = false, contentDispositionFilename = null) {\n this.length = length;\n this.initialData = initialData;\n this.progressiveDone = progressiveDone;\n this.contentDispositionFilename = contentDispositionFilename;\n this._rangeListeners = [];\n this._progressListeners = [];\n this._progressiveReadListeners = [];\n this._progressiveDoneListeners = [];\n this._readyCapability = (0, _util.createPromiseCapability)();\n }\n\n addRangeListener(listener) {\n this._rangeListeners.push(listener);\n }\n\n addProgressListener(listener) {\n this._progressListeners.push(listener);\n }\n\n addProgressiveReadListener(listener) {\n this._progressiveReadListeners.push(listener);\n }\n\n addProgressiveDoneListener(listener) {\n this._progressiveDoneListeners.push(listener);\n }\n\n onDataRange(begin, chunk) {\n for (const listener of this._rangeListeners) {\n listener(begin, chunk);\n }\n }\n\n onDataProgress(loaded, total) {\n this._readyCapability.promise.then(() => {\n for (const listener of this._progressListeners) {\n listener(loaded, total);\n }\n });\n }\n\n onDataProgressiveRead(chunk) {\n this._readyCapability.promise.then(() => {\n for (const listener of this._progressiveReadListeners) {\n listener(chunk);\n }\n });\n }\n\n onDataProgressiveDone() {\n this._readyCapability.promise.then(() => {\n for (const listener of this._progressiveDoneListeners) {\n listener();\n }\n });\n }\n\n transportReady() {\n this._readyCapability.resolve();\n }\n\n requestDataRange(begin, end) {\n (0, _util.unreachable)("Abstract method PDFDataRangeTransport.requestDataRange");\n }\n\n abort() {}\n\n}\n\nexports.PDFDataRangeTransport = PDFDataRangeTransport;\n\nclass PDFDocumentProxy {\n constructor(pdfInfo, transport) {\n this._pdfInfo = pdfInfo;\n this._transport = transport;\n Object.defineProperty(this, "fingerprint", {\n get() {\n (0, _display_utils.deprecated)("`PDFDocumentProxy.fingerprint`, " + "please use `PDFDocumentProxy.fingerprints` instead.");\n return this.fingerprints[0];\n }\n\n });\n Object.defineProperty(this, "getStats", {\n value: async () => {\n (0, _display_utils.deprecated)("`PDFDocumentProxy.getStats`, " + "please use the `PDFDocumentProxy.stats`-getter instead.");\n return this.stats || {\n streamTypes: {},\n fontTypes: {}\n };\n }\n });\n }\n\n get annotationStorage() {\n return this._transport.annotationStorage;\n }\n\n get numPages() {\n return this._pdfInfo.numPages;\n }\n\n get fingerprints() {\n return this._pdfInfo.fingerprints;\n }\n\n get stats() {\n return this._transport.stats;\n }\n\n get isPureXfa() {\n return !!this._transport._htmlForXfa;\n }\n\n get allXfaHtml() {\n return this._transport._htmlForXfa;\n }\n\n getPage(pageNumber) {\n return this._transport.getPage(pageNumber);\n }\n\n getPageIndex(ref) {\n return this._transport.getPageIndex(ref);\n }\n\n getDestinations() {\n return this._transport.getDestinations();\n }\n\n getDestination(id) {\n return this._transport.getDestination(id);\n }\n\n getPageLabels() {\n return this._transport.getPageLabels();\n }\n\n getPageLayout() {\n return this._transport.getPageLayout();\n }\n\n getPageMode() {\n return this._transport.getPageMode();\n }\n\n getViewerPreferences() {\n return this._transport.getViewerPreferences();\n }\n\n getOpenAction() {\n return this._transport.getOpenAction();\n }\n\n getAttachments() {\n return this._transport.getAttachments();\n }\n\n getJavaScript() {\n return this._transport.getJavaScript();\n }\n\n getJSActions() {\n return this._transport.getDocJSActions();\n }\n\n getOutline() {\n return this._transport.getOutline();\n }\n\n getOptionalContentConfig() {\n return this._transport.getOptionalContentConfig();\n }\n\n getPermissions() {\n return this._transport.getPermissions();\n }\n\n getMetadata() {\n return this._transport.getMetadata();\n }\n\n getMarkInfo() {\n return this._transport.getMarkInfo();\n }\n\n getData() {\n return this._transport.getData();\n }\n\n getDownloadInfo() {\n return this._transport.downloadInfoCapability.promise;\n }\n\n cleanup(keepLoadedFonts = false) {\n return this._transport.startCleanup(keepLoadedFonts || this.isPureXfa);\n }\n\n destroy() {\n return this.loadingTask.destroy();\n }\n\n get loadingParams() {\n return this._transport.loadingParams;\n }\n\n get loadingTask() {\n return this._transport.loadingTask;\n }\n\n saveDocument() {\n if (this._transport.annotationStorage.size <= 0) {\n (0, _display_utils.deprecated)("saveDocument called while `annotationStorage` is empty, " + "please use the getData-method instead.");\n }\n\n return this._transport.saveDocument();\n }\n\n getFieldObjects() {\n return this._transport.getFieldObjects();\n }\n\n hasJSActions() {\n return this._transport.hasJSActions();\n }\n\n getCalculationOrderIds() {\n return this._transport.getCalculationOrderIds();\n }\n\n}\n\nexports.PDFDocumentProxy = PDFDocumentProxy;\n\nclass PDFPageProxy {\n constructor(pageIndex, pageInfo, transport, ownerDocument, pdfBug = false) {\n this._pageIndex = pageIndex;\n this._pageInfo = pageInfo;\n this._ownerDocument = ownerDocument;\n this._transport = transport;\n this._stats = pdfBug ? new _display_utils.StatTimer() : null;\n this._pdfBug = pdfBug;\n this.commonObjs = transport.commonObjs;\n this.objs = new PDFObjects();\n this._bitmaps = new Set();\n this.cleanupAfterRender = false;\n this.pendingCleanup = false;\n this._intentStates = new Map();\n this._annotationPromises = new Map();\n this.destroyed = false;\n }\n\n get pageNumber() {\n return this._pageIndex + 1;\n }\n\n get rotate() {\n return this._pageInfo.rotate;\n }\n\n get ref() {\n return this._pageInfo.ref;\n }\n\n get userUnit() {\n return this._pageInfo.userUnit;\n }\n\n get view() {\n return this._pageInfo.view;\n }\n\n getViewport({\n scale,\n rotation = this.rotate,\n offsetX = 0,\n offsetY = 0,\n dontFlip = false\n } = {}) {\n return new _display_utils.PageViewport({\n viewBox: this.view,\n scale,\n rotation,\n offsetX,\n offsetY,\n dontFlip\n });\n }\n\n getAnnotations({\n intent = "display"\n } = {}) {\n const intentArgs = this._transport.getRenderingIntent(intent);\n\n let promise = this._annotationPromises.get(intentArgs.cacheKey);\n\n if (!promise) {\n promise = this._transport.getAnnotations(this._pageIndex, intentArgs.renderingIntent);\n\n this._annotationPromises.set(intentArgs.cacheKey, promise);\n\n promise = promise.then(annotations => {\n for (const annotation of annotations) {\n if (annotation.titleObj !== undefined) {\n Object.defineProperty(annotation, "title", {\n get() {\n (0, _display_utils.deprecated)("`title`-property on annotation, please use `titleObj` instead.");\n return annotation.titleObj.str;\n }\n\n });\n }\n\n if (annotation.contentsObj !== undefined) {\n Object.defineProperty(annotation, "contents", {\n get() {\n (0, _display_utils.deprecated)("`contents`-property on annotation, please use `contentsObj` instead.");\n return annotation.contentsObj.str;\n }\n\n });\n }\n }\n\n return annotations;\n });\n }\n\n return promise;\n }\n\n getJSActions() {\n return this._jsActionsPromise ||= this._transport.getPageJSActions(this._pageIndex);\n }\n\n async getXfa() {\n return this._transport._htmlForXfa?.children[this._pageIndex] || null;\n }\n\n render({\n canvasContext,\n viewport,\n intent = "display",\n annotationMode = _util.AnnotationMode.ENABLE,\n transform = null,\n imageLayer = null,\n canvasFactory = null,\n background = null,\n optionalContentConfigPromise = null,\n annotationCanvasMap = null,\n pageColors = null\n }) {\n if (arguments[0]?.renderInteractiveForms !== undefined) {\n (0, _display_utils.deprecated)("render no longer accepts the `renderInteractiveForms`-option, " + "please use the `annotationMode`-option instead.");\n\n if (arguments[0].renderInteractiveForms === true && annotationMode === _util.AnnotationMode.ENABLE) {\n annotationMode = _util.AnnotationMode.ENABLE_FORMS;\n }\n }\n\n if (arguments[0]?.includeAnnotationStorage !== undefined) {\n (0, _display_utils.deprecated)("render no longer accepts the `includeAnnotationStorage`-option, " + "please use the `annotationMode`-option instead.");\n\n if (arguments[0].includeAnnotationStorage === true && annotationMode === _util.AnnotationMode.ENABLE) {\n annotationMode = _util.AnnotationMode.ENABLE_STORAGE;\n }\n }\n\n if (this._stats) {\n this._stats.time("Overall");\n }\n\n const intentArgs = this._transport.getRenderingIntent(intent, annotationMode);\n\n this.pendingCleanup = false;\n\n if (!optionalContentConfigPromise) {\n optionalContentConfigPromise = this._transport.getOptionalContentConfig();\n }\n\n let intentState = this._intentStates.get(intentArgs.cacheKey);\n\n if (!intentState) {\n intentState = Object.create(null);\n\n this._intentStates.set(intentArgs.cacheKey, intentState);\n }\n\n if (intentState.streamReaderCancelTimeout) {\n clearTimeout(intentState.streamReaderCancelTimeout);\n intentState.streamReaderCancelTimeout = null;\n }\n\n const canvasFactoryInstance = canvasFactory || new DefaultCanvasFactory({\n ownerDocument: this._ownerDocument\n });\n const intentPrint = !!(intentArgs.renderingIntent & _util.RenderingIntentFlag.PRINT);\n\n if (!intentState.displayReadyCapability) {\n intentState.displayReadyCapability = (0, _util.createPromiseCapability)();\n intentState.operatorList = {\n fnArray: [],\n argsArray: [],\n lastChunk: false\n };\n\n if (this._stats) {\n this._stats.time("Page Request");\n }\n\n this._pumpOperatorList(intentArgs);\n }\n\n const complete = error => {\n intentState.renderTasks.delete(internalRenderTask);\n\n if (this.cleanupAfterRender || intentPrint) {\n this.pendingCleanup = true;\n }\n\n this._tryCleanup();\n\n if (error) {\n internalRenderTask.capability.reject(error);\n\n this._abortOperatorList({\n intentState,\n reason: error instanceof Error ? error : new Error(error)\n });\n } else {\n internalRenderTask.capability.resolve();\n }\n\n if (this._stats) {\n this._stats.timeEnd("Rendering");\n\n this._stats.timeEnd("Overall");\n }\n };\n\n const internalRenderTask = new InternalRenderTask({\n callback: complete,\n params: {\n canvasContext,\n viewport,\n transform,\n imageLayer,\n background\n },\n objs: this.objs,\n commonObjs: this.commonObjs,\n annotationCanvasMap,\n operatorList: intentState.operatorList,\n pageIndex: this._pageIndex,\n canvasFactory: canvasFactoryInstance,\n useRequestAnimationFrame: !intentPrint,\n pdfBug: this._pdfBug,\n pageColors\n });\n (intentState.renderTasks ||= new Set()).add(internalRenderTask);\n const renderTask = internalRenderTask.task;\n Promise.all([intentState.displayReadyCapability.promise, optionalContentConfigPromise]).then(([transparency, optionalContentConfig]) => {\n if (this.pendingCleanup) {\n complete();\n return;\n }\n\n if (this._stats) {\n this._stats.time("Rendering");\n }\n\n internalRenderTask.initializeGraphics({\n transparency,\n optionalContentConfig\n });\n internalRenderTask.operatorListChanged();\n }).catch(complete);\n return renderTask;\n }\n\n getOperatorList({\n intent = "display",\n annotationMode = _util.AnnotationMode.ENABLE\n } = {}) {\n function operatorListChanged() {\n if (intentState.operatorList.lastChunk) {\n intentState.opListReadCapability.resolve(intentState.operatorList);\n intentState.renderTasks.delete(opListTask);\n }\n }\n\n const intentArgs = this._transport.getRenderingIntent(intent, annotationMode, true);\n\n let intentState = this._intentStates.get(intentArgs.cacheKey);\n\n if (!intentState) {\n intentState = Object.create(null);\n\n this._intentStates.set(intentArgs.cacheKey, intentState);\n }\n\n let opListTask;\n\n if (!intentState.opListReadCapability) {\n opListTask = Object.create(null);\n opListTask.operatorListChanged = operatorListChanged;\n intentState.opListReadCapability = (0, _util.createPromiseCapability)();\n (intentState.renderTasks ||= new Set()).add(opListTask);\n intentState.operatorList = {\n fnArray: [],\n argsArray: [],\n lastChunk: false\n };\n\n if (this._stats) {\n this._stats.time("Page Request");\n }\n\n this._pumpOperatorList(intentArgs);\n }\n\n return intentState.opListReadCapability.promise;\n }\n\n streamTextContent({\n disableCombineTextItems = false,\n includeMarkedContent = false\n } = {}) {\n const TEXT_CONTENT_CHUNK_SIZE = 100;\n return this._transport.messageHandler.sendWithStream("GetTextContent", {\n pageIndex: this._pageIndex,\n combineTextItems: disableCombineTextItems !== true,\n includeMarkedContent: includeMarkedContent === true\n }, {\n highWaterMark: TEXT_CONTENT_CHUNK_SIZE,\n\n size(textContent) {\n return textContent.items.length;\n }\n\n });\n }\n\n getTextContent(params = {}) {\n if (this._transport._htmlForXfa) {\n return this.getXfa().then(xfa => {\n return _xfa_text.XfaText.textContent(xfa);\n });\n }\n\n const readableStream = this.streamTextContent(params);\n return new Promise(function (resolve, reject) {\n function pump() {\n reader.read().then(function ({\n value,\n done\n }) {\n if (done) {\n resolve(textContent);\n return;\n }\n\n Object.assign(textContent.styles, value.styles);\n textContent.items.push(...value.items);\n pump();\n }, reject);\n }\n\n const reader = readableStream.getReader();\n const textContent = {\n items: [],\n styles: Object.create(null)\n };\n pump();\n });\n }\n\n getStructTree() {\n return this._structTreePromise ||= this._transport.getStructTree(this._pageIndex);\n }\n\n _destroy() {\n this.destroyed = true;\n const waitOn = [];\n\n for (const intentState of this._intentStates.values()) {\n this._abortOperatorList({\n intentState,\n reason: new Error("Page was destroyed."),\n force: true\n });\n\n if (intentState.opListReadCapability) {\n continue;\n }\n\n for (const internalRenderTask of intentState.renderTasks) {\n waitOn.push(internalRenderTask.completed);\n internalRenderTask.cancel();\n }\n }\n\n this.objs.clear();\n\n for (const bitmap of this._bitmaps) {\n bitmap.close();\n }\n\n this._bitmaps.clear();\n\n this._annotationPromises.clear();\n\n this._jsActionsPromise = null;\n this._structTreePromise = null;\n this.pendingCleanup = false;\n return Promise.all(waitOn);\n }\n\n cleanup(resetStats = false) {\n this.pendingCleanup = true;\n return this._tryCleanup(resetStats);\n }\n\n _tryCleanup(resetStats = false) {\n if (!this.pendingCleanup) {\n return false;\n }\n\n for (const {\n renderTasks,\n operatorList\n } of this._intentStates.values()) {\n if (renderTasks.size > 0 || !operatorList.lastChunk) {\n return false;\n }\n }\n\n this._intentStates.clear();\n\n this.objs.clear();\n\n this._annotationPromises.clear();\n\n this._jsActionsPromise = null;\n this._structTreePromise = null;\n\n if (resetStats && this._stats) {\n this._stats = new _display_utils.StatTimer();\n }\n\n for (const bitmap of this._bitmaps) {\n bitmap.close();\n }\n\n this._bitmaps.clear();\n\n this.pendingCleanup = false;\n return true;\n }\n\n _startRenderPage(transparency, cacheKey) {\n const intentState = this._intentStates.get(cacheKey);\n\n if (!intentState) {\n return;\n }\n\n if (this._stats) {\n this._stats.timeEnd("Page Request");\n }\n\n if (intentState.displayReadyCapability) {\n intentState.displayReadyCapability.resolve(transparency);\n }\n }\n\n _renderPageChunk(operatorListChunk, intentState) {\n for (let i = 0, ii = operatorListChunk.length; i < ii; i++) {\n intentState.operatorList.fnArray.push(operatorListChunk.fnArray[i]);\n intentState.operatorList.argsArray.push(operatorListChunk.argsArray[i]);\n }\n\n intentState.operatorList.lastChunk = operatorListChunk.lastChunk;\n\n for (const internalRenderTask of intentState.renderTasks) {\n internalRenderTask.operatorListChanged();\n }\n\n if (operatorListChunk.lastChunk) {\n this._tryCleanup();\n }\n }\n\n _pumpOperatorList({\n renderingIntent,\n cacheKey\n }) {\n const readableStream = this._transport.messageHandler.sendWithStream("GetOperatorList", {\n pageIndex: this._pageIndex,\n intent: renderingIntent,\n cacheKey,\n annotationStorage: renderingIntent & _util.RenderingIntentFlag.ANNOTATIONS_STORAGE ? this._transport.annotationStorage.serializable : null\n });\n\n const reader = readableStream.getReader();\n\n const intentState = this._intentStates.get(cacheKey);\n\n intentState.streamReader = reader;\n\n const pump = () => {\n reader.read().then(({\n value,\n done\n }) => {\n if (done) {\n intentState.streamReader = null;\n return;\n }\n\n if (this._transport.destroyed) {\n return;\n }\n\n this._renderPageChunk(value, intentState);\n\n pump();\n }, reason => {\n intentState.streamReader = null;\n\n if (this._transport.destroyed) {\n return;\n }\n\n if (intentState.operatorList) {\n intentState.operatorList.lastChunk = true;\n\n for (const internalRenderTask of intentState.renderTasks) {\n internalRenderTask.operatorListChanged();\n }\n\n this._tryCleanup();\n }\n\n if (intentState.displayReadyCapability) {\n intentState.displayReadyCapability.reject(reason);\n } else if (intentState.opListReadCapability) {\n intentState.opListReadCapability.reject(reason);\n } else {\n throw reason;\n }\n });\n };\n\n pump();\n }\n\n _abortOperatorList({\n intentState,\n reason,\n force = false\n }) {\n if (!intentState.streamReader) {\n return;\n }\n\n if (!force) {\n if (intentState.renderTasks.size > 0) {\n return;\n }\n\n if (reason instanceof _display_utils.RenderingCancelledException) {\n intentState.streamReaderCancelTimeout = setTimeout(() => {\n this._abortOperatorList({\n intentState,\n reason,\n force: true\n });\n\n intentState.streamReaderCancelTimeout = null;\n }, RENDERING_CANCELLED_TIMEOUT);\n return;\n }\n }\n\n intentState.streamReader.cancel(new _util.AbortException(reason.message)).catch(() => {});\n intentState.streamReader = null;\n\n if (this._transport.destroyed) {\n return;\n }\n\n for (const [curCacheKey, curIntentState] of this._intentStates) {\n if (curIntentState === intentState) {\n this._intentStates.delete(curCacheKey);\n\n break;\n }\n }\n\n this.cleanup();\n }\n\n get stats() {\n return this._stats;\n }\n\n}\n\nexports.PDFPageProxy = PDFPageProxy;\n\nclass LoopbackPort {\n constructor() {\n this._listeners = [];\n this._deferred = Promise.resolve();\n }\n\n postMessage(obj, transfers) {\n const event = {\n data: structuredClone(obj, transfers)\n };\n\n this._deferred.then(() => {\n for (const listener of this._listeners) {\n listener.call(this, event);\n }\n });\n }\n\n addEventListener(name, listener) {\n this._listeners.push(listener);\n }\n\n removeEventListener(name, listener) {\n const i = this._listeners.indexOf(listener);\n\n this._listeners.splice(i, 1);\n }\n\n terminate() {\n this._listeners.length = 0;\n }\n\n}\n\nexports.LoopbackPort = LoopbackPort;\nconst PDFWorkerUtil = {\n isWorkerDisabled: false,\n fallbackWorkerSrc: null,\n fakeWorkerId: 0\n};\nexports.PDFWorkerUtil = PDFWorkerUtil;\n{\n if (_is_node.isNodeJS && "function" === "function") {\n PDFWorkerUtil.isWorkerDisabled = true;\n PDFWorkerUtil.fallbackWorkerSrc = "./pdf.worker.js";\n } else if (typeof document === "object") {\n const pdfjsFilePath = document?.currentScript?.src;\n\n if (pdfjsFilePath) {\n PDFWorkerUtil.fallbackWorkerSrc = pdfjsFilePath.replace(/(\\.(?:min\\.)?js)(\\?.*)?$/i, ".worker$1$2");\n }\n }\n\n PDFWorkerUtil.isSameOrigin = function (baseUrl, otherUrl) {\n let base;\n\n try {\n base = new URL(baseUrl);\n\n if (!base.origin || base.origin === "null") {\n return false;\n }\n } catch (e) {\n return false;\n }\n\n const other = new URL(otherUrl, base);\n return base.origin === other.origin;\n };\n\n PDFWorkerUtil.createCDNWrapper = function (url) {\n const wrapper = `importScripts("${url}");`;\n return URL.createObjectURL(new Blob([wrapper]));\n };\n}\n\nclass PDFWorker {\n static #workerPorts = new WeakMap();\n\n constructor({\n name = null,\n port = null,\n verbosity = (0, _util.getVerbosityLevel)()\n } = {}) {\n if (port && PDFWorker.#workerPorts.has(port)) {\n throw new Error("Cannot use more than one PDFWorker per port.");\n }\n\n this.name = name;\n this.destroyed = false;\n this.verbosity = verbosity;\n this._readyCapability = (0, _util.createPromiseCapability)();\n this._port = null;\n this._webWorker = null;\n this._messageHandler = null;\n\n if (port) {\n PDFWorker.#workerPorts.set(port, this);\n\n this._initializeFromPort(port);\n\n return;\n }\n\n this._initialize();\n }\n\n get promise() {\n return this._readyCapability.promise;\n }\n\n get port() {\n return this._port;\n }\n\n get messageHandler() {\n return this._messageHandler;\n }\n\n _initializeFromPort(port) {\n this._port = port;\n this._messageHandler = new _message_handler.MessageHandler("main", "worker", port);\n\n this._messageHandler.on("ready", function () {});\n\n this._readyCapability.resolve();\n }\n\n _initialize() {\n if (typeof Worker !== "undefined" && !PDFWorkerUtil.isWorkerDisabled && !PDFWorker._mainThreadWorkerMessageHandler) {\n let workerSrc = PDFWorker.workerSrc;\n\n try {\n if (!PDFWorkerUtil.isSameOrigin(window.location.href, workerSrc)) {\n workerSrc = PDFWorkerUtil.createCDNWrapper(new URL(workerSrc, window.location).href);\n }\n\n const worker = new Worker(workerSrc);\n const messageHandler = new _message_handler.MessageHandler("main", "worker", worker);\n\n const terminateEarly = () => {\n worker.removeEventListener("error", onWorkerError);\n messageHandler.destroy();\n worker.terminate();\n\n if (this.destroyed) {\n this._readyCapability.reject(new Error("Worker was destroyed"));\n } else {\n this._setupFakeWorker();\n }\n };\n\n const onWorkerError = () => {\n if (!this._webWorker) {\n terminateEarly();\n }\n };\n\n worker.addEventListener("error", onWorkerError);\n messageHandler.on("test", data => {\n worker.removeEventListener("error", onWorkerError);\n\n if (this.destroyed) {\n terminateEarly();\n return;\n }\n\n if (data) {\n this._messageHandler = messageHandler;\n this._port = worker;\n this._webWorker = worker;\n\n this._readyCapability.resolve();\n\n messageHandler.send("configure", {\n verbosity: this.verbosity\n });\n } else {\n this._setupFakeWorker();\n\n messageHandler.destroy();\n worker.terminate();\n }\n });\n messageHandler.on("ready", data => {\n worker.removeEventListener("error", onWorkerError);\n\n if (this.destroyed) {\n terminateEarly();\n return;\n }\n\n try {\n sendTest();\n } catch (e) {\n this._setupFakeWorker();\n }\n });\n\n const sendTest = () => {\n const testObj = new Uint8Array();\n messageHandler.send("test", testObj, [testObj.buffer]);\n };\n\n sendTest();\n return;\n } catch (e) {\n (0, _util.info)("The worker has been disabled.");\n }\n }\n\n this._setupFakeWorker();\n }\n\n _setupFakeWorker() {\n if (!PDFWorkerUtil.isWorkerDisabled) {\n (0, _util.warn)("Setting up fake worker.");\n PDFWorkerUtil.isWorkerDisabled = true;\n }\n\n PDFWorker._setupFakeWorkerGlobal.then(WorkerMessageHandler => {\n if (this.destroyed) {\n this._readyCapability.reject(new Error("Worker was destroyed"));\n\n return;\n }\n\n const port = new LoopbackPort();\n this._port = port;\n const id = `fake${PDFWorkerUtil.fakeWorkerId++}`;\n const workerHandler = new _message_handler.MessageHandler(id + "_worker", id, port);\n WorkerMessageHandler.setup(workerHandler, port);\n const messageHandler = new _message_handler.MessageHandler(id, id + "_worker", port);\n this._messageHandler = messageHandler;\n\n this._readyCapability.resolve();\n\n messageHandler.send("configure", {\n verbosity: this.verbosity\n });\n }).catch(reason => {\n this._readyCapability.reject(new Error(`Setting up fake worker failed: "${reason.message}".`));\n });\n }\n\n destroy() {\n this.destroyed = true;\n\n if (this._webWorker) {\n this._webWorker.terminate();\n\n this._webWorker = null;\n }\n\n PDFWorker.#workerPorts.delete(this._port);\n this._port = null;\n\n if (this._messageHandler) {\n this._messageHandler.destroy();\n\n this._messageHandler = null;\n }\n }\n\n static fromPort(params) {\n if (!params?.port) {\n throw new Error("PDFWorker.fromPort - invalid method signature.");\n }\n\n if (this.#workerPorts.has(params.port)) {\n return this.#workerPorts.get(params.port);\n }\n\n return new PDFWorker(params);\n }\n\n static get workerSrc() {\n if (_worker_options.GlobalWorkerOptions.workerSrc) {\n return _worker_options.GlobalWorkerOptions.workerSrc;\n }\n\n if (PDFWorkerUtil.fallbackWorkerSrc !== null) {\n if (!_is_node.isNodeJS) {\n (0, _display_utils.deprecated)(\'No "GlobalWorkerOptions.workerSrc" specified.\');\n }\n\n return PDFWorkerUtil.fallbackWorkerSrc;\n }\n\n throw new Error(\'No "GlobalWorkerOptions.workerSrc" specified.\');\n }\n\n static get _mainThreadWorkerMessageHandler() {\n try {\n return globalThis.pdfjsWorker?.WorkerMessageHandler || null;\n } catch (ex) {\n return null;\n }\n }\n\n static get _setupFakeWorkerGlobal() {\n const loader = async () => {\n const mainWorkerMessageHandler = this._mainThreadWorkerMessageHandler;\n\n if (mainWorkerMessageHandler) {\n return mainWorkerMessageHandler;\n }\n\n if (_is_node.isNodeJS && "function" === "function") {\n const worker = eval("require")(this.workerSrc);\n return worker.WorkerMessageHandler;\n }\n\n await (0, _display_utils.loadScript)(this.workerSrc);\n return window.pdfjsWorker.WorkerMessageHandler;\n };\n\n return (0, _util.shadow)(this, "_setupFakeWorkerGlobal", loader());\n }\n\n}\n\nexports.PDFWorker = PDFWorker;\n{\n PDFWorker.getWorkerSrc = function () {\n (0, _display_utils.deprecated)("`PDFWorker.getWorkerSrc()`, please use `PDFWorker.workerSrc` instead.");\n return this.workerSrc;\n };\n}\n\nclass WorkerTransport {\n #docStats = null;\n #pageCache = new Map();\n #pagePromises = new Map();\n #metadataPromise = null;\n\n constructor(messageHandler, loadingTask, networkStream, params) {\n this.messageHandler = messageHandler;\n this.loadingTask = loadingTask;\n this.commonObjs = new PDFObjects();\n this.fontLoader = new _font_loader.FontLoader({\n docId: loadingTask.docId,\n onUnsupportedFeature: this._onUnsupportedFeature.bind(this),\n ownerDocument: params.ownerDocument,\n styleElement: params.styleElement\n });\n this._params = params;\n\n if (!params.useWorkerFetch) {\n this.CMapReaderFactory = new params.CMapReaderFactory({\n baseUrl: params.cMapUrl,\n isCompressed: params.cMapPacked\n });\n this.StandardFontDataFactory = new params.StandardFontDataFactory({\n baseUrl: params.standardFontDataUrl\n });\n }\n\n this.destroyed = false;\n this.destroyCapability = null;\n this._passwordCapability = null;\n this._networkStream = networkStream;\n this._fullReader = null;\n this._lastProgress = null;\n this.downloadInfoCapability = (0, _util.createPromiseCapability)();\n this.setupMessageHandler();\n }\n\n get annotationStorage() {\n return (0, _util.shadow)(this, "annotationStorage", new _annotation_storage.AnnotationStorage());\n }\n\n get stats() {\n return this.#docStats;\n }\n\n getRenderingIntent(intent, annotationMode = _util.AnnotationMode.ENABLE, isOpList = false) {\n let renderingIntent = _util.RenderingIntentFlag.DISPLAY;\n let annotationHash = "";\n\n switch (intent) {\n case "any":\n renderingIntent = _util.RenderingIntentFlag.ANY;\n break;\n\n case "display":\n break;\n\n case "print":\n renderingIntent = _util.RenderingIntentFlag.PRINT;\n break;\n\n default:\n (0, _util.warn)(`getRenderingIntent - invalid intent: ${intent}`);\n }\n\n switch (annotationMode) {\n case _util.AnnotationMode.DISABLE:\n renderingIntent += _util.RenderingIntentFlag.ANNOTATIONS_DISABLE;\n break;\n\n case _util.AnnotationMode.ENABLE:\n break;\n\n case _util.AnnotationMode.ENABLE_FORMS:\n renderingIntent += _util.RenderingIntentFlag.ANNOTATIONS_FORMS;\n break;\n\n case _util.AnnotationMode.ENABLE_STORAGE:\n renderingIntent += _util.RenderingIntentFlag.ANNOTATIONS_STORAGE;\n annotationHash = this.annotationStorage.hash;\n break;\n\n default:\n (0, _util.warn)(`getRenderingIntent - invalid annotationMode: ${annotationMode}`);\n }\n\n if (isOpList) {\n renderingIntent += _util.RenderingIntentFlag.OPLIST;\n }\n\n return {\n renderingIntent,\n cacheKey: `${renderingIntent}_${annotationHash}`\n };\n }\n\n destroy() {\n if (this.destroyCapability) {\n return this.destroyCapability.promise;\n }\n\n this.destroyed = true;\n this.destroyCapability = (0, _util.createPromiseCapability)();\n\n if (this._passwordCapability) {\n this._passwordCapability.reject(new Error("Worker was destroyed during onPassword callback"));\n }\n\n const waitOn = [];\n\n for (const page of this.#pageCache.values()) {\n waitOn.push(page._destroy());\n }\n\n this.#pageCache.clear();\n this.#pagePromises.clear();\n\n if (this.hasOwnProperty("annotationStorage")) {\n this.annotationStorage.resetModified();\n }\n\n const terminated = this.messageHandler.sendWithPromise("Terminate", null);\n waitOn.push(terminated);\n Promise.all(waitOn).then(() => {\n this.commonObjs.clear();\n this.fontLoader.clear();\n this.#metadataPromise = null;\n this._getFieldObjectsPromise = null;\n this._hasJSActionsPromise = null;\n\n if (this._networkStream) {\n this._networkStream.cancelAllRequests(new _util.AbortException("Worker was terminated."));\n }\n\n if (this.messageHandler) {\n this.messageHandler.destroy();\n this.messageHandler = null;\n }\n\n this.destroyCapability.resolve();\n }, this.destroyCapability.reject);\n return this.destroyCapability.promise;\n }\n\n setupMessageHandler() {\n const {\n messageHandler,\n loadingTask\n } = this;\n messageHandler.on("GetReader", (data, sink) => {\n (0, _util.assert)(this._networkStream, "GetReader - no `IPDFStream` instance available.");\n this._fullReader = this._networkStream.getFullReader();\n\n this._fullReader.onProgress = evt => {\n this._lastProgress = {\n loaded: evt.loaded,\n total: evt.total\n };\n };\n\n sink.onPull = () => {\n this._fullReader.read().then(function ({\n value,\n done\n }) {\n if (done) {\n sink.close();\n return;\n }\n\n (0, _util.assert)((0, _util.isArrayBuffer)(value), "GetReader - expected an ArrayBuffer.");\n sink.enqueue(new Uint8Array(value), 1, [value]);\n }).catch(reason => {\n sink.error(reason);\n });\n };\n\n sink.onCancel = reason => {\n this._fullReader.cancel(reason);\n\n sink.ready.catch(readyReason => {\n if (this.destroyed) {\n return;\n }\n\n throw readyReason;\n });\n };\n });\n messageHandler.on("ReaderHeadersReady", data => {\n const headersCapability = (0, _util.createPromiseCapability)();\n const fullReader = this._fullReader;\n fullReader.headersReady.then(() => {\n if (!fullReader.isStreamingSupported || !fullReader.isRangeSupported) {\n if (this._lastProgress) {\n loadingTask.onProgress?.(this._lastProgress);\n }\n\n fullReader.onProgress = evt => {\n loadingTask.onProgress?.({\n loaded: evt.loaded,\n total: evt.total\n });\n };\n }\n\n headersCapability.resolve({\n isStreamingSupported: fullReader.isStreamingSupported,\n isRangeSupported: fullReader.isRangeSupported,\n contentLength: fullReader.contentLength\n });\n }, headersCapability.reject);\n return headersCapability.promise;\n });\n messageHandler.on("GetRangeReader", (data, sink) => {\n (0, _util.assert)(this._networkStream, "GetRangeReader - no `IPDFStream` instance available.");\n\n const rangeReader = this._networkStream.getRangeReader(data.begin, data.end);\n\n if (!rangeReader) {\n sink.close();\n return;\n }\n\n sink.onPull = () => {\n rangeReader.read().then(function ({\n value,\n done\n }) {\n if (done) {\n sink.close();\n return;\n }\n\n (0, _util.assert)((0, _util.isArrayBuffer)(value), "GetRangeReader - expected an ArrayBuffer.");\n sink.enqueue(new Uint8Array(value), 1, [value]);\n }).catch(reason => {\n sink.error(reason);\n });\n };\n\n sink.onCancel = reason => {\n rangeReader.cancel(reason);\n sink.ready.catch(readyReason => {\n if (this.destroyed) {\n return;\n }\n\n throw readyReason;\n });\n };\n });\n messageHandler.on("GetDoc", ({\n pdfInfo\n }) => {\n this._numPages = pdfInfo.numPages;\n this._htmlForXfa = pdfInfo.htmlForXfa;\n delete pdfInfo.htmlForXfa;\n\n loadingTask._capability.resolve(new PDFDocumentProxy(pdfInfo, this));\n });\n messageHandler.on("DocException", function (ex) {\n let reason;\n\n switch (ex.name) {\n case "PasswordException":\n reason = new _util.PasswordException(ex.message, ex.code);\n break;\n\n case "InvalidPDFException":\n reason = new _util.InvalidPDFException(ex.message);\n break;\n\n case "MissingPDFException":\n reason = new _util.MissingPDFException(ex.message);\n break;\n\n case "UnexpectedResponseException":\n reason = new _util.UnexpectedResponseException(ex.message, ex.status);\n break;\n\n case "UnknownErrorException":\n reason = new _util.UnknownErrorException(ex.message, ex.details);\n break;\n\n default:\n (0, _util.unreachable)("DocException - expected a valid Error.");\n }\n\n loadingTask._capability.reject(reason);\n });\n messageHandler.on("PasswordRequest", exception => {\n this._passwordCapability = (0, _util.createPromiseCapability)();\n\n if (loadingTask.onPassword) {\n const updatePassword = password => {\n if (password instanceof Error) {\n this._passwordCapability.reject(password);\n } else {\n this._passwordCapability.resolve({\n password\n });\n }\n };\n\n try {\n loadingTask.onPassword(updatePassword, exception.code);\n } catch (ex) {\n this._passwordCapability.reject(ex);\n }\n } else {\n this._passwordCapability.reject(new _util.PasswordException(exception.message, exception.code));\n }\n\n return this._passwordCapability.promise;\n });\n messageHandler.on("DataLoaded", data => {\n loadingTask.onProgress?.({\n loaded: data.length,\n total: data.length\n });\n this.downloadInfoCapability.resolve(data);\n });\n messageHandler.on("StartRenderPage", data => {\n if (this.destroyed) {\n return;\n }\n\n const page = this.#pageCache.get(data.pageIndex);\n\n page._startRenderPage(data.transparency, data.cacheKey);\n });\n messageHandler.on("commonobj", ([id, type, exportedData]) => {\n if (this.destroyed) {\n return;\n }\n\n if (this.commonObjs.has(id)) {\n return;\n }\n\n switch (type) {\n case "Font":\n const params = this._params;\n\n if ("error" in exportedData) {\n const exportedError = exportedData.error;\n (0, _util.warn)(`Error during font loading: ${exportedError}`);\n this.commonObjs.resolve(id, exportedError);\n break;\n }\n\n let fontRegistry = null;\n\n if (params.pdfBug && globalThis.FontInspector?.enabled) {\n fontRegistry = {\n registerFont(font, url) {\n globalThis.FontInspector.fontAdded(font, url);\n }\n\n };\n }\n\n const font = new _font_loader.FontFaceObject(exportedData, {\n isEvalSupported: params.isEvalSupported,\n disableFontFace: params.disableFontFace,\n ignoreErrors: params.ignoreErrors,\n onUnsupportedFeature: this._onUnsupportedFeature.bind(this),\n fontRegistry\n });\n this.fontLoader.bind(font).catch(reason => {\n return messageHandler.sendWithPromise("FontFallback", {\n id\n });\n }).finally(() => {\n if (!params.fontExtraProperties && font.data) {\n font.data = null;\n }\n\n this.commonObjs.resolve(id, font);\n });\n break;\n\n case "FontPath":\n case "Image":\n this.commonObjs.resolve(id, exportedData);\n break;\n\n default:\n throw new Error(`Got unknown common object type ${type}`);\n }\n });\n messageHandler.on("obj", ([id, pageIndex, type, imageData]) => {\n if (this.destroyed) {\n return;\n }\n\n const pageProxy = this.#pageCache.get(pageIndex);\n\n if (pageProxy.objs.has(id)) {\n return;\n }\n\n switch (type) {\n case "Image":\n pageProxy.objs.resolve(id, imageData);\n const MAX_IMAGE_SIZE_TO_STORE = 8000000;\n\n if (imageData) {\n let length;\n\n if (imageData.bitmap) {\n const {\n bitmap,\n width,\n height\n } = imageData;\n length = width * height * 4;\n\n pageProxy._bitmaps.add(bitmap);\n } else {\n length = imageData.data?.length || 0;\n }\n\n if (length > MAX_IMAGE_SIZE_TO_STORE) {\n pageProxy.cleanupAfterRender = true;\n }\n }\n\n break;\n\n case "Pattern":\n pageProxy.objs.resolve(id, imageData);\n break;\n\n default:\n throw new Error(`Got unknown object type ${type}`);\n }\n });\n messageHandler.on("DocProgress", data => {\n if (this.destroyed) {\n return;\n }\n\n loadingTask.onProgress?.({\n loaded: data.loaded,\n total: data.total\n });\n });\n messageHandler.on("DocStats", data => {\n if (this.destroyed) {\n return;\n }\n\n this.#docStats = Object.freeze({\n streamTypes: Object.freeze(data.streamTypes),\n fontTypes: Object.freeze(data.fontTypes)\n });\n });\n messageHandler.on("UnsupportedFeature", this._onUnsupportedFeature.bind(this));\n messageHandler.on("FetchBuiltInCMap", data => {\n if (this.destroyed) {\n return Promise.reject(new Error("Worker was destroyed."));\n }\n\n if (!this.CMapReaderFactory) {\n return Promise.reject(new Error("CMapReaderFactory not initialized, see the `useWorkerFetch` parameter."));\n }\n\n return this.CMapReaderFactory.fetch(data);\n });\n messageHandler.on("FetchStandardFontData", data => {\n if (this.destroyed) {\n return Promise.reject(new Error("Worker was destroyed."));\n }\n\n if (!this.StandardFontDataFactory) {\n return Promise.reject(new Error("StandardFontDataFactory not initialized, see the `useWorkerFetch` parameter."));\n }\n\n return this.StandardFontDataFactory.fetch(data);\n });\n }\n\n _onUnsupportedFeature({\n featureId\n }) {\n if (this.destroyed) {\n return;\n }\n\n this.loadingTask.onUnsupportedFeature?.(featureId);\n }\n\n getData() {\n return this.messageHandler.sendWithPromise("GetData", null);\n }\n\n getPage(pageNumber) {\n if (!Number.isInteger(pageNumber) || pageNumber <= 0 || pageNumber > this._numPages) {\n return Promise.reject(new Error("Invalid page request."));\n }\n\n const pageIndex = pageNumber - 1,\n cachedPromise = this.#pagePromises.get(pageIndex);\n\n if (cachedPromise) {\n return cachedPromise;\n }\n\n const promise = this.messageHandler.sendWithPromise("GetPage", {\n pageIndex\n }).then(pageInfo => {\n if (this.destroyed) {\n throw new Error("Transport destroyed");\n }\n\n const page = new PDFPageProxy(pageIndex, pageInfo, this, this._params.ownerDocument, this._params.pdfBug);\n this.#pageCache.set(pageIndex, page);\n return page;\n });\n this.#pagePromises.set(pageIndex, promise);\n return promise;\n }\n\n getPageIndex(ref) {\n if (typeof ref !== "object" || ref === null || !Number.isInteger(ref.num) || ref.num < 0 || !Number.isInteger(ref.gen) || ref.gen < 0) {\n return Promise.reject(new Error("Invalid pageIndex request."));\n }\n\n return this.messageHandler.sendWithPromise("GetPageIndex", {\n num: ref.num,\n gen: ref.gen\n });\n }\n\n getAnnotations(pageIndex, intent) {\n return this.messageHandler.sendWithPromise("GetAnnotations", {\n pageIndex,\n intent\n });\n }\n\n saveDocument() {\n return this.messageHandler.sendWithPromise("SaveDocument", {\n isPureXfa: !!this._htmlForXfa,\n numPages: this._numPages,\n annotationStorage: this.annotationStorage.serializable,\n filename: this._fullReader?.filename ?? null\n }).finally(() => {\n this.annotationStorage.resetModified();\n });\n }\n\n getFieldObjects() {\n return this._getFieldObjectsPromise ||= this.messageHandler.sendWithPromise("GetFieldObjects", null);\n }\n\n hasJSActions() {\n return this._hasJSActionsPromise ||= this.messageHandler.sendWithPromise("HasJSActions", null);\n }\n\n getCalculationOrderIds() {\n return this.messageHandler.sendWithPromise("GetCalculationOrderIds", null);\n }\n\n getDestinations() {\n return this.messageHandler.sendWithPromise("GetDestinations", null);\n }\n\n getDestination(id) {\n if (typeof id !== "string") {\n return Promise.reject(new Error("Invalid destination request."));\n }\n\n return this.messageHandler.sendWithPromise("GetDestination", {\n id\n });\n }\n\n getPageLabels() {\n return this.messageHandler.sendWithPromise("GetPageLabels", null);\n }\n\n getPageLayout() {\n return this.messageHandler.sendWithPromise("GetPageLayout", null);\n }\n\n getPageMode() {\n return this.messageHandler.sendWithPromise("GetPageMode", null);\n }\n\n getViewerPreferences() {\n return this.messageHandler.sendWithPromise("GetViewerPreferences", null);\n }\n\n getOpenAction() {\n return this.messageHandler.sendWithPromise("GetOpenAction", null);\n }\n\n getAttachments() {\n return this.messageHandler.sendWithPromise("GetAttachments", null);\n }\n\n getJavaScript() {\n return this.messageHandler.sendWithPromise("GetJavaScript", null);\n }\n\n getDocJSActions() {\n return this.messageHandler.sendWithPromise("GetDocJSActions", null);\n }\n\n getPageJSActions(pageIndex) {\n return this.messageHandler.sendWithPromise("GetPageJSActions", {\n pageIndex\n });\n }\n\n getStructTree(pageIndex) {\n return this.messageHandler.sendWithPromise("GetStructTree", {\n pageIndex\n });\n }\n\n getOutline() {\n return this.messageHandler.sendWithPromise("GetOutline", null);\n }\n\n getOptionalContentConfig() {\n return this.messageHandler.sendWithPromise("GetOptionalContentConfig", null).then(results => {\n return new _optional_content_config.OptionalContentConfig(results);\n });\n }\n\n getPermissions() {\n return this.messageHandler.sendWithPromise("GetPermissions", null);\n }\n\n getMetadata() {\n return this.#metadataPromise ||= this.messageHandler.sendWithPromise("GetMetadata", null).then(results => {\n return {\n info: results[0],\n metadata: results[1] ? new _metadata.Metadata(results[1]) : null,\n contentDispositionFilename: this._fullReader?.filename ?? null,\n contentLength: this._fullReader?.contentLength ?? null\n };\n });\n }\n\n getMarkInfo() {\n return this.messageHandler.sendWithPromise("GetMarkInfo", null);\n }\n\n async startCleanup(keepLoadedFonts = false) {\n await this.messageHandler.sendWithPromise("Cleanup", null);\n\n if (this.destroyed) {\n return;\n }\n\n for (const page of this.#pageCache.values()) {\n const cleanupSuccessful = page.cleanup();\n\n if (!cleanupSuccessful) {\n throw new Error(`startCleanup: Page ${page.pageNumber} is currently rendering.`);\n }\n }\n\n this.commonObjs.clear();\n\n if (!keepLoadedFonts) {\n this.fontLoader.clear();\n }\n\n this.#metadataPromise = null;\n this._getFieldObjectsPromise = null;\n this._hasJSActionsPromise = null;\n }\n\n get loadingParams() {\n const params = this._params;\n return (0, _util.shadow)(this, "loadingParams", {\n disableAutoFetch: params.disableAutoFetch,\n enableXfa: params.enableXfa\n });\n }\n\n}\n\nclass PDFObjects {\n #objs = Object.create(null);\n\n #ensureObj(objId) {\n const obj = this.#objs[objId];\n\n if (obj) {\n return obj;\n }\n\n return this.#objs[objId] = {\n capability: (0, _util.createPromiseCapability)(),\n data: null\n };\n }\n\n get(objId, callback = null) {\n if (callback) {\n const obj = this.#ensureObj(objId);\n obj.capability.promise.then(() => callback(obj.data));\n return null;\n }\n\n const obj = this.#objs[objId];\n\n if (!obj?.capability.settled) {\n throw new Error(`Requesting object that isn\'t resolved yet ${objId}.`);\n }\n\n return obj.data;\n }\n\n has(objId) {\n const obj = this.#objs[objId];\n return obj?.capability.settled || false;\n }\n\n resolve(objId, data = null) {\n const obj = this.#ensureObj(objId);\n obj.data = data;\n obj.capability.resolve();\n }\n\n clear() {\n this.#objs = Object.create(null);\n }\n\n}\n\nclass RenderTask {\n constructor(internalRenderTask) {\n this._internalRenderTask = internalRenderTask;\n this.onContinue = null;\n }\n\n get promise() {\n return this._internalRenderTask.capability.promise;\n }\n\n cancel() {\n this._internalRenderTask.cancel();\n }\n\n}\n\nexports.RenderTask = RenderTask;\n\nclass InternalRenderTask {\n static #canvasInUse = new WeakSet();\n\n constructor({\n callback,\n params,\n objs,\n commonObjs,\n annotationCanvasMap,\n operatorList,\n pageIndex,\n canvasFactory,\n useRequestAnimationFrame = false,\n pdfBug = false,\n pageColors = null\n }) {\n this.callback = callback;\n this.params = params;\n this.objs = objs;\n this.commonObjs = commonObjs;\n this.annotationCanvasMap = annotationCanvasMap;\n this.operatorListIdx = null;\n this.operatorList = operatorList;\n this._pageIndex = pageIndex;\n this.canvasFactory = canvasFactory;\n this._pdfBug = pdfBug;\n this.pageColors = pageColors;\n this.running = false;\n this.graphicsReadyCallback = null;\n this.graphicsReady = false;\n this._useRequestAnimationFrame = useRequestAnimationFrame === true && typeof window !== "undefined";\n this.cancelled = false;\n this.capability = (0, _util.createPromiseCapability)();\n this.task = new RenderTask(this);\n this._cancelBound = this.cancel.bind(this);\n this._continueBound = this._continue.bind(this);\n this._scheduleNextBound = this._scheduleNext.bind(this);\n this._nextBound = this._next.bind(this);\n this._canvas = params.canvasContext.canvas;\n }\n\n get completed() {\n return this.capability.promise.catch(function () {});\n }\n\n initializeGraphics({\n transparency = false,\n optionalContentConfig\n }) {\n if (this.cancelled) {\n return;\n }\n\n if (this._canvas) {\n if (InternalRenderTask.#canvasInUse.has(this._canvas)) {\n throw new Error("Cannot use the same canvas during multiple render() operations. " + "Use different canvas or ensure previous operations were " + "cancelled or completed.");\n }\n\n InternalRenderTask.#canvasInUse.add(this._canvas);\n }\n\n if (this._pdfBug && globalThis.StepperManager?.enabled) {\n this.stepper = globalThis.StepperManager.create(this._pageIndex);\n this.stepper.init(this.operatorList);\n this.stepper.nextBreakPoint = this.stepper.getNextBreakPoint();\n }\n\n const {\n canvasContext,\n viewport,\n transform,\n imageLayer,\n background\n } = this.params;\n this.gfx = new _canvas.CanvasGraphics(canvasContext, this.commonObjs, this.objs, this.canvasFactory, imageLayer, optionalContentConfig, this.annotationCanvasMap, this.pageColors);\n this.gfx.beginDrawing({\n transform,\n viewport,\n transparency,\n background\n });\n this.operatorListIdx = 0;\n this.graphicsReady = true;\n\n if (this.graphicsReadyCallback) {\n this.graphicsReadyCallback();\n }\n }\n\n cancel(error = null) {\n this.running = false;\n this.cancelled = true;\n\n if (this.gfx) {\n this.gfx.endDrawing();\n }\n\n if (this._canvas) {\n InternalRenderTask.#canvasInUse.delete(this._canvas);\n }\n\n this.callback(error || new _display_utils.RenderingCancelledException(`Rendering cancelled, page ${this._pageIndex + 1}`, "canvas"));\n }\n\n operatorListChanged() {\n if (!this.graphicsReady) {\n if (!this.graphicsReadyCallback) {\n this.graphicsReadyCallback = this._continueBound;\n }\n\n return;\n }\n\n if (this.stepper) {\n this.stepper.updateOperatorList(this.operatorList);\n }\n\n if (this.running) {\n return;\n }\n\n this._continue();\n }\n\n _continue() {\n this.running = true;\n\n if (this.cancelled) {\n return;\n }\n\n if (this.task.onContinue) {\n this.task.onContinue(this._scheduleNextBound);\n } else {\n this._scheduleNext();\n }\n }\n\n _scheduleNext() {\n if (this._useRequestAnimationFrame) {\n window.requestAnimationFrame(() => {\n this._nextBound().catch(this._cancelBound);\n });\n } else {\n Promise.resolve().then(this._nextBound).catch(this._cancelBound);\n }\n }\n\n async _next() {\n if (this.cancelled) {\n return;\n }\n\n this.operatorListIdx = this.gfx.executeOperatorList(this.operatorList, this.operatorListIdx, this._continueBound, this.stepper);\n\n if (this.operatorListIdx === this.operatorList.argsArray.length) {\n this.running = false;\n\n if (this.operatorList.lastChunk) {\n this.gfx.endDrawing();\n\n if (this._canvas) {\n InternalRenderTask.#canvasInUse.delete(this._canvas);\n }\n\n this.callback();\n }\n }\n }\n\n}\n\nconst version = \'2.14.305\';\nexports.version = version;\nconst build = \'eaaa8b4ad\';\nexports.build = build;\n\n/***/ }),\n/* 5 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.StatTimer = exports.RenderingCancelledException = exports.PixelsPerInch = exports.PageViewport = exports.PDFDateString = exports.DOMStandardFontDataFactory = exports.DOMSVGFactory = exports.DOMCanvasFactory = exports.DOMCMapReaderFactory = void 0;\nexports.deprecated = deprecated;\nexports.getFilenameFromUrl = getFilenameFromUrl;\nexports.getPdfFilenameFromUrl = getPdfFilenameFromUrl;\nexports.getXfaPageViewport = getXfaPageViewport;\nexports.isDataScheme = isDataScheme;\nexports.isPdfFile = isPdfFile;\nexports.isValidFetchUrl = isValidFetchUrl;\nexports.loadScript = loadScript;\n\nvar _base_factory = __w_pdfjs_require__(6);\n\nvar _util = __w_pdfjs_require__(1);\n\nconst SVG_NS = "http://www.w3.org/2000/svg";\n\nclass PixelsPerInch {\n static CSS = 96.0;\n static PDF = 72.0;\n static PDF_TO_CSS_UNITS = this.CSS / this.PDF;\n}\n\nexports.PixelsPerInch = PixelsPerInch;\n\nclass DOMCanvasFactory extends _base_factory.BaseCanvasFactory {\n constructor({\n ownerDocument = globalThis.document\n } = {}) {\n super();\n this._document = ownerDocument;\n }\n\n _createCanvas(width, height) {\n const canvas = this._document.createElement("canvas");\n\n canvas.width = width;\n canvas.height = height;\n return canvas;\n }\n\n}\n\nexports.DOMCanvasFactory = DOMCanvasFactory;\n\nasync function fetchData(url, asTypedArray = false) {\n if (isValidFetchUrl(url, document.baseURI)) {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(response.statusText);\n }\n\n return asTypedArray ? new Uint8Array(await response.arrayBuffer()) : (0, _util.stringToBytes)(await response.text());\n }\n\n return new Promise((resolve, reject) => {\n const request = new XMLHttpRequest();\n request.open("GET", url, true);\n\n if (asTypedArray) {\n request.responseType = "arraybuffer";\n }\n\n request.onreadystatechange = () => {\n if (request.readyState !== XMLHttpRequest.DONE) {\n return;\n }\n\n if (request.status === 200 || request.status === 0) {\n let data;\n\n if (asTypedArray && request.response) {\n data = new Uint8Array(request.response);\n } else if (!asTypedArray && request.responseText) {\n data = (0, _util.stringToBytes)(request.responseText);\n }\n\n if (data) {\n resolve(data);\n return;\n }\n }\n\n reject(new Error(request.statusText));\n };\n\n request.send(null);\n });\n}\n\nclass DOMCMapReaderFactory extends _base_factory.BaseCMapReaderFactory {\n _fetchData(url, compressionType) {\n return fetchData(url, this.isCompressed).then(data => {\n return {\n cMapData: data,\n compressionType\n };\n });\n }\n\n}\n\nexports.DOMCMapReaderFactory = DOMCMapReaderFactory;\n\nclass DOMStandardFontDataFactory extends _base_factory.BaseStandardFontDataFactory {\n _fetchData(url) {\n return fetchData(url, true);\n }\n\n}\n\nexports.DOMStandardFontDataFactory = DOMStandardFontDataFactory;\n\nclass DOMSVGFactory extends _base_factory.BaseSVGFactory {\n _createSVG(type) {\n return document.createElementNS(SVG_NS, type);\n }\n\n}\n\nexports.DOMSVGFactory = DOMSVGFactory;\n\nclass PageViewport {\n constructor({\n viewBox,\n scale,\n rotation,\n offsetX = 0,\n offsetY = 0,\n dontFlip = false\n }) {\n this.viewBox = viewBox;\n this.scale = scale;\n this.rotation = rotation;\n this.offsetX = offsetX;\n this.offsetY = offsetY;\n const centerX = (viewBox[2] + viewBox[0]) / 2;\n const centerY = (viewBox[3] + viewBox[1]) / 2;\n let rotateA, rotateB, rotateC, rotateD;\n rotation %= 360;\n\n if (rotation < 0) {\n rotation += 360;\n }\n\n switch (rotation) {\n case 180:\n rotateA = -1;\n rotateB = 0;\n rotateC = 0;\n rotateD = 1;\n break;\n\n case 90:\n rotateA = 0;\n rotateB = 1;\n rotateC = 1;\n rotateD = 0;\n break;\n\n case 270:\n rotateA = 0;\n rotateB = -1;\n rotateC = -1;\n rotateD = 0;\n break;\n\n case 0:\n rotateA = 1;\n rotateB = 0;\n rotateC = 0;\n rotateD = -1;\n break;\n\n default:\n throw new Error("PageViewport: Invalid rotation, must be a multiple of 90 degrees.");\n }\n\n if (dontFlip) {\n rotateC = -rotateC;\n rotateD = -rotateD;\n }\n\n let offsetCanvasX, offsetCanvasY;\n let width, height;\n\n if (rotateA === 0) {\n offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX;\n offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY;\n width = Math.abs(viewBox[3] - viewBox[1]) * scale;\n height = Math.abs(viewBox[2] - viewBox[0]) * scale;\n } else {\n offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX;\n offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY;\n width = Math.abs(viewBox[2] - viewBox[0]) * scale;\n height = Math.abs(viewBox[3] - viewBox[1]) * scale;\n }\n\n this.transform = [rotateA * scale, rotateB * scale, rotateC * scale, rotateD * scale, offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY, offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY];\n this.width = width;\n this.height = height;\n }\n\n clone({\n scale = this.scale,\n rotation = this.rotation,\n offsetX = this.offsetX,\n offsetY = this.offsetY,\n dontFlip = false\n } = {}) {\n return new PageViewport({\n viewBox: this.viewBox.slice(),\n scale,\n rotation,\n offsetX,\n offsetY,\n dontFlip\n });\n }\n\n convertToViewportPoint(x, y) {\n return _util.Util.applyTransform([x, y], this.transform);\n }\n\n convertToViewportRectangle(rect) {\n const topLeft = _util.Util.applyTransform([rect[0], rect[1]], this.transform);\n\n const bottomRight = _util.Util.applyTransform([rect[2], rect[3]], this.transform);\n\n return [topLeft[0], topLeft[1], bottomRight[0], bottomRight[1]];\n }\n\n convertToPdfPoint(x, y) {\n return _util.Util.applyInverseTransform([x, y], this.transform);\n }\n\n}\n\nexports.PageViewport = PageViewport;\n\nclass RenderingCancelledException extends _util.BaseException {\n constructor(msg, type) {\n super(msg, "RenderingCancelledException");\n this.type = type;\n }\n\n}\n\nexports.RenderingCancelledException = RenderingCancelledException;\n\nfunction isDataScheme(url) {\n const ii = url.length;\n let i = 0;\n\n while (i < ii && url[i].trim() === "") {\n i++;\n }\n\n return url.substring(i, i + 5).toLowerCase() === "data:";\n}\n\nfunction isPdfFile(filename) {\n return typeof filename === "string" && /\\.pdf$/i.test(filename);\n}\n\nfunction getFilenameFromUrl(url) {\n const anchor = url.indexOf("#");\n const query = url.indexOf("?");\n const end = Math.min(anchor > 0 ? anchor : url.length, query > 0 ? query : url.length);\n return url.substring(url.lastIndexOf("/", end) + 1, end);\n}\n\nfunction getPdfFilenameFromUrl(url, defaultFilename = "document.pdf") {\n if (typeof url !== "string") {\n return defaultFilename;\n }\n\n if (isDataScheme(url)) {\n (0, _util.warn)(\'getPdfFilenameFromUrl: ignore "data:"-URL for performance reasons.\');\n return defaultFilename;\n }\n\n const reURI = /^(?:(?:[^:]+:)?\\/\\/[^/]+)?([^?#]*)(\\?[^#]*)?(#.*)?$/;\n const reFilename = /[^/?#=]+\\.pdf\\b(?!.*\\.pdf\\b)/i;\n const splitURI = reURI.exec(url);\n let suggestedFilename = reFilename.exec(splitURI[1]) || reFilename.exec(splitURI[2]) || reFilename.exec(splitURI[3]);\n\n if (suggestedFilename) {\n suggestedFilename = suggestedFilename[0];\n\n if (suggestedFilename.includes("%")) {\n try {\n suggestedFilename = reFilename.exec(decodeURIComponent(suggestedFilename))[0];\n } catch (ex) {}\n }\n }\n\n return suggestedFilename || defaultFilename;\n}\n\nclass StatTimer {\n constructor() {\n this.started = Object.create(null);\n this.times = [];\n }\n\n time(name) {\n if (name in this.started) {\n (0, _util.warn)(`Timer is already running for ${name}`);\n }\n\n this.started[name] = Date.now();\n }\n\n timeEnd(name) {\n if (!(name in this.started)) {\n (0, _util.warn)(`Timer has not been started for ${name}`);\n }\n\n this.times.push({\n name,\n start: this.started[name],\n end: Date.now()\n });\n delete this.started[name];\n }\n\n toString() {\n const outBuf = [];\n let longest = 0;\n\n for (const time of this.times) {\n const name = time.name;\n\n if (name.length > longest) {\n longest = name.length;\n }\n }\n\n for (const time of this.times) {\n const duration = time.end - time.start;\n outBuf.push(`${time.name.padEnd(longest)} ${duration}ms\\n`);\n }\n\n return outBuf.join("");\n }\n\n}\n\nexports.StatTimer = StatTimer;\n\nfunction isValidFetchUrl(url, baseUrl) {\n try {\n const {\n protocol\n } = baseUrl ? new URL(url, baseUrl) : new URL(url);\n return protocol === "http:" || protocol === "https:";\n } catch (ex) {\n return false;\n }\n}\n\nfunction loadScript(src, removeScriptElement = false) {\n return new Promise((resolve, reject) => {\n const script = document.createElement("script");\n script.src = src;\n\n script.onload = function (evt) {\n if (removeScriptElement) {\n script.remove();\n }\n\n resolve(evt);\n };\n\n script.onerror = function () {\n reject(new Error(`Cannot load script at: ${script.src}`));\n };\n\n (document.head || document.documentElement).appendChild(script);\n });\n}\n\nfunction deprecated(details) {\n console.log("Deprecated API usage: " + details);\n}\n\nlet pdfDateStringRegex;\n\nclass PDFDateString {\n static toDateObject(input) {\n if (!input || typeof input !== "string") {\n return null;\n }\n\n if (!pdfDateStringRegex) {\n pdfDateStringRegex = new RegExp("^D:" + "(\\\\d{4})" + "(\\\\d{2})?" + "(\\\\d{2})?" + "(\\\\d{2})?" + "(\\\\d{2})?" + "(\\\\d{2})?" + "([Z|+|-])?" + "(\\\\d{2})?" + "\'?" + "(\\\\d{2})?" + "\'?");\n }\n\n const matches = pdfDateStringRegex.exec(input);\n\n if (!matches) {\n return null;\n }\n\n const year = parseInt(matches[1], 10);\n let month = parseInt(matches[2], 10);\n month = month >= 1 && month <= 12 ? month - 1 : 0;\n let day = parseInt(matches[3], 10);\n day = day >= 1 && day <= 31 ? day : 1;\n let hour = parseInt(matches[4], 10);\n hour = hour >= 0 && hour <= 23 ? hour : 0;\n let minute = parseInt(matches[5], 10);\n minute = minute >= 0 && minute <= 59 ? minute : 0;\n let second = parseInt(matches[6], 10);\n second = second >= 0 && second <= 59 ? second : 0;\n const universalTimeRelation = matches[7] || "Z";\n let offsetHour = parseInt(matches[8], 10);\n offsetHour = offsetHour >= 0 && offsetHour <= 23 ? offsetHour : 0;\n let offsetMinute = parseInt(matches[9], 10) || 0;\n offsetMinute = offsetMinute >= 0 && offsetMinute <= 59 ? offsetMinute : 0;\n\n if (universalTimeRelation === "-") {\n hour += offsetHour;\n minute += offsetMinute;\n } else if (universalTimeRelation === "+") {\n hour -= offsetHour;\n minute -= offsetMinute;\n }\n\n return new Date(Date.UTC(year, month, day, hour, minute, second));\n }\n\n}\n\nexports.PDFDateString = PDFDateString;\n\nfunction getXfaPageViewport(xfaPage, {\n scale = 1,\n rotation = 0\n}) {\n const {\n width,\n height\n } = xfaPage.attributes.style;\n const viewBox = [0, 0, parseInt(width), parseInt(height)];\n return new PageViewport({\n viewBox,\n scale,\n rotation\n });\n}\n\n/***/ }),\n/* 6 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.BaseStandardFontDataFactory = exports.BaseSVGFactory = exports.BaseCanvasFactory = exports.BaseCMapReaderFactory = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nclass BaseCanvasFactory {\n constructor() {\n if (this.constructor === BaseCanvasFactory) {\n (0, _util.unreachable)("Cannot initialize BaseCanvasFactory.");\n }\n }\n\n create(width, height) {\n if (width <= 0 || height <= 0) {\n throw new Error("Invalid canvas size");\n }\n\n const canvas = this._createCanvas(width, height);\n\n return {\n canvas,\n context: canvas.getContext("2d")\n };\n }\n\n reset(canvasAndContext, width, height) {\n if (!canvasAndContext.canvas) {\n throw new Error("Canvas is not specified");\n }\n\n if (width <= 0 || height <= 0) {\n throw new Error("Invalid canvas size");\n }\n\n canvasAndContext.canvas.width = width;\n canvasAndContext.canvas.height = height;\n }\n\n destroy(canvasAndContext) {\n if (!canvasAndContext.canvas) {\n throw new Error("Canvas is not specified");\n }\n\n canvasAndContext.canvas.width = 0;\n canvasAndContext.canvas.height = 0;\n canvasAndContext.canvas = null;\n canvasAndContext.context = null;\n }\n\n _createCanvas(width, height) {\n (0, _util.unreachable)("Abstract method `_createCanvas` called.");\n }\n\n}\n\nexports.BaseCanvasFactory = BaseCanvasFactory;\n\nclass BaseCMapReaderFactory {\n constructor({\n baseUrl = null,\n isCompressed = false\n }) {\n if (this.constructor === BaseCMapReaderFactory) {\n (0, _util.unreachable)("Cannot initialize BaseCMapReaderFactory.");\n }\n\n this.baseUrl = baseUrl;\n this.isCompressed = isCompressed;\n }\n\n async fetch({\n name\n }) {\n if (!this.baseUrl) {\n throw new Error(\'The CMap "baseUrl" parameter must be specified, ensure that \' + \'the "cMapUrl" and "cMapPacked" API parameters are provided.\');\n }\n\n if (!name) {\n throw new Error("CMap name must be specified.");\n }\n\n const url = this.baseUrl + name + (this.isCompressed ? ".bcmap" : "");\n const compressionType = this.isCompressed ? _util.CMapCompressionType.BINARY : _util.CMapCompressionType.NONE;\n return this._fetchData(url, compressionType).catch(reason => {\n throw new Error(`Unable to load ${this.isCompressed ? "binary " : ""}CMap at: ${url}`);\n });\n }\n\n _fetchData(url, compressionType) {\n (0, _util.unreachable)("Abstract method `_fetchData` called.");\n }\n\n}\n\nexports.BaseCMapReaderFactory = BaseCMapReaderFactory;\n\nclass BaseStandardFontDataFactory {\n constructor({\n baseUrl = null\n }) {\n if (this.constructor === BaseStandardFontDataFactory) {\n (0, _util.unreachable)("Cannot initialize BaseStandardFontDataFactory.");\n }\n\n this.baseUrl = baseUrl;\n }\n\n async fetch({\n filename\n }) {\n if (!this.baseUrl) {\n throw new Error(\'The standard font "baseUrl" parameter must be specified, ensure that \' + \'the "standardFontDataUrl" API parameter is provided.\');\n }\n\n if (!filename) {\n throw new Error("Font filename must be specified.");\n }\n\n const url = `${this.baseUrl}${filename}`;\n return this._fetchData(url).catch(reason => {\n throw new Error(`Unable to load font data at: ${url}`);\n });\n }\n\n _fetchData(url) {\n (0, _util.unreachable)("Abstract method `_fetchData` called.");\n }\n\n}\n\nexports.BaseStandardFontDataFactory = BaseStandardFontDataFactory;\n\nclass BaseSVGFactory {\n constructor() {\n if (this.constructor === BaseSVGFactory) {\n (0, _util.unreachable)("Cannot initialize BaseSVGFactory.");\n }\n }\n\n create(width, height) {\n if (width <= 0 || height <= 0) {\n throw new Error("Invalid SVG dimensions");\n }\n\n const svg = this._createSVG("svg:svg");\n\n svg.setAttribute("version", "1.1");\n svg.setAttribute("width", `${width}px`);\n svg.setAttribute("height", `${height}px`);\n svg.setAttribute("preserveAspectRatio", "none");\n svg.setAttribute("viewBox", `0 0 ${width} ${height}`);\n return svg;\n }\n\n createElement(type) {\n if (typeof type !== "string") {\n throw new Error("Invalid SVG element type");\n }\n\n return this._createSVG(type);\n }\n\n _createSVG(type) {\n (0, _util.unreachable)("Abstract method `_createSVG` called.");\n }\n\n}\n\nexports.BaseSVGFactory = BaseSVGFactory;\n\n/***/ }),\n/* 7 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.FontLoader = exports.FontFaceObject = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nclass BaseFontLoader {\n constructor({\n docId,\n onUnsupportedFeature,\n ownerDocument = globalThis.document,\n styleElement = null\n }) {\n if (this.constructor === BaseFontLoader) {\n (0, _util.unreachable)("Cannot initialize BaseFontLoader.");\n }\n\n this.docId = docId;\n this._onUnsupportedFeature = onUnsupportedFeature;\n this._document = ownerDocument;\n this.nativeFontFaces = [];\n this.styleElement = null;\n }\n\n addNativeFontFace(nativeFontFace) {\n this.nativeFontFaces.push(nativeFontFace);\n\n this._document.fonts.add(nativeFontFace);\n }\n\n insertRule(rule) {\n let styleElement = this.styleElement;\n\n if (!styleElement) {\n styleElement = this.styleElement = this._document.createElement("style");\n styleElement.id = `PDFJS_FONT_STYLE_TAG_${this.docId}`;\n\n this._document.documentElement.getElementsByTagName("head")[0].appendChild(styleElement);\n }\n\n const styleSheet = styleElement.sheet;\n styleSheet.insertRule(rule, styleSheet.cssRules.length);\n }\n\n clear() {\n for (const nativeFontFace of this.nativeFontFaces) {\n this._document.fonts.delete(nativeFontFace);\n }\n\n this.nativeFontFaces.length = 0;\n\n if (this.styleElement) {\n this.styleElement.remove();\n this.styleElement = null;\n }\n }\n\n async bind(font) {\n if (font.attached || font.missingFile) {\n return;\n }\n\n font.attached = true;\n\n if (this.isFontLoadingAPISupported) {\n const nativeFontFace = font.createNativeFontFace();\n\n if (nativeFontFace) {\n this.addNativeFontFace(nativeFontFace);\n\n try {\n await nativeFontFace.loaded;\n } catch (ex) {\n this._onUnsupportedFeature({\n featureId: _util.UNSUPPORTED_FEATURES.errorFontLoadNative\n });\n\n (0, _util.warn)(`Failed to load font \'${nativeFontFace.family}\': \'${ex}\'.`);\n font.disableFontFace = true;\n throw ex;\n }\n }\n\n return;\n }\n\n const rule = font.createFontFaceRule();\n\n if (rule) {\n this.insertRule(rule);\n\n if (this.isSyncFontLoadingSupported) {\n return;\n }\n\n await new Promise(resolve => {\n const request = this._queueLoadingCallback(resolve);\n\n this._prepareFontLoadEvent([rule], [font], request);\n });\n }\n }\n\n _queueLoadingCallback(callback) {\n (0, _util.unreachable)("Abstract method `_queueLoadingCallback`.");\n }\n\n get isFontLoadingAPISupported() {\n const hasFonts = !!this._document?.fonts;\n return (0, _util.shadow)(this, "isFontLoadingAPISupported", hasFonts);\n }\n\n get isSyncFontLoadingSupported() {\n (0, _util.unreachable)("Abstract method `isSyncFontLoadingSupported`.");\n }\n\n get _loadTestFont() {\n (0, _util.unreachable)("Abstract method `_loadTestFont`.");\n }\n\n _prepareFontLoadEvent(rules, fontsToLoad, request) {\n (0, _util.unreachable)("Abstract method `_prepareFontLoadEvent`.");\n }\n\n}\n\nlet FontLoader;\nexports.FontLoader = FontLoader;\n{\n exports.FontLoader = FontLoader = class GenericFontLoader extends BaseFontLoader {\n constructor(params) {\n super(params);\n this.loadingContext = {\n requests: [],\n nextRequestId: 0\n };\n this.loadTestFontId = 0;\n }\n\n get isSyncFontLoadingSupported() {\n let supported = false;\n\n if (typeof navigator === "undefined") {\n supported = true;\n } else {\n const m = /Mozilla\\/5.0.*?rv:(\\d+).*? Gecko/.exec(navigator.userAgent);\n\n if (m?.[1] >= 14) {\n supported = true;\n }\n }\n\n return (0, _util.shadow)(this, "isSyncFontLoadingSupported", supported);\n }\n\n _queueLoadingCallback(callback) {\n function completeRequest() {\n (0, _util.assert)(!request.done, "completeRequest() cannot be called twice.");\n request.done = true;\n\n while (context.requests.length > 0 && context.requests[0].done) {\n const otherRequest = context.requests.shift();\n setTimeout(otherRequest.callback, 0);\n }\n }\n\n const context = this.loadingContext;\n const request = {\n id: `pdfjs-font-loading-${context.nextRequestId++}`,\n done: false,\n complete: completeRequest,\n callback\n };\n context.requests.push(request);\n return request;\n }\n\n get _loadTestFont() {\n const getLoadTestFont = function () {\n return atob("T1RUTwALAIAAAwAwQ0ZGIDHtZg4AAAOYAAAAgUZGVE1lkzZwAAAEHAAAABxHREVGABQA" + "FQAABDgAAAAeT1MvMlYNYwkAAAEgAAAAYGNtYXABDQLUAAACNAAAAUJoZWFk/xVFDQAA" + "ALwAAAA2aGhlYQdkA+oAAAD0AAAAJGhtdHgD6AAAAAAEWAAAAAZtYXhwAAJQAAAAARgA" + "AAAGbmFtZVjmdH4AAAGAAAAAsXBvc3T/hgAzAAADeAAAACAAAQAAAAEAALZRFsRfDzz1" + "AAsD6AAAAADOBOTLAAAAAM4KHDwAAAAAA+gDIQAAAAgAAgAAAAAAAAABAAADIQAAAFoD" + "6AAAAAAD6AABAAAAAAAAAAAAAAAAAAAAAQAAUAAAAgAAAAQD6AH0AAUAAAKKArwAAACM" + "AooCvAAAAeAAMQECAAACAAYJAAAAAAAAAAAAAQAAAAAAAAAAAAAAAFBmRWQAwAAuAC4D" + "IP84AFoDIQAAAAAAAQAAAAAAAAAAACAAIAABAAAADgCuAAEAAAAAAAAAAQAAAAEAAAAA" + "AAEAAQAAAAEAAAAAAAIAAQAAAAEAAAAAAAMAAQAAAAEAAAAAAAQAAQAAAAEAAAAAAAUA" + "AQAAAAEAAAAAAAYAAQAAAAMAAQQJAAAAAgABAAMAAQQJAAEAAgABAAMAAQQJAAIAAgAB" + "AAMAAQQJAAMAAgABAAMAAQQJAAQAAgABAAMAAQQJAAUAAgABAAMAAQQJAAYAAgABWABY" + "AAAAAAAAAwAAAAMAAAAcAAEAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAAAC7//wAA" + "AC7////TAAEAAAAAAAABBgAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAD/gwAyAAAAAQAAAAAAAAAAAAAAAAAA" + "AAABAAQEAAEBAQJYAAEBASH4DwD4GwHEAvgcA/gXBIwMAYuL+nz5tQXkD5j3CBLnEQAC" + "AQEBIVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYAAABAQAADwACAQEEE/t3" + "Dov6fAH6fAT+fPp8+nwHDosMCvm1Cvm1DAz6fBQAAAAAAAABAAAAAMmJbzEAAAAAzgTj" + "FQAAAADOBOQpAAEAAAAAAAAADAAUAAQAAAABAAAAAgABAAAAAAAAAAAD6AAAAAAAAA==");\n };\n\n return (0, _util.shadow)(this, "_loadTestFont", getLoadTestFont());\n }\n\n _prepareFontLoadEvent(rules, fonts, request) {\n function int32(data, offset) {\n return data.charCodeAt(offset) << 24 | data.charCodeAt(offset + 1) << 16 | data.charCodeAt(offset + 2) << 8 | data.charCodeAt(offset + 3) & 0xff;\n }\n\n function spliceString(s, offset, remove, insert) {\n const chunk1 = s.substring(0, offset);\n const chunk2 = s.substring(offset + remove);\n return chunk1 + insert + chunk2;\n }\n\n let i, ii;\n\n const canvas = this._document.createElement("canvas");\n\n canvas.width = 1;\n canvas.height = 1;\n const ctx = canvas.getContext("2d");\n let called = 0;\n\n function isFontReady(name, callback) {\n called++;\n\n if (called > 30) {\n (0, _util.warn)("Load test font never loaded.");\n callback();\n return;\n }\n\n ctx.font = "30px " + name;\n ctx.fillText(".", 0, 20);\n const imageData = ctx.getImageData(0, 0, 1, 1);\n\n if (imageData.data[3] > 0) {\n callback();\n return;\n }\n\n setTimeout(isFontReady.bind(null, name, callback));\n }\n\n const loadTestFontId = `lt${Date.now()}${this.loadTestFontId++}`;\n let data = this._loadTestFont;\n const COMMENT_OFFSET = 976;\n data = spliceString(data, COMMENT_OFFSET, loadTestFontId.length, loadTestFontId);\n const CFF_CHECKSUM_OFFSET = 16;\n const XXXX_VALUE = 0x58585858;\n let checksum = int32(data, CFF_CHECKSUM_OFFSET);\n\n for (i = 0, ii = loadTestFontId.length - 3; i < ii; i += 4) {\n checksum = checksum - XXXX_VALUE + int32(loadTestFontId, i) | 0;\n }\n\n if (i < loadTestFontId.length) {\n checksum = checksum - XXXX_VALUE + int32(loadTestFontId + "XXX", i) | 0;\n }\n\n data = spliceString(data, CFF_CHECKSUM_OFFSET, 4, (0, _util.string32)(checksum));\n const url = `url(data:font/opentype;base64,${btoa(data)});`;\n const rule = `@font-face {font-family:"${loadTestFontId}";src:${url}}`;\n this.insertRule(rule);\n const names = [];\n\n for (const font of fonts) {\n names.push(font.loadedName);\n }\n\n names.push(loadTestFontId);\n\n const div = this._document.createElement("div");\n\n div.style.visibility = "hidden";\n div.style.width = div.style.height = "10px";\n div.style.position = "absolute";\n div.style.top = div.style.left = "0px";\n\n for (const name of names) {\n const span = this._document.createElement("span");\n\n span.textContent = "Hi";\n span.style.fontFamily = name;\n div.appendChild(span);\n }\n\n this._document.body.appendChild(div);\n\n isFontReady(loadTestFontId, () => {\n div.remove();\n request.complete();\n });\n }\n\n };\n}\n\nclass FontFaceObject {\n constructor(translatedData, {\n isEvalSupported = true,\n disableFontFace = false,\n ignoreErrors = false,\n onUnsupportedFeature,\n fontRegistry = null\n }) {\n this.compiledGlyphs = Object.create(null);\n\n for (const i in translatedData) {\n this[i] = translatedData[i];\n }\n\n this.isEvalSupported = isEvalSupported !== false;\n this.disableFontFace = disableFontFace === true;\n this.ignoreErrors = ignoreErrors === true;\n this._onUnsupportedFeature = onUnsupportedFeature;\n this.fontRegistry = fontRegistry;\n }\n\n createNativeFontFace() {\n if (!this.data || this.disableFontFace) {\n return null;\n }\n\n let nativeFontFace;\n\n if (!this.cssFontInfo) {\n nativeFontFace = new FontFace(this.loadedName, this.data, {});\n } else {\n const css = {\n weight: this.cssFontInfo.fontWeight\n };\n\n if (this.cssFontInfo.italicAngle) {\n css.style = `oblique ${this.cssFontInfo.italicAngle}deg`;\n }\n\n nativeFontFace = new FontFace(this.cssFontInfo.fontFamily, this.data, css);\n }\n\n if (this.fontRegistry) {\n this.fontRegistry.registerFont(this);\n }\n\n return nativeFontFace;\n }\n\n createFontFaceRule() {\n if (!this.data || this.disableFontFace) {\n return null;\n }\n\n const data = (0, _util.bytesToString)(this.data);\n const url = `url(data:${this.mimetype};base64,${btoa(data)});`;\n let rule;\n\n if (!this.cssFontInfo) {\n rule = `@font-face {font-family:"${this.loadedName}";src:${url}}`;\n } else {\n let css = `font-weight: ${this.cssFontInfo.fontWeight};`;\n\n if (this.cssFontInfo.italicAngle) {\n css += `font-style: oblique ${this.cssFontInfo.italicAngle}deg;`;\n }\n\n rule = `@font-face {font-family:"${this.cssFontInfo.fontFamily}";${css}src:${url}}`;\n }\n\n if (this.fontRegistry) {\n this.fontRegistry.registerFont(this, url);\n }\n\n return rule;\n }\n\n getPathGenerator(objs, character) {\n if (this.compiledGlyphs[character] !== undefined) {\n return this.compiledGlyphs[character];\n }\n\n let cmds;\n\n try {\n cmds = objs.get(this.loadedName + "_path_" + character);\n } catch (ex) {\n if (!this.ignoreErrors) {\n throw ex;\n }\n\n this._onUnsupportedFeature({\n featureId: _util.UNSUPPORTED_FEATURES.errorFontGetPath\n });\n\n (0, _util.warn)(`getPathGenerator - ignoring character: "${ex}".`);\n return this.compiledGlyphs[character] = function (c, size) {};\n }\n\n if (this.isEvalSupported && _util.FeatureTest.isEvalSupported) {\n const jsBuf = [];\n\n for (const current of cmds) {\n const args = current.args !== undefined ? current.args.join(",") : "";\n jsBuf.push("c.", current.cmd, "(", args, ");\\n");\n }\n\n return this.compiledGlyphs[character] = new Function("c", "size", jsBuf.join(""));\n }\n\n return this.compiledGlyphs[character] = function (c, size) {\n for (const current of cmds) {\n if (current.cmd === "scale") {\n current.args = [size, -size];\n }\n\n c[current.cmd].apply(c, current.args);\n }\n };\n }\n\n}\n\nexports.FontFaceObject = FontFaceObject;\n\n/***/ }),\n/* 8 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.AnnotationStorage = void 0;\n\nvar _murmurhash = __w_pdfjs_require__(9);\n\nvar _util = __w_pdfjs_require__(1);\n\nclass AnnotationStorage {\n constructor() {\n this._storage = new Map();\n this._modified = false;\n this.onSetModified = null;\n this.onResetModified = null;\n }\n\n getValue(key, defaultValue) {\n const value = this._storage.get(key);\n\n if (value === undefined) {\n return defaultValue;\n }\n\n return Object.assign(defaultValue, value);\n }\n\n getRawValue(key) {\n return this._storage.get(key);\n }\n\n setValue(key, value) {\n const obj = this._storage.get(key);\n\n let modified = false;\n\n if (obj !== undefined) {\n for (const [entry, val] of Object.entries(value)) {\n if (obj[entry] !== val) {\n modified = true;\n obj[entry] = val;\n }\n }\n } else {\n modified = true;\n\n this._storage.set(key, value);\n }\n\n if (modified) {\n this._setModified();\n }\n }\n\n getAll() {\n return this._storage.size > 0 ? (0, _util.objectFromMap)(this._storage) : null;\n }\n\n get size() {\n return this._storage.size;\n }\n\n _setModified() {\n if (!this._modified) {\n this._modified = true;\n\n if (typeof this.onSetModified === "function") {\n this.onSetModified();\n }\n }\n }\n\n resetModified() {\n if (this._modified) {\n this._modified = false;\n\n if (typeof this.onResetModified === "function") {\n this.onResetModified();\n }\n }\n }\n\n get serializable() {\n return this._storage.size > 0 ? this._storage : null;\n }\n\n get hash() {\n const hash = new _murmurhash.MurmurHash3_64();\n\n for (const [key, value] of this._storage) {\n hash.update(`${key}:${JSON.stringify(value)}`);\n }\n\n return hash.hexdigest();\n }\n\n}\n\nexports.AnnotationStorage = AnnotationStorage;\n\n/***/ }),\n/* 9 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.MurmurHash3_64 = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nconst SEED = 0xc3d2e1f0;\nconst MASK_HIGH = 0xffff0000;\nconst MASK_LOW = 0xffff;\n\nclass MurmurHash3_64 {\n constructor(seed) {\n this.h1 = seed ? seed & 0xffffffff : SEED;\n this.h2 = seed ? seed & 0xffffffff : SEED;\n }\n\n update(input) {\n let data, length;\n\n if (typeof input === "string") {\n data = new Uint8Array(input.length * 2);\n length = 0;\n\n for (let i = 0, ii = input.length; i < ii; i++) {\n const code = input.charCodeAt(i);\n\n if (code <= 0xff) {\n data[length++] = code;\n } else {\n data[length++] = code >>> 8;\n data[length++] = code & 0xff;\n }\n }\n } else if ((0, _util.isArrayBuffer)(input)) {\n data = input.slice();\n length = data.byteLength;\n } else {\n throw new Error("Wrong data format in MurmurHash3_64_update. " + "Input must be a string or array.");\n }\n\n const blockCounts = length >> 2;\n const tailLength = length - blockCounts * 4;\n const dataUint32 = new Uint32Array(data.buffer, 0, blockCounts);\n let k1 = 0,\n k2 = 0;\n let h1 = this.h1,\n h2 = this.h2;\n const C1 = 0xcc9e2d51,\n C2 = 0x1b873593;\n const C1_LOW = C1 & MASK_LOW,\n C2_LOW = C2 & MASK_LOW;\n\n for (let i = 0; i < blockCounts; i++) {\n if (i & 1) {\n k1 = dataUint32[i];\n k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW;\n k1 = k1 << 15 | k1 >>> 17;\n k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW;\n h1 ^= k1;\n h1 = h1 << 13 | h1 >>> 19;\n h1 = h1 * 5 + 0xe6546b64;\n } else {\n k2 = dataUint32[i];\n k2 = k2 * C1 & MASK_HIGH | k2 * C1_LOW & MASK_LOW;\n k2 = k2 << 15 | k2 >>> 17;\n k2 = k2 * C2 & MASK_HIGH | k2 * C2_LOW & MASK_LOW;\n h2 ^= k2;\n h2 = h2 << 13 | h2 >>> 19;\n h2 = h2 * 5 + 0xe6546b64;\n }\n }\n\n k1 = 0;\n\n switch (tailLength) {\n case 3:\n k1 ^= data[blockCounts * 4 + 2] << 16;\n\n case 2:\n k1 ^= data[blockCounts * 4 + 1] << 8;\n\n case 1:\n k1 ^= data[blockCounts * 4];\n k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW;\n k1 = k1 << 15 | k1 >>> 17;\n k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW;\n\n if (blockCounts & 1) {\n h1 ^= k1;\n } else {\n h2 ^= k1;\n }\n\n }\n\n this.h1 = h1;\n this.h2 = h2;\n }\n\n hexdigest() {\n let h1 = this.h1,\n h2 = this.h2;\n h1 ^= h2 >>> 1;\n h1 = h1 * 0xed558ccd & MASK_HIGH | h1 * 0x8ccd & MASK_LOW;\n h2 = h2 * 0xff51afd7 & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xafd7ed55 & MASK_HIGH) >>> 16;\n h1 ^= h2 >>> 1;\n h1 = h1 * 0x1a85ec53 & MASK_HIGH | h1 * 0xec53 & MASK_LOW;\n h2 = h2 * 0xc4ceb9fe & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xb9fe1a85 & MASK_HIGH) >>> 16;\n h1 ^= h2 >>> 1;\n const hex1 = (h1 >>> 0).toString(16),\n hex2 = (h2 >>> 0).toString(16);\n return hex1.padStart(8, "0") + hex2.padStart(8, "0");\n }\n\n}\n\nexports.MurmurHash3_64 = MurmurHash3_64;\n\n/***/ }),\n/* 10 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.CanvasGraphics = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _pattern_helper = __w_pdfjs_require__(11);\n\nvar _image_utils = __w_pdfjs_require__(12);\n\nvar _is_node = __w_pdfjs_require__(3);\n\nvar _display_utils = __w_pdfjs_require__(5);\n\nconst MIN_FONT_SIZE = 16;\nconst MAX_FONT_SIZE = 100;\nconst MAX_GROUP_SIZE = 4096;\nconst EXECUTION_TIME = 15;\nconst EXECUTION_STEPS = 10;\nconst COMPILE_TYPE3_GLYPHS = true;\nconst MAX_SIZE_TO_COMPILE = 1000;\nconst FULL_CHUNK_HEIGHT = 16;\nconst LINEWIDTH_SCALE_FACTOR = 1.000001;\n\nfunction mirrorContextOperations(ctx, destCtx) {\n if (ctx._removeMirroring) {\n throw new Error("Context is already forwarding operations.");\n }\n\n ctx.__originalSave = ctx.save;\n ctx.__originalRestore = ctx.restore;\n ctx.__originalRotate = ctx.rotate;\n ctx.__originalScale = ctx.scale;\n ctx.__originalTranslate = ctx.translate;\n ctx.__originalTransform = ctx.transform;\n ctx.__originalSetTransform = ctx.setTransform;\n ctx.__originalResetTransform = ctx.resetTransform;\n ctx.__originalClip = ctx.clip;\n ctx.__originalMoveTo = ctx.moveTo;\n ctx.__originalLineTo = ctx.lineTo;\n ctx.__originalBezierCurveTo = ctx.bezierCurveTo;\n ctx.__originalRect = ctx.rect;\n ctx.__originalClosePath = ctx.closePath;\n ctx.__originalBeginPath = ctx.beginPath;\n\n ctx._removeMirroring = () => {\n ctx.save = ctx.__originalSave;\n ctx.restore = ctx.__originalRestore;\n ctx.rotate = ctx.__originalRotate;\n ctx.scale = ctx.__originalScale;\n ctx.translate = ctx.__originalTranslate;\n ctx.transform = ctx.__originalTransform;\n ctx.setTransform = ctx.__originalSetTransform;\n ctx.resetTransform = ctx.__originalResetTransform;\n ctx.clip = ctx.__originalClip;\n ctx.moveTo = ctx.__originalMoveTo;\n ctx.lineTo = ctx.__originalLineTo;\n ctx.bezierCurveTo = ctx.__originalBezierCurveTo;\n ctx.rect = ctx.__originalRect;\n ctx.closePath = ctx.__originalClosePath;\n ctx.beginPath = ctx.__originalBeginPath;\n delete ctx._removeMirroring;\n };\n\n ctx.save = function ctxSave() {\n destCtx.save();\n\n this.__originalSave();\n };\n\n ctx.restore = function ctxRestore() {\n destCtx.restore();\n\n this.__originalRestore();\n };\n\n ctx.translate = function ctxTranslate(x, y) {\n destCtx.translate(x, y);\n\n this.__originalTranslate(x, y);\n };\n\n ctx.scale = function ctxScale(x, y) {\n destCtx.scale(x, y);\n\n this.__originalScale(x, y);\n };\n\n ctx.transform = function ctxTransform(a, b, c, d, e, f) {\n destCtx.transform(a, b, c, d, e, f);\n\n this.__originalTransform(a, b, c, d, e, f);\n };\n\n ctx.setTransform = function ctxSetTransform(a, b, c, d, e, f) {\n destCtx.setTransform(a, b, c, d, e, f);\n\n this.__originalSetTransform(a, b, c, d, e, f);\n };\n\n ctx.resetTransform = function ctxResetTransform() {\n destCtx.resetTransform();\n\n this.__originalResetTransform();\n };\n\n ctx.rotate = function ctxRotate(angle) {\n destCtx.rotate(angle);\n\n this.__originalRotate(angle);\n };\n\n ctx.clip = function ctxRotate(rule) {\n destCtx.clip(rule);\n\n this.__originalClip(rule);\n };\n\n ctx.moveTo = function (x, y) {\n destCtx.moveTo(x, y);\n\n this.__originalMoveTo(x, y);\n };\n\n ctx.lineTo = function (x, y) {\n destCtx.lineTo(x, y);\n\n this.__originalLineTo(x, y);\n };\n\n ctx.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) {\n destCtx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);\n\n this.__originalBezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);\n };\n\n ctx.rect = function (x, y, width, height) {\n destCtx.rect(x, y, width, height);\n\n this.__originalRect(x, y, width, height);\n };\n\n ctx.closePath = function () {\n destCtx.closePath();\n\n this.__originalClosePath();\n };\n\n ctx.beginPath = function () {\n destCtx.beginPath();\n\n this.__originalBeginPath();\n };\n}\n\nfunction addContextCurrentTransform(ctx) {\n if (ctx._transformStack) {\n ctx._transformStack = [];\n }\n\n if (ctx.mozCurrentTransform) {\n return;\n }\n\n ctx._originalSave = ctx.save;\n ctx._originalRestore = ctx.restore;\n ctx._originalRotate = ctx.rotate;\n ctx._originalScale = ctx.scale;\n ctx._originalTranslate = ctx.translate;\n ctx._originalTransform = ctx.transform;\n ctx._originalSetTransform = ctx.setTransform;\n ctx._originalResetTransform = ctx.resetTransform;\n ctx._transformMatrix = ctx._transformMatrix || [1, 0, 0, 1, 0, 0];\n ctx._transformStack = [];\n\n try {\n const desc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(ctx), "lineWidth");\n ctx._setLineWidth = desc.set;\n ctx._getLineWidth = desc.get;\n Object.defineProperty(ctx, "lineWidth", {\n set: function setLineWidth(width) {\n this._setLineWidth(width * LINEWIDTH_SCALE_FACTOR);\n },\n get: function getLineWidth() {\n return this._getLineWidth();\n }\n });\n } catch (_) {}\n\n Object.defineProperty(ctx, "mozCurrentTransform", {\n get: function getCurrentTransform() {\n return this._transformMatrix;\n }\n });\n Object.defineProperty(ctx, "mozCurrentTransformInverse", {\n get: function getCurrentTransformInverse() {\n const [a, b, c, d, e, f] = this._transformMatrix;\n const ad_bc = a * d - b * c;\n const bc_ad = b * c - a * d;\n return [d / ad_bc, b / bc_ad, c / bc_ad, a / ad_bc, (d * e - c * f) / bc_ad, (b * e - a * f) / ad_bc];\n }\n });\n\n ctx.save = function ctxSave() {\n const old = this._transformMatrix;\n\n this._transformStack.push(old);\n\n this._transformMatrix = old.slice(0, 6);\n\n this._originalSave();\n };\n\n ctx.restore = function ctxRestore() {\n if (this._transformStack.length === 0) {\n (0, _util.warn)("Tried to restore a ctx when the stack was already empty.");\n }\n\n const prev = this._transformStack.pop();\n\n if (prev) {\n this._transformMatrix = prev;\n\n this._originalRestore();\n }\n };\n\n ctx.translate = function ctxTranslate(x, y) {\n const m = this._transformMatrix;\n m[4] = m[0] * x + m[2] * y + m[4];\n m[5] = m[1] * x + m[3] * y + m[5];\n\n this._originalTranslate(x, y);\n };\n\n ctx.scale = function ctxScale(x, y) {\n const m = this._transformMatrix;\n m[0] *= x;\n m[1] *= x;\n m[2] *= y;\n m[3] *= y;\n\n this._originalScale(x, y);\n };\n\n ctx.transform = function ctxTransform(a, b, c, d, e, f) {\n const m = this._transformMatrix;\n this._transformMatrix = [m[0] * a + m[2] * b, m[1] * a + m[3] * b, m[0] * c + m[2] * d, m[1] * c + m[3] * d, m[0] * e + m[2] * f + m[4], m[1] * e + m[3] * f + m[5]];\n\n ctx._originalTransform(a, b, c, d, e, f);\n };\n\n ctx.setTransform = function ctxSetTransform(a, b, c, d, e, f) {\n this._transformMatrix = [a, b, c, d, e, f];\n\n ctx._originalSetTransform(a, b, c, d, e, f);\n };\n\n ctx.resetTransform = function ctxResetTransform() {\n this._transformMatrix = [1, 0, 0, 1, 0, 0];\n\n ctx._originalResetTransform();\n };\n\n ctx.rotate = function ctxRotate(angle) {\n const cosValue = Math.cos(angle);\n const sinValue = Math.sin(angle);\n const m = this._transformMatrix;\n this._transformMatrix = [m[0] * cosValue + m[2] * sinValue, m[1] * cosValue + m[3] * sinValue, m[0] * -sinValue + m[2] * cosValue, m[1] * -sinValue + m[3] * cosValue, m[4], m[5]];\n\n this._originalRotate(angle);\n };\n}\n\nclass CachedCanvases {\n constructor(canvasFactory) {\n this.canvasFactory = canvasFactory;\n this.cache = Object.create(null);\n }\n\n getCanvas(id, width, height, trackTransform) {\n let canvasEntry;\n\n if (this.cache[id] !== undefined) {\n canvasEntry = this.cache[id];\n this.canvasFactory.reset(canvasEntry, width, height);\n canvasEntry.context.setTransform(1, 0, 0, 1, 0, 0);\n } else {\n canvasEntry = this.canvasFactory.create(width, height);\n this.cache[id] = canvasEntry;\n }\n\n if (trackTransform) {\n addContextCurrentTransform(canvasEntry.context);\n }\n\n return canvasEntry;\n }\n\n delete(id) {\n delete this.cache[id];\n }\n\n clear() {\n for (const id in this.cache) {\n const canvasEntry = this.cache[id];\n this.canvasFactory.destroy(canvasEntry);\n delete this.cache[id];\n }\n }\n\n}\n\nfunction drawImageAtIntegerCoords(ctx, srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH) {\n const [a, b, c, d, tx, ty] = ctx.mozCurrentTransform;\n\n if (b === 0 && c === 0) {\n const tlX = destX * a + tx;\n const rTlX = Math.round(tlX);\n const tlY = destY * d + ty;\n const rTlY = Math.round(tlY);\n const brX = (destX + destW) * a + tx;\n const rWidth = Math.abs(Math.round(brX) - rTlX) || 1;\n const brY = (destY + destH) * d + ty;\n const rHeight = Math.abs(Math.round(brY) - rTlY) || 1;\n ctx.setTransform(Math.sign(a), 0, 0, Math.sign(d), rTlX, rTlY);\n ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rWidth, rHeight);\n ctx.setTransform(a, b, c, d, tx, ty);\n return [rWidth, rHeight];\n }\n\n if (a === 0 && d === 0) {\n const tlX = destY * c + tx;\n const rTlX = Math.round(tlX);\n const tlY = destX * b + ty;\n const rTlY = Math.round(tlY);\n const brX = (destY + destH) * c + tx;\n const rWidth = Math.abs(Math.round(brX) - rTlX) || 1;\n const brY = (destX + destW) * b + ty;\n const rHeight = Math.abs(Math.round(brY) - rTlY) || 1;\n ctx.setTransform(0, Math.sign(b), Math.sign(c), 0, rTlX, rTlY);\n ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rHeight, rWidth);\n ctx.setTransform(a, b, c, d, tx, ty);\n return [rHeight, rWidth];\n }\n\n ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH);\n const scaleX = Math.hypot(a, b);\n const scaleY = Math.hypot(c, d);\n return [scaleX * destW, scaleY * destH];\n}\n\nfunction compileType3Glyph(imgData) {\n const {\n width,\n height\n } = imgData;\n\n if (!COMPILE_TYPE3_GLYPHS || width > MAX_SIZE_TO_COMPILE || height > MAX_SIZE_TO_COMPILE) {\n return null;\n }\n\n const POINT_TO_PROCESS_LIMIT = 1000;\n const POINT_TYPES = new Uint8Array([0, 2, 4, 0, 1, 0, 5, 4, 8, 10, 0, 8, 0, 2, 1, 0]);\n const width1 = width + 1;\n let points = new Uint8Array(width1 * (height + 1));\n let i, j, j0;\n const lineSize = width + 7 & ~7;\n let data = new Uint8Array(lineSize * height),\n pos = 0;\n\n for (const elem of imgData.data) {\n let mask = 128;\n\n while (mask > 0) {\n data[pos++] = elem & mask ? 0 : 255;\n mask >>= 1;\n }\n }\n\n let count = 0;\n pos = 0;\n\n if (data[pos] !== 0) {\n points[0] = 1;\n ++count;\n }\n\n for (j = 1; j < width; j++) {\n if (data[pos] !== data[pos + 1]) {\n points[j] = data[pos] ? 2 : 1;\n ++count;\n }\n\n pos++;\n }\n\n if (data[pos] !== 0) {\n points[j] = 2;\n ++count;\n }\n\n for (i = 1; i < height; i++) {\n pos = i * lineSize;\n j0 = i * width1;\n\n if (data[pos - lineSize] !== data[pos]) {\n points[j0] = data[pos] ? 1 : 8;\n ++count;\n }\n\n let sum = (data[pos] ? 4 : 0) + (data[pos - lineSize] ? 8 : 0);\n\n for (j = 1; j < width; j++) {\n sum = (sum >> 2) + (data[pos + 1] ? 4 : 0) + (data[pos - lineSize + 1] ? 8 : 0);\n\n if (POINT_TYPES[sum]) {\n points[j0 + j] = POINT_TYPES[sum];\n ++count;\n }\n\n pos++;\n }\n\n if (data[pos - lineSize] !== data[pos]) {\n points[j0 + j] = data[pos] ? 2 : 4;\n ++count;\n }\n\n if (count > POINT_TO_PROCESS_LIMIT) {\n return null;\n }\n }\n\n pos = lineSize * (height - 1);\n j0 = i * width1;\n\n if (data[pos] !== 0) {\n points[j0] = 8;\n ++count;\n }\n\n for (j = 1; j < width; j++) {\n if (data[pos] !== data[pos + 1]) {\n points[j0 + j] = data[pos] ? 4 : 8;\n ++count;\n }\n\n pos++;\n }\n\n if (data[pos] !== 0) {\n points[j0 + j] = 4;\n ++count;\n }\n\n if (count > POINT_TO_PROCESS_LIMIT) {\n return null;\n }\n\n const steps = new Int32Array([0, width1, -1, 0, -width1, 0, 0, 0, 1]);\n let path, outlines, coords;\n\n if (!_is_node.isNodeJS) {\n path = new Path2D();\n } else {\n outlines = [];\n }\n\n for (i = 0; count && i <= height; i++) {\n let p = i * width1;\n const end = p + width;\n\n while (p < end && !points[p]) {\n p++;\n }\n\n if (p === end) {\n continue;\n }\n\n if (path) {\n path.moveTo(p % width1, i);\n } else {\n coords = [p % width1, i];\n }\n\n const p0 = p;\n let type = points[p];\n\n do {\n const step = steps[type];\n\n do {\n p += step;\n } while (!points[p]);\n\n const pp = points[p];\n\n if (pp !== 5 && pp !== 10) {\n type = pp;\n points[p] = 0;\n } else {\n type = pp & 0x33 * type >> 4;\n points[p] &= type >> 2 | type << 2;\n }\n\n if (path) {\n path.lineTo(p % width1, p / width1 | 0);\n } else {\n coords.push(p % width1, p / width1 | 0);\n }\n\n if (!points[p]) {\n --count;\n }\n } while (p0 !== p);\n\n if (!path) {\n outlines.push(coords);\n }\n\n --i;\n }\n\n data = null;\n points = null;\n\n const drawOutline = function (c) {\n c.save();\n c.scale(1 / width, -1 / height);\n c.translate(0, -height);\n\n if (path) {\n c.fill(path);\n } else {\n c.beginPath();\n\n for (const o of outlines) {\n c.moveTo(o[0], o[1]);\n\n for (let l = 2, ll = o.length; l < ll; l += 2) {\n c.lineTo(o[l], o[l + 1]);\n }\n }\n\n c.fill();\n }\n\n c.beginPath();\n c.restore();\n };\n\n return drawOutline;\n}\n\nclass CanvasExtraState {\n constructor(width, height) {\n this.alphaIsShape = false;\n this.fontSize = 0;\n this.fontSizeScale = 1;\n this.textMatrix = _util.IDENTITY_MATRIX;\n this.textMatrixScale = 1;\n this.fontMatrix = _util.FONT_IDENTITY_MATRIX;\n this.leading = 0;\n this.x = 0;\n this.y = 0;\n this.lineX = 0;\n this.lineY = 0;\n this.charSpacing = 0;\n this.wordSpacing = 0;\n this.textHScale = 1;\n this.textRenderingMode = _util.TextRenderingMode.FILL;\n this.textRise = 0;\n this.fillColor = "#000000";\n this.strokeColor = "#000000";\n this.patternFill = false;\n this.fillAlpha = 1;\n this.strokeAlpha = 1;\n this.lineWidth = 1;\n this.activeSMask = null;\n this.transferMaps = null;\n this.startNewPathAndClipBox([0, 0, width, height]);\n }\n\n clone() {\n const clone = Object.create(this);\n clone.clipBox = this.clipBox.slice();\n return clone;\n }\n\n setCurrentPoint(x, y) {\n this.x = x;\n this.y = y;\n }\n\n updatePathMinMax(transform, x, y) {\n [x, y] = _util.Util.applyTransform([x, y], transform);\n this.minX = Math.min(this.minX, x);\n this.minY = Math.min(this.minY, y);\n this.maxX = Math.max(this.maxX, x);\n this.maxY = Math.max(this.maxY, y);\n }\n\n updateRectMinMax(transform, rect) {\n const p1 = _util.Util.applyTransform(rect, transform);\n\n const p2 = _util.Util.applyTransform(rect.slice(2), transform);\n\n this.minX = Math.min(this.minX, p1[0], p2[0]);\n this.minY = Math.min(this.minY, p1[1], p2[1]);\n this.maxX = Math.max(this.maxX, p1[0], p2[0]);\n this.maxY = Math.max(this.maxY, p1[1], p2[1]);\n }\n\n updateScalingPathMinMax(transform, minMax) {\n _util.Util.scaleMinMax(transform, minMax);\n\n this.minX = Math.min(this.minX, minMax[0]);\n this.maxX = Math.max(this.maxX, minMax[1]);\n this.minY = Math.min(this.minY, minMax[2]);\n this.maxY = Math.max(this.maxY, minMax[3]);\n }\n\n updateCurvePathMinMax(transform, x0, y0, x1, y1, x2, y2, x3, y3, minMax) {\n const box = _util.Util.bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3);\n\n if (minMax) {\n minMax[0] = Math.min(minMax[0], box[0], box[2]);\n minMax[1] = Math.max(minMax[1], box[0], box[2]);\n minMax[2] = Math.min(minMax[2], box[1], box[3]);\n minMax[3] = Math.max(minMax[3], box[1], box[3]);\n return;\n }\n\n this.updateRectMinMax(transform, box);\n }\n\n getPathBoundingBox(pathType = _pattern_helper.PathType.FILL, transform = null) {\n const box = [this.minX, this.minY, this.maxX, this.maxY];\n\n if (pathType === _pattern_helper.PathType.STROKE) {\n if (!transform) {\n (0, _util.unreachable)("Stroke bounding box must include transform.");\n }\n\n const scale = _util.Util.singularValueDecompose2dScale(transform);\n\n const xStrokePad = scale[0] * this.lineWidth / 2;\n const yStrokePad = scale[1] * this.lineWidth / 2;\n box[0] -= xStrokePad;\n box[1] -= yStrokePad;\n box[2] += xStrokePad;\n box[3] += yStrokePad;\n }\n\n return box;\n }\n\n updateClipFromPath() {\n const intersect = _util.Util.intersect(this.clipBox, this.getPathBoundingBox());\n\n this.startNewPathAndClipBox(intersect || [0, 0, 0, 0]);\n }\n\n isEmptyClip() {\n return this.minX === Infinity;\n }\n\n startNewPathAndClipBox(box) {\n this.clipBox = box;\n this.minX = Infinity;\n this.minY = Infinity;\n this.maxX = 0;\n this.maxY = 0;\n }\n\n getClippedPathBoundingBox(pathType = _pattern_helper.PathType.FILL, transform = null) {\n return _util.Util.intersect(this.clipBox, this.getPathBoundingBox(pathType, transform));\n }\n\n}\n\nfunction putBinaryImageData(ctx, imgData, transferMaps = null) {\n if (typeof ImageData !== "undefined" && imgData instanceof ImageData) {\n ctx.putImageData(imgData, 0, 0);\n return;\n }\n\n const height = imgData.height,\n width = imgData.width;\n const partialChunkHeight = height % FULL_CHUNK_HEIGHT;\n const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT;\n const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1;\n const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT);\n let srcPos = 0,\n destPos;\n const src = imgData.data;\n const dest = chunkImgData.data;\n let i, j, thisChunkHeight, elemsInThisChunk;\n let transferMapRed, transferMapGreen, transferMapBlue, transferMapGray;\n\n if (transferMaps) {\n switch (transferMaps.length) {\n case 1:\n transferMapRed = transferMaps[0];\n transferMapGreen = transferMaps[0];\n transferMapBlue = transferMaps[0];\n transferMapGray = transferMaps[0];\n break;\n\n case 4:\n transferMapRed = transferMaps[0];\n transferMapGreen = transferMaps[1];\n transferMapBlue = transferMaps[2];\n transferMapGray = transferMaps[3];\n break;\n }\n }\n\n if (imgData.kind === _util.ImageKind.GRAYSCALE_1BPP) {\n const srcLength = src.byteLength;\n const dest32 = new Uint32Array(dest.buffer, 0, dest.byteLength >> 2);\n const dest32DataLength = dest32.length;\n const fullSrcDiff = width + 7 >> 3;\n let white = 0xffffffff;\n let black = _util.FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff;\n\n if (transferMapGray) {\n if (transferMapGray[0] === 0xff && transferMapGray[0xff] === 0) {\n [white, black] = [black, white];\n }\n }\n\n for (i = 0; i < totalChunks; i++) {\n thisChunkHeight = i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight;\n destPos = 0;\n\n for (j = 0; j < thisChunkHeight; j++) {\n const srcDiff = srcLength - srcPos;\n let k = 0;\n const kEnd = srcDiff > fullSrcDiff ? width : srcDiff * 8 - 7;\n const kEndUnrolled = kEnd & ~7;\n let mask = 0;\n let srcByte = 0;\n\n for (; k < kEndUnrolled; k += 8) {\n srcByte = src[srcPos++];\n dest32[destPos++] = srcByte & 128 ? white : black;\n dest32[destPos++] = srcByte & 64 ? white : black;\n dest32[destPos++] = srcByte & 32 ? white : black;\n dest32[destPos++] = srcByte & 16 ? white : black;\n dest32[destPos++] = srcByte & 8 ? white : black;\n dest32[destPos++] = srcByte & 4 ? white : black;\n dest32[destPos++] = srcByte & 2 ? white : black;\n dest32[destPos++] = srcByte & 1 ? white : black;\n }\n\n for (; k < kEnd; k++) {\n if (mask === 0) {\n srcByte = src[srcPos++];\n mask = 128;\n }\n\n dest32[destPos++] = srcByte & mask ? white : black;\n mask >>= 1;\n }\n }\n\n while (destPos < dest32DataLength) {\n dest32[destPos++] = 0;\n }\n\n ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT);\n }\n } else if (imgData.kind === _util.ImageKind.RGBA_32BPP) {\n const hasTransferMaps = !!(transferMapRed || transferMapGreen || transferMapBlue);\n j = 0;\n elemsInThisChunk = width * FULL_CHUNK_HEIGHT * 4;\n\n for (i = 0; i < fullChunks; i++) {\n dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk));\n srcPos += elemsInThisChunk;\n\n if (hasTransferMaps) {\n for (let k = 0; k < elemsInThisChunk; k += 4) {\n if (transferMapRed) {\n dest[k + 0] = transferMapRed[dest[k + 0]];\n }\n\n if (transferMapGreen) {\n dest[k + 1] = transferMapGreen[dest[k + 1]];\n }\n\n if (transferMapBlue) {\n dest[k + 2] = transferMapBlue[dest[k + 2]];\n }\n }\n }\n\n ctx.putImageData(chunkImgData, 0, j);\n j += FULL_CHUNK_HEIGHT;\n }\n\n if (i < totalChunks) {\n elemsInThisChunk = width * partialChunkHeight * 4;\n dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk));\n\n if (hasTransferMaps) {\n for (let k = 0; k < elemsInThisChunk; k += 4) {\n if (transferMapRed) {\n dest[k + 0] = transferMapRed[dest[k + 0]];\n }\n\n if (transferMapGreen) {\n dest[k + 1] = transferMapGreen[dest[k + 1]];\n }\n\n if (transferMapBlue) {\n dest[k + 2] = transferMapBlue[dest[k + 2]];\n }\n }\n }\n\n ctx.putImageData(chunkImgData, 0, j);\n }\n } else if (imgData.kind === _util.ImageKind.RGB_24BPP) {\n const hasTransferMaps = !!(transferMapRed || transferMapGreen || transferMapBlue);\n thisChunkHeight = FULL_CHUNK_HEIGHT;\n elemsInThisChunk = width * thisChunkHeight;\n\n for (i = 0; i < totalChunks; i++) {\n if (i >= fullChunks) {\n thisChunkHeight = partialChunkHeight;\n elemsInThisChunk = width * thisChunkHeight;\n }\n\n destPos = 0;\n\n for (j = elemsInThisChunk; j--;) {\n dest[destPos++] = src[srcPos++];\n dest[destPos++] = src[srcPos++];\n dest[destPos++] = src[srcPos++];\n dest[destPos++] = 255;\n }\n\n if (hasTransferMaps) {\n for (let k = 0; k < destPos; k += 4) {\n if (transferMapRed) {\n dest[k + 0] = transferMapRed[dest[k + 0]];\n }\n\n if (transferMapGreen) {\n dest[k + 1] = transferMapGreen[dest[k + 1]];\n }\n\n if (transferMapBlue) {\n dest[k + 2] = transferMapBlue[dest[k + 2]];\n }\n }\n }\n\n ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT);\n }\n } else {\n throw new Error(`bad image kind: ${imgData.kind}`);\n }\n}\n\nfunction putBinaryImageMask(ctx, imgData) {\n if (imgData.bitmap) {\n ctx.drawImage(imgData.bitmap, 0, 0);\n return;\n }\n\n const height = imgData.height,\n width = imgData.width;\n const partialChunkHeight = height % FULL_CHUNK_HEIGHT;\n const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT;\n const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1;\n const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT);\n let srcPos = 0;\n const src = imgData.data;\n const dest = chunkImgData.data;\n\n for (let i = 0; i < totalChunks; i++) {\n const thisChunkHeight = i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight;\n ({\n srcPos\n } = (0, _image_utils.applyMaskImageData)({\n src,\n srcPos,\n dest,\n width,\n height: thisChunkHeight\n }));\n ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT);\n }\n}\n\nfunction copyCtxState(sourceCtx, destCtx) {\n const properties = ["strokeStyle", "fillStyle", "fillRule", "globalAlpha", "lineWidth", "lineCap", "lineJoin", "miterLimit", "globalCompositeOperation", "font"];\n\n for (let i = 0, ii = properties.length; i < ii; i++) {\n const property = properties[i];\n\n if (sourceCtx[property] !== undefined) {\n destCtx[property] = sourceCtx[property];\n }\n }\n\n if (sourceCtx.setLineDash !== undefined) {\n destCtx.setLineDash(sourceCtx.getLineDash());\n destCtx.lineDashOffset = sourceCtx.lineDashOffset;\n }\n}\n\nfunction resetCtxToDefault(ctx, foregroundColor) {\n ctx.strokeStyle = ctx.fillStyle = foregroundColor || "#000000";\n ctx.fillRule = "nonzero";\n ctx.globalAlpha = 1;\n ctx.lineWidth = 1;\n ctx.lineCap = "butt";\n ctx.lineJoin = "miter";\n ctx.miterLimit = 10;\n ctx.globalCompositeOperation = "source-over";\n ctx.font = "10px sans-serif";\n\n if (ctx.setLineDash !== undefined) {\n ctx.setLineDash([]);\n ctx.lineDashOffset = 0;\n }\n}\n\nfunction composeSMaskBackdrop(bytes, r0, g0, b0) {\n const length = bytes.length;\n\n for (let i = 3; i < length; i += 4) {\n const alpha = bytes[i];\n\n if (alpha === 0) {\n bytes[i - 3] = r0;\n bytes[i - 2] = g0;\n bytes[i - 1] = b0;\n } else if (alpha < 255) {\n const alpha_ = 255 - alpha;\n bytes[i - 3] = bytes[i - 3] * alpha + r0 * alpha_ >> 8;\n bytes[i - 2] = bytes[i - 2] * alpha + g0 * alpha_ >> 8;\n bytes[i - 1] = bytes[i - 1] * alpha + b0 * alpha_ >> 8;\n }\n }\n}\n\nfunction composeSMaskAlpha(maskData, layerData, transferMap) {\n const length = maskData.length;\n const scale = 1 / 255;\n\n for (let i = 3; i < length; i += 4) {\n const alpha = transferMap ? transferMap[maskData[i]] : maskData[i];\n layerData[i] = layerData[i] * alpha * scale | 0;\n }\n}\n\nfunction composeSMaskLuminosity(maskData, layerData, transferMap) {\n const length = maskData.length;\n\n for (let i = 3; i < length; i += 4) {\n const y = maskData[i - 3] * 77 + maskData[i - 2] * 152 + maskData[i - 1] * 28;\n layerData[i] = transferMap ? layerData[i] * transferMap[y >> 8] >> 8 : layerData[i] * y >> 16;\n }\n}\n\nfunction genericComposeSMask(maskCtx, layerCtx, width, height, subtype, backdrop, transferMap, layerOffsetX, layerOffsetY, maskOffsetX, maskOffsetY) {\n const hasBackdrop = !!backdrop;\n const r0 = hasBackdrop ? backdrop[0] : 0;\n const g0 = hasBackdrop ? backdrop[1] : 0;\n const b0 = hasBackdrop ? backdrop[2] : 0;\n let composeFn;\n\n if (subtype === "Luminosity") {\n composeFn = composeSMaskLuminosity;\n } else {\n composeFn = composeSMaskAlpha;\n }\n\n const PIXELS_TO_PROCESS = 1048576;\n const chunkSize = Math.min(height, Math.ceil(PIXELS_TO_PROCESS / width));\n\n for (let row = 0; row < height; row += chunkSize) {\n const chunkHeight = Math.min(chunkSize, height - row);\n const maskData = maskCtx.getImageData(layerOffsetX - maskOffsetX, row + (layerOffsetY - maskOffsetY), width, chunkHeight);\n const layerData = layerCtx.getImageData(layerOffsetX, row + layerOffsetY, width, chunkHeight);\n\n if (hasBackdrop) {\n composeSMaskBackdrop(maskData.data, r0, g0, b0);\n }\n\n composeFn(maskData.data, layerData.data, transferMap);\n layerCtx.putImageData(layerData, layerOffsetX, row + layerOffsetY);\n }\n}\n\nfunction composeSMask(ctx, smask, layerCtx, layerBox) {\n const layerOffsetX = layerBox[0];\n const layerOffsetY = layerBox[1];\n const layerWidth = layerBox[2] - layerOffsetX;\n const layerHeight = layerBox[3] - layerOffsetY;\n\n if (layerWidth === 0 || layerHeight === 0) {\n return;\n }\n\n genericComposeSMask(smask.context, layerCtx, layerWidth, layerHeight, smask.subtype, smask.backdrop, smask.transferMap, layerOffsetX, layerOffsetY, smask.offsetX, smask.offsetY);\n ctx.save();\n ctx.globalAlpha = 1;\n ctx.globalCompositeOperation = "source-over";\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.drawImage(layerCtx.canvas, 0, 0);\n ctx.restore();\n}\n\nfunction getImageSmoothingEnabled(transform, interpolate) {\n const scale = _util.Util.singularValueDecompose2dScale(transform);\n\n scale[0] = Math.fround(scale[0]);\n scale[1] = Math.fround(scale[1]);\n const actualScale = Math.fround((globalThis.devicePixelRatio || 1) * _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS);\n\n if (interpolate !== undefined) {\n return interpolate;\n } else if (scale[0] <= actualScale || scale[1] <= actualScale) {\n return true;\n }\n\n return false;\n}\n\nconst LINE_CAP_STYLES = ["butt", "round", "square"];\nconst LINE_JOIN_STYLES = ["miter", "round", "bevel"];\nconst NORMAL_CLIP = {};\nconst EO_CLIP = {};\n\nclass CanvasGraphics {\n constructor(canvasCtx, commonObjs, objs, canvasFactory, imageLayer, optionalContentConfig, annotationCanvasMap, pageColors) {\n this.ctx = canvasCtx;\n this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height);\n this.stateStack = [];\n this.pendingClip = null;\n this.pendingEOFill = false;\n this.res = null;\n this.xobjs = null;\n this.commonObjs = commonObjs;\n this.objs = objs;\n this.canvasFactory = canvasFactory;\n this.imageLayer = imageLayer;\n this.groupStack = [];\n this.processingType3 = null;\n this.baseTransform = null;\n this.baseTransformStack = [];\n this.groupLevel = 0;\n this.smaskStack = [];\n this.smaskCounter = 0;\n this.tempSMask = null;\n this.suspendedCtx = null;\n this.contentVisible = true;\n this.markedContentStack = [];\n this.optionalContentConfig = optionalContentConfig;\n this.cachedCanvases = new CachedCanvases(this.canvasFactory);\n this.cachedPatterns = new Map();\n this.annotationCanvasMap = annotationCanvasMap;\n this.viewportScale = 1;\n this.outputScaleX = 1;\n this.outputScaleY = 1;\n this.backgroundColor = pageColors?.background || null;\n this.foregroundColor = pageColors?.foreground || null;\n\n if (canvasCtx) {\n addContextCurrentTransform(canvasCtx);\n }\n\n this._cachedScaleForStroking = null;\n this._cachedGetSinglePixelWidth = null;\n this._cachedBitmapsMap = new Map();\n }\n\n getObject(data, fallback = null) {\n if (typeof data === "string") {\n return data.startsWith("g_") ? this.commonObjs.get(data) : this.objs.get(data);\n }\n\n return fallback;\n }\n\n beginDrawing({\n transform,\n viewport,\n transparency = false,\n background = null\n }) {\n const width = this.ctx.canvas.width;\n const height = this.ctx.canvas.height;\n const defaultBackgroundColor = background || "#ffffff";\n this.ctx.save();\n\n if (this.foregroundColor && this.backgroundColor) {\n this.ctx.fillStyle = this.foregroundColor;\n const fg = this.foregroundColor = this.ctx.fillStyle;\n this.ctx.fillStyle = this.backgroundColor;\n const bg = this.backgroundColor = this.ctx.fillStyle;\n let isValidDefaultBg = true;\n let defaultBg = defaultBackgroundColor;\n this.ctx.fillStyle = defaultBackgroundColor;\n defaultBg = this.ctx.fillStyle;\n isValidDefaultBg = typeof defaultBg === "string" && /^#[0-9A-Fa-f]{6}$/.test(defaultBg);\n\n if (fg === "#000000" && bg === "#ffffff" || fg === bg || !isValidDefaultBg) {\n this.foregroundColor = this.backgroundColor = null;\n } else {\n const cB = parseInt(defaultBg.slice(1), 16);\n const rB = (cB && 0xff0000) >> 16;\n const gB = (cB && 0x00ff00) >> 8;\n const bB = cB && 0x0000ff;\n\n const newComp = x => {\n x /= 255;\n return x <= 0.03928 ? x / 12.92 : ((x + 0.055) / 1.055) ** 2.4;\n };\n\n const lumB = Math.round(0.2126 * newComp(rB) + 0.7152 * newComp(gB) + 0.0722 * newComp(bB));\n\n this.selectColor = (r, g, b) => {\n const lumC = 0.2126 * newComp(r) + 0.7152 * newComp(g) + 0.0722 * newComp(b);\n return Math.round(lumC) === lumB ? bg : fg;\n };\n }\n }\n\n this.ctx.fillStyle = this.backgroundColor || defaultBackgroundColor;\n this.ctx.fillRect(0, 0, width, height);\n this.ctx.restore();\n\n if (transparency) {\n const transparentCanvas = this.cachedCanvases.getCanvas("transparent", width, height, true);\n this.compositeCtx = this.ctx;\n this.transparentCanvas = transparentCanvas.canvas;\n this.ctx = transparentCanvas.context;\n this.ctx.save();\n this.ctx.transform.apply(this.ctx, this.compositeCtx.mozCurrentTransform);\n }\n\n this.ctx.save();\n resetCtxToDefault(this.ctx, this.foregroundColor);\n\n if (transform) {\n this.ctx.transform.apply(this.ctx, transform);\n this.outputScaleX = transform[0];\n this.outputScaleY = transform[0];\n }\n\n this.ctx.transform.apply(this.ctx, viewport.transform);\n this.viewportScale = viewport.scale;\n this.baseTransform = this.ctx.mozCurrentTransform.slice();\n\n if (this.imageLayer) {\n this.imageLayer.beginLayout();\n }\n }\n\n executeOperatorList(operatorList, executionStartIdx, continueCallback, stepper) {\n const argsArray = operatorList.argsArray;\n const fnArray = operatorList.fnArray;\n let i = executionStartIdx || 0;\n const argsArrayLen = argsArray.length;\n\n if (argsArrayLen === i) {\n return i;\n }\n\n const chunkOperations = argsArrayLen - i > EXECUTION_STEPS && typeof continueCallback === "function";\n const endTime = chunkOperations ? Date.now() + EXECUTION_TIME : 0;\n let steps = 0;\n const commonObjs = this.commonObjs;\n const objs = this.objs;\n let fnId;\n\n while (true) {\n if (stepper !== undefined && i === stepper.nextBreakPoint) {\n stepper.breakIt(i, continueCallback);\n return i;\n }\n\n fnId = fnArray[i];\n\n if (fnId !== _util.OPS.dependency) {\n this[fnId].apply(this, argsArray[i]);\n } else {\n for (const depObjId of argsArray[i]) {\n const objsPool = depObjId.startsWith("g_") ? commonObjs : objs;\n\n if (!objsPool.has(depObjId)) {\n objsPool.get(depObjId, continueCallback);\n return i;\n }\n }\n }\n\n i++;\n\n if (i === argsArrayLen) {\n return i;\n }\n\n if (chunkOperations && ++steps > EXECUTION_STEPS) {\n if (Date.now() > endTime) {\n continueCallback();\n return i;\n }\n\n steps = 0;\n }\n }\n }\n\n endDrawing() {\n while (this.stateStack.length || this.inSMaskMode) {\n this.restore();\n }\n\n this.ctx.restore();\n\n if (this.transparentCanvas) {\n this.ctx = this.compositeCtx;\n this.ctx.save();\n this.ctx.setTransform(1, 0, 0, 1, 0, 0);\n this.ctx.drawImage(this.transparentCanvas, 0, 0);\n this.ctx.restore();\n this.transparentCanvas = null;\n }\n\n this.cachedCanvases.clear();\n this.cachedPatterns.clear();\n\n for (const cache of this._cachedBitmapsMap.values()) {\n for (const canvas of cache.values()) {\n if (typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement) {\n canvas.width = canvas.height = 0;\n }\n }\n\n cache.clear();\n }\n\n this._cachedBitmapsMap.clear();\n\n if (this.imageLayer) {\n this.imageLayer.endLayout();\n }\n }\n\n _scaleImage(img, inverseTransform) {\n const width = img.width;\n const height = img.height;\n let widthScale = Math.max(Math.hypot(inverseTransform[0], inverseTransform[1]), 1);\n let heightScale = Math.max(Math.hypot(inverseTransform[2], inverseTransform[3]), 1);\n let paintWidth = width,\n paintHeight = height;\n let tmpCanvasId = "prescale1";\n let tmpCanvas, tmpCtx;\n\n while (widthScale > 2 && paintWidth > 1 || heightScale > 2 && paintHeight > 1) {\n let newWidth = paintWidth,\n newHeight = paintHeight;\n\n if (widthScale > 2 && paintWidth > 1) {\n newWidth = Math.ceil(paintWidth / 2);\n widthScale /= paintWidth / newWidth;\n }\n\n if (heightScale > 2 && paintHeight > 1) {\n newHeight = Math.ceil(paintHeight / 2);\n heightScale /= paintHeight / newHeight;\n }\n\n tmpCanvas = this.cachedCanvases.getCanvas(tmpCanvasId, newWidth, newHeight, false);\n tmpCtx = tmpCanvas.context;\n tmpCtx.clearRect(0, 0, newWidth, newHeight);\n tmpCtx.drawImage(img, 0, 0, paintWidth, paintHeight, 0, 0, newWidth, newHeight);\n img = tmpCanvas.canvas;\n paintWidth = newWidth;\n paintHeight = newHeight;\n tmpCanvasId = tmpCanvasId === "prescale1" ? "prescale2" : "prescale1";\n }\n\n return {\n img,\n paintWidth,\n paintHeight\n };\n }\n\n _createMaskCanvas(img) {\n const ctx = this.ctx;\n const {\n width,\n height\n } = img;\n const fillColor = this.current.fillColor;\n const isPatternFill = this.current.patternFill;\n const currentTransform = ctx.mozCurrentTransform;\n let cache, cacheKey, scaled, maskCanvas;\n\n if ((img.bitmap || img.data) && img.count > 1) {\n const mainKey = img.bitmap || img.data.buffer;\n const withoutTranslation = currentTransform.slice(0, 4);\n cacheKey = JSON.stringify(isPatternFill ? withoutTranslation : [withoutTranslation, fillColor]);\n cache = this._cachedBitmapsMap.get(mainKey);\n\n if (!cache) {\n cache = new Map();\n\n this._cachedBitmapsMap.set(mainKey, cache);\n }\n\n const cachedImage = cache.get(cacheKey);\n\n if (cachedImage && !isPatternFill) {\n const offsetX = Math.round(Math.min(currentTransform[0], currentTransform[2]) + currentTransform[4]);\n const offsetY = Math.round(Math.min(currentTransform[1], currentTransform[3]) + currentTransform[5]);\n return {\n canvas: cachedImage,\n offsetX,\n offsetY\n };\n }\n\n scaled = cachedImage;\n }\n\n if (!scaled) {\n maskCanvas = this.cachedCanvases.getCanvas("maskCanvas", width, height, false);\n putBinaryImageMask(maskCanvas.context, img);\n }\n\n let maskToCanvas = _util.Util.transform(currentTransform, [1 / width, 0, 0, -1 / height, 0, 0]);\n\n maskToCanvas = _util.Util.transform(maskToCanvas, [1, 0, 0, 1, 0, -height]);\n\n const cord1 = _util.Util.applyTransform([0, 0], maskToCanvas);\n\n const cord2 = _util.Util.applyTransform([width, height], maskToCanvas);\n\n const rect = _util.Util.normalizeRect([cord1[0], cord1[1], cord2[0], cord2[1]]);\n\n const drawnWidth = Math.round(rect[2] - rect[0]) || 1;\n const drawnHeight = Math.round(rect[3] - rect[1]) || 1;\n const fillCanvas = this.cachedCanvases.getCanvas("fillCanvas", drawnWidth, drawnHeight, true);\n const fillCtx = fillCanvas.context;\n const offsetX = Math.min(cord1[0], cord2[0]);\n const offsetY = Math.min(cord1[1], cord2[1]);\n fillCtx.translate(-offsetX, -offsetY);\n fillCtx.transform.apply(fillCtx, maskToCanvas);\n\n if (!scaled) {\n scaled = this._scaleImage(maskCanvas.canvas, fillCtx.mozCurrentTransformInverse);\n scaled = scaled.img;\n\n if (cache && isPatternFill) {\n cache.set(cacheKey, scaled);\n }\n }\n\n fillCtx.imageSmoothingEnabled = getImageSmoothingEnabled(fillCtx.mozCurrentTransform, img.interpolate);\n drawImageAtIntegerCoords(fillCtx, scaled, 0, 0, scaled.width, scaled.height, 0, 0, width, height);\n fillCtx.globalCompositeOperation = "source-in";\n\n const inverse = _util.Util.transform(fillCtx.mozCurrentTransformInverse, [1, 0, 0, 1, -offsetX, -offsetY]);\n\n fillCtx.fillStyle = isPatternFill ? fillColor.getPattern(ctx, this, inverse, _pattern_helper.PathType.FILL) : fillColor;\n fillCtx.fillRect(0, 0, width, height);\n\n if (cache && !isPatternFill) {\n this.cachedCanvases.delete("fillCanvas");\n cache.set(cacheKey, fillCanvas.canvas);\n }\n\n return {\n canvas: fillCanvas.canvas,\n offsetX: Math.round(offsetX),\n offsetY: Math.round(offsetY)\n };\n }\n\n setLineWidth(width) {\n if (width !== this.current.lineWidth) {\n this._cachedScaleForStroking = null;\n }\n\n this.current.lineWidth = width;\n this.ctx.lineWidth = width;\n }\n\n setLineCap(style) {\n this.ctx.lineCap = LINE_CAP_STYLES[style];\n }\n\n setLineJoin(style) {\n this.ctx.lineJoin = LINE_JOIN_STYLES[style];\n }\n\n setMiterLimit(limit) {\n this.ctx.miterLimit = limit;\n }\n\n setDash(dashArray, dashPhase) {\n const ctx = this.ctx;\n\n if (ctx.setLineDash !== undefined) {\n ctx.setLineDash(dashArray);\n ctx.lineDashOffset = dashPhase;\n }\n }\n\n setRenderingIntent(intent) {}\n\n setFlatness(flatness) {}\n\n setGState(states) {\n for (let i = 0, ii = states.length; i < ii; i++) {\n const state = states[i];\n const key = state[0];\n const value = state[1];\n\n switch (key) {\n case "LW":\n this.setLineWidth(value);\n break;\n\n case "LC":\n this.setLineCap(value);\n break;\n\n case "LJ":\n this.setLineJoin(value);\n break;\n\n case "ML":\n this.setMiterLimit(value);\n break;\n\n case "D":\n this.setDash(value[0], value[1]);\n break;\n\n case "RI":\n this.setRenderingIntent(value);\n break;\n\n case "FL":\n this.setFlatness(value);\n break;\n\n case "Font":\n this.setFont(value[0], value[1]);\n break;\n\n case "CA":\n this.current.strokeAlpha = state[1];\n break;\n\n case "ca":\n this.current.fillAlpha = state[1];\n this.ctx.globalAlpha = state[1];\n break;\n\n case "BM":\n this.ctx.globalCompositeOperation = value;\n break;\n\n case "SMask":\n this.current.activeSMask = value ? this.tempSMask : null;\n this.tempSMask = null;\n this.checkSMaskState();\n break;\n\n case "TR":\n this.current.transferMaps = value;\n }\n }\n }\n\n get inSMaskMode() {\n return !!this.suspendedCtx;\n }\n\n checkSMaskState() {\n const inSMaskMode = this.inSMaskMode;\n\n if (this.current.activeSMask && !inSMaskMode) {\n this.beginSMaskMode();\n } else if (!this.current.activeSMask && inSMaskMode) {\n this.endSMaskMode();\n }\n }\n\n beginSMaskMode() {\n if (this.inSMaskMode) {\n throw new Error("beginSMaskMode called while already in smask mode");\n }\n\n const drawnWidth = this.ctx.canvas.width;\n const drawnHeight = this.ctx.canvas.height;\n const cacheId = "smaskGroupAt" + this.groupLevel;\n const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight, true);\n this.suspendedCtx = this.ctx;\n this.ctx = scratchCanvas.context;\n const ctx = this.ctx;\n ctx.setTransform.apply(ctx, this.suspendedCtx.mozCurrentTransform);\n copyCtxState(this.suspendedCtx, ctx);\n mirrorContextOperations(ctx, this.suspendedCtx);\n this.setGState([["BM", "source-over"], ["ca", 1], ["CA", 1]]);\n }\n\n endSMaskMode() {\n if (!this.inSMaskMode) {\n throw new Error("endSMaskMode called while not in smask mode");\n }\n\n this.ctx._removeMirroring();\n\n copyCtxState(this.ctx, this.suspendedCtx);\n this.ctx = this.suspendedCtx;\n this.suspendedCtx = null;\n }\n\n compose(dirtyBox) {\n if (!this.current.activeSMask) {\n return;\n }\n\n if (!dirtyBox) {\n dirtyBox = [0, 0, this.ctx.canvas.width, this.ctx.canvas.height];\n } else {\n dirtyBox[0] = Math.floor(dirtyBox[0]);\n dirtyBox[1] = Math.floor(dirtyBox[1]);\n dirtyBox[2] = Math.ceil(dirtyBox[2]);\n dirtyBox[3] = Math.ceil(dirtyBox[3]);\n }\n\n const smask = this.current.activeSMask;\n const suspendedCtx = this.suspendedCtx;\n composeSMask(suspendedCtx, smask, this.ctx, dirtyBox);\n this.ctx.save();\n this.ctx.setTransform(1, 0, 0, 1, 0, 0);\n this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);\n this.ctx.restore();\n }\n\n save() {\n if (this.inSMaskMode) {\n copyCtxState(this.ctx, this.suspendedCtx);\n this.suspendedCtx.save();\n } else {\n this.ctx.save();\n }\n\n const old = this.current;\n this.stateStack.push(old);\n this.current = old.clone();\n }\n\n restore() {\n if (this.stateStack.length === 0 && this.inSMaskMode) {\n this.endSMaskMode();\n }\n\n if (this.stateStack.length !== 0) {\n this.current = this.stateStack.pop();\n\n if (this.inSMaskMode) {\n this.suspendedCtx.restore();\n copyCtxState(this.suspendedCtx, this.ctx);\n } else {\n this.ctx.restore();\n }\n\n this.checkSMaskState();\n this.pendingClip = null;\n this._cachedScaleForStroking = null;\n this._cachedGetSinglePixelWidth = null;\n }\n }\n\n transform(a, b, c, d, e, f) {\n this.ctx.transform(a, b, c, d, e, f);\n this._cachedScaleForStroking = null;\n this._cachedGetSinglePixelWidth = null;\n }\n\n constructPath(ops, args, minMax) {\n const ctx = this.ctx;\n const current = this.current;\n let x = current.x,\n y = current.y;\n let startX, startY;\n const currentTransform = ctx.mozCurrentTransform;\n const isScalingMatrix = currentTransform[0] === 0 && currentTransform[3] === 0 || currentTransform[1] === 0 && currentTransform[2] === 0;\n const minMaxForBezier = isScalingMatrix ? minMax.slice(0) : null;\n\n for (let i = 0, j = 0, ii = ops.length; i < ii; i++) {\n switch (ops[i] | 0) {\n case _util.OPS.rectangle:\n x = args[j++];\n y = args[j++];\n const width = args[j++];\n const height = args[j++];\n const xw = x + width;\n const yh = y + height;\n ctx.moveTo(x, y);\n\n if (width === 0 || height === 0) {\n ctx.lineTo(xw, yh);\n } else {\n ctx.lineTo(xw, y);\n ctx.lineTo(xw, yh);\n ctx.lineTo(x, yh);\n }\n\n if (!isScalingMatrix) {\n current.updateRectMinMax(currentTransform, [x, y, xw, yh]);\n }\n\n ctx.closePath();\n break;\n\n case _util.OPS.moveTo:\n x = args[j++];\n y = args[j++];\n ctx.moveTo(x, y);\n\n if (!isScalingMatrix) {\n current.updatePathMinMax(currentTransform, x, y);\n }\n\n break;\n\n case _util.OPS.lineTo:\n x = args[j++];\n y = args[j++];\n ctx.lineTo(x, y);\n\n if (!isScalingMatrix) {\n current.updatePathMinMax(currentTransform, x, y);\n }\n\n break;\n\n case _util.OPS.curveTo:\n startX = x;\n startY = y;\n x = args[j + 4];\n y = args[j + 5];\n ctx.bezierCurveTo(args[j], args[j + 1], args[j + 2], args[j + 3], x, y);\n current.updateCurvePathMinMax(currentTransform, startX, startY, args[j], args[j + 1], args[j + 2], args[j + 3], x, y, minMaxForBezier);\n j += 6;\n break;\n\n case _util.OPS.curveTo2:\n startX = x;\n startY = y;\n ctx.bezierCurveTo(x, y, args[j], args[j + 1], args[j + 2], args[j + 3]);\n current.updateCurvePathMinMax(currentTransform, startX, startY, x, y, args[j], args[j + 1], args[j + 2], args[j + 3], minMaxForBezier);\n x = args[j + 2];\n y = args[j + 3];\n j += 4;\n break;\n\n case _util.OPS.curveTo3:\n startX = x;\n startY = y;\n x = args[j + 2];\n y = args[j + 3];\n ctx.bezierCurveTo(args[j], args[j + 1], x, y, x, y);\n current.updateCurvePathMinMax(currentTransform, startX, startY, args[j], args[j + 1], x, y, x, y, minMaxForBezier);\n j += 4;\n break;\n\n case _util.OPS.closePath:\n ctx.closePath();\n break;\n }\n }\n\n if (isScalingMatrix) {\n current.updateScalingPathMinMax(currentTransform, minMaxForBezier);\n }\n\n current.setCurrentPoint(x, y);\n }\n\n closePath() {\n this.ctx.closePath();\n }\n\n stroke(consumePath) {\n consumePath = typeof consumePath !== "undefined" ? consumePath : true;\n const ctx = this.ctx;\n const strokeColor = this.current.strokeColor;\n ctx.globalAlpha = this.current.strokeAlpha;\n\n if (this.contentVisible) {\n if (typeof strokeColor === "object" && strokeColor?.getPattern) {\n ctx.save();\n ctx.strokeStyle = strokeColor.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.STROKE);\n this.rescaleAndStroke(false);\n ctx.restore();\n } else {\n this.rescaleAndStroke(true);\n }\n }\n\n if (consumePath) {\n this.consumePath(this.current.getClippedPathBoundingBox());\n }\n\n ctx.globalAlpha = this.current.fillAlpha;\n }\n\n closeStroke() {\n this.closePath();\n this.stroke();\n }\n\n fill(consumePath) {\n consumePath = typeof consumePath !== "undefined" ? consumePath : true;\n const ctx = this.ctx;\n const fillColor = this.current.fillColor;\n const isPatternFill = this.current.patternFill;\n let needRestore = false;\n\n if (isPatternFill) {\n ctx.save();\n ctx.fillStyle = fillColor.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.FILL);\n needRestore = true;\n }\n\n const intersect = this.current.getClippedPathBoundingBox();\n\n if (this.contentVisible && intersect !== null) {\n if (this.pendingEOFill) {\n ctx.fill("evenodd");\n this.pendingEOFill = false;\n } else {\n ctx.fill();\n }\n }\n\n if (needRestore) {\n ctx.restore();\n }\n\n if (consumePath) {\n this.consumePath(intersect);\n }\n }\n\n eoFill() {\n this.pendingEOFill = true;\n this.fill();\n }\n\n fillStroke() {\n this.fill(false);\n this.stroke(false);\n this.consumePath();\n }\n\n eoFillStroke() {\n this.pendingEOFill = true;\n this.fillStroke();\n }\n\n closeFillStroke() {\n this.closePath();\n this.fillStroke();\n }\n\n closeEOFillStroke() {\n this.pendingEOFill = true;\n this.closePath();\n this.fillStroke();\n }\n\n endPath() {\n this.consumePath();\n }\n\n clip() {\n this.pendingClip = NORMAL_CLIP;\n }\n\n eoClip() {\n this.pendingClip = EO_CLIP;\n }\n\n beginText() {\n this.current.textMatrix = _util.IDENTITY_MATRIX;\n this.current.textMatrixScale = 1;\n this.current.x = this.current.lineX = 0;\n this.current.y = this.current.lineY = 0;\n }\n\n endText() {\n const paths = this.pendingTextPaths;\n const ctx = this.ctx;\n\n if (paths === undefined) {\n ctx.beginPath();\n return;\n }\n\n ctx.save();\n ctx.beginPath();\n\n for (let i = 0; i < paths.length; i++) {\n const path = paths[i];\n ctx.setTransform.apply(ctx, path.transform);\n ctx.translate(path.x, path.y);\n path.addToPath(ctx, path.fontSize);\n }\n\n ctx.restore();\n ctx.clip();\n ctx.beginPath();\n delete this.pendingTextPaths;\n }\n\n setCharSpacing(spacing) {\n this.current.charSpacing = spacing;\n }\n\n setWordSpacing(spacing) {\n this.current.wordSpacing = spacing;\n }\n\n setHScale(scale) {\n this.current.textHScale = scale / 100;\n }\n\n setLeading(leading) {\n this.current.leading = -leading;\n }\n\n setFont(fontRefName, size) {\n const fontObj = this.commonObjs.get(fontRefName);\n const current = this.current;\n\n if (!fontObj) {\n throw new Error(`Can\'t find font for ${fontRefName}`);\n }\n\n current.fontMatrix = fontObj.fontMatrix || _util.FONT_IDENTITY_MATRIX;\n\n if (current.fontMatrix[0] === 0 || current.fontMatrix[3] === 0) {\n (0, _util.warn)("Invalid font matrix for font " + fontRefName);\n }\n\n if (size < 0) {\n size = -size;\n current.fontDirection = -1;\n } else {\n current.fontDirection = 1;\n }\n\n this.current.font = fontObj;\n this.current.fontSize = size;\n\n if (fontObj.isType3Font) {\n return;\n }\n\n const name = fontObj.loadedName || "sans-serif";\n let bold = "normal";\n\n if (fontObj.black) {\n bold = "900";\n } else if (fontObj.bold) {\n bold = "bold";\n }\n\n const italic = fontObj.italic ? "italic" : "normal";\n const typeface = `"${name}", ${fontObj.fallbackName}`;\n let browserFontSize = size;\n\n if (size < MIN_FONT_SIZE) {\n browserFontSize = MIN_FONT_SIZE;\n } else if (size > MAX_FONT_SIZE) {\n browserFontSize = MAX_FONT_SIZE;\n }\n\n this.current.fontSizeScale = size / browserFontSize;\n this.ctx.font = `${italic} ${bold} ${browserFontSize}px ${typeface}`;\n }\n\n setTextRenderingMode(mode) {\n this.current.textRenderingMode = mode;\n }\n\n setTextRise(rise) {\n this.current.textRise = rise;\n }\n\n moveText(x, y) {\n this.current.x = this.current.lineX += x;\n this.current.y = this.current.lineY += y;\n }\n\n setLeadingMoveText(x, y) {\n this.setLeading(-y);\n this.moveText(x, y);\n }\n\n setTextMatrix(a, b, c, d, e, f) {\n this.current.textMatrix = [a, b, c, d, e, f];\n this.current.textMatrixScale = Math.hypot(a, b);\n this.current.x = this.current.lineX = 0;\n this.current.y = this.current.lineY = 0;\n }\n\n nextLine() {\n this.moveText(0, this.current.leading);\n }\n\n paintChar(character, x, y, patternTransform) {\n const ctx = this.ctx;\n const current = this.current;\n const font = current.font;\n const textRenderingMode = current.textRenderingMode;\n const fontSize = current.fontSize / current.fontSizeScale;\n const fillStrokeMode = textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK;\n const isAddToPathSet = !!(textRenderingMode & _util.TextRenderingMode.ADD_TO_PATH_FLAG);\n const patternFill = current.patternFill && !font.missingFile;\n let addToPath;\n\n if (font.disableFontFace || isAddToPathSet || patternFill) {\n addToPath = font.getPathGenerator(this.commonObjs, character);\n }\n\n if (font.disableFontFace || patternFill) {\n ctx.save();\n ctx.translate(x, y);\n ctx.beginPath();\n addToPath(ctx, fontSize);\n\n if (patternTransform) {\n ctx.setTransform.apply(ctx, patternTransform);\n }\n\n if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) {\n ctx.fill();\n }\n\n if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) {\n ctx.stroke();\n }\n\n ctx.restore();\n } else {\n if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) {\n ctx.fillText(character, x, y);\n }\n\n if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) {\n ctx.strokeText(character, x, y);\n }\n }\n\n if (isAddToPathSet) {\n const paths = this.pendingTextPaths || (this.pendingTextPaths = []);\n paths.push({\n transform: ctx.mozCurrentTransform,\n x,\n y,\n fontSize,\n addToPath\n });\n }\n }\n\n get isFontSubpixelAAEnabled() {\n const {\n context: ctx\n } = this.cachedCanvases.getCanvas("isFontSubpixelAAEnabled", 10, 10, false);\n ctx.scale(1.5, 1);\n ctx.fillText("I", 0, 10);\n const data = ctx.getImageData(0, 0, 10, 10).data;\n let enabled = false;\n\n for (let i = 3; i < data.length; i += 4) {\n if (data[i] > 0 && data[i] < 255) {\n enabled = true;\n break;\n }\n }\n\n return (0, _util.shadow)(this, "isFontSubpixelAAEnabled", enabled);\n }\n\n showText(glyphs) {\n const current = this.current;\n const font = current.font;\n\n if (font.isType3Font) {\n return this.showType3Text(glyphs);\n }\n\n const fontSize = current.fontSize;\n\n if (fontSize === 0) {\n return undefined;\n }\n\n const ctx = this.ctx;\n const fontSizeScale = current.fontSizeScale;\n const charSpacing = current.charSpacing;\n const wordSpacing = current.wordSpacing;\n const fontDirection = current.fontDirection;\n const textHScale = current.textHScale * fontDirection;\n const glyphsLength = glyphs.length;\n const vertical = font.vertical;\n const spacingDir = vertical ? 1 : -1;\n const defaultVMetrics = font.defaultVMetrics;\n const widthAdvanceScale = fontSize * current.fontMatrix[0];\n const simpleFillText = current.textRenderingMode === _util.TextRenderingMode.FILL && !font.disableFontFace && !current.patternFill;\n ctx.save();\n ctx.transform.apply(ctx, current.textMatrix);\n ctx.translate(current.x, current.y + current.textRise);\n\n if (fontDirection > 0) {\n ctx.scale(textHScale, -1);\n } else {\n ctx.scale(textHScale, 1);\n }\n\n let patternTransform;\n\n if (current.patternFill) {\n ctx.save();\n const pattern = current.fillColor.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.FILL);\n patternTransform = ctx.mozCurrentTransform;\n ctx.restore();\n ctx.fillStyle = pattern;\n }\n\n let lineWidth = current.lineWidth;\n const scale = current.textMatrixScale;\n\n if (scale === 0 || lineWidth === 0) {\n const fillStrokeMode = current.textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK;\n\n if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) {\n lineWidth = this.getSinglePixelWidth();\n }\n } else {\n lineWidth /= scale;\n }\n\n if (fontSizeScale !== 1.0) {\n ctx.scale(fontSizeScale, fontSizeScale);\n lineWidth /= fontSizeScale;\n }\n\n ctx.lineWidth = lineWidth;\n let x = 0,\n i;\n\n for (i = 0; i < glyphsLength; ++i) {\n const glyph = glyphs[i];\n\n if (typeof glyph === "number") {\n x += spacingDir * glyph * fontSize / 1000;\n continue;\n }\n\n let restoreNeeded = false;\n const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing;\n const character = glyph.fontChar;\n const accent = glyph.accent;\n let scaledX, scaledY;\n let width = glyph.width;\n\n if (vertical) {\n const vmetric = glyph.vmetric || defaultVMetrics;\n const vx = -(glyph.vmetric ? vmetric[1] : width * 0.5) * widthAdvanceScale;\n const vy = vmetric[2] * widthAdvanceScale;\n width = vmetric ? -vmetric[0] : width;\n scaledX = vx / fontSizeScale;\n scaledY = (x + vy) / fontSizeScale;\n } else {\n scaledX = x / fontSizeScale;\n scaledY = 0;\n }\n\n if (font.remeasure && width > 0) {\n const measuredWidth = ctx.measureText(character).width * 1000 / fontSize * fontSizeScale;\n\n if (width < measuredWidth && this.isFontSubpixelAAEnabled) {\n const characterScaleX = width / measuredWidth;\n restoreNeeded = true;\n ctx.save();\n ctx.scale(characterScaleX, 1);\n scaledX /= characterScaleX;\n } else if (width !== measuredWidth) {\n scaledX += (width - measuredWidth) / 2000 * fontSize / fontSizeScale;\n }\n }\n\n if (this.contentVisible && (glyph.isInFont || font.missingFile)) {\n if (simpleFillText && !accent) {\n ctx.fillText(character, scaledX, scaledY);\n } else {\n this.paintChar(character, scaledX, scaledY, patternTransform);\n\n if (accent) {\n const scaledAccentX = scaledX + fontSize * accent.offset.x / fontSizeScale;\n const scaledAccentY = scaledY - fontSize * accent.offset.y / fontSizeScale;\n this.paintChar(accent.fontChar, scaledAccentX, scaledAccentY, patternTransform);\n }\n }\n }\n\n let charWidth;\n\n if (vertical) {\n charWidth = width * widthAdvanceScale - spacing * fontDirection;\n } else {\n charWidth = width * widthAdvanceScale + spacing * fontDirection;\n }\n\n x += charWidth;\n\n if (restoreNeeded) {\n ctx.restore();\n }\n }\n\n if (vertical) {\n current.y -= x;\n } else {\n current.x += x * textHScale;\n }\n\n ctx.restore();\n this.compose();\n return undefined;\n }\n\n showType3Text(glyphs) {\n const ctx = this.ctx;\n const current = this.current;\n const font = current.font;\n const fontSize = current.fontSize;\n const fontDirection = current.fontDirection;\n const spacingDir = font.vertical ? 1 : -1;\n const charSpacing = current.charSpacing;\n const wordSpacing = current.wordSpacing;\n const textHScale = current.textHScale * fontDirection;\n const fontMatrix = current.fontMatrix || _util.FONT_IDENTITY_MATRIX;\n const glyphsLength = glyphs.length;\n const isTextInvisible = current.textRenderingMode === _util.TextRenderingMode.INVISIBLE;\n let i, glyph, width, spacingLength;\n\n if (isTextInvisible || fontSize === 0) {\n return;\n }\n\n this._cachedScaleForStroking = null;\n this._cachedGetSinglePixelWidth = null;\n ctx.save();\n ctx.transform.apply(ctx, current.textMatrix);\n ctx.translate(current.x, current.y);\n ctx.scale(textHScale, fontDirection);\n\n for (i = 0; i < glyphsLength; ++i) {\n glyph = glyphs[i];\n\n if (typeof glyph === "number") {\n spacingLength = spacingDir * glyph * fontSize / 1000;\n this.ctx.translate(spacingLength, 0);\n current.x += spacingLength * textHScale;\n continue;\n }\n\n const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing;\n const operatorList = font.charProcOperatorList[glyph.operatorListId];\n\n if (!operatorList) {\n (0, _util.warn)(`Type3 character "${glyph.operatorListId}" is not available.`);\n continue;\n }\n\n if (this.contentVisible) {\n this.processingType3 = glyph;\n this.save();\n ctx.scale(fontSize, fontSize);\n ctx.transform.apply(ctx, fontMatrix);\n this.executeOperatorList(operatorList);\n this.restore();\n }\n\n const transformed = _util.Util.applyTransform([glyph.width, 0], fontMatrix);\n\n width = transformed[0] * fontSize + spacing;\n ctx.translate(width, 0);\n current.x += width * textHScale;\n }\n\n ctx.restore();\n this.processingType3 = null;\n }\n\n setCharWidth(xWidth, yWidth) {}\n\n setCharWidthAndBounds(xWidth, yWidth, llx, lly, urx, ury) {\n this.ctx.rect(llx, lly, urx - llx, ury - lly);\n this.ctx.clip();\n this.endPath();\n }\n\n getColorN_Pattern(IR) {\n let pattern;\n\n if (IR[0] === "TilingPattern") {\n const color = IR[1];\n const baseTransform = this.baseTransform || this.ctx.mozCurrentTransform.slice();\n const canvasGraphicsFactory = {\n createCanvasGraphics: ctx => {\n return new CanvasGraphics(ctx, this.commonObjs, this.objs, this.canvasFactory);\n }\n };\n pattern = new _pattern_helper.TilingPattern(IR, color, this.ctx, canvasGraphicsFactory, baseTransform);\n } else {\n pattern = this._getPattern(IR[1], IR[2]);\n }\n\n return pattern;\n }\n\n setStrokeColorN() {\n this.current.strokeColor = this.getColorN_Pattern(arguments);\n }\n\n setFillColorN() {\n this.current.fillColor = this.getColorN_Pattern(arguments);\n this.current.patternFill = true;\n }\n\n setStrokeRGBColor(r, g, b) {\n const color = this.selectColor?.(r, g, b) || _util.Util.makeHexColor(r, g, b);\n\n this.ctx.strokeStyle = color;\n this.current.strokeColor = color;\n }\n\n setFillRGBColor(r, g, b) {\n const color = this.selectColor?.(r, g, b) || _util.Util.makeHexColor(r, g, b);\n\n this.ctx.fillStyle = color;\n this.current.fillColor = color;\n this.current.patternFill = false;\n }\n\n _getPattern(objId, matrix = null) {\n let pattern;\n\n if (this.cachedPatterns.has(objId)) {\n pattern = this.cachedPatterns.get(objId);\n } else {\n pattern = (0, _pattern_helper.getShadingPattern)(this.objs.get(objId));\n this.cachedPatterns.set(objId, pattern);\n }\n\n if (matrix) {\n pattern.matrix = matrix;\n }\n\n return pattern;\n }\n\n shadingFill(objId) {\n if (!this.contentVisible) {\n return;\n }\n\n const ctx = this.ctx;\n this.save();\n\n const pattern = this._getPattern(objId);\n\n ctx.fillStyle = pattern.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.SHADING);\n const inv = ctx.mozCurrentTransformInverse;\n\n if (inv) {\n const canvas = ctx.canvas;\n const width = canvas.width;\n const height = canvas.height;\n\n const bl = _util.Util.applyTransform([0, 0], inv);\n\n const br = _util.Util.applyTransform([0, height], inv);\n\n const ul = _util.Util.applyTransform([width, 0], inv);\n\n const ur = _util.Util.applyTransform([width, height], inv);\n\n const x0 = Math.min(bl[0], br[0], ul[0], ur[0]);\n const y0 = Math.min(bl[1], br[1], ul[1], ur[1]);\n const x1 = Math.max(bl[0], br[0], ul[0], ur[0]);\n const y1 = Math.max(bl[1], br[1], ul[1], ur[1]);\n this.ctx.fillRect(x0, y0, x1 - x0, y1 - y0);\n } else {\n this.ctx.fillRect(-1e10, -1e10, 2e10, 2e10);\n }\n\n this.compose(this.current.getClippedPathBoundingBox());\n this.restore();\n }\n\n beginInlineImage() {\n (0, _util.unreachable)("Should not call beginInlineImage");\n }\n\n beginImageData() {\n (0, _util.unreachable)("Should not call beginImageData");\n }\n\n paintFormXObjectBegin(matrix, bbox) {\n if (!this.contentVisible) {\n return;\n }\n\n this.save();\n this.baseTransformStack.push(this.baseTransform);\n\n if (Array.isArray(matrix) && matrix.length === 6) {\n this.transform.apply(this, matrix);\n }\n\n this.baseTransform = this.ctx.mozCurrentTransform;\n\n if (bbox) {\n const width = bbox[2] - bbox[0];\n const height = bbox[3] - bbox[1];\n this.ctx.rect(bbox[0], bbox[1], width, height);\n this.current.updateRectMinMax(this.ctx.mozCurrentTransform, bbox);\n this.clip();\n this.endPath();\n }\n }\n\n paintFormXObjectEnd() {\n if (!this.contentVisible) {\n return;\n }\n\n this.restore();\n this.baseTransform = this.baseTransformStack.pop();\n }\n\n beginGroup(group) {\n if (!this.contentVisible) {\n return;\n }\n\n this.save();\n\n if (this.inSMaskMode) {\n this.endSMaskMode();\n this.current.activeSMask = null;\n }\n\n const currentCtx = this.ctx;\n\n if (!group.isolated) {\n (0, _util.info)("TODO: Support non-isolated groups.");\n }\n\n if (group.knockout) {\n (0, _util.warn)("Knockout groups not supported.");\n }\n\n const currentTransform = currentCtx.mozCurrentTransform;\n\n if (group.matrix) {\n currentCtx.transform.apply(currentCtx, group.matrix);\n }\n\n if (!group.bbox) {\n throw new Error("Bounding box is required.");\n }\n\n let bounds = _util.Util.getAxialAlignedBoundingBox(group.bbox, currentCtx.mozCurrentTransform);\n\n const canvasBounds = [0, 0, currentCtx.canvas.width, currentCtx.canvas.height];\n bounds = _util.Util.intersect(bounds, canvasBounds) || [0, 0, 0, 0];\n const offsetX = Math.floor(bounds[0]);\n const offsetY = Math.floor(bounds[1]);\n let drawnWidth = Math.max(Math.ceil(bounds[2]) - offsetX, 1);\n let drawnHeight = Math.max(Math.ceil(bounds[3]) - offsetY, 1);\n let scaleX = 1,\n scaleY = 1;\n\n if (drawnWidth > MAX_GROUP_SIZE) {\n scaleX = drawnWidth / MAX_GROUP_SIZE;\n drawnWidth = MAX_GROUP_SIZE;\n }\n\n if (drawnHeight > MAX_GROUP_SIZE) {\n scaleY = drawnHeight / MAX_GROUP_SIZE;\n drawnHeight = MAX_GROUP_SIZE;\n }\n\n this.current.startNewPathAndClipBox([0, 0, drawnWidth, drawnHeight]);\n let cacheId = "groupAt" + this.groupLevel;\n\n if (group.smask) {\n cacheId += "_smask_" + this.smaskCounter++ % 2;\n }\n\n const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight, true);\n const groupCtx = scratchCanvas.context;\n groupCtx.scale(1 / scaleX, 1 / scaleY);\n groupCtx.translate(-offsetX, -offsetY);\n groupCtx.transform.apply(groupCtx, currentTransform);\n\n if (group.smask) {\n this.smaskStack.push({\n canvas: scratchCanvas.canvas,\n context: groupCtx,\n offsetX,\n offsetY,\n scaleX,\n scaleY,\n subtype: group.smask.subtype,\n backdrop: group.smask.backdrop,\n transferMap: group.smask.transferMap || null,\n startTransformInverse: null\n });\n } else {\n currentCtx.setTransform(1, 0, 0, 1, 0, 0);\n currentCtx.translate(offsetX, offsetY);\n currentCtx.scale(scaleX, scaleY);\n currentCtx.save();\n }\n\n copyCtxState(currentCtx, groupCtx);\n this.ctx = groupCtx;\n this.setGState([["BM", "source-over"], ["ca", 1], ["CA", 1]]);\n this.groupStack.push(currentCtx);\n this.groupLevel++;\n }\n\n endGroup(group) {\n if (!this.contentVisible) {\n return;\n }\n\n this.groupLevel--;\n const groupCtx = this.ctx;\n const ctx = this.groupStack.pop();\n this.ctx = ctx;\n this.ctx.imageSmoothingEnabled = false;\n\n if (group.smask) {\n this.tempSMask = this.smaskStack.pop();\n this.restore();\n } else {\n this.ctx.restore();\n const currentMtx = this.ctx.mozCurrentTransform;\n this.restore();\n this.ctx.save();\n this.ctx.setTransform.apply(this.ctx, currentMtx);\n\n const dirtyBox = _util.Util.getAxialAlignedBoundingBox([0, 0, groupCtx.canvas.width, groupCtx.canvas.height], currentMtx);\n\n this.ctx.drawImage(groupCtx.canvas, 0, 0);\n this.ctx.restore();\n this.compose(dirtyBox);\n }\n }\n\n beginAnnotations() {\n this.save();\n\n if (this.baseTransform) {\n this.ctx.setTransform.apply(this.ctx, this.baseTransform);\n }\n }\n\n endAnnotations() {\n this.restore();\n }\n\n beginAnnotation(id, rect, transform, matrix, hasOwnCanvas) {\n this.save();\n\n if (Array.isArray(rect) && rect.length === 4) {\n const width = rect[2] - rect[0];\n const height = rect[3] - rect[1];\n\n if (hasOwnCanvas && this.annotationCanvasMap) {\n transform = transform.slice();\n transform[4] -= rect[0];\n transform[5] -= rect[1];\n rect = rect.slice();\n rect[0] = rect[1] = 0;\n rect[2] = width;\n rect[3] = height;\n\n const [scaleX, scaleY] = _util.Util.singularValueDecompose2dScale(this.ctx.mozCurrentTransform);\n\n const {\n viewportScale\n } = this;\n const canvasWidth = Math.ceil(width * this.outputScaleX * viewportScale);\n const canvasHeight = Math.ceil(height * this.outputScaleY * viewportScale);\n this.annotationCanvas = this.canvasFactory.create(canvasWidth, canvasHeight);\n const {\n canvas,\n context\n } = this.annotationCanvas;\n const viewportScaleFactorStr = `var(--zoom-factor) * ${_display_utils.PixelsPerInch.PDF_TO_CSS_UNITS}`;\n canvas.style.width = `calc(${width}px * ${viewportScaleFactorStr})`;\n canvas.style.height = `calc(${height}px * ${viewportScaleFactorStr})`;\n this.annotationCanvasMap.set(id, canvas);\n this.annotationCanvas.savedCtx = this.ctx;\n this.ctx = context;\n this.ctx.setTransform(scaleX, 0, 0, -scaleY, 0, height * scaleY);\n addContextCurrentTransform(this.ctx);\n resetCtxToDefault(this.ctx, this.foregroundColor);\n } else {\n resetCtxToDefault(this.ctx, this.foregroundColor);\n this.ctx.rect(rect[0], rect[1], width, height);\n this.ctx.clip();\n this.endPath();\n }\n }\n\n this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height);\n this.transform.apply(this, transform);\n this.transform.apply(this, matrix);\n }\n\n endAnnotation() {\n if (this.annotationCanvas) {\n this.ctx = this.annotationCanvas.savedCtx;\n delete this.annotationCanvas.savedCtx;\n delete this.annotationCanvas;\n }\n\n this.restore();\n }\n\n paintImageMaskXObject(img) {\n if (!this.contentVisible) {\n return;\n }\n\n const count = img.count;\n img = this.getObject(img.data, img);\n img.count = count;\n const ctx = this.ctx;\n const glyph = this.processingType3;\n\n if (glyph) {\n if (glyph.compiled === undefined) {\n glyph.compiled = compileType3Glyph(img);\n }\n\n if (glyph.compiled) {\n glyph.compiled(ctx);\n return;\n }\n }\n\n const mask = this._createMaskCanvas(img);\n\n const maskCanvas = mask.canvas;\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.drawImage(maskCanvas, mask.offsetX, mask.offsetY);\n ctx.restore();\n this.compose();\n }\n\n paintImageMaskXObjectRepeat(img, scaleX, skewX = 0, skewY = 0, scaleY, positions) {\n if (!this.contentVisible) {\n return;\n }\n\n img = this.getObject(img.data, img);\n const ctx = this.ctx;\n ctx.save();\n const currentTransform = ctx.mozCurrentTransform;\n ctx.transform(scaleX, skewX, skewY, scaleY, 0, 0);\n\n const mask = this._createMaskCanvas(img);\n\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n\n for (let i = 0, ii = positions.length; i < ii; i += 2) {\n const trans = _util.Util.transform(currentTransform, [scaleX, skewX, skewY, scaleY, positions[i], positions[i + 1]]);\n\n const [x, y] = _util.Util.applyTransform([0, 0], trans);\n\n ctx.drawImage(mask.canvas, x, y);\n }\n\n ctx.restore();\n this.compose();\n }\n\n paintImageMaskXObjectGroup(images) {\n if (!this.contentVisible) {\n return;\n }\n\n const ctx = this.ctx;\n const fillColor = this.current.fillColor;\n const isPatternFill = this.current.patternFill;\n\n for (let i = 0, ii = images.length; i < ii; i++) {\n const image = images[i];\n const width = image.width,\n height = image.height;\n const maskCanvas = this.cachedCanvases.getCanvas("maskCanvas", width, height, false);\n const maskCtx = maskCanvas.context;\n maskCtx.save();\n putBinaryImageMask(maskCtx, image);\n maskCtx.globalCompositeOperation = "source-in";\n maskCtx.fillStyle = isPatternFill ? fillColor.getPattern(maskCtx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.FILL) : fillColor;\n maskCtx.fillRect(0, 0, width, height);\n maskCtx.restore();\n ctx.save();\n ctx.transform.apply(ctx, image.transform);\n ctx.scale(1, -1);\n drawImageAtIntegerCoords(ctx, maskCanvas.canvas, 0, 0, width, height, 0, -1, 1, 1);\n ctx.restore();\n }\n\n this.compose();\n }\n\n paintImageXObject(objId) {\n if (!this.contentVisible) {\n return;\n }\n\n const imgData = this.getObject(objId);\n\n if (!imgData) {\n (0, _util.warn)("Dependent image isn\'t ready yet");\n return;\n }\n\n this.paintInlineImageXObject(imgData);\n }\n\n paintImageXObjectRepeat(objId, scaleX, scaleY, positions) {\n if (!this.contentVisible) {\n return;\n }\n\n const imgData = this.getObject(objId);\n\n if (!imgData) {\n (0, _util.warn)("Dependent image isn\'t ready yet");\n return;\n }\n\n const width = imgData.width;\n const height = imgData.height;\n const map = [];\n\n for (let i = 0, ii = positions.length; i < ii; i += 2) {\n map.push({\n transform: [scaleX, 0, 0, scaleY, positions[i], positions[i + 1]],\n x: 0,\n y: 0,\n w: width,\n h: height\n });\n }\n\n this.paintInlineImageXObjectGroup(imgData, map);\n }\n\n paintInlineImageXObject(imgData) {\n if (!this.contentVisible) {\n return;\n }\n\n const width = imgData.width;\n const height = imgData.height;\n const ctx = this.ctx;\n this.save();\n ctx.scale(1 / width, -1 / height);\n let imgToPaint;\n\n if (typeof HTMLElement === "function" && imgData instanceof HTMLElement || !imgData.data) {\n imgToPaint = imgData;\n } else {\n const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", width, height, false);\n const tmpCtx = tmpCanvas.context;\n putBinaryImageData(tmpCtx, imgData, this.current.transferMaps);\n imgToPaint = tmpCanvas.canvas;\n }\n\n const scaled = this._scaleImage(imgToPaint, ctx.mozCurrentTransformInverse);\n\n ctx.imageSmoothingEnabled = getImageSmoothingEnabled(ctx.mozCurrentTransform, imgData.interpolate);\n const [rWidth, rHeight] = drawImageAtIntegerCoords(ctx, scaled.img, 0, 0, scaled.paintWidth, scaled.paintHeight, 0, -height, width, height);\n\n if (this.imageLayer) {\n const position = this.getCanvasPosition(0, -height);\n this.imageLayer.appendImage({\n imgData,\n left: position[0],\n top: position[1],\n width: rWidth,\n height: rHeight\n });\n }\n\n this.compose();\n this.restore();\n }\n\n paintInlineImageXObjectGroup(imgData, map) {\n if (!this.contentVisible) {\n return;\n }\n\n const ctx = this.ctx;\n const w = imgData.width;\n const h = imgData.height;\n const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", w, h, false);\n const tmpCtx = tmpCanvas.context;\n putBinaryImageData(tmpCtx, imgData, this.current.transferMaps);\n\n for (let i = 0, ii = map.length; i < ii; i++) {\n const entry = map[i];\n ctx.save();\n ctx.transform.apply(ctx, entry.transform);\n ctx.scale(1, -1);\n drawImageAtIntegerCoords(ctx, tmpCanvas.canvas, entry.x, entry.y, entry.w, entry.h, 0, -1, 1, 1);\n\n if (this.imageLayer) {\n const position = this.getCanvasPosition(entry.x, entry.y);\n this.imageLayer.appendImage({\n imgData,\n left: position[0],\n top: position[1],\n width: w,\n height: h\n });\n }\n\n ctx.restore();\n }\n\n this.compose();\n }\n\n paintSolidColorImageMask() {\n if (!this.contentVisible) {\n return;\n }\n\n this.ctx.fillRect(0, 0, 1, 1);\n this.compose();\n }\n\n markPoint(tag) {}\n\n markPointProps(tag, properties) {}\n\n beginMarkedContent(tag) {\n this.markedContentStack.push({\n visible: true\n });\n }\n\n beginMarkedContentProps(tag, properties) {\n if (tag === "OC") {\n this.markedContentStack.push({\n visible: this.optionalContentConfig.isVisible(properties)\n });\n } else {\n this.markedContentStack.push({\n visible: true\n });\n }\n\n this.contentVisible = this.isContentVisible();\n }\n\n endMarkedContent() {\n this.markedContentStack.pop();\n this.contentVisible = this.isContentVisible();\n }\n\n beginCompat() {}\n\n endCompat() {}\n\n consumePath(clipBox) {\n const isEmpty = this.current.isEmptyClip();\n\n if (this.pendingClip) {\n this.current.updateClipFromPath();\n }\n\n if (!this.pendingClip) {\n this.compose(clipBox);\n }\n\n const ctx = this.ctx;\n\n if (this.pendingClip) {\n if (!isEmpty) {\n if (this.pendingClip === EO_CLIP) {\n ctx.clip("evenodd");\n } else {\n ctx.clip();\n }\n }\n\n this.pendingClip = null;\n }\n\n this.current.startNewPathAndClipBox(this.current.clipBox);\n ctx.beginPath();\n }\n\n getSinglePixelWidth() {\n if (!this._cachedGetSinglePixelWidth) {\n const m = this.ctx.mozCurrentTransform;\n\n if (m[1] === 0 && m[2] === 0) {\n this._cachedGetSinglePixelWidth = 1 / Math.min(Math.abs(m[0]), Math.abs(m[3]));\n } else {\n const absDet = Math.abs(m[0] * m[3] - m[2] * m[1]);\n const normX = Math.hypot(m[0], m[2]);\n const normY = Math.hypot(m[1], m[3]);\n this._cachedGetSinglePixelWidth = Math.max(normX, normY) / absDet;\n }\n }\n\n return this._cachedGetSinglePixelWidth;\n }\n\n getScaleForStroking() {\n if (!this._cachedScaleForStroking) {\n const {\n lineWidth\n } = this.current;\n const m = this.ctx.mozCurrentTransform;\n let scaleX, scaleY;\n\n if (m[1] === 0 && m[2] === 0) {\n const normX = Math.abs(m[0]);\n const normY = Math.abs(m[3]);\n\n if (lineWidth === 0) {\n scaleX = 1 / normX;\n scaleY = 1 / normY;\n } else {\n const scaledXLineWidth = normX * lineWidth;\n const scaledYLineWidth = normY * lineWidth;\n scaleX = scaledXLineWidth < 1 ? 1 / scaledXLineWidth : 1;\n scaleY = scaledYLineWidth < 1 ? 1 / scaledYLineWidth : 1;\n }\n } else {\n const absDet = Math.abs(m[0] * m[3] - m[2] * m[1]);\n const normX = Math.hypot(m[0], m[1]);\n const normY = Math.hypot(m[2], m[3]);\n\n if (lineWidth === 0) {\n scaleX = normY / absDet;\n scaleY = normX / absDet;\n } else {\n const baseArea = lineWidth * absDet;\n scaleX = normY > baseArea ? normY / baseArea : 1;\n scaleY = normX > baseArea ? normX / baseArea : 1;\n }\n }\n\n this._cachedScaleForStroking = [scaleX, scaleY];\n }\n\n return this._cachedScaleForStroking;\n }\n\n rescaleAndStroke(saveRestore) {\n const {\n ctx\n } = this;\n const {\n lineWidth\n } = this.current;\n const [scaleX, scaleY] = this.getScaleForStroking();\n ctx.lineWidth = lineWidth || 1;\n\n if (scaleX === 1 && scaleY === 1) {\n ctx.stroke();\n return;\n }\n\n let savedMatrix, savedDashes, savedDashOffset;\n\n if (saveRestore) {\n savedMatrix = ctx.mozCurrentTransform.slice();\n savedDashes = ctx.getLineDash().slice();\n savedDashOffset = ctx.lineDashOffset;\n }\n\n ctx.scale(scaleX, scaleY);\n const scale = Math.max(scaleX, scaleY);\n ctx.setLineDash(ctx.getLineDash().map(x => x / scale));\n ctx.lineDashOffset /= scale;\n ctx.stroke();\n\n if (saveRestore) {\n ctx.setTransform(...savedMatrix);\n ctx.setLineDash(savedDashes);\n ctx.lineDashOffset = savedDashOffset;\n }\n }\n\n getCanvasPosition(x, y) {\n const transform = this.ctx.mozCurrentTransform;\n return [transform[0] * x + transform[2] * y + transform[4], transform[1] * x + transform[3] * y + transform[5]];\n }\n\n isContentVisible() {\n for (let i = this.markedContentStack.length - 1; i >= 0; i--) {\n if (!this.markedContentStack[i].visible) {\n return false;\n }\n }\n\n return true;\n }\n\n}\n\nexports.CanvasGraphics = CanvasGraphics;\n\nfor (const op in _util.OPS) {\n if (CanvasGraphics.prototype[op] !== undefined) {\n CanvasGraphics.prototype[_util.OPS[op]] = CanvasGraphics.prototype[op];\n }\n}\n\n/***/ }),\n/* 11 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.TilingPattern = exports.PathType = void 0;\nexports.getShadingPattern = getShadingPattern;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _is_node = __w_pdfjs_require__(3);\n\nconst PathType = {\n FILL: "Fill",\n STROKE: "Stroke",\n SHADING: "Shading"\n};\nexports.PathType = PathType;\n\nfunction applyBoundingBox(ctx, bbox) {\n if (!bbox || _is_node.isNodeJS) {\n return;\n }\n\n const width = bbox[2] - bbox[0];\n const height = bbox[3] - bbox[1];\n const region = new Path2D();\n region.rect(bbox[0], bbox[1], width, height);\n ctx.clip(region);\n}\n\nclass BaseShadingPattern {\n constructor() {\n if (this.constructor === BaseShadingPattern) {\n (0, _util.unreachable)("Cannot initialize BaseShadingPattern.");\n }\n }\n\n getPattern() {\n (0, _util.unreachable)("Abstract method `getPattern` called.");\n }\n\n}\n\nclass RadialAxialShadingPattern extends BaseShadingPattern {\n constructor(IR) {\n super();\n this._type = IR[1];\n this._bbox = IR[2];\n this._colorStops = IR[3];\n this._p0 = IR[4];\n this._p1 = IR[5];\n this._r0 = IR[6];\n this._r1 = IR[7];\n this.matrix = null;\n }\n\n _createGradient(ctx) {\n let grad;\n\n if (this._type === "axial") {\n grad = ctx.createLinearGradient(this._p0[0], this._p0[1], this._p1[0], this._p1[1]);\n } else if (this._type === "radial") {\n grad = ctx.createRadialGradient(this._p0[0], this._p0[1], this._r0, this._p1[0], this._p1[1], this._r1);\n }\n\n for (const colorStop of this._colorStops) {\n grad.addColorStop(colorStop[0], colorStop[1]);\n }\n\n return grad;\n }\n\n getPattern(ctx, owner, inverse, pathType) {\n let pattern;\n\n if (pathType === PathType.STROKE || pathType === PathType.FILL) {\n const ownerBBox = owner.current.getClippedPathBoundingBox(pathType, ctx.mozCurrentTransform) || [0, 0, 0, 0];\n const width = Math.ceil(ownerBBox[2] - ownerBBox[0]) || 1;\n const height = Math.ceil(ownerBBox[3] - ownerBBox[1]) || 1;\n const tmpCanvas = owner.cachedCanvases.getCanvas("pattern", width, height, true);\n const tmpCtx = tmpCanvas.context;\n tmpCtx.clearRect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height);\n tmpCtx.beginPath();\n tmpCtx.rect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height);\n tmpCtx.translate(-ownerBBox[0], -ownerBBox[1]);\n inverse = _util.Util.transform(inverse, [1, 0, 0, 1, ownerBBox[0], ownerBBox[1]]);\n tmpCtx.transform.apply(tmpCtx, owner.baseTransform);\n\n if (this.matrix) {\n tmpCtx.transform.apply(tmpCtx, this.matrix);\n }\n\n applyBoundingBox(tmpCtx, this._bbox);\n tmpCtx.fillStyle = this._createGradient(tmpCtx);\n tmpCtx.fill();\n pattern = ctx.createPattern(tmpCanvas.canvas, "no-repeat");\n const domMatrix = new DOMMatrix(inverse);\n\n try {\n pattern.setTransform(domMatrix);\n } catch (ex) {\n (0, _util.warn)(`RadialAxialShadingPattern.getPattern: "${ex?.message}".`);\n }\n } else {\n applyBoundingBox(ctx, this._bbox);\n pattern = this._createGradient(ctx);\n }\n\n return pattern;\n }\n\n}\n\nfunction drawTriangle(data, context, p1, p2, p3, c1, c2, c3) {\n const coords = context.coords,\n colors = context.colors;\n const bytes = data.data,\n rowSize = data.width * 4;\n let tmp;\n\n if (coords[p1 + 1] > coords[p2 + 1]) {\n tmp = p1;\n p1 = p2;\n p2 = tmp;\n tmp = c1;\n c1 = c2;\n c2 = tmp;\n }\n\n if (coords[p2 + 1] > coords[p3 + 1]) {\n tmp = p2;\n p2 = p3;\n p3 = tmp;\n tmp = c2;\n c2 = c3;\n c3 = tmp;\n }\n\n if (coords[p1 + 1] > coords[p2 + 1]) {\n tmp = p1;\n p1 = p2;\n p2 = tmp;\n tmp = c1;\n c1 = c2;\n c2 = tmp;\n }\n\n const x1 = (coords[p1] + context.offsetX) * context.scaleX;\n const y1 = (coords[p1 + 1] + context.offsetY) * context.scaleY;\n const x2 = (coords[p2] + context.offsetX) * context.scaleX;\n const y2 = (coords[p2 + 1] + context.offsetY) * context.scaleY;\n const x3 = (coords[p3] + context.offsetX) * context.scaleX;\n const y3 = (coords[p3 + 1] + context.offsetY) * context.scaleY;\n\n if (y1 >= y3) {\n return;\n }\n\n const c1r = colors[c1],\n c1g = colors[c1 + 1],\n c1b = colors[c1 + 2];\n const c2r = colors[c2],\n c2g = colors[c2 + 1],\n c2b = colors[c2 + 2];\n const c3r = colors[c3],\n c3g = colors[c3 + 1],\n c3b = colors[c3 + 2];\n const minY = Math.round(y1),\n maxY = Math.round(y3);\n let xa, car, cag, cab;\n let xb, cbr, cbg, cbb;\n\n for (let y = minY; y <= maxY; y++) {\n if (y < y2) {\n let k;\n\n if (y < y1) {\n k = 0;\n } else {\n k = (y1 - y) / (y1 - y2);\n }\n\n xa = x1 - (x1 - x2) * k;\n car = c1r - (c1r - c2r) * k;\n cag = c1g - (c1g - c2g) * k;\n cab = c1b - (c1b - c2b) * k;\n } else {\n let k;\n\n if (y > y3) {\n k = 1;\n } else if (y2 === y3) {\n k = 0;\n } else {\n k = (y2 - y) / (y2 - y3);\n }\n\n xa = x2 - (x2 - x3) * k;\n car = c2r - (c2r - c3r) * k;\n cag = c2g - (c2g - c3g) * k;\n cab = c2b - (c2b - c3b) * k;\n }\n\n let k;\n\n if (y < y1) {\n k = 0;\n } else if (y > y3) {\n k = 1;\n } else {\n k = (y1 - y) / (y1 - y3);\n }\n\n xb = x1 - (x1 - x3) * k;\n cbr = c1r - (c1r - c3r) * k;\n cbg = c1g - (c1g - c3g) * k;\n cbb = c1b - (c1b - c3b) * k;\n const x1_ = Math.round(Math.min(xa, xb));\n const x2_ = Math.round(Math.max(xa, xb));\n let j = rowSize * y + x1_ * 4;\n\n for (let x = x1_; x <= x2_; x++) {\n k = (xa - x) / (xa - xb);\n\n if (k < 0) {\n k = 0;\n } else if (k > 1) {\n k = 1;\n }\n\n bytes[j++] = car - (car - cbr) * k | 0;\n bytes[j++] = cag - (cag - cbg) * k | 0;\n bytes[j++] = cab - (cab - cbb) * k | 0;\n bytes[j++] = 255;\n }\n }\n}\n\nfunction drawFigure(data, figure, context) {\n const ps = figure.coords;\n const cs = figure.colors;\n let i, ii;\n\n switch (figure.type) {\n case "lattice":\n const verticesPerRow = figure.verticesPerRow;\n const rows = Math.floor(ps.length / verticesPerRow) - 1;\n const cols = verticesPerRow - 1;\n\n for (i = 0; i < rows; i++) {\n let q = i * verticesPerRow;\n\n for (let j = 0; j < cols; j++, q++) {\n drawTriangle(data, context, ps[q], ps[q + 1], ps[q + verticesPerRow], cs[q], cs[q + 1], cs[q + verticesPerRow]);\n drawTriangle(data, context, ps[q + verticesPerRow + 1], ps[q + 1], ps[q + verticesPerRow], cs[q + verticesPerRow + 1], cs[q + 1], cs[q + verticesPerRow]);\n }\n }\n\n break;\n\n case "triangles":\n for (i = 0, ii = ps.length; i < ii; i += 3) {\n drawTriangle(data, context, ps[i], ps[i + 1], ps[i + 2], cs[i], cs[i + 1], cs[i + 2]);\n }\n\n break;\n\n default:\n throw new Error("illegal figure");\n }\n}\n\nclass MeshShadingPattern extends BaseShadingPattern {\n constructor(IR) {\n super();\n this._coords = IR[2];\n this._colors = IR[3];\n this._figures = IR[4];\n this._bounds = IR[5];\n this._bbox = IR[7];\n this._background = IR[8];\n this.matrix = null;\n }\n\n _createMeshCanvas(combinedScale, backgroundColor, cachedCanvases) {\n const EXPECTED_SCALE = 1.1;\n const MAX_PATTERN_SIZE = 3000;\n const BORDER_SIZE = 2;\n const offsetX = Math.floor(this._bounds[0]);\n const offsetY = Math.floor(this._bounds[1]);\n const boundsWidth = Math.ceil(this._bounds[2]) - offsetX;\n const boundsHeight = Math.ceil(this._bounds[3]) - offsetY;\n const width = Math.min(Math.ceil(Math.abs(boundsWidth * combinedScale[0] * EXPECTED_SCALE)), MAX_PATTERN_SIZE);\n const height = Math.min(Math.ceil(Math.abs(boundsHeight * combinedScale[1] * EXPECTED_SCALE)), MAX_PATTERN_SIZE);\n const scaleX = boundsWidth / width;\n const scaleY = boundsHeight / height;\n const context = {\n coords: this._coords,\n colors: this._colors,\n offsetX: -offsetX,\n offsetY: -offsetY,\n scaleX: 1 / scaleX,\n scaleY: 1 / scaleY\n };\n const paddedWidth = width + BORDER_SIZE * 2;\n const paddedHeight = height + BORDER_SIZE * 2;\n const tmpCanvas = cachedCanvases.getCanvas("mesh", paddedWidth, paddedHeight, false);\n const tmpCtx = tmpCanvas.context;\n const data = tmpCtx.createImageData(width, height);\n\n if (backgroundColor) {\n const bytes = data.data;\n\n for (let i = 0, ii = bytes.length; i < ii; i += 4) {\n bytes[i] = backgroundColor[0];\n bytes[i + 1] = backgroundColor[1];\n bytes[i + 2] = backgroundColor[2];\n bytes[i + 3] = 255;\n }\n }\n\n for (const figure of this._figures) {\n drawFigure(data, figure, context);\n }\n\n tmpCtx.putImageData(data, BORDER_SIZE, BORDER_SIZE);\n const canvas = tmpCanvas.canvas;\n return {\n canvas,\n offsetX: offsetX - BORDER_SIZE * scaleX,\n offsetY: offsetY - BORDER_SIZE * scaleY,\n scaleX,\n scaleY\n };\n }\n\n getPattern(ctx, owner, inverse, pathType) {\n applyBoundingBox(ctx, this._bbox);\n let scale;\n\n if (pathType === PathType.SHADING) {\n scale = _util.Util.singularValueDecompose2dScale(ctx.mozCurrentTransform);\n } else {\n scale = _util.Util.singularValueDecompose2dScale(owner.baseTransform);\n\n if (this.matrix) {\n const matrixScale = _util.Util.singularValueDecompose2dScale(this.matrix);\n\n scale = [scale[0] * matrixScale[0], scale[1] * matrixScale[1]];\n }\n }\n\n const temporaryPatternCanvas = this._createMeshCanvas(scale, pathType === PathType.SHADING ? null : this._background, owner.cachedCanvases);\n\n if (pathType !== PathType.SHADING) {\n ctx.setTransform.apply(ctx, owner.baseTransform);\n\n if (this.matrix) {\n ctx.transform.apply(ctx, this.matrix);\n }\n }\n\n ctx.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY);\n ctx.scale(temporaryPatternCanvas.scaleX, temporaryPatternCanvas.scaleY);\n return ctx.createPattern(temporaryPatternCanvas.canvas, "no-repeat");\n }\n\n}\n\nclass DummyShadingPattern extends BaseShadingPattern {\n getPattern() {\n return "hotpink";\n }\n\n}\n\nfunction getShadingPattern(IR) {\n switch (IR[0]) {\n case "RadialAxial":\n return new RadialAxialShadingPattern(IR);\n\n case "Mesh":\n return new MeshShadingPattern(IR);\n\n case "Dummy":\n return new DummyShadingPattern();\n }\n\n throw new Error(`Unknown IR type: ${IR[0]}`);\n}\n\nconst PaintType = {\n COLORED: 1,\n UNCOLORED: 2\n};\n\nclass TilingPattern {\n static get MAX_PATTERN_SIZE() {\n return (0, _util.shadow)(this, "MAX_PATTERN_SIZE", 3000);\n }\n\n constructor(IR, color, ctx, canvasGraphicsFactory, baseTransform) {\n this.operatorList = IR[2];\n this.matrix = IR[3] || [1, 0, 0, 1, 0, 0];\n this.bbox = IR[4];\n this.xstep = IR[5];\n this.ystep = IR[6];\n this.paintType = IR[7];\n this.tilingType = IR[8];\n this.color = color;\n this.ctx = ctx;\n this.canvasGraphicsFactory = canvasGraphicsFactory;\n this.baseTransform = baseTransform;\n }\n\n createPatternCanvas(owner) {\n const operatorList = this.operatorList;\n const bbox = this.bbox;\n const xstep = this.xstep;\n const ystep = this.ystep;\n const paintType = this.paintType;\n const tilingType = this.tilingType;\n const color = this.color;\n const canvasGraphicsFactory = this.canvasGraphicsFactory;\n (0, _util.info)("TilingType: " + tilingType);\n const x0 = bbox[0],\n y0 = bbox[1],\n x1 = bbox[2],\n y1 = bbox[3];\n\n const matrixScale = _util.Util.singularValueDecompose2dScale(this.matrix);\n\n const curMatrixScale = _util.Util.singularValueDecompose2dScale(this.baseTransform);\n\n const combinedScale = [matrixScale[0] * curMatrixScale[0], matrixScale[1] * curMatrixScale[1]];\n const dimx = this.getSizeAndScale(xstep, this.ctx.canvas.width, combinedScale[0]);\n const dimy = this.getSizeAndScale(ystep, this.ctx.canvas.height, combinedScale[1]);\n const tmpCanvas = owner.cachedCanvases.getCanvas("pattern", dimx.size, dimy.size, true);\n const tmpCtx = tmpCanvas.context;\n const graphics = canvasGraphicsFactory.createCanvasGraphics(tmpCtx);\n graphics.groupLevel = owner.groupLevel;\n this.setFillAndStrokeStyleToContext(graphics, paintType, color);\n let adjustedX0 = x0;\n let adjustedY0 = y0;\n let adjustedX1 = x1;\n let adjustedY1 = y1;\n\n if (x0 < 0) {\n adjustedX0 = 0;\n adjustedX1 += Math.abs(x0);\n }\n\n if (y0 < 0) {\n adjustedY0 = 0;\n adjustedY1 += Math.abs(y0);\n }\n\n tmpCtx.translate(-(dimx.scale * adjustedX0), -(dimy.scale * adjustedY0));\n graphics.transform(dimx.scale, 0, 0, dimy.scale, 0, 0);\n tmpCtx.save();\n this.clipBbox(graphics, adjustedX0, adjustedY0, adjustedX1, adjustedY1);\n graphics.baseTransform = graphics.ctx.mozCurrentTransform.slice();\n graphics.executeOperatorList(operatorList);\n graphics.endDrawing();\n return {\n canvas: tmpCanvas.canvas,\n scaleX: dimx.scale,\n scaleY: dimy.scale,\n offsetX: adjustedX0,\n offsetY: adjustedY0\n };\n }\n\n getSizeAndScale(step, realOutputSize, scale) {\n step = Math.abs(step);\n const maxSize = Math.max(TilingPattern.MAX_PATTERN_SIZE, realOutputSize);\n let size = Math.ceil(step * scale);\n\n if (size >= maxSize) {\n size = maxSize;\n } else {\n scale = size / step;\n }\n\n return {\n scale,\n size\n };\n }\n\n clipBbox(graphics, x0, y0, x1, y1) {\n const bboxWidth = x1 - x0;\n const bboxHeight = y1 - y0;\n graphics.ctx.rect(x0, y0, bboxWidth, bboxHeight);\n graphics.current.updateRectMinMax(graphics.ctx.mozCurrentTransform, [x0, y0, x1, y1]);\n graphics.clip();\n graphics.endPath();\n }\n\n setFillAndStrokeStyleToContext(graphics, paintType, color) {\n const context = graphics.ctx,\n current = graphics.current;\n\n switch (paintType) {\n case PaintType.COLORED:\n const ctx = this.ctx;\n context.fillStyle = ctx.fillStyle;\n context.strokeStyle = ctx.strokeStyle;\n current.fillColor = ctx.fillStyle;\n current.strokeColor = ctx.strokeStyle;\n break;\n\n case PaintType.UNCOLORED:\n const cssColor = _util.Util.makeHexColor(color[0], color[1], color[2]);\n\n context.fillStyle = cssColor;\n context.strokeStyle = cssColor;\n current.fillColor = cssColor;\n current.strokeColor = cssColor;\n break;\n\n default:\n throw new _util.FormatError(`Unsupported paint type: ${paintType}`);\n }\n }\n\n getPattern(ctx, owner, inverse, pathType) {\n let matrix = inverse;\n\n if (pathType !== PathType.SHADING) {\n matrix = _util.Util.transform(matrix, owner.baseTransform);\n\n if (this.matrix) {\n matrix = _util.Util.transform(matrix, this.matrix);\n }\n }\n\n const temporaryPatternCanvas = this.createPatternCanvas(owner);\n let domMatrix = new DOMMatrix(matrix);\n domMatrix = domMatrix.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY);\n domMatrix = domMatrix.scale(1 / temporaryPatternCanvas.scaleX, 1 / temporaryPatternCanvas.scaleY);\n const pattern = ctx.createPattern(temporaryPatternCanvas.canvas, "repeat");\n\n try {\n pattern.setTransform(domMatrix);\n } catch (ex) {\n (0, _util.warn)(`TilingPattern.getPattern: "${ex?.message}".`);\n }\n\n return pattern;\n }\n\n}\n\nexports.TilingPattern = TilingPattern;\n\n/***/ }),\n/* 12 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.applyMaskImageData = applyMaskImageData;\n\nvar _util = __w_pdfjs_require__(1);\n\nfunction applyMaskImageData({\n src,\n srcPos = 0,\n dest,\n destPos = 0,\n width,\n height,\n inverseDecode = false\n}) {\n const opaque = _util.FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff;\n const [zeroMapping, oneMapping] = !inverseDecode ? [opaque, 0] : [0, opaque];\n const widthInSource = width >> 3;\n const widthRemainder = width & 7;\n const srcLength = src.length;\n dest = new Uint32Array(dest.buffer);\n\n for (let i = 0; i < height; i++) {\n for (const max = srcPos + widthInSource; srcPos < max; srcPos++) {\n const elem = srcPos < srcLength ? src[srcPos] : 255;\n dest[destPos++] = elem & 0b10000000 ? oneMapping : zeroMapping;\n dest[destPos++] = elem & 0b1000000 ? oneMapping : zeroMapping;\n dest[destPos++] = elem & 0b100000 ? oneMapping : zeroMapping;\n dest[destPos++] = elem & 0b10000 ? oneMapping : zeroMapping;\n dest[destPos++] = elem & 0b1000 ? oneMapping : zeroMapping;\n dest[destPos++] = elem & 0b100 ? oneMapping : zeroMapping;\n dest[destPos++] = elem & 0b10 ? oneMapping : zeroMapping;\n dest[destPos++] = elem & 0b1 ? oneMapping : zeroMapping;\n }\n\n if (widthRemainder === 0) {\n continue;\n }\n\n const elem = srcPos < srcLength ? src[srcPos++] : 255;\n\n for (let j = 0; j < widthRemainder; j++) {\n dest[destPos++] = elem & 1 << 7 - j ? oneMapping : zeroMapping;\n }\n }\n\n return {\n srcPos,\n destPos\n };\n}\n\n/***/ }),\n/* 13 */\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.GlobalWorkerOptions = void 0;\nconst GlobalWorkerOptions = Object.create(null);\nexports.GlobalWorkerOptions = GlobalWorkerOptions;\nGlobalWorkerOptions.workerPort = GlobalWorkerOptions.workerPort === undefined ? null : GlobalWorkerOptions.workerPort;\nGlobalWorkerOptions.workerSrc = GlobalWorkerOptions.workerSrc === undefined ? "" : GlobalWorkerOptions.workerSrc;\n\n/***/ }),\n/* 14 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.MessageHandler = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nconst CallbackKind = {\n UNKNOWN: 0,\n DATA: 1,\n ERROR: 2\n};\nconst StreamKind = {\n UNKNOWN: 0,\n CANCEL: 1,\n CANCEL_COMPLETE: 2,\n CLOSE: 3,\n ENQUEUE: 4,\n ERROR: 5,\n PULL: 6,\n PULL_COMPLETE: 7,\n START_COMPLETE: 8\n};\n\nfunction wrapReason(reason) {\n if (!(reason instanceof Error || typeof reason === "object" && reason !== null)) {\n (0, _util.unreachable)(\'wrapReason: Expected "reason" to be a (possibly cloned) Error.\');\n }\n\n switch (reason.name) {\n case "AbortException":\n return new _util.AbortException(reason.message);\n\n case "MissingPDFException":\n return new _util.MissingPDFException(reason.message);\n\n case "PasswordException":\n return new _util.PasswordException(reason.message, reason.code);\n\n case "UnexpectedResponseException":\n return new _util.UnexpectedResponseException(reason.message, reason.status);\n\n case "UnknownErrorException":\n return new _util.UnknownErrorException(reason.message, reason.details);\n\n default:\n return new _util.UnknownErrorException(reason.message, reason.toString());\n }\n}\n\nclass MessageHandler {\n constructor(sourceName, targetName, comObj) {\n this.sourceName = sourceName;\n this.targetName = targetName;\n this.comObj = comObj;\n this.callbackId = 1;\n this.streamId = 1;\n this.streamSinks = Object.create(null);\n this.streamControllers = Object.create(null);\n this.callbackCapabilities = Object.create(null);\n this.actionHandler = Object.create(null);\n\n this._onComObjOnMessage = event => {\n const data = event.data;\n\n if (data.targetName !== this.sourceName) {\n return;\n }\n\n if (data.stream) {\n this._processStreamMessage(data);\n\n return;\n }\n\n if (data.callback) {\n const callbackId = data.callbackId;\n const capability = this.callbackCapabilities[callbackId];\n\n if (!capability) {\n throw new Error(`Cannot resolve callback ${callbackId}`);\n }\n\n delete this.callbackCapabilities[callbackId];\n\n if (data.callback === CallbackKind.DATA) {\n capability.resolve(data.data);\n } else if (data.callback === CallbackKind.ERROR) {\n capability.reject(wrapReason(data.reason));\n } else {\n throw new Error("Unexpected callback case");\n }\n\n return;\n }\n\n const action = this.actionHandler[data.action];\n\n if (!action) {\n throw new Error(`Unknown action from worker: ${data.action}`);\n }\n\n if (data.callbackId) {\n const cbSourceName = this.sourceName;\n const cbTargetName = data.sourceName;\n new Promise(function (resolve) {\n resolve(action(data.data));\n }).then(function (result) {\n comObj.postMessage({\n sourceName: cbSourceName,\n targetName: cbTargetName,\n callback: CallbackKind.DATA,\n callbackId: data.callbackId,\n data: result\n });\n }, function (reason) {\n comObj.postMessage({\n sourceName: cbSourceName,\n targetName: cbTargetName,\n callback: CallbackKind.ERROR,\n callbackId: data.callbackId,\n reason: wrapReason(reason)\n });\n });\n return;\n }\n\n if (data.streamId) {\n this._createStreamSink(data);\n\n return;\n }\n\n action(data.data);\n };\n\n comObj.addEventListener("message", this._onComObjOnMessage);\n }\n\n on(actionName, handler) {\n const ah = this.actionHandler;\n\n if (ah[actionName]) {\n throw new Error(`There is already an actionName called "${actionName}"`);\n }\n\n ah[actionName] = handler;\n }\n\n send(actionName, data, transfers) {\n this.comObj.postMessage({\n sourceName: this.sourceName,\n targetName: this.targetName,\n action: actionName,\n data\n }, transfers);\n }\n\n sendWithPromise(actionName, data, transfers) {\n const callbackId = this.callbackId++;\n const capability = (0, _util.createPromiseCapability)();\n this.callbackCapabilities[callbackId] = capability;\n\n try {\n this.comObj.postMessage({\n sourceName: this.sourceName,\n targetName: this.targetName,\n action: actionName,\n callbackId,\n data\n }, transfers);\n } catch (ex) {\n capability.reject(ex);\n }\n\n return capability.promise;\n }\n\n sendWithStream(actionName, data, queueingStrategy, transfers) {\n const streamId = this.streamId++,\n sourceName = this.sourceName,\n targetName = this.targetName,\n comObj = this.comObj;\n return new ReadableStream({\n start: controller => {\n const startCapability = (0, _util.createPromiseCapability)();\n this.streamControllers[streamId] = {\n controller,\n startCall: startCapability,\n pullCall: null,\n cancelCall: null,\n isClosed: false\n };\n comObj.postMessage({\n sourceName,\n targetName,\n action: actionName,\n streamId,\n data,\n desiredSize: controller.desiredSize\n }, transfers);\n return startCapability.promise;\n },\n pull: controller => {\n const pullCapability = (0, _util.createPromiseCapability)();\n this.streamControllers[streamId].pullCall = pullCapability;\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.PULL,\n streamId,\n desiredSize: controller.desiredSize\n });\n return pullCapability.promise;\n },\n cancel: reason => {\n (0, _util.assert)(reason instanceof Error, "cancel must have a valid reason");\n const cancelCapability = (0, _util.createPromiseCapability)();\n this.streamControllers[streamId].cancelCall = cancelCapability;\n this.streamControllers[streamId].isClosed = true;\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.CANCEL,\n streamId,\n reason: wrapReason(reason)\n });\n return cancelCapability.promise;\n }\n }, queueingStrategy);\n }\n\n _createStreamSink(data) {\n const streamId = data.streamId,\n sourceName = this.sourceName,\n targetName = data.sourceName,\n comObj = this.comObj;\n const self = this,\n action = this.actionHandler[data.action];\n const streamSink = {\n enqueue(chunk, size = 1, transfers) {\n if (this.isCancelled) {\n return;\n }\n\n const lastDesiredSize = this.desiredSize;\n this.desiredSize -= size;\n\n if (lastDesiredSize > 0 && this.desiredSize <= 0) {\n this.sinkCapability = (0, _util.createPromiseCapability)();\n this.ready = this.sinkCapability.promise;\n }\n\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.ENQUEUE,\n streamId,\n chunk\n }, transfers);\n },\n\n close() {\n if (this.isCancelled) {\n return;\n }\n\n this.isCancelled = true;\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.CLOSE,\n streamId\n });\n delete self.streamSinks[streamId];\n },\n\n error(reason) {\n (0, _util.assert)(reason instanceof Error, "error must have a valid reason");\n\n if (this.isCancelled) {\n return;\n }\n\n this.isCancelled = true;\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.ERROR,\n streamId,\n reason: wrapReason(reason)\n });\n },\n\n sinkCapability: (0, _util.createPromiseCapability)(),\n onPull: null,\n onCancel: null,\n isCancelled: false,\n desiredSize: data.desiredSize,\n ready: null\n };\n streamSink.sinkCapability.resolve();\n streamSink.ready = streamSink.sinkCapability.promise;\n this.streamSinks[streamId] = streamSink;\n new Promise(function (resolve) {\n resolve(action(data.data, streamSink));\n }).then(function () {\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.START_COMPLETE,\n streamId,\n success: true\n });\n }, function (reason) {\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.START_COMPLETE,\n streamId,\n reason: wrapReason(reason)\n });\n });\n }\n\n _processStreamMessage(data) {\n const streamId = data.streamId,\n sourceName = this.sourceName,\n targetName = data.sourceName,\n comObj = this.comObj;\n const streamController = this.streamControllers[streamId],\n streamSink = this.streamSinks[streamId];\n\n switch (data.stream) {\n case StreamKind.START_COMPLETE:\n if (data.success) {\n streamController.startCall.resolve();\n } else {\n streamController.startCall.reject(wrapReason(data.reason));\n }\n\n break;\n\n case StreamKind.PULL_COMPLETE:\n if (data.success) {\n streamController.pullCall.resolve();\n } else {\n streamController.pullCall.reject(wrapReason(data.reason));\n }\n\n break;\n\n case StreamKind.PULL:\n if (!streamSink) {\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.PULL_COMPLETE,\n streamId,\n success: true\n });\n break;\n }\n\n if (streamSink.desiredSize <= 0 && data.desiredSize > 0) {\n streamSink.sinkCapability.resolve();\n }\n\n streamSink.desiredSize = data.desiredSize;\n new Promise(function (resolve) {\n resolve(streamSink.onPull && streamSink.onPull());\n }).then(function () {\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.PULL_COMPLETE,\n streamId,\n success: true\n });\n }, function (reason) {\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.PULL_COMPLETE,\n streamId,\n reason: wrapReason(reason)\n });\n });\n break;\n\n case StreamKind.ENQUEUE:\n (0, _util.assert)(streamController, "enqueue should have stream controller");\n\n if (streamController.isClosed) {\n break;\n }\n\n streamController.controller.enqueue(data.chunk);\n break;\n\n case StreamKind.CLOSE:\n (0, _util.assert)(streamController, "close should have stream controller");\n\n if (streamController.isClosed) {\n break;\n }\n\n streamController.isClosed = true;\n streamController.controller.close();\n\n this._deleteStreamController(streamController, streamId);\n\n break;\n\n case StreamKind.ERROR:\n (0, _util.assert)(streamController, "error should have stream controller");\n streamController.controller.error(wrapReason(data.reason));\n\n this._deleteStreamController(streamController, streamId);\n\n break;\n\n case StreamKind.CANCEL_COMPLETE:\n if (data.success) {\n streamController.cancelCall.resolve();\n } else {\n streamController.cancelCall.reject(wrapReason(data.reason));\n }\n\n this._deleteStreamController(streamController, streamId);\n\n break;\n\n case StreamKind.CANCEL:\n if (!streamSink) {\n break;\n }\n\n new Promise(function (resolve) {\n resolve(streamSink.onCancel && streamSink.onCancel(wrapReason(data.reason)));\n }).then(function () {\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.CANCEL_COMPLETE,\n streamId,\n success: true\n });\n }, function (reason) {\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.CANCEL_COMPLETE,\n streamId,\n reason: wrapReason(reason)\n });\n });\n streamSink.sinkCapability.reject(wrapReason(data.reason));\n streamSink.isCancelled = true;\n delete this.streamSinks[streamId];\n break;\n\n default:\n throw new Error("Unexpected stream case");\n }\n }\n\n async _deleteStreamController(streamController, streamId) {\n await Promise.allSettled([streamController.startCall && streamController.startCall.promise, streamController.pullCall && streamController.pullCall.promise, streamController.cancelCall && streamController.cancelCall.promise]);\n delete this.streamControllers[streamId];\n }\n\n destroy() {\n this.comObj.removeEventListener("message", this._onComObjOnMessage);\n }\n\n}\n\nexports.MessageHandler = MessageHandler;\n\n/***/ }),\n/* 15 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.Metadata = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nclass Metadata {\n #metadataMap;\n #data;\n\n constructor({\n parsedData,\n rawData\n }) {\n this.#metadataMap = parsedData;\n this.#data = rawData;\n }\n\n getRaw() {\n return this.#data;\n }\n\n get(name) {\n return this.#metadataMap.get(name) ?? null;\n }\n\n getAll() {\n return (0, _util.objectFromMap)(this.#metadataMap);\n }\n\n has(name) {\n return this.#metadataMap.has(name);\n }\n\n}\n\nexports.Metadata = Metadata;\n\n/***/ }),\n/* 16 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.OptionalContentConfig = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nclass OptionalContentGroup {\n constructor(name, intent) {\n this.visible = true;\n this.name = name;\n this.intent = intent;\n }\n\n}\n\nclass OptionalContentConfig {\n constructor(data) {\n this.name = null;\n this.creator = null;\n this._order = null;\n this._groups = new Map();\n\n if (data === null) {\n return;\n }\n\n this.name = data.name;\n this.creator = data.creator;\n this._order = data.order;\n\n for (const group of data.groups) {\n this._groups.set(group.id, new OptionalContentGroup(group.name, group.intent));\n }\n\n if (data.baseState === "OFF") {\n for (const group of this._groups) {\n group.visible = false;\n }\n }\n\n for (const on of data.on) {\n this._groups.get(on).visible = true;\n }\n\n for (const off of data.off) {\n this._groups.get(off).visible = false;\n }\n }\n\n _evaluateVisibilityExpression(array) {\n const length = array.length;\n\n if (length < 2) {\n return true;\n }\n\n const operator = array[0];\n\n for (let i = 1; i < length; i++) {\n const element = array[i];\n let state;\n\n if (Array.isArray(element)) {\n state = this._evaluateVisibilityExpression(element);\n } else if (this._groups.has(element)) {\n state = this._groups.get(element).visible;\n } else {\n (0, _util.warn)(`Optional content group not found: ${element}`);\n return true;\n }\n\n switch (operator) {\n case "And":\n if (!state) {\n return false;\n }\n\n break;\n\n case "Or":\n if (state) {\n return true;\n }\n\n break;\n\n case "Not":\n return !state;\n\n default:\n return true;\n }\n }\n\n return operator === "And";\n }\n\n isVisible(group) {\n if (this._groups.size === 0) {\n return true;\n }\n\n if (!group) {\n (0, _util.warn)("Optional content group not defined.");\n return true;\n }\n\n if (group.type === "OCG") {\n if (!this._groups.has(group.id)) {\n (0, _util.warn)(`Optional content group not found: ${group.id}`);\n return true;\n }\n\n return this._groups.get(group.id).visible;\n } else if (group.type === "OCMD") {\n if (group.expression) {\n return this._evaluateVisibilityExpression(group.expression);\n }\n\n if (!group.policy || group.policy === "AnyOn") {\n for (const id of group.ids) {\n if (!this._groups.has(id)) {\n (0, _util.warn)(`Optional content group not found: ${id}`);\n return true;\n }\n\n if (this._groups.get(id).visible) {\n return true;\n }\n }\n\n return false;\n } else if (group.policy === "AllOn") {\n for (const id of group.ids) {\n if (!this._groups.has(id)) {\n (0, _util.warn)(`Optional content group not found: ${id}`);\n return true;\n }\n\n if (!this._groups.get(id).visible) {\n return false;\n }\n }\n\n return true;\n } else if (group.policy === "AnyOff") {\n for (const id of group.ids) {\n if (!this._groups.has(id)) {\n (0, _util.warn)(`Optional content group not found: ${id}`);\n return true;\n }\n\n if (!this._groups.get(id).visible) {\n return true;\n }\n }\n\n return false;\n } else if (group.policy === "AllOff") {\n for (const id of group.ids) {\n if (!this._groups.has(id)) {\n (0, _util.warn)(`Optional content group not found: ${id}`);\n return true;\n }\n\n if (this._groups.get(id).visible) {\n return false;\n }\n }\n\n return true;\n }\n\n (0, _util.warn)(`Unknown optional content policy ${group.policy}.`);\n return true;\n }\n\n (0, _util.warn)(`Unknown group type ${group.type}.`);\n return true;\n }\n\n setVisibility(id, visible = true) {\n if (!this._groups.has(id)) {\n (0, _util.warn)(`Optional content group not found: ${id}`);\n return;\n }\n\n this._groups.get(id).visible = !!visible;\n }\n\n getOrder() {\n if (!this._groups.size) {\n return null;\n }\n\n if (this._order) {\n return this._order.slice();\n }\n\n return Array.from(this._groups.keys());\n }\n\n getGroups() {\n return this._groups.size > 0 ? (0, _util.objectFromMap)(this._groups) : null;\n }\n\n getGroup(id) {\n return this._groups.get(id) || null;\n }\n\n}\n\nexports.OptionalContentConfig = OptionalContentConfig;\n\n/***/ }),\n/* 17 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.PDFDataTransportStream = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _display_utils = __w_pdfjs_require__(5);\n\nclass PDFDataTransportStream {\n constructor(params, pdfDataRangeTransport) {\n (0, _util.assert)(pdfDataRangeTransport, \'PDFDataTransportStream - missing required "pdfDataRangeTransport" argument.\');\n this._queuedChunks = [];\n this._progressiveDone = params.progressiveDone || false;\n this._contentDispositionFilename = params.contentDispositionFilename || null;\n const initialData = params.initialData;\n\n if (initialData?.length > 0) {\n const buffer = new Uint8Array(initialData).buffer;\n\n this._queuedChunks.push(buffer);\n }\n\n this._pdfDataRangeTransport = pdfDataRangeTransport;\n this._isStreamingSupported = !params.disableStream;\n this._isRangeSupported = !params.disableRange;\n this._contentLength = params.length;\n this._fullRequestReader = null;\n this._rangeReaders = [];\n\n this._pdfDataRangeTransport.addRangeListener((begin, chunk) => {\n this._onReceiveData({\n begin,\n chunk\n });\n });\n\n this._pdfDataRangeTransport.addProgressListener((loaded, total) => {\n this._onProgress({\n loaded,\n total\n });\n });\n\n this._pdfDataRangeTransport.addProgressiveReadListener(chunk => {\n this._onReceiveData({\n chunk\n });\n });\n\n this._pdfDataRangeTransport.addProgressiveDoneListener(() => {\n this._onProgressiveDone();\n });\n\n this._pdfDataRangeTransport.transportReady();\n }\n\n _onReceiveData(args) {\n const buffer = new Uint8Array(args.chunk).buffer;\n\n if (args.begin === undefined) {\n if (this._fullRequestReader) {\n this._fullRequestReader._enqueue(buffer);\n } else {\n this._queuedChunks.push(buffer);\n }\n } else {\n const found = this._rangeReaders.some(function (rangeReader) {\n if (rangeReader._begin !== args.begin) {\n return false;\n }\n\n rangeReader._enqueue(buffer);\n\n return true;\n });\n\n (0, _util.assert)(found, "_onReceiveData - no `PDFDataTransportStreamRangeReader` instance found.");\n }\n }\n\n get _progressiveDataLength() {\n return this._fullRequestReader?._loaded ?? 0;\n }\n\n _onProgress(evt) {\n if (evt.total === undefined) {\n const firstReader = this._rangeReaders[0];\n\n if (firstReader?.onProgress) {\n firstReader.onProgress({\n loaded: evt.loaded\n });\n }\n } else {\n const fullReader = this._fullRequestReader;\n\n if (fullReader?.onProgress) {\n fullReader.onProgress({\n loaded: evt.loaded,\n total: evt.total\n });\n }\n }\n }\n\n _onProgressiveDone() {\n if (this._fullRequestReader) {\n this._fullRequestReader.progressiveDone();\n }\n\n this._progressiveDone = true;\n }\n\n _removeRangeReader(reader) {\n const i = this._rangeReaders.indexOf(reader);\n\n if (i >= 0) {\n this._rangeReaders.splice(i, 1);\n }\n }\n\n getFullReader() {\n (0, _util.assert)(!this._fullRequestReader, "PDFDataTransportStream.getFullReader can only be called once.");\n const queuedChunks = this._queuedChunks;\n this._queuedChunks = null;\n return new PDFDataTransportStreamReader(this, queuedChunks, this._progressiveDone, this._contentDispositionFilename);\n }\n\n getRangeReader(begin, end) {\n if (end <= this._progressiveDataLength) {\n return null;\n }\n\n const reader = new PDFDataTransportStreamRangeReader(this, begin, end);\n\n this._pdfDataRangeTransport.requestDataRange(begin, end);\n\n this._rangeReaders.push(reader);\n\n return reader;\n }\n\n cancelAllRequests(reason) {\n if (this._fullRequestReader) {\n this._fullRequestReader.cancel(reason);\n }\n\n for (const reader of this._rangeReaders.slice(0)) {\n reader.cancel(reason);\n }\n\n this._pdfDataRangeTransport.abort();\n }\n\n}\n\nexports.PDFDataTransportStream = PDFDataTransportStream;\n\nclass PDFDataTransportStreamReader {\n constructor(stream, queuedChunks, progressiveDone = false, contentDispositionFilename = null) {\n this._stream = stream;\n this._done = progressiveDone || false;\n this._filename = (0, _display_utils.isPdfFile)(contentDispositionFilename) ? contentDispositionFilename : null;\n this._queuedChunks = queuedChunks || [];\n this._loaded = 0;\n\n for (const chunk of this._queuedChunks) {\n this._loaded += chunk.byteLength;\n }\n\n this._requests = [];\n this._headersReady = Promise.resolve();\n stream._fullRequestReader = this;\n this.onProgress = null;\n }\n\n _enqueue(chunk) {\n if (this._done) {\n return;\n }\n\n if (this._requests.length > 0) {\n const requestCapability = this._requests.shift();\n\n requestCapability.resolve({\n value: chunk,\n done: false\n });\n } else {\n this._queuedChunks.push(chunk);\n }\n\n this._loaded += chunk.byteLength;\n }\n\n get headersReady() {\n return this._headersReady;\n }\n\n get filename() {\n return this._filename;\n }\n\n get isRangeSupported() {\n return this._stream._isRangeSupported;\n }\n\n get isStreamingSupported() {\n return this._stream._isStreamingSupported;\n }\n\n get contentLength() {\n return this._stream._contentLength;\n }\n\n async read() {\n if (this._queuedChunks.length > 0) {\n const chunk = this._queuedChunks.shift();\n\n return {\n value: chunk,\n done: false\n };\n }\n\n if (this._done) {\n return {\n value: undefined,\n done: true\n };\n }\n\n const requestCapability = (0, _util.createPromiseCapability)();\n\n this._requests.push(requestCapability);\n\n return requestCapability.promise;\n }\n\n cancel(reason) {\n this._done = true;\n\n for (const requestCapability of this._requests) {\n requestCapability.resolve({\n value: undefined,\n done: true\n });\n }\n\n this._requests.length = 0;\n }\n\n progressiveDone() {\n if (this._done) {\n return;\n }\n\n this._done = true;\n }\n\n}\n\nclass PDFDataTransportStreamRangeReader {\n constructor(stream, begin, end) {\n this._stream = stream;\n this._begin = begin;\n this._end = end;\n this._queuedChunk = null;\n this._requests = [];\n this._done = false;\n this.onProgress = null;\n }\n\n _enqueue(chunk) {\n if (this._done) {\n return;\n }\n\n if (this._requests.length === 0) {\n this._queuedChunk = chunk;\n } else {\n const requestsCapability = this._requests.shift();\n\n requestsCapability.resolve({\n value: chunk,\n done: false\n });\n\n for (const requestCapability of this._requests) {\n requestCapability.resolve({\n value: undefined,\n done: true\n });\n }\n\n this._requests.length = 0;\n }\n\n this._done = true;\n\n this._stream._removeRangeReader(this);\n }\n\n get isStreamingSupported() {\n return false;\n }\n\n async read() {\n if (this._queuedChunk) {\n const chunk = this._queuedChunk;\n this._queuedChunk = null;\n return {\n value: chunk,\n done: false\n };\n }\n\n if (this._done) {\n return {\n value: undefined,\n done: true\n };\n }\n\n const requestCapability = (0, _util.createPromiseCapability)();\n\n this._requests.push(requestCapability);\n\n return requestCapability.promise;\n }\n\n cancel(reason) {\n this._done = true;\n\n for (const requestCapability of this._requests) {\n requestCapability.resolve({\n value: undefined,\n done: true\n });\n }\n\n this._requests.length = 0;\n\n this._stream._removeRangeReader(this);\n }\n\n}\n\n/***/ }),\n/* 18 */\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.XfaText = void 0;\n\nclass XfaText {\n static textContent(xfa) {\n const items = [];\n const output = {\n items,\n styles: Object.create(null)\n };\n\n function walk(node) {\n if (!node) {\n return;\n }\n\n let str = null;\n const name = node.name;\n\n if (name === "#text") {\n str = node.value;\n } else if (!XfaText.shouldBuildText(name)) {\n return;\n } else if (node?.attributes?.textContent) {\n str = node.attributes.textContent;\n } else if (node.value) {\n str = node.value;\n }\n\n if (str !== null) {\n items.push({\n str\n });\n }\n\n if (!node.children) {\n return;\n }\n\n for (const child of node.children) {\n walk(child);\n }\n }\n\n walk(xfa);\n return output;\n }\n\n static shouldBuildText(name) {\n return !(name === "textarea" || name === "input" || name === "option" || name === "select");\n }\n\n}\n\nexports.XfaText = XfaText;\n\n/***/ }),\n/* 19 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.NodeStandardFontDataFactory = exports.NodeCanvasFactory = exports.NodeCMapReaderFactory = void 0;\n\nvar _base_factory = __w_pdfjs_require__(6);\n\n;\n\nconst fetchData = function (url) {\n return new Promise((resolve, reject) => {\n const fs = __webpack_require__(172);\n\n fs.readFile(url, (error, data) => {\n if (error || !data) {\n reject(new Error(error));\n return;\n }\n\n resolve(new Uint8Array(data));\n });\n });\n};\n\nclass NodeCanvasFactory extends _base_factory.BaseCanvasFactory {\n _createCanvas(width, height) {\n const Canvas = __webpack_require__(414);\n\n return Canvas.createCanvas(width, height);\n }\n\n}\n\nexports.NodeCanvasFactory = NodeCanvasFactory;\n\nclass NodeCMapReaderFactory extends _base_factory.BaseCMapReaderFactory {\n _fetchData(url, compressionType) {\n return fetchData(url).then(data => {\n return {\n cMapData: data,\n compressionType\n };\n });\n }\n\n}\n\nexports.NodeCMapReaderFactory = NodeCMapReaderFactory;\n\nclass NodeStandardFontDataFactory extends _base_factory.BaseStandardFontDataFactory {\n _fetchData(url) {\n return fetchData(url);\n }\n\n}\n\nexports.NodeStandardFontDataFactory = NodeStandardFontDataFactory;\n\n/***/ }),\n/* 20 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.AnnotationLayer = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _display_utils = __w_pdfjs_require__(5);\n\nvar _annotation_storage = __w_pdfjs_require__(8);\n\nvar _scripting_utils = __w_pdfjs_require__(21);\n\nvar _xfa_layer = __w_pdfjs_require__(22);\n\nconst DEFAULT_TAB_INDEX = 1000;\nconst GetElementsByNameSet = new WeakSet();\n\nfunction getRectDims(rect) {\n return {\n width: rect[2] - rect[0],\n height: rect[3] - rect[1]\n };\n}\n\nclass AnnotationElementFactory {\n static create(parameters) {\n const subtype = parameters.data.annotationType;\n\n switch (subtype) {\n case _util.AnnotationType.LINK:\n return new LinkAnnotationElement(parameters);\n\n case _util.AnnotationType.TEXT:\n return new TextAnnotationElement(parameters);\n\n case _util.AnnotationType.WIDGET:\n const fieldType = parameters.data.fieldType;\n\n switch (fieldType) {\n case "Tx":\n return new TextWidgetAnnotationElement(parameters);\n\n case "Btn":\n if (parameters.data.radioButton) {\n return new RadioButtonWidgetAnnotationElement(parameters);\n } else if (parameters.data.checkBox) {\n return new CheckboxWidgetAnnotationElement(parameters);\n }\n\n return new PushButtonWidgetAnnotationElement(parameters);\n\n case "Ch":\n return new ChoiceWidgetAnnotationElement(parameters);\n }\n\n return new WidgetAnnotationElement(parameters);\n\n case _util.AnnotationType.POPUP:\n return new PopupAnnotationElement(parameters);\n\n case _util.AnnotationType.FREETEXT:\n return new FreeTextAnnotationElement(parameters);\n\n case _util.AnnotationType.LINE:\n return new LineAnnotationElement(parameters);\n\n case _util.AnnotationType.SQUARE:\n return new SquareAnnotationElement(parameters);\n\n case _util.AnnotationType.CIRCLE:\n return new CircleAnnotationElement(parameters);\n\n case _util.AnnotationType.POLYLINE:\n return new PolylineAnnotationElement(parameters);\n\n case _util.AnnotationType.CARET:\n return new CaretAnnotationElement(parameters);\n\n case _util.AnnotationType.INK:\n return new InkAnnotationElement(parameters);\n\n case _util.AnnotationType.POLYGON:\n return new PolygonAnnotationElement(parameters);\n\n case _util.AnnotationType.HIGHLIGHT:\n return new HighlightAnnotationElement(parameters);\n\n case _util.AnnotationType.UNDERLINE:\n return new UnderlineAnnotationElement(parameters);\n\n case _util.AnnotationType.SQUIGGLY:\n return new SquigglyAnnotationElement(parameters);\n\n case _util.AnnotationType.STRIKEOUT:\n return new StrikeOutAnnotationElement(parameters);\n\n case _util.AnnotationType.STAMP:\n return new StampAnnotationElement(parameters);\n\n case _util.AnnotationType.FILEATTACHMENT:\n return new FileAttachmentAnnotationElement(parameters);\n\n default:\n return new AnnotationElement(parameters);\n }\n }\n\n}\n\nclass AnnotationElement {\n constructor(parameters, {\n isRenderable = false,\n ignoreBorder = false,\n createQuadrilaterals = false\n } = {}) {\n this.isRenderable = isRenderable;\n this.data = parameters.data;\n this.layer = parameters.layer;\n this.page = parameters.page;\n this.viewport = parameters.viewport;\n this.linkService = parameters.linkService;\n this.downloadManager = parameters.downloadManager;\n this.imageResourcesPath = parameters.imageResourcesPath;\n this.renderForms = parameters.renderForms;\n this.svgFactory = parameters.svgFactory;\n this.annotationStorage = parameters.annotationStorage;\n this.enableScripting = parameters.enableScripting;\n this.hasJSActions = parameters.hasJSActions;\n this._fieldObjects = parameters.fieldObjects;\n this._mouseState = parameters.mouseState;\n\n if (isRenderable) {\n this.container = this._createContainer(ignoreBorder);\n }\n\n if (createQuadrilaterals) {\n this.quadrilaterals = this._createQuadrilaterals(ignoreBorder);\n }\n }\n\n _createContainer(ignoreBorder = false) {\n const data = this.data,\n page = this.page,\n viewport = this.viewport;\n const container = document.createElement("section");\n let {\n width,\n height\n } = getRectDims(data.rect);\n container.setAttribute("data-annotation-id", data.id);\n\n const rect = _util.Util.normalizeRect([data.rect[0], page.view[3] - data.rect[1] + page.view[1], data.rect[2], page.view[3] - data.rect[3] + page.view[1]]);\n\n if (data.hasOwnCanvas) {\n const transform = viewport.transform.slice();\n\n const [scaleX, scaleY] = _util.Util.singularValueDecompose2dScale(transform);\n\n width = Math.ceil(width * scaleX);\n height = Math.ceil(height * scaleY);\n rect[0] *= scaleX;\n rect[1] *= scaleY;\n\n for (let i = 0; i < 4; i++) {\n transform[i] = Math.sign(transform[i]);\n }\n\n container.style.transform = `matrix(${transform.join(",")})`;\n } else {\n container.style.transform = `matrix(${viewport.transform.join(",")})`;\n }\n\n container.style.transformOrigin = `${-rect[0]}px ${-rect[1]}px`;\n\n if (!ignoreBorder && data.borderStyle.width > 0) {\n container.style.borderWidth = `${data.borderStyle.width}px`;\n\n if (data.borderStyle.style !== _util.AnnotationBorderStyleType.UNDERLINE) {\n width -= 2 * data.borderStyle.width;\n height -= 2 * data.borderStyle.width;\n }\n\n const horizontalRadius = data.borderStyle.horizontalCornerRadius;\n const verticalRadius = data.borderStyle.verticalCornerRadius;\n\n if (horizontalRadius > 0 || verticalRadius > 0) {\n const radius = `${horizontalRadius}px / ${verticalRadius}px`;\n container.style.borderRadius = radius;\n }\n\n switch (data.borderStyle.style) {\n case _util.AnnotationBorderStyleType.SOLID:\n container.style.borderStyle = "solid";\n break;\n\n case _util.AnnotationBorderStyleType.DASHED:\n container.style.borderStyle = "dashed";\n break;\n\n case _util.AnnotationBorderStyleType.BEVELED:\n (0, _util.warn)("Unimplemented border style: beveled");\n break;\n\n case _util.AnnotationBorderStyleType.INSET:\n (0, _util.warn)("Unimplemented border style: inset");\n break;\n\n case _util.AnnotationBorderStyleType.UNDERLINE:\n container.style.borderBottomStyle = "solid";\n break;\n\n default:\n break;\n }\n\n const borderColor = data.borderColor || data.color || null;\n\n if (borderColor) {\n container.style.borderColor = _util.Util.makeHexColor(data.color[0] | 0, data.color[1] | 0, data.color[2] | 0);\n } else {\n container.style.borderWidth = 0;\n }\n }\n\n container.style.left = `${rect[0]}px`;\n container.style.top = `${rect[1]}px`;\n\n if (data.hasOwnCanvas) {\n container.style.width = container.style.height = "auto";\n } else {\n container.style.width = `${width}px`;\n container.style.height = `${height}px`;\n }\n\n return container;\n }\n\n get _commonActions() {\n const setColor = (jsName, styleName, event) => {\n const color = event.detail[jsName];\n event.target.style[styleName] = _scripting_utils.ColorConverters[`${color[0]}_HTML`](color.slice(1));\n };\n\n return (0, _util.shadow)(this, "_commonActions", {\n display: event => {\n const hidden = event.detail.display % 2 === 1;\n event.target.style.visibility = hidden ? "hidden" : "visible";\n this.annotationStorage.setValue(this.data.id, {\n hidden,\n print: event.detail.display === 0 || event.detail.display === 3\n });\n },\n print: event => {\n this.annotationStorage.setValue(this.data.id, {\n print: event.detail.print\n });\n },\n hidden: event => {\n event.target.style.visibility = event.detail.hidden ? "hidden" : "visible";\n this.annotationStorage.setValue(this.data.id, {\n hidden: event.detail.hidden\n });\n },\n focus: event => {\n setTimeout(() => event.target.focus({\n preventScroll: false\n }), 0);\n },\n userName: event => {\n event.target.title = event.detail.userName;\n },\n readonly: event => {\n if (event.detail.readonly) {\n event.target.setAttribute("readonly", "");\n } else {\n event.target.removeAttribute("readonly");\n }\n },\n required: event => {\n if (event.detail.required) {\n event.target.setAttribute("required", "");\n } else {\n event.target.removeAttribute("required");\n }\n },\n bgColor: event => {\n setColor("bgColor", "backgroundColor", event);\n },\n fillColor: event => {\n setColor("fillColor", "backgroundColor", event);\n },\n fgColor: event => {\n setColor("fgColor", "color", event);\n },\n textColor: event => {\n setColor("textColor", "color", event);\n },\n borderColor: event => {\n setColor("borderColor", "borderColor", event);\n },\n strokeColor: event => {\n setColor("strokeColor", "borderColor", event);\n }\n });\n }\n\n _dispatchEventFromSandbox(actions, jsEvent) {\n const commonActions = this._commonActions;\n\n for (const name of Object.keys(jsEvent.detail)) {\n const action = actions[name] || commonActions[name];\n\n if (action) {\n action(jsEvent);\n }\n }\n }\n\n _setDefaultPropertiesFromJS(element) {\n if (!this.enableScripting) {\n return;\n }\n\n const storedData = this.annotationStorage.getRawValue(this.data.id);\n\n if (!storedData) {\n return;\n }\n\n const commonActions = this._commonActions;\n\n for (const [actionName, detail] of Object.entries(storedData)) {\n const action = commonActions[actionName];\n\n if (action) {\n action({\n detail,\n target: element\n });\n delete storedData[actionName];\n }\n }\n }\n\n _createQuadrilaterals(ignoreBorder = false) {\n if (!this.data.quadPoints) {\n return null;\n }\n\n const quadrilaterals = [];\n const savedRect = this.data.rect;\n\n for (const quadPoint of this.data.quadPoints) {\n this.data.rect = [quadPoint[2].x, quadPoint[2].y, quadPoint[1].x, quadPoint[1].y];\n quadrilaterals.push(this._createContainer(ignoreBorder));\n }\n\n this.data.rect = savedRect;\n return quadrilaterals;\n }\n\n _createPopup(trigger, data) {\n let container = this.container;\n\n if (this.quadrilaterals) {\n trigger = trigger || this.quadrilaterals;\n container = this.quadrilaterals[0];\n }\n\n if (!trigger) {\n trigger = document.createElement("div");\n trigger.style.height = container.style.height;\n trigger.style.width = container.style.width;\n container.appendChild(trigger);\n }\n\n const popupElement = new PopupElement({\n container,\n trigger,\n color: data.color,\n titleObj: data.titleObj,\n modificationDate: data.modificationDate,\n contentsObj: data.contentsObj,\n richText: data.richText,\n hideWrapper: true\n });\n const popup = popupElement.render();\n popup.style.left = container.style.width;\n container.appendChild(popup);\n }\n\n _renderQuadrilaterals(className) {\n for (const quadrilateral of this.quadrilaterals) {\n quadrilateral.className = className;\n }\n\n return this.quadrilaterals;\n }\n\n render() {\n (0, _util.unreachable)("Abstract method `AnnotationElement.render` called");\n }\n\n _getElementsByName(name, skipId = null) {\n const fields = [];\n\n if (this._fieldObjects) {\n const fieldObj = this._fieldObjects[name];\n\n if (fieldObj) {\n for (const {\n page,\n id,\n exportValues\n } of fieldObj) {\n if (page === -1) {\n continue;\n }\n\n if (id === skipId) {\n continue;\n }\n\n const exportValue = typeof exportValues === "string" ? exportValues : null;\n const domElement = document.getElementById(id);\n\n if (domElement && !GetElementsByNameSet.has(domElement)) {\n (0, _util.warn)(`_getElementsByName - element not allowed: ${id}`);\n continue;\n }\n\n fields.push({\n id,\n exportValue,\n domElement\n });\n }\n }\n\n return fields;\n }\n\n for (const domElement of document.getElementsByName(name)) {\n const {\n id,\n exportValue\n } = domElement;\n\n if (id === skipId) {\n continue;\n }\n\n if (!GetElementsByNameSet.has(domElement)) {\n continue;\n }\n\n fields.push({\n id,\n exportValue,\n domElement\n });\n }\n\n return fields;\n }\n\n static get platform() {\n const platform = typeof navigator !== "undefined" ? navigator.platform : "";\n return (0, _util.shadow)(this, "platform", {\n isWin: platform.includes("Win"),\n isMac: platform.includes("Mac")\n });\n }\n\n}\n\nclass LinkAnnotationElement extends AnnotationElement {\n constructor(parameters, options = null) {\n const isRenderable = !!(parameters.data.url || parameters.data.dest || parameters.data.action || parameters.data.isTooltipOnly || parameters.data.resetForm || parameters.data.actions && (parameters.data.actions.Action || parameters.data.actions["Mouse Up"] || parameters.data.actions["Mouse Down"]));\n super(parameters, {\n isRenderable,\n ignoreBorder: !!options?.ignoreBorder,\n createQuadrilaterals: true\n });\n }\n\n render() {\n const {\n data,\n linkService\n } = this;\n const link = document.createElement("a");\n\n if (data.url) {\n linkService.addLinkAttributes(link, data.url, data.newWindow);\n } else if (data.action) {\n this._bindNamedAction(link, data.action);\n } else if (data.dest) {\n this._bindLink(link, data.dest);\n } else {\n let hasClickAction = false;\n\n if (data.actions && (data.actions.Action || data.actions["Mouse Up"] || data.actions["Mouse Down"]) && this.enableScripting && this.hasJSActions) {\n hasClickAction = true;\n\n this._bindJSAction(link, data);\n }\n\n if (data.resetForm) {\n this._bindResetFormAction(link, data.resetForm);\n } else if (!hasClickAction) {\n this._bindLink(link, "");\n }\n }\n\n if (this.quadrilaterals) {\n return this._renderQuadrilaterals("linkAnnotation").map((quadrilateral, index) => {\n const linkElement = index === 0 ? link : link.cloneNode();\n quadrilateral.appendChild(linkElement);\n return quadrilateral;\n });\n }\n\n this.container.className = "linkAnnotation";\n this.container.appendChild(link);\n return this.container;\n }\n\n _bindLink(link, destination) {\n link.href = this.linkService.getDestinationHash(destination);\n\n link.onclick = () => {\n if (destination) {\n this.linkService.goToDestination(destination);\n }\n\n return false;\n };\n\n if (destination || destination === "") {\n link.className = "internalLink";\n }\n }\n\n _bindNamedAction(link, action) {\n link.href = this.linkService.getAnchorUrl("");\n\n link.onclick = () => {\n this.linkService.executeNamedAction(action);\n return false;\n };\n\n link.className = "internalLink";\n }\n\n _bindJSAction(link, data) {\n link.href = this.linkService.getAnchorUrl("");\n const map = new Map([["Action", "onclick"], ["Mouse Up", "onmouseup"], ["Mouse Down", "onmousedown"]]);\n\n for (const name of Object.keys(data.actions)) {\n const jsName = map.get(name);\n\n if (!jsName) {\n continue;\n }\n\n link[jsName] = () => {\n this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {\n source: this,\n detail: {\n id: data.id,\n name\n }\n });\n return false;\n };\n }\n\n if (!link.onclick) {\n link.onclick = () => false;\n }\n\n link.className = "internalLink";\n }\n\n _bindResetFormAction(link, resetForm) {\n const otherClickAction = link.onclick;\n\n if (!otherClickAction) {\n link.href = this.linkService.getAnchorUrl("");\n }\n\n link.className = "internalLink";\n\n if (!this._fieldObjects) {\n (0, _util.warn)(`_bindResetFormAction - "resetForm" action not supported, ` + "ensure that the `fieldObjects` parameter is provided.");\n\n if (!otherClickAction) {\n link.onclick = () => false;\n }\n\n return;\n }\n\n link.onclick = () => {\n if (otherClickAction) {\n otherClickAction();\n }\n\n const {\n fields: resetFormFields,\n refs: resetFormRefs,\n include\n } = resetForm;\n const allFields = [];\n\n if (resetFormFields.length !== 0 || resetFormRefs.length !== 0) {\n const fieldIds = new Set(resetFormRefs);\n\n for (const fieldName of resetFormFields) {\n const fields = this._fieldObjects[fieldName] || [];\n\n for (const {\n id\n } of fields) {\n fieldIds.add(id);\n }\n }\n\n for (const fields of Object.values(this._fieldObjects)) {\n for (const field of fields) {\n if (fieldIds.has(field.id) === include) {\n allFields.push(field);\n }\n }\n }\n } else {\n for (const fields of Object.values(this._fieldObjects)) {\n allFields.push(...fields);\n }\n }\n\n const storage = this.annotationStorage;\n const allIds = [];\n\n for (const field of allFields) {\n const {\n id\n } = field;\n allIds.push(id);\n\n switch (field.type) {\n case "text":\n {\n const value = field.defaultValue || "";\n storage.setValue(id, {\n value\n });\n break;\n }\n\n case "checkbox":\n case "radiobutton":\n {\n const value = field.defaultValue === field.exportValues;\n storage.setValue(id, {\n value\n });\n break;\n }\n\n case "combobox":\n case "listbox":\n {\n const value = field.defaultValue || "";\n storage.setValue(id, {\n value\n });\n break;\n }\n\n default:\n continue;\n }\n\n const domElement = document.getElementById(id);\n\n if (!domElement || !GetElementsByNameSet.has(domElement)) {\n continue;\n }\n\n domElement.dispatchEvent(new Event("resetform"));\n }\n\n if (this.enableScripting) {\n this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {\n source: this,\n detail: {\n id: "app",\n ids: allIds,\n name: "ResetForm"\n }\n });\n }\n\n return false;\n };\n }\n\n}\n\nclass TextAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable\n });\n }\n\n render() {\n this.container.className = "textAnnotation";\n const image = document.createElement("img");\n image.style.height = this.container.style.height;\n image.style.width = this.container.style.width;\n image.src = this.imageResourcesPath + "annotation-" + this.data.name.toLowerCase() + ".svg";\n image.alt = "[{{type}} Annotation]";\n image.dataset.l10nId = "text_annotation_type";\n image.dataset.l10nArgs = JSON.stringify({\n type: this.data.name\n });\n\n if (!this.data.hasPopup) {\n this._createPopup(image, this.data);\n }\n\n this.container.appendChild(image);\n return this.container;\n }\n\n}\n\nclass WidgetAnnotationElement extends AnnotationElement {\n render() {\n if (this.data.alternativeText) {\n this.container.title = this.data.alternativeText;\n }\n\n return this.container;\n }\n\n _getKeyModifier(event) {\n const {\n isWin,\n isMac\n } = AnnotationElement.platform;\n return isWin && event.ctrlKey || isMac && event.metaKey;\n }\n\n _setEventListener(element, baseName, eventName, valueGetter) {\n if (baseName.includes("mouse")) {\n element.addEventListener(baseName, event => {\n this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {\n source: this,\n detail: {\n id: this.data.id,\n name: eventName,\n value: valueGetter(event),\n shift: event.shiftKey,\n modifier: this._getKeyModifier(event)\n }\n });\n });\n } else {\n element.addEventListener(baseName, event => {\n this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {\n source: this,\n detail: {\n id: this.data.id,\n name: eventName,\n value: valueGetter(event)\n }\n });\n });\n }\n }\n\n _setEventListeners(element, names, getter) {\n for (const [baseName, eventName] of names) {\n if (eventName === "Action" || this.data.actions?.[eventName]) {\n this._setEventListener(element, baseName, eventName, getter);\n }\n }\n }\n\n _setBackgroundColor(element) {\n const color = this.data.backgroundColor || null;\n element.style.backgroundColor = color === null ? "transparent" : _util.Util.makeHexColor(color[0], color[1], color[2]);\n }\n\n}\n\nclass TextWidgetAnnotationElement extends WidgetAnnotationElement {\n constructor(parameters) {\n const isRenderable = parameters.renderForms || !parameters.data.hasAppearance && !!parameters.data.fieldValue;\n super(parameters, {\n isRenderable\n });\n }\n\n setPropertyOnSiblings(base, key, value, keyInStorage) {\n const storage = this.annotationStorage;\n\n for (const element of this._getElementsByName(base.name, base.id)) {\n if (element.domElement) {\n element.domElement[key] = value;\n }\n\n storage.setValue(element.id, {\n [keyInStorage]: value\n });\n }\n }\n\n render() {\n const storage = this.annotationStorage;\n const id = this.data.id;\n this.container.className = "textWidgetAnnotation";\n let element = null;\n\n if (this.renderForms) {\n const storedData = storage.getValue(id, {\n value: this.data.fieldValue\n });\n const textContent = storedData.formattedValue || storedData.value || "";\n const elementData = {\n userValue: null,\n formattedValue: null,\n valueOnFocus: ""\n };\n\n if (this.data.multiLine) {\n element = document.createElement("textarea");\n element.textContent = textContent;\n } else {\n element = document.createElement("input");\n element.type = "text";\n element.setAttribute("value", textContent);\n }\n\n GetElementsByNameSet.add(element);\n element.disabled = this.data.readOnly;\n element.name = this.data.fieldName;\n element.tabIndex = DEFAULT_TAB_INDEX;\n elementData.userValue = textContent;\n element.setAttribute("id", id);\n element.addEventListener("input", event => {\n storage.setValue(id, {\n value: event.target.value\n });\n this.setPropertyOnSiblings(element, "value", event.target.value, "value");\n });\n element.addEventListener("resetform", event => {\n const defaultValue = this.data.defaultFieldValue ?? "";\n element.value = elementData.userValue = defaultValue;\n elementData.formattedValue = null;\n });\n\n let blurListener = event => {\n const {\n formattedValue\n } = elementData;\n\n if (formattedValue !== null && formattedValue !== undefined) {\n event.target.value = formattedValue;\n }\n\n event.target.scrollLeft = 0;\n };\n\n if (this.enableScripting && this.hasJSActions) {\n element.addEventListener("focus", event => {\n if (elementData.userValue) {\n event.target.value = elementData.userValue;\n }\n\n elementData.valueOnFocus = event.target.value;\n });\n element.addEventListener("updatefromsandbox", jsEvent => {\n const actions = {\n value(event) {\n elementData.userValue = event.detail.value ?? "";\n storage.setValue(id, {\n value: elementData.userValue.toString()\n });\n event.target.value = elementData.userValue;\n },\n\n formattedValue(event) {\n const {\n formattedValue\n } = event.detail;\n elementData.formattedValue = formattedValue;\n\n if (formattedValue !== null && formattedValue !== undefined && event.target !== document.activeElement) {\n event.target.value = formattedValue;\n }\n\n storage.setValue(id, {\n formattedValue\n });\n },\n\n selRange(event) {\n event.target.setSelectionRange(...event.detail.selRange);\n }\n\n };\n\n this._dispatchEventFromSandbox(actions, jsEvent);\n });\n element.addEventListener("keydown", event => {\n let commitKey = -1;\n\n if (event.key === "Escape") {\n commitKey = 0;\n } else if (event.key === "Enter") {\n commitKey = 2;\n } else if (event.key === "Tab") {\n commitKey = 3;\n }\n\n if (commitKey === -1) {\n return;\n }\n\n const {\n value\n } = event.target;\n\n if (elementData.valueOnFocus === value) {\n return;\n }\n\n elementData.userValue = value;\n this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {\n source: this,\n detail: {\n id,\n name: "Keystroke",\n value,\n willCommit: true,\n commitKey,\n selStart: event.target.selectionStart,\n selEnd: event.target.selectionEnd\n }\n });\n });\n const _blurListener = blurListener;\n blurListener = null;\n element.addEventListener("blur", event => {\n const {\n value\n } = event.target;\n elementData.userValue = value;\n\n if (this._mouseState.isDown && elementData.valueOnFocus !== value) {\n this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {\n source: this,\n detail: {\n id,\n name: "Keystroke",\n value,\n willCommit: true,\n commitKey: 1,\n selStart: event.target.selectionStart,\n selEnd: event.target.selectionEnd\n }\n });\n }\n\n _blurListener(event);\n });\n\n if (this.data.actions?.Keystroke) {\n element.addEventListener("beforeinput", event => {\n const {\n data,\n target\n } = event;\n const {\n value,\n selectionStart,\n selectionEnd\n } = target;\n let selStart = selectionStart,\n selEnd = selectionEnd;\n\n switch (event.inputType) {\n case "deleteWordBackward":\n {\n const match = value.substring(0, selectionStart).match(/\\w*[^\\w]*$/);\n\n if (match) {\n selStart -= match[0].length;\n }\n\n break;\n }\n\n case "deleteWordForward":\n {\n const match = value.substring(selectionStart).match(/^[^\\w]*\\w*/);\n\n if (match) {\n selEnd += match[0].length;\n }\n\n break;\n }\n\n case "deleteContentBackward":\n if (selectionStart === selectionEnd) {\n selStart -= 1;\n }\n\n break;\n\n case "deleteContentForward":\n if (selectionStart === selectionEnd) {\n selEnd += 1;\n }\n\n break;\n }\n\n event.preventDefault();\n this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {\n source: this,\n detail: {\n id,\n name: "Keystroke",\n value,\n change: data || "",\n willCommit: false,\n selStart,\n selEnd\n }\n });\n });\n }\n\n this._setEventListeners(element, [["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.value);\n }\n\n if (blurListener) {\n element.addEventListener("blur", blurListener);\n }\n\n if (this.data.maxLen !== null) {\n element.maxLength = this.data.maxLen;\n }\n\n if (this.data.comb) {\n const fieldWidth = this.data.rect[2] - this.data.rect[0];\n const combWidth = fieldWidth / this.data.maxLen;\n element.classList.add("comb");\n element.style.letterSpacing = `calc(${combWidth}px - 1ch)`;\n }\n } else {\n element = document.createElement("div");\n element.textContent = this.data.fieldValue;\n element.style.verticalAlign = "middle";\n element.style.display = "table-cell";\n }\n\n this._setTextStyle(element);\n\n this._setBackgroundColor(element);\n\n this._setDefaultPropertiesFromJS(element);\n\n this.container.appendChild(element);\n return this.container;\n }\n\n _setTextStyle(element) {\n const TEXT_ALIGNMENT = ["left", "center", "right"];\n const {\n fontSize,\n fontColor\n } = this.data.defaultAppearanceData;\n const style = element.style;\n\n if (fontSize) {\n style.fontSize = `${fontSize}px`;\n }\n\n style.color = _util.Util.makeHexColor(fontColor[0], fontColor[1], fontColor[2]);\n\n if (this.data.textAlignment !== null) {\n style.textAlign = TEXT_ALIGNMENT[this.data.textAlignment];\n }\n }\n\n}\n\nclass CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {\n constructor(parameters) {\n super(parameters, {\n isRenderable: parameters.renderForms\n });\n }\n\n render() {\n const storage = this.annotationStorage;\n const data = this.data;\n const id = data.id;\n let value = storage.getValue(id, {\n value: data.exportValue === data.fieldValue\n }).value;\n\n if (typeof value === "string") {\n value = value !== "Off";\n storage.setValue(id, {\n value\n });\n }\n\n this.container.className = "buttonWidgetAnnotation checkBox";\n const element = document.createElement("input");\n GetElementsByNameSet.add(element);\n element.disabled = data.readOnly;\n element.type = "checkbox";\n element.name = data.fieldName;\n\n if (value) {\n element.setAttribute("checked", true);\n }\n\n element.setAttribute("id", id);\n element.setAttribute("exportValue", data.exportValue);\n element.tabIndex = DEFAULT_TAB_INDEX;\n element.addEventListener("change", event => {\n const {\n name,\n checked\n } = event.target;\n\n for (const checkbox of this._getElementsByName(name, id)) {\n const curChecked = checked && checkbox.exportValue === data.exportValue;\n\n if (checkbox.domElement) {\n checkbox.domElement.checked = curChecked;\n }\n\n storage.setValue(checkbox.id, {\n value: curChecked\n });\n }\n\n storage.setValue(id, {\n value: checked\n });\n });\n element.addEventListener("resetform", event => {\n const defaultValue = data.defaultFieldValue || "Off";\n event.target.checked = defaultValue === data.exportValue;\n });\n\n if (this.enableScripting && this.hasJSActions) {\n element.addEventListener("updatefromsandbox", jsEvent => {\n const actions = {\n value(event) {\n event.target.checked = event.detail.value !== "Off";\n storage.setValue(id, {\n value: event.target.checked\n });\n }\n\n };\n\n this._dispatchEventFromSandbox(actions, jsEvent);\n });\n\n this._setEventListeners(element, [["change", "Validate"], ["change", "Action"], ["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.checked);\n }\n\n this._setBackgroundColor(element);\n\n this._setDefaultPropertiesFromJS(element);\n\n this.container.appendChild(element);\n return this.container;\n }\n\n}\n\nclass RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {\n constructor(parameters) {\n super(parameters, {\n isRenderable: parameters.renderForms\n });\n }\n\n render() {\n this.container.className = "buttonWidgetAnnotation radioButton";\n const storage = this.annotationStorage;\n const data = this.data;\n const id = data.id;\n let value = storage.getValue(id, {\n value: data.fieldValue === data.buttonValue\n }).value;\n\n if (typeof value === "string") {\n value = value !== data.buttonValue;\n storage.setValue(id, {\n value\n });\n }\n\n const element = document.createElement("input");\n GetElementsByNameSet.add(element);\n element.disabled = data.readOnly;\n element.type = "radio";\n element.name = data.fieldName;\n\n if (value) {\n element.setAttribute("checked", true);\n }\n\n element.setAttribute("id", id);\n element.tabIndex = DEFAULT_TAB_INDEX;\n element.addEventListener("change", event => {\n const {\n name,\n checked\n } = event.target;\n\n for (const radio of this._getElementsByName(name, id)) {\n storage.setValue(radio.id, {\n value: false\n });\n }\n\n storage.setValue(id, {\n value: checked\n });\n });\n element.addEventListener("resetform", event => {\n const defaultValue = data.defaultFieldValue;\n event.target.checked = defaultValue !== null && defaultValue !== undefined && defaultValue === data.buttonValue;\n });\n\n if (this.enableScripting && this.hasJSActions) {\n const pdfButtonValue = data.buttonValue;\n element.addEventListener("updatefromsandbox", jsEvent => {\n const actions = {\n value: event => {\n const checked = pdfButtonValue === event.detail.value;\n\n for (const radio of this._getElementsByName(event.target.name)) {\n const curChecked = checked && radio.id === id;\n\n if (radio.domElement) {\n radio.domElement.checked = curChecked;\n }\n\n storage.setValue(radio.id, {\n value: curChecked\n });\n }\n }\n };\n\n this._dispatchEventFromSandbox(actions, jsEvent);\n });\n\n this._setEventListeners(element, [["change", "Validate"], ["change", "Action"], ["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.checked);\n }\n\n this._setBackgroundColor(element);\n\n this._setDefaultPropertiesFromJS(element);\n\n this.container.appendChild(element);\n return this.container;\n }\n\n}\n\nclass PushButtonWidgetAnnotationElement extends LinkAnnotationElement {\n constructor(parameters) {\n super(parameters, {\n ignoreBorder: parameters.data.hasAppearance\n });\n }\n\n render() {\n const container = super.render();\n container.className = "buttonWidgetAnnotation pushButton";\n\n if (this.data.alternativeText) {\n container.title = this.data.alternativeText;\n }\n\n this._setDefaultPropertiesFromJS(container);\n\n return container;\n }\n\n}\n\nclass ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {\n constructor(parameters) {\n super(parameters, {\n isRenderable: parameters.renderForms\n });\n }\n\n render() {\n this.container.className = "choiceWidgetAnnotation";\n const storage = this.annotationStorage;\n const id = this.data.id;\n const storedData = storage.getValue(id, {\n value: this.data.fieldValue\n });\n let {\n fontSize\n } = this.data.defaultAppearanceData;\n\n if (!fontSize) {\n fontSize = 9;\n }\n\n const fontSizeStyle = `calc(${fontSize}px * var(--zoom-factor))`;\n const selectElement = document.createElement("select");\n GetElementsByNameSet.add(selectElement);\n selectElement.disabled = this.data.readOnly;\n selectElement.name = this.data.fieldName;\n selectElement.setAttribute("id", id);\n selectElement.tabIndex = DEFAULT_TAB_INDEX;\n selectElement.style.fontSize = `${fontSize}px`;\n\n if (!this.data.combo) {\n selectElement.size = this.data.options.length;\n\n if (this.data.multiSelect) {\n selectElement.multiple = true;\n }\n }\n\n selectElement.addEventListener("resetform", event => {\n const defaultValue = this.data.defaultFieldValue;\n\n for (const option of selectElement.options) {\n option.selected = option.value === defaultValue;\n }\n });\n\n for (const option of this.data.options) {\n const optionElement = document.createElement("option");\n optionElement.textContent = option.displayValue;\n optionElement.value = option.exportValue;\n\n if (this.data.combo) {\n optionElement.style.fontSize = fontSizeStyle;\n }\n\n if (storedData.value.includes(option.exportValue)) {\n optionElement.setAttribute("selected", true);\n }\n\n selectElement.appendChild(optionElement);\n }\n\n const getValue = (event, isExport) => {\n const name = isExport ? "value" : "textContent";\n const options = event.target.options;\n\n if (!event.target.multiple) {\n return options.selectedIndex === -1 ? null : options[options.selectedIndex][name];\n }\n\n return Array.prototype.filter.call(options, option => option.selected).map(option => option[name]);\n };\n\n const getItems = event => {\n const options = event.target.options;\n return Array.prototype.map.call(options, option => {\n return {\n displayValue: option.textContent,\n exportValue: option.value\n };\n });\n };\n\n if (this.enableScripting && this.hasJSActions) {\n selectElement.addEventListener("updatefromsandbox", jsEvent => {\n const actions = {\n value(event) {\n const value = event.detail.value;\n const values = new Set(Array.isArray(value) ? value : [value]);\n\n for (const option of selectElement.options) {\n option.selected = values.has(option.value);\n }\n\n storage.setValue(id, {\n value: getValue(event, true)\n });\n },\n\n multipleSelection(event) {\n selectElement.multiple = true;\n },\n\n remove(event) {\n const options = selectElement.options;\n const index = event.detail.remove;\n options[index].selected = false;\n selectElement.remove(index);\n\n if (options.length > 0) {\n const i = Array.prototype.findIndex.call(options, option => option.selected);\n\n if (i === -1) {\n options[0].selected = true;\n }\n }\n\n storage.setValue(id, {\n value: getValue(event, true),\n items: getItems(event)\n });\n },\n\n clear(event) {\n while (selectElement.length !== 0) {\n selectElement.remove(0);\n }\n\n storage.setValue(id, {\n value: null,\n items: []\n });\n },\n\n insert(event) {\n const {\n index,\n displayValue,\n exportValue\n } = event.detail.insert;\n const optionElement = document.createElement("option");\n optionElement.textContent = displayValue;\n optionElement.value = exportValue;\n selectElement.insertBefore(optionElement, selectElement.children[index]);\n storage.setValue(id, {\n value: getValue(event, true),\n items: getItems(event)\n });\n },\n\n items(event) {\n const {\n items\n } = event.detail;\n\n while (selectElement.length !== 0) {\n selectElement.remove(0);\n }\n\n for (const item of items) {\n const {\n displayValue,\n exportValue\n } = item;\n const optionElement = document.createElement("option");\n optionElement.textContent = displayValue;\n optionElement.value = exportValue;\n selectElement.appendChild(optionElement);\n }\n\n if (selectElement.options.length > 0) {\n selectElement.options[0].selected = true;\n }\n\n storage.setValue(id, {\n value: getValue(event, true),\n items: getItems(event)\n });\n },\n\n indices(event) {\n const indices = new Set(event.detail.indices);\n\n for (const option of event.target.options) {\n option.selected = indices.has(option.index);\n }\n\n storage.setValue(id, {\n value: getValue(event, true)\n });\n },\n\n editable(event) {\n event.target.disabled = !event.detail.editable;\n }\n\n };\n\n this._dispatchEventFromSandbox(actions, jsEvent);\n });\n selectElement.addEventListener("input", event => {\n const exportValue = getValue(event, true);\n const value = getValue(event, false);\n storage.setValue(id, {\n value: exportValue\n });\n this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {\n source: this,\n detail: {\n id,\n name: "Keystroke",\n value,\n changeEx: exportValue,\n willCommit: true,\n commitKey: 1,\n keyDown: false\n }\n });\n });\n\n this._setEventListeners(selectElement, [["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"], ["input", "Action"]], event => event.target.checked);\n } else {\n selectElement.addEventListener("input", function (event) {\n storage.setValue(id, {\n value: getValue(event, true)\n });\n });\n }\n\n this._setBackgroundColor(selectElement);\n\n this._setDefaultPropertiesFromJS(selectElement);\n\n this.container.appendChild(selectElement);\n return this.container;\n }\n\n}\n\nclass PopupAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable\n });\n }\n\n render() {\n const IGNORE_TYPES = ["Line", "Square", "Circle", "PolyLine", "Polygon", "Ink"];\n this.container.className = "popupAnnotation";\n\n if (IGNORE_TYPES.includes(this.data.parentType)) {\n return this.container;\n }\n\n const selector = `[data-annotation-id="${this.data.parentId}"]`;\n const parentElements = this.layer.querySelectorAll(selector);\n\n if (parentElements.length === 0) {\n return this.container;\n }\n\n const popup = new PopupElement({\n container: this.container,\n trigger: Array.from(parentElements),\n color: this.data.color,\n titleObj: this.data.titleObj,\n modificationDate: this.data.modificationDate,\n contentsObj: this.data.contentsObj,\n richText: this.data.richText\n });\n const page = this.page;\n\n const rect = _util.Util.normalizeRect([this.data.parentRect[0], page.view[3] - this.data.parentRect[1] + page.view[1], this.data.parentRect[2], page.view[3] - this.data.parentRect[3] + page.view[1]]);\n\n const popupLeft = rect[0] + this.data.parentRect[2] - this.data.parentRect[0];\n const popupTop = rect[1];\n this.container.style.transformOrigin = `${-popupLeft}px ${-popupTop}px`;\n this.container.style.left = `${popupLeft}px`;\n this.container.style.top = `${popupTop}px`;\n this.container.appendChild(popup.render());\n return this.container;\n }\n\n}\n\nclass PopupElement {\n constructor(parameters) {\n this.container = parameters.container;\n this.trigger = parameters.trigger;\n this.color = parameters.color;\n this.titleObj = parameters.titleObj;\n this.modificationDate = parameters.modificationDate;\n this.contentsObj = parameters.contentsObj;\n this.richText = parameters.richText;\n this.hideWrapper = parameters.hideWrapper || false;\n this.pinned = false;\n }\n\n render() {\n const BACKGROUND_ENLIGHT = 0.7;\n const wrapper = document.createElement("div");\n wrapper.className = "popupWrapper";\n this.hideElement = this.hideWrapper ? wrapper : this.container;\n this.hideElement.hidden = true;\n const popup = document.createElement("div");\n popup.className = "popup";\n const color = this.color;\n\n if (color) {\n const r = BACKGROUND_ENLIGHT * (255 - color[0]) + color[0];\n const g = BACKGROUND_ENLIGHT * (255 - color[1]) + color[1];\n const b = BACKGROUND_ENLIGHT * (255 - color[2]) + color[2];\n popup.style.backgroundColor = _util.Util.makeHexColor(r | 0, g | 0, b | 0);\n }\n\n const title = document.createElement("h1");\n title.dir = this.titleObj.dir;\n title.textContent = this.titleObj.str;\n popup.appendChild(title);\n\n const dateObject = _display_utils.PDFDateString.toDateObject(this.modificationDate);\n\n if (dateObject) {\n const modificationDate = document.createElement("span");\n modificationDate.className = "popupDate";\n modificationDate.textContent = "{{date}}, {{time}}";\n modificationDate.dataset.l10nId = "annotation_date_string";\n modificationDate.dataset.l10nArgs = JSON.stringify({\n date: dateObject.toLocaleDateString(),\n time: dateObject.toLocaleTimeString()\n });\n popup.appendChild(modificationDate);\n }\n\n if (this.richText?.str && (!this.contentsObj?.str || this.contentsObj.str === this.richText.str)) {\n _xfa_layer.XfaLayer.render({\n xfaHtml: this.richText.html,\n intent: "richText",\n div: popup\n });\n\n popup.lastChild.className = "richText popupContent";\n } else {\n const contents = this._formatContents(this.contentsObj);\n\n popup.appendChild(contents);\n }\n\n if (!Array.isArray(this.trigger)) {\n this.trigger = [this.trigger];\n }\n\n for (const element of this.trigger) {\n element.addEventListener("click", this._toggle.bind(this));\n element.addEventListener("mouseover", this._show.bind(this, false));\n element.addEventListener("mouseout", this._hide.bind(this, false));\n }\n\n popup.addEventListener("click", this._hide.bind(this, true));\n wrapper.appendChild(popup);\n return wrapper;\n }\n\n _formatContents({\n str,\n dir\n }) {\n const p = document.createElement("p");\n p.className = "popupContent";\n p.dir = dir;\n const lines = str.split(/(?:\\r\\n?|\\n)/);\n\n for (let i = 0, ii = lines.length; i < ii; ++i) {\n const line = lines[i];\n p.appendChild(document.createTextNode(line));\n\n if (i < ii - 1) {\n p.appendChild(document.createElement("br"));\n }\n }\n\n return p;\n }\n\n _toggle() {\n if (this.pinned) {\n this._hide(true);\n } else {\n this._show(true);\n }\n }\n\n _show(pin = false) {\n if (pin) {\n this.pinned = true;\n }\n\n if (this.hideElement.hidden) {\n this.hideElement.hidden = false;\n this.container.style.zIndex += 1;\n }\n }\n\n _hide(unpin = true) {\n if (unpin) {\n this.pinned = false;\n }\n\n if (!this.hideElement.hidden && !this.pinned) {\n this.hideElement.hidden = true;\n this.container.style.zIndex -= 1;\n }\n }\n\n}\n\nclass FreeTextAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true\n });\n }\n\n render() {\n this.container.className = "freeTextAnnotation";\n\n if (!this.data.hasPopup) {\n this._createPopup(null, this.data);\n }\n\n return this.container;\n }\n\n}\n\nclass LineAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true\n });\n }\n\n render() {\n this.container.className = "lineAnnotation";\n const data = this.data;\n const {\n width,\n height\n } = getRectDims(data.rect);\n const svg = this.svgFactory.create(width, height);\n const line = this.svgFactory.createElement("svg:line");\n line.setAttribute("x1", data.rect[2] - data.lineCoordinates[0]);\n line.setAttribute("y1", data.rect[3] - data.lineCoordinates[1]);\n line.setAttribute("x2", data.rect[2] - data.lineCoordinates[2]);\n line.setAttribute("y2", data.rect[3] - data.lineCoordinates[3]);\n line.setAttribute("stroke-width", data.borderStyle.width || 1);\n line.setAttribute("stroke", "transparent");\n line.setAttribute("fill", "transparent");\n svg.appendChild(line);\n this.container.append(svg);\n\n this._createPopup(line, data);\n\n return this.container;\n }\n\n}\n\nclass SquareAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true\n });\n }\n\n render() {\n this.container.className = "squareAnnotation";\n const data = this.data;\n const {\n width,\n height\n } = getRectDims(data.rect);\n const svg = this.svgFactory.create(width, height);\n const borderWidth = data.borderStyle.width;\n const square = this.svgFactory.createElement("svg:rect");\n square.setAttribute("x", borderWidth / 2);\n square.setAttribute("y", borderWidth / 2);\n square.setAttribute("width", width - borderWidth);\n square.setAttribute("height", height - borderWidth);\n square.setAttribute("stroke-width", borderWidth || 1);\n square.setAttribute("stroke", "transparent");\n square.setAttribute("fill", "transparent");\n svg.appendChild(square);\n this.container.append(svg);\n\n this._createPopup(square, data);\n\n return this.container;\n }\n\n}\n\nclass CircleAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true\n });\n }\n\n render() {\n this.container.className = "circleAnnotation";\n const data = this.data;\n const {\n width,\n height\n } = getRectDims(data.rect);\n const svg = this.svgFactory.create(width, height);\n const borderWidth = data.borderStyle.width;\n const circle = this.svgFactory.createElement("svg:ellipse");\n circle.setAttribute("cx", width / 2);\n circle.setAttribute("cy", height / 2);\n circle.setAttribute("rx", width / 2 - borderWidth / 2);\n circle.setAttribute("ry", height / 2 - borderWidth / 2);\n circle.setAttribute("stroke-width", borderWidth || 1);\n circle.setAttribute("stroke", "transparent");\n circle.setAttribute("fill", "transparent");\n svg.appendChild(circle);\n this.container.append(svg);\n\n this._createPopup(circle, data);\n\n return this.container;\n }\n\n}\n\nclass PolylineAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true\n });\n this.containerClassName = "polylineAnnotation";\n this.svgElementName = "svg:polyline";\n }\n\n render() {\n this.container.className = this.containerClassName;\n const data = this.data;\n const {\n width,\n height\n } = getRectDims(data.rect);\n const svg = this.svgFactory.create(width, height);\n let points = [];\n\n for (const coordinate of data.vertices) {\n const x = coordinate.x - data.rect[0];\n const y = data.rect[3] - coordinate.y;\n points.push(x + "," + y);\n }\n\n points = points.join(" ");\n const polyline = this.svgFactory.createElement(this.svgElementName);\n polyline.setAttribute("points", points);\n polyline.setAttribute("stroke-width", data.borderStyle.width || 1);\n polyline.setAttribute("stroke", "transparent");\n polyline.setAttribute("fill", "transparent");\n svg.appendChild(polyline);\n this.container.append(svg);\n\n this._createPopup(polyline, data);\n\n return this.container;\n }\n\n}\n\nclass PolygonAnnotationElement extends PolylineAnnotationElement {\n constructor(parameters) {\n super(parameters);\n this.containerClassName = "polygonAnnotation";\n this.svgElementName = "svg:polygon";\n }\n\n}\n\nclass CaretAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true\n });\n }\n\n render() {\n this.container.className = "caretAnnotation";\n\n if (!this.data.hasPopup) {\n this._createPopup(null, this.data);\n }\n\n return this.container;\n }\n\n}\n\nclass InkAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true\n });\n this.containerClassName = "inkAnnotation";\n this.svgElementName = "svg:polyline";\n }\n\n render() {\n this.container.className = this.containerClassName;\n const data = this.data;\n const {\n width,\n height\n } = getRectDims(data.rect);\n const svg = this.svgFactory.create(width, height);\n\n for (const inkList of data.inkLists) {\n let points = [];\n\n for (const coordinate of inkList) {\n const x = coordinate.x - data.rect[0];\n const y = data.rect[3] - coordinate.y;\n points.push(`${x},${y}`);\n }\n\n points = points.join(" ");\n const polyline = this.svgFactory.createElement(this.svgElementName);\n polyline.setAttribute("points", points);\n polyline.setAttribute("stroke-width", data.borderStyle.width || 1);\n polyline.setAttribute("stroke", "transparent");\n polyline.setAttribute("fill", "transparent");\n\n this._createPopup(polyline, data);\n\n svg.appendChild(polyline);\n }\n\n this.container.append(svg);\n return this.container;\n }\n\n}\n\nclass HighlightAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true,\n createQuadrilaterals: true\n });\n }\n\n render() {\n if (!this.data.hasPopup) {\n this._createPopup(null, this.data);\n }\n\n if (this.quadrilaterals) {\n return this._renderQuadrilaterals("highlightAnnotation");\n }\n\n this.container.className = "highlightAnnotation";\n return this.container;\n }\n\n}\n\nclass UnderlineAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true,\n createQuadrilaterals: true\n });\n }\n\n render() {\n if (!this.data.hasPopup) {\n this._createPopup(null, this.data);\n }\n\n if (this.quadrilaterals) {\n return this._renderQuadrilaterals("underlineAnnotation");\n }\n\n this.container.className = "underlineAnnotation";\n return this.container;\n }\n\n}\n\nclass SquigglyAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true,\n createQuadrilaterals: true\n });\n }\n\n render() {\n if (!this.data.hasPopup) {\n this._createPopup(null, this.data);\n }\n\n if (this.quadrilaterals) {\n return this._renderQuadrilaterals("squigglyAnnotation");\n }\n\n this.container.className = "squigglyAnnotation";\n return this.container;\n }\n\n}\n\nclass StrikeOutAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true,\n createQuadrilaterals: true\n });\n }\n\n render() {\n if (!this.data.hasPopup) {\n this._createPopup(null, this.data);\n }\n\n if (this.quadrilaterals) {\n return this._renderQuadrilaterals("strikeoutAnnotation");\n }\n\n this.container.className = "strikeoutAnnotation";\n return this.container;\n }\n\n}\n\nclass StampAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true\n });\n }\n\n render() {\n this.container.className = "stampAnnotation";\n\n if (!this.data.hasPopup) {\n this._createPopup(null, this.data);\n }\n\n return this.container;\n }\n\n}\n\nclass FileAttachmentAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n super(parameters, {\n isRenderable: true\n });\n const {\n filename,\n content\n } = this.data.file;\n this.filename = (0, _display_utils.getFilenameFromUrl)(filename);\n this.content = content;\n this.linkService.eventBus?.dispatch("fileattachmentannotation", {\n source: this,\n filename,\n content\n });\n }\n\n render() {\n this.container.className = "fileAttachmentAnnotation";\n const trigger = document.createElement("div");\n trigger.style.height = this.container.style.height;\n trigger.style.width = this.container.style.width;\n trigger.addEventListener("dblclick", this._download.bind(this));\n\n if (!this.data.hasPopup && (this.data.titleObj?.str || this.data.contentsObj?.str || this.data.richText)) {\n this._createPopup(trigger, this.data);\n }\n\n this.container.appendChild(trigger);\n return this.container;\n }\n\n _download() {\n this.downloadManager?.openOrDownloadData(this.container, this.content, this.filename);\n }\n\n}\n\nclass AnnotationLayer {\n static render(parameters) {\n const sortedAnnotations = [],\n popupAnnotations = [];\n\n for (const data of parameters.annotations) {\n if (!data) {\n continue;\n }\n\n const {\n width,\n height\n } = getRectDims(data.rect);\n\n if (width <= 0 || height <= 0) {\n continue;\n }\n\n if (data.annotationType === _util.AnnotationType.POPUP) {\n popupAnnotations.push(data);\n continue;\n }\n\n sortedAnnotations.push(data);\n }\n\n if (popupAnnotations.length) {\n sortedAnnotations.push(...popupAnnotations);\n }\n\n const div = parameters.div;\n\n for (const data of sortedAnnotations) {\n const element = AnnotationElementFactory.create({\n data,\n layer: div,\n page: parameters.page,\n viewport: parameters.viewport,\n linkService: parameters.linkService,\n downloadManager: parameters.downloadManager,\n imageResourcesPath: parameters.imageResourcesPath || "",\n renderForms: parameters.renderForms !== false,\n svgFactory: new _display_utils.DOMSVGFactory(),\n annotationStorage: parameters.annotationStorage || new _annotation_storage.AnnotationStorage(),\n enableScripting: parameters.enableScripting,\n hasJSActions: parameters.hasJSActions,\n fieldObjects: parameters.fieldObjects,\n mouseState: parameters.mouseState || {\n isDown: false\n }\n });\n\n if (element.isRenderable) {\n const rendered = element.render();\n\n if (data.hidden) {\n rendered.style.visibility = "hidden";\n }\n\n if (Array.isArray(rendered)) {\n for (const renderedElement of rendered) {\n div.appendChild(renderedElement);\n }\n } else {\n if (element instanceof PopupAnnotationElement) {\n div.prepend(rendered);\n } else {\n div.appendChild(rendered);\n }\n }\n }\n }\n\n this.#setAnnotationCanvasMap(div, parameters.annotationCanvasMap);\n }\n\n static update(parameters) {\n const {\n page,\n viewport,\n annotations,\n annotationCanvasMap,\n div\n } = parameters;\n const transform = viewport.transform;\n const matrix = `matrix(${transform.join(",")})`;\n let scale, ownMatrix;\n\n for (const data of annotations) {\n const elements = div.querySelectorAll(`[data-annotation-id="${data.id}"]`);\n\n if (elements) {\n for (const element of elements) {\n if (data.hasOwnCanvas) {\n const rect = _util.Util.normalizeRect([data.rect[0], page.view[3] - data.rect[1] + page.view[1], data.rect[2], page.view[3] - data.rect[3] + page.view[1]]);\n\n if (!ownMatrix) {\n scale = Math.abs(transform[0] || transform[1]);\n const ownTransform = transform.slice();\n\n for (let i = 0; i < 4; i++) {\n ownTransform[i] = Math.sign(ownTransform[i]);\n }\n\n ownMatrix = `matrix(${ownTransform.join(",")})`;\n }\n\n const left = rect[0] * scale;\n const top = rect[1] * scale;\n element.style.left = `${left}px`;\n element.style.top = `${top}px`;\n element.style.transformOrigin = `${-left}px ${-top}px`;\n element.style.transform = ownMatrix;\n } else {\n element.style.transform = matrix;\n }\n }\n }\n }\n\n this.#setAnnotationCanvasMap(div, annotationCanvasMap);\n div.hidden = false;\n }\n\n static #setAnnotationCanvasMap(div, annotationCanvasMap) {\n if (!annotationCanvasMap) {\n return;\n }\n\n for (const [id, canvas] of annotationCanvasMap) {\n const element = div.querySelector(`[data-annotation-id="${id}"]`);\n\n if (!element) {\n continue;\n }\n\n const {\n firstChild\n } = element;\n\n if (firstChild.nodeName === "CANVAS") {\n element.replaceChild(canvas, firstChild);\n } else {\n element.insertBefore(canvas, firstChild);\n }\n }\n\n annotationCanvasMap.clear();\n }\n\n}\n\nexports.AnnotationLayer = AnnotationLayer;\n\n/***/ }),\n/* 21 */\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.ColorConverters = void 0;\n\nfunction makeColorComp(n) {\n return Math.floor(Math.max(0, Math.min(1, n)) * 255).toString(16).padStart(2, "0");\n}\n\nclass ColorConverters {\n static CMYK_G([c, y, m, k]) {\n return ["G", 1 - Math.min(1, 0.3 * c + 0.59 * m + 0.11 * y + k)];\n }\n\n static G_CMYK([g]) {\n return ["CMYK", 0, 0, 0, 1 - g];\n }\n\n static G_RGB([g]) {\n return ["RGB", g, g, g];\n }\n\n static G_HTML([g]) {\n const G = makeColorComp(g);\n return `#${G}${G}${G}`;\n }\n\n static RGB_G([r, g, b]) {\n return ["G", 0.3 * r + 0.59 * g + 0.11 * b];\n }\n\n static RGB_HTML([r, g, b]) {\n const R = makeColorComp(r);\n const G = makeColorComp(g);\n const B = makeColorComp(b);\n return `#${R}${G}${B}`;\n }\n\n static T_HTML() {\n return "#00000000";\n }\n\n static CMYK_RGB([c, y, m, k]) {\n return ["RGB", 1 - Math.min(1, c + k), 1 - Math.min(1, m + k), 1 - Math.min(1, y + k)];\n }\n\n static CMYK_HTML(components) {\n return this.RGB_HTML(this.CMYK_RGB(components));\n }\n\n static RGB_CMYK([r, g, b]) {\n const c = 1 - r;\n const m = 1 - g;\n const y = 1 - b;\n const k = Math.min(c, m, y);\n return ["CMYK", c, m, y, k];\n }\n\n}\n\nexports.ColorConverters = ColorConverters;\n\n/***/ }),\n/* 22 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.XfaLayer = void 0;\n\nvar _xfa_text = __w_pdfjs_require__(18);\n\nclass XfaLayer {\n static setupStorage(html, id, element, storage, intent) {\n const storedData = storage.getValue(id, {\n value: null\n });\n\n switch (element.name) {\n case "textarea":\n if (storedData.value !== null) {\n html.textContent = storedData.value;\n }\n\n if (intent === "print") {\n break;\n }\n\n html.addEventListener("input", event => {\n storage.setValue(id, {\n value: event.target.value\n });\n });\n break;\n\n case "input":\n if (element.attributes.type === "radio" || element.attributes.type === "checkbox") {\n if (storedData.value === element.attributes.xfaOn) {\n html.setAttribute("checked", true);\n } else if (storedData.value === element.attributes.xfaOff) {\n html.removeAttribute("checked");\n }\n\n if (intent === "print") {\n break;\n }\n\n html.addEventListener("change", event => {\n storage.setValue(id, {\n value: event.target.checked ? event.target.getAttribute("xfaOn") : event.target.getAttribute("xfaOff")\n });\n });\n } else {\n if (storedData.value !== null) {\n html.setAttribute("value", storedData.value);\n }\n\n if (intent === "print") {\n break;\n }\n\n html.addEventListener("input", event => {\n storage.setValue(id, {\n value: event.target.value\n });\n });\n }\n\n break;\n\n case "select":\n if (storedData.value !== null) {\n for (const option of element.children) {\n if (option.attributes.value === storedData.value) {\n option.attributes.selected = true;\n }\n }\n }\n\n html.addEventListener("input", event => {\n const options = event.target.options;\n const value = options.selectedIndex === -1 ? "" : options[options.selectedIndex].value;\n storage.setValue(id, {\n value\n });\n });\n break;\n }\n }\n\n static setAttributes({\n html,\n element,\n storage = null,\n intent,\n linkService\n }) {\n const {\n attributes\n } = element;\n const isHTMLAnchorElement = html instanceof HTMLAnchorElement;\n\n if (attributes.type === "radio") {\n attributes.name = `${attributes.name}-${intent}`;\n }\n\n for (const [key, value] of Object.entries(attributes)) {\n if (value === null || value === undefined || key === "dataId") {\n continue;\n }\n\n if (key !== "style") {\n if (key === "textContent") {\n html.textContent = value;\n } else if (key === "class") {\n if (value.length) {\n html.setAttribute(key, value.join(" "));\n }\n } else {\n if (isHTMLAnchorElement && (key === "href" || key === "newWindow")) {\n continue;\n }\n\n html.setAttribute(key, value);\n }\n } else {\n Object.assign(html.style, value);\n }\n }\n\n if (isHTMLAnchorElement) {\n linkService.addLinkAttributes(html, attributes.href, attributes.newWindow);\n }\n\n if (storage && attributes.dataId) {\n this.setupStorage(html, attributes.dataId, element, storage);\n }\n }\n\n static render(parameters) {\n const storage = parameters.annotationStorage;\n const linkService = parameters.linkService;\n const root = parameters.xfaHtml;\n const intent = parameters.intent || "display";\n const rootHtml = document.createElement(root.name);\n\n if (root.attributes) {\n this.setAttributes({\n html: rootHtml,\n element: root,\n intent,\n linkService\n });\n }\n\n const stack = [[root, -1, rootHtml]];\n const rootDiv = parameters.div;\n rootDiv.appendChild(rootHtml);\n\n if (parameters.viewport) {\n const transform = `matrix(${parameters.viewport.transform.join(",")})`;\n rootDiv.style.transform = transform;\n }\n\n if (intent !== "richText") {\n rootDiv.setAttribute("class", "xfaLayer xfaFont");\n }\n\n const textDivs = [];\n\n while (stack.length > 0) {\n const [parent, i, html] = stack[stack.length - 1];\n\n if (i + 1 === parent.children.length) {\n stack.pop();\n continue;\n }\n\n const child = parent.children[++stack[stack.length - 1][1]];\n\n if (child === null) {\n continue;\n }\n\n const {\n name\n } = child;\n\n if (name === "#text") {\n const node = document.createTextNode(child.value);\n textDivs.push(node);\n html.appendChild(node);\n continue;\n }\n\n let childHtml;\n\n if (child?.attributes?.xmlns) {\n childHtml = document.createElementNS(child.attributes.xmlns, name);\n } else {\n childHtml = document.createElement(name);\n }\n\n html.appendChild(childHtml);\n\n if (child.attributes) {\n this.setAttributes({\n html: childHtml,\n element: child,\n storage,\n intent,\n linkService\n });\n }\n\n if (child.children && child.children.length > 0) {\n stack.push([child, -1, childHtml]);\n } else if (child.value) {\n const node = document.createTextNode(child.value);\n\n if (_xfa_text.XfaText.shouldBuildText(name)) {\n textDivs.push(node);\n }\n\n childHtml.appendChild(node);\n }\n }\n\n for (const el of rootDiv.querySelectorAll(".xfaNonInteractive input, .xfaNonInteractive textarea")) {\n el.setAttribute("readOnly", true);\n }\n\n return {\n textDivs\n };\n }\n\n static update(parameters) {\n const transform = `matrix(${parameters.viewport.transform.join(",")})`;\n parameters.div.style.transform = transform;\n parameters.div.hidden = false;\n }\n\n}\n\nexports.XfaLayer = XfaLayer;\n\n/***/ }),\n/* 23 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.renderTextLayer = renderTextLayer;\n\nvar _util = __w_pdfjs_require__(1);\n\nconst MAX_TEXT_DIVS_TO_RENDER = 100000;\nconst DEFAULT_FONT_SIZE = 30;\nconst DEFAULT_FONT_ASCENT = 0.8;\nconst ascentCache = new Map();\nconst AllWhitespaceRegexp = /^\\s+$/g;\n\nfunction getAscent(fontFamily, ctx) {\n const cachedAscent = ascentCache.get(fontFamily);\n\n if (cachedAscent) {\n return cachedAscent;\n }\n\n ctx.save();\n ctx.font = `${DEFAULT_FONT_SIZE}px ${fontFamily}`;\n const metrics = ctx.measureText("");\n let ascent = metrics.fontBoundingBoxAscent;\n let descent = Math.abs(metrics.fontBoundingBoxDescent);\n\n if (ascent) {\n ctx.restore();\n const ratio = ascent / (ascent + descent);\n ascentCache.set(fontFamily, ratio);\n return ratio;\n }\n\n ctx.strokeStyle = "red";\n ctx.clearRect(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE);\n ctx.strokeText("g", 0, 0);\n let pixels = ctx.getImageData(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE).data;\n descent = 0;\n\n for (let i = pixels.length - 1 - 3; i >= 0; i -= 4) {\n if (pixels[i] > 0) {\n descent = Math.ceil(i / 4 / DEFAULT_FONT_SIZE);\n break;\n }\n }\n\n ctx.clearRect(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE);\n ctx.strokeText("A", 0, DEFAULT_FONT_SIZE);\n pixels = ctx.getImageData(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE).data;\n ascent = 0;\n\n for (let i = 0, ii = pixels.length; i < ii; i += 4) {\n if (pixels[i] > 0) {\n ascent = DEFAULT_FONT_SIZE - Math.floor(i / 4 / DEFAULT_FONT_SIZE);\n break;\n }\n }\n\n ctx.restore();\n\n if (ascent) {\n const ratio = ascent / (ascent + descent);\n ascentCache.set(fontFamily, ratio);\n return ratio;\n }\n\n ascentCache.set(fontFamily, DEFAULT_FONT_ASCENT);\n return DEFAULT_FONT_ASCENT;\n}\n\nfunction appendText(task, geom, styles, ctx) {\n const textDiv = document.createElement("span");\n const textDivProperties = task._enhanceTextSelection ? {\n angle: 0,\n canvasWidth: 0,\n hasText: geom.str !== "",\n hasEOL: geom.hasEOL,\n originalTransform: null,\n paddingBottom: 0,\n paddingLeft: 0,\n paddingRight: 0,\n paddingTop: 0,\n scale: 1\n } : {\n angle: 0,\n canvasWidth: 0,\n hasText: geom.str !== "",\n hasEOL: geom.hasEOL\n };\n\n task._textDivs.push(textDiv);\n\n const tx = _util.Util.transform(task._viewport.transform, geom.transform);\n\n let angle = Math.atan2(tx[1], tx[0]);\n const style = styles[geom.fontName];\n\n if (style.vertical) {\n angle += Math.PI / 2;\n }\n\n const fontHeight = Math.hypot(tx[2], tx[3]);\n const fontAscent = fontHeight * getAscent(style.fontFamily, ctx);\n let left, top;\n\n if (angle === 0) {\n left = tx[4];\n top = tx[5] - fontAscent;\n } else {\n left = tx[4] + fontAscent * Math.sin(angle);\n top = tx[5] - fontAscent * Math.cos(angle);\n }\n\n textDiv.style.left = `${left}px`;\n textDiv.style.top = `${top}px`;\n textDiv.style.fontSize = `${fontHeight}px`;\n textDiv.style.fontFamily = style.fontFamily;\n textDiv.setAttribute("role", "presentation");\n textDiv.textContent = geom.str;\n textDiv.dir = geom.dir;\n\n if (task._fontInspectorEnabled) {\n textDiv.dataset.fontName = geom.fontName;\n }\n\n if (angle !== 0) {\n textDivProperties.angle = angle * (180 / Math.PI);\n }\n\n let shouldScaleText = false;\n\n if (geom.str.length > 1 || task._enhanceTextSelection && AllWhitespaceRegexp.test(geom.str)) {\n shouldScaleText = true;\n } else if (geom.str !== " " && geom.transform[0] !== geom.transform[3]) {\n const absScaleX = Math.abs(geom.transform[0]),\n absScaleY = Math.abs(geom.transform[3]);\n\n if (absScaleX !== absScaleY && Math.max(absScaleX, absScaleY) / Math.min(absScaleX, absScaleY) > 1.5) {\n shouldScaleText = true;\n }\n }\n\n if (shouldScaleText) {\n if (style.vertical) {\n textDivProperties.canvasWidth = geom.height * task._viewport.scale;\n } else {\n textDivProperties.canvasWidth = geom.width * task._viewport.scale;\n }\n }\n\n task._textDivProperties.set(textDiv, textDivProperties);\n\n if (task._textContentStream) {\n task._layoutText(textDiv);\n }\n\n if (task._enhanceTextSelection && textDivProperties.hasText) {\n let angleCos = 1,\n angleSin = 0;\n\n if (angle !== 0) {\n angleCos = Math.cos(angle);\n angleSin = Math.sin(angle);\n }\n\n const divWidth = (style.vertical ? geom.height : geom.width) * task._viewport.scale;\n const divHeight = fontHeight;\n let m, b;\n\n if (angle !== 0) {\n m = [angleCos, angleSin, -angleSin, angleCos, left, top];\n b = _util.Util.getAxialAlignedBoundingBox([0, 0, divWidth, divHeight], m);\n } else {\n b = [left, top, left + divWidth, top + divHeight];\n }\n\n task._bounds.push({\n left: b[0],\n top: b[1],\n right: b[2],\n bottom: b[3],\n div: textDiv,\n size: [divWidth, divHeight],\n m\n });\n }\n}\n\nfunction render(task) {\n if (task._canceled) {\n return;\n }\n\n const textDivs = task._textDivs;\n const capability = task._capability;\n const textDivsLength = textDivs.length;\n\n if (textDivsLength > MAX_TEXT_DIVS_TO_RENDER) {\n task._renderingDone = true;\n capability.resolve();\n return;\n }\n\n if (!task._textContentStream) {\n for (let i = 0; i < textDivsLength; i++) {\n task._layoutText(textDivs[i]);\n }\n }\n\n task._renderingDone = true;\n capability.resolve();\n}\n\nfunction findPositiveMin(ts, offset, count) {\n let result = 0;\n\n for (let i = 0; i < count; i++) {\n const t = ts[offset++];\n\n if (t > 0) {\n result = result ? Math.min(t, result) : t;\n }\n }\n\n return result;\n}\n\nfunction expand(task) {\n const bounds = task._bounds;\n const viewport = task._viewport;\n const expanded = expandBounds(viewport.width, viewport.height, bounds);\n\n for (let i = 0; i < expanded.length; i++) {\n const div = bounds[i].div;\n\n const divProperties = task._textDivProperties.get(div);\n\n if (divProperties.angle === 0) {\n divProperties.paddingLeft = bounds[i].left - expanded[i].left;\n divProperties.paddingTop = bounds[i].top - expanded[i].top;\n divProperties.paddingRight = expanded[i].right - bounds[i].right;\n divProperties.paddingBottom = expanded[i].bottom - bounds[i].bottom;\n\n task._textDivProperties.set(div, divProperties);\n\n continue;\n }\n\n const e = expanded[i],\n b = bounds[i];\n const m = b.m,\n c = m[0],\n s = m[1];\n const points = [[0, 0], [0, b.size[1]], [b.size[0], 0], b.size];\n const ts = new Float64Array(64);\n\n for (let j = 0, jj = points.length; j < jj; j++) {\n const t = _util.Util.applyTransform(points[j], m);\n\n ts[j + 0] = c && (e.left - t[0]) / c;\n ts[j + 4] = s && (e.top - t[1]) / s;\n ts[j + 8] = c && (e.right - t[0]) / c;\n ts[j + 12] = s && (e.bottom - t[1]) / s;\n ts[j + 16] = s && (e.left - t[0]) / -s;\n ts[j + 20] = c && (e.top - t[1]) / c;\n ts[j + 24] = s && (e.right - t[0]) / -s;\n ts[j + 28] = c && (e.bottom - t[1]) / c;\n ts[j + 32] = c && (e.left - t[0]) / -c;\n ts[j + 36] = s && (e.top - t[1]) / -s;\n ts[j + 40] = c && (e.right - t[0]) / -c;\n ts[j + 44] = s && (e.bottom - t[1]) / -s;\n ts[j + 48] = s && (e.left - t[0]) / s;\n ts[j + 52] = c && (e.top - t[1]) / -c;\n ts[j + 56] = s && (e.right - t[0]) / s;\n ts[j + 60] = c && (e.bottom - t[1]) / -c;\n }\n\n const boxScale = 1 + Math.min(Math.abs(c), Math.abs(s));\n divProperties.paddingLeft = findPositiveMin(ts, 32, 16) / boxScale;\n divProperties.paddingTop = findPositiveMin(ts, 48, 16) / boxScale;\n divProperties.paddingRight = findPositiveMin(ts, 0, 16) / boxScale;\n divProperties.paddingBottom = findPositiveMin(ts, 16, 16) / boxScale;\n\n task._textDivProperties.set(div, divProperties);\n }\n}\n\nfunction expandBounds(width, height, boxes) {\n const bounds = boxes.map(function (box, i) {\n return {\n x1: box.left,\n y1: box.top,\n x2: box.right,\n y2: box.bottom,\n index: i,\n x1New: undefined,\n x2New: undefined\n };\n });\n expandBoundsLTR(width, bounds);\n const expanded = new Array(boxes.length);\n\n for (const b of bounds) {\n const i = b.index;\n expanded[i] = {\n left: b.x1New,\n top: 0,\n right: b.x2New,\n bottom: 0\n };\n }\n\n boxes.map(function (box, i) {\n const e = expanded[i],\n b = bounds[i];\n b.x1 = box.top;\n b.y1 = width - e.right;\n b.x2 = box.bottom;\n b.y2 = width - e.left;\n b.index = i;\n b.x1New = undefined;\n b.x2New = undefined;\n });\n expandBoundsLTR(height, bounds);\n\n for (const b of bounds) {\n const i = b.index;\n expanded[i].top = b.x1New;\n expanded[i].bottom = b.x2New;\n }\n\n return expanded;\n}\n\nfunction expandBoundsLTR(width, bounds) {\n bounds.sort(function (a, b) {\n return a.x1 - b.x1 || a.index - b.index;\n });\n const fakeBoundary = {\n x1: -Infinity,\n y1: -Infinity,\n x2: 0,\n y2: Infinity,\n index: -1,\n x1New: 0,\n x2New: 0\n };\n const horizon = [{\n start: -Infinity,\n end: Infinity,\n boundary: fakeBoundary\n }];\n\n for (const boundary of bounds) {\n let i = 0;\n\n while (i < horizon.length && horizon[i].end <= boundary.y1) {\n i++;\n }\n\n let j = horizon.length - 1;\n\n while (j >= 0 && horizon[j].start >= boundary.y2) {\n j--;\n }\n\n let horizonPart, affectedBoundary;\n let q,\n k,\n maxXNew = -Infinity;\n\n for (q = i; q <= j; q++) {\n horizonPart = horizon[q];\n affectedBoundary = horizonPart.boundary;\n let xNew;\n\n if (affectedBoundary.x2 > boundary.x1) {\n xNew = affectedBoundary.index > boundary.index ? affectedBoundary.x1New : boundary.x1;\n } else if (affectedBoundary.x2New === undefined) {\n xNew = (affectedBoundary.x2 + boundary.x1) / 2;\n } else {\n xNew = affectedBoundary.x2New;\n }\n\n if (xNew > maxXNew) {\n maxXNew = xNew;\n }\n }\n\n boundary.x1New = maxXNew;\n\n for (q = i; q <= j; q++) {\n horizonPart = horizon[q];\n affectedBoundary = horizonPart.boundary;\n\n if (affectedBoundary.x2New === undefined) {\n if (affectedBoundary.x2 > boundary.x1) {\n if (affectedBoundary.index > boundary.index) {\n affectedBoundary.x2New = affectedBoundary.x2;\n }\n } else {\n affectedBoundary.x2New = maxXNew;\n }\n } else if (affectedBoundary.x2New > maxXNew) {\n affectedBoundary.x2New = Math.max(maxXNew, affectedBoundary.x2);\n }\n }\n\n const changedHorizon = [];\n let lastBoundary = null;\n\n for (q = i; q <= j; q++) {\n horizonPart = horizon[q];\n affectedBoundary = horizonPart.boundary;\n const useBoundary = affectedBoundary.x2 > boundary.x2 ? affectedBoundary : boundary;\n\n if (lastBoundary === useBoundary) {\n changedHorizon[changedHorizon.length - 1].end = horizonPart.end;\n } else {\n changedHorizon.push({\n start: horizonPart.start,\n end: horizonPart.end,\n boundary: useBoundary\n });\n lastBoundary = useBoundary;\n }\n }\n\n if (horizon[i].start < boundary.y1) {\n changedHorizon[0].start = boundary.y1;\n changedHorizon.unshift({\n start: horizon[i].start,\n end: boundary.y1,\n boundary: horizon[i].boundary\n });\n }\n\n if (boundary.y2 < horizon[j].end) {\n changedHorizon[changedHorizon.length - 1].end = boundary.y2;\n changedHorizon.push({\n start: boundary.y2,\n end: horizon[j].end,\n boundary: horizon[j].boundary\n });\n }\n\n for (q = i; q <= j; q++) {\n horizonPart = horizon[q];\n affectedBoundary = horizonPart.boundary;\n\n if (affectedBoundary.x2New !== undefined) {\n continue;\n }\n\n let used = false;\n\n for (k = i - 1; !used && k >= 0 && horizon[k].start >= affectedBoundary.y1; k--) {\n used = horizon[k].boundary === affectedBoundary;\n }\n\n for (k = j + 1; !used && k < horizon.length && horizon[k].end <= affectedBoundary.y2; k++) {\n used = horizon[k].boundary === affectedBoundary;\n }\n\n for (k = 0; !used && k < changedHorizon.length; k++) {\n used = changedHorizon[k].boundary === affectedBoundary;\n }\n\n if (!used) {\n affectedBoundary.x2New = maxXNew;\n }\n }\n\n Array.prototype.splice.apply(horizon, [i, j - i + 1].concat(changedHorizon));\n }\n\n for (const horizonPart of horizon) {\n const affectedBoundary = horizonPart.boundary;\n\n if (affectedBoundary.x2New === undefined) {\n affectedBoundary.x2New = Math.max(width, affectedBoundary.x2);\n }\n }\n}\n\nclass TextLayerRenderTask {\n constructor({\n textContent,\n textContentStream,\n container,\n viewport,\n textDivs,\n textContentItemsStr,\n enhanceTextSelection\n }) {\n this._textContent = textContent;\n this._textContentStream = textContentStream;\n this._container = container;\n this._document = container.ownerDocument;\n this._viewport = viewport;\n this._textDivs = textDivs || [];\n this._textContentItemsStr = textContentItemsStr || [];\n this._enhanceTextSelection = !!enhanceTextSelection;\n this._fontInspectorEnabled = !!globalThis.FontInspector?.enabled;\n this._reader = null;\n this._layoutTextLastFontSize = null;\n this._layoutTextLastFontFamily = null;\n this._layoutTextCtx = null;\n this._textDivProperties = new WeakMap();\n this._renderingDone = false;\n this._canceled = false;\n this._capability = (0, _util.createPromiseCapability)();\n this._renderTimer = null;\n this._bounds = [];\n\n this._capability.promise.finally(() => {\n if (!this._enhanceTextSelection) {\n this._textDivProperties = null;\n }\n\n if (this._layoutTextCtx) {\n this._layoutTextCtx.canvas.width = 0;\n this._layoutTextCtx.canvas.height = 0;\n this._layoutTextCtx = null;\n }\n }).catch(() => {});\n }\n\n get promise() {\n return this._capability.promise;\n }\n\n cancel() {\n this._canceled = true;\n\n if (this._reader) {\n this._reader.cancel(new _util.AbortException("TextLayer task cancelled.")).catch(() => {});\n\n this._reader = null;\n }\n\n if (this._renderTimer !== null) {\n clearTimeout(this._renderTimer);\n this._renderTimer = null;\n }\n\n this._capability.reject(new Error("TextLayer task cancelled."));\n }\n\n _processItems(items, styleCache) {\n for (let i = 0, len = items.length; i < len; i++) {\n if (items[i].str === undefined) {\n if (items[i].type === "beginMarkedContentProps" || items[i].type === "beginMarkedContent") {\n const parent = this._container;\n this._container = document.createElement("span");\n\n this._container.classList.add("markedContent");\n\n if (items[i].id !== null) {\n this._container.setAttribute("id", `${items[i].id}`);\n }\n\n parent.appendChild(this._container);\n } else if (items[i].type === "endMarkedContent") {\n this._container = this._container.parentNode;\n }\n\n continue;\n }\n\n this._textContentItemsStr.push(items[i].str);\n\n appendText(this, items[i], styleCache, this._layoutTextCtx);\n }\n }\n\n _layoutText(textDiv) {\n const textDivProperties = this._textDivProperties.get(textDiv);\n\n let transform = "";\n\n if (textDivProperties.canvasWidth !== 0 && textDivProperties.hasText) {\n const {\n fontSize,\n fontFamily\n } = textDiv.style;\n\n if (fontSize !== this._layoutTextLastFontSize || fontFamily !== this._layoutTextLastFontFamily) {\n this._layoutTextCtx.font = `${fontSize} ${fontFamily}`;\n this._layoutTextLastFontSize = fontSize;\n this._layoutTextLastFontFamily = fontFamily;\n }\n\n const {\n width\n } = this._layoutTextCtx.measureText(textDiv.textContent);\n\n if (width > 0) {\n const scale = textDivProperties.canvasWidth / width;\n\n if (this._enhanceTextSelection) {\n textDivProperties.scale = scale;\n }\n\n transform = `scaleX(${scale})`;\n }\n }\n\n if (textDivProperties.angle !== 0) {\n transform = `rotate(${textDivProperties.angle}deg) ${transform}`;\n }\n\n if (transform.length > 0) {\n if (this._enhanceTextSelection) {\n textDivProperties.originalTransform = transform;\n }\n\n textDiv.style.transform = transform;\n }\n\n if (textDivProperties.hasText) {\n this._container.appendChild(textDiv);\n }\n\n if (textDivProperties.hasEOL) {\n const br = document.createElement("br");\n br.setAttribute("role", "presentation");\n\n this._container.appendChild(br);\n }\n }\n\n _render(timeout = 0) {\n const capability = (0, _util.createPromiseCapability)();\n let styleCache = Object.create(null);\n\n const canvas = this._document.createElement("canvas");\n\n canvas.height = canvas.width = DEFAULT_FONT_SIZE;\n this._layoutTextCtx = canvas.getContext("2d", {\n alpha: false\n });\n\n if (this._textContent) {\n const textItems = this._textContent.items;\n const textStyles = this._textContent.styles;\n\n this._processItems(textItems, textStyles);\n\n capability.resolve();\n } else if (this._textContentStream) {\n const pump = () => {\n this._reader.read().then(({\n value,\n done\n }) => {\n if (done) {\n capability.resolve();\n return;\n }\n\n Object.assign(styleCache, value.styles);\n\n this._processItems(value.items, styleCache);\n\n pump();\n }, capability.reject);\n };\n\n this._reader = this._textContentStream.getReader();\n pump();\n } else {\n throw new Error(\'Neither "textContent" nor "textContentStream" parameters specified.\');\n }\n\n capability.promise.then(() => {\n styleCache = null;\n\n if (!timeout) {\n render(this);\n } else {\n this._renderTimer = setTimeout(() => {\n render(this);\n this._renderTimer = null;\n }, timeout);\n }\n }, this._capability.reject);\n }\n\n expandTextDivs(expandDivs = false) {\n if (!this._enhanceTextSelection || !this._renderingDone) {\n return;\n }\n\n if (this._bounds !== null) {\n expand(this);\n this._bounds = null;\n }\n\n const transformBuf = [],\n paddingBuf = [];\n\n for (let i = 0, ii = this._textDivs.length; i < ii; i++) {\n const div = this._textDivs[i];\n\n const divProps = this._textDivProperties.get(div);\n\n if (!divProps.hasText) {\n continue;\n }\n\n if (expandDivs) {\n transformBuf.length = 0;\n paddingBuf.length = 0;\n\n if (divProps.originalTransform) {\n transformBuf.push(divProps.originalTransform);\n }\n\n if (divProps.paddingTop > 0) {\n paddingBuf.push(`${divProps.paddingTop}px`);\n transformBuf.push(`translateY(${-divProps.paddingTop}px)`);\n } else {\n paddingBuf.push(0);\n }\n\n if (divProps.paddingRight > 0) {\n paddingBuf.push(`${divProps.paddingRight / divProps.scale}px`);\n } else {\n paddingBuf.push(0);\n }\n\n if (divProps.paddingBottom > 0) {\n paddingBuf.push(`${divProps.paddingBottom}px`);\n } else {\n paddingBuf.push(0);\n }\n\n if (divProps.paddingLeft > 0) {\n paddingBuf.push(`${divProps.paddingLeft / divProps.scale}px`);\n transformBuf.push(`translateX(${-divProps.paddingLeft / divProps.scale}px)`);\n } else {\n paddingBuf.push(0);\n }\n\n div.style.padding = paddingBuf.join(" ");\n\n if (transformBuf.length) {\n div.style.transform = transformBuf.join(" ");\n }\n } else {\n div.style.padding = null;\n div.style.transform = divProps.originalTransform;\n }\n }\n }\n\n}\n\nfunction renderTextLayer(renderParameters) {\n const task = new TextLayerRenderTask({\n textContent: renderParameters.textContent,\n textContentStream: renderParameters.textContentStream,\n container: renderParameters.container,\n viewport: renderParameters.viewport,\n textDivs: renderParameters.textDivs,\n textContentItemsStr: renderParameters.textContentItemsStr,\n enhanceTextSelection: renderParameters.enhanceTextSelection\n });\n\n task._render(renderParameters.timeout);\n\n return task;\n}\n\n/***/ }),\n/* 24 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.SVGGraphics = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _display_utils = __w_pdfjs_require__(5);\n\nvar _is_node = __w_pdfjs_require__(3);\n\nlet SVGGraphics = class {\n constructor() {\n (0, _util.unreachable)("Not implemented: SVGGraphics");\n }\n\n};\nexports.SVGGraphics = SVGGraphics;\n{\n const SVG_DEFAULTS = {\n fontStyle: "normal",\n fontWeight: "normal",\n fillColor: "#000000"\n };\n const XML_NS = "http://www.w3.org/XML/1998/namespace";\n const XLINK_NS = "http://www.w3.org/1999/xlink";\n const LINE_CAP_STYLES = ["butt", "round", "square"];\n const LINE_JOIN_STYLES = ["miter", "round", "bevel"];\n\n const createObjectURL = function (data, contentType = "", forceDataSchema = false) {\n if (URL.createObjectURL && typeof Blob !== "undefined" && !forceDataSchema) {\n return URL.createObjectURL(new Blob([data], {\n type: contentType\n }));\n }\n\n const digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";\n let buffer = `data:${contentType};base64,`;\n\n for (let i = 0, ii = data.length; i < ii; i += 3) {\n const b1 = data[i] & 0xff;\n const b2 = data[i + 1] & 0xff;\n const b3 = data[i + 2] & 0xff;\n const d1 = b1 >> 2,\n d2 = (b1 & 3) << 4 | b2 >> 4;\n const d3 = i + 1 < ii ? (b2 & 0xf) << 2 | b3 >> 6 : 64;\n const d4 = i + 2 < ii ? b3 & 0x3f : 64;\n buffer += digits[d1] + digits[d2] + digits[d3] + digits[d4];\n }\n\n return buffer;\n };\n\n const convertImgDataToPng = function () {\n const PNG_HEADER = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);\n const CHUNK_WRAPPER_SIZE = 12;\n const crcTable = new Int32Array(256);\n\n for (let i = 0; i < 256; i++) {\n let c = i;\n\n for (let h = 0; h < 8; h++) {\n if (c & 1) {\n c = 0xedb88320 ^ c >> 1 & 0x7fffffff;\n } else {\n c = c >> 1 & 0x7fffffff;\n }\n }\n\n crcTable[i] = c;\n }\n\n function crc32(data, start, end) {\n let crc = -1;\n\n for (let i = start; i < end; i++) {\n const a = (crc ^ data[i]) & 0xff;\n const b = crcTable[a];\n crc = crc >>> 8 ^ b;\n }\n\n return crc ^ -1;\n }\n\n function writePngChunk(type, body, data, offset) {\n let p = offset;\n const len = body.length;\n data[p] = len >> 24 & 0xff;\n data[p + 1] = len >> 16 & 0xff;\n data[p + 2] = len >> 8 & 0xff;\n data[p + 3] = len & 0xff;\n p += 4;\n data[p] = type.charCodeAt(0) & 0xff;\n data[p + 1] = type.charCodeAt(1) & 0xff;\n data[p + 2] = type.charCodeAt(2) & 0xff;\n data[p + 3] = type.charCodeAt(3) & 0xff;\n p += 4;\n data.set(body, p);\n p += body.length;\n const crc = crc32(data, offset + 4, p);\n data[p] = crc >> 24 & 0xff;\n data[p + 1] = crc >> 16 & 0xff;\n data[p + 2] = crc >> 8 & 0xff;\n data[p + 3] = crc & 0xff;\n }\n\n function adler32(data, start, end) {\n let a = 1;\n let b = 0;\n\n for (let i = start; i < end; ++i) {\n a = (a + (data[i] & 0xff)) % 65521;\n b = (b + a) % 65521;\n }\n\n return b << 16 | a;\n }\n\n function deflateSync(literals) {\n if (!_is_node.isNodeJS) {\n return deflateSyncUncompressed(literals);\n }\n\n try {\n let input;\n\n if (parseInt(process.versions.node) >= 8) {\n input = literals;\n } else {\n input = Buffer.from(literals);\n }\n\n const output = __webpack_require__(258).deflateSync(input, {\n level: 9\n });\n\n return output instanceof Uint8Array ? output : new Uint8Array(output);\n } catch (e) {\n (0, _util.warn)("Not compressing PNG because zlib.deflateSync is unavailable: " + e);\n }\n\n return deflateSyncUncompressed(literals);\n }\n\n function deflateSyncUncompressed(literals) {\n let len = literals.length;\n const maxBlockLength = 0xffff;\n const deflateBlocks = Math.ceil(len / maxBlockLength);\n const idat = new Uint8Array(2 + len + deflateBlocks * 5 + 4);\n let pi = 0;\n idat[pi++] = 0x78;\n idat[pi++] = 0x9c;\n let pos = 0;\n\n while (len > maxBlockLength) {\n idat[pi++] = 0x00;\n idat[pi++] = 0xff;\n idat[pi++] = 0xff;\n idat[pi++] = 0x00;\n idat[pi++] = 0x00;\n idat.set(literals.subarray(pos, pos + maxBlockLength), pi);\n pi += maxBlockLength;\n pos += maxBlockLength;\n len -= maxBlockLength;\n }\n\n idat[pi++] = 0x01;\n idat[pi++] = len & 0xff;\n idat[pi++] = len >> 8 & 0xff;\n idat[pi++] = ~len & 0xffff & 0xff;\n idat[pi++] = (~len & 0xffff) >> 8 & 0xff;\n idat.set(literals.subarray(pos), pi);\n pi += literals.length - pos;\n const adler = adler32(literals, 0, literals.length);\n idat[pi++] = adler >> 24 & 0xff;\n idat[pi++] = adler >> 16 & 0xff;\n idat[pi++] = adler >> 8 & 0xff;\n idat[pi++] = adler & 0xff;\n return idat;\n }\n\n function encode(imgData, kind, forceDataSchema, isMask) {\n const width = imgData.width;\n const height = imgData.height;\n let bitDepth, colorType, lineSize;\n const bytes = imgData.data;\n\n switch (kind) {\n case _util.ImageKind.GRAYSCALE_1BPP:\n colorType = 0;\n bitDepth = 1;\n lineSize = width + 7 >> 3;\n break;\n\n case _util.ImageKind.RGB_24BPP:\n colorType = 2;\n bitDepth = 8;\n lineSize = width * 3;\n break;\n\n case _util.ImageKind.RGBA_32BPP:\n colorType = 6;\n bitDepth = 8;\n lineSize = width * 4;\n break;\n\n default:\n throw new Error("invalid format");\n }\n\n const literals = new Uint8Array((1 + lineSize) * height);\n let offsetLiterals = 0,\n offsetBytes = 0;\n\n for (let y = 0; y < height; ++y) {\n literals[offsetLiterals++] = 0;\n literals.set(bytes.subarray(offsetBytes, offsetBytes + lineSize), offsetLiterals);\n offsetBytes += lineSize;\n offsetLiterals += lineSize;\n }\n\n if (kind === _util.ImageKind.GRAYSCALE_1BPP && isMask) {\n offsetLiterals = 0;\n\n for (let y = 0; y < height; y++) {\n offsetLiterals++;\n\n for (let i = 0; i < lineSize; i++) {\n literals[offsetLiterals++] ^= 0xff;\n }\n }\n }\n\n const ihdr = new Uint8Array([width >> 24 & 0xff, width >> 16 & 0xff, width >> 8 & 0xff, width & 0xff, height >> 24 & 0xff, height >> 16 & 0xff, height >> 8 & 0xff, height & 0xff, bitDepth, colorType, 0x00, 0x00, 0x00]);\n const idat = deflateSync(literals);\n const pngLength = PNG_HEADER.length + CHUNK_WRAPPER_SIZE * 3 + ihdr.length + idat.length;\n const data = new Uint8Array(pngLength);\n let offset = 0;\n data.set(PNG_HEADER, offset);\n offset += PNG_HEADER.length;\n writePngChunk("IHDR", ihdr, data, offset);\n offset += CHUNK_WRAPPER_SIZE + ihdr.length;\n writePngChunk("IDATA", idat, data, offset);\n offset += CHUNK_WRAPPER_SIZE + idat.length;\n writePngChunk("IEND", new Uint8Array(0), data, offset);\n return createObjectURL(data, "image/png", forceDataSchema);\n }\n\n return function convertImgDataToPng(imgData, forceDataSchema, isMask) {\n const kind = imgData.kind === undefined ? _util.ImageKind.GRAYSCALE_1BPP : imgData.kind;\n return encode(imgData, kind, forceDataSchema, isMask);\n };\n }();\n\n class SVGExtraState {\n constructor() {\n this.fontSizeScale = 1;\n this.fontWeight = SVG_DEFAULTS.fontWeight;\n this.fontSize = 0;\n this.textMatrix = _util.IDENTITY_MATRIX;\n this.fontMatrix = _util.FONT_IDENTITY_MATRIX;\n this.leading = 0;\n this.textRenderingMode = _util.TextRenderingMode.FILL;\n this.textMatrixScale = 1;\n this.x = 0;\n this.y = 0;\n this.lineX = 0;\n this.lineY = 0;\n this.charSpacing = 0;\n this.wordSpacing = 0;\n this.textHScale = 1;\n this.textRise = 0;\n this.fillColor = SVG_DEFAULTS.fillColor;\n this.strokeColor = "#000000";\n this.fillAlpha = 1;\n this.strokeAlpha = 1;\n this.lineWidth = 1;\n this.lineJoin = "";\n this.lineCap = "";\n this.miterLimit = 0;\n this.dashArray = [];\n this.dashPhase = 0;\n this.dependencies = [];\n this.activeClipUrl = null;\n this.clipGroup = null;\n this.maskId = "";\n }\n\n clone() {\n return Object.create(this);\n }\n\n setCurrentPoint(x, y) {\n this.x = x;\n this.y = y;\n }\n\n }\n\n function opListToTree(opList) {\n let opTree = [];\n const tmp = [];\n\n for (const opListElement of opList) {\n if (opListElement.fn === "save") {\n opTree.push({\n fnId: 92,\n fn: "group",\n items: []\n });\n tmp.push(opTree);\n opTree = opTree[opTree.length - 1].items;\n continue;\n }\n\n if (opListElement.fn === "restore") {\n opTree = tmp.pop();\n } else {\n opTree.push(opListElement);\n }\n }\n\n return opTree;\n }\n\n function pf(value) {\n if (Number.isInteger(value)) {\n return value.toString();\n }\n\n const s = value.toFixed(10);\n let i = s.length - 1;\n\n if (s[i] !== "0") {\n return s;\n }\n\n do {\n i--;\n } while (s[i] === "0");\n\n return s.substring(0, s[i] === "." ? i : i + 1);\n }\n\n function pm(m) {\n if (m[4] === 0 && m[5] === 0) {\n if (m[1] === 0 && m[2] === 0) {\n if (m[0] === 1 && m[3] === 1) {\n return "";\n }\n\n return `scale(${pf(m[0])} ${pf(m[3])})`;\n }\n\n if (m[0] === m[3] && m[1] === -m[2]) {\n const a = Math.acos(m[0]) * 180 / Math.PI;\n return `rotate(${pf(a)})`;\n }\n } else {\n if (m[0] === 1 && m[1] === 0 && m[2] === 0 && m[3] === 1) {\n return `translate(${pf(m[4])} ${pf(m[5])})`;\n }\n }\n\n return `matrix(${pf(m[0])} ${pf(m[1])} ${pf(m[2])} ${pf(m[3])} ${pf(m[4])} ` + `${pf(m[5])})`;\n }\n\n let clipCount = 0;\n let maskCount = 0;\n let shadingCount = 0;\n exports.SVGGraphics = SVGGraphics = class {\n constructor(commonObjs, objs, forceDataSchema = false) {\n this.svgFactory = new _display_utils.DOMSVGFactory();\n this.current = new SVGExtraState();\n this.transformMatrix = _util.IDENTITY_MATRIX;\n this.transformStack = [];\n this.extraStack = [];\n this.commonObjs = commonObjs;\n this.objs = objs;\n this.pendingClip = null;\n this.pendingEOFill = false;\n this.embedFonts = false;\n this.embeddedFonts = Object.create(null);\n this.cssStyle = null;\n this.forceDataSchema = !!forceDataSchema;\n this._operatorIdMapping = [];\n\n for (const op in _util.OPS) {\n this._operatorIdMapping[_util.OPS[op]] = op;\n }\n }\n\n save() {\n this.transformStack.push(this.transformMatrix);\n const old = this.current;\n this.extraStack.push(old);\n this.current = old.clone();\n }\n\n restore() {\n this.transformMatrix = this.transformStack.pop();\n this.current = this.extraStack.pop();\n this.pendingClip = null;\n this.tgrp = null;\n }\n\n group(items) {\n this.save();\n this.executeOpTree(items);\n this.restore();\n }\n\n loadDependencies(operatorList) {\n const fnArray = operatorList.fnArray;\n const argsArray = operatorList.argsArray;\n\n for (let i = 0, ii = fnArray.length; i < ii; i++) {\n if (fnArray[i] !== _util.OPS.dependency) {\n continue;\n }\n\n for (const obj of argsArray[i]) {\n const objsPool = obj.startsWith("g_") ? this.commonObjs : this.objs;\n const promise = new Promise(resolve => {\n objsPool.get(obj, resolve);\n });\n this.current.dependencies.push(promise);\n }\n }\n\n return Promise.all(this.current.dependencies);\n }\n\n transform(a, b, c, d, e, f) {\n const transformMatrix = [a, b, c, d, e, f];\n this.transformMatrix = _util.Util.transform(this.transformMatrix, transformMatrix);\n this.tgrp = null;\n }\n\n getSVG(operatorList, viewport) {\n this.viewport = viewport;\n\n const svgElement = this._initialize(viewport);\n\n return this.loadDependencies(operatorList).then(() => {\n this.transformMatrix = _util.IDENTITY_MATRIX;\n this.executeOpTree(this.convertOpList(operatorList));\n return svgElement;\n });\n }\n\n convertOpList(operatorList) {\n const operatorIdMapping = this._operatorIdMapping;\n const argsArray = operatorList.argsArray;\n const fnArray = operatorList.fnArray;\n const opList = [];\n\n for (let i = 0, ii = fnArray.length; i < ii; i++) {\n const fnId = fnArray[i];\n opList.push({\n fnId,\n fn: operatorIdMapping[fnId],\n args: argsArray[i]\n });\n }\n\n return opListToTree(opList);\n }\n\n executeOpTree(opTree) {\n for (const opTreeElement of opTree) {\n const fn = opTreeElement.fn;\n const fnId = opTreeElement.fnId;\n const args = opTreeElement.args;\n\n switch (fnId | 0) {\n case _util.OPS.beginText:\n this.beginText();\n break;\n\n case _util.OPS.dependency:\n break;\n\n case _util.OPS.setLeading:\n this.setLeading(args);\n break;\n\n case _util.OPS.setLeadingMoveText:\n this.setLeadingMoveText(args[0], args[1]);\n break;\n\n case _util.OPS.setFont:\n this.setFont(args);\n break;\n\n case _util.OPS.showText:\n this.showText(args[0]);\n break;\n\n case _util.OPS.showSpacedText:\n this.showText(args[0]);\n break;\n\n case _util.OPS.endText:\n this.endText();\n break;\n\n case _util.OPS.moveText:\n this.moveText(args[0], args[1]);\n break;\n\n case _util.OPS.setCharSpacing:\n this.setCharSpacing(args[0]);\n break;\n\n case _util.OPS.setWordSpacing:\n this.setWordSpacing(args[0]);\n break;\n\n case _util.OPS.setHScale:\n this.setHScale(args[0]);\n break;\n\n case _util.OPS.setTextMatrix:\n this.setTextMatrix(args[0], args[1], args[2], args[3], args[4], args[5]);\n break;\n\n case _util.OPS.setTextRise:\n this.setTextRise(args[0]);\n break;\n\n case _util.OPS.setTextRenderingMode:\n this.setTextRenderingMode(args[0]);\n break;\n\n case _util.OPS.setLineWidth:\n this.setLineWidth(args[0]);\n break;\n\n case _util.OPS.setLineJoin:\n this.setLineJoin(args[0]);\n break;\n\n case _util.OPS.setLineCap:\n this.setLineCap(args[0]);\n break;\n\n case _util.OPS.setMiterLimit:\n this.setMiterLimit(args[0]);\n break;\n\n case _util.OPS.setFillRGBColor:\n this.setFillRGBColor(args[0], args[1], args[2]);\n break;\n\n case _util.OPS.setStrokeRGBColor:\n this.setStrokeRGBColor(args[0], args[1], args[2]);\n break;\n\n case _util.OPS.setStrokeColorN:\n this.setStrokeColorN(args);\n break;\n\n case _util.OPS.setFillColorN:\n this.setFillColorN(args);\n break;\n\n case _util.OPS.shadingFill:\n this.shadingFill(args[0]);\n break;\n\n case _util.OPS.setDash:\n this.setDash(args[0], args[1]);\n break;\n\n case _util.OPS.setRenderingIntent:\n this.setRenderingIntent(args[0]);\n break;\n\n case _util.OPS.setFlatness:\n this.setFlatness(args[0]);\n break;\n\n case _util.OPS.setGState:\n this.setGState(args[0]);\n break;\n\n case _util.OPS.fill:\n this.fill();\n break;\n\n case _util.OPS.eoFill:\n this.eoFill();\n break;\n\n case _util.OPS.stroke:\n this.stroke();\n break;\n\n case _util.OPS.fillStroke:\n this.fillStroke();\n break;\n\n case _util.OPS.eoFillStroke:\n this.eoFillStroke();\n break;\n\n case _util.OPS.clip:\n this.clip("nonzero");\n break;\n\n case _util.OPS.eoClip:\n this.clip("evenodd");\n break;\n\n case _util.OPS.paintSolidColorImageMask:\n this.paintSolidColorImageMask();\n break;\n\n case _util.OPS.paintImageXObject:\n this.paintImageXObject(args[0]);\n break;\n\n case _util.OPS.paintInlineImageXObject:\n this.paintInlineImageXObject(args[0]);\n break;\n\n case _util.OPS.paintImageMaskXObject:\n this.paintImageMaskXObject(args[0]);\n break;\n\n case _util.OPS.paintFormXObjectBegin:\n this.paintFormXObjectBegin(args[0], args[1]);\n break;\n\n case _util.OPS.paintFormXObjectEnd:\n this.paintFormXObjectEnd();\n break;\n\n case _util.OPS.closePath:\n this.closePath();\n break;\n\n case _util.OPS.closeStroke:\n this.closeStroke();\n break;\n\n case _util.OPS.closeFillStroke:\n this.closeFillStroke();\n break;\n\n case _util.OPS.closeEOFillStroke:\n this.closeEOFillStroke();\n break;\n\n case _util.OPS.nextLine:\n this.nextLine();\n break;\n\n case _util.OPS.transform:\n this.transform(args[0], args[1], args[2], args[3], args[4], args[5]);\n break;\n\n case _util.OPS.constructPath:\n this.constructPath(args[0], args[1]);\n break;\n\n case _util.OPS.endPath:\n this.endPath();\n break;\n\n case 92:\n this.group(opTreeElement.items);\n break;\n\n default:\n (0, _util.warn)(`Unimplemented operator ${fn}`);\n break;\n }\n }\n }\n\n setWordSpacing(wordSpacing) {\n this.current.wordSpacing = wordSpacing;\n }\n\n setCharSpacing(charSpacing) {\n this.current.charSpacing = charSpacing;\n }\n\n nextLine() {\n this.moveText(0, this.current.leading);\n }\n\n setTextMatrix(a, b, c, d, e, f) {\n const current = this.current;\n current.textMatrix = current.lineMatrix = [a, b, c, d, e, f];\n current.textMatrixScale = Math.hypot(a, b);\n current.x = current.lineX = 0;\n current.y = current.lineY = 0;\n current.xcoords = [];\n current.ycoords = [];\n current.tspan = this.svgFactory.createElement("svg:tspan");\n current.tspan.setAttributeNS(null, "font-family", current.fontFamily);\n current.tspan.setAttributeNS(null, "font-size", `${pf(current.fontSize)}px`);\n current.tspan.setAttributeNS(null, "y", pf(-current.y));\n current.txtElement = this.svgFactory.createElement("svg:text");\n current.txtElement.appendChild(current.tspan);\n }\n\n beginText() {\n const current = this.current;\n current.x = current.lineX = 0;\n current.y = current.lineY = 0;\n current.textMatrix = _util.IDENTITY_MATRIX;\n current.lineMatrix = _util.IDENTITY_MATRIX;\n current.textMatrixScale = 1;\n current.tspan = this.svgFactory.createElement("svg:tspan");\n current.txtElement = this.svgFactory.createElement("svg:text");\n current.txtgrp = this.svgFactory.createElement("svg:g");\n current.xcoords = [];\n current.ycoords = [];\n }\n\n moveText(x, y) {\n const current = this.current;\n current.x = current.lineX += x;\n current.y = current.lineY += y;\n current.xcoords = [];\n current.ycoords = [];\n current.tspan = this.svgFactory.createElement("svg:tspan");\n current.tspan.setAttributeNS(null, "font-family", current.fontFamily);\n current.tspan.setAttributeNS(null, "font-size", `${pf(current.fontSize)}px`);\n current.tspan.setAttributeNS(null, "y", pf(-current.y));\n }\n\n showText(glyphs) {\n const current = this.current;\n const font = current.font;\n const fontSize = current.fontSize;\n\n if (fontSize === 0) {\n return;\n }\n\n const fontSizeScale = current.fontSizeScale;\n const charSpacing = current.charSpacing;\n const wordSpacing = current.wordSpacing;\n const fontDirection = current.fontDirection;\n const textHScale = current.textHScale * fontDirection;\n const vertical = font.vertical;\n const spacingDir = vertical ? 1 : -1;\n const defaultVMetrics = font.defaultVMetrics;\n const widthAdvanceScale = fontSize * current.fontMatrix[0];\n let x = 0;\n\n for (const glyph of glyphs) {\n if (glyph === null) {\n x += fontDirection * wordSpacing;\n continue;\n } else if (typeof glyph === "number") {\n x += spacingDir * glyph * fontSize / 1000;\n continue;\n }\n\n const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing;\n const character = glyph.fontChar;\n let scaledX, scaledY;\n let width = glyph.width;\n\n if (vertical) {\n let vx;\n const vmetric = glyph.vmetric || defaultVMetrics;\n vx = glyph.vmetric ? vmetric[1] : width * 0.5;\n vx = -vx * widthAdvanceScale;\n const vy = vmetric[2] * widthAdvanceScale;\n width = vmetric ? -vmetric[0] : width;\n scaledX = vx / fontSizeScale;\n scaledY = (x + vy) / fontSizeScale;\n } else {\n scaledX = x / fontSizeScale;\n scaledY = 0;\n }\n\n if (glyph.isInFont || font.missingFile) {\n current.xcoords.push(current.x + scaledX);\n\n if (vertical) {\n current.ycoords.push(-current.y + scaledY);\n }\n\n current.tspan.textContent += character;\n } else {}\n\n let charWidth;\n\n if (vertical) {\n charWidth = width * widthAdvanceScale - spacing * fontDirection;\n } else {\n charWidth = width * widthAdvanceScale + spacing * fontDirection;\n }\n\n x += charWidth;\n }\n\n current.tspan.setAttributeNS(null, "x", current.xcoords.map(pf).join(" "));\n\n if (vertical) {\n current.tspan.setAttributeNS(null, "y", current.ycoords.map(pf).join(" "));\n } else {\n current.tspan.setAttributeNS(null, "y", pf(-current.y));\n }\n\n if (vertical) {\n current.y -= x;\n } else {\n current.x += x * textHScale;\n }\n\n current.tspan.setAttributeNS(null, "font-family", current.fontFamily);\n current.tspan.setAttributeNS(null, "font-size", `${pf(current.fontSize)}px`);\n\n if (current.fontStyle !== SVG_DEFAULTS.fontStyle) {\n current.tspan.setAttributeNS(null, "font-style", current.fontStyle);\n }\n\n if (current.fontWeight !== SVG_DEFAULTS.fontWeight) {\n current.tspan.setAttributeNS(null, "font-weight", current.fontWeight);\n }\n\n const fillStrokeMode = current.textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK;\n\n if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) {\n if (current.fillColor !== SVG_DEFAULTS.fillColor) {\n current.tspan.setAttributeNS(null, "fill", current.fillColor);\n }\n\n if (current.fillAlpha < 1) {\n current.tspan.setAttributeNS(null, "fill-opacity", current.fillAlpha);\n }\n } else if (current.textRenderingMode === _util.TextRenderingMode.ADD_TO_PATH) {\n current.tspan.setAttributeNS(null, "fill", "transparent");\n } else {\n current.tspan.setAttributeNS(null, "fill", "none");\n }\n\n if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) {\n const lineWidthScale = 1 / (current.textMatrixScale || 1);\n\n this._setStrokeAttributes(current.tspan, lineWidthScale);\n }\n\n let textMatrix = current.textMatrix;\n\n if (current.textRise !== 0) {\n textMatrix = textMatrix.slice();\n textMatrix[5] += current.textRise;\n }\n\n current.txtElement.setAttributeNS(null, "transform", `${pm(textMatrix)} scale(${pf(textHScale)}, -1)`);\n current.txtElement.setAttributeNS(XML_NS, "xml:space", "preserve");\n current.txtElement.appendChild(current.tspan);\n current.txtgrp.appendChild(current.txtElement);\n\n this._ensureTransformGroup().appendChild(current.txtElement);\n }\n\n setLeadingMoveText(x, y) {\n this.setLeading(-y);\n this.moveText(x, y);\n }\n\n addFontStyle(fontObj) {\n if (!fontObj.data) {\n throw new Error("addFontStyle: No font data available, " + \'ensure that the "fontExtraProperties" API parameter is set.\');\n }\n\n if (!this.cssStyle) {\n this.cssStyle = this.svgFactory.createElement("svg:style");\n this.cssStyle.setAttributeNS(null, "type", "text/css");\n this.defs.appendChild(this.cssStyle);\n }\n\n const url = createObjectURL(fontObj.data, fontObj.mimetype, this.forceDataSchema);\n this.cssStyle.textContent += `@font-face { font-family: "${fontObj.loadedName}";` + ` src: url(${url}); }\\n`;\n }\n\n setFont(details) {\n const current = this.current;\n const fontObj = this.commonObjs.get(details[0]);\n let size = details[1];\n current.font = fontObj;\n\n if (this.embedFonts && !fontObj.missingFile && !this.embeddedFonts[fontObj.loadedName]) {\n this.addFontStyle(fontObj);\n this.embeddedFonts[fontObj.loadedName] = fontObj;\n }\n\n current.fontMatrix = fontObj.fontMatrix || _util.FONT_IDENTITY_MATRIX;\n let bold = "normal";\n\n if (fontObj.black) {\n bold = "900";\n } else if (fontObj.bold) {\n bold = "bold";\n }\n\n const italic = fontObj.italic ? "italic" : "normal";\n\n if (size < 0) {\n size = -size;\n current.fontDirection = -1;\n } else {\n current.fontDirection = 1;\n }\n\n current.fontSize = size;\n current.fontFamily = fontObj.loadedName;\n current.fontWeight = bold;\n current.fontStyle = italic;\n current.tspan = this.svgFactory.createElement("svg:tspan");\n current.tspan.setAttributeNS(null, "y", pf(-current.y));\n current.xcoords = [];\n current.ycoords = [];\n }\n\n endText() {\n const current = this.current;\n\n if (current.textRenderingMode & _util.TextRenderingMode.ADD_TO_PATH_FLAG && current.txtElement?.hasChildNodes()) {\n current.element = current.txtElement;\n this.clip("nonzero");\n this.endPath();\n }\n }\n\n setLineWidth(width) {\n if (width > 0) {\n this.current.lineWidth = width;\n }\n }\n\n setLineCap(style) {\n this.current.lineCap = LINE_CAP_STYLES[style];\n }\n\n setLineJoin(style) {\n this.current.lineJoin = LINE_JOIN_STYLES[style];\n }\n\n setMiterLimit(limit) {\n this.current.miterLimit = limit;\n }\n\n setStrokeAlpha(strokeAlpha) {\n this.current.strokeAlpha = strokeAlpha;\n }\n\n setStrokeRGBColor(r, g, b) {\n this.current.strokeColor = _util.Util.makeHexColor(r, g, b);\n }\n\n setFillAlpha(fillAlpha) {\n this.current.fillAlpha = fillAlpha;\n }\n\n setFillRGBColor(r, g, b) {\n this.current.fillColor = _util.Util.makeHexColor(r, g, b);\n this.current.tspan = this.svgFactory.createElement("svg:tspan");\n this.current.xcoords = [];\n this.current.ycoords = [];\n }\n\n setStrokeColorN(args) {\n this.current.strokeColor = this._makeColorN_Pattern(args);\n }\n\n setFillColorN(args) {\n this.current.fillColor = this._makeColorN_Pattern(args);\n }\n\n shadingFill(args) {\n const width = this.viewport.width;\n const height = this.viewport.height;\n\n const inv = _util.Util.inverseTransform(this.transformMatrix);\n\n const bl = _util.Util.applyTransform([0, 0], inv);\n\n const br = _util.Util.applyTransform([0, height], inv);\n\n const ul = _util.Util.applyTransform([width, 0], inv);\n\n const ur = _util.Util.applyTransform([width, height], inv);\n\n const x0 = Math.min(bl[0], br[0], ul[0], ur[0]);\n const y0 = Math.min(bl[1], br[1], ul[1], ur[1]);\n const x1 = Math.max(bl[0], br[0], ul[0], ur[0]);\n const y1 = Math.max(bl[1], br[1], ul[1], ur[1]);\n const rect = this.svgFactory.createElement("svg:rect");\n rect.setAttributeNS(null, "x", x0);\n rect.setAttributeNS(null, "y", y0);\n rect.setAttributeNS(null, "width", x1 - x0);\n rect.setAttributeNS(null, "height", y1 - y0);\n rect.setAttributeNS(null, "fill", this._makeShadingPattern(args));\n\n if (this.current.fillAlpha < 1) {\n rect.setAttributeNS(null, "fill-opacity", this.current.fillAlpha);\n }\n\n this._ensureTransformGroup().appendChild(rect);\n }\n\n _makeColorN_Pattern(args) {\n if (args[0] === "TilingPattern") {\n return this._makeTilingPattern(args);\n }\n\n return this._makeShadingPattern(args);\n }\n\n _makeTilingPattern(args) {\n const color = args[1];\n const operatorList = args[2];\n const matrix = args[3] || _util.IDENTITY_MATRIX;\n const [x0, y0, x1, y1] = args[4];\n const xstep = args[5];\n const ystep = args[6];\n const paintType = args[7];\n const tilingId = `shading${shadingCount++}`;\n\n const [tx0, ty0, tx1, ty1] = _util.Util.normalizeRect([..._util.Util.applyTransform([x0, y0], matrix), ..._util.Util.applyTransform([x1, y1], matrix)]);\n\n const [xscale, yscale] = _util.Util.singularValueDecompose2dScale(matrix);\n\n const txstep = xstep * xscale;\n const tystep = ystep * yscale;\n const tiling = this.svgFactory.createElement("svg:pattern");\n tiling.setAttributeNS(null, "id", tilingId);\n tiling.setAttributeNS(null, "patternUnits", "userSpaceOnUse");\n tiling.setAttributeNS(null, "width", txstep);\n tiling.setAttributeNS(null, "height", tystep);\n tiling.setAttributeNS(null, "x", `${tx0}`);\n tiling.setAttributeNS(null, "y", `${ty0}`);\n const svg = this.svg;\n const transformMatrix = this.transformMatrix;\n const fillColor = this.current.fillColor;\n const strokeColor = this.current.strokeColor;\n const bbox = this.svgFactory.create(tx1 - tx0, ty1 - ty0);\n this.svg = bbox;\n this.transformMatrix = matrix;\n\n if (paintType === 2) {\n const cssColor = _util.Util.makeHexColor(...color);\n\n this.current.fillColor = cssColor;\n this.current.strokeColor = cssColor;\n }\n\n this.executeOpTree(this.convertOpList(operatorList));\n this.svg = svg;\n this.transformMatrix = transformMatrix;\n this.current.fillColor = fillColor;\n this.current.strokeColor = strokeColor;\n tiling.appendChild(bbox.childNodes[0]);\n this.defs.appendChild(tiling);\n return `url(#${tilingId})`;\n }\n\n _makeShadingPattern(args) {\n if (typeof args === "string") {\n args = this.objs.get(args);\n }\n\n switch (args[0]) {\n case "RadialAxial":\n const shadingId = `shading${shadingCount++}`;\n const colorStops = args[3];\n let gradient;\n\n switch (args[1]) {\n case "axial":\n const point0 = args[4];\n const point1 = args[5];\n gradient = this.svgFactory.createElement("svg:linearGradient");\n gradient.setAttributeNS(null, "id", shadingId);\n gradient.setAttributeNS(null, "gradientUnits", "userSpaceOnUse");\n gradient.setAttributeNS(null, "x1", point0[0]);\n gradient.setAttributeNS(null, "y1", point0[1]);\n gradient.setAttributeNS(null, "x2", point1[0]);\n gradient.setAttributeNS(null, "y2", point1[1]);\n break;\n\n case "radial":\n const focalPoint = args[4];\n const circlePoint = args[5];\n const focalRadius = args[6];\n const circleRadius = args[7];\n gradient = this.svgFactory.createElement("svg:radialGradient");\n gradient.setAttributeNS(null, "id", shadingId);\n gradient.setAttributeNS(null, "gradientUnits", "userSpaceOnUse");\n gradient.setAttributeNS(null, "cx", circlePoint[0]);\n gradient.setAttributeNS(null, "cy", circlePoint[1]);\n gradient.setAttributeNS(null, "r", circleRadius);\n gradient.setAttributeNS(null, "fx", focalPoint[0]);\n gradient.setAttributeNS(null, "fy", focalPoint[1]);\n gradient.setAttributeNS(null, "fr", focalRadius);\n break;\n\n default:\n throw new Error(`Unknown RadialAxial type: ${args[1]}`);\n }\n\n for (const colorStop of colorStops) {\n const stop = this.svgFactory.createElement("svg:stop");\n stop.setAttributeNS(null, "offset", colorStop[0]);\n stop.setAttributeNS(null, "stop-color", colorStop[1]);\n gradient.appendChild(stop);\n }\n\n this.defs.appendChild(gradient);\n return `url(#${shadingId})`;\n\n case "Mesh":\n (0, _util.warn)("Unimplemented pattern Mesh");\n return null;\n\n case "Dummy":\n return "hotpink";\n\n default:\n throw new Error(`Unknown IR type: ${args[0]}`);\n }\n }\n\n setDash(dashArray, dashPhase) {\n this.current.dashArray = dashArray;\n this.current.dashPhase = dashPhase;\n }\n\n constructPath(ops, args) {\n const current = this.current;\n let x = current.x,\n y = current.y;\n let d = [];\n let j = 0;\n\n for (const op of ops) {\n switch (op | 0) {\n case _util.OPS.rectangle:\n x = args[j++];\n y = args[j++];\n const width = args[j++];\n const height = args[j++];\n const xw = x + width;\n const yh = y + height;\n d.push("M", pf(x), pf(y), "L", pf(xw), pf(y), "L", pf(xw), pf(yh), "L", pf(x), pf(yh), "Z");\n break;\n\n case _util.OPS.moveTo:\n x = args[j++];\n y = args[j++];\n d.push("M", pf(x), pf(y));\n break;\n\n case _util.OPS.lineTo:\n x = args[j++];\n y = args[j++];\n d.push("L", pf(x), pf(y));\n break;\n\n case _util.OPS.curveTo:\n x = args[j + 4];\n y = args[j + 5];\n d.push("C", pf(args[j]), pf(args[j + 1]), pf(args[j + 2]), pf(args[j + 3]), pf(x), pf(y));\n j += 6;\n break;\n\n case _util.OPS.curveTo2:\n d.push("C", pf(x), pf(y), pf(args[j]), pf(args[j + 1]), pf(args[j + 2]), pf(args[j + 3]));\n x = args[j + 2];\n y = args[j + 3];\n j += 4;\n break;\n\n case _util.OPS.curveTo3:\n x = args[j + 2];\n y = args[j + 3];\n d.push("C", pf(args[j]), pf(args[j + 1]), pf(x), pf(y), pf(x), pf(y));\n j += 4;\n break;\n\n case _util.OPS.closePath:\n d.push("Z");\n break;\n }\n }\n\n d = d.join(" ");\n\n if (current.path && ops.length > 0 && ops[0] !== _util.OPS.rectangle && ops[0] !== _util.OPS.moveTo) {\n d = current.path.getAttributeNS(null, "d") + d;\n } else {\n current.path = this.svgFactory.createElement("svg:path");\n\n this._ensureTransformGroup().appendChild(current.path);\n }\n\n current.path.setAttributeNS(null, "d", d);\n current.path.setAttributeNS(null, "fill", "none");\n current.element = current.path;\n current.setCurrentPoint(x, y);\n }\n\n endPath() {\n const current = this.current;\n current.path = null;\n\n if (!this.pendingClip) {\n return;\n }\n\n if (!current.element) {\n this.pendingClip = null;\n return;\n }\n\n const clipId = `clippath${clipCount++}`;\n const clipPath = this.svgFactory.createElement("svg:clipPath");\n clipPath.setAttributeNS(null, "id", clipId);\n clipPath.setAttributeNS(null, "transform", pm(this.transformMatrix));\n const clipElement = current.element.cloneNode(true);\n\n if (this.pendingClip === "evenodd") {\n clipElement.setAttributeNS(null, "clip-rule", "evenodd");\n } else {\n clipElement.setAttributeNS(null, "clip-rule", "nonzero");\n }\n\n this.pendingClip = null;\n clipPath.appendChild(clipElement);\n this.defs.appendChild(clipPath);\n\n if (current.activeClipUrl) {\n current.clipGroup = null;\n\n for (const prev of this.extraStack) {\n prev.clipGroup = null;\n }\n\n clipPath.setAttributeNS(null, "clip-path", current.activeClipUrl);\n }\n\n current.activeClipUrl = `url(#${clipId})`;\n this.tgrp = null;\n }\n\n clip(type) {\n this.pendingClip = type;\n }\n\n closePath() {\n const current = this.current;\n\n if (current.path) {\n const d = `${current.path.getAttributeNS(null, "d")}Z`;\n current.path.setAttributeNS(null, "d", d);\n }\n }\n\n setLeading(leading) {\n this.current.leading = -leading;\n }\n\n setTextRise(textRise) {\n this.current.textRise = textRise;\n }\n\n setTextRenderingMode(textRenderingMode) {\n this.current.textRenderingMode = textRenderingMode;\n }\n\n setHScale(scale) {\n this.current.textHScale = scale / 100;\n }\n\n setRenderingIntent(intent) {}\n\n setFlatness(flatness) {}\n\n setGState(states) {\n for (const [key, value] of states) {\n switch (key) {\n case "LW":\n this.setLineWidth(value);\n break;\n\n case "LC":\n this.setLineCap(value);\n break;\n\n case "LJ":\n this.setLineJoin(value);\n break;\n\n case "ML":\n this.setMiterLimit(value);\n break;\n\n case "D":\n this.setDash(value[0], value[1]);\n break;\n\n case "RI":\n this.setRenderingIntent(value);\n break;\n\n case "FL":\n this.setFlatness(value);\n break;\n\n case "Font":\n this.setFont(value);\n break;\n\n case "CA":\n this.setStrokeAlpha(value);\n break;\n\n case "ca":\n this.setFillAlpha(value);\n break;\n\n default:\n (0, _util.warn)(`Unimplemented graphic state operator ${key}`);\n break;\n }\n }\n }\n\n fill() {\n const current = this.current;\n\n if (current.element) {\n current.element.setAttributeNS(null, "fill", current.fillColor);\n current.element.setAttributeNS(null, "fill-opacity", current.fillAlpha);\n this.endPath();\n }\n }\n\n stroke() {\n const current = this.current;\n\n if (current.element) {\n this._setStrokeAttributes(current.element);\n\n current.element.setAttributeNS(null, "fill", "none");\n this.endPath();\n }\n }\n\n _setStrokeAttributes(element, lineWidthScale = 1) {\n const current = this.current;\n let dashArray = current.dashArray;\n\n if (lineWidthScale !== 1 && dashArray.length > 0) {\n dashArray = dashArray.map(function (value) {\n return lineWidthScale * value;\n });\n }\n\n element.setAttributeNS(null, "stroke", current.strokeColor);\n element.setAttributeNS(null, "stroke-opacity", current.strokeAlpha);\n element.setAttributeNS(null, "stroke-miterlimit", pf(current.miterLimit));\n element.setAttributeNS(null, "stroke-linecap", current.lineCap);\n element.setAttributeNS(null, "stroke-linejoin", current.lineJoin);\n element.setAttributeNS(null, "stroke-width", pf(lineWidthScale * current.lineWidth) + "px");\n element.setAttributeNS(null, "stroke-dasharray", dashArray.map(pf).join(" "));\n element.setAttributeNS(null, "stroke-dashoffset", pf(lineWidthScale * current.dashPhase) + "px");\n }\n\n eoFill() {\n if (this.current.element) {\n this.current.element.setAttributeNS(null, "fill-rule", "evenodd");\n }\n\n this.fill();\n }\n\n fillStroke() {\n this.stroke();\n this.fill();\n }\n\n eoFillStroke() {\n if (this.current.element) {\n this.current.element.setAttributeNS(null, "fill-rule", "evenodd");\n }\n\n this.fillStroke();\n }\n\n closeStroke() {\n this.closePath();\n this.stroke();\n }\n\n closeFillStroke() {\n this.closePath();\n this.fillStroke();\n }\n\n closeEOFillStroke() {\n this.closePath();\n this.eoFillStroke();\n }\n\n paintSolidColorImageMask() {\n const rect = this.svgFactory.createElement("svg:rect");\n rect.setAttributeNS(null, "x", "0");\n rect.setAttributeNS(null, "y", "0");\n rect.setAttributeNS(null, "width", "1px");\n rect.setAttributeNS(null, "height", "1px");\n rect.setAttributeNS(null, "fill", this.current.fillColor);\n\n this._ensureTransformGroup().appendChild(rect);\n }\n\n paintImageXObject(objId) {\n const imgData = objId.startsWith("g_") ? this.commonObjs.get(objId) : this.objs.get(objId);\n\n if (!imgData) {\n (0, _util.warn)(`Dependent image with object ID ${objId} is not ready yet`);\n return;\n }\n\n this.paintInlineImageXObject(imgData);\n }\n\n paintInlineImageXObject(imgData, mask) {\n const width = imgData.width;\n const height = imgData.height;\n const imgSrc = convertImgDataToPng(imgData, this.forceDataSchema, !!mask);\n const cliprect = this.svgFactory.createElement("svg:rect");\n cliprect.setAttributeNS(null, "x", "0");\n cliprect.setAttributeNS(null, "y", "0");\n cliprect.setAttributeNS(null, "width", pf(width));\n cliprect.setAttributeNS(null, "height", pf(height));\n this.current.element = cliprect;\n this.clip("nonzero");\n const imgEl = this.svgFactory.createElement("svg:image");\n imgEl.setAttributeNS(XLINK_NS, "xlink:href", imgSrc);\n imgEl.setAttributeNS(null, "x", "0");\n imgEl.setAttributeNS(null, "y", pf(-height));\n imgEl.setAttributeNS(null, "width", pf(width) + "px");\n imgEl.setAttributeNS(null, "height", pf(height) + "px");\n imgEl.setAttributeNS(null, "transform", `scale(${pf(1 / width)} ${pf(-1 / height)})`);\n\n if (mask) {\n mask.appendChild(imgEl);\n } else {\n this._ensureTransformGroup().appendChild(imgEl);\n }\n }\n\n paintImageMaskXObject(imgData) {\n const current = this.current;\n const width = imgData.width;\n const height = imgData.height;\n const fillColor = current.fillColor;\n current.maskId = `mask${maskCount++}`;\n const mask = this.svgFactory.createElement("svg:mask");\n mask.setAttributeNS(null, "id", current.maskId);\n const rect = this.svgFactory.createElement("svg:rect");\n rect.setAttributeNS(null, "x", "0");\n rect.setAttributeNS(null, "y", "0");\n rect.setAttributeNS(null, "width", pf(width));\n rect.setAttributeNS(null, "height", pf(height));\n rect.setAttributeNS(null, "fill", fillColor);\n rect.setAttributeNS(null, "mask", `url(#${current.maskId})`);\n this.defs.appendChild(mask);\n\n this._ensureTransformGroup().appendChild(rect);\n\n this.paintInlineImageXObject(imgData, mask);\n }\n\n paintFormXObjectBegin(matrix, bbox) {\n if (Array.isArray(matrix) && matrix.length === 6) {\n this.transform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);\n }\n\n if (bbox) {\n const width = bbox[2] - bbox[0];\n const height = bbox[3] - bbox[1];\n const cliprect = this.svgFactory.createElement("svg:rect");\n cliprect.setAttributeNS(null, "x", bbox[0]);\n cliprect.setAttributeNS(null, "y", bbox[1]);\n cliprect.setAttributeNS(null, "width", pf(width));\n cliprect.setAttributeNS(null, "height", pf(height));\n this.current.element = cliprect;\n this.clip("nonzero");\n this.endPath();\n }\n }\n\n paintFormXObjectEnd() {}\n\n _initialize(viewport) {\n const svg = this.svgFactory.create(viewport.width, viewport.height);\n const definitions = this.svgFactory.createElement("svg:defs");\n svg.appendChild(definitions);\n this.defs = definitions;\n const rootGroup = this.svgFactory.createElement("svg:g");\n rootGroup.setAttributeNS(null, "transform", pm(viewport.transform));\n svg.appendChild(rootGroup);\n this.svg = rootGroup;\n return svg;\n }\n\n _ensureClipGroup() {\n if (!this.current.clipGroup) {\n const clipGroup = this.svgFactory.createElement("svg:g");\n clipGroup.setAttributeNS(null, "clip-path", this.current.activeClipUrl);\n this.svg.appendChild(clipGroup);\n this.current.clipGroup = clipGroup;\n }\n\n return this.current.clipGroup;\n }\n\n _ensureTransformGroup() {\n if (!this.tgrp) {\n this.tgrp = this.svgFactory.createElement("svg:g");\n this.tgrp.setAttributeNS(null, "transform", pm(this.transformMatrix));\n\n if (this.current.activeClipUrl) {\n this._ensureClipGroup().appendChild(this.tgrp);\n } else {\n this.svg.appendChild(this.tgrp);\n }\n }\n\n return this.tgrp;\n }\n\n };\n}\n\n/***/ }),\n/* 25 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.PDFNodeStream = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _network_utils = __w_pdfjs_require__(26);\n\n;\n\nconst fs = __webpack_require__(172);\n\nconst http = __webpack_require__(1);\n\nconst https = __webpack_require__(779);\n\nconst url = __webpack_require__(558);\n\nconst fileUriRegex = /^file:\\/\\/\\/[a-zA-Z]:\\//;\n\nfunction parseUrl(sourceUrl) {\n const parsedUrl = url.parse(sourceUrl);\n\n if (parsedUrl.protocol === "file:" || parsedUrl.host) {\n return parsedUrl;\n }\n\n if (/^[a-z]:[/\\\\]/i.test(sourceUrl)) {\n return url.parse(`file:///${sourceUrl}`);\n }\n\n if (!parsedUrl.host) {\n parsedUrl.protocol = "file:";\n }\n\n return parsedUrl;\n}\n\nclass PDFNodeStream {\n constructor(source) {\n this.source = source;\n this.url = parseUrl(source.url);\n this.isHttp = this.url.protocol === "http:" || this.url.protocol === "https:";\n this.isFsUrl = this.url.protocol === "file:";\n this.httpHeaders = this.isHttp && source.httpHeaders || {};\n this._fullRequestReader = null;\n this._rangeRequestReaders = [];\n }\n\n get _progressiveDataLength() {\n return this._fullRequestReader?._loaded ?? 0;\n }\n\n getFullReader() {\n (0, _util.assert)(!this._fullRequestReader, "PDFNodeStream.getFullReader can only be called once.");\n this._fullRequestReader = this.isFsUrl ? new PDFNodeStreamFsFullReader(this) : new PDFNodeStreamFullReader(this);\n return this._fullRequestReader;\n }\n\n getRangeReader(start, end) {\n if (end <= this._progressiveDataLength) {\n return null;\n }\n\n const rangeReader = this.isFsUrl ? new PDFNodeStreamFsRangeReader(this, start, end) : new PDFNodeStreamRangeReader(this, start, end);\n\n this._rangeRequestReaders.push(rangeReader);\n\n return rangeReader;\n }\n\n cancelAllRequests(reason) {\n if (this._fullRequestReader) {\n this._fullRequestReader.cancel(reason);\n }\n\n for (const reader of this._rangeRequestReaders.slice(0)) {\n reader.cancel(reason);\n }\n }\n\n}\n\nexports.PDFNodeStream = PDFNodeStream;\n\nclass BaseFullReader {\n constructor(stream) {\n this._url = stream.url;\n this._done = false;\n this._storedError = null;\n this.onProgress = null;\n const source = stream.source;\n this._contentLength = source.length;\n this._loaded = 0;\n this._filename = null;\n this._disableRange = source.disableRange || false;\n this._rangeChunkSize = source.rangeChunkSize;\n\n if (!this._rangeChunkSize && !this._disableRange) {\n this._disableRange = true;\n }\n\n this._isStreamingSupported = !source.disableStream;\n this._isRangeSupported = !source.disableRange;\n this._readableStream = null;\n this._readCapability = (0, _util.createPromiseCapability)();\n this._headersCapability = (0, _util.createPromiseCapability)();\n }\n\n get headersReady() {\n return this._headersCapability.promise;\n }\n\n get filename() {\n return this._filename;\n }\n\n get contentLength() {\n return this._contentLength;\n }\n\n get isRangeSupported() {\n return this._isRangeSupported;\n }\n\n get isStreamingSupported() {\n return this._isStreamingSupported;\n }\n\n async read() {\n await this._readCapability.promise;\n\n if (this._done) {\n return {\n value: undefined,\n done: true\n };\n }\n\n if (this._storedError) {\n throw this._storedError;\n }\n\n const chunk = this._readableStream.read();\n\n if (chunk === null) {\n this._readCapability = (0, _util.createPromiseCapability)();\n return this.read();\n }\n\n this._loaded += chunk.length;\n\n if (this.onProgress) {\n this.onProgress({\n loaded: this._loaded,\n total: this._contentLength\n });\n }\n\n const buffer = new Uint8Array(chunk).buffer;\n return {\n value: buffer,\n done: false\n };\n }\n\n cancel(reason) {\n if (!this._readableStream) {\n this._error(reason);\n\n return;\n }\n\n this._readableStream.destroy(reason);\n }\n\n _error(reason) {\n this._storedError = reason;\n\n this._readCapability.resolve();\n }\n\n _setReadableStream(readableStream) {\n this._readableStream = readableStream;\n readableStream.on("readable", () => {\n this._readCapability.resolve();\n });\n readableStream.on("end", () => {\n readableStream.destroy();\n this._done = true;\n\n this._readCapability.resolve();\n });\n readableStream.on("error", reason => {\n this._error(reason);\n });\n\n if (!this._isStreamingSupported && this._isRangeSupported) {\n this._error(new _util.AbortException("streaming is disabled"));\n }\n\n if (this._storedError) {\n this._readableStream.destroy(this._storedError);\n }\n }\n\n}\n\nclass BaseRangeReader {\n constructor(stream) {\n this._url = stream.url;\n this._done = false;\n this._storedError = null;\n this.onProgress = null;\n this._loaded = 0;\n this._readableStream = null;\n this._readCapability = (0, _util.createPromiseCapability)();\n const source = stream.source;\n this._isStreamingSupported = !source.disableStream;\n }\n\n get isStreamingSupported() {\n return this._isStreamingSupported;\n }\n\n async read() {\n await this._readCapability.promise;\n\n if (this._done) {\n return {\n value: undefined,\n done: true\n };\n }\n\n if (this._storedError) {\n throw this._storedError;\n }\n\n const chunk = this._readableStream.read();\n\n if (chunk === null) {\n this._readCapability = (0, _util.createPromiseCapability)();\n return this.read();\n }\n\n this._loaded += chunk.length;\n\n if (this.onProgress) {\n this.onProgress({\n loaded: this._loaded\n });\n }\n\n const buffer = new Uint8Array(chunk).buffer;\n return {\n value: buffer,\n done: false\n };\n }\n\n cancel(reason) {\n if (!this._readableStream) {\n this._error(reason);\n\n return;\n }\n\n this._readableStream.destroy(reason);\n }\n\n _error(reason) {\n this._storedError = reason;\n\n this._readCapability.resolve();\n }\n\n _setReadableStream(readableStream) {\n this._readableStream = readableStream;\n readableStream.on("readable", () => {\n this._readCapability.resolve();\n });\n readableStream.on("end", () => {\n readableStream.destroy();\n this._done = true;\n\n this._readCapability.resolve();\n });\n readableStream.on("error", reason => {\n this._error(reason);\n });\n\n if (this._storedError) {\n this._readableStream.destroy(this._storedError);\n }\n }\n\n}\n\nfunction createRequestOptions(parsedUrl, headers) {\n return {\n protocol: parsedUrl.protocol,\n auth: parsedUrl.auth,\n host: parsedUrl.hostname,\n port: parsedUrl.port,\n path: parsedUrl.path,\n method: "GET",\n headers\n };\n}\n\nclass PDFNodeStreamFullReader extends BaseFullReader {\n constructor(stream) {\n super(stream);\n\n const handleResponse = response => {\n if (response.statusCode === 404) {\n const error = new _util.MissingPDFException(`Missing PDF "${this._url}".`);\n this._storedError = error;\n\n this._headersCapability.reject(error);\n\n return;\n }\n\n this._headersCapability.resolve();\n\n this._setReadableStream(response);\n\n const getResponseHeader = name => {\n return this._readableStream.headers[name.toLowerCase()];\n };\n\n const {\n allowRangeRequests,\n suggestedLength\n } = (0, _network_utils.validateRangeRequestCapabilities)({\n getResponseHeader,\n isHttp: stream.isHttp,\n rangeChunkSize: this._rangeChunkSize,\n disableRange: this._disableRange\n });\n this._isRangeSupported = allowRangeRequests;\n this._contentLength = suggestedLength || this._contentLength;\n this._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader);\n };\n\n this._request = null;\n\n if (this._url.protocol === "http:") {\n this._request = http.request(createRequestOptions(this._url, stream.httpHeaders), handleResponse);\n } else {\n this._request = https.request(createRequestOptions(this._url, stream.httpHeaders), handleResponse);\n }\n\n this._request.on("error", reason => {\n this._storedError = reason;\n\n this._headersCapability.reject(reason);\n });\n\n this._request.end();\n }\n\n}\n\nclass PDFNodeStreamRangeReader extends BaseRangeReader {\n constructor(stream, start, end) {\n super(stream);\n this._httpHeaders = {};\n\n for (const property in stream.httpHeaders) {\n const value = stream.httpHeaders[property];\n\n if (typeof value === "undefined") {\n continue;\n }\n\n this._httpHeaders[property] = value;\n }\n\n this._httpHeaders.Range = `bytes=${start}-${end - 1}`;\n\n const handleResponse = response => {\n if (response.statusCode === 404) {\n const error = new _util.MissingPDFException(`Missing PDF "${this._url}".`);\n this._storedError = error;\n return;\n }\n\n this._setReadableStream(response);\n };\n\n this._request = null;\n\n if (this._url.protocol === "http:") {\n this._request = http.request(createRequestOptions(this._url, this._httpHeaders), handleResponse);\n } else {\n this._request = https.request(createRequestOptions(this._url, this._httpHeaders), handleResponse);\n }\n\n this._request.on("error", reason => {\n this._storedError = reason;\n });\n\n this._request.end();\n }\n\n}\n\nclass PDFNodeStreamFsFullReader extends BaseFullReader {\n constructor(stream) {\n super(stream);\n let path = decodeURIComponent(this._url.path);\n\n if (fileUriRegex.test(this._url.href)) {\n path = path.replace(/^\\//, "");\n }\n\n fs.lstat(path, (error, stat) => {\n if (error) {\n if (error.code === "ENOENT") {\n error = new _util.MissingPDFException(`Missing PDF "${path}".`);\n }\n\n this._storedError = error;\n\n this._headersCapability.reject(error);\n\n return;\n }\n\n this._contentLength = stat.size;\n\n this._setReadableStream(fs.createReadStream(path));\n\n this._headersCapability.resolve();\n });\n }\n\n}\n\nclass PDFNodeStreamFsRangeReader extends BaseRangeReader {\n constructor(stream, start, end) {\n super(stream);\n let path = decodeURIComponent(this._url.path);\n\n if (fileUriRegex.test(this._url.href)) {\n path = path.replace(/^\\//, "");\n }\n\n this._setReadableStream(fs.createReadStream(path, {\n start,\n end: end - 1\n }));\n }\n\n}\n\n/***/ }),\n/* 26 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.createResponseStatusError = createResponseStatusError;\nexports.extractFilenameFromHeader = extractFilenameFromHeader;\nexports.validateRangeRequestCapabilities = validateRangeRequestCapabilities;\nexports.validateResponseStatus = validateResponseStatus;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _content_disposition = __w_pdfjs_require__(27);\n\nvar _display_utils = __w_pdfjs_require__(5);\n\nfunction validateRangeRequestCapabilities({\n getResponseHeader,\n isHttp,\n rangeChunkSize,\n disableRange\n}) {\n const returnValues = {\n allowRangeRequests: false,\n suggestedLength: undefined\n };\n const length = parseInt(getResponseHeader("Content-Length"), 10);\n\n if (!Number.isInteger(length)) {\n return returnValues;\n }\n\n returnValues.suggestedLength = length;\n\n if (length <= 2 * rangeChunkSize) {\n return returnValues;\n }\n\n if (disableRange || !isHttp) {\n return returnValues;\n }\n\n if (getResponseHeader("Accept-Ranges") !== "bytes") {\n return returnValues;\n }\n\n const contentEncoding = getResponseHeader("Content-Encoding") || "identity";\n\n if (contentEncoding !== "identity") {\n return returnValues;\n }\n\n returnValues.allowRangeRequests = true;\n return returnValues;\n}\n\nfunction extractFilenameFromHeader(getResponseHeader) {\n const contentDisposition = getResponseHeader("Content-Disposition");\n\n if (contentDisposition) {\n let filename = (0, _content_disposition.getFilenameFromContentDispositionHeader)(contentDisposition);\n\n if (filename.includes("%")) {\n try {\n filename = decodeURIComponent(filename);\n } catch (ex) {}\n }\n\n if ((0, _display_utils.isPdfFile)(filename)) {\n return filename;\n }\n }\n\n return null;\n}\n\nfunction createResponseStatusError(status, url) {\n if (status === 404 || status === 0 && url.startsWith("file:")) {\n return new _util.MissingPDFException(\'Missing PDF "\' + url + \'".\');\n }\n\n return new _util.UnexpectedResponseException(`Unexpected server response (${status}) while retrieving PDF "${url}".`, status);\n}\n\nfunction validateResponseStatus(status) {\n return status === 200 || status === 206;\n}\n\n/***/ }),\n/* 27 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.getFilenameFromContentDispositionHeader = getFilenameFromContentDispositionHeader;\n\nvar _util = __w_pdfjs_require__(1);\n\nfunction getFilenameFromContentDispositionHeader(contentDisposition) {\n let needsEncodingFixup = true;\n let tmp = toParamRegExp("filename\\\\*", "i").exec(contentDisposition);\n\n if (tmp) {\n tmp = tmp[1];\n let filename = rfc2616unquote(tmp);\n filename = unescape(filename);\n filename = rfc5987decode(filename);\n filename = rfc2047decode(filename);\n return fixupEncoding(filename);\n }\n\n tmp = rfc2231getparam(contentDisposition);\n\n if (tmp) {\n const filename = rfc2047decode(tmp);\n return fixupEncoding(filename);\n }\n\n tmp = toParamRegExp("filename", "i").exec(contentDisposition);\n\n if (tmp) {\n tmp = tmp[1];\n let filename = rfc2616unquote(tmp);\n filename = rfc2047decode(filename);\n return fixupEncoding(filename);\n }\n\n function toParamRegExp(attributePattern, flags) {\n return new RegExp("(?:^|;)\\\\s*" + attributePattern + "\\\\s*=\\\\s*" + "(" + \'[^";\\\\s][^;\\\\s]*\' + "|" + \'"(?:[^"\\\\\\\\]|\\\\\\\\"?)+"?\' + ")", flags);\n }\n\n function textdecode(encoding, value) {\n if (encoding) {\n if (!/^[\\x00-\\xFF]+$/.test(value)) {\n return value;\n }\n\n try {\n const decoder = new TextDecoder(encoding, {\n fatal: true\n });\n const buffer = (0, _util.stringToBytes)(value);\n value = decoder.decode(buffer);\n needsEncodingFixup = false;\n } catch (e) {}\n }\n\n return value;\n }\n\n function fixupEncoding(value) {\n if (needsEncodingFixup && /[\\x80-\\xff]/.test(value)) {\n value = textdecode("utf-8", value);\n\n if (needsEncodingFixup) {\n value = textdecode("iso-8859-1", value);\n }\n }\n\n return value;\n }\n\n function rfc2231getparam(contentDispositionStr) {\n const matches = [];\n let match;\n const iter = toParamRegExp("filename\\\\*((?!0\\\\d)\\\\d+)(\\\\*?)", "ig");\n\n while ((match = iter.exec(contentDispositionStr)) !== null) {\n let [, n, quot, part] = match;\n n = parseInt(n, 10);\n\n if (n in matches) {\n if (n === 0) {\n break;\n }\n\n continue;\n }\n\n matches[n] = [quot, part];\n }\n\n const parts = [];\n\n for (let n = 0; n < matches.length; ++n) {\n if (!(n in matches)) {\n break;\n }\n\n let [quot, part] = matches[n];\n part = rfc2616unquote(part);\n\n if (quot) {\n part = unescape(part);\n\n if (n === 0) {\n part = rfc5987decode(part);\n }\n }\n\n parts.push(part);\n }\n\n return parts.join("");\n }\n\n function rfc2616unquote(value) {\n if (value.startsWith(\'"\')) {\n const parts = value.slice(1).split(\'\\\\"\');\n\n for (let i = 0; i < parts.length; ++i) {\n const quotindex = parts[i].indexOf(\'"\');\n\n if (quotindex !== -1) {\n parts[i] = parts[i].slice(0, quotindex);\n parts.length = i + 1;\n }\n\n parts[i] = parts[i].replace(/\\\\(.)/g, "$1");\n }\n\n value = parts.join(\'"\');\n }\n\n return value;\n }\n\n function rfc5987decode(extvalue) {\n const encodingend = extvalue.indexOf("\'");\n\n if (encodingend === -1) {\n return extvalue;\n }\n\n const encoding = extvalue.slice(0, encodingend);\n const langvalue = extvalue.slice(encodingend + 1);\n const value = langvalue.replace(/^[^\']*\'/, "");\n return textdecode(encoding, value);\n }\n\n function rfc2047decode(value) {\n if (!value.startsWith("=?") || /[\\x00-\\x19\\x80-\\xff]/.test(value)) {\n return value;\n }\n\n return value.replace(/=\\?([\\w-]*)\\?([QqBb])\\?((?:[^?]|\\?(?!=))*)\\?=/g, function (matches, charset, encoding, text) {\n if (encoding === "q" || encoding === "Q") {\n text = text.replace(/_/g, " ");\n text = text.replace(/=([0-9a-fA-F]{2})/g, function (match, hex) {\n return String.fromCharCode(parseInt(hex, 16));\n });\n return textdecode(charset, text);\n }\n\n try {\n text = atob(text);\n } catch (e) {}\n\n return textdecode(charset, text);\n });\n }\n\n return "";\n}\n\n/***/ }),\n/* 28 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.PDFNetworkStream = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _network_utils = __w_pdfjs_require__(26);\n\n;\nconst OK_RESPONSE = 200;\nconst PARTIAL_CONTENT_RESPONSE = 206;\n\nfunction getArrayBuffer(xhr) {\n const data = xhr.response;\n\n if (typeof data !== "string") {\n return data;\n }\n\n const array = (0, _util.stringToBytes)(data);\n return array.buffer;\n}\n\nclass NetworkManager {\n constructor(url, args = {}) {\n this.url = url;\n this.isHttp = /^https?:/i.test(url);\n this.httpHeaders = this.isHttp && args.httpHeaders || Object.create(null);\n this.withCredentials = args.withCredentials || false;\n\n this.getXhr = args.getXhr || function NetworkManager_getXhr() {\n return new XMLHttpRequest();\n };\n\n this.currXhrId = 0;\n this.pendingRequests = Object.create(null);\n }\n\n requestRange(begin, end, listeners) {\n const args = {\n begin,\n end\n };\n\n for (const prop in listeners) {\n args[prop] = listeners[prop];\n }\n\n return this.request(args);\n }\n\n requestFull(listeners) {\n return this.request(listeners);\n }\n\n request(args) {\n const xhr = this.getXhr();\n const xhrId = this.currXhrId++;\n const pendingRequest = this.pendingRequests[xhrId] = {\n xhr\n };\n xhr.open("GET", this.url);\n xhr.withCredentials = this.withCredentials;\n\n for (const property in this.httpHeaders) {\n const value = this.httpHeaders[property];\n\n if (typeof value === "undefined") {\n continue;\n }\n\n xhr.setRequestHeader(property, value);\n }\n\n if (this.isHttp && "begin" in args && "end" in args) {\n xhr.setRequestHeader("Range", `bytes=${args.begin}-${args.end - 1}`);\n pendingRequest.expectedStatus = PARTIAL_CONTENT_RESPONSE;\n } else {\n pendingRequest.expectedStatus = OK_RESPONSE;\n }\n\n xhr.responseType = "arraybuffer";\n\n if (args.onError) {\n xhr.onerror = function (evt) {\n args.onError(xhr.status);\n };\n }\n\n xhr.onreadystatechange = this.onStateChange.bind(this, xhrId);\n xhr.onprogress = this.onProgress.bind(this, xhrId);\n pendingRequest.onHeadersReceived = args.onHeadersReceived;\n pendingRequest.onDone = args.onDone;\n pendingRequest.onError = args.onError;\n pendingRequest.onProgress = args.onProgress;\n xhr.send(null);\n return xhrId;\n }\n\n onProgress(xhrId, evt) {\n const pendingRequest = this.pendingRequests[xhrId];\n\n if (!pendingRequest) {\n return;\n }\n\n pendingRequest.onProgress?.(evt);\n }\n\n onStateChange(xhrId, evt) {\n const pendingRequest = this.pendingRequests[xhrId];\n\n if (!pendingRequest) {\n return;\n }\n\n const xhr = pendingRequest.xhr;\n\n if (xhr.readyState >= 2 && pendingRequest.onHeadersReceived) {\n pendingRequest.onHeadersReceived();\n delete pendingRequest.onHeadersReceived;\n }\n\n if (xhr.readyState !== 4) {\n return;\n }\n\n if (!(xhrId in this.pendingRequests)) {\n return;\n }\n\n delete this.pendingRequests[xhrId];\n\n if (xhr.status === 0 && this.isHttp) {\n pendingRequest.onError?.(xhr.status);\n return;\n }\n\n const xhrStatus = xhr.status || OK_RESPONSE;\n const ok_response_on_range_request = xhrStatus === OK_RESPONSE && pendingRequest.expectedStatus === PARTIAL_CONTENT_RESPONSE;\n\n if (!ok_response_on_range_request && xhrStatus !== pendingRequest.expectedStatus) {\n pendingRequest.onError?.(xhr.status);\n return;\n }\n\n const chunk = getArrayBuffer(xhr);\n\n if (xhrStatus === PARTIAL_CONTENT_RESPONSE) {\n const rangeHeader = xhr.getResponseHeader("Content-Range");\n const matches = /bytes (\\d+)-(\\d+)\\/(\\d+)/.exec(rangeHeader);\n pendingRequest.onDone({\n begin: parseInt(matches[1], 10),\n chunk\n });\n } else if (chunk) {\n pendingRequest.onDone({\n begin: 0,\n chunk\n });\n } else {\n pendingRequest.onError?.(xhr.status);\n }\n }\n\n getRequestXhr(xhrId) {\n return this.pendingRequests[xhrId].xhr;\n }\n\n isPendingRequest(xhrId) {\n return xhrId in this.pendingRequests;\n }\n\n abortRequest(xhrId) {\n const xhr = this.pendingRequests[xhrId].xhr;\n delete this.pendingRequests[xhrId];\n xhr.abort();\n }\n\n}\n\nclass PDFNetworkStream {\n constructor(source) {\n this._source = source;\n this._manager = new NetworkManager(source.url, {\n httpHeaders: source.httpHeaders,\n withCredentials: source.withCredentials\n });\n this._rangeChunkSize = source.rangeChunkSize;\n this._fullRequestReader = null;\n this._rangeRequestReaders = [];\n }\n\n _onRangeRequestReaderClosed(reader) {\n const i = this._rangeRequestReaders.indexOf(reader);\n\n if (i >= 0) {\n this._rangeRequestReaders.splice(i, 1);\n }\n }\n\n getFullReader() {\n (0, _util.assert)(!this._fullRequestReader, "PDFNetworkStream.getFullReader can only be called once.");\n this._fullRequestReader = new PDFNetworkStreamFullRequestReader(this._manager, this._source);\n return this._fullRequestReader;\n }\n\n getRangeReader(begin, end) {\n const reader = new PDFNetworkStreamRangeRequestReader(this._manager, begin, end);\n reader.onClosed = this._onRangeRequestReaderClosed.bind(this);\n\n this._rangeRequestReaders.push(reader);\n\n return reader;\n }\n\n cancelAllRequests(reason) {\n this._fullRequestReader?.cancel(reason);\n\n for (const reader of this._rangeRequestReaders.slice(0)) {\n reader.cancel(reason);\n }\n }\n\n}\n\nexports.PDFNetworkStream = PDFNetworkStream;\n\nclass PDFNetworkStreamFullRequestReader {\n constructor(manager, source) {\n this._manager = manager;\n const args = {\n onHeadersReceived: this._onHeadersReceived.bind(this),\n onDone: this._onDone.bind(this),\n onError: this._onError.bind(this),\n onProgress: this._onProgress.bind(this)\n };\n this._url = source.url;\n this._fullRequestId = manager.requestFull(args);\n this._headersReceivedCapability = (0, _util.createPromiseCapability)();\n this._disableRange = source.disableRange || false;\n this._contentLength = source.length;\n this._rangeChunkSize = source.rangeChunkSize;\n\n if (!this._rangeChunkSize && !this._disableRange) {\n this._disableRange = true;\n }\n\n this._isStreamingSupported = false;\n this._isRangeSupported = false;\n this._cachedChunks = [];\n this._requests = [];\n this._done = false;\n this._storedError = undefined;\n this._filename = null;\n this.onProgress = null;\n }\n\n _onHeadersReceived() {\n const fullRequestXhrId = this._fullRequestId;\n\n const fullRequestXhr = this._manager.getRequestXhr(fullRequestXhrId);\n\n const getResponseHeader = name => {\n return fullRequestXhr.getResponseHeader(name);\n };\n\n const {\n allowRangeRequests,\n suggestedLength\n } = (0, _network_utils.validateRangeRequestCapabilities)({\n getResponseHeader,\n isHttp: this._manager.isHttp,\n rangeChunkSize: this._rangeChunkSize,\n disableRange: this._disableRange\n });\n\n if (allowRangeRequests) {\n this._isRangeSupported = true;\n }\n\n this._contentLength = suggestedLength || this._contentLength;\n this._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader);\n\n if (this._isRangeSupported) {\n this._manager.abortRequest(fullRequestXhrId);\n }\n\n this._headersReceivedCapability.resolve();\n }\n\n _onDone(data) {\n if (data) {\n if (this._requests.length > 0) {\n const requestCapability = this._requests.shift();\n\n requestCapability.resolve({\n value: data.chunk,\n done: false\n });\n } else {\n this._cachedChunks.push(data.chunk);\n }\n }\n\n this._done = true;\n\n if (this._cachedChunks.length > 0) {\n return;\n }\n\n for (const requestCapability of this._requests) {\n requestCapability.resolve({\n value: undefined,\n done: true\n });\n }\n\n this._requests.length = 0;\n }\n\n _onError(status) {\n this._storedError = (0, _network_utils.createResponseStatusError)(status, this._url);\n\n this._headersReceivedCapability.reject(this._storedError);\n\n for (const requestCapability of this._requests) {\n requestCapability.reject(this._storedError);\n }\n\n this._requests.length = 0;\n this._cachedChunks.length = 0;\n }\n\n _onProgress(evt) {\n this.onProgress?.({\n loaded: evt.loaded,\n total: evt.lengthComputable ? evt.total : this._contentLength\n });\n }\n\n get filename() {\n return this._filename;\n }\n\n get isRangeSupported() {\n return this._isRangeSupported;\n }\n\n get isStreamingSupported() {\n return this._isStreamingSupported;\n }\n\n get contentLength() {\n return this._contentLength;\n }\n\n get headersReady() {\n return this._headersReceivedCapability.promise;\n }\n\n async read() {\n if (this._storedError) {\n throw this._storedError;\n }\n\n if (this._cachedChunks.length > 0) {\n const chunk = this._cachedChunks.shift();\n\n return {\n value: chunk,\n done: false\n };\n }\n\n if (this._done) {\n return {\n value: undefined,\n done: true\n };\n }\n\n const requestCapability = (0, _util.createPromiseCapability)();\n\n this._requests.push(requestCapability);\n\n return requestCapability.promise;\n }\n\n cancel(reason) {\n this._done = true;\n\n this._headersReceivedCapability.reject(reason);\n\n for (const requestCapability of this._requests) {\n requestCapability.resolve({\n value: undefined,\n done: true\n });\n }\n\n this._requests.length = 0;\n\n if (this._manager.isPendingRequest(this._fullRequestId)) {\n this._manager.abortRequest(this._fullRequestId);\n }\n\n this._fullRequestReader = null;\n }\n\n}\n\nclass PDFNetworkStreamRangeRequestReader {\n constructor(manager, begin, end) {\n this._manager = manager;\n const args = {\n onDone: this._onDone.bind(this),\n onError: this._onError.bind(this),\n onProgress: this._onProgress.bind(this)\n };\n this._url = manager.url;\n this._requestId = manager.requestRange(begin, end, args);\n this._requests = [];\n this._queuedChunk = null;\n this._done = false;\n this._storedError = undefined;\n this.onProgress = null;\n this.onClosed = null;\n }\n\n _close() {\n this.onClosed?.(this);\n }\n\n _onDone(data) {\n const chunk = data.chunk;\n\n if (this._requests.length > 0) {\n const requestCapability = this._requests.shift();\n\n requestCapability.resolve({\n value: chunk,\n done: false\n });\n } else {\n this._queuedChunk = chunk;\n }\n\n this._done = true;\n\n for (const requestCapability of this._requests) {\n requestCapability.resolve({\n value: undefined,\n done: true\n });\n }\n\n this._requests.length = 0;\n\n this._close();\n }\n\n _onError(status) {\n this._storedError = (0, _network_utils.createResponseStatusError)(status, this._url);\n\n for (const requestCapability of this._requests) {\n requestCapability.reject(this._storedError);\n }\n\n this._requests.length = 0;\n this._queuedChunk = null;\n }\n\n _onProgress(evt) {\n if (!this.isStreamingSupported) {\n this.onProgress?.({\n loaded: evt.loaded\n });\n }\n }\n\n get isStreamingSupported() {\n return false;\n }\n\n async read() {\n if (this._storedError) {\n throw this._storedError;\n }\n\n if (this._queuedChunk !== null) {\n const chunk = this._queuedChunk;\n this._queuedChunk = null;\n return {\n value: chunk,\n done: false\n };\n }\n\n if (this._done) {\n return {\n value: undefined,\n done: true\n };\n }\n\n const requestCapability = (0, _util.createPromiseCapability)();\n\n this._requests.push(requestCapability);\n\n return requestCapability.promise;\n }\n\n cancel(reason) {\n this._done = true;\n\n for (const requestCapability of this._requests) {\n requestCapability.resolve({\n value: undefined,\n done: true\n });\n }\n\n this._requests.length = 0;\n\n if (this._manager.isPendingRequest(this._requestId)) {\n this._manager.abortRequest(this._requestId);\n }\n\n this._close();\n }\n\n}\n\n/***/ }),\n/* 29 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.PDFFetchStream = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _network_utils = __w_pdfjs_require__(26);\n\n;\n\nfunction createFetchOptions(headers, withCredentials, abortController) {\n return {\n method: "GET",\n headers,\n signal: abortController?.signal,\n mode: "cors",\n credentials: withCredentials ? "include" : "same-origin",\n redirect: "follow"\n };\n}\n\nfunction createHeaders(httpHeaders) {\n const headers = new Headers();\n\n for (const property in httpHeaders) {\n const value = httpHeaders[property];\n\n if (typeof value === "undefined") {\n continue;\n }\n\n headers.append(property, value);\n }\n\n return headers;\n}\n\nclass PDFFetchStream {\n constructor(source) {\n this.source = source;\n this.isHttp = /^https?:/i.test(source.url);\n this.httpHeaders = this.isHttp && source.httpHeaders || {};\n this._fullRequestReader = null;\n this._rangeRequestReaders = [];\n }\n\n get _progressiveDataLength() {\n return this._fullRequestReader?._loaded ?? 0;\n }\n\n getFullReader() {\n (0, _util.assert)(!this._fullRequestReader, "PDFFetchStream.getFullReader can only be called once.");\n this._fullRequestReader = new PDFFetchStreamReader(this);\n return this._fullRequestReader;\n }\n\n getRangeReader(begin, end) {\n if (end <= this._progressiveDataLength) {\n return null;\n }\n\n const reader = new PDFFetchStreamRangeReader(this, begin, end);\n\n this._rangeRequestReaders.push(reader);\n\n return reader;\n }\n\n cancelAllRequests(reason) {\n if (this._fullRequestReader) {\n this._fullRequestReader.cancel(reason);\n }\n\n for (const reader of this._rangeRequestReaders.slice(0)) {\n reader.cancel(reason);\n }\n }\n\n}\n\nexports.PDFFetchStream = PDFFetchStream;\n\nclass PDFFetchStreamReader {\n constructor(stream) {\n this._stream = stream;\n this._reader = null;\n this._loaded = 0;\n this._filename = null;\n const source = stream.source;\n this._withCredentials = source.withCredentials || false;\n this._contentLength = source.length;\n this._headersCapability = (0, _util.createPromiseCapability)();\n this._disableRange = source.disableRange || false;\n this._rangeChunkSize = source.rangeChunkSize;\n\n if (!this._rangeChunkSize && !this._disableRange) {\n this._disableRange = true;\n }\n\n if (typeof AbortController !== "undefined") {\n this._abortController = new AbortController();\n }\n\n this._isStreamingSupported = !source.disableStream;\n this._isRangeSupported = !source.disableRange;\n this._headers = createHeaders(this._stream.httpHeaders);\n const url = source.url;\n fetch(url, createFetchOptions(this._headers, this._withCredentials, this._abortController)).then(response => {\n if (!(0, _network_utils.validateResponseStatus)(response.status)) {\n throw (0, _network_utils.createResponseStatusError)(response.status, url);\n }\n\n this._reader = response.body.getReader();\n\n this._headersCapability.resolve();\n\n const getResponseHeader = name => {\n return response.headers.get(name);\n };\n\n const {\n allowRangeRequests,\n suggestedLength\n } = (0, _network_utils.validateRangeRequestCapabilities)({\n getResponseHeader,\n isHttp: this._stream.isHttp,\n rangeChunkSize: this._rangeChunkSize,\n disableRange: this._disableRange\n });\n this._isRangeSupported = allowRangeRequests;\n this._contentLength = suggestedLength || this._contentLength;\n this._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader);\n\n if (!this._isStreamingSupported && this._isRangeSupported) {\n this.cancel(new _util.AbortException("Streaming is disabled."));\n }\n }).catch(this._headersCapability.reject);\n this.onProgress = null;\n }\n\n get headersReady() {\n return this._headersCapability.promise;\n }\n\n get filename() {\n return this._filename;\n }\n\n get contentLength() {\n return this._contentLength;\n }\n\n get isRangeSupported() {\n return this._isRangeSupported;\n }\n\n get isStreamingSupported() {\n return this._isStreamingSupported;\n }\n\n async read() {\n await this._headersCapability.promise;\n const {\n value,\n done\n } = await this._reader.read();\n\n if (done) {\n return {\n value,\n done\n };\n }\n\n this._loaded += value.byteLength;\n\n if (this.onProgress) {\n this.onProgress({\n loaded: this._loaded,\n total: this._contentLength\n });\n }\n\n const buffer = new Uint8Array(value).buffer;\n return {\n value: buffer,\n done: false\n };\n }\n\n cancel(reason) {\n if (this._reader) {\n this._reader.cancel(reason);\n }\n\n if (this._abortController) {\n this._abortController.abort();\n }\n }\n\n}\n\nclass PDFFetchStreamRangeReader {\n constructor(stream, begin, end) {\n this._stream = stream;\n this._reader = null;\n this._loaded = 0;\n const source = stream.source;\n this._withCredentials = source.withCredentials || false;\n this._readCapability = (0, _util.createPromiseCapability)();\n this._isStreamingSupported = !source.disableStream;\n\n if (typeof AbortController !== "undefined") {\n this._abortController = new AbortController();\n }\n\n this._headers = createHeaders(this._stream.httpHeaders);\n\n this._headers.append("Range", `bytes=${begin}-${end - 1}`);\n\n const url = source.url;\n fetch(url, createFetchOptions(this._headers, this._withCredentials, this._abortController)).then(response => {\n if (!(0, _network_utils.validateResponseStatus)(response.status)) {\n throw (0, _network_utils.createResponseStatusError)(response.status, url);\n }\n\n this._readCapability.resolve();\n\n this._reader = response.body.getReader();\n }).catch(this._readCapability.reject);\n this.onProgress = null;\n }\n\n get isStreamingSupported() {\n return this._isStreamingSupported;\n }\n\n async read() {\n await this._readCapability.promise;\n const {\n value,\n done\n } = await this._reader.read();\n\n if (done) {\n return {\n value,\n done\n };\n }\n\n this._loaded += value.byteLength;\n\n if (this.onProgress) {\n this.onProgress({\n loaded: this._loaded\n });\n }\n\n const buffer = new Uint8Array(value).buffer;\n return {\n value: buffer,\n done: false\n };\n }\n\n cancel(reason) {\n if (this._reader) {\n this._reader.cancel(reason);\n }\n\n if (this._abortController) {\n this._abortController.abort();\n }\n }\n\n}\n\n/***/ })\n/******/ \t]);\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __w_pdfjs_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tvar cachedModule = __webpack_module_cache__[moduleId];\n/******/ \t\tif (cachedModule !== undefined) {\n/******/ \t\t\treturn cachedModule.exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __w_pdfjs_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\nvar __webpack_exports__ = {};\n// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.\n(() => {\nvar exports = __webpack_exports__;\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nObject.defineProperty(exports, "AnnotationLayer", ({\n enumerable: true,\n get: function () {\n return _annotation_layer.AnnotationLayer;\n }\n}));\nObject.defineProperty(exports, "AnnotationMode", ({\n enumerable: true,\n get: function () {\n return _util.AnnotationMode;\n }\n}));\nObject.defineProperty(exports, "CMapCompressionType", ({\n enumerable: true,\n get: function () {\n return _util.CMapCompressionType;\n }\n}));\nObject.defineProperty(exports, "GlobalWorkerOptions", ({\n enumerable: true,\n get: function () {\n return _worker_options.GlobalWorkerOptions;\n }\n}));\nObject.defineProperty(exports, "InvalidPDFException", ({\n enumerable: true,\n get: function () {\n return _util.InvalidPDFException;\n }\n}));\nObject.defineProperty(exports, "LoopbackPort", ({\n enumerable: true,\n get: function () {\n return _api.LoopbackPort;\n }\n}));\nObject.defineProperty(exports, "MissingPDFException", ({\n enumerable: true,\n get: function () {\n return _util.MissingPDFException;\n }\n}));\nObject.defineProperty(exports, "OPS", ({\n enumerable: true,\n get: function () {\n return _util.OPS;\n }\n}));\nObject.defineProperty(exports, "PDFDataRangeTransport", ({\n enumerable: true,\n get: function () {\n return _api.PDFDataRangeTransport;\n }\n}));\nObject.defineProperty(exports, "PDFDateString", ({\n enumerable: true,\n get: function () {\n return _display_utils.PDFDateString;\n }\n}));\nObject.defineProperty(exports, "PDFWorker", ({\n enumerable: true,\n get: function () {\n return _api.PDFWorker;\n }\n}));\nObject.defineProperty(exports, "PasswordResponses", ({\n enumerable: true,\n get: function () {\n return _util.PasswordResponses;\n }\n}));\nObject.defineProperty(exports, "PermissionFlag", ({\n enumerable: true,\n get: function () {\n return _util.PermissionFlag;\n }\n}));\nObject.defineProperty(exports, "PixelsPerInch", ({\n enumerable: true,\n get: function () {\n return _display_utils.PixelsPerInch;\n }\n}));\nObject.defineProperty(exports, "RenderingCancelledException", ({\n enumerable: true,\n get: function () {\n return _display_utils.RenderingCancelledException;\n }\n}));\nObject.defineProperty(exports, "SVGGraphics", ({\n enumerable: true,\n get: function () {\n return _svg.SVGGraphics;\n }\n}));\nObject.defineProperty(exports, "UNSUPPORTED_FEATURES", ({\n enumerable: true,\n get: function () {\n return _util.UNSUPPORTED_FEATURES;\n }\n}));\nObject.defineProperty(exports, "UnexpectedResponseException", ({\n enumerable: true,\n get: function () {\n return _util.UnexpectedResponseException;\n }\n}));\nObject.defineProperty(exports, "Util", ({\n enumerable: true,\n get: function () {\n return _util.Util;\n }\n}));\nObject.defineProperty(exports, "VerbosityLevel", ({\n enumerable: true,\n get: function () {\n return _util.VerbosityLevel;\n }\n}));\nObject.defineProperty(exports, "XfaLayer", ({\n enumerable: true,\n get: function () {\n return _xfa_layer.XfaLayer;\n }\n}));\nObject.defineProperty(exports, "build", ({\n enumerable: true,\n get: function () {\n return _api.build;\n }\n}));\nObject.defineProperty(exports, "createPromiseCapability", ({\n enumerable: true,\n get: function () {\n return _util.createPromiseCapability;\n }\n}));\nObject.defineProperty(exports, "createValidAbsoluteUrl", ({\n enumerable: true,\n get: function () {\n return _util.createValidAbsoluteUrl;\n }\n}));\nObject.defineProperty(exports, "getDocument", ({\n enumerable: true,\n get: function () {\n return _api.getDocument;\n }\n}));\nObject.defineProperty(exports, "getFilenameFromUrl", ({\n enumerable: true,\n get: function () {\n return _display_utils.getFilenameFromUrl;\n }\n}));\nObject.defineProperty(exports, "getPdfFilenameFromUrl", ({\n enumerable: true,\n get: function () {\n return _display_utils.getPdfFilenameFromUrl;\n }\n}));\nObject.defineProperty(exports, "getXfaPageViewport", ({\n enumerable: true,\n get: function () {\n return _display_utils.getXfaPageViewport;\n }\n}));\nObject.defineProperty(exports, "isPdfFile", ({\n enumerable: true,\n get: function () {\n return _display_utils.isPdfFile;\n }\n}));\nObject.defineProperty(exports, "loadScript", ({\n enumerable: true,\n get: function () {\n return _display_utils.loadScript;\n }\n}));\nObject.defineProperty(exports, "renderTextLayer", ({\n enumerable: true,\n get: function () {\n return _text_layer.renderTextLayer;\n }\n}));\nObject.defineProperty(exports, "shadow", ({\n enumerable: true,\n get: function () {\n return _util.shadow;\n }\n}));\nObject.defineProperty(exports, "version", ({\n enumerable: true,\n get: function () {\n return _api.version;\n }\n}));\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _api = __w_pdfjs_require__(4);\n\nvar _display_utils = __w_pdfjs_require__(5);\n\nvar _annotation_layer = __w_pdfjs_require__(20);\n\nvar _worker_options = __w_pdfjs_require__(13);\n\nvar _is_node = __w_pdfjs_require__(3);\n\nvar _text_layer = __w_pdfjs_require__(23);\n\nvar _svg = __w_pdfjs_require__(24);\n\nvar _xfa_layer = __w_pdfjs_require__(22);\n\nconst pdfjsVersion = \'2.14.305\';\nconst pdfjsBuild = \'eaaa8b4ad\';\n{\n if (_is_node.isNodeJS) {\n const {\n PDFNodeStream\n } = __w_pdfjs_require__(25);\n\n (0, _api.setPDFNetworkStreamFactory)(params => {\n return new PDFNodeStream(params);\n });\n } else {\n const {\n PDFNetworkStream\n } = __w_pdfjs_require__(28);\n\n const {\n PDFFetchStream\n } = __w_pdfjs_require__(29);\n\n (0, _api.setPDFNetworkStreamFactory)(params => {\n if ((0, _display_utils.isValidFetchUrl)(params.url)) {\n return new PDFFetchStream(params);\n }\n\n return new PDFNetworkStream(params);\n });\n }\n}\n})();\n\n/******/ \treturn __webpack_exports__;\n/******/ })()\n;\n});\n//# sourceMappingURL=pdf.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9wZGZqcy1kaXN0L2J1aWxkL3BkZi5qcz85NTExIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLElBQUksSUFBeUQ7QUFDN0Q7QUFDQSxNQUFNLEVBS3FEO0FBQzNELENBQUM7QUFDRCx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx5QkFBeUIsSUFBSTtBQUM3QjtBQUNBOztBQUVBO0FBQ0E7QUFDQSw0QkFBNEIsSUFBSTtBQUNoQztBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMEJBQTBCLElBQUk7QUFDOUI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxpQkFBaUIsWUFBWTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsaUJBQWlCLFlBQVk7QUFDN0I7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBLGlCQUFpQixZQUFZO0FBQzdCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxpQkFBaUIsWUFBWTtBQUM3Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxlQUFlLGNBQWMsRUFBRSxjQUFjLEVBQUUsY0FBYztBQUM3RDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUIsT0FBTztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLE9BQU87QUFDUCxvQ0FBb0MsR0FBRztBQUN2QztBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsa0NBQWtDLFFBQVE7QUFDMUM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQSxnQkFBZ0IsTUFBTTtBQUN0QixHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsa0NBQWtDLFFBQVE7QUFDMUM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsbUNBQW1DLFFBQVE7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7O0FBRUE7O0FBRUEsT0FBTztBQUNQO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTs7QUFFQSxPQUFPO0FBQ1A7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWCx5REFBeUQsR0FBRztBQUM1RDtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQixnQ0FBZ0M7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHLEtBQUs7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0EsR0FBRyxLQUFLO0FBQ1I7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGFBQWE7QUFDYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsYUFBYTtBQUNiO0FBQ0E7O0FBRUE7QUFDQSxPQUFPO0FBQ1A7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRyxLQUFLO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUcsS0FBSztBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBLEtBQUs7QUFDTDs7QUFFQSw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87O0FBRVA7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0RBQWtELFFBQVE7QUFDMUQ7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXOztBQUVYO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQSw0RkFBNEY7QUFDNUY7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCLFVBQWM7QUFDekM7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0Esc0NBQXNDLElBQUksR0FBRztBQUM3QztBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdB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RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULE9BQU87QUFDUDtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwwREFBMEQsY0FBYztBQUN4RTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsV0FBVztBQUNYO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFdBQVc7QUFDWDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDREQUE0RCxLQUFLO0FBQ2pFO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7O0FBRUE7QUFDQSxhQUFhO0FBQ2I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxREFBcUQsS0FBSztBQUMxRDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDhDQUE4QyxnQkFBZ0I7QUFDOUQ7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsbUVBQW1FLE1BQU07QUFDekU7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsdURBQXVEO0FBQ3ZEOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSx1R0FBdUcsb0JBQW9CO0FBQzNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHLEtBQUs7QUFDUjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHLEtBQUs7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxzREFBc0QsS0FBSztBQUMzRDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx3REFBd0QsS0FBSztBQUM3RDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxQkFBcUIsMEJBQTBCLEdBQUcsU0FBUztBQUMzRDs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNM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QUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUIsSUFBSSxHQUFHLHNCQUFzQjtBQUNsRDs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSx3Q0FBd0MsUUFBUTtBQUNoRDs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixpQkFBaUI7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUEsT0FBTztBQUNQO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0EsQ0FBQztBQUNEOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGFBQWEsV0FBVztBQUN4QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGFBQWEsWUFBWTtBQUN6QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLGVBQWUsV0FBVztBQUMxQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsYUFBYSxXQUFXO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBLGFBQWEsc0JBQXNCO0FBQ25DO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxPQUFPOztBQUVQOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUEsc0NBQXNDLFFBQVE7QUFDOUM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7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QUFDQTs7QUFFQSxpQkFBaUIsWUFBWTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsbUJBQW1CLGNBQWM7QUFDakM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlFQUF5RSxFQUFFOztBQUUzRTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0EsdUNBQXVDLFFBQVE7QUFDL0M7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwyQ0FBMkMsUUFBUTtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsbUJBQW1CLGtCQUFrQjtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDZDQUE2QyxZQUFZO0FBQ3pEOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBLHlCQUF5QixLQUFLLEtBQUsscUJBQXFCO0FBQ3hEOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBLHVCQUF1QixPQUFPLEdBQUcsS0FBSyxHQUFHLGdCQUFnQixLQUFLLFNBQVM7QUFDdkU7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixpQkFBaUI7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxlQUFlLGtCQUFrQjtBQUNqQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZUFBZSxrQkFBa0I7QUFDakM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSw0Q0FBNEMscUJBQXFCO0FBQ2pFO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULCtEQUErRCw4Q0FBOEM7QUFDN0cscUNBQXFDLE1BQU0sT0FBTyx1QkFBdUI7QUFDekUsc0NBQXNDLE9BQU8sT0FBTyx1QkFBdUI7QUFDM0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSwwQ0FBMEMsUUFBUTtBQUNsRDs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsdUNBQXVDLFFBQVE7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLDBDQUEwQyxRQUFRO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsb0NBQW9DLFFBQVE7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG9EQUFvRCxRQUFRO0FBQzVEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPO0FBQ1A7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1Asa0VBQWtFLFlBQVk7QUFDOUU7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsb0JBQW9CLFdBQVc7QUFDL0I7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHFCQUFxQixVQUFVO0FBQy9COztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGlCQUFpQixVQUFVO0FBQzNCOztBQUVBLHVCQUF1QixVQUFVO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsaUNBQWlDLFFBQVE7QUFDekM7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsd0NBQXdDLFFBQVE7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHNDQUFzQyxNQUFNO0FBQzVDOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLCtEQUErRCxVQUFVO0FBQ3pFO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTCxvREFBb0QsWUFBWTtBQUNoRTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIsWUFBWTtBQUM3Qiw0Q0FBNEMsY0FBYztBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsbUJBQW1CLG9CQUFvQjtBQUN2QztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPO0FBQ1A7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPO0FBQ1A7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EscURBQXFELFdBQVc7QUFDaEU7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSx1REFBdUQsWUFBWTtBQUNuRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWCxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGdFQUFnRSxXQUFXO0FBQzNFOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxPQUFPOztBQUVQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWCxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYLFNBQVM7QUFDVDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1gsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxPQUFPO0FBQ1A7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBLG1CQUFtQixZQUFZO0FBQy9CO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLE9BQU87QUFDUCw2REFBNkQsUUFBUTtBQUNyRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2REFBNkQsU0FBUztBQUN0RTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxpRUFBaUUsR0FBRztBQUNwRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxpRUFBaUUsR0FBRztBQUNwRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxpRUFBaUUsR0FBRztBQUNwRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxpRUFBaUUsR0FBRztBQUNwRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEseURBQXlELGFBQWE7QUFDdEU7QUFDQTs7QUFFQSwwQ0FBMEMsV0FBVztBQUNyRDtBQUNBOztBQUVBO0FBQ0E7QUFDQSwyREFBMkQsR0FBRztBQUM5RDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxPQUFPO0FBQ1A7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQSxPQUFPO0FBQ1A7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsT0FBTztBQUNQO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsZUFBZSxtQkFBTyxDQUFDLEdBQUk7O0FBRTNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQSxtQkFBbUIsbUJBQU8sQ0FBQyxHQUFROztBQUVuQztBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHLEtBQUs7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxxQkFBcUIsT0FBTztBQUM1QjtBQUNBOztBQUVBLDRDQUE0QyxvQkFBb0I7QUFDaEUsS0FBSztBQUNMLDRDQUE0Qyw2QkFBNkI7QUFDekU7O0FBRUEseUNBQXlDLFNBQVMsS0FBSyxTQUFTOztBQUVoRTtBQUNBLHVDQUF1Qyx1QkFBdUI7O0FBRTlEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSwwQkFBMEIsaUJBQWlCLE9BQU8sZUFBZTtBQUNqRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUEsOEJBQThCLFFBQVE7QUFDdEMsNkJBQTZCLFFBQVE7O0FBRXJDO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsaUNBQWlDLE1BQU07QUFDdkMsa0NBQWtDLE9BQU87QUFDekM7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSwwRUFBMEUsU0FBUztBQUNuRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULE9BQU87QUFDUDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLHlFQUF5RSxHQUFHO0FBQzVFO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsTUFBTTtBQUMxQjtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0EsYUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxlQUFlO0FBQ2YsYUFBYTs7QUFFYjtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0EsV0FBVztBQUNYO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXOztBQUVYO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1gsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiOztBQUVBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFdBQVc7QUFDWDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4Q0FBOEMsVUFBVTtBQUN4RDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0EsMEJBQTBCLFNBQVM7QUFDbkM7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7O0FBRUE7O0FBRUE7QUFDQSxPQUFPOztBQUVQO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLE9BQU87O0FBRVA7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7O0FBRUEsa0NBQWtDLFNBQVM7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDLFNBQVM7O0FBRS9DO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFdBQVc7O0FBRVg7QUFDQTtBQUNBLFdBQVc7O0FBRVg7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixXQUFXOztBQUVYO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixXQUFXOztBQUVYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsV0FBVzs7QUFFWDtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsV0FBVzs7QUFFWDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFdBQVc7O0FBRVg7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPOztBQUVQO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1A7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSw2Q0FBNkMsbUJBQW1CO0FBQ2hFOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBOztBQUVBO0FBQ0E7QUFDQSw4Q0FBOEMsV0FBVyxLQUFLLFVBQVU7QUFDeEUsbUNBQW1DLFVBQVU7QUFDN0Msa0NBQWtDLFNBQVM7QUFDM0M7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxNQUFNLElBQUksTUFBTTtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPOztBQUVQO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHNDQUFzQyxRQUFRO0FBQzlDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsRUFBRSxHQUFHLEVBQUU7QUFDOUI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLDZCQUE2QixvQkFBb0I7QUFDakQ7O0FBRUE7QUFDQSxvRUFBb0UsUUFBUTs7QUFFNUU7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLDZCQUE2QixPQUFPO0FBQ3BDO0FBQ0E7O0FBRUEsb0NBQW9DLHVCQUF1QjtBQUMzRDs7QUFFQTtBQUNBO0FBQ0Esb0NBQW9DLEtBQUs7QUFDekMsbUNBQW1DLElBQUk7QUFDdkMsK0NBQStDLE1BQU0sS0FBSyxLQUFLO0FBQy9EO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0VBQWdFLEdBQUc7O0FBRW5FO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsZUFBZSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUU7QUFDekI7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUU7QUFDekI7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUEsT0FBTztBQUNQO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0EsQ0FBQztBQUNEOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1gsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixXQUFXO0FBQ1gsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFdBQVc7QUFDWDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1gsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBLDJCQUEyQixnQkFBZ0IsR0FBRyxPQUFPO0FBQ3JEOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtDQUFrQyx3Q0FBd0M7QUFDMUU7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0NBQWdDLHdDQUF3QztBQUN4RTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUEsT0FBTztBQUNQO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0EsQ0FBQztBQUNEOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxnQkFBZ0Isa0JBQWtCLEtBQUssV0FBVztBQUNsRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEscUNBQXFDLFFBQVE7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxxQ0FBcUMsUUFBUTtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUEsMEJBQTBCLEtBQUs7QUFDL0IseUJBQXlCLElBQUk7QUFDN0IsOEJBQThCLFdBQVc7QUFDekM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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Q0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxzREFBc0QsR0FBRztBQUN6RDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlEQUF5RCxxQkFBcUI7QUFDOUU7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlEQUF5RCxxQkFBcUI7QUFDOUU7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTOztBQUVUOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQSx5REFBeUQscUJBQXFCOztBQUU5RTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw4REFBOEQsZUFBZSxTQUFTLGVBQWU7QUFDckc7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdEQUFnRCxpQkFBaUIsbUJBQW1CLEVBQUUsaUJBQWlCLElBQUksRUFBRSxFQUFFO0FBQy9HOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQyxlQUFlOztBQUVoRDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQyxJQUFJO0FBQzlDLDBDQUEwQyxJQUFJO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLFNBQVM7QUFDOUI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHNDQUFzQyxlQUFlO0FBQ3JEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJEQUEyRCxRQUFRO0FBQ25FOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHlCQUF5QixVQUFVOztBQUVuQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDhDQUE4QyxRQUFRO0FBQ3REO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxnQ0FBZ0MsWUFBWTtBQUM1QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsc0NBQXNDLE9BQU87QUFDN0M7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLHFCQUFxQix1Q0FBdUM7QUFDNUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxvRUFBb0UsSUFBSTtBQUN4RTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDBEQUEwRCxNQUFNO0FBQ2hFO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdURBQXVELGNBQWMsR0FBRyxnQkFBZ0I7O0FBRXhGO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEIsWUFBWTtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELGVBQWU7QUFDL0Q7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQSxXQUFXLG1CQUFPLENBQUMsR0FBSTs7QUFFdkIsYUFBYSxtQkFBTyxDQUFDLENBQU07O0FBRTNCLGNBQWMsbUJBQU8sQ0FBQyxHQUFPOztBQUU3QixZQUFZLG1CQUFPLENBQUMsR0FBSzs7QUFFekI7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxnQ0FBZ0MsVUFBVTtBQUMxQzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvRUFBb0UsVUFBVTtBQUM5RTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSx1Q0FBdUMsTUFBTSxHQUFHLFFBQVE7O0FBRXhEO0FBQ0E7QUFDQSxvRUFBb0UsVUFBVTtBQUM5RTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLEtBQUs7QUFDckU7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7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Q0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSwyQ0FBMkMsTUFBTSxHQUFHLFFBQVE7O0FBRTVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0EsVUFBVTtBQUNWO0FBQ0EsQ0FBQztBQUNEIiwiZmlsZSI6IjI5OS5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY3N0YXJ0IFRoZSBmb2xsb3dpbmcgaXMgdGhlIGVudGlyZSBsaWNlbnNlIG5vdGljZSBmb3IgdGhlXG4gKiBKYXZhU2NyaXB0IGNvZGUgaW4gdGhpcyBwYWdlXG4gKlxuICogQ29weXJpZ2h0IDIwMjIgTW96aWxsYSBGb3VuZGF0aW9uXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqIEBsaWNlbmQgVGhlIGFib3ZlIGlzIHRoZSBlbnRpcmUgbGljZW5zZSBub3RpY2UgZm9yIHRoZVxuICogSmF2YVNjcmlwdCBjb2RlIGluIHRoaXMgcGFnZVxuICovXG5cbihmdW5jdGlvbiB3ZWJwYWNrVW5pdmVyc2FsTW9kdWxlRGVmaW5pdGlvbihyb290LCBmYWN0b3J5KSB7XG5cdGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0Jylcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTtcblx0ZWxzZSBpZih0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXG5cdFx0ZGVmaW5lKFwicGRmanMtZGlzdC9idWlsZC9wZGZcIiwgW10sIGZhY3RvcnkpO1xuXHRlbHNlIGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jylcblx0XHRleHBvcnRzW1wicGRmanMtZGlzdC9idWlsZC9wZGZcIl0gPSBmYWN0b3J5KCk7XG5cdGVsc2Vcblx0XHRyb290W1wicGRmanMtZGlzdC9idWlsZC9wZGZcIl0gPSByb290LnBkZmpzTGliID0gZmFjdG9yeSgpO1xufSkodGhpcywgKCkgPT4ge1xucmV0dXJuIC8qKioqKiovICgoKSA9PiB7IC8vIHdlYnBhY2tCb290c3RyYXBcbi8qKioqKiovIFx0XCJ1c2Ugc3RyaWN0XCI7XG4vKioqKioqLyBcdHZhciBfX3dlYnBhY2tfbW9kdWxlc19fID0gKFtcbi8qIDAgKi8sXG4vKiAxICovXG4vKioqLyAoKF9fdW51c2VkX3dlYnBhY2tfbW9kdWxlLCBleHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5leHBvcnRzLlZlcmJvc2l0eUxldmVsID0gZXhwb3J0cy5VdGlsID0gZXhwb3J0cy5Vbmtub3duRXJyb3JFeGNlcHRpb24gPSBleHBvcnRzLlVuZXhwZWN0ZWRSZXNwb25zZUV4Y2VwdGlvbiA9IGV4cG9ydHMuVU5TVVBQT1JURURfRkVBVFVSRVMgPSBleHBvcnRzLlRleHRSZW5kZXJpbmdNb2RlID0gZXhwb3J0cy5TdHJlYW1UeXBlID0gZXhwb3J0cy5SZW5kZXJpbmdJbnRlbnRGbGFnID0gZXhwb3J0cy5QZXJtaXNzaW9uRmxhZyA9IGV4cG9ydHMuUGFzc3dvcmRSZXNwb25zZXMgPSBleHBvcnRzLlBhc3N3b3JkRXhjZXB0aW9uID0gZXhwb3J0cy5QYWdlQWN0aW9uRXZlbnRUeXBlID0gZXhwb3J0cy5PUFMgPSBleHBvcnRzLk1pc3NpbmdQREZFeGNlcHRpb24gPSBleHBvcnRzLkludmFsaWRQREZFeGNlcHRpb24gPSBleHBvcnRzLkltYWdlS2luZCA9IGV4cG9ydHMuSURFTlRJVFlfTUFUUklYID0gZXhwb3J0cy5Gb3JtYXRFcnJvciA9IGV4cG9ydHMuRm9udFR5cGUgPSBleHBvcnRzLkZlYXR1cmVUZXN0ID0gZXhwb3J0cy5GT05UX0lERU5USVRZX01BVFJJWCA9IGV4cG9ydHMuRG9jdW1lbnRBY3Rpb25FdmVudFR5cGUgPSBleHBvcnRzLkNNYXBDb21wcmVzc2lvblR5cGUgPSBleHBvcnRzLkJhc2VFeGNlcHRpb24gPSBleHBvcnRzLkFubm90YXRpb25UeXBlID0gZXhwb3J0cy5Bbm5vdGF0aW9uU3RhdGVNb2RlbFR5cGUgPSBleHBvcnRzLkFubm90YXRpb25SZXZpZXdTdGF0ZSA9IGV4cG9ydHMuQW5ub3RhdGlvblJlcGx5VHlwZSA9IGV4cG9ydHMuQW5ub3RhdGlvbk1vZGUgPSBleHBvcnRzLkFubm90YXRpb25NYXJrZWRTdGF0ZSA9IGV4cG9ydHMuQW5ub3RhdGlvbkZsYWcgPSBleHBvcnRzLkFubm90YXRpb25GaWVsZEZsYWcgPSBleHBvcnRzLkFubm90YXRpb25Cb3JkZXJTdHlsZVR5cGUgPSBleHBvcnRzLkFubm90YXRpb25BY3Rpb25FdmVudFR5cGUgPSBleHBvcnRzLkFib3J0RXhjZXB0aW9uID0gdm9pZCAwO1xuZXhwb3J0cy5hcnJheUJ5dGVMZW5ndGggPSBhcnJheUJ5dGVMZW5ndGg7XG5leHBvcnRzLmFycmF5c1RvQnl0ZXMgPSBhcnJheXNUb0J5dGVzO1xuZXhwb3J0cy5hc3NlcnQgPSBhc3NlcnQ7XG5leHBvcnRzLmJ5dGVzVG9TdHJpbmcgPSBieXRlc1RvU3RyaW5nO1xuZXhwb3J0cy5jcmVhdGVQcm9taXNlQ2FwYWJpbGl0eSA9IGNyZWF0ZVByb21pc2VDYXBhYmlsaXR5O1xuZXhwb3J0cy5jcmVhdGVWYWxpZEFic29sdXRlVXJsID0gY3JlYXRlVmFsaWRBYnNvbHV0ZVVybDtcbmV4cG9ydHMuZXNjYXBlU3RyaW5nID0gZXNjYXBlU3RyaW5nO1xuZXhwb3J0cy5nZXRNb2RpZmljYXRpb25EYXRlID0gZ2V0TW9kaWZpY2F0aW9uRGF0ZTtcbmV4cG9ydHMuZ2V0VmVyYm9zaXR5TGV2ZWwgPSBnZXRWZXJib3NpdHlMZXZlbDtcbmV4cG9ydHMuaW5mbyA9IGluZm87XG5leHBvcnRzLmlzQXJyYXlCdWZmZXIgPSBpc0FycmF5QnVmZmVyO1xuZXhwb3J0cy5pc0FycmF5RXF1YWwgPSBpc0FycmF5RXF1YWw7XG5leHBvcnRzLmlzQXNjaWkgPSBpc0FzY2lpO1xuZXhwb3J0cy5vYmplY3RGcm9tTWFwID0gb2JqZWN0RnJvbU1hcDtcbmV4cG9ydHMub2JqZWN0U2l6ZSA9IG9iamVjdFNpemU7XG5leHBvcnRzLnNldFZlcmJvc2l0eUxldmVsID0gc2V0VmVyYm9zaXR5TGV2ZWw7XG5leHBvcnRzLnNoYWRvdyA9IHNoYWRvdztcbmV4cG9ydHMuc3RyaW5nMzIgPSBzdHJpbmczMjtcbmV4cG9ydHMuc3RyaW5nVG9CeXRlcyA9IHN0cmluZ1RvQnl0ZXM7XG5leHBvcnRzLnN0cmluZ1RvUERGU3RyaW5nID0gc3RyaW5nVG9QREZTdHJpbmc7XG5leHBvcnRzLnN0cmluZ1RvVVRGMTZCRVN0cmluZyA9IHN0cmluZ1RvVVRGMTZCRVN0cmluZztcbmV4cG9ydHMuc3RyaW5nVG9VVEY4U3RyaW5nID0gc3RyaW5nVG9VVEY4U3RyaW5nO1xuZXhwb3J0cy51bnJlYWNoYWJsZSA9IHVucmVhY2hhYmxlO1xuZXhwb3J0cy51dGY4U3RyaW5nVG9TdHJpbmcgPSB1dGY4U3RyaW5nVG9TdHJpbmc7XG5leHBvcnRzLndhcm4gPSB3YXJuO1xuXG5fX3dfcGRmanNfcmVxdWlyZV9fKDIpO1xuXG5jb25zdCBJREVOVElUWV9NQVRSSVggPSBbMSwgMCwgMCwgMSwgMCwgMF07XG5leHBvcnRzLklERU5USVRZX01BVFJJWCA9IElERU5USVRZX01BVFJJWDtcbmNvbnN0IEZPTlRfSURFTlRJVFlfTUFUUklYID0gWzAuMDAxLCAwLCAwLCAwLjAwMSwgMCwgMF07XG5leHBvcnRzLkZPTlRfSURFTlRJVFlfTUFUUklYID0gRk9OVF9JREVOVElUWV9NQVRSSVg7XG5jb25zdCBSZW5kZXJpbmdJbnRlbnRGbGFnID0ge1xuICBBTlk6IDB4MDEsXG4gIERJU1BMQVk6IDB4MDIsXG4gIFBSSU5UOiAweDA0LFxuICBBTk5PVEFUSU9OU19GT1JNUzogMHgxMCxcbiAgQU5OT1RBVElPTlNfU1RPUkFHRTogMHgyMCxcbiAgQU5OT1RBVElPTlNfRElTQUJMRTogMHg0MCxcbiAgT1BMSVNUOiAweDEwMFxufTtcbmV4cG9ydHMuUmVuZGVyaW5nSW50ZW50RmxhZyA9IFJlbmRlcmluZ0ludGVudEZsYWc7XG5jb25zdCBBbm5vdGF0aW9uTW9kZSA9IHtcbiAgRElTQUJMRTogMCxcbiAgRU5BQkxFOiAxLFxuICBFTkFCTEVfRk9STVM6IDIsXG4gIEVOQUJMRV9TVE9SQUdFOiAzXG59O1xuZXhwb3J0cy5Bbm5vdGF0aW9uTW9kZSA9IEFubm90YXRpb25Nb2RlO1xuY29uc3QgUGVybWlzc2lvbkZsYWcgPSB7XG4gIFBSSU5UOiAweDA0LFxuICBNT0RJRllfQ09OVEVOVFM6IDB4MDgsXG4gIENPUFk6IDB4MTAsXG4gIE1PRElGWV9BTk5PVEFUSU9OUzogMHgyMCxcbiAgRklMTF9JTlRFUkFDVElWRV9GT1JNUzogMHgxMDAsXG4gIENPUFlfRk9SX0FDQ0VTU0lCSUxJVFk6IDB4MjAwLFxuICBBU1NFTUJMRTogMHg0MDAsXG4gIFBSSU5UX0hJR0hfUVVBTElUWTogMHg4MDBcbn07XG5leHBvcnRzLlBlcm1pc3Npb25GbGFnID0gUGVybWlzc2lvbkZsYWc7XG5jb25zdCBUZXh0UmVuZGVyaW5nTW9kZSA9IHtcbiAgRklMTDogMCxcbiAgU1RST0tFOiAxLFxuICBGSUxMX1NUUk9LRTogMixcbiAgSU5WSVNJQkxFOiAzLFxuICBGSUxMX0FERF9UT19QQVRIOiA0LFxuICBTVFJPS0VfQUREX1RPX1BBVEg6IDUsXG4gIEZJTExfU1RST0tFX0FERF9UT19QQVRIOiA2LFxuICBBRERfVE9fUEFUSDogNyxcbiAgRklMTF9TVFJPS0VfTUFTSzogMyxcbiAgQUREX1RPX1BBVEhfRkxBRzogNFxufTtcbmV4cG9ydHMuVGV4dFJlbmRlcmluZ01vZGUgPSBUZXh0UmVuZGVyaW5nTW9kZTtcbmNvbnN0IEltYWdlS2luZCA9IHtcbiAgR1JBWVNDQUxFXzFCUFA6IDEsXG4gIFJHQl8yNEJQUDogMixcbiAgUkdCQV8zMkJQUDogM1xufTtcbmV4cG9ydHMuSW1hZ2VLaW5kID0gSW1hZ2VLaW5kO1xuY29uc3QgQW5ub3RhdGlvblR5cGUgPSB7XG4gIFRFWFQ6IDEsXG4gIExJTks6IDIsXG4gIEZSRUVURVhUOiAzLFxuICBMSU5FOiA0LFxuICBTUVVBUkU6IDUsXG4gIENJUkNMRTogNixcbiAgUE9MWUdPTjogNyxcbiAgUE9MWUxJTkU6IDgsXG4gIEhJR0hMSUdIVDogOSxcbiAgVU5ERVJMSU5FOiAxMCxcbiAgU1FVSUdHTFk6IDExLFxuICBTVFJJS0VPVVQ6IDEyLFxuICBTVEFNUDogMTMsXG4gIENBUkVUOiAxNCxcbiAgSU5LOiAxNSxcbiAgUE9QVVA6IDE2LFxuICBGSUxFQVRUQUNITUVOVDogMTcsXG4gIFNPVU5EOiAxOCxcbiAgTU9WSUU6IDE5LFxuICBXSURHRVQ6IDIwLFxuICBTQ1JFRU46IDIxLFxuICBQUklOVEVSTUFSSzogMjIsXG4gIFRSQVBORVQ6IDIzLFxuICBXQVRFUk1BUks6IDI0LFxuICBUSFJFRUQ6IDI1LFxuICBSRURBQ1Q6IDI2XG59O1xuZXhwb3J0cy5Bbm5vdGF0aW9uVHlwZSA9IEFubm90YXRpb25UeXBlO1xuY29uc3QgQW5ub3RhdGlvblN0YXRlTW9kZWxUeXBlID0ge1xuICBNQVJLRUQ6IFwiTWFya2VkXCIsXG4gIFJFVklFVzogXCJSZXZpZXdcIlxufTtcbmV4cG9ydHMuQW5ub3RhdGlvblN0YXRlTW9kZWxUeXBlID0gQW5ub3RhdGlvblN0YXRlTW9kZWxUeXBlO1xuY29uc3QgQW5ub3RhdGlvbk1hcmtlZFN0YXRlID0ge1xuICBNQVJLRUQ6IFwiTWFya2VkXCIsXG4gIFVOTUFSS0VEOiBcIlVubWFya2VkXCJcbn07XG5leHBvcnRzLkFubm90YXRpb25NYXJrZWRTdGF0ZSA9IEFubm90YXRpb25NYXJrZWRTdGF0ZTtcbmNvbnN0IEFubm90YXRpb25SZXZpZXdTdGF0ZSA9IHtcbiAgQUNDRVBURUQ6IFwiQWNjZXB0ZWRcIixcbiAgUkVKRUNURUQ6IFwiUmVqZWN0ZWRcIixcbiAgQ0FOQ0VMTEVEOiBcIkNhbmNlbGxlZFwiLFxuICBDT01QTEVURUQ6IFwiQ29tcGxldGVkXCIsXG4gIE5PTkU6IFwiTm9uZVwiXG59O1xuZXhwb3J0cy5Bbm5vdGF0aW9uUmV2aWV3U3RhdGUgPSBBbm5vdGF0aW9uUmV2aWV3U3RhdGU7XG5jb25zdCBBbm5vdGF0aW9uUmVwbHlUeXBlID0ge1xuICBHUk9VUDogXCJHcm91cFwiLFxuICBSRVBMWTogXCJSXCJcbn07XG5leHBvcnRzLkFubm90YXRpb25SZXBseVR5cGUgPSBBbm5vdGF0aW9uUmVwbHlUeXBlO1xuY29uc3QgQW5ub3RhdGlvbkZsYWcgPSB7XG4gIElOVklTSUJMRTogMHgwMSxcbiAgSElEREVOOiAweDAyLFxuICBQUklOVDogMHgwNCxcbiAgTk9aT09NOiAweDA4LFxuICBOT1JPVEFURTogMHgxMCxcbiAgTk9WSUVXOiAweDIwLFxuICBSRUFET05MWTogMHg0MCxcbiAgTE9DS0VEOiAweDgwLFxuICBUT0dHTEVOT1ZJRVc6IDB4MTAwLFxuICBMT0NLRURDT05URU5UUzogMHgyMDBcbn07XG5leHBvcnRzLkFubm90YXRpb25GbGFnID0gQW5ub3RhdGlvbkZsYWc7XG5jb25zdCBBbm5vdGF0aW9uRmllbGRGbGFnID0ge1xuICBSRUFET05MWTogMHgwMDAwMDAxLFxuICBSRVFVSVJFRDogMHgwMDAwMDAyLFxuICBOT0VYUE9SVDogMHgwMDAwMDA0LFxuICBNVUxUSUxJTkU6IDB4MDAwMTAwMCxcbiAgUEFTU1dPUkQ6IDB4MDAwMjAwMCxcbiAgTk9UT0dHTEVUT09GRjogMHgwMDA0MDAwLFxuICBSQURJTzogMHgwMDA4MDAwLFxuICBQVVNIQlVUVE9OOiAweDAwMTAwMDAsXG4gIENPTUJPOiAweDAwMjAwMDAsXG4gIEVESVQ6IDB4MDA0MDAwMCxcbiAgU09SVDogMHgwMDgwMDAwLFxuICBGSUxFU0VMRUNUOiAweDAxMDAwMDAsXG4gIE1VTFRJU0VMRUNUOiAweDAyMDAwMDAsXG4gIERPTk9UU1BFTExDSEVDSzogMHgwNDAwMDAwLFxuICBET05PVFNDUk9MTDogMHgwODAwMDAwLFxuICBDT01COiAweDEwMDAwMDAsXG4gIFJJQ0hURVhUOiAweDIwMDAwMDAsXG4gIFJBRElPU0lOVU5JU09OOiAweDIwMDAwMDAsXG4gIENPTU1JVE9OU0VMQ0hBTkdFOiAweDQwMDAwMDBcbn07XG5leHBvcnRzLkFubm90YXRpb25GaWVsZEZsYWcgPSBBbm5vdGF0aW9uRmllbGRGbGFnO1xuY29uc3QgQW5ub3RhdGlvbkJvcmRlclN0eWxlVHlwZSA9IHtcbiAgU09MSUQ6IDEsXG4gIERBU0hFRDogMixcbiAgQkVWRUxFRDogMyxcbiAgSU5TRVQ6IDQsXG4gIFVOREVSTElORTogNVxufTtcbmV4cG9ydHMuQW5ub3RhdGlvbkJvcmRlclN0eWxlVHlwZSA9IEFubm90YXRpb25Cb3JkZXJTdHlsZVR5cGU7XG5jb25zdCBBbm5vdGF0aW9uQWN0aW9uRXZlbnRUeXBlID0ge1xuICBFOiBcIk1vdXNlIEVudGVyXCIsXG4gIFg6IFwiTW91c2UgRXhpdFwiLFxuICBEOiBcIk1vdXNlIERvd25cIixcbiAgVTogXCJNb3VzZSBVcFwiLFxuICBGbzogXCJGb2N1c1wiLFxuICBCbDogXCJCbHVyXCIsXG4gIFBPOiBcIlBhZ2VPcGVuXCIsXG4gIFBDOiBcIlBhZ2VDbG9zZVwiLFxuICBQVjogXCJQYWdlVmlzaWJsZVwiLFxuICBQSTogXCJQYWdlSW52aXNpYmxlXCIsXG4gIEs6IFwiS2V5c3Ryb2tlXCIsXG4gIEY6IFwiRm9ybWF0XCIsXG4gIFY6IFwiVmFsaWRhdGVcIixcbiAgQzogXCJDYWxjdWxhdGVcIlxufTtcbmV4cG9ydHMuQW5ub3RhdGlvbkFjdGlvbkV2ZW50VHlwZSA9IEFubm90YXRpb25BY3Rpb25FdmVudFR5cGU7XG5jb25zdCBEb2N1bWVudEFjdGlvbkV2ZW50VHlwZSA9IHtcbiAgV0M6IFwiV2lsbENsb3NlXCIsXG4gIFdTOiBcIldpbGxTYXZlXCIsXG4gIERTOiBcIkRpZFNhdmVcIixcbiAgV1A6IFwiV2lsbFByaW50XCIsXG4gIERQOiBcIkRpZFByaW50XCJcbn07XG5leHBvcnRzLkRvY3VtZW50QWN0aW9uRXZlbnRUeXBlID0gRG9jdW1lbnRBY3Rpb25FdmVudFR5cGU7XG5jb25zdCBQYWdlQWN0aW9uRXZlbnRUeXBlID0ge1xuICBPOiBcIlBhZ2VPcGVuXCIsXG4gIEM6IFwiUGFnZUNsb3NlXCJcbn07XG5leHBvcnRzLlBhZ2VBY3Rpb25FdmVudFR5cGUgPSBQYWdlQWN0aW9uRXZlbnRUeXBlO1xuY29uc3QgU3RyZWFtVHlwZSA9IHtcbiAgVU5LTk9XTjogXCJVTktOT1dOXCIsXG4gIEZMQVRFOiBcIkZMQVRFXCIsXG4gIExaVzogXCJMWldcIixcbiAgRENUOiBcIkRDVFwiLFxuICBKUFg6IFwiSlBYXCIsXG4gIEpCSUc6IFwiSkJJR1wiLFxuICBBODU6IFwiQTg1XCIsXG4gIEFIWDogXCJBSFhcIixcbiAgQ0NGOiBcIkNDRlwiLFxuICBSTFg6IFwiUkxYXCJcbn07XG5leHBvcnRzLlN0cmVhbVR5cGUgPSBTdHJlYW1UeXBlO1xuY29uc3QgRm9udFR5cGUgPSB7XG4gIFVOS05PV046IFwiVU5LTk9XTlwiLFxuICBUWVBFMTogXCJUWVBFMVwiLFxuICBUWVBFMVNUQU5EQVJEOiBcIlRZUEUxU1RBTkRBUkRcIixcbiAgVFlQRTFDOiBcIlRZUEUxQ1wiLFxuICBDSURGT05UVFlQRTA6IFwiQ0lERk9OVFRZUEUwXCIsXG4gIENJREZPTlRUWVBFMEM6IFwiQ0lERk9OVFRZUEUwQ1wiLFxuICBUUlVFVFlQRTogXCJUUlVFVFlQRVwiLFxuICBDSURGT05UVFlQRTI6IFwiQ0lERk9OVFRZUEUyXCIsXG4gIFRZUEUzOiBcIlRZUEUzXCIsXG4gIE9QRU5UWVBFOiBcIk9QRU5UWVBFXCIsXG4gIFRZUEUwOiBcIlRZUEUwXCIsXG4gIE1NVFlQRTE6IFwiTU1UWVBFMVwiXG59O1xuZXhwb3J0cy5Gb250VHlwZSA9IEZvbnRUeXBlO1xuY29uc3QgVmVyYm9zaXR5TGV2ZWwgPSB7XG4gIEVSUk9SUzogMCxcbiAgV0FSTklOR1M6IDEsXG4gIElORk9TOiA1XG59O1xuZXhwb3J0cy5WZXJib3NpdHlMZXZlbCA9IFZlcmJvc2l0eUxldmVsO1xuY29uc3QgQ01hcENvbXByZXNzaW9uVHlwZSA9IHtcbiAgTk9ORTogMCxcbiAgQklOQVJZOiAxLFxuICBTVFJFQU06IDJcbn07XG5leHBvcnRzLkNNYXBDb21wcmVzc2lvblR5cGUgPSBDTWFwQ29tcHJlc3Npb25UeXBlO1xuY29uc3QgT1BTID0ge1xuICBkZXBlbmRlbmN5OiAxLFxuICBzZXRMaW5lV2lkdGg6IDIsXG4gIHNldExpbmVDYXA6IDMsXG4gIHNldExpbmVKb2luOiA0LFxuICBzZXRNaXRlckxpbWl0OiA1LFxuICBzZXREYXNoOiA2LFxuICBzZXRSZW5kZXJpbmdJbnRlbnQ6IDcsXG4gIHNldEZsYXRuZXNzOiA4LFxuICBzZXRHU3RhdGU6IDksXG4gIHNhdmU6IDEwLFxuICByZXN0b3JlOiAxMSxcbiAgdHJhbnNmb3JtOiAxMixcbiAgbW92ZVRvOiAxMyxcbiAgbGluZVRvOiAxNCxcbiAgY3VydmVUbzogMTUsXG4gIGN1cnZlVG8yOiAxNixcbiAgY3VydmVUbzM6IDE3LFxuICBjbG9zZVBhdGg6IDE4LFxuICByZWN0YW5nbGU6IDE5LFxuICBzdHJva2U6IDIwLFxuICBjbG9zZVN0cm9rZTogMjEsXG4gIGZpbGw6IDIyLFxuICBlb0ZpbGw6IDIzLFxuICBmaWxsU3Ryb2tlOiAyNCxcbiAgZW9GaWxsU3Ryb2tlOiAyNSxcbiAgY2xvc2VGaWxsU3Ryb2tlOiAyNixcbiAgY2xvc2VFT0ZpbGxTdHJva2U6IDI3LFxuICBlbmRQYXRoOiAyOCxcbiAgY2xpcDogMjksXG4gIGVvQ2xpcDogMzAsXG4gIGJlZ2luVGV4dDogMzEsXG4gIGVuZFRleHQ6IDMyLFxuICBzZXRDaGFyU3BhY2luZzogMzMsXG4gIHNldFdvcmRTcGFjaW5nOiAzNCxcbiAgc2V0SFNjYWxlOiAzNSxcbiAgc2V0TGVhZGluZzogMzYsXG4gIHNldEZvbnQ6IDM3LFxuICBzZXRUZXh0UmVuZGVyaW5nTW9kZTogMzgsXG4gIHNldFRleHRSaXNlOiAzOSxcbiAgbW92ZVRleHQ6IDQwLFxuICBzZXRMZWFkaW5nTW92ZVRleHQ6IDQxLFxuICBzZXRUZXh0TWF0cml4OiA0MixcbiAgbmV4dExpbmU6IDQzLFxuICBzaG93VGV4dDogNDQsXG4gIHNob3dTcGFjZWRUZXh0OiA0NSxcbiAgbmV4dExpbmVTaG93VGV4dDogNDYsXG4gIG5leHRMaW5lU2V0U3BhY2luZ1Nob3dUZXh0OiA0NyxcbiAgc2V0Q2hhcldpZHRoOiA0OCxcbiAgc2V0Q2hhcldpZHRoQW5kQm91bmRzOiA0OSxcbiAgc2V0U3Ryb2tlQ29sb3JTcGFjZTogNTAsXG4gIHNldEZpbGxDb2xvclNwYWNlOiA1MSxcbiAgc2V0U3Ryb2tlQ29sb3I6IDUyLFxuICBzZXRTdHJva2VDb2xvck46IDUzLFxuICBzZXRGaWxsQ29sb3I6IDU0LFxuICBzZXRGaWxsQ29sb3JOOiA1NSxcbiAgc2V0U3Ryb2tlR3JheTogNTYsXG4gIHNldEZpbGxHcmF5OiA1NyxcbiAgc2V0U3Ryb2tlUkdCQ29sb3I6IDU4LFxuICBzZXRGaWxsUkdCQ29sb3I6IDU5LFxuICBzZXRTdHJva2VDTVlLQ29sb3I6IDYwLFxuICBzZXRGaWxsQ01ZS0NvbG9yOiA2MSxcbiAgc2hhZGluZ0ZpbGw6IDYyLFxuICBiZWdpbklubGluZUltYWdlOiA2MyxcbiAgYmVnaW5JbWFnZURhdGE6IDY0LFxuICBlbmRJbmxpbmVJbWFnZTogNjUsXG4gIHBhaW50WE9iamVjdDogNjYsXG4gIG1hcmtQb2ludDogNjcsXG4gIG1hcmtQb2ludFByb3BzOiA2OCxcbiAgYmVnaW5NYXJrZWRDb250ZW50OiA2OSxcbiAgYmVnaW5NYXJrZWRDb250ZW50UHJvcHM6IDcwLFxuICBlbmRNYXJrZWRDb250ZW50OiA3MSxcbiAgYmVnaW5Db21wYXQ6IDcyLFxuICBlbmRDb21wYXQ6IDczLFxuICBwYWludEZvcm1YT2JqZWN0QmVnaW46IDc0LFxuICBwYWludEZvcm1YT2JqZWN0RW5kOiA3NSxcbiAgYmVnaW5Hcm91cDogNzYsXG4gIGVuZEdyb3VwOiA3NyxcbiAgYmVnaW5Bbm5vdGF0aW9uczogNzgsXG4gIGVuZEFubm90YXRpb25zOiA3OSxcbiAgYmVnaW5Bbm5vdGF0aW9uOiA4MCxcbiAgZW5kQW5ub3RhdGlvbjogODEsXG4gIHBhaW50SnBlZ1hPYmplY3Q6IDgyLFxuICBwYWludEltYWdlTWFza1hPYmplY3Q6IDgzLFxuICBwYWludEltYWdlTWFza1hPYmplY3RHcm91cDogODQsXG4gIHBhaW50SW1hZ2VYT2JqZWN0OiA4NSxcbiAgcGFpbnRJbmxpbmVJbWFnZVhPYmplY3Q6IDg2LFxuICBwYWludElubGluZUltYWdlWE9iamVjdEdyb3VwOiA4NyxcbiAgcGFpbnRJbWFnZVhPYmplY3RSZXBlYXQ6IDg4LFxuICBwYWludEltYWdlTWFza1hPYmplY3RSZXBlYXQ6IDg5LFxuICBwYWludFNvbGlkQ29sb3JJbWFnZU1hc2s6IDkwLFxuICBjb25zdHJ1Y3RQYXRoOiA5MVxufTtcbmV4cG9ydHMuT1BTID0gT1BTO1xuY29uc3QgVU5TVVBQT1JURURfRkVBVFVSRVMgPSB7XG4gIHVua25vd246IFwidW5rbm93blwiLFxuICBmb3JtczogXCJmb3Jtc1wiLFxuICBqYXZhU2NyaXB0OiBcImphdmFTY3JpcHRcIixcbiAgc2lnbmF0dXJlczogXCJzaWduYXR1cmVzXCIsXG4gIHNtYXNrOiBcInNtYXNrXCIsXG4gIHNoYWRpbmdQYXR0ZXJuOiBcInNoYWRpbmdQYXR0ZXJuXCIsXG4gIGZvbnQ6IFwiZm9udFwiLFxuICBlcnJvclRpbGluZ1BhdHRlcm46IFwiZXJyb3JUaWxpbmdQYXR0ZXJuXCIsXG4gIGVycm9yRXh0R1N0YXRlOiBcImVycm9yRXh0R1N0YXRlXCIsXG4gIGVycm9yWE9iamVjdDogXCJlcnJvclhPYmplY3RcIixcbiAgZXJyb3JGb250TG9hZFR5cGUzOiBcImVycm9yRm9udExvYWRUeXBlM1wiLFxuICBlcnJvckZvbnRTdGF0ZTogXCJlcnJvckZvbnRTdGF0ZVwiLFxuICBlcnJvckZvbnRNaXNzaW5nOiBcImVycm9yRm9udE1pc3NpbmdcIixcbiAgZXJyb3JGb250VHJhbnNsYXRlOiBcImVycm9yRm9udFRyYW5zbGF0ZVwiLFxuICBlcnJvckNvbG9yU3BhY2U6IFwiZXJyb3JDb2xvclNwYWNlXCIsXG4gIGVycm9yT3BlcmF0b3JMaXN0OiBcImVycm9yT3BlcmF0b3JMaXN0XCIsXG4gIGVycm9yRm9udFRvVW5pY29kZTogXCJlcnJvckZvbnRUb1VuaWNvZGVcIixcbiAgZXJyb3JGb250TG9hZE5hdGl2ZTogXCJlcnJvckZvbnRMb2FkTmF0aXZlXCIsXG4gIGVycm9yRm9udEJ1aWxkUGF0aDogXCJlcnJvckZvbnRCdWlsZFBhdGhcIixcbiAgZXJyb3JGb250R2V0UGF0aDogXCJlcnJvckZvbnRHZXRQYXRoXCIsXG4gIGVycm9yTWFya2VkQ29udGVudDogXCJlcnJvck1hcmtlZENvbnRlbnRcIixcbiAgZXJyb3JDb250ZW50U3ViU3RyZWFtOiBcImVycm9yQ29udGVudFN1YlN0cmVhbVwiXG59O1xuZXhwb3J0cy5VTlNVUFBPUlRFRF9GRUFUVVJFUyA9IFVOU1VQUE9SVEVEX0ZFQVRVUkVTO1xuY29uc3QgUGFzc3dvcmRSZXNwb25zZXMgPSB7XG4gIE5FRURfUEFTU1dPUkQ6IDEsXG4gIElOQ09SUkVDVF9QQVNTV09SRDogMlxufTtcbmV4cG9ydHMuUGFzc3dvcmRSZXNwb25zZXMgPSBQYXNzd29yZFJlc3BvbnNlcztcbmxldCB2ZXJib3NpdHkgPSBWZXJib3NpdHlMZXZlbC5XQVJOSU5HUztcblxuZnVuY3Rpb24gc2V0VmVyYm9zaXR5TGV2ZWwobGV2ZWwpIHtcbiAgaWYgKE51bWJlci5pc0ludGVnZXIobGV2ZWwpKSB7XG4gICAgdmVyYm9zaXR5ID0gbGV2ZWw7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0VmVyYm9zaXR5TGV2ZWwoKSB7XG4gIHJldHVybiB2ZXJib3NpdHk7XG59XG5cbmZ1bmN0aW9uIGluZm8obXNnKSB7XG4gIGlmICh2ZXJib3NpdHkgPj0gVmVyYm9zaXR5TGV2ZWwuSU5GT1MpIHtcbiAgICBjb25zb2xlLmxvZyhgSW5mbzogJHttc2d9YCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gd2Fybihtc2cpIHtcbiAgaWYgKHZlcmJvc2l0eSA+PSBWZXJib3NpdHlMZXZlbC5XQVJOSU5HUykge1xuICAgIGNvbnNvbGUubG9nKGBXYXJuaW5nOiAke21zZ31gKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB1bnJlYWNoYWJsZShtc2cpIHtcbiAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG59XG5cbmZ1bmN0aW9uIGFzc2VydChjb25kLCBtc2cpIHtcbiAgaWYgKCFjb25kKSB7XG4gICAgdW5yZWFjaGFibGUobXNnKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfaXNWYWxpZFByb3RvY29sKHVybCkge1xuICBpZiAoIXVybCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHN3aXRjaCAodXJsLnByb3RvY29sKSB7XG4gICAgY2FzZSBcImh0dHA6XCI6XG4gICAgY2FzZSBcImh0dHBzOlwiOlxuICAgIGNhc2UgXCJmdHA6XCI6XG4gICAgY2FzZSBcIm1haWx0bzpcIjpcbiAgICBjYXNlIFwidGVsOlwiOlxuICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVZhbGlkQWJzb2x1dGVVcmwodXJsLCBiYXNlVXJsID0gbnVsbCwgb3B0aW9ucyA9IG51bGwpIHtcbiAgaWYgKCF1cmwpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHRyeSB7XG4gICAgaWYgKG9wdGlvbnMgJiYgdHlwZW9mIHVybCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgaWYgKG9wdGlvbnMuYWRkRGVmYXVsdFByb3RvY29sICYmIHVybC5zdGFydHNXaXRoKFwid3d3LlwiKSkge1xuICAgICAgICBjb25zdCBkb3RzID0gdXJsLm1hdGNoKC9cXC4vZyk7XG5cbiAgICAgICAgaWYgKGRvdHMgJiYgZG90cy5sZW5ndGggPj0gMikge1xuICAgICAgICAgIHVybCA9IGBodHRwOi8vJHt1cmx9YDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9ucy50cnlDb252ZXJ0RW5jb2RpbmcpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB1cmwgPSBzdHJpbmdUb1VURjhTdHJpbmcodXJsKTtcbiAgICAgICAgfSBjYXRjaCAoZXgpIHt9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgYWJzb2x1dGVVcmwgPSBiYXNlVXJsID8gbmV3IFVSTCh1cmwsIGJhc2VVcmwpIDogbmV3IFVSTCh1cmwpO1xuXG4gICAgaWYgKF9pc1ZhbGlkUHJvdG9jb2woYWJzb2x1dGVVcmwpKSB7XG4gICAgICByZXR1cm4gYWJzb2x1dGVVcmw7XG4gICAgfVxuICB9IGNhdGNoIChleCkge31cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gc2hhZG93KG9iaiwgcHJvcCwgdmFsdWUpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwgcHJvcCwge1xuICAgIHZhbHVlLFxuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIHdyaXRhYmxlOiBmYWxzZVxuICB9KTtcbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5jb25zdCBCYXNlRXhjZXB0aW9uID0gZnVuY3Rpb24gQmFzZUV4Y2VwdGlvbkNsb3N1cmUoKSB7XG4gIGZ1bmN0aW9uIEJhc2VFeGNlcHRpb24obWVzc2FnZSwgbmFtZSkge1xuICAgIGlmICh0aGlzLmNvbnN0cnVjdG9yID09PSBCYXNlRXhjZXB0aW9uKSB7XG4gICAgICB1bnJlYWNoYWJsZShcIkNhbm5vdCBpbml0aWFsaXplIEJhc2VFeGNlcHRpb24uXCIpO1xuICAgIH1cblxuICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgfVxuXG4gIEJhc2VFeGNlcHRpb24ucHJvdG90eXBlID0gbmV3IEVycm9yKCk7XG4gIEJhc2VFeGNlcHRpb24uY29uc3RydWN0b3IgPSBCYXNlRXhjZXB0aW9uO1xuICByZXR1cm4gQmFzZUV4Y2VwdGlvbjtcbn0oKTtcblxuZXhwb3J0cy5CYXNlRXhjZXB0aW9uID0gQmFzZUV4Y2VwdGlvbjtcblxuY2xhc3MgUGFzc3dvcmRFeGNlcHRpb24gZXh0ZW5kcyBCYXNlRXhjZXB0aW9uIHtcbiAgY29uc3RydWN0b3IobXNnLCBjb2RlKSB7XG4gICAgc3VwZXIobXNnLCBcIlBhc3N3b3JkRXhjZXB0aW9uXCIpO1xuICAgIHRoaXMuY29kZSA9IGNvZGU7XG4gIH1cblxufVxuXG5leHBvcnRzLlBhc3N3b3JkRXhjZXB0aW9uID0gUGFzc3dvcmRFeGNlcHRpb247XG5cbmNsYXNzIFVua25vd25FcnJvckV4Y2VwdGlvbiBleHRlbmRzIEJhc2VFeGNlcHRpb24ge1xuICBjb25zdHJ1Y3Rvcihtc2csIGRldGFpbHMpIHtcbiAgICBzdXBlcihtc2csIFwiVW5rbm93bkVycm9yRXhjZXB0aW9uXCIpO1xuICAgIHRoaXMuZGV0YWlscyA9IGRldGFpbHM7XG4gIH1cblxufVxuXG5leHBvcnRzLlVua25vd25FcnJvckV4Y2VwdGlvbiA9IFVua25vd25FcnJvckV4Y2VwdGlvbjtcblxuY2xhc3MgSW52YWxpZFBERkV4Y2VwdGlvbiBleHRlbmRzIEJhc2VFeGNlcHRpb24ge1xuICBjb25zdHJ1Y3Rvcihtc2cpIHtcbiAgICBzdXBlcihtc2csIFwiSW52YWxpZFBERkV4Y2VwdGlvblwiKTtcbiAgfVxuXG59XG5cbmV4cG9ydHMuSW52YWxpZFBERkV4Y2VwdGlvbiA9IEludmFsaWRQREZFeGNlcHRpb247XG5cbmNsYXNzIE1pc3NpbmdQREZFeGNlcHRpb24gZXh0ZW5kcyBCYXNlRXhjZXB0aW9uIHtcbiAgY29uc3RydWN0b3IobXNnKSB7XG4gICAgc3VwZXIobXNnLCBcIk1pc3NpbmdQREZFeGNlcHRpb25cIik7XG4gIH1cblxufVxuXG5leHBvcnRzLk1pc3NpbmdQREZFeGNlcHRpb24gPSBNaXNzaW5nUERGRXhjZXB0aW9uO1xuXG5jbGFzcyBVbmV4cGVjdGVkUmVzcG9uc2VFeGNlcHRpb24gZXh0ZW5kcyBCYXNlRXhjZXB0aW9uIHtcbiAgY29uc3RydWN0b3IobXNnLCBzdGF0dXMpIHtcbiAgICBzdXBlcihtc2csIFwiVW5leHBlY3RlZFJlc3BvbnNlRXhjZXB0aW9uXCIpO1xuICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzO1xuICB9XG5cbn1cblxuZXhwb3J0cy5VbmV4cGVjdGVkUmVzcG9uc2VFeGNlcHRpb24gPSBVbmV4cGVjdGVkUmVzcG9uc2VFeGNlcHRpb247XG5cbmNsYXNzIEZvcm1hdEVycm9yIGV4dGVuZHMgQmFzZUV4Y2VwdGlvbiB7XG4gIGNvbnN0cnVjdG9yKG1zZykge1xuICAgIHN1cGVyKG1zZywgXCJGb3JtYXRFcnJvclwiKTtcbiAgfVxuXG59XG5cbmV4cG9ydHMuRm9ybWF0RXJyb3IgPSBGb3JtYXRFcnJvcjtcblxuY2xhc3MgQWJvcnRFeGNlcHRpb24gZXh0ZW5kcyBCYXNlRXhjZXB0aW9uIHtcbiAgY29uc3RydWN0b3IobXNnKSB7XG4gICAgc3VwZXIobXNnLCBcIkFib3J0RXhjZXB0aW9uXCIpO1xuICB9XG5cbn1cblxuZXhwb3J0cy5BYm9ydEV4Y2VwdGlvbiA9IEFib3J0RXhjZXB0aW9uO1xuXG5mdW5jdGlvbiBieXRlc1RvU3RyaW5nKGJ5dGVzKSB7XG4gIGlmICh0eXBlb2YgYnl0ZXMgIT09IFwib2JqZWN0XCIgfHwgYnl0ZXMgPT09IG51bGwgfHwgYnl0ZXMubGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICB1bnJlYWNoYWJsZShcIkludmFsaWQgYXJndW1lbnQgZm9yIGJ5dGVzVG9TdHJpbmdcIik7XG4gIH1cblxuICBjb25zdCBsZW5ndGggPSBieXRlcy5sZW5ndGg7XG4gIGNvbnN0IE1BWF9BUkdVTUVOVF9DT1VOVCA9IDgxOTI7XG5cbiAgaWYgKGxlbmd0aCA8IE1BWF9BUkdVTUVOVF9DT1VOVCkge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGJ5dGVzKTtcbiAgfVxuXG4gIGNvbnN0IHN0ckJ1ZiA9IFtdO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IE1BWF9BUkdVTUVOVF9DT1VOVCkge1xuICAgIGNvbnN0IGNodW5rRW5kID0gTWF0aC5taW4oaSArIE1BWF9BUkdVTUVOVF9DT1VOVCwgbGVuZ3RoKTtcbiAgICBjb25zdCBjaHVuayA9IGJ5dGVzLnN1YmFycmF5KGksIGNodW5rRW5kKTtcbiAgICBzdHJCdWYucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGNodW5rKSk7XG4gIH1cblxuICByZXR1cm4gc3RyQnVmLmpvaW4oXCJcIik7XG59XG5cbmZ1bmN0aW9uIHN0cmluZ1RvQnl0ZXMoc3RyKSB7XG4gIGlmICh0eXBlb2Ygc3RyICE9PSBcInN0cmluZ1wiKSB7XG4gICAgdW5yZWFjaGFibGUoXCJJbnZhbGlkIGFyZ3VtZW50IGZvciBzdHJpbmdUb0J5dGVzXCIpO1xuICB9XG5cbiAgY29uc3QgbGVuZ3RoID0gc3RyLmxlbmd0aDtcbiAgY29uc3QgYnl0ZXMgPSBuZXcgVWludDhBcnJheShsZW5ndGgpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBieXRlc1tpXSA9IHN0ci5jaGFyQ29kZUF0KGkpICYgMHhmZjtcbiAgfVxuXG4gIHJldHVybiBieXRlcztcbn1cblxuZnVuY3Rpb24gYXJyYXlCeXRlTGVuZ3RoKGFycikge1xuICBpZiAoYXJyLmxlbmd0aCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGFyci5sZW5ndGg7XG4gIH1cblxuICBpZiAoYXJyLmJ5dGVMZW5ndGggIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBhcnIuYnl0ZUxlbmd0aDtcbiAgfVxuXG4gIHVucmVhY2hhYmxlKFwiSW52YWxpZCBhcmd1bWVudCBmb3IgYXJyYXlCeXRlTGVuZ3RoXCIpO1xufVxuXG5mdW5jdGlvbiBhcnJheXNUb0J5dGVzKGFycikge1xuICBjb25zdCBsZW5ndGggPSBhcnIubGVuZ3RoO1xuXG4gIGlmIChsZW5ndGggPT09IDEgJiYgYXJyWzBdIGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuICAgIHJldHVybiBhcnJbMF07XG4gIH1cblxuICBsZXQgcmVzdWx0TGVuZ3RoID0gMDtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgcmVzdWx0TGVuZ3RoICs9IGFycmF5Qnl0ZUxlbmd0aChhcnJbaV0pO1xuICB9XG5cbiAgbGV0IHBvcyA9IDA7XG4gIGNvbnN0IGRhdGEgPSBuZXcgVWludDhBcnJheShyZXN1bHRMZW5ndGgpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBsZXQgaXRlbSA9IGFycltpXTtcblxuICAgIGlmICghKGl0ZW0gaW5zdGFuY2VvZiBVaW50OEFycmF5KSkge1xuICAgICAgaWYgKHR5cGVvZiBpdGVtID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIGl0ZW0gPSBzdHJpbmdUb0J5dGVzKGl0ZW0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaXRlbSA9IG5ldyBVaW50OEFycmF5KGl0ZW0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGl0ZW1MZW5ndGggPSBpdGVtLmJ5dGVMZW5ndGg7XG4gICAgZGF0YS5zZXQoaXRlbSwgcG9zKTtcbiAgICBwb3MgKz0gaXRlbUxlbmd0aDtcbiAgfVxuXG4gIHJldHVybiBkYXRhO1xufVxuXG5mdW5jdGlvbiBzdHJpbmczMih2YWx1ZSkge1xuICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSh2YWx1ZSA+PiAyNCAmIDB4ZmYsIHZhbHVlID4+IDE2ICYgMHhmZiwgdmFsdWUgPj4gOCAmIDB4ZmYsIHZhbHVlICYgMHhmZik7XG59XG5cbmZ1bmN0aW9uIG9iamVjdFNpemUob2JqKSB7XG4gIHJldHVybiBPYmplY3Qua2V5cyhvYmopLmxlbmd0aDtcbn1cblxuZnVuY3Rpb24gb2JqZWN0RnJvbU1hcChtYXApIHtcbiAgY29uc3Qgb2JqID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBtYXApIHtcbiAgICBvYmpba2V5XSA9IHZhbHVlO1xuICB9XG5cbiAgcmV0dXJuIG9iajtcbn1cblxuZnVuY3Rpb24gaXNMaXR0bGVFbmRpYW4oKSB7XG4gIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheSg0KTtcbiAgYnVmZmVyOFswXSA9IDE7XG4gIGNvbnN0IHZpZXczMiA9IG5ldyBVaW50MzJBcnJheShidWZmZXI4LmJ1ZmZlciwgMCwgMSk7XG4gIHJldHVybiB2aWV3MzJbMF0gPT09IDE7XG59XG5cbmZ1bmN0aW9uIGlzRXZhbFN1cHBvcnRlZCgpIHtcbiAgdHJ5IHtcbiAgICBuZXcgRnVuY3Rpb24oXCJcIik7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuY2xhc3MgRmVhdHVyZVRlc3Qge1xuICBzdGF0aWMgZ2V0IGlzTGl0dGxlRW5kaWFuKCkge1xuICAgIHJldHVybiBzaGFkb3codGhpcywgXCJpc0xpdHRsZUVuZGlhblwiLCBpc0xpdHRsZUVuZGlhbigpKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgaXNFdmFsU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiBzaGFkb3codGhpcywgXCJpc0V2YWxTdXBwb3J0ZWRcIiwgaXNFdmFsU3VwcG9ydGVkKCkpO1xuICB9XG5cbiAgc3RhdGljIGdldCBpc09mZnNjcmVlbkNhbnZhc1N1cHBvcnRlZCgpIHtcbiAgICByZXR1cm4gc2hhZG93KHRoaXMsIFwiaXNPZmZzY3JlZW5DYW52YXNTdXBwb3J0ZWRcIiwgdHlwZW9mIE9mZnNjcmVlbkNhbnZhcyAhPT0gXCJ1bmRlZmluZWRcIik7XG4gIH1cblxufVxuXG5leHBvcnRzLkZlYXR1cmVUZXN0ID0gRmVhdHVyZVRlc3Q7XG5jb25zdCBoZXhOdW1iZXJzID0gWy4uLkFycmF5KDI1Nikua2V5cygpXS5tYXAobiA9PiBuLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCBcIjBcIikpO1xuXG5jbGFzcyBVdGlsIHtcbiAgc3RhdGljIG1ha2VIZXhDb2xvcihyLCBnLCBiKSB7XG4gICAgcmV0dXJuIGAjJHtoZXhOdW1iZXJzW3JdfSR7aGV4TnVtYmVyc1tnXX0ke2hleE51bWJlcnNbYl19YDtcbiAgfVxuXG4gIHN0YXRpYyBzY2FsZU1pbk1heCh0cmFuc2Zvcm0sIG1pbk1heCkge1xuICAgIGxldCB0ZW1wO1xuXG4gICAgaWYgKHRyYW5zZm9ybVswXSkge1xuICAgICAgaWYgKHRyYW5zZm9ybVswXSA8IDApIHtcbiAgICAgICAgdGVtcCA9IG1pbk1heFswXTtcbiAgICAgICAgbWluTWF4WzBdID0gbWluTWF4WzFdO1xuICAgICAgICBtaW5NYXhbMV0gPSB0ZW1wO1xuICAgICAgfVxuXG4gICAgICBtaW5NYXhbMF0gKj0gdHJhbnNmb3JtWzBdO1xuICAgICAgbWluTWF4WzFdICo9IHRyYW5zZm9ybVswXTtcblxuICAgICAgaWYgKHRyYW5zZm9ybVszXSA8IDApIHtcbiAgICAgICAgdGVtcCA9IG1pbk1heFsyXTtcbiAgICAgICAgbWluTWF4WzJdID0gbWluTWF4WzNdO1xuICAgICAgICBtaW5NYXhbM10gPSB0ZW1wO1xuICAgICAgfVxuXG4gICAgICBtaW5NYXhbMl0gKj0gdHJhbnNmb3JtWzNdO1xuICAgICAgbWluTWF4WzNdICo9IHRyYW5zZm9ybVszXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGVtcCA9IG1pbk1heFswXTtcbiAgICAgIG1pbk1heFswXSA9IG1pbk1heFsyXTtcbiAgICAgIG1pbk1heFsyXSA9IHRlbXA7XG4gICAgICB0ZW1wID0gbWluTWF4WzFdO1xuICAgICAgbWluTWF4WzFdID0gbWluTWF4WzNdO1xuICAgICAgbWluTWF4WzNdID0gdGVtcDtcblxuICAgICAgaWYgKHRyYW5zZm9ybVsxXSA8IDApIHtcbiAgICAgICAgdGVtcCA9IG1pbk1heFsyXTtcbiAgICAgICAgbWluTWF4WzJdID0gbWluTWF4WzNdO1xuICAgICAgICBtaW5NYXhbM10gPSB0ZW1wO1xuICAgICAgfVxuXG4gICAgICBtaW5NYXhbMl0gKj0gdHJhbnNmb3JtWzFdO1xuICAgICAgbWluTWF4WzNdICo9IHRyYW5zZm9ybVsxXTtcblxuICAgICAgaWYgKHRyYW5zZm9ybVsyXSA8IDApIHtcbiAgICAgICAgdGVtcCA9IG1pbk1heFswXTtcbiAgICAgICAgbWluTWF4WzBdID0gbWluTWF4WzFdO1xuICAgICAgICBtaW5NYXhbMV0gPSB0ZW1wO1xuICAgICAgfVxuXG4gICAgICBtaW5NYXhbMF0gKj0gdHJhbnNmb3JtWzJdO1xuICAgICAgbWluTWF4WzFdICo9IHRyYW5zZm9ybVsyXTtcbiAgICB9XG5cbiAgICBtaW5NYXhbMF0gKz0gdHJhbnNmb3JtWzRdO1xuICAgIG1pbk1heFsxXSArPSB0cmFuc2Zvcm1bNF07XG4gICAgbWluTWF4WzJdICs9IHRyYW5zZm9ybVs1XTtcbiAgICBtaW5NYXhbM10gKz0gdHJhbnNmb3JtWzVdO1xuICB9XG5cbiAgc3RhdGljIHRyYW5zZm9ybShtMSwgbTIpIHtcbiAgICByZXR1cm4gW20xWzBdICogbTJbMF0gKyBtMVsyXSAqIG0yWzFdLCBtMVsxXSAqIG0yWzBdICsgbTFbM10gKiBtMlsxXSwgbTFbMF0gKiBtMlsyXSArIG0xWzJdICogbTJbM10sIG0xWzFdICogbTJbMl0gKyBtMVszXSAqIG0yWzNdLCBtMVswXSAqIG0yWzRdICsgbTFbMl0gKiBtMls1XSArIG0xWzRdLCBtMVsxXSAqIG0yWzRdICsgbTFbM10gKiBtMls1XSArIG0xWzVdXTtcbiAgfVxuXG4gIHN0YXRpYyBhcHBseVRyYW5zZm9ybShwLCBtKSB7XG4gICAgY29uc3QgeHQgPSBwWzBdICogbVswXSArIHBbMV0gKiBtWzJdICsgbVs0XTtcbiAgICBjb25zdCB5dCA9IHBbMF0gKiBtWzFdICsgcFsxXSAqIG1bM10gKyBtWzVdO1xuICAgIHJldHVybiBbeHQsIHl0XTtcbiAgfVxuXG4gIHN0YXRpYyBhcHBseUludmVyc2VUcmFuc2Zvcm0ocCwgbSkge1xuICAgIGNvbnN0IGQgPSBtWzBdICogbVszXSAtIG1bMV0gKiBtWzJdO1xuICAgIGNvbnN0IHh0ID0gKHBbMF0gKiBtWzNdIC0gcFsxXSAqIG1bMl0gKyBtWzJdICogbVs1XSAtIG1bNF0gKiBtWzNdKSAvIGQ7XG4gICAgY29uc3QgeXQgPSAoLXBbMF0gKiBtWzFdICsgcFsxXSAqIG1bMF0gKyBtWzRdICogbVsxXSAtIG1bNV0gKiBtWzBdKSAvIGQ7XG4gICAgcmV0dXJuIFt4dCwgeXRdO1xuICB9XG5cbiAgc3RhdGljIGdldEF4aWFsQWxpZ25lZEJvdW5kaW5nQm94KHIsIG0pIHtcbiAgICBjb25zdCBwMSA9IFV0aWwuYXBwbHlUcmFuc2Zvcm0ociwgbSk7XG4gICAgY29uc3QgcDIgPSBVdGlsLmFwcGx5VHJhbnNmb3JtKHIuc2xpY2UoMiwgNCksIG0pO1xuICAgIGNvbnN0IHAzID0gVXRpbC5hcHBseVRyYW5zZm9ybShbclswXSwgclszXV0sIG0pO1xuICAgIGNvbnN0IHA0ID0gVXRpbC5hcHBseVRyYW5zZm9ybShbclsyXSwgclsxXV0sIG0pO1xuICAgIHJldHVybiBbTWF0aC5taW4ocDFbMF0sIHAyWzBdLCBwM1swXSwgcDRbMF0pLCBNYXRoLm1pbihwMVsxXSwgcDJbMV0sIHAzWzFdLCBwNFsxXSksIE1hdGgubWF4KHAxWzBdLCBwMlswXSwgcDNbMF0sIHA0WzBdKSwgTWF0aC5tYXgocDFbMV0sIHAyWzFdLCBwM1sxXSwgcDRbMV0pXTtcbiAgfVxuXG4gIHN0YXRpYyBpbnZlcnNlVHJhbnNmb3JtKG0pIHtcbiAgICBjb25zdCBkID0gbVswXSAqIG1bM10gLSBtWzFdICogbVsyXTtcbiAgICByZXR1cm4gW21bM10gLyBkLCAtbVsxXSAvIGQsIC1tWzJdIC8gZCwgbVswXSAvIGQsIChtWzJdICogbVs1XSAtIG1bNF0gKiBtWzNdKSAvIGQsIChtWzRdICogbVsxXSAtIG1bNV0gKiBtWzBdKSAvIGRdO1xuICB9XG5cbiAgc3RhdGljIGFwcGx5M2RUcmFuc2Zvcm0obSwgdikge1xuICAgIHJldHVybiBbbVswXSAqIHZbMF0gKyBtWzFdICogdlsxXSArIG1bMl0gKiB2WzJdLCBtWzNdICogdlswXSArIG1bNF0gKiB2WzFdICsgbVs1XSAqIHZbMl0sIG1bNl0gKiB2WzBdICsgbVs3XSAqIHZbMV0gKyBtWzhdICogdlsyXV07XG4gIH1cblxuICBzdGF0aWMgc2luZ3VsYXJWYWx1ZURlY29tcG9zZTJkU2NhbGUobSkge1xuICAgIGNvbnN0IHRyYW5zcG9zZSA9IFttWzBdLCBtWzJdLCBtWzFdLCBtWzNdXTtcbiAgICBjb25zdCBhID0gbVswXSAqIHRyYW5zcG9zZVswXSArIG1bMV0gKiB0cmFuc3Bvc2VbMl07XG4gICAgY29uc3QgYiA9IG1bMF0gKiB0cmFuc3Bvc2VbMV0gKyBtWzFdICogdHJhbnNwb3NlWzNdO1xuICAgIGNvbnN0IGMgPSBtWzJdICogdHJhbnNwb3NlWzBdICsgbVszXSAqIHRyYW5zcG9zZVsyXTtcbiAgICBjb25zdCBkID0gbVsyXSAqIHRyYW5zcG9zZVsxXSArIG1bM10gKiB0cmFuc3Bvc2VbM107XG4gICAgY29uc3QgZmlyc3QgPSAoYSArIGQpIC8gMjtcbiAgICBjb25zdCBzZWNvbmQgPSBNYXRoLnNxcnQoKGEgKyBkKSAqKiAyIC0gNCAqIChhICogZCAtIGMgKiBiKSkgLyAyO1xuICAgIGNvbnN0IHN4ID0gZmlyc3QgKyBzZWNvbmQgfHwgMTtcbiAgICBjb25zdCBzeSA9IGZpcnN0IC0gc2Vjb25kIHx8IDE7XG4gICAgcmV0dXJuIFtNYXRoLnNxcnQoc3gpLCBNYXRoLnNxcnQoc3kpXTtcbiAgfVxuXG4gIHN0YXRpYyBub3JtYWxpemVSZWN0KHJlY3QpIHtcbiAgICBjb25zdCByID0gcmVjdC5zbGljZSgwKTtcblxuICAgIGlmIChyZWN0WzBdID4gcmVjdFsyXSkge1xuICAgICAgclswXSA9IHJlY3RbMl07XG4gICAgICByWzJdID0gcmVjdFswXTtcbiAgICB9XG5cbiAgICBpZiAocmVjdFsxXSA+IHJlY3RbM10pIHtcbiAgICAgIHJbMV0gPSByZWN0WzNdO1xuICAgICAgclszXSA9IHJlY3RbMV07XG4gICAgfVxuXG4gICAgcmV0dXJuIHI7XG4gIH1cblxuICBzdGF0aWMgaW50ZXJzZWN0KHJlY3QxLCByZWN0Mikge1xuICAgIGNvbnN0IHhMb3cgPSBNYXRoLm1heChNYXRoLm1pbihyZWN0MVswXSwgcmVjdDFbMl0pLCBNYXRoLm1pbihyZWN0MlswXSwgcmVjdDJbMl0pKTtcbiAgICBjb25zdCB4SGlnaCA9IE1hdGgubWluKE1hdGgubWF4KHJlY3QxWzBdLCByZWN0MVsyXSksIE1hdGgubWF4KHJlY3QyWzBdLCByZWN0MlsyXSkpO1xuXG4gICAgaWYgKHhMb3cgPiB4SGlnaCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgeUxvdyA9IE1hdGgubWF4KE1hdGgubWluKHJlY3QxWzFdLCByZWN0MVszXSksIE1hdGgubWluKHJlY3QyWzFdLCByZWN0MlszXSkpO1xuICAgIGNvbnN0IHlIaWdoID0gTWF0aC5taW4oTWF0aC5tYXgocmVjdDFbMV0sIHJlY3QxWzNdKSwgTWF0aC5tYXgocmVjdDJbMV0sIHJlY3QyWzNdKSk7XG5cbiAgICBpZiAoeUxvdyA+IHlIaWdoKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gW3hMb3csIHlMb3csIHhIaWdoLCB5SGlnaF07XG4gIH1cblxuICBzdGF0aWMgYmV6aWVyQm91bmRpbmdCb3goeDAsIHkwLCB4MSwgeTEsIHgyLCB5MiwgeDMsIHkzKSB7XG4gICAgY29uc3QgdHZhbHVlcyA9IFtdLFxuICAgICAgICAgIGJvdW5kcyA9IFtbXSwgW11dO1xuICAgIGxldCBhLCBiLCBjLCB0LCB0MSwgdDIsIGIyYWMsIHNxcnRiMmFjO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCAyOyArK2kpIHtcbiAgICAgIGlmIChpID09PSAwKSB7XG4gICAgICAgIGIgPSA2ICogeDAgLSAxMiAqIHgxICsgNiAqIHgyO1xuICAgICAgICBhID0gLTMgKiB4MCArIDkgKiB4MSAtIDkgKiB4MiArIDMgKiB4MztcbiAgICAgICAgYyA9IDMgKiB4MSAtIDMgKiB4MDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGIgPSA2ICogeTAgLSAxMiAqIHkxICsgNiAqIHkyO1xuICAgICAgICBhID0gLTMgKiB5MCArIDkgKiB5MSAtIDkgKiB5MiArIDMgKiB5MztcbiAgICAgICAgYyA9IDMgKiB5MSAtIDMgKiB5MDtcbiAgICAgIH1cblxuICAgICAgaWYgKE1hdGguYWJzKGEpIDwgMWUtMTIpIHtcbiAgICAgICAgaWYgKE1hdGguYWJzKGIpIDwgMWUtMTIpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHQgPSAtYyAvIGI7XG5cbiAgICAgICAgaWYgKDAgPCB0ICYmIHQgPCAxKSB7XG4gICAgICAgICAgdHZhbHVlcy5wdXNoKHQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGIyYWMgPSBiICogYiAtIDQgKiBjICogYTtcbiAgICAgIHNxcnRiMmFjID0gTWF0aC5zcXJ0KGIyYWMpO1xuXG4gICAgICBpZiAoYjJhYyA8IDApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHQxID0gKC1iICsgc3FydGIyYWMpIC8gKDIgKiBhKTtcblxuICAgICAgaWYgKDAgPCB0MSAmJiB0MSA8IDEpIHtcbiAgICAgICAgdHZhbHVlcy5wdXNoKHQxKTtcbiAgICAgIH1cblxuICAgICAgdDIgPSAoLWIgLSBzcXJ0YjJhYykgLyAoMiAqIGEpO1xuXG4gICAgICBpZiAoMCA8IHQyICYmIHQyIDwgMSkge1xuICAgICAgICB0dmFsdWVzLnB1c2godDIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBqID0gdHZhbHVlcy5sZW5ndGgsXG4gICAgICAgIG10O1xuICAgIGNvbnN0IGpsZW4gPSBqO1xuXG4gICAgd2hpbGUgKGotLSkge1xuICAgICAgdCA9IHR2YWx1ZXNbal07XG4gICAgICBtdCA9IDEgLSB0O1xuICAgICAgYm91bmRzWzBdW2pdID0gbXQgKiBtdCAqIG10ICogeDAgKyAzICogbXQgKiBtdCAqIHQgKiB4MSArIDMgKiBtdCAqIHQgKiB0ICogeDIgKyB0ICogdCAqIHQgKiB4MztcbiAgICAgIGJvdW5kc1sxXVtqXSA9IG10ICogbXQgKiBtdCAqIHkwICsgMyAqIG10ICogbXQgKiB0ICogeTEgKyAzICogbXQgKiB0ICogdCAqIHkyICsgdCAqIHQgKiB0ICogeTM7XG4gICAgfVxuXG4gICAgYm91bmRzWzBdW2psZW5dID0geDA7XG4gICAgYm91bmRzWzFdW2psZW5dID0geTA7XG4gICAgYm91bmRzWzBdW2psZW4gKyAxXSA9IHgzO1xuICAgIGJvdW5kc1sxXVtqbGVuICsgMV0gPSB5MztcbiAgICBib3VuZHNbMF0ubGVuZ3RoID0gYm91bmRzWzFdLmxlbmd0aCA9IGpsZW4gKyAyO1xuICAgIHJldHVybiBbTWF0aC5taW4oLi4uYm91bmRzWzBdKSwgTWF0aC5taW4oLi4uYm91bmRzWzFdKSwgTWF0aC5tYXgoLi4uYm91bmRzWzBdKSwgTWF0aC5tYXgoLi4uYm91bmRzWzFdKV07XG4gIH1cblxufVxuXG5leHBvcnRzLlV0aWwgPSBVdGlsO1xuY29uc3QgUERGU3RyaW5nVHJhbnNsYXRlVGFibGUgPSBbMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMHgyZDgsIDB4MmM3LCAweDJjNiwgMHgyZDksIDB4MmRkLCAweDJkYiwgMHgyZGEsIDB4MmRjLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAweDIwMjIsIDB4MjAyMCwgMHgyMDIxLCAweDIwMjYsIDB4MjAxNCwgMHgyMDEzLCAweDE5MiwgMHgyMDQ0LCAweDIwMzksIDB4MjAzYSwgMHgyMjEyLCAweDIwMzAsIDB4MjAxZSwgMHgyMDFjLCAweDIwMWQsIDB4MjAxOCwgMHgyMDE5LCAweDIwMWEsIDB4MjEyMiwgMHhmYjAxLCAweGZiMDIsIDB4MTQxLCAweDE1MiwgMHgxNjAsIDB4MTc4LCAweDE3ZCwgMHgxMzEsIDB4MTQyLCAweDE1MywgMHgxNjEsIDB4MTdlLCAwLCAweDIwYWNdO1xuXG5mdW5jdGlvbiBzdHJpbmdUb1BERlN0cmluZyhzdHIpIHtcbiAgaWYgKHN0clswXSA+PSBcIlxceEVGXCIpIHtcbiAgICBsZXQgZW5jb2Rpbmc7XG5cbiAgICBpZiAoc3RyWzBdID09PSBcIlxceEZFXCIgJiYgc3RyWzFdID09PSBcIlxceEZGXCIpIHtcbiAgICAgIGVuY29kaW5nID0gXCJ1dGYtMTZiZVwiO1xuICAgIH0gZWxzZSBpZiAoc3RyWzBdID09PSBcIlxceEZGXCIgJiYgc3RyWzFdID09PSBcIlxceEZFXCIpIHtcbiAgICAgIGVuY29kaW5nID0gXCJ1dGYtMTZsZVwiO1xuICAgIH0gZWxzZSBpZiAoc3RyWzBdID09PSBcIlxceEVGXCIgJiYgc3RyWzFdID09PSBcIlxceEJCXCIgJiYgc3RyWzJdID09PSBcIlxceEJGXCIpIHtcbiAgICAgIGVuY29kaW5nID0gXCJ1dGYtOFwiO1xuICAgIH1cblxuICAgIGlmIChlbmNvZGluZykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcihlbmNvZGluZywge1xuICAgICAgICAgIGZhdGFsOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBidWZmZXIgPSBzdHJpbmdUb0J5dGVzKHN0cik7XG4gICAgICAgIHJldHVybiBkZWNvZGVyLmRlY29kZShidWZmZXIpO1xuICAgICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgICAgd2Fybihgc3RyaW5nVG9QREZTdHJpbmc6IFwiJHtleH1cIi5gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBzdHJCdWYgPSBbXTtcblxuICBmb3IgKGxldCBpID0gMCwgaWkgPSBzdHIubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgIGNvbnN0IGNvZGUgPSBQREZTdHJpbmdUcmFuc2xhdGVUYWJsZVtzdHIuY2hhckNvZGVBdChpKV07XG4gICAgc3RyQnVmLnB1c2goY29kZSA/IFN0cmluZy5mcm9tQ2hhckNvZGUoY29kZSkgOiBzdHIuY2hhckF0KGkpKTtcbiAgfVxuXG4gIHJldHVybiBzdHJCdWYuam9pbihcIlwiKTtcbn1cblxuZnVuY3Rpb24gZXNjYXBlU3RyaW5nKHN0cikge1xuICByZXR1cm4gc3RyLnJlcGxhY2UoLyhbKClcXFxcXFxuXFxyXSkvZywgbWF0Y2ggPT4ge1xuICAgIGlmIChtYXRjaCA9PT0gXCJcXG5cIikge1xuICAgICAgcmV0dXJuIFwiXFxcXG5cIjtcbiAgICB9IGVsc2UgaWYgKG1hdGNoID09PSBcIlxcclwiKSB7XG4gICAgICByZXR1cm4gXCJcXFxcclwiO1xuICAgIH1cblxuICAgIHJldHVybiBgXFxcXCR7bWF0Y2h9YDtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGlzQXNjaWkoc3RyKSB7XG4gIHJldHVybiAvXltcXHgwMC1cXHg3Rl0qJC8udGVzdChzdHIpO1xufVxuXG5mdW5jdGlvbiBzdHJpbmdUb1VURjE2QkVTdHJpbmcoc3RyKSB7XG4gIGNvbnN0IGJ1ZiA9IFtcIlxceEZFXFx4RkZcIl07XG5cbiAgZm9yIChsZXQgaSA9IDAsIGlpID0gc3RyLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICBjb25zdCBjaGFyID0gc3RyLmNoYXJDb2RlQXQoaSk7XG4gICAgYnVmLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShjaGFyID4+IDggJiAweGZmKSwgU3RyaW5nLmZyb21DaGFyQ29kZShjaGFyICYgMHhmZikpO1xuICB9XG5cbiAgcmV0dXJuIGJ1Zi5qb2luKFwiXCIpO1xufVxuXG5mdW5jdGlvbiBzdHJpbmdUb1VURjhTdHJpbmcoc3RyKSB7XG4gIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKHN0cikpO1xufVxuXG5mdW5jdGlvbiB1dGY4U3RyaW5nVG9TdHJpbmcoc3RyKSB7XG4gIHJldHVybiB1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoc3RyKSk7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXlCdWZmZXIodikge1xuICByZXR1cm4gdHlwZW9mIHYgPT09IFwib2JqZWN0XCIgJiYgdiAhPT0gbnVsbCAmJiB2LmJ5dGVMZW5ndGggIT09IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gaXNBcnJheUVxdWFsKGFycjEsIGFycjIpIHtcbiAgaWYgKGFycjEubGVuZ3RoICE9PSBhcnIyLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZvciAobGV0IGkgPSAwLCBpaSA9IGFycjEubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgIGlmIChhcnIxW2ldICE9PSBhcnIyW2ldKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGdldE1vZGlmaWNhdGlvbkRhdGUoZGF0ZSA9IG5ldyBEYXRlKCkpIHtcbiAgY29uc3QgYnVmZmVyID0gW2RhdGUuZ2V0VVRDRnVsbFllYXIoKS50b1N0cmluZygpLCAoZGF0ZS5nZXRVVENNb250aCgpICsgMSkudG9TdHJpbmcoKS5wYWRTdGFydCgyLCBcIjBcIiksIGRhdGUuZ2V0VVRDRGF0ZSgpLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgXCIwXCIpLCBkYXRlLmdldFVUQ0hvdXJzKCkudG9TdHJpbmcoKS5wYWRTdGFydCgyLCBcIjBcIiksIGRhdGUuZ2V0VVRDTWludXRlcygpLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgXCIwXCIpLCBkYXRlLmdldFVUQ1NlY29uZHMoKS50b1N0cmluZygpLnBhZFN0YXJ0KDIsIFwiMFwiKV07XG4gIHJldHVybiBidWZmZXIuam9pbihcIlwiKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkoKSB7XG4gIGNvbnN0IGNhcGFiaWxpdHkgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICBsZXQgaXNTZXR0bGVkID0gZmFsc2U7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjYXBhYmlsaXR5LCBcInNldHRsZWRcIiwge1xuICAgIGdldCgpIHtcbiAgICAgIHJldHVybiBpc1NldHRsZWQ7XG4gICAgfVxuXG4gIH0pO1xuICBjYXBhYmlsaXR5LnByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgY2FwYWJpbGl0eS5yZXNvbHZlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgIGlzU2V0dGxlZCA9IHRydWU7XG4gICAgICByZXNvbHZlKGRhdGEpO1xuICAgIH07XG5cbiAgICBjYXBhYmlsaXR5LnJlamVjdCA9IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgIGlzU2V0dGxlZCA9IHRydWU7XG4gICAgICByZWplY3QocmVhc29uKTtcbiAgICB9O1xuICB9KTtcbiAgcmV0dXJuIGNhcGFiaWxpdHk7XG59XG5cbi8qKiovIH0pLFxuLyogMiAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgX191bnVzZWRfd2VicGFja19leHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG52YXIgX2lzX25vZGUgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDMpO1xuXG47XG5cbi8qKiovIH0pLFxuLyogMyAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5pc05vZGVKUyA9IHZvaWQgMDtcbmNvbnN0IGlzTm9kZUpTID0gdHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgcHJvY2VzcyArIFwiXCIgPT09IFwiW29iamVjdCBwcm9jZXNzXVwiICYmICFwcm9jZXNzLnZlcnNpb25zLm53ICYmICEocHJvY2Vzcy52ZXJzaW9ucy5lbGVjdHJvbiAmJiBwcm9jZXNzLnR5cGUgJiYgcHJvY2Vzcy50eXBlICE9PSBcImJyb3dzZXJcIik7XG5leHBvcnRzLmlzTm9kZUpTID0gaXNOb2RlSlM7XG5cbi8qKiovIH0pLFxuLyogNCAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5idWlsZCA9IGV4cG9ydHMuUmVuZGVyVGFzayA9IGV4cG9ydHMuUERGV29ya2VyVXRpbCA9IGV4cG9ydHMuUERGV29ya2VyID0gZXhwb3J0cy5QREZQYWdlUHJveHkgPSBleHBvcnRzLlBERkRvY3VtZW50UHJveHkgPSBleHBvcnRzLlBERkRvY3VtZW50TG9hZGluZ1Rhc2sgPSBleHBvcnRzLlBERkRhdGFSYW5nZVRyYW5zcG9ydCA9IGV4cG9ydHMuTG9vcGJhY2tQb3J0ID0gZXhwb3J0cy5EZWZhdWx0U3RhbmRhcmRGb250RGF0YUZhY3RvcnkgPSBleHBvcnRzLkRlZmF1bHRDYW52YXNGYWN0b3J5ID0gZXhwb3J0cy5EZWZhdWx0Q01hcFJlYWRlckZhY3RvcnkgPSB2b2lkIDA7XG5leHBvcnRzLmdldERvY3VtZW50ID0gZ2V0RG9jdW1lbnQ7XG5leHBvcnRzLnNldFBERk5ldHdvcmtTdHJlYW1GYWN0b3J5ID0gc2V0UERGTmV0d29ya1N0cmVhbUZhY3Rvcnk7XG5leHBvcnRzLnZlcnNpb24gPSB2b2lkIDA7XG5cbnZhciBfdXRpbCA9IF9fd19wZGZqc19yZXF1aXJlX18oMSk7XG5cbnZhciBfZGlzcGxheV91dGlscyA9IF9fd19wZGZqc19yZXF1aXJlX18oNSk7XG5cbnZhciBfZm9udF9sb2FkZXIgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDcpO1xuXG52YXIgX2Fubm90YXRpb25fc3RvcmFnZSA9IF9fd19wZGZqc19yZXF1aXJlX18oOCk7XG5cbnZhciBfY2FudmFzID0gX193X3BkZmpzX3JlcXVpcmVfXygxMCk7XG5cbnZhciBfd29ya2VyX29wdGlvbnMgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDEzKTtcblxudmFyIF9pc19ub2RlID0gX193X3BkZmpzX3JlcXVpcmVfXygzKTtcblxudmFyIF9tZXNzYWdlX2hhbmRsZXIgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDE0KTtcblxudmFyIF9tZXRhZGF0YSA9IF9fd19wZGZqc19yZXF1aXJlX18oMTUpO1xuXG52YXIgX29wdGlvbmFsX2NvbnRlbnRfY29uZmlnID0gX193X3BkZmpzX3JlcXVpcmVfXygxNik7XG5cbnZhciBfdHJhbnNwb3J0X3N0cmVhbSA9IF9fd19wZGZqc19yZXF1aXJlX18oMTcpO1xuXG52YXIgX3hmYV90ZXh0ID0gX193X3BkZmpzX3JlcXVpcmVfXygxOCk7XG5cbmNvbnN0IERFRkFVTFRfUkFOR0VfQ0hVTktfU0laRSA9IDY1NTM2O1xuY29uc3QgUkVOREVSSU5HX0NBTkNFTExFRF9USU1FT1VUID0gMTAwO1xubGV0IERlZmF1bHRDYW52YXNGYWN0b3J5ID0gX2Rpc3BsYXlfdXRpbHMuRE9NQ2FudmFzRmFjdG9yeTtcbmV4cG9ydHMuRGVmYXVsdENhbnZhc0ZhY3RvcnkgPSBEZWZhdWx0Q2FudmFzRmFjdG9yeTtcbmxldCBEZWZhdWx0Q01hcFJlYWRlckZhY3RvcnkgPSBfZGlzcGxheV91dGlscy5ET01DTWFwUmVhZGVyRmFjdG9yeTtcbmV4cG9ydHMuRGVmYXVsdENNYXBSZWFkZXJGYWN0b3J5ID0gRGVmYXVsdENNYXBSZWFkZXJGYWN0b3J5O1xubGV0IERlZmF1bHRTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSA9IF9kaXNwbGF5X3V0aWxzLkRPTVN0YW5kYXJkRm9udERhdGFGYWN0b3J5O1xuZXhwb3J0cy5EZWZhdWx0U3RhbmRhcmRGb250RGF0YUZhY3RvcnkgPSBEZWZhdWx0U3RhbmRhcmRGb250RGF0YUZhY3Rvcnk7XG5cbmlmIChfaXNfbm9kZS5pc05vZGVKUykge1xuICBjb25zdCB7XG4gICAgTm9kZUNhbnZhc0ZhY3RvcnksXG4gICAgTm9kZUNNYXBSZWFkZXJGYWN0b3J5LFxuICAgIE5vZGVTdGFuZGFyZEZvbnREYXRhRmFjdG9yeVxuICB9ID0gX193X3BkZmpzX3JlcXVpcmVfXygxOSk7XG5cbiAgZXhwb3J0cy5EZWZhdWx0Q2FudmFzRmFjdG9yeSA9IERlZmF1bHRDYW52YXNGYWN0b3J5ID0gTm9kZUNhbnZhc0ZhY3Rvcnk7XG4gIGV4cG9ydHMuRGVmYXVsdENNYXBSZWFkZXJGYWN0b3J5ID0gRGVmYXVsdENNYXBSZWFkZXJGYWN0b3J5ID0gTm9kZUNNYXBSZWFkZXJGYWN0b3J5O1xuICBleHBvcnRzLkRlZmF1bHRTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSA9IERlZmF1bHRTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSA9IE5vZGVTdGFuZGFyZEZvbnREYXRhRmFjdG9yeTtcbn1cblxubGV0IGNyZWF0ZVBERk5ldHdvcmtTdHJlYW07XG5cbmZ1bmN0aW9uIHNldFBERk5ldHdvcmtTdHJlYW1GYWN0b3J5KHBkZk5ldHdvcmtTdHJlYW1GYWN0b3J5KSB7XG4gIGNyZWF0ZVBERk5ldHdvcmtTdHJlYW0gPSBwZGZOZXR3b3JrU3RyZWFtRmFjdG9yeTtcbn1cblxuZnVuY3Rpb24gZ2V0RG9jdW1lbnQoc3JjKSB7XG4gIGNvbnN0IHRhc2sgPSBuZXcgUERGRG9jdW1lbnRMb2FkaW5nVGFzaygpO1xuICBsZXQgc291cmNlO1xuXG4gIGlmICh0eXBlb2Ygc3JjID09PSBcInN0cmluZ1wiIHx8IHNyYyBpbnN0YW5jZW9mIFVSTCkge1xuICAgIHNvdXJjZSA9IHtcbiAgICAgIHVybDogc3JjXG4gICAgfTtcbiAgfSBlbHNlIGlmICgoMCwgX3V0aWwuaXNBcnJheUJ1ZmZlcikoc3JjKSkge1xuICAgIHNvdXJjZSA9IHtcbiAgICAgIGRhdGE6IHNyY1xuICAgIH07XG4gIH0gZWxzZSBpZiAoc3JjIGluc3RhbmNlb2YgUERGRGF0YVJhbmdlVHJhbnNwb3J0KSB7XG4gICAgc291cmNlID0ge1xuICAgICAgcmFuZ2U6IHNyY1xuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgaWYgKHR5cGVvZiBzcmMgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgcGFyYW1ldGVyIGluIGdldERvY3VtZW50LCBcIiArIFwibmVlZCBlaXRoZXIgc3RyaW5nLCBVUkwsIFVpbnQ4QXJyYXksIG9yIHBhcmFtZXRlciBvYmplY3QuXCIpO1xuICAgIH1cblxuICAgIGlmICghc3JjLnVybCAmJiAhc3JjLmRhdGEgJiYgIXNyYy5yYW5nZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBwYXJhbWV0ZXIgb2JqZWN0OiBuZWVkIGVpdGhlciAuZGF0YSwgLnJhbmdlIG9yIC51cmxcIik7XG4gICAgfVxuXG4gICAgc291cmNlID0gc3JjO1xuICB9XG5cbiAgY29uc3QgcGFyYW1zID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgbGV0IHJhbmdlVHJhbnNwb3J0ID0gbnVsbCxcbiAgICAgIHdvcmtlciA9IG51bGw7XG5cbiAgZm9yIChjb25zdCBrZXkgaW4gc291cmNlKSB7XG4gICAgY29uc3QgdmFsdWUgPSBzb3VyY2Vba2V5XTtcblxuICAgIHN3aXRjaCAoa2V5KSB7XG4gICAgICBjYXNlIFwidXJsXCI6XG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHBhcmFtc1trZXldID0gbmV3IFVSTCh2YWx1ZSwgd2luZG93LmxvY2F0aW9uKS5ocmVmO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgICAgICAgICgwLCBfdXRpbC53YXJuKShgQ2Fubm90IGNyZWF0ZSB2YWxpZCBVUkw6IFwiJHtleH1cIi5gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiIHx8IHZhbHVlIGluc3RhbmNlb2YgVVJMKSB7XG4gICAgICAgICAgcGFyYW1zW2tleV0gPSB2YWx1ZS50b1N0cmluZygpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBQREYgdXJsIGRhdGE6IFwiICsgXCJlaXRoZXIgc3RyaW5nIG9yIFVSTC1vYmplY3QgaXMgZXhwZWN0ZWQgaW4gdGhlIHVybCBwcm9wZXJ0eS5cIik7XG5cbiAgICAgIGNhc2UgXCJyYW5nZVwiOlxuICAgICAgICByYW5nZVRyYW5zcG9ydCA9IHZhbHVlO1xuICAgICAgICBjb250aW51ZTtcblxuICAgICAgY2FzZSBcIndvcmtlclwiOlxuICAgICAgICB3b3JrZXIgPSB2YWx1ZTtcbiAgICAgICAgY29udGludWU7XG5cbiAgICAgIGNhc2UgXCJkYXRhXCI6XG4gICAgICAgIGlmIChfaXNfbm9kZS5pc05vZGVKUyAmJiB0eXBlb2YgQnVmZmVyICE9PSBcInVuZGVmaW5lZFwiICYmIHZhbHVlIGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgICAgICAgcGFyYW1zW2tleV0gPSBuZXcgVWludDhBcnJheSh2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgcGFyYW1zW2tleV0gPSAoMCwgX3V0aWwuc3RyaW5nVG9CeXRlcykodmFsdWUpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiB2YWx1ZSAhPT0gbnVsbCAmJiAhaXNOYU4odmFsdWUubGVuZ3RoKSkge1xuICAgICAgICAgIHBhcmFtc1trZXldID0gbmV3IFVpbnQ4QXJyYXkodmFsdWUpO1xuICAgICAgICB9IGVsc2UgaWYgKCgwLCBfdXRpbC5pc0FycmF5QnVmZmVyKSh2YWx1ZSkpIHtcbiAgICAgICAgICBwYXJhbXNba2V5XSA9IG5ldyBVaW50OEFycmF5KHZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIFBERiBiaW5hcnkgZGF0YTogZWl0aGVyIHR5cGVkIGFycmF5LCBcIiArIFwic3RyaW5nLCBvciBhcnJheS1saWtlIG9iamVjdCBpcyBleHBlY3RlZCBpbiB0aGUgZGF0YSBwcm9wZXJ0eS5cIik7XG4gICAgICAgIH1cblxuICAgICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBwYXJhbXNba2V5XSA9IHZhbHVlO1xuICB9XG5cbiAgcGFyYW1zLkNNYXBSZWFkZXJGYWN0b3J5ID0gcGFyYW1zLkNNYXBSZWFkZXJGYWN0b3J5IHx8IERlZmF1bHRDTWFwUmVhZGVyRmFjdG9yeTtcbiAgcGFyYW1zLlN0YW5kYXJkRm9udERhdGFGYWN0b3J5ID0gcGFyYW1zLlN0YW5kYXJkRm9udERhdGFGYWN0b3J5IHx8IERlZmF1bHRTdGFuZGFyZEZvbnREYXRhRmFjdG9yeTtcbiAgcGFyYW1zLmlnbm9yZUVycm9ycyA9IHBhcmFtcy5zdG9wQXRFcnJvcnMgIT09IHRydWU7XG4gIHBhcmFtcy5mb250RXh0cmFQcm9wZXJ0aWVzID0gcGFyYW1zLmZvbnRFeHRyYVByb3BlcnRpZXMgPT09IHRydWU7XG4gIHBhcmFtcy5wZGZCdWcgPSBwYXJhbXMucGRmQnVnID09PSB0cnVlO1xuICBwYXJhbXMuZW5hYmxlWGZhID0gcGFyYW1zLmVuYWJsZVhmYSA9PT0gdHJ1ZTtcblxuICBpZiAoIU51bWJlci5pc0ludGVnZXIocGFyYW1zLnJhbmdlQ2h1bmtTaXplKSB8fCBwYXJhbXMucmFuZ2VDaHVua1NpemUgPCAxKSB7XG4gICAgcGFyYW1zLnJhbmdlQ2h1bmtTaXplID0gREVGQVVMVF9SQU5HRV9DSFVOS19TSVpFO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBwYXJhbXMuZG9jQmFzZVVybCAhPT0gXCJzdHJpbmdcIiB8fCAoMCwgX2Rpc3BsYXlfdXRpbHMuaXNEYXRhU2NoZW1lKShwYXJhbXMuZG9jQmFzZVVybCkpIHtcbiAgICBwYXJhbXMuZG9jQmFzZVVybCA9IG51bGw7XG4gIH1cblxuICBpZiAoIU51bWJlci5pc0ludGVnZXIocGFyYW1zLm1heEltYWdlU2l6ZSkgfHwgcGFyYW1zLm1heEltYWdlU2l6ZSA8IC0xKSB7XG4gICAgcGFyYW1zLm1heEltYWdlU2l6ZSA9IC0xO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBwYXJhbXMuY01hcFVybCAhPT0gXCJzdHJpbmdcIikge1xuICAgIHBhcmFtcy5jTWFwVXJsID0gbnVsbDtcbiAgfVxuXG4gIGlmICh0eXBlb2YgcGFyYW1zLnN0YW5kYXJkRm9udERhdGFVcmwgIT09IFwic3RyaW5nXCIpIHtcbiAgICBwYXJhbXMuc3RhbmRhcmRGb250RGF0YVVybCA9IG51bGw7XG4gIH1cblxuICBpZiAodHlwZW9mIHBhcmFtcy51c2VXb3JrZXJGZXRjaCAhPT0gXCJib29sZWFuXCIpIHtcbiAgICBwYXJhbXMudXNlV29ya2VyRmV0Y2ggPSBwYXJhbXMuQ01hcFJlYWRlckZhY3RvcnkgPT09IF9kaXNwbGF5X3V0aWxzLkRPTUNNYXBSZWFkZXJGYWN0b3J5ICYmIHBhcmFtcy5TdGFuZGFyZEZvbnREYXRhRmFjdG9yeSA9PT0gX2Rpc3BsYXlfdXRpbHMuRE9NU3RhbmRhcmRGb250RGF0YUZhY3Rvcnk7XG4gIH1cblxuICBpZiAodHlwZW9mIHBhcmFtcy5pc0V2YWxTdXBwb3J0ZWQgIT09IFwiYm9vbGVhblwiKSB7XG4gICAgcGFyYW1zLmlzRXZhbFN1cHBvcnRlZCA9IHRydWU7XG4gIH1cblxuICBpZiAodHlwZW9mIHBhcmFtcy5kaXNhYmxlRm9udEZhY2UgIT09IFwiYm9vbGVhblwiKSB7XG4gICAgcGFyYW1zLmRpc2FibGVGb250RmFjZSA9IF9pc19ub2RlLmlzTm9kZUpTO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBwYXJhbXMudXNlU3lzdGVtRm9udHMgIT09IFwiYm9vbGVhblwiKSB7XG4gICAgcGFyYW1zLnVzZVN5c3RlbUZvbnRzID0gIV9pc19ub2RlLmlzTm9kZUpTICYmICFwYXJhbXMuZGlzYWJsZUZvbnRGYWNlO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBwYXJhbXMub3duZXJEb2N1bWVudCAhPT0gXCJvYmplY3RcIiB8fCBwYXJhbXMub3duZXJEb2N1bWVudCA9PT0gbnVsbCkge1xuICAgIHBhcmFtcy5vd25lckRvY3VtZW50ID0gZ2xvYmFsVGhpcy5kb2N1bWVudDtcbiAgfVxuXG4gIGlmICh0eXBlb2YgcGFyYW1zLmRpc2FibGVSYW5nZSAhPT0gXCJib29sZWFuXCIpIHtcbiAgICBwYXJhbXMuZGlzYWJsZVJhbmdlID0gZmFsc2U7XG4gIH1cblxuICBpZiAodHlwZW9mIHBhcmFtcy5kaXNhYmxlU3RyZWFtICE9PSBcImJvb2xlYW5cIikge1xuICAgIHBhcmFtcy5kaXNhYmxlU3RyZWFtID0gZmFsc2U7XG4gIH1cblxuICBpZiAodHlwZW9mIHBhcmFtcy5kaXNhYmxlQXV0b0ZldGNoICE9PSBcImJvb2xlYW5cIikge1xuICAgIHBhcmFtcy5kaXNhYmxlQXV0b0ZldGNoID0gZmFsc2U7XG4gIH1cblxuICAoMCwgX3V0aWwuc2V0VmVyYm9zaXR5TGV2ZWwpKHBhcmFtcy52ZXJib3NpdHkpO1xuXG4gIGlmICghd29ya2VyKSB7XG4gICAgY29uc3Qgd29ya2VyUGFyYW1zID0ge1xuICAgICAgdmVyYm9zaXR5OiBwYXJhbXMudmVyYm9zaXR5LFxuICAgICAgcG9ydDogX3dvcmtlcl9vcHRpb25zLkdsb2JhbFdvcmtlck9wdGlvbnMud29ya2VyUG9ydFxuICAgIH07XG4gICAgd29ya2VyID0gd29ya2VyUGFyYW1zLnBvcnQgPyBQREZXb3JrZXIuZnJvbVBvcnQod29ya2VyUGFyYW1zKSA6IG5ldyBQREZXb3JrZXIod29ya2VyUGFyYW1zKTtcbiAgICB0YXNrLl93b3JrZXIgPSB3b3JrZXI7XG4gIH1cblxuICBjb25zdCBkb2NJZCA9IHRhc2suZG9jSWQ7XG4gIHdvcmtlci5wcm9taXNlLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIGlmICh0YXNrLmRlc3Ryb3llZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTG9hZGluZyBhYm9ydGVkXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IHdvcmtlcklkUHJvbWlzZSA9IF9mZXRjaERvY3VtZW50KHdvcmtlciwgcGFyYW1zLCByYW5nZVRyYW5zcG9ydCwgZG9jSWQpO1xuXG4gICAgY29uc3QgbmV0d29ya1N0cmVhbVByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgbGV0IG5ldHdvcmtTdHJlYW07XG5cbiAgICAgIGlmIChyYW5nZVRyYW5zcG9ydCkge1xuICAgICAgICBuZXR3b3JrU3RyZWFtID0gbmV3IF90cmFuc3BvcnRfc3RyZWFtLlBERkRhdGFUcmFuc3BvcnRTdHJlYW0oe1xuICAgICAgICAgIGxlbmd0aDogcGFyYW1zLmxlbmd0aCxcbiAgICAgICAgICBpbml0aWFsRGF0YTogcGFyYW1zLmluaXRpYWxEYXRhLFxuICAgICAgICAgIHByb2dyZXNzaXZlRG9uZTogcGFyYW1zLnByb2dyZXNzaXZlRG9uZSxcbiAgICAgICAgICBjb250ZW50RGlzcG9zaXRpb25GaWxlbmFtZTogcGFyYW1zLmNvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lLFxuICAgICAgICAgIGRpc2FibGVSYW5nZTogcGFyYW1zLmRpc2FibGVSYW5nZSxcbiAgICAgICAgICBkaXNhYmxlU3RyZWFtOiBwYXJhbXMuZGlzYWJsZVN0cmVhbVxuICAgICAgICB9LCByYW5nZVRyYW5zcG9ydCk7XG4gICAgICB9IGVsc2UgaWYgKCFwYXJhbXMuZGF0YSkge1xuICAgICAgICBuZXR3b3JrU3RyZWFtID0gY3JlYXRlUERGTmV0d29ya1N0cmVhbSh7XG4gICAgICAgICAgdXJsOiBwYXJhbXMudXJsLFxuICAgICAgICAgIGxlbmd0aDogcGFyYW1zLmxlbmd0aCxcbiAgICAgICAgICBodHRwSGVhZGVyczogcGFyYW1zLmh0dHBIZWFkZXJzLFxuICAgICAgICAgIHdpdGhDcmVkZW50aWFsczogcGFyYW1zLndpdGhDcmVkZW50aWFscyxcbiAgICAgICAgICByYW5nZUNodW5rU2l6ZTogcGFyYW1zLnJhbmdlQ2h1bmtTaXplLFxuICAgICAgICAgIGRpc2FibGVSYW5nZTogcGFyYW1zLmRpc2FibGVSYW5nZSxcbiAgICAgICAgICBkaXNhYmxlU3RyZWFtOiBwYXJhbXMuZGlzYWJsZVN0cmVhbVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmVzb2x2ZShuZXR3b3JrU3RyZWFtKTtcbiAgICB9KTtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoW3dvcmtlcklkUHJvbWlzZSwgbmV0d29ya1N0cmVhbVByb21pc2VdKS50aGVuKGZ1bmN0aW9uIChbd29ya2VySWQsIG5ldHdvcmtTdHJlYW1dKSB7XG4gICAgICBpZiAodGFzay5kZXN0cm95ZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTG9hZGluZyBhYm9ydGVkXCIpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBtZXNzYWdlSGFuZGxlciA9IG5ldyBfbWVzc2FnZV9oYW5kbGVyLk1lc3NhZ2VIYW5kbGVyKGRvY0lkLCB3b3JrZXJJZCwgd29ya2VyLnBvcnQpO1xuICAgICAgY29uc3QgdHJhbnNwb3J0ID0gbmV3IFdvcmtlclRyYW5zcG9ydChtZXNzYWdlSGFuZGxlciwgdGFzaywgbmV0d29ya1N0cmVhbSwgcGFyYW1zKTtcbiAgICAgIHRhc2suX3RyYW5zcG9ydCA9IHRyYW5zcG9ydDtcbiAgICAgIG1lc3NhZ2VIYW5kbGVyLnNlbmQoXCJSZWFkeVwiLCBudWxsKTtcbiAgICB9KTtcbiAgfSkuY2F0Y2godGFzay5fY2FwYWJpbGl0eS5yZWplY3QpO1xuICByZXR1cm4gdGFzaztcbn1cblxuYXN5bmMgZnVuY3Rpb24gX2ZldGNoRG9jdW1lbnQod29ya2VyLCBzb3VyY2UsIHBkZkRhdGFSYW5nZVRyYW5zcG9ydCwgZG9jSWQpIHtcbiAgaWYgKHdvcmtlci5kZXN0cm95ZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJXb3JrZXIgd2FzIGRlc3Ryb3llZFwiKTtcbiAgfVxuXG4gIGlmIChwZGZEYXRhUmFuZ2VUcmFuc3BvcnQpIHtcbiAgICBzb3VyY2UubGVuZ3RoID0gcGRmRGF0YVJhbmdlVHJhbnNwb3J0Lmxlbmd0aDtcbiAgICBzb3VyY2UuaW5pdGlhbERhdGEgPSBwZGZEYXRhUmFuZ2VUcmFuc3BvcnQuaW5pdGlhbERhdGE7XG4gICAgc291cmNlLnByb2dyZXNzaXZlRG9uZSA9IHBkZkRhdGFSYW5nZVRyYW5zcG9ydC5wcm9ncmVzc2l2ZURvbmU7XG4gICAgc291cmNlLmNvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lID0gcGRmRGF0YVJhbmdlVHJhbnNwb3J0LmNvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lO1xuICB9XG5cbiAgY29uc3Qgd29ya2VySWQgPSBhd2FpdCB3b3JrZXIubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0RG9jUmVxdWVzdFwiLCB7XG4gICAgZG9jSWQsXG4gICAgYXBpVmVyc2lvbjogJzIuMTQuMzA1JyxcbiAgICBzb3VyY2U6IHtcbiAgICAgIGRhdGE6IHNvdXJjZS5kYXRhLFxuICAgICAgdXJsOiBzb3VyY2UudXJsLFxuICAgICAgcGFzc3dvcmQ6IHNvdXJjZS5wYXNzd29yZCxcbiAgICAgIGRpc2FibGVBdXRvRmV0Y2g6IHNvdXJjZS5kaXNhYmxlQXV0b0ZldGNoLFxuICAgICAgcmFuZ2VDaHVua1NpemU6IHNvdXJjZS5yYW5nZUNodW5rU2l6ZSxcbiAgICAgIGxlbmd0aDogc291cmNlLmxlbmd0aFxuICAgIH0sXG4gICAgbWF4SW1hZ2VTaXplOiBzb3VyY2UubWF4SW1hZ2VTaXplLFxuICAgIGRpc2FibGVGb250RmFjZTogc291cmNlLmRpc2FibGVGb250RmFjZSxcbiAgICBkb2NCYXNlVXJsOiBzb3VyY2UuZG9jQmFzZVVybCxcbiAgICBpZ25vcmVFcnJvcnM6IHNvdXJjZS5pZ25vcmVFcnJvcnMsXG4gICAgaXNFdmFsU3VwcG9ydGVkOiBzb3VyY2UuaXNFdmFsU3VwcG9ydGVkLFxuICAgIGZvbnRFeHRyYVByb3BlcnRpZXM6IHNvdXJjZS5mb250RXh0cmFQcm9wZXJ0aWVzLFxuICAgIGVuYWJsZVhmYTogc291cmNlLmVuYWJsZVhmYSxcbiAgICB1c2VTeXN0ZW1Gb250czogc291cmNlLnVzZVN5c3RlbUZvbnRzLFxuICAgIGNNYXBVcmw6IHNvdXJjZS51c2VXb3JrZXJGZXRjaCA/IHNvdXJjZS5jTWFwVXJsIDogbnVsbCxcbiAgICBzdGFuZGFyZEZvbnREYXRhVXJsOiBzb3VyY2UudXNlV29ya2VyRmV0Y2ggPyBzb3VyY2Uuc3RhbmRhcmRGb250RGF0YVVybCA6IG51bGxcbiAgfSk7XG5cbiAgaWYgKHdvcmtlci5kZXN0cm95ZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJXb3JrZXIgd2FzIGRlc3Ryb3llZFwiKTtcbiAgfVxuXG4gIHJldHVybiB3b3JrZXJJZDtcbn1cblxuY2xhc3MgUERGRG9jdW1lbnRMb2FkaW5nVGFzayB7XG4gIHN0YXRpYyAjZG9jSWQgPSAwO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuX2NhcGFiaWxpdHkgPSAoMCwgX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkpKCk7XG4gICAgdGhpcy5fdHJhbnNwb3J0ID0gbnVsbDtcbiAgICB0aGlzLl93b3JrZXIgPSBudWxsO1xuICAgIHRoaXMuZG9jSWQgPSBgZCR7UERGRG9jdW1lbnRMb2FkaW5nVGFzay4jZG9jSWQrK31gO1xuICAgIHRoaXMuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgdGhpcy5vblBhc3N3b3JkID0gbnVsbDtcbiAgICB0aGlzLm9uUHJvZ3Jlc3MgPSBudWxsO1xuICAgIHRoaXMub25VbnN1cHBvcnRlZEZlYXR1cmUgPSBudWxsO1xuICB9XG5cbiAgZ2V0IHByb21pc2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxuXG4gIGFzeW5jIGRlc3Ryb3koKSB7XG4gICAgdGhpcy5kZXN0cm95ZWQgPSB0cnVlO1xuICAgIGF3YWl0IHRoaXMuX3RyYW5zcG9ydD8uZGVzdHJveSgpO1xuICAgIHRoaXMuX3RyYW5zcG9ydCA9IG51bGw7XG5cbiAgICBpZiAodGhpcy5fd29ya2VyKSB7XG4gICAgICB0aGlzLl93b3JrZXIuZGVzdHJveSgpO1xuXG4gICAgICB0aGlzLl93b3JrZXIgPSBudWxsO1xuICAgIH1cbiAgfVxuXG59XG5cbmV4cG9ydHMuUERGRG9jdW1lbnRMb2FkaW5nVGFzayA9IFBERkRvY3VtZW50TG9hZGluZ1Rhc2s7XG5cbmNsYXNzIFBERkRhdGFSYW5nZVRyYW5zcG9ydCB7XG4gIGNvbnN0cnVjdG9yKGxlbmd0aCwgaW5pdGlhbERhdGEsIHByb2dyZXNzaXZlRG9uZSA9IGZhbHNlLCBjb250ZW50RGlzcG9zaXRpb25GaWxlbmFtZSA9IG51bGwpIHtcbiAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDtcbiAgICB0aGlzLmluaXRpYWxEYXRhID0gaW5pdGlhbERhdGE7XG4gICAgdGhpcy5wcm9ncmVzc2l2ZURvbmUgPSBwcm9ncmVzc2l2ZURvbmU7XG4gICAgdGhpcy5jb250ZW50RGlzcG9zaXRpb25GaWxlbmFtZSA9IGNvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lO1xuICAgIHRoaXMuX3JhbmdlTGlzdGVuZXJzID0gW107XG4gICAgdGhpcy5fcHJvZ3Jlc3NMaXN0ZW5lcnMgPSBbXTtcbiAgICB0aGlzLl9wcm9ncmVzc2l2ZVJlYWRMaXN0ZW5lcnMgPSBbXTtcbiAgICB0aGlzLl9wcm9ncmVzc2l2ZURvbmVMaXN0ZW5lcnMgPSBbXTtcbiAgICB0aGlzLl9yZWFkeUNhcGFiaWxpdHkgPSAoMCwgX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkpKCk7XG4gIH1cblxuICBhZGRSYW5nZUxpc3RlbmVyKGxpc3RlbmVyKSB7XG4gICAgdGhpcy5fcmFuZ2VMaXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7XG4gIH1cblxuICBhZGRQcm9ncmVzc0xpc3RlbmVyKGxpc3RlbmVyKSB7XG4gICAgdGhpcy5fcHJvZ3Jlc3NMaXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7XG4gIH1cblxuICBhZGRQcm9ncmVzc2l2ZVJlYWRMaXN0ZW5lcihsaXN0ZW5lcikge1xuICAgIHRoaXMuX3Byb2dyZXNzaXZlUmVhZExpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTtcbiAgfVxuXG4gIGFkZFByb2dyZXNzaXZlRG9uZUxpc3RlbmVyKGxpc3RlbmVyKSB7XG4gICAgdGhpcy5fcHJvZ3Jlc3NpdmVEb25lTGlzdGVuZXJzLnB1c2gobGlzdGVuZXIpO1xuICB9XG5cbiAgb25EYXRhUmFuZ2UoYmVnaW4sIGNodW5rKSB7XG4gICAgZm9yIChjb25zdCBsaXN0ZW5lciBvZiB0aGlzLl9yYW5nZUxpc3RlbmVycykge1xuICAgICAgbGlzdGVuZXIoYmVnaW4sIGNodW5rKTtcbiAgICB9XG4gIH1cblxuICBvbkRhdGFQcm9ncmVzcyhsb2FkZWQsIHRvdGFsKSB7XG4gICAgdGhpcy5fcmVhZHlDYXBhYmlsaXR5LnByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGxpc3RlbmVyIG9mIHRoaXMuX3Byb2dyZXNzTGlzdGVuZXJzKSB7XG4gICAgICAgIGxpc3RlbmVyKGxvYWRlZCwgdG90YWwpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgb25EYXRhUHJvZ3Jlc3NpdmVSZWFkKGNodW5rKSB7XG4gICAgdGhpcy5fcmVhZHlDYXBhYmlsaXR5LnByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGxpc3RlbmVyIG9mIHRoaXMuX3Byb2dyZXNzaXZlUmVhZExpc3RlbmVycykge1xuICAgICAgICBsaXN0ZW5lcihjaHVuayk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBvbkRhdGFQcm9ncmVzc2l2ZURvbmUoKSB7XG4gICAgdGhpcy5fcmVhZHlDYXBhYmlsaXR5LnByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGxpc3RlbmVyIG9mIHRoaXMuX3Byb2dyZXNzaXZlRG9uZUxpc3RlbmVycykge1xuICAgICAgICBsaXN0ZW5lcigpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgdHJhbnNwb3J0UmVhZHkoKSB7XG4gICAgdGhpcy5fcmVhZHlDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgfVxuXG4gIHJlcXVlc3REYXRhUmFuZ2UoYmVnaW4sIGVuZCkge1xuICAgICgwLCBfdXRpbC51bnJlYWNoYWJsZSkoXCJBYnN0cmFjdCBtZXRob2QgUERGRGF0YVJhbmdlVHJhbnNwb3J0LnJlcXVlc3REYXRhUmFuZ2VcIik7XG4gIH1cblxuICBhYm9ydCgpIHt9XG5cbn1cblxuZXhwb3J0cy5QREZEYXRhUmFuZ2VUcmFuc3BvcnQgPSBQREZEYXRhUmFuZ2VUcmFuc3BvcnQ7XG5cbmNsYXNzIFBERkRvY3VtZW50UHJveHkge1xuICBjb25zdHJ1Y3RvcihwZGZJbmZvLCB0cmFuc3BvcnQpIHtcbiAgICB0aGlzLl9wZGZJbmZvID0gcGRmSW5mbztcbiAgICB0aGlzLl90cmFuc3BvcnQgPSB0cmFuc3BvcnQ7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIFwiZmluZ2VycHJpbnRcIiwge1xuICAgICAgZ2V0KCkge1xuICAgICAgICAoMCwgX2Rpc3BsYXlfdXRpbHMuZGVwcmVjYXRlZCkoXCJgUERGRG9jdW1lbnRQcm94eS5maW5nZXJwcmludGAsIFwiICsgXCJwbGVhc2UgdXNlIGBQREZEb2N1bWVudFByb3h5LmZpbmdlcnByaW50c2AgaW5zdGVhZC5cIik7XG4gICAgICAgIHJldHVybiB0aGlzLmZpbmdlcnByaW50c1swXTtcbiAgICAgIH1cblxuICAgIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBcImdldFN0YXRzXCIsIHtcbiAgICAgIHZhbHVlOiBhc3luYyAoKSA9PiB7XG4gICAgICAgICgwLCBfZGlzcGxheV91dGlscy5kZXByZWNhdGVkKShcImBQREZEb2N1bWVudFByb3h5LmdldFN0YXRzYCwgXCIgKyBcInBsZWFzZSB1c2UgdGhlIGBQREZEb2N1bWVudFByb3h5LnN0YXRzYC1nZXR0ZXIgaW5zdGVhZC5cIik7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXRzIHx8IHtcbiAgICAgICAgICBzdHJlYW1UeXBlczoge30sXG4gICAgICAgICAgZm9udFR5cGVzOiB7fVxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZ2V0IGFubm90YXRpb25TdG9yYWdlKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuYW5ub3RhdGlvblN0b3JhZ2U7XG4gIH1cblxuICBnZXQgbnVtUGFnZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BkZkluZm8ubnVtUGFnZXM7XG4gIH1cblxuICBnZXQgZmluZ2VycHJpbnRzKCkge1xuICAgIHJldHVybiB0aGlzLl9wZGZJbmZvLmZpbmdlcnByaW50cztcbiAgfVxuXG4gIGdldCBzdGF0cygpIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0LnN0YXRzO1xuICB9XG5cbiAgZ2V0IGlzUHVyZVhmYSgpIHtcbiAgICByZXR1cm4gISF0aGlzLl90cmFuc3BvcnQuX2h0bWxGb3JYZmE7XG4gIH1cblxuICBnZXQgYWxsWGZhSHRtbCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0Ll9odG1sRm9yWGZhO1xuICB9XG5cbiAgZ2V0UGFnZShwYWdlTnVtYmVyKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RyYW5zcG9ydC5nZXRQYWdlKHBhZ2VOdW1iZXIpO1xuICB9XG5cbiAgZ2V0UGFnZUluZGV4KHJlZikge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0UGFnZUluZGV4KHJlZik7XG4gIH1cblxuICBnZXREZXN0aW5hdGlvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RyYW5zcG9ydC5nZXREZXN0aW5hdGlvbnMoKTtcbiAgfVxuXG4gIGdldERlc3RpbmF0aW9uKGlkKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RyYW5zcG9ydC5nZXREZXN0aW5hdGlvbihpZCk7XG4gIH1cblxuICBnZXRQYWdlTGFiZWxzKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0UGFnZUxhYmVscygpO1xuICB9XG5cbiAgZ2V0UGFnZUxheW91dCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0LmdldFBhZ2VMYXlvdXQoKTtcbiAgfVxuXG4gIGdldFBhZ2VNb2RlKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0UGFnZU1vZGUoKTtcbiAgfVxuXG4gIGdldFZpZXdlclByZWZlcmVuY2VzKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0Vmlld2VyUHJlZmVyZW5jZXMoKTtcbiAgfVxuXG4gIGdldE9wZW5BY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RyYW5zcG9ydC5nZXRPcGVuQWN0aW9uKCk7XG4gIH1cblxuICBnZXRBdHRhY2htZW50cygpIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0LmdldEF0dGFjaG1lbnRzKCk7XG4gIH1cblxuICBnZXRKYXZhU2NyaXB0KCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0SmF2YVNjcmlwdCgpO1xuICB9XG5cbiAgZ2V0SlNBY3Rpb25zKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0RG9jSlNBY3Rpb25zKCk7XG4gIH1cblxuICBnZXRPdXRsaW5lKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0T3V0bGluZSgpO1xuICB9XG5cbiAgZ2V0T3B0aW9uYWxDb250ZW50Q29uZmlnKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0T3B0aW9uYWxDb250ZW50Q29uZmlnKCk7XG4gIH1cblxuICBnZXRQZXJtaXNzaW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0LmdldFBlcm1pc3Npb25zKCk7XG4gIH1cblxuICBnZXRNZXRhZGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0LmdldE1ldGFkYXRhKCk7XG4gIH1cblxuICBnZXRNYXJrSW5mbygpIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0LmdldE1hcmtJbmZvKCk7XG4gIH1cblxuICBnZXREYXRhKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0RGF0YSgpO1xuICB9XG5cbiAgZ2V0RG93bmxvYWRJbmZvKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZG93bmxvYWRJbmZvQ2FwYWJpbGl0eS5wcm9taXNlO1xuICB9XG5cbiAgY2xlYW51cChrZWVwTG9hZGVkRm9udHMgPSBmYWxzZSkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuc3RhcnRDbGVhbnVwKGtlZXBMb2FkZWRGb250cyB8fCB0aGlzLmlzUHVyZVhmYSk7XG4gIH1cblxuICBkZXN0cm95KCkge1xuICAgIHJldHVybiB0aGlzLmxvYWRpbmdUYXNrLmRlc3Ryb3koKTtcbiAgfVxuXG4gIGdldCBsb2FkaW5nUGFyYW1zKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQubG9hZGluZ1BhcmFtcztcbiAgfVxuXG4gIGdldCBsb2FkaW5nVGFzaygpIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0LmxvYWRpbmdUYXNrO1xuICB9XG5cbiAgc2F2ZURvY3VtZW50KCkge1xuICAgIGlmICh0aGlzLl90cmFuc3BvcnQuYW5ub3RhdGlvblN0b3JhZ2Uuc2l6ZSA8PSAwKSB7XG4gICAgICAoMCwgX2Rpc3BsYXlfdXRpbHMuZGVwcmVjYXRlZCkoXCJzYXZlRG9jdW1lbnQgY2FsbGVkIHdoaWxlIGBhbm5vdGF0aW9uU3RvcmFnZWAgaXMgZW1wdHksIFwiICsgXCJwbGVhc2UgdXNlIHRoZSBnZXREYXRhLW1ldGhvZCBpbnN0ZWFkLlwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0LnNhdmVEb2N1bWVudCgpO1xuICB9XG5cbiAgZ2V0RmllbGRPYmplY3RzKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0RmllbGRPYmplY3RzKCk7XG4gIH1cblxuICBoYXNKU0FjdGlvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RyYW5zcG9ydC5oYXNKU0FjdGlvbnMoKTtcbiAgfVxuXG4gIGdldENhbGN1bGF0aW9uT3JkZXJJZHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RyYW5zcG9ydC5nZXRDYWxjdWxhdGlvbk9yZGVySWRzKCk7XG4gIH1cblxufVxuXG5leHBvcnRzLlBERkRvY3VtZW50UHJveHkgPSBQREZEb2N1bWVudFByb3h5O1xuXG5jbGFzcyBQREZQYWdlUHJveHkge1xuICBjb25zdHJ1Y3RvcihwYWdlSW5kZXgsIHBhZ2VJbmZvLCB0cmFuc3BvcnQsIG93bmVyRG9jdW1lbnQsIHBkZkJ1ZyA9IGZhbHNlKSB7XG4gICAgdGhpcy5fcGFnZUluZGV4ID0gcGFnZUluZGV4O1xuICAgIHRoaXMuX3BhZ2VJbmZvID0gcGFnZUluZm87XG4gICAgdGhpcy5fb3duZXJEb2N1bWVudCA9IG93bmVyRG9jdW1lbnQ7XG4gICAgdGhpcy5fdHJhbnNwb3J0ID0gdHJhbnNwb3J0O1xuICAgIHRoaXMuX3N0YXRzID0gcGRmQnVnID8gbmV3IF9kaXNwbGF5X3V0aWxzLlN0YXRUaW1lcigpIDogbnVsbDtcbiAgICB0aGlzLl9wZGZCdWcgPSBwZGZCdWc7XG4gICAgdGhpcy5jb21tb25PYmpzID0gdHJhbnNwb3J0LmNvbW1vbk9ianM7XG4gICAgdGhpcy5vYmpzID0gbmV3IFBERk9iamVjdHMoKTtcbiAgICB0aGlzLl9iaXRtYXBzID0gbmV3IFNldCgpO1xuICAgIHRoaXMuY2xlYW51cEFmdGVyUmVuZGVyID0gZmFsc2U7XG4gICAgdGhpcy5wZW5kaW5nQ2xlYW51cCA9IGZhbHNlO1xuICAgIHRoaXMuX2ludGVudFN0YXRlcyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLl9hbm5vdGF0aW9uUHJvbWlzZXMgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5kZXN0cm95ZWQgPSBmYWxzZTtcbiAgfVxuXG4gIGdldCBwYWdlTnVtYmVyKCkge1xuICAgIHJldHVybiB0aGlzLl9wYWdlSW5kZXggKyAxO1xuICB9XG5cbiAgZ2V0IHJvdGF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fcGFnZUluZm8ucm90YXRlO1xuICB9XG5cbiAgZ2V0IHJlZigpIHtcbiAgICByZXR1cm4gdGhpcy5fcGFnZUluZm8ucmVmO1xuICB9XG5cbiAgZ2V0IHVzZXJVbml0KCkge1xuICAgIHJldHVybiB0aGlzLl9wYWdlSW5mby51c2VyVW5pdDtcbiAgfVxuXG4gIGdldCB2aWV3KCkge1xuICAgIHJldHVybiB0aGlzLl9wYWdlSW5mby52aWV3O1xuICB9XG5cbiAgZ2V0Vmlld3BvcnQoe1xuICAgIHNjYWxlLFxuICAgIHJvdGF0aW9uID0gdGhpcy5yb3RhdGUsXG4gICAgb2Zmc2V0WCA9IDAsXG4gICAgb2Zmc2V0WSA9IDAsXG4gICAgZG9udEZsaXAgPSBmYWxzZVxuICB9ID0ge30pIHtcbiAgICByZXR1cm4gbmV3IF9kaXNwbGF5X3V0aWxzLlBhZ2VWaWV3cG9ydCh7XG4gICAgICB2aWV3Qm94OiB0aGlzLnZpZXcsXG4gICAgICBzY2FsZSxcbiAgICAgIHJvdGF0aW9uLFxuICAgICAgb2Zmc2V0WCxcbiAgICAgIG9mZnNldFksXG4gICAgICBkb250RmxpcFxuICAgIH0pO1xuICB9XG5cbiAgZ2V0QW5ub3RhdGlvbnMoe1xuICAgIGludGVudCA9IFwiZGlzcGxheVwiXG4gIH0gPSB7fSkge1xuICAgIGNvbnN0IGludGVudEFyZ3MgPSB0aGlzLl90cmFuc3BvcnQuZ2V0UmVuZGVyaW5nSW50ZW50KGludGVudCk7XG5cbiAgICBsZXQgcHJvbWlzZSA9IHRoaXMuX2Fubm90YXRpb25Qcm9taXNlcy5nZXQoaW50ZW50QXJncy5jYWNoZUtleSk7XG5cbiAgICBpZiAoIXByb21pc2UpIHtcbiAgICAgIHByb21pc2UgPSB0aGlzLl90cmFuc3BvcnQuZ2V0QW5ub3RhdGlvbnModGhpcy5fcGFnZUluZGV4LCBpbnRlbnRBcmdzLnJlbmRlcmluZ0ludGVudCk7XG5cbiAgICAgIHRoaXMuX2Fubm90YXRpb25Qcm9taXNlcy5zZXQoaW50ZW50QXJncy5jYWNoZUtleSwgcHJvbWlzZSk7XG5cbiAgICAgIHByb21pc2UgPSBwcm9taXNlLnRoZW4oYW5ub3RhdGlvbnMgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IGFubm90YXRpb24gb2YgYW5ub3RhdGlvbnMpIHtcbiAgICAgICAgICBpZiAoYW5ub3RhdGlvbi50aXRsZU9iaiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoYW5ub3RhdGlvbiwgXCJ0aXRsZVwiLCB7XG4gICAgICAgICAgICAgIGdldCgpIHtcbiAgICAgICAgICAgICAgICAoMCwgX2Rpc3BsYXlfdXRpbHMuZGVwcmVjYXRlZCkoXCJgdGl0bGVgLXByb3BlcnR5IG9uIGFubm90YXRpb24sIHBsZWFzZSB1c2UgYHRpdGxlT2JqYCBpbnN0ZWFkLlwiKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYW5ub3RhdGlvbi50aXRsZU9iai5zdHI7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGFubm90YXRpb24uY29udGVudHNPYmogIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGFubm90YXRpb24sIFwiY29udGVudHNcIiwge1xuICAgICAgICAgICAgICBnZXQoKSB7XG4gICAgICAgICAgICAgICAgKDAsIF9kaXNwbGF5X3V0aWxzLmRlcHJlY2F0ZWQpKFwiYGNvbnRlbnRzYC1wcm9wZXJ0eSBvbiBhbm5vdGF0aW9uLCBwbGVhc2UgdXNlIGBjb250ZW50c09iamAgaW5zdGVhZC5cIik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFubm90YXRpb24uY29udGVudHNPYmouc3RyO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhbm5vdGF0aW9ucztcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgZ2V0SlNBY3Rpb25zKCkge1xuICAgIHJldHVybiB0aGlzLl9qc0FjdGlvbnNQcm9taXNlIHx8PSB0aGlzLl90cmFuc3BvcnQuZ2V0UGFnZUpTQWN0aW9ucyh0aGlzLl9wYWdlSW5kZXgpO1xuICB9XG5cbiAgYXN5bmMgZ2V0WGZhKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuX2h0bWxGb3JYZmE/LmNoaWxkcmVuW3RoaXMuX3BhZ2VJbmRleF0gfHwgbnVsbDtcbiAgfVxuXG4gIHJlbmRlcih7XG4gICAgY2FudmFzQ29udGV4dCxcbiAgICB2aWV3cG9ydCxcbiAgICBpbnRlbnQgPSBcImRpc3BsYXlcIixcbiAgICBhbm5vdGF0aW9uTW9kZSA9IF91dGlsLkFubm90YXRpb25Nb2RlLkVOQUJMRSxcbiAgICB0cmFuc2Zvcm0gPSBudWxsLFxuICAgIGltYWdlTGF5ZXIgPSBudWxsLFxuICAgIGNhbnZhc0ZhY3RvcnkgPSBudWxsLFxuICAgIGJhY2tncm91bmQgPSBudWxsLFxuICAgIG9wdGlvbmFsQ29udGVudENvbmZpZ1Byb21pc2UgPSBudWxsLFxuICAgIGFubm90YXRpb25DYW52YXNNYXAgPSBudWxsLFxuICAgIHBhZ2VDb2xvcnMgPSBudWxsXG4gIH0pIHtcbiAgICBpZiAoYXJndW1lbnRzWzBdPy5yZW5kZXJJbnRlcmFjdGl2ZUZvcm1zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICgwLCBfZGlzcGxheV91dGlscy5kZXByZWNhdGVkKShcInJlbmRlciBubyBsb25nZXIgYWNjZXB0cyB0aGUgYHJlbmRlckludGVyYWN0aXZlRm9ybXNgLW9wdGlvbiwgXCIgKyBcInBsZWFzZSB1c2UgdGhlIGBhbm5vdGF0aW9uTW9kZWAtb3B0aW9uIGluc3RlYWQuXCIpO1xuXG4gICAgICBpZiAoYXJndW1lbnRzWzBdLnJlbmRlckludGVyYWN0aXZlRm9ybXMgPT09IHRydWUgJiYgYW5ub3RhdGlvbk1vZGUgPT09IF91dGlsLkFubm90YXRpb25Nb2RlLkVOQUJMRSkge1xuICAgICAgICBhbm5vdGF0aW9uTW9kZSA9IF91dGlsLkFubm90YXRpb25Nb2RlLkVOQUJMRV9GT1JNUztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYXJndW1lbnRzWzBdPy5pbmNsdWRlQW5ub3RhdGlvblN0b3JhZ2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgKDAsIF9kaXNwbGF5X3V0aWxzLmRlcHJlY2F0ZWQpKFwicmVuZGVyIG5vIGxvbmdlciBhY2NlcHRzIHRoZSBgaW5jbHVkZUFubm90YXRpb25TdG9yYWdlYC1vcHRpb24sIFwiICsgXCJwbGVhc2UgdXNlIHRoZSBgYW5ub3RhdGlvbk1vZGVgLW9wdGlvbiBpbnN0ZWFkLlwiKTtcblxuICAgICAgaWYgKGFyZ3VtZW50c1swXS5pbmNsdWRlQW5ub3RhdGlvblN0b3JhZ2UgPT09IHRydWUgJiYgYW5ub3RhdGlvbk1vZGUgPT09IF91dGlsLkFubm90YXRpb25Nb2RlLkVOQUJMRSkge1xuICAgICAgICBhbm5vdGF0aW9uTW9kZSA9IF91dGlsLkFubm90YXRpb25Nb2RlLkVOQUJMRV9TVE9SQUdFO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLl9zdGF0cykge1xuICAgICAgdGhpcy5fc3RhdHMudGltZShcIk92ZXJhbGxcIik7XG4gICAgfVxuXG4gICAgY29uc3QgaW50ZW50QXJncyA9IHRoaXMuX3RyYW5zcG9ydC5nZXRSZW5kZXJpbmdJbnRlbnQoaW50ZW50LCBhbm5vdGF0aW9uTW9kZSk7XG5cbiAgICB0aGlzLnBlbmRpbmdDbGVhbnVwID0gZmFsc2U7XG5cbiAgICBpZiAoIW9wdGlvbmFsQ29udGVudENvbmZpZ1Byb21pc2UpIHtcbiAgICAgIG9wdGlvbmFsQ29udGVudENvbmZpZ1Byb21pc2UgPSB0aGlzLl90cmFuc3BvcnQuZ2V0T3B0aW9uYWxDb250ZW50Q29uZmlnKCk7XG4gICAgfVxuXG4gICAgbGV0IGludGVudFN0YXRlID0gdGhpcy5faW50ZW50U3RhdGVzLmdldChpbnRlbnRBcmdzLmNhY2hlS2V5KTtcblxuICAgIGlmICghaW50ZW50U3RhdGUpIHtcbiAgICAgIGludGVudFN0YXRlID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuICAgICAgdGhpcy5faW50ZW50U3RhdGVzLnNldChpbnRlbnRBcmdzLmNhY2hlS2V5LCBpbnRlbnRTdGF0ZSk7XG4gICAgfVxuXG4gICAgaWYgKGludGVudFN0YXRlLnN0cmVhbVJlYWRlckNhbmNlbFRpbWVvdXQpIHtcbiAgICAgIGNsZWFyVGltZW91dChpbnRlbnRTdGF0ZS5zdHJlYW1SZWFkZXJDYW5jZWxUaW1lb3V0KTtcbiAgICAgIGludGVudFN0YXRlLnN0cmVhbVJlYWRlckNhbmNlbFRpbWVvdXQgPSBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IGNhbnZhc0ZhY3RvcnlJbnN0YW5jZSA9IGNhbnZhc0ZhY3RvcnkgfHwgbmV3IERlZmF1bHRDYW52YXNGYWN0b3J5KHtcbiAgICAgIG93bmVyRG9jdW1lbnQ6IHRoaXMuX293bmVyRG9jdW1lbnRcbiAgICB9KTtcbiAgICBjb25zdCBpbnRlbnRQcmludCA9ICEhKGludGVudEFyZ3MucmVuZGVyaW5nSW50ZW50ICYgX3V0aWwuUmVuZGVyaW5nSW50ZW50RmxhZy5QUklOVCk7XG5cbiAgICBpZiAoIWludGVudFN0YXRlLmRpc3BsYXlSZWFkeUNhcGFiaWxpdHkpIHtcbiAgICAgIGludGVudFN0YXRlLmRpc3BsYXlSZWFkeUNhcGFiaWxpdHkgPSAoMCwgX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkpKCk7XG4gICAgICBpbnRlbnRTdGF0ZS5vcGVyYXRvckxpc3QgPSB7XG4gICAgICAgIGZuQXJyYXk6IFtdLFxuICAgICAgICBhcmdzQXJyYXk6IFtdLFxuICAgICAgICBsYXN0Q2h1bms6IGZhbHNlXG4gICAgICB9O1xuXG4gICAgICBpZiAodGhpcy5fc3RhdHMpIHtcbiAgICAgICAgdGhpcy5fc3RhdHMudGltZShcIlBhZ2UgUmVxdWVzdFwiKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fcHVtcE9wZXJhdG9yTGlzdChpbnRlbnRBcmdzKTtcbiAgICB9XG5cbiAgICBjb25zdCBjb21wbGV0ZSA9IGVycm9yID0+IHtcbiAgICAgIGludGVudFN0YXRlLnJlbmRlclRhc2tzLmRlbGV0ZShpbnRlcm5hbFJlbmRlclRhc2spO1xuXG4gICAgICBpZiAodGhpcy5jbGVhbnVwQWZ0ZXJSZW5kZXIgfHwgaW50ZW50UHJpbnQpIHtcbiAgICAgICAgdGhpcy5wZW5kaW5nQ2xlYW51cCA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3RyeUNsZWFudXAoKTtcblxuICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgIGludGVybmFsUmVuZGVyVGFzay5jYXBhYmlsaXR5LnJlamVjdChlcnJvcik7XG5cbiAgICAgICAgdGhpcy5fYWJvcnRPcGVyYXRvckxpc3Qoe1xuICAgICAgICAgIGludGVudFN0YXRlLFxuICAgICAgICAgIHJlYXNvbjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKGVycm9yKVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGludGVybmFsUmVuZGVyVGFzay5jYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuX3N0YXRzKSB7XG4gICAgICAgIHRoaXMuX3N0YXRzLnRpbWVFbmQoXCJSZW5kZXJpbmdcIik7XG5cbiAgICAgICAgdGhpcy5fc3RhdHMudGltZUVuZChcIk92ZXJhbGxcIik7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0IGludGVybmFsUmVuZGVyVGFzayA9IG5ldyBJbnRlcm5hbFJlbmRlclRhc2soe1xuICAgICAgY2FsbGJhY2s6IGNvbXBsZXRlLFxuICAgICAgcGFyYW1zOiB7XG4gICAgICAgIGNhbnZhc0NvbnRleHQsXG4gICAgICAgIHZpZXdwb3J0LFxuICAgICAgICB0cmFuc2Zvcm0sXG4gICAgICAgIGltYWdlTGF5ZXIsXG4gICAgICAgIGJhY2tncm91bmRcbiAgICAgIH0sXG4gICAgICBvYmpzOiB0aGlzLm9ianMsXG4gICAgICBjb21tb25PYmpzOiB0aGlzLmNvbW1vbk9ianMsXG4gICAgICBhbm5vdGF0aW9uQ2FudmFzTWFwLFxuICAgICAgb3BlcmF0b3JMaXN0OiBpbnRlbnRTdGF0ZS5vcGVyYXRvckxpc3QsXG4gICAgICBwYWdlSW5kZXg6IHRoaXMuX3BhZ2VJbmRleCxcbiAgICAgIGNhbnZhc0ZhY3Rvcnk6IGNhbnZhc0ZhY3RvcnlJbnN0YW5jZSxcbiAgICAgIHVzZVJlcXVlc3RBbmltYXRpb25GcmFtZTogIWludGVudFByaW50LFxuICAgICAgcGRmQnVnOiB0aGlzLl9wZGZCdWcsXG4gICAgICBwYWdlQ29sb3JzXG4gICAgfSk7XG4gICAgKGludGVudFN0YXRlLnJlbmRlclRhc2tzIHx8PSBuZXcgU2V0KCkpLmFkZChpbnRlcm5hbFJlbmRlclRhc2spO1xuICAgIGNvbnN0IHJlbmRlclRhc2sgPSBpbnRlcm5hbFJlbmRlclRhc2sudGFzaztcbiAgICBQcm9taXNlLmFsbChbaW50ZW50U3RhdGUuZGlzcGxheVJlYWR5Q2FwYWJpbGl0eS5wcm9taXNlLCBvcHRpb25hbENvbnRlbnRDb25maWdQcm9taXNlXSkudGhlbigoW3RyYW5zcGFyZW5jeSwgb3B0aW9uYWxDb250ZW50Q29uZmlnXSkgPT4ge1xuICAgICAgaWYgKHRoaXMucGVuZGluZ0NsZWFudXApIHtcbiAgICAgICAgY29tcGxldGUoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5fc3RhdHMpIHtcbiAgICAgICAgdGhpcy5fc3RhdHMudGltZShcIlJlbmRlcmluZ1wiKTtcbiAgICAgIH1cblxuICAgICAgaW50ZXJuYWxSZW5kZXJUYXNrLmluaXRpYWxpemVHcmFwaGljcyh7XG4gICAgICAgIHRyYW5zcGFyZW5jeSxcbiAgICAgICAgb3B0aW9uYWxDb250ZW50Q29uZmlnXG4gICAgICB9KTtcbiAgICAgIGludGVybmFsUmVuZGVyVGFzay5vcGVyYXRvckxpc3RDaGFuZ2VkKCk7XG4gICAgfSkuY2F0Y2goY29tcGxldGUpO1xuICAgIHJldHVybiByZW5kZXJUYXNrO1xuICB9XG5cbiAgZ2V0T3BlcmF0b3JMaXN0KHtcbiAgICBpbnRlbnQgPSBcImRpc3BsYXlcIixcbiAgICBhbm5vdGF0aW9uTW9kZSA9IF91dGlsLkFubm90YXRpb25Nb2RlLkVOQUJMRVxuICB9ID0ge30pIHtcbiAgICBmdW5jdGlvbiBvcGVyYXRvckxpc3RDaGFuZ2VkKCkge1xuICAgICAgaWYgKGludGVudFN0YXRlLm9wZXJhdG9yTGlzdC5sYXN0Q2h1bmspIHtcbiAgICAgICAgaW50ZW50U3RhdGUub3BMaXN0UmVhZENhcGFiaWxpdHkucmVzb2x2ZShpbnRlbnRTdGF0ZS5vcGVyYXRvckxpc3QpO1xuICAgICAgICBpbnRlbnRTdGF0ZS5yZW5kZXJUYXNrcy5kZWxldGUob3BMaXN0VGFzayk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgaW50ZW50QXJncyA9IHRoaXMuX3RyYW5zcG9ydC5nZXRSZW5kZXJpbmdJbnRlbnQoaW50ZW50LCBhbm5vdGF0aW9uTW9kZSwgdHJ1ZSk7XG5cbiAgICBsZXQgaW50ZW50U3RhdGUgPSB0aGlzLl9pbnRlbnRTdGF0ZXMuZ2V0KGludGVudEFyZ3MuY2FjaGVLZXkpO1xuXG4gICAgaWYgKCFpbnRlbnRTdGF0ZSkge1xuICAgICAgaW50ZW50U3RhdGUgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4gICAgICB0aGlzLl9pbnRlbnRTdGF0ZXMuc2V0KGludGVudEFyZ3MuY2FjaGVLZXksIGludGVudFN0YXRlKTtcbiAgICB9XG5cbiAgICBsZXQgb3BMaXN0VGFzaztcblxuICAgIGlmICghaW50ZW50U3RhdGUub3BMaXN0UmVhZENhcGFiaWxpdHkpIHtcbiAgICAgIG9wTGlzdFRhc2sgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgb3BMaXN0VGFzay5vcGVyYXRvckxpc3RDaGFuZ2VkID0gb3BlcmF0b3JMaXN0Q2hhbmdlZDtcbiAgICAgIGludGVudFN0YXRlLm9wTGlzdFJlYWRDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgICAgKGludGVudFN0YXRlLnJlbmRlclRhc2tzIHx8PSBuZXcgU2V0KCkpLmFkZChvcExpc3RUYXNrKTtcbiAgICAgIGludGVudFN0YXRlLm9wZXJhdG9yTGlzdCA9IHtcbiAgICAgICAgZm5BcnJheTogW10sXG4gICAgICAgIGFyZ3NBcnJheTogW10sXG4gICAgICAgIGxhc3RDaHVuazogZmFsc2VcbiAgICAgIH07XG5cbiAgICAgIGlmICh0aGlzLl9zdGF0cykge1xuICAgICAgICB0aGlzLl9zdGF0cy50aW1lKFwiUGFnZSBSZXF1ZXN0XCIpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9wdW1wT3BlcmF0b3JMaXN0KGludGVudEFyZ3MpO1xuICAgIH1cblxuICAgIHJldHVybiBpbnRlbnRTdGF0ZS5vcExpc3RSZWFkQ2FwYWJpbGl0eS5wcm9taXNlO1xuICB9XG5cbiAgc3RyZWFtVGV4dENvbnRlbnQoe1xuICAgIGRpc2FibGVDb21iaW5lVGV4dEl0ZW1zID0gZmFsc2UsXG4gICAgaW5jbHVkZU1hcmtlZENvbnRlbnQgPSBmYWxzZVxuICB9ID0ge30pIHtcbiAgICBjb25zdCBURVhUX0NPTlRFTlRfQ0hVTktfU0laRSA9IDEwMDtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0Lm1lc3NhZ2VIYW5kbGVyLnNlbmRXaXRoU3RyZWFtKFwiR2V0VGV4dENvbnRlbnRcIiwge1xuICAgICAgcGFnZUluZGV4OiB0aGlzLl9wYWdlSW5kZXgsXG4gICAgICBjb21iaW5lVGV4dEl0ZW1zOiBkaXNhYmxlQ29tYmluZVRleHRJdGVtcyAhPT0gdHJ1ZSxcbiAgICAgIGluY2x1ZGVNYXJrZWRDb250ZW50OiBpbmNsdWRlTWFya2VkQ29udGVudCA9PT0gdHJ1ZVxuICAgIH0sIHtcbiAgICAgIGhpZ2hXYXRlck1hcms6IFRFWFRfQ09OVEVOVF9DSFVOS19TSVpFLFxuXG4gICAgICBzaXplKHRleHRDb250ZW50KSB7XG4gICAgICAgIHJldHVybiB0ZXh0Q29udGVudC5pdGVtcy5sZW5ndGg7XG4gICAgICB9XG5cbiAgICB9KTtcbiAgfVxuXG4gIGdldFRleHRDb250ZW50KHBhcmFtcyA9IHt9KSB7XG4gICAgaWYgKHRoaXMuX3RyYW5zcG9ydC5faHRtbEZvclhmYSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0WGZhKCkudGhlbih4ZmEgPT4ge1xuICAgICAgICByZXR1cm4gX3hmYV90ZXh0LlhmYVRleHQudGV4dENvbnRlbnQoeGZhKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IHJlYWRhYmxlU3RyZWFtID0gdGhpcy5zdHJlYW1UZXh0Q29udGVudChwYXJhbXMpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBmdW5jdGlvbiBwdW1wKCkge1xuICAgICAgICByZWFkZXIucmVhZCgpLnRoZW4oZnVuY3Rpb24gKHtcbiAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICBkb25lXG4gICAgICAgIH0pIHtcbiAgICAgICAgICBpZiAoZG9uZSkge1xuICAgICAgICAgICAgcmVzb2x2ZSh0ZXh0Q29udGVudCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgT2JqZWN0LmFzc2lnbih0ZXh0Q29udGVudC5zdHlsZXMsIHZhbHVlLnN0eWxlcyk7XG4gICAgICAgICAgdGV4dENvbnRlbnQuaXRlbXMucHVzaCguLi52YWx1ZS5pdGVtcyk7XG4gICAgICAgICAgcHVtcCgpO1xuICAgICAgICB9LCByZWplY3QpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZWFkZXIgPSByZWFkYWJsZVN0cmVhbS5nZXRSZWFkZXIoKTtcbiAgICAgIGNvbnN0IHRleHRDb250ZW50ID0ge1xuICAgICAgICBpdGVtczogW10sXG4gICAgICAgIHN0eWxlczogT2JqZWN0LmNyZWF0ZShudWxsKVxuICAgICAgfTtcbiAgICAgIHB1bXAoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldFN0cnVjdFRyZWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0cnVjdFRyZWVQcm9taXNlIHx8PSB0aGlzLl90cmFuc3BvcnQuZ2V0U3RydWN0VHJlZSh0aGlzLl9wYWdlSW5kZXgpO1xuICB9XG5cbiAgX2Rlc3Ryb3koKSB7XG4gICAgdGhpcy5kZXN0cm95ZWQgPSB0cnVlO1xuICAgIGNvbnN0IHdhaXRPbiA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBpbnRlbnRTdGF0ZSBvZiB0aGlzLl9pbnRlbnRTdGF0ZXMudmFsdWVzKCkpIHtcbiAgICAgIHRoaXMuX2Fib3J0T3BlcmF0b3JMaXN0KHtcbiAgICAgICAgaW50ZW50U3RhdGUsXG4gICAgICAgIHJlYXNvbjogbmV3IEVycm9yKFwiUGFnZSB3YXMgZGVzdHJveWVkLlwiKSxcbiAgICAgICAgZm9yY2U6IHRydWVcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoaW50ZW50U3RhdGUub3BMaXN0UmVhZENhcGFiaWxpdHkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgaW50ZXJuYWxSZW5kZXJUYXNrIG9mIGludGVudFN0YXRlLnJlbmRlclRhc2tzKSB7XG4gICAgICAgIHdhaXRPbi5wdXNoKGludGVybmFsUmVuZGVyVGFzay5jb21wbGV0ZWQpO1xuICAgICAgICBpbnRlcm5hbFJlbmRlclRhc2suY2FuY2VsKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5vYmpzLmNsZWFyKCk7XG5cbiAgICBmb3IgKGNvbnN0IGJpdG1hcCBvZiB0aGlzLl9iaXRtYXBzKSB7XG4gICAgICBiaXRtYXAuY2xvc2UoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9iaXRtYXBzLmNsZWFyKCk7XG5cbiAgICB0aGlzLl9hbm5vdGF0aW9uUHJvbWlzZXMuY2xlYXIoKTtcblxuICAgIHRoaXMuX2pzQWN0aW9uc1Byb21pc2UgPSBudWxsO1xuICAgIHRoaXMuX3N0cnVjdFRyZWVQcm9taXNlID0gbnVsbDtcbiAgICB0aGlzLnBlbmRpbmdDbGVhbnVwID0gZmFsc2U7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKHdhaXRPbik7XG4gIH1cblxuICBjbGVhbnVwKHJlc2V0U3RhdHMgPSBmYWxzZSkge1xuICAgIHRoaXMucGVuZGluZ0NsZWFudXAgPSB0cnVlO1xuICAgIHJldHVybiB0aGlzLl90cnlDbGVhbnVwKHJlc2V0U3RhdHMpO1xuICB9XG5cbiAgX3RyeUNsZWFudXAocmVzZXRTdGF0cyA9IGZhbHNlKSB7XG4gICAgaWYgKCF0aGlzLnBlbmRpbmdDbGVhbnVwKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCB7XG4gICAgICByZW5kZXJUYXNrcyxcbiAgICAgIG9wZXJhdG9yTGlzdFxuICAgIH0gb2YgdGhpcy5faW50ZW50U3RhdGVzLnZhbHVlcygpKSB7XG4gICAgICBpZiAocmVuZGVyVGFza3Muc2l6ZSA+IDAgfHwgIW9wZXJhdG9yTGlzdC5sYXN0Q2h1bmspIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX2ludGVudFN0YXRlcy5jbGVhcigpO1xuXG4gICAgdGhpcy5vYmpzLmNsZWFyKCk7XG5cbiAgICB0aGlzLl9hbm5vdGF0aW9uUHJvbWlzZXMuY2xlYXIoKTtcblxuICAgIHRoaXMuX2pzQWN0aW9uc1Byb21pc2UgPSBudWxsO1xuICAgIHRoaXMuX3N0cnVjdFRyZWVQcm9taXNlID0gbnVsbDtcblxuICAgIGlmIChyZXNldFN0YXRzICYmIHRoaXMuX3N0YXRzKSB7XG4gICAgICB0aGlzLl9zdGF0cyA9IG5ldyBfZGlzcGxheV91dGlscy5TdGF0VGltZXIoKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGJpdG1hcCBvZiB0aGlzLl9iaXRtYXBzKSB7XG4gICAgICBiaXRtYXAuY2xvc2UoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9iaXRtYXBzLmNsZWFyKCk7XG5cbiAgICB0aGlzLnBlbmRpbmdDbGVhbnVwID0gZmFsc2U7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBfc3RhcnRSZW5kZXJQYWdlKHRyYW5zcGFyZW5jeSwgY2FjaGVLZXkpIHtcbiAgICBjb25zdCBpbnRlbnRTdGF0ZSA9IHRoaXMuX2ludGVudFN0YXRlcy5nZXQoY2FjaGVLZXkpO1xuXG4gICAgaWYgKCFpbnRlbnRTdGF0ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9zdGF0cykge1xuICAgICAgdGhpcy5fc3RhdHMudGltZUVuZChcIlBhZ2UgUmVxdWVzdFwiKTtcbiAgICB9XG5cbiAgICBpZiAoaW50ZW50U3RhdGUuZGlzcGxheVJlYWR5Q2FwYWJpbGl0eSkge1xuICAgICAgaW50ZW50U3RhdGUuZGlzcGxheVJlYWR5Q2FwYWJpbGl0eS5yZXNvbHZlKHRyYW5zcGFyZW5jeSk7XG4gICAgfVxuICB9XG5cbiAgX3JlbmRlclBhZ2VDaHVuayhvcGVyYXRvckxpc3RDaHVuaywgaW50ZW50U3RhdGUpIHtcbiAgICBmb3IgKGxldCBpID0gMCwgaWkgPSBvcGVyYXRvckxpc3RDaHVuay5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICBpbnRlbnRTdGF0ZS5vcGVyYXRvckxpc3QuZm5BcnJheS5wdXNoKG9wZXJhdG9yTGlzdENodW5rLmZuQXJyYXlbaV0pO1xuICAgICAgaW50ZW50U3RhdGUub3BlcmF0b3JMaXN0LmFyZ3NBcnJheS5wdXNoKG9wZXJhdG9yTGlzdENodW5rLmFyZ3NBcnJheVtpXSk7XG4gICAgfVxuXG4gICAgaW50ZW50U3RhdGUub3BlcmF0b3JMaXN0Lmxhc3RDaHVuayA9IG9wZXJhdG9yTGlzdENodW5rLmxhc3RDaHVuaztcblxuICAgIGZvciAoY29uc3QgaW50ZXJuYWxSZW5kZXJUYXNrIG9mIGludGVudFN0YXRlLnJlbmRlclRhc2tzKSB7XG4gICAgICBpbnRlcm5hbFJlbmRlclRhc2sub3BlcmF0b3JMaXN0Q2hhbmdlZCgpO1xuICAgIH1cblxuICAgIGlmIChvcGVyYXRvckxpc3RDaHVuay5sYXN0Q2h1bmspIHtcbiAgICAgIHRoaXMuX3RyeUNsZWFudXAoKTtcbiAgICB9XG4gIH1cblxuICBfcHVtcE9wZXJhdG9yTGlzdCh7XG4gICAgcmVuZGVyaW5nSW50ZW50LFxuICAgIGNhY2hlS2V5XG4gIH0pIHtcbiAgICBjb25zdCByZWFkYWJsZVN0cmVhbSA9IHRoaXMuX3RyYW5zcG9ydC5tZXNzYWdlSGFuZGxlci5zZW5kV2l0aFN0cmVhbShcIkdldE9wZXJhdG9yTGlzdFwiLCB7XG4gICAgICBwYWdlSW5kZXg6IHRoaXMuX3BhZ2VJbmRleCxcbiAgICAgIGludGVudDogcmVuZGVyaW5nSW50ZW50LFxuICAgICAgY2FjaGVLZXksXG4gICAgICBhbm5vdGF0aW9uU3RvcmFnZTogcmVuZGVyaW5nSW50ZW50ICYgX3V0aWwuUmVuZGVyaW5nSW50ZW50RmxhZy5BTk5PVEFUSU9OU19TVE9SQUdFID8gdGhpcy5fdHJhbnNwb3J0LmFubm90YXRpb25TdG9yYWdlLnNlcmlhbGl6YWJsZSA6IG51bGxcbiAgICB9KTtcblxuICAgIGNvbnN0IHJlYWRlciA9IHJlYWRhYmxlU3RyZWFtLmdldFJlYWRlcigpO1xuXG4gICAgY29uc3QgaW50ZW50U3RhdGUgPSB0aGlzLl9pbnRlbnRTdGF0ZXMuZ2V0KGNhY2hlS2V5KTtcblxuICAgIGludGVudFN0YXRlLnN0cmVhbVJlYWRlciA9IHJlYWRlcjtcblxuICAgIGNvbnN0IHB1bXAgPSAoKSA9PiB7XG4gICAgICByZWFkZXIucmVhZCgpLnRoZW4oKHtcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIGRvbmVcbiAgICAgIH0pID0+IHtcbiAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICBpbnRlbnRTdGF0ZS5zdHJlYW1SZWFkZXIgPSBudWxsO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl90cmFuc3BvcnQuZGVzdHJveWVkKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fcmVuZGVyUGFnZUNodW5rKHZhbHVlLCBpbnRlbnRTdGF0ZSk7XG5cbiAgICAgICAgcHVtcCgpO1xuICAgICAgfSwgcmVhc29uID0+IHtcbiAgICAgICAgaW50ZW50U3RhdGUuc3RyZWFtUmVhZGVyID0gbnVsbDtcblxuICAgICAgICBpZiAodGhpcy5fdHJhbnNwb3J0LmRlc3Ryb3llZCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbnRlbnRTdGF0ZS5vcGVyYXRvckxpc3QpIHtcbiAgICAgICAgICBpbnRlbnRTdGF0ZS5vcGVyYXRvckxpc3QubGFzdENodW5rID0gdHJ1ZTtcblxuICAgICAgICAgIGZvciAoY29uc3QgaW50ZXJuYWxSZW5kZXJUYXNrIG9mIGludGVudFN0YXRlLnJlbmRlclRhc2tzKSB7XG4gICAgICAgICAgICBpbnRlcm5hbFJlbmRlclRhc2sub3BlcmF0b3JMaXN0Q2hhbmdlZCgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuX3RyeUNsZWFudXAoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbnRlbnRTdGF0ZS5kaXNwbGF5UmVhZHlDYXBhYmlsaXR5KSB7XG4gICAgICAgICAgaW50ZW50U3RhdGUuZGlzcGxheVJlYWR5Q2FwYWJpbGl0eS5yZWplY3QocmVhc29uKTtcbiAgICAgICAgfSBlbHNlIGlmIChpbnRlbnRTdGF0ZS5vcExpc3RSZWFkQ2FwYWJpbGl0eSkge1xuICAgICAgICAgIGludGVudFN0YXRlLm9wTGlzdFJlYWRDYXBhYmlsaXR5LnJlamVjdChyZWFzb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IHJlYXNvbjtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIHB1bXAoKTtcbiAgfVxuXG4gIF9hYm9ydE9wZXJhdG9yTGlzdCh7XG4gICAgaW50ZW50U3RhdGUsXG4gICAgcmVhc29uLFxuICAgIGZvcmNlID0gZmFsc2VcbiAgfSkge1xuICAgIGlmICghaW50ZW50U3RhdGUuc3RyZWFtUmVhZGVyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFmb3JjZSkge1xuICAgICAgaWYgKGludGVudFN0YXRlLnJlbmRlclRhc2tzLnNpemUgPiAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlYXNvbiBpbnN0YW5jZW9mIF9kaXNwbGF5X3V0aWxzLlJlbmRlcmluZ0NhbmNlbGxlZEV4Y2VwdGlvbikge1xuICAgICAgICBpbnRlbnRTdGF0ZS5zdHJlYW1SZWFkZXJDYW5jZWxUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5fYWJvcnRPcGVyYXRvckxpc3Qoe1xuICAgICAgICAgICAgaW50ZW50U3RhdGUsXG4gICAgICAgICAgICByZWFzb24sXG4gICAgICAgICAgICBmb3JjZTogdHJ1ZVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaW50ZW50U3RhdGUuc3RyZWFtUmVhZGVyQ2FuY2VsVGltZW91dCA9IG51bGw7XG4gICAgICAgIH0sIFJFTkRFUklOR19DQU5DRUxMRURfVElNRU9VVCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpbnRlbnRTdGF0ZS5zdHJlYW1SZWFkZXIuY2FuY2VsKG5ldyBfdXRpbC5BYm9ydEV4Y2VwdGlvbihyZWFzb24ubWVzc2FnZSkpLmNhdGNoKCgpID0+IHt9KTtcbiAgICBpbnRlbnRTdGF0ZS5zdHJlYW1SZWFkZXIgPSBudWxsO1xuXG4gICAgaWYgKHRoaXMuX3RyYW5zcG9ydC5kZXN0cm95ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IFtjdXJDYWNoZUtleSwgY3VySW50ZW50U3RhdGVdIG9mIHRoaXMuX2ludGVudFN0YXRlcykge1xuICAgICAgaWYgKGN1ckludGVudFN0YXRlID09PSBpbnRlbnRTdGF0ZSkge1xuICAgICAgICB0aGlzLl9pbnRlbnRTdGF0ZXMuZGVsZXRlKGN1ckNhY2hlS2V5KTtcblxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmNsZWFudXAoKTtcbiAgfVxuXG4gIGdldCBzdGF0cygpIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdHM7XG4gIH1cblxufVxuXG5leHBvcnRzLlBERlBhZ2VQcm94eSA9IFBERlBhZ2VQcm94eTtcblxuY2xhc3MgTG9vcGJhY2tQb3J0IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5fbGlzdGVuZXJzID0gW107XG4gICAgdGhpcy5fZGVmZXJyZWQgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIHBvc3RNZXNzYWdlKG9iaiwgdHJhbnNmZXJzKSB7XG4gICAgY29uc3QgZXZlbnQgPSB7XG4gICAgICBkYXRhOiBzdHJ1Y3R1cmVkQ2xvbmUob2JqLCB0cmFuc2ZlcnMpXG4gICAgfTtcblxuICAgIHRoaXMuX2RlZmVycmVkLnRoZW4oKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBsaXN0ZW5lciBvZiB0aGlzLl9saXN0ZW5lcnMpIHtcbiAgICAgICAgbGlzdGVuZXIuY2FsbCh0aGlzLCBldmVudCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBhZGRFdmVudExpc3RlbmVyKG5hbWUsIGxpc3RlbmVyKSB7XG4gICAgdGhpcy5fbGlzdGVuZXJzLnB1c2gobGlzdGVuZXIpO1xuICB9XG5cbiAgcmVtb3ZlRXZlbnRMaXN0ZW5lcihuYW1lLCBsaXN0ZW5lcikge1xuICAgIGNvbnN0IGkgPSB0aGlzLl9saXN0ZW5lcnMuaW5kZXhPZihsaXN0ZW5lcik7XG5cbiAgICB0aGlzLl9saXN0ZW5lcnMuc3BsaWNlKGksIDEpO1xuICB9XG5cbiAgdGVybWluYXRlKCkge1xuICAgIHRoaXMuX2xpc3RlbmVycy5sZW5ndGggPSAwO1xuICB9XG5cbn1cblxuZXhwb3J0cy5Mb29wYmFja1BvcnQgPSBMb29wYmFja1BvcnQ7XG5jb25zdCBQREZXb3JrZXJVdGlsID0ge1xuICBpc1dvcmtlckRpc2FibGVkOiBmYWxzZSxcbiAgZmFsbGJhY2tXb3JrZXJTcmM6IG51bGwsXG4gIGZha2VXb3JrZXJJZDogMFxufTtcbmV4cG9ydHMuUERGV29ya2VyVXRpbCA9IFBERldvcmtlclV0aWw7XG57XG4gIGlmIChfaXNfbm9kZS5pc05vZGVKUyAmJiB0eXBlb2YgcmVxdWlyZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgUERGV29ya2VyVXRpbC5pc1dvcmtlckRpc2FibGVkID0gdHJ1ZTtcbiAgICBQREZXb3JrZXJVdGlsLmZhbGxiYWNrV29ya2VyU3JjID0gXCIuL3BkZi53b3JrZXIuanNcIjtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09IFwib2JqZWN0XCIpIHtcbiAgICBjb25zdCBwZGZqc0ZpbGVQYXRoID0gZG9jdW1lbnQ/LmN1cnJlbnRTY3JpcHQ/LnNyYztcblxuICAgIGlmIChwZGZqc0ZpbGVQYXRoKSB7XG4gICAgICBQREZXb3JrZXJVdGlsLmZhbGxiYWNrV29ya2VyU3JjID0gcGRmanNGaWxlUGF0aC5yZXBsYWNlKC8oXFwuKD86bWluXFwuKT9qcykoXFw/LiopPyQvaSwgXCIud29ya2VyJDEkMlwiKTtcbiAgICB9XG4gIH1cblxuICBQREZXb3JrZXJVdGlsLmlzU2FtZU9yaWdpbiA9IGZ1bmN0aW9uIChiYXNlVXJsLCBvdGhlclVybCkge1xuICAgIGxldCBiYXNlO1xuXG4gICAgdHJ5IHtcbiAgICAgIGJhc2UgPSBuZXcgVVJMKGJhc2VVcmwpO1xuXG4gICAgICBpZiAoIWJhc2Uub3JpZ2luIHx8IGJhc2Uub3JpZ2luID09PSBcIm51bGxcIikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IG90aGVyID0gbmV3IFVSTChvdGhlclVybCwgYmFzZSk7XG4gICAgcmV0dXJuIGJhc2Uub3JpZ2luID09PSBvdGhlci5vcmlnaW47XG4gIH07XG5cbiAgUERGV29ya2VyVXRpbC5jcmVhdGVDRE5XcmFwcGVyID0gZnVuY3Rpb24gKHVybCkge1xuICAgIGNvbnN0IHdyYXBwZXIgPSBgaW1wb3J0U2NyaXB0cyhcIiR7dXJsfVwiKTtgO1xuICAgIHJldHVybiBVUkwuY3JlYXRlT2JqZWN0VVJMKG5ldyBCbG9iKFt3cmFwcGVyXSkpO1xuICB9O1xufVxuXG5jbGFzcyBQREZXb3JrZXIge1xuICBzdGF0aWMgI3dvcmtlclBvcnRzID0gbmV3IFdlYWtNYXAoKTtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgbmFtZSA9IG51bGwsXG4gICAgcG9ydCA9IG51bGwsXG4gICAgdmVyYm9zaXR5ID0gKDAsIF91dGlsLmdldFZlcmJvc2l0eUxldmVsKSgpXG4gIH0gPSB7fSkge1xuICAgIGlmIChwb3J0ICYmIFBERldvcmtlci4jd29ya2VyUG9ydHMuaGFzKHBvcnQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgdXNlIG1vcmUgdGhhbiBvbmUgUERGV29ya2VyIHBlciBwb3J0LlwiKTtcbiAgICB9XG5cbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIHRoaXMuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgdGhpcy52ZXJib3NpdHkgPSB2ZXJib3NpdHk7XG4gICAgdGhpcy5fcmVhZHlDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgIHRoaXMuX3BvcnQgPSBudWxsO1xuICAgIHRoaXMuX3dlYldvcmtlciA9IG51bGw7XG4gICAgdGhpcy5fbWVzc2FnZUhhbmRsZXIgPSBudWxsO1xuXG4gICAgaWYgKHBvcnQpIHtcbiAgICAgIFBERldvcmtlci4jd29ya2VyUG9ydHMuc2V0KHBvcnQsIHRoaXMpO1xuXG4gICAgICB0aGlzLl9pbml0aWFsaXplRnJvbVBvcnQocG9ydCk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9pbml0aWFsaXplKCk7XG4gIH1cblxuICBnZXQgcHJvbWlzZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fcmVhZHlDYXBhYmlsaXR5LnByb21pc2U7XG4gIH1cblxuICBnZXQgcG9ydCgpIHtcbiAgICByZXR1cm4gdGhpcy5fcG9ydDtcbiAgfVxuXG4gIGdldCBtZXNzYWdlSGFuZGxlcigpIHtcbiAgICByZXR1cm4gdGhpcy5fbWVzc2FnZUhhbmRsZXI7XG4gIH1cblxuICBfaW5pdGlhbGl6ZUZyb21Qb3J0KHBvcnQpIHtcbiAgICB0aGlzLl9wb3J0ID0gcG9ydDtcbiAgICB0aGlzLl9tZXNzYWdlSGFuZGxlciA9IG5ldyBfbWVzc2FnZV9oYW5kbGVyLk1lc3NhZ2VIYW5kbGVyKFwibWFpblwiLCBcIndvcmtlclwiLCBwb3J0KTtcblxuICAgIHRoaXMuX21lc3NhZ2VIYW5kbGVyLm9uKFwicmVhZHlcIiwgZnVuY3Rpb24gKCkge30pO1xuXG4gICAgdGhpcy5fcmVhZHlDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgfVxuXG4gIF9pbml0aWFsaXplKCkge1xuICAgIGlmICh0eXBlb2YgV29ya2VyICE9PSBcInVuZGVmaW5lZFwiICYmICFQREZXb3JrZXJVdGlsLmlzV29ya2VyRGlzYWJsZWQgJiYgIVBERldvcmtlci5fbWFpblRocmVhZFdvcmtlck1lc3NhZ2VIYW5kbGVyKSB7XG4gICAgICBsZXQgd29ya2VyU3JjID0gUERGV29ya2VyLndvcmtlclNyYztcblxuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKCFQREZXb3JrZXJVdGlsLmlzU2FtZU9yaWdpbih3aW5kb3cubG9jYXRpb24uaHJlZiwgd29ya2VyU3JjKSkge1xuICAgICAgICAgIHdvcmtlclNyYyA9IFBERldvcmtlclV0aWwuY3JlYXRlQ0ROV3JhcHBlcihuZXcgVVJMKHdvcmtlclNyYywgd2luZG93LmxvY2F0aW9uKS5ocmVmKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHdvcmtlciA9IG5ldyBXb3JrZXIod29ya2VyU3JjKTtcbiAgICAgICAgY29uc3QgbWVzc2FnZUhhbmRsZXIgPSBuZXcgX21lc3NhZ2VfaGFuZGxlci5NZXNzYWdlSGFuZGxlcihcIm1haW5cIiwgXCJ3b3JrZXJcIiwgd29ya2VyKTtcblxuICAgICAgICBjb25zdCB0ZXJtaW5hdGVFYXJseSA9ICgpID0+IHtcbiAgICAgICAgICB3b3JrZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImVycm9yXCIsIG9uV29ya2VyRXJyb3IpO1xuICAgICAgICAgIG1lc3NhZ2VIYW5kbGVyLmRlc3Ryb3koKTtcbiAgICAgICAgICB3b3JrZXIudGVybWluYXRlKCk7XG5cbiAgICAgICAgICBpZiAodGhpcy5kZXN0cm95ZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3JlYWR5Q2FwYWJpbGl0eS5yZWplY3QobmV3IEVycm9yKFwiV29ya2VyIHdhcyBkZXN0cm95ZWRcIikpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9zZXR1cEZha2VXb3JrZXIoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3Qgb25Xb3JrZXJFcnJvciA9ICgpID0+IHtcbiAgICAgICAgICBpZiAoIXRoaXMuX3dlYldvcmtlcikge1xuICAgICAgICAgICAgdGVybWluYXRlRWFybHkoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgd29ya2VyLmFkZEV2ZW50TGlzdGVuZXIoXCJlcnJvclwiLCBvbldvcmtlckVycm9yKTtcbiAgICAgICAgbWVzc2FnZUhhbmRsZXIub24oXCJ0ZXN0XCIsIGRhdGEgPT4ge1xuICAgICAgICAgIHdvcmtlci5yZW1vdmVFdmVudExpc3RlbmVyKFwiZXJyb3JcIiwgb25Xb3JrZXJFcnJvcik7XG5cbiAgICAgICAgICBpZiAodGhpcy5kZXN0cm95ZWQpIHtcbiAgICAgICAgICAgIHRlcm1pbmF0ZUVhcmx5KCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICAgIHRoaXMuX21lc3NhZ2VIYW5kbGVyID0gbWVzc2FnZUhhbmRsZXI7XG4gICAgICAgICAgICB0aGlzLl9wb3J0ID0gd29ya2VyO1xuICAgICAgICAgICAgdGhpcy5fd2ViV29ya2VyID0gd29ya2VyO1xuXG4gICAgICAgICAgICB0aGlzLl9yZWFkeUNhcGFiaWxpdHkucmVzb2x2ZSgpO1xuXG4gICAgICAgICAgICBtZXNzYWdlSGFuZGxlci5zZW5kKFwiY29uZmlndXJlXCIsIHtcbiAgICAgICAgICAgICAgdmVyYm9zaXR5OiB0aGlzLnZlcmJvc2l0eVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3NldHVwRmFrZVdvcmtlcigpO1xuXG4gICAgICAgICAgICBtZXNzYWdlSGFuZGxlci5kZXN0cm95KCk7XG4gICAgICAgICAgICB3b3JrZXIudGVybWluYXRlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgbWVzc2FnZUhhbmRsZXIub24oXCJyZWFkeVwiLCBkYXRhID0+IHtcbiAgICAgICAgICB3b3JrZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImVycm9yXCIsIG9uV29ya2VyRXJyb3IpO1xuXG4gICAgICAgICAgaWYgKHRoaXMuZGVzdHJveWVkKSB7XG4gICAgICAgICAgICB0ZXJtaW5hdGVFYXJseSgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzZW5kVGVzdCgpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRoaXMuX3NldHVwRmFrZVdvcmtlcigpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qgc2VuZFRlc3QgPSAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgdGVzdE9iaiA9IG5ldyBVaW50OEFycmF5KCk7XG4gICAgICAgICAgbWVzc2FnZUhhbmRsZXIuc2VuZChcInRlc3RcIiwgdGVzdE9iaiwgW3Rlc3RPYmouYnVmZmVyXSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgc2VuZFRlc3QoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAoMCwgX3V0aWwuaW5mbykoXCJUaGUgd29ya2VyIGhhcyBiZWVuIGRpc2FibGVkLlwiKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9zZXR1cEZha2VXb3JrZXIoKTtcbiAgfVxuXG4gIF9zZXR1cEZha2VXb3JrZXIoKSB7XG4gICAgaWYgKCFQREZXb3JrZXJVdGlsLmlzV29ya2VyRGlzYWJsZWQpIHtcbiAgICAgICgwLCBfdXRpbC53YXJuKShcIlNldHRpbmcgdXAgZmFrZSB3b3JrZXIuXCIpO1xuICAgICAgUERGV29ya2VyVXRpbC5pc1dvcmtlckRpc2FibGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBQREZXb3JrZXIuX3NldHVwRmFrZVdvcmtlckdsb2JhbC50aGVuKFdvcmtlck1lc3NhZ2VIYW5kbGVyID0+IHtcbiAgICAgIGlmICh0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgICB0aGlzLl9yZWFkeUNhcGFiaWxpdHkucmVqZWN0KG5ldyBFcnJvcihcIldvcmtlciB3YXMgZGVzdHJveWVkXCIpKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBvcnQgPSBuZXcgTG9vcGJhY2tQb3J0KCk7XG4gICAgICB0aGlzLl9wb3J0ID0gcG9ydDtcbiAgICAgIGNvbnN0IGlkID0gYGZha2Uke1BERldvcmtlclV0aWwuZmFrZVdvcmtlcklkKyt9YDtcbiAgICAgIGNvbnN0IHdvcmtlckhhbmRsZXIgPSBuZXcgX21lc3NhZ2VfaGFuZGxlci5NZXNzYWdlSGFuZGxlcihpZCArIFwiX3dvcmtlclwiLCBpZCwgcG9ydCk7XG4gICAgICBXb3JrZXJNZXNzYWdlSGFuZGxlci5zZXR1cCh3b3JrZXJIYW5kbGVyLCBwb3J0KTtcbiAgICAgIGNvbnN0IG1lc3NhZ2VIYW5kbGVyID0gbmV3IF9tZXNzYWdlX2hhbmRsZXIuTWVzc2FnZUhhbmRsZXIoaWQsIGlkICsgXCJfd29ya2VyXCIsIHBvcnQpO1xuICAgICAgdGhpcy5fbWVzc2FnZUhhbmRsZXIgPSBtZXNzYWdlSGFuZGxlcjtcblxuICAgICAgdGhpcy5fcmVhZHlDYXBhYmlsaXR5LnJlc29sdmUoKTtcblxuICAgICAgbWVzc2FnZUhhbmRsZXIuc2VuZChcImNvbmZpZ3VyZVwiLCB7XG4gICAgICAgIHZlcmJvc2l0eTogdGhpcy52ZXJib3NpdHlcbiAgICAgIH0pO1xuICAgIH0pLmNhdGNoKHJlYXNvbiA9PiB7XG4gICAgICB0aGlzLl9yZWFkeUNhcGFiaWxpdHkucmVqZWN0KG5ldyBFcnJvcihgU2V0dGluZyB1cCBmYWtlIHdvcmtlciBmYWlsZWQ6IFwiJHtyZWFzb24ubWVzc2FnZX1cIi5gKSk7XG4gICAgfSk7XG4gIH1cblxuICBkZXN0cm95KCkge1xuICAgIHRoaXMuZGVzdHJveWVkID0gdHJ1ZTtcblxuICAgIGlmICh0aGlzLl93ZWJXb3JrZXIpIHtcbiAgICAgIHRoaXMuX3dlYldvcmtlci50ZXJtaW5hdGUoKTtcblxuICAgICAgdGhpcy5fd2ViV29ya2VyID0gbnVsbDtcbiAgICB9XG5cbiAgICBQREZXb3JrZXIuI3dvcmtlclBvcnRzLmRlbGV0ZSh0aGlzLl9wb3J0KTtcbiAgICB0aGlzLl9wb3J0ID0gbnVsbDtcblxuICAgIGlmICh0aGlzLl9tZXNzYWdlSGFuZGxlcikge1xuICAgICAgdGhpcy5fbWVzc2FnZUhhbmRsZXIuZGVzdHJveSgpO1xuXG4gICAgICB0aGlzLl9tZXNzYWdlSGFuZGxlciA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGZyb21Qb3J0KHBhcmFtcykge1xuICAgIGlmICghcGFyYW1zPy5wb3J0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJQREZXb3JrZXIuZnJvbVBvcnQgLSBpbnZhbGlkIG1ldGhvZCBzaWduYXR1cmUuXCIpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLiN3b3JrZXJQb3J0cy5oYXMocGFyYW1zLnBvcnQpKSB7XG4gICAgICByZXR1cm4gdGhpcy4jd29ya2VyUG9ydHMuZ2V0KHBhcmFtcy5wb3J0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFBERldvcmtlcihwYXJhbXMpO1xuICB9XG5cbiAgc3RhdGljIGdldCB3b3JrZXJTcmMoKSB7XG4gICAgaWYgKF93b3JrZXJfb3B0aW9ucy5HbG9iYWxXb3JrZXJPcHRpb25zLndvcmtlclNyYykge1xuICAgICAgcmV0dXJuIF93b3JrZXJfb3B0aW9ucy5HbG9iYWxXb3JrZXJPcHRpb25zLndvcmtlclNyYztcbiAgICB9XG5cbiAgICBpZiAoUERGV29ya2VyVXRpbC5mYWxsYmFja1dvcmtlclNyYyAhPT0gbnVsbCkge1xuICAgICAgaWYgKCFfaXNfbm9kZS5pc05vZGVKUykge1xuICAgICAgICAoMCwgX2Rpc3BsYXlfdXRpbHMuZGVwcmVjYXRlZCkoJ05vIFwiR2xvYmFsV29ya2VyT3B0aW9ucy53b3JrZXJTcmNcIiBzcGVjaWZpZWQuJyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBQREZXb3JrZXJVdGlsLmZhbGxiYWNrV29ya2VyU3JjO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcignTm8gXCJHbG9iYWxXb3JrZXJPcHRpb25zLndvcmtlclNyY1wiIHNwZWNpZmllZC4nKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgX21haW5UaHJlYWRXb3JrZXJNZXNzYWdlSGFuZGxlcigpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGdsb2JhbFRoaXMucGRmanNXb3JrZXI/Lldvcmtlck1lc3NhZ2VIYW5kbGVyIHx8IG51bGw7XG4gICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBnZXQgX3NldHVwRmFrZVdvcmtlckdsb2JhbCgpIHtcbiAgICBjb25zdCBsb2FkZXIgPSBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBtYWluV29ya2VyTWVzc2FnZUhhbmRsZXIgPSB0aGlzLl9tYWluVGhyZWFkV29ya2VyTWVzc2FnZUhhbmRsZXI7XG5cbiAgICAgIGlmIChtYWluV29ya2VyTWVzc2FnZUhhbmRsZXIpIHtcbiAgICAgICAgcmV0dXJuIG1haW5Xb3JrZXJNZXNzYWdlSGFuZGxlcjtcbiAgICAgIH1cblxuICAgICAgaWYgKF9pc19ub2RlLmlzTm9kZUpTICYmIHR5cGVvZiByZXF1aXJlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgY29uc3Qgd29ya2VyID0gZXZhbChcInJlcXVpcmVcIikodGhpcy53b3JrZXJTcmMpO1xuICAgICAgICByZXR1cm4gd29ya2VyLldvcmtlck1lc3NhZ2VIYW5kbGVyO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCAoMCwgX2Rpc3BsYXlfdXRpbHMubG9hZFNjcmlwdCkodGhpcy53b3JrZXJTcmMpO1xuICAgICAgcmV0dXJuIHdpbmRvdy5wZGZqc1dvcmtlci5Xb3JrZXJNZXNzYWdlSGFuZGxlcjtcbiAgICB9O1xuXG4gICAgcmV0dXJuICgwLCBfdXRpbC5zaGFkb3cpKHRoaXMsIFwiX3NldHVwRmFrZVdvcmtlckdsb2JhbFwiLCBsb2FkZXIoKSk7XG4gIH1cblxufVxuXG5leHBvcnRzLlBERldvcmtlciA9IFBERldvcmtlcjtcbntcbiAgUERGV29ya2VyLmdldFdvcmtlclNyYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAoMCwgX2Rpc3BsYXlfdXRpbHMuZGVwcmVjYXRlZCkoXCJgUERGV29ya2VyLmdldFdvcmtlclNyYygpYCwgcGxlYXNlIHVzZSBgUERGV29ya2VyLndvcmtlclNyY2AgaW5zdGVhZC5cIik7XG4gICAgcmV0dXJuIHRoaXMud29ya2VyU3JjO1xuICB9O1xufVxuXG5jbGFzcyBXb3JrZXJUcmFuc3BvcnQge1xuICAjZG9jU3RhdHMgPSBudWxsO1xuICAjcGFnZUNhY2hlID0gbmV3IE1hcCgpO1xuICAjcGFnZVByb21pc2VzID0gbmV3IE1hcCgpO1xuICAjbWV0YWRhdGFQcm9taXNlID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcihtZXNzYWdlSGFuZGxlciwgbG9hZGluZ1Rhc2ssIG5ldHdvcmtTdHJlYW0sIHBhcmFtcykge1xuICAgIHRoaXMubWVzc2FnZUhhbmRsZXIgPSBtZXNzYWdlSGFuZGxlcjtcbiAgICB0aGlzLmxvYWRpbmdUYXNrID0gbG9hZGluZ1Rhc2s7XG4gICAgdGhpcy5jb21tb25PYmpzID0gbmV3IFBERk9iamVjdHMoKTtcbiAgICB0aGlzLmZvbnRMb2FkZXIgPSBuZXcgX2ZvbnRfbG9hZGVyLkZvbnRMb2FkZXIoe1xuICAgICAgZG9jSWQ6IGxvYWRpbmdUYXNrLmRvY0lkLFxuICAgICAgb25VbnN1cHBvcnRlZEZlYXR1cmU6IHRoaXMuX29uVW5zdXBwb3J0ZWRGZWF0dXJlLmJpbmQodGhpcyksXG4gICAgICBvd25lckRvY3VtZW50OiBwYXJhbXMub3duZXJEb2N1bWVudCxcbiAgICAgIHN0eWxlRWxlbWVudDogcGFyYW1zLnN0eWxlRWxlbWVudFxuICAgIH0pO1xuICAgIHRoaXMuX3BhcmFtcyA9IHBhcmFtcztcblxuICAgIGlmICghcGFyYW1zLnVzZVdvcmtlckZldGNoKSB7XG4gICAgICB0aGlzLkNNYXBSZWFkZXJGYWN0b3J5ID0gbmV3IHBhcmFtcy5DTWFwUmVhZGVyRmFjdG9yeSh7XG4gICAgICAgIGJhc2VVcmw6IHBhcmFtcy5jTWFwVXJsLFxuICAgICAgICBpc0NvbXByZXNzZWQ6IHBhcmFtcy5jTWFwUGFja2VkXG4gICAgICB9KTtcbiAgICAgIHRoaXMuU3RhbmRhcmRGb250RGF0YUZhY3RvcnkgPSBuZXcgcGFyYW1zLlN0YW5kYXJkRm9udERhdGFGYWN0b3J5KHtcbiAgICAgICAgYmFzZVVybDogcGFyYW1zLnN0YW5kYXJkRm9udERhdGFVcmxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgdGhpcy5kZXN0cm95Q2FwYWJpbGl0eSA9IG51bGw7XG4gICAgdGhpcy5fcGFzc3dvcmRDYXBhYmlsaXR5ID0gbnVsbDtcbiAgICB0aGlzLl9uZXR3b3JrU3RyZWFtID0gbmV0d29ya1N0cmVhbTtcbiAgICB0aGlzLl9mdWxsUmVhZGVyID0gbnVsbDtcbiAgICB0aGlzLl9sYXN0UHJvZ3Jlc3MgPSBudWxsO1xuICAgIHRoaXMuZG93bmxvYWRJbmZvQ2FwYWJpbGl0eSA9ICgwLCBfdXRpbC5jcmVhdGVQcm9taXNlQ2FwYWJpbGl0eSkoKTtcbiAgICB0aGlzLnNldHVwTWVzc2FnZUhhbmRsZXIoKTtcbiAgfVxuXG4gIGdldCBhbm5vdGF0aW9uU3RvcmFnZSgpIHtcbiAgICByZXR1cm4gKDAsIF91dGlsLnNoYWRvdykodGhpcywgXCJhbm5vdGF0aW9uU3RvcmFnZVwiLCBuZXcgX2Fubm90YXRpb25fc3RvcmFnZS5Bbm5vdGF0aW9uU3RvcmFnZSgpKTtcbiAgfVxuXG4gIGdldCBzdGF0cygpIHtcbiAgICByZXR1cm4gdGhpcy4jZG9jU3RhdHM7XG4gIH1cblxuICBnZXRSZW5kZXJpbmdJbnRlbnQoaW50ZW50LCBhbm5vdGF0aW9uTW9kZSA9IF91dGlsLkFubm90YXRpb25Nb2RlLkVOQUJMRSwgaXNPcExpc3QgPSBmYWxzZSkge1xuICAgIGxldCByZW5kZXJpbmdJbnRlbnQgPSBfdXRpbC5SZW5kZXJpbmdJbnRlbnRGbGFnLkRJU1BMQVk7XG4gICAgbGV0IGFubm90YXRpb25IYXNoID0gXCJcIjtcblxuICAgIHN3aXRjaCAoaW50ZW50KSB7XG4gICAgICBjYXNlIFwiYW55XCI6XG4gICAgICAgIHJlbmRlcmluZ0ludGVudCA9IF91dGlsLlJlbmRlcmluZ0ludGVudEZsYWcuQU5ZO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcImRpc3BsYXlcIjpcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgXCJwcmludFwiOlxuICAgICAgICByZW5kZXJpbmdJbnRlbnQgPSBfdXRpbC5SZW5kZXJpbmdJbnRlbnRGbGFnLlBSSU5UO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgKDAsIF91dGlsLndhcm4pKGBnZXRSZW5kZXJpbmdJbnRlbnQgLSBpbnZhbGlkIGludGVudDogJHtpbnRlbnR9YCk7XG4gICAgfVxuXG4gICAgc3dpdGNoIChhbm5vdGF0aW9uTW9kZSkge1xuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uTW9kZS5ESVNBQkxFOlxuICAgICAgICByZW5kZXJpbmdJbnRlbnQgKz0gX3V0aWwuUmVuZGVyaW5nSW50ZW50RmxhZy5BTk5PVEFUSU9OU19ESVNBQkxFO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uTW9kZS5FTkFCTEU6XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIF91dGlsLkFubm90YXRpb25Nb2RlLkVOQUJMRV9GT1JNUzpcbiAgICAgICAgcmVuZGVyaW5nSW50ZW50ICs9IF91dGlsLlJlbmRlcmluZ0ludGVudEZsYWcuQU5OT1RBVElPTlNfRk9STVM7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIF91dGlsLkFubm90YXRpb25Nb2RlLkVOQUJMRV9TVE9SQUdFOlxuICAgICAgICByZW5kZXJpbmdJbnRlbnQgKz0gX3V0aWwuUmVuZGVyaW5nSW50ZW50RmxhZy5BTk5PVEFUSU9OU19TVE9SQUdFO1xuICAgICAgICBhbm5vdGF0aW9uSGFzaCA9IHRoaXMuYW5ub3RhdGlvblN0b3JhZ2UuaGFzaDtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgICgwLCBfdXRpbC53YXJuKShgZ2V0UmVuZGVyaW5nSW50ZW50IC0gaW52YWxpZCBhbm5vdGF0aW9uTW9kZTogJHthbm5vdGF0aW9uTW9kZX1gKTtcbiAgICB9XG5cbiAgICBpZiAoaXNPcExpc3QpIHtcbiAgICAgIHJlbmRlcmluZ0ludGVudCArPSBfdXRpbC5SZW5kZXJpbmdJbnRlbnRGbGFnLk9QTElTVDtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcmVuZGVyaW5nSW50ZW50LFxuICAgICAgY2FjaGVLZXk6IGAke3JlbmRlcmluZ0ludGVudH1fJHthbm5vdGF0aW9uSGFzaH1gXG4gICAgfTtcbiAgfVxuXG4gIGRlc3Ryb3koKSB7XG4gICAgaWYgKHRoaXMuZGVzdHJveUNhcGFiaWxpdHkpIHtcbiAgICAgIHJldHVybiB0aGlzLmRlc3Ryb3lDYXBhYmlsaXR5LnByb21pc2U7XG4gICAgfVxuXG4gICAgdGhpcy5kZXN0cm95ZWQgPSB0cnVlO1xuICAgIHRoaXMuZGVzdHJveUNhcGFiaWxpdHkgPSAoMCwgX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkpKCk7XG5cbiAgICBpZiAodGhpcy5fcGFzc3dvcmRDYXBhYmlsaXR5KSB7XG4gICAgICB0aGlzLl9wYXNzd29yZENhcGFiaWxpdHkucmVqZWN0KG5ldyBFcnJvcihcIldvcmtlciB3YXMgZGVzdHJveWVkIGR1cmluZyBvblBhc3N3b3JkIGNhbGxiYWNrXCIpKTtcbiAgICB9XG5cbiAgICBjb25zdCB3YWl0T24gPSBbXTtcblxuICAgIGZvciAoY29uc3QgcGFnZSBvZiB0aGlzLiNwYWdlQ2FjaGUudmFsdWVzKCkpIHtcbiAgICAgIHdhaXRPbi5wdXNoKHBhZ2UuX2Rlc3Ryb3koKSk7XG4gICAgfVxuXG4gICAgdGhpcy4jcGFnZUNhY2hlLmNsZWFyKCk7XG4gICAgdGhpcy4jcGFnZVByb21pc2VzLmNsZWFyKCk7XG5cbiAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShcImFubm90YXRpb25TdG9yYWdlXCIpKSB7XG4gICAgICB0aGlzLmFubm90YXRpb25TdG9yYWdlLnJlc2V0TW9kaWZpZWQoKTtcbiAgICB9XG5cbiAgICBjb25zdCB0ZXJtaW5hdGVkID0gdGhpcy5tZXNzYWdlSGFuZGxlci5zZW5kV2l0aFByb21pc2UoXCJUZXJtaW5hdGVcIiwgbnVsbCk7XG4gICAgd2FpdE9uLnB1c2godGVybWluYXRlZCk7XG4gICAgUHJvbWlzZS5hbGwod2FpdE9uKS50aGVuKCgpID0+IHtcbiAgICAgIHRoaXMuY29tbW9uT2Jqcy5jbGVhcigpO1xuICAgICAgdGhpcy5mb250TG9hZGVyLmNsZWFyKCk7XG4gICAgICB0aGlzLiNtZXRhZGF0YVByb21pc2UgPSBudWxsO1xuICAgICAgdGhpcy5fZ2V0RmllbGRPYmplY3RzUHJvbWlzZSA9IG51bGw7XG4gICAgICB0aGlzLl9oYXNKU0FjdGlvbnNQcm9taXNlID0gbnVsbDtcblxuICAgICAgaWYgKHRoaXMuX25ldHdvcmtTdHJlYW0pIHtcbiAgICAgICAgdGhpcy5fbmV0d29ya1N0cmVhbS5jYW5jZWxBbGxSZXF1ZXN0cyhuZXcgX3V0aWwuQWJvcnRFeGNlcHRpb24oXCJXb3JrZXIgd2FzIHRlcm1pbmF0ZWQuXCIpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMubWVzc2FnZUhhbmRsZXIpIHtcbiAgICAgICAgdGhpcy5tZXNzYWdlSGFuZGxlci5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMubWVzc2FnZUhhbmRsZXIgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmRlc3Ryb3lDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgICB9LCB0aGlzLmRlc3Ryb3lDYXBhYmlsaXR5LnJlamVjdCk7XG4gICAgcmV0dXJuIHRoaXMuZGVzdHJveUNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxuXG4gIHNldHVwTWVzc2FnZUhhbmRsZXIoKSB7XG4gICAgY29uc3Qge1xuICAgICAgbWVzc2FnZUhhbmRsZXIsXG4gICAgICBsb2FkaW5nVGFza1xuICAgIH0gPSB0aGlzO1xuICAgIG1lc3NhZ2VIYW5kbGVyLm9uKFwiR2V0UmVhZGVyXCIsIChkYXRhLCBzaW5rKSA9PiB7XG4gICAgICAoMCwgX3V0aWwuYXNzZXJ0KSh0aGlzLl9uZXR3b3JrU3RyZWFtLCBcIkdldFJlYWRlciAtIG5vIGBJUERGU3RyZWFtYCBpbnN0YW5jZSBhdmFpbGFibGUuXCIpO1xuICAgICAgdGhpcy5fZnVsbFJlYWRlciA9IHRoaXMuX25ldHdvcmtTdHJlYW0uZ2V0RnVsbFJlYWRlcigpO1xuXG4gICAgICB0aGlzLl9mdWxsUmVhZGVyLm9uUHJvZ3Jlc3MgPSBldnQgPT4ge1xuICAgICAgICB0aGlzLl9sYXN0UHJvZ3Jlc3MgPSB7XG4gICAgICAgICAgbG9hZGVkOiBldnQubG9hZGVkLFxuICAgICAgICAgIHRvdGFsOiBldnQudG90YWxcbiAgICAgICAgfTtcbiAgICAgIH07XG5cbiAgICAgIHNpbmsub25QdWxsID0gKCkgPT4ge1xuICAgICAgICB0aGlzLl9mdWxsUmVhZGVyLnJlYWQoKS50aGVuKGZ1bmN0aW9uICh7XG4gICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgZG9uZVxuICAgICAgICB9KSB7XG4gICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgIHNpbmsuY2xvc2UoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAoMCwgX3V0aWwuYXNzZXJ0KSgoMCwgX3V0aWwuaXNBcnJheUJ1ZmZlcikodmFsdWUpLCBcIkdldFJlYWRlciAtIGV4cGVjdGVkIGFuIEFycmF5QnVmZmVyLlwiKTtcbiAgICAgICAgICBzaW5rLmVucXVldWUobmV3IFVpbnQ4QXJyYXkodmFsdWUpLCAxLCBbdmFsdWVdKTtcbiAgICAgICAgfSkuY2F0Y2gocmVhc29uID0+IHtcbiAgICAgICAgICBzaW5rLmVycm9yKHJlYXNvbik7XG4gICAgICAgIH0pO1xuICAgICAgfTtcblxuICAgICAgc2luay5vbkNhbmNlbCA9IHJlYXNvbiA9PiB7XG4gICAgICAgIHRoaXMuX2Z1bGxSZWFkZXIuY2FuY2VsKHJlYXNvbik7XG5cbiAgICAgICAgc2luay5yZWFkeS5jYXRjaChyZWFkeVJlYXNvbiA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMuZGVzdHJveWVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhyb3cgcmVhZHlSZWFzb247XG4gICAgICAgIH0pO1xuICAgICAgfTtcbiAgICB9KTtcbiAgICBtZXNzYWdlSGFuZGxlci5vbihcIlJlYWRlckhlYWRlcnNSZWFkeVwiLCBkYXRhID0+IHtcbiAgICAgIGNvbnN0IGhlYWRlcnNDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgICAgY29uc3QgZnVsbFJlYWRlciA9IHRoaXMuX2Z1bGxSZWFkZXI7XG4gICAgICBmdWxsUmVhZGVyLmhlYWRlcnNSZWFkeS50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKCFmdWxsUmVhZGVyLmlzU3RyZWFtaW5nU3VwcG9ydGVkIHx8ICFmdWxsUmVhZGVyLmlzUmFuZ2VTdXBwb3J0ZWQpIHtcbiAgICAgICAgICBpZiAodGhpcy5fbGFzdFByb2dyZXNzKSB7XG4gICAgICAgICAgICBsb2FkaW5nVGFzay5vblByb2dyZXNzPy4odGhpcy5fbGFzdFByb2dyZXNzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmdWxsUmVhZGVyLm9uUHJvZ3Jlc3MgPSBldnQgPT4ge1xuICAgICAgICAgICAgbG9hZGluZ1Rhc2sub25Qcm9ncmVzcz8uKHtcbiAgICAgICAgICAgICAgbG9hZGVkOiBldnQubG9hZGVkLFxuICAgICAgICAgICAgICB0b3RhbDogZXZ0LnRvdGFsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgaGVhZGVyc0NhcGFiaWxpdHkucmVzb2x2ZSh7XG4gICAgICAgICAgaXNTdHJlYW1pbmdTdXBwb3J0ZWQ6IGZ1bGxSZWFkZXIuaXNTdHJlYW1pbmdTdXBwb3J0ZWQsXG4gICAgICAgICAgaXNSYW5nZVN1cHBvcnRlZDogZnVsbFJlYWRlci5pc1JhbmdlU3VwcG9ydGVkLFxuICAgICAgICAgIGNvbnRlbnRMZW5ndGg6IGZ1bGxSZWFkZXIuY29udGVudExlbmd0aFxuICAgICAgICB9KTtcbiAgICAgIH0sIGhlYWRlcnNDYXBhYmlsaXR5LnJlamVjdCk7XG4gICAgICByZXR1cm4gaGVhZGVyc0NhcGFiaWxpdHkucHJvbWlzZTtcbiAgICB9KTtcbiAgICBtZXNzYWdlSGFuZGxlci5vbihcIkdldFJhbmdlUmVhZGVyXCIsIChkYXRhLCBzaW5rKSA9PiB7XG4gICAgICAoMCwgX3V0aWwuYXNzZXJ0KSh0aGlzLl9uZXR3b3JrU3RyZWFtLCBcIkdldFJhbmdlUmVhZGVyIC0gbm8gYElQREZTdHJlYW1gIGluc3RhbmNlIGF2YWlsYWJsZS5cIik7XG5cbiAgICAgIGNvbnN0IHJhbmdlUmVhZGVyID0gdGhpcy5fbmV0d29ya1N0cmVhbS5nZXRSYW5nZVJlYWRlcihkYXRhLmJlZ2luLCBkYXRhLmVuZCk7XG5cbiAgICAgIGlmICghcmFuZ2VSZWFkZXIpIHtcbiAgICAgICAgc2luay5jbG9zZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHNpbmsub25QdWxsID0gKCkgPT4ge1xuICAgICAgICByYW5nZVJlYWRlci5yZWFkKCkudGhlbihmdW5jdGlvbiAoe1xuICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgIGRvbmVcbiAgICAgICAgfSkge1xuICAgICAgICAgIGlmIChkb25lKSB7XG4gICAgICAgICAgICBzaW5rLmNsb3NlKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgKDAsIF91dGlsLmFzc2VydCkoKDAsIF91dGlsLmlzQXJyYXlCdWZmZXIpKHZhbHVlKSwgXCJHZXRSYW5nZVJlYWRlciAtIGV4cGVjdGVkIGFuIEFycmF5QnVmZmVyLlwiKTtcbiAgICAgICAgICBzaW5rLmVucXVldWUobmV3IFVpbnQ4QXJyYXkodmFsdWUpLCAxLCBbdmFsdWVdKTtcbiAgICAgICAgfSkuY2F0Y2gocmVhc29uID0+IHtcbiAgICAgICAgICBzaW5rLmVycm9yKHJlYXNvbik7XG4gICAgICAgIH0pO1xuICAgICAgfTtcblxuICAgICAgc2luay5vbkNhbmNlbCA9IHJlYXNvbiA9PiB7XG4gICAgICAgIHJhbmdlUmVhZGVyLmNhbmNlbChyZWFzb24pO1xuICAgICAgICBzaW5rLnJlYWR5LmNhdGNoKHJlYWR5UmVhc29uID0+IHtcbiAgICAgICAgICBpZiAodGhpcy5kZXN0cm95ZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aHJvdyByZWFkeVJlYXNvbjtcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgIH0pO1xuICAgIG1lc3NhZ2VIYW5kbGVyLm9uKFwiR2V0RG9jXCIsICh7XG4gICAgICBwZGZJbmZvXG4gICAgfSkgPT4ge1xuICAgICAgdGhpcy5fbnVtUGFnZXMgPSBwZGZJbmZvLm51bVBhZ2VzO1xuICAgICAgdGhpcy5faHRtbEZvclhmYSA9IHBkZkluZm8uaHRtbEZvclhmYTtcbiAgICAgIGRlbGV0ZSBwZGZJbmZvLmh0bWxGb3JYZmE7XG5cbiAgICAgIGxvYWRpbmdUYXNrLl9jYXBhYmlsaXR5LnJlc29sdmUobmV3IFBERkRvY3VtZW50UHJveHkocGRmSW5mbywgdGhpcykpO1xuICAgIH0pO1xuICAgIG1lc3NhZ2VIYW5kbGVyLm9uKFwiRG9jRXhjZXB0aW9uXCIsIGZ1bmN0aW9uIChleCkge1xuICAgICAgbGV0IHJlYXNvbjtcblxuICAgICAgc3dpdGNoIChleC5uYW1lKSB7XG4gICAgICAgIGNhc2UgXCJQYXNzd29yZEV4Y2VwdGlvblwiOlxuICAgICAgICAgIHJlYXNvbiA9IG5ldyBfdXRpbC5QYXNzd29yZEV4Y2VwdGlvbihleC5tZXNzYWdlLCBleC5jb2RlKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFwiSW52YWxpZFBERkV4Y2VwdGlvblwiOlxuICAgICAgICAgIHJlYXNvbiA9IG5ldyBfdXRpbC5JbnZhbGlkUERGRXhjZXB0aW9uKGV4Lm1lc3NhZ2UpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgXCJNaXNzaW5nUERGRXhjZXB0aW9uXCI6XG4gICAgICAgICAgcmVhc29uID0gbmV3IF91dGlsLk1pc3NpbmdQREZFeGNlcHRpb24oZXgubWVzc2FnZSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBcIlVuZXhwZWN0ZWRSZXNwb25zZUV4Y2VwdGlvblwiOlxuICAgICAgICAgIHJlYXNvbiA9IG5ldyBfdXRpbC5VbmV4cGVjdGVkUmVzcG9uc2VFeGNlcHRpb24oZXgubWVzc2FnZSwgZXguc3RhdHVzKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFwiVW5rbm93bkVycm9yRXhjZXB0aW9uXCI6XG4gICAgICAgICAgcmVhc29uID0gbmV3IF91dGlsLlVua25vd25FcnJvckV4Y2VwdGlvbihleC5tZXNzYWdlLCBleC5kZXRhaWxzKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICgwLCBfdXRpbC51bnJlYWNoYWJsZSkoXCJEb2NFeGNlcHRpb24gLSBleHBlY3RlZCBhIHZhbGlkIEVycm9yLlwiKTtcbiAgICAgIH1cblxuICAgICAgbG9hZGluZ1Rhc2suX2NhcGFiaWxpdHkucmVqZWN0KHJlYXNvbik7XG4gICAgfSk7XG4gICAgbWVzc2FnZUhhbmRsZXIub24oXCJQYXNzd29yZFJlcXVlc3RcIiwgZXhjZXB0aW9uID0+IHtcbiAgICAgIHRoaXMuX3Bhc3N3b3JkQ2FwYWJpbGl0eSA9ICgwLCBfdXRpbC5jcmVhdGVQcm9taXNlQ2FwYWJpbGl0eSkoKTtcblxuICAgICAgaWYgKGxvYWRpbmdUYXNrLm9uUGFzc3dvcmQpIHtcbiAgICAgICAgY29uc3QgdXBkYXRlUGFzc3dvcmQgPSBwYXNzd29yZCA9PiB7XG4gICAgICAgICAgaWYgKHBhc3N3b3JkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgIHRoaXMuX3Bhc3N3b3JkQ2FwYWJpbGl0eS5yZWplY3QocGFzc3dvcmQpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9wYXNzd29yZENhcGFiaWxpdHkucmVzb2x2ZSh7XG4gICAgICAgICAgICAgIHBhc3N3b3JkXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBsb2FkaW5nVGFzay5vblBhc3N3b3JkKHVwZGF0ZVBhc3N3b3JkLCBleGNlcHRpb24uY29kZSk7XG4gICAgICAgIH0gY2F0Y2ggKGV4KSB7XG4gICAgICAgICAgdGhpcy5fcGFzc3dvcmRDYXBhYmlsaXR5LnJlamVjdChleCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX3Bhc3N3b3JkQ2FwYWJpbGl0eS5yZWplY3QobmV3IF91dGlsLlBhc3N3b3JkRXhjZXB0aW9uKGV4Y2VwdGlvbi5tZXNzYWdlLCBleGNlcHRpb24uY29kZSkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5fcGFzc3dvcmRDYXBhYmlsaXR5LnByb21pc2U7XG4gICAgfSk7XG4gICAgbWVzc2FnZUhhbmRsZXIub24oXCJEYXRhTG9hZGVkXCIsIGRhdGEgPT4ge1xuICAgICAgbG9hZGluZ1Rhc2sub25Qcm9ncmVzcz8uKHtcbiAgICAgICAgbG9hZGVkOiBkYXRhLmxlbmd0aCxcbiAgICAgICAgdG90YWw6IGRhdGEubGVuZ3RoXG4gICAgICB9KTtcbiAgICAgIHRoaXMuZG93bmxvYWRJbmZvQ2FwYWJpbGl0eS5yZXNvbHZlKGRhdGEpO1xuICAgIH0pO1xuICAgIG1lc3NhZ2VIYW5kbGVyLm9uKFwiU3RhcnRSZW5kZXJQYWdlXCIsIGRhdGEgPT4ge1xuICAgICAgaWYgKHRoaXMuZGVzdHJveWVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGFnZSA9IHRoaXMuI3BhZ2VDYWNoZS5nZXQoZGF0YS5wYWdlSW5kZXgpO1xuXG4gICAgICBwYWdlLl9zdGFydFJlbmRlclBhZ2UoZGF0YS50cmFuc3BhcmVuY3ksIGRhdGEuY2FjaGVLZXkpO1xuICAgIH0pO1xuICAgIG1lc3NhZ2VIYW5kbGVyLm9uKFwiY29tbW9ub2JqXCIsIChbaWQsIHR5cGUsIGV4cG9ydGVkRGF0YV0pID0+IHtcbiAgICAgIGlmICh0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmNvbW1vbk9ianMuaGFzKGlkKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlIFwiRm9udFwiOlxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHRoaXMuX3BhcmFtcztcblxuICAgICAgICAgIGlmIChcImVycm9yXCIgaW4gZXhwb3J0ZWREYXRhKSB7XG4gICAgICAgICAgICBjb25zdCBleHBvcnRlZEVycm9yID0gZXhwb3J0ZWREYXRhLmVycm9yO1xuICAgICAgICAgICAgKDAsIF91dGlsLndhcm4pKGBFcnJvciBkdXJpbmcgZm9udCBsb2FkaW5nOiAke2V4cG9ydGVkRXJyb3J9YCk7XG4gICAgICAgICAgICB0aGlzLmNvbW1vbk9ianMucmVzb2x2ZShpZCwgZXhwb3J0ZWRFcnJvcik7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBsZXQgZm9udFJlZ2lzdHJ5ID0gbnVsbDtcblxuICAgICAgICAgIGlmIChwYXJhbXMucGRmQnVnICYmIGdsb2JhbFRoaXMuRm9udEluc3BlY3Rvcj8uZW5hYmxlZCkge1xuICAgICAgICAgICAgZm9udFJlZ2lzdHJ5ID0ge1xuICAgICAgICAgICAgICByZWdpc3RlckZvbnQoZm9udCwgdXJsKSB7XG4gICAgICAgICAgICAgICAgZ2xvYmFsVGhpcy5Gb250SW5zcGVjdG9yLmZvbnRBZGRlZChmb250LCB1cmwpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgZm9udCA9IG5ldyBfZm9udF9sb2FkZXIuRm9udEZhY2VPYmplY3QoZXhwb3J0ZWREYXRhLCB7XG4gICAgICAgICAgICBpc0V2YWxTdXBwb3J0ZWQ6IHBhcmFtcy5pc0V2YWxTdXBwb3J0ZWQsXG4gICAgICAgICAgICBkaXNhYmxlRm9udEZhY2U6IHBhcmFtcy5kaXNhYmxlRm9udEZhY2UsXG4gICAgICAgICAgICBpZ25vcmVFcnJvcnM6IHBhcmFtcy5pZ25vcmVFcnJvcnMsXG4gICAgICAgICAgICBvblVuc3VwcG9ydGVkRmVhdHVyZTogdGhpcy5fb25VbnN1cHBvcnRlZEZlYXR1cmUuYmluZCh0aGlzKSxcbiAgICAgICAgICAgIGZvbnRSZWdpc3RyeVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRoaXMuZm9udExvYWRlci5iaW5kKGZvbnQpLmNhdGNoKHJlYXNvbiA9PiB7XG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiRm9udEZhbGxiYWNrXCIsIHtcbiAgICAgICAgICAgICAgaWRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKCFwYXJhbXMuZm9udEV4dHJhUHJvcGVydGllcyAmJiBmb250LmRhdGEpIHtcbiAgICAgICAgICAgICAgZm9udC5kYXRhID0gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jb21tb25PYmpzLnJlc29sdmUoaWQsIGZvbnQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgXCJGb250UGF0aFwiOlxuICAgICAgICBjYXNlIFwiSW1hZ2VcIjpcbiAgICAgICAgICB0aGlzLmNvbW1vbk9ianMucmVzb2x2ZShpZCwgZXhwb3J0ZWREYXRhKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgR290IHVua25vd24gY29tbW9uIG9iamVjdCB0eXBlICR7dHlwZX1gKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBtZXNzYWdlSGFuZGxlci5vbihcIm9ialwiLCAoW2lkLCBwYWdlSW5kZXgsIHR5cGUsIGltYWdlRGF0YV0pID0+IHtcbiAgICAgIGlmICh0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBhZ2VQcm94eSA9IHRoaXMuI3BhZ2VDYWNoZS5nZXQocGFnZUluZGV4KTtcblxuICAgICAgaWYgKHBhZ2VQcm94eS5vYmpzLmhhcyhpZCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSBcIkltYWdlXCI6XG4gICAgICAgICAgcGFnZVByb3h5Lm9ianMucmVzb2x2ZShpZCwgaW1hZ2VEYXRhKTtcbiAgICAgICAgICBjb25zdCBNQVhfSU1BR0VfU0laRV9UT19TVE9SRSA9IDgwMDAwMDA7XG5cbiAgICAgICAgICBpZiAoaW1hZ2VEYXRhKSB7XG4gICAgICAgICAgICBsZXQgbGVuZ3RoO1xuXG4gICAgICAgICAgICBpZiAoaW1hZ2VEYXRhLmJpdG1hcCkge1xuICAgICAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICAgICAgYml0bWFwLFxuICAgICAgICAgICAgICAgIHdpZHRoLFxuICAgICAgICAgICAgICAgIGhlaWdodFxuICAgICAgICAgICAgICB9ID0gaW1hZ2VEYXRhO1xuICAgICAgICAgICAgICBsZW5ndGggPSB3aWR0aCAqIGhlaWdodCAqIDQ7XG5cbiAgICAgICAgICAgICAgcGFnZVByb3h5Ll9iaXRtYXBzLmFkZChiaXRtYXApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgbGVuZ3RoID0gaW1hZ2VEYXRhLmRhdGE/Lmxlbmd0aCB8fCAwO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobGVuZ3RoID4gTUFYX0lNQUdFX1NJWkVfVE9fU1RPUkUpIHtcbiAgICAgICAgICAgICAgcGFnZVByb3h5LmNsZWFudXBBZnRlclJlbmRlciA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBcIlBhdHRlcm5cIjpcbiAgICAgICAgICBwYWdlUHJveHkub2Jqcy5yZXNvbHZlKGlkLCBpbWFnZURhdGEpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBHb3QgdW5rbm93biBvYmplY3QgdHlwZSAke3R5cGV9YCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgbWVzc2FnZUhhbmRsZXIub24oXCJEb2NQcm9ncmVzc1wiLCBkYXRhID0+IHtcbiAgICAgIGlmICh0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGxvYWRpbmdUYXNrLm9uUHJvZ3Jlc3M/Lih7XG4gICAgICAgIGxvYWRlZDogZGF0YS5sb2FkZWQsXG4gICAgICAgIHRvdGFsOiBkYXRhLnRvdGFsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBtZXNzYWdlSGFuZGxlci5vbihcIkRvY1N0YXRzXCIsIGRhdGEgPT4ge1xuICAgICAgaWYgKHRoaXMuZGVzdHJveWVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy4jZG9jU3RhdHMgPSBPYmplY3QuZnJlZXplKHtcbiAgICAgICAgc3RyZWFtVHlwZXM6IE9iamVjdC5mcmVlemUoZGF0YS5zdHJlYW1UeXBlcyksXG4gICAgICAgIGZvbnRUeXBlczogT2JqZWN0LmZyZWV6ZShkYXRhLmZvbnRUeXBlcylcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIG1lc3NhZ2VIYW5kbGVyLm9uKFwiVW5zdXBwb3J0ZWRGZWF0dXJlXCIsIHRoaXMuX29uVW5zdXBwb3J0ZWRGZWF0dXJlLmJpbmQodGhpcykpO1xuICAgIG1lc3NhZ2VIYW5kbGVyLm9uKFwiRmV0Y2hCdWlsdEluQ01hcFwiLCBkYXRhID0+IHtcbiAgICAgIGlmICh0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiV29ya2VyIHdhcyBkZXN0cm95ZWQuXCIpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCF0aGlzLkNNYXBSZWFkZXJGYWN0b3J5KSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJDTWFwUmVhZGVyRmFjdG9yeSBub3QgaW5pdGlhbGl6ZWQsIHNlZSB0aGUgYHVzZVdvcmtlckZldGNoYCBwYXJhbWV0ZXIuXCIpKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuQ01hcFJlYWRlckZhY3RvcnkuZmV0Y2goZGF0YSk7XG4gICAgfSk7XG4gICAgbWVzc2FnZUhhbmRsZXIub24oXCJGZXRjaFN0YW5kYXJkRm9udERhdGFcIiwgZGF0YSA9PiB7XG4gICAgICBpZiAodGhpcy5kZXN0cm95ZWQpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIldvcmtlciB3YXMgZGVzdHJveWVkLlwiKSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghdGhpcy5TdGFuZGFyZEZvbnREYXRhRmFjdG9yeSkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiU3RhbmRhcmRGb250RGF0YUZhY3Rvcnkgbm90IGluaXRpYWxpemVkLCBzZWUgdGhlIGB1c2VXb3JrZXJGZXRjaGAgcGFyYW1ldGVyLlwiKSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLlN0YW5kYXJkRm9udERhdGFGYWN0b3J5LmZldGNoKGRhdGEpO1xuICAgIH0pO1xuICB9XG5cbiAgX29uVW5zdXBwb3J0ZWRGZWF0dXJlKHtcbiAgICBmZWF0dXJlSWRcbiAgfSkge1xuICAgIGlmICh0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMubG9hZGluZ1Rhc2sub25VbnN1cHBvcnRlZEZlYXR1cmU/LihmZWF0dXJlSWQpO1xuICB9XG5cbiAgZ2V0RGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy5tZXNzYWdlSGFuZGxlci5zZW5kV2l0aFByb21pc2UoXCJHZXREYXRhXCIsIG51bGwpO1xuICB9XG5cbiAgZ2V0UGFnZShwYWdlTnVtYmVyKSB7XG4gICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHBhZ2VOdW1iZXIpIHx8IHBhZ2VOdW1iZXIgPD0gMCB8fCBwYWdlTnVtYmVyID4gdGhpcy5fbnVtUGFnZXMpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJJbnZhbGlkIHBhZ2UgcmVxdWVzdC5cIikpO1xuICAgIH1cblxuICAgIGNvbnN0IHBhZ2VJbmRleCA9IHBhZ2VOdW1iZXIgLSAxLFxuICAgICAgICAgIGNhY2hlZFByb21pc2UgPSB0aGlzLiNwYWdlUHJvbWlzZXMuZ2V0KHBhZ2VJbmRleCk7XG5cbiAgICBpZiAoY2FjaGVkUHJvbWlzZSkge1xuICAgICAgcmV0dXJuIGNhY2hlZFByb21pc2U7XG4gICAgfVxuXG4gICAgY29uc3QgcHJvbWlzZSA9IHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0UGFnZVwiLCB7XG4gICAgICBwYWdlSW5kZXhcbiAgICB9KS50aGVuKHBhZ2VJbmZvID0+IHtcbiAgICAgIGlmICh0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUcmFuc3BvcnQgZGVzdHJveWVkXCIpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwYWdlID0gbmV3IFBERlBhZ2VQcm94eShwYWdlSW5kZXgsIHBhZ2VJbmZvLCB0aGlzLCB0aGlzLl9wYXJhbXMub3duZXJEb2N1bWVudCwgdGhpcy5fcGFyYW1zLnBkZkJ1Zyk7XG4gICAgICB0aGlzLiNwYWdlQ2FjaGUuc2V0KHBhZ2VJbmRleCwgcGFnZSk7XG4gICAgICByZXR1cm4gcGFnZTtcbiAgICB9KTtcbiAgICB0aGlzLiNwYWdlUHJvbWlzZXMuc2V0KHBhZ2VJbmRleCwgcHJvbWlzZSk7XG4gICAgcmV0dXJuIHByb21pc2U7XG4gIH1cblxuICBnZXRQYWdlSW5kZXgocmVmKSB7XG4gICAgaWYgKHR5cGVvZiByZWYgIT09IFwib2JqZWN0XCIgfHwgcmVmID09PSBudWxsIHx8ICFOdW1iZXIuaXNJbnRlZ2VyKHJlZi5udW0pIHx8IHJlZi5udW0gPCAwIHx8ICFOdW1iZXIuaXNJbnRlZ2VyKHJlZi5nZW4pIHx8IHJlZi5nZW4gPCAwKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiSW52YWxpZCBwYWdlSW5kZXggcmVxdWVzdC5cIikpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLm1lc3NhZ2VIYW5kbGVyLnNlbmRXaXRoUHJvbWlzZShcIkdldFBhZ2VJbmRleFwiLCB7XG4gICAgICBudW06IHJlZi5udW0sXG4gICAgICBnZW46IHJlZi5nZW5cbiAgICB9KTtcbiAgfVxuXG4gIGdldEFubm90YXRpb25zKHBhZ2VJbmRleCwgaW50ZW50KSB7XG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0QW5ub3RhdGlvbnNcIiwge1xuICAgICAgcGFnZUluZGV4LFxuICAgICAgaW50ZW50XG4gICAgfSk7XG4gIH1cblxuICBzYXZlRG9jdW1lbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiU2F2ZURvY3VtZW50XCIsIHtcbiAgICAgIGlzUHVyZVhmYTogISF0aGlzLl9odG1sRm9yWGZhLFxuICAgICAgbnVtUGFnZXM6IHRoaXMuX251bVBhZ2VzLFxuICAgICAgYW5ub3RhdGlvblN0b3JhZ2U6IHRoaXMuYW5ub3RhdGlvblN0b3JhZ2Uuc2VyaWFsaXphYmxlLFxuICAgICAgZmlsZW5hbWU6IHRoaXMuX2Z1bGxSZWFkZXI/LmZpbGVuYW1lID8/IG51bGxcbiAgICB9KS5maW5hbGx5KCgpID0+IHtcbiAgICAgIHRoaXMuYW5ub3RhdGlvblN0b3JhZ2UucmVzZXRNb2RpZmllZCgpO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0RmllbGRPYmplY3RzKCkge1xuICAgIHJldHVybiB0aGlzLl9nZXRGaWVsZE9iamVjdHNQcm9taXNlIHx8PSB0aGlzLm1lc3NhZ2VIYW5kbGVyLnNlbmRXaXRoUHJvbWlzZShcIkdldEZpZWxkT2JqZWN0c1wiLCBudWxsKTtcbiAgfVxuXG4gIGhhc0pTQWN0aW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy5faGFzSlNBY3Rpb25zUHJvbWlzZSB8fD0gdGhpcy5tZXNzYWdlSGFuZGxlci5zZW5kV2l0aFByb21pc2UoXCJIYXNKU0FjdGlvbnNcIiwgbnVsbCk7XG4gIH1cblxuICBnZXRDYWxjdWxhdGlvbk9yZGVySWRzKCkge1xuICAgIHJldHVybiB0aGlzLm1lc3NhZ2VIYW5kbGVyLnNlbmRXaXRoUHJvbWlzZShcIkdldENhbGN1bGF0aW9uT3JkZXJJZHNcIiwgbnVsbCk7XG4gIH1cblxuICBnZXREZXN0aW5hdGlvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0RGVzdGluYXRpb25zXCIsIG51bGwpO1xuICB9XG5cbiAgZ2V0RGVzdGluYXRpb24oaWQpIHtcbiAgICBpZiAodHlwZW9mIGlkICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiSW52YWxpZCBkZXN0aW5hdGlvbiByZXF1ZXN0LlwiKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0RGVzdGluYXRpb25cIiwge1xuICAgICAgaWRcbiAgICB9KTtcbiAgfVxuXG4gIGdldFBhZ2VMYWJlbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0UGFnZUxhYmVsc1wiLCBudWxsKTtcbiAgfVxuXG4gIGdldFBhZ2VMYXlvdXQoKSB7XG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0UGFnZUxheW91dFwiLCBudWxsKTtcbiAgfVxuXG4gIGdldFBhZ2VNb2RlKCkge1xuICAgIHJldHVybiB0aGlzLm1lc3NhZ2VIYW5kbGVyLnNlbmRXaXRoUHJvbWlzZShcIkdldFBhZ2VNb2RlXCIsIG51bGwpO1xuICB9XG5cbiAgZ2V0Vmlld2VyUHJlZmVyZW5jZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0Vmlld2VyUHJlZmVyZW5jZXNcIiwgbnVsbCk7XG4gIH1cblxuICBnZXRPcGVuQWN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLm1lc3NhZ2VIYW5kbGVyLnNlbmRXaXRoUHJvbWlzZShcIkdldE9wZW5BY3Rpb25cIiwgbnVsbCk7XG4gIH1cblxuICBnZXRBdHRhY2htZW50cygpIHtcbiAgICByZXR1cm4gdGhpcy5tZXNzYWdlSGFuZGxlci5zZW5kV2l0aFByb21pc2UoXCJHZXRBdHRhY2htZW50c1wiLCBudWxsKTtcbiAgfVxuXG4gIGdldEphdmFTY3JpcHQoKSB7XG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0SmF2YVNjcmlwdFwiLCBudWxsKTtcbiAgfVxuXG4gIGdldERvY0pTQWN0aW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy5tZXNzYWdlSGFuZGxlci5zZW5kV2l0aFByb21pc2UoXCJHZXREb2NKU0FjdGlvbnNcIiwgbnVsbCk7XG4gIH1cblxuICBnZXRQYWdlSlNBY3Rpb25zKHBhZ2VJbmRleCkge1xuICAgIHJldHVybiB0aGlzLm1lc3NhZ2VIYW5kbGVyLnNlbmRXaXRoUHJvbWlzZShcIkdldFBhZ2VKU0FjdGlvbnNcIiwge1xuICAgICAgcGFnZUluZGV4XG4gICAgfSk7XG4gIH1cblxuICBnZXRTdHJ1Y3RUcmVlKHBhZ2VJbmRleCkge1xuICAgIHJldHVybiB0aGlzLm1lc3NhZ2VIYW5kbGVyLnNlbmRXaXRoUHJvbWlzZShcIkdldFN0cnVjdFRyZWVcIiwge1xuICAgICAgcGFnZUluZGV4XG4gICAgfSk7XG4gIH1cblxuICBnZXRPdXRsaW5lKCkge1xuICAgIHJldHVybiB0aGlzLm1lc3NhZ2VIYW5kbGVyLnNlbmRXaXRoUHJvbWlzZShcIkdldE91dGxpbmVcIiwgbnVsbCk7XG4gIH1cblxuICBnZXRPcHRpb25hbENvbnRlbnRDb25maWcoKSB7XG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0T3B0aW9uYWxDb250ZW50Q29uZmlnXCIsIG51bGwpLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICByZXR1cm4gbmV3IF9vcHRpb25hbF9jb250ZW50X2NvbmZpZy5PcHRpb25hbENvbnRlbnRDb25maWcocmVzdWx0cyk7XG4gICAgfSk7XG4gIH1cblxuICBnZXRQZXJtaXNzaW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy5tZXNzYWdlSGFuZGxlci5zZW5kV2l0aFByb21pc2UoXCJHZXRQZXJtaXNzaW9uc1wiLCBudWxsKTtcbiAgfVxuXG4gIGdldE1ldGFkYXRhKCkge1xuICAgIHJldHVybiB0aGlzLiNtZXRhZGF0YVByb21pc2UgfHw9IHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0TWV0YWRhdGFcIiwgbnVsbCkudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGluZm86IHJlc3VsdHNbMF0sXG4gICAgICAgIG1ldGFkYXRhOiByZXN1bHRzWzFdID8gbmV3IF9tZXRhZGF0YS5NZXRhZGF0YShyZXN1bHRzWzFdKSA6IG51bGwsXG4gICAgICAgIGNvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lOiB0aGlzLl9mdWxsUmVhZGVyPy5maWxlbmFtZSA/PyBudWxsLFxuICAgICAgICBjb250ZW50TGVuZ3RoOiB0aGlzLl9mdWxsUmVhZGVyPy5jb250ZW50TGVuZ3RoID8/IG51bGxcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBnZXRNYXJrSW5mbygpIHtcbiAgICByZXR1cm4gdGhpcy5tZXNzYWdlSGFuZGxlci5zZW5kV2l0aFByb21pc2UoXCJHZXRNYXJrSW5mb1wiLCBudWxsKTtcbiAgfVxuXG4gIGFzeW5jIHN0YXJ0Q2xlYW51cChrZWVwTG9hZGVkRm9udHMgPSBmYWxzZSkge1xuICAgIGF3YWl0IHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiQ2xlYW51cFwiLCBudWxsKTtcblxuICAgIGlmICh0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcGFnZSBvZiB0aGlzLiNwYWdlQ2FjaGUudmFsdWVzKCkpIHtcbiAgICAgIGNvbnN0IGNsZWFudXBTdWNjZXNzZnVsID0gcGFnZS5jbGVhbnVwKCk7XG5cbiAgICAgIGlmICghY2xlYW51cFN1Y2Nlc3NmdWwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBzdGFydENsZWFudXA6IFBhZ2UgJHtwYWdlLnBhZ2VOdW1iZXJ9IGlzIGN1cnJlbnRseSByZW5kZXJpbmcuYCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5jb21tb25PYmpzLmNsZWFyKCk7XG5cbiAgICBpZiAoIWtlZXBMb2FkZWRGb250cykge1xuICAgICAgdGhpcy5mb250TG9hZGVyLmNsZWFyKCk7XG4gICAgfVxuXG4gICAgdGhpcy4jbWV0YWRhdGFQcm9taXNlID0gbnVsbDtcbiAgICB0aGlzLl9nZXRGaWVsZE9iamVjdHNQcm9taXNlID0gbnVsbDtcbiAgICB0aGlzLl9oYXNKU0FjdGlvbnNQcm9taXNlID0gbnVsbDtcbiAgfVxuXG4gIGdldCBsb2FkaW5nUGFyYW1zKCkge1xuICAgIGNvbnN0IHBhcmFtcyA9IHRoaXMuX3BhcmFtcztcbiAgICByZXR1cm4gKDAsIF91dGlsLnNoYWRvdykodGhpcywgXCJsb2FkaW5nUGFyYW1zXCIsIHtcbiAgICAgIGRpc2FibGVBdXRvRmV0Y2g6IHBhcmFtcy5kaXNhYmxlQXV0b0ZldGNoLFxuICAgICAgZW5hYmxlWGZhOiBwYXJhbXMuZW5hYmxlWGZhXG4gICAgfSk7XG4gIH1cblxufVxuXG5jbGFzcyBQREZPYmplY3RzIHtcbiAgI29ianMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4gICNlbnN1cmVPYmoob2JqSWQpIHtcbiAgICBjb25zdCBvYmogPSB0aGlzLiNvYmpzW29iaklkXTtcblxuICAgIGlmIChvYmopIHtcbiAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuI29ianNbb2JqSWRdID0ge1xuICAgICAgY2FwYWJpbGl0eTogKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpLFxuICAgICAgZGF0YTogbnVsbFxuICAgIH07XG4gIH1cblxuICBnZXQob2JqSWQsIGNhbGxiYWNrID0gbnVsbCkge1xuICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgY29uc3Qgb2JqID0gdGhpcy4jZW5zdXJlT2JqKG9iaklkKTtcbiAgICAgIG9iai5jYXBhYmlsaXR5LnByb21pc2UudGhlbigoKSA9PiBjYWxsYmFjayhvYmouZGF0YSkpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3Qgb2JqID0gdGhpcy4jb2Jqc1tvYmpJZF07XG5cbiAgICBpZiAoIW9iaj8uY2FwYWJpbGl0eS5zZXR0bGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFJlcXVlc3Rpbmcgb2JqZWN0IHRoYXQgaXNuJ3QgcmVzb2x2ZWQgeWV0ICR7b2JqSWR9LmApO1xuICAgIH1cblxuICAgIHJldHVybiBvYmouZGF0YTtcbiAgfVxuXG4gIGhhcyhvYmpJZCkge1xuICAgIGNvbnN0IG9iaiA9IHRoaXMuI29ianNbb2JqSWRdO1xuICAgIHJldHVybiBvYmo/LmNhcGFiaWxpdHkuc2V0dGxlZCB8fCBmYWxzZTtcbiAgfVxuXG4gIHJlc29sdmUob2JqSWQsIGRhdGEgPSBudWxsKSB7XG4gICAgY29uc3Qgb2JqID0gdGhpcy4jZW5zdXJlT2JqKG9iaklkKTtcbiAgICBvYmouZGF0YSA9IGRhdGE7XG4gICAgb2JqLmNhcGFiaWxpdHkucmVzb2x2ZSgpO1xuICB9XG5cbiAgY2xlYXIoKSB7XG4gICAgdGhpcy4jb2JqcyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gIH1cblxufVxuXG5jbGFzcyBSZW5kZXJUYXNrIHtcbiAgY29uc3RydWN0b3IoaW50ZXJuYWxSZW5kZXJUYXNrKSB7XG4gICAgdGhpcy5faW50ZXJuYWxSZW5kZXJUYXNrID0gaW50ZXJuYWxSZW5kZXJUYXNrO1xuICAgIHRoaXMub25Db250aW51ZSA9IG51bGw7XG4gIH1cblxuICBnZXQgcHJvbWlzZSgpIHtcbiAgICByZXR1cm4gdGhpcy5faW50ZXJuYWxSZW5kZXJUYXNrLmNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxuXG4gIGNhbmNlbCgpIHtcbiAgICB0aGlzLl9pbnRlcm5hbFJlbmRlclRhc2suY2FuY2VsKCk7XG4gIH1cblxufVxuXG5leHBvcnRzLlJlbmRlclRhc2sgPSBSZW5kZXJUYXNrO1xuXG5jbGFzcyBJbnRlcm5hbFJlbmRlclRhc2sge1xuICBzdGF0aWMgI2NhbnZhc0luVXNlID0gbmV3IFdlYWtTZXQoKTtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgY2FsbGJhY2ssXG4gICAgcGFyYW1zLFxuICAgIG9ianMsXG4gICAgY29tbW9uT2JqcyxcbiAgICBhbm5vdGF0aW9uQ2FudmFzTWFwLFxuICAgIG9wZXJhdG9yTGlzdCxcbiAgICBwYWdlSW5kZXgsXG4gICAgY2FudmFzRmFjdG9yeSxcbiAgICB1c2VSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPSBmYWxzZSxcbiAgICBwZGZCdWcgPSBmYWxzZSxcbiAgICBwYWdlQ29sb3JzID0gbnVsbFxuICB9KSB7XG4gICAgdGhpcy5jYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHRoaXMucGFyYW1zID0gcGFyYW1zO1xuICAgIHRoaXMub2JqcyA9IG9ianM7XG4gICAgdGhpcy5jb21tb25PYmpzID0gY29tbW9uT2JqcztcbiAgICB0aGlzLmFubm90YXRpb25DYW52YXNNYXAgPSBhbm5vdGF0aW9uQ2FudmFzTWFwO1xuICAgIHRoaXMub3BlcmF0b3JMaXN0SWR4ID0gbnVsbDtcbiAgICB0aGlzLm9wZXJhdG9yTGlzdCA9IG9wZXJhdG9yTGlzdDtcbiAgICB0aGlzLl9wYWdlSW5kZXggPSBwYWdlSW5kZXg7XG4gICAgdGhpcy5jYW52YXNGYWN0b3J5ID0gY2FudmFzRmFjdG9yeTtcbiAgICB0aGlzLl9wZGZCdWcgPSBwZGZCdWc7XG4gICAgdGhpcy5wYWdlQ29sb3JzID0gcGFnZUNvbG9ycztcbiAgICB0aGlzLnJ1bm5pbmcgPSBmYWxzZTtcbiAgICB0aGlzLmdyYXBoaWNzUmVhZHlDYWxsYmFjayA9IG51bGw7XG4gICAgdGhpcy5ncmFwaGljc1JlYWR5ID0gZmFsc2U7XG4gICAgdGhpcy5fdXNlUmVxdWVzdEFuaW1hdGlvbkZyYW1lID0gdXNlUmVxdWVzdEFuaW1hdGlvbkZyYW1lID09PSB0cnVlICYmIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCI7XG4gICAgdGhpcy5jYW5jZWxsZWQgPSBmYWxzZTtcbiAgICB0aGlzLmNhcGFiaWxpdHkgPSAoMCwgX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkpKCk7XG4gICAgdGhpcy50YXNrID0gbmV3IFJlbmRlclRhc2sodGhpcyk7XG4gICAgdGhpcy5fY2FuY2VsQm91bmQgPSB0aGlzLmNhbmNlbC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX2NvbnRpbnVlQm91bmQgPSB0aGlzLl9jb250aW51ZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX3NjaGVkdWxlTmV4dEJvdW5kID0gdGhpcy5fc2NoZWR1bGVOZXh0LmJpbmQodGhpcyk7XG4gICAgdGhpcy5fbmV4dEJvdW5kID0gdGhpcy5fbmV4dC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX2NhbnZhcyA9IHBhcmFtcy5jYW52YXNDb250ZXh0LmNhbnZhcztcbiAgfVxuXG4gIGdldCBjb21wbGV0ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FwYWJpbGl0eS5wcm9taXNlLmNhdGNoKGZ1bmN0aW9uICgpIHt9KTtcbiAgfVxuXG4gIGluaXRpYWxpemVHcmFwaGljcyh7XG4gICAgdHJhbnNwYXJlbmN5ID0gZmFsc2UsXG4gICAgb3B0aW9uYWxDb250ZW50Q29uZmlnXG4gIH0pIHtcbiAgICBpZiAodGhpcy5jYW5jZWxsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fY2FudmFzKSB7XG4gICAgICBpZiAoSW50ZXJuYWxSZW5kZXJUYXNrLiNjYW52YXNJblVzZS5oYXModGhpcy5fY2FudmFzKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgdXNlIHRoZSBzYW1lIGNhbnZhcyBkdXJpbmcgbXVsdGlwbGUgcmVuZGVyKCkgb3BlcmF0aW9ucy4gXCIgKyBcIlVzZSBkaWZmZXJlbnQgY2FudmFzIG9yIGVuc3VyZSBwcmV2aW91cyBvcGVyYXRpb25zIHdlcmUgXCIgKyBcImNhbmNlbGxlZCBvciBjb21wbGV0ZWQuXCIpO1xuICAgICAgfVxuXG4gICAgICBJbnRlcm5hbFJlbmRlclRhc2suI2NhbnZhc0luVXNlLmFkZCh0aGlzLl9jYW52YXMpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9wZGZCdWcgJiYgZ2xvYmFsVGhpcy5TdGVwcGVyTWFuYWdlcj8uZW5hYmxlZCkge1xuICAgICAgdGhpcy5zdGVwcGVyID0gZ2xvYmFsVGhpcy5TdGVwcGVyTWFuYWdlci5jcmVhdGUodGhpcy5fcGFnZUluZGV4KTtcbiAgICAgIHRoaXMuc3RlcHBlci5pbml0KHRoaXMub3BlcmF0b3JMaXN0KTtcbiAgICAgIHRoaXMuc3RlcHBlci5uZXh0QnJlYWtQb2ludCA9IHRoaXMuc3RlcHBlci5nZXROZXh0QnJlYWtQb2ludCgpO1xuICAgIH1cblxuICAgIGNvbnN0IHtcbiAgICAgIGNhbnZhc0NvbnRleHQsXG4gICAgICB2aWV3cG9ydCxcbiAgICAgIHRyYW5zZm9ybSxcbiAgICAgIGltYWdlTGF5ZXIsXG4gICAgICBiYWNrZ3JvdW5kXG4gICAgfSA9IHRoaXMucGFyYW1zO1xuICAgIHRoaXMuZ2Z4ID0gbmV3IF9jYW52YXMuQ2FudmFzR3JhcGhpY3MoY2FudmFzQ29udGV4dCwgdGhpcy5jb21tb25PYmpzLCB0aGlzLm9ianMsIHRoaXMuY2FudmFzRmFjdG9yeSwgaW1hZ2VMYXllciwgb3B0aW9uYWxDb250ZW50Q29uZmlnLCB0aGlzLmFubm90YXRpb25DYW52YXNNYXAsIHRoaXMucGFnZUNvbG9ycyk7XG4gICAgdGhpcy5nZnguYmVnaW5EcmF3aW5nKHtcbiAgICAgIHRyYW5zZm9ybSxcbiAgICAgIHZpZXdwb3J0LFxuICAgICAgdHJhbnNwYXJlbmN5LFxuICAgICAgYmFja2dyb3VuZFxuICAgIH0pO1xuICAgIHRoaXMub3BlcmF0b3JMaXN0SWR4ID0gMDtcbiAgICB0aGlzLmdyYXBoaWNzUmVhZHkgPSB0cnVlO1xuXG4gICAgaWYgKHRoaXMuZ3JhcGhpY3NSZWFkeUNhbGxiYWNrKSB7XG4gICAgICB0aGlzLmdyYXBoaWNzUmVhZHlDYWxsYmFjaygpO1xuICAgIH1cbiAgfVxuXG4gIGNhbmNlbChlcnJvciA9IG51bGwpIHtcbiAgICB0aGlzLnJ1bm5pbmcgPSBmYWxzZTtcbiAgICB0aGlzLmNhbmNlbGxlZCA9IHRydWU7XG5cbiAgICBpZiAodGhpcy5nZngpIHtcbiAgICAgIHRoaXMuZ2Z4LmVuZERyYXdpbmcoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fY2FudmFzKSB7XG4gICAgICBJbnRlcm5hbFJlbmRlclRhc2suI2NhbnZhc0luVXNlLmRlbGV0ZSh0aGlzLl9jYW52YXMpO1xuICAgIH1cblxuICAgIHRoaXMuY2FsbGJhY2soZXJyb3IgfHwgbmV3IF9kaXNwbGF5X3V0aWxzLlJlbmRlcmluZ0NhbmNlbGxlZEV4Y2VwdGlvbihgUmVuZGVyaW5nIGNhbmNlbGxlZCwgcGFnZSAke3RoaXMuX3BhZ2VJbmRleCArIDF9YCwgXCJjYW52YXNcIikpO1xuICB9XG5cbiAgb3BlcmF0b3JMaXN0Q2hhbmdlZCgpIHtcbiAgICBpZiAoIXRoaXMuZ3JhcGhpY3NSZWFkeSkge1xuICAgICAgaWYgKCF0aGlzLmdyYXBoaWNzUmVhZHlDYWxsYmFjaykge1xuICAgICAgICB0aGlzLmdyYXBoaWNzUmVhZHlDYWxsYmFjayA9IHRoaXMuX2NvbnRpbnVlQm91bmQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdGVwcGVyKSB7XG4gICAgICB0aGlzLnN0ZXBwZXIudXBkYXRlT3BlcmF0b3JMaXN0KHRoaXMub3BlcmF0b3JMaXN0KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5ydW5uaW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fY29udGludWUoKTtcbiAgfVxuXG4gIF9jb250aW51ZSgpIHtcbiAgICB0aGlzLnJ1bm5pbmcgPSB0cnVlO1xuXG4gICAgaWYgKHRoaXMuY2FuY2VsbGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudGFzay5vbkNvbnRpbnVlKSB7XG4gICAgICB0aGlzLnRhc2sub25Db250aW51ZSh0aGlzLl9zY2hlZHVsZU5leHRCb3VuZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3NjaGVkdWxlTmV4dCgpO1xuICAgIH1cbiAgfVxuXG4gIF9zY2hlZHVsZU5leHQoKSB7XG4gICAgaWYgKHRoaXMuX3VzZVJlcXVlc3RBbmltYXRpb25GcmFtZSkge1xuICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuX25leHRCb3VuZCgpLmNhdGNoKHRoaXMuX2NhbmNlbEJvdW5kKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKHRoaXMuX25leHRCb3VuZCkuY2F0Y2godGhpcy5fY2FuY2VsQm91bmQpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIF9uZXh0KCkge1xuICAgIGlmICh0aGlzLmNhbmNlbGxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMub3BlcmF0b3JMaXN0SWR4ID0gdGhpcy5nZnguZXhlY3V0ZU9wZXJhdG9yTGlzdCh0aGlzLm9wZXJhdG9yTGlzdCwgdGhpcy5vcGVyYXRvckxpc3RJZHgsIHRoaXMuX2NvbnRpbnVlQm91bmQsIHRoaXMuc3RlcHBlcik7XG5cbiAgICBpZiAodGhpcy5vcGVyYXRvckxpc3RJZHggPT09IHRoaXMub3BlcmF0b3JMaXN0LmFyZ3NBcnJheS5sZW5ndGgpIHtcbiAgICAgIHRoaXMucnVubmluZyA9IGZhbHNlO1xuXG4gICAgICBpZiAodGhpcy5vcGVyYXRvckxpc3QubGFzdENodW5rKSB7XG4gICAgICAgIHRoaXMuZ2Z4LmVuZERyYXdpbmcoKTtcblxuICAgICAgICBpZiAodGhpcy5fY2FudmFzKSB7XG4gICAgICAgICAgSW50ZXJuYWxSZW5kZXJUYXNrLiNjYW52YXNJblVzZS5kZWxldGUodGhpcy5fY2FudmFzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2FsbGJhY2soKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxufVxuXG5jb25zdCB2ZXJzaW9uID0gJzIuMTQuMzA1JztcbmV4cG9ydHMudmVyc2lvbiA9IHZlcnNpb247XG5jb25zdCBidWlsZCA9ICdlYWFhOGI0YWQnO1xuZXhwb3J0cy5idWlsZCA9IGJ1aWxkO1xuXG4vKioqLyB9KSxcbi8qIDUgKi9cbi8qKiovICgoX191bnVzZWRfd2VicGFja19tb2R1bGUsIGV4cG9ydHMsIF9fd19wZGZqc19yZXF1aXJlX18pID0+IHtcblxuXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgKHtcbiAgdmFsdWU6IHRydWVcbn0pKTtcbmV4cG9ydHMuU3RhdFRpbWVyID0gZXhwb3J0cy5SZW5kZXJpbmdDYW5jZWxsZWRFeGNlcHRpb24gPSBleHBvcnRzLlBpeGVsc1BlckluY2ggPSBleHBvcnRzLlBhZ2VWaWV3cG9ydCA9IGV4cG9ydHMuUERGRGF0ZVN0cmluZyA9IGV4cG9ydHMuRE9NU3RhbmRhcmRGb250RGF0YUZhY3RvcnkgPSBleHBvcnRzLkRPTVNWR0ZhY3RvcnkgPSBleHBvcnRzLkRPTUNhbnZhc0ZhY3RvcnkgPSBleHBvcnRzLkRPTUNNYXBSZWFkZXJGYWN0b3J5ID0gdm9pZCAwO1xuZXhwb3J0cy5kZXByZWNhdGVkID0gZGVwcmVjYXRlZDtcbmV4cG9ydHMuZ2V0RmlsZW5hbWVGcm9tVXJsID0gZ2V0RmlsZW5hbWVGcm9tVXJsO1xuZXhwb3J0cy5nZXRQZGZGaWxlbmFtZUZyb21VcmwgPSBnZXRQZGZGaWxlbmFtZUZyb21Vcmw7XG5leHBvcnRzLmdldFhmYVBhZ2VWaWV3cG9ydCA9IGdldFhmYVBhZ2VWaWV3cG9ydDtcbmV4cG9ydHMuaXNEYXRhU2NoZW1lID0gaXNEYXRhU2NoZW1lO1xuZXhwb3J0cy5pc1BkZkZpbGUgPSBpc1BkZkZpbGU7XG5leHBvcnRzLmlzVmFsaWRGZXRjaFVybCA9IGlzVmFsaWRGZXRjaFVybDtcbmV4cG9ydHMubG9hZFNjcmlwdCA9IGxvYWRTY3JpcHQ7XG5cbnZhciBfYmFzZV9mYWN0b3J5ID0gX193X3BkZmpzX3JlcXVpcmVfXyg2KTtcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxuY29uc3QgU1ZHX05TID0gXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiO1xuXG5jbGFzcyBQaXhlbHNQZXJJbmNoIHtcbiAgc3RhdGljIENTUyA9IDk2LjA7XG4gIHN0YXRpYyBQREYgPSA3Mi4wO1xuICBzdGF0aWMgUERGX1RPX0NTU19VTklUUyA9IHRoaXMuQ1NTIC8gdGhpcy5QREY7XG59XG5cbmV4cG9ydHMuUGl4ZWxzUGVySW5jaCA9IFBpeGVsc1BlckluY2g7XG5cbmNsYXNzIERPTUNhbnZhc0ZhY3RvcnkgZXh0ZW5kcyBfYmFzZV9mYWN0b3J5LkJhc2VDYW52YXNGYWN0b3J5IHtcbiAgY29uc3RydWN0b3Ioe1xuICAgIG93bmVyRG9jdW1lbnQgPSBnbG9iYWxUaGlzLmRvY3VtZW50XG4gIH0gPSB7fSkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5fZG9jdW1lbnQgPSBvd25lckRvY3VtZW50O1xuICB9XG5cbiAgX2NyZWF0ZUNhbnZhcyh3aWR0aCwgaGVpZ2h0KSB7XG4gICAgY29uc3QgY2FudmFzID0gdGhpcy5fZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcblxuICAgIGNhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgIGNhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgcmV0dXJuIGNhbnZhcztcbiAgfVxuXG59XG5cbmV4cG9ydHMuRE9NQ2FudmFzRmFjdG9yeSA9IERPTUNhbnZhc0ZhY3Rvcnk7XG5cbmFzeW5jIGZ1bmN0aW9uIGZldGNoRGF0YSh1cmwsIGFzVHlwZWRBcnJheSA9IGZhbHNlKSB7XG4gIGlmIChpc1ZhbGlkRmV0Y2hVcmwodXJsLCBkb2N1bWVudC5iYXNlVVJJKSkge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsKTtcblxuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihyZXNwb25zZS5zdGF0dXNUZXh0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXNUeXBlZEFycmF5ID8gbmV3IFVpbnQ4QXJyYXkoYXdhaXQgcmVzcG9uc2UuYXJyYXlCdWZmZXIoKSkgOiAoMCwgX3V0aWwuc3RyaW5nVG9CeXRlcykoYXdhaXQgcmVzcG9uc2UudGV4dCgpKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgIHJlcXVlc3Qub3BlbihcIkdFVFwiLCB1cmwsIHRydWUpO1xuXG4gICAgaWYgKGFzVHlwZWRBcnJheSkge1xuICAgICAgcmVxdWVzdC5yZXNwb25zZVR5cGUgPSBcImFycmF5YnVmZmVyXCI7XG4gICAgfVxuXG4gICAgcmVxdWVzdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICBpZiAocmVxdWVzdC5yZWFkeVN0YXRlICE9PSBYTUxIdHRwUmVxdWVzdC5ET05FKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlcXVlc3Quc3RhdHVzID09PSAyMDAgfHwgcmVxdWVzdC5zdGF0dXMgPT09IDApIHtcbiAgICAgICAgbGV0IGRhdGE7XG5cbiAgICAgICAgaWYgKGFzVHlwZWRBcnJheSAmJiByZXF1ZXN0LnJlc3BvbnNlKSB7XG4gICAgICAgICAgZGF0YSA9IG5ldyBVaW50OEFycmF5KHJlcXVlc3QucmVzcG9uc2UpO1xuICAgICAgICB9IGVsc2UgaWYgKCFhc1R5cGVkQXJyYXkgJiYgcmVxdWVzdC5yZXNwb25zZVRleHQpIHtcbiAgICAgICAgICBkYXRhID0gKDAsIF91dGlsLnN0cmluZ1RvQnl0ZXMpKHJlcXVlc3QucmVzcG9uc2VUZXh0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkYXRhKSB7XG4gICAgICAgICAgcmVzb2x2ZShkYXRhKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmVqZWN0KG5ldyBFcnJvcihyZXF1ZXN0LnN0YXR1c1RleHQpKTtcbiAgICB9O1xuXG4gICAgcmVxdWVzdC5zZW5kKG51bGwpO1xuICB9KTtcbn1cblxuY2xhc3MgRE9NQ01hcFJlYWRlckZhY3RvcnkgZXh0ZW5kcyBfYmFzZV9mYWN0b3J5LkJhc2VDTWFwUmVhZGVyRmFjdG9yeSB7XG4gIF9mZXRjaERhdGEodXJsLCBjb21wcmVzc2lvblR5cGUpIHtcbiAgICByZXR1cm4gZmV0Y2hEYXRhKHVybCwgdGhpcy5pc0NvbXByZXNzZWQpLnRoZW4oZGF0YSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjTWFwRGF0YTogZGF0YSxcbiAgICAgICAgY29tcHJlc3Npb25UeXBlXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbn1cblxuZXhwb3J0cy5ET01DTWFwUmVhZGVyRmFjdG9yeSA9IERPTUNNYXBSZWFkZXJGYWN0b3J5O1xuXG5jbGFzcyBET01TdGFuZGFyZEZvbnREYXRhRmFjdG9yeSBleHRlbmRzIF9iYXNlX2ZhY3RvcnkuQmFzZVN0YW5kYXJkRm9udERhdGFGYWN0b3J5IHtcbiAgX2ZldGNoRGF0YSh1cmwpIHtcbiAgICByZXR1cm4gZmV0Y2hEYXRhKHVybCwgdHJ1ZSk7XG4gIH1cblxufVxuXG5leHBvcnRzLkRPTVN0YW5kYXJkRm9udERhdGFGYWN0b3J5ID0gRE9NU3RhbmRhcmRGb250RGF0YUZhY3Rvcnk7XG5cbmNsYXNzIERPTVNWR0ZhY3RvcnkgZXh0ZW5kcyBfYmFzZV9mYWN0b3J5LkJhc2VTVkdGYWN0b3J5IHtcbiAgX2NyZWF0ZVNWRyh0eXBlKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsIHR5cGUpO1xuICB9XG5cbn1cblxuZXhwb3J0cy5ET01TVkdGYWN0b3J5ID0gRE9NU1ZHRmFjdG9yeTtcblxuY2xhc3MgUGFnZVZpZXdwb3J0IHtcbiAgY29uc3RydWN0b3Ioe1xuICAgIHZpZXdCb3gsXG4gICAgc2NhbGUsXG4gICAgcm90YXRpb24sXG4gICAgb2Zmc2V0WCA9IDAsXG4gICAgb2Zmc2V0WSA9IDAsXG4gICAgZG9udEZsaXAgPSBmYWxzZVxuICB9KSB7XG4gICAgdGhpcy52aWV3Qm94ID0gdmlld0JveDtcbiAgICB0aGlzLnNjYWxlID0gc2NhbGU7XG4gICAgdGhpcy5yb3RhdGlvbiA9IHJvdGF0aW9uO1xuICAgIHRoaXMub2Zmc2V0WCA9IG9mZnNldFg7XG4gICAgdGhpcy5vZmZzZXRZID0gb2Zmc2V0WTtcbiAgICBjb25zdCBjZW50ZXJYID0gKHZpZXdCb3hbMl0gKyB2aWV3Qm94WzBdKSAvIDI7XG4gICAgY29uc3QgY2VudGVyWSA9ICh2aWV3Qm94WzNdICsgdmlld0JveFsxXSkgLyAyO1xuICAgIGxldCByb3RhdGVBLCByb3RhdGVCLCByb3RhdGVDLCByb3RhdGVEO1xuICAgIHJvdGF0aW9uICU9IDM2MDtcblxuICAgIGlmIChyb3RhdGlvbiA8IDApIHtcbiAgICAgIHJvdGF0aW9uICs9IDM2MDtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHJvdGF0aW9uKSB7XG4gICAgICBjYXNlIDE4MDpcbiAgICAgICAgcm90YXRlQSA9IC0xO1xuICAgICAgICByb3RhdGVCID0gMDtcbiAgICAgICAgcm90YXRlQyA9IDA7XG4gICAgICAgIHJvdGF0ZUQgPSAxO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSA5MDpcbiAgICAgICAgcm90YXRlQSA9IDA7XG4gICAgICAgIHJvdGF0ZUIgPSAxO1xuICAgICAgICByb3RhdGVDID0gMTtcbiAgICAgICAgcm90YXRlRCA9IDA7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIDI3MDpcbiAgICAgICAgcm90YXRlQSA9IDA7XG4gICAgICAgIHJvdGF0ZUIgPSAtMTtcbiAgICAgICAgcm90YXRlQyA9IC0xO1xuICAgICAgICByb3RhdGVEID0gMDtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcm90YXRlQSA9IDE7XG4gICAgICAgIHJvdGF0ZUIgPSAwO1xuICAgICAgICByb3RhdGVDID0gMDtcbiAgICAgICAgcm90YXRlRCA9IC0xO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUGFnZVZpZXdwb3J0OiBJbnZhbGlkIHJvdGF0aW9uLCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgOTAgZGVncmVlcy5cIik7XG4gICAgfVxuXG4gICAgaWYgKGRvbnRGbGlwKSB7XG4gICAgICByb3RhdGVDID0gLXJvdGF0ZUM7XG4gICAgICByb3RhdGVEID0gLXJvdGF0ZUQ7XG4gICAgfVxuXG4gICAgbGV0IG9mZnNldENhbnZhc1gsIG9mZnNldENhbnZhc1k7XG4gICAgbGV0IHdpZHRoLCBoZWlnaHQ7XG5cbiAgICBpZiAocm90YXRlQSA9PT0gMCkge1xuICAgICAgb2Zmc2V0Q2FudmFzWCA9IE1hdGguYWJzKGNlbnRlclkgLSB2aWV3Qm94WzFdKSAqIHNjYWxlICsgb2Zmc2V0WDtcbiAgICAgIG9mZnNldENhbnZhc1kgPSBNYXRoLmFicyhjZW50ZXJYIC0gdmlld0JveFswXSkgKiBzY2FsZSArIG9mZnNldFk7XG4gICAgICB3aWR0aCA9IE1hdGguYWJzKHZpZXdCb3hbM10gLSB2aWV3Qm94WzFdKSAqIHNjYWxlO1xuICAgICAgaGVpZ2h0ID0gTWF0aC5hYnModmlld0JveFsyXSAtIHZpZXdCb3hbMF0pICogc2NhbGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9mZnNldENhbnZhc1ggPSBNYXRoLmFicyhjZW50ZXJYIC0gdmlld0JveFswXSkgKiBzY2FsZSArIG9mZnNldFg7XG4gICAgICBvZmZzZXRDYW52YXNZID0gTWF0aC5hYnMoY2VudGVyWSAtIHZpZXdCb3hbMV0pICogc2NhbGUgKyBvZmZzZXRZO1xuICAgICAgd2lkdGggPSBNYXRoLmFicyh2aWV3Qm94WzJdIC0gdmlld0JveFswXSkgKiBzY2FsZTtcbiAgICAgIGhlaWdodCA9IE1hdGguYWJzKHZpZXdCb3hbM10gLSB2aWV3Qm94WzFdKSAqIHNjYWxlO1xuICAgIH1cblxuICAgIHRoaXMudHJhbnNmb3JtID0gW3JvdGF0ZUEgKiBzY2FsZSwgcm90YXRlQiAqIHNjYWxlLCByb3RhdGVDICogc2NhbGUsIHJvdGF0ZUQgKiBzY2FsZSwgb2Zmc2V0Q2FudmFzWCAtIHJvdGF0ZUEgKiBzY2FsZSAqIGNlbnRlclggLSByb3RhdGVDICogc2NhbGUgKiBjZW50ZXJZLCBvZmZzZXRDYW52YXNZIC0gcm90YXRlQiAqIHNjYWxlICogY2VudGVyWCAtIHJvdGF0ZUQgKiBzY2FsZSAqIGNlbnRlclldO1xuICAgIHRoaXMud2lkdGggPSB3aWR0aDtcbiAgICB0aGlzLmhlaWdodCA9IGhlaWdodDtcbiAgfVxuXG4gIGNsb25lKHtcbiAgICBzY2FsZSA9IHRoaXMuc2NhbGUsXG4gICAgcm90YXRpb24gPSB0aGlzLnJvdGF0aW9uLFxuICAgIG9mZnNldFggPSB0aGlzLm9mZnNldFgsXG4gICAgb2Zmc2V0WSA9IHRoaXMub2Zmc2V0WSxcbiAgICBkb250RmxpcCA9IGZhbHNlXG4gIH0gPSB7fSkge1xuICAgIHJldHVybiBuZXcgUGFnZVZpZXdwb3J0KHtcbiAgICAgIHZpZXdCb3g6IHRoaXMudmlld0JveC5zbGljZSgpLFxuICAgICAgc2NhbGUsXG4gICAgICByb3RhdGlvbixcbiAgICAgIG9mZnNldFgsXG4gICAgICBvZmZzZXRZLFxuICAgICAgZG9udEZsaXBcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnZlcnRUb1ZpZXdwb3J0UG9pbnQoeCwgeSkge1xuICAgIHJldHVybiBfdXRpbC5VdGlsLmFwcGx5VHJhbnNmb3JtKFt4LCB5XSwgdGhpcy50cmFuc2Zvcm0pO1xuICB9XG5cbiAgY29udmVydFRvVmlld3BvcnRSZWN0YW5nbGUocmVjdCkge1xuICAgIGNvbnN0IHRvcExlZnQgPSBfdXRpbC5VdGlsLmFwcGx5VHJhbnNmb3JtKFtyZWN0WzBdLCByZWN0WzFdXSwgdGhpcy50cmFuc2Zvcm0pO1xuXG4gICAgY29uc3QgYm90dG9tUmlnaHQgPSBfdXRpbC5VdGlsLmFwcGx5VHJhbnNmb3JtKFtyZWN0WzJdLCByZWN0WzNdXSwgdGhpcy50cmFuc2Zvcm0pO1xuXG4gICAgcmV0dXJuIFt0b3BMZWZ0WzBdLCB0b3BMZWZ0WzFdLCBib3R0b21SaWdodFswXSwgYm90dG9tUmlnaHRbMV1dO1xuICB9XG5cbiAgY29udmVydFRvUGRmUG9pbnQoeCwgeSkge1xuICAgIHJldHVybiBfdXRpbC5VdGlsLmFwcGx5SW52ZXJzZVRyYW5zZm9ybShbeCwgeV0sIHRoaXMudHJhbnNmb3JtKTtcbiAgfVxuXG59XG5cbmV4cG9ydHMuUGFnZVZpZXdwb3J0ID0gUGFnZVZpZXdwb3J0O1xuXG5jbGFzcyBSZW5kZXJpbmdDYW5jZWxsZWRFeGNlcHRpb24gZXh0ZW5kcyBfdXRpbC5CYXNlRXhjZXB0aW9uIHtcbiAgY29uc3RydWN0b3IobXNnLCB0eXBlKSB7XG4gICAgc3VwZXIobXNnLCBcIlJlbmRlcmluZ0NhbmNlbGxlZEV4Y2VwdGlvblwiKTtcbiAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICB9XG5cbn1cblxuZXhwb3J0cy5SZW5kZXJpbmdDYW5jZWxsZWRFeGNlcHRpb24gPSBSZW5kZXJpbmdDYW5jZWxsZWRFeGNlcHRpb247XG5cbmZ1bmN0aW9uIGlzRGF0YVNjaGVtZSh1cmwpIHtcbiAgY29uc3QgaWkgPSB1cmwubGVuZ3RoO1xuICBsZXQgaSA9IDA7XG5cbiAgd2hpbGUgKGkgPCBpaSAmJiB1cmxbaV0udHJpbSgpID09PSBcIlwiKSB7XG4gICAgaSsrO1xuICB9XG5cbiAgcmV0dXJuIHVybC5zdWJzdHJpbmcoaSwgaSArIDUpLnRvTG93ZXJDYXNlKCkgPT09IFwiZGF0YTpcIjtcbn1cblxuZnVuY3Rpb24gaXNQZGZGaWxlKGZpbGVuYW1lKSB7XG4gIHJldHVybiB0eXBlb2YgZmlsZW5hbWUgPT09IFwic3RyaW5nXCIgJiYgL1xcLnBkZiQvaS50ZXN0KGZpbGVuYW1lKTtcbn1cblxuZnVuY3Rpb24gZ2V0RmlsZW5hbWVGcm9tVXJsKHVybCkge1xuICBjb25zdCBhbmNob3IgPSB1cmwuaW5kZXhPZihcIiNcIik7XG4gIGNvbnN0IHF1ZXJ5ID0gdXJsLmluZGV4T2YoXCI/XCIpO1xuICBjb25zdCBlbmQgPSBNYXRoLm1pbihhbmNob3IgPiAwID8gYW5jaG9yIDogdXJsLmxlbmd0aCwgcXVlcnkgPiAwID8gcXVlcnkgOiB1cmwubGVuZ3RoKTtcbiAgcmV0dXJuIHVybC5zdWJzdHJpbmcodXJsLmxhc3RJbmRleE9mKFwiL1wiLCBlbmQpICsgMSwgZW5kKTtcbn1cblxuZnVuY3Rpb24gZ2V0UGRmRmlsZW5hbWVGcm9tVXJsKHVybCwgZGVmYXVsdEZpbGVuYW1lID0gXCJkb2N1bWVudC5wZGZcIikge1xuICBpZiAodHlwZW9mIHVybCAhPT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiBkZWZhdWx0RmlsZW5hbWU7XG4gIH1cblxuICBpZiAoaXNEYXRhU2NoZW1lKHVybCkpIHtcbiAgICAoMCwgX3V0aWwud2FybikoJ2dldFBkZkZpbGVuYW1lRnJvbVVybDogaWdub3JlIFwiZGF0YTpcIi1VUkwgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMuJyk7XG4gICAgcmV0dXJuIGRlZmF1bHRGaWxlbmFtZTtcbiAgfVxuXG4gIGNvbnN0IHJlVVJJID0gL14oPzooPzpbXjpdKzopP1xcL1xcL1teL10rKT8oW14/I10qKShcXD9bXiNdKik/KCMuKik/JC87XG4gIGNvbnN0IHJlRmlsZW5hbWUgPSAvW14vPyM9XStcXC5wZGZcXGIoPyEuKlxcLnBkZlxcYikvaTtcbiAgY29uc3Qgc3BsaXRVUkkgPSByZVVSSS5leGVjKHVybCk7XG4gIGxldCBzdWdnZXN0ZWRGaWxlbmFtZSA9IHJlRmlsZW5hbWUuZXhlYyhzcGxpdFVSSVsxXSkgfHwgcmVGaWxlbmFtZS5leGVjKHNwbGl0VVJJWzJdKSB8fCByZUZpbGVuYW1lLmV4ZWMoc3BsaXRVUklbM10pO1xuXG4gIGlmIChzdWdnZXN0ZWRGaWxlbmFtZSkge1xuICAgIHN1Z2dlc3RlZEZpbGVuYW1lID0gc3VnZ2VzdGVkRmlsZW5hbWVbMF07XG5cbiAgICBpZiAoc3VnZ2VzdGVkRmlsZW5hbWUuaW5jbHVkZXMoXCIlXCIpKSB7XG4gICAgICB0cnkge1xuICAgICAgICBzdWdnZXN0ZWRGaWxlbmFtZSA9IHJlRmlsZW5hbWUuZXhlYyhkZWNvZGVVUklDb21wb25lbnQoc3VnZ2VzdGVkRmlsZW5hbWUpKVswXTtcbiAgICAgIH0gY2F0Y2ggKGV4KSB7fVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzdWdnZXN0ZWRGaWxlbmFtZSB8fCBkZWZhdWx0RmlsZW5hbWU7XG59XG5cbmNsYXNzIFN0YXRUaW1lciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuc3RhcnRlZCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgdGhpcy50aW1lcyA9IFtdO1xuICB9XG5cbiAgdGltZShuYW1lKSB7XG4gICAgaWYgKG5hbWUgaW4gdGhpcy5zdGFydGVkKSB7XG4gICAgICAoMCwgX3V0aWwud2FybikoYFRpbWVyIGlzIGFscmVhZHkgcnVubmluZyBmb3IgJHtuYW1lfWApO1xuICAgIH1cblxuICAgIHRoaXMuc3RhcnRlZFtuYW1lXSA9IERhdGUubm93KCk7XG4gIH1cblxuICB0aW1lRW5kKG5hbWUpIHtcbiAgICBpZiAoIShuYW1lIGluIHRoaXMuc3RhcnRlZCkpIHtcbiAgICAgICgwLCBfdXRpbC53YXJuKShgVGltZXIgaGFzIG5vdCBiZWVuIHN0YXJ0ZWQgZm9yICR7bmFtZX1gKTtcbiAgICB9XG5cbiAgICB0aGlzLnRpbWVzLnB1c2goe1xuICAgICAgbmFtZSxcbiAgICAgIHN0YXJ0OiB0aGlzLnN0YXJ0ZWRbbmFtZV0sXG4gICAgICBlbmQ6IERhdGUubm93KClcbiAgICB9KTtcbiAgICBkZWxldGUgdGhpcy5zdGFydGVkW25hbWVdO1xuICB9XG5cbiAgdG9TdHJpbmcoKSB7XG4gICAgY29uc3Qgb3V0QnVmID0gW107XG4gICAgbGV0IGxvbmdlc3QgPSAwO1xuXG4gICAgZm9yIChjb25zdCB0aW1lIG9mIHRoaXMudGltZXMpIHtcbiAgICAgIGNvbnN0IG5hbWUgPSB0aW1lLm5hbWU7XG5cbiAgICAgIGlmIChuYW1lLmxlbmd0aCA+IGxvbmdlc3QpIHtcbiAgICAgICAgbG9uZ2VzdCA9IG5hbWUubGVuZ3RoO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgdGltZSBvZiB0aGlzLnRpbWVzKSB7XG4gICAgICBjb25zdCBkdXJhdGlvbiA9IHRpbWUuZW5kIC0gdGltZS5zdGFydDtcbiAgICAgIG91dEJ1Zi5wdXNoKGAke3RpbWUubmFtZS5wYWRFbmQobG9uZ2VzdCl9ICR7ZHVyYXRpb259bXNcXG5gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0QnVmLmpvaW4oXCJcIik7XG4gIH1cblxufVxuXG5leHBvcnRzLlN0YXRUaW1lciA9IFN0YXRUaW1lcjtcblxuZnVuY3Rpb24gaXNWYWxpZEZldGNoVXJsKHVybCwgYmFzZVVybCkge1xuICB0cnkge1xuICAgIGNvbnN0IHtcbiAgICAgIHByb3RvY29sXG4gICAgfSA9IGJhc2VVcmwgPyBuZXcgVVJMKHVybCwgYmFzZVVybCkgOiBuZXcgVVJMKHVybCk7XG4gICAgcmV0dXJuIHByb3RvY29sID09PSBcImh0dHA6XCIgfHwgcHJvdG9jb2wgPT09IFwiaHR0cHM6XCI7XG4gIH0gY2F0Y2ggKGV4KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGxvYWRTY3JpcHQoc3JjLCByZW1vdmVTY3JpcHRFbGVtZW50ID0gZmFsc2UpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic2NyaXB0XCIpO1xuICAgIHNjcmlwdC5zcmMgPSBzcmM7XG5cbiAgICBzY3JpcHQub25sb2FkID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgaWYgKHJlbW92ZVNjcmlwdEVsZW1lbnQpIHtcbiAgICAgICAgc2NyaXB0LnJlbW92ZSgpO1xuICAgICAgfVxuXG4gICAgICByZXNvbHZlKGV2dCk7XG4gICAgfTtcblxuICAgIHNjcmlwdC5vbmVycm9yID0gZnVuY3Rpb24gKCkge1xuICAgICAgcmVqZWN0KG5ldyBFcnJvcihgQ2Fubm90IGxvYWQgc2NyaXB0IGF0OiAke3NjcmlwdC5zcmN9YCkpO1xuICAgIH07XG5cbiAgICAoZG9jdW1lbnQuaGVhZCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLmFwcGVuZENoaWxkKHNjcmlwdCk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBkZXByZWNhdGVkKGRldGFpbHMpIHtcbiAgY29uc29sZS5sb2coXCJEZXByZWNhdGVkIEFQSSB1c2FnZTogXCIgKyBkZXRhaWxzKTtcbn1cblxubGV0IHBkZkRhdGVTdHJpbmdSZWdleDtcblxuY2xhc3MgUERGRGF0ZVN0cmluZyB7XG4gIHN0YXRpYyB0b0RhdGVPYmplY3QoaW5wdXQpIHtcbiAgICBpZiAoIWlucHV0IHx8IHR5cGVvZiBpbnB1dCAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgaWYgKCFwZGZEYXRlU3RyaW5nUmVnZXgpIHtcbiAgICAgIHBkZkRhdGVTdHJpbmdSZWdleCA9IG5ldyBSZWdFeHAoXCJeRDpcIiArIFwiKFxcXFxkezR9KVwiICsgXCIoXFxcXGR7Mn0pP1wiICsgXCIoXFxcXGR7Mn0pP1wiICsgXCIoXFxcXGR7Mn0pP1wiICsgXCIoXFxcXGR7Mn0pP1wiICsgXCIoXFxcXGR7Mn0pP1wiICsgXCIoW1p8K3wtXSk/XCIgKyBcIihcXFxcZHsyfSk/XCIgKyBcIic/XCIgKyBcIihcXFxcZHsyfSk/XCIgKyBcIic/XCIpO1xuICAgIH1cblxuICAgIGNvbnN0IG1hdGNoZXMgPSBwZGZEYXRlU3RyaW5nUmVnZXguZXhlYyhpbnB1dCk7XG5cbiAgICBpZiAoIW1hdGNoZXMpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHllYXIgPSBwYXJzZUludChtYXRjaGVzWzFdLCAxMCk7XG4gICAgbGV0IG1vbnRoID0gcGFyc2VJbnQobWF0Y2hlc1syXSwgMTApO1xuICAgIG1vbnRoID0gbW9udGggPj0gMSAmJiBtb250aCA8PSAxMiA/IG1vbnRoIC0gMSA6IDA7XG4gICAgbGV0IGRheSA9IHBhcnNlSW50KG1hdGNoZXNbM10sIDEwKTtcbiAgICBkYXkgPSBkYXkgPj0gMSAmJiBkYXkgPD0gMzEgPyBkYXkgOiAxO1xuICAgIGxldCBob3VyID0gcGFyc2VJbnQobWF0Y2hlc1s0XSwgMTApO1xuICAgIGhvdXIgPSBob3VyID49IDAgJiYgaG91ciA8PSAyMyA/IGhvdXIgOiAwO1xuICAgIGxldCBtaW51dGUgPSBwYXJzZUludChtYXRjaGVzWzVdLCAxMCk7XG4gICAgbWludXRlID0gbWludXRlID49IDAgJiYgbWludXRlIDw9IDU5ID8gbWludXRlIDogMDtcbiAgICBsZXQgc2Vjb25kID0gcGFyc2VJbnQobWF0Y2hlc1s2XSwgMTApO1xuICAgIHNlY29uZCA9IHNlY29uZCA+PSAwICYmIHNlY29uZCA8PSA1OSA/IHNlY29uZCA6IDA7XG4gICAgY29uc3QgdW5pdmVyc2FsVGltZVJlbGF0aW9uID0gbWF0Y2hlc1s3XSB8fCBcIlpcIjtcbiAgICBsZXQgb2Zmc2V0SG91ciA9IHBhcnNlSW50KG1hdGNoZXNbOF0sIDEwKTtcbiAgICBvZmZzZXRIb3VyID0gb2Zmc2V0SG91ciA+PSAwICYmIG9mZnNldEhvdXIgPD0gMjMgPyBvZmZzZXRIb3VyIDogMDtcbiAgICBsZXQgb2Zmc2V0TWludXRlID0gcGFyc2VJbnQobWF0Y2hlc1s5XSwgMTApIHx8IDA7XG4gICAgb2Zmc2V0TWludXRlID0gb2Zmc2V0TWludXRlID49IDAgJiYgb2Zmc2V0TWludXRlIDw9IDU5ID8gb2Zmc2V0TWludXRlIDogMDtcblxuICAgIGlmICh1bml2ZXJzYWxUaW1lUmVsYXRpb24gPT09IFwiLVwiKSB7XG4gICAgICBob3VyICs9IG9mZnNldEhvdXI7XG4gICAgICBtaW51dGUgKz0gb2Zmc2V0TWludXRlO1xuICAgIH0gZWxzZSBpZiAodW5pdmVyc2FsVGltZVJlbGF0aW9uID09PSBcIitcIikge1xuICAgICAgaG91ciAtPSBvZmZzZXRIb3VyO1xuICAgICAgbWludXRlIC09IG9mZnNldE1pbnV0ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IERhdGUoRGF0ZS5VVEMoeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBzZWNvbmQpKTtcbiAgfVxuXG59XG5cbmV4cG9ydHMuUERGRGF0ZVN0cmluZyA9IFBERkRhdGVTdHJpbmc7XG5cbmZ1bmN0aW9uIGdldFhmYVBhZ2VWaWV3cG9ydCh4ZmFQYWdlLCB7XG4gIHNjYWxlID0gMSxcbiAgcm90YXRpb24gPSAwXG59KSB7XG4gIGNvbnN0IHtcbiAgICB3aWR0aCxcbiAgICBoZWlnaHRcbiAgfSA9IHhmYVBhZ2UuYXR0cmlidXRlcy5zdHlsZTtcbiAgY29uc3Qgdmlld0JveCA9IFswLCAwLCBwYXJzZUludCh3aWR0aCksIHBhcnNlSW50KGhlaWdodCldO1xuICByZXR1cm4gbmV3IFBhZ2VWaWV3cG9ydCh7XG4gICAgdmlld0JveCxcbiAgICBzY2FsZSxcbiAgICByb3RhdGlvblxuICB9KTtcbn1cblxuLyoqKi8gfSksXG4vKiA2ICovXG4vKioqLyAoKF9fdW51c2VkX3dlYnBhY2tfbW9kdWxlLCBleHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5leHBvcnRzLkJhc2VTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSA9IGV4cG9ydHMuQmFzZVNWR0ZhY3RvcnkgPSBleHBvcnRzLkJhc2VDYW52YXNGYWN0b3J5ID0gZXhwb3J0cy5CYXNlQ01hcFJlYWRlckZhY3RvcnkgPSB2b2lkIDA7XG5cbnZhciBfdXRpbCA9IF9fd19wZGZqc19yZXF1aXJlX18oMSk7XG5cbmNsYXNzIEJhc2VDYW52YXNGYWN0b3J5IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgaWYgKHRoaXMuY29uc3RydWN0b3IgPT09IEJhc2VDYW52YXNGYWN0b3J5KSB7XG4gICAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiQ2Fubm90IGluaXRpYWxpemUgQmFzZUNhbnZhc0ZhY3RvcnkuXCIpO1xuICAgIH1cbiAgfVxuXG4gIGNyZWF0ZSh3aWR0aCwgaGVpZ2h0KSB7XG4gICAgaWYgKHdpZHRoIDw9IDAgfHwgaGVpZ2h0IDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgY2FudmFzIHNpemVcIik7XG4gICAgfVxuXG4gICAgY29uc3QgY2FudmFzID0gdGhpcy5fY3JlYXRlQ2FudmFzKHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNhbnZhcyxcbiAgICAgIGNvbnRleHQ6IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIilcbiAgICB9O1xuICB9XG5cbiAgcmVzZXQoY2FudmFzQW5kQ29udGV4dCwgd2lkdGgsIGhlaWdodCkge1xuICAgIGlmICghY2FudmFzQW5kQ29udGV4dC5jYW52YXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbnZhcyBpcyBub3Qgc3BlY2lmaWVkXCIpO1xuICAgIH1cblxuICAgIGlmICh3aWR0aCA8PSAwIHx8IGhlaWdodCA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGNhbnZhcyBzaXplXCIpO1xuICAgIH1cblxuICAgIGNhbnZhc0FuZENvbnRleHQuY2FudmFzLndpZHRoID0gd2lkdGg7XG4gICAgY2FudmFzQW5kQ29udGV4dC5jYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xuICB9XG5cbiAgZGVzdHJveShjYW52YXNBbmRDb250ZXh0KSB7XG4gICAgaWYgKCFjYW52YXNBbmRDb250ZXh0LmNhbnZhcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FudmFzIGlzIG5vdCBzcGVjaWZpZWRcIik7XG4gICAgfVxuXG4gICAgY2FudmFzQW5kQ29udGV4dC5jYW52YXMud2lkdGggPSAwO1xuICAgIGNhbnZhc0FuZENvbnRleHQuY2FudmFzLmhlaWdodCA9IDA7XG4gICAgY2FudmFzQW5kQ29udGV4dC5jYW52YXMgPSBudWxsO1xuICAgIGNhbnZhc0FuZENvbnRleHQuY29udGV4dCA9IG51bGw7XG4gIH1cblxuICBfY3JlYXRlQ2FudmFzKHdpZHRoLCBoZWlnaHQpIHtcbiAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiQWJzdHJhY3QgbWV0aG9kIGBfY3JlYXRlQ2FudmFzYCBjYWxsZWQuXCIpO1xuICB9XG5cbn1cblxuZXhwb3J0cy5CYXNlQ2FudmFzRmFjdG9yeSA9IEJhc2VDYW52YXNGYWN0b3J5O1xuXG5jbGFzcyBCYXNlQ01hcFJlYWRlckZhY3Rvcnkge1xuICBjb25zdHJ1Y3Rvcih7XG4gICAgYmFzZVVybCA9IG51bGwsXG4gICAgaXNDb21wcmVzc2VkID0gZmFsc2VcbiAgfSkge1xuICAgIGlmICh0aGlzLmNvbnN0cnVjdG9yID09PSBCYXNlQ01hcFJlYWRlckZhY3RvcnkpIHtcbiAgICAgICgwLCBfdXRpbC51bnJlYWNoYWJsZSkoXCJDYW5ub3QgaW5pdGlhbGl6ZSBCYXNlQ01hcFJlYWRlckZhY3RvcnkuXCIpO1xuICAgIH1cblxuICAgIHRoaXMuYmFzZVVybCA9IGJhc2VVcmw7XG4gICAgdGhpcy5pc0NvbXByZXNzZWQgPSBpc0NvbXByZXNzZWQ7XG4gIH1cblxuICBhc3luYyBmZXRjaCh7XG4gICAgbmFtZVxuICB9KSB7XG4gICAgaWYgKCF0aGlzLmJhc2VVcmwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIENNYXAgXCJiYXNlVXJsXCIgcGFyYW1ldGVyIG11c3QgYmUgc3BlY2lmaWVkLCBlbnN1cmUgdGhhdCAnICsgJ3RoZSBcImNNYXBVcmxcIiBhbmQgXCJjTWFwUGFja2VkXCIgQVBJIHBhcmFtZXRlcnMgYXJlIHByb3ZpZGVkLicpO1xuICAgIH1cblxuICAgIGlmICghbmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ01hcCBuYW1lIG11c3QgYmUgc3BlY2lmaWVkLlwiKTtcbiAgICB9XG5cbiAgICBjb25zdCB1cmwgPSB0aGlzLmJhc2VVcmwgKyBuYW1lICsgKHRoaXMuaXNDb21wcmVzc2VkID8gXCIuYmNtYXBcIiA6IFwiXCIpO1xuICAgIGNvbnN0IGNvbXByZXNzaW9uVHlwZSA9IHRoaXMuaXNDb21wcmVzc2VkID8gX3V0aWwuQ01hcENvbXByZXNzaW9uVHlwZS5CSU5BUlkgOiBfdXRpbC5DTWFwQ29tcHJlc3Npb25UeXBlLk5PTkU7XG4gICAgcmV0dXJuIHRoaXMuX2ZldGNoRGF0YSh1cmwsIGNvbXByZXNzaW9uVHlwZSkuY2F0Y2gocmVhc29uID0+IHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGxvYWQgJHt0aGlzLmlzQ29tcHJlc3NlZCA/IFwiYmluYXJ5IFwiIDogXCJcIn1DTWFwIGF0OiAke3VybH1gKTtcbiAgICB9KTtcbiAgfVxuXG4gIF9mZXRjaERhdGEodXJsLCBjb21wcmVzc2lvblR5cGUpIHtcbiAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiQWJzdHJhY3QgbWV0aG9kIGBfZmV0Y2hEYXRhYCBjYWxsZWQuXCIpO1xuICB9XG5cbn1cblxuZXhwb3J0cy5CYXNlQ01hcFJlYWRlckZhY3RvcnkgPSBCYXNlQ01hcFJlYWRlckZhY3Rvcnk7XG5cbmNsYXNzIEJhc2VTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSB7XG4gIGNvbnN0cnVjdG9yKHtcbiAgICBiYXNlVXJsID0gbnVsbFxuICB9KSB7XG4gICAgaWYgKHRoaXMuY29uc3RydWN0b3IgPT09IEJhc2VTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSkge1xuICAgICAgKDAsIF91dGlsLnVucmVhY2hhYmxlKShcIkNhbm5vdCBpbml0aWFsaXplIEJhc2VTdGFuZGFyZEZvbnREYXRhRmFjdG9yeS5cIik7XG4gICAgfVxuXG4gICAgdGhpcy5iYXNlVXJsID0gYmFzZVVybDtcbiAgfVxuXG4gIGFzeW5jIGZldGNoKHtcbiAgICBmaWxlbmFtZVxuICB9KSB7XG4gICAgaWYgKCF0aGlzLmJhc2VVcmwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIHN0YW5kYXJkIGZvbnQgXCJiYXNlVXJsXCIgcGFyYW1ldGVyIG11c3QgYmUgc3BlY2lmaWVkLCBlbnN1cmUgdGhhdCAnICsgJ3RoZSBcInN0YW5kYXJkRm9udERhdGFVcmxcIiBBUEkgcGFyYW1ldGVyIGlzIHByb3ZpZGVkLicpO1xuICAgIH1cblxuICAgIGlmICghZmlsZW5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkZvbnQgZmlsZW5hbWUgbXVzdCBiZSBzcGVjaWZpZWQuXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IHVybCA9IGAke3RoaXMuYmFzZVVybH0ke2ZpbGVuYW1lfWA7XG4gICAgcmV0dXJuIHRoaXMuX2ZldGNoRGF0YSh1cmwpLmNhdGNoKHJlYXNvbiA9PiB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBsb2FkIGZvbnQgZGF0YSBhdDogJHt1cmx9YCk7XG4gICAgfSk7XG4gIH1cblxuICBfZmV0Y2hEYXRhKHVybCkge1xuICAgICgwLCBfdXRpbC51bnJlYWNoYWJsZSkoXCJBYnN0cmFjdCBtZXRob2QgYF9mZXRjaERhdGFgIGNhbGxlZC5cIik7XG4gIH1cblxufVxuXG5leHBvcnRzLkJhc2VTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSA9IEJhc2VTdGFuZGFyZEZvbnREYXRhRmFjdG9yeTtcblxuY2xhc3MgQmFzZVNWR0ZhY3Rvcnkge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBpZiAodGhpcy5jb25zdHJ1Y3RvciA9PT0gQmFzZVNWR0ZhY3RvcnkpIHtcbiAgICAgICgwLCBfdXRpbC51bnJlYWNoYWJsZSkoXCJDYW5ub3QgaW5pdGlhbGl6ZSBCYXNlU1ZHRmFjdG9yeS5cIik7XG4gICAgfVxuICB9XG5cbiAgY3JlYXRlKHdpZHRoLCBoZWlnaHQpIHtcbiAgICBpZiAod2lkdGggPD0gMCB8fCBoZWlnaHQgPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBTVkcgZGltZW5zaW9uc1wiKTtcbiAgICB9XG5cbiAgICBjb25zdCBzdmcgPSB0aGlzLl9jcmVhdGVTVkcoXCJzdmc6c3ZnXCIpO1xuXG4gICAgc3ZnLnNldEF0dHJpYnV0ZShcInZlcnNpb25cIiwgXCIxLjFcIik7XG4gICAgc3ZnLnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIGAke3dpZHRofXB4YCk7XG4gICAgc3ZnLnNldEF0dHJpYnV0ZShcImhlaWdodFwiLCBgJHtoZWlnaHR9cHhgKTtcbiAgICBzdmcuc2V0QXR0cmlidXRlKFwicHJlc2VydmVBc3BlY3RSYXRpb1wiLCBcIm5vbmVcIik7XG4gICAgc3ZnLnNldEF0dHJpYnV0ZShcInZpZXdCb3hcIiwgYDAgMCAke3dpZHRofSAke2hlaWdodH1gKTtcbiAgICByZXR1cm4gc3ZnO1xuICB9XG5cbiAgY3JlYXRlRWxlbWVudCh0eXBlKSB7XG4gICAgaWYgKHR5cGVvZiB0eXBlICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIFNWRyBlbGVtZW50IHR5cGVcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZVNWRyh0eXBlKTtcbiAgfVxuXG4gIF9jcmVhdGVTVkcodHlwZSkge1xuICAgICgwLCBfdXRpbC51bnJlYWNoYWJsZSkoXCJBYnN0cmFjdCBtZXRob2QgYF9jcmVhdGVTVkdgIGNhbGxlZC5cIik7XG4gIH1cblxufVxuXG5leHBvcnRzLkJhc2VTVkdGYWN0b3J5ID0gQmFzZVNWR0ZhY3Rvcnk7XG5cbi8qKiovIH0pLFxuLyogNyAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5Gb250TG9hZGVyID0gZXhwb3J0cy5Gb250RmFjZU9iamVjdCA9IHZvaWQgMDtcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxuY2xhc3MgQmFzZUZvbnRMb2FkZXIge1xuICBjb25zdHJ1Y3Rvcih7XG4gICAgZG9jSWQsXG4gICAgb25VbnN1cHBvcnRlZEZlYXR1cmUsXG4gICAgb3duZXJEb2N1bWVudCA9IGdsb2JhbFRoaXMuZG9jdW1lbnQsXG4gICAgc3R5bGVFbGVtZW50ID0gbnVsbFxuICB9KSB7XG4gICAgaWYgKHRoaXMuY29uc3RydWN0b3IgPT09IEJhc2VGb250TG9hZGVyKSB7XG4gICAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiQ2Fubm90IGluaXRpYWxpemUgQmFzZUZvbnRMb2FkZXIuXCIpO1xuICAgIH1cblxuICAgIHRoaXMuZG9jSWQgPSBkb2NJZDtcbiAgICB0aGlzLl9vblVuc3VwcG9ydGVkRmVhdHVyZSA9IG9uVW5zdXBwb3J0ZWRGZWF0dXJlO1xuICAgIHRoaXMuX2RvY3VtZW50ID0gb3duZXJEb2N1bWVudDtcbiAgICB0aGlzLm5hdGl2ZUZvbnRGYWNlcyA9IFtdO1xuICAgIHRoaXMuc3R5bGVFbGVtZW50ID0gbnVsbDtcbiAgfVxuXG4gIGFkZE5hdGl2ZUZvbnRGYWNlKG5hdGl2ZUZvbnRGYWNlKSB7XG4gICAgdGhpcy5uYXRpdmVGb250RmFjZXMucHVzaChuYXRpdmVGb250RmFjZSk7XG5cbiAgICB0aGlzLl9kb2N1bWVudC5mb250cy5hZGQobmF0aXZlRm9udEZhY2UpO1xuICB9XG5cbiAgaW5zZXJ0UnVsZShydWxlKSB7XG4gICAgbGV0IHN0eWxlRWxlbWVudCA9IHRoaXMuc3R5bGVFbGVtZW50O1xuXG4gICAgaWYgKCFzdHlsZUVsZW1lbnQpIHtcbiAgICAgIHN0eWxlRWxlbWVudCA9IHRoaXMuc3R5bGVFbGVtZW50ID0gdGhpcy5fZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInN0eWxlXCIpO1xuICAgICAgc3R5bGVFbGVtZW50LmlkID0gYFBERkpTX0ZPTlRfU1RZTEVfVEFHXyR7dGhpcy5kb2NJZH1gO1xuXG4gICAgICB0aGlzLl9kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJoZWFkXCIpWzBdLmFwcGVuZENoaWxkKHN0eWxlRWxlbWVudCk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3R5bGVTaGVldCA9IHN0eWxlRWxlbWVudC5zaGVldDtcbiAgICBzdHlsZVNoZWV0Lmluc2VydFJ1bGUocnVsZSwgc3R5bGVTaGVldC5jc3NSdWxlcy5sZW5ndGgpO1xuICB9XG5cbiAgY2xlYXIoKSB7XG4gICAgZm9yIChjb25zdCBuYXRpdmVGb250RmFjZSBvZiB0aGlzLm5hdGl2ZUZvbnRGYWNlcykge1xuICAgICAgdGhpcy5fZG9jdW1lbnQuZm9udHMuZGVsZXRlKG5hdGl2ZUZvbnRGYWNlKTtcbiAgICB9XG5cbiAgICB0aGlzLm5hdGl2ZUZvbnRGYWNlcy5sZW5ndGggPSAwO1xuXG4gICAgaWYgKHRoaXMuc3R5bGVFbGVtZW50KSB7XG4gICAgICB0aGlzLnN0eWxlRWxlbWVudC5yZW1vdmUoKTtcbiAgICAgIHRoaXMuc3R5bGVFbGVtZW50ID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBhc3luYyBiaW5kKGZvbnQpIHtcbiAgICBpZiAoZm9udC5hdHRhY2hlZCB8fCBmb250Lm1pc3NpbmdGaWxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZm9udC5hdHRhY2hlZCA9IHRydWU7XG5cbiAgICBpZiAodGhpcy5pc0ZvbnRMb2FkaW5nQVBJU3VwcG9ydGVkKSB7XG4gICAgICBjb25zdCBuYXRpdmVGb250RmFjZSA9IGZvbnQuY3JlYXRlTmF0aXZlRm9udEZhY2UoKTtcblxuICAgICAgaWYgKG5hdGl2ZUZvbnRGYWNlKSB7XG4gICAgICAgIHRoaXMuYWRkTmF0aXZlRm9udEZhY2UobmF0aXZlRm9udEZhY2UpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgbmF0aXZlRm9udEZhY2UubG9hZGVkO1xuICAgICAgICB9IGNhdGNoIChleCkge1xuICAgICAgICAgIHRoaXMuX29uVW5zdXBwb3J0ZWRGZWF0dXJlKHtcbiAgICAgICAgICAgIGZlYXR1cmVJZDogX3V0aWwuVU5TVVBQT1JURURfRkVBVFVSRVMuZXJyb3JGb250TG9hZE5hdGl2ZVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgKDAsIF91dGlsLndhcm4pKGBGYWlsZWQgdG8gbG9hZCBmb250ICcke25hdGl2ZUZvbnRGYWNlLmZhbWlseX0nOiAnJHtleH0nLmApO1xuICAgICAgICAgIGZvbnQuZGlzYWJsZUZvbnRGYWNlID0gdHJ1ZTtcbiAgICAgICAgICB0aHJvdyBleDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcnVsZSA9IGZvbnQuY3JlYXRlRm9udEZhY2VSdWxlKCk7XG5cbiAgICBpZiAocnVsZSkge1xuICAgICAgdGhpcy5pbnNlcnRSdWxlKHJ1bGUpO1xuXG4gICAgICBpZiAodGhpcy5pc1N5bmNGb250TG9hZGluZ1N1cHBvcnRlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gdGhpcy5fcXVldWVMb2FkaW5nQ2FsbGJhY2socmVzb2x2ZSk7XG5cbiAgICAgICAgdGhpcy5fcHJlcGFyZUZvbnRMb2FkRXZlbnQoW3J1bGVdLCBbZm9udF0sIHJlcXVlc3QpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgX3F1ZXVlTG9hZGluZ0NhbGxiYWNrKGNhbGxiYWNrKSB7XG4gICAgKDAsIF91dGlsLnVucmVhY2hhYmxlKShcIkFic3RyYWN0IG1ldGhvZCBgX3F1ZXVlTG9hZGluZ0NhbGxiYWNrYC5cIik7XG4gIH1cblxuICBnZXQgaXNGb250TG9hZGluZ0FQSVN1cHBvcnRlZCgpIHtcbiAgICBjb25zdCBoYXNGb250cyA9ICEhdGhpcy5fZG9jdW1lbnQ/LmZvbnRzO1xuICAgIHJldHVybiAoMCwgX3V0aWwuc2hhZG93KSh0aGlzLCBcImlzRm9udExvYWRpbmdBUElTdXBwb3J0ZWRcIiwgaGFzRm9udHMpO1xuICB9XG5cbiAgZ2V0IGlzU3luY0ZvbnRMb2FkaW5nU3VwcG9ydGVkKCkge1xuICAgICgwLCBfdXRpbC51bnJlYWNoYWJsZSkoXCJBYnN0cmFjdCBtZXRob2QgYGlzU3luY0ZvbnRMb2FkaW5nU3VwcG9ydGVkYC5cIik7XG4gIH1cblxuICBnZXQgX2xvYWRUZXN0Rm9udCgpIHtcbiAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiQWJzdHJhY3QgbWV0aG9kIGBfbG9hZFRlc3RGb250YC5cIik7XG4gIH1cblxuICBfcHJlcGFyZUZvbnRMb2FkRXZlbnQocnVsZXMsIGZvbnRzVG9Mb2FkLCByZXF1ZXN0KSB7XG4gICAgKDAsIF91dGlsLnVucmVhY2hhYmxlKShcIkFic3RyYWN0IG1ldGhvZCBgX3ByZXBhcmVGb250TG9hZEV2ZW50YC5cIik7XG4gIH1cblxufVxuXG5sZXQgRm9udExvYWRlcjtcbmV4cG9ydHMuRm9udExvYWRlciA9IEZvbnRMb2FkZXI7XG57XG4gIGV4cG9ydHMuRm9udExvYWRlciA9IEZvbnRMb2FkZXIgPSBjbGFzcyBHZW5lcmljRm9udExvYWRlciBleHRlbmRzIEJhc2VGb250TG9hZGVyIHtcbiAgICBjb25zdHJ1Y3RvcihwYXJhbXMpIHtcbiAgICAgIHN1cGVyKHBhcmFtcyk7XG4gICAgICB0aGlzLmxvYWRpbmdDb250ZXh0ID0ge1xuICAgICAgICByZXF1ZXN0czogW10sXG4gICAgICAgIG5leHRSZXF1ZXN0SWQ6IDBcbiAgICAgIH07XG4gICAgICB0aGlzLmxvYWRUZXN0Rm9udElkID0gMDtcbiAgICB9XG5cbiAgICBnZXQgaXNTeW5jRm9udExvYWRpbmdTdXBwb3J0ZWQoKSB7XG4gICAgICBsZXQgc3VwcG9ydGVkID0gZmFsc2U7XG5cbiAgICAgIGlmICh0eXBlb2YgbmF2aWdhdG9yID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIHN1cHBvcnRlZCA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBtID0gL01vemlsbGFcXC81LjAuKj9ydjooXFxkKykuKj8gR2Vja28vLmV4ZWMobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG5cbiAgICAgICAgaWYgKG0/LlsxXSA+PSAxNCkge1xuICAgICAgICAgIHN1cHBvcnRlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuICgwLCBfdXRpbC5zaGFkb3cpKHRoaXMsIFwiaXNTeW5jRm9udExvYWRpbmdTdXBwb3J0ZWRcIiwgc3VwcG9ydGVkKTtcbiAgICB9XG5cbiAgICBfcXVldWVMb2FkaW5nQ2FsbGJhY2soY2FsbGJhY2spIHtcbiAgICAgIGZ1bmN0aW9uIGNvbXBsZXRlUmVxdWVzdCgpIHtcbiAgICAgICAgKDAsIF91dGlsLmFzc2VydCkoIXJlcXVlc3QuZG9uZSwgXCJjb21wbGV0ZVJlcXVlc3QoKSBjYW5ub3QgYmUgY2FsbGVkIHR3aWNlLlwiKTtcbiAgICAgICAgcmVxdWVzdC5kb25lID0gdHJ1ZTtcblxuICAgICAgICB3aGlsZSAoY29udGV4dC5yZXF1ZXN0cy5sZW5ndGggPiAwICYmIGNvbnRleHQucmVxdWVzdHNbMF0uZG9uZSkge1xuICAgICAgICAgIGNvbnN0IG90aGVyUmVxdWVzdCA9IGNvbnRleHQucmVxdWVzdHMuc2hpZnQoKTtcbiAgICAgICAgICBzZXRUaW1lb3V0KG90aGVyUmVxdWVzdC5jYWxsYmFjaywgMCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMubG9hZGluZ0NvbnRleHQ7XG4gICAgICBjb25zdCByZXF1ZXN0ID0ge1xuICAgICAgICBpZDogYHBkZmpzLWZvbnQtbG9hZGluZy0ke2NvbnRleHQubmV4dFJlcXVlc3RJZCsrfWAsXG4gICAgICAgIGRvbmU6IGZhbHNlLFxuICAgICAgICBjb21wbGV0ZTogY29tcGxldGVSZXF1ZXN0LFxuICAgICAgICBjYWxsYmFja1xuICAgICAgfTtcbiAgICAgIGNvbnRleHQucmVxdWVzdHMucHVzaChyZXF1ZXN0KTtcbiAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgIH1cblxuICAgIGdldCBfbG9hZFRlc3RGb250KCkge1xuICAgICAgY29uc3QgZ2V0TG9hZFRlc3RGb250ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gYXRvYihcIlQxUlVUd0FMQUlBQUF3QXdRMFpHSURIdFpnNEFBQU9ZQUFBQWdVWkdWRTFsa3pad0FBQUVIQUFBQUJ4SFJFVkdBQlFBXCIgKyBcIkZRQUFCRGdBQUFBZVQxTXZNbFlOWXdrQUFBRWdBQUFBWUdOdFlYQUJEUUxVQUFBQ05BQUFBVUpvWldGay94VkZEUUFBXCIgKyBcIkFMd0FBQUEyYUdobFlRZGtBK29BQUFEMEFBQUFKR2h0ZEhnRDZBQUFBQUFFV0FBQUFBWnRZWGh3QUFKUUFBQUFBUmdBXCIgKyBcIkFBQUdibUZ0WlZqbWRINEFBQUdBQUFBQXNYQnZjM1QvaGdBekFBQURlQUFBQUNBQUFRQUFBQUVBQUxaUkZzUmZEenoxXCIgKyBcIkFBc0Q2QUFBQUFET0JPVExBQUFBQU00S0hEd0FBQUFBQStnRElRQUFBQWdBQWdBQUFBQUFBQUFCQUFBRElRQUFBRm9EXCIgKyBcIjZBQUFBQUFENkFBQkFBQUFBQUFBQUFBQUFBQUFBQUFBQVFBQVVBQUFBZ0FBQUFRRDZBSDBBQVVBQUFLS0Fyd0FBQUNNXCIgKyBcIkFvb0N2QUFBQWVBQU1RRUNBQUFDQUFZSkFBQUFBQUFBQUFBQUFRQUFBQUFBQUFBQUFBQUFBRkJtUldRQXdBQXVBQzREXCIgKyBcIklQODRBRm9ESVFBQUFBQUFBUUFBQUFBQUFBQUFBQ0FBSUFBQkFBQUFEZ0N1QUFFQUFBQUFBQUFBQVFBQUFBRUFBQUFBXCIgKyBcIkFBRUFBUUFBQUFFQUFBQUFBQUlBQVFBQUFBRUFBQUFBQUFNQUFRQUFBQUVBQUFBQUFBUUFBUUFBQUFFQUFBQUFBQVVBXCIgKyBcIkFRQUFBQUVBQUFBQUFBWUFBUUFBQUFNQUFRUUpBQUFBQWdBQkFBTUFBUVFKQUFFQUFnQUJBQU1BQVFRSkFBSUFBZ0FCXCIgKyBcIkFBTUFBUVFKQUFNQUFnQUJBQU1BQVFRSkFBUUFBZ0FCQUFNQUFRUUpBQVVBQWdBQkFBTUFBUVFKQUFZQUFnQUJXQUJZXCIgKyBcIkFBQUFBQUFBQXdBQUFBTUFBQUFjQUFFQUFBQUFBRHdBQXdBQkFBQUFIQUFFQUNBQUFBQUVBQVFBQVFBQUFDNy8vd0FBXCIgKyBcIkFDNy8vLy9UQUFFQUFBQUFBQUFCQmdBQUFRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBXCIgKyBcIkFBQUFBQUFBQUFBQUFBQUFBQUVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBXCIgKyBcIkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBXCIgKyBcIkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBXCIgKyBcIkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBXCIgKyBcIkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU1BQUFBQUFBRC9nd0F5QUFBQUFRQUFBQUFBQUFBQUFBQUFBQUFBXCIgKyBcIkFBQUJBQVFFQUFFQkFRSllBQUVCQVNINER3RDRHd0hFQXZnY0EvZ1hCSXdNQVl1TCtuejV0UVhrRDVqM0NCTG5FUUFDXCIgKyBcIkFRRUJJVmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWUFBQUJBUUFBRHdBQ0FRRUVFL3QzXCIgKyBcIkRvdjZmQUg2ZkFUK2ZQcDgrbndIRG9zTUN2bTFDdm0xREF6NmZCUUFBQUFBQUFBQkFBQUFBTW1KYnpFQUFBQUF6Z1RqXCIgKyBcIkZRQUFBQURPQk9RcEFBRUFBQUFBQUFBQURBQVVBQVFBQUFBQkFBQUFBZ0FCQUFBQUFBQUFBQUFENkFBQUFBQUFBQT09XCIpO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuICgwLCBfdXRpbC5zaGFkb3cpKHRoaXMsIFwiX2xvYWRUZXN0Rm9udFwiLCBnZXRMb2FkVGVzdEZvbnQoKSk7XG4gICAgfVxuXG4gICAgX3ByZXBhcmVGb250TG9hZEV2ZW50KHJ1bGVzLCBmb250cywgcmVxdWVzdCkge1xuICAgICAgZnVuY3Rpb24gaW50MzIoZGF0YSwgb2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiBkYXRhLmNoYXJDb2RlQXQob2Zmc2V0KSA8PCAyNCB8IGRhdGEuY2hhckNvZGVBdChvZmZzZXQgKyAxKSA8PCAxNiB8IGRhdGEuY2hhckNvZGVBdChvZmZzZXQgKyAyKSA8PCA4IHwgZGF0YS5jaGFyQ29kZUF0KG9mZnNldCArIDMpICYgMHhmZjtcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gc3BsaWNlU3RyaW5nKHMsIG9mZnNldCwgcmVtb3ZlLCBpbnNlcnQpIHtcbiAgICAgICAgY29uc3QgY2h1bmsxID0gcy5zdWJzdHJpbmcoMCwgb2Zmc2V0KTtcbiAgICAgICAgY29uc3QgY2h1bmsyID0gcy5zdWJzdHJpbmcob2Zmc2V0ICsgcmVtb3ZlKTtcbiAgICAgICAgcmV0dXJuIGNodW5rMSArIGluc2VydCArIGNodW5rMjtcbiAgICAgIH1cblxuICAgICAgbGV0IGksIGlpO1xuXG4gICAgICBjb25zdCBjYW52YXMgPSB0aGlzLl9kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xuXG4gICAgICBjYW52YXMud2lkdGggPSAxO1xuICAgICAgY2FudmFzLmhlaWdodCA9IDE7XG4gICAgICBjb25zdCBjdHggPSBjYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpO1xuICAgICAgbGV0IGNhbGxlZCA9IDA7XG5cbiAgICAgIGZ1bmN0aW9uIGlzRm9udFJlYWR5KG5hbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIGNhbGxlZCsrO1xuXG4gICAgICAgIGlmIChjYWxsZWQgPiAzMCkge1xuICAgICAgICAgICgwLCBfdXRpbC53YXJuKShcIkxvYWQgdGVzdCBmb250IG5ldmVyIGxvYWRlZC5cIik7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjdHguZm9udCA9IFwiMzBweCBcIiArIG5hbWU7XG4gICAgICAgIGN0eC5maWxsVGV4dChcIi5cIiwgMCwgMjApO1xuICAgICAgICBjb25zdCBpbWFnZURhdGEgPSBjdHguZ2V0SW1hZ2VEYXRhKDAsIDAsIDEsIDEpO1xuXG4gICAgICAgIGlmIChpbWFnZURhdGEuZGF0YVszXSA+IDApIHtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHNldFRpbWVvdXQoaXNGb250UmVhZHkuYmluZChudWxsLCBuYW1lLCBjYWxsYmFjaykpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBsb2FkVGVzdEZvbnRJZCA9IGBsdCR7RGF0ZS5ub3coKX0ke3RoaXMubG9hZFRlc3RGb250SWQrK31gO1xuICAgICAgbGV0IGRhdGEgPSB0aGlzLl9sb2FkVGVzdEZvbnQ7XG4gICAgICBjb25zdCBDT01NRU5UX09GRlNFVCA9IDk3NjtcbiAgICAgIGRhdGEgPSBzcGxpY2VTdHJpbmcoZGF0YSwgQ09NTUVOVF9PRkZTRVQsIGxvYWRUZXN0Rm9udElkLmxlbmd0aCwgbG9hZFRlc3RGb250SWQpO1xuICAgICAgY29uc3QgQ0ZGX0NIRUNLU1VNX09GRlNFVCA9IDE2O1xuICAgICAgY29uc3QgWFhYWF9WQUxVRSA9IDB4NTg1ODU4NTg7XG4gICAgICBsZXQgY2hlY2tzdW0gPSBpbnQzMihkYXRhLCBDRkZfQ0hFQ0tTVU1fT0ZGU0VUKTtcblxuICAgICAgZm9yIChpID0gMCwgaWkgPSBsb2FkVGVzdEZvbnRJZC5sZW5ndGggLSAzOyBpIDwgaWk7IGkgKz0gNCkge1xuICAgICAgICBjaGVja3N1bSA9IGNoZWNrc3VtIC0gWFhYWF9WQUxVRSArIGludDMyKGxvYWRUZXN0Rm9udElkLCBpKSB8IDA7XG4gICAgICB9XG5cbiAgICAgIGlmIChpIDwgbG9hZFRlc3RGb250SWQubGVuZ3RoKSB7XG4gICAgICAgIGNoZWNrc3VtID0gY2hlY2tzdW0gLSBYWFhYX1ZBTFVFICsgaW50MzIobG9hZFRlc3RGb250SWQgKyBcIlhYWFwiLCBpKSB8IDA7XG4gICAgICB9XG5cbiAgICAgIGRhdGEgPSBzcGxpY2VTdHJpbmcoZGF0YSwgQ0ZGX0NIRUNLU1VNX09GRlNFVCwgNCwgKDAsIF91dGlsLnN0cmluZzMyKShjaGVja3N1bSkpO1xuICAgICAgY29uc3QgdXJsID0gYHVybChkYXRhOmZvbnQvb3BlbnR5cGU7YmFzZTY0LCR7YnRvYShkYXRhKX0pO2A7XG4gICAgICBjb25zdCBydWxlID0gYEBmb250LWZhY2Uge2ZvbnQtZmFtaWx5OlwiJHtsb2FkVGVzdEZvbnRJZH1cIjtzcmM6JHt1cmx9fWA7XG4gICAgICB0aGlzLmluc2VydFJ1bGUocnVsZSk7XG4gICAgICBjb25zdCBuYW1lcyA9IFtdO1xuXG4gICAgICBmb3IgKGNvbnN0IGZvbnQgb2YgZm9udHMpIHtcbiAgICAgICAgbmFtZXMucHVzaChmb250LmxvYWRlZE5hbWUpO1xuICAgICAgfVxuXG4gICAgICBuYW1lcy5wdXNoKGxvYWRUZXN0Rm9udElkKTtcblxuICAgICAgY29uc3QgZGl2ID0gdGhpcy5fZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcblxuICAgICAgZGl2LnN0eWxlLnZpc2liaWxpdHkgPSBcImhpZGRlblwiO1xuICAgICAgZGl2LnN0eWxlLndpZHRoID0gZGl2LnN0eWxlLmhlaWdodCA9IFwiMTBweFwiO1xuICAgICAgZGl2LnN0eWxlLnBvc2l0aW9uID0gXCJhYnNvbHV0ZVwiO1xuICAgICAgZGl2LnN0eWxlLnRvcCA9IGRpdi5zdHlsZS5sZWZ0ID0gXCIwcHhcIjtcblxuICAgICAgZm9yIChjb25zdCBuYW1lIG9mIG5hbWVzKSB7XG4gICAgICAgIGNvbnN0IHNwYW4gPSB0aGlzLl9kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3BhblwiKTtcblxuICAgICAgICBzcGFuLnRleHRDb250ZW50ID0gXCJIaVwiO1xuICAgICAgICBzcGFuLnN0eWxlLmZvbnRGYW1pbHkgPSBuYW1lO1xuICAgICAgICBkaXYuYXBwZW5kQ2hpbGQoc3Bhbik7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZGl2KTtcblxuICAgICAgaXNGb250UmVhZHkobG9hZFRlc3RGb250SWQsICgpID0+IHtcbiAgICAgICAgZGl2LnJlbW92ZSgpO1xuICAgICAgICByZXF1ZXN0LmNvbXBsZXRlKCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgfTtcbn1cblxuY2xhc3MgRm9udEZhY2VPYmplY3Qge1xuICBjb25zdHJ1Y3Rvcih0cmFuc2xhdGVkRGF0YSwge1xuICAgIGlzRXZhbFN1cHBvcnRlZCA9IHRydWUsXG4gICAgZGlzYWJsZUZvbnRGYWNlID0gZmFsc2UsXG4gICAgaWdub3JlRXJyb3JzID0gZmFsc2UsXG4gICAgb25VbnN1cHBvcnRlZEZlYXR1cmUsXG4gICAgZm9udFJlZ2lzdHJ5ID0gbnVsbFxuICB9KSB7XG4gICAgdGhpcy5jb21waWxlZEdseXBocyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbiAgICBmb3IgKGNvbnN0IGkgaW4gdHJhbnNsYXRlZERhdGEpIHtcbiAgICAgIHRoaXNbaV0gPSB0cmFuc2xhdGVkRGF0YVtpXTtcbiAgICB9XG5cbiAgICB0aGlzLmlzRXZhbFN1cHBvcnRlZCA9IGlzRXZhbFN1cHBvcnRlZCAhPT0gZmFsc2U7XG4gICAgdGhpcy5kaXNhYmxlRm9udEZhY2UgPSBkaXNhYmxlRm9udEZhY2UgPT09IHRydWU7XG4gICAgdGhpcy5pZ25vcmVFcnJvcnMgPSBpZ25vcmVFcnJvcnMgPT09IHRydWU7XG4gICAgdGhpcy5fb25VbnN1cHBvcnRlZEZlYXR1cmUgPSBvblVuc3VwcG9ydGVkRmVhdHVyZTtcbiAgICB0aGlzLmZvbnRSZWdpc3RyeSA9IGZvbnRSZWdpc3RyeTtcbiAgfVxuXG4gIGNyZWF0ZU5hdGl2ZUZvbnRGYWNlKCkge1xuICAgIGlmICghdGhpcy5kYXRhIHx8IHRoaXMuZGlzYWJsZUZvbnRGYWNlKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBsZXQgbmF0aXZlRm9udEZhY2U7XG5cbiAgICBpZiAoIXRoaXMuY3NzRm9udEluZm8pIHtcbiAgICAgIG5hdGl2ZUZvbnRGYWNlID0gbmV3IEZvbnRGYWNlKHRoaXMubG9hZGVkTmFtZSwgdGhpcy5kYXRhLCB7fSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGNzcyA9IHtcbiAgICAgICAgd2VpZ2h0OiB0aGlzLmNzc0ZvbnRJbmZvLmZvbnRXZWlnaHRcbiAgICAgIH07XG5cbiAgICAgIGlmICh0aGlzLmNzc0ZvbnRJbmZvLml0YWxpY0FuZ2xlKSB7XG4gICAgICAgIGNzcy5zdHlsZSA9IGBvYmxpcXVlICR7dGhpcy5jc3NGb250SW5mby5pdGFsaWNBbmdsZX1kZWdgO1xuICAgICAgfVxuXG4gICAgICBuYXRpdmVGb250RmFjZSA9IG5ldyBGb250RmFjZSh0aGlzLmNzc0ZvbnRJbmZvLmZvbnRGYW1pbHksIHRoaXMuZGF0YSwgY3NzKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5mb250UmVnaXN0cnkpIHtcbiAgICAgIHRoaXMuZm9udFJlZ2lzdHJ5LnJlZ2lzdGVyRm9udCh0aGlzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmF0aXZlRm9udEZhY2U7XG4gIH1cblxuICBjcmVhdGVGb250RmFjZVJ1bGUoKSB7XG4gICAgaWYgKCF0aGlzLmRhdGEgfHwgdGhpcy5kaXNhYmxlRm9udEZhY2UpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGEgPSAoMCwgX3V0aWwuYnl0ZXNUb1N0cmluZykodGhpcy5kYXRhKTtcbiAgICBjb25zdCB1cmwgPSBgdXJsKGRhdGE6JHt0aGlzLm1pbWV0eXBlfTtiYXNlNjQsJHtidG9hKGRhdGEpfSk7YDtcbiAgICBsZXQgcnVsZTtcblxuICAgIGlmICghdGhpcy5jc3NGb250SW5mbykge1xuICAgICAgcnVsZSA9IGBAZm9udC1mYWNlIHtmb250LWZhbWlseTpcIiR7dGhpcy5sb2FkZWROYW1lfVwiO3NyYzoke3VybH19YDtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IGNzcyA9IGBmb250LXdlaWdodDogJHt0aGlzLmNzc0ZvbnRJbmZvLmZvbnRXZWlnaHR9O2A7XG5cbiAgICAgIGlmICh0aGlzLmNzc0ZvbnRJbmZvLml0YWxpY0FuZ2xlKSB7XG4gICAgICAgIGNzcyArPSBgZm9udC1zdHlsZTogb2JsaXF1ZSAke3RoaXMuY3NzRm9udEluZm8uaXRhbGljQW5nbGV9ZGVnO2A7XG4gICAgICB9XG5cbiAgICAgIHJ1bGUgPSBgQGZvbnQtZmFjZSB7Zm9udC1mYW1pbHk6XCIke3RoaXMuY3NzRm9udEluZm8uZm9udEZhbWlseX1cIjske2Nzc31zcmM6JHt1cmx9fWA7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZm9udFJlZ2lzdHJ5KSB7XG4gICAgICB0aGlzLmZvbnRSZWdpc3RyeS5yZWdpc3RlckZvbnQodGhpcywgdXJsKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcnVsZTtcbiAgfVxuXG4gIGdldFBhdGhHZW5lcmF0b3Iob2JqcywgY2hhcmFjdGVyKSB7XG4gICAgaWYgKHRoaXMuY29tcGlsZWRHbHlwaHNbY2hhcmFjdGVyXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb21waWxlZEdseXBoc1tjaGFyYWN0ZXJdO1xuICAgIH1cblxuICAgIGxldCBjbWRzO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNtZHMgPSBvYmpzLmdldCh0aGlzLmxvYWRlZE5hbWUgKyBcIl9wYXRoX1wiICsgY2hhcmFjdGVyKTtcbiAgICB9IGNhdGNoIChleCkge1xuICAgICAgaWYgKCF0aGlzLmlnbm9yZUVycm9ycykge1xuICAgICAgICB0aHJvdyBleDtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fb25VbnN1cHBvcnRlZEZlYXR1cmUoe1xuICAgICAgICBmZWF0dXJlSWQ6IF91dGlsLlVOU1VQUE9SVEVEX0ZFQVRVUkVTLmVycm9yRm9udEdldFBhdGhcbiAgICAgIH0pO1xuXG4gICAgICAoMCwgX3V0aWwud2FybikoYGdldFBhdGhHZW5lcmF0b3IgLSBpZ25vcmluZyBjaGFyYWN0ZXI6IFwiJHtleH1cIi5gKTtcbiAgICAgIHJldHVybiB0aGlzLmNvbXBpbGVkR2x5cGhzW2NoYXJhY3Rlcl0gPSBmdW5jdGlvbiAoYywgc2l6ZSkge307XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNFdmFsU3VwcG9ydGVkICYmIF91dGlsLkZlYXR1cmVUZXN0LmlzRXZhbFN1cHBvcnRlZCkge1xuICAgICAgY29uc3QganNCdWYgPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBjdXJyZW50IG9mIGNtZHMpIHtcbiAgICAgICAgY29uc3QgYXJncyA9IGN1cnJlbnQuYXJncyAhPT0gdW5kZWZpbmVkID8gY3VycmVudC5hcmdzLmpvaW4oXCIsXCIpIDogXCJcIjtcbiAgICAgICAganNCdWYucHVzaChcImMuXCIsIGN1cnJlbnQuY21kLCBcIihcIiwgYXJncywgXCIpO1xcblwiKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuY29tcGlsZWRHbHlwaHNbY2hhcmFjdGVyXSA9IG5ldyBGdW5jdGlvbihcImNcIiwgXCJzaXplXCIsIGpzQnVmLmpvaW4oXCJcIikpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbXBpbGVkR2x5cGhzW2NoYXJhY3Rlcl0gPSBmdW5jdGlvbiAoYywgc2l6ZSkge1xuICAgICAgZm9yIChjb25zdCBjdXJyZW50IG9mIGNtZHMpIHtcbiAgICAgICAgaWYgKGN1cnJlbnQuY21kID09PSBcInNjYWxlXCIpIHtcbiAgICAgICAgICBjdXJyZW50LmFyZ3MgPSBbc2l6ZSwgLXNpemVdO1xuICAgICAgICB9XG5cbiAgICAgICAgY1tjdXJyZW50LmNtZF0uYXBwbHkoYywgY3VycmVudC5hcmdzKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbn1cblxuZXhwb3J0cy5Gb250RmFjZU9iamVjdCA9IEZvbnRGYWNlT2JqZWN0O1xuXG4vKioqLyB9KSxcbi8qIDggKi9cbi8qKiovICgoX191bnVzZWRfd2VicGFja19tb2R1bGUsIGV4cG9ydHMsIF9fd19wZGZqc19yZXF1aXJlX18pID0+IHtcblxuXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgKHtcbiAgdmFsdWU6IHRydWVcbn0pKTtcbmV4cG9ydHMuQW5ub3RhdGlvblN0b3JhZ2UgPSB2b2lkIDA7XG5cbnZhciBfbXVybXVyaGFzaCA9IF9fd19wZGZqc19yZXF1aXJlX18oOSk7XG5cbnZhciBfdXRpbCA9IF9fd19wZGZqc19yZXF1aXJlX18oMSk7XG5cbmNsYXNzIEFubm90YXRpb25TdG9yYWdlIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5fc3RvcmFnZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLl9tb2RpZmllZCA9IGZhbHNlO1xuICAgIHRoaXMub25TZXRNb2RpZmllZCA9IG51bGw7XG4gICAgdGhpcy5vblJlc2V0TW9kaWZpZWQgPSBudWxsO1xuICB9XG5cbiAgZ2V0VmFsdWUoa2V5LCBkZWZhdWx0VmFsdWUpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX3N0b3JhZ2UuZ2V0KGtleSk7XG5cbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihkZWZhdWx0VmFsdWUsIHZhbHVlKTtcbiAgfVxuXG4gIGdldFJhd1ZhbHVlKGtleSkge1xuICAgIHJldHVybiB0aGlzLl9zdG9yYWdlLmdldChrZXkpO1xuICB9XG5cbiAgc2V0VmFsdWUoa2V5LCB2YWx1ZSkge1xuICAgIGNvbnN0IG9iaiA9IHRoaXMuX3N0b3JhZ2UuZ2V0KGtleSk7XG5cbiAgICBsZXQgbW9kaWZpZWQgPSBmYWxzZTtcblxuICAgIGlmIChvYmogIT09IHVuZGVmaW5lZCkge1xuICAgICAgZm9yIChjb25zdCBbZW50cnksIHZhbF0gb2YgT2JqZWN0LmVudHJpZXModmFsdWUpKSB7XG4gICAgICAgIGlmIChvYmpbZW50cnldICE9PSB2YWwpIHtcbiAgICAgICAgICBtb2RpZmllZCA9IHRydWU7XG4gICAgICAgICAgb2JqW2VudHJ5XSA9IHZhbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBtb2RpZmllZCA9IHRydWU7XG5cbiAgICAgIHRoaXMuX3N0b3JhZ2Uuc2V0KGtleSwgdmFsdWUpO1xuICAgIH1cblxuICAgIGlmIChtb2RpZmllZCkge1xuICAgICAgdGhpcy5fc2V0TW9kaWZpZWQoKTtcbiAgICB9XG4gIH1cblxuICBnZXRBbGwoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0b3JhZ2Uuc2l6ZSA+IDAgPyAoMCwgX3V0aWwub2JqZWN0RnJvbU1hcCkodGhpcy5fc3RvcmFnZSkgOiBudWxsO1xuICB9XG5cbiAgZ2V0IHNpemUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0b3JhZ2Uuc2l6ZTtcbiAgfVxuXG4gIF9zZXRNb2RpZmllZCgpIHtcbiAgICBpZiAoIXRoaXMuX21vZGlmaWVkKSB7XG4gICAgICB0aGlzLl9tb2RpZmllZCA9IHRydWU7XG5cbiAgICAgIGlmICh0eXBlb2YgdGhpcy5vblNldE1vZGlmaWVkID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhpcy5vblNldE1vZGlmaWVkKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmVzZXRNb2RpZmllZCgpIHtcbiAgICBpZiAodGhpcy5fbW9kaWZpZWQpIHtcbiAgICAgIHRoaXMuX21vZGlmaWVkID0gZmFsc2U7XG5cbiAgICAgIGlmICh0eXBlb2YgdGhpcy5vblJlc2V0TW9kaWZpZWQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aGlzLm9uUmVzZXRNb2RpZmllZCgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGdldCBzZXJpYWxpemFibGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0b3JhZ2Uuc2l6ZSA+IDAgPyB0aGlzLl9zdG9yYWdlIDogbnVsbDtcbiAgfVxuXG4gIGdldCBoYXNoKCkge1xuICAgIGNvbnN0IGhhc2ggPSBuZXcgX211cm11cmhhc2guTXVybXVySGFzaDNfNjQoKTtcblxuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIHRoaXMuX3N0b3JhZ2UpIHtcbiAgICAgIGhhc2gudXBkYXRlKGAke2tleX06JHtKU09OLnN0cmluZ2lmeSh2YWx1ZSl9YCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGhhc2guaGV4ZGlnZXN0KCk7XG4gIH1cblxufVxuXG5leHBvcnRzLkFubm90YXRpb25TdG9yYWdlID0gQW5ub3RhdGlvblN0b3JhZ2U7XG5cbi8qKiovIH0pLFxuLyogOSAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5NdXJtdXJIYXNoM182NCA9IHZvaWQgMDtcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxuY29uc3QgU0VFRCA9IDB4YzNkMmUxZjA7XG5jb25zdCBNQVNLX0hJR0ggPSAweGZmZmYwMDAwO1xuY29uc3QgTUFTS19MT1cgPSAweGZmZmY7XG5cbmNsYXNzIE11cm11ckhhc2gzXzY0IHtcbiAgY29uc3RydWN0b3Ioc2VlZCkge1xuICAgIHRoaXMuaDEgPSBzZWVkID8gc2VlZCAmIDB4ZmZmZmZmZmYgOiBTRUVEO1xuICAgIHRoaXMuaDIgPSBzZWVkID8gc2VlZCAmIDB4ZmZmZmZmZmYgOiBTRUVEO1xuICB9XG5cbiAgdXBkYXRlKGlucHV0KSB7XG4gICAgbGV0IGRhdGEsIGxlbmd0aDtcblxuICAgIGlmICh0eXBlb2YgaW5wdXQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIGRhdGEgPSBuZXcgVWludDhBcnJheShpbnB1dC5sZW5ndGggKiAyKTtcbiAgICAgIGxlbmd0aCA9IDA7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwLCBpaSA9IGlucHV0Lmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgY29uc3QgY29kZSA9IGlucHV0LmNoYXJDb2RlQXQoaSk7XG5cbiAgICAgICAgaWYgKGNvZGUgPD0gMHhmZikge1xuICAgICAgICAgIGRhdGFbbGVuZ3RoKytdID0gY29kZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkYXRhW2xlbmd0aCsrXSA9IGNvZGUgPj4+IDg7XG4gICAgICAgICAgZGF0YVtsZW5ndGgrK10gPSBjb2RlICYgMHhmZjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoKDAsIF91dGlsLmlzQXJyYXlCdWZmZXIpKGlucHV0KSkge1xuICAgICAgZGF0YSA9IGlucHV0LnNsaWNlKCk7XG4gICAgICBsZW5ndGggPSBkYXRhLmJ5dGVMZW5ndGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIldyb25nIGRhdGEgZm9ybWF0IGluIE11cm11ckhhc2gzXzY0X3VwZGF0ZS4gXCIgKyBcIklucHV0IG11c3QgYmUgYSBzdHJpbmcgb3IgYXJyYXkuXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IGJsb2NrQ291bnRzID0gbGVuZ3RoID4+IDI7XG4gICAgY29uc3QgdGFpbExlbmd0aCA9IGxlbmd0aCAtIGJsb2NrQ291bnRzICogNDtcbiAgICBjb25zdCBkYXRhVWludDMyID0gbmV3IFVpbnQzMkFycmF5KGRhdGEuYnVmZmVyLCAwLCBibG9ja0NvdW50cyk7XG4gICAgbGV0IGsxID0gMCxcbiAgICAgICAgazIgPSAwO1xuICAgIGxldCBoMSA9IHRoaXMuaDEsXG4gICAgICAgIGgyID0gdGhpcy5oMjtcbiAgICBjb25zdCBDMSA9IDB4Y2M5ZTJkNTEsXG4gICAgICAgICAgQzIgPSAweDFiODczNTkzO1xuICAgIGNvbnN0IEMxX0xPVyA9IEMxICYgTUFTS19MT1csXG4gICAgICAgICAgQzJfTE9XID0gQzIgJiBNQVNLX0xPVztcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYmxvY2tDb3VudHM7IGkrKykge1xuICAgICAgaWYgKGkgJiAxKSB7XG4gICAgICAgIGsxID0gZGF0YVVpbnQzMltpXTtcbiAgICAgICAgazEgPSBrMSAqIEMxICYgTUFTS19ISUdIIHwgazEgKiBDMV9MT1cgJiBNQVNLX0xPVztcbiAgICAgICAgazEgPSBrMSA8PCAxNSB8IGsxID4+PiAxNztcbiAgICAgICAgazEgPSBrMSAqIEMyICYgTUFTS19ISUdIIHwgazEgKiBDMl9MT1cgJiBNQVNLX0xPVztcbiAgICAgICAgaDEgXj0gazE7XG4gICAgICAgIGgxID0gaDEgPDwgMTMgfCBoMSA+Pj4gMTk7XG4gICAgICAgIGgxID0gaDEgKiA1ICsgMHhlNjU0NmI2NDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGsyID0gZGF0YVVpbnQzMltpXTtcbiAgICAgICAgazIgPSBrMiAqIEMxICYgTUFTS19ISUdIIHwgazIgKiBDMV9MT1cgJiBNQVNLX0xPVztcbiAgICAgICAgazIgPSBrMiA8PCAxNSB8IGsyID4+PiAxNztcbiAgICAgICAgazIgPSBrMiAqIEMyICYgTUFTS19ISUdIIHwgazIgKiBDMl9MT1cgJiBNQVNLX0xPVztcbiAgICAgICAgaDIgXj0gazI7XG4gICAgICAgIGgyID0gaDIgPDwgMTMgfCBoMiA+Pj4gMTk7XG4gICAgICAgIGgyID0gaDIgKiA1ICsgMHhlNjU0NmI2NDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBrMSA9IDA7XG5cbiAgICBzd2l0Y2ggKHRhaWxMZW5ndGgpIHtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgazEgXj0gZGF0YVtibG9ja0NvdW50cyAqIDQgKyAyXSA8PCAxNjtcblxuICAgICAgY2FzZSAyOlxuICAgICAgICBrMSBePSBkYXRhW2Jsb2NrQ291bnRzICogNCArIDFdIDw8IDg7XG5cbiAgICAgIGNhc2UgMTpcbiAgICAgICAgazEgXj0gZGF0YVtibG9ja0NvdW50cyAqIDRdO1xuICAgICAgICBrMSA9IGsxICogQzEgJiBNQVNLX0hJR0ggfCBrMSAqIEMxX0xPVyAmIE1BU0tfTE9XO1xuICAgICAgICBrMSA9IGsxIDw8IDE1IHwgazEgPj4+IDE3O1xuICAgICAgICBrMSA9IGsxICogQzIgJiBNQVNLX0hJR0ggfCBrMSAqIEMyX0xPVyAmIE1BU0tfTE9XO1xuXG4gICAgICAgIGlmIChibG9ja0NvdW50cyAmIDEpIHtcbiAgICAgICAgICBoMSBePSBrMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBoMiBePSBrMTtcbiAgICAgICAgfVxuXG4gICAgfVxuXG4gICAgdGhpcy5oMSA9IGgxO1xuICAgIHRoaXMuaDIgPSBoMjtcbiAgfVxuXG4gIGhleGRpZ2VzdCgpIHtcbiAgICBsZXQgaDEgPSB0aGlzLmgxLFxuICAgICAgICBoMiA9IHRoaXMuaDI7XG4gICAgaDEgXj0gaDIgPj4+IDE7XG4gICAgaDEgPSBoMSAqIDB4ZWQ1NThjY2QgJiBNQVNLX0hJR0ggfCBoMSAqIDB4OGNjZCAmIE1BU0tfTE9XO1xuICAgIGgyID0gaDIgKiAweGZmNTFhZmQ3ICYgTUFTS19ISUdIIHwgKChoMiA8PCAxNiB8IGgxID4+PiAxNikgKiAweGFmZDdlZDU1ICYgTUFTS19ISUdIKSA+Pj4gMTY7XG4gICAgaDEgXj0gaDIgPj4+IDE7XG4gICAgaDEgPSBoMSAqIDB4MWE4NWVjNTMgJiBNQVNLX0hJR0ggfCBoMSAqIDB4ZWM1MyAmIE1BU0tfTE9XO1xuICAgIGgyID0gaDIgKiAweGM0Y2ViOWZlICYgTUFTS19ISUdIIHwgKChoMiA8PCAxNiB8IGgxID4+PiAxNikgKiAweGI5ZmUxYTg1ICYgTUFTS19ISUdIKSA+Pj4gMTY7XG4gICAgaDEgXj0gaDIgPj4+IDE7XG4gICAgY29uc3QgaGV4MSA9IChoMSA+Pj4gMCkudG9TdHJpbmcoMTYpLFxuICAgICAgICAgIGhleDIgPSAoaDIgPj4+IDApLnRvU3RyaW5nKDE2KTtcbiAgICByZXR1cm4gaGV4MS5wYWRTdGFydCg4LCBcIjBcIikgKyBoZXgyLnBhZFN0YXJ0KDgsIFwiMFwiKTtcbiAgfVxuXG59XG5cbmV4cG9ydHMuTXVybXVySGFzaDNfNjQgPSBNdXJtdXJIYXNoM182NDtcblxuLyoqKi8gfSksXG4vKiAxMCAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5DYW52YXNHcmFwaGljcyA9IHZvaWQgMDtcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxudmFyIF9wYXR0ZXJuX2hlbHBlciA9IF9fd19wZGZqc19yZXF1aXJlX18oMTEpO1xuXG52YXIgX2ltYWdlX3V0aWxzID0gX193X3BkZmpzX3JlcXVpcmVfXygxMik7XG5cbnZhciBfaXNfbm9kZSA9IF9fd19wZGZqc19yZXF1aXJlX18oMyk7XG5cbnZhciBfZGlzcGxheV91dGlscyA9IF9fd19wZGZqc19yZXF1aXJlX18oNSk7XG5cbmNvbnN0IE1JTl9GT05UX1NJWkUgPSAxNjtcbmNvbnN0IE1BWF9GT05UX1NJWkUgPSAxMDA7XG5jb25zdCBNQVhfR1JPVVBfU0laRSA9IDQwOTY7XG5jb25zdCBFWEVDVVRJT05fVElNRSA9IDE1O1xuY29uc3QgRVhFQ1VUSU9OX1NURVBTID0gMTA7XG5jb25zdCBDT01QSUxFX1RZUEUzX0dMWVBIUyA9IHRydWU7XG5jb25zdCBNQVhfU0laRV9UT19DT01QSUxFID0gMTAwMDtcbmNvbnN0IEZVTExfQ0hVTktfSEVJR0hUID0gMTY7XG5jb25zdCBMSU5FV0lEVEhfU0NBTEVfRkFDVE9SID0gMS4wMDAwMDE7XG5cbmZ1bmN0aW9uIG1pcnJvckNvbnRleHRPcGVyYXRpb25zKGN0eCwgZGVzdEN0eCkge1xuICBpZiAoY3R4Ll9yZW1vdmVNaXJyb3JpbmcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb250ZXh0IGlzIGFscmVhZHkgZm9yd2FyZGluZyBvcGVyYXRpb25zLlwiKTtcbiAgfVxuXG4gIGN0eC5fX29yaWdpbmFsU2F2ZSA9IGN0eC5zYXZlO1xuICBjdHguX19vcmlnaW5hbFJlc3RvcmUgPSBjdHgucmVzdG9yZTtcbiAgY3R4Ll9fb3JpZ2luYWxSb3RhdGUgPSBjdHgucm90YXRlO1xuICBjdHguX19vcmlnaW5hbFNjYWxlID0gY3R4LnNjYWxlO1xuICBjdHguX19vcmlnaW5hbFRyYW5zbGF0ZSA9IGN0eC50cmFuc2xhdGU7XG4gIGN0eC5fX29yaWdpbmFsVHJhbnNmb3JtID0gY3R4LnRyYW5zZm9ybTtcbiAgY3R4Ll9fb3JpZ2luYWxTZXRUcmFuc2Zvcm0gPSBjdHguc2V0VHJhbnNmb3JtO1xuICBjdHguX19vcmlnaW5hbFJlc2V0VHJhbnNmb3JtID0gY3R4LnJlc2V0VHJhbnNmb3JtO1xuICBjdHguX19vcmlnaW5hbENsaXAgPSBjdHguY2xpcDtcbiAgY3R4Ll9fb3JpZ2luYWxNb3ZlVG8gPSBjdHgubW92ZVRvO1xuICBjdHguX19vcmlnaW5hbExpbmVUbyA9IGN0eC5saW5lVG87XG4gIGN0eC5fX29yaWdpbmFsQmV6aWVyQ3VydmVUbyA9IGN0eC5iZXppZXJDdXJ2ZVRvO1xuICBjdHguX19vcmlnaW5hbFJlY3QgPSBjdHgucmVjdDtcbiAgY3R4Ll9fb3JpZ2luYWxDbG9zZVBhdGggPSBjdHguY2xvc2VQYXRoO1xuICBjdHguX19vcmlnaW5hbEJlZ2luUGF0aCA9IGN0eC5iZWdpblBhdGg7XG5cbiAgY3R4Ll9yZW1vdmVNaXJyb3JpbmcgPSAoKSA9PiB7XG4gICAgY3R4LnNhdmUgPSBjdHguX19vcmlnaW5hbFNhdmU7XG4gICAgY3R4LnJlc3RvcmUgPSBjdHguX19vcmlnaW5hbFJlc3RvcmU7XG4gICAgY3R4LnJvdGF0ZSA9IGN0eC5fX29yaWdpbmFsUm90YXRlO1xuICAgIGN0eC5zY2FsZSA9IGN0eC5fX29yaWdpbmFsU2NhbGU7XG4gICAgY3R4LnRyYW5zbGF0ZSA9IGN0eC5fX29yaWdpbmFsVHJhbnNsYXRlO1xuICAgIGN0eC50cmFuc2Zvcm0gPSBjdHguX19vcmlnaW5hbFRyYW5zZm9ybTtcbiAgICBjdHguc2V0VHJhbnNmb3JtID0gY3R4Ll9fb3JpZ2luYWxTZXRUcmFuc2Zvcm07XG4gICAgY3R4LnJlc2V0VHJhbnNmb3JtID0gY3R4Ll9fb3JpZ2luYWxSZXNldFRyYW5zZm9ybTtcbiAgICBjdHguY2xpcCA9IGN0eC5fX29yaWdpbmFsQ2xpcDtcbiAgICBjdHgubW92ZVRvID0gY3R4Ll9fb3JpZ2luYWxNb3ZlVG87XG4gICAgY3R4LmxpbmVUbyA9IGN0eC5fX29yaWdpbmFsTGluZVRvO1xuICAgIGN0eC5iZXppZXJDdXJ2ZVRvID0gY3R4Ll9fb3JpZ2luYWxCZXppZXJDdXJ2ZVRvO1xuICAgIGN0eC5yZWN0ID0gY3R4Ll9fb3JpZ2luYWxSZWN0O1xuICAgIGN0eC5jbG9zZVBhdGggPSBjdHguX19vcmlnaW5hbENsb3NlUGF0aDtcbiAgICBjdHguYmVnaW5QYXRoID0gY3R4Ll9fb3JpZ2luYWxCZWdpblBhdGg7XG4gICAgZGVsZXRlIGN0eC5fcmVtb3ZlTWlycm9yaW5nO1xuICB9O1xuXG4gIGN0eC5zYXZlID0gZnVuY3Rpb24gY3R4U2F2ZSgpIHtcbiAgICBkZXN0Q3R4LnNhdmUoKTtcblxuICAgIHRoaXMuX19vcmlnaW5hbFNhdmUoKTtcbiAgfTtcblxuICBjdHgucmVzdG9yZSA9IGZ1bmN0aW9uIGN0eFJlc3RvcmUoKSB7XG4gICAgZGVzdEN0eC5yZXN0b3JlKCk7XG5cbiAgICB0aGlzLl9fb3JpZ2luYWxSZXN0b3JlKCk7XG4gIH07XG5cbiAgY3R4LnRyYW5zbGF0ZSA9IGZ1bmN0aW9uIGN0eFRyYW5zbGF0ZSh4LCB5KSB7XG4gICAgZGVzdEN0eC50cmFuc2xhdGUoeCwgeSk7XG5cbiAgICB0aGlzLl9fb3JpZ2luYWxUcmFuc2xhdGUoeCwgeSk7XG4gIH07XG5cbiAgY3R4LnNjYWxlID0gZnVuY3Rpb24gY3R4U2NhbGUoeCwgeSkge1xuICAgIGRlc3RDdHguc2NhbGUoeCwgeSk7XG5cbiAgICB0aGlzLl9fb3JpZ2luYWxTY2FsZSh4LCB5KTtcbiAgfTtcblxuICBjdHgudHJhbnNmb3JtID0gZnVuY3Rpb24gY3R4VHJhbnNmb3JtKGEsIGIsIGMsIGQsIGUsIGYpIHtcbiAgICBkZXN0Q3R4LnRyYW5zZm9ybShhLCBiLCBjLCBkLCBlLCBmKTtcblxuICAgIHRoaXMuX19vcmlnaW5hbFRyYW5zZm9ybShhLCBiLCBjLCBkLCBlLCBmKTtcbiAgfTtcblxuICBjdHguc2V0VHJhbnNmb3JtID0gZnVuY3Rpb24gY3R4U2V0VHJhbnNmb3JtKGEsIGIsIGMsIGQsIGUsIGYpIHtcbiAgICBkZXN0Q3R4LnNldFRyYW5zZm9ybShhLCBiLCBjLCBkLCBlLCBmKTtcblxuICAgIHRoaXMuX19vcmlnaW5hbFNldFRyYW5zZm9ybShhLCBiLCBjLCBkLCBlLCBmKTtcbiAgfTtcblxuICBjdHgucmVzZXRUcmFuc2Zvcm0gPSBmdW5jdGlvbiBjdHhSZXNldFRyYW5zZm9ybSgpIHtcbiAgICBkZXN0Q3R4LnJlc2V0VHJhbnNmb3JtKCk7XG5cbiAgICB0aGlzLl9fb3JpZ2luYWxSZXNldFRyYW5zZm9ybSgpO1xuICB9O1xuXG4gIGN0eC5yb3RhdGUgPSBmdW5jdGlvbiBjdHhSb3RhdGUoYW5nbGUpIHtcbiAgICBkZXN0Q3R4LnJvdGF0ZShhbmdsZSk7XG5cbiAgICB0aGlzLl9fb3JpZ2luYWxSb3RhdGUoYW5nbGUpO1xuICB9O1xuXG4gIGN0eC5jbGlwID0gZnVuY3Rpb24gY3R4Um90YXRlKHJ1bGUpIHtcbiAgICBkZXN0Q3R4LmNsaXAocnVsZSk7XG5cbiAgICB0aGlzLl9fb3JpZ2luYWxDbGlwKHJ1bGUpO1xuICB9O1xuXG4gIGN0eC5tb3ZlVG8gPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgIGRlc3RDdHgubW92ZVRvKHgsIHkpO1xuXG4gICAgdGhpcy5fX29yaWdpbmFsTW92ZVRvKHgsIHkpO1xuICB9O1xuXG4gIGN0eC5saW5lVG8gPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgIGRlc3RDdHgubGluZVRvKHgsIHkpO1xuXG4gICAgdGhpcy5fX29yaWdpbmFsTGluZVRvKHgsIHkpO1xuICB9O1xuXG4gIGN0eC5iZXppZXJDdXJ2ZVRvID0gZnVuY3Rpb24gKGNwMXgsIGNwMXksIGNwMngsIGNwMnksIHgsIHkpIHtcbiAgICBkZXN0Q3R4LmJlemllckN1cnZlVG8oY3AxeCwgY3AxeSwgY3AyeCwgY3AyeSwgeCwgeSk7XG5cbiAgICB0aGlzLl9fb3JpZ2luYWxCZXppZXJDdXJ2ZVRvKGNwMXgsIGNwMXksIGNwMngsIGNwMnksIHgsIHkpO1xuICB9O1xuXG4gIGN0eC5yZWN0ID0gZnVuY3Rpb24gKHgsIHksIHdpZHRoLCBoZWlnaHQpIHtcbiAgICBkZXN0Q3R4LnJlY3QoeCwgeSwgd2lkdGgsIGhlaWdodCk7XG5cbiAgICB0aGlzLl9fb3JpZ2luYWxSZWN0KHgsIHksIHdpZHRoLCBoZWlnaHQpO1xuICB9O1xuXG4gIGN0eC5jbG9zZVBhdGggPSBmdW5jdGlvbiAoKSB7XG4gICAgZGVzdEN0eC5jbG9zZVBhdGgoKTtcblxuICAgIHRoaXMuX19vcmlnaW5hbENsb3NlUGF0aCgpO1xuICB9O1xuXG4gIGN0eC5iZWdpblBhdGggPSBmdW5jdGlvbiAoKSB7XG4gICAgZGVzdEN0eC5iZWdpblBhdGgoKTtcblxuICAgIHRoaXMuX19vcmlnaW5hbEJlZ2luUGF0aCgpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBhZGRDb250ZXh0Q3VycmVudFRyYW5zZm9ybShjdHgpIHtcbiAgaWYgKGN0eC5fdHJhbnNmb3JtU3RhY2spIHtcbiAgICBjdHguX3RyYW5zZm9ybVN0YWNrID0gW107XG4gIH1cblxuICBpZiAoY3R4Lm1vekN1cnJlbnRUcmFuc2Zvcm0pIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjdHguX29yaWdpbmFsU2F2ZSA9IGN0eC5zYXZlO1xuICBjdHguX29yaWdpbmFsUmVzdG9yZSA9IGN0eC5yZXN0b3JlO1xuICBjdHguX29yaWdpbmFsUm90YXRlID0gY3R4LnJvdGF0ZTtcbiAgY3R4Ll9vcmlnaW5hbFNjYWxlID0gY3R4LnNjYWxlO1xuICBjdHguX29yaWdpbmFsVHJhbnNsYXRlID0gY3R4LnRyYW5zbGF0ZTtcbiAgY3R4Ll9vcmlnaW5hbFRyYW5zZm9ybSA9IGN0eC50cmFuc2Zvcm07XG4gIGN0eC5fb3JpZ2luYWxTZXRUcmFuc2Zvcm0gPSBjdHguc2V0VHJhbnNmb3JtO1xuICBjdHguX29yaWdpbmFsUmVzZXRUcmFuc2Zvcm0gPSBjdHgucmVzZXRUcmFuc2Zvcm07XG4gIGN0eC5fdHJhbnNmb3JtTWF0cml4ID0gY3R4Ll90cmFuc2Zvcm1NYXRyaXggfHwgWzEsIDAsIDAsIDEsIDAsIDBdO1xuICBjdHguX3RyYW5zZm9ybVN0YWNrID0gW107XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihPYmplY3QuZ2V0UHJvdG90eXBlT2YoY3R4KSwgXCJsaW5lV2lkdGhcIik7XG4gICAgY3R4Ll9zZXRMaW5lV2lkdGggPSBkZXNjLnNldDtcbiAgICBjdHguX2dldExpbmVXaWR0aCA9IGRlc2MuZ2V0O1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIFwibGluZVdpZHRoXCIsIHtcbiAgICAgIHNldDogZnVuY3Rpb24gc2V0TGluZVdpZHRoKHdpZHRoKSB7XG4gICAgICAgIHRoaXMuX3NldExpbmVXaWR0aCh3aWR0aCAqIExJTkVXSURUSF9TQ0FMRV9GQUNUT1IpO1xuICAgICAgfSxcbiAgICAgIGdldDogZnVuY3Rpb24gZ2V0TGluZVdpZHRoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TGluZVdpZHRoKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0gY2F0Y2ggKF8pIHt9XG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN0eCwgXCJtb3pDdXJyZW50VHJhbnNmb3JtXCIsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldEN1cnJlbnRUcmFuc2Zvcm0oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fdHJhbnNmb3JtTWF0cml4O1xuICAgIH1cbiAgfSk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIFwibW96Q3VycmVudFRyYW5zZm9ybUludmVyc2VcIiwge1xuICAgIGdldDogZnVuY3Rpb24gZ2V0Q3VycmVudFRyYW5zZm9ybUludmVyc2UoKSB7XG4gICAgICBjb25zdCBbYSwgYiwgYywgZCwgZSwgZl0gPSB0aGlzLl90cmFuc2Zvcm1NYXRyaXg7XG4gICAgICBjb25zdCBhZF9iYyA9IGEgKiBkIC0gYiAqIGM7XG4gICAgICBjb25zdCBiY19hZCA9IGIgKiBjIC0gYSAqIGQ7XG4gICAgICByZXR1cm4gW2QgLyBhZF9iYywgYiAvIGJjX2FkLCBjIC8gYmNfYWQsIGEgLyBhZF9iYywgKGQgKiBlIC0gYyAqIGYpIC8gYmNfYWQsIChiICogZSAtIGEgKiBmKSAvIGFkX2JjXTtcbiAgICB9XG4gIH0pO1xuXG4gIGN0eC5zYXZlID0gZnVuY3Rpb24gY3R4U2F2ZSgpIHtcbiAgICBjb25zdCBvbGQgPSB0aGlzLl90cmFuc2Zvcm1NYXRyaXg7XG5cbiAgICB0aGlzLl90cmFuc2Zvcm1TdGFjay5wdXNoKG9sZCk7XG5cbiAgICB0aGlzLl90cmFuc2Zvcm1NYXRyaXggPSBvbGQuc2xpY2UoMCwgNik7XG5cbiAgICB0aGlzLl9vcmlnaW5hbFNhdmUoKTtcbiAgfTtcblxuICBjdHgucmVzdG9yZSA9IGZ1bmN0aW9uIGN0eFJlc3RvcmUoKSB7XG4gICAgaWYgKHRoaXMuX3RyYW5zZm9ybVN0YWNrLmxlbmd0aCA9PT0gMCkge1xuICAgICAgKDAsIF91dGlsLndhcm4pKFwiVHJpZWQgdG8gcmVzdG9yZSBhIGN0eCB3aGVuIHRoZSBzdGFjayB3YXMgYWxyZWFkeSBlbXB0eS5cIik7XG4gICAgfVxuXG4gICAgY29uc3QgcHJldiA9IHRoaXMuX3RyYW5zZm9ybVN0YWNrLnBvcCgpO1xuXG4gICAgaWYgKHByZXYpIHtcbiAgICAgIHRoaXMuX3RyYW5zZm9ybU1hdHJpeCA9IHByZXY7XG5cbiAgICAgIHRoaXMuX29yaWdpbmFsUmVzdG9yZSgpO1xuICAgIH1cbiAgfTtcblxuICBjdHgudHJhbnNsYXRlID0gZnVuY3Rpb24gY3R4VHJhbnNsYXRlKHgsIHkpIHtcbiAgICBjb25zdCBtID0gdGhpcy5fdHJhbnNmb3JtTWF0cml4O1xuICAgIG1bNF0gPSBtWzBdICogeCArIG1bMl0gKiB5ICsgbVs0XTtcbiAgICBtWzVdID0gbVsxXSAqIHggKyBtWzNdICogeSArIG1bNV07XG5cbiAgICB0aGlzLl9vcmlnaW5hbFRyYW5zbGF0ZSh4LCB5KTtcbiAgfTtcblxuICBjdHguc2NhbGUgPSBmdW5jdGlvbiBjdHhTY2FsZSh4LCB5KSB7XG4gICAgY29uc3QgbSA9IHRoaXMuX3RyYW5zZm9ybU1hdHJpeDtcbiAgICBtWzBdICo9IHg7XG4gICAgbVsxXSAqPSB4O1xuICAgIG1bMl0gKj0geTtcbiAgICBtWzNdICo9IHk7XG5cbiAgICB0aGlzLl9vcmlnaW5hbFNjYWxlKHgsIHkpO1xuICB9O1xuXG4gIGN0eC50cmFuc2Zvcm0gPSBmdW5jdGlvbiBjdHhUcmFuc2Zvcm0oYSwgYiwgYywgZCwgZSwgZikge1xuICAgIGNvbnN0IG0gPSB0aGlzLl90cmFuc2Zvcm1NYXRyaXg7XG4gICAgdGhpcy5fdHJhbnNmb3JtTWF0cml4ID0gW21bMF0gKiBhICsgbVsyXSAqIGIsIG1bMV0gKiBhICsgbVszXSAqIGIsIG1bMF0gKiBjICsgbVsyXSAqIGQsIG1bMV0gKiBjICsgbVszXSAqIGQsIG1bMF0gKiBlICsgbVsyXSAqIGYgKyBtWzRdLCBtWzFdICogZSArIG1bM10gKiBmICsgbVs1XV07XG5cbiAgICBjdHguX29yaWdpbmFsVHJhbnNmb3JtKGEsIGIsIGMsIGQsIGUsIGYpO1xuICB9O1xuXG4gIGN0eC5zZXRUcmFuc2Zvcm0gPSBmdW5jdGlvbiBjdHhTZXRUcmFuc2Zvcm0oYSwgYiwgYywgZCwgZSwgZikge1xuICAgIHRoaXMuX3RyYW5zZm9ybU1hdHJpeCA9IFthLCBiLCBjLCBkLCBlLCBmXTtcblxuICAgIGN0eC5fb3JpZ2luYWxTZXRUcmFuc2Zvcm0oYSwgYiwgYywgZCwgZSwgZik7XG4gIH07XG5cbiAgY3R4LnJlc2V0VHJhbnNmb3JtID0gZnVuY3Rpb24gY3R4UmVzZXRUcmFuc2Zvcm0oKSB7XG4gICAgdGhpcy5fdHJhbnNmb3JtTWF0cml4ID0gWzEsIDAsIDAsIDEsIDAsIDBdO1xuXG4gICAgY3R4Ll9vcmlnaW5hbFJlc2V0VHJhbnNmb3JtKCk7XG4gIH07XG5cbiAgY3R4LnJvdGF0ZSA9IGZ1bmN0aW9uIGN0eFJvdGF0ZShhbmdsZSkge1xuICAgIGNvbnN0IGNvc1ZhbHVlID0gTWF0aC5jb3MoYW5nbGUpO1xuICAgIGNvbnN0IHNpblZhbHVlID0gTWF0aC5zaW4oYW5nbGUpO1xuICAgIGNvbnN0IG0gPSB0aGlzLl90cmFuc2Zvcm1NYXRyaXg7XG4gICAgdGhpcy5fdHJhbnNmb3JtTWF0cml4ID0gW21bMF0gKiBjb3NWYWx1ZSArIG1bMl0gKiBzaW5WYWx1ZSwgbVsxXSAqIGNvc1ZhbHVlICsgbVszXSAqIHNpblZhbHVlLCBtWzBdICogLXNpblZhbHVlICsgbVsyXSAqIGNvc1ZhbHVlLCBtWzFdICogLXNpblZhbHVlICsgbVszXSAqIGNvc1ZhbHVlLCBtWzRdLCBtWzVdXTtcblxuICAgIHRoaXMuX29yaWdpbmFsUm90YXRlKGFuZ2xlKTtcbiAgfTtcbn1cblxuY2xhc3MgQ2FjaGVkQ2FudmFzZXMge1xuICBjb25zdHJ1Y3RvcihjYW52YXNGYWN0b3J5KSB7XG4gICAgdGhpcy5jYW52YXNGYWN0b3J5ID0gY2FudmFzRmFjdG9yeTtcbiAgICB0aGlzLmNhY2hlID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgfVxuXG4gIGdldENhbnZhcyhpZCwgd2lkdGgsIGhlaWdodCwgdHJhY2tUcmFuc2Zvcm0pIHtcbiAgICBsZXQgY2FudmFzRW50cnk7XG5cbiAgICBpZiAodGhpcy5jYWNoZVtpZF0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgY2FudmFzRW50cnkgPSB0aGlzLmNhY2hlW2lkXTtcbiAgICAgIHRoaXMuY2FudmFzRmFjdG9yeS5yZXNldChjYW52YXNFbnRyeSwgd2lkdGgsIGhlaWdodCk7XG4gICAgICBjYW52YXNFbnRyeS5jb250ZXh0LnNldFRyYW5zZm9ybSgxLCAwLCAwLCAxLCAwLCAwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2FudmFzRW50cnkgPSB0aGlzLmNhbnZhc0ZhY3RvcnkuY3JlYXRlKHdpZHRoLCBoZWlnaHQpO1xuICAgICAgdGhpcy5jYWNoZVtpZF0gPSBjYW52YXNFbnRyeTtcbiAgICB9XG5cbiAgICBpZiAodHJhY2tUcmFuc2Zvcm0pIHtcbiAgICAgIGFkZENvbnRleHRDdXJyZW50VHJhbnNmb3JtKGNhbnZhc0VudHJ5LmNvbnRleHQpO1xuICAgIH1cblxuICAgIHJldHVybiBjYW52YXNFbnRyeTtcbiAgfVxuXG4gIGRlbGV0ZShpZCkge1xuICAgIGRlbGV0ZSB0aGlzLmNhY2hlW2lkXTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIGZvciAoY29uc3QgaWQgaW4gdGhpcy5jYWNoZSkge1xuICAgICAgY29uc3QgY2FudmFzRW50cnkgPSB0aGlzLmNhY2hlW2lkXTtcbiAgICAgIHRoaXMuY2FudmFzRmFjdG9yeS5kZXN0cm95KGNhbnZhc0VudHJ5KTtcbiAgICAgIGRlbGV0ZSB0aGlzLmNhY2hlW2lkXTtcbiAgICB9XG4gIH1cblxufVxuXG5mdW5jdGlvbiBkcmF3SW1hZ2VBdEludGVnZXJDb29yZHMoY3R4LCBzcmNJbWcsIHNyY1gsIHNyY1ksIHNyY1csIHNyY0gsIGRlc3RYLCBkZXN0WSwgZGVzdFcsIGRlc3RIKSB7XG4gIGNvbnN0IFthLCBiLCBjLCBkLCB0eCwgdHldID0gY3R4Lm1vekN1cnJlbnRUcmFuc2Zvcm07XG5cbiAgaWYgKGIgPT09IDAgJiYgYyA9PT0gMCkge1xuICAgIGNvbnN0IHRsWCA9IGRlc3RYICogYSArIHR4O1xuICAgIGNvbnN0IHJUbFggPSBNYXRoLnJvdW5kKHRsWCk7XG4gICAgY29uc3QgdGxZID0gZGVzdFkgKiBkICsgdHk7XG4gICAgY29uc3QgclRsWSA9IE1hdGgucm91bmQodGxZKTtcbiAgICBjb25zdCBiclggPSAoZGVzdFggKyBkZXN0VykgKiBhICsgdHg7XG4gICAgY29uc3QgcldpZHRoID0gTWF0aC5hYnMoTWF0aC5yb3VuZChiclgpIC0gclRsWCkgfHwgMTtcbiAgICBjb25zdCBiclkgPSAoZGVzdFkgKyBkZXN0SCkgKiBkICsgdHk7XG4gICAgY29uc3QgckhlaWdodCA9IE1hdGguYWJzKE1hdGgucm91bmQoYnJZKSAtIHJUbFkpIHx8IDE7XG4gICAgY3R4LnNldFRyYW5zZm9ybShNYXRoLnNpZ24oYSksIDAsIDAsIE1hdGguc2lnbihkKSwgclRsWCwgclRsWSk7XG4gICAgY3R4LmRyYXdJbWFnZShzcmNJbWcsIHNyY1gsIHNyY1ksIHNyY1csIHNyY0gsIDAsIDAsIHJXaWR0aCwgckhlaWdodCk7XG4gICAgY3R4LnNldFRyYW5zZm9ybShhLCBiLCBjLCBkLCB0eCwgdHkpO1xuICAgIHJldHVybiBbcldpZHRoLCBySGVpZ2h0XTtcbiAgfVxuXG4gIGlmIChhID09PSAwICYmIGQgPT09IDApIHtcbiAgICBjb25zdCB0bFggPSBkZXN0WSAqIGMgKyB0eDtcbiAgICBjb25zdCByVGxYID0gTWF0aC5yb3VuZCh0bFgpO1xuICAgIGNvbnN0IHRsWSA9IGRlc3RYICogYiArIHR5O1xuICAgIGNvbnN0IHJUbFkgPSBNYXRoLnJvdW5kKHRsWSk7XG4gICAgY29uc3QgYnJYID0gKGRlc3RZICsgZGVzdEgpICogYyArIHR4O1xuICAgIGNvbnN0IHJXaWR0aCA9IE1hdGguYWJzKE1hdGgucm91bmQoYnJYKSAtIHJUbFgpIHx8IDE7XG4gICAgY29uc3QgYnJZID0gKGRlc3RYICsgZGVzdFcpICogYiArIHR5O1xuICAgIGNvbnN0IHJIZWlnaHQgPSBNYXRoLmFicyhNYXRoLnJvdW5kKGJyWSkgLSByVGxZKSB8fCAxO1xuICAgIGN0eC5zZXRUcmFuc2Zvcm0oMCwgTWF0aC5zaWduKGIpLCBNYXRoLnNpZ24oYyksIDAsIHJUbFgsIHJUbFkpO1xuICAgIGN0eC5kcmF3SW1hZ2Uoc3JjSW1nLCBzcmNYLCBzcmNZLCBzcmNXLCBzcmNILCAwLCAwLCBySGVpZ2h0LCByV2lkdGgpO1xuICAgIGN0eC5zZXRUcmFuc2Zvcm0oYSwgYiwgYywgZCwgdHgsIHR5KTtcbiAgICByZXR1cm4gW3JIZWlnaHQsIHJXaWR0aF07XG4gIH1cblxuICBjdHguZHJhd0ltYWdlKHNyY0ltZywgc3JjWCwgc3JjWSwgc3JjVywgc3JjSCwgZGVzdFgsIGRlc3RZLCBkZXN0VywgZGVzdEgpO1xuICBjb25zdCBzY2FsZVggPSBNYXRoLmh5cG90KGEsIGIpO1xuICBjb25zdCBzY2FsZVkgPSBNYXRoLmh5cG90KGMsIGQpO1xuICByZXR1cm4gW3NjYWxlWCAqIGRlc3RXLCBzY2FsZVkgKiBkZXN0SF07XG59XG5cbmZ1bmN0aW9uIGNvbXBpbGVUeXBlM0dseXBoKGltZ0RhdGEpIHtcbiAgY29uc3Qge1xuICAgIHdpZHRoLFxuICAgIGhlaWdodFxuICB9ID0gaW1nRGF0YTtcblxuICBpZiAoIUNPTVBJTEVfVFlQRTNfR0xZUEhTIHx8IHdpZHRoID4gTUFYX1NJWkVfVE9fQ09NUElMRSB8fCBoZWlnaHQgPiBNQVhfU0laRV9UT19DT01QSUxFKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBQT0lOVF9UT19QUk9DRVNTX0xJTUlUID0gMTAwMDtcbiAgY29uc3QgUE9JTlRfVFlQRVMgPSBuZXcgVWludDhBcnJheShbMCwgMiwgNCwgMCwgMSwgMCwgNSwgNCwgOCwgMTAsIDAsIDgsIDAsIDIsIDEsIDBdKTtcbiAgY29uc3Qgd2lkdGgxID0gd2lkdGggKyAxO1xuICBsZXQgcG9pbnRzID0gbmV3IFVpbnQ4QXJyYXkod2lkdGgxICogKGhlaWdodCArIDEpKTtcbiAgbGV0IGksIGosIGowO1xuICBjb25zdCBsaW5lU2l6ZSA9IHdpZHRoICsgNyAmIH43O1xuICBsZXQgZGF0YSA9IG5ldyBVaW50OEFycmF5KGxpbmVTaXplICogaGVpZ2h0KSxcbiAgICAgIHBvcyA9IDA7XG5cbiAgZm9yIChjb25zdCBlbGVtIG9mIGltZ0RhdGEuZGF0YSkge1xuICAgIGxldCBtYXNrID0gMTI4O1xuXG4gICAgd2hpbGUgKG1hc2sgPiAwKSB7XG4gICAgICBkYXRhW3BvcysrXSA9IGVsZW0gJiBtYXNrID8gMCA6IDI1NTtcbiAgICAgIG1hc2sgPj49IDE7XG4gICAgfVxuICB9XG5cbiAgbGV0IGNvdW50ID0gMDtcbiAgcG9zID0gMDtcblxuICBpZiAoZGF0YVtwb3NdICE9PSAwKSB7XG4gICAgcG9pbnRzWzBdID0gMTtcbiAgICArK2NvdW50O1xuICB9XG5cbiAgZm9yIChqID0gMTsgaiA8IHdpZHRoOyBqKyspIHtcbiAgICBpZiAoZGF0YVtwb3NdICE9PSBkYXRhW3BvcyArIDFdKSB7XG4gICAgICBwb2ludHNbal0gPSBkYXRhW3Bvc10gPyAyIDogMTtcbiAgICAgICsrY291bnQ7XG4gICAgfVxuXG4gICAgcG9zKys7XG4gIH1cblxuICBpZiAoZGF0YVtwb3NdICE9PSAwKSB7XG4gICAgcG9pbnRzW2pdID0gMjtcbiAgICArK2NvdW50O1xuICB9XG5cbiAgZm9yIChpID0gMTsgaSA8IGhlaWdodDsgaSsrKSB7XG4gICAgcG9zID0gaSAqIGxpbmVTaXplO1xuICAgIGowID0gaSAqIHdpZHRoMTtcblxuICAgIGlmIChkYXRhW3BvcyAtIGxpbmVTaXplXSAhPT0gZGF0YVtwb3NdKSB7XG4gICAgICBwb2ludHNbajBdID0gZGF0YVtwb3NdID8gMSA6IDg7XG4gICAgICArK2NvdW50O1xuICAgIH1cblxuICAgIGxldCBzdW0gPSAoZGF0YVtwb3NdID8gNCA6IDApICsgKGRhdGFbcG9zIC0gbGluZVNpemVdID8gOCA6IDApO1xuXG4gICAgZm9yIChqID0gMTsgaiA8IHdpZHRoOyBqKyspIHtcbiAgICAgIHN1bSA9IChzdW0gPj4gMikgKyAoZGF0YVtwb3MgKyAxXSA/IDQgOiAwKSArIChkYXRhW3BvcyAtIGxpbmVTaXplICsgMV0gPyA4IDogMCk7XG5cbiAgICAgIGlmIChQT0lOVF9UWVBFU1tzdW1dKSB7XG4gICAgICAgIHBvaW50c1tqMCArIGpdID0gUE9JTlRfVFlQRVNbc3VtXTtcbiAgICAgICAgKytjb3VudDtcbiAgICAgIH1cblxuICAgICAgcG9zKys7XG4gICAgfVxuXG4gICAgaWYgKGRhdGFbcG9zIC0gbGluZVNpemVdICE9PSBkYXRhW3Bvc10pIHtcbiAgICAgIHBvaW50c1tqMCArIGpdID0gZGF0YVtwb3NdID8gMiA6IDQ7XG4gICAgICArK2NvdW50O1xuICAgIH1cblxuICAgIGlmIChjb3VudCA+IFBPSU5UX1RPX1BST0NFU1NfTElNSVQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHBvcyA9IGxpbmVTaXplICogKGhlaWdodCAtIDEpO1xuICBqMCA9IGkgKiB3aWR0aDE7XG5cbiAgaWYgKGRhdGFbcG9zXSAhPT0gMCkge1xuICAgIHBvaW50c1tqMF0gPSA4O1xuICAgICsrY291bnQ7XG4gIH1cblxuICBmb3IgKGogPSAxOyBqIDwgd2lkdGg7IGorKykge1xuICAgIGlmIChkYXRhW3Bvc10gIT09IGRhdGFbcG9zICsgMV0pIHtcbiAgICAgIHBvaW50c1tqMCArIGpdID0gZGF0YVtwb3NdID8gNCA6IDg7XG4gICAgICArK2NvdW50O1xuICAgIH1cblxuICAgIHBvcysrO1xuICB9XG5cbiAgaWYgKGRhdGFbcG9zXSAhPT0gMCkge1xuICAgIHBvaW50c1tqMCArIGpdID0gNDtcbiAgICArK2NvdW50O1xuICB9XG5cbiAgaWYgKGNvdW50ID4gUE9JTlRfVE9fUFJPQ0VTU19MSU1JVCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3Qgc3RlcHMgPSBuZXcgSW50MzJBcnJheShbMCwgd2lkdGgxLCAtMSwgMCwgLXdpZHRoMSwgMCwgMCwgMCwgMV0pO1xuICBsZXQgcGF0aCwgb3V0bGluZXMsIGNvb3JkcztcblxuICBpZiAoIV9pc19ub2RlLmlzTm9kZUpTKSB7XG4gICAgcGF0aCA9IG5ldyBQYXRoMkQoKTtcbiAgfSBlbHNlIHtcbiAgICBvdXRsaW5lcyA9IFtdO1xuICB9XG5cbiAgZm9yIChpID0gMDsgY291bnQgJiYgaSA8PSBoZWlnaHQ7IGkrKykge1xuICAgIGxldCBwID0gaSAqIHdpZHRoMTtcbiAgICBjb25zdCBlbmQgPSBwICsgd2lkdGg7XG5cbiAgICB3aGlsZSAocCA8IGVuZCAmJiAhcG9pbnRzW3BdKSB7XG4gICAgICBwKys7XG4gICAgfVxuXG4gICAgaWYgKHAgPT09IGVuZCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHBhdGgpIHtcbiAgICAgIHBhdGgubW92ZVRvKHAgJSB3aWR0aDEsIGkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb29yZHMgPSBbcCAlIHdpZHRoMSwgaV07XG4gICAgfVxuXG4gICAgY29uc3QgcDAgPSBwO1xuICAgIGxldCB0eXBlID0gcG9pbnRzW3BdO1xuXG4gICAgZG8ge1xuICAgICAgY29uc3Qgc3RlcCA9IHN0ZXBzW3R5cGVdO1xuXG4gICAgICBkbyB7XG4gICAgICAgIHAgKz0gc3RlcDtcbiAgICAgIH0gd2hpbGUgKCFwb2ludHNbcF0pO1xuXG4gICAgICBjb25zdCBwcCA9IHBvaW50c1twXTtcblxuICAgICAgaWYgKHBwICE9PSA1ICYmIHBwICE9PSAxMCkge1xuICAgICAgICB0eXBlID0gcHA7XG4gICAgICAgIHBvaW50c1twXSA9IDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0eXBlID0gcHAgJiAweDMzICogdHlwZSA+PiA0O1xuICAgICAgICBwb2ludHNbcF0gJj0gdHlwZSA+PiAyIHwgdHlwZSA8PCAyO1xuICAgICAgfVxuXG4gICAgICBpZiAocGF0aCkge1xuICAgICAgICBwYXRoLmxpbmVUbyhwICUgd2lkdGgxLCBwIC8gd2lkdGgxIHwgMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb29yZHMucHVzaChwICUgd2lkdGgxLCBwIC8gd2lkdGgxIHwgMCk7XG4gICAgICB9XG5cbiAgICAgIGlmICghcG9pbnRzW3BdKSB7XG4gICAgICAgIC0tY291bnQ7XG4gICAgICB9XG4gICAgfSB3aGlsZSAocDAgIT09IHApO1xuXG4gICAgaWYgKCFwYXRoKSB7XG4gICAgICBvdXRsaW5lcy5wdXNoKGNvb3Jkcyk7XG4gICAgfVxuXG4gICAgLS1pO1xuICB9XG5cbiAgZGF0YSA9IG51bGw7XG4gIHBvaW50cyA9IG51bGw7XG5cbiAgY29uc3QgZHJhd091dGxpbmUgPSBmdW5jdGlvbiAoYykge1xuICAgIGMuc2F2ZSgpO1xuICAgIGMuc2NhbGUoMSAvIHdpZHRoLCAtMSAvIGhlaWdodCk7XG4gICAgYy50cmFuc2xhdGUoMCwgLWhlaWdodCk7XG5cbiAgICBpZiAocGF0aCkge1xuICAgICAgYy5maWxsKHBhdGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjLmJlZ2luUGF0aCgpO1xuXG4gICAgICBmb3IgKGNvbnN0IG8gb2Ygb3V0bGluZXMpIHtcbiAgICAgICAgYy5tb3ZlVG8ob1swXSwgb1sxXSk7XG5cbiAgICAgICAgZm9yIChsZXQgbCA9IDIsIGxsID0gby5sZW5ndGg7IGwgPCBsbDsgbCArPSAyKSB7XG4gICAgICAgICAgYy5saW5lVG8ob1tsXSwgb1tsICsgMV0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGMuZmlsbCgpO1xuICAgIH1cblxuICAgIGMuYmVnaW5QYXRoKCk7XG4gICAgYy5yZXN0b3JlKCk7XG4gIH07XG5cbiAgcmV0dXJuIGRyYXdPdXRsaW5lO1xufVxuXG5jbGFzcyBDYW52YXNFeHRyYVN0YXRlIHtcbiAgY29uc3RydWN0b3Iod2lkdGgsIGhlaWdodCkge1xuICAgIHRoaXMuYWxwaGFJc1NoYXBlID0gZmFsc2U7XG4gICAgdGhpcy5mb250U2l6ZSA9IDA7XG4gICAgdGhpcy5mb250U2l6ZVNjYWxlID0gMTtcbiAgICB0aGlzLnRleHRNYXRyaXggPSBfdXRpbC5JREVOVElUWV9NQVRSSVg7XG4gICAgdGhpcy50ZXh0TWF0cml4U2NhbGUgPSAxO1xuICAgIHRoaXMuZm9udE1hdHJpeCA9IF91dGlsLkZPTlRfSURFTlRJVFlfTUFUUklYO1xuICAgIHRoaXMubGVhZGluZyA9IDA7XG4gICAgdGhpcy54ID0gMDtcbiAgICB0aGlzLnkgPSAwO1xuICAgIHRoaXMubGluZVggPSAwO1xuICAgIHRoaXMubGluZVkgPSAwO1xuICAgIHRoaXMuY2hhclNwYWNpbmcgPSAwO1xuICAgIHRoaXMud29yZFNwYWNpbmcgPSAwO1xuICAgIHRoaXMudGV4dEhTY2FsZSA9IDE7XG4gICAgdGhpcy50ZXh0UmVuZGVyaW5nTW9kZSA9IF91dGlsLlRleHRSZW5kZXJpbmdNb2RlLkZJTEw7XG4gICAgdGhpcy50ZXh0UmlzZSA9IDA7XG4gICAgdGhpcy5maWxsQ29sb3IgPSBcIiMwMDAwMDBcIjtcbiAgICB0aGlzLnN0cm9rZUNvbG9yID0gXCIjMDAwMDAwXCI7XG4gICAgdGhpcy5wYXR0ZXJuRmlsbCA9IGZhbHNlO1xuICAgIHRoaXMuZmlsbEFscGhhID0gMTtcbiAgICB0aGlzLnN0cm9rZUFscGhhID0gMTtcbiAgICB0aGlzLmxpbmVXaWR0aCA9IDE7XG4gICAgdGhpcy5hY3RpdmVTTWFzayA9IG51bGw7XG4gICAgdGhpcy50cmFuc2Zlck1hcHMgPSBudWxsO1xuICAgIHRoaXMuc3RhcnROZXdQYXRoQW5kQ2xpcEJveChbMCwgMCwgd2lkdGgsIGhlaWdodF0pO1xuICB9XG5cbiAgY2xvbmUoKSB7XG4gICAgY29uc3QgY2xvbmUgPSBPYmplY3QuY3JlYXRlKHRoaXMpO1xuICAgIGNsb25lLmNsaXBCb3ggPSB0aGlzLmNsaXBCb3guc2xpY2UoKTtcbiAgICByZXR1cm4gY2xvbmU7XG4gIH1cblxuICBzZXRDdXJyZW50UG9pbnQoeCwgeSkge1xuICAgIHRoaXMueCA9IHg7XG4gICAgdGhpcy55ID0geTtcbiAgfVxuXG4gIHVwZGF0ZVBhdGhNaW5NYXgodHJhbnNmb3JtLCB4LCB5KSB7XG4gICAgW3gsIHldID0gX3V0aWwuVXRpbC5hcHBseVRyYW5zZm9ybShbeCwgeV0sIHRyYW5zZm9ybSk7XG4gICAgdGhpcy5taW5YID0gTWF0aC5taW4odGhpcy5taW5YLCB4KTtcbiAgICB0aGlzLm1pblkgPSBNYXRoLm1pbih0aGlzLm1pblksIHkpO1xuICAgIHRoaXMubWF4WCA9IE1hdGgubWF4KHRoaXMubWF4WCwgeCk7XG4gICAgdGhpcy5tYXhZID0gTWF0aC5tYXgodGhpcy5tYXhZLCB5KTtcbiAgfVxuXG4gIHVwZGF0ZVJlY3RNaW5NYXgodHJhbnNmb3JtLCByZWN0KSB7XG4gICAgY29uc3QgcDEgPSBfdXRpbC5VdGlsLmFwcGx5VHJhbnNmb3JtKHJlY3QsIHRyYW5zZm9ybSk7XG5cbiAgICBjb25zdCBwMiA9IF91dGlsLlV0aWwuYXBwbHlUcmFuc2Zvcm0ocmVjdC5zbGljZSgyKSwgdHJhbnNmb3JtKTtcblxuICAgIHRoaXMubWluWCA9IE1hdGgubWluKHRoaXMubWluWCwgcDFbMF0sIHAyWzBdKTtcbiAgICB0aGlzLm1pblkgPSBNYXRoLm1pbih0aGlzLm1pblksIHAxWzFdLCBwMlsxXSk7XG4gICAgdGhpcy5tYXhYID0gTWF0aC5tYXgodGhpcy5tYXhYLCBwMVswXSwgcDJbMF0pO1xuICAgIHRoaXMubWF4WSA9IE1hdGgubWF4KHRoaXMubWF4WSwgcDFbMV0sIHAyWzFdKTtcbiAgfVxuXG4gIHVwZGF0ZVNjYWxpbmdQYXRoTWluTWF4KHRyYW5zZm9ybSwgbWluTWF4KSB7XG4gICAgX3V0aWwuVXRpbC5zY2FsZU1pbk1heCh0cmFuc2Zvcm0sIG1pbk1heCk7XG5cbiAgICB0aGlzLm1pblggPSBNYXRoLm1pbih0aGlzLm1pblgsIG1pbk1heFswXSk7XG4gICAgdGhpcy5tYXhYID0gTWF0aC5tYXgodGhpcy5tYXhYLCBtaW5NYXhbMV0pO1xuICAgIHRoaXMubWluWSA9IE1hdGgubWluKHRoaXMubWluWSwgbWluTWF4WzJdKTtcbiAgICB0aGlzLm1heFkgPSBNYXRoLm1heCh0aGlzLm1heFksIG1pbk1heFszXSk7XG4gIH1cblxuICB1cGRhdGVDdXJ2ZVBhdGhNaW5NYXgodHJhbnNmb3JtLCB4MCwgeTAsIHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIG1pbk1heCkge1xuICAgIGNvbnN0IGJveCA9IF91dGlsLlV0aWwuYmV6aWVyQm91bmRpbmdCb3goeDAsIHkwLCB4MSwgeTEsIHgyLCB5MiwgeDMsIHkzKTtcblxuICAgIGlmIChtaW5NYXgpIHtcbiAgICAgIG1pbk1heFswXSA9IE1hdGgubWluKG1pbk1heFswXSwgYm94WzBdLCBib3hbMl0pO1xuICAgICAgbWluTWF4WzFdID0gTWF0aC5tYXgobWluTWF4WzFdLCBib3hbMF0sIGJveFsyXSk7XG4gICAgICBtaW5NYXhbMl0gPSBNYXRoLm1pbihtaW5NYXhbMl0sIGJveFsxXSwgYm94WzNdKTtcbiAgICAgIG1pbk1heFszXSA9IE1hdGgubWF4KG1pbk1heFszXSwgYm94WzFdLCBib3hbM10pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlUmVjdE1pbk1heCh0cmFuc2Zvcm0sIGJveCk7XG4gIH1cblxuICBnZXRQYXRoQm91bmRpbmdCb3gocGF0aFR5cGUgPSBfcGF0dGVybl9oZWxwZXIuUGF0aFR5cGUuRklMTCwgdHJhbnNmb3JtID0gbnVsbCkge1xuICAgIGNvbnN0IGJveCA9IFt0aGlzLm1pblgsIHRoaXMubWluWSwgdGhpcy5tYXhYLCB0aGlzLm1heFldO1xuXG4gICAgaWYgKHBhdGhUeXBlID09PSBfcGF0dGVybl9oZWxwZXIuUGF0aFR5cGUuU1RST0tFKSB7XG4gICAgICBpZiAoIXRyYW5zZm9ybSkge1xuICAgICAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiU3Ryb2tlIGJvdW5kaW5nIGJveCBtdXN0IGluY2x1ZGUgdHJhbnNmb3JtLlwiKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc2NhbGUgPSBfdXRpbC5VdGlsLnNpbmd1bGFyVmFsdWVEZWNvbXBvc2UyZFNjYWxlKHRyYW5zZm9ybSk7XG5cbiAgICAgIGNvbnN0IHhTdHJva2VQYWQgPSBzY2FsZVswXSAqIHRoaXMubGluZVdpZHRoIC8gMjtcbiAgICAgIGNvbnN0IHlTdHJva2VQYWQgPSBzY2FsZVsxXSAqIHRoaXMubGluZVdpZHRoIC8gMjtcbiAgICAgIGJveFswXSAtPSB4U3Ryb2tlUGFkO1xuICAgICAgYm94WzFdIC09IHlTdHJva2VQYWQ7XG4gICAgICBib3hbMl0gKz0geFN0cm9rZVBhZDtcbiAgICAgIGJveFszXSArPSB5U3Ryb2tlUGFkO1xuICAgIH1cblxuICAgIHJldHVybiBib3g7XG4gIH1cblxuICB1cGRhdGVDbGlwRnJvbVBhdGgoKSB7XG4gICAgY29uc3QgaW50ZXJzZWN0ID0gX3V0aWwuVXRpbC5pbnRlcnNlY3QodGhpcy5jbGlwQm94LCB0aGlzLmdldFBhdGhCb3VuZGluZ0JveCgpKTtcblxuICAgIHRoaXMuc3RhcnROZXdQYXRoQW5kQ2xpcEJveChpbnRlcnNlY3QgfHwgWzAsIDAsIDAsIDBdKTtcbiAgfVxuXG4gIGlzRW1wdHlDbGlwKCkge1xuICAgIHJldHVybiB0aGlzLm1pblggPT09IEluZmluaXR5O1xuICB9XG5cbiAgc3RhcnROZXdQYXRoQW5kQ2xpcEJveChib3gpIHtcbiAgICB0aGlzLmNsaXBCb3ggPSBib3g7XG4gICAgdGhpcy5taW5YID0gSW5maW5pdHk7XG4gICAgdGhpcy5taW5ZID0gSW5maW5pdHk7XG4gICAgdGhpcy5tYXhYID0gMDtcbiAgICB0aGlzLm1heFkgPSAwO1xuICB9XG5cbiAgZ2V0Q2xpcHBlZFBhdGhCb3VuZGluZ0JveChwYXRoVHlwZSA9IF9wYXR0ZXJuX2hlbHBlci5QYXRoVHlwZS5GSUxMLCB0cmFuc2Zvcm0gPSBudWxsKSB7XG4gICAgcmV0dXJuIF91dGlsLlV0aWwuaW50ZXJzZWN0KHRoaXMuY2xpcEJveCwgdGhpcy5nZXRQYXRoQm91bmRpbmdCb3gocGF0aFR5cGUsIHRyYW5zZm9ybSkpO1xuICB9XG5cbn1cblxuZnVuY3Rpb24gcHV0QmluYXJ5SW1hZ2VEYXRhKGN0eCwgaW1nRGF0YSwgdHJhbnNmZXJNYXBzID0gbnVsbCkge1xuICBpZiAodHlwZW9mIEltYWdlRGF0YSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBpbWdEYXRhIGluc3RhbmNlb2YgSW1hZ2VEYXRhKSB7XG4gICAgY3R4LnB1dEltYWdlRGF0YShpbWdEYXRhLCAwLCAwKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBoZWlnaHQgPSBpbWdEYXRhLmhlaWdodCxcbiAgICAgICAgd2lkdGggPSBpbWdEYXRhLndpZHRoO1xuICBjb25zdCBwYXJ0aWFsQ2h1bmtIZWlnaHQgPSBoZWlnaHQgJSBGVUxMX0NIVU5LX0hFSUdIVDtcbiAgY29uc3QgZnVsbENodW5rcyA9IChoZWlnaHQgLSBwYXJ0aWFsQ2h1bmtIZWlnaHQpIC8gRlVMTF9DSFVOS19IRUlHSFQ7XG4gIGNvbnN0IHRvdGFsQ2h1bmtzID0gcGFydGlhbENodW5rSGVpZ2h0ID09PSAwID8gZnVsbENodW5rcyA6IGZ1bGxDaHVua3MgKyAxO1xuICBjb25zdCBjaHVua0ltZ0RhdGEgPSBjdHguY3JlYXRlSW1hZ2VEYXRhKHdpZHRoLCBGVUxMX0NIVU5LX0hFSUdIVCk7XG4gIGxldCBzcmNQb3MgPSAwLFxuICAgICAgZGVzdFBvcztcbiAgY29uc3Qgc3JjID0gaW1nRGF0YS5kYXRhO1xuICBjb25zdCBkZXN0ID0gY2h1bmtJbWdEYXRhLmRhdGE7XG4gIGxldCBpLCBqLCB0aGlzQ2h1bmtIZWlnaHQsIGVsZW1zSW5UaGlzQ2h1bms7XG4gIGxldCB0cmFuc2Zlck1hcFJlZCwgdHJhbnNmZXJNYXBHcmVlbiwgdHJhbnNmZXJNYXBCbHVlLCB0cmFuc2Zlck1hcEdyYXk7XG5cbiAgaWYgKHRyYW5zZmVyTWFwcykge1xuICAgIHN3aXRjaCAodHJhbnNmZXJNYXBzLmxlbmd0aCkge1xuICAgICAgY2FzZSAxOlxuICAgICAgICB0cmFuc2Zlck1hcFJlZCA9IHRyYW5zZmVyTWFwc1swXTtcbiAgICAgICAgdHJhbnNmZXJNYXBHcmVlbiA9IHRyYW5zZmVyTWFwc1swXTtcbiAgICAgICAgdHJhbnNmZXJNYXBCbHVlID0gdHJhbnNmZXJNYXBzWzBdO1xuICAgICAgICB0cmFuc2Zlck1hcEdyYXkgPSB0cmFuc2Zlck1hcHNbMF07XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIDQ6XG4gICAgICAgIHRyYW5zZmVyTWFwUmVkID0gdHJhbnNmZXJNYXBzWzBdO1xuICAgICAgICB0cmFuc2Zlck1hcEdyZWVuID0gdHJhbnNmZXJNYXBzWzFdO1xuICAgICAgICB0cmFuc2Zlck1hcEJsdWUgPSB0cmFuc2Zlck1hcHNbMl07XG4gICAgICAgIHRyYW5zZmVyTWFwR3JheSA9IHRyYW5zZmVyTWFwc1szXTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKGltZ0RhdGEua2luZCA9PT0gX3V0aWwuSW1hZ2VLaW5kLkdSQVlTQ0FMRV8xQlBQKSB7XG4gICAgY29uc3Qgc3JjTGVuZ3RoID0gc3JjLmJ5dGVMZW5ndGg7XG4gICAgY29uc3QgZGVzdDMyID0gbmV3IFVpbnQzMkFycmF5KGRlc3QuYnVmZmVyLCAwLCBkZXN0LmJ5dGVMZW5ndGggPj4gMik7XG4gICAgY29uc3QgZGVzdDMyRGF0YUxlbmd0aCA9IGRlc3QzMi5sZW5ndGg7XG4gICAgY29uc3QgZnVsbFNyY0RpZmYgPSB3aWR0aCArIDcgPj4gMztcbiAgICBsZXQgd2hpdGUgPSAweGZmZmZmZmZmO1xuICAgIGxldCBibGFjayA9IF91dGlsLkZlYXR1cmVUZXN0LmlzTGl0dGxlRW5kaWFuID8gMHhmZjAwMDAwMCA6IDB4MDAwMDAwZmY7XG5cbiAgICBpZiAodHJhbnNmZXJNYXBHcmF5KSB7XG4gICAgICBpZiAodHJhbnNmZXJNYXBHcmF5WzBdID09PSAweGZmICYmIHRyYW5zZmVyTWFwR3JheVsweGZmXSA9PT0gMCkge1xuICAgICAgICBbd2hpdGUsIGJsYWNrXSA9IFtibGFjaywgd2hpdGVdO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoaSA9IDA7IGkgPCB0b3RhbENodW5rczsgaSsrKSB7XG4gICAgICB0aGlzQ2h1bmtIZWlnaHQgPSBpIDwgZnVsbENodW5rcyA/IEZVTExfQ0hVTktfSEVJR0hUIDogcGFydGlhbENodW5rSGVpZ2h0O1xuICAgICAgZGVzdFBvcyA9IDA7XG5cbiAgICAgIGZvciAoaiA9IDA7IGogPCB0aGlzQ2h1bmtIZWlnaHQ7IGorKykge1xuICAgICAgICBjb25zdCBzcmNEaWZmID0gc3JjTGVuZ3RoIC0gc3JjUG9zO1xuICAgICAgICBsZXQgayA9IDA7XG4gICAgICAgIGNvbnN0IGtFbmQgPSBzcmNEaWZmID4gZnVsbFNyY0RpZmYgPyB3aWR0aCA6IHNyY0RpZmYgKiA4IC0gNztcbiAgICAgICAgY29uc3Qga0VuZFVucm9sbGVkID0ga0VuZCAmIH43O1xuICAgICAgICBsZXQgbWFzayA9IDA7XG4gICAgICAgIGxldCBzcmNCeXRlID0gMDtcblxuICAgICAgICBmb3IgKDsgayA8IGtFbmRVbnJvbGxlZDsgayArPSA4KSB7XG4gICAgICAgICAgc3JjQnl0ZSA9IHNyY1tzcmNQb3MrK107XG4gICAgICAgICAgZGVzdDMyW2Rlc3RQb3MrK10gPSBzcmNCeXRlICYgMTI4ID8gd2hpdGUgOiBibGFjaztcbiAgICAgICAgICBkZXN0MzJbZGVzdFBvcysrXSA9IHNyY0J5dGUgJiA2NCA/IHdoaXRlIDogYmxhY2s7XG4gICAgICAgICAgZGVzdDMyW2Rlc3RQb3MrK10gPSBzcmNCeXRlICYgMzIgPyB3aGl0ZSA6IGJsYWNrO1xuICAgICAgICAgIGRlc3QzMltkZXN0UG9zKytdID0gc3JjQnl0ZSAmIDE2ID8gd2hpdGUgOiBibGFjaztcbiAgICAgICAgICBkZXN0MzJbZGVzdFBvcysrXSA9IHNyY0J5dGUgJiA4ID8gd2hpdGUgOiBibGFjaztcbiAgICAgICAgICBkZXN0MzJbZGVzdFBvcysrXSA9IHNyY0J5dGUgJiA0ID8gd2hpdGUgOiBibGFjaztcbiAgICAgICAgICBkZXN0MzJbZGVzdFBvcysrXSA9IHNyY0J5dGUgJiAyID8gd2hpdGUgOiBibGFjaztcbiAgICAgICAgICBkZXN0MzJbZGVzdFBvcysrXSA9IHNyY0J5dGUgJiAxID8gd2hpdGUgOiBibGFjaztcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoOyBrIDwga0VuZDsgaysrKSB7XG4gICAgICAgICAgaWYgKG1hc2sgPT09IDApIHtcbiAgICAgICAgICAgIHNyY0J5dGUgPSBzcmNbc3JjUG9zKytdO1xuICAgICAgICAgICAgbWFzayA9IDEyODtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkZXN0MzJbZGVzdFBvcysrXSA9IHNyY0J5dGUgJiBtYXNrID8gd2hpdGUgOiBibGFjaztcbiAgICAgICAgICBtYXNrID4+PSAxO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHdoaWxlIChkZXN0UG9zIDwgZGVzdDMyRGF0YUxlbmd0aCkge1xuICAgICAgICBkZXN0MzJbZGVzdFBvcysrXSA9IDA7XG4gICAgICB9XG5cbiAgICAgIGN0eC5wdXRJbWFnZURhdGEoY2h1bmtJbWdEYXRhLCAwLCBpICogRlVMTF9DSFVOS19IRUlHSFQpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpbWdEYXRhLmtpbmQgPT09IF91dGlsLkltYWdlS2luZC5SR0JBXzMyQlBQKSB7XG4gICAgY29uc3QgaGFzVHJhbnNmZXJNYXBzID0gISEodHJhbnNmZXJNYXBSZWQgfHwgdHJhbnNmZXJNYXBHcmVlbiB8fCB0cmFuc2Zlck1hcEJsdWUpO1xuICAgIGogPSAwO1xuICAgIGVsZW1zSW5UaGlzQ2h1bmsgPSB3aWR0aCAqIEZVTExfQ0hVTktfSEVJR0hUICogNDtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBmdWxsQ2h1bmtzOyBpKyspIHtcbiAgICAgIGRlc3Quc2V0KHNyYy5zdWJhcnJheShzcmNQb3MsIHNyY1BvcyArIGVsZW1zSW5UaGlzQ2h1bmspKTtcbiAgICAgIHNyY1BvcyArPSBlbGVtc0luVGhpc0NodW5rO1xuXG4gICAgICBpZiAoaGFzVHJhbnNmZXJNYXBzKSB7XG4gICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgZWxlbXNJblRoaXNDaHVuazsgayArPSA0KSB7XG4gICAgICAgICAgaWYgKHRyYW5zZmVyTWFwUmVkKSB7XG4gICAgICAgICAgICBkZXN0W2sgKyAwXSA9IHRyYW5zZmVyTWFwUmVkW2Rlc3RbayArIDBdXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodHJhbnNmZXJNYXBHcmVlbikge1xuICAgICAgICAgICAgZGVzdFtrICsgMV0gPSB0cmFuc2Zlck1hcEdyZWVuW2Rlc3RbayArIDFdXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodHJhbnNmZXJNYXBCbHVlKSB7XG4gICAgICAgICAgICBkZXN0W2sgKyAyXSA9IHRyYW5zZmVyTWFwQmx1ZVtkZXN0W2sgKyAyXV07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGN0eC5wdXRJbWFnZURhdGEoY2h1bmtJbWdEYXRhLCAwLCBqKTtcbiAgICAgIGogKz0gRlVMTF9DSFVOS19IRUlHSFQ7XG4gICAgfVxuXG4gICAgaWYgKGkgPCB0b3RhbENodW5rcykge1xuICAgICAgZWxlbXNJblRoaXNDaHVuayA9IHdpZHRoICogcGFydGlhbENodW5rSGVpZ2h0ICogNDtcbiAgICAgIGRlc3Quc2V0KHNyYy5zdWJhcnJheShzcmNQb3MsIHNyY1BvcyArIGVsZW1zSW5UaGlzQ2h1bmspKTtcblxuICAgICAgaWYgKGhhc1RyYW5zZmVyTWFwcykge1xuICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IGVsZW1zSW5UaGlzQ2h1bms7IGsgKz0gNCkge1xuICAgICAgICAgIGlmICh0cmFuc2Zlck1hcFJlZCkge1xuICAgICAgICAgICAgZGVzdFtrICsgMF0gPSB0cmFuc2Zlck1hcFJlZFtkZXN0W2sgKyAwXV07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHRyYW5zZmVyTWFwR3JlZW4pIHtcbiAgICAgICAgICAgIGRlc3RbayArIDFdID0gdHJhbnNmZXJNYXBHcmVlbltkZXN0W2sgKyAxXV07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHRyYW5zZmVyTWFwQmx1ZSkge1xuICAgICAgICAgICAgZGVzdFtrICsgMl0gPSB0cmFuc2Zlck1hcEJsdWVbZGVzdFtrICsgMl1dO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjdHgucHV0SW1hZ2VEYXRhKGNodW5rSW1nRGF0YSwgMCwgaik7XG4gICAgfVxuICB9IGVsc2UgaWYgKGltZ0RhdGEua2luZCA9PT0gX3V0aWwuSW1hZ2VLaW5kLlJHQl8yNEJQUCkge1xuICAgIGNvbnN0IGhhc1RyYW5zZmVyTWFwcyA9ICEhKHRyYW5zZmVyTWFwUmVkIHx8IHRyYW5zZmVyTWFwR3JlZW4gfHwgdHJhbnNmZXJNYXBCbHVlKTtcbiAgICB0aGlzQ2h1bmtIZWlnaHQgPSBGVUxMX0NIVU5LX0hFSUdIVDtcbiAgICBlbGVtc0luVGhpc0NodW5rID0gd2lkdGggKiB0aGlzQ2h1bmtIZWlnaHQ7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgdG90YWxDaHVua3M7IGkrKykge1xuICAgICAgaWYgKGkgPj0gZnVsbENodW5rcykge1xuICAgICAgICB0aGlzQ2h1bmtIZWlnaHQgPSBwYXJ0aWFsQ2h1bmtIZWlnaHQ7XG4gICAgICAgIGVsZW1zSW5UaGlzQ2h1bmsgPSB3aWR0aCAqIHRoaXNDaHVua0hlaWdodDtcbiAgICAgIH1cblxuICAgICAgZGVzdFBvcyA9IDA7XG5cbiAgICAgIGZvciAoaiA9IGVsZW1zSW5UaGlzQ2h1bms7IGotLTspIHtcbiAgICAgICAgZGVzdFtkZXN0UG9zKytdID0gc3JjW3NyY1BvcysrXTtcbiAgICAgICAgZGVzdFtkZXN0UG9zKytdID0gc3JjW3NyY1BvcysrXTtcbiAgICAgICAgZGVzdFtkZXN0UG9zKytdID0gc3JjW3NyY1BvcysrXTtcbiAgICAgICAgZGVzdFtkZXN0UG9zKytdID0gMjU1O1xuICAgICAgfVxuXG4gICAgICBpZiAoaGFzVHJhbnNmZXJNYXBzKSB7XG4gICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgZGVzdFBvczsgayArPSA0KSB7XG4gICAgICAgICAgaWYgKHRyYW5zZmVyTWFwUmVkKSB7XG4gICAgICAgICAgICBkZXN0W2sgKyAwXSA9IHRyYW5zZmVyTWFwUmVkW2Rlc3RbayArIDBdXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodHJhbnNmZXJNYXBHcmVlbikge1xuICAgICAgICAgICAgZGVzdFtrICsgMV0gPSB0cmFuc2Zlck1hcEdyZWVuW2Rlc3RbayArIDFdXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodHJhbnNmZXJNYXBCbHVlKSB7XG4gICAgICAgICAgICBkZXN0W2sgKyAyXSA9IHRyYW5zZmVyTWFwQmx1ZVtkZXN0W2sgKyAyXV07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGN0eC5wdXRJbWFnZURhdGEoY2h1bmtJbWdEYXRhLCAwLCBpICogRlVMTF9DSFVOS19IRUlHSFQpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGJhZCBpbWFnZSBraW5kOiAke2ltZ0RhdGEua2luZH1gKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwdXRCaW5hcnlJbWFnZU1hc2soY3R4LCBpbWdEYXRhKSB7XG4gIGlmIChpbWdEYXRhLmJpdG1hcCkge1xuICAgIGN0eC5kcmF3SW1hZ2UoaW1nRGF0YS5iaXRtYXAsIDAsIDApO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGhlaWdodCA9IGltZ0RhdGEuaGVpZ2h0LFxuICAgICAgICB3aWR0aCA9IGltZ0RhdGEud2lkdGg7XG4gIGNvbnN0IHBhcnRpYWxDaHVua0hlaWdodCA9IGhlaWdodCAlIEZVTExfQ0hVTktfSEVJR0hUO1xuICBjb25zdCBmdWxsQ2h1bmtzID0gKGhlaWdodCAtIHBhcnRpYWxDaHVua0hlaWdodCkgLyBGVUxMX0NIVU5LX0hFSUdIVDtcbiAgY29uc3QgdG90YWxDaHVua3MgPSBwYXJ0aWFsQ2h1bmtIZWlnaHQgPT09IDAgPyBmdWxsQ2h1bmtzIDogZnVsbENodW5rcyArIDE7XG4gIGNvbnN0IGNodW5rSW1nRGF0YSA9IGN0eC5jcmVhdGVJbWFnZURhdGEod2lkdGgsIEZVTExfQ0hVTktfSEVJR0hUKTtcbiAgbGV0IHNyY1BvcyA9IDA7XG4gIGNvbnN0IHNyYyA9IGltZ0RhdGEuZGF0YTtcbiAgY29uc3QgZGVzdCA9IGNodW5rSW1nRGF0YS5kYXRhO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdG90YWxDaHVua3M7IGkrKykge1xuICAgIGNvbnN0IHRoaXNDaHVua0hlaWdodCA9IGkgPCBmdWxsQ2h1bmtzID8gRlVMTF9DSFVOS19IRUlHSFQgOiBwYXJ0aWFsQ2h1bmtIZWlnaHQ7XG4gICAgKHtcbiAgICAgIHNyY1Bvc1xuICAgIH0gPSAoMCwgX2ltYWdlX3V0aWxzLmFwcGx5TWFza0ltYWdlRGF0YSkoe1xuICAgICAgc3JjLFxuICAgICAgc3JjUG9zLFxuICAgICAgZGVzdCxcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0OiB0aGlzQ2h1bmtIZWlnaHRcbiAgICB9KSk7XG4gICAgY3R4LnB1dEltYWdlRGF0YShjaHVua0ltZ0RhdGEsIDAsIGkgKiBGVUxMX0NIVU5LX0hFSUdIVCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29weUN0eFN0YXRlKHNvdXJjZUN0eCwgZGVzdEN0eCkge1xuICBjb25zdCBwcm9wZXJ0aWVzID0gW1wic3Ryb2tlU3R5bGVcIiwgXCJmaWxsU3R5bGVcIiwgXCJmaWxsUnVsZVwiLCBcImdsb2JhbEFscGhhXCIsIFwibGluZVdpZHRoXCIsIFwibGluZUNhcFwiLCBcImxpbmVKb2luXCIsIFwibWl0ZXJMaW1pdFwiLCBcImdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvblwiLCBcImZvbnRcIl07XG5cbiAgZm9yIChsZXQgaSA9IDAsIGlpID0gcHJvcGVydGllcy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgY29uc3QgcHJvcGVydHkgPSBwcm9wZXJ0aWVzW2ldO1xuXG4gICAgaWYgKHNvdXJjZUN0eFtwcm9wZXJ0eV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgZGVzdEN0eFtwcm9wZXJ0eV0gPSBzb3VyY2VDdHhbcHJvcGVydHldO1xuICAgIH1cbiAgfVxuXG4gIGlmIChzb3VyY2VDdHguc2V0TGluZURhc2ggIT09IHVuZGVmaW5lZCkge1xuICAgIGRlc3RDdHguc2V0TGluZURhc2goc291cmNlQ3R4LmdldExpbmVEYXNoKCkpO1xuICAgIGRlc3RDdHgubGluZURhc2hPZmZzZXQgPSBzb3VyY2VDdHgubGluZURhc2hPZmZzZXQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzZXRDdHhUb0RlZmF1bHQoY3R4LCBmb3JlZ3JvdW5kQ29sb3IpIHtcbiAgY3R4LnN0cm9rZVN0eWxlID0gY3R4LmZpbGxTdHlsZSA9IGZvcmVncm91bmRDb2xvciB8fCBcIiMwMDAwMDBcIjtcbiAgY3R4LmZpbGxSdWxlID0gXCJub256ZXJvXCI7XG4gIGN0eC5nbG9iYWxBbHBoYSA9IDE7XG4gIGN0eC5saW5lV2lkdGggPSAxO1xuICBjdHgubGluZUNhcCA9IFwiYnV0dFwiO1xuICBjdHgubGluZUpvaW4gPSBcIm1pdGVyXCI7XG4gIGN0eC5taXRlckxpbWl0ID0gMTA7XG4gIGN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSBcInNvdXJjZS1vdmVyXCI7XG4gIGN0eC5mb250ID0gXCIxMHB4IHNhbnMtc2VyaWZcIjtcblxuICBpZiAoY3R4LnNldExpbmVEYXNoICE9PSB1bmRlZmluZWQpIHtcbiAgICBjdHguc2V0TGluZURhc2goW10pO1xuICAgIGN0eC5saW5lRGFzaE9mZnNldCA9IDA7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tcG9zZVNNYXNrQmFja2Ryb3AoYnl0ZXMsIHIwLCBnMCwgYjApIHtcbiAgY29uc3QgbGVuZ3RoID0gYnl0ZXMubGVuZ3RoO1xuXG4gIGZvciAobGV0IGkgPSAzOyBpIDwgbGVuZ3RoOyBpICs9IDQpIHtcbiAgICBjb25zdCBhbHBoYSA9IGJ5dGVzW2ldO1xuXG4gICAgaWYgKGFscGhhID09PSAwKSB7XG4gICAgICBieXRlc1tpIC0gM10gPSByMDtcbiAgICAgIGJ5dGVzW2kgLSAyXSA9IGcwO1xuICAgICAgYnl0ZXNbaSAtIDFdID0gYjA7XG4gICAgfSBlbHNlIGlmIChhbHBoYSA8IDI1NSkge1xuICAgICAgY29uc3QgYWxwaGFfID0gMjU1IC0gYWxwaGE7XG4gICAgICBieXRlc1tpIC0gM10gPSBieXRlc1tpIC0gM10gKiBhbHBoYSArIHIwICogYWxwaGFfID4+IDg7XG4gICAgICBieXRlc1tpIC0gMl0gPSBieXRlc1tpIC0gMl0gKiBhbHBoYSArIGcwICogYWxwaGFfID4+IDg7XG4gICAgICBieXRlc1tpIC0gMV0gPSBieXRlc1tpIC0gMV0gKiBhbHBoYSArIGIwICogYWxwaGFfID4+IDg7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNvbXBvc2VTTWFza0FscGhhKG1hc2tEYXRhLCBsYXllckRhdGEsIHRyYW5zZmVyTWFwKSB7XG4gIGNvbnN0IGxlbmd0aCA9IG1hc2tEYXRhLmxlbmd0aDtcbiAgY29uc3Qgc2NhbGUgPSAxIC8gMjU1O1xuXG4gIGZvciAobGV0IGkgPSAzOyBpIDwgbGVuZ3RoOyBpICs9IDQpIHtcbiAgICBjb25zdCBhbHBoYSA9IHRyYW5zZmVyTWFwID8gdHJhbnNmZXJNYXBbbWFza0RhdGFbaV1dIDogbWFza0RhdGFbaV07XG4gICAgbGF5ZXJEYXRhW2ldID0gbGF5ZXJEYXRhW2ldICogYWxwaGEgKiBzY2FsZSB8IDA7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tcG9zZVNNYXNrTHVtaW5vc2l0eShtYXNrRGF0YSwgbGF5ZXJEYXRhLCB0cmFuc2Zlck1hcCkge1xuICBjb25zdCBsZW5ndGggPSBtYXNrRGF0YS5sZW5ndGg7XG5cbiAgZm9yIChsZXQgaSA9IDM7IGkgPCBsZW5ndGg7IGkgKz0gNCkge1xuICAgIGNvbnN0IHkgPSBtYXNrRGF0YVtpIC0gM10gKiA3NyArIG1hc2tEYXRhW2kgLSAyXSAqIDE1MiArIG1hc2tEYXRhW2kgLSAxXSAqIDI4O1xuICAgIGxheWVyRGF0YVtpXSA9IHRyYW5zZmVyTWFwID8gbGF5ZXJEYXRhW2ldICogdHJhbnNmZXJNYXBbeSA+PiA4XSA+PiA4IDogbGF5ZXJEYXRhW2ldICogeSA+PiAxNjtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZW5lcmljQ29tcG9zZVNNYXNrKG1hc2tDdHgsIGxheWVyQ3R4LCB3aWR0aCwgaGVpZ2h0LCBzdWJ0eXBlLCBiYWNrZHJvcCwgdHJhbnNmZXJNYXAsIGxheWVyT2Zmc2V0WCwgbGF5ZXJPZmZzZXRZLCBtYXNrT2Zmc2V0WCwgbWFza09mZnNldFkpIHtcbiAgY29uc3QgaGFzQmFja2Ryb3AgPSAhIWJhY2tkcm9wO1xuICBjb25zdCByMCA9IGhhc0JhY2tkcm9wID8gYmFja2Ryb3BbMF0gOiAwO1xuICBjb25zdCBnMCA9IGhhc0JhY2tkcm9wID8gYmFja2Ryb3BbMV0gOiAwO1xuICBjb25zdCBiMCA9IGhhc0JhY2tkcm9wID8gYmFja2Ryb3BbMl0gOiAwO1xuICBsZXQgY29tcG9zZUZuO1xuXG4gIGlmIChzdWJ0eXBlID09PSBcIkx1bWlub3NpdHlcIikge1xuICAgIGNvbXBvc2VGbiA9IGNvbXBvc2VTTWFza0x1bWlub3NpdHk7XG4gIH0gZWxzZSB7XG4gICAgY29tcG9zZUZuID0gY29tcG9zZVNNYXNrQWxwaGE7XG4gIH1cblxuICBjb25zdCBQSVhFTFNfVE9fUFJPQ0VTUyA9IDEwNDg1NzY7XG4gIGNvbnN0IGNodW5rU2l6ZSA9IE1hdGgubWluKGhlaWdodCwgTWF0aC5jZWlsKFBJWEVMU19UT19QUk9DRVNTIC8gd2lkdGgpKTtcblxuICBmb3IgKGxldCByb3cgPSAwOyByb3cgPCBoZWlnaHQ7IHJvdyArPSBjaHVua1NpemUpIHtcbiAgICBjb25zdCBjaHVua0hlaWdodCA9IE1hdGgubWluKGNodW5rU2l6ZSwgaGVpZ2h0IC0gcm93KTtcbiAgICBjb25zdCBtYXNrRGF0YSA9IG1hc2tDdHguZ2V0SW1hZ2VEYXRhKGxheWVyT2Zmc2V0WCAtIG1hc2tPZmZzZXRYLCByb3cgKyAobGF5ZXJPZmZzZXRZIC0gbWFza09mZnNldFkpLCB3aWR0aCwgY2h1bmtIZWlnaHQpO1xuICAgIGNvbnN0IGxheWVyRGF0YSA9IGxheWVyQ3R4LmdldEltYWdlRGF0YShsYXllck9mZnNldFgsIHJvdyArIGxheWVyT2Zmc2V0WSwgd2lkdGgsIGNodW5rSGVpZ2h0KTtcblxuICAgIGlmIChoYXNCYWNrZHJvcCkge1xuICAgICAgY29tcG9zZVNNYXNrQmFja2Ryb3AobWFza0RhdGEuZGF0YSwgcjAsIGcwLCBiMCk7XG4gICAgfVxuXG4gICAgY29tcG9zZUZuKG1hc2tEYXRhLmRhdGEsIGxheWVyRGF0YS5kYXRhLCB0cmFuc2Zlck1hcCk7XG4gICAgbGF5ZXJDdHgucHV0SW1hZ2VEYXRhKGxheWVyRGF0YSwgbGF5ZXJPZmZzZXRYLCByb3cgKyBsYXllck9mZnNldFkpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbXBvc2VTTWFzayhjdHgsIHNtYXNrLCBsYXllckN0eCwgbGF5ZXJCb3gpIHtcbiAgY29uc3QgbGF5ZXJPZmZzZXRYID0gbGF5ZXJCb3hbMF07XG4gIGNvbnN0IGxheWVyT2Zmc2V0WSA9IGxheWVyQm94WzFdO1xuICBjb25zdCBsYXllcldpZHRoID0gbGF5ZXJCb3hbMl0gLSBsYXllck9mZnNldFg7XG4gIGNvbnN0IGxheWVySGVpZ2h0ID0gbGF5ZXJCb3hbM10gLSBsYXllck9mZnNldFk7XG5cbiAgaWYgKGxheWVyV2lkdGggPT09IDAgfHwgbGF5ZXJIZWlnaHQgPT09IDApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBnZW5lcmljQ29tcG9zZVNNYXNrKHNtYXNrLmNvbnRleHQsIGxheWVyQ3R4LCBsYXllcldpZHRoLCBsYXllckhlaWdodCwgc21hc2suc3VidHlwZSwgc21hc2suYmFja2Ryb3AsIHNtYXNrLnRyYW5zZmVyTWFwLCBsYXllck9mZnNldFgsIGxheWVyT2Zmc2V0WSwgc21hc2sub2Zmc2V0WCwgc21hc2sub2Zmc2V0WSk7XG4gIGN0eC5zYXZlKCk7XG4gIGN0eC5nbG9iYWxBbHBoYSA9IDE7XG4gIGN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSBcInNvdXJjZS1vdmVyXCI7XG4gIGN0eC5zZXRUcmFuc2Zvcm0oMSwgMCwgMCwgMSwgMCwgMCk7XG4gIGN0eC5kcmF3SW1hZ2UobGF5ZXJDdHguY2FudmFzLCAwLCAwKTtcbiAgY3R4LnJlc3RvcmUoKTtcbn1cblxuZnVuY3Rpb24gZ2V0SW1hZ2VTbW9vdGhpbmdFbmFibGVkKHRyYW5zZm9ybSwgaW50ZXJwb2xhdGUpIHtcbiAgY29uc3Qgc2NhbGUgPSBfdXRpbC5VdGlsLnNpbmd1bGFyVmFsdWVEZWNvbXBvc2UyZFNjYWxlKHRyYW5zZm9ybSk7XG5cbiAgc2NhbGVbMF0gPSBNYXRoLmZyb3VuZChzY2FsZVswXSk7XG4gIHNjYWxlWzFdID0gTWF0aC5mcm91bmQoc2NhbGVbMV0pO1xuICBjb25zdCBhY3R1YWxTY2FsZSA9IE1hdGguZnJvdW5kKChnbG9iYWxUaGlzLmRldmljZVBpeGVsUmF0aW8gfHwgMSkgKiBfZGlzcGxheV91dGlscy5QaXhlbHNQZXJJbmNoLlBERl9UT19DU1NfVU5JVFMpO1xuXG4gIGlmIChpbnRlcnBvbGF0ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGludGVycG9sYXRlO1xuICB9IGVsc2UgaWYgKHNjYWxlWzBdIDw9IGFjdHVhbFNjYWxlIHx8IHNjYWxlWzFdIDw9IGFjdHVhbFNjYWxlKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmNvbnN0IExJTkVfQ0FQX1NUWUxFUyA9IFtcImJ1dHRcIiwgXCJyb3VuZFwiLCBcInNxdWFyZVwiXTtcbmNvbnN0IExJTkVfSk9JTl9TVFlMRVMgPSBbXCJtaXRlclwiLCBcInJvdW5kXCIsIFwiYmV2ZWxcIl07XG5jb25zdCBOT1JNQUxfQ0xJUCA9IHt9O1xuY29uc3QgRU9fQ0xJUCA9IHt9O1xuXG5jbGFzcyBDYW52YXNHcmFwaGljcyB7XG4gIGNvbnN0cnVjdG9yKGNhbnZhc0N0eCwgY29tbW9uT2Jqcywgb2JqcywgY2FudmFzRmFjdG9yeSwgaW1hZ2VMYXllciwgb3B0aW9uYWxDb250ZW50Q29uZmlnLCBhbm5vdGF0aW9uQ2FudmFzTWFwLCBwYWdlQ29sb3JzKSB7XG4gICAgdGhpcy5jdHggPSBjYW52YXNDdHg7XG4gICAgdGhpcy5jdXJyZW50ID0gbmV3IENhbnZhc0V4dHJhU3RhdGUodGhpcy5jdHguY2FudmFzLndpZHRoLCB0aGlzLmN0eC5jYW52YXMuaGVpZ2h0KTtcbiAgICB0aGlzLnN0YXRlU3RhY2sgPSBbXTtcbiAgICB0aGlzLnBlbmRpbmdDbGlwID0gbnVsbDtcbiAgICB0aGlzLnBlbmRpbmdFT0ZpbGwgPSBmYWxzZTtcbiAgICB0aGlzLnJlcyA9IG51bGw7XG4gICAgdGhpcy54b2JqcyA9IG51bGw7XG4gICAgdGhpcy5jb21tb25PYmpzID0gY29tbW9uT2JqcztcbiAgICB0aGlzLm9ianMgPSBvYmpzO1xuICAgIHRoaXMuY2FudmFzRmFjdG9yeSA9IGNhbnZhc0ZhY3Rvcnk7XG4gICAgdGhpcy5pbWFnZUxheWVyID0gaW1hZ2VMYXllcjtcbiAgICB0aGlzLmdyb3VwU3RhY2sgPSBbXTtcbiAgICB0aGlzLnByb2Nlc3NpbmdUeXBlMyA9IG51bGw7XG4gICAgdGhpcy5iYXNlVHJhbnNmb3JtID0gbnVsbDtcbiAgICB0aGlzLmJhc2VUcmFuc2Zvcm1TdGFjayA9IFtdO1xuICAgIHRoaXMuZ3JvdXBMZXZlbCA9IDA7XG4gICAgdGhpcy5zbWFza1N0YWNrID0gW107XG4gICAgdGhpcy5zbWFza0NvdW50ZXIgPSAwO1xuICAgIHRoaXMudGVtcFNNYXNrID0gbnVsbDtcbiAgICB0aGlzLnN1c3BlbmRlZEN0eCA9IG51bGw7XG4gICAgdGhpcy5jb250ZW50VmlzaWJsZSA9IHRydWU7XG4gICAgdGhpcy5tYXJrZWRDb250ZW50U3RhY2sgPSBbXTtcbiAgICB0aGlzLm9wdGlvbmFsQ29udGVudENvbmZpZyA9IG9wdGlvbmFsQ29udGVudENvbmZpZztcbiAgICB0aGlzLmNhY2hlZENhbnZhc2VzID0gbmV3IENhY2hlZENhbnZhc2VzKHRoaXMuY2FudmFzRmFjdG9yeSk7XG4gICAgdGhpcy5jYWNoZWRQYXR0ZXJucyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmFubm90YXRpb25DYW52YXNNYXAgPSBhbm5vdGF0aW9uQ2FudmFzTWFwO1xuICAgIHRoaXMudmlld3BvcnRTY2FsZSA9IDE7XG4gICAgdGhpcy5vdXRwdXRTY2FsZVggPSAxO1xuICAgIHRoaXMub3V0cHV0U2NhbGVZID0gMTtcbiAgICB0aGlzLmJhY2tncm91bmRDb2xvciA9IHBhZ2VDb2xvcnM/LmJhY2tncm91bmQgfHwgbnVsbDtcbiAgICB0aGlzLmZvcmVncm91bmRDb2xvciA9IHBhZ2VDb2xvcnM/LmZvcmVncm91bmQgfHwgbnVsbDtcblxuICAgIGlmIChjYW52YXNDdHgpIHtcbiAgICAgIGFkZENvbnRleHRDdXJyZW50VHJhbnNmb3JtKGNhbnZhc0N0eCk7XG4gICAgfVxuXG4gICAgdGhpcy5fY2FjaGVkU2NhbGVGb3JTdHJva2luZyA9IG51bGw7XG4gICAgdGhpcy5fY2FjaGVkR2V0U2luZ2xlUGl4ZWxXaWR0aCA9IG51bGw7XG4gICAgdGhpcy5fY2FjaGVkQml0bWFwc01hcCA9IG5ldyBNYXAoKTtcbiAgfVxuXG4gIGdldE9iamVjdChkYXRhLCBmYWxsYmFjayA9IG51bGwpIHtcbiAgICBpZiAodHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHJldHVybiBkYXRhLnN0YXJ0c1dpdGgoXCJnX1wiKSA/IHRoaXMuY29tbW9uT2Jqcy5nZXQoZGF0YSkgOiB0aGlzLm9ianMuZ2V0KGRhdGEpO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxsYmFjaztcbiAgfVxuXG4gIGJlZ2luRHJhd2luZyh7XG4gICAgdHJhbnNmb3JtLFxuICAgIHZpZXdwb3J0LFxuICAgIHRyYW5zcGFyZW5jeSA9IGZhbHNlLFxuICAgIGJhY2tncm91bmQgPSBudWxsXG4gIH0pIHtcbiAgICBjb25zdCB3aWR0aCA9IHRoaXMuY3R4LmNhbnZhcy53aWR0aDtcbiAgICBjb25zdCBoZWlnaHQgPSB0aGlzLmN0eC5jYW52YXMuaGVpZ2h0O1xuICAgIGNvbnN0IGRlZmF1bHRCYWNrZ3JvdW5kQ29sb3IgPSBiYWNrZ3JvdW5kIHx8IFwiI2ZmZmZmZlwiO1xuICAgIHRoaXMuY3R4LnNhdmUoKTtcblxuICAgIGlmICh0aGlzLmZvcmVncm91bmRDb2xvciAmJiB0aGlzLmJhY2tncm91bmRDb2xvcikge1xuICAgICAgdGhpcy5jdHguZmlsbFN0eWxlID0gdGhpcy5mb3JlZ3JvdW5kQ29sb3I7XG4gICAgICBjb25zdCBmZyA9IHRoaXMuZm9yZWdyb3VuZENvbG9yID0gdGhpcy5jdHguZmlsbFN0eWxlO1xuICAgICAgdGhpcy5jdHguZmlsbFN0eWxlID0gdGhpcy5iYWNrZ3JvdW5kQ29sb3I7XG4gICAgICBjb25zdCBiZyA9IHRoaXMuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jdHguZmlsbFN0eWxlO1xuICAgICAgbGV0IGlzVmFsaWREZWZhdWx0QmcgPSB0cnVlO1xuICAgICAgbGV0IGRlZmF1bHRCZyA9IGRlZmF1bHRCYWNrZ3JvdW5kQ29sb3I7XG4gICAgICB0aGlzLmN0eC5maWxsU3R5bGUgPSBkZWZhdWx0QmFja2dyb3VuZENvbG9yO1xuICAgICAgZGVmYXVsdEJnID0gdGhpcy5jdHguZmlsbFN0eWxlO1xuICAgICAgaXNWYWxpZERlZmF1bHRCZyA9IHR5cGVvZiBkZWZhdWx0QmcgPT09IFwic3RyaW5nXCIgJiYgL14jWzAtOUEtRmEtZl17Nn0kLy50ZXN0KGRlZmF1bHRCZyk7XG5cbiAgICAgIGlmIChmZyA9PT0gXCIjMDAwMDAwXCIgJiYgYmcgPT09IFwiI2ZmZmZmZlwiIHx8IGZnID09PSBiZyB8fCAhaXNWYWxpZERlZmF1bHRCZykge1xuICAgICAgICB0aGlzLmZvcmVncm91bmRDb2xvciA9IHRoaXMuYmFja2dyb3VuZENvbG9yID0gbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGNCID0gcGFyc2VJbnQoZGVmYXVsdEJnLnNsaWNlKDEpLCAxNik7XG4gICAgICAgIGNvbnN0IHJCID0gKGNCICYmIDB4ZmYwMDAwKSA+PiAxNjtcbiAgICAgICAgY29uc3QgZ0IgPSAoY0IgJiYgMHgwMGZmMDApID4+IDg7XG4gICAgICAgIGNvbnN0IGJCID0gY0IgJiYgMHgwMDAwZmY7XG5cbiAgICAgICAgY29uc3QgbmV3Q29tcCA9IHggPT4ge1xuICAgICAgICAgIHggLz0gMjU1O1xuICAgICAgICAgIHJldHVybiB4IDw9IDAuMDM5MjggPyB4IC8gMTIuOTIgOiAoKHggKyAwLjA1NSkgLyAxLjA1NSkgKiogMi40O1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGx1bUIgPSBNYXRoLnJvdW5kKDAuMjEyNiAqIG5ld0NvbXAockIpICsgMC43MTUyICogbmV3Q29tcChnQikgKyAwLjA3MjIgKiBuZXdDb21wKGJCKSk7XG5cbiAgICAgICAgdGhpcy5zZWxlY3RDb2xvciA9IChyLCBnLCBiKSA9PiB7XG4gICAgICAgICAgY29uc3QgbHVtQyA9IDAuMjEyNiAqIG5ld0NvbXAocikgKyAwLjcxNTIgKiBuZXdDb21wKGcpICsgMC4wNzIyICogbmV3Q29tcChiKTtcbiAgICAgICAgICByZXR1cm4gTWF0aC5yb3VuZChsdW1DKSA9PT0gbHVtQiA/IGJnIDogZmc7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5jdHguZmlsbFN0eWxlID0gdGhpcy5iYWNrZ3JvdW5kQ29sb3IgfHwgZGVmYXVsdEJhY2tncm91bmRDb2xvcjtcbiAgICB0aGlzLmN0eC5maWxsUmVjdCgwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICB0aGlzLmN0eC5yZXN0b3JlKCk7XG5cbiAgICBpZiAodHJhbnNwYXJlbmN5KSB7XG4gICAgICBjb25zdCB0cmFuc3BhcmVudENhbnZhcyA9IHRoaXMuY2FjaGVkQ2FudmFzZXMuZ2V0Q2FudmFzKFwidHJhbnNwYXJlbnRcIiwgd2lkdGgsIGhlaWdodCwgdHJ1ZSk7XG4gICAgICB0aGlzLmNvbXBvc2l0ZUN0eCA9IHRoaXMuY3R4O1xuICAgICAgdGhpcy50cmFuc3BhcmVudENhbnZhcyA9IHRyYW5zcGFyZW50Q2FudmFzLmNhbnZhcztcbiAgICAgIHRoaXMuY3R4ID0gdHJhbnNwYXJlbnRDYW52YXMuY29udGV4dDtcbiAgICAgIHRoaXMuY3R4LnNhdmUoKTtcbiAgICAgIHRoaXMuY3R4LnRyYW5zZm9ybS5hcHBseSh0aGlzLmN0eCwgdGhpcy5jb21wb3NpdGVDdHgubW96Q3VycmVudFRyYW5zZm9ybSk7XG4gICAgfVxuXG4gICAgdGhpcy5jdHguc2F2ZSgpO1xuICAgIHJlc2V0Q3R4VG9EZWZhdWx0KHRoaXMuY3R4LCB0aGlzLmZvcmVncm91bmRDb2xvcik7XG5cbiAgICBpZiAodHJhbnNmb3JtKSB7XG4gICAgICB0aGlzLmN0eC50cmFuc2Zvcm0uYXBwbHkodGhpcy5jdHgsIHRyYW5zZm9ybSk7XG4gICAgICB0aGlzLm91dHB1dFNjYWxlWCA9IHRyYW5zZm9ybVswXTtcbiAgICAgIHRoaXMub3V0cHV0U2NhbGVZID0gdHJhbnNmb3JtWzBdO1xuICAgIH1cblxuICAgIHRoaXMuY3R4LnRyYW5zZm9ybS5hcHBseSh0aGlzLmN0eCwgdmlld3BvcnQudHJhbnNmb3JtKTtcbiAgICB0aGlzLnZpZXdwb3J0U2NhbGUgPSB2aWV3cG9ydC5zY2FsZTtcbiAgICB0aGlzLmJhc2VUcmFuc2Zvcm0gPSB0aGlzLmN0eC5tb3pDdXJyZW50VHJhbnNmb3JtLnNsaWNlKCk7XG5cbiAgICBpZiAodGhpcy5pbWFnZUxheWVyKSB7XG4gICAgICB0aGlzLmltYWdlTGF5ZXIuYmVnaW5MYXlvdXQoKTtcbiAgICB9XG4gIH1cblxuICBleGVjdXRlT3BlcmF0b3JMaXN0KG9wZXJhdG9yTGlzdCwgZXhlY3V0aW9uU3RhcnRJZHgsIGNvbnRpbnVlQ2FsbGJhY2ssIHN0ZXBwZXIpIHtcbiAgICBjb25zdCBhcmdzQXJyYXkgPSBvcGVyYXRvckxpc3QuYXJnc0FycmF5O1xuICAgIGNvbnN0IGZuQXJyYXkgPSBvcGVyYXRvckxpc3QuZm5BcnJheTtcbiAgICBsZXQgaSA9IGV4ZWN1dGlvblN0YXJ0SWR4IHx8IDA7XG4gICAgY29uc3QgYXJnc0FycmF5TGVuID0gYXJnc0FycmF5Lmxlbmd0aDtcblxuICAgIGlmIChhcmdzQXJyYXlMZW4gPT09IGkpIHtcbiAgICAgIHJldHVybiBpO1xuICAgIH1cblxuICAgIGNvbnN0IGNodW5rT3BlcmF0aW9ucyA9IGFyZ3NBcnJheUxlbiAtIGkgPiBFWEVDVVRJT05fU1RFUFMgJiYgdHlwZW9mIGNvbnRpbnVlQ2FsbGJhY2sgPT09IFwiZnVuY3Rpb25cIjtcbiAgICBjb25zdCBlbmRUaW1lID0gY2h1bmtPcGVyYXRpb25zID8gRGF0ZS5ub3coKSArIEVYRUNVVElPTl9USU1FIDogMDtcbiAgICBsZXQgc3RlcHMgPSAwO1xuICAgIGNvbnN0IGNvbW1vbk9ianMgPSB0aGlzLmNvbW1vbk9ianM7XG4gICAgY29uc3Qgb2JqcyA9IHRoaXMub2JqcztcbiAgICBsZXQgZm5JZDtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBpZiAoc3RlcHBlciAhPT0gdW5kZWZpbmVkICYmIGkgPT09IHN0ZXBwZXIubmV4dEJyZWFrUG9pbnQpIHtcbiAgICAgICAgc3RlcHBlci5icmVha0l0KGksIGNvbnRpbnVlQ2FsbGJhY2spO1xuICAgICAgICByZXR1cm4gaTtcbiAgICAgIH1cblxuICAgICAgZm5JZCA9IGZuQXJyYXlbaV07XG5cbiAgICAgIGlmIChmbklkICE9PSBfdXRpbC5PUFMuZGVwZW5kZW5jeSkge1xuICAgICAgICB0aGlzW2ZuSWRdLmFwcGx5KHRoaXMsIGFyZ3NBcnJheVtpXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGNvbnN0IGRlcE9iaklkIG9mIGFyZ3NBcnJheVtpXSkge1xuICAgICAgICAgIGNvbnN0IG9ianNQb29sID0gZGVwT2JqSWQuc3RhcnRzV2l0aChcImdfXCIpID8gY29tbW9uT2JqcyA6IG9ianM7XG5cbiAgICAgICAgICBpZiAoIW9ianNQb29sLmhhcyhkZXBPYmpJZCkpIHtcbiAgICAgICAgICAgIG9ianNQb29sLmdldChkZXBPYmpJZCwgY29udGludWVDYWxsYmFjayk7XG4gICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaSsrO1xuXG4gICAgICBpZiAoaSA9PT0gYXJnc0FycmF5TGVuKSB7XG4gICAgICAgIHJldHVybiBpO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2h1bmtPcGVyYXRpb25zICYmICsrc3RlcHMgPiBFWEVDVVRJT05fU1RFUFMpIHtcbiAgICAgICAgaWYgKERhdGUubm93KCkgPiBlbmRUaW1lKSB7XG4gICAgICAgICAgY29udGludWVDYWxsYmFjaygpO1xuICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICB9XG5cbiAgICAgICAgc3RlcHMgPSAwO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGVuZERyYXdpbmcoKSB7XG4gICAgd2hpbGUgKHRoaXMuc3RhdGVTdGFjay5sZW5ndGggfHwgdGhpcy5pblNNYXNrTW9kZSkge1xuICAgICAgdGhpcy5yZXN0b3JlKCk7XG4gICAgfVxuXG4gICAgdGhpcy5jdHgucmVzdG9yZSgpO1xuXG4gICAgaWYgKHRoaXMudHJhbnNwYXJlbnRDYW52YXMpIHtcbiAgICAgIHRoaXMuY3R4ID0gdGhpcy5jb21wb3NpdGVDdHg7XG4gICAgICB0aGlzLmN0eC5zYXZlKCk7XG4gICAgICB0aGlzLmN0eC5zZXRUcmFuc2Zvcm0oMSwgMCwgMCwgMSwgMCwgMCk7XG4gICAgICB0aGlzLmN0eC5kcmF3SW1hZ2UodGhpcy50cmFuc3BhcmVudENhbnZhcywgMCwgMCk7XG4gICAgICB0aGlzLmN0eC5yZXN0b3JlKCk7XG4gICAgICB0aGlzLnRyYW5zcGFyZW50Q2FudmFzID0gbnVsbDtcbiAgICB9XG5cbiAgICB0aGlzLmNhY2hlZENhbnZhc2VzLmNsZWFyKCk7XG4gICAgdGhpcy5jYWNoZWRQYXR0ZXJucy5jbGVhcigpO1xuXG4gICAgZm9yIChjb25zdCBjYWNoZSBvZiB0aGlzLl9jYWNoZWRCaXRtYXBzTWFwLnZhbHVlcygpKSB7XG4gICAgICBmb3IgKGNvbnN0IGNhbnZhcyBvZiBjYWNoZS52YWx1ZXMoKSkge1xuICAgICAgICBpZiAodHlwZW9mIEhUTUxDYW52YXNFbGVtZW50ICE9PSBcInVuZGVmaW5lZFwiICYmIGNhbnZhcyBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50KSB7XG4gICAgICAgICAgY2FudmFzLndpZHRoID0gY2FudmFzLmhlaWdodCA9IDA7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY2FjaGUuY2xlYXIoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9jYWNoZWRCaXRtYXBzTWFwLmNsZWFyKCk7XG5cbiAgICBpZiAodGhpcy5pbWFnZUxheWVyKSB7XG4gICAgICB0aGlzLmltYWdlTGF5ZXIuZW5kTGF5b3V0KCk7XG4gICAgfVxuICB9XG5cbiAgX3NjYWxlSW1hZ2UoaW1nLCBpbnZlcnNlVHJhbnNmb3JtKSB7XG4gICAgY29uc3Qgd2lkdGggPSBpbWcud2lkdGg7XG4gICAgY29uc3QgaGVpZ2h0ID0gaW1nLmhlaWdodDtcbiAgICBsZXQgd2lkdGhTY2FsZSA9IE1hdGgubWF4KE1hdGguaHlwb3QoaW52ZXJzZVRyYW5zZm9ybVswXSwgaW52ZXJzZVRyYW5zZm9ybVsxXSksIDEpO1xuICAgIGxldCBoZWlnaHRTY2FsZSA9IE1hdGgubWF4KE1hdGguaHlwb3QoaW52ZXJzZVRyYW5zZm9ybVsyXSwgaW52ZXJzZVRyYW5zZm9ybVszXSksIDEpO1xuICAgIGxldCBwYWludFdpZHRoID0gd2lkdGgsXG4gICAgICAgIHBhaW50SGVpZ2h0ID0gaGVpZ2h0O1xuICAgIGxldCB0bXBDYW52YXNJZCA9IFwicHJlc2NhbGUxXCI7XG4gICAgbGV0IHRtcENhbnZhcywgdG1wQ3R4O1xuXG4gICAgd2hpbGUgKHdpZHRoU2NhbGUgPiAyICYmIHBhaW50V2lkdGggPiAxIHx8IGhlaWdodFNjYWxlID4gMiAmJiBwYWludEhlaWdodCA+IDEpIHtcbiAgICAgIGxldCBuZXdXaWR0aCA9IHBhaW50V2lkdGgsXG4gICAgICAgICAgbmV3SGVpZ2h0ID0gcGFpbnRIZWlnaHQ7XG5cbiAgICAgIGlmICh3aWR0aFNjYWxlID4gMiAmJiBwYWludFdpZHRoID4gMSkge1xuICAgICAgICBuZXdXaWR0aCA9IE1hdGguY2VpbChwYWludFdpZHRoIC8gMik7XG4gICAgICAgIHdpZHRoU2NhbGUgLz0gcGFpbnRXaWR0aCAvIG5ld1dpZHRoO1xuICAgICAgfVxuXG4gICAgICBpZiAoaGVpZ2h0U2NhbGUgPiAyICYmIHBhaW50SGVpZ2h0ID4gMSkge1xuICAgICAgICBuZXdIZWlnaHQgPSBNYXRoLmNlaWwocGFpbnRIZWlnaHQgLyAyKTtcbiAgICAgICAgaGVpZ2h0U2NhbGUgLz0gcGFpbnRIZWlnaHQgLyBuZXdIZWlnaHQ7XG4gICAgICB9XG5cbiAgICAgIHRtcENhbnZhcyA9IHRoaXMuY2FjaGVkQ2FudmFzZXMuZ2V0Q2FudmFzKHRtcENhbnZhc0lkLCBuZXdXaWR0aCwgbmV3SGVpZ2h0LCBmYWxzZSk7XG4gICAgICB0bXBDdHggPSB0bXBDYW52YXMuY29udGV4dDtcbiAgICAgIHRtcEN0eC5jbGVhclJlY3QoMCwgMCwgbmV3V2lkdGgsIG5ld0hlaWdodCk7XG4gICAgICB0bXBDdHguZHJhd0ltYWdlKGltZywgMCwgMCwgcGFpbnRXaWR0aCwgcGFpbnRIZWlnaHQsIDAsIDAsIG5ld1dpZHRoLCBuZXdIZWlnaHQpO1xuICAgICAgaW1nID0gdG1wQ2FudmFzLmNhbnZhcztcbiAgICAgIHBhaW50V2lkdGggPSBuZXdXaWR0aDtcbiAgICAgIHBhaW50SGVpZ2h0ID0gbmV3SGVpZ2h0O1xuICAgICAgdG1wQ2FudmFzSWQgPSB0bXBDYW52YXNJZCA9PT0gXCJwcmVzY2FsZTFcIiA/IFwicHJlc2NhbGUyXCIgOiBcInByZXNjYWxlMVwiO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBpbWcsXG4gICAgICBwYWludFdpZHRoLFxuICAgICAgcGFpbnRIZWlnaHRcbiAgICB9O1xuICB9XG5cbiAgX2NyZWF0ZU1hc2tDYW52YXMoaW1nKSB7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY29uc3Qge1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHRcbiAgICB9ID0gaW1nO1xuICAgIGNvbnN0IGZpbGxDb2xvciA9IHRoaXMuY3VycmVudC5maWxsQ29sb3I7XG4gICAgY29uc3QgaXNQYXR0ZXJuRmlsbCA9IHRoaXMuY3VycmVudC5wYXR0ZXJuRmlsbDtcbiAgICBjb25zdCBjdXJyZW50VHJhbnNmb3JtID0gY3R4Lm1vekN1cnJlbnRUcmFuc2Zvcm07XG4gICAgbGV0IGNhY2hlLCBjYWNoZUtleSwgc2NhbGVkLCBtYXNrQ2FudmFzO1xuXG4gICAgaWYgKChpbWcuYml0bWFwIHx8IGltZy5kYXRhKSAmJiBpbWcuY291bnQgPiAxKSB7XG4gICAgICBjb25zdCBtYWluS2V5ID0gaW1nLmJpdG1hcCB8fCBpbWcuZGF0YS5idWZmZXI7XG4gICAgICBjb25zdCB3aXRob3V0VHJhbnNsYXRpb24gPSBjdXJyZW50VHJhbnNmb3JtLnNsaWNlKDAsIDQpO1xuICAgICAgY2FjaGVLZXkgPSBKU09OLnN0cmluZ2lmeShpc1BhdHRlcm5GaWxsID8gd2l0aG91dFRyYW5zbGF0aW9uIDogW3dpdGhvdXRUcmFuc2xhdGlvbiwgZmlsbENvbG9yXSk7XG4gICAgICBjYWNoZSA9IHRoaXMuX2NhY2hlZEJpdG1hcHNNYXAuZ2V0KG1haW5LZXkpO1xuXG4gICAgICBpZiAoIWNhY2hlKSB7XG4gICAgICAgIGNhY2hlID0gbmV3IE1hcCgpO1xuXG4gICAgICAgIHRoaXMuX2NhY2hlZEJpdG1hcHNNYXAuc2V0KG1haW5LZXksIGNhY2hlKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2FjaGVkSW1hZ2UgPSBjYWNoZS5nZXQoY2FjaGVLZXkpO1xuXG4gICAgICBpZiAoY2FjaGVkSW1hZ2UgJiYgIWlzUGF0dGVybkZpbGwpIHtcbiAgICAgICAgY29uc3Qgb2Zmc2V0WCA9IE1hdGgucm91bmQoTWF0aC5taW4oY3VycmVudFRyYW5zZm9ybVswXSwgY3VycmVudFRyYW5zZm9ybVsyXSkgKyBjdXJyZW50VHJhbnNmb3JtWzRdKTtcbiAgICAgICAgY29uc3Qgb2Zmc2V0WSA9IE1hdGgucm91bmQoTWF0aC5taW4oY3VycmVudFRyYW5zZm9ybVsxXSwgY3VycmVudFRyYW5zZm9ybVszXSkgKyBjdXJyZW50VHJhbnNmb3JtWzVdKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjYW52YXM6IGNhY2hlZEltYWdlLFxuICAgICAgICAgIG9mZnNldFgsXG4gICAgICAgICAgb2Zmc2V0WVxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBzY2FsZWQgPSBjYWNoZWRJbWFnZTtcbiAgICB9XG5cbiAgICBpZiAoIXNjYWxlZCkge1xuICAgICAgbWFza0NhbnZhcyA9IHRoaXMuY2FjaGVkQ2FudmFzZXMuZ2V0Q2FudmFzKFwibWFza0NhbnZhc1wiLCB3aWR0aCwgaGVpZ2h0LCBmYWxzZSk7XG4gICAgICBwdXRCaW5hcnlJbWFnZU1hc2sobWFza0NhbnZhcy5jb250ZXh0LCBpbWcpO1xuICAgIH1cblxuICAgIGxldCBtYXNrVG9DYW52YXMgPSBfdXRpbC5VdGlsLnRyYW5zZm9ybShjdXJyZW50VHJhbnNmb3JtLCBbMSAvIHdpZHRoLCAwLCAwLCAtMSAvIGhlaWdodCwgMCwgMF0pO1xuXG4gICAgbWFza1RvQ2FudmFzID0gX3V0aWwuVXRpbC50cmFuc2Zvcm0obWFza1RvQ2FudmFzLCBbMSwgMCwgMCwgMSwgMCwgLWhlaWdodF0pO1xuXG4gICAgY29uc3QgY29yZDEgPSBfdXRpbC5VdGlsLmFwcGx5VHJhbnNmb3JtKFswLCAwXSwgbWFza1RvQ2FudmFzKTtcblxuICAgIGNvbnN0IGNvcmQyID0gX3V0aWwuVXRpbC5hcHBseVRyYW5zZm9ybShbd2lkdGgsIGhlaWdodF0sIG1hc2tUb0NhbnZhcyk7XG5cbiAgICBjb25zdCByZWN0ID0gX3V0aWwuVXRpbC5ub3JtYWxpemVSZWN0KFtjb3JkMVswXSwgY29yZDFbMV0sIGNvcmQyWzBdLCBjb3JkMlsxXV0pO1xuXG4gICAgY29uc3QgZHJhd25XaWR0aCA9IE1hdGgucm91bmQocmVjdFsyXSAtIHJlY3RbMF0pIHx8IDE7XG4gICAgY29uc3QgZHJhd25IZWlnaHQgPSBNYXRoLnJvdW5kKHJlY3RbM10gLSByZWN0WzFdKSB8fCAxO1xuICAgIGNvbnN0IGZpbGxDYW52YXMgPSB0aGlzLmNhY2hlZENhbnZhc2VzLmdldENhbnZhcyhcImZpbGxDYW52YXNcIiwgZHJhd25XaWR0aCwgZHJhd25IZWlnaHQsIHRydWUpO1xuICAgIGNvbnN0IGZpbGxDdHggPSBmaWxsQ2FudmFzLmNvbnRleHQ7XG4gICAgY29uc3Qgb2Zmc2V0WCA9IE1hdGgubWluKGNvcmQxWzBdLCBjb3JkMlswXSk7XG4gICAgY29uc3Qgb2Zmc2V0WSA9IE1hdGgubWluKGNvcmQxWzFdLCBjb3JkMlsxXSk7XG4gICAgZmlsbEN0eC50cmFuc2xhdGUoLW9mZnNldFgsIC1vZmZzZXRZKTtcbiAgICBmaWxsQ3R4LnRyYW5zZm9ybS5hcHBseShmaWxsQ3R4LCBtYXNrVG9DYW52YXMpO1xuXG4gICAgaWYgKCFzY2FsZWQpIHtcbiAgICAgIHNjYWxlZCA9IHRoaXMuX3NjYWxlSW1hZ2UobWFza0NhbnZhcy5jYW52YXMsIGZpbGxDdHgubW96Q3VycmVudFRyYW5zZm9ybUludmVyc2UpO1xuICAgICAgc2NhbGVkID0gc2NhbGVkLmltZztcblxuICAgICAgaWYgKGNhY2hlICYmIGlzUGF0dGVybkZpbGwpIHtcbiAgICAgICAgY2FjaGUuc2V0KGNhY2hlS2V5LCBzY2FsZWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZpbGxDdHguaW1hZ2VTbW9vdGhpbmdFbmFibGVkID0gZ2V0SW1hZ2VTbW9vdGhpbmdFbmFibGVkKGZpbGxDdHgubW96Q3VycmVudFRyYW5zZm9ybSwgaW1nLmludGVycG9sYXRlKTtcbiAgICBkcmF3SW1hZ2VBdEludGVnZXJDb29yZHMoZmlsbEN0eCwgc2NhbGVkLCAwLCAwLCBzY2FsZWQud2lkdGgsIHNjYWxlZC5oZWlnaHQsIDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xuICAgIGZpbGxDdHguZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uID0gXCJzb3VyY2UtaW5cIjtcblxuICAgIGNvbnN0IGludmVyc2UgPSBfdXRpbC5VdGlsLnRyYW5zZm9ybShmaWxsQ3R4Lm1vekN1cnJlbnRUcmFuc2Zvcm1JbnZlcnNlLCBbMSwgMCwgMCwgMSwgLW9mZnNldFgsIC1vZmZzZXRZXSk7XG5cbiAgICBmaWxsQ3R4LmZpbGxTdHlsZSA9IGlzUGF0dGVybkZpbGwgPyBmaWxsQ29sb3IuZ2V0UGF0dGVybihjdHgsIHRoaXMsIGludmVyc2UsIF9wYXR0ZXJuX2hlbHBlci5QYXRoVHlwZS5GSUxMKSA6IGZpbGxDb2xvcjtcbiAgICBmaWxsQ3R4LmZpbGxSZWN0KDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgaWYgKGNhY2hlICYmICFpc1BhdHRlcm5GaWxsKSB7XG4gICAgICB0aGlzLmNhY2hlZENhbnZhc2VzLmRlbGV0ZShcImZpbGxDYW52YXNcIik7XG4gICAgICBjYWNoZS5zZXQoY2FjaGVLZXksIGZpbGxDYW52YXMuY2FudmFzKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgY2FudmFzOiBmaWxsQ2FudmFzLmNhbnZhcyxcbiAgICAgIG9mZnNldFg6IE1hdGgucm91bmQob2Zmc2V0WCksXG4gICAgICBvZmZzZXRZOiBNYXRoLnJvdW5kKG9mZnNldFkpXG4gICAgfTtcbiAgfVxuXG4gIHNldExpbmVXaWR0aCh3aWR0aCkge1xuICAgIGlmICh3aWR0aCAhPT0gdGhpcy5jdXJyZW50LmxpbmVXaWR0aCkge1xuICAgICAgdGhpcy5fY2FjaGVkU2NhbGVGb3JTdHJva2luZyA9IG51bGw7XG4gICAgfVxuXG4gICAgdGhpcy5jdXJyZW50LmxpbmVXaWR0aCA9IHdpZHRoO1xuICAgIHRoaXMuY3R4LmxpbmVXaWR0aCA9IHdpZHRoO1xuICB9XG5cbiAgc2V0TGluZUNhcChzdHlsZSkge1xuICAgIHRoaXMuY3R4LmxpbmVDYXAgPSBMSU5FX0NBUF9TVFlMRVNbc3R5bGVdO1xuICB9XG5cbiAgc2V0TGluZUpvaW4oc3R5bGUpIHtcbiAgICB0aGlzLmN0eC5saW5lSm9pbiA9IExJTkVfSk9JTl9TVFlMRVNbc3R5bGVdO1xuICB9XG5cbiAgc2V0TWl0ZXJMaW1pdChsaW1pdCkge1xuICAgIHRoaXMuY3R4Lm1pdGVyTGltaXQgPSBsaW1pdDtcbiAgfVxuXG4gIHNldERhc2goZGFzaEFycmF5LCBkYXNoUGhhc2UpIHtcbiAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcblxuICAgIGlmIChjdHguc2V0TGluZURhc2ggIT09IHVuZGVmaW5lZCkge1xuICAgICAgY3R4LnNldExpbmVEYXNoKGRhc2hBcnJheSk7XG4gICAgICBjdHgubGluZURhc2hPZmZzZXQgPSBkYXNoUGhhc2U7XG4gICAgfVxuICB9XG5cbiAgc2V0UmVuZGVyaW5nSW50ZW50KGludGVudCkge31cblxuICBzZXRGbGF0bmVzcyhmbGF0bmVzcykge31cblxuICBzZXRHU3RhdGUoc3RhdGVzKSB7XG4gICAgZm9yIChsZXQgaSA9IDAsIGlpID0gc3RhdGVzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgIGNvbnN0IHN0YXRlID0gc3RhdGVzW2ldO1xuICAgICAgY29uc3Qga2V5ID0gc3RhdGVbMF07XG4gICAgICBjb25zdCB2YWx1ZSA9IHN0YXRlWzFdO1xuXG4gICAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgICBjYXNlIFwiTFdcIjpcbiAgICAgICAgICB0aGlzLnNldExpbmVXaWR0aCh2YWx1ZSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBcIkxDXCI6XG4gICAgICAgICAgdGhpcy5zZXRMaW5lQ2FwKHZhbHVlKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFwiTEpcIjpcbiAgICAgICAgICB0aGlzLnNldExpbmVKb2luKHZhbHVlKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFwiTUxcIjpcbiAgICAgICAgICB0aGlzLnNldE1pdGVyTGltaXQodmFsdWUpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgXCJEXCI6XG4gICAgICAgICAgdGhpcy5zZXREYXNoKHZhbHVlWzBdLCB2YWx1ZVsxXSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBcIlJJXCI6XG4gICAgICAgICAgdGhpcy5zZXRSZW5kZXJpbmdJbnRlbnQodmFsdWUpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgXCJGTFwiOlxuICAgICAgICAgIHRoaXMuc2V0RmxhdG5lc3ModmFsdWUpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgXCJGb250XCI6XG4gICAgICAgICAgdGhpcy5zZXRGb250KHZhbHVlWzBdLCB2YWx1ZVsxXSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBcIkNBXCI6XG4gICAgICAgICAgdGhpcy5jdXJyZW50LnN0cm9rZUFscGhhID0gc3RhdGVbMV07XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBcImNhXCI6XG4gICAgICAgICAgdGhpcy5jdXJyZW50LmZpbGxBbHBoYSA9IHN0YXRlWzFdO1xuICAgICAgICAgIHRoaXMuY3R4Lmdsb2JhbEFscGhhID0gc3RhdGVbMV07XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBcIkJNXCI6XG4gICAgICAgICAgdGhpcy5jdHguZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBcIlNNYXNrXCI6XG4gICAgICAgICAgdGhpcy5jdXJyZW50LmFjdGl2ZVNNYXNrID0gdmFsdWUgPyB0aGlzLnRlbXBTTWFzayA6IG51bGw7XG4gICAgICAgICAgdGhpcy50ZW1wU01hc2sgPSBudWxsO1xuICAgICAgICAgIHRoaXMuY2hlY2tTTWFza1N0YXRlKCk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBcIlRSXCI6XG4gICAgICAgICAgdGhpcy5jdXJyZW50LnRyYW5zZmVyTWFwcyA9IHZhbHVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGdldCBpblNNYXNrTW9kZSgpIHtcbiAgICByZXR1cm4gISF0aGlzLnN1c3BlbmRlZEN0eDtcbiAgfVxuXG4gIGNoZWNrU01hc2tTdGF0ZSgpIHtcbiAgICBjb25zdCBpblNNYXNrTW9kZSA9IHRoaXMuaW5TTWFza01vZGU7XG5cbiAgICBpZiAodGhpcy5jdXJyZW50LmFjdGl2ZVNNYXNrICYmICFpblNNYXNrTW9kZSkge1xuICAgICAgdGhpcy5iZWdpblNNYXNrTW9kZSgpO1xuICAgIH0gZWxzZSBpZiAoIXRoaXMuY3VycmVudC5hY3RpdmVTTWFzayAmJiBpblNNYXNrTW9kZSkge1xuICAgICAgdGhpcy5lbmRTTWFza01vZGUoKTtcbiAgICB9XG4gIH1cblxuICBiZWdpblNNYXNrTW9kZSgpIHtcbiAgICBpZiAodGhpcy5pblNNYXNrTW9kZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiYmVnaW5TTWFza01vZGUgY2FsbGVkIHdoaWxlIGFscmVhZHkgaW4gc21hc2sgbW9kZVwiKTtcbiAgICB9XG5cbiAgICBjb25zdCBkcmF3bldpZHRoID0gdGhpcy5jdHguY2FudmFzLndpZHRoO1xuICAgIGNvbnN0IGRyYXduSGVpZ2h0ID0gdGhpcy5jdHguY2FudmFzLmhlaWdodDtcbiAgICBjb25zdCBjYWNoZUlkID0gXCJzbWFza0dyb3VwQXRcIiArIHRoaXMuZ3JvdXBMZXZlbDtcbiAgICBjb25zdCBzY3JhdGNoQ2FudmFzID0gdGhpcy5jYWNoZWRDYW52YXNlcy5nZXRDYW52YXMoY2FjaGVJZCwgZHJhd25XaWR0aCwgZHJhd25IZWlnaHQsIHRydWUpO1xuICAgIHRoaXMuc3VzcGVuZGVkQ3R4ID0gdGhpcy5jdHg7XG4gICAgdGhpcy5jdHggPSBzY3JhdGNoQ2FudmFzLmNvbnRleHQ7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY3R4LnNldFRyYW5zZm9ybS5hcHBseShjdHgsIHRoaXMuc3VzcGVuZGVkQ3R4Lm1vekN1cnJlbnRUcmFuc2Zvcm0pO1xuICAgIGNvcHlDdHhTdGF0ZSh0aGlzLnN1c3BlbmRlZEN0eCwgY3R4KTtcbiAgICBtaXJyb3JDb250ZXh0T3BlcmF0aW9ucyhjdHgsIHRoaXMuc3VzcGVuZGVkQ3R4KTtcbiAgICB0aGlzLnNldEdTdGF0ZShbW1wiQk1cIiwgXCJzb3VyY2Utb3ZlclwiXSwgW1wiY2FcIiwgMV0sIFtcIkNBXCIsIDFdXSk7XG4gIH1cblxuICBlbmRTTWFza01vZGUoKSB7XG4gICAgaWYgKCF0aGlzLmluU01hc2tNb2RlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJlbmRTTWFza01vZGUgY2FsbGVkIHdoaWxlIG5vdCBpbiBzbWFzayBtb2RlXCIpO1xuICAgIH1cblxuICAgIHRoaXMuY3R4Ll9yZW1vdmVNaXJyb3JpbmcoKTtcblxuICAgIGNvcHlDdHhTdGF0ZSh0aGlzLmN0eCwgdGhpcy5zdXNwZW5kZWRDdHgpO1xuICAgIHRoaXMuY3R4ID0gdGhpcy5zdXNwZW5kZWRDdHg7XG4gICAgdGhpcy5zdXNwZW5kZWRDdHggPSBudWxsO1xuICB9XG5cbiAgY29tcG9zZShkaXJ0eUJveCkge1xuICAgIGlmICghdGhpcy5jdXJyZW50LmFjdGl2ZVNNYXNrKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFkaXJ0eUJveCkge1xuICAgICAgZGlydHlCb3ggPSBbMCwgMCwgdGhpcy5jdHguY2FudmFzLndpZHRoLCB0aGlzLmN0eC5jYW52YXMuaGVpZ2h0XTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGlydHlCb3hbMF0gPSBNYXRoLmZsb29yKGRpcnR5Qm94WzBdKTtcbiAgICAgIGRpcnR5Qm94WzFdID0gTWF0aC5mbG9vcihkaXJ0eUJveFsxXSk7XG4gICAgICBkaXJ0eUJveFsyXSA9IE1hdGguY2VpbChkaXJ0eUJveFsyXSk7XG4gICAgICBkaXJ0eUJveFszXSA9IE1hdGguY2VpbChkaXJ0eUJveFszXSk7XG4gICAgfVxuXG4gICAgY29uc3Qgc21hc2sgPSB0aGlzLmN1cnJlbnQuYWN0aXZlU01hc2s7XG4gICAgY29uc3Qgc3VzcGVuZGVkQ3R4ID0gdGhpcy5zdXNwZW5kZWRDdHg7XG4gICAgY29tcG9zZVNNYXNrKHN1c3BlbmRlZEN0eCwgc21hc2ssIHRoaXMuY3R4LCBkaXJ0eUJveCk7XG4gICAgdGhpcy5jdHguc2F2ZSgpO1xuICAgIHRoaXMuY3R4LnNldFRyYW5zZm9ybSgxLCAwLCAwLCAxLCAwLCAwKTtcbiAgICB0aGlzLmN0eC5jbGVhclJlY3QoMCwgMCwgdGhpcy5jdHguY2FudmFzLndpZHRoLCB0aGlzLmN0eC5jYW52YXMuaGVpZ2h0KTtcbiAgICB0aGlzLmN0eC5yZXN0b3JlKCk7XG4gIH1cblxuICBzYXZlKCkge1xuICAgIGlmICh0aGlzLmluU01hc2tNb2RlKSB7XG4gICAgICBjb3B5Q3R4U3RhdGUodGhpcy5jdHgsIHRoaXMuc3VzcGVuZGVkQ3R4KTtcbiAgICAgIHRoaXMuc3VzcGVuZGVkQ3R4LnNhdmUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jdHguc2F2ZSgpO1xuICAgIH1cblxuICAgIGNvbnN0IG9sZCA9IHRoaXMuY3VycmVudDtcbiAgICB0aGlzLnN0YXRlU3RhY2sucHVzaChvbGQpO1xuICAgIHRoaXMuY3VycmVudCA9IG9sZC5jbG9uZSgpO1xuICB9XG5cbiAgcmVzdG9yZSgpIHtcbiAgICBpZiAodGhpcy5zdGF0ZVN0YWNrLmxlbmd0aCA9PT0gMCAmJiB0aGlzLmluU01hc2tNb2RlKSB7XG4gICAgICB0aGlzLmVuZFNNYXNrTW9kZSgpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnN0YXRlU3RhY2subGVuZ3RoICE9PSAwKSB7XG4gICAgICB0aGlzLmN1cnJlbnQgPSB0aGlzLnN0YXRlU3RhY2sucG9wKCk7XG5cbiAgICAgIGlmICh0aGlzLmluU01hc2tNb2RlKSB7XG4gICAgICAgIHRoaXMuc3VzcGVuZGVkQ3R4LnJlc3RvcmUoKTtcbiAgICAgICAgY29weUN0eFN0YXRlKHRoaXMuc3VzcGVuZGVkQ3R4LCB0aGlzLmN0eCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmN0eC5yZXN0b3JlKCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuY2hlY2tTTWFza1N0YXRlKCk7XG4gICAgICB0aGlzLnBlbmRpbmdDbGlwID0gbnVsbDtcbiAgICAgIHRoaXMuX2NhY2hlZFNjYWxlRm9yU3Ryb2tpbmcgPSBudWxsO1xuICAgICAgdGhpcy5fY2FjaGVkR2V0U2luZ2xlUGl4ZWxXaWR0aCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgdHJhbnNmb3JtKGEsIGIsIGMsIGQsIGUsIGYpIHtcbiAgICB0aGlzLmN0eC50cmFuc2Zvcm0oYSwgYiwgYywgZCwgZSwgZik7XG4gICAgdGhpcy5fY2FjaGVkU2NhbGVGb3JTdHJva2luZyA9IG51bGw7XG4gICAgdGhpcy5fY2FjaGVkR2V0U2luZ2xlUGl4ZWxXaWR0aCA9IG51bGw7XG4gIH1cblxuICBjb25zdHJ1Y3RQYXRoKG9wcywgYXJncywgbWluTWF4KSB7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcbiAgICBsZXQgeCA9IGN1cnJlbnQueCxcbiAgICAgICAgeSA9IGN1cnJlbnQueTtcbiAgICBsZXQgc3RhcnRYLCBzdGFydFk7XG4gICAgY29uc3QgY3VycmVudFRyYW5zZm9ybSA9IGN0eC5tb3pDdXJyZW50VHJhbnNmb3JtO1xuICAgIGNvbnN0IGlzU2NhbGluZ01hdHJpeCA9IGN1cnJlbnRUcmFuc2Zvcm1bMF0gPT09IDAgJiYgY3VycmVudFRyYW5zZm9ybVszXSA9PT0gMCB8fCBjdXJyZW50VHJhbnNmb3JtWzFdID09PSAwICYmIGN1cnJlbnRUcmFuc2Zvcm1bMl0gPT09IDA7XG4gICAgY29uc3QgbWluTWF4Rm9yQmV6aWVyID0gaXNTY2FsaW5nTWF0cml4ID8gbWluTWF4LnNsaWNlKDApIDogbnVsbDtcblxuICAgIGZvciAobGV0IGkgPSAwLCBqID0gMCwgaWkgPSBvcHMubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgc3dpdGNoIChvcHNbaV0gfCAwKSB7XG4gICAgICAgIGNhc2UgX3V0aWwuT1BTLnJlY3RhbmdsZTpcbiAgICAgICAgICB4ID0gYXJnc1tqKytdO1xuICAgICAgICAgIHkgPSBhcmdzW2orK107XG4gICAgICAgICAgY29uc3Qgd2lkdGggPSBhcmdzW2orK107XG4gICAgICAgICAgY29uc3QgaGVpZ2h0ID0gYXJnc1tqKytdO1xuICAgICAgICAgIGNvbnN0IHh3ID0geCArIHdpZHRoO1xuICAgICAgICAgIGNvbnN0IHloID0geSArIGhlaWdodDtcbiAgICAgICAgICBjdHgubW92ZVRvKHgsIHkpO1xuXG4gICAgICAgICAgaWYgKHdpZHRoID09PSAwIHx8IGhlaWdodCA9PT0gMCkge1xuICAgICAgICAgICAgY3R4LmxpbmVUbyh4dywgeWgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjdHgubGluZVRvKHh3LCB5KTtcbiAgICAgICAgICAgIGN0eC5saW5lVG8oeHcsIHloKTtcbiAgICAgICAgICAgIGN0eC5saW5lVG8oeCwgeWgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghaXNTY2FsaW5nTWF0cml4KSB7XG4gICAgICAgICAgICBjdXJyZW50LnVwZGF0ZVJlY3RNaW5NYXgoY3VycmVudFRyYW5zZm9ybSwgW3gsIHksIHh3LCB5aF0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGN0eC5jbG9zZVBhdGgoKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIF91dGlsLk9QUy5tb3ZlVG86XG4gICAgICAgICAgeCA9IGFyZ3NbaisrXTtcbiAgICAgICAgICB5ID0gYXJnc1tqKytdO1xuICAgICAgICAgIGN0eC5tb3ZlVG8oeCwgeSk7XG5cbiAgICAgICAgICBpZiAoIWlzU2NhbGluZ01hdHJpeCkge1xuICAgICAgICAgICAgY3VycmVudC51cGRhdGVQYXRoTWluTWF4KGN1cnJlbnRUcmFuc2Zvcm0sIHgsIHkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgX3V0aWwuT1BTLmxpbmVUbzpcbiAgICAgICAgICB4ID0gYXJnc1tqKytdO1xuICAgICAgICAgIHkgPSBhcmdzW2orK107XG4gICAgICAgICAgY3R4LmxpbmVUbyh4LCB5KTtcblxuICAgICAgICAgIGlmICghaXNTY2FsaW5nTWF0cml4KSB7XG4gICAgICAgICAgICBjdXJyZW50LnVwZGF0ZVBhdGhNaW5NYXgoY3VycmVudFRyYW5zZm9ybSwgeCwgeSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBfdXRpbC5PUFMuY3VydmVUbzpcbiAgICAgICAgICBzdGFydFggPSB4O1xuICAgICAgICAgIHN0YXJ0WSA9IHk7XG4gICAgICAgICAgeCA9IGFyZ3NbaiArIDRdO1xuICAgICAgICAgIHkgPSBhcmdzW2ogKyA1XTtcbiAgICAgICAgICBjdHguYmV6aWVyQ3VydmVUbyhhcmdzW2pdLCBhcmdzW2ogKyAxXSwgYXJnc1tqICsgMl0sIGFyZ3NbaiArIDNdLCB4LCB5KTtcbiAgICAgICAgICBjdXJyZW50LnVwZGF0ZUN1cnZlUGF0aE1pbk1heChjdXJyZW50VHJhbnNmb3JtLCBzdGFydFgsIHN0YXJ0WSwgYXJnc1tqXSwgYXJnc1tqICsgMV0sIGFyZ3NbaiArIDJdLCBhcmdzW2ogKyAzXSwgeCwgeSwgbWluTWF4Rm9yQmV6aWVyKTtcbiAgICAgICAgICBqICs9IDY7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBfdXRpbC5PUFMuY3VydmVUbzI6XG4gICAgICAgICAgc3RhcnRYID0geDtcbiAgICAgICAgICBzdGFydFkgPSB5O1xuICAgICAgICAgIGN0eC5iZXppZXJDdXJ2ZVRvKHgsIHksIGFyZ3Nbal0sIGFyZ3NbaiArIDFdLCBhcmdzW2ogKyAyXSwgYXJnc1tqICsgM10pO1xuICAgICAgICAgIGN1cnJlbnQudXBkYXRlQ3VydmVQYXRoTWluTWF4KGN1cnJlbnRUcmFuc2Zvcm0sIHN0YXJ0WCwgc3RhcnRZLCB4LCB5LCBhcmdzW2pdLCBhcmdzW2ogKyAxXSwgYXJnc1tqICsgMl0sIGFyZ3NbaiArIDNdLCBtaW5NYXhGb3JCZXppZXIpO1xuICAgICAgICAgIHggPSBhcmdzW2ogKyAyXTtcbiAgICAgICAgICB5ID0gYXJnc1tqICsgM107XG4gICAgICAgICAgaiArPSA0O1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgX3V0aWwuT1BTLmN1cnZlVG8zOlxuICAgICAgICAgIHN0YXJ0WCA9IHg7XG4gICAgICAgICAgc3RhcnRZID0geTtcbiAgICAgICAgICB4ID0gYXJnc1tqICsgMl07XG4gICAgICAgICAgeSA9IGFyZ3NbaiArIDNdO1xuICAgICAgICAgIGN0eC5iZXppZXJDdXJ2ZVRvKGFyZ3Nbal0sIGFyZ3NbaiArIDFdLCB4LCB5LCB4LCB5KTtcbiAgICAgICAgICBjdXJyZW50LnVwZGF0ZUN1cnZlUGF0aE1pbk1heChjdXJyZW50VHJhbnNmb3JtLCBzdGFydFgsIHN0YXJ0WSwgYXJnc1tqXSwgYXJnc1tqICsgMV0sIHgsIHksIHgsIHksIG1pbk1heEZvckJlemllcik7XG4gICAgICAgICAgaiArPSA0O1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgX3V0aWwuT1BTLmNsb3NlUGF0aDpcbiAgICAgICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlzU2NhbGluZ01hdHJpeCkge1xuICAgICAgY3VycmVudC51cGRhdGVTY2FsaW5nUGF0aE1pbk1heChjdXJyZW50VHJhbnNmb3JtLCBtaW5NYXhGb3JCZXppZXIpO1xuICAgIH1cblxuICAgIGN1cnJlbnQuc2V0Q3VycmVudFBvaW50KHgsIHkpO1xuICB9XG5cbiAgY2xvc2VQYXRoKCkge1xuICAgIHRoaXMuY3R4LmNsb3NlUGF0aCgpO1xuICB9XG5cbiAgc3Ryb2tlKGNvbnN1bWVQYXRoKSB7XG4gICAgY29uc3VtZVBhdGggPSB0eXBlb2YgY29uc3VtZVBhdGggIT09IFwidW5kZWZpbmVkXCIgPyBjb25zdW1lUGF0aCA6IHRydWU7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY29uc3Qgc3Ryb2tlQ29sb3IgPSB0aGlzLmN1cnJlbnQuc3Ryb2tlQ29sb3I7XG4gICAgY3R4Lmdsb2JhbEFscGhhID0gdGhpcy5jdXJyZW50LnN0cm9rZUFscGhhO1xuXG4gICAgaWYgKHRoaXMuY29udGVudFZpc2libGUpIHtcbiAgICAgIGlmICh0eXBlb2Ygc3Ryb2tlQ29sb3IgPT09IFwib2JqZWN0XCIgJiYgc3Ryb2tlQ29sb3I/LmdldFBhdHRlcm4pIHtcbiAgICAgICAgY3R4LnNhdmUoKTtcbiAgICAgICAgY3R4LnN0cm9rZVN0eWxlID0gc3Ryb2tlQ29sb3IuZ2V0UGF0dGVybihjdHgsIHRoaXMsIGN0eC5tb3pDdXJyZW50VHJhbnNmb3JtSW52ZXJzZSwgX3BhdHRlcm5faGVscGVyLlBhdGhUeXBlLlNUUk9LRSk7XG4gICAgICAgIHRoaXMucmVzY2FsZUFuZFN0cm9rZShmYWxzZSk7XG4gICAgICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnJlc2NhbGVBbmRTdHJva2UodHJ1ZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvbnN1bWVQYXRoKSB7XG4gICAgICB0aGlzLmNvbnN1bWVQYXRoKHRoaXMuY3VycmVudC5nZXRDbGlwcGVkUGF0aEJvdW5kaW5nQm94KCkpO1xuICAgIH1cblxuICAgIGN0eC5nbG9iYWxBbHBoYSA9IHRoaXMuY3VycmVudC5maWxsQWxwaGE7XG4gIH1cblxuICBjbG9zZVN0cm9rZSgpIHtcbiAgICB0aGlzLmNsb3NlUGF0aCgpO1xuICAgIHRoaXMuc3Ryb2tlKCk7XG4gIH1cblxuICBmaWxsKGNvbnN1bWVQYXRoKSB7XG4gICAgY29uc3VtZVBhdGggPSB0eXBlb2YgY29uc3VtZVBhdGggIT09IFwidW5kZWZpbmVkXCIgPyBjb25zdW1lUGF0aCA6IHRydWU7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY29uc3QgZmlsbENvbG9yID0gdGhpcy5jdXJyZW50LmZpbGxDb2xvcjtcbiAgICBjb25zdCBpc1BhdHRlcm5GaWxsID0gdGhpcy5jdXJyZW50LnBhdHRlcm5GaWxsO1xuICAgIGxldCBuZWVkUmVzdG9yZSA9IGZhbHNlO1xuXG4gICAgaWYgKGlzUGF0dGVybkZpbGwpIHtcbiAgICAgIGN0eC5zYXZlKCk7XG4gICAgICBjdHguZmlsbFN0eWxlID0gZmlsbENvbG9yLmdldFBhdHRlcm4oY3R4LCB0aGlzLCBjdHgubW96Q3VycmVudFRyYW5zZm9ybUludmVyc2UsIF9wYXR0ZXJuX2hlbHBlci5QYXRoVHlwZS5GSUxMKTtcbiAgICAgIG5lZWRSZXN0b3JlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBjb25zdCBpbnRlcnNlY3QgPSB0aGlzLmN1cnJlbnQuZ2V0Q2xpcHBlZFBhdGhCb3VuZGluZ0JveCgpO1xuXG4gICAgaWYgKHRoaXMuY29udGVudFZpc2libGUgJiYgaW50ZXJzZWN0ICE9PSBudWxsKSB7XG4gICAgICBpZiAodGhpcy5wZW5kaW5nRU9GaWxsKSB7XG4gICAgICAgIGN0eC5maWxsKFwiZXZlbm9kZFwiKTtcbiAgICAgICAgdGhpcy5wZW5kaW5nRU9GaWxsID0gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjdHguZmlsbCgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChuZWVkUmVzdG9yZSkge1xuICAgICAgY3R4LnJlc3RvcmUoKTtcbiAgICB9XG5cbiAgICBpZiAoY29uc3VtZVBhdGgpIHtcbiAgICAgIHRoaXMuY29uc3VtZVBhdGgoaW50ZXJzZWN0KTtcbiAgICB9XG4gIH1cblxuICBlb0ZpbGwoKSB7XG4gICAgdGhpcy5wZW5kaW5nRU9GaWxsID0gdHJ1ZTtcbiAgICB0aGlzLmZpbGwoKTtcbiAgfVxuXG4gIGZpbGxTdHJva2UoKSB7XG4gICAgdGhpcy5maWxsKGZhbHNlKTtcbiAgICB0aGlzLnN0cm9rZShmYWxzZSk7XG4gICAgdGhpcy5jb25zdW1lUGF0aCgpO1xuICB9XG5cbiAgZW9GaWxsU3Ryb2tlKCkge1xuICAgIHRoaXMucGVuZGluZ0VPRmlsbCA9IHRydWU7XG4gICAgdGhpcy5maWxsU3Ryb2tlKCk7XG4gIH1cblxuICBjbG9zZUZpbGxTdHJva2UoKSB7XG4gICAgdGhpcy5jbG9zZVBhdGgoKTtcbiAgICB0aGlzLmZpbGxTdHJva2UoKTtcbiAgfVxuXG4gIGNsb3NlRU9GaWxsU3Ryb2tlKCkge1xuICAgIHRoaXMucGVuZGluZ0VPRmlsbCA9IHRydWU7XG4gICAgdGhpcy5jbG9zZVBhdGgoKTtcbiAgICB0aGlzLmZpbGxTdHJva2UoKTtcbiAgfVxuXG4gIGVuZFBhdGgoKSB7XG4gICAgdGhpcy5jb25zdW1lUGF0aCgpO1xuICB9XG5cbiAgY2xpcCgpIHtcbiAgICB0aGlzLnBlbmRpbmdDbGlwID0gTk9STUFMX0NMSVA7XG4gIH1cblxuICBlb0NsaXAoKSB7XG4gICAgdGhpcy5wZW5kaW5nQ2xpcCA9IEVPX0NMSVA7XG4gIH1cblxuICBiZWdpblRleHQoKSB7XG4gICAgdGhpcy5jdXJyZW50LnRleHRNYXRyaXggPSBfdXRpbC5JREVOVElUWV9NQVRSSVg7XG4gICAgdGhpcy5jdXJyZW50LnRleHRNYXRyaXhTY2FsZSA9IDE7XG4gICAgdGhpcy5jdXJyZW50LnggPSB0aGlzLmN1cnJlbnQubGluZVggPSAwO1xuICAgIHRoaXMuY3VycmVudC55ID0gdGhpcy5jdXJyZW50LmxpbmVZID0gMDtcbiAgfVxuXG4gIGVuZFRleHQoKSB7XG4gICAgY29uc3QgcGF0aHMgPSB0aGlzLnBlbmRpbmdUZXh0UGF0aHM7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG5cbiAgICBpZiAocGF0aHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGN0eC5zYXZlKCk7XG4gICAgY3R4LmJlZ2luUGF0aCgpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXRocy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgcGF0aCA9IHBhdGhzW2ldO1xuICAgICAgY3R4LnNldFRyYW5zZm9ybS5hcHBseShjdHgsIHBhdGgudHJhbnNmb3JtKTtcbiAgICAgIGN0eC50cmFuc2xhdGUocGF0aC54LCBwYXRoLnkpO1xuICAgICAgcGF0aC5hZGRUb1BhdGgoY3R4LCBwYXRoLmZvbnRTaXplKTtcbiAgICB9XG5cbiAgICBjdHgucmVzdG9yZSgpO1xuICAgIGN0eC5jbGlwKCk7XG4gICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgIGRlbGV0ZSB0aGlzLnBlbmRpbmdUZXh0UGF0aHM7XG4gIH1cblxuICBzZXRDaGFyU3BhY2luZyhzcGFjaW5nKSB7XG4gICAgdGhpcy5jdXJyZW50LmNoYXJTcGFjaW5nID0gc3BhY2luZztcbiAgfVxuXG4gIHNldFdvcmRTcGFjaW5nKHNwYWNpbmcpIHtcbiAgICB0aGlzLmN1cnJlbnQud29yZFNwYWNpbmcgPSBzcGFjaW5nO1xuICB9XG5cbiAgc2V0SFNjYWxlKHNjYWxlKSB7XG4gICAgdGhpcy5jdXJyZW50LnRleHRIU2NhbGUgPSBzY2FsZSAvIDEwMDtcbiAgfVxuXG4gIHNldExlYWRpbmcobGVhZGluZykge1xuICAgIHRoaXMuY3VycmVudC5sZWFkaW5nID0gLWxlYWRpbmc7XG4gIH1cblxuICBzZXRGb250KGZvbnRSZWZOYW1lLCBzaXplKSB7XG4gICAgY29uc3QgZm9udE9iaiA9IHRoaXMuY29tbW9uT2Jqcy5nZXQoZm9udFJlZk5hbWUpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmN1cnJlbnQ7XG5cbiAgICBpZiAoIWZvbnRPYmopIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2FuJ3QgZmluZCBmb250IGZvciAke2ZvbnRSZWZOYW1lfWApO1xuICAgIH1cblxuICAgIGN1cnJlbnQuZm9udE1hdHJpeCA9IGZvbnRPYmouZm9udE1hdHJpeCB8fCBfdXRpbC5GT05UX0lERU5USVRZX01BVFJJWDtcblxuICAgIGlmIChjdXJyZW50LmZvbnRNYXRyaXhbMF0gPT09IDAgfHwgY3VycmVudC5mb250TWF0cml4WzNdID09PSAwKSB7XG4gICAgICAoMCwgX3V0aWwud2FybikoXCJJbnZhbGlkIGZvbnQgbWF0cml4IGZvciBmb250IFwiICsgZm9udFJlZk5hbWUpO1xuICAgIH1cblxuICAgIGlmIChzaXplIDwgMCkge1xuICAgICAgc2l6ZSA9IC1zaXplO1xuICAgICAgY3VycmVudC5mb250RGlyZWN0aW9uID0gLTE7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN1cnJlbnQuZm9udERpcmVjdGlvbiA9IDE7XG4gICAgfVxuXG4gICAgdGhpcy5jdXJyZW50LmZvbnQgPSBmb250T2JqO1xuICAgIHRoaXMuY3VycmVudC5mb250U2l6ZSA9IHNpemU7XG5cbiAgICBpZiAoZm9udE9iai5pc1R5cGUzRm9udCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG5hbWUgPSBmb250T2JqLmxvYWRlZE5hbWUgfHwgXCJzYW5zLXNlcmlmXCI7XG4gICAgbGV0IGJvbGQgPSBcIm5vcm1hbFwiO1xuXG4gICAgaWYgKGZvbnRPYmouYmxhY2spIHtcbiAgICAgIGJvbGQgPSBcIjkwMFwiO1xuICAgIH0gZWxzZSBpZiAoZm9udE9iai5ib2xkKSB7XG4gICAgICBib2xkID0gXCJib2xkXCI7XG4gICAgfVxuXG4gICAgY29uc3QgaXRhbGljID0gZm9udE9iai5pdGFsaWMgPyBcIml0YWxpY1wiIDogXCJub3JtYWxcIjtcbiAgICBjb25zdCB0eXBlZmFjZSA9IGBcIiR7bmFtZX1cIiwgJHtmb250T2JqLmZhbGxiYWNrTmFtZX1gO1xuICAgIGxldCBicm93c2VyRm9udFNpemUgPSBzaXplO1xuXG4gICAgaWYgKHNpemUgPCBNSU5fRk9OVF9TSVpFKSB7XG4gICAgICBicm93c2VyRm9udFNpemUgPSBNSU5fRk9OVF9TSVpFO1xuICAgIH0gZWxzZSBpZiAoc2l6ZSA+IE1BWF9GT05UX1NJWkUpIHtcbiAgICAgIGJyb3dzZXJGb250U2l6ZSA9IE1BWF9GT05UX1NJWkU7XG4gICAgfVxuXG4gICAgdGhpcy5jdXJyZW50LmZvbnRTaXplU2NhbGUgPSBzaXplIC8gYnJvd3NlckZvbnRTaXplO1xuICAgIHRoaXMuY3R4LmZvbnQgPSBgJHtpdGFsaWN9ICR7Ym9sZH0gJHticm93c2VyRm9udFNpemV9cHggJHt0eXBlZmFjZX1gO1xuICB9XG5cbiAgc2V0VGV4dFJlbmRlcmluZ01vZGUobW9kZSkge1xuICAgIHRoaXMuY3VycmVudC50ZXh0UmVuZGVyaW5nTW9kZSA9IG1vZGU7XG4gIH1cblxuICBzZXRUZXh0UmlzZShyaXNlKSB7XG4gICAgdGhpcy5jdXJyZW50LnRleHRSaXNlID0gcmlzZTtcbiAgfVxuXG4gIG1vdmVUZXh0KHgsIHkpIHtcbiAgICB0aGlzLmN1cnJlbnQueCA9IHRoaXMuY3VycmVudC5saW5lWCArPSB4O1xuICAgIHRoaXMuY3VycmVudC55ID0gdGhpcy5jdXJyZW50LmxpbmVZICs9IHk7XG4gIH1cblxuICBzZXRMZWFkaW5nTW92ZVRleHQoeCwgeSkge1xuICAgIHRoaXMuc2V0TGVhZGluZygteSk7XG4gICAgdGhpcy5tb3ZlVGV4dCh4LCB5KTtcbiAgfVxuXG4gIHNldFRleHRNYXRyaXgoYSwgYiwgYywgZCwgZSwgZikge1xuICAgIHRoaXMuY3VycmVudC50ZXh0TWF0cml4ID0gW2EsIGIsIGMsIGQsIGUsIGZdO1xuICAgIHRoaXMuY3VycmVudC50ZXh0TWF0cml4U2NhbGUgPSBNYXRoLmh5cG90KGEsIGIpO1xuICAgIHRoaXMuY3VycmVudC54ID0gdGhpcy5jdXJyZW50LmxpbmVYID0gMDtcbiAgICB0aGlzLmN1cnJlbnQueSA9IHRoaXMuY3VycmVudC5saW5lWSA9IDA7XG4gIH1cblxuICBuZXh0TGluZSgpIHtcbiAgICB0aGlzLm1vdmVUZXh0KDAsIHRoaXMuY3VycmVudC5sZWFkaW5nKTtcbiAgfVxuXG4gIHBhaW50Q2hhcihjaGFyYWN0ZXIsIHgsIHksIHBhdHRlcm5UcmFuc2Zvcm0pIHtcbiAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5jdXJyZW50O1xuICAgIGNvbnN0IGZvbnQgPSBjdXJyZW50LmZvbnQ7XG4gICAgY29uc3QgdGV4dFJlbmRlcmluZ01vZGUgPSBjdXJyZW50LnRleHRSZW5kZXJpbmdNb2RlO1xuICAgIGNvbnN0IGZvbnRTaXplID0gY3VycmVudC5mb250U2l6ZSAvIGN1cnJlbnQuZm9udFNpemVTY2FsZTtcbiAgICBjb25zdCBmaWxsU3Ryb2tlTW9kZSA9IHRleHRSZW5kZXJpbmdNb2RlICYgX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuRklMTF9TVFJPS0VfTUFTSztcbiAgICBjb25zdCBpc0FkZFRvUGF0aFNldCA9ICEhKHRleHRSZW5kZXJpbmdNb2RlICYgX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuQUREX1RPX1BBVEhfRkxBRyk7XG4gICAgY29uc3QgcGF0dGVybkZpbGwgPSBjdXJyZW50LnBhdHRlcm5GaWxsICYmICFmb250Lm1pc3NpbmdGaWxlO1xuICAgIGxldCBhZGRUb1BhdGg7XG5cbiAgICBpZiAoZm9udC5kaXNhYmxlRm9udEZhY2UgfHwgaXNBZGRUb1BhdGhTZXQgfHwgcGF0dGVybkZpbGwpIHtcbiAgICAgIGFkZFRvUGF0aCA9IGZvbnQuZ2V0UGF0aEdlbmVyYXRvcih0aGlzLmNvbW1vbk9ianMsIGNoYXJhY3Rlcik7XG4gICAgfVxuXG4gICAgaWYgKGZvbnQuZGlzYWJsZUZvbnRGYWNlIHx8IHBhdHRlcm5GaWxsKSB7XG4gICAgICBjdHguc2F2ZSgpO1xuICAgICAgY3R4LnRyYW5zbGF0ZSh4LCB5KTtcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgIGFkZFRvUGF0aChjdHgsIGZvbnRTaXplKTtcblxuICAgICAgaWYgKHBhdHRlcm5UcmFuc2Zvcm0pIHtcbiAgICAgICAgY3R4LnNldFRyYW5zZm9ybS5hcHBseShjdHgsIHBhdHRlcm5UcmFuc2Zvcm0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoZmlsbFN0cm9rZU1vZGUgPT09IF91dGlsLlRleHRSZW5kZXJpbmdNb2RlLkZJTEwgfHwgZmlsbFN0cm9rZU1vZGUgPT09IF91dGlsLlRleHRSZW5kZXJpbmdNb2RlLkZJTExfU1RST0tFKSB7XG4gICAgICAgIGN0eC5maWxsKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChmaWxsU3Ryb2tlTW9kZSA9PT0gX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuU1RST0tFIHx8IGZpbGxTdHJva2VNb2RlID09PSBfdXRpbC5UZXh0UmVuZGVyaW5nTW9kZS5GSUxMX1NUUk9LRSkge1xuICAgICAgICBjdHguc3Ryb2tlKCk7XG4gICAgICB9XG5cbiAgICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChmaWxsU3Ryb2tlTW9kZSA9PT0gX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuRklMTCB8fCBmaWxsU3Ryb2tlTW9kZSA9PT0gX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuRklMTF9TVFJPS0UpIHtcbiAgICAgICAgY3R4LmZpbGxUZXh0KGNoYXJhY3RlciwgeCwgeSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChmaWxsU3Ryb2tlTW9kZSA9PT0gX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuU1RST0tFIHx8IGZpbGxTdHJva2VNb2RlID09PSBfdXRpbC5UZXh0UmVuZGVyaW5nTW9kZS5GSUxMX1NUUk9LRSkge1xuICAgICAgICBjdHguc3Ryb2tlVGV4dChjaGFyYWN0ZXIsIHgsIHkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpc0FkZFRvUGF0aFNldCkge1xuICAgICAgY29uc3QgcGF0aHMgPSB0aGlzLnBlbmRpbmdUZXh0UGF0aHMgfHwgKHRoaXMucGVuZGluZ1RleHRQYXRocyA9IFtdKTtcbiAgICAgIHBhdGhzLnB1c2goe1xuICAgICAgICB0cmFuc2Zvcm06IGN0eC5tb3pDdXJyZW50VHJhbnNmb3JtLFxuICAgICAgICB4LFxuICAgICAgICB5LFxuICAgICAgICBmb250U2l6ZSxcbiAgICAgICAgYWRkVG9QYXRoXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBnZXQgaXNGb250U3VicGl4ZWxBQUVuYWJsZWQoKSB7XG4gICAgY29uc3Qge1xuICAgICAgY29udGV4dDogY3R4XG4gICAgfSA9IHRoaXMuY2FjaGVkQ2FudmFzZXMuZ2V0Q2FudmFzKFwiaXNGb250U3VicGl4ZWxBQUVuYWJsZWRcIiwgMTAsIDEwLCBmYWxzZSk7XG4gICAgY3R4LnNjYWxlKDEuNSwgMSk7XG4gICAgY3R4LmZpbGxUZXh0KFwiSVwiLCAwLCAxMCk7XG4gICAgY29uc3QgZGF0YSA9IGN0eC5nZXRJbWFnZURhdGEoMCwgMCwgMTAsIDEwKS5kYXRhO1xuICAgIGxldCBlbmFibGVkID0gZmFsc2U7XG5cbiAgICBmb3IgKGxldCBpID0gMzsgaSA8IGRhdGEubGVuZ3RoOyBpICs9IDQpIHtcbiAgICAgIGlmIChkYXRhW2ldID4gMCAmJiBkYXRhW2ldIDwgMjU1KSB7XG4gICAgICAgIGVuYWJsZWQgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gKDAsIF91dGlsLnNoYWRvdykodGhpcywgXCJpc0ZvbnRTdWJwaXhlbEFBRW5hYmxlZFwiLCBlbmFibGVkKTtcbiAgfVxuXG4gIHNob3dUZXh0KGdseXBocykge1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmN1cnJlbnQ7XG4gICAgY29uc3QgZm9udCA9IGN1cnJlbnQuZm9udDtcblxuICAgIGlmIChmb250LmlzVHlwZTNGb250KSB7XG4gICAgICByZXR1cm4gdGhpcy5zaG93VHlwZTNUZXh0KGdseXBocyk7XG4gICAgfVxuXG4gICAgY29uc3QgZm9udFNpemUgPSBjdXJyZW50LmZvbnRTaXplO1xuXG4gICAgaWYgKGZvbnRTaXplID09PSAwKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IGN0eCA9IHRoaXMuY3R4O1xuICAgIGNvbnN0IGZvbnRTaXplU2NhbGUgPSBjdXJyZW50LmZvbnRTaXplU2NhbGU7XG4gICAgY29uc3QgY2hhclNwYWNpbmcgPSBjdXJyZW50LmNoYXJTcGFjaW5nO1xuICAgIGNvbnN0IHdvcmRTcGFjaW5nID0gY3VycmVudC53b3JkU3BhY2luZztcbiAgICBjb25zdCBmb250RGlyZWN0aW9uID0gY3VycmVudC5mb250RGlyZWN0aW9uO1xuICAgIGNvbnN0IHRleHRIU2NhbGUgPSBjdXJyZW50LnRleHRIU2NhbGUgKiBmb250RGlyZWN0aW9uO1xuICAgIGNvbnN0IGdseXBoc0xlbmd0aCA9IGdseXBocy5sZW5ndGg7XG4gICAgY29uc3QgdmVydGljYWwgPSBmb250LnZlcnRpY2FsO1xuICAgIGNvbnN0IHNwYWNpbmdEaXIgPSB2ZXJ0aWNhbCA/IDEgOiAtMTtcbiAgICBjb25zdCBkZWZhdWx0Vk1ldHJpY3MgPSBmb250LmRlZmF1bHRWTWV0cmljcztcbiAgICBjb25zdCB3aWR0aEFkdmFuY2VTY2FsZSA9IGZvbnRTaXplICogY3VycmVudC5mb250TWF0cml4WzBdO1xuICAgIGNvbnN0IHNpbXBsZUZpbGxUZXh0ID0gY3VycmVudC50ZXh0UmVuZGVyaW5nTW9kZSA9PT0gX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuRklMTCAmJiAhZm9udC5kaXNhYmxlRm9udEZhY2UgJiYgIWN1cnJlbnQucGF0dGVybkZpbGw7XG4gICAgY3R4LnNhdmUoKTtcbiAgICBjdHgudHJhbnNmb3JtLmFwcGx5KGN0eCwgY3VycmVudC50ZXh0TWF0cml4KTtcbiAgICBjdHgudHJhbnNsYXRlKGN1cnJlbnQueCwgY3VycmVudC55ICsgY3VycmVudC50ZXh0UmlzZSk7XG5cbiAgICBpZiAoZm9udERpcmVjdGlvbiA+IDApIHtcbiAgICAgIGN0eC5zY2FsZSh0ZXh0SFNjYWxlLCAtMSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN0eC5zY2FsZSh0ZXh0SFNjYWxlLCAxKTtcbiAgICB9XG5cbiAgICBsZXQgcGF0dGVyblRyYW5zZm9ybTtcblxuICAgIGlmIChjdXJyZW50LnBhdHRlcm5GaWxsKSB7XG4gICAgICBjdHguc2F2ZSgpO1xuICAgICAgY29uc3QgcGF0dGVybiA9IGN1cnJlbnQuZmlsbENvbG9yLmdldFBhdHRlcm4oY3R4LCB0aGlzLCBjdHgubW96Q3VycmVudFRyYW5zZm9ybUludmVyc2UsIF9wYXR0ZXJuX2hlbHBlci5QYXRoVHlwZS5GSUxMKTtcbiAgICAgIHBhdHRlcm5UcmFuc2Zvcm0gPSBjdHgubW96Q3VycmVudFRyYW5zZm9ybTtcbiAgICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgICBjdHguZmlsbFN0eWxlID0gcGF0dGVybjtcbiAgICB9XG5cbiAgICBsZXQgbGluZVdpZHRoID0gY3VycmVudC5saW5lV2lkdGg7XG4gICAgY29uc3Qgc2NhbGUgPSBjdXJyZW50LnRleHRNYXRyaXhTY2FsZTtcblxuICAgIGlmIChzY2FsZSA9PT0gMCB8fCBsaW5lV2lkdGggPT09IDApIHtcbiAgICAgIGNvbnN0IGZpbGxTdHJva2VNb2RlID0gY3VycmVudC50ZXh0UmVuZGVyaW5nTW9kZSAmIF91dGlsLlRleHRSZW5kZXJpbmdNb2RlLkZJTExfU1RST0tFX01BU0s7XG5cbiAgICAgIGlmIChmaWxsU3Ryb2tlTW9kZSA9PT0gX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuU1RST0tFIHx8IGZpbGxTdHJva2VNb2RlID09PSBfdXRpbC5UZXh0UmVuZGVyaW5nTW9kZS5GSUxMX1NUUk9LRSkge1xuICAgICAgICBsaW5lV2lkdGggPSB0aGlzLmdldFNpbmdsZVBpeGVsV2lkdGgoKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbGluZVdpZHRoIC89IHNjYWxlO1xuICAgIH1cblxuICAgIGlmIChmb250U2l6ZVNjYWxlICE9PSAxLjApIHtcbiAgICAgIGN0eC5zY2FsZShmb250U2l6ZVNjYWxlLCBmb250U2l6ZVNjYWxlKTtcbiAgICAgIGxpbmVXaWR0aCAvPSBmb250U2l6ZVNjYWxlO1xuICAgIH1cblxuICAgIGN0eC5saW5lV2lkdGggPSBsaW5lV2lkdGg7XG4gICAgbGV0IHggPSAwLFxuICAgICAgICBpO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGdseXBoc0xlbmd0aDsgKytpKSB7XG4gICAgICBjb25zdCBnbHlwaCA9IGdseXBoc1tpXTtcblxuICAgICAgaWYgKHR5cGVvZiBnbHlwaCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICB4ICs9IHNwYWNpbmdEaXIgKiBnbHlwaCAqIGZvbnRTaXplIC8gMTAwMDtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGxldCByZXN0b3JlTmVlZGVkID0gZmFsc2U7XG4gICAgICBjb25zdCBzcGFjaW5nID0gKGdseXBoLmlzU3BhY2UgPyB3b3JkU3BhY2luZyA6IDApICsgY2hhclNwYWNpbmc7XG4gICAgICBjb25zdCBjaGFyYWN0ZXIgPSBnbHlwaC5mb250Q2hhcjtcbiAgICAgIGNvbnN0IGFjY2VudCA9IGdseXBoLmFjY2VudDtcbiAgICAgIGxldCBzY2FsZWRYLCBzY2FsZWRZO1xuICAgICAgbGV0IHdpZHRoID0gZ2x5cGgud2lkdGg7XG5cbiAgICAgIGlmICh2ZXJ0aWNhbCkge1xuICAgICAgICBjb25zdCB2bWV0cmljID0gZ2x5cGgudm1ldHJpYyB8fCBkZWZhdWx0Vk1ldHJpY3M7XG4gICAgICAgIGNvbnN0IHZ4ID0gLShnbHlwaC52bWV0cmljID8gdm1ldHJpY1sxXSA6IHdpZHRoICogMC41KSAqIHdpZHRoQWR2YW5jZVNjYWxlO1xuICAgICAgICBjb25zdCB2eSA9IHZtZXRyaWNbMl0gKiB3aWR0aEFkdmFuY2VTY2FsZTtcbiAgICAgICAgd2lkdGggPSB2bWV0cmljID8gLXZtZXRyaWNbMF0gOiB3aWR0aDtcbiAgICAgICAgc2NhbGVkWCA9IHZ4IC8gZm9udFNpemVTY2FsZTtcbiAgICAgICAgc2NhbGVkWSA9ICh4ICsgdnkpIC8gZm9udFNpemVTY2FsZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNjYWxlZFggPSB4IC8gZm9udFNpemVTY2FsZTtcbiAgICAgICAgc2NhbGVkWSA9IDA7XG4gICAgICB9XG5cbiAgICAgIGlmIChmb250LnJlbWVhc3VyZSAmJiB3aWR0aCA+IDApIHtcbiAgICAgICAgY29uc3QgbWVhc3VyZWRXaWR0aCA9IGN0eC5tZWFzdXJlVGV4dChjaGFyYWN0ZXIpLndpZHRoICogMTAwMCAvIGZvbnRTaXplICogZm9udFNpemVTY2FsZTtcblxuICAgICAgICBpZiAod2lkdGggPCBtZWFzdXJlZFdpZHRoICYmIHRoaXMuaXNGb250U3VicGl4ZWxBQUVuYWJsZWQpIHtcbiAgICAgICAgICBjb25zdCBjaGFyYWN0ZXJTY2FsZVggPSB3aWR0aCAvIG1lYXN1cmVkV2lkdGg7XG4gICAgICAgICAgcmVzdG9yZU5lZWRlZCA9IHRydWU7XG4gICAgICAgICAgY3R4LnNhdmUoKTtcbiAgICAgICAgICBjdHguc2NhbGUoY2hhcmFjdGVyU2NhbGVYLCAxKTtcbiAgICAgICAgICBzY2FsZWRYIC89IGNoYXJhY3RlclNjYWxlWDtcbiAgICAgICAgfSBlbHNlIGlmICh3aWR0aCAhPT0gbWVhc3VyZWRXaWR0aCkge1xuICAgICAgICAgIHNjYWxlZFggKz0gKHdpZHRoIC0gbWVhc3VyZWRXaWR0aCkgLyAyMDAwICogZm9udFNpemUgLyBmb250U2l6ZVNjYWxlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmNvbnRlbnRWaXNpYmxlICYmIChnbHlwaC5pc0luRm9udCB8fCBmb250Lm1pc3NpbmdGaWxlKSkge1xuICAgICAgICBpZiAoc2ltcGxlRmlsbFRleHQgJiYgIWFjY2VudCkge1xuICAgICAgICAgIGN0eC5maWxsVGV4dChjaGFyYWN0ZXIsIHNjYWxlZFgsIHNjYWxlZFkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMucGFpbnRDaGFyKGNoYXJhY3Rlciwgc2NhbGVkWCwgc2NhbGVkWSwgcGF0dGVyblRyYW5zZm9ybSk7XG5cbiAgICAgICAgICBpZiAoYWNjZW50KSB7XG4gICAgICAgICAgICBjb25zdCBzY2FsZWRBY2NlbnRYID0gc2NhbGVkWCArIGZvbnRTaXplICogYWNjZW50Lm9mZnNldC54IC8gZm9udFNpemVTY2FsZTtcbiAgICAgICAgICAgIGNvbnN0IHNjYWxlZEFjY2VudFkgPSBzY2FsZWRZIC0gZm9udFNpemUgKiBhY2NlbnQub2Zmc2V0LnkgLyBmb250U2l6ZVNjYWxlO1xuICAgICAgICAgICAgdGhpcy5wYWludENoYXIoYWNjZW50LmZvbnRDaGFyLCBzY2FsZWRBY2NlbnRYLCBzY2FsZWRBY2NlbnRZLCBwYXR0ZXJuVHJhbnNmb3JtKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbGV0IGNoYXJXaWR0aDtcblxuICAgICAgaWYgKHZlcnRpY2FsKSB7XG4gICAgICAgIGNoYXJXaWR0aCA9IHdpZHRoICogd2lkdGhBZHZhbmNlU2NhbGUgLSBzcGFjaW5nICogZm9udERpcmVjdGlvbjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNoYXJXaWR0aCA9IHdpZHRoICogd2lkdGhBZHZhbmNlU2NhbGUgKyBzcGFjaW5nICogZm9udERpcmVjdGlvbjtcbiAgICAgIH1cblxuICAgICAgeCArPSBjaGFyV2lkdGg7XG5cbiAgICAgIGlmIChyZXN0b3JlTmVlZGVkKSB7XG4gICAgICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHZlcnRpY2FsKSB7XG4gICAgICBjdXJyZW50LnkgLT0geDtcbiAgICB9IGVsc2Uge1xuICAgICAgY3VycmVudC54ICs9IHggKiB0ZXh0SFNjYWxlO1xuICAgIH1cblxuICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgdGhpcy5jb21wb3NlKCk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHNob3dUeXBlM1RleHQoZ2x5cGhzKSB7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcbiAgICBjb25zdCBmb250ID0gY3VycmVudC5mb250O1xuICAgIGNvbnN0IGZvbnRTaXplID0gY3VycmVudC5mb250U2l6ZTtcbiAgICBjb25zdCBmb250RGlyZWN0aW9uID0gY3VycmVudC5mb250RGlyZWN0aW9uO1xuICAgIGNvbnN0IHNwYWNpbmdEaXIgPSBmb250LnZlcnRpY2FsID8gMSA6IC0xO1xuICAgIGNvbnN0IGNoYXJTcGFjaW5nID0gY3VycmVudC5jaGFyU3BhY2luZztcbiAgICBjb25zdCB3b3JkU3BhY2luZyA9IGN1cnJlbnQud29yZFNwYWNpbmc7XG4gICAgY29uc3QgdGV4dEhTY2FsZSA9IGN1cnJlbnQudGV4dEhTY2FsZSAqIGZvbnREaXJlY3Rpb247XG4gICAgY29uc3QgZm9udE1hdHJpeCA9IGN1cnJlbnQuZm9udE1hdHJpeCB8fCBfdXRpbC5GT05UX0lERU5USVRZX01BVFJJWDtcbiAgICBjb25zdCBnbHlwaHNMZW5ndGggPSBnbHlwaHMubGVuZ3RoO1xuICAgIGNvbnN0IGlzVGV4dEludmlzaWJsZSA9IGN1cnJlbnQudGV4dFJlbmRlcmluZ01vZGUgPT09IF91dGlsLlRleHRSZW5kZXJpbmdNb2RlLklOVklTSUJMRTtcbiAgICBsZXQgaSwgZ2x5cGgsIHdpZHRoLCBzcGFjaW5nTGVuZ3RoO1xuXG4gICAgaWYgKGlzVGV4dEludmlzaWJsZSB8fCBmb250U2l6ZSA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2NhY2hlZFNjYWxlRm9yU3Ryb2tpbmcgPSBudWxsO1xuICAgIHRoaXMuX2NhY2hlZEdldFNpbmdsZVBpeGVsV2lkdGggPSBudWxsO1xuICAgIGN0eC5zYXZlKCk7XG4gICAgY3R4LnRyYW5zZm9ybS5hcHBseShjdHgsIGN1cnJlbnQudGV4dE1hdHJpeCk7XG4gICAgY3R4LnRyYW5zbGF0ZShjdXJyZW50LngsIGN1cnJlbnQueSk7XG4gICAgY3R4LnNjYWxlKHRleHRIU2NhbGUsIGZvbnREaXJlY3Rpb24pO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGdseXBoc0xlbmd0aDsgKytpKSB7XG4gICAgICBnbHlwaCA9IGdseXBoc1tpXTtcblxuICAgICAgaWYgKHR5cGVvZiBnbHlwaCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICBzcGFjaW5nTGVuZ3RoID0gc3BhY2luZ0RpciAqIGdseXBoICogZm9udFNpemUgLyAxMDAwO1xuICAgICAgICB0aGlzLmN0eC50cmFuc2xhdGUoc3BhY2luZ0xlbmd0aCwgMCk7XG4gICAgICAgIGN1cnJlbnQueCArPSBzcGFjaW5nTGVuZ3RoICogdGV4dEhTY2FsZTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNwYWNpbmcgPSAoZ2x5cGguaXNTcGFjZSA/IHdvcmRTcGFjaW5nIDogMCkgKyBjaGFyU3BhY2luZztcbiAgICAgIGNvbnN0IG9wZXJhdG9yTGlzdCA9IGZvbnQuY2hhclByb2NPcGVyYXRvckxpc3RbZ2x5cGgub3BlcmF0b3JMaXN0SWRdO1xuXG4gICAgICBpZiAoIW9wZXJhdG9yTGlzdCkge1xuICAgICAgICAoMCwgX3V0aWwud2FybikoYFR5cGUzIGNoYXJhY3RlciBcIiR7Z2x5cGgub3BlcmF0b3JMaXN0SWR9XCIgaXMgbm90IGF2YWlsYWJsZS5gKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmNvbnRlbnRWaXNpYmxlKSB7XG4gICAgICAgIHRoaXMucHJvY2Vzc2luZ1R5cGUzID0gZ2x5cGg7XG4gICAgICAgIHRoaXMuc2F2ZSgpO1xuICAgICAgICBjdHguc2NhbGUoZm9udFNpemUsIGZvbnRTaXplKTtcbiAgICAgICAgY3R4LnRyYW5zZm9ybS5hcHBseShjdHgsIGZvbnRNYXRyaXgpO1xuICAgICAgICB0aGlzLmV4ZWN1dGVPcGVyYXRvckxpc3Qob3BlcmF0b3JMaXN0KTtcbiAgICAgICAgdGhpcy5yZXN0b3JlKCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRyYW5zZm9ybWVkID0gX3V0aWwuVXRpbC5hcHBseVRyYW5zZm9ybShbZ2x5cGgud2lkdGgsIDBdLCBmb250TWF0cml4KTtcblxuICAgICAgd2lkdGggPSB0cmFuc2Zvcm1lZFswXSAqIGZvbnRTaXplICsgc3BhY2luZztcbiAgICAgIGN0eC50cmFuc2xhdGUod2lkdGgsIDApO1xuICAgICAgY3VycmVudC54ICs9IHdpZHRoICogdGV4dEhTY2FsZTtcbiAgICB9XG5cbiAgICBjdHgucmVzdG9yZSgpO1xuICAgIHRoaXMucHJvY2Vzc2luZ1R5cGUzID0gbnVsbDtcbiAgfVxuXG4gIHNldENoYXJXaWR0aCh4V2lkdGgsIHlXaWR0aCkge31cblxuICBzZXRDaGFyV2lkdGhBbmRCb3VuZHMoeFdpZHRoLCB5V2lkdGgsIGxseCwgbGx5LCB1cngsIHVyeSkge1xuICAgIHRoaXMuY3R4LnJlY3QobGx4LCBsbHksIHVyeCAtIGxseCwgdXJ5IC0gbGx5KTtcbiAgICB0aGlzLmN0eC5jbGlwKCk7XG4gICAgdGhpcy5lbmRQYXRoKCk7XG4gIH1cblxuICBnZXRDb2xvck5fUGF0dGVybihJUikge1xuICAgIGxldCBwYXR0ZXJuO1xuXG4gICAgaWYgKElSWzBdID09PSBcIlRpbGluZ1BhdHRlcm5cIikge1xuICAgICAgY29uc3QgY29sb3IgPSBJUlsxXTtcbiAgICAgIGNvbnN0IGJhc2VUcmFuc2Zvcm0gPSB0aGlzLmJhc2VUcmFuc2Zvcm0gfHwgdGhpcy5jdHgubW96Q3VycmVudFRyYW5zZm9ybS5zbGljZSgpO1xuICAgICAgY29uc3QgY2FudmFzR3JhcGhpY3NGYWN0b3J5ID0ge1xuICAgICAgICBjcmVhdGVDYW52YXNHcmFwaGljczogY3R4ID0+IHtcbiAgICAgICAgICByZXR1cm4gbmV3IENhbnZhc0dyYXBoaWNzKGN0eCwgdGhpcy5jb21tb25PYmpzLCB0aGlzLm9ianMsIHRoaXMuY2FudmFzRmFjdG9yeSk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBwYXR0ZXJuID0gbmV3IF9wYXR0ZXJuX2hlbHBlci5UaWxpbmdQYXR0ZXJuKElSLCBjb2xvciwgdGhpcy5jdHgsIGNhbnZhc0dyYXBoaWNzRmFjdG9yeSwgYmFzZVRyYW5zZm9ybSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhdHRlcm4gPSB0aGlzLl9nZXRQYXR0ZXJuKElSWzFdLCBJUlsyXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhdHRlcm47XG4gIH1cblxuICBzZXRTdHJva2VDb2xvck4oKSB7XG4gICAgdGhpcy5jdXJyZW50LnN0cm9rZUNvbG9yID0gdGhpcy5nZXRDb2xvck5fUGF0dGVybihhcmd1bWVudHMpO1xuICB9XG5cbiAgc2V0RmlsbENvbG9yTigpIHtcbiAgICB0aGlzLmN1cnJlbnQuZmlsbENvbG9yID0gdGhpcy5nZXRDb2xvck5fUGF0dGVybihhcmd1bWVudHMpO1xuICAgIHRoaXMuY3VycmVudC5wYXR0ZXJuRmlsbCA9IHRydWU7XG4gIH1cblxuICBzZXRTdHJva2VSR0JDb2xvcihyLCBnLCBiKSB7XG4gICAgY29uc3QgY29sb3IgPSB0aGlzLnNlbGVjdENvbG9yPy4ociwgZywgYikgfHwgX3V0aWwuVXRpbC5tYWtlSGV4Q29sb3IociwgZywgYik7XG5cbiAgICB0aGlzLmN0eC5zdHJva2VTdHlsZSA9IGNvbG9yO1xuICAgIHRoaXMuY3VycmVudC5zdHJva2VDb2xvciA9IGNvbG9yO1xuICB9XG5cbiAgc2V0RmlsbFJHQkNvbG9yKHIsIGcsIGIpIHtcbiAgICBjb25zdCBjb2xvciA9IHRoaXMuc2VsZWN0Q29sb3I/LihyLCBnLCBiKSB8fCBfdXRpbC5VdGlsLm1ha2VIZXhDb2xvcihyLCBnLCBiKTtcblxuICAgIHRoaXMuY3R4LmZpbGxTdHlsZSA9IGNvbG9yO1xuICAgIHRoaXMuY3VycmVudC5maWxsQ29sb3IgPSBjb2xvcjtcbiAgICB0aGlzLmN1cnJlbnQucGF0dGVybkZpbGwgPSBmYWxzZTtcbiAgfVxuXG4gIF9nZXRQYXR0ZXJuKG9iaklkLCBtYXRyaXggPSBudWxsKSB7XG4gICAgbGV0IHBhdHRlcm47XG5cbiAgICBpZiAodGhpcy5jYWNoZWRQYXR0ZXJucy5oYXMob2JqSWQpKSB7XG4gICAgICBwYXR0ZXJuID0gdGhpcy5jYWNoZWRQYXR0ZXJucy5nZXQob2JqSWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYXR0ZXJuID0gKDAsIF9wYXR0ZXJuX2hlbHBlci5nZXRTaGFkaW5nUGF0dGVybikodGhpcy5vYmpzLmdldChvYmpJZCkpO1xuICAgICAgdGhpcy5jYWNoZWRQYXR0ZXJucy5zZXQob2JqSWQsIHBhdHRlcm4pO1xuICAgIH1cblxuICAgIGlmIChtYXRyaXgpIHtcbiAgICAgIHBhdHRlcm4ubWF0cml4ID0gbWF0cml4O1xuICAgIH1cblxuICAgIHJldHVybiBwYXR0ZXJuO1xuICB9XG5cbiAgc2hhZGluZ0ZpbGwob2JqSWQpIHtcbiAgICBpZiAoIXRoaXMuY29udGVudFZpc2libGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcbiAgICB0aGlzLnNhdmUoKTtcblxuICAgIGNvbnN0IHBhdHRlcm4gPSB0aGlzLl9nZXRQYXR0ZXJuKG9iaklkKTtcblxuICAgIGN0eC5maWxsU3R5bGUgPSBwYXR0ZXJuLmdldFBhdHRlcm4oY3R4LCB0aGlzLCBjdHgubW96Q3VycmVudFRyYW5zZm9ybUludmVyc2UsIF9wYXR0ZXJuX2hlbHBlci5QYXRoVHlwZS5TSEFESU5HKTtcbiAgICBjb25zdCBpbnYgPSBjdHgubW96Q3VycmVudFRyYW5zZm9ybUludmVyc2U7XG5cbiAgICBpZiAoaW52KSB7XG4gICAgICBjb25zdCBjYW52YXMgPSBjdHguY2FudmFzO1xuICAgICAgY29uc3Qgd2lkdGggPSBjYW52YXMud2lkdGg7XG4gICAgICBjb25zdCBoZWlnaHQgPSBjYW52YXMuaGVpZ2h0O1xuXG4gICAgICBjb25zdCBibCA9IF91dGlsLlV0aWwuYXBwbHlUcmFuc2Zvcm0oWzAsIDBdLCBpbnYpO1xuXG4gICAgICBjb25zdCBiciA9IF91dGlsLlV0aWwuYXBwbHlUcmFuc2Zvcm0oWzAsIGhlaWdodF0sIGludik7XG5cbiAgICAgIGNvbnN0IHVsID0gX3V0aWwuVXRpbC5hcHBseVRyYW5zZm9ybShbd2lkdGgsIDBdLCBpbnYpO1xuXG4gICAgICBjb25zdCB1ciA9IF91dGlsLlV0aWwuYXBwbHlUcmFuc2Zvcm0oW3dpZHRoLCBoZWlnaHRdLCBpbnYpO1xuXG4gICAgICBjb25zdCB4MCA9IE1hdGgubWluKGJsWzBdLCBiclswXSwgdWxbMF0sIHVyWzBdKTtcbiAgICAgIGNvbnN0IHkwID0gTWF0aC5taW4oYmxbMV0sIGJyWzFdLCB1bFsxXSwgdXJbMV0pO1xuICAgICAgY29uc3QgeDEgPSBNYXRoLm1heChibFswXSwgYnJbMF0sIHVsWzBdLCB1clswXSk7XG4gICAgICBjb25zdCB5MSA9IE1hdGgubWF4KGJsWzFdLCBiclsxXSwgdWxbMV0sIHVyWzFdKTtcbiAgICAgIHRoaXMuY3R4LmZpbGxSZWN0KHgwLCB5MCwgeDEgLSB4MCwgeTEgLSB5MCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3R4LmZpbGxSZWN0KC0xZTEwLCAtMWUxMCwgMmUxMCwgMmUxMCk7XG4gICAgfVxuXG4gICAgdGhpcy5jb21wb3NlKHRoaXMuY3VycmVudC5nZXRDbGlwcGVkUGF0aEJvdW5kaW5nQm94KCkpO1xuICAgIHRoaXMucmVzdG9yZSgpO1xuICB9XG5cbiAgYmVnaW5JbmxpbmVJbWFnZSgpIHtcbiAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiU2hvdWxkIG5vdCBjYWxsIGJlZ2luSW5saW5lSW1hZ2VcIik7XG4gIH1cblxuICBiZWdpbkltYWdlRGF0YSgpIHtcbiAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiU2hvdWxkIG5vdCBjYWxsIGJlZ2luSW1hZ2VEYXRhXCIpO1xuICB9XG5cbiAgcGFpbnRGb3JtWE9iamVjdEJlZ2luKG1hdHJpeCwgYmJveCkge1xuICAgIGlmICghdGhpcy5jb250ZW50VmlzaWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc2F2ZSgpO1xuICAgIHRoaXMuYmFzZVRyYW5zZm9ybVN0YWNrLnB1c2godGhpcy5iYXNlVHJhbnNmb3JtKTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KG1hdHJpeCkgJiYgbWF0cml4Lmxlbmd0aCA9PT0gNikge1xuICAgICAgdGhpcy50cmFuc2Zvcm0uYXBwbHkodGhpcywgbWF0cml4KTtcbiAgICB9XG5cbiAgICB0aGlzLmJhc2VUcmFuc2Zvcm0gPSB0aGlzLmN0eC5tb3pDdXJyZW50VHJhbnNmb3JtO1xuXG4gICAgaWYgKGJib3gpIHtcbiAgICAgIGNvbnN0IHdpZHRoID0gYmJveFsyXSAtIGJib3hbMF07XG4gICAgICBjb25zdCBoZWlnaHQgPSBiYm94WzNdIC0gYmJveFsxXTtcbiAgICAgIHRoaXMuY3R4LnJlY3QoYmJveFswXSwgYmJveFsxXSwgd2lkdGgsIGhlaWdodCk7XG4gICAgICB0aGlzLmN1cnJlbnQudXBkYXRlUmVjdE1pbk1heCh0aGlzLmN0eC5tb3pDdXJyZW50VHJhbnNmb3JtLCBiYm94KTtcbiAgICAgIHRoaXMuY2xpcCgpO1xuICAgICAgdGhpcy5lbmRQYXRoKCk7XG4gICAgfVxuICB9XG5cbiAgcGFpbnRGb3JtWE9iamVjdEVuZCgpIHtcbiAgICBpZiAoIXRoaXMuY29udGVudFZpc2libGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnJlc3RvcmUoKTtcbiAgICB0aGlzLmJhc2VUcmFuc2Zvcm0gPSB0aGlzLmJhc2VUcmFuc2Zvcm1TdGFjay5wb3AoKTtcbiAgfVxuXG4gIGJlZ2luR3JvdXAoZ3JvdXApIHtcbiAgICBpZiAoIXRoaXMuY29udGVudFZpc2libGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNhdmUoKTtcblxuICAgIGlmICh0aGlzLmluU01hc2tNb2RlKSB7XG4gICAgICB0aGlzLmVuZFNNYXNrTW9kZSgpO1xuICAgICAgdGhpcy5jdXJyZW50LmFjdGl2ZVNNYXNrID0gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50Q3R4ID0gdGhpcy5jdHg7XG5cbiAgICBpZiAoIWdyb3VwLmlzb2xhdGVkKSB7XG4gICAgICAoMCwgX3V0aWwuaW5mbykoXCJUT0RPOiBTdXBwb3J0IG5vbi1pc29sYXRlZCBncm91cHMuXCIpO1xuICAgIH1cblxuICAgIGlmIChncm91cC5rbm9ja291dCkge1xuICAgICAgKDAsIF91dGlsLndhcm4pKFwiS25vY2tvdXQgZ3JvdXBzIG5vdCBzdXBwb3J0ZWQuXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IGN1cnJlbnRUcmFuc2Zvcm0gPSBjdXJyZW50Q3R4Lm1vekN1cnJlbnRUcmFuc2Zvcm07XG5cbiAgICBpZiAoZ3JvdXAubWF0cml4KSB7XG4gICAgICBjdXJyZW50Q3R4LnRyYW5zZm9ybS5hcHBseShjdXJyZW50Q3R4LCBncm91cC5tYXRyaXgpO1xuICAgIH1cblxuICAgIGlmICghZ3JvdXAuYmJveCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQm91bmRpbmcgYm94IGlzIHJlcXVpcmVkLlwiKTtcbiAgICB9XG5cbiAgICBsZXQgYm91bmRzID0gX3V0aWwuVXRpbC5nZXRBeGlhbEFsaWduZWRCb3VuZGluZ0JveChncm91cC5iYm94LCBjdXJyZW50Q3R4Lm1vekN1cnJlbnRUcmFuc2Zvcm0pO1xuXG4gICAgY29uc3QgY2FudmFzQm91bmRzID0gWzAsIDAsIGN1cnJlbnRDdHguY2FudmFzLndpZHRoLCBjdXJyZW50Q3R4LmNhbnZhcy5oZWlnaHRdO1xuICAgIGJvdW5kcyA9IF91dGlsLlV0aWwuaW50ZXJzZWN0KGJvdW5kcywgY2FudmFzQm91bmRzKSB8fCBbMCwgMCwgMCwgMF07XG4gICAgY29uc3Qgb2Zmc2V0WCA9IE1hdGguZmxvb3IoYm91bmRzWzBdKTtcbiAgICBjb25zdCBvZmZzZXRZID0gTWF0aC5mbG9vcihib3VuZHNbMV0pO1xuICAgIGxldCBkcmF3bldpZHRoID0gTWF0aC5tYXgoTWF0aC5jZWlsKGJvdW5kc1syXSkgLSBvZmZzZXRYLCAxKTtcbiAgICBsZXQgZHJhd25IZWlnaHQgPSBNYXRoLm1heChNYXRoLmNlaWwoYm91bmRzWzNdKSAtIG9mZnNldFksIDEpO1xuICAgIGxldCBzY2FsZVggPSAxLFxuICAgICAgICBzY2FsZVkgPSAxO1xuXG4gICAgaWYgKGRyYXduV2lkdGggPiBNQVhfR1JPVVBfU0laRSkge1xuICAgICAgc2NhbGVYID0gZHJhd25XaWR0aCAvIE1BWF9HUk9VUF9TSVpFO1xuICAgICAgZHJhd25XaWR0aCA9IE1BWF9HUk9VUF9TSVpFO1xuICAgIH1cblxuICAgIGlmIChkcmF3bkhlaWdodCA+IE1BWF9HUk9VUF9TSVpFKSB7XG4gICAgICBzY2FsZVkgPSBkcmF3bkhlaWdodCAvIE1BWF9HUk9VUF9TSVpFO1xuICAgICAgZHJhd25IZWlnaHQgPSBNQVhfR1JPVVBfU0laRTtcbiAgICB9XG5cbiAgICB0aGlzLmN1cnJlbnQuc3RhcnROZXdQYXRoQW5kQ2xpcEJveChbMCwgMCwgZHJhd25XaWR0aCwgZHJhd25IZWlnaHRdKTtcbiAgICBsZXQgY2FjaGVJZCA9IFwiZ3JvdXBBdFwiICsgdGhpcy5ncm91cExldmVsO1xuXG4gICAgaWYgKGdyb3VwLnNtYXNrKSB7XG4gICAgICBjYWNoZUlkICs9IFwiX3NtYXNrX1wiICsgdGhpcy5zbWFza0NvdW50ZXIrKyAlIDI7XG4gICAgfVxuXG4gICAgY29uc3Qgc2NyYXRjaENhbnZhcyA9IHRoaXMuY2FjaGVkQ2FudmFzZXMuZ2V0Q2FudmFzKGNhY2hlSWQsIGRyYXduV2lkdGgsIGRyYXduSGVpZ2h0LCB0cnVlKTtcbiAgICBjb25zdCBncm91cEN0eCA9IHNjcmF0Y2hDYW52YXMuY29udGV4dDtcbiAgICBncm91cEN0eC5zY2FsZSgxIC8gc2NhbGVYLCAxIC8gc2NhbGVZKTtcbiAgICBncm91cEN0eC50cmFuc2xhdGUoLW9mZnNldFgsIC1vZmZzZXRZKTtcbiAgICBncm91cEN0eC50cmFuc2Zvcm0uYXBwbHkoZ3JvdXBDdHgsIGN1cnJlbnRUcmFuc2Zvcm0pO1xuXG4gICAgaWYgKGdyb3VwLnNtYXNrKSB7XG4gICAgICB0aGlzLnNtYXNrU3RhY2sucHVzaCh7XG4gICAgICAgIGNhbnZhczogc2NyYXRjaENhbnZhcy5jYW52YXMsXG4gICAgICAgIGNvbnRleHQ6IGdyb3VwQ3R4LFxuICAgICAgICBvZmZzZXRYLFxuICAgICAgICBvZmZzZXRZLFxuICAgICAgICBzY2FsZVgsXG4gICAgICAgIHNjYWxlWSxcbiAgICAgICAgc3VidHlwZTogZ3JvdXAuc21hc2suc3VidHlwZSxcbiAgICAgICAgYmFja2Ryb3A6IGdyb3VwLnNtYXNrLmJhY2tkcm9wLFxuICAgICAgICB0cmFuc2Zlck1hcDogZ3JvdXAuc21hc2sudHJhbnNmZXJNYXAgfHwgbnVsbCxcbiAgICAgICAgc3RhcnRUcmFuc2Zvcm1JbnZlcnNlOiBudWxsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY3VycmVudEN0eC5zZXRUcmFuc2Zvcm0oMSwgMCwgMCwgMSwgMCwgMCk7XG4gICAgICBjdXJyZW50Q3R4LnRyYW5zbGF0ZShvZmZzZXRYLCBvZmZzZXRZKTtcbiAgICAgIGN1cnJlbnRDdHguc2NhbGUoc2NhbGVYLCBzY2FsZVkpO1xuICAgICAgY3VycmVudEN0eC5zYXZlKCk7XG4gICAgfVxuXG4gICAgY29weUN0eFN0YXRlKGN1cnJlbnRDdHgsIGdyb3VwQ3R4KTtcbiAgICB0aGlzLmN0eCA9IGdyb3VwQ3R4O1xuICAgIHRoaXMuc2V0R1N0YXRlKFtbXCJCTVwiLCBcInNvdXJjZS1vdmVyXCJdLCBbXCJjYVwiLCAxXSwgW1wiQ0FcIiwgMV1dKTtcbiAgICB0aGlzLmdyb3VwU3RhY2sucHVzaChjdXJyZW50Q3R4KTtcbiAgICB0aGlzLmdyb3VwTGV2ZWwrKztcbiAgfVxuXG4gIGVuZEdyb3VwKGdyb3VwKSB7XG4gICAgaWYgKCF0aGlzLmNvbnRlbnRWaXNpYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5ncm91cExldmVsLS07XG4gICAgY29uc3QgZ3JvdXBDdHggPSB0aGlzLmN0eDtcbiAgICBjb25zdCBjdHggPSB0aGlzLmdyb3VwU3RhY2sucG9wKCk7XG4gICAgdGhpcy5jdHggPSBjdHg7XG4gICAgdGhpcy5jdHguaW1hZ2VTbW9vdGhpbmdFbmFibGVkID0gZmFsc2U7XG5cbiAgICBpZiAoZ3JvdXAuc21hc2spIHtcbiAgICAgIHRoaXMudGVtcFNNYXNrID0gdGhpcy5zbWFza1N0YWNrLnBvcCgpO1xuICAgICAgdGhpcy5yZXN0b3JlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3R4LnJlc3RvcmUoKTtcbiAgICAgIGNvbnN0IGN1cnJlbnRNdHggPSB0aGlzLmN0eC5tb3pDdXJyZW50VHJhbnNmb3JtO1xuICAgICAgdGhpcy5yZXN0b3JlKCk7XG4gICAgICB0aGlzLmN0eC5zYXZlKCk7XG4gICAgICB0aGlzLmN0eC5zZXRUcmFuc2Zvcm0uYXBwbHkodGhpcy5jdHgsIGN1cnJlbnRNdHgpO1xuXG4gICAgICBjb25zdCBkaXJ0eUJveCA9IF91dGlsLlV0aWwuZ2V0QXhpYWxBbGlnbmVkQm91bmRpbmdCb3goWzAsIDAsIGdyb3VwQ3R4LmNhbnZhcy53aWR0aCwgZ3JvdXBDdHguY2FudmFzLmhlaWdodF0sIGN1cnJlbnRNdHgpO1xuXG4gICAgICB0aGlzLmN0eC5kcmF3SW1hZ2UoZ3JvdXBDdHguY2FudmFzLCAwLCAwKTtcbiAgICAgIHRoaXMuY3R4LnJlc3RvcmUoKTtcbiAgICAgIHRoaXMuY29tcG9zZShkaXJ0eUJveCk7XG4gICAgfVxuICB9XG5cbiAgYmVnaW5Bbm5vdGF0aW9ucygpIHtcbiAgICB0aGlzLnNhdmUoKTtcblxuICAgIGlmICh0aGlzLmJhc2VUcmFuc2Zvcm0pIHtcbiAgICAgIHRoaXMuY3R4LnNldFRyYW5zZm9ybS5hcHBseSh0aGlzLmN0eCwgdGhpcy5iYXNlVHJhbnNmb3JtKTtcbiAgICB9XG4gIH1cblxuICBlbmRBbm5vdGF0aW9ucygpIHtcbiAgICB0aGlzLnJlc3RvcmUoKTtcbiAgfVxuXG4gIGJlZ2luQW5ub3RhdGlvbihpZCwgcmVjdCwgdHJhbnNmb3JtLCBtYXRyaXgsIGhhc093bkNhbnZhcykge1xuICAgIHRoaXMuc2F2ZSgpO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkocmVjdCkgJiYgcmVjdC5sZW5ndGggPT09IDQpIHtcbiAgICAgIGNvbnN0IHdpZHRoID0gcmVjdFsyXSAtIHJlY3RbMF07XG4gICAgICBjb25zdCBoZWlnaHQgPSByZWN0WzNdIC0gcmVjdFsxXTtcblxuICAgICAgaWYgKGhhc093bkNhbnZhcyAmJiB0aGlzLmFubm90YXRpb25DYW52YXNNYXApIHtcbiAgICAgICAgdHJhbnNmb3JtID0gdHJhbnNmb3JtLnNsaWNlKCk7XG4gICAgICAgIHRyYW5zZm9ybVs0XSAtPSByZWN0WzBdO1xuICAgICAgICB0cmFuc2Zvcm1bNV0gLT0gcmVjdFsxXTtcbiAgICAgICAgcmVjdCA9IHJlY3Quc2xpY2UoKTtcbiAgICAgICAgcmVjdFswXSA9IHJlY3RbMV0gPSAwO1xuICAgICAgICByZWN0WzJdID0gd2lkdGg7XG4gICAgICAgIHJlY3RbM10gPSBoZWlnaHQ7XG5cbiAgICAgICAgY29uc3QgW3NjYWxlWCwgc2NhbGVZXSA9IF91dGlsLlV0aWwuc2luZ3VsYXJWYWx1ZURlY29tcG9zZTJkU2NhbGUodGhpcy5jdHgubW96Q3VycmVudFRyYW5zZm9ybSk7XG5cbiAgICAgICAgY29uc3Qge1xuICAgICAgICAgIHZpZXdwb3J0U2NhbGVcbiAgICAgICAgfSA9IHRoaXM7XG4gICAgICAgIGNvbnN0IGNhbnZhc1dpZHRoID0gTWF0aC5jZWlsKHdpZHRoICogdGhpcy5vdXRwdXRTY2FsZVggKiB2aWV3cG9ydFNjYWxlKTtcbiAgICAgICAgY29uc3QgY2FudmFzSGVpZ2h0ID0gTWF0aC5jZWlsKGhlaWdodCAqIHRoaXMub3V0cHV0U2NhbGVZICogdmlld3BvcnRTY2FsZSk7XG4gICAgICAgIHRoaXMuYW5ub3RhdGlvbkNhbnZhcyA9IHRoaXMuY2FudmFzRmFjdG9yeS5jcmVhdGUoY2FudmFzV2lkdGgsIGNhbnZhc0hlaWdodCk7XG4gICAgICAgIGNvbnN0IHtcbiAgICAgICAgICBjYW52YXMsXG4gICAgICAgICAgY29udGV4dFxuICAgICAgICB9ID0gdGhpcy5hbm5vdGF0aW9uQ2FudmFzO1xuICAgICAgICBjb25zdCB2aWV3cG9ydFNjYWxlRmFjdG9yU3RyID0gYHZhcigtLXpvb20tZmFjdG9yKSAqICR7X2Rpc3BsYXlfdXRpbHMuUGl4ZWxzUGVySW5jaC5QREZfVE9fQ1NTX1VOSVRTfWA7XG4gICAgICAgIGNhbnZhcy5zdHlsZS53aWR0aCA9IGBjYWxjKCR7d2lkdGh9cHggKiAke3ZpZXdwb3J0U2NhbGVGYWN0b3JTdHJ9KWA7XG4gICAgICAgIGNhbnZhcy5zdHlsZS5oZWlnaHQgPSBgY2FsYygke2hlaWdodH1weCAqICR7dmlld3BvcnRTY2FsZUZhY3RvclN0cn0pYDtcbiAgICAgICAgdGhpcy5hbm5vdGF0aW9uQ2FudmFzTWFwLnNldChpZCwgY2FudmFzKTtcbiAgICAgICAgdGhpcy5hbm5vdGF0aW9uQ2FudmFzLnNhdmVkQ3R4ID0gdGhpcy5jdHg7XG4gICAgICAgIHRoaXMuY3R4ID0gY29udGV4dDtcbiAgICAgICAgdGhpcy5jdHguc2V0VHJhbnNmb3JtKHNjYWxlWCwgMCwgMCwgLXNjYWxlWSwgMCwgaGVpZ2h0ICogc2NhbGVZKTtcbiAgICAgICAgYWRkQ29udGV4dEN1cnJlbnRUcmFuc2Zvcm0odGhpcy5jdHgpO1xuICAgICAgICByZXNldEN0eFRvRGVmYXVsdCh0aGlzLmN0eCwgdGhpcy5mb3JlZ3JvdW5kQ29sb3IpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzZXRDdHhUb0RlZmF1bHQodGhpcy5jdHgsIHRoaXMuZm9yZWdyb3VuZENvbG9yKTtcbiAgICAgICAgdGhpcy5jdHgucmVjdChyZWN0WzBdLCByZWN0WzFdLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICAgICAgdGhpcy5jdHguY2xpcCgpO1xuICAgICAgICB0aGlzLmVuZFBhdGgoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmN1cnJlbnQgPSBuZXcgQ2FudmFzRXh0cmFTdGF0ZSh0aGlzLmN0eC5jYW52YXMud2lkdGgsIHRoaXMuY3R4LmNhbnZhcy5oZWlnaHQpO1xuICAgIHRoaXMudHJhbnNmb3JtLmFwcGx5KHRoaXMsIHRyYW5zZm9ybSk7XG4gICAgdGhpcy50cmFuc2Zvcm0uYXBwbHkodGhpcywgbWF0cml4KTtcbiAgfVxuXG4gIGVuZEFubm90YXRpb24oKSB7XG4gICAgaWYgKHRoaXMuYW5ub3RhdGlvbkNhbnZhcykge1xuICAgICAgdGhpcy5jdHggPSB0aGlzLmFubm90YXRpb25DYW52YXMuc2F2ZWRDdHg7XG4gICAgICBkZWxldGUgdGhpcy5hbm5vdGF0aW9uQ2FudmFzLnNhdmVkQ3R4O1xuICAgICAgZGVsZXRlIHRoaXMuYW5ub3RhdGlvbkNhbnZhcztcbiAgICB9XG5cbiAgICB0aGlzLnJlc3RvcmUoKTtcbiAgfVxuXG4gIHBhaW50SW1hZ2VNYXNrWE9iamVjdChpbWcpIHtcbiAgICBpZiAoIXRoaXMuY29udGVudFZpc2libGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjb3VudCA9IGltZy5jb3VudDtcbiAgICBpbWcgPSB0aGlzLmdldE9iamVjdChpbWcuZGF0YSwgaW1nKTtcbiAgICBpbWcuY291bnQgPSBjb3VudDtcbiAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcbiAgICBjb25zdCBnbHlwaCA9IHRoaXMucHJvY2Vzc2luZ1R5cGUzO1xuXG4gICAgaWYgKGdseXBoKSB7XG4gICAgICBpZiAoZ2x5cGguY29tcGlsZWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBnbHlwaC5jb21waWxlZCA9IGNvbXBpbGVUeXBlM0dseXBoKGltZyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChnbHlwaC5jb21waWxlZCkge1xuICAgICAgICBnbHlwaC5jb21waWxlZChjdHgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgbWFzayA9IHRoaXMuX2NyZWF0ZU1hc2tDYW52YXMoaW1nKTtcblxuICAgIGNvbnN0IG1hc2tDYW52YXMgPSBtYXNrLmNhbnZhcztcbiAgICBjdHguc2F2ZSgpO1xuICAgIGN0eC5zZXRUcmFuc2Zvcm0oMSwgMCwgMCwgMSwgMCwgMCk7XG4gICAgY3R4LmRyYXdJbWFnZShtYXNrQ2FudmFzLCBtYXNrLm9mZnNldFgsIG1hc2sub2Zmc2V0WSk7XG4gICAgY3R4LnJlc3RvcmUoKTtcbiAgICB0aGlzLmNvbXBvc2UoKTtcbiAgfVxuXG4gIHBhaW50SW1hZ2VNYXNrWE9iamVjdFJlcGVhdChpbWcsIHNjYWxlWCwgc2tld1ggPSAwLCBza2V3WSA9IDAsIHNjYWxlWSwgcG9zaXRpb25zKSB7XG4gICAgaWYgKCF0aGlzLmNvbnRlbnRWaXNpYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaW1nID0gdGhpcy5nZXRPYmplY3QoaW1nLmRhdGEsIGltZyk7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY3R4LnNhdmUoKTtcbiAgICBjb25zdCBjdXJyZW50VHJhbnNmb3JtID0gY3R4Lm1vekN1cnJlbnRUcmFuc2Zvcm07XG4gICAgY3R4LnRyYW5zZm9ybShzY2FsZVgsIHNrZXdYLCBza2V3WSwgc2NhbGVZLCAwLCAwKTtcblxuICAgIGNvbnN0IG1hc2sgPSB0aGlzLl9jcmVhdGVNYXNrQ2FudmFzKGltZyk7XG5cbiAgICBjdHguc2V0VHJhbnNmb3JtKDEsIDAsIDAsIDEsIDAsIDApO1xuXG4gICAgZm9yIChsZXQgaSA9IDAsIGlpID0gcG9zaXRpb25zLmxlbmd0aDsgaSA8IGlpOyBpICs9IDIpIHtcbiAgICAgIGNvbnN0IHRyYW5zID0gX3V0aWwuVXRpbC50cmFuc2Zvcm0oY3VycmVudFRyYW5zZm9ybSwgW3NjYWxlWCwgc2tld1gsIHNrZXdZLCBzY2FsZVksIHBvc2l0aW9uc1tpXSwgcG9zaXRpb25zW2kgKyAxXV0pO1xuXG4gICAgICBjb25zdCBbeCwgeV0gPSBfdXRpbC5VdGlsLmFwcGx5VHJhbnNmb3JtKFswLCAwXSwgdHJhbnMpO1xuXG4gICAgICBjdHguZHJhd0ltYWdlKG1hc2suY2FudmFzLCB4LCB5KTtcbiAgICB9XG5cbiAgICBjdHgucmVzdG9yZSgpO1xuICAgIHRoaXMuY29tcG9zZSgpO1xuICB9XG5cbiAgcGFpbnRJbWFnZU1hc2tYT2JqZWN0R3JvdXAoaW1hZ2VzKSB7XG4gICAgaWYgKCF0aGlzLmNvbnRlbnRWaXNpYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY29uc3QgZmlsbENvbG9yID0gdGhpcy5jdXJyZW50LmZpbGxDb2xvcjtcbiAgICBjb25zdCBpc1BhdHRlcm5GaWxsID0gdGhpcy5jdXJyZW50LnBhdHRlcm5GaWxsO1xuXG4gICAgZm9yIChsZXQgaSA9IDAsIGlpID0gaW1hZ2VzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgIGNvbnN0IGltYWdlID0gaW1hZ2VzW2ldO1xuICAgICAgY29uc3Qgd2lkdGggPSBpbWFnZS53aWR0aCxcbiAgICAgICAgICAgIGhlaWdodCA9IGltYWdlLmhlaWdodDtcbiAgICAgIGNvbnN0IG1hc2tDYW52YXMgPSB0aGlzLmNhY2hlZENhbnZhc2VzLmdldENhbnZhcyhcIm1hc2tDYW52YXNcIiwgd2lkdGgsIGhlaWdodCwgZmFsc2UpO1xuICAgICAgY29uc3QgbWFza0N0eCA9IG1hc2tDYW52YXMuY29udGV4dDtcbiAgICAgIG1hc2tDdHguc2F2ZSgpO1xuICAgICAgcHV0QmluYXJ5SW1hZ2VNYXNrKG1hc2tDdHgsIGltYWdlKTtcbiAgICAgIG1hc2tDdHguZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uID0gXCJzb3VyY2UtaW5cIjtcbiAgICAgIG1hc2tDdHguZmlsbFN0eWxlID0gaXNQYXR0ZXJuRmlsbCA/IGZpbGxDb2xvci5nZXRQYXR0ZXJuKG1hc2tDdHgsIHRoaXMsIGN0eC5tb3pDdXJyZW50VHJhbnNmb3JtSW52ZXJzZSwgX3BhdHRlcm5faGVscGVyLlBhdGhUeXBlLkZJTEwpIDogZmlsbENvbG9yO1xuICAgICAgbWFza0N0eC5maWxsUmVjdCgwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICAgIG1hc2tDdHgucmVzdG9yZSgpO1xuICAgICAgY3R4LnNhdmUoKTtcbiAgICAgIGN0eC50cmFuc2Zvcm0uYXBwbHkoY3R4LCBpbWFnZS50cmFuc2Zvcm0pO1xuICAgICAgY3R4LnNjYWxlKDEsIC0xKTtcbiAgICAgIGRyYXdJbWFnZUF0SW50ZWdlckNvb3JkcyhjdHgsIG1hc2tDYW52YXMuY2FudmFzLCAwLCAwLCB3aWR0aCwgaGVpZ2h0LCAwLCAtMSwgMSwgMSk7XG4gICAgICBjdHgucmVzdG9yZSgpO1xuICAgIH1cblxuICAgIHRoaXMuY29tcG9zZSgpO1xuICB9XG5cbiAgcGFpbnRJbWFnZVhPYmplY3Qob2JqSWQpIHtcbiAgICBpZiAoIXRoaXMuY29udGVudFZpc2libGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBpbWdEYXRhID0gdGhpcy5nZXRPYmplY3Qob2JqSWQpO1xuXG4gICAgaWYgKCFpbWdEYXRhKSB7XG4gICAgICAoMCwgX3V0aWwud2FybikoXCJEZXBlbmRlbnQgaW1hZ2UgaXNuJ3QgcmVhZHkgeWV0XCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMucGFpbnRJbmxpbmVJbWFnZVhPYmplY3QoaW1nRGF0YSk7XG4gIH1cblxuICBwYWludEltYWdlWE9iamVjdFJlcGVhdChvYmpJZCwgc2NhbGVYLCBzY2FsZVksIHBvc2l0aW9ucykge1xuICAgIGlmICghdGhpcy5jb250ZW50VmlzaWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGltZ0RhdGEgPSB0aGlzLmdldE9iamVjdChvYmpJZCk7XG5cbiAgICBpZiAoIWltZ0RhdGEpIHtcbiAgICAgICgwLCBfdXRpbC53YXJuKShcIkRlcGVuZGVudCBpbWFnZSBpc24ndCByZWFkeSB5ZXRcIik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgd2lkdGggPSBpbWdEYXRhLndpZHRoO1xuICAgIGNvbnN0IGhlaWdodCA9IGltZ0RhdGEuaGVpZ2h0O1xuICAgIGNvbnN0IG1hcCA9IFtdO1xuXG4gICAgZm9yIChsZXQgaSA9IDAsIGlpID0gcG9zaXRpb25zLmxlbmd0aDsgaSA8IGlpOyBpICs9IDIpIHtcbiAgICAgIG1hcC5wdXNoKHtcbiAgICAgICAgdHJhbnNmb3JtOiBbc2NhbGVYLCAwLCAwLCBzY2FsZVksIHBvc2l0aW9uc1tpXSwgcG9zaXRpb25zW2kgKyAxXV0sXG4gICAgICAgIHg6IDAsXG4gICAgICAgIHk6IDAsXG4gICAgICAgIHc6IHdpZHRoLFxuICAgICAgICBoOiBoZWlnaHRcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMucGFpbnRJbmxpbmVJbWFnZVhPYmplY3RHcm91cChpbWdEYXRhLCBtYXApO1xuICB9XG5cbiAgcGFpbnRJbmxpbmVJbWFnZVhPYmplY3QoaW1nRGF0YSkge1xuICAgIGlmICghdGhpcy5jb250ZW50VmlzaWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHdpZHRoID0gaW1nRGF0YS53aWR0aDtcbiAgICBjb25zdCBoZWlnaHQgPSBpbWdEYXRhLmhlaWdodDtcbiAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcbiAgICB0aGlzLnNhdmUoKTtcbiAgICBjdHguc2NhbGUoMSAvIHdpZHRoLCAtMSAvIGhlaWdodCk7XG4gICAgbGV0IGltZ1RvUGFpbnQ7XG5cbiAgICBpZiAodHlwZW9mIEhUTUxFbGVtZW50ID09PSBcImZ1bmN0aW9uXCIgJiYgaW1nRGF0YSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50IHx8ICFpbWdEYXRhLmRhdGEpIHtcbiAgICAgIGltZ1RvUGFpbnQgPSBpbWdEYXRhO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB0bXBDYW52YXMgPSB0aGlzLmNhY2hlZENhbnZhc2VzLmdldENhbnZhcyhcImlubGluZUltYWdlXCIsIHdpZHRoLCBoZWlnaHQsIGZhbHNlKTtcbiAgICAgIGNvbnN0IHRtcEN0eCA9IHRtcENhbnZhcy5jb250ZXh0O1xuICAgICAgcHV0QmluYXJ5SW1hZ2VEYXRhKHRtcEN0eCwgaW1nRGF0YSwgdGhpcy5jdXJyZW50LnRyYW5zZmVyTWFwcyk7XG4gICAgICBpbWdUb1BhaW50ID0gdG1wQ2FudmFzLmNhbnZhcztcbiAgICB9XG5cbiAgICBjb25zdCBzY2FsZWQgPSB0aGlzLl9zY2FsZUltYWdlKGltZ1RvUGFpbnQsIGN0eC5tb3pDdXJyZW50VHJhbnNmb3JtSW52ZXJzZSk7XG5cbiAgICBjdHguaW1hZ2VTbW9vdGhpbmdFbmFibGVkID0gZ2V0SW1hZ2VTbW9vdGhpbmdFbmFibGVkKGN0eC5tb3pDdXJyZW50VHJhbnNmb3JtLCBpbWdEYXRhLmludGVycG9sYXRlKTtcbiAgICBjb25zdCBbcldpZHRoLCBySGVpZ2h0XSA9IGRyYXdJbWFnZUF0SW50ZWdlckNvb3JkcyhjdHgsIHNjYWxlZC5pbWcsIDAsIDAsIHNjYWxlZC5wYWludFdpZHRoLCBzY2FsZWQucGFpbnRIZWlnaHQsIDAsIC1oZWlnaHQsIHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgaWYgKHRoaXMuaW1hZ2VMYXllcikge1xuICAgICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmdldENhbnZhc1Bvc2l0aW9uKDAsIC1oZWlnaHQpO1xuICAgICAgdGhpcy5pbWFnZUxheWVyLmFwcGVuZEltYWdlKHtcbiAgICAgICAgaW1nRGF0YSxcbiAgICAgICAgbGVmdDogcG9zaXRpb25bMF0sXG4gICAgICAgIHRvcDogcG9zaXRpb25bMV0sXG4gICAgICAgIHdpZHRoOiByV2lkdGgsXG4gICAgICAgIGhlaWdodDogckhlaWdodFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5jb21wb3NlKCk7XG4gICAgdGhpcy5yZXN0b3JlKCk7XG4gIH1cblxuICBwYWludElubGluZUltYWdlWE9iamVjdEdyb3VwKGltZ0RhdGEsIG1hcCkge1xuICAgIGlmICghdGhpcy5jb250ZW50VmlzaWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGN0eCA9IHRoaXMuY3R4O1xuICAgIGNvbnN0IHcgPSBpbWdEYXRhLndpZHRoO1xuICAgIGNvbnN0IGggPSBpbWdEYXRhLmhlaWdodDtcbiAgICBjb25zdCB0bXBDYW52YXMgPSB0aGlzLmNhY2hlZENhbnZhc2VzLmdldENhbnZhcyhcImlubGluZUltYWdlXCIsIHcsIGgsIGZhbHNlKTtcbiAgICBjb25zdCB0bXBDdHggPSB0bXBDYW52YXMuY29udGV4dDtcbiAgICBwdXRCaW5hcnlJbWFnZURhdGEodG1wQ3R4LCBpbWdEYXRhLCB0aGlzLmN1cnJlbnQudHJhbnNmZXJNYXBzKTtcblxuICAgIGZvciAobGV0IGkgPSAwLCBpaSA9IG1hcC5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICBjb25zdCBlbnRyeSA9IG1hcFtpXTtcbiAgICAgIGN0eC5zYXZlKCk7XG4gICAgICBjdHgudHJhbnNmb3JtLmFwcGx5KGN0eCwgZW50cnkudHJhbnNmb3JtKTtcbiAgICAgIGN0eC5zY2FsZSgxLCAtMSk7XG4gICAgICBkcmF3SW1hZ2VBdEludGVnZXJDb29yZHMoY3R4LCB0bXBDYW52YXMuY2FudmFzLCBlbnRyeS54LCBlbnRyeS55LCBlbnRyeS53LCBlbnRyeS5oLCAwLCAtMSwgMSwgMSk7XG5cbiAgICAgIGlmICh0aGlzLmltYWdlTGF5ZXIpIHtcbiAgICAgICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmdldENhbnZhc1Bvc2l0aW9uKGVudHJ5LngsIGVudHJ5LnkpO1xuICAgICAgICB0aGlzLmltYWdlTGF5ZXIuYXBwZW5kSW1hZ2Uoe1xuICAgICAgICAgIGltZ0RhdGEsXG4gICAgICAgICAgbGVmdDogcG9zaXRpb25bMF0sXG4gICAgICAgICAgdG9wOiBwb3NpdGlvblsxXSxcbiAgICAgICAgICB3aWR0aDogdyxcbiAgICAgICAgICBoZWlnaHQ6IGhcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgfVxuXG4gICAgdGhpcy5jb21wb3NlKCk7XG4gIH1cblxuICBwYWludFNvbGlkQ29sb3JJbWFnZU1hc2soKSB7XG4gICAgaWYgKCF0aGlzLmNvbnRlbnRWaXNpYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5jdHguZmlsbFJlY3QoMCwgMCwgMSwgMSk7XG4gICAgdGhpcy5jb21wb3NlKCk7XG4gIH1cblxuICBtYXJrUG9pbnQodGFnKSB7fVxuXG4gIG1hcmtQb2ludFByb3BzKHRhZywgcHJvcGVydGllcykge31cblxuICBiZWdpbk1hcmtlZENvbnRlbnQodGFnKSB7XG4gICAgdGhpcy5tYXJrZWRDb250ZW50U3RhY2sucHVzaCh7XG4gICAgICB2aXNpYmxlOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICBiZWdpbk1hcmtlZENvbnRlbnRQcm9wcyh0YWcsIHByb3BlcnRpZXMpIHtcbiAgICBpZiAodGFnID09PSBcIk9DXCIpIHtcbiAgICAgIHRoaXMubWFya2VkQ29udGVudFN0YWNrLnB1c2goe1xuICAgICAgICB2aXNpYmxlOiB0aGlzLm9wdGlvbmFsQ29udGVudENvbmZpZy5pc1Zpc2libGUocHJvcGVydGllcylcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1hcmtlZENvbnRlbnRTdGFjay5wdXNoKHtcbiAgICAgICAgdmlzaWJsZTogdHJ1ZVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5jb250ZW50VmlzaWJsZSA9IHRoaXMuaXNDb250ZW50VmlzaWJsZSgpO1xuICB9XG5cbiAgZW5kTWFya2VkQ29udGVudCgpIHtcbiAgICB0aGlzLm1hcmtlZENvbnRlbnRTdGFjay5wb3AoKTtcbiAgICB0aGlzLmNvbnRlbnRWaXNpYmxlID0gdGhpcy5pc0NvbnRlbnRWaXNpYmxlKCk7XG4gIH1cblxuICBiZWdpbkNvbXBhdCgpIHt9XG5cbiAgZW5kQ29tcGF0KCkge31cblxuICBjb25zdW1lUGF0aChjbGlwQm94KSB7XG4gICAgY29uc3QgaXNFbXB0eSA9IHRoaXMuY3VycmVudC5pc0VtcHR5Q2xpcCgpO1xuXG4gICAgaWYgKHRoaXMucGVuZGluZ0NsaXApIHtcbiAgICAgIHRoaXMuY3VycmVudC51cGRhdGVDbGlwRnJvbVBhdGgoKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMucGVuZGluZ0NsaXApIHtcbiAgICAgIHRoaXMuY29tcG9zZShjbGlwQm94KTtcbiAgICB9XG5cbiAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcblxuICAgIGlmICh0aGlzLnBlbmRpbmdDbGlwKSB7XG4gICAgICBpZiAoIWlzRW1wdHkpIHtcbiAgICAgICAgaWYgKHRoaXMucGVuZGluZ0NsaXAgPT09IEVPX0NMSVApIHtcbiAgICAgICAgICBjdHguY2xpcChcImV2ZW5vZGRcIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY3R4LmNsaXAoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLnBlbmRpbmdDbGlwID0gbnVsbDtcbiAgICB9XG5cbiAgICB0aGlzLmN1cnJlbnQuc3RhcnROZXdQYXRoQW5kQ2xpcEJveCh0aGlzLmN1cnJlbnQuY2xpcEJveCk7XG4gICAgY3R4LmJlZ2luUGF0aCgpO1xuICB9XG5cbiAgZ2V0U2luZ2xlUGl4ZWxXaWR0aCgpIHtcbiAgICBpZiAoIXRoaXMuX2NhY2hlZEdldFNpbmdsZVBpeGVsV2lkdGgpIHtcbiAgICAgIGNvbnN0IG0gPSB0aGlzLmN0eC5tb3pDdXJyZW50VHJhbnNmb3JtO1xuXG4gICAgICBpZiAobVsxXSA9PT0gMCAmJiBtWzJdID09PSAwKSB7XG4gICAgICAgIHRoaXMuX2NhY2hlZEdldFNpbmdsZVBpeGVsV2lkdGggPSAxIC8gTWF0aC5taW4oTWF0aC5hYnMobVswXSksIE1hdGguYWJzKG1bM10pKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGFic0RldCA9IE1hdGguYWJzKG1bMF0gKiBtWzNdIC0gbVsyXSAqIG1bMV0pO1xuICAgICAgICBjb25zdCBub3JtWCA9IE1hdGguaHlwb3QobVswXSwgbVsyXSk7XG4gICAgICAgIGNvbnN0IG5vcm1ZID0gTWF0aC5oeXBvdChtWzFdLCBtWzNdKTtcbiAgICAgICAgdGhpcy5fY2FjaGVkR2V0U2luZ2xlUGl4ZWxXaWR0aCA9IE1hdGgubWF4KG5vcm1YLCBub3JtWSkgLyBhYnNEZXQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2NhY2hlZEdldFNpbmdsZVBpeGVsV2lkdGg7XG4gIH1cblxuICBnZXRTY2FsZUZvclN0cm9raW5nKCkge1xuICAgIGlmICghdGhpcy5fY2FjaGVkU2NhbGVGb3JTdHJva2luZykge1xuICAgICAgY29uc3Qge1xuICAgICAgICBsaW5lV2lkdGhcbiAgICAgIH0gPSB0aGlzLmN1cnJlbnQ7XG4gICAgICBjb25zdCBtID0gdGhpcy5jdHgubW96Q3VycmVudFRyYW5zZm9ybTtcbiAgICAgIGxldCBzY2FsZVgsIHNjYWxlWTtcblxuICAgICAgaWYgKG1bMV0gPT09IDAgJiYgbVsyXSA9PT0gMCkge1xuICAgICAgICBjb25zdCBub3JtWCA9IE1hdGguYWJzKG1bMF0pO1xuICAgICAgICBjb25zdCBub3JtWSA9IE1hdGguYWJzKG1bM10pO1xuXG4gICAgICAgIGlmIChsaW5lV2lkdGggPT09IDApIHtcbiAgICAgICAgICBzY2FsZVggPSAxIC8gbm9ybVg7XG4gICAgICAgICAgc2NhbGVZID0gMSAvIG5vcm1ZO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IHNjYWxlZFhMaW5lV2lkdGggPSBub3JtWCAqIGxpbmVXaWR0aDtcbiAgICAgICAgICBjb25zdCBzY2FsZWRZTGluZVdpZHRoID0gbm9ybVkgKiBsaW5lV2lkdGg7XG4gICAgICAgICAgc2NhbGVYID0gc2NhbGVkWExpbmVXaWR0aCA8IDEgPyAxIC8gc2NhbGVkWExpbmVXaWR0aCA6IDE7XG4gICAgICAgICAgc2NhbGVZID0gc2NhbGVkWUxpbmVXaWR0aCA8IDEgPyAxIC8gc2NhbGVkWUxpbmVXaWR0aCA6IDE7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGFic0RldCA9IE1hdGguYWJzKG1bMF0gKiBtWzNdIC0gbVsyXSAqIG1bMV0pO1xuICAgICAgICBjb25zdCBub3JtWCA9IE1hdGguaHlwb3QobVswXSwgbVsxXSk7XG4gICAgICAgIGNvbnN0IG5vcm1ZID0gTWF0aC5oeXBvdChtWzJdLCBtWzNdKTtcblxuICAgICAgICBpZiAobGluZVdpZHRoID09PSAwKSB7XG4gICAgICAgICAgc2NhbGVYID0gbm9ybVkgLyBhYnNEZXQ7XG4gICAgICAgICAgc2NhbGVZID0gbm9ybVggLyBhYnNEZXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgYmFzZUFyZWEgPSBsaW5lV2lkdGggKiBhYnNEZXQ7XG4gICAgICAgICAgc2NhbGVYID0gbm9ybVkgPiBiYXNlQXJlYSA/IG5vcm1ZIC8gYmFzZUFyZWEgOiAxO1xuICAgICAgICAgIHNjYWxlWSA9IG5vcm1YID4gYmFzZUFyZWEgPyBub3JtWCAvIGJhc2VBcmVhIDogMTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLl9jYWNoZWRTY2FsZUZvclN0cm9raW5nID0gW3NjYWxlWCwgc2NhbGVZXTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fY2FjaGVkU2NhbGVGb3JTdHJva2luZztcbiAgfVxuXG4gIHJlc2NhbGVBbmRTdHJva2Uoc2F2ZVJlc3RvcmUpIHtcbiAgICBjb25zdCB7XG4gICAgICBjdHhcbiAgICB9ID0gdGhpcztcbiAgICBjb25zdCB7XG4gICAgICBsaW5lV2lkdGhcbiAgICB9ID0gdGhpcy5jdXJyZW50O1xuICAgIGNvbnN0IFtzY2FsZVgsIHNjYWxlWV0gPSB0aGlzLmdldFNjYWxlRm9yU3Ryb2tpbmcoKTtcbiAgICBjdHgubGluZVdpZHRoID0gbGluZVdpZHRoIHx8IDE7XG5cbiAgICBpZiAoc2NhbGVYID09PSAxICYmIHNjYWxlWSA9PT0gMSkge1xuICAgICAgY3R4LnN0cm9rZSgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBzYXZlZE1hdHJpeCwgc2F2ZWREYXNoZXMsIHNhdmVkRGFzaE9mZnNldDtcblxuICAgIGlmIChzYXZlUmVzdG9yZSkge1xuICAgICAgc2F2ZWRNYXRyaXggPSBjdHgubW96Q3VycmVudFRyYW5zZm9ybS5zbGljZSgpO1xuICAgICAgc2F2ZWREYXNoZXMgPSBjdHguZ2V0TGluZURhc2goKS5zbGljZSgpO1xuICAgICAgc2F2ZWREYXNoT2Zmc2V0ID0gY3R4LmxpbmVEYXNoT2Zmc2V0O1xuICAgIH1cblxuICAgIGN0eC5zY2FsZShzY2FsZVgsIHNjYWxlWSk7XG4gICAgY29uc3Qgc2NhbGUgPSBNYXRoLm1heChzY2FsZVgsIHNjYWxlWSk7XG4gICAgY3R4LnNldExpbmVEYXNoKGN0eC5nZXRMaW5lRGFzaCgpLm1hcCh4ID0+IHggLyBzY2FsZSkpO1xuICAgIGN0eC5saW5lRGFzaE9mZnNldCAvPSBzY2FsZTtcbiAgICBjdHguc3Ryb2tlKCk7XG5cbiAgICBpZiAoc2F2ZVJlc3RvcmUpIHtcbiAgICAgIGN0eC5zZXRUcmFuc2Zvcm0oLi4uc2F2ZWRNYXRyaXgpO1xuICAgICAgY3R4LnNldExpbmVEYXNoKHNhdmVkRGFzaGVzKTtcbiAgICAgIGN0eC5saW5lRGFzaE9mZnNldCA9IHNhdmVkRGFzaE9mZnNldDtcbiAgICB9XG4gIH1cblxuICBnZXRDYW52YXNQb3NpdGlvbih4LCB5KSB7XG4gICAgY29uc3QgdHJhbnNmb3JtID0gdGhpcy5jdHgubW96Q3VycmVudFRyYW5zZm9ybTtcbiAgICByZXR1cm4gW3RyYW5zZm9ybVswXSAqIHggKyB0cmFuc2Zvcm1bMl0gKiB5ICsgdHJhbnNmb3JtWzRdLCB0cmFuc2Zvcm1bMV0gKiB4ICsgdHJhbnNmb3JtWzNdICogeSArIHRyYW5zZm9ybVs1XV07XG4gIH1cblxuICBpc0NvbnRlbnRWaXNpYmxlKCkge1xuICAgIGZvciAobGV0IGkgPSB0aGlzLm1hcmtlZENvbnRlbnRTdGFjay5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgaWYgKCF0aGlzLm1hcmtlZENvbnRlbnRTdGFja1tpXS52aXNpYmxlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG59XG5cbmV4cG9ydHMuQ2FudmFzR3JhcGhpY3MgPSBDYW52YXNHcmFwaGljcztcblxuZm9yIChjb25zdCBvcCBpbiBfdXRpbC5PUFMpIHtcbiAgaWYgKENhbnZhc0dyYXBoaWNzLnByb3RvdHlwZVtvcF0gIT09IHVuZGVmaW5lZCkge1xuICAgIENhbnZhc0dyYXBoaWNzLnByb3RvdHlwZVtfdXRpbC5PUFNbb3BdXSA9IENhbnZhc0dyYXBoaWNzLnByb3RvdHlwZVtvcF07XG4gIH1cbn1cblxuLyoqKi8gfSksXG4vKiAxMSAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5UaWxpbmdQYXR0ZXJuID0gZXhwb3J0cy5QYXRoVHlwZSA9IHZvaWQgMDtcbmV4cG9ydHMuZ2V0U2hhZGluZ1BhdHRlcm4gPSBnZXRTaGFkaW5nUGF0dGVybjtcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxudmFyIF9pc19ub2RlID0gX193X3BkZmpzX3JlcXVpcmVfXygzKTtcblxuY29uc3QgUGF0aFR5cGUgPSB7XG4gIEZJTEw6IFwiRmlsbFwiLFxuICBTVFJPS0U6IFwiU3Ryb2tlXCIsXG4gIFNIQURJTkc6IFwiU2hhZGluZ1wiXG59O1xuZXhwb3J0cy5QYXRoVHlwZSA9IFBhdGhUeXBlO1xuXG5mdW5jdGlvbiBhcHBseUJvdW5kaW5nQm94KGN0eCwgYmJveCkge1xuICBpZiAoIWJib3ggfHwgX2lzX25vZGUuaXNOb2RlSlMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCB3aWR0aCA9IGJib3hbMl0gLSBiYm94WzBdO1xuICBjb25zdCBoZWlnaHQgPSBiYm94WzNdIC0gYmJveFsxXTtcbiAgY29uc3QgcmVnaW9uID0gbmV3IFBhdGgyRCgpO1xuICByZWdpb24ucmVjdChiYm94WzBdLCBiYm94WzFdLCB3aWR0aCwgaGVpZ2h0KTtcbiAgY3R4LmNsaXAocmVnaW9uKTtcbn1cblxuY2xhc3MgQmFzZVNoYWRpbmdQYXR0ZXJuIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgaWYgKHRoaXMuY29uc3RydWN0b3IgPT09IEJhc2VTaGFkaW5nUGF0dGVybikge1xuICAgICAgKDAsIF91dGlsLnVucmVhY2hhYmxlKShcIkNhbm5vdCBpbml0aWFsaXplIEJhc2VTaGFkaW5nUGF0dGVybi5cIik7XG4gICAgfVxuICB9XG5cbiAgZ2V0UGF0dGVybigpIHtcbiAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiQWJzdHJhY3QgbWV0aG9kIGBnZXRQYXR0ZXJuYCBjYWxsZWQuXCIpO1xuICB9XG5cbn1cblxuY2xhc3MgUmFkaWFsQXhpYWxTaGFkaW5nUGF0dGVybiBleHRlbmRzIEJhc2VTaGFkaW5nUGF0dGVybiB7XG4gIGNvbnN0cnVjdG9yKElSKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLl90eXBlID0gSVJbMV07XG4gICAgdGhpcy5fYmJveCA9IElSWzJdO1xuICAgIHRoaXMuX2NvbG9yU3RvcHMgPSBJUlszXTtcbiAgICB0aGlzLl9wMCA9IElSWzRdO1xuICAgIHRoaXMuX3AxID0gSVJbNV07XG4gICAgdGhpcy5fcjAgPSBJUls2XTtcbiAgICB0aGlzLl9yMSA9IElSWzddO1xuICAgIHRoaXMubWF0cml4ID0gbnVsbDtcbiAgfVxuXG4gIF9jcmVhdGVHcmFkaWVudChjdHgpIHtcbiAgICBsZXQgZ3JhZDtcblxuICAgIGlmICh0aGlzLl90eXBlID09PSBcImF4aWFsXCIpIHtcbiAgICAgIGdyYWQgPSBjdHguY3JlYXRlTGluZWFyR3JhZGllbnQodGhpcy5fcDBbMF0sIHRoaXMuX3AwWzFdLCB0aGlzLl9wMVswXSwgdGhpcy5fcDFbMV0pO1xuICAgIH0gZWxzZSBpZiAodGhpcy5fdHlwZSA9PT0gXCJyYWRpYWxcIikge1xuICAgICAgZ3JhZCA9IGN0eC5jcmVhdGVSYWRpYWxHcmFkaWVudCh0aGlzLl9wMFswXSwgdGhpcy5fcDBbMV0sIHRoaXMuX3IwLCB0aGlzLl9wMVswXSwgdGhpcy5fcDFbMV0sIHRoaXMuX3IxKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGNvbG9yU3RvcCBvZiB0aGlzLl9jb2xvclN0b3BzKSB7XG4gICAgICBncmFkLmFkZENvbG9yU3RvcChjb2xvclN0b3BbMF0sIGNvbG9yU3RvcFsxXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGdyYWQ7XG4gIH1cblxuICBnZXRQYXR0ZXJuKGN0eCwgb3duZXIsIGludmVyc2UsIHBhdGhUeXBlKSB7XG4gICAgbGV0IHBhdHRlcm47XG5cbiAgICBpZiAocGF0aFR5cGUgPT09IFBhdGhUeXBlLlNUUk9LRSB8fCBwYXRoVHlwZSA9PT0gUGF0aFR5cGUuRklMTCkge1xuICAgICAgY29uc3Qgb3duZXJCQm94ID0gb3duZXIuY3VycmVudC5nZXRDbGlwcGVkUGF0aEJvdW5kaW5nQm94KHBhdGhUeXBlLCBjdHgubW96Q3VycmVudFRyYW5zZm9ybSkgfHwgWzAsIDAsIDAsIDBdO1xuICAgICAgY29uc3Qgd2lkdGggPSBNYXRoLmNlaWwob3duZXJCQm94WzJdIC0gb3duZXJCQm94WzBdKSB8fCAxO1xuICAgICAgY29uc3QgaGVpZ2h0ID0gTWF0aC5jZWlsKG93bmVyQkJveFszXSAtIG93bmVyQkJveFsxXSkgfHwgMTtcbiAgICAgIGNvbnN0IHRtcENhbnZhcyA9IG93bmVyLmNhY2hlZENhbnZhc2VzLmdldENhbnZhcyhcInBhdHRlcm5cIiwgd2lkdGgsIGhlaWdodCwgdHJ1ZSk7XG4gICAgICBjb25zdCB0bXBDdHggPSB0bXBDYW52YXMuY29udGV4dDtcbiAgICAgIHRtcEN0eC5jbGVhclJlY3QoMCwgMCwgdG1wQ3R4LmNhbnZhcy53aWR0aCwgdG1wQ3R4LmNhbnZhcy5oZWlnaHQpO1xuICAgICAgdG1wQ3R4LmJlZ2luUGF0aCgpO1xuICAgICAgdG1wQ3R4LnJlY3QoMCwgMCwgdG1wQ3R4LmNhbnZhcy53aWR0aCwgdG1wQ3R4LmNhbnZhcy5oZWlnaHQpO1xuICAgICAgdG1wQ3R4LnRyYW5zbGF0ZSgtb3duZXJCQm94WzBdLCAtb3duZXJCQm94WzFdKTtcbiAgICAgIGludmVyc2UgPSBfdXRpbC5VdGlsLnRyYW5zZm9ybShpbnZlcnNlLCBbMSwgMCwgMCwgMSwgb3duZXJCQm94WzBdLCBvd25lckJCb3hbMV1dKTtcbiAgICAgIHRtcEN0eC50cmFuc2Zvcm0uYXBwbHkodG1wQ3R4LCBvd25lci5iYXNlVHJhbnNmb3JtKTtcblxuICAgICAgaWYgKHRoaXMubWF0cml4KSB7XG4gICAgICAgIHRtcEN0eC50cmFuc2Zvcm0uYXBwbHkodG1wQ3R4LCB0aGlzLm1hdHJpeCk7XG4gICAgICB9XG5cbiAgICAgIGFwcGx5Qm91bmRpbmdCb3godG1wQ3R4LCB0aGlzLl9iYm94KTtcbiAgICAgIHRtcEN0eC5maWxsU3R5bGUgPSB0aGlzLl9jcmVhdGVHcmFkaWVudCh0bXBDdHgpO1xuICAgICAgdG1wQ3R4LmZpbGwoKTtcbiAgICAgIHBhdHRlcm4gPSBjdHguY3JlYXRlUGF0dGVybih0bXBDYW52YXMuY2FudmFzLCBcIm5vLXJlcGVhdFwiKTtcbiAgICAgIGNvbnN0IGRvbU1hdHJpeCA9IG5ldyBET01NYXRyaXgoaW52ZXJzZSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHBhdHRlcm4uc2V0VHJhbnNmb3JtKGRvbU1hdHJpeCk7XG4gICAgICB9IGNhdGNoIChleCkge1xuICAgICAgICAoMCwgX3V0aWwud2FybikoYFJhZGlhbEF4aWFsU2hhZGluZ1BhdHRlcm4uZ2V0UGF0dGVybjogXCIke2V4Py5tZXNzYWdlfVwiLmApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBhcHBseUJvdW5kaW5nQm94KGN0eCwgdGhpcy5fYmJveCk7XG4gICAgICBwYXR0ZXJuID0gdGhpcy5fY3JlYXRlR3JhZGllbnQoY3R4KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGF0dGVybjtcbiAgfVxuXG59XG5cbmZ1bmN0aW9uIGRyYXdUcmlhbmdsZShkYXRhLCBjb250ZXh0LCBwMSwgcDIsIHAzLCBjMSwgYzIsIGMzKSB7XG4gIGNvbnN0IGNvb3JkcyA9IGNvbnRleHQuY29vcmRzLFxuICAgICAgICBjb2xvcnMgPSBjb250ZXh0LmNvbG9ycztcbiAgY29uc3QgYnl0ZXMgPSBkYXRhLmRhdGEsXG4gICAgICAgIHJvd1NpemUgPSBkYXRhLndpZHRoICogNDtcbiAgbGV0IHRtcDtcblxuICBpZiAoY29vcmRzW3AxICsgMV0gPiBjb29yZHNbcDIgKyAxXSkge1xuICAgIHRtcCA9IHAxO1xuICAgIHAxID0gcDI7XG4gICAgcDIgPSB0bXA7XG4gICAgdG1wID0gYzE7XG4gICAgYzEgPSBjMjtcbiAgICBjMiA9IHRtcDtcbiAgfVxuXG4gIGlmIChjb29yZHNbcDIgKyAxXSA+IGNvb3Jkc1twMyArIDFdKSB7XG4gICAgdG1wID0gcDI7XG4gICAgcDIgPSBwMztcbiAgICBwMyA9IHRtcDtcbiAgICB0bXAgPSBjMjtcbiAgICBjMiA9IGMzO1xuICAgIGMzID0gdG1wO1xuICB9XG5cbiAgaWYgKGNvb3Jkc1twMSArIDFdID4gY29vcmRzW3AyICsgMV0pIHtcbiAgICB0bXAgPSBwMTtcbiAgICBwMSA9IHAyO1xuICAgIHAyID0gdG1wO1xuICAgIHRtcCA9IGMxO1xuICAgIGMxID0gYzI7XG4gICAgYzIgPSB0bXA7XG4gIH1cblxuICBjb25zdCB4MSA9IChjb29yZHNbcDFdICsgY29udGV4dC5vZmZzZXRYKSAqIGNvbnRleHQuc2NhbGVYO1xuICBjb25zdCB5MSA9IChjb29yZHNbcDEgKyAxXSArIGNvbnRleHQub2Zmc2V0WSkgKiBjb250ZXh0LnNjYWxlWTtcbiAgY29uc3QgeDIgPSAoY29vcmRzW3AyXSArIGNvbnRleHQub2Zmc2V0WCkgKiBjb250ZXh0LnNjYWxlWDtcbiAgY29uc3QgeTIgPSAoY29vcmRzW3AyICsgMV0gKyBjb250ZXh0Lm9mZnNldFkpICogY29udGV4dC5zY2FsZVk7XG4gIGNvbnN0IHgzID0gKGNvb3Jkc1twM10gKyBjb250ZXh0Lm9mZnNldFgpICogY29udGV4dC5zY2FsZVg7XG4gIGNvbnN0IHkzID0gKGNvb3Jkc1twMyArIDFdICsgY29udGV4dC5vZmZzZXRZKSAqIGNvbnRleHQuc2NhbGVZO1xuXG4gIGlmICh5MSA+PSB5Mykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGMxciA9IGNvbG9yc1tjMV0sXG4gICAgICAgIGMxZyA9IGNvbG9yc1tjMSArIDFdLFxuICAgICAgICBjMWIgPSBjb2xvcnNbYzEgKyAyXTtcbiAgY29uc3QgYzJyID0gY29sb3JzW2MyXSxcbiAgICAgICAgYzJnID0gY29sb3JzW2MyICsgMV0sXG4gICAgICAgIGMyYiA9IGNvbG9yc1tjMiArIDJdO1xuICBjb25zdCBjM3IgPSBjb2xvcnNbYzNdLFxuICAgICAgICBjM2cgPSBjb2xvcnNbYzMgKyAxXSxcbiAgICAgICAgYzNiID0gY29sb3JzW2MzICsgMl07XG4gIGNvbnN0IG1pblkgPSBNYXRoLnJvdW5kKHkxKSxcbiAgICAgICAgbWF4WSA9IE1hdGgucm91bmQoeTMpO1xuICBsZXQgeGEsIGNhciwgY2FnLCBjYWI7XG4gIGxldCB4YiwgY2JyLCBjYmcsIGNiYjtcblxuICBmb3IgKGxldCB5ID0gbWluWTsgeSA8PSBtYXhZOyB5KyspIHtcbiAgICBpZiAoeSA8IHkyKSB7XG4gICAgICBsZXQgaztcblxuICAgICAgaWYgKHkgPCB5MSkge1xuICAgICAgICBrID0gMDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGsgPSAoeTEgLSB5KSAvICh5MSAtIHkyKTtcbiAgICAgIH1cblxuICAgICAgeGEgPSB4MSAtICh4MSAtIHgyKSAqIGs7XG4gICAgICBjYXIgPSBjMXIgLSAoYzFyIC0gYzJyKSAqIGs7XG4gICAgICBjYWcgPSBjMWcgLSAoYzFnIC0gYzJnKSAqIGs7XG4gICAgICBjYWIgPSBjMWIgLSAoYzFiIC0gYzJiKSAqIGs7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBrO1xuXG4gICAgICBpZiAoeSA+IHkzKSB7XG4gICAgICAgIGsgPSAxO1xuICAgICAgfSBlbHNlIGlmICh5MiA9PT0geTMpIHtcbiAgICAgICAgayA9IDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBrID0gKHkyIC0geSkgLyAoeTIgLSB5Myk7XG4gICAgICB9XG5cbiAgICAgIHhhID0geDIgLSAoeDIgLSB4MykgKiBrO1xuICAgICAgY2FyID0gYzJyIC0gKGMyciAtIGMzcikgKiBrO1xuICAgICAgY2FnID0gYzJnIC0gKGMyZyAtIGMzZykgKiBrO1xuICAgICAgY2FiID0gYzJiIC0gKGMyYiAtIGMzYikgKiBrO1xuICAgIH1cblxuICAgIGxldCBrO1xuXG4gICAgaWYgKHkgPCB5MSkge1xuICAgICAgayA9IDA7XG4gICAgfSBlbHNlIGlmICh5ID4geTMpIHtcbiAgICAgIGsgPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBrID0gKHkxIC0geSkgLyAoeTEgLSB5Myk7XG4gICAgfVxuXG4gICAgeGIgPSB4MSAtICh4MSAtIHgzKSAqIGs7XG4gICAgY2JyID0gYzFyIC0gKGMxciAtIGMzcikgKiBrO1xuICAgIGNiZyA9IGMxZyAtIChjMWcgLSBjM2cpICogaztcbiAgICBjYmIgPSBjMWIgLSAoYzFiIC0gYzNiKSAqIGs7XG4gICAgY29uc3QgeDFfID0gTWF0aC5yb3VuZChNYXRoLm1pbih4YSwgeGIpKTtcbiAgICBjb25zdCB4Ml8gPSBNYXRoLnJvdW5kKE1hdGgubWF4KHhhLCB4YikpO1xuICAgIGxldCBqID0gcm93U2l6ZSAqIHkgKyB4MV8gKiA0O1xuXG4gICAgZm9yIChsZXQgeCA9IHgxXzsgeCA8PSB4Ml87IHgrKykge1xuICAgICAgayA9ICh4YSAtIHgpIC8gKHhhIC0geGIpO1xuXG4gICAgICBpZiAoayA8IDApIHtcbiAgICAgICAgayA9IDA7XG4gICAgICB9IGVsc2UgaWYgKGsgPiAxKSB7XG4gICAgICAgIGsgPSAxO1xuICAgICAgfVxuXG4gICAgICBieXRlc1tqKytdID0gY2FyIC0gKGNhciAtIGNicikgKiBrIHwgMDtcbiAgICAgIGJ5dGVzW2orK10gPSBjYWcgLSAoY2FnIC0gY2JnKSAqIGsgfCAwO1xuICAgICAgYnl0ZXNbaisrXSA9IGNhYiAtIChjYWIgLSBjYmIpICogayB8IDA7XG4gICAgICBieXRlc1tqKytdID0gMjU1O1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBkcmF3RmlndXJlKGRhdGEsIGZpZ3VyZSwgY29udGV4dCkge1xuICBjb25zdCBwcyA9IGZpZ3VyZS5jb29yZHM7XG4gIGNvbnN0IGNzID0gZmlndXJlLmNvbG9ycztcbiAgbGV0IGksIGlpO1xuXG4gIHN3aXRjaCAoZmlndXJlLnR5cGUpIHtcbiAgICBjYXNlIFwibGF0dGljZVwiOlxuICAgICAgY29uc3QgdmVydGljZXNQZXJSb3cgPSBmaWd1cmUudmVydGljZXNQZXJSb3c7XG4gICAgICBjb25zdCByb3dzID0gTWF0aC5mbG9vcihwcy5sZW5ndGggLyB2ZXJ0aWNlc1BlclJvdykgLSAxO1xuICAgICAgY29uc3QgY29scyA9IHZlcnRpY2VzUGVyUm93IC0gMTtcblxuICAgICAgZm9yIChpID0gMDsgaSA8IHJvd3M7IGkrKykge1xuICAgICAgICBsZXQgcSA9IGkgKiB2ZXJ0aWNlc1BlclJvdztcblxuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNvbHM7IGorKywgcSsrKSB7XG4gICAgICAgICAgZHJhd1RyaWFuZ2xlKGRhdGEsIGNvbnRleHQsIHBzW3FdLCBwc1txICsgMV0sIHBzW3EgKyB2ZXJ0aWNlc1BlclJvd10sIGNzW3FdLCBjc1txICsgMV0sIGNzW3EgKyB2ZXJ0aWNlc1BlclJvd10pO1xuICAgICAgICAgIGRyYXdUcmlhbmdsZShkYXRhLCBjb250ZXh0LCBwc1txICsgdmVydGljZXNQZXJSb3cgKyAxXSwgcHNbcSArIDFdLCBwc1txICsgdmVydGljZXNQZXJSb3ddLCBjc1txICsgdmVydGljZXNQZXJSb3cgKyAxXSwgY3NbcSArIDFdLCBjc1txICsgdmVydGljZXNQZXJSb3ddKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBicmVhaztcblxuICAgIGNhc2UgXCJ0cmlhbmdsZXNcIjpcbiAgICAgIGZvciAoaSA9IDAsIGlpID0gcHMubGVuZ3RoOyBpIDwgaWk7IGkgKz0gMykge1xuICAgICAgICBkcmF3VHJpYW5nbGUoZGF0YSwgY29udGV4dCwgcHNbaV0sIHBzW2kgKyAxXSwgcHNbaSArIDJdLCBjc1tpXSwgY3NbaSArIDFdLCBjc1tpICsgMl0pO1xuICAgICAgfVxuXG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJpbGxlZ2FsIGZpZ3VyZVwiKTtcbiAgfVxufVxuXG5jbGFzcyBNZXNoU2hhZGluZ1BhdHRlcm4gZXh0ZW5kcyBCYXNlU2hhZGluZ1BhdHRlcm4ge1xuICBjb25zdHJ1Y3RvcihJUikge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5fY29vcmRzID0gSVJbMl07XG4gICAgdGhpcy5fY29sb3JzID0gSVJbM107XG4gICAgdGhpcy5fZmlndXJlcyA9IElSWzRdO1xuICAgIHRoaXMuX2JvdW5kcyA9IElSWzVdO1xuICAgIHRoaXMuX2Jib3ggPSBJUls3XTtcbiAgICB0aGlzLl9iYWNrZ3JvdW5kID0gSVJbOF07XG4gICAgdGhpcy5tYXRyaXggPSBudWxsO1xuICB9XG5cbiAgX2NyZWF0ZU1lc2hDYW52YXMoY29tYmluZWRTY2FsZSwgYmFja2dyb3VuZENvbG9yLCBjYWNoZWRDYW52YXNlcykge1xuICAgIGNvbnN0IEVYUEVDVEVEX1NDQUxFID0gMS4xO1xuICAgIGNvbnN0IE1BWF9QQVRURVJOX1NJWkUgPSAzMDAwO1xuICAgIGNvbnN0IEJPUkRFUl9TSVpFID0gMjtcbiAgICBjb25zdCBvZmZzZXRYID0gTWF0aC5mbG9vcih0aGlzLl9ib3VuZHNbMF0pO1xuICAgIGNvbnN0IG9mZnNldFkgPSBNYXRoLmZsb29yKHRoaXMuX2JvdW5kc1sxXSk7XG4gICAgY29uc3QgYm91bmRzV2lkdGggPSBNYXRoLmNlaWwodGhpcy5fYm91bmRzWzJdKSAtIG9mZnNldFg7XG4gICAgY29uc3QgYm91bmRzSGVpZ2h0ID0gTWF0aC5jZWlsKHRoaXMuX2JvdW5kc1szXSkgLSBvZmZzZXRZO1xuICAgIGNvbnN0IHdpZHRoID0gTWF0aC5taW4oTWF0aC5jZWlsKE1hdGguYWJzKGJvdW5kc1dpZHRoICogY29tYmluZWRTY2FsZVswXSAqIEVYUEVDVEVEX1NDQUxFKSksIE1BWF9QQVRURVJOX1NJWkUpO1xuICAgIGNvbnN0IGhlaWdodCA9IE1hdGgubWluKE1hdGguY2VpbChNYXRoLmFicyhib3VuZHNIZWlnaHQgKiBjb21iaW5lZFNjYWxlWzFdICogRVhQRUNURURfU0NBTEUpKSwgTUFYX1BBVFRFUk5fU0laRSk7XG4gICAgY29uc3Qgc2NhbGVYID0gYm91bmRzV2lkdGggLyB3aWR0aDtcbiAgICBjb25zdCBzY2FsZVkgPSBib3VuZHNIZWlnaHQgLyBoZWlnaHQ7XG4gICAgY29uc3QgY29udGV4dCA9IHtcbiAgICAgIGNvb3JkczogdGhpcy5fY29vcmRzLFxuICAgICAgY29sb3JzOiB0aGlzLl9jb2xvcnMsXG4gICAgICBvZmZzZXRYOiAtb2Zmc2V0WCxcbiAgICAgIG9mZnNldFk6IC1vZmZzZXRZLFxuICAgICAgc2NhbGVYOiAxIC8gc2NhbGVYLFxuICAgICAgc2NhbGVZOiAxIC8gc2NhbGVZXG4gICAgfTtcbiAgICBjb25zdCBwYWRkZWRXaWR0aCA9IHdpZHRoICsgQk9SREVSX1NJWkUgKiAyO1xuICAgIGNvbnN0IHBhZGRlZEhlaWdodCA9IGhlaWdodCArIEJPUkRFUl9TSVpFICogMjtcbiAgICBjb25zdCB0bXBDYW52YXMgPSBjYWNoZWRDYW52YXNlcy5nZXRDYW52YXMoXCJtZXNoXCIsIHBhZGRlZFdpZHRoLCBwYWRkZWRIZWlnaHQsIGZhbHNlKTtcbiAgICBjb25zdCB0bXBDdHggPSB0bXBDYW52YXMuY29udGV4dDtcbiAgICBjb25zdCBkYXRhID0gdG1wQ3R4LmNyZWF0ZUltYWdlRGF0YSh3aWR0aCwgaGVpZ2h0KTtcblxuICAgIGlmIChiYWNrZ3JvdW5kQ29sb3IpIHtcbiAgICAgIGNvbnN0IGJ5dGVzID0gZGF0YS5kYXRhO1xuXG4gICAgICBmb3IgKGxldCBpID0gMCwgaWkgPSBieXRlcy5sZW5ndGg7IGkgPCBpaTsgaSArPSA0KSB7XG4gICAgICAgIGJ5dGVzW2ldID0gYmFja2dyb3VuZENvbG9yWzBdO1xuICAgICAgICBieXRlc1tpICsgMV0gPSBiYWNrZ3JvdW5kQ29sb3JbMV07XG4gICAgICAgIGJ5dGVzW2kgKyAyXSA9IGJhY2tncm91bmRDb2xvclsyXTtcbiAgICAgICAgYnl0ZXNbaSArIDNdID0gMjU1O1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZmlndXJlIG9mIHRoaXMuX2ZpZ3VyZXMpIHtcbiAgICAgIGRyYXdGaWd1cmUoZGF0YSwgZmlndXJlLCBjb250ZXh0KTtcbiAgICB9XG5cbiAgICB0bXBDdHgucHV0SW1hZ2VEYXRhKGRhdGEsIEJPUkRFUl9TSVpFLCBCT1JERVJfU0laRSk7XG4gICAgY29uc3QgY2FudmFzID0gdG1wQ2FudmFzLmNhbnZhcztcbiAgICByZXR1cm4ge1xuICAgICAgY2FudmFzLFxuICAgICAgb2Zmc2V0WDogb2Zmc2V0WCAtIEJPUkRFUl9TSVpFICogc2NhbGVYLFxuICAgICAgb2Zmc2V0WTogb2Zmc2V0WSAtIEJPUkRFUl9TSVpFICogc2NhbGVZLFxuICAgICAgc2NhbGVYLFxuICAgICAgc2NhbGVZXG4gICAgfTtcbiAgfVxuXG4gIGdldFBhdHRlcm4oY3R4LCBvd25lciwgaW52ZXJzZSwgcGF0aFR5cGUpIHtcbiAgICBhcHBseUJvdW5kaW5nQm94KGN0eCwgdGhpcy5fYmJveCk7XG4gICAgbGV0IHNjYWxlO1xuXG4gICAgaWYgKHBhdGhUeXBlID09PSBQYXRoVHlwZS5TSEFESU5HKSB7XG4gICAgICBzY2FsZSA9IF91dGlsLlV0aWwuc2luZ3VsYXJWYWx1ZURlY29tcG9zZTJkU2NhbGUoY3R4Lm1vekN1cnJlbnRUcmFuc2Zvcm0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2FsZSA9IF91dGlsLlV0aWwuc2luZ3VsYXJWYWx1ZURlY29tcG9zZTJkU2NhbGUob3duZXIuYmFzZVRyYW5zZm9ybSk7XG5cbiAgICAgIGlmICh0aGlzLm1hdHJpeCkge1xuICAgICAgICBjb25zdCBtYXRyaXhTY2FsZSA9IF91dGlsLlV0aWwuc2luZ3VsYXJWYWx1ZURlY29tcG9zZTJkU2NhbGUodGhpcy5tYXRyaXgpO1xuXG4gICAgICAgIHNjYWxlID0gW3NjYWxlWzBdICogbWF0cml4U2NhbGVbMF0sIHNjYWxlWzFdICogbWF0cml4U2NhbGVbMV1dO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHRlbXBvcmFyeVBhdHRlcm5DYW52YXMgPSB0aGlzLl9jcmVhdGVNZXNoQ2FudmFzKHNjYWxlLCBwYXRoVHlwZSA9PT0gUGF0aFR5cGUuU0hBRElORyA/IG51bGwgOiB0aGlzLl9iYWNrZ3JvdW5kLCBvd25lci5jYWNoZWRDYW52YXNlcyk7XG5cbiAgICBpZiAocGF0aFR5cGUgIT09IFBhdGhUeXBlLlNIQURJTkcpIHtcbiAgICAgIGN0eC5zZXRUcmFuc2Zvcm0uYXBwbHkoY3R4LCBvd25lci5iYXNlVHJhbnNmb3JtKTtcblxuICAgICAgaWYgKHRoaXMubWF0cml4KSB7XG4gICAgICAgIGN0eC50cmFuc2Zvcm0uYXBwbHkoY3R4LCB0aGlzLm1hdHJpeCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY3R4LnRyYW5zbGF0ZSh0ZW1wb3JhcnlQYXR0ZXJuQ2FudmFzLm9mZnNldFgsIHRlbXBvcmFyeVBhdHRlcm5DYW52YXMub2Zmc2V0WSk7XG4gICAgY3R4LnNjYWxlKHRlbXBvcmFyeVBhdHRlcm5DYW52YXMuc2NhbGVYLCB0ZW1wb3JhcnlQYXR0ZXJuQ2FudmFzLnNjYWxlWSk7XG4gICAgcmV0dXJuIGN0eC5jcmVhdGVQYXR0ZXJuKHRlbXBvcmFyeVBhdHRlcm5DYW52YXMuY2FudmFzLCBcIm5vLXJlcGVhdFwiKTtcbiAgfVxuXG59XG5cbmNsYXNzIER1bW15U2hhZGluZ1BhdHRlcm4gZXh0ZW5kcyBCYXNlU2hhZGluZ1BhdHRlcm4ge1xuICBnZXRQYXR0ZXJuKCkge1xuICAgIHJldHVybiBcImhvdHBpbmtcIjtcbiAgfVxuXG59XG5cbmZ1bmN0aW9uIGdldFNoYWRpbmdQYXR0ZXJuKElSKSB7XG4gIHN3aXRjaCAoSVJbMF0pIHtcbiAgICBjYXNlIFwiUmFkaWFsQXhpYWxcIjpcbiAgICAgIHJldHVybiBuZXcgUmFkaWFsQXhpYWxTaGFkaW5nUGF0dGVybihJUik7XG5cbiAgICBjYXNlIFwiTWVzaFwiOlxuICAgICAgcmV0dXJuIG5ldyBNZXNoU2hhZGluZ1BhdHRlcm4oSVIpO1xuXG4gICAgY2FzZSBcIkR1bW15XCI6XG4gICAgICByZXR1cm4gbmV3IER1bW15U2hhZGluZ1BhdHRlcm4oKTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBJUiB0eXBlOiAke0lSWzBdfWApO1xufVxuXG5jb25zdCBQYWludFR5cGUgPSB7XG4gIENPTE9SRUQ6IDEsXG4gIFVOQ09MT1JFRDogMlxufTtcblxuY2xhc3MgVGlsaW5nUGF0dGVybiB7XG4gIHN0YXRpYyBnZXQgTUFYX1BBVFRFUk5fU0laRSgpIHtcbiAgICByZXR1cm4gKDAsIF91dGlsLnNoYWRvdykodGhpcywgXCJNQVhfUEFUVEVSTl9TSVpFXCIsIDMwMDApO1xuICB9XG5cbiAgY29uc3RydWN0b3IoSVIsIGNvbG9yLCBjdHgsIGNhbnZhc0dyYXBoaWNzRmFjdG9yeSwgYmFzZVRyYW5zZm9ybSkge1xuICAgIHRoaXMub3BlcmF0b3JMaXN0ID0gSVJbMl07XG4gICAgdGhpcy5tYXRyaXggPSBJUlszXSB8fCBbMSwgMCwgMCwgMSwgMCwgMF07XG4gICAgdGhpcy5iYm94ID0gSVJbNF07XG4gICAgdGhpcy54c3RlcCA9IElSWzVdO1xuICAgIHRoaXMueXN0ZXAgPSBJUls2XTtcbiAgICB0aGlzLnBhaW50VHlwZSA9IElSWzddO1xuICAgIHRoaXMudGlsaW5nVHlwZSA9IElSWzhdO1xuICAgIHRoaXMuY29sb3IgPSBjb2xvcjtcbiAgICB0aGlzLmN0eCA9IGN0eDtcbiAgICB0aGlzLmNhbnZhc0dyYXBoaWNzRmFjdG9yeSA9IGNhbnZhc0dyYXBoaWNzRmFjdG9yeTtcbiAgICB0aGlzLmJhc2VUcmFuc2Zvcm0gPSBiYXNlVHJhbnNmb3JtO1xuICB9XG5cbiAgY3JlYXRlUGF0dGVybkNhbnZhcyhvd25lcikge1xuICAgIGNvbnN0IG9wZXJhdG9yTGlzdCA9IHRoaXMub3BlcmF0b3JMaXN0O1xuICAgIGNvbnN0IGJib3ggPSB0aGlzLmJib3g7XG4gICAgY29uc3QgeHN0ZXAgPSB0aGlzLnhzdGVwO1xuICAgIGNvbnN0IHlzdGVwID0gdGhpcy55c3RlcDtcbiAgICBjb25zdCBwYWludFR5cGUgPSB0aGlzLnBhaW50VHlwZTtcbiAgICBjb25zdCB0aWxpbmdUeXBlID0gdGhpcy50aWxpbmdUeXBlO1xuICAgIGNvbnN0IGNvbG9yID0gdGhpcy5jb2xvcjtcbiAgICBjb25zdCBjYW52YXNHcmFwaGljc0ZhY3RvcnkgPSB0aGlzLmNhbnZhc0dyYXBoaWNzRmFjdG9yeTtcbiAgICAoMCwgX3V0aWwuaW5mbykoXCJUaWxpbmdUeXBlOiBcIiArIHRpbGluZ1R5cGUpO1xuICAgIGNvbnN0IHgwID0gYmJveFswXSxcbiAgICAgICAgICB5MCA9IGJib3hbMV0sXG4gICAgICAgICAgeDEgPSBiYm94WzJdLFxuICAgICAgICAgIHkxID0gYmJveFszXTtcblxuICAgIGNvbnN0IG1hdHJpeFNjYWxlID0gX3V0aWwuVXRpbC5zaW5ndWxhclZhbHVlRGVjb21wb3NlMmRTY2FsZSh0aGlzLm1hdHJpeCk7XG5cbiAgICBjb25zdCBjdXJNYXRyaXhTY2FsZSA9IF91dGlsLlV0aWwuc2luZ3VsYXJWYWx1ZURlY29tcG9zZTJkU2NhbGUodGhpcy5iYXNlVHJhbnNmb3JtKTtcblxuICAgIGNvbnN0IGNvbWJpbmVkU2NhbGUgPSBbbWF0cml4U2NhbGVbMF0gKiBjdXJNYXRyaXhTY2FsZVswXSwgbWF0cml4U2NhbGVbMV0gKiBjdXJNYXRyaXhTY2FsZVsxXV07XG4gICAgY29uc3QgZGlteCA9IHRoaXMuZ2V0U2l6ZUFuZFNjYWxlKHhzdGVwLCB0aGlzLmN0eC5jYW52YXMud2lkdGgsIGNvbWJpbmVkU2NhbGVbMF0pO1xuICAgIGNvbnN0IGRpbXkgPSB0aGlzLmdldFNpemVBbmRTY2FsZSh5c3RlcCwgdGhpcy5jdHguY2FudmFzLmhlaWdodCwgY29tYmluZWRTY2FsZVsxXSk7XG4gICAgY29uc3QgdG1wQ2FudmFzID0gb3duZXIuY2FjaGVkQ2FudmFzZXMuZ2V0Q2FudmFzKFwicGF0dGVyblwiLCBkaW14LnNpemUsIGRpbXkuc2l6ZSwgdHJ1ZSk7XG4gICAgY29uc3QgdG1wQ3R4ID0gdG1wQ2FudmFzLmNvbnRleHQ7XG4gICAgY29uc3QgZ3JhcGhpY3MgPSBjYW52YXNHcmFwaGljc0ZhY3RvcnkuY3JlYXRlQ2FudmFzR3JhcGhpY3ModG1wQ3R4KTtcbiAgICBncmFwaGljcy5ncm91cExldmVsID0gb3duZXIuZ3JvdXBMZXZlbDtcbiAgICB0aGlzLnNldEZpbGxBbmRTdHJva2VTdHlsZVRvQ29udGV4dChncmFwaGljcywgcGFpbnRUeXBlLCBjb2xvcik7XG4gICAgbGV0IGFkanVzdGVkWDAgPSB4MDtcbiAgICBsZXQgYWRqdXN0ZWRZMCA9IHkwO1xuICAgIGxldCBhZGp1c3RlZFgxID0geDE7XG4gICAgbGV0IGFkanVzdGVkWTEgPSB5MTtcblxuICAgIGlmICh4MCA8IDApIHtcbiAgICAgIGFkanVzdGVkWDAgPSAwO1xuICAgICAgYWRqdXN0ZWRYMSArPSBNYXRoLmFicyh4MCk7XG4gICAgfVxuXG4gICAgaWYgKHkwIDwgMCkge1xuICAgICAgYWRqdXN0ZWRZMCA9IDA7XG4gICAgICBhZGp1c3RlZFkxICs9IE1hdGguYWJzKHkwKTtcbiAgICB9XG5cbiAgICB0bXBDdHgudHJhbnNsYXRlKC0oZGlteC5zY2FsZSAqIGFkanVzdGVkWDApLCAtKGRpbXkuc2NhbGUgKiBhZGp1c3RlZFkwKSk7XG4gICAgZ3JhcGhpY3MudHJhbnNmb3JtKGRpbXguc2NhbGUsIDAsIDAsIGRpbXkuc2NhbGUsIDAsIDApO1xuICAgIHRtcEN0eC5zYXZlKCk7XG4gICAgdGhpcy5jbGlwQmJveChncmFwaGljcywgYWRqdXN0ZWRYMCwgYWRqdXN0ZWRZMCwgYWRqdXN0ZWRYMSwgYWRqdXN0ZWRZMSk7XG4gICAgZ3JhcGhpY3MuYmFzZVRyYW5zZm9ybSA9IGdyYXBoaWNzLmN0eC5tb3pDdXJyZW50VHJhbnNmb3JtLnNsaWNlKCk7XG4gICAgZ3JhcGhpY3MuZXhlY3V0ZU9wZXJhdG9yTGlzdChvcGVyYXRvckxpc3QpO1xuICAgIGdyYXBoaWNzLmVuZERyYXdpbmcoKTtcbiAgICByZXR1cm4ge1xuICAgICAgY2FudmFzOiB0bXBDYW52YXMuY2FudmFzLFxuICAgICAgc2NhbGVYOiBkaW14LnNjYWxlLFxuICAgICAgc2NhbGVZOiBkaW15LnNjYWxlLFxuICAgICAgb2Zmc2V0WDogYWRqdXN0ZWRYMCxcbiAgICAgIG9mZnNldFk6IGFkanVzdGVkWTBcbiAgICB9O1xuICB9XG5cbiAgZ2V0U2l6ZUFuZFNjYWxlKHN0ZXAsIHJlYWxPdXRwdXRTaXplLCBzY2FsZSkge1xuICAgIHN0ZXAgPSBNYXRoLmFicyhzdGVwKTtcbiAgICBjb25zdCBtYXhTaXplID0gTWF0aC5tYXgoVGlsaW5nUGF0dGVybi5NQVhfUEFUVEVSTl9TSVpFLCByZWFsT3V0cHV0U2l6ZSk7XG4gICAgbGV0IHNpemUgPSBNYXRoLmNlaWwoc3RlcCAqIHNjYWxlKTtcblxuICAgIGlmIChzaXplID49IG1heFNpemUpIHtcbiAgICAgIHNpemUgPSBtYXhTaXplO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2FsZSA9IHNpemUgLyBzdGVwO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBzY2FsZSxcbiAgICAgIHNpemVcbiAgICB9O1xuICB9XG5cbiAgY2xpcEJib3goZ3JhcGhpY3MsIHgwLCB5MCwgeDEsIHkxKSB7XG4gICAgY29uc3QgYmJveFdpZHRoID0geDEgLSB4MDtcbiAgICBjb25zdCBiYm94SGVpZ2h0ID0geTEgLSB5MDtcbiAgICBncmFwaGljcy5jdHgucmVjdCh4MCwgeTAsIGJib3hXaWR0aCwgYmJveEhlaWdodCk7XG4gICAgZ3JhcGhpY3MuY3VycmVudC51cGRhdGVSZWN0TWluTWF4KGdyYXBoaWNzLmN0eC5tb3pDdXJyZW50VHJhbnNmb3JtLCBbeDAsIHkwLCB4MSwgeTFdKTtcbiAgICBncmFwaGljcy5jbGlwKCk7XG4gICAgZ3JhcGhpY3MuZW5kUGF0aCgpO1xuICB9XG5cbiAgc2V0RmlsbEFuZFN0cm9rZVN0eWxlVG9Db250ZXh0KGdyYXBoaWNzLCBwYWludFR5cGUsIGNvbG9yKSB7XG4gICAgY29uc3QgY29udGV4dCA9IGdyYXBoaWNzLmN0eCxcbiAgICAgICAgICBjdXJyZW50ID0gZ3JhcGhpY3MuY3VycmVudDtcblxuICAgIHN3aXRjaCAocGFpbnRUeXBlKSB7XG4gICAgICBjYXNlIFBhaW50VHlwZS5DT0xPUkVEOlxuICAgICAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcbiAgICAgICAgY29udGV4dC5maWxsU3R5bGUgPSBjdHguZmlsbFN0eWxlO1xuICAgICAgICBjb250ZXh0LnN0cm9rZVN0eWxlID0gY3R4LnN0cm9rZVN0eWxlO1xuICAgICAgICBjdXJyZW50LmZpbGxDb2xvciA9IGN0eC5maWxsU3R5bGU7XG4gICAgICAgIGN1cnJlbnQuc3Ryb2tlQ29sb3IgPSBjdHguc3Ryb2tlU3R5bGU7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIFBhaW50VHlwZS5VTkNPTE9SRUQ6XG4gICAgICAgIGNvbnN0IGNzc0NvbG9yID0gX3V0aWwuVXRpbC5tYWtlSGV4Q29sb3IoY29sb3JbMF0sIGNvbG9yWzFdLCBjb2xvclsyXSk7XG5cbiAgICAgICAgY29udGV4dC5maWxsU3R5bGUgPSBjc3NDb2xvcjtcbiAgICAgICAgY29udGV4dC5zdHJva2VTdHlsZSA9IGNzc0NvbG9yO1xuICAgICAgICBjdXJyZW50LmZpbGxDb2xvciA9IGNzc0NvbG9yO1xuICAgICAgICBjdXJyZW50LnN0cm9rZUNvbG9yID0gY3NzQ29sb3I7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgX3V0aWwuRm9ybWF0RXJyb3IoYFVuc3VwcG9ydGVkIHBhaW50IHR5cGU6ICR7cGFpbnRUeXBlfWApO1xuICAgIH1cbiAgfVxuXG4gIGdldFBhdHRlcm4oY3R4LCBvd25lciwgaW52ZXJzZSwgcGF0aFR5cGUpIHtcbiAgICBsZXQgbWF0cml4ID0gaW52ZXJzZTtcblxuICAgIGlmIChwYXRoVHlwZSAhPT0gUGF0aFR5cGUuU0hBRElORykge1xuICAgICAgbWF0cml4ID0gX3V0aWwuVXRpbC50cmFuc2Zvcm0obWF0cml4LCBvd25lci5iYXNlVHJhbnNmb3JtKTtcblxuICAgICAgaWYgKHRoaXMubWF0cml4KSB7XG4gICAgICAgIG1hdHJpeCA9IF91dGlsLlV0aWwudHJhbnNmb3JtKG1hdHJpeCwgdGhpcy5tYXRyaXgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHRlbXBvcmFyeVBhdHRlcm5DYW52YXMgPSB0aGlzLmNyZWF0ZVBhdHRlcm5DYW52YXMob3duZXIpO1xuICAgIGxldCBkb21NYXRyaXggPSBuZXcgRE9NTWF0cml4KG1hdHJpeCk7XG4gICAgZG9tTWF0cml4ID0gZG9tTWF0cml4LnRyYW5zbGF0ZSh0ZW1wb3JhcnlQYXR0ZXJuQ2FudmFzLm9mZnNldFgsIHRlbXBvcmFyeVBhdHRlcm5DYW52YXMub2Zmc2V0WSk7XG4gICAgZG9tTWF0cml4ID0gZG9tTWF0cml4LnNjYWxlKDEgLyB0ZW1wb3JhcnlQYXR0ZXJuQ2FudmFzLnNjYWxlWCwgMSAvIHRlbXBvcmFyeVBhdHRlcm5DYW52YXMuc2NhbGVZKTtcbiAgICBjb25zdCBwYXR0ZXJuID0gY3R4LmNyZWF0ZVBhdHRlcm4odGVtcG9yYXJ5UGF0dGVybkNhbnZhcy5jYW52YXMsIFwicmVwZWF0XCIpO1xuXG4gICAgdHJ5IHtcbiAgICAgIHBhdHRlcm4uc2V0VHJhbnNmb3JtKGRvbU1hdHJpeCk7XG4gICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgICgwLCBfdXRpbC53YXJuKShgVGlsaW5nUGF0dGVybi5nZXRQYXR0ZXJuOiBcIiR7ZXg/Lm1lc3NhZ2V9XCIuYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhdHRlcm47XG4gIH1cblxufVxuXG5leHBvcnRzLlRpbGluZ1BhdHRlcm4gPSBUaWxpbmdQYXR0ZXJuO1xuXG4vKioqLyB9KSxcbi8qIDEyICovXG4vKioqLyAoKF9fdW51c2VkX3dlYnBhY2tfbW9kdWxlLCBleHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5leHBvcnRzLmFwcGx5TWFza0ltYWdlRGF0YSA9IGFwcGx5TWFza0ltYWdlRGF0YTtcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxuZnVuY3Rpb24gYXBwbHlNYXNrSW1hZ2VEYXRhKHtcbiAgc3JjLFxuICBzcmNQb3MgPSAwLFxuICBkZXN0LFxuICBkZXN0UG9zID0gMCxcbiAgd2lkdGgsXG4gIGhlaWdodCxcbiAgaW52ZXJzZURlY29kZSA9IGZhbHNlXG59KSB7XG4gIGNvbnN0IG9wYXF1ZSA9IF91dGlsLkZlYXR1cmVUZXN0LmlzTGl0dGxlRW5kaWFuID8gMHhmZjAwMDAwMCA6IDB4MDAwMDAwZmY7XG4gIGNvbnN0IFt6ZXJvTWFwcGluZywgb25lTWFwcGluZ10gPSAhaW52ZXJzZURlY29kZSA/IFtvcGFxdWUsIDBdIDogWzAsIG9wYXF1ZV07XG4gIGNvbnN0IHdpZHRoSW5Tb3VyY2UgPSB3aWR0aCA+PiAzO1xuICBjb25zdCB3aWR0aFJlbWFpbmRlciA9IHdpZHRoICYgNztcbiAgY29uc3Qgc3JjTGVuZ3RoID0gc3JjLmxlbmd0aDtcbiAgZGVzdCA9IG5ldyBVaW50MzJBcnJheShkZXN0LmJ1ZmZlcik7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBoZWlnaHQ7IGkrKykge1xuICAgIGZvciAoY29uc3QgbWF4ID0gc3JjUG9zICsgd2lkdGhJblNvdXJjZTsgc3JjUG9zIDwgbWF4OyBzcmNQb3MrKykge1xuICAgICAgY29uc3QgZWxlbSA9IHNyY1BvcyA8IHNyY0xlbmd0aCA/IHNyY1tzcmNQb3NdIDogMjU1O1xuICAgICAgZGVzdFtkZXN0UG9zKytdID0gZWxlbSAmIDBiMTAwMDAwMDAgPyBvbmVNYXBwaW5nIDogemVyb01hcHBpbmc7XG4gICAgICBkZXN0W2Rlc3RQb3MrK10gPSBlbGVtICYgMGIxMDAwMDAwID8gb25lTWFwcGluZyA6IHplcm9NYXBwaW5nO1xuICAgICAgZGVzdFtkZXN0UG9zKytdID0gZWxlbSAmIDBiMTAwMDAwID8gb25lTWFwcGluZyA6IHplcm9NYXBwaW5nO1xuICAgICAgZGVzdFtkZXN0UG9zKytdID0gZWxlbSAmIDBiMTAwMDAgPyBvbmVNYXBwaW5nIDogemVyb01hcHBpbmc7XG4gICAgICBkZXN0W2Rlc3RQb3MrK10gPSBlbGVtICYgMGIxMDAwID8gb25lTWFwcGluZyA6IHplcm9NYXBwaW5nO1xuICAgICAgZGVzdFtkZXN0UG9zKytdID0gZWxlbSAmIDBiMTAwID8gb25lTWFwcGluZyA6IHplcm9NYXBwaW5nO1xuICAgICAgZGVzdFtkZXN0UG9zKytdID0gZWxlbSAmIDBiMTAgPyBvbmVNYXBwaW5nIDogemVyb01hcHBpbmc7XG4gICAgICBkZXN0W2Rlc3RQb3MrK10gPSBlbGVtICYgMGIxID8gb25lTWFwcGluZyA6IHplcm9NYXBwaW5nO1xuICAgIH1cblxuICAgIGlmICh3aWR0aFJlbWFpbmRlciA9PT0gMCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY29uc3QgZWxlbSA9IHNyY1BvcyA8IHNyY0xlbmd0aCA/IHNyY1tzcmNQb3MrK10gOiAyNTU7XG5cbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IHdpZHRoUmVtYWluZGVyOyBqKyspIHtcbiAgICAgIGRlc3RbZGVzdFBvcysrXSA9IGVsZW0gJiAxIDw8IDcgLSBqID8gb25lTWFwcGluZyA6IHplcm9NYXBwaW5nO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgc3JjUG9zLFxuICAgIGRlc3RQb3NcbiAgfTtcbn1cblxuLyoqKi8gfSksXG4vKiAxMyAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5HbG9iYWxXb3JrZXJPcHRpb25zID0gdm9pZCAwO1xuY29uc3QgR2xvYmFsV29ya2VyT3B0aW9ucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5leHBvcnRzLkdsb2JhbFdvcmtlck9wdGlvbnMgPSBHbG9iYWxXb3JrZXJPcHRpb25zO1xuR2xvYmFsV29ya2VyT3B0aW9ucy53b3JrZXJQb3J0ID0gR2xvYmFsV29ya2VyT3B0aW9ucy53b3JrZXJQb3J0ID09PSB1bmRlZmluZWQgPyBudWxsIDogR2xvYmFsV29ya2VyT3B0aW9ucy53b3JrZXJQb3J0O1xuR2xvYmFsV29ya2VyT3B0aW9ucy53b3JrZXJTcmMgPSBHbG9iYWxXb3JrZXJPcHRpb25zLndvcmtlclNyYyA9PT0gdW5kZWZpbmVkID8gXCJcIiA6IEdsb2JhbFdvcmtlck9wdGlvbnMud29ya2VyU3JjO1xuXG4vKioqLyB9KSxcbi8qIDE0ICovXG4vKioqLyAoKF9fdW51c2VkX3dlYnBhY2tfbW9kdWxlLCBleHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5leHBvcnRzLk1lc3NhZ2VIYW5kbGVyID0gdm9pZCAwO1xuXG52YXIgX3V0aWwgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDEpO1xuXG5jb25zdCBDYWxsYmFja0tpbmQgPSB7XG4gIFVOS05PV046IDAsXG4gIERBVEE6IDEsXG4gIEVSUk9SOiAyXG59O1xuY29uc3QgU3RyZWFtS2luZCA9IHtcbiAgVU5LTk9XTjogMCxcbiAgQ0FOQ0VMOiAxLFxuICBDQU5DRUxfQ09NUExFVEU6IDIsXG4gIENMT1NFOiAzLFxuICBFTlFVRVVFOiA0LFxuICBFUlJPUjogNSxcbiAgUFVMTDogNixcbiAgUFVMTF9DT01QTEVURTogNyxcbiAgU1RBUlRfQ09NUExFVEU6IDhcbn07XG5cbmZ1bmN0aW9uIHdyYXBSZWFzb24ocmVhc29uKSB7XG4gIGlmICghKHJlYXNvbiBpbnN0YW5jZW9mIEVycm9yIHx8IHR5cGVvZiByZWFzb24gPT09IFwib2JqZWN0XCIgJiYgcmVhc29uICE9PSBudWxsKSkge1xuICAgICgwLCBfdXRpbC51bnJlYWNoYWJsZSkoJ3dyYXBSZWFzb246IEV4cGVjdGVkIFwicmVhc29uXCIgdG8gYmUgYSAocG9zc2libHkgY2xvbmVkKSBFcnJvci4nKTtcbiAgfVxuXG4gIHN3aXRjaCAocmVhc29uLm5hbWUpIHtcbiAgICBjYXNlIFwiQWJvcnRFeGNlcHRpb25cIjpcbiAgICAgIHJldHVybiBuZXcgX3V0aWwuQWJvcnRFeGNlcHRpb24ocmVhc29uLm1lc3NhZ2UpO1xuXG4gICAgY2FzZSBcIk1pc3NpbmdQREZFeGNlcHRpb25cIjpcbiAgICAgIHJldHVybiBuZXcgX3V0aWwuTWlzc2luZ1BERkV4Y2VwdGlvbihyZWFzb24ubWVzc2FnZSk7XG5cbiAgICBjYXNlIFwiUGFzc3dvcmRFeGNlcHRpb25cIjpcbiAgICAgIHJldHVybiBuZXcgX3V0aWwuUGFzc3dvcmRFeGNlcHRpb24ocmVhc29uLm1lc3NhZ2UsIHJlYXNvbi5jb2RlKTtcblxuICAgIGNhc2UgXCJVbmV4cGVjdGVkUmVzcG9uc2VFeGNlcHRpb25cIjpcbiAgICAgIHJldHVybiBuZXcgX3V0aWwuVW5leHBlY3RlZFJlc3BvbnNlRXhjZXB0aW9uKHJlYXNvbi5tZXNzYWdlLCByZWFzb24uc3RhdHVzKTtcblxuICAgIGNhc2UgXCJVbmtub3duRXJyb3JFeGNlcHRpb25cIjpcbiAgICAgIHJldHVybiBuZXcgX3V0aWwuVW5rbm93bkVycm9yRXhjZXB0aW9uKHJlYXNvbi5tZXNzYWdlLCByZWFzb24uZGV0YWlscyk7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIG5ldyBfdXRpbC5Vbmtub3duRXJyb3JFeGNlcHRpb24ocmVhc29uLm1lc3NhZ2UsIHJlYXNvbi50b1N0cmluZygpKTtcbiAgfVxufVxuXG5jbGFzcyBNZXNzYWdlSGFuZGxlciB7XG4gIGNvbnN0cnVjdG9yKHNvdXJjZU5hbWUsIHRhcmdldE5hbWUsIGNvbU9iaikge1xuICAgIHRoaXMuc291cmNlTmFtZSA9IHNvdXJjZU5hbWU7XG4gICAgdGhpcy50YXJnZXROYW1lID0gdGFyZ2V0TmFtZTtcbiAgICB0aGlzLmNvbU9iaiA9IGNvbU9iajtcbiAgICB0aGlzLmNhbGxiYWNrSWQgPSAxO1xuICAgIHRoaXMuc3RyZWFtSWQgPSAxO1xuICAgIHRoaXMuc3RyZWFtU2lua3MgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMuc3RyZWFtQ29udHJvbGxlcnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMuY2FsbGJhY2tDYXBhYmlsaXRpZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMuYWN0aW9uSGFuZGxlciA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbiAgICB0aGlzLl9vbkNvbU9iak9uTWVzc2FnZSA9IGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IGRhdGEgPSBldmVudC5kYXRhO1xuXG4gICAgICBpZiAoZGF0YS50YXJnZXROYW1lICE9PSB0aGlzLnNvdXJjZU5hbWUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZGF0YS5zdHJlYW0pIHtcbiAgICAgICAgdGhpcy5fcHJvY2Vzc1N0cmVhbU1lc3NhZ2UoZGF0YSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZGF0YS5jYWxsYmFjaykge1xuICAgICAgICBjb25zdCBjYWxsYmFja0lkID0gZGF0YS5jYWxsYmFja0lkO1xuICAgICAgICBjb25zdCBjYXBhYmlsaXR5ID0gdGhpcy5jYWxsYmFja0NhcGFiaWxpdGllc1tjYWxsYmFja0lkXTtcblxuICAgICAgICBpZiAoIWNhcGFiaWxpdHkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCByZXNvbHZlIGNhbGxiYWNrICR7Y2FsbGJhY2tJZH1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrQ2FwYWJpbGl0aWVzW2NhbGxiYWNrSWRdO1xuXG4gICAgICAgIGlmIChkYXRhLmNhbGxiYWNrID09PSBDYWxsYmFja0tpbmQuREFUQSkge1xuICAgICAgICAgIGNhcGFiaWxpdHkucmVzb2x2ZShkYXRhLmRhdGEpO1xuICAgICAgICB9IGVsc2UgaWYgKGRhdGEuY2FsbGJhY2sgPT09IENhbGxiYWNrS2luZC5FUlJPUikge1xuICAgICAgICAgIGNhcGFiaWxpdHkucmVqZWN0KHdyYXBSZWFzb24oZGF0YS5yZWFzb24pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmV4cGVjdGVkIGNhbGxiYWNrIGNhc2VcIik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFjdGlvbiA9IHRoaXMuYWN0aW9uSGFuZGxlcltkYXRhLmFjdGlvbl07XG5cbiAgICAgIGlmICghYWN0aW9uKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBhY3Rpb24gZnJvbSB3b3JrZXI6ICR7ZGF0YS5hY3Rpb259YCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChkYXRhLmNhbGxiYWNrSWQpIHtcbiAgICAgICAgY29uc3QgY2JTb3VyY2VOYW1lID0gdGhpcy5zb3VyY2VOYW1lO1xuICAgICAgICBjb25zdCBjYlRhcmdldE5hbWUgPSBkYXRhLnNvdXJjZU5hbWU7XG4gICAgICAgIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgICAgICAgcmVzb2x2ZShhY3Rpb24oZGF0YS5kYXRhKSk7XG4gICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICAgIGNvbU9iai5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICBzb3VyY2VOYW1lOiBjYlNvdXJjZU5hbWUsXG4gICAgICAgICAgICB0YXJnZXROYW1lOiBjYlRhcmdldE5hbWUsXG4gICAgICAgICAgICBjYWxsYmFjazogQ2FsbGJhY2tLaW5kLkRBVEEsXG4gICAgICAgICAgICBjYWxsYmFja0lkOiBkYXRhLmNhbGxiYWNrSWQsXG4gICAgICAgICAgICBkYXRhOiByZXN1bHRcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICAgIGNvbU9iai5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICBzb3VyY2VOYW1lOiBjYlNvdXJjZU5hbWUsXG4gICAgICAgICAgICB0YXJnZXROYW1lOiBjYlRhcmdldE5hbWUsXG4gICAgICAgICAgICBjYWxsYmFjazogQ2FsbGJhY2tLaW5kLkVSUk9SLFxuICAgICAgICAgICAgY2FsbGJhY2tJZDogZGF0YS5jYWxsYmFja0lkLFxuICAgICAgICAgICAgcmVhc29uOiB3cmFwUmVhc29uKHJlYXNvbilcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGRhdGEuc3RyZWFtSWQpIHtcbiAgICAgICAgdGhpcy5fY3JlYXRlU3RyZWFtU2luayhkYXRhKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGFjdGlvbihkYXRhLmRhdGEpO1xuICAgIH07XG5cbiAgICBjb21PYmouYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgdGhpcy5fb25Db21PYmpPbk1lc3NhZ2UpO1xuICB9XG5cbiAgb24oYWN0aW9uTmFtZSwgaGFuZGxlcikge1xuICAgIGNvbnN0IGFoID0gdGhpcy5hY3Rpb25IYW5kbGVyO1xuXG4gICAgaWYgKGFoW2FjdGlvbk5hbWVdKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZXJlIGlzIGFscmVhZHkgYW4gYWN0aW9uTmFtZSBjYWxsZWQgXCIke2FjdGlvbk5hbWV9XCJgKTtcbiAgICB9XG5cbiAgICBhaFthY3Rpb25OYW1lXSA9IGhhbmRsZXI7XG4gIH1cblxuICBzZW5kKGFjdGlvbk5hbWUsIGRhdGEsIHRyYW5zZmVycykge1xuICAgIHRoaXMuY29tT2JqLnBvc3RNZXNzYWdlKHtcbiAgICAgIHNvdXJjZU5hbWU6IHRoaXMuc291cmNlTmFtZSxcbiAgICAgIHRhcmdldE5hbWU6IHRoaXMudGFyZ2V0TmFtZSxcbiAgICAgIGFjdGlvbjogYWN0aW9uTmFtZSxcbiAgICAgIGRhdGFcbiAgICB9LCB0cmFuc2ZlcnMpO1xuICB9XG5cbiAgc2VuZFdpdGhQcm9taXNlKGFjdGlvbk5hbWUsIGRhdGEsIHRyYW5zZmVycykge1xuICAgIGNvbnN0IGNhbGxiYWNrSWQgPSB0aGlzLmNhbGxiYWNrSWQrKztcbiAgICBjb25zdCBjYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgIHRoaXMuY2FsbGJhY2tDYXBhYmlsaXRpZXNbY2FsbGJhY2tJZF0gPSBjYXBhYmlsaXR5O1xuXG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuY29tT2JqLnBvc3RNZXNzYWdlKHtcbiAgICAgICAgc291cmNlTmFtZTogdGhpcy5zb3VyY2VOYW1lLFxuICAgICAgICB0YXJnZXROYW1lOiB0aGlzLnRhcmdldE5hbWUsXG4gICAgICAgIGFjdGlvbjogYWN0aW9uTmFtZSxcbiAgICAgICAgY2FsbGJhY2tJZCxcbiAgICAgICAgZGF0YVxuICAgICAgfSwgdHJhbnNmZXJzKTtcbiAgICB9IGNhdGNoIChleCkge1xuICAgICAgY2FwYWJpbGl0eS5yZWplY3QoZXgpO1xuICAgIH1cblxuICAgIHJldHVybiBjYXBhYmlsaXR5LnByb21pc2U7XG4gIH1cblxuICBzZW5kV2l0aFN0cmVhbShhY3Rpb25OYW1lLCBkYXRhLCBxdWV1ZWluZ1N0cmF0ZWd5LCB0cmFuc2ZlcnMpIHtcbiAgICBjb25zdCBzdHJlYW1JZCA9IHRoaXMuc3RyZWFtSWQrKyxcbiAgICAgICAgICBzb3VyY2VOYW1lID0gdGhpcy5zb3VyY2VOYW1lLFxuICAgICAgICAgIHRhcmdldE5hbWUgPSB0aGlzLnRhcmdldE5hbWUsXG4gICAgICAgICAgY29tT2JqID0gdGhpcy5jb21PYmo7XG4gICAgcmV0dXJuIG5ldyBSZWFkYWJsZVN0cmVhbSh7XG4gICAgICBzdGFydDogY29udHJvbGxlciA9PiB7XG4gICAgICAgIGNvbnN0IHN0YXJ0Q2FwYWJpbGl0eSA9ICgwLCBfdXRpbC5jcmVhdGVQcm9taXNlQ2FwYWJpbGl0eSkoKTtcbiAgICAgICAgdGhpcy5zdHJlYW1Db250cm9sbGVyc1tzdHJlYW1JZF0gPSB7XG4gICAgICAgICAgY29udHJvbGxlcixcbiAgICAgICAgICBzdGFydENhbGw6IHN0YXJ0Q2FwYWJpbGl0eSxcbiAgICAgICAgICBwdWxsQ2FsbDogbnVsbCxcbiAgICAgICAgICBjYW5jZWxDYWxsOiBudWxsLFxuICAgICAgICAgIGlzQ2xvc2VkOiBmYWxzZVxuICAgICAgICB9O1xuICAgICAgICBjb21PYmoucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgIHNvdXJjZU5hbWUsXG4gICAgICAgICAgdGFyZ2V0TmFtZSxcbiAgICAgICAgICBhY3Rpb246IGFjdGlvbk5hbWUsXG4gICAgICAgICAgc3RyZWFtSWQsXG4gICAgICAgICAgZGF0YSxcbiAgICAgICAgICBkZXNpcmVkU2l6ZTogY29udHJvbGxlci5kZXNpcmVkU2l6ZVxuICAgICAgICB9LCB0cmFuc2ZlcnMpO1xuICAgICAgICByZXR1cm4gc3RhcnRDYXBhYmlsaXR5LnByb21pc2U7XG4gICAgICB9LFxuICAgICAgcHVsbDogY29udHJvbGxlciA9PiB7XG4gICAgICAgIGNvbnN0IHB1bGxDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgICAgICB0aGlzLnN0cmVhbUNvbnRyb2xsZXJzW3N0cmVhbUlkXS5wdWxsQ2FsbCA9IHB1bGxDYXBhYmlsaXR5O1xuICAgICAgICBjb21PYmoucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgIHNvdXJjZU5hbWUsXG4gICAgICAgICAgdGFyZ2V0TmFtZSxcbiAgICAgICAgICBzdHJlYW06IFN0cmVhbUtpbmQuUFVMTCxcbiAgICAgICAgICBzdHJlYW1JZCxcbiAgICAgICAgICBkZXNpcmVkU2l6ZTogY29udHJvbGxlci5kZXNpcmVkU2l6ZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHB1bGxDYXBhYmlsaXR5LnByb21pc2U7XG4gICAgICB9LFxuICAgICAgY2FuY2VsOiByZWFzb24gPT4ge1xuICAgICAgICAoMCwgX3V0aWwuYXNzZXJ0KShyZWFzb24gaW5zdGFuY2VvZiBFcnJvciwgXCJjYW5jZWwgbXVzdCBoYXZlIGEgdmFsaWQgcmVhc29uXCIpO1xuICAgICAgICBjb25zdCBjYW5jZWxDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgICAgICB0aGlzLnN0cmVhbUNvbnRyb2xsZXJzW3N0cmVhbUlkXS5jYW5jZWxDYWxsID0gY2FuY2VsQ2FwYWJpbGl0eTtcbiAgICAgICAgdGhpcy5zdHJlYW1Db250cm9sbGVyc1tzdHJlYW1JZF0uaXNDbG9zZWQgPSB0cnVlO1xuICAgICAgICBjb21PYmoucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgIHNvdXJjZU5hbWUsXG4gICAgICAgICAgdGFyZ2V0TmFtZSxcbiAgICAgICAgICBzdHJlYW06IFN0cmVhbUtpbmQuQ0FOQ0VMLFxuICAgICAgICAgIHN0cmVhbUlkLFxuICAgICAgICAgIHJlYXNvbjogd3JhcFJlYXNvbihyZWFzb24pXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gY2FuY2VsQ2FwYWJpbGl0eS5wcm9taXNlO1xuICAgICAgfVxuICAgIH0sIHF1ZXVlaW5nU3RyYXRlZ3kpO1xuICB9XG5cbiAgX2NyZWF0ZVN0cmVhbVNpbmsoZGF0YSkge1xuICAgIGNvbnN0IHN0cmVhbUlkID0gZGF0YS5zdHJlYW1JZCxcbiAgICAgICAgICBzb3VyY2VOYW1lID0gdGhpcy5zb3VyY2VOYW1lLFxuICAgICAgICAgIHRhcmdldE5hbWUgPSBkYXRhLnNvdXJjZU5hbWUsXG4gICAgICAgICAgY29tT2JqID0gdGhpcy5jb21PYmo7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXMsXG4gICAgICAgICAgYWN0aW9uID0gdGhpcy5hY3Rpb25IYW5kbGVyW2RhdGEuYWN0aW9uXTtcbiAgICBjb25zdCBzdHJlYW1TaW5rID0ge1xuICAgICAgZW5xdWV1ZShjaHVuaywgc2l6ZSA9IDEsIHRyYW5zZmVycykge1xuICAgICAgICBpZiAodGhpcy5pc0NhbmNlbGxlZCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxhc3REZXNpcmVkU2l6ZSA9IHRoaXMuZGVzaXJlZFNpemU7XG4gICAgICAgIHRoaXMuZGVzaXJlZFNpemUgLT0gc2l6ZTtcblxuICAgICAgICBpZiAobGFzdERlc2lyZWRTaXplID4gMCAmJiB0aGlzLmRlc2lyZWRTaXplIDw9IDApIHtcbiAgICAgICAgICB0aGlzLnNpbmtDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgICAgICAgIHRoaXMucmVhZHkgPSB0aGlzLnNpbmtDYXBhYmlsaXR5LnByb21pc2U7XG4gICAgICAgIH1cblxuICAgICAgICBjb21PYmoucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgIHNvdXJjZU5hbWUsXG4gICAgICAgICAgdGFyZ2V0TmFtZSxcbiAgICAgICAgICBzdHJlYW06IFN0cmVhbUtpbmQuRU5RVUVVRSxcbiAgICAgICAgICBzdHJlYW1JZCxcbiAgICAgICAgICBjaHVua1xuICAgICAgICB9LCB0cmFuc2ZlcnMpO1xuICAgICAgfSxcblxuICAgICAgY2xvc2UoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzQ2FuY2VsbGVkKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5pc0NhbmNlbGxlZCA9IHRydWU7XG4gICAgICAgIGNvbU9iai5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgc291cmNlTmFtZSxcbiAgICAgICAgICB0YXJnZXROYW1lLFxuICAgICAgICAgIHN0cmVhbTogU3RyZWFtS2luZC5DTE9TRSxcbiAgICAgICAgICBzdHJlYW1JZFxuICAgICAgICB9KTtcbiAgICAgICAgZGVsZXRlIHNlbGYuc3RyZWFtU2lua3Nbc3RyZWFtSWRdO1xuICAgICAgfSxcblxuICAgICAgZXJyb3IocmVhc29uKSB7XG4gICAgICAgICgwLCBfdXRpbC5hc3NlcnQpKHJlYXNvbiBpbnN0YW5jZW9mIEVycm9yLCBcImVycm9yIG11c3QgaGF2ZSBhIHZhbGlkIHJlYXNvblwiKTtcblxuICAgICAgICBpZiAodGhpcy5pc0NhbmNlbGxlZCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuaXNDYW5jZWxsZWQgPSB0cnVlO1xuICAgICAgICBjb21PYmoucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgIHNvdXJjZU5hbWUsXG4gICAgICAgICAgdGFyZ2V0TmFtZSxcbiAgICAgICAgICBzdHJlYW06IFN0cmVhbUtpbmQuRVJST1IsXG4gICAgICAgICAgc3RyZWFtSWQsXG4gICAgICAgICAgcmVhc29uOiB3cmFwUmVhc29uKHJlYXNvbilcbiAgICAgICAgfSk7XG4gICAgICB9LFxuXG4gICAgICBzaW5rQ2FwYWJpbGl0eTogKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpLFxuICAgICAgb25QdWxsOiBudWxsLFxuICAgICAgb25DYW5jZWw6IG51bGwsXG4gICAgICBpc0NhbmNlbGxlZDogZmFsc2UsXG4gICAgICBkZXNpcmVkU2l6ZTogZGF0YS5kZXNpcmVkU2l6ZSxcbiAgICAgIHJlYWR5OiBudWxsXG4gICAgfTtcbiAgICBzdHJlYW1TaW5rLnNpbmtDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgICBzdHJlYW1TaW5rLnJlYWR5ID0gc3RyZWFtU2luay5zaW5rQ2FwYWJpbGl0eS5wcm9taXNlO1xuICAgIHRoaXMuc3RyZWFtU2lua3Nbc3RyZWFtSWRdID0gc3RyZWFtU2luaztcbiAgICBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgcmVzb2x2ZShhY3Rpb24oZGF0YS5kYXRhLCBzdHJlYW1TaW5rKSk7XG4gICAgfSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICBjb21PYmoucG9zdE1lc3NhZ2Uoe1xuICAgICAgICBzb3VyY2VOYW1lLFxuICAgICAgICB0YXJnZXROYW1lLFxuICAgICAgICBzdHJlYW06IFN0cmVhbUtpbmQuU1RBUlRfQ09NUExFVEUsXG4gICAgICAgIHN0cmVhbUlkLFxuICAgICAgICBzdWNjZXNzOiB0cnVlXG4gICAgICB9KTtcbiAgICB9LCBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgICBjb21PYmoucG9zdE1lc3NhZ2Uoe1xuICAgICAgICBzb3VyY2VOYW1lLFxuICAgICAgICB0YXJnZXROYW1lLFxuICAgICAgICBzdHJlYW06IFN0cmVhbUtpbmQuU1RBUlRfQ09NUExFVEUsXG4gICAgICAgIHN0cmVhbUlkLFxuICAgICAgICByZWFzb246IHdyYXBSZWFzb24ocmVhc29uKVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBfcHJvY2Vzc1N0cmVhbU1lc3NhZ2UoZGF0YSkge1xuICAgIGNvbnN0IHN0cmVhbUlkID0gZGF0YS5zdHJlYW1JZCxcbiAgICAgICAgICBzb3VyY2VOYW1lID0gdGhpcy5zb3VyY2VOYW1lLFxuICAgICAgICAgIHRhcmdldE5hbWUgPSBkYXRhLnNvdXJjZU5hbWUsXG4gICAgICAgICAgY29tT2JqID0gdGhpcy5jb21PYmo7XG4gICAgY29uc3Qgc3RyZWFtQ29udHJvbGxlciA9IHRoaXMuc3RyZWFtQ29udHJvbGxlcnNbc3RyZWFtSWRdLFxuICAgICAgICAgIHN0cmVhbVNpbmsgPSB0aGlzLnN0cmVhbVNpbmtzW3N0cmVhbUlkXTtcblxuICAgIHN3aXRjaCAoZGF0YS5zdHJlYW0pIHtcbiAgICAgIGNhc2UgU3RyZWFtS2luZC5TVEFSVF9DT01QTEVURTpcbiAgICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICAgIHN0cmVhbUNvbnRyb2xsZXIuc3RhcnRDYWxsLnJlc29sdmUoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzdHJlYW1Db250cm9sbGVyLnN0YXJ0Q2FsbC5yZWplY3Qod3JhcFJlYXNvbihkYXRhLnJlYXNvbikpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgU3RyZWFtS2luZC5QVUxMX0NPTVBMRVRFOlxuICAgICAgICBpZiAoZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgc3RyZWFtQ29udHJvbGxlci5wdWxsQ2FsbC5yZXNvbHZlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RyZWFtQ29udHJvbGxlci5wdWxsQ2FsbC5yZWplY3Qod3JhcFJlYXNvbihkYXRhLnJlYXNvbikpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgU3RyZWFtS2luZC5QVUxMOlxuICAgICAgICBpZiAoIXN0cmVhbVNpbmspIHtcbiAgICAgICAgICBjb21PYmoucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgICAgc291cmNlTmFtZSxcbiAgICAgICAgICAgIHRhcmdldE5hbWUsXG4gICAgICAgICAgICBzdHJlYW06IFN0cmVhbUtpbmQuUFVMTF9DT01QTEVURSxcbiAgICAgICAgICAgIHN0cmVhbUlkLFxuICAgICAgICAgICAgc3VjY2VzczogdHJ1ZVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHN0cmVhbVNpbmsuZGVzaXJlZFNpemUgPD0gMCAmJiBkYXRhLmRlc2lyZWRTaXplID4gMCkge1xuICAgICAgICAgIHN0cmVhbVNpbmsuc2lua0NhcGFiaWxpdHkucmVzb2x2ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgc3RyZWFtU2luay5kZXNpcmVkU2l6ZSA9IGRhdGEuZGVzaXJlZFNpemU7XG4gICAgICAgIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgICAgICAgcmVzb2x2ZShzdHJlYW1TaW5rLm9uUHVsbCAmJiBzdHJlYW1TaW5rLm9uUHVsbCgpKTtcbiAgICAgICAgfSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29tT2JqLnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIHNvdXJjZU5hbWUsXG4gICAgICAgICAgICB0YXJnZXROYW1lLFxuICAgICAgICAgICAgc3RyZWFtOiBTdHJlYW1LaW5kLlBVTExfQ09NUExFVEUsXG4gICAgICAgICAgICBzdHJlYW1JZCxcbiAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWVcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICAgIGNvbU9iai5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICBzb3VyY2VOYW1lLFxuICAgICAgICAgICAgdGFyZ2V0TmFtZSxcbiAgICAgICAgICAgIHN0cmVhbTogU3RyZWFtS2luZC5QVUxMX0NPTVBMRVRFLFxuICAgICAgICAgICAgc3RyZWFtSWQsXG4gICAgICAgICAgICByZWFzb246IHdyYXBSZWFzb24ocmVhc29uKVxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgU3RyZWFtS2luZC5FTlFVRVVFOlxuICAgICAgICAoMCwgX3V0aWwuYXNzZXJ0KShzdHJlYW1Db250cm9sbGVyLCBcImVucXVldWUgc2hvdWxkIGhhdmUgc3RyZWFtIGNvbnRyb2xsZXJcIik7XG5cbiAgICAgICAgaWYgKHN0cmVhbUNvbnRyb2xsZXIuaXNDbG9zZWQpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIHN0cmVhbUNvbnRyb2xsZXIuY29udHJvbGxlci5lbnF1ZXVlKGRhdGEuY2h1bmspO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBTdHJlYW1LaW5kLkNMT1NFOlxuICAgICAgICAoMCwgX3V0aWwuYXNzZXJ0KShzdHJlYW1Db250cm9sbGVyLCBcImNsb3NlIHNob3VsZCBoYXZlIHN0cmVhbSBjb250cm9sbGVyXCIpO1xuXG4gICAgICAgIGlmIChzdHJlYW1Db250cm9sbGVyLmlzQ2xvc2VkKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBzdHJlYW1Db250cm9sbGVyLmlzQ2xvc2VkID0gdHJ1ZTtcbiAgICAgICAgc3RyZWFtQ29udHJvbGxlci5jb250cm9sbGVyLmNsb3NlKCk7XG5cbiAgICAgICAgdGhpcy5fZGVsZXRlU3RyZWFtQ29udHJvbGxlcihzdHJlYW1Db250cm9sbGVyLCBzdHJlYW1JZCk7XG5cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgU3RyZWFtS2luZC5FUlJPUjpcbiAgICAgICAgKDAsIF91dGlsLmFzc2VydCkoc3RyZWFtQ29udHJvbGxlciwgXCJlcnJvciBzaG91bGQgaGF2ZSBzdHJlYW0gY29udHJvbGxlclwiKTtcbiAgICAgICAgc3RyZWFtQ29udHJvbGxlci5jb250cm9sbGVyLmVycm9yKHdyYXBSZWFzb24oZGF0YS5yZWFzb24pKTtcblxuICAgICAgICB0aGlzLl9kZWxldGVTdHJlYW1Db250cm9sbGVyKHN0cmVhbUNvbnRyb2xsZXIsIHN0cmVhbUlkKTtcblxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBTdHJlYW1LaW5kLkNBTkNFTF9DT01QTEVURTpcbiAgICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICAgIHN0cmVhbUNvbnRyb2xsZXIuY2FuY2VsQ2FsbC5yZXNvbHZlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RyZWFtQ29udHJvbGxlci5jYW5jZWxDYWxsLnJlamVjdCh3cmFwUmVhc29uKGRhdGEucmVhc29uKSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9kZWxldGVTdHJlYW1Db250cm9sbGVyKHN0cmVhbUNvbnRyb2xsZXIsIHN0cmVhbUlkKTtcblxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBTdHJlYW1LaW5kLkNBTkNFTDpcbiAgICAgICAgaWYgKCFzdHJlYW1TaW5rKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICAgIHJlc29sdmUoc3RyZWFtU2luay5vbkNhbmNlbCAmJiBzdHJlYW1TaW5rLm9uQ2FuY2VsKHdyYXBSZWFzb24oZGF0YS5yZWFzb24pKSk7XG4gICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbU9iai5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICBzb3VyY2VOYW1lLFxuICAgICAgICAgICAgdGFyZ2V0TmFtZSxcbiAgICAgICAgICAgIHN0cmVhbTogU3RyZWFtS2luZC5DQU5DRUxfQ09NUExFVEUsXG4gICAgICAgICAgICBzdHJlYW1JZCxcbiAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWVcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICAgIGNvbU9iai5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICBzb3VyY2VOYW1lLFxuICAgICAgICAgICAgdGFyZ2V0TmFtZSxcbiAgICAgICAgICAgIHN0cmVhbTogU3RyZWFtS2luZC5DQU5DRUxfQ09NUExFVEUsXG4gICAgICAgICAgICBzdHJlYW1JZCxcbiAgICAgICAgICAgIHJlYXNvbjogd3JhcFJlYXNvbihyZWFzb24pXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBzdHJlYW1TaW5rLnNpbmtDYXBhYmlsaXR5LnJlamVjdCh3cmFwUmVhc29uKGRhdGEucmVhc29uKSk7XG4gICAgICAgIHN0cmVhbVNpbmsuaXNDYW5jZWxsZWQgPSB0cnVlO1xuICAgICAgICBkZWxldGUgdGhpcy5zdHJlYW1TaW5rc1tzdHJlYW1JZF07XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmV4cGVjdGVkIHN0cmVhbSBjYXNlXCIpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIF9kZWxldGVTdHJlYW1Db250cm9sbGVyKHN0cmVhbUNvbnRyb2xsZXIsIHN0cmVhbUlkKSB7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFtzdHJlYW1Db250cm9sbGVyLnN0YXJ0Q2FsbCAmJiBzdHJlYW1Db250cm9sbGVyLnN0YXJ0Q2FsbC5wcm9taXNlLCBzdHJlYW1Db250cm9sbGVyLnB1bGxDYWxsICYmIHN0cmVhbUNvbnRyb2xsZXIucHVsbENhbGwucHJvbWlzZSwgc3RyZWFtQ29udHJvbGxlci5jYW5jZWxDYWxsICYmIHN0cmVhbUNvbnRyb2xsZXIuY2FuY2VsQ2FsbC5wcm9taXNlXSk7XG4gICAgZGVsZXRlIHRoaXMuc3RyZWFtQ29udHJvbGxlcnNbc3RyZWFtSWRdO1xuICB9XG5cbiAgZGVzdHJveSgpIHtcbiAgICB0aGlzLmNvbU9iai5yZW1vdmVFdmVudExpc3RlbmVyKFwibWVzc2FnZVwiLCB0aGlzLl9vbkNvbU9iak9uTWVzc2FnZSk7XG4gIH1cblxufVxuXG5leHBvcnRzLk1lc3NhZ2VIYW5kbGVyID0gTWVzc2FnZUhhbmRsZXI7XG5cbi8qKiovIH0pLFxuLyogMTUgKi9cbi8qKiovICgoX191bnVzZWRfd2VicGFja19tb2R1bGUsIGV4cG9ydHMsIF9fd19wZGZqc19yZXF1aXJlX18pID0+IHtcblxuXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgKHtcbiAgdmFsdWU6IHRydWVcbn0pKTtcbmV4cG9ydHMuTWV0YWRhdGEgPSB2b2lkIDA7XG5cbnZhciBfdXRpbCA9IF9fd19wZGZqc19yZXF1aXJlX18oMSk7XG5cbmNsYXNzIE1ldGFkYXRhIHtcbiAgI21ldGFkYXRhTWFwO1xuICAjZGF0YTtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgcGFyc2VkRGF0YSxcbiAgICByYXdEYXRhXG4gIH0pIHtcbiAgICB0aGlzLiNtZXRhZGF0YU1hcCA9IHBhcnNlZERhdGE7XG4gICAgdGhpcy4jZGF0YSA9IHJhd0RhdGE7XG4gIH1cblxuICBnZXRSYXcoKSB7XG4gICAgcmV0dXJuIHRoaXMuI2RhdGE7XG4gIH1cblxuICBnZXQobmFtZSkge1xuICAgIHJldHVybiB0aGlzLiNtZXRhZGF0YU1hcC5nZXQobmFtZSkgPz8gbnVsbDtcbiAgfVxuXG4gIGdldEFsbCgpIHtcbiAgICByZXR1cm4gKDAsIF91dGlsLm9iamVjdEZyb21NYXApKHRoaXMuI21ldGFkYXRhTWFwKTtcbiAgfVxuXG4gIGhhcyhuYW1lKSB7XG4gICAgcmV0dXJuIHRoaXMuI21ldGFkYXRhTWFwLmhhcyhuYW1lKTtcbiAgfVxuXG59XG5cbmV4cG9ydHMuTWV0YWRhdGEgPSBNZXRhZGF0YTtcblxuLyoqKi8gfSksXG4vKiAxNiAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5PcHRpb25hbENvbnRlbnRDb25maWcgPSB2b2lkIDA7XG5cbnZhciBfdXRpbCA9IF9fd19wZGZqc19yZXF1aXJlX18oMSk7XG5cbmNsYXNzIE9wdGlvbmFsQ29udGVudEdyb3VwIHtcbiAgY29uc3RydWN0b3IobmFtZSwgaW50ZW50KSB7XG4gICAgdGhpcy52aXNpYmxlID0gdHJ1ZTtcbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIHRoaXMuaW50ZW50ID0gaW50ZW50O1xuICB9XG5cbn1cblxuY2xhc3MgT3B0aW9uYWxDb250ZW50Q29uZmlnIHtcbiAgY29uc3RydWN0b3IoZGF0YSkge1xuICAgIHRoaXMubmFtZSA9IG51bGw7XG4gICAgdGhpcy5jcmVhdG9yID0gbnVsbDtcbiAgICB0aGlzLl9vcmRlciA9IG51bGw7XG4gICAgdGhpcy5fZ3JvdXBzID0gbmV3IE1hcCgpO1xuXG4gICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLm5hbWUgPSBkYXRhLm5hbWU7XG4gICAgdGhpcy5jcmVhdG9yID0gZGF0YS5jcmVhdG9yO1xuICAgIHRoaXMuX29yZGVyID0gZGF0YS5vcmRlcjtcblxuICAgIGZvciAoY29uc3QgZ3JvdXAgb2YgZGF0YS5ncm91cHMpIHtcbiAgICAgIHRoaXMuX2dyb3Vwcy5zZXQoZ3JvdXAuaWQsIG5ldyBPcHRpb25hbENvbnRlbnRHcm91cChncm91cC5uYW1lLCBncm91cC5pbnRlbnQpKTtcbiAgICB9XG5cbiAgICBpZiAoZGF0YS5iYXNlU3RhdGUgPT09IFwiT0ZGXCIpIHtcbiAgICAgIGZvciAoY29uc3QgZ3JvdXAgb2YgdGhpcy5fZ3JvdXBzKSB7XG4gICAgICAgIGdyb3VwLnZpc2libGUgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IG9uIG9mIGRhdGEub24pIHtcbiAgICAgIHRoaXMuX2dyb3Vwcy5nZXQob24pLnZpc2libGUgPSB0cnVlO1xuICAgIH1cblxuICAgIGZvciAoY29uc3Qgb2ZmIG9mIGRhdGEub2ZmKSB7XG4gICAgICB0aGlzLl9ncm91cHMuZ2V0KG9mZikudmlzaWJsZSA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIF9ldmFsdWF0ZVZpc2liaWxpdHlFeHByZXNzaW9uKGFycmF5KSB7XG4gICAgY29uc3QgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgaWYgKGxlbmd0aCA8IDIpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGNvbnN0IG9wZXJhdG9yID0gYXJyYXlbMF07XG5cbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gYXJyYXlbaV07XG4gICAgICBsZXQgc3RhdGU7XG5cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGVsZW1lbnQpKSB7XG4gICAgICAgIHN0YXRlID0gdGhpcy5fZXZhbHVhdGVWaXNpYmlsaXR5RXhwcmVzc2lvbihlbGVtZW50KTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5fZ3JvdXBzLmhhcyhlbGVtZW50KSkge1xuICAgICAgICBzdGF0ZSA9IHRoaXMuX2dyb3Vwcy5nZXQoZWxlbWVudCkudmlzaWJsZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgICgwLCBfdXRpbC53YXJuKShgT3B0aW9uYWwgY29udGVudCBncm91cCBub3QgZm91bmQ6ICR7ZWxlbWVudH1gKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIHN3aXRjaCAob3BlcmF0b3IpIHtcbiAgICAgICAgY2FzZSBcIkFuZFwiOlxuICAgICAgICAgIGlmICghc3RhdGUpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFwiT3JcIjpcbiAgICAgICAgICBpZiAoc3RhdGUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgXCJOb3RcIjpcbiAgICAgICAgICByZXR1cm4gIXN0YXRlO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG9wZXJhdG9yID09PSBcIkFuZFwiO1xuICB9XG5cbiAgaXNWaXNpYmxlKGdyb3VwKSB7XG4gICAgaWYgKHRoaXMuX2dyb3Vwcy5zaXplID09PSAwKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoIWdyb3VwKSB7XG4gICAgICAoMCwgX3V0aWwud2FybikoXCJPcHRpb25hbCBjb250ZW50IGdyb3VwIG5vdCBkZWZpbmVkLlwiKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChncm91cC50eXBlID09PSBcIk9DR1wiKSB7XG4gICAgICBpZiAoIXRoaXMuX2dyb3Vwcy5oYXMoZ3JvdXAuaWQpKSB7XG4gICAgICAgICgwLCBfdXRpbC53YXJuKShgT3B0aW9uYWwgY29udGVudCBncm91cCBub3QgZm91bmQ6ICR7Z3JvdXAuaWR9YCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5fZ3JvdXBzLmdldChncm91cC5pZCkudmlzaWJsZTtcbiAgICB9IGVsc2UgaWYgKGdyb3VwLnR5cGUgPT09IFwiT0NNRFwiKSB7XG4gICAgICBpZiAoZ3JvdXAuZXhwcmVzc2lvbikge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZhbHVhdGVWaXNpYmlsaXR5RXhwcmVzc2lvbihncm91cC5leHByZXNzaW9uKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFncm91cC5wb2xpY3kgfHwgZ3JvdXAucG9saWN5ID09PSBcIkFueU9uXCIpIHtcbiAgICAgICAgZm9yIChjb25zdCBpZCBvZiBncm91cC5pZHMpIHtcbiAgICAgICAgICBpZiAoIXRoaXMuX2dyb3Vwcy5oYXMoaWQpKSB7XG4gICAgICAgICAgICAoMCwgX3V0aWwud2FybikoYE9wdGlvbmFsIGNvbnRlbnQgZ3JvdXAgbm90IGZvdW5kOiAke2lkfWApO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHRoaXMuX2dyb3Vwcy5nZXQoaWQpLnZpc2libGUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0gZWxzZSBpZiAoZ3JvdXAucG9saWN5ID09PSBcIkFsbE9uXCIpIHtcbiAgICAgICAgZm9yIChjb25zdCBpZCBvZiBncm91cC5pZHMpIHtcbiAgICAgICAgICBpZiAoIXRoaXMuX2dyb3Vwcy5oYXMoaWQpKSB7XG4gICAgICAgICAgICAoMCwgX3V0aWwud2FybikoYE9wdGlvbmFsIGNvbnRlbnQgZ3JvdXAgbm90IGZvdW5kOiAke2lkfWApO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCF0aGlzLl9ncm91cHMuZ2V0KGlkKS52aXNpYmxlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGVsc2UgaWYgKGdyb3VwLnBvbGljeSA9PT0gXCJBbnlPZmZcIikge1xuICAgICAgICBmb3IgKGNvbnN0IGlkIG9mIGdyb3VwLmlkcykge1xuICAgICAgICAgIGlmICghdGhpcy5fZ3JvdXBzLmhhcyhpZCkpIHtcbiAgICAgICAgICAgICgwLCBfdXRpbC53YXJuKShgT3B0aW9uYWwgY29udGVudCBncm91cCBub3QgZm91bmQ6ICR7aWR9YCk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIXRoaXMuX2dyb3Vwcy5nZXQoaWQpLnZpc2libGUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0gZWxzZSBpZiAoZ3JvdXAucG9saWN5ID09PSBcIkFsbE9mZlwiKSB7XG4gICAgICAgIGZvciAoY29uc3QgaWQgb2YgZ3JvdXAuaWRzKSB7XG4gICAgICAgICAgaWYgKCF0aGlzLl9ncm91cHMuaGFzKGlkKSkge1xuICAgICAgICAgICAgKDAsIF91dGlsLndhcm4pKGBPcHRpb25hbCBjb250ZW50IGdyb3VwIG5vdCBmb3VuZDogJHtpZH1gKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICh0aGlzLl9ncm91cHMuZ2V0KGlkKS52aXNpYmxlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgICgwLCBfdXRpbC53YXJuKShgVW5rbm93biBvcHRpb25hbCBjb250ZW50IHBvbGljeSAke2dyb3VwLnBvbGljeX0uYCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAoMCwgX3V0aWwud2FybikoYFVua25vd24gZ3JvdXAgdHlwZSAke2dyb3VwLnR5cGV9LmApO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgc2V0VmlzaWJpbGl0eShpZCwgdmlzaWJsZSA9IHRydWUpIHtcbiAgICBpZiAoIXRoaXMuX2dyb3Vwcy5oYXMoaWQpKSB7XG4gICAgICAoMCwgX3V0aWwud2FybikoYE9wdGlvbmFsIGNvbnRlbnQgZ3JvdXAgbm90IGZvdW5kOiAke2lkfWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2dyb3Vwcy5nZXQoaWQpLnZpc2libGUgPSAhIXZpc2libGU7XG4gIH1cblxuICBnZXRPcmRlcigpIHtcbiAgICBpZiAoIXRoaXMuX2dyb3Vwcy5zaXplKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fb3JkZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLl9vcmRlci5zbGljZSgpO1xuICAgIH1cblxuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuX2dyb3Vwcy5rZXlzKCkpO1xuICB9XG5cbiAgZ2V0R3JvdXBzKCkge1xuICAgIHJldHVybiB0aGlzLl9ncm91cHMuc2l6ZSA+IDAgPyAoMCwgX3V0aWwub2JqZWN0RnJvbU1hcCkodGhpcy5fZ3JvdXBzKSA6IG51bGw7XG4gIH1cblxuICBnZXRHcm91cChpZCkge1xuICAgIHJldHVybiB0aGlzLl9ncm91cHMuZ2V0KGlkKSB8fCBudWxsO1xuICB9XG5cbn1cblxuZXhwb3J0cy5PcHRpb25hbENvbnRlbnRDb25maWcgPSBPcHRpb25hbENvbnRlbnRDb25maWc7XG5cbi8qKiovIH0pLFxuLyogMTcgKi9cbi8qKiovICgoX191bnVzZWRfd2VicGFja19tb2R1bGUsIGV4cG9ydHMsIF9fd19wZGZqc19yZXF1aXJlX18pID0+IHtcblxuXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgKHtcbiAgdmFsdWU6IHRydWVcbn0pKTtcbmV4cG9ydHMuUERGRGF0YVRyYW5zcG9ydFN0cmVhbSA9IHZvaWQgMDtcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxudmFyIF9kaXNwbGF5X3V0aWxzID0gX193X3BkZmpzX3JlcXVpcmVfXyg1KTtcblxuY2xhc3MgUERGRGF0YVRyYW5zcG9ydFN0cmVhbSB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtcywgcGRmRGF0YVJhbmdlVHJhbnNwb3J0KSB7XG4gICAgKDAsIF91dGlsLmFzc2VydCkocGRmRGF0YVJhbmdlVHJhbnNwb3J0LCAnUERGRGF0YVRyYW5zcG9ydFN0cmVhbSAtIG1pc3NpbmcgcmVxdWlyZWQgXCJwZGZEYXRhUmFuZ2VUcmFuc3BvcnRcIiBhcmd1bWVudC4nKTtcbiAgICB0aGlzLl9xdWV1ZWRDaHVua3MgPSBbXTtcbiAgICB0aGlzLl9wcm9ncmVzc2l2ZURvbmUgPSBwYXJhbXMucHJvZ3Jlc3NpdmVEb25lIHx8IGZhbHNlO1xuICAgIHRoaXMuX2NvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lID0gcGFyYW1zLmNvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lIHx8IG51bGw7XG4gICAgY29uc3QgaW5pdGlhbERhdGEgPSBwYXJhbXMuaW5pdGlhbERhdGE7XG5cbiAgICBpZiAoaW5pdGlhbERhdGE/Lmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KGluaXRpYWxEYXRhKS5idWZmZXI7XG5cbiAgICAgIHRoaXMuX3F1ZXVlZENodW5rcy5wdXNoKGJ1ZmZlcik7XG4gICAgfVxuXG4gICAgdGhpcy5fcGRmRGF0YVJhbmdlVHJhbnNwb3J0ID0gcGRmRGF0YVJhbmdlVHJhbnNwb3J0O1xuICAgIHRoaXMuX2lzU3RyZWFtaW5nU3VwcG9ydGVkID0gIXBhcmFtcy5kaXNhYmxlU3RyZWFtO1xuICAgIHRoaXMuX2lzUmFuZ2VTdXBwb3J0ZWQgPSAhcGFyYW1zLmRpc2FibGVSYW5nZTtcbiAgICB0aGlzLl9jb250ZW50TGVuZ3RoID0gcGFyYW1zLmxlbmd0aDtcbiAgICB0aGlzLl9mdWxsUmVxdWVzdFJlYWRlciA9IG51bGw7XG4gICAgdGhpcy5fcmFuZ2VSZWFkZXJzID0gW107XG5cbiAgICB0aGlzLl9wZGZEYXRhUmFuZ2VUcmFuc3BvcnQuYWRkUmFuZ2VMaXN0ZW5lcigoYmVnaW4sIGNodW5rKSA9PiB7XG4gICAgICB0aGlzLl9vblJlY2VpdmVEYXRhKHtcbiAgICAgICAgYmVnaW4sXG4gICAgICAgIGNodW5rXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRoaXMuX3BkZkRhdGFSYW5nZVRyYW5zcG9ydC5hZGRQcm9ncmVzc0xpc3RlbmVyKChsb2FkZWQsIHRvdGFsKSA9PiB7XG4gICAgICB0aGlzLl9vblByb2dyZXNzKHtcbiAgICAgICAgbG9hZGVkLFxuICAgICAgICB0b3RhbFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLl9wZGZEYXRhUmFuZ2VUcmFuc3BvcnQuYWRkUHJvZ3Jlc3NpdmVSZWFkTGlzdGVuZXIoY2h1bmsgPT4ge1xuICAgICAgdGhpcy5fb25SZWNlaXZlRGF0YSh7XG4gICAgICAgIGNodW5rXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRoaXMuX3BkZkRhdGFSYW5nZVRyYW5zcG9ydC5hZGRQcm9ncmVzc2l2ZURvbmVMaXN0ZW5lcigoKSA9PiB7XG4gICAgICB0aGlzLl9vblByb2dyZXNzaXZlRG9uZSgpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5fcGRmRGF0YVJhbmdlVHJhbnNwb3J0LnRyYW5zcG9ydFJlYWR5KCk7XG4gIH1cblxuICBfb25SZWNlaXZlRGF0YShhcmdzKSB7XG4gICAgY29uc3QgYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkoYXJncy5jaHVuaykuYnVmZmVyO1xuXG4gICAgaWYgKGFyZ3MuYmVnaW4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHRoaXMuX2Z1bGxSZXF1ZXN0UmVhZGVyKSB7XG4gICAgICAgIHRoaXMuX2Z1bGxSZXF1ZXN0UmVhZGVyLl9lbnF1ZXVlKGJ1ZmZlcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9xdWV1ZWRDaHVua3MucHVzaChidWZmZXIpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBmb3VuZCA9IHRoaXMuX3JhbmdlUmVhZGVycy5zb21lKGZ1bmN0aW9uIChyYW5nZVJlYWRlcikge1xuICAgICAgICBpZiAocmFuZ2VSZWFkZXIuX2JlZ2luICE9PSBhcmdzLmJlZ2luKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmFuZ2VSZWFkZXIuX2VucXVldWUoYnVmZmVyKTtcblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0pO1xuXG4gICAgICAoMCwgX3V0aWwuYXNzZXJ0KShmb3VuZCwgXCJfb25SZWNlaXZlRGF0YSAtIG5vIGBQREZEYXRhVHJhbnNwb3J0U3RyZWFtUmFuZ2VSZWFkZXJgIGluc3RhbmNlIGZvdW5kLlwiKTtcbiAgICB9XG4gIH1cblxuICBnZXQgX3Byb2dyZXNzaXZlRGF0YUxlbmd0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZnVsbFJlcXVlc3RSZWFkZXI/Ll9sb2FkZWQgPz8gMDtcbiAgfVxuXG4gIF9vblByb2dyZXNzKGV2dCkge1xuICAgIGlmIChldnQudG90YWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgZmlyc3RSZWFkZXIgPSB0aGlzLl9yYW5nZVJlYWRlcnNbMF07XG5cbiAgICAgIGlmIChmaXJzdFJlYWRlcj8ub25Qcm9ncmVzcykge1xuICAgICAgICBmaXJzdFJlYWRlci5vblByb2dyZXNzKHtcbiAgICAgICAgICBsb2FkZWQ6IGV2dC5sb2FkZWRcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGZ1bGxSZWFkZXIgPSB0aGlzLl9mdWxsUmVxdWVzdFJlYWRlcjtcblxuICAgICAgaWYgKGZ1bGxSZWFkZXI/Lm9uUHJvZ3Jlc3MpIHtcbiAgICAgICAgZnVsbFJlYWRlci5vblByb2dyZXNzKHtcbiAgICAgICAgICBsb2FkZWQ6IGV2dC5sb2FkZWQsXG4gICAgICAgICAgdG90YWw6IGV2dC50b3RhbFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBfb25Qcm9ncmVzc2l2ZURvbmUoKSB7XG4gICAgaWYgKHRoaXMuX2Z1bGxSZXF1ZXN0UmVhZGVyKSB7XG4gICAgICB0aGlzLl9mdWxsUmVxdWVzdFJlYWRlci5wcm9ncmVzc2l2ZURvbmUoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9wcm9ncmVzc2l2ZURvbmUgPSB0cnVlO1xuICB9XG5cbiAgX3JlbW92ZVJhbmdlUmVhZGVyKHJlYWRlcikge1xuICAgIGNvbnN0IGkgPSB0aGlzLl9yYW5nZVJlYWRlcnMuaW5kZXhPZihyZWFkZXIpO1xuXG4gICAgaWYgKGkgPj0gMCkge1xuICAgICAgdGhpcy5fcmFuZ2VSZWFkZXJzLnNwbGljZShpLCAxKTtcbiAgICB9XG4gIH1cblxuICBnZXRGdWxsUmVhZGVyKCkge1xuICAgICgwLCBfdXRpbC5hc3NlcnQpKCF0aGlzLl9mdWxsUmVxdWVzdFJlYWRlciwgXCJQREZEYXRhVHJhbnNwb3J0U3RyZWFtLmdldEZ1bGxSZWFkZXIgY2FuIG9ubHkgYmUgY2FsbGVkIG9uY2UuXCIpO1xuICAgIGNvbnN0IHF1ZXVlZENodW5rcyA9IHRoaXMuX3F1ZXVlZENodW5rcztcbiAgICB0aGlzLl9xdWV1ZWRDaHVua3MgPSBudWxsO1xuICAgIHJldHVybiBuZXcgUERGRGF0YVRyYW5zcG9ydFN0cmVhbVJlYWRlcih0aGlzLCBxdWV1ZWRDaHVua3MsIHRoaXMuX3Byb2dyZXNzaXZlRG9uZSwgdGhpcy5fY29udGVudERpc3Bvc2l0aW9uRmlsZW5hbWUpO1xuICB9XG5cbiAgZ2V0UmFuZ2VSZWFkZXIoYmVnaW4sIGVuZCkge1xuICAgIGlmIChlbmQgPD0gdGhpcy5fcHJvZ3Jlc3NpdmVEYXRhTGVuZ3RoKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCByZWFkZXIgPSBuZXcgUERGRGF0YVRyYW5zcG9ydFN0cmVhbVJhbmdlUmVhZGVyKHRoaXMsIGJlZ2luLCBlbmQpO1xuXG4gICAgdGhpcy5fcGRmRGF0YVJhbmdlVHJhbnNwb3J0LnJlcXVlc3REYXRhUmFuZ2UoYmVnaW4sIGVuZCk7XG5cbiAgICB0aGlzLl9yYW5nZVJlYWRlcnMucHVzaChyZWFkZXIpO1xuXG4gICAgcmV0dXJuIHJlYWRlcjtcbiAgfVxuXG4gIGNhbmNlbEFsbFJlcXVlc3RzKHJlYXNvbikge1xuICAgIGlmICh0aGlzLl9mdWxsUmVxdWVzdFJlYWRlcikge1xuICAgICAgdGhpcy5fZnVsbFJlcXVlc3RSZWFkZXIuY2FuY2VsKHJlYXNvbik7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCByZWFkZXIgb2YgdGhpcy5fcmFuZ2VSZWFkZXJzLnNsaWNlKDApKSB7XG4gICAgICByZWFkZXIuY2FuY2VsKHJlYXNvbik7XG4gICAgfVxuXG4gICAgdGhpcy5fcGRmRGF0YVJhbmdlVHJhbnNwb3J0LmFib3J0KCk7XG4gIH1cblxufVxuXG5leHBvcnRzLlBERkRhdGFUcmFuc3BvcnRTdHJlYW0gPSBQREZEYXRhVHJhbnNwb3J0U3RyZWFtO1xuXG5jbGFzcyBQREZEYXRhVHJhbnNwb3J0U3RyZWFtUmVhZGVyIHtcbiAgY29uc3RydWN0b3Ioc3RyZWFtLCBxdWV1ZWRDaHVua3MsIHByb2dyZXNzaXZlRG9uZSA9IGZhbHNlLCBjb250ZW50RGlzcG9zaXRpb25GaWxlbmFtZSA9IG51bGwpIHtcbiAgICB0aGlzLl9zdHJlYW0gPSBzdHJlYW07XG4gICAgdGhpcy5fZG9uZSA9IHByb2dyZXNzaXZlRG9uZSB8fCBmYWxzZTtcbiAgICB0aGlzLl9maWxlbmFtZSA9ICgwLCBfZGlzcGxheV91dGlscy5pc1BkZkZpbGUpKGNvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lKSA/IGNvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lIDogbnVsbDtcbiAgICB0aGlzLl9xdWV1ZWRDaHVua3MgPSBxdWV1ZWRDaHVua3MgfHwgW107XG4gICAgdGhpcy5fbG9hZGVkID0gMDtcblxuICAgIGZvciAoY29uc3QgY2h1bmsgb2YgdGhpcy5fcXVldWVkQ2h1bmtzKSB7XG4gICAgICB0aGlzLl9sb2FkZWQgKz0gY2h1bmsuYnl0ZUxlbmd0aDtcbiAgICB9XG5cbiAgICB0aGlzLl9yZXF1ZXN0cyA9IFtdO1xuICAgIHRoaXMuX2hlYWRlcnNSZWFkeSA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIHN0cmVhbS5fZnVsbFJlcXVlc3RSZWFkZXIgPSB0aGlzO1xuICAgIHRoaXMub25Qcm9ncmVzcyA9IG51bGw7XG4gIH1cblxuICBfZW5xdWV1ZShjaHVuaykge1xuICAgIGlmICh0aGlzLl9kb25lKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3JlcXVlc3RzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IHJlcXVlc3RDYXBhYmlsaXR5ID0gdGhpcy5fcmVxdWVzdHMuc2hpZnQoKTtcblxuICAgICAgcmVxdWVzdENhcGFiaWxpdHkucmVzb2x2ZSh7XG4gICAgICAgIHZhbHVlOiBjaHVuayxcbiAgICAgICAgZG9uZTogZmFsc2VcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9xdWV1ZWRDaHVua3MucHVzaChjaHVuayk7XG4gICAgfVxuXG4gICAgdGhpcy5fbG9hZGVkICs9IGNodW5rLmJ5dGVMZW5ndGg7XG4gIH1cblxuICBnZXQgaGVhZGVyc1JlYWR5KCkge1xuICAgIHJldHVybiB0aGlzLl9oZWFkZXJzUmVhZHk7XG4gIH1cblxuICBnZXQgZmlsZW5hbWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2ZpbGVuYW1lO1xuICB9XG5cbiAgZ2V0IGlzUmFuZ2VTdXBwb3J0ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0cmVhbS5faXNSYW5nZVN1cHBvcnRlZDtcbiAgfVxuXG4gIGdldCBpc1N0cmVhbWluZ1N1cHBvcnRlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fc3RyZWFtLl9pc1N0cmVhbWluZ1N1cHBvcnRlZDtcbiAgfVxuXG4gIGdldCBjb250ZW50TGVuZ3RoKCkge1xuICAgIHJldHVybiB0aGlzLl9zdHJlYW0uX2NvbnRlbnRMZW5ndGg7XG4gIH1cblxuICBhc3luYyByZWFkKCkge1xuICAgIGlmICh0aGlzLl9xdWV1ZWRDaHVua3MubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgY2h1bmsgPSB0aGlzLl9xdWV1ZWRDaHVua3Muc2hpZnQoKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWU6IGNodW5rLFxuICAgICAgICBkb25lOiBmYWxzZVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZG9uZSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgICAgZG9uZTogdHJ1ZVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCByZXF1ZXN0Q2FwYWJpbGl0eSA9ICgwLCBfdXRpbC5jcmVhdGVQcm9taXNlQ2FwYWJpbGl0eSkoKTtcblxuICAgIHRoaXMuX3JlcXVlc3RzLnB1c2gocmVxdWVzdENhcGFiaWxpdHkpO1xuXG4gICAgcmV0dXJuIHJlcXVlc3RDYXBhYmlsaXR5LnByb21pc2U7XG4gIH1cblxuICBjYW5jZWwocmVhc29uKSB7XG4gICAgdGhpcy5fZG9uZSA9IHRydWU7XG5cbiAgICBmb3IgKGNvbnN0IHJlcXVlc3RDYXBhYmlsaXR5IG9mIHRoaXMuX3JlcXVlc3RzKSB7XG4gICAgICByZXF1ZXN0Q2FwYWJpbGl0eS5yZXNvbHZlKHtcbiAgICAgICAgdmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgICAgZG9uZTogdHJ1ZVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5fcmVxdWVzdHMubGVuZ3RoID0gMDtcbiAgfVxuXG4gIHByb2dyZXNzaXZlRG9uZSgpIHtcbiAgICBpZiAodGhpcy5fZG9uZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2RvbmUgPSB0cnVlO1xuICB9XG5cbn1cblxuY2xhc3MgUERGRGF0YVRyYW5zcG9ydFN0cmVhbVJhbmdlUmVhZGVyIHtcbiAgY29uc3RydWN0b3Ioc3RyZWFtLCBiZWdpbiwgZW5kKSB7XG4gICAgdGhpcy5fc3RyZWFtID0gc3RyZWFtO1xuICAgIHRoaXMuX2JlZ2luID0gYmVnaW47XG4gICAgdGhpcy5fZW5kID0gZW5kO1xuICAgIHRoaXMuX3F1ZXVlZENodW5rID0gbnVsbDtcbiAgICB0aGlzLl9yZXF1ZXN0cyA9IFtdO1xuICAgIHRoaXMuX2RvbmUgPSBmYWxzZTtcbiAgICB0aGlzLm9uUHJvZ3Jlc3MgPSBudWxsO1xuICB9XG5cbiAgX2VucXVldWUoY2h1bmspIHtcbiAgICBpZiAodGhpcy5fZG9uZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9yZXF1ZXN0cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMuX3F1ZXVlZENodW5rID0gY2h1bms7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHJlcXVlc3RzQ2FwYWJpbGl0eSA9IHRoaXMuX3JlcXVlc3RzLnNoaWZ0KCk7XG5cbiAgICAgIHJlcXVlc3RzQ2FwYWJpbGl0eS5yZXNvbHZlKHtcbiAgICAgICAgdmFsdWU6IGNodW5rLFxuICAgICAgICBkb25lOiBmYWxzZVxuICAgICAgfSk7XG5cbiAgICAgIGZvciAoY29uc3QgcmVxdWVzdENhcGFiaWxpdHkgb2YgdGhpcy5fcmVxdWVzdHMpIHtcbiAgICAgICAgcmVxdWVzdENhcGFiaWxpdHkucmVzb2x2ZSh7XG4gICAgICAgICAgdmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgICAgICBkb25lOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9yZXF1ZXN0cy5sZW5ndGggPSAwO1xuICAgIH1cblxuICAgIHRoaXMuX2RvbmUgPSB0cnVlO1xuXG4gICAgdGhpcy5fc3RyZWFtLl9yZW1vdmVSYW5nZVJlYWRlcih0aGlzKTtcbiAgfVxuXG4gIGdldCBpc1N0cmVhbWluZ1N1cHBvcnRlZCgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBhc3luYyByZWFkKCkge1xuICAgIGlmICh0aGlzLl9xdWV1ZWRDaHVuaykge1xuICAgICAgY29uc3QgY2h1bmsgPSB0aGlzLl9xdWV1ZWRDaHVuaztcbiAgICAgIHRoaXMuX3F1ZXVlZENodW5rID0gbnVsbDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbHVlOiBjaHVuayxcbiAgICAgICAgZG9uZTogZmFsc2VcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2RvbmUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbHVlOiB1bmRlZmluZWQsXG4gICAgICAgIGRvbmU6IHRydWVcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgcmVxdWVzdENhcGFiaWxpdHkgPSAoMCwgX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkpKCk7XG5cbiAgICB0aGlzLl9yZXF1ZXN0cy5wdXNoKHJlcXVlc3RDYXBhYmlsaXR5KTtcblxuICAgIHJldHVybiByZXF1ZXN0Q2FwYWJpbGl0eS5wcm9taXNlO1xuICB9XG5cbiAgY2FuY2VsKHJlYXNvbikge1xuICAgIHRoaXMuX2RvbmUgPSB0cnVlO1xuXG4gICAgZm9yIChjb25zdCByZXF1ZXN0Q2FwYWJpbGl0eSBvZiB0aGlzLl9yZXF1ZXN0cykge1xuICAgICAgcmVxdWVzdENhcGFiaWxpdHkucmVzb2x2ZSh7XG4gICAgICAgIHZhbHVlOiB1bmRlZmluZWQsXG4gICAgICAgIGRvbmU6IHRydWVcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuX3JlcXVlc3RzLmxlbmd0aCA9IDA7XG5cbiAgICB0aGlzLl9zdHJlYW0uX3JlbW92ZVJhbmdlUmVhZGVyKHRoaXMpO1xuICB9XG5cbn1cblxuLyoqKi8gfSksXG4vKiAxOCAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5YZmFUZXh0ID0gdm9pZCAwO1xuXG5jbGFzcyBYZmFUZXh0IHtcbiAgc3RhdGljIHRleHRDb250ZW50KHhmYSkge1xuICAgIGNvbnN0IGl0ZW1zID0gW107XG4gICAgY29uc3Qgb3V0cHV0ID0ge1xuICAgICAgaXRlbXMsXG4gICAgICBzdHlsZXM6IE9iamVjdC5jcmVhdGUobnVsbClcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gd2Fsayhub2RlKSB7XG4gICAgICBpZiAoIW5vZGUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBsZXQgc3RyID0gbnVsbDtcbiAgICAgIGNvbnN0IG5hbWUgPSBub2RlLm5hbWU7XG5cbiAgICAgIGlmIChuYW1lID09PSBcIiN0ZXh0XCIpIHtcbiAgICAgICAgc3RyID0gbm9kZS52YWx1ZTtcbiAgICAgIH0gZWxzZSBpZiAoIVhmYVRleHQuc2hvdWxkQnVpbGRUZXh0KG5hbWUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSBpZiAobm9kZT8uYXR0cmlidXRlcz8udGV4dENvbnRlbnQpIHtcbiAgICAgICAgc3RyID0gbm9kZS5hdHRyaWJ1dGVzLnRleHRDb250ZW50O1xuICAgICAgfSBlbHNlIGlmIChub2RlLnZhbHVlKSB7XG4gICAgICAgIHN0ciA9IG5vZGUudmFsdWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChzdHIgIT09IG51bGwpIHtcbiAgICAgICAgaXRlbXMucHVzaCh7XG4gICAgICAgICAgc3RyXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoIW5vZGUuY2hpbGRyZW4pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIG5vZGUuY2hpbGRyZW4pIHtcbiAgICAgICAgd2FsayhjaGlsZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgd2Fsayh4ZmEpO1xuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cblxuICBzdGF0aWMgc2hvdWxkQnVpbGRUZXh0KG5hbWUpIHtcbiAgICByZXR1cm4gIShuYW1lID09PSBcInRleHRhcmVhXCIgfHwgbmFtZSA9PT0gXCJpbnB1dFwiIHx8IG5hbWUgPT09IFwib3B0aW9uXCIgfHwgbmFtZSA9PT0gXCJzZWxlY3RcIik7XG4gIH1cblxufVxuXG5leHBvcnRzLlhmYVRleHQgPSBYZmFUZXh0O1xuXG4vKioqLyB9KSxcbi8qIDE5ICovXG4vKioqLyAoKF9fdW51c2VkX3dlYnBhY2tfbW9kdWxlLCBleHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5leHBvcnRzLk5vZGVTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSA9IGV4cG9ydHMuTm9kZUNhbnZhc0ZhY3RvcnkgPSBleHBvcnRzLk5vZGVDTWFwUmVhZGVyRmFjdG9yeSA9IHZvaWQgMDtcblxudmFyIF9iYXNlX2ZhY3RvcnkgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDYpO1xuXG47XG5cbmNvbnN0IGZldGNoRGF0YSA9IGZ1bmN0aW9uICh1cmwpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBmcyA9IHJlcXVpcmUoXCJmc1wiKTtcblxuICAgIGZzLnJlYWRGaWxlKHVybCwgKGVycm9yLCBkYXRhKSA9PiB7XG4gICAgICBpZiAoZXJyb3IgfHwgIWRhdGEpIHtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihlcnJvcikpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHJlc29sdmUobmV3IFVpbnQ4QXJyYXkoZGF0YSkpO1xuICAgIH0pO1xuICB9KTtcbn07XG5cbmNsYXNzIE5vZGVDYW52YXNGYWN0b3J5IGV4dGVuZHMgX2Jhc2VfZmFjdG9yeS5CYXNlQ2FudmFzRmFjdG9yeSB7XG4gIF9jcmVhdGVDYW52YXMod2lkdGgsIGhlaWdodCkge1xuICAgIGNvbnN0IENhbnZhcyA9IHJlcXVpcmUoXCJjYW52YXNcIik7XG5cbiAgICByZXR1cm4gQ2FudmFzLmNyZWF0ZUNhbnZhcyh3aWR0aCwgaGVpZ2h0KTtcbiAgfVxuXG59XG5cbmV4cG9ydHMuTm9kZUNhbnZhc0ZhY3RvcnkgPSBOb2RlQ2FudmFzRmFjdG9yeTtcblxuY2xhc3MgTm9kZUNNYXBSZWFkZXJGYWN0b3J5IGV4dGVuZHMgX2Jhc2VfZmFjdG9yeS5CYXNlQ01hcFJlYWRlckZhY3Rvcnkge1xuICBfZmV0Y2hEYXRhKHVybCwgY29tcHJlc3Npb25UeXBlKSB7XG4gICAgcmV0dXJuIGZldGNoRGF0YSh1cmwpLnRoZW4oZGF0YSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjTWFwRGF0YTogZGF0YSxcbiAgICAgICAgY29tcHJlc3Npb25UeXBlXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbn1cblxuZXhwb3J0cy5Ob2RlQ01hcFJlYWRlckZhY3RvcnkgPSBOb2RlQ01hcFJlYWRlckZhY3Rvcnk7XG5cbmNsYXNzIE5vZGVTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSBleHRlbmRzIF9iYXNlX2ZhY3RvcnkuQmFzZVN0YW5kYXJkRm9udERhdGFGYWN0b3J5IHtcbiAgX2ZldGNoRGF0YSh1cmwpIHtcbiAgICByZXR1cm4gZmV0Y2hEYXRhKHVybCk7XG4gIH1cblxufVxuXG5leHBvcnRzLk5vZGVTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSA9IE5vZGVTdGFuZGFyZEZvbnREYXRhRmFjdG9yeTtcblxuLyoqKi8gfSksXG4vKiAyMCAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5Bbm5vdGF0aW9uTGF5ZXIgPSB2b2lkIDA7XG5cbnZhciBfdXRpbCA9IF9fd19wZGZqc19yZXF1aXJlX18oMSk7XG5cbnZhciBfZGlzcGxheV91dGlscyA9IF9fd19wZGZqc19yZXF1aXJlX18oNSk7XG5cbnZhciBfYW5ub3RhdGlvbl9zdG9yYWdlID0gX193X3BkZmpzX3JlcXVpcmVfXyg4KTtcblxudmFyIF9zY3JpcHRpbmdfdXRpbHMgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDIxKTtcblxudmFyIF94ZmFfbGF5ZXIgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDIyKTtcblxuY29uc3QgREVGQVVMVF9UQUJfSU5ERVggPSAxMDAwO1xuY29uc3QgR2V0RWxlbWVudHNCeU5hbWVTZXQgPSBuZXcgV2Vha1NldCgpO1xuXG5mdW5jdGlvbiBnZXRSZWN0RGltcyhyZWN0KSB7XG4gIHJldHVybiB7XG4gICAgd2lkdGg6IHJlY3RbMl0gLSByZWN0WzBdLFxuICAgIGhlaWdodDogcmVjdFszXSAtIHJlY3RbMV1cbiAgfTtcbn1cblxuY2xhc3MgQW5ub3RhdGlvbkVsZW1lbnRGYWN0b3J5IHtcbiAgc3RhdGljIGNyZWF0ZShwYXJhbWV0ZXJzKSB7XG4gICAgY29uc3Qgc3VidHlwZSA9IHBhcmFtZXRlcnMuZGF0YS5hbm5vdGF0aW9uVHlwZTtcblxuICAgIHN3aXRjaCAoc3VidHlwZSkge1xuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uVHlwZS5MSU5LOlxuICAgICAgICByZXR1cm4gbmV3IExpbmtBbm5vdGF0aW9uRWxlbWVudChwYXJhbWV0ZXJzKTtcblxuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uVHlwZS5URVhUOlxuICAgICAgICByZXR1cm4gbmV3IFRleHRBbm5vdGF0aW9uRWxlbWVudChwYXJhbWV0ZXJzKTtcblxuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uVHlwZS5XSURHRVQ6XG4gICAgICAgIGNvbnN0IGZpZWxkVHlwZSA9IHBhcmFtZXRlcnMuZGF0YS5maWVsZFR5cGU7XG5cbiAgICAgICAgc3dpdGNoIChmaWVsZFR5cGUpIHtcbiAgICAgICAgICBjYXNlIFwiVHhcIjpcbiAgICAgICAgICAgIHJldHVybiBuZXcgVGV4dFdpZGdldEFubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuXG4gICAgICAgICAgY2FzZSBcIkJ0blwiOlxuICAgICAgICAgICAgaWYgKHBhcmFtZXRlcnMuZGF0YS5yYWRpb0J1dHRvbikge1xuICAgICAgICAgICAgICByZXR1cm4gbmV3IFJhZGlvQnV0dG9uV2lkZ2V0QW5ub3RhdGlvbkVsZW1lbnQocGFyYW1ldGVycyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHBhcmFtZXRlcnMuZGF0YS5jaGVja0JveCkge1xuICAgICAgICAgICAgICByZXR1cm4gbmV3IENoZWNrYm94V2lkZ2V0QW5ub3RhdGlvbkVsZW1lbnQocGFyYW1ldGVycyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBuZXcgUHVzaEJ1dHRvbldpZGdldEFubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuXG4gICAgICAgICAgY2FzZSBcIkNoXCI6XG4gICAgICAgICAgICByZXR1cm4gbmV3IENob2ljZVdpZGdldEFubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBXaWRnZXRBbm5vdGF0aW9uRWxlbWVudChwYXJhbWV0ZXJzKTtcblxuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uVHlwZS5QT1BVUDpcbiAgICAgICAgcmV0dXJuIG5ldyBQb3B1cEFubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuXG4gICAgICBjYXNlIF91dGlsLkFubm90YXRpb25UeXBlLkZSRUVURVhUOlxuICAgICAgICByZXR1cm4gbmV3IEZyZWVUZXh0QW5ub3RhdGlvbkVsZW1lbnQocGFyYW1ldGVycyk7XG5cbiAgICAgIGNhc2UgX3V0aWwuQW5ub3RhdGlvblR5cGUuTElORTpcbiAgICAgICAgcmV0dXJuIG5ldyBMaW5lQW5ub3RhdGlvbkVsZW1lbnQocGFyYW1ldGVycyk7XG5cbiAgICAgIGNhc2UgX3V0aWwuQW5ub3RhdGlvblR5cGUuU1FVQVJFOlxuICAgICAgICByZXR1cm4gbmV3IFNxdWFyZUFubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuXG4gICAgICBjYXNlIF91dGlsLkFubm90YXRpb25UeXBlLkNJUkNMRTpcbiAgICAgICAgcmV0dXJuIG5ldyBDaXJjbGVBbm5vdGF0aW9uRWxlbWVudChwYXJhbWV0ZXJzKTtcblxuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uVHlwZS5QT0xZTElORTpcbiAgICAgICAgcmV0dXJuIG5ldyBQb2x5bGluZUFubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuXG4gICAgICBjYXNlIF91dGlsLkFubm90YXRpb25UeXBlLkNBUkVUOlxuICAgICAgICByZXR1cm4gbmV3IENhcmV0QW5ub3RhdGlvbkVsZW1lbnQocGFyYW1ldGVycyk7XG5cbiAgICAgIGNhc2UgX3V0aWwuQW5ub3RhdGlvblR5cGUuSU5LOlxuICAgICAgICByZXR1cm4gbmV3IElua0Fubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuXG4gICAgICBjYXNlIF91dGlsLkFubm90YXRpb25UeXBlLlBPTFlHT046XG4gICAgICAgIHJldHVybiBuZXcgUG9seWdvbkFubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuXG4gICAgICBjYXNlIF91dGlsLkFubm90YXRpb25UeXBlLkhJR0hMSUdIVDpcbiAgICAgICAgcmV0dXJuIG5ldyBIaWdobGlnaHRBbm5vdGF0aW9uRWxlbWVudChwYXJhbWV0ZXJzKTtcblxuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uVHlwZS5VTkRFUkxJTkU6XG4gICAgICAgIHJldHVybiBuZXcgVW5kZXJsaW5lQW5ub3RhdGlvbkVsZW1lbnQocGFyYW1ldGVycyk7XG5cbiAgICAgIGNhc2UgX3V0aWwuQW5ub3RhdGlvblR5cGUuU1FVSUdHTFk6XG4gICAgICAgIHJldHVybiBuZXcgU3F1aWdnbHlBbm5vdGF0aW9uRWxlbWVudChwYXJhbWV0ZXJzKTtcblxuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uVHlwZS5TVFJJS0VPVVQ6XG4gICAgICAgIHJldHVybiBuZXcgU3RyaWtlT3V0QW5ub3RhdGlvbkVsZW1lbnQocGFyYW1ldGVycyk7XG5cbiAgICAgIGNhc2UgX3V0aWwuQW5ub3RhdGlvblR5cGUuU1RBTVA6XG4gICAgICAgIHJldHVybiBuZXcgU3RhbXBBbm5vdGF0aW9uRWxlbWVudChwYXJhbWV0ZXJzKTtcblxuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uVHlwZS5GSUxFQVRUQUNITUVOVDpcbiAgICAgICAgcmV0dXJuIG5ldyBGaWxlQXR0YWNobWVudEFubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gbmV3IEFubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuICAgIH1cbiAgfVxuXG59XG5cbmNsYXNzIEFubm90YXRpb25FbGVtZW50IHtcbiAgY29uc3RydWN0b3IocGFyYW1ldGVycywge1xuICAgIGlzUmVuZGVyYWJsZSA9IGZhbHNlLFxuICAgIGlnbm9yZUJvcmRlciA9IGZhbHNlLFxuICAgIGNyZWF0ZVF1YWRyaWxhdGVyYWxzID0gZmFsc2VcbiAgfSA9IHt9KSB7XG4gICAgdGhpcy5pc1JlbmRlcmFibGUgPSBpc1JlbmRlcmFibGU7XG4gICAgdGhpcy5kYXRhID0gcGFyYW1ldGVycy5kYXRhO1xuICAgIHRoaXMubGF5ZXIgPSBwYXJhbWV0ZXJzLmxheWVyO1xuICAgIHRoaXMucGFnZSA9IHBhcmFtZXRlcnMucGFnZTtcbiAgICB0aGlzLnZpZXdwb3J0ID0gcGFyYW1ldGVycy52aWV3cG9ydDtcbiAgICB0aGlzLmxpbmtTZXJ2aWNlID0gcGFyYW1ldGVycy5saW5rU2VydmljZTtcbiAgICB0aGlzLmRvd25sb2FkTWFuYWdlciA9IHBhcmFtZXRlcnMuZG93bmxvYWRNYW5hZ2VyO1xuICAgIHRoaXMuaW1hZ2VSZXNvdXJjZXNQYXRoID0gcGFyYW1ldGVycy5pbWFnZVJlc291cmNlc1BhdGg7XG4gICAgdGhpcy5yZW5kZXJGb3JtcyA9IHBhcmFtZXRlcnMucmVuZGVyRm9ybXM7XG4gICAgdGhpcy5zdmdGYWN0b3J5ID0gcGFyYW1ldGVycy5zdmdGYWN0b3J5O1xuICAgIHRoaXMuYW5ub3RhdGlvblN0b3JhZ2UgPSBwYXJhbWV0ZXJzLmFubm90YXRpb25TdG9yYWdlO1xuICAgIHRoaXMuZW5hYmxlU2NyaXB0aW5nID0gcGFyYW1ldGVycy5lbmFibGVTY3JpcHRpbmc7XG4gICAgdGhpcy5oYXNKU0FjdGlvbnMgPSBwYXJhbWV0ZXJzLmhhc0pTQWN0aW9ucztcbiAgICB0aGlzLl9maWVsZE9iamVjdHMgPSBwYXJhbWV0ZXJzLmZpZWxkT2JqZWN0cztcbiAgICB0aGlzLl9tb3VzZVN0YXRlID0gcGFyYW1ldGVycy5tb3VzZVN0YXRlO1xuXG4gICAgaWYgKGlzUmVuZGVyYWJsZSkge1xuICAgICAgdGhpcy5jb250YWluZXIgPSB0aGlzLl9jcmVhdGVDb250YWluZXIoaWdub3JlQm9yZGVyKTtcbiAgICB9XG5cbiAgICBpZiAoY3JlYXRlUXVhZHJpbGF0ZXJhbHMpIHtcbiAgICAgIHRoaXMucXVhZHJpbGF0ZXJhbHMgPSB0aGlzLl9jcmVhdGVRdWFkcmlsYXRlcmFscyhpZ25vcmVCb3JkZXIpO1xuICAgIH1cbiAgfVxuXG4gIF9jcmVhdGVDb250YWluZXIoaWdub3JlQm9yZGVyID0gZmFsc2UpIHtcbiAgICBjb25zdCBkYXRhID0gdGhpcy5kYXRhLFxuICAgICAgICAgIHBhZ2UgPSB0aGlzLnBhZ2UsXG4gICAgICAgICAgdmlld3BvcnQgPSB0aGlzLnZpZXdwb3J0O1xuICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzZWN0aW9uXCIpO1xuICAgIGxldCB7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodFxuICAgIH0gPSBnZXRSZWN0RGltcyhkYXRhLnJlY3QpO1xuICAgIGNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJkYXRhLWFubm90YXRpb24taWRcIiwgZGF0YS5pZCk7XG5cbiAgICBjb25zdCByZWN0ID0gX3V0aWwuVXRpbC5ub3JtYWxpemVSZWN0KFtkYXRhLnJlY3RbMF0sIHBhZ2Uudmlld1szXSAtIGRhdGEucmVjdFsxXSArIHBhZ2Uudmlld1sxXSwgZGF0YS5yZWN0WzJdLCBwYWdlLnZpZXdbM10gLSBkYXRhLnJlY3RbM10gKyBwYWdlLnZpZXdbMV1dKTtcblxuICAgIGlmIChkYXRhLmhhc093bkNhbnZhcykge1xuICAgICAgY29uc3QgdHJhbnNmb3JtID0gdmlld3BvcnQudHJhbnNmb3JtLnNsaWNlKCk7XG5cbiAgICAgIGNvbnN0IFtzY2FsZVgsIHNjYWxlWV0gPSBfdXRpbC5VdGlsLnNpbmd1bGFyVmFsdWVEZWNvbXBvc2UyZFNjYWxlKHRyYW5zZm9ybSk7XG5cbiAgICAgIHdpZHRoID0gTWF0aC5jZWlsKHdpZHRoICogc2NhbGVYKTtcbiAgICAgIGhlaWdodCA9IE1hdGguY2VpbChoZWlnaHQgKiBzY2FsZVkpO1xuICAgICAgcmVjdFswXSAqPSBzY2FsZVg7XG4gICAgICByZWN0WzFdICo9IHNjYWxlWTtcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICAgICAgdHJhbnNmb3JtW2ldID0gTWF0aC5zaWduKHRyYW5zZm9ybVtpXSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnRhaW5lci5zdHlsZS50cmFuc2Zvcm0gPSBgbWF0cml4KCR7dHJhbnNmb3JtLmpvaW4oXCIsXCIpfSlgO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250YWluZXIuc3R5bGUudHJhbnNmb3JtID0gYG1hdHJpeCgke3ZpZXdwb3J0LnRyYW5zZm9ybS5qb2luKFwiLFwiKX0pYDtcbiAgICB9XG5cbiAgICBjb250YWluZXIuc3R5bGUudHJhbnNmb3JtT3JpZ2luID0gYCR7LXJlY3RbMF19cHggJHstcmVjdFsxXX1weGA7XG5cbiAgICBpZiAoIWlnbm9yZUJvcmRlciAmJiBkYXRhLmJvcmRlclN0eWxlLndpZHRoID4gMCkge1xuICAgICAgY29udGFpbmVyLnN0eWxlLmJvcmRlcldpZHRoID0gYCR7ZGF0YS5ib3JkZXJTdHlsZS53aWR0aH1weGA7XG5cbiAgICAgIGlmIChkYXRhLmJvcmRlclN0eWxlLnN0eWxlICE9PSBfdXRpbC5Bbm5vdGF0aW9uQm9yZGVyU3R5bGVUeXBlLlVOREVSTElORSkge1xuICAgICAgICB3aWR0aCAtPSAyICogZGF0YS5ib3JkZXJTdHlsZS53aWR0aDtcbiAgICAgICAgaGVpZ2h0IC09IDIgKiBkYXRhLmJvcmRlclN0eWxlLndpZHRoO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBob3Jpem9udGFsUmFkaXVzID0gZGF0YS5ib3JkZXJTdHlsZS5ob3Jpem9udGFsQ29ybmVyUmFkaXVzO1xuICAgICAgY29uc3QgdmVydGljYWxSYWRpdXMgPSBkYXRhLmJvcmRlclN0eWxlLnZlcnRpY2FsQ29ybmVyUmFkaXVzO1xuXG4gICAgICBpZiAoaG9yaXpvbnRhbFJhZGl1cyA+IDAgfHwgdmVydGljYWxSYWRpdXMgPiAwKSB7XG4gICAgICAgIGNvbnN0IHJhZGl1cyA9IGAke2hvcml6b250YWxSYWRpdXN9cHggLyAke3ZlcnRpY2FsUmFkaXVzfXB4YDtcbiAgICAgICAgY29udGFpbmVyLnN0eWxlLmJvcmRlclJhZGl1cyA9IHJhZGl1cztcbiAgICAgIH1cblxuICAgICAgc3dpdGNoIChkYXRhLmJvcmRlclN0eWxlLnN0eWxlKSB7XG4gICAgICAgIGNhc2UgX3V0aWwuQW5ub3RhdGlvbkJvcmRlclN0eWxlVHlwZS5TT0xJRDpcbiAgICAgICAgICBjb250YWluZXIuc3R5bGUuYm9yZGVyU3R5bGUgPSBcInNvbGlkXCI7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uQm9yZGVyU3R5bGVUeXBlLkRBU0hFRDpcbiAgICAgICAgICBjb250YWluZXIuc3R5bGUuYm9yZGVyU3R5bGUgPSBcImRhc2hlZFwiO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgX3V0aWwuQW5ub3RhdGlvbkJvcmRlclN0eWxlVHlwZS5CRVZFTEVEOlxuICAgICAgICAgICgwLCBfdXRpbC53YXJuKShcIlVuaW1wbGVtZW50ZWQgYm9yZGVyIHN0eWxlOiBiZXZlbGVkXCIpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgX3V0aWwuQW5ub3RhdGlvbkJvcmRlclN0eWxlVHlwZS5JTlNFVDpcbiAgICAgICAgICAoMCwgX3V0aWwud2FybikoXCJVbmltcGxlbWVudGVkIGJvcmRlciBzdHlsZTogaW5zZXRcIik7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uQm9yZGVyU3R5bGVUeXBlLlVOREVSTElORTpcbiAgICAgICAgICBjb250YWluZXIuc3R5bGUuYm9yZGVyQm90dG9tU3R5bGUgPSBcInNvbGlkXCI7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY29uc3QgYm9yZGVyQ29sb3IgPSBkYXRhLmJvcmRlckNvbG9yIHx8IGRhdGEuY29sb3IgfHwgbnVsbDtcblxuICAgICAgaWYgKGJvcmRlckNvbG9yKSB7XG4gICAgICAgIGNvbnRhaW5lci5zdHlsZS5ib3JkZXJDb2xvciA9IF91dGlsLlV0aWwubWFrZUhleENvbG9yKGRhdGEuY29sb3JbMF0gfCAwLCBkYXRhLmNvbG9yWzFdIHwgMCwgZGF0YS5jb2xvclsyXSB8IDApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29udGFpbmVyLnN0eWxlLmJvcmRlcldpZHRoID0gMDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb250YWluZXIuc3R5bGUubGVmdCA9IGAke3JlY3RbMF19cHhgO1xuICAgIGNvbnRhaW5lci5zdHlsZS50b3AgPSBgJHtyZWN0WzFdfXB4YDtcblxuICAgIGlmIChkYXRhLmhhc093bkNhbnZhcykge1xuICAgICAgY29udGFpbmVyLnN0eWxlLndpZHRoID0gY29udGFpbmVyLnN0eWxlLmhlaWdodCA9IFwiYXV0b1wiO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250YWluZXIuc3R5bGUud2lkdGggPSBgJHt3aWR0aH1weGA7XG4gICAgICBjb250YWluZXIuc3R5bGUuaGVpZ2h0ID0gYCR7aGVpZ2h0fXB4YDtcbiAgICB9XG5cbiAgICByZXR1cm4gY29udGFpbmVyO1xuICB9XG5cbiAgZ2V0IF9jb21tb25BY3Rpb25zKCkge1xuICAgIGNvbnN0IHNldENvbG9yID0gKGpzTmFtZSwgc3R5bGVOYW1lLCBldmVudCkgPT4ge1xuICAgICAgY29uc3QgY29sb3IgPSBldmVudC5kZXRhaWxbanNOYW1lXTtcbiAgICAgIGV2ZW50LnRhcmdldC5zdHlsZVtzdHlsZU5hbWVdID0gX3NjcmlwdGluZ191dGlscy5Db2xvckNvbnZlcnRlcnNbYCR7Y29sb3JbMF19X0hUTUxgXShjb2xvci5zbGljZSgxKSk7XG4gICAgfTtcblxuICAgIHJldHVybiAoMCwgX3V0aWwuc2hhZG93KSh0aGlzLCBcIl9jb21tb25BY3Rpb25zXCIsIHtcbiAgICAgIGRpc3BsYXk6IGV2ZW50ID0+IHtcbiAgICAgICAgY29uc3QgaGlkZGVuID0gZXZlbnQuZGV0YWlsLmRpc3BsYXkgJSAyID09PSAxO1xuICAgICAgICBldmVudC50YXJnZXQuc3R5bGUudmlzaWJpbGl0eSA9IGhpZGRlbiA/IFwiaGlkZGVuXCIgOiBcInZpc2libGVcIjtcbiAgICAgICAgdGhpcy5hbm5vdGF0aW9uU3RvcmFnZS5zZXRWYWx1ZSh0aGlzLmRhdGEuaWQsIHtcbiAgICAgICAgICBoaWRkZW4sXG4gICAgICAgICAgcHJpbnQ6IGV2ZW50LmRldGFpbC5kaXNwbGF5ID09PSAwIHx8IGV2ZW50LmRldGFpbC5kaXNwbGF5ID09PSAzXG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICAgIHByaW50OiBldmVudCA9PiB7XG4gICAgICAgIHRoaXMuYW5ub3RhdGlvblN0b3JhZ2Uuc2V0VmFsdWUodGhpcy5kYXRhLmlkLCB7XG4gICAgICAgICAgcHJpbnQ6IGV2ZW50LmRldGFpbC5wcmludFxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICBoaWRkZW46IGV2ZW50ID0+IHtcbiAgICAgICAgZXZlbnQudGFyZ2V0LnN0eWxlLnZpc2liaWxpdHkgPSBldmVudC5kZXRhaWwuaGlkZGVuID8gXCJoaWRkZW5cIiA6IFwidmlzaWJsZVwiO1xuICAgICAgICB0aGlzLmFubm90YXRpb25TdG9yYWdlLnNldFZhbHVlKHRoaXMuZGF0YS5pZCwge1xuICAgICAgICAgIGhpZGRlbjogZXZlbnQuZGV0YWlsLmhpZGRlblxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICBmb2N1czogZXZlbnQgPT4ge1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IGV2ZW50LnRhcmdldC5mb2N1cyh7XG4gICAgICAgICAgcHJldmVudFNjcm9sbDogZmFsc2VcbiAgICAgICAgfSksIDApO1xuICAgICAgfSxcbiAgICAgIHVzZXJOYW1lOiBldmVudCA9PiB7XG4gICAgICAgIGV2ZW50LnRhcmdldC50aXRsZSA9IGV2ZW50LmRldGFpbC51c2VyTmFtZTtcbiAgICAgIH0sXG4gICAgICByZWFkb25seTogZXZlbnQgPT4ge1xuICAgICAgICBpZiAoZXZlbnQuZGV0YWlsLnJlYWRvbmx5KSB7XG4gICAgICAgICAgZXZlbnQudGFyZ2V0LnNldEF0dHJpYnV0ZShcInJlYWRvbmx5XCIsIFwiXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGV2ZW50LnRhcmdldC5yZW1vdmVBdHRyaWJ1dGUoXCJyZWFkb25seVwiKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBldmVudCA9PiB7XG4gICAgICAgIGlmIChldmVudC5kZXRhaWwucmVxdWlyZWQpIHtcbiAgICAgICAgICBldmVudC50YXJnZXQuc2V0QXR0cmlidXRlKFwicmVxdWlyZWRcIiwgXCJcIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZXZlbnQudGFyZ2V0LnJlbW92ZUF0dHJpYnV0ZShcInJlcXVpcmVkXCIpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgYmdDb2xvcjogZXZlbnQgPT4ge1xuICAgICAgICBzZXRDb2xvcihcImJnQ29sb3JcIiwgXCJiYWNrZ3JvdW5kQ29sb3JcIiwgZXZlbnQpO1xuICAgICAgfSxcbiAgICAgIGZpbGxDb2xvcjogZXZlbnQgPT4ge1xuICAgICAgICBzZXRDb2xvcihcImZpbGxDb2xvclwiLCBcImJhY2tncm91bmRDb2xvclwiLCBldmVudCk7XG4gICAgICB9LFxuICAgICAgZmdDb2xvcjogZXZlbnQgPT4ge1xuICAgICAgICBzZXRDb2xvcihcImZnQ29sb3JcIiwgXCJjb2xvclwiLCBldmVudCk7XG4gICAgICB9LFxuICAgICAgdGV4dENvbG9yOiBldmVudCA9PiB7XG4gICAgICAgIHNldENvbG9yKFwidGV4dENvbG9yXCIsIFwiY29sb3JcIiwgZXZlbnQpO1xuICAgICAgfSxcbiAgICAgIGJvcmRlckNvbG9yOiBldmVudCA9PiB7XG4gICAgICAgIHNldENvbG9yKFwiYm9yZGVyQ29sb3JcIiwgXCJib3JkZXJDb2xvclwiLCBldmVudCk7XG4gICAgICB9LFxuICAgICAgc3Ryb2tlQ29sb3I6IGV2ZW50ID0+IHtcbiAgICAgICAgc2V0Q29sb3IoXCJzdHJva2VDb2xvclwiLCBcImJvcmRlckNvbG9yXCIsIGV2ZW50KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIF9kaXNwYXRjaEV2ZW50RnJvbVNhbmRib3goYWN0aW9ucywganNFdmVudCkge1xuICAgIGNvbnN0IGNvbW1vbkFjdGlvbnMgPSB0aGlzLl9jb21tb25BY3Rpb25zO1xuXG4gICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKGpzRXZlbnQuZGV0YWlsKSkge1xuICAgICAgY29uc3QgYWN0aW9uID0gYWN0aW9uc1tuYW1lXSB8fCBjb21tb25BY3Rpb25zW25hbWVdO1xuXG4gICAgICBpZiAoYWN0aW9uKSB7XG4gICAgICAgIGFjdGlvbihqc0V2ZW50KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBfc2V0RGVmYXVsdFByb3BlcnRpZXNGcm9tSlMoZWxlbWVudCkge1xuICAgIGlmICghdGhpcy5lbmFibGVTY3JpcHRpbmcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzdG9yZWREYXRhID0gdGhpcy5hbm5vdGF0aW9uU3RvcmFnZS5nZXRSYXdWYWx1ZSh0aGlzLmRhdGEuaWQpO1xuXG4gICAgaWYgKCFzdG9yZWREYXRhKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY29tbW9uQWN0aW9ucyA9IHRoaXMuX2NvbW1vbkFjdGlvbnM7XG5cbiAgICBmb3IgKGNvbnN0IFthY3Rpb25OYW1lLCBkZXRhaWxdIG9mIE9iamVjdC5lbnRyaWVzKHN0b3JlZERhdGEpKSB7XG4gICAgICBjb25zdCBhY3Rpb24gPSBjb21tb25BY3Rpb25zW2FjdGlvbk5hbWVdO1xuXG4gICAgICBpZiAoYWN0aW9uKSB7XG4gICAgICAgIGFjdGlvbih7XG4gICAgICAgICAgZGV0YWlsLFxuICAgICAgICAgIHRhcmdldDogZWxlbWVudFxuICAgICAgICB9KTtcbiAgICAgICAgZGVsZXRlIHN0b3JlZERhdGFbYWN0aW9uTmFtZV07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgX2NyZWF0ZVF1YWRyaWxhdGVyYWxzKGlnbm9yZUJvcmRlciA9IGZhbHNlKSB7XG4gICAgaWYgKCF0aGlzLmRhdGEucXVhZFBvaW50cykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgcXVhZHJpbGF0ZXJhbHMgPSBbXTtcbiAgICBjb25zdCBzYXZlZFJlY3QgPSB0aGlzLmRhdGEucmVjdDtcblxuICAgIGZvciAoY29uc3QgcXVhZFBvaW50IG9mIHRoaXMuZGF0YS5xdWFkUG9pbnRzKSB7XG4gICAgICB0aGlzLmRhdGEucmVjdCA9IFtxdWFkUG9pbnRbMl0ueCwgcXVhZFBvaW50WzJdLnksIHF1YWRQb2ludFsxXS54LCBxdWFkUG9pbnRbMV0ueV07XG4gICAgICBxdWFkcmlsYXRlcmFscy5wdXNoKHRoaXMuX2NyZWF0ZUNvbnRhaW5lcihpZ25vcmVCb3JkZXIpKTtcbiAgICB9XG5cbiAgICB0aGlzLmRhdGEucmVjdCA9IHNhdmVkUmVjdDtcbiAgICByZXR1cm4gcXVhZHJpbGF0ZXJhbHM7XG4gIH1cblxuICBfY3JlYXRlUG9wdXAodHJpZ2dlciwgZGF0YSkge1xuICAgIGxldCBjb250YWluZXIgPSB0aGlzLmNvbnRhaW5lcjtcblxuICAgIGlmICh0aGlzLnF1YWRyaWxhdGVyYWxzKSB7XG4gICAgICB0cmlnZ2VyID0gdHJpZ2dlciB8fCB0aGlzLnF1YWRyaWxhdGVyYWxzO1xuICAgICAgY29udGFpbmVyID0gdGhpcy5xdWFkcmlsYXRlcmFsc1swXTtcbiAgICB9XG5cbiAgICBpZiAoIXRyaWdnZXIpIHtcbiAgICAgIHRyaWdnZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgdHJpZ2dlci5zdHlsZS5oZWlnaHQgPSBjb250YWluZXIuc3R5bGUuaGVpZ2h0O1xuICAgICAgdHJpZ2dlci5zdHlsZS53aWR0aCA9IGNvbnRhaW5lci5zdHlsZS53aWR0aDtcbiAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZCh0cmlnZ2VyKTtcbiAgICB9XG5cbiAgICBjb25zdCBwb3B1cEVsZW1lbnQgPSBuZXcgUG9wdXBFbGVtZW50KHtcbiAgICAgIGNvbnRhaW5lcixcbiAgICAgIHRyaWdnZXIsXG4gICAgICBjb2xvcjogZGF0YS5jb2xvcixcbiAgICAgIHRpdGxlT2JqOiBkYXRhLnRpdGxlT2JqLFxuICAgICAgbW9kaWZpY2F0aW9uRGF0ZTogZGF0YS5tb2RpZmljYXRpb25EYXRlLFxuICAgICAgY29udGVudHNPYmo6IGRhdGEuY29udGVudHNPYmosXG4gICAgICByaWNoVGV4dDogZGF0YS5yaWNoVGV4dCxcbiAgICAgIGhpZGVXcmFwcGVyOiB0cnVlXG4gICAgfSk7XG4gICAgY29uc3QgcG9wdXAgPSBwb3B1cEVsZW1lbnQucmVuZGVyKCk7XG4gICAgcG9wdXAuc3R5bGUubGVmdCA9IGNvbnRhaW5lci5zdHlsZS53aWR0aDtcbiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQocG9wdXApO1xuICB9XG5cbiAgX3JlbmRlclF1YWRyaWxhdGVyYWxzKGNsYXNzTmFtZSkge1xuICAgIGZvciAoY29uc3QgcXVhZHJpbGF0ZXJhbCBvZiB0aGlzLnF1YWRyaWxhdGVyYWxzKSB7XG4gICAgICBxdWFkcmlsYXRlcmFsLmNsYXNzTmFtZSA9IGNsYXNzTmFtZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5xdWFkcmlsYXRlcmFscztcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiQWJzdHJhY3QgbWV0aG9kIGBBbm5vdGF0aW9uRWxlbWVudC5yZW5kZXJgIGNhbGxlZFwiKTtcbiAgfVxuXG4gIF9nZXRFbGVtZW50c0J5TmFtZShuYW1lLCBza2lwSWQgPSBudWxsKSB7XG4gICAgY29uc3QgZmllbGRzID0gW107XG5cbiAgICBpZiAodGhpcy5fZmllbGRPYmplY3RzKSB7XG4gICAgICBjb25zdCBmaWVsZE9iaiA9IHRoaXMuX2ZpZWxkT2JqZWN0c1tuYW1lXTtcblxuICAgICAgaWYgKGZpZWxkT2JqKSB7XG4gICAgICAgIGZvciAoY29uc3Qge1xuICAgICAgICAgIHBhZ2UsXG4gICAgICAgICAgaWQsXG4gICAgICAgICAgZXhwb3J0VmFsdWVzXG4gICAgICAgIH0gb2YgZmllbGRPYmopIHtcbiAgICAgICAgICBpZiAocGFnZSA9PT0gLTEpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChpZCA9PT0gc2tpcElkKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBleHBvcnRWYWx1ZSA9IHR5cGVvZiBleHBvcnRWYWx1ZXMgPT09IFwic3RyaW5nXCIgPyBleHBvcnRWYWx1ZXMgOiBudWxsO1xuICAgICAgICAgIGNvbnN0IGRvbUVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7XG5cbiAgICAgICAgICBpZiAoZG9tRWxlbWVudCAmJiAhR2V0RWxlbWVudHNCeU5hbWVTZXQuaGFzKGRvbUVsZW1lbnQpKSB7XG4gICAgICAgICAgICAoMCwgX3V0aWwud2FybikoYF9nZXRFbGVtZW50c0J5TmFtZSAtIGVsZW1lbnQgbm90IGFsbG93ZWQ6ICR7aWR9YCk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmaWVsZHMucHVzaCh7XG4gICAgICAgICAgICBpZCxcbiAgICAgICAgICAgIGV4cG9ydFZhbHVlLFxuICAgICAgICAgICAgZG9tRWxlbWVudFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmaWVsZHM7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBkb21FbGVtZW50IG9mIGRvY3VtZW50LmdldEVsZW1lbnRzQnlOYW1lKG5hbWUpKSB7XG4gICAgICBjb25zdCB7XG4gICAgICAgIGlkLFxuICAgICAgICBleHBvcnRWYWx1ZVxuICAgICAgfSA9IGRvbUVsZW1lbnQ7XG5cbiAgICAgIGlmIChpZCA9PT0gc2tpcElkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoIUdldEVsZW1lbnRzQnlOYW1lU2V0Lmhhcyhkb21FbGVtZW50KSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgZmllbGRzLnB1c2goe1xuICAgICAgICBpZCxcbiAgICAgICAgZXhwb3J0VmFsdWUsXG4gICAgICAgIGRvbUVsZW1lbnRcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBmaWVsZHM7XG4gIH1cblxuICBzdGF0aWMgZ2V0IHBsYXRmb3JtKCkge1xuICAgIGNvbnN0IHBsYXRmb3JtID0gdHlwZW9mIG5hdmlnYXRvciAhPT0gXCJ1bmRlZmluZWRcIiA/IG5hdmlnYXRvci5wbGF0Zm9ybSA6IFwiXCI7XG4gICAgcmV0dXJuICgwLCBfdXRpbC5zaGFkb3cpKHRoaXMsIFwicGxhdGZvcm1cIiwge1xuICAgICAgaXNXaW46IHBsYXRmb3JtLmluY2x1ZGVzKFwiV2luXCIpLFxuICAgICAgaXNNYWM6IHBsYXRmb3JtLmluY2x1ZGVzKFwiTWFjXCIpXG4gICAgfSk7XG4gIH1cblxufVxuXG5jbGFzcyBMaW5rQW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMsIG9wdGlvbnMgPSBudWxsKSB7XG4gICAgY29uc3QgaXNSZW5kZXJhYmxlID0gISEocGFyYW1ldGVycy5kYXRhLnVybCB8fCBwYXJhbWV0ZXJzLmRhdGEuZGVzdCB8fCBwYXJhbWV0ZXJzLmRhdGEuYWN0aW9uIHx8IHBhcmFtZXRlcnMuZGF0YS5pc1Rvb2x0aXBPbmx5IHx8IHBhcmFtZXRlcnMuZGF0YS5yZXNldEZvcm0gfHwgcGFyYW1ldGVycy5kYXRhLmFjdGlvbnMgJiYgKHBhcmFtZXRlcnMuZGF0YS5hY3Rpb25zLkFjdGlvbiB8fCBwYXJhbWV0ZXJzLmRhdGEuYWN0aW9uc1tcIk1vdXNlIFVwXCJdIHx8IHBhcmFtZXRlcnMuZGF0YS5hY3Rpb25zW1wiTW91c2UgRG93blwiXSkpO1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlzUmVuZGVyYWJsZSxcbiAgICAgIGlnbm9yZUJvcmRlcjogISFvcHRpb25zPy5pZ25vcmVCb3JkZXIsXG4gICAgICBjcmVhdGVRdWFkcmlsYXRlcmFsczogdHJ1ZVxuICAgIH0pO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGNvbnN0IHtcbiAgICAgIGRhdGEsXG4gICAgICBsaW5rU2VydmljZVxuICAgIH0gPSB0aGlzO1xuICAgIGNvbnN0IGxpbmsgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYVwiKTtcblxuICAgIGlmIChkYXRhLnVybCkge1xuICAgICAgbGlua1NlcnZpY2UuYWRkTGlua0F0dHJpYnV0ZXMobGluaywgZGF0YS51cmwsIGRhdGEubmV3V2luZG93KTtcbiAgICB9IGVsc2UgaWYgKGRhdGEuYWN0aW9uKSB7XG4gICAgICB0aGlzLl9iaW5kTmFtZWRBY3Rpb24obGluaywgZGF0YS5hY3Rpb24pO1xuICAgIH0gZWxzZSBpZiAoZGF0YS5kZXN0KSB7XG4gICAgICB0aGlzLl9iaW5kTGluayhsaW5rLCBkYXRhLmRlc3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgaGFzQ2xpY2tBY3Rpb24gPSBmYWxzZTtcblxuICAgICAgaWYgKGRhdGEuYWN0aW9ucyAmJiAoZGF0YS5hY3Rpb25zLkFjdGlvbiB8fCBkYXRhLmFjdGlvbnNbXCJNb3VzZSBVcFwiXSB8fCBkYXRhLmFjdGlvbnNbXCJNb3VzZSBEb3duXCJdKSAmJiB0aGlzLmVuYWJsZVNjcmlwdGluZyAmJiB0aGlzLmhhc0pTQWN0aW9ucykge1xuICAgICAgICBoYXNDbGlja0FjdGlvbiA9IHRydWU7XG5cbiAgICAgICAgdGhpcy5fYmluZEpTQWN0aW9uKGxpbmssIGRhdGEpO1xuICAgICAgfVxuXG4gICAgICBpZiAoZGF0YS5yZXNldEZvcm0pIHtcbiAgICAgICAgdGhpcy5fYmluZFJlc2V0Rm9ybUFjdGlvbihsaW5rLCBkYXRhLnJlc2V0Rm9ybSk7XG4gICAgICB9IGVsc2UgaWYgKCFoYXNDbGlja0FjdGlvbikge1xuICAgICAgICB0aGlzLl9iaW5kTGluayhsaW5rLCBcIlwiKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5xdWFkcmlsYXRlcmFscykge1xuICAgICAgcmV0dXJuIHRoaXMuX3JlbmRlclF1YWRyaWxhdGVyYWxzKFwibGlua0Fubm90YXRpb25cIikubWFwKChxdWFkcmlsYXRlcmFsLCBpbmRleCkgPT4ge1xuICAgICAgICBjb25zdCBsaW5rRWxlbWVudCA9IGluZGV4ID09PSAwID8gbGluayA6IGxpbmsuY2xvbmVOb2RlKCk7XG4gICAgICAgIHF1YWRyaWxhdGVyYWwuYXBwZW5kQ2hpbGQobGlua0VsZW1lbnQpO1xuICAgICAgICByZXR1cm4gcXVhZHJpbGF0ZXJhbDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IFwibGlua0Fubm90YXRpb25cIjtcbiAgICB0aGlzLmNvbnRhaW5lci5hcHBlbmRDaGlsZChsaW5rKTtcbiAgICByZXR1cm4gdGhpcy5jb250YWluZXI7XG4gIH1cblxuICBfYmluZExpbmsobGluaywgZGVzdGluYXRpb24pIHtcbiAgICBsaW5rLmhyZWYgPSB0aGlzLmxpbmtTZXJ2aWNlLmdldERlc3RpbmF0aW9uSGFzaChkZXN0aW5hdGlvbik7XG5cbiAgICBsaW5rLm9uY2xpY2sgPSAoKSA9PiB7XG4gICAgICBpZiAoZGVzdGluYXRpb24pIHtcbiAgICAgICAgdGhpcy5saW5rU2VydmljZS5nb1RvRGVzdGluYXRpb24oZGVzdGluYXRpb24pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIGlmIChkZXN0aW5hdGlvbiB8fCBkZXN0aW5hdGlvbiA9PT0gXCJcIikge1xuICAgICAgbGluay5jbGFzc05hbWUgPSBcImludGVybmFsTGlua1wiO1xuICAgIH1cbiAgfVxuXG4gIF9iaW5kTmFtZWRBY3Rpb24obGluaywgYWN0aW9uKSB7XG4gICAgbGluay5ocmVmID0gdGhpcy5saW5rU2VydmljZS5nZXRBbmNob3JVcmwoXCJcIik7XG5cbiAgICBsaW5rLm9uY2xpY2sgPSAoKSA9PiB7XG4gICAgICB0aGlzLmxpbmtTZXJ2aWNlLmV4ZWN1dGVOYW1lZEFjdGlvbihhY3Rpb24pO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG5cbiAgICBsaW5rLmNsYXNzTmFtZSA9IFwiaW50ZXJuYWxMaW5rXCI7XG4gIH1cblxuICBfYmluZEpTQWN0aW9uKGxpbmssIGRhdGEpIHtcbiAgICBsaW5rLmhyZWYgPSB0aGlzLmxpbmtTZXJ2aWNlLmdldEFuY2hvclVybChcIlwiKTtcbiAgICBjb25zdCBtYXAgPSBuZXcgTWFwKFtbXCJBY3Rpb25cIiwgXCJvbmNsaWNrXCJdLCBbXCJNb3VzZSBVcFwiLCBcIm9ubW91c2V1cFwiXSwgW1wiTW91c2UgRG93blwiLCBcIm9ubW91c2Vkb3duXCJdXSk7XG5cbiAgICBmb3IgKGNvbnN0IG5hbWUgb2YgT2JqZWN0LmtleXMoZGF0YS5hY3Rpb25zKSkge1xuICAgICAgY29uc3QganNOYW1lID0gbWFwLmdldChuYW1lKTtcblxuICAgICAgaWYgKCFqc05hbWUpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGxpbmtbanNOYW1lXSA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5saW5rU2VydmljZS5ldmVudEJ1cz8uZGlzcGF0Y2goXCJkaXNwYXRjaGV2ZW50aW5zYW5kYm94XCIsIHtcbiAgICAgICAgICBzb3VyY2U6IHRoaXMsXG4gICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICBpZDogZGF0YS5pZCxcbiAgICAgICAgICAgIG5hbWVcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICghbGluay5vbmNsaWNrKSB7XG4gICAgICBsaW5rLm9uY2xpY2sgPSAoKSA9PiBmYWxzZTtcbiAgICB9XG5cbiAgICBsaW5rLmNsYXNzTmFtZSA9IFwiaW50ZXJuYWxMaW5rXCI7XG4gIH1cblxuICBfYmluZFJlc2V0Rm9ybUFjdGlvbihsaW5rLCByZXNldEZvcm0pIHtcbiAgICBjb25zdCBvdGhlckNsaWNrQWN0aW9uID0gbGluay5vbmNsaWNrO1xuXG4gICAgaWYgKCFvdGhlckNsaWNrQWN0aW9uKSB7XG4gICAgICBsaW5rLmhyZWYgPSB0aGlzLmxpbmtTZXJ2aWNlLmdldEFuY2hvclVybChcIlwiKTtcbiAgICB9XG5cbiAgICBsaW5rLmNsYXNzTmFtZSA9IFwiaW50ZXJuYWxMaW5rXCI7XG5cbiAgICBpZiAoIXRoaXMuX2ZpZWxkT2JqZWN0cykge1xuICAgICAgKDAsIF91dGlsLndhcm4pKGBfYmluZFJlc2V0Rm9ybUFjdGlvbiAtIFwicmVzZXRGb3JtXCIgYWN0aW9uIG5vdCBzdXBwb3J0ZWQsIGAgKyBcImVuc3VyZSB0aGF0IHRoZSBgZmllbGRPYmplY3RzYCBwYXJhbWV0ZXIgaXMgcHJvdmlkZWQuXCIpO1xuXG4gICAgICBpZiAoIW90aGVyQ2xpY2tBY3Rpb24pIHtcbiAgICAgICAgbGluay5vbmNsaWNrID0gKCkgPT4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsaW5rLm9uY2xpY2sgPSAoKSA9PiB7XG4gICAgICBpZiAob3RoZXJDbGlja0FjdGlvbikge1xuICAgICAgICBvdGhlckNsaWNrQWN0aW9uKCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHtcbiAgICAgICAgZmllbGRzOiByZXNldEZvcm1GaWVsZHMsXG4gICAgICAgIHJlZnM6IHJlc2V0Rm9ybVJlZnMsXG4gICAgICAgIGluY2x1ZGVcbiAgICAgIH0gPSByZXNldEZvcm07XG4gICAgICBjb25zdCBhbGxGaWVsZHMgPSBbXTtcblxuICAgICAgaWYgKHJlc2V0Rm9ybUZpZWxkcy5sZW5ndGggIT09IDAgfHwgcmVzZXRGb3JtUmVmcy5sZW5ndGggIT09IDApIHtcbiAgICAgICAgY29uc3QgZmllbGRJZHMgPSBuZXcgU2V0KHJlc2V0Rm9ybVJlZnMpO1xuXG4gICAgICAgIGZvciAoY29uc3QgZmllbGROYW1lIG9mIHJlc2V0Rm9ybUZpZWxkcykge1xuICAgICAgICAgIGNvbnN0IGZpZWxkcyA9IHRoaXMuX2ZpZWxkT2JqZWN0c1tmaWVsZE5hbWVdIHx8IFtdO1xuXG4gICAgICAgICAgZm9yIChjb25zdCB7XG4gICAgICAgICAgICBpZFxuICAgICAgICAgIH0gb2YgZmllbGRzKSB7XG4gICAgICAgICAgICBmaWVsZElkcy5hZGQoaWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgZmllbGRzIG9mIE9iamVjdC52YWx1ZXModGhpcy5fZmllbGRPYmplY3RzKSkge1xuICAgICAgICAgIGZvciAoY29uc3QgZmllbGQgb2YgZmllbGRzKSB7XG4gICAgICAgICAgICBpZiAoZmllbGRJZHMuaGFzKGZpZWxkLmlkKSA9PT0gaW5jbHVkZSkge1xuICAgICAgICAgICAgICBhbGxGaWVsZHMucHVzaChmaWVsZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGNvbnN0IGZpZWxkcyBvZiBPYmplY3QudmFsdWVzKHRoaXMuX2ZpZWxkT2JqZWN0cykpIHtcbiAgICAgICAgICBhbGxGaWVsZHMucHVzaCguLi5maWVsZHMpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHN0b3JhZ2UgPSB0aGlzLmFubm90YXRpb25TdG9yYWdlO1xuICAgICAgY29uc3QgYWxsSWRzID0gW107XG5cbiAgICAgIGZvciAoY29uc3QgZmllbGQgb2YgYWxsRmllbGRzKSB7XG4gICAgICAgIGNvbnN0IHtcbiAgICAgICAgICBpZFxuICAgICAgICB9ID0gZmllbGQ7XG4gICAgICAgIGFsbElkcy5wdXNoKGlkKTtcblxuICAgICAgICBzd2l0Y2ggKGZpZWxkLnR5cGUpIHtcbiAgICAgICAgICBjYXNlIFwidGV4dFwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGZpZWxkLmRlZmF1bHRWYWx1ZSB8fCBcIlwiO1xuICAgICAgICAgICAgICBzdG9yYWdlLnNldFZhbHVlKGlkLCB7XG4gICAgICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgY2FzZSBcImNoZWNrYm94XCI6XG4gICAgICAgICAgY2FzZSBcInJhZGlvYnV0dG9uXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gZmllbGQuZGVmYXVsdFZhbHVlID09PSBmaWVsZC5leHBvcnRWYWx1ZXM7XG4gICAgICAgICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICAgICAgICB2YWx1ZVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICBjYXNlIFwiY29tYm9ib3hcIjpcbiAgICAgICAgICBjYXNlIFwibGlzdGJveFwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGZpZWxkLmRlZmF1bHRWYWx1ZSB8fCBcIlwiO1xuICAgICAgICAgICAgICBzdG9yYWdlLnNldFZhbHVlKGlkLCB7XG4gICAgICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZG9tRWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTtcblxuICAgICAgICBpZiAoIWRvbUVsZW1lbnQgfHwgIUdldEVsZW1lbnRzQnlOYW1lU2V0Lmhhcyhkb21FbGVtZW50KSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgZG9tRWxlbWVudC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcInJlc2V0Zm9ybVwiKSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmVuYWJsZVNjcmlwdGluZykge1xuICAgICAgICB0aGlzLmxpbmtTZXJ2aWNlLmV2ZW50QnVzPy5kaXNwYXRjaChcImRpc3BhdGNoZXZlbnRpbnNhbmRib3hcIiwge1xuICAgICAgICAgIHNvdXJjZTogdGhpcyxcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIGlkOiBcImFwcFwiLFxuICAgICAgICAgICAgaWRzOiBhbGxJZHMsXG4gICAgICAgICAgICBuYW1lOiBcIlJlc2V0Rm9ybVwiXG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG4gIH1cblxufVxuXG5jbGFzcyBUZXh0QW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCBpc1JlbmRlcmFibGUgPSAhIShwYXJhbWV0ZXJzLmRhdGEuaGFzUG9wdXAgfHwgcGFyYW1ldGVycy5kYXRhLnRpdGxlT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLmNvbnRlbnRzT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLnJpY2hUZXh0Py5zdHIpO1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlzUmVuZGVyYWJsZVxuICAgIH0pO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IFwidGV4dEFubm90YXRpb25cIjtcbiAgICBjb25zdCBpbWFnZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbWdcIik7XG4gICAgaW1hZ2Uuc3R5bGUuaGVpZ2h0ID0gdGhpcy5jb250YWluZXIuc3R5bGUuaGVpZ2h0O1xuICAgIGltYWdlLnN0eWxlLndpZHRoID0gdGhpcy5jb250YWluZXIuc3R5bGUud2lkdGg7XG4gICAgaW1hZ2Uuc3JjID0gdGhpcy5pbWFnZVJlc291cmNlc1BhdGggKyBcImFubm90YXRpb24tXCIgKyB0aGlzLmRhdGEubmFtZS50b0xvd2VyQ2FzZSgpICsgXCIuc3ZnXCI7XG4gICAgaW1hZ2UuYWx0ID0gXCJbe3t0eXBlfX0gQW5ub3RhdGlvbl1cIjtcbiAgICBpbWFnZS5kYXRhc2V0LmwxMG5JZCA9IFwidGV4dF9hbm5vdGF0aW9uX3R5cGVcIjtcbiAgICBpbWFnZS5kYXRhc2V0LmwxMG5BcmdzID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgdHlwZTogdGhpcy5kYXRhLm5hbWVcbiAgICB9KTtcblxuICAgIGlmICghdGhpcy5kYXRhLmhhc1BvcHVwKSB7XG4gICAgICB0aGlzLl9jcmVhdGVQb3B1cChpbWFnZSwgdGhpcy5kYXRhKTtcbiAgICB9XG5cbiAgICB0aGlzLmNvbnRhaW5lci5hcHBlbmRDaGlsZChpbWFnZSk7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgV2lkZ2V0QW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBBbm5vdGF0aW9uRWxlbWVudCB7XG4gIHJlbmRlcigpIHtcbiAgICBpZiAodGhpcy5kYXRhLmFsdGVybmF0aXZlVGV4dCkge1xuICAgICAgdGhpcy5jb250YWluZXIudGl0bGUgPSB0aGlzLmRhdGEuYWx0ZXJuYXRpdmVUZXh0O1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbnRhaW5lcjtcbiAgfVxuXG4gIF9nZXRLZXlNb2RpZmllcihldmVudCkge1xuICAgIGNvbnN0IHtcbiAgICAgIGlzV2luLFxuICAgICAgaXNNYWNcbiAgICB9ID0gQW5ub3RhdGlvbkVsZW1lbnQucGxhdGZvcm07XG4gICAgcmV0dXJuIGlzV2luICYmIGV2ZW50LmN0cmxLZXkgfHwgaXNNYWMgJiYgZXZlbnQubWV0YUtleTtcbiAgfVxuXG4gIF9zZXRFdmVudExpc3RlbmVyKGVsZW1lbnQsIGJhc2VOYW1lLCBldmVudE5hbWUsIHZhbHVlR2V0dGVyKSB7XG4gICAgaWYgKGJhc2VOYW1lLmluY2x1ZGVzKFwibW91c2VcIikpIHtcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihiYXNlTmFtZSwgZXZlbnQgPT4ge1xuICAgICAgICB0aGlzLmxpbmtTZXJ2aWNlLmV2ZW50QnVzPy5kaXNwYXRjaChcImRpc3BhdGNoZXZlbnRpbnNhbmRib3hcIiwge1xuICAgICAgICAgIHNvdXJjZTogdGhpcyxcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIGlkOiB0aGlzLmRhdGEuaWQsXG4gICAgICAgICAgICBuYW1lOiBldmVudE5hbWUsXG4gICAgICAgICAgICB2YWx1ZTogdmFsdWVHZXR0ZXIoZXZlbnQpLFxuICAgICAgICAgICAgc2hpZnQ6IGV2ZW50LnNoaWZ0S2V5LFxuICAgICAgICAgICAgbW9kaWZpZXI6IHRoaXMuX2dldEtleU1vZGlmaWVyKGV2ZW50KVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGJhc2VOYW1lLCBldmVudCA9PiB7XG4gICAgICAgIHRoaXMubGlua1NlcnZpY2UuZXZlbnRCdXM/LmRpc3BhdGNoKFwiZGlzcGF0Y2hldmVudGluc2FuZGJveFwiLCB7XG4gICAgICAgICAgc291cmNlOiB0aGlzLFxuICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgaWQ6IHRoaXMuZGF0YS5pZCxcbiAgICAgICAgICAgIG5hbWU6IGV2ZW50TmFtZSxcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZUdldHRlcihldmVudClcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgX3NldEV2ZW50TGlzdGVuZXJzKGVsZW1lbnQsIG5hbWVzLCBnZXR0ZXIpIHtcbiAgICBmb3IgKGNvbnN0IFtiYXNlTmFtZSwgZXZlbnROYW1lXSBvZiBuYW1lcykge1xuICAgICAgaWYgKGV2ZW50TmFtZSA9PT0gXCJBY3Rpb25cIiB8fCB0aGlzLmRhdGEuYWN0aW9ucz8uW2V2ZW50TmFtZV0pIHtcbiAgICAgICAgdGhpcy5fc2V0RXZlbnRMaXN0ZW5lcihlbGVtZW50LCBiYXNlTmFtZSwgZXZlbnROYW1lLCBnZXR0ZXIpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIF9zZXRCYWNrZ3JvdW5kQ29sb3IoZWxlbWVudCkge1xuICAgIGNvbnN0IGNvbG9yID0gdGhpcy5kYXRhLmJhY2tncm91bmRDb2xvciB8fCBudWxsO1xuICAgIGVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gY29sb3IgPT09IG51bGwgPyBcInRyYW5zcGFyZW50XCIgOiBfdXRpbC5VdGlsLm1ha2VIZXhDb2xvcihjb2xvclswXSwgY29sb3JbMV0sIGNvbG9yWzJdKTtcbiAgfVxuXG59XG5cbmNsYXNzIFRleHRXaWRnZXRBbm5vdGF0aW9uRWxlbWVudCBleHRlbmRzIFdpZGdldEFubm90YXRpb25FbGVtZW50IHtcbiAgY29uc3RydWN0b3IocGFyYW1ldGVycykge1xuICAgIGNvbnN0IGlzUmVuZGVyYWJsZSA9IHBhcmFtZXRlcnMucmVuZGVyRm9ybXMgfHwgIXBhcmFtZXRlcnMuZGF0YS5oYXNBcHBlYXJhbmNlICYmICEhcGFyYW1ldGVycy5kYXRhLmZpZWxkVmFsdWU7XG4gICAgc3VwZXIocGFyYW1ldGVycywge1xuICAgICAgaXNSZW5kZXJhYmxlXG4gICAgfSk7XG4gIH1cblxuICBzZXRQcm9wZXJ0eU9uU2libGluZ3MoYmFzZSwga2V5LCB2YWx1ZSwga2V5SW5TdG9yYWdlKSB7XG4gICAgY29uc3Qgc3RvcmFnZSA9IHRoaXMuYW5ub3RhdGlvblN0b3JhZ2U7XG5cbiAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgdGhpcy5fZ2V0RWxlbWVudHNCeU5hbWUoYmFzZS5uYW1lLCBiYXNlLmlkKSkge1xuICAgICAgaWYgKGVsZW1lbnQuZG9tRWxlbWVudCkge1xuICAgICAgICBlbGVtZW50LmRvbUVsZW1lbnRba2V5XSA9IHZhbHVlO1xuICAgICAgfVxuXG4gICAgICBzdG9yYWdlLnNldFZhbHVlKGVsZW1lbnQuaWQsIHtcbiAgICAgICAgW2tleUluU3RvcmFnZV06IHZhbHVlXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgY29uc3Qgc3RvcmFnZSA9IHRoaXMuYW5ub3RhdGlvblN0b3JhZ2U7XG4gICAgY29uc3QgaWQgPSB0aGlzLmRhdGEuaWQ7XG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NOYW1lID0gXCJ0ZXh0V2lkZ2V0QW5ub3RhdGlvblwiO1xuICAgIGxldCBlbGVtZW50ID0gbnVsbDtcblxuICAgIGlmICh0aGlzLnJlbmRlckZvcm1zKSB7XG4gICAgICBjb25zdCBzdG9yZWREYXRhID0gc3RvcmFnZS5nZXRWYWx1ZShpZCwge1xuICAgICAgICB2YWx1ZTogdGhpcy5kYXRhLmZpZWxkVmFsdWVcbiAgICAgIH0pO1xuICAgICAgY29uc3QgdGV4dENvbnRlbnQgPSBzdG9yZWREYXRhLmZvcm1hdHRlZFZhbHVlIHx8IHN0b3JlZERhdGEudmFsdWUgfHwgXCJcIjtcbiAgICAgIGNvbnN0IGVsZW1lbnREYXRhID0ge1xuICAgICAgICB1c2VyVmFsdWU6IG51bGwsXG4gICAgICAgIGZvcm1hdHRlZFZhbHVlOiBudWxsLFxuICAgICAgICB2YWx1ZU9uRm9jdXM6IFwiXCJcbiAgICAgIH07XG5cbiAgICAgIGlmICh0aGlzLmRhdGEubXVsdGlMaW5lKSB7XG4gICAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidGV4dGFyZWFcIik7XG4gICAgICAgIGVsZW1lbnQudGV4dENvbnRlbnQgPSB0ZXh0Q29udGVudDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIik7XG4gICAgICAgIGVsZW1lbnQudHlwZSA9IFwidGV4dFwiO1xuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShcInZhbHVlXCIsIHRleHRDb250ZW50KTtcbiAgICAgIH1cblxuICAgICAgR2V0RWxlbWVudHNCeU5hbWVTZXQuYWRkKGVsZW1lbnQpO1xuICAgICAgZWxlbWVudC5kaXNhYmxlZCA9IHRoaXMuZGF0YS5yZWFkT25seTtcbiAgICAgIGVsZW1lbnQubmFtZSA9IHRoaXMuZGF0YS5maWVsZE5hbWU7XG4gICAgICBlbGVtZW50LnRhYkluZGV4ID0gREVGQVVMVF9UQUJfSU5ERVg7XG4gICAgICBlbGVtZW50RGF0YS51c2VyVmFsdWUgPSB0ZXh0Q29udGVudDtcbiAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKFwiaWRcIiwgaWQpO1xuICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIiwgZXZlbnQgPT4ge1xuICAgICAgICBzdG9yYWdlLnNldFZhbHVlKGlkLCB7XG4gICAgICAgICAgdmFsdWU6IGV2ZW50LnRhcmdldC52YWx1ZVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zZXRQcm9wZXJ0eU9uU2libGluZ3MoZWxlbWVudCwgXCJ2YWx1ZVwiLCBldmVudC50YXJnZXQudmFsdWUsIFwidmFsdWVcIik7XG4gICAgICB9KTtcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInJlc2V0Zm9ybVwiLCBldmVudCA9PiB7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZSA9IHRoaXMuZGF0YS5kZWZhdWx0RmllbGRWYWx1ZSA/PyBcIlwiO1xuICAgICAgICBlbGVtZW50LnZhbHVlID0gZWxlbWVudERhdGEudXNlclZhbHVlID0gZGVmYXVsdFZhbHVlO1xuICAgICAgICBlbGVtZW50RGF0YS5mb3JtYXR0ZWRWYWx1ZSA9IG51bGw7XG4gICAgICB9KTtcblxuICAgICAgbGV0IGJsdXJMaXN0ZW5lciA9IGV2ZW50ID0+IHtcbiAgICAgICAgY29uc3Qge1xuICAgICAgICAgIGZvcm1hdHRlZFZhbHVlXG4gICAgICAgIH0gPSBlbGVtZW50RGF0YTtcblxuICAgICAgICBpZiAoZm9ybWF0dGVkVmFsdWUgIT09IG51bGwgJiYgZm9ybWF0dGVkVmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGV2ZW50LnRhcmdldC52YWx1ZSA9IGZvcm1hdHRlZFZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgZXZlbnQudGFyZ2V0LnNjcm9sbExlZnQgPSAwO1xuICAgICAgfTtcblxuICAgICAgaWYgKHRoaXMuZW5hYmxlU2NyaXB0aW5nICYmIHRoaXMuaGFzSlNBY3Rpb25zKSB7XG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImZvY3VzXCIsIGV2ZW50ID0+IHtcbiAgICAgICAgICBpZiAoZWxlbWVudERhdGEudXNlclZhbHVlKSB7XG4gICAgICAgICAgICBldmVudC50YXJnZXQudmFsdWUgPSBlbGVtZW50RGF0YS51c2VyVmFsdWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZWxlbWVudERhdGEudmFsdWVPbkZvY3VzID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidXBkYXRlZnJvbXNhbmRib3hcIiwganNFdmVudCA9PiB7XG4gICAgICAgICAgY29uc3QgYWN0aW9ucyA9IHtcbiAgICAgICAgICAgIHZhbHVlKGV2ZW50KSB7XG4gICAgICAgICAgICAgIGVsZW1lbnREYXRhLnVzZXJWYWx1ZSA9IGV2ZW50LmRldGFpbC52YWx1ZSA/PyBcIlwiO1xuICAgICAgICAgICAgICBzdG9yYWdlLnNldFZhbHVlKGlkLCB7XG4gICAgICAgICAgICAgICAgdmFsdWU6IGVsZW1lbnREYXRhLnVzZXJWYWx1ZS50b1N0cmluZygpXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBldmVudC50YXJnZXQudmFsdWUgPSBlbGVtZW50RGF0YS51c2VyVmFsdWU7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBmb3JtYXR0ZWRWYWx1ZShldmVudCkge1xuICAgICAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICAgICAgZm9ybWF0dGVkVmFsdWVcbiAgICAgICAgICAgICAgfSA9IGV2ZW50LmRldGFpbDtcbiAgICAgICAgICAgICAgZWxlbWVudERhdGEuZm9ybWF0dGVkVmFsdWUgPSBmb3JtYXR0ZWRWYWx1ZTtcblxuICAgICAgICAgICAgICBpZiAoZm9ybWF0dGVkVmFsdWUgIT09IG51bGwgJiYgZm9ybWF0dGVkVmFsdWUgIT09IHVuZGVmaW5lZCAmJiBldmVudC50YXJnZXQgIT09IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICBldmVudC50YXJnZXQudmFsdWUgPSBmb3JtYXR0ZWRWYWx1ZTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICAgICAgICBmb3JtYXR0ZWRWYWx1ZVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIHNlbFJhbmdlKGV2ZW50KSB7XG4gICAgICAgICAgICAgIGV2ZW50LnRhcmdldC5zZXRTZWxlY3Rpb25SYW5nZSguLi5ldmVudC5kZXRhaWwuc2VsUmFuZ2UpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIHRoaXMuX2Rpc3BhdGNoRXZlbnRGcm9tU2FuZGJveChhY3Rpb25zLCBqc0V2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImtleWRvd25cIiwgZXZlbnQgPT4ge1xuICAgICAgICAgIGxldCBjb21taXRLZXkgPSAtMTtcblxuICAgICAgICAgIGlmIChldmVudC5rZXkgPT09IFwiRXNjYXBlXCIpIHtcbiAgICAgICAgICAgIGNvbW1pdEtleSA9IDA7XG4gICAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IFwiRW50ZXJcIikge1xuICAgICAgICAgICAgY29tbWl0S2V5ID0gMjtcbiAgICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gXCJUYWJcIikge1xuICAgICAgICAgICAgY29tbWl0S2V5ID0gMztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoY29tbWl0S2V5ID09PSAtMSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgIHZhbHVlXG4gICAgICAgICAgfSA9IGV2ZW50LnRhcmdldDtcblxuICAgICAgICAgIGlmIChlbGVtZW50RGF0YS52YWx1ZU9uRm9jdXMgPT09IHZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZWxlbWVudERhdGEudXNlclZhbHVlID0gdmFsdWU7XG4gICAgICAgICAgdGhpcy5saW5rU2VydmljZS5ldmVudEJ1cz8uZGlzcGF0Y2goXCJkaXNwYXRjaGV2ZW50aW5zYW5kYm94XCIsIHtcbiAgICAgICAgICAgIHNvdXJjZTogdGhpcyxcbiAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICBpZCxcbiAgICAgICAgICAgICAgbmFtZTogXCJLZXlzdHJva2VcIixcbiAgICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICAgIHdpbGxDb21taXQ6IHRydWUsXG4gICAgICAgICAgICAgIGNvbW1pdEtleSxcbiAgICAgICAgICAgICAgc2VsU3RhcnQ6IGV2ZW50LnRhcmdldC5zZWxlY3Rpb25TdGFydCxcbiAgICAgICAgICAgICAgc2VsRW5kOiBldmVudC50YXJnZXQuc2VsZWN0aW9uRW5kXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBfYmx1ckxpc3RlbmVyID0gYmx1ckxpc3RlbmVyO1xuICAgICAgICBibHVyTGlzdGVuZXIgPSBudWxsO1xuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJibHVyXCIsIGV2ZW50ID0+IHtcbiAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICB2YWx1ZVxuICAgICAgICAgIH0gPSBldmVudC50YXJnZXQ7XG4gICAgICAgICAgZWxlbWVudERhdGEudXNlclZhbHVlID0gdmFsdWU7XG5cbiAgICAgICAgICBpZiAodGhpcy5fbW91c2VTdGF0ZS5pc0Rvd24gJiYgZWxlbWVudERhdGEudmFsdWVPbkZvY3VzICE9PSB2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5saW5rU2VydmljZS5ldmVudEJ1cz8uZGlzcGF0Y2goXCJkaXNwYXRjaGV2ZW50aW5zYW5kYm94XCIsIHtcbiAgICAgICAgICAgICAgc291cmNlOiB0aGlzLFxuICAgICAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgICAgICBpZCxcbiAgICAgICAgICAgICAgICBuYW1lOiBcIktleXN0cm9rZVwiLFxuICAgICAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgICAgIHdpbGxDb21taXQ6IHRydWUsXG4gICAgICAgICAgICAgICAgY29tbWl0S2V5OiAxLFxuICAgICAgICAgICAgICAgIHNlbFN0YXJ0OiBldmVudC50YXJnZXQuc2VsZWN0aW9uU3RhcnQsXG4gICAgICAgICAgICAgICAgc2VsRW5kOiBldmVudC50YXJnZXQuc2VsZWN0aW9uRW5kXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIF9ibHVyTGlzdGVuZXIoZXZlbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodGhpcy5kYXRhLmFjdGlvbnM/LktleXN0cm9rZSkge1xuICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImJlZm9yZWlucHV0XCIsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgICAgdGFyZ2V0XG4gICAgICAgICAgICB9ID0gZXZlbnQ7XG4gICAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgICBzZWxlY3Rpb25TdGFydCxcbiAgICAgICAgICAgICAgc2VsZWN0aW9uRW5kXG4gICAgICAgICAgICB9ID0gdGFyZ2V0O1xuICAgICAgICAgICAgbGV0IHNlbFN0YXJ0ID0gc2VsZWN0aW9uU3RhcnQsXG4gICAgICAgICAgICAgICAgc2VsRW5kID0gc2VsZWN0aW9uRW5kO1xuXG4gICAgICAgICAgICBzd2l0Y2ggKGV2ZW50LmlucHV0VHlwZSkge1xuICAgICAgICAgICAgICBjYXNlIFwiZGVsZXRlV29yZEJhY2t3YXJkXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgY29uc3QgbWF0Y2ggPSB2YWx1ZS5zdWJzdHJpbmcoMCwgc2VsZWN0aW9uU3RhcnQpLm1hdGNoKC9cXHcqW15cXHddKiQvKTtcblxuICAgICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbFN0YXJ0IC09IG1hdGNoWzBdLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGNhc2UgXCJkZWxldGVXb3JkRm9yd2FyZFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGNoID0gdmFsdWUuc3Vic3RyaW5nKHNlbGVjdGlvblN0YXJ0KS5tYXRjaCgvXlteXFx3XSpcXHcqLyk7XG5cbiAgICAgICAgICAgICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgICAgICAgICBzZWxFbmQgKz0gbWF0Y2hbMF0ubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgY2FzZSBcImRlbGV0ZUNvbnRlbnRCYWNrd2FyZFwiOlxuICAgICAgICAgICAgICAgIGlmIChzZWxlY3Rpb25TdGFydCA9PT0gc2VsZWN0aW9uRW5kKSB7XG4gICAgICAgICAgICAgICAgICBzZWxTdGFydCAtPSAxO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgIGNhc2UgXCJkZWxldGVDb250ZW50Rm9yd2FyZFwiOlxuICAgICAgICAgICAgICAgIGlmIChzZWxlY3Rpb25TdGFydCA9PT0gc2VsZWN0aW9uRW5kKSB7XG4gICAgICAgICAgICAgICAgICBzZWxFbmQgKz0gMTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHRoaXMubGlua1NlcnZpY2UuZXZlbnRCdXM/LmRpc3BhdGNoKFwiZGlzcGF0Y2hldmVudGluc2FuZGJveFwiLCB7XG4gICAgICAgICAgICAgIHNvdXJjZTogdGhpcyxcbiAgICAgICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICAgICAgbmFtZTogXCJLZXlzdHJva2VcIixcbiAgICAgICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgICAgICBjaGFuZ2U6IGRhdGEgfHwgXCJcIixcbiAgICAgICAgICAgICAgICB3aWxsQ29tbWl0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzZWxTdGFydCxcbiAgICAgICAgICAgICAgICBzZWxFbmRcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9zZXRFdmVudExpc3RlbmVycyhlbGVtZW50LCBbW1wiZm9jdXNcIiwgXCJGb2N1c1wiXSwgW1wiYmx1clwiLCBcIkJsdXJcIl0sIFtcIm1vdXNlZG93blwiLCBcIk1vdXNlIERvd25cIl0sIFtcIm1vdXNlZW50ZXJcIiwgXCJNb3VzZSBFbnRlclwiXSwgW1wibW91c2VsZWF2ZVwiLCBcIk1vdXNlIEV4aXRcIl0sIFtcIm1vdXNldXBcIiwgXCJNb3VzZSBVcFwiXV0sIGV2ZW50ID0+IGV2ZW50LnRhcmdldC52YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChibHVyTGlzdGVuZXIpIHtcbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwiYmx1clwiLCBibHVyTGlzdGVuZXIpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5kYXRhLm1heExlbiAhPT0gbnVsbCkge1xuICAgICAgICBlbGVtZW50Lm1heExlbmd0aCA9IHRoaXMuZGF0YS5tYXhMZW47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmRhdGEuY29tYikge1xuICAgICAgICBjb25zdCBmaWVsZFdpZHRoID0gdGhpcy5kYXRhLnJlY3RbMl0gLSB0aGlzLmRhdGEucmVjdFswXTtcbiAgICAgICAgY29uc3QgY29tYldpZHRoID0gZmllbGRXaWR0aCAvIHRoaXMuZGF0YS5tYXhMZW47XG4gICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZChcImNvbWJcIik7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUubGV0dGVyU3BhY2luZyA9IGBjYWxjKCR7Y29tYldpZHRofXB4IC0gMWNoKWA7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgZWxlbWVudC50ZXh0Q29udGVudCA9IHRoaXMuZGF0YS5maWVsZFZhbHVlO1xuICAgICAgZWxlbWVudC5zdHlsZS52ZXJ0aWNhbEFsaWduID0gXCJtaWRkbGVcIjtcbiAgICAgIGVsZW1lbnQuc3R5bGUuZGlzcGxheSA9IFwidGFibGUtY2VsbFwiO1xuICAgIH1cblxuICAgIHRoaXMuX3NldFRleHRTdHlsZShlbGVtZW50KTtcblxuICAgIHRoaXMuX3NldEJhY2tncm91bmRDb2xvcihlbGVtZW50KTtcblxuICAgIHRoaXMuX3NldERlZmF1bHRQcm9wZXJ0aWVzRnJvbUpTKGVsZW1lbnQpO1xuXG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbiAgX3NldFRleHRTdHlsZShlbGVtZW50KSB7XG4gICAgY29uc3QgVEVYVF9BTElHTk1FTlQgPSBbXCJsZWZ0XCIsIFwiY2VudGVyXCIsIFwicmlnaHRcIl07XG4gICAgY29uc3Qge1xuICAgICAgZm9udFNpemUsXG4gICAgICBmb250Q29sb3JcbiAgICB9ID0gdGhpcy5kYXRhLmRlZmF1bHRBcHBlYXJhbmNlRGF0YTtcbiAgICBjb25zdCBzdHlsZSA9IGVsZW1lbnQuc3R5bGU7XG5cbiAgICBpZiAoZm9udFNpemUpIHtcbiAgICAgIHN0eWxlLmZvbnRTaXplID0gYCR7Zm9udFNpemV9cHhgO1xuICAgIH1cblxuICAgIHN0eWxlLmNvbG9yID0gX3V0aWwuVXRpbC5tYWtlSGV4Q29sb3IoZm9udENvbG9yWzBdLCBmb250Q29sb3JbMV0sIGZvbnRDb2xvclsyXSk7XG5cbiAgICBpZiAodGhpcy5kYXRhLnRleHRBbGlnbm1lbnQgIT09IG51bGwpIHtcbiAgICAgIHN0eWxlLnRleHRBbGlnbiA9IFRFWFRfQUxJR05NRU5UW3RoaXMuZGF0YS50ZXh0QWxpZ25tZW50XTtcbiAgICB9XG4gIH1cblxufVxuXG5jbGFzcyBDaGVja2JveFdpZGdldEFubm90YXRpb25FbGVtZW50IGV4dGVuZHMgV2lkZ2V0QW5ub3RhdGlvbkVsZW1lbnQge1xuICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzKSB7XG4gICAgc3VwZXIocGFyYW1ldGVycywge1xuICAgICAgaXNSZW5kZXJhYmxlOiBwYXJhbWV0ZXJzLnJlbmRlckZvcm1zXG4gICAgfSk7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgY29uc3Qgc3RvcmFnZSA9IHRoaXMuYW5ub3RhdGlvblN0b3JhZ2U7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuZGF0YTtcbiAgICBjb25zdCBpZCA9IGRhdGEuaWQ7XG4gICAgbGV0IHZhbHVlID0gc3RvcmFnZS5nZXRWYWx1ZShpZCwge1xuICAgICAgdmFsdWU6IGRhdGEuZXhwb3J0VmFsdWUgPT09IGRhdGEuZmllbGRWYWx1ZVxuICAgIH0pLnZhbHVlO1xuXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgdmFsdWUgPSB2YWx1ZSAhPT0gXCJPZmZcIjtcbiAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgdmFsdWVcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IFwiYnV0dG9uV2lkZ2V0QW5ub3RhdGlvbiBjaGVja0JveFwiO1xuICAgIGNvbnN0IGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIik7XG4gICAgR2V0RWxlbWVudHNCeU5hbWVTZXQuYWRkKGVsZW1lbnQpO1xuICAgIGVsZW1lbnQuZGlzYWJsZWQgPSBkYXRhLnJlYWRPbmx5O1xuICAgIGVsZW1lbnQudHlwZSA9IFwiY2hlY2tib3hcIjtcbiAgICBlbGVtZW50Lm5hbWUgPSBkYXRhLmZpZWxkTmFtZTtcblxuICAgIGlmICh2YWx1ZSkge1xuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJjaGVja2VkXCIsIHRydWUpO1xuICAgIH1cblxuICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKFwiaWRcIiwgaWQpO1xuICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKFwiZXhwb3J0VmFsdWVcIiwgZGF0YS5leHBvcnRWYWx1ZSk7XG4gICAgZWxlbWVudC50YWJJbmRleCA9IERFRkFVTFRfVEFCX0lOREVYO1xuICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImNoYW5nZVwiLCBldmVudCA9PiB7XG4gICAgICBjb25zdCB7XG4gICAgICAgIG5hbWUsXG4gICAgICAgIGNoZWNrZWRcbiAgICAgIH0gPSBldmVudC50YXJnZXQ7XG5cbiAgICAgIGZvciAoY29uc3QgY2hlY2tib3ggb2YgdGhpcy5fZ2V0RWxlbWVudHNCeU5hbWUobmFtZSwgaWQpKSB7XG4gICAgICAgIGNvbnN0IGN1ckNoZWNrZWQgPSBjaGVja2VkICYmIGNoZWNrYm94LmV4cG9ydFZhbHVlID09PSBkYXRhLmV4cG9ydFZhbHVlO1xuXG4gICAgICAgIGlmIChjaGVja2JveC5kb21FbGVtZW50KSB7XG4gICAgICAgICAgY2hlY2tib3guZG9tRWxlbWVudC5jaGVja2VkID0gY3VyQ2hlY2tlZDtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoY2hlY2tib3guaWQsIHtcbiAgICAgICAgICB2YWx1ZTogY3VyQ2hlY2tlZFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgc3RvcmFnZS5zZXRWYWx1ZShpZCwge1xuICAgICAgICB2YWx1ZTogY2hlY2tlZFxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwicmVzZXRmb3JtXCIsIGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZSA9IGRhdGEuZGVmYXVsdEZpZWxkVmFsdWUgfHwgXCJPZmZcIjtcbiAgICAgIGV2ZW50LnRhcmdldC5jaGVja2VkID0gZGVmYXVsdFZhbHVlID09PSBkYXRhLmV4cG9ydFZhbHVlO1xuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMuZW5hYmxlU2NyaXB0aW5nICYmIHRoaXMuaGFzSlNBY3Rpb25zKSB7XG4gICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ1cGRhdGVmcm9tc2FuZGJveFwiLCBqc0V2ZW50ID0+IHtcbiAgICAgICAgY29uc3QgYWN0aW9ucyA9IHtcbiAgICAgICAgICB2YWx1ZShldmVudCkge1xuICAgICAgICAgICAgZXZlbnQudGFyZ2V0LmNoZWNrZWQgPSBldmVudC5kZXRhaWwudmFsdWUgIT09IFwiT2ZmXCI7XG4gICAgICAgICAgICBzdG9yYWdlLnNldFZhbHVlKGlkLCB7XG4gICAgICAgICAgICAgIHZhbHVlOiBldmVudC50YXJnZXQuY2hlY2tlZFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5fZGlzcGF0Y2hFdmVudEZyb21TYW5kYm94KGFjdGlvbnMsIGpzRXZlbnQpO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuX3NldEV2ZW50TGlzdGVuZXJzKGVsZW1lbnQsIFtbXCJjaGFuZ2VcIiwgXCJWYWxpZGF0ZVwiXSwgW1wiY2hhbmdlXCIsIFwiQWN0aW9uXCJdLCBbXCJmb2N1c1wiLCBcIkZvY3VzXCJdLCBbXCJibHVyXCIsIFwiQmx1clwiXSwgW1wibW91c2Vkb3duXCIsIFwiTW91c2UgRG93blwiXSwgW1wibW91c2VlbnRlclwiLCBcIk1vdXNlIEVudGVyXCJdLCBbXCJtb3VzZWxlYXZlXCIsIFwiTW91c2UgRXhpdFwiXSwgW1wibW91c2V1cFwiLCBcIk1vdXNlIFVwXCJdXSwgZXZlbnQgPT4gZXZlbnQudGFyZ2V0LmNoZWNrZWQpO1xuICAgIH1cblxuICAgIHRoaXMuX3NldEJhY2tncm91bmRDb2xvcihlbGVtZW50KTtcblxuICAgIHRoaXMuX3NldERlZmF1bHRQcm9wZXJ0aWVzRnJvbUpTKGVsZW1lbnQpO1xuXG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgUmFkaW9CdXR0b25XaWRnZXRBbm5vdGF0aW9uRWxlbWVudCBleHRlbmRzIFdpZGdldEFubm90YXRpb25FbGVtZW50IHtcbiAgY29uc3RydWN0b3IocGFyYW1ldGVycykge1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlzUmVuZGVyYWJsZTogcGFyYW1ldGVycy5yZW5kZXJGb3Jtc1xuICAgIH0pO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IFwiYnV0dG9uV2lkZ2V0QW5ub3RhdGlvbiByYWRpb0J1dHRvblwiO1xuICAgIGNvbnN0IHN0b3JhZ2UgPSB0aGlzLmFubm90YXRpb25TdG9yYWdlO1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLmRhdGE7XG4gICAgY29uc3QgaWQgPSBkYXRhLmlkO1xuICAgIGxldCB2YWx1ZSA9IHN0b3JhZ2UuZ2V0VmFsdWUoaWQsIHtcbiAgICAgIHZhbHVlOiBkYXRhLmZpZWxkVmFsdWUgPT09IGRhdGEuYnV0dG9uVmFsdWVcbiAgICB9KS52YWx1ZTtcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHZhbHVlID0gdmFsdWUgIT09IGRhdGEuYnV0dG9uVmFsdWU7XG4gICAgICBzdG9yYWdlLnNldFZhbHVlKGlkLCB7XG4gICAgICAgIHZhbHVlXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImlucHV0XCIpO1xuICAgIEdldEVsZW1lbnRzQnlOYW1lU2V0LmFkZChlbGVtZW50KTtcbiAgICBlbGVtZW50LmRpc2FibGVkID0gZGF0YS5yZWFkT25seTtcbiAgICBlbGVtZW50LnR5cGUgPSBcInJhZGlvXCI7XG4gICAgZWxlbWVudC5uYW1lID0gZGF0YS5maWVsZE5hbWU7XG5cbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKFwiY2hlY2tlZFwiLCB0cnVlKTtcbiAgICB9XG5cbiAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShcImlkXCIsIGlkKTtcbiAgICBlbGVtZW50LnRhYkluZGV4ID0gREVGQVVMVF9UQUJfSU5ERVg7XG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwiY2hhbmdlXCIsIGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgY2hlY2tlZFxuICAgICAgfSA9IGV2ZW50LnRhcmdldDtcblxuICAgICAgZm9yIChjb25zdCByYWRpbyBvZiB0aGlzLl9nZXRFbGVtZW50c0J5TmFtZShuYW1lLCBpZCkpIHtcbiAgICAgICAgc3RvcmFnZS5zZXRWYWx1ZShyYWRpby5pZCwge1xuICAgICAgICAgIHZhbHVlOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgc3RvcmFnZS5zZXRWYWx1ZShpZCwge1xuICAgICAgICB2YWx1ZTogY2hlY2tlZFxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwicmVzZXRmb3JtXCIsIGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZSA9IGRhdGEuZGVmYXVsdEZpZWxkVmFsdWU7XG4gICAgICBldmVudC50YXJnZXQuY2hlY2tlZCA9IGRlZmF1bHRWYWx1ZSAhPT0gbnVsbCAmJiBkZWZhdWx0VmFsdWUgIT09IHVuZGVmaW5lZCAmJiBkZWZhdWx0VmFsdWUgPT09IGRhdGEuYnV0dG9uVmFsdWU7XG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5lbmFibGVTY3JpcHRpbmcgJiYgdGhpcy5oYXNKU0FjdGlvbnMpIHtcbiAgICAgIGNvbnN0IHBkZkJ1dHRvblZhbHVlID0gZGF0YS5idXR0b25WYWx1ZTtcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInVwZGF0ZWZyb21zYW5kYm94XCIsIGpzRXZlbnQgPT4ge1xuICAgICAgICBjb25zdCBhY3Rpb25zID0ge1xuICAgICAgICAgIHZhbHVlOiBldmVudCA9PiB7XG4gICAgICAgICAgICBjb25zdCBjaGVja2VkID0gcGRmQnV0dG9uVmFsdWUgPT09IGV2ZW50LmRldGFpbC52YWx1ZTtcblxuICAgICAgICAgICAgZm9yIChjb25zdCByYWRpbyBvZiB0aGlzLl9nZXRFbGVtZW50c0J5TmFtZShldmVudC50YXJnZXQubmFtZSkpIHtcbiAgICAgICAgICAgICAgY29uc3QgY3VyQ2hlY2tlZCA9IGNoZWNrZWQgJiYgcmFkaW8uaWQgPT09IGlkO1xuXG4gICAgICAgICAgICAgIGlmIChyYWRpby5kb21FbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgcmFkaW8uZG9tRWxlbWVudC5jaGVja2VkID0gY3VyQ2hlY2tlZDtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUocmFkaW8uaWQsIHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogY3VyQ2hlY2tlZFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5fZGlzcGF0Y2hFdmVudEZyb21TYW5kYm94KGFjdGlvbnMsIGpzRXZlbnQpO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuX3NldEV2ZW50TGlzdGVuZXJzKGVsZW1lbnQsIFtbXCJjaGFuZ2VcIiwgXCJWYWxpZGF0ZVwiXSwgW1wiY2hhbmdlXCIsIFwiQWN0aW9uXCJdLCBbXCJmb2N1c1wiLCBcIkZvY3VzXCJdLCBbXCJibHVyXCIsIFwiQmx1clwiXSwgW1wibW91c2Vkb3duXCIsIFwiTW91c2UgRG93blwiXSwgW1wibW91c2VlbnRlclwiLCBcIk1vdXNlIEVudGVyXCJdLCBbXCJtb3VzZWxlYXZlXCIsIFwiTW91c2UgRXhpdFwiXSwgW1wibW91c2V1cFwiLCBcIk1vdXNlIFVwXCJdXSwgZXZlbnQgPT4gZXZlbnQudGFyZ2V0LmNoZWNrZWQpO1xuICAgIH1cblxuICAgIHRoaXMuX3NldEJhY2tncm91bmRDb2xvcihlbGVtZW50KTtcblxuICAgIHRoaXMuX3NldERlZmF1bHRQcm9wZXJ0aWVzRnJvbUpTKGVsZW1lbnQpO1xuXG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgUHVzaEJ1dHRvbldpZGdldEFubm90YXRpb25FbGVtZW50IGV4dGVuZHMgTGlua0Fubm90YXRpb25FbGVtZW50IHtcbiAgY29uc3RydWN0b3IocGFyYW1ldGVycykge1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlnbm9yZUJvcmRlcjogcGFyYW1ldGVycy5kYXRhLmhhc0FwcGVhcmFuY2VcbiAgICB9KTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBjb25zdCBjb250YWluZXIgPSBzdXBlci5yZW5kZXIoKTtcbiAgICBjb250YWluZXIuY2xhc3NOYW1lID0gXCJidXR0b25XaWRnZXRBbm5vdGF0aW9uIHB1c2hCdXR0b25cIjtcblxuICAgIGlmICh0aGlzLmRhdGEuYWx0ZXJuYXRpdmVUZXh0KSB7XG4gICAgICBjb250YWluZXIudGl0bGUgPSB0aGlzLmRhdGEuYWx0ZXJuYXRpdmVUZXh0O1xuICAgIH1cblxuICAgIHRoaXMuX3NldERlZmF1bHRQcm9wZXJ0aWVzRnJvbUpTKGNvbnRhaW5lcik7XG5cbiAgICByZXR1cm4gY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgQ2hvaWNlV2lkZ2V0QW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBXaWRnZXRBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICBzdXBlcihwYXJhbWV0ZXJzLCB7XG4gICAgICBpc1JlbmRlcmFibGU6IHBhcmFtZXRlcnMucmVuZGVyRm9ybXNcbiAgICB9KTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICB0aGlzLmNvbnRhaW5lci5jbGFzc05hbWUgPSBcImNob2ljZVdpZGdldEFubm90YXRpb25cIjtcbiAgICBjb25zdCBzdG9yYWdlID0gdGhpcy5hbm5vdGF0aW9uU3RvcmFnZTtcbiAgICBjb25zdCBpZCA9IHRoaXMuZGF0YS5pZDtcbiAgICBjb25zdCBzdG9yZWREYXRhID0gc3RvcmFnZS5nZXRWYWx1ZShpZCwge1xuICAgICAgdmFsdWU6IHRoaXMuZGF0YS5maWVsZFZhbHVlXG4gICAgfSk7XG4gICAgbGV0IHtcbiAgICAgIGZvbnRTaXplXG4gICAgfSA9IHRoaXMuZGF0YS5kZWZhdWx0QXBwZWFyYW5jZURhdGE7XG5cbiAgICBpZiAoIWZvbnRTaXplKSB7XG4gICAgICBmb250U2l6ZSA9IDk7XG4gICAgfVxuXG4gICAgY29uc3QgZm9udFNpemVTdHlsZSA9IGBjYWxjKCR7Zm9udFNpemV9cHggKiB2YXIoLS16b29tLWZhY3RvcikpYDtcbiAgICBjb25zdCBzZWxlY3RFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNlbGVjdFwiKTtcbiAgICBHZXRFbGVtZW50c0J5TmFtZVNldC5hZGQoc2VsZWN0RWxlbWVudCk7XG4gICAgc2VsZWN0RWxlbWVudC5kaXNhYmxlZCA9IHRoaXMuZGF0YS5yZWFkT25seTtcbiAgICBzZWxlY3RFbGVtZW50Lm5hbWUgPSB0aGlzLmRhdGEuZmllbGROYW1lO1xuICAgIHNlbGVjdEVsZW1lbnQuc2V0QXR0cmlidXRlKFwiaWRcIiwgaWQpO1xuICAgIHNlbGVjdEVsZW1lbnQudGFiSW5kZXggPSBERUZBVUxUX1RBQl9JTkRFWDtcbiAgICBzZWxlY3RFbGVtZW50LnN0eWxlLmZvbnRTaXplID0gYCR7Zm9udFNpemV9cHhgO1xuXG4gICAgaWYgKCF0aGlzLmRhdGEuY29tYm8pIHtcbiAgICAgIHNlbGVjdEVsZW1lbnQuc2l6ZSA9IHRoaXMuZGF0YS5vcHRpb25zLmxlbmd0aDtcblxuICAgICAgaWYgKHRoaXMuZGF0YS5tdWx0aVNlbGVjdCkge1xuICAgICAgICBzZWxlY3RFbGVtZW50Lm11bHRpcGxlID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzZWxlY3RFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJyZXNldGZvcm1cIiwgZXZlbnQgPT4ge1xuICAgICAgY29uc3QgZGVmYXVsdFZhbHVlID0gdGhpcy5kYXRhLmRlZmF1bHRGaWVsZFZhbHVlO1xuXG4gICAgICBmb3IgKGNvbnN0IG9wdGlvbiBvZiBzZWxlY3RFbGVtZW50Lm9wdGlvbnMpIHtcbiAgICAgICAgb3B0aW9uLnNlbGVjdGVkID0gb3B0aW9uLnZhbHVlID09PSBkZWZhdWx0VmFsdWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBmb3IgKGNvbnN0IG9wdGlvbiBvZiB0aGlzLmRhdGEub3B0aW9ucykge1xuICAgICAgY29uc3Qgb3B0aW9uRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJvcHRpb25cIik7XG4gICAgICBvcHRpb25FbGVtZW50LnRleHRDb250ZW50ID0gb3B0aW9uLmRpc3BsYXlWYWx1ZTtcbiAgICAgIG9wdGlvbkVsZW1lbnQudmFsdWUgPSBvcHRpb24uZXhwb3J0VmFsdWU7XG5cbiAgICAgIGlmICh0aGlzLmRhdGEuY29tYm8pIHtcbiAgICAgICAgb3B0aW9uRWxlbWVudC5zdHlsZS5mb250U2l6ZSA9IGZvbnRTaXplU3R5bGU7XG4gICAgICB9XG5cbiAgICAgIGlmIChzdG9yZWREYXRhLnZhbHVlLmluY2x1ZGVzKG9wdGlvbi5leHBvcnRWYWx1ZSkpIHtcbiAgICAgICAgb3B0aW9uRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJzZWxlY3RlZFwiLCB0cnVlKTtcbiAgICAgIH1cblxuICAgICAgc2VsZWN0RWxlbWVudC5hcHBlbmRDaGlsZChvcHRpb25FbGVtZW50KTtcbiAgICB9XG5cbiAgICBjb25zdCBnZXRWYWx1ZSA9IChldmVudCwgaXNFeHBvcnQpID0+IHtcbiAgICAgIGNvbnN0IG5hbWUgPSBpc0V4cG9ydCA/IFwidmFsdWVcIiA6IFwidGV4dENvbnRlbnRcIjtcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSBldmVudC50YXJnZXQub3B0aW9ucztcblxuICAgICAgaWYgKCFldmVudC50YXJnZXQubXVsdGlwbGUpIHtcbiAgICAgICAgcmV0dXJuIG9wdGlvbnMuc2VsZWN0ZWRJbmRleCA9PT0gLTEgPyBudWxsIDogb3B0aW9uc1tvcHRpb25zLnNlbGVjdGVkSW5kZXhdW25hbWVdO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gQXJyYXkucHJvdG90eXBlLmZpbHRlci5jYWxsKG9wdGlvbnMsIG9wdGlvbiA9PiBvcHRpb24uc2VsZWN0ZWQpLm1hcChvcHRpb24gPT4gb3B0aW9uW25hbWVdKTtcbiAgICB9O1xuXG4gICAgY29uc3QgZ2V0SXRlbXMgPSBldmVudCA9PiB7XG4gICAgICBjb25zdCBvcHRpb25zID0gZXZlbnQudGFyZ2V0Lm9wdGlvbnM7XG4gICAgICByZXR1cm4gQXJyYXkucHJvdG90eXBlLm1hcC5jYWxsKG9wdGlvbnMsIG9wdGlvbiA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZGlzcGxheVZhbHVlOiBvcHRpb24udGV4dENvbnRlbnQsXG4gICAgICAgICAgZXhwb3J0VmFsdWU6IG9wdGlvbi52YWx1ZVxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIGlmICh0aGlzLmVuYWJsZVNjcmlwdGluZyAmJiB0aGlzLmhhc0pTQWN0aW9ucykge1xuICAgICAgc2VsZWN0RWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidXBkYXRlZnJvbXNhbmRib3hcIiwganNFdmVudCA9PiB7XG4gICAgICAgIGNvbnN0IGFjdGlvbnMgPSB7XG4gICAgICAgICAgdmFsdWUoZXZlbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gZXZlbnQuZGV0YWlsLnZhbHVlO1xuICAgICAgICAgICAgY29uc3QgdmFsdWVzID0gbmV3IFNldChBcnJheS5pc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW3ZhbHVlXSk7XG5cbiAgICAgICAgICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIHNlbGVjdEVsZW1lbnQub3B0aW9ucykge1xuICAgICAgICAgICAgICBvcHRpb24uc2VsZWN0ZWQgPSB2YWx1ZXMuaGFzKG9wdGlvbi52YWx1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICAgICAgdmFsdWU6IGdldFZhbHVlKGV2ZW50LCB0cnVlKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcblxuICAgICAgICAgIG11bHRpcGxlU2VsZWN0aW9uKGV2ZW50KSB7XG4gICAgICAgICAgICBzZWxlY3RFbGVtZW50Lm11bHRpcGxlID0gdHJ1ZTtcbiAgICAgICAgICB9LFxuXG4gICAgICAgICAgcmVtb3ZlKGV2ZW50KSB7XG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0gc2VsZWN0RWxlbWVudC5vcHRpb25zO1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBldmVudC5kZXRhaWwucmVtb3ZlO1xuICAgICAgICAgICAgb3B0aW9uc1tpbmRleF0uc2VsZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHNlbGVjdEVsZW1lbnQucmVtb3ZlKGluZGV4KTtcblxuICAgICAgICAgICAgaWYgKG9wdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICBjb25zdCBpID0gQXJyYXkucHJvdG90eXBlLmZpbmRJbmRleC5jYWxsKG9wdGlvbnMsIG9wdGlvbiA9PiBvcHRpb24uc2VsZWN0ZWQpO1xuXG4gICAgICAgICAgICAgIGlmIChpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIG9wdGlvbnNbMF0uc2VsZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICAgICAgdmFsdWU6IGdldFZhbHVlKGV2ZW50LCB0cnVlKSxcbiAgICAgICAgICAgICAgaXRlbXM6IGdldEl0ZW1zKGV2ZW50KVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcblxuICAgICAgICAgIGNsZWFyKGV2ZW50KSB7XG4gICAgICAgICAgICB3aGlsZSAoc2VsZWN0RWxlbWVudC5sZW5ndGggIT09IDApIHtcbiAgICAgICAgICAgICAgc2VsZWN0RWxlbWVudC5yZW1vdmUoMCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICAgICAgdmFsdWU6IG51bGwsXG4gICAgICAgICAgICAgIGl0ZW1zOiBbXVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcblxuICAgICAgICAgIGluc2VydChldmVudCkge1xuICAgICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgICBpbmRleCxcbiAgICAgICAgICAgICAgZGlzcGxheVZhbHVlLFxuICAgICAgICAgICAgICBleHBvcnRWYWx1ZVxuICAgICAgICAgICAgfSA9IGV2ZW50LmRldGFpbC5pbnNlcnQ7XG4gICAgICAgICAgICBjb25zdCBvcHRpb25FbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcIm9wdGlvblwiKTtcbiAgICAgICAgICAgIG9wdGlvbkVsZW1lbnQudGV4dENvbnRlbnQgPSBkaXNwbGF5VmFsdWU7XG4gICAgICAgICAgICBvcHRpb25FbGVtZW50LnZhbHVlID0gZXhwb3J0VmFsdWU7XG4gICAgICAgICAgICBzZWxlY3RFbGVtZW50Lmluc2VydEJlZm9yZShvcHRpb25FbGVtZW50LCBzZWxlY3RFbGVtZW50LmNoaWxkcmVuW2luZGV4XSk7XG4gICAgICAgICAgICBzdG9yYWdlLnNldFZhbHVlKGlkLCB7XG4gICAgICAgICAgICAgIHZhbHVlOiBnZXRWYWx1ZShldmVudCwgdHJ1ZSksXG4gICAgICAgICAgICAgIGl0ZW1zOiBnZXRJdGVtcyhldmVudClcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sXG5cbiAgICAgICAgICBpdGVtcyhldmVudCkge1xuICAgICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgICBpdGVtc1xuICAgICAgICAgICAgfSA9IGV2ZW50LmRldGFpbDtcblxuICAgICAgICAgICAgd2hpbGUgKHNlbGVjdEVsZW1lbnQubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICAgIHNlbGVjdEVsZW1lbnQucmVtb3ZlKDApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHtcbiAgICAgICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgICAgIGRpc3BsYXlWYWx1ZSxcbiAgICAgICAgICAgICAgICBleHBvcnRWYWx1ZVxuICAgICAgICAgICAgICB9ID0gaXRlbTtcbiAgICAgICAgICAgICAgY29uc3Qgb3B0aW9uRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJvcHRpb25cIik7XG4gICAgICAgICAgICAgIG9wdGlvbkVsZW1lbnQudGV4dENvbnRlbnQgPSBkaXNwbGF5VmFsdWU7XG4gICAgICAgICAgICAgIG9wdGlvbkVsZW1lbnQudmFsdWUgPSBleHBvcnRWYWx1ZTtcbiAgICAgICAgICAgICAgc2VsZWN0RWxlbWVudC5hcHBlbmRDaGlsZChvcHRpb25FbGVtZW50KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHNlbGVjdEVsZW1lbnQub3B0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIHNlbGVjdEVsZW1lbnQub3B0aW9uc1swXS5zZWxlY3RlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICAgICAgdmFsdWU6IGdldFZhbHVlKGV2ZW50LCB0cnVlKSxcbiAgICAgICAgICAgICAgaXRlbXM6IGdldEl0ZW1zKGV2ZW50KVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcblxuICAgICAgICAgIGluZGljZXMoZXZlbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IGluZGljZXMgPSBuZXcgU2V0KGV2ZW50LmRldGFpbC5pbmRpY2VzKTtcblxuICAgICAgICAgICAgZm9yIChjb25zdCBvcHRpb24gb2YgZXZlbnQudGFyZ2V0Lm9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgb3B0aW9uLnNlbGVjdGVkID0gaW5kaWNlcy5oYXMob3B0aW9uLmluZGV4KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc3RvcmFnZS5zZXRWYWx1ZShpZCwge1xuICAgICAgICAgICAgICB2YWx1ZTogZ2V0VmFsdWUoZXZlbnQsIHRydWUpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9LFxuXG4gICAgICAgICAgZWRpdGFibGUoZXZlbnQpIHtcbiAgICAgICAgICAgIGV2ZW50LnRhcmdldC5kaXNhYmxlZCA9ICFldmVudC5kZXRhaWwuZWRpdGFibGU7XG4gICAgICAgICAgfVxuXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5fZGlzcGF0Y2hFdmVudEZyb21TYW5kYm94KGFjdGlvbnMsIGpzRXZlbnQpO1xuICAgICAgfSk7XG4gICAgICBzZWxlY3RFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJpbnB1dFwiLCBldmVudCA9PiB7XG4gICAgICAgIGNvbnN0IGV4cG9ydFZhbHVlID0gZ2V0VmFsdWUoZXZlbnQsIHRydWUpO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGdldFZhbHVlKGV2ZW50LCBmYWxzZSk7XG4gICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICB2YWx1ZTogZXhwb3J0VmFsdWVcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubGlua1NlcnZpY2UuZXZlbnRCdXM/LmRpc3BhdGNoKFwiZGlzcGF0Y2hldmVudGluc2FuZGJveFwiLCB7XG4gICAgICAgICAgc291cmNlOiB0aGlzLFxuICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICBuYW1lOiBcIktleXN0cm9rZVwiLFxuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICBjaGFuZ2VFeDogZXhwb3J0VmFsdWUsXG4gICAgICAgICAgICB3aWxsQ29tbWl0OiB0cnVlLFxuICAgICAgICAgICAgY29tbWl0S2V5OiAxLFxuICAgICAgICAgICAga2V5RG93bjogZmFsc2VcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuX3NldEV2ZW50TGlzdGVuZXJzKHNlbGVjdEVsZW1lbnQsIFtbXCJmb2N1c1wiLCBcIkZvY3VzXCJdLCBbXCJibHVyXCIsIFwiQmx1clwiXSwgW1wibW91c2Vkb3duXCIsIFwiTW91c2UgRG93blwiXSwgW1wibW91c2VlbnRlclwiLCBcIk1vdXNlIEVudGVyXCJdLCBbXCJtb3VzZWxlYXZlXCIsIFwiTW91c2UgRXhpdFwiXSwgW1wibW91c2V1cFwiLCBcIk1vdXNlIFVwXCJdLCBbXCJpbnB1dFwiLCBcIkFjdGlvblwiXV0sIGV2ZW50ID0+IGV2ZW50LnRhcmdldC5jaGVja2VkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2VsZWN0RWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIiwgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICB2YWx1ZTogZ2V0VmFsdWUoZXZlbnQsIHRydWUpXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5fc2V0QmFja2dyb3VuZENvbG9yKHNlbGVjdEVsZW1lbnQpO1xuXG4gICAgdGhpcy5fc2V0RGVmYXVsdFByb3BlcnRpZXNGcm9tSlMoc2VsZWN0RWxlbWVudCk7XG5cbiAgICB0aGlzLmNvbnRhaW5lci5hcHBlbmRDaGlsZChzZWxlY3RFbGVtZW50KTtcbiAgICByZXR1cm4gdGhpcy5jb250YWluZXI7XG4gIH1cblxufVxuXG5jbGFzcyBQb3B1cEFubm90YXRpb25FbGVtZW50IGV4dGVuZHMgQW5ub3RhdGlvbkVsZW1lbnQge1xuICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzKSB7XG4gICAgY29uc3QgaXNSZW5kZXJhYmxlID0gISEocGFyYW1ldGVycy5kYXRhLnRpdGxlT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLmNvbnRlbnRzT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLnJpY2hUZXh0Py5zdHIpO1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlzUmVuZGVyYWJsZVxuICAgIH0pO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGNvbnN0IElHTk9SRV9UWVBFUyA9IFtcIkxpbmVcIiwgXCJTcXVhcmVcIiwgXCJDaXJjbGVcIiwgXCJQb2x5TGluZVwiLCBcIlBvbHlnb25cIiwgXCJJbmtcIl07XG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NOYW1lID0gXCJwb3B1cEFubm90YXRpb25cIjtcblxuICAgIGlmIChJR05PUkVfVFlQRVMuaW5jbHVkZXModGhpcy5kYXRhLnBhcmVudFR5cGUpKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb250YWluZXI7XG4gICAgfVxuXG4gICAgY29uc3Qgc2VsZWN0b3IgPSBgW2RhdGEtYW5ub3RhdGlvbi1pZD1cIiR7dGhpcy5kYXRhLnBhcmVudElkfVwiXWA7XG4gICAgY29uc3QgcGFyZW50RWxlbWVudHMgPSB0aGlzLmxheWVyLnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpO1xuXG4gICAgaWYgKHBhcmVudEVsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICAgIH1cblxuICAgIGNvbnN0IHBvcHVwID0gbmV3IFBvcHVwRWxlbWVudCh7XG4gICAgICBjb250YWluZXI6IHRoaXMuY29udGFpbmVyLFxuICAgICAgdHJpZ2dlcjogQXJyYXkuZnJvbShwYXJlbnRFbGVtZW50cyksXG4gICAgICBjb2xvcjogdGhpcy5kYXRhLmNvbG9yLFxuICAgICAgdGl0bGVPYmo6IHRoaXMuZGF0YS50aXRsZU9iaixcbiAgICAgIG1vZGlmaWNhdGlvbkRhdGU6IHRoaXMuZGF0YS5tb2RpZmljYXRpb25EYXRlLFxuICAgICAgY29udGVudHNPYmo6IHRoaXMuZGF0YS5jb250ZW50c09iaixcbiAgICAgIHJpY2hUZXh0OiB0aGlzLmRhdGEucmljaFRleHRcbiAgICB9KTtcbiAgICBjb25zdCBwYWdlID0gdGhpcy5wYWdlO1xuXG4gICAgY29uc3QgcmVjdCA9IF91dGlsLlV0aWwubm9ybWFsaXplUmVjdChbdGhpcy5kYXRhLnBhcmVudFJlY3RbMF0sIHBhZ2Uudmlld1szXSAtIHRoaXMuZGF0YS5wYXJlbnRSZWN0WzFdICsgcGFnZS52aWV3WzFdLCB0aGlzLmRhdGEucGFyZW50UmVjdFsyXSwgcGFnZS52aWV3WzNdIC0gdGhpcy5kYXRhLnBhcmVudFJlY3RbM10gKyBwYWdlLnZpZXdbMV1dKTtcblxuICAgIGNvbnN0IHBvcHVwTGVmdCA9IHJlY3RbMF0gKyB0aGlzLmRhdGEucGFyZW50UmVjdFsyXSAtIHRoaXMuZGF0YS5wYXJlbnRSZWN0WzBdO1xuICAgIGNvbnN0IHBvcHVwVG9wID0gcmVjdFsxXTtcbiAgICB0aGlzLmNvbnRhaW5lci5zdHlsZS50cmFuc2Zvcm1PcmlnaW4gPSBgJHstcG9wdXBMZWZ0fXB4ICR7LXBvcHVwVG9wfXB4YDtcbiAgICB0aGlzLmNvbnRhaW5lci5zdHlsZS5sZWZ0ID0gYCR7cG9wdXBMZWZ0fXB4YDtcbiAgICB0aGlzLmNvbnRhaW5lci5zdHlsZS50b3AgPSBgJHtwb3B1cFRvcH1weGA7XG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQocG9wdXAucmVuZGVyKCkpO1xuICAgIHJldHVybiB0aGlzLmNvbnRhaW5lcjtcbiAgfVxuXG59XG5cbmNsYXNzIFBvcHVwRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICB0aGlzLmNvbnRhaW5lciA9IHBhcmFtZXRlcnMuY29udGFpbmVyO1xuICAgIHRoaXMudHJpZ2dlciA9IHBhcmFtZXRlcnMudHJpZ2dlcjtcbiAgICB0aGlzLmNvbG9yID0gcGFyYW1ldGVycy5jb2xvcjtcbiAgICB0aGlzLnRpdGxlT2JqID0gcGFyYW1ldGVycy50aXRsZU9iajtcbiAgICB0aGlzLm1vZGlmaWNhdGlvbkRhdGUgPSBwYXJhbWV0ZXJzLm1vZGlmaWNhdGlvbkRhdGU7XG4gICAgdGhpcy5jb250ZW50c09iaiA9IHBhcmFtZXRlcnMuY29udGVudHNPYmo7XG4gICAgdGhpcy5yaWNoVGV4dCA9IHBhcmFtZXRlcnMucmljaFRleHQ7XG4gICAgdGhpcy5oaWRlV3JhcHBlciA9IHBhcmFtZXRlcnMuaGlkZVdyYXBwZXIgfHwgZmFsc2U7XG4gICAgdGhpcy5waW5uZWQgPSBmYWxzZTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBjb25zdCBCQUNLR1JPVU5EX0VOTElHSFQgPSAwLjc7XG4gICAgY29uc3Qgd3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgd3JhcHBlci5jbGFzc05hbWUgPSBcInBvcHVwV3JhcHBlclwiO1xuICAgIHRoaXMuaGlkZUVsZW1lbnQgPSB0aGlzLmhpZGVXcmFwcGVyID8gd3JhcHBlciA6IHRoaXMuY29udGFpbmVyO1xuICAgIHRoaXMuaGlkZUVsZW1lbnQuaGlkZGVuID0gdHJ1ZTtcbiAgICBjb25zdCBwb3B1cCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgcG9wdXAuY2xhc3NOYW1lID0gXCJwb3B1cFwiO1xuICAgIGNvbnN0IGNvbG9yID0gdGhpcy5jb2xvcjtcblxuICAgIGlmIChjb2xvcikge1xuICAgICAgY29uc3QgciA9IEJBQ0tHUk9VTkRfRU5MSUdIVCAqICgyNTUgLSBjb2xvclswXSkgKyBjb2xvclswXTtcbiAgICAgIGNvbnN0IGcgPSBCQUNLR1JPVU5EX0VOTElHSFQgKiAoMjU1IC0gY29sb3JbMV0pICsgY29sb3JbMV07XG4gICAgICBjb25zdCBiID0gQkFDS0dST1VORF9FTkxJR0hUICogKDI1NSAtIGNvbG9yWzJdKSArIGNvbG9yWzJdO1xuICAgICAgcG9wdXAuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gX3V0aWwuVXRpbC5tYWtlSGV4Q29sb3IociB8IDAsIGcgfCAwLCBiIHwgMCk7XG4gICAgfVxuXG4gICAgY29uc3QgdGl0bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaDFcIik7XG4gICAgdGl0bGUuZGlyID0gdGhpcy50aXRsZU9iai5kaXI7XG4gICAgdGl0bGUudGV4dENvbnRlbnQgPSB0aGlzLnRpdGxlT2JqLnN0cjtcbiAgICBwb3B1cC5hcHBlbmRDaGlsZCh0aXRsZSk7XG5cbiAgICBjb25zdCBkYXRlT2JqZWN0ID0gX2Rpc3BsYXlfdXRpbHMuUERGRGF0ZVN0cmluZy50b0RhdGVPYmplY3QodGhpcy5tb2RpZmljYXRpb25EYXRlKTtcblxuICAgIGlmIChkYXRlT2JqZWN0KSB7XG4gICAgICBjb25zdCBtb2RpZmljYXRpb25EYXRlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNwYW5cIik7XG4gICAgICBtb2RpZmljYXRpb25EYXRlLmNsYXNzTmFtZSA9IFwicG9wdXBEYXRlXCI7XG4gICAgICBtb2RpZmljYXRpb25EYXRlLnRleHRDb250ZW50ID0gXCJ7e2RhdGV9fSwge3t0aW1lfX1cIjtcbiAgICAgIG1vZGlmaWNhdGlvbkRhdGUuZGF0YXNldC5sMTBuSWQgPSBcImFubm90YXRpb25fZGF0ZV9zdHJpbmdcIjtcbiAgICAgIG1vZGlmaWNhdGlvbkRhdGUuZGF0YXNldC5sMTBuQXJncyA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgZGF0ZTogZGF0ZU9iamVjdC50b0xvY2FsZURhdGVTdHJpbmcoKSxcbiAgICAgICAgdGltZTogZGF0ZU9iamVjdC50b0xvY2FsZVRpbWVTdHJpbmcoKVxuICAgICAgfSk7XG4gICAgICBwb3B1cC5hcHBlbmRDaGlsZChtb2RpZmljYXRpb25EYXRlKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5yaWNoVGV4dD8uc3RyICYmICghdGhpcy5jb250ZW50c09iaj8uc3RyIHx8IHRoaXMuY29udGVudHNPYmouc3RyID09PSB0aGlzLnJpY2hUZXh0LnN0cikpIHtcbiAgICAgIF94ZmFfbGF5ZXIuWGZhTGF5ZXIucmVuZGVyKHtcbiAgICAgICAgeGZhSHRtbDogdGhpcy5yaWNoVGV4dC5odG1sLFxuICAgICAgICBpbnRlbnQ6IFwicmljaFRleHRcIixcbiAgICAgICAgZGl2OiBwb3B1cFxuICAgICAgfSk7XG5cbiAgICAgIHBvcHVwLmxhc3RDaGlsZC5jbGFzc05hbWUgPSBcInJpY2hUZXh0IHBvcHVwQ29udGVudFwiO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBjb250ZW50cyA9IHRoaXMuX2Zvcm1hdENvbnRlbnRzKHRoaXMuY29udGVudHNPYmopO1xuXG4gICAgICBwb3B1cC5hcHBlbmRDaGlsZChjb250ZW50cyk7XG4gICAgfVxuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHRoaXMudHJpZ2dlcikpIHtcbiAgICAgIHRoaXMudHJpZ2dlciA9IFt0aGlzLnRyaWdnZXJdO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiB0aGlzLnRyaWdnZXIpIHtcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIHRoaXMuX3RvZ2dsZS5iaW5kKHRoaXMpKTtcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlb3ZlclwiLCB0aGlzLl9zaG93LmJpbmQodGhpcywgZmFsc2UpKTtcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlb3V0XCIsIHRoaXMuX2hpZGUuYmluZCh0aGlzLCBmYWxzZSkpO1xuICAgIH1cblxuICAgIHBvcHVwLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCB0aGlzLl9oaWRlLmJpbmQodGhpcywgdHJ1ZSkpO1xuICAgIHdyYXBwZXIuYXBwZW5kQ2hpbGQocG9wdXApO1xuICAgIHJldHVybiB3cmFwcGVyO1xuICB9XG5cbiAgX2Zvcm1hdENvbnRlbnRzKHtcbiAgICBzdHIsXG4gICAgZGlyXG4gIH0pIHtcbiAgICBjb25zdCBwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInBcIik7XG4gICAgcC5jbGFzc05hbWUgPSBcInBvcHVwQ29udGVudFwiO1xuICAgIHAuZGlyID0gZGlyO1xuICAgIGNvbnN0IGxpbmVzID0gc3RyLnNwbGl0KC8oPzpcXHJcXG4/fFxcbikvKTtcblxuICAgIGZvciAobGV0IGkgPSAwLCBpaSA9IGxpbmVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIGNvbnN0IGxpbmUgPSBsaW5lc1tpXTtcbiAgICAgIHAuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUobGluZSkpO1xuXG4gICAgICBpZiAoaSA8IGlpIC0gMSkge1xuICAgICAgICBwLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJiclwiKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHA7XG4gIH1cblxuICBfdG9nZ2xlKCkge1xuICAgIGlmICh0aGlzLnBpbm5lZCkge1xuICAgICAgdGhpcy5faGlkZSh0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fc2hvdyh0cnVlKTtcbiAgICB9XG4gIH1cblxuICBfc2hvdyhwaW4gPSBmYWxzZSkge1xuICAgIGlmIChwaW4pIHtcbiAgICAgIHRoaXMucGlubmVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5oaWRlRWxlbWVudC5oaWRkZW4pIHtcbiAgICAgIHRoaXMuaGlkZUVsZW1lbnQuaGlkZGVuID0gZmFsc2U7XG4gICAgICB0aGlzLmNvbnRhaW5lci5zdHlsZS56SW5kZXggKz0gMTtcbiAgICB9XG4gIH1cblxuICBfaGlkZSh1bnBpbiA9IHRydWUpIHtcbiAgICBpZiAodW5waW4pIHtcbiAgICAgIHRoaXMucGlubmVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmhpZGVFbGVtZW50LmhpZGRlbiAmJiAhdGhpcy5waW5uZWQpIHtcbiAgICAgIHRoaXMuaGlkZUVsZW1lbnQuaGlkZGVuID0gdHJ1ZTtcbiAgICAgIHRoaXMuY29udGFpbmVyLnN0eWxlLnpJbmRleCAtPSAxO1xuICAgIH1cbiAgfVxuXG59XG5cbmNsYXNzIEZyZWVUZXh0QW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCBpc1JlbmRlcmFibGUgPSAhIShwYXJhbWV0ZXJzLmRhdGEuaGFzUG9wdXAgfHwgcGFyYW1ldGVycy5kYXRhLnRpdGxlT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLmNvbnRlbnRzT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLnJpY2hUZXh0Py5zdHIpO1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlzUmVuZGVyYWJsZSxcbiAgICAgIGlnbm9yZUJvcmRlcjogdHJ1ZVxuICAgIH0pO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IFwiZnJlZVRleHRBbm5vdGF0aW9uXCI7XG5cbiAgICBpZiAoIXRoaXMuZGF0YS5oYXNQb3B1cCkge1xuICAgICAgdGhpcy5fY3JlYXRlUG9wdXAobnVsbCwgdGhpcy5kYXRhKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5jb250YWluZXI7XG4gIH1cblxufVxuXG5jbGFzcyBMaW5lQW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCBpc1JlbmRlcmFibGUgPSAhIShwYXJhbWV0ZXJzLmRhdGEuaGFzUG9wdXAgfHwgcGFyYW1ldGVycy5kYXRhLnRpdGxlT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLmNvbnRlbnRzT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLnJpY2hUZXh0Py5zdHIpO1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlzUmVuZGVyYWJsZSxcbiAgICAgIGlnbm9yZUJvcmRlcjogdHJ1ZVxuICAgIH0pO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IFwibGluZUFubm90YXRpb25cIjtcbiAgICBjb25zdCBkYXRhID0gdGhpcy5kYXRhO1xuICAgIGNvbnN0IHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0XG4gICAgfSA9IGdldFJlY3REaW1zKGRhdGEucmVjdCk7XG4gICAgY29uc3Qgc3ZnID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZSh3aWR0aCwgaGVpZ2h0KTtcbiAgICBjb25zdCBsaW5lID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZUVsZW1lbnQoXCJzdmc6bGluZVwiKTtcbiAgICBsaW5lLnNldEF0dHJpYnV0ZShcIngxXCIsIGRhdGEucmVjdFsyXSAtIGRhdGEubGluZUNvb3JkaW5hdGVzWzBdKTtcbiAgICBsaW5lLnNldEF0dHJpYnV0ZShcInkxXCIsIGRhdGEucmVjdFszXSAtIGRhdGEubGluZUNvb3JkaW5hdGVzWzFdKTtcbiAgICBsaW5lLnNldEF0dHJpYnV0ZShcIngyXCIsIGRhdGEucmVjdFsyXSAtIGRhdGEubGluZUNvb3JkaW5hdGVzWzJdKTtcbiAgICBsaW5lLnNldEF0dHJpYnV0ZShcInkyXCIsIGRhdGEucmVjdFszXSAtIGRhdGEubGluZUNvb3JkaW5hdGVzWzNdKTtcbiAgICBsaW5lLnNldEF0dHJpYnV0ZShcInN0cm9rZS13aWR0aFwiLCBkYXRhLmJvcmRlclN0eWxlLndpZHRoIHx8IDEpO1xuICAgIGxpbmUuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIFwidHJhbnNwYXJlbnRcIik7XG4gICAgbGluZS5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIFwidHJhbnNwYXJlbnRcIik7XG4gICAgc3ZnLmFwcGVuZENoaWxkKGxpbmUpO1xuICAgIHRoaXMuY29udGFpbmVyLmFwcGVuZChzdmcpO1xuXG4gICAgdGhpcy5fY3JlYXRlUG9wdXAobGluZSwgZGF0YSk7XG5cbiAgICByZXR1cm4gdGhpcy5jb250YWluZXI7XG4gIH1cblxufVxuXG5jbGFzcyBTcXVhcmVBbm5vdGF0aW9uRWxlbWVudCBleHRlbmRzIEFubm90YXRpb25FbGVtZW50IHtcbiAgY29uc3RydWN0b3IocGFyYW1ldGVycykge1xuICAgIGNvbnN0IGlzUmVuZGVyYWJsZSA9ICEhKHBhcmFtZXRlcnMuZGF0YS5oYXNQb3B1cCB8fCBwYXJhbWV0ZXJzLmRhdGEudGl0bGVPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEuY29udGVudHNPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEucmljaFRleHQ/LnN0cik7XG4gICAgc3VwZXIocGFyYW1ldGVycywge1xuICAgICAgaXNSZW5kZXJhYmxlLFxuICAgICAgaWdub3JlQm9yZGVyOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NOYW1lID0gXCJzcXVhcmVBbm5vdGF0aW9uXCI7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuZGF0YTtcbiAgICBjb25zdCB7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodFxuICAgIH0gPSBnZXRSZWN0RGltcyhkYXRhLnJlY3QpO1xuICAgIGNvbnN0IHN2ZyA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGUod2lkdGgsIGhlaWdodCk7XG4gICAgY29uc3QgYm9yZGVyV2lkdGggPSBkYXRhLmJvcmRlclN0eWxlLndpZHRoO1xuICAgIGNvbnN0IHNxdWFyZSA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOnJlY3RcIik7XG4gICAgc3F1YXJlLnNldEF0dHJpYnV0ZShcInhcIiwgYm9yZGVyV2lkdGggLyAyKTtcbiAgICBzcXVhcmUuc2V0QXR0cmlidXRlKFwieVwiLCBib3JkZXJXaWR0aCAvIDIpO1xuICAgIHNxdWFyZS5zZXRBdHRyaWJ1dGUoXCJ3aWR0aFwiLCB3aWR0aCAtIGJvcmRlcldpZHRoKTtcbiAgICBzcXVhcmUuc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIGhlaWdodCAtIGJvcmRlcldpZHRoKTtcbiAgICBzcXVhcmUuc2V0QXR0cmlidXRlKFwic3Ryb2tlLXdpZHRoXCIsIGJvcmRlcldpZHRoIHx8IDEpO1xuICAgIHNxdWFyZS5zZXRBdHRyaWJ1dGUoXCJzdHJva2VcIiwgXCJ0cmFuc3BhcmVudFwiKTtcbiAgICBzcXVhcmUuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBcInRyYW5zcGFyZW50XCIpO1xuICAgIHN2Zy5hcHBlbmRDaGlsZChzcXVhcmUpO1xuICAgIHRoaXMuY29udGFpbmVyLmFwcGVuZChzdmcpO1xuXG4gICAgdGhpcy5fY3JlYXRlUG9wdXAoc3F1YXJlLCBkYXRhKTtcblxuICAgIHJldHVybiB0aGlzLmNvbnRhaW5lcjtcbiAgfVxuXG59XG5cbmNsYXNzIENpcmNsZUFubm90YXRpb25FbGVtZW50IGV4dGVuZHMgQW5ub3RhdGlvbkVsZW1lbnQge1xuICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzKSB7XG4gICAgY29uc3QgaXNSZW5kZXJhYmxlID0gISEocGFyYW1ldGVycy5kYXRhLmhhc1BvcHVwIHx8IHBhcmFtZXRlcnMuZGF0YS50aXRsZU9iaj8uc3RyIHx8IHBhcmFtZXRlcnMuZGF0YS5jb250ZW50c09iaj8uc3RyIHx8IHBhcmFtZXRlcnMuZGF0YS5yaWNoVGV4dD8uc3RyKTtcbiAgICBzdXBlcihwYXJhbWV0ZXJzLCB7XG4gICAgICBpc1JlbmRlcmFibGUsXG4gICAgICBpZ25vcmVCb3JkZXI6IHRydWVcbiAgICB9KTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICB0aGlzLmNvbnRhaW5lci5jbGFzc05hbWUgPSBcImNpcmNsZUFubm90YXRpb25cIjtcbiAgICBjb25zdCBkYXRhID0gdGhpcy5kYXRhO1xuICAgIGNvbnN0IHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0XG4gICAgfSA9IGdldFJlY3REaW1zKGRhdGEucmVjdCk7XG4gICAgY29uc3Qgc3ZnID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZSh3aWR0aCwgaGVpZ2h0KTtcbiAgICBjb25zdCBib3JkZXJXaWR0aCA9IGRhdGEuYm9yZGVyU3R5bGUud2lkdGg7XG4gICAgY29uc3QgY2lyY2xlID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZUVsZW1lbnQoXCJzdmc6ZWxsaXBzZVwiKTtcbiAgICBjaXJjbGUuc2V0QXR0cmlidXRlKFwiY3hcIiwgd2lkdGggLyAyKTtcbiAgICBjaXJjbGUuc2V0QXR0cmlidXRlKFwiY3lcIiwgaGVpZ2h0IC8gMik7XG4gICAgY2lyY2xlLnNldEF0dHJpYnV0ZShcInJ4XCIsIHdpZHRoIC8gMiAtIGJvcmRlcldpZHRoIC8gMik7XG4gICAgY2lyY2xlLnNldEF0dHJpYnV0ZShcInJ5XCIsIGhlaWdodCAvIDIgLSBib3JkZXJXaWR0aCAvIDIpO1xuICAgIGNpcmNsZS5zZXRBdHRyaWJ1dGUoXCJzdHJva2Utd2lkdGhcIiwgYm9yZGVyV2lkdGggfHwgMSk7XG4gICAgY2lyY2xlLnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCBcInRyYW5zcGFyZW50XCIpO1xuICAgIGNpcmNsZS5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIFwidHJhbnNwYXJlbnRcIik7XG4gICAgc3ZnLmFwcGVuZENoaWxkKGNpcmNsZSk7XG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kKHN2Zyk7XG5cbiAgICB0aGlzLl9jcmVhdGVQb3B1cChjaXJjbGUsIGRhdGEpO1xuXG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgUG9seWxpbmVBbm5vdGF0aW9uRWxlbWVudCBleHRlbmRzIEFubm90YXRpb25FbGVtZW50IHtcbiAgY29uc3RydWN0b3IocGFyYW1ldGVycykge1xuICAgIGNvbnN0IGlzUmVuZGVyYWJsZSA9ICEhKHBhcmFtZXRlcnMuZGF0YS5oYXNQb3B1cCB8fCBwYXJhbWV0ZXJzLmRhdGEudGl0bGVPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEuY29udGVudHNPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEucmljaFRleHQ/LnN0cik7XG4gICAgc3VwZXIocGFyYW1ldGVycywge1xuICAgICAgaXNSZW5kZXJhYmxlLFxuICAgICAgaWdub3JlQm9yZGVyOiB0cnVlXG4gICAgfSk7XG4gICAgdGhpcy5jb250YWluZXJDbGFzc05hbWUgPSBcInBvbHlsaW5lQW5ub3RhdGlvblwiO1xuICAgIHRoaXMuc3ZnRWxlbWVudE5hbWUgPSBcInN2Zzpwb2x5bGluZVwiO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IHRoaXMuY29udGFpbmVyQ2xhc3NOYW1lO1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLmRhdGE7XG4gICAgY29uc3Qge1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHRcbiAgICB9ID0gZ2V0UmVjdERpbXMoZGF0YS5yZWN0KTtcbiAgICBjb25zdCBzdmcgPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlKHdpZHRoLCBoZWlnaHQpO1xuICAgIGxldCBwb2ludHMgPSBbXTtcblxuICAgIGZvciAoY29uc3QgY29vcmRpbmF0ZSBvZiBkYXRhLnZlcnRpY2VzKSB7XG4gICAgICBjb25zdCB4ID0gY29vcmRpbmF0ZS54IC0gZGF0YS5yZWN0WzBdO1xuICAgICAgY29uc3QgeSA9IGRhdGEucmVjdFszXSAtIGNvb3JkaW5hdGUueTtcbiAgICAgIHBvaW50cy5wdXNoKHggKyBcIixcIiArIHkpO1xuICAgIH1cblxuICAgIHBvaW50cyA9IHBvaW50cy5qb2luKFwiIFwiKTtcbiAgICBjb25zdCBwb2x5bGluZSA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KHRoaXMuc3ZnRWxlbWVudE5hbWUpO1xuICAgIHBvbHlsaW5lLnNldEF0dHJpYnV0ZShcInBvaW50c1wiLCBwb2ludHMpO1xuICAgIHBvbHlsaW5lLnNldEF0dHJpYnV0ZShcInN0cm9rZS13aWR0aFwiLCBkYXRhLmJvcmRlclN0eWxlLndpZHRoIHx8IDEpO1xuICAgIHBvbHlsaW5lLnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCBcInRyYW5zcGFyZW50XCIpO1xuICAgIHBvbHlsaW5lLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgXCJ0cmFuc3BhcmVudFwiKTtcbiAgICBzdmcuYXBwZW5kQ2hpbGQocG9seWxpbmUpO1xuICAgIHRoaXMuY29udGFpbmVyLmFwcGVuZChzdmcpO1xuXG4gICAgdGhpcy5fY3JlYXRlUG9wdXAocG9seWxpbmUsIGRhdGEpO1xuXG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgUG9seWdvbkFubm90YXRpb25FbGVtZW50IGV4dGVuZHMgUG9seWxpbmVBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB0aGlzLmNvbnRhaW5lckNsYXNzTmFtZSA9IFwicG9seWdvbkFubm90YXRpb25cIjtcbiAgICB0aGlzLnN2Z0VsZW1lbnROYW1lID0gXCJzdmc6cG9seWdvblwiO1xuICB9XG5cbn1cblxuY2xhc3MgQ2FyZXRBbm5vdGF0aW9uRWxlbWVudCBleHRlbmRzIEFubm90YXRpb25FbGVtZW50IHtcbiAgY29uc3RydWN0b3IocGFyYW1ldGVycykge1xuICAgIGNvbnN0IGlzUmVuZGVyYWJsZSA9ICEhKHBhcmFtZXRlcnMuZGF0YS5oYXNQb3B1cCB8fCBwYXJhbWV0ZXJzLmRhdGEudGl0bGVPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEuY29udGVudHNPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEucmljaFRleHQ/LnN0cik7XG4gICAgc3VwZXIocGFyYW1ldGVycywge1xuICAgICAgaXNSZW5kZXJhYmxlLFxuICAgICAgaWdub3JlQm9yZGVyOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NOYW1lID0gXCJjYXJldEFubm90YXRpb25cIjtcblxuICAgIGlmICghdGhpcy5kYXRhLmhhc1BvcHVwKSB7XG4gICAgICB0aGlzLl9jcmVhdGVQb3B1cChudWxsLCB0aGlzLmRhdGEpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbnRhaW5lcjtcbiAgfVxuXG59XG5cbmNsYXNzIElua0Fubm90YXRpb25FbGVtZW50IGV4dGVuZHMgQW5ub3RhdGlvbkVsZW1lbnQge1xuICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzKSB7XG4gICAgY29uc3QgaXNSZW5kZXJhYmxlID0gISEocGFyYW1ldGVycy5kYXRhLmhhc1BvcHVwIHx8IHBhcmFtZXRlcnMuZGF0YS50aXRsZU9iaj8uc3RyIHx8IHBhcmFtZXRlcnMuZGF0YS5jb250ZW50c09iaj8uc3RyIHx8IHBhcmFtZXRlcnMuZGF0YS5yaWNoVGV4dD8uc3RyKTtcbiAgICBzdXBlcihwYXJhbWV0ZXJzLCB7XG4gICAgICBpc1JlbmRlcmFibGUsXG4gICAgICBpZ25vcmVCb3JkZXI6IHRydWVcbiAgICB9KTtcbiAgICB0aGlzLmNvbnRhaW5lckNsYXNzTmFtZSA9IFwiaW5rQW5ub3RhdGlvblwiO1xuICAgIHRoaXMuc3ZnRWxlbWVudE5hbWUgPSBcInN2Zzpwb2x5bGluZVwiO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IHRoaXMuY29udGFpbmVyQ2xhc3NOYW1lO1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLmRhdGE7XG4gICAgY29uc3Qge1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHRcbiAgICB9ID0gZ2V0UmVjdERpbXMoZGF0YS5yZWN0KTtcbiAgICBjb25zdCBzdmcgPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlKHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgZm9yIChjb25zdCBpbmtMaXN0IG9mIGRhdGEuaW5rTGlzdHMpIHtcbiAgICAgIGxldCBwb2ludHMgPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBjb29yZGluYXRlIG9mIGlua0xpc3QpIHtcbiAgICAgICAgY29uc3QgeCA9IGNvb3JkaW5hdGUueCAtIGRhdGEucmVjdFswXTtcbiAgICAgICAgY29uc3QgeSA9IGRhdGEucmVjdFszXSAtIGNvb3JkaW5hdGUueTtcbiAgICAgICAgcG9pbnRzLnB1c2goYCR7eH0sJHt5fWApO1xuICAgICAgfVxuXG4gICAgICBwb2ludHMgPSBwb2ludHMuam9pbihcIiBcIik7XG4gICAgICBjb25zdCBwb2x5bGluZSA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KHRoaXMuc3ZnRWxlbWVudE5hbWUpO1xuICAgICAgcG9seWxpbmUuc2V0QXR0cmlidXRlKFwicG9pbnRzXCIsIHBvaW50cyk7XG4gICAgICBwb2x5bGluZS5zZXRBdHRyaWJ1dGUoXCJzdHJva2Utd2lkdGhcIiwgZGF0YS5ib3JkZXJTdHlsZS53aWR0aCB8fCAxKTtcbiAgICAgIHBvbHlsaW5lLnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCBcInRyYW5zcGFyZW50XCIpO1xuICAgICAgcG9seWxpbmUuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBcInRyYW5zcGFyZW50XCIpO1xuXG4gICAgICB0aGlzLl9jcmVhdGVQb3B1cChwb2x5bGluZSwgZGF0YSk7XG5cbiAgICAgIHN2Zy5hcHBlbmRDaGlsZChwb2x5bGluZSk7XG4gICAgfVxuXG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kKHN2Zyk7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgSGlnaGxpZ2h0QW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCBpc1JlbmRlcmFibGUgPSAhIShwYXJhbWV0ZXJzLmRhdGEuaGFzUG9wdXAgfHwgcGFyYW1ldGVycy5kYXRhLnRpdGxlT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLmNvbnRlbnRzT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLnJpY2hUZXh0Py5zdHIpO1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlzUmVuZGVyYWJsZSxcbiAgICAgIGlnbm9yZUJvcmRlcjogdHJ1ZSxcbiAgICAgIGNyZWF0ZVF1YWRyaWxhdGVyYWxzOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgaWYgKCF0aGlzLmRhdGEuaGFzUG9wdXApIHtcbiAgICAgIHRoaXMuX2NyZWF0ZVBvcHVwKG51bGwsIHRoaXMuZGF0YSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucXVhZHJpbGF0ZXJhbHMpIHtcbiAgICAgIHJldHVybiB0aGlzLl9yZW5kZXJRdWFkcmlsYXRlcmFscyhcImhpZ2hsaWdodEFubm90YXRpb25cIik7XG4gICAgfVxuXG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NOYW1lID0gXCJoaWdobGlnaHRBbm5vdGF0aW9uXCI7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgVW5kZXJsaW5lQW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCBpc1JlbmRlcmFibGUgPSAhIShwYXJhbWV0ZXJzLmRhdGEuaGFzUG9wdXAgfHwgcGFyYW1ldGVycy5kYXRhLnRpdGxlT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLmNvbnRlbnRzT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLnJpY2hUZXh0Py5zdHIpO1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlzUmVuZGVyYWJsZSxcbiAgICAgIGlnbm9yZUJvcmRlcjogdHJ1ZSxcbiAgICAgIGNyZWF0ZVF1YWRyaWxhdGVyYWxzOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgaWYgKCF0aGlzLmRhdGEuaGFzUG9wdXApIHtcbiAgICAgIHRoaXMuX2NyZWF0ZVBvcHVwKG51bGwsIHRoaXMuZGF0YSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucXVhZHJpbGF0ZXJhbHMpIHtcbiAgICAgIHJldHVybiB0aGlzLl9yZW5kZXJRdWFkcmlsYXRlcmFscyhcInVuZGVybGluZUFubm90YXRpb25cIik7XG4gICAgfVxuXG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NOYW1lID0gXCJ1bmRlcmxpbmVBbm5vdGF0aW9uXCI7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgU3F1aWdnbHlBbm5vdGF0aW9uRWxlbWVudCBleHRlbmRzIEFubm90YXRpb25FbGVtZW50IHtcbiAgY29uc3RydWN0b3IocGFyYW1ldGVycykge1xuICAgIGNvbnN0IGlzUmVuZGVyYWJsZSA9ICEhKHBhcmFtZXRlcnMuZGF0YS5oYXNQb3B1cCB8fCBwYXJhbWV0ZXJzLmRhdGEudGl0bGVPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEuY29udGVudHNPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEucmljaFRleHQ/LnN0cik7XG4gICAgc3VwZXIocGFyYW1ldGVycywge1xuICAgICAgaXNSZW5kZXJhYmxlLFxuICAgICAgaWdub3JlQm9yZGVyOiB0cnVlLFxuICAgICAgY3JlYXRlUXVhZHJpbGF0ZXJhbHM6IHRydWVcbiAgICB9KTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAoIXRoaXMuZGF0YS5oYXNQb3B1cCkge1xuICAgICAgdGhpcy5fY3JlYXRlUG9wdXAobnVsbCwgdGhpcy5kYXRhKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5xdWFkcmlsYXRlcmFscykge1xuICAgICAgcmV0dXJuIHRoaXMuX3JlbmRlclF1YWRyaWxhdGVyYWxzKFwic3F1aWdnbHlBbm5vdGF0aW9uXCIpO1xuICAgIH1cblxuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IFwic3F1aWdnbHlBbm5vdGF0aW9uXCI7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgU3RyaWtlT3V0QW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCBpc1JlbmRlcmFibGUgPSAhIShwYXJhbWV0ZXJzLmRhdGEuaGFzUG9wdXAgfHwgcGFyYW1ldGVycy5kYXRhLnRpdGxlT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLmNvbnRlbnRzT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLnJpY2hUZXh0Py5zdHIpO1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlzUmVuZGVyYWJsZSxcbiAgICAgIGlnbm9yZUJvcmRlcjogdHJ1ZSxcbiAgICAgIGNyZWF0ZVF1YWRyaWxhdGVyYWxzOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgaWYgKCF0aGlzLmRhdGEuaGFzUG9wdXApIHtcbiAgICAgIHRoaXMuX2NyZWF0ZVBvcHVwKG51bGwsIHRoaXMuZGF0YSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucXVhZHJpbGF0ZXJhbHMpIHtcbiAgICAgIHJldHVybiB0aGlzLl9yZW5kZXJRdWFkcmlsYXRlcmFscyhcInN0cmlrZW91dEFubm90YXRpb25cIik7XG4gICAgfVxuXG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NOYW1lID0gXCJzdHJpa2VvdXRBbm5vdGF0aW9uXCI7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgU3RhbXBBbm5vdGF0aW9uRWxlbWVudCBleHRlbmRzIEFubm90YXRpb25FbGVtZW50IHtcbiAgY29uc3RydWN0b3IocGFyYW1ldGVycykge1xuICAgIGNvbnN0IGlzUmVuZGVyYWJsZSA9ICEhKHBhcmFtZXRlcnMuZGF0YS5oYXNQb3B1cCB8fCBwYXJhbWV0ZXJzLmRhdGEudGl0bGVPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEuY29udGVudHNPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEucmljaFRleHQ/LnN0cik7XG4gICAgc3VwZXIocGFyYW1ldGVycywge1xuICAgICAgaXNSZW5kZXJhYmxlLFxuICAgICAgaWdub3JlQm9yZGVyOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NOYW1lID0gXCJzdGFtcEFubm90YXRpb25cIjtcblxuICAgIGlmICghdGhpcy5kYXRhLmhhc1BvcHVwKSB7XG4gICAgICB0aGlzLl9jcmVhdGVQb3B1cChudWxsLCB0aGlzLmRhdGEpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbnRhaW5lcjtcbiAgfVxuXG59XG5cbmNsYXNzIEZpbGVBdHRhY2htZW50QW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICBzdXBlcihwYXJhbWV0ZXJzLCB7XG4gICAgICBpc1JlbmRlcmFibGU6IHRydWVcbiAgICB9KTtcbiAgICBjb25zdCB7XG4gICAgICBmaWxlbmFtZSxcbiAgICAgIGNvbnRlbnRcbiAgICB9ID0gdGhpcy5kYXRhLmZpbGU7XG4gICAgdGhpcy5maWxlbmFtZSA9ICgwLCBfZGlzcGxheV91dGlscy5nZXRGaWxlbmFtZUZyb21VcmwpKGZpbGVuYW1lKTtcbiAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50O1xuICAgIHRoaXMubGlua1NlcnZpY2UuZXZlbnRCdXM/LmRpc3BhdGNoKFwiZmlsZWF0dGFjaG1lbnRhbm5vdGF0aW9uXCIsIHtcbiAgICAgIHNvdXJjZTogdGhpcyxcbiAgICAgIGZpbGVuYW1lLFxuICAgICAgY29udGVudFxuICAgIH0pO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IFwiZmlsZUF0dGFjaG1lbnRBbm5vdGF0aW9uXCI7XG4gICAgY29uc3QgdHJpZ2dlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgdHJpZ2dlci5zdHlsZS5oZWlnaHQgPSB0aGlzLmNvbnRhaW5lci5zdHlsZS5oZWlnaHQ7XG4gICAgdHJpZ2dlci5zdHlsZS53aWR0aCA9IHRoaXMuY29udGFpbmVyLnN0eWxlLndpZHRoO1xuICAgIHRyaWdnZXIuYWRkRXZlbnRMaXN0ZW5lcihcImRibGNsaWNrXCIsIHRoaXMuX2Rvd25sb2FkLmJpbmQodGhpcykpO1xuXG4gICAgaWYgKCF0aGlzLmRhdGEuaGFzUG9wdXAgJiYgKHRoaXMuZGF0YS50aXRsZU9iaj8uc3RyIHx8IHRoaXMuZGF0YS5jb250ZW50c09iaj8uc3RyIHx8IHRoaXMuZGF0YS5yaWNoVGV4dCkpIHtcbiAgICAgIHRoaXMuX2NyZWF0ZVBvcHVwKHRyaWdnZXIsIHRoaXMuZGF0YSk7XG4gICAgfVxuXG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQodHJpZ2dlcik7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbiAgX2Rvd25sb2FkKCkge1xuICAgIHRoaXMuZG93bmxvYWRNYW5hZ2VyPy5vcGVuT3JEb3dubG9hZERhdGEodGhpcy5jb250YWluZXIsIHRoaXMuY29udGVudCwgdGhpcy5maWxlbmFtZSk7XG4gIH1cblxufVxuXG5jbGFzcyBBbm5vdGF0aW9uTGF5ZXIge1xuICBzdGF0aWMgcmVuZGVyKHBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCBzb3J0ZWRBbm5vdGF0aW9ucyA9IFtdLFxuICAgICAgICAgIHBvcHVwQW5ub3RhdGlvbnMgPSBbXTtcblxuICAgIGZvciAoY29uc3QgZGF0YSBvZiBwYXJhbWV0ZXJzLmFubm90YXRpb25zKSB7XG4gICAgICBpZiAoIWRhdGEpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHtcbiAgICAgICAgd2lkdGgsXG4gICAgICAgIGhlaWdodFxuICAgICAgfSA9IGdldFJlY3REaW1zKGRhdGEucmVjdCk7XG5cbiAgICAgIGlmICh3aWR0aCA8PSAwIHx8IGhlaWdodCA8PSAwKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZGF0YS5hbm5vdGF0aW9uVHlwZSA9PT0gX3V0aWwuQW5ub3RhdGlvblR5cGUuUE9QVVApIHtcbiAgICAgICAgcG9wdXBBbm5vdGF0aW9ucy5wdXNoKGRhdGEpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgc29ydGVkQW5ub3RhdGlvbnMucHVzaChkYXRhKTtcbiAgICB9XG5cbiAgICBpZiAocG9wdXBBbm5vdGF0aW9ucy5sZW5ndGgpIHtcbiAgICAgIHNvcnRlZEFubm90YXRpb25zLnB1c2goLi4ucG9wdXBBbm5vdGF0aW9ucyk7XG4gICAgfVxuXG4gICAgY29uc3QgZGl2ID0gcGFyYW1ldGVycy5kaXY7XG5cbiAgICBmb3IgKGNvbnN0IGRhdGEgb2Ygc29ydGVkQW5ub3RhdGlvbnMpIHtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSBBbm5vdGF0aW9uRWxlbWVudEZhY3RvcnkuY3JlYXRlKHtcbiAgICAgICAgZGF0YSxcbiAgICAgICAgbGF5ZXI6IGRpdixcbiAgICAgICAgcGFnZTogcGFyYW1ldGVycy5wYWdlLFxuICAgICAgICB2aWV3cG9ydDogcGFyYW1ldGVycy52aWV3cG9ydCxcbiAgICAgICAgbGlua1NlcnZpY2U6IHBhcmFtZXRlcnMubGlua1NlcnZpY2UsXG4gICAgICAgIGRvd25sb2FkTWFuYWdlcjogcGFyYW1ldGVycy5kb3dubG9hZE1hbmFnZXIsXG4gICAgICAgIGltYWdlUmVzb3VyY2VzUGF0aDogcGFyYW1ldGVycy5pbWFnZVJlc291cmNlc1BhdGggfHwgXCJcIixcbiAgICAgICAgcmVuZGVyRm9ybXM6IHBhcmFtZXRlcnMucmVuZGVyRm9ybXMgIT09IGZhbHNlLFxuICAgICAgICBzdmdGYWN0b3J5OiBuZXcgX2Rpc3BsYXlfdXRpbHMuRE9NU1ZHRmFjdG9yeSgpLFxuICAgICAgICBhbm5vdGF0aW9uU3RvcmFnZTogcGFyYW1ldGVycy5hbm5vdGF0aW9uU3RvcmFnZSB8fCBuZXcgX2Fubm90YXRpb25fc3RvcmFnZS5Bbm5vdGF0aW9uU3RvcmFnZSgpLFxuICAgICAgICBlbmFibGVTY3JpcHRpbmc6IHBhcmFtZXRlcnMuZW5hYmxlU2NyaXB0aW5nLFxuICAgICAgICBoYXNKU0FjdGlvbnM6IHBhcmFtZXRlcnMuaGFzSlNBY3Rpb25zLFxuICAgICAgICBmaWVsZE9iamVjdHM6IHBhcmFtZXRlcnMuZmllbGRPYmplY3RzLFxuICAgICAgICBtb3VzZVN0YXRlOiBwYXJhbWV0ZXJzLm1vdXNlU3RhdGUgfHwge1xuICAgICAgICAgIGlzRG93bjogZmFsc2VcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGlmIChlbGVtZW50LmlzUmVuZGVyYWJsZSkge1xuICAgICAgICBjb25zdCByZW5kZXJlZCA9IGVsZW1lbnQucmVuZGVyKCk7XG5cbiAgICAgICAgaWYgKGRhdGEuaGlkZGVuKSB7XG4gICAgICAgICAgcmVuZGVyZWQuc3R5bGUudmlzaWJpbGl0eSA9IFwiaGlkZGVuXCI7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShyZW5kZXJlZCkpIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IHJlbmRlcmVkRWxlbWVudCBvZiByZW5kZXJlZCkge1xuICAgICAgICAgICAgZGl2LmFwcGVuZENoaWxkKHJlbmRlcmVkRWxlbWVudCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgUG9wdXBBbm5vdGF0aW9uRWxlbWVudCkge1xuICAgICAgICAgICAgZGl2LnByZXBlbmQocmVuZGVyZWQpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkaXYuYXBwZW5kQ2hpbGQocmVuZGVyZWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuI3NldEFubm90YXRpb25DYW52YXNNYXAoZGl2LCBwYXJhbWV0ZXJzLmFubm90YXRpb25DYW52YXNNYXApO1xuICB9XG5cbiAgc3RhdGljIHVwZGF0ZShwYXJhbWV0ZXJzKSB7XG4gICAgY29uc3Qge1xuICAgICAgcGFnZSxcbiAgICAgIHZpZXdwb3J0LFxuICAgICAgYW5ub3RhdGlvbnMsXG4gICAgICBhbm5vdGF0aW9uQ2FudmFzTWFwLFxuICAgICAgZGl2XG4gICAgfSA9IHBhcmFtZXRlcnM7XG4gICAgY29uc3QgdHJhbnNmb3JtID0gdmlld3BvcnQudHJhbnNmb3JtO1xuICAgIGNvbnN0IG1hdHJpeCA9IGBtYXRyaXgoJHt0cmFuc2Zvcm0uam9pbihcIixcIil9KWA7XG4gICAgbGV0IHNjYWxlLCBvd25NYXRyaXg7XG5cbiAgICBmb3IgKGNvbnN0IGRhdGEgb2YgYW5ub3RhdGlvbnMpIHtcbiAgICAgIGNvbnN0IGVsZW1lbnRzID0gZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoYFtkYXRhLWFubm90YXRpb24taWQ9XCIke2RhdGEuaWR9XCJdYCk7XG5cbiAgICAgIGlmIChlbGVtZW50cykge1xuICAgICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgZWxlbWVudHMpIHtcbiAgICAgICAgICBpZiAoZGF0YS5oYXNPd25DYW52YXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlY3QgPSBfdXRpbC5VdGlsLm5vcm1hbGl6ZVJlY3QoW2RhdGEucmVjdFswXSwgcGFnZS52aWV3WzNdIC0gZGF0YS5yZWN0WzFdICsgcGFnZS52aWV3WzFdLCBkYXRhLnJlY3RbMl0sIHBhZ2Uudmlld1szXSAtIGRhdGEucmVjdFszXSArIHBhZ2Uudmlld1sxXV0pO1xuXG4gICAgICAgICAgICBpZiAoIW93bk1hdHJpeCkge1xuICAgICAgICAgICAgICBzY2FsZSA9IE1hdGguYWJzKHRyYW5zZm9ybVswXSB8fCB0cmFuc2Zvcm1bMV0pO1xuICAgICAgICAgICAgICBjb25zdCBvd25UcmFuc2Zvcm0gPSB0cmFuc2Zvcm0uc2xpY2UoKTtcblxuICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgICAgICAgICAgICAgIG93blRyYW5zZm9ybVtpXSA9IE1hdGguc2lnbihvd25UcmFuc2Zvcm1baV0pO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgb3duTWF0cml4ID0gYG1hdHJpeCgke293blRyYW5zZm9ybS5qb2luKFwiLFwiKX0pYDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgbGVmdCA9IHJlY3RbMF0gKiBzY2FsZTtcbiAgICAgICAgICAgIGNvbnN0IHRvcCA9IHJlY3RbMV0gKiBzY2FsZTtcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUubGVmdCA9IGAke2xlZnR9cHhgO1xuICAgICAgICAgICAgZWxlbWVudC5zdHlsZS50b3AgPSBgJHt0b3B9cHhgO1xuICAgICAgICAgICAgZWxlbWVudC5zdHlsZS50cmFuc2Zvcm1PcmlnaW4gPSBgJHstbGVmdH1weCAkey10b3B9cHhgO1xuICAgICAgICAgICAgZWxlbWVudC5zdHlsZS50cmFuc2Zvcm0gPSBvd25NYXRyaXg7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUudHJhbnNmb3JtID0gbWF0cml4O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuI3NldEFubm90YXRpb25DYW52YXNNYXAoZGl2LCBhbm5vdGF0aW9uQ2FudmFzTWFwKTtcbiAgICBkaXYuaGlkZGVuID0gZmFsc2U7XG4gIH1cblxuICBzdGF0aWMgI3NldEFubm90YXRpb25DYW52YXNNYXAoZGl2LCBhbm5vdGF0aW9uQ2FudmFzTWFwKSB7XG4gICAgaWYgKCFhbm5vdGF0aW9uQ2FudmFzTWFwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBbaWQsIGNhbnZhc10gb2YgYW5ub3RhdGlvbkNhbnZhc01hcCkge1xuICAgICAgY29uc3QgZWxlbWVudCA9IGRpdi5xdWVyeVNlbGVjdG9yKGBbZGF0YS1hbm5vdGF0aW9uLWlkPVwiJHtpZH1cIl1gKTtcblxuICAgICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7XG4gICAgICAgIGZpcnN0Q2hpbGRcbiAgICAgIH0gPSBlbGVtZW50O1xuXG4gICAgICBpZiAoZmlyc3RDaGlsZC5ub2RlTmFtZSA9PT0gXCJDQU5WQVNcIikge1xuICAgICAgICBlbGVtZW50LnJlcGxhY2VDaGlsZChjYW52YXMsIGZpcnN0Q2hpbGQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWxlbWVudC5pbnNlcnRCZWZvcmUoY2FudmFzLCBmaXJzdENoaWxkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBhbm5vdGF0aW9uQ2FudmFzTWFwLmNsZWFyKCk7XG4gIH1cblxufVxuXG5leHBvcnRzLkFubm90YXRpb25MYXllciA9IEFubm90YXRpb25MYXllcjtcblxuLyoqKi8gfSksXG4vKiAyMSAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5Db2xvckNvbnZlcnRlcnMgPSB2b2lkIDA7XG5cbmZ1bmN0aW9uIG1ha2VDb2xvckNvbXAobikge1xuICByZXR1cm4gTWF0aC5mbG9vcihNYXRoLm1heCgwLCBNYXRoLm1pbigxLCBuKSkgKiAyNTUpLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCBcIjBcIik7XG59XG5cbmNsYXNzIENvbG9yQ29udmVydGVycyB7XG4gIHN0YXRpYyBDTVlLX0coW2MsIHksIG0sIGtdKSB7XG4gICAgcmV0dXJuIFtcIkdcIiwgMSAtIE1hdGgubWluKDEsIDAuMyAqIGMgKyAwLjU5ICogbSArIDAuMTEgKiB5ICsgayldO1xuICB9XG5cbiAgc3RhdGljIEdfQ01ZSyhbZ10pIHtcbiAgICByZXR1cm4gW1wiQ01ZS1wiLCAwLCAwLCAwLCAxIC0gZ107XG4gIH1cblxuICBzdGF0aWMgR19SR0IoW2ddKSB7XG4gICAgcmV0dXJuIFtcIlJHQlwiLCBnLCBnLCBnXTtcbiAgfVxuXG4gIHN0YXRpYyBHX0hUTUwoW2ddKSB7XG4gICAgY29uc3QgRyA9IG1ha2VDb2xvckNvbXAoZyk7XG4gICAgcmV0dXJuIGAjJHtHfSR7R30ke0d9YDtcbiAgfVxuXG4gIHN0YXRpYyBSR0JfRyhbciwgZywgYl0pIHtcbiAgICByZXR1cm4gW1wiR1wiLCAwLjMgKiByICsgMC41OSAqIGcgKyAwLjExICogYl07XG4gIH1cblxuICBzdGF0aWMgUkdCX0hUTUwoW3IsIGcsIGJdKSB7XG4gICAgY29uc3QgUiA9IG1ha2VDb2xvckNvbXAocik7XG4gICAgY29uc3QgRyA9IG1ha2VDb2xvckNvbXAoZyk7XG4gICAgY29uc3QgQiA9IG1ha2VDb2xvckNvbXAoYik7XG4gICAgcmV0dXJuIGAjJHtSfSR7R30ke0J9YDtcbiAgfVxuXG4gIHN0YXRpYyBUX0hUTUwoKSB7XG4gICAgcmV0dXJuIFwiIzAwMDAwMDAwXCI7XG4gIH1cblxuICBzdGF0aWMgQ01ZS19SR0IoW2MsIHksIG0sIGtdKSB7XG4gICAgcmV0dXJuIFtcIlJHQlwiLCAxIC0gTWF0aC5taW4oMSwgYyArIGspLCAxIC0gTWF0aC5taW4oMSwgbSArIGspLCAxIC0gTWF0aC5taW4oMSwgeSArIGspXTtcbiAgfVxuXG4gIHN0YXRpYyBDTVlLX0hUTUwoY29tcG9uZW50cykge1xuICAgIHJldHVybiB0aGlzLlJHQl9IVE1MKHRoaXMuQ01ZS19SR0IoY29tcG9uZW50cykpO1xuICB9XG5cbiAgc3RhdGljIFJHQl9DTVlLKFtyLCBnLCBiXSkge1xuICAgIGNvbnN0IGMgPSAxIC0gcjtcbiAgICBjb25zdCBtID0gMSAtIGc7XG4gICAgY29uc3QgeSA9IDEgLSBiO1xuICAgIGNvbnN0IGsgPSBNYXRoLm1pbihjLCBtLCB5KTtcbiAgICByZXR1cm4gW1wiQ01ZS1wiLCBjLCBtLCB5LCBrXTtcbiAgfVxuXG59XG5cbmV4cG9ydHMuQ29sb3JDb252ZXJ0ZXJzID0gQ29sb3JDb252ZXJ0ZXJzO1xuXG4vKioqLyB9KSxcbi8qIDIyICovXG4vKioqLyAoKF9fdW51c2VkX3dlYnBhY2tfbW9kdWxlLCBleHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5leHBvcnRzLlhmYUxheWVyID0gdm9pZCAwO1xuXG52YXIgX3hmYV90ZXh0ID0gX193X3BkZmpzX3JlcXVpcmVfXygxOCk7XG5cbmNsYXNzIFhmYUxheWVyIHtcbiAgc3RhdGljIHNldHVwU3RvcmFnZShodG1sLCBpZCwgZWxlbWVudCwgc3RvcmFnZSwgaW50ZW50KSB7XG4gICAgY29uc3Qgc3RvcmVkRGF0YSA9IHN0b3JhZ2UuZ2V0VmFsdWUoaWQsIHtcbiAgICAgIHZhbHVlOiBudWxsXG4gICAgfSk7XG5cbiAgICBzd2l0Y2ggKGVsZW1lbnQubmFtZSkge1xuICAgICAgY2FzZSBcInRleHRhcmVhXCI6XG4gICAgICAgIGlmIChzdG9yZWREYXRhLnZhbHVlICE9PSBudWxsKSB7XG4gICAgICAgICAgaHRtbC50ZXh0Q29udGVudCA9IHN0b3JlZERhdGEudmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaW50ZW50ID09PSBcInByaW50XCIpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGh0bWwuYWRkRXZlbnRMaXN0ZW5lcihcImlucHV0XCIsIGV2ZW50ID0+IHtcbiAgICAgICAgICBzdG9yYWdlLnNldFZhbHVlKGlkLCB7XG4gICAgICAgICAgICB2YWx1ZTogZXZlbnQudGFyZ2V0LnZhbHVlXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcImlucHV0XCI6XG4gICAgICAgIGlmIChlbGVtZW50LmF0dHJpYnV0ZXMudHlwZSA9PT0gXCJyYWRpb1wiIHx8IGVsZW1lbnQuYXR0cmlidXRlcy50eXBlID09PSBcImNoZWNrYm94XCIpIHtcbiAgICAgICAgICBpZiAoc3RvcmVkRGF0YS52YWx1ZSA9PT0gZWxlbWVudC5hdHRyaWJ1dGVzLnhmYU9uKSB7XG4gICAgICAgICAgICBodG1sLnNldEF0dHJpYnV0ZShcImNoZWNrZWRcIiwgdHJ1ZSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChzdG9yZWREYXRhLnZhbHVlID09PSBlbGVtZW50LmF0dHJpYnV0ZXMueGZhT2ZmKSB7XG4gICAgICAgICAgICBodG1sLnJlbW92ZUF0dHJpYnV0ZShcImNoZWNrZWRcIik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGludGVudCA9PT0gXCJwcmludFwiKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBodG1sLmFkZEV2ZW50TGlzdGVuZXIoXCJjaGFuZ2VcIiwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgc3RvcmFnZS5zZXRWYWx1ZShpZCwge1xuICAgICAgICAgICAgICB2YWx1ZTogZXZlbnQudGFyZ2V0LmNoZWNrZWQgPyBldmVudC50YXJnZXQuZ2V0QXR0cmlidXRlKFwieGZhT25cIikgOiBldmVudC50YXJnZXQuZ2V0QXR0cmlidXRlKFwieGZhT2ZmXCIpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoc3RvcmVkRGF0YS52YWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaHRtbC5zZXRBdHRyaWJ1dGUoXCJ2YWx1ZVwiLCBzdG9yZWREYXRhLnZhbHVlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaW50ZW50ID09PSBcInByaW50XCIpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGh0bWwuYWRkRXZlbnRMaXN0ZW5lcihcImlucHV0XCIsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICAgICAgdmFsdWU6IGV2ZW50LnRhcmdldC52YWx1ZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcInNlbGVjdFwiOlxuICAgICAgICBpZiAoc3RvcmVkRGF0YS52YWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIGVsZW1lbnQuY2hpbGRyZW4pIHtcbiAgICAgICAgICAgIGlmIChvcHRpb24uYXR0cmlidXRlcy52YWx1ZSA9PT0gc3RvcmVkRGF0YS52YWx1ZSkge1xuICAgICAgICAgICAgICBvcHRpb24uYXR0cmlidXRlcy5zZWxlY3RlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaHRtbC5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIiwgZXZlbnQgPT4ge1xuICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSBldmVudC50YXJnZXQub3B0aW9ucztcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IG9wdGlvbnMuc2VsZWN0ZWRJbmRleCA9PT0gLTEgPyBcIlwiIDogb3B0aW9uc1tvcHRpb25zLnNlbGVjdGVkSW5kZXhdLnZhbHVlO1xuICAgICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICAgIHZhbHVlXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgc2V0QXR0cmlidXRlcyh7XG4gICAgaHRtbCxcbiAgICBlbGVtZW50LFxuICAgIHN0b3JhZ2UgPSBudWxsLFxuICAgIGludGVudCxcbiAgICBsaW5rU2VydmljZVxuICB9KSB7XG4gICAgY29uc3Qge1xuICAgICAgYXR0cmlidXRlc1xuICAgIH0gPSBlbGVtZW50O1xuICAgIGNvbnN0IGlzSFRNTEFuY2hvckVsZW1lbnQgPSBodG1sIGluc3RhbmNlb2YgSFRNTEFuY2hvckVsZW1lbnQ7XG5cbiAgICBpZiAoYXR0cmlidXRlcy50eXBlID09PSBcInJhZGlvXCIpIHtcbiAgICAgIGF0dHJpYnV0ZXMubmFtZSA9IGAke2F0dHJpYnV0ZXMubmFtZX0tJHtpbnRlbnR9YDtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhhdHRyaWJ1dGVzKSkge1xuICAgICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgfHwga2V5ID09PSBcImRhdGFJZFwiKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoa2V5ICE9PSBcInN0eWxlXCIpIHtcbiAgICAgICAgaWYgKGtleSA9PT0gXCJ0ZXh0Q29udGVudFwiKSB7XG4gICAgICAgICAgaHRtbC50ZXh0Q29udGVudCA9IHZhbHVlO1xuICAgICAgICB9IGVsc2UgaWYgKGtleSA9PT0gXCJjbGFzc1wiKSB7XG4gICAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCkge1xuICAgICAgICAgICAgaHRtbC5zZXRBdHRyaWJ1dGUoa2V5LCB2YWx1ZS5qb2luKFwiIFwiKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChpc0hUTUxBbmNob3JFbGVtZW50ICYmIChrZXkgPT09IFwiaHJlZlwiIHx8IGtleSA9PT0gXCJuZXdXaW5kb3dcIikpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGh0bWwuc2V0QXR0cmlidXRlKGtleSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBPYmplY3QuYXNzaWduKGh0bWwuc3R5bGUsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNIVE1MQW5jaG9yRWxlbWVudCkge1xuICAgICAgbGlua1NlcnZpY2UuYWRkTGlua0F0dHJpYnV0ZXMoaHRtbCwgYXR0cmlidXRlcy5ocmVmLCBhdHRyaWJ1dGVzLm5ld1dpbmRvdyk7XG4gICAgfVxuXG4gICAgaWYgKHN0b3JhZ2UgJiYgYXR0cmlidXRlcy5kYXRhSWQpIHtcbiAgICAgIHRoaXMuc2V0dXBTdG9yYWdlKGh0bWwsIGF0dHJpYnV0ZXMuZGF0YUlkLCBlbGVtZW50LCBzdG9yYWdlKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgcmVuZGVyKHBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCBzdG9yYWdlID0gcGFyYW1ldGVycy5hbm5vdGF0aW9uU3RvcmFnZTtcbiAgICBjb25zdCBsaW5rU2VydmljZSA9IHBhcmFtZXRlcnMubGlua1NlcnZpY2U7XG4gICAgY29uc3Qgcm9vdCA9IHBhcmFtZXRlcnMueGZhSHRtbDtcbiAgICBjb25zdCBpbnRlbnQgPSBwYXJhbWV0ZXJzLmludGVudCB8fCBcImRpc3BsYXlcIjtcbiAgICBjb25zdCByb290SHRtbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQocm9vdC5uYW1lKTtcblxuICAgIGlmIChyb290LmF0dHJpYnV0ZXMpIHtcbiAgICAgIHRoaXMuc2V0QXR0cmlidXRlcyh7XG4gICAgICAgIGh0bWw6IHJvb3RIdG1sLFxuICAgICAgICBlbGVtZW50OiByb290LFxuICAgICAgICBpbnRlbnQsXG4gICAgICAgIGxpbmtTZXJ2aWNlXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBzdGFjayA9IFtbcm9vdCwgLTEsIHJvb3RIdG1sXV07XG4gICAgY29uc3Qgcm9vdERpdiA9IHBhcmFtZXRlcnMuZGl2O1xuICAgIHJvb3REaXYuYXBwZW5kQ2hpbGQocm9vdEh0bWwpO1xuXG4gICAgaWYgKHBhcmFtZXRlcnMudmlld3BvcnQpIHtcbiAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IGBtYXRyaXgoJHtwYXJhbWV0ZXJzLnZpZXdwb3J0LnRyYW5zZm9ybS5qb2luKFwiLFwiKX0pYDtcbiAgICAgIHJvb3REaXYuc3R5bGUudHJhbnNmb3JtID0gdHJhbnNmb3JtO1xuICAgIH1cblxuICAgIGlmIChpbnRlbnQgIT09IFwicmljaFRleHRcIikge1xuICAgICAgcm9vdERpdi5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBcInhmYUxheWVyIHhmYUZvbnRcIik7XG4gICAgfVxuXG4gICAgY29uc3QgdGV4dERpdnMgPSBbXTtcblxuICAgIHdoaWxlIChzdGFjay5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBbcGFyZW50LCBpLCBodG1sXSA9IHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdO1xuXG4gICAgICBpZiAoaSArIDEgPT09IHBhcmVudC5jaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjaGlsZCA9IHBhcmVudC5jaGlsZHJlblsrK3N0YWNrW3N0YWNrLmxlbmd0aCAtIDFdWzFdXTtcblxuICAgICAgaWYgKGNoaWxkID09PSBudWxsKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7XG4gICAgICAgIG5hbWVcbiAgICAgIH0gPSBjaGlsZDtcblxuICAgICAgaWYgKG5hbWUgPT09IFwiI3RleHRcIikge1xuICAgICAgICBjb25zdCBub2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoY2hpbGQudmFsdWUpO1xuICAgICAgICB0ZXh0RGl2cy5wdXNoKG5vZGUpO1xuICAgICAgICBodG1sLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgbGV0IGNoaWxkSHRtbDtcblxuICAgICAgaWYgKGNoaWxkPy5hdHRyaWJ1dGVzPy54bWxucykge1xuICAgICAgICBjaGlsZEh0bWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoY2hpbGQuYXR0cmlidXRlcy54bWxucywgbmFtZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjaGlsZEh0bWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KG5hbWUpO1xuICAgICAgfVxuXG4gICAgICBodG1sLmFwcGVuZENoaWxkKGNoaWxkSHRtbCk7XG5cbiAgICAgIGlmIChjaGlsZC5hdHRyaWJ1dGVzKSB7XG4gICAgICAgIHRoaXMuc2V0QXR0cmlidXRlcyh7XG4gICAgICAgICAgaHRtbDogY2hpbGRIdG1sLFxuICAgICAgICAgIGVsZW1lbnQ6IGNoaWxkLFxuICAgICAgICAgIHN0b3JhZ2UsXG4gICAgICAgICAgaW50ZW50LFxuICAgICAgICAgIGxpbmtTZXJ2aWNlXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2hpbGQuY2hpbGRyZW4gJiYgY2hpbGQuY2hpbGRyZW4ubGVuZ3RoID4gMCkge1xuICAgICAgICBzdGFjay5wdXNoKFtjaGlsZCwgLTEsIGNoaWxkSHRtbF0pO1xuICAgICAgfSBlbHNlIGlmIChjaGlsZC52YWx1ZSkge1xuICAgICAgICBjb25zdCBub2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoY2hpbGQudmFsdWUpO1xuXG4gICAgICAgIGlmIChfeGZhX3RleHQuWGZhVGV4dC5zaG91bGRCdWlsZFRleHQobmFtZSkpIHtcbiAgICAgICAgICB0ZXh0RGl2cy5wdXNoKG5vZGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgY2hpbGRIdG1sLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZWwgb2Ygcm9vdERpdi5xdWVyeVNlbGVjdG9yQWxsKFwiLnhmYU5vbkludGVyYWN0aXZlIGlucHV0LCAueGZhTm9uSW50ZXJhY3RpdmUgdGV4dGFyZWFcIikpIHtcbiAgICAgIGVsLnNldEF0dHJpYnV0ZShcInJlYWRPbmx5XCIsIHRydWUpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB0ZXh0RGl2c1xuICAgIH07XG4gIH1cblxuICBzdGF0aWMgdXBkYXRlKHBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCB0cmFuc2Zvcm0gPSBgbWF0cml4KCR7cGFyYW1ldGVycy52aWV3cG9ydC50cmFuc2Zvcm0uam9pbihcIixcIil9KWA7XG4gICAgcGFyYW1ldGVycy5kaXYuc3R5bGUudHJhbnNmb3JtID0gdHJhbnNmb3JtO1xuICAgIHBhcmFtZXRlcnMuZGl2LmhpZGRlbiA9IGZhbHNlO1xuICB9XG5cbn1cblxuZXhwb3J0cy5YZmFMYXllciA9IFhmYUxheWVyO1xuXG4vKioqLyB9KSxcbi8qIDIzICovXG4vKioqLyAoKF9fdW51c2VkX3dlYnBhY2tfbW9kdWxlLCBleHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5leHBvcnRzLnJlbmRlclRleHRMYXllciA9IHJlbmRlclRleHRMYXllcjtcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxuY29uc3QgTUFYX1RFWFRfRElWU19UT19SRU5ERVIgPSAxMDAwMDA7XG5jb25zdCBERUZBVUxUX0ZPTlRfU0laRSA9IDMwO1xuY29uc3QgREVGQVVMVF9GT05UX0FTQ0VOVCA9IDAuODtcbmNvbnN0IGFzY2VudENhY2hlID0gbmV3IE1hcCgpO1xuY29uc3QgQWxsV2hpdGVzcGFjZVJlZ2V4cCA9IC9eXFxzKyQvZztcblxuZnVuY3Rpb24gZ2V0QXNjZW50KGZvbnRGYW1pbHksIGN0eCkge1xuICBjb25zdCBjYWNoZWRBc2NlbnQgPSBhc2NlbnRDYWNoZS5nZXQoZm9udEZhbWlseSk7XG5cbiAgaWYgKGNhY2hlZEFzY2VudCkge1xuICAgIHJldHVybiBjYWNoZWRBc2NlbnQ7XG4gIH1cblxuICBjdHguc2F2ZSgpO1xuICBjdHguZm9udCA9IGAke0RFRkFVTFRfRk9OVF9TSVpFfXB4ICR7Zm9udEZhbWlseX1gO1xuICBjb25zdCBtZXRyaWNzID0gY3R4Lm1lYXN1cmVUZXh0KFwiXCIpO1xuICBsZXQgYXNjZW50ID0gbWV0cmljcy5mb250Qm91bmRpbmdCb3hBc2NlbnQ7XG4gIGxldCBkZXNjZW50ID0gTWF0aC5hYnMobWV0cmljcy5mb250Qm91bmRpbmdCb3hEZXNjZW50KTtcblxuICBpZiAoYXNjZW50KSB7XG4gICAgY3R4LnJlc3RvcmUoKTtcbiAgICBjb25zdCByYXRpbyA9IGFzY2VudCAvIChhc2NlbnQgKyBkZXNjZW50KTtcbiAgICBhc2NlbnRDYWNoZS5zZXQoZm9udEZhbWlseSwgcmF0aW8pO1xuICAgIHJldHVybiByYXRpbztcbiAgfVxuXG4gIGN0eC5zdHJva2VTdHlsZSA9IFwicmVkXCI7XG4gIGN0eC5jbGVhclJlY3QoMCwgMCwgREVGQVVMVF9GT05UX1NJWkUsIERFRkFVTFRfRk9OVF9TSVpFKTtcbiAgY3R4LnN0cm9rZVRleHQoXCJnXCIsIDAsIDApO1xuICBsZXQgcGl4ZWxzID0gY3R4LmdldEltYWdlRGF0YSgwLCAwLCBERUZBVUxUX0ZPTlRfU0laRSwgREVGQVVMVF9GT05UX1NJWkUpLmRhdGE7XG4gIGRlc2NlbnQgPSAwO1xuXG4gIGZvciAobGV0IGkgPSBwaXhlbHMubGVuZ3RoIC0gMSAtIDM7IGkgPj0gMDsgaSAtPSA0KSB7XG4gICAgaWYgKHBpeGVsc1tpXSA+IDApIHtcbiAgICAgIGRlc2NlbnQgPSBNYXRoLmNlaWwoaSAvIDQgLyBERUZBVUxUX0ZPTlRfU0laRSk7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBjdHguY2xlYXJSZWN0KDAsIDAsIERFRkFVTFRfRk9OVF9TSVpFLCBERUZBVUxUX0ZPTlRfU0laRSk7XG4gIGN0eC5zdHJva2VUZXh0KFwiQVwiLCAwLCBERUZBVUxUX0ZPTlRfU0laRSk7XG4gIHBpeGVscyA9IGN0eC5nZXRJbWFnZURhdGEoMCwgMCwgREVGQVVMVF9GT05UX1NJWkUsIERFRkFVTFRfRk9OVF9TSVpFKS5kYXRhO1xuICBhc2NlbnQgPSAwO1xuXG4gIGZvciAobGV0IGkgPSAwLCBpaSA9IHBpeGVscy5sZW5ndGg7IGkgPCBpaTsgaSArPSA0KSB7XG4gICAgaWYgKHBpeGVsc1tpXSA+IDApIHtcbiAgICAgIGFzY2VudCA9IERFRkFVTFRfRk9OVF9TSVpFIC0gTWF0aC5mbG9vcihpIC8gNCAvIERFRkFVTFRfRk9OVF9TSVpFKTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGN0eC5yZXN0b3JlKCk7XG5cbiAgaWYgKGFzY2VudCkge1xuICAgIGNvbnN0IHJhdGlvID0gYXNjZW50IC8gKGFzY2VudCArIGRlc2NlbnQpO1xuICAgIGFzY2VudENhY2hlLnNldChmb250RmFtaWx5LCByYXRpbyk7XG4gICAgcmV0dXJuIHJhdGlvO1xuICB9XG5cbiAgYXNjZW50Q2FjaGUuc2V0KGZvbnRGYW1pbHksIERFRkFVTFRfRk9OVF9BU0NFTlQpO1xuICByZXR1cm4gREVGQVVMVF9GT05UX0FTQ0VOVDtcbn1cblxuZnVuY3Rpb24gYXBwZW5kVGV4dCh0YXNrLCBnZW9tLCBzdHlsZXMsIGN0eCkge1xuICBjb25zdCB0ZXh0RGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNwYW5cIik7XG4gIGNvbnN0IHRleHREaXZQcm9wZXJ0aWVzID0gdGFzay5fZW5oYW5jZVRleHRTZWxlY3Rpb24gPyB7XG4gICAgYW5nbGU6IDAsXG4gICAgY2FudmFzV2lkdGg6IDAsXG4gICAgaGFzVGV4dDogZ2VvbS5zdHIgIT09IFwiXCIsXG4gICAgaGFzRU9MOiBnZW9tLmhhc0VPTCxcbiAgICBvcmlnaW5hbFRyYW5zZm9ybTogbnVsbCxcbiAgICBwYWRkaW5nQm90dG9tOiAwLFxuICAgIHBhZGRpbmdMZWZ0OiAwLFxuICAgIHBhZGRpbmdSaWdodDogMCxcbiAgICBwYWRkaW5nVG9wOiAwLFxuICAgIHNjYWxlOiAxXG4gIH0gOiB7XG4gICAgYW5nbGU6IDAsXG4gICAgY2FudmFzV2lkdGg6IDAsXG4gICAgaGFzVGV4dDogZ2VvbS5zdHIgIT09IFwiXCIsXG4gICAgaGFzRU9MOiBnZW9tLmhhc0VPTFxuICB9O1xuXG4gIHRhc2suX3RleHREaXZzLnB1c2godGV4dERpdik7XG5cbiAgY29uc3QgdHggPSBfdXRpbC5VdGlsLnRyYW5zZm9ybSh0YXNrLl92aWV3cG9ydC50cmFuc2Zvcm0sIGdlb20udHJhbnNmb3JtKTtcblxuICBsZXQgYW5nbGUgPSBNYXRoLmF0YW4yKHR4WzFdLCB0eFswXSk7XG4gIGNvbnN0IHN0eWxlID0gc3R5bGVzW2dlb20uZm9udE5hbWVdO1xuXG4gIGlmIChzdHlsZS52ZXJ0aWNhbCkge1xuICAgIGFuZ2xlICs9IE1hdGguUEkgLyAyO1xuICB9XG5cbiAgY29uc3QgZm9udEhlaWdodCA9IE1hdGguaHlwb3QodHhbMl0sIHR4WzNdKTtcbiAgY29uc3QgZm9udEFzY2VudCA9IGZvbnRIZWlnaHQgKiBnZXRBc2NlbnQoc3R5bGUuZm9udEZhbWlseSwgY3R4KTtcbiAgbGV0IGxlZnQsIHRvcDtcblxuICBpZiAoYW5nbGUgPT09IDApIHtcbiAgICBsZWZ0ID0gdHhbNF07XG4gICAgdG9wID0gdHhbNV0gLSBmb250QXNjZW50O1xuICB9IGVsc2Uge1xuICAgIGxlZnQgPSB0eFs0XSArIGZvbnRBc2NlbnQgKiBNYXRoLnNpbihhbmdsZSk7XG4gICAgdG9wID0gdHhbNV0gLSBmb250QXNjZW50ICogTWF0aC5jb3MoYW5nbGUpO1xuICB9XG5cbiAgdGV4dERpdi5zdHlsZS5sZWZ0ID0gYCR7bGVmdH1weGA7XG4gIHRleHREaXYuc3R5bGUudG9wID0gYCR7dG9wfXB4YDtcbiAgdGV4dERpdi5zdHlsZS5mb250U2l6ZSA9IGAke2ZvbnRIZWlnaHR9cHhgO1xuICB0ZXh0RGl2LnN0eWxlLmZvbnRGYW1pbHkgPSBzdHlsZS5mb250RmFtaWx5O1xuICB0ZXh0RGl2LnNldEF0dHJpYnV0ZShcInJvbGVcIiwgXCJwcmVzZW50YXRpb25cIik7XG4gIHRleHREaXYudGV4dENvbnRlbnQgPSBnZW9tLnN0cjtcbiAgdGV4dERpdi5kaXIgPSBnZW9tLmRpcjtcblxuICBpZiAodGFzay5fZm9udEluc3BlY3RvckVuYWJsZWQpIHtcbiAgICB0ZXh0RGl2LmRhdGFzZXQuZm9udE5hbWUgPSBnZW9tLmZvbnROYW1lO1xuICB9XG5cbiAgaWYgKGFuZ2xlICE9PSAwKSB7XG4gICAgdGV4dERpdlByb3BlcnRpZXMuYW5nbGUgPSBhbmdsZSAqICgxODAgLyBNYXRoLlBJKTtcbiAgfVxuXG4gIGxldCBzaG91bGRTY2FsZVRleHQgPSBmYWxzZTtcblxuICBpZiAoZ2VvbS5zdHIubGVuZ3RoID4gMSB8fCB0YXNrLl9lbmhhbmNlVGV4dFNlbGVjdGlvbiAmJiBBbGxXaGl0ZXNwYWNlUmVnZXhwLnRlc3QoZ2VvbS5zdHIpKSB7XG4gICAgc2hvdWxkU2NhbGVUZXh0ID0gdHJ1ZTtcbiAgfSBlbHNlIGlmIChnZW9tLnN0ciAhPT0gXCIgXCIgJiYgZ2VvbS50cmFuc2Zvcm1bMF0gIT09IGdlb20udHJhbnNmb3JtWzNdKSB7XG4gICAgY29uc3QgYWJzU2NhbGVYID0gTWF0aC5hYnMoZ2VvbS50cmFuc2Zvcm1bMF0pLFxuICAgICAgICAgIGFic1NjYWxlWSA9IE1hdGguYWJzKGdlb20udHJhbnNmb3JtWzNdKTtcblxuICAgIGlmIChhYnNTY2FsZVggIT09IGFic1NjYWxlWSAmJiBNYXRoLm1heChhYnNTY2FsZVgsIGFic1NjYWxlWSkgLyBNYXRoLm1pbihhYnNTY2FsZVgsIGFic1NjYWxlWSkgPiAxLjUpIHtcbiAgICAgIHNob3VsZFNjYWxlVGV4dCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgaWYgKHNob3VsZFNjYWxlVGV4dCkge1xuICAgIGlmIChzdHlsZS52ZXJ0aWNhbCkge1xuICAgICAgdGV4dERpdlByb3BlcnRpZXMuY2FudmFzV2lkdGggPSBnZW9tLmhlaWdodCAqIHRhc2suX3ZpZXdwb3J0LnNjYWxlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0ZXh0RGl2UHJvcGVydGllcy5jYW52YXNXaWR0aCA9IGdlb20ud2lkdGggKiB0YXNrLl92aWV3cG9ydC5zY2FsZTtcbiAgICB9XG4gIH1cblxuICB0YXNrLl90ZXh0RGl2UHJvcGVydGllcy5zZXQodGV4dERpdiwgdGV4dERpdlByb3BlcnRpZXMpO1xuXG4gIGlmICh0YXNrLl90ZXh0Q29udGVudFN0cmVhbSkge1xuICAgIHRhc2suX2xheW91dFRleHQodGV4dERpdik7XG4gIH1cblxuICBpZiAodGFzay5fZW5oYW5jZVRleHRTZWxlY3Rpb24gJiYgdGV4dERpdlByb3BlcnRpZXMuaGFzVGV4dCkge1xuICAgIGxldCBhbmdsZUNvcyA9IDEsXG4gICAgICAgIGFuZ2xlU2luID0gMDtcblxuICAgIGlmIChhbmdsZSAhPT0gMCkge1xuICAgICAgYW5nbGVDb3MgPSBNYXRoLmNvcyhhbmdsZSk7XG4gICAgICBhbmdsZVNpbiA9IE1hdGguc2luKGFuZ2xlKTtcbiAgICB9XG5cbiAgICBjb25zdCBkaXZXaWR0aCA9IChzdHlsZS52ZXJ0aWNhbCA/IGdlb20uaGVpZ2h0IDogZ2VvbS53aWR0aCkgKiB0YXNrLl92aWV3cG9ydC5zY2FsZTtcbiAgICBjb25zdCBkaXZIZWlnaHQgPSBmb250SGVpZ2h0O1xuICAgIGxldCBtLCBiO1xuXG4gICAgaWYgKGFuZ2xlICE9PSAwKSB7XG4gICAgICBtID0gW2FuZ2xlQ29zLCBhbmdsZVNpbiwgLWFuZ2xlU2luLCBhbmdsZUNvcywgbGVmdCwgdG9wXTtcbiAgICAgIGIgPSBfdXRpbC5VdGlsLmdldEF4aWFsQWxpZ25lZEJvdW5kaW5nQm94KFswLCAwLCBkaXZXaWR0aCwgZGl2SGVpZ2h0XSwgbSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGIgPSBbbGVmdCwgdG9wLCBsZWZ0ICsgZGl2V2lkdGgsIHRvcCArIGRpdkhlaWdodF07XG4gICAgfVxuXG4gICAgdGFzay5fYm91bmRzLnB1c2goe1xuICAgICAgbGVmdDogYlswXSxcbiAgICAgIHRvcDogYlsxXSxcbiAgICAgIHJpZ2h0OiBiWzJdLFxuICAgICAgYm90dG9tOiBiWzNdLFxuICAgICAgZGl2OiB0ZXh0RGl2LFxuICAgICAgc2l6ZTogW2RpdldpZHRoLCBkaXZIZWlnaHRdLFxuICAgICAgbVxuICAgIH0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlbmRlcih0YXNrKSB7XG4gIGlmICh0YXNrLl9jYW5jZWxlZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHRleHREaXZzID0gdGFzay5fdGV4dERpdnM7XG4gIGNvbnN0IGNhcGFiaWxpdHkgPSB0YXNrLl9jYXBhYmlsaXR5O1xuICBjb25zdCB0ZXh0RGl2c0xlbmd0aCA9IHRleHREaXZzLmxlbmd0aDtcblxuICBpZiAodGV4dERpdnNMZW5ndGggPiBNQVhfVEVYVF9ESVZTX1RPX1JFTkRFUikge1xuICAgIHRhc2suX3JlbmRlcmluZ0RvbmUgPSB0cnVlO1xuICAgIGNhcGFiaWxpdHkucmVzb2x2ZSgpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICghdGFzay5fdGV4dENvbnRlbnRTdHJlYW0pIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRleHREaXZzTGVuZ3RoOyBpKyspIHtcbiAgICAgIHRhc2suX2xheW91dFRleHQodGV4dERpdnNbaV0pO1xuICAgIH1cbiAgfVxuXG4gIHRhc2suX3JlbmRlcmluZ0RvbmUgPSB0cnVlO1xuICBjYXBhYmlsaXR5LnJlc29sdmUoKTtcbn1cblxuZnVuY3Rpb24gZmluZFBvc2l0aXZlTWluKHRzLCBvZmZzZXQsIGNvdW50KSB7XG4gIGxldCByZXN1bHQgPSAwO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgIGNvbnN0IHQgPSB0c1tvZmZzZXQrK107XG5cbiAgICBpZiAodCA+IDApIHtcbiAgICAgIHJlc3VsdCA9IHJlc3VsdCA/IE1hdGgubWluKHQsIHJlc3VsdCkgOiB0O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGV4cGFuZCh0YXNrKSB7XG4gIGNvbnN0IGJvdW5kcyA9IHRhc2suX2JvdW5kcztcbiAgY29uc3Qgdmlld3BvcnQgPSB0YXNrLl92aWV3cG9ydDtcbiAgY29uc3QgZXhwYW5kZWQgPSBleHBhbmRCb3VuZHModmlld3BvcnQud2lkdGgsIHZpZXdwb3J0LmhlaWdodCwgYm91bmRzKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cGFuZGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgZGl2ID0gYm91bmRzW2ldLmRpdjtcblxuICAgIGNvbnN0IGRpdlByb3BlcnRpZXMgPSB0YXNrLl90ZXh0RGl2UHJvcGVydGllcy5nZXQoZGl2KTtcblxuICAgIGlmIChkaXZQcm9wZXJ0aWVzLmFuZ2xlID09PSAwKSB7XG4gICAgICBkaXZQcm9wZXJ0aWVzLnBhZGRpbmdMZWZ0ID0gYm91bmRzW2ldLmxlZnQgLSBleHBhbmRlZFtpXS5sZWZ0O1xuICAgICAgZGl2UHJvcGVydGllcy5wYWRkaW5nVG9wID0gYm91bmRzW2ldLnRvcCAtIGV4cGFuZGVkW2ldLnRvcDtcbiAgICAgIGRpdlByb3BlcnRpZXMucGFkZGluZ1JpZ2h0ID0gZXhwYW5kZWRbaV0ucmlnaHQgLSBib3VuZHNbaV0ucmlnaHQ7XG4gICAgICBkaXZQcm9wZXJ0aWVzLnBhZGRpbmdCb3R0b20gPSBleHBhbmRlZFtpXS5ib3R0b20gLSBib3VuZHNbaV0uYm90dG9tO1xuXG4gICAgICB0YXNrLl90ZXh0RGl2UHJvcGVydGllcy5zZXQoZGl2LCBkaXZQcm9wZXJ0aWVzKTtcblxuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY29uc3QgZSA9IGV4cGFuZGVkW2ldLFxuICAgICAgICAgIGIgPSBib3VuZHNbaV07XG4gICAgY29uc3QgbSA9IGIubSxcbiAgICAgICAgICBjID0gbVswXSxcbiAgICAgICAgICBzID0gbVsxXTtcbiAgICBjb25zdCBwb2ludHMgPSBbWzAsIDBdLCBbMCwgYi5zaXplWzFdXSwgW2Iuc2l6ZVswXSwgMF0sIGIuc2l6ZV07XG4gICAgY29uc3QgdHMgPSBuZXcgRmxvYXQ2NEFycmF5KDY0KTtcblxuICAgIGZvciAobGV0IGogPSAwLCBqaiA9IHBvaW50cy5sZW5ndGg7IGogPCBqajsgaisrKSB7XG4gICAgICBjb25zdCB0ID0gX3V0aWwuVXRpbC5hcHBseVRyYW5zZm9ybShwb2ludHNbal0sIG0pO1xuXG4gICAgICB0c1tqICsgMF0gPSBjICYmIChlLmxlZnQgLSB0WzBdKSAvIGM7XG4gICAgICB0c1tqICsgNF0gPSBzICYmIChlLnRvcCAtIHRbMV0pIC8gcztcbiAgICAgIHRzW2ogKyA4XSA9IGMgJiYgKGUucmlnaHQgLSB0WzBdKSAvIGM7XG4gICAgICB0c1tqICsgMTJdID0gcyAmJiAoZS5ib3R0b20gLSB0WzFdKSAvIHM7XG4gICAgICB0c1tqICsgMTZdID0gcyAmJiAoZS5sZWZ0IC0gdFswXSkgLyAtcztcbiAgICAgIHRzW2ogKyAyMF0gPSBjICYmIChlLnRvcCAtIHRbMV0pIC8gYztcbiAgICAgIHRzW2ogKyAyNF0gPSBzICYmIChlLnJpZ2h0IC0gdFswXSkgLyAtcztcbiAgICAgIHRzW2ogKyAyOF0gPSBjICYmIChlLmJvdHRvbSAtIHRbMV0pIC8gYztcbiAgICAgIHRzW2ogKyAzMl0gPSBjICYmIChlLmxlZnQgLSB0WzBdKSAvIC1jO1xuICAgICAgdHNbaiArIDM2XSA9IHMgJiYgKGUudG9wIC0gdFsxXSkgLyAtcztcbiAgICAgIHRzW2ogKyA0MF0gPSBjICYmIChlLnJpZ2h0IC0gdFswXSkgLyAtYztcbiAgICAgIHRzW2ogKyA0NF0gPSBzICYmIChlLmJvdHRvbSAtIHRbMV0pIC8gLXM7XG4gICAgICB0c1tqICsgNDhdID0gcyAmJiAoZS5sZWZ0IC0gdFswXSkgLyBzO1xuICAgICAgdHNbaiArIDUyXSA9IGMgJiYgKGUudG9wIC0gdFsxXSkgLyAtYztcbiAgICAgIHRzW2ogKyA1Nl0gPSBzICYmIChlLnJpZ2h0IC0gdFswXSkgLyBzO1xuICAgICAgdHNbaiArIDYwXSA9IGMgJiYgKGUuYm90dG9tIC0gdFsxXSkgLyAtYztcbiAgICB9XG5cbiAgICBjb25zdCBib3hTY2FsZSA9IDEgKyBNYXRoLm1pbihNYXRoLmFicyhjKSwgTWF0aC5hYnMocykpO1xuICAgIGRpdlByb3BlcnRpZXMucGFkZGluZ0xlZnQgPSBmaW5kUG9zaXRpdmVNaW4odHMsIDMyLCAxNikgLyBib3hTY2FsZTtcbiAgICBkaXZQcm9wZXJ0aWVzLnBhZGRpbmdUb3AgPSBmaW5kUG9zaXRpdmVNaW4odHMsIDQ4LCAxNikgLyBib3hTY2FsZTtcbiAgICBkaXZQcm9wZXJ0aWVzLnBhZGRpbmdSaWdodCA9IGZpbmRQb3NpdGl2ZU1pbih0cywgMCwgMTYpIC8gYm94U2NhbGU7XG4gICAgZGl2UHJvcGVydGllcy5wYWRkaW5nQm90dG9tID0gZmluZFBvc2l0aXZlTWluKHRzLCAxNiwgMTYpIC8gYm94U2NhbGU7XG5cbiAgICB0YXNrLl90ZXh0RGl2UHJvcGVydGllcy5zZXQoZGl2LCBkaXZQcm9wZXJ0aWVzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBleHBhbmRCb3VuZHMod2lkdGgsIGhlaWdodCwgYm94ZXMpIHtcbiAgY29uc3QgYm91bmRzID0gYm94ZXMubWFwKGZ1bmN0aW9uIChib3gsIGkpIHtcbiAgICByZXR1cm4ge1xuICAgICAgeDE6IGJveC5sZWZ0LFxuICAgICAgeTE6IGJveC50b3AsXG4gICAgICB4MjogYm94LnJpZ2h0LFxuICAgICAgeTI6IGJveC5ib3R0b20sXG4gICAgICBpbmRleDogaSxcbiAgICAgIHgxTmV3OiB1bmRlZmluZWQsXG4gICAgICB4Mk5ldzogdW5kZWZpbmVkXG4gICAgfTtcbiAgfSk7XG4gIGV4cGFuZEJvdW5kc0xUUih3aWR0aCwgYm91bmRzKTtcbiAgY29uc3QgZXhwYW5kZWQgPSBuZXcgQXJyYXkoYm94ZXMubGVuZ3RoKTtcblxuICBmb3IgKGNvbnN0IGIgb2YgYm91bmRzKSB7XG4gICAgY29uc3QgaSA9IGIuaW5kZXg7XG4gICAgZXhwYW5kZWRbaV0gPSB7XG4gICAgICBsZWZ0OiBiLngxTmV3LFxuICAgICAgdG9wOiAwLFxuICAgICAgcmlnaHQ6IGIueDJOZXcsXG4gICAgICBib3R0b206IDBcbiAgICB9O1xuICB9XG5cbiAgYm94ZXMubWFwKGZ1bmN0aW9uIChib3gsIGkpIHtcbiAgICBjb25zdCBlID0gZXhwYW5kZWRbaV0sXG4gICAgICAgICAgYiA9IGJvdW5kc1tpXTtcbiAgICBiLngxID0gYm94LnRvcDtcbiAgICBiLnkxID0gd2lkdGggLSBlLnJpZ2h0O1xuICAgIGIueDIgPSBib3guYm90dG9tO1xuICAgIGIueTIgPSB3aWR0aCAtIGUubGVmdDtcbiAgICBiLmluZGV4ID0gaTtcbiAgICBiLngxTmV3ID0gdW5kZWZpbmVkO1xuICAgIGIueDJOZXcgPSB1bmRlZmluZWQ7XG4gIH0pO1xuICBleHBhbmRCb3VuZHNMVFIoaGVpZ2h0LCBib3VuZHMpO1xuXG4gIGZvciAoY29uc3QgYiBvZiBib3VuZHMpIHtcbiAgICBjb25zdCBpID0gYi5pbmRleDtcbiAgICBleHBhbmRlZFtpXS50b3AgPSBiLngxTmV3O1xuICAgIGV4cGFuZGVkW2ldLmJvdHRvbSA9IGIueDJOZXc7XG4gIH1cblxuICByZXR1cm4gZXhwYW5kZWQ7XG59XG5cbmZ1bmN0aW9uIGV4cGFuZEJvdW5kc0xUUih3aWR0aCwgYm91bmRzKSB7XG4gIGJvdW5kcy5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgcmV0dXJuIGEueDEgLSBiLngxIHx8IGEuaW5kZXggLSBiLmluZGV4O1xuICB9KTtcbiAgY29uc3QgZmFrZUJvdW5kYXJ5ID0ge1xuICAgIHgxOiAtSW5maW5pdHksXG4gICAgeTE6IC1JbmZpbml0eSxcbiAgICB4MjogMCxcbiAgICB5MjogSW5maW5pdHksXG4gICAgaW5kZXg6IC0xLFxuICAgIHgxTmV3OiAwLFxuICAgIHgyTmV3OiAwXG4gIH07XG4gIGNvbnN0IGhvcml6b24gPSBbe1xuICAgIHN0YXJ0OiAtSW5maW5pdHksXG4gICAgZW5kOiBJbmZpbml0eSxcbiAgICBib3VuZGFyeTogZmFrZUJvdW5kYXJ5XG4gIH1dO1xuXG4gIGZvciAoY29uc3QgYm91bmRhcnkgb2YgYm91bmRzKSB7XG4gICAgbGV0IGkgPSAwO1xuXG4gICAgd2hpbGUgKGkgPCBob3Jpem9uLmxlbmd0aCAmJiBob3Jpem9uW2ldLmVuZCA8PSBib3VuZGFyeS55MSkge1xuICAgICAgaSsrO1xuICAgIH1cblxuICAgIGxldCBqID0gaG9yaXpvbi5sZW5ndGggLSAxO1xuXG4gICAgd2hpbGUgKGogPj0gMCAmJiBob3Jpem9uW2pdLnN0YXJ0ID49IGJvdW5kYXJ5LnkyKSB7XG4gICAgICBqLS07XG4gICAgfVxuXG4gICAgbGV0IGhvcml6b25QYXJ0LCBhZmZlY3RlZEJvdW5kYXJ5O1xuICAgIGxldCBxLFxuICAgICAgICBrLFxuICAgICAgICBtYXhYTmV3ID0gLUluZmluaXR5O1xuXG4gICAgZm9yIChxID0gaTsgcSA8PSBqOyBxKyspIHtcbiAgICAgIGhvcml6b25QYXJ0ID0gaG9yaXpvbltxXTtcbiAgICAgIGFmZmVjdGVkQm91bmRhcnkgPSBob3Jpem9uUGFydC5ib3VuZGFyeTtcbiAgICAgIGxldCB4TmV3O1xuXG4gICAgICBpZiAoYWZmZWN0ZWRCb3VuZGFyeS54MiA+IGJvdW5kYXJ5LngxKSB7XG4gICAgICAgIHhOZXcgPSBhZmZlY3RlZEJvdW5kYXJ5LmluZGV4ID4gYm91bmRhcnkuaW5kZXggPyBhZmZlY3RlZEJvdW5kYXJ5LngxTmV3IDogYm91bmRhcnkueDE7XG4gICAgICB9IGVsc2UgaWYgKGFmZmVjdGVkQm91bmRhcnkueDJOZXcgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB4TmV3ID0gKGFmZmVjdGVkQm91bmRhcnkueDIgKyBib3VuZGFyeS54MSkgLyAyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgeE5ldyA9IGFmZmVjdGVkQm91bmRhcnkueDJOZXc7XG4gICAgICB9XG5cbiAgICAgIGlmICh4TmV3ID4gbWF4WE5ldykge1xuICAgICAgICBtYXhYTmV3ID0geE5ldztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBib3VuZGFyeS54MU5ldyA9IG1heFhOZXc7XG5cbiAgICBmb3IgKHEgPSBpOyBxIDw9IGo7IHErKykge1xuICAgICAgaG9yaXpvblBhcnQgPSBob3Jpem9uW3FdO1xuICAgICAgYWZmZWN0ZWRCb3VuZGFyeSA9IGhvcml6b25QYXJ0LmJvdW5kYXJ5O1xuXG4gICAgICBpZiAoYWZmZWN0ZWRCb3VuZGFyeS54Mk5ldyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChhZmZlY3RlZEJvdW5kYXJ5LngyID4gYm91bmRhcnkueDEpIHtcbiAgICAgICAgICBpZiAoYWZmZWN0ZWRCb3VuZGFyeS5pbmRleCA+IGJvdW5kYXJ5LmluZGV4KSB7XG4gICAgICAgICAgICBhZmZlY3RlZEJvdW5kYXJ5LngyTmV3ID0gYWZmZWN0ZWRCb3VuZGFyeS54MjtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYWZmZWN0ZWRCb3VuZGFyeS54Mk5ldyA9IG1heFhOZXc7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoYWZmZWN0ZWRCb3VuZGFyeS54Mk5ldyA+IG1heFhOZXcpIHtcbiAgICAgICAgYWZmZWN0ZWRCb3VuZGFyeS54Mk5ldyA9IE1hdGgubWF4KG1heFhOZXcsIGFmZmVjdGVkQm91bmRhcnkueDIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGNoYW5nZWRIb3Jpem9uID0gW107XG4gICAgbGV0IGxhc3RCb3VuZGFyeSA9IG51bGw7XG5cbiAgICBmb3IgKHEgPSBpOyBxIDw9IGo7IHErKykge1xuICAgICAgaG9yaXpvblBhcnQgPSBob3Jpem9uW3FdO1xuICAgICAgYWZmZWN0ZWRCb3VuZGFyeSA9IGhvcml6b25QYXJ0LmJvdW5kYXJ5O1xuICAgICAgY29uc3QgdXNlQm91bmRhcnkgPSBhZmZlY3RlZEJvdW5kYXJ5LngyID4gYm91bmRhcnkueDIgPyBhZmZlY3RlZEJvdW5kYXJ5IDogYm91bmRhcnk7XG5cbiAgICAgIGlmIChsYXN0Qm91bmRhcnkgPT09IHVzZUJvdW5kYXJ5KSB7XG4gICAgICAgIGNoYW5nZWRIb3Jpem9uW2NoYW5nZWRIb3Jpem9uLmxlbmd0aCAtIDFdLmVuZCA9IGhvcml6b25QYXJ0LmVuZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNoYW5nZWRIb3Jpem9uLnB1c2goe1xuICAgICAgICAgIHN0YXJ0OiBob3Jpem9uUGFydC5zdGFydCxcbiAgICAgICAgICBlbmQ6IGhvcml6b25QYXJ0LmVuZCxcbiAgICAgICAgICBib3VuZGFyeTogdXNlQm91bmRhcnlcbiAgICAgICAgfSk7XG4gICAgICAgIGxhc3RCb3VuZGFyeSA9IHVzZUJvdW5kYXJ5O1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChob3Jpem9uW2ldLnN0YXJ0IDwgYm91bmRhcnkueTEpIHtcbiAgICAgIGNoYW5nZWRIb3Jpem9uWzBdLnN0YXJ0ID0gYm91bmRhcnkueTE7XG4gICAgICBjaGFuZ2VkSG9yaXpvbi51bnNoaWZ0KHtcbiAgICAgICAgc3RhcnQ6IGhvcml6b25baV0uc3RhcnQsXG4gICAgICAgIGVuZDogYm91bmRhcnkueTEsXG4gICAgICAgIGJvdW5kYXJ5OiBob3Jpem9uW2ldLmJvdW5kYXJ5XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoYm91bmRhcnkueTIgPCBob3Jpem9uW2pdLmVuZCkge1xuICAgICAgY2hhbmdlZEhvcml6b25bY2hhbmdlZEhvcml6b24ubGVuZ3RoIC0gMV0uZW5kID0gYm91bmRhcnkueTI7XG4gICAgICBjaGFuZ2VkSG9yaXpvbi5wdXNoKHtcbiAgICAgICAgc3RhcnQ6IGJvdW5kYXJ5LnkyLFxuICAgICAgICBlbmQ6IGhvcml6b25bal0uZW5kLFxuICAgICAgICBib3VuZGFyeTogaG9yaXpvbltqXS5ib3VuZGFyeVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgZm9yIChxID0gaTsgcSA8PSBqOyBxKyspIHtcbiAgICAgIGhvcml6b25QYXJ0ID0gaG9yaXpvbltxXTtcbiAgICAgIGFmZmVjdGVkQm91bmRhcnkgPSBob3Jpem9uUGFydC5ib3VuZGFyeTtcblxuICAgICAgaWYgKGFmZmVjdGVkQm91bmRhcnkueDJOZXcgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgbGV0IHVzZWQgPSBmYWxzZTtcblxuICAgICAgZm9yIChrID0gaSAtIDE7ICF1c2VkICYmIGsgPj0gMCAmJiBob3Jpem9uW2tdLnN0YXJ0ID49IGFmZmVjdGVkQm91bmRhcnkueTE7IGstLSkge1xuICAgICAgICB1c2VkID0gaG9yaXpvbltrXS5ib3VuZGFyeSA9PT0gYWZmZWN0ZWRCb3VuZGFyeTtcbiAgICAgIH1cblxuICAgICAgZm9yIChrID0gaiArIDE7ICF1c2VkICYmIGsgPCBob3Jpem9uLmxlbmd0aCAmJiBob3Jpem9uW2tdLmVuZCA8PSBhZmZlY3RlZEJvdW5kYXJ5LnkyOyBrKyspIHtcbiAgICAgICAgdXNlZCA9IGhvcml6b25ba10uYm91bmRhcnkgPT09IGFmZmVjdGVkQm91bmRhcnk7XG4gICAgICB9XG5cbiAgICAgIGZvciAoayA9IDA7ICF1c2VkICYmIGsgPCBjaGFuZ2VkSG9yaXpvbi5sZW5ndGg7IGsrKykge1xuICAgICAgICB1c2VkID0gY2hhbmdlZEhvcml6b25ba10uYm91bmRhcnkgPT09IGFmZmVjdGVkQm91bmRhcnk7XG4gICAgICB9XG5cbiAgICAgIGlmICghdXNlZCkge1xuICAgICAgICBhZmZlY3RlZEJvdW5kYXJ5LngyTmV3ID0gbWF4WE5ldztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBBcnJheS5wcm90b3R5cGUuc3BsaWNlLmFwcGx5KGhvcml6b24sIFtpLCBqIC0gaSArIDFdLmNvbmNhdChjaGFuZ2VkSG9yaXpvbikpO1xuICB9XG5cbiAgZm9yIChjb25zdCBob3Jpem9uUGFydCBvZiBob3Jpem9uKSB7XG4gICAgY29uc3QgYWZmZWN0ZWRCb3VuZGFyeSA9IGhvcml6b25QYXJ0LmJvdW5kYXJ5O1xuXG4gICAgaWYgKGFmZmVjdGVkQm91bmRhcnkueDJOZXcgPT09IHVuZGVmaW5lZCkge1xuICAgICAgYWZmZWN0ZWRCb3VuZGFyeS54Mk5ldyA9IE1hdGgubWF4KHdpZHRoLCBhZmZlY3RlZEJvdW5kYXJ5LngyKTtcbiAgICB9XG4gIH1cbn1cblxuY2xhc3MgVGV4dExheWVyUmVuZGVyVGFzayB7XG4gIGNvbnN0cnVjdG9yKHtcbiAgICB0ZXh0Q29udGVudCxcbiAgICB0ZXh0Q29udGVudFN0cmVhbSxcbiAgICBjb250YWluZXIsXG4gICAgdmlld3BvcnQsXG4gICAgdGV4dERpdnMsXG4gICAgdGV4dENvbnRlbnRJdGVtc1N0cixcbiAgICBlbmhhbmNlVGV4dFNlbGVjdGlvblxuICB9KSB7XG4gICAgdGhpcy5fdGV4dENvbnRlbnQgPSB0ZXh0Q29udGVudDtcbiAgICB0aGlzLl90ZXh0Q29udGVudFN0cmVhbSA9IHRleHRDb250ZW50U3RyZWFtO1xuICAgIHRoaXMuX2NvbnRhaW5lciA9IGNvbnRhaW5lcjtcbiAgICB0aGlzLl9kb2N1bWVudCA9IGNvbnRhaW5lci5vd25lckRvY3VtZW50O1xuICAgIHRoaXMuX3ZpZXdwb3J0ID0gdmlld3BvcnQ7XG4gICAgdGhpcy5fdGV4dERpdnMgPSB0ZXh0RGl2cyB8fCBbXTtcbiAgICB0aGlzLl90ZXh0Q29udGVudEl0ZW1zU3RyID0gdGV4dENvbnRlbnRJdGVtc1N0ciB8fCBbXTtcbiAgICB0aGlzLl9lbmhhbmNlVGV4dFNlbGVjdGlvbiA9ICEhZW5oYW5jZVRleHRTZWxlY3Rpb247XG4gICAgdGhpcy5fZm9udEluc3BlY3RvckVuYWJsZWQgPSAhIWdsb2JhbFRoaXMuRm9udEluc3BlY3Rvcj8uZW5hYmxlZDtcbiAgICB0aGlzLl9yZWFkZXIgPSBudWxsO1xuICAgIHRoaXMuX2xheW91dFRleHRMYXN0Rm9udFNpemUgPSBudWxsO1xuICAgIHRoaXMuX2xheW91dFRleHRMYXN0Rm9udEZhbWlseSA9IG51bGw7XG4gICAgdGhpcy5fbGF5b3V0VGV4dEN0eCA9IG51bGw7XG4gICAgdGhpcy5fdGV4dERpdlByb3BlcnRpZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgIHRoaXMuX3JlbmRlcmluZ0RvbmUgPSBmYWxzZTtcbiAgICB0aGlzLl9jYW5jZWxlZCA9IGZhbHNlO1xuICAgIHRoaXMuX2NhcGFiaWxpdHkgPSAoMCwgX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkpKCk7XG4gICAgdGhpcy5fcmVuZGVyVGltZXIgPSBudWxsO1xuICAgIHRoaXMuX2JvdW5kcyA9IFtdO1xuXG4gICAgdGhpcy5fY2FwYWJpbGl0eS5wcm9taXNlLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLl9lbmhhbmNlVGV4dFNlbGVjdGlvbikge1xuICAgICAgICB0aGlzLl90ZXh0RGl2UHJvcGVydGllcyA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLl9sYXlvdXRUZXh0Q3R4KSB7XG4gICAgICAgIHRoaXMuX2xheW91dFRleHRDdHguY2FudmFzLndpZHRoID0gMDtcbiAgICAgICAgdGhpcy5fbGF5b3V0VGV4dEN0eC5jYW52YXMuaGVpZ2h0ID0gMDtcbiAgICAgICAgdGhpcy5fbGF5b3V0VGV4dEN0eCA9IG51bGw7XG4gICAgICB9XG4gICAgfSkuY2F0Y2goKCkgPT4ge30pO1xuICB9XG5cbiAgZ2V0IHByb21pc2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxuXG4gIGNhbmNlbCgpIHtcbiAgICB0aGlzLl9jYW5jZWxlZCA9IHRydWU7XG5cbiAgICBpZiAodGhpcy5fcmVhZGVyKSB7XG4gICAgICB0aGlzLl9yZWFkZXIuY2FuY2VsKG5ldyBfdXRpbC5BYm9ydEV4Y2VwdGlvbihcIlRleHRMYXllciB0YXNrIGNhbmNlbGxlZC5cIikpLmNhdGNoKCgpID0+IHt9KTtcblxuICAgICAgdGhpcy5fcmVhZGVyID0gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fcmVuZGVyVGltZXIgIT09IG51bGwpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9yZW5kZXJUaW1lcik7XG4gICAgICB0aGlzLl9yZW5kZXJUaW1lciA9IG51bGw7XG4gICAgfVxuXG4gICAgdGhpcy5fY2FwYWJpbGl0eS5yZWplY3QobmV3IEVycm9yKFwiVGV4dExheWVyIHRhc2sgY2FuY2VsbGVkLlwiKSk7XG4gIH1cblxuICBfcHJvY2Vzc0l0ZW1zKGl0ZW1zLCBzdHlsZUNhY2hlKSB7XG4gICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGl0ZW1zLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBpZiAoaXRlbXNbaV0uc3RyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKGl0ZW1zW2ldLnR5cGUgPT09IFwiYmVnaW5NYXJrZWRDb250ZW50UHJvcHNcIiB8fCBpdGVtc1tpXS50eXBlID09PSBcImJlZ2luTWFya2VkQ29udGVudFwiKSB7XG4gICAgICAgICAgY29uc3QgcGFyZW50ID0gdGhpcy5fY29udGFpbmVyO1xuICAgICAgICAgIHRoaXMuX2NvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpO1xuXG4gICAgICAgICAgdGhpcy5fY29udGFpbmVyLmNsYXNzTGlzdC5hZGQoXCJtYXJrZWRDb250ZW50XCIpO1xuXG4gICAgICAgICAgaWYgKGl0ZW1zW2ldLmlkICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9jb250YWluZXIuc2V0QXR0cmlidXRlKFwiaWRcIiwgYCR7aXRlbXNbaV0uaWR9YCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcGFyZW50LmFwcGVuZENoaWxkKHRoaXMuX2NvbnRhaW5lcik7XG4gICAgICAgIH0gZWxzZSBpZiAoaXRlbXNbaV0udHlwZSA9PT0gXCJlbmRNYXJrZWRDb250ZW50XCIpIHtcbiAgICAgICAgICB0aGlzLl9jb250YWluZXIgPSB0aGlzLl9jb250YWluZXIucGFyZW50Tm9kZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl90ZXh0Q29udGVudEl0ZW1zU3RyLnB1c2goaXRlbXNbaV0uc3RyKTtcblxuICAgICAgYXBwZW5kVGV4dCh0aGlzLCBpdGVtc1tpXSwgc3R5bGVDYWNoZSwgdGhpcy5fbGF5b3V0VGV4dEN0eCk7XG4gICAgfVxuICB9XG5cbiAgX2xheW91dFRleHQodGV4dERpdikge1xuICAgIGNvbnN0IHRleHREaXZQcm9wZXJ0aWVzID0gdGhpcy5fdGV4dERpdlByb3BlcnRpZXMuZ2V0KHRleHREaXYpO1xuXG4gICAgbGV0IHRyYW5zZm9ybSA9IFwiXCI7XG5cbiAgICBpZiAodGV4dERpdlByb3BlcnRpZXMuY2FudmFzV2lkdGggIT09IDAgJiYgdGV4dERpdlByb3BlcnRpZXMuaGFzVGV4dCkge1xuICAgICAgY29uc3Qge1xuICAgICAgICBmb250U2l6ZSxcbiAgICAgICAgZm9udEZhbWlseVxuICAgICAgfSA9IHRleHREaXYuc3R5bGU7XG5cbiAgICAgIGlmIChmb250U2l6ZSAhPT0gdGhpcy5fbGF5b3V0VGV4dExhc3RGb250U2l6ZSB8fCBmb250RmFtaWx5ICE9PSB0aGlzLl9sYXlvdXRUZXh0TGFzdEZvbnRGYW1pbHkpIHtcbiAgICAgICAgdGhpcy5fbGF5b3V0VGV4dEN0eC5mb250ID0gYCR7Zm9udFNpemV9ICR7Zm9udEZhbWlseX1gO1xuICAgICAgICB0aGlzLl9sYXlvdXRUZXh0TGFzdEZvbnRTaXplID0gZm9udFNpemU7XG4gICAgICAgIHRoaXMuX2xheW91dFRleHRMYXN0Rm9udEZhbWlseSA9IGZvbnRGYW1pbHk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHtcbiAgICAgICAgd2lkdGhcbiAgICAgIH0gPSB0aGlzLl9sYXlvdXRUZXh0Q3R4Lm1lYXN1cmVUZXh0KHRleHREaXYudGV4dENvbnRlbnQpO1xuXG4gICAgICBpZiAod2lkdGggPiAwKSB7XG4gICAgICAgIGNvbnN0IHNjYWxlID0gdGV4dERpdlByb3BlcnRpZXMuY2FudmFzV2lkdGggLyB3aWR0aDtcblxuICAgICAgICBpZiAodGhpcy5fZW5oYW5jZVRleHRTZWxlY3Rpb24pIHtcbiAgICAgICAgICB0ZXh0RGl2UHJvcGVydGllcy5zY2FsZSA9IHNjYWxlO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJhbnNmb3JtID0gYHNjYWxlWCgke3NjYWxlfSlgO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0ZXh0RGl2UHJvcGVydGllcy5hbmdsZSAhPT0gMCkge1xuICAgICAgdHJhbnNmb3JtID0gYHJvdGF0ZSgke3RleHREaXZQcm9wZXJ0aWVzLmFuZ2xlfWRlZykgJHt0cmFuc2Zvcm19YDtcbiAgICB9XG5cbiAgICBpZiAodHJhbnNmb3JtLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmICh0aGlzLl9lbmhhbmNlVGV4dFNlbGVjdGlvbikge1xuICAgICAgICB0ZXh0RGl2UHJvcGVydGllcy5vcmlnaW5hbFRyYW5zZm9ybSA9IHRyYW5zZm9ybTtcbiAgICAgIH1cblxuICAgICAgdGV4dERpdi5zdHlsZS50cmFuc2Zvcm0gPSB0cmFuc2Zvcm07XG4gICAgfVxuXG4gICAgaWYgKHRleHREaXZQcm9wZXJ0aWVzLmhhc1RleHQpIHtcbiAgICAgIHRoaXMuX2NvbnRhaW5lci5hcHBlbmRDaGlsZCh0ZXh0RGl2KTtcbiAgICB9XG5cbiAgICBpZiAodGV4dERpdlByb3BlcnRpZXMuaGFzRU9MKSB7XG4gICAgICBjb25zdCBiciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJiclwiKTtcbiAgICAgIGJyLnNldEF0dHJpYnV0ZShcInJvbGVcIiwgXCJwcmVzZW50YXRpb25cIik7XG5cbiAgICAgIHRoaXMuX2NvbnRhaW5lci5hcHBlbmRDaGlsZChicik7XG4gICAgfVxuICB9XG5cbiAgX3JlbmRlcih0aW1lb3V0ID0gMCkge1xuICAgIGNvbnN0IGNhcGFiaWxpdHkgPSAoMCwgX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkpKCk7XG4gICAgbGV0IHN0eWxlQ2FjaGUgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4gICAgY29uc3QgY2FudmFzID0gdGhpcy5fZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcblxuICAgIGNhbnZhcy5oZWlnaHQgPSBjYW52YXMud2lkdGggPSBERUZBVUxUX0ZPTlRfU0laRTtcbiAgICB0aGlzLl9sYXlvdXRUZXh0Q3R4ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiLCB7XG4gICAgICBhbHBoYTogZmFsc2VcbiAgICB9KTtcblxuICAgIGlmICh0aGlzLl90ZXh0Q29udGVudCkge1xuICAgICAgY29uc3QgdGV4dEl0ZW1zID0gdGhpcy5fdGV4dENvbnRlbnQuaXRlbXM7XG4gICAgICBjb25zdCB0ZXh0U3R5bGVzID0gdGhpcy5fdGV4dENvbnRlbnQuc3R5bGVzO1xuXG4gICAgICB0aGlzLl9wcm9jZXNzSXRlbXModGV4dEl0ZW1zLCB0ZXh0U3R5bGVzKTtcblxuICAgICAgY2FwYWJpbGl0eS5yZXNvbHZlKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLl90ZXh0Q29udGVudFN0cmVhbSkge1xuICAgICAgY29uc3QgcHVtcCA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5fcmVhZGVyLnJlYWQoKS50aGVuKCh7XG4gICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgZG9uZVxuICAgICAgICB9KSA9PiB7XG4gICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgIGNhcGFiaWxpdHkucmVzb2x2ZSgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIE9iamVjdC5hc3NpZ24oc3R5bGVDYWNoZSwgdmFsdWUuc3R5bGVzKTtcblxuICAgICAgICAgIHRoaXMuX3Byb2Nlc3NJdGVtcyh2YWx1ZS5pdGVtcywgc3R5bGVDYWNoZSk7XG5cbiAgICAgICAgICBwdW1wKCk7XG4gICAgICAgIH0sIGNhcGFiaWxpdHkucmVqZWN0KTtcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuX3JlYWRlciA9IHRoaXMuX3RleHRDb250ZW50U3RyZWFtLmdldFJlYWRlcigpO1xuICAgICAgcHVtcCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05laXRoZXIgXCJ0ZXh0Q29udGVudFwiIG5vciBcInRleHRDb250ZW50U3RyZWFtXCIgcGFyYW1ldGVycyBzcGVjaWZpZWQuJyk7XG4gICAgfVxuXG4gICAgY2FwYWJpbGl0eS5wcm9taXNlLnRoZW4oKCkgPT4ge1xuICAgICAgc3R5bGVDYWNoZSA9IG51bGw7XG5cbiAgICAgIGlmICghdGltZW91dCkge1xuICAgICAgICByZW5kZXIodGhpcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9yZW5kZXJUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHJlbmRlcih0aGlzKTtcbiAgICAgICAgICB0aGlzLl9yZW5kZXJUaW1lciA9IG51bGw7XG4gICAgICAgIH0sIHRpbWVvdXQpO1xuICAgICAgfVxuICAgIH0sIHRoaXMuX2NhcGFiaWxpdHkucmVqZWN0KTtcbiAgfVxuXG4gIGV4cGFuZFRleHREaXZzKGV4cGFuZERpdnMgPSBmYWxzZSkge1xuICAgIGlmICghdGhpcy5fZW5oYW5jZVRleHRTZWxlY3Rpb24gfHwgIXRoaXMuX3JlbmRlcmluZ0RvbmUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fYm91bmRzICE9PSBudWxsKSB7XG4gICAgICBleHBhbmQodGhpcyk7XG4gICAgICB0aGlzLl9ib3VuZHMgPSBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHRyYW5zZm9ybUJ1ZiA9IFtdLFxuICAgICAgICAgIHBhZGRpbmdCdWYgPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwLCBpaSA9IHRoaXMuX3RleHREaXZzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgIGNvbnN0IGRpdiA9IHRoaXMuX3RleHREaXZzW2ldO1xuXG4gICAgICBjb25zdCBkaXZQcm9wcyA9IHRoaXMuX3RleHREaXZQcm9wZXJ0aWVzLmdldChkaXYpO1xuXG4gICAgICBpZiAoIWRpdlByb3BzLmhhc1RleHQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChleHBhbmREaXZzKSB7XG4gICAgICAgIHRyYW5zZm9ybUJ1Zi5sZW5ndGggPSAwO1xuICAgICAgICBwYWRkaW5nQnVmLmxlbmd0aCA9IDA7XG5cbiAgICAgICAgaWYgKGRpdlByb3BzLm9yaWdpbmFsVHJhbnNmb3JtKSB7XG4gICAgICAgICAgdHJhbnNmb3JtQnVmLnB1c2goZGl2UHJvcHMub3JpZ2luYWxUcmFuc2Zvcm0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRpdlByb3BzLnBhZGRpbmdUb3AgPiAwKSB7XG4gICAgICAgICAgcGFkZGluZ0J1Zi5wdXNoKGAke2RpdlByb3BzLnBhZGRpbmdUb3B9cHhgKTtcbiAgICAgICAgICB0cmFuc2Zvcm1CdWYucHVzaChgdHJhbnNsYXRlWSgkey1kaXZQcm9wcy5wYWRkaW5nVG9wfXB4KWApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBhZGRpbmdCdWYucHVzaCgwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkaXZQcm9wcy5wYWRkaW5nUmlnaHQgPiAwKSB7XG4gICAgICAgICAgcGFkZGluZ0J1Zi5wdXNoKGAke2RpdlByb3BzLnBhZGRpbmdSaWdodCAvIGRpdlByb3BzLnNjYWxlfXB4YCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcGFkZGluZ0J1Zi5wdXNoKDApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRpdlByb3BzLnBhZGRpbmdCb3R0b20gPiAwKSB7XG4gICAgICAgICAgcGFkZGluZ0J1Zi5wdXNoKGAke2RpdlByb3BzLnBhZGRpbmdCb3R0b219cHhgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwYWRkaW5nQnVmLnB1c2goMCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZGl2UHJvcHMucGFkZGluZ0xlZnQgPiAwKSB7XG4gICAgICAgICAgcGFkZGluZ0J1Zi5wdXNoKGAke2RpdlByb3BzLnBhZGRpbmdMZWZ0IC8gZGl2UHJvcHMuc2NhbGV9cHhgKTtcbiAgICAgICAgICB0cmFuc2Zvcm1CdWYucHVzaChgdHJhbnNsYXRlWCgkey1kaXZQcm9wcy5wYWRkaW5nTGVmdCAvIGRpdlByb3BzLnNjYWxlfXB4KWApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBhZGRpbmdCdWYucHVzaCgwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRpdi5zdHlsZS5wYWRkaW5nID0gcGFkZGluZ0J1Zi5qb2luKFwiIFwiKTtcblxuICAgICAgICBpZiAodHJhbnNmb3JtQnVmLmxlbmd0aCkge1xuICAgICAgICAgIGRpdi5zdHlsZS50cmFuc2Zvcm0gPSB0cmFuc2Zvcm1CdWYuam9pbihcIiBcIik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRpdi5zdHlsZS5wYWRkaW5nID0gbnVsbDtcbiAgICAgICAgZGl2LnN0eWxlLnRyYW5zZm9ybSA9IGRpdlByb3BzLm9yaWdpbmFsVHJhbnNmb3JtO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG59XG5cbmZ1bmN0aW9uIHJlbmRlclRleHRMYXllcihyZW5kZXJQYXJhbWV0ZXJzKSB7XG4gIGNvbnN0IHRhc2sgPSBuZXcgVGV4dExheWVyUmVuZGVyVGFzayh7XG4gICAgdGV4dENvbnRlbnQ6IHJlbmRlclBhcmFtZXRlcnMudGV4dENvbnRlbnQsXG4gICAgdGV4dENvbnRlbnRTdHJlYW06IHJlbmRlclBhcmFtZXRlcnMudGV4dENvbnRlbnRTdHJlYW0sXG4gICAgY29udGFpbmVyOiByZW5kZXJQYXJhbWV0ZXJzLmNvbnRhaW5lcixcbiAgICB2aWV3cG9ydDogcmVuZGVyUGFyYW1ldGVycy52aWV3cG9ydCxcbiAgICB0ZXh0RGl2czogcmVuZGVyUGFyYW1ldGVycy50ZXh0RGl2cyxcbiAgICB0ZXh0Q29udGVudEl0ZW1zU3RyOiByZW5kZXJQYXJhbWV0ZXJzLnRleHRDb250ZW50SXRlbXNTdHIsXG4gICAgZW5oYW5jZVRleHRTZWxlY3Rpb246IHJlbmRlclBhcmFtZXRlcnMuZW5oYW5jZVRleHRTZWxlY3Rpb25cbiAgfSk7XG5cbiAgdGFzay5fcmVuZGVyKHJlbmRlclBhcmFtZXRlcnMudGltZW91dCk7XG5cbiAgcmV0dXJuIHRhc2s7XG59XG5cbi8qKiovIH0pLFxuLyogMjQgKi9cbi8qKiovICgoX191bnVzZWRfd2VicGFja19tb2R1bGUsIGV4cG9ydHMsIF9fd19wZGZqc19yZXF1aXJlX18pID0+IHtcblxuXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgKHtcbiAgdmFsdWU6IHRydWVcbn0pKTtcbmV4cG9ydHMuU1ZHR3JhcGhpY3MgPSB2b2lkIDA7XG5cbnZhciBfdXRpbCA9IF9fd19wZGZqc19yZXF1aXJlX18oMSk7XG5cbnZhciBfZGlzcGxheV91dGlscyA9IF9fd19wZGZqc19yZXF1aXJlX18oNSk7XG5cbnZhciBfaXNfbm9kZSA9IF9fd19wZGZqc19yZXF1aXJlX18oMyk7XG5cbmxldCBTVkdHcmFwaGljcyA9IGNsYXNzIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgKDAsIF91dGlsLnVucmVhY2hhYmxlKShcIk5vdCBpbXBsZW1lbnRlZDogU1ZHR3JhcGhpY3NcIik7XG4gIH1cblxufTtcbmV4cG9ydHMuU1ZHR3JhcGhpY3MgPSBTVkdHcmFwaGljcztcbntcbiAgY29uc3QgU1ZHX0RFRkFVTFRTID0ge1xuICAgIGZvbnRTdHlsZTogXCJub3JtYWxcIixcbiAgICBmb250V2VpZ2h0OiBcIm5vcm1hbFwiLFxuICAgIGZpbGxDb2xvcjogXCIjMDAwMDAwXCJcbiAgfTtcbiAgY29uc3QgWE1MX05TID0gXCJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2VcIjtcbiAgY29uc3QgWExJTktfTlMgPSBcImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIjtcbiAgY29uc3QgTElORV9DQVBfU1RZTEVTID0gW1wiYnV0dFwiLCBcInJvdW5kXCIsIFwic3F1YXJlXCJdO1xuICBjb25zdCBMSU5FX0pPSU5fU1RZTEVTID0gW1wibWl0ZXJcIiwgXCJyb3VuZFwiLCBcImJldmVsXCJdO1xuXG4gIGNvbnN0IGNyZWF0ZU9iamVjdFVSTCA9IGZ1bmN0aW9uIChkYXRhLCBjb250ZW50VHlwZSA9IFwiXCIsIGZvcmNlRGF0YVNjaGVtYSA9IGZhbHNlKSB7XG4gICAgaWYgKFVSTC5jcmVhdGVPYmplY3RVUkwgJiYgdHlwZW9mIEJsb2IgIT09IFwidW5kZWZpbmVkXCIgJiYgIWZvcmNlRGF0YVNjaGVtYSkge1xuICAgICAgcmV0dXJuIFVSTC5jcmVhdGVPYmplY3RVUkwobmV3IEJsb2IoW2RhdGFdLCB7XG4gICAgICAgIHR5cGU6IGNvbnRlbnRUeXBlXG4gICAgICB9KSk7XG4gICAgfVxuXG4gICAgY29uc3QgZGlnaXRzID0gXCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPVwiO1xuICAgIGxldCBidWZmZXIgPSBgZGF0YToke2NvbnRlbnRUeXBlfTtiYXNlNjQsYDtcblxuICAgIGZvciAobGV0IGkgPSAwLCBpaSA9IGRhdGEubGVuZ3RoOyBpIDwgaWk7IGkgKz0gMykge1xuICAgICAgY29uc3QgYjEgPSBkYXRhW2ldICYgMHhmZjtcbiAgICAgIGNvbnN0IGIyID0gZGF0YVtpICsgMV0gJiAweGZmO1xuICAgICAgY29uc3QgYjMgPSBkYXRhW2kgKyAyXSAmIDB4ZmY7XG4gICAgICBjb25zdCBkMSA9IGIxID4+IDIsXG4gICAgICAgICAgICBkMiA9IChiMSAmIDMpIDw8IDQgfCBiMiA+PiA0O1xuICAgICAgY29uc3QgZDMgPSBpICsgMSA8IGlpID8gKGIyICYgMHhmKSA8PCAyIHwgYjMgPj4gNiA6IDY0O1xuICAgICAgY29uc3QgZDQgPSBpICsgMiA8IGlpID8gYjMgJiAweDNmIDogNjQ7XG4gICAgICBidWZmZXIgKz0gZGlnaXRzW2QxXSArIGRpZ2l0c1tkMl0gKyBkaWdpdHNbZDNdICsgZGlnaXRzW2Q0XTtcbiAgICB9XG5cbiAgICByZXR1cm4gYnVmZmVyO1xuICB9O1xuXG4gIGNvbnN0IGNvbnZlcnRJbWdEYXRhVG9QbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgUE5HX0hFQURFUiA9IG5ldyBVaW50OEFycmF5KFsweDg5LCAweDUwLCAweDRlLCAweDQ3LCAweDBkLCAweDBhLCAweDFhLCAweDBhXSk7XG4gICAgY29uc3QgQ0hVTktfV1JBUFBFUl9TSVpFID0gMTI7XG4gICAgY29uc3QgY3JjVGFibGUgPSBuZXcgSW50MzJBcnJheSgyNTYpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICAgICAgbGV0IGMgPSBpO1xuXG4gICAgICBmb3IgKGxldCBoID0gMDsgaCA8IDg7IGgrKykge1xuICAgICAgICBpZiAoYyAmIDEpIHtcbiAgICAgICAgICBjID0gMHhlZGI4ODMyMCBeIGMgPj4gMSAmIDB4N2ZmZmZmZmY7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYyA9IGMgPj4gMSAmIDB4N2ZmZmZmZmY7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY3JjVGFibGVbaV0gPSBjO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNyYzMyKGRhdGEsIHN0YXJ0LCBlbmQpIHtcbiAgICAgIGxldCBjcmMgPSAtMTtcblxuICAgICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICAgICAgY29uc3QgYSA9IChjcmMgXiBkYXRhW2ldKSAmIDB4ZmY7XG4gICAgICAgIGNvbnN0IGIgPSBjcmNUYWJsZVthXTtcbiAgICAgICAgY3JjID0gY3JjID4+PiA4IF4gYjtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNyYyBeIC0xO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHdyaXRlUG5nQ2h1bmsodHlwZSwgYm9keSwgZGF0YSwgb2Zmc2V0KSB7XG4gICAgICBsZXQgcCA9IG9mZnNldDtcbiAgICAgIGNvbnN0IGxlbiA9IGJvZHkubGVuZ3RoO1xuICAgICAgZGF0YVtwXSA9IGxlbiA+PiAyNCAmIDB4ZmY7XG4gICAgICBkYXRhW3AgKyAxXSA9IGxlbiA+PiAxNiAmIDB4ZmY7XG4gICAgICBkYXRhW3AgKyAyXSA9IGxlbiA+PiA4ICYgMHhmZjtcbiAgICAgIGRhdGFbcCArIDNdID0gbGVuICYgMHhmZjtcbiAgICAgIHAgKz0gNDtcbiAgICAgIGRhdGFbcF0gPSB0eXBlLmNoYXJDb2RlQXQoMCkgJiAweGZmO1xuICAgICAgZGF0YVtwICsgMV0gPSB0eXBlLmNoYXJDb2RlQXQoMSkgJiAweGZmO1xuICAgICAgZGF0YVtwICsgMl0gPSB0eXBlLmNoYXJDb2RlQXQoMikgJiAweGZmO1xuICAgICAgZGF0YVtwICsgM10gPSB0eXBlLmNoYXJDb2RlQXQoMykgJiAweGZmO1xuICAgICAgcCArPSA0O1xuICAgICAgZGF0YS5zZXQoYm9keSwgcCk7XG4gICAgICBwICs9IGJvZHkubGVuZ3RoO1xuICAgICAgY29uc3QgY3JjID0gY3JjMzIoZGF0YSwgb2Zmc2V0ICsgNCwgcCk7XG4gICAgICBkYXRhW3BdID0gY3JjID4+IDI0ICYgMHhmZjtcbiAgICAgIGRhdGFbcCArIDFdID0gY3JjID4+IDE2ICYgMHhmZjtcbiAgICAgIGRhdGFbcCArIDJdID0gY3JjID4+IDggJiAweGZmO1xuICAgICAgZGF0YVtwICsgM10gPSBjcmMgJiAweGZmO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkbGVyMzIoZGF0YSwgc3RhcnQsIGVuZCkge1xuICAgICAgbGV0IGEgPSAxO1xuICAgICAgbGV0IGIgPSAwO1xuXG4gICAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgICAgICBhID0gKGEgKyAoZGF0YVtpXSAmIDB4ZmYpKSAlIDY1NTIxO1xuICAgICAgICBiID0gKGIgKyBhKSAlIDY1NTIxO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYiA8PCAxNiB8IGE7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGVmbGF0ZVN5bmMobGl0ZXJhbHMpIHtcbiAgICAgIGlmICghX2lzX25vZGUuaXNOb2RlSlMpIHtcbiAgICAgICAgcmV0dXJuIGRlZmxhdGVTeW5jVW5jb21wcmVzc2VkKGxpdGVyYWxzKTtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgbGV0IGlucHV0O1xuXG4gICAgICAgIGlmIChwYXJzZUludChwcm9jZXNzLnZlcnNpb25zLm5vZGUpID49IDgpIHtcbiAgICAgICAgICBpbnB1dCA9IGxpdGVyYWxzO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlucHV0ID0gQnVmZmVyLmZyb20obGl0ZXJhbHMpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgb3V0cHV0ID0gcmVxdWlyZShcInpsaWJcIikuZGVmbGF0ZVN5bmMoaW5wdXQsIHtcbiAgICAgICAgICBsZXZlbDogOVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gb3V0cHV0IGluc3RhbmNlb2YgVWludDhBcnJheSA/IG91dHB1dCA6IG5ldyBVaW50OEFycmF5KG91dHB1dCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICgwLCBfdXRpbC53YXJuKShcIk5vdCBjb21wcmVzc2luZyBQTkcgYmVjYXVzZSB6bGliLmRlZmxhdGVTeW5jIGlzIHVuYXZhaWxhYmxlOiBcIiArIGUpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZGVmbGF0ZVN5bmNVbmNvbXByZXNzZWQobGl0ZXJhbHMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRlZmxhdGVTeW5jVW5jb21wcmVzc2VkKGxpdGVyYWxzKSB7XG4gICAgICBsZXQgbGVuID0gbGl0ZXJhbHMubGVuZ3RoO1xuICAgICAgY29uc3QgbWF4QmxvY2tMZW5ndGggPSAweGZmZmY7XG4gICAgICBjb25zdCBkZWZsYXRlQmxvY2tzID0gTWF0aC5jZWlsKGxlbiAvIG1heEJsb2NrTGVuZ3RoKTtcbiAgICAgIGNvbnN0IGlkYXQgPSBuZXcgVWludDhBcnJheSgyICsgbGVuICsgZGVmbGF0ZUJsb2NrcyAqIDUgKyA0KTtcbiAgICAgIGxldCBwaSA9IDA7XG4gICAgICBpZGF0W3BpKytdID0gMHg3ODtcbiAgICAgIGlkYXRbcGkrK10gPSAweDljO1xuICAgICAgbGV0IHBvcyA9IDA7XG5cbiAgICAgIHdoaWxlIChsZW4gPiBtYXhCbG9ja0xlbmd0aCkge1xuICAgICAgICBpZGF0W3BpKytdID0gMHgwMDtcbiAgICAgICAgaWRhdFtwaSsrXSA9IDB4ZmY7XG4gICAgICAgIGlkYXRbcGkrK10gPSAweGZmO1xuICAgICAgICBpZGF0W3BpKytdID0gMHgwMDtcbiAgICAgICAgaWRhdFtwaSsrXSA9IDB4MDA7XG4gICAgICAgIGlkYXQuc2V0KGxpdGVyYWxzLnN1YmFycmF5KHBvcywgcG9zICsgbWF4QmxvY2tMZW5ndGgpLCBwaSk7XG4gICAgICAgIHBpICs9IG1heEJsb2NrTGVuZ3RoO1xuICAgICAgICBwb3MgKz0gbWF4QmxvY2tMZW5ndGg7XG4gICAgICAgIGxlbiAtPSBtYXhCbG9ja0xlbmd0aDtcbiAgICAgIH1cblxuICAgICAgaWRhdFtwaSsrXSA9IDB4MDE7XG4gICAgICBpZGF0W3BpKytdID0gbGVuICYgMHhmZjtcbiAgICAgIGlkYXRbcGkrK10gPSBsZW4gPj4gOCAmIDB4ZmY7XG4gICAgICBpZGF0W3BpKytdID0gfmxlbiAmIDB4ZmZmZiAmIDB4ZmY7XG4gICAgICBpZGF0W3BpKytdID0gKH5sZW4gJiAweGZmZmYpID4+IDggJiAweGZmO1xuICAgICAgaWRhdC5zZXQobGl0ZXJhbHMuc3ViYXJyYXkocG9zKSwgcGkpO1xuICAgICAgcGkgKz0gbGl0ZXJhbHMubGVuZ3RoIC0gcG9zO1xuICAgICAgY29uc3QgYWRsZXIgPSBhZGxlcjMyKGxpdGVyYWxzLCAwLCBsaXRlcmFscy5sZW5ndGgpO1xuICAgICAgaWRhdFtwaSsrXSA9IGFkbGVyID4+IDI0ICYgMHhmZjtcbiAgICAgIGlkYXRbcGkrK10gPSBhZGxlciA+PiAxNiAmIDB4ZmY7XG4gICAgICBpZGF0W3BpKytdID0gYWRsZXIgPj4gOCAmIDB4ZmY7XG4gICAgICBpZGF0W3BpKytdID0gYWRsZXIgJiAweGZmO1xuICAgICAgcmV0dXJuIGlkYXQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZW5jb2RlKGltZ0RhdGEsIGtpbmQsIGZvcmNlRGF0YVNjaGVtYSwgaXNNYXNrKSB7XG4gICAgICBjb25zdCB3aWR0aCA9IGltZ0RhdGEud2lkdGg7XG4gICAgICBjb25zdCBoZWlnaHQgPSBpbWdEYXRhLmhlaWdodDtcbiAgICAgIGxldCBiaXREZXB0aCwgY29sb3JUeXBlLCBsaW5lU2l6ZTtcbiAgICAgIGNvbnN0IGJ5dGVzID0gaW1nRGF0YS5kYXRhO1xuXG4gICAgICBzd2l0Y2ggKGtpbmQpIHtcbiAgICAgICAgY2FzZSBfdXRpbC5JbWFnZUtpbmQuR1JBWVNDQUxFXzFCUFA6XG4gICAgICAgICAgY29sb3JUeXBlID0gMDtcbiAgICAgICAgICBiaXREZXB0aCA9IDE7XG4gICAgICAgICAgbGluZVNpemUgPSB3aWR0aCArIDcgPj4gMztcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIF91dGlsLkltYWdlS2luZC5SR0JfMjRCUFA6XG4gICAgICAgICAgY29sb3JUeXBlID0gMjtcbiAgICAgICAgICBiaXREZXB0aCA9IDg7XG4gICAgICAgICAgbGluZVNpemUgPSB3aWR0aCAqIDM7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBfdXRpbC5JbWFnZUtpbmQuUkdCQV8zMkJQUDpcbiAgICAgICAgICBjb2xvclR5cGUgPSA2O1xuICAgICAgICAgIGJpdERlcHRoID0gODtcbiAgICAgICAgICBsaW5lU2l6ZSA9IHdpZHRoICogNDtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgZm9ybWF0XCIpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBsaXRlcmFscyA9IG5ldyBVaW50OEFycmF5KCgxICsgbGluZVNpemUpICogaGVpZ2h0KTtcbiAgICAgIGxldCBvZmZzZXRMaXRlcmFscyA9IDAsXG4gICAgICAgICAgb2Zmc2V0Qnl0ZXMgPSAwO1xuXG4gICAgICBmb3IgKGxldCB5ID0gMDsgeSA8IGhlaWdodDsgKyt5KSB7XG4gICAgICAgIGxpdGVyYWxzW29mZnNldExpdGVyYWxzKytdID0gMDtcbiAgICAgICAgbGl0ZXJhbHMuc2V0KGJ5dGVzLnN1YmFycmF5KG9mZnNldEJ5dGVzLCBvZmZzZXRCeXRlcyArIGxpbmVTaXplKSwgb2Zmc2V0TGl0ZXJhbHMpO1xuICAgICAgICBvZmZzZXRCeXRlcyArPSBsaW5lU2l6ZTtcbiAgICAgICAgb2Zmc2V0TGl0ZXJhbHMgKz0gbGluZVNpemU7XG4gICAgICB9XG5cbiAgICAgIGlmIChraW5kID09PSBfdXRpbC5JbWFnZUtpbmQuR1JBWVNDQUxFXzFCUFAgJiYgaXNNYXNrKSB7XG4gICAgICAgIG9mZnNldExpdGVyYWxzID0gMDtcblxuICAgICAgICBmb3IgKGxldCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7XG4gICAgICAgICAgb2Zmc2V0TGl0ZXJhbHMrKztcblxuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZVNpemU7IGkrKykge1xuICAgICAgICAgICAgbGl0ZXJhbHNbb2Zmc2V0TGl0ZXJhbHMrK10gXj0gMHhmZjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgaWhkciA9IG5ldyBVaW50OEFycmF5KFt3aWR0aCA+PiAyNCAmIDB4ZmYsIHdpZHRoID4+IDE2ICYgMHhmZiwgd2lkdGggPj4gOCAmIDB4ZmYsIHdpZHRoICYgMHhmZiwgaGVpZ2h0ID4+IDI0ICYgMHhmZiwgaGVpZ2h0ID4+IDE2ICYgMHhmZiwgaGVpZ2h0ID4+IDggJiAweGZmLCBoZWlnaHQgJiAweGZmLCBiaXREZXB0aCwgY29sb3JUeXBlLCAweDAwLCAweDAwLCAweDAwXSk7XG4gICAgICBjb25zdCBpZGF0ID0gZGVmbGF0ZVN5bmMobGl0ZXJhbHMpO1xuICAgICAgY29uc3QgcG5nTGVuZ3RoID0gUE5HX0hFQURFUi5sZW5ndGggKyBDSFVOS19XUkFQUEVSX1NJWkUgKiAzICsgaWhkci5sZW5ndGggKyBpZGF0Lmxlbmd0aDtcbiAgICAgIGNvbnN0IGRhdGEgPSBuZXcgVWludDhBcnJheShwbmdMZW5ndGgpO1xuICAgICAgbGV0IG9mZnNldCA9IDA7XG4gICAgICBkYXRhLnNldChQTkdfSEVBREVSLCBvZmZzZXQpO1xuICAgICAgb2Zmc2V0ICs9IFBOR19IRUFERVIubGVuZ3RoO1xuICAgICAgd3JpdGVQbmdDaHVuayhcIklIRFJcIiwgaWhkciwgZGF0YSwgb2Zmc2V0KTtcbiAgICAgIG9mZnNldCArPSBDSFVOS19XUkFQUEVSX1NJWkUgKyBpaGRyLmxlbmd0aDtcbiAgICAgIHdyaXRlUG5nQ2h1bmsoXCJJREFUQVwiLCBpZGF0LCBkYXRhLCBvZmZzZXQpO1xuICAgICAgb2Zmc2V0ICs9IENIVU5LX1dSQVBQRVJfU0laRSArIGlkYXQubGVuZ3RoO1xuICAgICAgd3JpdGVQbmdDaHVuayhcIklFTkRcIiwgbmV3IFVpbnQ4QXJyYXkoMCksIGRhdGEsIG9mZnNldCk7XG4gICAgICByZXR1cm4gY3JlYXRlT2JqZWN0VVJMKGRhdGEsIFwiaW1hZ2UvcG5nXCIsIGZvcmNlRGF0YVNjaGVtYSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIGNvbnZlcnRJbWdEYXRhVG9QbmcoaW1nRGF0YSwgZm9yY2VEYXRhU2NoZW1hLCBpc01hc2spIHtcbiAgICAgIGNvbnN0IGtpbmQgPSBpbWdEYXRhLmtpbmQgPT09IHVuZGVmaW5lZCA/IF91dGlsLkltYWdlS2luZC5HUkFZU0NBTEVfMUJQUCA6IGltZ0RhdGEua2luZDtcbiAgICAgIHJldHVybiBlbmNvZGUoaW1nRGF0YSwga2luZCwgZm9yY2VEYXRhU2NoZW1hLCBpc01hc2spO1xuICAgIH07XG4gIH0oKTtcblxuICBjbGFzcyBTVkdFeHRyYVN0YXRlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgIHRoaXMuZm9udFNpemVTY2FsZSA9IDE7XG4gICAgICB0aGlzLmZvbnRXZWlnaHQgPSBTVkdfREVGQVVMVFMuZm9udFdlaWdodDtcbiAgICAgIHRoaXMuZm9udFNpemUgPSAwO1xuICAgICAgdGhpcy50ZXh0TWF0cml4ID0gX3V0aWwuSURFTlRJVFlfTUFUUklYO1xuICAgICAgdGhpcy5mb250TWF0cml4ID0gX3V0aWwuRk9OVF9JREVOVElUWV9NQVRSSVg7XG4gICAgICB0aGlzLmxlYWRpbmcgPSAwO1xuICAgICAgdGhpcy50ZXh0UmVuZGVyaW5nTW9kZSA9IF91dGlsLlRleHRSZW5kZXJpbmdNb2RlLkZJTEw7XG4gICAgICB0aGlzLnRleHRNYXRyaXhTY2FsZSA9IDE7XG4gICAgICB0aGlzLnggPSAwO1xuICAgICAgdGhpcy55ID0gMDtcbiAgICAgIHRoaXMubGluZVggPSAwO1xuICAgICAgdGhpcy5saW5lWSA9IDA7XG4gICAgICB0aGlzLmNoYXJTcGFjaW5nID0gMDtcbiAgICAgIHRoaXMud29yZFNwYWNpbmcgPSAwO1xuICAgICAgdGhpcy50ZXh0SFNjYWxlID0gMTtcbiAgICAgIHRoaXMudGV4dFJpc2UgPSAwO1xuICAgICAgdGhpcy5maWxsQ29sb3IgPSBTVkdfREVGQVVMVFMuZmlsbENvbG9yO1xuICAgICAgdGhpcy5zdHJva2VDb2xvciA9IFwiIzAwMDAwMFwiO1xuICAgICAgdGhpcy5maWxsQWxwaGEgPSAxO1xuICAgICAgdGhpcy5zdHJva2VBbHBoYSA9IDE7XG4gICAgICB0aGlzLmxpbmVXaWR0aCA9IDE7XG4gICAgICB0aGlzLmxpbmVKb2luID0gXCJcIjtcbiAgICAgIHRoaXMubGluZUNhcCA9IFwiXCI7XG4gICAgICB0aGlzLm1pdGVyTGltaXQgPSAwO1xuICAgICAgdGhpcy5kYXNoQXJyYXkgPSBbXTtcbiAgICAgIHRoaXMuZGFzaFBoYXNlID0gMDtcbiAgICAgIHRoaXMuZGVwZW5kZW5jaWVzID0gW107XG4gICAgICB0aGlzLmFjdGl2ZUNsaXBVcmwgPSBudWxsO1xuICAgICAgdGhpcy5jbGlwR3JvdXAgPSBudWxsO1xuICAgICAgdGhpcy5tYXNrSWQgPSBcIlwiO1xuICAgIH1cblxuICAgIGNsb25lKCkge1xuICAgICAgcmV0dXJuIE9iamVjdC5jcmVhdGUodGhpcyk7XG4gICAgfVxuXG4gICAgc2V0Q3VycmVudFBvaW50KHgsIHkpIHtcbiAgICAgIHRoaXMueCA9IHg7XG4gICAgICB0aGlzLnkgPSB5O1xuICAgIH1cblxuICB9XG5cbiAgZnVuY3Rpb24gb3BMaXN0VG9UcmVlKG9wTGlzdCkge1xuICAgIGxldCBvcFRyZWUgPSBbXTtcbiAgICBjb25zdCB0bXAgPSBbXTtcblxuICAgIGZvciAoY29uc3Qgb3BMaXN0RWxlbWVudCBvZiBvcExpc3QpIHtcbiAgICAgIGlmIChvcExpc3RFbGVtZW50LmZuID09PSBcInNhdmVcIikge1xuICAgICAgICBvcFRyZWUucHVzaCh7XG4gICAgICAgICAgZm5JZDogOTIsXG4gICAgICAgICAgZm46IFwiZ3JvdXBcIixcbiAgICAgICAgICBpdGVtczogW11cbiAgICAgICAgfSk7XG4gICAgICAgIHRtcC5wdXNoKG9wVHJlZSk7XG4gICAgICAgIG9wVHJlZSA9IG9wVHJlZVtvcFRyZWUubGVuZ3RoIC0gMV0uaXRlbXM7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAob3BMaXN0RWxlbWVudC5mbiA9PT0gXCJyZXN0b3JlXCIpIHtcbiAgICAgICAgb3BUcmVlID0gdG1wLnBvcCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3BUcmVlLnB1c2gob3BMaXN0RWxlbWVudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG9wVHJlZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBmKHZhbHVlKSB7XG4gICAgaWYgKE51bWJlci5pc0ludGVnZXIodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWUudG9TdHJpbmcoKTtcbiAgICB9XG5cbiAgICBjb25zdCBzID0gdmFsdWUudG9GaXhlZCgxMCk7XG4gICAgbGV0IGkgPSBzLmxlbmd0aCAtIDE7XG5cbiAgICBpZiAoc1tpXSAhPT0gXCIwXCIpIHtcbiAgICAgIHJldHVybiBzO1xuICAgIH1cblxuICAgIGRvIHtcbiAgICAgIGktLTtcbiAgICB9IHdoaWxlIChzW2ldID09PSBcIjBcIik7XG5cbiAgICByZXR1cm4gcy5zdWJzdHJpbmcoMCwgc1tpXSA9PT0gXCIuXCIgPyBpIDogaSArIDEpO1xuICB9XG5cbiAgZnVuY3Rpb24gcG0obSkge1xuICAgIGlmIChtWzRdID09PSAwICYmIG1bNV0gPT09IDApIHtcbiAgICAgIGlmIChtWzFdID09PSAwICYmIG1bMl0gPT09IDApIHtcbiAgICAgICAgaWYgKG1bMF0gPT09IDEgJiYgbVszXSA9PT0gMSkge1xuICAgICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGBzY2FsZSgke3BmKG1bMF0pfSAke3BmKG1bM10pfSlgO1xuICAgICAgfVxuXG4gICAgICBpZiAobVswXSA9PT0gbVszXSAmJiBtWzFdID09PSAtbVsyXSkge1xuICAgICAgICBjb25zdCBhID0gTWF0aC5hY29zKG1bMF0pICogMTgwIC8gTWF0aC5QSTtcbiAgICAgICAgcmV0dXJuIGByb3RhdGUoJHtwZihhKX0pYDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKG1bMF0gPT09IDEgJiYgbVsxXSA9PT0gMCAmJiBtWzJdID09PSAwICYmIG1bM10gPT09IDEpIHtcbiAgICAgICAgcmV0dXJuIGB0cmFuc2xhdGUoJHtwZihtWzRdKX0gJHtwZihtWzVdKX0pYDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gYG1hdHJpeCgke3BmKG1bMF0pfSAke3BmKG1bMV0pfSAke3BmKG1bMl0pfSAke3BmKG1bM10pfSAke3BmKG1bNF0pfSBgICsgYCR7cGYobVs1XSl9KWA7XG4gIH1cblxuICBsZXQgY2xpcENvdW50ID0gMDtcbiAgbGV0IG1hc2tDb3VudCA9IDA7XG4gIGxldCBzaGFkaW5nQ291bnQgPSAwO1xuICBleHBvcnRzLlNWR0dyYXBoaWNzID0gU1ZHR3JhcGhpY3MgPSBjbGFzcyB7XG4gICAgY29uc3RydWN0b3IoY29tbW9uT2Jqcywgb2JqcywgZm9yY2VEYXRhU2NoZW1hID0gZmFsc2UpIHtcbiAgICAgIHRoaXMuc3ZnRmFjdG9yeSA9IG5ldyBfZGlzcGxheV91dGlscy5ET01TVkdGYWN0b3J5KCk7XG4gICAgICB0aGlzLmN1cnJlbnQgPSBuZXcgU1ZHRXh0cmFTdGF0ZSgpO1xuICAgICAgdGhpcy50cmFuc2Zvcm1NYXRyaXggPSBfdXRpbC5JREVOVElUWV9NQVRSSVg7XG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrID0gW107XG4gICAgICB0aGlzLmV4dHJhU3RhY2sgPSBbXTtcbiAgICAgIHRoaXMuY29tbW9uT2JqcyA9IGNvbW1vbk9ianM7XG4gICAgICB0aGlzLm9ianMgPSBvYmpzO1xuICAgICAgdGhpcy5wZW5kaW5nQ2xpcCA9IG51bGw7XG4gICAgICB0aGlzLnBlbmRpbmdFT0ZpbGwgPSBmYWxzZTtcbiAgICAgIHRoaXMuZW1iZWRGb250cyA9IGZhbHNlO1xuICAgICAgdGhpcy5lbWJlZGRlZEZvbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgIHRoaXMuY3NzU3R5bGUgPSBudWxsO1xuICAgICAgdGhpcy5mb3JjZURhdGFTY2hlbWEgPSAhIWZvcmNlRGF0YVNjaGVtYTtcbiAgICAgIHRoaXMuX29wZXJhdG9ySWRNYXBwaW5nID0gW107XG5cbiAgICAgIGZvciAoY29uc3Qgb3AgaW4gX3V0aWwuT1BTKSB7XG4gICAgICAgIHRoaXMuX29wZXJhdG9ySWRNYXBwaW5nW191dGlsLk9QU1tvcF1dID0gb3A7XG4gICAgICB9XG4gICAgfVxuXG4gICAgc2F2ZSgpIHtcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2sucHVzaCh0aGlzLnRyYW5zZm9ybU1hdHJpeCk7XG4gICAgICBjb25zdCBvbGQgPSB0aGlzLmN1cnJlbnQ7XG4gICAgICB0aGlzLmV4dHJhU3RhY2sucHVzaChvbGQpO1xuICAgICAgdGhpcy5jdXJyZW50ID0gb2xkLmNsb25lKCk7XG4gICAgfVxuXG4gICAgcmVzdG9yZSgpIHtcbiAgICAgIHRoaXMudHJhbnNmb3JtTWF0cml4ID0gdGhpcy50cmFuc2Zvcm1TdGFjay5wb3AoKTtcbiAgICAgIHRoaXMuY3VycmVudCA9IHRoaXMuZXh0cmFTdGFjay5wb3AoKTtcbiAgICAgIHRoaXMucGVuZGluZ0NsaXAgPSBudWxsO1xuICAgICAgdGhpcy50Z3JwID0gbnVsbDtcbiAgICB9XG5cbiAgICBncm91cChpdGVtcykge1xuICAgICAgdGhpcy5zYXZlKCk7XG4gICAgICB0aGlzLmV4ZWN1dGVPcFRyZWUoaXRlbXMpO1xuICAgICAgdGhpcy5yZXN0b3JlKCk7XG4gICAgfVxuXG4gICAgbG9hZERlcGVuZGVuY2llcyhvcGVyYXRvckxpc3QpIHtcbiAgICAgIGNvbnN0IGZuQXJyYXkgPSBvcGVyYXRvckxpc3QuZm5BcnJheTtcbiAgICAgIGNvbnN0IGFyZ3NBcnJheSA9IG9wZXJhdG9yTGlzdC5hcmdzQXJyYXk7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwLCBpaSA9IGZuQXJyYXkubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICBpZiAoZm5BcnJheVtpXSAhPT0gX3V0aWwuT1BTLmRlcGVuZGVuY3kpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3Qgb2JqIG9mIGFyZ3NBcnJheVtpXSkge1xuICAgICAgICAgIGNvbnN0IG9ianNQb29sID0gb2JqLnN0YXJ0c1dpdGgoXCJnX1wiKSA/IHRoaXMuY29tbW9uT2JqcyA6IHRoaXMub2JqcztcbiAgICAgICAgICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgICBvYmpzUG9vbC5nZXQob2JqLCByZXNvbHZlKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB0aGlzLmN1cnJlbnQuZGVwZW5kZW5jaWVzLnB1c2gocHJvbWlzZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHRoaXMuY3VycmVudC5kZXBlbmRlbmNpZXMpO1xuICAgIH1cblxuICAgIHRyYW5zZm9ybShhLCBiLCBjLCBkLCBlLCBmKSB7XG4gICAgICBjb25zdCB0cmFuc2Zvcm1NYXRyaXggPSBbYSwgYiwgYywgZCwgZSwgZl07XG4gICAgICB0aGlzLnRyYW5zZm9ybU1hdHJpeCA9IF91dGlsLlV0aWwudHJhbnNmb3JtKHRoaXMudHJhbnNmb3JtTWF0cml4LCB0cmFuc2Zvcm1NYXRyaXgpO1xuICAgICAgdGhpcy50Z3JwID0gbnVsbDtcbiAgICB9XG5cbiAgICBnZXRTVkcob3BlcmF0b3JMaXN0LCB2aWV3cG9ydCkge1xuICAgICAgdGhpcy52aWV3cG9ydCA9IHZpZXdwb3J0O1xuXG4gICAgICBjb25zdCBzdmdFbGVtZW50ID0gdGhpcy5faW5pdGlhbGl6ZSh2aWV3cG9ydCk7XG5cbiAgICAgIHJldHVybiB0aGlzLmxvYWREZXBlbmRlbmNpZXMob3BlcmF0b3JMaXN0KS50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1NYXRyaXggPSBfdXRpbC5JREVOVElUWV9NQVRSSVg7XG4gICAgICAgIHRoaXMuZXhlY3V0ZU9wVHJlZSh0aGlzLmNvbnZlcnRPcExpc3Qob3BlcmF0b3JMaXN0KSk7XG4gICAgICAgIHJldHVybiBzdmdFbGVtZW50O1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29udmVydE9wTGlzdChvcGVyYXRvckxpc3QpIHtcbiAgICAgIGNvbnN0IG9wZXJhdG9ySWRNYXBwaW5nID0gdGhpcy5fb3BlcmF0b3JJZE1hcHBpbmc7XG4gICAgICBjb25zdCBhcmdzQXJyYXkgPSBvcGVyYXRvckxpc3QuYXJnc0FycmF5O1xuICAgICAgY29uc3QgZm5BcnJheSA9IG9wZXJhdG9yTGlzdC5mbkFycmF5O1xuICAgICAgY29uc3Qgb3BMaXN0ID0gW107XG5cbiAgICAgIGZvciAobGV0IGkgPSAwLCBpaSA9IGZuQXJyYXkubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICBjb25zdCBmbklkID0gZm5BcnJheVtpXTtcbiAgICAgICAgb3BMaXN0LnB1c2goe1xuICAgICAgICAgIGZuSWQsXG4gICAgICAgICAgZm46IG9wZXJhdG9ySWRNYXBwaW5nW2ZuSWRdLFxuICAgICAgICAgIGFyZ3M6IGFyZ3NBcnJheVtpXVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG9wTGlzdFRvVHJlZShvcExpc3QpO1xuICAgIH1cblxuICAgIGV4ZWN1dGVPcFRyZWUob3BUcmVlKSB7XG4gICAgICBmb3IgKGNvbnN0IG9wVHJlZUVsZW1lbnQgb2Ygb3BUcmVlKSB7XG4gICAgICAgIGNvbnN0IGZuID0gb3BUcmVlRWxlbWVudC5mbjtcbiAgICAgICAgY29uc3QgZm5JZCA9IG9wVHJlZUVsZW1lbnQuZm5JZDtcbiAgICAgICAgY29uc3QgYXJncyA9IG9wVHJlZUVsZW1lbnQuYXJncztcblxuICAgICAgICBzd2l0Y2ggKGZuSWQgfCAwKSB7XG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuYmVnaW5UZXh0OlxuICAgICAgICAgICAgdGhpcy5iZWdpblRleHQoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuZGVwZW5kZW5jeTpcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0TGVhZGluZzpcbiAgICAgICAgICAgIHRoaXMuc2V0TGVhZGluZyhhcmdzKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0TGVhZGluZ01vdmVUZXh0OlxuICAgICAgICAgICAgdGhpcy5zZXRMZWFkaW5nTW92ZVRleHQoYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnNldEZvbnQ6XG4gICAgICAgICAgICB0aGlzLnNldEZvbnQoYXJncyk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnNob3dUZXh0OlxuICAgICAgICAgICAgdGhpcy5zaG93VGV4dChhcmdzWzBdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2hvd1NwYWNlZFRleHQ6XG4gICAgICAgICAgICB0aGlzLnNob3dUZXh0KGFyZ3NbMF0pO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5lbmRUZXh0OlxuICAgICAgICAgICAgdGhpcy5lbmRUZXh0KCk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLm1vdmVUZXh0OlxuICAgICAgICAgICAgdGhpcy5tb3ZlVGV4dChhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0Q2hhclNwYWNpbmc6XG4gICAgICAgICAgICB0aGlzLnNldENoYXJTcGFjaW5nKGFyZ3NbMF0pO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5zZXRXb3JkU3BhY2luZzpcbiAgICAgICAgICAgIHRoaXMuc2V0V29yZFNwYWNpbmcoYXJnc1swXSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnNldEhTY2FsZTpcbiAgICAgICAgICAgIHRoaXMuc2V0SFNjYWxlKGFyZ3NbMF0pO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5zZXRUZXh0TWF0cml4OlxuICAgICAgICAgICAgdGhpcy5zZXRUZXh0TWF0cml4KGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0sIGFyZ3NbNV0pO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5zZXRUZXh0UmlzZTpcbiAgICAgICAgICAgIHRoaXMuc2V0VGV4dFJpc2UoYXJnc1swXSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnNldFRleHRSZW5kZXJpbmdNb2RlOlxuICAgICAgICAgICAgdGhpcy5zZXRUZXh0UmVuZGVyaW5nTW9kZShhcmdzWzBdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0TGluZVdpZHRoOlxuICAgICAgICAgICAgdGhpcy5zZXRMaW5lV2lkdGgoYXJnc1swXSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnNldExpbmVKb2luOlxuICAgICAgICAgICAgdGhpcy5zZXRMaW5lSm9pbihhcmdzWzBdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0TGluZUNhcDpcbiAgICAgICAgICAgIHRoaXMuc2V0TGluZUNhcChhcmdzWzBdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0TWl0ZXJMaW1pdDpcbiAgICAgICAgICAgIHRoaXMuc2V0TWl0ZXJMaW1pdChhcmdzWzBdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0RmlsbFJHQkNvbG9yOlxuICAgICAgICAgICAgdGhpcy5zZXRGaWxsUkdCQ29sb3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnNldFN0cm9rZVJHQkNvbG9yOlxuICAgICAgICAgICAgdGhpcy5zZXRTdHJva2VSR0JDb2xvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0U3Ryb2tlQ29sb3JOOlxuICAgICAgICAgICAgdGhpcy5zZXRTdHJva2VDb2xvck4oYXJncyk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnNldEZpbGxDb2xvck46XG4gICAgICAgICAgICB0aGlzLnNldEZpbGxDb2xvck4oYXJncyk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnNoYWRpbmdGaWxsOlxuICAgICAgICAgICAgdGhpcy5zaGFkaW5nRmlsbChhcmdzWzBdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0RGFzaDpcbiAgICAgICAgICAgIHRoaXMuc2V0RGFzaChhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0UmVuZGVyaW5nSW50ZW50OlxuICAgICAgICAgICAgdGhpcy5zZXRSZW5kZXJpbmdJbnRlbnQoYXJnc1swXSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnNldEZsYXRuZXNzOlxuICAgICAgICAgICAgdGhpcy5zZXRGbGF0bmVzcyhhcmdzWzBdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0R1N0YXRlOlxuICAgICAgICAgICAgdGhpcy5zZXRHU3RhdGUoYXJnc1swXSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLmZpbGw6XG4gICAgICAgICAgICB0aGlzLmZpbGwoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuZW9GaWxsOlxuICAgICAgICAgICAgdGhpcy5lb0ZpbGwoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc3Ryb2tlOlxuICAgICAgICAgICAgdGhpcy5zdHJva2UoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuZmlsbFN0cm9rZTpcbiAgICAgICAgICAgIHRoaXMuZmlsbFN0cm9rZSgpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5lb0ZpbGxTdHJva2U6XG4gICAgICAgICAgICB0aGlzLmVvRmlsbFN0cm9rZSgpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5jbGlwOlxuICAgICAgICAgICAgdGhpcy5jbGlwKFwibm9uemVyb1wiKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuZW9DbGlwOlxuICAgICAgICAgICAgdGhpcy5jbGlwKFwiZXZlbm9kZFwiKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMucGFpbnRTb2xpZENvbG9ySW1hZ2VNYXNrOlxuICAgICAgICAgICAgdGhpcy5wYWludFNvbGlkQ29sb3JJbWFnZU1hc2soKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMucGFpbnRJbWFnZVhPYmplY3Q6XG4gICAgICAgICAgICB0aGlzLnBhaW50SW1hZ2VYT2JqZWN0KGFyZ3NbMF0pO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5wYWludElubGluZUltYWdlWE9iamVjdDpcbiAgICAgICAgICAgIHRoaXMucGFpbnRJbmxpbmVJbWFnZVhPYmplY3QoYXJnc1swXSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnBhaW50SW1hZ2VNYXNrWE9iamVjdDpcbiAgICAgICAgICAgIHRoaXMucGFpbnRJbWFnZU1hc2tYT2JqZWN0KGFyZ3NbMF0pO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5wYWludEZvcm1YT2JqZWN0QmVnaW46XG4gICAgICAgICAgICB0aGlzLnBhaW50Rm9ybVhPYmplY3RCZWdpbihhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMucGFpbnRGb3JtWE9iamVjdEVuZDpcbiAgICAgICAgICAgIHRoaXMucGFpbnRGb3JtWE9iamVjdEVuZCgpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5jbG9zZVBhdGg6XG4gICAgICAgICAgICB0aGlzLmNsb3NlUGF0aCgpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5jbG9zZVN0cm9rZTpcbiAgICAgICAgICAgIHRoaXMuY2xvc2VTdHJva2UoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuY2xvc2VGaWxsU3Ryb2tlOlxuICAgICAgICAgICAgdGhpcy5jbG9zZUZpbGxTdHJva2UoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuY2xvc2VFT0ZpbGxTdHJva2U6XG4gICAgICAgICAgICB0aGlzLmNsb3NlRU9GaWxsU3Ryb2tlKCk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLm5leHRMaW5lOlxuICAgICAgICAgICAgdGhpcy5uZXh0TGluZSgpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy50cmFuc2Zvcm06XG4gICAgICAgICAgICB0aGlzLnRyYW5zZm9ybShhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdLCBhcmdzWzVdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuY29uc3RydWN0UGF0aDpcbiAgICAgICAgICAgIHRoaXMuY29uc3RydWN0UGF0aChhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuZW5kUGF0aDpcbiAgICAgICAgICAgIHRoaXMuZW5kUGF0aCgpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIDkyOlxuICAgICAgICAgICAgdGhpcy5ncm91cChvcFRyZWVFbGVtZW50Lml0ZW1zKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICgwLCBfdXRpbC53YXJuKShgVW5pbXBsZW1lbnRlZCBvcGVyYXRvciAke2ZufWApO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRXb3JkU3BhY2luZyh3b3JkU3BhY2luZykge1xuICAgICAgdGhpcy5jdXJyZW50LndvcmRTcGFjaW5nID0gd29yZFNwYWNpbmc7XG4gICAgfVxuXG4gICAgc2V0Q2hhclNwYWNpbmcoY2hhclNwYWNpbmcpIHtcbiAgICAgIHRoaXMuY3VycmVudC5jaGFyU3BhY2luZyA9IGNoYXJTcGFjaW5nO1xuICAgIH1cblxuICAgIG5leHRMaW5lKCkge1xuICAgICAgdGhpcy5tb3ZlVGV4dCgwLCB0aGlzLmN1cnJlbnQubGVhZGluZyk7XG4gICAgfVxuXG4gICAgc2V0VGV4dE1hdHJpeChhLCBiLCBjLCBkLCBlLCBmKSB7XG4gICAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5jdXJyZW50O1xuICAgICAgY3VycmVudC50ZXh0TWF0cml4ID0gY3VycmVudC5saW5lTWF0cml4ID0gW2EsIGIsIGMsIGQsIGUsIGZdO1xuICAgICAgY3VycmVudC50ZXh0TWF0cml4U2NhbGUgPSBNYXRoLmh5cG90KGEsIGIpO1xuICAgICAgY3VycmVudC54ID0gY3VycmVudC5saW5lWCA9IDA7XG4gICAgICBjdXJyZW50LnkgPSBjdXJyZW50LmxpbmVZID0gMDtcbiAgICAgIGN1cnJlbnQueGNvb3JkcyA9IFtdO1xuICAgICAgY3VycmVudC55Y29vcmRzID0gW107XG4gICAgICBjdXJyZW50LnRzcGFuID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZUVsZW1lbnQoXCJzdmc6dHNwYW5cIik7XG4gICAgICBjdXJyZW50LnRzcGFuLnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZm9udC1mYW1pbHlcIiwgY3VycmVudC5mb250RmFtaWx5KTtcbiAgICAgIGN1cnJlbnQudHNwYW4uc2V0QXR0cmlidXRlTlMobnVsbCwgXCJmb250LXNpemVcIiwgYCR7cGYoY3VycmVudC5mb250U2l6ZSl9cHhgKTtcbiAgICAgIGN1cnJlbnQudHNwYW4uc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ5XCIsIHBmKC1jdXJyZW50LnkpKTtcbiAgICAgIGN1cnJlbnQudHh0RWxlbWVudCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOnRleHRcIik7XG4gICAgICBjdXJyZW50LnR4dEVsZW1lbnQuYXBwZW5kQ2hpbGQoY3VycmVudC50c3Bhbik7XG4gICAgfVxuXG4gICAgYmVnaW5UZXh0KCkge1xuICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcbiAgICAgIGN1cnJlbnQueCA9IGN1cnJlbnQubGluZVggPSAwO1xuICAgICAgY3VycmVudC55ID0gY3VycmVudC5saW5lWSA9IDA7XG4gICAgICBjdXJyZW50LnRleHRNYXRyaXggPSBfdXRpbC5JREVOVElUWV9NQVRSSVg7XG4gICAgICBjdXJyZW50LmxpbmVNYXRyaXggPSBfdXRpbC5JREVOVElUWV9NQVRSSVg7XG4gICAgICBjdXJyZW50LnRleHRNYXRyaXhTY2FsZSA9IDE7XG4gICAgICBjdXJyZW50LnRzcGFuID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZUVsZW1lbnQoXCJzdmc6dHNwYW5cIik7XG4gICAgICBjdXJyZW50LnR4dEVsZW1lbnQgPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlRWxlbWVudChcInN2Zzp0ZXh0XCIpO1xuICAgICAgY3VycmVudC50eHRncnAgPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlRWxlbWVudChcInN2ZzpnXCIpO1xuICAgICAgY3VycmVudC54Y29vcmRzID0gW107XG4gICAgICBjdXJyZW50Lnljb29yZHMgPSBbXTtcbiAgICB9XG5cbiAgICBtb3ZlVGV4dCh4LCB5KSB7XG4gICAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5jdXJyZW50O1xuICAgICAgY3VycmVudC54ID0gY3VycmVudC5saW5lWCArPSB4O1xuICAgICAgY3VycmVudC55ID0gY3VycmVudC5saW5lWSArPSB5O1xuICAgICAgY3VycmVudC54Y29vcmRzID0gW107XG4gICAgICBjdXJyZW50Lnljb29yZHMgPSBbXTtcbiAgICAgIGN1cnJlbnQudHNwYW4gPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlRWxlbWVudChcInN2Zzp0c3BhblwiKTtcbiAgICAgIGN1cnJlbnQudHNwYW4uc2V0QXR0cmlidXRlTlMobnVsbCwgXCJmb250LWZhbWlseVwiLCBjdXJyZW50LmZvbnRGYW1pbHkpO1xuICAgICAgY3VycmVudC50c3Bhbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImZvbnQtc2l6ZVwiLCBgJHtwZihjdXJyZW50LmZvbnRTaXplKX1weGApO1xuICAgICAgY3VycmVudC50c3Bhbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInlcIiwgcGYoLWN1cnJlbnQueSkpO1xuICAgIH1cblxuICAgIHNob3dUZXh0KGdseXBocykge1xuICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcbiAgICAgIGNvbnN0IGZvbnQgPSBjdXJyZW50LmZvbnQ7XG4gICAgICBjb25zdCBmb250U2l6ZSA9IGN1cnJlbnQuZm9udFNpemU7XG5cbiAgICAgIGlmIChmb250U2l6ZSA9PT0gMCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZvbnRTaXplU2NhbGUgPSBjdXJyZW50LmZvbnRTaXplU2NhbGU7XG4gICAgICBjb25zdCBjaGFyU3BhY2luZyA9IGN1cnJlbnQuY2hhclNwYWNpbmc7XG4gICAgICBjb25zdCB3b3JkU3BhY2luZyA9IGN1cnJlbnQud29yZFNwYWNpbmc7XG4gICAgICBjb25zdCBmb250RGlyZWN0aW9uID0gY3VycmVudC5mb250RGlyZWN0aW9uO1xuICAgICAgY29uc3QgdGV4dEhTY2FsZSA9IGN1cnJlbnQudGV4dEhTY2FsZSAqIGZvbnREaXJlY3Rpb247XG4gICAgICBjb25zdCB2ZXJ0aWNhbCA9IGZvbnQudmVydGljYWw7XG4gICAgICBjb25zdCBzcGFjaW5nRGlyID0gdmVydGljYWwgPyAxIDogLTE7XG4gICAgICBjb25zdCBkZWZhdWx0Vk1ldHJpY3MgPSBmb250LmRlZmF1bHRWTWV0cmljcztcbiAgICAgIGNvbnN0IHdpZHRoQWR2YW5jZVNjYWxlID0gZm9udFNpemUgKiBjdXJyZW50LmZvbnRNYXRyaXhbMF07XG4gICAgICBsZXQgeCA9IDA7XG5cbiAgICAgIGZvciAoY29uc3QgZ2x5cGggb2YgZ2x5cGhzKSB7XG4gICAgICAgIGlmIChnbHlwaCA9PT0gbnVsbCkge1xuICAgICAgICAgIHggKz0gZm9udERpcmVjdGlvbiAqIHdvcmRTcGFjaW5nO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBnbHlwaCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgIHggKz0gc3BhY2luZ0RpciAqIGdseXBoICogZm9udFNpemUgLyAxMDAwO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc3BhY2luZyA9IChnbHlwaC5pc1NwYWNlID8gd29yZFNwYWNpbmcgOiAwKSArIGNoYXJTcGFjaW5nO1xuICAgICAgICBjb25zdCBjaGFyYWN0ZXIgPSBnbHlwaC5mb250Q2hhcjtcbiAgICAgICAgbGV0IHNjYWxlZFgsIHNjYWxlZFk7XG4gICAgICAgIGxldCB3aWR0aCA9IGdseXBoLndpZHRoO1xuXG4gICAgICAgIGlmICh2ZXJ0aWNhbCkge1xuICAgICAgICAgIGxldCB2eDtcbiAgICAgICAgICBjb25zdCB2bWV0cmljID0gZ2x5cGgudm1ldHJpYyB8fCBkZWZhdWx0Vk1ldHJpY3M7XG4gICAgICAgICAgdnggPSBnbHlwaC52bWV0cmljID8gdm1ldHJpY1sxXSA6IHdpZHRoICogMC41O1xuICAgICAgICAgIHZ4ID0gLXZ4ICogd2lkdGhBZHZhbmNlU2NhbGU7XG4gICAgICAgICAgY29uc3QgdnkgPSB2bWV0cmljWzJdICogd2lkdGhBZHZhbmNlU2NhbGU7XG4gICAgICAgICAgd2lkdGggPSB2bWV0cmljID8gLXZtZXRyaWNbMF0gOiB3aWR0aDtcbiAgICAgICAgICBzY2FsZWRYID0gdnggLyBmb250U2l6ZVNjYWxlO1xuICAgICAgICAgIHNjYWxlZFkgPSAoeCArIHZ5KSAvIGZvbnRTaXplU2NhbGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2NhbGVkWCA9IHggLyBmb250U2l6ZVNjYWxlO1xuICAgICAgICAgIHNjYWxlZFkgPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGdseXBoLmlzSW5Gb250IHx8IGZvbnQubWlzc2luZ0ZpbGUpIHtcbiAgICAgICAgICBjdXJyZW50Lnhjb29yZHMucHVzaChjdXJyZW50LnggKyBzY2FsZWRYKTtcblxuICAgICAgICAgIGlmICh2ZXJ0aWNhbCkge1xuICAgICAgICAgICAgY3VycmVudC55Y29vcmRzLnB1c2goLWN1cnJlbnQueSArIHNjYWxlZFkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGN1cnJlbnQudHNwYW4udGV4dENvbnRlbnQgKz0gY2hhcmFjdGVyO1xuICAgICAgICB9IGVsc2Uge31cblxuICAgICAgICBsZXQgY2hhcldpZHRoO1xuXG4gICAgICAgIGlmICh2ZXJ0aWNhbCkge1xuICAgICAgICAgIGNoYXJXaWR0aCA9IHdpZHRoICogd2lkdGhBZHZhbmNlU2NhbGUgLSBzcGFjaW5nICogZm9udERpcmVjdGlvbjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjaGFyV2lkdGggPSB3aWR0aCAqIHdpZHRoQWR2YW5jZVNjYWxlICsgc3BhY2luZyAqIGZvbnREaXJlY3Rpb247XG4gICAgICAgIH1cblxuICAgICAgICB4ICs9IGNoYXJXaWR0aDtcbiAgICAgIH1cblxuICAgICAgY3VycmVudC50c3Bhbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInhcIiwgY3VycmVudC54Y29vcmRzLm1hcChwZikuam9pbihcIiBcIikpO1xuXG4gICAgICBpZiAodmVydGljYWwpIHtcbiAgICAgICAgY3VycmVudC50c3Bhbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInlcIiwgY3VycmVudC55Y29vcmRzLm1hcChwZikuam9pbihcIiBcIikpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3VycmVudC50c3Bhbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInlcIiwgcGYoLWN1cnJlbnQueSkpO1xuICAgICAgfVxuXG4gICAgICBpZiAodmVydGljYWwpIHtcbiAgICAgICAgY3VycmVudC55IC09IHg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjdXJyZW50LnggKz0geCAqIHRleHRIU2NhbGU7XG4gICAgICB9XG5cbiAgICAgIGN1cnJlbnQudHNwYW4uc2V0QXR0cmlidXRlTlMobnVsbCwgXCJmb250LWZhbWlseVwiLCBjdXJyZW50LmZvbnRGYW1pbHkpO1xuICAgICAgY3VycmVudC50c3Bhbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImZvbnQtc2l6ZVwiLCBgJHtwZihjdXJyZW50LmZvbnRTaXplKX1weGApO1xuXG4gICAgICBpZiAoY3VycmVudC5mb250U3R5bGUgIT09IFNWR19ERUZBVUxUUy5mb250U3R5bGUpIHtcbiAgICAgICAgY3VycmVudC50c3Bhbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImZvbnQtc3R5bGVcIiwgY3VycmVudC5mb250U3R5bGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoY3VycmVudC5mb250V2VpZ2h0ICE9PSBTVkdfREVGQVVMVFMuZm9udFdlaWdodCkge1xuICAgICAgICBjdXJyZW50LnRzcGFuLnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZm9udC13ZWlnaHRcIiwgY3VycmVudC5mb250V2VpZ2h0KTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZmlsbFN0cm9rZU1vZGUgPSBjdXJyZW50LnRleHRSZW5kZXJpbmdNb2RlICYgX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuRklMTF9TVFJPS0VfTUFTSztcblxuICAgICAgaWYgKGZpbGxTdHJva2VNb2RlID09PSBfdXRpbC5UZXh0UmVuZGVyaW5nTW9kZS5GSUxMIHx8IGZpbGxTdHJva2VNb2RlID09PSBfdXRpbC5UZXh0UmVuZGVyaW5nTW9kZS5GSUxMX1NUUk9LRSkge1xuICAgICAgICBpZiAoY3VycmVudC5maWxsQ29sb3IgIT09IFNWR19ERUZBVUxUUy5maWxsQ29sb3IpIHtcbiAgICAgICAgICBjdXJyZW50LnRzcGFuLnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZmlsbFwiLCBjdXJyZW50LmZpbGxDb2xvcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY3VycmVudC5maWxsQWxwaGEgPCAxKSB7XG4gICAgICAgICAgY3VycmVudC50c3Bhbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImZpbGwtb3BhY2l0eVwiLCBjdXJyZW50LmZpbGxBbHBoYSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoY3VycmVudC50ZXh0UmVuZGVyaW5nTW9kZSA9PT0gX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuQUREX1RPX1BBVEgpIHtcbiAgICAgICAgY3VycmVudC50c3Bhbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImZpbGxcIiwgXCJ0cmFuc3BhcmVudFwiKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGN1cnJlbnQudHNwYW4uc2V0QXR0cmlidXRlTlMobnVsbCwgXCJmaWxsXCIsIFwibm9uZVwiKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGZpbGxTdHJva2VNb2RlID09PSBfdXRpbC5UZXh0UmVuZGVyaW5nTW9kZS5TVFJPS0UgfHwgZmlsbFN0cm9rZU1vZGUgPT09IF91dGlsLlRleHRSZW5kZXJpbmdNb2RlLkZJTExfU1RST0tFKSB7XG4gICAgICAgIGNvbnN0IGxpbmVXaWR0aFNjYWxlID0gMSAvIChjdXJyZW50LnRleHRNYXRyaXhTY2FsZSB8fCAxKTtcblxuICAgICAgICB0aGlzLl9zZXRTdHJva2VBdHRyaWJ1dGVzKGN1cnJlbnQudHNwYW4sIGxpbmVXaWR0aFNjYWxlKTtcbiAgICAgIH1cblxuICAgICAgbGV0IHRleHRNYXRyaXggPSBjdXJyZW50LnRleHRNYXRyaXg7XG5cbiAgICAgIGlmIChjdXJyZW50LnRleHRSaXNlICE9PSAwKSB7XG4gICAgICAgIHRleHRNYXRyaXggPSB0ZXh0TWF0cml4LnNsaWNlKCk7XG4gICAgICAgIHRleHRNYXRyaXhbNV0gKz0gY3VycmVudC50ZXh0UmlzZTtcbiAgICAgIH1cblxuICAgICAgY3VycmVudC50eHRFbGVtZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwidHJhbnNmb3JtXCIsIGAke3BtKHRleHRNYXRyaXgpfSBzY2FsZSgke3BmKHRleHRIU2NhbGUpfSwgLTEpYCk7XG4gICAgICBjdXJyZW50LnR4dEVsZW1lbnQuc2V0QXR0cmlidXRlTlMoWE1MX05TLCBcInhtbDpzcGFjZVwiLCBcInByZXNlcnZlXCIpO1xuICAgICAgY3VycmVudC50eHRFbGVtZW50LmFwcGVuZENoaWxkKGN1cnJlbnQudHNwYW4pO1xuICAgICAgY3VycmVudC50eHRncnAuYXBwZW5kQ2hpbGQoY3VycmVudC50eHRFbGVtZW50KTtcblxuICAgICAgdGhpcy5fZW5zdXJlVHJhbnNmb3JtR3JvdXAoKS5hcHBlbmRDaGlsZChjdXJyZW50LnR4dEVsZW1lbnQpO1xuICAgIH1cblxuICAgIHNldExlYWRpbmdNb3ZlVGV4dCh4LCB5KSB7XG4gICAgICB0aGlzLnNldExlYWRpbmcoLXkpO1xuICAgICAgdGhpcy5tb3ZlVGV4dCh4LCB5KTtcbiAgICB9XG5cbiAgICBhZGRGb250U3R5bGUoZm9udE9iaikge1xuICAgICAgaWYgKCFmb250T2JqLmRhdGEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiYWRkRm9udFN0eWxlOiBObyBmb250IGRhdGEgYXZhaWxhYmxlLCBcIiArICdlbnN1cmUgdGhhdCB0aGUgXCJmb250RXh0cmFQcm9wZXJ0aWVzXCIgQVBJIHBhcmFtZXRlciBpcyBzZXQuJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghdGhpcy5jc3NTdHlsZSkge1xuICAgICAgICB0aGlzLmNzc1N0eWxlID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZUVsZW1lbnQoXCJzdmc6c3R5bGVcIik7XG4gICAgICAgIHRoaXMuY3NzU3R5bGUuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ0eXBlXCIsIFwidGV4dC9jc3NcIik7XG4gICAgICAgIHRoaXMuZGVmcy5hcHBlbmRDaGlsZCh0aGlzLmNzc1N0eWxlKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdXJsID0gY3JlYXRlT2JqZWN0VVJMKGZvbnRPYmouZGF0YSwgZm9udE9iai5taW1ldHlwZSwgdGhpcy5mb3JjZURhdGFTY2hlbWEpO1xuICAgICAgdGhpcy5jc3NTdHlsZS50ZXh0Q29udGVudCArPSBgQGZvbnQtZmFjZSB7IGZvbnQtZmFtaWx5OiBcIiR7Zm9udE9iai5sb2FkZWROYW1lfVwiO2AgKyBgIHNyYzogdXJsKCR7dXJsfSk7IH1cXG5gO1xuICAgIH1cblxuICAgIHNldEZvbnQoZGV0YWlscykge1xuICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcbiAgICAgIGNvbnN0IGZvbnRPYmogPSB0aGlzLmNvbW1vbk9ianMuZ2V0KGRldGFpbHNbMF0pO1xuICAgICAgbGV0IHNpemUgPSBkZXRhaWxzWzFdO1xuICAgICAgY3VycmVudC5mb250ID0gZm9udE9iajtcblxuICAgICAgaWYgKHRoaXMuZW1iZWRGb250cyAmJiAhZm9udE9iai5taXNzaW5nRmlsZSAmJiAhdGhpcy5lbWJlZGRlZEZvbnRzW2ZvbnRPYmoubG9hZGVkTmFtZV0pIHtcbiAgICAgICAgdGhpcy5hZGRGb250U3R5bGUoZm9udE9iaik7XG4gICAgICAgIHRoaXMuZW1iZWRkZWRGb250c1tmb250T2JqLmxvYWRlZE5hbWVdID0gZm9udE9iajtcbiAgICAgIH1cblxuICAgICAgY3VycmVudC5mb250TWF0cml4ID0gZm9udE9iai5mb250TWF0cml4IHx8IF91dGlsLkZPTlRfSURFTlRJVFlfTUFUUklYO1xuICAgICAgbGV0IGJvbGQgPSBcIm5vcm1hbFwiO1xuXG4gICAgICBpZiAoZm9udE9iai5ibGFjaykge1xuICAgICAgICBib2xkID0gXCI5MDBcIjtcbiAgICAgIH0gZWxzZSBpZiAoZm9udE9iai5ib2xkKSB7XG4gICAgICAgIGJvbGQgPSBcImJvbGRcIjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaXRhbGljID0gZm9udE9iai5pdGFsaWMgPyBcIml0YWxpY1wiIDogXCJub3JtYWxcIjtcblxuICAgICAgaWYgKHNpemUgPCAwKSB7XG4gICAgICAgIHNpemUgPSAtc2l6ZTtcbiAgICAgICAgY3VycmVudC5mb250RGlyZWN0aW9uID0gLTE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjdXJyZW50LmZvbnREaXJlY3Rpb24gPSAxO1xuICAgICAgfVxuXG4gICAgICBjdXJyZW50LmZvbnRTaXplID0gc2l6ZTtcbiAgICAgIGN1cnJlbnQuZm9udEZhbWlseSA9IGZvbnRPYmoubG9hZGVkTmFtZTtcbiAgICAgIGN1cnJlbnQuZm9udFdlaWdodCA9IGJvbGQ7XG4gICAgICBjdXJyZW50LmZvbnRTdHlsZSA9IGl0YWxpYztcbiAgICAgIGN1cnJlbnQudHNwYW4gPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlRWxlbWVudChcInN2Zzp0c3BhblwiKTtcbiAgICAgIGN1cnJlbnQudHNwYW4uc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ5XCIsIHBmKC1jdXJyZW50LnkpKTtcbiAgICAgIGN1cnJlbnQueGNvb3JkcyA9IFtdO1xuICAgICAgY3VycmVudC55Y29vcmRzID0gW107XG4gICAgfVxuXG4gICAgZW5kVGV4dCgpIHtcbiAgICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmN1cnJlbnQ7XG5cbiAgICAgIGlmIChjdXJyZW50LnRleHRSZW5kZXJpbmdNb2RlICYgX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuQUREX1RPX1BBVEhfRkxBRyAmJiBjdXJyZW50LnR4dEVsZW1lbnQ/Lmhhc0NoaWxkTm9kZXMoKSkge1xuICAgICAgICBjdXJyZW50LmVsZW1lbnQgPSBjdXJyZW50LnR4dEVsZW1lbnQ7XG4gICAgICAgIHRoaXMuY2xpcChcIm5vbnplcm9cIik7XG4gICAgICAgIHRoaXMuZW5kUGF0aCgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHNldExpbmVXaWR0aCh3aWR0aCkge1xuICAgICAgaWYgKHdpZHRoID4gMCkge1xuICAgICAgICB0aGlzLmN1cnJlbnQubGluZVdpZHRoID0gd2lkdGg7XG4gICAgICB9XG4gICAgfVxuXG4gICAgc2V0TGluZUNhcChzdHlsZSkge1xuICAgICAgdGhpcy5jdXJyZW50LmxpbmVDYXAgPSBMSU5FX0NBUF9TVFlMRVNbc3R5bGVdO1xuICAgIH1cblxuICAgIHNldExpbmVKb2luKHN0eWxlKSB7XG4gICAgICB0aGlzLmN1cnJlbnQubGluZUpvaW4gPSBMSU5FX0pPSU5fU1RZTEVTW3N0eWxlXTtcbiAgICB9XG5cbiAgICBzZXRNaXRlckxpbWl0KGxpbWl0KSB7XG4gICAgICB0aGlzLmN1cnJlbnQubWl0ZXJMaW1pdCA9IGxpbWl0O1xuICAgIH1cblxuICAgIHNldFN0cm9rZUFscGhhKHN0cm9rZUFscGhhKSB7XG4gICAgICB0aGlzLmN1cnJlbnQuc3Ryb2tlQWxwaGEgPSBzdHJva2VBbHBoYTtcbiAgICB9XG5cbiAgICBzZXRTdHJva2VSR0JDb2xvcihyLCBnLCBiKSB7XG4gICAgICB0aGlzLmN1cnJlbnQuc3Ryb2tlQ29sb3IgPSBfdXRpbC5VdGlsLm1ha2VIZXhDb2xvcihyLCBnLCBiKTtcbiAgICB9XG5cbiAgICBzZXRGaWxsQWxwaGEoZmlsbEFscGhhKSB7XG4gICAgICB0aGlzLmN1cnJlbnQuZmlsbEFscGhhID0gZmlsbEFscGhhO1xuICAgIH1cblxuICAgIHNldEZpbGxSR0JDb2xvcihyLCBnLCBiKSB7XG4gICAgICB0aGlzLmN1cnJlbnQuZmlsbENvbG9yID0gX3V0aWwuVXRpbC5tYWtlSGV4Q29sb3IociwgZywgYik7XG4gICAgICB0aGlzLmN1cnJlbnQudHNwYW4gPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlRWxlbWVudChcInN2Zzp0c3BhblwiKTtcbiAgICAgIHRoaXMuY3VycmVudC54Y29vcmRzID0gW107XG4gICAgICB0aGlzLmN1cnJlbnQueWNvb3JkcyA9IFtdO1xuICAgIH1cblxuICAgIHNldFN0cm9rZUNvbG9yTihhcmdzKSB7XG4gICAgICB0aGlzLmN1cnJlbnQuc3Ryb2tlQ29sb3IgPSB0aGlzLl9tYWtlQ29sb3JOX1BhdHRlcm4oYXJncyk7XG4gICAgfVxuXG4gICAgc2V0RmlsbENvbG9yTihhcmdzKSB7XG4gICAgICB0aGlzLmN1cnJlbnQuZmlsbENvbG9yID0gdGhpcy5fbWFrZUNvbG9yTl9QYXR0ZXJuKGFyZ3MpO1xuICAgIH1cblxuICAgIHNoYWRpbmdGaWxsKGFyZ3MpIHtcbiAgICAgIGNvbnN0IHdpZHRoID0gdGhpcy52aWV3cG9ydC53aWR0aDtcbiAgICAgIGNvbnN0IGhlaWdodCA9IHRoaXMudmlld3BvcnQuaGVpZ2h0O1xuXG4gICAgICBjb25zdCBpbnYgPSBfdXRpbC5VdGlsLmludmVyc2VUcmFuc2Zvcm0odGhpcy50cmFuc2Zvcm1NYXRyaXgpO1xuXG4gICAgICBjb25zdCBibCA9IF91dGlsLlV0aWwuYXBwbHlUcmFuc2Zvcm0oWzAsIDBdLCBpbnYpO1xuXG4gICAgICBjb25zdCBiciA9IF91dGlsLlV0aWwuYXBwbHlUcmFuc2Zvcm0oWzAsIGhlaWdodF0sIGludik7XG5cbiAgICAgIGNvbnN0IHVsID0gX3V0aWwuVXRpbC5hcHBseVRyYW5zZm9ybShbd2lkdGgsIDBdLCBpbnYpO1xuXG4gICAgICBjb25zdCB1ciA9IF91dGlsLlV0aWwuYXBwbHlUcmFuc2Zvcm0oW3dpZHRoLCBoZWlnaHRdLCBpbnYpO1xuXG4gICAgICBjb25zdCB4MCA9IE1hdGgubWluKGJsWzBdLCBiclswXSwgdWxbMF0sIHVyWzBdKTtcbiAgICAgIGNvbnN0IHkwID0gTWF0aC5taW4oYmxbMV0sIGJyWzFdLCB1bFsxXSwgdXJbMV0pO1xuICAgICAgY29uc3QgeDEgPSBNYXRoLm1heChibFswXSwgYnJbMF0sIHVsWzBdLCB1clswXSk7XG4gICAgICBjb25zdCB5MSA9IE1hdGgubWF4KGJsWzFdLCBiclsxXSwgdWxbMV0sIHVyWzFdKTtcbiAgICAgIGNvbnN0IHJlY3QgPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlRWxlbWVudChcInN2ZzpyZWN0XCIpO1xuICAgICAgcmVjdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInhcIiwgeDApO1xuICAgICAgcmVjdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInlcIiwgeTApO1xuICAgICAgcmVjdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcIndpZHRoXCIsIHgxIC0geDApO1xuICAgICAgcmVjdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImhlaWdodFwiLCB5MSAtIHkwKTtcbiAgICAgIHJlY3Quc2V0QXR0cmlidXRlTlMobnVsbCwgXCJmaWxsXCIsIHRoaXMuX21ha2VTaGFkaW5nUGF0dGVybihhcmdzKSk7XG5cbiAgICAgIGlmICh0aGlzLmN1cnJlbnQuZmlsbEFscGhhIDwgMSkge1xuICAgICAgICByZWN0LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZmlsbC1vcGFjaXR5XCIsIHRoaXMuY3VycmVudC5maWxsQWxwaGEpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9lbnN1cmVUcmFuc2Zvcm1Hcm91cCgpLmFwcGVuZENoaWxkKHJlY3QpO1xuICAgIH1cblxuICAgIF9tYWtlQ29sb3JOX1BhdHRlcm4oYXJncykge1xuICAgICAgaWYgKGFyZ3NbMF0gPT09IFwiVGlsaW5nUGF0dGVyblwiKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYWtlVGlsaW5nUGF0dGVybihhcmdzKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuX21ha2VTaGFkaW5nUGF0dGVybihhcmdzKTtcbiAgICB9XG5cbiAgICBfbWFrZVRpbGluZ1BhdHRlcm4oYXJncykge1xuICAgICAgY29uc3QgY29sb3IgPSBhcmdzWzFdO1xuICAgICAgY29uc3Qgb3BlcmF0b3JMaXN0ID0gYXJnc1syXTtcbiAgICAgIGNvbnN0IG1hdHJpeCA9IGFyZ3NbM10gfHwgX3V0aWwuSURFTlRJVFlfTUFUUklYO1xuICAgICAgY29uc3QgW3gwLCB5MCwgeDEsIHkxXSA9IGFyZ3NbNF07XG4gICAgICBjb25zdCB4c3RlcCA9IGFyZ3NbNV07XG4gICAgICBjb25zdCB5c3RlcCA9IGFyZ3NbNl07XG4gICAgICBjb25zdCBwYWludFR5cGUgPSBhcmdzWzddO1xuICAgICAgY29uc3QgdGlsaW5nSWQgPSBgc2hhZGluZyR7c2hhZGluZ0NvdW50Kyt9YDtcblxuICAgICAgY29uc3QgW3R4MCwgdHkwLCB0eDEsIHR5MV0gPSBfdXRpbC5VdGlsLm5vcm1hbGl6ZVJlY3QoWy4uLl91dGlsLlV0aWwuYXBwbHlUcmFuc2Zvcm0oW3gwLCB5MF0sIG1hdHJpeCksIC4uLl91dGlsLlV0aWwuYXBwbHlUcmFuc2Zvcm0oW3gxLCB5MV0sIG1hdHJpeCldKTtcblxuICAgICAgY29uc3QgW3hzY2FsZSwgeXNjYWxlXSA9IF91dGlsLlV0aWwuc2luZ3VsYXJWYWx1ZURlY29tcG9zZTJkU2NhbGUobWF0cml4KTtcblxuICAgICAgY29uc3QgdHhzdGVwID0geHN0ZXAgKiB4c2NhbGU7XG4gICAgICBjb25zdCB0eXN0ZXAgPSB5c3RlcCAqIHlzY2FsZTtcbiAgICAgIGNvbnN0IHRpbGluZyA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOnBhdHRlcm5cIik7XG4gICAgICB0aWxpbmcuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJpZFwiLCB0aWxpbmdJZCk7XG4gICAgICB0aWxpbmcuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJwYXR0ZXJuVW5pdHNcIiwgXCJ1c2VyU3BhY2VPblVzZVwiKTtcbiAgICAgIHRpbGluZy5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcIndpZHRoXCIsIHR4c3RlcCk7XG4gICAgICB0aWxpbmcuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJoZWlnaHRcIiwgdHlzdGVwKTtcbiAgICAgIHRpbGluZy5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInhcIiwgYCR7dHgwfWApO1xuICAgICAgdGlsaW5nLnNldEF0dHJpYnV0ZU5TKG51bGwsIFwieVwiLCBgJHt0eTB9YCk7XG4gICAgICBjb25zdCBzdmcgPSB0aGlzLnN2ZztcbiAgICAgIGNvbnN0IHRyYW5zZm9ybU1hdHJpeCA9IHRoaXMudHJhbnNmb3JtTWF0cml4O1xuICAgICAgY29uc3QgZmlsbENvbG9yID0gdGhpcy5jdXJyZW50LmZpbGxDb2xvcjtcbiAgICAgIGNvbnN0IHN0cm9rZUNvbG9yID0gdGhpcy5jdXJyZW50LnN0cm9rZUNvbG9yO1xuICAgICAgY29uc3QgYmJveCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGUodHgxIC0gdHgwLCB0eTEgLSB0eTApO1xuICAgICAgdGhpcy5zdmcgPSBiYm94O1xuICAgICAgdGhpcy50cmFuc2Zvcm1NYXRyaXggPSBtYXRyaXg7XG5cbiAgICAgIGlmIChwYWludFR5cGUgPT09IDIpIHtcbiAgICAgICAgY29uc3QgY3NzQ29sb3IgPSBfdXRpbC5VdGlsLm1ha2VIZXhDb2xvciguLi5jb2xvcik7XG5cbiAgICAgICAgdGhpcy5jdXJyZW50LmZpbGxDb2xvciA9IGNzc0NvbG9yO1xuICAgICAgICB0aGlzLmN1cnJlbnQuc3Ryb2tlQ29sb3IgPSBjc3NDb2xvcjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5leGVjdXRlT3BUcmVlKHRoaXMuY29udmVydE9wTGlzdChvcGVyYXRvckxpc3QpKTtcbiAgICAgIHRoaXMuc3ZnID0gc3ZnO1xuICAgICAgdGhpcy50cmFuc2Zvcm1NYXRyaXggPSB0cmFuc2Zvcm1NYXRyaXg7XG4gICAgICB0aGlzLmN1cnJlbnQuZmlsbENvbG9yID0gZmlsbENvbG9yO1xuICAgICAgdGhpcy5jdXJyZW50LnN0cm9rZUNvbG9yID0gc3Ryb2tlQ29sb3I7XG4gICAgICB0aWxpbmcuYXBwZW5kQ2hpbGQoYmJveC5jaGlsZE5vZGVzWzBdKTtcbiAgICAgIHRoaXMuZGVmcy5hcHBlbmRDaGlsZCh0aWxpbmcpO1xuICAgICAgcmV0dXJuIGB1cmwoIyR7dGlsaW5nSWR9KWA7XG4gICAgfVxuXG4gICAgX21ha2VTaGFkaW5nUGF0dGVybihhcmdzKSB7XG4gICAgICBpZiAodHlwZW9mIGFyZ3MgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgYXJncyA9IHRoaXMub2Jqcy5nZXQoYXJncyk7XG4gICAgICB9XG5cbiAgICAgIHN3aXRjaCAoYXJnc1swXSkge1xuICAgICAgICBjYXNlIFwiUmFkaWFsQXhpYWxcIjpcbiAgICAgICAgICBjb25zdCBzaGFkaW5nSWQgPSBgc2hhZGluZyR7c2hhZGluZ0NvdW50Kyt9YDtcbiAgICAgICAgICBjb25zdCBjb2xvclN0b3BzID0gYXJnc1szXTtcbiAgICAgICAgICBsZXQgZ3JhZGllbnQ7XG5cbiAgICAgICAgICBzd2l0Y2ggKGFyZ3NbMV0pIHtcbiAgICAgICAgICAgIGNhc2UgXCJheGlhbFwiOlxuICAgICAgICAgICAgICBjb25zdCBwb2ludDAgPSBhcmdzWzRdO1xuICAgICAgICAgICAgICBjb25zdCBwb2ludDEgPSBhcmdzWzVdO1xuICAgICAgICAgICAgICBncmFkaWVudCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOmxpbmVhckdyYWRpZW50XCIpO1xuICAgICAgICAgICAgICBncmFkaWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImlkXCIsIHNoYWRpbmdJZCk7XG4gICAgICAgICAgICAgIGdyYWRpZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZ3JhZGllbnRVbml0c1wiLCBcInVzZXJTcGFjZU9uVXNlXCIpO1xuICAgICAgICAgICAgICBncmFkaWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcIngxXCIsIHBvaW50MFswXSk7XG4gICAgICAgICAgICAgIGdyYWRpZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwieTFcIiwgcG9pbnQwWzFdKTtcbiAgICAgICAgICAgICAgZ3JhZGllbnQuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ4MlwiLCBwb2ludDFbMF0pO1xuICAgICAgICAgICAgICBncmFkaWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInkyXCIsIHBvaW50MVsxXSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlIFwicmFkaWFsXCI6XG4gICAgICAgICAgICAgIGNvbnN0IGZvY2FsUG9pbnQgPSBhcmdzWzRdO1xuICAgICAgICAgICAgICBjb25zdCBjaXJjbGVQb2ludCA9IGFyZ3NbNV07XG4gICAgICAgICAgICAgIGNvbnN0IGZvY2FsUmFkaXVzID0gYXJnc1s2XTtcbiAgICAgICAgICAgICAgY29uc3QgY2lyY2xlUmFkaXVzID0gYXJnc1s3XTtcbiAgICAgICAgICAgICAgZ3JhZGllbnQgPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlRWxlbWVudChcInN2ZzpyYWRpYWxHcmFkaWVudFwiKTtcbiAgICAgICAgICAgICAgZ3JhZGllbnQuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJpZFwiLCBzaGFkaW5nSWQpO1xuICAgICAgICAgICAgICBncmFkaWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImdyYWRpZW50VW5pdHNcIiwgXCJ1c2VyU3BhY2VPblVzZVwiKTtcbiAgICAgICAgICAgICAgZ3JhZGllbnQuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJjeFwiLCBjaXJjbGVQb2ludFswXSk7XG4gICAgICAgICAgICAgIGdyYWRpZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiY3lcIiwgY2lyY2xlUG9pbnRbMV0pO1xuICAgICAgICAgICAgICBncmFkaWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInJcIiwgY2lyY2xlUmFkaXVzKTtcbiAgICAgICAgICAgICAgZ3JhZGllbnQuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJmeFwiLCBmb2NhbFBvaW50WzBdKTtcbiAgICAgICAgICAgICAgZ3JhZGllbnQuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJmeVwiLCBmb2NhbFBvaW50WzFdKTtcbiAgICAgICAgICAgICAgZ3JhZGllbnQuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJmclwiLCBmb2NhbFJhZGl1cyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gUmFkaWFsQXhpYWwgdHlwZTogJHthcmdzWzFdfWApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGZvciAoY29uc3QgY29sb3JTdG9wIG9mIGNvbG9yU3RvcHMpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0b3AgPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlRWxlbWVudChcInN2ZzpzdG9wXCIpO1xuICAgICAgICAgICAgc3RvcC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcIm9mZnNldFwiLCBjb2xvclN0b3BbMF0pO1xuICAgICAgICAgICAgc3RvcC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInN0b3AtY29sb3JcIiwgY29sb3JTdG9wWzFdKTtcbiAgICAgICAgICAgIGdyYWRpZW50LmFwcGVuZENoaWxkKHN0b3ApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuZGVmcy5hcHBlbmRDaGlsZChncmFkaWVudCk7XG4gICAgICAgICAgcmV0dXJuIGB1cmwoIyR7c2hhZGluZ0lkfSlgO1xuXG4gICAgICAgIGNhc2UgXCJNZXNoXCI6XG4gICAgICAgICAgKDAsIF91dGlsLndhcm4pKFwiVW5pbXBsZW1lbnRlZCBwYXR0ZXJuIE1lc2hcIik7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgY2FzZSBcIkR1bW15XCI6XG4gICAgICAgICAgcmV0dXJuIFwiaG90cGlua1wiO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIElSIHR5cGU6ICR7YXJnc1swXX1gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzZXREYXNoKGRhc2hBcnJheSwgZGFzaFBoYXNlKSB7XG4gICAgICB0aGlzLmN1cnJlbnQuZGFzaEFycmF5ID0gZGFzaEFycmF5O1xuICAgICAgdGhpcy5jdXJyZW50LmRhc2hQaGFzZSA9IGRhc2hQaGFzZTtcbiAgICB9XG5cbiAgICBjb25zdHJ1Y3RQYXRoKG9wcywgYXJncykge1xuICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcbiAgICAgIGxldCB4ID0gY3VycmVudC54LFxuICAgICAgICAgIHkgPSBjdXJyZW50Lnk7XG4gICAgICBsZXQgZCA9IFtdO1xuICAgICAgbGV0IGogPSAwO1xuXG4gICAgICBmb3IgKGNvbnN0IG9wIG9mIG9wcykge1xuICAgICAgICBzd2l0Y2ggKG9wIHwgMCkge1xuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnJlY3RhbmdsZTpcbiAgICAgICAgICAgIHggPSBhcmdzW2orK107XG4gICAgICAgICAgICB5ID0gYXJnc1tqKytdO1xuICAgICAgICAgICAgY29uc3Qgd2lkdGggPSBhcmdzW2orK107XG4gICAgICAgICAgICBjb25zdCBoZWlnaHQgPSBhcmdzW2orK107XG4gICAgICAgICAgICBjb25zdCB4dyA9IHggKyB3aWR0aDtcbiAgICAgICAgICAgIGNvbnN0IHloID0geSArIGhlaWdodDtcbiAgICAgICAgICAgIGQucHVzaChcIk1cIiwgcGYoeCksIHBmKHkpLCBcIkxcIiwgcGYoeHcpLCBwZih5KSwgXCJMXCIsIHBmKHh3KSwgcGYoeWgpLCBcIkxcIiwgcGYoeCksIHBmKHloKSwgXCJaXCIpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5tb3ZlVG86XG4gICAgICAgICAgICB4ID0gYXJnc1tqKytdO1xuICAgICAgICAgICAgeSA9IGFyZ3NbaisrXTtcbiAgICAgICAgICAgIGQucHVzaChcIk1cIiwgcGYoeCksIHBmKHkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMubGluZVRvOlxuICAgICAgICAgICAgeCA9IGFyZ3NbaisrXTtcbiAgICAgICAgICAgIHkgPSBhcmdzW2orK107XG4gICAgICAgICAgICBkLnB1c2goXCJMXCIsIHBmKHgpLCBwZih5KSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLmN1cnZlVG86XG4gICAgICAgICAgICB4ID0gYXJnc1tqICsgNF07XG4gICAgICAgICAgICB5ID0gYXJnc1tqICsgNV07XG4gICAgICAgICAgICBkLnB1c2goXCJDXCIsIHBmKGFyZ3Nbal0pLCBwZihhcmdzW2ogKyAxXSksIHBmKGFyZ3NbaiArIDJdKSwgcGYoYXJnc1tqICsgM10pLCBwZih4KSwgcGYoeSkpO1xuICAgICAgICAgICAgaiArPSA2O1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5jdXJ2ZVRvMjpcbiAgICAgICAgICAgIGQucHVzaChcIkNcIiwgcGYoeCksIHBmKHkpLCBwZihhcmdzW2pdKSwgcGYoYXJnc1tqICsgMV0pLCBwZihhcmdzW2ogKyAyXSksIHBmKGFyZ3NbaiArIDNdKSk7XG4gICAgICAgICAgICB4ID0gYXJnc1tqICsgMl07XG4gICAgICAgICAgICB5ID0gYXJnc1tqICsgM107XG4gICAgICAgICAgICBqICs9IDQ7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLmN1cnZlVG8zOlxuICAgICAgICAgICAgeCA9IGFyZ3NbaiArIDJdO1xuICAgICAgICAgICAgeSA9IGFyZ3NbaiArIDNdO1xuICAgICAgICAgICAgZC5wdXNoKFwiQ1wiLCBwZihhcmdzW2pdKSwgcGYoYXJnc1tqICsgMV0pLCBwZih4KSwgcGYoeSksIHBmKHgpLCBwZih5KSk7XG4gICAgICAgICAgICBqICs9IDQ7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLmNsb3NlUGF0aDpcbiAgICAgICAgICAgIGQucHVzaChcIlpcIik7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBkID0gZC5qb2luKFwiIFwiKTtcblxuICAgICAgaWYgKGN1cnJlbnQucGF0aCAmJiBvcHMubGVuZ3RoID4gMCAmJiBvcHNbMF0gIT09IF91dGlsLk9QUy5yZWN0YW5nbGUgJiYgb3BzWzBdICE9PSBfdXRpbC5PUFMubW92ZVRvKSB7XG4gICAgICAgIGQgPSBjdXJyZW50LnBhdGguZ2V0QXR0cmlidXRlTlMobnVsbCwgXCJkXCIpICsgZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGN1cnJlbnQucGF0aCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOnBhdGhcIik7XG5cbiAgICAgICAgdGhpcy5fZW5zdXJlVHJhbnNmb3JtR3JvdXAoKS5hcHBlbmRDaGlsZChjdXJyZW50LnBhdGgpO1xuICAgICAgfVxuXG4gICAgICBjdXJyZW50LnBhdGguc2V0QXR0cmlidXRlTlMobnVsbCwgXCJkXCIsIGQpO1xuICAgICAgY3VycmVudC5wYXRoLnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZmlsbFwiLCBcIm5vbmVcIik7XG4gICAgICBjdXJyZW50LmVsZW1lbnQgPSBjdXJyZW50LnBhdGg7XG4gICAgICBjdXJyZW50LnNldEN1cnJlbnRQb2ludCh4LCB5KTtcbiAgICB9XG5cbiAgICBlbmRQYXRoKCkge1xuICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcbiAgICAgIGN1cnJlbnQucGF0aCA9IG51bGw7XG5cbiAgICAgIGlmICghdGhpcy5wZW5kaW5nQ2xpcCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICghY3VycmVudC5lbGVtZW50KSB7XG4gICAgICAgIHRoaXMucGVuZGluZ0NsaXAgPSBudWxsO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNsaXBJZCA9IGBjbGlwcGF0aCR7Y2xpcENvdW50Kyt9YDtcbiAgICAgIGNvbnN0IGNsaXBQYXRoID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZUVsZW1lbnQoXCJzdmc6Y2xpcFBhdGhcIik7XG4gICAgICBjbGlwUGF0aC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImlkXCIsIGNsaXBJZCk7XG4gICAgICBjbGlwUGF0aC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInRyYW5zZm9ybVwiLCBwbSh0aGlzLnRyYW5zZm9ybU1hdHJpeCkpO1xuICAgICAgY29uc3QgY2xpcEVsZW1lbnQgPSBjdXJyZW50LmVsZW1lbnQuY2xvbmVOb2RlKHRydWUpO1xuXG4gICAgICBpZiAodGhpcy5wZW5kaW5nQ2xpcCA9PT0gXCJldmVub2RkXCIpIHtcbiAgICAgICAgY2xpcEVsZW1lbnQuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJjbGlwLXJ1bGVcIiwgXCJldmVub2RkXCIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2xpcEVsZW1lbnQuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJjbGlwLXJ1bGVcIiwgXCJub256ZXJvXCIpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnBlbmRpbmdDbGlwID0gbnVsbDtcbiAgICAgIGNsaXBQYXRoLmFwcGVuZENoaWxkKGNsaXBFbGVtZW50KTtcbiAgICAgIHRoaXMuZGVmcy5hcHBlbmRDaGlsZChjbGlwUGF0aCk7XG5cbiAgICAgIGlmIChjdXJyZW50LmFjdGl2ZUNsaXBVcmwpIHtcbiAgICAgICAgY3VycmVudC5jbGlwR3JvdXAgPSBudWxsO1xuXG4gICAgICAgIGZvciAoY29uc3QgcHJldiBvZiB0aGlzLmV4dHJhU3RhY2spIHtcbiAgICAgICAgICBwcmV2LmNsaXBHcm91cCA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBjbGlwUGF0aC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImNsaXAtcGF0aFwiLCBjdXJyZW50LmFjdGl2ZUNsaXBVcmwpO1xuICAgICAgfVxuXG4gICAgICBjdXJyZW50LmFjdGl2ZUNsaXBVcmwgPSBgdXJsKCMke2NsaXBJZH0pYDtcbiAgICAgIHRoaXMudGdycCA9IG51bGw7XG4gICAgfVxuXG4gICAgY2xpcCh0eXBlKSB7XG4gICAgICB0aGlzLnBlbmRpbmdDbGlwID0gdHlwZTtcbiAgICB9XG5cbiAgICBjbG9zZVBhdGgoKSB7XG4gICAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5jdXJyZW50O1xuXG4gICAgICBpZiAoY3VycmVudC5wYXRoKSB7XG4gICAgICAgIGNvbnN0IGQgPSBgJHtjdXJyZW50LnBhdGguZ2V0QXR0cmlidXRlTlMobnVsbCwgXCJkXCIpfVpgO1xuICAgICAgICBjdXJyZW50LnBhdGguc2V0QXR0cmlidXRlTlMobnVsbCwgXCJkXCIsIGQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHNldExlYWRpbmcobGVhZGluZykge1xuICAgICAgdGhpcy5jdXJyZW50LmxlYWRpbmcgPSAtbGVhZGluZztcbiAgICB9XG5cbiAgICBzZXRUZXh0UmlzZSh0ZXh0UmlzZSkge1xuICAgICAgdGhpcy5jdXJyZW50LnRleHRSaXNlID0gdGV4dFJpc2U7XG4gICAgfVxuXG4gICAgc2V0VGV4dFJlbmRlcmluZ01vZGUodGV4dFJlbmRlcmluZ01vZGUpIHtcbiAgICAgIHRoaXMuY3VycmVudC50ZXh0UmVuZGVyaW5nTW9kZSA9IHRleHRSZW5kZXJpbmdNb2RlO1xuICAgIH1cblxuICAgIHNldEhTY2FsZShzY2FsZSkge1xuICAgICAgdGhpcy5jdXJyZW50LnRleHRIU2NhbGUgPSBzY2FsZSAvIDEwMDtcbiAgICB9XG5cbiAgICBzZXRSZW5kZXJpbmdJbnRlbnQoaW50ZW50KSB7fVxuXG4gICAgc2V0RmxhdG5lc3MoZmxhdG5lc3MpIHt9XG5cbiAgICBzZXRHU3RhdGUoc3RhdGVzKSB7XG4gICAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBzdGF0ZXMpIHtcbiAgICAgICAgc3dpdGNoIChrZXkpIHtcbiAgICAgICAgICBjYXNlIFwiTFdcIjpcbiAgICAgICAgICAgIHRoaXMuc2V0TGluZVdpZHRoKHZhbHVlKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBcIkxDXCI6XG4gICAgICAgICAgICB0aGlzLnNldExpbmVDYXAodmFsdWUpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFwiTEpcIjpcbiAgICAgICAgICAgIHRoaXMuc2V0TGluZUpvaW4odmFsdWUpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFwiTUxcIjpcbiAgICAgICAgICAgIHRoaXMuc2V0TWl0ZXJMaW1pdCh2YWx1ZSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgXCJEXCI6XG4gICAgICAgICAgICB0aGlzLnNldERhc2godmFsdWVbMF0sIHZhbHVlWzFdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBcIlJJXCI6XG4gICAgICAgICAgICB0aGlzLnNldFJlbmRlcmluZ0ludGVudCh2YWx1ZSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgXCJGTFwiOlxuICAgICAgICAgICAgdGhpcy5zZXRGbGF0bmVzcyh2YWx1ZSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgXCJGb250XCI6XG4gICAgICAgICAgICB0aGlzLnNldEZvbnQodmFsdWUpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFwiQ0FcIjpcbiAgICAgICAgICAgIHRoaXMuc2V0U3Ryb2tlQWxwaGEodmFsdWUpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFwiY2FcIjpcbiAgICAgICAgICAgIHRoaXMuc2V0RmlsbEFscGhhKHZhbHVlKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICgwLCBfdXRpbC53YXJuKShgVW5pbXBsZW1lbnRlZCBncmFwaGljIHN0YXRlIG9wZXJhdG9yICR7a2V5fWApO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBmaWxsKCkge1xuICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcblxuICAgICAgaWYgKGN1cnJlbnQuZWxlbWVudCkge1xuICAgICAgICBjdXJyZW50LmVsZW1lbnQuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJmaWxsXCIsIGN1cnJlbnQuZmlsbENvbG9yKTtcbiAgICAgICAgY3VycmVudC5lbGVtZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZmlsbC1vcGFjaXR5XCIsIGN1cnJlbnQuZmlsbEFscGhhKTtcbiAgICAgICAgdGhpcy5lbmRQYXRoKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgc3Ryb2tlKCkge1xuICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcblxuICAgICAgaWYgKGN1cnJlbnQuZWxlbWVudCkge1xuICAgICAgICB0aGlzLl9zZXRTdHJva2VBdHRyaWJ1dGVzKGN1cnJlbnQuZWxlbWVudCk7XG5cbiAgICAgICAgY3VycmVudC5lbGVtZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZmlsbFwiLCBcIm5vbmVcIik7XG4gICAgICAgIHRoaXMuZW5kUGF0aCgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIF9zZXRTdHJva2VBdHRyaWJ1dGVzKGVsZW1lbnQsIGxpbmVXaWR0aFNjYWxlID0gMSkge1xuICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcbiAgICAgIGxldCBkYXNoQXJyYXkgPSBjdXJyZW50LmRhc2hBcnJheTtcblxuICAgICAgaWYgKGxpbmVXaWR0aFNjYWxlICE9PSAxICYmIGRhc2hBcnJheS5sZW5ndGggPiAwKSB7XG4gICAgICAgIGRhc2hBcnJheSA9IGRhc2hBcnJheS5tYXAoZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgcmV0dXJuIGxpbmVXaWR0aFNjYWxlICogdmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwic3Ryb2tlXCIsIGN1cnJlbnQuc3Ryb2tlQ29sb3IpO1xuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInN0cm9rZS1vcGFjaXR5XCIsIGN1cnJlbnQuc3Ryb2tlQWxwaGEpO1xuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInN0cm9rZS1taXRlcmxpbWl0XCIsIHBmKGN1cnJlbnQubWl0ZXJMaW1pdCkpO1xuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInN0cm9rZS1saW5lY2FwXCIsIGN1cnJlbnQubGluZUNhcCk7XG4gICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwic3Ryb2tlLWxpbmVqb2luXCIsIGN1cnJlbnQubGluZUpvaW4pO1xuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInN0cm9rZS13aWR0aFwiLCBwZihsaW5lV2lkdGhTY2FsZSAqIGN1cnJlbnQubGluZVdpZHRoKSArIFwicHhcIik7XG4gICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwic3Ryb2tlLWRhc2hhcnJheVwiLCBkYXNoQXJyYXkubWFwKHBmKS5qb2luKFwiIFwiKSk7XG4gICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwic3Ryb2tlLWRhc2hvZmZzZXRcIiwgcGYobGluZVdpZHRoU2NhbGUgKiBjdXJyZW50LmRhc2hQaGFzZSkgKyBcInB4XCIpO1xuICAgIH1cblxuICAgIGVvRmlsbCgpIHtcbiAgICAgIGlmICh0aGlzLmN1cnJlbnQuZWxlbWVudCkge1xuICAgICAgICB0aGlzLmN1cnJlbnQuZWxlbWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImZpbGwtcnVsZVwiLCBcImV2ZW5vZGRcIik7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuZmlsbCgpO1xuICAgIH1cblxuICAgIGZpbGxTdHJva2UoKSB7XG4gICAgICB0aGlzLnN0cm9rZSgpO1xuICAgICAgdGhpcy5maWxsKCk7XG4gICAgfVxuXG4gICAgZW9GaWxsU3Ryb2tlKCkge1xuICAgICAgaWYgKHRoaXMuY3VycmVudC5lbGVtZW50KSB7XG4gICAgICAgIHRoaXMuY3VycmVudC5lbGVtZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZmlsbC1ydWxlXCIsIFwiZXZlbm9kZFwiKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5maWxsU3Ryb2tlKCk7XG4gICAgfVxuXG4gICAgY2xvc2VTdHJva2UoKSB7XG4gICAgICB0aGlzLmNsb3NlUGF0aCgpO1xuICAgICAgdGhpcy5zdHJva2UoKTtcbiAgICB9XG5cbiAgICBjbG9zZUZpbGxTdHJva2UoKSB7XG4gICAgICB0aGlzLmNsb3NlUGF0aCgpO1xuICAgICAgdGhpcy5maWxsU3Ryb2tlKCk7XG4gICAgfVxuXG4gICAgY2xvc2VFT0ZpbGxTdHJva2UoKSB7XG4gICAgICB0aGlzLmNsb3NlUGF0aCgpO1xuICAgICAgdGhpcy5lb0ZpbGxTdHJva2UoKTtcbiAgICB9XG5cbiAgICBwYWludFNvbGlkQ29sb3JJbWFnZU1hc2soKSB7XG4gICAgICBjb25zdCByZWN0ID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZUVsZW1lbnQoXCJzdmc6cmVjdFwiKTtcbiAgICAgIHJlY3Quc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ4XCIsIFwiMFwiKTtcbiAgICAgIHJlY3Quc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ5XCIsIFwiMFwiKTtcbiAgICAgIHJlY3Quc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ3aWR0aFwiLCBcIjFweFwiKTtcbiAgICAgIHJlY3Quc2V0QXR0cmlidXRlTlMobnVsbCwgXCJoZWlnaHRcIiwgXCIxcHhcIik7XG4gICAgICByZWN0LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZmlsbFwiLCB0aGlzLmN1cnJlbnQuZmlsbENvbG9yKTtcblxuICAgICAgdGhpcy5fZW5zdXJlVHJhbnNmb3JtR3JvdXAoKS5hcHBlbmRDaGlsZChyZWN0KTtcbiAgICB9XG5cbiAgICBwYWludEltYWdlWE9iamVjdChvYmpJZCkge1xuICAgICAgY29uc3QgaW1nRGF0YSA9IG9iaklkLnN0YXJ0c1dpdGgoXCJnX1wiKSA/IHRoaXMuY29tbW9uT2Jqcy5nZXQob2JqSWQpIDogdGhpcy5vYmpzLmdldChvYmpJZCk7XG5cbiAgICAgIGlmICghaW1nRGF0YSkge1xuICAgICAgICAoMCwgX3V0aWwud2FybikoYERlcGVuZGVudCBpbWFnZSB3aXRoIG9iamVjdCBJRCAke29iaklkfSBpcyBub3QgcmVhZHkgeWV0YCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5wYWludElubGluZUltYWdlWE9iamVjdChpbWdEYXRhKTtcbiAgICB9XG5cbiAgICBwYWludElubGluZUltYWdlWE9iamVjdChpbWdEYXRhLCBtYXNrKSB7XG4gICAgICBjb25zdCB3aWR0aCA9IGltZ0RhdGEud2lkdGg7XG4gICAgICBjb25zdCBoZWlnaHQgPSBpbWdEYXRhLmhlaWdodDtcbiAgICAgIGNvbnN0IGltZ1NyYyA9IGNvbnZlcnRJbWdEYXRhVG9QbmcoaW1nRGF0YSwgdGhpcy5mb3JjZURhdGFTY2hlbWEsICEhbWFzayk7XG4gICAgICBjb25zdCBjbGlwcmVjdCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOnJlY3RcIik7XG4gICAgICBjbGlwcmVjdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInhcIiwgXCIwXCIpO1xuICAgICAgY2xpcHJlY3Quc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ5XCIsIFwiMFwiKTtcbiAgICAgIGNsaXByZWN0LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwid2lkdGhcIiwgcGYod2lkdGgpKTtcbiAgICAgIGNsaXByZWN0LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiaGVpZ2h0XCIsIHBmKGhlaWdodCkpO1xuICAgICAgdGhpcy5jdXJyZW50LmVsZW1lbnQgPSBjbGlwcmVjdDtcbiAgICAgIHRoaXMuY2xpcChcIm5vbnplcm9cIik7XG4gICAgICBjb25zdCBpbWdFbCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOmltYWdlXCIpO1xuICAgICAgaW1nRWwuc2V0QXR0cmlidXRlTlMoWExJTktfTlMsIFwieGxpbms6aHJlZlwiLCBpbWdTcmMpO1xuICAgICAgaW1nRWwuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ4XCIsIFwiMFwiKTtcbiAgICAgIGltZ0VsLnNldEF0dHJpYnV0ZU5TKG51bGwsIFwieVwiLCBwZigtaGVpZ2h0KSk7XG4gICAgICBpbWdFbC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcIndpZHRoXCIsIHBmKHdpZHRoKSArIFwicHhcIik7XG4gICAgICBpbWdFbC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImhlaWdodFwiLCBwZihoZWlnaHQpICsgXCJweFwiKTtcbiAgICAgIGltZ0VsLnNldEF0dHJpYnV0ZU5TKG51bGwsIFwidHJhbnNmb3JtXCIsIGBzY2FsZSgke3BmKDEgLyB3aWR0aCl9ICR7cGYoLTEgLyBoZWlnaHQpfSlgKTtcblxuICAgICAgaWYgKG1hc2spIHtcbiAgICAgICAgbWFzay5hcHBlbmRDaGlsZChpbWdFbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9lbnN1cmVUcmFuc2Zvcm1Hcm91cCgpLmFwcGVuZENoaWxkKGltZ0VsKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwYWludEltYWdlTWFza1hPYmplY3QoaW1nRGF0YSkge1xuICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcbiAgICAgIGNvbnN0IHdpZHRoID0gaW1nRGF0YS53aWR0aDtcbiAgICAgIGNvbnN0IGhlaWdodCA9IGltZ0RhdGEuaGVpZ2h0O1xuICAgICAgY29uc3QgZmlsbENvbG9yID0gY3VycmVudC5maWxsQ29sb3I7XG4gICAgICBjdXJyZW50Lm1hc2tJZCA9IGBtYXNrJHttYXNrQ291bnQrK31gO1xuICAgICAgY29uc3QgbWFzayA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOm1hc2tcIik7XG4gICAgICBtYXNrLnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiaWRcIiwgY3VycmVudC5tYXNrSWQpO1xuICAgICAgY29uc3QgcmVjdCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOnJlY3RcIik7XG4gICAgICByZWN0LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwieFwiLCBcIjBcIik7XG4gICAgICByZWN0LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwieVwiLCBcIjBcIik7XG4gICAgICByZWN0LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwid2lkdGhcIiwgcGYod2lkdGgpKTtcbiAgICAgIHJlY3Quc2V0QXR0cmlidXRlTlMobnVsbCwgXCJoZWlnaHRcIiwgcGYoaGVpZ2h0KSk7XG4gICAgICByZWN0LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZmlsbFwiLCBmaWxsQ29sb3IpO1xuICAgICAgcmVjdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcIm1hc2tcIiwgYHVybCgjJHtjdXJyZW50Lm1hc2tJZH0pYCk7XG4gICAgICB0aGlzLmRlZnMuYXBwZW5kQ2hpbGQobWFzayk7XG5cbiAgICAgIHRoaXMuX2Vuc3VyZVRyYW5zZm9ybUdyb3VwKCkuYXBwZW5kQ2hpbGQocmVjdCk7XG5cbiAgICAgIHRoaXMucGFpbnRJbmxpbmVJbWFnZVhPYmplY3QoaW1nRGF0YSwgbWFzayk7XG4gICAgfVxuXG4gICAgcGFpbnRGb3JtWE9iamVjdEJlZ2luKG1hdHJpeCwgYmJveCkge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkobWF0cml4KSAmJiBtYXRyaXgubGVuZ3RoID09PSA2KSB7XG4gICAgICAgIHRoaXMudHJhbnNmb3JtKG1hdHJpeFswXSwgbWF0cml4WzFdLCBtYXRyaXhbMl0sIG1hdHJpeFszXSwgbWF0cml4WzRdLCBtYXRyaXhbNV0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoYmJveCkge1xuICAgICAgICBjb25zdCB3aWR0aCA9IGJib3hbMl0gLSBiYm94WzBdO1xuICAgICAgICBjb25zdCBoZWlnaHQgPSBiYm94WzNdIC0gYmJveFsxXTtcbiAgICAgICAgY29uc3QgY2xpcHJlY3QgPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlRWxlbWVudChcInN2ZzpyZWN0XCIpO1xuICAgICAgICBjbGlwcmVjdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInhcIiwgYmJveFswXSk7XG4gICAgICAgIGNsaXByZWN0LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwieVwiLCBiYm94WzFdKTtcbiAgICAgICAgY2xpcHJlY3Quc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ3aWR0aFwiLCBwZih3aWR0aCkpO1xuICAgICAgICBjbGlwcmVjdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImhlaWdodFwiLCBwZihoZWlnaHQpKTtcbiAgICAgICAgdGhpcy5jdXJyZW50LmVsZW1lbnQgPSBjbGlwcmVjdDtcbiAgICAgICAgdGhpcy5jbGlwKFwibm9uemVyb1wiKTtcbiAgICAgICAgdGhpcy5lbmRQYXRoKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcGFpbnRGb3JtWE9iamVjdEVuZCgpIHt9XG5cbiAgICBfaW5pdGlhbGl6ZSh2aWV3cG9ydCkge1xuICAgICAgY29uc3Qgc3ZnID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZSh2aWV3cG9ydC53aWR0aCwgdmlld3BvcnQuaGVpZ2h0KTtcbiAgICAgIGNvbnN0IGRlZmluaXRpb25zID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZUVsZW1lbnQoXCJzdmc6ZGVmc1wiKTtcbiAgICAgIHN2Zy5hcHBlbmRDaGlsZChkZWZpbml0aW9ucyk7XG4gICAgICB0aGlzLmRlZnMgPSBkZWZpbml0aW9ucztcbiAgICAgIGNvbnN0IHJvb3RHcm91cCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOmdcIik7XG4gICAgICByb290R3JvdXAuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ0cmFuc2Zvcm1cIiwgcG0odmlld3BvcnQudHJhbnNmb3JtKSk7XG4gICAgICBzdmcuYXBwZW5kQ2hpbGQocm9vdEdyb3VwKTtcbiAgICAgIHRoaXMuc3ZnID0gcm9vdEdyb3VwO1xuICAgICAgcmV0dXJuIHN2ZztcbiAgICB9XG5cbiAgICBfZW5zdXJlQ2xpcEdyb3VwKCkge1xuICAgICAgaWYgKCF0aGlzLmN1cnJlbnQuY2xpcEdyb3VwKSB7XG4gICAgICAgIGNvbnN0IGNsaXBHcm91cCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOmdcIik7XG4gICAgICAgIGNsaXBHcm91cC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImNsaXAtcGF0aFwiLCB0aGlzLmN1cnJlbnQuYWN0aXZlQ2xpcFVybCk7XG4gICAgICAgIHRoaXMuc3ZnLmFwcGVuZENoaWxkKGNsaXBHcm91cCk7XG4gICAgICAgIHRoaXMuY3VycmVudC5jbGlwR3JvdXAgPSBjbGlwR3JvdXA7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLmN1cnJlbnQuY2xpcEdyb3VwO1xuICAgIH1cblxuICAgIF9lbnN1cmVUcmFuc2Zvcm1Hcm91cCgpIHtcbiAgICAgIGlmICghdGhpcy50Z3JwKSB7XG4gICAgICAgIHRoaXMudGdycCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOmdcIik7XG4gICAgICAgIHRoaXMudGdycC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInRyYW5zZm9ybVwiLCBwbSh0aGlzLnRyYW5zZm9ybU1hdHJpeCkpO1xuXG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnQuYWN0aXZlQ2xpcFVybCkge1xuICAgICAgICAgIHRoaXMuX2Vuc3VyZUNsaXBHcm91cCgpLmFwcGVuZENoaWxkKHRoaXMudGdycCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zdmcuYXBwZW5kQ2hpbGQodGhpcy50Z3JwKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy50Z3JwO1xuICAgIH1cblxuICB9O1xufVxuXG4vKioqLyB9KSxcbi8qIDI1ICovXG4vKioqLyAoKF9fdW51c2VkX3dlYnBhY2tfbW9kdWxlLCBleHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5leHBvcnRzLlBERk5vZGVTdHJlYW0gPSB2b2lkIDA7XG5cbnZhciBfdXRpbCA9IF9fd19wZGZqc19yZXF1aXJlX18oMSk7XG5cbnZhciBfbmV0d29ya191dGlscyA9IF9fd19wZGZqc19yZXF1aXJlX18oMjYpO1xuXG47XG5cbmNvbnN0IGZzID0gcmVxdWlyZShcImZzXCIpO1xuXG5jb25zdCBodHRwID0gcmVxdWlyZShcImh0dHBcIik7XG5cbmNvbnN0IGh0dHBzID0gcmVxdWlyZShcImh0dHBzXCIpO1xuXG5jb25zdCB1cmwgPSByZXF1aXJlKFwidXJsXCIpO1xuXG5jb25zdCBmaWxlVXJpUmVnZXggPSAvXmZpbGU6XFwvXFwvXFwvW2EtekEtWl06XFwvLztcblxuZnVuY3Rpb24gcGFyc2VVcmwoc291cmNlVXJsKSB7XG4gIGNvbnN0IHBhcnNlZFVybCA9IHVybC5wYXJzZShzb3VyY2VVcmwpO1xuXG4gIGlmIChwYXJzZWRVcmwucHJvdG9jb2wgPT09IFwiZmlsZTpcIiB8fCBwYXJzZWRVcmwuaG9zdCkge1xuICAgIHJldHVybiBwYXJzZWRVcmw7XG4gIH1cblxuICBpZiAoL15bYS16XTpbL1xcXFxdL2kudGVzdChzb3VyY2VVcmwpKSB7XG4gICAgcmV0dXJuIHVybC5wYXJzZShgZmlsZTovLy8ke3NvdXJjZVVybH1gKTtcbiAgfVxuXG4gIGlmICghcGFyc2VkVXJsLmhvc3QpIHtcbiAgICBwYXJzZWRVcmwucHJvdG9jb2wgPSBcImZpbGU6XCI7XG4gIH1cblxuICByZXR1cm4gcGFyc2VkVXJsO1xufVxuXG5jbGFzcyBQREZOb2RlU3RyZWFtIHtcbiAgY29uc3RydWN0b3Ioc291cmNlKSB7XG4gICAgdGhpcy5zb3VyY2UgPSBzb3VyY2U7XG4gICAgdGhpcy51cmwgPSBwYXJzZVVybChzb3VyY2UudXJsKTtcbiAgICB0aGlzLmlzSHR0cCA9IHRoaXMudXJsLnByb3RvY29sID09PSBcImh0dHA6XCIgfHwgdGhpcy51cmwucHJvdG9jb2wgPT09IFwiaHR0cHM6XCI7XG4gICAgdGhpcy5pc0ZzVXJsID0gdGhpcy51cmwucHJvdG9jb2wgPT09IFwiZmlsZTpcIjtcbiAgICB0aGlzLmh0dHBIZWFkZXJzID0gdGhpcy5pc0h0dHAgJiYgc291cmNlLmh0dHBIZWFkZXJzIHx8IHt9O1xuICAgIHRoaXMuX2Z1bGxSZXF1ZXN0UmVhZGVyID0gbnVsbDtcbiAgICB0aGlzLl9yYW5nZVJlcXVlc3RSZWFkZXJzID0gW107XG4gIH1cblxuICBnZXQgX3Byb2dyZXNzaXZlRGF0YUxlbmd0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZnVsbFJlcXVlc3RSZWFkZXI/Ll9sb2FkZWQgPz8gMDtcbiAgfVxuXG4gIGdldEZ1bGxSZWFkZXIoKSB7XG4gICAgKDAsIF91dGlsLmFzc2VydCkoIXRoaXMuX2Z1bGxSZXF1ZXN0UmVhZGVyLCBcIlBERk5vZGVTdHJlYW0uZ2V0RnVsbFJlYWRlciBjYW4gb25seSBiZSBjYWxsZWQgb25jZS5cIik7XG4gICAgdGhpcy5fZnVsbFJlcXVlc3RSZWFkZXIgPSB0aGlzLmlzRnNVcmwgPyBuZXcgUERGTm9kZVN0cmVhbUZzRnVsbFJlYWRlcih0aGlzKSA6IG5ldyBQREZOb2RlU3RyZWFtRnVsbFJlYWRlcih0aGlzKTtcbiAgICByZXR1cm4gdGhpcy5fZnVsbFJlcXVlc3RSZWFkZXI7XG4gIH1cblxuICBnZXRSYW5nZVJlYWRlcihzdGFydCwgZW5kKSB7XG4gICAgaWYgKGVuZCA8PSB0aGlzLl9wcm9ncmVzc2l2ZURhdGFMZW5ndGgpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHJhbmdlUmVhZGVyID0gdGhpcy5pc0ZzVXJsID8gbmV3IFBERk5vZGVTdHJlYW1Gc1JhbmdlUmVhZGVyKHRoaXMsIHN0YXJ0LCBlbmQpIDogbmV3IFBERk5vZGVTdHJlYW1SYW5nZVJlYWRlcih0aGlzLCBzdGFydCwgZW5kKTtcblxuICAgIHRoaXMuX3JhbmdlUmVxdWVzdFJlYWRlcnMucHVzaChyYW5nZVJlYWRlcik7XG5cbiAgICByZXR1cm4gcmFuZ2VSZWFkZXI7XG4gIH1cblxuICBjYW5jZWxBbGxSZXF1ZXN0cyhyZWFzb24pIHtcbiAgICBpZiAodGhpcy5fZnVsbFJlcXVlc3RSZWFkZXIpIHtcbiAgICAgIHRoaXMuX2Z1bGxSZXF1ZXN0UmVhZGVyLmNhbmNlbChyZWFzb24pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcmVhZGVyIG9mIHRoaXMuX3JhbmdlUmVxdWVzdFJlYWRlcnMuc2xpY2UoMCkpIHtcbiAgICAgIHJlYWRlci5jYW5jZWwocmVhc29uKTtcbiAgICB9XG4gIH1cblxufVxuXG5leHBvcnRzLlBERk5vZGVTdHJlYW0gPSBQREZOb2RlU3RyZWFtO1xuXG5jbGFzcyBCYXNlRnVsbFJlYWRlciB7XG4gIGNvbnN0cnVjdG9yKHN0cmVhbSkge1xuICAgIHRoaXMuX3VybCA9IHN0cmVhbS51cmw7XG4gICAgdGhpcy5fZG9uZSA9IGZhbHNlO1xuICAgIHRoaXMuX3N0b3JlZEVycm9yID0gbnVsbDtcbiAgICB0aGlzLm9uUHJvZ3Jlc3MgPSBudWxsO1xuICAgIGNvbnN0IHNvdXJjZSA9IHN0cmVhbS5zb3VyY2U7XG4gICAgdGhpcy5fY29udGVudExlbmd0aCA9IHNvdXJjZS5sZW5ndGg7XG4gICAgdGhpcy5fbG9hZGVkID0gMDtcbiAgICB0aGlzLl9maWxlbmFtZSA9IG51bGw7XG4gICAgdGhpcy5fZGlzYWJsZVJhbmdlID0gc291cmNlLmRpc2FibGVSYW5nZSB8fCBmYWxzZTtcbiAgICB0aGlzLl9yYW5nZUNodW5rU2l6ZSA9IHNvdXJjZS5yYW5nZUNodW5rU2l6ZTtcblxuICAgIGlmICghdGhpcy5fcmFuZ2VDaHVua1NpemUgJiYgIXRoaXMuX2Rpc2FibGVSYW5nZSkge1xuICAgICAgdGhpcy5fZGlzYWJsZVJhbmdlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB0aGlzLl9pc1N0cmVhbWluZ1N1cHBvcnRlZCA9ICFzb3VyY2UuZGlzYWJsZVN0cmVhbTtcbiAgICB0aGlzLl9pc1JhbmdlU3VwcG9ydGVkID0gIXNvdXJjZS5kaXNhYmxlUmFuZ2U7XG4gICAgdGhpcy5fcmVhZGFibGVTdHJlYW0gPSBudWxsO1xuICAgIHRoaXMuX3JlYWRDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgIHRoaXMuX2hlYWRlcnNDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICB9XG5cbiAgZ2V0IGhlYWRlcnNSZWFkeSgpIHtcbiAgICByZXR1cm4gdGhpcy5faGVhZGVyc0NhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxuXG4gIGdldCBmaWxlbmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fZmlsZW5hbWU7XG4gIH1cblxuICBnZXQgY29udGVudExlbmd0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5fY29udGVudExlbmd0aDtcbiAgfVxuXG4gIGdldCBpc1JhbmdlU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9pc1JhbmdlU3VwcG9ydGVkO1xuICB9XG5cbiAgZ2V0IGlzU3RyZWFtaW5nU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9pc1N0cmVhbWluZ1N1cHBvcnRlZDtcbiAgfVxuXG4gIGFzeW5jIHJlYWQoKSB7XG4gICAgYXdhaXQgdGhpcy5fcmVhZENhcGFiaWxpdHkucHJvbWlzZTtcblxuICAgIGlmICh0aGlzLl9kb25lKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWx1ZTogdW5kZWZpbmVkLFxuICAgICAgICBkb25lOiB0cnVlXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9zdG9yZWRFcnJvcikge1xuICAgICAgdGhyb3cgdGhpcy5fc3RvcmVkRXJyb3I7XG4gICAgfVxuXG4gICAgY29uc3QgY2h1bmsgPSB0aGlzLl9yZWFkYWJsZVN0cmVhbS5yZWFkKCk7XG5cbiAgICBpZiAoY2h1bmsgPT09IG51bGwpIHtcbiAgICAgIHRoaXMuX3JlYWRDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgICAgcmV0dXJuIHRoaXMucmVhZCgpO1xuICAgIH1cblxuICAgIHRoaXMuX2xvYWRlZCArPSBjaHVuay5sZW5ndGg7XG5cbiAgICBpZiAodGhpcy5vblByb2dyZXNzKSB7XG4gICAgICB0aGlzLm9uUHJvZ3Jlc3Moe1xuICAgICAgICBsb2FkZWQ6IHRoaXMuX2xvYWRlZCxcbiAgICAgICAgdG90YWw6IHRoaXMuX2NvbnRlbnRMZW5ndGhcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KGNodW5rKS5idWZmZXI7XG4gICAgcmV0dXJuIHtcbiAgICAgIHZhbHVlOiBidWZmZXIsXG4gICAgICBkb25lOiBmYWxzZVxuICAgIH07XG4gIH1cblxuICBjYW5jZWwocmVhc29uKSB7XG4gICAgaWYgKCF0aGlzLl9yZWFkYWJsZVN0cmVhbSkge1xuICAgICAgdGhpcy5fZXJyb3IocmVhc29uKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX3JlYWRhYmxlU3RyZWFtLmRlc3Ryb3kocmVhc29uKTtcbiAgfVxuXG4gIF9lcnJvcihyZWFzb24pIHtcbiAgICB0aGlzLl9zdG9yZWRFcnJvciA9IHJlYXNvbjtcblxuICAgIHRoaXMuX3JlYWRDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgfVxuXG4gIF9zZXRSZWFkYWJsZVN0cmVhbShyZWFkYWJsZVN0cmVhbSkge1xuICAgIHRoaXMuX3JlYWRhYmxlU3RyZWFtID0gcmVhZGFibGVTdHJlYW07XG4gICAgcmVhZGFibGVTdHJlYW0ub24oXCJyZWFkYWJsZVwiLCAoKSA9PiB7XG4gICAgICB0aGlzLl9yZWFkQ2FwYWJpbGl0eS5yZXNvbHZlKCk7XG4gICAgfSk7XG4gICAgcmVhZGFibGVTdHJlYW0ub24oXCJlbmRcIiwgKCkgPT4ge1xuICAgICAgcmVhZGFibGVTdHJlYW0uZGVzdHJveSgpO1xuICAgICAgdGhpcy5fZG9uZSA9IHRydWU7XG5cbiAgICAgIHRoaXMuX3JlYWRDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgICB9KTtcbiAgICByZWFkYWJsZVN0cmVhbS5vbihcImVycm9yXCIsIHJlYXNvbiA9PiB7XG4gICAgICB0aGlzLl9lcnJvcihyZWFzb24pO1xuICAgIH0pO1xuXG4gICAgaWYgKCF0aGlzLl9pc1N0cmVhbWluZ1N1cHBvcnRlZCAmJiB0aGlzLl9pc1JhbmdlU3VwcG9ydGVkKSB7XG4gICAgICB0aGlzLl9lcnJvcihuZXcgX3V0aWwuQWJvcnRFeGNlcHRpb24oXCJzdHJlYW1pbmcgaXMgZGlzYWJsZWRcIikpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9zdG9yZWRFcnJvcikge1xuICAgICAgdGhpcy5fcmVhZGFibGVTdHJlYW0uZGVzdHJveSh0aGlzLl9zdG9yZWRFcnJvcik7XG4gICAgfVxuICB9XG5cbn1cblxuY2xhc3MgQmFzZVJhbmdlUmVhZGVyIHtcbiAgY29uc3RydWN0b3Ioc3RyZWFtKSB7XG4gICAgdGhpcy5fdXJsID0gc3RyZWFtLnVybDtcbiAgICB0aGlzLl9kb25lID0gZmFsc2U7XG4gICAgdGhpcy5fc3RvcmVkRXJyb3IgPSBudWxsO1xuICAgIHRoaXMub25Qcm9ncmVzcyA9IG51bGw7XG4gICAgdGhpcy5fbG9hZGVkID0gMDtcbiAgICB0aGlzLl9yZWFkYWJsZVN0cmVhbSA9IG51bGw7XG4gICAgdGhpcy5fcmVhZENhcGFiaWxpdHkgPSAoMCwgX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkpKCk7XG4gICAgY29uc3Qgc291cmNlID0gc3RyZWFtLnNvdXJjZTtcbiAgICB0aGlzLl9pc1N0cmVhbWluZ1N1cHBvcnRlZCA9ICFzb3VyY2UuZGlzYWJsZVN0cmVhbTtcbiAgfVxuXG4gIGdldCBpc1N0cmVhbWluZ1N1cHBvcnRlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5faXNTdHJlYW1pbmdTdXBwb3J0ZWQ7XG4gIH1cblxuICBhc3luYyByZWFkKCkge1xuICAgIGF3YWl0IHRoaXMuX3JlYWRDYXBhYmlsaXR5LnByb21pc2U7XG5cbiAgICBpZiAodGhpcy5fZG9uZSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgICAgZG9uZTogdHJ1ZVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fc3RvcmVkRXJyb3IpIHtcbiAgICAgIHRocm93IHRoaXMuX3N0b3JlZEVycm9yO1xuICAgIH1cblxuICAgIGNvbnN0IGNodW5rID0gdGhpcy5fcmVhZGFibGVTdHJlYW0ucmVhZCgpO1xuXG4gICAgaWYgKGNodW5rID09PSBudWxsKSB7XG4gICAgICB0aGlzLl9yZWFkQ2FwYWJpbGl0eSA9ICgwLCBfdXRpbC5jcmVhdGVQcm9taXNlQ2FwYWJpbGl0eSkoKTtcbiAgICAgIHJldHVybiB0aGlzLnJlYWQoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2FkZWQgKz0gY2h1bmsubGVuZ3RoO1xuXG4gICAgaWYgKHRoaXMub25Qcm9ncmVzcykge1xuICAgICAgdGhpcy5vblByb2dyZXNzKHtcbiAgICAgICAgbG9hZGVkOiB0aGlzLl9sb2FkZWRcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KGNodW5rKS5idWZmZXI7XG4gICAgcmV0dXJuIHtcbiAgICAgIHZhbHVlOiBidWZmZXIsXG4gICAgICBkb25lOiBmYWxzZVxuICAgIH07XG4gIH1cblxuICBjYW5jZWwocmVhc29uKSB7XG4gICAgaWYgKCF0aGlzLl9yZWFkYWJsZVN0cmVhbSkge1xuICAgICAgdGhpcy5fZXJyb3IocmVhc29uKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX3JlYWRhYmxlU3RyZWFtLmRlc3Ryb3kocmVhc29uKTtcbiAgfVxuXG4gIF9lcnJvcihyZWFzb24pIHtcbiAgICB0aGlzLl9zdG9yZWRFcnJvciA9IHJlYXNvbjtcblxuICAgIHRoaXMuX3JlYWRDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgfVxuXG4gIF9zZXRSZWFkYWJsZVN0cmVhbShyZWFkYWJsZVN0cmVhbSkge1xuICAgIHRoaXMuX3JlYWRhYmxlU3RyZWFtID0gcmVhZGFibGVTdHJlYW07XG4gICAgcmVhZGFibGVTdHJlYW0ub24oXCJyZWFkYWJsZVwiLCAoKSA9PiB7XG4gICAgICB0aGlzLl9yZWFkQ2FwYWJpbGl0eS5yZXNvbHZlKCk7XG4gICAgfSk7XG4gICAgcmVhZGFibGVTdHJlYW0ub24oXCJlbmRcIiwgKCkgPT4ge1xuICAgICAgcmVhZGFibGVTdHJlYW0uZGVzdHJveSgpO1xuICAgICAgdGhpcy5fZG9uZSA9IHRydWU7XG5cbiAgICAgIHRoaXMuX3JlYWRDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgICB9KTtcbiAgICByZWFkYWJsZVN0cmVhbS5vbihcImVycm9yXCIsIHJlYXNvbiA9PiB7XG4gICAgICB0aGlzLl9lcnJvcihyZWFzb24pO1xuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMuX3N0b3JlZEVycm9yKSB7XG4gICAgICB0aGlzLl9yZWFkYWJsZVN0cmVhbS5kZXN0cm95KHRoaXMuX3N0b3JlZEVycm9yKTtcbiAgICB9XG4gIH1cblxufVxuXG5mdW5jdGlvbiBjcmVhdGVSZXF1ZXN0T3B0aW9ucyhwYXJzZWRVcmwsIGhlYWRlcnMpIHtcbiAgcmV0dXJuIHtcbiAgICBwcm90b2NvbDogcGFyc2VkVXJsLnByb3RvY29sLFxuICAgIGF1dGg6IHBhcnNlZFVybC5hdXRoLFxuICAgIGhvc3Q6IHBhcnNlZFVybC5ob3N0bmFtZSxcbiAgICBwb3J0OiBwYXJzZWRVcmwucG9ydCxcbiAgICBwYXRoOiBwYXJzZWRVcmwucGF0aCxcbiAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgaGVhZGVyc1xuICB9O1xufVxuXG5jbGFzcyBQREZOb2RlU3RyZWFtRnVsbFJlYWRlciBleHRlbmRzIEJhc2VGdWxsUmVhZGVyIHtcbiAgY29uc3RydWN0b3Ioc3RyZWFtKSB7XG4gICAgc3VwZXIoc3RyZWFtKTtcblxuICAgIGNvbnN0IGhhbmRsZVJlc3BvbnNlID0gcmVzcG9uc2UgPT4ge1xuICAgICAgaWYgKHJlc3BvbnNlLnN0YXR1c0NvZGUgPT09IDQwNCkge1xuICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBfdXRpbC5NaXNzaW5nUERGRXhjZXB0aW9uKGBNaXNzaW5nIFBERiBcIiR7dGhpcy5fdXJsfVwiLmApO1xuICAgICAgICB0aGlzLl9zdG9yZWRFcnJvciA9IGVycm9yO1xuXG4gICAgICAgIHRoaXMuX2hlYWRlcnNDYXBhYmlsaXR5LnJlamVjdChlcnJvcik7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9oZWFkZXJzQ2FwYWJpbGl0eS5yZXNvbHZlKCk7XG5cbiAgICAgIHRoaXMuX3NldFJlYWRhYmxlU3RyZWFtKHJlc3BvbnNlKTtcblxuICAgICAgY29uc3QgZ2V0UmVzcG9uc2VIZWFkZXIgPSBuYW1lID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlYWRhYmxlU3RyZWFtLmhlYWRlcnNbbmFtZS50b0xvd2VyQ2FzZSgpXTtcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHtcbiAgICAgICAgYWxsb3dSYW5nZVJlcXVlc3RzLFxuICAgICAgICBzdWdnZXN0ZWRMZW5ndGhcbiAgICAgIH0gPSAoMCwgX25ldHdvcmtfdXRpbHMudmFsaWRhdGVSYW5nZVJlcXVlc3RDYXBhYmlsaXRpZXMpKHtcbiAgICAgICAgZ2V0UmVzcG9uc2VIZWFkZXIsXG4gICAgICAgIGlzSHR0cDogc3RyZWFtLmlzSHR0cCxcbiAgICAgICAgcmFuZ2VDaHVua1NpemU6IHRoaXMuX3JhbmdlQ2h1bmtTaXplLFxuICAgICAgICBkaXNhYmxlUmFuZ2U6IHRoaXMuX2Rpc2FibGVSYW5nZVxuICAgICAgfSk7XG4gICAgICB0aGlzLl9pc1JhbmdlU3VwcG9ydGVkID0gYWxsb3dSYW5nZVJlcXVlc3RzO1xuICAgICAgdGhpcy5fY29udGVudExlbmd0aCA9IHN1Z2dlc3RlZExlbmd0aCB8fCB0aGlzLl9jb250ZW50TGVuZ3RoO1xuICAgICAgdGhpcy5fZmlsZW5hbWUgPSAoMCwgX25ldHdvcmtfdXRpbHMuZXh0cmFjdEZpbGVuYW1lRnJvbUhlYWRlcikoZ2V0UmVzcG9uc2VIZWFkZXIpO1xuICAgIH07XG5cbiAgICB0aGlzLl9yZXF1ZXN0ID0gbnVsbDtcblxuICAgIGlmICh0aGlzLl91cmwucHJvdG9jb2wgPT09IFwiaHR0cDpcIikge1xuICAgICAgdGhpcy5fcmVxdWVzdCA9IGh0dHAucmVxdWVzdChjcmVhdGVSZXF1ZXN0T3B0aW9ucyh0aGlzLl91cmwsIHN0cmVhbS5odHRwSGVhZGVycyksIGhhbmRsZVJlc3BvbnNlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fcmVxdWVzdCA9IGh0dHBzLnJlcXVlc3QoY3JlYXRlUmVxdWVzdE9wdGlvbnModGhpcy5fdXJsLCBzdHJlYW0uaHR0cEhlYWRlcnMpLCBoYW5kbGVSZXNwb25zZSk7XG4gICAgfVxuXG4gICAgdGhpcy5fcmVxdWVzdC5vbihcImVycm9yXCIsIHJlYXNvbiA9PiB7XG4gICAgICB0aGlzLl9zdG9yZWRFcnJvciA9IHJlYXNvbjtcblxuICAgICAgdGhpcy5faGVhZGVyc0NhcGFiaWxpdHkucmVqZWN0KHJlYXNvbik7XG4gICAgfSk7XG5cbiAgICB0aGlzLl9yZXF1ZXN0LmVuZCgpO1xuICB9XG5cbn1cblxuY2xhc3MgUERGTm9kZVN0cmVhbVJhbmdlUmVhZGVyIGV4dGVuZHMgQmFzZVJhbmdlUmVhZGVyIHtcbiAgY29uc3RydWN0b3Ioc3RyZWFtLCBzdGFydCwgZW5kKSB7XG4gICAgc3VwZXIoc3RyZWFtKTtcbiAgICB0aGlzLl9odHRwSGVhZGVycyA9IHt9O1xuXG4gICAgZm9yIChjb25zdCBwcm9wZXJ0eSBpbiBzdHJlYW0uaHR0cEhlYWRlcnMpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gc3RyZWFtLmh0dHBIZWFkZXJzW3Byb3BlcnR5XTtcblxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5faHR0cEhlYWRlcnNbcHJvcGVydHldID0gdmFsdWU7XG4gICAgfVxuXG4gICAgdGhpcy5faHR0cEhlYWRlcnMuUmFuZ2UgPSBgYnl0ZXM9JHtzdGFydH0tJHtlbmQgLSAxfWA7XG5cbiAgICBjb25zdCBoYW5kbGVSZXNwb25zZSA9IHJlc3BvbnNlID0+IHtcbiAgICAgIGlmIChyZXNwb25zZS5zdGF0dXNDb2RlID09PSA0MDQpIHtcbiAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgX3V0aWwuTWlzc2luZ1BERkV4Y2VwdGlvbihgTWlzc2luZyBQREYgXCIke3RoaXMuX3VybH1cIi5gKTtcbiAgICAgICAgdGhpcy5fc3RvcmVkRXJyb3IgPSBlcnJvcjtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9zZXRSZWFkYWJsZVN0cmVhbShyZXNwb25zZSk7XG4gICAgfTtcblxuICAgIHRoaXMuX3JlcXVlc3QgPSBudWxsO1xuXG4gICAgaWYgKHRoaXMuX3VybC5wcm90b2NvbCA9PT0gXCJodHRwOlwiKSB7XG4gICAgICB0aGlzLl9yZXF1ZXN0ID0gaHR0cC5yZXF1ZXN0KGNyZWF0ZVJlcXVlc3RPcHRpb25zKHRoaXMuX3VybCwgdGhpcy5faHR0cEhlYWRlcnMpLCBoYW5kbGVSZXNwb25zZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3JlcXVlc3QgPSBodHRwcy5yZXF1ZXN0KGNyZWF0ZVJlcXVlc3RPcHRpb25zKHRoaXMuX3VybCwgdGhpcy5faHR0cEhlYWRlcnMpLCBoYW5kbGVSZXNwb25zZSk7XG4gICAgfVxuXG4gICAgdGhpcy5fcmVxdWVzdC5vbihcImVycm9yXCIsIHJlYXNvbiA9PiB7XG4gICAgICB0aGlzLl9zdG9yZWRFcnJvciA9IHJlYXNvbjtcbiAgICB9KTtcblxuICAgIHRoaXMuX3JlcXVlc3QuZW5kKCk7XG4gIH1cblxufVxuXG5jbGFzcyBQREZOb2RlU3RyZWFtRnNGdWxsUmVhZGVyIGV4dGVuZHMgQmFzZUZ1bGxSZWFkZXIge1xuICBjb25zdHJ1Y3RvcihzdHJlYW0pIHtcbiAgICBzdXBlcihzdHJlYW0pO1xuICAgIGxldCBwYXRoID0gZGVjb2RlVVJJQ29tcG9uZW50KHRoaXMuX3VybC5wYXRoKTtcblxuICAgIGlmIChmaWxlVXJpUmVnZXgudGVzdCh0aGlzLl91cmwuaHJlZikpIHtcbiAgICAgIHBhdGggPSBwYXRoLnJlcGxhY2UoL15cXC8vLCBcIlwiKTtcbiAgICB9XG5cbiAgICBmcy5sc3RhdChwYXRoLCAoZXJyb3IsIHN0YXQpID0+IHtcbiAgICAgIGlmIChlcnJvcikge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gXCJFTk9FTlRcIikge1xuICAgICAgICAgIGVycm9yID0gbmV3IF91dGlsLk1pc3NpbmdQREZFeGNlcHRpb24oYE1pc3NpbmcgUERGIFwiJHtwYXRofVwiLmApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fc3RvcmVkRXJyb3IgPSBlcnJvcjtcblxuICAgICAgICB0aGlzLl9oZWFkZXJzQ2FwYWJpbGl0eS5yZWplY3QoZXJyb3IpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fY29udGVudExlbmd0aCA9IHN0YXQuc2l6ZTtcblxuICAgICAgdGhpcy5fc2V0UmVhZGFibGVTdHJlYW0oZnMuY3JlYXRlUmVhZFN0cmVhbShwYXRoKSk7XG5cbiAgICAgIHRoaXMuX2hlYWRlcnNDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgICB9KTtcbiAgfVxuXG59XG5cbmNsYXNzIFBERk5vZGVTdHJlYW1Gc1JhbmdlUmVhZGVyIGV4dGVuZHMgQmFzZVJhbmdlUmVhZGVyIHtcbiAgY29uc3RydWN0b3Ioc3RyZWFtLCBzdGFydCwgZW5kKSB7XG4gICAgc3VwZXIoc3RyZWFtKTtcbiAgICBsZXQgcGF0aCA9IGRlY29kZVVSSUNvbXBvbmVudCh0aGlzLl91cmwucGF0aCk7XG5cbiAgICBpZiAoZmlsZVVyaVJlZ2V4LnRlc3QodGhpcy5fdXJsLmhyZWYpKSB7XG4gICAgICBwYXRoID0gcGF0aC5yZXBsYWNlKC9eXFwvLywgXCJcIik7XG4gICAgfVxuXG4gICAgdGhpcy5fc2V0UmVhZGFibGVTdHJlYW0oZnMuY3JlYXRlUmVhZFN0cmVhbShwYXRoLCB7XG4gICAgICBzdGFydCxcbiAgICAgIGVuZDogZW5kIC0gMVxuICAgIH0pKTtcbiAgfVxuXG59XG5cbi8qKiovIH0pLFxuLyogMjYgKi9cbi8qKiovICgoX191bnVzZWRfd2VicGFja19tb2R1bGUsIGV4cG9ydHMsIF9fd19wZGZqc19yZXF1aXJlX18pID0+IHtcblxuXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgKHtcbiAgdmFsdWU6IHRydWVcbn0pKTtcbmV4cG9ydHMuY3JlYXRlUmVzcG9uc2VTdGF0dXNFcnJvciA9IGNyZWF0ZVJlc3BvbnNlU3RhdHVzRXJyb3I7XG5leHBvcnRzLmV4dHJhY3RGaWxlbmFtZUZyb21IZWFkZXIgPSBleHRyYWN0RmlsZW5hbWVGcm9tSGVhZGVyO1xuZXhwb3J0cy52YWxpZGF0ZVJhbmdlUmVxdWVzdENhcGFiaWxpdGllcyA9IHZhbGlkYXRlUmFuZ2VSZXF1ZXN0Q2FwYWJpbGl0aWVzO1xuZXhwb3J0cy52YWxpZGF0ZVJlc3BvbnNlU3RhdHVzID0gdmFsaWRhdGVSZXNwb25zZVN0YXR1cztcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxudmFyIF9jb250ZW50X2Rpc3Bvc2l0aW9uID0gX193X3BkZmpzX3JlcXVpcmVfXygyNyk7XG5cbnZhciBfZGlzcGxheV91dGlscyA9IF9fd19wZGZqc19yZXF1aXJlX18oNSk7XG5cbmZ1bmN0aW9uIHZhbGlkYXRlUmFuZ2VSZXF1ZXN0Q2FwYWJpbGl0aWVzKHtcbiAgZ2V0UmVzcG9uc2VIZWFkZXIsXG4gIGlzSHR0cCxcbiAgcmFuZ2VDaHVua1NpemUsXG4gIGRpc2FibGVSYW5nZVxufSkge1xuICBjb25zdCByZXR1cm5WYWx1ZXMgPSB7XG4gICAgYWxsb3dSYW5nZVJlcXVlc3RzOiBmYWxzZSxcbiAgICBzdWdnZXN0ZWRMZW5ndGg6IHVuZGVmaW5lZFxuICB9O1xuICBjb25zdCBsZW5ndGggPSBwYXJzZUludChnZXRSZXNwb25zZUhlYWRlcihcIkNvbnRlbnQtTGVuZ3RoXCIpLCAxMCk7XG5cbiAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKGxlbmd0aCkpIHtcbiAgICByZXR1cm4gcmV0dXJuVmFsdWVzO1xuICB9XG5cbiAgcmV0dXJuVmFsdWVzLnN1Z2dlc3RlZExlbmd0aCA9IGxlbmd0aDtcblxuICBpZiAobGVuZ3RoIDw9IDIgKiByYW5nZUNodW5rU2l6ZSkge1xuICAgIHJldHVybiByZXR1cm5WYWx1ZXM7XG4gIH1cblxuICBpZiAoZGlzYWJsZVJhbmdlIHx8ICFpc0h0dHApIHtcbiAgICByZXR1cm4gcmV0dXJuVmFsdWVzO1xuICB9XG5cbiAgaWYgKGdldFJlc3BvbnNlSGVhZGVyKFwiQWNjZXB0LVJhbmdlc1wiKSAhPT0gXCJieXRlc1wiKSB7XG4gICAgcmV0dXJuIHJldHVyblZhbHVlcztcbiAgfVxuXG4gIGNvbnN0IGNvbnRlbnRFbmNvZGluZyA9IGdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1FbmNvZGluZ1wiKSB8fCBcImlkZW50aXR5XCI7XG5cbiAgaWYgKGNvbnRlbnRFbmNvZGluZyAhPT0gXCJpZGVudGl0eVwiKSB7XG4gICAgcmV0dXJuIHJldHVyblZhbHVlcztcbiAgfVxuXG4gIHJldHVyblZhbHVlcy5hbGxvd1JhbmdlUmVxdWVzdHMgPSB0cnVlO1xuICByZXR1cm4gcmV0dXJuVmFsdWVzO1xufVxuXG5mdW5jdGlvbiBleHRyYWN0RmlsZW5hbWVGcm9tSGVhZGVyKGdldFJlc3BvbnNlSGVhZGVyKSB7XG4gIGNvbnN0IGNvbnRlbnREaXNwb3NpdGlvbiA9IGdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1EaXNwb3NpdGlvblwiKTtcblxuICBpZiAoY29udGVudERpc3Bvc2l0aW9uKSB7XG4gICAgbGV0IGZpbGVuYW1lID0gKDAsIF9jb250ZW50X2Rpc3Bvc2l0aW9uLmdldEZpbGVuYW1lRnJvbUNvbnRlbnREaXNwb3NpdGlvbkhlYWRlcikoY29udGVudERpc3Bvc2l0aW9uKTtcblxuICAgIGlmIChmaWxlbmFtZS5pbmNsdWRlcyhcIiVcIikpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGZpbGVuYW1lID0gZGVjb2RlVVJJQ29tcG9uZW50KGZpbGVuYW1lKTtcbiAgICAgIH0gY2F0Y2ggKGV4KSB7fVxuICAgIH1cblxuICAgIGlmICgoMCwgX2Rpc3BsYXlfdXRpbHMuaXNQZGZGaWxlKShmaWxlbmFtZSkpIHtcbiAgICAgIHJldHVybiBmaWxlbmFtZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gY3JlYXRlUmVzcG9uc2VTdGF0dXNFcnJvcihzdGF0dXMsIHVybCkge1xuICBpZiAoc3RhdHVzID09PSA0MDQgfHwgc3RhdHVzID09PSAwICYmIHVybC5zdGFydHNXaXRoKFwiZmlsZTpcIikpIHtcbiAgICByZXR1cm4gbmV3IF91dGlsLk1pc3NpbmdQREZFeGNlcHRpb24oJ01pc3NpbmcgUERGIFwiJyArIHVybCArICdcIi4nKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgX3V0aWwuVW5leHBlY3RlZFJlc3BvbnNlRXhjZXB0aW9uKGBVbmV4cGVjdGVkIHNlcnZlciByZXNwb25zZSAoJHtzdGF0dXN9KSB3aGlsZSByZXRyaWV2aW5nIFBERiBcIiR7dXJsfVwiLmAsIHN0YXR1cyk7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlUmVzcG9uc2VTdGF0dXMoc3RhdHVzKSB7XG4gIHJldHVybiBzdGF0dXMgPT09IDIwMCB8fCBzdGF0dXMgPT09IDIwNjtcbn1cblxuLyoqKi8gfSksXG4vKiAyNyAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5nZXRGaWxlbmFtZUZyb21Db250ZW50RGlzcG9zaXRpb25IZWFkZXIgPSBnZXRGaWxlbmFtZUZyb21Db250ZW50RGlzcG9zaXRpb25IZWFkZXI7XG5cbnZhciBfdXRpbCA9IF9fd19wZGZqc19yZXF1aXJlX18oMSk7XG5cbmZ1bmN0aW9uIGdldEZpbGVuYW1lRnJvbUNvbnRlbnREaXNwb3NpdGlvbkhlYWRlcihjb250ZW50RGlzcG9zaXRpb24pIHtcbiAgbGV0IG5lZWRzRW5jb2RpbmdGaXh1cCA9IHRydWU7XG4gIGxldCB0bXAgPSB0b1BhcmFtUmVnRXhwKFwiZmlsZW5hbWVcXFxcKlwiLCBcImlcIikuZXhlYyhjb250ZW50RGlzcG9zaXRpb24pO1xuXG4gIGlmICh0bXApIHtcbiAgICB0bXAgPSB0bXBbMV07XG4gICAgbGV0IGZpbGVuYW1lID0gcmZjMjYxNnVucXVvdGUodG1wKTtcbiAgICBmaWxlbmFtZSA9IHVuZXNjYXBlKGZpbGVuYW1lKTtcbiAgICBmaWxlbmFtZSA9IHJmYzU5ODdkZWNvZGUoZmlsZW5hbWUpO1xuICAgIGZpbGVuYW1lID0gcmZjMjA0N2RlY29kZShmaWxlbmFtZSk7XG4gICAgcmV0dXJuIGZpeHVwRW5jb2RpbmcoZmlsZW5hbWUpO1xuICB9XG5cbiAgdG1wID0gcmZjMjIzMWdldHBhcmFtKGNvbnRlbnREaXNwb3NpdGlvbik7XG5cbiAgaWYgKHRtcCkge1xuICAgIGNvbnN0IGZpbGVuYW1lID0gcmZjMjA0N2RlY29kZSh0bXApO1xuICAgIHJldHVybiBmaXh1cEVuY29kaW5nKGZpbGVuYW1lKTtcbiAgfVxuXG4gIHRtcCA9IHRvUGFyYW1SZWdFeHAoXCJmaWxlbmFtZVwiLCBcImlcIikuZXhlYyhjb250ZW50RGlzcG9zaXRpb24pO1xuXG4gIGlmICh0bXApIHtcbiAgICB0bXAgPSB0bXBbMV07XG4gICAgbGV0IGZpbGVuYW1lID0gcmZjMjYxNnVucXVvdGUodG1wKTtcbiAgICBmaWxlbmFtZSA9IHJmYzIwNDdkZWNvZGUoZmlsZW5hbWUpO1xuICAgIHJldHVybiBmaXh1cEVuY29kaW5nKGZpbGVuYW1lKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRvUGFyYW1SZWdFeHAoYXR0cmlidXRlUGF0dGVybiwgZmxhZ3MpIHtcbiAgICByZXR1cm4gbmV3IFJlZ0V4cChcIig/Ol58OylcXFxccypcIiArIGF0dHJpYnV0ZVBhdHRlcm4gKyBcIlxcXFxzKj1cXFxccypcIiArIFwiKFwiICsgJ1teXCI7XFxcXHNdW147XFxcXHNdKicgKyBcInxcIiArICdcIig/OlteXCJcXFxcXFxcXF18XFxcXFxcXFxcIj8pK1wiPycgKyBcIilcIiwgZmxhZ3MpO1xuICB9XG5cbiAgZnVuY3Rpb24gdGV4dGRlY29kZShlbmNvZGluZywgdmFsdWUpIHtcbiAgICBpZiAoZW5jb2RpbmcpIHtcbiAgICAgIGlmICghL15bXFx4MDAtXFx4RkZdKyQvLnRlc3QodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcihlbmNvZGluZywge1xuICAgICAgICAgIGZhdGFsOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBidWZmZXIgPSAoMCwgX3V0aWwuc3RyaW5nVG9CeXRlcykodmFsdWUpO1xuICAgICAgICB2YWx1ZSA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlcik7XG4gICAgICAgIG5lZWRzRW5jb2RpbmdGaXh1cCA9IGZhbHNlO1xuICAgICAgfSBjYXRjaCAoZSkge31cbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBmdW5jdGlvbiBmaXh1cEVuY29kaW5nKHZhbHVlKSB7XG4gICAgaWYgKG5lZWRzRW5jb2RpbmdGaXh1cCAmJiAvW1xceDgwLVxceGZmXS8udGVzdCh2YWx1ZSkpIHtcbiAgICAgIHZhbHVlID0gdGV4dGRlY29kZShcInV0Zi04XCIsIHZhbHVlKTtcblxuICAgICAgaWYgKG5lZWRzRW5jb2RpbmdGaXh1cCkge1xuICAgICAgICB2YWx1ZSA9IHRleHRkZWNvZGUoXCJpc28tODg1OS0xXCIsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBmdW5jdGlvbiByZmMyMjMxZ2V0cGFyYW0oY29udGVudERpc3Bvc2l0aW9uU3RyKSB7XG4gICAgY29uc3QgbWF0Y2hlcyA9IFtdO1xuICAgIGxldCBtYXRjaDtcbiAgICBjb25zdCBpdGVyID0gdG9QYXJhbVJlZ0V4cChcImZpbGVuYW1lXFxcXCooKD8hMFxcXFxkKVxcXFxkKykoXFxcXCo/KVwiLCBcImlnXCIpO1xuXG4gICAgd2hpbGUgKChtYXRjaCA9IGl0ZXIuZXhlYyhjb250ZW50RGlzcG9zaXRpb25TdHIpKSAhPT0gbnVsbCkge1xuICAgICAgbGV0IFssIG4sIHF1b3QsIHBhcnRdID0gbWF0Y2g7XG4gICAgICBuID0gcGFyc2VJbnQobiwgMTApO1xuXG4gICAgICBpZiAobiBpbiBtYXRjaGVzKSB7XG4gICAgICAgIGlmIChuID09PSAwKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgbWF0Y2hlc1tuXSA9IFtxdW90LCBwYXJ0XTtcbiAgICB9XG5cbiAgICBjb25zdCBwYXJ0cyA9IFtdO1xuXG4gICAgZm9yIChsZXQgbiA9IDA7IG4gPCBtYXRjaGVzLmxlbmd0aDsgKytuKSB7XG4gICAgICBpZiAoIShuIGluIG1hdGNoZXMpKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBsZXQgW3F1b3QsIHBhcnRdID0gbWF0Y2hlc1tuXTtcbiAgICAgIHBhcnQgPSByZmMyNjE2dW5xdW90ZShwYXJ0KTtcblxuICAgICAgaWYgKHF1b3QpIHtcbiAgICAgICAgcGFydCA9IHVuZXNjYXBlKHBhcnQpO1xuXG4gICAgICAgIGlmIChuID09PSAwKSB7XG4gICAgICAgICAgcGFydCA9IHJmYzU5ODdkZWNvZGUocGFydCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcGFydHMucHVzaChwYXJ0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFydHMuam9pbihcIlwiKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJmYzI2MTZ1bnF1b3RlKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlLnN0YXJ0c1dpdGgoJ1wiJykpIHtcbiAgICAgIGNvbnN0IHBhcnRzID0gdmFsdWUuc2xpY2UoMSkuc3BsaXQoJ1xcXFxcIicpO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGNvbnN0IHF1b3RpbmRleCA9IHBhcnRzW2ldLmluZGV4T2YoJ1wiJyk7XG5cbiAgICAgICAgaWYgKHF1b3RpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICBwYXJ0c1tpXSA9IHBhcnRzW2ldLnNsaWNlKDAsIHF1b3RpbmRleCk7XG4gICAgICAgICAgcGFydHMubGVuZ3RoID0gaSArIDE7XG4gICAgICAgIH1cblxuICAgICAgICBwYXJ0c1tpXSA9IHBhcnRzW2ldLnJlcGxhY2UoL1xcXFwoLikvZywgXCIkMVwiKTtcbiAgICAgIH1cblxuICAgICAgdmFsdWUgPSBwYXJ0cy5qb2luKCdcIicpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJmYzU5ODdkZWNvZGUoZXh0dmFsdWUpIHtcbiAgICBjb25zdCBlbmNvZGluZ2VuZCA9IGV4dHZhbHVlLmluZGV4T2YoXCInXCIpO1xuXG4gICAgaWYgKGVuY29kaW5nZW5kID09PSAtMSkge1xuICAgICAgcmV0dXJuIGV4dHZhbHVlO1xuICAgIH1cblxuICAgIGNvbnN0IGVuY29kaW5nID0gZXh0dmFsdWUuc2xpY2UoMCwgZW5jb2RpbmdlbmQpO1xuICAgIGNvbnN0IGxhbmd2YWx1ZSA9IGV4dHZhbHVlLnNsaWNlKGVuY29kaW5nZW5kICsgMSk7XG4gICAgY29uc3QgdmFsdWUgPSBsYW5ndmFsdWUucmVwbGFjZSgvXlteJ10qJy8sIFwiXCIpO1xuICAgIHJldHVybiB0ZXh0ZGVjb2RlKGVuY29kaW5nLCB2YWx1ZSk7XG4gIH1cblxuICBmdW5jdGlvbiByZmMyMDQ3ZGVjb2RlKHZhbHVlKSB7XG4gICAgaWYgKCF2YWx1ZS5zdGFydHNXaXRoKFwiPT9cIikgfHwgL1tcXHgwMC1cXHgxOVxceDgwLVxceGZmXS8udGVzdCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWUucmVwbGFjZSgvPVxcPyhbXFx3LV0qKVxcPyhbUXFCYl0pXFw/KCg/OlteP118XFw/KD8hPSkpKilcXD89L2csIGZ1bmN0aW9uIChtYXRjaGVzLCBjaGFyc2V0LCBlbmNvZGluZywgdGV4dCkge1xuICAgICAgaWYgKGVuY29kaW5nID09PSBcInFcIiB8fCBlbmNvZGluZyA9PT0gXCJRXCIpIHtcbiAgICAgICAgdGV4dCA9IHRleHQucmVwbGFjZSgvXy9nLCBcIiBcIik7XG4gICAgICAgIHRleHQgPSB0ZXh0LnJlcGxhY2UoLz0oWzAtOWEtZkEtRl17Mn0pL2csIGZ1bmN0aW9uIChtYXRjaCwgaGV4KSB7XG4gICAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUocGFyc2VJbnQoaGV4LCAxNikpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRleHRkZWNvZGUoY2hhcnNldCwgdGV4dCk7XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHRleHQgPSBhdG9iKHRleHQpO1xuICAgICAgfSBjYXRjaCAoZSkge31cblxuICAgICAgcmV0dXJuIHRleHRkZWNvZGUoY2hhcnNldCwgdGV4dCk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gXCJcIjtcbn1cblxuLyoqKi8gfSksXG4vKiAyOCAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5QREZOZXR3b3JrU3RyZWFtID0gdm9pZCAwO1xuXG52YXIgX3V0aWwgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDEpO1xuXG52YXIgX25ldHdvcmtfdXRpbHMgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDI2KTtcblxuO1xuY29uc3QgT0tfUkVTUE9OU0UgPSAyMDA7XG5jb25zdCBQQVJUSUFMX0NPTlRFTlRfUkVTUE9OU0UgPSAyMDY7XG5cbmZ1bmN0aW9uIGdldEFycmF5QnVmZmVyKHhocikge1xuICBjb25zdCBkYXRhID0geGhyLnJlc3BvbnNlO1xuXG4gIGlmICh0eXBlb2YgZGF0YSAhPT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgY29uc3QgYXJyYXkgPSAoMCwgX3V0aWwuc3RyaW5nVG9CeXRlcykoZGF0YSk7XG4gIHJldHVybiBhcnJheS5idWZmZXI7XG59XG5cbmNsYXNzIE5ldHdvcmtNYW5hZ2VyIHtcbiAgY29uc3RydWN0b3IodXJsLCBhcmdzID0ge30pIHtcbiAgICB0aGlzLnVybCA9IHVybDtcbiAgICB0aGlzLmlzSHR0cCA9IC9eaHR0cHM/Oi9pLnRlc3QodXJsKTtcbiAgICB0aGlzLmh0dHBIZWFkZXJzID0gdGhpcy5pc0h0dHAgJiYgYXJncy5odHRwSGVhZGVycyB8fCBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMud2l0aENyZWRlbnRpYWxzID0gYXJncy53aXRoQ3JlZGVudGlhbHMgfHwgZmFsc2U7XG5cbiAgICB0aGlzLmdldFhociA9IGFyZ3MuZ2V0WGhyIHx8IGZ1bmN0aW9uIE5ldHdvcmtNYW5hZ2VyX2dldFhocigpIHtcbiAgICAgIHJldHVybiBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICB9O1xuXG4gICAgdGhpcy5jdXJyWGhySWQgPSAwO1xuICAgIHRoaXMucGVuZGluZ1JlcXVlc3RzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgfVxuXG4gIHJlcXVlc3RSYW5nZShiZWdpbiwgZW5kLCBsaXN0ZW5lcnMpIHtcbiAgICBjb25zdCBhcmdzID0ge1xuICAgICAgYmVnaW4sXG4gICAgICBlbmRcbiAgICB9O1xuXG4gICAgZm9yIChjb25zdCBwcm9wIGluIGxpc3RlbmVycykge1xuICAgICAgYXJnc1twcm9wXSA9IGxpc3RlbmVyc1twcm9wXTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KGFyZ3MpO1xuICB9XG5cbiAgcmVxdWVzdEZ1bGwobGlzdGVuZXJzKSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdChsaXN0ZW5lcnMpO1xuICB9XG5cbiAgcmVxdWVzdChhcmdzKSB7XG4gICAgY29uc3QgeGhyID0gdGhpcy5nZXRYaHIoKTtcbiAgICBjb25zdCB4aHJJZCA9IHRoaXMuY3VyclhocklkKys7XG4gICAgY29uc3QgcGVuZGluZ1JlcXVlc3QgPSB0aGlzLnBlbmRpbmdSZXF1ZXN0c1t4aHJJZF0gPSB7XG4gICAgICB4aHJcbiAgICB9O1xuICAgIHhoci5vcGVuKFwiR0VUXCIsIHRoaXMudXJsKTtcbiAgICB4aHIud2l0aENyZWRlbnRpYWxzID0gdGhpcy53aXRoQ3JlZGVudGlhbHM7XG5cbiAgICBmb3IgKGNvbnN0IHByb3BlcnR5IGluIHRoaXMuaHR0cEhlYWRlcnMpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5odHRwSGVhZGVyc1twcm9wZXJ0eV07XG5cbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKHByb3BlcnR5LCB2YWx1ZSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNIdHRwICYmIFwiYmVnaW5cIiBpbiBhcmdzICYmIFwiZW5kXCIgaW4gYXJncykge1xuICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoXCJSYW5nZVwiLCBgYnl0ZXM9JHthcmdzLmJlZ2lufS0ke2FyZ3MuZW5kIC0gMX1gKTtcbiAgICAgIHBlbmRpbmdSZXF1ZXN0LmV4cGVjdGVkU3RhdHVzID0gUEFSVElBTF9DT05URU5UX1JFU1BPTlNFO1xuICAgIH0gZWxzZSB7XG4gICAgICBwZW5kaW5nUmVxdWVzdC5leHBlY3RlZFN0YXR1cyA9IE9LX1JFU1BPTlNFO1xuICAgIH1cblxuICAgIHhoci5yZXNwb25zZVR5cGUgPSBcImFycmF5YnVmZmVyXCI7XG5cbiAgICBpZiAoYXJncy5vbkVycm9yKSB7XG4gICAgICB4aHIub25lcnJvciA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgYXJncy5vbkVycm9yKHhoci5zdGF0dXMpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gdGhpcy5vblN0YXRlQ2hhbmdlLmJpbmQodGhpcywgeGhySWQpO1xuICAgIHhoci5vbnByb2dyZXNzID0gdGhpcy5vblByb2dyZXNzLmJpbmQodGhpcywgeGhySWQpO1xuICAgIHBlbmRpbmdSZXF1ZXN0Lm9uSGVhZGVyc1JlY2VpdmVkID0gYXJncy5vbkhlYWRlcnNSZWNlaXZlZDtcbiAgICBwZW5kaW5nUmVxdWVzdC5vbkRvbmUgPSBhcmdzLm9uRG9uZTtcbiAgICBwZW5kaW5nUmVxdWVzdC5vbkVycm9yID0gYXJncy5vbkVycm9yO1xuICAgIHBlbmRpbmdSZXF1ZXN0Lm9uUHJvZ3Jlc3MgPSBhcmdzLm9uUHJvZ3Jlc3M7XG4gICAgeGhyLnNlbmQobnVsbCk7XG4gICAgcmV0dXJuIHhocklkO1xuICB9XG5cbiAgb25Qcm9ncmVzcyh4aHJJZCwgZXZ0KSB7XG4gICAgY29uc3QgcGVuZGluZ1JlcXVlc3QgPSB0aGlzLnBlbmRpbmdSZXF1ZXN0c1t4aHJJZF07XG5cbiAgICBpZiAoIXBlbmRpbmdSZXF1ZXN0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcGVuZGluZ1JlcXVlc3Qub25Qcm9ncmVzcz8uKGV2dCk7XG4gIH1cblxuICBvblN0YXRlQ2hhbmdlKHhocklkLCBldnQpIHtcbiAgICBjb25zdCBwZW5kaW5nUmVxdWVzdCA9IHRoaXMucGVuZGluZ1JlcXVlc3RzW3hocklkXTtcblxuICAgIGlmICghcGVuZGluZ1JlcXVlc3QpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB4aHIgPSBwZW5kaW5nUmVxdWVzdC54aHI7XG5cbiAgICBpZiAoeGhyLnJlYWR5U3RhdGUgPj0gMiAmJiBwZW5kaW5nUmVxdWVzdC5vbkhlYWRlcnNSZWNlaXZlZCkge1xuICAgICAgcGVuZGluZ1JlcXVlc3Qub25IZWFkZXJzUmVjZWl2ZWQoKTtcbiAgICAgIGRlbGV0ZSBwZW5kaW5nUmVxdWVzdC5vbkhlYWRlcnNSZWNlaXZlZDtcbiAgICB9XG5cbiAgICBpZiAoeGhyLnJlYWR5U3RhdGUgIT09IDQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoISh4aHJJZCBpbiB0aGlzLnBlbmRpbmdSZXF1ZXN0cykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBkZWxldGUgdGhpcy5wZW5kaW5nUmVxdWVzdHNbeGhySWRdO1xuXG4gICAgaWYgKHhoci5zdGF0dXMgPT09IDAgJiYgdGhpcy5pc0h0dHApIHtcbiAgICAgIHBlbmRpbmdSZXF1ZXN0Lm9uRXJyb3I/Lih4aHIuc3RhdHVzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB4aHJTdGF0dXMgPSB4aHIuc3RhdHVzIHx8IE9LX1JFU1BPTlNFO1xuICAgIGNvbnN0IG9rX3Jlc3BvbnNlX29uX3JhbmdlX3JlcXVlc3QgPSB4aHJTdGF0dXMgPT09IE9LX1JFU1BPTlNFICYmIHBlbmRpbmdSZXF1ZXN0LmV4cGVjdGVkU3RhdHVzID09PSBQQVJUSUFMX0NPTlRFTlRfUkVTUE9OU0U7XG5cbiAgICBpZiAoIW9rX3Jlc3BvbnNlX29uX3JhbmdlX3JlcXVlc3QgJiYgeGhyU3RhdHVzICE9PSBwZW5kaW5nUmVxdWVzdC5leHBlY3RlZFN0YXR1cykge1xuICAgICAgcGVuZGluZ1JlcXVlc3Qub25FcnJvcj8uKHhoci5zdGF0dXMpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGNodW5rID0gZ2V0QXJyYXlCdWZmZXIoeGhyKTtcblxuICAgIGlmICh4aHJTdGF0dXMgPT09IFBBUlRJQUxfQ09OVEVOVF9SRVNQT05TRSkge1xuICAgICAgY29uc3QgcmFuZ2VIZWFkZXIgPSB4aHIuZ2V0UmVzcG9uc2VIZWFkZXIoXCJDb250ZW50LVJhbmdlXCIpO1xuICAgICAgY29uc3QgbWF0Y2hlcyA9IC9ieXRlcyAoXFxkKyktKFxcZCspXFwvKFxcZCspLy5leGVjKHJhbmdlSGVhZGVyKTtcbiAgICAgIHBlbmRpbmdSZXF1ZXN0Lm9uRG9uZSh7XG4gICAgICAgIGJlZ2luOiBwYXJzZUludChtYXRjaGVzWzFdLCAxMCksXG4gICAgICAgIGNodW5rXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKGNodW5rKSB7XG4gICAgICBwZW5kaW5nUmVxdWVzdC5vbkRvbmUoe1xuICAgICAgICBiZWdpbjogMCxcbiAgICAgICAgY2h1bmtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBwZW5kaW5nUmVxdWVzdC5vbkVycm9yPy4oeGhyLnN0YXR1cyk7XG4gICAgfVxuICB9XG5cbiAgZ2V0UmVxdWVzdFhocih4aHJJZCkge1xuICAgIHJldHVybiB0aGlzLnBlbmRpbmdSZXF1ZXN0c1t4aHJJZF0ueGhyO1xuICB9XG5cbiAgaXNQZW5kaW5nUmVxdWVzdCh4aHJJZCkge1xuICAgIHJldHVybiB4aHJJZCBpbiB0aGlzLnBlbmRpbmdSZXF1ZXN0cztcbiAgfVxuXG4gIGFib3J0UmVxdWVzdCh4aHJJZCkge1xuICAgIGNvbnN0IHhociA9IHRoaXMucGVuZGluZ1JlcXVlc3RzW3hocklkXS54aHI7XG4gICAgZGVsZXRlIHRoaXMucGVuZGluZ1JlcXVlc3RzW3hocklkXTtcbiAgICB4aHIuYWJvcnQoKTtcbiAgfVxuXG59XG5cbmNsYXNzIFBERk5ldHdvcmtTdHJlYW0ge1xuICBjb25zdHJ1Y3Rvcihzb3VyY2UpIHtcbiAgICB0aGlzLl9zb3VyY2UgPSBzb3VyY2U7XG4gICAgdGhpcy5fbWFuYWdlciA9IG5ldyBOZXR3b3JrTWFuYWdlcihzb3VyY2UudXJsLCB7XG4gICAgICBodHRwSGVhZGVyczogc291cmNlLmh0dHBIZWFkZXJzLFxuICAgICAgd2l0aENyZWRlbnRpYWxzOiBzb3VyY2Uud2l0aENyZWRlbnRpYWxzXG4gICAgfSk7XG4gICAgdGhpcy5fcmFuZ2VDaHVua1NpemUgPSBzb3VyY2UucmFuZ2VDaHVua1NpemU7XG4gICAgdGhpcy5fZnVsbFJlcXVlc3RSZWFkZXIgPSBudWxsO1xuICAgIHRoaXMuX3JhbmdlUmVxdWVzdFJlYWRlcnMgPSBbXTtcbiAgfVxuXG4gIF9vblJhbmdlUmVxdWVzdFJlYWRlckNsb3NlZChyZWFkZXIpIHtcbiAgICBjb25zdCBpID0gdGhpcy5fcmFuZ2VSZXF1ZXN0UmVhZGVycy5pbmRleE9mKHJlYWRlcik7XG5cbiAgICBpZiAoaSA+PSAwKSB7XG4gICAgICB0aGlzLl9yYW5nZVJlcXVlc3RSZWFkZXJzLnNwbGljZShpLCAxKTtcbiAgICB9XG4gIH1cblxuICBnZXRGdWxsUmVhZGVyKCkge1xuICAgICgwLCBfdXRpbC5hc3NlcnQpKCF0aGlzLl9mdWxsUmVxdWVzdFJlYWRlciwgXCJQREZOZXR3b3JrU3RyZWFtLmdldEZ1bGxSZWFkZXIgY2FuIG9ubHkgYmUgY2FsbGVkIG9uY2UuXCIpO1xuICAgIHRoaXMuX2Z1bGxSZXF1ZXN0UmVhZGVyID0gbmV3IFBERk5ldHdvcmtTdHJlYW1GdWxsUmVxdWVzdFJlYWRlcih0aGlzLl9tYW5hZ2VyLCB0aGlzLl9zb3VyY2UpO1xuICAgIHJldHVybiB0aGlzLl9mdWxsUmVxdWVzdFJlYWRlcjtcbiAgfVxuXG4gIGdldFJhbmdlUmVhZGVyKGJlZ2luLCBlbmQpIHtcbiAgICBjb25zdCByZWFkZXIgPSBuZXcgUERGTmV0d29ya1N0cmVhbVJhbmdlUmVxdWVzdFJlYWRlcih0aGlzLl9tYW5hZ2VyLCBiZWdpbiwgZW5kKTtcbiAgICByZWFkZXIub25DbG9zZWQgPSB0aGlzLl9vblJhbmdlUmVxdWVzdFJlYWRlckNsb3NlZC5iaW5kKHRoaXMpO1xuXG4gICAgdGhpcy5fcmFuZ2VSZXF1ZXN0UmVhZGVycy5wdXNoKHJlYWRlcik7XG5cbiAgICByZXR1cm4gcmVhZGVyO1xuICB9XG5cbiAgY2FuY2VsQWxsUmVxdWVzdHMocmVhc29uKSB7XG4gICAgdGhpcy5fZnVsbFJlcXVlc3RSZWFkZXI/LmNhbmNlbChyZWFzb24pO1xuXG4gICAgZm9yIChjb25zdCByZWFkZXIgb2YgdGhpcy5fcmFuZ2VSZXF1ZXN0UmVhZGVycy5zbGljZSgwKSkge1xuICAgICAgcmVhZGVyLmNhbmNlbChyZWFzb24pO1xuICAgIH1cbiAgfVxuXG59XG5cbmV4cG9ydHMuUERGTmV0d29ya1N0cmVhbSA9IFBERk5ldHdvcmtTdHJlYW07XG5cbmNsYXNzIFBERk5ldHdvcmtTdHJlYW1GdWxsUmVxdWVzdFJlYWRlciB7XG4gIGNvbnN0cnVjdG9yKG1hbmFnZXIsIHNvdXJjZSkge1xuICAgIHRoaXMuX21hbmFnZXIgPSBtYW5hZ2VyO1xuICAgIGNvbnN0IGFyZ3MgPSB7XG4gICAgICBvbkhlYWRlcnNSZWNlaXZlZDogdGhpcy5fb25IZWFkZXJzUmVjZWl2ZWQuYmluZCh0aGlzKSxcbiAgICAgIG9uRG9uZTogdGhpcy5fb25Eb25lLmJpbmQodGhpcyksXG4gICAgICBvbkVycm9yOiB0aGlzLl9vbkVycm9yLmJpbmQodGhpcyksXG4gICAgICBvblByb2dyZXNzOiB0aGlzLl9vblByb2dyZXNzLmJpbmQodGhpcylcbiAgICB9O1xuICAgIHRoaXMuX3VybCA9IHNvdXJjZS51cmw7XG4gICAgdGhpcy5fZnVsbFJlcXVlc3RJZCA9IG1hbmFnZXIucmVxdWVzdEZ1bGwoYXJncyk7XG4gICAgdGhpcy5faGVhZGVyc1JlY2VpdmVkQ2FwYWJpbGl0eSA9ICgwLCBfdXRpbC5jcmVhdGVQcm9taXNlQ2FwYWJpbGl0eSkoKTtcbiAgICB0aGlzLl9kaXNhYmxlUmFuZ2UgPSBzb3VyY2UuZGlzYWJsZVJhbmdlIHx8IGZhbHNlO1xuICAgIHRoaXMuX2NvbnRlbnRMZW5ndGggPSBzb3VyY2UubGVuZ3RoO1xuICAgIHRoaXMuX3JhbmdlQ2h1bmtTaXplID0gc291cmNlLnJhbmdlQ2h1bmtTaXplO1xuXG4gICAgaWYgKCF0aGlzLl9yYW5nZUNodW5rU2l6ZSAmJiAhdGhpcy5fZGlzYWJsZVJhbmdlKSB7XG4gICAgICB0aGlzLl9kaXNhYmxlUmFuZ2UgPSB0cnVlO1xuICAgIH1cblxuICAgIHRoaXMuX2lzU3RyZWFtaW5nU3VwcG9ydGVkID0gZmFsc2U7XG4gICAgdGhpcy5faXNSYW5nZVN1cHBvcnRlZCA9IGZhbHNlO1xuICAgIHRoaXMuX2NhY2hlZENodW5rcyA9IFtdO1xuICAgIHRoaXMuX3JlcXVlc3RzID0gW107XG4gICAgdGhpcy5fZG9uZSA9IGZhbHNlO1xuICAgIHRoaXMuX3N0b3JlZEVycm9yID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX2ZpbGVuYW1lID0gbnVsbDtcbiAgICB0aGlzLm9uUHJvZ3Jlc3MgPSBudWxsO1xuICB9XG5cbiAgX29uSGVhZGVyc1JlY2VpdmVkKCkge1xuICAgIGNvbnN0IGZ1bGxSZXF1ZXN0WGhySWQgPSB0aGlzLl9mdWxsUmVxdWVzdElkO1xuXG4gICAgY29uc3QgZnVsbFJlcXVlc3RYaHIgPSB0aGlzLl9tYW5hZ2VyLmdldFJlcXVlc3RYaHIoZnVsbFJlcXVlc3RYaHJJZCk7XG5cbiAgICBjb25zdCBnZXRSZXNwb25zZUhlYWRlciA9IG5hbWUgPT4ge1xuICAgICAgcmV0dXJuIGZ1bGxSZXF1ZXN0WGhyLmdldFJlc3BvbnNlSGVhZGVyKG5hbWUpO1xuICAgIH07XG5cbiAgICBjb25zdCB7XG4gICAgICBhbGxvd1JhbmdlUmVxdWVzdHMsXG4gICAgICBzdWdnZXN0ZWRMZW5ndGhcbiAgICB9ID0gKDAsIF9uZXR3b3JrX3V0aWxzLnZhbGlkYXRlUmFuZ2VSZXF1ZXN0Q2FwYWJpbGl0aWVzKSh7XG4gICAgICBnZXRSZXNwb25zZUhlYWRlcixcbiAgICAgIGlzSHR0cDogdGhpcy5fbWFuYWdlci5pc0h0dHAsXG4gICAgICByYW5nZUNodW5rU2l6ZTogdGhpcy5fcmFuZ2VDaHVua1NpemUsXG4gICAgICBkaXNhYmxlUmFuZ2U6IHRoaXMuX2Rpc2FibGVSYW5nZVxuICAgIH0pO1xuXG4gICAgaWYgKGFsbG93UmFuZ2VSZXF1ZXN0cykge1xuICAgICAgdGhpcy5faXNSYW5nZVN1cHBvcnRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgdGhpcy5fY29udGVudExlbmd0aCA9IHN1Z2dlc3RlZExlbmd0aCB8fCB0aGlzLl9jb250ZW50TGVuZ3RoO1xuICAgIHRoaXMuX2ZpbGVuYW1lID0gKDAsIF9uZXR3b3JrX3V0aWxzLmV4dHJhY3RGaWxlbmFtZUZyb21IZWFkZXIpKGdldFJlc3BvbnNlSGVhZGVyKTtcblxuICAgIGlmICh0aGlzLl9pc1JhbmdlU3VwcG9ydGVkKSB7XG4gICAgICB0aGlzLl9tYW5hZ2VyLmFib3J0UmVxdWVzdChmdWxsUmVxdWVzdFhocklkKTtcbiAgICB9XG5cbiAgICB0aGlzLl9oZWFkZXJzUmVjZWl2ZWRDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgfVxuXG4gIF9vbkRvbmUoZGF0YSkge1xuICAgIGlmIChkYXRhKSB7XG4gICAgICBpZiAodGhpcy5fcmVxdWVzdHMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCByZXF1ZXN0Q2FwYWJpbGl0eSA9IHRoaXMuX3JlcXVlc3RzLnNoaWZ0KCk7XG5cbiAgICAgICAgcmVxdWVzdENhcGFiaWxpdHkucmVzb2x2ZSh7XG4gICAgICAgICAgdmFsdWU6IGRhdGEuY2h1bmssXG4gICAgICAgICAgZG9uZTogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9jYWNoZWRDaHVua3MucHVzaChkYXRhLmNodW5rKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9kb25lID0gdHJ1ZTtcblxuICAgIGlmICh0aGlzLl9jYWNoZWRDaHVua3MubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcmVxdWVzdENhcGFiaWxpdHkgb2YgdGhpcy5fcmVxdWVzdHMpIHtcbiAgICAgIHJlcXVlc3RDYXBhYmlsaXR5LnJlc29sdmUoe1xuICAgICAgICB2YWx1ZTogdW5kZWZpbmVkLFxuICAgICAgICBkb25lOiB0cnVlXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLl9yZXF1ZXN0cy5sZW5ndGggPSAwO1xuICB9XG5cbiAgX29uRXJyb3Ioc3RhdHVzKSB7XG4gICAgdGhpcy5fc3RvcmVkRXJyb3IgPSAoMCwgX25ldHdvcmtfdXRpbHMuY3JlYXRlUmVzcG9uc2VTdGF0dXNFcnJvcikoc3RhdHVzLCB0aGlzLl91cmwpO1xuXG4gICAgdGhpcy5faGVhZGVyc1JlY2VpdmVkQ2FwYWJpbGl0eS5yZWplY3QodGhpcy5fc3RvcmVkRXJyb3IpO1xuXG4gICAgZm9yIChjb25zdCByZXF1ZXN0Q2FwYWJpbGl0eSBvZiB0aGlzLl9yZXF1ZXN0cykge1xuICAgICAgcmVxdWVzdENhcGFiaWxpdHkucmVqZWN0KHRoaXMuX3N0b3JlZEVycm9yKTtcbiAgICB9XG5cbiAgICB0aGlzLl9yZXF1ZXN0cy5sZW5ndGggPSAwO1xuICAgIHRoaXMuX2NhY2hlZENodW5rcy5sZW5ndGggPSAwO1xuICB9XG5cbiAgX29uUHJvZ3Jlc3MoZXZ0KSB7XG4gICAgdGhpcy5vblByb2dyZXNzPy4oe1xuICAgICAgbG9hZGVkOiBldnQubG9hZGVkLFxuICAgICAgdG90YWw6IGV2dC5sZW5ndGhDb21wdXRhYmxlID8gZXZ0LnRvdGFsIDogdGhpcy5fY29udGVudExlbmd0aFxuICAgIH0pO1xuICB9XG5cbiAgZ2V0IGZpbGVuYW1lKCkge1xuICAgIHJldHVybiB0aGlzLl9maWxlbmFtZTtcbiAgfVxuXG4gIGdldCBpc1JhbmdlU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9pc1JhbmdlU3VwcG9ydGVkO1xuICB9XG5cbiAgZ2V0IGlzU3RyZWFtaW5nU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9pc1N0cmVhbWluZ1N1cHBvcnRlZDtcbiAgfVxuXG4gIGdldCBjb250ZW50TGVuZ3RoKCkge1xuICAgIHJldHVybiB0aGlzLl9jb250ZW50TGVuZ3RoO1xuICB9XG5cbiAgZ2V0IGhlYWRlcnNSZWFkeSgpIHtcbiAgICByZXR1cm4gdGhpcy5faGVhZGVyc1JlY2VpdmVkQ2FwYWJpbGl0eS5wcm9taXNlO1xuICB9XG5cbiAgYXN5bmMgcmVhZCgpIHtcbiAgICBpZiAodGhpcy5fc3RvcmVkRXJyb3IpIHtcbiAgICAgIHRocm93IHRoaXMuX3N0b3JlZEVycm9yO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9jYWNoZWRDaHVua3MubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgY2h1bmsgPSB0aGlzLl9jYWNoZWRDaHVua3Muc2hpZnQoKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWU6IGNodW5rLFxuICAgICAgICBkb25lOiBmYWxzZVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZG9uZSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgICAgZG9uZTogdHJ1ZVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCByZXF1ZXN0Q2FwYWJpbGl0eSA9ICgwLCBfdXRpbC5jcmVhdGVQcm9taXNlQ2FwYWJpbGl0eSkoKTtcblxuICAgIHRoaXMuX3JlcXVlc3RzLnB1c2gocmVxdWVzdENhcGFiaWxpdHkpO1xuXG4gICAgcmV0dXJuIHJlcXVlc3RDYXBhYmlsaXR5LnByb21pc2U7XG4gIH1cblxuICBjYW5jZWwocmVhc29uKSB7XG4gICAgdGhpcy5fZG9uZSA9IHRydWU7XG5cbiAgICB0aGlzLl9oZWFkZXJzUmVjZWl2ZWRDYXBhYmlsaXR5LnJlamVjdChyZWFzb24pO1xuXG4gICAgZm9yIChjb25zdCByZXF1ZXN0Q2FwYWJpbGl0eSBvZiB0aGlzLl9yZXF1ZXN0cykge1xuICAgICAgcmVxdWVzdENhcGFiaWxpdHkucmVzb2x2ZSh7XG4gICAgICAgIHZhbHVlOiB1bmRlZmluZWQsXG4gICAgICAgIGRvbmU6IHRydWVcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuX3JlcXVlc3RzLmxlbmd0aCA9IDA7XG5cbiAgICBpZiAodGhpcy5fbWFuYWdlci5pc1BlbmRpbmdSZXF1ZXN0KHRoaXMuX2Z1bGxSZXF1ZXN0SWQpKSB7XG4gICAgICB0aGlzLl9tYW5hZ2VyLmFib3J0UmVxdWVzdCh0aGlzLl9mdWxsUmVxdWVzdElkKTtcbiAgICB9XG5cbiAgICB0aGlzLl9mdWxsUmVxdWVzdFJlYWRlciA9IG51bGw7XG4gIH1cblxufVxuXG5jbGFzcyBQREZOZXR3b3JrU3RyZWFtUmFuZ2VSZXF1ZXN0UmVhZGVyIHtcbiAgY29uc3RydWN0b3IobWFuYWdlciwgYmVnaW4sIGVuZCkge1xuICAgIHRoaXMuX21hbmFnZXIgPSBtYW5hZ2VyO1xuICAgIGNvbnN0IGFyZ3MgPSB7XG4gICAgICBvbkRvbmU6IHRoaXMuX29uRG9uZS5iaW5kKHRoaXMpLFxuICAgICAgb25FcnJvcjogdGhpcy5fb25FcnJvci5iaW5kKHRoaXMpLFxuICAgICAgb25Qcm9ncmVzczogdGhpcy5fb25Qcm9ncmVzcy5iaW5kKHRoaXMpXG4gICAgfTtcbiAgICB0aGlzLl91cmwgPSBtYW5hZ2VyLnVybDtcbiAgICB0aGlzLl9yZXF1ZXN0SWQgPSBtYW5hZ2VyLnJlcXVlc3RSYW5nZShiZWdpbiwgZW5kLCBhcmdzKTtcbiAgICB0aGlzLl9yZXF1ZXN0cyA9IFtdO1xuICAgIHRoaXMuX3F1ZXVlZENodW5rID0gbnVsbDtcbiAgICB0aGlzLl9kb25lID0gZmFsc2U7XG4gICAgdGhpcy5fc3RvcmVkRXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5vblByb2dyZXNzID0gbnVsbDtcbiAgICB0aGlzLm9uQ2xvc2VkID0gbnVsbDtcbiAgfVxuXG4gIF9jbG9zZSgpIHtcbiAgICB0aGlzLm9uQ2xvc2VkPy4odGhpcyk7XG4gIH1cblxuICBfb25Eb25lKGRhdGEpIHtcbiAgICBjb25zdCBjaHVuayA9IGRhdGEuY2h1bms7XG5cbiAgICBpZiAodGhpcy5fcmVxdWVzdHMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgcmVxdWVzdENhcGFiaWxpdHkgPSB0aGlzLl9yZXF1ZXN0cy5zaGlmdCgpO1xuXG4gICAgICByZXF1ZXN0Q2FwYWJpbGl0eS5yZXNvbHZlKHtcbiAgICAgICAgdmFsdWU6IGNodW5rLFxuICAgICAgICBkb25lOiBmYWxzZVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3F1ZXVlZENodW5rID0gY2h1bms7XG4gICAgfVxuXG4gICAgdGhpcy5fZG9uZSA9IHRydWU7XG5cbiAgICBmb3IgKGNvbnN0IHJlcXVlc3RDYXBhYmlsaXR5IG9mIHRoaXMuX3JlcXVlc3RzKSB7XG4gICAgICByZXF1ZXN0Q2FwYWJpbGl0eS5yZXNvbHZlKHtcbiAgICAgICAgdmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgICAgZG9uZTogdHJ1ZVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5fcmVxdWVzdHMubGVuZ3RoID0gMDtcblxuICAgIHRoaXMuX2Nsb3NlKCk7XG4gIH1cblxuICBfb25FcnJvcihzdGF0dXMpIHtcbiAgICB0aGlzLl9zdG9yZWRFcnJvciA9ICgwLCBfbmV0d29ya191dGlscy5jcmVhdGVSZXNwb25zZVN0YXR1c0Vycm9yKShzdGF0dXMsIHRoaXMuX3VybCk7XG5cbiAgICBmb3IgKGNvbnN0IHJlcXVlc3RDYXBhYmlsaXR5IG9mIHRoaXMuX3JlcXVlc3RzKSB7XG4gICAgICByZXF1ZXN0Q2FwYWJpbGl0eS5yZWplY3QodGhpcy5fc3RvcmVkRXJyb3IpO1xuICAgIH1cblxuICAgIHRoaXMuX3JlcXVlc3RzLmxlbmd0aCA9IDA7XG4gICAgdGhpcy5fcXVldWVkQ2h1bmsgPSBudWxsO1xuICB9XG5cbiAgX29uUHJvZ3Jlc3MoZXZ0KSB7XG4gICAgaWYgKCF0aGlzLmlzU3RyZWFtaW5nU3VwcG9ydGVkKSB7XG4gICAgICB0aGlzLm9uUHJvZ3Jlc3M/Lih7XG4gICAgICAgIGxvYWRlZDogZXZ0LmxvYWRlZFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGlzU3RyZWFtaW5nU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGFzeW5jIHJlYWQoKSB7XG4gICAgaWYgKHRoaXMuX3N0b3JlZEVycm9yKSB7XG4gICAgICB0aHJvdyB0aGlzLl9zdG9yZWRFcnJvcjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fcXVldWVkQ2h1bmsgIT09IG51bGwpIHtcbiAgICAgIGNvbnN0IGNodW5rID0gdGhpcy5fcXVldWVkQ2h1bms7XG4gICAgICB0aGlzLl9xdWV1ZWRDaHVuayA9IG51bGw7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWx1ZTogY2h1bmssXG4gICAgICAgIGRvbmU6IGZhbHNlXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9kb25lKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWx1ZTogdW5kZWZpbmVkLFxuICAgICAgICBkb25lOiB0cnVlXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IHJlcXVlc3RDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuXG4gICAgdGhpcy5fcmVxdWVzdHMucHVzaChyZXF1ZXN0Q2FwYWJpbGl0eSk7XG5cbiAgICByZXR1cm4gcmVxdWVzdENhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxuXG4gIGNhbmNlbChyZWFzb24pIHtcbiAgICB0aGlzLl9kb25lID0gdHJ1ZTtcblxuICAgIGZvciAoY29uc3QgcmVxdWVzdENhcGFiaWxpdHkgb2YgdGhpcy5fcmVxdWVzdHMpIHtcbiAgICAgIHJlcXVlc3RDYXBhYmlsaXR5LnJlc29sdmUoe1xuICAgICAgICB2YWx1ZTogdW5kZWZpbmVkLFxuICAgICAgICBkb25lOiB0cnVlXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLl9yZXF1ZXN0cy5sZW5ndGggPSAwO1xuXG4gICAgaWYgKHRoaXMuX21hbmFnZXIuaXNQZW5kaW5nUmVxdWVzdCh0aGlzLl9yZXF1ZXN0SWQpKSB7XG4gICAgICB0aGlzLl9tYW5hZ2VyLmFib3J0UmVxdWVzdCh0aGlzLl9yZXF1ZXN0SWQpO1xuICAgIH1cblxuICAgIHRoaXMuX2Nsb3NlKCk7XG4gIH1cblxufVxuXG4vKioqLyB9KSxcbi8qIDI5ICovXG4vKioqLyAoKF9fdW51c2VkX3dlYnBhY2tfbW9kdWxlLCBleHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5leHBvcnRzLlBERkZldGNoU3RyZWFtID0gdm9pZCAwO1xuXG52YXIgX3V0aWwgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDEpO1xuXG52YXIgX25ldHdvcmtfdXRpbHMgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDI2KTtcblxuO1xuXG5mdW5jdGlvbiBjcmVhdGVGZXRjaE9wdGlvbnMoaGVhZGVycywgd2l0aENyZWRlbnRpYWxzLCBhYm9ydENvbnRyb2xsZXIpIHtcbiAgcmV0dXJuIHtcbiAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgaGVhZGVycyxcbiAgICBzaWduYWw6IGFib3J0Q29udHJvbGxlcj8uc2lnbmFsLFxuICAgIG1vZGU6IFwiY29yc1wiLFxuICAgIGNyZWRlbnRpYWxzOiB3aXRoQ3JlZGVudGlhbHMgPyBcImluY2x1ZGVcIiA6IFwic2FtZS1vcmlnaW5cIixcbiAgICByZWRpcmVjdDogXCJmb2xsb3dcIlxuICB9O1xufVxuXG5mdW5jdGlvbiBjcmVhdGVIZWFkZXJzKGh0dHBIZWFkZXJzKSB7XG4gIGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycygpO1xuXG4gIGZvciAoY29uc3QgcHJvcGVydHkgaW4gaHR0cEhlYWRlcnMpIHtcbiAgICBjb25zdCB2YWx1ZSA9IGh0dHBIZWFkZXJzW3Byb3BlcnR5XTtcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGhlYWRlcnMuYXBwZW5kKHByb3BlcnR5LCB2YWx1ZSk7XG4gIH1cblxuICByZXR1cm4gaGVhZGVycztcbn1cblxuY2xhc3MgUERGRmV0Y2hTdHJlYW0ge1xuICBjb25zdHJ1Y3Rvcihzb3VyY2UpIHtcbiAgICB0aGlzLnNvdXJjZSA9IHNvdXJjZTtcbiAgICB0aGlzLmlzSHR0cCA9IC9eaHR0cHM/Oi9pLnRlc3Qoc291cmNlLnVybCk7XG4gICAgdGhpcy5odHRwSGVhZGVycyA9IHRoaXMuaXNIdHRwICYmIHNvdXJjZS5odHRwSGVhZGVycyB8fCB7fTtcbiAgICB0aGlzLl9mdWxsUmVxdWVzdFJlYWRlciA9IG51bGw7XG4gICAgdGhpcy5fcmFuZ2VSZXF1ZXN0UmVhZGVycyA9IFtdO1xuICB9XG5cbiAgZ2V0IF9wcm9ncmVzc2l2ZURhdGFMZW5ndGgoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2Z1bGxSZXF1ZXN0UmVhZGVyPy5fbG9hZGVkID8/IDA7XG4gIH1cblxuICBnZXRGdWxsUmVhZGVyKCkge1xuICAgICgwLCBfdXRpbC5hc3NlcnQpKCF0aGlzLl9mdWxsUmVxdWVzdFJlYWRlciwgXCJQREZGZXRjaFN0cmVhbS5nZXRGdWxsUmVhZGVyIGNhbiBvbmx5IGJlIGNhbGxlZCBvbmNlLlwiKTtcbiAgICB0aGlzLl9mdWxsUmVxdWVzdFJlYWRlciA9IG5ldyBQREZGZXRjaFN0cmVhbVJlYWRlcih0aGlzKTtcbiAgICByZXR1cm4gdGhpcy5fZnVsbFJlcXVlc3RSZWFkZXI7XG4gIH1cblxuICBnZXRSYW5nZVJlYWRlcihiZWdpbiwgZW5kKSB7XG4gICAgaWYgKGVuZCA8PSB0aGlzLl9wcm9ncmVzc2l2ZURhdGFMZW5ndGgpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHJlYWRlciA9IG5ldyBQREZGZXRjaFN0cmVhbVJhbmdlUmVhZGVyKHRoaXMsIGJlZ2luLCBlbmQpO1xuXG4gICAgdGhpcy5fcmFuZ2VSZXF1ZXN0UmVhZGVycy5wdXNoKHJlYWRlcik7XG5cbiAgICByZXR1cm4gcmVhZGVyO1xuICB9XG5cbiAgY2FuY2VsQWxsUmVxdWVzdHMocmVhc29uKSB7XG4gICAgaWYgKHRoaXMuX2Z1bGxSZXF1ZXN0UmVhZGVyKSB7XG4gICAgICB0aGlzLl9mdWxsUmVxdWVzdFJlYWRlci5jYW5jZWwocmVhc29uKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHJlYWRlciBvZiB0aGlzLl9yYW5nZVJlcXVlc3RSZWFkZXJzLnNsaWNlKDApKSB7XG4gICAgICByZWFkZXIuY2FuY2VsKHJlYXNvbik7XG4gICAgfVxuICB9XG5cbn1cblxuZXhwb3J0cy5QREZGZXRjaFN0cmVhbSA9IFBERkZldGNoU3RyZWFtO1xuXG5jbGFzcyBQREZGZXRjaFN0cmVhbVJlYWRlciB7XG4gIGNvbnN0cnVjdG9yKHN0cmVhbSkge1xuICAgIHRoaXMuX3N0cmVhbSA9IHN0cmVhbTtcbiAgICB0aGlzLl9yZWFkZXIgPSBudWxsO1xuICAgIHRoaXMuX2xvYWRlZCA9IDA7XG4gICAgdGhpcy5fZmlsZW5hbWUgPSBudWxsO1xuICAgIGNvbnN0IHNvdXJjZSA9IHN0cmVhbS5zb3VyY2U7XG4gICAgdGhpcy5fd2l0aENyZWRlbnRpYWxzID0gc291cmNlLndpdGhDcmVkZW50aWFscyB8fCBmYWxzZTtcbiAgICB0aGlzLl9jb250ZW50TGVuZ3RoID0gc291cmNlLmxlbmd0aDtcbiAgICB0aGlzLl9oZWFkZXJzQ2FwYWJpbGl0eSA9ICgwLCBfdXRpbC5jcmVhdGVQcm9taXNlQ2FwYWJpbGl0eSkoKTtcbiAgICB0aGlzLl9kaXNhYmxlUmFuZ2UgPSBzb3VyY2UuZGlzYWJsZVJhbmdlIHx8IGZhbHNlO1xuICAgIHRoaXMuX3JhbmdlQ2h1bmtTaXplID0gc291cmNlLnJhbmdlQ2h1bmtTaXplO1xuXG4gICAgaWYgKCF0aGlzLl9yYW5nZUNodW5rU2l6ZSAmJiAhdGhpcy5fZGlzYWJsZVJhbmdlKSB7XG4gICAgICB0aGlzLl9kaXNhYmxlUmFuZ2UgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgQWJvcnRDb250cm9sbGVyICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICB0aGlzLl9hYm9ydENvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgfVxuXG4gICAgdGhpcy5faXNTdHJlYW1pbmdTdXBwb3J0ZWQgPSAhc291cmNlLmRpc2FibGVTdHJlYW07XG4gICAgdGhpcy5faXNSYW5nZVN1cHBvcnRlZCA9ICFzb3VyY2UuZGlzYWJsZVJhbmdlO1xuICAgIHRoaXMuX2hlYWRlcnMgPSBjcmVhdGVIZWFkZXJzKHRoaXMuX3N0cmVhbS5odHRwSGVhZGVycyk7XG4gICAgY29uc3QgdXJsID0gc291cmNlLnVybDtcbiAgICBmZXRjaCh1cmwsIGNyZWF0ZUZldGNoT3B0aW9ucyh0aGlzLl9oZWFkZXJzLCB0aGlzLl93aXRoQ3JlZGVudGlhbHMsIHRoaXMuX2Fib3J0Q29udHJvbGxlcikpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgaWYgKCEoMCwgX25ldHdvcmtfdXRpbHMudmFsaWRhdGVSZXNwb25zZVN0YXR1cykocmVzcG9uc2Uuc3RhdHVzKSkge1xuICAgICAgICB0aHJvdyAoMCwgX25ldHdvcmtfdXRpbHMuY3JlYXRlUmVzcG9uc2VTdGF0dXNFcnJvcikocmVzcG9uc2Uuc3RhdHVzLCB1cmwpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9yZWFkZXIgPSByZXNwb25zZS5ib2R5LmdldFJlYWRlcigpO1xuXG4gICAgICB0aGlzLl9oZWFkZXJzQ2FwYWJpbGl0eS5yZXNvbHZlKCk7XG5cbiAgICAgIGNvbnN0IGdldFJlc3BvbnNlSGVhZGVyID0gbmFtZSA9PiB7XG4gICAgICAgIHJldHVybiByZXNwb25zZS5oZWFkZXJzLmdldChuYW1lKTtcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHtcbiAgICAgICAgYWxsb3dSYW5nZVJlcXVlc3RzLFxuICAgICAgICBzdWdnZXN0ZWRMZW5ndGhcbiAgICAgIH0gPSAoMCwgX25ldHdvcmtfdXRpbHMudmFsaWRhdGVSYW5nZVJlcXVlc3RDYXBhYmlsaXRpZXMpKHtcbiAgICAgICAgZ2V0UmVzcG9uc2VIZWFkZXIsXG4gICAgICAgIGlzSHR0cDogdGhpcy5fc3RyZWFtLmlzSHR0cCxcbiAgICAgICAgcmFuZ2VDaHVua1NpemU6IHRoaXMuX3JhbmdlQ2h1bmtTaXplLFxuICAgICAgICBkaXNhYmxlUmFuZ2U6IHRoaXMuX2Rpc2FibGVSYW5nZVxuICAgICAgfSk7XG4gICAgICB0aGlzLl9pc1JhbmdlU3VwcG9ydGVkID0gYWxsb3dSYW5nZVJlcXVlc3RzO1xuICAgICAgdGhpcy5fY29udGVudExlbmd0aCA9IHN1Z2dlc3RlZExlbmd0aCB8fCB0aGlzLl9jb250ZW50TGVuZ3RoO1xuICAgICAgdGhpcy5fZmlsZW5hbWUgPSAoMCwgX25ldHdvcmtfdXRpbHMuZXh0cmFjdEZpbGVuYW1lRnJvbUhlYWRlcikoZ2V0UmVzcG9uc2VIZWFkZXIpO1xuXG4gICAgICBpZiAoIXRoaXMuX2lzU3RyZWFtaW5nU3VwcG9ydGVkICYmIHRoaXMuX2lzUmFuZ2VTdXBwb3J0ZWQpIHtcbiAgICAgICAgdGhpcy5jYW5jZWwobmV3IF91dGlsLkFib3J0RXhjZXB0aW9uKFwiU3RyZWFtaW5nIGlzIGRpc2FibGVkLlwiKSk7XG4gICAgICB9XG4gICAgfSkuY2F0Y2godGhpcy5faGVhZGVyc0NhcGFiaWxpdHkucmVqZWN0KTtcbiAgICB0aGlzLm9uUHJvZ3Jlc3MgPSBudWxsO1xuICB9XG5cbiAgZ2V0IGhlYWRlcnNSZWFkeSgpIHtcbiAgICByZXR1cm4gdGhpcy5faGVhZGVyc0NhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxuXG4gIGdldCBmaWxlbmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fZmlsZW5hbWU7XG4gIH1cblxuICBnZXQgY29udGVudExlbmd0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5fY29udGVudExlbmd0aDtcbiAgfVxuXG4gIGdldCBpc1JhbmdlU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9pc1JhbmdlU3VwcG9ydGVkO1xuICB9XG5cbiAgZ2V0IGlzU3RyZWFtaW5nU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9pc1N0cmVhbWluZ1N1cHBvcnRlZDtcbiAgfVxuXG4gIGFzeW5jIHJlYWQoKSB7XG4gICAgYXdhaXQgdGhpcy5faGVhZGVyc0NhcGFiaWxpdHkucHJvbWlzZTtcbiAgICBjb25zdCB7XG4gICAgICB2YWx1ZSxcbiAgICAgIGRvbmVcbiAgICB9ID0gYXdhaXQgdGhpcy5fcmVhZGVyLnJlYWQoKTtcblxuICAgIGlmIChkb25lKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWx1ZSxcbiAgICAgICAgZG9uZVxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2FkZWQgKz0gdmFsdWUuYnl0ZUxlbmd0aDtcblxuICAgIGlmICh0aGlzLm9uUHJvZ3Jlc3MpIHtcbiAgICAgIHRoaXMub25Qcm9ncmVzcyh7XG4gICAgICAgIGxvYWRlZDogdGhpcy5fbG9hZGVkLFxuICAgICAgICB0b3RhbDogdGhpcy5fY29udGVudExlbmd0aFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkodmFsdWUpLmJ1ZmZlcjtcbiAgICByZXR1cm4ge1xuICAgICAgdmFsdWU6IGJ1ZmZlcixcbiAgICAgIGRvbmU6IGZhbHNlXG4gICAgfTtcbiAgfVxuXG4gIGNhbmNlbChyZWFzb24pIHtcbiAgICBpZiAodGhpcy5fcmVhZGVyKSB7XG4gICAgICB0aGlzLl9yZWFkZXIuY2FuY2VsKHJlYXNvbik7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2Fib3J0Q29udHJvbGxlcikge1xuICAgICAgdGhpcy5fYWJvcnRDb250cm9sbGVyLmFib3J0KCk7XG4gICAgfVxuICB9XG5cbn1cblxuY2xhc3MgUERGRmV0Y2hTdHJlYW1SYW5nZVJlYWRlciB7XG4gIGNvbnN0cnVjdG9yKHN0cmVhbSwgYmVnaW4sIGVuZCkge1xuICAgIHRoaXMuX3N0cmVhbSA9IHN0cmVhbTtcbiAgICB0aGlzLl9yZWFkZXIgPSBudWxsO1xuICAgIHRoaXMuX2xvYWRlZCA9IDA7XG4gICAgY29uc3Qgc291cmNlID0gc3RyZWFtLnNvdXJjZTtcbiAgICB0aGlzLl93aXRoQ3JlZGVudGlhbHMgPSBzb3VyY2Uud2l0aENyZWRlbnRpYWxzIHx8IGZhbHNlO1xuICAgIHRoaXMuX3JlYWRDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgIHRoaXMuX2lzU3RyZWFtaW5nU3VwcG9ydGVkID0gIXNvdXJjZS5kaXNhYmxlU3RyZWFtO1xuXG4gICAgaWYgKHR5cGVvZiBBYm9ydENvbnRyb2xsZXIgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgIHRoaXMuX2Fib3J0Q29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9oZWFkZXJzID0gY3JlYXRlSGVhZGVycyh0aGlzLl9zdHJlYW0uaHR0cEhlYWRlcnMpO1xuXG4gICAgdGhpcy5faGVhZGVycy5hcHBlbmQoXCJSYW5nZVwiLCBgYnl0ZXM9JHtiZWdpbn0tJHtlbmQgLSAxfWApO1xuXG4gICAgY29uc3QgdXJsID0gc291cmNlLnVybDtcbiAgICBmZXRjaCh1cmwsIGNyZWF0ZUZldGNoT3B0aW9ucyh0aGlzLl9oZWFkZXJzLCB0aGlzLl93aXRoQ3JlZGVudGlhbHMsIHRoaXMuX2Fib3J0Q29udHJvbGxlcikpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgaWYgKCEoMCwgX25ldHdvcmtfdXRpbHMudmFsaWRhdGVSZXNwb25zZVN0YXR1cykocmVzcG9uc2Uuc3RhdHVzKSkge1xuICAgICAgICB0aHJvdyAoMCwgX25ldHdvcmtfdXRpbHMuY3JlYXRlUmVzcG9uc2VTdGF0dXNFcnJvcikocmVzcG9uc2Uuc3RhdHVzLCB1cmwpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9yZWFkQ2FwYWJpbGl0eS5yZXNvbHZlKCk7XG5cbiAgICAgIHRoaXMuX3JlYWRlciA9IHJlc3BvbnNlLmJvZHkuZ2V0UmVhZGVyKCk7XG4gICAgfSkuY2F0Y2godGhpcy5fcmVhZENhcGFiaWxpdHkucmVqZWN0KTtcbiAgICB0aGlzLm9uUHJvZ3Jlc3MgPSBudWxsO1xuICB9XG5cbiAgZ2V0IGlzU3RyZWFtaW5nU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9pc1N0cmVhbWluZ1N1cHBvcnRlZDtcbiAgfVxuXG4gIGFzeW5jIHJlYWQoKSB7XG4gICAgYXdhaXQgdGhpcy5fcmVhZENhcGFiaWxpdHkucHJvbWlzZTtcbiAgICBjb25zdCB7XG4gICAgICB2YWx1ZSxcbiAgICAgIGRvbmVcbiAgICB9ID0gYXdhaXQgdGhpcy5fcmVhZGVyLnJlYWQoKTtcblxuICAgIGlmIChkb25lKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWx1ZSxcbiAgICAgICAgZG9uZVxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2FkZWQgKz0gdmFsdWUuYnl0ZUxlbmd0aDtcblxuICAgIGlmICh0aGlzLm9uUHJvZ3Jlc3MpIHtcbiAgICAgIHRoaXMub25Qcm9ncmVzcyh7XG4gICAgICAgIGxvYWRlZDogdGhpcy5fbG9hZGVkXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBidWZmZXIgPSBuZXcgVWludDhBcnJheSh2YWx1ZSkuYnVmZmVyO1xuICAgIHJldHVybiB7XG4gICAgICB2YWx1ZTogYnVmZmVyLFxuICAgICAgZG9uZTogZmFsc2VcbiAgICB9O1xuICB9XG5cbiAgY2FuY2VsKHJlYXNvbikge1xuICAgIGlmICh0aGlzLl9yZWFkZXIpIHtcbiAgICAgIHRoaXMuX3JlYWRlci5jYW5jZWwocmVhc29uKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fYWJvcnRDb250cm9sbGVyKSB7XG4gICAgICB0aGlzLl9hYm9ydENvbnRyb2xsZXIuYWJvcnQoKTtcbiAgICB9XG4gIH1cblxufVxuXG4vKioqLyB9KVxuLyoqKioqKi8gXHRdKTtcbi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKioqKioqLyBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbi8qKioqKiovIFx0dmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuLyoqKioqKi8gXHRcbi8qKioqKiovIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbi8qKioqKiovIFx0ZnVuY3Rpb24gX193X3BkZmpzX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuLyoqKioqKi8gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuLyoqKioqKi8gXHRcdHZhciBjYWNoZWRNb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdO1xuLyoqKioqKi8gXHRcdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuLyoqKioqKi8gXHRcdFx0cmV0dXJuIGNhY2hlZE1vZHVsZS5leHBvcnRzO1xuLyoqKioqKi8gXHRcdH1cbi8qKioqKiovIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuLyoqKioqKi8gXHRcdHZhciBtb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdID0ge1xuLyoqKioqKi8gXHRcdFx0Ly8gbm8gbW9kdWxlLmlkIG5lZWRlZFxuLyoqKioqKi8gXHRcdFx0Ly8gbm8gbW9kdWxlLmxvYWRlZCBuZWVkZWRcbi8qKioqKiovIFx0XHRcdGV4cG9ydHM6IHt9XG4vKioqKioqLyBcdFx0fTtcbi8qKioqKiovIFx0XG4vKioqKioqLyBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4vKioqKioqLyBcdFx0X193ZWJwYWNrX21vZHVsZXNfX1ttb2R1bGVJZF0obW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXyk7XG4vKioqKioqLyBcdFxuLyoqKioqKi8gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4vKioqKioqLyBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuLyoqKioqKi8gXHR9XG4vKioqKioqLyBcdFxuLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbnZhciBfX3dlYnBhY2tfZXhwb3J0c19fID0ge307XG4vLyBUaGlzIGVudHJ5IG5lZWQgdG8gYmUgd3JhcHBlZCBpbiBhbiBJSUZFIGJlY2F1c2UgaXQgbmVlZCB0byBiZSBpc29sYXRlZCBhZ2FpbnN0IG90aGVyIG1vZHVsZXMgaW4gdGhlIGNodW5rLlxuKCgpID0+IHtcbnZhciBleHBvcnRzID0gX193ZWJwYWNrX2V4cG9ydHNfXztcblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJBbm5vdGF0aW9uTGF5ZXJcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF9hbm5vdGF0aW9uX2xheWVyLkFubm90YXRpb25MYXllcjtcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQW5ub3RhdGlvbk1vZGVcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF91dGlsLkFubm90YXRpb25Nb2RlO1xuICB9XG59KSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJDTWFwQ29tcHJlc3Npb25UeXBlXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdXRpbC5DTWFwQ29tcHJlc3Npb25UeXBlO1xuICB9XG59KSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJHbG9iYWxXb3JrZXJPcHRpb25zXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfd29ya2VyX29wdGlvbnMuR2xvYmFsV29ya2VyT3B0aW9ucztcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiSW52YWxpZFBERkV4Y2VwdGlvblwiLCAoe1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3V0aWwuSW52YWxpZFBERkV4Y2VwdGlvbjtcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiTG9vcGJhY2tQb3J0XCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfYXBpLkxvb3BiYWNrUG9ydDtcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiTWlzc2luZ1BERkV4Y2VwdGlvblwiLCAoe1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3V0aWwuTWlzc2luZ1BERkV4Y2VwdGlvbjtcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiT1BTXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdXRpbC5PUFM7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlBERkRhdGFSYW5nZVRyYW5zcG9ydFwiLCAoe1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX2FwaS5QREZEYXRhUmFuZ2VUcmFuc3BvcnQ7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlBERkRhdGVTdHJpbmdcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF9kaXNwbGF5X3V0aWxzLlBERkRhdGVTdHJpbmc7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlBERldvcmtlclwiLCAoe1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX2FwaS5QREZXb3JrZXI7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlBhc3N3b3JkUmVzcG9uc2VzXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdXRpbC5QYXNzd29yZFJlc3BvbnNlcztcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiUGVybWlzc2lvbkZsYWdcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF91dGlsLlBlcm1pc3Npb25GbGFnO1xuICB9XG59KSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJQaXhlbHNQZXJJbmNoXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfZGlzcGxheV91dGlscy5QaXhlbHNQZXJJbmNoO1xuICB9XG59KSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJSZW5kZXJpbmdDYW5jZWxsZWRFeGNlcHRpb25cIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF9kaXNwbGF5X3V0aWxzLlJlbmRlcmluZ0NhbmNlbGxlZEV4Y2VwdGlvbjtcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiU1ZHR3JhcGhpY3NcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF9zdmcuU1ZHR3JhcGhpY3M7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlVOU1VQUE9SVEVEX0ZFQVRVUkVTXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdXRpbC5VTlNVUFBPUlRFRF9GRUFUVVJFUztcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiVW5leHBlY3RlZFJlc3BvbnNlRXhjZXB0aW9uXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdXRpbC5VbmV4cGVjdGVkUmVzcG9uc2VFeGNlcHRpb247XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlV0aWxcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF91dGlsLlV0aWw7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlZlcmJvc2l0eUxldmVsXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdXRpbC5WZXJib3NpdHlMZXZlbDtcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiWGZhTGF5ZXJcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF94ZmFfbGF5ZXIuWGZhTGF5ZXI7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImJ1aWxkXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfYXBpLmJ1aWxkO1xuICB9XG59KSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJjcmVhdGVQcm9taXNlQ2FwYWJpbGl0eVwiLCAoe1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHk7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImNyZWF0ZVZhbGlkQWJzb2x1dGVVcmxcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF91dGlsLmNyZWF0ZVZhbGlkQWJzb2x1dGVVcmw7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImdldERvY3VtZW50XCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfYXBpLmdldERvY3VtZW50O1xuICB9XG59KSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJnZXRGaWxlbmFtZUZyb21VcmxcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF9kaXNwbGF5X3V0aWxzLmdldEZpbGVuYW1lRnJvbVVybDtcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiZ2V0UGRmRmlsZW5hbWVGcm9tVXJsXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfZGlzcGxheV91dGlscy5nZXRQZGZGaWxlbmFtZUZyb21Vcmw7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImdldFhmYVBhZ2VWaWV3cG9ydFwiLCAoe1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX2Rpc3BsYXlfdXRpbHMuZ2V0WGZhUGFnZVZpZXdwb3J0O1xuICB9XG59KSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJpc1BkZkZpbGVcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF9kaXNwbGF5X3V0aWxzLmlzUGRmRmlsZTtcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwibG9hZFNjcmlwdFwiLCAoe1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX2Rpc3BsYXlfdXRpbHMubG9hZFNjcmlwdDtcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicmVuZGVyVGV4dExheWVyXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdGV4dF9sYXllci5yZW5kZXJUZXh0TGF5ZXI7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInNoYWRvd1wiLCAoe1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3V0aWwuc2hhZG93O1xuICB9XG59KSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ2ZXJzaW9uXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfYXBpLnZlcnNpb247XG4gIH1cbn0pKTtcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxudmFyIF9hcGkgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDQpO1xuXG52YXIgX2Rpc3BsYXlfdXRpbHMgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDUpO1xuXG52YXIgX2Fubm90YXRpb25fbGF5ZXIgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDIwKTtcblxudmFyIF93b3JrZXJfb3B0aW9ucyA9IF9fd19wZGZqc19yZXF1aXJlX18oMTMpO1xuXG52YXIgX2lzX25vZGUgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDMpO1xuXG52YXIgX3RleHRfbGF5ZXIgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDIzKTtcblxudmFyIF9zdmcgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDI0KTtcblxudmFyIF94ZmFfbGF5ZXIgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDIyKTtcblxuY29uc3QgcGRmanNWZXJzaW9uID0gJzIuMTQuMzA1JztcbmNvbnN0IHBkZmpzQnVpbGQgPSAnZWFhYThiNGFkJztcbntcbiAgaWYgKF9pc19ub2RlLmlzTm9kZUpTKSB7XG4gICAgY29uc3Qge1xuICAgICAgUERGTm9kZVN0cmVhbVxuICAgIH0gPSBfX3dfcGRmanNfcmVxdWlyZV9fKDI1KTtcblxuICAgICgwLCBfYXBpLnNldFBERk5ldHdvcmtTdHJlYW1GYWN0b3J5KShwYXJhbXMgPT4ge1xuICAgICAgcmV0dXJuIG5ldyBQREZOb2RlU3RyZWFtKHBhcmFtcyk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3Qge1xuICAgICAgUERGTmV0d29ya1N0cmVhbVxuICAgIH0gPSBfX3dfcGRmanNfcmVxdWlyZV9fKDI4KTtcblxuICAgIGNvbnN0IHtcbiAgICAgIFBERkZldGNoU3RyZWFtXG4gICAgfSA9IF9fd19wZGZqc19yZXF1aXJlX18oMjkpO1xuXG4gICAgKDAsIF9hcGkuc2V0UERGTmV0d29ya1N0cmVhbUZhY3RvcnkpKHBhcmFtcyA9PiB7XG4gICAgICBpZiAoKDAsIF9kaXNwbGF5X3V0aWxzLmlzVmFsaWRGZXRjaFVybCkocGFyYW1zLnVybCkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQREZGZXRjaFN0cmVhbShwYXJhbXMpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbmV3IFBERk5ldHdvcmtTdHJlYW0ocGFyYW1zKTtcbiAgICB9KTtcbiAgfVxufVxufSkoKTtcblxuLyoqKioqKi8gXHRyZXR1cm4gX193ZWJwYWNrX2V4cG9ydHNfXztcbi8qKioqKiovIH0pKClcbjtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGRmLmpzLm1hcCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///299\n')},703:(module,__unused_webpack_exports,__webpack_require__)=>{"use strict";eval("/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\n\nvar ReactPropTypesSecret = __webpack_require__(268);\n\nfunction emptyFunction() {}\nfunction emptyFunctionWithReset() {}\nemptyFunctionWithReset.resetWarningCache = emptyFunction;\n\nmodule.exports = function() {\n function shim(props, propName, componentName, location, propFullName, secret) {\n if (secret === ReactPropTypesSecret) {\n // It is still safe when called from React.\n return;\n }\n var err = new Error(\n 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +\n 'Use PropTypes.checkPropTypes() to call them. ' +\n 'Read more at http://fb.me/use-check-prop-types'\n );\n err.name = 'Invariant Violation';\n throw err;\n };\n shim.isRequired = shim;\n function getShim() {\n return shim;\n };\n // Important!\n // Keep this list in sync with production version in `./factoryWithTypeCheckers.js`.\n var ReactPropTypes = {\n array: shim,\n bool: shim,\n func: shim,\n number: shim,\n object: shim,\n string: shim,\n symbol: shim,\n\n any: shim,\n arrayOf: getShim,\n element: shim,\n elementType: shim,\n instanceOf: getShim,\n node: shim,\n objectOf: getShim,\n oneOf: getShim,\n oneOfType: getShim,\n shape: getShim,\n exact: getShim,\n\n checkPropTypes: emptyFunctionWithReset,\n resetWarningCache: emptyFunction\n };\n\n ReactPropTypes.PropTypes = ReactPropTypes;\n\n return ReactPropTypes;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9wcm9wLXR5cGVzL2ZhY3RvcnlXaXRoVGhyb3dpbmdTaGltcy5qcz9kN2EwIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFYTs7QUFFYiwyQkFBMkIsbUJBQU8sQ0FBQyxHQUE0Qjs7QUFFL0Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EiLCJmaWxlIjoiNzAzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtcHJlc2VudCwgRmFjZWJvb2ssIEluYy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBSZWFjdFByb3BUeXBlc1NlY3JldCA9IHJlcXVpcmUoJy4vbGliL1JlYWN0UHJvcFR5cGVzU2VjcmV0Jyk7XG5cbmZ1bmN0aW9uIGVtcHR5RnVuY3Rpb24oKSB7fVxuZnVuY3Rpb24gZW1wdHlGdW5jdGlvbldpdGhSZXNldCgpIHt9XG5lbXB0eUZ1bmN0aW9uV2l0aFJlc2V0LnJlc2V0V2FybmluZ0NhY2hlID0gZW1wdHlGdW5jdGlvbjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbigpIHtcbiAgZnVuY3Rpb24gc2hpbShwcm9wcywgcHJvcE5hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBwcm9wRnVsbE5hbWUsIHNlY3JldCkge1xuICAgIGlmIChzZWNyZXQgPT09IFJlYWN0UHJvcFR5cGVzU2VjcmV0KSB7XG4gICAgICAvLyBJdCBpcyBzdGlsbCBzYWZlIHdoZW4gY2FsbGVkIGZyb20gUmVhY3QuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoXG4gICAgICAnQ2FsbGluZyBQcm9wVHlwZXMgdmFsaWRhdG9ycyBkaXJlY3RseSBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBgcHJvcC10eXBlc2AgcGFja2FnZS4gJyArXG4gICAgICAnVXNlIFByb3BUeXBlcy5jaGVja1Byb3BUeXBlcygpIHRvIGNhbGwgdGhlbS4gJyArXG4gICAgICAnUmVhZCBtb3JlIGF0IGh0dHA6Ly9mYi5tZS91c2UtY2hlY2stcHJvcC10eXBlcydcbiAgICApO1xuICAgIGVyci5uYW1lID0gJ0ludmFyaWFudCBWaW9sYXRpb24nO1xuICAgIHRocm93IGVycjtcbiAgfTtcbiAgc2hpbS5pc1JlcXVpcmVkID0gc2hpbTtcbiAgZnVuY3Rpb24gZ2V0U2hpbSgpIHtcbiAgICByZXR1cm4gc2hpbTtcbiAgfTtcbiAgLy8gSW1wb3J0YW50IVxuICAvLyBLZWVwIHRoaXMgbGlzdCBpbiBzeW5jIHdpdGggcHJvZHVjdGlvbiB2ZXJzaW9uIGluIGAuL2ZhY3RvcnlXaXRoVHlwZUNoZWNrZXJzLmpzYC5cbiAgdmFyIFJlYWN0UHJvcFR5cGVzID0ge1xuICAgIGFycmF5OiBzaGltLFxuICAgIGJvb2w6IHNoaW0sXG4gICAgZnVuYzogc2hpbSxcbiAgICBudW1iZXI6IHNoaW0sXG4gICAgb2JqZWN0OiBzaGltLFxuICAgIHN0cmluZzogc2hpbSxcbiAgICBzeW1ib2w6IHNoaW0sXG5cbiAgICBhbnk6IHNoaW0sXG4gICAgYXJyYXlPZjogZ2V0U2hpbSxcbiAgICBlbGVtZW50OiBzaGltLFxuICAgIGVsZW1lbnRUeXBlOiBzaGltLFxuICAgIGluc3RhbmNlT2Y6IGdldFNoaW0sXG4gICAgbm9kZTogc2hpbSxcbiAgICBvYmplY3RPZjogZ2V0U2hpbSxcbiAgICBvbmVPZjogZ2V0U2hpbSxcbiAgICBvbmVPZlR5cGU6IGdldFNoaW0sXG4gICAgc2hhcGU6IGdldFNoaW0sXG4gICAgZXhhY3Q6IGdldFNoaW0sXG5cbiAgICBjaGVja1Byb3BUeXBlczogZW1wdHlGdW5jdGlvbldpdGhSZXNldCxcbiAgICByZXNldFdhcm5pbmdDYWNoZTogZW1wdHlGdW5jdGlvblxuICB9O1xuXG4gIFJlYWN0UHJvcFR5cGVzLlByb3BUeXBlcyA9IFJlYWN0UHJvcFR5cGVzO1xuXG4gIHJldHVybiBSZWFjdFByb3BUeXBlcztcbn07XG4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///703\n")},697:(module,__unused_webpack_exports,__webpack_require__)=>{eval("/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nif (false) { var throwOnDirectAccess, ReactIs; } else {\n // By explicitly using `prop-types` you are opting into new production behavior.\n // http://fb.me/prop-types-in-prod\n module.exports = __webpack_require__(703)();\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9wcm9wLXR5cGVzL2luZGV4LmpzP2Q3YmMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLElBQUksS0FBcUMsRUFBRSxxQ0FPMUM7QUFDRDtBQUNBO0FBQ0EsbUJBQW1CLG1CQUFPLENBQUMsR0FBNEI7QUFDdkQiLCJmaWxlIjoiNjk3LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtcHJlc2VudCwgRmFjZWJvb2ssIEluYy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICB2YXIgUmVhY3RJcyA9IHJlcXVpcmUoJ3JlYWN0LWlzJyk7XG5cbiAgLy8gQnkgZXhwbGljaXRseSB1c2luZyBgcHJvcC10eXBlc2AgeW91IGFyZSBvcHRpbmcgaW50byBuZXcgZGV2ZWxvcG1lbnQgYmVoYXZpb3IuXG4gIC8vIGh0dHA6Ly9mYi5tZS9wcm9wLXR5cGVzLWluLXByb2RcbiAgdmFyIHRocm93T25EaXJlY3RBY2Nlc3MgPSB0cnVlO1xuICBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZmFjdG9yeVdpdGhUeXBlQ2hlY2tlcnMnKShSZWFjdElzLmlzRWxlbWVudCwgdGhyb3dPbkRpcmVjdEFjY2Vzcyk7XG59IGVsc2Uge1xuICAvLyBCeSBleHBsaWNpdGx5IHVzaW5nIGBwcm9wLXR5cGVzYCB5b3UgYXJlIG9wdGluZyBpbnRvIG5ldyBwcm9kdWN0aW9uIGJlaGF2aW9yLlxuICAvLyBodHRwOi8vZmIubWUvcHJvcC10eXBlcy1pbi1wcm9kXG4gIG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9mYWN0b3J5V2l0aFRocm93aW5nU2hpbXMnKSgpO1xufVxuIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///697\n")},268:module=>{"use strict";eval("/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\n\nvar ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';\n\nmodule.exports = ReactPropTypesSecret;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9wcm9wLXR5cGVzL2xpYi9SZWFjdFByb3BUeXBlc1NlY3JldC5qcz81OWIwIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFYTs7QUFFYjs7QUFFQSIsImZpbGUiOiIyNjguanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvcHlyaWdodCAoYykgMjAxMy1wcmVzZW50LCBGYWNlYm9vaywgSW5jLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIFJlYWN0UHJvcFR5cGVzU2VjcmV0ID0gJ1NFQ1JFVF9ET19OT1RfUEFTU19USElTX09SX1lPVV9XSUxMX0JFX0ZJUkVEJztcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdFByb3BUeXBlc1NlY3JldDtcbiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///268\n")},188:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval('\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n "default": () => (/* binding */ index)\n});\n\n// UNUSED EXPORTS: BoundingBox, ContextProvider, DocumentContext, DocumentWrapper, DownloadButton, HighlightOverlay, Outline, OutlineItem, Overlay, PageNumberControl, PageWrapper, ScrollContext, TransformContext, UiContext, ZoomInButton, ZoomOutButton, computeBoundingBoxStyle, computePageStyle, generatePageIdFromIndex, getPageHeight, getPageWidth, isSideways, rotateClockwise, rotateCounterClockwise, scaleRawBoundingBox, scrollToId, scrollToPdfPageIndex\n\n// EXTERNAL MODULE: ./node_modules/classnames/index.js\nvar classnames = __webpack_require__(184);\nvar classnames_default = /*#__PURE__*/__webpack_require__.n(classnames);\n// EXTERNAL MODULE: external {"commonjs":"react","commonjs2":"react","amd":"react","root":"React"}\nvar external_commonjs_react_commonjs2_react_amd_react_root_React_ = __webpack_require__(888);\nvar external_commonjs_react_commonjs2_react_amd_react_root_React_default = /*#__PURE__*/__webpack_require__.n(external_commonjs_react_commonjs2_react_amd_react_root_React_);\n;// CONCATENATED MODULE: ./src/utils/provider.ts\nfunction logProviderWarning(functionName, providerName) {\n console.warn(`Unable to call ${functionName}. The ${providerName} Provider may not be set up correctly.`);\n}\n\n;// CONCATENATED MODULE: ./src/utils/rotate.ts\nvar PageRotation;\n(function (PageRotation) {\n PageRotation[PageRotation["Rotate0"] = 0] = "Rotate0";\n PageRotation[PageRotation["Rotate90"] = 90] = "Rotate90";\n PageRotation[PageRotation["Rotate180"] = 180] = "Rotate180";\n PageRotation[PageRotation["Rotate270"] = 270] = "Rotate270";\n})(PageRotation || (PageRotation = {}));\nfunction rotateClockwise(rotation) {\n switch (rotation) {\n case PageRotation.Rotate0:\n return PageRotation.Rotate90;\n case PageRotation.Rotate90:\n return PageRotation.Rotate180;\n case PageRotation.Rotate180:\n return PageRotation.Rotate270;\n default:\n return PageRotation.Rotate0;\n }\n}\nfunction rotateCounterClockwise(rotation) {\n switch (rotation) {\n case PageRotation.Rotate0:\n return PageRotation.Rotate270;\n case PageRotation.Rotate90:\n return PageRotation.Rotate0;\n case PageRotation.Rotate180:\n return PageRotation.Rotate90;\n default:\n return PageRotation.Rotate180;\n }\n}\n/**\n * Tests whether the page is rotated 90 degrees clockwise or counterclockwise from zero,\n * e.g. whether the page "is rotated sideways."\n */\nfunction isSideways(rotation) {\n return rotation === PageRotation.Rotate90 || rotation === PageRotation.Rotate270;\n}\n\n;// CONCATENATED MODULE: ./src/utils/scroll.ts\n\n// Each page div is ID\'d according to page index\n// e.g. reader_pg_0, reader_pg_1, etc.\nconst PAGE_NAV_TARGET_ID_ROOT = \'reader_pg_\';\nconst PDF_HEIGHT_POINTS = 792;\nconst PDF_WIDTH_POINTS = 612;\nfunction generatePageIdFromIndex(pageIndex) {\n return `${PAGE_NAV_TARGET_ID_ROOT}${pageIndex}`;\n}\nfunction scrollToId(id) {\n const element = document.getElementById(id);\n if (element) {\n element.scrollIntoView({ behavior: \'smooth\', block: \'start\', inline: \'center\' });\n }\n else {\n console.error(`Could not find scroll target with ID #${id}`);\n }\n}\nfunction scrollToPdfPageIndex(pageIndex) {\n scrollToId(generatePageIdFromIndex(pageIndex));\n}\n/**\n * Scroll PDF document to a specific position.\n * @param pageIndex The index of the page where the position locates at\n * @param leftPoints The horizontal distance between the origin and the position (in PDF coordinates)\n * @param bottomPoints The vertical distance between the origin and the position (in PDF coordinates)\n * @param rotation The rotation degree of the document\n */\nfunction scrollToPosition(pageIndex, leftPoints, bottomPoints, rotation = PageRotation.Rotate0) {\n /*\n Vertical scroll distance is calculated as\n = total number of previous pages * page height including top/down margins\n + the margin top of current page\n + the distance from the page top to the specified position\n \n Notice that the scroll distance is measured in pixels,\n so leftPoints/bottomPoints has to be transformed from points to pixels first.\n */\n const { width, height, marginTop, marginBottom, marginLeft, marginRight } = getPagePropertiesInPixels();\n const heightWithMargins = height + marginTop + marginBottom;\n // When a paper is rotated, its height and width would be switched automatically. However, leftPoints and bottomPoints remain the same.\n let marginTopPixels = marginTop;\n let bottomPixels = (height * bottomPoints) / PDF_HEIGHT_POINTS;\n let leftPixels = (width * leftPoints) / PDF_WIDTH_POINTS;\n if (rotation == PageRotation.Rotate90) {\n marginTopPixels = marginLeft;\n bottomPixels = (height * (PDF_WIDTH_POINTS - leftPoints)) / PDF_WIDTH_POINTS;\n leftPixels = (width * bottomPoints) / PDF_HEIGHT_POINTS;\n }\n else if (rotation == PageRotation.Rotate180) {\n marginTopPixels = marginBottom;\n bottomPixels = (height * (PDF_HEIGHT_POINTS - bottomPoints)) / PDF_HEIGHT_POINTS;\n leftPixels = (width * (PDF_WIDTH_POINTS - leftPoints)) / PDF_WIDTH_POINTS;\n }\n else if (rotation == PageRotation.Rotate270) {\n marginTopPixels = marginRight;\n bottomPixels = (height * leftPoints) / PDF_WIDTH_POINTS;\n leftPixels = (width * (PDF_HEIGHT_POINTS - bottomPoints)) / PDF_HEIGHT_POINTS;\n }\n // Find page element\n const pageId = generatePageIdFromIndex(pageIndex);\n const pageIdElement = document.getElementById(pageId);\n if (!pageIdElement) {\n return;\n }\n // Find first scrollable parent\n const parentElement = getScrollParent(pageIdElement);\n if (!parentElement) {\n return;\n }\n // Apply scroll\n parentElement.scrollTo({\n top: calculateTopPx({\n heightWithMarginsInPx: heightWithMargins,\n pageIndex: pageIndex,\n marginTopPx: marginTopPixels,\n heightPx: height,\n bottomPx: bottomPixels,\n }),\n left: Math.floor(leftPixels),\n behavior: \'smooth\',\n });\n}\nfunction getScrollParent(node) {\n if (typeof document === \'undefined\') {\n return null;\n }\n if (!node || node.nodeName.toLowerCase() === \'body\') {\n return document.documentElement;\n }\n if (node.scrollHeight > node.clientHeight && !isOverflowIsHidden(node)) {\n return node;\n }\n return getScrollParent(node.parentElement);\n}\nfunction isOverflowIsHidden(node) {\n const style = getComputedStyle(node);\n return (style.overflow.includes(\'hidden\') ||\n style.overflowX.includes(\'hidden\') ||\n style.overflowY.includes(\'hidden\'));\n}\nfunction calculateTopPx({ heightWithMarginsInPx, pageIndex, marginTopPx, heightPx, bottomPx, }) {\n return Math.floor(heightWithMarginsInPx * pageIndex + marginTopPx + (heightPx - bottomPx));\n}\n/**\n * Get lengths, widths, and margins of a page.\n * @returns a PageProperties object\n */\nfunction getPagePropertiesInPixels() {\n const firstPage = document.getElementById(generatePageIdFromIndex(0));\n if (!firstPage) {\n console.error(`Cannot get the first page of this document.`);\n const emptyPageProperties = {\n width: 0,\n height: 0,\n marginTop: 0,\n marginBottom: 0,\n marginLeft: 0,\n marginRight: 0,\n };\n return emptyPageProperties;\n }\n const style = getComputedStyle(firstPage);\n const pageProperties = {\n width: parseInt(style.width),\n height: parseInt(style.height),\n marginTop: parseInt(style.marginTop),\n marginBottom: parseInt(style.marginBottom),\n marginLeft: parseInt(style.marginLeft),\n marginRight: parseInt(style.marginRight),\n };\n return pageProperties;\n}\nfunction calculateTargetPosition({ scale, leftPoint, bottomPoint, pageDimensions, rotation = PageRotation.Rotate0, }) {\n switch (rotation) {\n default:\n case PageRotation.Rotate0: {\n const leftPx = (leftPoint / PDF_WIDTH_POINTS) * pageDimensions.width * scale;\n const topPx = (1 - bottomPoint / PDF_HEIGHT_POINTS) * pageDimensions.height * scale;\n return { leftPx, topPx };\n }\n }\n}\n\n;// CONCATENATED MODULE: ./src/context/DocumentContext.ts\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n\n\n\nconst DocumentContext_DocumentContext = external_commonjs_react_commonjs2_react_amd_react_root_React_.createContext({\n numPages: 0,\n outline: [],\n outlinePositions: null,\n pageDimensions: { height: 0, width: 0 },\n pdfDocProxy: undefined,\n getOutlineTargets: opts => {\n logProviderWarning(`getOutlineTargets(${JSON.stringify(opts)})`, \'DocumentContext\');\n return [];\n },\n setNumPages: numPages => {\n logProviderWarning(`setNumPages(${numPages})`, \'DocumentContext\');\n },\n setOutline: outline => {\n logProviderWarning(`setOutline(${outline})`, \'DocumentContext\');\n },\n setOutlinePositions: outline => {\n logProviderWarning(`setOutlinePositions(${outline})`, \'DocumentContext\');\n },\n setPageDimensions: pageDimensions => {\n logProviderWarning(`setPageDimensions(${pageDimensions})`, \'DocumentContext\');\n },\n setPdfDocProxy: pdfDocProxy => {\n logProviderWarning(`setPdfDocProxy(${pdfDocProxy})`, \'DocumentContext\');\n },\n});\nfunction useDocumentContextProps() {\n const [numPages, setNumPages] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(0);\n const [outline, setOutline] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(null);\n const [outlinePositions, setOutlinePositions] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(null);\n const [pageDimensions, setPageDimensions] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState({ height: 0, width: 0 });\n const [pdfDocProxy, setPdfDocProxy] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState();\n // Draw outline target into the pdf based on the args\n const getOutlineTargets = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(({ pageNumber, pageIndex, scale, rotation, pageDimensions, }) => {\n if (typeof pageIndex === \'number\') {\n pageNumber = pageIndex + 1;\n }\n if (typeof pageNumber !== \'number\') {\n return [];\n }\n const positions = (outlinePositions === null || outlinePositions === void 0 ? void 0 : outlinePositions.get(pageNumber)) || [];\n return positions.map(({ dest, leftPoint, bottomPoint }) => {\n const { leftPx, topPx } = calculateTargetPosition({\n scale,\n rotation,\n leftPoint,\n bottomPoint,\n pageDimensions,\n });\n return {\n dest,\n leftPx,\n topPx,\n };\n });\n }, [outlinePositions]);\n return {\n numPages,\n outline,\n outlinePositions,\n pageDimensions,\n pdfDocProxy,\n getOutlineTargets,\n setNumPages,\n setOutline,\n setOutlinePositions,\n setPageDimensions: setPageDimensions,\n setPdfDocProxy,\n };\n}\nfunction buildOutlinePositions(pdfDocProxy, outline) {\n var _a;\n return __awaiter(this, void 0, void 0, function* () {\n if (!outline) {\n outline = yield pdfDocProxy.getOutline();\n }\n // Depth first search through outline items\n const itemQueue = outline.slice();\n const proms = [];\n while (itemQueue.length > 0) {\n const item = itemQueue.pop();\n if (!item) {\n continue; // Not able to process\n }\n const { dest, items } = item;\n // Add child items to queue\n if (Array.isArray(items)) {\n itemQueue.push(...items);\n }\n // Fetch destinations for item\n if (Array.isArray(dest)) {\n proms.push(...dest.map(dest => getDestination(pdfDocProxy, dest)));\n }\n else if (typeof dest === \'string\') {\n proms.push(getDestination(pdfDocProxy, dest));\n }\n }\n // Collect results all at once, so we don\'t have to pay for the cost of\n // queueing messages sent to the worker\n const results = yield Promise.all(proms);\n // Split results into pages\n const map = new Map();\n for (const result of results) {\n if (!result) {\n continue; // Filter out null\n }\n const { pageNumber } = result;\n if (!map.has(pageNumber)) {\n map.set(pageNumber, []);\n }\n (_a = map.get(pageNumber)) === null || _a === void 0 ? void 0 : _a.push(result);\n }\n // Freeze objects so consumers cannot mutate\n for (const pagePos of map.values()) {\n for (const pos of pagePos) {\n Object.freeze(pos);\n }\n Object.freeze(pagePos);\n }\n Object.freeze(map);\n return map;\n });\n}\nfunction getDestination(pdfDocProxy, dest) {\n return __awaiter(this, void 0, void 0, function* () {\n const result = yield pdfDocProxy.getDestination(dest);\n if (!result) {\n return null;\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const [ref, _format, leftPoint, bottomPoint] = result;\n const pageIndex = yield pdfDocProxy.getPageIndex(ref);\n const pageNumber = pageIndex + 1;\n return { pageNumber, dest, leftPoint, bottomPoint };\n });\n}\n\n;// CONCATENATED MODULE: ./src/context/TransformContext.ts\n\n\n\nconst TransformContext = external_commonjs_react_commonjs2_react_amd_react_root_React_.createContext({\n rotation: PageRotation.Rotate0,\n scale: 1,\n zoomMultiplier: 1.2,\n setRotation: rotation => {\n logProviderWarning(`setRotation(${rotation})`, \'TransformContext\');\n },\n setScale: scale => {\n logProviderWarning(`setScale(${scale})`, \'TransformContext\');\n },\n setZoomMultiplier: zoom => {\n logProviderWarning(`setZoomMultiplier(${zoom})`, \'TransformContext\');\n },\n});\nfunction useTransformContextProps() {\n const [rotation, setRotation] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(PageRotation.Rotate0);\n const [scale, setScale] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(1.0);\n const [zoomMultiplier, setZoomMultiplier] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(1.2);\n return {\n rotation,\n scale,\n setRotation,\n setScale,\n setZoomMultiplier,\n zoomMultiplier,\n };\n}\n\n;// CONCATENATED MODULE: ./src/utils/style.ts\n\n// Computes the style for a bounding box, accounting for page roation and page scaling/zoom\nfunction computeBoundingBoxStyle(boundingBoxSize, pageDimensions, rotation, scale) {\n const { top, left, height, width } = boundingBoxSize;\n switch (rotation) {\n case PageRotation.Rotate90:\n return {\n top: left * scale,\n left: (pageDimensions.height - height - top) * scale,\n height: width * scale,\n width: height * scale,\n };\n case PageRotation.Rotate180:\n return {\n top: (pageDimensions.height - height - top) * scale,\n left: (pageDimensions.width - width - left) * scale,\n height: height * scale,\n width: width * scale,\n };\n case PageRotation.Rotate270:\n return {\n top: (pageDimensions.width - width - left) * scale,\n left: top * scale,\n height: width * scale,\n width: height * scale,\n };\n default:\n return {\n top: top * scale,\n left: left * scale,\n height: height * scale,\n width: width * scale,\n };\n }\n}\n// Compute the style for a page, accounting for page rotation and page scaling/zoom\nfunction computePageStyle(pageDimensions, rotation, scale) {\n return {\n height: getPageHeight(pageDimensions, rotation) * scale,\n width: getPageWidth(pageDimensions, rotation) * scale,\n left: 0,\n top: 0,\n };\n}\n// Get page height accounting for page rotation- if the page is rotated on its side, its width becomes its height\nfunction getPageHeight(pageDimensions, rotation) {\n return isSideways(rotation) ? pageDimensions.width : pageDimensions.height;\n}\n// Get page width accounting for page rotation- if the page is rotated on its side, its height becomes its width\nfunction getPageWidth(pageDimensions, rotation) {\n return isSideways(rotation) ? pageDimensions.height : pageDimensions.width;\n}\n\n;// CONCATENATED MODULE: ./src/components/BoundingBox.tsx\nvar __rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\n\nconst BoundingBox = (_a) => {\n var { top, left, height, width, className, id, isHighlighted, onClick } = _a, extraProps = __rest(_a, ["top", "left", "height", "width", "className", "id", "isHighlighted", "onClick"]);\n const { pageDimensions } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(DocumentContext_DocumentContext);\n const { rotation, scale } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(TransformContext);\n const boxSize = { top, left, height, width };\n const componentClassName = classnames_default()(\'reader__page-overlay__bounding-box\', isHighlighted === true ? \'reader__page-overlay__bounding-box-highlighted\' : \'\', className);\n const getBoundingBoxStyle = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(() => {\n return computeBoundingBoxStyle(boxSize, pageDimensions, rotation, scale);\n }, [pageDimensions, rotation, scale]);\n const rotationClassName = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(() => {\n return `rotate${rotation}`;\n }, [rotation]);\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(external_commonjs_react_commonjs2_react_amd_react_root_React_.Fragment, null,\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("div", { className: `reader__page-overlay__bounding-box-underline ${rotationClassName()}`, style: getBoundingBoxStyle() }),\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("div", Object.assign({ id: id, className: `${componentClassName} ${rotationClassName()}`, style: getBoundingBoxStyle(), onClick: onClick }, extraProps))));\n};\n\n// EXTERNAL MODULE: ./node_modules/pdfjs-dist/build/pdf.js\nvar pdf = __webpack_require__(299);\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/extends.js\nfunction extends_extends() {\n extends_extends = Object.assign || function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n };\n\n return extends_extends.apply(this, arguments);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js\nfunction _objectWithoutPropertiesLoose(source, excluded) {\n if (source == null) return {};\n var target = {};\n var sourceKeys = Object.keys(source);\n var key, i;\n\n for (i = 0; i < sourceKeys.length; i++) {\n key = sourceKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n target[key] = source[key];\n }\n\n return target;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js\n\nfunction _objectWithoutProperties(source, excluded) {\n if (source == null) return {};\n var target = _objectWithoutPropertiesLoose(source, excluded);\n var key, i;\n\n if (Object.getOwnPropertySymbols) {\n var sourceSymbolKeys = Object.getOwnPropertySymbols(source);\n\n for (i = 0; i < sourceSymbolKeys.length; i++) {\n key = sourceSymbolKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;\n target[key] = source[key];\n }\n }\n\n return target;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/typeof.js\nfunction _typeof(obj) {\n "@babel/helpers - typeof";\n\n return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;\n }, _typeof(obj);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/classCallCheck.js\nfunction _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError("Cannot call a class as a function");\n }\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/createClass.js\nfunction _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if ("value" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nfunction _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n Object.defineProperty(Constructor, "prototype", {\n writable: false\n });\n return Constructor;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js\nfunction _assertThisInitialized(self) {\n if (self === void 0) {\n throw new ReferenceError("this hasn\'t been initialised - super() hasn\'t been called");\n }\n\n return self;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js\nfunction _setPrototypeOf(o, p) {\n _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n\n return _setPrototypeOf(o, p);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/inherits.js\n\nfunction _inherits(subClass, superClass) {\n if (typeof superClass !== "function" && superClass !== null) {\n throw new TypeError("Super expression must either be null or a function");\n }\n\n Object.defineProperty(subClass, "prototype", {\n value: Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n writable: true,\n configurable: true\n }\n }),\n writable: false\n });\n if (superClass) _setPrototypeOf(subClass, superClass);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js\n\n\nfunction _possibleConstructorReturn(self, call) {\n if (call && (_typeof(call) === "object" || typeof call === "function")) {\n return call;\n } else if (call !== void 0) {\n throw new TypeError("Derived constructors may only return object or undefined");\n }\n\n return _assertThisInitialized(self);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js\nfunction _getPrototypeOf(o) {\n _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {\n return o.__proto__ || Object.getPrototypeOf(o);\n };\n return _getPrototypeOf(o);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/defineProperty.js\nfunction _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}\n// EXTERNAL MODULE: ./node_modules/prop-types/index.js\nvar prop_types = __webpack_require__(697);\nvar prop_types_default = /*#__PURE__*/__webpack_require__.n(prop_types);\n;// CONCATENATED MODULE: ./node_modules/make-event-props/dist/esm/index.js\n// As defined on the list of supported events: https://reactjs.org/docs/events.html\nvar clipboardEvents = [\'onCopy\', \'onCut\', \'onPaste\'];\nvar compositionEvents = [\'onCompositionEnd\', \'onCompositionStart\', \'onCompositionUpdate\'];\nvar keyboardEvents = [\'onKeyDown\', \'onKeyPress\', \'onKeyUp\'];\nvar focusEvents = [\'onFocus\', \'onBlur\'];\nvar formEvents = [\'onChange\', \'onInput\', \'onInvalid\', \'onReset\', \'onSubmit\'];\nvar genericEvents = [\'onError\', \'onLoad\'];\nvar mouseEvents = [\'onClick\', \'onContextMenu\', \'onDoubleClick\', \'onDrag\', \'onDragEnd\', \'onDragEnter\', \'onDragExit\', \'onDragLeave\', \'onDragOver\', \'onDragStart\', \'onDrop\', \'onMouseDown\', \'onMouseEnter\', \'onMouseLeave\', \'onMouseMove\', \'onMouseOut\', \'onMouseOver\', \'onMouseUp\'];\nvar pointerEvents = [\'onPointerDown\', \'onPointerMove\', \'onPointerUp\', \'onPointerCancel\', \'onGotPointerCapture\', \'onLostPointerCapture\', \'onPointerEnter\', \'onPointerLeave\', \'onPointerOver\', \'onPointerOut\'];\nvar selectionEvents = [\'onSelect\'];\nvar touchEvents = [\'onTouchCancel\', \'onTouchEnd\', \'onTouchMove\', \'onTouchStart\'];\nvar uiEvents = [\'onScroll\'];\nvar wheelEvents = [\'onWheel\'];\nvar mediaEvents = [\'onAbort\', \'onCanPlay\', \'onCanPlayThrough\', \'onDurationChange\', \'onEmptied\', \'onEncrypted\', \'onEnded\', \'onError\', \'onLoadedData\', \'onLoadedMetadata\', \'onLoadStart\', \'onPause\', \'onPlay\', \'onPlaying\', \'onProgress\', \'onRateChange\', \'onSeeked\', \'onSeeking\', \'onStalled\', \'onSuspend\', \'onTimeUpdate\', \'onVolumeChange\', \'onWaiting\'];\nvar imageEvents = [\'onLoad\', \'onError\'];\nvar animationEvents = [\'onAnimationStart\', \'onAnimationEnd\', \'onAnimationIteration\'];\nvar transitionEvents = [\'onTransitionEnd\'];\nvar otherEvents = [\'onToggle\'];\nvar allEvents = [].concat(clipboardEvents, compositionEvents, keyboardEvents, focusEvents, formEvents, genericEvents, mouseEvents, pointerEvents, selectionEvents, touchEvents, uiEvents, wheelEvents, mediaEvents, imageEvents, animationEvents, transitionEvents, otherEvents);\n/**\n * Returns an object with on-event callback props curried with provided args.\n * @param {Object} props Props passed to a component.\n * @param {Function=} getArgs A function that returns argument(s) on-event callbacks\n * shall be curried with.\n */\n\nvar makeEventProps = function makeEventProps(props, getArgs) {\n var eventProps = {};\n allEvents.forEach(function (eventName) {\n if (!(eventName in props)) {\n return;\n }\n\n if (!getArgs) {\n eventProps[eventName] = props[eventName];\n return;\n }\n\n eventProps[eventName] = function (event) {\n return props[eventName](event, getArgs(eventName));\n };\n });\n return eventProps;\n};\n\n/* harmony default export */ const esm = (makeEventProps);\n;// CONCATENATED MODULE: ./node_modules/make-cancellable-promise/dist/esm/index.js\nfunction makeCancellablePromise(promise) {\n var isCancelled = false;\n var wrappedPromise = new Promise(function (resolve, reject) {\n promise.then(function () {\n return !isCancelled && resolve.apply(void 0, arguments);\n })["catch"](function (error) {\n return !isCancelled && reject(error);\n });\n });\n return {\n promise: wrappedPromise,\n cancel: function cancel() {\n isCancelled = true;\n }\n };\n}\n;// CONCATENATED MODULE: ./node_modules/merge-class-names/dist/esm/index.js\nfunction mergeClassNames() {\n return Array.prototype.slice.call(arguments).reduce(function (classList, arg) {\n return classList.concat(arg);\n }, []).filter(function (arg) {\n return typeof arg === \'string\';\n }).join(\' \');\n}\n;// CONCATENATED MODULE: ./node_modules/tiny-invariant/dist/tiny-invariant.esm.js\nvar isProduction = "production" === \'production\';\nvar prefix = \'Invariant failed\';\nfunction invariant(condition, message) {\n if (condition) {\n return;\n }\n if (isProduction) {\n throw new Error(prefix);\n }\n var provided = typeof message === \'function\' ? message() : message;\n var value = provided ? prefix + ": " + provided : prefix;\n throw new Error(value);\n}\n\n\n\n;// CONCATENATED MODULE: ./node_modules/tiny-warning/dist/tiny-warning.esm.js\nvar tiny_warning_esm_isProduction = "production" === \'production\';\nfunction warning(condition, message) {\n if (!tiny_warning_esm_isProduction) {\n if (condition) {\n return;\n }\n\n var text = "Warning: " + message;\n\n if (typeof console !== \'undefined\') {\n console.warn(text);\n }\n\n try {\n throw Error(text);\n } catch (x) {}\n }\n}\n\n/* harmony default export */ const tiny_warning_esm = (warning);\n\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/DocumentContext.js\n\n/* harmony default export */ const esm_DocumentContext = (/*#__PURE__*/(0,external_commonjs_react_commonjs2_react_amd_react_root_React_.createContext)(null));\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/Message.js\n\n\nfunction Message(_ref) {\n var children = _ref.children,\n type = _ref.type;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("div", {\n className: "react-pdf__message react-pdf__message--".concat(type)\n }, children);\n}\nMessage.propTypes = {\n children: (prop_types_default()).node,\n type: prop_types_default().oneOf([\'error\', \'loading\', \'no-data\']).isRequired\n};\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/LinkService.js\n\n\n\n/* Copyright 2015 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nvar DEFAULT_LINK_REL = \'noopener noreferrer nofollow\';\n\nvar LinkService = /*#__PURE__*/function () {\n function LinkService() {\n _classCallCheck(this, LinkService);\n\n this.externalLinkTarget = null;\n this.externalLinkRel = null;\n }\n\n _createClass(LinkService, [{\n key: "setDocument",\n value: function setDocument(pdfDocument) {\n this.pdfDocument = pdfDocument;\n }\n }, {\n key: "setViewer",\n value: function setViewer(pdfViewer) {\n this.pdfViewer = pdfViewer;\n }\n }, {\n key: "setExternalLinkRel",\n value: function setExternalLinkRel(externalLinkRel) {\n this.externalLinkRel = externalLinkRel;\n }\n }, {\n key: "setExternalLinkTarget",\n value: function setExternalLinkTarget(externalLinkTarget) {\n this.externalLinkTarget = externalLinkTarget;\n }\n }, {\n key: "setHistory",\n value: function setHistory() {}\n }, {\n key: "pagesCount",\n get: function get() {\n return this.pdfDocument ? this.pdfDocument.numPages : 0;\n }\n }, {\n key: "page",\n get: function get() {\n return this.pdfViewer.currentPageNumber;\n },\n set: function set(value) {\n this.pdfViewer.currentPageNumber = value;\n }\n }, {\n key: "rotation",\n get: function get() {\n return 0;\n },\n set: function set(value) {}\n }, {\n key: "goToDestination",\n value: function goToDestination(dest) {\n var _this = this;\n\n new Promise(function (resolve) {\n if (typeof dest === \'string\') {\n _this.pdfDocument.getDestination(dest).then(resolve);\n } else if (Array.isArray(dest)) {\n resolve(dest);\n } else {\n dest.then(resolve);\n }\n }).then(function (explicitDest) {\n invariant(Array.isArray(explicitDest), "\\"".concat(explicitDest, "\\" is not a valid destination array."));\n var destRef = explicitDest[0];\n new Promise(function (resolve) {\n if (destRef instanceof Object) {\n _this.pdfDocument.getPageIndex(destRef).then(function (pageIndex) {\n resolve(pageIndex);\n })["catch"](function () {\n invariant(false, "\\"".concat(destRef, "\\" is not a valid page reference."));\n });\n } else if (typeof destRef === \'number\') {\n resolve(destRef);\n } else {\n invariant(false, "\\"".concat(destRef, "\\" is not a valid destination reference."));\n }\n }).then(function (pageIndex) {\n var pageNumber = pageIndex + 1;\n invariant(pageNumber >= 1 && pageNumber <= _this.pagesCount, "\\"".concat(pageNumber, "\\" is not a valid page number."));\n\n _this.pdfViewer.scrollPageIntoView({\n dest: dest,\n pageIndex: pageIndex,\n pageNumber: pageNumber\n });\n });\n });\n }\n }, {\n key: "navigateTo",\n value: function navigateTo(dest) {\n this.goToDestination(dest);\n }\n }, {\n key: "goToPage",\n value: function goToPage() {}\n }, {\n key: "addLinkAttributes",\n value: function addLinkAttributes(link, url, newWindow) {\n link.href = url;\n link.rel = this.externalLinkRel || DEFAULT_LINK_REL;\n link.target = newWindow ? \'_blank\' : this.externalLinkTarget || \'\';\n }\n }, {\n key: "getDestinationHash",\n value: function getDestinationHash() {\n return \'#\';\n }\n }, {\n key: "getAnchorUrl",\n value: function getAnchorUrl() {\n return \'#\';\n }\n }, {\n key: "setHash",\n value: function setHash() {}\n }, {\n key: "executeNamedAction",\n value: function executeNamedAction() {}\n }, {\n key: "cachePageRef",\n value: function cachePageRef() {}\n }, {\n key: "isPageVisible",\n value: function isPageVisible() {\n return true;\n }\n }, {\n key: "isPageCached",\n value: function isPageCached() {\n return true;\n }\n }]);\n\n return LinkService;\n}();\n\n\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/PasswordResponses.js\n// As defined in https://github.com/mozilla/pdf.js/blob/d9fac3459609a807be6506fb3441b5da4b154d14/src/shared/util.js#L371-L374\nvar PasswordResponses = {\n NEED_PASSWORD: 1,\n INCORRECT_PASSWORD: 2\n};\n/* harmony default export */ const esm_PasswordResponses = (PasswordResponses);\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js\nfunction _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js\nfunction _iterableToArrayLimit(arr, i) {\n var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];\n\n if (_i == null) return;\n var _arr = [];\n var _n = true;\n var _d = false;\n\n var _s, _e;\n\n try {\n for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i["return"] != null) _i["return"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js\nfunction _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n\n for (var i = 0, arr2 = new Array(len); i < len; i++) {\n arr2[i] = arr[i];\n }\n\n return arr2;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js\n\nfunction _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === "string") return _arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === "Object" && o.constructor) n = o.constructor.name;\n if (n === "Map" || n === "Set") return Array.from(o);\n if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/nonIterableRest.js\nfunction _nonIterableRest() {\n throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/slicedToArray.js\n\n\n\n\nfunction _slicedToArray(arr, i) {\n return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();\n}\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/shared/utils.js\n\n\n\n/**\n * Checks if we\'re running in a browser environment.\n */\n\nvar isBrowser = typeof window !== \'undefined\';\n/**\n * Checks whether we\'re running from a local file system.\n */\n\nvar isLocalFileSystem = isBrowser && window.location.protocol === \'file:\';\n/**\n * Checks whether a variable is defined.\n *\n * @param {*} variable Variable to check\n */\n\nfunction isDefined(variable) {\n return typeof variable !== \'undefined\';\n}\n/**\n * Checks whether a variable is defined and not null.\n *\n * @param {*} variable Variable to check\n */\n\nfunction isProvided(variable) {\n return isDefined(variable) && variable !== null;\n}\n/**\n * Checkes whether a variable provided is a string.\n *\n * @param {*} variable Variable to check\n */\n\nfunction isString(variable) {\n return typeof variable === \'string\';\n}\n/**\n * Checks whether a variable provided is an ArrayBuffer.\n *\n * @param {*} variable Variable to check\n */\n\nfunction isArrayBuffer(variable) {\n return variable instanceof ArrayBuffer;\n}\n/**\n * Checkes whether a variable provided is a Blob.\n *\n * @param {*} variable Variable to check\n */\n\nfunction isBlob(variable) {\n invariant(isBrowser, \'isBlob can only be used in a browser environment\');\n return variable instanceof Blob;\n}\n/**\n * Checkes whether a variable provided is a File.\n *\n * @param {*} variable Variable to check\n */\n\nfunction isFile(variable) {\n invariant(isBrowser, \'isFile can only be used in a browser environment\');\n return variable instanceof File;\n}\n/**\n * Checks whether a string provided is a data URI.\n *\n * @param {string} str String to check\n */\n\nfunction isDataURI(str) {\n return isString(str) && /^data:/.test(str);\n}\nfunction dataURItoByteString(dataURI) {\n invariant(isDataURI(dataURI), \'Invalid data URI.\');\n\n var _dataURI$split = dataURI.split(\',\'),\n _dataURI$split2 = _slicedToArray(_dataURI$split, 2),\n headersString = _dataURI$split2[0],\n dataString = _dataURI$split2[1];\n\n var headers = headersString.split(\';\');\n\n if (headers.indexOf(\'base64\') !== -1) {\n return atob(dataString);\n }\n\n return unescape(dataString);\n}\nfunction getPixelRatio() {\n return isBrowser && window.devicePixelRatio || 1;\n}\nvar allowFileAccessFromFilesTip = \'On Chromium based browsers, you can use --allow-file-access-from-files flag for debugging purposes.\';\nfunction displayCORSWarning() {\n tiny_warning_esm(!isLocalFileSystem, "Loading PDF as base64 strings/URLs may not work on protocols other than HTTP/HTTPS. ".concat(allowFileAccessFromFilesTip));\n}\nfunction displayWorkerWarning() {\n tiny_warning_esm(!isLocalFileSystem, "Loading PDF.js worker may not work on protocols other than HTTP/HTTPS. ".concat(allowFileAccessFromFilesTip));\n}\nfunction cancelRunningTask(runningTask) {\n if (runningTask && runningTask.cancel) runningTask.cancel();\n}\nfunction makePageCallback(page, scale) {\n Object.defineProperty(page, \'width\', {\n get: function get() {\n return this.view[2] * scale;\n },\n configurable: true\n });\n Object.defineProperty(page, \'height\', {\n get: function get() {\n return this.view[3] * scale;\n },\n configurable: true\n });\n Object.defineProperty(page, \'originalWidth\', {\n get: function get() {\n return this.view[2];\n },\n configurable: true\n });\n Object.defineProperty(page, \'originalHeight\', {\n get: function get() {\n return this.view[3];\n },\n configurable: true\n });\n return page;\n}\nfunction isCancelException(error) {\n return error.name === \'RenderingCancelledException\';\n}\nfunction loadFromFile(file) {\n return new Promise(function (resolve, reject) {\n var reader = new FileReader();\n\n reader.onload = function () {\n return resolve(new Uint8Array(reader.result));\n };\n\n reader.onerror = function (event) {\n switch (event.target.error.code) {\n case event.target.error.NOT_FOUND_ERR:\n return reject(new Error(\'Error while reading a file: File not found.\'));\n\n case event.target.error.NOT_READABLE_ERR:\n return reject(new Error(\'Error while reading a file: File not readable.\'));\n\n case event.target.error.SECURITY_ERR:\n return reject(new Error(\'Error while reading a file: Security error.\'));\n\n case event.target.error.ABORT_ERR:\n return reject(new Error(\'Error while reading a file: Aborted.\'));\n\n default:\n return reject(new Error(\'Error while reading a file.\'));\n }\n };\n\n reader.readAsArrayBuffer(file);\n return null;\n });\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js\n\nfunction _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) return _arrayLikeToArray(arr);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/iterableToArray.js\nfunction _iterableToArray(iter) {\n if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js\nfunction _nonIterableSpread() {\n throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/toConsumableArray.js\n\n\n\n\nfunction _toConsumableArray(arr) {\n return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();\n}\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/shared/propTypes.js\n\n\n\n\n\n\nvar eventProps = function () {\n var result = {};\n [].concat(_toConsumableArray(mouseEvents), _toConsumableArray(touchEvents), _toConsumableArray(keyboardEvents)).forEach(function (eventName) {\n result[eventName] = (prop_types_default()).func;\n });\n return result;\n}();\nvar fileTypes = [(prop_types_default()).string, prop_types_default().instanceOf(ArrayBuffer), prop_types_default().shape({\n data: prop_types_default().oneOfType([(prop_types_default()).object, (prop_types_default()).string]),\n httpHeaders: (prop_types_default()).object,\n range: (prop_types_default()).object,\n url: (prop_types_default()).string,\n withCredentials: (prop_types_default()).bool\n})];\n\nif (typeof File !== \'undefined\') {\n fileTypes.push(prop_types_default().instanceOf(File));\n}\n\nif (typeof Blob !== \'undefined\') {\n fileTypes.push(prop_types_default().instanceOf(Blob));\n}\n\nvar isClassName = prop_types_default().oneOfType([(prop_types_default()).string, prop_types_default().arrayOf((prop_types_default()).string)]);\nvar propTypes_isFile = prop_types_default().oneOfType(fileTypes);\nvar isLinkService = prop_types_default().instanceOf(LinkService);\nvar isLinkTarget = prop_types_default().oneOf([\'_self\', \'_blank\', \'_parent\', \'_top\']);\nvar isPage = prop_types_default().shape({\n commonObjs: prop_types_default().shape({}).isRequired,\n getAnnotations: (prop_types_default()).func.isRequired,\n getTextContent: (prop_types_default()).func.isRequired,\n getViewport: (prop_types_default()).func.isRequired,\n render: (prop_types_default()).func.isRequired\n});\nvar isPageIndex = function isPageIndex(props, propName, componentName) {\n var pageIndex = props[propName],\n pageNumber = props.pageNumber,\n pdf = props.pdf;\n\n if (!isDefined(pdf)) {\n return null;\n }\n\n if (isDefined(pageIndex)) {\n if (typeof pageIndex !== \'number\') {\n return new Error("`".concat(propName, "` of type `").concat(_typeof(pageIndex), "` supplied to `").concat(componentName, "`, expected `number`."));\n }\n\n if (pageIndex < 0) {\n return new Error("Expected `".concat(propName, "` to be greater or equal to 0."));\n }\n\n var numPages = pdf.numPages;\n\n if (pageIndex + 1 > numPages) {\n return new Error("Expected `".concat(propName, "` to be less or equal to ").concat(numPages - 1, "."));\n }\n } else if (!isDefined(pageNumber)) {\n return new Error("`".concat(propName, "` not supplied. Either pageIndex or pageNumber must be supplied to `").concat(componentName, "`."));\n } // Everything is fine\n\n\n return null;\n};\nvar isPageNumber = function isPageNumber(props, propName, componentName) {\n var pageNumber = props[propName],\n pageIndex = props.pageIndex,\n pdf = props.pdf;\n\n if (!isDefined(pdf)) {\n return null;\n }\n\n if (isDefined(pageNumber)) {\n if (typeof pageNumber !== \'number\') {\n return new Error("`".concat(propName, "` of type `").concat(_typeof(pageNumber), "` supplied to `").concat(componentName, "`, expected `number`."));\n }\n\n if (pageNumber < 1) {\n return new Error("Expected `".concat(propName, "` to be greater or equal to 1."));\n }\n\n var numPages = pdf.numPages;\n\n if (pageNumber > numPages) {\n return new Error("Expected `".concat(propName, "` to be less or equal to ").concat(numPages, "."));\n }\n } else if (!isDefined(pageIndex)) {\n return new Error("`".concat(propName, "` not supplied. Either pageIndex or pageNumber must be supplied to `").concat(componentName, "`."));\n } // Everything is fine\n\n\n return null;\n};\nvar isPdf = prop_types_default().oneOfType([prop_types_default().shape({\n getDestination: (prop_types_default()).func.isRequired,\n getOutline: (prop_types_default()).func.isRequired,\n getPage: (prop_types_default()).func.isRequired,\n numPages: (prop_types_default()).number.isRequired\n}), (prop_types_default()).bool]);\nvar isRef = prop_types_default().oneOfType([(prop_types_default()).func, prop_types_default().shape({\n current: (prop_types_default()).any\n})]);\nvar isRenderMode = prop_types_default().oneOf([\'canvas\', \'none\', \'svg\']);\nvar isRotate = prop_types_default().oneOf([0, 90, 180, 270]);\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/Document.js\n\n\n\n\n\n\n\n\n\n\nvar _excluded = ["url"];\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\n/**\n * Loads a PDF document. Passes it to all children.\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar PDFDataRangeTransport = pdf.PDFDataRangeTransport;\n\nvar Document = /*#__PURE__*/function (_PureComponent) {\n _inherits(Document, _PureComponent);\n\n var _super = _createSuper(Document);\n\n function Document() {\n var _this;\n\n _classCallCheck(this, Document);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _super.call.apply(_super, [this].concat(args));\n\n _defineProperty(_assertThisInitialized(_this), "state", {\n pdf: null\n });\n\n _defineProperty(_assertThisInitialized(_this), "viewer", {\n scrollPageIntoView: function scrollPageIntoView(_ref) {\n var dest = _ref.dest,\n pageIndex = _ref.pageIndex,\n pageNumber = _ref.pageNumber;\n // Handling jumping to internal links target\n var onItemClick = _this.props.onItemClick; // First, check if custom handling of onItemClick was provided\n\n if (onItemClick) {\n onItemClick({\n dest: dest,\n pageIndex: pageIndex,\n pageNumber: pageNumber\n });\n return;\n } // If not, try to look for target page within the .\n\n\n var page = _this.pages[pageIndex];\n\n if (page) {\n // Scroll to the page automatically\n page.scrollIntoView();\n return;\n }\n\n tiny_warning_esm(false, "An internal link leading to page ".concat(pageNumber, " was clicked, but neither was provided with onItemClick nor it was able to find the page within itself. Either provide onItemClick to and handle navigating by yourself or ensure that all pages are rendered within ."));\n }\n });\n\n _defineProperty(_assertThisInitialized(_this), "linkService", new LinkService());\n\n _defineProperty(_assertThisInitialized(_this), "loadDocument", function () {\n // If another rendering is in progress, let\'s cancel it\n cancelRunningTask(_this.runningTask); // If another loading is in progress, let\'s destroy it\n\n if (_this.loadingTask) _this.loadingTask.destroy();\n var cancellable = makeCancellablePromise(_this.findDocumentSource());\n _this.runningTask = cancellable;\n cancellable.promise.then(function (source) {\n _this.onSourceSuccess();\n\n if (!source) {\n return;\n }\n\n _this.setState(function (prevState) {\n if (!prevState.pdf) {\n return null;\n }\n\n return {\n pdf: null\n };\n });\n\n var _this$props = _this.props,\n options = _this$props.options,\n onLoadProgress = _this$props.onLoadProgress,\n onPassword = _this$props.onPassword;\n _this.loadingTask = pdf.getDocument(_objectSpread(_objectSpread({}, source), options));\n _this.loadingTask.onPassword = onPassword;\n\n if (onLoadProgress) {\n _this.loadingTask.onProgress = onLoadProgress;\n }\n\n var cancellable = makeCancellablePromise(_this.loadingTask.promise);\n _this.runningTask = cancellable;\n cancellable.promise.then(function (pdf) {\n _this.setState(function (prevState) {\n if (prevState.pdf && prevState.pdf.fingerprint === pdf.fingerprint) {\n return null;\n }\n\n return {\n pdf: pdf\n };\n }, _this.onLoadSuccess);\n })["catch"](function (error) {\n _this.onLoadError(error);\n });\n })["catch"](function (error) {\n _this.onSourceError(error);\n });\n });\n\n _defineProperty(_assertThisInitialized(_this), "setupLinkService", function () {\n var _this$props2 = _this.props,\n externalLinkRel = _this$props2.externalLinkRel,\n externalLinkTarget = _this$props2.externalLinkTarget;\n\n _this.linkService.setViewer(_this.viewer);\n\n _this.linkService.setExternalLinkRel(externalLinkRel);\n\n _this.linkService.setExternalLinkTarget(externalLinkTarget);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onSourceSuccess", function () {\n var onSourceSuccess = _this.props.onSourceSuccess;\n if (onSourceSuccess) onSourceSuccess();\n });\n\n _defineProperty(_assertThisInitialized(_this), "onSourceError", function (error) {\n tiny_warning_esm(error);\n var onSourceError = _this.props.onSourceError;\n if (onSourceError) onSourceError(error);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onLoadSuccess", function () {\n var onLoadSuccess = _this.props.onLoadSuccess;\n var pdf = _this.state.pdf;\n if (onLoadSuccess) onLoadSuccess(pdf);\n _this.pages = new Array(pdf.numPages);\n\n _this.linkService.setDocument(pdf);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onLoadError", function (error) {\n _this.setState({\n pdf: false\n });\n\n tiny_warning_esm(error);\n var onLoadError = _this.props.onLoadError;\n if (onLoadError) onLoadError(error);\n });\n\n _defineProperty(_assertThisInitialized(_this), "findDocumentSource", function () {\n return new Promise(function (resolve) {\n var file = _this.props.file;\n\n if (!file) {\n resolve(null);\n } // File is a string\n\n\n if (typeof file === \'string\') {\n if (isDataURI(file)) {\n var fileByteString = dataURItoByteString(file);\n resolve({\n data: fileByteString\n });\n }\n\n displayCORSWarning();\n resolve({\n url: file\n });\n } // File is PDFDataRangeTransport\n\n\n if (file instanceof PDFDataRangeTransport) {\n resolve({\n range: file\n });\n } // File is an ArrayBuffer\n\n\n if (isArrayBuffer(file)) {\n resolve({\n data: file\n });\n }\n /**\n * The cases below are browser-only.\n * If you\'re running on a non-browser environment, these cases will be of no use.\n */\n\n\n if (isBrowser) {\n // File is a Blob\n if (isBlob(file) || isFile(file)) {\n loadFromFile(file).then(function (data) {\n resolve({\n data: data\n });\n });\n return;\n }\n } // At this point, file must be an object\n\n\n invariant(_typeof(file) === \'object\', \'Invalid parameter in file, need either Uint8Array, string or a parameter object\');\n invariant(file.url || file.data || file.range, \'Invalid parameter object: need either .data, .range or .url\'); // File .url is a string\n\n if (typeof file.url === \'string\') {\n if (isDataURI(file.url)) {\n var url = file.url,\n otherParams = _objectWithoutProperties(file, _excluded);\n\n var _fileByteString = dataURItoByteString(url);\n\n resolve(_objectSpread({\n data: _fileByteString\n }, otherParams));\n }\n\n displayCORSWarning();\n }\n\n resolve(file);\n });\n });\n\n _defineProperty(_assertThisInitialized(_this), "registerPage", function (pageIndex, ref) {\n _this.pages[pageIndex] = ref;\n });\n\n _defineProperty(_assertThisInitialized(_this), "unregisterPage", function (pageIndex) {\n delete _this.pages[pageIndex];\n });\n\n return _this;\n }\n\n _createClass(Document, [{\n key: "componentDidMount",\n value: function componentDidMount() {\n this.loadDocument();\n this.setupLinkService();\n }\n }, {\n key: "componentDidUpdate",\n value: function componentDidUpdate(prevProps) {\n var file = this.props.file;\n\n if (file !== prevProps.file) {\n this.loadDocument();\n }\n }\n }, {\n key: "componentWillUnmount",\n value: function componentWillUnmount() {\n // If rendering is in progress, let\'s cancel it\n cancelRunningTask(this.runningTask); // If loading is in progress, let\'s destroy it\n\n if (this.loadingTask) this.loadingTask.destroy();\n }\n }, {\n key: "childContext",\n get: function get() {\n var linkService = this.linkService,\n registerPage = this.registerPage,\n unregisterPage = this.unregisterPage;\n var _this$props3 = this.props,\n imageResourcesPath = _this$props3.imageResourcesPath,\n renderMode = _this$props3.renderMode,\n rotate = _this$props3.rotate;\n var pdf = this.state.pdf;\n return {\n imageResourcesPath: imageResourcesPath,\n linkService: linkService,\n pdf: pdf,\n registerPage: registerPage,\n renderMode: renderMode,\n rotate: rotate,\n unregisterPage: unregisterPage\n };\n }\n }, {\n key: "eventProps",\n get: function get() {\n var _this2 = this;\n\n return esm(this.props, function () {\n return _this2.state.pdf;\n });\n }\n /**\n * Called when a document source is resolved correctly\n */\n\n }, {\n key: "renderChildren",\n value: function renderChildren() {\n var children = this.props.children;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(esm_DocumentContext.Provider, {\n value: this.childContext\n }, children);\n }\n }, {\n key: "renderContent",\n value: function renderContent() {\n var file = this.props.file;\n var pdf = this.state.pdf;\n\n if (!file) {\n var noData = this.props.noData;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(Message, {\n type: "no-data"\n }, typeof noData === \'function\' ? noData() : noData);\n }\n\n if (pdf === null) {\n var loading = this.props.loading;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(Message, {\n type: "loading"\n }, typeof loading === \'function\' ? loading() : loading);\n }\n\n if (pdf === false) {\n var error = this.props.error;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(Message, {\n type: "error"\n }, typeof error === \'function\' ? error() : error);\n }\n\n return this.renderChildren();\n }\n }, {\n key: "render",\n value: function render() {\n var _this$props4 = this.props,\n className = _this$props4.className,\n inputRef = _this$props4.inputRef;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("div", extends_extends({\n className: mergeClassNames(\'react-pdf__Document\', className),\n ref: inputRef\n }, this.eventProps), this.renderContent());\n }\n }]);\n\n return Document;\n}(external_commonjs_react_commonjs2_react_amd_react_root_React_.PureComponent);\n\n\nDocument.defaultProps = {\n error: \'Failed to load PDF file.\',\n loading: \'Loading PDF…\',\n noData: \'No PDF file specified.\',\n onPassword: function onPassword(callback, reason) {\n switch (reason) {\n case esm_PasswordResponses.NEED_PASSWORD:\n {\n // eslint-disable-next-line no-alert\n var password = prompt(\'Enter the password to open this PDF file.\');\n callback(password);\n break;\n }\n\n case esm_PasswordResponses.INCORRECT_PASSWORD:\n {\n // eslint-disable-next-line no-alert\n var _password = prompt(\'Invalid password. Please try again.\');\n\n callback(_password);\n break;\n }\n\n default:\n }\n }\n};\nvar isFunctionOrNode = prop_types_default().oneOfType([(prop_types_default()).func, (prop_types_default()).node]);\nDocument.propTypes = _objectSpread(_objectSpread({}, eventProps), {}, {\n children: (prop_types_default()).node,\n className: isClassName,\n error: isFunctionOrNode,\n externalLinkRel: (prop_types_default()).string,\n externalLinkTarget: (prop_types_default()).string,\n file: propTypes_isFile,\n imageResourcesPath: (prop_types_default()).string,\n inputRef: isRef,\n loading: isFunctionOrNode,\n noData: isFunctionOrNode,\n onItemClick: (prop_types_default()).func,\n onLoadError: (prop_types_default()).func,\n onLoadProgress: (prop_types_default()).func,\n onLoadSuccess: (prop_types_default()).func,\n onPassword: (prop_types_default()).func,\n onSourceError: (prop_types_default()).func,\n onSourceSuccess: (prop_types_default()).func,\n rotate: (prop_types_default()).number\n});\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/OutlineContext.js\n\n/* harmony default export */ const OutlineContext = (/*#__PURE__*/(0,external_commonjs_react_commonjs2_react_amd_react_root_React_.createContext)(null));\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/Ref.js\n\n\n\nvar Ref = /*#__PURE__*/function () {\n function Ref(_ref) {\n var num = _ref.num,\n gen = _ref.gen;\n\n _classCallCheck(this, Ref);\n\n this.num = num;\n this.gen = gen;\n }\n\n _createClass(Ref, [{\n key: "toString",\n value: function toString() {\n var str = "".concat(this.num, "R");\n\n if (this.gen !== 0) {\n str += this.gen;\n }\n\n return str;\n }\n }]);\n\n return Ref;\n}();\n\n\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/OutlineItem.js\n\n\n\n\n\n\n\n\n\n\nvar OutlineItem_excluded = ["item"];\n\nfunction OutlineItem_createSuper(Derived) { var hasNativeReflectConstruct = OutlineItem_isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction OutlineItem_isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\n\n\n\n\n\n\n\nvar OutlineItemInternal = /*#__PURE__*/function (_PureComponent) {\n _inherits(OutlineItemInternal, _PureComponent);\n\n var _super = OutlineItem_createSuper(OutlineItemInternal);\n\n function OutlineItemInternal() {\n var _this;\n\n _classCallCheck(this, OutlineItemInternal);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _super.call.apply(_super, [this].concat(args));\n\n _defineProperty(_assertThisInitialized(_this), "getDestination", function () {\n return new Promise(function (resolve, reject) {\n var _this$props = _this.props,\n item = _this$props.item,\n pdf = _this$props.pdf;\n\n if (!isDefined(_this.destination)) {\n if (typeof item.dest === \'string\') {\n pdf.getDestination(item.dest).then(resolve)["catch"](reject);\n } else {\n resolve(item.dest);\n }\n }\n\n return _this.destination;\n }).then(function (destination) {\n _this.destination = destination;\n return destination;\n });\n });\n\n _defineProperty(_assertThisInitialized(_this), "getPageIndex", function () {\n return new Promise(function (resolve, reject) {\n var pdf = _this.props.pdf;\n\n if (isDefined(_this.pageIndex)) {\n resolve(_this.pageIndex);\n }\n\n _this.getDestination().then(function (destination) {\n if (!destination) {\n return;\n }\n\n var _destination = _slicedToArray(destination, 1),\n ref = _destination[0];\n\n pdf.getPageIndex(new Ref(ref)).then(resolve)["catch"](reject);\n });\n }).then(function (pageIndex) {\n _this.pageIndex = pageIndex;\n return _this.pageIndex;\n });\n });\n\n _defineProperty(_assertThisInitialized(_this), "getPageNumber", function () {\n return new Promise(function (resolve, reject) {\n if (isDefined(_this.pageNumber)) {\n resolve(_this.pageNumber);\n }\n\n _this.getPageIndex().then(function (pageIndex) {\n resolve(pageIndex + 1);\n })["catch"](reject);\n }).then(function (pageNumber) {\n _this.pageNumber = pageNumber;\n return pageNumber;\n });\n });\n\n _defineProperty(_assertThisInitialized(_this), "onClick", function (event) {\n var onClick = _this.props.onClick;\n event.preventDefault();\n\n if (!onClick) {\n return false;\n }\n\n return Promise.all([_this.getDestination(), _this.getPageIndex(), _this.getPageNumber()]).then(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 3),\n dest = _ref2[0],\n pageIndex = _ref2[1],\n pageNumber = _ref2[2];\n\n onClick({\n dest: dest,\n pageIndex: pageIndex,\n pageNumber: pageNumber\n });\n });\n });\n\n return _this;\n }\n\n _createClass(OutlineItemInternal, [{\n key: "renderSubitems",\n value: function renderSubitems() {\n var _this$props2 = this.props,\n item = _this$props2.item,\n otherProps = _objectWithoutProperties(_this$props2, OutlineItem_excluded);\n\n if (!item.items || !item.items.length) {\n return null;\n }\n\n var subitems = item.items;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("ul", null, subitems.map(function (subitem, subitemIndex) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(OutlineItemInternal, extends_extends({\n key: typeof subitem.destination === \'string\' ? subitem.destination : subitemIndex,\n item: subitem\n }, otherProps));\n }));\n }\n }, {\n key: "render",\n value: function render() {\n var item = this.props.item;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("li", null, /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("a", {\n href: "#",\n onClick: this.onClick\n }, item.title), this.renderSubitems());\n }\n }]);\n\n return OutlineItemInternal;\n}(external_commonjs_react_commonjs2_react_amd_react_root_React_.PureComponent);\nvar isDestination = prop_types_default().oneOfType([(prop_types_default()).string, prop_types_default().arrayOf((prop_types_default()).any)]);\nOutlineItemInternal.propTypes = {\n item: prop_types_default().shape({\n dest: isDestination,\n items: prop_types_default().arrayOf(prop_types_default().shape({\n dest: isDestination,\n title: (prop_types_default()).string\n })),\n title: (prop_types_default()).string\n }).isRequired,\n onClick: (prop_types_default()).func,\n pdf: isPdf.isRequired\n};\n\nvar OutlineItem = function OutlineItem(props) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(esm_DocumentContext.Consumer, null, function (documentContext) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(OutlineContext.Consumer, null, function (outlineContext) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(OutlineItemInternal, extends_extends({}, documentContext, outlineContext, props));\n });\n });\n};\n\n/* harmony default export */ const esm_OutlineItem = (OutlineItem);\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/Outline.js\n\n\n\n\n\n\n\n\n\nfunction Outline_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\n\nfunction Outline_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? Outline_ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : Outline_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\n\nfunction Outline_createSuper(Derived) { var hasNativeReflectConstruct = Outline_isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction Outline_isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar OutlineInternal = /*#__PURE__*/function (_PureComponent) {\n _inherits(OutlineInternal, _PureComponent);\n\n var _super = Outline_createSuper(OutlineInternal);\n\n function OutlineInternal() {\n var _this;\n\n _classCallCheck(this, OutlineInternal);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _super.call.apply(_super, [this].concat(args));\n\n _defineProperty(_assertThisInitialized(_this), "state", {\n outline: null\n });\n\n _defineProperty(_assertThisInitialized(_this), "loadOutline", function () {\n var pdf = _this.props.pdf;\n\n _this.setState(function (prevState) {\n if (!prevState.outline) {\n return null;\n }\n\n return {\n outline: null\n };\n });\n\n var cancellable = makeCancellablePromise(pdf.getOutline());\n _this.runningTask = cancellable;\n cancellable.promise.then(function (outline) {\n _this.setState({\n outline: outline\n }, _this.onLoadSuccess);\n })["catch"](function (error) {\n _this.onLoadError(error);\n });\n });\n\n _defineProperty(_assertThisInitialized(_this), "onLoadSuccess", function () {\n var onLoadSuccess = _this.props.onLoadSuccess;\n var outline = _this.state.outline;\n if (onLoadSuccess) onLoadSuccess(outline);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onLoadError", function (error) {\n _this.setState({\n outline: false\n });\n\n tiny_warning_esm(error);\n var onLoadError = _this.props.onLoadError;\n if (onLoadError) onLoadError(error);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onItemClick", function (_ref) {\n var dest = _ref.dest,\n pageIndex = _ref.pageIndex,\n pageNumber = _ref.pageNumber;\n var onItemClick = _this.props.onItemClick;\n\n if (onItemClick) {\n onItemClick({\n dest: dest,\n pageIndex: pageIndex,\n pageNumber: pageNumber\n });\n }\n });\n\n return _this;\n }\n\n _createClass(OutlineInternal, [{\n key: "componentDidMount",\n value: function componentDidMount() {\n var pdf = this.props.pdf;\n invariant(pdf, \'Attempted to load an outline, but no document was specified.\');\n this.loadOutline();\n }\n }, {\n key: "componentDidUpdate",\n value: function componentDidUpdate(prevProps) {\n var pdf = this.props.pdf;\n\n if (prevProps.pdf && pdf !== prevProps.pdf) {\n this.loadOutline();\n }\n }\n }, {\n key: "componentWillUnmount",\n value: function componentWillUnmount() {\n cancelRunningTask(this.runningTask);\n }\n }, {\n key: "childContext",\n get: function get() {\n return {\n onClick: this.onItemClick\n };\n }\n }, {\n key: "eventProps",\n get: function get() {\n var _this2 = this;\n\n return esm(this.props, function () {\n return _this2.state.outline;\n });\n }\n /**\n * Called when an outline is read successfully\n */\n\n }, {\n key: "renderOutline",\n value: function renderOutline() {\n var outline = this.state.outline;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("ul", null, outline.map(function (item, itemIndex) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(esm_OutlineItem, {\n key: typeof item.destination === \'string\' ? item.destination : itemIndex,\n item: item\n });\n }));\n }\n }, {\n key: "render",\n value: function render() {\n var pdf = this.props.pdf;\n var outline = this.state.outline;\n\n if (!pdf || !outline) {\n return null;\n }\n\n var _this$props = this.props,\n className = _this$props.className,\n inputRef = _this$props.inputRef;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("div", extends_extends({\n className: mergeClassNames(\'react-pdf__Outline\', className),\n ref: inputRef\n }, this.eventProps), /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(OutlineContext.Provider, {\n value: this.childContext\n }, this.renderOutline()));\n }\n }]);\n\n return OutlineInternal;\n}(external_commonjs_react_commonjs2_react_amd_react_root_React_.PureComponent);\nOutlineInternal.propTypes = Outline_objectSpread({\n className: isClassName,\n inputRef: isRef,\n onItemClick: (prop_types_default()).func,\n onLoadError: (prop_types_default()).func,\n onLoadSuccess: (prop_types_default()).func,\n pdf: isPdf\n}, eventProps);\n\nfunction Outline(props, ref) {\n return /*#__PURE__*/React.createElement(DocumentContext.Consumer, null, function (context) {\n return /*#__PURE__*/React.createElement(OutlineInternal, _extends({\n ref: ref\n }, context, props));\n });\n}\n\n/* harmony default export */ const esm_Outline = (/*#__PURE__*/(/* unused pure expression or super */ null && (React.forwardRef(Outline))));\n;// CONCATENATED MODULE: ./node_modules/merge-refs/dist/esm/index.js\n/**\n * A function that merges React refs into one.\n * Supports both functions and ref objects created using createRef() and useRef().\n *\n * Usage:\n * ```jsx\n *
\n * ```\n *\n * @param {...Array} inputRefs Array of refs\n * @returns {Function} Merged refs\n */\nfunction mergeRefs() {\n for (var _len = arguments.length, inputRefs = new Array(_len), _key = 0; _key < _len; _key++) {\n inputRefs[_key] = arguments[_key];\n }\n\n var filteredInputRefs = inputRefs.filter(Boolean);\n\n if (filteredInputRefs.length <= 1) {\n return filteredInputRefs[0];\n }\n\n return function mergedRefs(ref) {\n filteredInputRefs.forEach(function (inputRef) {\n if (typeof inputRef === \'function\') {\n inputRef(ref);\n } else {\n // eslint-disable-next-line no-param-reassign\n inputRef.current = ref;\n }\n });\n };\n}\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/PageContext.js\n\n/* harmony default export */ const PageContext = (/*#__PURE__*/(0,external_commonjs_react_commonjs2_react_amd_react_root_React_.createContext)(null));\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/Page/PageCanvas.js\n\n\n\n\n\n\n\n\n\nfunction PageCanvas_createSuper(Derived) { var hasNativeReflectConstruct = PageCanvas_isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction PageCanvas_isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\n\n\n\n\n\n\n\n\n\nvar ANNOTATION_MODE = pdf.AnnotationMode;\nvar PageCanvasInternal = /*#__PURE__*/function (_PureComponent) {\n _inherits(PageCanvasInternal, _PureComponent);\n\n var _super = PageCanvas_createSuper(PageCanvasInternal);\n\n function PageCanvasInternal() {\n var _this;\n\n _classCallCheck(this, PageCanvasInternal);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _super.call.apply(_super, [this].concat(args));\n\n _defineProperty(_assertThisInitialized(_this), "canvasElement", /*#__PURE__*/(0,external_commonjs_react_commonjs2_react_amd_react_root_React_.createRef)());\n\n _defineProperty(_assertThisInitialized(_this), "onRenderSuccess", function () {\n _this.renderer = null;\n var _this$props = _this.props,\n onRenderSuccess = _this$props.onRenderSuccess,\n page = _this$props.page,\n scale = _this$props.scale;\n if (onRenderSuccess) onRenderSuccess(makePageCallback(page, scale));\n });\n\n _defineProperty(_assertThisInitialized(_this), "onRenderError", function (error) {\n if (isCancelException(error)) {\n return;\n }\n\n tiny_warning_esm(error);\n var onRenderError = _this.props.onRenderError;\n if (onRenderError) onRenderError(error);\n });\n\n _defineProperty(_assertThisInitialized(_this), "drawPageOnCanvas", function () {\n var canvas = _this.canvasElement.current;\n\n if (!canvas) {\n return null;\n }\n\n var _assertThisInitialize = _assertThisInitialized(_this),\n renderViewport = _assertThisInitialize.renderViewport,\n viewport = _assertThisInitialize.viewport;\n\n var _this$props2 = _this.props,\n canvasBackground = _this$props2.canvasBackground,\n page = _this$props2.page,\n renderForms = _this$props2.renderForms;\n canvas.width = renderViewport.width;\n canvas.height = renderViewport.height;\n canvas.style.width = "".concat(Math.floor(viewport.width), "px");\n canvas.style.height = "".concat(Math.floor(viewport.height), "px");\n var renderContext = {\n annotationMode: renderForms ? ANNOTATION_MODE.ENABLE_FORMS : ANNOTATION_MODE.ENABLE,\n\n get canvasContext() {\n return canvas.getContext(\'2d\');\n },\n\n viewport: renderViewport\n };\n\n if (canvasBackground) {\n renderContext.background = canvasBackground;\n } // If another render is in progress, let\'s cancel it\n\n\n _this.cancelRenderingTask();\n\n _this.renderer = makeCancellablePromise(page.render(renderContext).promise);\n return _this.renderer.promise.then(_this.onRenderSuccess)["catch"](_this.onRenderError);\n });\n\n return _this;\n }\n\n _createClass(PageCanvasInternal, [{\n key: "componentDidMount",\n value: function componentDidMount() {\n this.drawPageOnCanvas();\n }\n }, {\n key: "componentDidUpdate",\n value: function componentDidUpdate(prevProps) {\n var _this$props3 = this.props,\n canvasBackground = _this$props3.canvasBackground,\n page = _this$props3.page,\n renderForms = _this$props3.renderForms;\n\n if (canvasBackground !== prevProps.canvasBackground || renderForms !== prevProps.renderForms) {\n // Ensures the canvas will be re-rendered from scratch. Otherwise all form data will stay.\n page.cleanup();\n this.drawPageOnCanvas();\n }\n }\n }, {\n key: "componentWillUnmount",\n value: function componentWillUnmount() {\n this.cancelRenderingTask();\n var canvas = this.canvasElement.current;\n /**\n * Zeroing the width and height cause most browsers to release graphics\n * resources immediately, which can greatly reduce memory consumption.\n */\n\n if (canvas) {\n canvas.width = 0;\n canvas.height = 0;\n }\n }\n }, {\n key: "cancelRenderingTask",\n value: function cancelRenderingTask() {\n if (this.renderer) {\n this.renderer.cancel();\n this.renderer = null;\n }\n }\n /**\n * Called when a page is rendered successfully.\n */\n\n }, {\n key: "renderViewport",\n get: function get() {\n var _this$props4 = this.props,\n page = _this$props4.page,\n rotate = _this$props4.rotate,\n scale = _this$props4.scale;\n var pixelRatio = getPixelRatio();\n return page.getViewport({\n scale: scale * pixelRatio,\n rotation: rotate\n });\n }\n }, {\n key: "viewport",\n get: function get() {\n var _this$props5 = this.props,\n page = _this$props5.page,\n rotate = _this$props5.rotate,\n scale = _this$props5.scale;\n return page.getViewport({\n scale: scale,\n rotation: rotate\n });\n }\n }, {\n key: "render",\n value: function render() {\n var canvasRef = this.props.canvasRef;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("canvas", {\n className: "react-pdf__Page__canvas",\n dir: "ltr",\n ref: mergeRefs(canvasRef, this.canvasElement),\n style: {\n display: \'block\',\n userSelect: \'none\'\n }\n });\n }\n }]);\n\n return PageCanvasInternal;\n}(external_commonjs_react_commonjs2_react_amd_react_root_React_.PureComponent);\nPageCanvasInternal.propTypes = {\n canvasBackground: (prop_types_default()).string,\n canvasRef: isRef,\n onRenderError: (prop_types_default()).func,\n onRenderSuccess: (prop_types_default()).func,\n page: isPage.isRequired,\n renderForms: (prop_types_default()).bool,\n rotate: isRotate,\n scale: (prop_types_default()).number.isRequired\n};\nfunction PageCanvas(props) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageContext.Consumer, null, function (context) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageCanvasInternal, extends_extends({}, context, props));\n });\n}\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/Page/PageSVG.js\n\n\n\n\n\n\n\n\n\nfunction PageSVG_createSuper(Derived) { var hasNativeReflectConstruct = PageSVG_isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction PageSVG_isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\n\n\n\n\n\n\n\nvar PageSVGInternal = /*#__PURE__*/function (_PureComponent) {\n _inherits(PageSVGInternal, _PureComponent);\n\n var _super = PageSVG_createSuper(PageSVGInternal);\n\n function PageSVGInternal() {\n var _this;\n\n _classCallCheck(this, PageSVGInternal);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _super.call.apply(_super, [this].concat(args));\n\n _defineProperty(_assertThisInitialized(_this), "state", {\n svg: null\n });\n\n _defineProperty(_assertThisInitialized(_this), "onRenderSuccess", function () {\n _this.renderer = null;\n var _this$props = _this.props,\n onRenderSuccess = _this$props.onRenderSuccess,\n page = _this$props.page,\n scale = _this$props.scale;\n if (onRenderSuccess) onRenderSuccess(makePageCallback(page, scale));\n });\n\n _defineProperty(_assertThisInitialized(_this), "onRenderError", function (error) {\n if (isCancelException(error)) {\n return;\n }\n\n tiny_warning_esm(error);\n var onRenderError = _this.props.onRenderError;\n if (onRenderError) onRenderError(error);\n });\n\n _defineProperty(_assertThisInitialized(_this), "renderSVG", function () {\n var page = _this.props.page;\n _this.renderer = page.getOperatorList();\n return _this.renderer.then(function (operatorList) {\n var svgGfx = new pdf.SVGGraphics(page.commonObjs, page.objs);\n _this.renderer = svgGfx.getSVG(operatorList, _this.viewport).then(function (svg) {\n _this.setState({\n svg: svg\n }, _this.onRenderSuccess);\n })["catch"](_this.onRenderError);\n })["catch"](_this.onRenderError);\n });\n\n _defineProperty(_assertThisInitialized(_this), "drawPageOnContainer", function (element) {\n var svg = _this.state.svg;\n\n if (!element || !svg) {\n return;\n } // Append SVG element to the main container, if this hasn\'t been done already\n\n\n if (!element.firstElementChild) {\n element.appendChild(svg);\n }\n\n var _this$viewport = _this.viewport,\n width = _this$viewport.width,\n height = _this$viewport.height;\n svg.setAttribute(\'width\', width);\n svg.setAttribute(\'height\', height);\n });\n\n return _this;\n }\n\n _createClass(PageSVGInternal, [{\n key: "componentDidMount",\n value: function componentDidMount() {\n this.renderSVG();\n }\n /**\n * Called when a page is rendered successfully.\n */\n\n }, {\n key: "viewport",\n get: function get() {\n var _this$props2 = this.props,\n page = _this$props2.page,\n rotate = _this$props2.rotate,\n scale = _this$props2.scale;\n return page.getViewport({\n scale: scale,\n rotation: rotate\n });\n }\n }, {\n key: "render",\n value: function render() {\n var _this2 = this;\n\n var _this$viewport2 = this.viewport,\n width = _this$viewport2.width,\n height = _this$viewport2.height;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("div", {\n className: "react-pdf__Page__svg" // Note: This cannot be shortened, as we need this function to be called with each render.\n ,\n ref: function ref(_ref) {\n return _this2.drawPageOnContainer(_ref);\n },\n style: {\n display: \'block\',\n backgroundColor: \'white\',\n overflow: \'hidden\',\n width: width,\n height: height,\n userSelect: \'none\'\n }\n });\n }\n }]);\n\n return PageSVGInternal;\n}(external_commonjs_react_commonjs2_react_amd_react_root_React_.PureComponent);\nPageSVGInternal.propTypes = {\n onRenderError: (prop_types_default()).func,\n onRenderSuccess: (prop_types_default()).func,\n page: isPage.isRequired,\n rotate: isRotate,\n scale: (prop_types_default()).number.isRequired\n};\nfunction PageSVG(props) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageContext.Consumer, null, function (context) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageSVGInternal, extends_extends({}, context, props));\n });\n}\n// EXTERNAL MODULE: ../demo/node_modules/react-dom/server.browser.js\nvar server_browser = __webpack_require__(190);\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/Page/TextLayer.js\n\n\n\n\n\n\n\n\n\nfunction TextLayer_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\n\nfunction TextLayer_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? TextLayer_ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : TextLayer_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\n\nfunction TextLayer_createSuper(Derived) { var hasNativeReflectConstruct = TextLayer_isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction TextLayer_isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\n\n\n\n\n\n\n\n\n\n\nvar TextLayerInternal = /*#__PURE__*/function (_PureComponent) {\n _inherits(TextLayerInternal, _PureComponent);\n\n var _super = TextLayer_createSuper(TextLayerInternal);\n\n function TextLayerInternal() {\n var _this;\n\n _classCallCheck(this, TextLayerInternal);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _super.call.apply(_super, [this].concat(args));\n\n _defineProperty(_assertThisInitialized(_this), "state", {\n textContent: null\n });\n\n _defineProperty(_assertThisInitialized(_this), "layerElement", /*#__PURE__*/(0,external_commonjs_react_commonjs2_react_amd_react_root_React_.createRef)());\n\n _defineProperty(_assertThisInitialized(_this), "loadTextContent", function () {\n var page = _this.props.page;\n var cancellable = makeCancellablePromise(page.getTextContent());\n _this.runningTask = cancellable;\n cancellable.promise.then(function (textContent) {\n _this.setState({\n textContent: textContent\n }, _this.onLoadSuccess);\n })["catch"](function (error) {\n _this.onLoadError(error);\n });\n });\n\n _defineProperty(_assertThisInitialized(_this), "onLoadSuccess", function () {\n var onGetTextSuccess = _this.props.onGetTextSuccess;\n var textContent = _this.state.textContent;\n if (onGetTextSuccess) onGetTextSuccess(textContent);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onLoadError", function (error) {\n _this.setState({\n textItems: false\n });\n\n tiny_warning_esm(error);\n var onGetTextError = _this.props.onGetTextError;\n if (onGetTextError) onGetTextError(error);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onRenderSuccess", function () {\n var onRenderTextLayerSuccess = _this.props.onRenderTextLayerSuccess;\n if (onRenderTextLayerSuccess) onRenderTextLayerSuccess();\n });\n\n _defineProperty(_assertThisInitialized(_this), "onRenderError", function (error) {\n tiny_warning_esm(error);\n var onRenderTextLayerError = _this.props.onRenderTextLayerError;\n if (onRenderTextLayerError) onRenderTextLayerError(error);\n });\n\n return _this;\n }\n\n _createClass(TextLayerInternal, [{\n key: "componentDidMount",\n value: function componentDidMount() {\n var page = this.props.page;\n invariant(page, \'Attempted to load page text content, but no page was specified.\');\n this.loadTextContent();\n }\n }, {\n key: "componentDidUpdate",\n value: function componentDidUpdate(prevProps) {\n var page = this.props.page;\n\n if (prevProps.page && page !== prevProps.page) {\n this.loadTextContent();\n }\n }\n }, {\n key: "componentWillUnmount",\n value: function componentWillUnmount() {\n cancelRunningTask(this.runningTask);\n }\n }, {\n key: "viewport",\n get: function get() {\n var _this$props = this.props,\n page = _this$props.page,\n rotate = _this$props.rotate,\n scale = _this$props.scale;\n return page.getViewport({\n scale: scale,\n rotation: rotate\n });\n }\n }, {\n key: "unrotatedViewport",\n get: function get() {\n var _this$props2 = this.props,\n page = _this$props2.page,\n scale = _this$props2.scale;\n return page.getViewport({\n scale: scale\n });\n }\n /**\n * It might happen that the page is rotated by default. In such cases, we shouldn\'t rotate\n * text content.\n */\n\n }, {\n key: "rotate",\n get: function get() {\n var _this$props3 = this.props,\n page = _this$props3.page,\n rotate = _this$props3.rotate;\n return rotate - page.rotate;\n }\n }, {\n key: "renderTextLayer",\n value: function renderTextLayer() {\n var _this2 = this;\n\n var textContent = this.state.textContent;\n\n if (!textContent) {\n return null;\n }\n\n var viewport = this.viewport;\n var _this$props4 = this.props,\n customTextRenderer = _this$props4.customTextRenderer,\n enhanceTextSelection = _this$props4.enhanceTextSelection; // If another rendering is in progress, let\'s cancel it\n\n cancelRunningTask(this.runningTask);\n var parameters = {\n container: this.layerElement.current,\n enhanceTextSelection: enhanceTextSelection,\n textContent: textContent,\n viewport: viewport\n };\n this.layerElement.current.innerHTML = \'\';\n this.runningTask = pdf.renderTextLayer(parameters);\n var cancellable = makeCancellablePromise(this.runningTask.promise);\n this.runningTask = cancellable;\n cancellable.promise.then(function () {\n if (customTextRenderer) {\n Array.from(_this2.layerElement.current.children).forEach(function (element, elementIndex) {\n var reactContent = customTextRenderer(TextLayer_objectSpread({\n itemIndex: elementIndex\n }, textContent.items[elementIndex]));\n element.innerHTML = (0,server_browser.renderToStaticMarkup)(reactContent);\n });\n }\n\n _this2.onRenderSuccess();\n })["catch"](function (error) {\n _this2.onRenderError(error);\n });\n }\n }, {\n key: "render",\n value: function render() {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("div", {\n className: "react-pdf__Page__textContent textLayer",\n ref: this.layerElement\n }, this.renderTextLayer());\n }\n }]);\n\n return TextLayerInternal;\n}(external_commonjs_react_commonjs2_react_amd_react_root_React_.PureComponent);\nTextLayerInternal.defaultProps = {\n enhanceTextSelection: true\n};\nTextLayerInternal.propTypes = {\n customTextRenderer: (prop_types_default()).func,\n enhanceTextSelection: (prop_types_default()).bool,\n onGetTextError: (prop_types_default()).func,\n onGetTextSuccess: (prop_types_default()).func,\n onRenderTextLayerError: (prop_types_default()).func,\n onRenderTextLayerSuccess: (prop_types_default()).func,\n page: isPage.isRequired,\n rotate: isRotate,\n scale: (prop_types_default()).number\n};\nfunction TextLayer(props) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageContext.Consumer, null, function (context) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(TextLayerInternal, extends_extends({}, context, props));\n });\n}\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/Page/AnnotationLayer.js\n\n\n\n\n\n\n\n\n\nfunction AnnotationLayer_createSuper(Derived) { var hasNativeReflectConstruct = AnnotationLayer_isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction AnnotationLayer_isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\n\n\n\n\n\n\n\n\n\n\nvar AnnotationLayerInternal = /*#__PURE__*/function (_PureComponent) {\n _inherits(AnnotationLayerInternal, _PureComponent);\n\n var _super = AnnotationLayer_createSuper(AnnotationLayerInternal);\n\n function AnnotationLayerInternal() {\n var _this;\n\n _classCallCheck(this, AnnotationLayerInternal);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _super.call.apply(_super, [this].concat(args));\n\n _defineProperty(_assertThisInitialized(_this), "state", {\n annotations: null\n });\n\n _defineProperty(_assertThisInitialized(_this), "layerElement", /*#__PURE__*/(0,external_commonjs_react_commonjs2_react_amd_react_root_React_.createRef)());\n\n _defineProperty(_assertThisInitialized(_this), "loadAnnotations", function () {\n var page = _this.props.page;\n var cancellable = makeCancellablePromise(page.getAnnotations());\n _this.runningTask = cancellable;\n cancellable.promise.then(function (annotations) {\n _this.setState({\n annotations: annotations\n }, _this.onLoadSuccess);\n })["catch"](function (error) {\n _this.onLoadError(error);\n });\n });\n\n _defineProperty(_assertThisInitialized(_this), "onLoadSuccess", function () {\n var onGetAnnotationsSuccess = _this.props.onGetAnnotationsSuccess;\n var annotations = _this.state.annotations;\n if (onGetAnnotationsSuccess) onGetAnnotationsSuccess(annotations);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onLoadError", function (error) {\n _this.setState({\n annotations: false\n });\n\n tiny_warning_esm(error);\n var onGetAnnotationsError = _this.props.onGetAnnotationsError;\n if (onGetAnnotationsError) onGetAnnotationsError(error);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onRenderSuccess", function () {\n var onRenderAnnotationLayerSuccess = _this.props.onRenderAnnotationLayerSuccess;\n if (onRenderAnnotationLayerSuccess) onRenderAnnotationLayerSuccess();\n });\n\n _defineProperty(_assertThisInitialized(_this), "onRenderError", function (error) {\n tiny_warning_esm(error);\n var onRenderAnnotationLayerError = _this.props.onRenderAnnotationLayerError;\n if (onRenderAnnotationLayerError) onRenderAnnotationLayerError(error);\n });\n\n return _this;\n }\n\n _createClass(AnnotationLayerInternal, [{\n key: "componentDidMount",\n value: function componentDidMount() {\n var page = this.props.page;\n invariant(page, \'Attempted to load page annotations, but no page was specified.\');\n this.loadAnnotations();\n }\n }, {\n key: "componentDidUpdate",\n value: function componentDidUpdate(prevProps) {\n var _this$props = this.props,\n page = _this$props.page,\n renderForms = _this$props.renderForms;\n\n if (prevProps.page && page !== prevProps.page || renderForms !== prevProps.renderForms) {\n this.loadAnnotations();\n }\n }\n }, {\n key: "componentWillUnmount",\n value: function componentWillUnmount() {\n cancelRunningTask(this.runningTask);\n }\n }, {\n key: "viewport",\n get: function get() {\n var _this$props2 = this.props,\n page = _this$props2.page,\n rotate = _this$props2.rotate,\n scale = _this$props2.scale;\n return page.getViewport({\n scale: scale,\n rotation: rotate\n });\n }\n }, {\n key: "renderAnnotationLayer",\n value: function renderAnnotationLayer() {\n var annotations = this.state.annotations;\n\n if (!annotations) {\n return;\n }\n\n var _this$props3 = this.props,\n imageResourcesPath = _this$props3.imageResourcesPath,\n linkService = _this$props3.linkService,\n page = _this$props3.page,\n renderForms = _this$props3.renderForms;\n var viewport = this.viewport.clone({\n dontFlip: true\n });\n var parameters = {\n annotations: annotations,\n div: this.layerElement.current,\n imageResourcesPath: imageResourcesPath,\n linkService: linkService,\n page: page,\n renderForms: renderForms,\n viewport: viewport\n };\n this.layerElement.current.innerHTML = \'\';\n\n try {\n pdf.AnnotationLayer.render(parameters);\n this.onRenderSuccess();\n } catch (error) {\n this.onRenderError(error);\n }\n }\n }, {\n key: "render",\n value: function render() {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("div", {\n className: "react-pdf__Page__annotations annotationLayer",\n ref: this.layerElement\n }, this.renderAnnotationLayer());\n }\n }]);\n\n return AnnotationLayerInternal;\n}(external_commonjs_react_commonjs2_react_amd_react_root_React_.PureComponent);\nAnnotationLayerInternal.propTypes = {\n imageResourcesPath: (prop_types_default()).string,\n linkService: isLinkService.isRequired,\n onGetAnnotationsError: (prop_types_default()).func,\n onGetAnnotationsSuccess: (prop_types_default()).func,\n onRenderAnnotationLayerError: (prop_types_default()).func,\n onRenderAnnotationLayerSuccess: (prop_types_default()).func,\n page: isPage,\n renderForms: (prop_types_default()).bool,\n rotate: isRotate,\n scale: (prop_types_default()).number\n};\n\nvar AnnotationLayer = function AnnotationLayer(props) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(esm_DocumentContext.Consumer, null, function (documentContext) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageContext.Consumer, null, function (pageContext) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(AnnotationLayerInternal, extends_extends({}, documentContext, pageContext, props));\n });\n });\n};\n\n/* harmony default export */ const Page_AnnotationLayer = (AnnotationLayer);\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/Page.js\n\n\n\n\n\n\n\n\n\nfunction Page_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\n\nfunction Page_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? Page_ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : Page_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\n\nfunction Page_createSuper(Derived) { var hasNativeReflectConstruct = Page_isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction Page_isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar defaultScale = 1;\nvar PageInternal = /*#__PURE__*/function (_PureComponent) {\n _inherits(PageInternal, _PureComponent);\n\n var _super = Page_createSuper(PageInternal);\n\n function PageInternal() {\n var _this;\n\n _classCallCheck(this, PageInternal);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _super.call.apply(_super, [this].concat(args));\n\n _defineProperty(_assertThisInitialized(_this), "state", {\n page: null\n });\n\n _defineProperty(_assertThisInitialized(_this), "pageElement", /*#__PURE__*/(0,external_commonjs_react_commonjs2_react_amd_react_root_React_.createRef)());\n\n _defineProperty(_assertThisInitialized(_this), "onLoadSuccess", function () {\n var _this$props = _this.props,\n onLoadSuccess = _this$props.onLoadSuccess,\n registerPage = _this$props.registerPage;\n var page = _this.state.page;\n if (onLoadSuccess) onLoadSuccess(makePageCallback(page, _this.scale));\n if (registerPage) registerPage(_this.pageIndex, _this.pageElement.current);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onLoadError", function (error) {\n _this.setState({\n page: false\n });\n\n tiny_warning_esm(error);\n var onLoadError = _this.props.onLoadError;\n if (onLoadError) onLoadError(error);\n });\n\n _defineProperty(_assertThisInitialized(_this), "loadPage", function () {\n var pdf = _this.props.pdf;\n\n var pageNumber = _this.getPageNumber();\n\n if (!pageNumber) {\n return;\n }\n\n _this.setState(function (prevState) {\n if (!prevState.page) {\n return null;\n }\n\n return {\n page: null\n };\n });\n\n var cancellable = makeCancellablePromise(pdf.getPage(pageNumber));\n _this.runningTask = cancellable;\n cancellable.promise.then(function (page) {\n _this.setState({\n page: page\n }, _this.onLoadSuccess);\n })["catch"](function (error) {\n _this.onLoadError(error);\n });\n });\n\n return _this;\n }\n\n _createClass(PageInternal, [{\n key: "componentDidMount",\n value: function componentDidMount() {\n var pdf = this.props.pdf;\n invariant(pdf, \'Attempted to load a page, but no document was specified.\');\n this.loadPage();\n }\n }, {\n key: "componentDidUpdate",\n value: function componentDidUpdate(prevProps) {\n var pdf = this.props.pdf;\n\n if (prevProps.pdf && pdf !== prevProps.pdf || this.getPageNumber() !== this.getPageNumber(prevProps)) {\n var unregisterPage = this.props.unregisterPage;\n if (unregisterPage) unregisterPage(this.getPageIndex(prevProps));\n this.loadPage();\n }\n }\n }, {\n key: "componentWillUnmount",\n value: function componentWillUnmount() {\n var unregisterPage = this.props.unregisterPage;\n if (unregisterPage) unregisterPage(this.pageIndex);\n cancelRunningTask(this.runningTask);\n }\n }, {\n key: "childContext",\n get: function get() {\n var page = this.state.page;\n\n if (!page) {\n return {};\n }\n\n var _this$props2 = this.props,\n canvasBackground = _this$props2.canvasBackground,\n customTextRenderer = _this$props2.customTextRenderer,\n enhanceTextSelection = _this$props2.enhanceTextSelection,\n onGetAnnotationsError = _this$props2.onGetAnnotationsError,\n onGetAnnotationsSuccess = _this$props2.onGetAnnotationsSuccess,\n onGetTextError = _this$props2.onGetTextError,\n onGetTextSuccess = _this$props2.onGetTextSuccess,\n onRenderAnnotationLayerError = _this$props2.onRenderAnnotationLayerError,\n onRenderAnnotationLayerSuccess = _this$props2.onRenderAnnotationLayerSuccess,\n onRenderError = _this$props2.onRenderError,\n onRenderSuccess = _this$props2.onRenderSuccess,\n onRenderTextLayerError = _this$props2.onRenderTextLayerError,\n onRenderTextLayerSuccess = _this$props2.onRenderTextLayerSuccess,\n renderForms = _this$props2.renderForms,\n renderInteractiveForms = _this$props2.renderInteractiveForms;\n return {\n canvasBackground: canvasBackground,\n customTextRenderer: customTextRenderer,\n enhanceTextSelection: enhanceTextSelection,\n onGetAnnotationsError: onGetAnnotationsError,\n onGetAnnotationsSuccess: onGetAnnotationsSuccess,\n onGetTextError: onGetTextError,\n onGetTextSuccess: onGetTextSuccess,\n onRenderAnnotationLayerError: onRenderAnnotationLayerError,\n onRenderAnnotationLayerSuccess: onRenderAnnotationLayerSuccess,\n onRenderError: onRenderError,\n onRenderSuccess: onRenderSuccess,\n onRenderTextLayerError: onRenderTextLayerError,\n onRenderTextLayerSuccess: onRenderTextLayerSuccess,\n page: page,\n renderForms: renderForms !== null && renderForms !== void 0 ? renderForms : renderInteractiveForms,\n // For backward compatibility\n rotate: this.rotate,\n scale: this.scale\n };\n }\n /**\n * Called when a page is loaded successfully\n */\n\n }, {\n key: "getPageIndex",\n value: function getPageIndex() {\n var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props;\n\n if (isProvided(props.pageNumber)) {\n return props.pageNumber - 1;\n }\n\n if (isProvided(props.pageIndex)) {\n return props.pageIndex;\n }\n\n return null;\n }\n }, {\n key: "getPageNumber",\n value: function getPageNumber() {\n var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props;\n\n if (isProvided(props.pageNumber)) {\n return props.pageNumber;\n }\n\n if (isProvided(props.pageIndex)) {\n return props.pageIndex + 1;\n }\n\n return null;\n }\n }, {\n key: "pageIndex",\n get: function get() {\n return this.getPageIndex();\n }\n }, {\n key: "pageNumber",\n get: function get() {\n return this.getPageNumber();\n }\n }, {\n key: "rotate",\n get: function get() {\n var rotate = this.props.rotate;\n\n if (isProvided(rotate)) {\n return rotate;\n }\n\n var page = this.state.page;\n\n if (!page) {\n return null;\n }\n\n return page.rotate;\n }\n }, {\n key: "scale",\n get: function get() {\n var page = this.state.page;\n\n if (!page) {\n return null;\n }\n\n var _this$props3 = this.props,\n scale = _this$props3.scale,\n width = _this$props3.width,\n height = _this$props3.height;\n var rotate = this.rotate; // Be default, we\'ll render page at 100% * scale width.\n\n var pageScale = 1; // Passing scale explicitly null would cause the page not to render\n\n var scaleWithDefault = scale === null ? defaultScale : scale; // If width/height is defined, calculate the scale of the page so it could be of desired width.\n\n if (width || height) {\n var viewport = page.getViewport({\n scale: 1,\n rotation: rotate\n });\n pageScale = width ? width / viewport.width : height / viewport.height;\n }\n\n return scaleWithDefault * pageScale;\n }\n }, {\n key: "eventProps",\n get: function get() {\n var _this2 = this;\n\n return esm(this.props, function () {\n var page = _this2.state.page;\n\n if (!page) {\n return page;\n }\n\n return makePageCallback(page, _this2.scale);\n });\n }\n }, {\n key: "pageKey",\n get: function get() {\n var page = this.state.page;\n return "".concat(page.pageIndex, "@").concat(this.scale, "/").concat(this.rotate);\n }\n }, {\n key: "pageKeyNoScale",\n get: function get() {\n var page = this.state.page;\n return "".concat(page.pageIndex, "/").concat(this.rotate);\n }\n }, {\n key: "renderMainLayer",\n value: function renderMainLayer() {\n var _this$props4 = this.props,\n canvasRef = _this$props4.canvasRef,\n renderMode = _this$props4.renderMode;\n\n switch (renderMode) {\n case \'none\':\n return null;\n\n case \'svg\':\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageSVG, {\n key: "".concat(this.pageKeyNoScale, "_svg")\n });\n\n case \'canvas\':\n default:\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageCanvas, {\n key: "".concat(this.pageKey, "_canvas"),\n canvasRef: canvasRef\n });\n }\n }\n }, {\n key: "renderTextLayer",\n value: function renderTextLayer() {\n var renderTextLayer = this.props.renderTextLayer;\n\n if (!renderTextLayer) {\n return null;\n }\n\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(TextLayer, {\n key: "".concat(this.pageKey, "_text")\n });\n }\n }, {\n key: "renderAnnotationLayer",\n value: function renderAnnotationLayer() {\n var renderAnnotationLayer = this.props.renderAnnotationLayer;\n\n if (!renderAnnotationLayer) {\n return null;\n }\n /**\n * As of now, PDF.js 2.0.943 returns warnings on unimplemented annotations in SVG mode.\n * Therefore, as a fallback, we render "traditional" AnnotationLayer component.\n */\n\n\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(Page_AnnotationLayer, {\n key: "".concat(this.pageKey, "_annotations")\n });\n }\n }, {\n key: "renderChildren",\n value: function renderChildren() {\n var children = this.props.children;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageContext.Provider, {\n value: this.childContext\n }, this.renderMainLayer(), this.renderTextLayer(), this.renderAnnotationLayer(), children);\n }\n }, {\n key: "renderContent",\n value: function renderContent() {\n var pageNumber = this.pageNumber;\n var pdf = this.props.pdf;\n var page = this.state.page;\n\n if (!pageNumber) {\n var noData = this.props.noData;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(Message, {\n type: "no-data"\n }, typeof noData === \'function\' ? noData() : noData);\n }\n\n if (pdf === null || page === null) {\n var loading = this.props.loading;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(Message, {\n type: "loading"\n }, typeof loading === \'function\' ? loading() : loading);\n }\n\n if (pdf === false || page === false) {\n var error = this.props.error;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(Message, {\n type: "error"\n }, typeof error === \'function\' ? error() : error);\n }\n\n return this.renderChildren();\n }\n }, {\n key: "render",\n value: function render() {\n var pageNumber = this.pageNumber;\n var _this$props5 = this.props,\n className = _this$props5.className,\n inputRef = _this$props5.inputRef;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("div", extends_extends({\n className: mergeClassNames(\'react-pdf__Page\', className),\n "data-page-number": pageNumber,\n ref: mergeRefs(inputRef, this.pageElement),\n style: {\n position: \'relative\'\n }\n }, this.eventProps), this.renderContent());\n }\n }]);\n\n return PageInternal;\n}(external_commonjs_react_commonjs2_react_amd_react_root_React_.PureComponent);\nPageInternal.defaultProps = {\n error: \'Failed to load the page.\',\n loading: \'Loading page…\',\n noData: \'No page specified.\',\n renderAnnotationLayer: true,\n renderForms: false,\n renderMode: \'canvas\',\n renderTextLayer: true,\n scale: defaultScale\n};\nvar Page_isFunctionOrNode = prop_types_default().oneOfType([(prop_types_default()).func, (prop_types_default()).node]);\nPageInternal.propTypes = Page_objectSpread(Page_objectSpread({}, eventProps), {}, {\n canvasBackground: (prop_types_default()).string,\n children: (prop_types_default()).node,\n className: isClassName,\n customTextRenderer: (prop_types_default()).func,\n enhanceTextSelection: (prop_types_default()).bool,\n error: Page_isFunctionOrNode,\n height: (prop_types_default()).number,\n imageResourcesPath: (prop_types_default()).string,\n inputRef: isRef,\n loading: Page_isFunctionOrNode,\n noData: Page_isFunctionOrNode,\n onGetTextError: (prop_types_default()).func,\n onGetTextSuccess: (prop_types_default()).func,\n onLoadError: (prop_types_default()).func,\n onLoadSuccess: (prop_types_default()).func,\n onRenderError: (prop_types_default()).func,\n onRenderSuccess: (prop_types_default()).func,\n onRenderTextLayerError: (prop_types_default()).func,\n onRenderTextLayerSuccess: (prop_types_default()).func,\n pageIndex: isPageIndex,\n pageNumber: isPageNumber,\n pdf: isPdf,\n registerPage: (prop_types_default()).func,\n renderAnnotationLayer: (prop_types_default()).bool,\n renderForms: (prop_types_default()).bool,\n renderInteractiveForms: (prop_types_default()).bool,\n // For backward compatibility\n renderMode: isRenderMode,\n renderTextLayer: (prop_types_default()).bool,\n rotate: isRotate,\n scale: (prop_types_default()).number,\n unregisterPage: (prop_types_default()).func,\n width: (prop_types_default()).number\n});\n\nfunction Page(props, ref) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(esm_DocumentContext.Consumer, null, function (context) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageInternal, extends_extends({\n ref: ref\n }, context, props));\n });\n}\n\n/* harmony default export */ const esm_Page = (/*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().forwardRef(Page));\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/entry.js\n\n\n\n\n\ndisplayWorkerWarning();\npdf.GlobalWorkerOptions.workerSrc = \'pdf.worker.js\';\n\n;// CONCATENATED MODULE: ./src/utils/ScrollDirectionDetector.ts\nvar ScrollDirection;\n(function (ScrollDirection) {\n ScrollDirection["UP"] = "UP";\n ScrollDirection["DOWN"] = "DOWN";\n})(ScrollDirection || (ScrollDirection = {}));\nclass ScrollDetector {\n constructor(el, setScrollDirection, setIsAtTop, setScrollThresholdReachedInDirection, scrollThreshold) {\n this._onScroll = () => {\n const currScrollTop = this._el.scrollTop;\n if (this._isAtTop !== (currScrollTop === 0)) {\n this._isAtTop = currScrollTop === 0;\n this._setIsAtTop(currScrollTop === 0);\n }\n if (this._lastScrollTop === currScrollTop) {\n return;\n }\n // Determine direction\n const currScrollDirection = (() => {\n if (currScrollTop <= 0) {\n return ScrollDirection.DOWN;\n }\n return this._lastScrollTop < currScrollTop ? ScrollDirection.DOWN : ScrollDirection.UP;\n })();\n // Update state, if changed\n this._lastScrollTop = currScrollTop;\n if (this._lastScrollDirection !== currScrollDirection) {\n this._lastScrollDirection = currScrollDirection;\n this._setScrollDirection(currScrollDirection);\n this._lastScrollTopBeforeDirectionChange = currScrollTop;\n this._isScrollThresholdReachedInDirection = null;\n if (this._setScrollThresholdReachedInDirection && !this._isAtTop) {\n this._setScrollThresholdReachedInDirection(null);\n }\n }\n else {\n if (this._scrollThreshold && this._setScrollThresholdReachedInDirection) {\n const scrolledAmount = Math.abs(this._lastScrollTopBeforeDirectionChange - currScrollTop);\n if (scrolledAmount >= this._scrollThreshold) {\n this._isScrollThresholdReachedInDirection = this._lastScrollDirection;\n this._setScrollThresholdReachedInDirection(this._lastScrollDirection);\n }\n }\n }\n };\n this._el = el;\n this._lastScrollTop = this._el.scrollTop;\n this._lastScrollDirection = null;\n this._setScrollDirection = setScrollDirection;\n this._isAtTop = null;\n this._setIsAtTop = setIsAtTop;\n this._lastScrollTopBeforeDirectionChange = this._el.scrollTop;\n this._scrollThreshold = scrollThreshold;\n this._isScrollThresholdReachedInDirection = null;\n this._setScrollThresholdReachedInDirection = setScrollThresholdReachedInDirection;\n }\n attachScrollListener() {\n var _a, _b;\n if (((_b = (_a = this._el) === null || _a === void 0 ? void 0 : _a.tagName) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === \'html\') {\n window.addEventListener(\'scroll\', this._onScroll, false);\n return;\n }\n this._el.addEventListener(\'scroll\', this._onScroll, false);\n }\n detachScrollListener() {\n var _a, _b;\n if (((_b = (_a = this._el) === null || _a === void 0 ? void 0 : _a.tagName) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === \'html\') {\n window.removeEventListener(\'scroll\', this._onScroll, false);\n return;\n }\n this._el.removeEventListener(\'scroll\', this._onScroll, false);\n }\n}\n\n;// CONCATENATED MODULE: ./src/utils/VisibleEntriesDetector.ts\nconst DEFAULT_ROOT_MARGIN = \'50px\';\n// This array is a range from 0.0001 to 1 range of threshold. It will help with detecting\n// on scroll with a better % compare to a fix threshold but not firing too frequent that\n// can hamper our performance.\nconst DEFAULT_THRESHOLD = [0.0001, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.99];\nclass VisibleEntriesDetector {\n constructor({ root, thresHold, setVisibleEntries, onVisibleEntriesChange, }) {\n var _a;\n this._root = root;\n this._lastVisibleEntries = new Map();\n this._setVisibleEntries = setVisibleEntries;\n this._onVisibleEntriesChange = onVisibleEntriesChange;\n this._observer = new IntersectionObserver(entries => {\n // Collect visible and hidden elements\n const visibleEntries = entries.filter(entry => entry.isIntersecting);\n const hiddenEntries = entries.filter(entry => !entry.isIntersecting);\n // Determine what needs saved\n const newVisibleEntries = this._onVisibleEntriesChange({\n visibleEntries,\n hiddenEntries,\n lastEntries: this._lastVisibleEntries,\n });\n const frozenEntries = new Map(newVisibleEntries);\n Object.freeze(frozenEntries);\n this._lastVisibleEntries = frozenEntries;\n this._setVisibleEntries(frozenEntries);\n }, \n // Default setting for intersection observer\n {\n root: ((_a = this._root.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === \'html\' ? null : this._root,\n rootMargin: DEFAULT_ROOT_MARGIN,\n threshold: thresHold ? thresHold : DEFAULT_THRESHOLD,\n });\n }\n observeNodes(selector) {\n for (const node of this._root.querySelectorAll(selector)) {\n this._observer.observe(node);\n }\n }\n destroy() {\n this._observer.disconnect();\n }\n}\n\n;// CONCATENATED MODULE: ./src/context/ScrollContext.ts\n\n\n\n\n\nconst OUTLINE_ATTRIBUTE = \'data-outline-target-dest\';\nconst OUTLINE_SELECTOR = \'.reader__page__outline-target\';\nconst PAGE_NUMBER_ATTRIBUTE = \'data-page-number\';\nconst PAGE_NUMBER_SELECTOR = `.reader__page[${PAGE_NUMBER_ATTRIBUTE}]`;\nconst DEFAULT_CONTEXT = {\n scrollDirection: null,\n visibleOutlineTargets: new Map(),\n visiblePageRatios: new Map(),\n isOutlineTargetVisible: opts => {\n logProviderWarning(`isOutlineTargetVisible(${JSON.stringify(opts)})`, \'ScrollContext\');\n return false;\n },\n isPageVisible: opts => {\n logProviderWarning(`isPageVisible(${JSON.stringify(opts)})`, \'ScrollContext\');\n return false;\n },\n resetScrollObservers: () => {\n logProviderWarning(`resetScrollObservers()`, \'ScrollContext\');\n },\n setScrollRoot: (_el) => {\n logProviderWarning(`setScrollRoot(...)`, \'ScrollContext\');\n },\n scrollToOutlineTarget: dest => {\n logProviderWarning(`scrollToOutlineTarget(${dest})`, \'ScrollContext\');\n },\n setScrollThreshold: (scrollThreshold) => {\n logProviderWarning(`setScrollThreshold(${scrollThreshold})`, \'ScrollContext\');\n },\n scrollToPage: opts => {\n logProviderWarning(`scrollToPage(${JSON.stringify(opts)})`, \'ScrollContext\');\n },\n updateScrollPosition: zoomMultiplier => {\n logProviderWarning(`updateScrollPosition(${JSON.stringify(zoomMultiplier)})`, \'ScrollContext\');\n },\n setIsOutlineClicked: opts => {\n logProviderWarning(`setIsOutlineGetClicked(${JSON.stringify(opts)})`, \'ScrollContext\');\n },\n scrollThresholdReachedInDirection: null,\n isAtTop: null,\n isOutlineClicked: null,\n};\nconst ScrollContext = external_commonjs_react_commonjs2_react_amd_react_root_React_.createContext(DEFAULT_CONTEXT);\nfunction useScrollContextProps() {\n // Node used for observing the scroll position\n const [scrollRoot, setScrollRoot] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(null);\n // Determine scroll direction\n const [scrollDirection, setScrollDirection] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(null);\n const [scrollThreshold, setScrollThreshold] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(null);\n const [scrollThresholdReachedInDirection, setScrollThresholdReachedInDirection] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(null);\n const [isAtTop, setIsAtTop] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(null);\n const [isOutlineClicked, setIsOutlineClicked] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(null);\n external_commonjs_react_commonjs2_react_amd_react_root_React_.useEffect(() => {\n const scrollElem = scrollRoot || document.documentElement;\n if (!scrollElem) {\n return;\n }\n let scrollDirectionDetector;\n if (!scrollThreshold) {\n // scroll threshold is optional\n scrollDirectionDetector = new ScrollDetector(scrollElem, setScrollDirection, setIsAtTop);\n }\n else {\n scrollDirectionDetector = new ScrollDetector(scrollElem, setScrollDirection, setIsAtTop, setScrollThresholdReachedInDirection, scrollThreshold);\n }\n scrollDirectionDetector.attachScrollListener();\n return () => {\n scrollDirectionDetector.detachScrollListener();\n };\n }, [scrollRoot, scrollThreshold]);\n // Causes the IntersectionObservers to disconnect and be recreated (useful when DOM changes)\n const [observerIndex, setObserverIndex] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(0);\n const resetScrollObservers = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(() => {\n setObserverIndex(observerIndex + 1);\n }, [observerIndex]);\n const [visibleOutlineTargets, setVisibleOutlineNodes] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(() => {\n const map = new Map();\n Object.freeze(map);\n return map;\n });\n const [visiblePageRatios, setVisiblePageRatios] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(() => {\n const map = new Map();\n Object.freeze(map);\n return map;\n });\n const isOutlineTargetVisible = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((dest) => {\n return visibleOutlineTargets.has(dest);\n }, [visibleOutlineTargets]);\n const scrollToOutlineTarget = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((dest) => {\n var _a;\n setIsOutlineClicked(true);\n (_a = document\n .querySelector(`[data-outline-target-dest="${dest}"]`)) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: \'smooth\' });\n }, []);\n const isPageVisible = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(({ pageNumber, pageIndex }) => {\n if (typeof pageIndex === \'number\') {\n pageNumber = pageIndex + 1;\n }\n if (typeof pageNumber !== \'number\') {\n return false;\n }\n return visiblePageRatios.has(pageNumber);\n }, [visiblePageRatios]);\n const scrollToPage = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(({ pageNumber, pageIndex }) => {\n var _a;\n if (typeof pageNumber === \'number\') {\n pageIndex = pageNumber - 1;\n }\n if (typeof pageIndex !== \'number\') {\n return;\n }\n (_a = document\n .getElementById(generatePageIdFromIndex(pageIndex))) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: \'smooth\' });\n }, []);\n // Watch outline nodes\n external_commonjs_react_commonjs2_react_amd_react_root_React_.useEffect(() => {\n const root = scrollRoot || document.documentElement;\n const detector = new VisibleEntriesDetector({\n root: root,\n setVisibleEntries: setVisibleOutlineNodes,\n onVisibleEntriesChange: ({ visibleEntries, hiddenEntries, lastEntries }) => {\n hiddenEntries.map(entry => lastEntries.delete(entry.target.getAttribute(OUTLINE_ATTRIBUTE)));\n const newEntries = new Map(lastEntries);\n visibleEntries.map(entry => newEntries.set(entry.target.getAttribute(OUTLINE_ATTRIBUTE), entry.intersectionRatio));\n return newEntries;\n },\n });\n detector.observeNodes(OUTLINE_SELECTOR);\n return () => {\n detector.destroy();\n };\n }, [scrollRoot, observerIndex]);\n // Watch pages\n external_commonjs_react_commonjs2_react_amd_react_root_React_.useEffect(() => {\n const root = scrollRoot || document.documentElement;\n const detector = new VisibleEntriesDetector({\n root: root,\n setVisibleEntries: setVisiblePageRatios,\n onVisibleEntriesChange: ({ visibleEntries, hiddenEntries, lastEntries }) => {\n hiddenEntries.map(entry => { var _a; return lastEntries.delete(parseInt(((_a = entry.target) === null || _a === void 0 ? void 0 : _a.getAttribute(PAGE_NUMBER_ATTRIBUTE)) || \'\', 10)); });\n const newEntries = new Map(lastEntries);\n visibleEntries.map(entry => {\n var _a;\n return newEntries.set(parseInt(((_a = entry.target) === null || _a === void 0 ? void 0 : _a.getAttribute(PAGE_NUMBER_ATTRIBUTE)) || \'\', 10), entry.intersectionRatio);\n });\n return newEntries;\n },\n });\n detector.observeNodes(PAGE_NUMBER_SELECTOR);\n return () => {\n detector.destroy();\n };\n }, [scrollRoot, observerIndex]);\n // calculates a new scroll position after zooming in/out so user doesnt lose their position\n const updateScrollPosition = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((zoomMultiplier) => {\n const root = scrollRoot || document.documentElement;\n if (!root) {\n return;\n }\n const newScrollTop = Math.floor(root.scrollTop * zoomMultiplier);\n setTimeout(() => {\n root.scrollTop = newScrollTop;\n }, 0);\n }, [scrollRoot]);\n return {\n isOutlineTargetVisible,\n isPageVisible,\n scrollDirection,\n visibleOutlineTargets,\n visiblePageRatios,\n resetScrollObservers,\n setScrollRoot,\n scrollToOutlineTarget,\n setScrollThreshold,\n scrollToPage,\n updateScrollPosition,\n setIsOutlineClicked,\n scrollThresholdReachedInDirection,\n isAtTop,\n isOutlineClicked,\n };\n}\n\n;// CONCATENATED MODULE: ./src/context/UiContext.ts\n\n\nconst UiContext = external_commonjs_react_commonjs2_react_amd_react_root_React_.createContext({\n errorMessage: null,\n isLoading: false,\n isShowingHighlightOverlay: false,\n isShowingOutline: false,\n isShowingTextHighlight: false,\n setErrorMessage: errorMessage => {\n logProviderWarning(`setErrorMessage(${errorMessage})`, \'UiContext\');\n },\n setIsShowingOutline: isShowingOutline => {\n logProviderWarning(`setIsShowingOutline(${isShowingOutline})`, \'UiContext\');\n },\n setIsLoading: isLoading => {\n logProviderWarning(`setIsLoading(${isLoading})`, \'UiContext\');\n },\n setIsShowingHighlightOverlay: isShowingHighlightOverlay => {\n logProviderWarning(`setIsShowingHighlightOverlay(${isShowingHighlightOverlay})`, \'UiContext\');\n },\n setIsShowingTextHighlight: isShowingTextHighlight => {\n logProviderWarning(`setIsShowingTextHighlight(${isShowingTextHighlight})`, \'UiContext\');\n },\n});\nfunction useUiContextProps() {\n const [errorMessage, setErrorMessage] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(null);\n const [isLoading, setIsLoading] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(true);\n const [isShowingHighlightOverlay, setIsShowingHighlightOverlay] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(false);\n const [isShowingOutline, setIsShowingOutline] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(false);\n const [isShowingTextHighlight, setIsShowingTextHighlight] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(false);\n return {\n errorMessage,\n isLoading,\n isShowingHighlightOverlay,\n isShowingOutline,\n isShowingTextHighlight,\n setErrorMessage,\n setIsLoading,\n setIsShowingHighlightOverlay,\n setIsShowingOutline,\n setIsShowingTextHighlight,\n };\n}\n\n;// CONCATENATED MODULE: ./src/utils/errorMessage.ts\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction getErrorMessage(error) {\n if (!error) {\n return \'Unknown error\';\n }\n if (typeof error === \'string\') {\n return error;\n }\n if (error instanceof Error) {\n return error.message;\n }\n if (typeof error.error === \'string\') {\n return error.error;\n }\n return error.toString();\n}\n\n;// CONCATENATED MODULE: ./src/utils/pdfWorker.ts\n\n// Set PDFjs worker source or else PDF will not load when this library is imported as a package.\nfunction initPdfWorker() {\n pdf.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdf.version}/pdf.worker.min.js`;\n}\n\n;// CONCATENATED MODULE: ./src/utils/scale.ts\n// We assume 96 DPI for display\n// TODO: There are more accurate ways to do this, but this is what ScholarPhi does now\nconst DPI = 96;\n// PDF units are in 1/72nds of an inch\nconst USER_UNIT_DENOMINATOR = 72;\n/**\n * Given a PDFPageProxy, calculates the screen pixel size of the PDF page at 100% scale\n * @param page The PDFPageProxy to calculate size for\n * @returns Pixel size of a page at 100% scale assuming 96DPI display\n */\nfunction computePageDimensions(page) {\n const [leftPx, topPx, rightPx, bottomPx] = page.view;\n const PPI = (page.userUnit / USER_UNIT_DENOMINATOR) * DPI;\n return {\n height: (bottomPx - topPx) * PPI,\n width: (rightPx - leftPx) * PPI,\n };\n}\n\n;// CONCATENATED MODULE: ./src/components/types/destination.ts\n/**\n * This class is the definition of the first item when Destination is returned as an array.\n * It is created based on the same class in \'react-pdf\' library:\n * https://github.com/wojtekmaj/react-pdf/blob/ca4453f123af51e2faed39a8a62800901030459a/src/Ref.js\n */\nclass destination_Ref {\n constructor({ num, gen }) {\n this.num = num;\n this.gen = gen;\n }\n toString() {\n return this.gen !== 0 ? `${this.num}R${this.gen}` : `${this.num}R`;\n }\n}\n\n;// CONCATENATED MODULE: ./src/components/DocumentWrapper.tsx\nvar DocumentWrapper_rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\n\n\n\n\n\n\n\nconst DocumentWrapper = (_a) => {\n var { children } = _a, extraProps = DocumentWrapper_rest(_a, ["children"]);\n initPdfWorker();\n const { pdfDocProxy, setNumPages, setPageDimensions, setPdfDocProxy } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(DocumentContext_DocumentContext);\n const { resetScrollObservers } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(ScrollContext);\n const { rotation } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(TransformContext);\n const { setErrorMessage, setIsLoading } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(UiContext);\n function getFirstPage(pdfDoc) {\n // getPage uses 1-indexed pageNumber, not 0-indexed pageIndex\n return pdfDoc.getPage(1);\n }\n external_commonjs_react_commonjs2_react_amd_react_root_React_.useEffect(() => {\n resetScrollObservers();\n }, []);\n const onPdfLoadSuccess = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((pdfDoc) => {\n setNumPages(pdfDoc.numPages);\n getFirstPage(pdfDoc)\n .then(page => {\n setPageDimensions(computePageDimensions(page));\n setErrorMessage(null);\n })\n .catch(error => {\n setErrorMessage(getErrorMessage(error));\n })\n .finally(() => {\n setIsLoading(false);\n });\n if (!pdfDocProxy) {\n setPdfDocProxy(pdfDoc);\n }\n }, []);\n const onPdfLoadError = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((error) => {\n setErrorMessage(getErrorMessage(error));\n setIsLoading(false);\n }, []);\n const onItemClicked = (param) => {\n if (!pdfDocProxy) {\n return;\n }\n // Scroll to the destination of the item\n pdfDocProxy.getDestination(param.dest).then(destArray => {\n if (!destArray) {\n return;\n }\n const [ref, , , bottomPoints] = destArray;\n pdfDocProxy.getPageIndex(new destination_Ref(ref)).then(refInfo => {\n scrollToPosition(parseInt(refInfo.toString()), 0, bottomPoints, rotation);\n });\n });\n };\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(Document, Object.assign({ options: { cMapUrl: \'cmaps/\', cMapPacked: true }, onLoadError: onPdfLoadError, onLoadSuccess: onPdfLoadSuccess, externalLinkTarget: "_blank", renderMode: "none", \n // @ts-ignore: the arguments should be { dest, pageIndex, pageNumber }\n // @types/react-pdf hasn\'t updated the function signature\n // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/d73eb652e0ba8f89395a0ef2ba69cf1e640ce5be/types/react-pdf/dist/Document.d.ts#L72\n onItemClick: onItemClicked }, extraProps), children));\n};\n\n;// CONCATENATED MODULE: ./src/components/DownloadButton.tsx\nvar DownloadButton_rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n/**\n * HTML anchor tag allows you to download a file from the same origin.\n * This is a workaround to download a file served from a different origin\n */\nconst DownloadButton = (_a) => {\n var { pdfUrl, children, className } = _a, extraProps = DownloadButton_rest(_a, ["pdfUrl", "children", "className"]);\n const [fetching, setFetching] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(false);\n const download = () => {\n setFetching(true);\n fetch(pdfUrl)\n .then(response => response.blob())\n .then(blob => {\n setFetching(false);\n const blobURL = URL.createObjectURL(blob);\n const a = document.createElement(\'a\');\n a.href = blobURL;\n a.download = pdfUrl.split(\'/\').pop() || pdfUrl;\n document.body.appendChild(a);\n a.click();\n });\n };\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("button", Object.assign({ disabled: fetching, onClick: () => download(), "aria-label": "Download PDF", className: `reader__download-btn ${className}` }, extraProps), children ? children : \'Download\'));\n};\n\n;// CONCATENATED MODULE: ./src/components/HighlightOverlay.tsx\nvar HighlightOverlay_rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\nconst HighlightOverlay = (_a) => {\n var { children, pageIndex } = _a, extraProps = HighlightOverlay_rest(_a, ["children", "pageIndex"]);\n const { pageDimensions } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(DocumentContext_DocumentContext);\n const { rotation, scale } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(TransformContext);\n const maskId = `highlight-overlay-mask-${pageIndex}`;\n const getPageStyle = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(() => {\n return computePageStyle(pageDimensions, rotation, scale);\n }, [pageDimensions, rotation, scale]);\n const getUnmaskedArea = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((boundingBoxes) => {\n const boxes = Array.isArray(boundingBoxes) ? boundingBoxes : [boundingBoxes];\n return boxes.map((box, i) => {\n const boxStyle = computeBoundingBoxStyle(box.props, pageDimensions, rotation, scale);\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("rect", { style: boxStyle, x: boxStyle.left, y: boxStyle.top, key: i, fill: "black" }));\n });\n }, [pageDimensions, rotation, scale]);\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("div", Object.assign({ className: "reader__page-highlight-overlay", style: getPageStyle() }, extraProps),\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("svg", { className: "page-mask", style: getPageStyle() },\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("mask", { id: maskId },\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("rect", { style: getPageStyle(), fill: "white" }),\n children && getUnmaskedArea(children)),\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("rect", { style: getPageStyle(), fill: "white", opacity: "0.6", mask: `url(#${maskId})` }))));\n};\n\n;// CONCATENATED MODULE: ./src/components/outline/OutlineItem.tsx\n\n\n\nconst OutlineItem_OutlineItem = ({ items, onClick }) => {\n const { isOutlineTargetVisible } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(ScrollContext);\n if (!items || !items.length) {\n return null;\n }\n function renderItem(item) {\n var _a;\n const clickHandler = (event) => {\n event.preventDefault();\n if (onClick) {\n onClick(item.dest);\n }\n };\n // If an item has sub titles, render \n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("li", { key: ((_a = item.dest) === null || _a === void 0 ? void 0 : _a.toString()) || item.title, className: classnames_default()(\'reader__outline-item\', {\n \'reader__outline-item--target-visible\': isOutlineTargetVisible(item.dest),\n }) },\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("a", { href: "#", onClick: clickHandler }, item.title),\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(OutlineItem_OutlineItem, { items: item.items, onClick: onClick })));\n }\n return external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("ul", { className: "reader__outline-items" }, items.map(item => renderItem(item)));\n};\n\n;// CONCATENATED MODULE: ./src/components/outline/Outline.tsx\nvar Outline_rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\nconst Outline_Outline = (_a) => {\n var extraProps = Outline_rest(_a, []);\n const { outline, pdfDocProxy, setOutline, setOutlinePositions } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(DocumentContext_DocumentContext);\n const { scrollToOutlineTarget, resetScrollObservers } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(ScrollContext);\n external_commonjs_react_commonjs2_react_amd_react_root_React_.useEffect(() => {\n if (outline) {\n return;\n }\n if (!pdfDocProxy) {\n return;\n }\n pdfDocProxy\n .getOutline()\n .then((outlineArray) => {\n setOutline(outlineArray);\n return buildOutlinePositions(pdfDocProxy, outlineArray);\n })\n .then(outlinePositions => {\n setOutlinePositions(outlinePositions);\n })\n .then(() => {\n resetScrollObservers();\n });\n }, [outline]);\n const clickHandler = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((dest) => {\n if (!dest) {\n return;\n }\n scrollToOutlineTarget(dest);\n return;\n }, []);\n if (!pdfDocProxy) {\n return null;\n }\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("div", Object.assign({ className: "reader__outline" }, extraProps), !!outline && external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(OutlineItem_OutlineItem, { items: outline, onClick: clickHandler })));\n};\n\n;// CONCATENATED MODULE: ./src/components/Overlay.tsx\nvar Overlay_rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\nconst Overlay = (_a) => {\n var { children } = _a, extraProps = Overlay_rest(_a, ["children"]);\n const { pageDimensions } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(DocumentContext_DocumentContext);\n const { rotation, scale } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(TransformContext);\n const getOverlayStyle = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(() => {\n return computePageStyle(pageDimensions, rotation, scale);\n }, [pageDimensions, rotation, scale]);\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("div", Object.assign({ className: "reader__page-overlay", style: getOverlayStyle() }, extraProps), children));\n};\n\n;// CONCATENATED MODULE: ./src/utils/MaxVisibleElement.ts\nfunction getMaxVisibleElement(visibleElements) {\n let maxVisibleKey = null;\n let maxRatio = 0;\n for (const [visibleKey, ratio] of visibleElements) {\n if (maxRatio < ratio) {\n maxVisibleKey = visibleKey;\n maxRatio = ratio;\n }\n }\n return maxVisibleKey;\n}\n\n;// CONCATENATED MODULE: ./src/components/PageNumberControl.tsx\n\n\n\n\n\nconst DELAY_SCROLL_TIME_OUT_MS = 1000;\nconst PageNumberControl = ({ className }) => {\n const delayTimerRef = external_commonjs_react_commonjs2_react_amd_react_root_React_.useRef();\n const { numPages } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(DocumentContext_DocumentContext);\n const { scrollToPage, visiblePageRatios } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(ScrollContext);\n const [minPage, setMinPage] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(0);\n const [userInput, setUserInput] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(\'0\');\n // Initialize page control element\n external_commonjs_react_commonjs2_react_amd_react_root_React_.useEffect(() => {\n if (numPages != 0) {\n setMinPage(1);\n }\n }, [numPages]);\n // Everytime we scroll through the page this useEffect\n // will trigger and set current page based on our current\n // scroll position\n external_commonjs_react_commonjs2_react_amd_react_root_React_.useEffect(() => {\n if (visiblePageRatios.size !== 0) {\n const maxVisiblePageNumber = getMaxVisibleElement(visiblePageRatios);\n if (maxVisiblePageNumber) {\n setUserInput(maxVisiblePageNumber.toString());\n }\n }\n }, [visiblePageRatios]);\n const onPageNumberChange = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((event) => {\n const { value } = event.currentTarget;\n // Decimal case\n if (!Number.isInteger(value)) {\n setUserInput(parseInt(value, 10).toString());\n }\n setUserInput(value);\n if (delayTimerRef.current) {\n clearTimeout(delayTimerRef.current);\n }\n // After user input the page that they want to scroll to\n // our ref will start setting a delay around 1s before scroll\n // to the position that user desire\n const newPageNumber = parseInt(value, 10);\n if (newPageNumber >= minPage && newPageNumber <= numPages) {\n delayTimerRef.current = setTimeout(() => {\n scrollToPage({ pageNumber: newPageNumber });\n }, DELAY_SCROLL_TIME_OUT_MS);\n }\n }, [minPage, numPages, scrollToPage]);\n const handleBlur = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(() => {\n if (delayTimerRef.current) {\n clearTimeout(delayTimerRef.current);\n }\n const pageNumber = parseInt(userInput, 10);\n if (Number.isNaN(pageNumber)) {\n return;\n }\n delayTimerRef.current = setTimeout(() => {\n scrollToPage({ pageNumber: pageNumber });\n }, DELAY_SCROLL_TIME_OUT_MS);\n }, [userInput, scrollToPage]);\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("div", { className: classnames_default()(\'reader__page-number-control\', className) },\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("input", { "aria-label": "Current Page", className: "reader__page-number-control__current-page", type: "number", name: "currentPage", value: userInput, onChange: onPageNumberChange, onBlur: handleBlur }),\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("span", { className: "reader__page-number-control__separator" }, "/"),\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("span", { "aria-label": "Total Pages", className: "reader__page-number-control__total-pages" }, numPages)));\n};\n\n;// CONCATENATED MODULE: ./src/context/PageRenderContext.ts\nvar PageRenderContext_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n\n\n\nconst PageRenderContext = external_commonjs_react_commonjs2_react_amd_react_root_React_.createContext({\n pageRenderStates: new Map(),\n getObjectURLForPage: args => {\n logProviderWarning(`getObjectURLForPage(${JSON.stringify(args)})`, \'PageRenderContext\');\n return null;\n },\n isBuildingObjectURLForPage: args => {\n logProviderWarning(`isBuildingObjectURLForPage(${JSON.stringify(args)})`, \'PageRenderContext\');\n return false;\n },\n buildObjectURLForPage: args => {\n logProviderWarning(`buildObjectURLForPage(${JSON.stringify(args)})`, \'PageRenderContext\');\n return Promise.resolve(\'\');\n },\n});\nfunction usePageRenderContextProps({ pdfDocProxy, scale, rotation, zoomMultiplier, visiblePageRatios, }) {\n const [pageRenderStates, _setPageRenderStates] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(() => {\n const map = new Map();\n Object.freeze(map);\n return map;\n });\n // Because rendering a page is async, we will lose the current pageRenderStates\n // This ref trick allows the latest to be accessible when the objectURL is ready\n const pageRenderStatesRef = external_commonjs_react_commonjs2_react_amd_react_root_React_.useRef(pageRenderStates);\n const setPageRenderStates = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((pageRenderStates) => {\n pageRenderStatesRef.current = pageRenderStates;\n _setPageRenderStates(pageRenderStates);\n }, [pageRenderStatesRef]);\n const isBuildingObjectURLForPage = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(({ pageNumber, pageIndex }) => {\n if (typeof pageIndex === \'number\') {\n pageNumber = pageIndex + 1;\n }\n if (typeof pageNumber !== \'number\') {\n return false;\n }\n const state = pageRenderStates.get(pageNumber);\n if (!state) {\n return false;\n }\n return !state.objectURL;\n }, [pageRenderStates]);\n const getObjectURLForPage = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(({ pageNumber, pageIndex }) => {\n var _a;\n if (typeof pageIndex === \'number\') {\n pageNumber = pageIndex + 1;\n }\n if (typeof pageNumber !== \'number\') {\n return null;\n }\n return ((_a = pageRenderStates.get(pageNumber)) === null || _a === void 0 ? void 0 : _a.objectURL) || null;\n }, [pageRenderStates]);\n const buildObjectURLForPage = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(({ pageNumber, pageIndex }) => {\n var _a;\n if (typeof pageIndex === \'number\') {\n pageNumber = pageIndex + 1;\n }\n if (typeof pageNumber !== \'number\') {\n throw new Error(\'prop "pageNumber" is not a number\');\n }\n if (!pdfDocProxy) {\n throw new Error(\'cannot build a page until a "pdfDocProxy" is set on DocumentContext\');\n }\n // Don\'t need to start another task if already rendered\n const existingPromise = (_a = pageRenderStates.get(pageNumber)) === null || _a === void 0 ? void 0 : _a.promise;\n if (existingPromise) {\n return existingPromise;\n }\n const promise = buildPageObjectURL({\n pageNumber,\n pdfDocProxy,\n scale,\n rotation,\n zoomMultiplier,\n });\n const renderState = {\n promise,\n objectURL: null,\n };\n promise.then(objectURL => {\n renderState.objectURL = objectURL;\n const newPageRenderStates = new Map(pageRenderStatesRef.current);\n Object.freeze(newPageRenderStates);\n setPageRenderStates(newPageRenderStates);\n });\n const newPageRenderStates = new Map(pageRenderStatesRef.current);\n newPageRenderStates.set(pageNumber, renderState);\n Object.freeze(newPageRenderStates);\n setPageRenderStates(newPageRenderStates);\n return promise;\n }, [pageRenderStates, pdfDocProxy, scale, rotation, zoomMultiplier]);\n external_commonjs_react_commonjs2_react_amd_react_root_React_.useEffect(() => {\n for (const pageNumber of visiblePageRatios.keys()) {\n if (pageRenderStates.has(pageNumber)) {\n continue;\n }\n buildObjectURLForPage({ pageNumber });\n }\n }, [pageRenderStates, visiblePageRatios]);\n return {\n pageRenderStates,\n getObjectURLForPage,\n isBuildingObjectURLForPage,\n buildObjectURLForPage,\n };\n}\n// Generate an object url for a given page, rendered in a shared canvas\nfunction buildPageObjectURL({ pageNumber, pdfDocProxy, scale = 1, \n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nrotation = PageRotation.Rotate0, zoomMultiplier = 1.2, imageType = \'image/png\', imageQuality = 1.0, }) {\n return PageRenderContext_awaiter(this, void 0, void 0, function* () {\n const pageProxy = yield pdfDocProxy.getPage(pageNumber);\n const blob = yield useRenderCanvas((canvas) => PageRenderContext_awaiter(this, void 0, void 0, function* () {\n // Render page in a canvas\n const viewport = pageProxy.getViewport({ scale: scale * zoomMultiplier * devicePixelRatio });\n canvas.height = viewport.height;\n canvas.width = viewport.width;\n const canvasContext = canvas.getContext(\'2d\');\n if (!canvasContext) {\n throw new Error(\'canvas was unable to get a context\');\n }\n const renderTask = pageProxy.render({\n canvasContext,\n viewport,\n });\n yield renderTask.promise;\n yield new Promise(resolve => setTimeout(resolve, 16));\n // Fetch a blob for an image of the canvas\n return new Promise((resolve, reject) => {\n try {\n canvas.toBlob(blob => resolve(blob), imageType, imageQuality);\n }\n catch (error) {\n reject(error);\n }\n });\n }));\n // Convert blob image to object url\n if (!blob) {\n throw new Error(\'unable to create image from page\');\n }\n return URL.createObjectURL(blob);\n });\n}\nlet renderCanvas = null;\n// Get or create a shared canvas for rendering pages in\nfunction getRenderCanvas() {\n if (!renderCanvas) {\n renderCanvas = document.createElement(\'canvas\');\n }\n return renderCanvas;\n}\nlet nextCanvasUse = Promise.resolve();\n// Use the shared canvas to render a page, using promises to create a queue\nfunction useRenderCanvas(callback) {\n return PageRenderContext_awaiter(this, void 0, void 0, function* () {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n let resolve = (_value) => { };\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n let reject = (_reason) => { };\n const prom = new Promise((_resolve, _reject) => {\n resolve = _resolve;\n reject = _reject;\n });\n nextCanvasUse = nextCanvasUse.then(() => callback(getRenderCanvas()).then(resolve, reject));\n const result = yield prom;\n yield new Promise(res => setTimeout(res, 16)); // Give some time between renders\n return result;\n });\n}\n\n;// CONCATENATED MODULE: ./src/components/PageWrapper.tsx\nvar PageWrapper_rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\n\n\n\n\nconst PageWrapper = (_a) => {\n var { children, error, loading, loadingContentForBuildingImage, noData, pageIndex } = _a, extraProps = PageWrapper_rest(_a, ["children", "error", "loading", "loadingContentForBuildingImage", "noData", "pageIndex"]);\n const { rotation, scale } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(TransformContext);\n const { pageDimensions, getOutlineTargets } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(DocumentContext_DocumentContext);\n const { getObjectURLForPage, isBuildingObjectURLForPage } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(PageRenderContext);\n const objectURLForPage = getObjectURLForPage({ pageIndex });\n const isBuildingPageImage = isBuildingObjectURLForPage({ pageIndex });\n // Don\'t display until we have page size data\n // TODO: Handle this nicer so we display either the loading or error treatment\n if (!pageDimensions) {\n return null;\n }\n const getPageStyle = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(() => {\n const styles = computePageStyle(pageDimensions, rotation, scale);\n if (objectURLForPage) {\n styles.backgroundImage = `url(${objectURLForPage})`;\n }\n return styles;\n }, [pageDimensions, rotation, scale, objectURLForPage]);\n const getWidth = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(() => {\n return getPageWidth(pageDimensions, rotation);\n }, [pageDimensions, rotation]);\n const outlineTargets = getOutlineTargets({ pageIndex, scale, rotation, pageDimensions });\n // Width needs to be set to prevent the outermost Page div from extending to fit the parent,\n // and mis-aligning the text layer.\n // TODO: Can we CSS this to auto-shrink?\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("div", Object.assign({ id: generatePageIdFromIndex(pageIndex), className: classnames_default()(\'reader__page\', { \'reader__page--has-page-image\': objectURLForPage }, { \'reader__page--no-page-image\': !objectURLForPage }, { \'reader__page--is-building-page-image\': isBuildingPageImage }), "data-page-number": pageIndex + 1, style: getPageStyle() }, extraProps),\n children,\n isBuildingPageImage && (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("div", { className: classnames_default()(\'reader__page\', {\n \'reader__page--is-loading-image\': isBuildingPageImage,\n }) }, loadingContentForBuildingImage)),\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(esm_Page, { width: getWidth(), error: error, loading: loading, noData: noData, pageIndex: pageIndex, scale: scale, rotate: rotation, renderAnnotationLayer: true }),\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("div", { className: "reader__page__outline-targets" }, outlineTargets.map(({ dest, leftPx, topPx }) => (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("span", { key: dest, className: "reader__page__outline-target", "data-outline-target-dest": dest, style: { left: leftPx + \'px\', top: topPx + \'px\' } }))))));\n};\n\n;// CONCATENATED MODULE: ./src/components/types/boundingBox.ts\n// Calculate a bounding box\'s pixel coordinates from the raw bounding box\'s coorditate ratios scaled to the page size\nfunction scaleRawBoundingBox(boundingBoxRaw, pageHeight, pageWidth) {\n const boxScaled = {\n page: boundingBoxRaw.page,\n top: boundingBoxRaw.top * pageHeight,\n left: boundingBoxRaw.left * pageWidth,\n height: boundingBoxRaw.height * pageHeight,\n width: boundingBoxRaw.width * pageWidth,\n };\n return boxScaled;\n}\n\n;// CONCATENATED MODULE: ./src/utils/format.ts\nconst PercentFormatter = new Intl.NumberFormat(\'en-US\', {\n style: \'percent\',\n maximumSignificantDigits: 3,\n});\n\n;// CONCATENATED MODULE: ./src/components/ZoomInButton.tsx\nvar ZoomInButton_rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\nconst MAX_ZOOM_IN_SCALE = 500;\nconst ZoomInButton = (_a) => {\n var { children } = _a, extraProps = ZoomInButton_rest(_a, ["children"]);\n const { scale, setScale, zoomMultiplier } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(TransformContext);\n const { updateScrollPosition } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(ScrollContext);\n const handleZoomIn = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((event) => {\n event.preventDefault();\n event.stopPropagation();\n const zoomScale = Number(PercentFormatter.format(scale * zoomMultiplier).replace(\'%\', \'\'));\n if (zoomScale <= MAX_ZOOM_IN_SCALE) {\n updateScrollPosition(1 * zoomMultiplier);\n setScale(scale * zoomMultiplier);\n }\n }, [scale, zoomMultiplier, updateScrollPosition]);\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("button", Object.assign({ className: "reader__zoom-btn zoom-in", onClick: handleZoomIn }, extraProps), children ? children : \'+\'));\n};\n\n;// CONCATENATED MODULE: ./src/components/ZoomOutButton.tsx\nvar ZoomOutButton_rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\nconst MIN_ZOOM_OUT_SCALE = 25;\nconst ZoomOutButton = (_a) => {\n var { children } = _a, extraProps = ZoomOutButton_rest(_a, ["children"]);\n const { scale, setScale, zoomMultiplier } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(TransformContext);\n const { updateScrollPosition } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(ScrollContext);\n const handleZoomOut = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((event) => {\n event.preventDefault();\n event.stopPropagation();\n const zoomScale = Number(PercentFormatter.format(scale / zoomMultiplier).replace(\'%\', \'\'));\n if (zoomScale >= MIN_ZOOM_OUT_SCALE) {\n updateScrollPosition(1 / zoomMultiplier);\n setScale(scale / zoomMultiplier);\n }\n }, [scale, zoomMultiplier, updateScrollPosition]);\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("button", Object.assign({ className: "reader__zoom-btn zoom-out", onClick: handleZoomOut }, extraProps), children ? children : \'-\'));\n};\n\n;// CONCATENATED MODULE: ./src/context/ContextProvider.tsx\n\n\n\n\n\n\nconst ContextProvider = ({ children }) => {\n const documentProps = useDocumentContextProps();\n const transformProps = useTransformContextProps();\n const uiProps = useUiContextProps();\n const scrollProps = useScrollContextProps();\n const pageRenderProps = usePageRenderContextProps({\n pdfDocProxy: documentProps.pdfDocProxy,\n scale: transformProps.scale,\n rotation: transformProps.rotation,\n zoomMultiplier: transformProps.zoomMultiplier,\n visiblePageRatios: scrollProps.visiblePageRatios,\n });\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(DocumentContext_DocumentContext.Provider, { value: documentProps },\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(TransformContext.Provider, { value: transformProps },\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(UiContext.Provider, { value: uiProps },\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(ScrollContext.Provider, { value: scrollProps },\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(PageRenderContext.Provider, { value: pageRenderProps }, children))))));\n};\n\n;// CONCATENATED MODULE: ./index.ts\n/*\n * PDF Component Library exports\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/* harmony default export */ const index = ({\n BoundingBox: BoundingBox,\n computeBoundingBoxStyle: computeBoundingBoxStyle,\n computePageStyle: computePageStyle,\n ContextProvider: ContextProvider,\n DocumentContext: DocumentContext_DocumentContext,\n DocumentWrapper: DocumentWrapper,\n DownloadButton: DownloadButton,\n generatePageIdFromIndex: generatePageIdFromIndex,\n getPageHeight: getPageHeight,\n getPageWidth: getPageWidth,\n HighlightOverlay: HighlightOverlay,\n isSideways: isSideways,\n Outline: Outline_Outline,\n OutlineItem: OutlineItem_OutlineItem,\n Overlay: Overlay,\n PageNumberControl: PageNumberControl,\n PageRotation: PageRotation,\n PageWrapper: PageWrapper,\n rotateClockwise: rotateClockwise,\n rotateCounterClockwise: rotateCounterClockwise,\n scaleRawBoundingBox: scaleRawBoundingBox,\n scrollToId: scrollToId,\n scrollToPdfPageIndex: scrollToPdfPageIndex,\n ScrollContext: ScrollContext,\n TransformContext: TransformContext,\n UiContext: UiContext,\n ZoomInButton: ZoomInButton,\n ZoomOutButton: ZoomOutButton,\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL3NyYy91dGlscy9wcm92aWRlci50cz84NWFhIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL3V0aWxzL3JvdGF0ZS50cz9jZGJiIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL3V0aWxzL3Njcm9sbC50cz83YjA1Iiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL2NvbnRleHQvRG9jdW1lbnRDb250ZXh0LnRzPzJmMDMiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvY29udGV4dC9UcmFuc2Zvcm1Db250ZXh0LnRzP2JlNjQiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvdXRpbHMvc3R5bGUudHM/ZTMxYiIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL3NyYy9jb21wb25lbnRzL0JvdW5kaW5nQm94LnRzeD81NmNmIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2V4dGVuZHMuanM/YzMxZCIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RXaXRob3V0UHJvcGVydGllc0xvb3NlLmpzP2NjYjUiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0V2l0aG91dFByb3BlcnRpZXMuanM/MTVmZCIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS90eXBlb2YuanM/NTNjYSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jbGFzc0NhbGxDaGVjay5qcz9kNGVjIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NyZWF0ZUNsYXNzLmpzP2JlZTIiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vYXNzZXJ0VGhpc0luaXRpYWxpemVkLmpzPzI1N2UiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vc2V0UHJvdG90eXBlT2YuanM/YjM4MCIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pbmhlcml0cy5qcz8yNjJlIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4uanM/OTlkZSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9nZXRQcm90b3R5cGVPZi5qcz83ZTg0Iiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2RlZmluZVByb3BlcnR5LmpzP2FkZTMiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvbWFrZS1ldmVudC1wcm9wcy9kaXN0L2VzbS9pbmRleC5qcz81NDA3Iiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL21ha2UtY2FuY2VsbGFibGUtcHJvbWlzZS9kaXN0L2VzbS9pbmRleC5qcz9hY2Y0Iiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL21lcmdlLWNsYXNzLW5hbWVzL2Rpc3QvZXNtL2luZGV4LmpzP2EyMWMiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvdGlueS1pbnZhcmlhbnQvZGlzdC90aW55LWludmFyaWFudC5lc20uanM/ZjUxZiIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy90aW55LXdhcm5pbmcvZGlzdC90aW55LXdhcm5pbmcuZXNtLmpzPzJkNDQiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvcmVhY3QtcGRmL2Rpc3QvZXNtL0RvY3VtZW50Q29udGV4dC5qcz8yZTIxIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL3JlYWN0LXBkZi9kaXN0L2VzbS9NZXNzYWdlLmpzP2NmNmYiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvcmVhY3QtcGRmL2Rpc3QvZXNtL0xpbmtTZXJ2aWNlLmpzPzk3NzgiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvcmVhY3QtcGRmL2Rpc3QvZXNtL1Bhc3N3b3JkUmVzcG9uc2VzLmpzPzE1ZjUiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vYXJyYXlXaXRoSG9sZXMuanM/MGQyMSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pdGVyYWJsZVRvQXJyYXlMaW1pdC5qcz8wOWYwIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2FycmF5TGlrZVRvQXJyYXkuanM/NmI3NSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheS5qcz8wNmM1Iiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL25vbkl0ZXJhYmxlUmVzdC5qcz8zZDhjIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3NsaWNlZFRvQXJyYXkuanM/MzgzNSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9yZWFjdC1wZGYvZGlzdC9lc20vc2hhcmVkL3V0aWxzLmpzPzM3Y2IiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vYXJyYXlXaXRob3V0SG9sZXMuanM/NjAwNSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pdGVyYWJsZVRvQXJyYXkuanM/ZGI5MCIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9ub25JdGVyYWJsZVNwcmVhZC5qcz8zNDI3Iiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3RvQ29uc3VtYWJsZUFycmF5LmpzPzI5MDkiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvcmVhY3QtcGRmL2Rpc3QvZXNtL3NoYXJlZC9wcm9wVHlwZXMuanM/OGIwNSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9yZWFjdC1wZGYvZGlzdC9lc20vRG9jdW1lbnQuanM/ODJiZCIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9yZWFjdC1wZGYvZGlzdC9lc20vT3V0bGluZUNvbnRleHQuanM/Y2RhNiIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9yZWFjdC1wZGYvZGlzdC9lc20vUmVmLmpzPzM2MGIiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvcmVhY3QtcGRmL2Rpc3QvZXNtL091dGxpbmVJdGVtLmpzPzU2ODciLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvcmVhY3QtcGRmL2Rpc3QvZXNtL091dGxpbmUuanM/Y2QzNSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9tZXJnZS1yZWZzL2Rpc3QvZXNtL2luZGV4LmpzP2FjMDkiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvcmVhY3QtcGRmL2Rpc3QvZXNtL1BhZ2VDb250ZXh0LmpzPzg4N2UiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvcmVhY3QtcGRmL2Rpc3QvZXNtL1BhZ2UvUGFnZUNhbnZhcy5qcz9jZTJlIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL3JlYWN0LXBkZi9kaXN0L2VzbS9QYWdlL1BhZ2VTVkcuanM/NDBlZCIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9yZWFjdC1wZGYvZGlzdC9lc20vUGFnZS9UZXh0TGF5ZXIuanM/ODMwMiIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9yZWFjdC1wZGYvZGlzdC9lc20vUGFnZS9Bbm5vdGF0aW9uTGF5ZXIuanM/MmNlYyIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9yZWFjdC1wZGYvZGlzdC9lc20vUGFnZS5qcz84NWFiIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL3JlYWN0LXBkZi9kaXN0L2VzbS9lbnRyeS5qcz9mNTY0Iiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL3V0aWxzL1Njcm9sbERpcmVjdGlvbkRldGVjdG9yLnRzP2FjZTYiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvdXRpbHMvVmlzaWJsZUVudHJpZXNEZXRlY3Rvci50cz9mZjZiIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL2NvbnRleHQvU2Nyb2xsQ29udGV4dC50cz9jZjkxIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL2NvbnRleHQvVWlDb250ZXh0LnRzPzZiYjMiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvdXRpbHMvZXJyb3JNZXNzYWdlLnRzPzMwYTUiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvdXRpbHMvcGRmV29ya2VyLnRzP2E1ZGUiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvdXRpbHMvc2NhbGUudHM/YTAwNSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL3NyYy9jb21wb25lbnRzL3R5cGVzL2Rlc3RpbmF0aW9uLnRzP2IxYTMiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvY29tcG9uZW50cy9Eb2N1bWVudFdyYXBwZXIudHN4PzUyMDQiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvY29tcG9uZW50cy9Eb3dubG9hZEJ1dHRvbi50c3g/ZTIzNSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL3NyYy9jb21wb25lbnRzL0hpZ2hsaWdodE92ZXJsYXkudHN4PzIyMWEiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvY29tcG9uZW50cy9vdXRsaW5lL091dGxpbmVJdGVtLnRzeD82YTczIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL2NvbXBvbmVudHMvb3V0bGluZS9PdXRsaW5lLnRzeD8zM2NhIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL2NvbXBvbmVudHMvT3ZlcmxheS50c3g/ZTlmMyIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL3NyYy91dGlscy9NYXhWaXNpYmxlRWxlbWVudC50cz8zOWM5Iiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL2NvbXBvbmVudHMvUGFnZU51bWJlckNvbnRyb2wudHN4Pzc5MGMiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvY29udGV4dC9QYWdlUmVuZGVyQ29udGV4dC50cz9mMDdjIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL2NvbXBvbmVudHMvUGFnZVdyYXBwZXIudHN4P2M5YzUiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvY29tcG9uZW50cy90eXBlcy9ib3VuZGluZ0JveC50cz84NjEwIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL3V0aWxzL2Zvcm1hdC50cz8yZDhjIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL2NvbXBvbmVudHMvWm9vbUluQnV0dG9uLnRzeD84NmI5Iiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL2NvbXBvbmVudHMvWm9vbU91dEJ1dHRvbi50c3g/NmJmMyIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL3NyYy9jb250ZXh0L0NvbnRleHRQcm92aWRlci50c3g/YmM4YiIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL2luZGV4LnRzP2E5NTkiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7O0FBQU8sU0FBUyxrQkFBa0IsQ0FBQyxZQUFvQixFQUFFLFlBQW9CO0lBQzNFLE9BQU8sQ0FBQyxJQUFJLENBQ1Ysa0JBQWtCLFlBQVksU0FBUyxZQUFZLHdDQUF3QyxDQUM1RixDQUFDO0FBQ0osQ0FBQzs7O0FDSkQsSUFBWSxZQUtYO0FBTEQsV0FBWSxZQUFZO0lBQ3RCLHFEQUFXO0lBQ1gsd0RBQWE7SUFDYiwyREFBZTtJQUNmLDJEQUFlO0FBQ2pCLENBQUMsRUFMVyxZQUFZLEtBQVosWUFBWSxRQUt2QjtBQUVNLFNBQVMsZUFBZSxDQUFDLFFBQXNCO0lBQ3BELFFBQVEsUUFBUSxFQUFFO1FBQ2hCLEtBQUssWUFBWSxDQUFDLE9BQU87WUFDdkIsT0FBTyxZQUFZLENBQUMsUUFBUSxDQUFDO1FBQy9CLEtBQUssWUFBWSxDQUFDLFFBQVE7WUFDeEIsT0FBTyxZQUFZLENBQUMsU0FBUyxDQUFDO1FBQ2hDLEtBQUssWUFBWSxDQUFDLFNBQVM7WUFDekIsT0FBTyxZQUFZLENBQUMsU0FBUyxDQUFD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Q3hDLDRFQUFDLDBCQUEwQixJQUFDLEtBQUssRUFBRSxlQUFlLElBQy9DLFFBQVEsQ0FDa0IsQ0FDTixDQUNOLENBQ0ssQ0FDSCxDQUM1QixDQUFDO0FBQ0osQ0FBQyxDQUFDOzs7QUN0Q0Y7O0dBRUc7QUFFd0I7QUFFMkQ7QUFDWTtBQUNIO0FBSXBEO0FBQ2dCO0FBQ1E7QUFDTztBQUNIO0FBQzBCO0FBUXJEO0FBSWlCO0FBQ0U7QUFDZ0M7QUFDYjtBQUNOO0FBQ1M7QUFDckI7QUFNcEM7QUFDbUU7QUFNcEU7QUF3RHpCO0FBRUYsNENBQWU7SUFDYixXQUFXO0lBQ1gsdUJBQXVCO0lBQ3ZCLGdCQUFnQjtJQUNoQixlQUFlO0lBQ2YsZUFBZTtJQUNmLGVBQWU7SUFDZixjQUFjO0lBQ2QsdUJBQXVCO0lBQ3ZCLGFBQWE7SUFDYixZQUFZO0lBQ1osZ0JBQWdCO0lBQ2hCLFVBQVU7SUFDVixPQUFPO0lBQ1AsV0FBVztJQUNYLE9BQU87SUFDUCxpQkFBaUI7SUFDakIsWUFBWTtJQUNaLFdBQVc7SUFDWCxlQUFlO0lBQ2Ysc0JBQXNCO0lBQ3RCLG1CQUFtQjtJQUNuQixVQUFVO0lBQ1Ysb0JBQW9CO0lBQ3BCLGFBQWE7SUFDYixnQkFBZ0I7SUFDaEIsU0FBUztJQUNULFlBQVk7SUFDWixhQUFhO0NBQ2QsRUFBQyIsImZpbGUiOiIxODguanMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZnVuY3Rpb24gbG9nUHJvdmlkZXJXYXJuaW5nKGZ1bmN0aW9uTmFtZTogc3RyaW5nLCBwcm92aWRlck5hbWU6IHN0cmluZyk6IHZvaWQge1xuICBjb25zb2xlLndhcm4oXG4gICAgYFVuYWJsZSB0byBjYWxsICR7ZnVuY3Rpb25OYW1lfS4gVGhlICR7cHJvdmlkZXJOYW1lfSBQcm92aWRlciBtYXkgbm90IGJlIHNldCB1cCBjb3JyZWN0bHkuYFxuICApO1xufVxuIiwiZXhwb3J0IGVudW0gUGFnZVJvdGF0aW9uIHtcbiAgUm90YXRlMCA9IDAsXG4gIFJvdGF0ZTkwID0gOTAsXG4gIFJvdGF0ZTE4MCA9IDE4MCxcbiAgUm90YXRlMjcwID0gMjcwLFxufVxuXG5leHBvcnQgZnVuY3Rpb24gcm90YXRlQ2xvY2t3aXNlKHJvdGF0aW9uOiBQYWdlUm90YXRpb24pOiBQYWdlUm90YXRpb24ge1xuICBzd2l0Y2ggKHJvdGF0aW9uKSB7XG4gICAgY2FzZSBQYWdlUm90YXRpb24uUm90YXRlMDpcbiAgICAgIHJldHVybiBQYWdlUm90YXRpb24uUm90YXRlOTA7XG4gICAgY2FzZSBQYWdlUm90YXRpb24uUm90YXRlOTA6XG4gICAgICByZXR1cm4gUGFnZVJvdGF0aW9uLlJvdGF0ZTE4MDtcbiAgICBjYXNlIFBhZ2VSb3RhdGlvbi5Sb3RhdGUxODA6XG4gICAgICByZXR1cm4gUGFnZVJvdGF0aW9uLlJvdGF0ZTI3MDtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIFBhZ2VSb3RhdGlvbi5Sb3RhdGUwO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByb3RhdGVDb3VudGVyQ2xvY2t3aXNlKHJvdGF0aW9uOiBQYWdlUm90YXRpb24pOiBQYWdlUm90YXRpb24ge1xuICBzd2l0Y2ggKHJvdGF0aW9uKSB7XG4gICAgY2FzZSBQYWdlUm90YXRpb24uUm90YXRlMDpcbiAgICAgIHJldHVybiBQYWdlUm90YXRpb24uUm90YXRlMjcwO1xuICAgIGNhc2UgUGFnZVJvdGF0aW9uLlJvdGF0ZTkwOlxuICAgICAgcmV0dXJuIFBhZ2VSb3RhdGlvbi5Sb3RhdGUwO1xuICAgIGNhc2UgUGFnZVJvdGF0aW9uLlJvdGF0ZTE4MDpcbiAgICAgIHJldHVybiBQYWdlUm90YXRpb24uUm90YXRlOTA7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBQYWdlUm90YXRpb24uUm90YXRlMTgwO1xuICB9XG59XG5cbi8qKlxuICogVGVzdHMgd2hldGhlciB0aGUgcGFnZSBpcyByb3RhdGVkIDkwIGRlZ3JlZXMgY2xvY2t3aXNlIG9yIGNvdW50ZXJjbG9ja3dpc2UgZnJvbSB6ZXJvLFxuICogZS5nLiB3aGV0aGVyIHRoZSBwYWdlIFwiaXMgcm90YXRlZCBzaWRld2F5cy5cIlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTaWRld2F5cyhyb3RhdGlvbjogUGFnZVJvdGF0aW9uKTogYm9vbGVhbiB7XG4gIHJldHVybiByb3RhdGlvbiA9PT0gUGFnZVJvdGF0aW9uLlJvdGF0ZTkwIHx8IHJvdGF0aW9uID09PSBQYWdlUm90YXRpb24uUm90YXRlMjcwO1xufVxuIiwiaW1wb3J0IHsgRGltZW5zaW9ucyB9IGZyb20gJy4uL2NvbXBvbmVudHMvdHlwZXMvYm91bmRpbmdCb3gnO1xuaW1wb3J0IHsgUGFnZVByb3BlcnRpZXMgfSBmcm9tICcuLi9jb21wb25lbnRzL3R5cGVzL3BhZ2UnO1xuaW1wb3J0IHsgTnVsbGFibGUgfSBmcm9tICcuLi9jb21wb25lbnRzL3R5cGVzL3V0aWxzJztcbmltcG9ydCB7IFBhZ2VSb3RhdGlvbiB9IGZyb20gJy4uL3V0aWxzL3JvdGF0ZSc7XG5cbi8vIEVhY2ggcGFnZSBkaXYgaXMgSUQnZCBhY2NvcmRpbmcgdG8gcGFnZSBpbmRleFxuLy8gZS5nLiByZWFkZXJfcGdfMCwgcmVhZGVyX3BnXzEsIGV0Yy5cbmV4cG9ydCBjb25zdCBQQUdFX05BVl9UQVJHRVRfSURfUk9PVCA9ICdyZWFkZXJfcGdfJztcblxuY29uc3QgUERGX0hFSUdIVF9QT0lOVFMgPSA3OTI7XG5jb25zdCBQREZfV0lEVEhfUE9JTlRTID0gNjEyO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVQYWdlSWRGcm9tSW5kZXgocGFnZUluZGV4OiBudW1iZXIgfCBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYCR7UEFHRV9OQVZfVEFSR0VUX0lEX1JPT1R9JHtwYWdlSW5kZXh9YDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbFRvSWQoaWQ6IHN0cmluZyk6IHZvaWQge1xuICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICBpZiAoZWxlbWVudCkge1xuICAgIGVsZW1lbnQuc2Nyb2xsSW50b1ZpZXcoeyBiZWhhdmlvcjogJ3Ntb290aCcsIGJsb2NrOiAnc3RhcnQnLCBpbmxpbmU6ICdjZW50ZXInIH0pO1xuICB9IGVsc2Uge1xuICAgIGNvbnNvbGUuZXJyb3IoYENvdWxkIG5vdCBmaW5kIHNjcm9sbCB0YXJnZXQgd2l0aCBJRCAjJHtpZH1gKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9QZGZQYWdlSW5kZXgocGFnZUluZGV4OiBudW1iZXIgfCBzdHJpbmcpOiB2b2lkIHtcbiAgc2Nyb2xsVG9JZChnZW5lcmF0ZVBhZ2VJZEZyb21JbmRleChwYWdlSW5kZXgpKTtcbn1cblxuLyoqXG4gKiBTY3JvbGwgUERGIGRvY3VtZW50IHRvIGEgc3BlY2lmaWMgcG9zaXRpb24uXG4gKiBAcGFyYW0gcGFnZUluZGV4IFRoZSBpbmRleCBvZiB0aGUgcGFnZSB3aGVyZSB0aGUgcG9zaXRpb24gbG9jYXRlcyBhdFxuICogQHBhcmFtIGxlZnRQb2ludHMgVGhlIGhvcml6b250YWwgZGlzdGFuY2UgYmV0d2VlbiB0aGUgb3JpZ2luIGFuZCB0aGUgcG9zaXRpb24gKGluIFBERiBjb29yZGluYXRlcylcbiAqIEBwYXJhbSBib3R0b21Qb2ludHMgVGhlIHZlcnRpY2FsIGRpc3RhbmNlIGJldHdlZW4gdGhlIG9yaWdpbiBhbmQgdGhlIHBvc2l0aW9uIChpbiBQREYgY29vcmRpbmF0ZXMpXG4gKiBAcGFyYW0gcm90YXRpb24gVGhlIHJvdGF0aW9uIGRlZ3JlZSBvZiB0aGUgZG9jdW1lbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbFRvUG9zaXRpb24oXG4gIHBhZ2VJbmRleDogbnVtYmVyLFxuICBsZWZ0UG9pbnRzOiBudW1iZXIsXG4gIGJvdHRvbVBvaW50czogbnVtYmVyLFxuICByb3RhdGlvbjogUGFnZVJvdGF0aW9uID0gUGFnZVJvdGF0aW9uLlJvdGF0ZTBcbik6IHZvaWQge1xuICAvKlxuICAgIFZlcnRpY2FsIHNjcm9sbCBkaXN0YW5jZSBpcyBjYWxjdWxhdGVkIGFzXG4gICAgPSB0b3RhbCBudW1iZXIgb2YgcHJldmlvdXMgcGFnZXMgKiBwYWdlIGhlaWdodCBpbmNsdWRpbmcgdG9wL2Rvd24gbWFyZ2luc1xuICAgICsgdGhlIG1hcmdpbiB0b3Agb2YgY3VycmVudCBwYWdlXG4gICAgKyB0aGUgZGlzdGFuY2UgZnJvbSB0aGUgcGFnZSB0b3AgdG8gdGhlIHNwZWNpZmllZCBwb3NpdGlvblxuXG4gICAgTm90aWNlIHRoYXQgdGhlIHNjcm9sbCBkaXN0YW5jZSBpcyBtZWFzdXJlZCBpbiBwaXhlbHMsXG4gICAgc28gbGVmdFBvaW50cy9ib3R0b21Qb2ludHMgaGFzIHRvIGJlIHRyYW5zZm9ybWVkIGZyb20gcG9pbnRzIHRvIHBpeGVscyBmaXJzdC5cbiAgKi9cblxuICBjb25zdCB7IHdpZHRoLCBoZWlnaHQsIG1hcmdpblRvcCwgbWFyZ2luQm90dG9tLCBtYXJnaW5MZWZ0LCBtYXJnaW5SaWdodCB9ID1cbiAgICBnZXRQYWdlUHJvcGVydGllc0luUGl4ZWxzKCk7XG4gIGNvbnN0IGhlaWdodFdpdGhNYXJnaW5zID0gaGVpZ2h0ICsgbWFyZ2luVG9wICsgbWFyZ2luQm90dG9tO1xuXG4gIC8vIFdoZW4gYSBwYXBlciBpcyByb3RhdGVkLCBpdHMgaGVpZ2h0IGFuZCB3aWR0aCB3b3VsZCBiZSBzd2l0Y2hlZCBhdXRvbWF0aWNhbGx5LiBIb3dldmVyLCBsZWZ0UG9pbnRzIGFuZCBib3R0b21Qb2ludHMgcmVtYWluIHRoZSBzYW1lLlxuICBsZXQgbWFyZ2luVG9wUGl4ZWxzID0gbWFyZ2luVG9wO1xuICBsZXQgYm90dG9tUGl4ZWxzID0gKGhlaWdodCAqIGJvdHRvbVBvaW50cykgLyBQREZfSEVJR0hUX1BPSU5UUztcbiAgbGV0IGxlZnRQaXhlbHMgPSAod2lkdGggKiBsZWZ0UG9pbnRzKSAvIFBERl9XSURUSF9QT0lOVFM7XG5cbiAgaWYgKHJvdGF0aW9uID09IFBhZ2VSb3RhdGlvbi5Sb3RhdGU5MCkge1xuICAgIG1hcmdpblRvcFBpeGVscyA9IG1hcmdpbkxlZnQ7XG4gICAgYm90dG9tUGl4ZWxzID0gKGhlaWdodCAqIChQREZfV0lEVEhfUE9JTlRTIC0gbGVmdFBvaW50cykpIC8gUERGX1dJRFRIX1BPSU5UUztcbiAgICBsZWZ0UGl4ZWxzID0gKHdpZHRoICogYm90dG9tUG9pbnRzKSAvIFBERl9IRUlHSFRfUE9JTlRTO1xuICB9IGVsc2UgaWYgKHJvdGF0aW9uID09IFBhZ2VSb3RhdGlvbi5Sb3RhdGUxODApIHtcbiAgICBtYXJnaW5Ub3BQaXhlbHMgPSBtYXJnaW5Cb3R0b207XG4gICAgYm90dG9tUGl4ZWxzID0gKGhlaWdodCAqIChQREZfSEVJR0hUX1BPSU5UUyAtIGJvdHRvbVBvaW50cykpIC8gUERGX0hFSUdIVF9QT0lOVFM7XG4gICAgbGVmdFBpeGVscyA9ICh3aWR0aCAqIChQREZfV0lEVEhfUE9JTlRTIC0gbGVmdFBvaW50cykpIC8gUERGX1dJRFRIX1BPSU5UUztcbiAgfSBlbHNlIGlmIChyb3RhdGlvbiA9PSBQYWdlUm90YXRpb24uUm90YXRlMjcwKSB7XG4gICAgbWFyZ2luVG9wUGl4ZWxzID0gbWFyZ2luUmlnaHQ7XG4gICAgYm90dG9tUGl4ZWxzID0gKGhlaWdodCAqIGxlZnRQb2ludHMpIC8gUERGX1dJRFRIX1BPSU5UUztcbiAgICBsZWZ0UGl4ZWxzID0gKHdpZHRoICogKFBERl9IRUlHSFRfUE9JTlRTIC0gYm90dG9tUG9pbnRzKSkgLyBQREZfSEVJR0hUX1BPSU5UUztcbiAgfVxuXG4gIC8vIEZpbmQgcGFnZSBlbGVtZW50XG4gIGNvbnN0IHBhZ2VJZCA9IGdlbmVyYXRlUGFnZUlkRnJvbUluZGV4KHBhZ2VJbmRleCk7XG4gIGNvbnN0IHBhZ2VJZEVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChwYWdlSWQpO1xuICBpZiAoIXBhZ2VJZEVsZW1lbnQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBGaW5kIGZpcnN0IHNjcm9sbGFibGUgcGFyZW50XG4gIGNvbnN0IHBhcmVudEVsZW1lbnQgPSBnZXRTY3JvbGxQYXJlbnQocGFnZUlkRWxlbWVudCk7XG4gIGlmICghcGFyZW50RWxlbWVudCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEFwcGx5IHNjcm9sbFxuICBwYXJlbnRFbGVtZW50LnNjcm9sbFRvKHtcbiAgICB0b3A6IGNhbGN1bGF0ZVRvcFB4KHtcbiAgICAgIGhlaWdodFdpdGhNYXJnaW5zSW5QeDogaGVpZ2h0V2l0aE1hcmdpbnMsXG4gICAgICBwYWdlSW5kZXg6IHBhZ2VJbmRleCxcbiAgICAgIG1hcmdpblRvcFB4OiBtYXJnaW5Ub3BQaXhlbHMsXG4gICAgICBoZWlnaHRQeDogaGVpZ2h0LFxuICAgICAgYm90dG9tUHg6IGJvdHRvbVBpeGVscyxcbiAgICB9KSxcbiAgICBsZWZ0OiBNYXRoLmZsb29yKGxlZnRQaXhlbHMpLFxuICAgIGJlaGF2aW9yOiAnc21vb3RoJyxcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTY3JvbGxQYXJlbnQobm9kZTogSFRNTEVsZW1lbnQpOiBOdWxsYWJsZTxIVE1MRWxlbWVudD4ge1xuICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGlmICghbm9kZSB8fCBub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdib2R5Jykge1xuICAgIHJldHVybiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gIH1cbiAgaWYgKG5vZGUuc2Nyb2xsSGVpZ2h0ID4gbm9kZS5jbGllbnRIZWlnaHQgJiYgIWlzT3ZlcmZsb3dJc0hpZGRlbihub2RlKSkge1xuICAgIHJldHVybiBub2RlO1xuICB9XG4gIHJldHVybiBnZXRTY3JvbGxQYXJlbnQobm9kZS5wYXJlbnRFbGVtZW50IGFzIEhUTUxFbGVtZW50KTtcbn1cblxuZnVuY3Rpb24gaXNPdmVyZmxvd0lzSGlkZGVuKG5vZGU6IEhUTUxFbGVtZW50KTogYm9vbGVhbiB7XG4gIGNvbnN0IHN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShub2RlKTtcbiAgcmV0dXJuIChcbiAgICBzdHlsZS5vdmVyZmxvdy5pbmNsdWRlcygnaGlkZGVuJykgfHxcbiAgICBzdHlsZS5vdmVyZmxvd1guaW5jbHVkZXMoJ2hpZGRlbicpIHx8XG4gICAgc3R5bGUub3ZlcmZsb3dZLmluY2x1ZGVzKCdoaWRkZW4nKVxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlVG9wUHgoe1xuICBoZWlnaHRXaXRoTWFyZ2luc0luUHgsXG4gIHBhZ2VJbmRleCxcbiAgbWFyZ2luVG9wUHgsXG4gIGhlaWdodFB4LFxuICBib3R0b21QeCxcbn06IHtcbiAgaGVpZ2h0V2l0aE1hcmdpbnNJblB4OiBudW1iZXI7XG4gIHBhZ2VJbmRleDogbnVtYmVyO1xuICBtYXJnaW5Ub3BQeDogbnVtYmVyO1xuICBoZWlnaHRQeDogbnVtYmVyO1xuICBib3R0b21QeDogbnVtYmVyO1xufSk6IG51bWJlciB7XG4gIHJldHVybiBNYXRoLmZsb29yKGhlaWdodFdpdGhNYXJnaW5zSW5QeCAqIHBhZ2VJbmRleCArIG1hcmdpblRvcFB4ICsgKGhlaWdodFB4IC0gYm90dG9tUHgpKTtcbn1cblxuLyoqXG4gKiBHZXQgbGVuZ3Rocywgd2lkdGhzLCBhbmQgbWFyZ2lucyBvZiBhIHBhZ2UuXG4gKiBAcmV0dXJucyBhIFBhZ2VQcm9wZXJ0aWVzIG9iamVjdFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UGFnZVByb3BlcnRpZXNJblBpeGVscygpOiBQYWdlUHJvcGVydGllcyB7XG4gIGNvbnN0IGZpcnN0UGFnZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGdlbmVyYXRlUGFnZUlkRnJvbUluZGV4KDApKTtcbiAgaWYgKCFmaXJzdFBhZ2UpIHtcbiAgICBjb25zb2xlLmVycm9yKGBDYW5ub3QgZ2V0IHRoZSBmaXJzdCBwYWdlIG9mIHRoaXMgZG9jdW1lbnQuYCk7XG4gICAgY29uc3QgZW1wdHlQYWdlUHJvcGVydGllczogUGFnZVByb3BlcnRpZXMgPSB7XG4gICAgICB3aWR0aDogMCxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIG1hcmdpblRvcDogMCxcbiAgICAgIG1hcmdpbkJvdHRvbTogMCxcbiAgICAgIG1hcmdpbkxlZnQ6IDAsXG4gICAgICBtYXJnaW5SaWdodDogMCxcbiAgICB9O1xuICAgIHJldHVybiBlbXB0eVBhZ2VQcm9wZXJ0aWVzO1xuICB9XG5cbiAgY29uc3Qgc3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKGZpcnN0UGFnZSBhcyBFbGVtZW50KTtcbiAgY29uc3QgcGFnZVByb3BlcnRpZXM6IFBhZ2VQcm9wZXJ0aWVzID0ge1xuICAgIHdpZHRoOiBwYXJzZUludChzdHlsZS53aWR0aCksXG4gICAgaGVpZ2h0OiBwYXJzZUludChzdHlsZS5oZWlnaHQpLFxuICAgIG1hcmdpblRvcDogcGFyc2VJbnQoc3R5bGUubWFyZ2luVG9wKSxcbiAgICBtYXJnaW5Cb3R0b206IHBhcnNlSW50KHN0eWxlLm1hcmdpbkJvdHRvbSksXG4gICAgbWFyZ2luTGVmdDogcGFyc2VJbnQoc3R5bGUubWFyZ2luTGVmdCksXG4gICAgbWFyZ2luUmlnaHQ6IHBhcnNlSW50KHN0eWxlLm1hcmdpblJpZ2h0KSxcbiAgfTtcblxuICByZXR1cm4gcGFnZVByb3BlcnRpZXM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVUYXJnZXRQb3NpdGlvbih7XG4gIHNjYWxlLFxuICBsZWZ0UG9pbnQsXG4gIGJvdHRvbVBvaW50LFxuICBwYWdlRGltZW5zaW9ucyxcbiAgcm90YXRpb24gPSBQYWdlUm90YXRpb24uUm90YXRlMCxcbn06IHtcbiAgc2NhbGU6IG51bWJlcjtcbiAgbGVmdFBvaW50OiBudW1iZXI7XG4gIGJvdHRvbVBvaW50OiBudW1iZXI7XG4gIHBhZ2VEaW1lbnNpb25zOiBEaW1lbnNpb25zO1xuICByb3RhdGlvbjogUGFnZVJvdGF0aW9uO1xufSk6IHsgbGVmdFB4OiBudW1iZXI7IHRvcFB4OiBudW1iZXIgfSB7XG4gIHN3aXRjaCAocm90YXRpb24pIHtcbiAgICBkZWZhdWx0OlxuICAgIGNhc2UgUGFnZVJvdGF0aW9uLlJvdGF0ZTA6IHtcbiAgICAgIGNvbnN0IGxlZnRQeCA9IChsZWZ0UG9pbnQgLyBQREZfV0lEVEhfUE9JTlRTKSAqIHBhZ2VEaW1lbnNpb25zLndpZHRoICogc2NhbGU7XG4gICAgICBjb25zdCB0b3BQeCA9ICgxIC0gYm90dG9tUG9pbnQgLyBQREZfSEVJR0hUX1BPSU5UUykgKiBwYWdlRGltZW5zaW9ucy5oZWlnaHQgKiBzY2FsZTtcbiAgICAgIHJldHVybiB7IGxlZnRQeCwgdG9wUHggfTtcbiAgICB9XG4gIH1cbn1cbiIsImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IHBkZmpzIH0gZnJvbSAncmVhY3QtcGRmJztcblxuaW1wb3J0IHsgRGltZW5zaW9ucyB9IGZyb20gJy4uL2NvbXBvbmVudHMvdHlwZXMvYm91bmRpbmdCb3gnO1xuaW1wb3J0IHtcbiAgT3V0bGluZU5vZGUsXG4gIE91dGxpbmVQb3NpdGlvbixcbiAgT3V0bGluZVBvc2l0aW9uc0J5UGFnZU51bWJlck1hcCxcbiAgT3V0bGluZVRhcmdldCxcbiAgT3V0bGluZVRhcmdldEFyZ3MsXG59IGZyb20gJy4uL2NvbXBvbmVudHMvdHlwZXMvb3V0bGluZSc7XG5pbXBvcnQgeyBOdWxsYWJsZSB9IGZyb20gJy4uL2NvbXBvbmVudHMvdHlwZXMvdXRpbHMnO1xuaW1wb3J0IHsgbG9nUHJvdmlkZXJXYXJuaW5nIH0gZnJvbSAnLi4vdXRpbHMvcHJvdmlkZXInO1xuaW1wb3J0IHsgY2FsY3VsYXRlVGFyZ2V0UG9zaXRpb24gfSBmcm9tICcuLi91dGlscy9zY3JvbGwnO1xuZXhwb3J0IGludGVyZmFjZSBJRG9jdW1lbnRDb250ZXh0IHtcbiAgbnVtUGFnZXM6IG51bWJlcjtcbiAgb3V0bGluZTogTnVsbGFibGU8QXJyYXk8T3V0bGluZU5vZGU+PjtcbiAgb3V0bGluZVBvc2l0aW9uczogTnVsbGFibGU8T3V0bGluZVBvc2l0aW9uc0J5UGFnZU51bWJlck1hcD47XG4gIHBhZ2VEaW1lbnNpb25zOiBEaW1lbnNpb25zOyAvLyBTY2FsZWQgYXQgMTAwJVxuICBwZGZEb2NQcm94eT86IHBkZmpzLlBERkRvY3VtZW50UHJveHk7XG4gIGdldE91dGxpbmVUYXJnZXRzOiAob3B0czogT3V0bGluZVRhcmdldEFyZ3MpID0+IE91dGxpbmVUYXJnZXRbXTtcbiAgc2V0TnVtUGFnZXM6IChudW1QYWdlczogbnVtYmVyKSA9PiB2b2lkO1xuICBzZXRPdXRsaW5lOiAob3V0bGluZTogTnVsbGFibGU8QXJyYXk8T3V0bGluZU5vZGU+PikgPT4gdm9pZDtcbiAgc2V0T3V0bGluZVBvc2l0aW9uczogKG91dGxpbmVQb3NpdGlvbnM6IE51bGxhYmxlPE91dGxpbmVQb3NpdGlvbnNCeVBhZ2VOdW1iZXJNYXA+KSA9PiB2b2lkO1xuICBzZXRQYWdlRGltZW5zaW9uczogKHBhZ2VEaW1lbnNpb25zOiBEaW1lbnNpb25zKSA9PiB2b2lkO1xuICBzZXRQZGZEb2NQcm94eTogKHBkZkRvY1Byb3h5OiBwZGZqcy5QREZEb2N1bWVudFByb3h5KSA9PiB2b2lkO1xufVxuXG5leHBvcnQgY29uc3QgRG9jdW1lbnRDb250ZXh0ID0gUmVhY3QuY3JlYXRlQ29udGV4dDxJRG9jdW1lbnRDb250ZXh0Pih7XG4gIG51bVBhZ2VzOiAwLFxuICBvdXRsaW5lOiBbXSxcbiAgb3V0bGluZVBvc2l0aW9uczogbnVsbCxcbiAgcGFnZURpbWVuc2lvbnM6IHsgaGVpZ2h0OiAwLCB3aWR0aDogMCB9LFxuICBwZGZEb2NQcm94eTogdW5kZWZpbmVkLFxuICBnZXRPdXRsaW5lVGFyZ2V0czogb3B0cyA9PiB7XG4gICAgbG9nUHJvdmlkZXJXYXJuaW5nKGBnZXRPdXRsaW5lVGFyZ2V0cygke0pTT04uc3RyaW5naWZ5KG9wdHMpfSlgLCAnRG9jdW1lbnRDb250ZXh0Jyk7XG4gICAgcmV0dXJuIFtdO1xuICB9LFxuICBzZXROdW1QYWdlczogbnVtUGFnZXMgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgc2V0TnVtUGFnZXMoJHtudW1QYWdlc30pYCwgJ0RvY3VtZW50Q29udGV4dCcpO1xuICB9LFxuICBzZXRPdXRsaW5lOiBvdXRsaW5lID0+IHtcbiAgICBsb2dQcm92aWRlcldhcm5pbmcoYHNldE91dGxpbmUoJHtvdXRsaW5lfSlgLCAnRG9jdW1lbnRDb250ZXh0Jyk7XG4gIH0sXG4gIHNldE91dGxpbmVQb3NpdGlvbnM6IG91dGxpbmUgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgc2V0T3V0bGluZVBvc2l0aW9ucygke291dGxpbmV9KWAsICdEb2N1bWVudENvbnRleHQnKTtcbiAgfSxcbiAgc2V0UGFnZURpbWVuc2lvbnM6IHBhZ2VEaW1lbnNpb25zID0+IHtcbiAgICBsb2dQcm92aWRlcldhcm5pbmcoYHNldFBhZ2VEaW1lbnNpb25zKCR7cGFnZURpbWVuc2lvbnN9KWAsICdEb2N1bWVudENvbnRleHQnKTtcbiAgfSxcbiAgc2V0UGRmRG9jUHJveHk6IHBkZkRvY1Byb3h5ID0+IHtcbiAgICBsb2dQcm92aWRlcldhcm5pbmcoYHNldFBkZkRvY1Byb3h5KCR7cGRmRG9jUHJveHl9KWAsICdEb2N1bWVudENvbnRleHQnKTtcbiAgfSxcbn0pO1xuXG5leHBvcnQgZnVuY3Rpb24gdXNlRG9jdW1lbnRDb250ZXh0UHJvcHMoKTogSURvY3VtZW50Q29udGV4dCB7XG4gIGNvbnN0IFtudW1QYWdlcywgc2V0TnVtUGFnZXNdID0gUmVhY3QudXNlU3RhdGU8bnVtYmVyPigwKTtcbiAgY29uc3QgW291dGxpbmUsIHNldE91dGxpbmVdID0gUmVhY3QudXNlU3RhdGU8TnVsbGFibGU8QXJyYXk8T3V0bGluZU5vZGU+Pj4obnVsbCk7XG4gIGNvbnN0IFtvdXRsaW5lUG9zaXRpb25zLCBzZXRPdXRsaW5lUG9zaXRpb25zXSA9XG4gICAgUmVhY3QudXNlU3RhdGU8TnVsbGFibGU8T3V0bGluZVBvc2l0aW9uc0J5UGFnZU51bWJlck1hcD4+KG51bGwpO1xuICBjb25zdCBbcGFnZURpbWVuc2lvbnMsIHNldFBhZ2VEaW1lbnNpb25zXSA9IFJlYWN0LnVzZVN0YXRlPERpbWVuc2lvbnM+KHsgaGVpZ2h0OiAwLCB3aWR0aDogMCB9KTtcbiAgY29uc3QgW3BkZkRvY1Byb3h5LCBzZXRQZGZEb2NQcm94eV0gPSBSZWFjdC51c2VTdGF0ZTxwZGZqcy5QREZEb2N1bWVudFByb3h5PigpO1xuXG4gIC8vIERyYXcgb3V0bGluZSB0YXJnZXQgaW50byB0aGUgcGRmIGJhc2VkIG9uIHRoZSBhcmdzXG4gIGNvbnN0IGdldE91dGxpbmVUYXJnZXRzID0gUmVhY3QudXNlQ2FsbGJhY2soXG4gICAgKHtcbiAgICAgIHBhZ2VOdW1iZXIsXG4gICAgICBwYWdlSW5kZXgsXG4gICAgICBzY2FsZSxcbiAgICAgIHJvdGF0aW9uLFxuICAgICAgcGFnZURpbWVuc2lvbnMsXG4gICAgfTogT3V0bGluZVRhcmdldEFyZ3MpOiBPdXRsaW5lVGFyZ2V0W10gPT4ge1xuICAgICAgaWYgKHR5cGVvZiBwYWdlSW5kZXggPT09ICdudW1iZXInKSB7XG4gICAgICAgIHBhZ2VOdW1iZXIgPSBwYWdlSW5kZXggKyAxO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBwYWdlTnVtYmVyICE9PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICBjb25zdCBwb3NpdGlvbnMgPSBvdXRsaW5lUG9zaXRpb25zPy5nZXQocGFnZU51bWJlcikgfHwgW107XG4gICAgICByZXR1cm4gcG9zaXRpb25zLm1hcCgoeyBkZXN0LCBsZWZ0UG9pbnQsIGJvdHRvbVBvaW50IH0pID0+IHtcbiAgICAgICAgY29uc3QgeyBsZWZ0UHgsIHRvcFB4IH0gPSBjYWxjdWxhdGVUYXJnZXRQb3NpdGlvbih7XG4gICAgICAgICAgc2NhbGUsXG4gICAgICAgICAgcm90YXRpb24sXG4gICAgICAgICAgbGVmdFBvaW50LFxuICAgICAgICAgIGJvdHRvbVBvaW50LFxuICAgICAgICAgIHBhZ2VEaW1lbnNpb25zLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBkZXN0LFxuICAgICAgICAgIGxlZnRQeCxcbiAgICAgICAgICB0b3BQeCxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgW291dGxpbmVQb3NpdGlvbnNdXG4gICk7XG5cbiAgcmV0dXJuIHtcbiAgICBudW1QYWdlcyxcbiAgICBvdXRsaW5lLFxuICAgIG91dGxpbmVQb3NpdGlvbnMsXG4gICAgcGFnZURpbWVuc2lvbnMsXG4gICAgcGRmRG9jUHJveHksXG4gICAgZ2V0T3V0bGluZVRhcmdldHMsXG4gICAgc2V0TnVtUGFnZXMsXG4gICAgc2V0T3V0bGluZSxcbiAgICBzZXRPdXRsaW5lUG9zaXRpb25zLFxuICAgIHNldFBhZ2VEaW1lbnNpb25zOiBzZXRQYWdlRGltZW5zaW9ucyxcbiAgICBzZXRQZGZEb2NQcm94eSxcbiAgfTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGJ1aWxkT3V0bGluZVBvc2l0aW9ucyhcbiAgcGRmRG9jUHJveHk6IHBkZmpzLlBERkRvY3VtZW50UHJveHksXG4gIG91dGxpbmU/OiBPdXRsaW5lTm9kZVtdXG4pOiBQcm9taXNlPE91dGxpbmVQb3NpdGlvbnNCeVBhZ2VOdW1iZXJNYXA+IHtcbiAgaWYgKCFvdXRsaW5lKSB7XG4gICAgb3V0bGluZSA9IGF3YWl0IHBkZkRvY1Byb3h5LmdldE91dGxpbmUoKTtcbiAgfVxuXG4gIC8vIERlcHRoIGZpcnN0IHNlYXJjaCB0aHJvdWdoIG91dGxpbmUgaXRlbXNcbiAgY29uc3QgaXRlbVF1ZXVlID0gb3V0bGluZS5zbGljZSgpO1xuICBjb25zdCBwcm9tczogUHJvbWlzZTxOdWxsYWJsZTxPdXRsaW5lUG9zaXRpb24+PltdID0gW107XG4gIHdoaWxlIChpdGVtUXVldWUubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IGl0ZW0gPSBpdGVtUXVldWUucG9wKCk7XG4gICAgaWYgKCFpdGVtKSB7XG4gICAgICBjb250aW51ZTsgLy8gTm90IGFibGUgdG8gcHJvY2Vzc1xuICAgIH1cbiAgICBjb25zdCB7IGRlc3QsIGl0ZW1zIH0gPSBpdGVtO1xuXG4gICAgLy8gQWRkIGNoaWxkIGl0ZW1zIHRvIHF1ZXVlXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoaXRlbXMpKSB7XG4gICAgICBpdGVtUXVldWUucHVzaCguLi5pdGVtcyk7XG4gICAgfVxuXG4gICAgLy8gRmV0Y2ggZGVzdGluYXRpb25zIGZvciBpdGVtXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZGVzdCkpIHtcbiAgICAgIHByb21zLnB1c2goLi4uZGVzdC5tYXAoZGVzdCA9PiBnZXREZXN0aW5hdGlvbihwZGZEb2NQcm94eSwgZGVzdCkpKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBkZXN0ID09PSAnc3RyaW5nJykge1xuICAgICAgcHJvbXMucHVzaChnZXREZXN0aW5hdGlvbihwZGZEb2NQcm94eSwgZGVzdCkpO1xuICAgIH1cbiAgfVxuXG4gIC8vIENvbGxlY3QgcmVzdWx0cyBhbGwgYXQgb25jZSwgc28gd2UgZG9uJ3QgaGF2ZSB0byBwYXkgZm9yIHRoZSBjb3N0IG9mXG4gIC8vIHF1ZXVlaW5nIG1lc3NhZ2VzIHNlbnQgdG8gdGhlIHdvcmtlclxuICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwocHJvbXMpO1xuXG4gIC8vIFNwbGl0IHJlc3VsdHMgaW50byBwYWdlc1xuICBjb25zdCBtYXAgPSBuZXcgTWFwPG51bWJlciwgT3V0bGluZVBvc2l0aW9uW10+KCk7XG4gIGZvciAoY29uc3QgcmVzdWx0IG9mIHJlc3VsdHMpIHtcbiAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgY29udGludWU7IC8vIEZpbHRlciBvdXQgbnVsbFxuICAgIH1cbiAgICBjb25zdCB7IHBhZ2VOdW1iZXIgfSA9IHJlc3VsdDtcbiAgICBpZiAoIW1hcC5oYXMocGFnZU51bWJlcikpIHtcbiAgICAgIG1hcC5zZXQocGFnZU51bWJlciwgW10pO1xuICAgIH1cbiAgICBtYXAuZ2V0KHBhZ2VOdW1iZXIpPy5wdXNoKHJlc3VsdCk7XG4gIH1cblxuICAvLyBGcmVlemUgb2JqZWN0cyBzbyBjb25zdW1lcnMgY2Fubm90IG11dGF0ZVxuICBmb3IgKGNvbnN0IHBhZ2VQb3Mgb2YgbWFwLnZhbHVlcygpKSB7XG4gICAgZm9yIChjb25zdCBwb3Mgb2YgcGFnZVBvcykge1xuICAgICAgT2JqZWN0LmZyZWV6ZShwb3MpO1xuICAgIH1cbiAgICBPYmplY3QuZnJlZXplKHBhZ2VQb3MpO1xuICB9XG4gIE9iamVjdC5mcmVlemUobWFwKTtcblxuICByZXR1cm4gbWFwO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXREZXN0aW5hdGlvbihcbiAgcGRmRG9jUHJveHk6IHBkZmpzLlBERkRvY3VtZW50UHJveHksXG4gIGRlc3Q6IHN0cmluZ1xuKTogUHJvbWlzZTxOdWxsYWJsZTxPdXRsaW5lUG9zaXRpb24+PiB7XG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBkZkRvY1Byb3h5LmdldERlc3RpbmF0aW9uKGRlc3QpO1xuICBpZiAoIXJlc3VsdCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBjb25zdCBbcmVmLCBfZm9ybWF0LCBsZWZ0UG9pbnQsIGJvdHRvbVBvaW50XSA9IHJlc3VsdDtcbiAgY29uc3QgcGFnZUluZGV4ID0gYXdhaXQgcGRmRG9jUHJveHkuZ2V0UGFnZUluZGV4KHJlZik7XG4gIGNvbnN0IHBhZ2VOdW1iZXIgPSBwYWdlSW5kZXggKyAxO1xuICByZXR1cm4geyBwYWdlTnVtYmVyLCBkZXN0LCBsZWZ0UG9pbnQsIGJvdHRvbVBvaW50IH07XG59XG4iLCJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5cbmltcG9ydCB7IGxvZ1Byb3ZpZGVyV2FybmluZyB9IGZyb20gJy4uL3V0aWxzL3Byb3ZpZGVyJztcbmltcG9ydCB7IFBhZ2VSb3RhdGlvbiB9IGZyb20gJy4uL3V0aWxzL3JvdGF0ZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVRyYW5zZm9ybUNvbnRleHQge1xuICByb3RhdGlvbjogUGFnZVJvdGF0aW9uO1xuICBzY2FsZTogbnVtYmVyO1xuICB6b29tTXVsdGlwbGllcjogbnVtYmVyO1xuICBzZXRSb3RhdGlvbjogKHJvdGF0aW9uOiBQYWdlUm90YXRpb24pID0+IHZvaWQ7XG4gIHNldFNjYWxlOiAoc2NhbGU6IG51bWJlcikgPT4gdm9pZDtcbiAgc2V0Wm9vbU11bHRpcGxpZXI6ICh6b29tOiBudW1iZXIpID0+IHZvaWQ7XG59XG5cbmV4cG9ydCBjb25zdCBUcmFuc2Zvcm1Db250ZXh0ID0gUmVhY3QuY3JlYXRlQ29udGV4dDxJVHJhbnNmb3JtQ29udGV4dD4oe1xuICByb3RhdGlvbjogUGFnZVJvdGF0aW9uLlJvdGF0ZTAsXG4gIHNjYWxlOiAxLFxuICB6b29tTXVsdGlwbGllcjogMS4yLFxuICBzZXRSb3RhdGlvbjogcm90YXRpb24gPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgc2V0Um90YXRpb24oJHtyb3RhdGlvbn0pYCwgJ1RyYW5zZm9ybUNvbnRleHQnKTtcbiAgfSxcbiAgc2V0U2NhbGU6IHNjYWxlID0+IHtcbiAgICBsb2dQcm92aWRlcldhcm5pbmcoYHNldFNjYWxlKCR7c2NhbGV9KWAsICdUcmFuc2Zvcm1Db250ZXh0Jyk7XG4gIH0sXG4gIHNldFpvb21NdWx0aXBsaWVyOiB6b29tID0+IHtcbiAgICBsb2dQcm92aWRlcldhcm5pbmcoYHNldFpvb21NdWx0aXBsaWVyKCR7em9vbX0pYCwgJ1RyYW5zZm9ybUNvbnRleHQnKTtcbiAgfSxcbn0pO1xuXG5leHBvcnQgZnVuY3Rpb24gdXNlVHJhbnNmb3JtQ29udGV4dFByb3BzKCk6IElUcmFuc2Zvcm1Db250ZXh0IHtcbiAgY29uc3QgW3JvdGF0aW9uLCBzZXRSb3RhdGlvbl0gPSBSZWFjdC51c2VTdGF0ZTxQYWdlUm90YXRpb24+KFBhZ2VSb3RhdGlvbi5Sb3RhdGUwKTtcbiAgY29uc3QgW3NjYWxlLCBzZXRTY2FsZV0gPSBSZWFjdC51c2VTdGF0ZTxudW1iZXI+KDEuMCk7XG4gIGNvbnN0IFt6b29tTXVsdGlwbGllciwgc2V0Wm9vbU11bHRpcGxpZXJdID0gUmVhY3QudXNlU3RhdGU8bnVtYmVyPigxLjIpO1xuXG4gIHJldHVybiB7XG4gICAgcm90YXRpb24sXG4gICAgc2NhbGUsXG4gICAgc2V0Um90YXRpb24sXG4gICAgc2V0U2NhbGUsXG4gICAgc2V0Wm9vbU11bHRpcGxpZXIsXG4gICAgem9vbU11bHRpcGxpZXIsXG4gIH07XG59XG4iLCJpbXBvcnQgeyBEaW1lbnNpb25zLCBTaXplIH0gZnJvbSAnLi4vY29tcG9uZW50cy90eXBlcy9ib3VuZGluZ0JveCc7XG5pbXBvcnQgeyBpc1NpZGV3YXlzLCBQYWdlUm90YXRpb24gfSBmcm9tICcuL3JvdGF0ZSc7XG5cbi8vIENvbXB1dGVzIHRoZSBzdHlsZSBmb3IgYSBib3VuZGluZyBib3gsIGFjY291bnRpbmcgZm9yIHBhZ2Ugcm9hdGlvbiBhbmQgcGFnZSBzY2FsaW5nL3pvb21cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlQm91bmRpbmdCb3hTdHlsZShcbiAgYm91bmRpbmdCb3hTaXplOiBTaXplLFxuICBwYWdlRGltZW5zaW9uczogRGltZW5zaW9ucyxcbiAgcm90YXRpb246IFBhZ2VSb3RhdGlvbixcbiAgc2NhbGU6IG51bWJlclxuKTogU2l6ZSB7XG4gIGNvbnN0IHsgdG9wLCBsZWZ0LCBoZWlnaHQsIHdpZHRoIH0gPSBib3VuZGluZ0JveFNpemU7XG5cbiAgc3dpdGNoIChyb3RhdGlvbikge1xuICAgIGNhc2UgUGFnZVJvdGF0aW9uLlJvdGF0ZTkwOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdG9wOiBsZWZ0ICogc2NhbGUsXG4gICAgICAgIGxlZnQ6IChwYWdlRGltZW5zaW9ucy5oZWlnaHQgLSBoZWlnaHQgLSB0b3ApICogc2NhbGUsXG4gICAgICAgIGhlaWdodDogd2lkdGggKiBzY2FsZSxcbiAgICAgICAgd2lkdGg6IGhlaWdodCAqIHNjYWxlLFxuICAgICAgfTtcbiAgICBjYXNlIFBhZ2VSb3RhdGlvbi5Sb3RhdGUxODA6XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0b3A6IChwYWdlRGltZW5zaW9ucy5oZWlnaHQgLSBoZWlnaHQgLSB0b3ApICogc2NhbGUsXG4gICAgICAgIGxlZnQ6IChwYWdlRGltZW5zaW9ucy53aWR0aCAtIHdpZHRoIC0gbGVmdCkgKiBzY2FsZSxcbiAgICAgICAgaGVpZ2h0OiBoZWlnaHQgKiBzY2FsZSxcbiAgICAgICAgd2lkdGg6IHdpZHRoICogc2NhbGUsXG4gICAgICB9O1xuICAgIGNhc2UgUGFnZVJvdGF0aW9uLlJvdGF0ZTI3MDpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRvcDogKHBhZ2VEaW1lbnNpb25zLndpZHRoIC0gd2lkdGggLSBsZWZ0KSAqIHNjYWxlLFxuICAgICAgICBsZWZ0OiB0b3AgKiBzY2FsZSxcbiAgICAgICAgaGVpZ2h0OiB3aWR0aCAqIHNjYWxlLFxuICAgICAgICB3aWR0aDogaGVpZ2h0ICogc2NhbGUsXG4gICAgICB9O1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0b3A6IHRvcCAqIHNjYWxlLFxuICAgICAgICBsZWZ0OiBsZWZ0ICogc2NhbGUsXG4gICAgICAgIGhlaWdodDogaGVpZ2h0ICogc2NhbGUsXG4gICAgICAgIHdpZHRoOiB3aWR0aCAqIHNjYWxlLFxuICAgICAgfTtcbiAgfVxufVxuXG4vLyBDb21wdXRlIHRoZSBzdHlsZSBmb3IgYSBwYWdlLCBhY2NvdW50aW5nIGZvciBwYWdlIHJvdGF0aW9uIGFuZCBwYWdlIHNjYWxpbmcvem9vbVxuZXhwb3J0IGZ1bmN0aW9uIGNvbXB1dGVQYWdlU3R5bGUoXG4gIHBhZ2VEaW1lbnNpb25zOiBEaW1lbnNpb25zLFxuICByb3RhdGlvbjogUGFnZVJvdGF0aW9uLFxuICBzY2FsZTogbnVtYmVyXG4pOiBTaXplIHtcbiAgcmV0dXJuIHtcbiAgICBoZWlnaHQ6IGdldFBhZ2VIZWlnaHQocGFnZURpbWVuc2lvbnMsIHJvdGF0aW9uKSAqIHNjYWxlLFxuICAgIHdpZHRoOiBnZXRQYWdlV2lkdGgocGFnZURpbWVuc2lvbnMsIHJvdGF0aW9uKSAqIHNjYWxlLFxuICAgIGxlZnQ6IDAsXG4gICAgdG9wOiAwLFxuICB9O1xufVxuXG4vLyBHZXQgcGFnZSBoZWlnaHQgYWNjb3VudGluZyBmb3IgcGFnZSByb3RhdGlvbi0gaWYgdGhlIHBhZ2UgaXMgcm90YXRlZCBvbiBpdHMgc2lkZSwgaXRzIHdpZHRoIGJlY29tZXMgaXRzIGhlaWdodFxuZXhwb3J0IGZ1bmN0aW9uIGdldFBhZ2VIZWlnaHQocGFnZURpbWVuc2lvbnM6IERpbWVuc2lvbnMsIHJvdGF0aW9uOiBQYWdlUm90YXRpb24pOiBudW1iZXIge1xuICByZXR1cm4gaXNTaWRld2F5cyhyb3RhdGlvbikgPyBwYWdlRGltZW5zaW9ucy53aWR0aCA6IHBhZ2VEaW1lbnNpb25zLmhlaWdodDtcbn1cblxuLy8gR2V0IHBhZ2Ugd2lkdGggYWNjb3VudGluZyBmb3IgcGFnZSByb3RhdGlvbi0gaWYgdGhlIHBhZ2UgaXMgcm90YXRlZCBvbiBpdHMgc2lkZSwgaXRzIGhlaWdodCBiZWNvbWVzIGl0cyB3aWR0aFxuZXhwb3J0IGZ1bmN0aW9uIGdldFBhZ2VXaWR0aChwYWdlRGltZW5zaW9uczogRGltZW5zaW9ucywgcm90YXRpb246IFBhZ2VSb3RhdGlvbik6IG51bWJlciB7XG4gIHJldHVybiBpc1NpZGV3YXlzKHJvdGF0aW9uKSA/IHBhZ2VEaW1lbnNpb25zLmhlaWdodCA6IHBhZ2VEaW1lbnNpb25zLndpZHRoO1xufVxuIiwiaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5cbmltcG9ydCB7IERvY3VtZW50Q29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvRG9jdW1lbnRDb250ZXh0JztcbmltcG9ydCB7IFRyYW5zZm9ybUNvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L1RyYW5zZm9ybUNvbnRleHQnO1xuaW1wb3J0IHsgY29tcHV0ZUJvdW5kaW5nQm94U3R5bGUgfSBmcm9tICcuLi91dGlscy9zdHlsZSc7XG5pbXBvcnQgeyBCb3VuZGluZ0JveCBhcyBCb3VuZGluZ0JveFR5cGUgfSBmcm9tICcuL3R5cGVzL2JvdW5kaW5nQm94JztcblxuZXhwb3J0IHR5cGUgUHJvcHMgPSB7XG4gIGNsYXNzTmFtZT86IHN0cmluZztcbiAgaWQ/OiBzdHJpbmc7XG4gIGlzSGlnaGxpZ2h0ZWQ/OiBib29sZWFuO1xuICBvbkNsaWNrPzogKCkgPT4gdm9pZDtcbn0gJiBCb3VuZGluZ0JveFR5cGU7XG5cbmV4cG9ydCBjb25zdCBCb3VuZGluZ0JveDogUmVhY3QuRnVuY3Rpb25Db21wb25lbnQ8UHJvcHM+ID0gKHtcbiAgdG9wLFxuICBsZWZ0LFxuICBoZWlnaHQsXG4gIHdpZHRoLFxuICBjbGFzc05hbWUsXG4gIGlkLFxuICBpc0hpZ2hsaWdodGVkLFxuICBvbkNsaWNrLFxuICAuLi5leHRyYVByb3BzXG59OiBQcm9wcykgPT4ge1xuICBjb25zdCB7IHBhZ2VEaW1lbnNpb25zIH0gPSBSZWFjdC51c2VDb250ZXh0KERvY3VtZW50Q29udGV4dCk7XG4gIGNvbnN0IHsgcm90YXRpb24sIHNjYWxlIH0gPSBSZWFjdC51c2VDb250ZXh0KFRyYW5zZm9ybUNvbnRleHQpO1xuICBjb25zdCBib3hTaXplID0geyB0b3AsIGxlZnQsIGhlaWdodCwgd2lkdGggfTtcbiAgY29uc3QgY29tcG9uZW50Q2xhc3NOYW1lID0gY2xhc3NOYW1lcyhcbiAgICAncmVhZGVyX19wYWdlLW92ZXJsYXlfX2JvdW5kaW5nLWJveCcsXG4gICAgaXNIaWdobGlnaHRlZCA9PT0gdHJ1ZSA/ICdyZWFkZXJfX3BhZ2Utb3ZlcmxheV9fYm91bmRpbmctYm94LWhpZ2hsaWdodGVkJyA6ICcnLFxuICAgIGNsYXNzTmFtZVxuICApO1xuXG4gIGNvbnN0IGdldEJvdW5kaW5nQm94U3R5bGUgPSBSZWFjdC51c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgcmV0dXJuIGNvbXB1dGVCb3VuZGluZ0JveFN0eWxlKGJveFNpemUsIHBhZ2VEaW1lbnNpb25zLCByb3RhdGlvbiwgc2NhbGUpO1xuICB9LCBbcGFnZURpbWVuc2lvbnMsIHJvdGF0aW9uLCBzY2FsZV0pO1xuXG4gIGNvbnN0IHJvdGF0aW9uQ2xhc3NOYW1lID0gUmVhY3QudXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIHJldHVybiBgcm90YXRlJHtyb3RhdGlvbn1gO1xuICB9LCBbcm90YXRpb25dKTtcblxuICByZXR1cm4gKFxuICAgIDxSZWFjdC5GcmFnbWVudD5cbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3NOYW1lPXtgcmVhZGVyX19wYWdlLW92ZXJsYXlfX2JvdW5kaW5nLWJveC11bmRlcmxpbmUgJHtyb3RhdGlvbkNsYXNzTmFtZSgpfWB9XG4gICAgICAgIHN0eWxlPXtnZXRCb3VuZGluZ0JveFN0eWxlKCl9XG4gICAgICAvPlxuICAgICAgPGRpdlxuICAgICAgICBpZD17aWR9XG4gICAgICAgIGNsYXNzTmFtZT17YCR7Y29tcG9uZW50Q2xhc3NOYW1lfSAke3JvdGF0aW9uQ2xhc3NOYW1lKCl9YH1cbiAgICAgICAgc3R5bGU9e2dldEJvdW5kaW5nQm94U3R5bGUoKX1cbiAgICAgICAgb25DbGljaz17b25DbGlja31cbiAgICAgICAgey4uLmV4dHJhUHJvcHN9XG4gICAgICAvPlxuICAgIDwvUmVhY3QuRnJhZ21lbnQ+XG4gICk7XG59O1xuIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2V4dGVuZHMoKSB7XG4gIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7XG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07XG5cbiAgICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHtcbiAgICAgICAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRhcmdldDtcbiAgfTtcblxuICByZXR1cm4gX2V4dGVuZHMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXNMb29zZShzb3VyY2UsIGV4Y2x1ZGVkKSB7XG4gIGlmIChzb3VyY2UgPT0gbnVsbCkgcmV0dXJuIHt9O1xuICB2YXIgdGFyZ2V0ID0ge307XG4gIHZhciBzb3VyY2VLZXlzID0gT2JqZWN0LmtleXMoc291cmNlKTtcbiAgdmFyIGtleSwgaTtcblxuICBmb3IgKGkgPSAwOyBpIDwgc291cmNlS2V5cy5sZW5ndGg7IGkrKykge1xuICAgIGtleSA9IHNvdXJjZUtleXNbaV07XG4gICAgaWYgKGV4Y2x1ZGVkLmluZGV4T2Yoa2V5KSA+PSAwKSBjb250aW51ZTtcbiAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldO1xuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn0iLCJpbXBvcnQgb2JqZWN0V2l0aG91dFByb3BlcnRpZXNMb29zZSBmcm9tIFwiLi9vYmplY3RXaXRob3V0UHJvcGVydGllc0xvb3NlLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMoc291cmNlLCBleGNsdWRlZCkge1xuICBpZiAoc291cmNlID09IG51bGwpIHJldHVybiB7fTtcbiAgdmFyIHRhcmdldCA9IG9iamVjdFdpdGhvdXRQcm9wZXJ0aWVzTG9vc2Uoc291cmNlLCBleGNsdWRlZCk7XG4gIHZhciBrZXksIGk7XG5cbiAgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHtcbiAgICB2YXIgc291cmNlU3ltYm9sS2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoc291cmNlKTtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBzb3VyY2VTeW1ib2xLZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBrZXkgPSBzb3VyY2VTeW1ib2xLZXlzW2ldO1xuICAgICAgaWYgKGV4Y2x1ZGVkLmluZGV4T2Yoa2V5KSA+PSAwKSBjb250aW51ZTtcbiAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHNvdXJjZSwga2V5KSkgY29udGludWU7XG4gICAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0YXJnZXQ7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX3R5cGVvZihvYmopIHtcbiAgXCJAYmFiZWwvaGVscGVycyAtIHR5cGVvZlwiO1xuXG4gIHJldHVybiBfdHlwZW9mID0gXCJmdW5jdGlvblwiID09IHR5cGVvZiBTeW1ib2wgJiYgXCJzeW1ib2xcIiA9PSB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID8gZnVuY3Rpb24gKG9iaikge1xuICAgIHJldHVybiB0eXBlb2Ygb2JqO1xuICB9IDogZnVuY3Rpb24gKG9iaikge1xuICAgIHJldHVybiBvYmogJiYgXCJmdW5jdGlvblwiID09IHR5cGVvZiBTeW1ib2wgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7XG4gIH0sIF90eXBlb2Yob2JqKTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7XG4gIGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTtcbiAgfVxufSIsImZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07XG4gICAgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlO1xuICAgIGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTtcbiAgICBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfY3JlYXRlQ2xhc3MoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7XG4gIGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpO1xuICBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShDb25zdHJ1Y3RvciwgXCJwcm90b3R5cGVcIiwge1xuICAgIHdyaXRhYmxlOiBmYWxzZVxuICB9KTtcbiAgcmV0dXJuIENvbnN0cnVjdG9yO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoc2VsZikge1xuICBpZiAoc2VsZiA9PT0gdm9pZCAwKSB7XG4gICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKFwidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkXCIpO1xuICB9XG5cbiAgcmV0dXJuIHNlbGY7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX3NldFByb3RvdHlwZU9mKG8sIHApIHtcbiAgX3NldFByb3RvdHlwZU9mID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IGZ1bmN0aW9uIF9zZXRQcm90b3R5cGVPZihvLCBwKSB7XG4gICAgby5fX3Byb3RvX18gPSBwO1xuICAgIHJldHVybiBvO1xuICB9O1xuXG4gIHJldHVybiBfc2V0UHJvdG90eXBlT2YobywgcCk7XG59IiwiaW1wb3J0IHNldFByb3RvdHlwZU9mIGZyb20gXCIuL3NldFByb3RvdHlwZU9mLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHtcbiAgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSBcImZ1bmN0aW9uXCIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvblwiKTtcbiAgfVxuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzdWJDbGFzcywgXCJwcm90b3R5cGVcIiwge1xuICAgIHZhbHVlOiBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHtcbiAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgIHZhbHVlOiBzdWJDbGFzcyxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgfVxuICAgIH0pLFxuICAgIHdyaXRhYmxlOiBmYWxzZVxuICB9KTtcbiAgaWYgKHN1cGVyQ2xhc3MpIHNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKTtcbn0iLCJpbXBvcnQgX3R5cGVvZiBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy90eXBlb2ZcIjtcbmltcG9ydCBhc3NlcnRUaGlzSW5pdGlhbGl6ZWQgZnJvbSBcIi4vYXNzZXJ0VGhpc0luaXRpYWxpemVkLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7XG4gIGlmIChjYWxsICYmIChfdHlwZW9mKGNhbGwpID09PSBcIm9iamVjdFwiIHx8IHR5cGVvZiBjYWxsID09PSBcImZ1bmN0aW9uXCIpKSB7XG4gICAgcmV0dXJuIGNhbGw7XG4gIH0gZWxzZSBpZiAoY2FsbCAhPT0gdm9pZCAwKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkRlcml2ZWQgY29uc3RydWN0b3JzIG1heSBvbmx5IHJldHVybiBvYmplY3Qgb3IgdW5kZWZpbmVkXCIpO1xuICB9XG5cbiAgcmV0dXJuIGFzc2VydFRoaXNJbml0aWFsaXplZChzZWxmKTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfZ2V0UHJvdG90eXBlT2Yobykge1xuICBfZ2V0UHJvdG90eXBlT2YgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3QuZ2V0UHJvdG90eXBlT2YgOiBmdW5jdGlvbiBfZ2V0UHJvdG90eXBlT2Yobykge1xuICAgIHJldHVybiBvLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2Yobyk7XG4gIH07XG4gIHJldHVybiBfZ2V0UHJvdG90eXBlT2Yobyk7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2RlZmluZVByb3BlcnR5KG9iaiwga2V5LCB2YWx1ZSkge1xuICBpZiAoa2V5IGluIG9iaikge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwge1xuICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgb2JqW2tleV0gPSB2YWx1ZTtcbiAgfVxuXG4gIHJldHVybiBvYmo7XG59IiwiLy8gQXMgZGVmaW5lZCBvbiB0aGUgbGlzdCBvZiBzdXBwb3J0ZWQgZXZlbnRzOiBodHRwczovL3JlYWN0anMub3JnL2RvY3MvZXZlbnRzLmh0bWxcbmV4cG9ydCB2YXIgY2xpcGJvYXJkRXZlbnRzID0gWydvbkNvcHknLCAnb25DdXQnLCAnb25QYXN0ZSddO1xuZXhwb3J0IHZhciBjb21wb3NpdGlvbkV2ZW50cyA9IFsnb25Db21wb3NpdGlvbkVuZCcsICdvbkNvbXBvc2l0aW9uU3RhcnQnLCAnb25Db21wb3NpdGlvblVwZGF0ZSddO1xuZXhwb3J0IHZhciBrZXlib2FyZEV2ZW50cyA9IFsnb25LZXlEb3duJywgJ29uS2V5UHJlc3MnLCAnb25LZXlVcCddO1xuZXhwb3J0IHZhciBmb2N1c0V2ZW50cyA9IFsnb25Gb2N1cycsICdvbkJsdXInXTtcbmV4cG9ydCB2YXIgZm9ybUV2ZW50cyA9IFsnb25DaGFuZ2UnLCAnb25JbnB1dCcsICdvbkludmFsaWQnLCAnb25SZXNldCcsICdvblN1Ym1pdCddO1xuZXhwb3J0IHZhciBnZW5lcmljRXZlbnRzID0gWydvbkVycm9yJywgJ29uTG9hZCddO1xuZXhwb3J0IHZhciBtb3VzZUV2ZW50cyA9IFsnb25DbGljaycsICdvbkNvbnRleHRNZW51JywgJ29uRG91YmxlQ2xpY2snLCAnb25EcmFnJywgJ29uRHJhZ0VuZCcsICdvbkRyYWdFbnRlcicsICdvbkRyYWdFeGl0JywgJ29uRHJhZ0xlYXZlJywgJ29uRHJhZ092ZXInLCAnb25EcmFnU3RhcnQnLCAnb25Ecm9wJywgJ29uTW91c2VEb3duJywgJ29uTW91c2VFbnRlcicsICdvbk1vdXNlTGVhdmUnLCAnb25Nb3VzZU1vdmUnLCAnb25Nb3VzZU91dCcsICdvbk1vdXNlT3ZlcicsICdvbk1vdXNlVXAnXTtcbmV4cG9ydCB2YXIgcG9pbnRlckV2ZW50cyA9IFsnb25Qb2ludGVyRG93bicsICdvblBvaW50ZXJNb3ZlJywgJ29uUG9pbnRlclVwJywgJ29uUG9pbnRlckNhbmNlbCcsICdvbkdvdFBvaW50ZXJDYXB0dXJlJywgJ29uTG9zdFBvaW50ZXJDYXB0dXJlJywgJ29uUG9pbnRlckVudGVyJywgJ29uUG9pbnRlckxlYXZlJywgJ29uUG9pbnRlck92ZXInLCAnb25Qb2ludGVyT3V0J107XG5leHBvcnQgdmFyIHNlbGVjdGlvbkV2ZW50cyA9IFsnb25TZWxlY3QnXTtcbmV4cG9ydCB2YXIgdG91Y2hFdmVudHMgPSBbJ29uVG91Y2hDYW5jZWwnLCAnb25Ub3VjaEVuZCcsICdvblRvdWNoTW92ZScsICdvblRvdWNoU3RhcnQnXTtcbmV4cG9ydCB2YXIgdWlFdmVudHMgPSBbJ29uU2Nyb2xsJ107XG5leHBvcnQgdmFyIHdoZWVsRXZlbnRzID0gWydvbldoZWVsJ107XG5leHBvcnQgdmFyIG1lZGlhRXZlbnRzID0gWydvbkFib3J0JywgJ29uQ2FuUGxheScsICdvbkNhblBsYXlUaHJvdWdoJywgJ29uRHVyYXRpb25DaGFuZ2UnLCAnb25FbXB0aWVkJywgJ29uRW5jcnlwdGVkJywgJ29uRW5kZWQnLCAnb25FcnJvcicsICdvbkxvYWRlZERhdGEnLCAnb25Mb2FkZWRNZXRhZGF0YScsICdvbkxvYWRTdGFydCcsICdvblBhdXNlJywgJ29uUGxheScsICdvblBsYXlpbmcnLCAnb25Qcm9ncmVzcycsICdvblJhdGVDaGFuZ2UnLCAnb25TZWVrZWQnLCAnb25TZWVraW5nJywgJ29uU3RhbGxlZCcsICdvblN1c3BlbmQnLCAnb25UaW1lVXBkYXRlJywgJ29uVm9sdW1lQ2hhbmdlJywgJ29uV2FpdGluZyddO1xuZXhwb3J0IHZhciBpbWFnZUV2ZW50cyA9IFsnb25Mb2FkJywgJ29uRXJyb3InXTtcbmV4cG9ydCB2YXIgYW5pbWF0aW9uRXZlbnRzID0gWydvbkFuaW1hdGlvblN0YXJ0JywgJ29uQW5pbWF0aW9uRW5kJywgJ29uQW5pbWF0aW9uSXRlcmF0aW9uJ107XG5leHBvcnQgdmFyIHRyYW5zaXRpb25FdmVudHMgPSBbJ29uVHJhbnNpdGlvbkVuZCddO1xuZXhwb3J0IHZhciBvdGhlckV2ZW50cyA9IFsnb25Ub2dnbGUnXTtcbmV4cG9ydCB2YXIgYWxsRXZlbnRzID0gW10uY29uY2F0KGNsaXBib2FyZEV2ZW50cywgY29tcG9zaXRpb25FdmVudHMsIGtleWJvYXJkRXZlbnRzLCBmb2N1c0V2ZW50cywgZm9ybUV2ZW50cywgZ2VuZXJpY0V2ZW50cywgbW91c2VFdmVudHMsIHBvaW50ZXJFdmVudHMsIHNlbGVjdGlvbkV2ZW50cywgdG91Y2hFdmVudHMsIHVpRXZlbnRzLCB3aGVlbEV2ZW50cywgbWVkaWFFdmVudHMsIGltYWdlRXZlbnRzLCBhbmltYXRpb25FdmVudHMsIHRyYW5zaXRpb25FdmVudHMsIG90aGVyRXZlbnRzKTtcbi8qKlxuICogUmV0dXJucyBhbiBvYmplY3Qgd2l0aCBvbi1ldmVudCBjYWxsYmFjayBwcm9wcyBjdXJyaWVkIHdpdGggcHJvdmlkZWQgYXJncy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm9wcyBQcm9wcyBwYXNzZWQgdG8gYSBjb21wb25lbnQuXG4gKiBAcGFyYW0ge0Z1bmN0aW9uPX0gZ2V0QXJncyBBIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhcmd1bWVudChzKSBvbi1ldmVudCBjYWxsYmFja3NcbiAqICAgc2hhbGwgYmUgY3VycmllZCB3aXRoLlxuICovXG5cbnZhciBtYWtlRXZlbnRQcm9wcyA9IGZ1bmN0aW9uIG1ha2VFdmVudFByb3BzKHByb3BzLCBnZXRBcmdzKSB7XG4gIHZhciBldmVudFByb3BzID0ge307XG4gIGFsbEV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChldmVudE5hbWUpIHtcbiAgICBpZiAoIShldmVudE5hbWUgaW4gcHJvcHMpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFnZXRBcmdzKSB7XG4gICAgICBldmVudFByb3BzW2V2ZW50TmFtZV0gPSBwcm9wc1tldmVudE5hbWVdO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGV2ZW50UHJvcHNbZXZlbnROYW1lXSA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgcmV0dXJuIHByb3BzW2V2ZW50TmFtZV0oZXZlbnQsIGdldEFyZ3MoZXZlbnROYW1lKSk7XG4gICAgfTtcbiAgfSk7XG4gIHJldHVybiBldmVudFByb3BzO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgbWFrZUV2ZW50UHJvcHM7IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbWFrZUNhbmNlbGxhYmxlUHJvbWlzZShwcm9taXNlKSB7XG4gIHZhciBpc0NhbmNlbGxlZCA9IGZhbHNlO1xuICB2YXIgd3JhcHBlZFByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgcHJvbWlzZS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiAhaXNDYW5jZWxsZWQgJiYgcmVzb2x2ZS5hcHBseSh2b2lkIDAsIGFyZ3VtZW50cyk7XG4gICAgfSlbXCJjYXRjaFwiXShmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIHJldHVybiAhaXNDYW5jZWxsZWQgJiYgcmVqZWN0KGVycm9yKTtcbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiB7XG4gICAgcHJvbWlzZTogd3JhcHBlZFByb21pc2UsXG4gICAgY2FuY2VsOiBmdW5jdGlvbiBjYW5jZWwoKSB7XG4gICAgICBpc0NhbmNlbGxlZCA9IHRydWU7XG4gICAgfVxuICB9O1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIG1lcmdlQ2xhc3NOYW1lcygpIHtcbiAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cykucmVkdWNlKGZ1bmN0aW9uIChjbGFzc0xpc3QsIGFyZykge1xuICAgIHJldHVybiBjbGFzc0xpc3QuY29uY2F0KGFyZyk7XG4gIH0sIFtdKS5maWx0ZXIoZnVuY3Rpb24gKGFyZykge1xuICAgIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3RyaW5nJztcbiAgfSkuam9pbignICcpO1xufSIsInZhciBpc1Byb2R1Y3Rpb24gPSBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Byb2R1Y3Rpb24nO1xudmFyIHByZWZpeCA9ICdJbnZhcmlhbnQgZmFpbGVkJztcbmZ1bmN0aW9uIGludmFyaWFudChjb25kaXRpb24sIG1lc3NhZ2UpIHtcbiAgICBpZiAoY29uZGl0aW9uKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGlzUHJvZHVjdGlvbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IocHJlZml4KTtcbiAgICB9XG4gICAgdmFyIHByb3ZpZGVkID0gdHlwZW9mIG1lc3NhZ2UgPT09ICdmdW5jdGlvbicgPyBtZXNzYWdlKCkgOiBtZXNzYWdlO1xuICAgIHZhciB2YWx1ZSA9IHByb3ZpZGVkID8gcHJlZml4ICsgXCI6IFwiICsgcHJvdmlkZWQgOiBwcmVmaXg7XG4gICAgdGhyb3cgbmV3IEVycm9yKHZhbHVlKTtcbn1cblxuZXhwb3J0IHsgaW52YXJpYW50IGFzIGRlZmF1bHQgfTtcbiIsInZhciBpc1Byb2R1Y3Rpb24gPSBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Byb2R1Y3Rpb24nO1xuZnVuY3Rpb24gd2FybmluZyhjb25kaXRpb24sIG1lc3NhZ2UpIHtcbiAgaWYgKCFpc1Byb2R1Y3Rpb24pIHtcbiAgICBpZiAoY29uZGl0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHRleHQgPSBcIldhcm5pbmc6IFwiICsgbWVzc2FnZTtcblxuICAgIGlmICh0eXBlb2YgY29uc29sZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGNvbnNvbGUud2Fybih0ZXh0KTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgdGhyb3cgRXJyb3IodGV4dCk7XG4gICAgfSBjYXRjaCAoeCkge31cbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCB3YXJuaW5nO1xuIiwiaW1wb3J0IHsgY3JlYXRlQ29udGV4dCB9IGZyb20gJ3JlYWN0JztcbmV4cG9ydCBkZWZhdWx0IC8qI19fUFVSRV9fKi9jcmVhdGVDb250ZXh0KG51bGwpOyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTWVzc2FnZShfcmVmKSB7XG4gIHZhciBjaGlsZHJlbiA9IF9yZWYuY2hpbGRyZW4sXG4gICAgICB0eXBlID0gX3JlZi50eXBlO1xuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogXCJyZWFjdC1wZGZfX21lc3NhZ2UgcmVhY3QtcGRmX19tZXNzYWdlLS1cIi5jb25jYXQodHlwZSlcbiAgfSwgY2hpbGRyZW4pO1xufVxuTWVzc2FnZS5wcm9wVHlwZXMgPSB7XG4gIGNoaWxkcmVuOiBQcm9wVHlwZXMubm9kZSxcbiAgdHlwZTogUHJvcFR5cGVzLm9uZU9mKFsnZXJyb3InLCAnbG9hZGluZycsICduby1kYXRhJ10pLmlzUmVxdWlyZWRcbn07IiwiaW1wb3J0IF9jbGFzc0NhbGxDaGVjayBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY2xhc3NDYWxsQ2hlY2tcIjtcbmltcG9ydCBfY3JlYXRlQ2xhc3MgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NyZWF0ZUNsYXNzXCI7XG5cbi8qIENvcHlyaWdodCAyMDE1IE1vemlsbGEgRm91bmRhdGlvblxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuaW1wb3J0IGludmFyaWFudCBmcm9tICd0aW55LWludmFyaWFudCc7XG52YXIgREVGQVVMVF9MSU5LX1JFTCA9ICdub29wZW5lciBub3JlZmVycmVyIG5vZm9sbG93JztcblxudmFyIExpbmtTZXJ2aWNlID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gTGlua1NlcnZpY2UoKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIExpbmtTZXJ2aWNlKTtcblxuICAgIHRoaXMuZXh0ZXJuYWxMaW5rVGFyZ2V0ID0gbnVsbDtcbiAgICB0aGlzLmV4dGVybmFsTGlua1JlbCA9IG51bGw7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3MoTGlua1NlcnZpY2UsIFt7XG4gICAga2V5OiBcInNldERvY3VtZW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHNldERvY3VtZW50KHBkZkRvY3VtZW50KSB7XG4gICAgICB0aGlzLnBkZkRvY3VtZW50ID0gcGRmRG9jdW1lbnQ7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInNldFZpZXdlclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRWaWV3ZXIocGRmVmlld2VyKSB7XG4gICAgICB0aGlzLnBkZlZpZXdlciA9IHBkZlZpZXdlcjtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwic2V0RXh0ZXJuYWxMaW5rUmVsXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHNldEV4dGVybmFsTGlua1JlbChleHRlcm5hbExpbmtSZWwpIHtcbiAgICAgIHRoaXMuZXh0ZXJuYWxMaW5rUmVsID0gZXh0ZXJuYWxMaW5rUmVsO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJzZXRFeHRlcm5hbExpbmtUYXJnZXRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2V0RXh0ZXJuYWxMaW5rVGFyZ2V0KGV4dGVybmFsTGlua1RhcmdldCkge1xuICAgICAgdGhpcy5leHRlcm5hbExpbmtUYXJnZXQgPSBleHRlcm5hbExpbmtUYXJnZXQ7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInNldEhpc3RvcnlcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2V0SGlzdG9yeSgpIHt9XG4gIH0sIHtcbiAgICBrZXk6IFwicGFnZXNDb3VudFwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgcmV0dXJuIHRoaXMucGRmRG9jdW1lbnQgPyB0aGlzLnBkZkRvY3VtZW50Lm51bVBhZ2VzIDogMDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicGFnZVwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgcmV0dXJuIHRoaXMucGRmVmlld2VyLmN1cnJlbnRQYWdlTnVtYmVyO1xuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbiBzZXQodmFsdWUpIHtcbiAgICAgIHRoaXMucGRmVmlld2VyLmN1cnJlbnRQYWdlTnVtYmVyID0gdmFsdWU7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInJvdGF0aW9uXCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9LFxuICAgIHNldDogZnVuY3Rpb24gc2V0KHZhbHVlKSB7fVxuICB9LCB7XG4gICAga2V5OiBcImdvVG9EZXN0aW5hdGlvblwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnb1RvRGVzdGluYXRpb24oZGVzdCkge1xuICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBkZXN0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIF90aGlzLnBkZkRvY3VtZW50LmdldERlc3RpbmF0aW9uKGRlc3QpLnRoZW4ocmVzb2x2ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShkZXN0KSkge1xuICAgICAgICAgIHJlc29sdmUoZGVzdCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZGVzdC50aGVuKHJlc29sdmUpO1xuICAgICAgICB9XG4gICAgICB9KS50aGVuKGZ1bmN0aW9uIChleHBsaWNpdERlc3QpIHtcbiAgICAgICAgaW52YXJpYW50KEFycmF5LmlzQXJyYXkoZXhwbGljaXREZXN0KSwgXCJcXFwiXCIuY29uY2F0KGV4cGxpY2l0RGVzdCwgXCJcXFwiIGlzIG5vdCBhIHZhbGlkIGRlc3RpbmF0aW9uIGFycmF5LlwiKSk7XG4gICAgICAgIHZhciBkZXN0UmVmID0gZXhwbGljaXREZXN0WzBdO1xuICAgICAgICBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICAgIGlmIChkZXN0UmVmIGluc3RhbmNlb2YgT2JqZWN0KSB7XG4gICAgICAgICAgICBfdGhpcy5wZGZEb2N1bWVudC5nZXRQYWdlSW5kZXgoZGVzdFJlZikudGhlbihmdW5jdGlvbiAocGFnZUluZGV4KSB7XG4gICAgICAgICAgICAgIHJlc29sdmUocGFnZUluZGV4KTtcbiAgICAgICAgICAgIH0pW1wiY2F0Y2hcIl0oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICBpbnZhcmlhbnQoZmFsc2UsIFwiXFxcIlwiLmNvbmNhdChkZXN0UmVmLCBcIlxcXCIgaXMgbm90IGEgdmFsaWQgcGFnZSByZWZlcmVuY2UuXCIpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGRlc3RSZWYgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICByZXNvbHZlKGRlc3RSZWYpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpbnZhcmlhbnQoZmFsc2UsIFwiXFxcIlwiLmNvbmNhdChkZXN0UmVmLCBcIlxcXCIgaXMgbm90IGEgdmFsaWQgZGVzdGluYXRpb24gcmVmZXJlbmNlLlwiKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChwYWdlSW5kZXgpIHtcbiAgICAgICAgICB2YXIgcGFnZU51bWJlciA9IHBhZ2VJbmRleCArIDE7XG4gICAgICAgICAgaW52YXJpYW50KHBhZ2VOdW1iZXIgPj0gMSAmJiBwYWdlTnVtYmVyIDw9IF90aGlzLnBhZ2VzQ291bnQsIFwiXFxcIlwiLmNvbmNhdChwYWdlTnVtYmVyLCBcIlxcXCIgaXMgbm90IGEgdmFsaWQgcGFnZSBudW1iZXIuXCIpKTtcblxuICAgICAgICAgIF90aGlzLnBkZlZpZXdlci5zY3JvbGxQYWdlSW50b1ZpZXcoe1xuICAgICAgICAgICAgZGVzdDogZGVzdCxcbiAgICAgICAgICAgIHBhZ2VJbmRleDogcGFnZUluZGV4LFxuICAgICAgICAgICAgcGFnZU51bWJlcjogcGFnZU51bWJlclxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJuYXZpZ2F0ZVRvXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIG5hdmlnYXRlVG8oZGVzdCkge1xuICAgICAgdGhpcy5nb1RvRGVzdGluYXRpb24oZGVzdCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdvVG9QYWdlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdvVG9QYWdlKCkge31cbiAgfSwge1xuICAgIGtleTogXCJhZGRMaW5rQXR0cmlidXRlc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBhZGRMaW5rQXR0cmlidXRlcyhsaW5rLCB1cmwsIG5ld1dpbmRvdykge1xuICAgICAgbGluay5ocmVmID0gdXJsO1xuICAgICAgbGluay5yZWwgPSB0aGlzLmV4dGVybmFsTGlua1JlbCB8fCBERUZBVUxUX0xJTktfUkVMO1xuICAgICAgbGluay50YXJnZXQgPSBuZXdXaW5kb3cgPyAnX2JsYW5rJyA6IHRoaXMuZXh0ZXJuYWxMaW5rVGFyZ2V0IHx8ICcnO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXREZXN0aW5hdGlvbkhhc2hcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0RGVzdGluYXRpb25IYXNoKCkge1xuICAgICAgcmV0dXJuICcjJztcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0QW5jaG9yVXJsXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldEFuY2hvclVybCgpIHtcbiAgICAgIHJldHVybiAnIyc7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInNldEhhc2hcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2V0SGFzaCgpIHt9XG4gIH0sIHtcbiAgICBrZXk6IFwiZXhlY3V0ZU5hbWVkQWN0aW9uXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGV4ZWN1dGVOYW1lZEFjdGlvbigpIHt9XG4gIH0sIHtcbiAgICBrZXk6IFwiY2FjaGVQYWdlUmVmXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNhY2hlUGFnZVJlZigpIHt9XG4gIH0sIHtcbiAgICBrZXk6IFwiaXNQYWdlVmlzaWJsZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBpc1BhZ2VWaXNpYmxlKCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImlzUGFnZUNhY2hlZFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBpc1BhZ2VDYWNoZWQoKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gTGlua1NlcnZpY2U7XG59KCk7XG5cbmV4cG9ydCB7IExpbmtTZXJ2aWNlIGFzIGRlZmF1bHQgfTsiLCIvLyBBcyBkZWZpbmVkIGluIGh0dHBzOi8vZ2l0aHViLmNvbS9tb3ppbGxhL3BkZi5qcy9ibG9iL2Q5ZmFjMzQ1OTYwOWE4MDdiZTY1MDZmYjM0NDFiNWRhNGIxNTRkMTQvc3JjL3NoYXJlZC91dGlsLmpzI0wzNzEtTDM3NFxudmFyIFBhc3N3b3JkUmVzcG9uc2VzID0ge1xuICBORUVEX1BBU1NXT1JEOiAxLFxuICBJTkNPUlJFQ1RfUEFTU1dPUkQ6IDJcbn07XG5leHBvcnQgZGVmYXVsdCBQYXNzd29yZFJlc3BvbnNlczsiLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfYXJyYXlXaXRoSG9sZXMoYXJyKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KGFycikpIHJldHVybiBhcnI7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2l0ZXJhYmxlVG9BcnJheUxpbWl0KGFyciwgaSkge1xuICB2YXIgX2kgPSBhcnIgPT0gbnVsbCA/IG51bGwgOiB0eXBlb2YgU3ltYm9sICE9PSBcInVuZGVmaW5lZFwiICYmIGFycltTeW1ib2wuaXRlcmF0b3JdIHx8IGFycltcIkBAaXRlcmF0b3JcIl07XG5cbiAgaWYgKF9pID09IG51bGwpIHJldHVybjtcbiAgdmFyIF9hcnIgPSBbXTtcbiAgdmFyIF9uID0gdHJ1ZTtcbiAgdmFyIF9kID0gZmFsc2U7XG5cbiAgdmFyIF9zLCBfZTtcblxuICB0cnkge1xuICAgIGZvciAoX2kgPSBfaS5jYWxsKGFycik7ICEoX24gPSAoX3MgPSBfaS5uZXh0KCkpLmRvbmUpOyBfbiA9IHRydWUpIHtcbiAgICAgIF9hcnIucHVzaChfcy52YWx1ZSk7XG5cbiAgICAgIGlmIChpICYmIF9hcnIubGVuZ3RoID09PSBpKSBicmVhaztcbiAgICB9XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIF9kID0gdHJ1ZTtcbiAgICBfZSA9IGVycjtcbiAgfSBmaW5hbGx5IHtcbiAgICB0cnkge1xuICAgICAgaWYgKCFfbiAmJiBfaVtcInJldHVyblwiXSAhPSBudWxsKSBfaVtcInJldHVyblwiXSgpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpZiAoX2QpIHRocm93IF9lO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBfYXJyO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9hcnJheUxpa2VUb0FycmF5KGFyciwgbGVuKSB7XG4gIGlmIChsZW4gPT0gbnVsbCB8fCBsZW4gPiBhcnIubGVuZ3RoKSBsZW4gPSBhcnIubGVuZ3RoO1xuXG4gIGZvciAodmFyIGkgPSAwLCBhcnIyID0gbmV3IEFycmF5KGxlbik7IGkgPCBsZW47IGkrKykge1xuICAgIGFycjJbaV0gPSBhcnJbaV07XG4gIH1cblxuICByZXR1cm4gYXJyMjtcbn0iLCJpbXBvcnQgYXJyYXlMaWtlVG9BcnJheSBmcm9tIFwiLi9hcnJheUxpa2VUb0FycmF5LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkobywgbWluTGVuKSB7XG4gIGlmICghbykgcmV0dXJuO1xuICBpZiAodHlwZW9mIG8gPT09IFwic3RyaW5nXCIpIHJldHVybiBhcnJheUxpa2VUb0FycmF5KG8sIG1pbkxlbik7XG4gIHZhciBuID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pLnNsaWNlKDgsIC0xKTtcbiAgaWYgKG4gPT09IFwiT2JqZWN0XCIgJiYgby5jb25zdHJ1Y3RvcikgbiA9IG8uY29uc3RydWN0b3IubmFtZTtcbiAgaWYgKG4gPT09IFwiTWFwXCIgfHwgbiA9PT0gXCJTZXRcIikgcmV0dXJuIEFycmF5LmZyb20obyk7XG4gIGlmIChuID09PSBcIkFyZ3VtZW50c1wiIHx8IC9eKD86VWl8SSludCg/Ojh8MTZ8MzIpKD86Q2xhbXBlZCk/QXJyYXkkLy50ZXN0KG4pKSByZXR1cm4gYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9ub25JdGVyYWJsZVJlc3QoKSB7XG4gIHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGF0dGVtcHQgdG8gZGVzdHJ1Y3R1cmUgbm9uLWl0ZXJhYmxlIGluc3RhbmNlLlxcbkluIG9yZGVyIHRvIGJlIGl0ZXJhYmxlLCBub24tYXJyYXkgb2JqZWN0cyBtdXN0IGhhdmUgYSBbU3ltYm9sLml0ZXJhdG9yXSgpIG1ldGhvZC5cIik7XG59IiwiaW1wb3J0IGFycmF5V2l0aEhvbGVzIGZyb20gXCIuL2FycmF5V2l0aEhvbGVzLmpzXCI7XG5pbXBvcnQgaXRlcmFibGVUb0FycmF5TGltaXQgZnJvbSBcIi4vaXRlcmFibGVUb0FycmF5TGltaXQuanNcIjtcbmltcG9ydCB1bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSBmcm9tIFwiLi91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheS5qc1wiO1xuaW1wb3J0IG5vbkl0ZXJhYmxlUmVzdCBmcm9tIFwiLi9ub25JdGVyYWJsZVJlc3QuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9zbGljZWRUb0FycmF5KGFyciwgaSkge1xuICByZXR1cm4gYXJyYXlXaXRoSG9sZXMoYXJyKSB8fCBpdGVyYWJsZVRvQXJyYXlMaW1pdChhcnIsIGkpIHx8IHVuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KGFyciwgaSkgfHwgbm9uSXRlcmFibGVSZXN0KCk7XG59IiwiaW1wb3J0IF9zbGljZWRUb0FycmF5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9zbGljZWRUb0FycmF5XCI7XG5pbXBvcnQgaW52YXJpYW50IGZyb20gJ3RpbnktaW52YXJpYW50JztcbmltcG9ydCB3YXJuaW5nIGZyb20gJ3Rpbnktd2FybmluZyc7XG4vKipcbiAqIENoZWNrcyBpZiB3ZSdyZSBydW5uaW5nIGluIGEgYnJvd3NlciBlbnZpcm9ubWVudC5cbiAqL1xuXG5leHBvcnQgdmFyIGlzQnJvd3NlciA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnO1xuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB3ZSdyZSBydW5uaW5nIGZyb20gYSBsb2NhbCBmaWxlIHN5c3RlbS5cbiAqL1xuXG5leHBvcnQgdmFyIGlzTG9jYWxGaWxlU3lzdGVtID0gaXNCcm93c2VyICYmIHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCA9PT0gJ2ZpbGU6Jztcbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSB2YXJpYWJsZSBpcyBkZWZpbmVkLlxuICpcbiAqIEBwYXJhbSB7Kn0gdmFyaWFibGUgVmFyaWFibGUgdG8gY2hlY2tcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaXNEZWZpbmVkKHZhcmlhYmxlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFyaWFibGUgIT09ICd1bmRlZmluZWQnO1xufVxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIHZhcmlhYmxlIGlzIGRlZmluZWQgYW5kIG5vdCBudWxsLlxuICpcbiAqIEBwYXJhbSB7Kn0gdmFyaWFibGUgVmFyaWFibGUgdG8gY2hlY2tcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaXNQcm92aWRlZCh2YXJpYWJsZSkge1xuICByZXR1cm4gaXNEZWZpbmVkKHZhcmlhYmxlKSAmJiB2YXJpYWJsZSAhPT0gbnVsbDtcbn1cbi8qKlxuICogQ2hlY2tlcyB3aGV0aGVyIGEgdmFyaWFibGUgcHJvdmlkZWQgaXMgYSBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHsqfSB2YXJpYWJsZSBWYXJpYWJsZSB0byBjaGVja1xuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBpc1N0cmluZyh2YXJpYWJsZSkge1xuICByZXR1cm4gdHlwZW9mIHZhcmlhYmxlID09PSAnc3RyaW5nJztcbn1cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSB2YXJpYWJsZSBwcm92aWRlZCBpcyBhbiBBcnJheUJ1ZmZlci5cbiAqXG4gKiBAcGFyYW0geyp9IHZhcmlhYmxlIFZhcmlhYmxlIHRvIGNoZWNrXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQXJyYXlCdWZmZXIodmFyaWFibGUpIHtcbiAgcmV0dXJuIHZhcmlhYmxlIGluc3RhbmNlb2YgQXJyYXlCdWZmZXI7XG59XG4vKipcbiAqIENoZWNrZXMgd2hldGhlciBhIHZhcmlhYmxlIHByb3ZpZGVkIGlzIGEgQmxvYi5cbiAqXG4gKiBAcGFyYW0geyp9IHZhcmlhYmxlIFZhcmlhYmxlIHRvIGNoZWNrXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQmxvYih2YXJpYWJsZSkge1xuICBpbnZhcmlhbnQoaXNCcm93c2VyLCAnaXNCbG9iIGNhbiBvbmx5IGJlIHVzZWQgaW4gYSBicm93c2VyIGVudmlyb25tZW50Jyk7XG4gIHJldHVybiB2YXJpYWJsZSBpbnN0YW5jZW9mIEJsb2I7XG59XG4vKipcbiAqIENoZWNrZXMgd2hldGhlciBhIHZhcmlhYmxlIHByb3ZpZGVkIGlzIGEgRmlsZS5cbiAqXG4gKiBAcGFyYW0geyp9IHZhcmlhYmxlIFZhcmlhYmxlIHRvIGNoZWNrXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRmlsZSh2YXJpYWJsZSkge1xuICBpbnZhcmlhbnQoaXNCcm93c2VyLCAnaXNGaWxlIGNhbiBvbmx5IGJlIHVzZWQgaW4gYSBicm93c2VyIGVudmlyb25tZW50Jyk7XG4gIHJldHVybiB2YXJpYWJsZSBpbnN0YW5jZW9mIEZpbGU7XG59XG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgc3RyaW5nIHByb3ZpZGVkIGlzIGEgZGF0YSBVUkkuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0ciBTdHJpbmcgdG8gY2hlY2tcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaXNEYXRhVVJJKHN0cikge1xuICByZXR1cm4gaXNTdHJpbmcoc3RyKSAmJiAvXmRhdGE6Ly50ZXN0KHN0cik7XG59XG5leHBvcnQgZnVuY3Rpb24gZGF0YVVSSXRvQnl0ZVN0cmluZyhkYXRhVVJJKSB7XG4gIGludmFyaWFudChpc0RhdGFVUkkoZGF0YVVSSSksICdJbnZhbGlkIGRhdGEgVVJJLicpO1xuXG4gIHZhciBfZGF0YVVSSSRzcGxpdCA9IGRhdGFVUkkuc3BsaXQoJywnKSxcbiAgICAgIF9kYXRhVVJJJHNwbGl0MiA9IF9zbGljZWRUb0FycmF5KF9kYXRhVVJJJHNwbGl0LCAyKSxcbiAgICAgIGhlYWRlcnNTdHJpbmcgPSBfZGF0YVVSSSRzcGxpdDJbMF0sXG4gICAgICBkYXRhU3RyaW5nID0gX2RhdGFVUkkkc3BsaXQyWzFdO1xuXG4gIHZhciBoZWFkZXJzID0gaGVhZGVyc1N0cmluZy5zcGxpdCgnOycpO1xuXG4gIGlmIChoZWFkZXJzLmluZGV4T2YoJ2Jhc2U2NCcpICE9PSAtMSkge1xuICAgIHJldHVybiBhdG9iKGRhdGFTdHJpbmcpO1xuICB9XG5cbiAgcmV0dXJuIHVuZXNjYXBlKGRhdGFTdHJpbmcpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdldFBpeGVsUmF0aW8oKSB7XG4gIHJldHVybiBpc0Jyb3dzZXIgJiYgd2luZG93LmRldmljZVBpeGVsUmF0aW8gfHwgMTtcbn1cbnZhciBhbGxvd0ZpbGVBY2Nlc3NGcm9tRmlsZXNUaXAgPSAnT24gQ2hyb21pdW0gYmFzZWQgYnJvd3NlcnMsIHlvdSBjYW4gdXNlIC0tYWxsb3ctZmlsZS1hY2Nlc3MtZnJvbS1maWxlcyBmbGFnIGZvciBkZWJ1Z2dpbmcgcHVycG9zZXMuJztcbmV4cG9ydCBmdW5jdGlvbiBkaXNwbGF5Q09SU1dhcm5pbmcoKSB7XG4gIHdhcm5pbmcoIWlzTG9jYWxGaWxlU3lzdGVtLCBcIkxvYWRpbmcgUERGIGFzIGJhc2U2NCBzdHJpbmdzL1VSTHMgbWF5IG5vdCB3b3JrIG9uIHByb3RvY29scyBvdGhlciB0aGFuIEhUVFAvSFRUUFMuIFwiLmNvbmNhdChhbGxvd0ZpbGVBY2Nlc3NGcm9tRmlsZXNUaXApKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBkaXNwbGF5V29ya2VyV2FybmluZygpIHtcbiAgd2FybmluZyghaXNMb2NhbEZpbGVTeXN0ZW0sIFwiTG9hZGluZyBQREYuanMgd29ya2VyIG1heSBub3Qgd29yayBvbiBwcm90b2NvbHMgb3RoZXIgdGhhbiBIVFRQL0hUVFBTLiBcIi5jb25jYXQoYWxsb3dGaWxlQWNjZXNzRnJvbUZpbGVzVGlwKSk7XG59XG5leHBvcnQgZnVuY3Rpb24gY2FuY2VsUnVubmluZ1Rhc2socnVubmluZ1Rhc2spIHtcbiAgaWYgKHJ1bm5pbmdUYXNrICYmIHJ1bm5pbmdUYXNrLmNhbmNlbCkgcnVubmluZ1Rhc2suY2FuY2VsKCk7XG59XG5leHBvcnQgZnVuY3Rpb24gbWFrZVBhZ2VDYWxsYmFjayhwYWdlLCBzY2FsZSkge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkocGFnZSwgJ3dpZHRoJywge1xuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgcmV0dXJuIHRoaXMudmlld1syXSAqIHNjYWxlO1xuICAgIH0sXG4gICAgY29uZmlndXJhYmxlOiB0cnVlXG4gIH0pO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkocGFnZSwgJ2hlaWdodCcsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiB0aGlzLnZpZXdbM10gKiBzY2FsZTtcbiAgICB9LFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICB9KTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHBhZ2UsICdvcmlnaW5hbFdpZHRoJywge1xuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgcmV0dXJuIHRoaXMudmlld1syXTtcbiAgICB9LFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICB9KTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHBhZ2UsICdvcmlnaW5hbEhlaWdodCcsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiB0aGlzLnZpZXdbM107XG4gICAgfSxcbiAgICBjb25maWd1cmFibGU6IHRydWVcbiAgfSk7XG4gIHJldHVybiBwYWdlO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGlzQ2FuY2VsRXhjZXB0aW9uKGVycm9yKSB7XG4gIHJldHVybiBlcnJvci5uYW1lID09PSAnUmVuZGVyaW5nQ2FuY2VsbGVkRXhjZXB0aW9uJztcbn1cbmV4cG9ydCBmdW5jdGlvbiBsb2FkRnJvbUZpbGUoZmlsZSkge1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIHZhciByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xuXG4gICAgcmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiByZXNvbHZlKG5ldyBVaW50OEFycmF5KHJlYWRlci5yZXN1bHQpKTtcbiAgICB9O1xuXG4gICAgcmVhZGVyLm9uZXJyb3IgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgIHN3aXRjaCAoZXZlbnQudGFyZ2V0LmVycm9yLmNvZGUpIHtcbiAgICAgICAgY2FzZSBldmVudC50YXJnZXQuZXJyb3IuTk9UX0ZPVU5EX0VSUjpcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcignRXJyb3Igd2hpbGUgcmVhZGluZyBhIGZpbGU6IEZpbGUgbm90IGZvdW5kLicpKTtcblxuICAgICAgICBjYXNlIGV2ZW50LnRhcmdldC5lcnJvci5OT1RfUkVBREFCTEVfRVJSOlxuICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCdFcnJvciB3aGlsZSByZWFkaW5nIGEgZmlsZTogRmlsZSBub3QgcmVhZGFibGUuJykpO1xuXG4gICAgICAgIGNhc2UgZXZlbnQudGFyZ2V0LmVycm9yLlNFQ1VSSVRZX0VSUjpcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcignRXJyb3Igd2hpbGUgcmVhZGluZyBhIGZpbGU6IFNlY3VyaXR5IGVycm9yLicpKTtcblxuICAgICAgICBjYXNlIGV2ZW50LnRhcmdldC5lcnJvci5BQk9SVF9FUlI6XG4gICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoJ0Vycm9yIHdoaWxlIHJlYWRpbmcgYSBmaWxlOiBBYm9ydGVkLicpKTtcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCdFcnJvciB3aGlsZSByZWFkaW5nIGEgZmlsZS4nKSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcihmaWxlKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfSk7XG59IiwiaW1wb3J0IGFycmF5TGlrZVRvQXJyYXkgZnJvbSBcIi4vYXJyYXlMaWtlVG9BcnJheS5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2FycmF5V2l0aG91dEhvbGVzKGFycikge1xuICBpZiAoQXJyYXkuaXNBcnJheShhcnIpKSByZXR1cm4gYXJyYXlMaWtlVG9BcnJheShhcnIpO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9pdGVyYWJsZVRvQXJyYXkoaXRlcikge1xuICBpZiAodHlwZW9mIFN5bWJvbCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBpdGVyW1N5bWJvbC5pdGVyYXRvcl0gIT0gbnVsbCB8fCBpdGVyW1wiQEBpdGVyYXRvclwiXSAhPSBudWxsKSByZXR1cm4gQXJyYXkuZnJvbShpdGVyKTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfbm9uSXRlcmFibGVTcHJlYWQoKSB7XG4gIHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGF0dGVtcHQgdG8gc3ByZWFkIG5vbi1pdGVyYWJsZSBpbnN0YW5jZS5cXG5JbiBvcmRlciB0byBiZSBpdGVyYWJsZSwgbm9uLWFycmF5IG9iamVjdHMgbXVzdCBoYXZlIGEgW1N5bWJvbC5pdGVyYXRvcl0oKSBtZXRob2QuXCIpO1xufSIsImltcG9ydCBhcnJheVdpdGhvdXRIb2xlcyBmcm9tIFwiLi9hcnJheVdpdGhvdXRIb2xlcy5qc1wiO1xuaW1wb3J0IGl0ZXJhYmxlVG9BcnJheSBmcm9tIFwiLi9pdGVyYWJsZVRvQXJyYXkuanNcIjtcbmltcG9ydCB1bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSBmcm9tIFwiLi91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheS5qc1wiO1xuaW1wb3J0IG5vbkl0ZXJhYmxlU3ByZWFkIGZyb20gXCIuL25vbkl0ZXJhYmxlU3ByZWFkLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfdG9Db25zdW1hYmxlQXJyYXkoYXJyKSB7XG4gIHJldHVybiBhcnJheVdpdGhvdXRIb2xlcyhhcnIpIHx8IGl0ZXJhYmxlVG9BcnJheShhcnIpIHx8IHVuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KGFycikgfHwgbm9uSXRlcmFibGVTcHJlYWQoKTtcbn0iLCJpbXBvcnQgX3R5cGVvZiBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vdHlwZW9mXCI7XG5pbXBvcnQgX3RvQ29uc3VtYWJsZUFycmF5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS90b0NvbnN1bWFibGVBcnJheVwiO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcbmltcG9ydCB7IG1vdXNlRXZlbnRzLCB0b3VjaEV2ZW50cywga2V5Ym9hcmRFdmVudHMgfSBmcm9tICdtYWtlLWV2ZW50LXByb3BzJztcbmltcG9ydCB7IGlzRGVmaW5lZCB9IGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IExpbmtTZXJ2aWNlIGZyb20gJy4uL0xpbmtTZXJ2aWNlJztcbmV4cG9ydCB2YXIgZXZlbnRQcm9wcyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHJlc3VsdCA9IHt9O1xuICBbXS5jb25jYXQoX3RvQ29uc3VtYWJsZUFycmF5KG1vdXNlRXZlbnRzKSwgX3RvQ29uc3VtYWJsZUFycmF5KHRvdWNoRXZlbnRzKSwgX3RvQ29uc3VtYWJsZUFycmF5KGtleWJvYXJkRXZlbnRzKSkuZm9yRWFjaChmdW5jdGlvbiAoZXZlbnROYW1lKSB7XG4gICAgcmVzdWx0W2V2ZW50TmFtZV0gPSBQcm9wVHlwZXMuZnVuYztcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59KCk7XG52YXIgZmlsZVR5cGVzID0gW1Byb3BUeXBlcy5zdHJpbmcsIFByb3BUeXBlcy5pbnN0YW5jZU9mKEFycmF5QnVmZmVyKSwgUHJvcFR5cGVzLnNoYXBlKHtcbiAgZGF0YTogUHJvcFR5cGVzLm9uZU9mVHlwZShbUHJvcFR5cGVzLm9iamVjdCwgUHJvcFR5cGVzLnN0cmluZ10pLFxuICBodHRwSGVhZGVyczogUHJvcFR5cGVzLm9iamVjdCxcbiAgcmFuZ2U6IFByb3BUeXBlcy5vYmplY3QsXG4gIHVybDogUHJvcFR5cGVzLnN0cmluZyxcbiAgd2l0aENyZWRlbnRpYWxzOiBQcm9wVHlwZXMuYm9vbFxufSldO1xuXG5pZiAodHlwZW9mIEZpbGUgIT09ICd1bmRlZmluZWQnKSB7XG4gIGZpbGVUeXBlcy5wdXNoKFByb3BUeXBlcy5pbnN0YW5jZU9mKEZpbGUpKTtcbn1cblxuaWYgKHR5cGVvZiBCbG9iICE9PSAndW5kZWZpbmVkJykge1xuICBmaWxlVHlwZXMucHVzaChQcm9wVHlwZXMuaW5zdGFuY2VPZihCbG9iKSk7XG59XG5cbmV4cG9ydCB2YXIgaXNDbGFzc05hbWUgPSBQcm9wVHlwZXMub25lT2ZUeXBlKFtQcm9wVHlwZXMuc3RyaW5nLCBQcm9wVHlwZXMuYXJyYXlPZihQcm9wVHlwZXMuc3RyaW5nKV0pO1xuZXhwb3J0IHZhciBpc0ZpbGUgPSBQcm9wVHlwZXMub25lT2ZUeXBlKGZpbGVUeXBlcyk7XG5leHBvcnQgdmFyIGlzTGlua1NlcnZpY2UgPSBQcm9wVHlwZXMuaW5zdGFuY2VPZihMaW5rU2VydmljZSk7XG5leHBvcnQgdmFyIGlzTGlua1RhcmdldCA9IFByb3BUeXBlcy5vbmVPZihbJ19zZWxmJywgJ19ibGFuaycsICdfcGFyZW50JywgJ190b3AnXSk7XG5leHBvcnQgdmFyIGlzUGFnZSA9IFByb3BUeXBlcy5zaGFwZSh7XG4gIGNvbW1vbk9ianM6IFByb3BUeXBlcy5zaGFwZSh7fSkuaXNSZXF1aXJlZCxcbiAgZ2V0QW5ub3RhdGlvbnM6IFByb3BUeXBlcy5mdW5jLmlzUmVxdWlyZWQsXG4gIGdldFRleHRDb250ZW50OiBQcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICBnZXRWaWV3cG9ydDogUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgcmVuZGVyOiBQcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkXG59KTtcbmV4cG9ydCB2YXIgaXNQYWdlSW5kZXggPSBmdW5jdGlvbiBpc1BhZ2VJbmRleChwcm9wcywgcHJvcE5hbWUsIGNvbXBvbmVudE5hbWUpIHtcbiAgdmFyIHBhZ2VJbmRleCA9IHByb3BzW3Byb3BOYW1lXSxcbiAgICAgIHBhZ2VOdW1iZXIgPSBwcm9wcy5wYWdlTnVtYmVyLFxuICAgICAgcGRmID0gcHJvcHMucGRmO1xuXG4gIGlmICghaXNEZWZpbmVkKHBkZikpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmIChpc0RlZmluZWQocGFnZUluZGV4KSkge1xuICAgIGlmICh0eXBlb2YgcGFnZUluZGV4ICE9PSAnbnVtYmVyJykge1xuICAgICAgcmV0dXJuIG5ldyBFcnJvcihcImBcIi5jb25jYXQocHJvcE5hbWUsIFwiYCBvZiB0eXBlIGBcIikuY29uY2F0KF90eXBlb2YocGFnZUluZGV4KSwgXCJgIHN1cHBsaWVkIHRvIGBcIikuY29uY2F0KGNvbXBvbmVudE5hbWUsIFwiYCwgZXhwZWN0ZWQgYG51bWJlcmAuXCIpKTtcbiAgICB9XG5cbiAgICBpZiAocGFnZUluZGV4IDwgMCkge1xuICAgICAgcmV0dXJuIG5ldyBFcnJvcihcIkV4cGVjdGVkIGBcIi5jb25jYXQocHJvcE5hbWUsIFwiYCB0byBiZSBncmVhdGVyIG9yIGVxdWFsIHRvIDAuXCIpKTtcbiAgICB9XG5cbiAgICB2YXIgbnVtUGFnZXMgPSBwZGYubnVtUGFnZXM7XG5cbiAgICBpZiAocGFnZUluZGV4ICsgMSA+IG51bVBhZ2VzKSB7XG4gICAgICByZXR1cm4gbmV3IEVycm9yKFwiRXhwZWN0ZWQgYFwiLmNvbmNhdChwcm9wTmFtZSwgXCJgIHRvIGJlIGxlc3Mgb3IgZXF1YWwgdG8gXCIpLmNvbmNhdChudW1QYWdlcyAtIDEsIFwiLlwiKSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKCFpc0RlZmluZWQocGFnZU51bWJlcikpIHtcbiAgICByZXR1cm4gbmV3IEVycm9yKFwiYFwiLmNvbmNhdChwcm9wTmFtZSwgXCJgIG5vdCBzdXBwbGllZC4gRWl0aGVyIHBhZ2VJbmRleCBvciBwYWdlTnVtYmVyIG11c3QgYmUgc3VwcGxpZWQgdG8gYFwiKS5jb25jYXQoY29tcG9uZW50TmFtZSwgXCJgLlwiKSk7XG4gIH0gLy8gRXZlcnl0aGluZyBpcyBmaW5lXG5cblxuICByZXR1cm4gbnVsbDtcbn07XG5leHBvcnQgdmFyIGlzUGFnZU51bWJlciA9IGZ1bmN0aW9uIGlzUGFnZU51bWJlcihwcm9wcywgcHJvcE5hbWUsIGNvbXBvbmVudE5hbWUpIHtcbiAgdmFyIHBhZ2VOdW1iZXIgPSBwcm9wc1twcm9wTmFtZV0sXG4gICAgICBwYWdlSW5kZXggPSBwcm9wcy5wYWdlSW5kZXgsXG4gICAgICBwZGYgPSBwcm9wcy5wZGY7XG5cbiAgaWYgKCFpc0RlZmluZWQocGRmKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKGlzRGVmaW5lZChwYWdlTnVtYmVyKSkge1xuICAgIGlmICh0eXBlb2YgcGFnZU51bWJlciAhPT0gJ251bWJlcicpIHtcbiAgICAgIHJldHVybiBuZXcgRXJyb3IoXCJgXCIuY29uY2F0KHByb3BOYW1lLCBcImAgb2YgdHlwZSBgXCIpLmNvbmNhdChfdHlwZW9mKHBhZ2VOdW1iZXIpLCBcImAgc3VwcGxpZWQgdG8gYFwiKS5jb25jYXQoY29tcG9uZW50TmFtZSwgXCJgLCBleHBlY3RlZCBgbnVtYmVyYC5cIikpO1xuICAgIH1cblxuICAgIGlmIChwYWdlTnVtYmVyIDwgMSkge1xuICAgICAgcmV0dXJuIG5ldyBFcnJvcihcIkV4cGVjdGVkIGBcIi5jb25jYXQocHJvcE5hbWUsIFwiYCB0byBiZSBncmVhdGVyIG9yIGVxdWFsIHRvIDEuXCIpKTtcbiAgICB9XG5cbiAgICB2YXIgbnVtUGFnZXMgPSBwZGYubnVtUGFnZXM7XG5cbiAgICBpZiAocGFnZU51bWJlciA+IG51bVBhZ2VzKSB7XG4gICAgICByZXR1cm4gbmV3IEVycm9yKFwiRXhwZWN0ZWQgYFwiLmNvbmNhdChwcm9wTmFtZSwgXCJgIHRvIGJlIGxlc3Mgb3IgZXF1YWwgdG8gXCIpLmNvbmNhdChudW1QYWdlcywgXCIuXCIpKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoIWlzRGVmaW5lZChwYWdlSW5kZXgpKSB7XG4gICAgcmV0dXJuIG5ldyBFcnJvcihcImBcIi5jb25jYXQocHJvcE5hbWUsIFwiYCBub3Qgc3VwcGxpZWQuIEVpdGhlciBwYWdlSW5kZXggb3IgcGFnZU51bWJlciBtdXN0IGJlIHN1cHBsaWVkIHRvIGBcIikuY29uY2F0KGNvbXBvbmVudE5hbWUsIFwiYC5cIikpO1xuICB9IC8vIEV2ZXJ5dGhpbmcgaXMgZmluZVxuXG5cbiAgcmV0dXJuIG51bGw7XG59O1xuZXhwb3J0IHZhciBpc1BkZiA9IFByb3BUeXBlcy5vbmVPZlR5cGUoW1Byb3BUeXBlcy5zaGFwZSh7XG4gIGdldERlc3RpbmF0aW9uOiBQcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICBnZXRPdXRsaW5lOiBQcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICBnZXRQYWdlOiBQcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICBudW1QYWdlczogUHJvcFR5cGVzLm51bWJlci5pc1JlcXVpcmVkXG59KSwgUHJvcFR5cGVzLmJvb2xdKTtcbmV4cG9ydCB2YXIgaXNSZWYgPSBQcm9wVHlwZXMub25lT2ZUeXBlKFtQcm9wVHlwZXMuZnVuYywgUHJvcFR5cGVzLnNoYXBlKHtcbiAgY3VycmVudDogUHJvcFR5cGVzLmFueVxufSldKTtcbmV4cG9ydCB2YXIgaXNSZW5kZXJNb2RlID0gUHJvcFR5cGVzLm9uZU9mKFsnY2FudmFzJywgJ25vbmUnLCAnc3ZnJ10pO1xuZXhwb3J0IHZhciBpc1JvdGF0ZSA9IFByb3BUeXBlcy5vbmVPZihbMCwgOTAsIDE4MCwgMjcwXSk7IiwiaW1wb3J0IF9leHRlbmRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9leHRlbmRzXCI7XG5pbXBvcnQgX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RXaXRob3V0UHJvcGVydGllc1wiO1xuaW1wb3J0IF90eXBlb2YgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3R5cGVvZlwiO1xuaW1wb3J0IF9jbGFzc0NhbGxDaGVjayBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY2xhc3NDYWxsQ2hlY2tcIjtcbmltcG9ydCBfY3JlYXRlQ2xhc3MgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NyZWF0ZUNsYXNzXCI7XG5pbXBvcnQgX2Fzc2VydFRoaXNJbml0aWFsaXplZCBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vYXNzZXJ0VGhpc0luaXRpYWxpemVkXCI7XG5pbXBvcnQgX2luaGVyaXRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pbmhlcml0c1wiO1xuaW1wb3J0IF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuXCI7XG5pbXBvcnQgX2dldFByb3RvdHlwZU9mIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9nZXRQcm90b3R5cGVPZlwiO1xuaW1wb3J0IF9kZWZpbmVQcm9wZXJ0eSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZGVmaW5lUHJvcGVydHlcIjtcbnZhciBfZXhjbHVkZWQgPSBbXCJ1cmxcIl07XG5cbmZ1bmN0aW9uIG93bktleXMob2JqZWN0LCBlbnVtZXJhYmxlT25seSkgeyB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iamVjdCk7IGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKSB7IHZhciBzeW1ib2xzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhvYmplY3QpOyBlbnVtZXJhYmxlT25seSAmJiAoc3ltYm9scyA9IHN5bWJvbHMuZmlsdGVyKGZ1bmN0aW9uIChzeW0pIHsgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBzeW0pLmVudW1lcmFibGU7IH0pKSwga2V5cy5wdXNoLmFwcGx5KGtleXMsIHN5bWJvbHMpOyB9IHJldHVybiBrZXlzOyB9XG5cbmZ1bmN0aW9uIF9vYmplY3RTcHJlYWQodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBudWxsICE9IGFyZ3VtZW50c1tpXSA/IGFyZ3VtZW50c1tpXSA6IHt9OyBpICUgMiA/IG93bktleXMoT2JqZWN0KHNvdXJjZSksICEwKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsgX2RlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBzb3VyY2Vba2V5XSk7IH0pIDogT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMgPyBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKHNvdXJjZSkpIDogb3duS2V5cyhPYmplY3Qoc291cmNlKSkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihzb3VyY2UsIGtleSkpOyB9KTsgfSByZXR1cm4gdGFyZ2V0OyB9XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlcihEZXJpdmVkKSB7IHZhciBoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0ID0gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCgpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZihEZXJpdmVkKSwgcmVzdWx0OyBpZiAoaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCkgeyB2YXIgTmV3VGFyZ2V0ID0gX2dldFByb3RvdHlwZU9mKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG4vKipcbiAqIExvYWRzIGEgUERGIGRvY3VtZW50LiBQYXNzZXMgaXQgdG8gYWxsIGNoaWxkcmVuLlxuICovXG5pbXBvcnQgUmVhY3QsIHsgUHVyZUNvbXBvbmVudCB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgbWFrZUV2ZW50UHJvcHMgZnJvbSAnbWFrZS1ldmVudC1wcm9wcyc7XG5pbXBvcnQgbWFrZUNhbmNlbGxhYmxlIGZyb20gJ21ha2UtY2FuY2VsbGFibGUtcHJvbWlzZSc7XG5pbXBvcnQgbWVyZ2VDbGFzc05hbWVzIGZyb20gJ21lcmdlLWNsYXNzLW5hbWVzJztcbmltcG9ydCBpbnZhcmlhbnQgZnJvbSAndGlueS1pbnZhcmlhbnQnO1xuaW1wb3J0IHdhcm5pbmcgZnJvbSAndGlueS13YXJuaW5nJztcbmltcG9ydCAqIGFzIHBkZmpzIGZyb20gJ3BkZmpzLWRpc3QvYnVpbGQvcGRmJztcbmltcG9ydCBEb2N1bWVudENvbnRleHQgZnJvbSAnLi9Eb2N1bWVudENvbnRleHQnO1xuaW1wb3J0IE1lc3NhZ2UgZnJvbSAnLi9NZXNzYWdlJztcbmltcG9ydCBMaW5rU2VydmljZSBmcm9tICcuL0xpbmtTZXJ2aWNlJztcbmltcG9ydCBQYXNzd29yZFJlc3BvbnNlcyBmcm9tICcuL1Bhc3N3b3JkUmVzcG9uc2VzJztcbmltcG9ydCB7IGNhbmNlbFJ1bm5pbmdUYXNrLCBkYXRhVVJJdG9CeXRlU3RyaW5nLCBkaXNwbGF5Q09SU1dhcm5pbmcsIGlzQXJyYXlCdWZmZXIsIGlzQmxvYiwgaXNCcm93c2VyLCBpc0RhdGFVUkksIGlzRmlsZSwgbG9hZEZyb21GaWxlIH0gZnJvbSAnLi9zaGFyZWQvdXRpbHMnO1xuaW1wb3J0IHsgZXZlbnRQcm9wcywgaXNDbGFzc05hbWUsIGlzRmlsZSBhcyBpc0ZpbGVQcm9wLCBpc1JlZiB9IGZyb20gJy4vc2hhcmVkL3Byb3BUeXBlcyc7XG52YXIgUERGRGF0YVJhbmdlVHJhbnNwb3J0ID0gcGRmanMuUERGRGF0YVJhbmdlVHJhbnNwb3J0O1xuXG52YXIgRG9jdW1lbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9QdXJlQ29tcG9uZW50KSB7XG4gIF9pbmhlcml0cyhEb2N1bWVudCwgX1B1cmVDb21wb25lbnQpO1xuXG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIoRG9jdW1lbnQpO1xuXG4gIGZ1bmN0aW9uIERvY3VtZW50KCkge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBEb2N1bWVudCk7XG5cbiAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgIGFyZ3NbX2tleV0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgfVxuXG4gICAgX3RoaXMgPSBfc3VwZXIuY2FsbC5hcHBseShfc3VwZXIsIFt0aGlzXS5jb25jYXQoYXJncykpO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcInN0YXRlXCIsIHtcbiAgICAgIHBkZjogbnVsbFxuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcInZpZXdlclwiLCB7XG4gICAgICBzY3JvbGxQYWdlSW50b1ZpZXc6IGZ1bmN0aW9uIHNjcm9sbFBhZ2VJbnRvVmlldyhfcmVmKSB7XG4gICAgICAgIHZhciBkZXN0ID0gX3JlZi5kZXN0LFxuICAgICAgICAgICAgcGFnZUluZGV4ID0gX3JlZi5wYWdlSW5kZXgsXG4gICAgICAgICAgICBwYWdlTnVtYmVyID0gX3JlZi5wYWdlTnVtYmVyO1xuICAgICAgICAvLyBIYW5kbGluZyBqdW1waW5nIHRvIGludGVybmFsIGxpbmtzIHRhcmdldFxuICAgICAgICB2YXIgb25JdGVtQ2xpY2sgPSBfdGhpcy5wcm9wcy5vbkl0ZW1DbGljazsgLy8gRmlyc3QsIGNoZWNrIGlmIGN1c3RvbSBoYW5kbGluZyBvZiBvbkl0ZW1DbGljayB3YXMgcHJvdmlkZWRcblxuICAgICAgICBpZiAob25JdGVtQ2xpY2spIHtcbiAgICAgICAgICBvbkl0ZW1DbGljayh7XG4gICAgICAgICAgICBkZXN0OiBkZXN0LFxuICAgICAgICAgICAgcGFnZUluZGV4OiBwYWdlSW5kZXgsXG4gICAgICAgICAgICBwYWdlTnVtYmVyOiBwYWdlTnVtYmVyXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IC8vIElmIG5vdCwgdHJ5IHRvIGxvb2sgZm9yIHRhcmdldCBwYWdlIHdpdGhpbiB0aGUgPERvY3VtZW50Pi5cblxuXG4gICAgICAgIHZhciBwYWdlID0gX3RoaXMucGFnZXNbcGFnZUluZGV4XTtcblxuICAgICAgICBpZiAocGFnZSkge1xuICAgICAgICAgIC8vIFNjcm9sbCB0byB0aGUgcGFnZSBhdXRvbWF0aWNhbGx5XG4gICAgICAgICAgcGFnZS5zY3JvbGxJbnRvVmlldygpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHdhcm5pbmcoZmFsc2UsIFwiQW4gaW50ZXJuYWwgbGluayBsZWFkaW5nIHRvIHBhZ2UgXCIuY29uY2F0KHBhZ2VOdW1iZXIsIFwiIHdhcyBjbGlja2VkLCBidXQgbmVpdGhlciA8RG9jdW1lbnQ+IHdhcyBwcm92aWRlZCB3aXRoIG9uSXRlbUNsaWNrIG5vciBpdCB3YXMgYWJsZSB0byBmaW5kIHRoZSBwYWdlIHdpdGhpbiBpdHNlbGYuIEVpdGhlciBwcm92aWRlIG9uSXRlbUNsaWNrIHRvIDxEb2N1bWVudD4gYW5kIGhhbmRsZSBuYXZpZ2F0aW5nIGJ5IHlvdXJzZWxmIG9yIGVuc3VyZSB0aGF0IGFsbCBwYWdlcyBhcmUgcmVuZGVyZWQgd2l0aGluIDxEb2N1bWVudD4uXCIpKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJsaW5rU2VydmljZVwiLCBuZXcgTGlua1NlcnZpY2UoKSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwibG9hZERvY3VtZW50XCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIElmIGFub3RoZXIgcmVuZGVyaW5nIGlzIGluIHByb2dyZXNzLCBsZXQncyBjYW5jZWwgaXRcbiAgICAgIGNhbmNlbFJ1bm5pbmdUYXNrKF90aGlzLnJ1bm5pbmdUYXNrKTsgLy8gSWYgYW5vdGhlciBsb2FkaW5nIGlzIGluIHByb2dyZXNzLCBsZXQncyBkZXN0cm95IGl0XG5cbiAgICAgIGlmIChfdGhpcy5sb2FkaW5nVGFzaykgX3RoaXMubG9hZGluZ1Rhc2suZGVzdHJveSgpO1xuICAgICAgdmFyIGNhbmNlbGxhYmxlID0gbWFrZUNhbmNlbGxhYmxlKF90aGlzLmZpbmREb2N1bWVudFNvdXJjZSgpKTtcbiAgICAgIF90aGlzLnJ1bm5pbmdUYXNrID0gY2FuY2VsbGFibGU7XG4gICAgICBjYW5jZWxsYWJsZS5wcm9taXNlLnRoZW4oZnVuY3Rpb24gKHNvdXJjZSkge1xuICAgICAgICBfdGhpcy5vblNvdXJjZVN1Y2Nlc3MoKTtcblxuICAgICAgICBpZiAoIXNvdXJjZSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIF90aGlzLnNldFN0YXRlKGZ1bmN0aW9uIChwcmV2U3RhdGUpIHtcbiAgICAgICAgICBpZiAoIXByZXZTdGF0ZS5wZGYpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBwZGY6IG51bGxcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcblxuICAgICAgICB2YXIgX3RoaXMkcHJvcHMgPSBfdGhpcy5wcm9wcyxcbiAgICAgICAgICAgIG9wdGlvbnMgPSBfdGhpcyRwcm9wcy5vcHRpb25zLFxuICAgICAgICAgICAgb25Mb2FkUHJvZ3Jlc3MgPSBfdGhpcyRwcm9wcy5vbkxvYWRQcm9ncmVzcyxcbiAgICAgICAgICAgIG9uUGFzc3dvcmQgPSBfdGhpcyRwcm9wcy5vblBhc3N3b3JkO1xuICAgICAgICBfdGhpcy5sb2FkaW5nVGFzayA9IHBkZmpzLmdldERvY3VtZW50KF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwgc291cmNlKSwgb3B0aW9ucykpO1xuICAgICAgICBfdGhpcy5sb2FkaW5nVGFzay5vblBhc3N3b3JkID0gb25QYXNzd29yZDtcblxuICAgICAgICBpZiAob25Mb2FkUHJvZ3Jlc3MpIHtcbiAgICAgICAgICBfdGhpcy5sb2FkaW5nVGFzay5vblByb2dyZXNzID0gb25Mb2FkUHJvZ3Jlc3M7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY2FuY2VsbGFibGUgPSBtYWtlQ2FuY2VsbGFibGUoX3RoaXMubG9hZGluZ1Rhc2sucHJvbWlzZSk7XG4gICAgICAgIF90aGlzLnJ1bm5pbmdUYXNrID0gY2FuY2VsbGFibGU7XG4gICAgICAgIGNhbmNlbGxhYmxlLnByb21pc2UudGhlbihmdW5jdGlvbiAocGRmKSB7XG4gICAgICAgICAgX3RoaXMuc2V0U3RhdGUoZnVuY3Rpb24gKHByZXZTdGF0ZSkge1xuICAgICAgICAgICAgaWYgKHByZXZTdGF0ZS5wZGYgJiYgcHJldlN0YXRlLnBkZi5maW5nZXJwcmludCA9PT0gcGRmLmZpbmdlcnByaW50KSB7XG4gICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBwZGY6IHBkZlxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9LCBfdGhpcy5vbkxvYWRTdWNjZXNzKTtcbiAgICAgICAgfSlbXCJjYXRjaFwiXShmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICBfdGhpcy5vbkxvYWRFcnJvcihlcnJvcik7XG4gICAgICAgIH0pO1xuICAgICAgfSlbXCJjYXRjaFwiXShmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgX3RoaXMub25Tb3VyY2VFcnJvcihlcnJvcik7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJzZXR1cExpbmtTZXJ2aWNlXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfdGhpcyRwcm9wczIgPSBfdGhpcy5wcm9wcyxcbiAgICAgICAgICBleHRlcm5hbExpbmtSZWwgPSBfdGhpcyRwcm9wczIuZXh0ZXJuYWxMaW5rUmVsLFxuICAgICAgICAgIGV4dGVybmFsTGlua1RhcmdldCA9IF90aGlzJHByb3BzMi5leHRlcm5hbExpbmtUYXJnZXQ7XG5cbiAgICAgIF90aGlzLmxpbmtTZXJ2aWNlLnNldFZpZXdlcihfdGhpcy52aWV3ZXIpO1xuXG4gICAgICBfdGhpcy5saW5rU2VydmljZS5zZXRFeHRlcm5hbExpbmtSZWwoZXh0ZXJuYWxMaW5rUmVsKTtcblxuICAgICAgX3RoaXMubGlua1NlcnZpY2Uuc2V0RXh0ZXJuYWxMaW5rVGFyZ2V0KGV4dGVybmFsTGlua1RhcmdldCk7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25Tb3VyY2VTdWNjZXNzXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBvblNvdXJjZVN1Y2Nlc3MgPSBfdGhpcy5wcm9wcy5vblNvdXJjZVN1Y2Nlc3M7XG4gICAgICBpZiAob25Tb3VyY2VTdWNjZXNzKSBvblNvdXJjZVN1Y2Nlc3MoKTtcbiAgICB9KTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJvblNvdXJjZUVycm9yXCIsIGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgd2FybmluZyhlcnJvcik7XG4gICAgICB2YXIgb25Tb3VyY2VFcnJvciA9IF90aGlzLnByb3BzLm9uU291cmNlRXJyb3I7XG4gICAgICBpZiAob25Tb3VyY2VFcnJvcikgb25Tb3VyY2VFcnJvcihlcnJvcik7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25Mb2FkU3VjY2Vzc1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgb25Mb2FkU3VjY2VzcyA9IF90aGlzLnByb3BzLm9uTG9hZFN1Y2Nlc3M7XG4gICAgICB2YXIgcGRmID0gX3RoaXMuc3RhdGUucGRmO1xuICAgICAgaWYgKG9uTG9hZFN1Y2Nlc3MpIG9uTG9hZFN1Y2Nlc3MocGRmKTtcbiAgICAgIF90aGlzLnBhZ2VzID0gbmV3IEFycmF5KHBkZi5udW1QYWdlcyk7XG5cbiAgICAgIF90aGlzLmxpbmtTZXJ2aWNlLnNldERvY3VtZW50KHBkZik7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25Mb2FkRXJyb3JcIiwgZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICBfdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHBkZjogZmFsc2VcbiAgICAgIH0pO1xuXG4gICAgICB3YXJuaW5nKGVycm9yKTtcbiAgICAgIHZhciBvbkxvYWRFcnJvciA9IF90aGlzLnByb3BzLm9uTG9hZEVycm9yO1xuICAgICAgaWYgKG9uTG9hZEVycm9yKSBvbkxvYWRFcnJvcihlcnJvcik7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwiZmluZERvY3VtZW50U291cmNlXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICB2YXIgZmlsZSA9IF90aGlzLnByb3BzLmZpbGU7XG5cbiAgICAgICAgaWYgKCFmaWxlKSB7XG4gICAgICAgICAgcmVzb2x2ZShudWxsKTtcbiAgICAgICAgfSAvLyBGaWxlIGlzIGEgc3RyaW5nXG5cblxuICAgICAgICBpZiAodHlwZW9mIGZpbGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgaWYgKGlzRGF0YVVSSShmaWxlKSkge1xuICAgICAgICAgICAgdmFyIGZpbGVCeXRlU3RyaW5nID0gZGF0YVVSSXRvQnl0ZVN0cmluZyhmaWxlKTtcbiAgICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgICBkYXRhOiBmaWxlQnl0ZVN0cmluZ1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZGlzcGxheUNPUlNXYXJuaW5nKCk7XG4gICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICB1cmw6IGZpbGVcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSAvLyBGaWxlIGlzIFBERkRhdGFSYW5nZVRyYW5zcG9ydFxuXG5cbiAgICAgICAgaWYgKGZpbGUgaW5zdGFuY2VvZiBQREZEYXRhUmFuZ2VUcmFuc3BvcnQpIHtcbiAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgIHJhbmdlOiBmaWxlXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gLy8gRmlsZSBpcyBhbiBBcnJheUJ1ZmZlclxuXG5cbiAgICAgICAgaWYgKGlzQXJyYXlCdWZmZXIoZmlsZSkpIHtcbiAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgIGRhdGE6IGZpbGVcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGNhc2VzIGJlbG93IGFyZSBicm93c2VyLW9ubHkuXG4gICAgICAgICAqIElmIHlvdSdyZSBydW5uaW5nIG9uIGEgbm9uLWJyb3dzZXIgZW52aXJvbm1lbnQsIHRoZXNlIGNhc2VzIHdpbGwgYmUgb2Ygbm8gdXNlLlxuICAgICAgICAgKi9cblxuXG4gICAgICAgIGlmIChpc0Jyb3dzZXIpIHtcbiAgICAgICAgICAvLyBGaWxlIGlzIGEgQmxvYlxuICAgICAgICAgIGlmIChpc0Jsb2IoZmlsZSkgfHwgaXNGaWxlKGZpbGUpKSB7XG4gICAgICAgICAgICBsb2FkRnJvbUZpbGUoZmlsZSkudGhlbihmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICBkYXRhOiBkYXRhXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9IC8vIEF0IHRoaXMgcG9pbnQsIGZpbGUgbXVzdCBiZSBhbiBvYmplY3RcblxuXG4gICAgICAgIGludmFyaWFudChfdHlwZW9mKGZpbGUpID09PSAnb2JqZWN0JywgJ0ludmFsaWQgcGFyYW1ldGVyIGluIGZpbGUsIG5lZWQgZWl0aGVyIFVpbnQ4QXJyYXksIHN0cmluZyBvciBhIHBhcmFtZXRlciBvYmplY3QnKTtcbiAgICAgICAgaW52YXJpYW50KGZpbGUudXJsIHx8IGZpbGUuZGF0YSB8fCBmaWxlLnJhbmdlLCAnSW52YWxpZCBwYXJhbWV0ZXIgb2JqZWN0OiBuZWVkIGVpdGhlciAuZGF0YSwgLnJhbmdlIG9yIC51cmwnKTsgLy8gRmlsZSAudXJsIGlzIGEgc3RyaW5nXG5cbiAgICAgICAgaWYgKHR5cGVvZiBmaWxlLnVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBpZiAoaXNEYXRhVVJJKGZpbGUudXJsKSkge1xuICAgICAgICAgICAgdmFyIHVybCA9IGZpbGUudXJsLFxuICAgICAgICAgICAgICAgIG90aGVyUGFyYW1zID0gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzKGZpbGUsIF9leGNsdWRlZCk7XG5cbiAgICAgICAgICAgIHZhciBfZmlsZUJ5dGVTdHJpbmcgPSBkYXRhVVJJdG9CeXRlU3RyaW5nKHVybCk7XG5cbiAgICAgICAgICAgIHJlc29sdmUoX29iamVjdFNwcmVhZCh7XG4gICAgICAgICAgICAgIGRhdGE6IF9maWxlQnl0ZVN0cmluZ1xuICAgICAgICAgICAgfSwgb3RoZXJQYXJhbXMpKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkaXNwbGF5Q09SU1dhcm5pbmcoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlc29sdmUoZmlsZSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJyZWdpc3RlclBhZ2VcIiwgZnVuY3Rpb24gKHBhZ2VJbmRleCwgcmVmKSB7XG4gICAgICBfdGhpcy5wYWdlc1twYWdlSW5kZXhdID0gcmVmO1xuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcInVucmVnaXN0ZXJQYWdlXCIsIGZ1bmN0aW9uIChwYWdlSW5kZXgpIHtcbiAgICAgIGRlbGV0ZSBfdGhpcy5wYWdlc1twYWdlSW5kZXhdO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzKERvY3VtZW50LCBbe1xuICAgIGtleTogXCJjb21wb25lbnREaWRNb3VudFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgIHRoaXMubG9hZERvY3VtZW50KCk7XG4gICAgICB0aGlzLnNldHVwTGlua1NlcnZpY2UoKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY29tcG9uZW50RGlkVXBkYXRlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHMpIHtcbiAgICAgIHZhciBmaWxlID0gdGhpcy5wcm9wcy5maWxlO1xuXG4gICAgICBpZiAoZmlsZSAhPT0gcHJldlByb3BzLmZpbGUpIHtcbiAgICAgICAgdGhpcy5sb2FkRG9jdW1lbnQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY29tcG9uZW50V2lsbFVubW91bnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAvLyBJZiByZW5kZXJpbmcgaXMgaW4gcHJvZ3Jlc3MsIGxldCdzIGNhbmNlbCBpdFxuICAgICAgY2FuY2VsUnVubmluZ1Rhc2sodGhpcy5ydW5uaW5nVGFzayk7IC8vIElmIGxvYWRpbmcgaXMgaW4gcHJvZ3Jlc3MsIGxldCdzIGRlc3Ryb3kgaXRcblxuICAgICAgaWYgKHRoaXMubG9hZGluZ1Rhc2spIHRoaXMubG9hZGluZ1Rhc2suZGVzdHJveSgpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJjaGlsZENvbnRleHRcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHZhciBsaW5rU2VydmljZSA9IHRoaXMubGlua1NlcnZpY2UsXG4gICAgICAgICAgcmVnaXN0ZXJQYWdlID0gdGhpcy5yZWdpc3RlclBhZ2UsXG4gICAgICAgICAgdW5yZWdpc3RlclBhZ2UgPSB0aGlzLnVucmVnaXN0ZXJQYWdlO1xuICAgICAgdmFyIF90aGlzJHByb3BzMyA9IHRoaXMucHJvcHMsXG4gICAgICAgICAgaW1hZ2VSZXNvdXJjZXNQYXRoID0gX3RoaXMkcHJvcHMzLmltYWdlUmVzb3VyY2VzUGF0aCxcbiAgICAgICAgICByZW5kZXJNb2RlID0gX3RoaXMkcHJvcHMzLnJlbmRlck1vZGUsXG4gICAgICAgICAgcm90YXRlID0gX3RoaXMkcHJvcHMzLnJvdGF0ZTtcbiAgICAgIHZhciBwZGYgPSB0aGlzLnN0YXRlLnBkZjtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGltYWdlUmVzb3VyY2VzUGF0aDogaW1hZ2VSZXNvdXJjZXNQYXRoLFxuICAgICAgICBsaW5rU2VydmljZTogbGlua1NlcnZpY2UsXG4gICAgICAgIHBkZjogcGRmLFxuICAgICAgICByZWdpc3RlclBhZ2U6IHJlZ2lzdGVyUGFnZSxcbiAgICAgICAgcmVuZGVyTW9kZTogcmVuZGVyTW9kZSxcbiAgICAgICAgcm90YXRlOiByb3RhdGUsXG4gICAgICAgIHVucmVnaXN0ZXJQYWdlOiB1bnJlZ2lzdGVyUGFnZVxuICAgICAgfTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZXZlbnRQcm9wc1wiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgIHJldHVybiBtYWtlRXZlbnRQcm9wcyh0aGlzLnByb3BzLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBfdGhpczIuc3RhdGUucGRmO1xuICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbGxlZCB3aGVuIGEgZG9jdW1lbnQgc291cmNlIGlzIHJlc29sdmVkIGNvcnJlY3RseVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwicmVuZGVyQ2hpbGRyZW5cIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyQ2hpbGRyZW4oKSB7XG4gICAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLnByb3BzLmNoaWxkcmVuO1xuICAgICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KERvY3VtZW50Q29udGV4dC5Qcm92aWRlciwge1xuICAgICAgICB2YWx1ZTogdGhpcy5jaGlsZENvbnRleHRcbiAgICAgIH0sIGNoaWxkcmVuKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicmVuZGVyQ29udGVudFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXJDb250ZW50KCkge1xuICAgICAgdmFyIGZpbGUgPSB0aGlzLnByb3BzLmZpbGU7XG4gICAgICB2YXIgcGRmID0gdGhpcy5zdGF0ZS5wZGY7XG5cbiAgICAgIGlmICghZmlsZSkge1xuICAgICAgICB2YXIgbm9EYXRhID0gdGhpcy5wcm9wcy5ub0RhdGE7XG4gICAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChNZXNzYWdlLCB7XG4gICAgICAgICAgdHlwZTogXCJuby1kYXRhXCJcbiAgICAgICAgfSwgdHlwZW9mIG5vRGF0YSA9PT0gJ2Z1bmN0aW9uJyA/IG5vRGF0YSgpIDogbm9EYXRhKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHBkZiA9PT0gbnVsbCkge1xuICAgICAgICB2YXIgbG9hZGluZyA9IHRoaXMucHJvcHMubG9hZGluZztcbiAgICAgICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KE1lc3NhZ2UsIHtcbiAgICAgICAgICB0eXBlOiBcImxvYWRpbmdcIlxuICAgICAgICB9LCB0eXBlb2YgbG9hZGluZyA9PT0gJ2Z1bmN0aW9uJyA/IGxvYWRpbmcoKSA6IGxvYWRpbmcpO1xuICAgICAgfVxuXG4gICAgICBpZiAocGRmID09PSBmYWxzZSkge1xuICAgICAgICB2YXIgZXJyb3IgPSB0aGlzLnByb3BzLmVycm9yO1xuICAgICAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoTWVzc2FnZSwge1xuICAgICAgICAgIHR5cGU6IFwiZXJyb3JcIlxuICAgICAgICB9LCB0eXBlb2YgZXJyb3IgPT09ICdmdW5jdGlvbicgPyBlcnJvcigpIDogZXJyb3IpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5yZW5kZXJDaGlsZHJlbigpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgdmFyIF90aGlzJHByb3BzNCA9IHRoaXMucHJvcHMsXG4gICAgICAgICAgY2xhc3NOYW1lID0gX3RoaXMkcHJvcHM0LmNsYXNzTmFtZSxcbiAgICAgICAgICBpbnB1dFJlZiA9IF90aGlzJHByb3BzNC5pbnB1dFJlZjtcbiAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCBfZXh0ZW5kcyh7XG4gICAgICAgIGNsYXNzTmFtZTogbWVyZ2VDbGFzc05hbWVzKCdyZWFjdC1wZGZfX0RvY3VtZW50JywgY2xhc3NOYW1lKSxcbiAgICAgICAgcmVmOiBpbnB1dFJlZlxuICAgICAgfSwgdGhpcy5ldmVudFByb3BzKSwgdGhpcy5yZW5kZXJDb250ZW50KCkpO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBEb2N1bWVudDtcbn0oUHVyZUNvbXBvbmVudCk7XG5cbmV4cG9ydCB7IERvY3VtZW50IGFzIGRlZmF1bHQgfTtcbkRvY3VtZW50LmRlZmF1bHRQcm9wcyA9IHtcbiAgZXJyb3I6ICdGYWlsZWQgdG8gbG9hZCBQREYgZmlsZS4nLFxuICBsb2FkaW5nOiAnTG9hZGluZyBQREbigKYnLFxuICBub0RhdGE6ICdObyBQREYgZmlsZSBzcGVjaWZpZWQuJyxcbiAgb25QYXNzd29yZDogZnVuY3Rpb24gb25QYXNzd29yZChjYWxsYmFjaywgcmVhc29uKSB7XG4gICAgc3dpdGNoIChyZWFzb24pIHtcbiAgICAgIGNhc2UgUGFzc3dvcmRSZXNwb25zZXMuTkVFRF9QQVNTV09SRDpcbiAgICAgICAge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hbGVydFxuICAgICAgICAgIHZhciBwYXNzd29yZCA9IHByb21wdCgnRW50ZXIgdGhlIHBhc3N3b3JkIHRvIG9wZW4gdGhpcyBQREYgZmlsZS4nKTtcbiAgICAgICAgICBjYWxsYmFjayhwYXNzd29yZCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBQYXNzd29yZFJlc3BvbnNlcy5JTkNPUlJFQ1RfUEFTU1dPUkQ6XG4gICAgICAgIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYWxlcnRcbiAgICAgICAgICB2YXIgX3Bhc3N3b3JkID0gcHJvbXB0KCdJbnZhbGlkIHBhc3N3b3JkLiBQbGVhc2UgdHJ5IGFnYWluLicpO1xuXG4gICAgICAgICAgY2FsbGJhY2soX3Bhc3N3b3JkKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBkZWZhdWx0OlxuICAgIH1cbiAgfVxufTtcbnZhciBpc0Z1bmN0aW9uT3JOb2RlID0gUHJvcFR5cGVzLm9uZU9mVHlwZShbUHJvcFR5cGVzLmZ1bmMsIFByb3BUeXBlcy5ub2RlXSk7XG5Eb2N1bWVudC5wcm9wVHlwZXMgPSBfb2JqZWN0U3ByZWFkKF9vYmplY3RTcHJlYWQoe30sIGV2ZW50UHJvcHMpLCB7fSwge1xuICBjaGlsZHJlbjogUHJvcFR5cGVzLm5vZGUsXG4gIGNsYXNzTmFtZTogaXNDbGFzc05hbWUsXG4gIGVycm9yOiBpc0Z1bmN0aW9uT3JOb2RlLFxuICBleHRlcm5hbExpbmtSZWw6IFByb3BUeXBlcy5zdHJpbmcsXG4gIGV4dGVybmFsTGlua1RhcmdldDogUHJvcFR5cGVzLnN0cmluZyxcbiAgZmlsZTogaXNGaWxlUHJvcCxcbiAgaW1hZ2VSZXNvdXJjZXNQYXRoOiBQcm9wVHlwZXMuc3RyaW5nLFxuICBpbnB1dFJlZjogaXNSZWYsXG4gIGxvYWRpbmc6IGlzRnVuY3Rpb25Pck5vZGUsXG4gIG5vRGF0YTogaXNGdW5jdGlvbk9yTm9kZSxcbiAgb25JdGVtQ2xpY2s6IFByb3BUeXBlcy5mdW5jLFxuICBvbkxvYWRFcnJvcjogUHJvcFR5cGVzLmZ1bmMsXG4gIG9uTG9hZFByb2dyZXNzOiBQcm9wVHlwZXMuZnVuYyxcbiAgb25Mb2FkU3VjY2VzczogUHJvcFR5cGVzLmZ1bmMsXG4gIG9uUGFzc3dvcmQ6IFByb3BUeXBlcy5mdW5jLFxuICBvblNvdXJjZUVycm9yOiBQcm9wVHlwZXMuZnVuYyxcbiAgb25Tb3VyY2VTdWNjZXNzOiBQcm9wVHlwZXMuZnVuYyxcbiAgcm90YXRlOiBQcm9wVHlwZXMubnVtYmVyXG59KTsiLCJpbXBvcnQgeyBjcmVhdGVDb250ZXh0IH0gZnJvbSAncmVhY3QnO1xuZXhwb3J0IGRlZmF1bHQgLyojX19QVVJFX18qL2NyZWF0ZUNvbnRleHQobnVsbCk7IiwiaW1wb3J0IF9jbGFzc0NhbGxDaGVjayBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY2xhc3NDYWxsQ2hlY2tcIjtcbmltcG9ydCBfY3JlYXRlQ2xhc3MgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NyZWF0ZUNsYXNzXCI7XG5cbnZhciBSZWYgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBSZWYoX3JlZikge1xuICAgIHZhciBudW0gPSBfcmVmLm51bSxcbiAgICAgICAgZ2VuID0gX3JlZi5nZW47XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgUmVmKTtcblxuICAgIHRoaXMubnVtID0gbnVtO1xuICAgIHRoaXMuZ2VuID0gZ2VuO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzKFJlZiwgW3tcbiAgICBrZXk6IFwidG9TdHJpbmdcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgICB2YXIgc3RyID0gXCJcIi5jb25jYXQodGhpcy5udW0sIFwiUlwiKTtcblxuICAgICAgaWYgKHRoaXMuZ2VuICE9PSAwKSB7XG4gICAgICAgIHN0ciArPSB0aGlzLmdlbjtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gUmVmO1xufSgpO1xuXG5leHBvcnQgeyBSZWYgYXMgZGVmYXVsdCB9OyIsImltcG9ydCBfZXh0ZW5kcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZXh0ZW5kc1wiO1xuaW1wb3J0IF9vYmplY3RXaXRob3V0UHJvcGVydGllcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0V2l0aG91dFByb3BlcnRpZXNcIjtcbmltcG9ydCBfc2xpY2VkVG9BcnJheSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vc2xpY2VkVG9BcnJheVwiO1xuaW1wb3J0IF9jbGFzc0NhbGxDaGVjayBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY2xhc3NDYWxsQ2hlY2tcIjtcbmltcG9ydCBfY3JlYXRlQ2xhc3MgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NyZWF0ZUNsYXNzXCI7XG5pbXBvcnQgX2Fzc2VydFRoaXNJbml0aWFsaXplZCBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vYXNzZXJ0VGhpc0luaXRpYWxpemVkXCI7XG5pbXBvcnQgX2luaGVyaXRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pbmhlcml0c1wiO1xuaW1wb3J0IF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuXCI7XG5pbXBvcnQgX2dldFByb3RvdHlwZU9mIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9nZXRQcm90b3R5cGVPZlwiO1xuaW1wb3J0IF9kZWZpbmVQcm9wZXJ0eSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZGVmaW5lUHJvcGVydHlcIjtcbnZhciBfZXhjbHVkZWQgPSBbXCJpdGVtXCJdO1xuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2YoRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZih0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxuaW1wb3J0IFJlYWN0LCB7IFB1cmVDb21wb25lbnQgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuaW1wb3J0IERvY3VtZW50Q29udGV4dCBmcm9tICcuL0RvY3VtZW50Q29udGV4dCc7XG5pbXBvcnQgT3V0bGluZUNvbnRleHQgZnJvbSAnLi9PdXRsaW5lQ29udGV4dCc7XG5pbXBvcnQgUmVmIGZyb20gJy4vUmVmJztcbmltcG9ydCB7IGlzRGVmaW5lZCB9IGZyb20gJy4vc2hhcmVkL3V0aWxzJztcbmltcG9ydCB7IGlzUGRmIH0gZnJvbSAnLi9zaGFyZWQvcHJvcFR5cGVzJztcbmV4cG9ydCB2YXIgT3V0bGluZUl0ZW1JbnRlcm5hbCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX1B1cmVDb21wb25lbnQpIHtcbiAgX2luaGVyaXRzKE91dGxpbmVJdGVtSW50ZXJuYWwsIF9QdXJlQ29tcG9uZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyKE91dGxpbmVJdGVtSW50ZXJuYWwpO1xuXG4gIGZ1bmN0aW9uIE91dGxpbmVJdGVtSW50ZXJuYWwoKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIE91dGxpbmVJdGVtSW50ZXJuYWwpO1xuXG4gICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICAgIH1cblxuICAgIF90aGlzID0gX3N1cGVyLmNhbGwuYXBwbHkoX3N1cGVyLCBbdGhpc10uY29uY2F0KGFyZ3MpKTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJnZXREZXN0aW5hdGlvblwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICB2YXIgX3RoaXMkcHJvcHMgPSBfdGhpcy5wcm9wcyxcbiAgICAgICAgICAgIGl0ZW0gPSBfdGhpcyRwcm9wcy5pdGVtLFxuICAgICAgICAgICAgcGRmID0gX3RoaXMkcHJvcHMucGRmO1xuXG4gICAgICAgIGlmICghaXNEZWZpbmVkKF90aGlzLmRlc3RpbmF0aW9uKSkge1xuICAgICAgICAgIGlmICh0eXBlb2YgaXRlbS5kZXN0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcGRmLmdldERlc3RpbmF0aW9uKGl0ZW0uZGVzdCkudGhlbihyZXNvbHZlKVtcImNhdGNoXCJdKHJlamVjdCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc29sdmUoaXRlbS5kZXN0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gX3RoaXMuZGVzdGluYXRpb247XG4gICAgICB9KS50aGVuKGZ1bmN0aW9uIChkZXN0aW5hdGlvbikge1xuICAgICAgICBfdGhpcy5kZXN0aW5hdGlvbiA9IGRlc3RpbmF0aW9uO1xuICAgICAgICByZXR1cm4gZGVzdGluYXRpb247XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJnZXRQYWdlSW5kZXhcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgdmFyIHBkZiA9IF90aGlzLnByb3BzLnBkZjtcblxuICAgICAgICBpZiAoaXNEZWZpbmVkKF90aGlzLnBhZ2VJbmRleCkpIHtcbiAgICAgICAgICByZXNvbHZlKF90aGlzLnBhZ2VJbmRleCk7XG4gICAgICAgIH1cblxuICAgICAgICBfdGhpcy5nZXREZXN0aW5hdGlvbigpLnRoZW4oZnVuY3Rpb24gKGRlc3RpbmF0aW9uKSB7XG4gICAgICAgICAgaWYgKCFkZXN0aW5hdGlvbikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBfZGVzdGluYXRpb24gPSBfc2xpY2VkVG9BcnJheShkZXN0aW5hdGlvbiwgMSksXG4gICAgICAgICAgICAgIHJlZiA9IF9kZXN0aW5hdGlvblswXTtcblxuICAgICAgICAgIHBkZi5nZXRQYWdlSW5kZXgobmV3IFJlZihyZWYpKS50aGVuKHJlc29sdmUpW1wiY2F0Y2hcIl0ocmVqZWN0KTtcbiAgICAgICAgfSk7XG4gICAgICB9KS50aGVuKGZ1bmN0aW9uIChwYWdlSW5kZXgpIHtcbiAgICAgICAgX3RoaXMucGFnZUluZGV4ID0gcGFnZUluZGV4O1xuICAgICAgICByZXR1cm4gX3RoaXMucGFnZUluZGV4O1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwiZ2V0UGFnZU51bWJlclwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBpZiAoaXNEZWZpbmVkKF90aGlzLnBhZ2VOdW1iZXIpKSB7XG4gICAgICAgICAgcmVzb2x2ZShfdGhpcy5wYWdlTnVtYmVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIF90aGlzLmdldFBhZ2VJbmRleCgpLnRoZW4oZnVuY3Rpb24gKHBhZ2VJbmRleCkge1xuICAgICAgICAgIHJlc29sdmUocGFnZUluZGV4ICsgMSk7XG4gICAgICAgIH0pW1wiY2F0Y2hcIl0ocmVqZWN0KTtcbiAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKHBhZ2VOdW1iZXIpIHtcbiAgICAgICAgX3RoaXMucGFnZU51bWJlciA9IHBhZ2VOdW1iZXI7XG4gICAgICAgIHJldHVybiBwYWdlTnVtYmVyO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25DbGlja1wiLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgIHZhciBvbkNsaWNrID0gX3RoaXMucHJvcHMub25DbGljaztcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgIGlmICghb25DbGljaykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBQcm9taXNlLmFsbChbX3RoaXMuZ2V0RGVzdGluYXRpb24oKSwgX3RoaXMuZ2V0UGFnZUluZGV4KCksIF90aGlzLmdldFBhZ2VOdW1iZXIoKV0pLnRoZW4oZnVuY3Rpb24gKF9yZWYpIHtcbiAgICAgICAgdmFyIF9yZWYyID0gX3NsaWNlZFRvQXJyYXkoX3JlZiwgMyksXG4gICAgICAgICAgICBkZXN0ID0gX3JlZjJbMF0sXG4gICAgICAgICAgICBwYWdlSW5kZXggPSBfcmVmMlsxXSxcbiAgICAgICAgICAgIHBhZ2VOdW1iZXIgPSBfcmVmMlsyXTtcblxuICAgICAgICBvbkNsaWNrKHtcbiAgICAgICAgICBkZXN0OiBkZXN0LFxuICAgICAgICAgIHBhZ2VJbmRleDogcGFnZUluZGV4LFxuICAgICAgICAgIHBhZ2VOdW1iZXI6IHBhZ2VOdW1iZXJcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIF9jcmVhdGVDbGFzcyhPdXRsaW5lSXRlbUludGVybmFsLCBbe1xuICAgIGtleTogXCJyZW5kZXJTdWJpdGVtc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXJTdWJpdGVtcygpIHtcbiAgICAgIHZhciBfdGhpcyRwcm9wczIgPSB0aGlzLnByb3BzLFxuICAgICAgICAgIGl0ZW0gPSBfdGhpcyRwcm9wczIuaXRlbSxcbiAgICAgICAgICBvdGhlclByb3BzID0gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzKF90aGlzJHByb3BzMiwgX2V4Y2x1ZGVkKTtcblxuICAgICAgaWYgKCFpdGVtLml0ZW1zIHx8ICFpdGVtLml0ZW1zLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgdmFyIHN1Yml0ZW1zID0gaXRlbS5pdGVtcztcbiAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcInVsXCIsIG51bGwsIHN1Yml0ZW1zLm1hcChmdW5jdGlvbiAoc3ViaXRlbSwgc3ViaXRlbUluZGV4KSB7XG4gICAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChPdXRsaW5lSXRlbUludGVybmFsLCBfZXh0ZW5kcyh7XG4gICAgICAgICAga2V5OiB0eXBlb2Ygc3ViaXRlbS5kZXN0aW5hdGlvbiA9PT0gJ3N0cmluZycgPyBzdWJpdGVtLmRlc3RpbmF0aW9uIDogc3ViaXRlbUluZGV4LFxuICAgICAgICAgIGl0ZW06IHN1Yml0ZW1cbiAgICAgICAgfSwgb3RoZXJQcm9wcykpO1xuICAgICAgfSkpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgdmFyIGl0ZW0gPSB0aGlzLnByb3BzLml0ZW07XG4gICAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJsaVwiLCBudWxsLCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImFcIiwge1xuICAgICAgICBocmVmOiBcIiNcIixcbiAgICAgICAgb25DbGljazogdGhpcy5vbkNsaWNrXG4gICAgICB9LCBpdGVtLnRpdGxlKSwgdGhpcy5yZW5kZXJTdWJpdGVtcygpKTtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gT3V0bGluZUl0ZW1JbnRlcm5hbDtcbn0oUHVyZUNvbXBvbmVudCk7XG52YXIgaXNEZXN0aW5hdGlvbiA9IFByb3BUeXBlcy5vbmVPZlR5cGUoW1Byb3BUeXBlcy5zdHJpbmcsIFByb3BUeXBlcy5hcnJheU9mKFByb3BUeXBlcy5hbnkpXSk7XG5PdXRsaW5lSXRlbUludGVybmFsLnByb3BUeXBlcyA9IHtcbiAgaXRlbTogUHJvcFR5cGVzLnNoYXBlKHtcbiAgICBkZXN0OiBpc0Rlc3RpbmF0aW9uLFxuICAgIGl0ZW1zOiBQcm9wVHlwZXMuYXJyYXlPZihQcm9wVHlwZXMuc2hhcGUoe1xuICAgICAgZGVzdDogaXNEZXN0aW5hdGlvbixcbiAgICAgIHRpdGxlOiBQcm9wVHlwZXMuc3RyaW5nXG4gICAgfSkpLFxuICAgIHRpdGxlOiBQcm9wVHlwZXMuc3RyaW5nXG4gIH0pLmlzUmVxdWlyZWQsXG4gIG9uQ2xpY2s6IFByb3BUeXBlcy5mdW5jLFxuICBwZGY6IGlzUGRmLmlzUmVxdWlyZWRcbn07XG5cbnZhciBPdXRsaW5lSXRlbSA9IGZ1bmN0aW9uIE91dGxpbmVJdGVtKHByb3BzKSB7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChEb2N1bWVudENvbnRleHQuQ29uc3VtZXIsIG51bGwsIGZ1bmN0aW9uIChkb2N1bWVudENvbnRleHQpIHtcbiAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoT3V0bGluZUNvbnRleHQuQ29uc3VtZXIsIG51bGwsIGZ1bmN0aW9uIChvdXRsaW5lQ29udGV4dCkge1xuICAgICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KE91dGxpbmVJdGVtSW50ZXJuYWwsIF9leHRlbmRzKHt9LCBkb2N1bWVudENvbnRleHQsIG91dGxpbmVDb250ZXh0LCBwcm9wcykpO1xuICAgIH0pO1xuICB9KTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IE91dGxpbmVJdGVtOyIsImltcG9ydCBfZXh0ZW5kcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZXh0ZW5kc1wiO1xuaW1wb3J0IF9jbGFzc0NhbGxDaGVjayBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY2xhc3NDYWxsQ2hlY2tcIjtcbmltcG9ydCBfY3JlYXRlQ2xhc3MgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NyZWF0ZUNsYXNzXCI7XG5pbXBvcnQgX2Fzc2VydFRoaXNJbml0aWFsaXplZCBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vYXNzZXJ0VGhpc0luaXRpYWxpemVkXCI7XG5pbXBvcnQgX2luaGVyaXRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pbmhlcml0c1wiO1xuaW1wb3J0IF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuXCI7XG5pbXBvcnQgX2dldFByb3RvdHlwZU9mIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9nZXRQcm90b3R5cGVPZlwiO1xuaW1wb3J0IF9kZWZpbmVQcm9wZXJ0eSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZGVmaW5lUHJvcGVydHlcIjtcblxuZnVuY3Rpb24gb3duS2V5cyhvYmplY3QsIGVudW1lcmFibGVPbmx5KSB7IHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqZWN0KTsgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHsgdmFyIHN5bWJvbHMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKG9iamVjdCk7IGVudW1lcmFibGVPbmx5ICYmIChzeW1ib2xzID0gc3ltYm9scy5maWx0ZXIoZnVuY3Rpb24gKHN5bSkgeyByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmplY3QsIHN5bSkuZW51bWVyYWJsZTsgfSkpLCBrZXlzLnB1c2guYXBwbHkoa2V5cywgc3ltYm9scyk7IH0gcmV0dXJuIGtleXM7IH1cblxuZnVuY3Rpb24gX29iamVjdFNwcmVhZCh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IG51bGwgIT0gYXJndW1lbnRzW2ldID8gYXJndW1lbnRzW2ldIDoge307IGkgJSAyID8gb3duS2V5cyhPYmplY3Qoc291cmNlKSwgITApLmZvckVhY2goZnVuY3Rpb24gKGtleSkgeyBfZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHNvdXJjZVtrZXldKTsgfSkgOiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyA/IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoc291cmNlKSkgOiBvd25LZXlzKE9iamVjdChzb3VyY2UpKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHNvdXJjZSwga2V5KSk7IH0pOyB9IHJldHVybiB0YXJnZXQ7IH1cblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KCk7IHJldHVybiBmdW5jdGlvbiBfY3JlYXRlU3VwZXJJbnRlcm5hbCgpIHsgdmFyIFN1cGVyID0gX2dldFByb3RvdHlwZU9mKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2YodGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIHJlc3VsdCk7IH07IH1cblxuZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCgpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbmltcG9ydCBSZWFjdCwgeyBQdXJlQ29tcG9uZW50IH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcbmltcG9ydCBtYWtlQ2FuY2VsbGFibGUgZnJvbSAnbWFrZS1jYW5jZWxsYWJsZS1wcm9taXNlJztcbmltcG9ydCBtYWtlRXZlbnRQcm9wcyBmcm9tICdtYWtlLWV2ZW50LXByb3BzJztcbmltcG9ydCBtZXJnZUNsYXNzTmFtZXMgZnJvbSAnbWVyZ2UtY2xhc3MtbmFtZXMnO1xuaW1wb3J0IGludmFyaWFudCBmcm9tICd0aW55LWludmFyaWFudCc7XG5pbXBvcnQgd2FybmluZyBmcm9tICd0aW55LXdhcm5pbmcnO1xuaW1wb3J0IERvY3VtZW50Q29udGV4dCBmcm9tICcuL0RvY3VtZW50Q29udGV4dCc7XG5pbXBvcnQgT3V0bGluZUNvbnRleHQgZnJvbSAnLi9PdXRsaW5lQ29udGV4dCc7XG5pbXBvcnQgT3V0bGluZUl0ZW0gZnJvbSAnLi9PdXRsaW5lSXRlbSc7XG5pbXBvcnQgeyBjYW5jZWxSdW5uaW5nVGFzayB9IGZyb20gJy4vc2hhcmVkL3V0aWxzJztcbmltcG9ydCB7IGV2ZW50UHJvcHMsIGlzQ2xhc3NOYW1lLCBpc1BkZiwgaXNSZWYgfSBmcm9tICcuL3NoYXJlZC9wcm9wVHlwZXMnO1xuZXhwb3J0IHZhciBPdXRsaW5lSW50ZXJuYWwgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9QdXJlQ29tcG9uZW50KSB7XG4gIF9pbmhlcml0cyhPdXRsaW5lSW50ZXJuYWwsIF9QdXJlQ29tcG9uZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyKE91dGxpbmVJbnRlcm5hbCk7XG5cbiAgZnVuY3Rpb24gT3V0bGluZUludGVybmFsKCkge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBPdXRsaW5lSW50ZXJuYWwpO1xuXG4gICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICAgIH1cblxuICAgIF90aGlzID0gX3N1cGVyLmNhbGwuYXBwbHkoX3N1cGVyLCBbdGhpc10uY29uY2F0KGFyZ3MpKTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJzdGF0ZVwiLCB7XG4gICAgICBvdXRsaW5lOiBudWxsXG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwibG9hZE91dGxpbmVcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIHBkZiA9IF90aGlzLnByb3BzLnBkZjtcblxuICAgICAgX3RoaXMuc2V0U3RhdGUoZnVuY3Rpb24gKHByZXZTdGF0ZSkge1xuICAgICAgICBpZiAoIXByZXZTdGF0ZS5vdXRsaW5lKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIG91dGxpbmU6IG51bGxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuXG4gICAgICB2YXIgY2FuY2VsbGFibGUgPSBtYWtlQ2FuY2VsbGFibGUocGRmLmdldE91dGxpbmUoKSk7XG4gICAgICBfdGhpcy5ydW5uaW5nVGFzayA9IGNhbmNlbGxhYmxlO1xuICAgICAgY2FuY2VsbGFibGUucHJvbWlzZS50aGVuKGZ1bmN0aW9uIChvdXRsaW5lKSB7XG4gICAgICAgIF90aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBvdXRsaW5lOiBvdXRsaW5lXG4gICAgICAgIH0sIF90aGlzLm9uTG9hZFN1Y2Nlc3MpO1xuICAgICAgfSlbXCJjYXRjaFwiXShmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgX3RoaXMub25Mb2FkRXJyb3IoZXJyb3IpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25Mb2FkU3VjY2Vzc1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgb25Mb2FkU3VjY2VzcyA9IF90aGlzLnByb3BzLm9uTG9hZFN1Y2Nlc3M7XG4gICAgICB2YXIgb3V0bGluZSA9IF90aGlzLnN0YXRlLm91dGxpbmU7XG4gICAgICBpZiAob25Mb2FkU3VjY2Vzcykgb25Mb2FkU3VjY2VzcyhvdXRsaW5lKTtcbiAgICB9KTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJvbkxvYWRFcnJvclwiLCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIF90aGlzLnNldFN0YXRlKHtcbiAgICAgICAgb3V0bGluZTogZmFsc2VcbiAgICAgIH0pO1xuXG4gICAgICB3YXJuaW5nKGVycm9yKTtcbiAgICAgIHZhciBvbkxvYWRFcnJvciA9IF90aGlzLnByb3BzLm9uTG9hZEVycm9yO1xuICAgICAgaWYgKG9uTG9hZEVycm9yKSBvbkxvYWRFcnJvcihlcnJvcik7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25JdGVtQ2xpY2tcIiwgZnVuY3Rpb24gKF9yZWYpIHtcbiAgICAgIHZhciBkZXN0ID0gX3JlZi5kZXN0LFxuICAgICAgICAgIHBhZ2VJbmRleCA9IF9yZWYucGFnZUluZGV4LFxuICAgICAgICAgIHBhZ2VOdW1iZXIgPSBfcmVmLnBhZ2VOdW1iZXI7XG4gICAgICB2YXIgb25JdGVtQ2xpY2sgPSBfdGhpcy5wcm9wcy5vbkl0ZW1DbGljaztcblxuICAgICAgaWYgKG9uSXRlbUNsaWNrKSB7XG4gICAgICAgIG9uSXRlbUNsaWNrKHtcbiAgICAgICAgICBkZXN0OiBkZXN0LFxuICAgICAgICAgIHBhZ2VJbmRleDogcGFnZUluZGV4LFxuICAgICAgICAgIHBhZ2VOdW1iZXI6IHBhZ2VOdW1iZXJcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3MoT3V0bGluZUludGVybmFsLCBbe1xuICAgIGtleTogXCJjb21wb25lbnREaWRNb3VudFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgIHZhciBwZGYgPSB0aGlzLnByb3BzLnBkZjtcbiAgICAgIGludmFyaWFudChwZGYsICdBdHRlbXB0ZWQgdG8gbG9hZCBhbiBvdXRsaW5lLCBidXQgbm8gZG9jdW1lbnQgd2FzIHNwZWNpZmllZC4nKTtcbiAgICAgIHRoaXMubG9hZE91dGxpbmUoKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY29tcG9uZW50RGlkVXBkYXRlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHMpIHtcbiAgICAgIHZhciBwZGYgPSB0aGlzLnByb3BzLnBkZjtcblxuICAgICAgaWYgKHByZXZQcm9wcy5wZGYgJiYgcGRmICE9PSBwcmV2UHJvcHMucGRmKSB7XG4gICAgICAgIHRoaXMubG9hZE91dGxpbmUoKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY29tcG9uZW50V2lsbFVubW91bnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICBjYW5jZWxSdW5uaW5nVGFzayh0aGlzLnJ1bm5pbmdUYXNrKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY2hpbGRDb250ZXh0XCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvbkNsaWNrOiB0aGlzLm9uSXRlbUNsaWNrXG4gICAgICB9O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJldmVudFByb3BzXCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgICAgcmV0dXJuIG1ha2VFdmVudFByb3BzKHRoaXMucHJvcHMsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIF90aGlzMi5zdGF0ZS5vdXRsaW5lO1xuICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbGxlZCB3aGVuIGFuIG91dGxpbmUgaXMgcmVhZCBzdWNjZXNzZnVsbHlcbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInJlbmRlck91dGxpbmVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyT3V0bGluZSgpIHtcbiAgICAgIHZhciBvdXRsaW5lID0gdGhpcy5zdGF0ZS5vdXRsaW5lO1xuICAgICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwidWxcIiwgbnVsbCwgb3V0bGluZS5tYXAoZnVuY3Rpb24gKGl0ZW0sIGl0ZW1JbmRleCkge1xuICAgICAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoT3V0bGluZUl0ZW0sIHtcbiAgICAgICAgICBrZXk6IHR5cGVvZiBpdGVtLmRlc3RpbmF0aW9uID09PSAnc3RyaW5nJyA/IGl0ZW0uZGVzdGluYXRpb24gOiBpdGVtSW5kZXgsXG4gICAgICAgICAgaXRlbTogaXRlbVxuICAgICAgICB9KTtcbiAgICAgIH0pKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicmVuZGVyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgIHZhciBwZGYgPSB0aGlzLnByb3BzLnBkZjtcbiAgICAgIHZhciBvdXRsaW5lID0gdGhpcy5zdGF0ZS5vdXRsaW5lO1xuXG4gICAgICBpZiAoIXBkZiB8fCAhb3V0bGluZSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgdmFyIF90aGlzJHByb3BzID0gdGhpcy5wcm9wcyxcbiAgICAgICAgICBjbGFzc05hbWUgPSBfdGhpcyRwcm9wcy5jbGFzc05hbWUsXG4gICAgICAgICAgaW5wdXRSZWYgPSBfdGhpcyRwcm9wcy5pbnB1dFJlZjtcbiAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCBfZXh0ZW5kcyh7XG4gICAgICAgIGNsYXNzTmFtZTogbWVyZ2VDbGFzc05hbWVzKCdyZWFjdC1wZGZfX091dGxpbmUnLCBjbGFzc05hbWUpLFxuICAgICAgICByZWY6IGlucHV0UmVmXG4gICAgICB9LCB0aGlzLmV2ZW50UHJvcHMpLCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChPdXRsaW5lQ29udGV4dC5Qcm92aWRlciwge1xuICAgICAgICB2YWx1ZTogdGhpcy5jaGlsZENvbnRleHRcbiAgICAgIH0sIHRoaXMucmVuZGVyT3V0bGluZSgpKSk7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIE91dGxpbmVJbnRlcm5hbDtcbn0oUHVyZUNvbXBvbmVudCk7XG5PdXRsaW5lSW50ZXJuYWwucHJvcFR5cGVzID0gX29iamVjdFNwcmVhZCh7XG4gIGNsYXNzTmFtZTogaXNDbGFzc05hbWUsXG4gIGlucHV0UmVmOiBpc1JlZixcbiAgb25JdGVtQ2xpY2s6IFByb3BUeXBlcy5mdW5jLFxuICBvbkxvYWRFcnJvcjogUHJvcFR5cGVzLmZ1bmMsXG4gIG9uTG9hZFN1Y2Nlc3M6IFByb3BUeXBlcy5mdW5jLFxuICBwZGY6IGlzUGRmXG59LCBldmVudFByb3BzKTtcblxuZnVuY3Rpb24gT3V0bGluZShwcm9wcywgcmVmKSB7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChEb2N1bWVudENvbnRleHQuQ29uc3VtZXIsIG51bGwsIGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KE91dGxpbmVJbnRlcm5hbCwgX2V4dGVuZHMoe1xuICAgICAgcmVmOiByZWZcbiAgICB9LCBjb250ZXh0LCBwcm9wcykpO1xuICB9KTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoT3V0bGluZSk7IiwiLyoqXG4gKiBBIGZ1bmN0aW9uIHRoYXQgbWVyZ2VzIFJlYWN0IHJlZnMgaW50byBvbmUuXG4gKiBTdXBwb3J0cyBib3RoIGZ1bmN0aW9ucyBhbmQgcmVmIG9iamVjdHMgY3JlYXRlZCB1c2luZyBjcmVhdGVSZWYoKSBhbmQgdXNlUmVmKCkuXG4gKlxuICogVXNhZ2U6XG4gKiBgYGBqc3hcbiAqIDxkaXYgcmVmPXttZXJnZVJlZnMocmVmMSwgcmVmMiwgcmVmMyl9IC8+XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0gey4uLkFycmF5PEZ1bmN0aW9ufG9iamVjdD59IGlucHV0UmVmcyBBcnJheSBvZiByZWZzXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IE1lcmdlZCByZWZzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIG1lcmdlUmVmcygpIHtcbiAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGlucHV0UmVmcyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICBpbnB1dFJlZnNbX2tleV0gPSBhcmd1bWVudHNbX2tleV07XG4gIH1cblxuICB2YXIgZmlsdGVyZWRJbnB1dFJlZnMgPSBpbnB1dFJlZnMuZmlsdGVyKEJvb2xlYW4pO1xuXG4gIGlmIChmaWx0ZXJlZElucHV0UmVmcy5sZW5ndGggPD0gMSkge1xuICAgIHJldHVybiBmaWx0ZXJlZElucHV0UmVmc1swXTtcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiBtZXJnZWRSZWZzKHJlZikge1xuICAgIGZpbHRlcmVkSW5wdXRSZWZzLmZvckVhY2goZnVuY3Rpb24gKGlucHV0UmVmKSB7XG4gICAgICBpZiAodHlwZW9mIGlucHV0UmVmID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGlucHV0UmVmKHJlZik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cbiAgICAgICAgaW5wdXRSZWYuY3VycmVudCA9IHJlZjtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn0iLCJpbXBvcnQgeyBjcmVhdGVDb250ZXh0IH0gZnJvbSAncmVhY3QnO1xuZXhwb3J0IGRlZmF1bHQgLyojX19QVVJFX18qL2NyZWF0ZUNvbnRleHQobnVsbCk7IiwiaW1wb3J0IF9leHRlbmRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9leHRlbmRzXCI7XG5pbXBvcnQgX2NsYXNzQ2FsbENoZWNrIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jbGFzc0NhbGxDaGVja1wiO1xuaW1wb3J0IF9jcmVhdGVDbGFzcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY3JlYXRlQ2xhc3NcIjtcbmltcG9ydCBfYXNzZXJ0VGhpc0luaXRpYWxpemVkIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9hc3NlcnRUaGlzSW5pdGlhbGl6ZWRcIjtcbmltcG9ydCBfaW5oZXJpdHMgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2luaGVyaXRzXCI7XG5pbXBvcnQgX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4gZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5cIjtcbmltcG9ydCBfZ2V0UHJvdG90eXBlT2YgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2dldFByb3RvdHlwZU9mXCI7XG5pbXBvcnQgX2RlZmluZVByb3BlcnR5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9kZWZpbmVQcm9wZXJ0eVwiO1xuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2YoRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZih0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxuaW1wb3J0IFJlYWN0LCB7IGNyZWF0ZVJlZiwgUHVyZUNvbXBvbmVudCB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgbWFrZUNhbmNlbGxhYmxlIGZyb20gJ21ha2UtY2FuY2VsbGFibGUtcHJvbWlzZSc7XG5pbXBvcnQgbWVyZ2VSZWZzIGZyb20gJ21lcmdlLXJlZnMnO1xuaW1wb3J0IHdhcm5pbmcgZnJvbSAndGlueS13YXJuaW5nJztcbmltcG9ydCAqIGFzIHBkZmpzIGZyb20gJ3BkZmpzLWRpc3QvYnVpbGQvcGRmJztcbmltcG9ydCBQYWdlQ29udGV4dCBmcm9tICcuLi9QYWdlQ29udGV4dCc7XG5pbXBvcnQgeyBnZXRQaXhlbFJhdGlvLCBpc0NhbmNlbEV4Y2VwdGlvbiwgbWFrZVBhZ2VDYWxsYmFjayB9IGZyb20gJy4uL3NoYXJlZC91dGlscyc7XG5pbXBvcnQgeyBpc1BhZ2UsIGlzUmVmLCBpc1JvdGF0ZSB9IGZyb20gJy4uL3NoYXJlZC9wcm9wVHlwZXMnO1xudmFyIEFOTk9UQVRJT05fTU9ERSA9IHBkZmpzLkFubm90YXRpb25Nb2RlO1xuZXhwb3J0IHZhciBQYWdlQ2FudmFzSW50ZXJuYWwgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9QdXJlQ29tcG9uZW50KSB7XG4gIF9pbmhlcml0cyhQYWdlQ2FudmFzSW50ZXJuYWwsIF9QdXJlQ29tcG9uZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyKFBhZ2VDYW52YXNJbnRlcm5hbCk7XG5cbiAgZnVuY3Rpb24gUGFnZUNhbnZhc0ludGVybmFsKCkge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBQYWdlQ2FudmFzSW50ZXJuYWwpO1xuXG4gICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICAgIH1cblxuICAgIF90aGlzID0gX3N1cGVyLmNhbGwuYXBwbHkoX3N1cGVyLCBbdGhpc10uY29uY2F0KGFyZ3MpKTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJjYW52YXNFbGVtZW50XCIsIC8qI19fUFVSRV9fKi9jcmVhdGVSZWYoKSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25SZW5kZXJTdWNjZXNzXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgIF90aGlzLnJlbmRlcmVyID0gbnVsbDtcbiAgICAgIHZhciBfdGhpcyRwcm9wcyA9IF90aGlzLnByb3BzLFxuICAgICAgICAgIG9uUmVuZGVyU3VjY2VzcyA9IF90aGlzJHByb3BzLm9uUmVuZGVyU3VjY2VzcyxcbiAgICAgICAgICBwYWdlID0gX3RoaXMkcHJvcHMucGFnZSxcbiAgICAgICAgICBzY2FsZSA9IF90aGlzJHByb3BzLnNjYWxlO1xuICAgICAgaWYgKG9uUmVuZGVyU3VjY2Vzcykgb25SZW5kZXJTdWNjZXNzKG1ha2VQYWdlQ2FsbGJhY2socGFnZSwgc2NhbGUpKTtcbiAgICB9KTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJvblJlbmRlckVycm9yXCIsIGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgaWYgKGlzQ2FuY2VsRXhjZXB0aW9uKGVycm9yKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHdhcm5pbmcoZXJyb3IpO1xuICAgICAgdmFyIG9uUmVuZGVyRXJyb3IgPSBfdGhpcy5wcm9wcy5vblJlbmRlckVycm9yO1xuICAgICAgaWYgKG9uUmVuZGVyRXJyb3IpIG9uUmVuZGVyRXJyb3IoZXJyb3IpO1xuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcImRyYXdQYWdlT25DYW52YXNcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIGNhbnZhcyA9IF90aGlzLmNhbnZhc0VsZW1lbnQuY3VycmVudDtcblxuICAgICAgaWYgKCFjYW52YXMpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIHZhciBfYXNzZXJ0VGhpc0luaXRpYWxpemUgPSBfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSxcbiAgICAgICAgICByZW5kZXJWaWV3cG9ydCA9IF9hc3NlcnRUaGlzSW5pdGlhbGl6ZS5yZW5kZXJWaWV3cG9ydCxcbiAgICAgICAgICB2aWV3cG9ydCA9IF9hc3NlcnRUaGlzSW5pdGlhbGl6ZS52aWV3cG9ydDtcblxuICAgICAgdmFyIF90aGlzJHByb3BzMiA9IF90aGlzLnByb3BzLFxuICAgICAgICAgIGNhbnZhc0JhY2tncm91bmQgPSBfdGhpcyRwcm9wczIuY2FudmFzQmFja2dyb3VuZCxcbiAgICAgICAgICBwYWdlID0gX3RoaXMkcHJvcHMyLnBhZ2UsXG4gICAgICAgICAgcmVuZGVyRm9ybXMgPSBfdGhpcyRwcm9wczIucmVuZGVyRm9ybXM7XG4gICAgICBjYW52YXMud2lkdGggPSByZW5kZXJWaWV3cG9ydC53aWR0aDtcbiAgICAgIGNhbnZhcy5oZWlnaHQgPSByZW5kZXJWaWV3cG9ydC5oZWlnaHQ7XG4gICAgICBjYW52YXMuc3R5bGUud2lkdGggPSBcIlwiLmNvbmNhdChNYXRoLmZsb29yKHZpZXdwb3J0LndpZHRoKSwgXCJweFwiKTtcbiAgICAgIGNhbnZhcy5zdHlsZS5oZWlnaHQgPSBcIlwiLmNvbmNhdChNYXRoLmZsb29yKHZpZXdwb3J0LmhlaWdodCksIFwicHhcIik7XG4gICAgICB2YXIgcmVuZGVyQ29udGV4dCA9IHtcbiAgICAgICAgYW5ub3RhdGlvbk1vZGU6IHJlbmRlckZvcm1zID8gQU5OT1RBVElPTl9NT0RFLkVOQUJMRV9GT1JNUyA6IEFOTk9UQVRJT05fTU9ERS5FTkFCTEUsXG5cbiAgICAgICAgZ2V0IGNhbnZhc0NvbnRleHQoKSB7XG4gICAgICAgICAgcmV0dXJuIGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHZpZXdwb3J0OiByZW5kZXJWaWV3cG9ydFxuICAgICAgfTtcblxuICAgICAgaWYgKGNhbnZhc0JhY2tncm91bmQpIHtcbiAgICAgICAgcmVuZGVyQ29udGV4dC5iYWNrZ3JvdW5kID0gY2FudmFzQmFja2dyb3VuZDtcbiAgICAgIH0gLy8gSWYgYW5vdGhlciByZW5kZXIgaXMgaW4gcHJvZ3Jlc3MsIGxldCdzIGNhbmNlbCBpdFxuXG5cbiAgICAgIF90aGlzLmNhbmNlbFJlbmRlcmluZ1Rhc2soKTtcblxuICAgICAgX3RoaXMucmVuZGVyZXIgPSBtYWtlQ2FuY2VsbGFibGUocGFnZS5yZW5kZXIocmVuZGVyQ29udGV4dCkucHJvbWlzZSk7XG4gICAgICByZXR1cm4gX3RoaXMucmVuZGVyZXIucHJvbWlzZS50aGVuKF90aGlzLm9uUmVuZGVyU3VjY2VzcylbXCJjYXRjaFwiXShfdGhpcy5vblJlbmRlckVycm9yKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIF9jcmVhdGVDbGFzcyhQYWdlQ2FudmFzSW50ZXJuYWwsIFt7XG4gICAga2V5OiBcImNvbXBvbmVudERpZE1vdW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgdGhpcy5kcmF3UGFnZU9uQ2FudmFzKCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNvbXBvbmVudERpZFVwZGF0ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnREaWRVcGRhdGUocHJldlByb3BzKSB7XG4gICAgICB2YXIgX3RoaXMkcHJvcHMzID0gdGhpcy5wcm9wcyxcbiAgICAgICAgICBjYW52YXNCYWNrZ3JvdW5kID0gX3RoaXMkcHJvcHMzLmNhbnZhc0JhY2tncm91bmQsXG4gICAgICAgICAgcGFnZSA9IF90aGlzJHByb3BzMy5wYWdlLFxuICAgICAgICAgIHJlbmRlckZvcm1zID0gX3RoaXMkcHJvcHMzLnJlbmRlckZvcm1zO1xuXG4gICAgICBpZiAoY2FudmFzQmFja2dyb3VuZCAhPT0gcHJldlByb3BzLmNhbnZhc0JhY2tncm91bmQgfHwgcmVuZGVyRm9ybXMgIT09IHByZXZQcm9wcy5yZW5kZXJGb3Jtcykge1xuICAgICAgICAvLyBFbnN1cmVzIHRoZSBjYW52YXMgd2lsbCBiZSByZS1yZW5kZXJlZCBmcm9tIHNjcmF0Y2guIE90aGVyd2lzZSBhbGwgZm9ybSBkYXRhIHdpbGwgc3RheS5cbiAgICAgICAgcGFnZS5jbGVhbnVwKCk7XG4gICAgICAgIHRoaXMuZHJhd1BhZ2VPbkNhbnZhcygpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJjb21wb25lbnRXaWxsVW5tb3VudFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgIHRoaXMuY2FuY2VsUmVuZGVyaW5nVGFzaygpO1xuICAgICAgdmFyIGNhbnZhcyA9IHRoaXMuY2FudmFzRWxlbWVudC5jdXJyZW50O1xuICAgICAgLyoqXG4gICAgICAgKiBaZXJvaW5nIHRoZSB3aWR0aCBhbmQgaGVpZ2h0IGNhdXNlIG1vc3QgYnJvd3NlcnMgdG8gcmVsZWFzZSBncmFwaGljc1xuICAgICAgICogcmVzb3VyY2VzIGltbWVkaWF0ZWx5LCB3aGljaCBjYW4gZ3JlYXRseSByZWR1Y2UgbWVtb3J5IGNvbnN1bXB0aW9uLlxuICAgICAgICovXG5cbiAgICAgIGlmIChjYW52YXMpIHtcbiAgICAgICAgY2FudmFzLndpZHRoID0gMDtcbiAgICAgICAgY2FudmFzLmhlaWdodCA9IDA7XG4gICAgICB9XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNhbmNlbFJlbmRlcmluZ1Rhc2tcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY2FuY2VsUmVuZGVyaW5nVGFzaygpIHtcbiAgICAgIGlmICh0aGlzLnJlbmRlcmVyKSB7XG4gICAgICAgIHRoaXMucmVuZGVyZXIuY2FuY2VsKCk7XG4gICAgICAgIHRoaXMucmVuZGVyZXIgPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYWxsZWQgd2hlbiBhIHBhZ2UgaXMgcmVuZGVyZWQgc3VjY2Vzc2Z1bGx5LlxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwicmVuZGVyVmlld3BvcnRcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHZhciBfdGhpcyRwcm9wczQgPSB0aGlzLnByb3BzLFxuICAgICAgICAgIHBhZ2UgPSBfdGhpcyRwcm9wczQucGFnZSxcbiAgICAgICAgICByb3RhdGUgPSBfdGhpcyRwcm9wczQucm90YXRlLFxuICAgICAgICAgIHNjYWxlID0gX3RoaXMkcHJvcHM0LnNjYWxlO1xuICAgICAgdmFyIHBpeGVsUmF0aW8gPSBnZXRQaXhlbFJhdGlvKCk7XG4gICAgICByZXR1cm4gcGFnZS5nZXRWaWV3cG9ydCh7XG4gICAgICAgIHNjYWxlOiBzY2FsZSAqIHBpeGVsUmF0aW8sXG4gICAgICAgIHJvdGF0aW9uOiByb3RhdGVcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJ2aWV3cG9ydFwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgdmFyIF90aGlzJHByb3BzNSA9IHRoaXMucHJvcHMsXG4gICAgICAgICAgcGFnZSA9IF90aGlzJHByb3BzNS5wYWdlLFxuICAgICAgICAgIHJvdGF0ZSA9IF90aGlzJHByb3BzNS5yb3RhdGUsXG4gICAgICAgICAgc2NhbGUgPSBfdGhpcyRwcm9wczUuc2NhbGU7XG4gICAgICByZXR1cm4gcGFnZS5nZXRWaWV3cG9ydCh7XG4gICAgICAgIHNjYWxlOiBzY2FsZSxcbiAgICAgICAgcm90YXRpb246IHJvdGF0ZVxuICAgICAgfSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInJlbmRlclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICB2YXIgY2FudmFzUmVmID0gdGhpcy5wcm9wcy5jYW52YXNSZWY7XG4gICAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIiwge1xuICAgICAgICBjbGFzc05hbWU6IFwicmVhY3QtcGRmX19QYWdlX19jYW52YXNcIixcbiAgICAgICAgZGlyOiBcImx0clwiLFxuICAgICAgICByZWY6IG1lcmdlUmVmcyhjYW52YXNSZWYsIHRoaXMuY2FudmFzRWxlbWVudCksXG4gICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgZGlzcGxheTogJ2Jsb2NrJyxcbiAgICAgICAgICB1c2VyU2VsZWN0OiAnbm9uZSdcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIFBhZ2VDYW52YXNJbnRlcm5hbDtcbn0oUHVyZUNvbXBvbmVudCk7XG5QYWdlQ2FudmFzSW50ZXJuYWwucHJvcFR5cGVzID0ge1xuICBjYW52YXNCYWNrZ3JvdW5kOiBQcm9wVHlwZXMuc3RyaW5nLFxuICBjYW52YXNSZWY6IGlzUmVmLFxuICBvblJlbmRlckVycm9yOiBQcm9wVHlwZXMuZnVuYyxcbiAgb25SZW5kZXJTdWNjZXNzOiBQcm9wVHlwZXMuZnVuYyxcbiAgcGFnZTogaXNQYWdlLmlzUmVxdWlyZWQsXG4gIHJlbmRlckZvcm1zOiBQcm9wVHlwZXMuYm9vbCxcbiAgcm90YXRlOiBpc1JvdGF0ZSxcbiAgc2NhbGU6IFByb3BUeXBlcy5udW1iZXIuaXNSZXF1aXJlZFxufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFBhZ2VDYW52YXMocHJvcHMpIHtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFBhZ2VDb250ZXh0LkNvbnN1bWVyLCBudWxsLCBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChQYWdlQ2FudmFzSW50ZXJuYWwsIF9leHRlbmRzKHt9LCBjb250ZXh0LCBwcm9wcykpO1xuICB9KTtcbn0iLCJpbXBvcnQgX2V4dGVuZHMgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2V4dGVuZHNcIjtcbmltcG9ydCBfY2xhc3NDYWxsQ2hlY2sgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NsYXNzQ2FsbENoZWNrXCI7XG5pbXBvcnQgX2NyZWF0ZUNsYXNzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jcmVhdGVDbGFzc1wiO1xuaW1wb3J0IF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2Fzc2VydFRoaXNJbml0aWFsaXplZFwiO1xuaW1wb3J0IF9pbmhlcml0cyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vaW5oZXJpdHNcIjtcbmltcG9ydCBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybiBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vcG9zc2libGVDb25zdHJ1Y3RvclJldHVyblwiO1xuaW1wb3J0IF9nZXRQcm90b3R5cGVPZiBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZ2V0UHJvdG90eXBlT2ZcIjtcbmltcG9ydCBfZGVmaW5lUHJvcGVydHkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2RlZmluZVByb3BlcnR5XCI7XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlcihEZXJpdmVkKSB7IHZhciBoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0ID0gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCgpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZihEZXJpdmVkKSwgcmVzdWx0OyBpZiAoaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCkgeyB2YXIgTmV3VGFyZ2V0ID0gX2dldFByb3RvdHlwZU9mKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG5pbXBvcnQgUmVhY3QsIHsgUHVyZUNvbXBvbmVudCB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgd2FybmluZyBmcm9tICd0aW55LXdhcm5pbmcnO1xuaW1wb3J0ICogYXMgcGRmanMgZnJvbSAncGRmanMtZGlzdC9idWlsZC9wZGYnO1xuaW1wb3J0IFBhZ2VDb250ZXh0IGZyb20gJy4uL1BhZ2VDb250ZXh0JztcbmltcG9ydCB7IGlzQ2FuY2VsRXhjZXB0aW9uLCBtYWtlUGFnZUNhbGxiYWNrIH0gZnJvbSAnLi4vc2hhcmVkL3V0aWxzJztcbmltcG9ydCB7IGlzUGFnZSwgaXNSb3RhdGUgfSBmcm9tICcuLi9zaGFyZWQvcHJvcFR5cGVzJztcbmV4cG9ydCB2YXIgUGFnZVNWR0ludGVybmFsID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfUHVyZUNvbXBvbmVudCkge1xuICBfaW5oZXJpdHMoUGFnZVNWR0ludGVybmFsLCBfUHVyZUNvbXBvbmVudCk7XG5cbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlcihQYWdlU1ZHSW50ZXJuYWwpO1xuXG4gIGZ1bmN0aW9uIFBhZ2VTVkdJbnRlcm5hbCgpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgUGFnZVNWR0ludGVybmFsKTtcblxuICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4pLCBfa2V5ID0gMDsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICB9XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsLmFwcGx5KF9zdXBlciwgW3RoaXNdLmNvbmNhdChhcmdzKSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwic3RhdGVcIiwge1xuICAgICAgc3ZnOiBudWxsXG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25SZW5kZXJTdWNjZXNzXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgIF90aGlzLnJlbmRlcmVyID0gbnVsbDtcbiAgICAgIHZhciBfdGhpcyRwcm9wcyA9IF90aGlzLnByb3BzLFxuICAgICAgICAgIG9uUmVuZGVyU3VjY2VzcyA9IF90aGlzJHByb3BzLm9uUmVuZGVyU3VjY2VzcyxcbiAgICAgICAgICBwYWdlID0gX3RoaXMkcHJvcHMucGFnZSxcbiAgICAgICAgICBzY2FsZSA9IF90aGlzJHByb3BzLnNjYWxlO1xuICAgICAgaWYgKG9uUmVuZGVyU3VjY2Vzcykgb25SZW5kZXJTdWNjZXNzKG1ha2VQYWdlQ2FsbGJhY2socGFnZSwgc2NhbGUpKTtcbiAgICB9KTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJvblJlbmRlckVycm9yXCIsIGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgaWYgKGlzQ2FuY2VsRXhjZXB0aW9uKGVycm9yKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHdhcm5pbmcoZXJyb3IpO1xuICAgICAgdmFyIG9uUmVuZGVyRXJyb3IgPSBfdGhpcy5wcm9wcy5vblJlbmRlckVycm9yO1xuICAgICAgaWYgKG9uUmVuZGVyRXJyb3IpIG9uUmVuZGVyRXJyb3IoZXJyb3IpO1xuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcInJlbmRlclNWR1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgcGFnZSA9IF90aGlzLnByb3BzLnBhZ2U7XG4gICAgICBfdGhpcy5yZW5kZXJlciA9IHBhZ2UuZ2V0T3BlcmF0b3JMaXN0KCk7XG4gICAgICByZXR1cm4gX3RoaXMucmVuZGVyZXIudGhlbihmdW5jdGlvbiAob3BlcmF0b3JMaXN0KSB7XG4gICAgICAgIHZhciBzdmdHZnggPSBuZXcgcGRmanMuU1ZHR3JhcGhpY3MocGFnZS5jb21tb25PYmpzLCBwYWdlLm9ianMpO1xuICAgICAgICBfdGhpcy5yZW5kZXJlciA9IHN2Z0dmeC5nZXRTVkcob3BlcmF0b3JMaXN0LCBfdGhpcy52aWV3cG9ydCkudGhlbihmdW5jdGlvbiAoc3ZnKSB7XG4gICAgICAgICAgX3RoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc3ZnOiBzdmdcbiAgICAgICAgICB9LCBfdGhpcy5vblJlbmRlclN1Y2Nlc3MpO1xuICAgICAgICB9KVtcImNhdGNoXCJdKF90aGlzLm9uUmVuZGVyRXJyb3IpO1xuICAgICAgfSlbXCJjYXRjaFwiXShfdGhpcy5vblJlbmRlckVycm9yKTtcbiAgICB9KTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJkcmF3UGFnZU9uQ29udGFpbmVyXCIsIGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICB2YXIgc3ZnID0gX3RoaXMuc3RhdGUuc3ZnO1xuXG4gICAgICBpZiAoIWVsZW1lbnQgfHwgIXN2Zykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9IC8vIEFwcGVuZCBTVkcgZWxlbWVudCB0byB0aGUgbWFpbiBjb250YWluZXIsIGlmIHRoaXMgaGFzbid0IGJlZW4gZG9uZSBhbHJlYWR5XG5cblxuICAgICAgaWYgKCFlbGVtZW50LmZpcnN0RWxlbWVudENoaWxkKSB7XG4gICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoc3ZnKTtcbiAgICAgIH1cblxuICAgICAgdmFyIF90aGlzJHZpZXdwb3J0ID0gX3RoaXMudmlld3BvcnQsXG4gICAgICAgICAgd2lkdGggPSBfdGhpcyR2aWV3cG9ydC53aWR0aCxcbiAgICAgICAgICBoZWlnaHQgPSBfdGhpcyR2aWV3cG9ydC5oZWlnaHQ7XG4gICAgICBzdmcuc2V0QXR0cmlidXRlKCd3aWR0aCcsIHdpZHRoKTtcbiAgICAgIHN2Zy5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIGhlaWdodCk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3MoUGFnZVNWR0ludGVybmFsLCBbe1xuICAgIGtleTogXCJjb21wb25lbnREaWRNb3VudFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgIHRoaXMucmVuZGVyU1ZHKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbGxlZCB3aGVuIGEgcGFnZSBpcyByZW5kZXJlZCBzdWNjZXNzZnVsbHkuXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJ2aWV3cG9ydFwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgdmFyIF90aGlzJHByb3BzMiA9IHRoaXMucHJvcHMsXG4gICAgICAgICAgcGFnZSA9IF90aGlzJHByb3BzMi5wYWdlLFxuICAgICAgICAgIHJvdGF0ZSA9IF90aGlzJHByb3BzMi5yb3RhdGUsXG4gICAgICAgICAgc2NhbGUgPSBfdGhpcyRwcm9wczIuc2NhbGU7XG4gICAgICByZXR1cm4gcGFnZS5nZXRWaWV3cG9ydCh7XG4gICAgICAgIHNjYWxlOiBzY2FsZSxcbiAgICAgICAgcm90YXRpb246IHJvdGF0ZVxuICAgICAgfSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInJlbmRlclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgICAgdmFyIF90aGlzJHZpZXdwb3J0MiA9IHRoaXMudmlld3BvcnQsXG4gICAgICAgICAgd2lkdGggPSBfdGhpcyR2aWV3cG9ydDIud2lkdGgsXG4gICAgICAgICAgaGVpZ2h0ID0gX3RoaXMkdmlld3BvcnQyLmhlaWdodDtcbiAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgICAgIGNsYXNzTmFtZTogXCJyZWFjdC1wZGZfX1BhZ2VfX3N2Z1wiIC8vIE5vdGU6IFRoaXMgY2Fubm90IGJlIHNob3J0ZW5lZCwgYXMgd2UgbmVlZCB0aGlzIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCB3aXRoIGVhY2ggcmVuZGVyLlxuICAgICAgICAsXG4gICAgICAgIHJlZjogZnVuY3Rpb24gcmVmKF9yZWYpIHtcbiAgICAgICAgICByZXR1cm4gX3RoaXMyLmRyYXdQYWdlT25Db250YWluZXIoX3JlZik7XG4gICAgICAgIH0sXG4gICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgZGlzcGxheTogJ2Jsb2NrJyxcbiAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICd3aGl0ZScsXG4gICAgICAgICAgb3ZlcmZsb3c6ICdoaWRkZW4nLFxuICAgICAgICAgIHdpZHRoOiB3aWR0aCxcbiAgICAgICAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICAgICAgICB1c2VyU2VsZWN0OiAnbm9uZSdcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIFBhZ2VTVkdJbnRlcm5hbDtcbn0oUHVyZUNvbXBvbmVudCk7XG5QYWdlU1ZHSW50ZXJuYWwucHJvcFR5cGVzID0ge1xuICBvblJlbmRlckVycm9yOiBQcm9wVHlwZXMuZnVuYyxcbiAgb25SZW5kZXJTdWNjZXNzOiBQcm9wVHlwZXMuZnVuYyxcbiAgcGFnZTogaXNQYWdlLmlzUmVxdWlyZWQsXG4gIHJvdGF0ZTogaXNSb3RhdGUsXG4gIHNjYWxlOiBQcm9wVHlwZXMubnVtYmVyLmlzUmVxdWlyZWRcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBQYWdlU1ZHKHByb3BzKSB7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChQYWdlQ29udGV4dC5Db25zdW1lciwgbnVsbCwgZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoUGFnZVNWR0ludGVybmFsLCBfZXh0ZW5kcyh7fSwgY29udGV4dCwgcHJvcHMpKTtcbiAgfSk7XG59IiwiaW1wb3J0IF9leHRlbmRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9leHRlbmRzXCI7XG5pbXBvcnQgX2NsYXNzQ2FsbENoZWNrIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jbGFzc0NhbGxDaGVja1wiO1xuaW1wb3J0IF9jcmVhdGVDbGFzcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY3JlYXRlQ2xhc3NcIjtcbmltcG9ydCBfYXNzZXJ0VGhpc0luaXRpYWxpemVkIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9hc3NlcnRUaGlzSW5pdGlhbGl6ZWRcIjtcbmltcG9ydCBfaW5oZXJpdHMgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2luaGVyaXRzXCI7XG5pbXBvcnQgX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4gZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5cIjtcbmltcG9ydCBfZ2V0UHJvdG90eXBlT2YgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2dldFByb3RvdHlwZU9mXCI7XG5pbXBvcnQgX2RlZmluZVByb3BlcnR5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9kZWZpbmVQcm9wZXJ0eVwiO1xuXG5mdW5jdGlvbiBvd25LZXlzKG9iamVjdCwgZW51bWVyYWJsZU9ubHkpIHsgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmplY3QpOyBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykgeyB2YXIgc3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMob2JqZWN0KTsgZW51bWVyYWJsZU9ubHkgJiYgKHN5bWJvbHMgPSBzeW1ib2xzLmZpbHRlcihmdW5jdGlvbiAoc3ltKSB7IHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgc3ltKS5lbnVtZXJhYmxlOyB9KSksIGtleXMucHVzaC5hcHBseShrZXlzLCBzeW1ib2xzKTsgfSByZXR1cm4ga2V5czsgfVxuXG5mdW5jdGlvbiBfb2JqZWN0U3ByZWFkKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gbnVsbCAhPSBhcmd1bWVudHNbaV0gPyBhcmd1bWVudHNbaV0gOiB7fTsgaSAlIDIgPyBvd25LZXlzKE9iamVjdChzb3VyY2UpLCAhMCkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7IF9kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgc291cmNlW2tleV0pOyB9KSA6IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzID8gT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhzb3VyY2UpKSA6IG93bktleXMoT2JqZWN0KHNvdXJjZSkpLmZvckVhY2goZnVuY3Rpb24gKGtleSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Ioc291cmNlLCBrZXkpKTsgfSk7IH0gcmV0dXJuIHRhcmdldDsgfVxuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2YoRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZih0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxuaW1wb3J0IFJlYWN0LCB7IGNyZWF0ZVJlZiwgUHVyZUNvbXBvbmVudCB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IHJlbmRlclRvU3RhdGljTWFya3VwIH0gZnJvbSAncmVhY3QtZG9tL3NlcnZlcic7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuaW1wb3J0IG1ha2VDYW5jZWxsYWJsZSBmcm9tICdtYWtlLWNhbmNlbGxhYmxlLXByb21pc2UnO1xuaW1wb3J0IGludmFyaWFudCBmcm9tICd0aW55LWludmFyaWFudCc7XG5pbXBvcnQgd2FybmluZyBmcm9tICd0aW55LXdhcm5pbmcnO1xuaW1wb3J0ICogYXMgcGRmanMgZnJvbSAncGRmanMtZGlzdC9idWlsZC9wZGYnO1xuaW1wb3J0IFBhZ2VDb250ZXh0IGZyb20gJy4uL1BhZ2VDb250ZXh0JztcbmltcG9ydCB7IGNhbmNlbFJ1bm5pbmdUYXNrIH0gZnJvbSAnLi4vc2hhcmVkL3V0aWxzJztcbmltcG9ydCB7IGlzUGFnZSwgaXNSb3RhdGUgfSBmcm9tICcuLi9zaGFyZWQvcHJvcFR5cGVzJztcbmV4cG9ydCB2YXIgVGV4dExheWVySW50ZXJuYWwgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9QdXJlQ29tcG9uZW50KSB7XG4gIF9pbmhlcml0cyhUZXh0TGF5ZXJJbnRlcm5hbCwgX1B1cmVDb21wb25lbnQpO1xuXG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIoVGV4dExheWVySW50ZXJuYWwpO1xuXG4gIGZ1bmN0aW9uIFRleHRMYXllckludGVybmFsKCkge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBUZXh0TGF5ZXJJbnRlcm5hbCk7XG5cbiAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgIGFyZ3NbX2tleV0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgfVxuXG4gICAgX3RoaXMgPSBfc3VwZXIuY2FsbC5hcHBseShfc3VwZXIsIFt0aGlzXS5jb25jYXQoYXJncykpO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcInN0YXRlXCIsIHtcbiAgICAgIHRleHRDb250ZW50OiBudWxsXG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwibGF5ZXJFbGVtZW50XCIsIC8qI19fUFVSRV9fKi9jcmVhdGVSZWYoKSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwibG9hZFRleHRDb250ZW50XCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBwYWdlID0gX3RoaXMucHJvcHMucGFnZTtcbiAgICAgIHZhciBjYW5jZWxsYWJsZSA9IG1ha2VDYW5jZWxsYWJsZShwYWdlLmdldFRleHRDb250ZW50KCkpO1xuICAgICAgX3RoaXMucnVubmluZ1Rhc2sgPSBjYW5jZWxsYWJsZTtcbiAgICAgIGNhbmNlbGxhYmxlLnByb21pc2UudGhlbihmdW5jdGlvbiAodGV4dENvbnRlbnQpIHtcbiAgICAgICAgX3RoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHRleHRDb250ZW50OiB0ZXh0Q29udGVudFxuICAgICAgICB9LCBfdGhpcy5vbkxvYWRTdWNjZXNzKTtcbiAgICAgIH0pW1wiY2F0Y2hcIl0oZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIF90aGlzLm9uTG9hZEVycm9yKGVycm9yKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcIm9uTG9hZFN1Y2Nlc3NcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIG9uR2V0VGV4dFN1Y2Nlc3MgPSBfdGhpcy5wcm9wcy5vbkdldFRleHRTdWNjZXNzO1xuICAgICAgdmFyIHRleHRDb250ZW50ID0gX3RoaXMuc3RhdGUudGV4dENvbnRlbnQ7XG4gICAgICBpZiAob25HZXRUZXh0U3VjY2Vzcykgb25HZXRUZXh0U3VjY2Vzcyh0ZXh0Q29udGVudCk7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25Mb2FkRXJyb3JcIiwgZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICBfdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHRleHRJdGVtczogZmFsc2VcbiAgICAgIH0pO1xuXG4gICAgICB3YXJuaW5nKGVycm9yKTtcbiAgICAgIHZhciBvbkdldFRleHRFcnJvciA9IF90aGlzLnByb3BzLm9uR2V0VGV4dEVycm9yO1xuICAgICAgaWYgKG9uR2V0VGV4dEVycm9yKSBvbkdldFRleHRFcnJvcihlcnJvcik7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25SZW5kZXJTdWNjZXNzXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBvblJlbmRlclRleHRMYXllclN1Y2Nlc3MgPSBfdGhpcy5wcm9wcy5vblJlbmRlclRleHRMYXllclN1Y2Nlc3M7XG4gICAgICBpZiAob25SZW5kZXJUZXh0TGF5ZXJTdWNjZXNzKSBvblJlbmRlclRleHRMYXllclN1Y2Nlc3MoKTtcbiAgICB9KTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJvblJlbmRlckVycm9yXCIsIGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgd2FybmluZyhlcnJvcik7XG4gICAgICB2YXIgb25SZW5kZXJUZXh0TGF5ZXJFcnJvciA9IF90aGlzLnByb3BzLm9uUmVuZGVyVGV4dExheWVyRXJyb3I7XG4gICAgICBpZiAob25SZW5kZXJUZXh0TGF5ZXJFcnJvcikgb25SZW5kZXJUZXh0TGF5ZXJFcnJvcihlcnJvcik7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3MoVGV4dExheWVySW50ZXJuYWwsIFt7XG4gICAga2V5OiBcImNvbXBvbmVudERpZE1vdW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgdmFyIHBhZ2UgPSB0aGlzLnByb3BzLnBhZ2U7XG4gICAgICBpbnZhcmlhbnQocGFnZSwgJ0F0dGVtcHRlZCB0byBsb2FkIHBhZ2UgdGV4dCBjb250ZW50LCBidXQgbm8gcGFnZSB3YXMgc3BlY2lmaWVkLicpO1xuICAgICAgdGhpcy5sb2FkVGV4dENvbnRlbnQoKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY29tcG9uZW50RGlkVXBkYXRlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHMpIHtcbiAgICAgIHZhciBwYWdlID0gdGhpcy5wcm9wcy5wYWdlO1xuXG4gICAgICBpZiAocHJldlByb3BzLnBhZ2UgJiYgcGFnZSAhPT0gcHJldlByb3BzLnBhZ2UpIHtcbiAgICAgICAgdGhpcy5sb2FkVGV4dENvbnRlbnQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY29tcG9uZW50V2lsbFVubW91bnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICBjYW5jZWxSdW5uaW5nVGFzayh0aGlzLnJ1bm5pbmdUYXNrKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwidmlld3BvcnRcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHZhciBfdGhpcyRwcm9wcyA9IHRoaXMucHJvcHMsXG4gICAgICAgICAgcGFnZSA9IF90aGlzJHByb3BzLnBhZ2UsXG4gICAgICAgICAgcm90YXRlID0gX3RoaXMkcHJvcHMucm90YXRlLFxuICAgICAgICAgIHNjYWxlID0gX3RoaXMkcHJvcHMuc2NhbGU7XG4gICAgICByZXR1cm4gcGFnZS5nZXRWaWV3cG9ydCh7XG4gICAgICAgIHNjYWxlOiBzY2FsZSxcbiAgICAgICAgcm90YXRpb246IHJvdGF0ZVxuICAgICAgfSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInVucm90YXRlZFZpZXdwb3J0XCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICB2YXIgX3RoaXMkcHJvcHMyID0gdGhpcy5wcm9wcyxcbiAgICAgICAgICBwYWdlID0gX3RoaXMkcHJvcHMyLnBhZ2UsXG4gICAgICAgICAgc2NhbGUgPSBfdGhpcyRwcm9wczIuc2NhbGU7XG4gICAgICByZXR1cm4gcGFnZS5nZXRWaWV3cG9ydCh7XG4gICAgICAgIHNjYWxlOiBzY2FsZVxuICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0IG1pZ2h0IGhhcHBlbiB0aGF0IHRoZSBwYWdlIGlzIHJvdGF0ZWQgYnkgZGVmYXVsdC4gSW4gc3VjaCBjYXNlcywgd2Ugc2hvdWxkbid0IHJvdGF0ZVxuICAgICAqIHRleHQgY29udGVudC5cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInJvdGF0ZVwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgdmFyIF90aGlzJHByb3BzMyA9IHRoaXMucHJvcHMsXG4gICAgICAgICAgcGFnZSA9IF90aGlzJHByb3BzMy5wYWdlLFxuICAgICAgICAgIHJvdGF0ZSA9IF90aGlzJHByb3BzMy5yb3RhdGU7XG4gICAgICByZXR1cm4gcm90YXRlIC0gcGFnZS5yb3RhdGU7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInJlbmRlclRleHRMYXllclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXJUZXh0TGF5ZXIoKSB7XG4gICAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgICAgdmFyIHRleHRDb250ZW50ID0gdGhpcy5zdGF0ZS50ZXh0Q29udGVudDtcblxuICAgICAgaWYgKCF0ZXh0Q29udGVudCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgdmFyIHZpZXdwb3J0ID0gdGhpcy52aWV3cG9ydDtcbiAgICAgIHZhciBfdGhpcyRwcm9wczQgPSB0aGlzLnByb3BzLFxuICAgICAgICAgIGN1c3RvbVRleHRSZW5kZXJlciA9IF90aGlzJHByb3BzNC5jdXN0b21UZXh0UmVuZGVyZXIsXG4gICAgICAgICAgZW5oYW5jZVRleHRTZWxlY3Rpb24gPSBfdGhpcyRwcm9wczQuZW5oYW5jZVRleHRTZWxlY3Rpb247IC8vIElmIGFub3RoZXIgcmVuZGVyaW5nIGlzIGluIHByb2dyZXNzLCBsZXQncyBjYW5jZWwgaXRcblxuICAgICAgY2FuY2VsUnVubmluZ1Rhc2sodGhpcy5ydW5uaW5nVGFzayk7XG4gICAgICB2YXIgcGFyYW1ldGVycyA9IHtcbiAgICAgICAgY29udGFpbmVyOiB0aGlzLmxheWVyRWxlbWVudC5jdXJyZW50LFxuICAgICAgICBlbmhhbmNlVGV4dFNlbGVjdGlvbjogZW5oYW5jZVRleHRTZWxlY3Rpb24sXG4gICAgICAgIHRleHRDb250ZW50OiB0ZXh0Q29udGVudCxcbiAgICAgICAgdmlld3BvcnQ6IHZpZXdwb3J0XG4gICAgICB9O1xuICAgICAgdGhpcy5sYXllckVsZW1lbnQuY3VycmVudC5pbm5lckhUTUwgPSAnJztcbiAgICAgIHRoaXMucnVubmluZ1Rhc2sgPSBwZGZqcy5yZW5kZXJUZXh0TGF5ZXIocGFyYW1ldGVycyk7XG4gICAgICB2YXIgY2FuY2VsbGFibGUgPSBtYWtlQ2FuY2VsbGFibGUodGhpcy5ydW5uaW5nVGFzay5wcm9taXNlKTtcbiAgICAgIHRoaXMucnVubmluZ1Rhc2sgPSBjYW5jZWxsYWJsZTtcbiAgICAgIGNhbmNlbGxhYmxlLnByb21pc2UudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChjdXN0b21UZXh0UmVuZGVyZXIpIHtcbiAgICAgICAgICBBcnJheS5mcm9tKF90aGlzMi5sYXllckVsZW1lbnQuY3VycmVudC5jaGlsZHJlbikuZm9yRWFjaChmdW5jdGlvbiAoZWxlbWVudCwgZWxlbWVudEluZGV4KSB7XG4gICAgICAgICAgICB2YXIgcmVhY3RDb250ZW50ID0gY3VzdG9tVGV4dFJlbmRlcmVyKF9vYmplY3RTcHJlYWQoe1xuICAgICAgICAgICAgICBpdGVtSW5kZXg6IGVsZW1lbnRJbmRleFxuICAgICAgICAgICAgfSwgdGV4dENvbnRlbnQuaXRlbXNbZWxlbWVudEluZGV4XSkpO1xuICAgICAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSByZW5kZXJUb1N0YXRpY01hcmt1cChyZWFjdENvbnRlbnQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgX3RoaXMyLm9uUmVuZGVyU3VjY2VzcygpO1xuICAgICAgfSlbXCJjYXRjaFwiXShmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgX3RoaXMyLm9uUmVuZGVyRXJyb3IoZXJyb3IpO1xuICAgICAgfSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInJlbmRlclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgICAgICBjbGFzc05hbWU6IFwicmVhY3QtcGRmX19QYWdlX190ZXh0Q29udGVudCB0ZXh0TGF5ZXJcIixcbiAgICAgICAgcmVmOiB0aGlzLmxheWVyRWxlbWVudFxuICAgICAgfSwgdGhpcy5yZW5kZXJUZXh0TGF5ZXIoKSk7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIFRleHRMYXllckludGVybmFsO1xufShQdXJlQ29tcG9uZW50KTtcblRleHRMYXllckludGVybmFsLmRlZmF1bHRQcm9wcyA9IHtcbiAgZW5oYW5jZVRleHRTZWxlY3Rpb246IHRydWVcbn07XG5UZXh0TGF5ZXJJbnRlcm5hbC5wcm9wVHlwZXMgPSB7XG4gIGN1c3RvbVRleHRSZW5kZXJlcjogUHJvcFR5cGVzLmZ1bmMsXG4gIGVuaGFuY2VUZXh0U2VsZWN0aW9uOiBQcm9wVHlwZXMuYm9vbCxcbiAgb25HZXRUZXh0RXJyb3I6IFByb3BUeXBlcy5mdW5jLFxuICBvbkdldFRleHRTdWNjZXNzOiBQcm9wVHlwZXMuZnVuYyxcbiAgb25SZW5kZXJUZXh0TGF5ZXJFcnJvcjogUHJvcFR5cGVzLmZ1bmMsXG4gIG9uUmVuZGVyVGV4dExheWVyU3VjY2VzczogUHJvcFR5cGVzLmZ1bmMsXG4gIHBhZ2U6IGlzUGFnZS5pc1JlcXVpcmVkLFxuICByb3RhdGU6IGlzUm90YXRlLFxuICBzY2FsZTogUHJvcFR5cGVzLm51bWJlclxufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFRleHRMYXllcihwcm9wcykge1xuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoUGFnZUNvbnRleHQuQ29uc3VtZXIsIG51bGwsIGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFRleHRMYXllckludGVybmFsLCBfZXh0ZW5kcyh7fSwgY29udGV4dCwgcHJvcHMpKTtcbiAgfSk7XG59IiwiaW1wb3J0IF9leHRlbmRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9leHRlbmRzXCI7XG5pbXBvcnQgX2NsYXNzQ2FsbENoZWNrIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jbGFzc0NhbGxDaGVja1wiO1xuaW1wb3J0IF9jcmVhdGVDbGFzcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY3JlYXRlQ2xhc3NcIjtcbmltcG9ydCBfYXNzZXJ0VGhpc0luaXRpYWxpemVkIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9hc3NlcnRUaGlzSW5pdGlhbGl6ZWRcIjtcbmltcG9ydCBfaW5oZXJpdHMgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2luaGVyaXRzXCI7XG5pbXBvcnQgX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4gZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5cIjtcbmltcG9ydCBfZ2V0UHJvdG90eXBlT2YgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2dldFByb3RvdHlwZU9mXCI7XG5pbXBvcnQgX2RlZmluZVByb3BlcnR5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9kZWZpbmVQcm9wZXJ0eVwiO1xuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2YoRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZih0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxuaW1wb3J0IFJlYWN0LCB7IGNyZWF0ZVJlZiwgUHVyZUNvbXBvbmVudCB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgbWFrZUNhbmNlbGxhYmxlIGZyb20gJ21ha2UtY2FuY2VsbGFibGUtcHJvbWlzZSc7XG5pbXBvcnQgaW52YXJpYW50IGZyb20gJ3RpbnktaW52YXJpYW50JztcbmltcG9ydCB3YXJuaW5nIGZyb20gJ3Rpbnktd2FybmluZyc7XG5pbXBvcnQgKiBhcyBwZGZqcyBmcm9tICdwZGZqcy1kaXN0L2J1aWxkL3BkZic7XG5pbXBvcnQgRG9jdW1lbnRDb250ZXh0IGZyb20gJy4uL0RvY3VtZW50Q29udGV4dCc7XG5pbXBvcnQgUGFnZUNvbnRleHQgZnJvbSAnLi4vUGFnZUNvbnRleHQnO1xuaW1wb3J0IHsgY2FuY2VsUnVubmluZ1Rhc2sgfSBmcm9tICcuLi9zaGFyZWQvdXRpbHMnO1xuaW1wb3J0IHsgaXNMaW5rU2VydmljZSwgaXNQYWdlLCBpc1JvdGF0ZSB9IGZyb20gJy4uL3NoYXJlZC9wcm9wVHlwZXMnO1xuZXhwb3J0IHZhciBBbm5vdGF0aW9uTGF5ZXJJbnRlcm5hbCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX1B1cmVDb21wb25lbnQpIHtcbiAgX2luaGVyaXRzKEFubm90YXRpb25MYXllckludGVybmFsLCBfUHVyZUNvbXBvbmVudCk7XG5cbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlcihBbm5vdGF0aW9uTGF5ZXJJbnRlcm5hbCk7XG5cbiAgZnVuY3Rpb24gQW5ub3RhdGlvbkxheWVySW50ZXJuYWwoKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEFubm90YXRpb25MYXllckludGVybmFsKTtcblxuICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4pLCBfa2V5ID0gMDsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICB9XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsLmFwcGx5KF9zdXBlciwgW3RoaXNdLmNvbmNhdChhcmdzKSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwic3RhdGVcIiwge1xuICAgICAgYW5ub3RhdGlvbnM6IG51bGxcbiAgICB9KTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJsYXllckVsZW1lbnRcIiwgLyojX19QVVJFX18qL2NyZWF0ZVJlZigpKTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJsb2FkQW5ub3RhdGlvbnNcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIHBhZ2UgPSBfdGhpcy5wcm9wcy5wYWdlO1xuICAgICAgdmFyIGNhbmNlbGxhYmxlID0gbWFrZUNhbmNlbGxhYmxlKHBhZ2UuZ2V0QW5ub3RhdGlvbnMoKSk7XG4gICAgICBfdGhpcy5ydW5uaW5nVGFzayA9IGNhbmNlbGxhYmxlO1xuICAgICAgY2FuY2VsbGFibGUucHJvbWlzZS50aGVuKGZ1bmN0aW9uIChhbm5vdGF0aW9ucykge1xuICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgYW5ub3RhdGlvbnM6IGFubm90YXRpb25zXG4gICAgICAgIH0sIF90aGlzLm9uTG9hZFN1Y2Nlc3MpO1xuICAgICAgfSlbXCJjYXRjaFwiXShmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgX3RoaXMub25Mb2FkRXJyb3IoZXJyb3IpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25Mb2FkU3VjY2Vzc1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgb25HZXRBbm5vdGF0aW9uc1N1Y2Nlc3MgPSBfdGhpcy5wcm9wcy5vbkdldEFubm90YXRpb25zU3VjY2VzcztcbiAgICAgIHZhciBhbm5vdGF0aW9ucyA9IF90aGlzLnN0YXRlLmFubm90YXRpb25zO1xuICAgICAgaWYgKG9uR2V0QW5ub3RhdGlvbnNTdWNjZXNzKSBvbkdldEFubm90YXRpb25zU3VjY2Vzcyhhbm5vdGF0aW9ucyk7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25Mb2FkRXJyb3JcIiwgZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICBfdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGFubm90YXRpb25zOiBmYWxzZVxuICAgICAgfSk7XG5cbiAgICAgIHdhcm5pbmcoZXJyb3IpO1xuICAgICAgdmFyIG9uR2V0QW5ub3RhdGlvbnNFcnJvciA9IF90aGlzLnByb3BzLm9uR2V0QW5ub3RhdGlvbnNFcnJvcjtcbiAgICAgIGlmIChvbkdldEFubm90YXRpb25zRXJyb3IpIG9uR2V0QW5ub3RhdGlvbnNFcnJvcihlcnJvcik7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25SZW5kZXJTdWNjZXNzXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBvblJlbmRlckFubm90YXRpb25MYXllclN1Y2Nlc3MgPSBfdGhpcy5wcm9wcy5vblJlbmRlckFubm90YXRpb25MYXllclN1Y2Nlc3M7XG4gICAgICBpZiAob25SZW5kZXJBbm5vdGF0aW9uTGF5ZXJTdWNjZXNzKSBvblJlbmRlckFubm90YXRpb25MYXllclN1Y2Nlc3MoKTtcbiAgICB9KTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJvblJlbmRlckVycm9yXCIsIGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgd2FybmluZyhlcnJvcik7XG4gICAgICB2YXIgb25SZW5kZXJBbm5vdGF0aW9uTGF5ZXJFcnJvciA9IF90aGlzLnByb3BzLm9uUmVuZGVyQW5ub3RhdGlvbkxheWVyRXJyb3I7XG4gICAgICBpZiAob25SZW5kZXJBbm5vdGF0aW9uTGF5ZXJFcnJvcikgb25SZW5kZXJBbm5vdGF0aW9uTGF5ZXJFcnJvcihlcnJvcik7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3MoQW5ub3RhdGlvbkxheWVySW50ZXJuYWwsIFt7XG4gICAga2V5OiBcImNvbXBvbmVudERpZE1vdW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgdmFyIHBhZ2UgPSB0aGlzLnByb3BzLnBhZ2U7XG4gICAgICBpbnZhcmlhbnQocGFnZSwgJ0F0dGVtcHRlZCB0byBsb2FkIHBhZ2UgYW5ub3RhdGlvbnMsIGJ1dCBubyBwYWdlIHdhcyBzcGVjaWZpZWQuJyk7XG4gICAgICB0aGlzLmxvYWRBbm5vdGF0aW9ucygpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJjb21wb25lbnREaWRVcGRhdGVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wcykge1xuICAgICAgdmFyIF90aGlzJHByb3BzID0gdGhpcy5wcm9wcyxcbiAgICAgICAgICBwYWdlID0gX3RoaXMkcHJvcHMucGFnZSxcbiAgICAgICAgICByZW5kZXJGb3JtcyA9IF90aGlzJHByb3BzLnJlbmRlckZvcm1zO1xuXG4gICAgICBpZiAocHJldlByb3BzLnBhZ2UgJiYgcGFnZSAhPT0gcHJldlByb3BzLnBhZ2UgfHwgcmVuZGVyRm9ybXMgIT09IHByZXZQcm9wcy5yZW5kZXJGb3Jtcykge1xuICAgICAgICB0aGlzLmxvYWRBbm5vdGF0aW9ucygpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJjb21wb25lbnRXaWxsVW5tb3VudFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgIGNhbmNlbFJ1bm5pbmdUYXNrKHRoaXMucnVubmluZ1Rhc2spO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJ2aWV3cG9ydFwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgdmFyIF90aGlzJHByb3BzMiA9IHRoaXMucHJvcHMsXG4gICAgICAgICAgcGFnZSA9IF90aGlzJHByb3BzMi5wYWdlLFxuICAgICAgICAgIHJvdGF0ZSA9IF90aGlzJHByb3BzMi5yb3RhdGUsXG4gICAgICAgICAgc2NhbGUgPSBfdGhpcyRwcm9wczIuc2NhbGU7XG4gICAgICByZXR1cm4gcGFnZS5nZXRWaWV3cG9ydCh7XG4gICAgICAgIHNjYWxlOiBzY2FsZSxcbiAgICAgICAgcm90YXRpb246IHJvdGF0ZVxuICAgICAgfSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInJlbmRlckFubm90YXRpb25MYXllclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXJBbm5vdGF0aW9uTGF5ZXIoKSB7XG4gICAgICB2YXIgYW5ub3RhdGlvbnMgPSB0aGlzLnN0YXRlLmFubm90YXRpb25zO1xuXG4gICAgICBpZiAoIWFubm90YXRpb25zKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIF90aGlzJHByb3BzMyA9IHRoaXMucHJvcHMsXG4gICAgICAgICAgaW1hZ2VSZXNvdXJjZXNQYXRoID0gX3RoaXMkcHJvcHMzLmltYWdlUmVzb3VyY2VzUGF0aCxcbiAgICAgICAgICBsaW5rU2VydmljZSA9IF90aGlzJHByb3BzMy5saW5rU2VydmljZSxcbiAgICAgICAgICBwYWdlID0gX3RoaXMkcHJvcHMzLnBhZ2UsXG4gICAgICAgICAgcmVuZGVyRm9ybXMgPSBfdGhpcyRwcm9wczMucmVuZGVyRm9ybXM7XG4gICAgICB2YXIgdmlld3BvcnQgPSB0aGlzLnZpZXdwb3J0LmNsb25lKHtcbiAgICAgICAgZG9udEZsaXA6IHRydWVcbiAgICAgIH0pO1xuICAgICAgdmFyIHBhcmFtZXRlcnMgPSB7XG4gICAgICAgIGFubm90YXRpb25zOiBhbm5vdGF0aW9ucyxcbiAgICAgICAgZGl2OiB0aGlzLmxheWVyRWxlbWVudC5jdXJyZW50LFxuICAgICAgICBpbWFnZVJlc291cmNlc1BhdGg6IGltYWdlUmVzb3VyY2VzUGF0aCxcbiAgICAgICAgbGlua1NlcnZpY2U6IGxpbmtTZXJ2aWNlLFxuICAgICAgICBwYWdlOiBwYWdlLFxuICAgICAgICByZW5kZXJGb3JtczogcmVuZGVyRm9ybXMsXG4gICAgICAgIHZpZXdwb3J0OiB2aWV3cG9ydFxuICAgICAgfTtcbiAgICAgIHRoaXMubGF5ZXJFbGVtZW50LmN1cnJlbnQuaW5uZXJIVE1MID0gJyc7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHBkZmpzLkFubm90YXRpb25MYXllci5yZW5kZXIocGFyYW1ldGVycyk7XG4gICAgICAgIHRoaXMub25SZW5kZXJTdWNjZXNzKCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICB0aGlzLm9uUmVuZGVyRXJyb3IoZXJyb3IpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICAgICAgY2xhc3NOYW1lOiBcInJlYWN0LXBkZl9fUGFnZV9fYW5ub3RhdGlvbnMgYW5ub3RhdGlvbkxheWVyXCIsXG4gICAgICAgIHJlZjogdGhpcy5sYXllckVsZW1lbnRcbiAgICAgIH0sIHRoaXMucmVuZGVyQW5ub3RhdGlvbkxheWVyKCkpO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBBbm5vdGF0aW9uTGF5ZXJJbnRlcm5hbDtcbn0oUHVyZUNvbXBvbmVudCk7XG5Bbm5vdGF0aW9uTGF5ZXJJbnRlcm5hbC5wcm9wVHlwZXMgPSB7XG4gIGltYWdlUmVzb3VyY2VzUGF0aDogUHJvcFR5cGVzLnN0cmluZyxcbiAgbGlua1NlcnZpY2U6IGlzTGlua1NlcnZpY2UuaXNSZXF1aXJlZCxcbiAgb25HZXRBbm5vdGF0aW9uc0Vycm9yOiBQcm9wVHlwZXMuZnVuYyxcbiAgb25HZXRBbm5vdGF0aW9uc1N1Y2Nlc3M6IFByb3BUeXBlcy5mdW5jLFxuICBvblJlbmRlckFubm90YXRpb25MYXllckVycm9yOiBQcm9wVHlwZXMuZnVuYyxcbiAgb25SZW5kZXJBbm5vdGF0aW9uTGF5ZXJTdWNjZXNzOiBQcm9wVHlwZXMuZnVuYyxcbiAgcGFnZTogaXNQYWdlLFxuICByZW5kZXJGb3JtczogUHJvcFR5cGVzLmJvb2wsXG4gIHJvdGF0ZTogaXNSb3RhdGUsXG4gIHNjYWxlOiBQcm9wVHlwZXMubnVtYmVyXG59O1xuXG52YXIgQW5ub3RhdGlvbkxheWVyID0gZnVuY3Rpb24gQW5ub3RhdGlvbkxheWVyKHByb3BzKSB7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChEb2N1bWVudENvbnRleHQuQ29uc3VtZXIsIG51bGwsIGZ1bmN0aW9uIChkb2N1bWVudENvbnRleHQpIHtcbiAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoUGFnZUNvbnRleHQuQ29uc3VtZXIsIG51bGwsIGZ1bmN0aW9uIChwYWdlQ29udGV4dCkge1xuICAgICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KEFubm90YXRpb25MYXllckludGVybmFsLCBfZXh0ZW5kcyh7fSwgZG9jdW1lbnRDb250ZXh0LCBwYWdlQ29udGV4dCwgcHJvcHMpKTtcbiAgICB9KTtcbiAgfSk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBBbm5vdGF0aW9uTGF5ZXI7IiwiaW1wb3J0IF9leHRlbmRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9leHRlbmRzXCI7XG5pbXBvcnQgX2NsYXNzQ2FsbENoZWNrIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jbGFzc0NhbGxDaGVja1wiO1xuaW1wb3J0IF9jcmVhdGVDbGFzcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY3JlYXRlQ2xhc3NcIjtcbmltcG9ydCBfYXNzZXJ0VGhpc0luaXRpYWxpemVkIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9hc3NlcnRUaGlzSW5pdGlhbGl6ZWRcIjtcbmltcG9ydCBfaW5oZXJpdHMgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2luaGVyaXRzXCI7XG5pbXBvcnQgX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4gZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5cIjtcbmltcG9ydCBfZ2V0UHJvdG90eXBlT2YgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2dldFByb3RvdHlwZU9mXCI7XG5pbXBvcnQgX2RlZmluZVByb3BlcnR5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9kZWZpbmVQcm9wZXJ0eVwiO1xuXG5mdW5jdGlvbiBvd25LZXlzKG9iamVjdCwgZW51bWVyYWJsZU9ubHkpIHsgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmplY3QpOyBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykgeyB2YXIgc3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMob2JqZWN0KTsgZW51bWVyYWJsZU9ubHkgJiYgKHN5bWJvbHMgPSBzeW1ib2xzLmZpbHRlcihmdW5jdGlvbiAoc3ltKSB7IHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgc3ltKS5lbnVtZXJhYmxlOyB9KSksIGtleXMucHVzaC5hcHBseShrZXlzLCBzeW1ib2xzKTsgfSByZXR1cm4ga2V5czsgfVxuXG5mdW5jdGlvbiBfb2JqZWN0U3ByZWFkKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gbnVsbCAhPSBhcmd1bWVudHNbaV0gPyBhcmd1bWVudHNbaV0gOiB7fTsgaSAlIDIgPyBvd25LZXlzKE9iamVjdChzb3VyY2UpLCAhMCkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7IF9kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgc291cmNlW2tleV0pOyB9KSA6IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzID8gT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhzb3VyY2UpKSA6IG93bktleXMoT2JqZWN0KHNvdXJjZSkpLmZvckVhY2goZnVuY3Rpb24gKGtleSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Ioc291cmNlLCBrZXkpKTsgfSk7IH0gcmV0dXJuIHRhcmdldDsgfVxuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2YoRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZih0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxuaW1wb3J0IFJlYWN0LCB7IGNyZWF0ZVJlZiwgUHVyZUNvbXBvbmVudCB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgbWFrZUNhbmNlbGxhYmxlIGZyb20gJ21ha2UtY2FuY2VsbGFibGUtcHJvbWlzZSc7XG5pbXBvcnQgbWFrZUV2ZW50UHJvcHMgZnJvbSAnbWFrZS1ldmVudC1wcm9wcyc7XG5pbXBvcnQgbWVyZ2VDbGFzc05hbWVzIGZyb20gJ21lcmdlLWNsYXNzLW5hbWVzJztcbmltcG9ydCBtZXJnZVJlZnMgZnJvbSAnbWVyZ2UtcmVmcyc7XG5pbXBvcnQgaW52YXJpYW50IGZyb20gJ3RpbnktaW52YXJpYW50JztcbmltcG9ydCB3YXJuaW5nIGZyb20gJ3Rpbnktd2FybmluZyc7XG5pbXBvcnQgRG9jdW1lbnRDb250ZXh0IGZyb20gJy4vRG9jdW1lbnRDb250ZXh0JztcbmltcG9ydCBQYWdlQ29udGV4dCBmcm9tICcuL1BhZ2VDb250ZXh0JztcbmltcG9ydCBNZXNzYWdlIGZyb20gJy4vTWVzc2FnZSc7XG5pbXBvcnQgUGFnZUNhbnZhcyBmcm9tICcuL1BhZ2UvUGFnZUNhbnZhcyc7XG5pbXBvcnQgUGFnZVNWRyBmcm9tICcuL1BhZ2UvUGFnZVNWRyc7XG5pbXBvcnQgVGV4dExheWVyIGZyb20gJy4vUGFnZS9UZXh0TGF5ZXInO1xuaW1wb3J0IEFubm90YXRpb25MYXllciBmcm9tICcuL1BhZ2UvQW5ub3RhdGlvbkxheWVyJztcbmltcG9ydCB7IGNhbmNlbFJ1bm5pbmdUYXNrLCBpc1Byb3ZpZGVkLCBtYWtlUGFnZUNhbGxiYWNrIH0gZnJvbSAnLi9zaGFyZWQvdXRpbHMnO1xuaW1wb3J0IHsgZXZlbnRQcm9wcywgaXNDbGFzc05hbWUsIGlzUGFnZUluZGV4LCBpc1BhZ2VOdW1iZXIsIGlzUGRmLCBpc1JlZiwgaXNSZW5kZXJNb2RlLCBpc1JvdGF0ZSB9IGZyb20gJy4vc2hhcmVkL3Byb3BUeXBlcyc7XG52YXIgZGVmYXVsdFNjYWxlID0gMTtcbmV4cG9ydCB2YXIgUGFnZUludGVybmFsID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfUHVyZUNvbXBvbmVudCkge1xuICBfaW5oZXJpdHMoUGFnZUludGVybmFsLCBfUHVyZUNvbXBvbmVudCk7XG5cbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlcihQYWdlSW50ZXJuYWwpO1xuXG4gIGZ1bmN0aW9uIFBhZ2VJbnRlcm5hbCgpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgUGFnZUludGVybmFsKTtcblxuICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4pLCBfa2V5ID0gMDsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICB9XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsLmFwcGx5KF9zdXBlciwgW3RoaXNdLmNvbmNhdChhcmdzKSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwic3RhdGVcIiwge1xuICAgICAgcGFnZTogbnVsbFxuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcInBhZ2VFbGVtZW50XCIsIC8qI19fUFVSRV9fKi9jcmVhdGVSZWYoKSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25Mb2FkU3VjY2Vzc1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX3RoaXMkcHJvcHMgPSBfdGhpcy5wcm9wcyxcbiAgICAgICAgICBvbkxvYWRTdWNjZXNzID0gX3RoaXMkcHJvcHMub25Mb2FkU3VjY2VzcyxcbiAgICAgICAgICByZWdpc3RlclBhZ2UgPSBfdGhpcyRwcm9wcy5yZWdpc3RlclBhZ2U7XG4gICAgICB2YXIgcGFnZSA9IF90aGlzLnN0YXRlLnBhZ2U7XG4gICAgICBpZiAob25Mb2FkU3VjY2Vzcykgb25Mb2FkU3VjY2VzcyhtYWtlUGFnZUNhbGxiYWNrKHBhZ2UsIF90aGlzLnNjYWxlKSk7XG4gICAgICBpZiAocmVnaXN0ZXJQYWdlKSByZWdpc3RlclBhZ2UoX3RoaXMucGFnZUluZGV4LCBfdGhpcy5wYWdlRWxlbWVudC5jdXJyZW50KTtcbiAgICB9KTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJvbkxvYWRFcnJvclwiLCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIF90aGlzLnNldFN0YXRlKHtcbiAgICAgICAgcGFnZTogZmFsc2VcbiAgICAgIH0pO1xuXG4gICAgICB3YXJuaW5nKGVycm9yKTtcbiAgICAgIHZhciBvbkxvYWRFcnJvciA9IF90aGlzLnByb3BzLm9uTG9hZEVycm9yO1xuICAgICAgaWYgKG9uTG9hZEVycm9yKSBvbkxvYWRFcnJvcihlcnJvcik7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwibG9hZFBhZ2VcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIHBkZiA9IF90aGlzLnByb3BzLnBkZjtcblxuICAgICAgdmFyIHBhZ2VOdW1iZXIgPSBfdGhpcy5nZXRQYWdlTnVtYmVyKCk7XG5cbiAgICAgIGlmICghcGFnZU51bWJlcikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIF90aGlzLnNldFN0YXRlKGZ1bmN0aW9uIChwcmV2U3RhdGUpIHtcbiAgICAgICAgaWYgKCFwcmV2U3RhdGUucGFnZSkge1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBwYWdlOiBudWxsXG4gICAgICAgIH07XG4gICAgICB9KTtcblxuICAgICAgdmFyIGNhbmNlbGxhYmxlID0gbWFrZUNhbmNlbGxhYmxlKHBkZi5nZXRQYWdlKHBhZ2VOdW1iZXIpKTtcbiAgICAgIF90aGlzLnJ1bm5pbmdUYXNrID0gY2FuY2VsbGFibGU7XG4gICAgICBjYW5jZWxsYWJsZS5wcm9taXNlLnRoZW4oZnVuY3Rpb24gKHBhZ2UpIHtcbiAgICAgICAgX3RoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHBhZ2U6IHBhZ2VcbiAgICAgICAgfSwgX3RoaXMub25Mb2FkU3VjY2Vzcyk7XG4gICAgICB9KVtcImNhdGNoXCJdKGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICBfdGhpcy5vbkxvYWRFcnJvcihlcnJvcik7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIF9jcmVhdGVDbGFzcyhQYWdlSW50ZXJuYWwsIFt7XG4gICAga2V5OiBcImNvbXBvbmVudERpZE1vdW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgdmFyIHBkZiA9IHRoaXMucHJvcHMucGRmO1xuICAgICAgaW52YXJpYW50KHBkZiwgJ0F0dGVtcHRlZCB0byBsb2FkIGEgcGFnZSwgYnV0IG5vIGRvY3VtZW50IHdhcyBzcGVjaWZpZWQuJyk7XG4gICAgICB0aGlzLmxvYWRQYWdlKCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNvbXBvbmVudERpZFVwZGF0ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnREaWRVcGRhdGUocHJldlByb3BzKSB7XG4gICAgICB2YXIgcGRmID0gdGhpcy5wcm9wcy5wZGY7XG5cbiAgICAgIGlmIChwcmV2UHJvcHMucGRmICYmIHBkZiAhPT0gcHJldlByb3BzLnBkZiB8fCB0aGlzLmdldFBhZ2VOdW1iZXIoKSAhPT0gdGhpcy5nZXRQYWdlTnVtYmVyKHByZXZQcm9wcykpIHtcbiAgICAgICAgdmFyIHVucmVnaXN0ZXJQYWdlID0gdGhpcy5wcm9wcy51bnJlZ2lzdGVyUGFnZTtcbiAgICAgICAgaWYgKHVucmVnaXN0ZXJQYWdlKSB1bnJlZ2lzdGVyUGFnZSh0aGlzLmdldFBhZ2VJbmRleChwcmV2UHJvcHMpKTtcbiAgICAgICAgdGhpcy5sb2FkUGFnZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJjb21wb25lbnRXaWxsVW5tb3VudFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgIHZhciB1bnJlZ2lzdGVyUGFnZSA9IHRoaXMucHJvcHMudW5yZWdpc3RlclBhZ2U7XG4gICAgICBpZiAodW5yZWdpc3RlclBhZ2UpIHVucmVnaXN0ZXJQYWdlKHRoaXMucGFnZUluZGV4KTtcbiAgICAgIGNhbmNlbFJ1bm5pbmdUYXNrKHRoaXMucnVubmluZ1Rhc2spO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJjaGlsZENvbnRleHRcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHZhciBwYWdlID0gdGhpcy5zdGF0ZS5wYWdlO1xuXG4gICAgICBpZiAoIXBhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgfVxuXG4gICAgICB2YXIgX3RoaXMkcHJvcHMyID0gdGhpcy5wcm9wcyxcbiAgICAgICAgICBjYW52YXNCYWNrZ3JvdW5kID0gX3RoaXMkcHJvcHMyLmNhbnZhc0JhY2tncm91bmQsXG4gICAgICAgICAgY3VzdG9tVGV4dFJlbmRlcmVyID0gX3RoaXMkcHJvcHMyLmN1c3RvbVRleHRSZW5kZXJlcixcbiAgICAgICAgICBlbmhhbmNlVGV4dFNlbGVjdGlvbiA9IF90aGlzJHByb3BzMi5lbmhhbmNlVGV4dFNlbGVjdGlvbixcbiAgICAgICAgICBvbkdldEFubm90YXRpb25zRXJyb3IgPSBfdGhpcyRwcm9wczIub25HZXRBbm5vdGF0aW9uc0Vycm9yLFxuICAgICAgICAgIG9uR2V0QW5ub3RhdGlvbnNTdWNjZXNzID0gX3RoaXMkcHJvcHMyLm9uR2V0QW5ub3RhdGlvbnNTdWNjZXNzLFxuICAgICAgICAgIG9uR2V0VGV4dEVycm9yID0gX3RoaXMkcHJvcHMyLm9uR2V0VGV4dEVycm9yLFxuICAgICAgICAgIG9uR2V0VGV4dFN1Y2Nlc3MgPSBfdGhpcyRwcm9wczIub25HZXRUZXh0U3VjY2VzcyxcbiAgICAgICAgICBvblJlbmRlckFubm90YXRpb25MYXllckVycm9yID0gX3RoaXMkcHJvcHMyLm9uUmVuZGVyQW5ub3RhdGlvbkxheWVyRXJyb3IsXG4gICAgICAgICAgb25SZW5kZXJBbm5vdGF0aW9uTGF5ZXJTdWNjZXNzID0gX3RoaXMkcHJvcHMyLm9uUmVuZGVyQW5ub3RhdGlvbkxheWVyU3VjY2VzcyxcbiAgICAgICAgICBvblJlbmRlckVycm9yID0gX3RoaXMkcHJvcHMyLm9uUmVuZGVyRXJyb3IsXG4gICAgICAgICAgb25SZW5kZXJTdWNjZXNzID0gX3RoaXMkcHJvcHMyLm9uUmVuZGVyU3VjY2VzcyxcbiAgICAgICAgICBvblJlbmRlclRleHRMYXllckVycm9yID0gX3RoaXMkcHJvcHMyLm9uUmVuZGVyVGV4dExheWVyRXJyb3IsXG4gICAgICAgICAgb25SZW5kZXJUZXh0TGF5ZXJTdWNjZXNzID0gX3RoaXMkcHJvcHMyLm9uUmVuZGVyVGV4dExheWVyU3VjY2VzcyxcbiAgICAgICAgICByZW5kZXJGb3JtcyA9IF90aGlzJHByb3BzMi5yZW5kZXJGb3JtcyxcbiAgICAgICAgICByZW5kZXJJbnRlcmFjdGl2ZUZvcm1zID0gX3RoaXMkcHJvcHMyLnJlbmRlckludGVyYWN0aXZlRm9ybXM7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjYW52YXNCYWNrZ3JvdW5kOiBjYW52YXNCYWNrZ3JvdW5kLFxuICAgICAgICBjdXN0b21UZXh0UmVuZGVyZXI6IGN1c3RvbVRleHRSZW5kZXJlcixcbiAgICAgICAgZW5oYW5jZVRleHRTZWxlY3Rpb246IGVuaGFuY2VUZXh0U2VsZWN0aW9uLFxuICAgICAgICBvbkdldEFubm90YXRpb25zRXJyb3I6IG9uR2V0QW5ub3RhdGlvbnNFcnJvcixcbiAgICAgICAgb25HZXRBbm5vdGF0aW9uc1N1Y2Nlc3M6IG9uR2V0QW5ub3RhdGlvbnNTdWNjZXNzLFxuICAgICAgICBvbkdldFRleHRFcnJvcjogb25HZXRUZXh0RXJyb3IsXG4gICAgICAgIG9uR2V0VGV4dFN1Y2Nlc3M6IG9uR2V0VGV4dFN1Y2Nlc3MsXG4gICAgICAgIG9uUmVuZGVyQW5ub3RhdGlvbkxheWVyRXJyb3I6IG9uUmVuZGVyQW5ub3RhdGlvbkxheWVyRXJyb3IsXG4gICAgICAgIG9uUmVuZGVyQW5ub3RhdGlvbkxheWVyU3VjY2Vzczogb25SZW5kZXJBbm5vdGF0aW9uTGF5ZXJTdWNjZXNzLFxuICAgICAgICBvblJlbmRlckVycm9yOiBvblJlbmRlckVycm9yLFxuICAgICAgICBvblJlbmRlclN1Y2Nlc3M6IG9uUmVuZGVyU3VjY2VzcyxcbiAgICAgICAgb25SZW5kZXJUZXh0TGF5ZXJFcnJvcjogb25SZW5kZXJUZXh0TGF5ZXJFcnJvcixcbiAgICAgICAgb25SZW5kZXJUZXh0TGF5ZXJTdWNjZXNzOiBvblJlbmRlclRleHRMYXllclN1Y2Nlc3MsXG4gICAgICAgIHBhZ2U6IHBhZ2UsXG4gICAgICAgIHJlbmRlckZvcm1zOiByZW5kZXJGb3JtcyAhPT0gbnVsbCAmJiByZW5kZXJGb3JtcyAhPT0gdm9pZCAwID8gcmVuZGVyRm9ybXMgOiByZW5kZXJJbnRlcmFjdGl2ZUZvcm1zLFxuICAgICAgICAvLyBGb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eVxuICAgICAgICByb3RhdGU6IHRoaXMucm90YXRlLFxuICAgICAgICBzY2FsZTogdGhpcy5zY2FsZVxuICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FsbGVkIHdoZW4gYSBwYWdlIGlzIGxvYWRlZCBzdWNjZXNzZnVsbHlcbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImdldFBhZ2VJbmRleFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRQYWdlSW5kZXgoKSB7XG4gICAgICB2YXIgcHJvcHMgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHRoaXMucHJvcHM7XG5cbiAgICAgIGlmIChpc1Byb3ZpZGVkKHByb3BzLnBhZ2VOdW1iZXIpKSB7XG4gICAgICAgIHJldHVybiBwcm9wcy5wYWdlTnVtYmVyIC0gMTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzUHJvdmlkZWQocHJvcHMucGFnZUluZGV4KSkge1xuICAgICAgICByZXR1cm4gcHJvcHMucGFnZUluZGV4O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0UGFnZU51bWJlclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRQYWdlTnVtYmVyKCkge1xuICAgICAgdmFyIHByb3BzID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiB0aGlzLnByb3BzO1xuXG4gICAgICBpZiAoaXNQcm92aWRlZChwcm9wcy5wYWdlTnVtYmVyKSkge1xuICAgICAgICByZXR1cm4gcHJvcHMucGFnZU51bWJlcjtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzUHJvdmlkZWQocHJvcHMucGFnZUluZGV4KSkge1xuICAgICAgICByZXR1cm4gcHJvcHMucGFnZUluZGV4ICsgMTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInBhZ2VJbmRleFwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFnZUluZGV4KCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInBhZ2VOdW1iZXJcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldFBhZ2VOdW1iZXIoKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicm90YXRlXCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICB2YXIgcm90YXRlID0gdGhpcy5wcm9wcy5yb3RhdGU7XG5cbiAgICAgIGlmIChpc1Byb3ZpZGVkKHJvdGF0ZSkpIHtcbiAgICAgICAgcmV0dXJuIHJvdGF0ZTtcbiAgICAgIH1cblxuICAgICAgdmFyIHBhZ2UgPSB0aGlzLnN0YXRlLnBhZ2U7XG5cbiAgICAgIGlmICghcGFnZSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHBhZ2Uucm90YXRlO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJzY2FsZVwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgdmFyIHBhZ2UgPSB0aGlzLnN0YXRlLnBhZ2U7XG5cbiAgICAgIGlmICghcGFnZSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgdmFyIF90aGlzJHByb3BzMyA9IHRoaXMucHJvcHMsXG4gICAgICAgICAgc2NhbGUgPSBfdGhpcyRwcm9wczMuc2NhbGUsXG4gICAgICAgICAgd2lkdGggPSBfdGhpcyRwcm9wczMud2lkdGgsXG4gICAgICAgICAgaGVpZ2h0ID0gX3RoaXMkcHJvcHMzLmhlaWdodDtcbiAgICAgIHZhciByb3RhdGUgPSB0aGlzLnJvdGF0ZTsgLy8gQmUgZGVmYXVsdCwgd2UnbGwgcmVuZGVyIHBhZ2UgYXQgMTAwJSAqIHNjYWxlIHdpZHRoLlxuXG4gICAgICB2YXIgcGFnZVNjYWxlID0gMTsgLy8gUGFzc2luZyBzY2FsZSBleHBsaWNpdGx5IG51bGwgd291bGQgY2F1c2UgdGhlIHBhZ2Ugbm90IHRvIHJlbmRlclxuXG4gICAgICB2YXIgc2NhbGVXaXRoRGVmYXVsdCA9IHNjYWxlID09PSBudWxsID8gZGVmYXVsdFNjYWxlIDogc2NhbGU7IC8vIElmIHdpZHRoL2hlaWdodCBpcyBkZWZpbmVkLCBjYWxjdWxhdGUgdGhlIHNjYWxlIG9mIHRoZSBwYWdlIHNvIGl0IGNvdWxkIGJlIG9mIGRlc2lyZWQgd2lkdGguXG5cbiAgICAgIGlmICh3aWR0aCB8fCBoZWlnaHQpIHtcbiAgICAgICAgdmFyIHZpZXdwb3J0ID0gcGFnZS5nZXRWaWV3cG9ydCh7XG4gICAgICAgICAgc2NhbGU6IDEsXG4gICAgICAgICAgcm90YXRpb246IHJvdGF0ZVxuICAgICAgICB9KTtcbiAgICAgICAgcGFnZVNjYWxlID0gd2lkdGggPyB3aWR0aCAvIHZpZXdwb3J0LndpZHRoIDogaGVpZ2h0IC8gdmlld3BvcnQuaGVpZ2h0O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gc2NhbGVXaXRoRGVmYXVsdCAqIHBhZ2VTY2FsZTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZXZlbnRQcm9wc1wiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgIHJldHVybiBtYWtlRXZlbnRQcm9wcyh0aGlzLnByb3BzLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwYWdlID0gX3RoaXMyLnN0YXRlLnBhZ2U7XG5cbiAgICAgICAgaWYgKCFwYWdlKSB7XG4gICAgICAgICAgcmV0dXJuIHBhZ2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbWFrZVBhZ2VDYWxsYmFjayhwYWdlLCBfdGhpczIuc2NhbGUpO1xuICAgICAgfSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInBhZ2VLZXlcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHZhciBwYWdlID0gdGhpcy5zdGF0ZS5wYWdlO1xuICAgICAgcmV0dXJuIFwiXCIuY29uY2F0KHBhZ2UucGFnZUluZGV4LCBcIkBcIikuY29uY2F0KHRoaXMuc2NhbGUsIFwiL1wiKS5jb25jYXQodGhpcy5yb3RhdGUpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJwYWdlS2V5Tm9TY2FsZVwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgdmFyIHBhZ2UgPSB0aGlzLnN0YXRlLnBhZ2U7XG4gICAgICByZXR1cm4gXCJcIi5jb25jYXQocGFnZS5wYWdlSW5kZXgsIFwiL1wiKS5jb25jYXQodGhpcy5yb3RhdGUpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJNYWluTGF5ZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyTWFpbkxheWVyKCkge1xuICAgICAgdmFyIF90aGlzJHByb3BzNCA9IHRoaXMucHJvcHMsXG4gICAgICAgICAgY2FudmFzUmVmID0gX3RoaXMkcHJvcHM0LmNhbnZhc1JlZixcbiAgICAgICAgICByZW5kZXJNb2RlID0gX3RoaXMkcHJvcHM0LnJlbmRlck1vZGU7XG5cbiAgICAgIHN3aXRjaCAocmVuZGVyTW9kZSkge1xuICAgICAgICBjYXNlICdub25lJzpcbiAgICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgICAgICBjYXNlICdzdmcnOlxuICAgICAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChQYWdlU1ZHLCB7XG4gICAgICAgICAgICBrZXk6IFwiXCIuY29uY2F0KHRoaXMucGFnZUtleU5vU2NhbGUsIFwiX3N2Z1wiKVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNhc2UgJ2NhbnZhcyc6XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFBhZ2VDYW52YXMsIHtcbiAgICAgICAgICAgIGtleTogXCJcIi5jb25jYXQodGhpcy5wYWdlS2V5LCBcIl9jYW52YXNcIiksXG4gICAgICAgICAgICBjYW52YXNSZWY6IGNhbnZhc1JlZlxuICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJUZXh0TGF5ZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyVGV4dExheWVyKCkge1xuICAgICAgdmFyIHJlbmRlclRleHRMYXllciA9IHRoaXMucHJvcHMucmVuZGVyVGV4dExheWVyO1xuXG4gICAgICBpZiAoIXJlbmRlclRleHRMYXllcikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFRleHRMYXllciwge1xuICAgICAgICBrZXk6IFwiXCIuY29uY2F0KHRoaXMucGFnZUtleSwgXCJfdGV4dFwiKVxuICAgICAgfSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInJlbmRlckFubm90YXRpb25MYXllclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXJBbm5vdGF0aW9uTGF5ZXIoKSB7XG4gICAgICB2YXIgcmVuZGVyQW5ub3RhdGlvbkxheWVyID0gdGhpcy5wcm9wcy5yZW5kZXJBbm5vdGF0aW9uTGF5ZXI7XG5cbiAgICAgIGlmICghcmVuZGVyQW5ub3RhdGlvbkxheWVyKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgLyoqXG4gICAgICAgKiBBcyBvZiBub3csIFBERi5qcyAyLjAuOTQzIHJldHVybnMgd2FybmluZ3Mgb24gdW5pbXBsZW1lbnRlZCBhbm5vdGF0aW9ucyBpbiBTVkcgbW9kZS5cbiAgICAgICAqIFRoZXJlZm9yZSwgYXMgYSBmYWxsYmFjaywgd2UgcmVuZGVyIFwidHJhZGl0aW9uYWxcIiBBbm5vdGF0aW9uTGF5ZXIgY29tcG9uZW50LlxuICAgICAgICovXG5cblxuICAgICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KEFubm90YXRpb25MYXllciwge1xuICAgICAgICBrZXk6IFwiXCIuY29uY2F0KHRoaXMucGFnZUtleSwgXCJfYW5ub3RhdGlvbnNcIilcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJDaGlsZHJlblwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXJDaGlsZHJlbigpIHtcbiAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMucHJvcHMuY2hpbGRyZW47XG4gICAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoUGFnZUNvbnRleHQuUHJvdmlkZXIsIHtcbiAgICAgICAgdmFsdWU6IHRoaXMuY2hpbGRDb250ZXh0XG4gICAgICB9LCB0aGlzLnJlbmRlck1haW5MYXllcigpLCB0aGlzLnJlbmRlclRleHRMYXllcigpLCB0aGlzLnJlbmRlckFubm90YXRpb25MYXllcigpLCBjaGlsZHJlbik7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInJlbmRlckNvbnRlbnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyQ29udGVudCgpIHtcbiAgICAgIHZhciBwYWdlTnVtYmVyID0gdGhpcy5wYWdlTnVtYmVyO1xuICAgICAgdmFyIHBkZiA9IHRoaXMucHJvcHMucGRmO1xuICAgICAgdmFyIHBhZ2UgPSB0aGlzLnN0YXRlLnBhZ2U7XG5cbiAgICAgIGlmICghcGFnZU51bWJlcikge1xuICAgICAgICB2YXIgbm9EYXRhID0gdGhpcy5wcm9wcy5ub0RhdGE7XG4gICAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChNZXNzYWdlLCB7XG4gICAgICAgICAgdHlwZTogXCJuby1kYXRhXCJcbiAgICAgICAgfSwgdHlwZW9mIG5vRGF0YSA9PT0gJ2Z1bmN0aW9uJyA/IG5vRGF0YSgpIDogbm9EYXRhKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHBkZiA9PT0gbnVsbCB8fCBwYWdlID09PSBudWxsKSB7XG4gICAgICAgIHZhciBsb2FkaW5nID0gdGhpcy5wcm9wcy5sb2FkaW5nO1xuICAgICAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoTWVzc2FnZSwge1xuICAgICAgICAgIHR5cGU6IFwibG9hZGluZ1wiXG4gICAgICAgIH0sIHR5cGVvZiBsb2FkaW5nID09PSAnZnVuY3Rpb24nID8gbG9hZGluZygpIDogbG9hZGluZyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwZGYgPT09IGZhbHNlIHx8IHBhZ2UgPT09IGZhbHNlKSB7XG4gICAgICAgIHZhciBlcnJvciA9IHRoaXMucHJvcHMuZXJyb3I7XG4gICAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChNZXNzYWdlLCB7XG4gICAgICAgICAgdHlwZTogXCJlcnJvclwiXG4gICAgICAgIH0sIHR5cGVvZiBlcnJvciA9PT0gJ2Z1bmN0aW9uJyA/IGVycm9yKCkgOiBlcnJvcik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLnJlbmRlckNoaWxkcmVuKCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInJlbmRlclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICB2YXIgcGFnZU51bWJlciA9IHRoaXMucGFnZU51bWJlcjtcbiAgICAgIHZhciBfdGhpcyRwcm9wczUgPSB0aGlzLnByb3BzLFxuICAgICAgICAgIGNsYXNzTmFtZSA9IF90aGlzJHByb3BzNS5jbGFzc05hbWUsXG4gICAgICAgICAgaW5wdXRSZWYgPSBfdGhpcyRwcm9wczUuaW5wdXRSZWY7XG4gICAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgX2V4dGVuZHMoe1xuICAgICAgICBjbGFzc05hbWU6IG1lcmdlQ2xhc3NOYW1lcygncmVhY3QtcGRmX19QYWdlJywgY2xhc3NOYW1lKSxcbiAgICAgICAgXCJkYXRhLXBhZ2UtbnVtYmVyXCI6IHBhZ2VOdW1iZXIsXG4gICAgICAgIHJlZjogbWVyZ2VSZWZzKGlucHV0UmVmLCB0aGlzLnBhZ2VFbGVtZW50KSxcbiAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICBwb3NpdGlvbjogJ3JlbGF0aXZlJ1xuICAgICAgICB9XG4gICAgICB9LCB0aGlzLmV2ZW50UHJvcHMpLCB0aGlzLnJlbmRlckNvbnRlbnQoKSk7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIFBhZ2VJbnRlcm5hbDtcbn0oUHVyZUNvbXBvbmVudCk7XG5QYWdlSW50ZXJuYWwuZGVmYXVsdFByb3BzID0ge1xuICBlcnJvcjogJ0ZhaWxlZCB0byBsb2FkIHRoZSBwYWdlLicsXG4gIGxvYWRpbmc6ICdMb2FkaW5nIHBhZ2XigKYnLFxuICBub0RhdGE6ICdObyBwYWdlIHNwZWNpZmllZC4nLFxuICByZW5kZXJBbm5vdGF0aW9uTGF5ZXI6IHRydWUsXG4gIHJlbmRlckZvcm1zOiBmYWxzZSxcbiAgcmVuZGVyTW9kZTogJ2NhbnZhcycsXG4gIHJlbmRlclRleHRMYXllcjogdHJ1ZSxcbiAgc2NhbGU6IGRlZmF1bHRTY2FsZVxufTtcbnZhciBpc0Z1bmN0aW9uT3JOb2RlID0gUHJvcFR5cGVzLm9uZU9mVHlwZShbUHJvcFR5cGVzLmZ1bmMsIFByb3BUeXBlcy5ub2RlXSk7XG5QYWdlSW50ZXJuYWwucHJvcFR5cGVzID0gX29iamVjdFNwcmVhZChfb2JqZWN0U3ByZWFkKHt9LCBldmVudFByb3BzKSwge30sIHtcbiAgY2FudmFzQmFja2dyb3VuZDogUHJvcFR5cGVzLnN0cmluZyxcbiAgY2hpbGRyZW46IFByb3BUeXBlcy5ub2RlLFxuICBjbGFzc05hbWU6IGlzQ2xhc3NOYW1lLFxuICBjdXN0b21UZXh0UmVuZGVyZXI6IFByb3BUeXBlcy5mdW5jLFxuICBlbmhhbmNlVGV4dFNlbGVjdGlvbjogUHJvcFR5cGVzLmJvb2wsXG4gIGVycm9yOiBpc0Z1bmN0aW9uT3JOb2RlLFxuICBoZWlnaHQ6IFByb3BUeXBlcy5udW1iZXIsXG4gIGltYWdlUmVzb3VyY2VzUGF0aDogUHJvcFR5cGVzLnN0cmluZyxcbiAgaW5wdXRSZWY6IGlzUmVmLFxuICBsb2FkaW5nOiBpc0Z1bmN0aW9uT3JOb2RlLFxuICBub0RhdGE6IGlzRnVuY3Rpb25Pck5vZGUsXG4gIG9uR2V0VGV4dEVycm9yOiBQcm9wVHlwZXMuZnVuYyxcbiAgb25HZXRUZXh0U3VjY2VzczogUHJvcFR5cGVzLmZ1bmMsXG4gIG9uTG9hZEVycm9yOiBQcm9wVHlwZXMuZnVuYyxcbiAgb25Mb2FkU3VjY2VzczogUHJvcFR5cGVzLmZ1bmMsXG4gIG9uUmVuZGVyRXJyb3I6IFByb3BUeXBlcy5mdW5jLFxuICBvblJlbmRlclN1Y2Nlc3M6IFByb3BUeXBlcy5mdW5jLFxuICBvblJlbmRlclRleHRMYXllckVycm9yOiBQcm9wVHlwZXMuZnVuYyxcbiAgb25SZW5kZXJUZXh0TGF5ZXJTdWNjZXNzOiBQcm9wVHlwZXMuZnVuYyxcbiAgcGFnZUluZGV4OiBpc1BhZ2VJbmRleCxcbiAgcGFnZU51bWJlcjogaXNQYWdlTnVtYmVyLFxuICBwZGY6IGlzUGRmLFxuICByZWdpc3RlclBhZ2U6IFByb3BUeXBlcy5mdW5jLFxuICByZW5kZXJBbm5vdGF0aW9uTGF5ZXI6IFByb3BUeXBlcy5ib29sLFxuICByZW5kZXJGb3JtczogUHJvcFR5cGVzLmJvb2wsXG4gIHJlbmRlckludGVyYWN0aXZlRm9ybXM6IFByb3BUeXBlcy5ib29sLFxuICAvLyBGb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eVxuICByZW5kZXJNb2RlOiBpc1JlbmRlck1vZGUsXG4gIHJlbmRlclRleHRMYXllcjogUHJvcFR5cGVzLmJvb2wsXG4gIHJvdGF0ZTogaXNSb3RhdGUsXG4gIHNjYWxlOiBQcm9wVHlwZXMubnVtYmVyLFxuICB1bnJlZ2lzdGVyUGFnZTogUHJvcFR5cGVzLmZ1bmMsXG4gIHdpZHRoOiBQcm9wVHlwZXMubnVtYmVyXG59KTtcblxuZnVuY3Rpb24gUGFnZShwcm9wcywgcmVmKSB7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChEb2N1bWVudENvbnRleHQuQ29uc3VtZXIsIG51bGwsIGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFBhZ2VJbnRlcm5hbCwgX2V4dGVuZHMoe1xuICAgICAgcmVmOiByZWZcbiAgICB9LCBjb250ZXh0LCBwcm9wcykpO1xuICB9KTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoUGFnZSk7IiwiaW1wb3J0ICogYXMgcGRmanMgZnJvbSAncGRmanMtZGlzdC9idWlsZC9wZGYnO1xuaW1wb3J0IERvY3VtZW50IGZyb20gJy4vRG9jdW1lbnQnO1xuaW1wb3J0IE91dGxpbmUgZnJvbSAnLi9PdXRsaW5lJztcbmltcG9ydCBQYWdlIGZyb20gJy4vUGFnZSc7XG5pbXBvcnQgeyBkaXNwbGF5V29ya2VyV2FybmluZyB9IGZyb20gJy4vc2hhcmVkL3V0aWxzJztcbmRpc3BsYXlXb3JrZXJXYXJuaW5nKCk7XG5wZGZqcy5HbG9iYWxXb3JrZXJPcHRpb25zLndvcmtlclNyYyA9ICdwZGYud29ya2VyLmpzJztcbmV4cG9ydCB7IHBkZmpzLCBEb2N1bWVudCwgT3V0bGluZSwgUGFnZSB9OyIsImltcG9ydCB7IE51bGxhYmxlIH0gZnJvbSAnLi4vY29tcG9uZW50cy90eXBlcy91dGlscyc7XG5cbmV4cG9ydCBlbnVtIFNjcm9sbERpcmVjdGlvbiB7XG4gIFVQID0gJ1VQJyxcbiAgRE9XTiA9ICdET1dOJyxcbn1cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNjcm9sbERldGVjdG9yIHtcbiAgX2xhc3RTY3JvbGxUb3A6IG51bWJlcjtcbiAgX2xhc3RTY3JvbGxEaXJlY3Rpb246IE51bGxhYmxlPFNjcm9sbERpcmVjdGlvbj47XG4gIF9lbDogRWxlbWVudDtcbiAgX3NldFNjcm9sbERpcmVjdGlvbjogKHNjcm9sbERpcmVjdGlvbjogU2Nyb2xsRGlyZWN0aW9uKSA9PiBhbnk7XG4gIF9sYXN0U2Nyb2xsVG9wQmVmb3JlRGlyZWN0aW9uQ2hhbmdlOiBudW1iZXI7XG4gIF9zY3JvbGxUaHJlc2hvbGQ/OiBudW1iZXI7XG4gIF9pc1Njcm9sbFRocmVzaG9sZFJlYWNoZWRJbkRpcmVjdGlvbjogTnVsbGFibGU8U2Nyb2xsRGlyZWN0aW9uPjtcbiAgX3NldFNjcm9sbFRocmVzaG9sZFJlYWNoZWRJbkRpcmVjdGlvbj86IChzY3JvbGxEaXJlY3Rpb246IE51bGxhYmxlPFNjcm9sbERpcmVjdGlvbj4pID0+IGFueTtcbiAgX2lzQXRUb3A6IE51bGxhYmxlPGJvb2xlYW4+O1xuICBfc2V0SXNBdFRvcDogKGlzQXRUb3A6IGJvb2xlYW4pID0+IGFueTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBlbDogRWxlbWVudCxcbiAgICBzZXRTY3JvbGxEaXJlY3Rpb246IChzY3JvbGxEaXJlY3Rpb246IFNjcm9sbERpcmVjdGlvbikgPT4gYW55LFxuICAgIHNldElzQXRUb3A6IChpc0F0VG9wOiBib29sZWFuKSA9PiBhbnksXG4gICAgc2V0U2Nyb2xsVGhyZXNob2xkUmVhY2hlZEluRGlyZWN0aW9uPzogKHNjcm9sbERpcmVjdGlvbjogTnVsbGFibGU8U2Nyb2xsRGlyZWN0aW9uPikgPT4gYW55LFxuICAgIHNjcm9sbFRocmVzaG9sZD86IG51bWJlclxuICApIHtcbiAgICB0aGlzLl9lbCA9IGVsO1xuICAgIHRoaXMuX2xhc3RTY3JvbGxUb3AgPSB0aGlzLl9lbC5zY3JvbGxUb3A7XG4gICAgdGhpcy5fbGFzdFNjcm9sbERpcmVjdGlvbiA9IG51bGw7XG4gICAgdGhpcy5fc2V0U2Nyb2xsRGlyZWN0aW9uID0gc2V0U2Nyb2xsRGlyZWN0aW9uO1xuICAgIHRoaXMuX2lzQXRUb3AgPSBudWxsO1xuICAgIHRoaXMuX3NldElzQXRUb3AgPSBzZXRJc0F0VG9wO1xuICAgIHRoaXMuX2xhc3RTY3JvbGxUb3BCZWZvcmVEaXJlY3Rpb25DaGFuZ2UgPSB0aGlzLl9lbC5zY3JvbGxUb3A7XG4gICAgdGhpcy5fc2Nyb2xsVGhyZXNob2xkID0gc2Nyb2xsVGhyZXNob2xkO1xuXG4gICAgdGhpcy5faXNTY3JvbGxUaHJlc2hvbGRSZWFjaGVkSW5EaXJlY3Rpb24gPSBudWxsO1xuICAgIHRoaXMuX3NldFNjcm9sbFRocmVzaG9sZFJlYWNoZWRJbkRpcmVjdGlvbiA9IHNldFNjcm9sbFRocmVzaG9sZFJlYWNoZWRJbkRpcmVjdGlvbjtcbiAgfVxuXG4gIGF0dGFjaFNjcm9sbExpc3RlbmVyKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9lbD8udGFnTmFtZT8udG9Mb3dlckNhc2UoKSA9PT0gJ2h0bWwnKSB7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5fb25TY3JvbGwsIGZhbHNlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fZWwuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5fb25TY3JvbGwsIGZhbHNlKTtcbiAgfVxuXG4gIGRldGFjaFNjcm9sbExpc3RlbmVyKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9lbD8udGFnTmFtZT8udG9Mb3dlckNhc2UoKSA9PT0gJ2h0bWwnKSB7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5fb25TY3JvbGwsIGZhbHNlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5fb25TY3JvbGwsIGZhbHNlKTtcbiAgfVxuXG4gIF9vblNjcm9sbCA9ICgpOiB2b2lkID0+IHtcbiAgICBjb25zdCBjdXJyU2Nyb2xsVG9wID0gdGhpcy5fZWwuc2Nyb2xsVG9wO1xuICAgIGlmICh0aGlzLl9pc0F0VG9wICE9PSAoY3VyclNjcm9sbFRvcCA9PT0gMCkpIHtcbiAgICAgIHRoaXMuX2lzQXRUb3AgPSBjdXJyU2Nyb2xsVG9wID09PSAwO1xuICAgICAgdGhpcy5fc2V0SXNBdFRvcChjdXJyU2Nyb2xsVG9wID09PSAwKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2xhc3RTY3JvbGxUb3AgPT09IGN1cnJTY3JvbGxUb3ApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBEZXRlcm1pbmUgZGlyZWN0aW9uXG4gICAgY29uc3QgY3VyclNjcm9sbERpcmVjdGlvbiA9ICgoKSA9PiB7XG4gICAgICBpZiAoY3VyclNjcm9sbFRvcCA8PSAwKSB7XG4gICAgICAgIHJldHVybiBTY3JvbGxEaXJlY3Rpb24uRE9XTjtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLl9sYXN0U2Nyb2xsVG9wIDwgY3VyclNjcm9sbFRvcCA/IFNjcm9sbERpcmVjdGlvbi5ET1dOIDogU2Nyb2xsRGlyZWN0aW9uLlVQO1xuICAgIH0pKCk7XG5cbiAgICAvLyBVcGRhdGUgc3RhdGUsIGlmIGNoYW5nZWRcbiAgICB0aGlzLl9sYXN0U2Nyb2xsVG9wID0gY3VyclNjcm9sbFRvcDtcbiAgICBpZiAodGhpcy5fbGFzdFNjcm9sbERpcmVjdGlvbiAhPT0gY3VyclNjcm9sbERpcmVjdGlvbikge1xuICAgICAgdGhpcy5fbGFzdFNjcm9sbERpcmVjdGlvbiA9IGN1cnJTY3JvbGxEaXJlY3Rpb247XG4gICAgICB0aGlzLl9zZXRTY3JvbGxEaXJlY3Rpb24oY3VyclNjcm9sbERpcmVjdGlvbik7XG5cbiAgICAgIHRoaXMuX2xhc3RTY3JvbGxUb3BCZWZvcmVEaXJlY3Rpb25DaGFuZ2UgPSBjdXJyU2Nyb2xsVG9wO1xuICAgICAgdGhpcy5faXNTY3JvbGxUaHJlc2hvbGRSZWFjaGVkSW5EaXJlY3Rpb24gPSBudWxsO1xuICAgICAgaWYgKHRoaXMuX3NldFNjcm9sbFRocmVzaG9sZFJlYWNoZWRJbkRpcmVjdGlvbiAmJiAhdGhpcy5faXNBdFRvcCkge1xuICAgICAgICB0aGlzLl9zZXRTY3JvbGxUaHJlc2hvbGRSZWFjaGVkSW5EaXJlY3Rpb24obnVsbCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLl9zY3JvbGxUaHJlc2hvbGQgJiYgdGhpcy5fc2V0U2Nyb2xsVGhyZXNob2xkUmVhY2hlZEluRGlyZWN0aW9uKSB7XG4gICAgICAgIGNvbnN0IHNjcm9sbGVkQW1vdW50ID0gTWF0aC5hYnModGhpcy5fbGFzdFNjcm9sbFRvcEJlZm9yZURpcmVjdGlvbkNoYW5nZSAtIGN1cnJTY3JvbGxUb3ApO1xuICAgICAgICBpZiAoc2Nyb2xsZWRBbW91bnQgPj0gdGhpcy5fc2Nyb2xsVGhyZXNob2xkKSB7XG4gICAgICAgICAgdGhpcy5faXNTY3JvbGxUaHJlc2hvbGRSZWFjaGVkSW5EaXJlY3Rpb24gPSB0aGlzLl9sYXN0U2Nyb2xsRGlyZWN0aW9uO1xuICAgICAgICAgIHRoaXMuX3NldFNjcm9sbFRocmVzaG9sZFJlYWNoZWRJbkRpcmVjdGlvbih0aGlzLl9sYXN0U2Nyb2xsRGlyZWN0aW9uKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cbiIsImNvbnN0IERFRkFVTFRfUk9PVF9NQVJHSU4gPSAnNTBweCc7XG4vLyBUaGlzIGFycmF5IGlzIGEgcmFuZ2UgZnJvbSAwLjAwMDEgdG8gMSByYW5nZSBvZiB0aHJlc2hvbGQuIEl0IHdpbGwgaGVscCB3aXRoIGRldGVjdGluZ1xuLy8gb24gc2Nyb2xsIHdpdGggYSBiZXR0ZXIgJSBjb21wYXJlIHRvIGEgZml4IHRocmVzaG9sZCBidXQgbm90IGZpcmluZyB0b28gZnJlcXVlbnQgdGhhdFxuLy8gY2FuIGhhbXBlciBvdXIgcGVyZm9ybWFuY2UuXG5jb25zdCBERUZBVUxUX1RIUkVTSE9MRCA9IFswLjAwMDEsIDAuMSwgMC4yLCAwLjMsIDAuNCwgMC41LCAwLjYsIDAuNywgMC44LCAwLjksIDAuOTldO1xuXG5leHBvcnQgdHlwZSBTZXRWaXNpYmxlRW50cmllc0NhbGxiYWNrPFRFbnRyeT4gPSAodmlzaWJsZTogTWFwPFRFbnRyeSwgbnVtYmVyPikgPT4gdm9pZDtcbmV4cG9ydCB0eXBlIG9uVmlzaWJsZUVudHJpZXNDaGFuZ2VDYWxsYmFjazxURW50cnk+ID0gKGFyZ3M6IHtcbiAgdmlzaWJsZUVudHJpZXM6IEludGVyc2VjdGlvbk9ic2VydmVyRW50cnlbXTtcbiAgaGlkZGVuRW50cmllczogSW50ZXJzZWN0aW9uT2JzZXJ2ZXJFbnRyeVtdO1xuICBsYXN0RW50cmllczogTWFwPFRFbnRyeSwgbnVtYmVyPjtcbn0pID0+IE1hcDxURW50cnksIG51bWJlcj47XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFZpc2libGVFbnRyaWVzRGV0ZWN0b3I8VEVudHJ5PiB7XG4gIF9yb290OiBFbGVtZW50O1xuICBfb2JzZXJ2ZXI6IEludGVyc2VjdGlvbk9ic2VydmVyO1xuICBfbGFzdFZpc2libGVFbnRyaWVzOiBNYXA8VEVudHJ5LCBudW1iZXI+O1xuICBfc2V0VmlzaWJsZUVudHJpZXM6IFNldFZpc2libGVFbnRyaWVzQ2FsbGJhY2s8VEVudHJ5PjtcbiAgX29uVmlzaWJsZUVudHJpZXNDaGFuZ2U6IG9uVmlzaWJsZUVudHJpZXNDaGFuZ2VDYWxsYmFjazxURW50cnk+O1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICByb290LFxuICAgIHRocmVzSG9sZCxcbiAgICBzZXRWaXNpYmxlRW50cmllcyxcbiAgICBvblZpc2libGVFbnRyaWVzQ2hhbmdlLFxuICB9OiB7XG4gICAgcm9vdDogRWxlbWVudDtcbiAgICB0aHJlc0hvbGQ/OiBudW1iZXIgfCBBcnJheTxudW1iZXI+O1xuICAgIHNldFZpc2libGVFbnRyaWVzOiBTZXRWaXNpYmxlRW50cmllc0NhbGxiYWNrPFRFbnRyeT47XG4gICAgb25WaXNpYmxlRW50cmllc0NoYW5nZTogb25WaXNpYmxlRW50cmllc0NoYW5nZUNhbGxiYWNrPFRFbnRyeT47XG4gIH0pIHtcbiAgICB0aGlzLl9yb290ID0gcm9vdDtcbiAgICB0aGlzLl9sYXN0VmlzaWJsZUVudHJpZXMgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5fc2V0VmlzaWJsZUVudHJpZXMgPSBzZXRWaXNpYmxlRW50cmllcztcbiAgICB0aGlzLl9vblZpc2libGVFbnRyaWVzQ2hhbmdlID0gb25WaXNpYmxlRW50cmllc0NoYW5nZTtcbiAgICB0aGlzLl9vYnNlcnZlciA9IG5ldyBJbnRlcnNlY3Rpb25PYnNlcnZlcihcbiAgICAgIGVudHJpZXMgPT4ge1xuICAgICAgICAvLyBDb2xsZWN0IHZpc2libGUgYW5kIGhpZGRlbiBlbGVtZW50c1xuICAgICAgICBjb25zdCB2aXNpYmxlRW50cmllcyA9IGVudHJpZXMuZmlsdGVyKGVudHJ5ID0+IGVudHJ5LmlzSW50ZXJzZWN0aW5nKTtcbiAgICAgICAgY29uc3QgaGlkZGVuRW50cmllcyA9IGVudHJpZXMuZmlsdGVyKGVudHJ5ID0+ICFlbnRyeS5pc0ludGVyc2VjdGluZyk7XG5cbiAgICAgICAgLy8gRGV0ZXJtaW5lIHdoYXQgbmVlZHMgc2F2ZWRcbiAgICAgICAgY29uc3QgbmV3VmlzaWJsZUVudHJpZXMgPSB0aGlzLl9vblZpc2libGVFbnRyaWVzQ2hhbmdlKHtcbiAgICAgICAgICB2aXNpYmxlRW50cmllcyxcbiAgICAgICAgICBoaWRkZW5FbnRyaWVzLFxuICAgICAgICAgIGxhc3RFbnRyaWVzOiB0aGlzLl9sYXN0VmlzaWJsZUVudHJpZXMsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGZyb3plbkVudHJpZXMgPSBuZXcgTWFwKG5ld1Zpc2libGVFbnRyaWVzKTtcbiAgICAgICAgT2JqZWN0LmZyZWV6ZShmcm96ZW5FbnRyaWVzKTtcbiAgICAgICAgdGhpcy5fbGFzdFZpc2libGVFbnRyaWVzID0gZnJvemVuRW50cmllcztcbiAgICAgICAgdGhpcy5fc2V0VmlzaWJsZUVudHJpZXMoZnJvemVuRW50cmllcyk7XG4gICAgICB9LFxuXG4gICAgICAvLyBEZWZhdWx0IHNldHRpbmcgZm9yIGludGVyc2VjdGlvbiBvYnNlcnZlclxuICAgICAge1xuICAgICAgICByb290OiB0aGlzLl9yb290LnRhZ05hbWU/LnRvTG93ZXJDYXNlKCkgPT09ICdodG1sJyA/IG51bGwgOiB0aGlzLl9yb290LFxuICAgICAgICByb290TWFyZ2luOiBERUZBVUxUX1JPT1RfTUFSR0lOLFxuICAgICAgICB0aHJlc2hvbGQ6IHRocmVzSG9sZCA/IHRocmVzSG9sZCA6IERFRkFVTFRfVEhSRVNIT0xELFxuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBvYnNlcnZlTm9kZXMoc2VsZWN0b3I6IHN0cmluZyk6IHZvaWQge1xuICAgIGZvciAoY29uc3Qgbm9kZSBvZiB0aGlzLl9yb290LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpKSB7XG4gICAgICB0aGlzLl9vYnNlcnZlci5vYnNlcnZlKG5vZGUpO1xuICAgIH1cbiAgfVxuXG4gIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5fb2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICB9XG59XG4iLCJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5cbmltcG9ydCB7IE5vZGVEZXN0aW5hdGlvbiB9IGZyb20gJy4uL2NvbXBvbmVudHMvdHlwZXMvb3V0bGluZSc7XG5pbXBvcnQgeyBQYWdlTnVtYmVyIH0gZnJvbSAnLi4vY29tcG9uZW50cy90eXBlcy9wYWdlJztcbmltcG9ydCB7IE51bGxhYmxlIH0gZnJvbSAnLi4vY29tcG9uZW50cy90eXBlcy91dGlscyc7XG5pbXBvcnQgeyBsb2dQcm92aWRlcldhcm5pbmcgfSBmcm9tICcuLi91dGlscy9wcm92aWRlcic7XG5pbXBvcnQgeyBnZW5lcmF0ZVBhZ2VJZEZyb21JbmRleCB9IGZyb20gJy4uL3V0aWxzL3Njcm9sbCc7XG5pbXBvcnQgU2Nyb2xsRGV0ZWN0b3IsIHsgU2Nyb2xsRGlyZWN0aW9uIH0gZnJvbSAnLi4vdXRpbHMvU2Nyb2xsRGlyZWN0aW9uRGV0ZWN0b3InO1xuaW1wb3J0IFZpc2libGVFbnRyaWVzRGV0ZWN0b3IgZnJvbSAnLi4vdXRpbHMvVmlzaWJsZUVudHJpZXNEZXRlY3Rvcic7XG5cbmNvbnN0IE9VVExJTkVfQVRUUklCVVRFID0gJ2RhdGEtb3V0bGluZS10YXJnZXQtZGVzdCc7XG5cbmNvbnN0IE9VVExJTkVfU0VMRUNUT1IgPSAnLnJlYWRlcl9fcGFnZV9fb3V0bGluZS10YXJnZXQnO1xuXG5jb25zdCBQQUdFX05VTUJFUl9BVFRSSUJVVEUgPSAnZGF0YS1wYWdlLW51bWJlcic7XG5cbmNvbnN0IFBBR0VfTlVNQkVSX1NFTEVDVE9SID0gYC5yZWFkZXJfX3BhZ2VbJHtQQUdFX05VTUJFUl9BVFRSSUJVVEV9XWA7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVNjcm9sbENvbnRleHQge1xuICBpc091dGxpbmVUYXJnZXRWaXNpYmxlOiAoZGVzdDogTm9kZURlc3RpbmF0aW9uKSA9PiBib29sZWFuO1xuICBpc1BhZ2VWaXNpYmxlOiAocGFnZU51bWJlcjogUGFnZU51bWJlcikgPT4gYm9vbGVhbjtcbiAgc2Nyb2xsRGlyZWN0aW9uOiBOdWxsYWJsZTxTY3JvbGxEaXJlY3Rpb24+O1xuICB2aXNpYmxlT3V0bGluZVRhcmdldHM6IE1hcDxOb2RlRGVzdGluYXRpb24sIG51bWJlcj47IC8vIG1hcHBpbmcgbm9kZSBkZXN0aW5hdGlvbiB3aXRoIHRoZWlyIGludGVyc2VjdGlvbiByYXRpb1xuICB2aXNpYmxlUGFnZVJhdGlvczogTWFwPG51bWJlciwgbnVtYmVyPjsgLy8gbWFwcGluZyBwYWdlIG51bWJlciB3aXRoIHRoZWlyIGludGVyc2VjdGlvbiByYXRpb1xuICByZXNldFNjcm9sbE9ic2VydmVyczogKCkgPT4gdm9pZDtcbiAgc2V0U2Nyb2xsUm9vdDogKHJvb3Q6IE51bGxhYmxlPEVsZW1lbnQ+KSA9PiB2b2lkO1xuICBzY3JvbGxUb091dGxpbmVUYXJnZXQ6IChkZXN0OiBOb2RlRGVzdGluYXRpb24pID0+IHZvaWQ7XG4gIHNldFNjcm9sbFRocmVzaG9sZDogKHNjcm9sbFRocmVzaG9sZDogTnVsbGFibGU8bnVtYmVyPikgPT4gdm9pZDtcbiAgc2Nyb2xsVG9QYWdlOiAocGFnZU51bWJlcjogUGFnZU51bWJlcikgPT4gdm9pZDtcbiAgdXBkYXRlU2Nyb2xsUG9zaXRpb246ICh6b29tTXVsdGlwbGllcjogbnVtYmVyKSA9PiB2b2lkO1xuICBzZXRJc091dGxpbmVDbGlja2VkOiAoaXNPdXRsaW5lR2V0Q2xpY2tlZDogYm9vbGVhbikgPT4gdm9pZDtcbiAgc2Nyb2xsVGhyZXNob2xkUmVhY2hlZEluRGlyZWN0aW9uOiBOdWxsYWJsZTxTY3JvbGxEaXJlY3Rpb24+O1xuICBpc0F0VG9wOiBOdWxsYWJsZTxib29sZWFuPjtcbiAgaXNPdXRsaW5lQ2xpY2tlZDogTnVsbGFibGU8Ym9vbGVhbj47XG59XG5cbmNvbnN0IERFRkFVTFRfQ09OVEVYVDogSVNjcm9sbENvbnRleHQgPSB7XG4gIHNjcm9sbERpcmVjdGlvbjogbnVsbCxcbiAgdmlzaWJsZU91dGxpbmVUYXJnZXRzOiBuZXcgTWFwKCksXG4gIHZpc2libGVQYWdlUmF0aW9zOiBuZXcgTWFwKCksXG4gIGlzT3V0bGluZVRhcmdldFZpc2libGU6IG9wdHMgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgaXNPdXRsaW5lVGFyZ2V0VmlzaWJsZSgke0pTT04uc3RyaW5naWZ5KG9wdHMpfSlgLCAnU2Nyb2xsQ29udGV4dCcpO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSxcbiAgaXNQYWdlVmlzaWJsZTogb3B0cyA9PiB7XG4gICAgbG9nUHJvdmlkZXJXYXJuaW5nKGBpc1BhZ2VWaXNpYmxlKCR7SlNPTi5zdHJpbmdpZnkob3B0cyl9KWAsICdTY3JvbGxDb250ZXh0Jyk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9LFxuICByZXNldFNjcm9sbE9ic2VydmVyczogKCkgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgcmVzZXRTY3JvbGxPYnNlcnZlcnMoKWAsICdTY3JvbGxDb250ZXh0Jyk7XG4gIH0sXG4gIHNldFNjcm9sbFJvb3Q6IChfZWw6IE51bGxhYmxlPEVsZW1lbnQ+KSA9PiB7XG4gICAgbG9nUHJvdmlkZXJXYXJuaW5nKGBzZXRTY3JvbGxSb290KC4uLilgLCAnU2Nyb2xsQ29udGV4dCcpO1xuICB9LFxuICBzY3JvbGxUb091dGxpbmVUYXJnZXQ6IGRlc3QgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgc2Nyb2xsVG9PdXRsaW5lVGFyZ2V0KCR7ZGVzdH0pYCwgJ1Njcm9sbENvbnRleHQnKTtcbiAgfSxcbiAgc2V0U2Nyb2xsVGhyZXNob2xkOiAoc2Nyb2xsVGhyZXNob2xkOiBOdWxsYWJsZTxudW1iZXI+KSA9PiB7XG4gICAgbG9nUHJvdmlkZXJXYXJuaW5nKGBzZXRTY3JvbGxUaHJlc2hvbGQoJHtzY3JvbGxUaHJlc2hvbGR9KWAsICdTY3JvbGxDb250ZXh0Jyk7XG4gIH0sXG4gIHNjcm9sbFRvUGFnZTogb3B0cyA9PiB7XG4gICAgbG9nUHJvdmlkZXJXYXJuaW5nKGBzY3JvbGxUb1BhZ2UoJHtKU09OLnN0cmluZ2lmeShvcHRzKX0pYCwgJ1Njcm9sbENvbnRleHQnKTtcbiAgfSxcbiAgdXBkYXRlU2Nyb2xsUG9zaXRpb246IHpvb21NdWx0aXBsaWVyID0+IHtcbiAgICBsb2dQcm92aWRlcldhcm5pbmcoYHVwZGF0ZVNjcm9sbFBvc2l0aW9uKCR7SlNPTi5zdHJpbmdpZnkoem9vbU11bHRpcGxpZXIpfSlgLCAnU2Nyb2xsQ29udGV4dCcpO1xuICB9LFxuICBzZXRJc091dGxpbmVDbGlja2VkOiBvcHRzID0+IHtcbiAgICBsb2dQcm92aWRlcldhcm5pbmcoYHNldElzT3V0bGluZUdldENsaWNrZWQoJHtKU09OLnN0cmluZ2lmeShvcHRzKX0pYCwgJ1Njcm9sbENvbnRleHQnKTtcbiAgfSxcbiAgc2Nyb2xsVGhyZXNob2xkUmVhY2hlZEluRGlyZWN0aW9uOiBudWxsLFxuICBpc0F0VG9wOiBudWxsLFxuICBpc091dGxpbmVDbGlja2VkOiBudWxsLFxufTtcblxuZXhwb3J0IGNvbnN0IFNjcm9sbENvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PElTY3JvbGxDb250ZXh0PihERUZBVUxUX0NPTlRFWFQpO1xuXG5leHBvcnQgZnVuY3Rpb24gdXNlU2Nyb2xsQ29udGV4dFByb3BzKCk6IElTY3JvbGxDb250ZXh0IHtcbiAgLy8gTm9kZSB1c2VkIGZvciBvYnNlcnZpbmcgdGhlIHNjcm9sbCBwb3NpdGlvblxuICBjb25zdCBbc2Nyb2xsUm9vdCwgc2V0U2Nyb2xsUm9vdF0gPSBSZWFjdC51c2VTdGF0ZTxOdWxsYWJsZTxFbGVtZW50Pj4obnVsbCk7XG5cbiAgLy8gRGV0ZXJtaW5lIHNjcm9sbCBkaXJlY3Rpb25cbiAgY29uc3QgW3Njcm9sbERpcmVjdGlvbiwgc2V0U2Nyb2xsRGlyZWN0aW9uXSA9IFJlYWN0LnVzZVN0YXRlPE51bGxhYmxlPFNjcm9sbERpcmVjdGlvbj4+KG51bGwpO1xuICBjb25zdCBbc2Nyb2xsVGhyZXNob2xkLCBzZXRTY3JvbGxUaHJlc2hvbGRdID0gUmVhY3QudXNlU3RhdGU8TnVsbGFibGU8bnVtYmVyPj4obnVsbCk7XG4gIGNvbnN0IFtzY3JvbGxUaHJlc2hvbGRSZWFjaGVkSW5EaXJlY3Rpb24sIHNldFNjcm9sbFRocmVzaG9sZFJlYWNoZWRJbkRpcmVjdGlvbl0gPVxuICAgIFJlYWN0LnVzZVN0YXRlPE51bGxhYmxlPFNjcm9sbERpcmVjdGlvbj4+KG51bGwpO1xuICBjb25zdCBbaXNBdFRvcCwgc2V0SXNBdFRvcF0gPSBSZWFjdC51c2VTdGF0ZTxOdWxsYWJsZTxib29sZWFuPj4obnVsbCk7XG4gIGNvbnN0IFtpc091dGxpbmVDbGlja2VkLCBzZXRJc091dGxpbmVDbGlja2VkXSA9IFJlYWN0LnVzZVN0YXRlPE51bGxhYmxlPGJvb2xlYW4+PihudWxsKTtcblxuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IHNjcm9sbEVsZW0gPSBzY3JvbGxSb290IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiAgICBpZiAoIXNjcm9sbEVsZW0pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgc2Nyb2xsRGlyZWN0aW9uRGV0ZWN0b3I6IFNjcm9sbERldGVjdG9yO1xuICAgIGlmICghc2Nyb2xsVGhyZXNob2xkKSB7XG4gICAgICAvLyBzY3JvbGwgdGhyZXNob2xkIGlzIG9wdGlvbmFsXG4gICAgICBzY3JvbGxEaXJlY3Rpb25EZXRlY3RvciA9IG5ldyBTY3JvbGxEZXRlY3RvcihzY3JvbGxFbGVtLCBzZXRTY3JvbGxEaXJlY3Rpb24sIHNldElzQXRUb3ApO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY3JvbGxEaXJlY3Rpb25EZXRlY3RvciA9IG5ldyBTY3JvbGxEZXRlY3RvcihcbiAgICAgICAgc2Nyb2xsRWxlbSxcbiAgICAgICAgc2V0U2Nyb2xsRGlyZWN0aW9uLFxuICAgICAgICBzZXRJc0F0VG9wLFxuICAgICAgICBzZXRTY3JvbGxUaHJlc2hvbGRSZWFjaGVkSW5EaXJlY3Rpb24sXG4gICAgICAgIHNjcm9sbFRocmVzaG9sZFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBzY3JvbGxEaXJlY3Rpb25EZXRlY3Rvci5hdHRhY2hTY3JvbGxMaXN0ZW5lcigpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBzY3JvbGxEaXJlY3Rpb25EZXRlY3Rvci5kZXRhY2hTY3JvbGxMaXN0ZW5lcigpO1xuICAgIH07XG4gIH0sIFtzY3JvbGxSb290LCBzY3JvbGxUaHJlc2hvbGRdKTtcblxuICAvLyBDYXVzZXMgdGhlIEludGVyc2VjdGlvbk9ic2VydmVycyB0byBkaXNjb25uZWN0IGFuZCBiZSByZWNyZWF0ZWQgKHVzZWZ1bCB3aGVuIERPTSBjaGFuZ2VzKVxuICBjb25zdCBbb2JzZXJ2ZXJJbmRleCwgc2V0T2JzZXJ2ZXJJbmRleF0gPSBSZWFjdC51c2VTdGF0ZSgwKTtcbiAgY29uc3QgcmVzZXRTY3JvbGxPYnNlcnZlcnMgPSBSZWFjdC51c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgc2V0T2JzZXJ2ZXJJbmRleChvYnNlcnZlckluZGV4ICsgMSk7XG4gIH0sIFtvYnNlcnZlckluZGV4XSk7XG5cbiAgY29uc3QgW3Zpc2libGVPdXRsaW5lVGFyZ2V0cywgc2V0VmlzaWJsZU91dGxpbmVOb2Rlc10gPSBSZWFjdC51c2VTdGF0ZTxcbiAgICBNYXA8Tm9kZURlc3RpbmF0aW9uLCBudW1iZXI+XG4gID4oKCkgPT4ge1xuICAgIGNvbnN0IG1hcCA9IG5ldyBNYXA8Tm9kZURlc3RpbmF0aW9uLCBudW1iZXI+KCk7XG4gICAgT2JqZWN0LmZyZWV6ZShtYXApO1xuICAgIHJldHVybiBtYXA7XG4gIH0pO1xuXG4gIGNvbnN0IFt2aXNpYmxlUGFnZVJhdGlvcywgc2V0VmlzaWJsZVBhZ2VSYXRpb3NdID0gUmVhY3QudXNlU3RhdGU8TWFwPG51bWJlciwgbnVtYmVyPj4oKCkgPT4ge1xuICAgIGNvbnN0IG1hcCA9IG5ldyBNYXA8bnVtYmVyLCBudW1iZXI+KCk7XG4gICAgT2JqZWN0LmZyZWV6ZShtYXApO1xuICAgIHJldHVybiBtYXA7XG4gIH0pO1xuXG4gIGNvbnN0IGlzT3V0bGluZVRhcmdldFZpc2libGUgPSBSZWFjdC51c2VDYWxsYmFjayhcbiAgICAoZGVzdDogTm9kZURlc3RpbmF0aW9uKTogYm9vbGVhbiA9PiB7XG4gICAgICByZXR1cm4gdmlzaWJsZU91dGxpbmVUYXJnZXRzLmhhcyhkZXN0KTtcbiAgICB9LFxuICAgIFt2aXNpYmxlT3V0bGluZVRhcmdldHNdXG4gICk7XG5cbiAgY29uc3Qgc2Nyb2xsVG9PdXRsaW5lVGFyZ2V0ID0gUmVhY3QudXNlQ2FsbGJhY2soKGRlc3Q6IE5vZGVEZXN0aW5hdGlvbik6IHZvaWQgPT4ge1xuICAgIHNldElzT3V0bGluZUNsaWNrZWQodHJ1ZSk7XG4gICAgZG9jdW1lbnRcbiAgICAgIC5xdWVyeVNlbGVjdG9yKGBbZGF0YS1vdXRsaW5lLXRhcmdldC1kZXN0PVwiJHtkZXN0fVwiXWApXG4gICAgICA/LnNjcm9sbEludG9WaWV3KHsgYmVoYXZpb3I6ICdzbW9vdGgnIH0pO1xuICB9LCBbXSk7XG5cbiAgY29uc3QgaXNQYWdlVmlzaWJsZSA9IFJlYWN0LnVzZUNhbGxiYWNrKFxuICAgICh7IHBhZ2VOdW1iZXIsIHBhZ2VJbmRleCB9OiBQYWdlTnVtYmVyKTogYm9vbGVhbiA9PiB7XG4gICAgICBpZiAodHlwZW9mIHBhZ2VJbmRleCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgcGFnZU51bWJlciA9IHBhZ2VJbmRleCArIDE7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHBhZ2VOdW1iZXIgIT09ICdudW1iZXInKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB2aXNpYmxlUGFnZVJhdGlvcy5oYXMocGFnZU51bWJlcik7XG4gICAgfSxcbiAgICBbdmlzaWJsZVBhZ2VSYXRpb3NdXG4gICk7XG5cbiAgY29uc3Qgc2Nyb2xsVG9QYWdlID0gUmVhY3QudXNlQ2FsbGJhY2soKHsgcGFnZU51bWJlciwgcGFnZUluZGV4IH06IFBhZ2VOdW1iZXIpOiB2b2lkID0+IHtcbiAgICBpZiAodHlwZW9mIHBhZ2VOdW1iZXIgPT09ICdudW1iZXInKSB7XG4gICAgICBwYWdlSW5kZXggPSBwYWdlTnVtYmVyIC0gMTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBwYWdlSW5kZXggIT09ICdudW1iZXInKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGRvY3VtZW50XG4gICAgICAuZ2V0RWxlbWVudEJ5SWQoZ2VuZXJhdGVQYWdlSWRGcm9tSW5kZXgocGFnZUluZGV4KSlcbiAgICAgID8uc2Nyb2xsSW50b1ZpZXcoeyBiZWhhdmlvcjogJ3Ntb290aCcgfSk7XG4gIH0sIFtdKTtcblxuICAvLyBXYXRjaCBvdXRsaW5lIG5vZGVzXG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3Qgcm9vdCA9IHNjcm9sbFJvb3QgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuICAgIGNvbnN0IGRldGVjdG9yID0gbmV3IFZpc2libGVFbnRyaWVzRGV0ZWN0b3I8Tm9kZURlc3RpbmF0aW9uPih7XG4gICAgICByb290OiByb290LFxuICAgICAgc2V0VmlzaWJsZUVudHJpZXM6IHNldFZpc2libGVPdXRsaW5lTm9kZXMsXG4gICAgICBvblZpc2libGVFbnRyaWVzQ2hhbmdlOiAoeyB2aXNpYmxlRW50cmllcywgaGlkZGVuRW50cmllcywgbGFzdEVudHJpZXMgfSkgPT4ge1xuICAgICAgICBoaWRkZW5FbnRyaWVzLm1hcChlbnRyeSA9PlxuICAgICAgICAgIGxhc3RFbnRyaWVzLmRlbGV0ZShlbnRyeS50YXJnZXQuZ2V0QXR0cmlidXRlKE9VVExJTkVfQVRUUklCVVRFKSlcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgbmV3RW50cmllcyA9IG5ldyBNYXAobGFzdEVudHJpZXMpO1xuICAgICAgICB2aXNpYmxlRW50cmllcy5tYXAoZW50cnkgPT5cbiAgICAgICAgICBuZXdFbnRyaWVzLnNldChlbnRyeS50YXJnZXQuZ2V0QXR0cmlidXRlKE9VVExJTkVfQVRUUklCVVRFKSwgZW50cnkuaW50ZXJzZWN0aW9uUmF0aW8pXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBuZXdFbnRyaWVzO1xuICAgICAgfSxcbiAgICB9KTtcbiAgICBkZXRlY3Rvci5vYnNlcnZlTm9kZXMoT1VUTElORV9TRUxFQ1RPUik7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGRldGVjdG9yLmRlc3Ryb3koKTtcbiAgICB9O1xuICB9LCBbc2Nyb2xsUm9vdCwgb2JzZXJ2ZXJJbmRleF0pO1xuXG4gIC8vIFdhdGNoIHBhZ2VzXG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3Qgcm9vdCA9IHNjcm9sbFJvb3QgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuICAgIGNvbnN0IGRldGVjdG9yID0gbmV3IFZpc2libGVFbnRyaWVzRGV0ZWN0b3I8bnVtYmVyPih7XG4gICAgICByb290OiByb290LFxuICAgICAgc2V0VmlzaWJsZUVudHJpZXM6IHNldFZpc2libGVQYWdlUmF0aW9zLFxuICAgICAgb25WaXNpYmxlRW50cmllc0NoYW5nZTogKHsgdmlzaWJsZUVudHJpZXMsIGhpZGRlbkVudHJpZXMsIGxhc3RFbnRyaWVzIH0pID0+IHtcbiAgICAgICAgaGlkZGVuRW50cmllcy5tYXAoZW50cnkgPT5cbiAgICAgICAgICBsYXN0RW50cmllcy5kZWxldGUocGFyc2VJbnQoZW50cnkudGFyZ2V0Py5nZXRBdHRyaWJ1dGUoUEFHRV9OVU1CRVJfQVRUUklCVVRFKSB8fCAnJywgMTApKVxuICAgICAgICApO1xuICAgICAgICBjb25zdCBuZXdFbnRyaWVzID0gbmV3IE1hcChsYXN0RW50cmllcyk7XG4gICAgICAgIHZpc2libGVFbnRyaWVzLm1hcChlbnRyeSA9PlxuICAgICAgICAgIG5ld0VudHJpZXMuc2V0KFxuICAgICAgICAgICAgcGFyc2VJbnQoZW50cnkudGFyZ2V0Py5nZXRBdHRyaWJ1dGUoUEFHRV9OVU1CRVJfQVRUUklCVVRFKSB8fCAnJywgMTApLFxuICAgICAgICAgICAgZW50cnkuaW50ZXJzZWN0aW9uUmF0aW9cbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBuZXdFbnRyaWVzO1xuICAgICAgfSxcbiAgICB9KTtcbiAgICBkZXRlY3Rvci5vYnNlcnZlTm9kZXMoUEFHRV9OVU1CRVJfU0VMRUNUT1IpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBkZXRlY3Rvci5kZXN0cm95KCk7XG4gICAgfTtcbiAgfSwgW3Njcm9sbFJvb3QsIG9ic2VydmVySW5kZXhdKTtcblxuICAvLyBjYWxjdWxhdGVzIGEgbmV3IHNjcm9sbCBwb3NpdGlvbiBhZnRlciB6b29taW5nIGluL291dCBzbyB1c2VyIGRvZXNudCBsb3NlIHRoZWlyIHBvc2l0aW9uXG4gIGNvbnN0IHVwZGF0ZVNjcm9sbFBvc2l0aW9uID0gUmVhY3QudXNlQ2FsbGJhY2soXG4gICAgKHpvb21NdWx0aXBsaWVyOiBudW1iZXIpOiB2b2lkID0+IHtcbiAgICAgIGNvbnN0IHJvb3QgPSBzY3JvbGxSb290IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiAgICAgIGlmICghcm9vdCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBuZXdTY3JvbGxUb3AgPSBNYXRoLmZsb29yKHJvb3Quc2Nyb2xsVG9wICogem9vbU11bHRpcGxpZXIpO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHJvb3Quc2Nyb2xsVG9wID0gbmV3U2Nyb2xsVG9wO1xuICAgICAgfSwgMCk7XG4gICAgfSxcbiAgICBbc2Nyb2xsUm9vdF1cbiAgKTtcblxuICByZXR1cm4ge1xuICAgIGlzT3V0bGluZVRhcmdldFZpc2libGUsXG4gICAgaXNQYWdlVmlzaWJsZSxcbiAgICBzY3JvbGxEaXJlY3Rpb24sXG4gICAgdmlzaWJsZU91dGxpbmVUYXJnZXRzLFxuICAgIHZpc2libGVQYWdlUmF0aW9zLFxuICAgIHJlc2V0U2Nyb2xsT2JzZXJ2ZXJzLFxuICAgIHNldFNjcm9sbFJvb3QsXG4gICAgc2Nyb2xsVG9PdXRsaW5lVGFyZ2V0LFxuICAgIHNldFNjcm9sbFRocmVzaG9sZCxcbiAgICBzY3JvbGxUb1BhZ2UsXG4gICAgdXBkYXRlU2Nyb2xsUG9zaXRpb24sXG4gICAgc2V0SXNPdXRsaW5lQ2xpY2tlZCxcbiAgICBzY3JvbGxUaHJlc2hvbGRSZWFjaGVkSW5EaXJlY3Rpb24sXG4gICAgaXNBdFRvcCxcbiAgICBpc091dGxpbmVDbGlja2VkLFxuICB9O1xufVxuIiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5pbXBvcnQgeyBOdWxsYWJsZSB9IGZyb20gJy4uL2NvbXBvbmVudHMvdHlwZXMvdXRpbHMnO1xuaW1wb3J0IHsgbG9nUHJvdmlkZXJXYXJuaW5nIH0gZnJvbSAnLi4vdXRpbHMvcHJvdmlkZXInO1xuXG5leHBvcnQgaW50ZXJmYWNlIElVaUNvbnRleHQge1xuICBlcnJvck1lc3NhZ2U6IE51bGxhYmxlPHN0cmluZz47XG4gIGlzTG9hZGluZzogYm9vbGVhbjtcbiAgaXNTaG93aW5nSGlnaGxpZ2h0T3ZlcmxheTogYm9vbGVhbjtcbiAgaXNTaG93aW5nT3V0bGluZTogYm9vbGVhbjtcbiAgaXNTaG93aW5nVGV4dEhpZ2hsaWdodDogYm9vbGVhbjtcbiAgc2V0RXJyb3JNZXNzYWdlOiAoZXJyb3JNZXNzYWdlOiBOdWxsYWJsZTxzdHJpbmc+KSA9PiB2b2lkO1xuICBzZXRJc0xvYWRpbmc6IChpc0xvYWRpbmc6IGJvb2xlYW4pID0+IHZvaWQ7XG4gIHNldElzU2hvd2luZ0hpZ2hsaWdodE92ZXJsYXk6IChpc1Nob3dpbmdIaWdobGlnaHRPdmVybGF5OiBib29sZWFuKSA9PiB2b2lkO1xuICBzZXRJc1Nob3dpbmdPdXRsaW5lOiAoaXNTaG93aW5nT3V0bGluZTogYm9vbGVhbikgPT4gdm9pZDtcbiAgc2V0SXNTaG93aW5nVGV4dEhpZ2hsaWdodDogKGlzU2hvd2luZ1RleHRIaWdobGlnaHQ6IGJvb2xlYW4pID0+IHZvaWQ7XG59XG5cbmV4cG9ydCBjb25zdCBVaUNvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PElVaUNvbnRleHQ+KHtcbiAgZXJyb3JNZXNzYWdlOiBudWxsLFxuICBpc0xvYWRpbmc6IGZhbHNlLFxuICBpc1Nob3dpbmdIaWdobGlnaHRPdmVybGF5OiBmYWxzZSxcbiAgaXNTaG93aW5nT3V0bGluZTogZmFsc2UsXG4gIGlzU2hvd2luZ1RleHRIaWdobGlnaHQ6IGZhbHNlLFxuICBzZXRFcnJvck1lc3NhZ2U6IGVycm9yTWVzc2FnZSA9PiB7XG4gICAgbG9nUHJvdmlkZXJXYXJuaW5nKGBzZXRFcnJvck1lc3NhZ2UoJHtlcnJvck1lc3NhZ2V9KWAsICdVaUNvbnRleHQnKTtcbiAgfSxcbiAgc2V0SXNTaG93aW5nT3V0bGluZTogaXNTaG93aW5nT3V0bGluZSA9PiB7XG4gICAgbG9nUHJvdmlkZXJXYXJuaW5nKGBzZXRJc1Nob3dpbmdPdXRsaW5lKCR7aXNTaG93aW5nT3V0bGluZX0pYCwgJ1VpQ29udGV4dCcpO1xuICB9LFxuICBzZXRJc0xvYWRpbmc6IGlzTG9hZGluZyA9PiB7XG4gICAgbG9nUHJvdmlkZXJXYXJuaW5nKGBzZXRJc0xvYWRpbmcoJHtpc0xvYWRpbmd9KWAsICdVaUNvbnRleHQnKTtcbiAgfSxcbiAgc2V0SXNTaG93aW5nSGlnaGxpZ2h0T3ZlcmxheTogaXNTaG93aW5nSGlnaGxpZ2h0T3ZlcmxheSA9PiB7XG4gICAgbG9nUHJvdmlkZXJXYXJuaW5nKGBzZXRJc1Nob3dpbmdIaWdobGlnaHRPdmVybGF5KCR7aXNTaG93aW5nSGlnaGxpZ2h0T3ZlcmxheX0pYCwgJ1VpQ29udGV4dCcpO1xuICB9LFxuICBzZXRJc1Nob3dpbmdUZXh0SGlnaGxpZ2h0OiBpc1Nob3dpbmdUZXh0SGlnaGxpZ2h0ID0+IHtcbiAgICBsb2dQcm92aWRlcldhcm5pbmcoYHNldElzU2hvd2luZ1RleHRIaWdobGlnaHQoJHtpc1Nob3dpbmdUZXh0SGlnaGxpZ2h0fSlgLCAnVWlDb250ZXh0Jyk7XG4gIH0sXG59KTtcblxuZXhwb3J0IGZ1bmN0aW9uIHVzZVVpQ29udGV4dFByb3BzKCk6IElVaUNvbnRleHQge1xuICBjb25zdCBbZXJyb3JNZXNzYWdlLCBzZXRFcnJvck1lc3NhZ2VdID0gUmVhY3QudXNlU3RhdGU8TnVsbGFibGU8c3RyaW5nPj4obnVsbCk7XG4gIGNvbnN0IFtpc0xvYWRpbmcsIHNldElzTG9hZGluZ10gPSBSZWFjdC51c2VTdGF0ZTxib29sZWFuPih0cnVlKTtcbiAgY29uc3QgW2lzU2hvd2luZ0hpZ2hsaWdodE92ZXJsYXksIHNldElzU2hvd2luZ0hpZ2hsaWdodE92ZXJsYXldID0gUmVhY3QudXNlU3RhdGU8Ym9vbGVhbj4oZmFsc2UpO1xuICBjb25zdCBbaXNTaG93aW5nT3V0bGluZSwgc2V0SXNTaG93aW5nT3V0bGluZV0gPSBSZWFjdC51c2VTdGF0ZTxib29sZWFuPihmYWxzZSk7XG4gIGNvbnN0IFtpc1Nob3dpbmdUZXh0SGlnaGxpZ2h0LCBzZXRJc1Nob3dpbmdUZXh0SGlnaGxpZ2h0XSA9IFJlYWN0LnVzZVN0YXRlPGJvb2xlYW4+KGZhbHNlKTtcblxuICByZXR1cm4ge1xuICAgIGVycm9yTWVzc2FnZSxcbiAgICBpc0xvYWRpbmcsXG4gICAgaXNTaG93aW5nSGlnaGxpZ2h0T3ZlcmxheSxcbiAgICBpc1Nob3dpbmdPdXRsaW5lLFxuICAgIGlzU2hvd2luZ1RleHRIaWdobGlnaHQsXG4gICAgc2V0RXJyb3JNZXNzYWdlLFxuICAgIHNldElzTG9hZGluZyxcbiAgICBzZXRJc1Nob3dpbmdIaWdobGlnaHRPdmVybGF5LFxuICAgIHNldElzU2hvd2luZ091dGxpbmUsXG4gICAgc2V0SXNTaG93aW5nVGV4dEhpZ2hsaWdodCxcbiAgfTtcbn1cbiIsIi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG5leHBvcnQgZnVuY3Rpb24gZ2V0RXJyb3JNZXNzYWdlKGVycm9yOiBhbnkpOiBzdHJpbmcge1xuICBpZiAoIWVycm9yKSB7XG4gICAgcmV0dXJuICdVbmtub3duIGVycm9yJztcbiAgfVxuICBpZiAodHlwZW9mIGVycm9yID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBlcnJvcjtcbiAgfVxuICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgIHJldHVybiBlcnJvci5tZXNzYWdlO1xuICB9XG4gIGlmICh0eXBlb2YgZXJyb3IuZXJyb3IgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGVycm9yLmVycm9yO1xuICB9XG4gIHJldHVybiBlcnJvci50b1N0cmluZygpO1xufVxuIiwiaW1wb3J0IHsgcGRmanMgfSBmcm9tICdyZWFjdC1wZGYnO1xuXG4vLyBTZXQgUERGanMgd29ya2VyIHNvdXJjZSBvciBlbHNlIFBERiB3aWxsIG5vdCBsb2FkIHdoZW4gdGhpcyBsaWJyYXJ5IGlzIGltcG9ydGVkIGFzIGEgcGFja2FnZS5cbmV4cG9ydCBmdW5jdGlvbiBpbml0UGRmV29ya2VyKCk6IHZvaWQge1xuICBwZGZqcy5HbG9iYWxXb3JrZXJPcHRpb25zLndvcmtlclNyYyA9IGAvL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9wZGYuanMvJHtwZGZqcy52ZXJzaW9ufS9wZGYud29ya2VyLm1pbi5qc2A7XG59XG4iLCJpbXBvcnQgeyBEaW1lbnNpb25zIH0gZnJvbSAnLi4vY29tcG9uZW50cy90eXBlcy9ib3VuZGluZ0JveCc7XG5cbi8vIERhdGEgZnJvbSByZWFjdC1wZGYvcGRmanMgdGhhdCB3ZSBuZWVkIHRvIGNvbXB1dGUgdGhlIHBpeGVsIHNpemUgb2YgdGhlIFBERidzIHBhZ2UocykuXG5leHBvcnQgaW50ZXJmYWNlIElQREZQYWdlUHJveHkge1xuICB1c2VyVW5pdDogbnVtYmVyOyAvLyB0aGUgZGVmYXVsdCBzaXplIG9mIHVuaXRzIGluIDEvNzJuZHMgb2YgYW4gaW5jaFxuICB2aWV3OiBBcnJheTxudW1iZXI+OyAvLyBmb3JtYXQ6IFsgdG9wIGxlZnQgeCBjb29yZGluYXRlLCB0b3AgbGVmdCB5IGNvb3JkaW5hdGUsIGJvdHRvbSByaWdodCB4LCBib3R0b20gcmlnaHQgeV1cbn1cblxuLy8gV2UgYXNzdW1lIDk2IERQSSBmb3IgZGlzcGxheVxuLy8gVE9ETzogVGhlcmUgYXJlIG1vcmUgYWNjdXJhdGUgd2F5cyB0byBkbyB0aGlzLCBidXQgdGhpcyBpcyB3aGF0IFNjaG9sYXJQaGkgZG9lcyBub3dcbmNvbnN0IERQSSA9IDk2O1xuXG4vLyBQREYgdW5pdHMgYXJlIGluIDEvNzJuZHMgb2YgYW4gaW5jaFxuY29uc3QgVVNFUl9VTklUX0RFTk9NSU5BVE9SID0gNzI7XG5cbi8qKlxuICogR2l2ZW4gYSBQREZQYWdlUHJveHksIGNhbGN1bGF0ZXMgdGhlIHNjcmVlbiBwaXhlbCBzaXplIG9mIHRoZSBQREYgcGFnZSBhdCAxMDAlIHNjYWxlXG4gKiBAcGFyYW0gcGFnZSBUaGUgUERGUGFnZVByb3h5IHRvIGNhbGN1bGF0ZSBzaXplIGZvclxuICogQHJldHVybnMgUGl4ZWwgc2l6ZSBvZiBhIHBhZ2UgYXQgMTAwJSBzY2FsZSBhc3N1bWluZyA5NkRQSSBkaXNwbGF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlUGFnZURpbWVuc2lvbnMocGFnZTogSVBERlBhZ2VQcm94eSk6IERpbWVuc2lvbnMge1xuICBjb25zdCBbbGVmdFB4LCB0b3BQeCwgcmlnaHRQeCwgYm90dG9tUHhdID0gcGFnZS52aWV3O1xuICBjb25zdCBQUEkgPSAocGFnZS51c2VyVW5pdCAvIFVTRVJfVU5JVF9ERU5PTUlOQVRPUikgKiBEUEk7XG5cbiAgcmV0dXJuIHtcbiAgICBoZWlnaHQ6IChib3R0b21QeCAtIHRvcFB4KSAqIFBQSSxcbiAgICB3aWR0aDogKHJpZ2h0UHggLSBsZWZ0UHgpICogUFBJLFxuICB9O1xufVxuIiwiaW1wb3J0IHsgUGFnZVJlZmVyZW5jZSB9IGZyb20gJy4vcGFnZSc7XG5cbmV4cG9ydCB0eXBlIERlc3RpbmF0aW9uID0ge1xuICBkZXN0OiBzdHJpbmc7XG4gIHBhZ2VJbmRleDogbnVtYmVyO1xuICBwYWdlTnVtYmVyOiBudW1iZXI7XG59O1xuXG4vKipcbiAqIFRoaXMgY2xhc3MgaXMgdGhlIGRlZmluaXRpb24gb2YgdGhlIGZpcnN0IGl0ZW0gd2hlbiBEZXN0aW5hdGlvbiBpcyByZXR1cm5lZCBhcyBhbiBhcnJheS5cbiAqIEl0IGlzIGNyZWF0ZWQgYmFzZWQgb24gdGhlIHNhbWUgY2xhc3MgaW4gJ3JlYWN0LXBkZicgbGlicmFyeTpcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS93b2p0ZWttYWovcmVhY3QtcGRmL2Jsb2IvY2E0NDUzZjEyM2FmNTFlMmZhZWQzOWE4YTYyODAwOTAxMDMwNDU5YS9zcmMvUmVmLmpzXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWYgaW1wbGVtZW50cyBQYWdlUmVmZXJlbmNlIHtcbiAgbnVtOiBudW1iZXI7XG4gIGdlbjogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKHsgbnVtLCBnZW4gfTogUGFnZVJlZmVyZW5jZSkge1xuICAgIHRoaXMubnVtID0gbnVtO1xuICAgIHRoaXMuZ2VuID0gZ2VuO1xuICB9XG5cbiAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5nZW4gIT09IDAgPyBgJHt0aGlzLm51bX1SJHt0aGlzLmdlbn1gIDogYCR7dGhpcy5udW19UmA7XG4gIH1cbn1cbiIsImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IERvY3VtZW50LCBEb2N1bWVudFByb3BzLCBwZGZqcyB9IGZyb20gJ3JlYWN0LXBkZic7XG5cbmltcG9ydCB7IERvY3VtZW50Q29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvRG9jdW1lbnRDb250ZXh0JztcbmltcG9ydCB7IFNjcm9sbENvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L1Njcm9sbENvbnRleHQnO1xuaW1wb3J0IHsgVHJhbnNmb3JtQ29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvVHJhbnNmb3JtQ29udGV4dCc7XG5pbXBvcnQgeyBVaUNvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L1VpQ29udGV4dCc7XG5pbXBvcnQgeyBnZXRFcnJvck1lc3NhZ2UgfSBmcm9tICcuLi91dGlscy9lcnJvck1lc3NhZ2UnO1xuaW1wb3J0IHsgaW5pdFBkZldvcmtlciB9IGZyb20gJy4uL3V0aWxzL3BkZldvcmtlcic7XG5pbXBvcnQgeyBjb21wdXRlUGFnZURpbWVuc2lvbnMsIElQREZQYWdlUHJveHkgfSBmcm9tICcuLi91dGlscy9zY2FsZSc7XG5pbXBvcnQgeyBzY3JvbGxUb1Bvc2l0aW9uIH0gZnJvbSAnLi4vdXRpbHMvc2Nyb2xsJztcbmltcG9ydCB7IERlc3RpbmF0aW9uLCBSZWYgfSBmcm9tICcuL3R5cGVzL2Rlc3RpbmF0aW9uJztcblxuZXhwb3J0IHR5cGUgUHJvcHMgPSB7XG4gIGNoaWxkcmVuPzogUmVhY3QuUmVhY3ROb2RlO1xufSAmIERvY3VtZW50UHJvcHM7XG5cbmV4cG9ydCBjb25zdCBEb2N1bWVudFdyYXBwZXI6IFJlYWN0LkZ1bmN0aW9uQ29tcG9uZW50PFByb3BzPiA9ICh7XG4gIGNoaWxkcmVuLFxuICAuLi5leHRyYVByb3BzXG59OiBQcm9wcykgPT4ge1xuICBpbml0UGRmV29ya2VyKCk7XG5cbiAgY29uc3QgeyBwZGZEb2NQcm94eSwgc2V0TnVtUGFnZXMsIHNldFBhZ2VEaW1lbnNpb25zLCBzZXRQZGZEb2NQcm94eSB9ID1cbiAgICBSZWFjdC51c2VDb250ZXh0KERvY3VtZW50Q29udGV4dCk7XG4gIGNvbnN0IHsgcmVzZXRTY3JvbGxPYnNlcnZlcnMgfSA9IFJlYWN0LnVzZUNvbnRleHQoU2Nyb2xsQ29udGV4dCk7XG4gIGNvbnN0IHsgcm90YXRpb24gfSA9IFJlYWN0LnVzZUNvbnRleHQoVHJhbnNmb3JtQ29udGV4dCk7XG4gIGNvbnN0IHsgc2V0RXJyb3JNZXNzYWdlLCBzZXRJc0xvYWRpbmcgfSA9IFJlYWN0LnVzZUNvbnRleHQoVWlDb250ZXh0KTtcblxuICBmdW5jdGlvbiBnZXRGaXJzdFBhZ2UocGRmRG9jOiBwZGZqcy5QREZEb2N1bWVudFByb3h5KTogUHJvbWlzZTxJUERGUGFnZVByb3h5PiB7XG4gICAgLy8gZ2V0UGFnZSB1c2VzIDEtaW5kZXhlZCBwYWdlTnVtYmVyLCBub3QgMC1pbmRleGVkIHBhZ2VJbmRleFxuICAgIHJldHVybiBwZGZEb2MuZ2V0UGFnZSgxKTtcbiAgfVxuXG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgcmVzZXRTY3JvbGxPYnNlcnZlcnMoKTtcbiAgfSwgW10pO1xuXG4gIGNvbnN0IG9uUGRmTG9hZFN1Y2Nlc3MgPSBSZWFjdC51c2VDYWxsYmFjaygocGRmRG9jOiBwZGZqcy5QREZEb2N1bWVudFByb3h5KTogdm9pZCA9PiB7XG4gICAgc2V0TnVtUGFnZXMocGRmRG9jLm51bVBhZ2VzKTtcbiAgICBnZXRGaXJzdFBhZ2UocGRmRG9jKVxuICAgICAgLnRoZW4ocGFnZSA9PiB7XG4gICAgICAgIHNldFBhZ2VEaW1lbnNpb25zKGNvbXB1dGVQYWdlRGltZW5zaW9ucyhwYWdlKSk7XG4gICAgICAgIHNldEVycm9yTWVzc2FnZShudWxsKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBzZXRFcnJvck1lc3NhZ2UoZ2V0RXJyb3JNZXNzYWdlKGVycm9yKSk7XG4gICAgICB9KVxuICAgICAgLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICBzZXRJc0xvYWRpbmcoZmFsc2UpO1xuICAgICAgfSk7XG5cbiAgICBpZiAoIXBkZkRvY1Byb3h5KSB7XG4gICAgICBzZXRQZGZEb2NQcm94eShwZGZEb2MpO1xuICAgIH1cbiAgfSwgW10pO1xuXG4gIGNvbnN0IG9uUGRmTG9hZEVycm9yID0gUmVhY3QudXNlQ2FsbGJhY2soKGVycm9yOiB1bmtub3duKTogdm9pZCA9PiB7XG4gICAgc2V0RXJyb3JNZXNzYWdlKGdldEVycm9yTWVzc2FnZShlcnJvcikpO1xuICAgIHNldElzTG9hZGluZyhmYWxzZSk7XG4gIH0sIFtdKTtcblxuICBjb25zdCBvbkl0ZW1DbGlja2VkID0gKHBhcmFtOiBEZXN0aW5hdGlvbik6IHZvaWQgPT4ge1xuICAgIGlmICghcGRmRG9jUHJveHkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBTY3JvbGwgdG8gdGhlIGRlc3RpbmF0aW9uIG9mIHRoZSBpdGVtXG4gICAgcGRmRG9jUHJveHkuZ2V0RGVzdGluYXRpb24ocGFyYW0uZGVzdCkudGhlbihkZXN0QXJyYXkgPT4ge1xuICAgICAgaWYgKCFkZXN0QXJyYXkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBbcmVmLCAsICwgYm90dG9tUG9pbnRzXSA9IGRlc3RBcnJheTtcbiAgICAgIHBkZkRvY1Byb3h5LmdldFBhZ2VJbmRleChuZXcgUmVmKHJlZikpLnRoZW4ocmVmSW5mbyA9PiB7XG4gICAgICAgIHNjcm9sbFRvUG9zaXRpb24ocGFyc2VJbnQocmVmSW5mby50b1N0cmluZygpKSwgMCwgYm90dG9tUG9pbnRzLCByb3RhdGlvbik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICByZXR1cm4gKFxuICAgIDxEb2N1bWVudFxuICAgICAgb3B0aW9ucz17eyBjTWFwVXJsOiAnY21hcHMvJywgY01hcFBhY2tlZDogdHJ1ZSB9fVxuICAgICAgb25Mb2FkRXJyb3I9e29uUGRmTG9hZEVycm9yfVxuICAgICAgb25Mb2FkU3VjY2Vzcz17b25QZGZMb2FkU3VjY2Vzc31cbiAgICAgIGV4dGVybmFsTGlua1RhcmdldD1cIl9ibGFua1wiXG4gICAgICByZW5kZXJNb2RlPVwibm9uZVwiXG4gICAgICAvLyBAdHMtaWdub3JlOiB0aGUgYXJndW1lbnRzIHNob3VsZCBiZSB7IGRlc3QsIHBhZ2VJbmRleCwgcGFnZU51bWJlciB9XG4gICAgICAvLyBAdHlwZXMvcmVhY3QtcGRmIGhhc24ndCB1cGRhdGVkIHRoZSBmdW5jdGlvbiBzaWduYXR1cmVcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9EZWZpbml0ZWx5VHlwZWQvRGVmaW5pdGVseVR5cGVkL2Jsb2IvZDczZWI2NTJlMGJhOGY4OTM5NWEwZWYyYmE2OWNmMWU2NDBjZTViZS90eXBlcy9yZWFjdC1wZGYvZGlzdC9Eb2N1bWVudC5kLnRzI0w3MlxuICAgICAgb25JdGVtQ2xpY2s9e29uSXRlbUNsaWNrZWR9XG4gICAgICB7Li4uZXh0cmFQcm9wc30+XG4gICAgICB7Y2hpbGRyZW59XG4gICAgPC9Eb2N1bWVudD5cbiAgKTtcbn07XG4iLCJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5cbmV4cG9ydCB0eXBlIFByb3BzID0ge1xuICBjbGFzc05hbWU/OiBzdHJpbmc7XG4gIGNoaWxkcmVuPzogUmVhY3QuUmVhY3ROb2RlO1xuICBwZGZVcmw6IHN0cmluZztcbn07XG5cbi8qKlxuICogSFRNTCBhbmNob3IgdGFnIGFsbG93cyB5b3UgdG8gZG93bmxvYWQgYSBmaWxlIGZyb20gdGhlIHNhbWUgb3JpZ2luLlxuICogVGhpcyBpcyBhIHdvcmthcm91bmQgdG8gZG93bmxvYWQgYSBmaWxlIHNlcnZlZCBmcm9tIGEgZGlmZmVyZW50IG9yaWdpblxuICovXG5leHBvcnQgY29uc3QgRG93bmxvYWRCdXR0b246IFJlYWN0LkZ1bmN0aW9uQ29tcG9uZW50PFByb3BzPiA9ICh7XG4gIHBkZlVybCxcbiAgY2hpbGRyZW4sXG4gIGNsYXNzTmFtZSxcbiAgLi4uZXh0cmFQcm9wc1xufTogUHJvcHMpID0+IHtcbiAgY29uc3QgW2ZldGNoaW5nLCBzZXRGZXRjaGluZ10gPSBSZWFjdC51c2VTdGF0ZShmYWxzZSk7XG5cbiAgY29uc3QgZG93bmxvYWQgPSAoKSA9PiB7XG4gICAgc2V0RmV0Y2hpbmcodHJ1ZSk7XG5cbiAgICBmZXRjaChwZGZVcmwpXG4gICAgICAudGhlbihyZXNwb25zZSA9PiByZXNwb25zZS5ibG9iKCkpXG4gICAgICAudGhlbihibG9iID0+IHtcbiAgICAgICAgc2V0RmV0Y2hpbmcoZmFsc2UpO1xuICAgICAgICBjb25zdCBibG9iVVJMID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICAgICAgY29uc3QgYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgYS5ocmVmID0gYmxvYlVSTDtcbiAgICAgICAgYS5kb3dubG9hZCA9IHBkZlVybC5zcGxpdCgnLycpLnBvcCgpIHx8IHBkZlVybDtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChhKTtcbiAgICAgICAgYS5jbGljaygpO1xuICAgICAgfSk7XG4gIH07XG5cbiAgcmV0dXJuIChcbiAgICA8YnV0dG9uXG4gICAgICBkaXNhYmxlZD17ZmV0Y2hpbmd9XG4gICAgICBvbkNsaWNrPXsoKSA9PiBkb3dubG9hZCgpfVxuICAgICAgYXJpYS1sYWJlbD1cIkRvd25sb2FkIFBERlwiXG4gICAgICBjbGFzc05hbWU9e2ByZWFkZXJfX2Rvd25sb2FkLWJ0biAke2NsYXNzTmFtZX1gfVxuICAgICAgey4uLmV4dHJhUHJvcHN9PlxuICAgICAge2NoaWxkcmVuID8gY2hpbGRyZW4gOiAnRG93bmxvYWQnfVxuICAgIDwvYnV0dG9uPlxuICApO1xufTtcbiIsImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcblxuaW1wb3J0IHsgRG9jdW1lbnRDb250ZXh0IH0gZnJvbSAnLi4vY29udGV4dC9Eb2N1bWVudENvbnRleHQnO1xuaW1wb3J0IHsgVHJhbnNmb3JtQ29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvVHJhbnNmb3JtQ29udGV4dCc7XG5pbXBvcnQgeyBjb21wdXRlQm91bmRpbmdCb3hTdHlsZSwgY29tcHV0ZVBhZ2VTdHlsZSB9IGZyb20gJy4uL3V0aWxzL3N0eWxlJztcbmltcG9ydCB7IFByb3BzIGFzIEJvdW5kaW5nQm94UHJvcHMgfSBmcm9tICcuL0JvdW5kaW5nQm94JztcblxuZXhwb3J0IHR5cGUgUHJvcHMgPSB7XG4gIGNoaWxkcmVuPzogUmVhY3QuUmVhY3RFbGVtZW50PEJvdW5kaW5nQm94UHJvcHM+IHwgQXJyYXk8UmVhY3QuUmVhY3RFbGVtZW50PEJvdW5kaW5nQm94UHJvcHM+PjtcbiAgcGFnZUluZGV4OiBudW1iZXI7XG59O1xuXG5leHBvcnQgY29uc3QgSGlnaGxpZ2h0T3ZlcmxheTogUmVhY3QuRnVuY3Rpb25Db21wb25lbnQ8UHJvcHM+ID0gKHtcbiAgY2hpbGRyZW4sXG4gIHBhZ2VJbmRleCxcbiAgLi4uZXh0cmFQcm9wc1xufTogUHJvcHMpID0+IHtcbiAgY29uc3QgeyBwYWdlRGltZW5zaW9ucyB9ID0gUmVhY3QudXNlQ29udGV4dChEb2N1bWVudENvbnRleHQpO1xuICBjb25zdCB7IHJvdGF0aW9uLCBzY2FsZSB9ID0gUmVhY3QudXNlQ29udGV4dChUcmFuc2Zvcm1Db250ZXh0KTtcbiAgY29uc3QgbWFza0lkID0gYGhpZ2hsaWdodC1vdmVybGF5LW1hc2stJHtwYWdlSW5kZXh9YDtcblxuICBjb25zdCBnZXRQYWdlU3R5bGUgPSBSZWFjdC51c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgcmV0dXJuIGNvbXB1dGVQYWdlU3R5bGUocGFnZURpbWVuc2lvbnMsIHJvdGF0aW9uLCBzY2FsZSk7XG4gIH0sIFtwYWdlRGltZW5zaW9ucywgcm90YXRpb24sIHNjYWxlXSk7XG5cbiAgY29uc3QgZ2V0VW5tYXNrZWRBcmVhID0gUmVhY3QudXNlQ2FsbGJhY2soXG4gICAgKFxuICAgICAgYm91bmRpbmdCb3hlczpcbiAgICAgICAgfCBSZWFjdC5SZWFjdEVsZW1lbnQ8Qm91bmRpbmdCb3hQcm9wcz5cbiAgICAgICAgfCBBcnJheTxSZWFjdC5SZWFjdEVsZW1lbnQ8Qm91bmRpbmdCb3hQcm9wcz4+XG4gICAgKSA9PiB7XG4gICAgICBjb25zdCBib3hlcyA9IEFycmF5LmlzQXJyYXkoYm91bmRpbmdCb3hlcykgPyBib3VuZGluZ0JveGVzIDogW2JvdW5kaW5nQm94ZXNdO1xuICAgICAgcmV0dXJuIGJveGVzLm1hcCgoYm94LCBpKSA9PiB7XG4gICAgICAgIGNvbnN0IGJveFN0eWxlID0gY29tcHV0ZUJvdW5kaW5nQm94U3R5bGUoYm94LnByb3BzLCBwYWdlRGltZW5zaW9ucywgcm90YXRpb24sIHNjYWxlKTtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICA8cmVjdCBzdHlsZT17Ym94U3R5bGV9IHg9e2JveFN0eWxlLmxlZnR9IHk9e2JveFN0eWxlLnRvcH0ga2V5PXtpfSBmaWxsPVwiYmxhY2tcIj48L3JlY3Q+XG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9LFxuICAgIFtwYWdlRGltZW5zaW9ucywgcm90YXRpb24sIHNjYWxlXVxuICApO1xuXG4gIHJldHVybiAoXG4gICAgPGRpdiBjbGFzc05hbWU9XCJyZWFkZXJfX3BhZ2UtaGlnaGxpZ2h0LW92ZXJsYXlcIiBzdHlsZT17Z2V0UGFnZVN0eWxlKCl9IHsuLi5leHRyYVByb3BzfT5cbiAgICAgIDxzdmcgY2xhc3NOYW1lPVwicGFnZS1tYXNrXCIgc3R5bGU9e2dldFBhZ2VTdHlsZSgpfT5cbiAgICAgICAgPG1hc2sgaWQ9e21hc2tJZH0+XG4gICAgICAgICAgPHJlY3Qgc3R5bGU9e2dldFBhZ2VTdHlsZSgpfSBmaWxsPVwid2hpdGVcIj48L3JlY3Q+XG4gICAgICAgICAge2NoaWxkcmVuICYmIGdldFVubWFza2VkQXJlYShjaGlsZHJlbil9XG4gICAgICAgIDwvbWFzaz5cbiAgICAgICAgPHJlY3Qgc3R5bGU9e2dldFBhZ2VTdHlsZSgpfSBmaWxsPVwid2hpdGVcIiBvcGFjaXR5PVwiMC42XCIgbWFzaz17YHVybCgjJHttYXNrSWR9KWB9PjwvcmVjdD5cbiAgICAgIDwvc3ZnPlxuICAgIDwvZGl2PlxuICApO1xufTtcbiIsImltcG9ydCBjbGFzc25hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5pbXBvcnQgeyBTY3JvbGxDb250ZXh0IH0gZnJvbSAnLi4vLi4vY29udGV4dC9TY3JvbGxDb250ZXh0JztcbmltcG9ydCB7IE5vZGVEZXN0aW5hdGlvbiwgT3V0bGluZU5vZGUgfSBmcm9tICcuLi90eXBlcy9vdXRsaW5lJztcblxudHlwZSBQcm9wcyA9IHtcbiAgaXRlbXM/OiBBcnJheTxPdXRsaW5lTm9kZT47XG4gIG9uQ2xpY2s/OiAoZGVzdDogTm9kZURlc3RpbmF0aW9uKSA9PiB2b2lkO1xufTtcblxuZXhwb3J0IGNvbnN0IE91dGxpbmVJdGVtOiBSZWFjdC5GdW5jdGlvbkNvbXBvbmVudDxQcm9wcz4gPSAoeyBpdGVtcywgb25DbGljayB9OiBQcm9wcykgPT4ge1xuICBjb25zdCB7IGlzT3V0bGluZVRhcmdldFZpc2libGUgfSA9IFJlYWN0LnVzZUNvbnRleHQoU2Nyb2xsQ29udGV4dCk7XG5cbiAgaWYgKCFpdGVtcyB8fCAhaXRlbXMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBmdW5jdGlvbiByZW5kZXJJdGVtKGl0ZW06IE91dGxpbmVOb2RlKSB7XG4gICAgY29uc3QgY2xpY2tIYW5kbGVyID0gKGV2ZW50OiBhbnkpID0+IHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBpZiAob25DbGljaykge1xuICAgICAgICBvbkNsaWNrKGl0ZW0uZGVzdCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIC8vIElmIGFuIGl0ZW0gaGFzIHN1YiB0aXRsZXMsIHJlbmRlciA8T3V0bGluZUl0ZW0gLz5cbiAgICByZXR1cm4gKFxuICAgICAgPGxpXG4gICAgICAgIGtleT17aXRlbS5kZXN0Py50b1N0cmluZygpIHx8IGl0ZW0udGl0bGV9XG4gICAgICAgIGNsYXNzTmFtZT17Y2xhc3NuYW1lcygncmVhZGVyX19vdXRsaW5lLWl0ZW0nLCB7XG4gICAgICAgICAgJ3JlYWRlcl9fb3V0bGluZS1pdGVtLS10YXJnZXQtdmlzaWJsZSc6IGlzT3V0bGluZVRhcmdldFZpc2libGUoaXRlbS5kZXN0KSxcbiAgICAgICAgfSl9PlxuICAgICAgICA8YSBocmVmPVwiI1wiIG9uQ2xpY2s9e2NsaWNrSGFuZGxlcn0+XG4gICAgICAgICAge2l0ZW0udGl0bGV9XG4gICAgICAgIDwvYT5cbiAgICAgICAgPE91dGxpbmVJdGVtIGl0ZW1zPXtpdGVtLml0ZW1zfSBvbkNsaWNrPXtvbkNsaWNrfSAvPlxuICAgICAgPC9saT5cbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIDx1bCBjbGFzc05hbWU9XCJyZWFkZXJfX291dGxpbmUtaXRlbXNcIj57aXRlbXMubWFwKGl0ZW0gPT4gcmVuZGVySXRlbShpdGVtKSl9PC91bD47XG59O1xuIiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5pbXBvcnQgeyBidWlsZE91dGxpbmVQb3NpdGlvbnMsIERvY3VtZW50Q29udGV4dCB9IGZyb20gJy4uLy4uL2NvbnRleHQvRG9jdW1lbnRDb250ZXh0JztcbmltcG9ydCB7IFNjcm9sbENvbnRleHQgfSBmcm9tICcuLi8uLi9jb250ZXh0L1Njcm9sbENvbnRleHQnO1xuaW1wb3J0IHsgTm9kZURlc3RpbmF0aW9uLCBPdXRsaW5lTm9kZSB9IGZyb20gJy4uL3R5cGVzL291dGxpbmUnO1xuaW1wb3J0IHsgT3V0bGluZUl0ZW0gfSBmcm9tICcuL091dGxpbmVJdGVtJztcblxuZXhwb3J0IGNvbnN0IE91dGxpbmU6IFJlYWN0LkZ1bmN0aW9uQ29tcG9uZW50ID0gKHsgLi4uZXh0cmFQcm9wcyB9KSA9PiB7XG4gIGNvbnN0IHsgb3V0bGluZSwgcGRmRG9jUHJveHksIHNldE91dGxpbmUsIHNldE91dGxpbmVQb3NpdGlvbnMgfSA9XG4gICAgUmVhY3QudXNlQ29udGV4dChEb2N1bWVudENvbnRleHQpO1xuICBjb25zdCB7IHNjcm9sbFRvT3V0bGluZVRhcmdldCwgcmVzZXRTY3JvbGxPYnNlcnZlcnMgfSA9IFJlYWN0LnVzZUNvbnRleHQoU2Nyb2xsQ29udGV4dCk7XG5cbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAob3V0bGluZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghcGRmRG9jUHJveHkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBwZGZEb2NQcm94eVxuICAgICAgLmdldE91dGxpbmUoKVxuICAgICAgLnRoZW4oKG91dGxpbmVBcnJheTogQXJyYXk8T3V0bGluZU5vZGU+KSA9PiB7XG4gICAgICAgIHNldE91dGxpbmUob3V0bGluZUFycmF5KTtcbiAgICAgICAgcmV0dXJuIGJ1aWxkT3V0bGluZVBvc2l0aW9ucyhwZGZEb2NQcm94eSwgb3V0bGluZUFycmF5KTtcbiAgICAgIH0pXG4gICAgICAudGhlbihvdXRsaW5lUG9zaXRpb25zID0+IHtcbiAgICAgICAgc2V0T3V0bGluZVBvc2l0aW9ucyhvdXRsaW5lUG9zaXRpb25zKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJlc2V0U2Nyb2xsT2JzZXJ2ZXJzKCk7XG4gICAgICB9KTtcbiAgfSwgW291dGxpbmVdKTtcblxuICBjb25zdCBjbGlja0hhbmRsZXIgPSBSZWFjdC51c2VDYWxsYmFjaygoZGVzdDogTm9kZURlc3RpbmF0aW9uKTogdm9pZCA9PiB7XG4gICAgaWYgKCFkZXN0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHNjcm9sbFRvT3V0bGluZVRhcmdldChkZXN0KTtcbiAgICByZXR1cm47XG4gIH0sIFtdKTtcblxuICBpZiAoIXBkZkRvY1Byb3h5KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gKFxuICAgIDxkaXYgY2xhc3NOYW1lPVwicmVhZGVyX19vdXRsaW5lXCIgey4uLmV4dHJhUHJvcHN9PlxuICAgICAgeyEhb3V0bGluZSAmJiA8T3V0bGluZUl0ZW0gaXRlbXM9e291dGxpbmV9IG9uQ2xpY2s9e2NsaWNrSGFuZGxlcn0gLz59XG4gICAgPC9kaXY+XG4gICk7XG59O1xuIiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5pbXBvcnQgeyBEb2N1bWVudENvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L0RvY3VtZW50Q29udGV4dCc7XG5pbXBvcnQgeyBUcmFuc2Zvcm1Db250ZXh0IH0gZnJvbSAnLi4vY29udGV4dC9UcmFuc2Zvcm1Db250ZXh0JztcbmltcG9ydCB7IGNvbXB1dGVQYWdlU3R5bGUgfSBmcm9tICcuLi91dGlscy9zdHlsZSc7XG5pbXBvcnQgeyBCb3VuZGluZ0JveCB9IGZyb20gJy4vQm91bmRpbmdCb3gnO1xuXG5leHBvcnQgdHlwZSBQcm9wcyA9IHtcbiAgY2hpbGRyZW4/OiBSZWFjdC5SZWFjdEVsZW1lbnQ8dHlwZW9mIEJvdW5kaW5nQm94PiB8IEFycmF5PFJlYWN0LlJlYWN0RWxlbWVudDx0eXBlb2YgQm91bmRpbmdCb3g+Pjtcbn07XG5cbmV4cG9ydCBjb25zdCBPdmVybGF5OiBSZWFjdC5GdW5jdGlvbkNvbXBvbmVudDxQcm9wcz4gPSAoeyBjaGlsZHJlbiwgLi4uZXh0cmFQcm9wcyB9OiBQcm9wcykgPT4ge1xuICBjb25zdCB7IHBhZ2VEaW1lbnNpb25zIH0gPSBSZWFjdC51c2VDb250ZXh0KERvY3VtZW50Q29udGV4dCk7XG4gIGNvbnN0IHsgcm90YXRpb24sIHNjYWxlIH0gPSBSZWFjdC51c2VDb250ZXh0KFRyYW5zZm9ybUNvbnRleHQpO1xuXG4gIGNvbnN0IGdldE92ZXJsYXlTdHlsZSA9IFJlYWN0LnVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICByZXR1cm4gY29tcHV0ZVBhZ2VTdHlsZShwYWdlRGltZW5zaW9ucywgcm90YXRpb24sIHNjYWxlKTtcbiAgfSwgW3BhZ2VEaW1lbnNpb25zLCByb3RhdGlvbiwgc2NhbGVdKTtcblxuICByZXR1cm4gKFxuICAgIDxkaXYgY2xhc3NOYW1lPVwicmVhZGVyX19wYWdlLW92ZXJsYXlcIiBzdHlsZT17Z2V0T3ZlcmxheVN0eWxlKCl9IHsuLi5leHRyYVByb3BzfT5cbiAgICAgIHtjaGlsZHJlbn1cbiAgICA8L2Rpdj5cbiAgKTtcbn07XG4iLCJpbXBvcnQgeyBOdWxsYWJsZSB9IGZyb20gJy4uL2NvbXBvbmVudHMvdHlwZXMvdXRpbHMnO1xuXG50eXBlIFZpc2libGVFbGVtZW50ID0gTnVsbGFibGU8bnVtYmVyIHwgc3RyaW5nPjtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldE1heFZpc2libGVFbGVtZW50KHZpc2libGVFbGVtZW50czogTWFwPFZpc2libGVFbGVtZW50LCBudW1iZXI+KTogVmlzaWJsZUVsZW1lbnQge1xuICBsZXQgbWF4VmlzaWJsZUtleSA9IG51bGw7XG4gIGxldCBtYXhSYXRpbyA9IDA7XG4gIGZvciAoY29uc3QgW3Zpc2libGVLZXksIHJhdGlvXSBvZiB2aXNpYmxlRWxlbWVudHMpIHtcbiAgICBpZiAobWF4UmF0aW8gPCByYXRpbykge1xuICAgICAgbWF4VmlzaWJsZUtleSA9IHZpc2libGVLZXk7XG4gICAgICBtYXhSYXRpbyA9IHJhdGlvO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbWF4VmlzaWJsZUtleTtcbn1cbiIsImltcG9ydCBjbGFzc25hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5pbXBvcnQgeyBEb2N1bWVudENvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L0RvY3VtZW50Q29udGV4dCc7XG5pbXBvcnQgeyBTY3JvbGxDb250ZXh0IH0gZnJvbSAnLi4vY29udGV4dC9TY3JvbGxDb250ZXh0JztcbmltcG9ydCB7IGdldE1heFZpc2libGVFbGVtZW50IH0gZnJvbSAnLi4vdXRpbHMvTWF4VmlzaWJsZUVsZW1lbnQnO1xuXG5leHBvcnQgdHlwZSBQcm9wcyA9IHtcbiAgY2xhc3NOYW1lPzogc3RyaW5nO1xufTtcblxudHlwZSBUT0RPX19USU1FUiA9IGFueTtcblxuY29uc3QgREVMQVlfU0NST0xMX1RJTUVfT1VUX01TID0gMTAwMDtcblxuZXhwb3J0IGNvbnN0IFBhZ2VOdW1iZXJDb250cm9sOiBSZWFjdC5GdW5jdGlvbkNvbXBvbmVudDxQcm9wcz4gPSAoeyBjbGFzc05hbWUgfTogUHJvcHMpID0+IHtcbiAgY29uc3QgZGVsYXlUaW1lclJlZiA9IFJlYWN0LnVzZVJlZjxUT0RPX19USU1FUj4oKTtcbiAgY29uc3QgeyBudW1QYWdlcyB9ID0gUmVhY3QudXNlQ29udGV4dChEb2N1bWVudENvbnRleHQpO1xuICBjb25zdCB7IHNjcm9sbFRvUGFnZSwgdmlzaWJsZVBhZ2VSYXRpb3MgfSA9IFJlYWN0LnVzZUNvbnRleHQoU2Nyb2xsQ29udGV4dCk7XG4gIGNvbnN0IFttaW5QYWdlLCBzZXRNaW5QYWdlXSA9IFJlYWN0LnVzZVN0YXRlPG51bWJlcj4oMCk7XG4gIGNvbnN0IFt1c2VySW5wdXQsIHNldFVzZXJJbnB1dF0gPSBSZWFjdC51c2VTdGF0ZTxzdHJpbmc+KCcwJyk7XG5cbiAgLy8gSW5pdGlhbGl6ZSBwYWdlIGNvbnRyb2wgZWxlbWVudFxuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChudW1QYWdlcyAhPSAwKSB7XG4gICAgICBzZXRNaW5QYWdlKDEpO1xuICAgIH1cbiAgfSwgW251bVBhZ2VzXSk7XG5cbiAgLy8gRXZlcnl0aW1lIHdlIHNjcm9sbCB0aHJvdWdoIHRoZSBwYWdlIHRoaXMgdXNlRWZmZWN0XG4gIC8vIHdpbGwgdHJpZ2dlciBhbmQgc2V0IGN1cnJlbnQgcGFnZSBiYXNlZCBvbiBvdXIgY3VycmVudFxuICAvLyBzY3JvbGwgcG9zaXRpb25cbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAodmlzaWJsZVBhZ2VSYXRpb3Muc2l6ZSAhPT0gMCkge1xuICAgICAgY29uc3QgbWF4VmlzaWJsZVBhZ2VOdW1iZXIgPSBnZXRNYXhWaXNpYmxlRWxlbWVudCh2aXNpYmxlUGFnZVJhdGlvcyk7XG4gICAgICBpZiAobWF4VmlzaWJsZVBhZ2VOdW1iZXIpIHtcbiAgICAgICAgc2V0VXNlcklucHV0KG1heFZpc2libGVQYWdlTnVtYmVyLnRvU3RyaW5nKCkpO1xuICAgICAgfVxuICAgIH1cbiAgfSwgW3Zpc2libGVQYWdlUmF0aW9zXSk7XG5cbiAgY29uc3Qgb25QYWdlTnVtYmVyQ2hhbmdlID0gUmVhY3QudXNlQ2FsbGJhY2soXG4gICAgKGV2ZW50OiBSZWFjdC5DaGFuZ2VFdmVudDxIVE1MSW5wdXRFbGVtZW50PikgPT4ge1xuICAgICAgY29uc3QgeyB2YWx1ZSB9ID0gZXZlbnQuY3VycmVudFRhcmdldDtcbiAgICAgIC8vIERlY2ltYWwgY2FzZVxuICAgICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKSkge1xuICAgICAgICBzZXRVc2VySW5wdXQocGFyc2VJbnQodmFsdWUsIDEwKS50b1N0cmluZygpKTtcbiAgICAgIH1cblxuICAgICAgc2V0VXNlcklucHV0KHZhbHVlKTtcbiAgICAgIGlmIChkZWxheVRpbWVyUmVmLmN1cnJlbnQpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KGRlbGF5VGltZXJSZWYuY3VycmVudCk7XG4gICAgICB9XG5cbiAgICAgIC8vIEFmdGVyIHVzZXIgaW5wdXQgdGhlIHBhZ2UgdGhhdCB0aGV5IHdhbnQgdG8gc2Nyb2xsIHRvXG4gICAgICAvLyBvdXIgcmVmIHdpbGwgc3RhcnQgc2V0dGluZyBhIGRlbGF5IGFyb3VuZCAxcyBiZWZvcmUgc2Nyb2xsXG4gICAgICAvLyB0byB0aGUgcG9zaXRpb24gdGhhdCB1c2VyIGRlc2lyZVxuICAgICAgY29uc3QgbmV3UGFnZU51bWJlciA9IHBhcnNlSW50KHZhbHVlLCAxMCk7XG4gICAgICBpZiAobmV3UGFnZU51bWJlciA+PSBtaW5QYWdlICYmIG5ld1BhZ2VOdW1iZXIgPD0gbnVtUGFnZXMpIHtcbiAgICAgICAgZGVsYXlUaW1lclJlZi5jdXJyZW50ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgc2Nyb2xsVG9QYWdlKHsgcGFnZU51bWJlcjogbmV3UGFnZU51bWJlciB9KTtcbiAgICAgICAgfSwgREVMQVlfU0NST0xMX1RJTUVfT1VUX01TKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIFttaW5QYWdlLCBudW1QYWdlcywgc2Nyb2xsVG9QYWdlXVxuICApO1xuXG4gIGNvbnN0IGhhbmRsZUJsdXIgPSBSZWFjdC51c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgaWYgKGRlbGF5VGltZXJSZWYuY3VycmVudCkge1xuICAgICAgY2xlYXJUaW1lb3V0KGRlbGF5VGltZXJSZWYuY3VycmVudCk7XG4gICAgfVxuICAgIGNvbnN0IHBhZ2VOdW1iZXIgPSBwYXJzZUludCh1c2VySW5wdXQsIDEwKTtcbiAgICBpZiAoTnVtYmVyLmlzTmFOKHBhZ2VOdW1iZXIpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZGVsYXlUaW1lclJlZi5jdXJyZW50ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBzY3JvbGxUb1BhZ2UoeyBwYWdlTnVtYmVyOiBwYWdlTnVtYmVyIH0pO1xuICAgIH0sIERFTEFZX1NDUk9MTF9USU1FX09VVF9NUyk7XG4gIH0sIFt1c2VySW5wdXQsIHNjcm9sbFRvUGFnZV0pO1xuXG4gIHJldHVybiAoXG4gICAgPGRpdiBjbGFzc05hbWU9e2NsYXNzbmFtZXMoJ3JlYWRlcl9fcGFnZS1udW1iZXItY29udHJvbCcsIGNsYXNzTmFtZSl9PlxuICAgICAgPGlucHV0XG4gICAgICAgIGFyaWEtbGFiZWw9XCJDdXJyZW50IFBhZ2VcIlxuICAgICAgICBjbGFzc05hbWU9XCJyZWFkZXJfX3BhZ2UtbnVtYmVyLWNvbnRyb2xfX2N1cnJlbnQtcGFnZVwiXG4gICAgICAgIHR5cGU9XCJudW1iZXJcIlxuICAgICAgICBuYW1lPVwiY3VycmVudFBhZ2VcIlxuICAgICAgICB2YWx1ZT17dXNlcklucHV0fVxuICAgICAgICBvbkNoYW5nZT17b25QYWdlTnVtYmVyQ2hhbmdlfVxuICAgICAgICBvbkJsdXI9e2hhbmRsZUJsdXJ9XG4gICAgICAvPlxuICAgICAgPHNwYW4gY2xhc3NOYW1lPVwicmVhZGVyX19wYWdlLW51bWJlci1jb250cm9sX19zZXBhcmF0b3JcIj4vPC9zcGFuPlxuICAgICAgPHNwYW4gYXJpYS1sYWJlbD1cIlRvdGFsIFBhZ2VzXCIgY2xhc3NOYW1lPVwicmVhZGVyX19wYWdlLW51bWJlci1jb250cm9sX190b3RhbC1wYWdlc1wiPlxuICAgICAgICB7bnVtUGFnZXN9XG4gICAgICA8L3NwYW4+XG4gICAgPC9kaXY+XG4gICk7XG59O1xuIiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgcGRmanMgfSBmcm9tICdyZWFjdC1wZGYnO1xuXG5pbXBvcnQgeyBQYWdlTnVtYmVyIH0gZnJvbSAnLi4vY29tcG9uZW50cy90eXBlcy9wYWdlJztcbmltcG9ydCB7IE51bGxhYmxlIH0gZnJvbSAnLi4vY29tcG9uZW50cy90eXBlcy91dGlscyc7XG5pbXBvcnQgeyBsb2dQcm92aWRlcldhcm5pbmcgfSBmcm9tICcuLi91dGlscy9wcm92aWRlcic7XG5pbXBvcnQgeyBQYWdlUm90YXRpb24gfSBmcm9tICcuLi91dGlscy9yb3RhdGUnO1xuXG5leHBvcnQgdHlwZSBSZW5kZXJTdGF0ZSA9IHtcbiAgcHJvbWlzZTogUHJvbWlzZTxzdHJpbmc+O1xuICBvYmplY3RVUkw6IE51bGxhYmxlPHN0cmluZz47XG59O1xuXG5leHBvcnQgdHlwZSBQYWdlTnVtYmVyVG9SZW5kZXJTdGF0ZU1hcCA9IE1hcDxudW1iZXIsIFJlbmRlclN0YXRlPjtcblxuZXhwb3J0IGludGVyZmFjZSBJUGFnZVJlbmRlckNvbnRleHQge1xuICBwYWdlUmVuZGVyU3RhdGVzOiBQYWdlTnVtYmVyVG9SZW5kZXJTdGF0ZU1hcDtcbiAgZ2V0T2JqZWN0VVJMRm9yUGFnZTogKHBhZ2VOdW1iZXI6IFBhZ2VOdW1iZXIpID0+IE51bGxhYmxlPHN0cmluZz47XG4gIGlzQnVpbGRpbmdPYmplY3RVUkxGb3JQYWdlOiAocGFnZU51bWJlcjogUGFnZU51bWJlcikgPT4gYm9vbGVhbjtcbiAgYnVpbGRPYmplY3RVUkxGb3JQYWdlOiAocGFnZU51bWJlcjogUGFnZU51bWJlcikgPT4gUHJvbWlzZTxzdHJpbmc+O1xufVxuXG5leHBvcnQgY29uc3QgUGFnZVJlbmRlckNvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PElQYWdlUmVuZGVyQ29udGV4dD4oe1xuICBwYWdlUmVuZGVyU3RhdGVzOiBuZXcgTWFwKCksXG4gIGdldE9iamVjdFVSTEZvclBhZ2U6IGFyZ3MgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgZ2V0T2JqZWN0VVJMRm9yUGFnZSgke0pTT04uc3RyaW5naWZ5KGFyZ3MpfSlgLCAnUGFnZVJlbmRlckNvbnRleHQnKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfSxcbiAgaXNCdWlsZGluZ09iamVjdFVSTEZvclBhZ2U6IGFyZ3MgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgaXNCdWlsZGluZ09iamVjdFVSTEZvclBhZ2UoJHtKU09OLnN0cmluZ2lmeShhcmdzKX0pYCwgJ1BhZ2VSZW5kZXJDb250ZXh0Jyk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9LFxuICBidWlsZE9iamVjdFVSTEZvclBhZ2U6IGFyZ3MgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgYnVpbGRPYmplY3RVUkxGb3JQYWdlKCR7SlNPTi5zdHJpbmdpZnkoYXJncyl9KWAsICdQYWdlUmVuZGVyQ29udGV4dCcpO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoJycpO1xuICB9LFxufSk7XG5cbmV4cG9ydCBmdW5jdGlvbiB1c2VQYWdlUmVuZGVyQ29udGV4dFByb3BzKHtcbiAgcGRmRG9jUHJveHksXG4gIHNjYWxlLFxuICByb3RhdGlvbixcbiAgem9vbU11bHRpcGxpZXIsXG4gIHZpc2libGVQYWdlUmF0aW9zLFxufToge1xuICBwZGZEb2NQcm94eT86IHBkZmpzLlBERkRvY3VtZW50UHJveHk7XG4gIHNjYWxlOiBudW1iZXI7XG4gIHJvdGF0aW9uOiBQYWdlUm90YXRpb247XG4gIHpvb21NdWx0aXBsaWVyOiBudW1iZXI7XG4gIHZpc2libGVQYWdlUmF0aW9zOiBNYXA8bnVtYmVyLCBudW1iZXI+O1xufSk6IElQYWdlUmVuZGVyQ29udGV4dCB7XG4gIGNvbnN0IFtwYWdlUmVuZGVyU3RhdGVzLCBfc2V0UGFnZVJlbmRlclN0YXRlc10gPSBSZWFjdC51c2VTdGF0ZTxQYWdlTnVtYmVyVG9SZW5kZXJTdGF0ZU1hcD4oXG4gICAgKCkgPT4ge1xuICAgICAgY29uc3QgbWFwID0gbmV3IE1hcCgpO1xuICAgICAgT2JqZWN0LmZyZWV6ZShtYXApO1xuICAgICAgcmV0dXJuIG1hcDtcbiAgICB9XG4gICk7XG5cbiAgLy8gQmVjYXVzZSByZW5kZXJpbmcgYSBwYWdlIGlzIGFzeW5jLCB3ZSB3aWxsIGxvc2UgdGhlIGN1cnJlbnQgcGFnZVJlbmRlclN0YXRlc1xuICAvLyBUaGlzIHJlZiB0cmljayBhbGxvd3MgdGhlIGxhdGVzdCB0byBiZSBhY2Nlc3NpYmxlIHdoZW4gdGhlIG9iamVjdFVSTCBpcyByZWFkeVxuICBjb25zdCBwYWdlUmVuZGVyU3RhdGVzUmVmID0gUmVhY3QudXNlUmVmKHBhZ2VSZW5kZXJTdGF0ZXMpO1xuICBjb25zdCBzZXRQYWdlUmVuZGVyU3RhdGVzID0gUmVhY3QudXNlQ2FsbGJhY2soXG4gICAgKHBhZ2VSZW5kZXJTdGF0ZXM6IFBhZ2VOdW1iZXJUb1JlbmRlclN0YXRlTWFwKSA9PiB7XG4gICAgICBwYWdlUmVuZGVyU3RhdGVzUmVmLmN1cnJlbnQgPSBwYWdlUmVuZGVyU3RhdGVzO1xuICAgICAgX3NldFBhZ2VSZW5kZXJTdGF0ZXMocGFnZVJlbmRlclN0YXRlcyk7XG4gICAgfSxcbiAgICBbcGFnZVJlbmRlclN0YXRlc1JlZl1cbiAgKTtcblxuICBjb25zdCBpc0J1aWxkaW5nT2JqZWN0VVJMRm9yUGFnZSA9IFJlYWN0LnVzZUNhbGxiYWNrKFxuICAgICh7IHBhZ2VOdW1iZXIsIHBhZ2VJbmRleCB9OiBQYWdlTnVtYmVyKTogYm9vbGVhbiA9PiB7XG4gICAgICBpZiAodHlwZW9mIHBhZ2VJbmRleCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgcGFnZU51bWJlciA9IHBhZ2VJbmRleCArIDE7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHBhZ2VOdW1iZXIgIT09ICdudW1iZXInKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHN0YXRlID0gcGFnZVJlbmRlclN0YXRlcy5nZXQocGFnZU51bWJlcik7XG4gICAgICBpZiAoIXN0YXRlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiAhc3RhdGUub2JqZWN0VVJMO1xuICAgIH0sXG4gICAgW3BhZ2VSZW5kZXJTdGF0ZXNdXG4gICk7XG5cbiAgY29uc3QgZ2V0T2JqZWN0VVJMRm9yUGFnZSA9IFJlYWN0LnVzZUNhbGxiYWNrKFxuICAgICh7IHBhZ2VOdW1iZXIsIHBhZ2VJbmRleCB9OiBQYWdlTnVtYmVyKTogTnVsbGFibGU8c3RyaW5nPiA9PiB7XG4gICAgICBpZiAodHlwZW9mIHBhZ2VJbmRleCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgcGFnZU51bWJlciA9IHBhZ2VJbmRleCArIDE7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHBhZ2VOdW1iZXIgIT09ICdudW1iZXInKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHBhZ2VSZW5kZXJTdGF0ZXMuZ2V0KHBhZ2VOdW1iZXIpPy5vYmplY3RVUkwgfHwgbnVsbDtcbiAgICB9LFxuICAgIFtwYWdlUmVuZGVyU3RhdGVzXVxuICApO1xuXG4gIGNvbnN0IGJ1aWxkT2JqZWN0VVJMRm9yUGFnZSA9IFJlYWN0LnVzZUNhbGxiYWNrKFxuICAgICh7IHBhZ2VOdW1iZXIsIHBhZ2VJbmRleCB9OiBQYWdlTnVtYmVyKTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgICAgIGlmICh0eXBlb2YgcGFnZUluZGV4ID09PSAnbnVtYmVyJykge1xuICAgICAgICBwYWdlTnVtYmVyID0gcGFnZUluZGV4ICsgMTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgcGFnZU51bWJlciAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdwcm9wIFwicGFnZU51bWJlclwiIGlzIG5vdCBhIG51bWJlcicpO1xuICAgICAgfVxuICAgICAgaWYgKCFwZGZEb2NQcm94eSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBidWlsZCBhIHBhZ2UgdW50aWwgYSBcInBkZkRvY1Byb3h5XCIgaXMgc2V0IG9uIERvY3VtZW50Q29udGV4dCcpO1xuICAgICAgfVxuXG4gICAgICAvLyBEb24ndCBuZWVkIHRvIHN0YXJ0IGFub3RoZXIgdGFzayBpZiBhbHJlYWR5IHJlbmRlcmVkXG4gICAgICBjb25zdCBleGlzdGluZ1Byb21pc2UgPSBwYWdlUmVuZGVyU3RhdGVzLmdldChwYWdlTnVtYmVyKT8ucHJvbWlzZTtcbiAgICAgIGlmIChleGlzdGluZ1Byb21pc2UpIHtcbiAgICAgICAgcmV0dXJuIGV4aXN0aW5nUHJvbWlzZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcHJvbWlzZSA9IGJ1aWxkUGFnZU9iamVjdFVSTCh7XG4gICAgICAgIHBhZ2VOdW1iZXIsXG4gICAgICAgIHBkZkRvY1Byb3h5LFxuICAgICAgICBzY2FsZSxcbiAgICAgICAgcm90YXRpb24sXG4gICAgICAgIHpvb21NdWx0aXBsaWVyLFxuICAgICAgfSk7XG4gICAgICBjb25zdCByZW5kZXJTdGF0ZTogUmVuZGVyU3RhdGUgPSB7XG4gICAgICAgIHByb21pc2UsXG4gICAgICAgIG9iamVjdFVSTDogbnVsbCxcbiAgICAgIH07XG4gICAgICBwcm9taXNlLnRoZW4ob2JqZWN0VVJMID0+IHtcbiAgICAgICAgcmVuZGVyU3RhdGUub2JqZWN0VVJMID0gb2JqZWN0VVJMO1xuICAgICAgICBjb25zdCBuZXdQYWdlUmVuZGVyU3RhdGVzID0gbmV3IE1hcChwYWdlUmVuZGVyU3RhdGVzUmVmLmN1cnJlbnQpO1xuICAgICAgICBPYmplY3QuZnJlZXplKG5ld1BhZ2VSZW5kZXJTdGF0ZXMpO1xuICAgICAgICBzZXRQYWdlUmVuZGVyU3RhdGVzKG5ld1BhZ2VSZW5kZXJTdGF0ZXMpO1xuICAgICAgfSk7XG4gICAgICBjb25zdCBuZXdQYWdlUmVuZGVyU3RhdGVzID0gbmV3IE1hcChwYWdlUmVuZGVyU3RhdGVzUmVmLmN1cnJlbnQpO1xuICAgICAgbmV3UGFnZVJlbmRlclN0YXRlcy5zZXQocGFnZU51bWJlciwgcmVuZGVyU3RhdGUpO1xuICAgICAgT2JqZWN0LmZyZWV6ZShuZXdQYWdlUmVuZGVyU3RhdGVzKTtcbiAgICAgIHNldFBhZ2VSZW5kZXJTdGF0ZXMobmV3UGFnZVJlbmRlclN0YXRlcyk7XG4gICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9LFxuICAgIFtwYWdlUmVuZGVyU3RhdGVzLCBwZGZEb2NQcm94eSwgc2NhbGUsIHJvdGF0aW9uLCB6b29tTXVsdGlwbGllcl1cbiAgKTtcblxuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGZvciAoY29uc3QgcGFnZU51bWJlciBvZiB2aXNpYmxlUGFnZVJhdGlvcy5rZXlzKCkpIHtcbiAgICAgIGlmIChwYWdlUmVuZGVyU3RhdGVzLmhhcyhwYWdlTnVtYmVyKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGJ1aWxkT2JqZWN0VVJMRm9yUGFnZSh7IHBhZ2VOdW1iZXIgfSk7XG4gICAgfVxuICB9LCBbcGFnZVJlbmRlclN0YXRlcywgdmlzaWJsZVBhZ2VSYXRpb3NdKTtcblxuICByZXR1cm4ge1xuICAgIHBhZ2VSZW5kZXJTdGF0ZXMsXG4gICAgZ2V0T2JqZWN0VVJMRm9yUGFnZSxcbiAgICBpc0J1aWxkaW5nT2JqZWN0VVJMRm9yUGFnZSxcbiAgICBidWlsZE9iamVjdFVSTEZvclBhZ2UsXG4gIH07XG59XG5cbi8vIEdlbmVyYXRlIGFuIG9iamVjdCB1cmwgZm9yIGEgZ2l2ZW4gcGFnZSwgcmVuZGVyZWQgaW4gYSBzaGFyZWQgY2FudmFzXG5hc3luYyBmdW5jdGlvbiBidWlsZFBhZ2VPYmplY3RVUkwoe1xuICBwYWdlTnVtYmVyLFxuICBwZGZEb2NQcm94eSxcbiAgc2NhbGUgPSAxLFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIHJvdGF0aW9uID0gUGFnZVJvdGF0aW9uLlJvdGF0ZTAsXG4gIHpvb21NdWx0aXBsaWVyID0gMS4yLFxuICBpbWFnZVR5cGUgPSAnaW1hZ2UvcG5nJyxcbiAgaW1hZ2VRdWFsaXR5ID0gMS4wLFxufToge1xuICBwYWdlTnVtYmVyOiBudW1iZXI7XG4gIHBkZkRvY1Byb3h5OiBwZGZqcy5QREZEb2N1bWVudFByb3h5O1xuICBzY2FsZT86IG51bWJlcjtcbiAgcm90YXRpb24/OiBQYWdlUm90YXRpb247XG4gIHpvb21NdWx0aXBsaWVyPzogbnVtYmVyO1xuICBpbWFnZVR5cGU/OiBzdHJpbmc7XG4gIGltYWdlUXVhbGl0eT86IG51bWJlcjtcbn0pOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBwYWdlUHJveHkgPSBhd2FpdCBwZGZEb2NQcm94eS5nZXRQYWdlKHBhZ2VOdW1iZXIpO1xuXG4gIGNvbnN0IGJsb2I6IE51bGxhYmxlPEJsb2I+ID0gYXdhaXQgdXNlUmVuZGVyQ2FudmFzKGFzeW5jIGNhbnZhcyA9PiB7XG4gICAgLy8gUmVuZGVyIHBhZ2UgaW4gYSBjYW52YXNcbiAgICBjb25zdCB2aWV3cG9ydCA9IHBhZ2VQcm94eS5nZXRWaWV3cG9ydCh7IHNjYWxlOiBzY2FsZSAqIHpvb21NdWx0aXBsaWVyICogZGV2aWNlUGl4ZWxSYXRpbyB9KTtcbiAgICBjYW52YXMuaGVpZ2h0ID0gdmlld3BvcnQuaGVpZ2h0O1xuICAgIGNhbnZhcy53aWR0aCA9IHZpZXdwb3J0LndpZHRoO1xuICAgIGNvbnN0IGNhbnZhc0NvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICBpZiAoIWNhbnZhc0NvbnRleHQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2FudmFzIHdhcyB1bmFibGUgdG8gZ2V0IGEgY29udGV4dCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHJlbmRlclRhc2sgPSBwYWdlUHJveHkucmVuZGVyKHtcbiAgICAgIGNhbnZhc0NvbnRleHQsXG4gICAgICB2aWV3cG9ydCxcbiAgICB9KTtcbiAgICBhd2FpdCByZW5kZXJUYXNrLnByb21pc2U7XG5cbiAgICBhd2FpdCBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgMTYpKTtcblxuICAgIC8vIEZldGNoIGEgYmxvYiBmb3IgYW4gaW1hZ2Ugb2YgdGhlIGNhbnZhc1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBjYW52YXMudG9CbG9iKGJsb2IgPT4gcmVzb2x2ZShibG9iKSwgaW1hZ2VUeXBlLCBpbWFnZVF1YWxpdHkpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gQ29udmVydCBibG9iIGltYWdlIHRvIG9iamVjdCB1cmxcbiAgaWYgKCFibG9iKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1bmFibGUgdG8gY3JlYXRlIGltYWdlIGZyb20gcGFnZScpO1xuICB9XG4gIHJldHVybiBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xufVxuXG5sZXQgcmVuZGVyQ2FudmFzOiBOdWxsYWJsZTxIVE1MQ2FudmFzRWxlbWVudD4gPSBudWxsO1xuXG4vLyBHZXQgb3IgY3JlYXRlIGEgc2hhcmVkIGNhbnZhcyBmb3IgcmVuZGVyaW5nIHBhZ2VzIGluXG5mdW5jdGlvbiBnZXRSZW5kZXJDYW52YXMoKTogSFRNTENhbnZhc0VsZW1lbnQge1xuICBpZiAoIXJlbmRlckNhbnZhcykge1xuICAgIHJlbmRlckNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICB9XG4gIHJldHVybiByZW5kZXJDYW52YXM7XG59XG5cbmxldCBuZXh0Q2FudmFzVXNlOiBQcm9taXNlPGFueT4gPSBQcm9taXNlLnJlc29sdmUoKTtcblxuLy8gVXNlIHRoZSBzaGFyZWQgY2FudmFzIHRvIHJlbmRlciBhIHBhZ2UsIHVzaW5nIHByb21pc2VzIHRvIGNyZWF0ZSBhIHF1ZXVlXG5hc3luYyBmdW5jdGlvbiB1c2VSZW5kZXJDYW52YXM8VD4oY2FsbGJhY2s6IChjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50KSA9PiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZW1wdHktZnVuY3Rpb25cbiAgbGV0IHJlc29sdmUgPSAoX3ZhbHVlOiBUIHwgUHJvbWlzZUxpa2U8VD4pID0+IHt9O1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWVtcHR5LWZ1bmN0aW9uXG4gIGxldCByZWplY3QgPSAoX3JlYXNvbjogYW55KSA9PiB7fTtcbiAgY29uc3QgcHJvbSA9IG5ldyBQcm9taXNlPFQ+KChfcmVzb2x2ZSwgX3JlamVjdCkgPT4ge1xuICAgIHJlc29sdmUgPSBfcmVzb2x2ZTtcbiAgICByZWplY3QgPSBfcmVqZWN0O1xuICB9KTtcbiAgbmV4dENhbnZhc1VzZSA9IG5leHRDYW52YXNVc2UudGhlbigoKSA9PiBjYWxsYmFjayhnZXRSZW5kZXJDYW52YXMoKSkudGhlbihyZXNvbHZlLCByZWplY3QpKTtcbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcHJvbTtcbiAgYXdhaXQgbmV3IFByb21pc2UocmVzID0+IHNldFRpbWVvdXQocmVzLCAxNikpOyAvLyBHaXZlIHNvbWUgdGltZSBiZXR3ZWVuIHJlbmRlcnNcbiAgcmV0dXJuIHJlc3VsdDtcbn1cbiIsImltcG9ydCBjbGFzc25hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgUGFnZSB9IGZyb20gJ3JlYWN0LXBkZic7XG5pbXBvcnQgeyBSZW5kZXJGdW5jdGlvbiB9IGZyb20gJ3JlYWN0LXBkZi9kaXN0L1BhZ2UnO1xuXG5pbXBvcnQgeyBEb2N1bWVudENvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L0RvY3VtZW50Q29udGV4dCc7XG5pbXBvcnQgeyBQYWdlUmVuZGVyQ29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvUGFnZVJlbmRlckNvbnRleHQnO1xuaW1wb3J0IHsgVHJhbnNmb3JtQ29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvVHJhbnNmb3JtQ29udGV4dCc7XG5pbXBvcnQgeyBnZW5lcmF0ZVBhZ2VJZEZyb21JbmRleCB9IGZyb20gJy4uL3V0aWxzL3Njcm9sbCc7XG5pbXBvcnQgeyBjb21wdXRlUGFnZVN0eWxlLCBnZXRQYWdlV2lkdGggfSBmcm9tICcuLi91dGlscy9zdHlsZSc7XG5pbXBvcnQgeyBIaWdobGlnaHRPdmVybGF5IH0gZnJvbSAnLi9IaWdobGlnaHRPdmVybGF5JztcbmltcG9ydCB7IE92ZXJsYXkgfSBmcm9tICcuL092ZXJsYXknO1xuXG4vKipcbiAqIEEgc3Vic2V0IG9mIHJlYWN0LXBkZidzIFBhZ2UgY29tcG9uZW50IHByb3BzIGV4cG9zZWQgYnkgdGhpcyB3cmFwcGVyXG4gKi9cbmV4cG9ydCB0eXBlIFBhZ2VQcm9wcyA9IHtcbiAgZXJyb3I/OiBzdHJpbmcgfCBSZWFjdC5SZWFjdEVsZW1lbnQgfCBSZW5kZXJGdW5jdGlvbjtcbiAgbG9hZGluZz86IHN0cmluZyB8IFJlYWN0LlJlYWN0RWxlbWVudCB8IFJlbmRlckZ1bmN0aW9uO1xuICBub0RhdGE/OiBzdHJpbmcgfCBSZWFjdC5SZWFjdEVsZW1lbnQgfCBSZW5kZXJGdW5jdGlvbjtcbiAgcGFnZUluZGV4OiBudW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBQcm9wcyA9IHtcbiAgY2xhc3NOYW1lPzogc3RyaW5nO1xuICBsb2FkaW5nQ29udGVudEZvckJ1aWxkaW5nSW1hZ2U/OiBSZWFjdC5SZWFjdEVsZW1lbnQ7XG4gIGNoaWxkcmVuPzogUmVhY3QuUmVhY3RFbGVtZW50PHR5cGVvZiBIaWdobGlnaHRPdmVybGF5IHwgdHlwZW9mIE92ZXJsYXk+O1xufSAmIFBhZ2VQcm9wcztcblxuZXhwb3J0IGNvbnN0IFBhZ2VXcmFwcGVyOiBSZWFjdC5GdW5jdGlvbkNvbXBvbmVudDxQcm9wcz4gPSAoe1xuICBjaGlsZHJlbixcbiAgZXJyb3IsXG4gIGxvYWRpbmcsXG4gIGxvYWRpbmdDb250ZW50Rm9yQnVpbGRpbmdJbWFnZSxcbiAgbm9EYXRhLFxuICBwYWdlSW5kZXgsXG4gIC4uLmV4dHJhUHJvcHNcbn06IFByb3BzKSA9PiB7XG4gIGNvbnN0IHsgcm90YXRpb24sIHNjYWxlIH0gPSBSZWFjdC51c2VDb250ZXh0KFRyYW5zZm9ybUNvbnRleHQpO1xuICBjb25zdCB7IHBhZ2VEaW1lbnNpb25zLCBnZXRPdXRsaW5lVGFyZ2V0cyB9ID0gUmVhY3QudXNlQ29udGV4dChEb2N1bWVudENvbnRleHQpO1xuICBjb25zdCB7IGdldE9iamVjdFVSTEZvclBhZ2UsIGlzQnVpbGRpbmdPYmplY3RVUkxGb3JQYWdlIH0gPSBSZWFjdC51c2VDb250ZXh0KFBhZ2VSZW5kZXJDb250ZXh0KTtcblxuICBjb25zdCBvYmplY3RVUkxGb3JQYWdlID0gZ2V0T2JqZWN0VVJMRm9yUGFnZSh7IHBhZ2VJbmRleCB9KTtcbiAgY29uc3QgaXNCdWlsZGluZ1BhZ2VJbWFnZSA9IGlzQnVpbGRpbmdPYmplY3RVUkxGb3JQYWdlKHsgcGFnZUluZGV4IH0pO1xuXG4gIC8vIERvbid0IGRpc3BsYXkgdW50aWwgd2UgaGF2ZSBwYWdlIHNpemUgZGF0YVxuICAvLyBUT0RPOiBIYW5kbGUgdGhpcyBuaWNlciBzbyB3ZSBkaXNwbGF5IGVpdGhlciB0aGUgbG9hZGluZyBvciBlcnJvciB0cmVhdG1lbnRcbiAgaWYgKCFwYWdlRGltZW5zaW9ucykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgZ2V0UGFnZVN0eWxlID0gUmVhY3QudXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIGNvbnN0IHN0eWxlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSBjb21wdXRlUGFnZVN0eWxlKHBhZ2VEaW1lbnNpb25zLCByb3RhdGlvbiwgc2NhbGUpO1xuICAgIGlmIChvYmplY3RVUkxGb3JQYWdlKSB7XG4gICAgICBzdHlsZXMuYmFja2dyb3VuZEltYWdlID0gYHVybCgke29iamVjdFVSTEZvclBhZ2V9KWA7XG4gICAgfVxuICAgIHJldHVybiBzdHlsZXM7XG4gIH0sIFtwYWdlRGltZW5zaW9ucywgcm90YXRpb24sIHNjYWxlLCBvYmplY3RVUkxGb3JQYWdlXSk7XG5cbiAgY29uc3QgZ2V0V2lkdGggPSBSZWFjdC51c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgcmV0dXJuIGdldFBhZ2VXaWR0aChwYWdlRGltZW5zaW9ucywgcm90YXRpb24pO1xuICB9LCBbcGFnZURpbWVuc2lvbnMsIHJvdGF0aW9uXSk7XG5cbiAgY29uc3Qgb3V0bGluZVRhcmdldHMgPSBnZXRPdXRsaW5lVGFyZ2V0cyh7IHBhZ2VJbmRleCwgc2NhbGUsIHJvdGF0aW9uLCBwYWdlRGltZW5zaW9ucyB9KTtcblxuICAvLyBXaWR0aCBuZWVkcyB0byBiZSBzZXQgdG8gcHJldmVudCB0aGUgb3V0ZXJtb3N0IFBhZ2UgZGl2IGZyb20gZXh0ZW5kaW5nIHRvIGZpdCB0aGUgcGFyZW50LFxuICAvLyBhbmQgbWlzLWFsaWduaW5nIHRoZSB0ZXh0IGxheWVyLlxuICAvLyBUT0RPOiBDYW4gd2UgQ1NTIHRoaXMgdG8gYXV0by1zaHJpbms/XG4gIHJldHVybiAoXG4gICAgPGRpdlxuICAgICAgaWQ9e2dlbmVyYXRlUGFnZUlkRnJvbUluZGV4KHBhZ2VJbmRleCl9XG4gICAgICBjbGFzc05hbWU9e2NsYXNzbmFtZXMoXG4gICAgICAgICdyZWFkZXJfX3BhZ2UnLFxuICAgICAgICB7ICdyZWFkZXJfX3BhZ2UtLWhhcy1wYWdlLWltYWdlJzogb2JqZWN0VVJMRm9yUGFnZSB9LFxuICAgICAgICB7ICdyZWFkZXJfX3BhZ2UtLW5vLXBhZ2UtaW1hZ2UnOiAhb2JqZWN0VVJMRm9yUGFnZSB9LFxuICAgICAgICB7ICdyZWFkZXJfX3BhZ2UtLWlzLWJ1aWxkaW5nLXBhZ2UtaW1hZ2UnOiBpc0J1aWxkaW5nUGFnZUltYWdlIH1cbiAgICAgICl9XG4gICAgICBkYXRhLXBhZ2UtbnVtYmVyPXtwYWdlSW5kZXggKyAxfVxuICAgICAgc3R5bGU9e2dldFBhZ2VTdHlsZSgpfVxuICAgICAgey4uLmV4dHJhUHJvcHN9PlxuICAgICAge2NoaWxkcmVufVxuICAgICAge2lzQnVpbGRpbmdQYWdlSW1hZ2UgJiYgKFxuICAgICAgICA8ZGl2XG4gICAgICAgICAgY2xhc3NOYW1lPXtjbGFzc25hbWVzKCdyZWFkZXJfX3BhZ2UnLCB7XG4gICAgICAgICAgICAncmVhZGVyX19wYWdlLS1pcy1sb2FkaW5nLWltYWdlJzogaXNCdWlsZGluZ1BhZ2VJbWFnZSxcbiAgICAgICAgICB9KX0+XG4gICAgICAgICAge2xvYWRpbmdDb250ZW50Rm9yQnVpbGRpbmdJbWFnZX1cbiAgICAgICAgPC9kaXY+XG4gICAgICApfVxuICAgICAgPFBhZ2VcbiAgICAgICAgd2lkdGg9e2dldFdpZHRoKCl9XG4gICAgICAgIGVycm9yPXtlcnJvcn1cbiAgICAgICAgbG9hZGluZz17bG9hZGluZ31cbiAgICAgICAgbm9EYXRhPXtub0RhdGF9XG4gICAgICAgIHBhZ2VJbmRleD17cGFnZUluZGV4fVxuICAgICAgICBzY2FsZT17c2NhbGV9XG4gICAgICAgIHJvdGF0ZT17cm90YXRpb259XG4gICAgICAgIHJlbmRlckFubm90YXRpb25MYXllcj17dHJ1ZX1cbiAgICAgIC8+XG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cInJlYWRlcl9fcGFnZV9fb3V0bGluZS10YXJnZXRzXCI+XG4gICAgICAgIHtvdXRsaW5lVGFyZ2V0cy5tYXAoKHsgZGVzdCwgbGVmdFB4LCB0b3BQeCB9KSA9PiAoXG4gICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgIGtleT17ZGVzdH1cbiAgICAgICAgICAgIGNsYXNzTmFtZT1cInJlYWRlcl9fcGFnZV9fb3V0bGluZS10YXJnZXRcIlxuICAgICAgICAgICAgZGF0YS1vdXRsaW5lLXRhcmdldC1kZXN0PXtkZXN0fVxuICAgICAgICAgICAgc3R5bGU9e3sgbGVmdDogbGVmdFB4ICsgJ3B4JywgdG9wOiB0b3BQeCArICdweCcgfX1cbiAgICAgICAgICAvPlxuICAgICAgICApKX1cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICApO1xufTtcbiIsIi8vIEhlaWdodCBhbmQgd2lkdGggYXJlIGluIHNjcmVlbiBwaXhlbCB1bml0cyBhdCAxMDAlIHNjYWxpbmcgb2YgdGhlIHBhZ2VcbmV4cG9ydCB0eXBlIERpbWVuc2lvbnMgPSB7XG4gIGhlaWdodDogbnVtYmVyO1xuICB3aWR0aDogbnVtYmVyO1xufTtcblxuLy8gVG9wIGFuZCBsZWZ0IGFyZSBpbiBzY3JlZW4gcGl4ZWwgdW5pdHMgYXQgMTAwJSBzY2FsaW5nIG9mIHRoZSBwYWdlXG5leHBvcnQgdHlwZSBPcmlnaW4gPSB7XG4gIHRvcDogbnVtYmVyO1xuICBsZWZ0OiBudW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBTaXplID0gRGltZW5zaW9ucyAmIE9yaWdpbjtcblxuZXhwb3J0IHR5cGUgQm91bmRpbmdCb3ggPSB7XG4gIHBhZ2U6IG51bWJlcjtcbn0gJiBTaXplO1xuXG4vLyBSYXcgQm91bmRpbmdCb3hlcyB0b3AsIGxlZnQsIGhlaWdodCwgYW5kIHdpZHRoIGF0dHJpYnV0ZXMgYXJlIGV4cHJlc3NlZCBhcyBhIHJhdGlvIG9mIHRoZVxuLy8gcGFnZSBoZWlnaHQvd2lkdGggYW5kIG5lZWQgdG8gYmUgc2NhbGVkIGFjY29yZGluZyB0byBwYWdlIHNpemUgYmVmb3JlIHRoZXkgY2FuIGJlIHJlbmRlcmVkXG5leHBvcnQgdHlwZSBSYXdCb3VuZGluZ0JveCA9IEJvdW5kaW5nQm94O1xuXG4vLyBDYWxjdWxhdGUgYSBib3VuZGluZyBib3gncyBwaXhlbCBjb29yZGluYXRlcyBmcm9tIHRoZSByYXcgYm91bmRpbmcgYm94J3MgY29vcmRpdGF0ZSByYXRpb3Mgc2NhbGVkIHRvIHRoZSBwYWdlIHNpemVcbmV4cG9ydCBmdW5jdGlvbiBzY2FsZVJhd0JvdW5kaW5nQm94KFxuICBib3VuZGluZ0JveFJhdzogUmF3Qm91bmRpbmdCb3gsXG4gIHBhZ2VIZWlnaHQ6IG51bWJlcixcbiAgcGFnZVdpZHRoOiBudW1iZXJcbik6IEJvdW5kaW5nQm94IHtcbiAgY29uc3QgYm94U2NhbGVkOiBCb3VuZGluZ0JveCA9IHtcbiAgICBwYWdlOiBib3VuZGluZ0JveFJhdy5wYWdlLFxuICAgIHRvcDogYm91bmRpbmdCb3hSYXcudG9wICogcGFnZUhlaWdodCxcbiAgICBsZWZ0OiBib3VuZGluZ0JveFJhdy5sZWZ0ICogcGFnZVdpZHRoLFxuICAgIGhlaWdodDogYm91bmRpbmdCb3hSYXcuaGVpZ2h0ICogcGFnZUhlaWdodCxcbiAgICB3aWR0aDogYm91bmRpbmdCb3hSYXcud2lkdGggKiBwYWdlV2lkdGgsXG4gIH07XG5cbiAgcmV0dXJuIGJveFNjYWxlZDtcbn1cbiIsImV4cG9ydCBjb25zdCBQZXJjZW50Rm9ybWF0dGVyID0gbmV3IEludGwuTnVtYmVyRm9ybWF0KCdlbi1VUycsIHtcbiAgc3R5bGU6ICdwZXJjZW50JyxcbiAgbWF4aW11bVNpZ25pZmljYW50RGlnaXRzOiAzLFxufSk7XG4iLCJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5cbmltcG9ydCB7IFNjcm9sbENvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L1Njcm9sbENvbnRleHQnO1xuaW1wb3J0IHsgVHJhbnNmb3JtQ29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvVHJhbnNmb3JtQ29udGV4dCc7XG5pbXBvcnQgeyBQZXJjZW50Rm9ybWF0dGVyIH0gZnJvbSAnLi4vdXRpbHMvZm9ybWF0JztcblxuZXhwb3J0IHR5cGUgUHJvcHMgPSB7XG4gIGNoaWxkcmVuPzogUmVhY3QuUmVhY3ROb2RlO1xufTtcblxuY29uc3QgTUFYX1pPT01fSU5fU0NBTEUgPSA1MDA7XG5cbmV4cG9ydCBjb25zdCBab29tSW5CdXR0b246IFJlYWN0LkZ1bmN0aW9uQ29tcG9uZW50PFByb3BzPiA9ICh7XG4gIGNoaWxkcmVuLFxuICAuLi5leHRyYVByb3BzXG59OiBQcm9wcykgPT4ge1xuICBjb25zdCB7IHNjYWxlLCBzZXRTY2FsZSwgem9vbU11bHRpcGxpZXIgfSA9IFJlYWN0LnVzZUNvbnRleHQoVHJhbnNmb3JtQ29udGV4dCk7XG4gIGNvbnN0IHsgdXBkYXRlU2Nyb2xsUG9zaXRpb24gfSA9IFJlYWN0LnVzZUNvbnRleHQoU2Nyb2xsQ29udGV4dCk7XG5cbiAgY29uc3QgaGFuZGxlWm9vbUluID0gUmVhY3QudXNlQ2FsbGJhY2soXG4gICAgKGV2ZW50KTogdm9pZCA9PiB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBjb25zdCB6b29tU2NhbGUgPSBOdW1iZXIoUGVyY2VudEZvcm1hdHRlci5mb3JtYXQoc2NhbGUgKiB6b29tTXVsdGlwbGllcikucmVwbGFjZSgnJScsICcnKSk7XG4gICAgICBpZiAoem9vbVNjYWxlIDw9IE1BWF9aT09NX0lOX1NDQUxFKSB7XG4gICAgICAgIHVwZGF0ZVNjcm9sbFBvc2l0aW9uKDEgKiB6b29tTXVsdGlwbGllcik7XG4gICAgICAgIHNldFNjYWxlKHNjYWxlICogem9vbU11bHRpcGxpZXIpO1xuICAgICAgfVxuICAgIH0sXG4gICAgW3NjYWxlLCB6b29tTXVsdGlwbGllciwgdXBkYXRlU2Nyb2xsUG9zaXRpb25dXG4gICk7XG5cbiAgcmV0dXJuIChcbiAgICA8YnV0dG9uIGNsYXNzTmFtZT1cInJlYWRlcl9fem9vbS1idG4gem9vbS1pblwiIG9uQ2xpY2s9e2hhbmRsZVpvb21Jbn0gey4uLmV4dHJhUHJvcHN9PlxuICAgICAge2NoaWxkcmVuID8gY2hpbGRyZW4gOiAnKyd9XG4gICAgPC9idXR0b24+XG4gICk7XG59O1xuIiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5pbXBvcnQgeyBTY3JvbGxDb250ZXh0IH0gZnJvbSAnLi4vY29udGV4dC9TY3JvbGxDb250ZXh0JztcbmltcG9ydCB7IFRyYW5zZm9ybUNvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L1RyYW5zZm9ybUNvbnRleHQnO1xuaW1wb3J0IHsgUGVyY2VudEZvcm1hdHRlciB9IGZyb20gJy4uL3V0aWxzL2Zvcm1hdCc7XG5cbmV4cG9ydCB0eXBlIFByb3BzID0ge1xuICBjaGlsZHJlbj86IFJlYWN0LlJlYWN0Tm9kZTtcbn07XG5cbmNvbnN0IE1JTl9aT09NX09VVF9TQ0FMRSA9IDI1O1xuXG5leHBvcnQgY29uc3QgWm9vbU91dEJ1dHRvbjogUmVhY3QuRnVuY3Rpb25Db21wb25lbnQgPSAoeyBjaGlsZHJlbiwgLi4uZXh0cmFQcm9wcyB9OiBQcm9wcykgPT4ge1xuICBjb25zdCB7IHNjYWxlLCBzZXRTY2FsZSwgem9vbU11bHRpcGxpZXIgfSA9IFJlYWN0LnVzZUNvbnRleHQoVHJhbnNmb3JtQ29udGV4dCk7XG4gIGNvbnN0IHsgdXBkYXRlU2Nyb2xsUG9zaXRpb24gfSA9IFJlYWN0LnVzZUNvbnRleHQoU2Nyb2xsQ29udGV4dCk7XG5cbiAgY29uc3QgaGFuZGxlWm9vbU91dCA9IFJlYWN0LnVzZUNhbGxiYWNrKFxuICAgIChldmVudCk6IHZvaWQgPT4ge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgY29uc3Qgem9vbVNjYWxlID0gTnVtYmVyKFBlcmNlbnRGb3JtYXR0ZXIuZm9ybWF0KHNjYWxlIC8gem9vbU11bHRpcGxpZXIpLnJlcGxhY2UoJyUnLCAnJykpO1xuICAgICAgaWYgKHpvb21TY2FsZSA+PSBNSU5fWk9PTV9PVVRfU0NBTEUpIHtcbiAgICAgICAgdXBkYXRlU2Nyb2xsUG9zaXRpb24oMSAvIHpvb21NdWx0aXBsaWVyKTtcbiAgICAgICAgc2V0U2NhbGUoc2NhbGUgLyB6b29tTXVsdGlwbGllcik7XG4gICAgICB9XG4gICAgfSxcbiAgICBbc2NhbGUsIHpvb21NdWx0aXBsaWVyLCB1cGRhdGVTY3JvbGxQb3NpdGlvbl1cbiAgKTtcblxuICByZXR1cm4gKFxuICAgIDxidXR0b24gY2xhc3NOYW1lPVwicmVhZGVyX196b29tLWJ0biB6b29tLW91dFwiIG9uQ2xpY2s9e2hhbmRsZVpvb21PdXR9IHsuLi5leHRyYVByb3BzfT5cbiAgICAgIHtjaGlsZHJlbiA/IGNoaWxkcmVuIDogJy0nfVxuICAgIDwvYnV0dG9uPlxuICApO1xufTtcbiIsImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcblxuaW1wb3J0IHsgRG9jdW1lbnRDb250ZXh0LCB1c2VEb2N1bWVudENvbnRleHRQcm9wcyB9IGZyb20gJy4vRG9jdW1lbnRDb250ZXh0JztcbmltcG9ydCB7IFBhZ2VSZW5kZXJDb250ZXh0LCB1c2VQYWdlUmVuZGVyQ29udGV4dFByb3BzIH0gZnJvbSAnLi9QYWdlUmVuZGVyQ29udGV4dCc7XG5pbXBvcnQgeyBTY3JvbGxDb250ZXh0LCB1c2VTY3JvbGxDb250ZXh0UHJvcHMgfSBmcm9tICcuL1Njcm9sbENvbnRleHQnO1xuaW1wb3J0IHsgVHJhbnNmb3JtQ29udGV4dCwgdXNlVHJhbnNmb3JtQ29udGV4dFByb3BzIH0gZnJvbSAnLi9UcmFuc2Zvcm1Db250ZXh0JztcbmltcG9ydCB7IFVpQ29udGV4dCwgdXNlVWlDb250ZXh0UHJvcHMgfSBmcm9tICcuL1VpQ29udGV4dCc7XG5cbmV4cG9ydCB0eXBlIFByb3BzID0ge1xuICBjaGlsZHJlbj86IFJlYWN0LlJlYWN0RWxlbWVudCB8IEFycmF5PFJlYWN0LlJlYWN0RWxlbWVudD47XG59O1xuXG5leHBvcnQgY29uc3QgQ29udGV4dFByb3ZpZGVyOiBSZWFjdC5GdW5jdGlvbkNvbXBvbmVudDxQcm9wcz4gPSAoeyBjaGlsZHJlbiB9OiBQcm9wcykgPT4ge1xuICBjb25zdCBkb2N1bWVudFByb3BzID0gdXNlRG9jdW1lbnRDb250ZXh0UHJvcHMoKTtcbiAgY29uc3QgdHJhbnNmb3JtUHJvcHMgPSB1c2VUcmFuc2Zvcm1Db250ZXh0UHJvcHMoKTtcbiAgY29uc3QgdWlQcm9wcyA9IHVzZVVpQ29udGV4dFByb3BzKCk7XG4gIGNvbnN0IHNjcm9sbFByb3BzID0gdXNlU2Nyb2xsQ29udGV4dFByb3BzKCk7XG4gIGNvbnN0IHBhZ2VSZW5kZXJQcm9wcyA9IHVzZVBhZ2VSZW5kZXJDb250ZXh0UHJvcHMoe1xuICAgIHBkZkRvY1Byb3h5OiBkb2N1bWVudFByb3BzLnBkZkRvY1Byb3h5LFxuICAgIHNjYWxlOiB0cmFuc2Zvcm1Qcm9wcy5zY2FsZSxcbiAgICByb3RhdGlvbjogdHJhbnNmb3JtUHJvcHMucm90YXRpb24sXG4gICAgem9vbU11bHRpcGxpZXI6IHRyYW5zZm9ybVByb3BzLnpvb21NdWx0aXBsaWVyLFxuICAgIHZpc2libGVQYWdlUmF0aW9zOiBzY3JvbGxQcm9wcy52aXNpYmxlUGFnZVJhdGlvcyxcbiAgfSk7XG5cbiAgcmV0dXJuIChcbiAgICA8RG9jdW1lbnRDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXtkb2N1bWVudFByb3BzfT5cbiAgICAgIDxUcmFuc2Zvcm1Db250ZXh0LlByb3ZpZGVyIHZhbHVlPXt0cmFuc2Zvcm1Qcm9wc30+XG4gICAgICAgIDxVaUNvbnRleHQuUHJvdmlkZXIgdmFsdWU9e3VpUHJvcHN9PlxuICAgICAgICAgIDxTY3JvbGxDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXtzY3JvbGxQcm9wc30+XG4gICAgICAgICAgICA8UGFnZVJlbmRlckNvbnRleHQuUHJvdmlkZXIgdmFsdWU9e3BhZ2VSZW5kZXJQcm9wc30+XG4gICAgICAgICAgICAgIHtjaGlsZHJlbn1cbiAgICAgICAgICAgIDwvUGFnZVJlbmRlckNvbnRleHQuUHJvdmlkZXI+XG4gICAgICAgICAgPC9TY3JvbGxDb250ZXh0LlByb3ZpZGVyPlxuICAgICAgICA8L1VpQ29udGV4dC5Qcm92aWRlcj5cbiAgICAgIDwvVHJhbnNmb3JtQ29udGV4dC5Qcm92aWRlcj5cbiAgICA8L0RvY3VtZW50Q29udGV4dC5Qcm92aWRlcj5cbiAgKTtcbn07XG4iLCIvKlxuICogUERGIENvbXBvbmVudCBMaWJyYXJ5IGV4cG9ydHNcbiAqL1xuXG5pbXBvcnQgJy4vbGVzcy9pbmRleC5sZXNzJztcblxuaW1wb3J0IHsgQm91bmRpbmdCb3gsIFByb3BzIGFzIEJvdW5kaW5nQm94UHJvcHMgfSBmcm9tICcuL3NyYy9jb21wb25lbnRzL0JvdW5kaW5nQm94JztcbmltcG9ydCB7IERvY3VtZW50V3JhcHBlciwgUHJvcHMgYXMgRG9jdW1lbnRXcmFwcGVyUHJvcHMgfSBmcm9tICcuL3NyYy9jb21wb25lbnRzL0RvY3VtZW50V3JhcHBlcic7XG5pbXBvcnQgeyBEb3dubG9hZEJ1dHRvbiwgUHJvcHMgYXMgRG93bmxvYWRCdXR0b25Qcm9wcyB9IGZyb20gJy4vc3JjL2NvbXBvbmVudHMvRG93bmxvYWRCdXR0b24nO1xuaW1wb3J0IHtcbiAgSGlnaGxpZ2h0T3ZlcmxheSxcbiAgUHJvcHMgYXMgSGlnaGxpZ2h0T3ZlcmxheVByb3BzLFxufSBmcm9tICcuL3NyYy9jb21wb25lbnRzL0hpZ2hsaWdodE92ZXJsYXknO1xuaW1wb3J0IHsgT3V0bGluZSB9IGZyb20gJy4vc3JjL2NvbXBvbmVudHMvb3V0bGluZS9PdXRsaW5lJztcbmltcG9ydCB7IE91dGxpbmVJdGVtIH0gZnJvbSAnLi9zcmMvY29tcG9uZW50cy9vdXRsaW5lL091dGxpbmVJdGVtJztcbmltcG9ydCB7IE92ZXJsYXksIFByb3BzIGFzIE92ZXJsYXlQcm9wcyB9IGZyb20gJy4vc3JjL2NvbXBvbmVudHMvT3ZlcmxheSc7XG5pbXBvcnQgeyBQYWdlTnVtYmVyQ29udHJvbCB9IGZyb20gJy4vc3JjL2NvbXBvbmVudHMvUGFnZU51bWJlckNvbnRyb2wnO1xuaW1wb3J0IHsgUGFnZVByb3BzLCBQYWdlV3JhcHBlciwgUHJvcHMgYXMgUGFnZVdyYXBwZXJQcm9wcyB9IGZyb20gJy4vc3JjL2NvbXBvbmVudHMvUGFnZVdyYXBwZXInO1xuaW1wb3J0IHtcbiAgQm91bmRpbmdCb3ggYXMgQm91bmRpbmdCb3hUeXBlLFxuICBEaW1lbnNpb25zLFxuICBPcmlnaW4sXG4gIFJhd0JvdW5kaW5nQm94LFxuICBzY2FsZVJhd0JvdW5kaW5nQm94LFxuICBTaXplLFxufSBmcm9tICcuL3NyYy9jb21wb25lbnRzL3R5cGVzL2JvdW5kaW5nQm94JztcbmltcG9ydCB7IE5vZGVEZXN0aW5hdGlvbiwgT3V0bGluZU5vZGUgfSBmcm9tICcuL3NyYy9jb21wb25lbnRzL3R5cGVzL291dGxpbmUnO1xuaW1wb3J0IHsgUGFnZVByb3BlcnRpZXMsIFBhZ2VSZWZlcmVuY2UgfSBmcm9tICcuL3NyYy9jb21wb25lbnRzL3R5cGVzL3BhZ2UnO1xuaW1wb3J0IHsgTnVsbGFibGUgfSBmcm9tICcuL3NyYy9jb21wb25lbnRzL3R5cGVzL3V0aWxzJztcbmltcG9ydCB7IFpvb21JbkJ1dHRvbiB9IGZyb20gJy4vc3JjL2NvbXBvbmVudHMvWm9vbUluQnV0dG9uJztcbmltcG9ydCB7IFpvb21PdXRCdXR0b24gfSBmcm9tICcuL3NyYy9jb21wb25lbnRzL1pvb21PdXRCdXR0b24nO1xuaW1wb3J0IHsgQ29udGV4dFByb3ZpZGVyLCBQcm9wcyBhcyBDb250ZXh0UHJvdmlkZXJQcm9wcyB9IGZyb20gJy4vc3JjL2NvbnRleHQvQ29udGV4dFByb3ZpZGVyJztcbmltcG9ydCB7IERvY3VtZW50Q29udGV4dCwgSURvY3VtZW50Q29udGV4dCB9IGZyb20gJy4vc3JjL2NvbnRleHQvRG9jdW1lbnRDb250ZXh0JztcbmltcG9ydCB7IElTY3JvbGxDb250ZXh0LCBTY3JvbGxDb250ZXh0IH0gZnJvbSAnLi9zcmMvY29udGV4dC9TY3JvbGxDb250ZXh0JztcbmltcG9ydCB7IElUcmFuc2Zvcm1Db250ZXh0LCBUcmFuc2Zvcm1Db250ZXh0IH0gZnJvbSAnLi9zcmMvY29udGV4dC9UcmFuc2Zvcm1Db250ZXh0JztcbmltcG9ydCB7IElVaUNvbnRleHQsIFVpQ29udGV4dCB9IGZyb20gJy4vc3JjL2NvbnRleHQvVWlDb250ZXh0JztcbmltcG9ydCB7XG4gIGlzU2lkZXdheXMsXG4gIFBhZ2VSb3RhdGlvbixcbiAgcm90YXRlQ2xvY2t3aXNlLFxuICByb3RhdGVDb3VudGVyQ2xvY2t3aXNlLFxufSBmcm9tICcuL3NyYy91dGlscy9yb3RhdGUnO1xuaW1wb3J0IHsgZ2VuZXJhdGVQYWdlSWRGcm9tSW5kZXgsIHNjcm9sbFRvSWQsIHNjcm9sbFRvUGRmUGFnZUluZGV4IH0gZnJvbSAnLi9zcmMvdXRpbHMvc2Nyb2xsJztcbmltcG9ydCB7XG4gIGNvbXB1dGVCb3VuZGluZ0JveFN0eWxlLFxuICBjb21wdXRlUGFnZVN0eWxlLFxuICBnZXRQYWdlSGVpZ2h0LFxuICBnZXRQYWdlV2lkdGgsXG59IGZyb20gJy4vc3JjL3V0aWxzL3N0eWxlJztcblxuZXhwb3J0IHR5cGUge1xuICBCb3VuZGluZ0JveFByb3BzLFxuICBCb3VuZGluZ0JveFR5cGUsXG4gIENvbnRleHRQcm92aWRlclByb3BzLFxuICBEaW1lbnNpb25zLFxuICBEb2N1bWVudFdyYXBwZXJQcm9wcyxcbiAgRG93bmxvYWRCdXR0b25Qcm9wcyxcbiAgSGlnaGxpZ2h0T3ZlcmxheVByb3BzLFxuICBJRG9jdW1lbnRDb250ZXh0LFxuICBJU2Nyb2xsQ29udGV4dCxcbiAgSVRyYW5zZm9ybUNvbnRleHQsXG4gIElVaUNvbnRleHQsXG4gIE5vZGVEZXN0aW5hdGlvbixcbiAgTnVsbGFibGUsXG4gIE9yaWdpbixcbiAgT3V0bGluZU5vZGUsXG4gIE92ZXJsYXlQcm9wcyxcbiAgUGFnZVByb3BlcnRpZXMsXG4gIFBhZ2VQcm9wcyxcbiAgUGFnZVJlZmVyZW5jZSxcbiAgUGFnZVJvdGF0aW9uLFxuICBQYWdlV3JhcHBlclByb3BzLFxuICBSYXdCb3VuZGluZ0JveCxcbiAgU2l6ZSxcbn07XG5cbmV4cG9ydCB7XG4gIEJvdW5kaW5nQm94LFxuICBjb21wdXRlQm91bmRpbmdCb3hTdHlsZSxcbiAgY29tcHV0ZVBhZ2VTdHlsZSxcbiAgQ29udGV4dFByb3ZpZGVyLFxuICBEb2N1bWVudENvbnRleHQsXG4gIERvY3VtZW50V3JhcHBlcixcbiAgRG93bmxvYWRCdXR0b24sXG4gIGdlbmVyYXRlUGFnZUlkRnJvbUluZGV4LFxuICBnZXRQYWdlSGVpZ2h0LFxuICBnZXRQYWdlV2lkdGgsXG4gIEhpZ2hsaWdodE92ZXJsYXksXG4gIGlzU2lkZXdheXMsXG4gIE91dGxpbmUsXG4gIE91dGxpbmVJdGVtLFxuICBPdmVybGF5LFxuICBQYWdlTnVtYmVyQ29udHJvbCxcbiAgUGFnZVdyYXBwZXIsXG4gIHJvdGF0ZUNsb2Nrd2lzZSxcbiAgcm90YXRlQ291bnRlckNsb2Nrd2lzZSxcbiAgc2NhbGVSYXdCb3VuZGluZ0JveCxcbiAgU2Nyb2xsQ29udGV4dCxcbiAgc2Nyb2xsVG9JZCxcbiAgc2Nyb2xsVG9QZGZQYWdlSW5kZXgsXG4gIFRyYW5zZm9ybUNvbnRleHQsXG4gIFVpQ29udGV4dCxcbiAgWm9vbUluQnV0dG9uLFxuICBab29tT3V0QnV0dG9uLFxufTtcblxuZXhwb3J0IGRlZmF1bHQge1xuICBCb3VuZGluZ0JveCxcbiAgY29tcHV0ZUJvdW5kaW5nQm94U3R5bGUsXG4gIGNvbXB1dGVQYWdlU3R5bGUsXG4gIENvbnRleHRQcm92aWRlcixcbiAgRG9jdW1lbnRDb250ZXh0LFxuICBEb2N1bWVudFdyYXBwZXIsXG4gIERvd25sb2FkQnV0dG9uLFxuICBnZW5lcmF0ZVBhZ2VJZEZyb21JbmRleCxcbiAgZ2V0UGFnZUhlaWdodCxcbiAgZ2V0UGFnZVdpZHRoLFxuICBIaWdobGlnaHRPdmVybGF5LFxuICBpc1NpZGV3YXlzLFxuICBPdXRsaW5lLFxuICBPdXRsaW5lSXRlbSxcbiAgT3ZlcmxheSxcbiAgUGFnZU51bWJlckNvbnRyb2wsXG4gIFBhZ2VSb3RhdGlvbixcbiAgUGFnZVdyYXBwZXIsXG4gIHJvdGF0ZUNsb2Nrd2lzZSxcbiAgcm90YXRlQ291bnRlckNsb2Nrd2lzZSxcbiAgc2NhbGVSYXdCb3VuZGluZ0JveCxcbiAgc2Nyb2xsVG9JZCxcbiAgc2Nyb2xsVG9QZGZQYWdlSW5kZXgsXG4gIFNjcm9sbENvbnRleHQsXG4gIFRyYW5zZm9ybUNvbnRleHQsXG4gIFVpQ29udGV4dCxcbiAgWm9vbUluQnV0dG9uLFxuICBab29tT3V0QnV0dG9uLFxufTtcbiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///188\n')},888:n=>{"use strict";n.exports=__WEBPACK_EXTERNAL_MODULE__888__},414:()=>{},172:()=>{},1:()=>{},779:()=>{},558:()=>{},258:()=>{}},__webpack_module_cache__={};function __webpack_require__(n){var t=__webpack_module_cache__[n];if(void 0!==t)return t.exports;var g=__webpack_module_cache__[n]={exports:{}};return __webpack_modules__[n].call(g.exports,g,g.exports,__webpack_require__),g.exports}__webpack_require__.n=n=>{var t=n&&n.__esModule?()=>n.default:()=>n;return __webpack_require__.d(t,{a:t}),t},__webpack_require__.d=(n,t)=>{for(var g in t)__webpack_require__.o(t,g)&&!__webpack_require__.o(n,g)&&Object.defineProperty(n,g,{enumerable:!0,get:t[g]})},__webpack_require__.o=(n,t)=>Object.prototype.hasOwnProperty.call(n,t);var __webpack_exports__=__webpack_require__(188);return __webpack_exports__=__webpack_exports__.default,__webpack_exports__})()})); \ No newline at end of file +!function(n,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react")):"function"==typeof define&&define.amd?define(["react"],t):"object"==typeof exports?exports["@allenai/pdf-components"]=t(require("react")):n["@allenai/pdf-components"]=t(n.React)}(this,(function(__WEBPACK_EXTERNAL_MODULE__888__){return(()=>{var __webpack_modules__={822:module=>{"use strict";eval("/*\nobject-assign\n(c) Sindre Sorhus\n@license MIT\n*/\n\n\n/* eslint-disable no-unused-vars */\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\nfunction toObject(val) {\n\tif (val === null || val === undefined) {\n\t\tthrow new TypeError('Object.assign cannot be called with null or undefined');\n\t}\n\n\treturn Object(val);\n}\n\nfunction shouldUseNative() {\n\ttry {\n\t\tif (!Object.assign) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Detect buggy property enumeration order in older V8 versions.\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=4118\n\t\tvar test1 = new String('abc'); // eslint-disable-line no-new-wrappers\n\t\ttest1[5] = 'de';\n\t\tif (Object.getOwnPropertyNames(test1)[0] === '5') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test2 = {};\n\t\tfor (var i = 0; i < 10; i++) {\n\t\t\ttest2['_' + String.fromCharCode(i)] = i;\n\t\t}\n\t\tvar order2 = Object.getOwnPropertyNames(test2).map(function (n) {\n\t\t\treturn test2[n];\n\t\t});\n\t\tif (order2.join('') !== '0123456789') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test3 = {};\n\t\t'abcdefghijklmnopqrst'.split('').forEach(function (letter) {\n\t\t\ttest3[letter] = letter;\n\t\t});\n\t\tif (Object.keys(Object.assign({}, test3)).join('') !==\n\t\t\t\t'abcdefghijklmnopqrst') {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} catch (err) {\n\t\t// We don't expect any of the above to throw, but better to be safe.\n\t\treturn false;\n\t}\n}\n\nmodule.exports = shouldUseNative() ? Object.assign : function (target, source) {\n\tvar from;\n\tvar to = toObject(target);\n\tvar symbols;\n\n\tfor (var s = 1; s < arguments.length; s++) {\n\t\tfrom = Object(arguments[s]);\n\n\t\tfor (var key in from) {\n\t\t\tif (hasOwnProperty.call(from, key)) {\n\t\t\t\tto[key] = from[key];\n\t\t\t}\n\t\t}\n\n\t\tif (getOwnPropertySymbols) {\n\t\t\tsymbols = getOwnPropertySymbols(from);\n\t\t\tfor (var i = 0; i < symbols.length; i++) {\n\t\t\t\tif (propIsEnumerable.call(from, symbols[i])) {\n\t\t\t\t\tto[symbols[i]] = from[symbols[i]];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn to;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uLi9kZW1vL25vZGVfbW9kdWxlcy9vYmplY3QtYXNzaWduL2luZGV4LmpzPzYyMTIiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFYTtBQUNiO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLGdDQUFnQztBQUNoQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILGtDQUFrQztBQUNsQztBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZ0JBQWdCLHNCQUFzQjtBQUN0Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxrQkFBa0Isb0JBQW9CO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBIiwiZmlsZSI6IjgyMi5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG5vYmplY3QtYXNzaWduXG4oYykgU2luZHJlIFNvcmh1c1xuQGxpY2Vuc2UgTUlUXG4qL1xuXG4ndXNlIHN0cmljdCc7XG4vKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtdmFycyAqL1xudmFyIGdldE93blByb3BlcnR5U3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xudmFyIHByb3BJc0VudW1lcmFibGUgPSBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlO1xuXG5mdW5jdGlvbiB0b09iamVjdCh2YWwpIHtcblx0aWYgKHZhbCA9PT0gbnVsbCB8fCB2YWwgPT09IHVuZGVmaW5lZCkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ09iamVjdC5hc3NpZ24gY2Fubm90IGJlIGNhbGxlZCB3aXRoIG51bGwgb3IgdW5kZWZpbmVkJyk7XG5cdH1cblxuXHRyZXR1cm4gT2JqZWN0KHZhbCk7XG59XG5cbmZ1bmN0aW9uIHNob3VsZFVzZU5hdGl2ZSgpIHtcblx0dHJ5IHtcblx0XHRpZiAoIU9iamVjdC5hc3NpZ24pIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBEZXRlY3QgYnVnZ3kgcHJvcGVydHkgZW51bWVyYXRpb24gb3JkZXIgaW4gb2xkZXIgVjggdmVyc2lvbnMuXG5cblx0XHQvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD00MTE4XG5cdFx0dmFyIHRlc3QxID0gbmV3IFN0cmluZygnYWJjJyk7ICAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ldy13cmFwcGVyc1xuXHRcdHRlc3QxWzVdID0gJ2RlJztcblx0XHRpZiAoT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGVzdDEpWzBdID09PSAnNScpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0zMDU2XG5cdFx0dmFyIHRlc3QyID0ge307XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCAxMDsgaSsrKSB7XG5cdFx0XHR0ZXN0MlsnXycgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKGkpXSA9IGk7XG5cdFx0fVxuXHRcdHZhciBvcmRlcjIgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0ZXN0MikubWFwKGZ1bmN0aW9uIChuKSB7XG5cdFx0XHRyZXR1cm4gdGVzdDJbbl07XG5cdFx0fSk7XG5cdFx0aWYgKG9yZGVyMi5qb2luKCcnKSAhPT0gJzAxMjM0NTY3ODknKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzA1NlxuXHRcdHZhciB0ZXN0MyA9IHt9O1xuXHRcdCdhYmNkZWZnaGlqa2xtbm9wcXJzdCcuc3BsaXQoJycpLmZvckVhY2goZnVuY3Rpb24gKGxldHRlcikge1xuXHRcdFx0dGVzdDNbbGV0dGVyXSA9IGxldHRlcjtcblx0XHR9KTtcblx0XHRpZiAoT2JqZWN0LmtleXMoT2JqZWN0LmFzc2lnbih7fSwgdGVzdDMpKS5qb2luKCcnKSAhPT1cblx0XHRcdFx0J2FiY2RlZmdoaWprbG1ub3BxcnN0Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHJldHVybiB0cnVlO1xuXHR9IGNhdGNoIChlcnIpIHtcblx0XHQvLyBXZSBkb24ndCBleHBlY3QgYW55IG9mIHRoZSBhYm92ZSB0byB0aHJvdywgYnV0IGJldHRlciB0byBiZSBzYWZlLlxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNob3VsZFVzZU5hdGl2ZSgpID8gT2JqZWN0LmFzc2lnbiA6IGZ1bmN0aW9uICh0YXJnZXQsIHNvdXJjZSkge1xuXHR2YXIgZnJvbTtcblx0dmFyIHRvID0gdG9PYmplY3QodGFyZ2V0KTtcblx0dmFyIHN5bWJvbHM7XG5cblx0Zm9yICh2YXIgcyA9IDE7IHMgPCBhcmd1bWVudHMubGVuZ3RoOyBzKyspIHtcblx0XHRmcm9tID0gT2JqZWN0KGFyZ3VtZW50c1tzXSk7XG5cblx0XHRmb3IgKHZhciBrZXkgaW4gZnJvbSkge1xuXHRcdFx0aWYgKGhhc093blByb3BlcnR5LmNhbGwoZnJvbSwga2V5KSkge1xuXHRcdFx0XHR0b1trZXldID0gZnJvbVtrZXldO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChnZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHtcblx0XHRcdHN5bWJvbHMgPSBnZXRPd25Qcm9wZXJ0eVN5bWJvbHMoZnJvbSk7XG5cdFx0XHRmb3IgKHZhciBpID0gMDsgaSA8IHN5bWJvbHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0aWYgKHByb3BJc0VudW1lcmFibGUuY2FsbChmcm9tLCBzeW1ib2xzW2ldKSkge1xuXHRcdFx0XHRcdHRvW3N5bWJvbHNbaV1dID0gZnJvbVtzeW1ib2xzW2ldXTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiB0bztcbn07XG4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///822\n")},692:(__unused_webpack_module,exports,__webpack_require__)=>{"use strict";eval('var __webpack_unused_export__;\n/** @license React v17.0.2\n * react-dom-server.browser.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nvar l=__webpack_require__(822),m=__webpack_require__(888);function p(a){for(var b="https://reactjs.org/docs/error-decoder.html?invariant="+a,c=1;cK;K++)J[K]=K+1;J[15]=0;var oa=/^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD][:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$/,pa=Object.prototype.hasOwnProperty,qa={},ra={};\nfunction sa(a){if(pa.call(ra,a))return!0;if(pa.call(qa,a))return!1;if(oa.test(a))return ra[a]=!0;qa[a]=!0;return!1}function ta(a,b,c,d){if(null!==c&&0===c.type)return!1;switch(typeof b){case "function":case "symbol":return!0;case "boolean":if(d)return!1;if(null!==c)return!c.acceptsBooleans;a=a.toLowerCase().slice(0,5);return"data-"!==a&&"aria-"!==a;default:return!1}}\nfunction ua(a,b,c,d){if(null===b||"undefined"===typeof b||ta(a,b,c,d))return!0;if(d)return!1;if(null!==c)switch(c.type){case 3:return!b;case 4:return!1===b;case 5:return isNaN(b);case 6:return isNaN(b)||1>b}return!1}function M(a,b,c,d,f,h,t){this.acceptsBooleans=2===b||3===b||4===b;this.attributeName=d;this.attributeNamespace=f;this.mustUseProperty=c;this.propertyName=a;this.type=b;this.sanitizeURL=h;this.removeEmptyString=t}var N={};\n"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(a){N[a]=new M(a,0,!1,a,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(a){var b=a[0];N[b]=new M(b,1,!1,a[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(a){N[a]=new M(a,2,!1,a.toLowerCase(),null,!1,!1)});\n["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(a){N[a]=new M(a,2,!1,a,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(a){N[a]=new M(a,3,!1,a.toLowerCase(),null,!1,!1)});\n["checked","multiple","muted","selected"].forEach(function(a){N[a]=new M(a,3,!0,a,null,!1,!1)});["capture","download"].forEach(function(a){N[a]=new M(a,4,!1,a,null,!1,!1)});["cols","rows","size","span"].forEach(function(a){N[a]=new M(a,6,!1,a,null,!1,!1)});["rowSpan","start"].forEach(function(a){N[a]=new M(a,5,!1,a.toLowerCase(),null,!1,!1)});var va=/[\\-:]([a-z])/g;function wa(a){return a[1].toUpperCase()}\n"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(a){var b=a.replace(va,\nwa);N[b]=new M(b,1,!1,a,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(a){var b=a.replace(va,wa);N[b]=new M(b,1,!1,a,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(a){var b=a.replace(va,wa);N[b]=new M(b,1,!1,a,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(a){N[a]=new M(a,1,!1,a.toLowerCase(),null,!1,!1)});\nN.xlinkHref=new M("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(a){N[a]=new M(a,1,!1,a.toLowerCase(),null,!0,!0)});var xa=/["\'&<>]/;\nfunction O(a){if("boolean"===typeof a||"number"===typeof a)return""+a;a=""+a;var b=xa.exec(a);if(b){var c="",d,f=0;for(d=b.index;dV))throw Error(p(301));if(a===P)if(T=!0,a={action:c,next:null},null===U&&(U=new Map),c=U.get(b),void 0===c)U.set(b,a);else{for(b=c;null!==b.next;)b=b.next;b.next=a}}function Ja(){}\nvar X=null,Ka={readContext:function(a){var b=X.threadID;I(a,b);return a[b]},useContext:function(a){W();var b=X.threadID;I(a,b);return a[b]},useMemo:Ia,useReducer:Ga,useRef:function(a){P=W();R=Ca();var b=R.memoizedState;return null===b?(a={current:a},R.memoizedState=a):b},useState:function(a){return Ga(Fa,a)},useLayoutEffect:function(){},useCallback:function(a,b){return Ia(function(){return a},b)},useImperativeHandle:Ja,useEffect:Ja,useDebugValue:Ja,useDeferredValue:function(a){W();return a},useTransition:function(){W();\nreturn[function(a){a()},!1]},useOpaqueIdentifier:function(){return(X.identifierPrefix||"")+"R:"+(X.uniqueID++).toString(36)},useMutableSource:function(a,b){W();return b(a._source)}},La={html:"http://www.w3.org/1999/xhtml",mathml:"http://www.w3.org/1998/Math/MathML",svg:"http://www.w3.org/2000/svg"};function Ma(a){switch(a){case "svg":return"http://www.w3.org/2000/svg";case "math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}\nvar Na={area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},Oa=l({menuitem:!0},Na),Y={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,\ngridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Pa=["Webkit","ms","Moz","O"];Object.keys(Y).forEach(function(a){Pa.forEach(function(b){b=b+a.charAt(0).toUpperCase()+a.substring(1);Y[b]=Y[a]})});\nvar Qa=/([A-Z])/g,Ra=/^ms-/,Z=m.Children.toArray,Sa=la.ReactCurrentDispatcher,Ta={listing:!0,pre:!0,textarea:!0},Ua=/^[a-zA-Z][a-zA-Z:_\\.\\-\\d]*$/,Va={},Wa={};function Xa(a){if(void 0===a||null===a)return a;var b="";m.Children.forEach(a,function(a){null!=a&&(b+=a)});return b}var Ya=Object.prototype.hasOwnProperty,Za={children:null,dangerouslySetInnerHTML:null,suppressContentEditableWarning:null,suppressHydrationWarning:null};function $a(a,b){if(void 0===a)throw Error(p(152,F(b)||"Component"));}\nfunction ab(a,b,c){function d(d,h){var e=h.prototype&&h.prototype.isReactComponent,f=na(h,b,c,e),t=[],g=!1,n={isMounted:function(){return!1},enqueueForceUpdate:function(){if(null===t)return null},enqueueReplaceState:function(a,c){g=!0;t=[c]},enqueueSetState:function(a,c){if(null===t)return null;t.push(c)}};if(e){if(e=new h(d.props,f,n),"function"===typeof h.getDerivedStateFromProps){var k=h.getDerivedStateFromProps.call(null,d.props,e.state);null!=k&&(e.state=l({},e.state,k))}}else if(P={},e=h(d.props,\nf,n),e=Da(h,d.props,e,f),null==e||null==e.render){a=e;$a(a,h);return}e.props=d.props;e.context=f;e.updater=n;n=e.state;void 0===n&&(e.state=n=null);if("function"===typeof e.UNSAFE_componentWillMount||"function"===typeof e.componentWillMount)if("function"===typeof e.componentWillMount&&"function"!==typeof h.getDerivedStateFromProps&&e.componentWillMount(),"function"===typeof e.UNSAFE_componentWillMount&&"function"!==typeof h.getDerivedStateFromProps&&e.UNSAFE_componentWillMount(),t.length){n=t;var v=\ng;t=null;g=!1;if(v&&1===n.length)e.state=n[0];else{k=v?n[0]:e.state;var H=!0;for(v=v?1:0;v=g))throw Error(p(304));var e=new Uint16Array(g);e.set(d);J=e;J[0]=c+1;for(d=c;d=e.children.length){var L=e.footer;""!==L&&(this.previousWasTextNode=!1);this.stack.pop();if("select"===e.type)this.currentSelectValue=null;else if(null!=e.type&&null!=e.type.type&&e.type.type.$$typeof===B)this.popProvider(e.type);else if(e.type===D){this.suspenseDepth--;var G=h.pop();if(t){t=!1;var C=e.fallbackFrame;if(!C)throw Error(p(303));this.stack.push(C);h[this.suspenseDepth]+="\\x3c!--$!--\\x3e";continue}else h[this.suspenseDepth]+=\nG}h[this.suspenseDepth]+=L}else{var n=e.children[e.childIndex++],k="";try{k+=this.render(n,e.context,e.domNamespace)}catch(v){if(null!=v&&"function"===typeof v.then)throw Error(p(294));throw v;}finally{}h.length<=this.suspenseDepth&&h.push("");h[this.suspenseDepth]+=k}}return h[0]}finally{Sa.current=c,X=b,Ea()}};b.render=function(a,b,f){if("string"===typeof a||"number"===typeof a){f=""+a;if(""===f)return"";if(this.makeStaticMarkup)return O(f);if(this.previousWasTextNode)return"\\x3c!-- --\\x3e"+O(f);\nthis.previousWasTextNode=!0;return O(f)}b=ab(a,b,this.threadID);a=b.child;b=b.context;if(null===a||!1===a)return"";if(!m.isValidElement(a)){if(null!=a&&null!=a.$$typeof){f=a.$$typeof;if(f===q)throw Error(p(257));throw Error(p(258,f.toString()));}a=Z(a);this.stack.push({type:null,domNamespace:f,children:a,childIndex:0,context:b,footer:""});return""}var c=a.type;if("string"===typeof c)return this.renderDOM(a,b,f);switch(c){case ka:case ja:case u:case z:case ca:case r:return a=Z(a.props.children),this.stack.push({type:null,\ndomNamespace:f,children:a,childIndex:0,context:b,footer:""}),"";case D:throw Error(p(294));case ia:throw Error(p(343));}if("object"===typeof c&&null!==c)switch(c.$$typeof){case ba:P={};var d=c.render(a.props,a.ref);d=Da(c.render,a.props,d,a.ref);d=Z(d);this.stack.push({type:null,domNamespace:f,children:d,childIndex:0,context:b,footer:""});return"";case da:return a=[m.createElement(c.type,l({ref:a.ref},a.props))],this.stack.push({type:null,domNamespace:f,children:a,childIndex:0,context:b,footer:""}),\n"";case B:return c=Z(a.props.children),f={type:a,domNamespace:f,children:c,childIndex:0,context:b,footer:""},this.pushProvider(a),this.stack.push(f),"";case aa:c=a.type;d=a.props;var g=this.threadID;I(c,g);c=Z(d.children(c[g]));this.stack.push({type:a,domNamespace:f,children:c,childIndex:0,context:b,footer:""});return"";case ha:throw Error(p(338));case ea:return c=a.type,d=c._init,c=d(c._payload),a=[m.createElement(c,l({ref:a.ref},a.props))],this.stack.push({type:null,domNamespace:f,children:a,childIndex:0,\ncontext:b,footer:""}),""}throw Error(p(130,null==c?c:typeof c,""));};b.renderDOM=function(a,b,f){var c=a.type.toLowerCase();f===La.html&&Ma(c);if(!Va.hasOwnProperty(c)){if(!Ua.test(c))throw Error(p(65,c));Va[c]=!0}var d=a.props;if("input"===c)d=l({type:void 0},d,{defaultChecked:void 0,defaultValue:void 0,value:null!=d.value?d.value:d.defaultValue,checked:null!=d.checked?d.checked:d.defaultChecked});else if("textarea"===c){var g=d.value;if(null==g){g=d.defaultValue;var e=d.children;if(null!=e){if(null!=\ng)throw Error(p(92));if(Array.isArray(e)){if(!(1>=e.length))throw Error(p(93));e=e[0]}g=""+e}null==g&&(g="")}d=l({},d,{value:void 0,children:""+g})}else if("select"===c)this.currentSelectValue=null!=d.value?d.value:d.defaultValue,d=l({},d,{value:void 0});else if("option"===c){e=this.currentSelectValue;var L=Xa(d.children);if(null!=e){var G=null!=d.value?d.value+"":L;g=!1;if(Array.isArray(e))for(var C=0;C":(w+=">",g="");a:{e=d.dangerouslySetInnerHTML;if(null!=e){if(null!=e.__html){e=e.__html;break a}}else if(e=d.children,"string"===typeof e||"number"===typeof e){e=O(e);break a}e=null}null!=e?(d=[],Ta.hasOwnProperty(c)&&"\\n"===e.charAt(0)&&(w+="\\n"),w+=e):d=Z(d.children);a=a.type;f=null==f||"http://www.w3.org/1999/xhtml"===f?Ma(a):"http://www.w3.org/2000/svg"===\nf&&"foreignObject"===a?"http://www.w3.org/1999/xhtml":f;this.stack.push({domNamespace:f,type:c,children:d,childIndex:0,context:b,footer:g});this.previousWasTextNode=!1;return w};return a}();__webpack_unused_export__=function(){throw Error(p(207));};exports.renderToStaticMarkup=function(a,b){a=new bb(a,!0,b);try{return a.read(Infinity)}finally{a.destroy()}};__webpack_unused_export__=function(){throw Error(p(208));};__webpack_unused_export__=function(a,b){a=new bb(a,!1,b);try{return a.read(Infinity)}finally{a.destroy()}};\n__webpack_unused_export__="17.0.2";\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uLi9kZW1vL25vZGVfbW9kdWxlcy9yZWFjdC1kb20vY2pzL3JlYWN0LWRvbS1zZXJ2ZXIuYnJvd3Nlci5wcm9kdWN0aW9uLm1pbi5qcz9iNzQyIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2EsTUFBTSxtQkFBTyxDQUFDLEdBQWUsSUFBSSxtQkFBTyxDQUFDLEdBQU8sRUFBRSxjQUFjLHlFQUF5RSxtQkFBbUIsbURBQW1ELG1DQUFtQztBQUMvUDtBQUNBLDJDQUEyQyxpQkFBaUIsb0JBQW9CLHNCQUFzQix5QkFBeUIsc0JBQXNCLHNCQUFzQixzQkFBc0IsMEJBQTBCLHNCQUFzQiw0QkFBNEIsbUJBQW1CLG1CQUFtQixvQkFBb0IsMEJBQTBCLG9CQUFvQiwrQkFBK0I7QUFDcFosY0FBYyx1QkFBdUIsNERBQTRELGdDQUFnQyxVQUFVLHdCQUF3QixzQkFBc0Isd0JBQXdCLDBCQUEwQix3QkFBd0IsNkJBQTZCLDBDQUEwQyxxREFBcUQsNkRBQTZELHVCQUF1Qiw0QkFBNEI7QUFDL2UsMENBQTBDLHlCQUF5Qiw0QkFBNEIscUJBQXFCLFVBQVUsSUFBSSxlQUFlLFdBQVcsWUFBWSxrRUFBa0UsZ0JBQWdCLDJCQUEyQixLQUFLLDZDQUE2QyxxQkFBcUIseUVBQXlFLHFCQUFxQixLQUFLLHlCQUF5QixJQUFJLFVBQVU7QUFDdGUsa0NBQWtDLEtBQUssYUFBYSxRQUFRLDZZQUE2WTtBQUN6YyxlQUFlLDBCQUEwQiwwQkFBMEIsOEJBQThCLFNBQVMsU0FBUyxxQkFBcUIsaUNBQWlDLGlCQUFpQix1Q0FBdUMsNkJBQTZCLHFDQUFxQyw2QkFBNkIsK0JBQStCO0FBQy9WLHFCQUFxQiwwREFBMEQsY0FBYywyQkFBMkIsZ0JBQWdCLG9CQUFvQix1QkFBdUIsNEJBQTRCLFNBQVMsMEJBQTBCLHlDQUF5QyxxQkFBcUIsMEJBQTBCLHVC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USxPQUFPLHdGQUF3RixTQUFTO0FBQ2xiLHdEQUF3RCxpQkFBaUIsaUVBQWlFLEVBQUUsNEJBQTRCLFVBQVUsU0FBUyxHQUFHLHlCQUEwQixZQUFZLHNCQUFzQiw0QkFBNEIsZUFBZSxpQkFBaUIsSUFBSSx3QkFBd0IsUUFBUSxjQUFjLHlCQUFnQyxZQUFZLHNCQUFzQix5QkFBc0IsZUFBZSxpQkFBaUIsSUFBSSx3QkFBd0IsUUFBUTtBQUNwZ0IseUJBQWUiLCJmaWxlIjoiNjkyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoqIEBsaWNlbnNlIFJlYWN0IHYxNy4wLjJcbiAqIHJlYWN0LWRvbS1zZXJ2ZXIuYnJvd3Nlci5wcm9kdWN0aW9uLm1pbi5qc1xuICpcbiAqIENvcHlyaWdodCAoYykgRmFjZWJvb2ssIEluYy4gYW5kIGl0cyBhZmZpbGlhdGVzLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICovXG4ndXNlIHN0cmljdCc7dmFyIGw9cmVxdWlyZShcIm9iamVjdC1hc3NpZ25cIiksbT1yZXF1aXJlKFwicmVhY3RcIik7ZnVuY3Rpb24gcChhKXtmb3IodmFyIGI9XCJodHRwczovL3JlYWN0anMub3JnL2RvY3MvZXJyb3ItZGVjb2Rlci5odG1sP2ludmFyaWFudD1cIithLGM9MTtjPGFyZ3VtZW50cy5sZW5ndGg7YysrKWIrPVwiJmFyZ3NbXT1cIitlbmNvZGVVUklDb21wb25lbnQoYXJndW1lbnRzW2NdKTtyZXR1cm5cIk1pbmlmaWVkIFJlYWN0IGVycm9yICNcIithK1wiOyB2aXNpdCBcIitiK1wiIGZvciB0aGUgZnVsbCBtZXNzYWdlIG9yIHVzZSB0aGUgbm9uLW1pbmlmaWVkIGRldiBlbnZpcm9ubWVudCBmb3IgZnVsbCBlcnJvcnMgYW5kIGFkZGl0aW9uYWwgaGVscGZ1bCB3YXJuaW5ncy5cIn1cbnZhciBxPTYwMTA2LHI9NjAxMDcsdT02MDEwOCx6PTYwMTE0LEI9NjAxMDksYWE9NjAxMTAsYmE9NjAxMTIsRD02MDExMyxjYT02MDEyMCxkYT02MDExNSxlYT02MDExNixmYT02MDEyMSxoYT02MDExNyxpYT02MDExOSxqYT02MDEyOSxrYT02MDEzMTtcbmlmKFwiZnVuY3Rpb25cIj09PXR5cGVvZiBTeW1ib2wmJlN5bWJvbC5mb3Ipe3ZhciBFPVN5bWJvbC5mb3I7cT1FKFwicmVhY3QucG9ydGFsXCIpO3I9RShcInJlYWN0LmZyYWdtZW50XCIpO3U9RShcInJlYWN0LnN0cmljdF9tb2RlXCIpO3o9RShcInJlYWN0LnByb2ZpbGVyXCIpO0I9RShcInJlYWN0LnByb3ZpZGVyXCIpO2FhPUUoXCJyZWFjdC5jb250ZXh0XCIpO2JhPUUoXCJyZWFjdC5mb3J3YXJkX3JlZlwiKTtEPUUoXCJyZWFjdC5zdXNwZW5zZVwiKTtjYT1FKFwicmVhY3Quc3VzcGVuc2VfbGlzdFwiKTtkYT1FKFwicmVhY3QubWVtb1wiKTtlYT1FKFwicmVhY3QubGF6eVwiKTtmYT1FKFwicmVhY3QuYmxvY2tcIik7aGE9RShcInJlYWN0LmZ1bmRhbWVudGFsXCIpO2lhPUUoXCJyZWFjdC5zY29wZVwiKTtqYT1FKFwicmVhY3QuZGVidWdfdHJhY2VfbW9kZVwiKTtrYT1FKFwicmVhY3QubGVnYWN5X2hpZGRlblwiKX1cbmZ1bmN0aW9uIEYoYSl7aWYobnVsbD09YSlyZXR1cm4gbnVsbDtpZihcImZ1bmN0aW9uXCI9PT10eXBlb2YgYSlyZXR1cm4gYS5kaXNwbGF5TmFtZXx8YS5uYW1lfHxudWxsO2lmKFwic3RyaW5nXCI9PT10eXBlb2YgYSlyZXR1cm4gYTtzd2l0Y2goYSl7Y2FzZSByOnJldHVyblwiRnJhZ21lbnRcIjtjYXNlIHE6cmV0dXJuXCJQb3J0YWxcIjtjYXNlIHo6cmV0dXJuXCJQcm9maWxlclwiO2Nhc2UgdTpyZXR1cm5cIlN0cmljdE1vZGVcIjtjYXNlIEQ6cmV0dXJuXCJTdXNwZW5zZVwiO2Nhc2UgY2E6cmV0dXJuXCJTdXNwZW5zZUxpc3RcIn1pZihcIm9iamVjdFwiPT09dHlwZW9mIGEpc3dpdGNoKGEuJCR0eXBlb2Ype2Nhc2UgYWE6cmV0dXJuKGEuZGlzcGxheU5hbWV8fFwiQ29udGV4dFwiKStcIi5Db25zdW1lclwiO2Nhc2UgQjpyZXR1cm4oYS5fY29udGV4dC5kaXNwbGF5TmFtZXx8XCJDb250ZXh0XCIpK1wiLlByb3ZpZGVyXCI7Y2FzZSBiYTp2YXIgYj1hLnJlbmRlcjtiPWIuZGlzcGxheU5hbWV8fGIubmFtZXx8XCJcIjtyZXR1cm4gYS5kaXNwbGF5TmFtZXx8XG4oXCJcIiE9PWI/XCJGb3J3YXJkUmVmKFwiK2IrXCIpXCI6XCJGb3J3YXJkUmVmXCIpO2Nhc2UgZGE6cmV0dXJuIEYoYS50eXBlKTtjYXNlIGZhOnJldHVybiBGKGEuX3JlbmRlcik7Y2FzZSBlYTpiPWEuX3BheWxvYWQ7YT1hLl9pbml0O3RyeXtyZXR1cm4gRihhKGIpKX1jYXRjaChjKXt9fXJldHVybiBudWxsfXZhciBsYT1tLl9fU0VDUkVUX0lOVEVSTkFMU19ET19OT1RfVVNFX09SX1lPVV9XSUxMX0JFX0ZJUkVELG1hPXt9O2Z1bmN0aW9uIEkoYSxiKXtmb3IodmFyIGM9YS5fdGhyZWFkQ291bnR8MDtjPD1iO2MrKylhW2NdPWEuX2N1cnJlbnRWYWx1ZTIsYS5fdGhyZWFkQ291bnQ9YysxfWZ1bmN0aW9uIG5hKGEsYixjLGQpe2lmKGQmJihkPWEuY29udGV4dFR5cGUsXCJvYmplY3RcIj09PXR5cGVvZiBkJiZudWxsIT09ZCkpcmV0dXJuIEkoZCxjKSxkW2NdO2lmKGE9YS5jb250ZXh0VHlwZXMpe2M9e307Zm9yKHZhciBmIGluIGEpY1tmXT1iW2ZdO2I9Y31lbHNlIGI9bWE7cmV0dXJuIGJ9XG5mb3IodmFyIEo9bmV3IFVpbnQxNkFycmF5KDE2KSxLPTA7MTU+SztLKyspSltLXT1LKzE7SlsxNV09MDt2YXIgb2E9L15bOkEtWl9hLXpcXHUwMEMwLVxcdTAwRDZcXHUwMEQ4LVxcdTAwRjZcXHUwMEY4LVxcdTAyRkZcXHUwMzcwLVxcdTAzN0RcXHUwMzdGLVxcdTFGRkZcXHUyMDBDLVxcdTIwMERcXHUyMDcwLVxcdTIxOEZcXHUyQzAwLVxcdTJGRUZcXHUzMDAxLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRkRdWzpBLVpfYS16XFx1MDBDMC1cXHUwMEQ2XFx1MDBEOC1cXHUwMEY2XFx1MDBGOC1cXHUwMkZGXFx1MDM3MC1cXHUwMzdEXFx1MDM3Ri1cXHUxRkZGXFx1MjAwQy1cXHUyMDBEXFx1MjA3MC1cXHUyMThGXFx1MkMwMC1cXHUyRkVGXFx1MzAwMS1cXHVEN0ZGXFx1RjkwMC1cXHVGRENGXFx1RkRGMC1cXHVGRkZEXFwtLjAtOVxcdTAwQjdcXHUwMzAwLVxcdTAzNkZcXHUyMDNGLVxcdTIwNDBdKiQvLHBhPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkscWE9e30scmE9e307XG5mdW5jdGlvbiBzYShhKXtpZihwYS5jYWxsKHJhLGEpKXJldHVybiEwO2lmKHBhLmNhbGwocWEsYSkpcmV0dXJuITE7aWYob2EudGVzdChhKSlyZXR1cm4gcmFbYV09ITA7cWFbYV09ITA7cmV0dXJuITF9ZnVuY3Rpb24gdGEoYSxiLGMsZCl7aWYobnVsbCE9PWMmJjA9PT1jLnR5cGUpcmV0dXJuITE7c3dpdGNoKHR5cGVvZiBiKXtjYXNlIFwiZnVuY3Rpb25cIjpjYXNlIFwic3ltYm9sXCI6cmV0dXJuITA7Y2FzZSBcImJvb2xlYW5cIjppZihkKXJldHVybiExO2lmKG51bGwhPT1jKXJldHVybiFjLmFjY2VwdHNCb29sZWFuczthPWEudG9Mb3dlckNhc2UoKS5zbGljZSgwLDUpO3JldHVyblwiZGF0YS1cIiE9PWEmJlwiYXJpYS1cIiE9PWE7ZGVmYXVsdDpyZXR1cm4hMX19XG5mdW5jdGlvbiB1YShhLGIsYyxkKXtpZihudWxsPT09Ynx8XCJ1bmRlZmluZWRcIj09PXR5cGVvZiBifHx0YShhLGIsYyxkKSlyZXR1cm4hMDtpZihkKXJldHVybiExO2lmKG51bGwhPT1jKXN3aXRjaChjLnR5cGUpe2Nhc2UgMzpyZXR1cm4hYjtjYXNlIDQ6cmV0dXJuITE9PT1iO2Nhc2UgNTpyZXR1cm4gaXNOYU4oYik7Y2FzZSA2OnJldHVybiBpc05hTihiKXx8MT5ifXJldHVybiExfWZ1bmN0aW9uIE0oYSxiLGMsZCxmLGgsdCl7dGhpcy5hY2NlcHRzQm9vbGVhbnM9Mj09PWJ8fDM9PT1ifHw0PT09Yjt0aGlzLmF0dHJpYnV0ZU5hbWU9ZDt0aGlzLmF0dHJpYnV0ZU5hbWVzcGFjZT1mO3RoaXMubXVzdFVzZVByb3BlcnR5PWM7dGhpcy5wcm9wZXJ0eU5hbWU9YTt0aGlzLnR5cGU9Yjt0aGlzLnNhbml0aXplVVJMPWg7dGhpcy5yZW1vdmVFbXB0eVN0cmluZz10fXZhciBOPXt9O1xuXCJjaGlsZHJlbiBkYW5nZXJvdXNseVNldElubmVySFRNTCBkZWZhdWx0VmFsdWUgZGVmYXVsdENoZWNrZWQgaW5uZXJIVE1MIHN1cHByZXNzQ29udGVudEVkaXRhYmxlV2FybmluZyBzdXBwcmVzc0h5ZHJhdGlvbldhcm5pbmcgc3R5bGVcIi5zcGxpdChcIiBcIikuZm9yRWFjaChmdW5jdGlvbihhKXtOW2FdPW5ldyBNKGEsMCwhMSxhLG51bGwsITEsITEpfSk7W1tcImFjY2VwdENoYXJzZXRcIixcImFjY2VwdC1jaGFyc2V0XCJdLFtcImNsYXNzTmFtZVwiLFwiY2xhc3NcIl0sW1wiaHRtbEZvclwiLFwiZm9yXCJdLFtcImh0dHBFcXVpdlwiLFwiaHR0cC1lcXVpdlwiXV0uZm9yRWFjaChmdW5jdGlvbihhKXt2YXIgYj1hWzBdO05bYl09bmV3IE0oYiwxLCExLGFbMV0sbnVsbCwhMSwhMSl9KTtbXCJjb250ZW50RWRpdGFibGVcIixcImRyYWdnYWJsZVwiLFwic3BlbGxDaGVja1wiLFwidmFsdWVcIl0uZm9yRWFjaChmdW5jdGlvbihhKXtOW2FdPW5ldyBNKGEsMiwhMSxhLnRvTG93ZXJDYXNlKCksbnVsbCwhMSwhMSl9KTtcbltcImF1dG9SZXZlcnNlXCIsXCJleHRlcm5hbFJlc291cmNlc1JlcXVpcmVkXCIsXCJmb2N1c2FibGVcIixcInByZXNlcnZlQWxwaGFcIl0uZm9yRWFjaChmdW5jdGlvbihhKXtOW2FdPW5ldyBNKGEsMiwhMSxhLG51bGwsITEsITEpfSk7XCJhbGxvd0Z1bGxTY3JlZW4gYXN5bmMgYXV0b0ZvY3VzIGF1dG9QbGF5IGNvbnRyb2xzIGRlZmF1bHQgZGVmZXIgZGlzYWJsZWQgZGlzYWJsZVBpY3R1cmVJblBpY3R1cmUgZGlzYWJsZVJlbW90ZVBsYXliYWNrIGZvcm1Ob1ZhbGlkYXRlIGhpZGRlbiBsb29wIG5vTW9kdWxlIG5vVmFsaWRhdGUgb3BlbiBwbGF5c0lubGluZSByZWFkT25seSByZXF1aXJlZCByZXZlcnNlZCBzY29wZWQgc2VhbWxlc3MgaXRlbVNjb3BlXCIuc3BsaXQoXCIgXCIpLmZvckVhY2goZnVuY3Rpb24oYSl7TlthXT1uZXcgTShhLDMsITEsYS50b0xvd2VyQ2FzZSgpLG51bGwsITEsITEpfSk7XG5bXCJjaGVja2VkXCIsXCJtdWx0aXBsZVwiLFwibXV0ZWRcIixcInNlbGVjdGVkXCJdLmZvckVhY2goZnVuY3Rpb24oYSl7TlthXT1uZXcgTShhLDMsITAsYSxudWxsLCExLCExKX0pO1tcImNhcHR1cmVcIixcImRvd25sb2FkXCJdLmZvckVhY2goZnVuY3Rpb24oYSl7TlthXT1uZXcgTShhLDQsITEsYSxudWxsLCExLCExKX0pO1tcImNvbHNcIixcInJvd3NcIixcInNpemVcIixcInNwYW5cIl0uZm9yRWFjaChmdW5jdGlvbihhKXtOW2FdPW5ldyBNKGEsNiwhMSxhLG51bGwsITEsITEpfSk7W1wicm93U3BhblwiLFwic3RhcnRcIl0uZm9yRWFjaChmdW5jdGlvbihhKXtOW2FdPW5ldyBNKGEsNSwhMSxhLnRvTG93ZXJDYXNlKCksbnVsbCwhMSwhMSl9KTt2YXIgdmE9L1tcXC06XShbYS16XSkvZztmdW5jdGlvbiB3YShhKXtyZXR1cm4gYVsxXS50b1VwcGVyQ2FzZSgpfVxuXCJhY2NlbnQtaGVpZ2h0IGFsaWdubWVudC1iYXNlbGluZSBhcmFiaWMtZm9ybSBiYXNlbGluZS1zaGlmdCBjYXAtaGVpZ2h0IGNsaXAtcGF0aCBjbGlwLXJ1bGUgY29sb3ItaW50ZXJwb2xhdGlvbiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnMgY29sb3ItcHJvZmlsZSBjb2xvci1yZW5kZXJpbmcgZG9taW5hbnQtYmFzZWxpbmUgZW5hYmxlLWJhY2tncm91bmQgZmlsbC1vcGFjaXR5IGZpbGwtcnVsZSBmbG9vZC1jb2xvciBmbG9vZC1vcGFjaXR5IGZvbnQtZmFtaWx5IGZvbnQtc2l6ZSBmb250LXNpemUtYWRqdXN0IGZvbnQtc3RyZXRjaCBmb250LXN0eWxlIGZvbnQtdmFyaWFudCBmb250LXdlaWdodCBnbHlwaC1uYW1lIGdseXBoLW9yaWVudGF0aW9uLWhvcml6b250YWwgZ2x5cGgtb3JpZW50YXRpb24tdmVydGljYWwgaG9yaXotYWR2LXggaG9yaXotb3JpZ2luLXggaW1hZ2UtcmVuZGVyaW5nIGxldHRlci1zcGFjaW5nIGxpZ2h0aW5nLWNvbG9yIG1hcmtlci1lbmQgbWFya2VyLW1pZCBtYXJrZXItc3RhcnQgb3ZlcmxpbmUtcG9zaXRpb24gb3ZlcmxpbmUtdGhpY2tuZXNzIHBhaW50LW9yZGVyIHBhbm9zZS0xIHBvaW50ZXItZXZlbnRzIHJlbmRlcmluZy1pbnRlbnQgc2hhcGUtcmVuZGVyaW5nIHN0b3AtY29sb3Igc3RvcC1vcGFjaXR5IHN0cmlrZXRocm91Z2gtcG9zaXRpb24gc3RyaWtldGhyb3VnaC10aGlja25lc3Mgc3Ryb2tlLWRhc2hhcnJheSBzdHJva2UtZGFzaG9mZnNldCBzdHJva2UtbGluZWNhcCBzdHJva2UtbGluZWpvaW4gc3Ryb2tlLW1pdGVybGltaXQgc3Ryb2tlLW9wYWNpdHkgc3Ryb2tlLXdpZHRoIHRleHQtYW5jaG9yIHRleHQtZGVjb3JhdGlvbiB0ZXh0LXJlbmRlcmluZyB1bmRlcmxpbmUtcG9zaXRpb24gdW5kZXJsaW5lLXRoaWNrbmVzcyB1bmljb2RlLWJpZGkgdW5pY29kZS1yYW5nZSB1bml0cy1wZXItZW0gdi1hbHBoYWJldGljIHYtaGFuZ2luZyB2LWlkZW9ncmFwaGljIHYtbWF0aGVtYXRpY2FsIHZlY3Rvci1lZmZlY3QgdmVydC1hZHYteSB2ZXJ0LW9yaWdpbi14IHZlcnQtb3JpZ2luLXkgd29yZC1zcGFjaW5nIHdyaXRpbmctbW9kZSB4bWxuczp4bGluayB4LWhlaWdodFwiLnNwbGl0KFwiIFwiKS5mb3JFYWNoKGZ1bmN0aW9uKGEpe3ZhciBiPWEucmVwbGFjZSh2YSxcbndhKTtOW2JdPW5ldyBNKGIsMSwhMSxhLG51bGwsITEsITEpfSk7XCJ4bGluazphY3R1YXRlIHhsaW5rOmFyY3JvbGUgeGxpbms6cm9sZSB4bGluazpzaG93IHhsaW5rOnRpdGxlIHhsaW5rOnR5cGVcIi5zcGxpdChcIiBcIikuZm9yRWFjaChmdW5jdGlvbihhKXt2YXIgYj1hLnJlcGxhY2UodmEsd2EpO05bYl09bmV3IE0oYiwxLCExLGEsXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIsITEsITEpfSk7W1wieG1sOmJhc2VcIixcInhtbDpsYW5nXCIsXCJ4bWw6c3BhY2VcIl0uZm9yRWFjaChmdW5jdGlvbihhKXt2YXIgYj1hLnJlcGxhY2UodmEsd2EpO05bYl09bmV3IE0oYiwxLCExLGEsXCJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2VcIiwhMSwhMSl9KTtbXCJ0YWJJbmRleFwiLFwiY3Jvc3NPcmlnaW5cIl0uZm9yRWFjaChmdW5jdGlvbihhKXtOW2FdPW5ldyBNKGEsMSwhMSxhLnRvTG93ZXJDYXNlKCksbnVsbCwhMSwhMSl9KTtcbk4ueGxpbmtIcmVmPW5ldyBNKFwieGxpbmtIcmVmXCIsMSwhMSxcInhsaW5rOmhyZWZcIixcImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiwhMCwhMSk7W1wic3JjXCIsXCJocmVmXCIsXCJhY3Rpb25cIixcImZvcm1BY3Rpb25cIl0uZm9yRWFjaChmdW5jdGlvbihhKXtOW2FdPW5ldyBNKGEsMSwhMSxhLnRvTG93ZXJDYXNlKCksbnVsbCwhMCwhMCl9KTt2YXIgeGE9L1tcIicmPD5dLztcbmZ1bmN0aW9uIE8oYSl7aWYoXCJib29sZWFuXCI9PT10eXBlb2YgYXx8XCJudW1iZXJcIj09PXR5cGVvZiBhKXJldHVyblwiXCIrYTthPVwiXCIrYTt2YXIgYj14YS5leGVjKGEpO2lmKGIpe3ZhciBjPVwiXCIsZCxmPTA7Zm9yKGQ9Yi5pbmRleDtkPGEubGVuZ3RoO2QrKyl7c3dpdGNoKGEuY2hhckNvZGVBdChkKSl7Y2FzZSAzNDpiPVwiJnF1b3Q7XCI7YnJlYWs7Y2FzZSAzODpiPVwiJmFtcDtcIjticmVhaztjYXNlIDM5OmI9XCImI3gyNztcIjticmVhaztjYXNlIDYwOmI9XCImbHQ7XCI7YnJlYWs7Y2FzZSA2MjpiPVwiJmd0O1wiO2JyZWFrO2RlZmF1bHQ6Y29udGludWV9ZiE9PWQmJihjKz1hLnN1YnN0cmluZyhmLGQpKTtmPWQrMTtjKz1ifWE9ZiE9PWQ/YythLnN1YnN0cmluZyhmLGQpOmN9cmV0dXJuIGF9XG5mdW5jdGlvbiB5YShhLGIpe3ZhciBjPU4uaGFzT3duUHJvcGVydHkoYSk/TlthXTpudWxsO3ZhciBkO2lmKGQ9XCJzdHlsZVwiIT09YSlkPW51bGwhPT1jPzA9PT1jLnR5cGU6ISgyPGEubGVuZ3RoKXx8XCJvXCIhPT1hWzBdJiZcIk9cIiE9PWFbMF18fFwiblwiIT09YVsxXSYmXCJOXCIhPT1hWzFdPyExOiEwO2lmKGR8fHVhKGEsYixjLCExKSlyZXR1cm5cIlwiO2lmKG51bGwhPT1jKXthPWMuYXR0cmlidXRlTmFtZTtkPWMudHlwZTtpZigzPT09ZHx8ND09PWQmJiEwPT09YilyZXR1cm4gYSsnPVwiXCInO2Muc2FuaXRpemVVUkwmJihiPVwiXCIrYik7cmV0dXJuIGErJz1cIicrKE8oYikrJ1wiJyl9cmV0dXJuIHNhKGEpP2ErJz1cIicrKE8oYikrJ1wiJyk6XCJcIn1mdW5jdGlvbiB6YShhLGIpe3JldHVybiBhPT09YiYmKDAhPT1hfHwxL2E9PT0xL2IpfHxhIT09YSYmYiE9PWJ9XG52YXIgQWE9XCJmdW5jdGlvblwiPT09dHlwZW9mIE9iamVjdC5pcz9PYmplY3QuaXM6emEsUD1udWxsLFE9bnVsbCxSPW51bGwsUz0hMSxUPSExLFU9bnVsbCxWPTA7ZnVuY3Rpb24gVygpe2lmKG51bGw9PT1QKXRocm93IEVycm9yKHAoMzIxKSk7cmV0dXJuIFB9ZnVuY3Rpb24gQmEoKXtpZigwPFYpdGhyb3cgRXJyb3IocCgzMTIpKTtyZXR1cm57bWVtb2l6ZWRTdGF0ZTpudWxsLHF1ZXVlOm51bGwsbmV4dDpudWxsfX1mdW5jdGlvbiBDYSgpe251bGw9PT1SP251bGw9PT1RPyhTPSExLFE9Uj1CYSgpKTooUz0hMCxSPVEpOm51bGw9PT1SLm5leHQ/KFM9ITEsUj1SLm5leHQ9QmEoKSk6KFM9ITAsUj1SLm5leHQpO3JldHVybiBSfWZ1bmN0aW9uIERhKGEsYixjLGQpe2Zvcig7VDspVD0hMSxWKz0xLFI9bnVsbCxjPWEoYixkKTtFYSgpO3JldHVybiBjfWZ1bmN0aW9uIEVhKCl7UD1udWxsO1Q9ITE7UT1udWxsO1Y9MDtSPVU9bnVsbH1cbmZ1bmN0aW9uIEZhKGEsYil7cmV0dXJuXCJmdW5jdGlvblwiPT09dHlwZW9mIGI/YihhKTpifWZ1bmN0aW9uIEdhKGEsYixjKXtQPVcoKTtSPUNhKCk7aWYoUyl7dmFyIGQ9Ui5xdWV1ZTtiPWQuZGlzcGF0Y2g7aWYobnVsbCE9PVUmJihjPVUuZ2V0KGQpLHZvaWQgMCE9PWMpKXtVLmRlbGV0ZShkKTtkPVIubWVtb2l6ZWRTdGF0ZTtkbyBkPWEoZCxjLmFjdGlvbiksYz1jLm5leHQ7d2hpbGUobnVsbCE9PWMpO1IubWVtb2l6ZWRTdGF0ZT1kO3JldHVybltkLGJdfXJldHVybltSLm1lbW9pemVkU3RhdGUsYl19YT1hPT09RmE/XCJmdW5jdGlvblwiPT09dHlwZW9mIGI/YigpOmI6dm9pZCAwIT09Yz9jKGIpOmI7Ui5tZW1vaXplZFN0YXRlPWE7YT1SLnF1ZXVlPXtsYXN0Om51bGwsZGlzcGF0Y2g6bnVsbH07YT1hLmRpc3BhdGNoPUhhLmJpbmQobnVsbCxQLGEpO3JldHVybltSLm1lbW9pemVkU3RhdGUsYV19XG5mdW5jdGlvbiBJYShhLGIpe1A9VygpO1I9Q2EoKTtiPXZvaWQgMD09PWI/bnVsbDpiO2lmKG51bGwhPT1SKXt2YXIgYz1SLm1lbW9pemVkU3RhdGU7aWYobnVsbCE9PWMmJm51bGwhPT1iKXt2YXIgZD1jWzFdO2E6aWYobnVsbD09PWQpZD0hMTtlbHNle2Zvcih2YXIgZj0wO2Y8ZC5sZW5ndGgmJmY8Yi5sZW5ndGg7ZisrKWlmKCFBYShiW2ZdLGRbZl0pKXtkPSExO2JyZWFrIGF9ZD0hMH1pZihkKXJldHVybiBjWzBdfX1hPWEoKTtSLm1lbW9pemVkU3RhdGU9W2EsYl07cmV0dXJuIGF9ZnVuY3Rpb24gSGEoYSxiLGMpe2lmKCEoMjU+VikpdGhyb3cgRXJyb3IocCgzMDEpKTtpZihhPT09UClpZihUPSEwLGE9e2FjdGlvbjpjLG5leHQ6bnVsbH0sbnVsbD09PVUmJihVPW5ldyBNYXApLGM9VS5nZXQoYiksdm9pZCAwPT09YylVLnNldChiLGEpO2Vsc2V7Zm9yKGI9YztudWxsIT09Yi5uZXh0OyliPWIubmV4dDtiLm5leHQ9YX19ZnVuY3Rpb24gSmEoKXt9XG52YXIgWD1udWxsLEthPXtyZWFkQ29udGV4dDpmdW5jdGlvbihhKXt2YXIgYj1YLnRocmVhZElEO0koYSxiKTtyZXR1cm4gYVtiXX0sdXNlQ29udGV4dDpmdW5jdGlvbihhKXtXKCk7dmFyIGI9WC50aHJlYWRJRDtJKGEsYik7cmV0dXJuIGFbYl19LHVzZU1lbW86SWEsdXNlUmVkdWNlcjpHYSx1c2VSZWY6ZnVuY3Rpb24oYSl7UD1XKCk7Uj1DYSgpO3ZhciBiPVIubWVtb2l6ZWRTdGF0ZTtyZXR1cm4gbnVsbD09PWI/KGE9e2N1cnJlbnQ6YX0sUi5tZW1vaXplZFN0YXRlPWEpOmJ9LHVzZVN0YXRlOmZ1bmN0aW9uKGEpe3JldHVybiBHYShGYSxhKX0sdXNlTGF5b3V0RWZmZWN0OmZ1bmN0aW9uKCl7fSx1c2VDYWxsYmFjazpmdW5jdGlvbihhLGIpe3JldHVybiBJYShmdW5jdGlvbigpe3JldHVybiBhfSxiKX0sdXNlSW1wZXJhdGl2ZUhhbmRsZTpKYSx1c2VFZmZlY3Q6SmEsdXNlRGVidWdWYWx1ZTpKYSx1c2VEZWZlcnJlZFZhbHVlOmZ1bmN0aW9uKGEpe1coKTtyZXR1cm4gYX0sdXNlVHJhbnNpdGlvbjpmdW5jdGlvbigpe1coKTtcbnJldHVybltmdW5jdGlvbihhKXthKCl9LCExXX0sdXNlT3BhcXVlSWRlbnRpZmllcjpmdW5jdGlvbigpe3JldHVybihYLmlkZW50aWZpZXJQcmVmaXh8fFwiXCIpK1wiUjpcIisoWC51bmlxdWVJRCsrKS50b1N0cmluZygzNil9LHVzZU11dGFibGVTb3VyY2U6ZnVuY3Rpb24oYSxiKXtXKCk7cmV0dXJuIGIoYS5fc291cmNlKX19LExhPXtodG1sOlwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiLG1hdGhtbDpcImh0dHA6Ly93d3cudzMub3JnLzE5OTgvTWF0aC9NYXRoTUxcIixzdmc6XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wifTtmdW5jdGlvbiBNYShhKXtzd2l0Y2goYSl7Y2FzZSBcInN2Z1wiOnJldHVyblwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIjtjYXNlIFwibWF0aFwiOnJldHVyblwiaHR0cDovL3d3dy53My5vcmcvMTk5OC9NYXRoL01hdGhNTFwiO2RlZmF1bHQ6cmV0dXJuXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCJ9fVxudmFyIE5hPXthcmVhOiEwLGJhc2U6ITAsYnI6ITAsY29sOiEwLGVtYmVkOiEwLGhyOiEwLGltZzohMCxpbnB1dDohMCxrZXlnZW46ITAsbGluazohMCxtZXRhOiEwLHBhcmFtOiEwLHNvdXJjZTohMCx0cmFjazohMCx3YnI6ITB9LE9hPWwoe21lbnVpdGVtOiEwfSxOYSksWT17YW5pbWF0aW9uSXRlcmF0aW9uQ291bnQ6ITAsYm9yZGVySW1hZ2VPdXRzZXQ6ITAsYm9yZGVySW1hZ2VTbGljZTohMCxib3JkZXJJbWFnZVdpZHRoOiEwLGJveEZsZXg6ITAsYm94RmxleEdyb3VwOiEwLGJveE9yZGluYWxHcm91cDohMCxjb2x1bW5Db3VudDohMCxjb2x1bW5zOiEwLGZsZXg6ITAsZmxleEdyb3c6ITAsZmxleFBvc2l0aXZlOiEwLGZsZXhTaHJpbms6ITAsZmxleE5lZ2F0aXZlOiEwLGZsZXhPcmRlcjohMCxncmlkQXJlYTohMCxncmlkUm93OiEwLGdyaWRSb3dFbmQ6ITAsZ3JpZFJvd1NwYW46ITAsZ3JpZFJvd1N0YXJ0OiEwLGdyaWRDb2x1bW46ITAsZ3JpZENvbHVtbkVuZDohMCxncmlkQ29sdW1uU3BhbjohMCxcbmdyaWRDb2x1bW5TdGFydDohMCxmb250V2VpZ2h0OiEwLGxpbmVDbGFtcDohMCxsaW5lSGVpZ2h0OiEwLG9wYWNpdHk6ITAsb3JkZXI6ITAsb3JwaGFuczohMCx0YWJTaXplOiEwLHdpZG93czohMCx6SW5kZXg6ITAsem9vbTohMCxmaWxsT3BhY2l0eTohMCxmbG9vZE9wYWNpdHk6ITAsc3RvcE9wYWNpdHk6ITAsc3Ryb2tlRGFzaGFycmF5OiEwLHN0cm9rZURhc2hvZmZzZXQ6ITAsc3Ryb2tlTWl0ZXJsaW1pdDohMCxzdHJva2VPcGFjaXR5OiEwLHN0cm9rZVdpZHRoOiEwfSxQYT1bXCJXZWJraXRcIixcIm1zXCIsXCJNb3pcIixcIk9cIl07T2JqZWN0LmtleXMoWSkuZm9yRWFjaChmdW5jdGlvbihhKXtQYS5mb3JFYWNoKGZ1bmN0aW9uKGIpe2I9YithLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpK2Euc3Vic3RyaW5nKDEpO1lbYl09WVthXX0pfSk7XG52YXIgUWE9LyhbQS1aXSkvZyxSYT0vXm1zLS8sWj1tLkNoaWxkcmVuLnRvQXJyYXksU2E9bGEuUmVhY3RDdXJyZW50RGlzcGF0Y2hlcixUYT17bGlzdGluZzohMCxwcmU6ITAsdGV4dGFyZWE6ITB9LFVhPS9eW2EtekEtWl1bYS16QS1aOl9cXC5cXC1cXGRdKiQvLFZhPXt9LFdhPXt9O2Z1bmN0aW9uIFhhKGEpe2lmKHZvaWQgMD09PWF8fG51bGw9PT1hKXJldHVybiBhO3ZhciBiPVwiXCI7bS5DaGlsZHJlbi5mb3JFYWNoKGEsZnVuY3Rpb24oYSl7bnVsbCE9YSYmKGIrPWEpfSk7cmV0dXJuIGJ9dmFyIFlhPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksWmE9e2NoaWxkcmVuOm51bGwsZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUw6bnVsbCxzdXBwcmVzc0NvbnRlbnRFZGl0YWJsZVdhcm5pbmc6bnVsbCxzdXBwcmVzc0h5ZHJhdGlvbldhcm5pbmc6bnVsbH07ZnVuY3Rpb24gJGEoYSxiKXtpZih2b2lkIDA9PT1hKXRocm93IEVycm9yKHAoMTUyLEYoYil8fFwiQ29tcG9uZW50XCIpKTt9XG5mdW5jdGlvbiBhYihhLGIsYyl7ZnVuY3Rpb24gZChkLGgpe3ZhciBlPWgucHJvdG90eXBlJiZoLnByb3RvdHlwZS5pc1JlYWN0Q29tcG9uZW50LGY9bmEoaCxiLGMsZSksdD1bXSxnPSExLG49e2lzTW91bnRlZDpmdW5jdGlvbigpe3JldHVybiExfSxlbnF1ZXVlRm9yY2VVcGRhdGU6ZnVuY3Rpb24oKXtpZihudWxsPT09dClyZXR1cm4gbnVsbH0sZW5xdWV1ZVJlcGxhY2VTdGF0ZTpmdW5jdGlvbihhLGMpe2c9ITA7dD1bY119LGVucXVldWVTZXRTdGF0ZTpmdW5jdGlvbihhLGMpe2lmKG51bGw9PT10KXJldHVybiBudWxsO3QucHVzaChjKX19O2lmKGUpe2lmKGU9bmV3IGgoZC5wcm9wcyxmLG4pLFwiZnVuY3Rpb25cIj09PXR5cGVvZiBoLmdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyl7dmFyIGs9aC5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMuY2FsbChudWxsLGQucHJvcHMsZS5zdGF0ZSk7bnVsbCE9ayYmKGUuc3RhdGU9bCh7fSxlLnN0YXRlLGspKX19ZWxzZSBpZihQPXt9LGU9aChkLnByb3BzLFxuZixuKSxlPURhKGgsZC5wcm9wcyxlLGYpLG51bGw9PWV8fG51bGw9PWUucmVuZGVyKXthPWU7JGEoYSxoKTtyZXR1cm59ZS5wcm9wcz1kLnByb3BzO2UuY29udGV4dD1mO2UudXBkYXRlcj1uO249ZS5zdGF0ZTt2b2lkIDA9PT1uJiYoZS5zdGF0ZT1uPW51bGwpO2lmKFwiZnVuY3Rpb25cIj09PXR5cGVvZiBlLlVOU0FGRV9jb21wb25lbnRXaWxsTW91bnR8fFwiZnVuY3Rpb25cIj09PXR5cGVvZiBlLmNvbXBvbmVudFdpbGxNb3VudClpZihcImZ1bmN0aW9uXCI9PT10eXBlb2YgZS5jb21wb25lbnRXaWxsTW91bnQmJlwiZnVuY3Rpb25cIiE9PXR5cGVvZiBoLmdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyYmZS5jb21wb25lbnRXaWxsTW91bnQoKSxcImZ1bmN0aW9uXCI9PT10eXBlb2YgZS5VTlNBRkVfY29tcG9uZW50V2lsbE1vdW50JiZcImZ1bmN0aW9uXCIhPT10eXBlb2YgaC5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMmJmUuVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudCgpLHQubGVuZ3RoKXtuPXQ7dmFyIHY9XG5nO3Q9bnVsbDtnPSExO2lmKHYmJjE9PT1uLmxlbmd0aCllLnN0YXRlPW5bMF07ZWxzZXtrPXY/blswXTplLnN0YXRlO3ZhciBIPSEwO2Zvcih2PXY/MTowO3Y8bi5sZW5ndGg7disrKXt2YXIgeD1uW3ZdO3g9XCJmdW5jdGlvblwiPT09dHlwZW9mIHg/eC5jYWxsKGUsayxkLnByb3BzLGYpOng7bnVsbCE9eCYmKEg/KEg9ITEsaz1sKHt9LGsseCkpOmwoayx4KSl9ZS5zdGF0ZT1rfX1lbHNlIHQ9bnVsbDthPWUucmVuZGVyKCk7JGEoYSxoKTtpZihcImZ1bmN0aW9uXCI9PT10eXBlb2YgZS5nZXRDaGlsZENvbnRleHQmJihkPWguY2hpbGRDb250ZXh0VHlwZXMsXCJvYmplY3RcIj09PXR5cGVvZiBkKSl7dmFyIHk9ZS5nZXRDaGlsZENvbnRleHQoKTtmb3IodmFyIEEgaW4geSlpZighKEEgaW4gZCkpdGhyb3cgRXJyb3IocCgxMDgsRihoKXx8XCJVbmtub3duXCIsQSkpO315JiYoYj1sKHt9LGIseSkpfWZvcig7bS5pc1ZhbGlkRWxlbWVudChhKTspe3ZhciBmPWEsaD1mLnR5cGU7aWYoXCJmdW5jdGlvblwiIT09XG50eXBlb2YgaClicmVhaztkKGYsaCl9cmV0dXJue2NoaWxkOmEsY29udGV4dDpifX1cbnZhciBiYj1mdW5jdGlvbigpe2Z1bmN0aW9uIGEoYSxiLGYpe20uaXNWYWxpZEVsZW1lbnQoYSk/YS50eXBlIT09cj9hPVthXTooYT1hLnByb3BzLmNoaWxkcmVuLGE9bS5pc1ZhbGlkRWxlbWVudChhKT9bYV06WihhKSk6YT1aKGEpO2E9e3R5cGU6bnVsbCxkb21OYW1lc3BhY2U6TGEuaHRtbCxjaGlsZHJlbjphLGNoaWxkSW5kZXg6MCxjb250ZXh0Om1hLGZvb3RlcjpcIlwifTt2YXIgYz1KWzBdO2lmKDA9PT1jKXt2YXIgZD1KO2M9ZC5sZW5ndGg7dmFyIGc9MipjO2lmKCEoNjU1MzY+PWcpKXRocm93IEVycm9yKHAoMzA0KSk7dmFyIGU9bmV3IFVpbnQxNkFycmF5KGcpO2Uuc2V0KGQpO0o9ZTtKWzBdPWMrMTtmb3IoZD1jO2Q8Zy0xO2QrKylKW2RdPWQrMTtKW2ctMV09MH1lbHNlIEpbMF09SltjXTt0aGlzLnRocmVhZElEPWM7dGhpcy5zdGFjaz1bYV07dGhpcy5leGhhdXN0ZWQ9ITE7dGhpcy5jdXJyZW50U2VsZWN0VmFsdWU9bnVsbDt0aGlzLnByZXZpb3VzV2FzVGV4dE5vZGU9ITE7XG50aGlzLm1ha2VTdGF0aWNNYXJrdXA9Yjt0aGlzLnN1c3BlbnNlRGVwdGg9MDt0aGlzLmNvbnRleHRJbmRleD0tMTt0aGlzLmNvbnRleHRTdGFjaz1bXTt0aGlzLmNvbnRleHRWYWx1ZVN0YWNrPVtdO3RoaXMudW5pcXVlSUQ9MDt0aGlzLmlkZW50aWZpZXJQcmVmaXg9ZiYmZi5pZGVudGlmaWVyUHJlZml4fHxcIlwifXZhciBiPWEucHJvdG90eXBlO2IuZGVzdHJveT1mdW5jdGlvbigpe2lmKCF0aGlzLmV4aGF1c3RlZCl7dGhpcy5leGhhdXN0ZWQ9ITA7dGhpcy5jbGVhclByb3ZpZGVycygpO3ZhciBhPXRoaXMudGhyZWFkSUQ7SlthXT1KWzBdO0pbMF09YX19O2IucHVzaFByb3ZpZGVyPWZ1bmN0aW9uKGEpe3ZhciBiPSsrdGhpcy5jb250ZXh0SW5kZXgsYz1hLnR5cGUuX2NvbnRleHQsaD10aGlzLnRocmVhZElEO0koYyxoKTt2YXIgdD1jW2hdO3RoaXMuY29udGV4dFN0YWNrW2JdPWM7dGhpcy5jb250ZXh0VmFsdWVTdGFja1tiXT10O2NbaF09YS5wcm9wcy52YWx1ZX07Yi5wb3BQcm92aWRlcj1cbmZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5jb250ZXh0SW5kZXgsYj10aGlzLmNvbnRleHRTdGFja1thXSxmPXRoaXMuY29udGV4dFZhbHVlU3RhY2tbYV07dGhpcy5jb250ZXh0U3RhY2tbYV09bnVsbDt0aGlzLmNvbnRleHRWYWx1ZVN0YWNrW2FdPW51bGw7dGhpcy5jb250ZXh0SW5kZXgtLTtiW3RoaXMudGhyZWFkSURdPWZ9O2IuY2xlYXJQcm92aWRlcnM9ZnVuY3Rpb24oKXtmb3IodmFyIGE9dGhpcy5jb250ZXh0SW5kZXg7MDw9YTthLS0pdGhpcy5jb250ZXh0U3RhY2tbYV1bdGhpcy50aHJlYWRJRF09dGhpcy5jb250ZXh0VmFsdWVTdGFja1thXX07Yi5yZWFkPWZ1bmN0aW9uKGEpe2lmKHRoaXMuZXhoYXVzdGVkKXJldHVybiBudWxsO3ZhciBiPVg7WD10aGlzO3ZhciBjPVNhLmN1cnJlbnQ7U2EuY3VycmVudD1LYTt0cnl7Zm9yKHZhciBoPVtcIlwiXSx0PSExO2hbMF0ubGVuZ3RoPGE7KXtpZigwPT09dGhpcy5zdGFjay5sZW5ndGgpe3RoaXMuZXhoYXVzdGVkPSEwO3ZhciBnPXRoaXMudGhyZWFkSUQ7XG5KW2ddPUpbMF07SlswXT1nO2JyZWFrfXZhciBlPXRoaXMuc3RhY2tbdGhpcy5zdGFjay5sZW5ndGgtMV07aWYodHx8ZS5jaGlsZEluZGV4Pj1lLmNoaWxkcmVuLmxlbmd0aCl7dmFyIEw9ZS5mb290ZXI7XCJcIiE9PUwmJih0aGlzLnByZXZpb3VzV2FzVGV4dE5vZGU9ITEpO3RoaXMuc3RhY2sucG9wKCk7aWYoXCJzZWxlY3RcIj09PWUudHlwZSl0aGlzLmN1cnJlbnRTZWxlY3RWYWx1ZT1udWxsO2Vsc2UgaWYobnVsbCE9ZS50eXBlJiZudWxsIT1lLnR5cGUudHlwZSYmZS50eXBlLnR5cGUuJCR0eXBlb2Y9PT1CKXRoaXMucG9wUHJvdmlkZXIoZS50eXBlKTtlbHNlIGlmKGUudHlwZT09PUQpe3RoaXMuc3VzcGVuc2VEZXB0aC0tO3ZhciBHPWgucG9wKCk7aWYodCl7dD0hMTt2YXIgQz1lLmZhbGxiYWNrRnJhbWU7aWYoIUMpdGhyb3cgRXJyb3IocCgzMDMpKTt0aGlzLnN0YWNrLnB1c2goQyk7aFt0aGlzLnN1c3BlbnNlRGVwdGhdKz1cIlxceDNjIS0tJCEtLVxceDNlXCI7Y29udGludWV9ZWxzZSBoW3RoaXMuc3VzcGVuc2VEZXB0aF0rPVxuR31oW3RoaXMuc3VzcGVuc2VEZXB0aF0rPUx9ZWxzZXt2YXIgbj1lLmNoaWxkcmVuW2UuY2hpbGRJbmRleCsrXSxrPVwiXCI7dHJ5e2srPXRoaXMucmVuZGVyKG4sZS5jb250ZXh0LGUuZG9tTmFtZXNwYWNlKX1jYXRjaCh2KXtpZihudWxsIT12JiZcImZ1bmN0aW9uXCI9PT10eXBlb2Ygdi50aGVuKXRocm93IEVycm9yKHAoMjk0KSk7dGhyb3cgdjt9ZmluYWxseXt9aC5sZW5ndGg8PXRoaXMuc3VzcGVuc2VEZXB0aCYmaC5wdXNoKFwiXCIpO2hbdGhpcy5zdXNwZW5zZURlcHRoXSs9a319cmV0dXJuIGhbMF19ZmluYWxseXtTYS5jdXJyZW50PWMsWD1iLEVhKCl9fTtiLnJlbmRlcj1mdW5jdGlvbihhLGIsZil7aWYoXCJzdHJpbmdcIj09PXR5cGVvZiBhfHxcIm51bWJlclwiPT09dHlwZW9mIGEpe2Y9XCJcIithO2lmKFwiXCI9PT1mKXJldHVyblwiXCI7aWYodGhpcy5tYWtlU3RhdGljTWFya3VwKXJldHVybiBPKGYpO2lmKHRoaXMucHJldmlvdXNXYXNUZXh0Tm9kZSlyZXR1cm5cIlxceDNjIS0tIC0tXFx4M2VcIitPKGYpO1xudGhpcy5wcmV2aW91c1dhc1RleHROb2RlPSEwO3JldHVybiBPKGYpfWI9YWIoYSxiLHRoaXMudGhyZWFkSUQpO2E9Yi5jaGlsZDtiPWIuY29udGV4dDtpZihudWxsPT09YXx8ITE9PT1hKXJldHVyblwiXCI7aWYoIW0uaXNWYWxpZEVsZW1lbnQoYSkpe2lmKG51bGwhPWEmJm51bGwhPWEuJCR0eXBlb2Ype2Y9YS4kJHR5cGVvZjtpZihmPT09cSl0aHJvdyBFcnJvcihwKDI1NykpO3Rocm93IEVycm9yKHAoMjU4LGYudG9TdHJpbmcoKSkpO31hPVooYSk7dGhpcy5zdGFjay5wdXNoKHt0eXBlOm51bGwsZG9tTmFtZXNwYWNlOmYsY2hpbGRyZW46YSxjaGlsZEluZGV4OjAsY29udGV4dDpiLGZvb3RlcjpcIlwifSk7cmV0dXJuXCJcIn12YXIgYz1hLnR5cGU7aWYoXCJzdHJpbmdcIj09PXR5cGVvZiBjKXJldHVybiB0aGlzLnJlbmRlckRPTShhLGIsZik7c3dpdGNoKGMpe2Nhc2Uga2E6Y2FzZSBqYTpjYXNlIHU6Y2FzZSB6OmNhc2UgY2E6Y2FzZSByOnJldHVybiBhPVooYS5wcm9wcy5jaGlsZHJlbiksdGhpcy5zdGFjay5wdXNoKHt0eXBlOm51bGwsXG5kb21OYW1lc3BhY2U6ZixjaGlsZHJlbjphLGNoaWxkSW5kZXg6MCxjb250ZXh0OmIsZm9vdGVyOlwiXCJ9KSxcIlwiO2Nhc2UgRDp0aHJvdyBFcnJvcihwKDI5NCkpO2Nhc2UgaWE6dGhyb3cgRXJyb3IocCgzNDMpKTt9aWYoXCJvYmplY3RcIj09PXR5cGVvZiBjJiZudWxsIT09Yylzd2l0Y2goYy4kJHR5cGVvZil7Y2FzZSBiYTpQPXt9O3ZhciBkPWMucmVuZGVyKGEucHJvcHMsYS5yZWYpO2Q9RGEoYy5yZW5kZXIsYS5wcm9wcyxkLGEucmVmKTtkPVooZCk7dGhpcy5zdGFjay5wdXNoKHt0eXBlOm51bGwsZG9tTmFtZXNwYWNlOmYsY2hpbGRyZW46ZCxjaGlsZEluZGV4OjAsY29udGV4dDpiLGZvb3RlcjpcIlwifSk7cmV0dXJuXCJcIjtjYXNlIGRhOnJldHVybiBhPVttLmNyZWF0ZUVsZW1lbnQoYy50eXBlLGwoe3JlZjphLnJlZn0sYS5wcm9wcykpXSx0aGlzLnN0YWNrLnB1c2goe3R5cGU6bnVsbCxkb21OYW1lc3BhY2U6ZixjaGlsZHJlbjphLGNoaWxkSW5kZXg6MCxjb250ZXh0OmIsZm9vdGVyOlwiXCJ9KSxcblwiXCI7Y2FzZSBCOnJldHVybiBjPVooYS5wcm9wcy5jaGlsZHJlbiksZj17dHlwZTphLGRvbU5hbWVzcGFjZTpmLGNoaWxkcmVuOmMsY2hpbGRJbmRleDowLGNvbnRleHQ6Yixmb290ZXI6XCJcIn0sdGhpcy5wdXNoUHJvdmlkZXIoYSksdGhpcy5zdGFjay5wdXNoKGYpLFwiXCI7Y2FzZSBhYTpjPWEudHlwZTtkPWEucHJvcHM7dmFyIGc9dGhpcy50aHJlYWRJRDtJKGMsZyk7Yz1aKGQuY2hpbGRyZW4oY1tnXSkpO3RoaXMuc3RhY2sucHVzaCh7dHlwZTphLGRvbU5hbWVzcGFjZTpmLGNoaWxkcmVuOmMsY2hpbGRJbmRleDowLGNvbnRleHQ6Yixmb290ZXI6XCJcIn0pO3JldHVyblwiXCI7Y2FzZSBoYTp0aHJvdyBFcnJvcihwKDMzOCkpO2Nhc2UgZWE6cmV0dXJuIGM9YS50eXBlLGQ9Yy5faW5pdCxjPWQoYy5fcGF5bG9hZCksYT1bbS5jcmVhdGVFbGVtZW50KGMsbCh7cmVmOmEucmVmfSxhLnByb3BzKSldLHRoaXMuc3RhY2sucHVzaCh7dHlwZTpudWxsLGRvbU5hbWVzcGFjZTpmLGNoaWxkcmVuOmEsY2hpbGRJbmRleDowLFxuY29udGV4dDpiLGZvb3RlcjpcIlwifSksXCJcIn10aHJvdyBFcnJvcihwKDEzMCxudWxsPT1jP2M6dHlwZW9mIGMsXCJcIikpO307Yi5yZW5kZXJET009ZnVuY3Rpb24oYSxiLGYpe3ZhciBjPWEudHlwZS50b0xvd2VyQ2FzZSgpO2Y9PT1MYS5odG1sJiZNYShjKTtpZighVmEuaGFzT3duUHJvcGVydHkoYykpe2lmKCFVYS50ZXN0KGMpKXRocm93IEVycm9yKHAoNjUsYykpO1ZhW2NdPSEwfXZhciBkPWEucHJvcHM7aWYoXCJpbnB1dFwiPT09YylkPWwoe3R5cGU6dm9pZCAwfSxkLHtkZWZhdWx0Q2hlY2tlZDp2b2lkIDAsZGVmYXVsdFZhbHVlOnZvaWQgMCx2YWx1ZTpudWxsIT1kLnZhbHVlP2QudmFsdWU6ZC5kZWZhdWx0VmFsdWUsY2hlY2tlZDpudWxsIT1kLmNoZWNrZWQ/ZC5jaGVja2VkOmQuZGVmYXVsdENoZWNrZWR9KTtlbHNlIGlmKFwidGV4dGFyZWFcIj09PWMpe3ZhciBnPWQudmFsdWU7aWYobnVsbD09Zyl7Zz1kLmRlZmF1bHRWYWx1ZTt2YXIgZT1kLmNoaWxkcmVuO2lmKG51bGwhPWUpe2lmKG51bGwhPVxuZyl0aHJvdyBFcnJvcihwKDkyKSk7aWYoQXJyYXkuaXNBcnJheShlKSl7aWYoISgxPj1lLmxlbmd0aCkpdGhyb3cgRXJyb3IocCg5MykpO2U9ZVswXX1nPVwiXCIrZX1udWxsPT1nJiYoZz1cIlwiKX1kPWwoe30sZCx7dmFsdWU6dm9pZCAwLGNoaWxkcmVuOlwiXCIrZ30pfWVsc2UgaWYoXCJzZWxlY3RcIj09PWMpdGhpcy5jdXJyZW50U2VsZWN0VmFsdWU9bnVsbCE9ZC52YWx1ZT9kLnZhbHVlOmQuZGVmYXVsdFZhbHVlLGQ9bCh7fSxkLHt2YWx1ZTp2b2lkIDB9KTtlbHNlIGlmKFwib3B0aW9uXCI9PT1jKXtlPXRoaXMuY3VycmVudFNlbGVjdFZhbHVlO3ZhciBMPVhhKGQuY2hpbGRyZW4pO2lmKG51bGwhPWUpe3ZhciBHPW51bGwhPWQudmFsdWU/ZC52YWx1ZStcIlwiOkw7Zz0hMTtpZihBcnJheS5pc0FycmF5KGUpKWZvcih2YXIgQz0wO0M8ZS5sZW5ndGg7QysrKXtpZihcIlwiK2VbQ109PT1HKXtnPSEwO2JyZWFrfX1lbHNlIGc9XCJcIitlPT09RztkPWwoe3NlbGVjdGVkOnZvaWQgMCxjaGlsZHJlbjp2b2lkIDB9LFxuZCx7c2VsZWN0ZWQ6ZyxjaGlsZHJlbjpMfSl9fWlmKGc9ZCl7aWYoT2FbY10mJihudWxsIT1nLmNoaWxkcmVufHxudWxsIT1nLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MKSl0aHJvdyBFcnJvcihwKDEzNyxjKSk7aWYobnVsbCE9Zy5kYW5nZXJvdXNseVNldElubmVySFRNTCl7aWYobnVsbCE9Zy5jaGlsZHJlbil0aHJvdyBFcnJvcihwKDYwKSk7aWYoIShcIm9iamVjdFwiPT09dHlwZW9mIGcuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwmJlwiX19odG1sXCJpbiBnLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MKSl0aHJvdyBFcnJvcihwKDYxKSk7fWlmKG51bGwhPWcuc3R5bGUmJlwib2JqZWN0XCIhPT10eXBlb2YgZy5zdHlsZSl0aHJvdyBFcnJvcihwKDYyKSk7fWc9ZDtlPXRoaXMubWFrZVN0YXRpY01hcmt1cDtMPTE9PT10aGlzLnN0YWNrLmxlbmd0aDtHPVwiPFwiK2EudHlwZTtiOmlmKC0xPT09Yy5pbmRleE9mKFwiLVwiKSlDPVwic3RyaW5nXCI9PT10eXBlb2YgZy5pcztlbHNlIHN3aXRjaChjKXtjYXNlIFwiYW5ub3RhdGlvbi14bWxcIjpjYXNlIFwiY29sb3ItcHJvZmlsZVwiOmNhc2UgXCJmb250LWZhY2VcIjpjYXNlIFwiZm9udC1mYWNlLXNyY1wiOmNhc2UgXCJmb250LWZhY2UtdXJpXCI6Y2FzZSBcImZvbnQtZmFjZS1mb3JtYXRcIjpjYXNlIFwiZm9udC1mYWNlLW5hbWVcIjpjYXNlIFwibWlzc2luZy1nbHlwaFwiOkM9XG4hMTticmVhayBiO2RlZmF1bHQ6Qz0hMH1mb3IodyBpbiBnKWlmKFlhLmNhbGwoZyx3KSl7dmFyIG49Z1t3XTtpZihudWxsIT1uKXtpZihcInN0eWxlXCI9PT13KXt2YXIgaz12b2lkIDAsdj1cIlwiLEg9XCJcIjtmb3IoayBpbiBuKWlmKG4uaGFzT3duUHJvcGVydHkoaykpe3ZhciB4PTA9PT1rLmluZGV4T2YoXCItLVwiKSx5PW5ba107aWYobnVsbCE9eSl7aWYoeCl2YXIgQT1rO2Vsc2UgaWYoQT1rLFdhLmhhc093blByb3BlcnR5KEEpKUE9V2FbQV07ZWxzZXt2YXIgY2I9QS5yZXBsYWNlKFFhLFwiLSQxXCIpLnRvTG93ZXJDYXNlKCkucmVwbGFjZShSYSxcIi1tcy1cIik7QT1XYVtBXT1jYn12Kz1IK0ErXCI6XCI7SD1rO3g9bnVsbD09eXx8XCJib29sZWFuXCI9PT10eXBlb2YgeXx8XCJcIj09PXk/XCJcIjp4fHxcIm51bWJlclwiIT09dHlwZW9mIHl8fDA9PT15fHxZLmhhc093blByb3BlcnR5KEgpJiZZW0hdPyhcIlwiK3kpLnRyaW0oKTp5K1wicHhcIjt2Kz14O0g9XCI7XCJ9fW49dnx8bnVsbH1rPW51bGw7Qz9aYS5oYXNPd25Qcm9wZXJ0eSh3KXx8XG4oaz13LGs9c2EoaykmJm51bGwhPW4/aysnPVwiJysoTyhuKSsnXCInKTpcIlwiKTprPXlhKHcsbik7ayYmKEcrPVwiIFwiK2spfX1lfHxMJiYoRys9JyBkYXRhLXJlYWN0cm9vdD1cIlwiJyk7dmFyIHc9RztnPVwiXCI7TmEuaGFzT3duUHJvcGVydHkoYyk/dys9XCIvPlwiOih3Kz1cIj5cIixnPVwiPC9cIithLnR5cGUrXCI+XCIpO2E6e2U9ZC5kYW5nZXJvdXNseVNldElubmVySFRNTDtpZihudWxsIT1lKXtpZihudWxsIT1lLl9faHRtbCl7ZT1lLl9faHRtbDticmVhayBhfX1lbHNlIGlmKGU9ZC5jaGlsZHJlbixcInN0cmluZ1wiPT09dHlwZW9mIGV8fFwibnVtYmVyXCI9PT10eXBlb2YgZSl7ZT1PKGUpO2JyZWFrIGF9ZT1udWxsfW51bGwhPWU/KGQ9W10sVGEuaGFzT3duUHJvcGVydHkoYykmJlwiXFxuXCI9PT1lLmNoYXJBdCgwKSYmKHcrPVwiXFxuXCIpLHcrPWUpOmQ9WihkLmNoaWxkcmVuKTthPWEudHlwZTtmPW51bGw9PWZ8fFwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiPT09Zj9NYShhKTpcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI9PT1cbmYmJlwiZm9yZWlnbk9iamVjdFwiPT09YT9cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIjpmO3RoaXMuc3RhY2sucHVzaCh7ZG9tTmFtZXNwYWNlOmYsdHlwZTpjLGNoaWxkcmVuOmQsY2hpbGRJbmRleDowLGNvbnRleHQ6Yixmb290ZXI6Z30pO3RoaXMucHJldmlvdXNXYXNUZXh0Tm9kZT0hMTtyZXR1cm4gd307cmV0dXJuIGF9KCk7ZXhwb3J0cy5yZW5kZXJUb05vZGVTdHJlYW09ZnVuY3Rpb24oKXt0aHJvdyBFcnJvcihwKDIwNykpO307ZXhwb3J0cy5yZW5kZXJUb1N0YXRpY01hcmt1cD1mdW5jdGlvbihhLGIpe2E9bmV3IGJiKGEsITAsYik7dHJ5e3JldHVybiBhLnJlYWQoSW5maW5pdHkpfWZpbmFsbHl7YS5kZXN0cm95KCl9fTtleHBvcnRzLnJlbmRlclRvU3RhdGljTm9kZVN0cmVhbT1mdW5jdGlvbigpe3Rocm93IEVycm9yKHAoMjA4KSk7fTtleHBvcnRzLnJlbmRlclRvU3RyaW5nPWZ1bmN0aW9uKGEsYil7YT1uZXcgYmIoYSwhMSxiKTt0cnl7cmV0dXJuIGEucmVhZChJbmZpbml0eSl9ZmluYWxseXthLmRlc3Ryb3koKX19O1xuZXhwb3J0cy52ZXJzaW9uPVwiMTcuMC4yXCI7XG4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///692\n')},190:(module,__unused_webpack_exports,__webpack_require__)=>{"use strict";eval("\n\nif (true) {\n module.exports = __webpack_require__(692);\n} else {}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uLi9kZW1vL25vZGVfbW9kdWxlcy9yZWFjdC1kb20vc2VydmVyLmJyb3dzZXIuanM/ODM2NCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixJQUFJLElBQXFDO0FBQ3pDLEVBQUUseUNBQTRFO0FBQzlFLENBQUMsTUFBTSxFQUVOIiwiZmlsZSI6IjE5MC5qcyIsInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbicpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9yZWFjdC1kb20tc2VydmVyLmJyb3dzZXIucHJvZHVjdGlvbi5taW4uanMnKTtcbn0gZWxzZSB7XG4gIG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9janMvcmVhY3QtZG9tLXNlcnZlci5icm93c2VyLmRldmVsb3BtZW50LmpzJyk7XG59XG4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///190\n")},184:(module,exports)=>{eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\n Copyright (c) 2018 Jed Watson.\n Licensed under the MIT License (MIT), see\n http://jedwatson.github.io/classnames\n*/\n/* global define */\n\n(function () {\n\t'use strict';\n\n\tvar hasOwn = {}.hasOwnProperty;\n\n\tfunction classNames() {\n\t\tvar classes = [];\n\n\t\tfor (var i = 0; i < arguments.length; i++) {\n\t\t\tvar arg = arguments[i];\n\t\t\tif (!arg) continue;\n\n\t\t\tvar argType = typeof arg;\n\n\t\t\tif (argType === 'string' || argType === 'number') {\n\t\t\t\tclasses.push(arg);\n\t\t\t} else if (Array.isArray(arg)) {\n\t\t\t\tif (arg.length) {\n\t\t\t\t\tvar inner = classNames.apply(null, arg);\n\t\t\t\t\tif (inner) {\n\t\t\t\t\t\tclasses.push(inner);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (argType === 'object') {\n\t\t\t\tif (arg.toString === Object.prototype.toString) {\n\t\t\t\t\tfor (var key in arg) {\n\t\t\t\t\t\tif (hasOwn.call(arg, key) && arg[key]) {\n\t\t\t\t\t\t\tclasses.push(key);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tclasses.push(arg.toString());\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn classes.join(' ');\n\t}\n\n\tif ( true && module.exports) {\n\t\tclassNames.default = classNames;\n\t\tmodule.exports = classNames;\n\t} else if (true) {\n\t\t// register as 'classnames', consistent with npm package name\n\t\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () {\n\t\t\treturn classNames;\n\t\t}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t} else {}\n}());\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9jbGFzc25hbWVzL2luZGV4LmpzPzRkMjYiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsZ0JBQWdCOztBQUVoQjtBQUNBOztBQUVBLGlCQUFpQixzQkFBc0I7QUFDdkM7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxLQUFLLEtBQTZCO0FBQ2xDO0FBQ0E7QUFDQSxFQUFFLFVBQVUsSUFBNEU7QUFDeEY7QUFDQSxFQUFFLGlDQUFxQixFQUFFLG1DQUFFO0FBQzNCO0FBQ0EsR0FBRztBQUFBLGtHQUFDO0FBQ0osRUFBRSxNQUFNLEVBRU47QUFDRixDQUFDIiwiZmlsZSI6IjE4NC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qIVxuICBDb3B5cmlnaHQgKGMpIDIwMTggSmVkIFdhdHNvbi5cbiAgTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlIChNSVQpLCBzZWVcbiAgaHR0cDovL2plZHdhdHNvbi5naXRodWIuaW8vY2xhc3NuYW1lc1xuKi9cbi8qIGdsb2JhbCBkZWZpbmUgKi9cblxuKGZ1bmN0aW9uICgpIHtcblx0J3VzZSBzdHJpY3QnO1xuXG5cdHZhciBoYXNPd24gPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuXHRmdW5jdGlvbiBjbGFzc05hbWVzKCkge1xuXHRcdHZhciBjbGFzc2VzID0gW107XG5cblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0dmFyIGFyZyA9IGFyZ3VtZW50c1tpXTtcblx0XHRcdGlmICghYXJnKSBjb250aW51ZTtcblxuXHRcdFx0dmFyIGFyZ1R5cGUgPSB0eXBlb2YgYXJnO1xuXG5cdFx0XHRpZiAoYXJnVHlwZSA9PT0gJ3N0cmluZycgfHwgYXJnVHlwZSA9PT0gJ251bWJlcicpIHtcblx0XHRcdFx0Y2xhc3Nlcy5wdXNoKGFyZyk7XG5cdFx0XHR9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoYXJnKSkge1xuXHRcdFx0XHRpZiAoYXJnLmxlbmd0aCkge1xuXHRcdFx0XHRcdHZhciBpbm5lciA9IGNsYXNzTmFtZXMuYXBwbHkobnVsbCwgYXJnKTtcblx0XHRcdFx0XHRpZiAoaW5uZXIpIHtcblx0XHRcdFx0XHRcdGNsYXNzZXMucHVzaChpbm5lcik7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2UgaWYgKGFyZ1R5cGUgPT09ICdvYmplY3QnKSB7XG5cdFx0XHRcdGlmIChhcmcudG9TdHJpbmcgPT09IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcpIHtcblx0XHRcdFx0XHRmb3IgKHZhciBrZXkgaW4gYXJnKSB7XG5cdFx0XHRcdFx0XHRpZiAoaGFzT3duLmNhbGwoYXJnLCBrZXkpICYmIGFyZ1trZXldKSB7XG5cdFx0XHRcdFx0XHRcdGNsYXNzZXMucHVzaChrZXkpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRjbGFzc2VzLnB1c2goYXJnLnRvU3RyaW5nKCkpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGNsYXNzZXMuam9pbignICcpO1xuXHR9XG5cblx0aWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7XG5cdFx0Y2xhc3NOYW1lcy5kZWZhdWx0ID0gY2xhc3NOYW1lcztcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGNsYXNzTmFtZXM7XG5cdH0gZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgZGVmaW5lLmFtZCA9PT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIHJlZ2lzdGVyIGFzICdjbGFzc25hbWVzJywgY29uc2lzdGVudCB3aXRoIG5wbSBwYWNrYWdlIG5hbWVcblx0XHRkZWZpbmUoJ2NsYXNzbmFtZXMnLCBbXSwgZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIGNsYXNzTmFtZXM7XG5cdFx0fSk7XG5cdH0gZWxzZSB7XG5cdFx0d2luZG93LmNsYXNzTmFtZXMgPSBjbGFzc05hbWVzO1xuXHR9XG59KCkpO1xuIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///184\n")},299:function(module,__unused_webpack_exports,__webpack_require__){eval('/**\n * @licstart The following is the entire license notice for the\n * JavaScript code in this page\n *\n * Copyright 2022 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @licend The above is the entire license notice for the\n * JavaScript code in this page\n */\n\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(true)\n\t\tmodule.exports = factory();\n\telse {}\n})(this, () => {\nreturn /******/ (() => { // webpackBootstrap\n/******/ \t"use strict";\n/******/ \tvar __webpack_modules__ = ([\n/* 0 */,\n/* 1 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.VerbosityLevel = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.UNSUPPORTED_FEATURES = exports.TextRenderingMode = exports.StreamType = exports.RenderingIntentFlag = exports.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.PageActionEventType = exports.OPS = exports.MissingPDFException = exports.InvalidPDFException = exports.ImageKind = exports.IDENTITY_MATRIX = exports.FormatError = exports.FontType = exports.FeatureTest = exports.FONT_IDENTITY_MATRIX = exports.DocumentActionEventType = exports.CMapCompressionType = exports.BaseException = exports.AnnotationType = exports.AnnotationStateModelType = exports.AnnotationReviewState = exports.AnnotationReplyType = exports.AnnotationMode = exports.AnnotationMarkedState = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationBorderStyleType = exports.AnnotationActionEventType = exports.AbortException = void 0;\nexports.arrayByteLength = arrayByteLength;\nexports.arraysToBytes = arraysToBytes;\nexports.assert = assert;\nexports.bytesToString = bytesToString;\nexports.createPromiseCapability = createPromiseCapability;\nexports.createValidAbsoluteUrl = createValidAbsoluteUrl;\nexports.escapeString = escapeString;\nexports.getModificationDate = getModificationDate;\nexports.getVerbosityLevel = getVerbosityLevel;\nexports.info = info;\nexports.isArrayBuffer = isArrayBuffer;\nexports.isArrayEqual = isArrayEqual;\nexports.isAscii = isAscii;\nexports.objectFromMap = objectFromMap;\nexports.objectSize = objectSize;\nexports.setVerbosityLevel = setVerbosityLevel;\nexports.shadow = shadow;\nexports.string32 = string32;\nexports.stringToBytes = stringToBytes;\nexports.stringToPDFString = stringToPDFString;\nexports.stringToUTF16BEString = stringToUTF16BEString;\nexports.stringToUTF8String = stringToUTF8String;\nexports.unreachable = unreachable;\nexports.utf8StringToString = utf8StringToString;\nexports.warn = warn;\n\n__w_pdfjs_require__(2);\n\nconst IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];\nexports.IDENTITY_MATRIX = IDENTITY_MATRIX;\nconst FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];\nexports.FONT_IDENTITY_MATRIX = FONT_IDENTITY_MATRIX;\nconst RenderingIntentFlag = {\n ANY: 0x01,\n DISPLAY: 0x02,\n PRINT: 0x04,\n ANNOTATIONS_FORMS: 0x10,\n ANNOTATIONS_STORAGE: 0x20,\n ANNOTATIONS_DISABLE: 0x40,\n OPLIST: 0x100\n};\nexports.RenderingIntentFlag = RenderingIntentFlag;\nconst AnnotationMode = {\n DISABLE: 0,\n ENABLE: 1,\n ENABLE_FORMS: 2,\n ENABLE_STORAGE: 3\n};\nexports.AnnotationMode = AnnotationMode;\nconst PermissionFlag = {\n PRINT: 0x04,\n MODIFY_CONTENTS: 0x08,\n COPY: 0x10,\n MODIFY_ANNOTATIONS: 0x20,\n FILL_INTERACTIVE_FORMS: 0x100,\n COPY_FOR_ACCESSIBILITY: 0x200,\n ASSEMBLE: 0x400,\n PRINT_HIGH_QUALITY: 0x800\n};\nexports.PermissionFlag = PermissionFlag;\nconst TextRenderingMode = {\n FILL: 0,\n STROKE: 1,\n FILL_STROKE: 2,\n INVISIBLE: 3,\n FILL_ADD_TO_PATH: 4,\n STROKE_ADD_TO_PATH: 5,\n FILL_STROKE_ADD_TO_PATH: 6,\n ADD_TO_PATH: 7,\n FILL_STROKE_MASK: 3,\n ADD_TO_PATH_FLAG: 4\n};\nexports.TextRenderingMode = TextRenderingMode;\nconst ImageKind = {\n GRAYSCALE_1BPP: 1,\n RGB_24BPP: 2,\n RGBA_32BPP: 3\n};\nexports.ImageKind = ImageKind;\nconst AnnotationType = {\n TEXT: 1,\n LINK: 2,\n FREETEXT: 3,\n LINE: 4,\n SQUARE: 5,\n CIRCLE: 6,\n POLYGON: 7,\n POLYLINE: 8,\n HIGHLIGHT: 9,\n UNDERLINE: 10,\n SQUIGGLY: 11,\n STRIKEOUT: 12,\n STAMP: 13,\n CARET: 14,\n INK: 15,\n POPUP: 16,\n FILEATTACHMENT: 17,\n SOUND: 18,\n MOVIE: 19,\n WIDGET: 20,\n SCREEN: 21,\n PRINTERMARK: 22,\n TRAPNET: 23,\n WATERMARK: 24,\n THREED: 25,\n REDACT: 26\n};\nexports.AnnotationType = AnnotationType;\nconst AnnotationStateModelType = {\n MARKED: "Marked",\n REVIEW: "Review"\n};\nexports.AnnotationStateModelType = AnnotationStateModelType;\nconst AnnotationMarkedState = {\n MARKED: "Marked",\n UNMARKED: "Unmarked"\n};\nexports.AnnotationMarkedState = AnnotationMarkedState;\nconst AnnotationReviewState = {\n ACCEPTED: "Accepted",\n REJECTED: "Rejected",\n CANCELLED: "Cancelled",\n COMPLETED: "Completed",\n NONE: "None"\n};\nexports.AnnotationReviewState = AnnotationReviewState;\nconst AnnotationReplyType = {\n GROUP: "Group",\n REPLY: "R"\n};\nexports.AnnotationReplyType = AnnotationReplyType;\nconst AnnotationFlag = {\n INVISIBLE: 0x01,\n HIDDEN: 0x02,\n PRINT: 0x04,\n NOZOOM: 0x08,\n NOROTATE: 0x10,\n NOVIEW: 0x20,\n READONLY: 0x40,\n LOCKED: 0x80,\n TOGGLENOVIEW: 0x100,\n LOCKEDCONTENTS: 0x200\n};\nexports.AnnotationFlag = AnnotationFlag;\nconst AnnotationFieldFlag = {\n READONLY: 0x0000001,\n REQUIRED: 0x0000002,\n NOEXPORT: 0x0000004,\n MULTILINE: 0x0001000,\n PASSWORD: 0x0002000,\n NOTOGGLETOOFF: 0x0004000,\n RADIO: 0x0008000,\n PUSHBUTTON: 0x0010000,\n COMBO: 0x0020000,\n EDIT: 0x0040000,\n SORT: 0x0080000,\n FILESELECT: 0x0100000,\n MULTISELECT: 0x0200000,\n DONOTSPELLCHECK: 0x0400000,\n DONOTSCROLL: 0x0800000,\n COMB: 0x1000000,\n RICHTEXT: 0x2000000,\n RADIOSINUNISON: 0x2000000,\n COMMITONSELCHANGE: 0x4000000\n};\nexports.AnnotationFieldFlag = AnnotationFieldFlag;\nconst AnnotationBorderStyleType = {\n SOLID: 1,\n DASHED: 2,\n BEVELED: 3,\n INSET: 4,\n UNDERLINE: 5\n};\nexports.AnnotationBorderStyleType = AnnotationBorderStyleType;\nconst AnnotationActionEventType = {\n E: "Mouse Enter",\n X: "Mouse Exit",\n D: "Mouse Down",\n U: "Mouse Up",\n Fo: "Focus",\n Bl: "Blur",\n PO: "PageOpen",\n PC: "PageClose",\n PV: "PageVisible",\n PI: "PageInvisible",\n K: "Keystroke",\n F: "Format",\n V: "Validate",\n C: "Calculate"\n};\nexports.AnnotationActionEventType = AnnotationActionEventType;\nconst DocumentActionEventType = {\n WC: "WillClose",\n WS: "WillSave",\n DS: "DidSave",\n WP: "WillPrint",\n DP: "DidPrint"\n};\nexports.DocumentActionEventType = DocumentActionEventType;\nconst PageActionEventType = {\n O: "PageOpen",\n C: "PageClose"\n};\nexports.PageActionEventType = PageActionEventType;\nconst StreamType = {\n UNKNOWN: "UNKNOWN",\n FLATE: "FLATE",\n LZW: "LZW",\n DCT: "DCT",\n JPX: "JPX",\n JBIG: "JBIG",\n A85: "A85",\n AHX: "AHX",\n CCF: "CCF",\n RLX: "RLX"\n};\nexports.StreamType = StreamType;\nconst FontType = {\n UNKNOWN: "UNKNOWN",\n TYPE1: "TYPE1",\n TYPE1STANDARD: "TYPE1STANDARD",\n TYPE1C: "TYPE1C",\n CIDFONTTYPE0: "CIDFONTTYPE0",\n CIDFONTTYPE0C: "CIDFONTTYPE0C",\n TRUETYPE: "TRUETYPE",\n CIDFONTTYPE2: "CIDFONTTYPE2",\n TYPE3: "TYPE3",\n OPENTYPE: "OPENTYPE",\n TYPE0: "TYPE0",\n MMTYPE1: "MMTYPE1"\n};\nexports.FontType = FontType;\nconst VerbosityLevel = {\n ERRORS: 0,\n WARNINGS: 1,\n INFOS: 5\n};\nexports.VerbosityLevel = VerbosityLevel;\nconst CMapCompressionType = {\n NONE: 0,\n BINARY: 1,\n STREAM: 2\n};\nexports.CMapCompressionType = CMapCompressionType;\nconst OPS = {\n dependency: 1,\n setLineWidth: 2,\n setLineCap: 3,\n setLineJoin: 4,\n setMiterLimit: 5,\n setDash: 6,\n setRenderingIntent: 7,\n setFlatness: 8,\n setGState: 9,\n save: 10,\n restore: 11,\n transform: 12,\n moveTo: 13,\n lineTo: 14,\n curveTo: 15,\n curveTo2: 16,\n curveTo3: 17,\n closePath: 18,\n rectangle: 19,\n stroke: 20,\n closeStroke: 21,\n fill: 22,\n eoFill: 23,\n fillStroke: 24,\n eoFillStroke: 25,\n closeFillStroke: 26,\n closeEOFillStroke: 27,\n endPath: 28,\n clip: 29,\n eoClip: 30,\n beginText: 31,\n endText: 32,\n setCharSpacing: 33,\n setWordSpacing: 34,\n setHScale: 35,\n setLeading: 36,\n setFont: 37,\n setTextRenderingMode: 38,\n setTextRise: 39,\n moveText: 40,\n setLeadingMoveText: 41,\n setTextMatrix: 42,\n nextLine: 43,\n showText: 44,\n showSpacedText: 45,\n nextLineShowText: 46,\n nextLineSetSpacingShowText: 47,\n setCharWidth: 48,\n setCharWidthAndBounds: 49,\n setStrokeColorSpace: 50,\n setFillColorSpace: 51,\n setStrokeColor: 52,\n setStrokeColorN: 53,\n setFillColor: 54,\n setFillColorN: 55,\n setStrokeGray: 56,\n setFillGray: 57,\n setStrokeRGBColor: 58,\n setFillRGBColor: 59,\n setStrokeCMYKColor: 60,\n setFillCMYKColor: 61,\n shadingFill: 62,\n beginInlineImage: 63,\n beginImageData: 64,\n endInlineImage: 65,\n paintXObject: 66,\n markPoint: 67,\n markPointProps: 68,\n beginMarkedContent: 69,\n beginMarkedContentProps: 70,\n endMarkedContent: 71,\n beginCompat: 72,\n endCompat: 73,\n paintFormXObjectBegin: 74,\n paintFormXObjectEnd: 75,\n beginGroup: 76,\n endGroup: 77,\n beginAnnotations: 78,\n endAnnotations: 79,\n beginAnnotation: 80,\n endAnnotation: 81,\n paintJpegXObject: 82,\n paintImageMaskXObject: 83,\n paintImageMaskXObjectGroup: 84,\n paintImageXObject: 85,\n paintInlineImageXObject: 86,\n paintInlineImageXObjectGroup: 87,\n paintImageXObjectRepeat: 88,\n paintImageMaskXObjectRepeat: 89,\n paintSolidColorImageMask: 90,\n constructPath: 91\n};\nexports.OPS = OPS;\nconst UNSUPPORTED_FEATURES = {\n unknown: "unknown",\n forms: "forms",\n javaScript: "javaScript",\n signatures: "signatures",\n smask: "smask",\n shadingPattern: "shadingPattern",\n font: "font",\n errorTilingPattern: "errorTilingPattern",\n errorExtGState: "errorExtGState",\n errorXObject: "errorXObject",\n errorFontLoadType3: "errorFontLoadType3",\n errorFontState: "errorFontState",\n errorFontMissing: "errorFontMissing",\n errorFontTranslate: "errorFontTranslate",\n errorColorSpace: "errorColorSpace",\n errorOperatorList: "errorOperatorList",\n errorFontToUnicode: "errorFontToUnicode",\n errorFontLoadNative: "errorFontLoadNative",\n errorFontBuildPath: "errorFontBuildPath",\n errorFontGetPath: "errorFontGetPath",\n errorMarkedContent: "errorMarkedContent",\n errorContentSubStream: "errorContentSubStream"\n};\nexports.UNSUPPORTED_FEATURES = UNSUPPORTED_FEATURES;\nconst PasswordResponses = {\n NEED_PASSWORD: 1,\n INCORRECT_PASSWORD: 2\n};\nexports.PasswordResponses = PasswordResponses;\nlet verbosity = VerbosityLevel.WARNINGS;\n\nfunction setVerbosityLevel(level) {\n if (Number.isInteger(level)) {\n verbosity = level;\n }\n}\n\nfunction getVerbosityLevel() {\n return verbosity;\n}\n\nfunction info(msg) {\n if (verbosity >= VerbosityLevel.INFOS) {\n console.log(`Info: ${msg}`);\n }\n}\n\nfunction warn(msg) {\n if (verbosity >= VerbosityLevel.WARNINGS) {\n console.log(`Warning: ${msg}`);\n }\n}\n\nfunction unreachable(msg) {\n throw new Error(msg);\n}\n\nfunction assert(cond, msg) {\n if (!cond) {\n unreachable(msg);\n }\n}\n\nfunction _isValidProtocol(url) {\n if (!url) {\n return false;\n }\n\n switch (url.protocol) {\n case "http:":\n case "https:":\n case "ftp:":\n case "mailto:":\n case "tel:":\n return true;\n\n default:\n return false;\n }\n}\n\nfunction createValidAbsoluteUrl(url, baseUrl = null, options = null) {\n if (!url) {\n return null;\n }\n\n try {\n if (options && typeof url === "string") {\n if (options.addDefaultProtocol && url.startsWith("www.")) {\n const dots = url.match(/\\./g);\n\n if (dots && dots.length >= 2) {\n url = `http://${url}`;\n }\n }\n\n if (options.tryConvertEncoding) {\n try {\n url = stringToUTF8String(url);\n } catch (ex) {}\n }\n }\n\n const absoluteUrl = baseUrl ? new URL(url, baseUrl) : new URL(url);\n\n if (_isValidProtocol(absoluteUrl)) {\n return absoluteUrl;\n }\n } catch (ex) {}\n\n return null;\n}\n\nfunction shadow(obj, prop, value) {\n Object.defineProperty(obj, prop, {\n value,\n enumerable: true,\n configurable: true,\n writable: false\n });\n return value;\n}\n\nconst BaseException = function BaseExceptionClosure() {\n function BaseException(message, name) {\n if (this.constructor === BaseException) {\n unreachable("Cannot initialize BaseException.");\n }\n\n this.message = message;\n this.name = name;\n }\n\n BaseException.prototype = new Error();\n BaseException.constructor = BaseException;\n return BaseException;\n}();\n\nexports.BaseException = BaseException;\n\nclass PasswordException extends BaseException {\n constructor(msg, code) {\n super(msg, "PasswordException");\n this.code = code;\n }\n\n}\n\nexports.PasswordException = PasswordException;\n\nclass UnknownErrorException extends BaseException {\n constructor(msg, details) {\n super(msg, "UnknownErrorException");\n this.details = details;\n }\n\n}\n\nexports.UnknownErrorException = UnknownErrorException;\n\nclass InvalidPDFException extends BaseException {\n constructor(msg) {\n super(msg, "InvalidPDFException");\n }\n\n}\n\nexports.InvalidPDFException = InvalidPDFException;\n\nclass MissingPDFException extends BaseException {\n constructor(msg) {\n super(msg, "MissingPDFException");\n }\n\n}\n\nexports.MissingPDFException = MissingPDFException;\n\nclass UnexpectedResponseException extends BaseException {\n constructor(msg, status) {\n super(msg, "UnexpectedResponseException");\n this.status = status;\n }\n\n}\n\nexports.UnexpectedResponseException = UnexpectedResponseException;\n\nclass FormatError extends BaseException {\n constructor(msg) {\n super(msg, "FormatError");\n }\n\n}\n\nexports.FormatError = FormatError;\n\nclass AbortException extends BaseException {\n constructor(msg) {\n super(msg, "AbortException");\n }\n\n}\n\nexports.AbortException = AbortException;\n\nfunction bytesToString(bytes) {\n if (typeof bytes !== "object" || bytes === null || bytes.length === undefined) {\n unreachable("Invalid argument for bytesToString");\n }\n\n const length = bytes.length;\n const MAX_ARGUMENT_COUNT = 8192;\n\n if (length < MAX_ARGUMENT_COUNT) {\n return String.fromCharCode.apply(null, bytes);\n }\n\n const strBuf = [];\n\n for (let i = 0; i < length; i += MAX_ARGUMENT_COUNT) {\n const chunkEnd = Math.min(i + MAX_ARGUMENT_COUNT, length);\n const chunk = bytes.subarray(i, chunkEnd);\n strBuf.push(String.fromCharCode.apply(null, chunk));\n }\n\n return strBuf.join("");\n}\n\nfunction stringToBytes(str) {\n if (typeof str !== "string") {\n unreachable("Invalid argument for stringToBytes");\n }\n\n const length = str.length;\n const bytes = new Uint8Array(length);\n\n for (let i = 0; i < length; ++i) {\n bytes[i] = str.charCodeAt(i) & 0xff;\n }\n\n return bytes;\n}\n\nfunction arrayByteLength(arr) {\n if (arr.length !== undefined) {\n return arr.length;\n }\n\n if (arr.byteLength !== undefined) {\n return arr.byteLength;\n }\n\n unreachable("Invalid argument for arrayByteLength");\n}\n\nfunction arraysToBytes(arr) {\n const length = arr.length;\n\n if (length === 1 && arr[0] instanceof Uint8Array) {\n return arr[0];\n }\n\n let resultLength = 0;\n\n for (let i = 0; i < length; i++) {\n resultLength += arrayByteLength(arr[i]);\n }\n\n let pos = 0;\n const data = new Uint8Array(resultLength);\n\n for (let i = 0; i < length; i++) {\n let item = arr[i];\n\n if (!(item instanceof Uint8Array)) {\n if (typeof item === "string") {\n item = stringToBytes(item);\n } else {\n item = new Uint8Array(item);\n }\n }\n\n const itemLength = item.byteLength;\n data.set(item, pos);\n pos += itemLength;\n }\n\n return data;\n}\n\nfunction string32(value) {\n return String.fromCharCode(value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff);\n}\n\nfunction objectSize(obj) {\n return Object.keys(obj).length;\n}\n\nfunction objectFromMap(map) {\n const obj = Object.create(null);\n\n for (const [key, value] of map) {\n obj[key] = value;\n }\n\n return obj;\n}\n\nfunction isLittleEndian() {\n const buffer8 = new Uint8Array(4);\n buffer8[0] = 1;\n const view32 = new Uint32Array(buffer8.buffer, 0, 1);\n return view32[0] === 1;\n}\n\nfunction isEvalSupported() {\n try {\n new Function("");\n return true;\n } catch (e) {\n return false;\n }\n}\n\nclass FeatureTest {\n static get isLittleEndian() {\n return shadow(this, "isLittleEndian", isLittleEndian());\n }\n\n static get isEvalSupported() {\n return shadow(this, "isEvalSupported", isEvalSupported());\n }\n\n static get isOffscreenCanvasSupported() {\n return shadow(this, "isOffscreenCanvasSupported", typeof OffscreenCanvas !== "undefined");\n }\n\n}\n\nexports.FeatureTest = FeatureTest;\nconst hexNumbers = [...Array(256).keys()].map(n => n.toString(16).padStart(2, "0"));\n\nclass Util {\n static makeHexColor(r, g, b) {\n return `#${hexNumbers[r]}${hexNumbers[g]}${hexNumbers[b]}`;\n }\n\n static scaleMinMax(transform, minMax) {\n let temp;\n\n if (transform[0]) {\n if (transform[0] < 0) {\n temp = minMax[0];\n minMax[0] = minMax[1];\n minMax[1] = temp;\n }\n\n minMax[0] *= transform[0];\n minMax[1] *= transform[0];\n\n if (transform[3] < 0) {\n temp = minMax[2];\n minMax[2] = minMax[3];\n minMax[3] = temp;\n }\n\n minMax[2] *= transform[3];\n minMax[3] *= transform[3];\n } else {\n temp = minMax[0];\n minMax[0] = minMax[2];\n minMax[2] = temp;\n temp = minMax[1];\n minMax[1] = minMax[3];\n minMax[3] = temp;\n\n if (transform[1] < 0) {\n temp = minMax[2];\n minMax[2] = minMax[3];\n minMax[3] = temp;\n }\n\n minMax[2] *= transform[1];\n minMax[3] *= transform[1];\n\n if (transform[2] < 0) {\n temp = minMax[0];\n minMax[0] = minMax[1];\n minMax[1] = temp;\n }\n\n minMax[0] *= transform[2];\n minMax[1] *= transform[2];\n }\n\n minMax[0] += transform[4];\n minMax[1] += transform[4];\n minMax[2] += transform[5];\n minMax[3] += transform[5];\n }\n\n static transform(m1, m2) {\n return [m1[0] * m2[0] + m1[2] * m2[1], m1[1] * m2[0] + m1[3] * m2[1], m1[0] * m2[2] + m1[2] * m2[3], m1[1] * m2[2] + m1[3] * m2[3], m1[0] * m2[4] + m1[2] * m2[5] + m1[4], m1[1] * m2[4] + m1[3] * m2[5] + m1[5]];\n }\n\n static applyTransform(p, m) {\n const xt = p[0] * m[0] + p[1] * m[2] + m[4];\n const yt = p[0] * m[1] + p[1] * m[3] + m[5];\n return [xt, yt];\n }\n\n static applyInverseTransform(p, m) {\n const d = m[0] * m[3] - m[1] * m[2];\n const xt = (p[0] * m[3] - p[1] * m[2] + m[2] * m[5] - m[4] * m[3]) / d;\n const yt = (-p[0] * m[1] + p[1] * m[0] + m[4] * m[1] - m[5] * m[0]) / d;\n return [xt, yt];\n }\n\n static getAxialAlignedBoundingBox(r, m) {\n const p1 = Util.applyTransform(r, m);\n const p2 = Util.applyTransform(r.slice(2, 4), m);\n const p3 = Util.applyTransform([r[0], r[3]], m);\n const p4 = Util.applyTransform([r[2], r[1]], m);\n return [Math.min(p1[0], p2[0], p3[0], p4[0]), Math.min(p1[1], p2[1], p3[1], p4[1]), Math.max(p1[0], p2[0], p3[0], p4[0]), Math.max(p1[1], p2[1], p3[1], p4[1])];\n }\n\n static inverseTransform(m) {\n const d = m[0] * m[3] - m[1] * m[2];\n return [m[3] / d, -m[1] / d, -m[2] / d, m[0] / d, (m[2] * m[5] - m[4] * m[3]) / d, (m[4] * m[1] - m[5] * m[0]) / d];\n }\n\n static apply3dTransform(m, v) {\n return [m[0] * v[0] + m[1] * v[1] + m[2] * v[2], m[3] * v[0] + m[4] * v[1] + m[5] * v[2], m[6] * v[0] + m[7] * v[1] + m[8] * v[2]];\n }\n\n static singularValueDecompose2dScale(m) {\n const transpose = [m[0], m[2], m[1], m[3]];\n const a = m[0] * transpose[0] + m[1] * transpose[2];\n const b = m[0] * transpose[1] + m[1] * transpose[3];\n const c = m[2] * transpose[0] + m[3] * transpose[2];\n const d = m[2] * transpose[1] + m[3] * transpose[3];\n const first = (a + d) / 2;\n const second = Math.sqrt((a + d) ** 2 - 4 * (a * d - c * b)) / 2;\n const sx = first + second || 1;\n const sy = first - second || 1;\n return [Math.sqrt(sx), Math.sqrt(sy)];\n }\n\n static normalizeRect(rect) {\n const r = rect.slice(0);\n\n if (rect[0] > rect[2]) {\n r[0] = rect[2];\n r[2] = rect[0];\n }\n\n if (rect[1] > rect[3]) {\n r[1] = rect[3];\n r[3] = rect[1];\n }\n\n return r;\n }\n\n static intersect(rect1, rect2) {\n const xLow = Math.max(Math.min(rect1[0], rect1[2]), Math.min(rect2[0], rect2[2]));\n const xHigh = Math.min(Math.max(rect1[0], rect1[2]), Math.max(rect2[0], rect2[2]));\n\n if (xLow > xHigh) {\n return null;\n }\n\n const yLow = Math.max(Math.min(rect1[1], rect1[3]), Math.min(rect2[1], rect2[3]));\n const yHigh = Math.min(Math.max(rect1[1], rect1[3]), Math.max(rect2[1], rect2[3]));\n\n if (yLow > yHigh) {\n return null;\n }\n\n return [xLow, yLow, xHigh, yHigh];\n }\n\n static bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3) {\n const tvalues = [],\n bounds = [[], []];\n let a, b, c, t, t1, t2, b2ac, sqrtb2ac;\n\n for (let i = 0; i < 2; ++i) {\n if (i === 0) {\n b = 6 * x0 - 12 * x1 + 6 * x2;\n a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;\n c = 3 * x1 - 3 * x0;\n } else {\n b = 6 * y0 - 12 * y1 + 6 * y2;\n a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;\n c = 3 * y1 - 3 * y0;\n }\n\n if (Math.abs(a) < 1e-12) {\n if (Math.abs(b) < 1e-12) {\n continue;\n }\n\n t = -c / b;\n\n if (0 < t && t < 1) {\n tvalues.push(t);\n }\n\n continue;\n }\n\n b2ac = b * b - 4 * c * a;\n sqrtb2ac = Math.sqrt(b2ac);\n\n if (b2ac < 0) {\n continue;\n }\n\n t1 = (-b + sqrtb2ac) / (2 * a);\n\n if (0 < t1 && t1 < 1) {\n tvalues.push(t1);\n }\n\n t2 = (-b - sqrtb2ac) / (2 * a);\n\n if (0 < t2 && t2 < 1) {\n tvalues.push(t2);\n }\n }\n\n let j = tvalues.length,\n mt;\n const jlen = j;\n\n while (j--) {\n t = tvalues[j];\n mt = 1 - t;\n bounds[0][j] = mt * mt * mt * x0 + 3 * mt * mt * t * x1 + 3 * mt * t * t * x2 + t * t * t * x3;\n bounds[1][j] = mt * mt * mt * y0 + 3 * mt * mt * t * y1 + 3 * mt * t * t * y2 + t * t * t * y3;\n }\n\n bounds[0][jlen] = x0;\n bounds[1][jlen] = y0;\n bounds[0][jlen + 1] = x3;\n bounds[1][jlen + 1] = y3;\n bounds[0].length = bounds[1].length = jlen + 2;\n return [Math.min(...bounds[0]), Math.min(...bounds[1]), Math.max(...bounds[0]), Math.max(...bounds[1])];\n }\n\n}\n\nexports.Util = Util;\nconst PDFStringTranslateTable = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2d8, 0x2c7, 0x2c6, 0x2d9, 0x2dd, 0x2db, 0x2da, 0x2dc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x192, 0x2044, 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018, 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x141, 0x152, 0x160, 0x178, 0x17d, 0x131, 0x142, 0x153, 0x161, 0x17e, 0, 0x20ac];\n\nfunction stringToPDFString(str) {\n if (str[0] >= "\\xEF") {\n let encoding;\n\n if (str[0] === "\\xFE" && str[1] === "\\xFF") {\n encoding = "utf-16be";\n } else if (str[0] === "\\xFF" && str[1] === "\\xFE") {\n encoding = "utf-16le";\n } else if (str[0] === "\\xEF" && str[1] === "\\xBB" && str[2] === "\\xBF") {\n encoding = "utf-8";\n }\n\n if (encoding) {\n try {\n const decoder = new TextDecoder(encoding, {\n fatal: true\n });\n const buffer = stringToBytes(str);\n return decoder.decode(buffer);\n } catch (ex) {\n warn(`stringToPDFString: "${ex}".`);\n }\n }\n }\n\n const strBuf = [];\n\n for (let i = 0, ii = str.length; i < ii; i++) {\n const code = PDFStringTranslateTable[str.charCodeAt(i)];\n strBuf.push(code ? String.fromCharCode(code) : str.charAt(i));\n }\n\n return strBuf.join("");\n}\n\nfunction escapeString(str) {\n return str.replace(/([()\\\\\\n\\r])/g, match => {\n if (match === "\\n") {\n return "\\\\n";\n } else if (match === "\\r") {\n return "\\\\r";\n }\n\n return `\\\\${match}`;\n });\n}\n\nfunction isAscii(str) {\n return /^[\\x00-\\x7F]*$/.test(str);\n}\n\nfunction stringToUTF16BEString(str) {\n const buf = ["\\xFE\\xFF"];\n\n for (let i = 0, ii = str.length; i < ii; i++) {\n const char = str.charCodeAt(i);\n buf.push(String.fromCharCode(char >> 8 & 0xff), String.fromCharCode(char & 0xff));\n }\n\n return buf.join("");\n}\n\nfunction stringToUTF8String(str) {\n return decodeURIComponent(escape(str));\n}\n\nfunction utf8StringToString(str) {\n return unescape(encodeURIComponent(str));\n}\n\nfunction isArrayBuffer(v) {\n return typeof v === "object" && v !== null && v.byteLength !== undefined;\n}\n\nfunction isArrayEqual(arr1, arr2) {\n if (arr1.length !== arr2.length) {\n return false;\n }\n\n for (let i = 0, ii = arr1.length; i < ii; i++) {\n if (arr1[i] !== arr2[i]) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction getModificationDate(date = new Date()) {\n const buffer = [date.getUTCFullYear().toString(), (date.getUTCMonth() + 1).toString().padStart(2, "0"), date.getUTCDate().toString().padStart(2, "0"), date.getUTCHours().toString().padStart(2, "0"), date.getUTCMinutes().toString().padStart(2, "0"), date.getUTCSeconds().toString().padStart(2, "0")];\n return buffer.join("");\n}\n\nfunction createPromiseCapability() {\n const capability = Object.create(null);\n let isSettled = false;\n Object.defineProperty(capability, "settled", {\n get() {\n return isSettled;\n }\n\n });\n capability.promise = new Promise(function (resolve, reject) {\n capability.resolve = function (data) {\n isSettled = true;\n resolve(data);\n };\n\n capability.reject = function (reason) {\n isSettled = true;\n reject(reason);\n };\n });\n return capability;\n}\n\n/***/ }),\n/* 2 */\n/***/ ((__unused_webpack_module, __unused_webpack_exports, __w_pdfjs_require__) => {\n\n\n\nvar _is_node = __w_pdfjs_require__(3);\n\n;\n\n/***/ }),\n/* 3 */\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.isNodeJS = void 0;\nconst isNodeJS = typeof process === "object" && process + "" === "[object process]" && !process.versions.nw && !(process.versions.electron && process.type && process.type !== "browser");\nexports.isNodeJS = isNodeJS;\n\n/***/ }),\n/* 4 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.build = exports.RenderTask = exports.PDFWorkerUtil = exports.PDFWorker = exports.PDFPageProxy = exports.PDFDocumentProxy = exports.PDFDocumentLoadingTask = exports.PDFDataRangeTransport = exports.LoopbackPort = exports.DefaultStandardFontDataFactory = exports.DefaultCanvasFactory = exports.DefaultCMapReaderFactory = void 0;\nexports.getDocument = getDocument;\nexports.setPDFNetworkStreamFactory = setPDFNetworkStreamFactory;\nexports.version = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _display_utils = __w_pdfjs_require__(5);\n\nvar _font_loader = __w_pdfjs_require__(7);\n\nvar _annotation_storage = __w_pdfjs_require__(8);\n\nvar _canvas = __w_pdfjs_require__(10);\n\nvar _worker_options = __w_pdfjs_require__(13);\n\nvar _is_node = __w_pdfjs_require__(3);\n\nvar _message_handler = __w_pdfjs_require__(14);\n\nvar _metadata = __w_pdfjs_require__(15);\n\nvar _optional_content_config = __w_pdfjs_require__(16);\n\nvar _transport_stream = __w_pdfjs_require__(17);\n\nvar _xfa_text = __w_pdfjs_require__(18);\n\nconst DEFAULT_RANGE_CHUNK_SIZE = 65536;\nconst RENDERING_CANCELLED_TIMEOUT = 100;\nlet DefaultCanvasFactory = _display_utils.DOMCanvasFactory;\nexports.DefaultCanvasFactory = DefaultCanvasFactory;\nlet DefaultCMapReaderFactory = _display_utils.DOMCMapReaderFactory;\nexports.DefaultCMapReaderFactory = DefaultCMapReaderFactory;\nlet DefaultStandardFontDataFactory = _display_utils.DOMStandardFontDataFactory;\nexports.DefaultStandardFontDataFactory = DefaultStandardFontDataFactory;\n\nif (_is_node.isNodeJS) {\n const {\n NodeCanvasFactory,\n NodeCMapReaderFactory,\n NodeStandardFontDataFactory\n } = __w_pdfjs_require__(19);\n\n exports.DefaultCanvasFactory = DefaultCanvasFactory = NodeCanvasFactory;\n exports.DefaultCMapReaderFactory = DefaultCMapReaderFactory = NodeCMapReaderFactory;\n exports.DefaultStandardFontDataFactory = DefaultStandardFontDataFactory = NodeStandardFontDataFactory;\n}\n\nlet createPDFNetworkStream;\n\nfunction setPDFNetworkStreamFactory(pdfNetworkStreamFactory) {\n createPDFNetworkStream = pdfNetworkStreamFactory;\n}\n\nfunction getDocument(src) {\n const task = new PDFDocumentLoadingTask();\n let source;\n\n if (typeof src === "string" || src instanceof URL) {\n source = {\n url: src\n };\n } else if ((0, _util.isArrayBuffer)(src)) {\n source = {\n data: src\n };\n } else if (src instanceof PDFDataRangeTransport) {\n source = {\n range: src\n };\n } else {\n if (typeof src !== "object") {\n throw new Error("Invalid parameter in getDocument, " + "need either string, URL, Uint8Array, or parameter object.");\n }\n\n if (!src.url && !src.data && !src.range) {\n throw new Error("Invalid parameter object: need either .data, .range or .url");\n }\n\n source = src;\n }\n\n const params = Object.create(null);\n let rangeTransport = null,\n worker = null;\n\n for (const key in source) {\n const value = source[key];\n\n switch (key) {\n case "url":\n if (typeof window !== "undefined") {\n try {\n params[key] = new URL(value, window.location).href;\n continue;\n } catch (ex) {\n (0, _util.warn)(`Cannot create valid URL: "${ex}".`);\n }\n } else if (typeof value === "string" || value instanceof URL) {\n params[key] = value.toString();\n continue;\n }\n\n throw new Error("Invalid PDF url data: " + "either string or URL-object is expected in the url property.");\n\n case "range":\n rangeTransport = value;\n continue;\n\n case "worker":\n worker = value;\n continue;\n\n case "data":\n if (_is_node.isNodeJS && typeof Buffer !== "undefined" && value instanceof Buffer) {\n params[key] = new Uint8Array(value);\n } else if (value instanceof Uint8Array) {\n break;\n } else if (typeof value === "string") {\n params[key] = (0, _util.stringToBytes)(value);\n } else if (typeof value === "object" && value !== null && !isNaN(value.length)) {\n params[key] = new Uint8Array(value);\n } else if ((0, _util.isArrayBuffer)(value)) {\n params[key] = new Uint8Array(value);\n } else {\n throw new Error("Invalid PDF binary data: either typed array, " + "string, or array-like object is expected in the data property.");\n }\n\n continue;\n }\n\n params[key] = value;\n }\n\n params.CMapReaderFactory = params.CMapReaderFactory || DefaultCMapReaderFactory;\n params.StandardFontDataFactory = params.StandardFontDataFactory || DefaultStandardFontDataFactory;\n params.ignoreErrors = params.stopAtErrors !== true;\n params.fontExtraProperties = params.fontExtraProperties === true;\n params.pdfBug = params.pdfBug === true;\n params.enableXfa = params.enableXfa === true;\n\n if (!Number.isInteger(params.rangeChunkSize) || params.rangeChunkSize < 1) {\n params.rangeChunkSize = DEFAULT_RANGE_CHUNK_SIZE;\n }\n\n if (typeof params.docBaseUrl !== "string" || (0, _display_utils.isDataScheme)(params.docBaseUrl)) {\n params.docBaseUrl = null;\n }\n\n if (!Number.isInteger(params.maxImageSize) || params.maxImageSize < -1) {\n params.maxImageSize = -1;\n }\n\n if (typeof params.cMapUrl !== "string") {\n params.cMapUrl = null;\n }\n\n if (typeof params.standardFontDataUrl !== "string") {\n params.standardFontDataUrl = null;\n }\n\n if (typeof params.useWorkerFetch !== "boolean") {\n params.useWorkerFetch = params.CMapReaderFactory === _display_utils.DOMCMapReaderFactory && params.StandardFontDataFactory === _display_utils.DOMStandardFontDataFactory;\n }\n\n if (typeof params.isEvalSupported !== "boolean") {\n params.isEvalSupported = true;\n }\n\n if (typeof params.disableFontFace !== "boolean") {\n params.disableFontFace = _is_node.isNodeJS;\n }\n\n if (typeof params.useSystemFonts !== "boolean") {\n params.useSystemFonts = !_is_node.isNodeJS && !params.disableFontFace;\n }\n\n if (typeof params.ownerDocument !== "object" || params.ownerDocument === null) {\n params.ownerDocument = globalThis.document;\n }\n\n if (typeof params.disableRange !== "boolean") {\n params.disableRange = false;\n }\n\n if (typeof params.disableStream !== "boolean") {\n params.disableStream = false;\n }\n\n if (typeof params.disableAutoFetch !== "boolean") {\n params.disableAutoFetch = false;\n }\n\n (0, _util.setVerbosityLevel)(params.verbosity);\n\n if (!worker) {\n const workerParams = {\n verbosity: params.verbosity,\n port: _worker_options.GlobalWorkerOptions.workerPort\n };\n worker = workerParams.port ? PDFWorker.fromPort(workerParams) : new PDFWorker(workerParams);\n task._worker = worker;\n }\n\n const docId = task.docId;\n worker.promise.then(function () {\n if (task.destroyed) {\n throw new Error("Loading aborted");\n }\n\n const workerIdPromise = _fetchDocument(worker, params, rangeTransport, docId);\n\n const networkStreamPromise = new Promise(function (resolve) {\n let networkStream;\n\n if (rangeTransport) {\n networkStream = new _transport_stream.PDFDataTransportStream({\n length: params.length,\n initialData: params.initialData,\n progressiveDone: params.progressiveDone,\n contentDispositionFilename: params.contentDispositionFilename,\n disableRange: params.disableRange,\n disableStream: params.disableStream\n }, rangeTransport);\n } else if (!params.data) {\n networkStream = createPDFNetworkStream({\n url: params.url,\n length: params.length,\n httpHeaders: params.httpHeaders,\n withCredentials: params.withCredentials,\n rangeChunkSize: params.rangeChunkSize,\n disableRange: params.disableRange,\n disableStream: params.disableStream\n });\n }\n\n resolve(networkStream);\n });\n return Promise.all([workerIdPromise, networkStreamPromise]).then(function ([workerId, networkStream]) {\n if (task.destroyed) {\n throw new Error("Loading aborted");\n }\n\n const messageHandler = new _message_handler.MessageHandler(docId, workerId, worker.port);\n const transport = new WorkerTransport(messageHandler, task, networkStream, params);\n task._transport = transport;\n messageHandler.send("Ready", null);\n });\n }).catch(task._capability.reject);\n return task;\n}\n\nasync function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {\n if (worker.destroyed) {\n throw new Error("Worker was destroyed");\n }\n\n if (pdfDataRangeTransport) {\n source.length = pdfDataRangeTransport.length;\n source.initialData = pdfDataRangeTransport.initialData;\n source.progressiveDone = pdfDataRangeTransport.progressiveDone;\n source.contentDispositionFilename = pdfDataRangeTransport.contentDispositionFilename;\n }\n\n const workerId = await worker.messageHandler.sendWithPromise("GetDocRequest", {\n docId,\n apiVersion: \'2.14.305\',\n source: {\n data: source.data,\n url: source.url,\n password: source.password,\n disableAutoFetch: source.disableAutoFetch,\n rangeChunkSize: source.rangeChunkSize,\n length: source.length\n },\n maxImageSize: source.maxImageSize,\n disableFontFace: source.disableFontFace,\n docBaseUrl: source.docBaseUrl,\n ignoreErrors: source.ignoreErrors,\n isEvalSupported: source.isEvalSupported,\n fontExtraProperties: source.fontExtraProperties,\n enableXfa: source.enableXfa,\n useSystemFonts: source.useSystemFonts,\n cMapUrl: source.useWorkerFetch ? source.cMapUrl : null,\n standardFontDataUrl: source.useWorkerFetch ? source.standardFontDataUrl : null\n });\n\n if (worker.destroyed) {\n throw new Error("Worker was destroyed");\n }\n\n return workerId;\n}\n\nclass PDFDocumentLoadingTask {\n static #docId = 0;\n\n constructor() {\n this._capability = (0, _util.createPromiseCapability)();\n this._transport = null;\n this._worker = null;\n this.docId = `d${PDFDocumentLoadingTask.#docId++}`;\n this.destroyed = false;\n this.onPassword = null;\n this.onProgress = null;\n this.onUnsupportedFeature = null;\n }\n\n get promise() {\n return this._capability.promise;\n }\n\n async destroy() {\n this.destroyed = true;\n await this._transport?.destroy();\n this._transport = null;\n\n if (this._worker) {\n this._worker.destroy();\n\n this._worker = null;\n }\n }\n\n}\n\nexports.PDFDocumentLoadingTask = PDFDocumentLoadingTask;\n\nclass PDFDataRangeTransport {\n constructor(length, initialData, progressiveDone = false, contentDispositionFilename = null) {\n this.length = length;\n this.initialData = initialData;\n this.progressiveDone = progressiveDone;\n this.contentDispositionFilename = contentDispositionFilename;\n this._rangeListeners = [];\n this._progressListeners = [];\n this._progressiveReadListeners = [];\n this._progressiveDoneListeners = [];\n this._readyCapability = (0, _util.createPromiseCapability)();\n }\n\n addRangeListener(listener) {\n this._rangeListeners.push(listener);\n }\n\n addProgressListener(listener) {\n this._progressListeners.push(listener);\n }\n\n addProgressiveReadListener(listener) {\n this._progressiveReadListeners.push(listener);\n }\n\n addProgressiveDoneListener(listener) {\n this._progressiveDoneListeners.push(listener);\n }\n\n onDataRange(begin, chunk) {\n for (const listener of this._rangeListeners) {\n listener(begin, chunk);\n }\n }\n\n onDataProgress(loaded, total) {\n this._readyCapability.promise.then(() => {\n for (const listener of this._progressListeners) {\n listener(loaded, total);\n }\n });\n }\n\n onDataProgressiveRead(chunk) {\n this._readyCapability.promise.then(() => {\n for (const listener of this._progressiveReadListeners) {\n listener(chunk);\n }\n });\n }\n\n onDataProgressiveDone() {\n this._readyCapability.promise.then(() => {\n for (const listener of this._progressiveDoneListeners) {\n listener();\n }\n });\n }\n\n transportReady() {\n this._readyCapability.resolve();\n }\n\n requestDataRange(begin, end) {\n (0, _util.unreachable)("Abstract method PDFDataRangeTransport.requestDataRange");\n }\n\n abort() {}\n\n}\n\nexports.PDFDataRangeTransport = PDFDataRangeTransport;\n\nclass PDFDocumentProxy {\n constructor(pdfInfo, transport) {\n this._pdfInfo = pdfInfo;\n this._transport = transport;\n Object.defineProperty(this, "fingerprint", {\n get() {\n (0, _display_utils.deprecated)("`PDFDocumentProxy.fingerprint`, " + "please use `PDFDocumentProxy.fingerprints` instead.");\n return this.fingerprints[0];\n }\n\n });\n Object.defineProperty(this, "getStats", {\n value: async () => {\n (0, _display_utils.deprecated)("`PDFDocumentProxy.getStats`, " + "please use the `PDFDocumentProxy.stats`-getter instead.");\n return this.stats || {\n streamTypes: {},\n fontTypes: {}\n };\n }\n });\n }\n\n get annotationStorage() {\n return this._transport.annotationStorage;\n }\n\n get numPages() {\n return this._pdfInfo.numPages;\n }\n\n get fingerprints() {\n return this._pdfInfo.fingerprints;\n }\n\n get stats() {\n return this._transport.stats;\n }\n\n get isPureXfa() {\n return !!this._transport._htmlForXfa;\n }\n\n get allXfaHtml() {\n return this._transport._htmlForXfa;\n }\n\n getPage(pageNumber) {\n return this._transport.getPage(pageNumber);\n }\n\n getPageIndex(ref) {\n return this._transport.getPageIndex(ref);\n }\n\n getDestinations() {\n return this._transport.getDestinations();\n }\n\n getDestination(id) {\n return this._transport.getDestination(id);\n }\n\n getPageLabels() {\n return this._transport.getPageLabels();\n }\n\n getPageLayout() {\n return this._transport.getPageLayout();\n }\n\n getPageMode() {\n return this._transport.getPageMode();\n }\n\n getViewerPreferences() {\n return this._transport.getViewerPreferences();\n }\n\n getOpenAction() {\n return this._transport.getOpenAction();\n }\n\n getAttachments() {\n return this._transport.getAttachments();\n }\n\n getJavaScript() {\n return this._transport.getJavaScript();\n }\n\n getJSActions() {\n return this._transport.getDocJSActions();\n }\n\n getOutline() {\n return this._transport.getOutline();\n }\n\n getOptionalContentConfig() {\n return this._transport.getOptionalContentConfig();\n }\n\n getPermissions() {\n return this._transport.getPermissions();\n }\n\n getMetadata() {\n return this._transport.getMetadata();\n }\n\n getMarkInfo() {\n return this._transport.getMarkInfo();\n }\n\n getData() {\n return this._transport.getData();\n }\n\n getDownloadInfo() {\n return this._transport.downloadInfoCapability.promise;\n }\n\n cleanup(keepLoadedFonts = false) {\n return this._transport.startCleanup(keepLoadedFonts || this.isPureXfa);\n }\n\n destroy() {\n return this.loadingTask.destroy();\n }\n\n get loadingParams() {\n return this._transport.loadingParams;\n }\n\n get loadingTask() {\n return this._transport.loadingTask;\n }\n\n saveDocument() {\n if (this._transport.annotationStorage.size <= 0) {\n (0, _display_utils.deprecated)("saveDocument called while `annotationStorage` is empty, " + "please use the getData-method instead.");\n }\n\n return this._transport.saveDocument();\n }\n\n getFieldObjects() {\n return this._transport.getFieldObjects();\n }\n\n hasJSActions() {\n return this._transport.hasJSActions();\n }\n\n getCalculationOrderIds() {\n return this._transport.getCalculationOrderIds();\n }\n\n}\n\nexports.PDFDocumentProxy = PDFDocumentProxy;\n\nclass PDFPageProxy {\n constructor(pageIndex, pageInfo, transport, ownerDocument, pdfBug = false) {\n this._pageIndex = pageIndex;\n this._pageInfo = pageInfo;\n this._ownerDocument = ownerDocument;\n this._transport = transport;\n this._stats = pdfBug ? new _display_utils.StatTimer() : null;\n this._pdfBug = pdfBug;\n this.commonObjs = transport.commonObjs;\n this.objs = new PDFObjects();\n this._bitmaps = new Set();\n this.cleanupAfterRender = false;\n this.pendingCleanup = false;\n this._intentStates = new Map();\n this._annotationPromises = new Map();\n this.destroyed = false;\n }\n\n get pageNumber() {\n return this._pageIndex + 1;\n }\n\n get rotate() {\n return this._pageInfo.rotate;\n }\n\n get ref() {\n return this._pageInfo.ref;\n }\n\n get userUnit() {\n return this._pageInfo.userUnit;\n }\n\n get view() {\n return this._pageInfo.view;\n }\n\n getViewport({\n scale,\n rotation = this.rotate,\n offsetX = 0,\n offsetY = 0,\n dontFlip = false\n } = {}) {\n return new _display_utils.PageViewport({\n viewBox: this.view,\n scale,\n rotation,\n offsetX,\n offsetY,\n dontFlip\n });\n }\n\n getAnnotations({\n intent = "display"\n } = {}) {\n const intentArgs = this._transport.getRenderingIntent(intent);\n\n let promise = this._annotationPromises.get(intentArgs.cacheKey);\n\n if (!promise) {\n promise = this._transport.getAnnotations(this._pageIndex, intentArgs.renderingIntent);\n\n this._annotationPromises.set(intentArgs.cacheKey, promise);\n\n promise = promise.then(annotations => {\n for (const annotation of annotations) {\n if (annotation.titleObj !== undefined) {\n Object.defineProperty(annotation, "title", {\n get() {\n (0, _display_utils.deprecated)("`title`-property on annotation, please use `titleObj` instead.");\n return annotation.titleObj.str;\n }\n\n });\n }\n\n if (annotation.contentsObj !== undefined) {\n Object.defineProperty(annotation, "contents", {\n get() {\n (0, _display_utils.deprecated)("`contents`-property on annotation, please use `contentsObj` instead.");\n return annotation.contentsObj.str;\n }\n\n });\n }\n }\n\n return annotations;\n });\n }\n\n return promise;\n }\n\n getJSActions() {\n return this._jsActionsPromise ||= this._transport.getPageJSActions(this._pageIndex);\n }\n\n async getXfa() {\n return this._transport._htmlForXfa?.children[this._pageIndex] || null;\n }\n\n render({\n canvasContext,\n viewport,\n intent = "display",\n annotationMode = _util.AnnotationMode.ENABLE,\n transform = null,\n imageLayer = null,\n canvasFactory = null,\n background = null,\n optionalContentConfigPromise = null,\n annotationCanvasMap = null,\n pageColors = null\n }) {\n if (arguments[0]?.renderInteractiveForms !== undefined) {\n (0, _display_utils.deprecated)("render no longer accepts the `renderInteractiveForms`-option, " + "please use the `annotationMode`-option instead.");\n\n if (arguments[0].renderInteractiveForms === true && annotationMode === _util.AnnotationMode.ENABLE) {\n annotationMode = _util.AnnotationMode.ENABLE_FORMS;\n }\n }\n\n if (arguments[0]?.includeAnnotationStorage !== undefined) {\n (0, _display_utils.deprecated)("render no longer accepts the `includeAnnotationStorage`-option, " + "please use the `annotationMode`-option instead.");\n\n if (arguments[0].includeAnnotationStorage === true && annotationMode === _util.AnnotationMode.ENABLE) {\n annotationMode = _util.AnnotationMode.ENABLE_STORAGE;\n }\n }\n\n if (this._stats) {\n this._stats.time("Overall");\n }\n\n const intentArgs = this._transport.getRenderingIntent(intent, annotationMode);\n\n this.pendingCleanup = false;\n\n if (!optionalContentConfigPromise) {\n optionalContentConfigPromise = this._transport.getOptionalContentConfig();\n }\n\n let intentState = this._intentStates.get(intentArgs.cacheKey);\n\n if (!intentState) {\n intentState = Object.create(null);\n\n this._intentStates.set(intentArgs.cacheKey, intentState);\n }\n\n if (intentState.streamReaderCancelTimeout) {\n clearTimeout(intentState.streamReaderCancelTimeout);\n intentState.streamReaderCancelTimeout = null;\n }\n\n const canvasFactoryInstance = canvasFactory || new DefaultCanvasFactory({\n ownerDocument: this._ownerDocument\n });\n const intentPrint = !!(intentArgs.renderingIntent & _util.RenderingIntentFlag.PRINT);\n\n if (!intentState.displayReadyCapability) {\n intentState.displayReadyCapability = (0, _util.createPromiseCapability)();\n intentState.operatorList = {\n fnArray: [],\n argsArray: [],\n lastChunk: false\n };\n\n if (this._stats) {\n this._stats.time("Page Request");\n }\n\n this._pumpOperatorList(intentArgs);\n }\n\n const complete = error => {\n intentState.renderTasks.delete(internalRenderTask);\n\n if (this.cleanupAfterRender || intentPrint) {\n this.pendingCleanup = true;\n }\n\n this._tryCleanup();\n\n if (error) {\n internalRenderTask.capability.reject(error);\n\n this._abortOperatorList({\n intentState,\n reason: error instanceof Error ? error : new Error(error)\n });\n } else {\n internalRenderTask.capability.resolve();\n }\n\n if (this._stats) {\n this._stats.timeEnd("Rendering");\n\n this._stats.timeEnd("Overall");\n }\n };\n\n const internalRenderTask = new InternalRenderTask({\n callback: complete,\n params: {\n canvasContext,\n viewport,\n transform,\n imageLayer,\n background\n },\n objs: this.objs,\n commonObjs: this.commonObjs,\n annotationCanvasMap,\n operatorList: intentState.operatorList,\n pageIndex: this._pageIndex,\n canvasFactory: canvasFactoryInstance,\n useRequestAnimationFrame: !intentPrint,\n pdfBug: this._pdfBug,\n pageColors\n });\n (intentState.renderTasks ||= new Set()).add(internalRenderTask);\n const renderTask = internalRenderTask.task;\n Promise.all([intentState.displayReadyCapability.promise, optionalContentConfigPromise]).then(([transparency, optionalContentConfig]) => {\n if (this.pendingCleanup) {\n complete();\n return;\n }\n\n if (this._stats) {\n this._stats.time("Rendering");\n }\n\n internalRenderTask.initializeGraphics({\n transparency,\n optionalContentConfig\n });\n internalRenderTask.operatorListChanged();\n }).catch(complete);\n return renderTask;\n }\n\n getOperatorList({\n intent = "display",\n annotationMode = _util.AnnotationMode.ENABLE\n } = {}) {\n function operatorListChanged() {\n if (intentState.operatorList.lastChunk) {\n intentState.opListReadCapability.resolve(intentState.operatorList);\n intentState.renderTasks.delete(opListTask);\n }\n }\n\n const intentArgs = this._transport.getRenderingIntent(intent, annotationMode, true);\n\n let intentState = this._intentStates.get(intentArgs.cacheKey);\n\n if (!intentState) {\n intentState = Object.create(null);\n\n this._intentStates.set(intentArgs.cacheKey, intentState);\n }\n\n let opListTask;\n\n if (!intentState.opListReadCapability) {\n opListTask = Object.create(null);\n opListTask.operatorListChanged = operatorListChanged;\n intentState.opListReadCapability = (0, _util.createPromiseCapability)();\n (intentState.renderTasks ||= new Set()).add(opListTask);\n intentState.operatorList = {\n fnArray: [],\n argsArray: [],\n lastChunk: false\n };\n\n if (this._stats) {\n this._stats.time("Page Request");\n }\n\n this._pumpOperatorList(intentArgs);\n }\n\n return intentState.opListReadCapability.promise;\n }\n\n streamTextContent({\n disableCombineTextItems = false,\n includeMarkedContent = false\n } = {}) {\n const TEXT_CONTENT_CHUNK_SIZE = 100;\n return this._transport.messageHandler.sendWithStream("GetTextContent", {\n pageIndex: this._pageIndex,\n combineTextItems: disableCombineTextItems !== true,\n includeMarkedContent: includeMarkedContent === true\n }, {\n highWaterMark: TEXT_CONTENT_CHUNK_SIZE,\n\n size(textContent) {\n return textContent.items.length;\n }\n\n });\n }\n\n getTextContent(params = {}) {\n if (this._transport._htmlForXfa) {\n return this.getXfa().then(xfa => {\n return _xfa_text.XfaText.textContent(xfa);\n });\n }\n\n const readableStream = this.streamTextContent(params);\n return new Promise(function (resolve, reject) {\n function pump() {\n reader.read().then(function ({\n value,\n done\n }) {\n if (done) {\n resolve(textContent);\n return;\n }\n\n Object.assign(textContent.styles, value.styles);\n textContent.items.push(...value.items);\n pump();\n }, reject);\n }\n\n const reader = readableStream.getReader();\n const textContent = {\n items: [],\n styles: Object.create(null)\n };\n pump();\n });\n }\n\n getStructTree() {\n return this._structTreePromise ||= this._transport.getStructTree(this._pageIndex);\n }\n\n _destroy() {\n this.destroyed = true;\n const waitOn = [];\n\n for (const intentState of this._intentStates.values()) {\n this._abortOperatorList({\n intentState,\n reason: new Error("Page was destroyed."),\n force: true\n });\n\n if (intentState.opListReadCapability) {\n continue;\n }\n\n for (const internalRenderTask of intentState.renderTasks) {\n waitOn.push(internalRenderTask.completed);\n internalRenderTask.cancel();\n }\n }\n\n this.objs.clear();\n\n for (const bitmap of this._bitmaps) {\n bitmap.close();\n }\n\n this._bitmaps.clear();\n\n this._annotationPromises.clear();\n\n this._jsActionsPromise = null;\n this._structTreePromise = null;\n this.pendingCleanup = false;\n return Promise.all(waitOn);\n }\n\n cleanup(resetStats = false) {\n this.pendingCleanup = true;\n return this._tryCleanup(resetStats);\n }\n\n _tryCleanup(resetStats = false) {\n if (!this.pendingCleanup) {\n return false;\n }\n\n for (const {\n renderTasks,\n operatorList\n } of this._intentStates.values()) {\n if (renderTasks.size > 0 || !operatorList.lastChunk) {\n return false;\n }\n }\n\n this._intentStates.clear();\n\n this.objs.clear();\n\n this._annotationPromises.clear();\n\n this._jsActionsPromise = null;\n this._structTreePromise = null;\n\n if (resetStats && this._stats) {\n this._stats = new _display_utils.StatTimer();\n }\n\n for (const bitmap of this._bitmaps) {\n bitmap.close();\n }\n\n this._bitmaps.clear();\n\n this.pendingCleanup = false;\n return true;\n }\n\n _startRenderPage(transparency, cacheKey) {\n const intentState = this._intentStates.get(cacheKey);\n\n if (!intentState) {\n return;\n }\n\n if (this._stats) {\n this._stats.timeEnd("Page Request");\n }\n\n if (intentState.displayReadyCapability) {\n intentState.displayReadyCapability.resolve(transparency);\n }\n }\n\n _renderPageChunk(operatorListChunk, intentState) {\n for (let i = 0, ii = operatorListChunk.length; i < ii; i++) {\n intentState.operatorList.fnArray.push(operatorListChunk.fnArray[i]);\n intentState.operatorList.argsArray.push(operatorListChunk.argsArray[i]);\n }\n\n intentState.operatorList.lastChunk = operatorListChunk.lastChunk;\n\n for (const internalRenderTask of intentState.renderTasks) {\n internalRenderTask.operatorListChanged();\n }\n\n if (operatorListChunk.lastChunk) {\n this._tryCleanup();\n }\n }\n\n _pumpOperatorList({\n renderingIntent,\n cacheKey\n }) {\n const readableStream = this._transport.messageHandler.sendWithStream("GetOperatorList", {\n pageIndex: this._pageIndex,\n intent: renderingIntent,\n cacheKey,\n annotationStorage: renderingIntent & _util.RenderingIntentFlag.ANNOTATIONS_STORAGE ? this._transport.annotationStorage.serializable : null\n });\n\n const reader = readableStream.getReader();\n\n const intentState = this._intentStates.get(cacheKey);\n\n intentState.streamReader = reader;\n\n const pump = () => {\n reader.read().then(({\n value,\n done\n }) => {\n if (done) {\n intentState.streamReader = null;\n return;\n }\n\n if (this._transport.destroyed) {\n return;\n }\n\n this._renderPageChunk(value, intentState);\n\n pump();\n }, reason => {\n intentState.streamReader = null;\n\n if (this._transport.destroyed) {\n return;\n }\n\n if (intentState.operatorList) {\n intentState.operatorList.lastChunk = true;\n\n for (const internalRenderTask of intentState.renderTasks) {\n internalRenderTask.operatorListChanged();\n }\n\n this._tryCleanup();\n }\n\n if (intentState.displayReadyCapability) {\n intentState.displayReadyCapability.reject(reason);\n } else if (intentState.opListReadCapability) {\n intentState.opListReadCapability.reject(reason);\n } else {\n throw reason;\n }\n });\n };\n\n pump();\n }\n\n _abortOperatorList({\n intentState,\n reason,\n force = false\n }) {\n if (!intentState.streamReader) {\n return;\n }\n\n if (!force) {\n if (intentState.renderTasks.size > 0) {\n return;\n }\n\n if (reason instanceof _display_utils.RenderingCancelledException) {\n intentState.streamReaderCancelTimeout = setTimeout(() => {\n this._abortOperatorList({\n intentState,\n reason,\n force: true\n });\n\n intentState.streamReaderCancelTimeout = null;\n }, RENDERING_CANCELLED_TIMEOUT);\n return;\n }\n }\n\n intentState.streamReader.cancel(new _util.AbortException(reason.message)).catch(() => {});\n intentState.streamReader = null;\n\n if (this._transport.destroyed) {\n return;\n }\n\n for (const [curCacheKey, curIntentState] of this._intentStates) {\n if (curIntentState === intentState) {\n this._intentStates.delete(curCacheKey);\n\n break;\n }\n }\n\n this.cleanup();\n }\n\n get stats() {\n return this._stats;\n }\n\n}\n\nexports.PDFPageProxy = PDFPageProxy;\n\nclass LoopbackPort {\n constructor() {\n this._listeners = [];\n this._deferred = Promise.resolve();\n }\n\n postMessage(obj, transfers) {\n const event = {\n data: structuredClone(obj, transfers)\n };\n\n this._deferred.then(() => {\n for (const listener of this._listeners) {\n listener.call(this, event);\n }\n });\n }\n\n addEventListener(name, listener) {\n this._listeners.push(listener);\n }\n\n removeEventListener(name, listener) {\n const i = this._listeners.indexOf(listener);\n\n this._listeners.splice(i, 1);\n }\n\n terminate() {\n this._listeners.length = 0;\n }\n\n}\n\nexports.LoopbackPort = LoopbackPort;\nconst PDFWorkerUtil = {\n isWorkerDisabled: false,\n fallbackWorkerSrc: null,\n fakeWorkerId: 0\n};\nexports.PDFWorkerUtil = PDFWorkerUtil;\n{\n if (_is_node.isNodeJS && "function" === "function") {\n PDFWorkerUtil.isWorkerDisabled = true;\n PDFWorkerUtil.fallbackWorkerSrc = "./pdf.worker.js";\n } else if (typeof document === "object") {\n const pdfjsFilePath = document?.currentScript?.src;\n\n if (pdfjsFilePath) {\n PDFWorkerUtil.fallbackWorkerSrc = pdfjsFilePath.replace(/(\\.(?:min\\.)?js)(\\?.*)?$/i, ".worker$1$2");\n }\n }\n\n PDFWorkerUtil.isSameOrigin = function (baseUrl, otherUrl) {\n let base;\n\n try {\n base = new URL(baseUrl);\n\n if (!base.origin || base.origin === "null") {\n return false;\n }\n } catch (e) {\n return false;\n }\n\n const other = new URL(otherUrl, base);\n return base.origin === other.origin;\n };\n\n PDFWorkerUtil.createCDNWrapper = function (url) {\n const wrapper = `importScripts("${url}");`;\n return URL.createObjectURL(new Blob([wrapper]));\n };\n}\n\nclass PDFWorker {\n static #workerPorts = new WeakMap();\n\n constructor({\n name = null,\n port = null,\n verbosity = (0, _util.getVerbosityLevel)()\n } = {}) {\n if (port && PDFWorker.#workerPorts.has(port)) {\n throw new Error("Cannot use more than one PDFWorker per port.");\n }\n\n this.name = name;\n this.destroyed = false;\n this.verbosity = verbosity;\n this._readyCapability = (0, _util.createPromiseCapability)();\n this._port = null;\n this._webWorker = null;\n this._messageHandler = null;\n\n if (port) {\n PDFWorker.#workerPorts.set(port, this);\n\n this._initializeFromPort(port);\n\n return;\n }\n\n this._initialize();\n }\n\n get promise() {\n return this._readyCapability.promise;\n }\n\n get port() {\n return this._port;\n }\n\n get messageHandler() {\n return this._messageHandler;\n }\n\n _initializeFromPort(port) {\n this._port = port;\n this._messageHandler = new _message_handler.MessageHandler("main", "worker", port);\n\n this._messageHandler.on("ready", function () {});\n\n this._readyCapability.resolve();\n }\n\n _initialize() {\n if (typeof Worker !== "undefined" && !PDFWorkerUtil.isWorkerDisabled && !PDFWorker._mainThreadWorkerMessageHandler) {\n let workerSrc = PDFWorker.workerSrc;\n\n try {\n if (!PDFWorkerUtil.isSameOrigin(window.location.href, workerSrc)) {\n workerSrc = PDFWorkerUtil.createCDNWrapper(new URL(workerSrc, window.location).href);\n }\n\n const worker = new Worker(workerSrc);\n const messageHandler = new _message_handler.MessageHandler("main", "worker", worker);\n\n const terminateEarly = () => {\n worker.removeEventListener("error", onWorkerError);\n messageHandler.destroy();\n worker.terminate();\n\n if (this.destroyed) {\n this._readyCapability.reject(new Error("Worker was destroyed"));\n } else {\n this._setupFakeWorker();\n }\n };\n\n const onWorkerError = () => {\n if (!this._webWorker) {\n terminateEarly();\n }\n };\n\n worker.addEventListener("error", onWorkerError);\n messageHandler.on("test", data => {\n worker.removeEventListener("error", onWorkerError);\n\n if (this.destroyed) {\n terminateEarly();\n return;\n }\n\n if (data) {\n this._messageHandler = messageHandler;\n this._port = worker;\n this._webWorker = worker;\n\n this._readyCapability.resolve();\n\n messageHandler.send("configure", {\n verbosity: this.verbosity\n });\n } else {\n this._setupFakeWorker();\n\n messageHandler.destroy();\n worker.terminate();\n }\n });\n messageHandler.on("ready", data => {\n worker.removeEventListener("error", onWorkerError);\n\n if (this.destroyed) {\n terminateEarly();\n return;\n }\n\n try {\n sendTest();\n } catch (e) {\n this._setupFakeWorker();\n }\n });\n\n const sendTest = () => {\n const testObj = new Uint8Array();\n messageHandler.send("test", testObj, [testObj.buffer]);\n };\n\n sendTest();\n return;\n } catch (e) {\n (0, _util.info)("The worker has been disabled.");\n }\n }\n\n this._setupFakeWorker();\n }\n\n _setupFakeWorker() {\n if (!PDFWorkerUtil.isWorkerDisabled) {\n (0, _util.warn)("Setting up fake worker.");\n PDFWorkerUtil.isWorkerDisabled = true;\n }\n\n PDFWorker._setupFakeWorkerGlobal.then(WorkerMessageHandler => {\n if (this.destroyed) {\n this._readyCapability.reject(new Error("Worker was destroyed"));\n\n return;\n }\n\n const port = new LoopbackPort();\n this._port = port;\n const id = `fake${PDFWorkerUtil.fakeWorkerId++}`;\n const workerHandler = new _message_handler.MessageHandler(id + "_worker", id, port);\n WorkerMessageHandler.setup(workerHandler, port);\n const messageHandler = new _message_handler.MessageHandler(id, id + "_worker", port);\n this._messageHandler = messageHandler;\n\n this._readyCapability.resolve();\n\n messageHandler.send("configure", {\n verbosity: this.verbosity\n });\n }).catch(reason => {\n this._readyCapability.reject(new Error(`Setting up fake worker failed: "${reason.message}".`));\n });\n }\n\n destroy() {\n this.destroyed = true;\n\n if (this._webWorker) {\n this._webWorker.terminate();\n\n this._webWorker = null;\n }\n\n PDFWorker.#workerPorts.delete(this._port);\n this._port = null;\n\n if (this._messageHandler) {\n this._messageHandler.destroy();\n\n this._messageHandler = null;\n }\n }\n\n static fromPort(params) {\n if (!params?.port) {\n throw new Error("PDFWorker.fromPort - invalid method signature.");\n }\n\n if (this.#workerPorts.has(params.port)) {\n return this.#workerPorts.get(params.port);\n }\n\n return new PDFWorker(params);\n }\n\n static get workerSrc() {\n if (_worker_options.GlobalWorkerOptions.workerSrc) {\n return _worker_options.GlobalWorkerOptions.workerSrc;\n }\n\n if (PDFWorkerUtil.fallbackWorkerSrc !== null) {\n if (!_is_node.isNodeJS) {\n (0, _display_utils.deprecated)(\'No "GlobalWorkerOptions.workerSrc" specified.\');\n }\n\n return PDFWorkerUtil.fallbackWorkerSrc;\n }\n\n throw new Error(\'No "GlobalWorkerOptions.workerSrc" specified.\');\n }\n\n static get _mainThreadWorkerMessageHandler() {\n try {\n return globalThis.pdfjsWorker?.WorkerMessageHandler || null;\n } catch (ex) {\n return null;\n }\n }\n\n static get _setupFakeWorkerGlobal() {\n const loader = async () => {\n const mainWorkerMessageHandler = this._mainThreadWorkerMessageHandler;\n\n if (mainWorkerMessageHandler) {\n return mainWorkerMessageHandler;\n }\n\n if (_is_node.isNodeJS && "function" === "function") {\n const worker = eval("require")(this.workerSrc);\n return worker.WorkerMessageHandler;\n }\n\n await (0, _display_utils.loadScript)(this.workerSrc);\n return window.pdfjsWorker.WorkerMessageHandler;\n };\n\n return (0, _util.shadow)(this, "_setupFakeWorkerGlobal", loader());\n }\n\n}\n\nexports.PDFWorker = PDFWorker;\n{\n PDFWorker.getWorkerSrc = function () {\n (0, _display_utils.deprecated)("`PDFWorker.getWorkerSrc()`, please use `PDFWorker.workerSrc` instead.");\n return this.workerSrc;\n };\n}\n\nclass WorkerTransport {\n #docStats = null;\n #pageCache = new Map();\n #pagePromises = new Map();\n #metadataPromise = null;\n\n constructor(messageHandler, loadingTask, networkStream, params) {\n this.messageHandler = messageHandler;\n this.loadingTask = loadingTask;\n this.commonObjs = new PDFObjects();\n this.fontLoader = new _font_loader.FontLoader({\n docId: loadingTask.docId,\n onUnsupportedFeature: this._onUnsupportedFeature.bind(this),\n ownerDocument: params.ownerDocument,\n styleElement: params.styleElement\n });\n this._params = params;\n\n if (!params.useWorkerFetch) {\n this.CMapReaderFactory = new params.CMapReaderFactory({\n baseUrl: params.cMapUrl,\n isCompressed: params.cMapPacked\n });\n this.StandardFontDataFactory = new params.StandardFontDataFactory({\n baseUrl: params.standardFontDataUrl\n });\n }\n\n this.destroyed = false;\n this.destroyCapability = null;\n this._passwordCapability = null;\n this._networkStream = networkStream;\n this._fullReader = null;\n this._lastProgress = null;\n this.downloadInfoCapability = (0, _util.createPromiseCapability)();\n this.setupMessageHandler();\n }\n\n get annotationStorage() {\n return (0, _util.shadow)(this, "annotationStorage", new _annotation_storage.AnnotationStorage());\n }\n\n get stats() {\n return this.#docStats;\n }\n\n getRenderingIntent(intent, annotationMode = _util.AnnotationMode.ENABLE, isOpList = false) {\n let renderingIntent = _util.RenderingIntentFlag.DISPLAY;\n let annotationHash = "";\n\n switch (intent) {\n case "any":\n renderingIntent = _util.RenderingIntentFlag.ANY;\n break;\n\n case "display":\n break;\n\n case "print":\n renderingIntent = _util.RenderingIntentFlag.PRINT;\n break;\n\n default:\n (0, _util.warn)(`getRenderingIntent - invalid intent: ${intent}`);\n }\n\n switch (annotationMode) {\n case _util.AnnotationMode.DISABLE:\n renderingIntent += _util.RenderingIntentFlag.ANNOTATIONS_DISABLE;\n break;\n\n case _util.AnnotationMode.ENABLE:\n break;\n\n case _util.AnnotationMode.ENABLE_FORMS:\n renderingIntent += _util.RenderingIntentFlag.ANNOTATIONS_FORMS;\n break;\n\n case _util.AnnotationMode.ENABLE_STORAGE:\n renderingIntent += _util.RenderingIntentFlag.ANNOTATIONS_STORAGE;\n annotationHash = this.annotationStorage.hash;\n break;\n\n default:\n (0, _util.warn)(`getRenderingIntent - invalid annotationMode: ${annotationMode}`);\n }\n\n if (isOpList) {\n renderingIntent += _util.RenderingIntentFlag.OPLIST;\n }\n\n return {\n renderingIntent,\n cacheKey: `${renderingIntent}_${annotationHash}`\n };\n }\n\n destroy() {\n if (this.destroyCapability) {\n return this.destroyCapability.promise;\n }\n\n this.destroyed = true;\n this.destroyCapability = (0, _util.createPromiseCapability)();\n\n if (this._passwordCapability) {\n this._passwordCapability.reject(new Error("Worker was destroyed during onPassword callback"));\n }\n\n const waitOn = [];\n\n for (const page of this.#pageCache.values()) {\n waitOn.push(page._destroy());\n }\n\n this.#pageCache.clear();\n this.#pagePromises.clear();\n\n if (this.hasOwnProperty("annotationStorage")) {\n this.annotationStorage.resetModified();\n }\n\n const terminated = this.messageHandler.sendWithPromise("Terminate", null);\n waitOn.push(terminated);\n Promise.all(waitOn).then(() => {\n this.commonObjs.clear();\n this.fontLoader.clear();\n this.#metadataPromise = null;\n this._getFieldObjectsPromise = null;\n this._hasJSActionsPromise = null;\n\n if (this._networkStream) {\n this._networkStream.cancelAllRequests(new _util.AbortException("Worker was terminated."));\n }\n\n if (this.messageHandler) {\n this.messageHandler.destroy();\n this.messageHandler = null;\n }\n\n this.destroyCapability.resolve();\n }, this.destroyCapability.reject);\n return this.destroyCapability.promise;\n }\n\n setupMessageHandler() {\n const {\n messageHandler,\n loadingTask\n } = this;\n messageHandler.on("GetReader", (data, sink) => {\n (0, _util.assert)(this._networkStream, "GetReader - no `IPDFStream` instance available.");\n this._fullReader = this._networkStream.getFullReader();\n\n this._fullReader.onProgress = evt => {\n this._lastProgress = {\n loaded: evt.loaded,\n total: evt.total\n };\n };\n\n sink.onPull = () => {\n this._fullReader.read().then(function ({\n value,\n done\n }) {\n if (done) {\n sink.close();\n return;\n }\n\n (0, _util.assert)((0, _util.isArrayBuffer)(value), "GetReader - expected an ArrayBuffer.");\n sink.enqueue(new Uint8Array(value), 1, [value]);\n }).catch(reason => {\n sink.error(reason);\n });\n };\n\n sink.onCancel = reason => {\n this._fullReader.cancel(reason);\n\n sink.ready.catch(readyReason => {\n if (this.destroyed) {\n return;\n }\n\n throw readyReason;\n });\n };\n });\n messageHandler.on("ReaderHeadersReady", data => {\n const headersCapability = (0, _util.createPromiseCapability)();\n const fullReader = this._fullReader;\n fullReader.headersReady.then(() => {\n if (!fullReader.isStreamingSupported || !fullReader.isRangeSupported) {\n if (this._lastProgress) {\n loadingTask.onProgress?.(this._lastProgress);\n }\n\n fullReader.onProgress = evt => {\n loadingTask.onProgress?.({\n loaded: evt.loaded,\n total: evt.total\n });\n };\n }\n\n headersCapability.resolve({\n isStreamingSupported: fullReader.isStreamingSupported,\n isRangeSupported: fullReader.isRangeSupported,\n contentLength: fullReader.contentLength\n });\n }, headersCapability.reject);\n return headersCapability.promise;\n });\n messageHandler.on("GetRangeReader", (data, sink) => {\n (0, _util.assert)(this._networkStream, "GetRangeReader - no `IPDFStream` instance available.");\n\n const rangeReader = this._networkStream.getRangeReader(data.begin, data.end);\n\n if (!rangeReader) {\n sink.close();\n return;\n }\n\n sink.onPull = () => {\n rangeReader.read().then(function ({\n value,\n done\n }) {\n if (done) {\n sink.close();\n return;\n }\n\n (0, _util.assert)((0, _util.isArrayBuffer)(value), "GetRangeReader - expected an ArrayBuffer.");\n sink.enqueue(new Uint8Array(value), 1, [value]);\n }).catch(reason => {\n sink.error(reason);\n });\n };\n\n sink.onCancel = reason => {\n rangeReader.cancel(reason);\n sink.ready.catch(readyReason => {\n if (this.destroyed) {\n return;\n }\n\n throw readyReason;\n });\n };\n });\n messageHandler.on("GetDoc", ({\n pdfInfo\n }) => {\n this._numPages = pdfInfo.numPages;\n this._htmlForXfa = pdfInfo.htmlForXfa;\n delete pdfInfo.htmlForXfa;\n\n loadingTask._capability.resolve(new PDFDocumentProxy(pdfInfo, this));\n });\n messageHandler.on("DocException", function (ex) {\n let reason;\n\n switch (ex.name) {\n case "PasswordException":\n reason = new _util.PasswordException(ex.message, ex.code);\n break;\n\n case "InvalidPDFException":\n reason = new _util.InvalidPDFException(ex.message);\n break;\n\n case "MissingPDFException":\n reason = new _util.MissingPDFException(ex.message);\n break;\n\n case "UnexpectedResponseException":\n reason = new _util.UnexpectedResponseException(ex.message, ex.status);\n break;\n\n case "UnknownErrorException":\n reason = new _util.UnknownErrorException(ex.message, ex.details);\n break;\n\n default:\n (0, _util.unreachable)("DocException - expected a valid Error.");\n }\n\n loadingTask._capability.reject(reason);\n });\n messageHandler.on("PasswordRequest", exception => {\n this._passwordCapability = (0, _util.createPromiseCapability)();\n\n if (loadingTask.onPassword) {\n const updatePassword = password => {\n if (password instanceof Error) {\n this._passwordCapability.reject(password);\n } else {\n this._passwordCapability.resolve({\n password\n });\n }\n };\n\n try {\n loadingTask.onPassword(updatePassword, exception.code);\n } catch (ex) {\n this._passwordCapability.reject(ex);\n }\n } else {\n this._passwordCapability.reject(new _util.PasswordException(exception.message, exception.code));\n }\n\n return this._passwordCapability.promise;\n });\n messageHandler.on("DataLoaded", data => {\n loadingTask.onProgress?.({\n loaded: data.length,\n total: data.length\n });\n this.downloadInfoCapability.resolve(data);\n });\n messageHandler.on("StartRenderPage", data => {\n if (this.destroyed) {\n return;\n }\n\n const page = this.#pageCache.get(data.pageIndex);\n\n page._startRenderPage(data.transparency, data.cacheKey);\n });\n messageHandler.on("commonobj", ([id, type, exportedData]) => {\n if (this.destroyed) {\n return;\n }\n\n if (this.commonObjs.has(id)) {\n return;\n }\n\n switch (type) {\n case "Font":\n const params = this._params;\n\n if ("error" in exportedData) {\n const exportedError = exportedData.error;\n (0, _util.warn)(`Error during font loading: ${exportedError}`);\n this.commonObjs.resolve(id, exportedError);\n break;\n }\n\n let fontRegistry = null;\n\n if (params.pdfBug && globalThis.FontInspector?.enabled) {\n fontRegistry = {\n registerFont(font, url) {\n globalThis.FontInspector.fontAdded(font, url);\n }\n\n };\n }\n\n const font = new _font_loader.FontFaceObject(exportedData, {\n isEvalSupported: params.isEvalSupported,\n disableFontFace: params.disableFontFace,\n ignoreErrors: params.ignoreErrors,\n onUnsupportedFeature: this._onUnsupportedFeature.bind(this),\n fontRegistry\n });\n this.fontLoader.bind(font).catch(reason => {\n return messageHandler.sendWithPromise("FontFallback", {\n id\n });\n }).finally(() => {\n if (!params.fontExtraProperties && font.data) {\n font.data = null;\n }\n\n this.commonObjs.resolve(id, font);\n });\n break;\n\n case "FontPath":\n case "Image":\n this.commonObjs.resolve(id, exportedData);\n break;\n\n default:\n throw new Error(`Got unknown common object type ${type}`);\n }\n });\n messageHandler.on("obj", ([id, pageIndex, type, imageData]) => {\n if (this.destroyed) {\n return;\n }\n\n const pageProxy = this.#pageCache.get(pageIndex);\n\n if (pageProxy.objs.has(id)) {\n return;\n }\n\n switch (type) {\n case "Image":\n pageProxy.objs.resolve(id, imageData);\n const MAX_IMAGE_SIZE_TO_STORE = 8000000;\n\n if (imageData) {\n let length;\n\n if (imageData.bitmap) {\n const {\n bitmap,\n width,\n height\n } = imageData;\n length = width * height * 4;\n\n pageProxy._bitmaps.add(bitmap);\n } else {\n length = imageData.data?.length || 0;\n }\n\n if (length > MAX_IMAGE_SIZE_TO_STORE) {\n pageProxy.cleanupAfterRender = true;\n }\n }\n\n break;\n\n case "Pattern":\n pageProxy.objs.resolve(id, imageData);\n break;\n\n default:\n throw new Error(`Got unknown object type ${type}`);\n }\n });\n messageHandler.on("DocProgress", data => {\n if (this.destroyed) {\n return;\n }\n\n loadingTask.onProgress?.({\n loaded: data.loaded,\n total: data.total\n });\n });\n messageHandler.on("DocStats", data => {\n if (this.destroyed) {\n return;\n }\n\n this.#docStats = Object.freeze({\n streamTypes: Object.freeze(data.streamTypes),\n fontTypes: Object.freeze(data.fontTypes)\n });\n });\n messageHandler.on("UnsupportedFeature", this._onUnsupportedFeature.bind(this));\n messageHandler.on("FetchBuiltInCMap", data => {\n if (this.destroyed) {\n return Promise.reject(new Error("Worker was destroyed."));\n }\n\n if (!this.CMapReaderFactory) {\n return Promise.reject(new Error("CMapReaderFactory not initialized, see the `useWorkerFetch` parameter."));\n }\n\n return this.CMapReaderFactory.fetch(data);\n });\n messageHandler.on("FetchStandardFontData", data => {\n if (this.destroyed) {\n return Promise.reject(new Error("Worker was destroyed."));\n }\n\n if (!this.StandardFontDataFactory) {\n return Promise.reject(new Error("StandardFontDataFactory not initialized, see the `useWorkerFetch` parameter."));\n }\n\n return this.StandardFontDataFactory.fetch(data);\n });\n }\n\n _onUnsupportedFeature({\n featureId\n }) {\n if (this.destroyed) {\n return;\n }\n\n this.loadingTask.onUnsupportedFeature?.(featureId);\n }\n\n getData() {\n return this.messageHandler.sendWithPromise("GetData", null);\n }\n\n getPage(pageNumber) {\n if (!Number.isInteger(pageNumber) || pageNumber <= 0 || pageNumber > this._numPages) {\n return Promise.reject(new Error("Invalid page request."));\n }\n\n const pageIndex = pageNumber - 1,\n cachedPromise = this.#pagePromises.get(pageIndex);\n\n if (cachedPromise) {\n return cachedPromise;\n }\n\n const promise = this.messageHandler.sendWithPromise("GetPage", {\n pageIndex\n }).then(pageInfo => {\n if (this.destroyed) {\n throw new Error("Transport destroyed");\n }\n\n const page = new PDFPageProxy(pageIndex, pageInfo, this, this._params.ownerDocument, this._params.pdfBug);\n this.#pageCache.set(pageIndex, page);\n return page;\n });\n this.#pagePromises.set(pageIndex, promise);\n return promise;\n }\n\n getPageIndex(ref) {\n if (typeof ref !== "object" || ref === null || !Number.isInteger(ref.num) || ref.num < 0 || !Number.isInteger(ref.gen) || ref.gen < 0) {\n return Promise.reject(new Error("Invalid pageIndex request."));\n }\n\n return this.messageHandler.sendWithPromise("GetPageIndex", {\n num: ref.num,\n gen: ref.gen\n });\n }\n\n getAnnotations(pageIndex, intent) {\n return this.messageHandler.sendWithPromise("GetAnnotations", {\n pageIndex,\n intent\n });\n }\n\n saveDocument() {\n return this.messageHandler.sendWithPromise("SaveDocument", {\n isPureXfa: !!this._htmlForXfa,\n numPages: this._numPages,\n annotationStorage: this.annotationStorage.serializable,\n filename: this._fullReader?.filename ?? null\n }).finally(() => {\n this.annotationStorage.resetModified();\n });\n }\n\n getFieldObjects() {\n return this._getFieldObjectsPromise ||= this.messageHandler.sendWithPromise("GetFieldObjects", null);\n }\n\n hasJSActions() {\n return this._hasJSActionsPromise ||= this.messageHandler.sendWithPromise("HasJSActions", null);\n }\n\n getCalculationOrderIds() {\n return this.messageHandler.sendWithPromise("GetCalculationOrderIds", null);\n }\n\n getDestinations() {\n return this.messageHandler.sendWithPromise("GetDestinations", null);\n }\n\n getDestination(id) {\n if (typeof id !== "string") {\n return Promise.reject(new Error("Invalid destination request."));\n }\n\n return this.messageHandler.sendWithPromise("GetDestination", {\n id\n });\n }\n\n getPageLabels() {\n return this.messageHandler.sendWithPromise("GetPageLabels", null);\n }\n\n getPageLayout() {\n return this.messageHandler.sendWithPromise("GetPageLayout", null);\n }\n\n getPageMode() {\n return this.messageHandler.sendWithPromise("GetPageMode", null);\n }\n\n getViewerPreferences() {\n return this.messageHandler.sendWithPromise("GetViewerPreferences", null);\n }\n\n getOpenAction() {\n return this.messageHandler.sendWithPromise("GetOpenAction", null);\n }\n\n getAttachments() {\n return this.messageHandler.sendWithPromise("GetAttachments", null);\n }\n\n getJavaScript() {\n return this.messageHandler.sendWithPromise("GetJavaScript", null);\n }\n\n getDocJSActions() {\n return this.messageHandler.sendWithPromise("GetDocJSActions", null);\n }\n\n getPageJSActions(pageIndex) {\n return this.messageHandler.sendWithPromise("GetPageJSActions", {\n pageIndex\n });\n }\n\n getStructTree(pageIndex) {\n return this.messageHandler.sendWithPromise("GetStructTree", {\n pageIndex\n });\n }\n\n getOutline() {\n return this.messageHandler.sendWithPromise("GetOutline", null);\n }\n\n getOptionalContentConfig() {\n return this.messageHandler.sendWithPromise("GetOptionalContentConfig", null).then(results => {\n return new _optional_content_config.OptionalContentConfig(results);\n });\n }\n\n getPermissions() {\n return this.messageHandler.sendWithPromise("GetPermissions", null);\n }\n\n getMetadata() {\n return this.#metadataPromise ||= this.messageHandler.sendWithPromise("GetMetadata", null).then(results => {\n return {\n info: results[0],\n metadata: results[1] ? new _metadata.Metadata(results[1]) : null,\n contentDispositionFilename: this._fullReader?.filename ?? null,\n contentLength: this._fullReader?.contentLength ?? null\n };\n });\n }\n\n getMarkInfo() {\n return this.messageHandler.sendWithPromise("GetMarkInfo", null);\n }\n\n async startCleanup(keepLoadedFonts = false) {\n await this.messageHandler.sendWithPromise("Cleanup", null);\n\n if (this.destroyed) {\n return;\n }\n\n for (const page of this.#pageCache.values()) {\n const cleanupSuccessful = page.cleanup();\n\n if (!cleanupSuccessful) {\n throw new Error(`startCleanup: Page ${page.pageNumber} is currently rendering.`);\n }\n }\n\n this.commonObjs.clear();\n\n if (!keepLoadedFonts) {\n this.fontLoader.clear();\n }\n\n this.#metadataPromise = null;\n this._getFieldObjectsPromise = null;\n this._hasJSActionsPromise = null;\n }\n\n get loadingParams() {\n const params = this._params;\n return (0, _util.shadow)(this, "loadingParams", {\n disableAutoFetch: params.disableAutoFetch,\n enableXfa: params.enableXfa\n });\n }\n\n}\n\nclass PDFObjects {\n #objs = Object.create(null);\n\n #ensureObj(objId) {\n const obj = this.#objs[objId];\n\n if (obj) {\n return obj;\n }\n\n return this.#objs[objId] = {\n capability: (0, _util.createPromiseCapability)(),\n data: null\n };\n }\n\n get(objId, callback = null) {\n if (callback) {\n const obj = this.#ensureObj(objId);\n obj.capability.promise.then(() => callback(obj.data));\n return null;\n }\n\n const obj = this.#objs[objId];\n\n if (!obj?.capability.settled) {\n throw new Error(`Requesting object that isn\'t resolved yet ${objId}.`);\n }\n\n return obj.data;\n }\n\n has(objId) {\n const obj = this.#objs[objId];\n return obj?.capability.settled || false;\n }\n\n resolve(objId, data = null) {\n const obj = this.#ensureObj(objId);\n obj.data = data;\n obj.capability.resolve();\n }\n\n clear() {\n this.#objs = Object.create(null);\n }\n\n}\n\nclass RenderTask {\n constructor(internalRenderTask) {\n this._internalRenderTask = internalRenderTask;\n this.onContinue = null;\n }\n\n get promise() {\n return this._internalRenderTask.capability.promise;\n }\n\n cancel() {\n this._internalRenderTask.cancel();\n }\n\n}\n\nexports.RenderTask = RenderTask;\n\nclass InternalRenderTask {\n static #canvasInUse = new WeakSet();\n\n constructor({\n callback,\n params,\n objs,\n commonObjs,\n annotationCanvasMap,\n operatorList,\n pageIndex,\n canvasFactory,\n useRequestAnimationFrame = false,\n pdfBug = false,\n pageColors = null\n }) {\n this.callback = callback;\n this.params = params;\n this.objs = objs;\n this.commonObjs = commonObjs;\n this.annotationCanvasMap = annotationCanvasMap;\n this.operatorListIdx = null;\n this.operatorList = operatorList;\n this._pageIndex = pageIndex;\n this.canvasFactory = canvasFactory;\n this._pdfBug = pdfBug;\n this.pageColors = pageColors;\n this.running = false;\n this.graphicsReadyCallback = null;\n this.graphicsReady = false;\n this._useRequestAnimationFrame = useRequestAnimationFrame === true && typeof window !== "undefined";\n this.cancelled = false;\n this.capability = (0, _util.createPromiseCapability)();\n this.task = new RenderTask(this);\n this._cancelBound = this.cancel.bind(this);\n this._continueBound = this._continue.bind(this);\n this._scheduleNextBound = this._scheduleNext.bind(this);\n this._nextBound = this._next.bind(this);\n this._canvas = params.canvasContext.canvas;\n }\n\n get completed() {\n return this.capability.promise.catch(function () {});\n }\n\n initializeGraphics({\n transparency = false,\n optionalContentConfig\n }) {\n if (this.cancelled) {\n return;\n }\n\n if (this._canvas) {\n if (InternalRenderTask.#canvasInUse.has(this._canvas)) {\n throw new Error("Cannot use the same canvas during multiple render() operations. " + "Use different canvas or ensure previous operations were " + "cancelled or completed.");\n }\n\n InternalRenderTask.#canvasInUse.add(this._canvas);\n }\n\n if (this._pdfBug && globalThis.StepperManager?.enabled) {\n this.stepper = globalThis.StepperManager.create(this._pageIndex);\n this.stepper.init(this.operatorList);\n this.stepper.nextBreakPoint = this.stepper.getNextBreakPoint();\n }\n\n const {\n canvasContext,\n viewport,\n transform,\n imageLayer,\n background\n } = this.params;\n this.gfx = new _canvas.CanvasGraphics(canvasContext, this.commonObjs, this.objs, this.canvasFactory, imageLayer, optionalContentConfig, this.annotationCanvasMap, this.pageColors);\n this.gfx.beginDrawing({\n transform,\n viewport,\n transparency,\n background\n });\n this.operatorListIdx = 0;\n this.graphicsReady = true;\n\n if (this.graphicsReadyCallback) {\n this.graphicsReadyCallback();\n }\n }\n\n cancel(error = null) {\n this.running = false;\n this.cancelled = true;\n\n if (this.gfx) {\n this.gfx.endDrawing();\n }\n\n if (this._canvas) {\n InternalRenderTask.#canvasInUse.delete(this._canvas);\n }\n\n this.callback(error || new _display_utils.RenderingCancelledException(`Rendering cancelled, page ${this._pageIndex + 1}`, "canvas"));\n }\n\n operatorListChanged() {\n if (!this.graphicsReady) {\n if (!this.graphicsReadyCallback) {\n this.graphicsReadyCallback = this._continueBound;\n }\n\n return;\n }\n\n if (this.stepper) {\n this.stepper.updateOperatorList(this.operatorList);\n }\n\n if (this.running) {\n return;\n }\n\n this._continue();\n }\n\n _continue() {\n this.running = true;\n\n if (this.cancelled) {\n return;\n }\n\n if (this.task.onContinue) {\n this.task.onContinue(this._scheduleNextBound);\n } else {\n this._scheduleNext();\n }\n }\n\n _scheduleNext() {\n if (this._useRequestAnimationFrame) {\n window.requestAnimationFrame(() => {\n this._nextBound().catch(this._cancelBound);\n });\n } else {\n Promise.resolve().then(this._nextBound).catch(this._cancelBound);\n }\n }\n\n async _next() {\n if (this.cancelled) {\n return;\n }\n\n this.operatorListIdx = this.gfx.executeOperatorList(this.operatorList, this.operatorListIdx, this._continueBound, this.stepper);\n\n if (this.operatorListIdx === this.operatorList.argsArray.length) {\n this.running = false;\n\n if (this.operatorList.lastChunk) {\n this.gfx.endDrawing();\n\n if (this._canvas) {\n InternalRenderTask.#canvasInUse.delete(this._canvas);\n }\n\n this.callback();\n }\n }\n }\n\n}\n\nconst version = \'2.14.305\';\nexports.version = version;\nconst build = \'eaaa8b4ad\';\nexports.build = build;\n\n/***/ }),\n/* 5 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.StatTimer = exports.RenderingCancelledException = exports.PixelsPerInch = exports.PageViewport = exports.PDFDateString = exports.DOMStandardFontDataFactory = exports.DOMSVGFactory = exports.DOMCanvasFactory = exports.DOMCMapReaderFactory = void 0;\nexports.deprecated = deprecated;\nexports.getFilenameFromUrl = getFilenameFromUrl;\nexports.getPdfFilenameFromUrl = getPdfFilenameFromUrl;\nexports.getXfaPageViewport = getXfaPageViewport;\nexports.isDataScheme = isDataScheme;\nexports.isPdfFile = isPdfFile;\nexports.isValidFetchUrl = isValidFetchUrl;\nexports.loadScript = loadScript;\n\nvar _base_factory = __w_pdfjs_require__(6);\n\nvar _util = __w_pdfjs_require__(1);\n\nconst SVG_NS = "http://www.w3.org/2000/svg";\n\nclass PixelsPerInch {\n static CSS = 96.0;\n static PDF = 72.0;\n static PDF_TO_CSS_UNITS = this.CSS / this.PDF;\n}\n\nexports.PixelsPerInch = PixelsPerInch;\n\nclass DOMCanvasFactory extends _base_factory.BaseCanvasFactory {\n constructor({\n ownerDocument = globalThis.document\n } = {}) {\n super();\n this._document = ownerDocument;\n }\n\n _createCanvas(width, height) {\n const canvas = this._document.createElement("canvas");\n\n canvas.width = width;\n canvas.height = height;\n return canvas;\n }\n\n}\n\nexports.DOMCanvasFactory = DOMCanvasFactory;\n\nasync function fetchData(url, asTypedArray = false) {\n if (isValidFetchUrl(url, document.baseURI)) {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(response.statusText);\n }\n\n return asTypedArray ? new Uint8Array(await response.arrayBuffer()) : (0, _util.stringToBytes)(await response.text());\n }\n\n return new Promise((resolve, reject) => {\n const request = new XMLHttpRequest();\n request.open("GET", url, true);\n\n if (asTypedArray) {\n request.responseType = "arraybuffer";\n }\n\n request.onreadystatechange = () => {\n if (request.readyState !== XMLHttpRequest.DONE) {\n return;\n }\n\n if (request.status === 200 || request.status === 0) {\n let data;\n\n if (asTypedArray && request.response) {\n data = new Uint8Array(request.response);\n } else if (!asTypedArray && request.responseText) {\n data = (0, _util.stringToBytes)(request.responseText);\n }\n\n if (data) {\n resolve(data);\n return;\n }\n }\n\n reject(new Error(request.statusText));\n };\n\n request.send(null);\n });\n}\n\nclass DOMCMapReaderFactory extends _base_factory.BaseCMapReaderFactory {\n _fetchData(url, compressionType) {\n return fetchData(url, this.isCompressed).then(data => {\n return {\n cMapData: data,\n compressionType\n };\n });\n }\n\n}\n\nexports.DOMCMapReaderFactory = DOMCMapReaderFactory;\n\nclass DOMStandardFontDataFactory extends _base_factory.BaseStandardFontDataFactory {\n _fetchData(url) {\n return fetchData(url, true);\n }\n\n}\n\nexports.DOMStandardFontDataFactory = DOMStandardFontDataFactory;\n\nclass DOMSVGFactory extends _base_factory.BaseSVGFactory {\n _createSVG(type) {\n return document.createElementNS(SVG_NS, type);\n }\n\n}\n\nexports.DOMSVGFactory = DOMSVGFactory;\n\nclass PageViewport {\n constructor({\n viewBox,\n scale,\n rotation,\n offsetX = 0,\n offsetY = 0,\n dontFlip = false\n }) {\n this.viewBox = viewBox;\n this.scale = scale;\n this.rotation = rotation;\n this.offsetX = offsetX;\n this.offsetY = offsetY;\n const centerX = (viewBox[2] + viewBox[0]) / 2;\n const centerY = (viewBox[3] + viewBox[1]) / 2;\n let rotateA, rotateB, rotateC, rotateD;\n rotation %= 360;\n\n if (rotation < 0) {\n rotation += 360;\n }\n\n switch (rotation) {\n case 180:\n rotateA = -1;\n rotateB = 0;\n rotateC = 0;\n rotateD = 1;\n break;\n\n case 90:\n rotateA = 0;\n rotateB = 1;\n rotateC = 1;\n rotateD = 0;\n break;\n\n case 270:\n rotateA = 0;\n rotateB = -1;\n rotateC = -1;\n rotateD = 0;\n break;\n\n case 0:\n rotateA = 1;\n rotateB = 0;\n rotateC = 0;\n rotateD = -1;\n break;\n\n default:\n throw new Error("PageViewport: Invalid rotation, must be a multiple of 90 degrees.");\n }\n\n if (dontFlip) {\n rotateC = -rotateC;\n rotateD = -rotateD;\n }\n\n let offsetCanvasX, offsetCanvasY;\n let width, height;\n\n if (rotateA === 0) {\n offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX;\n offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY;\n width = Math.abs(viewBox[3] - viewBox[1]) * scale;\n height = Math.abs(viewBox[2] - viewBox[0]) * scale;\n } else {\n offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX;\n offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY;\n width = Math.abs(viewBox[2] - viewBox[0]) * scale;\n height = Math.abs(viewBox[3] - viewBox[1]) * scale;\n }\n\n this.transform = [rotateA * scale, rotateB * scale, rotateC * scale, rotateD * scale, offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY, offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY];\n this.width = width;\n this.height = height;\n }\n\n clone({\n scale = this.scale,\n rotation = this.rotation,\n offsetX = this.offsetX,\n offsetY = this.offsetY,\n dontFlip = false\n } = {}) {\n return new PageViewport({\n viewBox: this.viewBox.slice(),\n scale,\n rotation,\n offsetX,\n offsetY,\n dontFlip\n });\n }\n\n convertToViewportPoint(x, y) {\n return _util.Util.applyTransform([x, y], this.transform);\n }\n\n convertToViewportRectangle(rect) {\n const topLeft = _util.Util.applyTransform([rect[0], rect[1]], this.transform);\n\n const bottomRight = _util.Util.applyTransform([rect[2], rect[3]], this.transform);\n\n return [topLeft[0], topLeft[1], bottomRight[0], bottomRight[1]];\n }\n\n convertToPdfPoint(x, y) {\n return _util.Util.applyInverseTransform([x, y], this.transform);\n }\n\n}\n\nexports.PageViewport = PageViewport;\n\nclass RenderingCancelledException extends _util.BaseException {\n constructor(msg, type) {\n super(msg, "RenderingCancelledException");\n this.type = type;\n }\n\n}\n\nexports.RenderingCancelledException = RenderingCancelledException;\n\nfunction isDataScheme(url) {\n const ii = url.length;\n let i = 0;\n\n while (i < ii && url[i].trim() === "") {\n i++;\n }\n\n return url.substring(i, i + 5).toLowerCase() === "data:";\n}\n\nfunction isPdfFile(filename) {\n return typeof filename === "string" && /\\.pdf$/i.test(filename);\n}\n\nfunction getFilenameFromUrl(url) {\n const anchor = url.indexOf("#");\n const query = url.indexOf("?");\n const end = Math.min(anchor > 0 ? anchor : url.length, query > 0 ? query : url.length);\n return url.substring(url.lastIndexOf("/", end) + 1, end);\n}\n\nfunction getPdfFilenameFromUrl(url, defaultFilename = "document.pdf") {\n if (typeof url !== "string") {\n return defaultFilename;\n }\n\n if (isDataScheme(url)) {\n (0, _util.warn)(\'getPdfFilenameFromUrl: ignore "data:"-URL for performance reasons.\');\n return defaultFilename;\n }\n\n const reURI = /^(?:(?:[^:]+:)?\\/\\/[^/]+)?([^?#]*)(\\?[^#]*)?(#.*)?$/;\n const reFilename = /[^/?#=]+\\.pdf\\b(?!.*\\.pdf\\b)/i;\n const splitURI = reURI.exec(url);\n let suggestedFilename = reFilename.exec(splitURI[1]) || reFilename.exec(splitURI[2]) || reFilename.exec(splitURI[3]);\n\n if (suggestedFilename) {\n suggestedFilename = suggestedFilename[0];\n\n if (suggestedFilename.includes("%")) {\n try {\n suggestedFilename = reFilename.exec(decodeURIComponent(suggestedFilename))[0];\n } catch (ex) {}\n }\n }\n\n return suggestedFilename || defaultFilename;\n}\n\nclass StatTimer {\n constructor() {\n this.started = Object.create(null);\n this.times = [];\n }\n\n time(name) {\n if (name in this.started) {\n (0, _util.warn)(`Timer is already running for ${name}`);\n }\n\n this.started[name] = Date.now();\n }\n\n timeEnd(name) {\n if (!(name in this.started)) {\n (0, _util.warn)(`Timer has not been started for ${name}`);\n }\n\n this.times.push({\n name,\n start: this.started[name],\n end: Date.now()\n });\n delete this.started[name];\n }\n\n toString() {\n const outBuf = [];\n let longest = 0;\n\n for (const time of this.times) {\n const name = time.name;\n\n if (name.length > longest) {\n longest = name.length;\n }\n }\n\n for (const time of this.times) {\n const duration = time.end - time.start;\n outBuf.push(`${time.name.padEnd(longest)} ${duration}ms\\n`);\n }\n\n return outBuf.join("");\n }\n\n}\n\nexports.StatTimer = StatTimer;\n\nfunction isValidFetchUrl(url, baseUrl) {\n try {\n const {\n protocol\n } = baseUrl ? new URL(url, baseUrl) : new URL(url);\n return protocol === "http:" || protocol === "https:";\n } catch (ex) {\n return false;\n }\n}\n\nfunction loadScript(src, removeScriptElement = false) {\n return new Promise((resolve, reject) => {\n const script = document.createElement("script");\n script.src = src;\n\n script.onload = function (evt) {\n if (removeScriptElement) {\n script.remove();\n }\n\n resolve(evt);\n };\n\n script.onerror = function () {\n reject(new Error(`Cannot load script at: ${script.src}`));\n };\n\n (document.head || document.documentElement).appendChild(script);\n });\n}\n\nfunction deprecated(details) {\n console.log("Deprecated API usage: " + details);\n}\n\nlet pdfDateStringRegex;\n\nclass PDFDateString {\n static toDateObject(input) {\n if (!input || typeof input !== "string") {\n return null;\n }\n\n if (!pdfDateStringRegex) {\n pdfDateStringRegex = new RegExp("^D:" + "(\\\\d{4})" + "(\\\\d{2})?" + "(\\\\d{2})?" + "(\\\\d{2})?" + "(\\\\d{2})?" + "(\\\\d{2})?" + "([Z|+|-])?" + "(\\\\d{2})?" + "\'?" + "(\\\\d{2})?" + "\'?");\n }\n\n const matches = pdfDateStringRegex.exec(input);\n\n if (!matches) {\n return null;\n }\n\n const year = parseInt(matches[1], 10);\n let month = parseInt(matches[2], 10);\n month = month >= 1 && month <= 12 ? month - 1 : 0;\n let day = parseInt(matches[3], 10);\n day = day >= 1 && day <= 31 ? day : 1;\n let hour = parseInt(matches[4], 10);\n hour = hour >= 0 && hour <= 23 ? hour : 0;\n let minute = parseInt(matches[5], 10);\n minute = minute >= 0 && minute <= 59 ? minute : 0;\n let second = parseInt(matches[6], 10);\n second = second >= 0 && second <= 59 ? second : 0;\n const universalTimeRelation = matches[7] || "Z";\n let offsetHour = parseInt(matches[8], 10);\n offsetHour = offsetHour >= 0 && offsetHour <= 23 ? offsetHour : 0;\n let offsetMinute = parseInt(matches[9], 10) || 0;\n offsetMinute = offsetMinute >= 0 && offsetMinute <= 59 ? offsetMinute : 0;\n\n if (universalTimeRelation === "-") {\n hour += offsetHour;\n minute += offsetMinute;\n } else if (universalTimeRelation === "+") {\n hour -= offsetHour;\n minute -= offsetMinute;\n }\n\n return new Date(Date.UTC(year, month, day, hour, minute, second));\n }\n\n}\n\nexports.PDFDateString = PDFDateString;\n\nfunction getXfaPageViewport(xfaPage, {\n scale = 1,\n rotation = 0\n}) {\n const {\n width,\n height\n } = xfaPage.attributes.style;\n const viewBox = [0, 0, parseInt(width), parseInt(height)];\n return new PageViewport({\n viewBox,\n scale,\n rotation\n });\n}\n\n/***/ }),\n/* 6 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.BaseStandardFontDataFactory = exports.BaseSVGFactory = exports.BaseCanvasFactory = exports.BaseCMapReaderFactory = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nclass BaseCanvasFactory {\n constructor() {\n if (this.constructor === BaseCanvasFactory) {\n (0, _util.unreachable)("Cannot initialize BaseCanvasFactory.");\n }\n }\n\n create(width, height) {\n if (width <= 0 || height <= 0) {\n throw new Error("Invalid canvas size");\n }\n\n const canvas = this._createCanvas(width, height);\n\n return {\n canvas,\n context: canvas.getContext("2d")\n };\n }\n\n reset(canvasAndContext, width, height) {\n if (!canvasAndContext.canvas) {\n throw new Error("Canvas is not specified");\n }\n\n if (width <= 0 || height <= 0) {\n throw new Error("Invalid canvas size");\n }\n\n canvasAndContext.canvas.width = width;\n canvasAndContext.canvas.height = height;\n }\n\n destroy(canvasAndContext) {\n if (!canvasAndContext.canvas) {\n throw new Error("Canvas is not specified");\n }\n\n canvasAndContext.canvas.width = 0;\n canvasAndContext.canvas.height = 0;\n canvasAndContext.canvas = null;\n canvasAndContext.context = null;\n }\n\n _createCanvas(width, height) {\n (0, _util.unreachable)("Abstract method `_createCanvas` called.");\n }\n\n}\n\nexports.BaseCanvasFactory = BaseCanvasFactory;\n\nclass BaseCMapReaderFactory {\n constructor({\n baseUrl = null,\n isCompressed = false\n }) {\n if (this.constructor === BaseCMapReaderFactory) {\n (0, _util.unreachable)("Cannot initialize BaseCMapReaderFactory.");\n }\n\n this.baseUrl = baseUrl;\n this.isCompressed = isCompressed;\n }\n\n async fetch({\n name\n }) {\n if (!this.baseUrl) {\n throw new Error(\'The CMap "baseUrl" parameter must be specified, ensure that \' + \'the "cMapUrl" and "cMapPacked" API parameters are provided.\');\n }\n\n if (!name) {\n throw new Error("CMap name must be specified.");\n }\n\n const url = this.baseUrl + name + (this.isCompressed ? ".bcmap" : "");\n const compressionType = this.isCompressed ? _util.CMapCompressionType.BINARY : _util.CMapCompressionType.NONE;\n return this._fetchData(url, compressionType).catch(reason => {\n throw new Error(`Unable to load ${this.isCompressed ? "binary " : ""}CMap at: ${url}`);\n });\n }\n\n _fetchData(url, compressionType) {\n (0, _util.unreachable)("Abstract method `_fetchData` called.");\n }\n\n}\n\nexports.BaseCMapReaderFactory = BaseCMapReaderFactory;\n\nclass BaseStandardFontDataFactory {\n constructor({\n baseUrl = null\n }) {\n if (this.constructor === BaseStandardFontDataFactory) {\n (0, _util.unreachable)("Cannot initialize BaseStandardFontDataFactory.");\n }\n\n this.baseUrl = baseUrl;\n }\n\n async fetch({\n filename\n }) {\n if (!this.baseUrl) {\n throw new Error(\'The standard font "baseUrl" parameter must be specified, ensure that \' + \'the "standardFontDataUrl" API parameter is provided.\');\n }\n\n if (!filename) {\n throw new Error("Font filename must be specified.");\n }\n\n const url = `${this.baseUrl}${filename}`;\n return this._fetchData(url).catch(reason => {\n throw new Error(`Unable to load font data at: ${url}`);\n });\n }\n\n _fetchData(url) {\n (0, _util.unreachable)("Abstract method `_fetchData` called.");\n }\n\n}\n\nexports.BaseStandardFontDataFactory = BaseStandardFontDataFactory;\n\nclass BaseSVGFactory {\n constructor() {\n if (this.constructor === BaseSVGFactory) {\n (0, _util.unreachable)("Cannot initialize BaseSVGFactory.");\n }\n }\n\n create(width, height) {\n if (width <= 0 || height <= 0) {\n throw new Error("Invalid SVG dimensions");\n }\n\n const svg = this._createSVG("svg:svg");\n\n svg.setAttribute("version", "1.1");\n svg.setAttribute("width", `${width}px`);\n svg.setAttribute("height", `${height}px`);\n svg.setAttribute("preserveAspectRatio", "none");\n svg.setAttribute("viewBox", `0 0 ${width} ${height}`);\n return svg;\n }\n\n createElement(type) {\n if (typeof type !== "string") {\n throw new Error("Invalid SVG element type");\n }\n\n return this._createSVG(type);\n }\n\n _createSVG(type) {\n (0, _util.unreachable)("Abstract method `_createSVG` called.");\n }\n\n}\n\nexports.BaseSVGFactory = BaseSVGFactory;\n\n/***/ }),\n/* 7 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.FontLoader = exports.FontFaceObject = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nclass BaseFontLoader {\n constructor({\n docId,\n onUnsupportedFeature,\n ownerDocument = globalThis.document,\n styleElement = null\n }) {\n if (this.constructor === BaseFontLoader) {\n (0, _util.unreachable)("Cannot initialize BaseFontLoader.");\n }\n\n this.docId = docId;\n this._onUnsupportedFeature = onUnsupportedFeature;\n this._document = ownerDocument;\n this.nativeFontFaces = [];\n this.styleElement = null;\n }\n\n addNativeFontFace(nativeFontFace) {\n this.nativeFontFaces.push(nativeFontFace);\n\n this._document.fonts.add(nativeFontFace);\n }\n\n insertRule(rule) {\n let styleElement = this.styleElement;\n\n if (!styleElement) {\n styleElement = this.styleElement = this._document.createElement("style");\n styleElement.id = `PDFJS_FONT_STYLE_TAG_${this.docId}`;\n\n this._document.documentElement.getElementsByTagName("head")[0].appendChild(styleElement);\n }\n\n const styleSheet = styleElement.sheet;\n styleSheet.insertRule(rule, styleSheet.cssRules.length);\n }\n\n clear() {\n for (const nativeFontFace of this.nativeFontFaces) {\n this._document.fonts.delete(nativeFontFace);\n }\n\n this.nativeFontFaces.length = 0;\n\n if (this.styleElement) {\n this.styleElement.remove();\n this.styleElement = null;\n }\n }\n\n async bind(font) {\n if (font.attached || font.missingFile) {\n return;\n }\n\n font.attached = true;\n\n if (this.isFontLoadingAPISupported) {\n const nativeFontFace = font.createNativeFontFace();\n\n if (nativeFontFace) {\n this.addNativeFontFace(nativeFontFace);\n\n try {\n await nativeFontFace.loaded;\n } catch (ex) {\n this._onUnsupportedFeature({\n featureId: _util.UNSUPPORTED_FEATURES.errorFontLoadNative\n });\n\n (0, _util.warn)(`Failed to load font \'${nativeFontFace.family}\': \'${ex}\'.`);\n font.disableFontFace = true;\n throw ex;\n }\n }\n\n return;\n }\n\n const rule = font.createFontFaceRule();\n\n if (rule) {\n this.insertRule(rule);\n\n if (this.isSyncFontLoadingSupported) {\n return;\n }\n\n await new Promise(resolve => {\n const request = this._queueLoadingCallback(resolve);\n\n this._prepareFontLoadEvent([rule], [font], request);\n });\n }\n }\n\n _queueLoadingCallback(callback) {\n (0, _util.unreachable)("Abstract method `_queueLoadingCallback`.");\n }\n\n get isFontLoadingAPISupported() {\n const hasFonts = !!this._document?.fonts;\n return (0, _util.shadow)(this, "isFontLoadingAPISupported", hasFonts);\n }\n\n get isSyncFontLoadingSupported() {\n (0, _util.unreachable)("Abstract method `isSyncFontLoadingSupported`.");\n }\n\n get _loadTestFont() {\n (0, _util.unreachable)("Abstract method `_loadTestFont`.");\n }\n\n _prepareFontLoadEvent(rules, fontsToLoad, request) {\n (0, _util.unreachable)("Abstract method `_prepareFontLoadEvent`.");\n }\n\n}\n\nlet FontLoader;\nexports.FontLoader = FontLoader;\n{\n exports.FontLoader = FontLoader = class GenericFontLoader extends BaseFontLoader {\n constructor(params) {\n super(params);\n this.loadingContext = {\n requests: [],\n nextRequestId: 0\n };\n this.loadTestFontId = 0;\n }\n\n get isSyncFontLoadingSupported() {\n let supported = false;\n\n if (typeof navigator === "undefined") {\n supported = true;\n } else {\n const m = /Mozilla\\/5.0.*?rv:(\\d+).*? Gecko/.exec(navigator.userAgent);\n\n if (m?.[1] >= 14) {\n supported = true;\n }\n }\n\n return (0, _util.shadow)(this, "isSyncFontLoadingSupported", supported);\n }\n\n _queueLoadingCallback(callback) {\n function completeRequest() {\n (0, _util.assert)(!request.done, "completeRequest() cannot be called twice.");\n request.done = true;\n\n while (context.requests.length > 0 && context.requests[0].done) {\n const otherRequest = context.requests.shift();\n setTimeout(otherRequest.callback, 0);\n }\n }\n\n const context = this.loadingContext;\n const request = {\n id: `pdfjs-font-loading-${context.nextRequestId++}`,\n done: false,\n complete: completeRequest,\n callback\n };\n context.requests.push(request);\n return request;\n }\n\n get _loadTestFont() {\n const getLoadTestFont = function () {\n return atob("T1RUTwALAIAAAwAwQ0ZGIDHtZg4AAAOYAAAAgUZGVE1lkzZwAAAEHAAAABxHREVGABQA" + "FQAABDgAAAAeT1MvMlYNYwkAAAEgAAAAYGNtYXABDQLUAAACNAAAAUJoZWFk/xVFDQAA" + "ALwAAAA2aGhlYQdkA+oAAAD0AAAAJGhtdHgD6AAAAAAEWAAAAAZtYXhwAAJQAAAAARgA" + "AAAGbmFtZVjmdH4AAAGAAAAAsXBvc3T/hgAzAAADeAAAACAAAQAAAAEAALZRFsRfDzz1" + "AAsD6AAAAADOBOTLAAAAAM4KHDwAAAAAA+gDIQAAAAgAAgAAAAAAAAABAAADIQAAAFoD" + "6AAAAAAD6AABAAAAAAAAAAAAAAAAAAAAAQAAUAAAAgAAAAQD6AH0AAUAAAKKArwAAACM" + "AooCvAAAAeAAMQECAAACAAYJAAAAAAAAAAAAAQAAAAAAAAAAAAAAAFBmRWQAwAAuAC4D" + "IP84AFoDIQAAAAAAAQAAAAAAAAAAACAAIAABAAAADgCuAAEAAAAAAAAAAQAAAAEAAAAA" + "AAEAAQAAAAEAAAAAAAIAAQAAAAEAAAAAAAMAAQAAAAEAAAAAAAQAAQAAAAEAAAAAAAUA" + "AQAAAAEAAAAAAAYAAQAAAAMAAQQJAAAAAgABAAMAAQQJAAEAAgABAAMAAQQJAAIAAgAB" + "AAMAAQQJAAMAAgABAAMAAQQJAAQAAgABAAMAAQQJAAUAAgABAAMAAQQJAAYAAgABWABY" + "AAAAAAAAAwAAAAMAAAAcAAEAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAAAC7//wAA" + "AC7////TAAEAAAAAAAABBgAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAD/gwAyAAAAAQAAAAAAAAAAAAAAAAAA" + "AAABAAQEAAEBAQJYAAEBASH4DwD4GwHEAvgcA/gXBIwMAYuL+nz5tQXkD5j3CBLnEQAC" + "AQEBIVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYAAABAQAADwACAQEEE/t3" + "Dov6fAH6fAT+fPp8+nwHDosMCvm1Cvm1DAz6fBQAAAAAAAABAAAAAMmJbzEAAAAAzgTj" + "FQAAAADOBOQpAAEAAAAAAAAADAAUAAQAAAABAAAAAgABAAAAAAAAAAAD6AAAAAAAAA==");\n };\n\n return (0, _util.shadow)(this, "_loadTestFont", getLoadTestFont());\n }\n\n _prepareFontLoadEvent(rules, fonts, request) {\n function int32(data, offset) {\n return data.charCodeAt(offset) << 24 | data.charCodeAt(offset + 1) << 16 | data.charCodeAt(offset + 2) << 8 | data.charCodeAt(offset + 3) & 0xff;\n }\n\n function spliceString(s, offset, remove, insert) {\n const chunk1 = s.substring(0, offset);\n const chunk2 = s.substring(offset + remove);\n return chunk1 + insert + chunk2;\n }\n\n let i, ii;\n\n const canvas = this._document.createElement("canvas");\n\n canvas.width = 1;\n canvas.height = 1;\n const ctx = canvas.getContext("2d");\n let called = 0;\n\n function isFontReady(name, callback) {\n called++;\n\n if (called > 30) {\n (0, _util.warn)("Load test font never loaded.");\n callback();\n return;\n }\n\n ctx.font = "30px " + name;\n ctx.fillText(".", 0, 20);\n const imageData = ctx.getImageData(0, 0, 1, 1);\n\n if (imageData.data[3] > 0) {\n callback();\n return;\n }\n\n setTimeout(isFontReady.bind(null, name, callback));\n }\n\n const loadTestFontId = `lt${Date.now()}${this.loadTestFontId++}`;\n let data = this._loadTestFont;\n const COMMENT_OFFSET = 976;\n data = spliceString(data, COMMENT_OFFSET, loadTestFontId.length, loadTestFontId);\n const CFF_CHECKSUM_OFFSET = 16;\n const XXXX_VALUE = 0x58585858;\n let checksum = int32(data, CFF_CHECKSUM_OFFSET);\n\n for (i = 0, ii = loadTestFontId.length - 3; i < ii; i += 4) {\n checksum = checksum - XXXX_VALUE + int32(loadTestFontId, i) | 0;\n }\n\n if (i < loadTestFontId.length) {\n checksum = checksum - XXXX_VALUE + int32(loadTestFontId + "XXX", i) | 0;\n }\n\n data = spliceString(data, CFF_CHECKSUM_OFFSET, 4, (0, _util.string32)(checksum));\n const url = `url(data:font/opentype;base64,${btoa(data)});`;\n const rule = `@font-face {font-family:"${loadTestFontId}";src:${url}}`;\n this.insertRule(rule);\n const names = [];\n\n for (const font of fonts) {\n names.push(font.loadedName);\n }\n\n names.push(loadTestFontId);\n\n const div = this._document.createElement("div");\n\n div.style.visibility = "hidden";\n div.style.width = div.style.height = "10px";\n div.style.position = "absolute";\n div.style.top = div.style.left = "0px";\n\n for (const name of names) {\n const span = this._document.createElement("span");\n\n span.textContent = "Hi";\n span.style.fontFamily = name;\n div.appendChild(span);\n }\n\n this._document.body.appendChild(div);\n\n isFontReady(loadTestFontId, () => {\n div.remove();\n request.complete();\n });\n }\n\n };\n}\n\nclass FontFaceObject {\n constructor(translatedData, {\n isEvalSupported = true,\n disableFontFace = false,\n ignoreErrors = false,\n onUnsupportedFeature,\n fontRegistry = null\n }) {\n this.compiledGlyphs = Object.create(null);\n\n for (const i in translatedData) {\n this[i] = translatedData[i];\n }\n\n this.isEvalSupported = isEvalSupported !== false;\n this.disableFontFace = disableFontFace === true;\n this.ignoreErrors = ignoreErrors === true;\n this._onUnsupportedFeature = onUnsupportedFeature;\n this.fontRegistry = fontRegistry;\n }\n\n createNativeFontFace() {\n if (!this.data || this.disableFontFace) {\n return null;\n }\n\n let nativeFontFace;\n\n if (!this.cssFontInfo) {\n nativeFontFace = new FontFace(this.loadedName, this.data, {});\n } else {\n const css = {\n weight: this.cssFontInfo.fontWeight\n };\n\n if (this.cssFontInfo.italicAngle) {\n css.style = `oblique ${this.cssFontInfo.italicAngle}deg`;\n }\n\n nativeFontFace = new FontFace(this.cssFontInfo.fontFamily, this.data, css);\n }\n\n if (this.fontRegistry) {\n this.fontRegistry.registerFont(this);\n }\n\n return nativeFontFace;\n }\n\n createFontFaceRule() {\n if (!this.data || this.disableFontFace) {\n return null;\n }\n\n const data = (0, _util.bytesToString)(this.data);\n const url = `url(data:${this.mimetype};base64,${btoa(data)});`;\n let rule;\n\n if (!this.cssFontInfo) {\n rule = `@font-face {font-family:"${this.loadedName}";src:${url}}`;\n } else {\n let css = `font-weight: ${this.cssFontInfo.fontWeight};`;\n\n if (this.cssFontInfo.italicAngle) {\n css += `font-style: oblique ${this.cssFontInfo.italicAngle}deg;`;\n }\n\n rule = `@font-face {font-family:"${this.cssFontInfo.fontFamily}";${css}src:${url}}`;\n }\n\n if (this.fontRegistry) {\n this.fontRegistry.registerFont(this, url);\n }\n\n return rule;\n }\n\n getPathGenerator(objs, character) {\n if (this.compiledGlyphs[character] !== undefined) {\n return this.compiledGlyphs[character];\n }\n\n let cmds;\n\n try {\n cmds = objs.get(this.loadedName + "_path_" + character);\n } catch (ex) {\n if (!this.ignoreErrors) {\n throw ex;\n }\n\n this._onUnsupportedFeature({\n featureId: _util.UNSUPPORTED_FEATURES.errorFontGetPath\n });\n\n (0, _util.warn)(`getPathGenerator - ignoring character: "${ex}".`);\n return this.compiledGlyphs[character] = function (c, size) {};\n }\n\n if (this.isEvalSupported && _util.FeatureTest.isEvalSupported) {\n const jsBuf = [];\n\n for (const current of cmds) {\n const args = current.args !== undefined ? current.args.join(",") : "";\n jsBuf.push("c.", current.cmd, "(", args, ");\\n");\n }\n\n return this.compiledGlyphs[character] = new Function("c", "size", jsBuf.join(""));\n }\n\n return this.compiledGlyphs[character] = function (c, size) {\n for (const current of cmds) {\n if (current.cmd === "scale") {\n current.args = [size, -size];\n }\n\n c[current.cmd].apply(c, current.args);\n }\n };\n }\n\n}\n\nexports.FontFaceObject = FontFaceObject;\n\n/***/ }),\n/* 8 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.AnnotationStorage = void 0;\n\nvar _murmurhash = __w_pdfjs_require__(9);\n\nvar _util = __w_pdfjs_require__(1);\n\nclass AnnotationStorage {\n constructor() {\n this._storage = new Map();\n this._modified = false;\n this.onSetModified = null;\n this.onResetModified = null;\n }\n\n getValue(key, defaultValue) {\n const value = this._storage.get(key);\n\n if (value === undefined) {\n return defaultValue;\n }\n\n return Object.assign(defaultValue, value);\n }\n\n getRawValue(key) {\n return this._storage.get(key);\n }\n\n setValue(key, value) {\n const obj = this._storage.get(key);\n\n let modified = false;\n\n if (obj !== undefined) {\n for (const [entry, val] of Object.entries(value)) {\n if (obj[entry] !== val) {\n modified = true;\n obj[entry] = val;\n }\n }\n } else {\n modified = true;\n\n this._storage.set(key, value);\n }\n\n if (modified) {\n this._setModified();\n }\n }\n\n getAll() {\n return this._storage.size > 0 ? (0, _util.objectFromMap)(this._storage) : null;\n }\n\n get size() {\n return this._storage.size;\n }\n\n _setModified() {\n if (!this._modified) {\n this._modified = true;\n\n if (typeof this.onSetModified === "function") {\n this.onSetModified();\n }\n }\n }\n\n resetModified() {\n if (this._modified) {\n this._modified = false;\n\n if (typeof this.onResetModified === "function") {\n this.onResetModified();\n }\n }\n }\n\n get serializable() {\n return this._storage.size > 0 ? this._storage : null;\n }\n\n get hash() {\n const hash = new _murmurhash.MurmurHash3_64();\n\n for (const [key, value] of this._storage) {\n hash.update(`${key}:${JSON.stringify(value)}`);\n }\n\n return hash.hexdigest();\n }\n\n}\n\nexports.AnnotationStorage = AnnotationStorage;\n\n/***/ }),\n/* 9 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.MurmurHash3_64 = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nconst SEED = 0xc3d2e1f0;\nconst MASK_HIGH = 0xffff0000;\nconst MASK_LOW = 0xffff;\n\nclass MurmurHash3_64 {\n constructor(seed) {\n this.h1 = seed ? seed & 0xffffffff : SEED;\n this.h2 = seed ? seed & 0xffffffff : SEED;\n }\n\n update(input) {\n let data, length;\n\n if (typeof input === "string") {\n data = new Uint8Array(input.length * 2);\n length = 0;\n\n for (let i = 0, ii = input.length; i < ii; i++) {\n const code = input.charCodeAt(i);\n\n if (code <= 0xff) {\n data[length++] = code;\n } else {\n data[length++] = code >>> 8;\n data[length++] = code & 0xff;\n }\n }\n } else if ((0, _util.isArrayBuffer)(input)) {\n data = input.slice();\n length = data.byteLength;\n } else {\n throw new Error("Wrong data format in MurmurHash3_64_update. " + "Input must be a string or array.");\n }\n\n const blockCounts = length >> 2;\n const tailLength = length - blockCounts * 4;\n const dataUint32 = new Uint32Array(data.buffer, 0, blockCounts);\n let k1 = 0,\n k2 = 0;\n let h1 = this.h1,\n h2 = this.h2;\n const C1 = 0xcc9e2d51,\n C2 = 0x1b873593;\n const C1_LOW = C1 & MASK_LOW,\n C2_LOW = C2 & MASK_LOW;\n\n for (let i = 0; i < blockCounts; i++) {\n if (i & 1) {\n k1 = dataUint32[i];\n k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW;\n k1 = k1 << 15 | k1 >>> 17;\n k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW;\n h1 ^= k1;\n h1 = h1 << 13 | h1 >>> 19;\n h1 = h1 * 5 + 0xe6546b64;\n } else {\n k2 = dataUint32[i];\n k2 = k2 * C1 & MASK_HIGH | k2 * C1_LOW & MASK_LOW;\n k2 = k2 << 15 | k2 >>> 17;\n k2 = k2 * C2 & MASK_HIGH | k2 * C2_LOW & MASK_LOW;\n h2 ^= k2;\n h2 = h2 << 13 | h2 >>> 19;\n h2 = h2 * 5 + 0xe6546b64;\n }\n }\n\n k1 = 0;\n\n switch (tailLength) {\n case 3:\n k1 ^= data[blockCounts * 4 + 2] << 16;\n\n case 2:\n k1 ^= data[blockCounts * 4 + 1] << 8;\n\n case 1:\n k1 ^= data[blockCounts * 4];\n k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW;\n k1 = k1 << 15 | k1 >>> 17;\n k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW;\n\n if (blockCounts & 1) {\n h1 ^= k1;\n } else {\n h2 ^= k1;\n }\n\n }\n\n this.h1 = h1;\n this.h2 = h2;\n }\n\n hexdigest() {\n let h1 = this.h1,\n h2 = this.h2;\n h1 ^= h2 >>> 1;\n h1 = h1 * 0xed558ccd & MASK_HIGH | h1 * 0x8ccd & MASK_LOW;\n h2 = h2 * 0xff51afd7 & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xafd7ed55 & MASK_HIGH) >>> 16;\n h1 ^= h2 >>> 1;\n h1 = h1 * 0x1a85ec53 & MASK_HIGH | h1 * 0xec53 & MASK_LOW;\n h2 = h2 * 0xc4ceb9fe & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xb9fe1a85 & MASK_HIGH) >>> 16;\n h1 ^= h2 >>> 1;\n const hex1 = (h1 >>> 0).toString(16),\n hex2 = (h2 >>> 0).toString(16);\n return hex1.padStart(8, "0") + hex2.padStart(8, "0");\n }\n\n}\n\nexports.MurmurHash3_64 = MurmurHash3_64;\n\n/***/ }),\n/* 10 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.CanvasGraphics = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _pattern_helper = __w_pdfjs_require__(11);\n\nvar _image_utils = __w_pdfjs_require__(12);\n\nvar _is_node = __w_pdfjs_require__(3);\n\nvar _display_utils = __w_pdfjs_require__(5);\n\nconst MIN_FONT_SIZE = 16;\nconst MAX_FONT_SIZE = 100;\nconst MAX_GROUP_SIZE = 4096;\nconst EXECUTION_TIME = 15;\nconst EXECUTION_STEPS = 10;\nconst COMPILE_TYPE3_GLYPHS = true;\nconst MAX_SIZE_TO_COMPILE = 1000;\nconst FULL_CHUNK_HEIGHT = 16;\nconst LINEWIDTH_SCALE_FACTOR = 1.000001;\n\nfunction mirrorContextOperations(ctx, destCtx) {\n if (ctx._removeMirroring) {\n throw new Error("Context is already forwarding operations.");\n }\n\n ctx.__originalSave = ctx.save;\n ctx.__originalRestore = ctx.restore;\n ctx.__originalRotate = ctx.rotate;\n ctx.__originalScale = ctx.scale;\n ctx.__originalTranslate = ctx.translate;\n ctx.__originalTransform = ctx.transform;\n ctx.__originalSetTransform = ctx.setTransform;\n ctx.__originalResetTransform = ctx.resetTransform;\n ctx.__originalClip = ctx.clip;\n ctx.__originalMoveTo = ctx.moveTo;\n ctx.__originalLineTo = ctx.lineTo;\n ctx.__originalBezierCurveTo = ctx.bezierCurveTo;\n ctx.__originalRect = ctx.rect;\n ctx.__originalClosePath = ctx.closePath;\n ctx.__originalBeginPath = ctx.beginPath;\n\n ctx._removeMirroring = () => {\n ctx.save = ctx.__originalSave;\n ctx.restore = ctx.__originalRestore;\n ctx.rotate = ctx.__originalRotate;\n ctx.scale = ctx.__originalScale;\n ctx.translate = ctx.__originalTranslate;\n ctx.transform = ctx.__originalTransform;\n ctx.setTransform = ctx.__originalSetTransform;\n ctx.resetTransform = ctx.__originalResetTransform;\n ctx.clip = ctx.__originalClip;\n ctx.moveTo = ctx.__originalMoveTo;\n ctx.lineTo = ctx.__originalLineTo;\n ctx.bezierCurveTo = ctx.__originalBezierCurveTo;\n ctx.rect = ctx.__originalRect;\n ctx.closePath = ctx.__originalClosePath;\n ctx.beginPath = ctx.__originalBeginPath;\n delete ctx._removeMirroring;\n };\n\n ctx.save = function ctxSave() {\n destCtx.save();\n\n this.__originalSave();\n };\n\n ctx.restore = function ctxRestore() {\n destCtx.restore();\n\n this.__originalRestore();\n };\n\n ctx.translate = function ctxTranslate(x, y) {\n destCtx.translate(x, y);\n\n this.__originalTranslate(x, y);\n };\n\n ctx.scale = function ctxScale(x, y) {\n destCtx.scale(x, y);\n\n this.__originalScale(x, y);\n };\n\n ctx.transform = function ctxTransform(a, b, c, d, e, f) {\n destCtx.transform(a, b, c, d, e, f);\n\n this.__originalTransform(a, b, c, d, e, f);\n };\n\n ctx.setTransform = function ctxSetTransform(a, b, c, d, e, f) {\n destCtx.setTransform(a, b, c, d, e, f);\n\n this.__originalSetTransform(a, b, c, d, e, f);\n };\n\n ctx.resetTransform = function ctxResetTransform() {\n destCtx.resetTransform();\n\n this.__originalResetTransform();\n };\n\n ctx.rotate = function ctxRotate(angle) {\n destCtx.rotate(angle);\n\n this.__originalRotate(angle);\n };\n\n ctx.clip = function ctxRotate(rule) {\n destCtx.clip(rule);\n\n this.__originalClip(rule);\n };\n\n ctx.moveTo = function (x, y) {\n destCtx.moveTo(x, y);\n\n this.__originalMoveTo(x, y);\n };\n\n ctx.lineTo = function (x, y) {\n destCtx.lineTo(x, y);\n\n this.__originalLineTo(x, y);\n };\n\n ctx.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) {\n destCtx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);\n\n this.__originalBezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);\n };\n\n ctx.rect = function (x, y, width, height) {\n destCtx.rect(x, y, width, height);\n\n this.__originalRect(x, y, width, height);\n };\n\n ctx.closePath = function () {\n destCtx.closePath();\n\n this.__originalClosePath();\n };\n\n ctx.beginPath = function () {\n destCtx.beginPath();\n\n this.__originalBeginPath();\n };\n}\n\nfunction addContextCurrentTransform(ctx) {\n if (ctx._transformStack) {\n ctx._transformStack = [];\n }\n\n if (ctx.mozCurrentTransform) {\n return;\n }\n\n ctx._originalSave = ctx.save;\n ctx._originalRestore = ctx.restore;\n ctx._originalRotate = ctx.rotate;\n ctx._originalScale = ctx.scale;\n ctx._originalTranslate = ctx.translate;\n ctx._originalTransform = ctx.transform;\n ctx._originalSetTransform = ctx.setTransform;\n ctx._originalResetTransform = ctx.resetTransform;\n ctx._transformMatrix = ctx._transformMatrix || [1, 0, 0, 1, 0, 0];\n ctx._transformStack = [];\n\n try {\n const desc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(ctx), "lineWidth");\n ctx._setLineWidth = desc.set;\n ctx._getLineWidth = desc.get;\n Object.defineProperty(ctx, "lineWidth", {\n set: function setLineWidth(width) {\n this._setLineWidth(width * LINEWIDTH_SCALE_FACTOR);\n },\n get: function getLineWidth() {\n return this._getLineWidth();\n }\n });\n } catch (_) {}\n\n Object.defineProperty(ctx, "mozCurrentTransform", {\n get: function getCurrentTransform() {\n return this._transformMatrix;\n }\n });\n Object.defineProperty(ctx, "mozCurrentTransformInverse", {\n get: function getCurrentTransformInverse() {\n const [a, b, c, d, e, f] = this._transformMatrix;\n const ad_bc = a * d - b * c;\n const bc_ad = b * c - a * d;\n return [d / ad_bc, b / bc_ad, c / bc_ad, a / ad_bc, (d * e - c * f) / bc_ad, (b * e - a * f) / ad_bc];\n }\n });\n\n ctx.save = function ctxSave() {\n const old = this._transformMatrix;\n\n this._transformStack.push(old);\n\n this._transformMatrix = old.slice(0, 6);\n\n this._originalSave();\n };\n\n ctx.restore = function ctxRestore() {\n if (this._transformStack.length === 0) {\n (0, _util.warn)("Tried to restore a ctx when the stack was already empty.");\n }\n\n const prev = this._transformStack.pop();\n\n if (prev) {\n this._transformMatrix = prev;\n\n this._originalRestore();\n }\n };\n\n ctx.translate = function ctxTranslate(x, y) {\n const m = this._transformMatrix;\n m[4] = m[0] * x + m[2] * y + m[4];\n m[5] = m[1] * x + m[3] * y + m[5];\n\n this._originalTranslate(x, y);\n };\n\n ctx.scale = function ctxScale(x, y) {\n const m = this._transformMatrix;\n m[0] *= x;\n m[1] *= x;\n m[2] *= y;\n m[3] *= y;\n\n this._originalScale(x, y);\n };\n\n ctx.transform = function ctxTransform(a, b, c, d, e, f) {\n const m = this._transformMatrix;\n this._transformMatrix = [m[0] * a + m[2] * b, m[1] * a + m[3] * b, m[0] * c + m[2] * d, m[1] * c + m[3] * d, m[0] * e + m[2] * f + m[4], m[1] * e + m[3] * f + m[5]];\n\n ctx._originalTransform(a, b, c, d, e, f);\n };\n\n ctx.setTransform = function ctxSetTransform(a, b, c, d, e, f) {\n this._transformMatrix = [a, b, c, d, e, f];\n\n ctx._originalSetTransform(a, b, c, d, e, f);\n };\n\n ctx.resetTransform = function ctxResetTransform() {\n this._transformMatrix = [1, 0, 0, 1, 0, 0];\n\n ctx._originalResetTransform();\n };\n\n ctx.rotate = function ctxRotate(angle) {\n const cosValue = Math.cos(angle);\n const sinValue = Math.sin(angle);\n const m = this._transformMatrix;\n this._transformMatrix = [m[0] * cosValue + m[2] * sinValue, m[1] * cosValue + m[3] * sinValue, m[0] * -sinValue + m[2] * cosValue, m[1] * -sinValue + m[3] * cosValue, m[4], m[5]];\n\n this._originalRotate(angle);\n };\n}\n\nclass CachedCanvases {\n constructor(canvasFactory) {\n this.canvasFactory = canvasFactory;\n this.cache = Object.create(null);\n }\n\n getCanvas(id, width, height, trackTransform) {\n let canvasEntry;\n\n if (this.cache[id] !== undefined) {\n canvasEntry = this.cache[id];\n this.canvasFactory.reset(canvasEntry, width, height);\n canvasEntry.context.setTransform(1, 0, 0, 1, 0, 0);\n } else {\n canvasEntry = this.canvasFactory.create(width, height);\n this.cache[id] = canvasEntry;\n }\n\n if (trackTransform) {\n addContextCurrentTransform(canvasEntry.context);\n }\n\n return canvasEntry;\n }\n\n delete(id) {\n delete this.cache[id];\n }\n\n clear() {\n for (const id in this.cache) {\n const canvasEntry = this.cache[id];\n this.canvasFactory.destroy(canvasEntry);\n delete this.cache[id];\n }\n }\n\n}\n\nfunction drawImageAtIntegerCoords(ctx, srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH) {\n const [a, b, c, d, tx, ty] = ctx.mozCurrentTransform;\n\n if (b === 0 && c === 0) {\n const tlX = destX * a + tx;\n const rTlX = Math.round(tlX);\n const tlY = destY * d + ty;\n const rTlY = Math.round(tlY);\n const brX = (destX + destW) * a + tx;\n const rWidth = Math.abs(Math.round(brX) - rTlX) || 1;\n const brY = (destY + destH) * d + ty;\n const rHeight = Math.abs(Math.round(brY) - rTlY) || 1;\n ctx.setTransform(Math.sign(a), 0, 0, Math.sign(d), rTlX, rTlY);\n ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rWidth, rHeight);\n ctx.setTransform(a, b, c, d, tx, ty);\n return [rWidth, rHeight];\n }\n\n if (a === 0 && d === 0) {\n const tlX = destY * c + tx;\n const rTlX = Math.round(tlX);\n const tlY = destX * b + ty;\n const rTlY = Math.round(tlY);\n const brX = (destY + destH) * c + tx;\n const rWidth = Math.abs(Math.round(brX) - rTlX) || 1;\n const brY = (destX + destW) * b + ty;\n const rHeight = Math.abs(Math.round(brY) - rTlY) || 1;\n ctx.setTransform(0, Math.sign(b), Math.sign(c), 0, rTlX, rTlY);\n ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rHeight, rWidth);\n ctx.setTransform(a, b, c, d, tx, ty);\n return [rHeight, rWidth];\n }\n\n ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH);\n const scaleX = Math.hypot(a, b);\n const scaleY = Math.hypot(c, d);\n return [scaleX * destW, scaleY * destH];\n}\n\nfunction compileType3Glyph(imgData) {\n const {\n width,\n height\n } = imgData;\n\n if (!COMPILE_TYPE3_GLYPHS || width > MAX_SIZE_TO_COMPILE || height > MAX_SIZE_TO_COMPILE) {\n return null;\n }\n\n const POINT_TO_PROCESS_LIMIT = 1000;\n const POINT_TYPES = new Uint8Array([0, 2, 4, 0, 1, 0, 5, 4, 8, 10, 0, 8, 0, 2, 1, 0]);\n const width1 = width + 1;\n let points = new Uint8Array(width1 * (height + 1));\n let i, j, j0;\n const lineSize = width + 7 & ~7;\n let data = new Uint8Array(lineSize * height),\n pos = 0;\n\n for (const elem of imgData.data) {\n let mask = 128;\n\n while (mask > 0) {\n data[pos++] = elem & mask ? 0 : 255;\n mask >>= 1;\n }\n }\n\n let count = 0;\n pos = 0;\n\n if (data[pos] !== 0) {\n points[0] = 1;\n ++count;\n }\n\n for (j = 1; j < width; j++) {\n if (data[pos] !== data[pos + 1]) {\n points[j] = data[pos] ? 2 : 1;\n ++count;\n }\n\n pos++;\n }\n\n if (data[pos] !== 0) {\n points[j] = 2;\n ++count;\n }\n\n for (i = 1; i < height; i++) {\n pos = i * lineSize;\n j0 = i * width1;\n\n if (data[pos - lineSize] !== data[pos]) {\n points[j0] = data[pos] ? 1 : 8;\n ++count;\n }\n\n let sum = (data[pos] ? 4 : 0) + (data[pos - lineSize] ? 8 : 0);\n\n for (j = 1; j < width; j++) {\n sum = (sum >> 2) + (data[pos + 1] ? 4 : 0) + (data[pos - lineSize + 1] ? 8 : 0);\n\n if (POINT_TYPES[sum]) {\n points[j0 + j] = POINT_TYPES[sum];\n ++count;\n }\n\n pos++;\n }\n\n if (data[pos - lineSize] !== data[pos]) {\n points[j0 + j] = data[pos] ? 2 : 4;\n ++count;\n }\n\n if (count > POINT_TO_PROCESS_LIMIT) {\n return null;\n }\n }\n\n pos = lineSize * (height - 1);\n j0 = i * width1;\n\n if (data[pos] !== 0) {\n points[j0] = 8;\n ++count;\n }\n\n for (j = 1; j < width; j++) {\n if (data[pos] !== data[pos + 1]) {\n points[j0 + j] = data[pos] ? 4 : 8;\n ++count;\n }\n\n pos++;\n }\n\n if (data[pos] !== 0) {\n points[j0 + j] = 4;\n ++count;\n }\n\n if (count > POINT_TO_PROCESS_LIMIT) {\n return null;\n }\n\n const steps = new Int32Array([0, width1, -1, 0, -width1, 0, 0, 0, 1]);\n let path, outlines, coords;\n\n if (!_is_node.isNodeJS) {\n path = new Path2D();\n } else {\n outlines = [];\n }\n\n for (i = 0; count && i <= height; i++) {\n let p = i * width1;\n const end = p + width;\n\n while (p < end && !points[p]) {\n p++;\n }\n\n if (p === end) {\n continue;\n }\n\n if (path) {\n path.moveTo(p % width1, i);\n } else {\n coords = [p % width1, i];\n }\n\n const p0 = p;\n let type = points[p];\n\n do {\n const step = steps[type];\n\n do {\n p += step;\n } while (!points[p]);\n\n const pp = points[p];\n\n if (pp !== 5 && pp !== 10) {\n type = pp;\n points[p] = 0;\n } else {\n type = pp & 0x33 * type >> 4;\n points[p] &= type >> 2 | type << 2;\n }\n\n if (path) {\n path.lineTo(p % width1, p / width1 | 0);\n } else {\n coords.push(p % width1, p / width1 | 0);\n }\n\n if (!points[p]) {\n --count;\n }\n } while (p0 !== p);\n\n if (!path) {\n outlines.push(coords);\n }\n\n --i;\n }\n\n data = null;\n points = null;\n\n const drawOutline = function (c) {\n c.save();\n c.scale(1 / width, -1 / height);\n c.translate(0, -height);\n\n if (path) {\n c.fill(path);\n } else {\n c.beginPath();\n\n for (const o of outlines) {\n c.moveTo(o[0], o[1]);\n\n for (let l = 2, ll = o.length; l < ll; l += 2) {\n c.lineTo(o[l], o[l + 1]);\n }\n }\n\n c.fill();\n }\n\n c.beginPath();\n c.restore();\n };\n\n return drawOutline;\n}\n\nclass CanvasExtraState {\n constructor(width, height) {\n this.alphaIsShape = false;\n this.fontSize = 0;\n this.fontSizeScale = 1;\n this.textMatrix = _util.IDENTITY_MATRIX;\n this.textMatrixScale = 1;\n this.fontMatrix = _util.FONT_IDENTITY_MATRIX;\n this.leading = 0;\n this.x = 0;\n this.y = 0;\n this.lineX = 0;\n this.lineY = 0;\n this.charSpacing = 0;\n this.wordSpacing = 0;\n this.textHScale = 1;\n this.textRenderingMode = _util.TextRenderingMode.FILL;\n this.textRise = 0;\n this.fillColor = "#000000";\n this.strokeColor = "#000000";\n this.patternFill = false;\n this.fillAlpha = 1;\n this.strokeAlpha = 1;\n this.lineWidth = 1;\n this.activeSMask = null;\n this.transferMaps = null;\n this.startNewPathAndClipBox([0, 0, width, height]);\n }\n\n clone() {\n const clone = Object.create(this);\n clone.clipBox = this.clipBox.slice();\n return clone;\n }\n\n setCurrentPoint(x, y) {\n this.x = x;\n this.y = y;\n }\n\n updatePathMinMax(transform, x, y) {\n [x, y] = _util.Util.applyTransform([x, y], transform);\n this.minX = Math.min(this.minX, x);\n this.minY = Math.min(this.minY, y);\n this.maxX = Math.max(this.maxX, x);\n this.maxY = Math.max(this.maxY, y);\n }\n\n updateRectMinMax(transform, rect) {\n const p1 = _util.Util.applyTransform(rect, transform);\n\n const p2 = _util.Util.applyTransform(rect.slice(2), transform);\n\n this.minX = Math.min(this.minX, p1[0], p2[0]);\n this.minY = Math.min(this.minY, p1[1], p2[1]);\n this.maxX = Math.max(this.maxX, p1[0], p2[0]);\n this.maxY = Math.max(this.maxY, p1[1], p2[1]);\n }\n\n updateScalingPathMinMax(transform, minMax) {\n _util.Util.scaleMinMax(transform, minMax);\n\n this.minX = Math.min(this.minX, minMax[0]);\n this.maxX = Math.max(this.maxX, minMax[1]);\n this.minY = Math.min(this.minY, minMax[2]);\n this.maxY = Math.max(this.maxY, minMax[3]);\n }\n\n updateCurvePathMinMax(transform, x0, y0, x1, y1, x2, y2, x3, y3, minMax) {\n const box = _util.Util.bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3);\n\n if (minMax) {\n minMax[0] = Math.min(minMax[0], box[0], box[2]);\n minMax[1] = Math.max(minMax[1], box[0], box[2]);\n minMax[2] = Math.min(minMax[2], box[1], box[3]);\n minMax[3] = Math.max(minMax[3], box[1], box[3]);\n return;\n }\n\n this.updateRectMinMax(transform, box);\n }\n\n getPathBoundingBox(pathType = _pattern_helper.PathType.FILL, transform = null) {\n const box = [this.minX, this.minY, this.maxX, this.maxY];\n\n if (pathType === _pattern_helper.PathType.STROKE) {\n if (!transform) {\n (0, _util.unreachable)("Stroke bounding box must include transform.");\n }\n\n const scale = _util.Util.singularValueDecompose2dScale(transform);\n\n const xStrokePad = scale[0] * this.lineWidth / 2;\n const yStrokePad = scale[1] * this.lineWidth / 2;\n box[0] -= xStrokePad;\n box[1] -= yStrokePad;\n box[2] += xStrokePad;\n box[3] += yStrokePad;\n }\n\n return box;\n }\n\n updateClipFromPath() {\n const intersect = _util.Util.intersect(this.clipBox, this.getPathBoundingBox());\n\n this.startNewPathAndClipBox(intersect || [0, 0, 0, 0]);\n }\n\n isEmptyClip() {\n return this.minX === Infinity;\n }\n\n startNewPathAndClipBox(box) {\n this.clipBox = box;\n this.minX = Infinity;\n this.minY = Infinity;\n this.maxX = 0;\n this.maxY = 0;\n }\n\n getClippedPathBoundingBox(pathType = _pattern_helper.PathType.FILL, transform = null) {\n return _util.Util.intersect(this.clipBox, this.getPathBoundingBox(pathType, transform));\n }\n\n}\n\nfunction putBinaryImageData(ctx, imgData, transferMaps = null) {\n if (typeof ImageData !== "undefined" && imgData instanceof ImageData) {\n ctx.putImageData(imgData, 0, 0);\n return;\n }\n\n const height = imgData.height,\n width = imgData.width;\n const partialChunkHeight = height % FULL_CHUNK_HEIGHT;\n const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT;\n const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1;\n const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT);\n let srcPos = 0,\n destPos;\n const src = imgData.data;\n const dest = chunkImgData.data;\n let i, j, thisChunkHeight, elemsInThisChunk;\n let transferMapRed, transferMapGreen, transferMapBlue, transferMapGray;\n\n if (transferMaps) {\n switch (transferMaps.length) {\n case 1:\n transferMapRed = transferMaps[0];\n transferMapGreen = transferMaps[0];\n transferMapBlue = transferMaps[0];\n transferMapGray = transferMaps[0];\n break;\n\n case 4:\n transferMapRed = transferMaps[0];\n transferMapGreen = transferMaps[1];\n transferMapBlue = transferMaps[2];\n transferMapGray = transferMaps[3];\n break;\n }\n }\n\n if (imgData.kind === _util.ImageKind.GRAYSCALE_1BPP) {\n const srcLength = src.byteLength;\n const dest32 = new Uint32Array(dest.buffer, 0, dest.byteLength >> 2);\n const dest32DataLength = dest32.length;\n const fullSrcDiff = width + 7 >> 3;\n let white = 0xffffffff;\n let black = _util.FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff;\n\n if (transferMapGray) {\n if (transferMapGray[0] === 0xff && transferMapGray[0xff] === 0) {\n [white, black] = [black, white];\n }\n }\n\n for (i = 0; i < totalChunks; i++) {\n thisChunkHeight = i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight;\n destPos = 0;\n\n for (j = 0; j < thisChunkHeight; j++) {\n const srcDiff = srcLength - srcPos;\n let k = 0;\n const kEnd = srcDiff > fullSrcDiff ? width : srcDiff * 8 - 7;\n const kEndUnrolled = kEnd & ~7;\n let mask = 0;\n let srcByte = 0;\n\n for (; k < kEndUnrolled; k += 8) {\n srcByte = src[srcPos++];\n dest32[destPos++] = srcByte & 128 ? white : black;\n dest32[destPos++] = srcByte & 64 ? white : black;\n dest32[destPos++] = srcByte & 32 ? white : black;\n dest32[destPos++] = srcByte & 16 ? white : black;\n dest32[destPos++] = srcByte & 8 ? white : black;\n dest32[destPos++] = srcByte & 4 ? white : black;\n dest32[destPos++] = srcByte & 2 ? white : black;\n dest32[destPos++] = srcByte & 1 ? white : black;\n }\n\n for (; k < kEnd; k++) {\n if (mask === 0) {\n srcByte = src[srcPos++];\n mask = 128;\n }\n\n dest32[destPos++] = srcByte & mask ? white : black;\n mask >>= 1;\n }\n }\n\n while (destPos < dest32DataLength) {\n dest32[destPos++] = 0;\n }\n\n ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT);\n }\n } else if (imgData.kind === _util.ImageKind.RGBA_32BPP) {\n const hasTransferMaps = !!(transferMapRed || transferMapGreen || transferMapBlue);\n j = 0;\n elemsInThisChunk = width * FULL_CHUNK_HEIGHT * 4;\n\n for (i = 0; i < fullChunks; i++) {\n dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk));\n srcPos += elemsInThisChunk;\n\n if (hasTransferMaps) {\n for (let k = 0; k < elemsInThisChunk; k += 4) {\n if (transferMapRed) {\n dest[k + 0] = transferMapRed[dest[k + 0]];\n }\n\n if (transferMapGreen) {\n dest[k + 1] = transferMapGreen[dest[k + 1]];\n }\n\n if (transferMapBlue) {\n dest[k + 2] = transferMapBlue[dest[k + 2]];\n }\n }\n }\n\n ctx.putImageData(chunkImgData, 0, j);\n j += FULL_CHUNK_HEIGHT;\n }\n\n if (i < totalChunks) {\n elemsInThisChunk = width * partialChunkHeight * 4;\n dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk));\n\n if (hasTransferMaps) {\n for (let k = 0; k < elemsInThisChunk; k += 4) {\n if (transferMapRed) {\n dest[k + 0] = transferMapRed[dest[k + 0]];\n }\n\n if (transferMapGreen) {\n dest[k + 1] = transferMapGreen[dest[k + 1]];\n }\n\n if (transferMapBlue) {\n dest[k + 2] = transferMapBlue[dest[k + 2]];\n }\n }\n }\n\n ctx.putImageData(chunkImgData, 0, j);\n }\n } else if (imgData.kind === _util.ImageKind.RGB_24BPP) {\n const hasTransferMaps = !!(transferMapRed || transferMapGreen || transferMapBlue);\n thisChunkHeight = FULL_CHUNK_HEIGHT;\n elemsInThisChunk = width * thisChunkHeight;\n\n for (i = 0; i < totalChunks; i++) {\n if (i >= fullChunks) {\n thisChunkHeight = partialChunkHeight;\n elemsInThisChunk = width * thisChunkHeight;\n }\n\n destPos = 0;\n\n for (j = elemsInThisChunk; j--;) {\n dest[destPos++] = src[srcPos++];\n dest[destPos++] = src[srcPos++];\n dest[destPos++] = src[srcPos++];\n dest[destPos++] = 255;\n }\n\n if (hasTransferMaps) {\n for (let k = 0; k < destPos; k += 4) {\n if (transferMapRed) {\n dest[k + 0] = transferMapRed[dest[k + 0]];\n }\n\n if (transferMapGreen) {\n dest[k + 1] = transferMapGreen[dest[k + 1]];\n }\n\n if (transferMapBlue) {\n dest[k + 2] = transferMapBlue[dest[k + 2]];\n }\n }\n }\n\n ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT);\n }\n } else {\n throw new Error(`bad image kind: ${imgData.kind}`);\n }\n}\n\nfunction putBinaryImageMask(ctx, imgData) {\n if (imgData.bitmap) {\n ctx.drawImage(imgData.bitmap, 0, 0);\n return;\n }\n\n const height = imgData.height,\n width = imgData.width;\n const partialChunkHeight = height % FULL_CHUNK_HEIGHT;\n const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT;\n const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1;\n const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT);\n let srcPos = 0;\n const src = imgData.data;\n const dest = chunkImgData.data;\n\n for (let i = 0; i < totalChunks; i++) {\n const thisChunkHeight = i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight;\n ({\n srcPos\n } = (0, _image_utils.applyMaskImageData)({\n src,\n srcPos,\n dest,\n width,\n height: thisChunkHeight\n }));\n ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT);\n }\n}\n\nfunction copyCtxState(sourceCtx, destCtx) {\n const properties = ["strokeStyle", "fillStyle", "fillRule", "globalAlpha", "lineWidth", "lineCap", "lineJoin", "miterLimit", "globalCompositeOperation", "font"];\n\n for (let i = 0, ii = properties.length; i < ii; i++) {\n const property = properties[i];\n\n if (sourceCtx[property] !== undefined) {\n destCtx[property] = sourceCtx[property];\n }\n }\n\n if (sourceCtx.setLineDash !== undefined) {\n destCtx.setLineDash(sourceCtx.getLineDash());\n destCtx.lineDashOffset = sourceCtx.lineDashOffset;\n }\n}\n\nfunction resetCtxToDefault(ctx, foregroundColor) {\n ctx.strokeStyle = ctx.fillStyle = foregroundColor || "#000000";\n ctx.fillRule = "nonzero";\n ctx.globalAlpha = 1;\n ctx.lineWidth = 1;\n ctx.lineCap = "butt";\n ctx.lineJoin = "miter";\n ctx.miterLimit = 10;\n ctx.globalCompositeOperation = "source-over";\n ctx.font = "10px sans-serif";\n\n if (ctx.setLineDash !== undefined) {\n ctx.setLineDash([]);\n ctx.lineDashOffset = 0;\n }\n}\n\nfunction composeSMaskBackdrop(bytes, r0, g0, b0) {\n const length = bytes.length;\n\n for (let i = 3; i < length; i += 4) {\n const alpha = bytes[i];\n\n if (alpha === 0) {\n bytes[i - 3] = r0;\n bytes[i - 2] = g0;\n bytes[i - 1] = b0;\n } else if (alpha < 255) {\n const alpha_ = 255 - alpha;\n bytes[i - 3] = bytes[i - 3] * alpha + r0 * alpha_ >> 8;\n bytes[i - 2] = bytes[i - 2] * alpha + g0 * alpha_ >> 8;\n bytes[i - 1] = bytes[i - 1] * alpha + b0 * alpha_ >> 8;\n }\n }\n}\n\nfunction composeSMaskAlpha(maskData, layerData, transferMap) {\n const length = maskData.length;\n const scale = 1 / 255;\n\n for (let i = 3; i < length; i += 4) {\n const alpha = transferMap ? transferMap[maskData[i]] : maskData[i];\n layerData[i] = layerData[i] * alpha * scale | 0;\n }\n}\n\nfunction composeSMaskLuminosity(maskData, layerData, transferMap) {\n const length = maskData.length;\n\n for (let i = 3; i < length; i += 4) {\n const y = maskData[i - 3] * 77 + maskData[i - 2] * 152 + maskData[i - 1] * 28;\n layerData[i] = transferMap ? layerData[i] * transferMap[y >> 8] >> 8 : layerData[i] * y >> 16;\n }\n}\n\nfunction genericComposeSMask(maskCtx, layerCtx, width, height, subtype, backdrop, transferMap, layerOffsetX, layerOffsetY, maskOffsetX, maskOffsetY) {\n const hasBackdrop = !!backdrop;\n const r0 = hasBackdrop ? backdrop[0] : 0;\n const g0 = hasBackdrop ? backdrop[1] : 0;\n const b0 = hasBackdrop ? backdrop[2] : 0;\n let composeFn;\n\n if (subtype === "Luminosity") {\n composeFn = composeSMaskLuminosity;\n } else {\n composeFn = composeSMaskAlpha;\n }\n\n const PIXELS_TO_PROCESS = 1048576;\n const chunkSize = Math.min(height, Math.ceil(PIXELS_TO_PROCESS / width));\n\n for (let row = 0; row < height; row += chunkSize) {\n const chunkHeight = Math.min(chunkSize, height - row);\n const maskData = maskCtx.getImageData(layerOffsetX - maskOffsetX, row + (layerOffsetY - maskOffsetY), width, chunkHeight);\n const layerData = layerCtx.getImageData(layerOffsetX, row + layerOffsetY, width, chunkHeight);\n\n if (hasBackdrop) {\n composeSMaskBackdrop(maskData.data, r0, g0, b0);\n }\n\n composeFn(maskData.data, layerData.data, transferMap);\n layerCtx.putImageData(layerData, layerOffsetX, row + layerOffsetY);\n }\n}\n\nfunction composeSMask(ctx, smask, layerCtx, layerBox) {\n const layerOffsetX = layerBox[0];\n const layerOffsetY = layerBox[1];\n const layerWidth = layerBox[2] - layerOffsetX;\n const layerHeight = layerBox[3] - layerOffsetY;\n\n if (layerWidth === 0 || layerHeight === 0) {\n return;\n }\n\n genericComposeSMask(smask.context, layerCtx, layerWidth, layerHeight, smask.subtype, smask.backdrop, smask.transferMap, layerOffsetX, layerOffsetY, smask.offsetX, smask.offsetY);\n ctx.save();\n ctx.globalAlpha = 1;\n ctx.globalCompositeOperation = "source-over";\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.drawImage(layerCtx.canvas, 0, 0);\n ctx.restore();\n}\n\nfunction getImageSmoothingEnabled(transform, interpolate) {\n const scale = _util.Util.singularValueDecompose2dScale(transform);\n\n scale[0] = Math.fround(scale[0]);\n scale[1] = Math.fround(scale[1]);\n const actualScale = Math.fround((globalThis.devicePixelRatio || 1) * _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS);\n\n if (interpolate !== undefined) {\n return interpolate;\n } else if (scale[0] <= actualScale || scale[1] <= actualScale) {\n return true;\n }\n\n return false;\n}\n\nconst LINE_CAP_STYLES = ["butt", "round", "square"];\nconst LINE_JOIN_STYLES = ["miter", "round", "bevel"];\nconst NORMAL_CLIP = {};\nconst EO_CLIP = {};\n\nclass CanvasGraphics {\n constructor(canvasCtx, commonObjs, objs, canvasFactory, imageLayer, optionalContentConfig, annotationCanvasMap, pageColors) {\n this.ctx = canvasCtx;\n this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height);\n this.stateStack = [];\n this.pendingClip = null;\n this.pendingEOFill = false;\n this.res = null;\n this.xobjs = null;\n this.commonObjs = commonObjs;\n this.objs = objs;\n this.canvasFactory = canvasFactory;\n this.imageLayer = imageLayer;\n this.groupStack = [];\n this.processingType3 = null;\n this.baseTransform = null;\n this.baseTransformStack = [];\n this.groupLevel = 0;\n this.smaskStack = [];\n this.smaskCounter = 0;\n this.tempSMask = null;\n this.suspendedCtx = null;\n this.contentVisible = true;\n this.markedContentStack = [];\n this.optionalContentConfig = optionalContentConfig;\n this.cachedCanvases = new CachedCanvases(this.canvasFactory);\n this.cachedPatterns = new Map();\n this.annotationCanvasMap = annotationCanvasMap;\n this.viewportScale = 1;\n this.outputScaleX = 1;\n this.outputScaleY = 1;\n this.backgroundColor = pageColors?.background || null;\n this.foregroundColor = pageColors?.foreground || null;\n\n if (canvasCtx) {\n addContextCurrentTransform(canvasCtx);\n }\n\n this._cachedScaleForStroking = null;\n this._cachedGetSinglePixelWidth = null;\n this._cachedBitmapsMap = new Map();\n }\n\n getObject(data, fallback = null) {\n if (typeof data === "string") {\n return data.startsWith("g_") ? this.commonObjs.get(data) : this.objs.get(data);\n }\n\n return fallback;\n }\n\n beginDrawing({\n transform,\n viewport,\n transparency = false,\n background = null\n }) {\n const width = this.ctx.canvas.width;\n const height = this.ctx.canvas.height;\n const defaultBackgroundColor = background || "#ffffff";\n this.ctx.save();\n\n if (this.foregroundColor && this.backgroundColor) {\n this.ctx.fillStyle = this.foregroundColor;\n const fg = this.foregroundColor = this.ctx.fillStyle;\n this.ctx.fillStyle = this.backgroundColor;\n const bg = this.backgroundColor = this.ctx.fillStyle;\n let isValidDefaultBg = true;\n let defaultBg = defaultBackgroundColor;\n this.ctx.fillStyle = defaultBackgroundColor;\n defaultBg = this.ctx.fillStyle;\n isValidDefaultBg = typeof defaultBg === "string" && /^#[0-9A-Fa-f]{6}$/.test(defaultBg);\n\n if (fg === "#000000" && bg === "#ffffff" || fg === bg || !isValidDefaultBg) {\n this.foregroundColor = this.backgroundColor = null;\n } else {\n const cB = parseInt(defaultBg.slice(1), 16);\n const rB = (cB && 0xff0000) >> 16;\n const gB = (cB && 0x00ff00) >> 8;\n const bB = cB && 0x0000ff;\n\n const newComp = x => {\n x /= 255;\n return x <= 0.03928 ? x / 12.92 : ((x + 0.055) / 1.055) ** 2.4;\n };\n\n const lumB = Math.round(0.2126 * newComp(rB) + 0.7152 * newComp(gB) + 0.0722 * newComp(bB));\n\n this.selectColor = (r, g, b) => {\n const lumC = 0.2126 * newComp(r) + 0.7152 * newComp(g) + 0.0722 * newComp(b);\n return Math.round(lumC) === lumB ? bg : fg;\n };\n }\n }\n\n this.ctx.fillStyle = this.backgroundColor || defaultBackgroundColor;\n this.ctx.fillRect(0, 0, width, height);\n this.ctx.restore();\n\n if (transparency) {\n const transparentCanvas = this.cachedCanvases.getCanvas("transparent", width, height, true);\n this.compositeCtx = this.ctx;\n this.transparentCanvas = transparentCanvas.canvas;\n this.ctx = transparentCanvas.context;\n this.ctx.save();\n this.ctx.transform.apply(this.ctx, this.compositeCtx.mozCurrentTransform);\n }\n\n this.ctx.save();\n resetCtxToDefault(this.ctx, this.foregroundColor);\n\n if (transform) {\n this.ctx.transform.apply(this.ctx, transform);\n this.outputScaleX = transform[0];\n this.outputScaleY = transform[0];\n }\n\n this.ctx.transform.apply(this.ctx, viewport.transform);\n this.viewportScale = viewport.scale;\n this.baseTransform = this.ctx.mozCurrentTransform.slice();\n\n if (this.imageLayer) {\n this.imageLayer.beginLayout();\n }\n }\n\n executeOperatorList(operatorList, executionStartIdx, continueCallback, stepper) {\n const argsArray = operatorList.argsArray;\n const fnArray = operatorList.fnArray;\n let i = executionStartIdx || 0;\n const argsArrayLen = argsArray.length;\n\n if (argsArrayLen === i) {\n return i;\n }\n\n const chunkOperations = argsArrayLen - i > EXECUTION_STEPS && typeof continueCallback === "function";\n const endTime = chunkOperations ? Date.now() + EXECUTION_TIME : 0;\n let steps = 0;\n const commonObjs = this.commonObjs;\n const objs = this.objs;\n let fnId;\n\n while (true) {\n if (stepper !== undefined && i === stepper.nextBreakPoint) {\n stepper.breakIt(i, continueCallback);\n return i;\n }\n\n fnId = fnArray[i];\n\n if (fnId !== _util.OPS.dependency) {\n this[fnId].apply(this, argsArray[i]);\n } else {\n for (const depObjId of argsArray[i]) {\n const objsPool = depObjId.startsWith("g_") ? commonObjs : objs;\n\n if (!objsPool.has(depObjId)) {\n objsPool.get(depObjId, continueCallback);\n return i;\n }\n }\n }\n\n i++;\n\n if (i === argsArrayLen) {\n return i;\n }\n\n if (chunkOperations && ++steps > EXECUTION_STEPS) {\n if (Date.now() > endTime) {\n continueCallback();\n return i;\n }\n\n steps = 0;\n }\n }\n }\n\n endDrawing() {\n while (this.stateStack.length || this.inSMaskMode) {\n this.restore();\n }\n\n this.ctx.restore();\n\n if (this.transparentCanvas) {\n this.ctx = this.compositeCtx;\n this.ctx.save();\n this.ctx.setTransform(1, 0, 0, 1, 0, 0);\n this.ctx.drawImage(this.transparentCanvas, 0, 0);\n this.ctx.restore();\n this.transparentCanvas = null;\n }\n\n this.cachedCanvases.clear();\n this.cachedPatterns.clear();\n\n for (const cache of this._cachedBitmapsMap.values()) {\n for (const canvas of cache.values()) {\n if (typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement) {\n canvas.width = canvas.height = 0;\n }\n }\n\n cache.clear();\n }\n\n this._cachedBitmapsMap.clear();\n\n if (this.imageLayer) {\n this.imageLayer.endLayout();\n }\n }\n\n _scaleImage(img, inverseTransform) {\n const width = img.width;\n const height = img.height;\n let widthScale = Math.max(Math.hypot(inverseTransform[0], inverseTransform[1]), 1);\n let heightScale = Math.max(Math.hypot(inverseTransform[2], inverseTransform[3]), 1);\n let paintWidth = width,\n paintHeight = height;\n let tmpCanvasId = "prescale1";\n let tmpCanvas, tmpCtx;\n\n while (widthScale > 2 && paintWidth > 1 || heightScale > 2 && paintHeight > 1) {\n let newWidth = paintWidth,\n newHeight = paintHeight;\n\n if (widthScale > 2 && paintWidth > 1) {\n newWidth = Math.ceil(paintWidth / 2);\n widthScale /= paintWidth / newWidth;\n }\n\n if (heightScale > 2 && paintHeight > 1) {\n newHeight = Math.ceil(paintHeight / 2);\n heightScale /= paintHeight / newHeight;\n }\n\n tmpCanvas = this.cachedCanvases.getCanvas(tmpCanvasId, newWidth, newHeight, false);\n tmpCtx = tmpCanvas.context;\n tmpCtx.clearRect(0, 0, newWidth, newHeight);\n tmpCtx.drawImage(img, 0, 0, paintWidth, paintHeight, 0, 0, newWidth, newHeight);\n img = tmpCanvas.canvas;\n paintWidth = newWidth;\n paintHeight = newHeight;\n tmpCanvasId = tmpCanvasId === "prescale1" ? "prescale2" : "prescale1";\n }\n\n return {\n img,\n paintWidth,\n paintHeight\n };\n }\n\n _createMaskCanvas(img) {\n const ctx = this.ctx;\n const {\n width,\n height\n } = img;\n const fillColor = this.current.fillColor;\n const isPatternFill = this.current.patternFill;\n const currentTransform = ctx.mozCurrentTransform;\n let cache, cacheKey, scaled, maskCanvas;\n\n if ((img.bitmap || img.data) && img.count > 1) {\n const mainKey = img.bitmap || img.data.buffer;\n const withoutTranslation = currentTransform.slice(0, 4);\n cacheKey = JSON.stringify(isPatternFill ? withoutTranslation : [withoutTranslation, fillColor]);\n cache = this._cachedBitmapsMap.get(mainKey);\n\n if (!cache) {\n cache = new Map();\n\n this._cachedBitmapsMap.set(mainKey, cache);\n }\n\n const cachedImage = cache.get(cacheKey);\n\n if (cachedImage && !isPatternFill) {\n const offsetX = Math.round(Math.min(currentTransform[0], currentTransform[2]) + currentTransform[4]);\n const offsetY = Math.round(Math.min(currentTransform[1], currentTransform[3]) + currentTransform[5]);\n return {\n canvas: cachedImage,\n offsetX,\n offsetY\n };\n }\n\n scaled = cachedImage;\n }\n\n if (!scaled) {\n maskCanvas = this.cachedCanvases.getCanvas("maskCanvas", width, height, false);\n putBinaryImageMask(maskCanvas.context, img);\n }\n\n let maskToCanvas = _util.Util.transform(currentTransform, [1 / width, 0, 0, -1 / height, 0, 0]);\n\n maskToCanvas = _util.Util.transform(maskToCanvas, [1, 0, 0, 1, 0, -height]);\n\n const cord1 = _util.Util.applyTransform([0, 0], maskToCanvas);\n\n const cord2 = _util.Util.applyTransform([width, height], maskToCanvas);\n\n const rect = _util.Util.normalizeRect([cord1[0], cord1[1], cord2[0], cord2[1]]);\n\n const drawnWidth = Math.round(rect[2] - rect[0]) || 1;\n const drawnHeight = Math.round(rect[3] - rect[1]) || 1;\n const fillCanvas = this.cachedCanvases.getCanvas("fillCanvas", drawnWidth, drawnHeight, true);\n const fillCtx = fillCanvas.context;\n const offsetX = Math.min(cord1[0], cord2[0]);\n const offsetY = Math.min(cord1[1], cord2[1]);\n fillCtx.translate(-offsetX, -offsetY);\n fillCtx.transform.apply(fillCtx, maskToCanvas);\n\n if (!scaled) {\n scaled = this._scaleImage(maskCanvas.canvas, fillCtx.mozCurrentTransformInverse);\n scaled = scaled.img;\n\n if (cache && isPatternFill) {\n cache.set(cacheKey, scaled);\n }\n }\n\n fillCtx.imageSmoothingEnabled = getImageSmoothingEnabled(fillCtx.mozCurrentTransform, img.interpolate);\n drawImageAtIntegerCoords(fillCtx, scaled, 0, 0, scaled.width, scaled.height, 0, 0, width, height);\n fillCtx.globalCompositeOperation = "source-in";\n\n const inverse = _util.Util.transform(fillCtx.mozCurrentTransformInverse, [1, 0, 0, 1, -offsetX, -offsetY]);\n\n fillCtx.fillStyle = isPatternFill ? fillColor.getPattern(ctx, this, inverse, _pattern_helper.PathType.FILL) : fillColor;\n fillCtx.fillRect(0, 0, width, height);\n\n if (cache && !isPatternFill) {\n this.cachedCanvases.delete("fillCanvas");\n cache.set(cacheKey, fillCanvas.canvas);\n }\n\n return {\n canvas: fillCanvas.canvas,\n offsetX: Math.round(offsetX),\n offsetY: Math.round(offsetY)\n };\n }\n\n setLineWidth(width) {\n if (width !== this.current.lineWidth) {\n this._cachedScaleForStroking = null;\n }\n\n this.current.lineWidth = width;\n this.ctx.lineWidth = width;\n }\n\n setLineCap(style) {\n this.ctx.lineCap = LINE_CAP_STYLES[style];\n }\n\n setLineJoin(style) {\n this.ctx.lineJoin = LINE_JOIN_STYLES[style];\n }\n\n setMiterLimit(limit) {\n this.ctx.miterLimit = limit;\n }\n\n setDash(dashArray, dashPhase) {\n const ctx = this.ctx;\n\n if (ctx.setLineDash !== undefined) {\n ctx.setLineDash(dashArray);\n ctx.lineDashOffset = dashPhase;\n }\n }\n\n setRenderingIntent(intent) {}\n\n setFlatness(flatness) {}\n\n setGState(states) {\n for (let i = 0, ii = states.length; i < ii; i++) {\n const state = states[i];\n const key = state[0];\n const value = state[1];\n\n switch (key) {\n case "LW":\n this.setLineWidth(value);\n break;\n\n case "LC":\n this.setLineCap(value);\n break;\n\n case "LJ":\n this.setLineJoin(value);\n break;\n\n case "ML":\n this.setMiterLimit(value);\n break;\n\n case "D":\n this.setDash(value[0], value[1]);\n break;\n\n case "RI":\n this.setRenderingIntent(value);\n break;\n\n case "FL":\n this.setFlatness(value);\n break;\n\n case "Font":\n this.setFont(value[0], value[1]);\n break;\n\n case "CA":\n this.current.strokeAlpha = state[1];\n break;\n\n case "ca":\n this.current.fillAlpha = state[1];\n this.ctx.globalAlpha = state[1];\n break;\n\n case "BM":\n this.ctx.globalCompositeOperation = value;\n break;\n\n case "SMask":\n this.current.activeSMask = value ? this.tempSMask : null;\n this.tempSMask = null;\n this.checkSMaskState();\n break;\n\n case "TR":\n this.current.transferMaps = value;\n }\n }\n }\n\n get inSMaskMode() {\n return !!this.suspendedCtx;\n }\n\n checkSMaskState() {\n const inSMaskMode = this.inSMaskMode;\n\n if (this.current.activeSMask && !inSMaskMode) {\n this.beginSMaskMode();\n } else if (!this.current.activeSMask && inSMaskMode) {\n this.endSMaskMode();\n }\n }\n\n beginSMaskMode() {\n if (this.inSMaskMode) {\n throw new Error("beginSMaskMode called while already in smask mode");\n }\n\n const drawnWidth = this.ctx.canvas.width;\n const drawnHeight = this.ctx.canvas.height;\n const cacheId = "smaskGroupAt" + this.groupLevel;\n const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight, true);\n this.suspendedCtx = this.ctx;\n this.ctx = scratchCanvas.context;\n const ctx = this.ctx;\n ctx.setTransform.apply(ctx, this.suspendedCtx.mozCurrentTransform);\n copyCtxState(this.suspendedCtx, ctx);\n mirrorContextOperations(ctx, this.suspendedCtx);\n this.setGState([["BM", "source-over"], ["ca", 1], ["CA", 1]]);\n }\n\n endSMaskMode() {\n if (!this.inSMaskMode) {\n throw new Error("endSMaskMode called while not in smask mode");\n }\n\n this.ctx._removeMirroring();\n\n copyCtxState(this.ctx, this.suspendedCtx);\n this.ctx = this.suspendedCtx;\n this.suspendedCtx = null;\n }\n\n compose(dirtyBox) {\n if (!this.current.activeSMask) {\n return;\n }\n\n if (!dirtyBox) {\n dirtyBox = [0, 0, this.ctx.canvas.width, this.ctx.canvas.height];\n } else {\n dirtyBox[0] = Math.floor(dirtyBox[0]);\n dirtyBox[1] = Math.floor(dirtyBox[1]);\n dirtyBox[2] = Math.ceil(dirtyBox[2]);\n dirtyBox[3] = Math.ceil(dirtyBox[3]);\n }\n\n const smask = this.current.activeSMask;\n const suspendedCtx = this.suspendedCtx;\n composeSMask(suspendedCtx, smask, this.ctx, dirtyBox);\n this.ctx.save();\n this.ctx.setTransform(1, 0, 0, 1, 0, 0);\n this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);\n this.ctx.restore();\n }\n\n save() {\n if (this.inSMaskMode) {\n copyCtxState(this.ctx, this.suspendedCtx);\n this.suspendedCtx.save();\n } else {\n this.ctx.save();\n }\n\n const old = this.current;\n this.stateStack.push(old);\n this.current = old.clone();\n }\n\n restore() {\n if (this.stateStack.length === 0 && this.inSMaskMode) {\n this.endSMaskMode();\n }\n\n if (this.stateStack.length !== 0) {\n this.current = this.stateStack.pop();\n\n if (this.inSMaskMode) {\n this.suspendedCtx.restore();\n copyCtxState(this.suspendedCtx, this.ctx);\n } else {\n this.ctx.restore();\n }\n\n this.checkSMaskState();\n this.pendingClip = null;\n this._cachedScaleForStroking = null;\n this._cachedGetSinglePixelWidth = null;\n }\n }\n\n transform(a, b, c, d, e, f) {\n this.ctx.transform(a, b, c, d, e, f);\n this._cachedScaleForStroking = null;\n this._cachedGetSinglePixelWidth = null;\n }\n\n constructPath(ops, args, minMax) {\n const ctx = this.ctx;\n const current = this.current;\n let x = current.x,\n y = current.y;\n let startX, startY;\n const currentTransform = ctx.mozCurrentTransform;\n const isScalingMatrix = currentTransform[0] === 0 && currentTransform[3] === 0 || currentTransform[1] === 0 && currentTransform[2] === 0;\n const minMaxForBezier = isScalingMatrix ? minMax.slice(0) : null;\n\n for (let i = 0, j = 0, ii = ops.length; i < ii; i++) {\n switch (ops[i] | 0) {\n case _util.OPS.rectangle:\n x = args[j++];\n y = args[j++];\n const width = args[j++];\n const height = args[j++];\n const xw = x + width;\n const yh = y + height;\n ctx.moveTo(x, y);\n\n if (width === 0 || height === 0) {\n ctx.lineTo(xw, yh);\n } else {\n ctx.lineTo(xw, y);\n ctx.lineTo(xw, yh);\n ctx.lineTo(x, yh);\n }\n\n if (!isScalingMatrix) {\n current.updateRectMinMax(currentTransform, [x, y, xw, yh]);\n }\n\n ctx.closePath();\n break;\n\n case _util.OPS.moveTo:\n x = args[j++];\n y = args[j++];\n ctx.moveTo(x, y);\n\n if (!isScalingMatrix) {\n current.updatePathMinMax(currentTransform, x, y);\n }\n\n break;\n\n case _util.OPS.lineTo:\n x = args[j++];\n y = args[j++];\n ctx.lineTo(x, y);\n\n if (!isScalingMatrix) {\n current.updatePathMinMax(currentTransform, x, y);\n }\n\n break;\n\n case _util.OPS.curveTo:\n startX = x;\n startY = y;\n x = args[j + 4];\n y = args[j + 5];\n ctx.bezierCurveTo(args[j], args[j + 1], args[j + 2], args[j + 3], x, y);\n current.updateCurvePathMinMax(currentTransform, startX, startY, args[j], args[j + 1], args[j + 2], args[j + 3], x, y, minMaxForBezier);\n j += 6;\n break;\n\n case _util.OPS.curveTo2:\n startX = x;\n startY = y;\n ctx.bezierCurveTo(x, y, args[j], args[j + 1], args[j + 2], args[j + 3]);\n current.updateCurvePathMinMax(currentTransform, startX, startY, x, y, args[j], args[j + 1], args[j + 2], args[j + 3], minMaxForBezier);\n x = args[j + 2];\n y = args[j + 3];\n j += 4;\n break;\n\n case _util.OPS.curveTo3:\n startX = x;\n startY = y;\n x = args[j + 2];\n y = args[j + 3];\n ctx.bezierCurveTo(args[j], args[j + 1], x, y, x, y);\n current.updateCurvePathMinMax(currentTransform, startX, startY, args[j], args[j + 1], x, y, x, y, minMaxForBezier);\n j += 4;\n break;\n\n case _util.OPS.closePath:\n ctx.closePath();\n break;\n }\n }\n\n if (isScalingMatrix) {\n current.updateScalingPathMinMax(currentTransform, minMaxForBezier);\n }\n\n current.setCurrentPoint(x, y);\n }\n\n closePath() {\n this.ctx.closePath();\n }\n\n stroke(consumePath) {\n consumePath = typeof consumePath !== "undefined" ? consumePath : true;\n const ctx = this.ctx;\n const strokeColor = this.current.strokeColor;\n ctx.globalAlpha = this.current.strokeAlpha;\n\n if (this.contentVisible) {\n if (typeof strokeColor === "object" && strokeColor?.getPattern) {\n ctx.save();\n ctx.strokeStyle = strokeColor.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.STROKE);\n this.rescaleAndStroke(false);\n ctx.restore();\n } else {\n this.rescaleAndStroke(true);\n }\n }\n\n if (consumePath) {\n this.consumePath(this.current.getClippedPathBoundingBox());\n }\n\n ctx.globalAlpha = this.current.fillAlpha;\n }\n\n closeStroke() {\n this.closePath();\n this.stroke();\n }\n\n fill(consumePath) {\n consumePath = typeof consumePath !== "undefined" ? consumePath : true;\n const ctx = this.ctx;\n const fillColor = this.current.fillColor;\n const isPatternFill = this.current.patternFill;\n let needRestore = false;\n\n if (isPatternFill) {\n ctx.save();\n ctx.fillStyle = fillColor.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.FILL);\n needRestore = true;\n }\n\n const intersect = this.current.getClippedPathBoundingBox();\n\n if (this.contentVisible && intersect !== null) {\n if (this.pendingEOFill) {\n ctx.fill("evenodd");\n this.pendingEOFill = false;\n } else {\n ctx.fill();\n }\n }\n\n if (needRestore) {\n ctx.restore();\n }\n\n if (consumePath) {\n this.consumePath(intersect);\n }\n }\n\n eoFill() {\n this.pendingEOFill = true;\n this.fill();\n }\n\n fillStroke() {\n this.fill(false);\n this.stroke(false);\n this.consumePath();\n }\n\n eoFillStroke() {\n this.pendingEOFill = true;\n this.fillStroke();\n }\n\n closeFillStroke() {\n this.closePath();\n this.fillStroke();\n }\n\n closeEOFillStroke() {\n this.pendingEOFill = true;\n this.closePath();\n this.fillStroke();\n }\n\n endPath() {\n this.consumePath();\n }\n\n clip() {\n this.pendingClip = NORMAL_CLIP;\n }\n\n eoClip() {\n this.pendingClip = EO_CLIP;\n }\n\n beginText() {\n this.current.textMatrix = _util.IDENTITY_MATRIX;\n this.current.textMatrixScale = 1;\n this.current.x = this.current.lineX = 0;\n this.current.y = this.current.lineY = 0;\n }\n\n endText() {\n const paths = this.pendingTextPaths;\n const ctx = this.ctx;\n\n if (paths === undefined) {\n ctx.beginPath();\n return;\n }\n\n ctx.save();\n ctx.beginPath();\n\n for (let i = 0; i < paths.length; i++) {\n const path = paths[i];\n ctx.setTransform.apply(ctx, path.transform);\n ctx.translate(path.x, path.y);\n path.addToPath(ctx, path.fontSize);\n }\n\n ctx.restore();\n ctx.clip();\n ctx.beginPath();\n delete this.pendingTextPaths;\n }\n\n setCharSpacing(spacing) {\n this.current.charSpacing = spacing;\n }\n\n setWordSpacing(spacing) {\n this.current.wordSpacing = spacing;\n }\n\n setHScale(scale) {\n this.current.textHScale = scale / 100;\n }\n\n setLeading(leading) {\n this.current.leading = -leading;\n }\n\n setFont(fontRefName, size) {\n const fontObj = this.commonObjs.get(fontRefName);\n const current = this.current;\n\n if (!fontObj) {\n throw new Error(`Can\'t find font for ${fontRefName}`);\n }\n\n current.fontMatrix = fontObj.fontMatrix || _util.FONT_IDENTITY_MATRIX;\n\n if (current.fontMatrix[0] === 0 || current.fontMatrix[3] === 0) {\n (0, _util.warn)("Invalid font matrix for font " + fontRefName);\n }\n\n if (size < 0) {\n size = -size;\n current.fontDirection = -1;\n } else {\n current.fontDirection = 1;\n }\n\n this.current.font = fontObj;\n this.current.fontSize = size;\n\n if (fontObj.isType3Font) {\n return;\n }\n\n const name = fontObj.loadedName || "sans-serif";\n let bold = "normal";\n\n if (fontObj.black) {\n bold = "900";\n } else if (fontObj.bold) {\n bold = "bold";\n }\n\n const italic = fontObj.italic ? "italic" : "normal";\n const typeface = `"${name}", ${fontObj.fallbackName}`;\n let browserFontSize = size;\n\n if (size < MIN_FONT_SIZE) {\n browserFontSize = MIN_FONT_SIZE;\n } else if (size > MAX_FONT_SIZE) {\n browserFontSize = MAX_FONT_SIZE;\n }\n\n this.current.fontSizeScale = size / browserFontSize;\n this.ctx.font = `${italic} ${bold} ${browserFontSize}px ${typeface}`;\n }\n\n setTextRenderingMode(mode) {\n this.current.textRenderingMode = mode;\n }\n\n setTextRise(rise) {\n this.current.textRise = rise;\n }\n\n moveText(x, y) {\n this.current.x = this.current.lineX += x;\n this.current.y = this.current.lineY += y;\n }\n\n setLeadingMoveText(x, y) {\n this.setLeading(-y);\n this.moveText(x, y);\n }\n\n setTextMatrix(a, b, c, d, e, f) {\n this.current.textMatrix = [a, b, c, d, e, f];\n this.current.textMatrixScale = Math.hypot(a, b);\n this.current.x = this.current.lineX = 0;\n this.current.y = this.current.lineY = 0;\n }\n\n nextLine() {\n this.moveText(0, this.current.leading);\n }\n\n paintChar(character, x, y, patternTransform) {\n const ctx = this.ctx;\n const current = this.current;\n const font = current.font;\n const textRenderingMode = current.textRenderingMode;\n const fontSize = current.fontSize / current.fontSizeScale;\n const fillStrokeMode = textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK;\n const isAddToPathSet = !!(textRenderingMode & _util.TextRenderingMode.ADD_TO_PATH_FLAG);\n const patternFill = current.patternFill && !font.missingFile;\n let addToPath;\n\n if (font.disableFontFace || isAddToPathSet || patternFill) {\n addToPath = font.getPathGenerator(this.commonObjs, character);\n }\n\n if (font.disableFontFace || patternFill) {\n ctx.save();\n ctx.translate(x, y);\n ctx.beginPath();\n addToPath(ctx, fontSize);\n\n if (patternTransform) {\n ctx.setTransform.apply(ctx, patternTransform);\n }\n\n if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) {\n ctx.fill();\n }\n\n if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) {\n ctx.stroke();\n }\n\n ctx.restore();\n } else {\n if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) {\n ctx.fillText(character, x, y);\n }\n\n if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) {\n ctx.strokeText(character, x, y);\n }\n }\n\n if (isAddToPathSet) {\n const paths = this.pendingTextPaths || (this.pendingTextPaths = []);\n paths.push({\n transform: ctx.mozCurrentTransform,\n x,\n y,\n fontSize,\n addToPath\n });\n }\n }\n\n get isFontSubpixelAAEnabled() {\n const {\n context: ctx\n } = this.cachedCanvases.getCanvas("isFontSubpixelAAEnabled", 10, 10, false);\n ctx.scale(1.5, 1);\n ctx.fillText("I", 0, 10);\n const data = ctx.getImageData(0, 0, 10, 10).data;\n let enabled = false;\n\n for (let i = 3; i < data.length; i += 4) {\n if (data[i] > 0 && data[i] < 255) {\n enabled = true;\n break;\n }\n }\n\n return (0, _util.shadow)(this, "isFontSubpixelAAEnabled", enabled);\n }\n\n showText(glyphs) {\n const current = this.current;\n const font = current.font;\n\n if (font.isType3Font) {\n return this.showType3Text(glyphs);\n }\n\n const fontSize = current.fontSize;\n\n if (fontSize === 0) {\n return undefined;\n }\n\n const ctx = this.ctx;\n const fontSizeScale = current.fontSizeScale;\n const charSpacing = current.charSpacing;\n const wordSpacing = current.wordSpacing;\n const fontDirection = current.fontDirection;\n const textHScale = current.textHScale * fontDirection;\n const glyphsLength = glyphs.length;\n const vertical = font.vertical;\n const spacingDir = vertical ? 1 : -1;\n const defaultVMetrics = font.defaultVMetrics;\n const widthAdvanceScale = fontSize * current.fontMatrix[0];\n const simpleFillText = current.textRenderingMode === _util.TextRenderingMode.FILL && !font.disableFontFace && !current.patternFill;\n ctx.save();\n ctx.transform.apply(ctx, current.textMatrix);\n ctx.translate(current.x, current.y + current.textRise);\n\n if (fontDirection > 0) {\n ctx.scale(textHScale, -1);\n } else {\n ctx.scale(textHScale, 1);\n }\n\n let patternTransform;\n\n if (current.patternFill) {\n ctx.save();\n const pattern = current.fillColor.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.FILL);\n patternTransform = ctx.mozCurrentTransform;\n ctx.restore();\n ctx.fillStyle = pattern;\n }\n\n let lineWidth = current.lineWidth;\n const scale = current.textMatrixScale;\n\n if (scale === 0 || lineWidth === 0) {\n const fillStrokeMode = current.textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK;\n\n if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) {\n lineWidth = this.getSinglePixelWidth();\n }\n } else {\n lineWidth /= scale;\n }\n\n if (fontSizeScale !== 1.0) {\n ctx.scale(fontSizeScale, fontSizeScale);\n lineWidth /= fontSizeScale;\n }\n\n ctx.lineWidth = lineWidth;\n let x = 0,\n i;\n\n for (i = 0; i < glyphsLength; ++i) {\n const glyph = glyphs[i];\n\n if (typeof glyph === "number") {\n x += spacingDir * glyph * fontSize / 1000;\n continue;\n }\n\n let restoreNeeded = false;\n const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing;\n const character = glyph.fontChar;\n const accent = glyph.accent;\n let scaledX, scaledY;\n let width = glyph.width;\n\n if (vertical) {\n const vmetric = glyph.vmetric || defaultVMetrics;\n const vx = -(glyph.vmetric ? vmetric[1] : width * 0.5) * widthAdvanceScale;\n const vy = vmetric[2] * widthAdvanceScale;\n width = vmetric ? -vmetric[0] : width;\n scaledX = vx / fontSizeScale;\n scaledY = (x + vy) / fontSizeScale;\n } else {\n scaledX = x / fontSizeScale;\n scaledY = 0;\n }\n\n if (font.remeasure && width > 0) {\n const measuredWidth = ctx.measureText(character).width * 1000 / fontSize * fontSizeScale;\n\n if (width < measuredWidth && this.isFontSubpixelAAEnabled) {\n const characterScaleX = width / measuredWidth;\n restoreNeeded = true;\n ctx.save();\n ctx.scale(characterScaleX, 1);\n scaledX /= characterScaleX;\n } else if (width !== measuredWidth) {\n scaledX += (width - measuredWidth) / 2000 * fontSize / fontSizeScale;\n }\n }\n\n if (this.contentVisible && (glyph.isInFont || font.missingFile)) {\n if (simpleFillText && !accent) {\n ctx.fillText(character, scaledX, scaledY);\n } else {\n this.paintChar(character, scaledX, scaledY, patternTransform);\n\n if (accent) {\n const scaledAccentX = scaledX + fontSize * accent.offset.x / fontSizeScale;\n const scaledAccentY = scaledY - fontSize * accent.offset.y / fontSizeScale;\n this.paintChar(accent.fontChar, scaledAccentX, scaledAccentY, patternTransform);\n }\n }\n }\n\n let charWidth;\n\n if (vertical) {\n charWidth = width * widthAdvanceScale - spacing * fontDirection;\n } else {\n charWidth = width * widthAdvanceScale + spacing * fontDirection;\n }\n\n x += charWidth;\n\n if (restoreNeeded) {\n ctx.restore();\n }\n }\n\n if (vertical) {\n current.y -= x;\n } else {\n current.x += x * textHScale;\n }\n\n ctx.restore();\n this.compose();\n return undefined;\n }\n\n showType3Text(glyphs) {\n const ctx = this.ctx;\n const current = this.current;\n const font = current.font;\n const fontSize = current.fontSize;\n const fontDirection = current.fontDirection;\n const spacingDir = font.vertical ? 1 : -1;\n const charSpacing = current.charSpacing;\n const wordSpacing = current.wordSpacing;\n const textHScale = current.textHScale * fontDirection;\n const fontMatrix = current.fontMatrix || _util.FONT_IDENTITY_MATRIX;\n const glyphsLength = glyphs.length;\n const isTextInvisible = current.textRenderingMode === _util.TextRenderingMode.INVISIBLE;\n let i, glyph, width, spacingLength;\n\n if (isTextInvisible || fontSize === 0) {\n return;\n }\n\n this._cachedScaleForStroking = null;\n this._cachedGetSinglePixelWidth = null;\n ctx.save();\n ctx.transform.apply(ctx, current.textMatrix);\n ctx.translate(current.x, current.y);\n ctx.scale(textHScale, fontDirection);\n\n for (i = 0; i < glyphsLength; ++i) {\n glyph = glyphs[i];\n\n if (typeof glyph === "number") {\n spacingLength = spacingDir * glyph * fontSize / 1000;\n this.ctx.translate(spacingLength, 0);\n current.x += spacingLength * textHScale;\n continue;\n }\n\n const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing;\n const operatorList = font.charProcOperatorList[glyph.operatorListId];\n\n if (!operatorList) {\n (0, _util.warn)(`Type3 character "${glyph.operatorListId}" is not available.`);\n continue;\n }\n\n if (this.contentVisible) {\n this.processingType3 = glyph;\n this.save();\n ctx.scale(fontSize, fontSize);\n ctx.transform.apply(ctx, fontMatrix);\n this.executeOperatorList(operatorList);\n this.restore();\n }\n\n const transformed = _util.Util.applyTransform([glyph.width, 0], fontMatrix);\n\n width = transformed[0] * fontSize + spacing;\n ctx.translate(width, 0);\n current.x += width * textHScale;\n }\n\n ctx.restore();\n this.processingType3 = null;\n }\n\n setCharWidth(xWidth, yWidth) {}\n\n setCharWidthAndBounds(xWidth, yWidth, llx, lly, urx, ury) {\n this.ctx.rect(llx, lly, urx - llx, ury - lly);\n this.ctx.clip();\n this.endPath();\n }\n\n getColorN_Pattern(IR) {\n let pattern;\n\n if (IR[0] === "TilingPattern") {\n const color = IR[1];\n const baseTransform = this.baseTransform || this.ctx.mozCurrentTransform.slice();\n const canvasGraphicsFactory = {\n createCanvasGraphics: ctx => {\n return new CanvasGraphics(ctx, this.commonObjs, this.objs, this.canvasFactory);\n }\n };\n pattern = new _pattern_helper.TilingPattern(IR, color, this.ctx, canvasGraphicsFactory, baseTransform);\n } else {\n pattern = this._getPattern(IR[1], IR[2]);\n }\n\n return pattern;\n }\n\n setStrokeColorN() {\n this.current.strokeColor = this.getColorN_Pattern(arguments);\n }\n\n setFillColorN() {\n this.current.fillColor = this.getColorN_Pattern(arguments);\n this.current.patternFill = true;\n }\n\n setStrokeRGBColor(r, g, b) {\n const color = this.selectColor?.(r, g, b) || _util.Util.makeHexColor(r, g, b);\n\n this.ctx.strokeStyle = color;\n this.current.strokeColor = color;\n }\n\n setFillRGBColor(r, g, b) {\n const color = this.selectColor?.(r, g, b) || _util.Util.makeHexColor(r, g, b);\n\n this.ctx.fillStyle = color;\n this.current.fillColor = color;\n this.current.patternFill = false;\n }\n\n _getPattern(objId, matrix = null) {\n let pattern;\n\n if (this.cachedPatterns.has(objId)) {\n pattern = this.cachedPatterns.get(objId);\n } else {\n pattern = (0, _pattern_helper.getShadingPattern)(this.objs.get(objId));\n this.cachedPatterns.set(objId, pattern);\n }\n\n if (matrix) {\n pattern.matrix = matrix;\n }\n\n return pattern;\n }\n\n shadingFill(objId) {\n if (!this.contentVisible) {\n return;\n }\n\n const ctx = this.ctx;\n this.save();\n\n const pattern = this._getPattern(objId);\n\n ctx.fillStyle = pattern.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.SHADING);\n const inv = ctx.mozCurrentTransformInverse;\n\n if (inv) {\n const canvas = ctx.canvas;\n const width = canvas.width;\n const height = canvas.height;\n\n const bl = _util.Util.applyTransform([0, 0], inv);\n\n const br = _util.Util.applyTransform([0, height], inv);\n\n const ul = _util.Util.applyTransform([width, 0], inv);\n\n const ur = _util.Util.applyTransform([width, height], inv);\n\n const x0 = Math.min(bl[0], br[0], ul[0], ur[0]);\n const y0 = Math.min(bl[1], br[1], ul[1], ur[1]);\n const x1 = Math.max(bl[0], br[0], ul[0], ur[0]);\n const y1 = Math.max(bl[1], br[1], ul[1], ur[1]);\n this.ctx.fillRect(x0, y0, x1 - x0, y1 - y0);\n } else {\n this.ctx.fillRect(-1e10, -1e10, 2e10, 2e10);\n }\n\n this.compose(this.current.getClippedPathBoundingBox());\n this.restore();\n }\n\n beginInlineImage() {\n (0, _util.unreachable)("Should not call beginInlineImage");\n }\n\n beginImageData() {\n (0, _util.unreachable)("Should not call beginImageData");\n }\n\n paintFormXObjectBegin(matrix, bbox) {\n if (!this.contentVisible) {\n return;\n }\n\n this.save();\n this.baseTransformStack.push(this.baseTransform);\n\n if (Array.isArray(matrix) && matrix.length === 6) {\n this.transform.apply(this, matrix);\n }\n\n this.baseTransform = this.ctx.mozCurrentTransform;\n\n if (bbox) {\n const width = bbox[2] - bbox[0];\n const height = bbox[3] - bbox[1];\n this.ctx.rect(bbox[0], bbox[1], width, height);\n this.current.updateRectMinMax(this.ctx.mozCurrentTransform, bbox);\n this.clip();\n this.endPath();\n }\n }\n\n paintFormXObjectEnd() {\n if (!this.contentVisible) {\n return;\n }\n\n this.restore();\n this.baseTransform = this.baseTransformStack.pop();\n }\n\n beginGroup(group) {\n if (!this.contentVisible) {\n return;\n }\n\n this.save();\n\n if (this.inSMaskMode) {\n this.endSMaskMode();\n this.current.activeSMask = null;\n }\n\n const currentCtx = this.ctx;\n\n if (!group.isolated) {\n (0, _util.info)("TODO: Support non-isolated groups.");\n }\n\n if (group.knockout) {\n (0, _util.warn)("Knockout groups not supported.");\n }\n\n const currentTransform = currentCtx.mozCurrentTransform;\n\n if (group.matrix) {\n currentCtx.transform.apply(currentCtx, group.matrix);\n }\n\n if (!group.bbox) {\n throw new Error("Bounding box is required.");\n }\n\n let bounds = _util.Util.getAxialAlignedBoundingBox(group.bbox, currentCtx.mozCurrentTransform);\n\n const canvasBounds = [0, 0, currentCtx.canvas.width, currentCtx.canvas.height];\n bounds = _util.Util.intersect(bounds, canvasBounds) || [0, 0, 0, 0];\n const offsetX = Math.floor(bounds[0]);\n const offsetY = Math.floor(bounds[1]);\n let drawnWidth = Math.max(Math.ceil(bounds[2]) - offsetX, 1);\n let drawnHeight = Math.max(Math.ceil(bounds[3]) - offsetY, 1);\n let scaleX = 1,\n scaleY = 1;\n\n if (drawnWidth > MAX_GROUP_SIZE) {\n scaleX = drawnWidth / MAX_GROUP_SIZE;\n drawnWidth = MAX_GROUP_SIZE;\n }\n\n if (drawnHeight > MAX_GROUP_SIZE) {\n scaleY = drawnHeight / MAX_GROUP_SIZE;\n drawnHeight = MAX_GROUP_SIZE;\n }\n\n this.current.startNewPathAndClipBox([0, 0, drawnWidth, drawnHeight]);\n let cacheId = "groupAt" + this.groupLevel;\n\n if (group.smask) {\n cacheId += "_smask_" + this.smaskCounter++ % 2;\n }\n\n const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight, true);\n const groupCtx = scratchCanvas.context;\n groupCtx.scale(1 / scaleX, 1 / scaleY);\n groupCtx.translate(-offsetX, -offsetY);\n groupCtx.transform.apply(groupCtx, currentTransform);\n\n if (group.smask) {\n this.smaskStack.push({\n canvas: scratchCanvas.canvas,\n context: groupCtx,\n offsetX,\n offsetY,\n scaleX,\n scaleY,\n subtype: group.smask.subtype,\n backdrop: group.smask.backdrop,\n transferMap: group.smask.transferMap || null,\n startTransformInverse: null\n });\n } else {\n currentCtx.setTransform(1, 0, 0, 1, 0, 0);\n currentCtx.translate(offsetX, offsetY);\n currentCtx.scale(scaleX, scaleY);\n currentCtx.save();\n }\n\n copyCtxState(currentCtx, groupCtx);\n this.ctx = groupCtx;\n this.setGState([["BM", "source-over"], ["ca", 1], ["CA", 1]]);\n this.groupStack.push(currentCtx);\n this.groupLevel++;\n }\n\n endGroup(group) {\n if (!this.contentVisible) {\n return;\n }\n\n this.groupLevel--;\n const groupCtx = this.ctx;\n const ctx = this.groupStack.pop();\n this.ctx = ctx;\n this.ctx.imageSmoothingEnabled = false;\n\n if (group.smask) {\n this.tempSMask = this.smaskStack.pop();\n this.restore();\n } else {\n this.ctx.restore();\n const currentMtx = this.ctx.mozCurrentTransform;\n this.restore();\n this.ctx.save();\n this.ctx.setTransform.apply(this.ctx, currentMtx);\n\n const dirtyBox = _util.Util.getAxialAlignedBoundingBox([0, 0, groupCtx.canvas.width, groupCtx.canvas.height], currentMtx);\n\n this.ctx.drawImage(groupCtx.canvas, 0, 0);\n this.ctx.restore();\n this.compose(dirtyBox);\n }\n }\n\n beginAnnotations() {\n this.save();\n\n if (this.baseTransform) {\n this.ctx.setTransform.apply(this.ctx, this.baseTransform);\n }\n }\n\n endAnnotations() {\n this.restore();\n }\n\n beginAnnotation(id, rect, transform, matrix, hasOwnCanvas) {\n this.save();\n\n if (Array.isArray(rect) && rect.length === 4) {\n const width = rect[2] - rect[0];\n const height = rect[3] - rect[1];\n\n if (hasOwnCanvas && this.annotationCanvasMap) {\n transform = transform.slice();\n transform[4] -= rect[0];\n transform[5] -= rect[1];\n rect = rect.slice();\n rect[0] = rect[1] = 0;\n rect[2] = width;\n rect[3] = height;\n\n const [scaleX, scaleY] = _util.Util.singularValueDecompose2dScale(this.ctx.mozCurrentTransform);\n\n const {\n viewportScale\n } = this;\n const canvasWidth = Math.ceil(width * this.outputScaleX * viewportScale);\n const canvasHeight = Math.ceil(height * this.outputScaleY * viewportScale);\n this.annotationCanvas = this.canvasFactory.create(canvasWidth, canvasHeight);\n const {\n canvas,\n context\n } = this.annotationCanvas;\n const viewportScaleFactorStr = `var(--zoom-factor) * ${_display_utils.PixelsPerInch.PDF_TO_CSS_UNITS}`;\n canvas.style.width = `calc(${width}px * ${viewportScaleFactorStr})`;\n canvas.style.height = `calc(${height}px * ${viewportScaleFactorStr})`;\n this.annotationCanvasMap.set(id, canvas);\n this.annotationCanvas.savedCtx = this.ctx;\n this.ctx = context;\n this.ctx.setTransform(scaleX, 0, 0, -scaleY, 0, height * scaleY);\n addContextCurrentTransform(this.ctx);\n resetCtxToDefault(this.ctx, this.foregroundColor);\n } else {\n resetCtxToDefault(this.ctx, this.foregroundColor);\n this.ctx.rect(rect[0], rect[1], width, height);\n this.ctx.clip();\n this.endPath();\n }\n }\n\n this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height);\n this.transform.apply(this, transform);\n this.transform.apply(this, matrix);\n }\n\n endAnnotation() {\n if (this.annotationCanvas) {\n this.ctx = this.annotationCanvas.savedCtx;\n delete this.annotationCanvas.savedCtx;\n delete this.annotationCanvas;\n }\n\n this.restore();\n }\n\n paintImageMaskXObject(img) {\n if (!this.contentVisible) {\n return;\n }\n\n const count = img.count;\n img = this.getObject(img.data, img);\n img.count = count;\n const ctx = this.ctx;\n const glyph = this.processingType3;\n\n if (glyph) {\n if (glyph.compiled === undefined) {\n glyph.compiled = compileType3Glyph(img);\n }\n\n if (glyph.compiled) {\n glyph.compiled(ctx);\n return;\n }\n }\n\n const mask = this._createMaskCanvas(img);\n\n const maskCanvas = mask.canvas;\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.drawImage(maskCanvas, mask.offsetX, mask.offsetY);\n ctx.restore();\n this.compose();\n }\n\n paintImageMaskXObjectRepeat(img, scaleX, skewX = 0, skewY = 0, scaleY, positions) {\n if (!this.contentVisible) {\n return;\n }\n\n img = this.getObject(img.data, img);\n const ctx = this.ctx;\n ctx.save();\n const currentTransform = ctx.mozCurrentTransform;\n ctx.transform(scaleX, skewX, skewY, scaleY, 0, 0);\n\n const mask = this._createMaskCanvas(img);\n\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n\n for (let i = 0, ii = positions.length; i < ii; i += 2) {\n const trans = _util.Util.transform(currentTransform, [scaleX, skewX, skewY, scaleY, positions[i], positions[i + 1]]);\n\n const [x, y] = _util.Util.applyTransform([0, 0], trans);\n\n ctx.drawImage(mask.canvas, x, y);\n }\n\n ctx.restore();\n this.compose();\n }\n\n paintImageMaskXObjectGroup(images) {\n if (!this.contentVisible) {\n return;\n }\n\n const ctx = this.ctx;\n const fillColor = this.current.fillColor;\n const isPatternFill = this.current.patternFill;\n\n for (let i = 0, ii = images.length; i < ii; i++) {\n const image = images[i];\n const width = image.width,\n height = image.height;\n const maskCanvas = this.cachedCanvases.getCanvas("maskCanvas", width, height, false);\n const maskCtx = maskCanvas.context;\n maskCtx.save();\n putBinaryImageMask(maskCtx, image);\n maskCtx.globalCompositeOperation = "source-in";\n maskCtx.fillStyle = isPatternFill ? fillColor.getPattern(maskCtx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.FILL) : fillColor;\n maskCtx.fillRect(0, 0, width, height);\n maskCtx.restore();\n ctx.save();\n ctx.transform.apply(ctx, image.transform);\n ctx.scale(1, -1);\n drawImageAtIntegerCoords(ctx, maskCanvas.canvas, 0, 0, width, height, 0, -1, 1, 1);\n ctx.restore();\n }\n\n this.compose();\n }\n\n paintImageXObject(objId) {\n if (!this.contentVisible) {\n return;\n }\n\n const imgData = this.getObject(objId);\n\n if (!imgData) {\n (0, _util.warn)("Dependent image isn\'t ready yet");\n return;\n }\n\n this.paintInlineImageXObject(imgData);\n }\n\n paintImageXObjectRepeat(objId, scaleX, scaleY, positions) {\n if (!this.contentVisible) {\n return;\n }\n\n const imgData = this.getObject(objId);\n\n if (!imgData) {\n (0, _util.warn)("Dependent image isn\'t ready yet");\n return;\n }\n\n const width = imgData.width;\n const height = imgData.height;\n const map = [];\n\n for (let i = 0, ii = positions.length; i < ii; i += 2) {\n map.push({\n transform: [scaleX, 0, 0, scaleY, positions[i], positions[i + 1]],\n x: 0,\n y: 0,\n w: width,\n h: height\n });\n }\n\n this.paintInlineImageXObjectGroup(imgData, map);\n }\n\n paintInlineImageXObject(imgData) {\n if (!this.contentVisible) {\n return;\n }\n\n const width = imgData.width;\n const height = imgData.height;\n const ctx = this.ctx;\n this.save();\n ctx.scale(1 / width, -1 / height);\n let imgToPaint;\n\n if (typeof HTMLElement === "function" && imgData instanceof HTMLElement || !imgData.data) {\n imgToPaint = imgData;\n } else {\n const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", width, height, false);\n const tmpCtx = tmpCanvas.context;\n putBinaryImageData(tmpCtx, imgData, this.current.transferMaps);\n imgToPaint = tmpCanvas.canvas;\n }\n\n const scaled = this._scaleImage(imgToPaint, ctx.mozCurrentTransformInverse);\n\n ctx.imageSmoothingEnabled = getImageSmoothingEnabled(ctx.mozCurrentTransform, imgData.interpolate);\n const [rWidth, rHeight] = drawImageAtIntegerCoords(ctx, scaled.img, 0, 0, scaled.paintWidth, scaled.paintHeight, 0, -height, width, height);\n\n if (this.imageLayer) {\n const position = this.getCanvasPosition(0, -height);\n this.imageLayer.appendImage({\n imgData,\n left: position[0],\n top: position[1],\n width: rWidth,\n height: rHeight\n });\n }\n\n this.compose();\n this.restore();\n }\n\n paintInlineImageXObjectGroup(imgData, map) {\n if (!this.contentVisible) {\n return;\n }\n\n const ctx = this.ctx;\n const w = imgData.width;\n const h = imgData.height;\n const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", w, h, false);\n const tmpCtx = tmpCanvas.context;\n putBinaryImageData(tmpCtx, imgData, this.current.transferMaps);\n\n for (let i = 0, ii = map.length; i < ii; i++) {\n const entry = map[i];\n ctx.save();\n ctx.transform.apply(ctx, entry.transform);\n ctx.scale(1, -1);\n drawImageAtIntegerCoords(ctx, tmpCanvas.canvas, entry.x, entry.y, entry.w, entry.h, 0, -1, 1, 1);\n\n if (this.imageLayer) {\n const position = this.getCanvasPosition(entry.x, entry.y);\n this.imageLayer.appendImage({\n imgData,\n left: position[0],\n top: position[1],\n width: w,\n height: h\n });\n }\n\n ctx.restore();\n }\n\n this.compose();\n }\n\n paintSolidColorImageMask() {\n if (!this.contentVisible) {\n return;\n }\n\n this.ctx.fillRect(0, 0, 1, 1);\n this.compose();\n }\n\n markPoint(tag) {}\n\n markPointProps(tag, properties) {}\n\n beginMarkedContent(tag) {\n this.markedContentStack.push({\n visible: true\n });\n }\n\n beginMarkedContentProps(tag, properties) {\n if (tag === "OC") {\n this.markedContentStack.push({\n visible: this.optionalContentConfig.isVisible(properties)\n });\n } else {\n this.markedContentStack.push({\n visible: true\n });\n }\n\n this.contentVisible = this.isContentVisible();\n }\n\n endMarkedContent() {\n this.markedContentStack.pop();\n this.contentVisible = this.isContentVisible();\n }\n\n beginCompat() {}\n\n endCompat() {}\n\n consumePath(clipBox) {\n const isEmpty = this.current.isEmptyClip();\n\n if (this.pendingClip) {\n this.current.updateClipFromPath();\n }\n\n if (!this.pendingClip) {\n this.compose(clipBox);\n }\n\n const ctx = this.ctx;\n\n if (this.pendingClip) {\n if (!isEmpty) {\n if (this.pendingClip === EO_CLIP) {\n ctx.clip("evenodd");\n } else {\n ctx.clip();\n }\n }\n\n this.pendingClip = null;\n }\n\n this.current.startNewPathAndClipBox(this.current.clipBox);\n ctx.beginPath();\n }\n\n getSinglePixelWidth() {\n if (!this._cachedGetSinglePixelWidth) {\n const m = this.ctx.mozCurrentTransform;\n\n if (m[1] === 0 && m[2] === 0) {\n this._cachedGetSinglePixelWidth = 1 / Math.min(Math.abs(m[0]), Math.abs(m[3]));\n } else {\n const absDet = Math.abs(m[0] * m[3] - m[2] * m[1]);\n const normX = Math.hypot(m[0], m[2]);\n const normY = Math.hypot(m[1], m[3]);\n this._cachedGetSinglePixelWidth = Math.max(normX, normY) / absDet;\n }\n }\n\n return this._cachedGetSinglePixelWidth;\n }\n\n getScaleForStroking() {\n if (!this._cachedScaleForStroking) {\n const {\n lineWidth\n } = this.current;\n const m = this.ctx.mozCurrentTransform;\n let scaleX, scaleY;\n\n if (m[1] === 0 && m[2] === 0) {\n const normX = Math.abs(m[0]);\n const normY = Math.abs(m[3]);\n\n if (lineWidth === 0) {\n scaleX = 1 / normX;\n scaleY = 1 / normY;\n } else {\n const scaledXLineWidth = normX * lineWidth;\n const scaledYLineWidth = normY * lineWidth;\n scaleX = scaledXLineWidth < 1 ? 1 / scaledXLineWidth : 1;\n scaleY = scaledYLineWidth < 1 ? 1 / scaledYLineWidth : 1;\n }\n } else {\n const absDet = Math.abs(m[0] * m[3] - m[2] * m[1]);\n const normX = Math.hypot(m[0], m[1]);\n const normY = Math.hypot(m[2], m[3]);\n\n if (lineWidth === 0) {\n scaleX = normY / absDet;\n scaleY = normX / absDet;\n } else {\n const baseArea = lineWidth * absDet;\n scaleX = normY > baseArea ? normY / baseArea : 1;\n scaleY = normX > baseArea ? normX / baseArea : 1;\n }\n }\n\n this._cachedScaleForStroking = [scaleX, scaleY];\n }\n\n return this._cachedScaleForStroking;\n }\n\n rescaleAndStroke(saveRestore) {\n const {\n ctx\n } = this;\n const {\n lineWidth\n } = this.current;\n const [scaleX, scaleY] = this.getScaleForStroking();\n ctx.lineWidth = lineWidth || 1;\n\n if (scaleX === 1 && scaleY === 1) {\n ctx.stroke();\n return;\n }\n\n let savedMatrix, savedDashes, savedDashOffset;\n\n if (saveRestore) {\n savedMatrix = ctx.mozCurrentTransform.slice();\n savedDashes = ctx.getLineDash().slice();\n savedDashOffset = ctx.lineDashOffset;\n }\n\n ctx.scale(scaleX, scaleY);\n const scale = Math.max(scaleX, scaleY);\n ctx.setLineDash(ctx.getLineDash().map(x => x / scale));\n ctx.lineDashOffset /= scale;\n ctx.stroke();\n\n if (saveRestore) {\n ctx.setTransform(...savedMatrix);\n ctx.setLineDash(savedDashes);\n ctx.lineDashOffset = savedDashOffset;\n }\n }\n\n getCanvasPosition(x, y) {\n const transform = this.ctx.mozCurrentTransform;\n return [transform[0] * x + transform[2] * y + transform[4], transform[1] * x + transform[3] * y + transform[5]];\n }\n\n isContentVisible() {\n for (let i = this.markedContentStack.length - 1; i >= 0; i--) {\n if (!this.markedContentStack[i].visible) {\n return false;\n }\n }\n\n return true;\n }\n\n}\n\nexports.CanvasGraphics = CanvasGraphics;\n\nfor (const op in _util.OPS) {\n if (CanvasGraphics.prototype[op] !== undefined) {\n CanvasGraphics.prototype[_util.OPS[op]] = CanvasGraphics.prototype[op];\n }\n}\n\n/***/ }),\n/* 11 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.TilingPattern = exports.PathType = void 0;\nexports.getShadingPattern = getShadingPattern;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _is_node = __w_pdfjs_require__(3);\n\nconst PathType = {\n FILL: "Fill",\n STROKE: "Stroke",\n SHADING: "Shading"\n};\nexports.PathType = PathType;\n\nfunction applyBoundingBox(ctx, bbox) {\n if (!bbox || _is_node.isNodeJS) {\n return;\n }\n\n const width = bbox[2] - bbox[0];\n const height = bbox[3] - bbox[1];\n const region = new Path2D();\n region.rect(bbox[0], bbox[1], width, height);\n ctx.clip(region);\n}\n\nclass BaseShadingPattern {\n constructor() {\n if (this.constructor === BaseShadingPattern) {\n (0, _util.unreachable)("Cannot initialize BaseShadingPattern.");\n }\n }\n\n getPattern() {\n (0, _util.unreachable)("Abstract method `getPattern` called.");\n }\n\n}\n\nclass RadialAxialShadingPattern extends BaseShadingPattern {\n constructor(IR) {\n super();\n this._type = IR[1];\n this._bbox = IR[2];\n this._colorStops = IR[3];\n this._p0 = IR[4];\n this._p1 = IR[5];\n this._r0 = IR[6];\n this._r1 = IR[7];\n this.matrix = null;\n }\n\n _createGradient(ctx) {\n let grad;\n\n if (this._type === "axial") {\n grad = ctx.createLinearGradient(this._p0[0], this._p0[1], this._p1[0], this._p1[1]);\n } else if (this._type === "radial") {\n grad = ctx.createRadialGradient(this._p0[0], this._p0[1], this._r0, this._p1[0], this._p1[1], this._r1);\n }\n\n for (const colorStop of this._colorStops) {\n grad.addColorStop(colorStop[0], colorStop[1]);\n }\n\n return grad;\n }\n\n getPattern(ctx, owner, inverse, pathType) {\n let pattern;\n\n if (pathType === PathType.STROKE || pathType === PathType.FILL) {\n const ownerBBox = owner.current.getClippedPathBoundingBox(pathType, ctx.mozCurrentTransform) || [0, 0, 0, 0];\n const width = Math.ceil(ownerBBox[2] - ownerBBox[0]) || 1;\n const height = Math.ceil(ownerBBox[3] - ownerBBox[1]) || 1;\n const tmpCanvas = owner.cachedCanvases.getCanvas("pattern", width, height, true);\n const tmpCtx = tmpCanvas.context;\n tmpCtx.clearRect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height);\n tmpCtx.beginPath();\n tmpCtx.rect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height);\n tmpCtx.translate(-ownerBBox[0], -ownerBBox[1]);\n inverse = _util.Util.transform(inverse, [1, 0, 0, 1, ownerBBox[0], ownerBBox[1]]);\n tmpCtx.transform.apply(tmpCtx, owner.baseTransform);\n\n if (this.matrix) {\n tmpCtx.transform.apply(tmpCtx, this.matrix);\n }\n\n applyBoundingBox(tmpCtx, this._bbox);\n tmpCtx.fillStyle = this._createGradient(tmpCtx);\n tmpCtx.fill();\n pattern = ctx.createPattern(tmpCanvas.canvas, "no-repeat");\n const domMatrix = new DOMMatrix(inverse);\n\n try {\n pattern.setTransform(domMatrix);\n } catch (ex) {\n (0, _util.warn)(`RadialAxialShadingPattern.getPattern: "${ex?.message}".`);\n }\n } else {\n applyBoundingBox(ctx, this._bbox);\n pattern = this._createGradient(ctx);\n }\n\n return pattern;\n }\n\n}\n\nfunction drawTriangle(data, context, p1, p2, p3, c1, c2, c3) {\n const coords = context.coords,\n colors = context.colors;\n const bytes = data.data,\n rowSize = data.width * 4;\n let tmp;\n\n if (coords[p1 + 1] > coords[p2 + 1]) {\n tmp = p1;\n p1 = p2;\n p2 = tmp;\n tmp = c1;\n c1 = c2;\n c2 = tmp;\n }\n\n if (coords[p2 + 1] > coords[p3 + 1]) {\n tmp = p2;\n p2 = p3;\n p3 = tmp;\n tmp = c2;\n c2 = c3;\n c3 = tmp;\n }\n\n if (coords[p1 + 1] > coords[p2 + 1]) {\n tmp = p1;\n p1 = p2;\n p2 = tmp;\n tmp = c1;\n c1 = c2;\n c2 = tmp;\n }\n\n const x1 = (coords[p1] + context.offsetX) * context.scaleX;\n const y1 = (coords[p1 + 1] + context.offsetY) * context.scaleY;\n const x2 = (coords[p2] + context.offsetX) * context.scaleX;\n const y2 = (coords[p2 + 1] + context.offsetY) * context.scaleY;\n const x3 = (coords[p3] + context.offsetX) * context.scaleX;\n const y3 = (coords[p3 + 1] + context.offsetY) * context.scaleY;\n\n if (y1 >= y3) {\n return;\n }\n\n const c1r = colors[c1],\n c1g = colors[c1 + 1],\n c1b = colors[c1 + 2];\n const c2r = colors[c2],\n c2g = colors[c2 + 1],\n c2b = colors[c2 + 2];\n const c3r = colors[c3],\n c3g = colors[c3 + 1],\n c3b = colors[c3 + 2];\n const minY = Math.round(y1),\n maxY = Math.round(y3);\n let xa, car, cag, cab;\n let xb, cbr, cbg, cbb;\n\n for (let y = minY; y <= maxY; y++) {\n if (y < y2) {\n let k;\n\n if (y < y1) {\n k = 0;\n } else {\n k = (y1 - y) / (y1 - y2);\n }\n\n xa = x1 - (x1 - x2) * k;\n car = c1r - (c1r - c2r) * k;\n cag = c1g - (c1g - c2g) * k;\n cab = c1b - (c1b - c2b) * k;\n } else {\n let k;\n\n if (y > y3) {\n k = 1;\n } else if (y2 === y3) {\n k = 0;\n } else {\n k = (y2 - y) / (y2 - y3);\n }\n\n xa = x2 - (x2 - x3) * k;\n car = c2r - (c2r - c3r) * k;\n cag = c2g - (c2g - c3g) * k;\n cab = c2b - (c2b - c3b) * k;\n }\n\n let k;\n\n if (y < y1) {\n k = 0;\n } else if (y > y3) {\n k = 1;\n } else {\n k = (y1 - y) / (y1 - y3);\n }\n\n xb = x1 - (x1 - x3) * k;\n cbr = c1r - (c1r - c3r) * k;\n cbg = c1g - (c1g - c3g) * k;\n cbb = c1b - (c1b - c3b) * k;\n const x1_ = Math.round(Math.min(xa, xb));\n const x2_ = Math.round(Math.max(xa, xb));\n let j = rowSize * y + x1_ * 4;\n\n for (let x = x1_; x <= x2_; x++) {\n k = (xa - x) / (xa - xb);\n\n if (k < 0) {\n k = 0;\n } else if (k > 1) {\n k = 1;\n }\n\n bytes[j++] = car - (car - cbr) * k | 0;\n bytes[j++] = cag - (cag - cbg) * k | 0;\n bytes[j++] = cab - (cab - cbb) * k | 0;\n bytes[j++] = 255;\n }\n }\n}\n\nfunction drawFigure(data, figure, context) {\n const ps = figure.coords;\n const cs = figure.colors;\n let i, ii;\n\n switch (figure.type) {\n case "lattice":\n const verticesPerRow = figure.verticesPerRow;\n const rows = Math.floor(ps.length / verticesPerRow) - 1;\n const cols = verticesPerRow - 1;\n\n for (i = 0; i < rows; i++) {\n let q = i * verticesPerRow;\n\n for (let j = 0; j < cols; j++, q++) {\n drawTriangle(data, context, ps[q], ps[q + 1], ps[q + verticesPerRow], cs[q], cs[q + 1], cs[q + verticesPerRow]);\n drawTriangle(data, context, ps[q + verticesPerRow + 1], ps[q + 1], ps[q + verticesPerRow], cs[q + verticesPerRow + 1], cs[q + 1], cs[q + verticesPerRow]);\n }\n }\n\n break;\n\n case "triangles":\n for (i = 0, ii = ps.length; i < ii; i += 3) {\n drawTriangle(data, context, ps[i], ps[i + 1], ps[i + 2], cs[i], cs[i + 1], cs[i + 2]);\n }\n\n break;\n\n default:\n throw new Error("illegal figure");\n }\n}\n\nclass MeshShadingPattern extends BaseShadingPattern {\n constructor(IR) {\n super();\n this._coords = IR[2];\n this._colors = IR[3];\n this._figures = IR[4];\n this._bounds = IR[5];\n this._bbox = IR[7];\n this._background = IR[8];\n this.matrix = null;\n }\n\n _createMeshCanvas(combinedScale, backgroundColor, cachedCanvases) {\n const EXPECTED_SCALE = 1.1;\n const MAX_PATTERN_SIZE = 3000;\n const BORDER_SIZE = 2;\n const offsetX = Math.floor(this._bounds[0]);\n const offsetY = Math.floor(this._bounds[1]);\n const boundsWidth = Math.ceil(this._bounds[2]) - offsetX;\n const boundsHeight = Math.ceil(this._bounds[3]) - offsetY;\n const width = Math.min(Math.ceil(Math.abs(boundsWidth * combinedScale[0] * EXPECTED_SCALE)), MAX_PATTERN_SIZE);\n const height = Math.min(Math.ceil(Math.abs(boundsHeight * combinedScale[1] * EXPECTED_SCALE)), MAX_PATTERN_SIZE);\n const scaleX = boundsWidth / width;\n const scaleY = boundsHeight / height;\n const context = {\n coords: this._coords,\n colors: this._colors,\n offsetX: -offsetX,\n offsetY: -offsetY,\n scaleX: 1 / scaleX,\n scaleY: 1 / scaleY\n };\n const paddedWidth = width + BORDER_SIZE * 2;\n const paddedHeight = height + BORDER_SIZE * 2;\n const tmpCanvas = cachedCanvases.getCanvas("mesh", paddedWidth, paddedHeight, false);\n const tmpCtx = tmpCanvas.context;\n const data = tmpCtx.createImageData(width, height);\n\n if (backgroundColor) {\n const bytes = data.data;\n\n for (let i = 0, ii = bytes.length; i < ii; i += 4) {\n bytes[i] = backgroundColor[0];\n bytes[i + 1] = backgroundColor[1];\n bytes[i + 2] = backgroundColor[2];\n bytes[i + 3] = 255;\n }\n }\n\n for (const figure of this._figures) {\n drawFigure(data, figure, context);\n }\n\n tmpCtx.putImageData(data, BORDER_SIZE, BORDER_SIZE);\n const canvas = tmpCanvas.canvas;\n return {\n canvas,\n offsetX: offsetX - BORDER_SIZE * scaleX,\n offsetY: offsetY - BORDER_SIZE * scaleY,\n scaleX,\n scaleY\n };\n }\n\n getPattern(ctx, owner, inverse, pathType) {\n applyBoundingBox(ctx, this._bbox);\n let scale;\n\n if (pathType === PathType.SHADING) {\n scale = _util.Util.singularValueDecompose2dScale(ctx.mozCurrentTransform);\n } else {\n scale = _util.Util.singularValueDecompose2dScale(owner.baseTransform);\n\n if (this.matrix) {\n const matrixScale = _util.Util.singularValueDecompose2dScale(this.matrix);\n\n scale = [scale[0] * matrixScale[0], scale[1] * matrixScale[1]];\n }\n }\n\n const temporaryPatternCanvas = this._createMeshCanvas(scale, pathType === PathType.SHADING ? null : this._background, owner.cachedCanvases);\n\n if (pathType !== PathType.SHADING) {\n ctx.setTransform.apply(ctx, owner.baseTransform);\n\n if (this.matrix) {\n ctx.transform.apply(ctx, this.matrix);\n }\n }\n\n ctx.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY);\n ctx.scale(temporaryPatternCanvas.scaleX, temporaryPatternCanvas.scaleY);\n return ctx.createPattern(temporaryPatternCanvas.canvas, "no-repeat");\n }\n\n}\n\nclass DummyShadingPattern extends BaseShadingPattern {\n getPattern() {\n return "hotpink";\n }\n\n}\n\nfunction getShadingPattern(IR) {\n switch (IR[0]) {\n case "RadialAxial":\n return new RadialAxialShadingPattern(IR);\n\n case "Mesh":\n return new MeshShadingPattern(IR);\n\n case "Dummy":\n return new DummyShadingPattern();\n }\n\n throw new Error(`Unknown IR type: ${IR[0]}`);\n}\n\nconst PaintType = {\n COLORED: 1,\n UNCOLORED: 2\n};\n\nclass TilingPattern {\n static get MAX_PATTERN_SIZE() {\n return (0, _util.shadow)(this, "MAX_PATTERN_SIZE", 3000);\n }\n\n constructor(IR, color, ctx, canvasGraphicsFactory, baseTransform) {\n this.operatorList = IR[2];\n this.matrix = IR[3] || [1, 0, 0, 1, 0, 0];\n this.bbox = IR[4];\n this.xstep = IR[5];\n this.ystep = IR[6];\n this.paintType = IR[7];\n this.tilingType = IR[8];\n this.color = color;\n this.ctx = ctx;\n this.canvasGraphicsFactory = canvasGraphicsFactory;\n this.baseTransform = baseTransform;\n }\n\n createPatternCanvas(owner) {\n const operatorList = this.operatorList;\n const bbox = this.bbox;\n const xstep = this.xstep;\n const ystep = this.ystep;\n const paintType = this.paintType;\n const tilingType = this.tilingType;\n const color = this.color;\n const canvasGraphicsFactory = this.canvasGraphicsFactory;\n (0, _util.info)("TilingType: " + tilingType);\n const x0 = bbox[0],\n y0 = bbox[1],\n x1 = bbox[2],\n y1 = bbox[3];\n\n const matrixScale = _util.Util.singularValueDecompose2dScale(this.matrix);\n\n const curMatrixScale = _util.Util.singularValueDecompose2dScale(this.baseTransform);\n\n const combinedScale = [matrixScale[0] * curMatrixScale[0], matrixScale[1] * curMatrixScale[1]];\n const dimx = this.getSizeAndScale(xstep, this.ctx.canvas.width, combinedScale[0]);\n const dimy = this.getSizeAndScale(ystep, this.ctx.canvas.height, combinedScale[1]);\n const tmpCanvas = owner.cachedCanvases.getCanvas("pattern", dimx.size, dimy.size, true);\n const tmpCtx = tmpCanvas.context;\n const graphics = canvasGraphicsFactory.createCanvasGraphics(tmpCtx);\n graphics.groupLevel = owner.groupLevel;\n this.setFillAndStrokeStyleToContext(graphics, paintType, color);\n let adjustedX0 = x0;\n let adjustedY0 = y0;\n let adjustedX1 = x1;\n let adjustedY1 = y1;\n\n if (x0 < 0) {\n adjustedX0 = 0;\n adjustedX1 += Math.abs(x0);\n }\n\n if (y0 < 0) {\n adjustedY0 = 0;\n adjustedY1 += Math.abs(y0);\n }\n\n tmpCtx.translate(-(dimx.scale * adjustedX0), -(dimy.scale * adjustedY0));\n graphics.transform(dimx.scale, 0, 0, dimy.scale, 0, 0);\n tmpCtx.save();\n this.clipBbox(graphics, adjustedX0, adjustedY0, adjustedX1, adjustedY1);\n graphics.baseTransform = graphics.ctx.mozCurrentTransform.slice();\n graphics.executeOperatorList(operatorList);\n graphics.endDrawing();\n return {\n canvas: tmpCanvas.canvas,\n scaleX: dimx.scale,\n scaleY: dimy.scale,\n offsetX: adjustedX0,\n offsetY: adjustedY0\n };\n }\n\n getSizeAndScale(step, realOutputSize, scale) {\n step = Math.abs(step);\n const maxSize = Math.max(TilingPattern.MAX_PATTERN_SIZE, realOutputSize);\n let size = Math.ceil(step * scale);\n\n if (size >= maxSize) {\n size = maxSize;\n } else {\n scale = size / step;\n }\n\n return {\n scale,\n size\n };\n }\n\n clipBbox(graphics, x0, y0, x1, y1) {\n const bboxWidth = x1 - x0;\n const bboxHeight = y1 - y0;\n graphics.ctx.rect(x0, y0, bboxWidth, bboxHeight);\n graphics.current.updateRectMinMax(graphics.ctx.mozCurrentTransform, [x0, y0, x1, y1]);\n graphics.clip();\n graphics.endPath();\n }\n\n setFillAndStrokeStyleToContext(graphics, paintType, color) {\n const context = graphics.ctx,\n current = graphics.current;\n\n switch (paintType) {\n case PaintType.COLORED:\n const ctx = this.ctx;\n context.fillStyle = ctx.fillStyle;\n context.strokeStyle = ctx.strokeStyle;\n current.fillColor = ctx.fillStyle;\n current.strokeColor = ctx.strokeStyle;\n break;\n\n case PaintType.UNCOLORED:\n const cssColor = _util.Util.makeHexColor(color[0], color[1], color[2]);\n\n context.fillStyle = cssColor;\n context.strokeStyle = cssColor;\n current.fillColor = cssColor;\n current.strokeColor = cssColor;\n break;\n\n default:\n throw new _util.FormatError(`Unsupported paint type: ${paintType}`);\n }\n }\n\n getPattern(ctx, owner, inverse, pathType) {\n let matrix = inverse;\n\n if (pathType !== PathType.SHADING) {\n matrix = _util.Util.transform(matrix, owner.baseTransform);\n\n if (this.matrix) {\n matrix = _util.Util.transform(matrix, this.matrix);\n }\n }\n\n const temporaryPatternCanvas = this.createPatternCanvas(owner);\n let domMatrix = new DOMMatrix(matrix);\n domMatrix = domMatrix.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY);\n domMatrix = domMatrix.scale(1 / temporaryPatternCanvas.scaleX, 1 / temporaryPatternCanvas.scaleY);\n const pattern = ctx.createPattern(temporaryPatternCanvas.canvas, "repeat");\n\n try {\n pattern.setTransform(domMatrix);\n } catch (ex) {\n (0, _util.warn)(`TilingPattern.getPattern: "${ex?.message}".`);\n }\n\n return pattern;\n }\n\n}\n\nexports.TilingPattern = TilingPattern;\n\n/***/ }),\n/* 12 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.applyMaskImageData = applyMaskImageData;\n\nvar _util = __w_pdfjs_require__(1);\n\nfunction applyMaskImageData({\n src,\n srcPos = 0,\n dest,\n destPos = 0,\n width,\n height,\n inverseDecode = false\n}) {\n const opaque = _util.FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff;\n const [zeroMapping, oneMapping] = !inverseDecode ? [opaque, 0] : [0, opaque];\n const widthInSource = width >> 3;\n const widthRemainder = width & 7;\n const srcLength = src.length;\n dest = new Uint32Array(dest.buffer);\n\n for (let i = 0; i < height; i++) {\n for (const max = srcPos + widthInSource; srcPos < max; srcPos++) {\n const elem = srcPos < srcLength ? src[srcPos] : 255;\n dest[destPos++] = elem & 0b10000000 ? oneMapping : zeroMapping;\n dest[destPos++] = elem & 0b1000000 ? oneMapping : zeroMapping;\n dest[destPos++] = elem & 0b100000 ? oneMapping : zeroMapping;\n dest[destPos++] = elem & 0b10000 ? oneMapping : zeroMapping;\n dest[destPos++] = elem & 0b1000 ? oneMapping : zeroMapping;\n dest[destPos++] = elem & 0b100 ? oneMapping : zeroMapping;\n dest[destPos++] = elem & 0b10 ? oneMapping : zeroMapping;\n dest[destPos++] = elem & 0b1 ? oneMapping : zeroMapping;\n }\n\n if (widthRemainder === 0) {\n continue;\n }\n\n const elem = srcPos < srcLength ? src[srcPos++] : 255;\n\n for (let j = 0; j < widthRemainder; j++) {\n dest[destPos++] = elem & 1 << 7 - j ? oneMapping : zeroMapping;\n }\n }\n\n return {\n srcPos,\n destPos\n };\n}\n\n/***/ }),\n/* 13 */\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.GlobalWorkerOptions = void 0;\nconst GlobalWorkerOptions = Object.create(null);\nexports.GlobalWorkerOptions = GlobalWorkerOptions;\nGlobalWorkerOptions.workerPort = GlobalWorkerOptions.workerPort === undefined ? null : GlobalWorkerOptions.workerPort;\nGlobalWorkerOptions.workerSrc = GlobalWorkerOptions.workerSrc === undefined ? "" : GlobalWorkerOptions.workerSrc;\n\n/***/ }),\n/* 14 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.MessageHandler = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nconst CallbackKind = {\n UNKNOWN: 0,\n DATA: 1,\n ERROR: 2\n};\nconst StreamKind = {\n UNKNOWN: 0,\n CANCEL: 1,\n CANCEL_COMPLETE: 2,\n CLOSE: 3,\n ENQUEUE: 4,\n ERROR: 5,\n PULL: 6,\n PULL_COMPLETE: 7,\n START_COMPLETE: 8\n};\n\nfunction wrapReason(reason) {\n if (!(reason instanceof Error || typeof reason === "object" && reason !== null)) {\n (0, _util.unreachable)(\'wrapReason: Expected "reason" to be a (possibly cloned) Error.\');\n }\n\n switch (reason.name) {\n case "AbortException":\n return new _util.AbortException(reason.message);\n\n case "MissingPDFException":\n return new _util.MissingPDFException(reason.message);\n\n case "PasswordException":\n return new _util.PasswordException(reason.message, reason.code);\n\n case "UnexpectedResponseException":\n return new _util.UnexpectedResponseException(reason.message, reason.status);\n\n case "UnknownErrorException":\n return new _util.UnknownErrorException(reason.message, reason.details);\n\n default:\n return new _util.UnknownErrorException(reason.message, reason.toString());\n }\n}\n\nclass MessageHandler {\n constructor(sourceName, targetName, comObj) {\n this.sourceName = sourceName;\n this.targetName = targetName;\n this.comObj = comObj;\n this.callbackId = 1;\n this.streamId = 1;\n this.streamSinks = Object.create(null);\n this.streamControllers = Object.create(null);\n this.callbackCapabilities = Object.create(null);\n this.actionHandler = Object.create(null);\n\n this._onComObjOnMessage = event => {\n const data = event.data;\n\n if (data.targetName !== this.sourceName) {\n return;\n }\n\n if (data.stream) {\n this._processStreamMessage(data);\n\n return;\n }\n\n if (data.callback) {\n const callbackId = data.callbackId;\n const capability = this.callbackCapabilities[callbackId];\n\n if (!capability) {\n throw new Error(`Cannot resolve callback ${callbackId}`);\n }\n\n delete this.callbackCapabilities[callbackId];\n\n if (data.callback === CallbackKind.DATA) {\n capability.resolve(data.data);\n } else if (data.callback === CallbackKind.ERROR) {\n capability.reject(wrapReason(data.reason));\n } else {\n throw new Error("Unexpected callback case");\n }\n\n return;\n }\n\n const action = this.actionHandler[data.action];\n\n if (!action) {\n throw new Error(`Unknown action from worker: ${data.action}`);\n }\n\n if (data.callbackId) {\n const cbSourceName = this.sourceName;\n const cbTargetName = data.sourceName;\n new Promise(function (resolve) {\n resolve(action(data.data));\n }).then(function (result) {\n comObj.postMessage({\n sourceName: cbSourceName,\n targetName: cbTargetName,\n callback: CallbackKind.DATA,\n callbackId: data.callbackId,\n data: result\n });\n }, function (reason) {\n comObj.postMessage({\n sourceName: cbSourceName,\n targetName: cbTargetName,\n callback: CallbackKind.ERROR,\n callbackId: data.callbackId,\n reason: wrapReason(reason)\n });\n });\n return;\n }\n\n if (data.streamId) {\n this._createStreamSink(data);\n\n return;\n }\n\n action(data.data);\n };\n\n comObj.addEventListener("message", this._onComObjOnMessage);\n }\n\n on(actionName, handler) {\n const ah = this.actionHandler;\n\n if (ah[actionName]) {\n throw new Error(`There is already an actionName called "${actionName}"`);\n }\n\n ah[actionName] = handler;\n }\n\n send(actionName, data, transfers) {\n this.comObj.postMessage({\n sourceName: this.sourceName,\n targetName: this.targetName,\n action: actionName,\n data\n }, transfers);\n }\n\n sendWithPromise(actionName, data, transfers) {\n const callbackId = this.callbackId++;\n const capability = (0, _util.createPromiseCapability)();\n this.callbackCapabilities[callbackId] = capability;\n\n try {\n this.comObj.postMessage({\n sourceName: this.sourceName,\n targetName: this.targetName,\n action: actionName,\n callbackId,\n data\n }, transfers);\n } catch (ex) {\n capability.reject(ex);\n }\n\n return capability.promise;\n }\n\n sendWithStream(actionName, data, queueingStrategy, transfers) {\n const streamId = this.streamId++,\n sourceName = this.sourceName,\n targetName = this.targetName,\n comObj = this.comObj;\n return new ReadableStream({\n start: controller => {\n const startCapability = (0, _util.createPromiseCapability)();\n this.streamControllers[streamId] = {\n controller,\n startCall: startCapability,\n pullCall: null,\n cancelCall: null,\n isClosed: false\n };\n comObj.postMessage({\n sourceName,\n targetName,\n action: actionName,\n streamId,\n data,\n desiredSize: controller.desiredSize\n }, transfers);\n return startCapability.promise;\n },\n pull: controller => {\n const pullCapability = (0, _util.createPromiseCapability)();\n this.streamControllers[streamId].pullCall = pullCapability;\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.PULL,\n streamId,\n desiredSize: controller.desiredSize\n });\n return pullCapability.promise;\n },\n cancel: reason => {\n (0, _util.assert)(reason instanceof Error, "cancel must have a valid reason");\n const cancelCapability = (0, _util.createPromiseCapability)();\n this.streamControllers[streamId].cancelCall = cancelCapability;\n this.streamControllers[streamId].isClosed = true;\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.CANCEL,\n streamId,\n reason: wrapReason(reason)\n });\n return cancelCapability.promise;\n }\n }, queueingStrategy);\n }\n\n _createStreamSink(data) {\n const streamId = data.streamId,\n sourceName = this.sourceName,\n targetName = data.sourceName,\n comObj = this.comObj;\n const self = this,\n action = this.actionHandler[data.action];\n const streamSink = {\n enqueue(chunk, size = 1, transfers) {\n if (this.isCancelled) {\n return;\n }\n\n const lastDesiredSize = this.desiredSize;\n this.desiredSize -= size;\n\n if (lastDesiredSize > 0 && this.desiredSize <= 0) {\n this.sinkCapability = (0, _util.createPromiseCapability)();\n this.ready = this.sinkCapability.promise;\n }\n\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.ENQUEUE,\n streamId,\n chunk\n }, transfers);\n },\n\n close() {\n if (this.isCancelled) {\n return;\n }\n\n this.isCancelled = true;\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.CLOSE,\n streamId\n });\n delete self.streamSinks[streamId];\n },\n\n error(reason) {\n (0, _util.assert)(reason instanceof Error, "error must have a valid reason");\n\n if (this.isCancelled) {\n return;\n }\n\n this.isCancelled = true;\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.ERROR,\n streamId,\n reason: wrapReason(reason)\n });\n },\n\n sinkCapability: (0, _util.createPromiseCapability)(),\n onPull: null,\n onCancel: null,\n isCancelled: false,\n desiredSize: data.desiredSize,\n ready: null\n };\n streamSink.sinkCapability.resolve();\n streamSink.ready = streamSink.sinkCapability.promise;\n this.streamSinks[streamId] = streamSink;\n new Promise(function (resolve) {\n resolve(action(data.data, streamSink));\n }).then(function () {\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.START_COMPLETE,\n streamId,\n success: true\n });\n }, function (reason) {\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.START_COMPLETE,\n streamId,\n reason: wrapReason(reason)\n });\n });\n }\n\n _processStreamMessage(data) {\n const streamId = data.streamId,\n sourceName = this.sourceName,\n targetName = data.sourceName,\n comObj = this.comObj;\n const streamController = this.streamControllers[streamId],\n streamSink = this.streamSinks[streamId];\n\n switch (data.stream) {\n case StreamKind.START_COMPLETE:\n if (data.success) {\n streamController.startCall.resolve();\n } else {\n streamController.startCall.reject(wrapReason(data.reason));\n }\n\n break;\n\n case StreamKind.PULL_COMPLETE:\n if (data.success) {\n streamController.pullCall.resolve();\n } else {\n streamController.pullCall.reject(wrapReason(data.reason));\n }\n\n break;\n\n case StreamKind.PULL:\n if (!streamSink) {\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.PULL_COMPLETE,\n streamId,\n success: true\n });\n break;\n }\n\n if (streamSink.desiredSize <= 0 && data.desiredSize > 0) {\n streamSink.sinkCapability.resolve();\n }\n\n streamSink.desiredSize = data.desiredSize;\n new Promise(function (resolve) {\n resolve(streamSink.onPull && streamSink.onPull());\n }).then(function () {\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.PULL_COMPLETE,\n streamId,\n success: true\n });\n }, function (reason) {\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.PULL_COMPLETE,\n streamId,\n reason: wrapReason(reason)\n });\n });\n break;\n\n case StreamKind.ENQUEUE:\n (0, _util.assert)(streamController, "enqueue should have stream controller");\n\n if (streamController.isClosed) {\n break;\n }\n\n streamController.controller.enqueue(data.chunk);\n break;\n\n case StreamKind.CLOSE:\n (0, _util.assert)(streamController, "close should have stream controller");\n\n if (streamController.isClosed) {\n break;\n }\n\n streamController.isClosed = true;\n streamController.controller.close();\n\n this._deleteStreamController(streamController, streamId);\n\n break;\n\n case StreamKind.ERROR:\n (0, _util.assert)(streamController, "error should have stream controller");\n streamController.controller.error(wrapReason(data.reason));\n\n this._deleteStreamController(streamController, streamId);\n\n break;\n\n case StreamKind.CANCEL_COMPLETE:\n if (data.success) {\n streamController.cancelCall.resolve();\n } else {\n streamController.cancelCall.reject(wrapReason(data.reason));\n }\n\n this._deleteStreamController(streamController, streamId);\n\n break;\n\n case StreamKind.CANCEL:\n if (!streamSink) {\n break;\n }\n\n new Promise(function (resolve) {\n resolve(streamSink.onCancel && streamSink.onCancel(wrapReason(data.reason)));\n }).then(function () {\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.CANCEL_COMPLETE,\n streamId,\n success: true\n });\n }, function (reason) {\n comObj.postMessage({\n sourceName,\n targetName,\n stream: StreamKind.CANCEL_COMPLETE,\n streamId,\n reason: wrapReason(reason)\n });\n });\n streamSink.sinkCapability.reject(wrapReason(data.reason));\n streamSink.isCancelled = true;\n delete this.streamSinks[streamId];\n break;\n\n default:\n throw new Error("Unexpected stream case");\n }\n }\n\n async _deleteStreamController(streamController, streamId) {\n await Promise.allSettled([streamController.startCall && streamController.startCall.promise, streamController.pullCall && streamController.pullCall.promise, streamController.cancelCall && streamController.cancelCall.promise]);\n delete this.streamControllers[streamId];\n }\n\n destroy() {\n this.comObj.removeEventListener("message", this._onComObjOnMessage);\n }\n\n}\n\nexports.MessageHandler = MessageHandler;\n\n/***/ }),\n/* 15 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.Metadata = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nclass Metadata {\n #metadataMap;\n #data;\n\n constructor({\n parsedData,\n rawData\n }) {\n this.#metadataMap = parsedData;\n this.#data = rawData;\n }\n\n getRaw() {\n return this.#data;\n }\n\n get(name) {\n return this.#metadataMap.get(name) ?? null;\n }\n\n getAll() {\n return (0, _util.objectFromMap)(this.#metadataMap);\n }\n\n has(name) {\n return this.#metadataMap.has(name);\n }\n\n}\n\nexports.Metadata = Metadata;\n\n/***/ }),\n/* 16 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.OptionalContentConfig = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nclass OptionalContentGroup {\n constructor(name, intent) {\n this.visible = true;\n this.name = name;\n this.intent = intent;\n }\n\n}\n\nclass OptionalContentConfig {\n constructor(data) {\n this.name = null;\n this.creator = null;\n this._order = null;\n this._groups = new Map();\n\n if (data === null) {\n return;\n }\n\n this.name = data.name;\n this.creator = data.creator;\n this._order = data.order;\n\n for (const group of data.groups) {\n this._groups.set(group.id, new OptionalContentGroup(group.name, group.intent));\n }\n\n if (data.baseState === "OFF") {\n for (const group of this._groups) {\n group.visible = false;\n }\n }\n\n for (const on of data.on) {\n this._groups.get(on).visible = true;\n }\n\n for (const off of data.off) {\n this._groups.get(off).visible = false;\n }\n }\n\n _evaluateVisibilityExpression(array) {\n const length = array.length;\n\n if (length < 2) {\n return true;\n }\n\n const operator = array[0];\n\n for (let i = 1; i < length; i++) {\n const element = array[i];\n let state;\n\n if (Array.isArray(element)) {\n state = this._evaluateVisibilityExpression(element);\n } else if (this._groups.has(element)) {\n state = this._groups.get(element).visible;\n } else {\n (0, _util.warn)(`Optional content group not found: ${element}`);\n return true;\n }\n\n switch (operator) {\n case "And":\n if (!state) {\n return false;\n }\n\n break;\n\n case "Or":\n if (state) {\n return true;\n }\n\n break;\n\n case "Not":\n return !state;\n\n default:\n return true;\n }\n }\n\n return operator === "And";\n }\n\n isVisible(group) {\n if (this._groups.size === 0) {\n return true;\n }\n\n if (!group) {\n (0, _util.warn)("Optional content group not defined.");\n return true;\n }\n\n if (group.type === "OCG") {\n if (!this._groups.has(group.id)) {\n (0, _util.warn)(`Optional content group not found: ${group.id}`);\n return true;\n }\n\n return this._groups.get(group.id).visible;\n } else if (group.type === "OCMD") {\n if (group.expression) {\n return this._evaluateVisibilityExpression(group.expression);\n }\n\n if (!group.policy || group.policy === "AnyOn") {\n for (const id of group.ids) {\n if (!this._groups.has(id)) {\n (0, _util.warn)(`Optional content group not found: ${id}`);\n return true;\n }\n\n if (this._groups.get(id).visible) {\n return true;\n }\n }\n\n return false;\n } else if (group.policy === "AllOn") {\n for (const id of group.ids) {\n if (!this._groups.has(id)) {\n (0, _util.warn)(`Optional content group not found: ${id}`);\n return true;\n }\n\n if (!this._groups.get(id).visible) {\n return false;\n }\n }\n\n return true;\n } else if (group.policy === "AnyOff") {\n for (const id of group.ids) {\n if (!this._groups.has(id)) {\n (0, _util.warn)(`Optional content group not found: ${id}`);\n return true;\n }\n\n if (!this._groups.get(id).visible) {\n return true;\n }\n }\n\n return false;\n } else if (group.policy === "AllOff") {\n for (const id of group.ids) {\n if (!this._groups.has(id)) {\n (0, _util.warn)(`Optional content group not found: ${id}`);\n return true;\n }\n\n if (this._groups.get(id).visible) {\n return false;\n }\n }\n\n return true;\n }\n\n (0, _util.warn)(`Unknown optional content policy ${group.policy}.`);\n return true;\n }\n\n (0, _util.warn)(`Unknown group type ${group.type}.`);\n return true;\n }\n\n setVisibility(id, visible = true) {\n if (!this._groups.has(id)) {\n (0, _util.warn)(`Optional content group not found: ${id}`);\n return;\n }\n\n this._groups.get(id).visible = !!visible;\n }\n\n getOrder() {\n if (!this._groups.size) {\n return null;\n }\n\n if (this._order) {\n return this._order.slice();\n }\n\n return Array.from(this._groups.keys());\n }\n\n getGroups() {\n return this._groups.size > 0 ? (0, _util.objectFromMap)(this._groups) : null;\n }\n\n getGroup(id) {\n return this._groups.get(id) || null;\n }\n\n}\n\nexports.OptionalContentConfig = OptionalContentConfig;\n\n/***/ }),\n/* 17 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.PDFDataTransportStream = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _display_utils = __w_pdfjs_require__(5);\n\nclass PDFDataTransportStream {\n constructor(params, pdfDataRangeTransport) {\n (0, _util.assert)(pdfDataRangeTransport, \'PDFDataTransportStream - missing required "pdfDataRangeTransport" argument.\');\n this._queuedChunks = [];\n this._progressiveDone = params.progressiveDone || false;\n this._contentDispositionFilename = params.contentDispositionFilename || null;\n const initialData = params.initialData;\n\n if (initialData?.length > 0) {\n const buffer = new Uint8Array(initialData).buffer;\n\n this._queuedChunks.push(buffer);\n }\n\n this._pdfDataRangeTransport = pdfDataRangeTransport;\n this._isStreamingSupported = !params.disableStream;\n this._isRangeSupported = !params.disableRange;\n this._contentLength = params.length;\n this._fullRequestReader = null;\n this._rangeReaders = [];\n\n this._pdfDataRangeTransport.addRangeListener((begin, chunk) => {\n this._onReceiveData({\n begin,\n chunk\n });\n });\n\n this._pdfDataRangeTransport.addProgressListener((loaded, total) => {\n this._onProgress({\n loaded,\n total\n });\n });\n\n this._pdfDataRangeTransport.addProgressiveReadListener(chunk => {\n this._onReceiveData({\n chunk\n });\n });\n\n this._pdfDataRangeTransport.addProgressiveDoneListener(() => {\n this._onProgressiveDone();\n });\n\n this._pdfDataRangeTransport.transportReady();\n }\n\n _onReceiveData(args) {\n const buffer = new Uint8Array(args.chunk).buffer;\n\n if (args.begin === undefined) {\n if (this._fullRequestReader) {\n this._fullRequestReader._enqueue(buffer);\n } else {\n this._queuedChunks.push(buffer);\n }\n } else {\n const found = this._rangeReaders.some(function (rangeReader) {\n if (rangeReader._begin !== args.begin) {\n return false;\n }\n\n rangeReader._enqueue(buffer);\n\n return true;\n });\n\n (0, _util.assert)(found, "_onReceiveData - no `PDFDataTransportStreamRangeReader` instance found.");\n }\n }\n\n get _progressiveDataLength() {\n return this._fullRequestReader?._loaded ?? 0;\n }\n\n _onProgress(evt) {\n if (evt.total === undefined) {\n const firstReader = this._rangeReaders[0];\n\n if (firstReader?.onProgress) {\n firstReader.onProgress({\n loaded: evt.loaded\n });\n }\n } else {\n const fullReader = this._fullRequestReader;\n\n if (fullReader?.onProgress) {\n fullReader.onProgress({\n loaded: evt.loaded,\n total: evt.total\n });\n }\n }\n }\n\n _onProgressiveDone() {\n if (this._fullRequestReader) {\n this._fullRequestReader.progressiveDone();\n }\n\n this._progressiveDone = true;\n }\n\n _removeRangeReader(reader) {\n const i = this._rangeReaders.indexOf(reader);\n\n if (i >= 0) {\n this._rangeReaders.splice(i, 1);\n }\n }\n\n getFullReader() {\n (0, _util.assert)(!this._fullRequestReader, "PDFDataTransportStream.getFullReader can only be called once.");\n const queuedChunks = this._queuedChunks;\n this._queuedChunks = null;\n return new PDFDataTransportStreamReader(this, queuedChunks, this._progressiveDone, this._contentDispositionFilename);\n }\n\n getRangeReader(begin, end) {\n if (end <= this._progressiveDataLength) {\n return null;\n }\n\n const reader = new PDFDataTransportStreamRangeReader(this, begin, end);\n\n this._pdfDataRangeTransport.requestDataRange(begin, end);\n\n this._rangeReaders.push(reader);\n\n return reader;\n }\n\n cancelAllRequests(reason) {\n if (this._fullRequestReader) {\n this._fullRequestReader.cancel(reason);\n }\n\n for (const reader of this._rangeReaders.slice(0)) {\n reader.cancel(reason);\n }\n\n this._pdfDataRangeTransport.abort();\n }\n\n}\n\nexports.PDFDataTransportStream = PDFDataTransportStream;\n\nclass PDFDataTransportStreamReader {\n constructor(stream, queuedChunks, progressiveDone = false, contentDispositionFilename = null) {\n this._stream = stream;\n this._done = progressiveDone || false;\n this._filename = (0, _display_utils.isPdfFile)(contentDispositionFilename) ? contentDispositionFilename : null;\n this._queuedChunks = queuedChunks || [];\n this._loaded = 0;\n\n for (const chunk of this._queuedChunks) {\n this._loaded += chunk.byteLength;\n }\n\n this._requests = [];\n this._headersReady = Promise.resolve();\n stream._fullRequestReader = this;\n this.onProgress = null;\n }\n\n _enqueue(chunk) {\n if (this._done) {\n return;\n }\n\n if (this._requests.length > 0) {\n const requestCapability = this._requests.shift();\n\n requestCapability.resolve({\n value: chunk,\n done: false\n });\n } else {\n this._queuedChunks.push(chunk);\n }\n\n this._loaded += chunk.byteLength;\n }\n\n get headersReady() {\n return this._headersReady;\n }\n\n get filename() {\n return this._filename;\n }\n\n get isRangeSupported() {\n return this._stream._isRangeSupported;\n }\n\n get isStreamingSupported() {\n return this._stream._isStreamingSupported;\n }\n\n get contentLength() {\n return this._stream._contentLength;\n }\n\n async read() {\n if (this._queuedChunks.length > 0) {\n const chunk = this._queuedChunks.shift();\n\n return {\n value: chunk,\n done: false\n };\n }\n\n if (this._done) {\n return {\n value: undefined,\n done: true\n };\n }\n\n const requestCapability = (0, _util.createPromiseCapability)();\n\n this._requests.push(requestCapability);\n\n return requestCapability.promise;\n }\n\n cancel(reason) {\n this._done = true;\n\n for (const requestCapability of this._requests) {\n requestCapability.resolve({\n value: undefined,\n done: true\n });\n }\n\n this._requests.length = 0;\n }\n\n progressiveDone() {\n if (this._done) {\n return;\n }\n\n this._done = true;\n }\n\n}\n\nclass PDFDataTransportStreamRangeReader {\n constructor(stream, begin, end) {\n this._stream = stream;\n this._begin = begin;\n this._end = end;\n this._queuedChunk = null;\n this._requests = [];\n this._done = false;\n this.onProgress = null;\n }\n\n _enqueue(chunk) {\n if (this._done) {\n return;\n }\n\n if (this._requests.length === 0) {\n this._queuedChunk = chunk;\n } else {\n const requestsCapability = this._requests.shift();\n\n requestsCapability.resolve({\n value: chunk,\n done: false\n });\n\n for (const requestCapability of this._requests) {\n requestCapability.resolve({\n value: undefined,\n done: true\n });\n }\n\n this._requests.length = 0;\n }\n\n this._done = true;\n\n this._stream._removeRangeReader(this);\n }\n\n get isStreamingSupported() {\n return false;\n }\n\n async read() {\n if (this._queuedChunk) {\n const chunk = this._queuedChunk;\n this._queuedChunk = null;\n return {\n value: chunk,\n done: false\n };\n }\n\n if (this._done) {\n return {\n value: undefined,\n done: true\n };\n }\n\n const requestCapability = (0, _util.createPromiseCapability)();\n\n this._requests.push(requestCapability);\n\n return requestCapability.promise;\n }\n\n cancel(reason) {\n this._done = true;\n\n for (const requestCapability of this._requests) {\n requestCapability.resolve({\n value: undefined,\n done: true\n });\n }\n\n this._requests.length = 0;\n\n this._stream._removeRangeReader(this);\n }\n\n}\n\n/***/ }),\n/* 18 */\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.XfaText = void 0;\n\nclass XfaText {\n static textContent(xfa) {\n const items = [];\n const output = {\n items,\n styles: Object.create(null)\n };\n\n function walk(node) {\n if (!node) {\n return;\n }\n\n let str = null;\n const name = node.name;\n\n if (name === "#text") {\n str = node.value;\n } else if (!XfaText.shouldBuildText(name)) {\n return;\n } else if (node?.attributes?.textContent) {\n str = node.attributes.textContent;\n } else if (node.value) {\n str = node.value;\n }\n\n if (str !== null) {\n items.push({\n str\n });\n }\n\n if (!node.children) {\n return;\n }\n\n for (const child of node.children) {\n walk(child);\n }\n }\n\n walk(xfa);\n return output;\n }\n\n static shouldBuildText(name) {\n return !(name === "textarea" || name === "input" || name === "option" || name === "select");\n }\n\n}\n\nexports.XfaText = XfaText;\n\n/***/ }),\n/* 19 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.NodeStandardFontDataFactory = exports.NodeCanvasFactory = exports.NodeCMapReaderFactory = void 0;\n\nvar _base_factory = __w_pdfjs_require__(6);\n\n;\n\nconst fetchData = function (url) {\n return new Promise((resolve, reject) => {\n const fs = __webpack_require__(172);\n\n fs.readFile(url, (error, data) => {\n if (error || !data) {\n reject(new Error(error));\n return;\n }\n\n resolve(new Uint8Array(data));\n });\n });\n};\n\nclass NodeCanvasFactory extends _base_factory.BaseCanvasFactory {\n _createCanvas(width, height) {\n const Canvas = __webpack_require__(414);\n\n return Canvas.createCanvas(width, height);\n }\n\n}\n\nexports.NodeCanvasFactory = NodeCanvasFactory;\n\nclass NodeCMapReaderFactory extends _base_factory.BaseCMapReaderFactory {\n _fetchData(url, compressionType) {\n return fetchData(url).then(data => {\n return {\n cMapData: data,\n compressionType\n };\n });\n }\n\n}\n\nexports.NodeCMapReaderFactory = NodeCMapReaderFactory;\n\nclass NodeStandardFontDataFactory extends _base_factory.BaseStandardFontDataFactory {\n _fetchData(url) {\n return fetchData(url);\n }\n\n}\n\nexports.NodeStandardFontDataFactory = NodeStandardFontDataFactory;\n\n/***/ }),\n/* 20 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.AnnotationLayer = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _display_utils = __w_pdfjs_require__(5);\n\nvar _annotation_storage = __w_pdfjs_require__(8);\n\nvar _scripting_utils = __w_pdfjs_require__(21);\n\nvar _xfa_layer = __w_pdfjs_require__(22);\n\nconst DEFAULT_TAB_INDEX = 1000;\nconst GetElementsByNameSet = new WeakSet();\n\nfunction getRectDims(rect) {\n return {\n width: rect[2] - rect[0],\n height: rect[3] - rect[1]\n };\n}\n\nclass AnnotationElementFactory {\n static create(parameters) {\n const subtype = parameters.data.annotationType;\n\n switch (subtype) {\n case _util.AnnotationType.LINK:\n return new LinkAnnotationElement(parameters);\n\n case _util.AnnotationType.TEXT:\n return new TextAnnotationElement(parameters);\n\n case _util.AnnotationType.WIDGET:\n const fieldType = parameters.data.fieldType;\n\n switch (fieldType) {\n case "Tx":\n return new TextWidgetAnnotationElement(parameters);\n\n case "Btn":\n if (parameters.data.radioButton) {\n return new RadioButtonWidgetAnnotationElement(parameters);\n } else if (parameters.data.checkBox) {\n return new CheckboxWidgetAnnotationElement(parameters);\n }\n\n return new PushButtonWidgetAnnotationElement(parameters);\n\n case "Ch":\n return new ChoiceWidgetAnnotationElement(parameters);\n }\n\n return new WidgetAnnotationElement(parameters);\n\n case _util.AnnotationType.POPUP:\n return new PopupAnnotationElement(parameters);\n\n case _util.AnnotationType.FREETEXT:\n return new FreeTextAnnotationElement(parameters);\n\n case _util.AnnotationType.LINE:\n return new LineAnnotationElement(parameters);\n\n case _util.AnnotationType.SQUARE:\n return new SquareAnnotationElement(parameters);\n\n case _util.AnnotationType.CIRCLE:\n return new CircleAnnotationElement(parameters);\n\n case _util.AnnotationType.POLYLINE:\n return new PolylineAnnotationElement(parameters);\n\n case _util.AnnotationType.CARET:\n return new CaretAnnotationElement(parameters);\n\n case _util.AnnotationType.INK:\n return new InkAnnotationElement(parameters);\n\n case _util.AnnotationType.POLYGON:\n return new PolygonAnnotationElement(parameters);\n\n case _util.AnnotationType.HIGHLIGHT:\n return new HighlightAnnotationElement(parameters);\n\n case _util.AnnotationType.UNDERLINE:\n return new UnderlineAnnotationElement(parameters);\n\n case _util.AnnotationType.SQUIGGLY:\n return new SquigglyAnnotationElement(parameters);\n\n case _util.AnnotationType.STRIKEOUT:\n return new StrikeOutAnnotationElement(parameters);\n\n case _util.AnnotationType.STAMP:\n return new StampAnnotationElement(parameters);\n\n case _util.AnnotationType.FILEATTACHMENT:\n return new FileAttachmentAnnotationElement(parameters);\n\n default:\n return new AnnotationElement(parameters);\n }\n }\n\n}\n\nclass AnnotationElement {\n constructor(parameters, {\n isRenderable = false,\n ignoreBorder = false,\n createQuadrilaterals = false\n } = {}) {\n this.isRenderable = isRenderable;\n this.data = parameters.data;\n this.layer = parameters.layer;\n this.page = parameters.page;\n this.viewport = parameters.viewport;\n this.linkService = parameters.linkService;\n this.downloadManager = parameters.downloadManager;\n this.imageResourcesPath = parameters.imageResourcesPath;\n this.renderForms = parameters.renderForms;\n this.svgFactory = parameters.svgFactory;\n this.annotationStorage = parameters.annotationStorage;\n this.enableScripting = parameters.enableScripting;\n this.hasJSActions = parameters.hasJSActions;\n this._fieldObjects = parameters.fieldObjects;\n this._mouseState = parameters.mouseState;\n\n if (isRenderable) {\n this.container = this._createContainer(ignoreBorder);\n }\n\n if (createQuadrilaterals) {\n this.quadrilaterals = this._createQuadrilaterals(ignoreBorder);\n }\n }\n\n _createContainer(ignoreBorder = false) {\n const data = this.data,\n page = this.page,\n viewport = this.viewport;\n const container = document.createElement("section");\n let {\n width,\n height\n } = getRectDims(data.rect);\n container.setAttribute("data-annotation-id", data.id);\n\n const rect = _util.Util.normalizeRect([data.rect[0], page.view[3] - data.rect[1] + page.view[1], data.rect[2], page.view[3] - data.rect[3] + page.view[1]]);\n\n if (data.hasOwnCanvas) {\n const transform = viewport.transform.slice();\n\n const [scaleX, scaleY] = _util.Util.singularValueDecompose2dScale(transform);\n\n width = Math.ceil(width * scaleX);\n height = Math.ceil(height * scaleY);\n rect[0] *= scaleX;\n rect[1] *= scaleY;\n\n for (let i = 0; i < 4; i++) {\n transform[i] = Math.sign(transform[i]);\n }\n\n container.style.transform = `matrix(${transform.join(",")})`;\n } else {\n container.style.transform = `matrix(${viewport.transform.join(",")})`;\n }\n\n container.style.transformOrigin = `${-rect[0]}px ${-rect[1]}px`;\n\n if (!ignoreBorder && data.borderStyle.width > 0) {\n container.style.borderWidth = `${data.borderStyle.width}px`;\n\n if (data.borderStyle.style !== _util.AnnotationBorderStyleType.UNDERLINE) {\n width -= 2 * data.borderStyle.width;\n height -= 2 * data.borderStyle.width;\n }\n\n const horizontalRadius = data.borderStyle.horizontalCornerRadius;\n const verticalRadius = data.borderStyle.verticalCornerRadius;\n\n if (horizontalRadius > 0 || verticalRadius > 0) {\n const radius = `${horizontalRadius}px / ${verticalRadius}px`;\n container.style.borderRadius = radius;\n }\n\n switch (data.borderStyle.style) {\n case _util.AnnotationBorderStyleType.SOLID:\n container.style.borderStyle = "solid";\n break;\n\n case _util.AnnotationBorderStyleType.DASHED:\n container.style.borderStyle = "dashed";\n break;\n\n case _util.AnnotationBorderStyleType.BEVELED:\n (0, _util.warn)("Unimplemented border style: beveled");\n break;\n\n case _util.AnnotationBorderStyleType.INSET:\n (0, _util.warn)("Unimplemented border style: inset");\n break;\n\n case _util.AnnotationBorderStyleType.UNDERLINE:\n container.style.borderBottomStyle = "solid";\n break;\n\n default:\n break;\n }\n\n const borderColor = data.borderColor || data.color || null;\n\n if (borderColor) {\n container.style.borderColor = _util.Util.makeHexColor(data.color[0] | 0, data.color[1] | 0, data.color[2] | 0);\n } else {\n container.style.borderWidth = 0;\n }\n }\n\n container.style.left = `${rect[0]}px`;\n container.style.top = `${rect[1]}px`;\n\n if (data.hasOwnCanvas) {\n container.style.width = container.style.height = "auto";\n } else {\n container.style.width = `${width}px`;\n container.style.height = `${height}px`;\n }\n\n return container;\n }\n\n get _commonActions() {\n const setColor = (jsName, styleName, event) => {\n const color = event.detail[jsName];\n event.target.style[styleName] = _scripting_utils.ColorConverters[`${color[0]}_HTML`](color.slice(1));\n };\n\n return (0, _util.shadow)(this, "_commonActions", {\n display: event => {\n const hidden = event.detail.display % 2 === 1;\n event.target.style.visibility = hidden ? "hidden" : "visible";\n this.annotationStorage.setValue(this.data.id, {\n hidden,\n print: event.detail.display === 0 || event.detail.display === 3\n });\n },\n print: event => {\n this.annotationStorage.setValue(this.data.id, {\n print: event.detail.print\n });\n },\n hidden: event => {\n event.target.style.visibility = event.detail.hidden ? "hidden" : "visible";\n this.annotationStorage.setValue(this.data.id, {\n hidden: event.detail.hidden\n });\n },\n focus: event => {\n setTimeout(() => event.target.focus({\n preventScroll: false\n }), 0);\n },\n userName: event => {\n event.target.title = event.detail.userName;\n },\n readonly: event => {\n if (event.detail.readonly) {\n event.target.setAttribute("readonly", "");\n } else {\n event.target.removeAttribute("readonly");\n }\n },\n required: event => {\n if (event.detail.required) {\n event.target.setAttribute("required", "");\n } else {\n event.target.removeAttribute("required");\n }\n },\n bgColor: event => {\n setColor("bgColor", "backgroundColor", event);\n },\n fillColor: event => {\n setColor("fillColor", "backgroundColor", event);\n },\n fgColor: event => {\n setColor("fgColor", "color", event);\n },\n textColor: event => {\n setColor("textColor", "color", event);\n },\n borderColor: event => {\n setColor("borderColor", "borderColor", event);\n },\n strokeColor: event => {\n setColor("strokeColor", "borderColor", event);\n }\n });\n }\n\n _dispatchEventFromSandbox(actions, jsEvent) {\n const commonActions = this._commonActions;\n\n for (const name of Object.keys(jsEvent.detail)) {\n const action = actions[name] || commonActions[name];\n\n if (action) {\n action(jsEvent);\n }\n }\n }\n\n _setDefaultPropertiesFromJS(element) {\n if (!this.enableScripting) {\n return;\n }\n\n const storedData = this.annotationStorage.getRawValue(this.data.id);\n\n if (!storedData) {\n return;\n }\n\n const commonActions = this._commonActions;\n\n for (const [actionName, detail] of Object.entries(storedData)) {\n const action = commonActions[actionName];\n\n if (action) {\n action({\n detail,\n target: element\n });\n delete storedData[actionName];\n }\n }\n }\n\n _createQuadrilaterals(ignoreBorder = false) {\n if (!this.data.quadPoints) {\n return null;\n }\n\n const quadrilaterals = [];\n const savedRect = this.data.rect;\n\n for (const quadPoint of this.data.quadPoints) {\n this.data.rect = [quadPoint[2].x, quadPoint[2].y, quadPoint[1].x, quadPoint[1].y];\n quadrilaterals.push(this._createContainer(ignoreBorder));\n }\n\n this.data.rect = savedRect;\n return quadrilaterals;\n }\n\n _createPopup(trigger, data) {\n let container = this.container;\n\n if (this.quadrilaterals) {\n trigger = trigger || this.quadrilaterals;\n container = this.quadrilaterals[0];\n }\n\n if (!trigger) {\n trigger = document.createElement("div");\n trigger.style.height = container.style.height;\n trigger.style.width = container.style.width;\n container.appendChild(trigger);\n }\n\n const popupElement = new PopupElement({\n container,\n trigger,\n color: data.color,\n titleObj: data.titleObj,\n modificationDate: data.modificationDate,\n contentsObj: data.contentsObj,\n richText: data.richText,\n hideWrapper: true\n });\n const popup = popupElement.render();\n popup.style.left = container.style.width;\n container.appendChild(popup);\n }\n\n _renderQuadrilaterals(className) {\n for (const quadrilateral of this.quadrilaterals) {\n quadrilateral.className = className;\n }\n\n return this.quadrilaterals;\n }\n\n render() {\n (0, _util.unreachable)("Abstract method `AnnotationElement.render` called");\n }\n\n _getElementsByName(name, skipId = null) {\n const fields = [];\n\n if (this._fieldObjects) {\n const fieldObj = this._fieldObjects[name];\n\n if (fieldObj) {\n for (const {\n page,\n id,\n exportValues\n } of fieldObj) {\n if (page === -1) {\n continue;\n }\n\n if (id === skipId) {\n continue;\n }\n\n const exportValue = typeof exportValues === "string" ? exportValues : null;\n const domElement = document.getElementById(id);\n\n if (domElement && !GetElementsByNameSet.has(domElement)) {\n (0, _util.warn)(`_getElementsByName - element not allowed: ${id}`);\n continue;\n }\n\n fields.push({\n id,\n exportValue,\n domElement\n });\n }\n }\n\n return fields;\n }\n\n for (const domElement of document.getElementsByName(name)) {\n const {\n id,\n exportValue\n } = domElement;\n\n if (id === skipId) {\n continue;\n }\n\n if (!GetElementsByNameSet.has(domElement)) {\n continue;\n }\n\n fields.push({\n id,\n exportValue,\n domElement\n });\n }\n\n return fields;\n }\n\n static get platform() {\n const platform = typeof navigator !== "undefined" ? navigator.platform : "";\n return (0, _util.shadow)(this, "platform", {\n isWin: platform.includes("Win"),\n isMac: platform.includes("Mac")\n });\n }\n\n}\n\nclass LinkAnnotationElement extends AnnotationElement {\n constructor(parameters, options = null) {\n const isRenderable = !!(parameters.data.url || parameters.data.dest || parameters.data.action || parameters.data.isTooltipOnly || parameters.data.resetForm || parameters.data.actions && (parameters.data.actions.Action || parameters.data.actions["Mouse Up"] || parameters.data.actions["Mouse Down"]));\n super(parameters, {\n isRenderable,\n ignoreBorder: !!options?.ignoreBorder,\n createQuadrilaterals: true\n });\n }\n\n render() {\n const {\n data,\n linkService\n } = this;\n const link = document.createElement("a");\n\n if (data.url) {\n linkService.addLinkAttributes(link, data.url, data.newWindow);\n } else if (data.action) {\n this._bindNamedAction(link, data.action);\n } else if (data.dest) {\n this._bindLink(link, data.dest);\n } else {\n let hasClickAction = false;\n\n if (data.actions && (data.actions.Action || data.actions["Mouse Up"] || data.actions["Mouse Down"]) && this.enableScripting && this.hasJSActions) {\n hasClickAction = true;\n\n this._bindJSAction(link, data);\n }\n\n if (data.resetForm) {\n this._bindResetFormAction(link, data.resetForm);\n } else if (!hasClickAction) {\n this._bindLink(link, "");\n }\n }\n\n if (this.quadrilaterals) {\n return this._renderQuadrilaterals("linkAnnotation").map((quadrilateral, index) => {\n const linkElement = index === 0 ? link : link.cloneNode();\n quadrilateral.appendChild(linkElement);\n return quadrilateral;\n });\n }\n\n this.container.className = "linkAnnotation";\n this.container.appendChild(link);\n return this.container;\n }\n\n _bindLink(link, destination) {\n link.href = this.linkService.getDestinationHash(destination);\n\n link.onclick = () => {\n if (destination) {\n this.linkService.goToDestination(destination);\n }\n\n return false;\n };\n\n if (destination || destination === "") {\n link.className = "internalLink";\n }\n }\n\n _bindNamedAction(link, action) {\n link.href = this.linkService.getAnchorUrl("");\n\n link.onclick = () => {\n this.linkService.executeNamedAction(action);\n return false;\n };\n\n link.className = "internalLink";\n }\n\n _bindJSAction(link, data) {\n link.href = this.linkService.getAnchorUrl("");\n const map = new Map([["Action", "onclick"], ["Mouse Up", "onmouseup"], ["Mouse Down", "onmousedown"]]);\n\n for (const name of Object.keys(data.actions)) {\n const jsName = map.get(name);\n\n if (!jsName) {\n continue;\n }\n\n link[jsName] = () => {\n this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {\n source: this,\n detail: {\n id: data.id,\n name\n }\n });\n return false;\n };\n }\n\n if (!link.onclick) {\n link.onclick = () => false;\n }\n\n link.className = "internalLink";\n }\n\n _bindResetFormAction(link, resetForm) {\n const otherClickAction = link.onclick;\n\n if (!otherClickAction) {\n link.href = this.linkService.getAnchorUrl("");\n }\n\n link.className = "internalLink";\n\n if (!this._fieldObjects) {\n (0, _util.warn)(`_bindResetFormAction - "resetForm" action not supported, ` + "ensure that the `fieldObjects` parameter is provided.");\n\n if (!otherClickAction) {\n link.onclick = () => false;\n }\n\n return;\n }\n\n link.onclick = () => {\n if (otherClickAction) {\n otherClickAction();\n }\n\n const {\n fields: resetFormFields,\n refs: resetFormRefs,\n include\n } = resetForm;\n const allFields = [];\n\n if (resetFormFields.length !== 0 || resetFormRefs.length !== 0) {\n const fieldIds = new Set(resetFormRefs);\n\n for (const fieldName of resetFormFields) {\n const fields = this._fieldObjects[fieldName] || [];\n\n for (const {\n id\n } of fields) {\n fieldIds.add(id);\n }\n }\n\n for (const fields of Object.values(this._fieldObjects)) {\n for (const field of fields) {\n if (fieldIds.has(field.id) === include) {\n allFields.push(field);\n }\n }\n }\n } else {\n for (const fields of Object.values(this._fieldObjects)) {\n allFields.push(...fields);\n }\n }\n\n const storage = this.annotationStorage;\n const allIds = [];\n\n for (const field of allFields) {\n const {\n id\n } = field;\n allIds.push(id);\n\n switch (field.type) {\n case "text":\n {\n const value = field.defaultValue || "";\n storage.setValue(id, {\n value\n });\n break;\n }\n\n case "checkbox":\n case "radiobutton":\n {\n const value = field.defaultValue === field.exportValues;\n storage.setValue(id, {\n value\n });\n break;\n }\n\n case "combobox":\n case "listbox":\n {\n const value = field.defaultValue || "";\n storage.setValue(id, {\n value\n });\n break;\n }\n\n default:\n continue;\n }\n\n const domElement = document.getElementById(id);\n\n if (!domElement || !GetElementsByNameSet.has(domElement)) {\n continue;\n }\n\n domElement.dispatchEvent(new Event("resetform"));\n }\n\n if (this.enableScripting) {\n this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {\n source: this,\n detail: {\n id: "app",\n ids: allIds,\n name: "ResetForm"\n }\n });\n }\n\n return false;\n };\n }\n\n}\n\nclass TextAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable\n });\n }\n\n render() {\n this.container.className = "textAnnotation";\n const image = document.createElement("img");\n image.style.height = this.container.style.height;\n image.style.width = this.container.style.width;\n image.src = this.imageResourcesPath + "annotation-" + this.data.name.toLowerCase() + ".svg";\n image.alt = "[{{type}} Annotation]";\n image.dataset.l10nId = "text_annotation_type";\n image.dataset.l10nArgs = JSON.stringify({\n type: this.data.name\n });\n\n if (!this.data.hasPopup) {\n this._createPopup(image, this.data);\n }\n\n this.container.appendChild(image);\n return this.container;\n }\n\n}\n\nclass WidgetAnnotationElement extends AnnotationElement {\n render() {\n if (this.data.alternativeText) {\n this.container.title = this.data.alternativeText;\n }\n\n return this.container;\n }\n\n _getKeyModifier(event) {\n const {\n isWin,\n isMac\n } = AnnotationElement.platform;\n return isWin && event.ctrlKey || isMac && event.metaKey;\n }\n\n _setEventListener(element, baseName, eventName, valueGetter) {\n if (baseName.includes("mouse")) {\n element.addEventListener(baseName, event => {\n this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {\n source: this,\n detail: {\n id: this.data.id,\n name: eventName,\n value: valueGetter(event),\n shift: event.shiftKey,\n modifier: this._getKeyModifier(event)\n }\n });\n });\n } else {\n element.addEventListener(baseName, event => {\n this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {\n source: this,\n detail: {\n id: this.data.id,\n name: eventName,\n value: valueGetter(event)\n }\n });\n });\n }\n }\n\n _setEventListeners(element, names, getter) {\n for (const [baseName, eventName] of names) {\n if (eventName === "Action" || this.data.actions?.[eventName]) {\n this._setEventListener(element, baseName, eventName, getter);\n }\n }\n }\n\n _setBackgroundColor(element) {\n const color = this.data.backgroundColor || null;\n element.style.backgroundColor = color === null ? "transparent" : _util.Util.makeHexColor(color[0], color[1], color[2]);\n }\n\n}\n\nclass TextWidgetAnnotationElement extends WidgetAnnotationElement {\n constructor(parameters) {\n const isRenderable = parameters.renderForms || !parameters.data.hasAppearance && !!parameters.data.fieldValue;\n super(parameters, {\n isRenderable\n });\n }\n\n setPropertyOnSiblings(base, key, value, keyInStorage) {\n const storage = this.annotationStorage;\n\n for (const element of this._getElementsByName(base.name, base.id)) {\n if (element.domElement) {\n element.domElement[key] = value;\n }\n\n storage.setValue(element.id, {\n [keyInStorage]: value\n });\n }\n }\n\n render() {\n const storage = this.annotationStorage;\n const id = this.data.id;\n this.container.className = "textWidgetAnnotation";\n let element = null;\n\n if (this.renderForms) {\n const storedData = storage.getValue(id, {\n value: this.data.fieldValue\n });\n const textContent = storedData.formattedValue || storedData.value || "";\n const elementData = {\n userValue: null,\n formattedValue: null,\n valueOnFocus: ""\n };\n\n if (this.data.multiLine) {\n element = document.createElement("textarea");\n element.textContent = textContent;\n } else {\n element = document.createElement("input");\n element.type = "text";\n element.setAttribute("value", textContent);\n }\n\n GetElementsByNameSet.add(element);\n element.disabled = this.data.readOnly;\n element.name = this.data.fieldName;\n element.tabIndex = DEFAULT_TAB_INDEX;\n elementData.userValue = textContent;\n element.setAttribute("id", id);\n element.addEventListener("input", event => {\n storage.setValue(id, {\n value: event.target.value\n });\n this.setPropertyOnSiblings(element, "value", event.target.value, "value");\n });\n element.addEventListener("resetform", event => {\n const defaultValue = this.data.defaultFieldValue ?? "";\n element.value = elementData.userValue = defaultValue;\n elementData.formattedValue = null;\n });\n\n let blurListener = event => {\n const {\n formattedValue\n } = elementData;\n\n if (formattedValue !== null && formattedValue !== undefined) {\n event.target.value = formattedValue;\n }\n\n event.target.scrollLeft = 0;\n };\n\n if (this.enableScripting && this.hasJSActions) {\n element.addEventListener("focus", event => {\n if (elementData.userValue) {\n event.target.value = elementData.userValue;\n }\n\n elementData.valueOnFocus = event.target.value;\n });\n element.addEventListener("updatefromsandbox", jsEvent => {\n const actions = {\n value(event) {\n elementData.userValue = event.detail.value ?? "";\n storage.setValue(id, {\n value: elementData.userValue.toString()\n });\n event.target.value = elementData.userValue;\n },\n\n formattedValue(event) {\n const {\n formattedValue\n } = event.detail;\n elementData.formattedValue = formattedValue;\n\n if (formattedValue !== null && formattedValue !== undefined && event.target !== document.activeElement) {\n event.target.value = formattedValue;\n }\n\n storage.setValue(id, {\n formattedValue\n });\n },\n\n selRange(event) {\n event.target.setSelectionRange(...event.detail.selRange);\n }\n\n };\n\n this._dispatchEventFromSandbox(actions, jsEvent);\n });\n element.addEventListener("keydown", event => {\n let commitKey = -1;\n\n if (event.key === "Escape") {\n commitKey = 0;\n } else if (event.key === "Enter") {\n commitKey = 2;\n } else if (event.key === "Tab") {\n commitKey = 3;\n }\n\n if (commitKey === -1) {\n return;\n }\n\n const {\n value\n } = event.target;\n\n if (elementData.valueOnFocus === value) {\n return;\n }\n\n elementData.userValue = value;\n this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {\n source: this,\n detail: {\n id,\n name: "Keystroke",\n value,\n willCommit: true,\n commitKey,\n selStart: event.target.selectionStart,\n selEnd: event.target.selectionEnd\n }\n });\n });\n const _blurListener = blurListener;\n blurListener = null;\n element.addEventListener("blur", event => {\n const {\n value\n } = event.target;\n elementData.userValue = value;\n\n if (this._mouseState.isDown && elementData.valueOnFocus !== value) {\n this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {\n source: this,\n detail: {\n id,\n name: "Keystroke",\n value,\n willCommit: true,\n commitKey: 1,\n selStart: event.target.selectionStart,\n selEnd: event.target.selectionEnd\n }\n });\n }\n\n _blurListener(event);\n });\n\n if (this.data.actions?.Keystroke) {\n element.addEventListener("beforeinput", event => {\n const {\n data,\n target\n } = event;\n const {\n value,\n selectionStart,\n selectionEnd\n } = target;\n let selStart = selectionStart,\n selEnd = selectionEnd;\n\n switch (event.inputType) {\n case "deleteWordBackward":\n {\n const match = value.substring(0, selectionStart).match(/\\w*[^\\w]*$/);\n\n if (match) {\n selStart -= match[0].length;\n }\n\n break;\n }\n\n case "deleteWordForward":\n {\n const match = value.substring(selectionStart).match(/^[^\\w]*\\w*/);\n\n if (match) {\n selEnd += match[0].length;\n }\n\n break;\n }\n\n case "deleteContentBackward":\n if (selectionStart === selectionEnd) {\n selStart -= 1;\n }\n\n break;\n\n case "deleteContentForward":\n if (selectionStart === selectionEnd) {\n selEnd += 1;\n }\n\n break;\n }\n\n event.preventDefault();\n this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {\n source: this,\n detail: {\n id,\n name: "Keystroke",\n value,\n change: data || "",\n willCommit: false,\n selStart,\n selEnd\n }\n });\n });\n }\n\n this._setEventListeners(element, [["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.value);\n }\n\n if (blurListener) {\n element.addEventListener("blur", blurListener);\n }\n\n if (this.data.maxLen !== null) {\n element.maxLength = this.data.maxLen;\n }\n\n if (this.data.comb) {\n const fieldWidth = this.data.rect[2] - this.data.rect[0];\n const combWidth = fieldWidth / this.data.maxLen;\n element.classList.add("comb");\n element.style.letterSpacing = `calc(${combWidth}px - 1ch)`;\n }\n } else {\n element = document.createElement("div");\n element.textContent = this.data.fieldValue;\n element.style.verticalAlign = "middle";\n element.style.display = "table-cell";\n }\n\n this._setTextStyle(element);\n\n this._setBackgroundColor(element);\n\n this._setDefaultPropertiesFromJS(element);\n\n this.container.appendChild(element);\n return this.container;\n }\n\n _setTextStyle(element) {\n const TEXT_ALIGNMENT = ["left", "center", "right"];\n const {\n fontSize,\n fontColor\n } = this.data.defaultAppearanceData;\n const style = element.style;\n\n if (fontSize) {\n style.fontSize = `${fontSize}px`;\n }\n\n style.color = _util.Util.makeHexColor(fontColor[0], fontColor[1], fontColor[2]);\n\n if (this.data.textAlignment !== null) {\n style.textAlign = TEXT_ALIGNMENT[this.data.textAlignment];\n }\n }\n\n}\n\nclass CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {\n constructor(parameters) {\n super(parameters, {\n isRenderable: parameters.renderForms\n });\n }\n\n render() {\n const storage = this.annotationStorage;\n const data = this.data;\n const id = data.id;\n let value = storage.getValue(id, {\n value: data.exportValue === data.fieldValue\n }).value;\n\n if (typeof value === "string") {\n value = value !== "Off";\n storage.setValue(id, {\n value\n });\n }\n\n this.container.className = "buttonWidgetAnnotation checkBox";\n const element = document.createElement("input");\n GetElementsByNameSet.add(element);\n element.disabled = data.readOnly;\n element.type = "checkbox";\n element.name = data.fieldName;\n\n if (value) {\n element.setAttribute("checked", true);\n }\n\n element.setAttribute("id", id);\n element.setAttribute("exportValue", data.exportValue);\n element.tabIndex = DEFAULT_TAB_INDEX;\n element.addEventListener("change", event => {\n const {\n name,\n checked\n } = event.target;\n\n for (const checkbox of this._getElementsByName(name, id)) {\n const curChecked = checked && checkbox.exportValue === data.exportValue;\n\n if (checkbox.domElement) {\n checkbox.domElement.checked = curChecked;\n }\n\n storage.setValue(checkbox.id, {\n value: curChecked\n });\n }\n\n storage.setValue(id, {\n value: checked\n });\n });\n element.addEventListener("resetform", event => {\n const defaultValue = data.defaultFieldValue || "Off";\n event.target.checked = defaultValue === data.exportValue;\n });\n\n if (this.enableScripting && this.hasJSActions) {\n element.addEventListener("updatefromsandbox", jsEvent => {\n const actions = {\n value(event) {\n event.target.checked = event.detail.value !== "Off";\n storage.setValue(id, {\n value: event.target.checked\n });\n }\n\n };\n\n this._dispatchEventFromSandbox(actions, jsEvent);\n });\n\n this._setEventListeners(element, [["change", "Validate"], ["change", "Action"], ["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.checked);\n }\n\n this._setBackgroundColor(element);\n\n this._setDefaultPropertiesFromJS(element);\n\n this.container.appendChild(element);\n return this.container;\n }\n\n}\n\nclass RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {\n constructor(parameters) {\n super(parameters, {\n isRenderable: parameters.renderForms\n });\n }\n\n render() {\n this.container.className = "buttonWidgetAnnotation radioButton";\n const storage = this.annotationStorage;\n const data = this.data;\n const id = data.id;\n let value = storage.getValue(id, {\n value: data.fieldValue === data.buttonValue\n }).value;\n\n if (typeof value === "string") {\n value = value !== data.buttonValue;\n storage.setValue(id, {\n value\n });\n }\n\n const element = document.createElement("input");\n GetElementsByNameSet.add(element);\n element.disabled = data.readOnly;\n element.type = "radio";\n element.name = data.fieldName;\n\n if (value) {\n element.setAttribute("checked", true);\n }\n\n element.setAttribute("id", id);\n element.tabIndex = DEFAULT_TAB_INDEX;\n element.addEventListener("change", event => {\n const {\n name,\n checked\n } = event.target;\n\n for (const radio of this._getElementsByName(name, id)) {\n storage.setValue(radio.id, {\n value: false\n });\n }\n\n storage.setValue(id, {\n value: checked\n });\n });\n element.addEventListener("resetform", event => {\n const defaultValue = data.defaultFieldValue;\n event.target.checked = defaultValue !== null && defaultValue !== undefined && defaultValue === data.buttonValue;\n });\n\n if (this.enableScripting && this.hasJSActions) {\n const pdfButtonValue = data.buttonValue;\n element.addEventListener("updatefromsandbox", jsEvent => {\n const actions = {\n value: event => {\n const checked = pdfButtonValue === event.detail.value;\n\n for (const radio of this._getElementsByName(event.target.name)) {\n const curChecked = checked && radio.id === id;\n\n if (radio.domElement) {\n radio.domElement.checked = curChecked;\n }\n\n storage.setValue(radio.id, {\n value: curChecked\n });\n }\n }\n };\n\n this._dispatchEventFromSandbox(actions, jsEvent);\n });\n\n this._setEventListeners(element, [["change", "Validate"], ["change", "Action"], ["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.checked);\n }\n\n this._setBackgroundColor(element);\n\n this._setDefaultPropertiesFromJS(element);\n\n this.container.appendChild(element);\n return this.container;\n }\n\n}\n\nclass PushButtonWidgetAnnotationElement extends LinkAnnotationElement {\n constructor(parameters) {\n super(parameters, {\n ignoreBorder: parameters.data.hasAppearance\n });\n }\n\n render() {\n const container = super.render();\n container.className = "buttonWidgetAnnotation pushButton";\n\n if (this.data.alternativeText) {\n container.title = this.data.alternativeText;\n }\n\n this._setDefaultPropertiesFromJS(container);\n\n return container;\n }\n\n}\n\nclass ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {\n constructor(parameters) {\n super(parameters, {\n isRenderable: parameters.renderForms\n });\n }\n\n render() {\n this.container.className = "choiceWidgetAnnotation";\n const storage = this.annotationStorage;\n const id = this.data.id;\n const storedData = storage.getValue(id, {\n value: this.data.fieldValue\n });\n let {\n fontSize\n } = this.data.defaultAppearanceData;\n\n if (!fontSize) {\n fontSize = 9;\n }\n\n const fontSizeStyle = `calc(${fontSize}px * var(--zoom-factor))`;\n const selectElement = document.createElement("select");\n GetElementsByNameSet.add(selectElement);\n selectElement.disabled = this.data.readOnly;\n selectElement.name = this.data.fieldName;\n selectElement.setAttribute("id", id);\n selectElement.tabIndex = DEFAULT_TAB_INDEX;\n selectElement.style.fontSize = `${fontSize}px`;\n\n if (!this.data.combo) {\n selectElement.size = this.data.options.length;\n\n if (this.data.multiSelect) {\n selectElement.multiple = true;\n }\n }\n\n selectElement.addEventListener("resetform", event => {\n const defaultValue = this.data.defaultFieldValue;\n\n for (const option of selectElement.options) {\n option.selected = option.value === defaultValue;\n }\n });\n\n for (const option of this.data.options) {\n const optionElement = document.createElement("option");\n optionElement.textContent = option.displayValue;\n optionElement.value = option.exportValue;\n\n if (this.data.combo) {\n optionElement.style.fontSize = fontSizeStyle;\n }\n\n if (storedData.value.includes(option.exportValue)) {\n optionElement.setAttribute("selected", true);\n }\n\n selectElement.appendChild(optionElement);\n }\n\n const getValue = (event, isExport) => {\n const name = isExport ? "value" : "textContent";\n const options = event.target.options;\n\n if (!event.target.multiple) {\n return options.selectedIndex === -1 ? null : options[options.selectedIndex][name];\n }\n\n return Array.prototype.filter.call(options, option => option.selected).map(option => option[name]);\n };\n\n const getItems = event => {\n const options = event.target.options;\n return Array.prototype.map.call(options, option => {\n return {\n displayValue: option.textContent,\n exportValue: option.value\n };\n });\n };\n\n if (this.enableScripting && this.hasJSActions) {\n selectElement.addEventListener("updatefromsandbox", jsEvent => {\n const actions = {\n value(event) {\n const value = event.detail.value;\n const values = new Set(Array.isArray(value) ? value : [value]);\n\n for (const option of selectElement.options) {\n option.selected = values.has(option.value);\n }\n\n storage.setValue(id, {\n value: getValue(event, true)\n });\n },\n\n multipleSelection(event) {\n selectElement.multiple = true;\n },\n\n remove(event) {\n const options = selectElement.options;\n const index = event.detail.remove;\n options[index].selected = false;\n selectElement.remove(index);\n\n if (options.length > 0) {\n const i = Array.prototype.findIndex.call(options, option => option.selected);\n\n if (i === -1) {\n options[0].selected = true;\n }\n }\n\n storage.setValue(id, {\n value: getValue(event, true),\n items: getItems(event)\n });\n },\n\n clear(event) {\n while (selectElement.length !== 0) {\n selectElement.remove(0);\n }\n\n storage.setValue(id, {\n value: null,\n items: []\n });\n },\n\n insert(event) {\n const {\n index,\n displayValue,\n exportValue\n } = event.detail.insert;\n const optionElement = document.createElement("option");\n optionElement.textContent = displayValue;\n optionElement.value = exportValue;\n selectElement.insertBefore(optionElement, selectElement.children[index]);\n storage.setValue(id, {\n value: getValue(event, true),\n items: getItems(event)\n });\n },\n\n items(event) {\n const {\n items\n } = event.detail;\n\n while (selectElement.length !== 0) {\n selectElement.remove(0);\n }\n\n for (const item of items) {\n const {\n displayValue,\n exportValue\n } = item;\n const optionElement = document.createElement("option");\n optionElement.textContent = displayValue;\n optionElement.value = exportValue;\n selectElement.appendChild(optionElement);\n }\n\n if (selectElement.options.length > 0) {\n selectElement.options[0].selected = true;\n }\n\n storage.setValue(id, {\n value: getValue(event, true),\n items: getItems(event)\n });\n },\n\n indices(event) {\n const indices = new Set(event.detail.indices);\n\n for (const option of event.target.options) {\n option.selected = indices.has(option.index);\n }\n\n storage.setValue(id, {\n value: getValue(event, true)\n });\n },\n\n editable(event) {\n event.target.disabled = !event.detail.editable;\n }\n\n };\n\n this._dispatchEventFromSandbox(actions, jsEvent);\n });\n selectElement.addEventListener("input", event => {\n const exportValue = getValue(event, true);\n const value = getValue(event, false);\n storage.setValue(id, {\n value: exportValue\n });\n this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {\n source: this,\n detail: {\n id,\n name: "Keystroke",\n value,\n changeEx: exportValue,\n willCommit: true,\n commitKey: 1,\n keyDown: false\n }\n });\n });\n\n this._setEventListeners(selectElement, [["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"], ["input", "Action"]], event => event.target.checked);\n } else {\n selectElement.addEventListener("input", function (event) {\n storage.setValue(id, {\n value: getValue(event, true)\n });\n });\n }\n\n this._setBackgroundColor(selectElement);\n\n this._setDefaultPropertiesFromJS(selectElement);\n\n this.container.appendChild(selectElement);\n return this.container;\n }\n\n}\n\nclass PopupAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable\n });\n }\n\n render() {\n const IGNORE_TYPES = ["Line", "Square", "Circle", "PolyLine", "Polygon", "Ink"];\n this.container.className = "popupAnnotation";\n\n if (IGNORE_TYPES.includes(this.data.parentType)) {\n return this.container;\n }\n\n const selector = `[data-annotation-id="${this.data.parentId}"]`;\n const parentElements = this.layer.querySelectorAll(selector);\n\n if (parentElements.length === 0) {\n return this.container;\n }\n\n const popup = new PopupElement({\n container: this.container,\n trigger: Array.from(parentElements),\n color: this.data.color,\n titleObj: this.data.titleObj,\n modificationDate: this.data.modificationDate,\n contentsObj: this.data.contentsObj,\n richText: this.data.richText\n });\n const page = this.page;\n\n const rect = _util.Util.normalizeRect([this.data.parentRect[0], page.view[3] - this.data.parentRect[1] + page.view[1], this.data.parentRect[2], page.view[3] - this.data.parentRect[3] + page.view[1]]);\n\n const popupLeft = rect[0] + this.data.parentRect[2] - this.data.parentRect[0];\n const popupTop = rect[1];\n this.container.style.transformOrigin = `${-popupLeft}px ${-popupTop}px`;\n this.container.style.left = `${popupLeft}px`;\n this.container.style.top = `${popupTop}px`;\n this.container.appendChild(popup.render());\n return this.container;\n }\n\n}\n\nclass PopupElement {\n constructor(parameters) {\n this.container = parameters.container;\n this.trigger = parameters.trigger;\n this.color = parameters.color;\n this.titleObj = parameters.titleObj;\n this.modificationDate = parameters.modificationDate;\n this.contentsObj = parameters.contentsObj;\n this.richText = parameters.richText;\n this.hideWrapper = parameters.hideWrapper || false;\n this.pinned = false;\n }\n\n render() {\n const BACKGROUND_ENLIGHT = 0.7;\n const wrapper = document.createElement("div");\n wrapper.className = "popupWrapper";\n this.hideElement = this.hideWrapper ? wrapper : this.container;\n this.hideElement.hidden = true;\n const popup = document.createElement("div");\n popup.className = "popup";\n const color = this.color;\n\n if (color) {\n const r = BACKGROUND_ENLIGHT * (255 - color[0]) + color[0];\n const g = BACKGROUND_ENLIGHT * (255 - color[1]) + color[1];\n const b = BACKGROUND_ENLIGHT * (255 - color[2]) + color[2];\n popup.style.backgroundColor = _util.Util.makeHexColor(r | 0, g | 0, b | 0);\n }\n\n const title = document.createElement("h1");\n title.dir = this.titleObj.dir;\n title.textContent = this.titleObj.str;\n popup.appendChild(title);\n\n const dateObject = _display_utils.PDFDateString.toDateObject(this.modificationDate);\n\n if (dateObject) {\n const modificationDate = document.createElement("span");\n modificationDate.className = "popupDate";\n modificationDate.textContent = "{{date}}, {{time}}";\n modificationDate.dataset.l10nId = "annotation_date_string";\n modificationDate.dataset.l10nArgs = JSON.stringify({\n date: dateObject.toLocaleDateString(),\n time: dateObject.toLocaleTimeString()\n });\n popup.appendChild(modificationDate);\n }\n\n if (this.richText?.str && (!this.contentsObj?.str || this.contentsObj.str === this.richText.str)) {\n _xfa_layer.XfaLayer.render({\n xfaHtml: this.richText.html,\n intent: "richText",\n div: popup\n });\n\n popup.lastChild.className = "richText popupContent";\n } else {\n const contents = this._formatContents(this.contentsObj);\n\n popup.appendChild(contents);\n }\n\n if (!Array.isArray(this.trigger)) {\n this.trigger = [this.trigger];\n }\n\n for (const element of this.trigger) {\n element.addEventListener("click", this._toggle.bind(this));\n element.addEventListener("mouseover", this._show.bind(this, false));\n element.addEventListener("mouseout", this._hide.bind(this, false));\n }\n\n popup.addEventListener("click", this._hide.bind(this, true));\n wrapper.appendChild(popup);\n return wrapper;\n }\n\n _formatContents({\n str,\n dir\n }) {\n const p = document.createElement("p");\n p.className = "popupContent";\n p.dir = dir;\n const lines = str.split(/(?:\\r\\n?|\\n)/);\n\n for (let i = 0, ii = lines.length; i < ii; ++i) {\n const line = lines[i];\n p.appendChild(document.createTextNode(line));\n\n if (i < ii - 1) {\n p.appendChild(document.createElement("br"));\n }\n }\n\n return p;\n }\n\n _toggle() {\n if (this.pinned) {\n this._hide(true);\n } else {\n this._show(true);\n }\n }\n\n _show(pin = false) {\n if (pin) {\n this.pinned = true;\n }\n\n if (this.hideElement.hidden) {\n this.hideElement.hidden = false;\n this.container.style.zIndex += 1;\n }\n }\n\n _hide(unpin = true) {\n if (unpin) {\n this.pinned = false;\n }\n\n if (!this.hideElement.hidden && !this.pinned) {\n this.hideElement.hidden = true;\n this.container.style.zIndex -= 1;\n }\n }\n\n}\n\nclass FreeTextAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true\n });\n }\n\n render() {\n this.container.className = "freeTextAnnotation";\n\n if (!this.data.hasPopup) {\n this._createPopup(null, this.data);\n }\n\n return this.container;\n }\n\n}\n\nclass LineAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true\n });\n }\n\n render() {\n this.container.className = "lineAnnotation";\n const data = this.data;\n const {\n width,\n height\n } = getRectDims(data.rect);\n const svg = this.svgFactory.create(width, height);\n const line = this.svgFactory.createElement("svg:line");\n line.setAttribute("x1", data.rect[2] - data.lineCoordinates[0]);\n line.setAttribute("y1", data.rect[3] - data.lineCoordinates[1]);\n line.setAttribute("x2", data.rect[2] - data.lineCoordinates[2]);\n line.setAttribute("y2", data.rect[3] - data.lineCoordinates[3]);\n line.setAttribute("stroke-width", data.borderStyle.width || 1);\n line.setAttribute("stroke", "transparent");\n line.setAttribute("fill", "transparent");\n svg.appendChild(line);\n this.container.append(svg);\n\n this._createPopup(line, data);\n\n return this.container;\n }\n\n}\n\nclass SquareAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true\n });\n }\n\n render() {\n this.container.className = "squareAnnotation";\n const data = this.data;\n const {\n width,\n height\n } = getRectDims(data.rect);\n const svg = this.svgFactory.create(width, height);\n const borderWidth = data.borderStyle.width;\n const square = this.svgFactory.createElement("svg:rect");\n square.setAttribute("x", borderWidth / 2);\n square.setAttribute("y", borderWidth / 2);\n square.setAttribute("width", width - borderWidth);\n square.setAttribute("height", height - borderWidth);\n square.setAttribute("stroke-width", borderWidth || 1);\n square.setAttribute("stroke", "transparent");\n square.setAttribute("fill", "transparent");\n svg.appendChild(square);\n this.container.append(svg);\n\n this._createPopup(square, data);\n\n return this.container;\n }\n\n}\n\nclass CircleAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true\n });\n }\n\n render() {\n this.container.className = "circleAnnotation";\n const data = this.data;\n const {\n width,\n height\n } = getRectDims(data.rect);\n const svg = this.svgFactory.create(width, height);\n const borderWidth = data.borderStyle.width;\n const circle = this.svgFactory.createElement("svg:ellipse");\n circle.setAttribute("cx", width / 2);\n circle.setAttribute("cy", height / 2);\n circle.setAttribute("rx", width / 2 - borderWidth / 2);\n circle.setAttribute("ry", height / 2 - borderWidth / 2);\n circle.setAttribute("stroke-width", borderWidth || 1);\n circle.setAttribute("stroke", "transparent");\n circle.setAttribute("fill", "transparent");\n svg.appendChild(circle);\n this.container.append(svg);\n\n this._createPopup(circle, data);\n\n return this.container;\n }\n\n}\n\nclass PolylineAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true\n });\n this.containerClassName = "polylineAnnotation";\n this.svgElementName = "svg:polyline";\n }\n\n render() {\n this.container.className = this.containerClassName;\n const data = this.data;\n const {\n width,\n height\n } = getRectDims(data.rect);\n const svg = this.svgFactory.create(width, height);\n let points = [];\n\n for (const coordinate of data.vertices) {\n const x = coordinate.x - data.rect[0];\n const y = data.rect[3] - coordinate.y;\n points.push(x + "," + y);\n }\n\n points = points.join(" ");\n const polyline = this.svgFactory.createElement(this.svgElementName);\n polyline.setAttribute("points", points);\n polyline.setAttribute("stroke-width", data.borderStyle.width || 1);\n polyline.setAttribute("stroke", "transparent");\n polyline.setAttribute("fill", "transparent");\n svg.appendChild(polyline);\n this.container.append(svg);\n\n this._createPopup(polyline, data);\n\n return this.container;\n }\n\n}\n\nclass PolygonAnnotationElement extends PolylineAnnotationElement {\n constructor(parameters) {\n super(parameters);\n this.containerClassName = "polygonAnnotation";\n this.svgElementName = "svg:polygon";\n }\n\n}\n\nclass CaretAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true\n });\n }\n\n render() {\n this.container.className = "caretAnnotation";\n\n if (!this.data.hasPopup) {\n this._createPopup(null, this.data);\n }\n\n return this.container;\n }\n\n}\n\nclass InkAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true\n });\n this.containerClassName = "inkAnnotation";\n this.svgElementName = "svg:polyline";\n }\n\n render() {\n this.container.className = this.containerClassName;\n const data = this.data;\n const {\n width,\n height\n } = getRectDims(data.rect);\n const svg = this.svgFactory.create(width, height);\n\n for (const inkList of data.inkLists) {\n let points = [];\n\n for (const coordinate of inkList) {\n const x = coordinate.x - data.rect[0];\n const y = data.rect[3] - coordinate.y;\n points.push(`${x},${y}`);\n }\n\n points = points.join(" ");\n const polyline = this.svgFactory.createElement(this.svgElementName);\n polyline.setAttribute("points", points);\n polyline.setAttribute("stroke-width", data.borderStyle.width || 1);\n polyline.setAttribute("stroke", "transparent");\n polyline.setAttribute("fill", "transparent");\n\n this._createPopup(polyline, data);\n\n svg.appendChild(polyline);\n }\n\n this.container.append(svg);\n return this.container;\n }\n\n}\n\nclass HighlightAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true,\n createQuadrilaterals: true\n });\n }\n\n render() {\n if (!this.data.hasPopup) {\n this._createPopup(null, this.data);\n }\n\n if (this.quadrilaterals) {\n return this._renderQuadrilaterals("highlightAnnotation");\n }\n\n this.container.className = "highlightAnnotation";\n return this.container;\n }\n\n}\n\nclass UnderlineAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true,\n createQuadrilaterals: true\n });\n }\n\n render() {\n if (!this.data.hasPopup) {\n this._createPopup(null, this.data);\n }\n\n if (this.quadrilaterals) {\n return this._renderQuadrilaterals("underlineAnnotation");\n }\n\n this.container.className = "underlineAnnotation";\n return this.container;\n }\n\n}\n\nclass SquigglyAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true,\n createQuadrilaterals: true\n });\n }\n\n render() {\n if (!this.data.hasPopup) {\n this._createPopup(null, this.data);\n }\n\n if (this.quadrilaterals) {\n return this._renderQuadrilaterals("squigglyAnnotation");\n }\n\n this.container.className = "squigglyAnnotation";\n return this.container;\n }\n\n}\n\nclass StrikeOutAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true,\n createQuadrilaterals: true\n });\n }\n\n render() {\n if (!this.data.hasPopup) {\n this._createPopup(null, this.data);\n }\n\n if (this.quadrilaterals) {\n return this._renderQuadrilaterals("strikeoutAnnotation");\n }\n\n this.container.className = "strikeoutAnnotation";\n return this.container;\n }\n\n}\n\nclass StampAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n const isRenderable = !!(parameters.data.hasPopup || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str);\n super(parameters, {\n isRenderable,\n ignoreBorder: true\n });\n }\n\n render() {\n this.container.className = "stampAnnotation";\n\n if (!this.data.hasPopup) {\n this._createPopup(null, this.data);\n }\n\n return this.container;\n }\n\n}\n\nclass FileAttachmentAnnotationElement extends AnnotationElement {\n constructor(parameters) {\n super(parameters, {\n isRenderable: true\n });\n const {\n filename,\n content\n } = this.data.file;\n this.filename = (0, _display_utils.getFilenameFromUrl)(filename);\n this.content = content;\n this.linkService.eventBus?.dispatch("fileattachmentannotation", {\n source: this,\n filename,\n content\n });\n }\n\n render() {\n this.container.className = "fileAttachmentAnnotation";\n const trigger = document.createElement("div");\n trigger.style.height = this.container.style.height;\n trigger.style.width = this.container.style.width;\n trigger.addEventListener("dblclick", this._download.bind(this));\n\n if (!this.data.hasPopup && (this.data.titleObj?.str || this.data.contentsObj?.str || this.data.richText)) {\n this._createPopup(trigger, this.data);\n }\n\n this.container.appendChild(trigger);\n return this.container;\n }\n\n _download() {\n this.downloadManager?.openOrDownloadData(this.container, this.content, this.filename);\n }\n\n}\n\nclass AnnotationLayer {\n static render(parameters) {\n const sortedAnnotations = [],\n popupAnnotations = [];\n\n for (const data of parameters.annotations) {\n if (!data) {\n continue;\n }\n\n const {\n width,\n height\n } = getRectDims(data.rect);\n\n if (width <= 0 || height <= 0) {\n continue;\n }\n\n if (data.annotationType === _util.AnnotationType.POPUP) {\n popupAnnotations.push(data);\n continue;\n }\n\n sortedAnnotations.push(data);\n }\n\n if (popupAnnotations.length) {\n sortedAnnotations.push(...popupAnnotations);\n }\n\n const div = parameters.div;\n\n for (const data of sortedAnnotations) {\n const element = AnnotationElementFactory.create({\n data,\n layer: div,\n page: parameters.page,\n viewport: parameters.viewport,\n linkService: parameters.linkService,\n downloadManager: parameters.downloadManager,\n imageResourcesPath: parameters.imageResourcesPath || "",\n renderForms: parameters.renderForms !== false,\n svgFactory: new _display_utils.DOMSVGFactory(),\n annotationStorage: parameters.annotationStorage || new _annotation_storage.AnnotationStorage(),\n enableScripting: parameters.enableScripting,\n hasJSActions: parameters.hasJSActions,\n fieldObjects: parameters.fieldObjects,\n mouseState: parameters.mouseState || {\n isDown: false\n }\n });\n\n if (element.isRenderable) {\n const rendered = element.render();\n\n if (data.hidden) {\n rendered.style.visibility = "hidden";\n }\n\n if (Array.isArray(rendered)) {\n for (const renderedElement of rendered) {\n div.appendChild(renderedElement);\n }\n } else {\n if (element instanceof PopupAnnotationElement) {\n div.prepend(rendered);\n } else {\n div.appendChild(rendered);\n }\n }\n }\n }\n\n this.#setAnnotationCanvasMap(div, parameters.annotationCanvasMap);\n }\n\n static update(parameters) {\n const {\n page,\n viewport,\n annotations,\n annotationCanvasMap,\n div\n } = parameters;\n const transform = viewport.transform;\n const matrix = `matrix(${transform.join(",")})`;\n let scale, ownMatrix;\n\n for (const data of annotations) {\n const elements = div.querySelectorAll(`[data-annotation-id="${data.id}"]`);\n\n if (elements) {\n for (const element of elements) {\n if (data.hasOwnCanvas) {\n const rect = _util.Util.normalizeRect([data.rect[0], page.view[3] - data.rect[1] + page.view[1], data.rect[2], page.view[3] - data.rect[3] + page.view[1]]);\n\n if (!ownMatrix) {\n scale = Math.abs(transform[0] || transform[1]);\n const ownTransform = transform.slice();\n\n for (let i = 0; i < 4; i++) {\n ownTransform[i] = Math.sign(ownTransform[i]);\n }\n\n ownMatrix = `matrix(${ownTransform.join(",")})`;\n }\n\n const left = rect[0] * scale;\n const top = rect[1] * scale;\n element.style.left = `${left}px`;\n element.style.top = `${top}px`;\n element.style.transformOrigin = `${-left}px ${-top}px`;\n element.style.transform = ownMatrix;\n } else {\n element.style.transform = matrix;\n }\n }\n }\n }\n\n this.#setAnnotationCanvasMap(div, annotationCanvasMap);\n div.hidden = false;\n }\n\n static #setAnnotationCanvasMap(div, annotationCanvasMap) {\n if (!annotationCanvasMap) {\n return;\n }\n\n for (const [id, canvas] of annotationCanvasMap) {\n const element = div.querySelector(`[data-annotation-id="${id}"]`);\n\n if (!element) {\n continue;\n }\n\n const {\n firstChild\n } = element;\n\n if (firstChild.nodeName === "CANVAS") {\n element.replaceChild(canvas, firstChild);\n } else {\n element.insertBefore(canvas, firstChild);\n }\n }\n\n annotationCanvasMap.clear();\n }\n\n}\n\nexports.AnnotationLayer = AnnotationLayer;\n\n/***/ }),\n/* 21 */\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.ColorConverters = void 0;\n\nfunction makeColorComp(n) {\n return Math.floor(Math.max(0, Math.min(1, n)) * 255).toString(16).padStart(2, "0");\n}\n\nclass ColorConverters {\n static CMYK_G([c, y, m, k]) {\n return ["G", 1 - Math.min(1, 0.3 * c + 0.59 * m + 0.11 * y + k)];\n }\n\n static G_CMYK([g]) {\n return ["CMYK", 0, 0, 0, 1 - g];\n }\n\n static G_RGB([g]) {\n return ["RGB", g, g, g];\n }\n\n static G_HTML([g]) {\n const G = makeColorComp(g);\n return `#${G}${G}${G}`;\n }\n\n static RGB_G([r, g, b]) {\n return ["G", 0.3 * r + 0.59 * g + 0.11 * b];\n }\n\n static RGB_HTML([r, g, b]) {\n const R = makeColorComp(r);\n const G = makeColorComp(g);\n const B = makeColorComp(b);\n return `#${R}${G}${B}`;\n }\n\n static T_HTML() {\n return "#00000000";\n }\n\n static CMYK_RGB([c, y, m, k]) {\n return ["RGB", 1 - Math.min(1, c + k), 1 - Math.min(1, m + k), 1 - Math.min(1, y + k)];\n }\n\n static CMYK_HTML(components) {\n return this.RGB_HTML(this.CMYK_RGB(components));\n }\n\n static RGB_CMYK([r, g, b]) {\n const c = 1 - r;\n const m = 1 - g;\n const y = 1 - b;\n const k = Math.min(c, m, y);\n return ["CMYK", c, m, y, k];\n }\n\n}\n\nexports.ColorConverters = ColorConverters;\n\n/***/ }),\n/* 22 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.XfaLayer = void 0;\n\nvar _xfa_text = __w_pdfjs_require__(18);\n\nclass XfaLayer {\n static setupStorage(html, id, element, storage, intent) {\n const storedData = storage.getValue(id, {\n value: null\n });\n\n switch (element.name) {\n case "textarea":\n if (storedData.value !== null) {\n html.textContent = storedData.value;\n }\n\n if (intent === "print") {\n break;\n }\n\n html.addEventListener("input", event => {\n storage.setValue(id, {\n value: event.target.value\n });\n });\n break;\n\n case "input":\n if (element.attributes.type === "radio" || element.attributes.type === "checkbox") {\n if (storedData.value === element.attributes.xfaOn) {\n html.setAttribute("checked", true);\n } else if (storedData.value === element.attributes.xfaOff) {\n html.removeAttribute("checked");\n }\n\n if (intent === "print") {\n break;\n }\n\n html.addEventListener("change", event => {\n storage.setValue(id, {\n value: event.target.checked ? event.target.getAttribute("xfaOn") : event.target.getAttribute("xfaOff")\n });\n });\n } else {\n if (storedData.value !== null) {\n html.setAttribute("value", storedData.value);\n }\n\n if (intent === "print") {\n break;\n }\n\n html.addEventListener("input", event => {\n storage.setValue(id, {\n value: event.target.value\n });\n });\n }\n\n break;\n\n case "select":\n if (storedData.value !== null) {\n for (const option of element.children) {\n if (option.attributes.value === storedData.value) {\n option.attributes.selected = true;\n }\n }\n }\n\n html.addEventListener("input", event => {\n const options = event.target.options;\n const value = options.selectedIndex === -1 ? "" : options[options.selectedIndex].value;\n storage.setValue(id, {\n value\n });\n });\n break;\n }\n }\n\n static setAttributes({\n html,\n element,\n storage = null,\n intent,\n linkService\n }) {\n const {\n attributes\n } = element;\n const isHTMLAnchorElement = html instanceof HTMLAnchorElement;\n\n if (attributes.type === "radio") {\n attributes.name = `${attributes.name}-${intent}`;\n }\n\n for (const [key, value] of Object.entries(attributes)) {\n if (value === null || value === undefined || key === "dataId") {\n continue;\n }\n\n if (key !== "style") {\n if (key === "textContent") {\n html.textContent = value;\n } else if (key === "class") {\n if (value.length) {\n html.setAttribute(key, value.join(" "));\n }\n } else {\n if (isHTMLAnchorElement && (key === "href" || key === "newWindow")) {\n continue;\n }\n\n html.setAttribute(key, value);\n }\n } else {\n Object.assign(html.style, value);\n }\n }\n\n if (isHTMLAnchorElement) {\n linkService.addLinkAttributes(html, attributes.href, attributes.newWindow);\n }\n\n if (storage && attributes.dataId) {\n this.setupStorage(html, attributes.dataId, element, storage);\n }\n }\n\n static render(parameters) {\n const storage = parameters.annotationStorage;\n const linkService = parameters.linkService;\n const root = parameters.xfaHtml;\n const intent = parameters.intent || "display";\n const rootHtml = document.createElement(root.name);\n\n if (root.attributes) {\n this.setAttributes({\n html: rootHtml,\n element: root,\n intent,\n linkService\n });\n }\n\n const stack = [[root, -1, rootHtml]];\n const rootDiv = parameters.div;\n rootDiv.appendChild(rootHtml);\n\n if (parameters.viewport) {\n const transform = `matrix(${parameters.viewport.transform.join(",")})`;\n rootDiv.style.transform = transform;\n }\n\n if (intent !== "richText") {\n rootDiv.setAttribute("class", "xfaLayer xfaFont");\n }\n\n const textDivs = [];\n\n while (stack.length > 0) {\n const [parent, i, html] = stack[stack.length - 1];\n\n if (i + 1 === parent.children.length) {\n stack.pop();\n continue;\n }\n\n const child = parent.children[++stack[stack.length - 1][1]];\n\n if (child === null) {\n continue;\n }\n\n const {\n name\n } = child;\n\n if (name === "#text") {\n const node = document.createTextNode(child.value);\n textDivs.push(node);\n html.appendChild(node);\n continue;\n }\n\n let childHtml;\n\n if (child?.attributes?.xmlns) {\n childHtml = document.createElementNS(child.attributes.xmlns, name);\n } else {\n childHtml = document.createElement(name);\n }\n\n html.appendChild(childHtml);\n\n if (child.attributes) {\n this.setAttributes({\n html: childHtml,\n element: child,\n storage,\n intent,\n linkService\n });\n }\n\n if (child.children && child.children.length > 0) {\n stack.push([child, -1, childHtml]);\n } else if (child.value) {\n const node = document.createTextNode(child.value);\n\n if (_xfa_text.XfaText.shouldBuildText(name)) {\n textDivs.push(node);\n }\n\n childHtml.appendChild(node);\n }\n }\n\n for (const el of rootDiv.querySelectorAll(".xfaNonInteractive input, .xfaNonInteractive textarea")) {\n el.setAttribute("readOnly", true);\n }\n\n return {\n textDivs\n };\n }\n\n static update(parameters) {\n const transform = `matrix(${parameters.viewport.transform.join(",")})`;\n parameters.div.style.transform = transform;\n parameters.div.hidden = false;\n }\n\n}\n\nexports.XfaLayer = XfaLayer;\n\n/***/ }),\n/* 23 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.renderTextLayer = renderTextLayer;\n\nvar _util = __w_pdfjs_require__(1);\n\nconst MAX_TEXT_DIVS_TO_RENDER = 100000;\nconst DEFAULT_FONT_SIZE = 30;\nconst DEFAULT_FONT_ASCENT = 0.8;\nconst ascentCache = new Map();\nconst AllWhitespaceRegexp = /^\\s+$/g;\n\nfunction getAscent(fontFamily, ctx) {\n const cachedAscent = ascentCache.get(fontFamily);\n\n if (cachedAscent) {\n return cachedAscent;\n }\n\n ctx.save();\n ctx.font = `${DEFAULT_FONT_SIZE}px ${fontFamily}`;\n const metrics = ctx.measureText("");\n let ascent = metrics.fontBoundingBoxAscent;\n let descent = Math.abs(metrics.fontBoundingBoxDescent);\n\n if (ascent) {\n ctx.restore();\n const ratio = ascent / (ascent + descent);\n ascentCache.set(fontFamily, ratio);\n return ratio;\n }\n\n ctx.strokeStyle = "red";\n ctx.clearRect(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE);\n ctx.strokeText("g", 0, 0);\n let pixels = ctx.getImageData(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE).data;\n descent = 0;\n\n for (let i = pixels.length - 1 - 3; i >= 0; i -= 4) {\n if (pixels[i] > 0) {\n descent = Math.ceil(i / 4 / DEFAULT_FONT_SIZE);\n break;\n }\n }\n\n ctx.clearRect(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE);\n ctx.strokeText("A", 0, DEFAULT_FONT_SIZE);\n pixels = ctx.getImageData(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE).data;\n ascent = 0;\n\n for (let i = 0, ii = pixels.length; i < ii; i += 4) {\n if (pixels[i] > 0) {\n ascent = DEFAULT_FONT_SIZE - Math.floor(i / 4 / DEFAULT_FONT_SIZE);\n break;\n }\n }\n\n ctx.restore();\n\n if (ascent) {\n const ratio = ascent / (ascent + descent);\n ascentCache.set(fontFamily, ratio);\n return ratio;\n }\n\n ascentCache.set(fontFamily, DEFAULT_FONT_ASCENT);\n return DEFAULT_FONT_ASCENT;\n}\n\nfunction appendText(task, geom, styles, ctx) {\n const textDiv = document.createElement("span");\n const textDivProperties = task._enhanceTextSelection ? {\n angle: 0,\n canvasWidth: 0,\n hasText: geom.str !== "",\n hasEOL: geom.hasEOL,\n originalTransform: null,\n paddingBottom: 0,\n paddingLeft: 0,\n paddingRight: 0,\n paddingTop: 0,\n scale: 1\n } : {\n angle: 0,\n canvasWidth: 0,\n hasText: geom.str !== "",\n hasEOL: geom.hasEOL\n };\n\n task._textDivs.push(textDiv);\n\n const tx = _util.Util.transform(task._viewport.transform, geom.transform);\n\n let angle = Math.atan2(tx[1], tx[0]);\n const style = styles[geom.fontName];\n\n if (style.vertical) {\n angle += Math.PI / 2;\n }\n\n const fontHeight = Math.hypot(tx[2], tx[3]);\n const fontAscent = fontHeight * getAscent(style.fontFamily, ctx);\n let left, top;\n\n if (angle === 0) {\n left = tx[4];\n top = tx[5] - fontAscent;\n } else {\n left = tx[4] + fontAscent * Math.sin(angle);\n top = tx[5] - fontAscent * Math.cos(angle);\n }\n\n textDiv.style.left = `${left}px`;\n textDiv.style.top = `${top}px`;\n textDiv.style.fontSize = `${fontHeight}px`;\n textDiv.style.fontFamily = style.fontFamily;\n textDiv.setAttribute("role", "presentation");\n textDiv.textContent = geom.str;\n textDiv.dir = geom.dir;\n\n if (task._fontInspectorEnabled) {\n textDiv.dataset.fontName = geom.fontName;\n }\n\n if (angle !== 0) {\n textDivProperties.angle = angle * (180 / Math.PI);\n }\n\n let shouldScaleText = false;\n\n if (geom.str.length > 1 || task._enhanceTextSelection && AllWhitespaceRegexp.test(geom.str)) {\n shouldScaleText = true;\n } else if (geom.str !== " " && geom.transform[0] !== geom.transform[3]) {\n const absScaleX = Math.abs(geom.transform[0]),\n absScaleY = Math.abs(geom.transform[3]);\n\n if (absScaleX !== absScaleY && Math.max(absScaleX, absScaleY) / Math.min(absScaleX, absScaleY) > 1.5) {\n shouldScaleText = true;\n }\n }\n\n if (shouldScaleText) {\n if (style.vertical) {\n textDivProperties.canvasWidth = geom.height * task._viewport.scale;\n } else {\n textDivProperties.canvasWidth = geom.width * task._viewport.scale;\n }\n }\n\n task._textDivProperties.set(textDiv, textDivProperties);\n\n if (task._textContentStream) {\n task._layoutText(textDiv);\n }\n\n if (task._enhanceTextSelection && textDivProperties.hasText) {\n let angleCos = 1,\n angleSin = 0;\n\n if (angle !== 0) {\n angleCos = Math.cos(angle);\n angleSin = Math.sin(angle);\n }\n\n const divWidth = (style.vertical ? geom.height : geom.width) * task._viewport.scale;\n const divHeight = fontHeight;\n let m, b;\n\n if (angle !== 0) {\n m = [angleCos, angleSin, -angleSin, angleCos, left, top];\n b = _util.Util.getAxialAlignedBoundingBox([0, 0, divWidth, divHeight], m);\n } else {\n b = [left, top, left + divWidth, top + divHeight];\n }\n\n task._bounds.push({\n left: b[0],\n top: b[1],\n right: b[2],\n bottom: b[3],\n div: textDiv,\n size: [divWidth, divHeight],\n m\n });\n }\n}\n\nfunction render(task) {\n if (task._canceled) {\n return;\n }\n\n const textDivs = task._textDivs;\n const capability = task._capability;\n const textDivsLength = textDivs.length;\n\n if (textDivsLength > MAX_TEXT_DIVS_TO_RENDER) {\n task._renderingDone = true;\n capability.resolve();\n return;\n }\n\n if (!task._textContentStream) {\n for (let i = 0; i < textDivsLength; i++) {\n task._layoutText(textDivs[i]);\n }\n }\n\n task._renderingDone = true;\n capability.resolve();\n}\n\nfunction findPositiveMin(ts, offset, count) {\n let result = 0;\n\n for (let i = 0; i < count; i++) {\n const t = ts[offset++];\n\n if (t > 0) {\n result = result ? Math.min(t, result) : t;\n }\n }\n\n return result;\n}\n\nfunction expand(task) {\n const bounds = task._bounds;\n const viewport = task._viewport;\n const expanded = expandBounds(viewport.width, viewport.height, bounds);\n\n for (let i = 0; i < expanded.length; i++) {\n const div = bounds[i].div;\n\n const divProperties = task._textDivProperties.get(div);\n\n if (divProperties.angle === 0) {\n divProperties.paddingLeft = bounds[i].left - expanded[i].left;\n divProperties.paddingTop = bounds[i].top - expanded[i].top;\n divProperties.paddingRight = expanded[i].right - bounds[i].right;\n divProperties.paddingBottom = expanded[i].bottom - bounds[i].bottom;\n\n task._textDivProperties.set(div, divProperties);\n\n continue;\n }\n\n const e = expanded[i],\n b = bounds[i];\n const m = b.m,\n c = m[0],\n s = m[1];\n const points = [[0, 0], [0, b.size[1]], [b.size[0], 0], b.size];\n const ts = new Float64Array(64);\n\n for (let j = 0, jj = points.length; j < jj; j++) {\n const t = _util.Util.applyTransform(points[j], m);\n\n ts[j + 0] = c && (e.left - t[0]) / c;\n ts[j + 4] = s && (e.top - t[1]) / s;\n ts[j + 8] = c && (e.right - t[0]) / c;\n ts[j + 12] = s && (e.bottom - t[1]) / s;\n ts[j + 16] = s && (e.left - t[0]) / -s;\n ts[j + 20] = c && (e.top - t[1]) / c;\n ts[j + 24] = s && (e.right - t[0]) / -s;\n ts[j + 28] = c && (e.bottom - t[1]) / c;\n ts[j + 32] = c && (e.left - t[0]) / -c;\n ts[j + 36] = s && (e.top - t[1]) / -s;\n ts[j + 40] = c && (e.right - t[0]) / -c;\n ts[j + 44] = s && (e.bottom - t[1]) / -s;\n ts[j + 48] = s && (e.left - t[0]) / s;\n ts[j + 52] = c && (e.top - t[1]) / -c;\n ts[j + 56] = s && (e.right - t[0]) / s;\n ts[j + 60] = c && (e.bottom - t[1]) / -c;\n }\n\n const boxScale = 1 + Math.min(Math.abs(c), Math.abs(s));\n divProperties.paddingLeft = findPositiveMin(ts, 32, 16) / boxScale;\n divProperties.paddingTop = findPositiveMin(ts, 48, 16) / boxScale;\n divProperties.paddingRight = findPositiveMin(ts, 0, 16) / boxScale;\n divProperties.paddingBottom = findPositiveMin(ts, 16, 16) / boxScale;\n\n task._textDivProperties.set(div, divProperties);\n }\n}\n\nfunction expandBounds(width, height, boxes) {\n const bounds = boxes.map(function (box, i) {\n return {\n x1: box.left,\n y1: box.top,\n x2: box.right,\n y2: box.bottom,\n index: i,\n x1New: undefined,\n x2New: undefined\n };\n });\n expandBoundsLTR(width, bounds);\n const expanded = new Array(boxes.length);\n\n for (const b of bounds) {\n const i = b.index;\n expanded[i] = {\n left: b.x1New,\n top: 0,\n right: b.x2New,\n bottom: 0\n };\n }\n\n boxes.map(function (box, i) {\n const e = expanded[i],\n b = bounds[i];\n b.x1 = box.top;\n b.y1 = width - e.right;\n b.x2 = box.bottom;\n b.y2 = width - e.left;\n b.index = i;\n b.x1New = undefined;\n b.x2New = undefined;\n });\n expandBoundsLTR(height, bounds);\n\n for (const b of bounds) {\n const i = b.index;\n expanded[i].top = b.x1New;\n expanded[i].bottom = b.x2New;\n }\n\n return expanded;\n}\n\nfunction expandBoundsLTR(width, bounds) {\n bounds.sort(function (a, b) {\n return a.x1 - b.x1 || a.index - b.index;\n });\n const fakeBoundary = {\n x1: -Infinity,\n y1: -Infinity,\n x2: 0,\n y2: Infinity,\n index: -1,\n x1New: 0,\n x2New: 0\n };\n const horizon = [{\n start: -Infinity,\n end: Infinity,\n boundary: fakeBoundary\n }];\n\n for (const boundary of bounds) {\n let i = 0;\n\n while (i < horizon.length && horizon[i].end <= boundary.y1) {\n i++;\n }\n\n let j = horizon.length - 1;\n\n while (j >= 0 && horizon[j].start >= boundary.y2) {\n j--;\n }\n\n let horizonPart, affectedBoundary;\n let q,\n k,\n maxXNew = -Infinity;\n\n for (q = i; q <= j; q++) {\n horizonPart = horizon[q];\n affectedBoundary = horizonPart.boundary;\n let xNew;\n\n if (affectedBoundary.x2 > boundary.x1) {\n xNew = affectedBoundary.index > boundary.index ? affectedBoundary.x1New : boundary.x1;\n } else if (affectedBoundary.x2New === undefined) {\n xNew = (affectedBoundary.x2 + boundary.x1) / 2;\n } else {\n xNew = affectedBoundary.x2New;\n }\n\n if (xNew > maxXNew) {\n maxXNew = xNew;\n }\n }\n\n boundary.x1New = maxXNew;\n\n for (q = i; q <= j; q++) {\n horizonPart = horizon[q];\n affectedBoundary = horizonPart.boundary;\n\n if (affectedBoundary.x2New === undefined) {\n if (affectedBoundary.x2 > boundary.x1) {\n if (affectedBoundary.index > boundary.index) {\n affectedBoundary.x2New = affectedBoundary.x2;\n }\n } else {\n affectedBoundary.x2New = maxXNew;\n }\n } else if (affectedBoundary.x2New > maxXNew) {\n affectedBoundary.x2New = Math.max(maxXNew, affectedBoundary.x2);\n }\n }\n\n const changedHorizon = [];\n let lastBoundary = null;\n\n for (q = i; q <= j; q++) {\n horizonPart = horizon[q];\n affectedBoundary = horizonPart.boundary;\n const useBoundary = affectedBoundary.x2 > boundary.x2 ? affectedBoundary : boundary;\n\n if (lastBoundary === useBoundary) {\n changedHorizon[changedHorizon.length - 1].end = horizonPart.end;\n } else {\n changedHorizon.push({\n start: horizonPart.start,\n end: horizonPart.end,\n boundary: useBoundary\n });\n lastBoundary = useBoundary;\n }\n }\n\n if (horizon[i].start < boundary.y1) {\n changedHorizon[0].start = boundary.y1;\n changedHorizon.unshift({\n start: horizon[i].start,\n end: boundary.y1,\n boundary: horizon[i].boundary\n });\n }\n\n if (boundary.y2 < horizon[j].end) {\n changedHorizon[changedHorizon.length - 1].end = boundary.y2;\n changedHorizon.push({\n start: boundary.y2,\n end: horizon[j].end,\n boundary: horizon[j].boundary\n });\n }\n\n for (q = i; q <= j; q++) {\n horizonPart = horizon[q];\n affectedBoundary = horizonPart.boundary;\n\n if (affectedBoundary.x2New !== undefined) {\n continue;\n }\n\n let used = false;\n\n for (k = i - 1; !used && k >= 0 && horizon[k].start >= affectedBoundary.y1; k--) {\n used = horizon[k].boundary === affectedBoundary;\n }\n\n for (k = j + 1; !used && k < horizon.length && horizon[k].end <= affectedBoundary.y2; k++) {\n used = horizon[k].boundary === affectedBoundary;\n }\n\n for (k = 0; !used && k < changedHorizon.length; k++) {\n used = changedHorizon[k].boundary === affectedBoundary;\n }\n\n if (!used) {\n affectedBoundary.x2New = maxXNew;\n }\n }\n\n Array.prototype.splice.apply(horizon, [i, j - i + 1].concat(changedHorizon));\n }\n\n for (const horizonPart of horizon) {\n const affectedBoundary = horizonPart.boundary;\n\n if (affectedBoundary.x2New === undefined) {\n affectedBoundary.x2New = Math.max(width, affectedBoundary.x2);\n }\n }\n}\n\nclass TextLayerRenderTask {\n constructor({\n textContent,\n textContentStream,\n container,\n viewport,\n textDivs,\n textContentItemsStr,\n enhanceTextSelection\n }) {\n this._textContent = textContent;\n this._textContentStream = textContentStream;\n this._container = container;\n this._document = container.ownerDocument;\n this._viewport = viewport;\n this._textDivs = textDivs || [];\n this._textContentItemsStr = textContentItemsStr || [];\n this._enhanceTextSelection = !!enhanceTextSelection;\n this._fontInspectorEnabled = !!globalThis.FontInspector?.enabled;\n this._reader = null;\n this._layoutTextLastFontSize = null;\n this._layoutTextLastFontFamily = null;\n this._layoutTextCtx = null;\n this._textDivProperties = new WeakMap();\n this._renderingDone = false;\n this._canceled = false;\n this._capability = (0, _util.createPromiseCapability)();\n this._renderTimer = null;\n this._bounds = [];\n\n this._capability.promise.finally(() => {\n if (!this._enhanceTextSelection) {\n this._textDivProperties = null;\n }\n\n if (this._layoutTextCtx) {\n this._layoutTextCtx.canvas.width = 0;\n this._layoutTextCtx.canvas.height = 0;\n this._layoutTextCtx = null;\n }\n }).catch(() => {});\n }\n\n get promise() {\n return this._capability.promise;\n }\n\n cancel() {\n this._canceled = true;\n\n if (this._reader) {\n this._reader.cancel(new _util.AbortException("TextLayer task cancelled.")).catch(() => {});\n\n this._reader = null;\n }\n\n if (this._renderTimer !== null) {\n clearTimeout(this._renderTimer);\n this._renderTimer = null;\n }\n\n this._capability.reject(new Error("TextLayer task cancelled."));\n }\n\n _processItems(items, styleCache) {\n for (let i = 0, len = items.length; i < len; i++) {\n if (items[i].str === undefined) {\n if (items[i].type === "beginMarkedContentProps" || items[i].type === "beginMarkedContent") {\n const parent = this._container;\n this._container = document.createElement("span");\n\n this._container.classList.add("markedContent");\n\n if (items[i].id !== null) {\n this._container.setAttribute("id", `${items[i].id}`);\n }\n\n parent.appendChild(this._container);\n } else if (items[i].type === "endMarkedContent") {\n this._container = this._container.parentNode;\n }\n\n continue;\n }\n\n this._textContentItemsStr.push(items[i].str);\n\n appendText(this, items[i], styleCache, this._layoutTextCtx);\n }\n }\n\n _layoutText(textDiv) {\n const textDivProperties = this._textDivProperties.get(textDiv);\n\n let transform = "";\n\n if (textDivProperties.canvasWidth !== 0 && textDivProperties.hasText) {\n const {\n fontSize,\n fontFamily\n } = textDiv.style;\n\n if (fontSize !== this._layoutTextLastFontSize || fontFamily !== this._layoutTextLastFontFamily) {\n this._layoutTextCtx.font = `${fontSize} ${fontFamily}`;\n this._layoutTextLastFontSize = fontSize;\n this._layoutTextLastFontFamily = fontFamily;\n }\n\n const {\n width\n } = this._layoutTextCtx.measureText(textDiv.textContent);\n\n if (width > 0) {\n const scale = textDivProperties.canvasWidth / width;\n\n if (this._enhanceTextSelection) {\n textDivProperties.scale = scale;\n }\n\n transform = `scaleX(${scale})`;\n }\n }\n\n if (textDivProperties.angle !== 0) {\n transform = `rotate(${textDivProperties.angle}deg) ${transform}`;\n }\n\n if (transform.length > 0) {\n if (this._enhanceTextSelection) {\n textDivProperties.originalTransform = transform;\n }\n\n textDiv.style.transform = transform;\n }\n\n if (textDivProperties.hasText) {\n this._container.appendChild(textDiv);\n }\n\n if (textDivProperties.hasEOL) {\n const br = document.createElement("br");\n br.setAttribute("role", "presentation");\n\n this._container.appendChild(br);\n }\n }\n\n _render(timeout = 0) {\n const capability = (0, _util.createPromiseCapability)();\n let styleCache = Object.create(null);\n\n const canvas = this._document.createElement("canvas");\n\n canvas.height = canvas.width = DEFAULT_FONT_SIZE;\n this._layoutTextCtx = canvas.getContext("2d", {\n alpha: false\n });\n\n if (this._textContent) {\n const textItems = this._textContent.items;\n const textStyles = this._textContent.styles;\n\n this._processItems(textItems, textStyles);\n\n capability.resolve();\n } else if (this._textContentStream) {\n const pump = () => {\n this._reader.read().then(({\n value,\n done\n }) => {\n if (done) {\n capability.resolve();\n return;\n }\n\n Object.assign(styleCache, value.styles);\n\n this._processItems(value.items, styleCache);\n\n pump();\n }, capability.reject);\n };\n\n this._reader = this._textContentStream.getReader();\n pump();\n } else {\n throw new Error(\'Neither "textContent" nor "textContentStream" parameters specified.\');\n }\n\n capability.promise.then(() => {\n styleCache = null;\n\n if (!timeout) {\n render(this);\n } else {\n this._renderTimer = setTimeout(() => {\n render(this);\n this._renderTimer = null;\n }, timeout);\n }\n }, this._capability.reject);\n }\n\n expandTextDivs(expandDivs = false) {\n if (!this._enhanceTextSelection || !this._renderingDone) {\n return;\n }\n\n if (this._bounds !== null) {\n expand(this);\n this._bounds = null;\n }\n\n const transformBuf = [],\n paddingBuf = [];\n\n for (let i = 0, ii = this._textDivs.length; i < ii; i++) {\n const div = this._textDivs[i];\n\n const divProps = this._textDivProperties.get(div);\n\n if (!divProps.hasText) {\n continue;\n }\n\n if (expandDivs) {\n transformBuf.length = 0;\n paddingBuf.length = 0;\n\n if (divProps.originalTransform) {\n transformBuf.push(divProps.originalTransform);\n }\n\n if (divProps.paddingTop > 0) {\n paddingBuf.push(`${divProps.paddingTop}px`);\n transformBuf.push(`translateY(${-divProps.paddingTop}px)`);\n } else {\n paddingBuf.push(0);\n }\n\n if (divProps.paddingRight > 0) {\n paddingBuf.push(`${divProps.paddingRight / divProps.scale}px`);\n } else {\n paddingBuf.push(0);\n }\n\n if (divProps.paddingBottom > 0) {\n paddingBuf.push(`${divProps.paddingBottom}px`);\n } else {\n paddingBuf.push(0);\n }\n\n if (divProps.paddingLeft > 0) {\n paddingBuf.push(`${divProps.paddingLeft / divProps.scale}px`);\n transformBuf.push(`translateX(${-divProps.paddingLeft / divProps.scale}px)`);\n } else {\n paddingBuf.push(0);\n }\n\n div.style.padding = paddingBuf.join(" ");\n\n if (transformBuf.length) {\n div.style.transform = transformBuf.join(" ");\n }\n } else {\n div.style.padding = null;\n div.style.transform = divProps.originalTransform;\n }\n }\n }\n\n}\n\nfunction renderTextLayer(renderParameters) {\n const task = new TextLayerRenderTask({\n textContent: renderParameters.textContent,\n textContentStream: renderParameters.textContentStream,\n container: renderParameters.container,\n viewport: renderParameters.viewport,\n textDivs: renderParameters.textDivs,\n textContentItemsStr: renderParameters.textContentItemsStr,\n enhanceTextSelection: renderParameters.enhanceTextSelection\n });\n\n task._render(renderParameters.timeout);\n\n return task;\n}\n\n/***/ }),\n/* 24 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.SVGGraphics = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _display_utils = __w_pdfjs_require__(5);\n\nvar _is_node = __w_pdfjs_require__(3);\n\nlet SVGGraphics = class {\n constructor() {\n (0, _util.unreachable)("Not implemented: SVGGraphics");\n }\n\n};\nexports.SVGGraphics = SVGGraphics;\n{\n const SVG_DEFAULTS = {\n fontStyle: "normal",\n fontWeight: "normal",\n fillColor: "#000000"\n };\n const XML_NS = "http://www.w3.org/XML/1998/namespace";\n const XLINK_NS = "http://www.w3.org/1999/xlink";\n const LINE_CAP_STYLES = ["butt", "round", "square"];\n const LINE_JOIN_STYLES = ["miter", "round", "bevel"];\n\n const createObjectURL = function (data, contentType = "", forceDataSchema = false) {\n if (URL.createObjectURL && typeof Blob !== "undefined" && !forceDataSchema) {\n return URL.createObjectURL(new Blob([data], {\n type: contentType\n }));\n }\n\n const digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";\n let buffer = `data:${contentType};base64,`;\n\n for (let i = 0, ii = data.length; i < ii; i += 3) {\n const b1 = data[i] & 0xff;\n const b2 = data[i + 1] & 0xff;\n const b3 = data[i + 2] & 0xff;\n const d1 = b1 >> 2,\n d2 = (b1 & 3) << 4 | b2 >> 4;\n const d3 = i + 1 < ii ? (b2 & 0xf) << 2 | b3 >> 6 : 64;\n const d4 = i + 2 < ii ? b3 & 0x3f : 64;\n buffer += digits[d1] + digits[d2] + digits[d3] + digits[d4];\n }\n\n return buffer;\n };\n\n const convertImgDataToPng = function () {\n const PNG_HEADER = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);\n const CHUNK_WRAPPER_SIZE = 12;\n const crcTable = new Int32Array(256);\n\n for (let i = 0; i < 256; i++) {\n let c = i;\n\n for (let h = 0; h < 8; h++) {\n if (c & 1) {\n c = 0xedb88320 ^ c >> 1 & 0x7fffffff;\n } else {\n c = c >> 1 & 0x7fffffff;\n }\n }\n\n crcTable[i] = c;\n }\n\n function crc32(data, start, end) {\n let crc = -1;\n\n for (let i = start; i < end; i++) {\n const a = (crc ^ data[i]) & 0xff;\n const b = crcTable[a];\n crc = crc >>> 8 ^ b;\n }\n\n return crc ^ -1;\n }\n\n function writePngChunk(type, body, data, offset) {\n let p = offset;\n const len = body.length;\n data[p] = len >> 24 & 0xff;\n data[p + 1] = len >> 16 & 0xff;\n data[p + 2] = len >> 8 & 0xff;\n data[p + 3] = len & 0xff;\n p += 4;\n data[p] = type.charCodeAt(0) & 0xff;\n data[p + 1] = type.charCodeAt(1) & 0xff;\n data[p + 2] = type.charCodeAt(2) & 0xff;\n data[p + 3] = type.charCodeAt(3) & 0xff;\n p += 4;\n data.set(body, p);\n p += body.length;\n const crc = crc32(data, offset + 4, p);\n data[p] = crc >> 24 & 0xff;\n data[p + 1] = crc >> 16 & 0xff;\n data[p + 2] = crc >> 8 & 0xff;\n data[p + 3] = crc & 0xff;\n }\n\n function adler32(data, start, end) {\n let a = 1;\n let b = 0;\n\n for (let i = start; i < end; ++i) {\n a = (a + (data[i] & 0xff)) % 65521;\n b = (b + a) % 65521;\n }\n\n return b << 16 | a;\n }\n\n function deflateSync(literals) {\n if (!_is_node.isNodeJS) {\n return deflateSyncUncompressed(literals);\n }\n\n try {\n let input;\n\n if (parseInt(process.versions.node) >= 8) {\n input = literals;\n } else {\n input = Buffer.from(literals);\n }\n\n const output = __webpack_require__(258).deflateSync(input, {\n level: 9\n });\n\n return output instanceof Uint8Array ? output : new Uint8Array(output);\n } catch (e) {\n (0, _util.warn)("Not compressing PNG because zlib.deflateSync is unavailable: " + e);\n }\n\n return deflateSyncUncompressed(literals);\n }\n\n function deflateSyncUncompressed(literals) {\n let len = literals.length;\n const maxBlockLength = 0xffff;\n const deflateBlocks = Math.ceil(len / maxBlockLength);\n const idat = new Uint8Array(2 + len + deflateBlocks * 5 + 4);\n let pi = 0;\n idat[pi++] = 0x78;\n idat[pi++] = 0x9c;\n let pos = 0;\n\n while (len > maxBlockLength) {\n idat[pi++] = 0x00;\n idat[pi++] = 0xff;\n idat[pi++] = 0xff;\n idat[pi++] = 0x00;\n idat[pi++] = 0x00;\n idat.set(literals.subarray(pos, pos + maxBlockLength), pi);\n pi += maxBlockLength;\n pos += maxBlockLength;\n len -= maxBlockLength;\n }\n\n idat[pi++] = 0x01;\n idat[pi++] = len & 0xff;\n idat[pi++] = len >> 8 & 0xff;\n idat[pi++] = ~len & 0xffff & 0xff;\n idat[pi++] = (~len & 0xffff) >> 8 & 0xff;\n idat.set(literals.subarray(pos), pi);\n pi += literals.length - pos;\n const adler = adler32(literals, 0, literals.length);\n idat[pi++] = adler >> 24 & 0xff;\n idat[pi++] = adler >> 16 & 0xff;\n idat[pi++] = adler >> 8 & 0xff;\n idat[pi++] = adler & 0xff;\n return idat;\n }\n\n function encode(imgData, kind, forceDataSchema, isMask) {\n const width = imgData.width;\n const height = imgData.height;\n let bitDepth, colorType, lineSize;\n const bytes = imgData.data;\n\n switch (kind) {\n case _util.ImageKind.GRAYSCALE_1BPP:\n colorType = 0;\n bitDepth = 1;\n lineSize = width + 7 >> 3;\n break;\n\n case _util.ImageKind.RGB_24BPP:\n colorType = 2;\n bitDepth = 8;\n lineSize = width * 3;\n break;\n\n case _util.ImageKind.RGBA_32BPP:\n colorType = 6;\n bitDepth = 8;\n lineSize = width * 4;\n break;\n\n default:\n throw new Error("invalid format");\n }\n\n const literals = new Uint8Array((1 + lineSize) * height);\n let offsetLiterals = 0,\n offsetBytes = 0;\n\n for (let y = 0; y < height; ++y) {\n literals[offsetLiterals++] = 0;\n literals.set(bytes.subarray(offsetBytes, offsetBytes + lineSize), offsetLiterals);\n offsetBytes += lineSize;\n offsetLiterals += lineSize;\n }\n\n if (kind === _util.ImageKind.GRAYSCALE_1BPP && isMask) {\n offsetLiterals = 0;\n\n for (let y = 0; y < height; y++) {\n offsetLiterals++;\n\n for (let i = 0; i < lineSize; i++) {\n literals[offsetLiterals++] ^= 0xff;\n }\n }\n }\n\n const ihdr = new Uint8Array([width >> 24 & 0xff, width >> 16 & 0xff, width >> 8 & 0xff, width & 0xff, height >> 24 & 0xff, height >> 16 & 0xff, height >> 8 & 0xff, height & 0xff, bitDepth, colorType, 0x00, 0x00, 0x00]);\n const idat = deflateSync(literals);\n const pngLength = PNG_HEADER.length + CHUNK_WRAPPER_SIZE * 3 + ihdr.length + idat.length;\n const data = new Uint8Array(pngLength);\n let offset = 0;\n data.set(PNG_HEADER, offset);\n offset += PNG_HEADER.length;\n writePngChunk("IHDR", ihdr, data, offset);\n offset += CHUNK_WRAPPER_SIZE + ihdr.length;\n writePngChunk("IDATA", idat, data, offset);\n offset += CHUNK_WRAPPER_SIZE + idat.length;\n writePngChunk("IEND", new Uint8Array(0), data, offset);\n return createObjectURL(data, "image/png", forceDataSchema);\n }\n\n return function convertImgDataToPng(imgData, forceDataSchema, isMask) {\n const kind = imgData.kind === undefined ? _util.ImageKind.GRAYSCALE_1BPP : imgData.kind;\n return encode(imgData, kind, forceDataSchema, isMask);\n };\n }();\n\n class SVGExtraState {\n constructor() {\n this.fontSizeScale = 1;\n this.fontWeight = SVG_DEFAULTS.fontWeight;\n this.fontSize = 0;\n this.textMatrix = _util.IDENTITY_MATRIX;\n this.fontMatrix = _util.FONT_IDENTITY_MATRIX;\n this.leading = 0;\n this.textRenderingMode = _util.TextRenderingMode.FILL;\n this.textMatrixScale = 1;\n this.x = 0;\n this.y = 0;\n this.lineX = 0;\n this.lineY = 0;\n this.charSpacing = 0;\n this.wordSpacing = 0;\n this.textHScale = 1;\n this.textRise = 0;\n this.fillColor = SVG_DEFAULTS.fillColor;\n this.strokeColor = "#000000";\n this.fillAlpha = 1;\n this.strokeAlpha = 1;\n this.lineWidth = 1;\n this.lineJoin = "";\n this.lineCap = "";\n this.miterLimit = 0;\n this.dashArray = [];\n this.dashPhase = 0;\n this.dependencies = [];\n this.activeClipUrl = null;\n this.clipGroup = null;\n this.maskId = "";\n }\n\n clone() {\n return Object.create(this);\n }\n\n setCurrentPoint(x, y) {\n this.x = x;\n this.y = y;\n }\n\n }\n\n function opListToTree(opList) {\n let opTree = [];\n const tmp = [];\n\n for (const opListElement of opList) {\n if (opListElement.fn === "save") {\n opTree.push({\n fnId: 92,\n fn: "group",\n items: []\n });\n tmp.push(opTree);\n opTree = opTree[opTree.length - 1].items;\n continue;\n }\n\n if (opListElement.fn === "restore") {\n opTree = tmp.pop();\n } else {\n opTree.push(opListElement);\n }\n }\n\n return opTree;\n }\n\n function pf(value) {\n if (Number.isInteger(value)) {\n return value.toString();\n }\n\n const s = value.toFixed(10);\n let i = s.length - 1;\n\n if (s[i] !== "0") {\n return s;\n }\n\n do {\n i--;\n } while (s[i] === "0");\n\n return s.substring(0, s[i] === "." ? i : i + 1);\n }\n\n function pm(m) {\n if (m[4] === 0 && m[5] === 0) {\n if (m[1] === 0 && m[2] === 0) {\n if (m[0] === 1 && m[3] === 1) {\n return "";\n }\n\n return `scale(${pf(m[0])} ${pf(m[3])})`;\n }\n\n if (m[0] === m[3] && m[1] === -m[2]) {\n const a = Math.acos(m[0]) * 180 / Math.PI;\n return `rotate(${pf(a)})`;\n }\n } else {\n if (m[0] === 1 && m[1] === 0 && m[2] === 0 && m[3] === 1) {\n return `translate(${pf(m[4])} ${pf(m[5])})`;\n }\n }\n\n return `matrix(${pf(m[0])} ${pf(m[1])} ${pf(m[2])} ${pf(m[3])} ${pf(m[4])} ` + `${pf(m[5])})`;\n }\n\n let clipCount = 0;\n let maskCount = 0;\n let shadingCount = 0;\n exports.SVGGraphics = SVGGraphics = class {\n constructor(commonObjs, objs, forceDataSchema = false) {\n this.svgFactory = new _display_utils.DOMSVGFactory();\n this.current = new SVGExtraState();\n this.transformMatrix = _util.IDENTITY_MATRIX;\n this.transformStack = [];\n this.extraStack = [];\n this.commonObjs = commonObjs;\n this.objs = objs;\n this.pendingClip = null;\n this.pendingEOFill = false;\n this.embedFonts = false;\n this.embeddedFonts = Object.create(null);\n this.cssStyle = null;\n this.forceDataSchema = !!forceDataSchema;\n this._operatorIdMapping = [];\n\n for (const op in _util.OPS) {\n this._operatorIdMapping[_util.OPS[op]] = op;\n }\n }\n\n save() {\n this.transformStack.push(this.transformMatrix);\n const old = this.current;\n this.extraStack.push(old);\n this.current = old.clone();\n }\n\n restore() {\n this.transformMatrix = this.transformStack.pop();\n this.current = this.extraStack.pop();\n this.pendingClip = null;\n this.tgrp = null;\n }\n\n group(items) {\n this.save();\n this.executeOpTree(items);\n this.restore();\n }\n\n loadDependencies(operatorList) {\n const fnArray = operatorList.fnArray;\n const argsArray = operatorList.argsArray;\n\n for (let i = 0, ii = fnArray.length; i < ii; i++) {\n if (fnArray[i] !== _util.OPS.dependency) {\n continue;\n }\n\n for (const obj of argsArray[i]) {\n const objsPool = obj.startsWith("g_") ? this.commonObjs : this.objs;\n const promise = new Promise(resolve => {\n objsPool.get(obj, resolve);\n });\n this.current.dependencies.push(promise);\n }\n }\n\n return Promise.all(this.current.dependencies);\n }\n\n transform(a, b, c, d, e, f) {\n const transformMatrix = [a, b, c, d, e, f];\n this.transformMatrix = _util.Util.transform(this.transformMatrix, transformMatrix);\n this.tgrp = null;\n }\n\n getSVG(operatorList, viewport) {\n this.viewport = viewport;\n\n const svgElement = this._initialize(viewport);\n\n return this.loadDependencies(operatorList).then(() => {\n this.transformMatrix = _util.IDENTITY_MATRIX;\n this.executeOpTree(this.convertOpList(operatorList));\n return svgElement;\n });\n }\n\n convertOpList(operatorList) {\n const operatorIdMapping = this._operatorIdMapping;\n const argsArray = operatorList.argsArray;\n const fnArray = operatorList.fnArray;\n const opList = [];\n\n for (let i = 0, ii = fnArray.length; i < ii; i++) {\n const fnId = fnArray[i];\n opList.push({\n fnId,\n fn: operatorIdMapping[fnId],\n args: argsArray[i]\n });\n }\n\n return opListToTree(opList);\n }\n\n executeOpTree(opTree) {\n for (const opTreeElement of opTree) {\n const fn = opTreeElement.fn;\n const fnId = opTreeElement.fnId;\n const args = opTreeElement.args;\n\n switch (fnId | 0) {\n case _util.OPS.beginText:\n this.beginText();\n break;\n\n case _util.OPS.dependency:\n break;\n\n case _util.OPS.setLeading:\n this.setLeading(args);\n break;\n\n case _util.OPS.setLeadingMoveText:\n this.setLeadingMoveText(args[0], args[1]);\n break;\n\n case _util.OPS.setFont:\n this.setFont(args);\n break;\n\n case _util.OPS.showText:\n this.showText(args[0]);\n break;\n\n case _util.OPS.showSpacedText:\n this.showText(args[0]);\n break;\n\n case _util.OPS.endText:\n this.endText();\n break;\n\n case _util.OPS.moveText:\n this.moveText(args[0], args[1]);\n break;\n\n case _util.OPS.setCharSpacing:\n this.setCharSpacing(args[0]);\n break;\n\n case _util.OPS.setWordSpacing:\n this.setWordSpacing(args[0]);\n break;\n\n case _util.OPS.setHScale:\n this.setHScale(args[0]);\n break;\n\n case _util.OPS.setTextMatrix:\n this.setTextMatrix(args[0], args[1], args[2], args[3], args[4], args[5]);\n break;\n\n case _util.OPS.setTextRise:\n this.setTextRise(args[0]);\n break;\n\n case _util.OPS.setTextRenderingMode:\n this.setTextRenderingMode(args[0]);\n break;\n\n case _util.OPS.setLineWidth:\n this.setLineWidth(args[0]);\n break;\n\n case _util.OPS.setLineJoin:\n this.setLineJoin(args[0]);\n break;\n\n case _util.OPS.setLineCap:\n this.setLineCap(args[0]);\n break;\n\n case _util.OPS.setMiterLimit:\n this.setMiterLimit(args[0]);\n break;\n\n case _util.OPS.setFillRGBColor:\n this.setFillRGBColor(args[0], args[1], args[2]);\n break;\n\n case _util.OPS.setStrokeRGBColor:\n this.setStrokeRGBColor(args[0], args[1], args[2]);\n break;\n\n case _util.OPS.setStrokeColorN:\n this.setStrokeColorN(args);\n break;\n\n case _util.OPS.setFillColorN:\n this.setFillColorN(args);\n break;\n\n case _util.OPS.shadingFill:\n this.shadingFill(args[0]);\n break;\n\n case _util.OPS.setDash:\n this.setDash(args[0], args[1]);\n break;\n\n case _util.OPS.setRenderingIntent:\n this.setRenderingIntent(args[0]);\n break;\n\n case _util.OPS.setFlatness:\n this.setFlatness(args[0]);\n break;\n\n case _util.OPS.setGState:\n this.setGState(args[0]);\n break;\n\n case _util.OPS.fill:\n this.fill();\n break;\n\n case _util.OPS.eoFill:\n this.eoFill();\n break;\n\n case _util.OPS.stroke:\n this.stroke();\n break;\n\n case _util.OPS.fillStroke:\n this.fillStroke();\n break;\n\n case _util.OPS.eoFillStroke:\n this.eoFillStroke();\n break;\n\n case _util.OPS.clip:\n this.clip("nonzero");\n break;\n\n case _util.OPS.eoClip:\n this.clip("evenodd");\n break;\n\n case _util.OPS.paintSolidColorImageMask:\n this.paintSolidColorImageMask();\n break;\n\n case _util.OPS.paintImageXObject:\n this.paintImageXObject(args[0]);\n break;\n\n case _util.OPS.paintInlineImageXObject:\n this.paintInlineImageXObject(args[0]);\n break;\n\n case _util.OPS.paintImageMaskXObject:\n this.paintImageMaskXObject(args[0]);\n break;\n\n case _util.OPS.paintFormXObjectBegin:\n this.paintFormXObjectBegin(args[0], args[1]);\n break;\n\n case _util.OPS.paintFormXObjectEnd:\n this.paintFormXObjectEnd();\n break;\n\n case _util.OPS.closePath:\n this.closePath();\n break;\n\n case _util.OPS.closeStroke:\n this.closeStroke();\n break;\n\n case _util.OPS.closeFillStroke:\n this.closeFillStroke();\n break;\n\n case _util.OPS.closeEOFillStroke:\n this.closeEOFillStroke();\n break;\n\n case _util.OPS.nextLine:\n this.nextLine();\n break;\n\n case _util.OPS.transform:\n this.transform(args[0], args[1], args[2], args[3], args[4], args[5]);\n break;\n\n case _util.OPS.constructPath:\n this.constructPath(args[0], args[1]);\n break;\n\n case _util.OPS.endPath:\n this.endPath();\n break;\n\n case 92:\n this.group(opTreeElement.items);\n break;\n\n default:\n (0, _util.warn)(`Unimplemented operator ${fn}`);\n break;\n }\n }\n }\n\n setWordSpacing(wordSpacing) {\n this.current.wordSpacing = wordSpacing;\n }\n\n setCharSpacing(charSpacing) {\n this.current.charSpacing = charSpacing;\n }\n\n nextLine() {\n this.moveText(0, this.current.leading);\n }\n\n setTextMatrix(a, b, c, d, e, f) {\n const current = this.current;\n current.textMatrix = current.lineMatrix = [a, b, c, d, e, f];\n current.textMatrixScale = Math.hypot(a, b);\n current.x = current.lineX = 0;\n current.y = current.lineY = 0;\n current.xcoords = [];\n current.ycoords = [];\n current.tspan = this.svgFactory.createElement("svg:tspan");\n current.tspan.setAttributeNS(null, "font-family", current.fontFamily);\n current.tspan.setAttributeNS(null, "font-size", `${pf(current.fontSize)}px`);\n current.tspan.setAttributeNS(null, "y", pf(-current.y));\n current.txtElement = this.svgFactory.createElement("svg:text");\n current.txtElement.appendChild(current.tspan);\n }\n\n beginText() {\n const current = this.current;\n current.x = current.lineX = 0;\n current.y = current.lineY = 0;\n current.textMatrix = _util.IDENTITY_MATRIX;\n current.lineMatrix = _util.IDENTITY_MATRIX;\n current.textMatrixScale = 1;\n current.tspan = this.svgFactory.createElement("svg:tspan");\n current.txtElement = this.svgFactory.createElement("svg:text");\n current.txtgrp = this.svgFactory.createElement("svg:g");\n current.xcoords = [];\n current.ycoords = [];\n }\n\n moveText(x, y) {\n const current = this.current;\n current.x = current.lineX += x;\n current.y = current.lineY += y;\n current.xcoords = [];\n current.ycoords = [];\n current.tspan = this.svgFactory.createElement("svg:tspan");\n current.tspan.setAttributeNS(null, "font-family", current.fontFamily);\n current.tspan.setAttributeNS(null, "font-size", `${pf(current.fontSize)}px`);\n current.tspan.setAttributeNS(null, "y", pf(-current.y));\n }\n\n showText(glyphs) {\n const current = this.current;\n const font = current.font;\n const fontSize = current.fontSize;\n\n if (fontSize === 0) {\n return;\n }\n\n const fontSizeScale = current.fontSizeScale;\n const charSpacing = current.charSpacing;\n const wordSpacing = current.wordSpacing;\n const fontDirection = current.fontDirection;\n const textHScale = current.textHScale * fontDirection;\n const vertical = font.vertical;\n const spacingDir = vertical ? 1 : -1;\n const defaultVMetrics = font.defaultVMetrics;\n const widthAdvanceScale = fontSize * current.fontMatrix[0];\n let x = 0;\n\n for (const glyph of glyphs) {\n if (glyph === null) {\n x += fontDirection * wordSpacing;\n continue;\n } else if (typeof glyph === "number") {\n x += spacingDir * glyph * fontSize / 1000;\n continue;\n }\n\n const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing;\n const character = glyph.fontChar;\n let scaledX, scaledY;\n let width = glyph.width;\n\n if (vertical) {\n let vx;\n const vmetric = glyph.vmetric || defaultVMetrics;\n vx = glyph.vmetric ? vmetric[1] : width * 0.5;\n vx = -vx * widthAdvanceScale;\n const vy = vmetric[2] * widthAdvanceScale;\n width = vmetric ? -vmetric[0] : width;\n scaledX = vx / fontSizeScale;\n scaledY = (x + vy) / fontSizeScale;\n } else {\n scaledX = x / fontSizeScale;\n scaledY = 0;\n }\n\n if (glyph.isInFont || font.missingFile) {\n current.xcoords.push(current.x + scaledX);\n\n if (vertical) {\n current.ycoords.push(-current.y + scaledY);\n }\n\n current.tspan.textContent += character;\n } else {}\n\n let charWidth;\n\n if (vertical) {\n charWidth = width * widthAdvanceScale - spacing * fontDirection;\n } else {\n charWidth = width * widthAdvanceScale + spacing * fontDirection;\n }\n\n x += charWidth;\n }\n\n current.tspan.setAttributeNS(null, "x", current.xcoords.map(pf).join(" "));\n\n if (vertical) {\n current.tspan.setAttributeNS(null, "y", current.ycoords.map(pf).join(" "));\n } else {\n current.tspan.setAttributeNS(null, "y", pf(-current.y));\n }\n\n if (vertical) {\n current.y -= x;\n } else {\n current.x += x * textHScale;\n }\n\n current.tspan.setAttributeNS(null, "font-family", current.fontFamily);\n current.tspan.setAttributeNS(null, "font-size", `${pf(current.fontSize)}px`);\n\n if (current.fontStyle !== SVG_DEFAULTS.fontStyle) {\n current.tspan.setAttributeNS(null, "font-style", current.fontStyle);\n }\n\n if (current.fontWeight !== SVG_DEFAULTS.fontWeight) {\n current.tspan.setAttributeNS(null, "font-weight", current.fontWeight);\n }\n\n const fillStrokeMode = current.textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK;\n\n if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) {\n if (current.fillColor !== SVG_DEFAULTS.fillColor) {\n current.tspan.setAttributeNS(null, "fill", current.fillColor);\n }\n\n if (current.fillAlpha < 1) {\n current.tspan.setAttributeNS(null, "fill-opacity", current.fillAlpha);\n }\n } else if (current.textRenderingMode === _util.TextRenderingMode.ADD_TO_PATH) {\n current.tspan.setAttributeNS(null, "fill", "transparent");\n } else {\n current.tspan.setAttributeNS(null, "fill", "none");\n }\n\n if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) {\n const lineWidthScale = 1 / (current.textMatrixScale || 1);\n\n this._setStrokeAttributes(current.tspan, lineWidthScale);\n }\n\n let textMatrix = current.textMatrix;\n\n if (current.textRise !== 0) {\n textMatrix = textMatrix.slice();\n textMatrix[5] += current.textRise;\n }\n\n current.txtElement.setAttributeNS(null, "transform", `${pm(textMatrix)} scale(${pf(textHScale)}, -1)`);\n current.txtElement.setAttributeNS(XML_NS, "xml:space", "preserve");\n current.txtElement.appendChild(current.tspan);\n current.txtgrp.appendChild(current.txtElement);\n\n this._ensureTransformGroup().appendChild(current.txtElement);\n }\n\n setLeadingMoveText(x, y) {\n this.setLeading(-y);\n this.moveText(x, y);\n }\n\n addFontStyle(fontObj) {\n if (!fontObj.data) {\n throw new Error("addFontStyle: No font data available, " + \'ensure that the "fontExtraProperties" API parameter is set.\');\n }\n\n if (!this.cssStyle) {\n this.cssStyle = this.svgFactory.createElement("svg:style");\n this.cssStyle.setAttributeNS(null, "type", "text/css");\n this.defs.appendChild(this.cssStyle);\n }\n\n const url = createObjectURL(fontObj.data, fontObj.mimetype, this.forceDataSchema);\n this.cssStyle.textContent += `@font-face { font-family: "${fontObj.loadedName}";` + ` src: url(${url}); }\\n`;\n }\n\n setFont(details) {\n const current = this.current;\n const fontObj = this.commonObjs.get(details[0]);\n let size = details[1];\n current.font = fontObj;\n\n if (this.embedFonts && !fontObj.missingFile && !this.embeddedFonts[fontObj.loadedName]) {\n this.addFontStyle(fontObj);\n this.embeddedFonts[fontObj.loadedName] = fontObj;\n }\n\n current.fontMatrix = fontObj.fontMatrix || _util.FONT_IDENTITY_MATRIX;\n let bold = "normal";\n\n if (fontObj.black) {\n bold = "900";\n } else if (fontObj.bold) {\n bold = "bold";\n }\n\n const italic = fontObj.italic ? "italic" : "normal";\n\n if (size < 0) {\n size = -size;\n current.fontDirection = -1;\n } else {\n current.fontDirection = 1;\n }\n\n current.fontSize = size;\n current.fontFamily = fontObj.loadedName;\n current.fontWeight = bold;\n current.fontStyle = italic;\n current.tspan = this.svgFactory.createElement("svg:tspan");\n current.tspan.setAttributeNS(null, "y", pf(-current.y));\n current.xcoords = [];\n current.ycoords = [];\n }\n\n endText() {\n const current = this.current;\n\n if (current.textRenderingMode & _util.TextRenderingMode.ADD_TO_PATH_FLAG && current.txtElement?.hasChildNodes()) {\n current.element = current.txtElement;\n this.clip("nonzero");\n this.endPath();\n }\n }\n\n setLineWidth(width) {\n if (width > 0) {\n this.current.lineWidth = width;\n }\n }\n\n setLineCap(style) {\n this.current.lineCap = LINE_CAP_STYLES[style];\n }\n\n setLineJoin(style) {\n this.current.lineJoin = LINE_JOIN_STYLES[style];\n }\n\n setMiterLimit(limit) {\n this.current.miterLimit = limit;\n }\n\n setStrokeAlpha(strokeAlpha) {\n this.current.strokeAlpha = strokeAlpha;\n }\n\n setStrokeRGBColor(r, g, b) {\n this.current.strokeColor = _util.Util.makeHexColor(r, g, b);\n }\n\n setFillAlpha(fillAlpha) {\n this.current.fillAlpha = fillAlpha;\n }\n\n setFillRGBColor(r, g, b) {\n this.current.fillColor = _util.Util.makeHexColor(r, g, b);\n this.current.tspan = this.svgFactory.createElement("svg:tspan");\n this.current.xcoords = [];\n this.current.ycoords = [];\n }\n\n setStrokeColorN(args) {\n this.current.strokeColor = this._makeColorN_Pattern(args);\n }\n\n setFillColorN(args) {\n this.current.fillColor = this._makeColorN_Pattern(args);\n }\n\n shadingFill(args) {\n const width = this.viewport.width;\n const height = this.viewport.height;\n\n const inv = _util.Util.inverseTransform(this.transformMatrix);\n\n const bl = _util.Util.applyTransform([0, 0], inv);\n\n const br = _util.Util.applyTransform([0, height], inv);\n\n const ul = _util.Util.applyTransform([width, 0], inv);\n\n const ur = _util.Util.applyTransform([width, height], inv);\n\n const x0 = Math.min(bl[0], br[0], ul[0], ur[0]);\n const y0 = Math.min(bl[1], br[1], ul[1], ur[1]);\n const x1 = Math.max(bl[0], br[0], ul[0], ur[0]);\n const y1 = Math.max(bl[1], br[1], ul[1], ur[1]);\n const rect = this.svgFactory.createElement("svg:rect");\n rect.setAttributeNS(null, "x", x0);\n rect.setAttributeNS(null, "y", y0);\n rect.setAttributeNS(null, "width", x1 - x0);\n rect.setAttributeNS(null, "height", y1 - y0);\n rect.setAttributeNS(null, "fill", this._makeShadingPattern(args));\n\n if (this.current.fillAlpha < 1) {\n rect.setAttributeNS(null, "fill-opacity", this.current.fillAlpha);\n }\n\n this._ensureTransformGroup().appendChild(rect);\n }\n\n _makeColorN_Pattern(args) {\n if (args[0] === "TilingPattern") {\n return this._makeTilingPattern(args);\n }\n\n return this._makeShadingPattern(args);\n }\n\n _makeTilingPattern(args) {\n const color = args[1];\n const operatorList = args[2];\n const matrix = args[3] || _util.IDENTITY_MATRIX;\n const [x0, y0, x1, y1] = args[4];\n const xstep = args[5];\n const ystep = args[6];\n const paintType = args[7];\n const tilingId = `shading${shadingCount++}`;\n\n const [tx0, ty0, tx1, ty1] = _util.Util.normalizeRect([..._util.Util.applyTransform([x0, y0], matrix), ..._util.Util.applyTransform([x1, y1], matrix)]);\n\n const [xscale, yscale] = _util.Util.singularValueDecompose2dScale(matrix);\n\n const txstep = xstep * xscale;\n const tystep = ystep * yscale;\n const tiling = this.svgFactory.createElement("svg:pattern");\n tiling.setAttributeNS(null, "id", tilingId);\n tiling.setAttributeNS(null, "patternUnits", "userSpaceOnUse");\n tiling.setAttributeNS(null, "width", txstep);\n tiling.setAttributeNS(null, "height", tystep);\n tiling.setAttributeNS(null, "x", `${tx0}`);\n tiling.setAttributeNS(null, "y", `${ty0}`);\n const svg = this.svg;\n const transformMatrix = this.transformMatrix;\n const fillColor = this.current.fillColor;\n const strokeColor = this.current.strokeColor;\n const bbox = this.svgFactory.create(tx1 - tx0, ty1 - ty0);\n this.svg = bbox;\n this.transformMatrix = matrix;\n\n if (paintType === 2) {\n const cssColor = _util.Util.makeHexColor(...color);\n\n this.current.fillColor = cssColor;\n this.current.strokeColor = cssColor;\n }\n\n this.executeOpTree(this.convertOpList(operatorList));\n this.svg = svg;\n this.transformMatrix = transformMatrix;\n this.current.fillColor = fillColor;\n this.current.strokeColor = strokeColor;\n tiling.appendChild(bbox.childNodes[0]);\n this.defs.appendChild(tiling);\n return `url(#${tilingId})`;\n }\n\n _makeShadingPattern(args) {\n if (typeof args === "string") {\n args = this.objs.get(args);\n }\n\n switch (args[0]) {\n case "RadialAxial":\n const shadingId = `shading${shadingCount++}`;\n const colorStops = args[3];\n let gradient;\n\n switch (args[1]) {\n case "axial":\n const point0 = args[4];\n const point1 = args[5];\n gradient = this.svgFactory.createElement("svg:linearGradient");\n gradient.setAttributeNS(null, "id", shadingId);\n gradient.setAttributeNS(null, "gradientUnits", "userSpaceOnUse");\n gradient.setAttributeNS(null, "x1", point0[0]);\n gradient.setAttributeNS(null, "y1", point0[1]);\n gradient.setAttributeNS(null, "x2", point1[0]);\n gradient.setAttributeNS(null, "y2", point1[1]);\n break;\n\n case "radial":\n const focalPoint = args[4];\n const circlePoint = args[5];\n const focalRadius = args[6];\n const circleRadius = args[7];\n gradient = this.svgFactory.createElement("svg:radialGradient");\n gradient.setAttributeNS(null, "id", shadingId);\n gradient.setAttributeNS(null, "gradientUnits", "userSpaceOnUse");\n gradient.setAttributeNS(null, "cx", circlePoint[0]);\n gradient.setAttributeNS(null, "cy", circlePoint[1]);\n gradient.setAttributeNS(null, "r", circleRadius);\n gradient.setAttributeNS(null, "fx", focalPoint[0]);\n gradient.setAttributeNS(null, "fy", focalPoint[1]);\n gradient.setAttributeNS(null, "fr", focalRadius);\n break;\n\n default:\n throw new Error(`Unknown RadialAxial type: ${args[1]}`);\n }\n\n for (const colorStop of colorStops) {\n const stop = this.svgFactory.createElement("svg:stop");\n stop.setAttributeNS(null, "offset", colorStop[0]);\n stop.setAttributeNS(null, "stop-color", colorStop[1]);\n gradient.appendChild(stop);\n }\n\n this.defs.appendChild(gradient);\n return `url(#${shadingId})`;\n\n case "Mesh":\n (0, _util.warn)("Unimplemented pattern Mesh");\n return null;\n\n case "Dummy":\n return "hotpink";\n\n default:\n throw new Error(`Unknown IR type: ${args[0]}`);\n }\n }\n\n setDash(dashArray, dashPhase) {\n this.current.dashArray = dashArray;\n this.current.dashPhase = dashPhase;\n }\n\n constructPath(ops, args) {\n const current = this.current;\n let x = current.x,\n y = current.y;\n let d = [];\n let j = 0;\n\n for (const op of ops) {\n switch (op | 0) {\n case _util.OPS.rectangle:\n x = args[j++];\n y = args[j++];\n const width = args[j++];\n const height = args[j++];\n const xw = x + width;\n const yh = y + height;\n d.push("M", pf(x), pf(y), "L", pf(xw), pf(y), "L", pf(xw), pf(yh), "L", pf(x), pf(yh), "Z");\n break;\n\n case _util.OPS.moveTo:\n x = args[j++];\n y = args[j++];\n d.push("M", pf(x), pf(y));\n break;\n\n case _util.OPS.lineTo:\n x = args[j++];\n y = args[j++];\n d.push("L", pf(x), pf(y));\n break;\n\n case _util.OPS.curveTo:\n x = args[j + 4];\n y = args[j + 5];\n d.push("C", pf(args[j]), pf(args[j + 1]), pf(args[j + 2]), pf(args[j + 3]), pf(x), pf(y));\n j += 6;\n break;\n\n case _util.OPS.curveTo2:\n d.push("C", pf(x), pf(y), pf(args[j]), pf(args[j + 1]), pf(args[j + 2]), pf(args[j + 3]));\n x = args[j + 2];\n y = args[j + 3];\n j += 4;\n break;\n\n case _util.OPS.curveTo3:\n x = args[j + 2];\n y = args[j + 3];\n d.push("C", pf(args[j]), pf(args[j + 1]), pf(x), pf(y), pf(x), pf(y));\n j += 4;\n break;\n\n case _util.OPS.closePath:\n d.push("Z");\n break;\n }\n }\n\n d = d.join(" ");\n\n if (current.path && ops.length > 0 && ops[0] !== _util.OPS.rectangle && ops[0] !== _util.OPS.moveTo) {\n d = current.path.getAttributeNS(null, "d") + d;\n } else {\n current.path = this.svgFactory.createElement("svg:path");\n\n this._ensureTransformGroup().appendChild(current.path);\n }\n\n current.path.setAttributeNS(null, "d", d);\n current.path.setAttributeNS(null, "fill", "none");\n current.element = current.path;\n current.setCurrentPoint(x, y);\n }\n\n endPath() {\n const current = this.current;\n current.path = null;\n\n if (!this.pendingClip) {\n return;\n }\n\n if (!current.element) {\n this.pendingClip = null;\n return;\n }\n\n const clipId = `clippath${clipCount++}`;\n const clipPath = this.svgFactory.createElement("svg:clipPath");\n clipPath.setAttributeNS(null, "id", clipId);\n clipPath.setAttributeNS(null, "transform", pm(this.transformMatrix));\n const clipElement = current.element.cloneNode(true);\n\n if (this.pendingClip === "evenodd") {\n clipElement.setAttributeNS(null, "clip-rule", "evenodd");\n } else {\n clipElement.setAttributeNS(null, "clip-rule", "nonzero");\n }\n\n this.pendingClip = null;\n clipPath.appendChild(clipElement);\n this.defs.appendChild(clipPath);\n\n if (current.activeClipUrl) {\n current.clipGroup = null;\n\n for (const prev of this.extraStack) {\n prev.clipGroup = null;\n }\n\n clipPath.setAttributeNS(null, "clip-path", current.activeClipUrl);\n }\n\n current.activeClipUrl = `url(#${clipId})`;\n this.tgrp = null;\n }\n\n clip(type) {\n this.pendingClip = type;\n }\n\n closePath() {\n const current = this.current;\n\n if (current.path) {\n const d = `${current.path.getAttributeNS(null, "d")}Z`;\n current.path.setAttributeNS(null, "d", d);\n }\n }\n\n setLeading(leading) {\n this.current.leading = -leading;\n }\n\n setTextRise(textRise) {\n this.current.textRise = textRise;\n }\n\n setTextRenderingMode(textRenderingMode) {\n this.current.textRenderingMode = textRenderingMode;\n }\n\n setHScale(scale) {\n this.current.textHScale = scale / 100;\n }\n\n setRenderingIntent(intent) {}\n\n setFlatness(flatness) {}\n\n setGState(states) {\n for (const [key, value] of states) {\n switch (key) {\n case "LW":\n this.setLineWidth(value);\n break;\n\n case "LC":\n this.setLineCap(value);\n break;\n\n case "LJ":\n this.setLineJoin(value);\n break;\n\n case "ML":\n this.setMiterLimit(value);\n break;\n\n case "D":\n this.setDash(value[0], value[1]);\n break;\n\n case "RI":\n this.setRenderingIntent(value);\n break;\n\n case "FL":\n this.setFlatness(value);\n break;\n\n case "Font":\n this.setFont(value);\n break;\n\n case "CA":\n this.setStrokeAlpha(value);\n break;\n\n case "ca":\n this.setFillAlpha(value);\n break;\n\n default:\n (0, _util.warn)(`Unimplemented graphic state operator ${key}`);\n break;\n }\n }\n }\n\n fill() {\n const current = this.current;\n\n if (current.element) {\n current.element.setAttributeNS(null, "fill", current.fillColor);\n current.element.setAttributeNS(null, "fill-opacity", current.fillAlpha);\n this.endPath();\n }\n }\n\n stroke() {\n const current = this.current;\n\n if (current.element) {\n this._setStrokeAttributes(current.element);\n\n current.element.setAttributeNS(null, "fill", "none");\n this.endPath();\n }\n }\n\n _setStrokeAttributes(element, lineWidthScale = 1) {\n const current = this.current;\n let dashArray = current.dashArray;\n\n if (lineWidthScale !== 1 && dashArray.length > 0) {\n dashArray = dashArray.map(function (value) {\n return lineWidthScale * value;\n });\n }\n\n element.setAttributeNS(null, "stroke", current.strokeColor);\n element.setAttributeNS(null, "stroke-opacity", current.strokeAlpha);\n element.setAttributeNS(null, "stroke-miterlimit", pf(current.miterLimit));\n element.setAttributeNS(null, "stroke-linecap", current.lineCap);\n element.setAttributeNS(null, "stroke-linejoin", current.lineJoin);\n element.setAttributeNS(null, "stroke-width", pf(lineWidthScale * current.lineWidth) + "px");\n element.setAttributeNS(null, "stroke-dasharray", dashArray.map(pf).join(" "));\n element.setAttributeNS(null, "stroke-dashoffset", pf(lineWidthScale * current.dashPhase) + "px");\n }\n\n eoFill() {\n if (this.current.element) {\n this.current.element.setAttributeNS(null, "fill-rule", "evenodd");\n }\n\n this.fill();\n }\n\n fillStroke() {\n this.stroke();\n this.fill();\n }\n\n eoFillStroke() {\n if (this.current.element) {\n this.current.element.setAttributeNS(null, "fill-rule", "evenodd");\n }\n\n this.fillStroke();\n }\n\n closeStroke() {\n this.closePath();\n this.stroke();\n }\n\n closeFillStroke() {\n this.closePath();\n this.fillStroke();\n }\n\n closeEOFillStroke() {\n this.closePath();\n this.eoFillStroke();\n }\n\n paintSolidColorImageMask() {\n const rect = this.svgFactory.createElement("svg:rect");\n rect.setAttributeNS(null, "x", "0");\n rect.setAttributeNS(null, "y", "0");\n rect.setAttributeNS(null, "width", "1px");\n rect.setAttributeNS(null, "height", "1px");\n rect.setAttributeNS(null, "fill", this.current.fillColor);\n\n this._ensureTransformGroup().appendChild(rect);\n }\n\n paintImageXObject(objId) {\n const imgData = objId.startsWith("g_") ? this.commonObjs.get(objId) : this.objs.get(objId);\n\n if (!imgData) {\n (0, _util.warn)(`Dependent image with object ID ${objId} is not ready yet`);\n return;\n }\n\n this.paintInlineImageXObject(imgData);\n }\n\n paintInlineImageXObject(imgData, mask) {\n const width = imgData.width;\n const height = imgData.height;\n const imgSrc = convertImgDataToPng(imgData, this.forceDataSchema, !!mask);\n const cliprect = this.svgFactory.createElement("svg:rect");\n cliprect.setAttributeNS(null, "x", "0");\n cliprect.setAttributeNS(null, "y", "0");\n cliprect.setAttributeNS(null, "width", pf(width));\n cliprect.setAttributeNS(null, "height", pf(height));\n this.current.element = cliprect;\n this.clip("nonzero");\n const imgEl = this.svgFactory.createElement("svg:image");\n imgEl.setAttributeNS(XLINK_NS, "xlink:href", imgSrc);\n imgEl.setAttributeNS(null, "x", "0");\n imgEl.setAttributeNS(null, "y", pf(-height));\n imgEl.setAttributeNS(null, "width", pf(width) + "px");\n imgEl.setAttributeNS(null, "height", pf(height) + "px");\n imgEl.setAttributeNS(null, "transform", `scale(${pf(1 / width)} ${pf(-1 / height)})`);\n\n if (mask) {\n mask.appendChild(imgEl);\n } else {\n this._ensureTransformGroup().appendChild(imgEl);\n }\n }\n\n paintImageMaskXObject(imgData) {\n const current = this.current;\n const width = imgData.width;\n const height = imgData.height;\n const fillColor = current.fillColor;\n current.maskId = `mask${maskCount++}`;\n const mask = this.svgFactory.createElement("svg:mask");\n mask.setAttributeNS(null, "id", current.maskId);\n const rect = this.svgFactory.createElement("svg:rect");\n rect.setAttributeNS(null, "x", "0");\n rect.setAttributeNS(null, "y", "0");\n rect.setAttributeNS(null, "width", pf(width));\n rect.setAttributeNS(null, "height", pf(height));\n rect.setAttributeNS(null, "fill", fillColor);\n rect.setAttributeNS(null, "mask", `url(#${current.maskId})`);\n this.defs.appendChild(mask);\n\n this._ensureTransformGroup().appendChild(rect);\n\n this.paintInlineImageXObject(imgData, mask);\n }\n\n paintFormXObjectBegin(matrix, bbox) {\n if (Array.isArray(matrix) && matrix.length === 6) {\n this.transform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);\n }\n\n if (bbox) {\n const width = bbox[2] - bbox[0];\n const height = bbox[3] - bbox[1];\n const cliprect = this.svgFactory.createElement("svg:rect");\n cliprect.setAttributeNS(null, "x", bbox[0]);\n cliprect.setAttributeNS(null, "y", bbox[1]);\n cliprect.setAttributeNS(null, "width", pf(width));\n cliprect.setAttributeNS(null, "height", pf(height));\n this.current.element = cliprect;\n this.clip("nonzero");\n this.endPath();\n }\n }\n\n paintFormXObjectEnd() {}\n\n _initialize(viewport) {\n const svg = this.svgFactory.create(viewport.width, viewport.height);\n const definitions = this.svgFactory.createElement("svg:defs");\n svg.appendChild(definitions);\n this.defs = definitions;\n const rootGroup = this.svgFactory.createElement("svg:g");\n rootGroup.setAttributeNS(null, "transform", pm(viewport.transform));\n svg.appendChild(rootGroup);\n this.svg = rootGroup;\n return svg;\n }\n\n _ensureClipGroup() {\n if (!this.current.clipGroup) {\n const clipGroup = this.svgFactory.createElement("svg:g");\n clipGroup.setAttributeNS(null, "clip-path", this.current.activeClipUrl);\n this.svg.appendChild(clipGroup);\n this.current.clipGroup = clipGroup;\n }\n\n return this.current.clipGroup;\n }\n\n _ensureTransformGroup() {\n if (!this.tgrp) {\n this.tgrp = this.svgFactory.createElement("svg:g");\n this.tgrp.setAttributeNS(null, "transform", pm(this.transformMatrix));\n\n if (this.current.activeClipUrl) {\n this._ensureClipGroup().appendChild(this.tgrp);\n } else {\n this.svg.appendChild(this.tgrp);\n }\n }\n\n return this.tgrp;\n }\n\n };\n}\n\n/***/ }),\n/* 25 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.PDFNodeStream = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _network_utils = __w_pdfjs_require__(26);\n\n;\n\nconst fs = __webpack_require__(172);\n\nconst http = __webpack_require__(1);\n\nconst https = __webpack_require__(779);\n\nconst url = __webpack_require__(558);\n\nconst fileUriRegex = /^file:\\/\\/\\/[a-zA-Z]:\\//;\n\nfunction parseUrl(sourceUrl) {\n const parsedUrl = url.parse(sourceUrl);\n\n if (parsedUrl.protocol === "file:" || parsedUrl.host) {\n return parsedUrl;\n }\n\n if (/^[a-z]:[/\\\\]/i.test(sourceUrl)) {\n return url.parse(`file:///${sourceUrl}`);\n }\n\n if (!parsedUrl.host) {\n parsedUrl.protocol = "file:";\n }\n\n return parsedUrl;\n}\n\nclass PDFNodeStream {\n constructor(source) {\n this.source = source;\n this.url = parseUrl(source.url);\n this.isHttp = this.url.protocol === "http:" || this.url.protocol === "https:";\n this.isFsUrl = this.url.protocol === "file:";\n this.httpHeaders = this.isHttp && source.httpHeaders || {};\n this._fullRequestReader = null;\n this._rangeRequestReaders = [];\n }\n\n get _progressiveDataLength() {\n return this._fullRequestReader?._loaded ?? 0;\n }\n\n getFullReader() {\n (0, _util.assert)(!this._fullRequestReader, "PDFNodeStream.getFullReader can only be called once.");\n this._fullRequestReader = this.isFsUrl ? new PDFNodeStreamFsFullReader(this) : new PDFNodeStreamFullReader(this);\n return this._fullRequestReader;\n }\n\n getRangeReader(start, end) {\n if (end <= this._progressiveDataLength) {\n return null;\n }\n\n const rangeReader = this.isFsUrl ? new PDFNodeStreamFsRangeReader(this, start, end) : new PDFNodeStreamRangeReader(this, start, end);\n\n this._rangeRequestReaders.push(rangeReader);\n\n return rangeReader;\n }\n\n cancelAllRequests(reason) {\n if (this._fullRequestReader) {\n this._fullRequestReader.cancel(reason);\n }\n\n for (const reader of this._rangeRequestReaders.slice(0)) {\n reader.cancel(reason);\n }\n }\n\n}\n\nexports.PDFNodeStream = PDFNodeStream;\n\nclass BaseFullReader {\n constructor(stream) {\n this._url = stream.url;\n this._done = false;\n this._storedError = null;\n this.onProgress = null;\n const source = stream.source;\n this._contentLength = source.length;\n this._loaded = 0;\n this._filename = null;\n this._disableRange = source.disableRange || false;\n this._rangeChunkSize = source.rangeChunkSize;\n\n if (!this._rangeChunkSize && !this._disableRange) {\n this._disableRange = true;\n }\n\n this._isStreamingSupported = !source.disableStream;\n this._isRangeSupported = !source.disableRange;\n this._readableStream = null;\n this._readCapability = (0, _util.createPromiseCapability)();\n this._headersCapability = (0, _util.createPromiseCapability)();\n }\n\n get headersReady() {\n return this._headersCapability.promise;\n }\n\n get filename() {\n return this._filename;\n }\n\n get contentLength() {\n return this._contentLength;\n }\n\n get isRangeSupported() {\n return this._isRangeSupported;\n }\n\n get isStreamingSupported() {\n return this._isStreamingSupported;\n }\n\n async read() {\n await this._readCapability.promise;\n\n if (this._done) {\n return {\n value: undefined,\n done: true\n };\n }\n\n if (this._storedError) {\n throw this._storedError;\n }\n\n const chunk = this._readableStream.read();\n\n if (chunk === null) {\n this._readCapability = (0, _util.createPromiseCapability)();\n return this.read();\n }\n\n this._loaded += chunk.length;\n\n if (this.onProgress) {\n this.onProgress({\n loaded: this._loaded,\n total: this._contentLength\n });\n }\n\n const buffer = new Uint8Array(chunk).buffer;\n return {\n value: buffer,\n done: false\n };\n }\n\n cancel(reason) {\n if (!this._readableStream) {\n this._error(reason);\n\n return;\n }\n\n this._readableStream.destroy(reason);\n }\n\n _error(reason) {\n this._storedError = reason;\n\n this._readCapability.resolve();\n }\n\n _setReadableStream(readableStream) {\n this._readableStream = readableStream;\n readableStream.on("readable", () => {\n this._readCapability.resolve();\n });\n readableStream.on("end", () => {\n readableStream.destroy();\n this._done = true;\n\n this._readCapability.resolve();\n });\n readableStream.on("error", reason => {\n this._error(reason);\n });\n\n if (!this._isStreamingSupported && this._isRangeSupported) {\n this._error(new _util.AbortException("streaming is disabled"));\n }\n\n if (this._storedError) {\n this._readableStream.destroy(this._storedError);\n }\n }\n\n}\n\nclass BaseRangeReader {\n constructor(stream) {\n this._url = stream.url;\n this._done = false;\n this._storedError = null;\n this.onProgress = null;\n this._loaded = 0;\n this._readableStream = null;\n this._readCapability = (0, _util.createPromiseCapability)();\n const source = stream.source;\n this._isStreamingSupported = !source.disableStream;\n }\n\n get isStreamingSupported() {\n return this._isStreamingSupported;\n }\n\n async read() {\n await this._readCapability.promise;\n\n if (this._done) {\n return {\n value: undefined,\n done: true\n };\n }\n\n if (this._storedError) {\n throw this._storedError;\n }\n\n const chunk = this._readableStream.read();\n\n if (chunk === null) {\n this._readCapability = (0, _util.createPromiseCapability)();\n return this.read();\n }\n\n this._loaded += chunk.length;\n\n if (this.onProgress) {\n this.onProgress({\n loaded: this._loaded\n });\n }\n\n const buffer = new Uint8Array(chunk).buffer;\n return {\n value: buffer,\n done: false\n };\n }\n\n cancel(reason) {\n if (!this._readableStream) {\n this._error(reason);\n\n return;\n }\n\n this._readableStream.destroy(reason);\n }\n\n _error(reason) {\n this._storedError = reason;\n\n this._readCapability.resolve();\n }\n\n _setReadableStream(readableStream) {\n this._readableStream = readableStream;\n readableStream.on("readable", () => {\n this._readCapability.resolve();\n });\n readableStream.on("end", () => {\n readableStream.destroy();\n this._done = true;\n\n this._readCapability.resolve();\n });\n readableStream.on("error", reason => {\n this._error(reason);\n });\n\n if (this._storedError) {\n this._readableStream.destroy(this._storedError);\n }\n }\n\n}\n\nfunction createRequestOptions(parsedUrl, headers) {\n return {\n protocol: parsedUrl.protocol,\n auth: parsedUrl.auth,\n host: parsedUrl.hostname,\n port: parsedUrl.port,\n path: parsedUrl.path,\n method: "GET",\n headers\n };\n}\n\nclass PDFNodeStreamFullReader extends BaseFullReader {\n constructor(stream) {\n super(stream);\n\n const handleResponse = response => {\n if (response.statusCode === 404) {\n const error = new _util.MissingPDFException(`Missing PDF "${this._url}".`);\n this._storedError = error;\n\n this._headersCapability.reject(error);\n\n return;\n }\n\n this._headersCapability.resolve();\n\n this._setReadableStream(response);\n\n const getResponseHeader = name => {\n return this._readableStream.headers[name.toLowerCase()];\n };\n\n const {\n allowRangeRequests,\n suggestedLength\n } = (0, _network_utils.validateRangeRequestCapabilities)({\n getResponseHeader,\n isHttp: stream.isHttp,\n rangeChunkSize: this._rangeChunkSize,\n disableRange: this._disableRange\n });\n this._isRangeSupported = allowRangeRequests;\n this._contentLength = suggestedLength || this._contentLength;\n this._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader);\n };\n\n this._request = null;\n\n if (this._url.protocol === "http:") {\n this._request = http.request(createRequestOptions(this._url, stream.httpHeaders), handleResponse);\n } else {\n this._request = https.request(createRequestOptions(this._url, stream.httpHeaders), handleResponse);\n }\n\n this._request.on("error", reason => {\n this._storedError = reason;\n\n this._headersCapability.reject(reason);\n });\n\n this._request.end();\n }\n\n}\n\nclass PDFNodeStreamRangeReader extends BaseRangeReader {\n constructor(stream, start, end) {\n super(stream);\n this._httpHeaders = {};\n\n for (const property in stream.httpHeaders) {\n const value = stream.httpHeaders[property];\n\n if (typeof value === "undefined") {\n continue;\n }\n\n this._httpHeaders[property] = value;\n }\n\n this._httpHeaders.Range = `bytes=${start}-${end - 1}`;\n\n const handleResponse = response => {\n if (response.statusCode === 404) {\n const error = new _util.MissingPDFException(`Missing PDF "${this._url}".`);\n this._storedError = error;\n return;\n }\n\n this._setReadableStream(response);\n };\n\n this._request = null;\n\n if (this._url.protocol === "http:") {\n this._request = http.request(createRequestOptions(this._url, this._httpHeaders), handleResponse);\n } else {\n this._request = https.request(createRequestOptions(this._url, this._httpHeaders), handleResponse);\n }\n\n this._request.on("error", reason => {\n this._storedError = reason;\n });\n\n this._request.end();\n }\n\n}\n\nclass PDFNodeStreamFsFullReader extends BaseFullReader {\n constructor(stream) {\n super(stream);\n let path = decodeURIComponent(this._url.path);\n\n if (fileUriRegex.test(this._url.href)) {\n path = path.replace(/^\\//, "");\n }\n\n fs.lstat(path, (error, stat) => {\n if (error) {\n if (error.code === "ENOENT") {\n error = new _util.MissingPDFException(`Missing PDF "${path}".`);\n }\n\n this._storedError = error;\n\n this._headersCapability.reject(error);\n\n return;\n }\n\n this._contentLength = stat.size;\n\n this._setReadableStream(fs.createReadStream(path));\n\n this._headersCapability.resolve();\n });\n }\n\n}\n\nclass PDFNodeStreamFsRangeReader extends BaseRangeReader {\n constructor(stream, start, end) {\n super(stream);\n let path = decodeURIComponent(this._url.path);\n\n if (fileUriRegex.test(this._url.href)) {\n path = path.replace(/^\\//, "");\n }\n\n this._setReadableStream(fs.createReadStream(path, {\n start,\n end: end - 1\n }));\n }\n\n}\n\n/***/ }),\n/* 26 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.createResponseStatusError = createResponseStatusError;\nexports.extractFilenameFromHeader = extractFilenameFromHeader;\nexports.validateRangeRequestCapabilities = validateRangeRequestCapabilities;\nexports.validateResponseStatus = validateResponseStatus;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _content_disposition = __w_pdfjs_require__(27);\n\nvar _display_utils = __w_pdfjs_require__(5);\n\nfunction validateRangeRequestCapabilities({\n getResponseHeader,\n isHttp,\n rangeChunkSize,\n disableRange\n}) {\n const returnValues = {\n allowRangeRequests: false,\n suggestedLength: undefined\n };\n const length = parseInt(getResponseHeader("Content-Length"), 10);\n\n if (!Number.isInteger(length)) {\n return returnValues;\n }\n\n returnValues.suggestedLength = length;\n\n if (length <= 2 * rangeChunkSize) {\n return returnValues;\n }\n\n if (disableRange || !isHttp) {\n return returnValues;\n }\n\n if (getResponseHeader("Accept-Ranges") !== "bytes") {\n return returnValues;\n }\n\n const contentEncoding = getResponseHeader("Content-Encoding") || "identity";\n\n if (contentEncoding !== "identity") {\n return returnValues;\n }\n\n returnValues.allowRangeRequests = true;\n return returnValues;\n}\n\nfunction extractFilenameFromHeader(getResponseHeader) {\n const contentDisposition = getResponseHeader("Content-Disposition");\n\n if (contentDisposition) {\n let filename = (0, _content_disposition.getFilenameFromContentDispositionHeader)(contentDisposition);\n\n if (filename.includes("%")) {\n try {\n filename = decodeURIComponent(filename);\n } catch (ex) {}\n }\n\n if ((0, _display_utils.isPdfFile)(filename)) {\n return filename;\n }\n }\n\n return null;\n}\n\nfunction createResponseStatusError(status, url) {\n if (status === 404 || status === 0 && url.startsWith("file:")) {\n return new _util.MissingPDFException(\'Missing PDF "\' + url + \'".\');\n }\n\n return new _util.UnexpectedResponseException(`Unexpected server response (${status}) while retrieving PDF "${url}".`, status);\n}\n\nfunction validateResponseStatus(status) {\n return status === 200 || status === 206;\n}\n\n/***/ }),\n/* 27 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.getFilenameFromContentDispositionHeader = getFilenameFromContentDispositionHeader;\n\nvar _util = __w_pdfjs_require__(1);\n\nfunction getFilenameFromContentDispositionHeader(contentDisposition) {\n let needsEncodingFixup = true;\n let tmp = toParamRegExp("filename\\\\*", "i").exec(contentDisposition);\n\n if (tmp) {\n tmp = tmp[1];\n let filename = rfc2616unquote(tmp);\n filename = unescape(filename);\n filename = rfc5987decode(filename);\n filename = rfc2047decode(filename);\n return fixupEncoding(filename);\n }\n\n tmp = rfc2231getparam(contentDisposition);\n\n if (tmp) {\n const filename = rfc2047decode(tmp);\n return fixupEncoding(filename);\n }\n\n tmp = toParamRegExp("filename", "i").exec(contentDisposition);\n\n if (tmp) {\n tmp = tmp[1];\n let filename = rfc2616unquote(tmp);\n filename = rfc2047decode(filename);\n return fixupEncoding(filename);\n }\n\n function toParamRegExp(attributePattern, flags) {\n return new RegExp("(?:^|;)\\\\s*" + attributePattern + "\\\\s*=\\\\s*" + "(" + \'[^";\\\\s][^;\\\\s]*\' + "|" + \'"(?:[^"\\\\\\\\]|\\\\\\\\"?)+"?\' + ")", flags);\n }\n\n function textdecode(encoding, value) {\n if (encoding) {\n if (!/^[\\x00-\\xFF]+$/.test(value)) {\n return value;\n }\n\n try {\n const decoder = new TextDecoder(encoding, {\n fatal: true\n });\n const buffer = (0, _util.stringToBytes)(value);\n value = decoder.decode(buffer);\n needsEncodingFixup = false;\n } catch (e) {}\n }\n\n return value;\n }\n\n function fixupEncoding(value) {\n if (needsEncodingFixup && /[\\x80-\\xff]/.test(value)) {\n value = textdecode("utf-8", value);\n\n if (needsEncodingFixup) {\n value = textdecode("iso-8859-1", value);\n }\n }\n\n return value;\n }\n\n function rfc2231getparam(contentDispositionStr) {\n const matches = [];\n let match;\n const iter = toParamRegExp("filename\\\\*((?!0\\\\d)\\\\d+)(\\\\*?)", "ig");\n\n while ((match = iter.exec(contentDispositionStr)) !== null) {\n let [, n, quot, part] = match;\n n = parseInt(n, 10);\n\n if (n in matches) {\n if (n === 0) {\n break;\n }\n\n continue;\n }\n\n matches[n] = [quot, part];\n }\n\n const parts = [];\n\n for (let n = 0; n < matches.length; ++n) {\n if (!(n in matches)) {\n break;\n }\n\n let [quot, part] = matches[n];\n part = rfc2616unquote(part);\n\n if (quot) {\n part = unescape(part);\n\n if (n === 0) {\n part = rfc5987decode(part);\n }\n }\n\n parts.push(part);\n }\n\n return parts.join("");\n }\n\n function rfc2616unquote(value) {\n if (value.startsWith(\'"\')) {\n const parts = value.slice(1).split(\'\\\\"\');\n\n for (let i = 0; i < parts.length; ++i) {\n const quotindex = parts[i].indexOf(\'"\');\n\n if (quotindex !== -1) {\n parts[i] = parts[i].slice(0, quotindex);\n parts.length = i + 1;\n }\n\n parts[i] = parts[i].replace(/\\\\(.)/g, "$1");\n }\n\n value = parts.join(\'"\');\n }\n\n return value;\n }\n\n function rfc5987decode(extvalue) {\n const encodingend = extvalue.indexOf("\'");\n\n if (encodingend === -1) {\n return extvalue;\n }\n\n const encoding = extvalue.slice(0, encodingend);\n const langvalue = extvalue.slice(encodingend + 1);\n const value = langvalue.replace(/^[^\']*\'/, "");\n return textdecode(encoding, value);\n }\n\n function rfc2047decode(value) {\n if (!value.startsWith("=?") || /[\\x00-\\x19\\x80-\\xff]/.test(value)) {\n return value;\n }\n\n return value.replace(/=\\?([\\w-]*)\\?([QqBb])\\?((?:[^?]|\\?(?!=))*)\\?=/g, function (matches, charset, encoding, text) {\n if (encoding === "q" || encoding === "Q") {\n text = text.replace(/_/g, " ");\n text = text.replace(/=([0-9a-fA-F]{2})/g, function (match, hex) {\n return String.fromCharCode(parseInt(hex, 16));\n });\n return textdecode(charset, text);\n }\n\n try {\n text = atob(text);\n } catch (e) {}\n\n return textdecode(charset, text);\n });\n }\n\n return "";\n}\n\n/***/ }),\n/* 28 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.PDFNetworkStream = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _network_utils = __w_pdfjs_require__(26);\n\n;\nconst OK_RESPONSE = 200;\nconst PARTIAL_CONTENT_RESPONSE = 206;\n\nfunction getArrayBuffer(xhr) {\n const data = xhr.response;\n\n if (typeof data !== "string") {\n return data;\n }\n\n const array = (0, _util.stringToBytes)(data);\n return array.buffer;\n}\n\nclass NetworkManager {\n constructor(url, args = {}) {\n this.url = url;\n this.isHttp = /^https?:/i.test(url);\n this.httpHeaders = this.isHttp && args.httpHeaders || Object.create(null);\n this.withCredentials = args.withCredentials || false;\n\n this.getXhr = args.getXhr || function NetworkManager_getXhr() {\n return new XMLHttpRequest();\n };\n\n this.currXhrId = 0;\n this.pendingRequests = Object.create(null);\n }\n\n requestRange(begin, end, listeners) {\n const args = {\n begin,\n end\n };\n\n for (const prop in listeners) {\n args[prop] = listeners[prop];\n }\n\n return this.request(args);\n }\n\n requestFull(listeners) {\n return this.request(listeners);\n }\n\n request(args) {\n const xhr = this.getXhr();\n const xhrId = this.currXhrId++;\n const pendingRequest = this.pendingRequests[xhrId] = {\n xhr\n };\n xhr.open("GET", this.url);\n xhr.withCredentials = this.withCredentials;\n\n for (const property in this.httpHeaders) {\n const value = this.httpHeaders[property];\n\n if (typeof value === "undefined") {\n continue;\n }\n\n xhr.setRequestHeader(property, value);\n }\n\n if (this.isHttp && "begin" in args && "end" in args) {\n xhr.setRequestHeader("Range", `bytes=${args.begin}-${args.end - 1}`);\n pendingRequest.expectedStatus = PARTIAL_CONTENT_RESPONSE;\n } else {\n pendingRequest.expectedStatus = OK_RESPONSE;\n }\n\n xhr.responseType = "arraybuffer";\n\n if (args.onError) {\n xhr.onerror = function (evt) {\n args.onError(xhr.status);\n };\n }\n\n xhr.onreadystatechange = this.onStateChange.bind(this, xhrId);\n xhr.onprogress = this.onProgress.bind(this, xhrId);\n pendingRequest.onHeadersReceived = args.onHeadersReceived;\n pendingRequest.onDone = args.onDone;\n pendingRequest.onError = args.onError;\n pendingRequest.onProgress = args.onProgress;\n xhr.send(null);\n return xhrId;\n }\n\n onProgress(xhrId, evt) {\n const pendingRequest = this.pendingRequests[xhrId];\n\n if (!pendingRequest) {\n return;\n }\n\n pendingRequest.onProgress?.(evt);\n }\n\n onStateChange(xhrId, evt) {\n const pendingRequest = this.pendingRequests[xhrId];\n\n if (!pendingRequest) {\n return;\n }\n\n const xhr = pendingRequest.xhr;\n\n if (xhr.readyState >= 2 && pendingRequest.onHeadersReceived) {\n pendingRequest.onHeadersReceived();\n delete pendingRequest.onHeadersReceived;\n }\n\n if (xhr.readyState !== 4) {\n return;\n }\n\n if (!(xhrId in this.pendingRequests)) {\n return;\n }\n\n delete this.pendingRequests[xhrId];\n\n if (xhr.status === 0 && this.isHttp) {\n pendingRequest.onError?.(xhr.status);\n return;\n }\n\n const xhrStatus = xhr.status || OK_RESPONSE;\n const ok_response_on_range_request = xhrStatus === OK_RESPONSE && pendingRequest.expectedStatus === PARTIAL_CONTENT_RESPONSE;\n\n if (!ok_response_on_range_request && xhrStatus !== pendingRequest.expectedStatus) {\n pendingRequest.onError?.(xhr.status);\n return;\n }\n\n const chunk = getArrayBuffer(xhr);\n\n if (xhrStatus === PARTIAL_CONTENT_RESPONSE) {\n const rangeHeader = xhr.getResponseHeader("Content-Range");\n const matches = /bytes (\\d+)-(\\d+)\\/(\\d+)/.exec(rangeHeader);\n pendingRequest.onDone({\n begin: parseInt(matches[1], 10),\n chunk\n });\n } else if (chunk) {\n pendingRequest.onDone({\n begin: 0,\n chunk\n });\n } else {\n pendingRequest.onError?.(xhr.status);\n }\n }\n\n getRequestXhr(xhrId) {\n return this.pendingRequests[xhrId].xhr;\n }\n\n isPendingRequest(xhrId) {\n return xhrId in this.pendingRequests;\n }\n\n abortRequest(xhrId) {\n const xhr = this.pendingRequests[xhrId].xhr;\n delete this.pendingRequests[xhrId];\n xhr.abort();\n }\n\n}\n\nclass PDFNetworkStream {\n constructor(source) {\n this._source = source;\n this._manager = new NetworkManager(source.url, {\n httpHeaders: source.httpHeaders,\n withCredentials: source.withCredentials\n });\n this._rangeChunkSize = source.rangeChunkSize;\n this._fullRequestReader = null;\n this._rangeRequestReaders = [];\n }\n\n _onRangeRequestReaderClosed(reader) {\n const i = this._rangeRequestReaders.indexOf(reader);\n\n if (i >= 0) {\n this._rangeRequestReaders.splice(i, 1);\n }\n }\n\n getFullReader() {\n (0, _util.assert)(!this._fullRequestReader, "PDFNetworkStream.getFullReader can only be called once.");\n this._fullRequestReader = new PDFNetworkStreamFullRequestReader(this._manager, this._source);\n return this._fullRequestReader;\n }\n\n getRangeReader(begin, end) {\n const reader = new PDFNetworkStreamRangeRequestReader(this._manager, begin, end);\n reader.onClosed = this._onRangeRequestReaderClosed.bind(this);\n\n this._rangeRequestReaders.push(reader);\n\n return reader;\n }\n\n cancelAllRequests(reason) {\n this._fullRequestReader?.cancel(reason);\n\n for (const reader of this._rangeRequestReaders.slice(0)) {\n reader.cancel(reason);\n }\n }\n\n}\n\nexports.PDFNetworkStream = PDFNetworkStream;\n\nclass PDFNetworkStreamFullRequestReader {\n constructor(manager, source) {\n this._manager = manager;\n const args = {\n onHeadersReceived: this._onHeadersReceived.bind(this),\n onDone: this._onDone.bind(this),\n onError: this._onError.bind(this),\n onProgress: this._onProgress.bind(this)\n };\n this._url = source.url;\n this._fullRequestId = manager.requestFull(args);\n this._headersReceivedCapability = (0, _util.createPromiseCapability)();\n this._disableRange = source.disableRange || false;\n this._contentLength = source.length;\n this._rangeChunkSize = source.rangeChunkSize;\n\n if (!this._rangeChunkSize && !this._disableRange) {\n this._disableRange = true;\n }\n\n this._isStreamingSupported = false;\n this._isRangeSupported = false;\n this._cachedChunks = [];\n this._requests = [];\n this._done = false;\n this._storedError = undefined;\n this._filename = null;\n this.onProgress = null;\n }\n\n _onHeadersReceived() {\n const fullRequestXhrId = this._fullRequestId;\n\n const fullRequestXhr = this._manager.getRequestXhr(fullRequestXhrId);\n\n const getResponseHeader = name => {\n return fullRequestXhr.getResponseHeader(name);\n };\n\n const {\n allowRangeRequests,\n suggestedLength\n } = (0, _network_utils.validateRangeRequestCapabilities)({\n getResponseHeader,\n isHttp: this._manager.isHttp,\n rangeChunkSize: this._rangeChunkSize,\n disableRange: this._disableRange\n });\n\n if (allowRangeRequests) {\n this._isRangeSupported = true;\n }\n\n this._contentLength = suggestedLength || this._contentLength;\n this._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader);\n\n if (this._isRangeSupported) {\n this._manager.abortRequest(fullRequestXhrId);\n }\n\n this._headersReceivedCapability.resolve();\n }\n\n _onDone(data) {\n if (data) {\n if (this._requests.length > 0) {\n const requestCapability = this._requests.shift();\n\n requestCapability.resolve({\n value: data.chunk,\n done: false\n });\n } else {\n this._cachedChunks.push(data.chunk);\n }\n }\n\n this._done = true;\n\n if (this._cachedChunks.length > 0) {\n return;\n }\n\n for (const requestCapability of this._requests) {\n requestCapability.resolve({\n value: undefined,\n done: true\n });\n }\n\n this._requests.length = 0;\n }\n\n _onError(status) {\n this._storedError = (0, _network_utils.createResponseStatusError)(status, this._url);\n\n this._headersReceivedCapability.reject(this._storedError);\n\n for (const requestCapability of this._requests) {\n requestCapability.reject(this._storedError);\n }\n\n this._requests.length = 0;\n this._cachedChunks.length = 0;\n }\n\n _onProgress(evt) {\n this.onProgress?.({\n loaded: evt.loaded,\n total: evt.lengthComputable ? evt.total : this._contentLength\n });\n }\n\n get filename() {\n return this._filename;\n }\n\n get isRangeSupported() {\n return this._isRangeSupported;\n }\n\n get isStreamingSupported() {\n return this._isStreamingSupported;\n }\n\n get contentLength() {\n return this._contentLength;\n }\n\n get headersReady() {\n return this._headersReceivedCapability.promise;\n }\n\n async read() {\n if (this._storedError) {\n throw this._storedError;\n }\n\n if (this._cachedChunks.length > 0) {\n const chunk = this._cachedChunks.shift();\n\n return {\n value: chunk,\n done: false\n };\n }\n\n if (this._done) {\n return {\n value: undefined,\n done: true\n };\n }\n\n const requestCapability = (0, _util.createPromiseCapability)();\n\n this._requests.push(requestCapability);\n\n return requestCapability.promise;\n }\n\n cancel(reason) {\n this._done = true;\n\n this._headersReceivedCapability.reject(reason);\n\n for (const requestCapability of this._requests) {\n requestCapability.resolve({\n value: undefined,\n done: true\n });\n }\n\n this._requests.length = 0;\n\n if (this._manager.isPendingRequest(this._fullRequestId)) {\n this._manager.abortRequest(this._fullRequestId);\n }\n\n this._fullRequestReader = null;\n }\n\n}\n\nclass PDFNetworkStreamRangeRequestReader {\n constructor(manager, begin, end) {\n this._manager = manager;\n const args = {\n onDone: this._onDone.bind(this),\n onError: this._onError.bind(this),\n onProgress: this._onProgress.bind(this)\n };\n this._url = manager.url;\n this._requestId = manager.requestRange(begin, end, args);\n this._requests = [];\n this._queuedChunk = null;\n this._done = false;\n this._storedError = undefined;\n this.onProgress = null;\n this.onClosed = null;\n }\n\n _close() {\n this.onClosed?.(this);\n }\n\n _onDone(data) {\n const chunk = data.chunk;\n\n if (this._requests.length > 0) {\n const requestCapability = this._requests.shift();\n\n requestCapability.resolve({\n value: chunk,\n done: false\n });\n } else {\n this._queuedChunk = chunk;\n }\n\n this._done = true;\n\n for (const requestCapability of this._requests) {\n requestCapability.resolve({\n value: undefined,\n done: true\n });\n }\n\n this._requests.length = 0;\n\n this._close();\n }\n\n _onError(status) {\n this._storedError = (0, _network_utils.createResponseStatusError)(status, this._url);\n\n for (const requestCapability of this._requests) {\n requestCapability.reject(this._storedError);\n }\n\n this._requests.length = 0;\n this._queuedChunk = null;\n }\n\n _onProgress(evt) {\n if (!this.isStreamingSupported) {\n this.onProgress?.({\n loaded: evt.loaded\n });\n }\n }\n\n get isStreamingSupported() {\n return false;\n }\n\n async read() {\n if (this._storedError) {\n throw this._storedError;\n }\n\n if (this._queuedChunk !== null) {\n const chunk = this._queuedChunk;\n this._queuedChunk = null;\n return {\n value: chunk,\n done: false\n };\n }\n\n if (this._done) {\n return {\n value: undefined,\n done: true\n };\n }\n\n const requestCapability = (0, _util.createPromiseCapability)();\n\n this._requests.push(requestCapability);\n\n return requestCapability.promise;\n }\n\n cancel(reason) {\n this._done = true;\n\n for (const requestCapability of this._requests) {\n requestCapability.resolve({\n value: undefined,\n done: true\n });\n }\n\n this._requests.length = 0;\n\n if (this._manager.isPendingRequest(this._requestId)) {\n this._manager.abortRequest(this._requestId);\n }\n\n this._close();\n }\n\n}\n\n/***/ }),\n/* 29 */\n/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {\n\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.PDFFetchStream = void 0;\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _network_utils = __w_pdfjs_require__(26);\n\n;\n\nfunction createFetchOptions(headers, withCredentials, abortController) {\n return {\n method: "GET",\n headers,\n signal: abortController?.signal,\n mode: "cors",\n credentials: withCredentials ? "include" : "same-origin",\n redirect: "follow"\n };\n}\n\nfunction createHeaders(httpHeaders) {\n const headers = new Headers();\n\n for (const property in httpHeaders) {\n const value = httpHeaders[property];\n\n if (typeof value === "undefined") {\n continue;\n }\n\n headers.append(property, value);\n }\n\n return headers;\n}\n\nclass PDFFetchStream {\n constructor(source) {\n this.source = source;\n this.isHttp = /^https?:/i.test(source.url);\n this.httpHeaders = this.isHttp && source.httpHeaders || {};\n this._fullRequestReader = null;\n this._rangeRequestReaders = [];\n }\n\n get _progressiveDataLength() {\n return this._fullRequestReader?._loaded ?? 0;\n }\n\n getFullReader() {\n (0, _util.assert)(!this._fullRequestReader, "PDFFetchStream.getFullReader can only be called once.");\n this._fullRequestReader = new PDFFetchStreamReader(this);\n return this._fullRequestReader;\n }\n\n getRangeReader(begin, end) {\n if (end <= this._progressiveDataLength) {\n return null;\n }\n\n const reader = new PDFFetchStreamRangeReader(this, begin, end);\n\n this._rangeRequestReaders.push(reader);\n\n return reader;\n }\n\n cancelAllRequests(reason) {\n if (this._fullRequestReader) {\n this._fullRequestReader.cancel(reason);\n }\n\n for (const reader of this._rangeRequestReaders.slice(0)) {\n reader.cancel(reason);\n }\n }\n\n}\n\nexports.PDFFetchStream = PDFFetchStream;\n\nclass PDFFetchStreamReader {\n constructor(stream) {\n this._stream = stream;\n this._reader = null;\n this._loaded = 0;\n this._filename = null;\n const source = stream.source;\n this._withCredentials = source.withCredentials || false;\n this._contentLength = source.length;\n this._headersCapability = (0, _util.createPromiseCapability)();\n this._disableRange = source.disableRange || false;\n this._rangeChunkSize = source.rangeChunkSize;\n\n if (!this._rangeChunkSize && !this._disableRange) {\n this._disableRange = true;\n }\n\n if (typeof AbortController !== "undefined") {\n this._abortController = new AbortController();\n }\n\n this._isStreamingSupported = !source.disableStream;\n this._isRangeSupported = !source.disableRange;\n this._headers = createHeaders(this._stream.httpHeaders);\n const url = source.url;\n fetch(url, createFetchOptions(this._headers, this._withCredentials, this._abortController)).then(response => {\n if (!(0, _network_utils.validateResponseStatus)(response.status)) {\n throw (0, _network_utils.createResponseStatusError)(response.status, url);\n }\n\n this._reader = response.body.getReader();\n\n this._headersCapability.resolve();\n\n const getResponseHeader = name => {\n return response.headers.get(name);\n };\n\n const {\n allowRangeRequests,\n suggestedLength\n } = (0, _network_utils.validateRangeRequestCapabilities)({\n getResponseHeader,\n isHttp: this._stream.isHttp,\n rangeChunkSize: this._rangeChunkSize,\n disableRange: this._disableRange\n });\n this._isRangeSupported = allowRangeRequests;\n this._contentLength = suggestedLength || this._contentLength;\n this._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader);\n\n if (!this._isStreamingSupported && this._isRangeSupported) {\n this.cancel(new _util.AbortException("Streaming is disabled."));\n }\n }).catch(this._headersCapability.reject);\n this.onProgress = null;\n }\n\n get headersReady() {\n return this._headersCapability.promise;\n }\n\n get filename() {\n return this._filename;\n }\n\n get contentLength() {\n return this._contentLength;\n }\n\n get isRangeSupported() {\n return this._isRangeSupported;\n }\n\n get isStreamingSupported() {\n return this._isStreamingSupported;\n }\n\n async read() {\n await this._headersCapability.promise;\n const {\n value,\n done\n } = await this._reader.read();\n\n if (done) {\n return {\n value,\n done\n };\n }\n\n this._loaded += value.byteLength;\n\n if (this.onProgress) {\n this.onProgress({\n loaded: this._loaded,\n total: this._contentLength\n });\n }\n\n const buffer = new Uint8Array(value).buffer;\n return {\n value: buffer,\n done: false\n };\n }\n\n cancel(reason) {\n if (this._reader) {\n this._reader.cancel(reason);\n }\n\n if (this._abortController) {\n this._abortController.abort();\n }\n }\n\n}\n\nclass PDFFetchStreamRangeReader {\n constructor(stream, begin, end) {\n this._stream = stream;\n this._reader = null;\n this._loaded = 0;\n const source = stream.source;\n this._withCredentials = source.withCredentials || false;\n this._readCapability = (0, _util.createPromiseCapability)();\n this._isStreamingSupported = !source.disableStream;\n\n if (typeof AbortController !== "undefined") {\n this._abortController = new AbortController();\n }\n\n this._headers = createHeaders(this._stream.httpHeaders);\n\n this._headers.append("Range", `bytes=${begin}-${end - 1}`);\n\n const url = source.url;\n fetch(url, createFetchOptions(this._headers, this._withCredentials, this._abortController)).then(response => {\n if (!(0, _network_utils.validateResponseStatus)(response.status)) {\n throw (0, _network_utils.createResponseStatusError)(response.status, url);\n }\n\n this._readCapability.resolve();\n\n this._reader = response.body.getReader();\n }).catch(this._readCapability.reject);\n this.onProgress = null;\n }\n\n get isStreamingSupported() {\n return this._isStreamingSupported;\n }\n\n async read() {\n await this._readCapability.promise;\n const {\n value,\n done\n } = await this._reader.read();\n\n if (done) {\n return {\n value,\n done\n };\n }\n\n this._loaded += value.byteLength;\n\n if (this.onProgress) {\n this.onProgress({\n loaded: this._loaded\n });\n }\n\n const buffer = new Uint8Array(value).buffer;\n return {\n value: buffer,\n done: false\n };\n }\n\n cancel(reason) {\n if (this._reader) {\n this._reader.cancel(reason);\n }\n\n if (this._abortController) {\n this._abortController.abort();\n }\n }\n\n}\n\n/***/ })\n/******/ \t]);\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __w_pdfjs_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tvar cachedModule = __webpack_module_cache__[moduleId];\n/******/ \t\tif (cachedModule !== undefined) {\n/******/ \t\t\treturn cachedModule.exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __w_pdfjs_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\nvar __webpack_exports__ = {};\n// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.\n(() => {\nvar exports = __webpack_exports__;\n\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nObject.defineProperty(exports, "AnnotationLayer", ({\n enumerable: true,\n get: function () {\n return _annotation_layer.AnnotationLayer;\n }\n}));\nObject.defineProperty(exports, "AnnotationMode", ({\n enumerable: true,\n get: function () {\n return _util.AnnotationMode;\n }\n}));\nObject.defineProperty(exports, "CMapCompressionType", ({\n enumerable: true,\n get: function () {\n return _util.CMapCompressionType;\n }\n}));\nObject.defineProperty(exports, "GlobalWorkerOptions", ({\n enumerable: true,\n get: function () {\n return _worker_options.GlobalWorkerOptions;\n }\n}));\nObject.defineProperty(exports, "InvalidPDFException", ({\n enumerable: true,\n get: function () {\n return _util.InvalidPDFException;\n }\n}));\nObject.defineProperty(exports, "LoopbackPort", ({\n enumerable: true,\n get: function () {\n return _api.LoopbackPort;\n }\n}));\nObject.defineProperty(exports, "MissingPDFException", ({\n enumerable: true,\n get: function () {\n return _util.MissingPDFException;\n }\n}));\nObject.defineProperty(exports, "OPS", ({\n enumerable: true,\n get: function () {\n return _util.OPS;\n }\n}));\nObject.defineProperty(exports, "PDFDataRangeTransport", ({\n enumerable: true,\n get: function () {\n return _api.PDFDataRangeTransport;\n }\n}));\nObject.defineProperty(exports, "PDFDateString", ({\n enumerable: true,\n get: function () {\n return _display_utils.PDFDateString;\n }\n}));\nObject.defineProperty(exports, "PDFWorker", ({\n enumerable: true,\n get: function () {\n return _api.PDFWorker;\n }\n}));\nObject.defineProperty(exports, "PasswordResponses", ({\n enumerable: true,\n get: function () {\n return _util.PasswordResponses;\n }\n}));\nObject.defineProperty(exports, "PermissionFlag", ({\n enumerable: true,\n get: function () {\n return _util.PermissionFlag;\n }\n}));\nObject.defineProperty(exports, "PixelsPerInch", ({\n enumerable: true,\n get: function () {\n return _display_utils.PixelsPerInch;\n }\n}));\nObject.defineProperty(exports, "RenderingCancelledException", ({\n enumerable: true,\n get: function () {\n return _display_utils.RenderingCancelledException;\n }\n}));\nObject.defineProperty(exports, "SVGGraphics", ({\n enumerable: true,\n get: function () {\n return _svg.SVGGraphics;\n }\n}));\nObject.defineProperty(exports, "UNSUPPORTED_FEATURES", ({\n enumerable: true,\n get: function () {\n return _util.UNSUPPORTED_FEATURES;\n }\n}));\nObject.defineProperty(exports, "UnexpectedResponseException", ({\n enumerable: true,\n get: function () {\n return _util.UnexpectedResponseException;\n }\n}));\nObject.defineProperty(exports, "Util", ({\n enumerable: true,\n get: function () {\n return _util.Util;\n }\n}));\nObject.defineProperty(exports, "VerbosityLevel", ({\n enumerable: true,\n get: function () {\n return _util.VerbosityLevel;\n }\n}));\nObject.defineProperty(exports, "XfaLayer", ({\n enumerable: true,\n get: function () {\n return _xfa_layer.XfaLayer;\n }\n}));\nObject.defineProperty(exports, "build", ({\n enumerable: true,\n get: function () {\n return _api.build;\n }\n}));\nObject.defineProperty(exports, "createPromiseCapability", ({\n enumerable: true,\n get: function () {\n return _util.createPromiseCapability;\n }\n}));\nObject.defineProperty(exports, "createValidAbsoluteUrl", ({\n enumerable: true,\n get: function () {\n return _util.createValidAbsoluteUrl;\n }\n}));\nObject.defineProperty(exports, "getDocument", ({\n enumerable: true,\n get: function () {\n return _api.getDocument;\n }\n}));\nObject.defineProperty(exports, "getFilenameFromUrl", ({\n enumerable: true,\n get: function () {\n return _display_utils.getFilenameFromUrl;\n }\n}));\nObject.defineProperty(exports, "getPdfFilenameFromUrl", ({\n enumerable: true,\n get: function () {\n return _display_utils.getPdfFilenameFromUrl;\n }\n}));\nObject.defineProperty(exports, "getXfaPageViewport", ({\n enumerable: true,\n get: function () {\n return _display_utils.getXfaPageViewport;\n }\n}));\nObject.defineProperty(exports, "isPdfFile", ({\n enumerable: true,\n get: function () {\n return _display_utils.isPdfFile;\n }\n}));\nObject.defineProperty(exports, "loadScript", ({\n enumerable: true,\n get: function () {\n return _display_utils.loadScript;\n }\n}));\nObject.defineProperty(exports, "renderTextLayer", ({\n enumerable: true,\n get: function () {\n return _text_layer.renderTextLayer;\n }\n}));\nObject.defineProperty(exports, "shadow", ({\n enumerable: true,\n get: function () {\n return _util.shadow;\n }\n}));\nObject.defineProperty(exports, "version", ({\n enumerable: true,\n get: function () {\n return _api.version;\n }\n}));\n\nvar _util = __w_pdfjs_require__(1);\n\nvar _api = __w_pdfjs_require__(4);\n\nvar _display_utils = __w_pdfjs_require__(5);\n\nvar _annotation_layer = __w_pdfjs_require__(20);\n\nvar _worker_options = __w_pdfjs_require__(13);\n\nvar _is_node = __w_pdfjs_require__(3);\n\nvar _text_layer = __w_pdfjs_require__(23);\n\nvar _svg = __w_pdfjs_require__(24);\n\nvar _xfa_layer = __w_pdfjs_require__(22);\n\nconst pdfjsVersion = \'2.14.305\';\nconst pdfjsBuild = \'eaaa8b4ad\';\n{\n if (_is_node.isNodeJS) {\n const {\n PDFNodeStream\n } = __w_pdfjs_require__(25);\n\n (0, _api.setPDFNetworkStreamFactory)(params => {\n return new PDFNodeStream(params);\n });\n } else {\n const {\n PDFNetworkStream\n } = __w_pdfjs_require__(28);\n\n const {\n PDFFetchStream\n } = __w_pdfjs_require__(29);\n\n (0, _api.setPDFNetworkStreamFactory)(params => {\n if ((0, _display_utils.isValidFetchUrl)(params.url)) {\n return new PDFFetchStream(params);\n }\n\n return new PDFNetworkStream(params);\n });\n }\n}\n})();\n\n/******/ \treturn __webpack_exports__;\n/******/ })()\n;\n});\n//# sourceMappingURL=pdf.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9wZGZqcy1kaXN0L2J1aWxkL3BkZi5qcz85NTExIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLElBQUksSUFBeUQ7QUFDN0Q7QUFDQSxNQUFNLEVBS3FEO0FBQzNELENBQUM7QUFDRCx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx5QkFBeUIsSUFBSTtBQUM3QjtBQUNBOztBQUVBO0FBQ0E7QUFDQSw0QkFBNEIsSUFBSTtBQUNoQztBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMEJBQTBCLElBQUk7QUFDOUI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxpQkFBaUIsWUFBWTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsaUJBQWlCLFlBQVk7QUFDN0I7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBLGlCQUFpQixZQUFZO0FBQzdCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxpQkFBaUIsWUFBWTtBQUM3Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxlQUFlLGNBQWMsRUFBRSxjQUFjLEVBQUUsY0FBYztBQUM3RDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUIsT0FBTztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLE9BQU87QUFDUCxvQ0FBb0MsR0FBRztBQUN2QztBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsa0NBQWtDLFFBQVE7QUFDMUM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQSxnQkFBZ0IsTUFBTTtBQUN0QixHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsa0NBQWtDLFFBQVE7QUFDMUM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsbUNBQW1DLFFBQVE7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7O0FBRUE7O0FBRUEsT0FBTztBQUNQO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTs7QUFFQSxPQUFPO0FBQ1A7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWCx5REFBeUQsR0FBRztBQUM1RDtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQixnQ0FBZ0M7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHLEtBQUs7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0EsR0FBRyxLQUFLO0FBQ1I7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGFBQWE7QUFDYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsYUFBYTtBQUNiO0FBQ0E7O0FBRUE7QUFDQSxPQUFPO0FBQ1A7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRyxLQUFLO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUcsS0FBSztBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBLEtBQUs7QUFDTDs7QUFFQSw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87O0FBRVA7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0RBQWtELFFBQVE7QUFDMUQ7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXOztBQUVYO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQSw0RkFBNEY7QUFDNUY7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCLFVBQWM7QUFDekM7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0Esc0NBQXNDLElBQUksR0FBRztBQUM3QztBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdB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RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULE9BQU87QUFDUDtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwwREFBMEQsY0FBYztBQUN4RTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsV0FBVztBQUNYO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFdBQVc7QUFDWDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDREQUE0RCxLQUFLO0FBQ2pFO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7O0FBRUE7QUFDQSxhQUFhO0FBQ2I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxREFBcUQsS0FBSztBQUMxRDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDhDQUE4QyxnQkFBZ0I7QUFDOUQ7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsbUVBQW1FLE1BQU07QUFDekU7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsdURBQXVEO0FBQ3ZEOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSx1R0FBdUcsb0JBQW9CO0FBQzNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHLEtBQUs7QUFDUjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHLEtBQUs7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxzREFBc0QsS0FBSztBQUMzRDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx3REFBd0QsS0FBSztBQUM3RDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxQkFBcUIsMEJBQTBCLEdBQUcsU0FBUztBQUMzRDs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNM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QUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUIsSUFBSSxHQUFHLHNCQUFzQjtBQUNsRDs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSx3Q0FBd0MsUUFBUTtBQUNoRDs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixpQkFBaUI7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUEsT0FBTztBQUNQO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0EsQ0FBQztBQUNEOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGFBQWEsV0FBVztBQUN4QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGFBQWEsWUFBWTtBQUN6QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLGVBQWUsV0FBVztBQUMxQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsYUFBYSxXQUFXO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBLGFBQWEsc0JBQXNCO0FBQ25DO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxPQUFPOztBQUVQOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUEsc0NBQXNDLFFBQVE7QUFDOUM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZUFBZSxpQkFBaUI7QUFDaEM7QUFDQTs7QUFFQSxpQkFBaUIscUJBQXFCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxjQUFjLGtCQUFrQjtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxjQUFjLFVBQVU7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBLGVBQWUsZ0JBQWdCO0FBQy9CO0FBQ0E7O0FBRUE7QUFDQSx1QkFBdUIsc0JBQXNCO0FBQzdDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsdUJBQXVCLHNCQUFzQjtBQUM3QztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUEsZUFBZSxpQkFBaUI7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsZ0NBQWdDLEtBQUs7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHVCQUF1QixhQUFhO0FBQ3BDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNILHVDQUF1QyxhQUFhO0FBQ3BEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsaUJBQWlCLGlCQUFpQjtBQUNsQztBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSx5Q0FBeUMsUUFBUTtBQUNqRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxpQkFBaUIsWUFBWTtBQUM3Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsaUJBQWlCLFlBQVk7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxpQkFBaUIsWUFBWTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsbUJBQW1CLGNBQWM7QUFDakM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlFQUF5RSxFQUFFOztBQUUzRTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0EsdUNBQXVDLFFBQVE7QUFDL0M7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwyQ0FBMkMsUUFBUTtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsbUJBQW1CLGtCQUFrQjtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDZDQUE2QyxZQUFZO0FBQ3pEOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBLHlCQUF5QixLQUFLLEtBQUsscUJBQXFCO0FBQ3hEOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBLHVCQUF1QixPQUFPLEdBQUcsS0FBSyxHQUFHLGdCQUFnQixLQUFLLFNBQVM7QUFDdkU7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixpQkFBaUI7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxlQUFlLGtCQUFrQjtBQUNqQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZUFBZSxrQkFBa0I7QUFDakM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSw0Q0FBNEMscUJBQXFCO0FBQ2pFO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULCtEQUErRCw4Q0FBOEM7QUFDN0cscUNBQXFDLE1BQU0sT0FBTyx1QkFBdUI7QUFDekUsc0NBQXNDLE9BQU8sT0FBTyx1QkFBdUI7QUFDM0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSwwQ0FBMEMsUUFBUTtBQUNsRDs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsdUNBQXVDLFFBQVE7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLDBDQUEwQyxRQUFRO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsb0NBQW9DLFFBQVE7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG9EQUFvRCxRQUFRO0FBQzVEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPO0FBQ1A7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1Asa0VBQWtFLFlBQVk7QUFDOUU7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsb0JBQW9CLFdBQVc7QUFDL0I7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHFCQUFxQixVQUFVO0FBQy9COztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGlCQUFpQixVQUFVO0FBQzNCOztBQUVBLHVCQUF1QixVQUFVO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsaUNBQWlDLFFBQVE7QUFDekM7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsd0NBQXdDLFFBQVE7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHNDQUFzQyxNQUFNO0FBQzVDOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLCtEQUErRCxVQUFVO0FBQ3pFO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTCxvREFBb0QsWUFBWTtBQUNoRTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIsWUFBWTtBQUM3Qiw0Q0FBNEMsY0FBYztBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsbUJBQW1CLG9CQUFvQjtBQUN2QztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPO0FBQ1A7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPO0FBQ1A7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EscURBQXFELFdBQVc7QUFDaEU7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSx1REFBdUQsWUFBWTtBQUNuRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWCxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGdFQUFnRSxXQUFXO0FBQzNFOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxPQUFPOztBQUVQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWCxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYLFNBQVM7QUFDVDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1gsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxPQUFPO0FBQ1A7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBLG1CQUFtQixZQUFZO0FBQy9CO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLE9BQU87QUFDUCw2REFBNkQsUUFBUTtBQUNyRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2REFBNkQsU0FBUztBQUN0RTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxpRUFBaUUsR0FBRztBQUNwRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxpRUFBaUUsR0FBRztBQUNwRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxpRUFBaUUsR0FBRztBQUNwRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxpRUFBaUUsR0FBRztBQUNwRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEseURBQXlELGFBQWE7QUFDdEU7QUFDQTs7QUFFQSwwQ0FBMEMsV0FBVztBQUNyRDtBQUNBOztBQUVBO0FBQ0E7QUFDQSwyREFBMkQsR0FBRztBQUM5RDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxPQUFPO0FBQ1A7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQSxPQUFPO0FBQ1A7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsT0FBTztBQUNQO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsZUFBZSxtQkFBTyxDQUFDLEdBQUk7O0FBRTNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQSxtQkFBbUIsbUJBQU8sQ0FBQyxHQUFROztBQUVuQztBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHLEtBQUs7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxxQkFBcUIsT0FBTztBQUM1QjtBQUNBOztBQUVBLDRDQUE0QyxvQkFBb0I7QUFDaEUsS0FBSztBQUNMLDRDQUE0Qyw2QkFBNkI7QUFDekU7O0FBRUEseUNBQXlDLFNBQVMsS0FBSyxTQUFTOztBQUVoRTtBQUNBLHVDQUF1Qyx1QkFBdUI7O0FBRTlEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSwwQkFBMEIsaUJBQWlCLE9BQU8sZUFBZTtBQUNqRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUEsOEJBQThCLFFBQVE7QUFDdEMsNkJBQTZCLFFBQVE7O0FBRXJDO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsaUNBQWlDLE1BQU07QUFDdkMsa0NBQWtDLE9BQU87QUFDekM7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSwwRUFBMEUsU0FBUztBQUNuRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULE9BQU87QUFDUDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLHlFQUF5RSxHQUFHO0FBQzVFO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsTUFBTTtBQUMxQjtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0EsYUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxlQUFlO0FBQ2YsYUFBYTs7QUFFYjtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0EsV0FBVztBQUNYO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXOztBQUVYO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1gsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiOztBQUVBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFdBQVc7QUFDWDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4Q0FBOEMsVUFBVTtBQUN4RDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0EsMEJBQTBCLFNBQVM7QUFDbkM7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7O0FBRUE7O0FBRUE7QUFDQSxPQUFPOztBQUVQO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLE9BQU87O0FBRVA7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7O0FBRUEsa0NBQWtDLFNBQVM7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDLFNBQVM7O0FBRS9DO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFdBQVc7O0FBRVg7QUFDQTtBQUNBLFdBQVc7O0FBRVg7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixXQUFXOztBQUVYO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixXQUFXOztBQUVYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsV0FBVzs7QUFFWDtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsV0FBVzs7QUFFWDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFdBQVc7O0FBRVg7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPOztBQUVQO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1A7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSw2Q0FBNkMsbUJBQW1CO0FBQ2hFOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBOztBQUVBO0FBQ0E7QUFDQSw4Q0FBOEMsV0FBVyxLQUFLLFVBQVU7QUFDeEUsbUNBQW1DLFVBQVU7QUFDN0Msa0NBQWtDLFNBQVM7QUFDM0M7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxNQUFNLElBQUksTUFBTTtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPOztBQUVQO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHNDQUFzQyxRQUFRO0FBQzlDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsRUFBRSxHQUFHLEVBQUU7QUFDOUI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLDZCQUE2QixvQkFBb0I7QUFDakQ7O0FBRUE7QUFDQSxvRUFBb0UsUUFBUTs7QUFFNUU7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLDZCQUE2QixPQUFPO0FBQ3BDO0FBQ0E7O0FBRUEsb0NBQW9DLHVCQUF1QjtBQUMzRDs7QUFFQTtBQUNBO0FBQ0Esb0NBQW9DLEtBQUs7QUFDekMsbUNBQW1DLElBQUk7QUFDdkMsK0NBQStDLE1BQU0sS0FBSyxLQUFLO0FBQy9EO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0VBQWdFLEdBQUc7O0FBRW5FO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsZUFBZSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUU7QUFDekI7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUU7QUFDekI7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUEsT0FBTztBQUNQO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0EsQ0FBQztBQUNEOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1gsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixXQUFXO0FBQ1gsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFdBQVc7QUFDWDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1gsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBLDJCQUEyQixnQkFBZ0IsR0FBRyxPQUFPO0FBQ3JEOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtDQUFrQyx3Q0FBd0M7QUFDMUU7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0NBQWdDLHdDQUF3QztBQUN4RTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUEsT0FBTztBQUNQO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0EsQ0FBQztBQUNEOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxnQkFBZ0Isa0JBQWtCLEtBQUssV0FBVztBQUNsRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEscUNBQXFDLFFBQVE7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxxQ0FBcUMsUUFBUTtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUEsMEJBQTBCLEtBQUs7QUFDL0IseUJBQXlCLElBQUk7QUFDN0IsOEJBQThCLFdBQVc7QUFDekM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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Q0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxzREFBc0QsR0FBRztBQUN6RDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlEQUF5RCxxQkFBcUI7QUFDOUU7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlEQUF5RCxxQkFBcUI7QUFDOUU7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTOztBQUVUOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQSx5REFBeUQscUJBQXFCOztBQUU5RTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw4REFBOEQsZUFBZSxTQUFTLGVBQWU7QUFDckc7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdEQUFnRCxpQkFBaUIsbUJBQW1CLEVBQUUsaUJBQWlCLElBQUksRUFBRSxFQUFFO0FBQy9HOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQyxlQUFlOztBQUVoRDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQyxJQUFJO0FBQzlDLDBDQUEwQyxJQUFJO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLFNBQVM7QUFDOUI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHNDQUFzQyxlQUFlO0FBQ3JEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJEQUEyRCxRQUFRO0FBQ25FOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHlCQUF5QixVQUFVOztBQUVuQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDhDQUE4QyxRQUFRO0FBQ3REO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxnQ0FBZ0MsWUFBWTtBQUM1QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsc0NBQXNDLE9BQU87QUFDN0M7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLHFCQUFxQix1Q0FBdUM7QUFDNUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxvRUFBb0UsSUFBSTtBQUN4RTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDBEQUEwRCxNQUFNO0FBQ2hFO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdURBQXVELGNBQWMsR0FBRyxnQkFBZ0I7O0FBRXhGO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEIsWUFBWTtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELGVBQWU7QUFDL0Q7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQSxXQUFXLG1CQUFPLENBQUMsR0FBSTs7QUFFdkIsYUFBYSxtQkFBTyxDQUFDLENBQU07O0FBRTNCLGNBQWMsbUJBQU8sQ0FBQyxHQUFPOztBQUU3QixZQUFZLG1CQUFPLENBQUMsR0FBSzs7QUFFekI7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxnQ0FBZ0MsVUFBVTtBQUMxQzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvRUFBb0UsVUFBVTtBQUM5RTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSx1Q0FBdUMsTUFBTSxHQUFHLFFBQVE7O0FBRXhEO0FBQ0E7QUFDQSxvRUFBb0UsVUFBVTtBQUM5RTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLEtBQUs7QUFDckU7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7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Q0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBLE9BQU87QUFDUDtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSwyQ0FBMkMsTUFBTSxHQUFHLFFBQVE7O0FBRTVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0EsVUFBVTtBQUNWO0FBQ0EsQ0FBQztBQUNEIiwiZmlsZSI6IjI5OS5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY3N0YXJ0IFRoZSBmb2xsb3dpbmcgaXMgdGhlIGVudGlyZSBsaWNlbnNlIG5vdGljZSBmb3IgdGhlXG4gKiBKYXZhU2NyaXB0IGNvZGUgaW4gdGhpcyBwYWdlXG4gKlxuICogQ29weXJpZ2h0IDIwMjIgTW96aWxsYSBGb3VuZGF0aW9uXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqIEBsaWNlbmQgVGhlIGFib3ZlIGlzIHRoZSBlbnRpcmUgbGljZW5zZSBub3RpY2UgZm9yIHRoZVxuICogSmF2YVNjcmlwdCBjb2RlIGluIHRoaXMgcGFnZVxuICovXG5cbihmdW5jdGlvbiB3ZWJwYWNrVW5pdmVyc2FsTW9kdWxlRGVmaW5pdGlvbihyb290LCBmYWN0b3J5KSB7XG5cdGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0Jylcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTtcblx0ZWxzZSBpZih0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXG5cdFx0ZGVmaW5lKFwicGRmanMtZGlzdC9idWlsZC9wZGZcIiwgW10sIGZhY3RvcnkpO1xuXHRlbHNlIGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jylcblx0XHRleHBvcnRzW1wicGRmanMtZGlzdC9idWlsZC9wZGZcIl0gPSBmYWN0b3J5KCk7XG5cdGVsc2Vcblx0XHRyb290W1wicGRmanMtZGlzdC9idWlsZC9wZGZcIl0gPSByb290LnBkZmpzTGliID0gZmFjdG9yeSgpO1xufSkodGhpcywgKCkgPT4ge1xucmV0dXJuIC8qKioqKiovICgoKSA9PiB7IC8vIHdlYnBhY2tCb290c3RyYXBcbi8qKioqKiovIFx0XCJ1c2Ugc3RyaWN0XCI7XG4vKioqKioqLyBcdHZhciBfX3dlYnBhY2tfbW9kdWxlc19fID0gKFtcbi8qIDAgKi8sXG4vKiAxICovXG4vKioqLyAoKF9fdW51c2VkX3dlYnBhY2tfbW9kdWxlLCBleHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5leHBvcnRzLlZlcmJvc2l0eUxldmVsID0gZXhwb3J0cy5VdGlsID0gZXhwb3J0cy5Vbmtub3duRXJyb3JFeGNlcHRpb24gPSBleHBvcnRzLlVuZXhwZWN0ZWRSZXNwb25zZUV4Y2VwdGlvbiA9IGV4cG9ydHMuVU5TVVBQT1JURURfRkVBVFVSRVMgPSBleHBvcnRzLlRleHRSZW5kZXJpbmdNb2RlID0gZXhwb3J0cy5TdHJlYW1UeXBlID0gZXhwb3J0cy5SZW5kZXJpbmdJbnRlbnRGbGFnID0gZXhwb3J0cy5QZXJtaXNzaW9uRmxhZyA9IGV4cG9ydHMuUGFzc3dvcmRSZXNwb25zZXMgPSBleHBvcnRzLlBhc3N3b3JkRXhjZXB0aW9uID0gZXhwb3J0cy5QYWdlQWN0aW9uRXZlbnRUeXBlID0gZXhwb3J0cy5PUFMgPSBleHBvcnRzLk1pc3NpbmdQREZFeGNlcHRpb24gPSBleHBvcnRzLkludmFsaWRQREZFeGNlcHRpb24gPSBleHBvcnRzLkltYWdlS2luZCA9IGV4cG9ydHMuSURFTlRJVFlfTUFUUklYID0gZXhwb3J0cy5Gb3JtYXRFcnJvciA9IGV4cG9ydHMuRm9udFR5cGUgPSBleHBvcnRzLkZlYXR1cmVUZXN0ID0gZXhwb3J0cy5GT05UX0lERU5USVRZX01BVFJJWCA9IGV4cG9ydHMuRG9jdW1lbnRBY3Rpb25FdmVudFR5cGUgPSBleHBvcnRzLkNNYXBDb21wcmVzc2lvblR5cGUgPSBleHBvcnRzLkJhc2VFeGNlcHRpb24gPSBleHBvcnRzLkFubm90YXRpb25UeXBlID0gZXhwb3J0cy5Bbm5vdGF0aW9uU3RhdGVNb2RlbFR5cGUgPSBleHBvcnRzLkFubm90YXRpb25SZXZpZXdTdGF0ZSA9IGV4cG9ydHMuQW5ub3RhdGlvblJlcGx5VHlwZSA9IGV4cG9ydHMuQW5ub3RhdGlvbk1vZGUgPSBleHBvcnRzLkFubm90YXRpb25NYXJrZWRTdGF0ZSA9IGV4cG9ydHMuQW5ub3RhdGlvbkZsYWcgPSBleHBvcnRzLkFubm90YXRpb25GaWVsZEZsYWcgPSBleHBvcnRzLkFubm90YXRpb25Cb3JkZXJTdHlsZVR5cGUgPSBleHBvcnRzLkFubm90YXRpb25BY3Rpb25FdmVudFR5cGUgPSBleHBvcnRzLkFib3J0RXhjZXB0aW9uID0gdm9pZCAwO1xuZXhwb3J0cy5hcnJheUJ5dGVMZW5ndGggPSBhcnJheUJ5dGVMZW5ndGg7XG5leHBvcnRzLmFycmF5c1RvQnl0ZXMgPSBhcnJheXNUb0J5dGVzO1xuZXhwb3J0cy5hc3NlcnQgPSBhc3NlcnQ7XG5leHBvcnRzLmJ5dGVzVG9TdHJpbmcgPSBieXRlc1RvU3RyaW5nO1xuZXhwb3J0cy5jcmVhdGVQcm9taXNlQ2FwYWJpbGl0eSA9IGNyZWF0ZVByb21pc2VDYXBhYmlsaXR5O1xuZXhwb3J0cy5jcmVhdGVWYWxpZEFic29sdXRlVXJsID0gY3JlYXRlVmFsaWRBYnNvbHV0ZVVybDtcbmV4cG9ydHMuZXNjYXBlU3RyaW5nID0gZXNjYXBlU3RyaW5nO1xuZXhwb3J0cy5nZXRNb2RpZmljYXRpb25EYXRlID0gZ2V0TW9kaWZpY2F0aW9uRGF0ZTtcbmV4cG9ydHMuZ2V0VmVyYm9zaXR5TGV2ZWwgPSBnZXRWZXJib3NpdHlMZXZlbDtcbmV4cG9ydHMuaW5mbyA9IGluZm87XG5leHBvcnRzLmlzQXJyYXlCdWZmZXIgPSBpc0FycmF5QnVmZmVyO1xuZXhwb3J0cy5pc0FycmF5RXF1YWwgPSBpc0FycmF5RXF1YWw7XG5leHBvcnRzLmlzQXNjaWkgPSBpc0FzY2lpO1xuZXhwb3J0cy5vYmplY3RGcm9tTWFwID0gb2JqZWN0RnJvbU1hcDtcbmV4cG9ydHMub2JqZWN0U2l6ZSA9IG9iamVjdFNpemU7XG5leHBvcnRzLnNldFZlcmJvc2l0eUxldmVsID0gc2V0VmVyYm9zaXR5TGV2ZWw7XG5leHBvcnRzLnNoYWRvdyA9IHNoYWRvdztcbmV4cG9ydHMuc3RyaW5nMzIgPSBzdHJpbmczMjtcbmV4cG9ydHMuc3RyaW5nVG9CeXRlcyA9IHN0cmluZ1RvQnl0ZXM7XG5leHBvcnRzLnN0cmluZ1RvUERGU3RyaW5nID0gc3RyaW5nVG9QREZTdHJpbmc7XG5leHBvcnRzLnN0cmluZ1RvVVRGMTZCRVN0cmluZyA9IHN0cmluZ1RvVVRGMTZCRVN0cmluZztcbmV4cG9ydHMuc3RyaW5nVG9VVEY4U3RyaW5nID0gc3RyaW5nVG9VVEY4U3RyaW5nO1xuZXhwb3J0cy51bnJlYWNoYWJsZSA9IHVucmVhY2hhYmxlO1xuZXhwb3J0cy51dGY4U3RyaW5nVG9TdHJpbmcgPSB1dGY4U3RyaW5nVG9TdHJpbmc7XG5leHBvcnRzLndhcm4gPSB3YXJuO1xuXG5fX3dfcGRmanNfcmVxdWlyZV9fKDIpO1xuXG5jb25zdCBJREVOVElUWV9NQVRSSVggPSBbMSwgMCwgMCwgMSwgMCwgMF07XG5leHBvcnRzLklERU5USVRZX01BVFJJWCA9IElERU5USVRZX01BVFJJWDtcbmNvbnN0IEZPTlRfSURFTlRJVFlfTUFUUklYID0gWzAuMDAxLCAwLCAwLCAwLjAwMSwgMCwgMF07XG5leHBvcnRzLkZPTlRfSURFTlRJVFlfTUFUUklYID0gRk9OVF9JREVOVElUWV9NQVRSSVg7XG5jb25zdCBSZW5kZXJpbmdJbnRlbnRGbGFnID0ge1xuICBBTlk6IDB4MDEsXG4gIERJU1BMQVk6IDB4MDIsXG4gIFBSSU5UOiAweDA0LFxuICBBTk5PVEFUSU9OU19GT1JNUzogMHgxMCxcbiAgQU5OT1RBVElPTlNfU1RPUkFHRTogMHgyMCxcbiAgQU5OT1RBVElPTlNfRElTQUJMRTogMHg0MCxcbiAgT1BMSVNUOiAweDEwMFxufTtcbmV4cG9ydHMuUmVuZGVyaW5nSW50ZW50RmxhZyA9IFJlbmRlcmluZ0ludGVudEZsYWc7XG5jb25zdCBBbm5vdGF0aW9uTW9kZSA9IHtcbiAgRElTQUJMRTogMCxcbiAgRU5BQkxFOiAxLFxuICBFTkFCTEVfRk9STVM6IDIsXG4gIEVOQUJMRV9TVE9SQUdFOiAzXG59O1xuZXhwb3J0cy5Bbm5vdGF0aW9uTW9kZSA9IEFubm90YXRpb25Nb2RlO1xuY29uc3QgUGVybWlzc2lvbkZsYWcgPSB7XG4gIFBSSU5UOiAweDA0LFxuICBNT0RJRllfQ09OVEVOVFM6IDB4MDgsXG4gIENPUFk6IDB4MTAsXG4gIE1PRElGWV9BTk5PVEFUSU9OUzogMHgyMCxcbiAgRklMTF9JTlRFUkFDVElWRV9GT1JNUzogMHgxMDAsXG4gIENPUFlfRk9SX0FDQ0VTU0lCSUxJVFk6IDB4MjAwLFxuICBBU1NFTUJMRTogMHg0MDAsXG4gIFBSSU5UX0hJR0hfUVVBTElUWTogMHg4MDBcbn07XG5leHBvcnRzLlBlcm1pc3Npb25GbGFnID0gUGVybWlzc2lvbkZsYWc7XG5jb25zdCBUZXh0UmVuZGVyaW5nTW9kZSA9IHtcbiAgRklMTDogMCxcbiAgU1RST0tFOiAxLFxuICBGSUxMX1NUUk9LRTogMixcbiAgSU5WSVNJQkxFOiAzLFxuICBGSUxMX0FERF9UT19QQVRIOiA0LFxuICBTVFJPS0VfQUREX1RPX1BBVEg6IDUsXG4gIEZJTExfU1RST0tFX0FERF9UT19QQVRIOiA2LFxuICBBRERfVE9fUEFUSDogNyxcbiAgRklMTF9TVFJPS0VfTUFTSzogMyxcbiAgQUREX1RPX1BBVEhfRkxBRzogNFxufTtcbmV4cG9ydHMuVGV4dFJlbmRlcmluZ01vZGUgPSBUZXh0UmVuZGVyaW5nTW9kZTtcbmNvbnN0IEltYWdlS2luZCA9IHtcbiAgR1JBWVNDQUxFXzFCUFA6IDEsXG4gIFJHQl8yNEJQUDogMixcbiAgUkdCQV8zMkJQUDogM1xufTtcbmV4cG9ydHMuSW1hZ2VLaW5kID0gSW1hZ2VLaW5kO1xuY29uc3QgQW5ub3RhdGlvblR5cGUgPSB7XG4gIFRFWFQ6IDEsXG4gIExJTks6IDIsXG4gIEZSRUVURVhUOiAzLFxuICBMSU5FOiA0LFxuICBTUVVBUkU6IDUsXG4gIENJUkNMRTogNixcbiAgUE9MWUdPTjogNyxcbiAgUE9MWUxJTkU6IDgsXG4gIEhJR0hMSUdIVDogOSxcbiAgVU5ERVJMSU5FOiAxMCxcbiAgU1FVSUdHTFk6IDExLFxuICBTVFJJS0VPVVQ6IDEyLFxuICBTVEFNUDogMTMsXG4gIENBUkVUOiAxNCxcbiAgSU5LOiAxNSxcbiAgUE9QVVA6IDE2LFxuICBGSUxFQVRUQUNITUVOVDogMTcsXG4gIFNPVU5EOiAxOCxcbiAgTU9WSUU6IDE5LFxuICBXSURHRVQ6IDIwLFxuICBTQ1JFRU46IDIxLFxuICBQUklOVEVSTUFSSzogMjIsXG4gIFRSQVBORVQ6IDIzLFxuICBXQVRFUk1BUks6IDI0LFxuICBUSFJFRUQ6IDI1LFxuICBSRURBQ1Q6IDI2XG59O1xuZXhwb3J0cy5Bbm5vdGF0aW9uVHlwZSA9IEFubm90YXRpb25UeXBlO1xuY29uc3QgQW5ub3RhdGlvblN0YXRlTW9kZWxUeXBlID0ge1xuICBNQVJLRUQ6IFwiTWFya2VkXCIsXG4gIFJFVklFVzogXCJSZXZpZXdcIlxufTtcbmV4cG9ydHMuQW5ub3RhdGlvblN0YXRlTW9kZWxUeXBlID0gQW5ub3RhdGlvblN0YXRlTW9kZWxUeXBlO1xuY29uc3QgQW5ub3RhdGlvbk1hcmtlZFN0YXRlID0ge1xuICBNQVJLRUQ6IFwiTWFya2VkXCIsXG4gIFVOTUFSS0VEOiBcIlVubWFya2VkXCJcbn07XG5leHBvcnRzLkFubm90YXRpb25NYXJrZWRTdGF0ZSA9IEFubm90YXRpb25NYXJrZWRTdGF0ZTtcbmNvbnN0IEFubm90YXRpb25SZXZpZXdTdGF0ZSA9IHtcbiAgQUNDRVBURUQ6IFwiQWNjZXB0ZWRcIixcbiAgUkVKRUNURUQ6IFwiUmVqZWN0ZWRcIixcbiAgQ0FOQ0VMTEVEOiBcIkNhbmNlbGxlZFwiLFxuICBDT01QTEVURUQ6IFwiQ29tcGxldGVkXCIsXG4gIE5PTkU6IFwiTm9uZVwiXG59O1xuZXhwb3J0cy5Bbm5vdGF0aW9uUmV2aWV3U3RhdGUgPSBBbm5vdGF0aW9uUmV2aWV3U3RhdGU7XG5jb25zdCBBbm5vdGF0aW9uUmVwbHlUeXBlID0ge1xuICBHUk9VUDogXCJHcm91cFwiLFxuICBSRVBMWTogXCJSXCJcbn07XG5leHBvcnRzLkFubm90YXRpb25SZXBseVR5cGUgPSBBbm5vdGF0aW9uUmVwbHlUeXBlO1xuY29uc3QgQW5ub3RhdGlvbkZsYWcgPSB7XG4gIElOVklTSUJMRTogMHgwMSxcbiAgSElEREVOOiAweDAyLFxuICBQUklOVDogMHgwNCxcbiAgTk9aT09NOiAweDA4LFxuICBOT1JPVEFURTogMHgxMCxcbiAgTk9WSUVXOiAweDIwLFxuICBSRUFET05MWTogMHg0MCxcbiAgTE9DS0VEOiAweDgwLFxuICBUT0dHTEVOT1ZJRVc6IDB4MTAwLFxuICBMT0NLRURDT05URU5UUzogMHgyMDBcbn07XG5leHBvcnRzLkFubm90YXRpb25GbGFnID0gQW5ub3RhdGlvbkZsYWc7XG5jb25zdCBBbm5vdGF0aW9uRmllbGRGbGFnID0ge1xuICBSRUFET05MWTogMHgwMDAwMDAxLFxuICBSRVFVSVJFRDogMHgwMDAwMDAyLFxuICBOT0VYUE9SVDogMHgwMDAwMDA0LFxuICBNVUxUSUxJTkU6IDB4MDAwMTAwMCxcbiAgUEFTU1dPUkQ6IDB4MDAwMjAwMCxcbiAgTk9UT0dHTEVUT09GRjogMHgwMDA0MDAwLFxuICBSQURJTzogMHgwMDA4MDAwLFxuICBQVVNIQlVUVE9OOiAweDAwMTAwMDAsXG4gIENPTUJPOiAweDAwMjAwMDAsXG4gIEVESVQ6IDB4MDA0MDAwMCxcbiAgU09SVDogMHgwMDgwMDAwLFxuICBGSUxFU0VMRUNUOiAweDAxMDAwMDAsXG4gIE1VTFRJU0VMRUNUOiAweDAyMDAwMDAsXG4gIERPTk9UU1BFTExDSEVDSzogMHgwNDAwMDAwLFxuICBET05PVFNDUk9MTDogMHgwODAwMDAwLFxuICBDT01COiAweDEwMDAwMDAsXG4gIFJJQ0hURVhUOiAweDIwMDAwMDAsXG4gIFJBRElPU0lOVU5JU09OOiAweDIwMDAwMDAsXG4gIENPTU1JVE9OU0VMQ0hBTkdFOiAweDQwMDAwMDBcbn07XG5leHBvcnRzLkFubm90YXRpb25GaWVsZEZsYWcgPSBBbm5vdGF0aW9uRmllbGRGbGFnO1xuY29uc3QgQW5ub3RhdGlvbkJvcmRlclN0eWxlVHlwZSA9IHtcbiAgU09MSUQ6IDEsXG4gIERBU0hFRDogMixcbiAgQkVWRUxFRDogMyxcbiAgSU5TRVQ6IDQsXG4gIFVOREVSTElORTogNVxufTtcbmV4cG9ydHMuQW5ub3RhdGlvbkJvcmRlclN0eWxlVHlwZSA9IEFubm90YXRpb25Cb3JkZXJTdHlsZVR5cGU7XG5jb25zdCBBbm5vdGF0aW9uQWN0aW9uRXZlbnRUeXBlID0ge1xuICBFOiBcIk1vdXNlIEVudGVyXCIsXG4gIFg6IFwiTW91c2UgRXhpdFwiLFxuICBEOiBcIk1vdXNlIERvd25cIixcbiAgVTogXCJNb3VzZSBVcFwiLFxuICBGbzogXCJGb2N1c1wiLFxuICBCbDogXCJCbHVyXCIsXG4gIFBPOiBcIlBhZ2VPcGVuXCIsXG4gIFBDOiBcIlBhZ2VDbG9zZVwiLFxuICBQVjogXCJQYWdlVmlzaWJsZVwiLFxuICBQSTogXCJQYWdlSW52aXNpYmxlXCIsXG4gIEs6IFwiS2V5c3Ryb2tlXCIsXG4gIEY6IFwiRm9ybWF0XCIsXG4gIFY6IFwiVmFsaWRhdGVcIixcbiAgQzogXCJDYWxjdWxhdGVcIlxufTtcbmV4cG9ydHMuQW5ub3RhdGlvbkFjdGlvbkV2ZW50VHlwZSA9IEFubm90YXRpb25BY3Rpb25FdmVudFR5cGU7XG5jb25zdCBEb2N1bWVudEFjdGlvbkV2ZW50VHlwZSA9IHtcbiAgV0M6IFwiV2lsbENsb3NlXCIsXG4gIFdTOiBcIldpbGxTYXZlXCIsXG4gIERTOiBcIkRpZFNhdmVcIixcbiAgV1A6IFwiV2lsbFByaW50XCIsXG4gIERQOiBcIkRpZFByaW50XCJcbn07XG5leHBvcnRzLkRvY3VtZW50QWN0aW9uRXZlbnRUeXBlID0gRG9jdW1lbnRBY3Rpb25FdmVudFR5cGU7XG5jb25zdCBQYWdlQWN0aW9uRXZlbnRUeXBlID0ge1xuICBPOiBcIlBhZ2VPcGVuXCIsXG4gIEM6IFwiUGFnZUNsb3NlXCJcbn07XG5leHBvcnRzLlBhZ2VBY3Rpb25FdmVudFR5cGUgPSBQYWdlQWN0aW9uRXZlbnRUeXBlO1xuY29uc3QgU3RyZWFtVHlwZSA9IHtcbiAgVU5LTk9XTjogXCJVTktOT1dOXCIsXG4gIEZMQVRFOiBcIkZMQVRFXCIsXG4gIExaVzogXCJMWldcIixcbiAgRENUOiBcIkRDVFwiLFxuICBKUFg6IFwiSlBYXCIsXG4gIEpCSUc6IFwiSkJJR1wiLFxuICBBODU6IFwiQTg1XCIsXG4gIEFIWDogXCJBSFhcIixcbiAgQ0NGOiBcIkNDRlwiLFxuICBSTFg6IFwiUkxYXCJcbn07XG5leHBvcnRzLlN0cmVhbVR5cGUgPSBTdHJlYW1UeXBlO1xuY29uc3QgRm9udFR5cGUgPSB7XG4gIFVOS05PV046IFwiVU5LTk9XTlwiLFxuICBUWVBFMTogXCJUWVBFMVwiLFxuICBUWVBFMVNUQU5EQVJEOiBcIlRZUEUxU1RBTkRBUkRcIixcbiAgVFlQRTFDOiBcIlRZUEUxQ1wiLFxuICBDSURGT05UVFlQRTA6IFwiQ0lERk9OVFRZUEUwXCIsXG4gIENJREZPTlRUWVBFMEM6IFwiQ0lERk9OVFRZUEUwQ1wiLFxuICBUUlVFVFlQRTogXCJUUlVFVFlQRVwiLFxuICBDSURGT05UVFlQRTI6IFwiQ0lERk9OVFRZUEUyXCIsXG4gIFRZUEUzOiBcIlRZUEUzXCIsXG4gIE9QRU5UWVBFOiBcIk9QRU5UWVBFXCIsXG4gIFRZUEUwOiBcIlRZUEUwXCIsXG4gIE1NVFlQRTE6IFwiTU1UWVBFMVwiXG59O1xuZXhwb3J0cy5Gb250VHlwZSA9IEZvbnRUeXBlO1xuY29uc3QgVmVyYm9zaXR5TGV2ZWwgPSB7XG4gIEVSUk9SUzogMCxcbiAgV0FSTklOR1M6IDEsXG4gIElORk9TOiA1XG59O1xuZXhwb3J0cy5WZXJib3NpdHlMZXZlbCA9IFZlcmJvc2l0eUxldmVsO1xuY29uc3QgQ01hcENvbXByZXNzaW9uVHlwZSA9IHtcbiAgTk9ORTogMCxcbiAgQklOQVJZOiAxLFxuICBTVFJFQU06IDJcbn07XG5leHBvcnRzLkNNYXBDb21wcmVzc2lvblR5cGUgPSBDTWFwQ29tcHJlc3Npb25UeXBlO1xuY29uc3QgT1BTID0ge1xuICBkZXBlbmRlbmN5OiAxLFxuICBzZXRMaW5lV2lkdGg6IDIsXG4gIHNldExpbmVDYXA6IDMsXG4gIHNldExpbmVKb2luOiA0LFxuICBzZXRNaXRlckxpbWl0OiA1LFxuICBzZXREYXNoOiA2LFxuICBzZXRSZW5kZXJpbmdJbnRlbnQ6IDcsXG4gIHNldEZsYXRuZXNzOiA4LFxuICBzZXRHU3RhdGU6IDksXG4gIHNhdmU6IDEwLFxuICByZXN0b3JlOiAxMSxcbiAgdHJhbnNmb3JtOiAxMixcbiAgbW92ZVRvOiAxMyxcbiAgbGluZVRvOiAxNCxcbiAgY3VydmVUbzogMTUsXG4gIGN1cnZlVG8yOiAxNixcbiAgY3VydmVUbzM6IDE3LFxuICBjbG9zZVBhdGg6IDE4LFxuICByZWN0YW5nbGU6IDE5LFxuICBzdHJva2U6IDIwLFxuICBjbG9zZVN0cm9rZTogMjEsXG4gIGZpbGw6IDIyLFxuICBlb0ZpbGw6IDIzLFxuICBmaWxsU3Ryb2tlOiAyNCxcbiAgZW9GaWxsU3Ryb2tlOiAyNSxcbiAgY2xvc2VGaWxsU3Ryb2tlOiAyNixcbiAgY2xvc2VFT0ZpbGxTdHJva2U6IDI3LFxuICBlbmRQYXRoOiAyOCxcbiAgY2xpcDogMjksXG4gIGVvQ2xpcDogMzAsXG4gIGJlZ2luVGV4dDogMzEsXG4gIGVuZFRleHQ6IDMyLFxuICBzZXRDaGFyU3BhY2luZzogMzMsXG4gIHNldFdvcmRTcGFjaW5nOiAzNCxcbiAgc2V0SFNjYWxlOiAzNSxcbiAgc2V0TGVhZGluZzogMzYsXG4gIHNldEZvbnQ6IDM3LFxuICBzZXRUZXh0UmVuZGVyaW5nTW9kZTogMzgsXG4gIHNldFRleHRSaXNlOiAzOSxcbiAgbW92ZVRleHQ6IDQwLFxuICBzZXRMZWFkaW5nTW92ZVRleHQ6IDQxLFxuICBzZXRUZXh0TWF0cml4OiA0MixcbiAgbmV4dExpbmU6IDQzLFxuICBzaG93VGV4dDogNDQsXG4gIHNob3dTcGFjZWRUZXh0OiA0NSxcbiAgbmV4dExpbmVTaG93VGV4dDogNDYsXG4gIG5leHRMaW5lU2V0U3BhY2luZ1Nob3dUZXh0OiA0NyxcbiAgc2V0Q2hhcldpZHRoOiA0OCxcbiAgc2V0Q2hhcldpZHRoQW5kQm91bmRzOiA0OSxcbiAgc2V0U3Ryb2tlQ29sb3JTcGFjZTogNTAsXG4gIHNldEZpbGxDb2xvclNwYWNlOiA1MSxcbiAgc2V0U3Ryb2tlQ29sb3I6IDUyLFxuICBzZXRTdHJva2VDb2xvck46IDUzLFxuICBzZXRGaWxsQ29sb3I6IDU0LFxuICBzZXRGaWxsQ29sb3JOOiA1NSxcbiAgc2V0U3Ryb2tlR3JheTogNTYsXG4gIHNldEZpbGxHcmF5OiA1NyxcbiAgc2V0U3Ryb2tlUkdCQ29sb3I6IDU4LFxuICBzZXRGaWxsUkdCQ29sb3I6IDU5LFxuICBzZXRTdHJva2VDTVlLQ29sb3I6IDYwLFxuICBzZXRGaWxsQ01ZS0NvbG9yOiA2MSxcbiAgc2hhZGluZ0ZpbGw6IDYyLFxuICBiZWdpbklubGluZUltYWdlOiA2MyxcbiAgYmVnaW5JbWFnZURhdGE6IDY0LFxuICBlbmRJbmxpbmVJbWFnZTogNjUsXG4gIHBhaW50WE9iamVjdDogNjYsXG4gIG1hcmtQb2ludDogNjcsXG4gIG1hcmtQb2ludFByb3BzOiA2OCxcbiAgYmVnaW5NYXJrZWRDb250ZW50OiA2OSxcbiAgYmVnaW5NYXJrZWRDb250ZW50UHJvcHM6IDcwLFxuICBlbmRNYXJrZWRDb250ZW50OiA3MSxcbiAgYmVnaW5Db21wYXQ6IDcyLFxuICBlbmRDb21wYXQ6IDczLFxuICBwYWludEZvcm1YT2JqZWN0QmVnaW46IDc0LFxuICBwYWludEZvcm1YT2JqZWN0RW5kOiA3NSxcbiAgYmVnaW5Hcm91cDogNzYsXG4gIGVuZEdyb3VwOiA3NyxcbiAgYmVnaW5Bbm5vdGF0aW9uczogNzgsXG4gIGVuZEFubm90YXRpb25zOiA3OSxcbiAgYmVnaW5Bbm5vdGF0aW9uOiA4MCxcbiAgZW5kQW5ub3RhdGlvbjogODEsXG4gIHBhaW50SnBlZ1hPYmplY3Q6IDgyLFxuICBwYWludEltYWdlTWFza1hPYmplY3Q6IDgzLFxuICBwYWludEltYWdlTWFza1hPYmplY3RHcm91cDogODQsXG4gIHBhaW50SW1hZ2VYT2JqZWN0OiA4NSxcbiAgcGFpbnRJbmxpbmVJbWFnZVhPYmplY3Q6IDg2LFxuICBwYWludElubGluZUltYWdlWE9iamVjdEdyb3VwOiA4NyxcbiAgcGFpbnRJbWFnZVhPYmplY3RSZXBlYXQ6IDg4LFxuICBwYWludEltYWdlTWFza1hPYmplY3RSZXBlYXQ6IDg5LFxuICBwYWludFNvbGlkQ29sb3JJbWFnZU1hc2s6IDkwLFxuICBjb25zdHJ1Y3RQYXRoOiA5MVxufTtcbmV4cG9ydHMuT1BTID0gT1BTO1xuY29uc3QgVU5TVVBQT1JURURfRkVBVFVSRVMgPSB7XG4gIHVua25vd246IFwidW5rbm93blwiLFxuICBmb3JtczogXCJmb3Jtc1wiLFxuICBqYXZhU2NyaXB0OiBcImphdmFTY3JpcHRcIixcbiAgc2lnbmF0dXJlczogXCJzaWduYXR1cmVzXCIsXG4gIHNtYXNrOiBcInNtYXNrXCIsXG4gIHNoYWRpbmdQYXR0ZXJuOiBcInNoYWRpbmdQYXR0ZXJuXCIsXG4gIGZvbnQ6IFwiZm9udFwiLFxuICBlcnJvclRpbGluZ1BhdHRlcm46IFwiZXJyb3JUaWxpbmdQYXR0ZXJuXCIsXG4gIGVycm9yRXh0R1N0YXRlOiBcImVycm9yRXh0R1N0YXRlXCIsXG4gIGVycm9yWE9iamVjdDogXCJlcnJvclhPYmplY3RcIixcbiAgZXJyb3JGb250TG9hZFR5cGUzOiBcImVycm9yRm9udExvYWRUeXBlM1wiLFxuICBlcnJvckZvbnRTdGF0ZTogXCJlcnJvckZvbnRTdGF0ZVwiLFxuICBlcnJvckZvbnRNaXNzaW5nOiBcImVycm9yRm9udE1pc3NpbmdcIixcbiAgZXJyb3JGb250VHJhbnNsYXRlOiBcImVycm9yRm9udFRyYW5zbGF0ZVwiLFxuICBlcnJvckNvbG9yU3BhY2U6IFwiZXJyb3JDb2xvclNwYWNlXCIsXG4gIGVycm9yT3BlcmF0b3JMaXN0OiBcImVycm9yT3BlcmF0b3JMaXN0XCIsXG4gIGVycm9yRm9udFRvVW5pY29kZTogXCJlcnJvckZvbnRUb1VuaWNvZGVcIixcbiAgZXJyb3JGb250TG9hZE5hdGl2ZTogXCJlcnJvckZvbnRMb2FkTmF0aXZlXCIsXG4gIGVycm9yRm9udEJ1aWxkUGF0aDogXCJlcnJvckZvbnRCdWlsZFBhdGhcIixcbiAgZXJyb3JGb250R2V0UGF0aDogXCJlcnJvckZvbnRHZXRQYXRoXCIsXG4gIGVycm9yTWFya2VkQ29udGVudDogXCJlcnJvck1hcmtlZENvbnRlbnRcIixcbiAgZXJyb3JDb250ZW50U3ViU3RyZWFtOiBcImVycm9yQ29udGVudFN1YlN0cmVhbVwiXG59O1xuZXhwb3J0cy5VTlNVUFBPUlRFRF9GRUFUVVJFUyA9IFVOU1VQUE9SVEVEX0ZFQVRVUkVTO1xuY29uc3QgUGFzc3dvcmRSZXNwb25zZXMgPSB7XG4gIE5FRURfUEFTU1dPUkQ6IDEsXG4gIElOQ09SUkVDVF9QQVNTV09SRDogMlxufTtcbmV4cG9ydHMuUGFzc3dvcmRSZXNwb25zZXMgPSBQYXNzd29yZFJlc3BvbnNlcztcbmxldCB2ZXJib3NpdHkgPSBWZXJib3NpdHlMZXZlbC5XQVJOSU5HUztcblxuZnVuY3Rpb24gc2V0VmVyYm9zaXR5TGV2ZWwobGV2ZWwpIHtcbiAgaWYgKE51bWJlci5pc0ludGVnZXIobGV2ZWwpKSB7XG4gICAgdmVyYm9zaXR5ID0gbGV2ZWw7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0VmVyYm9zaXR5TGV2ZWwoKSB7XG4gIHJldHVybiB2ZXJib3NpdHk7XG59XG5cbmZ1bmN0aW9uIGluZm8obXNnKSB7XG4gIGlmICh2ZXJib3NpdHkgPj0gVmVyYm9zaXR5TGV2ZWwuSU5GT1MpIHtcbiAgICBjb25zb2xlLmxvZyhgSW5mbzogJHttc2d9YCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gd2Fybihtc2cpIHtcbiAgaWYgKHZlcmJvc2l0eSA+PSBWZXJib3NpdHlMZXZlbC5XQVJOSU5HUykge1xuICAgIGNvbnNvbGUubG9nKGBXYXJuaW5nOiAke21zZ31gKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB1bnJlYWNoYWJsZShtc2cpIHtcbiAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG59XG5cbmZ1bmN0aW9uIGFzc2VydChjb25kLCBtc2cpIHtcbiAgaWYgKCFjb25kKSB7XG4gICAgdW5yZWFjaGFibGUobXNnKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfaXNWYWxpZFByb3RvY29sKHVybCkge1xuICBpZiAoIXVybCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHN3aXRjaCAodXJsLnByb3RvY29sKSB7XG4gICAgY2FzZSBcImh0dHA6XCI6XG4gICAgY2FzZSBcImh0dHBzOlwiOlxuICAgIGNhc2UgXCJmdHA6XCI6XG4gICAgY2FzZSBcIm1haWx0bzpcIjpcbiAgICBjYXNlIFwidGVsOlwiOlxuICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVZhbGlkQWJzb2x1dGVVcmwodXJsLCBiYXNlVXJsID0gbnVsbCwgb3B0aW9ucyA9IG51bGwpIHtcbiAgaWYgKCF1cmwpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHRyeSB7XG4gICAgaWYgKG9wdGlvbnMgJiYgdHlwZW9mIHVybCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgaWYgKG9wdGlvbnMuYWRkRGVmYXVsdFByb3RvY29sICYmIHVybC5zdGFydHNXaXRoKFwid3d3LlwiKSkge1xuICAgICAgICBjb25zdCBkb3RzID0gdXJsLm1hdGNoKC9cXC4vZyk7XG5cbiAgICAgICAgaWYgKGRvdHMgJiYgZG90cy5sZW5ndGggPj0gMikge1xuICAgICAgICAgIHVybCA9IGBodHRwOi8vJHt1cmx9YDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9ucy50cnlDb252ZXJ0RW5jb2RpbmcpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB1cmwgPSBzdHJpbmdUb1VURjhTdHJpbmcodXJsKTtcbiAgICAgICAgfSBjYXRjaCAoZXgpIHt9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgYWJzb2x1dGVVcmwgPSBiYXNlVXJsID8gbmV3IFVSTCh1cmwsIGJhc2VVcmwpIDogbmV3IFVSTCh1cmwpO1xuXG4gICAgaWYgKF9pc1ZhbGlkUHJvdG9jb2woYWJzb2x1dGVVcmwpKSB7XG4gICAgICByZXR1cm4gYWJzb2x1dGVVcmw7XG4gICAgfVxuICB9IGNhdGNoIChleCkge31cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gc2hhZG93KG9iaiwgcHJvcCwgdmFsdWUpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwgcHJvcCwge1xuICAgIHZhbHVlLFxuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIHdyaXRhYmxlOiBmYWxzZVxuICB9KTtcbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5jb25zdCBCYXNlRXhjZXB0aW9uID0gZnVuY3Rpb24gQmFzZUV4Y2VwdGlvbkNsb3N1cmUoKSB7XG4gIGZ1bmN0aW9uIEJhc2VFeGNlcHRpb24obWVzc2FnZSwgbmFtZSkge1xuICAgIGlmICh0aGlzLmNvbnN0cnVjdG9yID09PSBCYXNlRXhjZXB0aW9uKSB7XG4gICAgICB1bnJlYWNoYWJsZShcIkNhbm5vdCBpbml0aWFsaXplIEJhc2VFeGNlcHRpb24uXCIpO1xuICAgIH1cblxuICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgfVxuXG4gIEJhc2VFeGNlcHRpb24ucHJvdG90eXBlID0gbmV3IEVycm9yKCk7XG4gIEJhc2VFeGNlcHRpb24uY29uc3RydWN0b3IgPSBCYXNlRXhjZXB0aW9uO1xuICByZXR1cm4gQmFzZUV4Y2VwdGlvbjtcbn0oKTtcblxuZXhwb3J0cy5CYXNlRXhjZXB0aW9uID0gQmFzZUV4Y2VwdGlvbjtcblxuY2xhc3MgUGFzc3dvcmRFeGNlcHRpb24gZXh0ZW5kcyBCYXNlRXhjZXB0aW9uIHtcbiAgY29uc3RydWN0b3IobXNnLCBjb2RlKSB7XG4gICAgc3VwZXIobXNnLCBcIlBhc3N3b3JkRXhjZXB0aW9uXCIpO1xuICAgIHRoaXMuY29kZSA9IGNvZGU7XG4gIH1cblxufVxuXG5leHBvcnRzLlBhc3N3b3JkRXhjZXB0aW9uID0gUGFzc3dvcmRFeGNlcHRpb247XG5cbmNsYXNzIFVua25vd25FcnJvckV4Y2VwdGlvbiBleHRlbmRzIEJhc2VFeGNlcHRpb24ge1xuICBjb25zdHJ1Y3Rvcihtc2csIGRldGFpbHMpIHtcbiAgICBzdXBlcihtc2csIFwiVW5rbm93bkVycm9yRXhjZXB0aW9uXCIpO1xuICAgIHRoaXMuZGV0YWlscyA9IGRldGFpbHM7XG4gIH1cblxufVxuXG5leHBvcnRzLlVua25vd25FcnJvckV4Y2VwdGlvbiA9IFVua25vd25FcnJvckV4Y2VwdGlvbjtcblxuY2xhc3MgSW52YWxpZFBERkV4Y2VwdGlvbiBleHRlbmRzIEJhc2VFeGNlcHRpb24ge1xuICBjb25zdHJ1Y3Rvcihtc2cpIHtcbiAgICBzdXBlcihtc2csIFwiSW52YWxpZFBERkV4Y2VwdGlvblwiKTtcbiAgfVxuXG59XG5cbmV4cG9ydHMuSW52YWxpZFBERkV4Y2VwdGlvbiA9IEludmFsaWRQREZFeGNlcHRpb247XG5cbmNsYXNzIE1pc3NpbmdQREZFeGNlcHRpb24gZXh0ZW5kcyBCYXNlRXhjZXB0aW9uIHtcbiAgY29uc3RydWN0b3IobXNnKSB7XG4gICAgc3VwZXIobXNnLCBcIk1pc3NpbmdQREZFeGNlcHRpb25cIik7XG4gIH1cblxufVxuXG5leHBvcnRzLk1pc3NpbmdQREZFeGNlcHRpb24gPSBNaXNzaW5nUERGRXhjZXB0aW9uO1xuXG5jbGFzcyBVbmV4cGVjdGVkUmVzcG9uc2VFeGNlcHRpb24gZXh0ZW5kcyBCYXNlRXhjZXB0aW9uIHtcbiAgY29uc3RydWN0b3IobXNnLCBzdGF0dXMpIHtcbiAgICBzdXBlcihtc2csIFwiVW5leHBlY3RlZFJlc3BvbnNlRXhjZXB0aW9uXCIpO1xuICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzO1xuICB9XG5cbn1cblxuZXhwb3J0cy5VbmV4cGVjdGVkUmVzcG9uc2VFeGNlcHRpb24gPSBVbmV4cGVjdGVkUmVzcG9uc2VFeGNlcHRpb247XG5cbmNsYXNzIEZvcm1hdEVycm9yIGV4dGVuZHMgQmFzZUV4Y2VwdGlvbiB7XG4gIGNvbnN0cnVjdG9yKG1zZykge1xuICAgIHN1cGVyKG1zZywgXCJGb3JtYXRFcnJvclwiKTtcbiAgfVxuXG59XG5cbmV4cG9ydHMuRm9ybWF0RXJyb3IgPSBGb3JtYXRFcnJvcjtcblxuY2xhc3MgQWJvcnRFeGNlcHRpb24gZXh0ZW5kcyBCYXNlRXhjZXB0aW9uIHtcbiAgY29uc3RydWN0b3IobXNnKSB7XG4gICAgc3VwZXIobXNnLCBcIkFib3J0RXhjZXB0aW9uXCIpO1xuICB9XG5cbn1cblxuZXhwb3J0cy5BYm9ydEV4Y2VwdGlvbiA9IEFib3J0RXhjZXB0aW9uO1xuXG5mdW5jdGlvbiBieXRlc1RvU3RyaW5nKGJ5dGVzKSB7XG4gIGlmICh0eXBlb2YgYnl0ZXMgIT09IFwib2JqZWN0XCIgfHwgYnl0ZXMgPT09IG51bGwgfHwgYnl0ZXMubGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICB1bnJlYWNoYWJsZShcIkludmFsaWQgYXJndW1lbnQgZm9yIGJ5dGVzVG9TdHJpbmdcIik7XG4gIH1cblxuICBjb25zdCBsZW5ndGggPSBieXRlcy5sZW5ndGg7XG4gIGNvbnN0IE1BWF9BUkdVTUVOVF9DT1VOVCA9IDgxOTI7XG5cbiAgaWYgKGxlbmd0aCA8IE1BWF9BUkdVTUVOVF9DT1VOVCkge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGJ5dGVzKTtcbiAgfVxuXG4gIGNvbnN0IHN0ckJ1ZiA9IFtdO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IE1BWF9BUkdVTUVOVF9DT1VOVCkge1xuICAgIGNvbnN0IGNodW5rRW5kID0gTWF0aC5taW4oaSArIE1BWF9BUkdVTUVOVF9DT1VOVCwgbGVuZ3RoKTtcbiAgICBjb25zdCBjaHVuayA9IGJ5dGVzLnN1YmFycmF5KGksIGNodW5rRW5kKTtcbiAgICBzdHJCdWYucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGNodW5rKSk7XG4gIH1cblxuICByZXR1cm4gc3RyQnVmLmpvaW4oXCJcIik7XG59XG5cbmZ1bmN0aW9uIHN0cmluZ1RvQnl0ZXMoc3RyKSB7XG4gIGlmICh0eXBlb2Ygc3RyICE9PSBcInN0cmluZ1wiKSB7XG4gICAgdW5yZWFjaGFibGUoXCJJbnZhbGlkIGFyZ3VtZW50IGZvciBzdHJpbmdUb0J5dGVzXCIpO1xuICB9XG5cbiAgY29uc3QgbGVuZ3RoID0gc3RyLmxlbmd0aDtcbiAgY29uc3QgYnl0ZXMgPSBuZXcgVWludDhBcnJheShsZW5ndGgpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBieXRlc1tpXSA9IHN0ci5jaGFyQ29kZUF0KGkpICYgMHhmZjtcbiAgfVxuXG4gIHJldHVybiBieXRlcztcbn1cblxuZnVuY3Rpb24gYXJyYXlCeXRlTGVuZ3RoKGFycikge1xuICBpZiAoYXJyLmxlbmd0aCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGFyci5sZW5ndGg7XG4gIH1cblxuICBpZiAoYXJyLmJ5dGVMZW5ndGggIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBhcnIuYnl0ZUxlbmd0aDtcbiAgfVxuXG4gIHVucmVhY2hhYmxlKFwiSW52YWxpZCBhcmd1bWVudCBmb3IgYXJyYXlCeXRlTGVuZ3RoXCIpO1xufVxuXG5mdW5jdGlvbiBhcnJheXNUb0J5dGVzKGFycikge1xuICBjb25zdCBsZW5ndGggPSBhcnIubGVuZ3RoO1xuXG4gIGlmIChsZW5ndGggPT09IDEgJiYgYXJyWzBdIGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuICAgIHJldHVybiBhcnJbMF07XG4gIH1cblxuICBsZXQgcmVzdWx0TGVuZ3RoID0gMDtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgcmVzdWx0TGVuZ3RoICs9IGFycmF5Qnl0ZUxlbmd0aChhcnJbaV0pO1xuICB9XG5cbiAgbGV0IHBvcyA9IDA7XG4gIGNvbnN0IGRhdGEgPSBuZXcgVWludDhBcnJheShyZXN1bHRMZW5ndGgpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBsZXQgaXRlbSA9IGFycltpXTtcblxuICAgIGlmICghKGl0ZW0gaW5zdGFuY2VvZiBVaW50OEFycmF5KSkge1xuICAgICAgaWYgKHR5cGVvZiBpdGVtID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIGl0ZW0gPSBzdHJpbmdUb0J5dGVzKGl0ZW0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaXRlbSA9IG5ldyBVaW50OEFycmF5KGl0ZW0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGl0ZW1MZW5ndGggPSBpdGVtLmJ5dGVMZW5ndGg7XG4gICAgZGF0YS5zZXQoaXRlbSwgcG9zKTtcbiAgICBwb3MgKz0gaXRlbUxlbmd0aDtcbiAgfVxuXG4gIHJldHVybiBkYXRhO1xufVxuXG5mdW5jdGlvbiBzdHJpbmczMih2YWx1ZSkge1xuICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSh2YWx1ZSA+PiAyNCAmIDB4ZmYsIHZhbHVlID4+IDE2ICYgMHhmZiwgdmFsdWUgPj4gOCAmIDB4ZmYsIHZhbHVlICYgMHhmZik7XG59XG5cbmZ1bmN0aW9uIG9iamVjdFNpemUob2JqKSB7XG4gIHJldHVybiBPYmplY3Qua2V5cyhvYmopLmxlbmd0aDtcbn1cblxuZnVuY3Rpb24gb2JqZWN0RnJvbU1hcChtYXApIHtcbiAgY29uc3Qgb2JqID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBtYXApIHtcbiAgICBvYmpba2V5XSA9IHZhbHVlO1xuICB9XG5cbiAgcmV0dXJuIG9iajtcbn1cblxuZnVuY3Rpb24gaXNMaXR0bGVFbmRpYW4oKSB7XG4gIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheSg0KTtcbiAgYnVmZmVyOFswXSA9IDE7XG4gIGNvbnN0IHZpZXczMiA9IG5ldyBVaW50MzJBcnJheShidWZmZXI4LmJ1ZmZlciwgMCwgMSk7XG4gIHJldHVybiB2aWV3MzJbMF0gPT09IDE7XG59XG5cbmZ1bmN0aW9uIGlzRXZhbFN1cHBvcnRlZCgpIHtcbiAgdHJ5IHtcbiAgICBuZXcgRnVuY3Rpb24oXCJcIik7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuY2xhc3MgRmVhdHVyZVRlc3Qge1xuICBzdGF0aWMgZ2V0IGlzTGl0dGxlRW5kaWFuKCkge1xuICAgIHJldHVybiBzaGFkb3codGhpcywgXCJpc0xpdHRsZUVuZGlhblwiLCBpc0xpdHRsZUVuZGlhbigpKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgaXNFdmFsU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiBzaGFkb3codGhpcywgXCJpc0V2YWxTdXBwb3J0ZWRcIiwgaXNFdmFsU3VwcG9ydGVkKCkpO1xuICB9XG5cbiAgc3RhdGljIGdldCBpc09mZnNjcmVlbkNhbnZhc1N1cHBvcnRlZCgpIHtcbiAgICByZXR1cm4gc2hhZG93KHRoaXMsIFwiaXNPZmZzY3JlZW5DYW52YXNTdXBwb3J0ZWRcIiwgdHlwZW9mIE9mZnNjcmVlbkNhbnZhcyAhPT0gXCJ1bmRlZmluZWRcIik7XG4gIH1cblxufVxuXG5leHBvcnRzLkZlYXR1cmVUZXN0ID0gRmVhdHVyZVRlc3Q7XG5jb25zdCBoZXhOdW1iZXJzID0gWy4uLkFycmF5KDI1Nikua2V5cygpXS5tYXAobiA9PiBuLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCBcIjBcIikpO1xuXG5jbGFzcyBVdGlsIHtcbiAgc3RhdGljIG1ha2VIZXhDb2xvcihyLCBnLCBiKSB7XG4gICAgcmV0dXJuIGAjJHtoZXhOdW1iZXJzW3JdfSR7aGV4TnVtYmVyc1tnXX0ke2hleE51bWJlcnNbYl19YDtcbiAgfVxuXG4gIHN0YXRpYyBzY2FsZU1pbk1heCh0cmFuc2Zvcm0sIG1pbk1heCkge1xuICAgIGxldCB0ZW1wO1xuXG4gICAgaWYgKHRyYW5zZm9ybVswXSkge1xuICAgICAgaWYgKHRyYW5zZm9ybVswXSA8IDApIHtcbiAgICAgICAgdGVtcCA9IG1pbk1heFswXTtcbiAgICAgICAgbWluTWF4WzBdID0gbWluTWF4WzFdO1xuICAgICAgICBtaW5NYXhbMV0gPSB0ZW1wO1xuICAgICAgfVxuXG4gICAgICBtaW5NYXhbMF0gKj0gdHJhbnNmb3JtWzBdO1xuICAgICAgbWluTWF4WzFdICo9IHRyYW5zZm9ybVswXTtcblxuICAgICAgaWYgKHRyYW5zZm9ybVszXSA8IDApIHtcbiAgICAgICAgdGVtcCA9IG1pbk1heFsyXTtcbiAgICAgICAgbWluTWF4WzJdID0gbWluTWF4WzNdO1xuICAgICAgICBtaW5NYXhbM10gPSB0ZW1wO1xuICAgICAgfVxuXG4gICAgICBtaW5NYXhbMl0gKj0gdHJhbnNmb3JtWzNdO1xuICAgICAgbWluTWF4WzNdICo9IHRyYW5zZm9ybVszXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGVtcCA9IG1pbk1heFswXTtcbiAgICAgIG1pbk1heFswXSA9IG1pbk1heFsyXTtcbiAgICAgIG1pbk1heFsyXSA9IHRlbXA7XG4gICAgICB0ZW1wID0gbWluTWF4WzFdO1xuICAgICAgbWluTWF4WzFdID0gbWluTWF4WzNdO1xuICAgICAgbWluTWF4WzNdID0gdGVtcDtcblxuICAgICAgaWYgKHRyYW5zZm9ybVsxXSA8IDApIHtcbiAgICAgICAgdGVtcCA9IG1pbk1heFsyXTtcbiAgICAgICAgbWluTWF4WzJdID0gbWluTWF4WzNdO1xuICAgICAgICBtaW5NYXhbM10gPSB0ZW1wO1xuICAgICAgfVxuXG4gICAgICBtaW5NYXhbMl0gKj0gdHJhbnNmb3JtWzFdO1xuICAgICAgbWluTWF4WzNdICo9IHRyYW5zZm9ybVsxXTtcblxuICAgICAgaWYgKHRyYW5zZm9ybVsyXSA8IDApIHtcbiAgICAgICAgdGVtcCA9IG1pbk1heFswXTtcbiAgICAgICAgbWluTWF4WzBdID0gbWluTWF4WzFdO1xuICAgICAgICBtaW5NYXhbMV0gPSB0ZW1wO1xuICAgICAgfVxuXG4gICAgICBtaW5NYXhbMF0gKj0gdHJhbnNmb3JtWzJdO1xuICAgICAgbWluTWF4WzFdICo9IHRyYW5zZm9ybVsyXTtcbiAgICB9XG5cbiAgICBtaW5NYXhbMF0gKz0gdHJhbnNmb3JtWzRdO1xuICAgIG1pbk1heFsxXSArPSB0cmFuc2Zvcm1bNF07XG4gICAgbWluTWF4WzJdICs9IHRyYW5zZm9ybVs1XTtcbiAgICBtaW5NYXhbM10gKz0gdHJhbnNmb3JtWzVdO1xuICB9XG5cbiAgc3RhdGljIHRyYW5zZm9ybShtMSwgbTIpIHtcbiAgICByZXR1cm4gW20xWzBdICogbTJbMF0gKyBtMVsyXSAqIG0yWzFdLCBtMVsxXSAqIG0yWzBdICsgbTFbM10gKiBtMlsxXSwgbTFbMF0gKiBtMlsyXSArIG0xWzJdICogbTJbM10sIG0xWzFdICogbTJbMl0gKyBtMVszXSAqIG0yWzNdLCBtMVswXSAqIG0yWzRdICsgbTFbMl0gKiBtMls1XSArIG0xWzRdLCBtMVsxXSAqIG0yWzRdICsgbTFbM10gKiBtMls1XSArIG0xWzVdXTtcbiAgfVxuXG4gIHN0YXRpYyBhcHBseVRyYW5zZm9ybShwLCBtKSB7XG4gICAgY29uc3QgeHQgPSBwWzBdICogbVswXSArIHBbMV0gKiBtWzJdICsgbVs0XTtcbiAgICBjb25zdCB5dCA9IHBbMF0gKiBtWzFdICsgcFsxXSAqIG1bM10gKyBtWzVdO1xuICAgIHJldHVybiBbeHQsIHl0XTtcbiAgfVxuXG4gIHN0YXRpYyBhcHBseUludmVyc2VUcmFuc2Zvcm0ocCwgbSkge1xuICAgIGNvbnN0IGQgPSBtWzBdICogbVszXSAtIG1bMV0gKiBtWzJdO1xuICAgIGNvbnN0IHh0ID0gKHBbMF0gKiBtWzNdIC0gcFsxXSAqIG1bMl0gKyBtWzJdICogbVs1XSAtIG1bNF0gKiBtWzNdKSAvIGQ7XG4gICAgY29uc3QgeXQgPSAoLXBbMF0gKiBtWzFdICsgcFsxXSAqIG1bMF0gKyBtWzRdICogbVsxXSAtIG1bNV0gKiBtWzBdKSAvIGQ7XG4gICAgcmV0dXJuIFt4dCwgeXRdO1xuICB9XG5cbiAgc3RhdGljIGdldEF4aWFsQWxpZ25lZEJvdW5kaW5nQm94KHIsIG0pIHtcbiAgICBjb25zdCBwMSA9IFV0aWwuYXBwbHlUcmFuc2Zvcm0ociwgbSk7XG4gICAgY29uc3QgcDIgPSBVdGlsLmFwcGx5VHJhbnNmb3JtKHIuc2xpY2UoMiwgNCksIG0pO1xuICAgIGNvbnN0IHAzID0gVXRpbC5hcHBseVRyYW5zZm9ybShbclswXSwgclszXV0sIG0pO1xuICAgIGNvbnN0IHA0ID0gVXRpbC5hcHBseVRyYW5zZm9ybShbclsyXSwgclsxXV0sIG0pO1xuICAgIHJldHVybiBbTWF0aC5taW4ocDFbMF0sIHAyWzBdLCBwM1swXSwgcDRbMF0pLCBNYXRoLm1pbihwMVsxXSwgcDJbMV0sIHAzWzFdLCBwNFsxXSksIE1hdGgubWF4KHAxWzBdLCBwMlswXSwgcDNbMF0sIHA0WzBdKSwgTWF0aC5tYXgocDFbMV0sIHAyWzFdLCBwM1sxXSwgcDRbMV0pXTtcbiAgfVxuXG4gIHN0YXRpYyBpbnZlcnNlVHJhbnNmb3JtKG0pIHtcbiAgICBjb25zdCBkID0gbVswXSAqIG1bM10gLSBtWzFdICogbVsyXTtcbiAgICByZXR1cm4gW21bM10gLyBkLCAtbVsxXSAvIGQsIC1tWzJdIC8gZCwgbVswXSAvIGQsIChtWzJdICogbVs1XSAtIG1bNF0gKiBtWzNdKSAvIGQsIChtWzRdICogbVsxXSAtIG1bNV0gKiBtWzBdKSAvIGRdO1xuICB9XG5cbiAgc3RhdGljIGFwcGx5M2RUcmFuc2Zvcm0obSwgdikge1xuICAgIHJldHVybiBbbVswXSAqIHZbMF0gKyBtWzFdICogdlsxXSArIG1bMl0gKiB2WzJdLCBtWzNdICogdlswXSArIG1bNF0gKiB2WzFdICsgbVs1XSAqIHZbMl0sIG1bNl0gKiB2WzBdICsgbVs3XSAqIHZbMV0gKyBtWzhdICogdlsyXV07XG4gIH1cblxuICBzdGF0aWMgc2luZ3VsYXJWYWx1ZURlY29tcG9zZTJkU2NhbGUobSkge1xuICAgIGNvbnN0IHRyYW5zcG9zZSA9IFttWzBdLCBtWzJdLCBtWzFdLCBtWzNdXTtcbiAgICBjb25zdCBhID0gbVswXSAqIHRyYW5zcG9zZVswXSArIG1bMV0gKiB0cmFuc3Bvc2VbMl07XG4gICAgY29uc3QgYiA9IG1bMF0gKiB0cmFuc3Bvc2VbMV0gKyBtWzFdICogdHJhbnNwb3NlWzNdO1xuICAgIGNvbnN0IGMgPSBtWzJdICogdHJhbnNwb3NlWzBdICsgbVszXSAqIHRyYW5zcG9zZVsyXTtcbiAgICBjb25zdCBkID0gbVsyXSAqIHRyYW5zcG9zZVsxXSArIG1bM10gKiB0cmFuc3Bvc2VbM107XG4gICAgY29uc3QgZmlyc3QgPSAoYSArIGQpIC8gMjtcbiAgICBjb25zdCBzZWNvbmQgPSBNYXRoLnNxcnQoKGEgKyBkKSAqKiAyIC0gNCAqIChhICogZCAtIGMgKiBiKSkgLyAyO1xuICAgIGNvbnN0IHN4ID0gZmlyc3QgKyBzZWNvbmQgfHwgMTtcbiAgICBjb25zdCBzeSA9IGZpcnN0IC0gc2Vjb25kIHx8IDE7XG4gICAgcmV0dXJuIFtNYXRoLnNxcnQoc3gpLCBNYXRoLnNxcnQoc3kpXTtcbiAgfVxuXG4gIHN0YXRpYyBub3JtYWxpemVSZWN0KHJlY3QpIHtcbiAgICBjb25zdCByID0gcmVjdC5zbGljZSgwKTtcblxuICAgIGlmIChyZWN0WzBdID4gcmVjdFsyXSkge1xuICAgICAgclswXSA9IHJlY3RbMl07XG4gICAgICByWzJdID0gcmVjdFswXTtcbiAgICB9XG5cbiAgICBpZiAocmVjdFsxXSA+IHJlY3RbM10pIHtcbiAgICAgIHJbMV0gPSByZWN0WzNdO1xuICAgICAgclszXSA9IHJlY3RbMV07XG4gICAgfVxuXG4gICAgcmV0dXJuIHI7XG4gIH1cblxuICBzdGF0aWMgaW50ZXJzZWN0KHJlY3QxLCByZWN0Mikge1xuICAgIGNvbnN0IHhMb3cgPSBNYXRoLm1heChNYXRoLm1pbihyZWN0MVswXSwgcmVjdDFbMl0pLCBNYXRoLm1pbihyZWN0MlswXSwgcmVjdDJbMl0pKTtcbiAgICBjb25zdCB4SGlnaCA9IE1hdGgubWluKE1hdGgubWF4KHJlY3QxWzBdLCByZWN0MVsyXSksIE1hdGgubWF4KHJlY3QyWzBdLCByZWN0MlsyXSkpO1xuXG4gICAgaWYgKHhMb3cgPiB4SGlnaCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgeUxvdyA9IE1hdGgubWF4KE1hdGgubWluKHJlY3QxWzFdLCByZWN0MVszXSksIE1hdGgubWluKHJlY3QyWzFdLCByZWN0MlszXSkpO1xuICAgIGNvbnN0IHlIaWdoID0gTWF0aC5taW4oTWF0aC5tYXgocmVjdDFbMV0sIHJlY3QxWzNdKSwgTWF0aC5tYXgocmVjdDJbMV0sIHJlY3QyWzNdKSk7XG5cbiAgICBpZiAoeUxvdyA+IHlIaWdoKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gW3hMb3csIHlMb3csIHhIaWdoLCB5SGlnaF07XG4gIH1cblxuICBzdGF0aWMgYmV6aWVyQm91bmRpbmdCb3goeDAsIHkwLCB4MSwgeTEsIHgyLCB5MiwgeDMsIHkzKSB7XG4gICAgY29uc3QgdHZhbHVlcyA9IFtdLFxuICAgICAgICAgIGJvdW5kcyA9IFtbXSwgW11dO1xuICAgIGxldCBhLCBiLCBjLCB0LCB0MSwgdDIsIGIyYWMsIHNxcnRiMmFjO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCAyOyArK2kpIHtcbiAgICAgIGlmIChpID09PSAwKSB7XG4gICAgICAgIGIgPSA2ICogeDAgLSAxMiAqIHgxICsgNiAqIHgyO1xuICAgICAgICBhID0gLTMgKiB4MCArIDkgKiB4MSAtIDkgKiB4MiArIDMgKiB4MztcbiAgICAgICAgYyA9IDMgKiB4MSAtIDMgKiB4MDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGIgPSA2ICogeTAgLSAxMiAqIHkxICsgNiAqIHkyO1xuICAgICAgICBhID0gLTMgKiB5MCArIDkgKiB5MSAtIDkgKiB5MiArIDMgKiB5MztcbiAgICAgICAgYyA9IDMgKiB5MSAtIDMgKiB5MDtcbiAgICAgIH1cblxuICAgICAgaWYgKE1hdGguYWJzKGEpIDwgMWUtMTIpIHtcbiAgICAgICAgaWYgKE1hdGguYWJzKGIpIDwgMWUtMTIpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHQgPSAtYyAvIGI7XG5cbiAgICAgICAgaWYgKDAgPCB0ICYmIHQgPCAxKSB7XG4gICAgICAgICAgdHZhbHVlcy5wdXNoKHQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGIyYWMgPSBiICogYiAtIDQgKiBjICogYTtcbiAgICAgIHNxcnRiMmFjID0gTWF0aC5zcXJ0KGIyYWMpO1xuXG4gICAgICBpZiAoYjJhYyA8IDApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHQxID0gKC1iICsgc3FydGIyYWMpIC8gKDIgKiBhKTtcblxuICAgICAgaWYgKDAgPCB0MSAmJiB0MSA8IDEpIHtcbiAgICAgICAgdHZhbHVlcy5wdXNoKHQxKTtcbiAgICAgIH1cblxuICAgICAgdDIgPSAoLWIgLSBzcXJ0YjJhYykgLyAoMiAqIGEpO1xuXG4gICAgICBpZiAoMCA8IHQyICYmIHQyIDwgMSkge1xuICAgICAgICB0dmFsdWVzLnB1c2godDIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBqID0gdHZhbHVlcy5sZW5ndGgsXG4gICAgICAgIG10O1xuICAgIGNvbnN0IGpsZW4gPSBqO1xuXG4gICAgd2hpbGUgKGotLSkge1xuICAgICAgdCA9IHR2YWx1ZXNbal07XG4gICAgICBtdCA9IDEgLSB0O1xuICAgICAgYm91bmRzWzBdW2pdID0gbXQgKiBtdCAqIG10ICogeDAgKyAzICogbXQgKiBtdCAqIHQgKiB4MSArIDMgKiBtdCAqIHQgKiB0ICogeDIgKyB0ICogdCAqIHQgKiB4MztcbiAgICAgIGJvdW5kc1sxXVtqXSA9IG10ICogbXQgKiBtdCAqIHkwICsgMyAqIG10ICogbXQgKiB0ICogeTEgKyAzICogbXQgKiB0ICogdCAqIHkyICsgdCAqIHQgKiB0ICogeTM7XG4gICAgfVxuXG4gICAgYm91bmRzWzBdW2psZW5dID0geDA7XG4gICAgYm91bmRzWzFdW2psZW5dID0geTA7XG4gICAgYm91bmRzWzBdW2psZW4gKyAxXSA9IHgzO1xuICAgIGJvdW5kc1sxXVtqbGVuICsgMV0gPSB5MztcbiAgICBib3VuZHNbMF0ubGVuZ3RoID0gYm91bmRzWzFdLmxlbmd0aCA9IGpsZW4gKyAyO1xuICAgIHJldHVybiBbTWF0aC5taW4oLi4uYm91bmRzWzBdKSwgTWF0aC5taW4oLi4uYm91bmRzWzFdKSwgTWF0aC5tYXgoLi4uYm91bmRzWzBdKSwgTWF0aC5tYXgoLi4uYm91bmRzWzFdKV07XG4gIH1cblxufVxuXG5leHBvcnRzLlV0aWwgPSBVdGlsO1xuY29uc3QgUERGU3RyaW5nVHJhbnNsYXRlVGFibGUgPSBbMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMHgyZDgsIDB4MmM3LCAweDJjNiwgMHgyZDksIDB4MmRkLCAweDJkYiwgMHgyZGEsIDB4MmRjLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAweDIwMjIsIDB4MjAyMCwgMHgyMDIxLCAweDIwMjYsIDB4MjAxNCwgMHgyMDEzLCAweDE5MiwgMHgyMDQ0LCAweDIwMzksIDB4MjAzYSwgMHgyMjEyLCAweDIwMzAsIDB4MjAxZSwgMHgyMDFjLCAweDIwMWQsIDB4MjAxOCwgMHgyMDE5LCAweDIwMWEsIDB4MjEyMiwgMHhmYjAxLCAweGZiMDIsIDB4MTQxLCAweDE1MiwgMHgxNjAsIDB4MTc4LCAweDE3ZCwgMHgxMzEsIDB4MTQyLCAweDE1MywgMHgxNjEsIDB4MTdlLCAwLCAweDIwYWNdO1xuXG5mdW5jdGlvbiBzdHJpbmdUb1BERlN0cmluZyhzdHIpIHtcbiAgaWYgKHN0clswXSA+PSBcIlxceEVGXCIpIHtcbiAgICBsZXQgZW5jb2Rpbmc7XG5cbiAgICBpZiAoc3RyWzBdID09PSBcIlxceEZFXCIgJiYgc3RyWzFdID09PSBcIlxceEZGXCIpIHtcbiAgICAgIGVuY29kaW5nID0gXCJ1dGYtMTZiZVwiO1xuICAgIH0gZWxzZSBpZiAoc3RyWzBdID09PSBcIlxceEZGXCIgJiYgc3RyWzFdID09PSBcIlxceEZFXCIpIHtcbiAgICAgIGVuY29kaW5nID0gXCJ1dGYtMTZsZVwiO1xuICAgIH0gZWxzZSBpZiAoc3RyWzBdID09PSBcIlxceEVGXCIgJiYgc3RyWzFdID09PSBcIlxceEJCXCIgJiYgc3RyWzJdID09PSBcIlxceEJGXCIpIHtcbiAgICAgIGVuY29kaW5nID0gXCJ1dGYtOFwiO1xuICAgIH1cblxuICAgIGlmIChlbmNvZGluZykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcihlbmNvZGluZywge1xuICAgICAgICAgIGZhdGFsOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBidWZmZXIgPSBzdHJpbmdUb0J5dGVzKHN0cik7XG4gICAgICAgIHJldHVybiBkZWNvZGVyLmRlY29kZShidWZmZXIpO1xuICAgICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgICAgd2Fybihgc3RyaW5nVG9QREZTdHJpbmc6IFwiJHtleH1cIi5gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBzdHJCdWYgPSBbXTtcblxuICBmb3IgKGxldCBpID0gMCwgaWkgPSBzdHIubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgIGNvbnN0IGNvZGUgPSBQREZTdHJpbmdUcmFuc2xhdGVUYWJsZVtzdHIuY2hhckNvZGVBdChpKV07XG4gICAgc3RyQnVmLnB1c2goY29kZSA/IFN0cmluZy5mcm9tQ2hhckNvZGUoY29kZSkgOiBzdHIuY2hhckF0KGkpKTtcbiAgfVxuXG4gIHJldHVybiBzdHJCdWYuam9pbihcIlwiKTtcbn1cblxuZnVuY3Rpb24gZXNjYXBlU3RyaW5nKHN0cikge1xuICByZXR1cm4gc3RyLnJlcGxhY2UoLyhbKClcXFxcXFxuXFxyXSkvZywgbWF0Y2ggPT4ge1xuICAgIGlmIChtYXRjaCA9PT0gXCJcXG5cIikge1xuICAgICAgcmV0dXJuIFwiXFxcXG5cIjtcbiAgICB9IGVsc2UgaWYgKG1hdGNoID09PSBcIlxcclwiKSB7XG4gICAgICByZXR1cm4gXCJcXFxcclwiO1xuICAgIH1cblxuICAgIHJldHVybiBgXFxcXCR7bWF0Y2h9YDtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGlzQXNjaWkoc3RyKSB7XG4gIHJldHVybiAvXltcXHgwMC1cXHg3Rl0qJC8udGVzdChzdHIpO1xufVxuXG5mdW5jdGlvbiBzdHJpbmdUb1VURjE2QkVTdHJpbmcoc3RyKSB7XG4gIGNvbnN0IGJ1ZiA9IFtcIlxceEZFXFx4RkZcIl07XG5cbiAgZm9yIChsZXQgaSA9IDAsIGlpID0gc3RyLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICBjb25zdCBjaGFyID0gc3RyLmNoYXJDb2RlQXQoaSk7XG4gICAgYnVmLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShjaGFyID4+IDggJiAweGZmKSwgU3RyaW5nLmZyb21DaGFyQ29kZShjaGFyICYgMHhmZikpO1xuICB9XG5cbiAgcmV0dXJuIGJ1Zi5qb2luKFwiXCIpO1xufVxuXG5mdW5jdGlvbiBzdHJpbmdUb1VURjhTdHJpbmcoc3RyKSB7XG4gIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKHN0cikpO1xufVxuXG5mdW5jdGlvbiB1dGY4U3RyaW5nVG9TdHJpbmcoc3RyKSB7XG4gIHJldHVybiB1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoc3RyKSk7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXlCdWZmZXIodikge1xuICByZXR1cm4gdHlwZW9mIHYgPT09IFwib2JqZWN0XCIgJiYgdiAhPT0gbnVsbCAmJiB2LmJ5dGVMZW5ndGggIT09IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gaXNBcnJheUVxdWFsKGFycjEsIGFycjIpIHtcbiAgaWYgKGFycjEubGVuZ3RoICE9PSBhcnIyLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZvciAobGV0IGkgPSAwLCBpaSA9IGFycjEubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgIGlmIChhcnIxW2ldICE9PSBhcnIyW2ldKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGdldE1vZGlmaWNhdGlvbkRhdGUoZGF0ZSA9IG5ldyBEYXRlKCkpIHtcbiAgY29uc3QgYnVmZmVyID0gW2RhdGUuZ2V0VVRDRnVsbFllYXIoKS50b1N0cmluZygpLCAoZGF0ZS5nZXRVVENNb250aCgpICsgMSkudG9TdHJpbmcoKS5wYWRTdGFydCgyLCBcIjBcIiksIGRhdGUuZ2V0VVRDRGF0ZSgpLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgXCIwXCIpLCBkYXRlLmdldFVUQ0hvdXJzKCkudG9TdHJpbmcoKS5wYWRTdGFydCgyLCBcIjBcIiksIGRhdGUuZ2V0VVRDTWludXRlcygpLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgXCIwXCIpLCBkYXRlLmdldFVUQ1NlY29uZHMoKS50b1N0cmluZygpLnBhZFN0YXJ0KDIsIFwiMFwiKV07XG4gIHJldHVybiBidWZmZXIuam9pbihcIlwiKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkoKSB7XG4gIGNvbnN0IGNhcGFiaWxpdHkgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICBsZXQgaXNTZXR0bGVkID0gZmFsc2U7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjYXBhYmlsaXR5LCBcInNldHRsZWRcIiwge1xuICAgIGdldCgpIHtcbiAgICAgIHJldHVybiBpc1NldHRsZWQ7XG4gICAgfVxuXG4gIH0pO1xuICBjYXBhYmlsaXR5LnByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgY2FwYWJpbGl0eS5yZXNvbHZlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgIGlzU2V0dGxlZCA9IHRydWU7XG4gICAgICByZXNvbHZlKGRhdGEpO1xuICAgIH07XG5cbiAgICBjYXBhYmlsaXR5LnJlamVjdCA9IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgIGlzU2V0dGxlZCA9IHRydWU7XG4gICAgICByZWplY3QocmVhc29uKTtcbiAgICB9O1xuICB9KTtcbiAgcmV0dXJuIGNhcGFiaWxpdHk7XG59XG5cbi8qKiovIH0pLFxuLyogMiAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgX191bnVzZWRfd2VicGFja19leHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG52YXIgX2lzX25vZGUgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDMpO1xuXG47XG5cbi8qKiovIH0pLFxuLyogMyAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5pc05vZGVKUyA9IHZvaWQgMDtcbmNvbnN0IGlzTm9kZUpTID0gdHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgcHJvY2VzcyArIFwiXCIgPT09IFwiW29iamVjdCBwcm9jZXNzXVwiICYmICFwcm9jZXNzLnZlcnNpb25zLm53ICYmICEocHJvY2Vzcy52ZXJzaW9ucy5lbGVjdHJvbiAmJiBwcm9jZXNzLnR5cGUgJiYgcHJvY2Vzcy50eXBlICE9PSBcImJyb3dzZXJcIik7XG5leHBvcnRzLmlzTm9kZUpTID0gaXNOb2RlSlM7XG5cbi8qKiovIH0pLFxuLyogNCAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5idWlsZCA9IGV4cG9ydHMuUmVuZGVyVGFzayA9IGV4cG9ydHMuUERGV29ya2VyVXRpbCA9IGV4cG9ydHMuUERGV29ya2VyID0gZXhwb3J0cy5QREZQYWdlUHJveHkgPSBleHBvcnRzLlBERkRvY3VtZW50UHJveHkgPSBleHBvcnRzLlBERkRvY3VtZW50TG9hZGluZ1Rhc2sgPSBleHBvcnRzLlBERkRhdGFSYW5nZVRyYW5zcG9ydCA9IGV4cG9ydHMuTG9vcGJhY2tQb3J0ID0gZXhwb3J0cy5EZWZhdWx0U3RhbmRhcmRGb250RGF0YUZhY3RvcnkgPSBleHBvcnRzLkRlZmF1bHRDYW52YXNGYWN0b3J5ID0gZXhwb3J0cy5EZWZhdWx0Q01hcFJlYWRlckZhY3RvcnkgPSB2b2lkIDA7XG5leHBvcnRzLmdldERvY3VtZW50ID0gZ2V0RG9jdW1lbnQ7XG5leHBvcnRzLnNldFBERk5ldHdvcmtTdHJlYW1GYWN0b3J5ID0gc2V0UERGTmV0d29ya1N0cmVhbUZhY3Rvcnk7XG5leHBvcnRzLnZlcnNpb24gPSB2b2lkIDA7XG5cbnZhciBfdXRpbCA9IF9fd19wZGZqc19yZXF1aXJlX18oMSk7XG5cbnZhciBfZGlzcGxheV91dGlscyA9IF9fd19wZGZqc19yZXF1aXJlX18oNSk7XG5cbnZhciBfZm9udF9sb2FkZXIgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDcpO1xuXG52YXIgX2Fubm90YXRpb25fc3RvcmFnZSA9IF9fd19wZGZqc19yZXF1aXJlX18oOCk7XG5cbnZhciBfY2FudmFzID0gX193X3BkZmpzX3JlcXVpcmVfXygxMCk7XG5cbnZhciBfd29ya2VyX29wdGlvbnMgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDEzKTtcblxudmFyIF9pc19ub2RlID0gX193X3BkZmpzX3JlcXVpcmVfXygzKTtcblxudmFyIF9tZXNzYWdlX2hhbmRsZXIgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDE0KTtcblxudmFyIF9tZXRhZGF0YSA9IF9fd19wZGZqc19yZXF1aXJlX18oMTUpO1xuXG52YXIgX29wdGlvbmFsX2NvbnRlbnRfY29uZmlnID0gX193X3BkZmpzX3JlcXVpcmVfXygxNik7XG5cbnZhciBfdHJhbnNwb3J0X3N0cmVhbSA9IF9fd19wZGZqc19yZXF1aXJlX18oMTcpO1xuXG52YXIgX3hmYV90ZXh0ID0gX193X3BkZmpzX3JlcXVpcmVfXygxOCk7XG5cbmNvbnN0IERFRkFVTFRfUkFOR0VfQ0hVTktfU0laRSA9IDY1NTM2O1xuY29uc3QgUkVOREVSSU5HX0NBTkNFTExFRF9USU1FT1VUID0gMTAwO1xubGV0IERlZmF1bHRDYW52YXNGYWN0b3J5ID0gX2Rpc3BsYXlfdXRpbHMuRE9NQ2FudmFzRmFjdG9yeTtcbmV4cG9ydHMuRGVmYXVsdENhbnZhc0ZhY3RvcnkgPSBEZWZhdWx0Q2FudmFzRmFjdG9yeTtcbmxldCBEZWZhdWx0Q01hcFJlYWRlckZhY3RvcnkgPSBfZGlzcGxheV91dGlscy5ET01DTWFwUmVhZGVyRmFjdG9yeTtcbmV4cG9ydHMuRGVmYXVsdENNYXBSZWFkZXJGYWN0b3J5ID0gRGVmYXVsdENNYXBSZWFkZXJGYWN0b3J5O1xubGV0IERlZmF1bHRTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSA9IF9kaXNwbGF5X3V0aWxzLkRPTVN0YW5kYXJkRm9udERhdGFGYWN0b3J5O1xuZXhwb3J0cy5EZWZhdWx0U3RhbmRhcmRGb250RGF0YUZhY3RvcnkgPSBEZWZhdWx0U3RhbmRhcmRGb250RGF0YUZhY3Rvcnk7XG5cbmlmIChfaXNfbm9kZS5pc05vZGVKUykge1xuICBjb25zdCB7XG4gICAgTm9kZUNhbnZhc0ZhY3RvcnksXG4gICAgTm9kZUNNYXBSZWFkZXJGYWN0b3J5LFxuICAgIE5vZGVTdGFuZGFyZEZvbnREYXRhRmFjdG9yeVxuICB9ID0gX193X3BkZmpzX3JlcXVpcmVfXygxOSk7XG5cbiAgZXhwb3J0cy5EZWZhdWx0Q2FudmFzRmFjdG9yeSA9IERlZmF1bHRDYW52YXNGYWN0b3J5ID0gTm9kZUNhbnZhc0ZhY3Rvcnk7XG4gIGV4cG9ydHMuRGVmYXVsdENNYXBSZWFkZXJGYWN0b3J5ID0gRGVmYXVsdENNYXBSZWFkZXJGYWN0b3J5ID0gTm9kZUNNYXBSZWFkZXJGYWN0b3J5O1xuICBleHBvcnRzLkRlZmF1bHRTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSA9IERlZmF1bHRTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSA9IE5vZGVTdGFuZGFyZEZvbnREYXRhRmFjdG9yeTtcbn1cblxubGV0IGNyZWF0ZVBERk5ldHdvcmtTdHJlYW07XG5cbmZ1bmN0aW9uIHNldFBERk5ldHdvcmtTdHJlYW1GYWN0b3J5KHBkZk5ldHdvcmtTdHJlYW1GYWN0b3J5KSB7XG4gIGNyZWF0ZVBERk5ldHdvcmtTdHJlYW0gPSBwZGZOZXR3b3JrU3RyZWFtRmFjdG9yeTtcbn1cblxuZnVuY3Rpb24gZ2V0RG9jdW1lbnQoc3JjKSB7XG4gIGNvbnN0IHRhc2sgPSBuZXcgUERGRG9jdW1lbnRMb2FkaW5nVGFzaygpO1xuICBsZXQgc291cmNlO1xuXG4gIGlmICh0eXBlb2Ygc3JjID09PSBcInN0cmluZ1wiIHx8IHNyYyBpbnN0YW5jZW9mIFVSTCkge1xuICAgIHNvdXJjZSA9IHtcbiAgICAgIHVybDogc3JjXG4gICAgfTtcbiAgfSBlbHNlIGlmICgoMCwgX3V0aWwuaXNBcnJheUJ1ZmZlcikoc3JjKSkge1xuICAgIHNvdXJjZSA9IHtcbiAgICAgIGRhdGE6IHNyY1xuICAgIH07XG4gIH0gZWxzZSBpZiAoc3JjIGluc3RhbmNlb2YgUERGRGF0YVJhbmdlVHJhbnNwb3J0KSB7XG4gICAgc291cmNlID0ge1xuICAgICAgcmFuZ2U6IHNyY1xuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgaWYgKHR5cGVvZiBzcmMgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgcGFyYW1ldGVyIGluIGdldERvY3VtZW50LCBcIiArIFwibmVlZCBlaXRoZXIgc3RyaW5nLCBVUkwsIFVpbnQ4QXJyYXksIG9yIHBhcmFtZXRlciBvYmplY3QuXCIpO1xuICAgIH1cblxuICAgIGlmICghc3JjLnVybCAmJiAhc3JjLmRhdGEgJiYgIXNyYy5yYW5nZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBwYXJhbWV0ZXIgb2JqZWN0OiBuZWVkIGVpdGhlciAuZGF0YSwgLnJhbmdlIG9yIC51cmxcIik7XG4gICAgfVxuXG4gICAgc291cmNlID0gc3JjO1xuICB9XG5cbiAgY29uc3QgcGFyYW1zID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgbGV0IHJhbmdlVHJhbnNwb3J0ID0gbnVsbCxcbiAgICAgIHdvcmtlciA9IG51bGw7XG5cbiAgZm9yIChjb25zdCBrZXkgaW4gc291cmNlKSB7XG4gICAgY29uc3QgdmFsdWUgPSBzb3VyY2Vba2V5XTtcblxuICAgIHN3aXRjaCAoa2V5KSB7XG4gICAgICBjYXNlIFwidXJsXCI6XG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHBhcmFtc1trZXldID0gbmV3IFVSTCh2YWx1ZSwgd2luZG93LmxvY2F0aW9uKS5ocmVmO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgICAgICAgICgwLCBfdXRpbC53YXJuKShgQ2Fubm90IGNyZWF0ZSB2YWxpZCBVUkw6IFwiJHtleH1cIi5gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiIHx8IHZhbHVlIGluc3RhbmNlb2YgVVJMKSB7XG4gICAgICAgICAgcGFyYW1zW2tleV0gPSB2YWx1ZS50b1N0cmluZygpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBQREYgdXJsIGRhdGE6IFwiICsgXCJlaXRoZXIgc3RyaW5nIG9yIFVSTC1vYmplY3QgaXMgZXhwZWN0ZWQgaW4gdGhlIHVybCBwcm9wZXJ0eS5cIik7XG5cbiAgICAgIGNhc2UgXCJyYW5nZVwiOlxuICAgICAgICByYW5nZVRyYW5zcG9ydCA9IHZhbHVlO1xuICAgICAgICBjb250aW51ZTtcblxuICAgICAgY2FzZSBcIndvcmtlclwiOlxuICAgICAgICB3b3JrZXIgPSB2YWx1ZTtcbiAgICAgICAgY29udGludWU7XG5cbiAgICAgIGNhc2UgXCJkYXRhXCI6XG4gICAgICAgIGlmIChfaXNfbm9kZS5pc05vZGVKUyAmJiB0eXBlb2YgQnVmZmVyICE9PSBcInVuZGVmaW5lZFwiICYmIHZhbHVlIGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgICAgICAgcGFyYW1zW2tleV0gPSBuZXcgVWludDhBcnJheSh2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgcGFyYW1zW2tleV0gPSAoMCwgX3V0aWwuc3RyaW5nVG9CeXRlcykodmFsdWUpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiB2YWx1ZSAhPT0gbnVsbCAmJiAhaXNOYU4odmFsdWUubGVuZ3RoKSkge1xuICAgICAgICAgIHBhcmFtc1trZXldID0gbmV3IFVpbnQ4QXJyYXkodmFsdWUpO1xuICAgICAgICB9IGVsc2UgaWYgKCgwLCBfdXRpbC5pc0FycmF5QnVmZmVyKSh2YWx1ZSkpIHtcbiAgICAgICAgICBwYXJhbXNba2V5XSA9IG5ldyBVaW50OEFycmF5KHZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIFBERiBiaW5hcnkgZGF0YTogZWl0aGVyIHR5cGVkIGFycmF5LCBcIiArIFwic3RyaW5nLCBvciBhcnJheS1saWtlIG9iamVjdCBpcyBleHBlY3RlZCBpbiB0aGUgZGF0YSBwcm9wZXJ0eS5cIik7XG4gICAgICAgIH1cblxuICAgICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBwYXJhbXNba2V5XSA9IHZhbHVlO1xuICB9XG5cbiAgcGFyYW1zLkNNYXBSZWFkZXJGYWN0b3J5ID0gcGFyYW1zLkNNYXBSZWFkZXJGYWN0b3J5IHx8IERlZmF1bHRDTWFwUmVhZGVyRmFjdG9yeTtcbiAgcGFyYW1zLlN0YW5kYXJkRm9udERhdGFGYWN0b3J5ID0gcGFyYW1zLlN0YW5kYXJkRm9udERhdGFGYWN0b3J5IHx8IERlZmF1bHRTdGFuZGFyZEZvbnREYXRhRmFjdG9yeTtcbiAgcGFyYW1zLmlnbm9yZUVycm9ycyA9IHBhcmFtcy5zdG9wQXRFcnJvcnMgIT09IHRydWU7XG4gIHBhcmFtcy5mb250RXh0cmFQcm9wZXJ0aWVzID0gcGFyYW1zLmZvbnRFeHRyYVByb3BlcnRpZXMgPT09IHRydWU7XG4gIHBhcmFtcy5wZGZCdWcgPSBwYXJhbXMucGRmQnVnID09PSB0cnVlO1xuICBwYXJhbXMuZW5hYmxlWGZhID0gcGFyYW1zLmVuYWJsZVhmYSA9PT0gdHJ1ZTtcblxuICBpZiAoIU51bWJlci5pc0ludGVnZXIocGFyYW1zLnJhbmdlQ2h1bmtTaXplKSB8fCBwYXJhbXMucmFuZ2VDaHVua1NpemUgPCAxKSB7XG4gICAgcGFyYW1zLnJhbmdlQ2h1bmtTaXplID0gREVGQVVMVF9SQU5HRV9DSFVOS19TSVpFO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBwYXJhbXMuZG9jQmFzZVVybCAhPT0gXCJzdHJpbmdcIiB8fCAoMCwgX2Rpc3BsYXlfdXRpbHMuaXNEYXRhU2NoZW1lKShwYXJhbXMuZG9jQmFzZVVybCkpIHtcbiAgICBwYXJhbXMuZG9jQmFzZVVybCA9IG51bGw7XG4gIH1cblxuICBpZiAoIU51bWJlci5pc0ludGVnZXIocGFyYW1zLm1heEltYWdlU2l6ZSkgfHwgcGFyYW1zLm1heEltYWdlU2l6ZSA8IC0xKSB7XG4gICAgcGFyYW1zLm1heEltYWdlU2l6ZSA9IC0xO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBwYXJhbXMuY01hcFVybCAhPT0gXCJzdHJpbmdcIikge1xuICAgIHBhcmFtcy5jTWFwVXJsID0gbnVsbDtcbiAgfVxuXG4gIGlmICh0eXBlb2YgcGFyYW1zLnN0YW5kYXJkRm9udERhdGFVcmwgIT09IFwic3RyaW5nXCIpIHtcbiAgICBwYXJhbXMuc3RhbmRhcmRGb250RGF0YVVybCA9IG51bGw7XG4gIH1cblxuICBpZiAodHlwZW9mIHBhcmFtcy51c2VXb3JrZXJGZXRjaCAhPT0gXCJib29sZWFuXCIpIHtcbiAgICBwYXJhbXMudXNlV29ya2VyRmV0Y2ggPSBwYXJhbXMuQ01hcFJlYWRlckZhY3RvcnkgPT09IF9kaXNwbGF5X3V0aWxzLkRPTUNNYXBSZWFkZXJGYWN0b3J5ICYmIHBhcmFtcy5TdGFuZGFyZEZvbnREYXRhRmFjdG9yeSA9PT0gX2Rpc3BsYXlfdXRpbHMuRE9NU3RhbmRhcmRGb250RGF0YUZhY3Rvcnk7XG4gIH1cblxuICBpZiAodHlwZW9mIHBhcmFtcy5pc0V2YWxTdXBwb3J0ZWQgIT09IFwiYm9vbGVhblwiKSB7XG4gICAgcGFyYW1zLmlzRXZhbFN1cHBvcnRlZCA9IHRydWU7XG4gIH1cblxuICBpZiAodHlwZW9mIHBhcmFtcy5kaXNhYmxlRm9udEZhY2UgIT09IFwiYm9vbGVhblwiKSB7XG4gICAgcGFyYW1zLmRpc2FibGVGb250RmFjZSA9IF9pc19ub2RlLmlzTm9kZUpTO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBwYXJhbXMudXNlU3lzdGVtRm9udHMgIT09IFwiYm9vbGVhblwiKSB7XG4gICAgcGFyYW1zLnVzZVN5c3RlbUZvbnRzID0gIV9pc19ub2RlLmlzTm9kZUpTICYmICFwYXJhbXMuZGlzYWJsZUZvbnRGYWNlO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBwYXJhbXMub3duZXJEb2N1bWVudCAhPT0gXCJvYmplY3RcIiB8fCBwYXJhbXMub3duZXJEb2N1bWVudCA9PT0gbnVsbCkge1xuICAgIHBhcmFtcy5vd25lckRvY3VtZW50ID0gZ2xvYmFsVGhpcy5kb2N1bWVudDtcbiAgfVxuXG4gIGlmICh0eXBlb2YgcGFyYW1zLmRpc2FibGVSYW5nZSAhPT0gXCJib29sZWFuXCIpIHtcbiAgICBwYXJhbXMuZGlzYWJsZVJhbmdlID0gZmFsc2U7XG4gIH1cblxuICBpZiAodHlwZW9mIHBhcmFtcy5kaXNhYmxlU3RyZWFtICE9PSBcImJvb2xlYW5cIikge1xuICAgIHBhcmFtcy5kaXNhYmxlU3RyZWFtID0gZmFsc2U7XG4gIH1cblxuICBpZiAodHlwZW9mIHBhcmFtcy5kaXNhYmxlQXV0b0ZldGNoICE9PSBcImJvb2xlYW5cIikge1xuICAgIHBhcmFtcy5kaXNhYmxlQXV0b0ZldGNoID0gZmFsc2U7XG4gIH1cblxuICAoMCwgX3V0aWwuc2V0VmVyYm9zaXR5TGV2ZWwpKHBhcmFtcy52ZXJib3NpdHkpO1xuXG4gIGlmICghd29ya2VyKSB7XG4gICAgY29uc3Qgd29ya2VyUGFyYW1zID0ge1xuICAgICAgdmVyYm9zaXR5OiBwYXJhbXMudmVyYm9zaXR5LFxuICAgICAgcG9ydDogX3dvcmtlcl9vcHRpb25zLkdsb2JhbFdvcmtlck9wdGlvbnMud29ya2VyUG9ydFxuICAgIH07XG4gICAgd29ya2VyID0gd29ya2VyUGFyYW1zLnBvcnQgPyBQREZXb3JrZXIuZnJvbVBvcnQod29ya2VyUGFyYW1zKSA6IG5ldyBQREZXb3JrZXIod29ya2VyUGFyYW1zKTtcbiAgICB0YXNrLl93b3JrZXIgPSB3b3JrZXI7XG4gIH1cblxuICBjb25zdCBkb2NJZCA9IHRhc2suZG9jSWQ7XG4gIHdvcmtlci5wcm9taXNlLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIGlmICh0YXNrLmRlc3Ryb3llZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTG9hZGluZyBhYm9ydGVkXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IHdvcmtlcklkUHJvbWlzZSA9IF9mZXRjaERvY3VtZW50KHdvcmtlciwgcGFyYW1zLCByYW5nZVRyYW5zcG9ydCwgZG9jSWQpO1xuXG4gICAgY29uc3QgbmV0d29ya1N0cmVhbVByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgbGV0IG5ldHdvcmtTdHJlYW07XG5cbiAgICAgIGlmIChyYW5nZVRyYW5zcG9ydCkge1xuICAgICAgICBuZXR3b3JrU3RyZWFtID0gbmV3IF90cmFuc3BvcnRfc3RyZWFtLlBERkRhdGFUcmFuc3BvcnRTdHJlYW0oe1xuICAgICAgICAgIGxlbmd0aDogcGFyYW1zLmxlbmd0aCxcbiAgICAgICAgICBpbml0aWFsRGF0YTogcGFyYW1zLmluaXRpYWxEYXRhLFxuICAgICAgICAgIHByb2dyZXNzaXZlRG9uZTogcGFyYW1zLnByb2dyZXNzaXZlRG9uZSxcbiAgICAgICAgICBjb250ZW50RGlzcG9zaXRpb25GaWxlbmFtZTogcGFyYW1zLmNvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lLFxuICAgICAgICAgIGRpc2FibGVSYW5nZTogcGFyYW1zLmRpc2FibGVSYW5nZSxcbiAgICAgICAgICBkaXNhYmxlU3RyZWFtOiBwYXJhbXMuZGlzYWJsZVN0cmVhbVxuICAgICAgICB9LCByYW5nZVRyYW5zcG9ydCk7XG4gICAgICB9IGVsc2UgaWYgKCFwYXJhbXMuZGF0YSkge1xuICAgICAgICBuZXR3b3JrU3RyZWFtID0gY3JlYXRlUERGTmV0d29ya1N0cmVhbSh7XG4gICAgICAgICAgdXJsOiBwYXJhbXMudXJsLFxuICAgICAgICAgIGxlbmd0aDogcGFyYW1zLmxlbmd0aCxcbiAgICAgICAgICBodHRwSGVhZGVyczogcGFyYW1zLmh0dHBIZWFkZXJzLFxuICAgICAgICAgIHdpdGhDcmVkZW50aWFsczogcGFyYW1zLndpdGhDcmVkZW50aWFscyxcbiAgICAgICAgICByYW5nZUNodW5rU2l6ZTogcGFyYW1zLnJhbmdlQ2h1bmtTaXplLFxuICAgICAgICAgIGRpc2FibGVSYW5nZTogcGFyYW1zLmRpc2FibGVSYW5nZSxcbiAgICAgICAgICBkaXNhYmxlU3RyZWFtOiBwYXJhbXMuZGlzYWJsZVN0cmVhbVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmVzb2x2ZShuZXR3b3JrU3RyZWFtKTtcbiAgICB9KTtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoW3dvcmtlcklkUHJvbWlzZSwgbmV0d29ya1N0cmVhbVByb21pc2VdKS50aGVuKGZ1bmN0aW9uIChbd29ya2VySWQsIG5ldHdvcmtTdHJlYW1dKSB7XG4gICAgICBpZiAodGFzay5kZXN0cm95ZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTG9hZGluZyBhYm9ydGVkXCIpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBtZXNzYWdlSGFuZGxlciA9IG5ldyBfbWVzc2FnZV9oYW5kbGVyLk1lc3NhZ2VIYW5kbGVyKGRvY0lkLCB3b3JrZXJJZCwgd29ya2VyLnBvcnQpO1xuICAgICAgY29uc3QgdHJhbnNwb3J0ID0gbmV3IFdvcmtlclRyYW5zcG9ydChtZXNzYWdlSGFuZGxlciwgdGFzaywgbmV0d29ya1N0cmVhbSwgcGFyYW1zKTtcbiAgICAgIHRhc2suX3RyYW5zcG9ydCA9IHRyYW5zcG9ydDtcbiAgICAgIG1lc3NhZ2VIYW5kbGVyLnNlbmQoXCJSZWFkeVwiLCBudWxsKTtcbiAgICB9KTtcbiAgfSkuY2F0Y2godGFzay5fY2FwYWJpbGl0eS5yZWplY3QpO1xuICByZXR1cm4gdGFzaztcbn1cblxuYXN5bmMgZnVuY3Rpb24gX2ZldGNoRG9jdW1lbnQod29ya2VyLCBzb3VyY2UsIHBkZkRhdGFSYW5nZVRyYW5zcG9ydCwgZG9jSWQpIHtcbiAgaWYgKHdvcmtlci5kZXN0cm95ZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJXb3JrZXIgd2FzIGRlc3Ryb3llZFwiKTtcbiAgfVxuXG4gIGlmIChwZGZEYXRhUmFuZ2VUcmFuc3BvcnQpIHtcbiAgICBzb3VyY2UubGVuZ3RoID0gcGRmRGF0YVJhbmdlVHJhbnNwb3J0Lmxlbmd0aDtcbiAgICBzb3VyY2UuaW5pdGlhbERhdGEgPSBwZGZEYXRhUmFuZ2VUcmFuc3BvcnQuaW5pdGlhbERhdGE7XG4gICAgc291cmNlLnByb2dyZXNzaXZlRG9uZSA9IHBkZkRhdGFSYW5nZVRyYW5zcG9ydC5wcm9ncmVzc2l2ZURvbmU7XG4gICAgc291cmNlLmNvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lID0gcGRmRGF0YVJhbmdlVHJhbnNwb3J0LmNvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lO1xuICB9XG5cbiAgY29uc3Qgd29ya2VySWQgPSBhd2FpdCB3b3JrZXIubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0RG9jUmVxdWVzdFwiLCB7XG4gICAgZG9jSWQsXG4gICAgYXBpVmVyc2lvbjogJzIuMTQuMzA1JyxcbiAgICBzb3VyY2U6IHtcbiAgICAgIGRhdGE6IHNvdXJjZS5kYXRhLFxuICAgICAgdXJsOiBzb3VyY2UudXJsLFxuICAgICAgcGFzc3dvcmQ6IHNvdXJjZS5wYXNzd29yZCxcbiAgICAgIGRpc2FibGVBdXRvRmV0Y2g6IHNvdXJjZS5kaXNhYmxlQXV0b0ZldGNoLFxuICAgICAgcmFuZ2VDaHVua1NpemU6IHNvdXJjZS5yYW5nZUNodW5rU2l6ZSxcbiAgICAgIGxlbmd0aDogc291cmNlLmxlbmd0aFxuICAgIH0sXG4gICAgbWF4SW1hZ2VTaXplOiBzb3VyY2UubWF4SW1hZ2VTaXplLFxuICAgIGRpc2FibGVGb250RmFjZTogc291cmNlLmRpc2FibGVGb250RmFjZSxcbiAgICBkb2NCYXNlVXJsOiBzb3VyY2UuZG9jQmFzZVVybCxcbiAgICBpZ25vcmVFcnJvcnM6IHNvdXJjZS5pZ25vcmVFcnJvcnMsXG4gICAgaXNFdmFsU3VwcG9ydGVkOiBzb3VyY2UuaXNFdmFsU3VwcG9ydGVkLFxuICAgIGZvbnRFeHRyYVByb3BlcnRpZXM6IHNvdXJjZS5mb250RXh0cmFQcm9wZXJ0aWVzLFxuICAgIGVuYWJsZVhmYTogc291cmNlLmVuYWJsZVhmYSxcbiAgICB1c2VTeXN0ZW1Gb250czogc291cmNlLnVzZVN5c3RlbUZvbnRzLFxuICAgIGNNYXBVcmw6IHNvdXJjZS51c2VXb3JrZXJGZXRjaCA/IHNvdXJjZS5jTWFwVXJsIDogbnVsbCxcbiAgICBzdGFuZGFyZEZvbnREYXRhVXJsOiBzb3VyY2UudXNlV29ya2VyRmV0Y2ggPyBzb3VyY2Uuc3RhbmRhcmRGb250RGF0YVVybCA6IG51bGxcbiAgfSk7XG5cbiAgaWYgKHdvcmtlci5kZXN0cm95ZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJXb3JrZXIgd2FzIGRlc3Ryb3llZFwiKTtcbiAgfVxuXG4gIHJldHVybiB3b3JrZXJJZDtcbn1cblxuY2xhc3MgUERGRG9jdW1lbnRMb2FkaW5nVGFzayB7XG4gIHN0YXRpYyAjZG9jSWQgPSAwO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuX2NhcGFiaWxpdHkgPSAoMCwgX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkpKCk7XG4gICAgdGhpcy5fdHJhbnNwb3J0ID0gbnVsbDtcbiAgICB0aGlzLl93b3JrZXIgPSBudWxsO1xuICAgIHRoaXMuZG9jSWQgPSBgZCR7UERGRG9jdW1lbnRMb2FkaW5nVGFzay4jZG9jSWQrK31gO1xuICAgIHRoaXMuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgdGhpcy5vblBhc3N3b3JkID0gbnVsbDtcbiAgICB0aGlzLm9uUHJvZ3Jlc3MgPSBudWxsO1xuICAgIHRoaXMub25VbnN1cHBvcnRlZEZlYXR1cmUgPSBudWxsO1xuICB9XG5cbiAgZ2V0IHByb21pc2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxuXG4gIGFzeW5jIGRlc3Ryb3koKSB7XG4gICAgdGhpcy5kZXN0cm95ZWQgPSB0cnVlO1xuICAgIGF3YWl0IHRoaXMuX3RyYW5zcG9ydD8uZGVzdHJveSgpO1xuICAgIHRoaXMuX3RyYW5zcG9ydCA9IG51bGw7XG5cbiAgICBpZiAodGhpcy5fd29ya2VyKSB7XG4gICAgICB0aGlzLl93b3JrZXIuZGVzdHJveSgpO1xuXG4gICAgICB0aGlzLl93b3JrZXIgPSBudWxsO1xuICAgIH1cbiAgfVxuXG59XG5cbmV4cG9ydHMuUERGRG9jdW1lbnRMb2FkaW5nVGFzayA9IFBERkRvY3VtZW50TG9hZGluZ1Rhc2s7XG5cbmNsYXNzIFBERkRhdGFSYW5nZVRyYW5zcG9ydCB7XG4gIGNvbnN0cnVjdG9yKGxlbmd0aCwgaW5pdGlhbERhdGEsIHByb2dyZXNzaXZlRG9uZSA9IGZhbHNlLCBjb250ZW50RGlzcG9zaXRpb25GaWxlbmFtZSA9IG51bGwpIHtcbiAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDtcbiAgICB0aGlzLmluaXRpYWxEYXRhID0gaW5pdGlhbERhdGE7XG4gICAgdGhpcy5wcm9ncmVzc2l2ZURvbmUgPSBwcm9ncmVzc2l2ZURvbmU7XG4gICAgdGhpcy5jb250ZW50RGlzcG9zaXRpb25GaWxlbmFtZSA9IGNvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lO1xuICAgIHRoaXMuX3JhbmdlTGlzdGVuZXJzID0gW107XG4gICAgdGhpcy5fcHJvZ3Jlc3NMaXN0ZW5lcnMgPSBbXTtcbiAgICB0aGlzLl9wcm9ncmVzc2l2ZVJlYWRMaXN0ZW5lcnMgPSBbXTtcbiAgICB0aGlzLl9wcm9ncmVzc2l2ZURvbmVMaXN0ZW5lcnMgPSBbXTtcbiAgICB0aGlzLl9yZWFkeUNhcGFiaWxpdHkgPSAoMCwgX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkpKCk7XG4gIH1cblxuICBhZGRSYW5nZUxpc3RlbmVyKGxpc3RlbmVyKSB7XG4gICAgdGhpcy5fcmFuZ2VMaXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7XG4gIH1cblxuICBhZGRQcm9ncmVzc0xpc3RlbmVyKGxpc3RlbmVyKSB7XG4gICAgdGhpcy5fcHJvZ3Jlc3NMaXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7XG4gIH1cblxuICBhZGRQcm9ncmVzc2l2ZVJlYWRMaXN0ZW5lcihsaXN0ZW5lcikge1xuICAgIHRoaXMuX3Byb2dyZXNzaXZlUmVhZExpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTtcbiAgfVxuXG4gIGFkZFByb2dyZXNzaXZlRG9uZUxpc3RlbmVyKGxpc3RlbmVyKSB7XG4gICAgdGhpcy5fcHJvZ3Jlc3NpdmVEb25lTGlzdGVuZXJzLnB1c2gobGlzdGVuZXIpO1xuICB9XG5cbiAgb25EYXRhUmFuZ2UoYmVnaW4sIGNodW5rKSB7XG4gICAgZm9yIChjb25zdCBsaXN0ZW5lciBvZiB0aGlzLl9yYW5nZUxpc3RlbmVycykge1xuICAgICAgbGlzdGVuZXIoYmVnaW4sIGNodW5rKTtcbiAgICB9XG4gIH1cblxuICBvbkRhdGFQcm9ncmVzcyhsb2FkZWQsIHRvdGFsKSB7XG4gICAgdGhpcy5fcmVhZHlDYXBhYmlsaXR5LnByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGxpc3RlbmVyIG9mIHRoaXMuX3Byb2dyZXNzTGlzdGVuZXJzKSB7XG4gICAgICAgIGxpc3RlbmVyKGxvYWRlZCwgdG90YWwpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgb25EYXRhUHJvZ3Jlc3NpdmVSZWFkKGNodW5rKSB7XG4gICAgdGhpcy5fcmVhZHlDYXBhYmlsaXR5LnByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGxpc3RlbmVyIG9mIHRoaXMuX3Byb2dyZXNzaXZlUmVhZExpc3RlbmVycykge1xuICAgICAgICBsaXN0ZW5lcihjaHVuayk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBvbkRhdGFQcm9ncmVzc2l2ZURvbmUoKSB7XG4gICAgdGhpcy5fcmVhZHlDYXBhYmlsaXR5LnByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGxpc3RlbmVyIG9mIHRoaXMuX3Byb2dyZXNzaXZlRG9uZUxpc3RlbmVycykge1xuICAgICAgICBsaXN0ZW5lcigpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgdHJhbnNwb3J0UmVhZHkoKSB7XG4gICAgdGhpcy5fcmVhZHlDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgfVxuXG4gIHJlcXVlc3REYXRhUmFuZ2UoYmVnaW4sIGVuZCkge1xuICAgICgwLCBfdXRpbC51bnJlYWNoYWJsZSkoXCJBYnN0cmFjdCBtZXRob2QgUERGRGF0YVJhbmdlVHJhbnNwb3J0LnJlcXVlc3REYXRhUmFuZ2VcIik7XG4gIH1cblxuICBhYm9ydCgpIHt9XG5cbn1cblxuZXhwb3J0cy5QREZEYXRhUmFuZ2VUcmFuc3BvcnQgPSBQREZEYXRhUmFuZ2VUcmFuc3BvcnQ7XG5cbmNsYXNzIFBERkRvY3VtZW50UHJveHkge1xuICBjb25zdHJ1Y3RvcihwZGZJbmZvLCB0cmFuc3BvcnQpIHtcbiAgICB0aGlzLl9wZGZJbmZvID0gcGRmSW5mbztcbiAgICB0aGlzLl90cmFuc3BvcnQgPSB0cmFuc3BvcnQ7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIFwiZmluZ2VycHJpbnRcIiwge1xuICAgICAgZ2V0KCkge1xuICAgICAgICAoMCwgX2Rpc3BsYXlfdXRpbHMuZGVwcmVjYXRlZCkoXCJgUERGRG9jdW1lbnRQcm94eS5maW5nZXJwcmludGAsIFwiICsgXCJwbGVhc2UgdXNlIGBQREZEb2N1bWVudFByb3h5LmZpbmdlcnByaW50c2AgaW5zdGVhZC5cIik7XG4gICAgICAgIHJldHVybiB0aGlzLmZpbmdlcnByaW50c1swXTtcbiAgICAgIH1cblxuICAgIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBcImdldFN0YXRzXCIsIHtcbiAgICAgIHZhbHVlOiBhc3luYyAoKSA9PiB7XG4gICAgICAgICgwLCBfZGlzcGxheV91dGlscy5kZXByZWNhdGVkKShcImBQREZEb2N1bWVudFByb3h5LmdldFN0YXRzYCwgXCIgKyBcInBsZWFzZSB1c2UgdGhlIGBQREZEb2N1bWVudFByb3h5LnN0YXRzYC1nZXR0ZXIgaW5zdGVhZC5cIik7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXRzIHx8IHtcbiAgICAgICAgICBzdHJlYW1UeXBlczoge30sXG4gICAgICAgICAgZm9udFR5cGVzOiB7fVxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZ2V0IGFubm90YXRpb25TdG9yYWdlKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuYW5ub3RhdGlvblN0b3JhZ2U7XG4gIH1cblxuICBnZXQgbnVtUGFnZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BkZkluZm8ubnVtUGFnZXM7XG4gIH1cblxuICBnZXQgZmluZ2VycHJpbnRzKCkge1xuICAgIHJldHVybiB0aGlzLl9wZGZJbmZvLmZpbmdlcnByaW50cztcbiAgfVxuXG4gIGdldCBzdGF0cygpIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0LnN0YXRzO1xuICB9XG5cbiAgZ2V0IGlzUHVyZVhmYSgpIHtcbiAgICByZXR1cm4gISF0aGlzLl90cmFuc3BvcnQuX2h0bWxGb3JYZmE7XG4gIH1cblxuICBnZXQgYWxsWGZhSHRtbCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0Ll9odG1sRm9yWGZhO1xuICB9XG5cbiAgZ2V0UGFnZShwYWdlTnVtYmVyKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RyYW5zcG9ydC5nZXRQYWdlKHBhZ2VOdW1iZXIpO1xuICB9XG5cbiAgZ2V0UGFnZUluZGV4KHJlZikge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0UGFnZUluZGV4KHJlZik7XG4gIH1cblxuICBnZXREZXN0aW5hdGlvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RyYW5zcG9ydC5nZXREZXN0aW5hdGlvbnMoKTtcbiAgfVxuXG4gIGdldERlc3RpbmF0aW9uKGlkKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RyYW5zcG9ydC5nZXREZXN0aW5hdGlvbihpZCk7XG4gIH1cblxuICBnZXRQYWdlTGFiZWxzKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0UGFnZUxhYmVscygpO1xuICB9XG5cbiAgZ2V0UGFnZUxheW91dCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0LmdldFBhZ2VMYXlvdXQoKTtcbiAgfVxuXG4gIGdldFBhZ2VNb2RlKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0UGFnZU1vZGUoKTtcbiAgfVxuXG4gIGdldFZpZXdlclByZWZlcmVuY2VzKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0Vmlld2VyUHJlZmVyZW5jZXMoKTtcbiAgfVxuXG4gIGdldE9wZW5BY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RyYW5zcG9ydC5nZXRPcGVuQWN0aW9uKCk7XG4gIH1cblxuICBnZXRBdHRhY2htZW50cygpIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0LmdldEF0dGFjaG1lbnRzKCk7XG4gIH1cblxuICBnZXRKYXZhU2NyaXB0KCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0SmF2YVNjcmlwdCgpO1xuICB9XG5cbiAgZ2V0SlNBY3Rpb25zKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0RG9jSlNBY3Rpb25zKCk7XG4gIH1cblxuICBnZXRPdXRsaW5lKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0T3V0bGluZSgpO1xuICB9XG5cbiAgZ2V0T3B0aW9uYWxDb250ZW50Q29uZmlnKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0T3B0aW9uYWxDb250ZW50Q29uZmlnKCk7XG4gIH1cblxuICBnZXRQZXJtaXNzaW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0LmdldFBlcm1pc3Npb25zKCk7XG4gIH1cblxuICBnZXRNZXRhZGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0LmdldE1ldGFkYXRhKCk7XG4gIH1cblxuICBnZXRNYXJrSW5mbygpIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0LmdldE1hcmtJbmZvKCk7XG4gIH1cblxuICBnZXREYXRhKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0RGF0YSgpO1xuICB9XG5cbiAgZ2V0RG93bmxvYWRJbmZvKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZG93bmxvYWRJbmZvQ2FwYWJpbGl0eS5wcm9taXNlO1xuICB9XG5cbiAgY2xlYW51cChrZWVwTG9hZGVkRm9udHMgPSBmYWxzZSkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuc3RhcnRDbGVhbnVwKGtlZXBMb2FkZWRGb250cyB8fCB0aGlzLmlzUHVyZVhmYSk7XG4gIH1cblxuICBkZXN0cm95KCkge1xuICAgIHJldHVybiB0aGlzLmxvYWRpbmdUYXNrLmRlc3Ryb3koKTtcbiAgfVxuXG4gIGdldCBsb2FkaW5nUGFyYW1zKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQubG9hZGluZ1BhcmFtcztcbiAgfVxuXG4gIGdldCBsb2FkaW5nVGFzaygpIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0LmxvYWRpbmdUYXNrO1xuICB9XG5cbiAgc2F2ZURvY3VtZW50KCkge1xuICAgIGlmICh0aGlzLl90cmFuc3BvcnQuYW5ub3RhdGlvblN0b3JhZ2Uuc2l6ZSA8PSAwKSB7XG4gICAgICAoMCwgX2Rpc3BsYXlfdXRpbHMuZGVwcmVjYXRlZCkoXCJzYXZlRG9jdW1lbnQgY2FsbGVkIHdoaWxlIGBhbm5vdGF0aW9uU3RvcmFnZWAgaXMgZW1wdHksIFwiICsgXCJwbGVhc2UgdXNlIHRoZSBnZXREYXRhLW1ldGhvZCBpbnN0ZWFkLlwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0LnNhdmVEb2N1bWVudCgpO1xuICB9XG5cbiAgZ2V0RmllbGRPYmplY3RzKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuZ2V0RmllbGRPYmplY3RzKCk7XG4gIH1cblxuICBoYXNKU0FjdGlvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RyYW5zcG9ydC5oYXNKU0FjdGlvbnMoKTtcbiAgfVxuXG4gIGdldENhbGN1bGF0aW9uT3JkZXJJZHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RyYW5zcG9ydC5nZXRDYWxjdWxhdGlvbk9yZGVySWRzKCk7XG4gIH1cblxufVxuXG5leHBvcnRzLlBERkRvY3VtZW50UHJveHkgPSBQREZEb2N1bWVudFByb3h5O1xuXG5jbGFzcyBQREZQYWdlUHJveHkge1xuICBjb25zdHJ1Y3RvcihwYWdlSW5kZXgsIHBhZ2VJbmZvLCB0cmFuc3BvcnQsIG93bmVyRG9jdW1lbnQsIHBkZkJ1ZyA9IGZhbHNlKSB7XG4gICAgdGhpcy5fcGFnZUluZGV4ID0gcGFnZUluZGV4O1xuICAgIHRoaXMuX3BhZ2VJbmZvID0gcGFnZUluZm87XG4gICAgdGhpcy5fb3duZXJEb2N1bWVudCA9IG93bmVyRG9jdW1lbnQ7XG4gICAgdGhpcy5fdHJhbnNwb3J0ID0gdHJhbnNwb3J0O1xuICAgIHRoaXMuX3N0YXRzID0gcGRmQnVnID8gbmV3IF9kaXNwbGF5X3V0aWxzLlN0YXRUaW1lcigpIDogbnVsbDtcbiAgICB0aGlzLl9wZGZCdWcgPSBwZGZCdWc7XG4gICAgdGhpcy5jb21tb25PYmpzID0gdHJhbnNwb3J0LmNvbW1vbk9ianM7XG4gICAgdGhpcy5vYmpzID0gbmV3IFBERk9iamVjdHMoKTtcbiAgICB0aGlzLl9iaXRtYXBzID0gbmV3IFNldCgpO1xuICAgIHRoaXMuY2xlYW51cEFmdGVyUmVuZGVyID0gZmFsc2U7XG4gICAgdGhpcy5wZW5kaW5nQ2xlYW51cCA9IGZhbHNlO1xuICAgIHRoaXMuX2ludGVudFN0YXRlcyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLl9hbm5vdGF0aW9uUHJvbWlzZXMgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5kZXN0cm95ZWQgPSBmYWxzZTtcbiAgfVxuXG4gIGdldCBwYWdlTnVtYmVyKCkge1xuICAgIHJldHVybiB0aGlzLl9wYWdlSW5kZXggKyAxO1xuICB9XG5cbiAgZ2V0IHJvdGF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fcGFnZUluZm8ucm90YXRlO1xuICB9XG5cbiAgZ2V0IHJlZigpIHtcbiAgICByZXR1cm4gdGhpcy5fcGFnZUluZm8ucmVmO1xuICB9XG5cbiAgZ2V0IHVzZXJVbml0KCkge1xuICAgIHJldHVybiB0aGlzLl9wYWdlSW5mby51c2VyVW5pdDtcbiAgfVxuXG4gIGdldCB2aWV3KCkge1xuICAgIHJldHVybiB0aGlzLl9wYWdlSW5mby52aWV3O1xuICB9XG5cbiAgZ2V0Vmlld3BvcnQoe1xuICAgIHNjYWxlLFxuICAgIHJvdGF0aW9uID0gdGhpcy5yb3RhdGUsXG4gICAgb2Zmc2V0WCA9IDAsXG4gICAgb2Zmc2V0WSA9IDAsXG4gICAgZG9udEZsaXAgPSBmYWxzZVxuICB9ID0ge30pIHtcbiAgICByZXR1cm4gbmV3IF9kaXNwbGF5X3V0aWxzLlBhZ2VWaWV3cG9ydCh7XG4gICAgICB2aWV3Qm94OiB0aGlzLnZpZXcsXG4gICAgICBzY2FsZSxcbiAgICAgIHJvdGF0aW9uLFxuICAgICAgb2Zmc2V0WCxcbiAgICAgIG9mZnNldFksXG4gICAgICBkb250RmxpcFxuICAgIH0pO1xuICB9XG5cbiAgZ2V0QW5ub3RhdGlvbnMoe1xuICAgIGludGVudCA9IFwiZGlzcGxheVwiXG4gIH0gPSB7fSkge1xuICAgIGNvbnN0IGludGVudEFyZ3MgPSB0aGlzLl90cmFuc3BvcnQuZ2V0UmVuZGVyaW5nSW50ZW50KGludGVudCk7XG5cbiAgICBsZXQgcHJvbWlzZSA9IHRoaXMuX2Fubm90YXRpb25Qcm9taXNlcy5nZXQoaW50ZW50QXJncy5jYWNoZUtleSk7XG5cbiAgICBpZiAoIXByb21pc2UpIHtcbiAgICAgIHByb21pc2UgPSB0aGlzLl90cmFuc3BvcnQuZ2V0QW5ub3RhdGlvbnModGhpcy5fcGFnZUluZGV4LCBpbnRlbnRBcmdzLnJlbmRlcmluZ0ludGVudCk7XG5cbiAgICAgIHRoaXMuX2Fubm90YXRpb25Qcm9taXNlcy5zZXQoaW50ZW50QXJncy5jYWNoZUtleSwgcHJvbWlzZSk7XG5cbiAgICAgIHByb21pc2UgPSBwcm9taXNlLnRoZW4oYW5ub3RhdGlvbnMgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IGFubm90YXRpb24gb2YgYW5ub3RhdGlvbnMpIHtcbiAgICAgICAgICBpZiAoYW5ub3RhdGlvbi50aXRsZU9iaiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoYW5ub3RhdGlvbiwgXCJ0aXRsZVwiLCB7XG4gICAgICAgICAgICAgIGdldCgpIHtcbiAgICAgICAgICAgICAgICAoMCwgX2Rpc3BsYXlfdXRpbHMuZGVwcmVjYXRlZCkoXCJgdGl0bGVgLXByb3BlcnR5IG9uIGFubm90YXRpb24sIHBsZWFzZSB1c2UgYHRpdGxlT2JqYCBpbnN0ZWFkLlwiKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYW5ub3RhdGlvbi50aXRsZU9iai5zdHI7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGFubm90YXRpb24uY29udGVudHNPYmogIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGFubm90YXRpb24sIFwiY29udGVudHNcIiwge1xuICAgICAgICAgICAgICBnZXQoKSB7XG4gICAgICAgICAgICAgICAgKDAsIF9kaXNwbGF5X3V0aWxzLmRlcHJlY2F0ZWQpKFwiYGNvbnRlbnRzYC1wcm9wZXJ0eSBvbiBhbm5vdGF0aW9uLCBwbGVhc2UgdXNlIGBjb250ZW50c09iamAgaW5zdGVhZC5cIik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFubm90YXRpb24uY29udGVudHNPYmouc3RyO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhbm5vdGF0aW9ucztcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgZ2V0SlNBY3Rpb25zKCkge1xuICAgIHJldHVybiB0aGlzLl9qc0FjdGlvbnNQcm9taXNlIHx8PSB0aGlzLl90cmFuc3BvcnQuZ2V0UGFnZUpTQWN0aW9ucyh0aGlzLl9wYWdlSW5kZXgpO1xuICB9XG5cbiAgYXN5bmMgZ2V0WGZhKCkge1xuICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQuX2h0bWxGb3JYZmE/LmNoaWxkcmVuW3RoaXMuX3BhZ2VJbmRleF0gfHwgbnVsbDtcbiAgfVxuXG4gIHJlbmRlcih7XG4gICAgY2FudmFzQ29udGV4dCxcbiAgICB2aWV3cG9ydCxcbiAgICBpbnRlbnQgPSBcImRpc3BsYXlcIixcbiAgICBhbm5vdGF0aW9uTW9kZSA9IF91dGlsLkFubm90YXRpb25Nb2RlLkVOQUJMRSxcbiAgICB0cmFuc2Zvcm0gPSBudWxsLFxuICAgIGltYWdlTGF5ZXIgPSBudWxsLFxuICAgIGNhbnZhc0ZhY3RvcnkgPSBudWxsLFxuICAgIGJhY2tncm91bmQgPSBudWxsLFxuICAgIG9wdGlvbmFsQ29udGVudENvbmZpZ1Byb21pc2UgPSBudWxsLFxuICAgIGFubm90YXRpb25DYW52YXNNYXAgPSBudWxsLFxuICAgIHBhZ2VDb2xvcnMgPSBudWxsXG4gIH0pIHtcbiAgICBpZiAoYXJndW1lbnRzWzBdPy5yZW5kZXJJbnRlcmFjdGl2ZUZvcm1zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICgwLCBfZGlzcGxheV91dGlscy5kZXByZWNhdGVkKShcInJlbmRlciBubyBsb25nZXIgYWNjZXB0cyB0aGUgYHJlbmRlckludGVyYWN0aXZlRm9ybXNgLW9wdGlvbiwgXCIgKyBcInBsZWFzZSB1c2UgdGhlIGBhbm5vdGF0aW9uTW9kZWAtb3B0aW9uIGluc3RlYWQuXCIpO1xuXG4gICAgICBpZiAoYXJndW1lbnRzWzBdLnJlbmRlckludGVyYWN0aXZlRm9ybXMgPT09IHRydWUgJiYgYW5ub3RhdGlvbk1vZGUgPT09IF91dGlsLkFubm90YXRpb25Nb2RlLkVOQUJMRSkge1xuICAgICAgICBhbm5vdGF0aW9uTW9kZSA9IF91dGlsLkFubm90YXRpb25Nb2RlLkVOQUJMRV9GT1JNUztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYXJndW1lbnRzWzBdPy5pbmNsdWRlQW5ub3RhdGlvblN0b3JhZ2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgKDAsIF9kaXNwbGF5X3V0aWxzLmRlcHJlY2F0ZWQpKFwicmVuZGVyIG5vIGxvbmdlciBhY2NlcHRzIHRoZSBgaW5jbHVkZUFubm90YXRpb25TdG9yYWdlYC1vcHRpb24sIFwiICsgXCJwbGVhc2UgdXNlIHRoZSBgYW5ub3RhdGlvbk1vZGVgLW9wdGlvbiBpbnN0ZWFkLlwiKTtcblxuICAgICAgaWYgKGFyZ3VtZW50c1swXS5pbmNsdWRlQW5ub3RhdGlvblN0b3JhZ2UgPT09IHRydWUgJiYgYW5ub3RhdGlvbk1vZGUgPT09IF91dGlsLkFubm90YXRpb25Nb2RlLkVOQUJMRSkge1xuICAgICAgICBhbm5vdGF0aW9uTW9kZSA9IF91dGlsLkFubm90YXRpb25Nb2RlLkVOQUJMRV9TVE9SQUdFO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLl9zdGF0cykge1xuICAgICAgdGhpcy5fc3RhdHMudGltZShcIk92ZXJhbGxcIik7XG4gICAgfVxuXG4gICAgY29uc3QgaW50ZW50QXJncyA9IHRoaXMuX3RyYW5zcG9ydC5nZXRSZW5kZXJpbmdJbnRlbnQoaW50ZW50LCBhbm5vdGF0aW9uTW9kZSk7XG5cbiAgICB0aGlzLnBlbmRpbmdDbGVhbnVwID0gZmFsc2U7XG5cbiAgICBpZiAoIW9wdGlvbmFsQ29udGVudENvbmZpZ1Byb21pc2UpIHtcbiAgICAgIG9wdGlvbmFsQ29udGVudENvbmZpZ1Byb21pc2UgPSB0aGlzLl90cmFuc3BvcnQuZ2V0T3B0aW9uYWxDb250ZW50Q29uZmlnKCk7XG4gICAgfVxuXG4gICAgbGV0IGludGVudFN0YXRlID0gdGhpcy5faW50ZW50U3RhdGVzLmdldChpbnRlbnRBcmdzLmNhY2hlS2V5KTtcblxuICAgIGlmICghaW50ZW50U3RhdGUpIHtcbiAgICAgIGludGVudFN0YXRlID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuICAgICAgdGhpcy5faW50ZW50U3RhdGVzLnNldChpbnRlbnRBcmdzLmNhY2hlS2V5LCBpbnRlbnRTdGF0ZSk7XG4gICAgfVxuXG4gICAgaWYgKGludGVudFN0YXRlLnN0cmVhbVJlYWRlckNhbmNlbFRpbWVvdXQpIHtcbiAgICAgIGNsZWFyVGltZW91dChpbnRlbnRTdGF0ZS5zdHJlYW1SZWFkZXJDYW5jZWxUaW1lb3V0KTtcbiAgICAgIGludGVudFN0YXRlLnN0cmVhbVJlYWRlckNhbmNlbFRpbWVvdXQgPSBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IGNhbnZhc0ZhY3RvcnlJbnN0YW5jZSA9IGNhbnZhc0ZhY3RvcnkgfHwgbmV3IERlZmF1bHRDYW52YXNGYWN0b3J5KHtcbiAgICAgIG93bmVyRG9jdW1lbnQ6IHRoaXMuX293bmVyRG9jdW1lbnRcbiAgICB9KTtcbiAgICBjb25zdCBpbnRlbnRQcmludCA9ICEhKGludGVudEFyZ3MucmVuZGVyaW5nSW50ZW50ICYgX3V0aWwuUmVuZGVyaW5nSW50ZW50RmxhZy5QUklOVCk7XG5cbiAgICBpZiAoIWludGVudFN0YXRlLmRpc3BsYXlSZWFkeUNhcGFiaWxpdHkpIHtcbiAgICAgIGludGVudFN0YXRlLmRpc3BsYXlSZWFkeUNhcGFiaWxpdHkgPSAoMCwgX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkpKCk7XG4gICAgICBpbnRlbnRTdGF0ZS5vcGVyYXRvckxpc3QgPSB7XG4gICAgICAgIGZuQXJyYXk6IFtdLFxuICAgICAgICBhcmdzQXJyYXk6IFtdLFxuICAgICAgICBsYXN0Q2h1bms6IGZhbHNlXG4gICAgICB9O1xuXG4gICAgICBpZiAodGhpcy5fc3RhdHMpIHtcbiAgICAgICAgdGhpcy5fc3RhdHMudGltZShcIlBhZ2UgUmVxdWVzdFwiKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fcHVtcE9wZXJhdG9yTGlzdChpbnRlbnRBcmdzKTtcbiAgICB9XG5cbiAgICBjb25zdCBjb21wbGV0ZSA9IGVycm9yID0+IHtcbiAgICAgIGludGVudFN0YXRlLnJlbmRlclRhc2tzLmRlbGV0ZShpbnRlcm5hbFJlbmRlclRhc2spO1xuXG4gICAgICBpZiAodGhpcy5jbGVhbnVwQWZ0ZXJSZW5kZXIgfHwgaW50ZW50UHJpbnQpIHtcbiAgICAgICAgdGhpcy5wZW5kaW5nQ2xlYW51cCA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3RyeUNsZWFudXAoKTtcblxuICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgIGludGVybmFsUmVuZGVyVGFzay5jYXBhYmlsaXR5LnJlamVjdChlcnJvcik7XG5cbiAgICAgICAgdGhpcy5fYWJvcnRPcGVyYXRvckxpc3Qoe1xuICAgICAgICAgIGludGVudFN0YXRlLFxuICAgICAgICAgIHJlYXNvbjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKGVycm9yKVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGludGVybmFsUmVuZGVyVGFzay5jYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuX3N0YXRzKSB7XG4gICAgICAgIHRoaXMuX3N0YXRzLnRpbWVFbmQoXCJSZW5kZXJpbmdcIik7XG5cbiAgICAgICAgdGhpcy5fc3RhdHMudGltZUVuZChcIk92ZXJhbGxcIik7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0IGludGVybmFsUmVuZGVyVGFzayA9IG5ldyBJbnRlcm5hbFJlbmRlclRhc2soe1xuICAgICAgY2FsbGJhY2s6IGNvbXBsZXRlLFxuICAgICAgcGFyYW1zOiB7XG4gICAgICAgIGNhbnZhc0NvbnRleHQsXG4gICAgICAgIHZpZXdwb3J0LFxuICAgICAgICB0cmFuc2Zvcm0sXG4gICAgICAgIGltYWdlTGF5ZXIsXG4gICAgICAgIGJhY2tncm91bmRcbiAgICAgIH0sXG4gICAgICBvYmpzOiB0aGlzLm9ianMsXG4gICAgICBjb21tb25PYmpzOiB0aGlzLmNvbW1vbk9ianMsXG4gICAgICBhbm5vdGF0aW9uQ2FudmFzTWFwLFxuICAgICAgb3BlcmF0b3JMaXN0OiBpbnRlbnRTdGF0ZS5vcGVyYXRvckxpc3QsXG4gICAgICBwYWdlSW5kZXg6IHRoaXMuX3BhZ2VJbmRleCxcbiAgICAgIGNhbnZhc0ZhY3Rvcnk6IGNhbnZhc0ZhY3RvcnlJbnN0YW5jZSxcbiAgICAgIHVzZVJlcXVlc3RBbmltYXRpb25GcmFtZTogIWludGVudFByaW50LFxuICAgICAgcGRmQnVnOiB0aGlzLl9wZGZCdWcsXG4gICAgICBwYWdlQ29sb3JzXG4gICAgfSk7XG4gICAgKGludGVudFN0YXRlLnJlbmRlclRhc2tzIHx8PSBuZXcgU2V0KCkpLmFkZChpbnRlcm5hbFJlbmRlclRhc2spO1xuICAgIGNvbnN0IHJlbmRlclRhc2sgPSBpbnRlcm5hbFJlbmRlclRhc2sudGFzaztcbiAgICBQcm9taXNlLmFsbChbaW50ZW50U3RhdGUuZGlzcGxheVJlYWR5Q2FwYWJpbGl0eS5wcm9taXNlLCBvcHRpb25hbENvbnRlbnRDb25maWdQcm9taXNlXSkudGhlbigoW3RyYW5zcGFyZW5jeSwgb3B0aW9uYWxDb250ZW50Q29uZmlnXSkgPT4ge1xuICAgICAgaWYgKHRoaXMucGVuZGluZ0NsZWFudXApIHtcbiAgICAgICAgY29tcGxldGUoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5fc3RhdHMpIHtcbiAgICAgICAgdGhpcy5fc3RhdHMudGltZShcIlJlbmRlcmluZ1wiKTtcbiAgICAgIH1cblxuICAgICAgaW50ZXJuYWxSZW5kZXJUYXNrLmluaXRpYWxpemVHcmFwaGljcyh7XG4gICAgICAgIHRyYW5zcGFyZW5jeSxcbiAgICAgICAgb3B0aW9uYWxDb250ZW50Q29uZmlnXG4gICAgICB9KTtcbiAgICAgIGludGVybmFsUmVuZGVyVGFzay5vcGVyYXRvckxpc3RDaGFuZ2VkKCk7XG4gICAgfSkuY2F0Y2goY29tcGxldGUpO1xuICAgIHJldHVybiByZW5kZXJUYXNrO1xuICB9XG5cbiAgZ2V0T3BlcmF0b3JMaXN0KHtcbiAgICBpbnRlbnQgPSBcImRpc3BsYXlcIixcbiAgICBhbm5vdGF0aW9uTW9kZSA9IF91dGlsLkFubm90YXRpb25Nb2RlLkVOQUJMRVxuICB9ID0ge30pIHtcbiAgICBmdW5jdGlvbiBvcGVyYXRvckxpc3RDaGFuZ2VkKCkge1xuICAgICAgaWYgKGludGVudFN0YXRlLm9wZXJhdG9yTGlzdC5sYXN0Q2h1bmspIHtcbiAgICAgICAgaW50ZW50U3RhdGUub3BMaXN0UmVhZENhcGFiaWxpdHkucmVzb2x2ZShpbnRlbnRTdGF0ZS5vcGVyYXRvckxpc3QpO1xuICAgICAgICBpbnRlbnRTdGF0ZS5yZW5kZXJUYXNrcy5kZWxldGUob3BMaXN0VGFzayk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgaW50ZW50QXJncyA9IHRoaXMuX3RyYW5zcG9ydC5nZXRSZW5kZXJpbmdJbnRlbnQoaW50ZW50LCBhbm5vdGF0aW9uTW9kZSwgdHJ1ZSk7XG5cbiAgICBsZXQgaW50ZW50U3RhdGUgPSB0aGlzLl9pbnRlbnRTdGF0ZXMuZ2V0KGludGVudEFyZ3MuY2FjaGVLZXkpO1xuXG4gICAgaWYgKCFpbnRlbnRTdGF0ZSkge1xuICAgICAgaW50ZW50U3RhdGUgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4gICAgICB0aGlzLl9pbnRlbnRTdGF0ZXMuc2V0KGludGVudEFyZ3MuY2FjaGVLZXksIGludGVudFN0YXRlKTtcbiAgICB9XG5cbiAgICBsZXQgb3BMaXN0VGFzaztcblxuICAgIGlmICghaW50ZW50U3RhdGUub3BMaXN0UmVhZENhcGFiaWxpdHkpIHtcbiAgICAgIG9wTGlzdFRhc2sgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgb3BMaXN0VGFzay5vcGVyYXRvckxpc3RDaGFuZ2VkID0gb3BlcmF0b3JMaXN0Q2hhbmdlZDtcbiAgICAgIGludGVudFN0YXRlLm9wTGlzdFJlYWRDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgICAgKGludGVudFN0YXRlLnJlbmRlclRhc2tzIHx8PSBuZXcgU2V0KCkpLmFkZChvcExpc3RUYXNrKTtcbiAgICAgIGludGVudFN0YXRlLm9wZXJhdG9yTGlzdCA9IHtcbiAgICAgICAgZm5BcnJheTogW10sXG4gICAgICAgIGFyZ3NBcnJheTogW10sXG4gICAgICAgIGxhc3RDaHVuazogZmFsc2VcbiAgICAgIH07XG5cbiAgICAgIGlmICh0aGlzLl9zdGF0cykge1xuICAgICAgICB0aGlzLl9zdGF0cy50aW1lKFwiUGFnZSBSZXF1ZXN0XCIpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9wdW1wT3BlcmF0b3JMaXN0KGludGVudEFyZ3MpO1xuICAgIH1cblxuICAgIHJldHVybiBpbnRlbnRTdGF0ZS5vcExpc3RSZWFkQ2FwYWJpbGl0eS5wcm9taXNlO1xuICB9XG5cbiAgc3RyZWFtVGV4dENvbnRlbnQoe1xuICAgIGRpc2FibGVDb21iaW5lVGV4dEl0ZW1zID0gZmFsc2UsXG4gICAgaW5jbHVkZU1hcmtlZENvbnRlbnQgPSBmYWxzZVxuICB9ID0ge30pIHtcbiAgICBjb25zdCBURVhUX0NPTlRFTlRfQ0hVTktfU0laRSA9IDEwMDtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0Lm1lc3NhZ2VIYW5kbGVyLnNlbmRXaXRoU3RyZWFtKFwiR2V0VGV4dENvbnRlbnRcIiwge1xuICAgICAgcGFnZUluZGV4OiB0aGlzLl9wYWdlSW5kZXgsXG4gICAgICBjb21iaW5lVGV4dEl0ZW1zOiBkaXNhYmxlQ29tYmluZVRleHRJdGVtcyAhPT0gdHJ1ZSxcbiAgICAgIGluY2x1ZGVNYXJrZWRDb250ZW50OiBpbmNsdWRlTWFya2VkQ29udGVudCA9PT0gdHJ1ZVxuICAgIH0sIHtcbiAgICAgIGhpZ2hXYXRlck1hcms6IFRFWFRfQ09OVEVOVF9DSFVOS19TSVpFLFxuXG4gICAgICBzaXplKHRleHRDb250ZW50KSB7XG4gICAgICAgIHJldHVybiB0ZXh0Q29udGVudC5pdGVtcy5sZW5ndGg7XG4gICAgICB9XG5cbiAgICB9KTtcbiAgfVxuXG4gIGdldFRleHRDb250ZW50KHBhcmFtcyA9IHt9KSB7XG4gICAgaWYgKHRoaXMuX3RyYW5zcG9ydC5faHRtbEZvclhmYSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0WGZhKCkudGhlbih4ZmEgPT4ge1xuICAgICAgICByZXR1cm4gX3hmYV90ZXh0LlhmYVRleHQudGV4dENvbnRlbnQoeGZhKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IHJlYWRhYmxlU3RyZWFtID0gdGhpcy5zdHJlYW1UZXh0Q29udGVudChwYXJhbXMpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBmdW5jdGlvbiBwdW1wKCkge1xuICAgICAgICByZWFkZXIucmVhZCgpLnRoZW4oZnVuY3Rpb24gKHtcbiAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICBkb25lXG4gICAgICAgIH0pIHtcbiAgICAgICAgICBpZiAoZG9uZSkge1xuICAgICAgICAgICAgcmVzb2x2ZSh0ZXh0Q29udGVudCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgT2JqZWN0LmFzc2lnbih0ZXh0Q29udGVudC5zdHlsZXMsIHZhbHVlLnN0eWxlcyk7XG4gICAgICAgICAgdGV4dENvbnRlbnQuaXRlbXMucHVzaCguLi52YWx1ZS5pdGVtcyk7XG4gICAgICAgICAgcHVtcCgpO1xuICAgICAgICB9LCByZWplY3QpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZWFkZXIgPSByZWFkYWJsZVN0cmVhbS5nZXRSZWFkZXIoKTtcbiAgICAgIGNvbnN0IHRleHRDb250ZW50ID0ge1xuICAgICAgICBpdGVtczogW10sXG4gICAgICAgIHN0eWxlczogT2JqZWN0LmNyZWF0ZShudWxsKVxuICAgICAgfTtcbiAgICAgIHB1bXAoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldFN0cnVjdFRyZWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0cnVjdFRyZWVQcm9taXNlIHx8PSB0aGlzLl90cmFuc3BvcnQuZ2V0U3RydWN0VHJlZSh0aGlzLl9wYWdlSW5kZXgpO1xuICB9XG5cbiAgX2Rlc3Ryb3koKSB7XG4gICAgdGhpcy5kZXN0cm95ZWQgPSB0cnVlO1xuICAgIGNvbnN0IHdhaXRPbiA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBpbnRlbnRTdGF0ZSBvZiB0aGlzLl9pbnRlbnRTdGF0ZXMudmFsdWVzKCkpIHtcbiAgICAgIHRoaXMuX2Fib3J0T3BlcmF0b3JMaXN0KHtcbiAgICAgICAgaW50ZW50U3RhdGUsXG4gICAgICAgIHJlYXNvbjogbmV3IEVycm9yKFwiUGFnZSB3YXMgZGVzdHJveWVkLlwiKSxcbiAgICAgICAgZm9yY2U6IHRydWVcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoaW50ZW50U3RhdGUub3BMaXN0UmVhZENhcGFiaWxpdHkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgaW50ZXJuYWxSZW5kZXJUYXNrIG9mIGludGVudFN0YXRlLnJlbmRlclRhc2tzKSB7XG4gICAgICAgIHdhaXRPbi5wdXNoKGludGVybmFsUmVuZGVyVGFzay5jb21wbGV0ZWQpO1xuICAgICAgICBpbnRlcm5hbFJlbmRlclRhc2suY2FuY2VsKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5vYmpzLmNsZWFyKCk7XG5cbiAgICBmb3IgKGNvbnN0IGJpdG1hcCBvZiB0aGlzLl9iaXRtYXBzKSB7XG4gICAgICBiaXRtYXAuY2xvc2UoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9iaXRtYXBzLmNsZWFyKCk7XG5cbiAgICB0aGlzLl9hbm5vdGF0aW9uUHJvbWlzZXMuY2xlYXIoKTtcblxuICAgIHRoaXMuX2pzQWN0aW9uc1Byb21pc2UgPSBudWxsO1xuICAgIHRoaXMuX3N0cnVjdFRyZWVQcm9taXNlID0gbnVsbDtcbiAgICB0aGlzLnBlbmRpbmdDbGVhbnVwID0gZmFsc2U7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKHdhaXRPbik7XG4gIH1cblxuICBjbGVhbnVwKHJlc2V0U3RhdHMgPSBmYWxzZSkge1xuICAgIHRoaXMucGVuZGluZ0NsZWFudXAgPSB0cnVlO1xuICAgIHJldHVybiB0aGlzLl90cnlDbGVhbnVwKHJlc2V0U3RhdHMpO1xuICB9XG5cbiAgX3RyeUNsZWFudXAocmVzZXRTdGF0cyA9IGZhbHNlKSB7XG4gICAgaWYgKCF0aGlzLnBlbmRpbmdDbGVhbnVwKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCB7XG4gICAgICByZW5kZXJUYXNrcyxcbiAgICAgIG9wZXJhdG9yTGlzdFxuICAgIH0gb2YgdGhpcy5faW50ZW50U3RhdGVzLnZhbHVlcygpKSB7XG4gICAgICBpZiAocmVuZGVyVGFza3Muc2l6ZSA+IDAgfHwgIW9wZXJhdG9yTGlzdC5sYXN0Q2h1bmspIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX2ludGVudFN0YXRlcy5jbGVhcigpO1xuXG4gICAgdGhpcy5vYmpzLmNsZWFyKCk7XG5cbiAgICB0aGlzLl9hbm5vdGF0aW9uUHJvbWlzZXMuY2xlYXIoKTtcblxuICAgIHRoaXMuX2pzQWN0aW9uc1Byb21pc2UgPSBudWxsO1xuICAgIHRoaXMuX3N0cnVjdFRyZWVQcm9taXNlID0gbnVsbDtcblxuICAgIGlmIChyZXNldFN0YXRzICYmIHRoaXMuX3N0YXRzKSB7XG4gICAgICB0aGlzLl9zdGF0cyA9IG5ldyBfZGlzcGxheV91dGlscy5TdGF0VGltZXIoKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGJpdG1hcCBvZiB0aGlzLl9iaXRtYXBzKSB7XG4gICAgICBiaXRtYXAuY2xvc2UoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9iaXRtYXBzLmNsZWFyKCk7XG5cbiAgICB0aGlzLnBlbmRpbmdDbGVhbnVwID0gZmFsc2U7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBfc3RhcnRSZW5kZXJQYWdlKHRyYW5zcGFyZW5jeSwgY2FjaGVLZXkpIHtcbiAgICBjb25zdCBpbnRlbnRTdGF0ZSA9IHRoaXMuX2ludGVudFN0YXRlcy5nZXQoY2FjaGVLZXkpO1xuXG4gICAgaWYgKCFpbnRlbnRTdGF0ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9zdGF0cykge1xuICAgICAgdGhpcy5fc3RhdHMudGltZUVuZChcIlBhZ2UgUmVxdWVzdFwiKTtcbiAgICB9XG5cbiAgICBpZiAoaW50ZW50U3RhdGUuZGlzcGxheVJlYWR5Q2FwYWJpbGl0eSkge1xuICAgICAgaW50ZW50U3RhdGUuZGlzcGxheVJlYWR5Q2FwYWJpbGl0eS5yZXNvbHZlKHRyYW5zcGFyZW5jeSk7XG4gICAgfVxuICB9XG5cbiAgX3JlbmRlclBhZ2VDaHVuayhvcGVyYXRvckxpc3RDaHVuaywgaW50ZW50U3RhdGUpIHtcbiAgICBmb3IgKGxldCBpID0gMCwgaWkgPSBvcGVyYXRvckxpc3RDaHVuay5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICBpbnRlbnRTdGF0ZS5vcGVyYXRvckxpc3QuZm5BcnJheS5wdXNoKG9wZXJhdG9yTGlzdENodW5rLmZuQXJyYXlbaV0pO1xuICAgICAgaW50ZW50U3RhdGUub3BlcmF0b3JMaXN0LmFyZ3NBcnJheS5wdXNoKG9wZXJhdG9yTGlzdENodW5rLmFyZ3NBcnJheVtpXSk7XG4gICAgfVxuXG4gICAgaW50ZW50U3RhdGUub3BlcmF0b3JMaXN0Lmxhc3RDaHVuayA9IG9wZXJhdG9yTGlzdENodW5rLmxhc3RDaHVuaztcblxuICAgIGZvciAoY29uc3QgaW50ZXJuYWxSZW5kZXJUYXNrIG9mIGludGVudFN0YXRlLnJlbmRlclRhc2tzKSB7XG4gICAgICBpbnRlcm5hbFJlbmRlclRhc2sub3BlcmF0b3JMaXN0Q2hhbmdlZCgpO1xuICAgIH1cblxuICAgIGlmIChvcGVyYXRvckxpc3RDaHVuay5sYXN0Q2h1bmspIHtcbiAgICAgIHRoaXMuX3RyeUNsZWFudXAoKTtcbiAgICB9XG4gIH1cblxuICBfcHVtcE9wZXJhdG9yTGlzdCh7XG4gICAgcmVuZGVyaW5nSW50ZW50LFxuICAgIGNhY2hlS2V5XG4gIH0pIHtcbiAgICBjb25zdCByZWFkYWJsZVN0cmVhbSA9IHRoaXMuX3RyYW5zcG9ydC5tZXNzYWdlSGFuZGxlci5zZW5kV2l0aFN0cmVhbShcIkdldE9wZXJhdG9yTGlzdFwiLCB7XG4gICAgICBwYWdlSW5kZXg6IHRoaXMuX3BhZ2VJbmRleCxcbiAgICAgIGludGVudDogcmVuZGVyaW5nSW50ZW50LFxuICAgICAgY2FjaGVLZXksXG4gICAgICBhbm5vdGF0aW9uU3RvcmFnZTogcmVuZGVyaW5nSW50ZW50ICYgX3V0aWwuUmVuZGVyaW5nSW50ZW50RmxhZy5BTk5PVEFUSU9OU19TVE9SQUdFID8gdGhpcy5fdHJhbnNwb3J0LmFubm90YXRpb25TdG9yYWdlLnNlcmlhbGl6YWJsZSA6IG51bGxcbiAgICB9KTtcblxuICAgIGNvbnN0IHJlYWRlciA9IHJlYWRhYmxlU3RyZWFtLmdldFJlYWRlcigpO1xuXG4gICAgY29uc3QgaW50ZW50U3RhdGUgPSB0aGlzLl9pbnRlbnRTdGF0ZXMuZ2V0KGNhY2hlS2V5KTtcblxuICAgIGludGVudFN0YXRlLnN0cmVhbVJlYWRlciA9IHJlYWRlcjtcblxuICAgIGNvbnN0IHB1bXAgPSAoKSA9PiB7XG4gICAgICByZWFkZXIucmVhZCgpLnRoZW4oKHtcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIGRvbmVcbiAgICAgIH0pID0+IHtcbiAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICBpbnRlbnRTdGF0ZS5zdHJlYW1SZWFkZXIgPSBudWxsO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl90cmFuc3BvcnQuZGVzdHJveWVkKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fcmVuZGVyUGFnZUNodW5rKHZhbHVlLCBpbnRlbnRTdGF0ZSk7XG5cbiAgICAgICAgcHVtcCgpO1xuICAgICAgfSwgcmVhc29uID0+IHtcbiAgICAgICAgaW50ZW50U3RhdGUuc3RyZWFtUmVhZGVyID0gbnVsbDtcblxuICAgICAgICBpZiAodGhpcy5fdHJhbnNwb3J0LmRlc3Ryb3llZCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbnRlbnRTdGF0ZS5vcGVyYXRvckxpc3QpIHtcbiAgICAgICAgICBpbnRlbnRTdGF0ZS5vcGVyYXRvckxpc3QubGFzdENodW5rID0gdHJ1ZTtcblxuICAgICAgICAgIGZvciAoY29uc3QgaW50ZXJuYWxSZW5kZXJUYXNrIG9mIGludGVudFN0YXRlLnJlbmRlclRhc2tzKSB7XG4gICAgICAgICAgICBpbnRlcm5hbFJlbmRlclRhc2sub3BlcmF0b3JMaXN0Q2hhbmdlZCgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuX3RyeUNsZWFudXAoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbnRlbnRTdGF0ZS5kaXNwbGF5UmVhZHlDYXBhYmlsaXR5KSB7XG4gICAgICAgICAgaW50ZW50U3RhdGUuZGlzcGxheVJlYWR5Q2FwYWJpbGl0eS5yZWplY3QocmVhc29uKTtcbiAgICAgICAgfSBlbHNlIGlmIChpbnRlbnRTdGF0ZS5vcExpc3RSZWFkQ2FwYWJpbGl0eSkge1xuICAgICAgICAgIGludGVudFN0YXRlLm9wTGlzdFJlYWRDYXBhYmlsaXR5LnJlamVjdChyZWFzb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IHJlYXNvbjtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIHB1bXAoKTtcbiAgfVxuXG4gIF9hYm9ydE9wZXJhdG9yTGlzdCh7XG4gICAgaW50ZW50U3RhdGUsXG4gICAgcmVhc29uLFxuICAgIGZvcmNlID0gZmFsc2VcbiAgfSkge1xuICAgIGlmICghaW50ZW50U3RhdGUuc3RyZWFtUmVhZGVyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFmb3JjZSkge1xuICAgICAgaWYgKGludGVudFN0YXRlLnJlbmRlclRhc2tzLnNpemUgPiAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlYXNvbiBpbnN0YW5jZW9mIF9kaXNwbGF5X3V0aWxzLlJlbmRlcmluZ0NhbmNlbGxlZEV4Y2VwdGlvbikge1xuICAgICAgICBpbnRlbnRTdGF0ZS5zdHJlYW1SZWFkZXJDYW5jZWxUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5fYWJvcnRPcGVyYXRvckxpc3Qoe1xuICAgICAgICAgICAgaW50ZW50U3RhdGUsXG4gICAgICAgICAgICByZWFzb24sXG4gICAgICAgICAgICBmb3JjZTogdHJ1ZVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaW50ZW50U3RhdGUuc3RyZWFtUmVhZGVyQ2FuY2VsVGltZW91dCA9IG51bGw7XG4gICAgICAgIH0sIFJFTkRFUklOR19DQU5DRUxMRURfVElNRU9VVCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpbnRlbnRTdGF0ZS5zdHJlYW1SZWFkZXIuY2FuY2VsKG5ldyBfdXRpbC5BYm9ydEV4Y2VwdGlvbihyZWFzb24ubWVzc2FnZSkpLmNhdGNoKCgpID0+IHt9KTtcbiAgICBpbnRlbnRTdGF0ZS5zdHJlYW1SZWFkZXIgPSBudWxsO1xuXG4gICAgaWYgKHRoaXMuX3RyYW5zcG9ydC5kZXN0cm95ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IFtjdXJDYWNoZUtleSwgY3VySW50ZW50U3RhdGVdIG9mIHRoaXMuX2ludGVudFN0YXRlcykge1xuICAgICAgaWYgKGN1ckludGVudFN0YXRlID09PSBpbnRlbnRTdGF0ZSkge1xuICAgICAgICB0aGlzLl9pbnRlbnRTdGF0ZXMuZGVsZXRlKGN1ckNhY2hlS2V5KTtcblxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmNsZWFudXAoKTtcbiAgfVxuXG4gIGdldCBzdGF0cygpIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdHM7XG4gIH1cblxufVxuXG5leHBvcnRzLlBERlBhZ2VQcm94eSA9IFBERlBhZ2VQcm94eTtcblxuY2xhc3MgTG9vcGJhY2tQb3J0IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5fbGlzdGVuZXJzID0gW107XG4gICAgdGhpcy5fZGVmZXJyZWQgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIHBvc3RNZXNzYWdlKG9iaiwgdHJhbnNmZXJzKSB7XG4gICAgY29uc3QgZXZlbnQgPSB7XG4gICAgICBkYXRhOiBzdHJ1Y3R1cmVkQ2xvbmUob2JqLCB0cmFuc2ZlcnMpXG4gICAgfTtcblxuICAgIHRoaXMuX2RlZmVycmVkLnRoZW4oKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBsaXN0ZW5lciBvZiB0aGlzLl9saXN0ZW5lcnMpIHtcbiAgICAgICAgbGlzdGVuZXIuY2FsbCh0aGlzLCBldmVudCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBhZGRFdmVudExpc3RlbmVyKG5hbWUsIGxpc3RlbmVyKSB7XG4gICAgdGhpcy5fbGlzdGVuZXJzLnB1c2gobGlzdGVuZXIpO1xuICB9XG5cbiAgcmVtb3ZlRXZlbnRMaXN0ZW5lcihuYW1lLCBsaXN0ZW5lcikge1xuICAgIGNvbnN0IGkgPSB0aGlzLl9saXN0ZW5lcnMuaW5kZXhPZihsaXN0ZW5lcik7XG5cbiAgICB0aGlzLl9saXN0ZW5lcnMuc3BsaWNlKGksIDEpO1xuICB9XG5cbiAgdGVybWluYXRlKCkge1xuICAgIHRoaXMuX2xpc3RlbmVycy5sZW5ndGggPSAwO1xuICB9XG5cbn1cblxuZXhwb3J0cy5Mb29wYmFja1BvcnQgPSBMb29wYmFja1BvcnQ7XG5jb25zdCBQREZXb3JrZXJVdGlsID0ge1xuICBpc1dvcmtlckRpc2FibGVkOiBmYWxzZSxcbiAgZmFsbGJhY2tXb3JrZXJTcmM6IG51bGwsXG4gIGZha2VXb3JrZXJJZDogMFxufTtcbmV4cG9ydHMuUERGV29ya2VyVXRpbCA9IFBERldvcmtlclV0aWw7XG57XG4gIGlmIChfaXNfbm9kZS5pc05vZGVKUyAmJiB0eXBlb2YgcmVxdWlyZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgUERGV29ya2VyVXRpbC5pc1dvcmtlckRpc2FibGVkID0gdHJ1ZTtcbiAgICBQREZXb3JrZXJVdGlsLmZhbGxiYWNrV29ya2VyU3JjID0gXCIuL3BkZi53b3JrZXIuanNcIjtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09IFwib2JqZWN0XCIpIHtcbiAgICBjb25zdCBwZGZqc0ZpbGVQYXRoID0gZG9jdW1lbnQ/LmN1cnJlbnRTY3JpcHQ/LnNyYztcblxuICAgIGlmIChwZGZqc0ZpbGVQYXRoKSB7XG4gICAgICBQREZXb3JrZXJVdGlsLmZhbGxiYWNrV29ya2VyU3JjID0gcGRmanNGaWxlUGF0aC5yZXBsYWNlKC8oXFwuKD86bWluXFwuKT9qcykoXFw/LiopPyQvaSwgXCIud29ya2VyJDEkMlwiKTtcbiAgICB9XG4gIH1cblxuICBQREZXb3JrZXJVdGlsLmlzU2FtZU9yaWdpbiA9IGZ1bmN0aW9uIChiYXNlVXJsLCBvdGhlclVybCkge1xuICAgIGxldCBiYXNlO1xuXG4gICAgdHJ5IHtcbiAgICAgIGJhc2UgPSBuZXcgVVJMKGJhc2VVcmwpO1xuXG4gICAgICBpZiAoIWJhc2Uub3JpZ2luIHx8IGJhc2Uub3JpZ2luID09PSBcIm51bGxcIikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IG90aGVyID0gbmV3IFVSTChvdGhlclVybCwgYmFzZSk7XG4gICAgcmV0dXJuIGJhc2Uub3JpZ2luID09PSBvdGhlci5vcmlnaW47XG4gIH07XG5cbiAgUERGV29ya2VyVXRpbC5jcmVhdGVDRE5XcmFwcGVyID0gZnVuY3Rpb24gKHVybCkge1xuICAgIGNvbnN0IHdyYXBwZXIgPSBgaW1wb3J0U2NyaXB0cyhcIiR7dXJsfVwiKTtgO1xuICAgIHJldHVybiBVUkwuY3JlYXRlT2JqZWN0VVJMKG5ldyBCbG9iKFt3cmFwcGVyXSkpO1xuICB9O1xufVxuXG5jbGFzcyBQREZXb3JrZXIge1xuICBzdGF0aWMgI3dvcmtlclBvcnRzID0gbmV3IFdlYWtNYXAoKTtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgbmFtZSA9IG51bGwsXG4gICAgcG9ydCA9IG51bGwsXG4gICAgdmVyYm9zaXR5ID0gKDAsIF91dGlsLmdldFZlcmJvc2l0eUxldmVsKSgpXG4gIH0gPSB7fSkge1xuICAgIGlmIChwb3J0ICYmIFBERldvcmtlci4jd29ya2VyUG9ydHMuaGFzKHBvcnQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgdXNlIG1vcmUgdGhhbiBvbmUgUERGV29ya2VyIHBlciBwb3J0LlwiKTtcbiAgICB9XG5cbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIHRoaXMuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgdGhpcy52ZXJib3NpdHkgPSB2ZXJib3NpdHk7XG4gICAgdGhpcy5fcmVhZHlDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgIHRoaXMuX3BvcnQgPSBudWxsO1xuICAgIHRoaXMuX3dlYldvcmtlciA9IG51bGw7XG4gICAgdGhpcy5fbWVzc2FnZUhhbmRsZXIgPSBudWxsO1xuXG4gICAgaWYgKHBvcnQpIHtcbiAgICAgIFBERldvcmtlci4jd29ya2VyUG9ydHMuc2V0KHBvcnQsIHRoaXMpO1xuXG4gICAgICB0aGlzLl9pbml0aWFsaXplRnJvbVBvcnQocG9ydCk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9pbml0aWFsaXplKCk7XG4gIH1cblxuICBnZXQgcHJvbWlzZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fcmVhZHlDYXBhYmlsaXR5LnByb21pc2U7XG4gIH1cblxuICBnZXQgcG9ydCgpIHtcbiAgICByZXR1cm4gdGhpcy5fcG9ydDtcbiAgfVxuXG4gIGdldCBtZXNzYWdlSGFuZGxlcigpIHtcbiAgICByZXR1cm4gdGhpcy5fbWVzc2FnZUhhbmRsZXI7XG4gIH1cblxuICBfaW5pdGlhbGl6ZUZyb21Qb3J0KHBvcnQpIHtcbiAgICB0aGlzLl9wb3J0ID0gcG9ydDtcbiAgICB0aGlzLl9tZXNzYWdlSGFuZGxlciA9IG5ldyBfbWVzc2FnZV9oYW5kbGVyLk1lc3NhZ2VIYW5kbGVyKFwibWFpblwiLCBcIndvcmtlclwiLCBwb3J0KTtcblxuICAgIHRoaXMuX21lc3NhZ2VIYW5kbGVyLm9uKFwicmVhZHlcIiwgZnVuY3Rpb24gKCkge30pO1xuXG4gICAgdGhpcy5fcmVhZHlDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgfVxuXG4gIF9pbml0aWFsaXplKCkge1xuICAgIGlmICh0eXBlb2YgV29ya2VyICE9PSBcInVuZGVmaW5lZFwiICYmICFQREZXb3JrZXJVdGlsLmlzV29ya2VyRGlzYWJsZWQgJiYgIVBERldvcmtlci5fbWFpblRocmVhZFdvcmtlck1lc3NhZ2VIYW5kbGVyKSB7XG4gICAgICBsZXQgd29ya2VyU3JjID0gUERGV29ya2VyLndvcmtlclNyYztcblxuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKCFQREZXb3JrZXJVdGlsLmlzU2FtZU9yaWdpbih3aW5kb3cubG9jYXRpb24uaHJlZiwgd29ya2VyU3JjKSkge1xuICAgICAgICAgIHdvcmtlclNyYyA9IFBERldvcmtlclV0aWwuY3JlYXRlQ0ROV3JhcHBlcihuZXcgVVJMKHdvcmtlclNyYywgd2luZG93LmxvY2F0aW9uKS5ocmVmKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHdvcmtlciA9IG5ldyBXb3JrZXIod29ya2VyU3JjKTtcbiAgICAgICAgY29uc3QgbWVzc2FnZUhhbmRsZXIgPSBuZXcgX21lc3NhZ2VfaGFuZGxlci5NZXNzYWdlSGFuZGxlcihcIm1haW5cIiwgXCJ3b3JrZXJcIiwgd29ya2VyKTtcblxuICAgICAgICBjb25zdCB0ZXJtaW5hdGVFYXJseSA9ICgpID0+IHtcbiAgICAgICAgICB3b3JrZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImVycm9yXCIsIG9uV29ya2VyRXJyb3IpO1xuICAgICAgICAgIG1lc3NhZ2VIYW5kbGVyLmRlc3Ryb3koKTtcbiAgICAgICAgICB3b3JrZXIudGVybWluYXRlKCk7XG5cbiAgICAgICAgICBpZiAodGhpcy5kZXN0cm95ZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3JlYWR5Q2FwYWJpbGl0eS5yZWplY3QobmV3IEVycm9yKFwiV29ya2VyIHdhcyBkZXN0cm95ZWRcIikpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9zZXR1cEZha2VXb3JrZXIoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3Qgb25Xb3JrZXJFcnJvciA9ICgpID0+IHtcbiAgICAgICAgICBpZiAoIXRoaXMuX3dlYldvcmtlcikge1xuICAgICAgICAgICAgdGVybWluYXRlRWFybHkoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgd29ya2VyLmFkZEV2ZW50TGlzdGVuZXIoXCJlcnJvclwiLCBvbldvcmtlckVycm9yKTtcbiAgICAgICAgbWVzc2FnZUhhbmRsZXIub24oXCJ0ZXN0XCIsIGRhdGEgPT4ge1xuICAgICAgICAgIHdvcmtlci5yZW1vdmVFdmVudExpc3RlbmVyKFwiZXJyb3JcIiwgb25Xb3JrZXJFcnJvcik7XG5cbiAgICAgICAgICBpZiAodGhpcy5kZXN0cm95ZWQpIHtcbiAgICAgICAgICAgIHRlcm1pbmF0ZUVhcmx5KCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICAgIHRoaXMuX21lc3NhZ2VIYW5kbGVyID0gbWVzc2FnZUhhbmRsZXI7XG4gICAgICAgICAgICB0aGlzLl9wb3J0ID0gd29ya2VyO1xuICAgICAgICAgICAgdGhpcy5fd2ViV29ya2VyID0gd29ya2VyO1xuXG4gICAgICAgICAgICB0aGlzLl9yZWFkeUNhcGFiaWxpdHkucmVzb2x2ZSgpO1xuXG4gICAgICAgICAgICBtZXNzYWdlSGFuZGxlci5zZW5kKFwiY29uZmlndXJlXCIsIHtcbiAgICAgICAgICAgICAgdmVyYm9zaXR5OiB0aGlzLnZlcmJvc2l0eVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3NldHVwRmFrZVdvcmtlcigpO1xuXG4gICAgICAgICAgICBtZXNzYWdlSGFuZGxlci5kZXN0cm95KCk7XG4gICAgICAgICAgICB3b3JrZXIudGVybWluYXRlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgbWVzc2FnZUhhbmRsZXIub24oXCJyZWFkeVwiLCBkYXRhID0+IHtcbiAgICAgICAgICB3b3JrZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImVycm9yXCIsIG9uV29ya2VyRXJyb3IpO1xuXG4gICAgICAgICAgaWYgKHRoaXMuZGVzdHJveWVkKSB7XG4gICAgICAgICAgICB0ZXJtaW5hdGVFYXJseSgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzZW5kVGVzdCgpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRoaXMuX3NldHVwRmFrZVdvcmtlcigpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qgc2VuZFRlc3QgPSAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgdGVzdE9iaiA9IG5ldyBVaW50OEFycmF5KCk7XG4gICAgICAgICAgbWVzc2FnZUhhbmRsZXIuc2VuZChcInRlc3RcIiwgdGVzdE9iaiwgW3Rlc3RPYmouYnVmZmVyXSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgc2VuZFRlc3QoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAoMCwgX3V0aWwuaW5mbykoXCJUaGUgd29ya2VyIGhhcyBiZWVuIGRpc2FibGVkLlwiKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9zZXR1cEZha2VXb3JrZXIoKTtcbiAgfVxuXG4gIF9zZXR1cEZha2VXb3JrZXIoKSB7XG4gICAgaWYgKCFQREZXb3JrZXJVdGlsLmlzV29ya2VyRGlzYWJsZWQpIHtcbiAgICAgICgwLCBfdXRpbC53YXJuKShcIlNldHRpbmcgdXAgZmFrZSB3b3JrZXIuXCIpO1xuICAgICAgUERGV29ya2VyVXRpbC5pc1dvcmtlckRpc2FibGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBQREZXb3JrZXIuX3NldHVwRmFrZVdvcmtlckdsb2JhbC50aGVuKFdvcmtlck1lc3NhZ2VIYW5kbGVyID0+IHtcbiAgICAgIGlmICh0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgICB0aGlzLl9yZWFkeUNhcGFiaWxpdHkucmVqZWN0KG5ldyBFcnJvcihcIldvcmtlciB3YXMgZGVzdHJveWVkXCIpKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBvcnQgPSBuZXcgTG9vcGJhY2tQb3J0KCk7XG4gICAgICB0aGlzLl9wb3J0ID0gcG9ydDtcbiAgICAgIGNvbnN0IGlkID0gYGZha2Uke1BERldvcmtlclV0aWwuZmFrZVdvcmtlcklkKyt9YDtcbiAgICAgIGNvbnN0IHdvcmtlckhhbmRsZXIgPSBuZXcgX21lc3NhZ2VfaGFuZGxlci5NZXNzYWdlSGFuZGxlcihpZCArIFwiX3dvcmtlclwiLCBpZCwgcG9ydCk7XG4gICAgICBXb3JrZXJNZXNzYWdlSGFuZGxlci5zZXR1cCh3b3JrZXJIYW5kbGVyLCBwb3J0KTtcbiAgICAgIGNvbnN0IG1lc3NhZ2VIYW5kbGVyID0gbmV3IF9tZXNzYWdlX2hhbmRsZXIuTWVzc2FnZUhhbmRsZXIoaWQsIGlkICsgXCJfd29ya2VyXCIsIHBvcnQpO1xuICAgICAgdGhpcy5fbWVzc2FnZUhhbmRsZXIgPSBtZXNzYWdlSGFuZGxlcjtcblxuICAgICAgdGhpcy5fcmVhZHlDYXBhYmlsaXR5LnJlc29sdmUoKTtcblxuICAgICAgbWVzc2FnZUhhbmRsZXIuc2VuZChcImNvbmZpZ3VyZVwiLCB7XG4gICAgICAgIHZlcmJvc2l0eTogdGhpcy52ZXJib3NpdHlcbiAgICAgIH0pO1xuICAgIH0pLmNhdGNoKHJlYXNvbiA9PiB7XG4gICAgICB0aGlzLl9yZWFkeUNhcGFiaWxpdHkucmVqZWN0KG5ldyBFcnJvcihgU2V0dGluZyB1cCBmYWtlIHdvcmtlciBmYWlsZWQ6IFwiJHtyZWFzb24ubWVzc2FnZX1cIi5gKSk7XG4gICAgfSk7XG4gIH1cblxuICBkZXN0cm95KCkge1xuICAgIHRoaXMuZGVzdHJveWVkID0gdHJ1ZTtcblxuICAgIGlmICh0aGlzLl93ZWJXb3JrZXIpIHtcbiAgICAgIHRoaXMuX3dlYldvcmtlci50ZXJtaW5hdGUoKTtcblxuICAgICAgdGhpcy5fd2ViV29ya2VyID0gbnVsbDtcbiAgICB9XG5cbiAgICBQREZXb3JrZXIuI3dvcmtlclBvcnRzLmRlbGV0ZSh0aGlzLl9wb3J0KTtcbiAgICB0aGlzLl9wb3J0ID0gbnVsbDtcblxuICAgIGlmICh0aGlzLl9tZXNzYWdlSGFuZGxlcikge1xuICAgICAgdGhpcy5fbWVzc2FnZUhhbmRsZXIuZGVzdHJveSgpO1xuXG4gICAgICB0aGlzLl9tZXNzYWdlSGFuZGxlciA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGZyb21Qb3J0KHBhcmFtcykge1xuICAgIGlmICghcGFyYW1zPy5wb3J0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJQREZXb3JrZXIuZnJvbVBvcnQgLSBpbnZhbGlkIG1ldGhvZCBzaWduYXR1cmUuXCIpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLiN3b3JrZXJQb3J0cy5oYXMocGFyYW1zLnBvcnQpKSB7XG4gICAgICByZXR1cm4gdGhpcy4jd29ya2VyUG9ydHMuZ2V0KHBhcmFtcy5wb3J0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFBERldvcmtlcihwYXJhbXMpO1xuICB9XG5cbiAgc3RhdGljIGdldCB3b3JrZXJTcmMoKSB7XG4gICAgaWYgKF93b3JrZXJfb3B0aW9ucy5HbG9iYWxXb3JrZXJPcHRpb25zLndvcmtlclNyYykge1xuICAgICAgcmV0dXJuIF93b3JrZXJfb3B0aW9ucy5HbG9iYWxXb3JrZXJPcHRpb25zLndvcmtlclNyYztcbiAgICB9XG5cbiAgICBpZiAoUERGV29ya2VyVXRpbC5mYWxsYmFja1dvcmtlclNyYyAhPT0gbnVsbCkge1xuICAgICAgaWYgKCFfaXNfbm9kZS5pc05vZGVKUykge1xuICAgICAgICAoMCwgX2Rpc3BsYXlfdXRpbHMuZGVwcmVjYXRlZCkoJ05vIFwiR2xvYmFsV29ya2VyT3B0aW9ucy53b3JrZXJTcmNcIiBzcGVjaWZpZWQuJyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBQREZXb3JrZXJVdGlsLmZhbGxiYWNrV29ya2VyU3JjO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcignTm8gXCJHbG9iYWxXb3JrZXJPcHRpb25zLndvcmtlclNyY1wiIHNwZWNpZmllZC4nKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgX21haW5UaHJlYWRXb3JrZXJNZXNzYWdlSGFuZGxlcigpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGdsb2JhbFRoaXMucGRmanNXb3JrZXI/Lldvcmtlck1lc3NhZ2VIYW5kbGVyIHx8IG51bGw7XG4gICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBnZXQgX3NldHVwRmFrZVdvcmtlckdsb2JhbCgpIHtcbiAgICBjb25zdCBsb2FkZXIgPSBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBtYWluV29ya2VyTWVzc2FnZUhhbmRsZXIgPSB0aGlzLl9tYWluVGhyZWFkV29ya2VyTWVzc2FnZUhhbmRsZXI7XG5cbiAgICAgIGlmIChtYWluV29ya2VyTWVzc2FnZUhhbmRsZXIpIHtcbiAgICAgICAgcmV0dXJuIG1haW5Xb3JrZXJNZXNzYWdlSGFuZGxlcjtcbiAgICAgIH1cblxuICAgICAgaWYgKF9pc19ub2RlLmlzTm9kZUpTICYmIHR5cGVvZiByZXF1aXJlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgY29uc3Qgd29ya2VyID0gZXZhbChcInJlcXVpcmVcIikodGhpcy53b3JrZXJTcmMpO1xuICAgICAgICByZXR1cm4gd29ya2VyLldvcmtlck1lc3NhZ2VIYW5kbGVyO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCAoMCwgX2Rpc3BsYXlfdXRpbHMubG9hZFNjcmlwdCkodGhpcy53b3JrZXJTcmMpO1xuICAgICAgcmV0dXJuIHdpbmRvdy5wZGZqc1dvcmtlci5Xb3JrZXJNZXNzYWdlSGFuZGxlcjtcbiAgICB9O1xuXG4gICAgcmV0dXJuICgwLCBfdXRpbC5zaGFkb3cpKHRoaXMsIFwiX3NldHVwRmFrZVdvcmtlckdsb2JhbFwiLCBsb2FkZXIoKSk7XG4gIH1cblxufVxuXG5leHBvcnRzLlBERldvcmtlciA9IFBERldvcmtlcjtcbntcbiAgUERGV29ya2VyLmdldFdvcmtlclNyYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAoMCwgX2Rpc3BsYXlfdXRpbHMuZGVwcmVjYXRlZCkoXCJgUERGV29ya2VyLmdldFdvcmtlclNyYygpYCwgcGxlYXNlIHVzZSBgUERGV29ya2VyLndvcmtlclNyY2AgaW5zdGVhZC5cIik7XG4gICAgcmV0dXJuIHRoaXMud29ya2VyU3JjO1xuICB9O1xufVxuXG5jbGFzcyBXb3JrZXJUcmFuc3BvcnQge1xuICAjZG9jU3RhdHMgPSBudWxsO1xuICAjcGFnZUNhY2hlID0gbmV3IE1hcCgpO1xuICAjcGFnZVByb21pc2VzID0gbmV3IE1hcCgpO1xuICAjbWV0YWRhdGFQcm9taXNlID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcihtZXNzYWdlSGFuZGxlciwgbG9hZGluZ1Rhc2ssIG5ldHdvcmtTdHJlYW0sIHBhcmFtcykge1xuICAgIHRoaXMubWVzc2FnZUhhbmRsZXIgPSBtZXNzYWdlSGFuZGxlcjtcbiAgICB0aGlzLmxvYWRpbmdUYXNrID0gbG9hZGluZ1Rhc2s7XG4gICAgdGhpcy5jb21tb25PYmpzID0gbmV3IFBERk9iamVjdHMoKTtcbiAgICB0aGlzLmZvbnRMb2FkZXIgPSBuZXcgX2ZvbnRfbG9hZGVyLkZvbnRMb2FkZXIoe1xuICAgICAgZG9jSWQ6IGxvYWRpbmdUYXNrLmRvY0lkLFxuICAgICAgb25VbnN1cHBvcnRlZEZlYXR1cmU6IHRoaXMuX29uVW5zdXBwb3J0ZWRGZWF0dXJlLmJpbmQodGhpcyksXG4gICAgICBvd25lckRvY3VtZW50OiBwYXJhbXMub3duZXJEb2N1bWVudCxcbiAgICAgIHN0eWxlRWxlbWVudDogcGFyYW1zLnN0eWxlRWxlbWVudFxuICAgIH0pO1xuICAgIHRoaXMuX3BhcmFtcyA9IHBhcmFtcztcblxuICAgIGlmICghcGFyYW1zLnVzZVdvcmtlckZldGNoKSB7XG4gICAgICB0aGlzLkNNYXBSZWFkZXJGYWN0b3J5ID0gbmV3IHBhcmFtcy5DTWFwUmVhZGVyRmFjdG9yeSh7XG4gICAgICAgIGJhc2VVcmw6IHBhcmFtcy5jTWFwVXJsLFxuICAgICAgICBpc0NvbXByZXNzZWQ6IHBhcmFtcy5jTWFwUGFja2VkXG4gICAgICB9KTtcbiAgICAgIHRoaXMuU3RhbmRhcmRGb250RGF0YUZhY3RvcnkgPSBuZXcgcGFyYW1zLlN0YW5kYXJkRm9udERhdGFGYWN0b3J5KHtcbiAgICAgICAgYmFzZVVybDogcGFyYW1zLnN0YW5kYXJkRm9udERhdGFVcmxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgdGhpcy5kZXN0cm95Q2FwYWJpbGl0eSA9IG51bGw7XG4gICAgdGhpcy5fcGFzc3dvcmRDYXBhYmlsaXR5ID0gbnVsbDtcbiAgICB0aGlzLl9uZXR3b3JrU3RyZWFtID0gbmV0d29ya1N0cmVhbTtcbiAgICB0aGlzLl9mdWxsUmVhZGVyID0gbnVsbDtcbiAgICB0aGlzLl9sYXN0UHJvZ3Jlc3MgPSBudWxsO1xuICAgIHRoaXMuZG93bmxvYWRJbmZvQ2FwYWJpbGl0eSA9ICgwLCBfdXRpbC5jcmVhdGVQcm9taXNlQ2FwYWJpbGl0eSkoKTtcbiAgICB0aGlzLnNldHVwTWVzc2FnZUhhbmRsZXIoKTtcbiAgfVxuXG4gIGdldCBhbm5vdGF0aW9uU3RvcmFnZSgpIHtcbiAgICByZXR1cm4gKDAsIF91dGlsLnNoYWRvdykodGhpcywgXCJhbm5vdGF0aW9uU3RvcmFnZVwiLCBuZXcgX2Fubm90YXRpb25fc3RvcmFnZS5Bbm5vdGF0aW9uU3RvcmFnZSgpKTtcbiAgfVxuXG4gIGdldCBzdGF0cygpIHtcbiAgICByZXR1cm4gdGhpcy4jZG9jU3RhdHM7XG4gIH1cblxuICBnZXRSZW5kZXJpbmdJbnRlbnQoaW50ZW50LCBhbm5vdGF0aW9uTW9kZSA9IF91dGlsLkFubm90YXRpb25Nb2RlLkVOQUJMRSwgaXNPcExpc3QgPSBmYWxzZSkge1xuICAgIGxldCByZW5kZXJpbmdJbnRlbnQgPSBfdXRpbC5SZW5kZXJpbmdJbnRlbnRGbGFnLkRJU1BMQVk7XG4gICAgbGV0IGFubm90YXRpb25IYXNoID0gXCJcIjtcblxuICAgIHN3aXRjaCAoaW50ZW50KSB7XG4gICAgICBjYXNlIFwiYW55XCI6XG4gICAgICAgIHJlbmRlcmluZ0ludGVudCA9IF91dGlsLlJlbmRlcmluZ0ludGVudEZsYWcuQU5ZO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcImRpc3BsYXlcIjpcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgXCJwcmludFwiOlxuICAgICAgICByZW5kZXJpbmdJbnRlbnQgPSBfdXRpbC5SZW5kZXJpbmdJbnRlbnRGbGFnLlBSSU5UO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgKDAsIF91dGlsLndhcm4pKGBnZXRSZW5kZXJpbmdJbnRlbnQgLSBpbnZhbGlkIGludGVudDogJHtpbnRlbnR9YCk7XG4gICAgfVxuXG4gICAgc3dpdGNoIChhbm5vdGF0aW9uTW9kZSkge1xuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uTW9kZS5ESVNBQkxFOlxuICAgICAgICByZW5kZXJpbmdJbnRlbnQgKz0gX3V0aWwuUmVuZGVyaW5nSW50ZW50RmxhZy5BTk5PVEFUSU9OU19ESVNBQkxFO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uTW9kZS5FTkFCTEU6XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIF91dGlsLkFubm90YXRpb25Nb2RlLkVOQUJMRV9GT1JNUzpcbiAgICAgICAgcmVuZGVyaW5nSW50ZW50ICs9IF91dGlsLlJlbmRlcmluZ0ludGVudEZsYWcuQU5OT1RBVElPTlNfRk9STVM7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIF91dGlsLkFubm90YXRpb25Nb2RlLkVOQUJMRV9TVE9SQUdFOlxuICAgICAgICByZW5kZXJpbmdJbnRlbnQgKz0gX3V0aWwuUmVuZGVyaW5nSW50ZW50RmxhZy5BTk5PVEFUSU9OU19TVE9SQUdFO1xuICAgICAgICBhbm5vdGF0aW9uSGFzaCA9IHRoaXMuYW5ub3RhdGlvblN0b3JhZ2UuaGFzaDtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgICgwLCBfdXRpbC53YXJuKShgZ2V0UmVuZGVyaW5nSW50ZW50IC0gaW52YWxpZCBhbm5vdGF0aW9uTW9kZTogJHthbm5vdGF0aW9uTW9kZX1gKTtcbiAgICB9XG5cbiAgICBpZiAoaXNPcExpc3QpIHtcbiAgICAgIHJlbmRlcmluZ0ludGVudCArPSBfdXRpbC5SZW5kZXJpbmdJbnRlbnRGbGFnLk9QTElTVDtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcmVuZGVyaW5nSW50ZW50LFxuICAgICAgY2FjaGVLZXk6IGAke3JlbmRlcmluZ0ludGVudH1fJHthbm5vdGF0aW9uSGFzaH1gXG4gICAgfTtcbiAgfVxuXG4gIGRlc3Ryb3koKSB7XG4gICAgaWYgKHRoaXMuZGVzdHJveUNhcGFiaWxpdHkpIHtcbiAgICAgIHJldHVybiB0aGlzLmRlc3Ryb3lDYXBhYmlsaXR5LnByb21pc2U7XG4gICAgfVxuXG4gICAgdGhpcy5kZXN0cm95ZWQgPSB0cnVlO1xuICAgIHRoaXMuZGVzdHJveUNhcGFiaWxpdHkgPSAoMCwgX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkpKCk7XG5cbiAgICBpZiAodGhpcy5fcGFzc3dvcmRDYXBhYmlsaXR5KSB7XG4gICAgICB0aGlzLl9wYXNzd29yZENhcGFiaWxpdHkucmVqZWN0KG5ldyBFcnJvcihcIldvcmtlciB3YXMgZGVzdHJveWVkIGR1cmluZyBvblBhc3N3b3JkIGNhbGxiYWNrXCIpKTtcbiAgICB9XG5cbiAgICBjb25zdCB3YWl0T24gPSBbXTtcblxuICAgIGZvciAoY29uc3QgcGFnZSBvZiB0aGlzLiNwYWdlQ2FjaGUudmFsdWVzKCkpIHtcbiAgICAgIHdhaXRPbi5wdXNoKHBhZ2UuX2Rlc3Ryb3koKSk7XG4gICAgfVxuXG4gICAgdGhpcy4jcGFnZUNhY2hlLmNsZWFyKCk7XG4gICAgdGhpcy4jcGFnZVByb21pc2VzLmNsZWFyKCk7XG5cbiAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShcImFubm90YXRpb25TdG9yYWdlXCIpKSB7XG4gICAgICB0aGlzLmFubm90YXRpb25TdG9yYWdlLnJlc2V0TW9kaWZpZWQoKTtcbiAgICB9XG5cbiAgICBjb25zdCB0ZXJtaW5hdGVkID0gdGhpcy5tZXNzYWdlSGFuZGxlci5zZW5kV2l0aFByb21pc2UoXCJUZXJtaW5hdGVcIiwgbnVsbCk7XG4gICAgd2FpdE9uLnB1c2godGVybWluYXRlZCk7XG4gICAgUHJvbWlzZS5hbGwod2FpdE9uKS50aGVuKCgpID0+IHtcbiAgICAgIHRoaXMuY29tbW9uT2Jqcy5jbGVhcigpO1xuICAgICAgdGhpcy5mb250TG9hZGVyLmNsZWFyKCk7XG4gICAgICB0aGlzLiNtZXRhZGF0YVByb21pc2UgPSBudWxsO1xuICAgICAgdGhpcy5fZ2V0RmllbGRPYmplY3RzUHJvbWlzZSA9IG51bGw7XG4gICAgICB0aGlzLl9oYXNKU0FjdGlvbnNQcm9taXNlID0gbnVsbDtcblxuICAgICAgaWYgKHRoaXMuX25ldHdvcmtTdHJlYW0pIHtcbiAgICAgICAgdGhpcy5fbmV0d29ya1N0cmVhbS5jYW5jZWxBbGxSZXF1ZXN0cyhuZXcgX3V0aWwuQWJvcnRFeGNlcHRpb24oXCJXb3JrZXIgd2FzIHRlcm1pbmF0ZWQuXCIpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMubWVzc2FnZUhhbmRsZXIpIHtcbiAgICAgICAgdGhpcy5tZXNzYWdlSGFuZGxlci5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMubWVzc2FnZUhhbmRsZXIgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmRlc3Ryb3lDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgICB9LCB0aGlzLmRlc3Ryb3lDYXBhYmlsaXR5LnJlamVjdCk7XG4gICAgcmV0dXJuIHRoaXMuZGVzdHJveUNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxuXG4gIHNldHVwTWVzc2FnZUhhbmRsZXIoKSB7XG4gICAgY29uc3Qge1xuICAgICAgbWVzc2FnZUhhbmRsZXIsXG4gICAgICBsb2FkaW5nVGFza1xuICAgIH0gPSB0aGlzO1xuICAgIG1lc3NhZ2VIYW5kbGVyLm9uKFwiR2V0UmVhZGVyXCIsIChkYXRhLCBzaW5rKSA9PiB7XG4gICAgICAoMCwgX3V0aWwuYXNzZXJ0KSh0aGlzLl9uZXR3b3JrU3RyZWFtLCBcIkdldFJlYWRlciAtIG5vIGBJUERGU3RyZWFtYCBpbnN0YW5jZSBhdmFpbGFibGUuXCIpO1xuICAgICAgdGhpcy5fZnVsbFJlYWRlciA9IHRoaXMuX25ldHdvcmtTdHJlYW0uZ2V0RnVsbFJlYWRlcigpO1xuXG4gICAgICB0aGlzLl9mdWxsUmVhZGVyLm9uUHJvZ3Jlc3MgPSBldnQgPT4ge1xuICAgICAgICB0aGlzLl9sYXN0UHJvZ3Jlc3MgPSB7XG4gICAgICAgICAgbG9hZGVkOiBldnQubG9hZGVkLFxuICAgICAgICAgIHRvdGFsOiBldnQudG90YWxcbiAgICAgICAgfTtcbiAgICAgIH07XG5cbiAgICAgIHNpbmsub25QdWxsID0gKCkgPT4ge1xuICAgICAgICB0aGlzLl9mdWxsUmVhZGVyLnJlYWQoKS50aGVuKGZ1bmN0aW9uICh7XG4gICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgZG9uZVxuICAgICAgICB9KSB7XG4gICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgIHNpbmsuY2xvc2UoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAoMCwgX3V0aWwuYXNzZXJ0KSgoMCwgX3V0aWwuaXNBcnJheUJ1ZmZlcikodmFsdWUpLCBcIkdldFJlYWRlciAtIGV4cGVjdGVkIGFuIEFycmF5QnVmZmVyLlwiKTtcbiAgICAgICAgICBzaW5rLmVucXVldWUobmV3IFVpbnQ4QXJyYXkodmFsdWUpLCAxLCBbdmFsdWVdKTtcbiAgICAgICAgfSkuY2F0Y2gocmVhc29uID0+IHtcbiAgICAgICAgICBzaW5rLmVycm9yKHJlYXNvbik7XG4gICAgICAgIH0pO1xuICAgICAgfTtcblxuICAgICAgc2luay5vbkNhbmNlbCA9IHJlYXNvbiA9PiB7XG4gICAgICAgIHRoaXMuX2Z1bGxSZWFkZXIuY2FuY2VsKHJlYXNvbik7XG5cbiAgICAgICAgc2luay5yZWFkeS5jYXRjaChyZWFkeVJlYXNvbiA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMuZGVzdHJveWVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhyb3cgcmVhZHlSZWFzb247XG4gICAgICAgIH0pO1xuICAgICAgfTtcbiAgICB9KTtcbiAgICBtZXNzYWdlSGFuZGxlci5vbihcIlJlYWRlckhlYWRlcnNSZWFkeVwiLCBkYXRhID0+IHtcbiAgICAgIGNvbnN0IGhlYWRlcnNDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgICAgY29uc3QgZnVsbFJlYWRlciA9IHRoaXMuX2Z1bGxSZWFkZXI7XG4gICAgICBmdWxsUmVhZGVyLmhlYWRlcnNSZWFkeS50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKCFmdWxsUmVhZGVyLmlzU3RyZWFtaW5nU3VwcG9ydGVkIHx8ICFmdWxsUmVhZGVyLmlzUmFuZ2VTdXBwb3J0ZWQpIHtcbiAgICAgICAgICBpZiAodGhpcy5fbGFzdFByb2dyZXNzKSB7XG4gICAgICAgICAgICBsb2FkaW5nVGFzay5vblByb2dyZXNzPy4odGhpcy5fbGFzdFByb2dyZXNzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmdWxsUmVhZGVyLm9uUHJvZ3Jlc3MgPSBldnQgPT4ge1xuICAgICAgICAgICAgbG9hZGluZ1Rhc2sub25Qcm9ncmVzcz8uKHtcbiAgICAgICAgICAgICAgbG9hZGVkOiBldnQubG9hZGVkLFxuICAgICAgICAgICAgICB0b3RhbDogZXZ0LnRvdGFsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgaGVhZGVyc0NhcGFiaWxpdHkucmVzb2x2ZSh7XG4gICAgICAgICAgaXNTdHJlYW1pbmdTdXBwb3J0ZWQ6IGZ1bGxSZWFkZXIuaXNTdHJlYW1pbmdTdXBwb3J0ZWQsXG4gICAgICAgICAgaXNSYW5nZVN1cHBvcnRlZDogZnVsbFJlYWRlci5pc1JhbmdlU3VwcG9ydGVkLFxuICAgICAgICAgIGNvbnRlbnRMZW5ndGg6IGZ1bGxSZWFkZXIuY29udGVudExlbmd0aFxuICAgICAgICB9KTtcbiAgICAgIH0sIGhlYWRlcnNDYXBhYmlsaXR5LnJlamVjdCk7XG4gICAgICByZXR1cm4gaGVhZGVyc0NhcGFiaWxpdHkucHJvbWlzZTtcbiAgICB9KTtcbiAgICBtZXNzYWdlSGFuZGxlci5vbihcIkdldFJhbmdlUmVhZGVyXCIsIChkYXRhLCBzaW5rKSA9PiB7XG4gICAgICAoMCwgX3V0aWwuYXNzZXJ0KSh0aGlzLl9uZXR3b3JrU3RyZWFtLCBcIkdldFJhbmdlUmVhZGVyIC0gbm8gYElQREZTdHJlYW1gIGluc3RhbmNlIGF2YWlsYWJsZS5cIik7XG5cbiAgICAgIGNvbnN0IHJhbmdlUmVhZGVyID0gdGhpcy5fbmV0d29ya1N0cmVhbS5nZXRSYW5nZVJlYWRlcihkYXRhLmJlZ2luLCBkYXRhLmVuZCk7XG5cbiAgICAgIGlmICghcmFuZ2VSZWFkZXIpIHtcbiAgICAgICAgc2luay5jbG9zZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHNpbmsub25QdWxsID0gKCkgPT4ge1xuICAgICAgICByYW5nZVJlYWRlci5yZWFkKCkudGhlbihmdW5jdGlvbiAoe1xuICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgIGRvbmVcbiAgICAgICAgfSkge1xuICAgICAgICAgIGlmIChkb25lKSB7XG4gICAgICAgICAgICBzaW5rLmNsb3NlKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgKDAsIF91dGlsLmFzc2VydCkoKDAsIF91dGlsLmlzQXJyYXlCdWZmZXIpKHZhbHVlKSwgXCJHZXRSYW5nZVJlYWRlciAtIGV4cGVjdGVkIGFuIEFycmF5QnVmZmVyLlwiKTtcbiAgICAgICAgICBzaW5rLmVucXVldWUobmV3IFVpbnQ4QXJyYXkodmFsdWUpLCAxLCBbdmFsdWVdKTtcbiAgICAgICAgfSkuY2F0Y2gocmVhc29uID0+IHtcbiAgICAgICAgICBzaW5rLmVycm9yKHJlYXNvbik7XG4gICAgICAgIH0pO1xuICAgICAgfTtcblxuICAgICAgc2luay5vbkNhbmNlbCA9IHJlYXNvbiA9PiB7XG4gICAgICAgIHJhbmdlUmVhZGVyLmNhbmNlbChyZWFzb24pO1xuICAgICAgICBzaW5rLnJlYWR5LmNhdGNoKHJlYWR5UmVhc29uID0+IHtcbiAgICAgICAgICBpZiAodGhpcy5kZXN0cm95ZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aHJvdyByZWFkeVJlYXNvbjtcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgIH0pO1xuICAgIG1lc3NhZ2VIYW5kbGVyLm9uKFwiR2V0RG9jXCIsICh7XG4gICAgICBwZGZJbmZvXG4gICAgfSkgPT4ge1xuICAgICAgdGhpcy5fbnVtUGFnZXMgPSBwZGZJbmZvLm51bVBhZ2VzO1xuICAgICAgdGhpcy5faHRtbEZvclhmYSA9IHBkZkluZm8uaHRtbEZvclhmYTtcbiAgICAgIGRlbGV0ZSBwZGZJbmZvLmh0bWxGb3JYZmE7XG5cbiAgICAgIGxvYWRpbmdUYXNrLl9jYXBhYmlsaXR5LnJlc29sdmUobmV3IFBERkRvY3VtZW50UHJveHkocGRmSW5mbywgdGhpcykpO1xuICAgIH0pO1xuICAgIG1lc3NhZ2VIYW5kbGVyLm9uKFwiRG9jRXhjZXB0aW9uXCIsIGZ1bmN0aW9uIChleCkge1xuICAgICAgbGV0IHJlYXNvbjtcblxuICAgICAgc3dpdGNoIChleC5uYW1lKSB7XG4gICAgICAgIGNhc2UgXCJQYXNzd29yZEV4Y2VwdGlvblwiOlxuICAgICAgICAgIHJlYXNvbiA9IG5ldyBfdXRpbC5QYXNzd29yZEV4Y2VwdGlvbihleC5tZXNzYWdlLCBleC5jb2RlKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFwiSW52YWxpZFBERkV4Y2VwdGlvblwiOlxuICAgICAgICAgIHJlYXNvbiA9IG5ldyBfdXRpbC5JbnZhbGlkUERGRXhjZXB0aW9uKGV4Lm1lc3NhZ2UpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgXCJNaXNzaW5nUERGRXhjZXB0aW9uXCI6XG4gICAgICAgICAgcmVhc29uID0gbmV3IF91dGlsLk1pc3NpbmdQREZFeGNlcHRpb24oZXgubWVzc2FnZSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBcIlVuZXhwZWN0ZWRSZXNwb25zZUV4Y2VwdGlvblwiOlxuICAgICAgICAgIHJlYXNvbiA9IG5ldyBfdXRpbC5VbmV4cGVjdGVkUmVzcG9uc2VFeGNlcHRpb24oZXgubWVzc2FnZSwgZXguc3RhdHVzKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFwiVW5rbm93bkVycm9yRXhjZXB0aW9uXCI6XG4gICAgICAgICAgcmVhc29uID0gbmV3IF91dGlsLlVua25vd25FcnJvckV4Y2VwdGlvbihleC5tZXNzYWdlLCBleC5kZXRhaWxzKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICgwLCBfdXRpbC51bnJlYWNoYWJsZSkoXCJEb2NFeGNlcHRpb24gLSBleHBlY3RlZCBhIHZhbGlkIEVycm9yLlwiKTtcbiAgICAgIH1cblxuICAgICAgbG9hZGluZ1Rhc2suX2NhcGFiaWxpdHkucmVqZWN0KHJlYXNvbik7XG4gICAgfSk7XG4gICAgbWVzc2FnZUhhbmRsZXIub24oXCJQYXNzd29yZFJlcXVlc3RcIiwgZXhjZXB0aW9uID0+IHtcbiAgICAgIHRoaXMuX3Bhc3N3b3JkQ2FwYWJpbGl0eSA9ICgwLCBfdXRpbC5jcmVhdGVQcm9taXNlQ2FwYWJpbGl0eSkoKTtcblxuICAgICAgaWYgKGxvYWRpbmdUYXNrLm9uUGFzc3dvcmQpIHtcbiAgICAgICAgY29uc3QgdXBkYXRlUGFzc3dvcmQgPSBwYXNzd29yZCA9PiB7XG4gICAgICAgICAgaWYgKHBhc3N3b3JkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgIHRoaXMuX3Bhc3N3b3JkQ2FwYWJpbGl0eS5yZWplY3QocGFzc3dvcmQpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9wYXNzd29yZENhcGFiaWxpdHkucmVzb2x2ZSh7XG4gICAgICAgICAgICAgIHBhc3N3b3JkXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBsb2FkaW5nVGFzay5vblBhc3N3b3JkKHVwZGF0ZVBhc3N3b3JkLCBleGNlcHRpb24uY29kZSk7XG4gICAgICAgIH0gY2F0Y2ggKGV4KSB7XG4gICAgICAgICAgdGhpcy5fcGFzc3dvcmRDYXBhYmlsaXR5LnJlamVjdChleCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX3Bhc3N3b3JkQ2FwYWJpbGl0eS5yZWplY3QobmV3IF91dGlsLlBhc3N3b3JkRXhjZXB0aW9uKGV4Y2VwdGlvbi5tZXNzYWdlLCBleGNlcHRpb24uY29kZSkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5fcGFzc3dvcmRDYXBhYmlsaXR5LnByb21pc2U7XG4gICAgfSk7XG4gICAgbWVzc2FnZUhhbmRsZXIub24oXCJEYXRhTG9hZGVkXCIsIGRhdGEgPT4ge1xuICAgICAgbG9hZGluZ1Rhc2sub25Qcm9ncmVzcz8uKHtcbiAgICAgICAgbG9hZGVkOiBkYXRhLmxlbmd0aCxcbiAgICAgICAgdG90YWw6IGRhdGEubGVuZ3RoXG4gICAgICB9KTtcbiAgICAgIHRoaXMuZG93bmxvYWRJbmZvQ2FwYWJpbGl0eS5yZXNvbHZlKGRhdGEpO1xuICAgIH0pO1xuICAgIG1lc3NhZ2VIYW5kbGVyLm9uKFwiU3RhcnRSZW5kZXJQYWdlXCIsIGRhdGEgPT4ge1xuICAgICAgaWYgKHRoaXMuZGVzdHJveWVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGFnZSA9IHRoaXMuI3BhZ2VDYWNoZS5nZXQoZGF0YS5wYWdlSW5kZXgpO1xuXG4gICAgICBwYWdlLl9zdGFydFJlbmRlclBhZ2UoZGF0YS50cmFuc3BhcmVuY3ksIGRhdGEuY2FjaGVLZXkpO1xuICAgIH0pO1xuICAgIG1lc3NhZ2VIYW5kbGVyLm9uKFwiY29tbW9ub2JqXCIsIChbaWQsIHR5cGUsIGV4cG9ydGVkRGF0YV0pID0+IHtcbiAgICAgIGlmICh0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmNvbW1vbk9ianMuaGFzKGlkKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlIFwiRm9udFwiOlxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHRoaXMuX3BhcmFtcztcblxuICAgICAgICAgIGlmIChcImVycm9yXCIgaW4gZXhwb3J0ZWREYXRhKSB7XG4gICAgICAgICAgICBjb25zdCBleHBvcnRlZEVycm9yID0gZXhwb3J0ZWREYXRhLmVycm9yO1xuICAgICAgICAgICAgKDAsIF91dGlsLndhcm4pKGBFcnJvciBkdXJpbmcgZm9udCBsb2FkaW5nOiAke2V4cG9ydGVkRXJyb3J9YCk7XG4gICAgICAgICAgICB0aGlzLmNvbW1vbk9ianMucmVzb2x2ZShpZCwgZXhwb3J0ZWRFcnJvcik7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBsZXQgZm9udFJlZ2lzdHJ5ID0gbnVsbDtcblxuICAgICAgICAgIGlmIChwYXJhbXMucGRmQnVnICYmIGdsb2JhbFRoaXMuRm9udEluc3BlY3Rvcj8uZW5hYmxlZCkge1xuICAgICAgICAgICAgZm9udFJlZ2lzdHJ5ID0ge1xuICAgICAgICAgICAgICByZWdpc3RlckZvbnQoZm9udCwgdXJsKSB7XG4gICAgICAgICAgICAgICAgZ2xvYmFsVGhpcy5Gb250SW5zcGVjdG9yLmZvbnRBZGRlZChmb250LCB1cmwpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgZm9udCA9IG5ldyBfZm9udF9sb2FkZXIuRm9udEZhY2VPYmplY3QoZXhwb3J0ZWREYXRhLCB7XG4gICAgICAgICAgICBpc0V2YWxTdXBwb3J0ZWQ6IHBhcmFtcy5pc0V2YWxTdXBwb3J0ZWQsXG4gICAgICAgICAgICBkaXNhYmxlRm9udEZhY2U6IHBhcmFtcy5kaXNhYmxlRm9udEZhY2UsXG4gICAgICAgICAgICBpZ25vcmVFcnJvcnM6IHBhcmFtcy5pZ25vcmVFcnJvcnMsXG4gICAgICAgICAgICBvblVuc3VwcG9ydGVkRmVhdHVyZTogdGhpcy5fb25VbnN1cHBvcnRlZEZlYXR1cmUuYmluZCh0aGlzKSxcbiAgICAgICAgICAgIGZvbnRSZWdpc3RyeVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRoaXMuZm9udExvYWRlci5iaW5kKGZvbnQpLmNhdGNoKHJlYXNvbiA9PiB7XG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiRm9udEZhbGxiYWNrXCIsIHtcbiAgICAgICAgICAgICAgaWRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKCFwYXJhbXMuZm9udEV4dHJhUHJvcGVydGllcyAmJiBmb250LmRhdGEpIHtcbiAgICAgICAgICAgICAgZm9udC5kYXRhID0gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jb21tb25PYmpzLnJlc29sdmUoaWQsIGZvbnQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgXCJGb250UGF0aFwiOlxuICAgICAgICBjYXNlIFwiSW1hZ2VcIjpcbiAgICAgICAgICB0aGlzLmNvbW1vbk9ianMucmVzb2x2ZShpZCwgZXhwb3J0ZWREYXRhKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgR290IHVua25vd24gY29tbW9uIG9iamVjdCB0eXBlICR7dHlwZX1gKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBtZXNzYWdlSGFuZGxlci5vbihcIm9ialwiLCAoW2lkLCBwYWdlSW5kZXgsIHR5cGUsIGltYWdlRGF0YV0pID0+IHtcbiAgICAgIGlmICh0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBhZ2VQcm94eSA9IHRoaXMuI3BhZ2VDYWNoZS5nZXQocGFnZUluZGV4KTtcblxuICAgICAgaWYgKHBhZ2VQcm94eS5vYmpzLmhhcyhpZCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSBcIkltYWdlXCI6XG4gICAgICAgICAgcGFnZVByb3h5Lm9ianMucmVzb2x2ZShpZCwgaW1hZ2VEYXRhKTtcbiAgICAgICAgICBjb25zdCBNQVhfSU1BR0VfU0laRV9UT19TVE9SRSA9IDgwMDAwMDA7XG5cbiAgICAgICAgICBpZiAoaW1hZ2VEYXRhKSB7XG4gICAgICAgICAgICBsZXQgbGVuZ3RoO1xuXG4gICAgICAgICAgICBpZiAoaW1hZ2VEYXRhLmJpdG1hcCkge1xuICAgICAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICAgICAgYml0bWFwLFxuICAgICAgICAgICAgICAgIHdpZHRoLFxuICAgICAgICAgICAgICAgIGhlaWdodFxuICAgICAgICAgICAgICB9ID0gaW1hZ2VEYXRhO1xuICAgICAgICAgICAgICBsZW5ndGggPSB3aWR0aCAqIGhlaWdodCAqIDQ7XG5cbiAgICAgICAgICAgICAgcGFnZVByb3h5Ll9iaXRtYXBzLmFkZChiaXRtYXApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgbGVuZ3RoID0gaW1hZ2VEYXRhLmRhdGE/Lmxlbmd0aCB8fCAwO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobGVuZ3RoID4gTUFYX0lNQUdFX1NJWkVfVE9fU1RPUkUpIHtcbiAgICAgICAgICAgICAgcGFnZVByb3h5LmNsZWFudXBBZnRlclJlbmRlciA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBcIlBhdHRlcm5cIjpcbiAgICAgICAgICBwYWdlUHJveHkub2Jqcy5yZXNvbHZlKGlkLCBpbWFnZURhdGEpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBHb3QgdW5rbm93biBvYmplY3QgdHlwZSAke3R5cGV9YCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgbWVzc2FnZUhhbmRsZXIub24oXCJEb2NQcm9ncmVzc1wiLCBkYXRhID0+IHtcbiAgICAgIGlmICh0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGxvYWRpbmdUYXNrLm9uUHJvZ3Jlc3M/Lih7XG4gICAgICAgIGxvYWRlZDogZGF0YS5sb2FkZWQsXG4gICAgICAgIHRvdGFsOiBkYXRhLnRvdGFsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBtZXNzYWdlSGFuZGxlci5vbihcIkRvY1N0YXRzXCIsIGRhdGEgPT4ge1xuICAgICAgaWYgKHRoaXMuZGVzdHJveWVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy4jZG9jU3RhdHMgPSBPYmplY3QuZnJlZXplKHtcbiAgICAgICAgc3RyZWFtVHlwZXM6IE9iamVjdC5mcmVlemUoZGF0YS5zdHJlYW1UeXBlcyksXG4gICAgICAgIGZvbnRUeXBlczogT2JqZWN0LmZyZWV6ZShkYXRhLmZvbnRUeXBlcylcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIG1lc3NhZ2VIYW5kbGVyLm9uKFwiVW5zdXBwb3J0ZWRGZWF0dXJlXCIsIHRoaXMuX29uVW5zdXBwb3J0ZWRGZWF0dXJlLmJpbmQodGhpcykpO1xuICAgIG1lc3NhZ2VIYW5kbGVyLm9uKFwiRmV0Y2hCdWlsdEluQ01hcFwiLCBkYXRhID0+IHtcbiAgICAgIGlmICh0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiV29ya2VyIHdhcyBkZXN0cm95ZWQuXCIpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCF0aGlzLkNNYXBSZWFkZXJGYWN0b3J5KSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJDTWFwUmVhZGVyRmFjdG9yeSBub3QgaW5pdGlhbGl6ZWQsIHNlZSB0aGUgYHVzZVdvcmtlckZldGNoYCBwYXJhbWV0ZXIuXCIpKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuQ01hcFJlYWRlckZhY3RvcnkuZmV0Y2goZGF0YSk7XG4gICAgfSk7XG4gICAgbWVzc2FnZUhhbmRsZXIub24oXCJGZXRjaFN0YW5kYXJkRm9udERhdGFcIiwgZGF0YSA9PiB7XG4gICAgICBpZiAodGhpcy5kZXN0cm95ZWQpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIldvcmtlciB3YXMgZGVzdHJveWVkLlwiKSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghdGhpcy5TdGFuZGFyZEZvbnREYXRhRmFjdG9yeSkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiU3RhbmRhcmRGb250RGF0YUZhY3Rvcnkgbm90IGluaXRpYWxpemVkLCBzZWUgdGhlIGB1c2VXb3JrZXJGZXRjaGAgcGFyYW1ldGVyLlwiKSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLlN0YW5kYXJkRm9udERhdGFGYWN0b3J5LmZldGNoKGRhdGEpO1xuICAgIH0pO1xuICB9XG5cbiAgX29uVW5zdXBwb3J0ZWRGZWF0dXJlKHtcbiAgICBmZWF0dXJlSWRcbiAgfSkge1xuICAgIGlmICh0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMubG9hZGluZ1Rhc2sub25VbnN1cHBvcnRlZEZlYXR1cmU/LihmZWF0dXJlSWQpO1xuICB9XG5cbiAgZ2V0RGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy5tZXNzYWdlSGFuZGxlci5zZW5kV2l0aFByb21pc2UoXCJHZXREYXRhXCIsIG51bGwpO1xuICB9XG5cbiAgZ2V0UGFnZShwYWdlTnVtYmVyKSB7XG4gICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHBhZ2VOdW1iZXIpIHx8IHBhZ2VOdW1iZXIgPD0gMCB8fCBwYWdlTnVtYmVyID4gdGhpcy5fbnVtUGFnZXMpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJJbnZhbGlkIHBhZ2UgcmVxdWVzdC5cIikpO1xuICAgIH1cblxuICAgIGNvbnN0IHBhZ2VJbmRleCA9IHBhZ2VOdW1iZXIgLSAxLFxuICAgICAgICAgIGNhY2hlZFByb21pc2UgPSB0aGlzLiNwYWdlUHJvbWlzZXMuZ2V0KHBhZ2VJbmRleCk7XG5cbiAgICBpZiAoY2FjaGVkUHJvbWlzZSkge1xuICAgICAgcmV0dXJuIGNhY2hlZFByb21pc2U7XG4gICAgfVxuXG4gICAgY29uc3QgcHJvbWlzZSA9IHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0UGFnZVwiLCB7XG4gICAgICBwYWdlSW5kZXhcbiAgICB9KS50aGVuKHBhZ2VJbmZvID0+IHtcbiAgICAgIGlmICh0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUcmFuc3BvcnQgZGVzdHJveWVkXCIpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwYWdlID0gbmV3IFBERlBhZ2VQcm94eShwYWdlSW5kZXgsIHBhZ2VJbmZvLCB0aGlzLCB0aGlzLl9wYXJhbXMub3duZXJEb2N1bWVudCwgdGhpcy5fcGFyYW1zLnBkZkJ1Zyk7XG4gICAgICB0aGlzLiNwYWdlQ2FjaGUuc2V0KHBhZ2VJbmRleCwgcGFnZSk7XG4gICAgICByZXR1cm4gcGFnZTtcbiAgICB9KTtcbiAgICB0aGlzLiNwYWdlUHJvbWlzZXMuc2V0KHBhZ2VJbmRleCwgcHJvbWlzZSk7XG4gICAgcmV0dXJuIHByb21pc2U7XG4gIH1cblxuICBnZXRQYWdlSW5kZXgocmVmKSB7XG4gICAgaWYgKHR5cGVvZiByZWYgIT09IFwib2JqZWN0XCIgfHwgcmVmID09PSBudWxsIHx8ICFOdW1iZXIuaXNJbnRlZ2VyKHJlZi5udW0pIHx8IHJlZi5udW0gPCAwIHx8ICFOdW1iZXIuaXNJbnRlZ2VyKHJlZi5nZW4pIHx8IHJlZi5nZW4gPCAwKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiSW52YWxpZCBwYWdlSW5kZXggcmVxdWVzdC5cIikpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLm1lc3NhZ2VIYW5kbGVyLnNlbmRXaXRoUHJvbWlzZShcIkdldFBhZ2VJbmRleFwiLCB7XG4gICAgICBudW06IHJlZi5udW0sXG4gICAgICBnZW46IHJlZi5nZW5cbiAgICB9KTtcbiAgfVxuXG4gIGdldEFubm90YXRpb25zKHBhZ2VJbmRleCwgaW50ZW50KSB7XG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0QW5ub3RhdGlvbnNcIiwge1xuICAgICAgcGFnZUluZGV4LFxuICAgICAgaW50ZW50XG4gICAgfSk7XG4gIH1cblxuICBzYXZlRG9jdW1lbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiU2F2ZURvY3VtZW50XCIsIHtcbiAgICAgIGlzUHVyZVhmYTogISF0aGlzLl9odG1sRm9yWGZhLFxuICAgICAgbnVtUGFnZXM6IHRoaXMuX251bVBhZ2VzLFxuICAgICAgYW5ub3RhdGlvblN0b3JhZ2U6IHRoaXMuYW5ub3RhdGlvblN0b3JhZ2Uuc2VyaWFsaXphYmxlLFxuICAgICAgZmlsZW5hbWU6IHRoaXMuX2Z1bGxSZWFkZXI/LmZpbGVuYW1lID8/IG51bGxcbiAgICB9KS5maW5hbGx5KCgpID0+IHtcbiAgICAgIHRoaXMuYW5ub3RhdGlvblN0b3JhZ2UucmVzZXRNb2RpZmllZCgpO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0RmllbGRPYmplY3RzKCkge1xuICAgIHJldHVybiB0aGlzLl9nZXRGaWVsZE9iamVjdHNQcm9taXNlIHx8PSB0aGlzLm1lc3NhZ2VIYW5kbGVyLnNlbmRXaXRoUHJvbWlzZShcIkdldEZpZWxkT2JqZWN0c1wiLCBudWxsKTtcbiAgfVxuXG4gIGhhc0pTQWN0aW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy5faGFzSlNBY3Rpb25zUHJvbWlzZSB8fD0gdGhpcy5tZXNzYWdlSGFuZGxlci5zZW5kV2l0aFByb21pc2UoXCJIYXNKU0FjdGlvbnNcIiwgbnVsbCk7XG4gIH1cblxuICBnZXRDYWxjdWxhdGlvbk9yZGVySWRzKCkge1xuICAgIHJldHVybiB0aGlzLm1lc3NhZ2VIYW5kbGVyLnNlbmRXaXRoUHJvbWlzZShcIkdldENhbGN1bGF0aW9uT3JkZXJJZHNcIiwgbnVsbCk7XG4gIH1cblxuICBnZXREZXN0aW5hdGlvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0RGVzdGluYXRpb25zXCIsIG51bGwpO1xuICB9XG5cbiAgZ2V0RGVzdGluYXRpb24oaWQpIHtcbiAgICBpZiAodHlwZW9mIGlkICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiSW52YWxpZCBkZXN0aW5hdGlvbiByZXF1ZXN0LlwiKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0RGVzdGluYXRpb25cIiwge1xuICAgICAgaWRcbiAgICB9KTtcbiAgfVxuXG4gIGdldFBhZ2VMYWJlbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0UGFnZUxhYmVsc1wiLCBudWxsKTtcbiAgfVxuXG4gIGdldFBhZ2VMYXlvdXQoKSB7XG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0UGFnZUxheW91dFwiLCBudWxsKTtcbiAgfVxuXG4gIGdldFBhZ2VNb2RlKCkge1xuICAgIHJldHVybiB0aGlzLm1lc3NhZ2VIYW5kbGVyLnNlbmRXaXRoUHJvbWlzZShcIkdldFBhZ2VNb2RlXCIsIG51bGwpO1xuICB9XG5cbiAgZ2V0Vmlld2VyUHJlZmVyZW5jZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0Vmlld2VyUHJlZmVyZW5jZXNcIiwgbnVsbCk7XG4gIH1cblxuICBnZXRPcGVuQWN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLm1lc3NhZ2VIYW5kbGVyLnNlbmRXaXRoUHJvbWlzZShcIkdldE9wZW5BY3Rpb25cIiwgbnVsbCk7XG4gIH1cblxuICBnZXRBdHRhY2htZW50cygpIHtcbiAgICByZXR1cm4gdGhpcy5tZXNzYWdlSGFuZGxlci5zZW5kV2l0aFByb21pc2UoXCJHZXRBdHRhY2htZW50c1wiLCBudWxsKTtcbiAgfVxuXG4gIGdldEphdmFTY3JpcHQoKSB7XG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0SmF2YVNjcmlwdFwiLCBudWxsKTtcbiAgfVxuXG4gIGdldERvY0pTQWN0aW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy5tZXNzYWdlSGFuZGxlci5zZW5kV2l0aFByb21pc2UoXCJHZXREb2NKU0FjdGlvbnNcIiwgbnVsbCk7XG4gIH1cblxuICBnZXRQYWdlSlNBY3Rpb25zKHBhZ2VJbmRleCkge1xuICAgIHJldHVybiB0aGlzLm1lc3NhZ2VIYW5kbGVyLnNlbmRXaXRoUHJvbWlzZShcIkdldFBhZ2VKU0FjdGlvbnNcIiwge1xuICAgICAgcGFnZUluZGV4XG4gICAgfSk7XG4gIH1cblxuICBnZXRTdHJ1Y3RUcmVlKHBhZ2VJbmRleCkge1xuICAgIHJldHVybiB0aGlzLm1lc3NhZ2VIYW5kbGVyLnNlbmRXaXRoUHJvbWlzZShcIkdldFN0cnVjdFRyZWVcIiwge1xuICAgICAgcGFnZUluZGV4XG4gICAgfSk7XG4gIH1cblxuICBnZXRPdXRsaW5lKCkge1xuICAgIHJldHVybiB0aGlzLm1lc3NhZ2VIYW5kbGVyLnNlbmRXaXRoUHJvbWlzZShcIkdldE91dGxpbmVcIiwgbnVsbCk7XG4gIH1cblxuICBnZXRPcHRpb25hbENvbnRlbnRDb25maWcoKSB7XG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0T3B0aW9uYWxDb250ZW50Q29uZmlnXCIsIG51bGwpLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICByZXR1cm4gbmV3IF9vcHRpb25hbF9jb250ZW50X2NvbmZpZy5PcHRpb25hbENvbnRlbnRDb25maWcocmVzdWx0cyk7XG4gICAgfSk7XG4gIH1cblxuICBnZXRQZXJtaXNzaW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy5tZXNzYWdlSGFuZGxlci5zZW5kV2l0aFByb21pc2UoXCJHZXRQZXJtaXNzaW9uc1wiLCBudWxsKTtcbiAgfVxuXG4gIGdldE1ldGFkYXRhKCkge1xuICAgIHJldHVybiB0aGlzLiNtZXRhZGF0YVByb21pc2UgfHw9IHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiR2V0TWV0YWRhdGFcIiwgbnVsbCkudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGluZm86IHJlc3VsdHNbMF0sXG4gICAgICAgIG1ldGFkYXRhOiByZXN1bHRzWzFdID8gbmV3IF9tZXRhZGF0YS5NZXRhZGF0YShyZXN1bHRzWzFdKSA6IG51bGwsXG4gICAgICAgIGNvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lOiB0aGlzLl9mdWxsUmVhZGVyPy5maWxlbmFtZSA/PyBudWxsLFxuICAgICAgICBjb250ZW50TGVuZ3RoOiB0aGlzLl9mdWxsUmVhZGVyPy5jb250ZW50TGVuZ3RoID8/IG51bGxcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBnZXRNYXJrSW5mbygpIHtcbiAgICByZXR1cm4gdGhpcy5tZXNzYWdlSGFuZGxlci5zZW5kV2l0aFByb21pc2UoXCJHZXRNYXJrSW5mb1wiLCBudWxsKTtcbiAgfVxuXG4gIGFzeW5jIHN0YXJ0Q2xlYW51cChrZWVwTG9hZGVkRm9udHMgPSBmYWxzZSkge1xuICAgIGF3YWl0IHRoaXMubWVzc2FnZUhhbmRsZXIuc2VuZFdpdGhQcm9taXNlKFwiQ2xlYW51cFwiLCBudWxsKTtcblxuICAgIGlmICh0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcGFnZSBvZiB0aGlzLiNwYWdlQ2FjaGUudmFsdWVzKCkpIHtcbiAgICAgIGNvbnN0IGNsZWFudXBTdWNjZXNzZnVsID0gcGFnZS5jbGVhbnVwKCk7XG5cbiAgICAgIGlmICghY2xlYW51cFN1Y2Nlc3NmdWwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBzdGFydENsZWFudXA6IFBhZ2UgJHtwYWdlLnBhZ2VOdW1iZXJ9IGlzIGN1cnJlbnRseSByZW5kZXJpbmcuYCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5jb21tb25PYmpzLmNsZWFyKCk7XG5cbiAgICBpZiAoIWtlZXBMb2FkZWRGb250cykge1xuICAgICAgdGhpcy5mb250TG9hZGVyLmNsZWFyKCk7XG4gICAgfVxuXG4gICAgdGhpcy4jbWV0YWRhdGFQcm9taXNlID0gbnVsbDtcbiAgICB0aGlzLl9nZXRGaWVsZE9iamVjdHNQcm9taXNlID0gbnVsbDtcbiAgICB0aGlzLl9oYXNKU0FjdGlvbnNQcm9taXNlID0gbnVsbDtcbiAgfVxuXG4gIGdldCBsb2FkaW5nUGFyYW1zKCkge1xuICAgIGNvbnN0IHBhcmFtcyA9IHRoaXMuX3BhcmFtcztcbiAgICByZXR1cm4gKDAsIF91dGlsLnNoYWRvdykodGhpcywgXCJsb2FkaW5nUGFyYW1zXCIsIHtcbiAgICAgIGRpc2FibGVBdXRvRmV0Y2g6IHBhcmFtcy5kaXNhYmxlQXV0b0ZldGNoLFxuICAgICAgZW5hYmxlWGZhOiBwYXJhbXMuZW5hYmxlWGZhXG4gICAgfSk7XG4gIH1cblxufVxuXG5jbGFzcyBQREZPYmplY3RzIHtcbiAgI29ianMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4gICNlbnN1cmVPYmoob2JqSWQpIHtcbiAgICBjb25zdCBvYmogPSB0aGlzLiNvYmpzW29iaklkXTtcblxuICAgIGlmIChvYmopIHtcbiAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuI29ianNbb2JqSWRdID0ge1xuICAgICAgY2FwYWJpbGl0eTogKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpLFxuICAgICAgZGF0YTogbnVsbFxuICAgIH07XG4gIH1cblxuICBnZXQob2JqSWQsIGNhbGxiYWNrID0gbnVsbCkge1xuICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgY29uc3Qgb2JqID0gdGhpcy4jZW5zdXJlT2JqKG9iaklkKTtcbiAgICAgIG9iai5jYXBhYmlsaXR5LnByb21pc2UudGhlbigoKSA9PiBjYWxsYmFjayhvYmouZGF0YSkpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3Qgb2JqID0gdGhpcy4jb2Jqc1tvYmpJZF07XG5cbiAgICBpZiAoIW9iaj8uY2FwYWJpbGl0eS5zZXR0bGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFJlcXVlc3Rpbmcgb2JqZWN0IHRoYXQgaXNuJ3QgcmVzb2x2ZWQgeWV0ICR7b2JqSWR9LmApO1xuICAgIH1cblxuICAgIHJldHVybiBvYmouZGF0YTtcbiAgfVxuXG4gIGhhcyhvYmpJZCkge1xuICAgIGNvbnN0IG9iaiA9IHRoaXMuI29ianNbb2JqSWRdO1xuICAgIHJldHVybiBvYmo/LmNhcGFiaWxpdHkuc2V0dGxlZCB8fCBmYWxzZTtcbiAgfVxuXG4gIHJlc29sdmUob2JqSWQsIGRhdGEgPSBudWxsKSB7XG4gICAgY29uc3Qgb2JqID0gdGhpcy4jZW5zdXJlT2JqKG9iaklkKTtcbiAgICBvYmouZGF0YSA9IGRhdGE7XG4gICAgb2JqLmNhcGFiaWxpdHkucmVzb2x2ZSgpO1xuICB9XG5cbiAgY2xlYXIoKSB7XG4gICAgdGhpcy4jb2JqcyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gIH1cblxufVxuXG5jbGFzcyBSZW5kZXJUYXNrIHtcbiAgY29uc3RydWN0b3IoaW50ZXJuYWxSZW5kZXJUYXNrKSB7XG4gICAgdGhpcy5faW50ZXJuYWxSZW5kZXJUYXNrID0gaW50ZXJuYWxSZW5kZXJUYXNrO1xuICAgIHRoaXMub25Db250aW51ZSA9IG51bGw7XG4gIH1cblxuICBnZXQgcHJvbWlzZSgpIHtcbiAgICByZXR1cm4gdGhpcy5faW50ZXJuYWxSZW5kZXJUYXNrLmNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxuXG4gIGNhbmNlbCgpIHtcbiAgICB0aGlzLl9pbnRlcm5hbFJlbmRlclRhc2suY2FuY2VsKCk7XG4gIH1cblxufVxuXG5leHBvcnRzLlJlbmRlclRhc2sgPSBSZW5kZXJUYXNrO1xuXG5jbGFzcyBJbnRlcm5hbFJlbmRlclRhc2sge1xuICBzdGF0aWMgI2NhbnZhc0luVXNlID0gbmV3IFdlYWtTZXQoKTtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgY2FsbGJhY2ssXG4gICAgcGFyYW1zLFxuICAgIG9ianMsXG4gICAgY29tbW9uT2JqcyxcbiAgICBhbm5vdGF0aW9uQ2FudmFzTWFwLFxuICAgIG9wZXJhdG9yTGlzdCxcbiAgICBwYWdlSW5kZXgsXG4gICAgY2FudmFzRmFjdG9yeSxcbiAgICB1c2VSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPSBmYWxzZSxcbiAgICBwZGZCdWcgPSBmYWxzZSxcbiAgICBwYWdlQ29sb3JzID0gbnVsbFxuICB9KSB7XG4gICAgdGhpcy5jYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHRoaXMucGFyYW1zID0gcGFyYW1zO1xuICAgIHRoaXMub2JqcyA9IG9ianM7XG4gICAgdGhpcy5jb21tb25PYmpzID0gY29tbW9uT2JqcztcbiAgICB0aGlzLmFubm90YXRpb25DYW52YXNNYXAgPSBhbm5vdGF0aW9uQ2FudmFzTWFwO1xuICAgIHRoaXMub3BlcmF0b3JMaXN0SWR4ID0gbnVsbDtcbiAgICB0aGlzLm9wZXJhdG9yTGlzdCA9IG9wZXJhdG9yTGlzdDtcbiAgICB0aGlzLl9wYWdlSW5kZXggPSBwYWdlSW5kZXg7XG4gICAgdGhpcy5jYW52YXNGYWN0b3J5ID0gY2FudmFzRmFjdG9yeTtcbiAgICB0aGlzLl9wZGZCdWcgPSBwZGZCdWc7XG4gICAgdGhpcy5wYWdlQ29sb3JzID0gcGFnZUNvbG9ycztcbiAgICB0aGlzLnJ1bm5pbmcgPSBmYWxzZTtcbiAgICB0aGlzLmdyYXBoaWNzUmVhZHlDYWxsYmFjayA9IG51bGw7XG4gICAgdGhpcy5ncmFwaGljc1JlYWR5ID0gZmFsc2U7XG4gICAgdGhpcy5fdXNlUmVxdWVzdEFuaW1hdGlvbkZyYW1lID0gdXNlUmVxdWVzdEFuaW1hdGlvbkZyYW1lID09PSB0cnVlICYmIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCI7XG4gICAgdGhpcy5jYW5jZWxsZWQgPSBmYWxzZTtcbiAgICB0aGlzLmNhcGFiaWxpdHkgPSAoMCwgX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkpKCk7XG4gICAgdGhpcy50YXNrID0gbmV3IFJlbmRlclRhc2sodGhpcyk7XG4gICAgdGhpcy5fY2FuY2VsQm91bmQgPSB0aGlzLmNhbmNlbC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX2NvbnRpbnVlQm91bmQgPSB0aGlzLl9jb250aW51ZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX3NjaGVkdWxlTmV4dEJvdW5kID0gdGhpcy5fc2NoZWR1bGVOZXh0LmJpbmQodGhpcyk7XG4gICAgdGhpcy5fbmV4dEJvdW5kID0gdGhpcy5fbmV4dC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX2NhbnZhcyA9IHBhcmFtcy5jYW52YXNDb250ZXh0LmNhbnZhcztcbiAgfVxuXG4gIGdldCBjb21wbGV0ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FwYWJpbGl0eS5wcm9taXNlLmNhdGNoKGZ1bmN0aW9uICgpIHt9KTtcbiAgfVxuXG4gIGluaXRpYWxpemVHcmFwaGljcyh7XG4gICAgdHJhbnNwYXJlbmN5ID0gZmFsc2UsXG4gICAgb3B0aW9uYWxDb250ZW50Q29uZmlnXG4gIH0pIHtcbiAgICBpZiAodGhpcy5jYW5jZWxsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fY2FudmFzKSB7XG4gICAgICBpZiAoSW50ZXJuYWxSZW5kZXJUYXNrLiNjYW52YXNJblVzZS5oYXModGhpcy5fY2FudmFzKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgdXNlIHRoZSBzYW1lIGNhbnZhcyBkdXJpbmcgbXVsdGlwbGUgcmVuZGVyKCkgb3BlcmF0aW9ucy4gXCIgKyBcIlVzZSBkaWZmZXJlbnQgY2FudmFzIG9yIGVuc3VyZSBwcmV2aW91cyBvcGVyYXRpb25zIHdlcmUgXCIgKyBcImNhbmNlbGxlZCBvciBjb21wbGV0ZWQuXCIpO1xuICAgICAgfVxuXG4gICAgICBJbnRlcm5hbFJlbmRlclRhc2suI2NhbnZhc0luVXNlLmFkZCh0aGlzLl9jYW52YXMpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9wZGZCdWcgJiYgZ2xvYmFsVGhpcy5TdGVwcGVyTWFuYWdlcj8uZW5hYmxlZCkge1xuICAgICAgdGhpcy5zdGVwcGVyID0gZ2xvYmFsVGhpcy5TdGVwcGVyTWFuYWdlci5jcmVhdGUodGhpcy5fcGFnZUluZGV4KTtcbiAgICAgIHRoaXMuc3RlcHBlci5pbml0KHRoaXMub3BlcmF0b3JMaXN0KTtcbiAgICAgIHRoaXMuc3RlcHBlci5uZXh0QnJlYWtQb2ludCA9IHRoaXMuc3RlcHBlci5nZXROZXh0QnJlYWtQb2ludCgpO1xuICAgIH1cblxuICAgIGNvbnN0IHtcbiAgICAgIGNhbnZhc0NvbnRleHQsXG4gICAgICB2aWV3cG9ydCxcbiAgICAgIHRyYW5zZm9ybSxcbiAgICAgIGltYWdlTGF5ZXIsXG4gICAgICBiYWNrZ3JvdW5kXG4gICAgfSA9IHRoaXMucGFyYW1zO1xuICAgIHRoaXMuZ2Z4ID0gbmV3IF9jYW52YXMuQ2FudmFzR3JhcGhpY3MoY2FudmFzQ29udGV4dCwgdGhpcy5jb21tb25PYmpzLCB0aGlzLm9ianMsIHRoaXMuY2FudmFzRmFjdG9yeSwgaW1hZ2VMYXllciwgb3B0aW9uYWxDb250ZW50Q29uZmlnLCB0aGlzLmFubm90YXRpb25DYW52YXNNYXAsIHRoaXMucGFnZUNvbG9ycyk7XG4gICAgdGhpcy5nZnguYmVnaW5EcmF3aW5nKHtcbiAgICAgIHRyYW5zZm9ybSxcbiAgICAgIHZpZXdwb3J0LFxuICAgICAgdHJhbnNwYXJlbmN5LFxuICAgICAgYmFja2dyb3VuZFxuICAgIH0pO1xuICAgIHRoaXMub3BlcmF0b3JMaXN0SWR4ID0gMDtcbiAgICB0aGlzLmdyYXBoaWNzUmVhZHkgPSB0cnVlO1xuXG4gICAgaWYgKHRoaXMuZ3JhcGhpY3NSZWFkeUNhbGxiYWNrKSB7XG4gICAgICB0aGlzLmdyYXBoaWNzUmVhZHlDYWxsYmFjaygpO1xuICAgIH1cbiAgfVxuXG4gIGNhbmNlbChlcnJvciA9IG51bGwpIHtcbiAgICB0aGlzLnJ1bm5pbmcgPSBmYWxzZTtcbiAgICB0aGlzLmNhbmNlbGxlZCA9IHRydWU7XG5cbiAgICBpZiAodGhpcy5nZngpIHtcbiAgICAgIHRoaXMuZ2Z4LmVuZERyYXdpbmcoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fY2FudmFzKSB7XG4gICAgICBJbnRlcm5hbFJlbmRlclRhc2suI2NhbnZhc0luVXNlLmRlbGV0ZSh0aGlzLl9jYW52YXMpO1xuICAgIH1cblxuICAgIHRoaXMuY2FsbGJhY2soZXJyb3IgfHwgbmV3IF9kaXNwbGF5X3V0aWxzLlJlbmRlcmluZ0NhbmNlbGxlZEV4Y2VwdGlvbihgUmVuZGVyaW5nIGNhbmNlbGxlZCwgcGFnZSAke3RoaXMuX3BhZ2VJbmRleCArIDF9YCwgXCJjYW52YXNcIikpO1xuICB9XG5cbiAgb3BlcmF0b3JMaXN0Q2hhbmdlZCgpIHtcbiAgICBpZiAoIXRoaXMuZ3JhcGhpY3NSZWFkeSkge1xuICAgICAgaWYgKCF0aGlzLmdyYXBoaWNzUmVhZHlDYWxsYmFjaykge1xuICAgICAgICB0aGlzLmdyYXBoaWNzUmVhZHlDYWxsYmFjayA9IHRoaXMuX2NvbnRpbnVlQm91bmQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdGVwcGVyKSB7XG4gICAgICB0aGlzLnN0ZXBwZXIudXBkYXRlT3BlcmF0b3JMaXN0KHRoaXMub3BlcmF0b3JMaXN0KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5ydW5uaW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fY29udGludWUoKTtcbiAgfVxuXG4gIF9jb250aW51ZSgpIHtcbiAgICB0aGlzLnJ1bm5pbmcgPSB0cnVlO1xuXG4gICAgaWYgKHRoaXMuY2FuY2VsbGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudGFzay5vbkNvbnRpbnVlKSB7XG4gICAgICB0aGlzLnRhc2sub25Db250aW51ZSh0aGlzLl9zY2hlZHVsZU5leHRCb3VuZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3NjaGVkdWxlTmV4dCgpO1xuICAgIH1cbiAgfVxuXG4gIF9zY2hlZHVsZU5leHQoKSB7XG4gICAgaWYgKHRoaXMuX3VzZVJlcXVlc3RBbmltYXRpb25GcmFtZSkge1xuICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuX25leHRCb3VuZCgpLmNhdGNoKHRoaXMuX2NhbmNlbEJvdW5kKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKHRoaXMuX25leHRCb3VuZCkuY2F0Y2godGhpcy5fY2FuY2VsQm91bmQpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIF9uZXh0KCkge1xuICAgIGlmICh0aGlzLmNhbmNlbGxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMub3BlcmF0b3JMaXN0SWR4ID0gdGhpcy5nZnguZXhlY3V0ZU9wZXJhdG9yTGlzdCh0aGlzLm9wZXJhdG9yTGlzdCwgdGhpcy5vcGVyYXRvckxpc3RJZHgsIHRoaXMuX2NvbnRpbnVlQm91bmQsIHRoaXMuc3RlcHBlcik7XG5cbiAgICBpZiAodGhpcy5vcGVyYXRvckxpc3RJZHggPT09IHRoaXMub3BlcmF0b3JMaXN0LmFyZ3NBcnJheS5sZW5ndGgpIHtcbiAgICAgIHRoaXMucnVubmluZyA9IGZhbHNlO1xuXG4gICAgICBpZiAodGhpcy5vcGVyYXRvckxpc3QubGFzdENodW5rKSB7XG4gICAgICAgIHRoaXMuZ2Z4LmVuZERyYXdpbmcoKTtcblxuICAgICAgICBpZiAodGhpcy5fY2FudmFzKSB7XG4gICAgICAgICAgSW50ZXJuYWxSZW5kZXJUYXNrLiNjYW52YXNJblVzZS5kZWxldGUodGhpcy5fY2FudmFzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2FsbGJhY2soKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxufVxuXG5jb25zdCB2ZXJzaW9uID0gJzIuMTQuMzA1JztcbmV4cG9ydHMudmVyc2lvbiA9IHZlcnNpb247XG5jb25zdCBidWlsZCA9ICdlYWFhOGI0YWQnO1xuZXhwb3J0cy5idWlsZCA9IGJ1aWxkO1xuXG4vKioqLyB9KSxcbi8qIDUgKi9cbi8qKiovICgoX191bnVzZWRfd2VicGFja19tb2R1bGUsIGV4cG9ydHMsIF9fd19wZGZqc19yZXF1aXJlX18pID0+IHtcblxuXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgKHtcbiAgdmFsdWU6IHRydWVcbn0pKTtcbmV4cG9ydHMuU3RhdFRpbWVyID0gZXhwb3J0cy5SZW5kZXJpbmdDYW5jZWxsZWRFeGNlcHRpb24gPSBleHBvcnRzLlBpeGVsc1BlckluY2ggPSBleHBvcnRzLlBhZ2VWaWV3cG9ydCA9IGV4cG9ydHMuUERGRGF0ZVN0cmluZyA9IGV4cG9ydHMuRE9NU3RhbmRhcmRGb250RGF0YUZhY3RvcnkgPSBleHBvcnRzLkRPTVNWR0ZhY3RvcnkgPSBleHBvcnRzLkRPTUNhbnZhc0ZhY3RvcnkgPSBleHBvcnRzLkRPTUNNYXBSZWFkZXJGYWN0b3J5ID0gdm9pZCAwO1xuZXhwb3J0cy5kZXByZWNhdGVkID0gZGVwcmVjYXRlZDtcbmV4cG9ydHMuZ2V0RmlsZW5hbWVGcm9tVXJsID0gZ2V0RmlsZW5hbWVGcm9tVXJsO1xuZXhwb3J0cy5nZXRQZGZGaWxlbmFtZUZyb21VcmwgPSBnZXRQZGZGaWxlbmFtZUZyb21Vcmw7XG5leHBvcnRzLmdldFhmYVBhZ2VWaWV3cG9ydCA9IGdldFhmYVBhZ2VWaWV3cG9ydDtcbmV4cG9ydHMuaXNEYXRhU2NoZW1lID0gaXNEYXRhU2NoZW1lO1xuZXhwb3J0cy5pc1BkZkZpbGUgPSBpc1BkZkZpbGU7XG5leHBvcnRzLmlzVmFsaWRGZXRjaFVybCA9IGlzVmFsaWRGZXRjaFVybDtcbmV4cG9ydHMubG9hZFNjcmlwdCA9IGxvYWRTY3JpcHQ7XG5cbnZhciBfYmFzZV9mYWN0b3J5ID0gX193X3BkZmpzX3JlcXVpcmVfXyg2KTtcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxuY29uc3QgU1ZHX05TID0gXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiO1xuXG5jbGFzcyBQaXhlbHNQZXJJbmNoIHtcbiAgc3RhdGljIENTUyA9IDk2LjA7XG4gIHN0YXRpYyBQREYgPSA3Mi4wO1xuICBzdGF0aWMgUERGX1RPX0NTU19VTklUUyA9IHRoaXMuQ1NTIC8gdGhpcy5QREY7XG59XG5cbmV4cG9ydHMuUGl4ZWxzUGVySW5jaCA9IFBpeGVsc1BlckluY2g7XG5cbmNsYXNzIERPTUNhbnZhc0ZhY3RvcnkgZXh0ZW5kcyBfYmFzZV9mYWN0b3J5LkJhc2VDYW52YXNGYWN0b3J5IHtcbiAgY29uc3RydWN0b3Ioe1xuICAgIG93bmVyRG9jdW1lbnQgPSBnbG9iYWxUaGlzLmRvY3VtZW50XG4gIH0gPSB7fSkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5fZG9jdW1lbnQgPSBvd25lckRvY3VtZW50O1xuICB9XG5cbiAgX2NyZWF0ZUNhbnZhcyh3aWR0aCwgaGVpZ2h0KSB7XG4gICAgY29uc3QgY2FudmFzID0gdGhpcy5fZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcblxuICAgIGNhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgIGNhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgcmV0dXJuIGNhbnZhcztcbiAgfVxuXG59XG5cbmV4cG9ydHMuRE9NQ2FudmFzRmFjdG9yeSA9IERPTUNhbnZhc0ZhY3Rvcnk7XG5cbmFzeW5jIGZ1bmN0aW9uIGZldGNoRGF0YSh1cmwsIGFzVHlwZWRBcnJheSA9IGZhbHNlKSB7XG4gIGlmIChpc1ZhbGlkRmV0Y2hVcmwodXJsLCBkb2N1bWVudC5iYXNlVVJJKSkge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsKTtcblxuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihyZXNwb25zZS5zdGF0dXNUZXh0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXNUeXBlZEFycmF5ID8gbmV3IFVpbnQ4QXJyYXkoYXdhaXQgcmVzcG9uc2UuYXJyYXlCdWZmZXIoKSkgOiAoMCwgX3V0aWwuc3RyaW5nVG9CeXRlcykoYXdhaXQgcmVzcG9uc2UudGV4dCgpKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgIHJlcXVlc3Qub3BlbihcIkdFVFwiLCB1cmwsIHRydWUpO1xuXG4gICAgaWYgKGFzVHlwZWRBcnJheSkge1xuICAgICAgcmVxdWVzdC5yZXNwb25zZVR5cGUgPSBcImFycmF5YnVmZmVyXCI7XG4gICAgfVxuXG4gICAgcmVxdWVzdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICBpZiAocmVxdWVzdC5yZWFkeVN0YXRlICE9PSBYTUxIdHRwUmVxdWVzdC5ET05FKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlcXVlc3Quc3RhdHVzID09PSAyMDAgfHwgcmVxdWVzdC5zdGF0dXMgPT09IDApIHtcbiAgICAgICAgbGV0IGRhdGE7XG5cbiAgICAgICAgaWYgKGFzVHlwZWRBcnJheSAmJiByZXF1ZXN0LnJlc3BvbnNlKSB7XG4gICAgICAgICAgZGF0YSA9IG5ldyBVaW50OEFycmF5KHJlcXVlc3QucmVzcG9uc2UpO1xuICAgICAgICB9IGVsc2UgaWYgKCFhc1R5cGVkQXJyYXkgJiYgcmVxdWVzdC5yZXNwb25zZVRleHQpIHtcbiAgICAgICAgICBkYXRhID0gKDAsIF91dGlsLnN0cmluZ1RvQnl0ZXMpKHJlcXVlc3QucmVzcG9uc2VUZXh0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkYXRhKSB7XG4gICAgICAgICAgcmVzb2x2ZShkYXRhKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmVqZWN0KG5ldyBFcnJvcihyZXF1ZXN0LnN0YXR1c1RleHQpKTtcbiAgICB9O1xuXG4gICAgcmVxdWVzdC5zZW5kKG51bGwpO1xuICB9KTtcbn1cblxuY2xhc3MgRE9NQ01hcFJlYWRlckZhY3RvcnkgZXh0ZW5kcyBfYmFzZV9mYWN0b3J5LkJhc2VDTWFwUmVhZGVyRmFjdG9yeSB7XG4gIF9mZXRjaERhdGEodXJsLCBjb21wcmVzc2lvblR5cGUpIHtcbiAgICByZXR1cm4gZmV0Y2hEYXRhKHVybCwgdGhpcy5pc0NvbXByZXNzZWQpLnRoZW4oZGF0YSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjTWFwRGF0YTogZGF0YSxcbiAgICAgICAgY29tcHJlc3Npb25UeXBlXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbn1cblxuZXhwb3J0cy5ET01DTWFwUmVhZGVyRmFjdG9yeSA9IERPTUNNYXBSZWFkZXJGYWN0b3J5O1xuXG5jbGFzcyBET01TdGFuZGFyZEZvbnREYXRhRmFjdG9yeSBleHRlbmRzIF9iYXNlX2ZhY3RvcnkuQmFzZVN0YW5kYXJkRm9udERhdGFGYWN0b3J5IHtcbiAgX2ZldGNoRGF0YSh1cmwpIHtcbiAgICByZXR1cm4gZmV0Y2hEYXRhKHVybCwgdHJ1ZSk7XG4gIH1cblxufVxuXG5leHBvcnRzLkRPTVN0YW5kYXJkRm9udERhdGFGYWN0b3J5ID0gRE9NU3RhbmRhcmRGb250RGF0YUZhY3Rvcnk7XG5cbmNsYXNzIERPTVNWR0ZhY3RvcnkgZXh0ZW5kcyBfYmFzZV9mYWN0b3J5LkJhc2VTVkdGYWN0b3J5IHtcbiAgX2NyZWF0ZVNWRyh0eXBlKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsIHR5cGUpO1xuICB9XG5cbn1cblxuZXhwb3J0cy5ET01TVkdGYWN0b3J5ID0gRE9NU1ZHRmFjdG9yeTtcblxuY2xhc3MgUGFnZVZpZXdwb3J0IHtcbiAgY29uc3RydWN0b3Ioe1xuICAgIHZpZXdCb3gsXG4gICAgc2NhbGUsXG4gICAgcm90YXRpb24sXG4gICAgb2Zmc2V0WCA9IDAsXG4gICAgb2Zmc2V0WSA9IDAsXG4gICAgZG9udEZsaXAgPSBmYWxzZVxuICB9KSB7XG4gICAgdGhpcy52aWV3Qm94ID0gdmlld0JveDtcbiAgICB0aGlzLnNjYWxlID0gc2NhbGU7XG4gICAgdGhpcy5yb3RhdGlvbiA9IHJvdGF0aW9uO1xuICAgIHRoaXMub2Zmc2V0WCA9IG9mZnNldFg7XG4gICAgdGhpcy5vZmZzZXRZID0gb2Zmc2V0WTtcbiAgICBjb25zdCBjZW50ZXJYID0gKHZpZXdCb3hbMl0gKyB2aWV3Qm94WzBdKSAvIDI7XG4gICAgY29uc3QgY2VudGVyWSA9ICh2aWV3Qm94WzNdICsgdmlld0JveFsxXSkgLyAyO1xuICAgIGxldCByb3RhdGVBLCByb3RhdGVCLCByb3RhdGVDLCByb3RhdGVEO1xuICAgIHJvdGF0aW9uICU9IDM2MDtcblxuICAgIGlmIChyb3RhdGlvbiA8IDApIHtcbiAgICAgIHJvdGF0aW9uICs9IDM2MDtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHJvdGF0aW9uKSB7XG4gICAgICBjYXNlIDE4MDpcbiAgICAgICAgcm90YXRlQSA9IC0xO1xuICAgICAgICByb3RhdGVCID0gMDtcbiAgICAgICAgcm90YXRlQyA9IDA7XG4gICAgICAgIHJvdGF0ZUQgPSAxO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSA5MDpcbiAgICAgICAgcm90YXRlQSA9IDA7XG4gICAgICAgIHJvdGF0ZUIgPSAxO1xuICAgICAgICByb3RhdGVDID0gMTtcbiAgICAgICAgcm90YXRlRCA9IDA7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIDI3MDpcbiAgICAgICAgcm90YXRlQSA9IDA7XG4gICAgICAgIHJvdGF0ZUIgPSAtMTtcbiAgICAgICAgcm90YXRlQyA9IC0xO1xuICAgICAgICByb3RhdGVEID0gMDtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcm90YXRlQSA9IDE7XG4gICAgICAgIHJvdGF0ZUIgPSAwO1xuICAgICAgICByb3RhdGVDID0gMDtcbiAgICAgICAgcm90YXRlRCA9IC0xO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUGFnZVZpZXdwb3J0OiBJbnZhbGlkIHJvdGF0aW9uLCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgOTAgZGVncmVlcy5cIik7XG4gICAgfVxuXG4gICAgaWYgKGRvbnRGbGlwKSB7XG4gICAgICByb3RhdGVDID0gLXJvdGF0ZUM7XG4gICAgICByb3RhdGVEID0gLXJvdGF0ZUQ7XG4gICAgfVxuXG4gICAgbGV0IG9mZnNldENhbnZhc1gsIG9mZnNldENhbnZhc1k7XG4gICAgbGV0IHdpZHRoLCBoZWlnaHQ7XG5cbiAgICBpZiAocm90YXRlQSA9PT0gMCkge1xuICAgICAgb2Zmc2V0Q2FudmFzWCA9IE1hdGguYWJzKGNlbnRlclkgLSB2aWV3Qm94WzFdKSAqIHNjYWxlICsgb2Zmc2V0WDtcbiAgICAgIG9mZnNldENhbnZhc1kgPSBNYXRoLmFicyhjZW50ZXJYIC0gdmlld0JveFswXSkgKiBzY2FsZSArIG9mZnNldFk7XG4gICAgICB3aWR0aCA9IE1hdGguYWJzKHZpZXdCb3hbM10gLSB2aWV3Qm94WzFdKSAqIHNjYWxlO1xuICAgICAgaGVpZ2h0ID0gTWF0aC5hYnModmlld0JveFsyXSAtIHZpZXdCb3hbMF0pICogc2NhbGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9mZnNldENhbnZhc1ggPSBNYXRoLmFicyhjZW50ZXJYIC0gdmlld0JveFswXSkgKiBzY2FsZSArIG9mZnNldFg7XG4gICAgICBvZmZzZXRDYW52YXNZID0gTWF0aC5hYnMoY2VudGVyWSAtIHZpZXdCb3hbMV0pICogc2NhbGUgKyBvZmZzZXRZO1xuICAgICAgd2lkdGggPSBNYXRoLmFicyh2aWV3Qm94WzJdIC0gdmlld0JveFswXSkgKiBzY2FsZTtcbiAgICAgIGhlaWdodCA9IE1hdGguYWJzKHZpZXdCb3hbM10gLSB2aWV3Qm94WzFdKSAqIHNjYWxlO1xuICAgIH1cblxuICAgIHRoaXMudHJhbnNmb3JtID0gW3JvdGF0ZUEgKiBzY2FsZSwgcm90YXRlQiAqIHNjYWxlLCByb3RhdGVDICogc2NhbGUsIHJvdGF0ZUQgKiBzY2FsZSwgb2Zmc2V0Q2FudmFzWCAtIHJvdGF0ZUEgKiBzY2FsZSAqIGNlbnRlclggLSByb3RhdGVDICogc2NhbGUgKiBjZW50ZXJZLCBvZmZzZXRDYW52YXNZIC0gcm90YXRlQiAqIHNjYWxlICogY2VudGVyWCAtIHJvdGF0ZUQgKiBzY2FsZSAqIGNlbnRlclldO1xuICAgIHRoaXMud2lkdGggPSB3aWR0aDtcbiAgICB0aGlzLmhlaWdodCA9IGhlaWdodDtcbiAgfVxuXG4gIGNsb25lKHtcbiAgICBzY2FsZSA9IHRoaXMuc2NhbGUsXG4gICAgcm90YXRpb24gPSB0aGlzLnJvdGF0aW9uLFxuICAgIG9mZnNldFggPSB0aGlzLm9mZnNldFgsXG4gICAgb2Zmc2V0WSA9IHRoaXMub2Zmc2V0WSxcbiAgICBkb250RmxpcCA9IGZhbHNlXG4gIH0gPSB7fSkge1xuICAgIHJldHVybiBuZXcgUGFnZVZpZXdwb3J0KHtcbiAgICAgIHZpZXdCb3g6IHRoaXMudmlld0JveC5zbGljZSgpLFxuICAgICAgc2NhbGUsXG4gICAgICByb3RhdGlvbixcbiAgICAgIG9mZnNldFgsXG4gICAgICBvZmZzZXRZLFxuICAgICAgZG9udEZsaXBcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnZlcnRUb1ZpZXdwb3J0UG9pbnQoeCwgeSkge1xuICAgIHJldHVybiBfdXRpbC5VdGlsLmFwcGx5VHJhbnNmb3JtKFt4LCB5XSwgdGhpcy50cmFuc2Zvcm0pO1xuICB9XG5cbiAgY29udmVydFRvVmlld3BvcnRSZWN0YW5nbGUocmVjdCkge1xuICAgIGNvbnN0IHRvcExlZnQgPSBfdXRpbC5VdGlsLmFwcGx5VHJhbnNmb3JtKFtyZWN0WzBdLCByZWN0WzFdXSwgdGhpcy50cmFuc2Zvcm0pO1xuXG4gICAgY29uc3QgYm90dG9tUmlnaHQgPSBfdXRpbC5VdGlsLmFwcGx5VHJhbnNmb3JtKFtyZWN0WzJdLCByZWN0WzNdXSwgdGhpcy50cmFuc2Zvcm0pO1xuXG4gICAgcmV0dXJuIFt0b3BMZWZ0WzBdLCB0b3BMZWZ0WzFdLCBib3R0b21SaWdodFswXSwgYm90dG9tUmlnaHRbMV1dO1xuICB9XG5cbiAgY29udmVydFRvUGRmUG9pbnQoeCwgeSkge1xuICAgIHJldHVybiBfdXRpbC5VdGlsLmFwcGx5SW52ZXJzZVRyYW5zZm9ybShbeCwgeV0sIHRoaXMudHJhbnNmb3JtKTtcbiAgfVxuXG59XG5cbmV4cG9ydHMuUGFnZVZpZXdwb3J0ID0gUGFnZVZpZXdwb3J0O1xuXG5jbGFzcyBSZW5kZXJpbmdDYW5jZWxsZWRFeGNlcHRpb24gZXh0ZW5kcyBfdXRpbC5CYXNlRXhjZXB0aW9uIHtcbiAgY29uc3RydWN0b3IobXNnLCB0eXBlKSB7XG4gICAgc3VwZXIobXNnLCBcIlJlbmRlcmluZ0NhbmNlbGxlZEV4Y2VwdGlvblwiKTtcbiAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICB9XG5cbn1cblxuZXhwb3J0cy5SZW5kZXJpbmdDYW5jZWxsZWRFeGNlcHRpb24gPSBSZW5kZXJpbmdDYW5jZWxsZWRFeGNlcHRpb247XG5cbmZ1bmN0aW9uIGlzRGF0YVNjaGVtZSh1cmwpIHtcbiAgY29uc3QgaWkgPSB1cmwubGVuZ3RoO1xuICBsZXQgaSA9IDA7XG5cbiAgd2hpbGUgKGkgPCBpaSAmJiB1cmxbaV0udHJpbSgpID09PSBcIlwiKSB7XG4gICAgaSsrO1xuICB9XG5cbiAgcmV0dXJuIHVybC5zdWJzdHJpbmcoaSwgaSArIDUpLnRvTG93ZXJDYXNlKCkgPT09IFwiZGF0YTpcIjtcbn1cblxuZnVuY3Rpb24gaXNQZGZGaWxlKGZpbGVuYW1lKSB7XG4gIHJldHVybiB0eXBlb2YgZmlsZW5hbWUgPT09IFwic3RyaW5nXCIgJiYgL1xcLnBkZiQvaS50ZXN0KGZpbGVuYW1lKTtcbn1cblxuZnVuY3Rpb24gZ2V0RmlsZW5hbWVGcm9tVXJsKHVybCkge1xuICBjb25zdCBhbmNob3IgPSB1cmwuaW5kZXhPZihcIiNcIik7XG4gIGNvbnN0IHF1ZXJ5ID0gdXJsLmluZGV4T2YoXCI/XCIpO1xuICBjb25zdCBlbmQgPSBNYXRoLm1pbihhbmNob3IgPiAwID8gYW5jaG9yIDogdXJsLmxlbmd0aCwgcXVlcnkgPiAwID8gcXVlcnkgOiB1cmwubGVuZ3RoKTtcbiAgcmV0dXJuIHVybC5zdWJzdHJpbmcodXJsLmxhc3RJbmRleE9mKFwiL1wiLCBlbmQpICsgMSwgZW5kKTtcbn1cblxuZnVuY3Rpb24gZ2V0UGRmRmlsZW5hbWVGcm9tVXJsKHVybCwgZGVmYXVsdEZpbGVuYW1lID0gXCJkb2N1bWVudC5wZGZcIikge1xuICBpZiAodHlwZW9mIHVybCAhPT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiBkZWZhdWx0RmlsZW5hbWU7XG4gIH1cblxuICBpZiAoaXNEYXRhU2NoZW1lKHVybCkpIHtcbiAgICAoMCwgX3V0aWwud2FybikoJ2dldFBkZkZpbGVuYW1lRnJvbVVybDogaWdub3JlIFwiZGF0YTpcIi1VUkwgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMuJyk7XG4gICAgcmV0dXJuIGRlZmF1bHRGaWxlbmFtZTtcbiAgfVxuXG4gIGNvbnN0IHJlVVJJID0gL14oPzooPzpbXjpdKzopP1xcL1xcL1teL10rKT8oW14/I10qKShcXD9bXiNdKik/KCMuKik/JC87XG4gIGNvbnN0IHJlRmlsZW5hbWUgPSAvW14vPyM9XStcXC5wZGZcXGIoPyEuKlxcLnBkZlxcYikvaTtcbiAgY29uc3Qgc3BsaXRVUkkgPSByZVVSSS5leGVjKHVybCk7XG4gIGxldCBzdWdnZXN0ZWRGaWxlbmFtZSA9IHJlRmlsZW5hbWUuZXhlYyhzcGxpdFVSSVsxXSkgfHwgcmVGaWxlbmFtZS5leGVjKHNwbGl0VVJJWzJdKSB8fCByZUZpbGVuYW1lLmV4ZWMoc3BsaXRVUklbM10pO1xuXG4gIGlmIChzdWdnZXN0ZWRGaWxlbmFtZSkge1xuICAgIHN1Z2dlc3RlZEZpbGVuYW1lID0gc3VnZ2VzdGVkRmlsZW5hbWVbMF07XG5cbiAgICBpZiAoc3VnZ2VzdGVkRmlsZW5hbWUuaW5jbHVkZXMoXCIlXCIpKSB7XG4gICAgICB0cnkge1xuICAgICAgICBzdWdnZXN0ZWRGaWxlbmFtZSA9IHJlRmlsZW5hbWUuZXhlYyhkZWNvZGVVUklDb21wb25lbnQoc3VnZ2VzdGVkRmlsZW5hbWUpKVswXTtcbiAgICAgIH0gY2F0Y2ggKGV4KSB7fVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzdWdnZXN0ZWRGaWxlbmFtZSB8fCBkZWZhdWx0RmlsZW5hbWU7XG59XG5cbmNsYXNzIFN0YXRUaW1lciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuc3RhcnRlZCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgdGhpcy50aW1lcyA9IFtdO1xuICB9XG5cbiAgdGltZShuYW1lKSB7XG4gICAgaWYgKG5hbWUgaW4gdGhpcy5zdGFydGVkKSB7XG4gICAgICAoMCwgX3V0aWwud2FybikoYFRpbWVyIGlzIGFscmVhZHkgcnVubmluZyBmb3IgJHtuYW1lfWApO1xuICAgIH1cblxuICAgIHRoaXMuc3RhcnRlZFtuYW1lXSA9IERhdGUubm93KCk7XG4gIH1cblxuICB0aW1lRW5kKG5hbWUpIHtcbiAgICBpZiAoIShuYW1lIGluIHRoaXMuc3RhcnRlZCkpIHtcbiAgICAgICgwLCBfdXRpbC53YXJuKShgVGltZXIgaGFzIG5vdCBiZWVuIHN0YXJ0ZWQgZm9yICR7bmFtZX1gKTtcbiAgICB9XG5cbiAgICB0aGlzLnRpbWVzLnB1c2goe1xuICAgICAgbmFtZSxcbiAgICAgIHN0YXJ0OiB0aGlzLnN0YXJ0ZWRbbmFtZV0sXG4gICAgICBlbmQ6IERhdGUubm93KClcbiAgICB9KTtcbiAgICBkZWxldGUgdGhpcy5zdGFydGVkW25hbWVdO1xuICB9XG5cbiAgdG9TdHJpbmcoKSB7XG4gICAgY29uc3Qgb3V0QnVmID0gW107XG4gICAgbGV0IGxvbmdlc3QgPSAwO1xuXG4gICAgZm9yIChjb25zdCB0aW1lIG9mIHRoaXMudGltZXMpIHtcbiAgICAgIGNvbnN0IG5hbWUgPSB0aW1lLm5hbWU7XG5cbiAgICAgIGlmIChuYW1lLmxlbmd0aCA+IGxvbmdlc3QpIHtcbiAgICAgICAgbG9uZ2VzdCA9IG5hbWUubGVuZ3RoO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgdGltZSBvZiB0aGlzLnRpbWVzKSB7XG4gICAgICBjb25zdCBkdXJhdGlvbiA9IHRpbWUuZW5kIC0gdGltZS5zdGFydDtcbiAgICAgIG91dEJ1Zi5wdXNoKGAke3RpbWUubmFtZS5wYWRFbmQobG9uZ2VzdCl9ICR7ZHVyYXRpb259bXNcXG5gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0QnVmLmpvaW4oXCJcIik7XG4gIH1cblxufVxuXG5leHBvcnRzLlN0YXRUaW1lciA9IFN0YXRUaW1lcjtcblxuZnVuY3Rpb24gaXNWYWxpZEZldGNoVXJsKHVybCwgYmFzZVVybCkge1xuICB0cnkge1xuICAgIGNvbnN0IHtcbiAgICAgIHByb3RvY29sXG4gICAgfSA9IGJhc2VVcmwgPyBuZXcgVVJMKHVybCwgYmFzZVVybCkgOiBuZXcgVVJMKHVybCk7XG4gICAgcmV0dXJuIHByb3RvY29sID09PSBcImh0dHA6XCIgfHwgcHJvdG9jb2wgPT09IFwiaHR0cHM6XCI7XG4gIH0gY2F0Y2ggKGV4KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGxvYWRTY3JpcHQoc3JjLCByZW1vdmVTY3JpcHRFbGVtZW50ID0gZmFsc2UpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic2NyaXB0XCIpO1xuICAgIHNjcmlwdC5zcmMgPSBzcmM7XG5cbiAgICBzY3JpcHQub25sb2FkID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgaWYgKHJlbW92ZVNjcmlwdEVsZW1lbnQpIHtcbiAgICAgICAgc2NyaXB0LnJlbW92ZSgpO1xuICAgICAgfVxuXG4gICAgICByZXNvbHZlKGV2dCk7XG4gICAgfTtcblxuICAgIHNjcmlwdC5vbmVycm9yID0gZnVuY3Rpb24gKCkge1xuICAgICAgcmVqZWN0KG5ldyBFcnJvcihgQ2Fubm90IGxvYWQgc2NyaXB0IGF0OiAke3NjcmlwdC5zcmN9YCkpO1xuICAgIH07XG5cbiAgICAoZG9jdW1lbnQuaGVhZCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLmFwcGVuZENoaWxkKHNjcmlwdCk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBkZXByZWNhdGVkKGRldGFpbHMpIHtcbiAgY29uc29sZS5sb2coXCJEZXByZWNhdGVkIEFQSSB1c2FnZTogXCIgKyBkZXRhaWxzKTtcbn1cblxubGV0IHBkZkRhdGVTdHJpbmdSZWdleDtcblxuY2xhc3MgUERGRGF0ZVN0cmluZyB7XG4gIHN0YXRpYyB0b0RhdGVPYmplY3QoaW5wdXQpIHtcbiAgICBpZiAoIWlucHV0IHx8IHR5cGVvZiBpbnB1dCAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgaWYgKCFwZGZEYXRlU3RyaW5nUmVnZXgpIHtcbiAgICAgIHBkZkRhdGVTdHJpbmdSZWdleCA9IG5ldyBSZWdFeHAoXCJeRDpcIiArIFwiKFxcXFxkezR9KVwiICsgXCIoXFxcXGR7Mn0pP1wiICsgXCIoXFxcXGR7Mn0pP1wiICsgXCIoXFxcXGR7Mn0pP1wiICsgXCIoXFxcXGR7Mn0pP1wiICsgXCIoXFxcXGR7Mn0pP1wiICsgXCIoW1p8K3wtXSk/XCIgKyBcIihcXFxcZHsyfSk/XCIgKyBcIic/XCIgKyBcIihcXFxcZHsyfSk/XCIgKyBcIic/XCIpO1xuICAgIH1cblxuICAgIGNvbnN0IG1hdGNoZXMgPSBwZGZEYXRlU3RyaW5nUmVnZXguZXhlYyhpbnB1dCk7XG5cbiAgICBpZiAoIW1hdGNoZXMpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHllYXIgPSBwYXJzZUludChtYXRjaGVzWzFdLCAxMCk7XG4gICAgbGV0IG1vbnRoID0gcGFyc2VJbnQobWF0Y2hlc1syXSwgMTApO1xuICAgIG1vbnRoID0gbW9udGggPj0gMSAmJiBtb250aCA8PSAxMiA/IG1vbnRoIC0gMSA6IDA7XG4gICAgbGV0IGRheSA9IHBhcnNlSW50KG1hdGNoZXNbM10sIDEwKTtcbiAgICBkYXkgPSBkYXkgPj0gMSAmJiBkYXkgPD0gMzEgPyBkYXkgOiAxO1xuICAgIGxldCBob3VyID0gcGFyc2VJbnQobWF0Y2hlc1s0XSwgMTApO1xuICAgIGhvdXIgPSBob3VyID49IDAgJiYgaG91ciA8PSAyMyA/IGhvdXIgOiAwO1xuICAgIGxldCBtaW51dGUgPSBwYXJzZUludChtYXRjaGVzWzVdLCAxMCk7XG4gICAgbWludXRlID0gbWludXRlID49IDAgJiYgbWludXRlIDw9IDU5ID8gbWludXRlIDogMDtcbiAgICBsZXQgc2Vjb25kID0gcGFyc2VJbnQobWF0Y2hlc1s2XSwgMTApO1xuICAgIHNlY29uZCA9IHNlY29uZCA+PSAwICYmIHNlY29uZCA8PSA1OSA/IHNlY29uZCA6IDA7XG4gICAgY29uc3QgdW5pdmVyc2FsVGltZVJlbGF0aW9uID0gbWF0Y2hlc1s3XSB8fCBcIlpcIjtcbiAgICBsZXQgb2Zmc2V0SG91ciA9IHBhcnNlSW50KG1hdGNoZXNbOF0sIDEwKTtcbiAgICBvZmZzZXRIb3VyID0gb2Zmc2V0SG91ciA+PSAwICYmIG9mZnNldEhvdXIgPD0gMjMgPyBvZmZzZXRIb3VyIDogMDtcbiAgICBsZXQgb2Zmc2V0TWludXRlID0gcGFyc2VJbnQobWF0Y2hlc1s5XSwgMTApIHx8IDA7XG4gICAgb2Zmc2V0TWludXRlID0gb2Zmc2V0TWludXRlID49IDAgJiYgb2Zmc2V0TWludXRlIDw9IDU5ID8gb2Zmc2V0TWludXRlIDogMDtcblxuICAgIGlmICh1bml2ZXJzYWxUaW1lUmVsYXRpb24gPT09IFwiLVwiKSB7XG4gICAgICBob3VyICs9IG9mZnNldEhvdXI7XG4gICAgICBtaW51dGUgKz0gb2Zmc2V0TWludXRlO1xuICAgIH0gZWxzZSBpZiAodW5pdmVyc2FsVGltZVJlbGF0aW9uID09PSBcIitcIikge1xuICAgICAgaG91ciAtPSBvZmZzZXRIb3VyO1xuICAgICAgbWludXRlIC09IG9mZnNldE1pbnV0ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IERhdGUoRGF0ZS5VVEMoeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBzZWNvbmQpKTtcbiAgfVxuXG59XG5cbmV4cG9ydHMuUERGRGF0ZVN0cmluZyA9IFBERkRhdGVTdHJpbmc7XG5cbmZ1bmN0aW9uIGdldFhmYVBhZ2VWaWV3cG9ydCh4ZmFQYWdlLCB7XG4gIHNjYWxlID0gMSxcbiAgcm90YXRpb24gPSAwXG59KSB7XG4gIGNvbnN0IHtcbiAgICB3aWR0aCxcbiAgICBoZWlnaHRcbiAgfSA9IHhmYVBhZ2UuYXR0cmlidXRlcy5zdHlsZTtcbiAgY29uc3Qgdmlld0JveCA9IFswLCAwLCBwYXJzZUludCh3aWR0aCksIHBhcnNlSW50KGhlaWdodCldO1xuICByZXR1cm4gbmV3IFBhZ2VWaWV3cG9ydCh7XG4gICAgdmlld0JveCxcbiAgICBzY2FsZSxcbiAgICByb3RhdGlvblxuICB9KTtcbn1cblxuLyoqKi8gfSksXG4vKiA2ICovXG4vKioqLyAoKF9fdW51c2VkX3dlYnBhY2tfbW9kdWxlLCBleHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5leHBvcnRzLkJhc2VTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSA9IGV4cG9ydHMuQmFzZVNWR0ZhY3RvcnkgPSBleHBvcnRzLkJhc2VDYW52YXNGYWN0b3J5ID0gZXhwb3J0cy5CYXNlQ01hcFJlYWRlckZhY3RvcnkgPSB2b2lkIDA7XG5cbnZhciBfdXRpbCA9IF9fd19wZGZqc19yZXF1aXJlX18oMSk7XG5cbmNsYXNzIEJhc2VDYW52YXNGYWN0b3J5IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgaWYgKHRoaXMuY29uc3RydWN0b3IgPT09IEJhc2VDYW52YXNGYWN0b3J5KSB7XG4gICAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiQ2Fubm90IGluaXRpYWxpemUgQmFzZUNhbnZhc0ZhY3RvcnkuXCIpO1xuICAgIH1cbiAgfVxuXG4gIGNyZWF0ZSh3aWR0aCwgaGVpZ2h0KSB7XG4gICAgaWYgKHdpZHRoIDw9IDAgfHwgaGVpZ2h0IDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgY2FudmFzIHNpemVcIik7XG4gICAgfVxuXG4gICAgY29uc3QgY2FudmFzID0gdGhpcy5fY3JlYXRlQ2FudmFzKHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNhbnZhcyxcbiAgICAgIGNvbnRleHQ6IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIilcbiAgICB9O1xuICB9XG5cbiAgcmVzZXQoY2FudmFzQW5kQ29udGV4dCwgd2lkdGgsIGhlaWdodCkge1xuICAgIGlmICghY2FudmFzQW5kQ29udGV4dC5jYW52YXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbnZhcyBpcyBub3Qgc3BlY2lmaWVkXCIpO1xuICAgIH1cblxuICAgIGlmICh3aWR0aCA8PSAwIHx8IGhlaWdodCA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGNhbnZhcyBzaXplXCIpO1xuICAgIH1cblxuICAgIGNhbnZhc0FuZENvbnRleHQuY2FudmFzLndpZHRoID0gd2lkdGg7XG4gICAgY2FudmFzQW5kQ29udGV4dC5jYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xuICB9XG5cbiAgZGVzdHJveShjYW52YXNBbmRDb250ZXh0KSB7XG4gICAgaWYgKCFjYW52YXNBbmRDb250ZXh0LmNhbnZhcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FudmFzIGlzIG5vdCBzcGVjaWZpZWRcIik7XG4gICAgfVxuXG4gICAgY2FudmFzQW5kQ29udGV4dC5jYW52YXMud2lkdGggPSAwO1xuICAgIGNhbnZhc0FuZENvbnRleHQuY2FudmFzLmhlaWdodCA9IDA7XG4gICAgY2FudmFzQW5kQ29udGV4dC5jYW52YXMgPSBudWxsO1xuICAgIGNhbnZhc0FuZENvbnRleHQuY29udGV4dCA9IG51bGw7XG4gIH1cblxuICBfY3JlYXRlQ2FudmFzKHdpZHRoLCBoZWlnaHQpIHtcbiAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiQWJzdHJhY3QgbWV0aG9kIGBfY3JlYXRlQ2FudmFzYCBjYWxsZWQuXCIpO1xuICB9XG5cbn1cblxuZXhwb3J0cy5CYXNlQ2FudmFzRmFjdG9yeSA9IEJhc2VDYW52YXNGYWN0b3J5O1xuXG5jbGFzcyBCYXNlQ01hcFJlYWRlckZhY3Rvcnkge1xuICBjb25zdHJ1Y3Rvcih7XG4gICAgYmFzZVVybCA9IG51bGwsXG4gICAgaXNDb21wcmVzc2VkID0gZmFsc2VcbiAgfSkge1xuICAgIGlmICh0aGlzLmNvbnN0cnVjdG9yID09PSBCYXNlQ01hcFJlYWRlckZhY3RvcnkpIHtcbiAgICAgICgwLCBfdXRpbC51bnJlYWNoYWJsZSkoXCJDYW5ub3QgaW5pdGlhbGl6ZSBCYXNlQ01hcFJlYWRlckZhY3RvcnkuXCIpO1xuICAgIH1cblxuICAgIHRoaXMuYmFzZVVybCA9IGJhc2VVcmw7XG4gICAgdGhpcy5pc0NvbXByZXNzZWQgPSBpc0NvbXByZXNzZWQ7XG4gIH1cblxuICBhc3luYyBmZXRjaCh7XG4gICAgbmFtZVxuICB9KSB7XG4gICAgaWYgKCF0aGlzLmJhc2VVcmwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIENNYXAgXCJiYXNlVXJsXCIgcGFyYW1ldGVyIG11c3QgYmUgc3BlY2lmaWVkLCBlbnN1cmUgdGhhdCAnICsgJ3RoZSBcImNNYXBVcmxcIiBhbmQgXCJjTWFwUGFja2VkXCIgQVBJIHBhcmFtZXRlcnMgYXJlIHByb3ZpZGVkLicpO1xuICAgIH1cblxuICAgIGlmICghbmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ01hcCBuYW1lIG11c3QgYmUgc3BlY2lmaWVkLlwiKTtcbiAgICB9XG5cbiAgICBjb25zdCB1cmwgPSB0aGlzLmJhc2VVcmwgKyBuYW1lICsgKHRoaXMuaXNDb21wcmVzc2VkID8gXCIuYmNtYXBcIiA6IFwiXCIpO1xuICAgIGNvbnN0IGNvbXByZXNzaW9uVHlwZSA9IHRoaXMuaXNDb21wcmVzc2VkID8gX3V0aWwuQ01hcENvbXByZXNzaW9uVHlwZS5CSU5BUlkgOiBfdXRpbC5DTWFwQ29tcHJlc3Npb25UeXBlLk5PTkU7XG4gICAgcmV0dXJuIHRoaXMuX2ZldGNoRGF0YSh1cmwsIGNvbXByZXNzaW9uVHlwZSkuY2F0Y2gocmVhc29uID0+IHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGxvYWQgJHt0aGlzLmlzQ29tcHJlc3NlZCA/IFwiYmluYXJ5IFwiIDogXCJcIn1DTWFwIGF0OiAke3VybH1gKTtcbiAgICB9KTtcbiAgfVxuXG4gIF9mZXRjaERhdGEodXJsLCBjb21wcmVzc2lvblR5cGUpIHtcbiAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiQWJzdHJhY3QgbWV0aG9kIGBfZmV0Y2hEYXRhYCBjYWxsZWQuXCIpO1xuICB9XG5cbn1cblxuZXhwb3J0cy5CYXNlQ01hcFJlYWRlckZhY3RvcnkgPSBCYXNlQ01hcFJlYWRlckZhY3Rvcnk7XG5cbmNsYXNzIEJhc2VTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSB7XG4gIGNvbnN0cnVjdG9yKHtcbiAgICBiYXNlVXJsID0gbnVsbFxuICB9KSB7XG4gICAgaWYgKHRoaXMuY29uc3RydWN0b3IgPT09IEJhc2VTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSkge1xuICAgICAgKDAsIF91dGlsLnVucmVhY2hhYmxlKShcIkNhbm5vdCBpbml0aWFsaXplIEJhc2VTdGFuZGFyZEZvbnREYXRhRmFjdG9yeS5cIik7XG4gICAgfVxuXG4gICAgdGhpcy5iYXNlVXJsID0gYmFzZVVybDtcbiAgfVxuXG4gIGFzeW5jIGZldGNoKHtcbiAgICBmaWxlbmFtZVxuICB9KSB7XG4gICAgaWYgKCF0aGlzLmJhc2VVcmwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIHN0YW5kYXJkIGZvbnQgXCJiYXNlVXJsXCIgcGFyYW1ldGVyIG11c3QgYmUgc3BlY2lmaWVkLCBlbnN1cmUgdGhhdCAnICsgJ3RoZSBcInN0YW5kYXJkRm9udERhdGFVcmxcIiBBUEkgcGFyYW1ldGVyIGlzIHByb3ZpZGVkLicpO1xuICAgIH1cblxuICAgIGlmICghZmlsZW5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkZvbnQgZmlsZW5hbWUgbXVzdCBiZSBzcGVjaWZpZWQuXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IHVybCA9IGAke3RoaXMuYmFzZVVybH0ke2ZpbGVuYW1lfWA7XG4gICAgcmV0dXJuIHRoaXMuX2ZldGNoRGF0YSh1cmwpLmNhdGNoKHJlYXNvbiA9PiB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBsb2FkIGZvbnQgZGF0YSBhdDogJHt1cmx9YCk7XG4gICAgfSk7XG4gIH1cblxuICBfZmV0Y2hEYXRhKHVybCkge1xuICAgICgwLCBfdXRpbC51bnJlYWNoYWJsZSkoXCJBYnN0cmFjdCBtZXRob2QgYF9mZXRjaERhdGFgIGNhbGxlZC5cIik7XG4gIH1cblxufVxuXG5leHBvcnRzLkJhc2VTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSA9IEJhc2VTdGFuZGFyZEZvbnREYXRhRmFjdG9yeTtcblxuY2xhc3MgQmFzZVNWR0ZhY3Rvcnkge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBpZiAodGhpcy5jb25zdHJ1Y3RvciA9PT0gQmFzZVNWR0ZhY3RvcnkpIHtcbiAgICAgICgwLCBfdXRpbC51bnJlYWNoYWJsZSkoXCJDYW5ub3QgaW5pdGlhbGl6ZSBCYXNlU1ZHRmFjdG9yeS5cIik7XG4gICAgfVxuICB9XG5cbiAgY3JlYXRlKHdpZHRoLCBoZWlnaHQpIHtcbiAgICBpZiAod2lkdGggPD0gMCB8fCBoZWlnaHQgPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBTVkcgZGltZW5zaW9uc1wiKTtcbiAgICB9XG5cbiAgICBjb25zdCBzdmcgPSB0aGlzLl9jcmVhdGVTVkcoXCJzdmc6c3ZnXCIpO1xuXG4gICAgc3ZnLnNldEF0dHJpYnV0ZShcInZlcnNpb25cIiwgXCIxLjFcIik7XG4gICAgc3ZnLnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIGAke3dpZHRofXB4YCk7XG4gICAgc3ZnLnNldEF0dHJpYnV0ZShcImhlaWdodFwiLCBgJHtoZWlnaHR9cHhgKTtcbiAgICBzdmcuc2V0QXR0cmlidXRlKFwicHJlc2VydmVBc3BlY3RSYXRpb1wiLCBcIm5vbmVcIik7XG4gICAgc3ZnLnNldEF0dHJpYnV0ZShcInZpZXdCb3hcIiwgYDAgMCAke3dpZHRofSAke2hlaWdodH1gKTtcbiAgICByZXR1cm4gc3ZnO1xuICB9XG5cbiAgY3JlYXRlRWxlbWVudCh0eXBlKSB7XG4gICAgaWYgKHR5cGVvZiB0eXBlICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIFNWRyBlbGVtZW50IHR5cGVcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZVNWRyh0eXBlKTtcbiAgfVxuXG4gIF9jcmVhdGVTVkcodHlwZSkge1xuICAgICgwLCBfdXRpbC51bnJlYWNoYWJsZSkoXCJBYnN0cmFjdCBtZXRob2QgYF9jcmVhdGVTVkdgIGNhbGxlZC5cIik7XG4gIH1cblxufVxuXG5leHBvcnRzLkJhc2VTVkdGYWN0b3J5ID0gQmFzZVNWR0ZhY3Rvcnk7XG5cbi8qKiovIH0pLFxuLyogNyAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5Gb250TG9hZGVyID0gZXhwb3J0cy5Gb250RmFjZU9iamVjdCA9IHZvaWQgMDtcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxuY2xhc3MgQmFzZUZvbnRMb2FkZXIge1xuICBjb25zdHJ1Y3Rvcih7XG4gICAgZG9jSWQsXG4gICAgb25VbnN1cHBvcnRlZEZlYXR1cmUsXG4gICAgb3duZXJEb2N1bWVudCA9IGdsb2JhbFRoaXMuZG9jdW1lbnQsXG4gICAgc3R5bGVFbGVtZW50ID0gbnVsbFxuICB9KSB7XG4gICAgaWYgKHRoaXMuY29uc3RydWN0b3IgPT09IEJhc2VGb250TG9hZGVyKSB7XG4gICAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiQ2Fubm90IGluaXRpYWxpemUgQmFzZUZvbnRMb2FkZXIuXCIpO1xuICAgIH1cblxuICAgIHRoaXMuZG9jSWQgPSBkb2NJZDtcbiAgICB0aGlzLl9vblVuc3VwcG9ydGVkRmVhdHVyZSA9IG9uVW5zdXBwb3J0ZWRGZWF0dXJlO1xuICAgIHRoaXMuX2RvY3VtZW50ID0gb3duZXJEb2N1bWVudDtcbiAgICB0aGlzLm5hdGl2ZUZvbnRGYWNlcyA9IFtdO1xuICAgIHRoaXMuc3R5bGVFbGVtZW50ID0gbnVsbDtcbiAgfVxuXG4gIGFkZE5hdGl2ZUZvbnRGYWNlKG5hdGl2ZUZvbnRGYWNlKSB7XG4gICAgdGhpcy5uYXRpdmVGb250RmFjZXMucHVzaChuYXRpdmVGb250RmFjZSk7XG5cbiAgICB0aGlzLl9kb2N1bWVudC5mb250cy5hZGQobmF0aXZlRm9udEZhY2UpO1xuICB9XG5cbiAgaW5zZXJ0UnVsZShydWxlKSB7XG4gICAgbGV0IHN0eWxlRWxlbWVudCA9IHRoaXMuc3R5bGVFbGVtZW50O1xuXG4gICAgaWYgKCFzdHlsZUVsZW1lbnQpIHtcbiAgICAgIHN0eWxlRWxlbWVudCA9IHRoaXMuc3R5bGVFbGVtZW50ID0gdGhpcy5fZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInN0eWxlXCIpO1xuICAgICAgc3R5bGVFbGVtZW50LmlkID0gYFBERkpTX0ZPTlRfU1RZTEVfVEFHXyR7dGhpcy5kb2NJZH1gO1xuXG4gICAgICB0aGlzLl9kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJoZWFkXCIpWzBdLmFwcGVuZENoaWxkKHN0eWxlRWxlbWVudCk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3R5bGVTaGVldCA9IHN0eWxlRWxlbWVudC5zaGVldDtcbiAgICBzdHlsZVNoZWV0Lmluc2VydFJ1bGUocnVsZSwgc3R5bGVTaGVldC5jc3NSdWxlcy5sZW5ndGgpO1xuICB9XG5cbiAgY2xlYXIoKSB7XG4gICAgZm9yIChjb25zdCBuYXRpdmVGb250RmFjZSBvZiB0aGlzLm5hdGl2ZUZvbnRGYWNlcykge1xuICAgICAgdGhpcy5fZG9jdW1lbnQuZm9udHMuZGVsZXRlKG5hdGl2ZUZvbnRGYWNlKTtcbiAgICB9XG5cbiAgICB0aGlzLm5hdGl2ZUZvbnRGYWNlcy5sZW5ndGggPSAwO1xuXG4gICAgaWYgKHRoaXMuc3R5bGVFbGVtZW50KSB7XG4gICAgICB0aGlzLnN0eWxlRWxlbWVudC5yZW1vdmUoKTtcbiAgICAgIHRoaXMuc3R5bGVFbGVtZW50ID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBhc3luYyBiaW5kKGZvbnQpIHtcbiAgICBpZiAoZm9udC5hdHRhY2hlZCB8fCBmb250Lm1pc3NpbmdGaWxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZm9udC5hdHRhY2hlZCA9IHRydWU7XG5cbiAgICBpZiAodGhpcy5pc0ZvbnRMb2FkaW5nQVBJU3VwcG9ydGVkKSB7XG4gICAgICBjb25zdCBuYXRpdmVGb250RmFjZSA9IGZvbnQuY3JlYXRlTmF0aXZlRm9udEZhY2UoKTtcblxuICAgICAgaWYgKG5hdGl2ZUZvbnRGYWNlKSB7XG4gICAgICAgIHRoaXMuYWRkTmF0aXZlRm9udEZhY2UobmF0aXZlRm9udEZhY2UpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgbmF0aXZlRm9udEZhY2UubG9hZGVkO1xuICAgICAgICB9IGNhdGNoIChleCkge1xuICAgICAgICAgIHRoaXMuX29uVW5zdXBwb3J0ZWRGZWF0dXJlKHtcbiAgICAgICAgICAgIGZlYXR1cmVJZDogX3V0aWwuVU5TVVBQT1JURURfRkVBVFVSRVMuZXJyb3JGb250TG9hZE5hdGl2ZVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgKDAsIF91dGlsLndhcm4pKGBGYWlsZWQgdG8gbG9hZCBmb250ICcke25hdGl2ZUZvbnRGYWNlLmZhbWlseX0nOiAnJHtleH0nLmApO1xuICAgICAgICAgIGZvbnQuZGlzYWJsZUZvbnRGYWNlID0gdHJ1ZTtcbiAgICAgICAgICB0aHJvdyBleDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcnVsZSA9IGZvbnQuY3JlYXRlRm9udEZhY2VSdWxlKCk7XG5cbiAgICBpZiAocnVsZSkge1xuICAgICAgdGhpcy5pbnNlcnRSdWxlKHJ1bGUpO1xuXG4gICAgICBpZiAodGhpcy5pc1N5bmNGb250TG9hZGluZ1N1cHBvcnRlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gdGhpcy5fcXVldWVMb2FkaW5nQ2FsbGJhY2socmVzb2x2ZSk7XG5cbiAgICAgICAgdGhpcy5fcHJlcGFyZUZvbnRMb2FkRXZlbnQoW3J1bGVdLCBbZm9udF0sIHJlcXVlc3QpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgX3F1ZXVlTG9hZGluZ0NhbGxiYWNrKGNhbGxiYWNrKSB7XG4gICAgKDAsIF91dGlsLnVucmVhY2hhYmxlKShcIkFic3RyYWN0IG1ldGhvZCBgX3F1ZXVlTG9hZGluZ0NhbGxiYWNrYC5cIik7XG4gIH1cblxuICBnZXQgaXNGb250TG9hZGluZ0FQSVN1cHBvcnRlZCgpIHtcbiAgICBjb25zdCBoYXNGb250cyA9ICEhdGhpcy5fZG9jdW1lbnQ/LmZvbnRzO1xuICAgIHJldHVybiAoMCwgX3V0aWwuc2hhZG93KSh0aGlzLCBcImlzRm9udExvYWRpbmdBUElTdXBwb3J0ZWRcIiwgaGFzRm9udHMpO1xuICB9XG5cbiAgZ2V0IGlzU3luY0ZvbnRMb2FkaW5nU3VwcG9ydGVkKCkge1xuICAgICgwLCBfdXRpbC51bnJlYWNoYWJsZSkoXCJBYnN0cmFjdCBtZXRob2QgYGlzU3luY0ZvbnRMb2FkaW5nU3VwcG9ydGVkYC5cIik7XG4gIH1cblxuICBnZXQgX2xvYWRUZXN0Rm9udCgpIHtcbiAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiQWJzdHJhY3QgbWV0aG9kIGBfbG9hZFRlc3RGb250YC5cIik7XG4gIH1cblxuICBfcHJlcGFyZUZvbnRMb2FkRXZlbnQocnVsZXMsIGZvbnRzVG9Mb2FkLCByZXF1ZXN0KSB7XG4gICAgKDAsIF91dGlsLnVucmVhY2hhYmxlKShcIkFic3RyYWN0IG1ldGhvZCBgX3ByZXBhcmVGb250TG9hZEV2ZW50YC5cIik7XG4gIH1cblxufVxuXG5sZXQgRm9udExvYWRlcjtcbmV4cG9ydHMuRm9udExvYWRlciA9IEZvbnRMb2FkZXI7XG57XG4gIGV4cG9ydHMuRm9udExvYWRlciA9IEZvbnRMb2FkZXIgPSBjbGFzcyBHZW5lcmljRm9udExvYWRlciBleHRlbmRzIEJhc2VGb250TG9hZGVyIHtcbiAgICBjb25zdHJ1Y3RvcihwYXJhbXMpIHtcbiAgICAgIHN1cGVyKHBhcmFtcyk7XG4gICAgICB0aGlzLmxvYWRpbmdDb250ZXh0ID0ge1xuICAgICAgICByZXF1ZXN0czogW10sXG4gICAgICAgIG5leHRSZXF1ZXN0SWQ6IDBcbiAgICAgIH07XG4gICAgICB0aGlzLmxvYWRUZXN0Rm9udElkID0gMDtcbiAgICB9XG5cbiAgICBnZXQgaXNTeW5jRm9udExvYWRpbmdTdXBwb3J0ZWQoKSB7XG4gICAgICBsZXQgc3VwcG9ydGVkID0gZmFsc2U7XG5cbiAgICAgIGlmICh0eXBlb2YgbmF2aWdhdG9yID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIHN1cHBvcnRlZCA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBtID0gL01vemlsbGFcXC81LjAuKj9ydjooXFxkKykuKj8gR2Vja28vLmV4ZWMobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG5cbiAgICAgICAgaWYgKG0/LlsxXSA+PSAxNCkge1xuICAgICAgICAgIHN1cHBvcnRlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuICgwLCBfdXRpbC5zaGFkb3cpKHRoaXMsIFwiaXNTeW5jRm9udExvYWRpbmdTdXBwb3J0ZWRcIiwgc3VwcG9ydGVkKTtcbiAgICB9XG5cbiAgICBfcXVldWVMb2FkaW5nQ2FsbGJhY2soY2FsbGJhY2spIHtcbiAgICAgIGZ1bmN0aW9uIGNvbXBsZXRlUmVxdWVzdCgpIHtcbiAgICAgICAgKDAsIF91dGlsLmFzc2VydCkoIXJlcXVlc3QuZG9uZSwgXCJjb21wbGV0ZVJlcXVlc3QoKSBjYW5ub3QgYmUgY2FsbGVkIHR3aWNlLlwiKTtcbiAgICAgICAgcmVxdWVzdC5kb25lID0gdHJ1ZTtcblxuICAgICAgICB3aGlsZSAoY29udGV4dC5yZXF1ZXN0cy5sZW5ndGggPiAwICYmIGNvbnRleHQucmVxdWVzdHNbMF0uZG9uZSkge1xuICAgICAgICAgIGNvbnN0IG90aGVyUmVxdWVzdCA9IGNvbnRleHQucmVxdWVzdHMuc2hpZnQoKTtcbiAgICAgICAgICBzZXRUaW1lb3V0KG90aGVyUmVxdWVzdC5jYWxsYmFjaywgMCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMubG9hZGluZ0NvbnRleHQ7XG4gICAgICBjb25zdCByZXF1ZXN0ID0ge1xuICAgICAgICBpZDogYHBkZmpzLWZvbnQtbG9hZGluZy0ke2NvbnRleHQubmV4dFJlcXVlc3RJZCsrfWAsXG4gICAgICAgIGRvbmU6IGZhbHNlLFxuICAgICAgICBjb21wbGV0ZTogY29tcGxldGVSZXF1ZXN0LFxuICAgICAgICBjYWxsYmFja1xuICAgICAgfTtcbiAgICAgIGNvbnRleHQucmVxdWVzdHMucHVzaChyZXF1ZXN0KTtcbiAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgIH1cblxuICAgIGdldCBfbG9hZFRlc3RGb250KCkge1xuICAgICAgY29uc3QgZ2V0TG9hZFRlc3RGb250ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gYXRvYihcIlQxUlVUd0FMQUlBQUF3QXdRMFpHSURIdFpnNEFBQU9ZQUFBQWdVWkdWRTFsa3pad0FBQUVIQUFBQUJ4SFJFVkdBQlFBXCIgKyBcIkZRQUFCRGdBQUFBZVQxTXZNbFlOWXdrQUFBRWdBQUFBWUdOdFlYQUJEUUxVQUFBQ05BQUFBVUpvWldGay94VkZEUUFBXCIgKyBcIkFMd0FBQUEyYUdobFlRZGtBK29BQUFEMEFBQUFKR2h0ZEhnRDZBQUFBQUFFV0FBQUFBWnRZWGh3QUFKUUFBQUFBUmdBXCIgKyBcIkFBQUdibUZ0WlZqbWRINEFBQUdBQUFBQXNYQnZjM1QvaGdBekFBQURlQUFBQUNBQUFRQUFBQUVBQUxaUkZzUmZEenoxXCIgKyBcIkFBc0Q2QUFBQUFET0JPVExBQUFBQU00S0hEd0FBQUFBQStnRElRQUFBQWdBQWdBQUFBQUFBQUFCQUFBRElRQUFBRm9EXCIgKyBcIjZBQUFBQUFENkFBQkFBQUFBQUFBQUFBQUFBQUFBQUFBQVFBQVVBQUFBZ0FBQUFRRDZBSDBBQVVBQUFLS0Fyd0FBQUNNXCIgKyBcIkFvb0N2QUFBQWVBQU1RRUNBQUFDQUFZSkFBQUFBQUFBQUFBQUFRQUFBQUFBQUFBQUFBQUFBRkJtUldRQXdBQXVBQzREXCIgKyBcIklQODRBRm9ESVFBQUFBQUFBUUFBQUFBQUFBQUFBQ0FBSUFBQkFBQUFEZ0N1QUFFQUFBQUFBQUFBQVFBQUFBRUFBQUFBXCIgKyBcIkFBRUFBUUFBQUFFQUFBQUFBQUlBQVFBQUFBRUFBQUFBQUFNQUFRQUFBQUVBQUFBQUFBUUFBUUFBQUFFQUFBQUFBQVVBXCIgKyBcIkFRQUFBQUVBQUFBQUFBWUFBUUFBQUFNQUFRUUpBQUFBQWdBQkFBTUFBUVFKQUFFQUFnQUJBQU1BQVFRSkFBSUFBZ0FCXCIgKyBcIkFBTUFBUVFKQUFNQUFnQUJBQU1BQVFRSkFBUUFBZ0FCQUFNQUFRUUpBQVVBQWdBQkFBTUFBUVFKQUFZQUFnQUJXQUJZXCIgKyBcIkFBQUFBQUFBQXdBQUFBTUFBQUFjQUFFQUFBQUFBRHdBQXdBQkFBQUFIQUFFQUNBQUFBQUVBQVFBQVFBQUFDNy8vd0FBXCIgKyBcIkFDNy8vLy9UQUFFQUFBQUFBQUFCQmdBQUFRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBXCIgKyBcIkFBQUFBQUFBQUFBQUFBQUFBQUVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBXCIgKyBcIkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBXCIgKyBcIkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBXCIgKyBcIkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBXCIgKyBcIkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU1BQUFBQUFBRC9nd0F5QUFBQUFRQUFBQUFBQUFBQUFBQUFBQUFBXCIgKyBcIkFBQUJBQVFFQUFFQkFRSllBQUVCQVNINER3RDRHd0hFQXZnY0EvZ1hCSXdNQVl1TCtuejV0UVhrRDVqM0NCTG5FUUFDXCIgKyBcIkFRRUJJVmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWUFBQUJBUUFBRHdBQ0FRRUVFL3QzXCIgKyBcIkRvdjZmQUg2ZkFUK2ZQcDgrbndIRG9zTUN2bTFDdm0xREF6NmZCUUFBQUFBQUFBQkFBQUFBTW1KYnpFQUFBQUF6Z1RqXCIgKyBcIkZRQUFBQURPQk9RcEFBRUFBQUFBQUFBQURBQVVBQVFBQUFBQkFBQUFBZ0FCQUFBQUFBQUFBQUFENkFBQUFBQUFBQT09XCIpO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuICgwLCBfdXRpbC5zaGFkb3cpKHRoaXMsIFwiX2xvYWRUZXN0Rm9udFwiLCBnZXRMb2FkVGVzdEZvbnQoKSk7XG4gICAgfVxuXG4gICAgX3ByZXBhcmVGb250TG9hZEV2ZW50KHJ1bGVzLCBmb250cywgcmVxdWVzdCkge1xuICAgICAgZnVuY3Rpb24gaW50MzIoZGF0YSwgb2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiBkYXRhLmNoYXJDb2RlQXQob2Zmc2V0KSA8PCAyNCB8IGRhdGEuY2hhckNvZGVBdChvZmZzZXQgKyAxKSA8PCAxNiB8IGRhdGEuY2hhckNvZGVBdChvZmZzZXQgKyAyKSA8PCA4IHwgZGF0YS5jaGFyQ29kZUF0KG9mZnNldCArIDMpICYgMHhmZjtcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gc3BsaWNlU3RyaW5nKHMsIG9mZnNldCwgcmVtb3ZlLCBpbnNlcnQpIHtcbiAgICAgICAgY29uc3QgY2h1bmsxID0gcy5zdWJzdHJpbmcoMCwgb2Zmc2V0KTtcbiAgICAgICAgY29uc3QgY2h1bmsyID0gcy5zdWJzdHJpbmcob2Zmc2V0ICsgcmVtb3ZlKTtcbiAgICAgICAgcmV0dXJuIGNodW5rMSArIGluc2VydCArIGNodW5rMjtcbiAgICAgIH1cblxuICAgICAgbGV0IGksIGlpO1xuXG4gICAgICBjb25zdCBjYW52YXMgPSB0aGlzLl9kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xuXG4gICAgICBjYW52YXMud2lkdGggPSAxO1xuICAgICAgY2FudmFzLmhlaWdodCA9IDE7XG4gICAgICBjb25zdCBjdHggPSBjYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpO1xuICAgICAgbGV0IGNhbGxlZCA9IDA7XG5cbiAgICAgIGZ1bmN0aW9uIGlzRm9udFJlYWR5KG5hbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIGNhbGxlZCsrO1xuXG4gICAgICAgIGlmIChjYWxsZWQgPiAzMCkge1xuICAgICAgICAgICgwLCBfdXRpbC53YXJuKShcIkxvYWQgdGVzdCBmb250IG5ldmVyIGxvYWRlZC5cIik7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjdHguZm9udCA9IFwiMzBweCBcIiArIG5hbWU7XG4gICAgICAgIGN0eC5maWxsVGV4dChcIi5cIiwgMCwgMjApO1xuICAgICAgICBjb25zdCBpbWFnZURhdGEgPSBjdHguZ2V0SW1hZ2VEYXRhKDAsIDAsIDEsIDEpO1xuXG4gICAgICAgIGlmIChpbWFnZURhdGEuZGF0YVszXSA+IDApIHtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHNldFRpbWVvdXQoaXNGb250UmVhZHkuYmluZChudWxsLCBuYW1lLCBjYWxsYmFjaykpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBsb2FkVGVzdEZvbnRJZCA9IGBsdCR7RGF0ZS5ub3coKX0ke3RoaXMubG9hZFRlc3RGb250SWQrK31gO1xuICAgICAgbGV0IGRhdGEgPSB0aGlzLl9sb2FkVGVzdEZvbnQ7XG4gICAgICBjb25zdCBDT01NRU5UX09GRlNFVCA9IDk3NjtcbiAgICAgIGRhdGEgPSBzcGxpY2VTdHJpbmcoZGF0YSwgQ09NTUVOVF9PRkZTRVQsIGxvYWRUZXN0Rm9udElkLmxlbmd0aCwgbG9hZFRlc3RGb250SWQpO1xuICAgICAgY29uc3QgQ0ZGX0NIRUNLU1VNX09GRlNFVCA9IDE2O1xuICAgICAgY29uc3QgWFhYWF9WQUxVRSA9IDB4NTg1ODU4NTg7XG4gICAgICBsZXQgY2hlY2tzdW0gPSBpbnQzMihkYXRhLCBDRkZfQ0hFQ0tTVU1fT0ZGU0VUKTtcblxuICAgICAgZm9yIChpID0gMCwgaWkgPSBsb2FkVGVzdEZvbnRJZC5sZW5ndGggLSAzOyBpIDwgaWk7IGkgKz0gNCkge1xuICAgICAgICBjaGVja3N1bSA9IGNoZWNrc3VtIC0gWFhYWF9WQUxVRSArIGludDMyKGxvYWRUZXN0Rm9udElkLCBpKSB8IDA7XG4gICAgICB9XG5cbiAgICAgIGlmIChpIDwgbG9hZFRlc3RGb250SWQubGVuZ3RoKSB7XG4gICAgICAgIGNoZWNrc3VtID0gY2hlY2tzdW0gLSBYWFhYX1ZBTFVFICsgaW50MzIobG9hZFRlc3RGb250SWQgKyBcIlhYWFwiLCBpKSB8IDA7XG4gICAgICB9XG5cbiAgICAgIGRhdGEgPSBzcGxpY2VTdHJpbmcoZGF0YSwgQ0ZGX0NIRUNLU1VNX09GRlNFVCwgNCwgKDAsIF91dGlsLnN0cmluZzMyKShjaGVja3N1bSkpO1xuICAgICAgY29uc3QgdXJsID0gYHVybChkYXRhOmZvbnQvb3BlbnR5cGU7YmFzZTY0LCR7YnRvYShkYXRhKX0pO2A7XG4gICAgICBjb25zdCBydWxlID0gYEBmb250LWZhY2Uge2ZvbnQtZmFtaWx5OlwiJHtsb2FkVGVzdEZvbnRJZH1cIjtzcmM6JHt1cmx9fWA7XG4gICAgICB0aGlzLmluc2VydFJ1bGUocnVsZSk7XG4gICAgICBjb25zdCBuYW1lcyA9IFtdO1xuXG4gICAgICBmb3IgKGNvbnN0IGZvbnQgb2YgZm9udHMpIHtcbiAgICAgICAgbmFtZXMucHVzaChmb250LmxvYWRlZE5hbWUpO1xuICAgICAgfVxuXG4gICAgICBuYW1lcy5wdXNoKGxvYWRUZXN0Rm9udElkKTtcblxuICAgICAgY29uc3QgZGl2ID0gdGhpcy5fZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcblxuICAgICAgZGl2LnN0eWxlLnZpc2liaWxpdHkgPSBcImhpZGRlblwiO1xuICAgICAgZGl2LnN0eWxlLndpZHRoID0gZGl2LnN0eWxlLmhlaWdodCA9IFwiMTBweFwiO1xuICAgICAgZGl2LnN0eWxlLnBvc2l0aW9uID0gXCJhYnNvbHV0ZVwiO1xuICAgICAgZGl2LnN0eWxlLnRvcCA9IGRpdi5zdHlsZS5sZWZ0ID0gXCIwcHhcIjtcblxuICAgICAgZm9yIChjb25zdCBuYW1lIG9mIG5hbWVzKSB7XG4gICAgICAgIGNvbnN0IHNwYW4gPSB0aGlzLl9kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3BhblwiKTtcblxuICAgICAgICBzcGFuLnRleHRDb250ZW50ID0gXCJIaVwiO1xuICAgICAgICBzcGFuLnN0eWxlLmZvbnRGYW1pbHkgPSBuYW1lO1xuICAgICAgICBkaXYuYXBwZW5kQ2hpbGQoc3Bhbik7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZGl2KTtcblxuICAgICAgaXNGb250UmVhZHkobG9hZFRlc3RGb250SWQsICgpID0+IHtcbiAgICAgICAgZGl2LnJlbW92ZSgpO1xuICAgICAgICByZXF1ZXN0LmNvbXBsZXRlKCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgfTtcbn1cblxuY2xhc3MgRm9udEZhY2VPYmplY3Qge1xuICBjb25zdHJ1Y3Rvcih0cmFuc2xhdGVkRGF0YSwge1xuICAgIGlzRXZhbFN1cHBvcnRlZCA9IHRydWUsXG4gICAgZGlzYWJsZUZvbnRGYWNlID0gZmFsc2UsXG4gICAgaWdub3JlRXJyb3JzID0gZmFsc2UsXG4gICAgb25VbnN1cHBvcnRlZEZlYXR1cmUsXG4gICAgZm9udFJlZ2lzdHJ5ID0gbnVsbFxuICB9KSB7XG4gICAgdGhpcy5jb21waWxlZEdseXBocyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbiAgICBmb3IgKGNvbnN0IGkgaW4gdHJhbnNsYXRlZERhdGEpIHtcbiAgICAgIHRoaXNbaV0gPSB0cmFuc2xhdGVkRGF0YVtpXTtcbiAgICB9XG5cbiAgICB0aGlzLmlzRXZhbFN1cHBvcnRlZCA9IGlzRXZhbFN1cHBvcnRlZCAhPT0gZmFsc2U7XG4gICAgdGhpcy5kaXNhYmxlRm9udEZhY2UgPSBkaXNhYmxlRm9udEZhY2UgPT09IHRydWU7XG4gICAgdGhpcy5pZ25vcmVFcnJvcnMgPSBpZ25vcmVFcnJvcnMgPT09IHRydWU7XG4gICAgdGhpcy5fb25VbnN1cHBvcnRlZEZlYXR1cmUgPSBvblVuc3VwcG9ydGVkRmVhdHVyZTtcbiAgICB0aGlzLmZvbnRSZWdpc3RyeSA9IGZvbnRSZWdpc3RyeTtcbiAgfVxuXG4gIGNyZWF0ZU5hdGl2ZUZvbnRGYWNlKCkge1xuICAgIGlmICghdGhpcy5kYXRhIHx8IHRoaXMuZGlzYWJsZUZvbnRGYWNlKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBsZXQgbmF0aXZlRm9udEZhY2U7XG5cbiAgICBpZiAoIXRoaXMuY3NzRm9udEluZm8pIHtcbiAgICAgIG5hdGl2ZUZvbnRGYWNlID0gbmV3IEZvbnRGYWNlKHRoaXMubG9hZGVkTmFtZSwgdGhpcy5kYXRhLCB7fSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGNzcyA9IHtcbiAgICAgICAgd2VpZ2h0OiB0aGlzLmNzc0ZvbnRJbmZvLmZvbnRXZWlnaHRcbiAgICAgIH07XG5cbiAgICAgIGlmICh0aGlzLmNzc0ZvbnRJbmZvLml0YWxpY0FuZ2xlKSB7XG4gICAgICAgIGNzcy5zdHlsZSA9IGBvYmxpcXVlICR7dGhpcy5jc3NGb250SW5mby5pdGFsaWNBbmdsZX1kZWdgO1xuICAgICAgfVxuXG4gICAgICBuYXRpdmVGb250RmFjZSA9IG5ldyBGb250RmFjZSh0aGlzLmNzc0ZvbnRJbmZvLmZvbnRGYW1pbHksIHRoaXMuZGF0YSwgY3NzKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5mb250UmVnaXN0cnkpIHtcbiAgICAgIHRoaXMuZm9udFJlZ2lzdHJ5LnJlZ2lzdGVyRm9udCh0aGlzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmF0aXZlRm9udEZhY2U7XG4gIH1cblxuICBjcmVhdGVGb250RmFjZVJ1bGUoKSB7XG4gICAgaWYgKCF0aGlzLmRhdGEgfHwgdGhpcy5kaXNhYmxlRm9udEZhY2UpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGEgPSAoMCwgX3V0aWwuYnl0ZXNUb1N0cmluZykodGhpcy5kYXRhKTtcbiAgICBjb25zdCB1cmwgPSBgdXJsKGRhdGE6JHt0aGlzLm1pbWV0eXBlfTtiYXNlNjQsJHtidG9hKGRhdGEpfSk7YDtcbiAgICBsZXQgcnVsZTtcblxuICAgIGlmICghdGhpcy5jc3NGb250SW5mbykge1xuICAgICAgcnVsZSA9IGBAZm9udC1mYWNlIHtmb250LWZhbWlseTpcIiR7dGhpcy5sb2FkZWROYW1lfVwiO3NyYzoke3VybH19YDtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IGNzcyA9IGBmb250LXdlaWdodDogJHt0aGlzLmNzc0ZvbnRJbmZvLmZvbnRXZWlnaHR9O2A7XG5cbiAgICAgIGlmICh0aGlzLmNzc0ZvbnRJbmZvLml0YWxpY0FuZ2xlKSB7XG4gICAgICAgIGNzcyArPSBgZm9udC1zdHlsZTogb2JsaXF1ZSAke3RoaXMuY3NzRm9udEluZm8uaXRhbGljQW5nbGV9ZGVnO2A7XG4gICAgICB9XG5cbiAgICAgIHJ1bGUgPSBgQGZvbnQtZmFjZSB7Zm9udC1mYW1pbHk6XCIke3RoaXMuY3NzRm9udEluZm8uZm9udEZhbWlseX1cIjske2Nzc31zcmM6JHt1cmx9fWA7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZm9udFJlZ2lzdHJ5KSB7XG4gICAgICB0aGlzLmZvbnRSZWdpc3RyeS5yZWdpc3RlckZvbnQodGhpcywgdXJsKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcnVsZTtcbiAgfVxuXG4gIGdldFBhdGhHZW5lcmF0b3Iob2JqcywgY2hhcmFjdGVyKSB7XG4gICAgaWYgKHRoaXMuY29tcGlsZWRHbHlwaHNbY2hhcmFjdGVyXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb21waWxlZEdseXBoc1tjaGFyYWN0ZXJdO1xuICAgIH1cblxuICAgIGxldCBjbWRzO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNtZHMgPSBvYmpzLmdldCh0aGlzLmxvYWRlZE5hbWUgKyBcIl9wYXRoX1wiICsgY2hhcmFjdGVyKTtcbiAgICB9IGNhdGNoIChleCkge1xuICAgICAgaWYgKCF0aGlzLmlnbm9yZUVycm9ycykge1xuICAgICAgICB0aHJvdyBleDtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fb25VbnN1cHBvcnRlZEZlYXR1cmUoe1xuICAgICAgICBmZWF0dXJlSWQ6IF91dGlsLlVOU1VQUE9SVEVEX0ZFQVRVUkVTLmVycm9yRm9udEdldFBhdGhcbiAgICAgIH0pO1xuXG4gICAgICAoMCwgX3V0aWwud2FybikoYGdldFBhdGhHZW5lcmF0b3IgLSBpZ25vcmluZyBjaGFyYWN0ZXI6IFwiJHtleH1cIi5gKTtcbiAgICAgIHJldHVybiB0aGlzLmNvbXBpbGVkR2x5cGhzW2NoYXJhY3Rlcl0gPSBmdW5jdGlvbiAoYywgc2l6ZSkge307XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNFdmFsU3VwcG9ydGVkICYmIF91dGlsLkZlYXR1cmVUZXN0LmlzRXZhbFN1cHBvcnRlZCkge1xuICAgICAgY29uc3QganNCdWYgPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBjdXJyZW50IG9mIGNtZHMpIHtcbiAgICAgICAgY29uc3QgYXJncyA9IGN1cnJlbnQuYXJncyAhPT0gdW5kZWZpbmVkID8gY3VycmVudC5hcmdzLmpvaW4oXCIsXCIpIDogXCJcIjtcbiAgICAgICAganNCdWYucHVzaChcImMuXCIsIGN1cnJlbnQuY21kLCBcIihcIiwgYXJncywgXCIpO1xcblwiKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuY29tcGlsZWRHbHlwaHNbY2hhcmFjdGVyXSA9IG5ldyBGdW5jdGlvbihcImNcIiwgXCJzaXplXCIsIGpzQnVmLmpvaW4oXCJcIikpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbXBpbGVkR2x5cGhzW2NoYXJhY3Rlcl0gPSBmdW5jdGlvbiAoYywgc2l6ZSkge1xuICAgICAgZm9yIChjb25zdCBjdXJyZW50IG9mIGNtZHMpIHtcbiAgICAgICAgaWYgKGN1cnJlbnQuY21kID09PSBcInNjYWxlXCIpIHtcbiAgICAgICAgICBjdXJyZW50LmFyZ3MgPSBbc2l6ZSwgLXNpemVdO1xuICAgICAgICB9XG5cbiAgICAgICAgY1tjdXJyZW50LmNtZF0uYXBwbHkoYywgY3VycmVudC5hcmdzKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbn1cblxuZXhwb3J0cy5Gb250RmFjZU9iamVjdCA9IEZvbnRGYWNlT2JqZWN0O1xuXG4vKioqLyB9KSxcbi8qIDggKi9cbi8qKiovICgoX191bnVzZWRfd2VicGFja19tb2R1bGUsIGV4cG9ydHMsIF9fd19wZGZqc19yZXF1aXJlX18pID0+IHtcblxuXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgKHtcbiAgdmFsdWU6IHRydWVcbn0pKTtcbmV4cG9ydHMuQW5ub3RhdGlvblN0b3JhZ2UgPSB2b2lkIDA7XG5cbnZhciBfbXVybXVyaGFzaCA9IF9fd19wZGZqc19yZXF1aXJlX18oOSk7XG5cbnZhciBfdXRpbCA9IF9fd19wZGZqc19yZXF1aXJlX18oMSk7XG5cbmNsYXNzIEFubm90YXRpb25TdG9yYWdlIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5fc3RvcmFnZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLl9tb2RpZmllZCA9IGZhbHNlO1xuICAgIHRoaXMub25TZXRNb2RpZmllZCA9IG51bGw7XG4gICAgdGhpcy5vblJlc2V0TW9kaWZpZWQgPSBudWxsO1xuICB9XG5cbiAgZ2V0VmFsdWUoa2V5LCBkZWZhdWx0VmFsdWUpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX3N0b3JhZ2UuZ2V0KGtleSk7XG5cbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihkZWZhdWx0VmFsdWUsIHZhbHVlKTtcbiAgfVxuXG4gIGdldFJhd1ZhbHVlKGtleSkge1xuICAgIHJldHVybiB0aGlzLl9zdG9yYWdlLmdldChrZXkpO1xuICB9XG5cbiAgc2V0VmFsdWUoa2V5LCB2YWx1ZSkge1xuICAgIGNvbnN0IG9iaiA9IHRoaXMuX3N0b3JhZ2UuZ2V0KGtleSk7XG5cbiAgICBsZXQgbW9kaWZpZWQgPSBmYWxzZTtcblxuICAgIGlmIChvYmogIT09IHVuZGVmaW5lZCkge1xuICAgICAgZm9yIChjb25zdCBbZW50cnksIHZhbF0gb2YgT2JqZWN0LmVudHJpZXModmFsdWUpKSB7XG4gICAgICAgIGlmIChvYmpbZW50cnldICE9PSB2YWwpIHtcbiAgICAgICAgICBtb2RpZmllZCA9IHRydWU7XG4gICAgICAgICAgb2JqW2VudHJ5XSA9IHZhbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBtb2RpZmllZCA9IHRydWU7XG5cbiAgICAgIHRoaXMuX3N0b3JhZ2Uuc2V0KGtleSwgdmFsdWUpO1xuICAgIH1cblxuICAgIGlmIChtb2RpZmllZCkge1xuICAgICAgdGhpcy5fc2V0TW9kaWZpZWQoKTtcbiAgICB9XG4gIH1cblxuICBnZXRBbGwoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0b3JhZ2Uuc2l6ZSA+IDAgPyAoMCwgX3V0aWwub2JqZWN0RnJvbU1hcCkodGhpcy5fc3RvcmFnZSkgOiBudWxsO1xuICB9XG5cbiAgZ2V0IHNpemUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0b3JhZ2Uuc2l6ZTtcbiAgfVxuXG4gIF9zZXRNb2RpZmllZCgpIHtcbiAgICBpZiAoIXRoaXMuX21vZGlmaWVkKSB7XG4gICAgICB0aGlzLl9tb2RpZmllZCA9IHRydWU7XG5cbiAgICAgIGlmICh0eXBlb2YgdGhpcy5vblNldE1vZGlmaWVkID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhpcy5vblNldE1vZGlmaWVkKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmVzZXRNb2RpZmllZCgpIHtcbiAgICBpZiAodGhpcy5fbW9kaWZpZWQpIHtcbiAgICAgIHRoaXMuX21vZGlmaWVkID0gZmFsc2U7XG5cbiAgICAgIGlmICh0eXBlb2YgdGhpcy5vblJlc2V0TW9kaWZpZWQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aGlzLm9uUmVzZXRNb2RpZmllZCgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGdldCBzZXJpYWxpemFibGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0b3JhZ2Uuc2l6ZSA+IDAgPyB0aGlzLl9zdG9yYWdlIDogbnVsbDtcbiAgfVxuXG4gIGdldCBoYXNoKCkge1xuICAgIGNvbnN0IGhhc2ggPSBuZXcgX211cm11cmhhc2guTXVybXVySGFzaDNfNjQoKTtcblxuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIHRoaXMuX3N0b3JhZ2UpIHtcbiAgICAgIGhhc2gudXBkYXRlKGAke2tleX06JHtKU09OLnN0cmluZ2lmeSh2YWx1ZSl9YCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGhhc2guaGV4ZGlnZXN0KCk7XG4gIH1cblxufVxuXG5leHBvcnRzLkFubm90YXRpb25TdG9yYWdlID0gQW5ub3RhdGlvblN0b3JhZ2U7XG5cbi8qKiovIH0pLFxuLyogOSAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5NdXJtdXJIYXNoM182NCA9IHZvaWQgMDtcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxuY29uc3QgU0VFRCA9IDB4YzNkMmUxZjA7XG5jb25zdCBNQVNLX0hJR0ggPSAweGZmZmYwMDAwO1xuY29uc3QgTUFTS19MT1cgPSAweGZmZmY7XG5cbmNsYXNzIE11cm11ckhhc2gzXzY0IHtcbiAgY29uc3RydWN0b3Ioc2VlZCkge1xuICAgIHRoaXMuaDEgPSBzZWVkID8gc2VlZCAmIDB4ZmZmZmZmZmYgOiBTRUVEO1xuICAgIHRoaXMuaDIgPSBzZWVkID8gc2VlZCAmIDB4ZmZmZmZmZmYgOiBTRUVEO1xuICB9XG5cbiAgdXBkYXRlKGlucHV0KSB7XG4gICAgbGV0IGRhdGEsIGxlbmd0aDtcblxuICAgIGlmICh0eXBlb2YgaW5wdXQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIGRhdGEgPSBuZXcgVWludDhBcnJheShpbnB1dC5sZW5ndGggKiAyKTtcbiAgICAgIGxlbmd0aCA9IDA7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwLCBpaSA9IGlucHV0Lmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgY29uc3QgY29kZSA9IGlucHV0LmNoYXJDb2RlQXQoaSk7XG5cbiAgICAgICAgaWYgKGNvZGUgPD0gMHhmZikge1xuICAgICAgICAgIGRhdGFbbGVuZ3RoKytdID0gY29kZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkYXRhW2xlbmd0aCsrXSA9IGNvZGUgPj4+IDg7XG4gICAgICAgICAgZGF0YVtsZW5ndGgrK10gPSBjb2RlICYgMHhmZjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoKDAsIF91dGlsLmlzQXJyYXlCdWZmZXIpKGlucHV0KSkge1xuICAgICAgZGF0YSA9IGlucHV0LnNsaWNlKCk7XG4gICAgICBsZW5ndGggPSBkYXRhLmJ5dGVMZW5ndGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIldyb25nIGRhdGEgZm9ybWF0IGluIE11cm11ckhhc2gzXzY0X3VwZGF0ZS4gXCIgKyBcIklucHV0IG11c3QgYmUgYSBzdHJpbmcgb3IgYXJyYXkuXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IGJsb2NrQ291bnRzID0gbGVuZ3RoID4+IDI7XG4gICAgY29uc3QgdGFpbExlbmd0aCA9IGxlbmd0aCAtIGJsb2NrQ291bnRzICogNDtcbiAgICBjb25zdCBkYXRhVWludDMyID0gbmV3IFVpbnQzMkFycmF5KGRhdGEuYnVmZmVyLCAwLCBibG9ja0NvdW50cyk7XG4gICAgbGV0IGsxID0gMCxcbiAgICAgICAgazIgPSAwO1xuICAgIGxldCBoMSA9IHRoaXMuaDEsXG4gICAgICAgIGgyID0gdGhpcy5oMjtcbiAgICBjb25zdCBDMSA9IDB4Y2M5ZTJkNTEsXG4gICAgICAgICAgQzIgPSAweDFiODczNTkzO1xuICAgIGNvbnN0IEMxX0xPVyA9IEMxICYgTUFTS19MT1csXG4gICAgICAgICAgQzJfTE9XID0gQzIgJiBNQVNLX0xPVztcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYmxvY2tDb3VudHM7IGkrKykge1xuICAgICAgaWYgKGkgJiAxKSB7XG4gICAgICAgIGsxID0gZGF0YVVpbnQzMltpXTtcbiAgICAgICAgazEgPSBrMSAqIEMxICYgTUFTS19ISUdIIHwgazEgKiBDMV9MT1cgJiBNQVNLX0xPVztcbiAgICAgICAgazEgPSBrMSA8PCAxNSB8IGsxID4+PiAxNztcbiAgICAgICAgazEgPSBrMSAqIEMyICYgTUFTS19ISUdIIHwgazEgKiBDMl9MT1cgJiBNQVNLX0xPVztcbiAgICAgICAgaDEgXj0gazE7XG4gICAgICAgIGgxID0gaDEgPDwgMTMgfCBoMSA+Pj4gMTk7XG4gICAgICAgIGgxID0gaDEgKiA1ICsgMHhlNjU0NmI2NDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGsyID0gZGF0YVVpbnQzMltpXTtcbiAgICAgICAgazIgPSBrMiAqIEMxICYgTUFTS19ISUdIIHwgazIgKiBDMV9MT1cgJiBNQVNLX0xPVztcbiAgICAgICAgazIgPSBrMiA8PCAxNSB8IGsyID4+PiAxNztcbiAgICAgICAgazIgPSBrMiAqIEMyICYgTUFTS19ISUdIIHwgazIgKiBDMl9MT1cgJiBNQVNLX0xPVztcbiAgICAgICAgaDIgXj0gazI7XG4gICAgICAgIGgyID0gaDIgPDwgMTMgfCBoMiA+Pj4gMTk7XG4gICAgICAgIGgyID0gaDIgKiA1ICsgMHhlNjU0NmI2NDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBrMSA9IDA7XG5cbiAgICBzd2l0Y2ggKHRhaWxMZW5ndGgpIHtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgazEgXj0gZGF0YVtibG9ja0NvdW50cyAqIDQgKyAyXSA8PCAxNjtcblxuICAgICAgY2FzZSAyOlxuICAgICAgICBrMSBePSBkYXRhW2Jsb2NrQ291bnRzICogNCArIDFdIDw8IDg7XG5cbiAgICAgIGNhc2UgMTpcbiAgICAgICAgazEgXj0gZGF0YVtibG9ja0NvdW50cyAqIDRdO1xuICAgICAgICBrMSA9IGsxICogQzEgJiBNQVNLX0hJR0ggfCBrMSAqIEMxX0xPVyAmIE1BU0tfTE9XO1xuICAgICAgICBrMSA9IGsxIDw8IDE1IHwgazEgPj4+IDE3O1xuICAgICAgICBrMSA9IGsxICogQzIgJiBNQVNLX0hJR0ggfCBrMSAqIEMyX0xPVyAmIE1BU0tfTE9XO1xuXG4gICAgICAgIGlmIChibG9ja0NvdW50cyAmIDEpIHtcbiAgICAgICAgICBoMSBePSBrMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBoMiBePSBrMTtcbiAgICAgICAgfVxuXG4gICAgfVxuXG4gICAgdGhpcy5oMSA9IGgxO1xuICAgIHRoaXMuaDIgPSBoMjtcbiAgfVxuXG4gIGhleGRpZ2VzdCgpIHtcbiAgICBsZXQgaDEgPSB0aGlzLmgxLFxuICAgICAgICBoMiA9IHRoaXMuaDI7XG4gICAgaDEgXj0gaDIgPj4+IDE7XG4gICAgaDEgPSBoMSAqIDB4ZWQ1NThjY2QgJiBNQVNLX0hJR0ggfCBoMSAqIDB4OGNjZCAmIE1BU0tfTE9XO1xuICAgIGgyID0gaDIgKiAweGZmNTFhZmQ3ICYgTUFTS19ISUdIIHwgKChoMiA8PCAxNiB8IGgxID4+PiAxNikgKiAweGFmZDdlZDU1ICYgTUFTS19ISUdIKSA+Pj4gMTY7XG4gICAgaDEgXj0gaDIgPj4+IDE7XG4gICAgaDEgPSBoMSAqIDB4MWE4NWVjNTMgJiBNQVNLX0hJR0ggfCBoMSAqIDB4ZWM1MyAmIE1BU0tfTE9XO1xuICAgIGgyID0gaDIgKiAweGM0Y2ViOWZlICYgTUFTS19ISUdIIHwgKChoMiA8PCAxNiB8IGgxID4+PiAxNikgKiAweGI5ZmUxYTg1ICYgTUFTS19ISUdIKSA+Pj4gMTY7XG4gICAgaDEgXj0gaDIgPj4+IDE7XG4gICAgY29uc3QgaGV4MSA9IChoMSA+Pj4gMCkudG9TdHJpbmcoMTYpLFxuICAgICAgICAgIGhleDIgPSAoaDIgPj4+IDApLnRvU3RyaW5nKDE2KTtcbiAgICByZXR1cm4gaGV4MS5wYWRTdGFydCg4LCBcIjBcIikgKyBoZXgyLnBhZFN0YXJ0KDgsIFwiMFwiKTtcbiAgfVxuXG59XG5cbmV4cG9ydHMuTXVybXVySGFzaDNfNjQgPSBNdXJtdXJIYXNoM182NDtcblxuLyoqKi8gfSksXG4vKiAxMCAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5DYW52YXNHcmFwaGljcyA9IHZvaWQgMDtcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxudmFyIF9wYXR0ZXJuX2hlbHBlciA9IF9fd19wZGZqc19yZXF1aXJlX18oMTEpO1xuXG52YXIgX2ltYWdlX3V0aWxzID0gX193X3BkZmpzX3JlcXVpcmVfXygxMik7XG5cbnZhciBfaXNfbm9kZSA9IF9fd19wZGZqc19yZXF1aXJlX18oMyk7XG5cbnZhciBfZGlzcGxheV91dGlscyA9IF9fd19wZGZqc19yZXF1aXJlX18oNSk7XG5cbmNvbnN0IE1JTl9GT05UX1NJWkUgPSAxNjtcbmNvbnN0IE1BWF9GT05UX1NJWkUgPSAxMDA7XG5jb25zdCBNQVhfR1JPVVBfU0laRSA9IDQwOTY7XG5jb25zdCBFWEVDVVRJT05fVElNRSA9IDE1O1xuY29uc3QgRVhFQ1VUSU9OX1NURVBTID0gMTA7XG5jb25zdCBDT01QSUxFX1RZUEUzX0dMWVBIUyA9IHRydWU7XG5jb25zdCBNQVhfU0laRV9UT19DT01QSUxFID0gMTAwMDtcbmNvbnN0IEZVTExfQ0hVTktfSEVJR0hUID0gMTY7XG5jb25zdCBMSU5FV0lEVEhfU0NBTEVfRkFDVE9SID0gMS4wMDAwMDE7XG5cbmZ1bmN0aW9uIG1pcnJvckNvbnRleHRPcGVyYXRpb25zKGN0eCwgZGVzdEN0eCkge1xuICBpZiAoY3R4Ll9yZW1vdmVNaXJyb3JpbmcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb250ZXh0IGlzIGFscmVhZHkgZm9yd2FyZGluZyBvcGVyYXRpb25zLlwiKTtcbiAgfVxuXG4gIGN0eC5fX29yaWdpbmFsU2F2ZSA9IGN0eC5zYXZlO1xuICBjdHguX19vcmlnaW5hbFJlc3RvcmUgPSBjdHgucmVzdG9yZTtcbiAgY3R4Ll9fb3JpZ2luYWxSb3RhdGUgPSBjdHgucm90YXRlO1xuICBjdHguX19vcmlnaW5hbFNjYWxlID0gY3R4LnNjYWxlO1xuICBjdHguX19vcmlnaW5hbFRyYW5zbGF0ZSA9IGN0eC50cmFuc2xhdGU7XG4gIGN0eC5fX29yaWdpbmFsVHJhbnNmb3JtID0gY3R4LnRyYW5zZm9ybTtcbiAgY3R4Ll9fb3JpZ2luYWxTZXRUcmFuc2Zvcm0gPSBjdHguc2V0VHJhbnNmb3JtO1xuICBjdHguX19vcmlnaW5hbFJlc2V0VHJhbnNmb3JtID0gY3R4LnJlc2V0VHJhbnNmb3JtO1xuICBjdHguX19vcmlnaW5hbENsaXAgPSBjdHguY2xpcDtcbiAgY3R4Ll9fb3JpZ2luYWxNb3ZlVG8gPSBjdHgubW92ZVRvO1xuICBjdHguX19vcmlnaW5hbExpbmVUbyA9IGN0eC5saW5lVG87XG4gIGN0eC5fX29yaWdpbmFsQmV6aWVyQ3VydmVUbyA9IGN0eC5iZXppZXJDdXJ2ZVRvO1xuICBjdHguX19vcmlnaW5hbFJlY3QgPSBjdHgucmVjdDtcbiAgY3R4Ll9fb3JpZ2luYWxDbG9zZVBhdGggPSBjdHguY2xvc2VQYXRoO1xuICBjdHguX19vcmlnaW5hbEJlZ2luUGF0aCA9IGN0eC5iZWdpblBhdGg7XG5cbiAgY3R4Ll9yZW1vdmVNaXJyb3JpbmcgPSAoKSA9PiB7XG4gICAgY3R4LnNhdmUgPSBjdHguX19vcmlnaW5hbFNhdmU7XG4gICAgY3R4LnJlc3RvcmUgPSBjdHguX19vcmlnaW5hbFJlc3RvcmU7XG4gICAgY3R4LnJvdGF0ZSA9IGN0eC5fX29yaWdpbmFsUm90YXRlO1xuICAgIGN0eC5zY2FsZSA9IGN0eC5fX29yaWdpbmFsU2NhbGU7XG4gICAgY3R4LnRyYW5zbGF0ZSA9IGN0eC5fX29yaWdpbmFsVHJhbnNsYXRlO1xuICAgIGN0eC50cmFuc2Zvcm0gPSBjdHguX19vcmlnaW5hbFRyYW5zZm9ybTtcbiAgICBjdHguc2V0VHJhbnNmb3JtID0gY3R4Ll9fb3JpZ2luYWxTZXRUcmFuc2Zvcm07XG4gICAgY3R4LnJlc2V0VHJhbnNmb3JtID0gY3R4Ll9fb3JpZ2luYWxSZXNldFRyYW5zZm9ybTtcbiAgICBjdHguY2xpcCA9IGN0eC5fX29yaWdpbmFsQ2xpcDtcbiAgICBjdHgubW92ZVRvID0gY3R4Ll9fb3JpZ2luYWxNb3ZlVG87XG4gICAgY3R4LmxpbmVUbyA9IGN0eC5fX29yaWdpbmFsTGluZVRvO1xuICAgIGN0eC5iZXppZXJDdXJ2ZVRvID0gY3R4Ll9fb3JpZ2luYWxCZXppZXJDdXJ2ZVRvO1xuICAgIGN0eC5yZWN0ID0gY3R4Ll9fb3JpZ2luYWxSZWN0O1xuICAgIGN0eC5jbG9zZVBhdGggPSBjdHguX19vcmlnaW5hbENsb3NlUGF0aDtcbiAgICBjdHguYmVnaW5QYXRoID0gY3R4Ll9fb3JpZ2luYWxCZWdpblBhdGg7XG4gICAgZGVsZXRlIGN0eC5fcmVtb3ZlTWlycm9yaW5nO1xuICB9O1xuXG4gIGN0eC5zYXZlID0gZnVuY3Rpb24gY3R4U2F2ZSgpIHtcbiAgICBkZXN0Q3R4LnNhdmUoKTtcblxuICAgIHRoaXMuX19vcmlnaW5hbFNhdmUoKTtcbiAgfTtcblxuICBjdHgucmVzdG9yZSA9IGZ1bmN0aW9uIGN0eFJlc3RvcmUoKSB7XG4gICAgZGVzdEN0eC5yZXN0b3JlKCk7XG5cbiAgICB0aGlzLl9fb3JpZ2luYWxSZXN0b3JlKCk7XG4gIH07XG5cbiAgY3R4LnRyYW5zbGF0ZSA9IGZ1bmN0aW9uIGN0eFRyYW5zbGF0ZSh4LCB5KSB7XG4gICAgZGVzdEN0eC50cmFuc2xhdGUoeCwgeSk7XG5cbiAgICB0aGlzLl9fb3JpZ2luYWxUcmFuc2xhdGUoeCwgeSk7XG4gIH07XG5cbiAgY3R4LnNjYWxlID0gZnVuY3Rpb24gY3R4U2NhbGUoeCwgeSkge1xuICAgIGRlc3RDdHguc2NhbGUoeCwgeSk7XG5cbiAgICB0aGlzLl9fb3JpZ2luYWxTY2FsZSh4LCB5KTtcbiAgfTtcblxuICBjdHgudHJhbnNmb3JtID0gZnVuY3Rpb24gY3R4VHJhbnNmb3JtKGEsIGIsIGMsIGQsIGUsIGYpIHtcbiAgICBkZXN0Q3R4LnRyYW5zZm9ybShhLCBiLCBjLCBkLCBlLCBmKTtcblxuICAgIHRoaXMuX19vcmlnaW5hbFRyYW5zZm9ybShhLCBiLCBjLCBkLCBlLCBmKTtcbiAgfTtcblxuICBjdHguc2V0VHJhbnNmb3JtID0gZnVuY3Rpb24gY3R4U2V0VHJhbnNmb3JtKGEsIGIsIGMsIGQsIGUsIGYpIHtcbiAgICBkZXN0Q3R4LnNldFRyYW5zZm9ybShhLCBiLCBjLCBkLCBlLCBmKTtcblxuICAgIHRoaXMuX19vcmlnaW5hbFNldFRyYW5zZm9ybShhLCBiLCBjLCBkLCBlLCBmKTtcbiAgfTtcblxuICBjdHgucmVzZXRUcmFuc2Zvcm0gPSBmdW5jdGlvbiBjdHhSZXNldFRyYW5zZm9ybSgpIHtcbiAgICBkZXN0Q3R4LnJlc2V0VHJhbnNmb3JtKCk7XG5cbiAgICB0aGlzLl9fb3JpZ2luYWxSZXNldFRyYW5zZm9ybSgpO1xuICB9O1xuXG4gIGN0eC5yb3RhdGUgPSBmdW5jdGlvbiBjdHhSb3RhdGUoYW5nbGUpIHtcbiAgICBkZXN0Q3R4LnJvdGF0ZShhbmdsZSk7XG5cbiAgICB0aGlzLl9fb3JpZ2luYWxSb3RhdGUoYW5nbGUpO1xuICB9O1xuXG4gIGN0eC5jbGlwID0gZnVuY3Rpb24gY3R4Um90YXRlKHJ1bGUpIHtcbiAgICBkZXN0Q3R4LmNsaXAocnVsZSk7XG5cbiAgICB0aGlzLl9fb3JpZ2luYWxDbGlwKHJ1bGUpO1xuICB9O1xuXG4gIGN0eC5tb3ZlVG8gPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgIGRlc3RDdHgubW92ZVRvKHgsIHkpO1xuXG4gICAgdGhpcy5fX29yaWdpbmFsTW92ZVRvKHgsIHkpO1xuICB9O1xuXG4gIGN0eC5saW5lVG8gPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgIGRlc3RDdHgubGluZVRvKHgsIHkpO1xuXG4gICAgdGhpcy5fX29yaWdpbmFsTGluZVRvKHgsIHkpO1xuICB9O1xuXG4gIGN0eC5iZXppZXJDdXJ2ZVRvID0gZnVuY3Rpb24gKGNwMXgsIGNwMXksIGNwMngsIGNwMnksIHgsIHkpIHtcbiAgICBkZXN0Q3R4LmJlemllckN1cnZlVG8oY3AxeCwgY3AxeSwgY3AyeCwgY3AyeSwgeCwgeSk7XG5cbiAgICB0aGlzLl9fb3JpZ2luYWxCZXppZXJDdXJ2ZVRvKGNwMXgsIGNwMXksIGNwMngsIGNwMnksIHgsIHkpO1xuICB9O1xuXG4gIGN0eC5yZWN0ID0gZnVuY3Rpb24gKHgsIHksIHdpZHRoLCBoZWlnaHQpIHtcbiAgICBkZXN0Q3R4LnJlY3QoeCwgeSwgd2lkdGgsIGhlaWdodCk7XG5cbiAgICB0aGlzLl9fb3JpZ2luYWxSZWN0KHgsIHksIHdpZHRoLCBoZWlnaHQpO1xuICB9O1xuXG4gIGN0eC5jbG9zZVBhdGggPSBmdW5jdGlvbiAoKSB7XG4gICAgZGVzdEN0eC5jbG9zZVBhdGgoKTtcblxuICAgIHRoaXMuX19vcmlnaW5hbENsb3NlUGF0aCgpO1xuICB9O1xuXG4gIGN0eC5iZWdpblBhdGggPSBmdW5jdGlvbiAoKSB7XG4gICAgZGVzdEN0eC5iZWdpblBhdGgoKTtcblxuICAgIHRoaXMuX19vcmlnaW5hbEJlZ2luUGF0aCgpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBhZGRDb250ZXh0Q3VycmVudFRyYW5zZm9ybShjdHgpIHtcbiAgaWYgKGN0eC5fdHJhbnNmb3JtU3RhY2spIHtcbiAgICBjdHguX3RyYW5zZm9ybVN0YWNrID0gW107XG4gIH1cblxuICBpZiAoY3R4Lm1vekN1cnJlbnRUcmFuc2Zvcm0pIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjdHguX29yaWdpbmFsU2F2ZSA9IGN0eC5zYXZlO1xuICBjdHguX29yaWdpbmFsUmVzdG9yZSA9IGN0eC5yZXN0b3JlO1xuICBjdHguX29yaWdpbmFsUm90YXRlID0gY3R4LnJvdGF0ZTtcbiAgY3R4Ll9vcmlnaW5hbFNjYWxlID0gY3R4LnNjYWxlO1xuICBjdHguX29yaWdpbmFsVHJhbnNsYXRlID0gY3R4LnRyYW5zbGF0ZTtcbiAgY3R4Ll9vcmlnaW5hbFRyYW5zZm9ybSA9IGN0eC50cmFuc2Zvcm07XG4gIGN0eC5fb3JpZ2luYWxTZXRUcmFuc2Zvcm0gPSBjdHguc2V0VHJhbnNmb3JtO1xuICBjdHguX29yaWdpbmFsUmVzZXRUcmFuc2Zvcm0gPSBjdHgucmVzZXRUcmFuc2Zvcm07XG4gIGN0eC5fdHJhbnNmb3JtTWF0cml4ID0gY3R4Ll90cmFuc2Zvcm1NYXRyaXggfHwgWzEsIDAsIDAsIDEsIDAsIDBdO1xuICBjdHguX3RyYW5zZm9ybVN0YWNrID0gW107XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihPYmplY3QuZ2V0UHJvdG90eXBlT2YoY3R4KSwgXCJsaW5lV2lkdGhcIik7XG4gICAgY3R4Ll9zZXRMaW5lV2lkdGggPSBkZXNjLnNldDtcbiAgICBjdHguX2dldExpbmVXaWR0aCA9IGRlc2MuZ2V0O1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIFwibGluZVdpZHRoXCIsIHtcbiAgICAgIHNldDogZnVuY3Rpb24gc2V0TGluZVdpZHRoKHdpZHRoKSB7XG4gICAgICAgIHRoaXMuX3NldExpbmVXaWR0aCh3aWR0aCAqIExJTkVXSURUSF9TQ0FMRV9GQUNUT1IpO1xuICAgICAgfSxcbiAgICAgIGdldDogZnVuY3Rpb24gZ2V0TGluZVdpZHRoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TGluZVdpZHRoKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0gY2F0Y2ggKF8pIHt9XG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN0eCwgXCJtb3pDdXJyZW50VHJhbnNmb3JtXCIsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldEN1cnJlbnRUcmFuc2Zvcm0oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fdHJhbnNmb3JtTWF0cml4O1xuICAgIH1cbiAgfSk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIFwibW96Q3VycmVudFRyYW5zZm9ybUludmVyc2VcIiwge1xuICAgIGdldDogZnVuY3Rpb24gZ2V0Q3VycmVudFRyYW5zZm9ybUludmVyc2UoKSB7XG4gICAgICBjb25zdCBbYSwgYiwgYywgZCwgZSwgZl0gPSB0aGlzLl90cmFuc2Zvcm1NYXRyaXg7XG4gICAgICBjb25zdCBhZF9iYyA9IGEgKiBkIC0gYiAqIGM7XG4gICAgICBjb25zdCBiY19hZCA9IGIgKiBjIC0gYSAqIGQ7XG4gICAgICByZXR1cm4gW2QgLyBhZF9iYywgYiAvIGJjX2FkLCBjIC8gYmNfYWQsIGEgLyBhZF9iYywgKGQgKiBlIC0gYyAqIGYpIC8gYmNfYWQsIChiICogZSAtIGEgKiBmKSAvIGFkX2JjXTtcbiAgICB9XG4gIH0pO1xuXG4gIGN0eC5zYXZlID0gZnVuY3Rpb24gY3R4U2F2ZSgpIHtcbiAgICBjb25zdCBvbGQgPSB0aGlzLl90cmFuc2Zvcm1NYXRyaXg7XG5cbiAgICB0aGlzLl90cmFuc2Zvcm1TdGFjay5wdXNoKG9sZCk7XG5cbiAgICB0aGlzLl90cmFuc2Zvcm1NYXRyaXggPSBvbGQuc2xpY2UoMCwgNik7XG5cbiAgICB0aGlzLl9vcmlnaW5hbFNhdmUoKTtcbiAgfTtcblxuICBjdHgucmVzdG9yZSA9IGZ1bmN0aW9uIGN0eFJlc3RvcmUoKSB7XG4gICAgaWYgKHRoaXMuX3RyYW5zZm9ybVN0YWNrLmxlbmd0aCA9PT0gMCkge1xuICAgICAgKDAsIF91dGlsLndhcm4pKFwiVHJpZWQgdG8gcmVzdG9yZSBhIGN0eCB3aGVuIHRoZSBzdGFjayB3YXMgYWxyZWFkeSBlbXB0eS5cIik7XG4gICAgfVxuXG4gICAgY29uc3QgcHJldiA9IHRoaXMuX3RyYW5zZm9ybVN0YWNrLnBvcCgpO1xuXG4gICAgaWYgKHByZXYpIHtcbiAgICAgIHRoaXMuX3RyYW5zZm9ybU1hdHJpeCA9IHByZXY7XG5cbiAgICAgIHRoaXMuX29yaWdpbmFsUmVzdG9yZSgpO1xuICAgIH1cbiAgfTtcblxuICBjdHgudHJhbnNsYXRlID0gZnVuY3Rpb24gY3R4VHJhbnNsYXRlKHgsIHkpIHtcbiAgICBjb25zdCBtID0gdGhpcy5fdHJhbnNmb3JtTWF0cml4O1xuICAgIG1bNF0gPSBtWzBdICogeCArIG1bMl0gKiB5ICsgbVs0XTtcbiAgICBtWzVdID0gbVsxXSAqIHggKyBtWzNdICogeSArIG1bNV07XG5cbiAgICB0aGlzLl9vcmlnaW5hbFRyYW5zbGF0ZSh4LCB5KTtcbiAgfTtcblxuICBjdHguc2NhbGUgPSBmdW5jdGlvbiBjdHhTY2FsZSh4LCB5KSB7XG4gICAgY29uc3QgbSA9IHRoaXMuX3RyYW5zZm9ybU1hdHJpeDtcbiAgICBtWzBdICo9IHg7XG4gICAgbVsxXSAqPSB4O1xuICAgIG1bMl0gKj0geTtcbiAgICBtWzNdICo9IHk7XG5cbiAgICB0aGlzLl9vcmlnaW5hbFNjYWxlKHgsIHkpO1xuICB9O1xuXG4gIGN0eC50cmFuc2Zvcm0gPSBmdW5jdGlvbiBjdHhUcmFuc2Zvcm0oYSwgYiwgYywgZCwgZSwgZikge1xuICAgIGNvbnN0IG0gPSB0aGlzLl90cmFuc2Zvcm1NYXRyaXg7XG4gICAgdGhpcy5fdHJhbnNmb3JtTWF0cml4ID0gW21bMF0gKiBhICsgbVsyXSAqIGIsIG1bMV0gKiBhICsgbVszXSAqIGIsIG1bMF0gKiBjICsgbVsyXSAqIGQsIG1bMV0gKiBjICsgbVszXSAqIGQsIG1bMF0gKiBlICsgbVsyXSAqIGYgKyBtWzRdLCBtWzFdICogZSArIG1bM10gKiBmICsgbVs1XV07XG5cbiAgICBjdHguX29yaWdpbmFsVHJhbnNmb3JtKGEsIGIsIGMsIGQsIGUsIGYpO1xuICB9O1xuXG4gIGN0eC5zZXRUcmFuc2Zvcm0gPSBmdW5jdGlvbiBjdHhTZXRUcmFuc2Zvcm0oYSwgYiwgYywgZCwgZSwgZikge1xuICAgIHRoaXMuX3RyYW5zZm9ybU1hdHJpeCA9IFthLCBiLCBjLCBkLCBlLCBmXTtcblxuICAgIGN0eC5fb3JpZ2luYWxTZXRUcmFuc2Zvcm0oYSwgYiwgYywgZCwgZSwgZik7XG4gIH07XG5cbiAgY3R4LnJlc2V0VHJhbnNmb3JtID0gZnVuY3Rpb24gY3R4UmVzZXRUcmFuc2Zvcm0oKSB7XG4gICAgdGhpcy5fdHJhbnNmb3JtTWF0cml4ID0gWzEsIDAsIDAsIDEsIDAsIDBdO1xuXG4gICAgY3R4Ll9vcmlnaW5hbFJlc2V0VHJhbnNmb3JtKCk7XG4gIH07XG5cbiAgY3R4LnJvdGF0ZSA9IGZ1bmN0aW9uIGN0eFJvdGF0ZShhbmdsZSkge1xuICAgIGNvbnN0IGNvc1ZhbHVlID0gTWF0aC5jb3MoYW5nbGUpO1xuICAgIGNvbnN0IHNpblZhbHVlID0gTWF0aC5zaW4oYW5nbGUpO1xuICAgIGNvbnN0IG0gPSB0aGlzLl90cmFuc2Zvcm1NYXRyaXg7XG4gICAgdGhpcy5fdHJhbnNmb3JtTWF0cml4ID0gW21bMF0gKiBjb3NWYWx1ZSArIG1bMl0gKiBzaW5WYWx1ZSwgbVsxXSAqIGNvc1ZhbHVlICsgbVszXSAqIHNpblZhbHVlLCBtWzBdICogLXNpblZhbHVlICsgbVsyXSAqIGNvc1ZhbHVlLCBtWzFdICogLXNpblZhbHVlICsgbVszXSAqIGNvc1ZhbHVlLCBtWzRdLCBtWzVdXTtcblxuICAgIHRoaXMuX29yaWdpbmFsUm90YXRlKGFuZ2xlKTtcbiAgfTtcbn1cblxuY2xhc3MgQ2FjaGVkQ2FudmFzZXMge1xuICBjb25zdHJ1Y3RvcihjYW52YXNGYWN0b3J5KSB7XG4gICAgdGhpcy5jYW52YXNGYWN0b3J5ID0gY2FudmFzRmFjdG9yeTtcbiAgICB0aGlzLmNhY2hlID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgfVxuXG4gIGdldENhbnZhcyhpZCwgd2lkdGgsIGhlaWdodCwgdHJhY2tUcmFuc2Zvcm0pIHtcbiAgICBsZXQgY2FudmFzRW50cnk7XG5cbiAgICBpZiAodGhpcy5jYWNoZVtpZF0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgY2FudmFzRW50cnkgPSB0aGlzLmNhY2hlW2lkXTtcbiAgICAgIHRoaXMuY2FudmFzRmFjdG9yeS5yZXNldChjYW52YXNFbnRyeSwgd2lkdGgsIGhlaWdodCk7XG4gICAgICBjYW52YXNFbnRyeS5jb250ZXh0LnNldFRyYW5zZm9ybSgxLCAwLCAwLCAxLCAwLCAwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2FudmFzRW50cnkgPSB0aGlzLmNhbnZhc0ZhY3RvcnkuY3JlYXRlKHdpZHRoLCBoZWlnaHQpO1xuICAgICAgdGhpcy5jYWNoZVtpZF0gPSBjYW52YXNFbnRyeTtcbiAgICB9XG5cbiAgICBpZiAodHJhY2tUcmFuc2Zvcm0pIHtcbiAgICAgIGFkZENvbnRleHRDdXJyZW50VHJhbnNmb3JtKGNhbnZhc0VudHJ5LmNvbnRleHQpO1xuICAgIH1cblxuICAgIHJldHVybiBjYW52YXNFbnRyeTtcbiAgfVxuXG4gIGRlbGV0ZShpZCkge1xuICAgIGRlbGV0ZSB0aGlzLmNhY2hlW2lkXTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIGZvciAoY29uc3QgaWQgaW4gdGhpcy5jYWNoZSkge1xuICAgICAgY29uc3QgY2FudmFzRW50cnkgPSB0aGlzLmNhY2hlW2lkXTtcbiAgICAgIHRoaXMuY2FudmFzRmFjdG9yeS5kZXN0cm95KGNhbnZhc0VudHJ5KTtcbiAgICAgIGRlbGV0ZSB0aGlzLmNhY2hlW2lkXTtcbiAgICB9XG4gIH1cblxufVxuXG5mdW5jdGlvbiBkcmF3SW1hZ2VBdEludGVnZXJDb29yZHMoY3R4LCBzcmNJbWcsIHNyY1gsIHNyY1ksIHNyY1csIHNyY0gsIGRlc3RYLCBkZXN0WSwgZGVzdFcsIGRlc3RIKSB7XG4gIGNvbnN0IFthLCBiLCBjLCBkLCB0eCwgdHldID0gY3R4Lm1vekN1cnJlbnRUcmFuc2Zvcm07XG5cbiAgaWYgKGIgPT09IDAgJiYgYyA9PT0gMCkge1xuICAgIGNvbnN0IHRsWCA9IGRlc3RYICogYSArIHR4O1xuICAgIGNvbnN0IHJUbFggPSBNYXRoLnJvdW5kKHRsWCk7XG4gICAgY29uc3QgdGxZID0gZGVzdFkgKiBkICsgdHk7XG4gICAgY29uc3QgclRsWSA9IE1hdGgucm91bmQodGxZKTtcbiAgICBjb25zdCBiclggPSAoZGVzdFggKyBkZXN0VykgKiBhICsgdHg7XG4gICAgY29uc3QgcldpZHRoID0gTWF0aC5hYnMoTWF0aC5yb3VuZChiclgpIC0gclRsWCkgfHwgMTtcbiAgICBjb25zdCBiclkgPSAoZGVzdFkgKyBkZXN0SCkgKiBkICsgdHk7XG4gICAgY29uc3QgckhlaWdodCA9IE1hdGguYWJzKE1hdGgucm91bmQoYnJZKSAtIHJUbFkpIHx8IDE7XG4gICAgY3R4LnNldFRyYW5zZm9ybShNYXRoLnNpZ24oYSksIDAsIDAsIE1hdGguc2lnbihkKSwgclRsWCwgclRsWSk7XG4gICAgY3R4LmRyYXdJbWFnZShzcmNJbWcsIHNyY1gsIHNyY1ksIHNyY1csIHNyY0gsIDAsIDAsIHJXaWR0aCwgckhlaWdodCk7XG4gICAgY3R4LnNldFRyYW5zZm9ybShhLCBiLCBjLCBkLCB0eCwgdHkpO1xuICAgIHJldHVybiBbcldpZHRoLCBySGVpZ2h0XTtcbiAgfVxuXG4gIGlmIChhID09PSAwICYmIGQgPT09IDApIHtcbiAgICBjb25zdCB0bFggPSBkZXN0WSAqIGMgKyB0eDtcbiAgICBjb25zdCByVGxYID0gTWF0aC5yb3VuZCh0bFgpO1xuICAgIGNvbnN0IHRsWSA9IGRlc3RYICogYiArIHR5O1xuICAgIGNvbnN0IHJUbFkgPSBNYXRoLnJvdW5kKHRsWSk7XG4gICAgY29uc3QgYnJYID0gKGRlc3RZICsgZGVzdEgpICogYyArIHR4O1xuICAgIGNvbnN0IHJXaWR0aCA9IE1hdGguYWJzKE1hdGgucm91bmQoYnJYKSAtIHJUbFgpIHx8IDE7XG4gICAgY29uc3QgYnJZID0gKGRlc3RYICsgZGVzdFcpICogYiArIHR5O1xuICAgIGNvbnN0IHJIZWlnaHQgPSBNYXRoLmFicyhNYXRoLnJvdW5kKGJyWSkgLSByVGxZKSB8fCAxO1xuICAgIGN0eC5zZXRUcmFuc2Zvcm0oMCwgTWF0aC5zaWduKGIpLCBNYXRoLnNpZ24oYyksIDAsIHJUbFgsIHJUbFkpO1xuICAgIGN0eC5kcmF3SW1hZ2Uoc3JjSW1nLCBzcmNYLCBzcmNZLCBzcmNXLCBzcmNILCAwLCAwLCBySGVpZ2h0LCByV2lkdGgpO1xuICAgIGN0eC5zZXRUcmFuc2Zvcm0oYSwgYiwgYywgZCwgdHgsIHR5KTtcbiAgICByZXR1cm4gW3JIZWlnaHQsIHJXaWR0aF07XG4gIH1cblxuICBjdHguZHJhd0ltYWdlKHNyY0ltZywgc3JjWCwgc3JjWSwgc3JjVywgc3JjSCwgZGVzdFgsIGRlc3RZLCBkZXN0VywgZGVzdEgpO1xuICBjb25zdCBzY2FsZVggPSBNYXRoLmh5cG90KGEsIGIpO1xuICBjb25zdCBzY2FsZVkgPSBNYXRoLmh5cG90KGMsIGQpO1xuICByZXR1cm4gW3NjYWxlWCAqIGRlc3RXLCBzY2FsZVkgKiBkZXN0SF07XG59XG5cbmZ1bmN0aW9uIGNvbXBpbGVUeXBlM0dseXBoKGltZ0RhdGEpIHtcbiAgY29uc3Qge1xuICAgIHdpZHRoLFxuICAgIGhlaWdodFxuICB9ID0gaW1nRGF0YTtcblxuICBpZiAoIUNPTVBJTEVfVFlQRTNfR0xZUEhTIHx8IHdpZHRoID4gTUFYX1NJWkVfVE9fQ09NUElMRSB8fCBoZWlnaHQgPiBNQVhfU0laRV9UT19DT01QSUxFKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBQT0lOVF9UT19QUk9DRVNTX0xJTUlUID0gMTAwMDtcbiAgY29uc3QgUE9JTlRfVFlQRVMgPSBuZXcgVWludDhBcnJheShbMCwgMiwgNCwgMCwgMSwgMCwgNSwgNCwgOCwgMTAsIDAsIDgsIDAsIDIsIDEsIDBdKTtcbiAgY29uc3Qgd2lkdGgxID0gd2lkdGggKyAxO1xuICBsZXQgcG9pbnRzID0gbmV3IFVpbnQ4QXJyYXkod2lkdGgxICogKGhlaWdodCArIDEpKTtcbiAgbGV0IGksIGosIGowO1xuICBjb25zdCBsaW5lU2l6ZSA9IHdpZHRoICsgNyAmIH43O1xuICBsZXQgZGF0YSA9IG5ldyBVaW50OEFycmF5KGxpbmVTaXplICogaGVpZ2h0KSxcbiAgICAgIHBvcyA9IDA7XG5cbiAgZm9yIChjb25zdCBlbGVtIG9mIGltZ0RhdGEuZGF0YSkge1xuICAgIGxldCBtYXNrID0gMTI4O1xuXG4gICAgd2hpbGUgKG1hc2sgPiAwKSB7XG4gICAgICBkYXRhW3BvcysrXSA9IGVsZW0gJiBtYXNrID8gMCA6IDI1NTtcbiAgICAgIG1hc2sgPj49IDE7XG4gICAgfVxuICB9XG5cbiAgbGV0IGNvdW50ID0gMDtcbiAgcG9zID0gMDtcblxuICBpZiAoZGF0YVtwb3NdICE9PSAwKSB7XG4gICAgcG9pbnRzWzBdID0gMTtcbiAgICArK2NvdW50O1xuICB9XG5cbiAgZm9yIChqID0gMTsgaiA8IHdpZHRoOyBqKyspIHtcbiAgICBpZiAoZGF0YVtwb3NdICE9PSBkYXRhW3BvcyArIDFdKSB7XG4gICAgICBwb2ludHNbal0gPSBkYXRhW3Bvc10gPyAyIDogMTtcbiAgICAgICsrY291bnQ7XG4gICAgfVxuXG4gICAgcG9zKys7XG4gIH1cblxuICBpZiAoZGF0YVtwb3NdICE9PSAwKSB7XG4gICAgcG9pbnRzW2pdID0gMjtcbiAgICArK2NvdW50O1xuICB9XG5cbiAgZm9yIChpID0gMTsgaSA8IGhlaWdodDsgaSsrKSB7XG4gICAgcG9zID0gaSAqIGxpbmVTaXplO1xuICAgIGowID0gaSAqIHdpZHRoMTtcblxuICAgIGlmIChkYXRhW3BvcyAtIGxpbmVTaXplXSAhPT0gZGF0YVtwb3NdKSB7XG4gICAgICBwb2ludHNbajBdID0gZGF0YVtwb3NdID8gMSA6IDg7XG4gICAgICArK2NvdW50O1xuICAgIH1cblxuICAgIGxldCBzdW0gPSAoZGF0YVtwb3NdID8gNCA6IDApICsgKGRhdGFbcG9zIC0gbGluZVNpemVdID8gOCA6IDApO1xuXG4gICAgZm9yIChqID0gMTsgaiA8IHdpZHRoOyBqKyspIHtcbiAgICAgIHN1bSA9IChzdW0gPj4gMikgKyAoZGF0YVtwb3MgKyAxXSA/IDQgOiAwKSArIChkYXRhW3BvcyAtIGxpbmVTaXplICsgMV0gPyA4IDogMCk7XG5cbiAgICAgIGlmIChQT0lOVF9UWVBFU1tzdW1dKSB7XG4gICAgICAgIHBvaW50c1tqMCArIGpdID0gUE9JTlRfVFlQRVNbc3VtXTtcbiAgICAgICAgKytjb3VudDtcbiAgICAgIH1cblxuICAgICAgcG9zKys7XG4gICAgfVxuXG4gICAgaWYgKGRhdGFbcG9zIC0gbGluZVNpemVdICE9PSBkYXRhW3Bvc10pIHtcbiAgICAgIHBvaW50c1tqMCArIGpdID0gZGF0YVtwb3NdID8gMiA6IDQ7XG4gICAgICArK2NvdW50O1xuICAgIH1cblxuICAgIGlmIChjb3VudCA+IFBPSU5UX1RPX1BST0NFU1NfTElNSVQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHBvcyA9IGxpbmVTaXplICogKGhlaWdodCAtIDEpO1xuICBqMCA9IGkgKiB3aWR0aDE7XG5cbiAgaWYgKGRhdGFbcG9zXSAhPT0gMCkge1xuICAgIHBvaW50c1tqMF0gPSA4O1xuICAgICsrY291bnQ7XG4gIH1cblxuICBmb3IgKGogPSAxOyBqIDwgd2lkdGg7IGorKykge1xuICAgIGlmIChkYXRhW3Bvc10gIT09IGRhdGFbcG9zICsgMV0pIHtcbiAgICAgIHBvaW50c1tqMCArIGpdID0gZGF0YVtwb3NdID8gNCA6IDg7XG4gICAgICArK2NvdW50O1xuICAgIH1cblxuICAgIHBvcysrO1xuICB9XG5cbiAgaWYgKGRhdGFbcG9zXSAhPT0gMCkge1xuICAgIHBvaW50c1tqMCArIGpdID0gNDtcbiAgICArK2NvdW50O1xuICB9XG5cbiAgaWYgKGNvdW50ID4gUE9JTlRfVE9fUFJPQ0VTU19MSU1JVCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3Qgc3RlcHMgPSBuZXcgSW50MzJBcnJheShbMCwgd2lkdGgxLCAtMSwgMCwgLXdpZHRoMSwgMCwgMCwgMCwgMV0pO1xuICBsZXQgcGF0aCwgb3V0bGluZXMsIGNvb3JkcztcblxuICBpZiAoIV9pc19ub2RlLmlzTm9kZUpTKSB7XG4gICAgcGF0aCA9IG5ldyBQYXRoMkQoKTtcbiAgfSBlbHNlIHtcbiAgICBvdXRsaW5lcyA9IFtdO1xuICB9XG5cbiAgZm9yIChpID0gMDsgY291bnQgJiYgaSA8PSBoZWlnaHQ7IGkrKykge1xuICAgIGxldCBwID0gaSAqIHdpZHRoMTtcbiAgICBjb25zdCBlbmQgPSBwICsgd2lkdGg7XG5cbiAgICB3aGlsZSAocCA8IGVuZCAmJiAhcG9pbnRzW3BdKSB7XG4gICAgICBwKys7XG4gICAgfVxuXG4gICAgaWYgKHAgPT09IGVuZCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHBhdGgpIHtcbiAgICAgIHBhdGgubW92ZVRvKHAgJSB3aWR0aDEsIGkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb29yZHMgPSBbcCAlIHdpZHRoMSwgaV07XG4gICAgfVxuXG4gICAgY29uc3QgcDAgPSBwO1xuICAgIGxldCB0eXBlID0gcG9pbnRzW3BdO1xuXG4gICAgZG8ge1xuICAgICAgY29uc3Qgc3RlcCA9IHN0ZXBzW3R5cGVdO1xuXG4gICAgICBkbyB7XG4gICAgICAgIHAgKz0gc3RlcDtcbiAgICAgIH0gd2hpbGUgKCFwb2ludHNbcF0pO1xuXG4gICAgICBjb25zdCBwcCA9IHBvaW50c1twXTtcblxuICAgICAgaWYgKHBwICE9PSA1ICYmIHBwICE9PSAxMCkge1xuICAgICAgICB0eXBlID0gcHA7XG4gICAgICAgIHBvaW50c1twXSA9IDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0eXBlID0gcHAgJiAweDMzICogdHlwZSA+PiA0O1xuICAgICAgICBwb2ludHNbcF0gJj0gdHlwZSA+PiAyIHwgdHlwZSA8PCAyO1xuICAgICAgfVxuXG4gICAgICBpZiAocGF0aCkge1xuICAgICAgICBwYXRoLmxpbmVUbyhwICUgd2lkdGgxLCBwIC8gd2lkdGgxIHwgMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb29yZHMucHVzaChwICUgd2lkdGgxLCBwIC8gd2lkdGgxIHwgMCk7XG4gICAgICB9XG5cbiAgICAgIGlmICghcG9pbnRzW3BdKSB7XG4gICAgICAgIC0tY291bnQ7XG4gICAgICB9XG4gICAgfSB3aGlsZSAocDAgIT09IHApO1xuXG4gICAgaWYgKCFwYXRoKSB7XG4gICAgICBvdXRsaW5lcy5wdXNoKGNvb3Jkcyk7XG4gICAgfVxuXG4gICAgLS1pO1xuICB9XG5cbiAgZGF0YSA9IG51bGw7XG4gIHBvaW50cyA9IG51bGw7XG5cbiAgY29uc3QgZHJhd091dGxpbmUgPSBmdW5jdGlvbiAoYykge1xuICAgIGMuc2F2ZSgpO1xuICAgIGMuc2NhbGUoMSAvIHdpZHRoLCAtMSAvIGhlaWdodCk7XG4gICAgYy50cmFuc2xhdGUoMCwgLWhlaWdodCk7XG5cbiAgICBpZiAocGF0aCkge1xuICAgICAgYy5maWxsKHBhdGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjLmJlZ2luUGF0aCgpO1xuXG4gICAgICBmb3IgKGNvbnN0IG8gb2Ygb3V0bGluZXMpIHtcbiAgICAgICAgYy5tb3ZlVG8ob1swXSwgb1sxXSk7XG5cbiAgICAgICAgZm9yIChsZXQgbCA9IDIsIGxsID0gby5sZW5ndGg7IGwgPCBsbDsgbCArPSAyKSB7XG4gICAgICAgICAgYy5saW5lVG8ob1tsXSwgb1tsICsgMV0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGMuZmlsbCgpO1xuICAgIH1cblxuICAgIGMuYmVnaW5QYXRoKCk7XG4gICAgYy5yZXN0b3JlKCk7XG4gIH07XG5cbiAgcmV0dXJuIGRyYXdPdXRsaW5lO1xufVxuXG5jbGFzcyBDYW52YXNFeHRyYVN0YXRlIHtcbiAgY29uc3RydWN0b3Iod2lkdGgsIGhlaWdodCkge1xuICAgIHRoaXMuYWxwaGFJc1NoYXBlID0gZmFsc2U7XG4gICAgdGhpcy5mb250U2l6ZSA9IDA7XG4gICAgdGhpcy5mb250U2l6ZVNjYWxlID0gMTtcbiAgICB0aGlzLnRleHRNYXRyaXggPSBfdXRpbC5JREVOVElUWV9NQVRSSVg7XG4gICAgdGhpcy50ZXh0TWF0cml4U2NhbGUgPSAxO1xuICAgIHRoaXMuZm9udE1hdHJpeCA9IF91dGlsLkZPTlRfSURFTlRJVFlfTUFUUklYO1xuICAgIHRoaXMubGVhZGluZyA9IDA7XG4gICAgdGhpcy54ID0gMDtcbiAgICB0aGlzLnkgPSAwO1xuICAgIHRoaXMubGluZVggPSAwO1xuICAgIHRoaXMubGluZVkgPSAwO1xuICAgIHRoaXMuY2hhclNwYWNpbmcgPSAwO1xuICAgIHRoaXMud29yZFNwYWNpbmcgPSAwO1xuICAgIHRoaXMudGV4dEhTY2FsZSA9IDE7XG4gICAgdGhpcy50ZXh0UmVuZGVyaW5nTW9kZSA9IF91dGlsLlRleHRSZW5kZXJpbmdNb2RlLkZJTEw7XG4gICAgdGhpcy50ZXh0UmlzZSA9IDA7XG4gICAgdGhpcy5maWxsQ29sb3IgPSBcIiMwMDAwMDBcIjtcbiAgICB0aGlzLnN0cm9rZUNvbG9yID0gXCIjMDAwMDAwXCI7XG4gICAgdGhpcy5wYXR0ZXJuRmlsbCA9IGZhbHNlO1xuICAgIHRoaXMuZmlsbEFscGhhID0gMTtcbiAgICB0aGlzLnN0cm9rZUFscGhhID0gMTtcbiAgICB0aGlzLmxpbmVXaWR0aCA9IDE7XG4gICAgdGhpcy5hY3RpdmVTTWFzayA9IG51bGw7XG4gICAgdGhpcy50cmFuc2Zlck1hcHMgPSBudWxsO1xuICAgIHRoaXMuc3RhcnROZXdQYXRoQW5kQ2xpcEJveChbMCwgMCwgd2lkdGgsIGhlaWdodF0pO1xuICB9XG5cbiAgY2xvbmUoKSB7XG4gICAgY29uc3QgY2xvbmUgPSBPYmplY3QuY3JlYXRlKHRoaXMpO1xuICAgIGNsb25lLmNsaXBCb3ggPSB0aGlzLmNsaXBCb3guc2xpY2UoKTtcbiAgICByZXR1cm4gY2xvbmU7XG4gIH1cblxuICBzZXRDdXJyZW50UG9pbnQoeCwgeSkge1xuICAgIHRoaXMueCA9IHg7XG4gICAgdGhpcy55ID0geTtcbiAgfVxuXG4gIHVwZGF0ZVBhdGhNaW5NYXgodHJhbnNmb3JtLCB4LCB5KSB7XG4gICAgW3gsIHldID0gX3V0aWwuVXRpbC5hcHBseVRyYW5zZm9ybShbeCwgeV0sIHRyYW5zZm9ybSk7XG4gICAgdGhpcy5taW5YID0gTWF0aC5taW4odGhpcy5taW5YLCB4KTtcbiAgICB0aGlzLm1pblkgPSBNYXRoLm1pbih0aGlzLm1pblksIHkpO1xuICAgIHRoaXMubWF4WCA9IE1hdGgubWF4KHRoaXMubWF4WCwgeCk7XG4gICAgdGhpcy5tYXhZID0gTWF0aC5tYXgodGhpcy5tYXhZLCB5KTtcbiAgfVxuXG4gIHVwZGF0ZVJlY3RNaW5NYXgodHJhbnNmb3JtLCByZWN0KSB7XG4gICAgY29uc3QgcDEgPSBfdXRpbC5VdGlsLmFwcGx5VHJhbnNmb3JtKHJlY3QsIHRyYW5zZm9ybSk7XG5cbiAgICBjb25zdCBwMiA9IF91dGlsLlV0aWwuYXBwbHlUcmFuc2Zvcm0ocmVjdC5zbGljZSgyKSwgdHJhbnNmb3JtKTtcblxuICAgIHRoaXMubWluWCA9IE1hdGgubWluKHRoaXMubWluWCwgcDFbMF0sIHAyWzBdKTtcbiAgICB0aGlzLm1pblkgPSBNYXRoLm1pbih0aGlzLm1pblksIHAxWzFdLCBwMlsxXSk7XG4gICAgdGhpcy5tYXhYID0gTWF0aC5tYXgodGhpcy5tYXhYLCBwMVswXSwgcDJbMF0pO1xuICAgIHRoaXMubWF4WSA9IE1hdGgubWF4KHRoaXMubWF4WSwgcDFbMV0sIHAyWzFdKTtcbiAgfVxuXG4gIHVwZGF0ZVNjYWxpbmdQYXRoTWluTWF4KHRyYW5zZm9ybSwgbWluTWF4KSB7XG4gICAgX3V0aWwuVXRpbC5zY2FsZU1pbk1heCh0cmFuc2Zvcm0sIG1pbk1heCk7XG5cbiAgICB0aGlzLm1pblggPSBNYXRoLm1pbih0aGlzLm1pblgsIG1pbk1heFswXSk7XG4gICAgdGhpcy5tYXhYID0gTWF0aC5tYXgodGhpcy5tYXhYLCBtaW5NYXhbMV0pO1xuICAgIHRoaXMubWluWSA9IE1hdGgubWluKHRoaXMubWluWSwgbWluTWF4WzJdKTtcbiAgICB0aGlzLm1heFkgPSBNYXRoLm1heCh0aGlzLm1heFksIG1pbk1heFszXSk7XG4gIH1cblxuICB1cGRhdGVDdXJ2ZVBhdGhNaW5NYXgodHJhbnNmb3JtLCB4MCwgeTAsIHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIG1pbk1heCkge1xuICAgIGNvbnN0IGJveCA9IF91dGlsLlV0aWwuYmV6aWVyQm91bmRpbmdCb3goeDAsIHkwLCB4MSwgeTEsIHgyLCB5MiwgeDMsIHkzKTtcblxuICAgIGlmIChtaW5NYXgpIHtcbiAgICAgIG1pbk1heFswXSA9IE1hdGgubWluKG1pbk1heFswXSwgYm94WzBdLCBib3hbMl0pO1xuICAgICAgbWluTWF4WzFdID0gTWF0aC5tYXgobWluTWF4WzFdLCBib3hbMF0sIGJveFsyXSk7XG4gICAgICBtaW5NYXhbMl0gPSBNYXRoLm1pbihtaW5NYXhbMl0sIGJveFsxXSwgYm94WzNdKTtcbiAgICAgIG1pbk1heFszXSA9IE1hdGgubWF4KG1pbk1heFszXSwgYm94WzFdLCBib3hbM10pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlUmVjdE1pbk1heCh0cmFuc2Zvcm0sIGJveCk7XG4gIH1cblxuICBnZXRQYXRoQm91bmRpbmdCb3gocGF0aFR5cGUgPSBfcGF0dGVybl9oZWxwZXIuUGF0aFR5cGUuRklMTCwgdHJhbnNmb3JtID0gbnVsbCkge1xuICAgIGNvbnN0IGJveCA9IFt0aGlzLm1pblgsIHRoaXMubWluWSwgdGhpcy5tYXhYLCB0aGlzLm1heFldO1xuXG4gICAgaWYgKHBhdGhUeXBlID09PSBfcGF0dGVybl9oZWxwZXIuUGF0aFR5cGUuU1RST0tFKSB7XG4gICAgICBpZiAoIXRyYW5zZm9ybSkge1xuICAgICAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiU3Ryb2tlIGJvdW5kaW5nIGJveCBtdXN0IGluY2x1ZGUgdHJhbnNmb3JtLlwiKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc2NhbGUgPSBfdXRpbC5VdGlsLnNpbmd1bGFyVmFsdWVEZWNvbXBvc2UyZFNjYWxlKHRyYW5zZm9ybSk7XG5cbiAgICAgIGNvbnN0IHhTdHJva2VQYWQgPSBzY2FsZVswXSAqIHRoaXMubGluZVdpZHRoIC8gMjtcbiAgICAgIGNvbnN0IHlTdHJva2VQYWQgPSBzY2FsZVsxXSAqIHRoaXMubGluZVdpZHRoIC8gMjtcbiAgICAgIGJveFswXSAtPSB4U3Ryb2tlUGFkO1xuICAgICAgYm94WzFdIC09IHlTdHJva2VQYWQ7XG4gICAgICBib3hbMl0gKz0geFN0cm9rZVBhZDtcbiAgICAgIGJveFszXSArPSB5U3Ryb2tlUGFkO1xuICAgIH1cblxuICAgIHJldHVybiBib3g7XG4gIH1cblxuICB1cGRhdGVDbGlwRnJvbVBhdGgoKSB7XG4gICAgY29uc3QgaW50ZXJzZWN0ID0gX3V0aWwuVXRpbC5pbnRlcnNlY3QodGhpcy5jbGlwQm94LCB0aGlzLmdldFBhdGhCb3VuZGluZ0JveCgpKTtcblxuICAgIHRoaXMuc3RhcnROZXdQYXRoQW5kQ2xpcEJveChpbnRlcnNlY3QgfHwgWzAsIDAsIDAsIDBdKTtcbiAgfVxuXG4gIGlzRW1wdHlDbGlwKCkge1xuICAgIHJldHVybiB0aGlzLm1pblggPT09IEluZmluaXR5O1xuICB9XG5cbiAgc3RhcnROZXdQYXRoQW5kQ2xpcEJveChib3gpIHtcbiAgICB0aGlzLmNsaXBCb3ggPSBib3g7XG4gICAgdGhpcy5taW5YID0gSW5maW5pdHk7XG4gICAgdGhpcy5taW5ZID0gSW5maW5pdHk7XG4gICAgdGhpcy5tYXhYID0gMDtcbiAgICB0aGlzLm1heFkgPSAwO1xuICB9XG5cbiAgZ2V0Q2xpcHBlZFBhdGhCb3VuZGluZ0JveChwYXRoVHlwZSA9IF9wYXR0ZXJuX2hlbHBlci5QYXRoVHlwZS5GSUxMLCB0cmFuc2Zvcm0gPSBudWxsKSB7XG4gICAgcmV0dXJuIF91dGlsLlV0aWwuaW50ZXJzZWN0KHRoaXMuY2xpcEJveCwgdGhpcy5nZXRQYXRoQm91bmRpbmdCb3gocGF0aFR5cGUsIHRyYW5zZm9ybSkpO1xuICB9XG5cbn1cblxuZnVuY3Rpb24gcHV0QmluYXJ5SW1hZ2VEYXRhKGN0eCwgaW1nRGF0YSwgdHJhbnNmZXJNYXBzID0gbnVsbCkge1xuICBpZiAodHlwZW9mIEltYWdlRGF0YSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBpbWdEYXRhIGluc3RhbmNlb2YgSW1hZ2VEYXRhKSB7XG4gICAgY3R4LnB1dEltYWdlRGF0YShpbWdEYXRhLCAwLCAwKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBoZWlnaHQgPSBpbWdEYXRhLmhlaWdodCxcbiAgICAgICAgd2lkdGggPSBpbWdEYXRhLndpZHRoO1xuICBjb25zdCBwYXJ0aWFsQ2h1bmtIZWlnaHQgPSBoZWlnaHQgJSBGVUxMX0NIVU5LX0hFSUdIVDtcbiAgY29uc3QgZnVsbENodW5rcyA9IChoZWlnaHQgLSBwYXJ0aWFsQ2h1bmtIZWlnaHQpIC8gRlVMTF9DSFVOS19IRUlHSFQ7XG4gIGNvbnN0IHRvdGFsQ2h1bmtzID0gcGFydGlhbENodW5rSGVpZ2h0ID09PSAwID8gZnVsbENodW5rcyA6IGZ1bGxDaHVua3MgKyAxO1xuICBjb25zdCBjaHVua0ltZ0RhdGEgPSBjdHguY3JlYXRlSW1hZ2VEYXRhKHdpZHRoLCBGVUxMX0NIVU5LX0hFSUdIVCk7XG4gIGxldCBzcmNQb3MgPSAwLFxuICAgICAgZGVzdFBvcztcbiAgY29uc3Qgc3JjID0gaW1nRGF0YS5kYXRhO1xuICBjb25zdCBkZXN0ID0gY2h1bmtJbWdEYXRhLmRhdGE7XG4gIGxldCBpLCBqLCB0aGlzQ2h1bmtIZWlnaHQsIGVsZW1zSW5UaGlzQ2h1bms7XG4gIGxldCB0cmFuc2Zlck1hcFJlZCwgdHJhbnNmZXJNYXBHcmVlbiwgdHJhbnNmZXJNYXBCbHVlLCB0cmFuc2Zlck1hcEdyYXk7XG5cbiAgaWYgKHRyYW5zZmVyTWFwcykge1xuICAgIHN3aXRjaCAodHJhbnNmZXJNYXBzLmxlbmd0aCkge1xuICAgICAgY2FzZSAxOlxuICAgICAgICB0cmFuc2Zlck1hcFJlZCA9IHRyYW5zZmVyTWFwc1swXTtcbiAgICAgICAgdHJhbnNmZXJNYXBHcmVlbiA9IHRyYW5zZmVyTWFwc1swXTtcbiAgICAgICAgdHJhbnNmZXJNYXBCbHVlID0gdHJhbnNmZXJNYXBzWzBdO1xuICAgICAgICB0cmFuc2Zlck1hcEdyYXkgPSB0cmFuc2Zlck1hcHNbMF07XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIDQ6XG4gICAgICAgIHRyYW5zZmVyTWFwUmVkID0gdHJhbnNmZXJNYXBzWzBdO1xuICAgICAgICB0cmFuc2Zlck1hcEdyZWVuID0gdHJhbnNmZXJNYXBzWzFdO1xuICAgICAgICB0cmFuc2Zlck1hcEJsdWUgPSB0cmFuc2Zlck1hcHNbMl07XG4gICAgICAgIHRyYW5zZmVyTWFwR3JheSA9IHRyYW5zZmVyTWFwc1szXTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKGltZ0RhdGEua2luZCA9PT0gX3V0aWwuSW1hZ2VLaW5kLkdSQVlTQ0FMRV8xQlBQKSB7XG4gICAgY29uc3Qgc3JjTGVuZ3RoID0gc3JjLmJ5dGVMZW5ndGg7XG4gICAgY29uc3QgZGVzdDMyID0gbmV3IFVpbnQzMkFycmF5KGRlc3QuYnVmZmVyLCAwLCBkZXN0LmJ5dGVMZW5ndGggPj4gMik7XG4gICAgY29uc3QgZGVzdDMyRGF0YUxlbmd0aCA9IGRlc3QzMi5sZW5ndGg7XG4gICAgY29uc3QgZnVsbFNyY0RpZmYgPSB3aWR0aCArIDcgPj4gMztcbiAgICBsZXQgd2hpdGUgPSAweGZmZmZmZmZmO1xuICAgIGxldCBibGFjayA9IF91dGlsLkZlYXR1cmVUZXN0LmlzTGl0dGxlRW5kaWFuID8gMHhmZjAwMDAwMCA6IDB4MDAwMDAwZmY7XG5cbiAgICBpZiAodHJhbnNmZXJNYXBHcmF5KSB7XG4gICAgICBpZiAodHJhbnNmZXJNYXBHcmF5WzBdID09PSAweGZmICYmIHRyYW5zZmVyTWFwR3JheVsweGZmXSA9PT0gMCkge1xuICAgICAgICBbd2hpdGUsIGJsYWNrXSA9IFtibGFjaywgd2hpdGVdO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoaSA9IDA7IGkgPCB0b3RhbENodW5rczsgaSsrKSB7XG4gICAgICB0aGlzQ2h1bmtIZWlnaHQgPSBpIDwgZnVsbENodW5rcyA/IEZVTExfQ0hVTktfSEVJR0hUIDogcGFydGlhbENodW5rSGVpZ2h0O1xuICAgICAgZGVzdFBvcyA9IDA7XG5cbiAgICAgIGZvciAoaiA9IDA7IGogPCB0aGlzQ2h1bmtIZWlnaHQ7IGorKykge1xuICAgICAgICBjb25zdCBzcmNEaWZmID0gc3JjTGVuZ3RoIC0gc3JjUG9zO1xuICAgICAgICBsZXQgayA9IDA7XG4gICAgICAgIGNvbnN0IGtFbmQgPSBzcmNEaWZmID4gZnVsbFNyY0RpZmYgPyB3aWR0aCA6IHNyY0RpZmYgKiA4IC0gNztcbiAgICAgICAgY29uc3Qga0VuZFVucm9sbGVkID0ga0VuZCAmIH43O1xuICAgICAgICBsZXQgbWFzayA9IDA7XG4gICAgICAgIGxldCBzcmNCeXRlID0gMDtcblxuICAgICAgICBmb3IgKDsgayA8IGtFbmRVbnJvbGxlZDsgayArPSA4KSB7XG4gICAgICAgICAgc3JjQnl0ZSA9IHNyY1tzcmNQb3MrK107XG4gICAgICAgICAgZGVzdDMyW2Rlc3RQb3MrK10gPSBzcmNCeXRlICYgMTI4ID8gd2hpdGUgOiBibGFjaztcbiAgICAgICAgICBkZXN0MzJbZGVzdFBvcysrXSA9IHNyY0J5dGUgJiA2NCA/IHdoaXRlIDogYmxhY2s7XG4gICAgICAgICAgZGVzdDMyW2Rlc3RQb3MrK10gPSBzcmNCeXRlICYgMzIgPyB3aGl0ZSA6IGJsYWNrO1xuICAgICAgICAgIGRlc3QzMltkZXN0UG9zKytdID0gc3JjQnl0ZSAmIDE2ID8gd2hpdGUgOiBibGFjaztcbiAgICAgICAgICBkZXN0MzJbZGVzdFBvcysrXSA9IHNyY0J5dGUgJiA4ID8gd2hpdGUgOiBibGFjaztcbiAgICAgICAgICBkZXN0MzJbZGVzdFBvcysrXSA9IHNyY0J5dGUgJiA0ID8gd2hpdGUgOiBibGFjaztcbiAgICAgICAgICBkZXN0MzJbZGVzdFBvcysrXSA9IHNyY0J5dGUgJiAyID8gd2hpdGUgOiBibGFjaztcbiAgICAgICAgICBkZXN0MzJbZGVzdFBvcysrXSA9IHNyY0J5dGUgJiAxID8gd2hpdGUgOiBibGFjaztcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoOyBrIDwga0VuZDsgaysrKSB7XG4gICAgICAgICAgaWYgKG1hc2sgPT09IDApIHtcbiAgICAgICAgICAgIHNyY0J5dGUgPSBzcmNbc3JjUG9zKytdO1xuICAgICAgICAgICAgbWFzayA9IDEyODtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkZXN0MzJbZGVzdFBvcysrXSA9IHNyY0J5dGUgJiBtYXNrID8gd2hpdGUgOiBibGFjaztcbiAgICAgICAgICBtYXNrID4+PSAxO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHdoaWxlIChkZXN0UG9zIDwgZGVzdDMyRGF0YUxlbmd0aCkge1xuICAgICAgICBkZXN0MzJbZGVzdFBvcysrXSA9IDA7XG4gICAgICB9XG5cbiAgICAgIGN0eC5wdXRJbWFnZURhdGEoY2h1bmtJbWdEYXRhLCAwLCBpICogRlVMTF9DSFVOS19IRUlHSFQpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpbWdEYXRhLmtpbmQgPT09IF91dGlsLkltYWdlS2luZC5SR0JBXzMyQlBQKSB7XG4gICAgY29uc3QgaGFzVHJhbnNmZXJNYXBzID0gISEodHJhbnNmZXJNYXBSZWQgfHwgdHJhbnNmZXJNYXBHcmVlbiB8fCB0cmFuc2Zlck1hcEJsdWUpO1xuICAgIGogPSAwO1xuICAgIGVsZW1zSW5UaGlzQ2h1bmsgPSB3aWR0aCAqIEZVTExfQ0hVTktfSEVJR0hUICogNDtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBmdWxsQ2h1bmtzOyBpKyspIHtcbiAgICAgIGRlc3Quc2V0KHNyYy5zdWJhcnJheShzcmNQb3MsIHNyY1BvcyArIGVsZW1zSW5UaGlzQ2h1bmspKTtcbiAgICAgIHNyY1BvcyArPSBlbGVtc0luVGhpc0NodW5rO1xuXG4gICAgICBpZiAoaGFzVHJhbnNmZXJNYXBzKSB7XG4gICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgZWxlbXNJblRoaXNDaHVuazsgayArPSA0KSB7XG4gICAgICAgICAgaWYgKHRyYW5zZmVyTWFwUmVkKSB7XG4gICAgICAgICAgICBkZXN0W2sgKyAwXSA9IHRyYW5zZmVyTWFwUmVkW2Rlc3RbayArIDBdXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodHJhbnNmZXJNYXBHcmVlbikge1xuICAgICAgICAgICAgZGVzdFtrICsgMV0gPSB0cmFuc2Zlck1hcEdyZWVuW2Rlc3RbayArIDFdXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodHJhbnNmZXJNYXBCbHVlKSB7XG4gICAgICAgICAgICBkZXN0W2sgKyAyXSA9IHRyYW5zZmVyTWFwQmx1ZVtkZXN0W2sgKyAyXV07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGN0eC5wdXRJbWFnZURhdGEoY2h1bmtJbWdEYXRhLCAwLCBqKTtcbiAgICAgIGogKz0gRlVMTF9DSFVOS19IRUlHSFQ7XG4gICAgfVxuXG4gICAgaWYgKGkgPCB0b3RhbENodW5rcykge1xuICAgICAgZWxlbXNJblRoaXNDaHVuayA9IHdpZHRoICogcGFydGlhbENodW5rSGVpZ2h0ICogNDtcbiAgICAgIGRlc3Quc2V0KHNyYy5zdWJhcnJheShzcmNQb3MsIHNyY1BvcyArIGVsZW1zSW5UaGlzQ2h1bmspKTtcblxuICAgICAgaWYgKGhhc1RyYW5zZmVyTWFwcykge1xuICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IGVsZW1zSW5UaGlzQ2h1bms7IGsgKz0gNCkge1xuICAgICAgICAgIGlmICh0cmFuc2Zlck1hcFJlZCkge1xuICAgICAgICAgICAgZGVzdFtrICsgMF0gPSB0cmFuc2Zlck1hcFJlZFtkZXN0W2sgKyAwXV07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHRyYW5zZmVyTWFwR3JlZW4pIHtcbiAgICAgICAgICAgIGRlc3RbayArIDFdID0gdHJhbnNmZXJNYXBHcmVlbltkZXN0W2sgKyAxXV07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHRyYW5zZmVyTWFwQmx1ZSkge1xuICAgICAgICAgICAgZGVzdFtrICsgMl0gPSB0cmFuc2Zlck1hcEJsdWVbZGVzdFtrICsgMl1dO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjdHgucHV0SW1hZ2VEYXRhKGNodW5rSW1nRGF0YSwgMCwgaik7XG4gICAgfVxuICB9IGVsc2UgaWYgKGltZ0RhdGEua2luZCA9PT0gX3V0aWwuSW1hZ2VLaW5kLlJHQl8yNEJQUCkge1xuICAgIGNvbnN0IGhhc1RyYW5zZmVyTWFwcyA9ICEhKHRyYW5zZmVyTWFwUmVkIHx8IHRyYW5zZmVyTWFwR3JlZW4gfHwgdHJhbnNmZXJNYXBCbHVlKTtcbiAgICB0aGlzQ2h1bmtIZWlnaHQgPSBGVUxMX0NIVU5LX0hFSUdIVDtcbiAgICBlbGVtc0luVGhpc0NodW5rID0gd2lkdGggKiB0aGlzQ2h1bmtIZWlnaHQ7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgdG90YWxDaHVua3M7IGkrKykge1xuICAgICAgaWYgKGkgPj0gZnVsbENodW5rcykge1xuICAgICAgICB0aGlzQ2h1bmtIZWlnaHQgPSBwYXJ0aWFsQ2h1bmtIZWlnaHQ7XG4gICAgICAgIGVsZW1zSW5UaGlzQ2h1bmsgPSB3aWR0aCAqIHRoaXNDaHVua0hlaWdodDtcbiAgICAgIH1cblxuICAgICAgZGVzdFBvcyA9IDA7XG5cbiAgICAgIGZvciAoaiA9IGVsZW1zSW5UaGlzQ2h1bms7IGotLTspIHtcbiAgICAgICAgZGVzdFtkZXN0UG9zKytdID0gc3JjW3NyY1BvcysrXTtcbiAgICAgICAgZGVzdFtkZXN0UG9zKytdID0gc3JjW3NyY1BvcysrXTtcbiAgICAgICAgZGVzdFtkZXN0UG9zKytdID0gc3JjW3NyY1BvcysrXTtcbiAgICAgICAgZGVzdFtkZXN0UG9zKytdID0gMjU1O1xuICAgICAgfVxuXG4gICAgICBpZiAoaGFzVHJhbnNmZXJNYXBzKSB7XG4gICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgZGVzdFBvczsgayArPSA0KSB7XG4gICAgICAgICAgaWYgKHRyYW5zZmVyTWFwUmVkKSB7XG4gICAgICAgICAgICBkZXN0W2sgKyAwXSA9IHRyYW5zZmVyTWFwUmVkW2Rlc3RbayArIDBdXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodHJhbnNmZXJNYXBHcmVlbikge1xuICAgICAgICAgICAgZGVzdFtrICsgMV0gPSB0cmFuc2Zlck1hcEdyZWVuW2Rlc3RbayArIDFdXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodHJhbnNmZXJNYXBCbHVlKSB7XG4gICAgICAgICAgICBkZXN0W2sgKyAyXSA9IHRyYW5zZmVyTWFwQmx1ZVtkZXN0W2sgKyAyXV07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGN0eC5wdXRJbWFnZURhdGEoY2h1bmtJbWdEYXRhLCAwLCBpICogRlVMTF9DSFVOS19IRUlHSFQpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGJhZCBpbWFnZSBraW5kOiAke2ltZ0RhdGEua2luZH1gKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwdXRCaW5hcnlJbWFnZU1hc2soY3R4LCBpbWdEYXRhKSB7XG4gIGlmIChpbWdEYXRhLmJpdG1hcCkge1xuICAgIGN0eC5kcmF3SW1hZ2UoaW1nRGF0YS5iaXRtYXAsIDAsIDApO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGhlaWdodCA9IGltZ0RhdGEuaGVpZ2h0LFxuICAgICAgICB3aWR0aCA9IGltZ0RhdGEud2lkdGg7XG4gIGNvbnN0IHBhcnRpYWxDaHVua0hlaWdodCA9IGhlaWdodCAlIEZVTExfQ0hVTktfSEVJR0hUO1xuICBjb25zdCBmdWxsQ2h1bmtzID0gKGhlaWdodCAtIHBhcnRpYWxDaHVua0hlaWdodCkgLyBGVUxMX0NIVU5LX0hFSUdIVDtcbiAgY29uc3QgdG90YWxDaHVua3MgPSBwYXJ0aWFsQ2h1bmtIZWlnaHQgPT09IDAgPyBmdWxsQ2h1bmtzIDogZnVsbENodW5rcyArIDE7XG4gIGNvbnN0IGNodW5rSW1nRGF0YSA9IGN0eC5jcmVhdGVJbWFnZURhdGEod2lkdGgsIEZVTExfQ0hVTktfSEVJR0hUKTtcbiAgbGV0IHNyY1BvcyA9IDA7XG4gIGNvbnN0IHNyYyA9IGltZ0RhdGEuZGF0YTtcbiAgY29uc3QgZGVzdCA9IGNodW5rSW1nRGF0YS5kYXRhO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdG90YWxDaHVua3M7IGkrKykge1xuICAgIGNvbnN0IHRoaXNDaHVua0hlaWdodCA9IGkgPCBmdWxsQ2h1bmtzID8gRlVMTF9DSFVOS19IRUlHSFQgOiBwYXJ0aWFsQ2h1bmtIZWlnaHQ7XG4gICAgKHtcbiAgICAgIHNyY1Bvc1xuICAgIH0gPSAoMCwgX2ltYWdlX3V0aWxzLmFwcGx5TWFza0ltYWdlRGF0YSkoe1xuICAgICAgc3JjLFxuICAgICAgc3JjUG9zLFxuICAgICAgZGVzdCxcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0OiB0aGlzQ2h1bmtIZWlnaHRcbiAgICB9KSk7XG4gICAgY3R4LnB1dEltYWdlRGF0YShjaHVua0ltZ0RhdGEsIDAsIGkgKiBGVUxMX0NIVU5LX0hFSUdIVCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29weUN0eFN0YXRlKHNvdXJjZUN0eCwgZGVzdEN0eCkge1xuICBjb25zdCBwcm9wZXJ0aWVzID0gW1wic3Ryb2tlU3R5bGVcIiwgXCJmaWxsU3R5bGVcIiwgXCJmaWxsUnVsZVwiLCBcImdsb2JhbEFscGhhXCIsIFwibGluZVdpZHRoXCIsIFwibGluZUNhcFwiLCBcImxpbmVKb2luXCIsIFwibWl0ZXJMaW1pdFwiLCBcImdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvblwiLCBcImZvbnRcIl07XG5cbiAgZm9yIChsZXQgaSA9IDAsIGlpID0gcHJvcGVydGllcy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgY29uc3QgcHJvcGVydHkgPSBwcm9wZXJ0aWVzW2ldO1xuXG4gICAgaWYgKHNvdXJjZUN0eFtwcm9wZXJ0eV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgZGVzdEN0eFtwcm9wZXJ0eV0gPSBzb3VyY2VDdHhbcHJvcGVydHldO1xuICAgIH1cbiAgfVxuXG4gIGlmIChzb3VyY2VDdHguc2V0TGluZURhc2ggIT09IHVuZGVmaW5lZCkge1xuICAgIGRlc3RDdHguc2V0TGluZURhc2goc291cmNlQ3R4LmdldExpbmVEYXNoKCkpO1xuICAgIGRlc3RDdHgubGluZURhc2hPZmZzZXQgPSBzb3VyY2VDdHgubGluZURhc2hPZmZzZXQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzZXRDdHhUb0RlZmF1bHQoY3R4LCBmb3JlZ3JvdW5kQ29sb3IpIHtcbiAgY3R4LnN0cm9rZVN0eWxlID0gY3R4LmZpbGxTdHlsZSA9IGZvcmVncm91bmRDb2xvciB8fCBcIiMwMDAwMDBcIjtcbiAgY3R4LmZpbGxSdWxlID0gXCJub256ZXJvXCI7XG4gIGN0eC5nbG9iYWxBbHBoYSA9IDE7XG4gIGN0eC5saW5lV2lkdGggPSAxO1xuICBjdHgubGluZUNhcCA9IFwiYnV0dFwiO1xuICBjdHgubGluZUpvaW4gPSBcIm1pdGVyXCI7XG4gIGN0eC5taXRlckxpbWl0ID0gMTA7XG4gIGN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSBcInNvdXJjZS1vdmVyXCI7XG4gIGN0eC5mb250ID0gXCIxMHB4IHNhbnMtc2VyaWZcIjtcblxuICBpZiAoY3R4LnNldExpbmVEYXNoICE9PSB1bmRlZmluZWQpIHtcbiAgICBjdHguc2V0TGluZURhc2goW10pO1xuICAgIGN0eC5saW5lRGFzaE9mZnNldCA9IDA7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tcG9zZVNNYXNrQmFja2Ryb3AoYnl0ZXMsIHIwLCBnMCwgYjApIHtcbiAgY29uc3QgbGVuZ3RoID0gYnl0ZXMubGVuZ3RoO1xuXG4gIGZvciAobGV0IGkgPSAzOyBpIDwgbGVuZ3RoOyBpICs9IDQpIHtcbiAgICBjb25zdCBhbHBoYSA9IGJ5dGVzW2ldO1xuXG4gICAgaWYgKGFscGhhID09PSAwKSB7XG4gICAgICBieXRlc1tpIC0gM10gPSByMDtcbiAgICAgIGJ5dGVzW2kgLSAyXSA9IGcwO1xuICAgICAgYnl0ZXNbaSAtIDFdID0gYjA7XG4gICAgfSBlbHNlIGlmIChhbHBoYSA8IDI1NSkge1xuICAgICAgY29uc3QgYWxwaGFfID0gMjU1IC0gYWxwaGE7XG4gICAgICBieXRlc1tpIC0gM10gPSBieXRlc1tpIC0gM10gKiBhbHBoYSArIHIwICogYWxwaGFfID4+IDg7XG4gICAgICBieXRlc1tpIC0gMl0gPSBieXRlc1tpIC0gMl0gKiBhbHBoYSArIGcwICogYWxwaGFfID4+IDg7XG4gICAgICBieXRlc1tpIC0gMV0gPSBieXRlc1tpIC0gMV0gKiBhbHBoYSArIGIwICogYWxwaGFfID4+IDg7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNvbXBvc2VTTWFza0FscGhhKG1hc2tEYXRhLCBsYXllckRhdGEsIHRyYW5zZmVyTWFwKSB7XG4gIGNvbnN0IGxlbmd0aCA9IG1hc2tEYXRhLmxlbmd0aDtcbiAgY29uc3Qgc2NhbGUgPSAxIC8gMjU1O1xuXG4gIGZvciAobGV0IGkgPSAzOyBpIDwgbGVuZ3RoOyBpICs9IDQpIHtcbiAgICBjb25zdCBhbHBoYSA9IHRyYW5zZmVyTWFwID8gdHJhbnNmZXJNYXBbbWFza0RhdGFbaV1dIDogbWFza0RhdGFbaV07XG4gICAgbGF5ZXJEYXRhW2ldID0gbGF5ZXJEYXRhW2ldICogYWxwaGEgKiBzY2FsZSB8IDA7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tcG9zZVNNYXNrTHVtaW5vc2l0eShtYXNrRGF0YSwgbGF5ZXJEYXRhLCB0cmFuc2Zlck1hcCkge1xuICBjb25zdCBsZW5ndGggPSBtYXNrRGF0YS5sZW5ndGg7XG5cbiAgZm9yIChsZXQgaSA9IDM7IGkgPCBsZW5ndGg7IGkgKz0gNCkge1xuICAgIGNvbnN0IHkgPSBtYXNrRGF0YVtpIC0gM10gKiA3NyArIG1hc2tEYXRhW2kgLSAyXSAqIDE1MiArIG1hc2tEYXRhW2kgLSAxXSAqIDI4O1xuICAgIGxheWVyRGF0YVtpXSA9IHRyYW5zZmVyTWFwID8gbGF5ZXJEYXRhW2ldICogdHJhbnNmZXJNYXBbeSA+PiA4XSA+PiA4IDogbGF5ZXJEYXRhW2ldICogeSA+PiAxNjtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZW5lcmljQ29tcG9zZVNNYXNrKG1hc2tDdHgsIGxheWVyQ3R4LCB3aWR0aCwgaGVpZ2h0LCBzdWJ0eXBlLCBiYWNrZHJvcCwgdHJhbnNmZXJNYXAsIGxheWVyT2Zmc2V0WCwgbGF5ZXJPZmZzZXRZLCBtYXNrT2Zmc2V0WCwgbWFza09mZnNldFkpIHtcbiAgY29uc3QgaGFzQmFja2Ryb3AgPSAhIWJhY2tkcm9wO1xuICBjb25zdCByMCA9IGhhc0JhY2tkcm9wID8gYmFja2Ryb3BbMF0gOiAwO1xuICBjb25zdCBnMCA9IGhhc0JhY2tkcm9wID8gYmFja2Ryb3BbMV0gOiAwO1xuICBjb25zdCBiMCA9IGhhc0JhY2tkcm9wID8gYmFja2Ryb3BbMl0gOiAwO1xuICBsZXQgY29tcG9zZUZuO1xuXG4gIGlmIChzdWJ0eXBlID09PSBcIkx1bWlub3NpdHlcIikge1xuICAgIGNvbXBvc2VGbiA9IGNvbXBvc2VTTWFza0x1bWlub3NpdHk7XG4gIH0gZWxzZSB7XG4gICAgY29tcG9zZUZuID0gY29tcG9zZVNNYXNrQWxwaGE7XG4gIH1cblxuICBjb25zdCBQSVhFTFNfVE9fUFJPQ0VTUyA9IDEwNDg1NzY7XG4gIGNvbnN0IGNodW5rU2l6ZSA9IE1hdGgubWluKGhlaWdodCwgTWF0aC5jZWlsKFBJWEVMU19UT19QUk9DRVNTIC8gd2lkdGgpKTtcblxuICBmb3IgKGxldCByb3cgPSAwOyByb3cgPCBoZWlnaHQ7IHJvdyArPSBjaHVua1NpemUpIHtcbiAgICBjb25zdCBjaHVua0hlaWdodCA9IE1hdGgubWluKGNodW5rU2l6ZSwgaGVpZ2h0IC0gcm93KTtcbiAgICBjb25zdCBtYXNrRGF0YSA9IG1hc2tDdHguZ2V0SW1hZ2VEYXRhKGxheWVyT2Zmc2V0WCAtIG1hc2tPZmZzZXRYLCByb3cgKyAobGF5ZXJPZmZzZXRZIC0gbWFza09mZnNldFkpLCB3aWR0aCwgY2h1bmtIZWlnaHQpO1xuICAgIGNvbnN0IGxheWVyRGF0YSA9IGxheWVyQ3R4LmdldEltYWdlRGF0YShsYXllck9mZnNldFgsIHJvdyArIGxheWVyT2Zmc2V0WSwgd2lkdGgsIGNodW5rSGVpZ2h0KTtcblxuICAgIGlmIChoYXNCYWNrZHJvcCkge1xuICAgICAgY29tcG9zZVNNYXNrQmFja2Ryb3AobWFza0RhdGEuZGF0YSwgcjAsIGcwLCBiMCk7XG4gICAgfVxuXG4gICAgY29tcG9zZUZuKG1hc2tEYXRhLmRhdGEsIGxheWVyRGF0YS5kYXRhLCB0cmFuc2Zlck1hcCk7XG4gICAgbGF5ZXJDdHgucHV0SW1hZ2VEYXRhKGxheWVyRGF0YSwgbGF5ZXJPZmZzZXRYLCByb3cgKyBsYXllck9mZnNldFkpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbXBvc2VTTWFzayhjdHgsIHNtYXNrLCBsYXllckN0eCwgbGF5ZXJCb3gpIHtcbiAgY29uc3QgbGF5ZXJPZmZzZXRYID0gbGF5ZXJCb3hbMF07XG4gIGNvbnN0IGxheWVyT2Zmc2V0WSA9IGxheWVyQm94WzFdO1xuICBjb25zdCBsYXllcldpZHRoID0gbGF5ZXJCb3hbMl0gLSBsYXllck9mZnNldFg7XG4gIGNvbnN0IGxheWVySGVpZ2h0ID0gbGF5ZXJCb3hbM10gLSBsYXllck9mZnNldFk7XG5cbiAgaWYgKGxheWVyV2lkdGggPT09IDAgfHwgbGF5ZXJIZWlnaHQgPT09IDApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBnZW5lcmljQ29tcG9zZVNNYXNrKHNtYXNrLmNvbnRleHQsIGxheWVyQ3R4LCBsYXllcldpZHRoLCBsYXllckhlaWdodCwgc21hc2suc3VidHlwZSwgc21hc2suYmFja2Ryb3AsIHNtYXNrLnRyYW5zZmVyTWFwLCBsYXllck9mZnNldFgsIGxheWVyT2Zmc2V0WSwgc21hc2sub2Zmc2V0WCwgc21hc2sub2Zmc2V0WSk7XG4gIGN0eC5zYXZlKCk7XG4gIGN0eC5nbG9iYWxBbHBoYSA9IDE7XG4gIGN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSBcInNvdXJjZS1vdmVyXCI7XG4gIGN0eC5zZXRUcmFuc2Zvcm0oMSwgMCwgMCwgMSwgMCwgMCk7XG4gIGN0eC5kcmF3SW1hZ2UobGF5ZXJDdHguY2FudmFzLCAwLCAwKTtcbiAgY3R4LnJlc3RvcmUoKTtcbn1cblxuZnVuY3Rpb24gZ2V0SW1hZ2VTbW9vdGhpbmdFbmFibGVkKHRyYW5zZm9ybSwgaW50ZXJwb2xhdGUpIHtcbiAgY29uc3Qgc2NhbGUgPSBfdXRpbC5VdGlsLnNpbmd1bGFyVmFsdWVEZWNvbXBvc2UyZFNjYWxlKHRyYW5zZm9ybSk7XG5cbiAgc2NhbGVbMF0gPSBNYXRoLmZyb3VuZChzY2FsZVswXSk7XG4gIHNjYWxlWzFdID0gTWF0aC5mcm91bmQoc2NhbGVbMV0pO1xuICBjb25zdCBhY3R1YWxTY2FsZSA9IE1hdGguZnJvdW5kKChnbG9iYWxUaGlzLmRldmljZVBpeGVsUmF0aW8gfHwgMSkgKiBfZGlzcGxheV91dGlscy5QaXhlbHNQZXJJbmNoLlBERl9UT19DU1NfVU5JVFMpO1xuXG4gIGlmIChpbnRlcnBvbGF0ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGludGVycG9sYXRlO1xuICB9IGVsc2UgaWYgKHNjYWxlWzBdIDw9IGFjdHVhbFNjYWxlIHx8IHNjYWxlWzFdIDw9IGFjdHVhbFNjYWxlKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmNvbnN0IExJTkVfQ0FQX1NUWUxFUyA9IFtcImJ1dHRcIiwgXCJyb3VuZFwiLCBcInNxdWFyZVwiXTtcbmNvbnN0IExJTkVfSk9JTl9TVFlMRVMgPSBbXCJtaXRlclwiLCBcInJvdW5kXCIsIFwiYmV2ZWxcIl07XG5jb25zdCBOT1JNQUxfQ0xJUCA9IHt9O1xuY29uc3QgRU9fQ0xJUCA9IHt9O1xuXG5jbGFzcyBDYW52YXNHcmFwaGljcyB7XG4gIGNvbnN0cnVjdG9yKGNhbnZhc0N0eCwgY29tbW9uT2Jqcywgb2JqcywgY2FudmFzRmFjdG9yeSwgaW1hZ2VMYXllciwgb3B0aW9uYWxDb250ZW50Q29uZmlnLCBhbm5vdGF0aW9uQ2FudmFzTWFwLCBwYWdlQ29sb3JzKSB7XG4gICAgdGhpcy5jdHggPSBjYW52YXNDdHg7XG4gICAgdGhpcy5jdXJyZW50ID0gbmV3IENhbnZhc0V4dHJhU3RhdGUodGhpcy5jdHguY2FudmFzLndpZHRoLCB0aGlzLmN0eC5jYW52YXMuaGVpZ2h0KTtcbiAgICB0aGlzLnN0YXRlU3RhY2sgPSBbXTtcbiAgICB0aGlzLnBlbmRpbmdDbGlwID0gbnVsbDtcbiAgICB0aGlzLnBlbmRpbmdFT0ZpbGwgPSBmYWxzZTtcbiAgICB0aGlzLnJlcyA9IG51bGw7XG4gICAgdGhpcy54b2JqcyA9IG51bGw7XG4gICAgdGhpcy5jb21tb25PYmpzID0gY29tbW9uT2JqcztcbiAgICB0aGlzLm9ianMgPSBvYmpzO1xuICAgIHRoaXMuY2FudmFzRmFjdG9yeSA9IGNhbnZhc0ZhY3Rvcnk7XG4gICAgdGhpcy5pbWFnZUxheWVyID0gaW1hZ2VMYXllcjtcbiAgICB0aGlzLmdyb3VwU3RhY2sgPSBbXTtcbiAgICB0aGlzLnByb2Nlc3NpbmdUeXBlMyA9IG51bGw7XG4gICAgdGhpcy5iYXNlVHJhbnNmb3JtID0gbnVsbDtcbiAgICB0aGlzLmJhc2VUcmFuc2Zvcm1TdGFjayA9IFtdO1xuICAgIHRoaXMuZ3JvdXBMZXZlbCA9IDA7XG4gICAgdGhpcy5zbWFza1N0YWNrID0gW107XG4gICAgdGhpcy5zbWFza0NvdW50ZXIgPSAwO1xuICAgIHRoaXMudGVtcFNNYXNrID0gbnVsbDtcbiAgICB0aGlzLnN1c3BlbmRlZEN0eCA9IG51bGw7XG4gICAgdGhpcy5jb250ZW50VmlzaWJsZSA9IHRydWU7XG4gICAgdGhpcy5tYXJrZWRDb250ZW50U3RhY2sgPSBbXTtcbiAgICB0aGlzLm9wdGlvbmFsQ29udGVudENvbmZpZyA9IG9wdGlvbmFsQ29udGVudENvbmZpZztcbiAgICB0aGlzLmNhY2hlZENhbnZhc2VzID0gbmV3IENhY2hlZENhbnZhc2VzKHRoaXMuY2FudmFzRmFjdG9yeSk7XG4gICAgdGhpcy5jYWNoZWRQYXR0ZXJucyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmFubm90YXRpb25DYW52YXNNYXAgPSBhbm5vdGF0aW9uQ2FudmFzTWFwO1xuICAgIHRoaXMudmlld3BvcnRTY2FsZSA9IDE7XG4gICAgdGhpcy5vdXRwdXRTY2FsZVggPSAxO1xuICAgIHRoaXMub3V0cHV0U2NhbGVZID0gMTtcbiAgICB0aGlzLmJhY2tncm91bmRDb2xvciA9IHBhZ2VDb2xvcnM/LmJhY2tncm91bmQgfHwgbnVsbDtcbiAgICB0aGlzLmZvcmVncm91bmRDb2xvciA9IHBhZ2VDb2xvcnM/LmZvcmVncm91bmQgfHwgbnVsbDtcblxuICAgIGlmIChjYW52YXNDdHgpIHtcbiAgICAgIGFkZENvbnRleHRDdXJyZW50VHJhbnNmb3JtKGNhbnZhc0N0eCk7XG4gICAgfVxuXG4gICAgdGhpcy5fY2FjaGVkU2NhbGVGb3JTdHJva2luZyA9IG51bGw7XG4gICAgdGhpcy5fY2FjaGVkR2V0U2luZ2xlUGl4ZWxXaWR0aCA9IG51bGw7XG4gICAgdGhpcy5fY2FjaGVkQml0bWFwc01hcCA9IG5ldyBNYXAoKTtcbiAgfVxuXG4gIGdldE9iamVjdChkYXRhLCBmYWxsYmFjayA9IG51bGwpIHtcbiAgICBpZiAodHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHJldHVybiBkYXRhLnN0YXJ0c1dpdGgoXCJnX1wiKSA/IHRoaXMuY29tbW9uT2Jqcy5nZXQoZGF0YSkgOiB0aGlzLm9ianMuZ2V0KGRhdGEpO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxsYmFjaztcbiAgfVxuXG4gIGJlZ2luRHJhd2luZyh7XG4gICAgdHJhbnNmb3JtLFxuICAgIHZpZXdwb3J0LFxuICAgIHRyYW5zcGFyZW5jeSA9IGZhbHNlLFxuICAgIGJhY2tncm91bmQgPSBudWxsXG4gIH0pIHtcbiAgICBjb25zdCB3aWR0aCA9IHRoaXMuY3R4LmNhbnZhcy53aWR0aDtcbiAgICBjb25zdCBoZWlnaHQgPSB0aGlzLmN0eC5jYW52YXMuaGVpZ2h0O1xuICAgIGNvbnN0IGRlZmF1bHRCYWNrZ3JvdW5kQ29sb3IgPSBiYWNrZ3JvdW5kIHx8IFwiI2ZmZmZmZlwiO1xuICAgIHRoaXMuY3R4LnNhdmUoKTtcblxuICAgIGlmICh0aGlzLmZvcmVncm91bmRDb2xvciAmJiB0aGlzLmJhY2tncm91bmRDb2xvcikge1xuICAgICAgdGhpcy5jdHguZmlsbFN0eWxlID0gdGhpcy5mb3JlZ3JvdW5kQ29sb3I7XG4gICAgICBjb25zdCBmZyA9IHRoaXMuZm9yZWdyb3VuZENvbG9yID0gdGhpcy5jdHguZmlsbFN0eWxlO1xuICAgICAgdGhpcy5jdHguZmlsbFN0eWxlID0gdGhpcy5iYWNrZ3JvdW5kQ29sb3I7XG4gICAgICBjb25zdCBiZyA9IHRoaXMuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jdHguZmlsbFN0eWxlO1xuICAgICAgbGV0IGlzVmFsaWREZWZhdWx0QmcgPSB0cnVlO1xuICAgICAgbGV0IGRlZmF1bHRCZyA9IGRlZmF1bHRCYWNrZ3JvdW5kQ29sb3I7XG4gICAgICB0aGlzLmN0eC5maWxsU3R5bGUgPSBkZWZhdWx0QmFja2dyb3VuZENvbG9yO1xuICAgICAgZGVmYXVsdEJnID0gdGhpcy5jdHguZmlsbFN0eWxlO1xuICAgICAgaXNWYWxpZERlZmF1bHRCZyA9IHR5cGVvZiBkZWZhdWx0QmcgPT09IFwic3RyaW5nXCIgJiYgL14jWzAtOUEtRmEtZl17Nn0kLy50ZXN0KGRlZmF1bHRCZyk7XG5cbiAgICAgIGlmIChmZyA9PT0gXCIjMDAwMDAwXCIgJiYgYmcgPT09IFwiI2ZmZmZmZlwiIHx8IGZnID09PSBiZyB8fCAhaXNWYWxpZERlZmF1bHRCZykge1xuICAgICAgICB0aGlzLmZvcmVncm91bmRDb2xvciA9IHRoaXMuYmFja2dyb3VuZENvbG9yID0gbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGNCID0gcGFyc2VJbnQoZGVmYXVsdEJnLnNsaWNlKDEpLCAxNik7XG4gICAgICAgIGNvbnN0IHJCID0gKGNCICYmIDB4ZmYwMDAwKSA+PiAxNjtcbiAgICAgICAgY29uc3QgZ0IgPSAoY0IgJiYgMHgwMGZmMDApID4+IDg7XG4gICAgICAgIGNvbnN0IGJCID0gY0IgJiYgMHgwMDAwZmY7XG5cbiAgICAgICAgY29uc3QgbmV3Q29tcCA9IHggPT4ge1xuICAgICAgICAgIHggLz0gMjU1O1xuICAgICAgICAgIHJldHVybiB4IDw9IDAuMDM5MjggPyB4IC8gMTIuOTIgOiAoKHggKyAwLjA1NSkgLyAxLjA1NSkgKiogMi40O1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGx1bUIgPSBNYXRoLnJvdW5kKDAuMjEyNiAqIG5ld0NvbXAockIpICsgMC43MTUyICogbmV3Q29tcChnQikgKyAwLjA3MjIgKiBuZXdDb21wKGJCKSk7XG5cbiAgICAgICAgdGhpcy5zZWxlY3RDb2xvciA9IChyLCBnLCBiKSA9PiB7XG4gICAgICAgICAgY29uc3QgbHVtQyA9IDAuMjEyNiAqIG5ld0NvbXAocikgKyAwLjcxNTIgKiBuZXdDb21wKGcpICsgMC4wNzIyICogbmV3Q29tcChiKTtcbiAgICAgICAgICByZXR1cm4gTWF0aC5yb3VuZChsdW1DKSA9PT0gbHVtQiA/IGJnIDogZmc7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5jdHguZmlsbFN0eWxlID0gdGhpcy5iYWNrZ3JvdW5kQ29sb3IgfHwgZGVmYXVsdEJhY2tncm91bmRDb2xvcjtcbiAgICB0aGlzLmN0eC5maWxsUmVjdCgwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICB0aGlzLmN0eC5yZXN0b3JlKCk7XG5cbiAgICBpZiAodHJhbnNwYXJlbmN5KSB7XG4gICAgICBjb25zdCB0cmFuc3BhcmVudENhbnZhcyA9IHRoaXMuY2FjaGVkQ2FudmFzZXMuZ2V0Q2FudmFzKFwidHJhbnNwYXJlbnRcIiwgd2lkdGgsIGhlaWdodCwgdHJ1ZSk7XG4gICAgICB0aGlzLmNvbXBvc2l0ZUN0eCA9IHRoaXMuY3R4O1xuICAgICAgdGhpcy50cmFuc3BhcmVudENhbnZhcyA9IHRyYW5zcGFyZW50Q2FudmFzLmNhbnZhcztcbiAgICAgIHRoaXMuY3R4ID0gdHJhbnNwYXJlbnRDYW52YXMuY29udGV4dDtcbiAgICAgIHRoaXMuY3R4LnNhdmUoKTtcbiAgICAgIHRoaXMuY3R4LnRyYW5zZm9ybS5hcHBseSh0aGlzLmN0eCwgdGhpcy5jb21wb3NpdGVDdHgubW96Q3VycmVudFRyYW5zZm9ybSk7XG4gICAgfVxuXG4gICAgdGhpcy5jdHguc2F2ZSgpO1xuICAgIHJlc2V0Q3R4VG9EZWZhdWx0KHRoaXMuY3R4LCB0aGlzLmZvcmVncm91bmRDb2xvcik7XG5cbiAgICBpZiAodHJhbnNmb3JtKSB7XG4gICAgICB0aGlzLmN0eC50cmFuc2Zvcm0uYXBwbHkodGhpcy5jdHgsIHRyYW5zZm9ybSk7XG4gICAgICB0aGlzLm91dHB1dFNjYWxlWCA9IHRyYW5zZm9ybVswXTtcbiAgICAgIHRoaXMub3V0cHV0U2NhbGVZID0gdHJhbnNmb3JtWzBdO1xuICAgIH1cblxuICAgIHRoaXMuY3R4LnRyYW5zZm9ybS5hcHBseSh0aGlzLmN0eCwgdmlld3BvcnQudHJhbnNmb3JtKTtcbiAgICB0aGlzLnZpZXdwb3J0U2NhbGUgPSB2aWV3cG9ydC5zY2FsZTtcbiAgICB0aGlzLmJhc2VUcmFuc2Zvcm0gPSB0aGlzLmN0eC5tb3pDdXJyZW50VHJhbnNmb3JtLnNsaWNlKCk7XG5cbiAgICBpZiAodGhpcy5pbWFnZUxheWVyKSB7XG4gICAgICB0aGlzLmltYWdlTGF5ZXIuYmVnaW5MYXlvdXQoKTtcbiAgICB9XG4gIH1cblxuICBleGVjdXRlT3BlcmF0b3JMaXN0KG9wZXJhdG9yTGlzdCwgZXhlY3V0aW9uU3RhcnRJZHgsIGNvbnRpbnVlQ2FsbGJhY2ssIHN0ZXBwZXIpIHtcbiAgICBjb25zdCBhcmdzQXJyYXkgPSBvcGVyYXRvckxpc3QuYXJnc0FycmF5O1xuICAgIGNvbnN0IGZuQXJyYXkgPSBvcGVyYXRvckxpc3QuZm5BcnJheTtcbiAgICBsZXQgaSA9IGV4ZWN1dGlvblN0YXJ0SWR4IHx8IDA7XG4gICAgY29uc3QgYXJnc0FycmF5TGVuID0gYXJnc0FycmF5Lmxlbmd0aDtcblxuICAgIGlmIChhcmdzQXJyYXlMZW4gPT09IGkpIHtcbiAgICAgIHJldHVybiBpO1xuICAgIH1cblxuICAgIGNvbnN0IGNodW5rT3BlcmF0aW9ucyA9IGFyZ3NBcnJheUxlbiAtIGkgPiBFWEVDVVRJT05fU1RFUFMgJiYgdHlwZW9mIGNvbnRpbnVlQ2FsbGJhY2sgPT09IFwiZnVuY3Rpb25cIjtcbiAgICBjb25zdCBlbmRUaW1lID0gY2h1bmtPcGVyYXRpb25zID8gRGF0ZS5ub3coKSArIEVYRUNVVElPTl9USU1FIDogMDtcbiAgICBsZXQgc3RlcHMgPSAwO1xuICAgIGNvbnN0IGNvbW1vbk9ianMgPSB0aGlzLmNvbW1vbk9ianM7XG4gICAgY29uc3Qgb2JqcyA9IHRoaXMub2JqcztcbiAgICBsZXQgZm5JZDtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBpZiAoc3RlcHBlciAhPT0gdW5kZWZpbmVkICYmIGkgPT09IHN0ZXBwZXIubmV4dEJyZWFrUG9pbnQpIHtcbiAgICAgICAgc3RlcHBlci5icmVha0l0KGksIGNvbnRpbnVlQ2FsbGJhY2spO1xuICAgICAgICByZXR1cm4gaTtcbiAgICAgIH1cblxuICAgICAgZm5JZCA9IGZuQXJyYXlbaV07XG5cbiAgICAgIGlmIChmbklkICE9PSBfdXRpbC5PUFMuZGVwZW5kZW5jeSkge1xuICAgICAgICB0aGlzW2ZuSWRdLmFwcGx5KHRoaXMsIGFyZ3NBcnJheVtpXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGNvbnN0IGRlcE9iaklkIG9mIGFyZ3NBcnJheVtpXSkge1xuICAgICAgICAgIGNvbnN0IG9ianNQb29sID0gZGVwT2JqSWQuc3RhcnRzV2l0aChcImdfXCIpID8gY29tbW9uT2JqcyA6IG9ianM7XG5cbiAgICAgICAgICBpZiAoIW9ianNQb29sLmhhcyhkZXBPYmpJZCkpIHtcbiAgICAgICAgICAgIG9ianNQb29sLmdldChkZXBPYmpJZCwgY29udGludWVDYWxsYmFjayk7XG4gICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaSsrO1xuXG4gICAgICBpZiAoaSA9PT0gYXJnc0FycmF5TGVuKSB7XG4gICAgICAgIHJldHVybiBpO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2h1bmtPcGVyYXRpb25zICYmICsrc3RlcHMgPiBFWEVDVVRJT05fU1RFUFMpIHtcbiAgICAgICAgaWYgKERhdGUubm93KCkgPiBlbmRUaW1lKSB7XG4gICAgICAgICAgY29udGludWVDYWxsYmFjaygpO1xuICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICB9XG5cbiAgICAgICAgc3RlcHMgPSAwO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGVuZERyYXdpbmcoKSB7XG4gICAgd2hpbGUgKHRoaXMuc3RhdGVTdGFjay5sZW5ndGggfHwgdGhpcy5pblNNYXNrTW9kZSkge1xuICAgICAgdGhpcy5yZXN0b3JlKCk7XG4gICAgfVxuXG4gICAgdGhpcy5jdHgucmVzdG9yZSgpO1xuXG4gICAgaWYgKHRoaXMudHJhbnNwYXJlbnRDYW52YXMpIHtcbiAgICAgIHRoaXMuY3R4ID0gdGhpcy5jb21wb3NpdGVDdHg7XG4gICAgICB0aGlzLmN0eC5zYXZlKCk7XG4gICAgICB0aGlzLmN0eC5zZXRUcmFuc2Zvcm0oMSwgMCwgMCwgMSwgMCwgMCk7XG4gICAgICB0aGlzLmN0eC5kcmF3SW1hZ2UodGhpcy50cmFuc3BhcmVudENhbnZhcywgMCwgMCk7XG4gICAgICB0aGlzLmN0eC5yZXN0b3JlKCk7XG4gICAgICB0aGlzLnRyYW5zcGFyZW50Q2FudmFzID0gbnVsbDtcbiAgICB9XG5cbiAgICB0aGlzLmNhY2hlZENhbnZhc2VzLmNsZWFyKCk7XG4gICAgdGhpcy5jYWNoZWRQYXR0ZXJucy5jbGVhcigpO1xuXG4gICAgZm9yIChjb25zdCBjYWNoZSBvZiB0aGlzLl9jYWNoZWRCaXRtYXBzTWFwLnZhbHVlcygpKSB7XG4gICAgICBmb3IgKGNvbnN0IGNhbnZhcyBvZiBjYWNoZS52YWx1ZXMoKSkge1xuICAgICAgICBpZiAodHlwZW9mIEhUTUxDYW52YXNFbGVtZW50ICE9PSBcInVuZGVmaW5lZFwiICYmIGNhbnZhcyBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50KSB7XG4gICAgICAgICAgY2FudmFzLndpZHRoID0gY2FudmFzLmhlaWdodCA9IDA7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY2FjaGUuY2xlYXIoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9jYWNoZWRCaXRtYXBzTWFwLmNsZWFyKCk7XG5cbiAgICBpZiAodGhpcy5pbWFnZUxheWVyKSB7XG4gICAgICB0aGlzLmltYWdlTGF5ZXIuZW5kTGF5b3V0KCk7XG4gICAgfVxuICB9XG5cbiAgX3NjYWxlSW1hZ2UoaW1nLCBpbnZlcnNlVHJhbnNmb3JtKSB7XG4gICAgY29uc3Qgd2lkdGggPSBpbWcud2lkdGg7XG4gICAgY29uc3QgaGVpZ2h0ID0gaW1nLmhlaWdodDtcbiAgICBsZXQgd2lkdGhTY2FsZSA9IE1hdGgubWF4KE1hdGguaHlwb3QoaW52ZXJzZVRyYW5zZm9ybVswXSwgaW52ZXJzZVRyYW5zZm9ybVsxXSksIDEpO1xuICAgIGxldCBoZWlnaHRTY2FsZSA9IE1hdGgubWF4KE1hdGguaHlwb3QoaW52ZXJzZVRyYW5zZm9ybVsyXSwgaW52ZXJzZVRyYW5zZm9ybVszXSksIDEpO1xuICAgIGxldCBwYWludFdpZHRoID0gd2lkdGgsXG4gICAgICAgIHBhaW50SGVpZ2h0ID0gaGVpZ2h0O1xuICAgIGxldCB0bXBDYW52YXNJZCA9IFwicHJlc2NhbGUxXCI7XG4gICAgbGV0IHRtcENhbnZhcywgdG1wQ3R4O1xuXG4gICAgd2hpbGUgKHdpZHRoU2NhbGUgPiAyICYmIHBhaW50V2lkdGggPiAxIHx8IGhlaWdodFNjYWxlID4gMiAmJiBwYWludEhlaWdodCA+IDEpIHtcbiAgICAgIGxldCBuZXdXaWR0aCA9IHBhaW50V2lkdGgsXG4gICAgICAgICAgbmV3SGVpZ2h0ID0gcGFpbnRIZWlnaHQ7XG5cbiAgICAgIGlmICh3aWR0aFNjYWxlID4gMiAmJiBwYWludFdpZHRoID4gMSkge1xuICAgICAgICBuZXdXaWR0aCA9IE1hdGguY2VpbChwYWludFdpZHRoIC8gMik7XG4gICAgICAgIHdpZHRoU2NhbGUgLz0gcGFpbnRXaWR0aCAvIG5ld1dpZHRoO1xuICAgICAgfVxuXG4gICAgICBpZiAoaGVpZ2h0U2NhbGUgPiAyICYmIHBhaW50SGVpZ2h0ID4gMSkge1xuICAgICAgICBuZXdIZWlnaHQgPSBNYXRoLmNlaWwocGFpbnRIZWlnaHQgLyAyKTtcbiAgICAgICAgaGVpZ2h0U2NhbGUgLz0gcGFpbnRIZWlnaHQgLyBuZXdIZWlnaHQ7XG4gICAgICB9XG5cbiAgICAgIHRtcENhbnZhcyA9IHRoaXMuY2FjaGVkQ2FudmFzZXMuZ2V0Q2FudmFzKHRtcENhbnZhc0lkLCBuZXdXaWR0aCwgbmV3SGVpZ2h0LCBmYWxzZSk7XG4gICAgICB0bXBDdHggPSB0bXBDYW52YXMuY29udGV4dDtcbiAgICAgIHRtcEN0eC5jbGVhclJlY3QoMCwgMCwgbmV3V2lkdGgsIG5ld0hlaWdodCk7XG4gICAgICB0bXBDdHguZHJhd0ltYWdlKGltZywgMCwgMCwgcGFpbnRXaWR0aCwgcGFpbnRIZWlnaHQsIDAsIDAsIG5ld1dpZHRoLCBuZXdIZWlnaHQpO1xuICAgICAgaW1nID0gdG1wQ2FudmFzLmNhbnZhcztcbiAgICAgIHBhaW50V2lkdGggPSBuZXdXaWR0aDtcbiAgICAgIHBhaW50SGVpZ2h0ID0gbmV3SGVpZ2h0O1xuICAgICAgdG1wQ2FudmFzSWQgPSB0bXBDYW52YXNJZCA9PT0gXCJwcmVzY2FsZTFcIiA/IFwicHJlc2NhbGUyXCIgOiBcInByZXNjYWxlMVwiO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBpbWcsXG4gICAgICBwYWludFdpZHRoLFxuICAgICAgcGFpbnRIZWlnaHRcbiAgICB9O1xuICB9XG5cbiAgX2NyZWF0ZU1hc2tDYW52YXMoaW1nKSB7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY29uc3Qge1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHRcbiAgICB9ID0gaW1nO1xuICAgIGNvbnN0IGZpbGxDb2xvciA9IHRoaXMuY3VycmVudC5maWxsQ29sb3I7XG4gICAgY29uc3QgaXNQYXR0ZXJuRmlsbCA9IHRoaXMuY3VycmVudC5wYXR0ZXJuRmlsbDtcbiAgICBjb25zdCBjdXJyZW50VHJhbnNmb3JtID0gY3R4Lm1vekN1cnJlbnRUcmFuc2Zvcm07XG4gICAgbGV0IGNhY2hlLCBjYWNoZUtleSwgc2NhbGVkLCBtYXNrQ2FudmFzO1xuXG4gICAgaWYgKChpbWcuYml0bWFwIHx8IGltZy5kYXRhKSAmJiBpbWcuY291bnQgPiAxKSB7XG4gICAgICBjb25zdCBtYWluS2V5ID0gaW1nLmJpdG1hcCB8fCBpbWcuZGF0YS5idWZmZXI7XG4gICAgICBjb25zdCB3aXRob3V0VHJhbnNsYXRpb24gPSBjdXJyZW50VHJhbnNmb3JtLnNsaWNlKDAsIDQpO1xuICAgICAgY2FjaGVLZXkgPSBKU09OLnN0cmluZ2lmeShpc1BhdHRlcm5GaWxsID8gd2l0aG91dFRyYW5zbGF0aW9uIDogW3dpdGhvdXRUcmFuc2xhdGlvbiwgZmlsbENvbG9yXSk7XG4gICAgICBjYWNoZSA9IHRoaXMuX2NhY2hlZEJpdG1hcHNNYXAuZ2V0KG1haW5LZXkpO1xuXG4gICAgICBpZiAoIWNhY2hlKSB7XG4gICAgICAgIGNhY2hlID0gbmV3IE1hcCgpO1xuXG4gICAgICAgIHRoaXMuX2NhY2hlZEJpdG1hcHNNYXAuc2V0KG1haW5LZXksIGNhY2hlKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2FjaGVkSW1hZ2UgPSBjYWNoZS5nZXQoY2FjaGVLZXkpO1xuXG4gICAgICBpZiAoY2FjaGVkSW1hZ2UgJiYgIWlzUGF0dGVybkZpbGwpIHtcbiAgICAgICAgY29uc3Qgb2Zmc2V0WCA9IE1hdGgucm91bmQoTWF0aC5taW4oY3VycmVudFRyYW5zZm9ybVswXSwgY3VycmVudFRyYW5zZm9ybVsyXSkgKyBjdXJyZW50VHJhbnNmb3JtWzRdKTtcbiAgICAgICAgY29uc3Qgb2Zmc2V0WSA9IE1hdGgucm91bmQoTWF0aC5taW4oY3VycmVudFRyYW5zZm9ybVsxXSwgY3VycmVudFRyYW5zZm9ybVszXSkgKyBjdXJyZW50VHJhbnNmb3JtWzVdKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjYW52YXM6IGNhY2hlZEltYWdlLFxuICAgICAgICAgIG9mZnNldFgsXG4gICAgICAgICAgb2Zmc2V0WVxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBzY2FsZWQgPSBjYWNoZWRJbWFnZTtcbiAgICB9XG5cbiAgICBpZiAoIXNjYWxlZCkge1xuICAgICAgbWFza0NhbnZhcyA9IHRoaXMuY2FjaGVkQ2FudmFzZXMuZ2V0Q2FudmFzKFwibWFza0NhbnZhc1wiLCB3aWR0aCwgaGVpZ2h0LCBmYWxzZSk7XG4gICAgICBwdXRCaW5hcnlJbWFnZU1hc2sobWFza0NhbnZhcy5jb250ZXh0LCBpbWcpO1xuICAgIH1cblxuICAgIGxldCBtYXNrVG9DYW52YXMgPSBfdXRpbC5VdGlsLnRyYW5zZm9ybShjdXJyZW50VHJhbnNmb3JtLCBbMSAvIHdpZHRoLCAwLCAwLCAtMSAvIGhlaWdodCwgMCwgMF0pO1xuXG4gICAgbWFza1RvQ2FudmFzID0gX3V0aWwuVXRpbC50cmFuc2Zvcm0obWFza1RvQ2FudmFzLCBbMSwgMCwgMCwgMSwgMCwgLWhlaWdodF0pO1xuXG4gICAgY29uc3QgY29yZDEgPSBfdXRpbC5VdGlsLmFwcGx5VHJhbnNmb3JtKFswLCAwXSwgbWFza1RvQ2FudmFzKTtcblxuICAgIGNvbnN0IGNvcmQyID0gX3V0aWwuVXRpbC5hcHBseVRyYW5zZm9ybShbd2lkdGgsIGhlaWdodF0sIG1hc2tUb0NhbnZhcyk7XG5cbiAgICBjb25zdCByZWN0ID0gX3V0aWwuVXRpbC5ub3JtYWxpemVSZWN0KFtjb3JkMVswXSwgY29yZDFbMV0sIGNvcmQyWzBdLCBjb3JkMlsxXV0pO1xuXG4gICAgY29uc3QgZHJhd25XaWR0aCA9IE1hdGgucm91bmQocmVjdFsyXSAtIHJlY3RbMF0pIHx8IDE7XG4gICAgY29uc3QgZHJhd25IZWlnaHQgPSBNYXRoLnJvdW5kKHJlY3RbM10gLSByZWN0WzFdKSB8fCAxO1xuICAgIGNvbnN0IGZpbGxDYW52YXMgPSB0aGlzLmNhY2hlZENhbnZhc2VzLmdldENhbnZhcyhcImZpbGxDYW52YXNcIiwgZHJhd25XaWR0aCwgZHJhd25IZWlnaHQsIHRydWUpO1xuICAgIGNvbnN0IGZpbGxDdHggPSBmaWxsQ2FudmFzLmNvbnRleHQ7XG4gICAgY29uc3Qgb2Zmc2V0WCA9IE1hdGgubWluKGNvcmQxWzBdLCBjb3JkMlswXSk7XG4gICAgY29uc3Qgb2Zmc2V0WSA9IE1hdGgubWluKGNvcmQxWzFdLCBjb3JkMlsxXSk7XG4gICAgZmlsbEN0eC50cmFuc2xhdGUoLW9mZnNldFgsIC1vZmZzZXRZKTtcbiAgICBmaWxsQ3R4LnRyYW5zZm9ybS5hcHBseShmaWxsQ3R4LCBtYXNrVG9DYW52YXMpO1xuXG4gICAgaWYgKCFzY2FsZWQpIHtcbiAgICAgIHNjYWxlZCA9IHRoaXMuX3NjYWxlSW1hZ2UobWFza0NhbnZhcy5jYW52YXMsIGZpbGxDdHgubW96Q3VycmVudFRyYW5zZm9ybUludmVyc2UpO1xuICAgICAgc2NhbGVkID0gc2NhbGVkLmltZztcblxuICAgICAgaWYgKGNhY2hlICYmIGlzUGF0dGVybkZpbGwpIHtcbiAgICAgICAgY2FjaGUuc2V0KGNhY2hlS2V5LCBzY2FsZWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZpbGxDdHguaW1hZ2VTbW9vdGhpbmdFbmFibGVkID0gZ2V0SW1hZ2VTbW9vdGhpbmdFbmFibGVkKGZpbGxDdHgubW96Q3VycmVudFRyYW5zZm9ybSwgaW1nLmludGVycG9sYXRlKTtcbiAgICBkcmF3SW1hZ2VBdEludGVnZXJDb29yZHMoZmlsbEN0eCwgc2NhbGVkLCAwLCAwLCBzY2FsZWQud2lkdGgsIHNjYWxlZC5oZWlnaHQsIDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xuICAgIGZpbGxDdHguZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uID0gXCJzb3VyY2UtaW5cIjtcblxuICAgIGNvbnN0IGludmVyc2UgPSBfdXRpbC5VdGlsLnRyYW5zZm9ybShmaWxsQ3R4Lm1vekN1cnJlbnRUcmFuc2Zvcm1JbnZlcnNlLCBbMSwgMCwgMCwgMSwgLW9mZnNldFgsIC1vZmZzZXRZXSk7XG5cbiAgICBmaWxsQ3R4LmZpbGxTdHlsZSA9IGlzUGF0dGVybkZpbGwgPyBmaWxsQ29sb3IuZ2V0UGF0dGVybihjdHgsIHRoaXMsIGludmVyc2UsIF9wYXR0ZXJuX2hlbHBlci5QYXRoVHlwZS5GSUxMKSA6IGZpbGxDb2xvcjtcbiAgICBmaWxsQ3R4LmZpbGxSZWN0KDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgaWYgKGNhY2hlICYmICFpc1BhdHRlcm5GaWxsKSB7XG4gICAgICB0aGlzLmNhY2hlZENhbnZhc2VzLmRlbGV0ZShcImZpbGxDYW52YXNcIik7XG4gICAgICBjYWNoZS5zZXQoY2FjaGVLZXksIGZpbGxDYW52YXMuY2FudmFzKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgY2FudmFzOiBmaWxsQ2FudmFzLmNhbnZhcyxcbiAgICAgIG9mZnNldFg6IE1hdGgucm91bmQob2Zmc2V0WCksXG4gICAgICBvZmZzZXRZOiBNYXRoLnJvdW5kKG9mZnNldFkpXG4gICAgfTtcbiAgfVxuXG4gIHNldExpbmVXaWR0aCh3aWR0aCkge1xuICAgIGlmICh3aWR0aCAhPT0gdGhpcy5jdXJyZW50LmxpbmVXaWR0aCkge1xuICAgICAgdGhpcy5fY2FjaGVkU2NhbGVGb3JTdHJva2luZyA9IG51bGw7XG4gICAgfVxuXG4gICAgdGhpcy5jdXJyZW50LmxpbmVXaWR0aCA9IHdpZHRoO1xuICAgIHRoaXMuY3R4LmxpbmVXaWR0aCA9IHdpZHRoO1xuICB9XG5cbiAgc2V0TGluZUNhcChzdHlsZSkge1xuICAgIHRoaXMuY3R4LmxpbmVDYXAgPSBMSU5FX0NBUF9TVFlMRVNbc3R5bGVdO1xuICB9XG5cbiAgc2V0TGluZUpvaW4oc3R5bGUpIHtcbiAgICB0aGlzLmN0eC5saW5lSm9pbiA9IExJTkVfSk9JTl9TVFlMRVNbc3R5bGVdO1xuICB9XG5cbiAgc2V0TWl0ZXJMaW1pdChsaW1pdCkge1xuICAgIHRoaXMuY3R4Lm1pdGVyTGltaXQgPSBsaW1pdDtcbiAgfVxuXG4gIHNldERhc2goZGFzaEFycmF5LCBkYXNoUGhhc2UpIHtcbiAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcblxuICAgIGlmIChjdHguc2V0TGluZURhc2ggIT09IHVuZGVmaW5lZCkge1xuICAgICAgY3R4LnNldExpbmVEYXNoKGRhc2hBcnJheSk7XG4gICAgICBjdHgubGluZURhc2hPZmZzZXQgPSBkYXNoUGhhc2U7XG4gICAgfVxuICB9XG5cbiAgc2V0UmVuZGVyaW5nSW50ZW50KGludGVudCkge31cblxuICBzZXRGbGF0bmVzcyhmbGF0bmVzcykge31cblxuICBzZXRHU3RhdGUoc3RhdGVzKSB7XG4gICAgZm9yIChsZXQgaSA9IDAsIGlpID0gc3RhdGVzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgIGNvbnN0IHN0YXRlID0gc3RhdGVzW2ldO1xuICAgICAgY29uc3Qga2V5ID0gc3RhdGVbMF07XG4gICAgICBjb25zdCB2YWx1ZSA9IHN0YXRlWzFdO1xuXG4gICAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgICBjYXNlIFwiTFdcIjpcbiAgICAgICAgICB0aGlzLnNldExpbmVXaWR0aCh2YWx1ZSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBcIkxDXCI6XG4gICAgICAgICAgdGhpcy5zZXRMaW5lQ2FwKHZhbHVlKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFwiTEpcIjpcbiAgICAgICAgICB0aGlzLnNldExpbmVKb2luKHZhbHVlKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFwiTUxcIjpcbiAgICAgICAgICB0aGlzLnNldE1pdGVyTGltaXQodmFsdWUpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgXCJEXCI6XG4gICAgICAgICAgdGhpcy5zZXREYXNoKHZhbHVlWzBdLCB2YWx1ZVsxXSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBcIlJJXCI6XG4gICAgICAgICAgdGhpcy5zZXRSZW5kZXJpbmdJbnRlbnQodmFsdWUpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgXCJGTFwiOlxuICAgICAgICAgIHRoaXMuc2V0RmxhdG5lc3ModmFsdWUpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgXCJGb250XCI6XG4gICAgICAgICAgdGhpcy5zZXRGb250KHZhbHVlWzBdLCB2YWx1ZVsxXSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBcIkNBXCI6XG4gICAgICAgICAgdGhpcy5jdXJyZW50LnN0cm9rZUFscGhhID0gc3RhdGVbMV07XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBcImNhXCI6XG4gICAgICAgICAgdGhpcy5jdXJyZW50LmZpbGxBbHBoYSA9IHN0YXRlWzFdO1xuICAgICAgICAgIHRoaXMuY3R4Lmdsb2JhbEFscGhhID0gc3RhdGVbMV07XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBcIkJNXCI6XG4gICAgICAgICAgdGhpcy5jdHguZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBcIlNNYXNrXCI6XG4gICAgICAgICAgdGhpcy5jdXJyZW50LmFjdGl2ZVNNYXNrID0gdmFsdWUgPyB0aGlzLnRlbXBTTWFzayA6IG51bGw7XG4gICAgICAgICAgdGhpcy50ZW1wU01hc2sgPSBudWxsO1xuICAgICAgICAgIHRoaXMuY2hlY2tTTWFza1N0YXRlKCk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBcIlRSXCI6XG4gICAgICAgICAgdGhpcy5jdXJyZW50LnRyYW5zZmVyTWFwcyA9IHZhbHVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGdldCBpblNNYXNrTW9kZSgpIHtcbiAgICByZXR1cm4gISF0aGlzLnN1c3BlbmRlZEN0eDtcbiAgfVxuXG4gIGNoZWNrU01hc2tTdGF0ZSgpIHtcbiAgICBjb25zdCBpblNNYXNrTW9kZSA9IHRoaXMuaW5TTWFza01vZGU7XG5cbiAgICBpZiAodGhpcy5jdXJyZW50LmFjdGl2ZVNNYXNrICYmICFpblNNYXNrTW9kZSkge1xuICAgICAgdGhpcy5iZWdpblNNYXNrTW9kZSgpO1xuICAgIH0gZWxzZSBpZiAoIXRoaXMuY3VycmVudC5hY3RpdmVTTWFzayAmJiBpblNNYXNrTW9kZSkge1xuICAgICAgdGhpcy5lbmRTTWFza01vZGUoKTtcbiAgICB9XG4gIH1cblxuICBiZWdpblNNYXNrTW9kZSgpIHtcbiAgICBpZiAodGhpcy5pblNNYXNrTW9kZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiYmVnaW5TTWFza01vZGUgY2FsbGVkIHdoaWxlIGFscmVhZHkgaW4gc21hc2sgbW9kZVwiKTtcbiAgICB9XG5cbiAgICBjb25zdCBkcmF3bldpZHRoID0gdGhpcy5jdHguY2FudmFzLndpZHRoO1xuICAgIGNvbnN0IGRyYXduSGVpZ2h0ID0gdGhpcy5jdHguY2FudmFzLmhlaWdodDtcbiAgICBjb25zdCBjYWNoZUlkID0gXCJzbWFza0dyb3VwQXRcIiArIHRoaXMuZ3JvdXBMZXZlbDtcbiAgICBjb25zdCBzY3JhdGNoQ2FudmFzID0gdGhpcy5jYWNoZWRDYW52YXNlcy5nZXRDYW52YXMoY2FjaGVJZCwgZHJhd25XaWR0aCwgZHJhd25IZWlnaHQsIHRydWUpO1xuICAgIHRoaXMuc3VzcGVuZGVkQ3R4ID0gdGhpcy5jdHg7XG4gICAgdGhpcy5jdHggPSBzY3JhdGNoQ2FudmFzLmNvbnRleHQ7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY3R4LnNldFRyYW5zZm9ybS5hcHBseShjdHgsIHRoaXMuc3VzcGVuZGVkQ3R4Lm1vekN1cnJlbnRUcmFuc2Zvcm0pO1xuICAgIGNvcHlDdHhTdGF0ZSh0aGlzLnN1c3BlbmRlZEN0eCwgY3R4KTtcbiAgICBtaXJyb3JDb250ZXh0T3BlcmF0aW9ucyhjdHgsIHRoaXMuc3VzcGVuZGVkQ3R4KTtcbiAgICB0aGlzLnNldEdTdGF0ZShbW1wiQk1cIiwgXCJzb3VyY2Utb3ZlclwiXSwgW1wiY2FcIiwgMV0sIFtcIkNBXCIsIDFdXSk7XG4gIH1cblxuICBlbmRTTWFza01vZGUoKSB7XG4gICAgaWYgKCF0aGlzLmluU01hc2tNb2RlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJlbmRTTWFza01vZGUgY2FsbGVkIHdoaWxlIG5vdCBpbiBzbWFzayBtb2RlXCIpO1xuICAgIH1cblxuICAgIHRoaXMuY3R4Ll9yZW1vdmVNaXJyb3JpbmcoKTtcblxuICAgIGNvcHlDdHhTdGF0ZSh0aGlzLmN0eCwgdGhpcy5zdXNwZW5kZWRDdHgpO1xuICAgIHRoaXMuY3R4ID0gdGhpcy5zdXNwZW5kZWRDdHg7XG4gICAgdGhpcy5zdXNwZW5kZWRDdHggPSBudWxsO1xuICB9XG5cbiAgY29tcG9zZShkaXJ0eUJveCkge1xuICAgIGlmICghdGhpcy5jdXJyZW50LmFjdGl2ZVNNYXNrKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFkaXJ0eUJveCkge1xuICAgICAgZGlydHlCb3ggPSBbMCwgMCwgdGhpcy5jdHguY2FudmFzLndpZHRoLCB0aGlzLmN0eC5jYW52YXMuaGVpZ2h0XTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGlydHlCb3hbMF0gPSBNYXRoLmZsb29yKGRpcnR5Qm94WzBdKTtcbiAgICAgIGRpcnR5Qm94WzFdID0gTWF0aC5mbG9vcihkaXJ0eUJveFsxXSk7XG4gICAgICBkaXJ0eUJveFsyXSA9IE1hdGguY2VpbChkaXJ0eUJveFsyXSk7XG4gICAgICBkaXJ0eUJveFszXSA9IE1hdGguY2VpbChkaXJ0eUJveFszXSk7XG4gICAgfVxuXG4gICAgY29uc3Qgc21hc2sgPSB0aGlzLmN1cnJlbnQuYWN0aXZlU01hc2s7XG4gICAgY29uc3Qgc3VzcGVuZGVkQ3R4ID0gdGhpcy5zdXNwZW5kZWRDdHg7XG4gICAgY29tcG9zZVNNYXNrKHN1c3BlbmRlZEN0eCwgc21hc2ssIHRoaXMuY3R4LCBkaXJ0eUJveCk7XG4gICAgdGhpcy5jdHguc2F2ZSgpO1xuICAgIHRoaXMuY3R4LnNldFRyYW5zZm9ybSgxLCAwLCAwLCAxLCAwLCAwKTtcbiAgICB0aGlzLmN0eC5jbGVhclJlY3QoMCwgMCwgdGhpcy5jdHguY2FudmFzLndpZHRoLCB0aGlzLmN0eC5jYW52YXMuaGVpZ2h0KTtcbiAgICB0aGlzLmN0eC5yZXN0b3JlKCk7XG4gIH1cblxuICBzYXZlKCkge1xuICAgIGlmICh0aGlzLmluU01hc2tNb2RlKSB7XG4gICAgICBjb3B5Q3R4U3RhdGUodGhpcy5jdHgsIHRoaXMuc3VzcGVuZGVkQ3R4KTtcbiAgICAgIHRoaXMuc3VzcGVuZGVkQ3R4LnNhdmUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jdHguc2F2ZSgpO1xuICAgIH1cblxuICAgIGNvbnN0IG9sZCA9IHRoaXMuY3VycmVudDtcbiAgICB0aGlzLnN0YXRlU3RhY2sucHVzaChvbGQpO1xuICAgIHRoaXMuY3VycmVudCA9IG9sZC5jbG9uZSgpO1xuICB9XG5cbiAgcmVzdG9yZSgpIHtcbiAgICBpZiAodGhpcy5zdGF0ZVN0YWNrLmxlbmd0aCA9PT0gMCAmJiB0aGlzLmluU01hc2tNb2RlKSB7XG4gICAgICB0aGlzLmVuZFNNYXNrTW9kZSgpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnN0YXRlU3RhY2subGVuZ3RoICE9PSAwKSB7XG4gICAgICB0aGlzLmN1cnJlbnQgPSB0aGlzLnN0YXRlU3RhY2sucG9wKCk7XG5cbiAgICAgIGlmICh0aGlzLmluU01hc2tNb2RlKSB7XG4gICAgICAgIHRoaXMuc3VzcGVuZGVkQ3R4LnJlc3RvcmUoKTtcbiAgICAgICAgY29weUN0eFN0YXRlKHRoaXMuc3VzcGVuZGVkQ3R4LCB0aGlzLmN0eCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmN0eC5yZXN0b3JlKCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuY2hlY2tTTWFza1N0YXRlKCk7XG4gICAgICB0aGlzLnBlbmRpbmdDbGlwID0gbnVsbDtcbiAgICAgIHRoaXMuX2NhY2hlZFNjYWxlRm9yU3Ryb2tpbmcgPSBudWxsO1xuICAgICAgdGhpcy5fY2FjaGVkR2V0U2luZ2xlUGl4ZWxXaWR0aCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgdHJhbnNmb3JtKGEsIGIsIGMsIGQsIGUsIGYpIHtcbiAgICB0aGlzLmN0eC50cmFuc2Zvcm0oYSwgYiwgYywgZCwgZSwgZik7XG4gICAgdGhpcy5fY2FjaGVkU2NhbGVGb3JTdHJva2luZyA9IG51bGw7XG4gICAgdGhpcy5fY2FjaGVkR2V0U2luZ2xlUGl4ZWxXaWR0aCA9IG51bGw7XG4gIH1cblxuICBjb25zdHJ1Y3RQYXRoKG9wcywgYXJncywgbWluTWF4KSB7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcbiAgICBsZXQgeCA9IGN1cnJlbnQueCxcbiAgICAgICAgeSA9IGN1cnJlbnQueTtcbiAgICBsZXQgc3RhcnRYLCBzdGFydFk7XG4gICAgY29uc3QgY3VycmVudFRyYW5zZm9ybSA9IGN0eC5tb3pDdXJyZW50VHJhbnNmb3JtO1xuICAgIGNvbnN0IGlzU2NhbGluZ01hdHJpeCA9IGN1cnJlbnRUcmFuc2Zvcm1bMF0gPT09IDAgJiYgY3VycmVudFRyYW5zZm9ybVszXSA9PT0gMCB8fCBjdXJyZW50VHJhbnNmb3JtWzFdID09PSAwICYmIGN1cnJlbnRUcmFuc2Zvcm1bMl0gPT09IDA7XG4gICAgY29uc3QgbWluTWF4Rm9yQmV6aWVyID0gaXNTY2FsaW5nTWF0cml4ID8gbWluTWF4LnNsaWNlKDApIDogbnVsbDtcblxuICAgIGZvciAobGV0IGkgPSAwLCBqID0gMCwgaWkgPSBvcHMubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgc3dpdGNoIChvcHNbaV0gfCAwKSB7XG4gICAgICAgIGNhc2UgX3V0aWwuT1BTLnJlY3RhbmdsZTpcbiAgICAgICAgICB4ID0gYXJnc1tqKytdO1xuICAgICAgICAgIHkgPSBhcmdzW2orK107XG4gICAgICAgICAgY29uc3Qgd2lkdGggPSBhcmdzW2orK107XG4gICAgICAgICAgY29uc3QgaGVpZ2h0ID0gYXJnc1tqKytdO1xuICAgICAgICAgIGNvbnN0IHh3ID0geCArIHdpZHRoO1xuICAgICAgICAgIGNvbnN0IHloID0geSArIGhlaWdodDtcbiAgICAgICAgICBjdHgubW92ZVRvKHgsIHkpO1xuXG4gICAgICAgICAgaWYgKHdpZHRoID09PSAwIHx8IGhlaWdodCA9PT0gMCkge1xuICAgICAgICAgICAgY3R4LmxpbmVUbyh4dywgeWgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjdHgubGluZVRvKHh3LCB5KTtcbiAgICAgICAgICAgIGN0eC5saW5lVG8oeHcsIHloKTtcbiAgICAgICAgICAgIGN0eC5saW5lVG8oeCwgeWgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghaXNTY2FsaW5nTWF0cml4KSB7XG4gICAgICAgICAgICBjdXJyZW50LnVwZGF0ZVJlY3RNaW5NYXgoY3VycmVudFRyYW5zZm9ybSwgW3gsIHksIHh3LCB5aF0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGN0eC5jbG9zZVBhdGgoKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIF91dGlsLk9QUy5tb3ZlVG86XG4gICAgICAgICAgeCA9IGFyZ3NbaisrXTtcbiAgICAgICAgICB5ID0gYXJnc1tqKytdO1xuICAgICAgICAgIGN0eC5tb3ZlVG8oeCwgeSk7XG5cbiAgICAgICAgICBpZiAoIWlzU2NhbGluZ01hdHJpeCkge1xuICAgICAgICAgICAgY3VycmVudC51cGRhdGVQYXRoTWluTWF4KGN1cnJlbnRUcmFuc2Zvcm0sIHgsIHkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgX3V0aWwuT1BTLmxpbmVUbzpcbiAgICAgICAgICB4ID0gYXJnc1tqKytdO1xuICAgICAgICAgIHkgPSBhcmdzW2orK107XG4gICAgICAgICAgY3R4LmxpbmVUbyh4LCB5KTtcblxuICAgICAgICAgIGlmICghaXNTY2FsaW5nTWF0cml4KSB7XG4gICAgICAgICAgICBjdXJyZW50LnVwZGF0ZVBhdGhNaW5NYXgoY3VycmVudFRyYW5zZm9ybSwgeCwgeSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBfdXRpbC5PUFMuY3VydmVUbzpcbiAgICAgICAgICBzdGFydFggPSB4O1xuICAgICAgICAgIHN0YXJ0WSA9IHk7XG4gICAgICAgICAgeCA9IGFyZ3NbaiArIDRdO1xuICAgICAgICAgIHkgPSBhcmdzW2ogKyA1XTtcbiAgICAgICAgICBjdHguYmV6aWVyQ3VydmVUbyhhcmdzW2pdLCBhcmdzW2ogKyAxXSwgYXJnc1tqICsgMl0sIGFyZ3NbaiArIDNdLCB4LCB5KTtcbiAgICAgICAgICBjdXJyZW50LnVwZGF0ZUN1cnZlUGF0aE1pbk1heChjdXJyZW50VHJhbnNmb3JtLCBzdGFydFgsIHN0YXJ0WSwgYXJnc1tqXSwgYXJnc1tqICsgMV0sIGFyZ3NbaiArIDJdLCBhcmdzW2ogKyAzXSwgeCwgeSwgbWluTWF4Rm9yQmV6aWVyKTtcbiAgICAgICAgICBqICs9IDY7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBfdXRpbC5PUFMuY3VydmVUbzI6XG4gICAgICAgICAgc3RhcnRYID0geDtcbiAgICAgICAgICBzdGFydFkgPSB5O1xuICAgICAgICAgIGN0eC5iZXppZXJDdXJ2ZVRvKHgsIHksIGFyZ3Nbal0sIGFyZ3NbaiArIDFdLCBhcmdzW2ogKyAyXSwgYXJnc1tqICsgM10pO1xuICAgICAgICAgIGN1cnJlbnQudXBkYXRlQ3VydmVQYXRoTWluTWF4KGN1cnJlbnRUcmFuc2Zvcm0sIHN0YXJ0WCwgc3RhcnRZLCB4LCB5LCBhcmdzW2pdLCBhcmdzW2ogKyAxXSwgYXJnc1tqICsgMl0sIGFyZ3NbaiArIDNdLCBtaW5NYXhGb3JCZXppZXIpO1xuICAgICAgICAgIHggPSBhcmdzW2ogKyAyXTtcbiAgICAgICAgICB5ID0gYXJnc1tqICsgM107XG4gICAgICAgICAgaiArPSA0O1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgX3V0aWwuT1BTLmN1cnZlVG8zOlxuICAgICAgICAgIHN0YXJ0WCA9IHg7XG4gICAgICAgICAgc3RhcnRZID0geTtcbiAgICAgICAgICB4ID0gYXJnc1tqICsgMl07XG4gICAgICAgICAgeSA9IGFyZ3NbaiArIDNdO1xuICAgICAgICAgIGN0eC5iZXppZXJDdXJ2ZVRvKGFyZ3Nbal0sIGFyZ3NbaiArIDFdLCB4LCB5LCB4LCB5KTtcbiAgICAgICAgICBjdXJyZW50LnVwZGF0ZUN1cnZlUGF0aE1pbk1heChjdXJyZW50VHJhbnNmb3JtLCBzdGFydFgsIHN0YXJ0WSwgYXJnc1tqXSwgYXJnc1tqICsgMV0sIHgsIHksIHgsIHksIG1pbk1heEZvckJlemllcik7XG4gICAgICAgICAgaiArPSA0O1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgX3V0aWwuT1BTLmNsb3NlUGF0aDpcbiAgICAgICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlzU2NhbGluZ01hdHJpeCkge1xuICAgICAgY3VycmVudC51cGRhdGVTY2FsaW5nUGF0aE1pbk1heChjdXJyZW50VHJhbnNmb3JtLCBtaW5NYXhGb3JCZXppZXIpO1xuICAgIH1cblxuICAgIGN1cnJlbnQuc2V0Q3VycmVudFBvaW50KHgsIHkpO1xuICB9XG5cbiAgY2xvc2VQYXRoKCkge1xuICAgIHRoaXMuY3R4LmNsb3NlUGF0aCgpO1xuICB9XG5cbiAgc3Ryb2tlKGNvbnN1bWVQYXRoKSB7XG4gICAgY29uc3VtZVBhdGggPSB0eXBlb2YgY29uc3VtZVBhdGggIT09IFwidW5kZWZpbmVkXCIgPyBjb25zdW1lUGF0aCA6IHRydWU7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY29uc3Qgc3Ryb2tlQ29sb3IgPSB0aGlzLmN1cnJlbnQuc3Ryb2tlQ29sb3I7XG4gICAgY3R4Lmdsb2JhbEFscGhhID0gdGhpcy5jdXJyZW50LnN0cm9rZUFscGhhO1xuXG4gICAgaWYgKHRoaXMuY29udGVudFZpc2libGUpIHtcbiAgICAgIGlmICh0eXBlb2Ygc3Ryb2tlQ29sb3IgPT09IFwib2JqZWN0XCIgJiYgc3Ryb2tlQ29sb3I/LmdldFBhdHRlcm4pIHtcbiAgICAgICAgY3R4LnNhdmUoKTtcbiAgICAgICAgY3R4LnN0cm9rZVN0eWxlID0gc3Ryb2tlQ29sb3IuZ2V0UGF0dGVybihjdHgsIHRoaXMsIGN0eC5tb3pDdXJyZW50VHJhbnNmb3JtSW52ZXJzZSwgX3BhdHRlcm5faGVscGVyLlBhdGhUeXBlLlNUUk9LRSk7XG4gICAgICAgIHRoaXMucmVzY2FsZUFuZFN0cm9rZShmYWxzZSk7XG4gICAgICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnJlc2NhbGVBbmRTdHJva2UodHJ1ZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvbnN1bWVQYXRoKSB7XG4gICAgICB0aGlzLmNvbnN1bWVQYXRoKHRoaXMuY3VycmVudC5nZXRDbGlwcGVkUGF0aEJvdW5kaW5nQm94KCkpO1xuICAgIH1cblxuICAgIGN0eC5nbG9iYWxBbHBoYSA9IHRoaXMuY3VycmVudC5maWxsQWxwaGE7XG4gIH1cblxuICBjbG9zZVN0cm9rZSgpIHtcbiAgICB0aGlzLmNsb3NlUGF0aCgpO1xuICAgIHRoaXMuc3Ryb2tlKCk7XG4gIH1cblxuICBmaWxsKGNvbnN1bWVQYXRoKSB7XG4gICAgY29uc3VtZVBhdGggPSB0eXBlb2YgY29uc3VtZVBhdGggIT09IFwidW5kZWZpbmVkXCIgPyBjb25zdW1lUGF0aCA6IHRydWU7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY29uc3QgZmlsbENvbG9yID0gdGhpcy5jdXJyZW50LmZpbGxDb2xvcjtcbiAgICBjb25zdCBpc1BhdHRlcm5GaWxsID0gdGhpcy5jdXJyZW50LnBhdHRlcm5GaWxsO1xuICAgIGxldCBuZWVkUmVzdG9yZSA9IGZhbHNlO1xuXG4gICAgaWYgKGlzUGF0dGVybkZpbGwpIHtcbiAgICAgIGN0eC5zYXZlKCk7XG4gICAgICBjdHguZmlsbFN0eWxlID0gZmlsbENvbG9yLmdldFBhdHRlcm4oY3R4LCB0aGlzLCBjdHgubW96Q3VycmVudFRyYW5zZm9ybUludmVyc2UsIF9wYXR0ZXJuX2hlbHBlci5QYXRoVHlwZS5GSUxMKTtcbiAgICAgIG5lZWRSZXN0b3JlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBjb25zdCBpbnRlcnNlY3QgPSB0aGlzLmN1cnJlbnQuZ2V0Q2xpcHBlZFBhdGhCb3VuZGluZ0JveCgpO1xuXG4gICAgaWYgKHRoaXMuY29udGVudFZpc2libGUgJiYgaW50ZXJzZWN0ICE9PSBudWxsKSB7XG4gICAgICBpZiAodGhpcy5wZW5kaW5nRU9GaWxsKSB7XG4gICAgICAgIGN0eC5maWxsKFwiZXZlbm9kZFwiKTtcbiAgICAgICAgdGhpcy5wZW5kaW5nRU9GaWxsID0gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjdHguZmlsbCgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChuZWVkUmVzdG9yZSkge1xuICAgICAgY3R4LnJlc3RvcmUoKTtcbiAgICB9XG5cbiAgICBpZiAoY29uc3VtZVBhdGgpIHtcbiAgICAgIHRoaXMuY29uc3VtZVBhdGgoaW50ZXJzZWN0KTtcbiAgICB9XG4gIH1cblxuICBlb0ZpbGwoKSB7XG4gICAgdGhpcy5wZW5kaW5nRU9GaWxsID0gdHJ1ZTtcbiAgICB0aGlzLmZpbGwoKTtcbiAgfVxuXG4gIGZpbGxTdHJva2UoKSB7XG4gICAgdGhpcy5maWxsKGZhbHNlKTtcbiAgICB0aGlzLnN0cm9rZShmYWxzZSk7XG4gICAgdGhpcy5jb25zdW1lUGF0aCgpO1xuICB9XG5cbiAgZW9GaWxsU3Ryb2tlKCkge1xuICAgIHRoaXMucGVuZGluZ0VPRmlsbCA9IHRydWU7XG4gICAgdGhpcy5maWxsU3Ryb2tlKCk7XG4gIH1cblxuICBjbG9zZUZpbGxTdHJva2UoKSB7XG4gICAgdGhpcy5jbG9zZVBhdGgoKTtcbiAgICB0aGlzLmZpbGxTdHJva2UoKTtcbiAgfVxuXG4gIGNsb3NlRU9GaWxsU3Ryb2tlKCkge1xuICAgIHRoaXMucGVuZGluZ0VPRmlsbCA9IHRydWU7XG4gICAgdGhpcy5jbG9zZVBhdGgoKTtcbiAgICB0aGlzLmZpbGxTdHJva2UoKTtcbiAgfVxuXG4gIGVuZFBhdGgoKSB7XG4gICAgdGhpcy5jb25zdW1lUGF0aCgpO1xuICB9XG5cbiAgY2xpcCgpIHtcbiAgICB0aGlzLnBlbmRpbmdDbGlwID0gTk9STUFMX0NMSVA7XG4gIH1cblxuICBlb0NsaXAoKSB7XG4gICAgdGhpcy5wZW5kaW5nQ2xpcCA9IEVPX0NMSVA7XG4gIH1cblxuICBiZWdpblRleHQoKSB7XG4gICAgdGhpcy5jdXJyZW50LnRleHRNYXRyaXggPSBfdXRpbC5JREVOVElUWV9NQVRSSVg7XG4gICAgdGhpcy5jdXJyZW50LnRleHRNYXRyaXhTY2FsZSA9IDE7XG4gICAgdGhpcy5jdXJyZW50LnggPSB0aGlzLmN1cnJlbnQubGluZVggPSAwO1xuICAgIHRoaXMuY3VycmVudC55ID0gdGhpcy5jdXJyZW50LmxpbmVZID0gMDtcbiAgfVxuXG4gIGVuZFRleHQoKSB7XG4gICAgY29uc3QgcGF0aHMgPSB0aGlzLnBlbmRpbmdUZXh0UGF0aHM7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG5cbiAgICBpZiAocGF0aHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGN0eC5zYXZlKCk7XG4gICAgY3R4LmJlZ2luUGF0aCgpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXRocy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgcGF0aCA9IHBhdGhzW2ldO1xuICAgICAgY3R4LnNldFRyYW5zZm9ybS5hcHBseShjdHgsIHBhdGgudHJhbnNmb3JtKTtcbiAgICAgIGN0eC50cmFuc2xhdGUocGF0aC54LCBwYXRoLnkpO1xuICAgICAgcGF0aC5hZGRUb1BhdGgoY3R4LCBwYXRoLmZvbnRTaXplKTtcbiAgICB9XG5cbiAgICBjdHgucmVzdG9yZSgpO1xuICAgIGN0eC5jbGlwKCk7XG4gICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgIGRlbGV0ZSB0aGlzLnBlbmRpbmdUZXh0UGF0aHM7XG4gIH1cblxuICBzZXRDaGFyU3BhY2luZyhzcGFjaW5nKSB7XG4gICAgdGhpcy5jdXJyZW50LmNoYXJTcGFjaW5nID0gc3BhY2luZztcbiAgfVxuXG4gIHNldFdvcmRTcGFjaW5nKHNwYWNpbmcpIHtcbiAgICB0aGlzLmN1cnJlbnQud29yZFNwYWNpbmcgPSBzcGFjaW5nO1xuICB9XG5cbiAgc2V0SFNjYWxlKHNjYWxlKSB7XG4gICAgdGhpcy5jdXJyZW50LnRleHRIU2NhbGUgPSBzY2FsZSAvIDEwMDtcbiAgfVxuXG4gIHNldExlYWRpbmcobGVhZGluZykge1xuICAgIHRoaXMuY3VycmVudC5sZWFkaW5nID0gLWxlYWRpbmc7XG4gIH1cblxuICBzZXRGb250KGZvbnRSZWZOYW1lLCBzaXplKSB7XG4gICAgY29uc3QgZm9udE9iaiA9IHRoaXMuY29tbW9uT2Jqcy5nZXQoZm9udFJlZk5hbWUpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmN1cnJlbnQ7XG5cbiAgICBpZiAoIWZvbnRPYmopIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2FuJ3QgZmluZCBmb250IGZvciAke2ZvbnRSZWZOYW1lfWApO1xuICAgIH1cblxuICAgIGN1cnJlbnQuZm9udE1hdHJpeCA9IGZvbnRPYmouZm9udE1hdHJpeCB8fCBfdXRpbC5GT05UX0lERU5USVRZX01BVFJJWDtcblxuICAgIGlmIChjdXJyZW50LmZvbnRNYXRyaXhbMF0gPT09IDAgfHwgY3VycmVudC5mb250TWF0cml4WzNdID09PSAwKSB7XG4gICAgICAoMCwgX3V0aWwud2FybikoXCJJbnZhbGlkIGZvbnQgbWF0cml4IGZvciBmb250IFwiICsgZm9udFJlZk5hbWUpO1xuICAgIH1cblxuICAgIGlmIChzaXplIDwgMCkge1xuICAgICAgc2l6ZSA9IC1zaXplO1xuICAgICAgY3VycmVudC5mb250RGlyZWN0aW9uID0gLTE7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN1cnJlbnQuZm9udERpcmVjdGlvbiA9IDE7XG4gICAgfVxuXG4gICAgdGhpcy5jdXJyZW50LmZvbnQgPSBmb250T2JqO1xuICAgIHRoaXMuY3VycmVudC5mb250U2l6ZSA9IHNpemU7XG5cbiAgICBpZiAoZm9udE9iai5pc1R5cGUzRm9udCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG5hbWUgPSBmb250T2JqLmxvYWRlZE5hbWUgfHwgXCJzYW5zLXNlcmlmXCI7XG4gICAgbGV0IGJvbGQgPSBcIm5vcm1hbFwiO1xuXG4gICAgaWYgKGZvbnRPYmouYmxhY2spIHtcbiAgICAgIGJvbGQgPSBcIjkwMFwiO1xuICAgIH0gZWxzZSBpZiAoZm9udE9iai5ib2xkKSB7XG4gICAgICBib2xkID0gXCJib2xkXCI7XG4gICAgfVxuXG4gICAgY29uc3QgaXRhbGljID0gZm9udE9iai5pdGFsaWMgPyBcIml0YWxpY1wiIDogXCJub3JtYWxcIjtcbiAgICBjb25zdCB0eXBlZmFjZSA9IGBcIiR7bmFtZX1cIiwgJHtmb250T2JqLmZhbGxiYWNrTmFtZX1gO1xuICAgIGxldCBicm93c2VyRm9udFNpemUgPSBzaXplO1xuXG4gICAgaWYgKHNpemUgPCBNSU5fRk9OVF9TSVpFKSB7XG4gICAgICBicm93c2VyRm9udFNpemUgPSBNSU5fRk9OVF9TSVpFO1xuICAgIH0gZWxzZSBpZiAoc2l6ZSA+IE1BWF9GT05UX1NJWkUpIHtcbiAgICAgIGJyb3dzZXJGb250U2l6ZSA9IE1BWF9GT05UX1NJWkU7XG4gICAgfVxuXG4gICAgdGhpcy5jdXJyZW50LmZvbnRTaXplU2NhbGUgPSBzaXplIC8gYnJvd3NlckZvbnRTaXplO1xuICAgIHRoaXMuY3R4LmZvbnQgPSBgJHtpdGFsaWN9ICR7Ym9sZH0gJHticm93c2VyRm9udFNpemV9cHggJHt0eXBlZmFjZX1gO1xuICB9XG5cbiAgc2V0VGV4dFJlbmRlcmluZ01vZGUobW9kZSkge1xuICAgIHRoaXMuY3VycmVudC50ZXh0UmVuZGVyaW5nTW9kZSA9IG1vZGU7XG4gIH1cblxuICBzZXRUZXh0UmlzZShyaXNlKSB7XG4gICAgdGhpcy5jdXJyZW50LnRleHRSaXNlID0gcmlzZTtcbiAgfVxuXG4gIG1vdmVUZXh0KHgsIHkpIHtcbiAgICB0aGlzLmN1cnJlbnQueCA9IHRoaXMuY3VycmVudC5saW5lWCArPSB4O1xuICAgIHRoaXMuY3VycmVudC55ID0gdGhpcy5jdXJyZW50LmxpbmVZICs9IHk7XG4gIH1cblxuICBzZXRMZWFkaW5nTW92ZVRleHQoeCwgeSkge1xuICAgIHRoaXMuc2V0TGVhZGluZygteSk7XG4gICAgdGhpcy5tb3ZlVGV4dCh4LCB5KTtcbiAgfVxuXG4gIHNldFRleHRNYXRyaXgoYSwgYiwgYywgZCwgZSwgZikge1xuICAgIHRoaXMuY3VycmVudC50ZXh0TWF0cml4ID0gW2EsIGIsIGMsIGQsIGUsIGZdO1xuICAgIHRoaXMuY3VycmVudC50ZXh0TWF0cml4U2NhbGUgPSBNYXRoLmh5cG90KGEsIGIpO1xuICAgIHRoaXMuY3VycmVudC54ID0gdGhpcy5jdXJyZW50LmxpbmVYID0gMDtcbiAgICB0aGlzLmN1cnJlbnQueSA9IHRoaXMuY3VycmVudC5saW5lWSA9IDA7XG4gIH1cblxuICBuZXh0TGluZSgpIHtcbiAgICB0aGlzLm1vdmVUZXh0KDAsIHRoaXMuY3VycmVudC5sZWFkaW5nKTtcbiAgfVxuXG4gIHBhaW50Q2hhcihjaGFyYWN0ZXIsIHgsIHksIHBhdHRlcm5UcmFuc2Zvcm0pIHtcbiAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5jdXJyZW50O1xuICAgIGNvbnN0IGZvbnQgPSBjdXJyZW50LmZvbnQ7XG4gICAgY29uc3QgdGV4dFJlbmRlcmluZ01vZGUgPSBjdXJyZW50LnRleHRSZW5kZXJpbmdNb2RlO1xuICAgIGNvbnN0IGZvbnRTaXplID0gY3VycmVudC5mb250U2l6ZSAvIGN1cnJlbnQuZm9udFNpemVTY2FsZTtcbiAgICBjb25zdCBmaWxsU3Ryb2tlTW9kZSA9IHRleHRSZW5kZXJpbmdNb2RlICYgX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuRklMTF9TVFJPS0VfTUFTSztcbiAgICBjb25zdCBpc0FkZFRvUGF0aFNldCA9ICEhKHRleHRSZW5kZXJpbmdNb2RlICYgX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuQUREX1RPX1BBVEhfRkxBRyk7XG4gICAgY29uc3QgcGF0dGVybkZpbGwgPSBjdXJyZW50LnBhdHRlcm5GaWxsICYmICFmb250Lm1pc3NpbmdGaWxlO1xuICAgIGxldCBhZGRUb1BhdGg7XG5cbiAgICBpZiAoZm9udC5kaXNhYmxlRm9udEZhY2UgfHwgaXNBZGRUb1BhdGhTZXQgfHwgcGF0dGVybkZpbGwpIHtcbiAgICAgIGFkZFRvUGF0aCA9IGZvbnQuZ2V0UGF0aEdlbmVyYXRvcih0aGlzLmNvbW1vbk9ianMsIGNoYXJhY3Rlcik7XG4gICAgfVxuXG4gICAgaWYgKGZvbnQuZGlzYWJsZUZvbnRGYWNlIHx8IHBhdHRlcm5GaWxsKSB7XG4gICAgICBjdHguc2F2ZSgpO1xuICAgICAgY3R4LnRyYW5zbGF0ZSh4LCB5KTtcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgIGFkZFRvUGF0aChjdHgsIGZvbnRTaXplKTtcblxuICAgICAgaWYgKHBhdHRlcm5UcmFuc2Zvcm0pIHtcbiAgICAgICAgY3R4LnNldFRyYW5zZm9ybS5hcHBseShjdHgsIHBhdHRlcm5UcmFuc2Zvcm0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoZmlsbFN0cm9rZU1vZGUgPT09IF91dGlsLlRleHRSZW5kZXJpbmdNb2RlLkZJTEwgfHwgZmlsbFN0cm9rZU1vZGUgPT09IF91dGlsLlRleHRSZW5kZXJpbmdNb2RlLkZJTExfU1RST0tFKSB7XG4gICAgICAgIGN0eC5maWxsKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChmaWxsU3Ryb2tlTW9kZSA9PT0gX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuU1RST0tFIHx8IGZpbGxTdHJva2VNb2RlID09PSBfdXRpbC5UZXh0UmVuZGVyaW5nTW9kZS5GSUxMX1NUUk9LRSkge1xuICAgICAgICBjdHguc3Ryb2tlKCk7XG4gICAgICB9XG5cbiAgICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChmaWxsU3Ryb2tlTW9kZSA9PT0gX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuRklMTCB8fCBmaWxsU3Ryb2tlTW9kZSA9PT0gX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuRklMTF9TVFJPS0UpIHtcbiAgICAgICAgY3R4LmZpbGxUZXh0KGNoYXJhY3RlciwgeCwgeSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChmaWxsU3Ryb2tlTW9kZSA9PT0gX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuU1RST0tFIHx8IGZpbGxTdHJva2VNb2RlID09PSBfdXRpbC5UZXh0UmVuZGVyaW5nTW9kZS5GSUxMX1NUUk9LRSkge1xuICAgICAgICBjdHguc3Ryb2tlVGV4dChjaGFyYWN0ZXIsIHgsIHkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpc0FkZFRvUGF0aFNldCkge1xuICAgICAgY29uc3QgcGF0aHMgPSB0aGlzLnBlbmRpbmdUZXh0UGF0aHMgfHwgKHRoaXMucGVuZGluZ1RleHRQYXRocyA9IFtdKTtcbiAgICAgIHBhdGhzLnB1c2goe1xuICAgICAgICB0cmFuc2Zvcm06IGN0eC5tb3pDdXJyZW50VHJhbnNmb3JtLFxuICAgICAgICB4LFxuICAgICAgICB5LFxuICAgICAgICBmb250U2l6ZSxcbiAgICAgICAgYWRkVG9QYXRoXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBnZXQgaXNGb250U3VicGl4ZWxBQUVuYWJsZWQoKSB7XG4gICAgY29uc3Qge1xuICAgICAgY29udGV4dDogY3R4XG4gICAgfSA9IHRoaXMuY2FjaGVkQ2FudmFzZXMuZ2V0Q2FudmFzKFwiaXNGb250U3VicGl4ZWxBQUVuYWJsZWRcIiwgMTAsIDEwLCBmYWxzZSk7XG4gICAgY3R4LnNjYWxlKDEuNSwgMSk7XG4gICAgY3R4LmZpbGxUZXh0KFwiSVwiLCAwLCAxMCk7XG4gICAgY29uc3QgZGF0YSA9IGN0eC5nZXRJbWFnZURhdGEoMCwgMCwgMTAsIDEwKS5kYXRhO1xuICAgIGxldCBlbmFibGVkID0gZmFsc2U7XG5cbiAgICBmb3IgKGxldCBpID0gMzsgaSA8IGRhdGEubGVuZ3RoOyBpICs9IDQpIHtcbiAgICAgIGlmIChkYXRhW2ldID4gMCAmJiBkYXRhW2ldIDwgMjU1KSB7XG4gICAgICAgIGVuYWJsZWQgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gKDAsIF91dGlsLnNoYWRvdykodGhpcywgXCJpc0ZvbnRTdWJwaXhlbEFBRW5hYmxlZFwiLCBlbmFibGVkKTtcbiAgfVxuXG4gIHNob3dUZXh0KGdseXBocykge1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmN1cnJlbnQ7XG4gICAgY29uc3QgZm9udCA9IGN1cnJlbnQuZm9udDtcblxuICAgIGlmIChmb250LmlzVHlwZTNGb250KSB7XG4gICAgICByZXR1cm4gdGhpcy5zaG93VHlwZTNUZXh0KGdseXBocyk7XG4gICAgfVxuXG4gICAgY29uc3QgZm9udFNpemUgPSBjdXJyZW50LmZvbnRTaXplO1xuXG4gICAgaWYgKGZvbnRTaXplID09PSAwKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IGN0eCA9IHRoaXMuY3R4O1xuICAgIGNvbnN0IGZvbnRTaXplU2NhbGUgPSBjdXJyZW50LmZvbnRTaXplU2NhbGU7XG4gICAgY29uc3QgY2hhclNwYWNpbmcgPSBjdXJyZW50LmNoYXJTcGFjaW5nO1xuICAgIGNvbnN0IHdvcmRTcGFjaW5nID0gY3VycmVudC53b3JkU3BhY2luZztcbiAgICBjb25zdCBmb250RGlyZWN0aW9uID0gY3VycmVudC5mb250RGlyZWN0aW9uO1xuICAgIGNvbnN0IHRleHRIU2NhbGUgPSBjdXJyZW50LnRleHRIU2NhbGUgKiBmb250RGlyZWN0aW9uO1xuICAgIGNvbnN0IGdseXBoc0xlbmd0aCA9IGdseXBocy5sZW5ndGg7XG4gICAgY29uc3QgdmVydGljYWwgPSBmb250LnZlcnRpY2FsO1xuICAgIGNvbnN0IHNwYWNpbmdEaXIgPSB2ZXJ0aWNhbCA/IDEgOiAtMTtcbiAgICBjb25zdCBkZWZhdWx0Vk1ldHJpY3MgPSBmb250LmRlZmF1bHRWTWV0cmljcztcbiAgICBjb25zdCB3aWR0aEFkdmFuY2VTY2FsZSA9IGZvbnRTaXplICogY3VycmVudC5mb250TWF0cml4WzBdO1xuICAgIGNvbnN0IHNpbXBsZUZpbGxUZXh0ID0gY3VycmVudC50ZXh0UmVuZGVyaW5nTW9kZSA9PT0gX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuRklMTCAmJiAhZm9udC5kaXNhYmxlRm9udEZhY2UgJiYgIWN1cnJlbnQucGF0dGVybkZpbGw7XG4gICAgY3R4LnNhdmUoKTtcbiAgICBjdHgudHJhbnNmb3JtLmFwcGx5KGN0eCwgY3VycmVudC50ZXh0TWF0cml4KTtcbiAgICBjdHgudHJhbnNsYXRlKGN1cnJlbnQueCwgY3VycmVudC55ICsgY3VycmVudC50ZXh0UmlzZSk7XG5cbiAgICBpZiAoZm9udERpcmVjdGlvbiA+IDApIHtcbiAgICAgIGN0eC5zY2FsZSh0ZXh0SFNjYWxlLCAtMSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN0eC5zY2FsZSh0ZXh0SFNjYWxlLCAxKTtcbiAgICB9XG5cbiAgICBsZXQgcGF0dGVyblRyYW5zZm9ybTtcblxuICAgIGlmIChjdXJyZW50LnBhdHRlcm5GaWxsKSB7XG4gICAgICBjdHguc2F2ZSgpO1xuICAgICAgY29uc3QgcGF0dGVybiA9IGN1cnJlbnQuZmlsbENvbG9yLmdldFBhdHRlcm4oY3R4LCB0aGlzLCBjdHgubW96Q3VycmVudFRyYW5zZm9ybUludmVyc2UsIF9wYXR0ZXJuX2hlbHBlci5QYXRoVHlwZS5GSUxMKTtcbiAgICAgIHBhdHRlcm5UcmFuc2Zvcm0gPSBjdHgubW96Q3VycmVudFRyYW5zZm9ybTtcbiAgICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgICBjdHguZmlsbFN0eWxlID0gcGF0dGVybjtcbiAgICB9XG5cbiAgICBsZXQgbGluZVdpZHRoID0gY3VycmVudC5saW5lV2lkdGg7XG4gICAgY29uc3Qgc2NhbGUgPSBjdXJyZW50LnRleHRNYXRyaXhTY2FsZTtcblxuICAgIGlmIChzY2FsZSA9PT0gMCB8fCBsaW5lV2lkdGggPT09IDApIHtcbiAgICAgIGNvbnN0IGZpbGxTdHJva2VNb2RlID0gY3VycmVudC50ZXh0UmVuZGVyaW5nTW9kZSAmIF91dGlsLlRleHRSZW5kZXJpbmdNb2RlLkZJTExfU1RST0tFX01BU0s7XG5cbiAgICAgIGlmIChmaWxsU3Ryb2tlTW9kZSA9PT0gX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuU1RST0tFIHx8IGZpbGxTdHJva2VNb2RlID09PSBfdXRpbC5UZXh0UmVuZGVyaW5nTW9kZS5GSUxMX1NUUk9LRSkge1xuICAgICAgICBsaW5lV2lkdGggPSB0aGlzLmdldFNpbmdsZVBpeGVsV2lkdGgoKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbGluZVdpZHRoIC89IHNjYWxlO1xuICAgIH1cblxuICAgIGlmIChmb250U2l6ZVNjYWxlICE9PSAxLjApIHtcbiAgICAgIGN0eC5zY2FsZShmb250U2l6ZVNjYWxlLCBmb250U2l6ZVNjYWxlKTtcbiAgICAgIGxpbmVXaWR0aCAvPSBmb250U2l6ZVNjYWxlO1xuICAgIH1cblxuICAgIGN0eC5saW5lV2lkdGggPSBsaW5lV2lkdGg7XG4gICAgbGV0IHggPSAwLFxuICAgICAgICBpO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGdseXBoc0xlbmd0aDsgKytpKSB7XG4gICAgICBjb25zdCBnbHlwaCA9IGdseXBoc1tpXTtcblxuICAgICAgaWYgKHR5cGVvZiBnbHlwaCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICB4ICs9IHNwYWNpbmdEaXIgKiBnbHlwaCAqIGZvbnRTaXplIC8gMTAwMDtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGxldCByZXN0b3JlTmVlZGVkID0gZmFsc2U7XG4gICAgICBjb25zdCBzcGFjaW5nID0gKGdseXBoLmlzU3BhY2UgPyB3b3JkU3BhY2luZyA6IDApICsgY2hhclNwYWNpbmc7XG4gICAgICBjb25zdCBjaGFyYWN0ZXIgPSBnbHlwaC5mb250Q2hhcjtcbiAgICAgIGNvbnN0IGFjY2VudCA9IGdseXBoLmFjY2VudDtcbiAgICAgIGxldCBzY2FsZWRYLCBzY2FsZWRZO1xuICAgICAgbGV0IHdpZHRoID0gZ2x5cGgud2lkdGg7XG5cbiAgICAgIGlmICh2ZXJ0aWNhbCkge1xuICAgICAgICBjb25zdCB2bWV0cmljID0gZ2x5cGgudm1ldHJpYyB8fCBkZWZhdWx0Vk1ldHJpY3M7XG4gICAgICAgIGNvbnN0IHZ4ID0gLShnbHlwaC52bWV0cmljID8gdm1ldHJpY1sxXSA6IHdpZHRoICogMC41KSAqIHdpZHRoQWR2YW5jZVNjYWxlO1xuICAgICAgICBjb25zdCB2eSA9IHZtZXRyaWNbMl0gKiB3aWR0aEFkdmFuY2VTY2FsZTtcbiAgICAgICAgd2lkdGggPSB2bWV0cmljID8gLXZtZXRyaWNbMF0gOiB3aWR0aDtcbiAgICAgICAgc2NhbGVkWCA9IHZ4IC8gZm9udFNpemVTY2FsZTtcbiAgICAgICAgc2NhbGVkWSA9ICh4ICsgdnkpIC8gZm9udFNpemVTY2FsZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNjYWxlZFggPSB4IC8gZm9udFNpemVTY2FsZTtcbiAgICAgICAgc2NhbGVkWSA9IDA7XG4gICAgICB9XG5cbiAgICAgIGlmIChmb250LnJlbWVhc3VyZSAmJiB3aWR0aCA+IDApIHtcbiAgICAgICAgY29uc3QgbWVhc3VyZWRXaWR0aCA9IGN0eC5tZWFzdXJlVGV4dChjaGFyYWN0ZXIpLndpZHRoICogMTAwMCAvIGZvbnRTaXplICogZm9udFNpemVTY2FsZTtcblxuICAgICAgICBpZiAod2lkdGggPCBtZWFzdXJlZFdpZHRoICYmIHRoaXMuaXNGb250U3VicGl4ZWxBQUVuYWJsZWQpIHtcbiAgICAgICAgICBjb25zdCBjaGFyYWN0ZXJTY2FsZVggPSB3aWR0aCAvIG1lYXN1cmVkV2lkdGg7XG4gICAgICAgICAgcmVzdG9yZU5lZWRlZCA9IHRydWU7XG4gICAgICAgICAgY3R4LnNhdmUoKTtcbiAgICAgICAgICBjdHguc2NhbGUoY2hhcmFjdGVyU2NhbGVYLCAxKTtcbiAgICAgICAgICBzY2FsZWRYIC89IGNoYXJhY3RlclNjYWxlWDtcbiAgICAgICAgfSBlbHNlIGlmICh3aWR0aCAhPT0gbWVhc3VyZWRXaWR0aCkge1xuICAgICAgICAgIHNjYWxlZFggKz0gKHdpZHRoIC0gbWVhc3VyZWRXaWR0aCkgLyAyMDAwICogZm9udFNpemUgLyBmb250U2l6ZVNjYWxlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmNvbnRlbnRWaXNpYmxlICYmIChnbHlwaC5pc0luRm9udCB8fCBmb250Lm1pc3NpbmdGaWxlKSkge1xuICAgICAgICBpZiAoc2ltcGxlRmlsbFRleHQgJiYgIWFjY2VudCkge1xuICAgICAgICAgIGN0eC5maWxsVGV4dChjaGFyYWN0ZXIsIHNjYWxlZFgsIHNjYWxlZFkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMucGFpbnRDaGFyKGNoYXJhY3Rlciwgc2NhbGVkWCwgc2NhbGVkWSwgcGF0dGVyblRyYW5zZm9ybSk7XG5cbiAgICAgICAgICBpZiAoYWNjZW50KSB7XG4gICAgICAgICAgICBjb25zdCBzY2FsZWRBY2NlbnRYID0gc2NhbGVkWCArIGZvbnRTaXplICogYWNjZW50Lm9mZnNldC54IC8gZm9udFNpemVTY2FsZTtcbiAgICAgICAgICAgIGNvbnN0IHNjYWxlZEFjY2VudFkgPSBzY2FsZWRZIC0gZm9udFNpemUgKiBhY2NlbnQub2Zmc2V0LnkgLyBmb250U2l6ZVNjYWxlO1xuICAgICAgICAgICAgdGhpcy5wYWludENoYXIoYWNjZW50LmZvbnRDaGFyLCBzY2FsZWRBY2NlbnRYLCBzY2FsZWRBY2NlbnRZLCBwYXR0ZXJuVHJhbnNmb3JtKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbGV0IGNoYXJXaWR0aDtcblxuICAgICAgaWYgKHZlcnRpY2FsKSB7XG4gICAgICAgIGNoYXJXaWR0aCA9IHdpZHRoICogd2lkdGhBZHZhbmNlU2NhbGUgLSBzcGFjaW5nICogZm9udERpcmVjdGlvbjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNoYXJXaWR0aCA9IHdpZHRoICogd2lkdGhBZHZhbmNlU2NhbGUgKyBzcGFjaW5nICogZm9udERpcmVjdGlvbjtcbiAgICAgIH1cblxuICAgICAgeCArPSBjaGFyV2lkdGg7XG5cbiAgICAgIGlmIChyZXN0b3JlTmVlZGVkKSB7XG4gICAgICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHZlcnRpY2FsKSB7XG4gICAgICBjdXJyZW50LnkgLT0geDtcbiAgICB9IGVsc2Uge1xuICAgICAgY3VycmVudC54ICs9IHggKiB0ZXh0SFNjYWxlO1xuICAgIH1cblxuICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgdGhpcy5jb21wb3NlKCk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHNob3dUeXBlM1RleHQoZ2x5cGhzKSB7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcbiAgICBjb25zdCBmb250ID0gY3VycmVudC5mb250O1xuICAgIGNvbnN0IGZvbnRTaXplID0gY3VycmVudC5mb250U2l6ZTtcbiAgICBjb25zdCBmb250RGlyZWN0aW9uID0gY3VycmVudC5mb250RGlyZWN0aW9uO1xuICAgIGNvbnN0IHNwYWNpbmdEaXIgPSBmb250LnZlcnRpY2FsID8gMSA6IC0xO1xuICAgIGNvbnN0IGNoYXJTcGFjaW5nID0gY3VycmVudC5jaGFyU3BhY2luZztcbiAgICBjb25zdCB3b3JkU3BhY2luZyA9IGN1cnJlbnQud29yZFNwYWNpbmc7XG4gICAgY29uc3QgdGV4dEhTY2FsZSA9IGN1cnJlbnQudGV4dEhTY2FsZSAqIGZvbnREaXJlY3Rpb247XG4gICAgY29uc3QgZm9udE1hdHJpeCA9IGN1cnJlbnQuZm9udE1hdHJpeCB8fCBfdXRpbC5GT05UX0lERU5USVRZX01BVFJJWDtcbiAgICBjb25zdCBnbHlwaHNMZW5ndGggPSBnbHlwaHMubGVuZ3RoO1xuICAgIGNvbnN0IGlzVGV4dEludmlzaWJsZSA9IGN1cnJlbnQudGV4dFJlbmRlcmluZ01vZGUgPT09IF91dGlsLlRleHRSZW5kZXJpbmdNb2RlLklOVklTSUJMRTtcbiAgICBsZXQgaSwgZ2x5cGgsIHdpZHRoLCBzcGFjaW5nTGVuZ3RoO1xuXG4gICAgaWYgKGlzVGV4dEludmlzaWJsZSB8fCBmb250U2l6ZSA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2NhY2hlZFNjYWxlRm9yU3Ryb2tpbmcgPSBudWxsO1xuICAgIHRoaXMuX2NhY2hlZEdldFNpbmdsZVBpeGVsV2lkdGggPSBudWxsO1xuICAgIGN0eC5zYXZlKCk7XG4gICAgY3R4LnRyYW5zZm9ybS5hcHBseShjdHgsIGN1cnJlbnQudGV4dE1hdHJpeCk7XG4gICAgY3R4LnRyYW5zbGF0ZShjdXJyZW50LngsIGN1cnJlbnQueSk7XG4gICAgY3R4LnNjYWxlKHRleHRIU2NhbGUsIGZvbnREaXJlY3Rpb24pO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGdseXBoc0xlbmd0aDsgKytpKSB7XG4gICAgICBnbHlwaCA9IGdseXBoc1tpXTtcblxuICAgICAgaWYgKHR5cGVvZiBnbHlwaCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICBzcGFjaW5nTGVuZ3RoID0gc3BhY2luZ0RpciAqIGdseXBoICogZm9udFNpemUgLyAxMDAwO1xuICAgICAgICB0aGlzLmN0eC50cmFuc2xhdGUoc3BhY2luZ0xlbmd0aCwgMCk7XG4gICAgICAgIGN1cnJlbnQueCArPSBzcGFjaW5nTGVuZ3RoICogdGV4dEhTY2FsZTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNwYWNpbmcgPSAoZ2x5cGguaXNTcGFjZSA/IHdvcmRTcGFjaW5nIDogMCkgKyBjaGFyU3BhY2luZztcbiAgICAgIGNvbnN0IG9wZXJhdG9yTGlzdCA9IGZvbnQuY2hhclByb2NPcGVyYXRvckxpc3RbZ2x5cGgub3BlcmF0b3JMaXN0SWRdO1xuXG4gICAgICBpZiAoIW9wZXJhdG9yTGlzdCkge1xuICAgICAgICAoMCwgX3V0aWwud2FybikoYFR5cGUzIGNoYXJhY3RlciBcIiR7Z2x5cGgub3BlcmF0b3JMaXN0SWR9XCIgaXMgbm90IGF2YWlsYWJsZS5gKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmNvbnRlbnRWaXNpYmxlKSB7XG4gICAgICAgIHRoaXMucHJvY2Vzc2luZ1R5cGUzID0gZ2x5cGg7XG4gICAgICAgIHRoaXMuc2F2ZSgpO1xuICAgICAgICBjdHguc2NhbGUoZm9udFNpemUsIGZvbnRTaXplKTtcbiAgICAgICAgY3R4LnRyYW5zZm9ybS5hcHBseShjdHgsIGZvbnRNYXRyaXgpO1xuICAgICAgICB0aGlzLmV4ZWN1dGVPcGVyYXRvckxpc3Qob3BlcmF0b3JMaXN0KTtcbiAgICAgICAgdGhpcy5yZXN0b3JlKCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRyYW5zZm9ybWVkID0gX3V0aWwuVXRpbC5hcHBseVRyYW5zZm9ybShbZ2x5cGgud2lkdGgsIDBdLCBmb250TWF0cml4KTtcblxuICAgICAgd2lkdGggPSB0cmFuc2Zvcm1lZFswXSAqIGZvbnRTaXplICsgc3BhY2luZztcbiAgICAgIGN0eC50cmFuc2xhdGUod2lkdGgsIDApO1xuICAgICAgY3VycmVudC54ICs9IHdpZHRoICogdGV4dEhTY2FsZTtcbiAgICB9XG5cbiAgICBjdHgucmVzdG9yZSgpO1xuICAgIHRoaXMucHJvY2Vzc2luZ1R5cGUzID0gbnVsbDtcbiAgfVxuXG4gIHNldENoYXJXaWR0aCh4V2lkdGgsIHlXaWR0aCkge31cblxuICBzZXRDaGFyV2lkdGhBbmRCb3VuZHMoeFdpZHRoLCB5V2lkdGgsIGxseCwgbGx5LCB1cngsIHVyeSkge1xuICAgIHRoaXMuY3R4LnJlY3QobGx4LCBsbHksIHVyeCAtIGxseCwgdXJ5IC0gbGx5KTtcbiAgICB0aGlzLmN0eC5jbGlwKCk7XG4gICAgdGhpcy5lbmRQYXRoKCk7XG4gIH1cblxuICBnZXRDb2xvck5fUGF0dGVybihJUikge1xuICAgIGxldCBwYXR0ZXJuO1xuXG4gICAgaWYgKElSWzBdID09PSBcIlRpbGluZ1BhdHRlcm5cIikge1xuICAgICAgY29uc3QgY29sb3IgPSBJUlsxXTtcbiAgICAgIGNvbnN0IGJhc2VUcmFuc2Zvcm0gPSB0aGlzLmJhc2VUcmFuc2Zvcm0gfHwgdGhpcy5jdHgubW96Q3VycmVudFRyYW5zZm9ybS5zbGljZSgpO1xuICAgICAgY29uc3QgY2FudmFzR3JhcGhpY3NGYWN0b3J5ID0ge1xuICAgICAgICBjcmVhdGVDYW52YXNHcmFwaGljczogY3R4ID0+IHtcbiAgICAgICAgICByZXR1cm4gbmV3IENhbnZhc0dyYXBoaWNzKGN0eCwgdGhpcy5jb21tb25PYmpzLCB0aGlzLm9ianMsIHRoaXMuY2FudmFzRmFjdG9yeSk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBwYXR0ZXJuID0gbmV3IF9wYXR0ZXJuX2hlbHBlci5UaWxpbmdQYXR0ZXJuKElSLCBjb2xvciwgdGhpcy5jdHgsIGNhbnZhc0dyYXBoaWNzRmFjdG9yeSwgYmFzZVRyYW5zZm9ybSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhdHRlcm4gPSB0aGlzLl9nZXRQYXR0ZXJuKElSWzFdLCBJUlsyXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhdHRlcm47XG4gIH1cblxuICBzZXRTdHJva2VDb2xvck4oKSB7XG4gICAgdGhpcy5jdXJyZW50LnN0cm9rZUNvbG9yID0gdGhpcy5nZXRDb2xvck5fUGF0dGVybihhcmd1bWVudHMpO1xuICB9XG5cbiAgc2V0RmlsbENvbG9yTigpIHtcbiAgICB0aGlzLmN1cnJlbnQuZmlsbENvbG9yID0gdGhpcy5nZXRDb2xvck5fUGF0dGVybihhcmd1bWVudHMpO1xuICAgIHRoaXMuY3VycmVudC5wYXR0ZXJuRmlsbCA9IHRydWU7XG4gIH1cblxuICBzZXRTdHJva2VSR0JDb2xvcihyLCBnLCBiKSB7XG4gICAgY29uc3QgY29sb3IgPSB0aGlzLnNlbGVjdENvbG9yPy4ociwgZywgYikgfHwgX3V0aWwuVXRpbC5tYWtlSGV4Q29sb3IociwgZywgYik7XG5cbiAgICB0aGlzLmN0eC5zdHJva2VTdHlsZSA9IGNvbG9yO1xuICAgIHRoaXMuY3VycmVudC5zdHJva2VDb2xvciA9IGNvbG9yO1xuICB9XG5cbiAgc2V0RmlsbFJHQkNvbG9yKHIsIGcsIGIpIHtcbiAgICBjb25zdCBjb2xvciA9IHRoaXMuc2VsZWN0Q29sb3I/LihyLCBnLCBiKSB8fCBfdXRpbC5VdGlsLm1ha2VIZXhDb2xvcihyLCBnLCBiKTtcblxuICAgIHRoaXMuY3R4LmZpbGxTdHlsZSA9IGNvbG9yO1xuICAgIHRoaXMuY3VycmVudC5maWxsQ29sb3IgPSBjb2xvcjtcbiAgICB0aGlzLmN1cnJlbnQucGF0dGVybkZpbGwgPSBmYWxzZTtcbiAgfVxuXG4gIF9nZXRQYXR0ZXJuKG9iaklkLCBtYXRyaXggPSBudWxsKSB7XG4gICAgbGV0IHBhdHRlcm47XG5cbiAgICBpZiAodGhpcy5jYWNoZWRQYXR0ZXJucy5oYXMob2JqSWQpKSB7XG4gICAgICBwYXR0ZXJuID0gdGhpcy5jYWNoZWRQYXR0ZXJucy5nZXQob2JqSWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYXR0ZXJuID0gKDAsIF9wYXR0ZXJuX2hlbHBlci5nZXRTaGFkaW5nUGF0dGVybikodGhpcy5vYmpzLmdldChvYmpJZCkpO1xuICAgICAgdGhpcy5jYWNoZWRQYXR0ZXJucy5zZXQob2JqSWQsIHBhdHRlcm4pO1xuICAgIH1cblxuICAgIGlmIChtYXRyaXgpIHtcbiAgICAgIHBhdHRlcm4ubWF0cml4ID0gbWF0cml4O1xuICAgIH1cblxuICAgIHJldHVybiBwYXR0ZXJuO1xuICB9XG5cbiAgc2hhZGluZ0ZpbGwob2JqSWQpIHtcbiAgICBpZiAoIXRoaXMuY29udGVudFZpc2libGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcbiAgICB0aGlzLnNhdmUoKTtcblxuICAgIGNvbnN0IHBhdHRlcm4gPSB0aGlzLl9nZXRQYXR0ZXJuKG9iaklkKTtcblxuICAgIGN0eC5maWxsU3R5bGUgPSBwYXR0ZXJuLmdldFBhdHRlcm4oY3R4LCB0aGlzLCBjdHgubW96Q3VycmVudFRyYW5zZm9ybUludmVyc2UsIF9wYXR0ZXJuX2hlbHBlci5QYXRoVHlwZS5TSEFESU5HKTtcbiAgICBjb25zdCBpbnYgPSBjdHgubW96Q3VycmVudFRyYW5zZm9ybUludmVyc2U7XG5cbiAgICBpZiAoaW52KSB7XG4gICAgICBjb25zdCBjYW52YXMgPSBjdHguY2FudmFzO1xuICAgICAgY29uc3Qgd2lkdGggPSBjYW52YXMud2lkdGg7XG4gICAgICBjb25zdCBoZWlnaHQgPSBjYW52YXMuaGVpZ2h0O1xuXG4gICAgICBjb25zdCBibCA9IF91dGlsLlV0aWwuYXBwbHlUcmFuc2Zvcm0oWzAsIDBdLCBpbnYpO1xuXG4gICAgICBjb25zdCBiciA9IF91dGlsLlV0aWwuYXBwbHlUcmFuc2Zvcm0oWzAsIGhlaWdodF0sIGludik7XG5cbiAgICAgIGNvbnN0IHVsID0gX3V0aWwuVXRpbC5hcHBseVRyYW5zZm9ybShbd2lkdGgsIDBdLCBpbnYpO1xuXG4gICAgICBjb25zdCB1ciA9IF91dGlsLlV0aWwuYXBwbHlUcmFuc2Zvcm0oW3dpZHRoLCBoZWlnaHRdLCBpbnYpO1xuXG4gICAgICBjb25zdCB4MCA9IE1hdGgubWluKGJsWzBdLCBiclswXSwgdWxbMF0sIHVyWzBdKTtcbiAgICAgIGNvbnN0IHkwID0gTWF0aC5taW4oYmxbMV0sIGJyWzFdLCB1bFsxXSwgdXJbMV0pO1xuICAgICAgY29uc3QgeDEgPSBNYXRoLm1heChibFswXSwgYnJbMF0sIHVsWzBdLCB1clswXSk7XG4gICAgICBjb25zdCB5MSA9IE1hdGgubWF4KGJsWzFdLCBiclsxXSwgdWxbMV0sIHVyWzFdKTtcbiAgICAgIHRoaXMuY3R4LmZpbGxSZWN0KHgwLCB5MCwgeDEgLSB4MCwgeTEgLSB5MCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3R4LmZpbGxSZWN0KC0xZTEwLCAtMWUxMCwgMmUxMCwgMmUxMCk7XG4gICAgfVxuXG4gICAgdGhpcy5jb21wb3NlKHRoaXMuY3VycmVudC5nZXRDbGlwcGVkUGF0aEJvdW5kaW5nQm94KCkpO1xuICAgIHRoaXMucmVzdG9yZSgpO1xuICB9XG5cbiAgYmVnaW5JbmxpbmVJbWFnZSgpIHtcbiAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiU2hvdWxkIG5vdCBjYWxsIGJlZ2luSW5saW5lSW1hZ2VcIik7XG4gIH1cblxuICBiZWdpbkltYWdlRGF0YSgpIHtcbiAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiU2hvdWxkIG5vdCBjYWxsIGJlZ2luSW1hZ2VEYXRhXCIpO1xuICB9XG5cbiAgcGFpbnRGb3JtWE9iamVjdEJlZ2luKG1hdHJpeCwgYmJveCkge1xuICAgIGlmICghdGhpcy5jb250ZW50VmlzaWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc2F2ZSgpO1xuICAgIHRoaXMuYmFzZVRyYW5zZm9ybVN0YWNrLnB1c2godGhpcy5iYXNlVHJhbnNmb3JtKTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KG1hdHJpeCkgJiYgbWF0cml4Lmxlbmd0aCA9PT0gNikge1xuICAgICAgdGhpcy50cmFuc2Zvcm0uYXBwbHkodGhpcywgbWF0cml4KTtcbiAgICB9XG5cbiAgICB0aGlzLmJhc2VUcmFuc2Zvcm0gPSB0aGlzLmN0eC5tb3pDdXJyZW50VHJhbnNmb3JtO1xuXG4gICAgaWYgKGJib3gpIHtcbiAgICAgIGNvbnN0IHdpZHRoID0gYmJveFsyXSAtIGJib3hbMF07XG4gICAgICBjb25zdCBoZWlnaHQgPSBiYm94WzNdIC0gYmJveFsxXTtcbiAgICAgIHRoaXMuY3R4LnJlY3QoYmJveFswXSwgYmJveFsxXSwgd2lkdGgsIGhlaWdodCk7XG4gICAgICB0aGlzLmN1cnJlbnQudXBkYXRlUmVjdE1pbk1heCh0aGlzLmN0eC5tb3pDdXJyZW50VHJhbnNmb3JtLCBiYm94KTtcbiAgICAgIHRoaXMuY2xpcCgpO1xuICAgICAgdGhpcy5lbmRQYXRoKCk7XG4gICAgfVxuICB9XG5cbiAgcGFpbnRGb3JtWE9iamVjdEVuZCgpIHtcbiAgICBpZiAoIXRoaXMuY29udGVudFZpc2libGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnJlc3RvcmUoKTtcbiAgICB0aGlzLmJhc2VUcmFuc2Zvcm0gPSB0aGlzLmJhc2VUcmFuc2Zvcm1TdGFjay5wb3AoKTtcbiAgfVxuXG4gIGJlZ2luR3JvdXAoZ3JvdXApIHtcbiAgICBpZiAoIXRoaXMuY29udGVudFZpc2libGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNhdmUoKTtcblxuICAgIGlmICh0aGlzLmluU01hc2tNb2RlKSB7XG4gICAgICB0aGlzLmVuZFNNYXNrTW9kZSgpO1xuICAgICAgdGhpcy5jdXJyZW50LmFjdGl2ZVNNYXNrID0gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50Q3R4ID0gdGhpcy5jdHg7XG5cbiAgICBpZiAoIWdyb3VwLmlzb2xhdGVkKSB7XG4gICAgICAoMCwgX3V0aWwuaW5mbykoXCJUT0RPOiBTdXBwb3J0IG5vbi1pc29sYXRlZCBncm91cHMuXCIpO1xuICAgIH1cblxuICAgIGlmIChncm91cC5rbm9ja291dCkge1xuICAgICAgKDAsIF91dGlsLndhcm4pKFwiS25vY2tvdXQgZ3JvdXBzIG5vdCBzdXBwb3J0ZWQuXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IGN1cnJlbnRUcmFuc2Zvcm0gPSBjdXJyZW50Q3R4Lm1vekN1cnJlbnRUcmFuc2Zvcm07XG5cbiAgICBpZiAoZ3JvdXAubWF0cml4KSB7XG4gICAgICBjdXJyZW50Q3R4LnRyYW5zZm9ybS5hcHBseShjdXJyZW50Q3R4LCBncm91cC5tYXRyaXgpO1xuICAgIH1cblxuICAgIGlmICghZ3JvdXAuYmJveCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQm91bmRpbmcgYm94IGlzIHJlcXVpcmVkLlwiKTtcbiAgICB9XG5cbiAgICBsZXQgYm91bmRzID0gX3V0aWwuVXRpbC5nZXRBeGlhbEFsaWduZWRCb3VuZGluZ0JveChncm91cC5iYm94LCBjdXJyZW50Q3R4Lm1vekN1cnJlbnRUcmFuc2Zvcm0pO1xuXG4gICAgY29uc3QgY2FudmFzQm91bmRzID0gWzAsIDAsIGN1cnJlbnRDdHguY2FudmFzLndpZHRoLCBjdXJyZW50Q3R4LmNhbnZhcy5oZWlnaHRdO1xuICAgIGJvdW5kcyA9IF91dGlsLlV0aWwuaW50ZXJzZWN0KGJvdW5kcywgY2FudmFzQm91bmRzKSB8fCBbMCwgMCwgMCwgMF07XG4gICAgY29uc3Qgb2Zmc2V0WCA9IE1hdGguZmxvb3IoYm91bmRzWzBdKTtcbiAgICBjb25zdCBvZmZzZXRZID0gTWF0aC5mbG9vcihib3VuZHNbMV0pO1xuICAgIGxldCBkcmF3bldpZHRoID0gTWF0aC5tYXgoTWF0aC5jZWlsKGJvdW5kc1syXSkgLSBvZmZzZXRYLCAxKTtcbiAgICBsZXQgZHJhd25IZWlnaHQgPSBNYXRoLm1heChNYXRoLmNlaWwoYm91bmRzWzNdKSAtIG9mZnNldFksIDEpO1xuICAgIGxldCBzY2FsZVggPSAxLFxuICAgICAgICBzY2FsZVkgPSAxO1xuXG4gICAgaWYgKGRyYXduV2lkdGggPiBNQVhfR1JPVVBfU0laRSkge1xuICAgICAgc2NhbGVYID0gZHJhd25XaWR0aCAvIE1BWF9HUk9VUF9TSVpFO1xuICAgICAgZHJhd25XaWR0aCA9IE1BWF9HUk9VUF9TSVpFO1xuICAgIH1cblxuICAgIGlmIChkcmF3bkhlaWdodCA+IE1BWF9HUk9VUF9TSVpFKSB7XG4gICAgICBzY2FsZVkgPSBkcmF3bkhlaWdodCAvIE1BWF9HUk9VUF9TSVpFO1xuICAgICAgZHJhd25IZWlnaHQgPSBNQVhfR1JPVVBfU0laRTtcbiAgICB9XG5cbiAgICB0aGlzLmN1cnJlbnQuc3RhcnROZXdQYXRoQW5kQ2xpcEJveChbMCwgMCwgZHJhd25XaWR0aCwgZHJhd25IZWlnaHRdKTtcbiAgICBsZXQgY2FjaGVJZCA9IFwiZ3JvdXBBdFwiICsgdGhpcy5ncm91cExldmVsO1xuXG4gICAgaWYgKGdyb3VwLnNtYXNrKSB7XG4gICAgICBjYWNoZUlkICs9IFwiX3NtYXNrX1wiICsgdGhpcy5zbWFza0NvdW50ZXIrKyAlIDI7XG4gICAgfVxuXG4gICAgY29uc3Qgc2NyYXRjaENhbnZhcyA9IHRoaXMuY2FjaGVkQ2FudmFzZXMuZ2V0Q2FudmFzKGNhY2hlSWQsIGRyYXduV2lkdGgsIGRyYXduSGVpZ2h0LCB0cnVlKTtcbiAgICBjb25zdCBncm91cEN0eCA9IHNjcmF0Y2hDYW52YXMuY29udGV4dDtcbiAgICBncm91cEN0eC5zY2FsZSgxIC8gc2NhbGVYLCAxIC8gc2NhbGVZKTtcbiAgICBncm91cEN0eC50cmFuc2xhdGUoLW9mZnNldFgsIC1vZmZzZXRZKTtcbiAgICBncm91cEN0eC50cmFuc2Zvcm0uYXBwbHkoZ3JvdXBDdHgsIGN1cnJlbnRUcmFuc2Zvcm0pO1xuXG4gICAgaWYgKGdyb3VwLnNtYXNrKSB7XG4gICAgICB0aGlzLnNtYXNrU3RhY2sucHVzaCh7XG4gICAgICAgIGNhbnZhczogc2NyYXRjaENhbnZhcy5jYW52YXMsXG4gICAgICAgIGNvbnRleHQ6IGdyb3VwQ3R4LFxuICAgICAgICBvZmZzZXRYLFxuICAgICAgICBvZmZzZXRZLFxuICAgICAgICBzY2FsZVgsXG4gICAgICAgIHNjYWxlWSxcbiAgICAgICAgc3VidHlwZTogZ3JvdXAuc21hc2suc3VidHlwZSxcbiAgICAgICAgYmFja2Ryb3A6IGdyb3VwLnNtYXNrLmJhY2tkcm9wLFxuICAgICAgICB0cmFuc2Zlck1hcDogZ3JvdXAuc21hc2sudHJhbnNmZXJNYXAgfHwgbnVsbCxcbiAgICAgICAgc3RhcnRUcmFuc2Zvcm1JbnZlcnNlOiBudWxsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY3VycmVudEN0eC5zZXRUcmFuc2Zvcm0oMSwgMCwgMCwgMSwgMCwgMCk7XG4gICAgICBjdXJyZW50Q3R4LnRyYW5zbGF0ZShvZmZzZXRYLCBvZmZzZXRZKTtcbiAgICAgIGN1cnJlbnRDdHguc2NhbGUoc2NhbGVYLCBzY2FsZVkpO1xuICAgICAgY3VycmVudEN0eC5zYXZlKCk7XG4gICAgfVxuXG4gICAgY29weUN0eFN0YXRlKGN1cnJlbnRDdHgsIGdyb3VwQ3R4KTtcbiAgICB0aGlzLmN0eCA9IGdyb3VwQ3R4O1xuICAgIHRoaXMuc2V0R1N0YXRlKFtbXCJCTVwiLCBcInNvdXJjZS1vdmVyXCJdLCBbXCJjYVwiLCAxXSwgW1wiQ0FcIiwgMV1dKTtcbiAgICB0aGlzLmdyb3VwU3RhY2sucHVzaChjdXJyZW50Q3R4KTtcbiAgICB0aGlzLmdyb3VwTGV2ZWwrKztcbiAgfVxuXG4gIGVuZEdyb3VwKGdyb3VwKSB7XG4gICAgaWYgKCF0aGlzLmNvbnRlbnRWaXNpYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5ncm91cExldmVsLS07XG4gICAgY29uc3QgZ3JvdXBDdHggPSB0aGlzLmN0eDtcbiAgICBjb25zdCBjdHggPSB0aGlzLmdyb3VwU3RhY2sucG9wKCk7XG4gICAgdGhpcy5jdHggPSBjdHg7XG4gICAgdGhpcy5jdHguaW1hZ2VTbW9vdGhpbmdFbmFibGVkID0gZmFsc2U7XG5cbiAgICBpZiAoZ3JvdXAuc21hc2spIHtcbiAgICAgIHRoaXMudGVtcFNNYXNrID0gdGhpcy5zbWFza1N0YWNrLnBvcCgpO1xuICAgICAgdGhpcy5yZXN0b3JlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3R4LnJlc3RvcmUoKTtcbiAgICAgIGNvbnN0IGN1cnJlbnRNdHggPSB0aGlzLmN0eC5tb3pDdXJyZW50VHJhbnNmb3JtO1xuICAgICAgdGhpcy5yZXN0b3JlKCk7XG4gICAgICB0aGlzLmN0eC5zYXZlKCk7XG4gICAgICB0aGlzLmN0eC5zZXRUcmFuc2Zvcm0uYXBwbHkodGhpcy5jdHgsIGN1cnJlbnRNdHgpO1xuXG4gICAgICBjb25zdCBkaXJ0eUJveCA9IF91dGlsLlV0aWwuZ2V0QXhpYWxBbGlnbmVkQm91bmRpbmdCb3goWzAsIDAsIGdyb3VwQ3R4LmNhbnZhcy53aWR0aCwgZ3JvdXBDdHguY2FudmFzLmhlaWdodF0sIGN1cnJlbnRNdHgpO1xuXG4gICAgICB0aGlzLmN0eC5kcmF3SW1hZ2UoZ3JvdXBDdHguY2FudmFzLCAwLCAwKTtcbiAgICAgIHRoaXMuY3R4LnJlc3RvcmUoKTtcbiAgICAgIHRoaXMuY29tcG9zZShkaXJ0eUJveCk7XG4gICAgfVxuICB9XG5cbiAgYmVnaW5Bbm5vdGF0aW9ucygpIHtcbiAgICB0aGlzLnNhdmUoKTtcblxuICAgIGlmICh0aGlzLmJhc2VUcmFuc2Zvcm0pIHtcbiAgICAgIHRoaXMuY3R4LnNldFRyYW5zZm9ybS5hcHBseSh0aGlzLmN0eCwgdGhpcy5iYXNlVHJhbnNmb3JtKTtcbiAgICB9XG4gIH1cblxuICBlbmRBbm5vdGF0aW9ucygpIHtcbiAgICB0aGlzLnJlc3RvcmUoKTtcbiAgfVxuXG4gIGJlZ2luQW5ub3RhdGlvbihpZCwgcmVjdCwgdHJhbnNmb3JtLCBtYXRyaXgsIGhhc093bkNhbnZhcykge1xuICAgIHRoaXMuc2F2ZSgpO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkocmVjdCkgJiYgcmVjdC5sZW5ndGggPT09IDQpIHtcbiAgICAgIGNvbnN0IHdpZHRoID0gcmVjdFsyXSAtIHJlY3RbMF07XG4gICAgICBjb25zdCBoZWlnaHQgPSByZWN0WzNdIC0gcmVjdFsxXTtcblxuICAgICAgaWYgKGhhc093bkNhbnZhcyAmJiB0aGlzLmFubm90YXRpb25DYW52YXNNYXApIHtcbiAgICAgICAgdHJhbnNmb3JtID0gdHJhbnNmb3JtLnNsaWNlKCk7XG4gICAgICAgIHRyYW5zZm9ybVs0XSAtPSByZWN0WzBdO1xuICAgICAgICB0cmFuc2Zvcm1bNV0gLT0gcmVjdFsxXTtcbiAgICAgICAgcmVjdCA9IHJlY3Quc2xpY2UoKTtcbiAgICAgICAgcmVjdFswXSA9IHJlY3RbMV0gPSAwO1xuICAgICAgICByZWN0WzJdID0gd2lkdGg7XG4gICAgICAgIHJlY3RbM10gPSBoZWlnaHQ7XG5cbiAgICAgICAgY29uc3QgW3NjYWxlWCwgc2NhbGVZXSA9IF91dGlsLlV0aWwuc2luZ3VsYXJWYWx1ZURlY29tcG9zZTJkU2NhbGUodGhpcy5jdHgubW96Q3VycmVudFRyYW5zZm9ybSk7XG5cbiAgICAgICAgY29uc3Qge1xuICAgICAgICAgIHZpZXdwb3J0U2NhbGVcbiAgICAgICAgfSA9IHRoaXM7XG4gICAgICAgIGNvbnN0IGNhbnZhc1dpZHRoID0gTWF0aC5jZWlsKHdpZHRoICogdGhpcy5vdXRwdXRTY2FsZVggKiB2aWV3cG9ydFNjYWxlKTtcbiAgICAgICAgY29uc3QgY2FudmFzSGVpZ2h0ID0gTWF0aC5jZWlsKGhlaWdodCAqIHRoaXMub3V0cHV0U2NhbGVZICogdmlld3BvcnRTY2FsZSk7XG4gICAgICAgIHRoaXMuYW5ub3RhdGlvbkNhbnZhcyA9IHRoaXMuY2FudmFzRmFjdG9yeS5jcmVhdGUoY2FudmFzV2lkdGgsIGNhbnZhc0hlaWdodCk7XG4gICAgICAgIGNvbnN0IHtcbiAgICAgICAgICBjYW52YXMsXG4gICAgICAgICAgY29udGV4dFxuICAgICAgICB9ID0gdGhpcy5hbm5vdGF0aW9uQ2FudmFzO1xuICAgICAgICBjb25zdCB2aWV3cG9ydFNjYWxlRmFjdG9yU3RyID0gYHZhcigtLXpvb20tZmFjdG9yKSAqICR7X2Rpc3BsYXlfdXRpbHMuUGl4ZWxzUGVySW5jaC5QREZfVE9fQ1NTX1VOSVRTfWA7XG4gICAgICAgIGNhbnZhcy5zdHlsZS53aWR0aCA9IGBjYWxjKCR7d2lkdGh9cHggKiAke3ZpZXdwb3J0U2NhbGVGYWN0b3JTdHJ9KWA7XG4gICAgICAgIGNhbnZhcy5zdHlsZS5oZWlnaHQgPSBgY2FsYygke2hlaWdodH1weCAqICR7dmlld3BvcnRTY2FsZUZhY3RvclN0cn0pYDtcbiAgICAgICAgdGhpcy5hbm5vdGF0aW9uQ2FudmFzTWFwLnNldChpZCwgY2FudmFzKTtcbiAgICAgICAgdGhpcy5hbm5vdGF0aW9uQ2FudmFzLnNhdmVkQ3R4ID0gdGhpcy5jdHg7XG4gICAgICAgIHRoaXMuY3R4ID0gY29udGV4dDtcbiAgICAgICAgdGhpcy5jdHguc2V0VHJhbnNmb3JtKHNjYWxlWCwgMCwgMCwgLXNjYWxlWSwgMCwgaGVpZ2h0ICogc2NhbGVZKTtcbiAgICAgICAgYWRkQ29udGV4dEN1cnJlbnRUcmFuc2Zvcm0odGhpcy5jdHgpO1xuICAgICAgICByZXNldEN0eFRvRGVmYXVsdCh0aGlzLmN0eCwgdGhpcy5mb3JlZ3JvdW5kQ29sb3IpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzZXRDdHhUb0RlZmF1bHQodGhpcy5jdHgsIHRoaXMuZm9yZWdyb3VuZENvbG9yKTtcbiAgICAgICAgdGhpcy5jdHgucmVjdChyZWN0WzBdLCByZWN0WzFdLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICAgICAgdGhpcy5jdHguY2xpcCgpO1xuICAgICAgICB0aGlzLmVuZFBhdGgoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmN1cnJlbnQgPSBuZXcgQ2FudmFzRXh0cmFTdGF0ZSh0aGlzLmN0eC5jYW52YXMud2lkdGgsIHRoaXMuY3R4LmNhbnZhcy5oZWlnaHQpO1xuICAgIHRoaXMudHJhbnNmb3JtLmFwcGx5KHRoaXMsIHRyYW5zZm9ybSk7XG4gICAgdGhpcy50cmFuc2Zvcm0uYXBwbHkodGhpcywgbWF0cml4KTtcbiAgfVxuXG4gIGVuZEFubm90YXRpb24oKSB7XG4gICAgaWYgKHRoaXMuYW5ub3RhdGlvbkNhbnZhcykge1xuICAgICAgdGhpcy5jdHggPSB0aGlzLmFubm90YXRpb25DYW52YXMuc2F2ZWRDdHg7XG4gICAgICBkZWxldGUgdGhpcy5hbm5vdGF0aW9uQ2FudmFzLnNhdmVkQ3R4O1xuICAgICAgZGVsZXRlIHRoaXMuYW5ub3RhdGlvbkNhbnZhcztcbiAgICB9XG5cbiAgICB0aGlzLnJlc3RvcmUoKTtcbiAgfVxuXG4gIHBhaW50SW1hZ2VNYXNrWE9iamVjdChpbWcpIHtcbiAgICBpZiAoIXRoaXMuY29udGVudFZpc2libGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjb3VudCA9IGltZy5jb3VudDtcbiAgICBpbWcgPSB0aGlzLmdldE9iamVjdChpbWcuZGF0YSwgaW1nKTtcbiAgICBpbWcuY291bnQgPSBjb3VudDtcbiAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcbiAgICBjb25zdCBnbHlwaCA9IHRoaXMucHJvY2Vzc2luZ1R5cGUzO1xuXG4gICAgaWYgKGdseXBoKSB7XG4gICAgICBpZiAoZ2x5cGguY29tcGlsZWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBnbHlwaC5jb21waWxlZCA9IGNvbXBpbGVUeXBlM0dseXBoKGltZyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChnbHlwaC5jb21waWxlZCkge1xuICAgICAgICBnbHlwaC5jb21waWxlZChjdHgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgbWFzayA9IHRoaXMuX2NyZWF0ZU1hc2tDYW52YXMoaW1nKTtcblxuICAgIGNvbnN0IG1hc2tDYW52YXMgPSBtYXNrLmNhbnZhcztcbiAgICBjdHguc2F2ZSgpO1xuICAgIGN0eC5zZXRUcmFuc2Zvcm0oMSwgMCwgMCwgMSwgMCwgMCk7XG4gICAgY3R4LmRyYXdJbWFnZShtYXNrQ2FudmFzLCBtYXNrLm9mZnNldFgsIG1hc2sub2Zmc2V0WSk7XG4gICAgY3R4LnJlc3RvcmUoKTtcbiAgICB0aGlzLmNvbXBvc2UoKTtcbiAgfVxuXG4gIHBhaW50SW1hZ2VNYXNrWE9iamVjdFJlcGVhdChpbWcsIHNjYWxlWCwgc2tld1ggPSAwLCBza2V3WSA9IDAsIHNjYWxlWSwgcG9zaXRpb25zKSB7XG4gICAgaWYgKCF0aGlzLmNvbnRlbnRWaXNpYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaW1nID0gdGhpcy5nZXRPYmplY3QoaW1nLmRhdGEsIGltZyk7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY3R4LnNhdmUoKTtcbiAgICBjb25zdCBjdXJyZW50VHJhbnNmb3JtID0gY3R4Lm1vekN1cnJlbnRUcmFuc2Zvcm07XG4gICAgY3R4LnRyYW5zZm9ybShzY2FsZVgsIHNrZXdYLCBza2V3WSwgc2NhbGVZLCAwLCAwKTtcblxuICAgIGNvbnN0IG1hc2sgPSB0aGlzLl9jcmVhdGVNYXNrQ2FudmFzKGltZyk7XG5cbiAgICBjdHguc2V0VHJhbnNmb3JtKDEsIDAsIDAsIDEsIDAsIDApO1xuXG4gICAgZm9yIChsZXQgaSA9IDAsIGlpID0gcG9zaXRpb25zLmxlbmd0aDsgaSA8IGlpOyBpICs9IDIpIHtcbiAgICAgIGNvbnN0IHRyYW5zID0gX3V0aWwuVXRpbC50cmFuc2Zvcm0oY3VycmVudFRyYW5zZm9ybSwgW3NjYWxlWCwgc2tld1gsIHNrZXdZLCBzY2FsZVksIHBvc2l0aW9uc1tpXSwgcG9zaXRpb25zW2kgKyAxXV0pO1xuXG4gICAgICBjb25zdCBbeCwgeV0gPSBfdXRpbC5VdGlsLmFwcGx5VHJhbnNmb3JtKFswLCAwXSwgdHJhbnMpO1xuXG4gICAgICBjdHguZHJhd0ltYWdlKG1hc2suY2FudmFzLCB4LCB5KTtcbiAgICB9XG5cbiAgICBjdHgucmVzdG9yZSgpO1xuICAgIHRoaXMuY29tcG9zZSgpO1xuICB9XG5cbiAgcGFpbnRJbWFnZU1hc2tYT2JqZWN0R3JvdXAoaW1hZ2VzKSB7XG4gICAgaWYgKCF0aGlzLmNvbnRlbnRWaXNpYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY29uc3QgZmlsbENvbG9yID0gdGhpcy5jdXJyZW50LmZpbGxDb2xvcjtcbiAgICBjb25zdCBpc1BhdHRlcm5GaWxsID0gdGhpcy5jdXJyZW50LnBhdHRlcm5GaWxsO1xuXG4gICAgZm9yIChsZXQgaSA9IDAsIGlpID0gaW1hZ2VzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgIGNvbnN0IGltYWdlID0gaW1hZ2VzW2ldO1xuICAgICAgY29uc3Qgd2lkdGggPSBpbWFnZS53aWR0aCxcbiAgICAgICAgICAgIGhlaWdodCA9IGltYWdlLmhlaWdodDtcbiAgICAgIGNvbnN0IG1hc2tDYW52YXMgPSB0aGlzLmNhY2hlZENhbnZhc2VzLmdldENhbnZhcyhcIm1hc2tDYW52YXNcIiwgd2lkdGgsIGhlaWdodCwgZmFsc2UpO1xuICAgICAgY29uc3QgbWFza0N0eCA9IG1hc2tDYW52YXMuY29udGV4dDtcbiAgICAgIG1hc2tDdHguc2F2ZSgpO1xuICAgICAgcHV0QmluYXJ5SW1hZ2VNYXNrKG1hc2tDdHgsIGltYWdlKTtcbiAgICAgIG1hc2tDdHguZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uID0gXCJzb3VyY2UtaW5cIjtcbiAgICAgIG1hc2tDdHguZmlsbFN0eWxlID0gaXNQYXR0ZXJuRmlsbCA/IGZpbGxDb2xvci5nZXRQYXR0ZXJuKG1hc2tDdHgsIHRoaXMsIGN0eC5tb3pDdXJyZW50VHJhbnNmb3JtSW52ZXJzZSwgX3BhdHRlcm5faGVscGVyLlBhdGhUeXBlLkZJTEwpIDogZmlsbENvbG9yO1xuICAgICAgbWFza0N0eC5maWxsUmVjdCgwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICAgIG1hc2tDdHgucmVzdG9yZSgpO1xuICAgICAgY3R4LnNhdmUoKTtcbiAgICAgIGN0eC50cmFuc2Zvcm0uYXBwbHkoY3R4LCBpbWFnZS50cmFuc2Zvcm0pO1xuICAgICAgY3R4LnNjYWxlKDEsIC0xKTtcbiAgICAgIGRyYXdJbWFnZUF0SW50ZWdlckNvb3JkcyhjdHgsIG1hc2tDYW52YXMuY2FudmFzLCAwLCAwLCB3aWR0aCwgaGVpZ2h0LCAwLCAtMSwgMSwgMSk7XG4gICAgICBjdHgucmVzdG9yZSgpO1xuICAgIH1cblxuICAgIHRoaXMuY29tcG9zZSgpO1xuICB9XG5cbiAgcGFpbnRJbWFnZVhPYmplY3Qob2JqSWQpIHtcbiAgICBpZiAoIXRoaXMuY29udGVudFZpc2libGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBpbWdEYXRhID0gdGhpcy5nZXRPYmplY3Qob2JqSWQpO1xuXG4gICAgaWYgKCFpbWdEYXRhKSB7XG4gICAgICAoMCwgX3V0aWwud2FybikoXCJEZXBlbmRlbnQgaW1hZ2UgaXNuJ3QgcmVhZHkgeWV0XCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMucGFpbnRJbmxpbmVJbWFnZVhPYmplY3QoaW1nRGF0YSk7XG4gIH1cblxuICBwYWludEltYWdlWE9iamVjdFJlcGVhdChvYmpJZCwgc2NhbGVYLCBzY2FsZVksIHBvc2l0aW9ucykge1xuICAgIGlmICghdGhpcy5jb250ZW50VmlzaWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGltZ0RhdGEgPSB0aGlzLmdldE9iamVjdChvYmpJZCk7XG5cbiAgICBpZiAoIWltZ0RhdGEpIHtcbiAgICAgICgwLCBfdXRpbC53YXJuKShcIkRlcGVuZGVudCBpbWFnZSBpc24ndCByZWFkeSB5ZXRcIik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgd2lkdGggPSBpbWdEYXRhLndpZHRoO1xuICAgIGNvbnN0IGhlaWdodCA9IGltZ0RhdGEuaGVpZ2h0O1xuICAgIGNvbnN0IG1hcCA9IFtdO1xuXG4gICAgZm9yIChsZXQgaSA9IDAsIGlpID0gcG9zaXRpb25zLmxlbmd0aDsgaSA8IGlpOyBpICs9IDIpIHtcbiAgICAgIG1hcC5wdXNoKHtcbiAgICAgICAgdHJhbnNmb3JtOiBbc2NhbGVYLCAwLCAwLCBzY2FsZVksIHBvc2l0aW9uc1tpXSwgcG9zaXRpb25zW2kgKyAxXV0sXG4gICAgICAgIHg6IDAsXG4gICAgICAgIHk6IDAsXG4gICAgICAgIHc6IHdpZHRoLFxuICAgICAgICBoOiBoZWlnaHRcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMucGFpbnRJbmxpbmVJbWFnZVhPYmplY3RHcm91cChpbWdEYXRhLCBtYXApO1xuICB9XG5cbiAgcGFpbnRJbmxpbmVJbWFnZVhPYmplY3QoaW1nRGF0YSkge1xuICAgIGlmICghdGhpcy5jb250ZW50VmlzaWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHdpZHRoID0gaW1nRGF0YS53aWR0aDtcbiAgICBjb25zdCBoZWlnaHQgPSBpbWdEYXRhLmhlaWdodDtcbiAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcbiAgICB0aGlzLnNhdmUoKTtcbiAgICBjdHguc2NhbGUoMSAvIHdpZHRoLCAtMSAvIGhlaWdodCk7XG4gICAgbGV0IGltZ1RvUGFpbnQ7XG5cbiAgICBpZiAodHlwZW9mIEhUTUxFbGVtZW50ID09PSBcImZ1bmN0aW9uXCIgJiYgaW1nRGF0YSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50IHx8ICFpbWdEYXRhLmRhdGEpIHtcbiAgICAgIGltZ1RvUGFpbnQgPSBpbWdEYXRhO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB0bXBDYW52YXMgPSB0aGlzLmNhY2hlZENhbnZhc2VzLmdldENhbnZhcyhcImlubGluZUltYWdlXCIsIHdpZHRoLCBoZWlnaHQsIGZhbHNlKTtcbiAgICAgIGNvbnN0IHRtcEN0eCA9IHRtcENhbnZhcy5jb250ZXh0O1xuICAgICAgcHV0QmluYXJ5SW1hZ2VEYXRhKHRtcEN0eCwgaW1nRGF0YSwgdGhpcy5jdXJyZW50LnRyYW5zZmVyTWFwcyk7XG4gICAgICBpbWdUb1BhaW50ID0gdG1wQ2FudmFzLmNhbnZhcztcbiAgICB9XG5cbiAgICBjb25zdCBzY2FsZWQgPSB0aGlzLl9zY2FsZUltYWdlKGltZ1RvUGFpbnQsIGN0eC5tb3pDdXJyZW50VHJhbnNmb3JtSW52ZXJzZSk7XG5cbiAgICBjdHguaW1hZ2VTbW9vdGhpbmdFbmFibGVkID0gZ2V0SW1hZ2VTbW9vdGhpbmdFbmFibGVkKGN0eC5tb3pDdXJyZW50VHJhbnNmb3JtLCBpbWdEYXRhLmludGVycG9sYXRlKTtcbiAgICBjb25zdCBbcldpZHRoLCBySGVpZ2h0XSA9IGRyYXdJbWFnZUF0SW50ZWdlckNvb3JkcyhjdHgsIHNjYWxlZC5pbWcsIDAsIDAsIHNjYWxlZC5wYWludFdpZHRoLCBzY2FsZWQucGFpbnRIZWlnaHQsIDAsIC1oZWlnaHQsIHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgaWYgKHRoaXMuaW1hZ2VMYXllcikge1xuICAgICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmdldENhbnZhc1Bvc2l0aW9uKDAsIC1oZWlnaHQpO1xuICAgICAgdGhpcy5pbWFnZUxheWVyLmFwcGVuZEltYWdlKHtcbiAgICAgICAgaW1nRGF0YSxcbiAgICAgICAgbGVmdDogcG9zaXRpb25bMF0sXG4gICAgICAgIHRvcDogcG9zaXRpb25bMV0sXG4gICAgICAgIHdpZHRoOiByV2lkdGgsXG4gICAgICAgIGhlaWdodDogckhlaWdodFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5jb21wb3NlKCk7XG4gICAgdGhpcy5yZXN0b3JlKCk7XG4gIH1cblxuICBwYWludElubGluZUltYWdlWE9iamVjdEdyb3VwKGltZ0RhdGEsIG1hcCkge1xuICAgIGlmICghdGhpcy5jb250ZW50VmlzaWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGN0eCA9IHRoaXMuY3R4O1xuICAgIGNvbnN0IHcgPSBpbWdEYXRhLndpZHRoO1xuICAgIGNvbnN0IGggPSBpbWdEYXRhLmhlaWdodDtcbiAgICBjb25zdCB0bXBDYW52YXMgPSB0aGlzLmNhY2hlZENhbnZhc2VzLmdldENhbnZhcyhcImlubGluZUltYWdlXCIsIHcsIGgsIGZhbHNlKTtcbiAgICBjb25zdCB0bXBDdHggPSB0bXBDYW52YXMuY29udGV4dDtcbiAgICBwdXRCaW5hcnlJbWFnZURhdGEodG1wQ3R4LCBpbWdEYXRhLCB0aGlzLmN1cnJlbnQudHJhbnNmZXJNYXBzKTtcblxuICAgIGZvciAobGV0IGkgPSAwLCBpaSA9IG1hcC5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICBjb25zdCBlbnRyeSA9IG1hcFtpXTtcbiAgICAgIGN0eC5zYXZlKCk7XG4gICAgICBjdHgudHJhbnNmb3JtLmFwcGx5KGN0eCwgZW50cnkudHJhbnNmb3JtKTtcbiAgICAgIGN0eC5zY2FsZSgxLCAtMSk7XG4gICAgICBkcmF3SW1hZ2VBdEludGVnZXJDb29yZHMoY3R4LCB0bXBDYW52YXMuY2FudmFzLCBlbnRyeS54LCBlbnRyeS55LCBlbnRyeS53LCBlbnRyeS5oLCAwLCAtMSwgMSwgMSk7XG5cbiAgICAgIGlmICh0aGlzLmltYWdlTGF5ZXIpIHtcbiAgICAgICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmdldENhbnZhc1Bvc2l0aW9uKGVudHJ5LngsIGVudHJ5LnkpO1xuICAgICAgICB0aGlzLmltYWdlTGF5ZXIuYXBwZW5kSW1hZ2Uoe1xuICAgICAgICAgIGltZ0RhdGEsXG4gICAgICAgICAgbGVmdDogcG9zaXRpb25bMF0sXG4gICAgICAgICAgdG9wOiBwb3NpdGlvblsxXSxcbiAgICAgICAgICB3aWR0aDogdyxcbiAgICAgICAgICBoZWlnaHQ6IGhcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgfVxuXG4gICAgdGhpcy5jb21wb3NlKCk7XG4gIH1cblxuICBwYWludFNvbGlkQ29sb3JJbWFnZU1hc2soKSB7XG4gICAgaWYgKCF0aGlzLmNvbnRlbnRWaXNpYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5jdHguZmlsbFJlY3QoMCwgMCwgMSwgMSk7XG4gICAgdGhpcy5jb21wb3NlKCk7XG4gIH1cblxuICBtYXJrUG9pbnQodGFnKSB7fVxuXG4gIG1hcmtQb2ludFByb3BzKHRhZywgcHJvcGVydGllcykge31cblxuICBiZWdpbk1hcmtlZENvbnRlbnQodGFnKSB7XG4gICAgdGhpcy5tYXJrZWRDb250ZW50U3RhY2sucHVzaCh7XG4gICAgICB2aXNpYmxlOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICBiZWdpbk1hcmtlZENvbnRlbnRQcm9wcyh0YWcsIHByb3BlcnRpZXMpIHtcbiAgICBpZiAodGFnID09PSBcIk9DXCIpIHtcbiAgICAgIHRoaXMubWFya2VkQ29udGVudFN0YWNrLnB1c2goe1xuICAgICAgICB2aXNpYmxlOiB0aGlzLm9wdGlvbmFsQ29udGVudENvbmZpZy5pc1Zpc2libGUocHJvcGVydGllcylcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1hcmtlZENvbnRlbnRTdGFjay5wdXNoKHtcbiAgICAgICAgdmlzaWJsZTogdHJ1ZVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5jb250ZW50VmlzaWJsZSA9IHRoaXMuaXNDb250ZW50VmlzaWJsZSgpO1xuICB9XG5cbiAgZW5kTWFya2VkQ29udGVudCgpIHtcbiAgICB0aGlzLm1hcmtlZENvbnRlbnRTdGFjay5wb3AoKTtcbiAgICB0aGlzLmNvbnRlbnRWaXNpYmxlID0gdGhpcy5pc0NvbnRlbnRWaXNpYmxlKCk7XG4gIH1cblxuICBiZWdpbkNvbXBhdCgpIHt9XG5cbiAgZW5kQ29tcGF0KCkge31cblxuICBjb25zdW1lUGF0aChjbGlwQm94KSB7XG4gICAgY29uc3QgaXNFbXB0eSA9IHRoaXMuY3VycmVudC5pc0VtcHR5Q2xpcCgpO1xuXG4gICAgaWYgKHRoaXMucGVuZGluZ0NsaXApIHtcbiAgICAgIHRoaXMuY3VycmVudC51cGRhdGVDbGlwRnJvbVBhdGgoKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMucGVuZGluZ0NsaXApIHtcbiAgICAgIHRoaXMuY29tcG9zZShjbGlwQm94KTtcbiAgICB9XG5cbiAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcblxuICAgIGlmICh0aGlzLnBlbmRpbmdDbGlwKSB7XG4gICAgICBpZiAoIWlzRW1wdHkpIHtcbiAgICAgICAgaWYgKHRoaXMucGVuZGluZ0NsaXAgPT09IEVPX0NMSVApIHtcbiAgICAgICAgICBjdHguY2xpcChcImV2ZW5vZGRcIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY3R4LmNsaXAoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLnBlbmRpbmdDbGlwID0gbnVsbDtcbiAgICB9XG5cbiAgICB0aGlzLmN1cnJlbnQuc3RhcnROZXdQYXRoQW5kQ2xpcEJveCh0aGlzLmN1cnJlbnQuY2xpcEJveCk7XG4gICAgY3R4LmJlZ2luUGF0aCgpO1xuICB9XG5cbiAgZ2V0U2luZ2xlUGl4ZWxXaWR0aCgpIHtcbiAgICBpZiAoIXRoaXMuX2NhY2hlZEdldFNpbmdsZVBpeGVsV2lkdGgpIHtcbiAgICAgIGNvbnN0IG0gPSB0aGlzLmN0eC5tb3pDdXJyZW50VHJhbnNmb3JtO1xuXG4gICAgICBpZiAobVsxXSA9PT0gMCAmJiBtWzJdID09PSAwKSB7XG4gICAgICAgIHRoaXMuX2NhY2hlZEdldFNpbmdsZVBpeGVsV2lkdGggPSAxIC8gTWF0aC5taW4oTWF0aC5hYnMobVswXSksIE1hdGguYWJzKG1bM10pKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGFic0RldCA9IE1hdGguYWJzKG1bMF0gKiBtWzNdIC0gbVsyXSAqIG1bMV0pO1xuICAgICAgICBjb25zdCBub3JtWCA9IE1hdGguaHlwb3QobVswXSwgbVsyXSk7XG4gICAgICAgIGNvbnN0IG5vcm1ZID0gTWF0aC5oeXBvdChtWzFdLCBtWzNdKTtcbiAgICAgICAgdGhpcy5fY2FjaGVkR2V0U2luZ2xlUGl4ZWxXaWR0aCA9IE1hdGgubWF4KG5vcm1YLCBub3JtWSkgLyBhYnNEZXQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2NhY2hlZEdldFNpbmdsZVBpeGVsV2lkdGg7XG4gIH1cblxuICBnZXRTY2FsZUZvclN0cm9raW5nKCkge1xuICAgIGlmICghdGhpcy5fY2FjaGVkU2NhbGVGb3JTdHJva2luZykge1xuICAgICAgY29uc3Qge1xuICAgICAgICBsaW5lV2lkdGhcbiAgICAgIH0gPSB0aGlzLmN1cnJlbnQ7XG4gICAgICBjb25zdCBtID0gdGhpcy5jdHgubW96Q3VycmVudFRyYW5zZm9ybTtcbiAgICAgIGxldCBzY2FsZVgsIHNjYWxlWTtcblxuICAgICAgaWYgKG1bMV0gPT09IDAgJiYgbVsyXSA9PT0gMCkge1xuICAgICAgICBjb25zdCBub3JtWCA9IE1hdGguYWJzKG1bMF0pO1xuICAgICAgICBjb25zdCBub3JtWSA9IE1hdGguYWJzKG1bM10pO1xuXG4gICAgICAgIGlmIChsaW5lV2lkdGggPT09IDApIHtcbiAgICAgICAgICBzY2FsZVggPSAxIC8gbm9ybVg7XG4gICAgICAgICAgc2NhbGVZID0gMSAvIG5vcm1ZO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IHNjYWxlZFhMaW5lV2lkdGggPSBub3JtWCAqIGxpbmVXaWR0aDtcbiAgICAgICAgICBjb25zdCBzY2FsZWRZTGluZVdpZHRoID0gbm9ybVkgKiBsaW5lV2lkdGg7XG4gICAgICAgICAgc2NhbGVYID0gc2NhbGVkWExpbmVXaWR0aCA8IDEgPyAxIC8gc2NhbGVkWExpbmVXaWR0aCA6IDE7XG4gICAgICAgICAgc2NhbGVZID0gc2NhbGVkWUxpbmVXaWR0aCA8IDEgPyAxIC8gc2NhbGVkWUxpbmVXaWR0aCA6IDE7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGFic0RldCA9IE1hdGguYWJzKG1bMF0gKiBtWzNdIC0gbVsyXSAqIG1bMV0pO1xuICAgICAgICBjb25zdCBub3JtWCA9IE1hdGguaHlwb3QobVswXSwgbVsxXSk7XG4gICAgICAgIGNvbnN0IG5vcm1ZID0gTWF0aC5oeXBvdChtWzJdLCBtWzNdKTtcblxuICAgICAgICBpZiAobGluZVdpZHRoID09PSAwKSB7XG4gICAgICAgICAgc2NhbGVYID0gbm9ybVkgLyBhYnNEZXQ7XG4gICAgICAgICAgc2NhbGVZID0gbm9ybVggLyBhYnNEZXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgYmFzZUFyZWEgPSBsaW5lV2lkdGggKiBhYnNEZXQ7XG4gICAgICAgICAgc2NhbGVYID0gbm9ybVkgPiBiYXNlQXJlYSA/IG5vcm1ZIC8gYmFzZUFyZWEgOiAxO1xuICAgICAgICAgIHNjYWxlWSA9IG5vcm1YID4gYmFzZUFyZWEgPyBub3JtWCAvIGJhc2VBcmVhIDogMTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLl9jYWNoZWRTY2FsZUZvclN0cm9raW5nID0gW3NjYWxlWCwgc2NhbGVZXTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fY2FjaGVkU2NhbGVGb3JTdHJva2luZztcbiAgfVxuXG4gIHJlc2NhbGVBbmRTdHJva2Uoc2F2ZVJlc3RvcmUpIHtcbiAgICBjb25zdCB7XG4gICAgICBjdHhcbiAgICB9ID0gdGhpcztcbiAgICBjb25zdCB7XG4gICAgICBsaW5lV2lkdGhcbiAgICB9ID0gdGhpcy5jdXJyZW50O1xuICAgIGNvbnN0IFtzY2FsZVgsIHNjYWxlWV0gPSB0aGlzLmdldFNjYWxlRm9yU3Ryb2tpbmcoKTtcbiAgICBjdHgubGluZVdpZHRoID0gbGluZVdpZHRoIHx8IDE7XG5cbiAgICBpZiAoc2NhbGVYID09PSAxICYmIHNjYWxlWSA9PT0gMSkge1xuICAgICAgY3R4LnN0cm9rZSgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBzYXZlZE1hdHJpeCwgc2F2ZWREYXNoZXMsIHNhdmVkRGFzaE9mZnNldDtcblxuICAgIGlmIChzYXZlUmVzdG9yZSkge1xuICAgICAgc2F2ZWRNYXRyaXggPSBjdHgubW96Q3VycmVudFRyYW5zZm9ybS5zbGljZSgpO1xuICAgICAgc2F2ZWREYXNoZXMgPSBjdHguZ2V0TGluZURhc2goKS5zbGljZSgpO1xuICAgICAgc2F2ZWREYXNoT2Zmc2V0ID0gY3R4LmxpbmVEYXNoT2Zmc2V0O1xuICAgIH1cblxuICAgIGN0eC5zY2FsZShzY2FsZVgsIHNjYWxlWSk7XG4gICAgY29uc3Qgc2NhbGUgPSBNYXRoLm1heChzY2FsZVgsIHNjYWxlWSk7XG4gICAgY3R4LnNldExpbmVEYXNoKGN0eC5nZXRMaW5lRGFzaCgpLm1hcCh4ID0+IHggLyBzY2FsZSkpO1xuICAgIGN0eC5saW5lRGFzaE9mZnNldCAvPSBzY2FsZTtcbiAgICBjdHguc3Ryb2tlKCk7XG5cbiAgICBpZiAoc2F2ZVJlc3RvcmUpIHtcbiAgICAgIGN0eC5zZXRUcmFuc2Zvcm0oLi4uc2F2ZWRNYXRyaXgpO1xuICAgICAgY3R4LnNldExpbmVEYXNoKHNhdmVkRGFzaGVzKTtcbiAgICAgIGN0eC5saW5lRGFzaE9mZnNldCA9IHNhdmVkRGFzaE9mZnNldDtcbiAgICB9XG4gIH1cblxuICBnZXRDYW52YXNQb3NpdGlvbih4LCB5KSB7XG4gICAgY29uc3QgdHJhbnNmb3JtID0gdGhpcy5jdHgubW96Q3VycmVudFRyYW5zZm9ybTtcbiAgICByZXR1cm4gW3RyYW5zZm9ybVswXSAqIHggKyB0cmFuc2Zvcm1bMl0gKiB5ICsgdHJhbnNmb3JtWzRdLCB0cmFuc2Zvcm1bMV0gKiB4ICsgdHJhbnNmb3JtWzNdICogeSArIHRyYW5zZm9ybVs1XV07XG4gIH1cblxuICBpc0NvbnRlbnRWaXNpYmxlKCkge1xuICAgIGZvciAobGV0IGkgPSB0aGlzLm1hcmtlZENvbnRlbnRTdGFjay5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgaWYgKCF0aGlzLm1hcmtlZENvbnRlbnRTdGFja1tpXS52aXNpYmxlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG59XG5cbmV4cG9ydHMuQ2FudmFzR3JhcGhpY3MgPSBDYW52YXNHcmFwaGljcztcblxuZm9yIChjb25zdCBvcCBpbiBfdXRpbC5PUFMpIHtcbiAgaWYgKENhbnZhc0dyYXBoaWNzLnByb3RvdHlwZVtvcF0gIT09IHVuZGVmaW5lZCkge1xuICAgIENhbnZhc0dyYXBoaWNzLnByb3RvdHlwZVtfdXRpbC5PUFNbb3BdXSA9IENhbnZhc0dyYXBoaWNzLnByb3RvdHlwZVtvcF07XG4gIH1cbn1cblxuLyoqKi8gfSksXG4vKiAxMSAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5UaWxpbmdQYXR0ZXJuID0gZXhwb3J0cy5QYXRoVHlwZSA9IHZvaWQgMDtcbmV4cG9ydHMuZ2V0U2hhZGluZ1BhdHRlcm4gPSBnZXRTaGFkaW5nUGF0dGVybjtcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxudmFyIF9pc19ub2RlID0gX193X3BkZmpzX3JlcXVpcmVfXygzKTtcblxuY29uc3QgUGF0aFR5cGUgPSB7XG4gIEZJTEw6IFwiRmlsbFwiLFxuICBTVFJPS0U6IFwiU3Ryb2tlXCIsXG4gIFNIQURJTkc6IFwiU2hhZGluZ1wiXG59O1xuZXhwb3J0cy5QYXRoVHlwZSA9IFBhdGhUeXBlO1xuXG5mdW5jdGlvbiBhcHBseUJvdW5kaW5nQm94KGN0eCwgYmJveCkge1xuICBpZiAoIWJib3ggfHwgX2lzX25vZGUuaXNOb2RlSlMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCB3aWR0aCA9IGJib3hbMl0gLSBiYm94WzBdO1xuICBjb25zdCBoZWlnaHQgPSBiYm94WzNdIC0gYmJveFsxXTtcbiAgY29uc3QgcmVnaW9uID0gbmV3IFBhdGgyRCgpO1xuICByZWdpb24ucmVjdChiYm94WzBdLCBiYm94WzFdLCB3aWR0aCwgaGVpZ2h0KTtcbiAgY3R4LmNsaXAocmVnaW9uKTtcbn1cblxuY2xhc3MgQmFzZVNoYWRpbmdQYXR0ZXJuIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgaWYgKHRoaXMuY29uc3RydWN0b3IgPT09IEJhc2VTaGFkaW5nUGF0dGVybikge1xuICAgICAgKDAsIF91dGlsLnVucmVhY2hhYmxlKShcIkNhbm5vdCBpbml0aWFsaXplIEJhc2VTaGFkaW5nUGF0dGVybi5cIik7XG4gICAgfVxuICB9XG5cbiAgZ2V0UGF0dGVybigpIHtcbiAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiQWJzdHJhY3QgbWV0aG9kIGBnZXRQYXR0ZXJuYCBjYWxsZWQuXCIpO1xuICB9XG5cbn1cblxuY2xhc3MgUmFkaWFsQXhpYWxTaGFkaW5nUGF0dGVybiBleHRlbmRzIEJhc2VTaGFkaW5nUGF0dGVybiB7XG4gIGNvbnN0cnVjdG9yKElSKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLl90eXBlID0gSVJbMV07XG4gICAgdGhpcy5fYmJveCA9IElSWzJdO1xuICAgIHRoaXMuX2NvbG9yU3RvcHMgPSBJUlszXTtcbiAgICB0aGlzLl9wMCA9IElSWzRdO1xuICAgIHRoaXMuX3AxID0gSVJbNV07XG4gICAgdGhpcy5fcjAgPSBJUls2XTtcbiAgICB0aGlzLl9yMSA9IElSWzddO1xuICAgIHRoaXMubWF0cml4ID0gbnVsbDtcbiAgfVxuXG4gIF9jcmVhdGVHcmFkaWVudChjdHgpIHtcbiAgICBsZXQgZ3JhZDtcblxuICAgIGlmICh0aGlzLl90eXBlID09PSBcImF4aWFsXCIpIHtcbiAgICAgIGdyYWQgPSBjdHguY3JlYXRlTGluZWFyR3JhZGllbnQodGhpcy5fcDBbMF0sIHRoaXMuX3AwWzFdLCB0aGlzLl9wMVswXSwgdGhpcy5fcDFbMV0pO1xuICAgIH0gZWxzZSBpZiAodGhpcy5fdHlwZSA9PT0gXCJyYWRpYWxcIikge1xuICAgICAgZ3JhZCA9IGN0eC5jcmVhdGVSYWRpYWxHcmFkaWVudCh0aGlzLl9wMFswXSwgdGhpcy5fcDBbMV0sIHRoaXMuX3IwLCB0aGlzLl9wMVswXSwgdGhpcy5fcDFbMV0sIHRoaXMuX3IxKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGNvbG9yU3RvcCBvZiB0aGlzLl9jb2xvclN0b3BzKSB7XG4gICAgICBncmFkLmFkZENvbG9yU3RvcChjb2xvclN0b3BbMF0sIGNvbG9yU3RvcFsxXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGdyYWQ7XG4gIH1cblxuICBnZXRQYXR0ZXJuKGN0eCwgb3duZXIsIGludmVyc2UsIHBhdGhUeXBlKSB7XG4gICAgbGV0IHBhdHRlcm47XG5cbiAgICBpZiAocGF0aFR5cGUgPT09IFBhdGhUeXBlLlNUUk9LRSB8fCBwYXRoVHlwZSA9PT0gUGF0aFR5cGUuRklMTCkge1xuICAgICAgY29uc3Qgb3duZXJCQm94ID0gb3duZXIuY3VycmVudC5nZXRDbGlwcGVkUGF0aEJvdW5kaW5nQm94KHBhdGhUeXBlLCBjdHgubW96Q3VycmVudFRyYW5zZm9ybSkgfHwgWzAsIDAsIDAsIDBdO1xuICAgICAgY29uc3Qgd2lkdGggPSBNYXRoLmNlaWwob3duZXJCQm94WzJdIC0gb3duZXJCQm94WzBdKSB8fCAxO1xuICAgICAgY29uc3QgaGVpZ2h0ID0gTWF0aC5jZWlsKG93bmVyQkJveFszXSAtIG93bmVyQkJveFsxXSkgfHwgMTtcbiAgICAgIGNvbnN0IHRtcENhbnZhcyA9IG93bmVyLmNhY2hlZENhbnZhc2VzLmdldENhbnZhcyhcInBhdHRlcm5cIiwgd2lkdGgsIGhlaWdodCwgdHJ1ZSk7XG4gICAgICBjb25zdCB0bXBDdHggPSB0bXBDYW52YXMuY29udGV4dDtcbiAgICAgIHRtcEN0eC5jbGVhclJlY3QoMCwgMCwgdG1wQ3R4LmNhbnZhcy53aWR0aCwgdG1wQ3R4LmNhbnZhcy5oZWlnaHQpO1xuICAgICAgdG1wQ3R4LmJlZ2luUGF0aCgpO1xuICAgICAgdG1wQ3R4LnJlY3QoMCwgMCwgdG1wQ3R4LmNhbnZhcy53aWR0aCwgdG1wQ3R4LmNhbnZhcy5oZWlnaHQpO1xuICAgICAgdG1wQ3R4LnRyYW5zbGF0ZSgtb3duZXJCQm94WzBdLCAtb3duZXJCQm94WzFdKTtcbiAgICAgIGludmVyc2UgPSBfdXRpbC5VdGlsLnRyYW5zZm9ybShpbnZlcnNlLCBbMSwgMCwgMCwgMSwgb3duZXJCQm94WzBdLCBvd25lckJCb3hbMV1dKTtcbiAgICAgIHRtcEN0eC50cmFuc2Zvcm0uYXBwbHkodG1wQ3R4LCBvd25lci5iYXNlVHJhbnNmb3JtKTtcblxuICAgICAgaWYgKHRoaXMubWF0cml4KSB7XG4gICAgICAgIHRtcEN0eC50cmFuc2Zvcm0uYXBwbHkodG1wQ3R4LCB0aGlzLm1hdHJpeCk7XG4gICAgICB9XG5cbiAgICAgIGFwcGx5Qm91bmRpbmdCb3godG1wQ3R4LCB0aGlzLl9iYm94KTtcbiAgICAgIHRtcEN0eC5maWxsU3R5bGUgPSB0aGlzLl9jcmVhdGVHcmFkaWVudCh0bXBDdHgpO1xuICAgICAgdG1wQ3R4LmZpbGwoKTtcbiAgICAgIHBhdHRlcm4gPSBjdHguY3JlYXRlUGF0dGVybih0bXBDYW52YXMuY2FudmFzLCBcIm5vLXJlcGVhdFwiKTtcbiAgICAgIGNvbnN0IGRvbU1hdHJpeCA9IG5ldyBET01NYXRyaXgoaW52ZXJzZSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHBhdHRlcm4uc2V0VHJhbnNmb3JtKGRvbU1hdHJpeCk7XG4gICAgICB9IGNhdGNoIChleCkge1xuICAgICAgICAoMCwgX3V0aWwud2FybikoYFJhZGlhbEF4aWFsU2hhZGluZ1BhdHRlcm4uZ2V0UGF0dGVybjogXCIke2V4Py5tZXNzYWdlfVwiLmApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBhcHBseUJvdW5kaW5nQm94KGN0eCwgdGhpcy5fYmJveCk7XG4gICAgICBwYXR0ZXJuID0gdGhpcy5fY3JlYXRlR3JhZGllbnQoY3R4KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGF0dGVybjtcbiAgfVxuXG59XG5cbmZ1bmN0aW9uIGRyYXdUcmlhbmdsZShkYXRhLCBjb250ZXh0LCBwMSwgcDIsIHAzLCBjMSwgYzIsIGMzKSB7XG4gIGNvbnN0IGNvb3JkcyA9IGNvbnRleHQuY29vcmRzLFxuICAgICAgICBjb2xvcnMgPSBjb250ZXh0LmNvbG9ycztcbiAgY29uc3QgYnl0ZXMgPSBkYXRhLmRhdGEsXG4gICAgICAgIHJvd1NpemUgPSBkYXRhLndpZHRoICogNDtcbiAgbGV0IHRtcDtcblxuICBpZiAoY29vcmRzW3AxICsgMV0gPiBjb29yZHNbcDIgKyAxXSkge1xuICAgIHRtcCA9IHAxO1xuICAgIHAxID0gcDI7XG4gICAgcDIgPSB0bXA7XG4gICAgdG1wID0gYzE7XG4gICAgYzEgPSBjMjtcbiAgICBjMiA9IHRtcDtcbiAgfVxuXG4gIGlmIChjb29yZHNbcDIgKyAxXSA+IGNvb3Jkc1twMyArIDFdKSB7XG4gICAgdG1wID0gcDI7XG4gICAgcDIgPSBwMztcbiAgICBwMyA9IHRtcDtcbiAgICB0bXAgPSBjMjtcbiAgICBjMiA9IGMzO1xuICAgIGMzID0gdG1wO1xuICB9XG5cbiAgaWYgKGNvb3Jkc1twMSArIDFdID4gY29vcmRzW3AyICsgMV0pIHtcbiAgICB0bXAgPSBwMTtcbiAgICBwMSA9IHAyO1xuICAgIHAyID0gdG1wO1xuICAgIHRtcCA9IGMxO1xuICAgIGMxID0gYzI7XG4gICAgYzIgPSB0bXA7XG4gIH1cblxuICBjb25zdCB4MSA9IChjb29yZHNbcDFdICsgY29udGV4dC5vZmZzZXRYKSAqIGNvbnRleHQuc2NhbGVYO1xuICBjb25zdCB5MSA9IChjb29yZHNbcDEgKyAxXSArIGNvbnRleHQub2Zmc2V0WSkgKiBjb250ZXh0LnNjYWxlWTtcbiAgY29uc3QgeDIgPSAoY29vcmRzW3AyXSArIGNvbnRleHQub2Zmc2V0WCkgKiBjb250ZXh0LnNjYWxlWDtcbiAgY29uc3QgeTIgPSAoY29vcmRzW3AyICsgMV0gKyBjb250ZXh0Lm9mZnNldFkpICogY29udGV4dC5zY2FsZVk7XG4gIGNvbnN0IHgzID0gKGNvb3Jkc1twM10gKyBjb250ZXh0Lm9mZnNldFgpICogY29udGV4dC5zY2FsZVg7XG4gIGNvbnN0IHkzID0gKGNvb3Jkc1twMyArIDFdICsgY29udGV4dC5vZmZzZXRZKSAqIGNvbnRleHQuc2NhbGVZO1xuXG4gIGlmICh5MSA+PSB5Mykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGMxciA9IGNvbG9yc1tjMV0sXG4gICAgICAgIGMxZyA9IGNvbG9yc1tjMSArIDFdLFxuICAgICAgICBjMWIgPSBjb2xvcnNbYzEgKyAyXTtcbiAgY29uc3QgYzJyID0gY29sb3JzW2MyXSxcbiAgICAgICAgYzJnID0gY29sb3JzW2MyICsgMV0sXG4gICAgICAgIGMyYiA9IGNvbG9yc1tjMiArIDJdO1xuICBjb25zdCBjM3IgPSBjb2xvcnNbYzNdLFxuICAgICAgICBjM2cgPSBjb2xvcnNbYzMgKyAxXSxcbiAgICAgICAgYzNiID0gY29sb3JzW2MzICsgMl07XG4gIGNvbnN0IG1pblkgPSBNYXRoLnJvdW5kKHkxKSxcbiAgICAgICAgbWF4WSA9IE1hdGgucm91bmQoeTMpO1xuICBsZXQgeGEsIGNhciwgY2FnLCBjYWI7XG4gIGxldCB4YiwgY2JyLCBjYmcsIGNiYjtcblxuICBmb3IgKGxldCB5ID0gbWluWTsgeSA8PSBtYXhZOyB5KyspIHtcbiAgICBpZiAoeSA8IHkyKSB7XG4gICAgICBsZXQgaztcblxuICAgICAgaWYgKHkgPCB5MSkge1xuICAgICAgICBrID0gMDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGsgPSAoeTEgLSB5KSAvICh5MSAtIHkyKTtcbiAgICAgIH1cblxuICAgICAgeGEgPSB4MSAtICh4MSAtIHgyKSAqIGs7XG4gICAgICBjYXIgPSBjMXIgLSAoYzFyIC0gYzJyKSAqIGs7XG4gICAgICBjYWcgPSBjMWcgLSAoYzFnIC0gYzJnKSAqIGs7XG4gICAgICBjYWIgPSBjMWIgLSAoYzFiIC0gYzJiKSAqIGs7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBrO1xuXG4gICAgICBpZiAoeSA+IHkzKSB7XG4gICAgICAgIGsgPSAxO1xuICAgICAgfSBlbHNlIGlmICh5MiA9PT0geTMpIHtcbiAgICAgICAgayA9IDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBrID0gKHkyIC0geSkgLyAoeTIgLSB5Myk7XG4gICAgICB9XG5cbiAgICAgIHhhID0geDIgLSAoeDIgLSB4MykgKiBrO1xuICAgICAgY2FyID0gYzJyIC0gKGMyciAtIGMzcikgKiBrO1xuICAgICAgY2FnID0gYzJnIC0gKGMyZyAtIGMzZykgKiBrO1xuICAgICAgY2FiID0gYzJiIC0gKGMyYiAtIGMzYikgKiBrO1xuICAgIH1cblxuICAgIGxldCBrO1xuXG4gICAgaWYgKHkgPCB5MSkge1xuICAgICAgayA9IDA7XG4gICAgfSBlbHNlIGlmICh5ID4geTMpIHtcbiAgICAgIGsgPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBrID0gKHkxIC0geSkgLyAoeTEgLSB5Myk7XG4gICAgfVxuXG4gICAgeGIgPSB4MSAtICh4MSAtIHgzKSAqIGs7XG4gICAgY2JyID0gYzFyIC0gKGMxciAtIGMzcikgKiBrO1xuICAgIGNiZyA9IGMxZyAtIChjMWcgLSBjM2cpICogaztcbiAgICBjYmIgPSBjMWIgLSAoYzFiIC0gYzNiKSAqIGs7XG4gICAgY29uc3QgeDFfID0gTWF0aC5yb3VuZChNYXRoLm1pbih4YSwgeGIpKTtcbiAgICBjb25zdCB4Ml8gPSBNYXRoLnJvdW5kKE1hdGgubWF4KHhhLCB4YikpO1xuICAgIGxldCBqID0gcm93U2l6ZSAqIHkgKyB4MV8gKiA0O1xuXG4gICAgZm9yIChsZXQgeCA9IHgxXzsgeCA8PSB4Ml87IHgrKykge1xuICAgICAgayA9ICh4YSAtIHgpIC8gKHhhIC0geGIpO1xuXG4gICAgICBpZiAoayA8IDApIHtcbiAgICAgICAgayA9IDA7XG4gICAgICB9IGVsc2UgaWYgKGsgPiAxKSB7XG4gICAgICAgIGsgPSAxO1xuICAgICAgfVxuXG4gICAgICBieXRlc1tqKytdID0gY2FyIC0gKGNhciAtIGNicikgKiBrIHwgMDtcbiAgICAgIGJ5dGVzW2orK10gPSBjYWcgLSAoY2FnIC0gY2JnKSAqIGsgfCAwO1xuICAgICAgYnl0ZXNbaisrXSA9IGNhYiAtIChjYWIgLSBjYmIpICogayB8IDA7XG4gICAgICBieXRlc1tqKytdID0gMjU1O1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBkcmF3RmlndXJlKGRhdGEsIGZpZ3VyZSwgY29udGV4dCkge1xuICBjb25zdCBwcyA9IGZpZ3VyZS5jb29yZHM7XG4gIGNvbnN0IGNzID0gZmlndXJlLmNvbG9ycztcbiAgbGV0IGksIGlpO1xuXG4gIHN3aXRjaCAoZmlndXJlLnR5cGUpIHtcbiAgICBjYXNlIFwibGF0dGljZVwiOlxuICAgICAgY29uc3QgdmVydGljZXNQZXJSb3cgPSBmaWd1cmUudmVydGljZXNQZXJSb3c7XG4gICAgICBjb25zdCByb3dzID0gTWF0aC5mbG9vcihwcy5sZW5ndGggLyB2ZXJ0aWNlc1BlclJvdykgLSAxO1xuICAgICAgY29uc3QgY29scyA9IHZlcnRpY2VzUGVyUm93IC0gMTtcblxuICAgICAgZm9yIChpID0gMDsgaSA8IHJvd3M7IGkrKykge1xuICAgICAgICBsZXQgcSA9IGkgKiB2ZXJ0aWNlc1BlclJvdztcblxuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNvbHM7IGorKywgcSsrKSB7XG4gICAgICAgICAgZHJhd1RyaWFuZ2xlKGRhdGEsIGNvbnRleHQsIHBzW3FdLCBwc1txICsgMV0sIHBzW3EgKyB2ZXJ0aWNlc1BlclJvd10sIGNzW3FdLCBjc1txICsgMV0sIGNzW3EgKyB2ZXJ0aWNlc1BlclJvd10pO1xuICAgICAgICAgIGRyYXdUcmlhbmdsZShkYXRhLCBjb250ZXh0LCBwc1txICsgdmVydGljZXNQZXJSb3cgKyAxXSwgcHNbcSArIDFdLCBwc1txICsgdmVydGljZXNQZXJSb3ddLCBjc1txICsgdmVydGljZXNQZXJSb3cgKyAxXSwgY3NbcSArIDFdLCBjc1txICsgdmVydGljZXNQZXJSb3ddKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBicmVhaztcblxuICAgIGNhc2UgXCJ0cmlhbmdsZXNcIjpcbiAgICAgIGZvciAoaSA9IDAsIGlpID0gcHMubGVuZ3RoOyBpIDwgaWk7IGkgKz0gMykge1xuICAgICAgICBkcmF3VHJpYW5nbGUoZGF0YSwgY29udGV4dCwgcHNbaV0sIHBzW2kgKyAxXSwgcHNbaSArIDJdLCBjc1tpXSwgY3NbaSArIDFdLCBjc1tpICsgMl0pO1xuICAgICAgfVxuXG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJpbGxlZ2FsIGZpZ3VyZVwiKTtcbiAgfVxufVxuXG5jbGFzcyBNZXNoU2hhZGluZ1BhdHRlcm4gZXh0ZW5kcyBCYXNlU2hhZGluZ1BhdHRlcm4ge1xuICBjb25zdHJ1Y3RvcihJUikge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5fY29vcmRzID0gSVJbMl07XG4gICAgdGhpcy5fY29sb3JzID0gSVJbM107XG4gICAgdGhpcy5fZmlndXJlcyA9IElSWzRdO1xuICAgIHRoaXMuX2JvdW5kcyA9IElSWzVdO1xuICAgIHRoaXMuX2Jib3ggPSBJUls3XTtcbiAgICB0aGlzLl9iYWNrZ3JvdW5kID0gSVJbOF07XG4gICAgdGhpcy5tYXRyaXggPSBudWxsO1xuICB9XG5cbiAgX2NyZWF0ZU1lc2hDYW52YXMoY29tYmluZWRTY2FsZSwgYmFja2dyb3VuZENvbG9yLCBjYWNoZWRDYW52YXNlcykge1xuICAgIGNvbnN0IEVYUEVDVEVEX1NDQUxFID0gMS4xO1xuICAgIGNvbnN0IE1BWF9QQVRURVJOX1NJWkUgPSAzMDAwO1xuICAgIGNvbnN0IEJPUkRFUl9TSVpFID0gMjtcbiAgICBjb25zdCBvZmZzZXRYID0gTWF0aC5mbG9vcih0aGlzLl9ib3VuZHNbMF0pO1xuICAgIGNvbnN0IG9mZnNldFkgPSBNYXRoLmZsb29yKHRoaXMuX2JvdW5kc1sxXSk7XG4gICAgY29uc3QgYm91bmRzV2lkdGggPSBNYXRoLmNlaWwodGhpcy5fYm91bmRzWzJdKSAtIG9mZnNldFg7XG4gICAgY29uc3QgYm91bmRzSGVpZ2h0ID0gTWF0aC5jZWlsKHRoaXMuX2JvdW5kc1szXSkgLSBvZmZzZXRZO1xuICAgIGNvbnN0IHdpZHRoID0gTWF0aC5taW4oTWF0aC5jZWlsKE1hdGguYWJzKGJvdW5kc1dpZHRoICogY29tYmluZWRTY2FsZVswXSAqIEVYUEVDVEVEX1NDQUxFKSksIE1BWF9QQVRURVJOX1NJWkUpO1xuICAgIGNvbnN0IGhlaWdodCA9IE1hdGgubWluKE1hdGguY2VpbChNYXRoLmFicyhib3VuZHNIZWlnaHQgKiBjb21iaW5lZFNjYWxlWzFdICogRVhQRUNURURfU0NBTEUpKSwgTUFYX1BBVFRFUk5fU0laRSk7XG4gICAgY29uc3Qgc2NhbGVYID0gYm91bmRzV2lkdGggLyB3aWR0aDtcbiAgICBjb25zdCBzY2FsZVkgPSBib3VuZHNIZWlnaHQgLyBoZWlnaHQ7XG4gICAgY29uc3QgY29udGV4dCA9IHtcbiAgICAgIGNvb3JkczogdGhpcy5fY29vcmRzLFxuICAgICAgY29sb3JzOiB0aGlzLl9jb2xvcnMsXG4gICAgICBvZmZzZXRYOiAtb2Zmc2V0WCxcbiAgICAgIG9mZnNldFk6IC1vZmZzZXRZLFxuICAgICAgc2NhbGVYOiAxIC8gc2NhbGVYLFxuICAgICAgc2NhbGVZOiAxIC8gc2NhbGVZXG4gICAgfTtcbiAgICBjb25zdCBwYWRkZWRXaWR0aCA9IHdpZHRoICsgQk9SREVSX1NJWkUgKiAyO1xuICAgIGNvbnN0IHBhZGRlZEhlaWdodCA9IGhlaWdodCArIEJPUkRFUl9TSVpFICogMjtcbiAgICBjb25zdCB0bXBDYW52YXMgPSBjYWNoZWRDYW52YXNlcy5nZXRDYW52YXMoXCJtZXNoXCIsIHBhZGRlZFdpZHRoLCBwYWRkZWRIZWlnaHQsIGZhbHNlKTtcbiAgICBjb25zdCB0bXBDdHggPSB0bXBDYW52YXMuY29udGV4dDtcbiAgICBjb25zdCBkYXRhID0gdG1wQ3R4LmNyZWF0ZUltYWdlRGF0YSh3aWR0aCwgaGVpZ2h0KTtcblxuICAgIGlmIChiYWNrZ3JvdW5kQ29sb3IpIHtcbiAgICAgIGNvbnN0IGJ5dGVzID0gZGF0YS5kYXRhO1xuXG4gICAgICBmb3IgKGxldCBpID0gMCwgaWkgPSBieXRlcy5sZW5ndGg7IGkgPCBpaTsgaSArPSA0KSB7XG4gICAgICAgIGJ5dGVzW2ldID0gYmFja2dyb3VuZENvbG9yWzBdO1xuICAgICAgICBieXRlc1tpICsgMV0gPSBiYWNrZ3JvdW5kQ29sb3JbMV07XG4gICAgICAgIGJ5dGVzW2kgKyAyXSA9IGJhY2tncm91bmRDb2xvclsyXTtcbiAgICAgICAgYnl0ZXNbaSArIDNdID0gMjU1O1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZmlndXJlIG9mIHRoaXMuX2ZpZ3VyZXMpIHtcbiAgICAgIGRyYXdGaWd1cmUoZGF0YSwgZmlndXJlLCBjb250ZXh0KTtcbiAgICB9XG5cbiAgICB0bXBDdHgucHV0SW1hZ2VEYXRhKGRhdGEsIEJPUkRFUl9TSVpFLCBCT1JERVJfU0laRSk7XG4gICAgY29uc3QgY2FudmFzID0gdG1wQ2FudmFzLmNhbnZhcztcbiAgICByZXR1cm4ge1xuICAgICAgY2FudmFzLFxuICAgICAgb2Zmc2V0WDogb2Zmc2V0WCAtIEJPUkRFUl9TSVpFICogc2NhbGVYLFxuICAgICAgb2Zmc2V0WTogb2Zmc2V0WSAtIEJPUkRFUl9TSVpFICogc2NhbGVZLFxuICAgICAgc2NhbGVYLFxuICAgICAgc2NhbGVZXG4gICAgfTtcbiAgfVxuXG4gIGdldFBhdHRlcm4oY3R4LCBvd25lciwgaW52ZXJzZSwgcGF0aFR5cGUpIHtcbiAgICBhcHBseUJvdW5kaW5nQm94KGN0eCwgdGhpcy5fYmJveCk7XG4gICAgbGV0IHNjYWxlO1xuXG4gICAgaWYgKHBhdGhUeXBlID09PSBQYXRoVHlwZS5TSEFESU5HKSB7XG4gICAgICBzY2FsZSA9IF91dGlsLlV0aWwuc2luZ3VsYXJWYWx1ZURlY29tcG9zZTJkU2NhbGUoY3R4Lm1vekN1cnJlbnRUcmFuc2Zvcm0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2FsZSA9IF91dGlsLlV0aWwuc2luZ3VsYXJWYWx1ZURlY29tcG9zZTJkU2NhbGUob3duZXIuYmFzZVRyYW5zZm9ybSk7XG5cbiAgICAgIGlmICh0aGlzLm1hdHJpeCkge1xuICAgICAgICBjb25zdCBtYXRyaXhTY2FsZSA9IF91dGlsLlV0aWwuc2luZ3VsYXJWYWx1ZURlY29tcG9zZTJkU2NhbGUodGhpcy5tYXRyaXgpO1xuXG4gICAgICAgIHNjYWxlID0gW3NjYWxlWzBdICogbWF0cml4U2NhbGVbMF0sIHNjYWxlWzFdICogbWF0cml4U2NhbGVbMV1dO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHRlbXBvcmFyeVBhdHRlcm5DYW52YXMgPSB0aGlzLl9jcmVhdGVNZXNoQ2FudmFzKHNjYWxlLCBwYXRoVHlwZSA9PT0gUGF0aFR5cGUuU0hBRElORyA/IG51bGwgOiB0aGlzLl9iYWNrZ3JvdW5kLCBvd25lci5jYWNoZWRDYW52YXNlcyk7XG5cbiAgICBpZiAocGF0aFR5cGUgIT09IFBhdGhUeXBlLlNIQURJTkcpIHtcbiAgICAgIGN0eC5zZXRUcmFuc2Zvcm0uYXBwbHkoY3R4LCBvd25lci5iYXNlVHJhbnNmb3JtKTtcblxuICAgICAgaWYgKHRoaXMubWF0cml4KSB7XG4gICAgICAgIGN0eC50cmFuc2Zvcm0uYXBwbHkoY3R4LCB0aGlzLm1hdHJpeCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY3R4LnRyYW5zbGF0ZSh0ZW1wb3JhcnlQYXR0ZXJuQ2FudmFzLm9mZnNldFgsIHRlbXBvcmFyeVBhdHRlcm5DYW52YXMub2Zmc2V0WSk7XG4gICAgY3R4LnNjYWxlKHRlbXBvcmFyeVBhdHRlcm5DYW52YXMuc2NhbGVYLCB0ZW1wb3JhcnlQYXR0ZXJuQ2FudmFzLnNjYWxlWSk7XG4gICAgcmV0dXJuIGN0eC5jcmVhdGVQYXR0ZXJuKHRlbXBvcmFyeVBhdHRlcm5DYW52YXMuY2FudmFzLCBcIm5vLXJlcGVhdFwiKTtcbiAgfVxuXG59XG5cbmNsYXNzIER1bW15U2hhZGluZ1BhdHRlcm4gZXh0ZW5kcyBCYXNlU2hhZGluZ1BhdHRlcm4ge1xuICBnZXRQYXR0ZXJuKCkge1xuICAgIHJldHVybiBcImhvdHBpbmtcIjtcbiAgfVxuXG59XG5cbmZ1bmN0aW9uIGdldFNoYWRpbmdQYXR0ZXJuKElSKSB7XG4gIHN3aXRjaCAoSVJbMF0pIHtcbiAgICBjYXNlIFwiUmFkaWFsQXhpYWxcIjpcbiAgICAgIHJldHVybiBuZXcgUmFkaWFsQXhpYWxTaGFkaW5nUGF0dGVybihJUik7XG5cbiAgICBjYXNlIFwiTWVzaFwiOlxuICAgICAgcmV0dXJuIG5ldyBNZXNoU2hhZGluZ1BhdHRlcm4oSVIpO1xuXG4gICAgY2FzZSBcIkR1bW15XCI6XG4gICAgICByZXR1cm4gbmV3IER1bW15U2hhZGluZ1BhdHRlcm4oKTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBJUiB0eXBlOiAke0lSWzBdfWApO1xufVxuXG5jb25zdCBQYWludFR5cGUgPSB7XG4gIENPTE9SRUQ6IDEsXG4gIFVOQ09MT1JFRDogMlxufTtcblxuY2xhc3MgVGlsaW5nUGF0dGVybiB7XG4gIHN0YXRpYyBnZXQgTUFYX1BBVFRFUk5fU0laRSgpIHtcbiAgICByZXR1cm4gKDAsIF91dGlsLnNoYWRvdykodGhpcywgXCJNQVhfUEFUVEVSTl9TSVpFXCIsIDMwMDApO1xuICB9XG5cbiAgY29uc3RydWN0b3IoSVIsIGNvbG9yLCBjdHgsIGNhbnZhc0dyYXBoaWNzRmFjdG9yeSwgYmFzZVRyYW5zZm9ybSkge1xuICAgIHRoaXMub3BlcmF0b3JMaXN0ID0gSVJbMl07XG4gICAgdGhpcy5tYXRyaXggPSBJUlszXSB8fCBbMSwgMCwgMCwgMSwgMCwgMF07XG4gICAgdGhpcy5iYm94ID0gSVJbNF07XG4gICAgdGhpcy54c3RlcCA9IElSWzVdO1xuICAgIHRoaXMueXN0ZXAgPSBJUls2XTtcbiAgICB0aGlzLnBhaW50VHlwZSA9IElSWzddO1xuICAgIHRoaXMudGlsaW5nVHlwZSA9IElSWzhdO1xuICAgIHRoaXMuY29sb3IgPSBjb2xvcjtcbiAgICB0aGlzLmN0eCA9IGN0eDtcbiAgICB0aGlzLmNhbnZhc0dyYXBoaWNzRmFjdG9yeSA9IGNhbnZhc0dyYXBoaWNzRmFjdG9yeTtcbiAgICB0aGlzLmJhc2VUcmFuc2Zvcm0gPSBiYXNlVHJhbnNmb3JtO1xuICB9XG5cbiAgY3JlYXRlUGF0dGVybkNhbnZhcyhvd25lcikge1xuICAgIGNvbnN0IG9wZXJhdG9yTGlzdCA9IHRoaXMub3BlcmF0b3JMaXN0O1xuICAgIGNvbnN0IGJib3ggPSB0aGlzLmJib3g7XG4gICAgY29uc3QgeHN0ZXAgPSB0aGlzLnhzdGVwO1xuICAgIGNvbnN0IHlzdGVwID0gdGhpcy55c3RlcDtcbiAgICBjb25zdCBwYWludFR5cGUgPSB0aGlzLnBhaW50VHlwZTtcbiAgICBjb25zdCB0aWxpbmdUeXBlID0gdGhpcy50aWxpbmdUeXBlO1xuICAgIGNvbnN0IGNvbG9yID0gdGhpcy5jb2xvcjtcbiAgICBjb25zdCBjYW52YXNHcmFwaGljc0ZhY3RvcnkgPSB0aGlzLmNhbnZhc0dyYXBoaWNzRmFjdG9yeTtcbiAgICAoMCwgX3V0aWwuaW5mbykoXCJUaWxpbmdUeXBlOiBcIiArIHRpbGluZ1R5cGUpO1xuICAgIGNvbnN0IHgwID0gYmJveFswXSxcbiAgICAgICAgICB5MCA9IGJib3hbMV0sXG4gICAgICAgICAgeDEgPSBiYm94WzJdLFxuICAgICAgICAgIHkxID0gYmJveFszXTtcblxuICAgIGNvbnN0IG1hdHJpeFNjYWxlID0gX3V0aWwuVXRpbC5zaW5ndWxhclZhbHVlRGVjb21wb3NlMmRTY2FsZSh0aGlzLm1hdHJpeCk7XG5cbiAgICBjb25zdCBjdXJNYXRyaXhTY2FsZSA9IF91dGlsLlV0aWwuc2luZ3VsYXJWYWx1ZURlY29tcG9zZTJkU2NhbGUodGhpcy5iYXNlVHJhbnNmb3JtKTtcblxuICAgIGNvbnN0IGNvbWJpbmVkU2NhbGUgPSBbbWF0cml4U2NhbGVbMF0gKiBjdXJNYXRyaXhTY2FsZVswXSwgbWF0cml4U2NhbGVbMV0gKiBjdXJNYXRyaXhTY2FsZVsxXV07XG4gICAgY29uc3QgZGlteCA9IHRoaXMuZ2V0U2l6ZUFuZFNjYWxlKHhzdGVwLCB0aGlzLmN0eC5jYW52YXMud2lkdGgsIGNvbWJpbmVkU2NhbGVbMF0pO1xuICAgIGNvbnN0IGRpbXkgPSB0aGlzLmdldFNpemVBbmRTY2FsZSh5c3RlcCwgdGhpcy5jdHguY2FudmFzLmhlaWdodCwgY29tYmluZWRTY2FsZVsxXSk7XG4gICAgY29uc3QgdG1wQ2FudmFzID0gb3duZXIuY2FjaGVkQ2FudmFzZXMuZ2V0Q2FudmFzKFwicGF0dGVyblwiLCBkaW14LnNpemUsIGRpbXkuc2l6ZSwgdHJ1ZSk7XG4gICAgY29uc3QgdG1wQ3R4ID0gdG1wQ2FudmFzLmNvbnRleHQ7XG4gICAgY29uc3QgZ3JhcGhpY3MgPSBjYW52YXNHcmFwaGljc0ZhY3RvcnkuY3JlYXRlQ2FudmFzR3JhcGhpY3ModG1wQ3R4KTtcbiAgICBncmFwaGljcy5ncm91cExldmVsID0gb3duZXIuZ3JvdXBMZXZlbDtcbiAgICB0aGlzLnNldEZpbGxBbmRTdHJva2VTdHlsZVRvQ29udGV4dChncmFwaGljcywgcGFpbnRUeXBlLCBjb2xvcik7XG4gICAgbGV0IGFkanVzdGVkWDAgPSB4MDtcbiAgICBsZXQgYWRqdXN0ZWRZMCA9IHkwO1xuICAgIGxldCBhZGp1c3RlZFgxID0geDE7XG4gICAgbGV0IGFkanVzdGVkWTEgPSB5MTtcblxuICAgIGlmICh4MCA8IDApIHtcbiAgICAgIGFkanVzdGVkWDAgPSAwO1xuICAgICAgYWRqdXN0ZWRYMSArPSBNYXRoLmFicyh4MCk7XG4gICAgfVxuXG4gICAgaWYgKHkwIDwgMCkge1xuICAgICAgYWRqdXN0ZWRZMCA9IDA7XG4gICAgICBhZGp1c3RlZFkxICs9IE1hdGguYWJzKHkwKTtcbiAgICB9XG5cbiAgICB0bXBDdHgudHJhbnNsYXRlKC0oZGlteC5zY2FsZSAqIGFkanVzdGVkWDApLCAtKGRpbXkuc2NhbGUgKiBhZGp1c3RlZFkwKSk7XG4gICAgZ3JhcGhpY3MudHJhbnNmb3JtKGRpbXguc2NhbGUsIDAsIDAsIGRpbXkuc2NhbGUsIDAsIDApO1xuICAgIHRtcEN0eC5zYXZlKCk7XG4gICAgdGhpcy5jbGlwQmJveChncmFwaGljcywgYWRqdXN0ZWRYMCwgYWRqdXN0ZWRZMCwgYWRqdXN0ZWRYMSwgYWRqdXN0ZWRZMSk7XG4gICAgZ3JhcGhpY3MuYmFzZVRyYW5zZm9ybSA9IGdyYXBoaWNzLmN0eC5tb3pDdXJyZW50VHJhbnNmb3JtLnNsaWNlKCk7XG4gICAgZ3JhcGhpY3MuZXhlY3V0ZU9wZXJhdG9yTGlzdChvcGVyYXRvckxpc3QpO1xuICAgIGdyYXBoaWNzLmVuZERyYXdpbmcoKTtcbiAgICByZXR1cm4ge1xuICAgICAgY2FudmFzOiB0bXBDYW52YXMuY2FudmFzLFxuICAgICAgc2NhbGVYOiBkaW14LnNjYWxlLFxuICAgICAgc2NhbGVZOiBkaW15LnNjYWxlLFxuICAgICAgb2Zmc2V0WDogYWRqdXN0ZWRYMCxcbiAgICAgIG9mZnNldFk6IGFkanVzdGVkWTBcbiAgICB9O1xuICB9XG5cbiAgZ2V0U2l6ZUFuZFNjYWxlKHN0ZXAsIHJlYWxPdXRwdXRTaXplLCBzY2FsZSkge1xuICAgIHN0ZXAgPSBNYXRoLmFicyhzdGVwKTtcbiAgICBjb25zdCBtYXhTaXplID0gTWF0aC5tYXgoVGlsaW5nUGF0dGVybi5NQVhfUEFUVEVSTl9TSVpFLCByZWFsT3V0cHV0U2l6ZSk7XG4gICAgbGV0IHNpemUgPSBNYXRoLmNlaWwoc3RlcCAqIHNjYWxlKTtcblxuICAgIGlmIChzaXplID49IG1heFNpemUpIHtcbiAgICAgIHNpemUgPSBtYXhTaXplO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2FsZSA9IHNpemUgLyBzdGVwO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBzY2FsZSxcbiAgICAgIHNpemVcbiAgICB9O1xuICB9XG5cbiAgY2xpcEJib3goZ3JhcGhpY3MsIHgwLCB5MCwgeDEsIHkxKSB7XG4gICAgY29uc3QgYmJveFdpZHRoID0geDEgLSB4MDtcbiAgICBjb25zdCBiYm94SGVpZ2h0ID0geTEgLSB5MDtcbiAgICBncmFwaGljcy5jdHgucmVjdCh4MCwgeTAsIGJib3hXaWR0aCwgYmJveEhlaWdodCk7XG4gICAgZ3JhcGhpY3MuY3VycmVudC51cGRhdGVSZWN0TWluTWF4KGdyYXBoaWNzLmN0eC5tb3pDdXJyZW50VHJhbnNmb3JtLCBbeDAsIHkwLCB4MSwgeTFdKTtcbiAgICBncmFwaGljcy5jbGlwKCk7XG4gICAgZ3JhcGhpY3MuZW5kUGF0aCgpO1xuICB9XG5cbiAgc2V0RmlsbEFuZFN0cm9rZVN0eWxlVG9Db250ZXh0KGdyYXBoaWNzLCBwYWludFR5cGUsIGNvbG9yKSB7XG4gICAgY29uc3QgY29udGV4dCA9IGdyYXBoaWNzLmN0eCxcbiAgICAgICAgICBjdXJyZW50ID0gZ3JhcGhpY3MuY3VycmVudDtcblxuICAgIHN3aXRjaCAocGFpbnRUeXBlKSB7XG4gICAgICBjYXNlIFBhaW50VHlwZS5DT0xPUkVEOlxuICAgICAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcbiAgICAgICAgY29udGV4dC5maWxsU3R5bGUgPSBjdHguZmlsbFN0eWxlO1xuICAgICAgICBjb250ZXh0LnN0cm9rZVN0eWxlID0gY3R4LnN0cm9rZVN0eWxlO1xuICAgICAgICBjdXJyZW50LmZpbGxDb2xvciA9IGN0eC5maWxsU3R5bGU7XG4gICAgICAgIGN1cnJlbnQuc3Ryb2tlQ29sb3IgPSBjdHguc3Ryb2tlU3R5bGU7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIFBhaW50VHlwZS5VTkNPTE9SRUQ6XG4gICAgICAgIGNvbnN0IGNzc0NvbG9yID0gX3V0aWwuVXRpbC5tYWtlSGV4Q29sb3IoY29sb3JbMF0sIGNvbG9yWzFdLCBjb2xvclsyXSk7XG5cbiAgICAgICAgY29udGV4dC5maWxsU3R5bGUgPSBjc3NDb2xvcjtcbiAgICAgICAgY29udGV4dC5zdHJva2VTdHlsZSA9IGNzc0NvbG9yO1xuICAgICAgICBjdXJyZW50LmZpbGxDb2xvciA9IGNzc0NvbG9yO1xuICAgICAgICBjdXJyZW50LnN0cm9rZUNvbG9yID0gY3NzQ29sb3I7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgX3V0aWwuRm9ybWF0RXJyb3IoYFVuc3VwcG9ydGVkIHBhaW50IHR5cGU6ICR7cGFpbnRUeXBlfWApO1xuICAgIH1cbiAgfVxuXG4gIGdldFBhdHRlcm4oY3R4LCBvd25lciwgaW52ZXJzZSwgcGF0aFR5cGUpIHtcbiAgICBsZXQgbWF0cml4ID0gaW52ZXJzZTtcblxuICAgIGlmIChwYXRoVHlwZSAhPT0gUGF0aFR5cGUuU0hBRElORykge1xuICAgICAgbWF0cml4ID0gX3V0aWwuVXRpbC50cmFuc2Zvcm0obWF0cml4LCBvd25lci5iYXNlVHJhbnNmb3JtKTtcblxuICAgICAgaWYgKHRoaXMubWF0cml4KSB7XG4gICAgICAgIG1hdHJpeCA9IF91dGlsLlV0aWwudHJhbnNmb3JtKG1hdHJpeCwgdGhpcy5tYXRyaXgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHRlbXBvcmFyeVBhdHRlcm5DYW52YXMgPSB0aGlzLmNyZWF0ZVBhdHRlcm5DYW52YXMob3duZXIpO1xuICAgIGxldCBkb21NYXRyaXggPSBuZXcgRE9NTWF0cml4KG1hdHJpeCk7XG4gICAgZG9tTWF0cml4ID0gZG9tTWF0cml4LnRyYW5zbGF0ZSh0ZW1wb3JhcnlQYXR0ZXJuQ2FudmFzLm9mZnNldFgsIHRlbXBvcmFyeVBhdHRlcm5DYW52YXMub2Zmc2V0WSk7XG4gICAgZG9tTWF0cml4ID0gZG9tTWF0cml4LnNjYWxlKDEgLyB0ZW1wb3JhcnlQYXR0ZXJuQ2FudmFzLnNjYWxlWCwgMSAvIHRlbXBvcmFyeVBhdHRlcm5DYW52YXMuc2NhbGVZKTtcbiAgICBjb25zdCBwYXR0ZXJuID0gY3R4LmNyZWF0ZVBhdHRlcm4odGVtcG9yYXJ5UGF0dGVybkNhbnZhcy5jYW52YXMsIFwicmVwZWF0XCIpO1xuXG4gICAgdHJ5IHtcbiAgICAgIHBhdHRlcm4uc2V0VHJhbnNmb3JtKGRvbU1hdHJpeCk7XG4gICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgICgwLCBfdXRpbC53YXJuKShgVGlsaW5nUGF0dGVybi5nZXRQYXR0ZXJuOiBcIiR7ZXg/Lm1lc3NhZ2V9XCIuYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhdHRlcm47XG4gIH1cblxufVxuXG5leHBvcnRzLlRpbGluZ1BhdHRlcm4gPSBUaWxpbmdQYXR0ZXJuO1xuXG4vKioqLyB9KSxcbi8qIDEyICovXG4vKioqLyAoKF9fdW51c2VkX3dlYnBhY2tfbW9kdWxlLCBleHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5leHBvcnRzLmFwcGx5TWFza0ltYWdlRGF0YSA9IGFwcGx5TWFza0ltYWdlRGF0YTtcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxuZnVuY3Rpb24gYXBwbHlNYXNrSW1hZ2VEYXRhKHtcbiAgc3JjLFxuICBzcmNQb3MgPSAwLFxuICBkZXN0LFxuICBkZXN0UG9zID0gMCxcbiAgd2lkdGgsXG4gIGhlaWdodCxcbiAgaW52ZXJzZURlY29kZSA9IGZhbHNlXG59KSB7XG4gIGNvbnN0IG9wYXF1ZSA9IF91dGlsLkZlYXR1cmVUZXN0LmlzTGl0dGxlRW5kaWFuID8gMHhmZjAwMDAwMCA6IDB4MDAwMDAwZmY7XG4gIGNvbnN0IFt6ZXJvTWFwcGluZywgb25lTWFwcGluZ10gPSAhaW52ZXJzZURlY29kZSA/IFtvcGFxdWUsIDBdIDogWzAsIG9wYXF1ZV07XG4gIGNvbnN0IHdpZHRoSW5Tb3VyY2UgPSB3aWR0aCA+PiAzO1xuICBjb25zdCB3aWR0aFJlbWFpbmRlciA9IHdpZHRoICYgNztcbiAgY29uc3Qgc3JjTGVuZ3RoID0gc3JjLmxlbmd0aDtcbiAgZGVzdCA9IG5ldyBVaW50MzJBcnJheShkZXN0LmJ1ZmZlcik7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBoZWlnaHQ7IGkrKykge1xuICAgIGZvciAoY29uc3QgbWF4ID0gc3JjUG9zICsgd2lkdGhJblNvdXJjZTsgc3JjUG9zIDwgbWF4OyBzcmNQb3MrKykge1xuICAgICAgY29uc3QgZWxlbSA9IHNyY1BvcyA8IHNyY0xlbmd0aCA/IHNyY1tzcmNQb3NdIDogMjU1O1xuICAgICAgZGVzdFtkZXN0UG9zKytdID0gZWxlbSAmIDBiMTAwMDAwMDAgPyBvbmVNYXBwaW5nIDogemVyb01hcHBpbmc7XG4gICAgICBkZXN0W2Rlc3RQb3MrK10gPSBlbGVtICYgMGIxMDAwMDAwID8gb25lTWFwcGluZyA6IHplcm9NYXBwaW5nO1xuICAgICAgZGVzdFtkZXN0UG9zKytdID0gZWxlbSAmIDBiMTAwMDAwID8gb25lTWFwcGluZyA6IHplcm9NYXBwaW5nO1xuICAgICAgZGVzdFtkZXN0UG9zKytdID0gZWxlbSAmIDBiMTAwMDAgPyBvbmVNYXBwaW5nIDogemVyb01hcHBpbmc7XG4gICAgICBkZXN0W2Rlc3RQb3MrK10gPSBlbGVtICYgMGIxMDAwID8gb25lTWFwcGluZyA6IHplcm9NYXBwaW5nO1xuICAgICAgZGVzdFtkZXN0UG9zKytdID0gZWxlbSAmIDBiMTAwID8gb25lTWFwcGluZyA6IHplcm9NYXBwaW5nO1xuICAgICAgZGVzdFtkZXN0UG9zKytdID0gZWxlbSAmIDBiMTAgPyBvbmVNYXBwaW5nIDogemVyb01hcHBpbmc7XG4gICAgICBkZXN0W2Rlc3RQb3MrK10gPSBlbGVtICYgMGIxID8gb25lTWFwcGluZyA6IHplcm9NYXBwaW5nO1xuICAgIH1cblxuICAgIGlmICh3aWR0aFJlbWFpbmRlciA9PT0gMCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY29uc3QgZWxlbSA9IHNyY1BvcyA8IHNyY0xlbmd0aCA/IHNyY1tzcmNQb3MrK10gOiAyNTU7XG5cbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IHdpZHRoUmVtYWluZGVyOyBqKyspIHtcbiAgICAgIGRlc3RbZGVzdFBvcysrXSA9IGVsZW0gJiAxIDw8IDcgLSBqID8gb25lTWFwcGluZyA6IHplcm9NYXBwaW5nO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgc3JjUG9zLFxuICAgIGRlc3RQb3NcbiAgfTtcbn1cblxuLyoqKi8gfSksXG4vKiAxMyAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5HbG9iYWxXb3JrZXJPcHRpb25zID0gdm9pZCAwO1xuY29uc3QgR2xvYmFsV29ya2VyT3B0aW9ucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5leHBvcnRzLkdsb2JhbFdvcmtlck9wdGlvbnMgPSBHbG9iYWxXb3JrZXJPcHRpb25zO1xuR2xvYmFsV29ya2VyT3B0aW9ucy53b3JrZXJQb3J0ID0gR2xvYmFsV29ya2VyT3B0aW9ucy53b3JrZXJQb3J0ID09PSB1bmRlZmluZWQgPyBudWxsIDogR2xvYmFsV29ya2VyT3B0aW9ucy53b3JrZXJQb3J0O1xuR2xvYmFsV29ya2VyT3B0aW9ucy53b3JrZXJTcmMgPSBHbG9iYWxXb3JrZXJPcHRpb25zLndvcmtlclNyYyA9PT0gdW5kZWZpbmVkID8gXCJcIiA6IEdsb2JhbFdvcmtlck9wdGlvbnMud29ya2VyU3JjO1xuXG4vKioqLyB9KSxcbi8qIDE0ICovXG4vKioqLyAoKF9fdW51c2VkX3dlYnBhY2tfbW9kdWxlLCBleHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5leHBvcnRzLk1lc3NhZ2VIYW5kbGVyID0gdm9pZCAwO1xuXG52YXIgX3V0aWwgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDEpO1xuXG5jb25zdCBDYWxsYmFja0tpbmQgPSB7XG4gIFVOS05PV046IDAsXG4gIERBVEE6IDEsXG4gIEVSUk9SOiAyXG59O1xuY29uc3QgU3RyZWFtS2luZCA9IHtcbiAgVU5LTk9XTjogMCxcbiAgQ0FOQ0VMOiAxLFxuICBDQU5DRUxfQ09NUExFVEU6IDIsXG4gIENMT1NFOiAzLFxuICBFTlFVRVVFOiA0LFxuICBFUlJPUjogNSxcbiAgUFVMTDogNixcbiAgUFVMTF9DT01QTEVURTogNyxcbiAgU1RBUlRfQ09NUExFVEU6IDhcbn07XG5cbmZ1bmN0aW9uIHdyYXBSZWFzb24ocmVhc29uKSB7XG4gIGlmICghKHJlYXNvbiBpbnN0YW5jZW9mIEVycm9yIHx8IHR5cGVvZiByZWFzb24gPT09IFwib2JqZWN0XCIgJiYgcmVhc29uICE9PSBudWxsKSkge1xuICAgICgwLCBfdXRpbC51bnJlYWNoYWJsZSkoJ3dyYXBSZWFzb246IEV4cGVjdGVkIFwicmVhc29uXCIgdG8gYmUgYSAocG9zc2libHkgY2xvbmVkKSBFcnJvci4nKTtcbiAgfVxuXG4gIHN3aXRjaCAocmVhc29uLm5hbWUpIHtcbiAgICBjYXNlIFwiQWJvcnRFeGNlcHRpb25cIjpcbiAgICAgIHJldHVybiBuZXcgX3V0aWwuQWJvcnRFeGNlcHRpb24ocmVhc29uLm1lc3NhZ2UpO1xuXG4gICAgY2FzZSBcIk1pc3NpbmdQREZFeGNlcHRpb25cIjpcbiAgICAgIHJldHVybiBuZXcgX3V0aWwuTWlzc2luZ1BERkV4Y2VwdGlvbihyZWFzb24ubWVzc2FnZSk7XG5cbiAgICBjYXNlIFwiUGFzc3dvcmRFeGNlcHRpb25cIjpcbiAgICAgIHJldHVybiBuZXcgX3V0aWwuUGFzc3dvcmRFeGNlcHRpb24ocmVhc29uLm1lc3NhZ2UsIHJlYXNvbi5jb2RlKTtcblxuICAgIGNhc2UgXCJVbmV4cGVjdGVkUmVzcG9uc2VFeGNlcHRpb25cIjpcbiAgICAgIHJldHVybiBuZXcgX3V0aWwuVW5leHBlY3RlZFJlc3BvbnNlRXhjZXB0aW9uKHJlYXNvbi5tZXNzYWdlLCByZWFzb24uc3RhdHVzKTtcblxuICAgIGNhc2UgXCJVbmtub3duRXJyb3JFeGNlcHRpb25cIjpcbiAgICAgIHJldHVybiBuZXcgX3V0aWwuVW5rbm93bkVycm9yRXhjZXB0aW9uKHJlYXNvbi5tZXNzYWdlLCByZWFzb24uZGV0YWlscyk7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIG5ldyBfdXRpbC5Vbmtub3duRXJyb3JFeGNlcHRpb24ocmVhc29uLm1lc3NhZ2UsIHJlYXNvbi50b1N0cmluZygpKTtcbiAgfVxufVxuXG5jbGFzcyBNZXNzYWdlSGFuZGxlciB7XG4gIGNvbnN0cnVjdG9yKHNvdXJjZU5hbWUsIHRhcmdldE5hbWUsIGNvbU9iaikge1xuICAgIHRoaXMuc291cmNlTmFtZSA9IHNvdXJjZU5hbWU7XG4gICAgdGhpcy50YXJnZXROYW1lID0gdGFyZ2V0TmFtZTtcbiAgICB0aGlzLmNvbU9iaiA9IGNvbU9iajtcbiAgICB0aGlzLmNhbGxiYWNrSWQgPSAxO1xuICAgIHRoaXMuc3RyZWFtSWQgPSAxO1xuICAgIHRoaXMuc3RyZWFtU2lua3MgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMuc3RyZWFtQ29udHJvbGxlcnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMuY2FsbGJhY2tDYXBhYmlsaXRpZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMuYWN0aW9uSGFuZGxlciA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbiAgICB0aGlzLl9vbkNvbU9iak9uTWVzc2FnZSA9IGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IGRhdGEgPSBldmVudC5kYXRhO1xuXG4gICAgICBpZiAoZGF0YS50YXJnZXROYW1lICE9PSB0aGlzLnNvdXJjZU5hbWUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZGF0YS5zdHJlYW0pIHtcbiAgICAgICAgdGhpcy5fcHJvY2Vzc1N0cmVhbU1lc3NhZ2UoZGF0YSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZGF0YS5jYWxsYmFjaykge1xuICAgICAgICBjb25zdCBjYWxsYmFja0lkID0gZGF0YS5jYWxsYmFja0lkO1xuICAgICAgICBjb25zdCBjYXBhYmlsaXR5ID0gdGhpcy5jYWxsYmFja0NhcGFiaWxpdGllc1tjYWxsYmFja0lkXTtcblxuICAgICAgICBpZiAoIWNhcGFiaWxpdHkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCByZXNvbHZlIGNhbGxiYWNrICR7Y2FsbGJhY2tJZH1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrQ2FwYWJpbGl0aWVzW2NhbGxiYWNrSWRdO1xuXG4gICAgICAgIGlmIChkYXRhLmNhbGxiYWNrID09PSBDYWxsYmFja0tpbmQuREFUQSkge1xuICAgICAgICAgIGNhcGFiaWxpdHkucmVzb2x2ZShkYXRhLmRhdGEpO1xuICAgICAgICB9IGVsc2UgaWYgKGRhdGEuY2FsbGJhY2sgPT09IENhbGxiYWNrS2luZC5FUlJPUikge1xuICAgICAgICAgIGNhcGFiaWxpdHkucmVqZWN0KHdyYXBSZWFzb24oZGF0YS5yZWFzb24pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmV4cGVjdGVkIGNhbGxiYWNrIGNhc2VcIik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFjdGlvbiA9IHRoaXMuYWN0aW9uSGFuZGxlcltkYXRhLmFjdGlvbl07XG5cbiAgICAgIGlmICghYWN0aW9uKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBhY3Rpb24gZnJvbSB3b3JrZXI6ICR7ZGF0YS5hY3Rpb259YCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChkYXRhLmNhbGxiYWNrSWQpIHtcbiAgICAgICAgY29uc3QgY2JTb3VyY2VOYW1lID0gdGhpcy5zb3VyY2VOYW1lO1xuICAgICAgICBjb25zdCBjYlRhcmdldE5hbWUgPSBkYXRhLnNvdXJjZU5hbWU7XG4gICAgICAgIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgICAgICAgcmVzb2x2ZShhY3Rpb24oZGF0YS5kYXRhKSk7XG4gICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICAgIGNvbU9iai5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICBzb3VyY2VOYW1lOiBjYlNvdXJjZU5hbWUsXG4gICAgICAgICAgICB0YXJnZXROYW1lOiBjYlRhcmdldE5hbWUsXG4gICAgICAgICAgICBjYWxsYmFjazogQ2FsbGJhY2tLaW5kLkRBVEEsXG4gICAgICAgICAgICBjYWxsYmFja0lkOiBkYXRhLmNhbGxiYWNrSWQsXG4gICAgICAgICAgICBkYXRhOiByZXN1bHRcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICAgIGNvbU9iai5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICBzb3VyY2VOYW1lOiBjYlNvdXJjZU5hbWUsXG4gICAgICAgICAgICB0YXJnZXROYW1lOiBjYlRhcmdldE5hbWUsXG4gICAgICAgICAgICBjYWxsYmFjazogQ2FsbGJhY2tLaW5kLkVSUk9SLFxuICAgICAgICAgICAgY2FsbGJhY2tJZDogZGF0YS5jYWxsYmFja0lkLFxuICAgICAgICAgICAgcmVhc29uOiB3cmFwUmVhc29uKHJlYXNvbilcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGRhdGEuc3RyZWFtSWQpIHtcbiAgICAgICAgdGhpcy5fY3JlYXRlU3RyZWFtU2luayhkYXRhKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGFjdGlvbihkYXRhLmRhdGEpO1xuICAgIH07XG5cbiAgICBjb21PYmouYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgdGhpcy5fb25Db21PYmpPbk1lc3NhZ2UpO1xuICB9XG5cbiAgb24oYWN0aW9uTmFtZSwgaGFuZGxlcikge1xuICAgIGNvbnN0IGFoID0gdGhpcy5hY3Rpb25IYW5kbGVyO1xuXG4gICAgaWYgKGFoW2FjdGlvbk5hbWVdKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZXJlIGlzIGFscmVhZHkgYW4gYWN0aW9uTmFtZSBjYWxsZWQgXCIke2FjdGlvbk5hbWV9XCJgKTtcbiAgICB9XG5cbiAgICBhaFthY3Rpb25OYW1lXSA9IGhhbmRsZXI7XG4gIH1cblxuICBzZW5kKGFjdGlvbk5hbWUsIGRhdGEsIHRyYW5zZmVycykge1xuICAgIHRoaXMuY29tT2JqLnBvc3RNZXNzYWdlKHtcbiAgICAgIHNvdXJjZU5hbWU6IHRoaXMuc291cmNlTmFtZSxcbiAgICAgIHRhcmdldE5hbWU6IHRoaXMudGFyZ2V0TmFtZSxcbiAgICAgIGFjdGlvbjogYWN0aW9uTmFtZSxcbiAgICAgIGRhdGFcbiAgICB9LCB0cmFuc2ZlcnMpO1xuICB9XG5cbiAgc2VuZFdpdGhQcm9taXNlKGFjdGlvbk5hbWUsIGRhdGEsIHRyYW5zZmVycykge1xuICAgIGNvbnN0IGNhbGxiYWNrSWQgPSB0aGlzLmNhbGxiYWNrSWQrKztcbiAgICBjb25zdCBjYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgIHRoaXMuY2FsbGJhY2tDYXBhYmlsaXRpZXNbY2FsbGJhY2tJZF0gPSBjYXBhYmlsaXR5O1xuXG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuY29tT2JqLnBvc3RNZXNzYWdlKHtcbiAgICAgICAgc291cmNlTmFtZTogdGhpcy5zb3VyY2VOYW1lLFxuICAgICAgICB0YXJnZXROYW1lOiB0aGlzLnRhcmdldE5hbWUsXG4gICAgICAgIGFjdGlvbjogYWN0aW9uTmFtZSxcbiAgICAgICAgY2FsbGJhY2tJZCxcbiAgICAgICAgZGF0YVxuICAgICAgfSwgdHJhbnNmZXJzKTtcbiAgICB9IGNhdGNoIChleCkge1xuICAgICAgY2FwYWJpbGl0eS5yZWplY3QoZXgpO1xuICAgIH1cblxuICAgIHJldHVybiBjYXBhYmlsaXR5LnByb21pc2U7XG4gIH1cblxuICBzZW5kV2l0aFN0cmVhbShhY3Rpb25OYW1lLCBkYXRhLCBxdWV1ZWluZ1N0cmF0ZWd5LCB0cmFuc2ZlcnMpIHtcbiAgICBjb25zdCBzdHJlYW1JZCA9IHRoaXMuc3RyZWFtSWQrKyxcbiAgICAgICAgICBzb3VyY2VOYW1lID0gdGhpcy5zb3VyY2VOYW1lLFxuICAgICAgICAgIHRhcmdldE5hbWUgPSB0aGlzLnRhcmdldE5hbWUsXG4gICAgICAgICAgY29tT2JqID0gdGhpcy5jb21PYmo7XG4gICAgcmV0dXJuIG5ldyBSZWFkYWJsZVN0cmVhbSh7XG4gICAgICBzdGFydDogY29udHJvbGxlciA9PiB7XG4gICAgICAgIGNvbnN0IHN0YXJ0Q2FwYWJpbGl0eSA9ICgwLCBfdXRpbC5jcmVhdGVQcm9taXNlQ2FwYWJpbGl0eSkoKTtcbiAgICAgICAgdGhpcy5zdHJlYW1Db250cm9sbGVyc1tzdHJlYW1JZF0gPSB7XG4gICAgICAgICAgY29udHJvbGxlcixcbiAgICAgICAgICBzdGFydENhbGw6IHN0YXJ0Q2FwYWJpbGl0eSxcbiAgICAgICAgICBwdWxsQ2FsbDogbnVsbCxcbiAgICAgICAgICBjYW5jZWxDYWxsOiBudWxsLFxuICAgICAgICAgIGlzQ2xvc2VkOiBmYWxzZVxuICAgICAgICB9O1xuICAgICAgICBjb21PYmoucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgIHNvdXJjZU5hbWUsXG4gICAgICAgICAgdGFyZ2V0TmFtZSxcbiAgICAgICAgICBhY3Rpb246IGFjdGlvbk5hbWUsXG4gICAgICAgICAgc3RyZWFtSWQsXG4gICAgICAgICAgZGF0YSxcbiAgICAgICAgICBkZXNpcmVkU2l6ZTogY29udHJvbGxlci5kZXNpcmVkU2l6ZVxuICAgICAgICB9LCB0cmFuc2ZlcnMpO1xuICAgICAgICByZXR1cm4gc3RhcnRDYXBhYmlsaXR5LnByb21pc2U7XG4gICAgICB9LFxuICAgICAgcHVsbDogY29udHJvbGxlciA9PiB7XG4gICAgICAgIGNvbnN0IHB1bGxDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgICAgICB0aGlzLnN0cmVhbUNvbnRyb2xsZXJzW3N0cmVhbUlkXS5wdWxsQ2FsbCA9IHB1bGxDYXBhYmlsaXR5O1xuICAgICAgICBjb21PYmoucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgIHNvdXJjZU5hbWUsXG4gICAgICAgICAgdGFyZ2V0TmFtZSxcbiAgICAgICAgICBzdHJlYW06IFN0cmVhbUtpbmQuUFVMTCxcbiAgICAgICAgICBzdHJlYW1JZCxcbiAgICAgICAgICBkZXNpcmVkU2l6ZTogY29udHJvbGxlci5kZXNpcmVkU2l6ZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHB1bGxDYXBhYmlsaXR5LnByb21pc2U7XG4gICAgICB9LFxuICAgICAgY2FuY2VsOiByZWFzb24gPT4ge1xuICAgICAgICAoMCwgX3V0aWwuYXNzZXJ0KShyZWFzb24gaW5zdGFuY2VvZiBFcnJvciwgXCJjYW5jZWwgbXVzdCBoYXZlIGEgdmFsaWQgcmVhc29uXCIpO1xuICAgICAgICBjb25zdCBjYW5jZWxDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgICAgICB0aGlzLnN0cmVhbUNvbnRyb2xsZXJzW3N0cmVhbUlkXS5jYW5jZWxDYWxsID0gY2FuY2VsQ2FwYWJpbGl0eTtcbiAgICAgICAgdGhpcy5zdHJlYW1Db250cm9sbGVyc1tzdHJlYW1JZF0uaXNDbG9zZWQgPSB0cnVlO1xuICAgICAgICBjb21PYmoucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgIHNvdXJjZU5hbWUsXG4gICAgICAgICAgdGFyZ2V0TmFtZSxcbiAgICAgICAgICBzdHJlYW06IFN0cmVhbUtpbmQuQ0FOQ0VMLFxuICAgICAgICAgIHN0cmVhbUlkLFxuICAgICAgICAgIHJlYXNvbjogd3JhcFJlYXNvbihyZWFzb24pXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gY2FuY2VsQ2FwYWJpbGl0eS5wcm9taXNlO1xuICAgICAgfVxuICAgIH0sIHF1ZXVlaW5nU3RyYXRlZ3kpO1xuICB9XG5cbiAgX2NyZWF0ZVN0cmVhbVNpbmsoZGF0YSkge1xuICAgIGNvbnN0IHN0cmVhbUlkID0gZGF0YS5zdHJlYW1JZCxcbiAgICAgICAgICBzb3VyY2VOYW1lID0gdGhpcy5zb3VyY2VOYW1lLFxuICAgICAgICAgIHRhcmdldE5hbWUgPSBkYXRhLnNvdXJjZU5hbWUsXG4gICAgICAgICAgY29tT2JqID0gdGhpcy5jb21PYmo7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXMsXG4gICAgICAgICAgYWN0aW9uID0gdGhpcy5hY3Rpb25IYW5kbGVyW2RhdGEuYWN0aW9uXTtcbiAgICBjb25zdCBzdHJlYW1TaW5rID0ge1xuICAgICAgZW5xdWV1ZShjaHVuaywgc2l6ZSA9IDEsIHRyYW5zZmVycykge1xuICAgICAgICBpZiAodGhpcy5pc0NhbmNlbGxlZCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxhc3REZXNpcmVkU2l6ZSA9IHRoaXMuZGVzaXJlZFNpemU7XG4gICAgICAgIHRoaXMuZGVzaXJlZFNpemUgLT0gc2l6ZTtcblxuICAgICAgICBpZiAobGFzdERlc2lyZWRTaXplID4gMCAmJiB0aGlzLmRlc2lyZWRTaXplIDw9IDApIHtcbiAgICAgICAgICB0aGlzLnNpbmtDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgICAgICAgIHRoaXMucmVhZHkgPSB0aGlzLnNpbmtDYXBhYmlsaXR5LnByb21pc2U7XG4gICAgICAgIH1cblxuICAgICAgICBjb21PYmoucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgIHNvdXJjZU5hbWUsXG4gICAgICAgICAgdGFyZ2V0TmFtZSxcbiAgICAgICAgICBzdHJlYW06IFN0cmVhbUtpbmQuRU5RVUVVRSxcbiAgICAgICAgICBzdHJlYW1JZCxcbiAgICAgICAgICBjaHVua1xuICAgICAgICB9LCB0cmFuc2ZlcnMpO1xuICAgICAgfSxcblxuICAgICAgY2xvc2UoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzQ2FuY2VsbGVkKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5pc0NhbmNlbGxlZCA9IHRydWU7XG4gICAgICAgIGNvbU9iai5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgc291cmNlTmFtZSxcbiAgICAgICAgICB0YXJnZXROYW1lLFxuICAgICAgICAgIHN0cmVhbTogU3RyZWFtS2luZC5DTE9TRSxcbiAgICAgICAgICBzdHJlYW1JZFxuICAgICAgICB9KTtcbiAgICAgICAgZGVsZXRlIHNlbGYuc3RyZWFtU2lua3Nbc3RyZWFtSWRdO1xuICAgICAgfSxcblxuICAgICAgZXJyb3IocmVhc29uKSB7XG4gICAgICAgICgwLCBfdXRpbC5hc3NlcnQpKHJlYXNvbiBpbnN0YW5jZW9mIEVycm9yLCBcImVycm9yIG11c3QgaGF2ZSBhIHZhbGlkIHJlYXNvblwiKTtcblxuICAgICAgICBpZiAodGhpcy5pc0NhbmNlbGxlZCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuaXNDYW5jZWxsZWQgPSB0cnVlO1xuICAgICAgICBjb21PYmoucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgIHNvdXJjZU5hbWUsXG4gICAgICAgICAgdGFyZ2V0TmFtZSxcbiAgICAgICAgICBzdHJlYW06IFN0cmVhbUtpbmQuRVJST1IsXG4gICAgICAgICAgc3RyZWFtSWQsXG4gICAgICAgICAgcmVhc29uOiB3cmFwUmVhc29uKHJlYXNvbilcbiAgICAgICAgfSk7XG4gICAgICB9LFxuXG4gICAgICBzaW5rQ2FwYWJpbGl0eTogKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpLFxuICAgICAgb25QdWxsOiBudWxsLFxuICAgICAgb25DYW5jZWw6IG51bGwsXG4gICAgICBpc0NhbmNlbGxlZDogZmFsc2UsXG4gICAgICBkZXNpcmVkU2l6ZTogZGF0YS5kZXNpcmVkU2l6ZSxcbiAgICAgIHJlYWR5OiBudWxsXG4gICAgfTtcbiAgICBzdHJlYW1TaW5rLnNpbmtDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgICBzdHJlYW1TaW5rLnJlYWR5ID0gc3RyZWFtU2luay5zaW5rQ2FwYWJpbGl0eS5wcm9taXNlO1xuICAgIHRoaXMuc3RyZWFtU2lua3Nbc3RyZWFtSWRdID0gc3RyZWFtU2luaztcbiAgICBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgcmVzb2x2ZShhY3Rpb24oZGF0YS5kYXRhLCBzdHJlYW1TaW5rKSk7XG4gICAgfSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICBjb21PYmoucG9zdE1lc3NhZ2Uoe1xuICAgICAgICBzb3VyY2VOYW1lLFxuICAgICAgICB0YXJnZXROYW1lLFxuICAgICAgICBzdHJlYW06IFN0cmVhbUtpbmQuU1RBUlRfQ09NUExFVEUsXG4gICAgICAgIHN0cmVhbUlkLFxuICAgICAgICBzdWNjZXNzOiB0cnVlXG4gICAgICB9KTtcbiAgICB9LCBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgICBjb21PYmoucG9zdE1lc3NhZ2Uoe1xuICAgICAgICBzb3VyY2VOYW1lLFxuICAgICAgICB0YXJnZXROYW1lLFxuICAgICAgICBzdHJlYW06IFN0cmVhbUtpbmQuU1RBUlRfQ09NUExFVEUsXG4gICAgICAgIHN0cmVhbUlkLFxuICAgICAgICByZWFzb246IHdyYXBSZWFzb24ocmVhc29uKVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBfcHJvY2Vzc1N0cmVhbU1lc3NhZ2UoZGF0YSkge1xuICAgIGNvbnN0IHN0cmVhbUlkID0gZGF0YS5zdHJlYW1JZCxcbiAgICAgICAgICBzb3VyY2VOYW1lID0gdGhpcy5zb3VyY2VOYW1lLFxuICAgICAgICAgIHRhcmdldE5hbWUgPSBkYXRhLnNvdXJjZU5hbWUsXG4gICAgICAgICAgY29tT2JqID0gdGhpcy5jb21PYmo7XG4gICAgY29uc3Qgc3RyZWFtQ29udHJvbGxlciA9IHRoaXMuc3RyZWFtQ29udHJvbGxlcnNbc3RyZWFtSWRdLFxuICAgICAgICAgIHN0cmVhbVNpbmsgPSB0aGlzLnN0cmVhbVNpbmtzW3N0cmVhbUlkXTtcblxuICAgIHN3aXRjaCAoZGF0YS5zdHJlYW0pIHtcbiAgICAgIGNhc2UgU3RyZWFtS2luZC5TVEFSVF9DT01QTEVURTpcbiAgICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICAgIHN0cmVhbUNvbnRyb2xsZXIuc3RhcnRDYWxsLnJlc29sdmUoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzdHJlYW1Db250cm9sbGVyLnN0YXJ0Q2FsbC5yZWplY3Qod3JhcFJlYXNvbihkYXRhLnJlYXNvbikpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgU3RyZWFtS2luZC5QVUxMX0NPTVBMRVRFOlxuICAgICAgICBpZiAoZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgc3RyZWFtQ29udHJvbGxlci5wdWxsQ2FsbC5yZXNvbHZlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RyZWFtQ29udHJvbGxlci5wdWxsQ2FsbC5yZWplY3Qod3JhcFJlYXNvbihkYXRhLnJlYXNvbikpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgU3RyZWFtS2luZC5QVUxMOlxuICAgICAgICBpZiAoIXN0cmVhbVNpbmspIHtcbiAgICAgICAgICBjb21PYmoucG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgICAgc291cmNlTmFtZSxcbiAgICAgICAgICAgIHRhcmdldE5hbWUsXG4gICAgICAgICAgICBzdHJlYW06IFN0cmVhbUtpbmQuUFVMTF9DT01QTEVURSxcbiAgICAgICAgICAgIHN0cmVhbUlkLFxuICAgICAgICAgICAgc3VjY2VzczogdHJ1ZVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHN0cmVhbVNpbmsuZGVzaXJlZFNpemUgPD0gMCAmJiBkYXRhLmRlc2lyZWRTaXplID4gMCkge1xuICAgICAgICAgIHN0cmVhbVNpbmsuc2lua0NhcGFiaWxpdHkucmVzb2x2ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgc3RyZWFtU2luay5kZXNpcmVkU2l6ZSA9IGRhdGEuZGVzaXJlZFNpemU7XG4gICAgICAgIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgICAgICAgcmVzb2x2ZShzdHJlYW1TaW5rLm9uUHVsbCAmJiBzdHJlYW1TaW5rLm9uUHVsbCgpKTtcbiAgICAgICAgfSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29tT2JqLnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIHNvdXJjZU5hbWUsXG4gICAgICAgICAgICB0YXJnZXROYW1lLFxuICAgICAgICAgICAgc3RyZWFtOiBTdHJlYW1LaW5kLlBVTExfQ09NUExFVEUsXG4gICAgICAgICAgICBzdHJlYW1JZCxcbiAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWVcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICAgIGNvbU9iai5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICBzb3VyY2VOYW1lLFxuICAgICAgICAgICAgdGFyZ2V0TmFtZSxcbiAgICAgICAgICAgIHN0cmVhbTogU3RyZWFtS2luZC5QVUxMX0NPTVBMRVRFLFxuICAgICAgICAgICAgc3RyZWFtSWQsXG4gICAgICAgICAgICByZWFzb246IHdyYXBSZWFzb24ocmVhc29uKVxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgU3RyZWFtS2luZC5FTlFVRVVFOlxuICAgICAgICAoMCwgX3V0aWwuYXNzZXJ0KShzdHJlYW1Db250cm9sbGVyLCBcImVucXVldWUgc2hvdWxkIGhhdmUgc3RyZWFtIGNvbnRyb2xsZXJcIik7XG5cbiAgICAgICAgaWYgKHN0cmVhbUNvbnRyb2xsZXIuaXNDbG9zZWQpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIHN0cmVhbUNvbnRyb2xsZXIuY29udHJvbGxlci5lbnF1ZXVlKGRhdGEuY2h1bmspO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBTdHJlYW1LaW5kLkNMT1NFOlxuICAgICAgICAoMCwgX3V0aWwuYXNzZXJ0KShzdHJlYW1Db250cm9sbGVyLCBcImNsb3NlIHNob3VsZCBoYXZlIHN0cmVhbSBjb250cm9sbGVyXCIpO1xuXG4gICAgICAgIGlmIChzdHJlYW1Db250cm9sbGVyLmlzQ2xvc2VkKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBzdHJlYW1Db250cm9sbGVyLmlzQ2xvc2VkID0gdHJ1ZTtcbiAgICAgICAgc3RyZWFtQ29udHJvbGxlci5jb250cm9sbGVyLmNsb3NlKCk7XG5cbiAgICAgICAgdGhpcy5fZGVsZXRlU3RyZWFtQ29udHJvbGxlcihzdHJlYW1Db250cm9sbGVyLCBzdHJlYW1JZCk7XG5cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgU3RyZWFtS2luZC5FUlJPUjpcbiAgICAgICAgKDAsIF91dGlsLmFzc2VydCkoc3RyZWFtQ29udHJvbGxlciwgXCJlcnJvciBzaG91bGQgaGF2ZSBzdHJlYW0gY29udHJvbGxlclwiKTtcbiAgICAgICAgc3RyZWFtQ29udHJvbGxlci5jb250cm9sbGVyLmVycm9yKHdyYXBSZWFzb24oZGF0YS5yZWFzb24pKTtcblxuICAgICAgICB0aGlzLl9kZWxldGVTdHJlYW1Db250cm9sbGVyKHN0cmVhbUNvbnRyb2xsZXIsIHN0cmVhbUlkKTtcblxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBTdHJlYW1LaW5kLkNBTkNFTF9DT01QTEVURTpcbiAgICAgICAgaWYgKGRhdGEuc3VjY2Vzcykge1xuICAgICAgICAgIHN0cmVhbUNvbnRyb2xsZXIuY2FuY2VsQ2FsbC5yZXNvbHZlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RyZWFtQ29udHJvbGxlci5jYW5jZWxDYWxsLnJlamVjdCh3cmFwUmVhc29uKGRhdGEucmVhc29uKSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9kZWxldGVTdHJlYW1Db250cm9sbGVyKHN0cmVhbUNvbnRyb2xsZXIsIHN0cmVhbUlkKTtcblxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBTdHJlYW1LaW5kLkNBTkNFTDpcbiAgICAgICAgaWYgKCFzdHJlYW1TaW5rKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICAgIHJlc29sdmUoc3RyZWFtU2luay5vbkNhbmNlbCAmJiBzdHJlYW1TaW5rLm9uQ2FuY2VsKHdyYXBSZWFzb24oZGF0YS5yZWFzb24pKSk7XG4gICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbU9iai5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICBzb3VyY2VOYW1lLFxuICAgICAgICAgICAgdGFyZ2V0TmFtZSxcbiAgICAgICAgICAgIHN0cmVhbTogU3RyZWFtS2luZC5DQU5DRUxfQ09NUExFVEUsXG4gICAgICAgICAgICBzdHJlYW1JZCxcbiAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWVcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICAgIGNvbU9iai5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICBzb3VyY2VOYW1lLFxuICAgICAgICAgICAgdGFyZ2V0TmFtZSxcbiAgICAgICAgICAgIHN0cmVhbTogU3RyZWFtS2luZC5DQU5DRUxfQ09NUExFVEUsXG4gICAgICAgICAgICBzdHJlYW1JZCxcbiAgICAgICAgICAgIHJlYXNvbjogd3JhcFJlYXNvbihyZWFzb24pXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBzdHJlYW1TaW5rLnNpbmtDYXBhYmlsaXR5LnJlamVjdCh3cmFwUmVhc29uKGRhdGEucmVhc29uKSk7XG4gICAgICAgIHN0cmVhbVNpbmsuaXNDYW5jZWxsZWQgPSB0cnVlO1xuICAgICAgICBkZWxldGUgdGhpcy5zdHJlYW1TaW5rc1tzdHJlYW1JZF07XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmV4cGVjdGVkIHN0cmVhbSBjYXNlXCIpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIF9kZWxldGVTdHJlYW1Db250cm9sbGVyKHN0cmVhbUNvbnRyb2xsZXIsIHN0cmVhbUlkKSB7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFtzdHJlYW1Db250cm9sbGVyLnN0YXJ0Q2FsbCAmJiBzdHJlYW1Db250cm9sbGVyLnN0YXJ0Q2FsbC5wcm9taXNlLCBzdHJlYW1Db250cm9sbGVyLnB1bGxDYWxsICYmIHN0cmVhbUNvbnRyb2xsZXIucHVsbENhbGwucHJvbWlzZSwgc3RyZWFtQ29udHJvbGxlci5jYW5jZWxDYWxsICYmIHN0cmVhbUNvbnRyb2xsZXIuY2FuY2VsQ2FsbC5wcm9taXNlXSk7XG4gICAgZGVsZXRlIHRoaXMuc3RyZWFtQ29udHJvbGxlcnNbc3RyZWFtSWRdO1xuICB9XG5cbiAgZGVzdHJveSgpIHtcbiAgICB0aGlzLmNvbU9iai5yZW1vdmVFdmVudExpc3RlbmVyKFwibWVzc2FnZVwiLCB0aGlzLl9vbkNvbU9iak9uTWVzc2FnZSk7XG4gIH1cblxufVxuXG5leHBvcnRzLk1lc3NhZ2VIYW5kbGVyID0gTWVzc2FnZUhhbmRsZXI7XG5cbi8qKiovIH0pLFxuLyogMTUgKi9cbi8qKiovICgoX191bnVzZWRfd2VicGFja19tb2R1bGUsIGV4cG9ydHMsIF9fd19wZGZqc19yZXF1aXJlX18pID0+IHtcblxuXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgKHtcbiAgdmFsdWU6IHRydWVcbn0pKTtcbmV4cG9ydHMuTWV0YWRhdGEgPSB2b2lkIDA7XG5cbnZhciBfdXRpbCA9IF9fd19wZGZqc19yZXF1aXJlX18oMSk7XG5cbmNsYXNzIE1ldGFkYXRhIHtcbiAgI21ldGFkYXRhTWFwO1xuICAjZGF0YTtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgcGFyc2VkRGF0YSxcbiAgICByYXdEYXRhXG4gIH0pIHtcbiAgICB0aGlzLiNtZXRhZGF0YU1hcCA9IHBhcnNlZERhdGE7XG4gICAgdGhpcy4jZGF0YSA9IHJhd0RhdGE7XG4gIH1cblxuICBnZXRSYXcoKSB7XG4gICAgcmV0dXJuIHRoaXMuI2RhdGE7XG4gIH1cblxuICBnZXQobmFtZSkge1xuICAgIHJldHVybiB0aGlzLiNtZXRhZGF0YU1hcC5nZXQobmFtZSkgPz8gbnVsbDtcbiAgfVxuXG4gIGdldEFsbCgpIHtcbiAgICByZXR1cm4gKDAsIF91dGlsLm9iamVjdEZyb21NYXApKHRoaXMuI21ldGFkYXRhTWFwKTtcbiAgfVxuXG4gIGhhcyhuYW1lKSB7XG4gICAgcmV0dXJuIHRoaXMuI21ldGFkYXRhTWFwLmhhcyhuYW1lKTtcbiAgfVxuXG59XG5cbmV4cG9ydHMuTWV0YWRhdGEgPSBNZXRhZGF0YTtcblxuLyoqKi8gfSksXG4vKiAxNiAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5PcHRpb25hbENvbnRlbnRDb25maWcgPSB2b2lkIDA7XG5cbnZhciBfdXRpbCA9IF9fd19wZGZqc19yZXF1aXJlX18oMSk7XG5cbmNsYXNzIE9wdGlvbmFsQ29udGVudEdyb3VwIHtcbiAgY29uc3RydWN0b3IobmFtZSwgaW50ZW50KSB7XG4gICAgdGhpcy52aXNpYmxlID0gdHJ1ZTtcbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIHRoaXMuaW50ZW50ID0gaW50ZW50O1xuICB9XG5cbn1cblxuY2xhc3MgT3B0aW9uYWxDb250ZW50Q29uZmlnIHtcbiAgY29uc3RydWN0b3IoZGF0YSkge1xuICAgIHRoaXMubmFtZSA9IG51bGw7XG4gICAgdGhpcy5jcmVhdG9yID0gbnVsbDtcbiAgICB0aGlzLl9vcmRlciA9IG51bGw7XG4gICAgdGhpcy5fZ3JvdXBzID0gbmV3IE1hcCgpO1xuXG4gICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLm5hbWUgPSBkYXRhLm5hbWU7XG4gICAgdGhpcy5jcmVhdG9yID0gZGF0YS5jcmVhdG9yO1xuICAgIHRoaXMuX29yZGVyID0gZGF0YS5vcmRlcjtcblxuICAgIGZvciAoY29uc3QgZ3JvdXAgb2YgZGF0YS5ncm91cHMpIHtcbiAgICAgIHRoaXMuX2dyb3Vwcy5zZXQoZ3JvdXAuaWQsIG5ldyBPcHRpb25hbENvbnRlbnRHcm91cChncm91cC5uYW1lLCBncm91cC5pbnRlbnQpKTtcbiAgICB9XG5cbiAgICBpZiAoZGF0YS5iYXNlU3RhdGUgPT09IFwiT0ZGXCIpIHtcbiAgICAgIGZvciAoY29uc3QgZ3JvdXAgb2YgdGhpcy5fZ3JvdXBzKSB7XG4gICAgICAgIGdyb3VwLnZpc2libGUgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IG9uIG9mIGRhdGEub24pIHtcbiAgICAgIHRoaXMuX2dyb3Vwcy5nZXQob24pLnZpc2libGUgPSB0cnVlO1xuICAgIH1cblxuICAgIGZvciAoY29uc3Qgb2ZmIG9mIGRhdGEub2ZmKSB7XG4gICAgICB0aGlzLl9ncm91cHMuZ2V0KG9mZikudmlzaWJsZSA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIF9ldmFsdWF0ZVZpc2liaWxpdHlFeHByZXNzaW9uKGFycmF5KSB7XG4gICAgY29uc3QgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgaWYgKGxlbmd0aCA8IDIpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGNvbnN0IG9wZXJhdG9yID0gYXJyYXlbMF07XG5cbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gYXJyYXlbaV07XG4gICAgICBsZXQgc3RhdGU7XG5cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGVsZW1lbnQpKSB7XG4gICAgICAgIHN0YXRlID0gdGhpcy5fZXZhbHVhdGVWaXNpYmlsaXR5RXhwcmVzc2lvbihlbGVtZW50KTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5fZ3JvdXBzLmhhcyhlbGVtZW50KSkge1xuICAgICAgICBzdGF0ZSA9IHRoaXMuX2dyb3Vwcy5nZXQoZWxlbWVudCkudmlzaWJsZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgICgwLCBfdXRpbC53YXJuKShgT3B0aW9uYWwgY29udGVudCBncm91cCBub3QgZm91bmQ6ICR7ZWxlbWVudH1gKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIHN3aXRjaCAob3BlcmF0b3IpIHtcbiAgICAgICAgY2FzZSBcIkFuZFwiOlxuICAgICAgICAgIGlmICghc3RhdGUpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFwiT3JcIjpcbiAgICAgICAgICBpZiAoc3RhdGUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgXCJOb3RcIjpcbiAgICAgICAgICByZXR1cm4gIXN0YXRlO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG9wZXJhdG9yID09PSBcIkFuZFwiO1xuICB9XG5cbiAgaXNWaXNpYmxlKGdyb3VwKSB7XG4gICAgaWYgKHRoaXMuX2dyb3Vwcy5zaXplID09PSAwKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoIWdyb3VwKSB7XG4gICAgICAoMCwgX3V0aWwud2FybikoXCJPcHRpb25hbCBjb250ZW50IGdyb3VwIG5vdCBkZWZpbmVkLlwiKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChncm91cC50eXBlID09PSBcIk9DR1wiKSB7XG4gICAgICBpZiAoIXRoaXMuX2dyb3Vwcy5oYXMoZ3JvdXAuaWQpKSB7XG4gICAgICAgICgwLCBfdXRpbC53YXJuKShgT3B0aW9uYWwgY29udGVudCBncm91cCBub3QgZm91bmQ6ICR7Z3JvdXAuaWR9YCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5fZ3JvdXBzLmdldChncm91cC5pZCkudmlzaWJsZTtcbiAgICB9IGVsc2UgaWYgKGdyb3VwLnR5cGUgPT09IFwiT0NNRFwiKSB7XG4gICAgICBpZiAoZ3JvdXAuZXhwcmVzc2lvbikge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZhbHVhdGVWaXNpYmlsaXR5RXhwcmVzc2lvbihncm91cC5leHByZXNzaW9uKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFncm91cC5wb2xpY3kgfHwgZ3JvdXAucG9saWN5ID09PSBcIkFueU9uXCIpIHtcbiAgICAgICAgZm9yIChjb25zdCBpZCBvZiBncm91cC5pZHMpIHtcbiAgICAgICAgICBpZiAoIXRoaXMuX2dyb3Vwcy5oYXMoaWQpKSB7XG4gICAgICAgICAgICAoMCwgX3V0aWwud2FybikoYE9wdGlvbmFsIGNvbnRlbnQgZ3JvdXAgbm90IGZvdW5kOiAke2lkfWApO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHRoaXMuX2dyb3Vwcy5nZXQoaWQpLnZpc2libGUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0gZWxzZSBpZiAoZ3JvdXAucG9saWN5ID09PSBcIkFsbE9uXCIpIHtcbiAgICAgICAgZm9yIChjb25zdCBpZCBvZiBncm91cC5pZHMpIHtcbiAgICAgICAgICBpZiAoIXRoaXMuX2dyb3Vwcy5oYXMoaWQpKSB7XG4gICAgICAgICAgICAoMCwgX3V0aWwud2FybikoYE9wdGlvbmFsIGNvbnRlbnQgZ3JvdXAgbm90IGZvdW5kOiAke2lkfWApO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCF0aGlzLl9ncm91cHMuZ2V0KGlkKS52aXNpYmxlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGVsc2UgaWYgKGdyb3VwLnBvbGljeSA9PT0gXCJBbnlPZmZcIikge1xuICAgICAgICBmb3IgKGNvbnN0IGlkIG9mIGdyb3VwLmlkcykge1xuICAgICAgICAgIGlmICghdGhpcy5fZ3JvdXBzLmhhcyhpZCkpIHtcbiAgICAgICAgICAgICgwLCBfdXRpbC53YXJuKShgT3B0aW9uYWwgY29udGVudCBncm91cCBub3QgZm91bmQ6ICR7aWR9YCk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIXRoaXMuX2dyb3Vwcy5nZXQoaWQpLnZpc2libGUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0gZWxzZSBpZiAoZ3JvdXAucG9saWN5ID09PSBcIkFsbE9mZlwiKSB7XG4gICAgICAgIGZvciAoY29uc3QgaWQgb2YgZ3JvdXAuaWRzKSB7XG4gICAgICAgICAgaWYgKCF0aGlzLl9ncm91cHMuaGFzKGlkKSkge1xuICAgICAgICAgICAgKDAsIF91dGlsLndhcm4pKGBPcHRpb25hbCBjb250ZW50IGdyb3VwIG5vdCBmb3VuZDogJHtpZH1gKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICh0aGlzLl9ncm91cHMuZ2V0KGlkKS52aXNpYmxlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgICgwLCBfdXRpbC53YXJuKShgVW5rbm93biBvcHRpb25hbCBjb250ZW50IHBvbGljeSAke2dyb3VwLnBvbGljeX0uYCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAoMCwgX3V0aWwud2FybikoYFVua25vd24gZ3JvdXAgdHlwZSAke2dyb3VwLnR5cGV9LmApO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgc2V0VmlzaWJpbGl0eShpZCwgdmlzaWJsZSA9IHRydWUpIHtcbiAgICBpZiAoIXRoaXMuX2dyb3Vwcy5oYXMoaWQpKSB7XG4gICAgICAoMCwgX3V0aWwud2FybikoYE9wdGlvbmFsIGNvbnRlbnQgZ3JvdXAgbm90IGZvdW5kOiAke2lkfWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2dyb3Vwcy5nZXQoaWQpLnZpc2libGUgPSAhIXZpc2libGU7XG4gIH1cblxuICBnZXRPcmRlcigpIHtcbiAgICBpZiAoIXRoaXMuX2dyb3Vwcy5zaXplKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fb3JkZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLl9vcmRlci5zbGljZSgpO1xuICAgIH1cblxuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuX2dyb3Vwcy5rZXlzKCkpO1xuICB9XG5cbiAgZ2V0R3JvdXBzKCkge1xuICAgIHJldHVybiB0aGlzLl9ncm91cHMuc2l6ZSA+IDAgPyAoMCwgX3V0aWwub2JqZWN0RnJvbU1hcCkodGhpcy5fZ3JvdXBzKSA6IG51bGw7XG4gIH1cblxuICBnZXRHcm91cChpZCkge1xuICAgIHJldHVybiB0aGlzLl9ncm91cHMuZ2V0KGlkKSB8fCBudWxsO1xuICB9XG5cbn1cblxuZXhwb3J0cy5PcHRpb25hbENvbnRlbnRDb25maWcgPSBPcHRpb25hbENvbnRlbnRDb25maWc7XG5cbi8qKiovIH0pLFxuLyogMTcgKi9cbi8qKiovICgoX191bnVzZWRfd2VicGFja19tb2R1bGUsIGV4cG9ydHMsIF9fd19wZGZqc19yZXF1aXJlX18pID0+IHtcblxuXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgKHtcbiAgdmFsdWU6IHRydWVcbn0pKTtcbmV4cG9ydHMuUERGRGF0YVRyYW5zcG9ydFN0cmVhbSA9IHZvaWQgMDtcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxudmFyIF9kaXNwbGF5X3V0aWxzID0gX193X3BkZmpzX3JlcXVpcmVfXyg1KTtcblxuY2xhc3MgUERGRGF0YVRyYW5zcG9ydFN0cmVhbSB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtcywgcGRmRGF0YVJhbmdlVHJhbnNwb3J0KSB7XG4gICAgKDAsIF91dGlsLmFzc2VydCkocGRmRGF0YVJhbmdlVHJhbnNwb3J0LCAnUERGRGF0YVRyYW5zcG9ydFN0cmVhbSAtIG1pc3NpbmcgcmVxdWlyZWQgXCJwZGZEYXRhUmFuZ2VUcmFuc3BvcnRcIiBhcmd1bWVudC4nKTtcbiAgICB0aGlzLl9xdWV1ZWRDaHVua3MgPSBbXTtcbiAgICB0aGlzLl9wcm9ncmVzc2l2ZURvbmUgPSBwYXJhbXMucHJvZ3Jlc3NpdmVEb25lIHx8IGZhbHNlO1xuICAgIHRoaXMuX2NvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lID0gcGFyYW1zLmNvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lIHx8IG51bGw7XG4gICAgY29uc3QgaW5pdGlhbERhdGEgPSBwYXJhbXMuaW5pdGlhbERhdGE7XG5cbiAgICBpZiAoaW5pdGlhbERhdGE/Lmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KGluaXRpYWxEYXRhKS5idWZmZXI7XG5cbiAgICAgIHRoaXMuX3F1ZXVlZENodW5rcy5wdXNoKGJ1ZmZlcik7XG4gICAgfVxuXG4gICAgdGhpcy5fcGRmRGF0YVJhbmdlVHJhbnNwb3J0ID0gcGRmRGF0YVJhbmdlVHJhbnNwb3J0O1xuICAgIHRoaXMuX2lzU3RyZWFtaW5nU3VwcG9ydGVkID0gIXBhcmFtcy5kaXNhYmxlU3RyZWFtO1xuICAgIHRoaXMuX2lzUmFuZ2VTdXBwb3J0ZWQgPSAhcGFyYW1zLmRpc2FibGVSYW5nZTtcbiAgICB0aGlzLl9jb250ZW50TGVuZ3RoID0gcGFyYW1zLmxlbmd0aDtcbiAgICB0aGlzLl9mdWxsUmVxdWVzdFJlYWRlciA9IG51bGw7XG4gICAgdGhpcy5fcmFuZ2VSZWFkZXJzID0gW107XG5cbiAgICB0aGlzLl9wZGZEYXRhUmFuZ2VUcmFuc3BvcnQuYWRkUmFuZ2VMaXN0ZW5lcigoYmVnaW4sIGNodW5rKSA9PiB7XG4gICAgICB0aGlzLl9vblJlY2VpdmVEYXRhKHtcbiAgICAgICAgYmVnaW4sXG4gICAgICAgIGNodW5rXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRoaXMuX3BkZkRhdGFSYW5nZVRyYW5zcG9ydC5hZGRQcm9ncmVzc0xpc3RlbmVyKChsb2FkZWQsIHRvdGFsKSA9PiB7XG4gICAgICB0aGlzLl9vblByb2dyZXNzKHtcbiAgICAgICAgbG9hZGVkLFxuICAgICAgICB0b3RhbFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLl9wZGZEYXRhUmFuZ2VUcmFuc3BvcnQuYWRkUHJvZ3Jlc3NpdmVSZWFkTGlzdGVuZXIoY2h1bmsgPT4ge1xuICAgICAgdGhpcy5fb25SZWNlaXZlRGF0YSh7XG4gICAgICAgIGNodW5rXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRoaXMuX3BkZkRhdGFSYW5nZVRyYW5zcG9ydC5hZGRQcm9ncmVzc2l2ZURvbmVMaXN0ZW5lcigoKSA9PiB7XG4gICAgICB0aGlzLl9vblByb2dyZXNzaXZlRG9uZSgpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5fcGRmRGF0YVJhbmdlVHJhbnNwb3J0LnRyYW5zcG9ydFJlYWR5KCk7XG4gIH1cblxuICBfb25SZWNlaXZlRGF0YShhcmdzKSB7XG4gICAgY29uc3QgYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkoYXJncy5jaHVuaykuYnVmZmVyO1xuXG4gICAgaWYgKGFyZ3MuYmVnaW4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHRoaXMuX2Z1bGxSZXF1ZXN0UmVhZGVyKSB7XG4gICAgICAgIHRoaXMuX2Z1bGxSZXF1ZXN0UmVhZGVyLl9lbnF1ZXVlKGJ1ZmZlcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9xdWV1ZWRDaHVua3MucHVzaChidWZmZXIpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBmb3VuZCA9IHRoaXMuX3JhbmdlUmVhZGVycy5zb21lKGZ1bmN0aW9uIChyYW5nZVJlYWRlcikge1xuICAgICAgICBpZiAocmFuZ2VSZWFkZXIuX2JlZ2luICE9PSBhcmdzLmJlZ2luKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmFuZ2VSZWFkZXIuX2VucXVldWUoYnVmZmVyKTtcblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0pO1xuXG4gICAgICAoMCwgX3V0aWwuYXNzZXJ0KShmb3VuZCwgXCJfb25SZWNlaXZlRGF0YSAtIG5vIGBQREZEYXRhVHJhbnNwb3J0U3RyZWFtUmFuZ2VSZWFkZXJgIGluc3RhbmNlIGZvdW5kLlwiKTtcbiAgICB9XG4gIH1cblxuICBnZXQgX3Byb2dyZXNzaXZlRGF0YUxlbmd0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZnVsbFJlcXVlc3RSZWFkZXI/Ll9sb2FkZWQgPz8gMDtcbiAgfVxuXG4gIF9vblByb2dyZXNzKGV2dCkge1xuICAgIGlmIChldnQudG90YWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgZmlyc3RSZWFkZXIgPSB0aGlzLl9yYW5nZVJlYWRlcnNbMF07XG5cbiAgICAgIGlmIChmaXJzdFJlYWRlcj8ub25Qcm9ncmVzcykge1xuICAgICAgICBmaXJzdFJlYWRlci5vblByb2dyZXNzKHtcbiAgICAgICAgICBsb2FkZWQ6IGV2dC5sb2FkZWRcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGZ1bGxSZWFkZXIgPSB0aGlzLl9mdWxsUmVxdWVzdFJlYWRlcjtcblxuICAgICAgaWYgKGZ1bGxSZWFkZXI/Lm9uUHJvZ3Jlc3MpIHtcbiAgICAgICAgZnVsbFJlYWRlci5vblByb2dyZXNzKHtcbiAgICAgICAgICBsb2FkZWQ6IGV2dC5sb2FkZWQsXG4gICAgICAgICAgdG90YWw6IGV2dC50b3RhbFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBfb25Qcm9ncmVzc2l2ZURvbmUoKSB7XG4gICAgaWYgKHRoaXMuX2Z1bGxSZXF1ZXN0UmVhZGVyKSB7XG4gICAgICB0aGlzLl9mdWxsUmVxdWVzdFJlYWRlci5wcm9ncmVzc2l2ZURvbmUoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9wcm9ncmVzc2l2ZURvbmUgPSB0cnVlO1xuICB9XG5cbiAgX3JlbW92ZVJhbmdlUmVhZGVyKHJlYWRlcikge1xuICAgIGNvbnN0IGkgPSB0aGlzLl9yYW5nZVJlYWRlcnMuaW5kZXhPZihyZWFkZXIpO1xuXG4gICAgaWYgKGkgPj0gMCkge1xuICAgICAgdGhpcy5fcmFuZ2VSZWFkZXJzLnNwbGljZShpLCAxKTtcbiAgICB9XG4gIH1cblxuICBnZXRGdWxsUmVhZGVyKCkge1xuICAgICgwLCBfdXRpbC5hc3NlcnQpKCF0aGlzLl9mdWxsUmVxdWVzdFJlYWRlciwgXCJQREZEYXRhVHJhbnNwb3J0U3RyZWFtLmdldEZ1bGxSZWFkZXIgY2FuIG9ubHkgYmUgY2FsbGVkIG9uY2UuXCIpO1xuICAgIGNvbnN0IHF1ZXVlZENodW5rcyA9IHRoaXMuX3F1ZXVlZENodW5rcztcbiAgICB0aGlzLl9xdWV1ZWRDaHVua3MgPSBudWxsO1xuICAgIHJldHVybiBuZXcgUERGRGF0YVRyYW5zcG9ydFN0cmVhbVJlYWRlcih0aGlzLCBxdWV1ZWRDaHVua3MsIHRoaXMuX3Byb2dyZXNzaXZlRG9uZSwgdGhpcy5fY29udGVudERpc3Bvc2l0aW9uRmlsZW5hbWUpO1xuICB9XG5cbiAgZ2V0UmFuZ2VSZWFkZXIoYmVnaW4sIGVuZCkge1xuICAgIGlmIChlbmQgPD0gdGhpcy5fcHJvZ3Jlc3NpdmVEYXRhTGVuZ3RoKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCByZWFkZXIgPSBuZXcgUERGRGF0YVRyYW5zcG9ydFN0cmVhbVJhbmdlUmVhZGVyKHRoaXMsIGJlZ2luLCBlbmQpO1xuXG4gICAgdGhpcy5fcGRmRGF0YVJhbmdlVHJhbnNwb3J0LnJlcXVlc3REYXRhUmFuZ2UoYmVnaW4sIGVuZCk7XG5cbiAgICB0aGlzLl9yYW5nZVJlYWRlcnMucHVzaChyZWFkZXIpO1xuXG4gICAgcmV0dXJuIHJlYWRlcjtcbiAgfVxuXG4gIGNhbmNlbEFsbFJlcXVlc3RzKHJlYXNvbikge1xuICAgIGlmICh0aGlzLl9mdWxsUmVxdWVzdFJlYWRlcikge1xuICAgICAgdGhpcy5fZnVsbFJlcXVlc3RSZWFkZXIuY2FuY2VsKHJlYXNvbik7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCByZWFkZXIgb2YgdGhpcy5fcmFuZ2VSZWFkZXJzLnNsaWNlKDApKSB7XG4gICAgICByZWFkZXIuY2FuY2VsKHJlYXNvbik7XG4gICAgfVxuXG4gICAgdGhpcy5fcGRmRGF0YVJhbmdlVHJhbnNwb3J0LmFib3J0KCk7XG4gIH1cblxufVxuXG5leHBvcnRzLlBERkRhdGFUcmFuc3BvcnRTdHJlYW0gPSBQREZEYXRhVHJhbnNwb3J0U3RyZWFtO1xuXG5jbGFzcyBQREZEYXRhVHJhbnNwb3J0U3RyZWFtUmVhZGVyIHtcbiAgY29uc3RydWN0b3Ioc3RyZWFtLCBxdWV1ZWRDaHVua3MsIHByb2dyZXNzaXZlRG9uZSA9IGZhbHNlLCBjb250ZW50RGlzcG9zaXRpb25GaWxlbmFtZSA9IG51bGwpIHtcbiAgICB0aGlzLl9zdHJlYW0gPSBzdHJlYW07XG4gICAgdGhpcy5fZG9uZSA9IHByb2dyZXNzaXZlRG9uZSB8fCBmYWxzZTtcbiAgICB0aGlzLl9maWxlbmFtZSA9ICgwLCBfZGlzcGxheV91dGlscy5pc1BkZkZpbGUpKGNvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lKSA/IGNvbnRlbnREaXNwb3NpdGlvbkZpbGVuYW1lIDogbnVsbDtcbiAgICB0aGlzLl9xdWV1ZWRDaHVua3MgPSBxdWV1ZWRDaHVua3MgfHwgW107XG4gICAgdGhpcy5fbG9hZGVkID0gMDtcblxuICAgIGZvciAoY29uc3QgY2h1bmsgb2YgdGhpcy5fcXVldWVkQ2h1bmtzKSB7XG4gICAgICB0aGlzLl9sb2FkZWQgKz0gY2h1bmsuYnl0ZUxlbmd0aDtcbiAgICB9XG5cbiAgICB0aGlzLl9yZXF1ZXN0cyA9IFtdO1xuICAgIHRoaXMuX2hlYWRlcnNSZWFkeSA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIHN0cmVhbS5fZnVsbFJlcXVlc3RSZWFkZXIgPSB0aGlzO1xuICAgIHRoaXMub25Qcm9ncmVzcyA9IG51bGw7XG4gIH1cblxuICBfZW5xdWV1ZShjaHVuaykge1xuICAgIGlmICh0aGlzLl9kb25lKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3JlcXVlc3RzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IHJlcXVlc3RDYXBhYmlsaXR5ID0gdGhpcy5fcmVxdWVzdHMuc2hpZnQoKTtcblxuICAgICAgcmVxdWVzdENhcGFiaWxpdHkucmVzb2x2ZSh7XG4gICAgICAgIHZhbHVlOiBjaHVuayxcbiAgICAgICAgZG9uZTogZmFsc2VcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9xdWV1ZWRDaHVua3MucHVzaChjaHVuayk7XG4gICAgfVxuXG4gICAgdGhpcy5fbG9hZGVkICs9IGNodW5rLmJ5dGVMZW5ndGg7XG4gIH1cblxuICBnZXQgaGVhZGVyc1JlYWR5KCkge1xuICAgIHJldHVybiB0aGlzLl9oZWFkZXJzUmVhZHk7XG4gIH1cblxuICBnZXQgZmlsZW5hbWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2ZpbGVuYW1lO1xuICB9XG5cbiAgZ2V0IGlzUmFuZ2VTdXBwb3J0ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0cmVhbS5faXNSYW5nZVN1cHBvcnRlZDtcbiAgfVxuXG4gIGdldCBpc1N0cmVhbWluZ1N1cHBvcnRlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fc3RyZWFtLl9pc1N0cmVhbWluZ1N1cHBvcnRlZDtcbiAgfVxuXG4gIGdldCBjb250ZW50TGVuZ3RoKCkge1xuICAgIHJldHVybiB0aGlzLl9zdHJlYW0uX2NvbnRlbnRMZW5ndGg7XG4gIH1cblxuICBhc3luYyByZWFkKCkge1xuICAgIGlmICh0aGlzLl9xdWV1ZWRDaHVua3MubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgY2h1bmsgPSB0aGlzLl9xdWV1ZWRDaHVua3Muc2hpZnQoKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWU6IGNodW5rLFxuICAgICAgICBkb25lOiBmYWxzZVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZG9uZSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgICAgZG9uZTogdHJ1ZVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCByZXF1ZXN0Q2FwYWJpbGl0eSA9ICgwLCBfdXRpbC5jcmVhdGVQcm9taXNlQ2FwYWJpbGl0eSkoKTtcblxuICAgIHRoaXMuX3JlcXVlc3RzLnB1c2gocmVxdWVzdENhcGFiaWxpdHkpO1xuXG4gICAgcmV0dXJuIHJlcXVlc3RDYXBhYmlsaXR5LnByb21pc2U7XG4gIH1cblxuICBjYW5jZWwocmVhc29uKSB7XG4gICAgdGhpcy5fZG9uZSA9IHRydWU7XG5cbiAgICBmb3IgKGNvbnN0IHJlcXVlc3RDYXBhYmlsaXR5IG9mIHRoaXMuX3JlcXVlc3RzKSB7XG4gICAgICByZXF1ZXN0Q2FwYWJpbGl0eS5yZXNvbHZlKHtcbiAgICAgICAgdmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgICAgZG9uZTogdHJ1ZVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5fcmVxdWVzdHMubGVuZ3RoID0gMDtcbiAgfVxuXG4gIHByb2dyZXNzaXZlRG9uZSgpIHtcbiAgICBpZiAodGhpcy5fZG9uZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2RvbmUgPSB0cnVlO1xuICB9XG5cbn1cblxuY2xhc3MgUERGRGF0YVRyYW5zcG9ydFN0cmVhbVJhbmdlUmVhZGVyIHtcbiAgY29uc3RydWN0b3Ioc3RyZWFtLCBiZWdpbiwgZW5kKSB7XG4gICAgdGhpcy5fc3RyZWFtID0gc3RyZWFtO1xuICAgIHRoaXMuX2JlZ2luID0gYmVnaW47XG4gICAgdGhpcy5fZW5kID0gZW5kO1xuICAgIHRoaXMuX3F1ZXVlZENodW5rID0gbnVsbDtcbiAgICB0aGlzLl9yZXF1ZXN0cyA9IFtdO1xuICAgIHRoaXMuX2RvbmUgPSBmYWxzZTtcbiAgICB0aGlzLm9uUHJvZ3Jlc3MgPSBudWxsO1xuICB9XG5cbiAgX2VucXVldWUoY2h1bmspIHtcbiAgICBpZiAodGhpcy5fZG9uZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9yZXF1ZXN0cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMuX3F1ZXVlZENodW5rID0gY2h1bms7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHJlcXVlc3RzQ2FwYWJpbGl0eSA9IHRoaXMuX3JlcXVlc3RzLnNoaWZ0KCk7XG5cbiAgICAgIHJlcXVlc3RzQ2FwYWJpbGl0eS5yZXNvbHZlKHtcbiAgICAgICAgdmFsdWU6IGNodW5rLFxuICAgICAgICBkb25lOiBmYWxzZVxuICAgICAgfSk7XG5cbiAgICAgIGZvciAoY29uc3QgcmVxdWVzdENhcGFiaWxpdHkgb2YgdGhpcy5fcmVxdWVzdHMpIHtcbiAgICAgICAgcmVxdWVzdENhcGFiaWxpdHkucmVzb2x2ZSh7XG4gICAgICAgICAgdmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgICAgICBkb25lOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9yZXF1ZXN0cy5sZW5ndGggPSAwO1xuICAgIH1cblxuICAgIHRoaXMuX2RvbmUgPSB0cnVlO1xuXG4gICAgdGhpcy5fc3RyZWFtLl9yZW1vdmVSYW5nZVJlYWRlcih0aGlzKTtcbiAgfVxuXG4gIGdldCBpc1N0cmVhbWluZ1N1cHBvcnRlZCgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBhc3luYyByZWFkKCkge1xuICAgIGlmICh0aGlzLl9xdWV1ZWRDaHVuaykge1xuICAgICAgY29uc3QgY2h1bmsgPSB0aGlzLl9xdWV1ZWRDaHVuaztcbiAgICAgIHRoaXMuX3F1ZXVlZENodW5rID0gbnVsbDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbHVlOiBjaHVuayxcbiAgICAgICAgZG9uZTogZmFsc2VcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2RvbmUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbHVlOiB1bmRlZmluZWQsXG4gICAgICAgIGRvbmU6IHRydWVcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgcmVxdWVzdENhcGFiaWxpdHkgPSAoMCwgX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkpKCk7XG5cbiAgICB0aGlzLl9yZXF1ZXN0cy5wdXNoKHJlcXVlc3RDYXBhYmlsaXR5KTtcblxuICAgIHJldHVybiByZXF1ZXN0Q2FwYWJpbGl0eS5wcm9taXNlO1xuICB9XG5cbiAgY2FuY2VsKHJlYXNvbikge1xuICAgIHRoaXMuX2RvbmUgPSB0cnVlO1xuXG4gICAgZm9yIChjb25zdCByZXF1ZXN0Q2FwYWJpbGl0eSBvZiB0aGlzLl9yZXF1ZXN0cykge1xuICAgICAgcmVxdWVzdENhcGFiaWxpdHkucmVzb2x2ZSh7XG4gICAgICAgIHZhbHVlOiB1bmRlZmluZWQsXG4gICAgICAgIGRvbmU6IHRydWVcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuX3JlcXVlc3RzLmxlbmd0aCA9IDA7XG5cbiAgICB0aGlzLl9zdHJlYW0uX3JlbW92ZVJhbmdlUmVhZGVyKHRoaXMpO1xuICB9XG5cbn1cblxuLyoqKi8gfSksXG4vKiAxOCAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5YZmFUZXh0ID0gdm9pZCAwO1xuXG5jbGFzcyBYZmFUZXh0IHtcbiAgc3RhdGljIHRleHRDb250ZW50KHhmYSkge1xuICAgIGNvbnN0IGl0ZW1zID0gW107XG4gICAgY29uc3Qgb3V0cHV0ID0ge1xuICAgICAgaXRlbXMsXG4gICAgICBzdHlsZXM6IE9iamVjdC5jcmVhdGUobnVsbClcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gd2Fsayhub2RlKSB7XG4gICAgICBpZiAoIW5vZGUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBsZXQgc3RyID0gbnVsbDtcbiAgICAgIGNvbnN0IG5hbWUgPSBub2RlLm5hbWU7XG5cbiAgICAgIGlmIChuYW1lID09PSBcIiN0ZXh0XCIpIHtcbiAgICAgICAgc3RyID0gbm9kZS52YWx1ZTtcbiAgICAgIH0gZWxzZSBpZiAoIVhmYVRleHQuc2hvdWxkQnVpbGRUZXh0KG5hbWUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSBpZiAobm9kZT8uYXR0cmlidXRlcz8udGV4dENvbnRlbnQpIHtcbiAgICAgICAgc3RyID0gbm9kZS5hdHRyaWJ1dGVzLnRleHRDb250ZW50O1xuICAgICAgfSBlbHNlIGlmIChub2RlLnZhbHVlKSB7XG4gICAgICAgIHN0ciA9IG5vZGUudmFsdWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChzdHIgIT09IG51bGwpIHtcbiAgICAgICAgaXRlbXMucHVzaCh7XG4gICAgICAgICAgc3RyXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoIW5vZGUuY2hpbGRyZW4pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIG5vZGUuY2hpbGRyZW4pIHtcbiAgICAgICAgd2FsayhjaGlsZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgd2Fsayh4ZmEpO1xuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cblxuICBzdGF0aWMgc2hvdWxkQnVpbGRUZXh0KG5hbWUpIHtcbiAgICByZXR1cm4gIShuYW1lID09PSBcInRleHRhcmVhXCIgfHwgbmFtZSA9PT0gXCJpbnB1dFwiIHx8IG5hbWUgPT09IFwib3B0aW9uXCIgfHwgbmFtZSA9PT0gXCJzZWxlY3RcIik7XG4gIH1cblxufVxuXG5leHBvcnRzLlhmYVRleHQgPSBYZmFUZXh0O1xuXG4vKioqLyB9KSxcbi8qIDE5ICovXG4vKioqLyAoKF9fdW51c2VkX3dlYnBhY2tfbW9kdWxlLCBleHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5leHBvcnRzLk5vZGVTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSA9IGV4cG9ydHMuTm9kZUNhbnZhc0ZhY3RvcnkgPSBleHBvcnRzLk5vZGVDTWFwUmVhZGVyRmFjdG9yeSA9IHZvaWQgMDtcblxudmFyIF9iYXNlX2ZhY3RvcnkgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDYpO1xuXG47XG5cbmNvbnN0IGZldGNoRGF0YSA9IGZ1bmN0aW9uICh1cmwpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBmcyA9IHJlcXVpcmUoXCJmc1wiKTtcblxuICAgIGZzLnJlYWRGaWxlKHVybCwgKGVycm9yLCBkYXRhKSA9PiB7XG4gICAgICBpZiAoZXJyb3IgfHwgIWRhdGEpIHtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihlcnJvcikpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHJlc29sdmUobmV3IFVpbnQ4QXJyYXkoZGF0YSkpO1xuICAgIH0pO1xuICB9KTtcbn07XG5cbmNsYXNzIE5vZGVDYW52YXNGYWN0b3J5IGV4dGVuZHMgX2Jhc2VfZmFjdG9yeS5CYXNlQ2FudmFzRmFjdG9yeSB7XG4gIF9jcmVhdGVDYW52YXMod2lkdGgsIGhlaWdodCkge1xuICAgIGNvbnN0IENhbnZhcyA9IHJlcXVpcmUoXCJjYW52YXNcIik7XG5cbiAgICByZXR1cm4gQ2FudmFzLmNyZWF0ZUNhbnZhcyh3aWR0aCwgaGVpZ2h0KTtcbiAgfVxuXG59XG5cbmV4cG9ydHMuTm9kZUNhbnZhc0ZhY3RvcnkgPSBOb2RlQ2FudmFzRmFjdG9yeTtcblxuY2xhc3MgTm9kZUNNYXBSZWFkZXJGYWN0b3J5IGV4dGVuZHMgX2Jhc2VfZmFjdG9yeS5CYXNlQ01hcFJlYWRlckZhY3Rvcnkge1xuICBfZmV0Y2hEYXRhKHVybCwgY29tcHJlc3Npb25UeXBlKSB7XG4gICAgcmV0dXJuIGZldGNoRGF0YSh1cmwpLnRoZW4oZGF0YSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjTWFwRGF0YTogZGF0YSxcbiAgICAgICAgY29tcHJlc3Npb25UeXBlXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbn1cblxuZXhwb3J0cy5Ob2RlQ01hcFJlYWRlckZhY3RvcnkgPSBOb2RlQ01hcFJlYWRlckZhY3Rvcnk7XG5cbmNsYXNzIE5vZGVTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSBleHRlbmRzIF9iYXNlX2ZhY3RvcnkuQmFzZVN0YW5kYXJkRm9udERhdGFGYWN0b3J5IHtcbiAgX2ZldGNoRGF0YSh1cmwpIHtcbiAgICByZXR1cm4gZmV0Y2hEYXRhKHVybCk7XG4gIH1cblxufVxuXG5leHBvcnRzLk5vZGVTdGFuZGFyZEZvbnREYXRhRmFjdG9yeSA9IE5vZGVTdGFuZGFyZEZvbnREYXRhRmFjdG9yeTtcblxuLyoqKi8gfSksXG4vKiAyMCAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5Bbm5vdGF0aW9uTGF5ZXIgPSB2b2lkIDA7XG5cbnZhciBfdXRpbCA9IF9fd19wZGZqc19yZXF1aXJlX18oMSk7XG5cbnZhciBfZGlzcGxheV91dGlscyA9IF9fd19wZGZqc19yZXF1aXJlX18oNSk7XG5cbnZhciBfYW5ub3RhdGlvbl9zdG9yYWdlID0gX193X3BkZmpzX3JlcXVpcmVfXyg4KTtcblxudmFyIF9zY3JpcHRpbmdfdXRpbHMgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDIxKTtcblxudmFyIF94ZmFfbGF5ZXIgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDIyKTtcblxuY29uc3QgREVGQVVMVF9UQUJfSU5ERVggPSAxMDAwO1xuY29uc3QgR2V0RWxlbWVudHNCeU5hbWVTZXQgPSBuZXcgV2Vha1NldCgpO1xuXG5mdW5jdGlvbiBnZXRSZWN0RGltcyhyZWN0KSB7XG4gIHJldHVybiB7XG4gICAgd2lkdGg6IHJlY3RbMl0gLSByZWN0WzBdLFxuICAgIGhlaWdodDogcmVjdFszXSAtIHJlY3RbMV1cbiAgfTtcbn1cblxuY2xhc3MgQW5ub3RhdGlvbkVsZW1lbnRGYWN0b3J5IHtcbiAgc3RhdGljIGNyZWF0ZShwYXJhbWV0ZXJzKSB7XG4gICAgY29uc3Qgc3VidHlwZSA9IHBhcmFtZXRlcnMuZGF0YS5hbm5vdGF0aW9uVHlwZTtcblxuICAgIHN3aXRjaCAoc3VidHlwZSkge1xuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uVHlwZS5MSU5LOlxuICAgICAgICByZXR1cm4gbmV3IExpbmtBbm5vdGF0aW9uRWxlbWVudChwYXJhbWV0ZXJzKTtcblxuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uVHlwZS5URVhUOlxuICAgICAgICByZXR1cm4gbmV3IFRleHRBbm5vdGF0aW9uRWxlbWVudChwYXJhbWV0ZXJzKTtcblxuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uVHlwZS5XSURHRVQ6XG4gICAgICAgIGNvbnN0IGZpZWxkVHlwZSA9IHBhcmFtZXRlcnMuZGF0YS5maWVsZFR5cGU7XG5cbiAgICAgICAgc3dpdGNoIChmaWVsZFR5cGUpIHtcbiAgICAgICAgICBjYXNlIFwiVHhcIjpcbiAgICAgICAgICAgIHJldHVybiBuZXcgVGV4dFdpZGdldEFubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuXG4gICAgICAgICAgY2FzZSBcIkJ0blwiOlxuICAgICAgICAgICAgaWYgKHBhcmFtZXRlcnMuZGF0YS5yYWRpb0J1dHRvbikge1xuICAgICAgICAgICAgICByZXR1cm4gbmV3IFJhZGlvQnV0dG9uV2lkZ2V0QW5ub3RhdGlvbkVsZW1lbnQocGFyYW1ldGVycyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHBhcmFtZXRlcnMuZGF0YS5jaGVja0JveCkge1xuICAgICAgICAgICAgICByZXR1cm4gbmV3IENoZWNrYm94V2lkZ2V0QW5ub3RhdGlvbkVsZW1lbnQocGFyYW1ldGVycyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBuZXcgUHVzaEJ1dHRvbldpZGdldEFubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuXG4gICAgICAgICAgY2FzZSBcIkNoXCI6XG4gICAgICAgICAgICByZXR1cm4gbmV3IENob2ljZVdpZGdldEFubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBXaWRnZXRBbm5vdGF0aW9uRWxlbWVudChwYXJhbWV0ZXJzKTtcblxuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uVHlwZS5QT1BVUDpcbiAgICAgICAgcmV0dXJuIG5ldyBQb3B1cEFubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuXG4gICAgICBjYXNlIF91dGlsLkFubm90YXRpb25UeXBlLkZSRUVURVhUOlxuICAgICAgICByZXR1cm4gbmV3IEZyZWVUZXh0QW5ub3RhdGlvbkVsZW1lbnQocGFyYW1ldGVycyk7XG5cbiAgICAgIGNhc2UgX3V0aWwuQW5ub3RhdGlvblR5cGUuTElORTpcbiAgICAgICAgcmV0dXJuIG5ldyBMaW5lQW5ub3RhdGlvbkVsZW1lbnQocGFyYW1ldGVycyk7XG5cbiAgICAgIGNhc2UgX3V0aWwuQW5ub3RhdGlvblR5cGUuU1FVQVJFOlxuICAgICAgICByZXR1cm4gbmV3IFNxdWFyZUFubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuXG4gICAgICBjYXNlIF91dGlsLkFubm90YXRpb25UeXBlLkNJUkNMRTpcbiAgICAgICAgcmV0dXJuIG5ldyBDaXJjbGVBbm5vdGF0aW9uRWxlbWVudChwYXJhbWV0ZXJzKTtcblxuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uVHlwZS5QT0xZTElORTpcbiAgICAgICAgcmV0dXJuIG5ldyBQb2x5bGluZUFubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuXG4gICAgICBjYXNlIF91dGlsLkFubm90YXRpb25UeXBlLkNBUkVUOlxuICAgICAgICByZXR1cm4gbmV3IENhcmV0QW5ub3RhdGlvbkVsZW1lbnQocGFyYW1ldGVycyk7XG5cbiAgICAgIGNhc2UgX3V0aWwuQW5ub3RhdGlvblR5cGUuSU5LOlxuICAgICAgICByZXR1cm4gbmV3IElua0Fubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuXG4gICAgICBjYXNlIF91dGlsLkFubm90YXRpb25UeXBlLlBPTFlHT046XG4gICAgICAgIHJldHVybiBuZXcgUG9seWdvbkFubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuXG4gICAgICBjYXNlIF91dGlsLkFubm90YXRpb25UeXBlLkhJR0hMSUdIVDpcbiAgICAgICAgcmV0dXJuIG5ldyBIaWdobGlnaHRBbm5vdGF0aW9uRWxlbWVudChwYXJhbWV0ZXJzKTtcblxuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uVHlwZS5VTkRFUkxJTkU6XG4gICAgICAgIHJldHVybiBuZXcgVW5kZXJsaW5lQW5ub3RhdGlvbkVsZW1lbnQocGFyYW1ldGVycyk7XG5cbiAgICAgIGNhc2UgX3V0aWwuQW5ub3RhdGlvblR5cGUuU1FVSUdHTFk6XG4gICAgICAgIHJldHVybiBuZXcgU3F1aWdnbHlBbm5vdGF0aW9uRWxlbWVudChwYXJhbWV0ZXJzKTtcblxuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uVHlwZS5TVFJJS0VPVVQ6XG4gICAgICAgIHJldHVybiBuZXcgU3RyaWtlT3V0QW5ub3RhdGlvbkVsZW1lbnQocGFyYW1ldGVycyk7XG5cbiAgICAgIGNhc2UgX3V0aWwuQW5ub3RhdGlvblR5cGUuU1RBTVA6XG4gICAgICAgIHJldHVybiBuZXcgU3RhbXBBbm5vdGF0aW9uRWxlbWVudChwYXJhbWV0ZXJzKTtcblxuICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uVHlwZS5GSUxFQVRUQUNITUVOVDpcbiAgICAgICAgcmV0dXJuIG5ldyBGaWxlQXR0YWNobWVudEFubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gbmV3IEFubm90YXRpb25FbGVtZW50KHBhcmFtZXRlcnMpO1xuICAgIH1cbiAgfVxuXG59XG5cbmNsYXNzIEFubm90YXRpb25FbGVtZW50IHtcbiAgY29uc3RydWN0b3IocGFyYW1ldGVycywge1xuICAgIGlzUmVuZGVyYWJsZSA9IGZhbHNlLFxuICAgIGlnbm9yZUJvcmRlciA9IGZhbHNlLFxuICAgIGNyZWF0ZVF1YWRyaWxhdGVyYWxzID0gZmFsc2VcbiAgfSA9IHt9KSB7XG4gICAgdGhpcy5pc1JlbmRlcmFibGUgPSBpc1JlbmRlcmFibGU7XG4gICAgdGhpcy5kYXRhID0gcGFyYW1ldGVycy5kYXRhO1xuICAgIHRoaXMubGF5ZXIgPSBwYXJhbWV0ZXJzLmxheWVyO1xuICAgIHRoaXMucGFnZSA9IHBhcmFtZXRlcnMucGFnZTtcbiAgICB0aGlzLnZpZXdwb3J0ID0gcGFyYW1ldGVycy52aWV3cG9ydDtcbiAgICB0aGlzLmxpbmtTZXJ2aWNlID0gcGFyYW1ldGVycy5saW5rU2VydmljZTtcbiAgICB0aGlzLmRvd25sb2FkTWFuYWdlciA9IHBhcmFtZXRlcnMuZG93bmxvYWRNYW5hZ2VyO1xuICAgIHRoaXMuaW1hZ2VSZXNvdXJjZXNQYXRoID0gcGFyYW1ldGVycy5pbWFnZVJlc291cmNlc1BhdGg7XG4gICAgdGhpcy5yZW5kZXJGb3JtcyA9IHBhcmFtZXRlcnMucmVuZGVyRm9ybXM7XG4gICAgdGhpcy5zdmdGYWN0b3J5ID0gcGFyYW1ldGVycy5zdmdGYWN0b3J5O1xuICAgIHRoaXMuYW5ub3RhdGlvblN0b3JhZ2UgPSBwYXJhbWV0ZXJzLmFubm90YXRpb25TdG9yYWdlO1xuICAgIHRoaXMuZW5hYmxlU2NyaXB0aW5nID0gcGFyYW1ldGVycy5lbmFibGVTY3JpcHRpbmc7XG4gICAgdGhpcy5oYXNKU0FjdGlvbnMgPSBwYXJhbWV0ZXJzLmhhc0pTQWN0aW9ucztcbiAgICB0aGlzLl9maWVsZE9iamVjdHMgPSBwYXJhbWV0ZXJzLmZpZWxkT2JqZWN0cztcbiAgICB0aGlzLl9tb3VzZVN0YXRlID0gcGFyYW1ldGVycy5tb3VzZVN0YXRlO1xuXG4gICAgaWYgKGlzUmVuZGVyYWJsZSkge1xuICAgICAgdGhpcy5jb250YWluZXIgPSB0aGlzLl9jcmVhdGVDb250YWluZXIoaWdub3JlQm9yZGVyKTtcbiAgICB9XG5cbiAgICBpZiAoY3JlYXRlUXVhZHJpbGF0ZXJhbHMpIHtcbiAgICAgIHRoaXMucXVhZHJpbGF0ZXJhbHMgPSB0aGlzLl9jcmVhdGVRdWFkcmlsYXRlcmFscyhpZ25vcmVCb3JkZXIpO1xuICAgIH1cbiAgfVxuXG4gIF9jcmVhdGVDb250YWluZXIoaWdub3JlQm9yZGVyID0gZmFsc2UpIHtcbiAgICBjb25zdCBkYXRhID0gdGhpcy5kYXRhLFxuICAgICAgICAgIHBhZ2UgPSB0aGlzLnBhZ2UsXG4gICAgICAgICAgdmlld3BvcnQgPSB0aGlzLnZpZXdwb3J0O1xuICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzZWN0aW9uXCIpO1xuICAgIGxldCB7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodFxuICAgIH0gPSBnZXRSZWN0RGltcyhkYXRhLnJlY3QpO1xuICAgIGNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJkYXRhLWFubm90YXRpb24taWRcIiwgZGF0YS5pZCk7XG5cbiAgICBjb25zdCByZWN0ID0gX3V0aWwuVXRpbC5ub3JtYWxpemVSZWN0KFtkYXRhLnJlY3RbMF0sIHBhZ2Uudmlld1szXSAtIGRhdGEucmVjdFsxXSArIHBhZ2Uudmlld1sxXSwgZGF0YS5yZWN0WzJdLCBwYWdlLnZpZXdbM10gLSBkYXRhLnJlY3RbM10gKyBwYWdlLnZpZXdbMV1dKTtcblxuICAgIGlmIChkYXRhLmhhc093bkNhbnZhcykge1xuICAgICAgY29uc3QgdHJhbnNmb3JtID0gdmlld3BvcnQudHJhbnNmb3JtLnNsaWNlKCk7XG5cbiAgICAgIGNvbnN0IFtzY2FsZVgsIHNjYWxlWV0gPSBfdXRpbC5VdGlsLnNpbmd1bGFyVmFsdWVEZWNvbXBvc2UyZFNjYWxlKHRyYW5zZm9ybSk7XG5cbiAgICAgIHdpZHRoID0gTWF0aC5jZWlsKHdpZHRoICogc2NhbGVYKTtcbiAgICAgIGhlaWdodCA9IE1hdGguY2VpbChoZWlnaHQgKiBzY2FsZVkpO1xuICAgICAgcmVjdFswXSAqPSBzY2FsZVg7XG4gICAgICByZWN0WzFdICo9IHNjYWxlWTtcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICAgICAgdHJhbnNmb3JtW2ldID0gTWF0aC5zaWduKHRyYW5zZm9ybVtpXSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnRhaW5lci5zdHlsZS50cmFuc2Zvcm0gPSBgbWF0cml4KCR7dHJhbnNmb3JtLmpvaW4oXCIsXCIpfSlgO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250YWluZXIuc3R5bGUudHJhbnNmb3JtID0gYG1hdHJpeCgke3ZpZXdwb3J0LnRyYW5zZm9ybS5qb2luKFwiLFwiKX0pYDtcbiAgICB9XG5cbiAgICBjb250YWluZXIuc3R5bGUudHJhbnNmb3JtT3JpZ2luID0gYCR7LXJlY3RbMF19cHggJHstcmVjdFsxXX1weGA7XG5cbiAgICBpZiAoIWlnbm9yZUJvcmRlciAmJiBkYXRhLmJvcmRlclN0eWxlLndpZHRoID4gMCkge1xuICAgICAgY29udGFpbmVyLnN0eWxlLmJvcmRlcldpZHRoID0gYCR7ZGF0YS5ib3JkZXJTdHlsZS53aWR0aH1weGA7XG5cbiAgICAgIGlmIChkYXRhLmJvcmRlclN0eWxlLnN0eWxlICE9PSBfdXRpbC5Bbm5vdGF0aW9uQm9yZGVyU3R5bGVUeXBlLlVOREVSTElORSkge1xuICAgICAgICB3aWR0aCAtPSAyICogZGF0YS5ib3JkZXJTdHlsZS53aWR0aDtcbiAgICAgICAgaGVpZ2h0IC09IDIgKiBkYXRhLmJvcmRlclN0eWxlLndpZHRoO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBob3Jpem9udGFsUmFkaXVzID0gZGF0YS5ib3JkZXJTdHlsZS5ob3Jpem9udGFsQ29ybmVyUmFkaXVzO1xuICAgICAgY29uc3QgdmVydGljYWxSYWRpdXMgPSBkYXRhLmJvcmRlclN0eWxlLnZlcnRpY2FsQ29ybmVyUmFkaXVzO1xuXG4gICAgICBpZiAoaG9yaXpvbnRhbFJhZGl1cyA+IDAgfHwgdmVydGljYWxSYWRpdXMgPiAwKSB7XG4gICAgICAgIGNvbnN0IHJhZGl1cyA9IGAke2hvcml6b250YWxSYWRpdXN9cHggLyAke3ZlcnRpY2FsUmFkaXVzfXB4YDtcbiAgICAgICAgY29udGFpbmVyLnN0eWxlLmJvcmRlclJhZGl1cyA9IHJhZGl1cztcbiAgICAgIH1cblxuICAgICAgc3dpdGNoIChkYXRhLmJvcmRlclN0eWxlLnN0eWxlKSB7XG4gICAgICAgIGNhc2UgX3V0aWwuQW5ub3RhdGlvbkJvcmRlclN0eWxlVHlwZS5TT0xJRDpcbiAgICAgICAgICBjb250YWluZXIuc3R5bGUuYm9yZGVyU3R5bGUgPSBcInNvbGlkXCI7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uQm9yZGVyU3R5bGVUeXBlLkRBU0hFRDpcbiAgICAgICAgICBjb250YWluZXIuc3R5bGUuYm9yZGVyU3R5bGUgPSBcImRhc2hlZFwiO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgX3V0aWwuQW5ub3RhdGlvbkJvcmRlclN0eWxlVHlwZS5CRVZFTEVEOlxuICAgICAgICAgICgwLCBfdXRpbC53YXJuKShcIlVuaW1wbGVtZW50ZWQgYm9yZGVyIHN0eWxlOiBiZXZlbGVkXCIpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgX3V0aWwuQW5ub3RhdGlvbkJvcmRlclN0eWxlVHlwZS5JTlNFVDpcbiAgICAgICAgICAoMCwgX3V0aWwud2FybikoXCJVbmltcGxlbWVudGVkIGJvcmRlciBzdHlsZTogaW5zZXRcIik7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBfdXRpbC5Bbm5vdGF0aW9uQm9yZGVyU3R5bGVUeXBlLlVOREVSTElORTpcbiAgICAgICAgICBjb250YWluZXIuc3R5bGUuYm9yZGVyQm90dG9tU3R5bGUgPSBcInNvbGlkXCI7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY29uc3QgYm9yZGVyQ29sb3IgPSBkYXRhLmJvcmRlckNvbG9yIHx8IGRhdGEuY29sb3IgfHwgbnVsbDtcblxuICAgICAgaWYgKGJvcmRlckNvbG9yKSB7XG4gICAgICAgIGNvbnRhaW5lci5zdHlsZS5ib3JkZXJDb2xvciA9IF91dGlsLlV0aWwubWFrZUhleENvbG9yKGRhdGEuY29sb3JbMF0gfCAwLCBkYXRhLmNvbG9yWzFdIHwgMCwgZGF0YS5jb2xvclsyXSB8IDApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29udGFpbmVyLnN0eWxlLmJvcmRlcldpZHRoID0gMDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb250YWluZXIuc3R5bGUubGVmdCA9IGAke3JlY3RbMF19cHhgO1xuICAgIGNvbnRhaW5lci5zdHlsZS50b3AgPSBgJHtyZWN0WzFdfXB4YDtcblxuICAgIGlmIChkYXRhLmhhc093bkNhbnZhcykge1xuICAgICAgY29udGFpbmVyLnN0eWxlLndpZHRoID0gY29udGFpbmVyLnN0eWxlLmhlaWdodCA9IFwiYXV0b1wiO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250YWluZXIuc3R5bGUud2lkdGggPSBgJHt3aWR0aH1weGA7XG4gICAgICBjb250YWluZXIuc3R5bGUuaGVpZ2h0ID0gYCR7aGVpZ2h0fXB4YDtcbiAgICB9XG5cbiAgICByZXR1cm4gY29udGFpbmVyO1xuICB9XG5cbiAgZ2V0IF9jb21tb25BY3Rpb25zKCkge1xuICAgIGNvbnN0IHNldENvbG9yID0gKGpzTmFtZSwgc3R5bGVOYW1lLCBldmVudCkgPT4ge1xuICAgICAgY29uc3QgY29sb3IgPSBldmVudC5kZXRhaWxbanNOYW1lXTtcbiAgICAgIGV2ZW50LnRhcmdldC5zdHlsZVtzdHlsZU5hbWVdID0gX3NjcmlwdGluZ191dGlscy5Db2xvckNvbnZlcnRlcnNbYCR7Y29sb3JbMF19X0hUTUxgXShjb2xvci5zbGljZSgxKSk7XG4gICAgfTtcblxuICAgIHJldHVybiAoMCwgX3V0aWwuc2hhZG93KSh0aGlzLCBcIl9jb21tb25BY3Rpb25zXCIsIHtcbiAgICAgIGRpc3BsYXk6IGV2ZW50ID0+IHtcbiAgICAgICAgY29uc3QgaGlkZGVuID0gZXZlbnQuZGV0YWlsLmRpc3BsYXkgJSAyID09PSAxO1xuICAgICAgICBldmVudC50YXJnZXQuc3R5bGUudmlzaWJpbGl0eSA9IGhpZGRlbiA/IFwiaGlkZGVuXCIgOiBcInZpc2libGVcIjtcbiAgICAgICAgdGhpcy5hbm5vdGF0aW9uU3RvcmFnZS5zZXRWYWx1ZSh0aGlzLmRhdGEuaWQsIHtcbiAgICAgICAgICBoaWRkZW4sXG4gICAgICAgICAgcHJpbnQ6IGV2ZW50LmRldGFpbC5kaXNwbGF5ID09PSAwIHx8IGV2ZW50LmRldGFpbC5kaXNwbGF5ID09PSAzXG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICAgIHByaW50OiBldmVudCA9PiB7XG4gICAgICAgIHRoaXMuYW5ub3RhdGlvblN0b3JhZ2Uuc2V0VmFsdWUodGhpcy5kYXRhLmlkLCB7XG4gICAgICAgICAgcHJpbnQ6IGV2ZW50LmRldGFpbC5wcmludFxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICBoaWRkZW46IGV2ZW50ID0+IHtcbiAgICAgICAgZXZlbnQudGFyZ2V0LnN0eWxlLnZpc2liaWxpdHkgPSBldmVudC5kZXRhaWwuaGlkZGVuID8gXCJoaWRkZW5cIiA6IFwidmlzaWJsZVwiO1xuICAgICAgICB0aGlzLmFubm90YXRpb25TdG9yYWdlLnNldFZhbHVlKHRoaXMuZGF0YS5pZCwge1xuICAgICAgICAgIGhpZGRlbjogZXZlbnQuZGV0YWlsLmhpZGRlblxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICBmb2N1czogZXZlbnQgPT4ge1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IGV2ZW50LnRhcmdldC5mb2N1cyh7XG4gICAgICAgICAgcHJldmVudFNjcm9sbDogZmFsc2VcbiAgICAgICAgfSksIDApO1xuICAgICAgfSxcbiAgICAgIHVzZXJOYW1lOiBldmVudCA9PiB7XG4gICAgICAgIGV2ZW50LnRhcmdldC50aXRsZSA9IGV2ZW50LmRldGFpbC51c2VyTmFtZTtcbiAgICAgIH0sXG4gICAgICByZWFkb25seTogZXZlbnQgPT4ge1xuICAgICAgICBpZiAoZXZlbnQuZGV0YWlsLnJlYWRvbmx5KSB7XG4gICAgICAgICAgZXZlbnQudGFyZ2V0LnNldEF0dHJpYnV0ZShcInJlYWRvbmx5XCIsIFwiXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGV2ZW50LnRhcmdldC5yZW1vdmVBdHRyaWJ1dGUoXCJyZWFkb25seVwiKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBldmVudCA9PiB7XG4gICAgICAgIGlmIChldmVudC5kZXRhaWwucmVxdWlyZWQpIHtcbiAgICAgICAgICBldmVudC50YXJnZXQuc2V0QXR0cmlidXRlKFwicmVxdWlyZWRcIiwgXCJcIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZXZlbnQudGFyZ2V0LnJlbW92ZUF0dHJpYnV0ZShcInJlcXVpcmVkXCIpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgYmdDb2xvcjogZXZlbnQgPT4ge1xuICAgICAgICBzZXRDb2xvcihcImJnQ29sb3JcIiwgXCJiYWNrZ3JvdW5kQ29sb3JcIiwgZXZlbnQpO1xuICAgICAgfSxcbiAgICAgIGZpbGxDb2xvcjogZXZlbnQgPT4ge1xuICAgICAgICBzZXRDb2xvcihcImZpbGxDb2xvclwiLCBcImJhY2tncm91bmRDb2xvclwiLCBldmVudCk7XG4gICAgICB9LFxuICAgICAgZmdDb2xvcjogZXZlbnQgPT4ge1xuICAgICAgICBzZXRDb2xvcihcImZnQ29sb3JcIiwgXCJjb2xvclwiLCBldmVudCk7XG4gICAgICB9LFxuICAgICAgdGV4dENvbG9yOiBldmVudCA9PiB7XG4gICAgICAgIHNldENvbG9yKFwidGV4dENvbG9yXCIsIFwiY29sb3JcIiwgZXZlbnQpO1xuICAgICAgfSxcbiAgICAgIGJvcmRlckNvbG9yOiBldmVudCA9PiB7XG4gICAgICAgIHNldENvbG9yKFwiYm9yZGVyQ29sb3JcIiwgXCJib3JkZXJDb2xvclwiLCBldmVudCk7XG4gICAgICB9LFxuICAgICAgc3Ryb2tlQ29sb3I6IGV2ZW50ID0+IHtcbiAgICAgICAgc2V0Q29sb3IoXCJzdHJva2VDb2xvclwiLCBcImJvcmRlckNvbG9yXCIsIGV2ZW50KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIF9kaXNwYXRjaEV2ZW50RnJvbVNhbmRib3goYWN0aW9ucywganNFdmVudCkge1xuICAgIGNvbnN0IGNvbW1vbkFjdGlvbnMgPSB0aGlzLl9jb21tb25BY3Rpb25zO1xuXG4gICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKGpzRXZlbnQuZGV0YWlsKSkge1xuICAgICAgY29uc3QgYWN0aW9uID0gYWN0aW9uc1tuYW1lXSB8fCBjb21tb25BY3Rpb25zW25hbWVdO1xuXG4gICAgICBpZiAoYWN0aW9uKSB7XG4gICAgICAgIGFjdGlvbihqc0V2ZW50KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBfc2V0RGVmYXVsdFByb3BlcnRpZXNGcm9tSlMoZWxlbWVudCkge1xuICAgIGlmICghdGhpcy5lbmFibGVTY3JpcHRpbmcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzdG9yZWREYXRhID0gdGhpcy5hbm5vdGF0aW9uU3RvcmFnZS5nZXRSYXdWYWx1ZSh0aGlzLmRhdGEuaWQpO1xuXG4gICAgaWYgKCFzdG9yZWREYXRhKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY29tbW9uQWN0aW9ucyA9IHRoaXMuX2NvbW1vbkFjdGlvbnM7XG5cbiAgICBmb3IgKGNvbnN0IFthY3Rpb25OYW1lLCBkZXRhaWxdIG9mIE9iamVjdC5lbnRyaWVzKHN0b3JlZERhdGEpKSB7XG4gICAgICBjb25zdCBhY3Rpb24gPSBjb21tb25BY3Rpb25zW2FjdGlvbk5hbWVdO1xuXG4gICAgICBpZiAoYWN0aW9uKSB7XG4gICAgICAgIGFjdGlvbih7XG4gICAgICAgICAgZGV0YWlsLFxuICAgICAgICAgIHRhcmdldDogZWxlbWVudFxuICAgICAgICB9KTtcbiAgICAgICAgZGVsZXRlIHN0b3JlZERhdGFbYWN0aW9uTmFtZV07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgX2NyZWF0ZVF1YWRyaWxhdGVyYWxzKGlnbm9yZUJvcmRlciA9IGZhbHNlKSB7XG4gICAgaWYgKCF0aGlzLmRhdGEucXVhZFBvaW50cykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgcXVhZHJpbGF0ZXJhbHMgPSBbXTtcbiAgICBjb25zdCBzYXZlZFJlY3QgPSB0aGlzLmRhdGEucmVjdDtcblxuICAgIGZvciAoY29uc3QgcXVhZFBvaW50IG9mIHRoaXMuZGF0YS5xdWFkUG9pbnRzKSB7XG4gICAgICB0aGlzLmRhdGEucmVjdCA9IFtxdWFkUG9pbnRbMl0ueCwgcXVhZFBvaW50WzJdLnksIHF1YWRQb2ludFsxXS54LCBxdWFkUG9pbnRbMV0ueV07XG4gICAgICBxdWFkcmlsYXRlcmFscy5wdXNoKHRoaXMuX2NyZWF0ZUNvbnRhaW5lcihpZ25vcmVCb3JkZXIpKTtcbiAgICB9XG5cbiAgICB0aGlzLmRhdGEucmVjdCA9IHNhdmVkUmVjdDtcbiAgICByZXR1cm4gcXVhZHJpbGF0ZXJhbHM7XG4gIH1cblxuICBfY3JlYXRlUG9wdXAodHJpZ2dlciwgZGF0YSkge1xuICAgIGxldCBjb250YWluZXIgPSB0aGlzLmNvbnRhaW5lcjtcblxuICAgIGlmICh0aGlzLnF1YWRyaWxhdGVyYWxzKSB7XG4gICAgICB0cmlnZ2VyID0gdHJpZ2dlciB8fCB0aGlzLnF1YWRyaWxhdGVyYWxzO1xuICAgICAgY29udGFpbmVyID0gdGhpcy5xdWFkcmlsYXRlcmFsc1swXTtcbiAgICB9XG5cbiAgICBpZiAoIXRyaWdnZXIpIHtcbiAgICAgIHRyaWdnZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgdHJpZ2dlci5zdHlsZS5oZWlnaHQgPSBjb250YWluZXIuc3R5bGUuaGVpZ2h0O1xuICAgICAgdHJpZ2dlci5zdHlsZS53aWR0aCA9IGNvbnRhaW5lci5zdHlsZS53aWR0aDtcbiAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZCh0cmlnZ2VyKTtcbiAgICB9XG5cbiAgICBjb25zdCBwb3B1cEVsZW1lbnQgPSBuZXcgUG9wdXBFbGVtZW50KHtcbiAgICAgIGNvbnRhaW5lcixcbiAgICAgIHRyaWdnZXIsXG4gICAgICBjb2xvcjogZGF0YS5jb2xvcixcbiAgICAgIHRpdGxlT2JqOiBkYXRhLnRpdGxlT2JqLFxuICAgICAgbW9kaWZpY2F0aW9uRGF0ZTogZGF0YS5tb2RpZmljYXRpb25EYXRlLFxuICAgICAgY29udGVudHNPYmo6IGRhdGEuY29udGVudHNPYmosXG4gICAgICByaWNoVGV4dDogZGF0YS5yaWNoVGV4dCxcbiAgICAgIGhpZGVXcmFwcGVyOiB0cnVlXG4gICAgfSk7XG4gICAgY29uc3QgcG9wdXAgPSBwb3B1cEVsZW1lbnQucmVuZGVyKCk7XG4gICAgcG9wdXAuc3R5bGUubGVmdCA9IGNvbnRhaW5lci5zdHlsZS53aWR0aDtcbiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQocG9wdXApO1xuICB9XG5cbiAgX3JlbmRlclF1YWRyaWxhdGVyYWxzKGNsYXNzTmFtZSkge1xuICAgIGZvciAoY29uc3QgcXVhZHJpbGF0ZXJhbCBvZiB0aGlzLnF1YWRyaWxhdGVyYWxzKSB7XG4gICAgICBxdWFkcmlsYXRlcmFsLmNsYXNzTmFtZSA9IGNsYXNzTmFtZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5xdWFkcmlsYXRlcmFscztcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICAoMCwgX3V0aWwudW5yZWFjaGFibGUpKFwiQWJzdHJhY3QgbWV0aG9kIGBBbm5vdGF0aW9uRWxlbWVudC5yZW5kZXJgIGNhbGxlZFwiKTtcbiAgfVxuXG4gIF9nZXRFbGVtZW50c0J5TmFtZShuYW1lLCBza2lwSWQgPSBudWxsKSB7XG4gICAgY29uc3QgZmllbGRzID0gW107XG5cbiAgICBpZiAodGhpcy5fZmllbGRPYmplY3RzKSB7XG4gICAgICBjb25zdCBmaWVsZE9iaiA9IHRoaXMuX2ZpZWxkT2JqZWN0c1tuYW1lXTtcblxuICAgICAgaWYgKGZpZWxkT2JqKSB7XG4gICAgICAgIGZvciAoY29uc3Qge1xuICAgICAgICAgIHBhZ2UsXG4gICAgICAgICAgaWQsXG4gICAgICAgICAgZXhwb3J0VmFsdWVzXG4gICAgICAgIH0gb2YgZmllbGRPYmopIHtcbiAgICAgICAgICBpZiAocGFnZSA9PT0gLTEpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChpZCA9PT0gc2tpcElkKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBleHBvcnRWYWx1ZSA9IHR5cGVvZiBleHBvcnRWYWx1ZXMgPT09IFwic3RyaW5nXCIgPyBleHBvcnRWYWx1ZXMgOiBudWxsO1xuICAgICAgICAgIGNvbnN0IGRvbUVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7XG5cbiAgICAgICAgICBpZiAoZG9tRWxlbWVudCAmJiAhR2V0RWxlbWVudHNCeU5hbWVTZXQuaGFzKGRvbUVsZW1lbnQpKSB7XG4gICAgICAgICAgICAoMCwgX3V0aWwud2FybikoYF9nZXRFbGVtZW50c0J5TmFtZSAtIGVsZW1lbnQgbm90IGFsbG93ZWQ6ICR7aWR9YCk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmaWVsZHMucHVzaCh7XG4gICAgICAgICAgICBpZCxcbiAgICAgICAgICAgIGV4cG9ydFZhbHVlLFxuICAgICAgICAgICAgZG9tRWxlbWVudFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmaWVsZHM7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBkb21FbGVtZW50IG9mIGRvY3VtZW50LmdldEVsZW1lbnRzQnlOYW1lKG5hbWUpKSB7XG4gICAgICBjb25zdCB7XG4gICAgICAgIGlkLFxuICAgICAgICBleHBvcnRWYWx1ZVxuICAgICAgfSA9IGRvbUVsZW1lbnQ7XG5cbiAgICAgIGlmIChpZCA9PT0gc2tpcElkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoIUdldEVsZW1lbnRzQnlOYW1lU2V0Lmhhcyhkb21FbGVtZW50KSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgZmllbGRzLnB1c2goe1xuICAgICAgICBpZCxcbiAgICAgICAgZXhwb3J0VmFsdWUsXG4gICAgICAgIGRvbUVsZW1lbnRcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBmaWVsZHM7XG4gIH1cblxuICBzdGF0aWMgZ2V0IHBsYXRmb3JtKCkge1xuICAgIGNvbnN0IHBsYXRmb3JtID0gdHlwZW9mIG5hdmlnYXRvciAhPT0gXCJ1bmRlZmluZWRcIiA/IG5hdmlnYXRvci5wbGF0Zm9ybSA6IFwiXCI7XG4gICAgcmV0dXJuICgwLCBfdXRpbC5zaGFkb3cpKHRoaXMsIFwicGxhdGZvcm1cIiwge1xuICAgICAgaXNXaW46IHBsYXRmb3JtLmluY2x1ZGVzKFwiV2luXCIpLFxuICAgICAgaXNNYWM6IHBsYXRmb3JtLmluY2x1ZGVzKFwiTWFjXCIpXG4gICAgfSk7XG4gIH1cblxufVxuXG5jbGFzcyBMaW5rQW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMsIG9wdGlvbnMgPSBudWxsKSB7XG4gICAgY29uc3QgaXNSZW5kZXJhYmxlID0gISEocGFyYW1ldGVycy5kYXRhLnVybCB8fCBwYXJhbWV0ZXJzLmRhdGEuZGVzdCB8fCBwYXJhbWV0ZXJzLmRhdGEuYWN0aW9uIHx8IHBhcmFtZXRlcnMuZGF0YS5pc1Rvb2x0aXBPbmx5IHx8IHBhcmFtZXRlcnMuZGF0YS5yZXNldEZvcm0gfHwgcGFyYW1ldGVycy5kYXRhLmFjdGlvbnMgJiYgKHBhcmFtZXRlcnMuZGF0YS5hY3Rpb25zLkFjdGlvbiB8fCBwYXJhbWV0ZXJzLmRhdGEuYWN0aW9uc1tcIk1vdXNlIFVwXCJdIHx8IHBhcmFtZXRlcnMuZGF0YS5hY3Rpb25zW1wiTW91c2UgRG93blwiXSkpO1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlzUmVuZGVyYWJsZSxcbiAgICAgIGlnbm9yZUJvcmRlcjogISFvcHRpb25zPy5pZ25vcmVCb3JkZXIsXG4gICAgICBjcmVhdGVRdWFkcmlsYXRlcmFsczogdHJ1ZVxuICAgIH0pO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGNvbnN0IHtcbiAgICAgIGRhdGEsXG4gICAgICBsaW5rU2VydmljZVxuICAgIH0gPSB0aGlzO1xuICAgIGNvbnN0IGxpbmsgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYVwiKTtcblxuICAgIGlmIChkYXRhLnVybCkge1xuICAgICAgbGlua1NlcnZpY2UuYWRkTGlua0F0dHJpYnV0ZXMobGluaywgZGF0YS51cmwsIGRhdGEubmV3V2luZG93KTtcbiAgICB9IGVsc2UgaWYgKGRhdGEuYWN0aW9uKSB7XG4gICAgICB0aGlzLl9iaW5kTmFtZWRBY3Rpb24obGluaywgZGF0YS5hY3Rpb24pO1xuICAgIH0gZWxzZSBpZiAoZGF0YS5kZXN0KSB7XG4gICAgICB0aGlzLl9iaW5kTGluayhsaW5rLCBkYXRhLmRlc3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgaGFzQ2xpY2tBY3Rpb24gPSBmYWxzZTtcblxuICAgICAgaWYgKGRhdGEuYWN0aW9ucyAmJiAoZGF0YS5hY3Rpb25zLkFjdGlvbiB8fCBkYXRhLmFjdGlvbnNbXCJNb3VzZSBVcFwiXSB8fCBkYXRhLmFjdGlvbnNbXCJNb3VzZSBEb3duXCJdKSAmJiB0aGlzLmVuYWJsZVNjcmlwdGluZyAmJiB0aGlzLmhhc0pTQWN0aW9ucykge1xuICAgICAgICBoYXNDbGlja0FjdGlvbiA9IHRydWU7XG5cbiAgICAgICAgdGhpcy5fYmluZEpTQWN0aW9uKGxpbmssIGRhdGEpO1xuICAgICAgfVxuXG4gICAgICBpZiAoZGF0YS5yZXNldEZvcm0pIHtcbiAgICAgICAgdGhpcy5fYmluZFJlc2V0Rm9ybUFjdGlvbihsaW5rLCBkYXRhLnJlc2V0Rm9ybSk7XG4gICAgICB9IGVsc2UgaWYgKCFoYXNDbGlja0FjdGlvbikge1xuICAgICAgICB0aGlzLl9iaW5kTGluayhsaW5rLCBcIlwiKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5xdWFkcmlsYXRlcmFscykge1xuICAgICAgcmV0dXJuIHRoaXMuX3JlbmRlclF1YWRyaWxhdGVyYWxzKFwibGlua0Fubm90YXRpb25cIikubWFwKChxdWFkcmlsYXRlcmFsLCBpbmRleCkgPT4ge1xuICAgICAgICBjb25zdCBsaW5rRWxlbWVudCA9IGluZGV4ID09PSAwID8gbGluayA6IGxpbmsuY2xvbmVOb2RlKCk7XG4gICAgICAgIHF1YWRyaWxhdGVyYWwuYXBwZW5kQ2hpbGQobGlua0VsZW1lbnQpO1xuICAgICAgICByZXR1cm4gcXVhZHJpbGF0ZXJhbDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IFwibGlua0Fubm90YXRpb25cIjtcbiAgICB0aGlzLmNvbnRhaW5lci5hcHBlbmRDaGlsZChsaW5rKTtcbiAgICByZXR1cm4gdGhpcy5jb250YWluZXI7XG4gIH1cblxuICBfYmluZExpbmsobGluaywgZGVzdGluYXRpb24pIHtcbiAgICBsaW5rLmhyZWYgPSB0aGlzLmxpbmtTZXJ2aWNlLmdldERlc3RpbmF0aW9uSGFzaChkZXN0aW5hdGlvbik7XG5cbiAgICBsaW5rLm9uY2xpY2sgPSAoKSA9PiB7XG4gICAgICBpZiAoZGVzdGluYXRpb24pIHtcbiAgICAgICAgdGhpcy5saW5rU2VydmljZS5nb1RvRGVzdGluYXRpb24oZGVzdGluYXRpb24pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIGlmIChkZXN0aW5hdGlvbiB8fCBkZXN0aW5hdGlvbiA9PT0gXCJcIikge1xuICAgICAgbGluay5jbGFzc05hbWUgPSBcImludGVybmFsTGlua1wiO1xuICAgIH1cbiAgfVxuXG4gIF9iaW5kTmFtZWRBY3Rpb24obGluaywgYWN0aW9uKSB7XG4gICAgbGluay5ocmVmID0gdGhpcy5saW5rU2VydmljZS5nZXRBbmNob3JVcmwoXCJcIik7XG5cbiAgICBsaW5rLm9uY2xpY2sgPSAoKSA9PiB7XG4gICAgICB0aGlzLmxpbmtTZXJ2aWNlLmV4ZWN1dGVOYW1lZEFjdGlvbihhY3Rpb24pO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG5cbiAgICBsaW5rLmNsYXNzTmFtZSA9IFwiaW50ZXJuYWxMaW5rXCI7XG4gIH1cblxuICBfYmluZEpTQWN0aW9uKGxpbmssIGRhdGEpIHtcbiAgICBsaW5rLmhyZWYgPSB0aGlzLmxpbmtTZXJ2aWNlLmdldEFuY2hvclVybChcIlwiKTtcbiAgICBjb25zdCBtYXAgPSBuZXcgTWFwKFtbXCJBY3Rpb25cIiwgXCJvbmNsaWNrXCJdLCBbXCJNb3VzZSBVcFwiLCBcIm9ubW91c2V1cFwiXSwgW1wiTW91c2UgRG93blwiLCBcIm9ubW91c2Vkb3duXCJdXSk7XG5cbiAgICBmb3IgKGNvbnN0IG5hbWUgb2YgT2JqZWN0LmtleXMoZGF0YS5hY3Rpb25zKSkge1xuICAgICAgY29uc3QganNOYW1lID0gbWFwLmdldChuYW1lKTtcblxuICAgICAgaWYgKCFqc05hbWUpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGxpbmtbanNOYW1lXSA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5saW5rU2VydmljZS5ldmVudEJ1cz8uZGlzcGF0Y2goXCJkaXNwYXRjaGV2ZW50aW5zYW5kYm94XCIsIHtcbiAgICAgICAgICBzb3VyY2U6IHRoaXMsXG4gICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICBpZDogZGF0YS5pZCxcbiAgICAgICAgICAgIG5hbWVcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICghbGluay5vbmNsaWNrKSB7XG4gICAgICBsaW5rLm9uY2xpY2sgPSAoKSA9PiBmYWxzZTtcbiAgICB9XG5cbiAgICBsaW5rLmNsYXNzTmFtZSA9IFwiaW50ZXJuYWxMaW5rXCI7XG4gIH1cblxuICBfYmluZFJlc2V0Rm9ybUFjdGlvbihsaW5rLCByZXNldEZvcm0pIHtcbiAgICBjb25zdCBvdGhlckNsaWNrQWN0aW9uID0gbGluay5vbmNsaWNrO1xuXG4gICAgaWYgKCFvdGhlckNsaWNrQWN0aW9uKSB7XG4gICAgICBsaW5rLmhyZWYgPSB0aGlzLmxpbmtTZXJ2aWNlLmdldEFuY2hvclVybChcIlwiKTtcbiAgICB9XG5cbiAgICBsaW5rLmNsYXNzTmFtZSA9IFwiaW50ZXJuYWxMaW5rXCI7XG5cbiAgICBpZiAoIXRoaXMuX2ZpZWxkT2JqZWN0cykge1xuICAgICAgKDAsIF91dGlsLndhcm4pKGBfYmluZFJlc2V0Rm9ybUFjdGlvbiAtIFwicmVzZXRGb3JtXCIgYWN0aW9uIG5vdCBzdXBwb3J0ZWQsIGAgKyBcImVuc3VyZSB0aGF0IHRoZSBgZmllbGRPYmplY3RzYCBwYXJhbWV0ZXIgaXMgcHJvdmlkZWQuXCIpO1xuXG4gICAgICBpZiAoIW90aGVyQ2xpY2tBY3Rpb24pIHtcbiAgICAgICAgbGluay5vbmNsaWNrID0gKCkgPT4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsaW5rLm9uY2xpY2sgPSAoKSA9PiB7XG4gICAgICBpZiAob3RoZXJDbGlja0FjdGlvbikge1xuICAgICAgICBvdGhlckNsaWNrQWN0aW9uKCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHtcbiAgICAgICAgZmllbGRzOiByZXNldEZvcm1GaWVsZHMsXG4gICAgICAgIHJlZnM6IHJlc2V0Rm9ybVJlZnMsXG4gICAgICAgIGluY2x1ZGVcbiAgICAgIH0gPSByZXNldEZvcm07XG4gICAgICBjb25zdCBhbGxGaWVsZHMgPSBbXTtcblxuICAgICAgaWYgKHJlc2V0Rm9ybUZpZWxkcy5sZW5ndGggIT09IDAgfHwgcmVzZXRGb3JtUmVmcy5sZW5ndGggIT09IDApIHtcbiAgICAgICAgY29uc3QgZmllbGRJZHMgPSBuZXcgU2V0KHJlc2V0Rm9ybVJlZnMpO1xuXG4gICAgICAgIGZvciAoY29uc3QgZmllbGROYW1lIG9mIHJlc2V0Rm9ybUZpZWxkcykge1xuICAgICAgICAgIGNvbnN0IGZpZWxkcyA9IHRoaXMuX2ZpZWxkT2JqZWN0c1tmaWVsZE5hbWVdIHx8IFtdO1xuXG4gICAgICAgICAgZm9yIChjb25zdCB7XG4gICAgICAgICAgICBpZFxuICAgICAgICAgIH0gb2YgZmllbGRzKSB7XG4gICAgICAgICAgICBmaWVsZElkcy5hZGQoaWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgZmllbGRzIG9mIE9iamVjdC52YWx1ZXModGhpcy5fZmllbGRPYmplY3RzKSkge1xuICAgICAgICAgIGZvciAoY29uc3QgZmllbGQgb2YgZmllbGRzKSB7XG4gICAgICAgICAgICBpZiAoZmllbGRJZHMuaGFzKGZpZWxkLmlkKSA9PT0gaW5jbHVkZSkge1xuICAgICAgICAgICAgICBhbGxGaWVsZHMucHVzaChmaWVsZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGNvbnN0IGZpZWxkcyBvZiBPYmplY3QudmFsdWVzKHRoaXMuX2ZpZWxkT2JqZWN0cykpIHtcbiAgICAgICAgICBhbGxGaWVsZHMucHVzaCguLi5maWVsZHMpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHN0b3JhZ2UgPSB0aGlzLmFubm90YXRpb25TdG9yYWdlO1xuICAgICAgY29uc3QgYWxsSWRzID0gW107XG5cbiAgICAgIGZvciAoY29uc3QgZmllbGQgb2YgYWxsRmllbGRzKSB7XG4gICAgICAgIGNvbnN0IHtcbiAgICAgICAgICBpZFxuICAgICAgICB9ID0gZmllbGQ7XG4gICAgICAgIGFsbElkcy5wdXNoKGlkKTtcblxuICAgICAgICBzd2l0Y2ggKGZpZWxkLnR5cGUpIHtcbiAgICAgICAgICBjYXNlIFwidGV4dFwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGZpZWxkLmRlZmF1bHRWYWx1ZSB8fCBcIlwiO1xuICAgICAgICAgICAgICBzdG9yYWdlLnNldFZhbHVlKGlkLCB7XG4gICAgICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgY2FzZSBcImNoZWNrYm94XCI6XG4gICAgICAgICAgY2FzZSBcInJhZGlvYnV0dG9uXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gZmllbGQuZGVmYXVsdFZhbHVlID09PSBmaWVsZC5leHBvcnRWYWx1ZXM7XG4gICAgICAgICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICAgICAgICB2YWx1ZVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICBjYXNlIFwiY29tYm9ib3hcIjpcbiAgICAgICAgICBjYXNlIFwibGlzdGJveFwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGZpZWxkLmRlZmF1bHRWYWx1ZSB8fCBcIlwiO1xuICAgICAgICAgICAgICBzdG9yYWdlLnNldFZhbHVlKGlkLCB7XG4gICAgICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZG9tRWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTtcblxuICAgICAgICBpZiAoIWRvbUVsZW1lbnQgfHwgIUdldEVsZW1lbnRzQnlOYW1lU2V0Lmhhcyhkb21FbGVtZW50KSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgZG9tRWxlbWVudC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcInJlc2V0Zm9ybVwiKSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmVuYWJsZVNjcmlwdGluZykge1xuICAgICAgICB0aGlzLmxpbmtTZXJ2aWNlLmV2ZW50QnVzPy5kaXNwYXRjaChcImRpc3BhdGNoZXZlbnRpbnNhbmRib3hcIiwge1xuICAgICAgICAgIHNvdXJjZTogdGhpcyxcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIGlkOiBcImFwcFwiLFxuICAgICAgICAgICAgaWRzOiBhbGxJZHMsXG4gICAgICAgICAgICBuYW1lOiBcIlJlc2V0Rm9ybVwiXG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG4gIH1cblxufVxuXG5jbGFzcyBUZXh0QW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCBpc1JlbmRlcmFibGUgPSAhIShwYXJhbWV0ZXJzLmRhdGEuaGFzUG9wdXAgfHwgcGFyYW1ldGVycy5kYXRhLnRpdGxlT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLmNvbnRlbnRzT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLnJpY2hUZXh0Py5zdHIpO1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlzUmVuZGVyYWJsZVxuICAgIH0pO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IFwidGV4dEFubm90YXRpb25cIjtcbiAgICBjb25zdCBpbWFnZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbWdcIik7XG4gICAgaW1hZ2Uuc3R5bGUuaGVpZ2h0ID0gdGhpcy5jb250YWluZXIuc3R5bGUuaGVpZ2h0O1xuICAgIGltYWdlLnN0eWxlLndpZHRoID0gdGhpcy5jb250YWluZXIuc3R5bGUud2lkdGg7XG4gICAgaW1hZ2Uuc3JjID0gdGhpcy5pbWFnZVJlc291cmNlc1BhdGggKyBcImFubm90YXRpb24tXCIgKyB0aGlzLmRhdGEubmFtZS50b0xvd2VyQ2FzZSgpICsgXCIuc3ZnXCI7XG4gICAgaW1hZ2UuYWx0ID0gXCJbe3t0eXBlfX0gQW5ub3RhdGlvbl1cIjtcbiAgICBpbWFnZS5kYXRhc2V0LmwxMG5JZCA9IFwidGV4dF9hbm5vdGF0aW9uX3R5cGVcIjtcbiAgICBpbWFnZS5kYXRhc2V0LmwxMG5BcmdzID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgdHlwZTogdGhpcy5kYXRhLm5hbWVcbiAgICB9KTtcblxuICAgIGlmICghdGhpcy5kYXRhLmhhc1BvcHVwKSB7XG4gICAgICB0aGlzLl9jcmVhdGVQb3B1cChpbWFnZSwgdGhpcy5kYXRhKTtcbiAgICB9XG5cbiAgICB0aGlzLmNvbnRhaW5lci5hcHBlbmRDaGlsZChpbWFnZSk7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgV2lkZ2V0QW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBBbm5vdGF0aW9uRWxlbWVudCB7XG4gIHJlbmRlcigpIHtcbiAgICBpZiAodGhpcy5kYXRhLmFsdGVybmF0aXZlVGV4dCkge1xuICAgICAgdGhpcy5jb250YWluZXIudGl0bGUgPSB0aGlzLmRhdGEuYWx0ZXJuYXRpdmVUZXh0O1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbnRhaW5lcjtcbiAgfVxuXG4gIF9nZXRLZXlNb2RpZmllcihldmVudCkge1xuICAgIGNvbnN0IHtcbiAgICAgIGlzV2luLFxuICAgICAgaXNNYWNcbiAgICB9ID0gQW5ub3RhdGlvbkVsZW1lbnQucGxhdGZvcm07XG4gICAgcmV0dXJuIGlzV2luICYmIGV2ZW50LmN0cmxLZXkgfHwgaXNNYWMgJiYgZXZlbnQubWV0YUtleTtcbiAgfVxuXG4gIF9zZXRFdmVudExpc3RlbmVyKGVsZW1lbnQsIGJhc2VOYW1lLCBldmVudE5hbWUsIHZhbHVlR2V0dGVyKSB7XG4gICAgaWYgKGJhc2VOYW1lLmluY2x1ZGVzKFwibW91c2VcIikpIHtcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihiYXNlTmFtZSwgZXZlbnQgPT4ge1xuICAgICAgICB0aGlzLmxpbmtTZXJ2aWNlLmV2ZW50QnVzPy5kaXNwYXRjaChcImRpc3BhdGNoZXZlbnRpbnNhbmRib3hcIiwge1xuICAgICAgICAgIHNvdXJjZTogdGhpcyxcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIGlkOiB0aGlzLmRhdGEuaWQsXG4gICAgICAgICAgICBuYW1lOiBldmVudE5hbWUsXG4gICAgICAgICAgICB2YWx1ZTogdmFsdWVHZXR0ZXIoZXZlbnQpLFxuICAgICAgICAgICAgc2hpZnQ6IGV2ZW50LnNoaWZ0S2V5LFxuICAgICAgICAgICAgbW9kaWZpZXI6IHRoaXMuX2dldEtleU1vZGlmaWVyKGV2ZW50KVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGJhc2VOYW1lLCBldmVudCA9PiB7XG4gICAgICAgIHRoaXMubGlua1NlcnZpY2UuZXZlbnRCdXM/LmRpc3BhdGNoKFwiZGlzcGF0Y2hldmVudGluc2FuZGJveFwiLCB7XG4gICAgICAgICAgc291cmNlOiB0aGlzLFxuICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgaWQ6IHRoaXMuZGF0YS5pZCxcbiAgICAgICAgICAgIG5hbWU6IGV2ZW50TmFtZSxcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZUdldHRlcihldmVudClcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgX3NldEV2ZW50TGlzdGVuZXJzKGVsZW1lbnQsIG5hbWVzLCBnZXR0ZXIpIHtcbiAgICBmb3IgKGNvbnN0IFtiYXNlTmFtZSwgZXZlbnROYW1lXSBvZiBuYW1lcykge1xuICAgICAgaWYgKGV2ZW50TmFtZSA9PT0gXCJBY3Rpb25cIiB8fCB0aGlzLmRhdGEuYWN0aW9ucz8uW2V2ZW50TmFtZV0pIHtcbiAgICAgICAgdGhpcy5fc2V0RXZlbnRMaXN0ZW5lcihlbGVtZW50LCBiYXNlTmFtZSwgZXZlbnROYW1lLCBnZXR0ZXIpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIF9zZXRCYWNrZ3JvdW5kQ29sb3IoZWxlbWVudCkge1xuICAgIGNvbnN0IGNvbG9yID0gdGhpcy5kYXRhLmJhY2tncm91bmRDb2xvciB8fCBudWxsO1xuICAgIGVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gY29sb3IgPT09IG51bGwgPyBcInRyYW5zcGFyZW50XCIgOiBfdXRpbC5VdGlsLm1ha2VIZXhDb2xvcihjb2xvclswXSwgY29sb3JbMV0sIGNvbG9yWzJdKTtcbiAgfVxuXG59XG5cbmNsYXNzIFRleHRXaWRnZXRBbm5vdGF0aW9uRWxlbWVudCBleHRlbmRzIFdpZGdldEFubm90YXRpb25FbGVtZW50IHtcbiAgY29uc3RydWN0b3IocGFyYW1ldGVycykge1xuICAgIGNvbnN0IGlzUmVuZGVyYWJsZSA9IHBhcmFtZXRlcnMucmVuZGVyRm9ybXMgfHwgIXBhcmFtZXRlcnMuZGF0YS5oYXNBcHBlYXJhbmNlICYmICEhcGFyYW1ldGVycy5kYXRhLmZpZWxkVmFsdWU7XG4gICAgc3VwZXIocGFyYW1ldGVycywge1xuICAgICAgaXNSZW5kZXJhYmxlXG4gICAgfSk7XG4gIH1cblxuICBzZXRQcm9wZXJ0eU9uU2libGluZ3MoYmFzZSwga2V5LCB2YWx1ZSwga2V5SW5TdG9yYWdlKSB7XG4gICAgY29uc3Qgc3RvcmFnZSA9IHRoaXMuYW5ub3RhdGlvblN0b3JhZ2U7XG5cbiAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgdGhpcy5fZ2V0RWxlbWVudHNCeU5hbWUoYmFzZS5uYW1lLCBiYXNlLmlkKSkge1xuICAgICAgaWYgKGVsZW1lbnQuZG9tRWxlbWVudCkge1xuICAgICAgICBlbGVtZW50LmRvbUVsZW1lbnRba2V5XSA9IHZhbHVlO1xuICAgICAgfVxuXG4gICAgICBzdG9yYWdlLnNldFZhbHVlKGVsZW1lbnQuaWQsIHtcbiAgICAgICAgW2tleUluU3RvcmFnZV06IHZhbHVlXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgY29uc3Qgc3RvcmFnZSA9IHRoaXMuYW5ub3RhdGlvblN0b3JhZ2U7XG4gICAgY29uc3QgaWQgPSB0aGlzLmRhdGEuaWQ7XG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NOYW1lID0gXCJ0ZXh0V2lkZ2V0QW5ub3RhdGlvblwiO1xuICAgIGxldCBlbGVtZW50ID0gbnVsbDtcblxuICAgIGlmICh0aGlzLnJlbmRlckZvcm1zKSB7XG4gICAgICBjb25zdCBzdG9yZWREYXRhID0gc3RvcmFnZS5nZXRWYWx1ZShpZCwge1xuICAgICAgICB2YWx1ZTogdGhpcy5kYXRhLmZpZWxkVmFsdWVcbiAgICAgIH0pO1xuICAgICAgY29uc3QgdGV4dENvbnRlbnQgPSBzdG9yZWREYXRhLmZvcm1hdHRlZFZhbHVlIHx8IHN0b3JlZERhdGEudmFsdWUgfHwgXCJcIjtcbiAgICAgIGNvbnN0IGVsZW1lbnREYXRhID0ge1xuICAgICAgICB1c2VyVmFsdWU6IG51bGwsXG4gICAgICAgIGZvcm1hdHRlZFZhbHVlOiBudWxsLFxuICAgICAgICB2YWx1ZU9uRm9jdXM6IFwiXCJcbiAgICAgIH07XG5cbiAgICAgIGlmICh0aGlzLmRhdGEubXVsdGlMaW5lKSB7XG4gICAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidGV4dGFyZWFcIik7XG4gICAgICAgIGVsZW1lbnQudGV4dENvbnRlbnQgPSB0ZXh0Q29udGVudDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIik7XG4gICAgICAgIGVsZW1lbnQudHlwZSA9IFwidGV4dFwiO1xuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShcInZhbHVlXCIsIHRleHRDb250ZW50KTtcbiAgICAgIH1cblxuICAgICAgR2V0RWxlbWVudHNCeU5hbWVTZXQuYWRkKGVsZW1lbnQpO1xuICAgICAgZWxlbWVudC5kaXNhYmxlZCA9IHRoaXMuZGF0YS5yZWFkT25seTtcbiAgICAgIGVsZW1lbnQubmFtZSA9IHRoaXMuZGF0YS5maWVsZE5hbWU7XG4gICAgICBlbGVtZW50LnRhYkluZGV4ID0gREVGQVVMVF9UQUJfSU5ERVg7XG4gICAgICBlbGVtZW50RGF0YS51c2VyVmFsdWUgPSB0ZXh0Q29udGVudDtcbiAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKFwiaWRcIiwgaWQpO1xuICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIiwgZXZlbnQgPT4ge1xuICAgICAgICBzdG9yYWdlLnNldFZhbHVlKGlkLCB7XG4gICAgICAgICAgdmFsdWU6IGV2ZW50LnRhcmdldC52YWx1ZVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zZXRQcm9wZXJ0eU9uU2libGluZ3MoZWxlbWVudCwgXCJ2YWx1ZVwiLCBldmVudC50YXJnZXQudmFsdWUsIFwidmFsdWVcIik7XG4gICAgICB9KTtcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInJlc2V0Zm9ybVwiLCBldmVudCA9PiB7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZSA9IHRoaXMuZGF0YS5kZWZhdWx0RmllbGRWYWx1ZSA/PyBcIlwiO1xuICAgICAgICBlbGVtZW50LnZhbHVlID0gZWxlbWVudERhdGEudXNlclZhbHVlID0gZGVmYXVsdFZhbHVlO1xuICAgICAgICBlbGVtZW50RGF0YS5mb3JtYXR0ZWRWYWx1ZSA9IG51bGw7XG4gICAgICB9KTtcblxuICAgICAgbGV0IGJsdXJMaXN0ZW5lciA9IGV2ZW50ID0+IHtcbiAgICAgICAgY29uc3Qge1xuICAgICAgICAgIGZvcm1hdHRlZFZhbHVlXG4gICAgICAgIH0gPSBlbGVtZW50RGF0YTtcblxuICAgICAgICBpZiAoZm9ybWF0dGVkVmFsdWUgIT09IG51bGwgJiYgZm9ybWF0dGVkVmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGV2ZW50LnRhcmdldC52YWx1ZSA9IGZvcm1hdHRlZFZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgZXZlbnQudGFyZ2V0LnNjcm9sbExlZnQgPSAwO1xuICAgICAgfTtcblxuICAgICAgaWYgKHRoaXMuZW5hYmxlU2NyaXB0aW5nICYmIHRoaXMuaGFzSlNBY3Rpb25zKSB7XG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImZvY3VzXCIsIGV2ZW50ID0+IHtcbiAgICAgICAgICBpZiAoZWxlbWVudERhdGEudXNlclZhbHVlKSB7XG4gICAgICAgICAgICBldmVudC50YXJnZXQudmFsdWUgPSBlbGVtZW50RGF0YS51c2VyVmFsdWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZWxlbWVudERhdGEudmFsdWVPbkZvY3VzID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidXBkYXRlZnJvbXNhbmRib3hcIiwganNFdmVudCA9PiB7XG4gICAgICAgICAgY29uc3QgYWN0aW9ucyA9IHtcbiAgICAgICAgICAgIHZhbHVlKGV2ZW50KSB7XG4gICAgICAgICAgICAgIGVsZW1lbnREYXRhLnVzZXJWYWx1ZSA9IGV2ZW50LmRldGFpbC52YWx1ZSA/PyBcIlwiO1xuICAgICAgICAgICAgICBzdG9yYWdlLnNldFZhbHVlKGlkLCB7XG4gICAgICAgICAgICAgICAgdmFsdWU6IGVsZW1lbnREYXRhLnVzZXJWYWx1ZS50b1N0cmluZygpXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBldmVudC50YXJnZXQudmFsdWUgPSBlbGVtZW50RGF0YS51c2VyVmFsdWU7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBmb3JtYXR0ZWRWYWx1ZShldmVudCkge1xuICAgICAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICAgICAgZm9ybWF0dGVkVmFsdWVcbiAgICAgICAgICAgICAgfSA9IGV2ZW50LmRldGFpbDtcbiAgICAgICAgICAgICAgZWxlbWVudERhdGEuZm9ybWF0dGVkVmFsdWUgPSBmb3JtYXR0ZWRWYWx1ZTtcblxuICAgICAgICAgICAgICBpZiAoZm9ybWF0dGVkVmFsdWUgIT09IG51bGwgJiYgZm9ybWF0dGVkVmFsdWUgIT09IHVuZGVmaW5lZCAmJiBldmVudC50YXJnZXQgIT09IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICBldmVudC50YXJnZXQudmFsdWUgPSBmb3JtYXR0ZWRWYWx1ZTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICAgICAgICBmb3JtYXR0ZWRWYWx1ZVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIHNlbFJhbmdlKGV2ZW50KSB7XG4gICAgICAgICAgICAgIGV2ZW50LnRhcmdldC5zZXRTZWxlY3Rpb25SYW5nZSguLi5ldmVudC5kZXRhaWwuc2VsUmFuZ2UpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIHRoaXMuX2Rpc3BhdGNoRXZlbnRGcm9tU2FuZGJveChhY3Rpb25zLCBqc0V2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImtleWRvd25cIiwgZXZlbnQgPT4ge1xuICAgICAgICAgIGxldCBjb21taXRLZXkgPSAtMTtcblxuICAgICAgICAgIGlmIChldmVudC5rZXkgPT09IFwiRXNjYXBlXCIpIHtcbiAgICAgICAgICAgIGNvbW1pdEtleSA9IDA7XG4gICAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IFwiRW50ZXJcIikge1xuICAgICAgICAgICAgY29tbWl0S2V5ID0gMjtcbiAgICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gXCJUYWJcIikge1xuICAgICAgICAgICAgY29tbWl0S2V5ID0gMztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoY29tbWl0S2V5ID09PSAtMSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgIHZhbHVlXG4gICAgICAgICAgfSA9IGV2ZW50LnRhcmdldDtcblxuICAgICAgICAgIGlmIChlbGVtZW50RGF0YS52YWx1ZU9uRm9jdXMgPT09IHZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZWxlbWVudERhdGEudXNlclZhbHVlID0gdmFsdWU7XG4gICAgICAgICAgdGhpcy5saW5rU2VydmljZS5ldmVudEJ1cz8uZGlzcGF0Y2goXCJkaXNwYXRjaGV2ZW50aW5zYW5kYm94XCIsIHtcbiAgICAgICAgICAgIHNvdXJjZTogdGhpcyxcbiAgICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgICBpZCxcbiAgICAgICAgICAgICAgbmFtZTogXCJLZXlzdHJva2VcIixcbiAgICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICAgIHdpbGxDb21taXQ6IHRydWUsXG4gICAgICAgICAgICAgIGNvbW1pdEtleSxcbiAgICAgICAgICAgICAgc2VsU3RhcnQ6IGV2ZW50LnRhcmdldC5zZWxlY3Rpb25TdGFydCxcbiAgICAgICAgICAgICAgc2VsRW5kOiBldmVudC50YXJnZXQuc2VsZWN0aW9uRW5kXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBfYmx1ckxpc3RlbmVyID0gYmx1ckxpc3RlbmVyO1xuICAgICAgICBibHVyTGlzdGVuZXIgPSBudWxsO1xuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJibHVyXCIsIGV2ZW50ID0+IHtcbiAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICB2YWx1ZVxuICAgICAgICAgIH0gPSBldmVudC50YXJnZXQ7XG4gICAgICAgICAgZWxlbWVudERhdGEudXNlclZhbHVlID0gdmFsdWU7XG5cbiAgICAgICAgICBpZiAodGhpcy5fbW91c2VTdGF0ZS5pc0Rvd24gJiYgZWxlbWVudERhdGEudmFsdWVPbkZvY3VzICE9PSB2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5saW5rU2VydmljZS5ldmVudEJ1cz8uZGlzcGF0Y2goXCJkaXNwYXRjaGV2ZW50aW5zYW5kYm94XCIsIHtcbiAgICAgICAgICAgICAgc291cmNlOiB0aGlzLFxuICAgICAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgICAgICBpZCxcbiAgICAgICAgICAgICAgICBuYW1lOiBcIktleXN0cm9rZVwiLFxuICAgICAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgICAgIHdpbGxDb21taXQ6IHRydWUsXG4gICAgICAgICAgICAgICAgY29tbWl0S2V5OiAxLFxuICAgICAgICAgICAgICAgIHNlbFN0YXJ0OiBldmVudC50YXJnZXQuc2VsZWN0aW9uU3RhcnQsXG4gICAgICAgICAgICAgICAgc2VsRW5kOiBldmVudC50YXJnZXQuc2VsZWN0aW9uRW5kXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIF9ibHVyTGlzdGVuZXIoZXZlbnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodGhpcy5kYXRhLmFjdGlvbnM/LktleXN0cm9rZSkge1xuICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImJlZm9yZWlucHV0XCIsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgICAgdGFyZ2V0XG4gICAgICAgICAgICB9ID0gZXZlbnQ7XG4gICAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgICBzZWxlY3Rpb25TdGFydCxcbiAgICAgICAgICAgICAgc2VsZWN0aW9uRW5kXG4gICAgICAgICAgICB9ID0gdGFyZ2V0O1xuICAgICAgICAgICAgbGV0IHNlbFN0YXJ0ID0gc2VsZWN0aW9uU3RhcnQsXG4gICAgICAgICAgICAgICAgc2VsRW5kID0gc2VsZWN0aW9uRW5kO1xuXG4gICAgICAgICAgICBzd2l0Y2ggKGV2ZW50LmlucHV0VHlwZSkge1xuICAgICAgICAgICAgICBjYXNlIFwiZGVsZXRlV29yZEJhY2t3YXJkXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgY29uc3QgbWF0Y2ggPSB2YWx1ZS5zdWJzdHJpbmcoMCwgc2VsZWN0aW9uU3RhcnQpLm1hdGNoKC9cXHcqW15cXHddKiQvKTtcblxuICAgICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbFN0YXJ0IC09IG1hdGNoWzBdLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGNhc2UgXCJkZWxldGVXb3JkRm9yd2FyZFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGNoID0gdmFsdWUuc3Vic3RyaW5nKHNlbGVjdGlvblN0YXJ0KS5tYXRjaCgvXlteXFx3XSpcXHcqLyk7XG5cbiAgICAgICAgICAgICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgICAgICAgICBzZWxFbmQgKz0gbWF0Y2hbMF0ubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgY2FzZSBcImRlbGV0ZUNvbnRlbnRCYWNrd2FyZFwiOlxuICAgICAgICAgICAgICAgIGlmIChzZWxlY3Rpb25TdGFydCA9PT0gc2VsZWN0aW9uRW5kKSB7XG4gICAgICAgICAgICAgICAgICBzZWxTdGFydCAtPSAxO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgIGNhc2UgXCJkZWxldGVDb250ZW50Rm9yd2FyZFwiOlxuICAgICAgICAgICAgICAgIGlmIChzZWxlY3Rpb25TdGFydCA9PT0gc2VsZWN0aW9uRW5kKSB7XG4gICAgICAgICAgICAgICAgICBzZWxFbmQgKz0gMTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHRoaXMubGlua1NlcnZpY2UuZXZlbnRCdXM/LmRpc3BhdGNoKFwiZGlzcGF0Y2hldmVudGluc2FuZGJveFwiLCB7XG4gICAgICAgICAgICAgIHNvdXJjZTogdGhpcyxcbiAgICAgICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICAgICAgbmFtZTogXCJLZXlzdHJva2VcIixcbiAgICAgICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgICAgICBjaGFuZ2U6IGRhdGEgfHwgXCJcIixcbiAgICAgICAgICAgICAgICB3aWxsQ29tbWl0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzZWxTdGFydCxcbiAgICAgICAgICAgICAgICBzZWxFbmRcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9zZXRFdmVudExpc3RlbmVycyhlbGVtZW50LCBbW1wiZm9jdXNcIiwgXCJGb2N1c1wiXSwgW1wiYmx1clwiLCBcIkJsdXJcIl0sIFtcIm1vdXNlZG93blwiLCBcIk1vdXNlIERvd25cIl0sIFtcIm1vdXNlZW50ZXJcIiwgXCJNb3VzZSBFbnRlclwiXSwgW1wibW91c2VsZWF2ZVwiLCBcIk1vdXNlIEV4aXRcIl0sIFtcIm1vdXNldXBcIiwgXCJNb3VzZSBVcFwiXV0sIGV2ZW50ID0+IGV2ZW50LnRhcmdldC52YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChibHVyTGlzdGVuZXIpIHtcbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwiYmx1clwiLCBibHVyTGlzdGVuZXIpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5kYXRhLm1heExlbiAhPT0gbnVsbCkge1xuICAgICAgICBlbGVtZW50Lm1heExlbmd0aCA9IHRoaXMuZGF0YS5tYXhMZW47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmRhdGEuY29tYikge1xuICAgICAgICBjb25zdCBmaWVsZFdpZHRoID0gdGhpcy5kYXRhLnJlY3RbMl0gLSB0aGlzLmRhdGEucmVjdFswXTtcbiAgICAgICAgY29uc3QgY29tYldpZHRoID0gZmllbGRXaWR0aCAvIHRoaXMuZGF0YS5tYXhMZW47XG4gICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZChcImNvbWJcIik7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUubGV0dGVyU3BhY2luZyA9IGBjYWxjKCR7Y29tYldpZHRofXB4IC0gMWNoKWA7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgZWxlbWVudC50ZXh0Q29udGVudCA9IHRoaXMuZGF0YS5maWVsZFZhbHVlO1xuICAgICAgZWxlbWVudC5zdHlsZS52ZXJ0aWNhbEFsaWduID0gXCJtaWRkbGVcIjtcbiAgICAgIGVsZW1lbnQuc3R5bGUuZGlzcGxheSA9IFwidGFibGUtY2VsbFwiO1xuICAgIH1cblxuICAgIHRoaXMuX3NldFRleHRTdHlsZShlbGVtZW50KTtcblxuICAgIHRoaXMuX3NldEJhY2tncm91bmRDb2xvcihlbGVtZW50KTtcblxuICAgIHRoaXMuX3NldERlZmF1bHRQcm9wZXJ0aWVzRnJvbUpTKGVsZW1lbnQpO1xuXG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbiAgX3NldFRleHRTdHlsZShlbGVtZW50KSB7XG4gICAgY29uc3QgVEVYVF9BTElHTk1FTlQgPSBbXCJsZWZ0XCIsIFwiY2VudGVyXCIsIFwicmlnaHRcIl07XG4gICAgY29uc3Qge1xuICAgICAgZm9udFNpemUsXG4gICAgICBmb250Q29sb3JcbiAgICB9ID0gdGhpcy5kYXRhLmRlZmF1bHRBcHBlYXJhbmNlRGF0YTtcbiAgICBjb25zdCBzdHlsZSA9IGVsZW1lbnQuc3R5bGU7XG5cbiAgICBpZiAoZm9udFNpemUpIHtcbiAgICAgIHN0eWxlLmZvbnRTaXplID0gYCR7Zm9udFNpemV9cHhgO1xuICAgIH1cblxuICAgIHN0eWxlLmNvbG9yID0gX3V0aWwuVXRpbC5tYWtlSGV4Q29sb3IoZm9udENvbG9yWzBdLCBmb250Q29sb3JbMV0sIGZvbnRDb2xvclsyXSk7XG5cbiAgICBpZiAodGhpcy5kYXRhLnRleHRBbGlnbm1lbnQgIT09IG51bGwpIHtcbiAgICAgIHN0eWxlLnRleHRBbGlnbiA9IFRFWFRfQUxJR05NRU5UW3RoaXMuZGF0YS50ZXh0QWxpZ25tZW50XTtcbiAgICB9XG4gIH1cblxufVxuXG5jbGFzcyBDaGVja2JveFdpZGdldEFubm90YXRpb25FbGVtZW50IGV4dGVuZHMgV2lkZ2V0QW5ub3RhdGlvbkVsZW1lbnQge1xuICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzKSB7XG4gICAgc3VwZXIocGFyYW1ldGVycywge1xuICAgICAgaXNSZW5kZXJhYmxlOiBwYXJhbWV0ZXJzLnJlbmRlckZvcm1zXG4gICAgfSk7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgY29uc3Qgc3RvcmFnZSA9IHRoaXMuYW5ub3RhdGlvblN0b3JhZ2U7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuZGF0YTtcbiAgICBjb25zdCBpZCA9IGRhdGEuaWQ7XG4gICAgbGV0IHZhbHVlID0gc3RvcmFnZS5nZXRWYWx1ZShpZCwge1xuICAgICAgdmFsdWU6IGRhdGEuZXhwb3J0VmFsdWUgPT09IGRhdGEuZmllbGRWYWx1ZVxuICAgIH0pLnZhbHVlO1xuXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgdmFsdWUgPSB2YWx1ZSAhPT0gXCJPZmZcIjtcbiAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgdmFsdWVcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IFwiYnV0dG9uV2lkZ2V0QW5ub3RhdGlvbiBjaGVja0JveFwiO1xuICAgIGNvbnN0IGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIik7XG4gICAgR2V0RWxlbWVudHNCeU5hbWVTZXQuYWRkKGVsZW1lbnQpO1xuICAgIGVsZW1lbnQuZGlzYWJsZWQgPSBkYXRhLnJlYWRPbmx5O1xuICAgIGVsZW1lbnQudHlwZSA9IFwiY2hlY2tib3hcIjtcbiAgICBlbGVtZW50Lm5hbWUgPSBkYXRhLmZpZWxkTmFtZTtcblxuICAgIGlmICh2YWx1ZSkge1xuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJjaGVja2VkXCIsIHRydWUpO1xuICAgIH1cblxuICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKFwiaWRcIiwgaWQpO1xuICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKFwiZXhwb3J0VmFsdWVcIiwgZGF0YS5leHBvcnRWYWx1ZSk7XG4gICAgZWxlbWVudC50YWJJbmRleCA9IERFRkFVTFRfVEFCX0lOREVYO1xuICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImNoYW5nZVwiLCBldmVudCA9PiB7XG4gICAgICBjb25zdCB7XG4gICAgICAgIG5hbWUsXG4gICAgICAgIGNoZWNrZWRcbiAgICAgIH0gPSBldmVudC50YXJnZXQ7XG5cbiAgICAgIGZvciAoY29uc3QgY2hlY2tib3ggb2YgdGhpcy5fZ2V0RWxlbWVudHNCeU5hbWUobmFtZSwgaWQpKSB7XG4gICAgICAgIGNvbnN0IGN1ckNoZWNrZWQgPSBjaGVja2VkICYmIGNoZWNrYm94LmV4cG9ydFZhbHVlID09PSBkYXRhLmV4cG9ydFZhbHVlO1xuXG4gICAgICAgIGlmIChjaGVja2JveC5kb21FbGVtZW50KSB7XG4gICAgICAgICAgY2hlY2tib3guZG9tRWxlbWVudC5jaGVja2VkID0gY3VyQ2hlY2tlZDtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoY2hlY2tib3guaWQsIHtcbiAgICAgICAgICB2YWx1ZTogY3VyQ2hlY2tlZFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgc3RvcmFnZS5zZXRWYWx1ZShpZCwge1xuICAgICAgICB2YWx1ZTogY2hlY2tlZFxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwicmVzZXRmb3JtXCIsIGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZSA9IGRhdGEuZGVmYXVsdEZpZWxkVmFsdWUgfHwgXCJPZmZcIjtcbiAgICAgIGV2ZW50LnRhcmdldC5jaGVja2VkID0gZGVmYXVsdFZhbHVlID09PSBkYXRhLmV4cG9ydFZhbHVlO1xuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMuZW5hYmxlU2NyaXB0aW5nICYmIHRoaXMuaGFzSlNBY3Rpb25zKSB7XG4gICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ1cGRhdGVmcm9tc2FuZGJveFwiLCBqc0V2ZW50ID0+IHtcbiAgICAgICAgY29uc3QgYWN0aW9ucyA9IHtcbiAgICAgICAgICB2YWx1ZShldmVudCkge1xuICAgICAgICAgICAgZXZlbnQudGFyZ2V0LmNoZWNrZWQgPSBldmVudC5kZXRhaWwudmFsdWUgIT09IFwiT2ZmXCI7XG4gICAgICAgICAgICBzdG9yYWdlLnNldFZhbHVlKGlkLCB7XG4gICAgICAgICAgICAgIHZhbHVlOiBldmVudC50YXJnZXQuY2hlY2tlZFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5fZGlzcGF0Y2hFdmVudEZyb21TYW5kYm94KGFjdGlvbnMsIGpzRXZlbnQpO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuX3NldEV2ZW50TGlzdGVuZXJzKGVsZW1lbnQsIFtbXCJjaGFuZ2VcIiwgXCJWYWxpZGF0ZVwiXSwgW1wiY2hhbmdlXCIsIFwiQWN0aW9uXCJdLCBbXCJmb2N1c1wiLCBcIkZvY3VzXCJdLCBbXCJibHVyXCIsIFwiQmx1clwiXSwgW1wibW91c2Vkb3duXCIsIFwiTW91c2UgRG93blwiXSwgW1wibW91c2VlbnRlclwiLCBcIk1vdXNlIEVudGVyXCJdLCBbXCJtb3VzZWxlYXZlXCIsIFwiTW91c2UgRXhpdFwiXSwgW1wibW91c2V1cFwiLCBcIk1vdXNlIFVwXCJdXSwgZXZlbnQgPT4gZXZlbnQudGFyZ2V0LmNoZWNrZWQpO1xuICAgIH1cblxuICAgIHRoaXMuX3NldEJhY2tncm91bmRDb2xvcihlbGVtZW50KTtcblxuICAgIHRoaXMuX3NldERlZmF1bHRQcm9wZXJ0aWVzRnJvbUpTKGVsZW1lbnQpO1xuXG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgUmFkaW9CdXR0b25XaWRnZXRBbm5vdGF0aW9uRWxlbWVudCBleHRlbmRzIFdpZGdldEFubm90YXRpb25FbGVtZW50IHtcbiAgY29uc3RydWN0b3IocGFyYW1ldGVycykge1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlzUmVuZGVyYWJsZTogcGFyYW1ldGVycy5yZW5kZXJGb3Jtc1xuICAgIH0pO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IFwiYnV0dG9uV2lkZ2V0QW5ub3RhdGlvbiByYWRpb0J1dHRvblwiO1xuICAgIGNvbnN0IHN0b3JhZ2UgPSB0aGlzLmFubm90YXRpb25TdG9yYWdlO1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLmRhdGE7XG4gICAgY29uc3QgaWQgPSBkYXRhLmlkO1xuICAgIGxldCB2YWx1ZSA9IHN0b3JhZ2UuZ2V0VmFsdWUoaWQsIHtcbiAgICAgIHZhbHVlOiBkYXRhLmZpZWxkVmFsdWUgPT09IGRhdGEuYnV0dG9uVmFsdWVcbiAgICB9KS52YWx1ZTtcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHZhbHVlID0gdmFsdWUgIT09IGRhdGEuYnV0dG9uVmFsdWU7XG4gICAgICBzdG9yYWdlLnNldFZhbHVlKGlkLCB7XG4gICAgICAgIHZhbHVlXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImlucHV0XCIpO1xuICAgIEdldEVsZW1lbnRzQnlOYW1lU2V0LmFkZChlbGVtZW50KTtcbiAgICBlbGVtZW50LmRpc2FibGVkID0gZGF0YS5yZWFkT25seTtcbiAgICBlbGVtZW50LnR5cGUgPSBcInJhZGlvXCI7XG4gICAgZWxlbWVudC5uYW1lID0gZGF0YS5maWVsZE5hbWU7XG5cbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKFwiY2hlY2tlZFwiLCB0cnVlKTtcbiAgICB9XG5cbiAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShcImlkXCIsIGlkKTtcbiAgICBlbGVtZW50LnRhYkluZGV4ID0gREVGQVVMVF9UQUJfSU5ERVg7XG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwiY2hhbmdlXCIsIGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgY2hlY2tlZFxuICAgICAgfSA9IGV2ZW50LnRhcmdldDtcblxuICAgICAgZm9yIChjb25zdCByYWRpbyBvZiB0aGlzLl9nZXRFbGVtZW50c0J5TmFtZShuYW1lLCBpZCkpIHtcbiAgICAgICAgc3RvcmFnZS5zZXRWYWx1ZShyYWRpby5pZCwge1xuICAgICAgICAgIHZhbHVlOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgc3RvcmFnZS5zZXRWYWx1ZShpZCwge1xuICAgICAgICB2YWx1ZTogY2hlY2tlZFxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwicmVzZXRmb3JtXCIsIGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZSA9IGRhdGEuZGVmYXVsdEZpZWxkVmFsdWU7XG4gICAgICBldmVudC50YXJnZXQuY2hlY2tlZCA9IGRlZmF1bHRWYWx1ZSAhPT0gbnVsbCAmJiBkZWZhdWx0VmFsdWUgIT09IHVuZGVmaW5lZCAmJiBkZWZhdWx0VmFsdWUgPT09IGRhdGEuYnV0dG9uVmFsdWU7XG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5lbmFibGVTY3JpcHRpbmcgJiYgdGhpcy5oYXNKU0FjdGlvbnMpIHtcbiAgICAgIGNvbnN0IHBkZkJ1dHRvblZhbHVlID0gZGF0YS5idXR0b25WYWx1ZTtcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInVwZGF0ZWZyb21zYW5kYm94XCIsIGpzRXZlbnQgPT4ge1xuICAgICAgICBjb25zdCBhY3Rpb25zID0ge1xuICAgICAgICAgIHZhbHVlOiBldmVudCA9PiB7XG4gICAgICAgICAgICBjb25zdCBjaGVja2VkID0gcGRmQnV0dG9uVmFsdWUgPT09IGV2ZW50LmRldGFpbC52YWx1ZTtcblxuICAgICAgICAgICAgZm9yIChjb25zdCByYWRpbyBvZiB0aGlzLl9nZXRFbGVtZW50c0J5TmFtZShldmVudC50YXJnZXQubmFtZSkpIHtcbiAgICAgICAgICAgICAgY29uc3QgY3VyQ2hlY2tlZCA9IGNoZWNrZWQgJiYgcmFkaW8uaWQgPT09IGlkO1xuXG4gICAgICAgICAgICAgIGlmIChyYWRpby5kb21FbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgcmFkaW8uZG9tRWxlbWVudC5jaGVja2VkID0gY3VyQ2hlY2tlZDtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUocmFkaW8uaWQsIHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogY3VyQ2hlY2tlZFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5fZGlzcGF0Y2hFdmVudEZyb21TYW5kYm94KGFjdGlvbnMsIGpzRXZlbnQpO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuX3NldEV2ZW50TGlzdGVuZXJzKGVsZW1lbnQsIFtbXCJjaGFuZ2VcIiwgXCJWYWxpZGF0ZVwiXSwgW1wiY2hhbmdlXCIsIFwiQWN0aW9uXCJdLCBbXCJmb2N1c1wiLCBcIkZvY3VzXCJdLCBbXCJibHVyXCIsIFwiQmx1clwiXSwgW1wibW91c2Vkb3duXCIsIFwiTW91c2UgRG93blwiXSwgW1wibW91c2VlbnRlclwiLCBcIk1vdXNlIEVudGVyXCJdLCBbXCJtb3VzZWxlYXZlXCIsIFwiTW91c2UgRXhpdFwiXSwgW1wibW91c2V1cFwiLCBcIk1vdXNlIFVwXCJdXSwgZXZlbnQgPT4gZXZlbnQudGFyZ2V0LmNoZWNrZWQpO1xuICAgIH1cblxuICAgIHRoaXMuX3NldEJhY2tncm91bmRDb2xvcihlbGVtZW50KTtcblxuICAgIHRoaXMuX3NldERlZmF1bHRQcm9wZXJ0aWVzRnJvbUpTKGVsZW1lbnQpO1xuXG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgUHVzaEJ1dHRvbldpZGdldEFubm90YXRpb25FbGVtZW50IGV4dGVuZHMgTGlua0Fubm90YXRpb25FbGVtZW50IHtcbiAgY29uc3RydWN0b3IocGFyYW1ldGVycykge1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlnbm9yZUJvcmRlcjogcGFyYW1ldGVycy5kYXRhLmhhc0FwcGVhcmFuY2VcbiAgICB9KTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBjb25zdCBjb250YWluZXIgPSBzdXBlci5yZW5kZXIoKTtcbiAgICBjb250YWluZXIuY2xhc3NOYW1lID0gXCJidXR0b25XaWRnZXRBbm5vdGF0aW9uIHB1c2hCdXR0b25cIjtcblxuICAgIGlmICh0aGlzLmRhdGEuYWx0ZXJuYXRpdmVUZXh0KSB7XG4gICAgICBjb250YWluZXIudGl0bGUgPSB0aGlzLmRhdGEuYWx0ZXJuYXRpdmVUZXh0O1xuICAgIH1cblxuICAgIHRoaXMuX3NldERlZmF1bHRQcm9wZXJ0aWVzRnJvbUpTKGNvbnRhaW5lcik7XG5cbiAgICByZXR1cm4gY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgQ2hvaWNlV2lkZ2V0QW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBXaWRnZXRBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICBzdXBlcihwYXJhbWV0ZXJzLCB7XG4gICAgICBpc1JlbmRlcmFibGU6IHBhcmFtZXRlcnMucmVuZGVyRm9ybXNcbiAgICB9KTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICB0aGlzLmNvbnRhaW5lci5jbGFzc05hbWUgPSBcImNob2ljZVdpZGdldEFubm90YXRpb25cIjtcbiAgICBjb25zdCBzdG9yYWdlID0gdGhpcy5hbm5vdGF0aW9uU3RvcmFnZTtcbiAgICBjb25zdCBpZCA9IHRoaXMuZGF0YS5pZDtcbiAgICBjb25zdCBzdG9yZWREYXRhID0gc3RvcmFnZS5nZXRWYWx1ZShpZCwge1xuICAgICAgdmFsdWU6IHRoaXMuZGF0YS5maWVsZFZhbHVlXG4gICAgfSk7XG4gICAgbGV0IHtcbiAgICAgIGZvbnRTaXplXG4gICAgfSA9IHRoaXMuZGF0YS5kZWZhdWx0QXBwZWFyYW5jZURhdGE7XG5cbiAgICBpZiAoIWZvbnRTaXplKSB7XG4gICAgICBmb250U2l6ZSA9IDk7XG4gICAgfVxuXG4gICAgY29uc3QgZm9udFNpemVTdHlsZSA9IGBjYWxjKCR7Zm9udFNpemV9cHggKiB2YXIoLS16b29tLWZhY3RvcikpYDtcbiAgICBjb25zdCBzZWxlY3RFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNlbGVjdFwiKTtcbiAgICBHZXRFbGVtZW50c0J5TmFtZVNldC5hZGQoc2VsZWN0RWxlbWVudCk7XG4gICAgc2VsZWN0RWxlbWVudC5kaXNhYmxlZCA9IHRoaXMuZGF0YS5yZWFkT25seTtcbiAgICBzZWxlY3RFbGVtZW50Lm5hbWUgPSB0aGlzLmRhdGEuZmllbGROYW1lO1xuICAgIHNlbGVjdEVsZW1lbnQuc2V0QXR0cmlidXRlKFwiaWRcIiwgaWQpO1xuICAgIHNlbGVjdEVsZW1lbnQudGFiSW5kZXggPSBERUZBVUxUX1RBQl9JTkRFWDtcbiAgICBzZWxlY3RFbGVtZW50LnN0eWxlLmZvbnRTaXplID0gYCR7Zm9udFNpemV9cHhgO1xuXG4gICAgaWYgKCF0aGlzLmRhdGEuY29tYm8pIHtcbiAgICAgIHNlbGVjdEVsZW1lbnQuc2l6ZSA9IHRoaXMuZGF0YS5vcHRpb25zLmxlbmd0aDtcblxuICAgICAgaWYgKHRoaXMuZGF0YS5tdWx0aVNlbGVjdCkge1xuICAgICAgICBzZWxlY3RFbGVtZW50Lm11bHRpcGxlID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzZWxlY3RFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJyZXNldGZvcm1cIiwgZXZlbnQgPT4ge1xuICAgICAgY29uc3QgZGVmYXVsdFZhbHVlID0gdGhpcy5kYXRhLmRlZmF1bHRGaWVsZFZhbHVlO1xuXG4gICAgICBmb3IgKGNvbnN0IG9wdGlvbiBvZiBzZWxlY3RFbGVtZW50Lm9wdGlvbnMpIHtcbiAgICAgICAgb3B0aW9uLnNlbGVjdGVkID0gb3B0aW9uLnZhbHVlID09PSBkZWZhdWx0VmFsdWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBmb3IgKGNvbnN0IG9wdGlvbiBvZiB0aGlzLmRhdGEub3B0aW9ucykge1xuICAgICAgY29uc3Qgb3B0aW9uRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJvcHRpb25cIik7XG4gICAgICBvcHRpb25FbGVtZW50LnRleHRDb250ZW50ID0gb3B0aW9uLmRpc3BsYXlWYWx1ZTtcbiAgICAgIG9wdGlvbkVsZW1lbnQudmFsdWUgPSBvcHRpb24uZXhwb3J0VmFsdWU7XG5cbiAgICAgIGlmICh0aGlzLmRhdGEuY29tYm8pIHtcbiAgICAgICAgb3B0aW9uRWxlbWVudC5zdHlsZS5mb250U2l6ZSA9IGZvbnRTaXplU3R5bGU7XG4gICAgICB9XG5cbiAgICAgIGlmIChzdG9yZWREYXRhLnZhbHVlLmluY2x1ZGVzKG9wdGlvbi5leHBvcnRWYWx1ZSkpIHtcbiAgICAgICAgb3B0aW9uRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJzZWxlY3RlZFwiLCB0cnVlKTtcbiAgICAgIH1cblxuICAgICAgc2VsZWN0RWxlbWVudC5hcHBlbmRDaGlsZChvcHRpb25FbGVtZW50KTtcbiAgICB9XG5cbiAgICBjb25zdCBnZXRWYWx1ZSA9IChldmVudCwgaXNFeHBvcnQpID0+IHtcbiAgICAgIGNvbnN0IG5hbWUgPSBpc0V4cG9ydCA/IFwidmFsdWVcIiA6IFwidGV4dENvbnRlbnRcIjtcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSBldmVudC50YXJnZXQub3B0aW9ucztcblxuICAgICAgaWYgKCFldmVudC50YXJnZXQubXVsdGlwbGUpIHtcbiAgICAgICAgcmV0dXJuIG9wdGlvbnMuc2VsZWN0ZWRJbmRleCA9PT0gLTEgPyBudWxsIDogb3B0aW9uc1tvcHRpb25zLnNlbGVjdGVkSW5kZXhdW25hbWVdO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gQXJyYXkucHJvdG90eXBlLmZpbHRlci5jYWxsKG9wdGlvbnMsIG9wdGlvbiA9PiBvcHRpb24uc2VsZWN0ZWQpLm1hcChvcHRpb24gPT4gb3B0aW9uW25hbWVdKTtcbiAgICB9O1xuXG4gICAgY29uc3QgZ2V0SXRlbXMgPSBldmVudCA9PiB7XG4gICAgICBjb25zdCBvcHRpb25zID0gZXZlbnQudGFyZ2V0Lm9wdGlvbnM7XG4gICAgICByZXR1cm4gQXJyYXkucHJvdG90eXBlLm1hcC5jYWxsKG9wdGlvbnMsIG9wdGlvbiA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZGlzcGxheVZhbHVlOiBvcHRpb24udGV4dENvbnRlbnQsXG4gICAgICAgICAgZXhwb3J0VmFsdWU6IG9wdGlvbi52YWx1ZVxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIGlmICh0aGlzLmVuYWJsZVNjcmlwdGluZyAmJiB0aGlzLmhhc0pTQWN0aW9ucykge1xuICAgICAgc2VsZWN0RWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidXBkYXRlZnJvbXNhbmRib3hcIiwganNFdmVudCA9PiB7XG4gICAgICAgIGNvbnN0IGFjdGlvbnMgPSB7XG4gICAgICAgICAgdmFsdWUoZXZlbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gZXZlbnQuZGV0YWlsLnZhbHVlO1xuICAgICAgICAgICAgY29uc3QgdmFsdWVzID0gbmV3IFNldChBcnJheS5pc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW3ZhbHVlXSk7XG5cbiAgICAgICAgICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIHNlbGVjdEVsZW1lbnQub3B0aW9ucykge1xuICAgICAgICAgICAgICBvcHRpb24uc2VsZWN0ZWQgPSB2YWx1ZXMuaGFzKG9wdGlvbi52YWx1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICAgICAgdmFsdWU6IGdldFZhbHVlKGV2ZW50LCB0cnVlKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcblxuICAgICAgICAgIG11bHRpcGxlU2VsZWN0aW9uKGV2ZW50KSB7XG4gICAgICAgICAgICBzZWxlY3RFbGVtZW50Lm11bHRpcGxlID0gdHJ1ZTtcbiAgICAgICAgICB9LFxuXG4gICAgICAgICAgcmVtb3ZlKGV2ZW50KSB7XG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0gc2VsZWN0RWxlbWVudC5vcHRpb25zO1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBldmVudC5kZXRhaWwucmVtb3ZlO1xuICAgICAgICAgICAgb3B0aW9uc1tpbmRleF0uc2VsZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHNlbGVjdEVsZW1lbnQucmVtb3ZlKGluZGV4KTtcblxuICAgICAgICAgICAgaWYgKG9wdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICBjb25zdCBpID0gQXJyYXkucHJvdG90eXBlLmZpbmRJbmRleC5jYWxsKG9wdGlvbnMsIG9wdGlvbiA9PiBvcHRpb24uc2VsZWN0ZWQpO1xuXG4gICAgICAgICAgICAgIGlmIChpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIG9wdGlvbnNbMF0uc2VsZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICAgICAgdmFsdWU6IGdldFZhbHVlKGV2ZW50LCB0cnVlKSxcbiAgICAgICAgICAgICAgaXRlbXM6IGdldEl0ZW1zKGV2ZW50KVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcblxuICAgICAgICAgIGNsZWFyKGV2ZW50KSB7XG4gICAgICAgICAgICB3aGlsZSAoc2VsZWN0RWxlbWVudC5sZW5ndGggIT09IDApIHtcbiAgICAgICAgICAgICAgc2VsZWN0RWxlbWVudC5yZW1vdmUoMCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICAgICAgdmFsdWU6IG51bGwsXG4gICAgICAgICAgICAgIGl0ZW1zOiBbXVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcblxuICAgICAgICAgIGluc2VydChldmVudCkge1xuICAgICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgICBpbmRleCxcbiAgICAgICAgICAgICAgZGlzcGxheVZhbHVlLFxuICAgICAgICAgICAgICBleHBvcnRWYWx1ZVxuICAgICAgICAgICAgfSA9IGV2ZW50LmRldGFpbC5pbnNlcnQ7XG4gICAgICAgICAgICBjb25zdCBvcHRpb25FbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcIm9wdGlvblwiKTtcbiAgICAgICAgICAgIG9wdGlvbkVsZW1lbnQudGV4dENvbnRlbnQgPSBkaXNwbGF5VmFsdWU7XG4gICAgICAgICAgICBvcHRpb25FbGVtZW50LnZhbHVlID0gZXhwb3J0VmFsdWU7XG4gICAgICAgICAgICBzZWxlY3RFbGVtZW50Lmluc2VydEJlZm9yZShvcHRpb25FbGVtZW50LCBzZWxlY3RFbGVtZW50LmNoaWxkcmVuW2luZGV4XSk7XG4gICAgICAgICAgICBzdG9yYWdlLnNldFZhbHVlKGlkLCB7XG4gICAgICAgICAgICAgIHZhbHVlOiBnZXRWYWx1ZShldmVudCwgdHJ1ZSksXG4gICAgICAgICAgICAgIGl0ZW1zOiBnZXRJdGVtcyhldmVudClcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sXG5cbiAgICAgICAgICBpdGVtcyhldmVudCkge1xuICAgICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgICBpdGVtc1xuICAgICAgICAgICAgfSA9IGV2ZW50LmRldGFpbDtcblxuICAgICAgICAgICAgd2hpbGUgKHNlbGVjdEVsZW1lbnQubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICAgIHNlbGVjdEVsZW1lbnQucmVtb3ZlKDApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHtcbiAgICAgICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgICAgIGRpc3BsYXlWYWx1ZSxcbiAgICAgICAgICAgICAgICBleHBvcnRWYWx1ZVxuICAgICAgICAgICAgICB9ID0gaXRlbTtcbiAgICAgICAgICAgICAgY29uc3Qgb3B0aW9uRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJvcHRpb25cIik7XG4gICAgICAgICAgICAgIG9wdGlvbkVsZW1lbnQudGV4dENvbnRlbnQgPSBkaXNwbGF5VmFsdWU7XG4gICAgICAgICAgICAgIG9wdGlvbkVsZW1lbnQudmFsdWUgPSBleHBvcnRWYWx1ZTtcbiAgICAgICAgICAgICAgc2VsZWN0RWxlbWVudC5hcHBlbmRDaGlsZChvcHRpb25FbGVtZW50KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHNlbGVjdEVsZW1lbnQub3B0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIHNlbGVjdEVsZW1lbnQub3B0aW9uc1swXS5zZWxlY3RlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICAgICAgdmFsdWU6IGdldFZhbHVlKGV2ZW50LCB0cnVlKSxcbiAgICAgICAgICAgICAgaXRlbXM6IGdldEl0ZW1zKGV2ZW50KVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcblxuICAgICAgICAgIGluZGljZXMoZXZlbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IGluZGljZXMgPSBuZXcgU2V0KGV2ZW50LmRldGFpbC5pbmRpY2VzKTtcblxuICAgICAgICAgICAgZm9yIChjb25zdCBvcHRpb24gb2YgZXZlbnQudGFyZ2V0Lm9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgb3B0aW9uLnNlbGVjdGVkID0gaW5kaWNlcy5oYXMob3B0aW9uLmluZGV4KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc3RvcmFnZS5zZXRWYWx1ZShpZCwge1xuICAgICAgICAgICAgICB2YWx1ZTogZ2V0VmFsdWUoZXZlbnQsIHRydWUpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9LFxuXG4gICAgICAgICAgZWRpdGFibGUoZXZlbnQpIHtcbiAgICAgICAgICAgIGV2ZW50LnRhcmdldC5kaXNhYmxlZCA9ICFldmVudC5kZXRhaWwuZWRpdGFibGU7XG4gICAgICAgICAgfVxuXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5fZGlzcGF0Y2hFdmVudEZyb21TYW5kYm94KGFjdGlvbnMsIGpzRXZlbnQpO1xuICAgICAgfSk7XG4gICAgICBzZWxlY3RFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJpbnB1dFwiLCBldmVudCA9PiB7XG4gICAgICAgIGNvbnN0IGV4cG9ydFZhbHVlID0gZ2V0VmFsdWUoZXZlbnQsIHRydWUpO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGdldFZhbHVlKGV2ZW50LCBmYWxzZSk7XG4gICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICB2YWx1ZTogZXhwb3J0VmFsdWVcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubGlua1NlcnZpY2UuZXZlbnRCdXM/LmRpc3BhdGNoKFwiZGlzcGF0Y2hldmVudGluc2FuZGJveFwiLCB7XG4gICAgICAgICAgc291cmNlOiB0aGlzLFxuICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICBuYW1lOiBcIktleXN0cm9rZVwiLFxuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICBjaGFuZ2VFeDogZXhwb3J0VmFsdWUsXG4gICAgICAgICAgICB3aWxsQ29tbWl0OiB0cnVlLFxuICAgICAgICAgICAgY29tbWl0S2V5OiAxLFxuICAgICAgICAgICAga2V5RG93bjogZmFsc2VcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuX3NldEV2ZW50TGlzdGVuZXJzKHNlbGVjdEVsZW1lbnQsIFtbXCJmb2N1c1wiLCBcIkZvY3VzXCJdLCBbXCJibHVyXCIsIFwiQmx1clwiXSwgW1wibW91c2Vkb3duXCIsIFwiTW91c2UgRG93blwiXSwgW1wibW91c2VlbnRlclwiLCBcIk1vdXNlIEVudGVyXCJdLCBbXCJtb3VzZWxlYXZlXCIsIFwiTW91c2UgRXhpdFwiXSwgW1wibW91c2V1cFwiLCBcIk1vdXNlIFVwXCJdLCBbXCJpbnB1dFwiLCBcIkFjdGlvblwiXV0sIGV2ZW50ID0+IGV2ZW50LnRhcmdldC5jaGVja2VkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2VsZWN0RWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIiwgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICB2YWx1ZTogZ2V0VmFsdWUoZXZlbnQsIHRydWUpXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5fc2V0QmFja2dyb3VuZENvbG9yKHNlbGVjdEVsZW1lbnQpO1xuXG4gICAgdGhpcy5fc2V0RGVmYXVsdFByb3BlcnRpZXNGcm9tSlMoc2VsZWN0RWxlbWVudCk7XG5cbiAgICB0aGlzLmNvbnRhaW5lci5hcHBlbmRDaGlsZChzZWxlY3RFbGVtZW50KTtcbiAgICByZXR1cm4gdGhpcy5jb250YWluZXI7XG4gIH1cblxufVxuXG5jbGFzcyBQb3B1cEFubm90YXRpb25FbGVtZW50IGV4dGVuZHMgQW5ub3RhdGlvbkVsZW1lbnQge1xuICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzKSB7XG4gICAgY29uc3QgaXNSZW5kZXJhYmxlID0gISEocGFyYW1ldGVycy5kYXRhLnRpdGxlT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLmNvbnRlbnRzT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLnJpY2hUZXh0Py5zdHIpO1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlzUmVuZGVyYWJsZVxuICAgIH0pO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGNvbnN0IElHTk9SRV9UWVBFUyA9IFtcIkxpbmVcIiwgXCJTcXVhcmVcIiwgXCJDaXJjbGVcIiwgXCJQb2x5TGluZVwiLCBcIlBvbHlnb25cIiwgXCJJbmtcIl07XG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NOYW1lID0gXCJwb3B1cEFubm90YXRpb25cIjtcblxuICAgIGlmIChJR05PUkVfVFlQRVMuaW5jbHVkZXModGhpcy5kYXRhLnBhcmVudFR5cGUpKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb250YWluZXI7XG4gICAgfVxuXG4gICAgY29uc3Qgc2VsZWN0b3IgPSBgW2RhdGEtYW5ub3RhdGlvbi1pZD1cIiR7dGhpcy5kYXRhLnBhcmVudElkfVwiXWA7XG4gICAgY29uc3QgcGFyZW50RWxlbWVudHMgPSB0aGlzLmxheWVyLnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpO1xuXG4gICAgaWYgKHBhcmVudEVsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICAgIH1cblxuICAgIGNvbnN0IHBvcHVwID0gbmV3IFBvcHVwRWxlbWVudCh7XG4gICAgICBjb250YWluZXI6IHRoaXMuY29udGFpbmVyLFxuICAgICAgdHJpZ2dlcjogQXJyYXkuZnJvbShwYXJlbnRFbGVtZW50cyksXG4gICAgICBjb2xvcjogdGhpcy5kYXRhLmNvbG9yLFxuICAgICAgdGl0bGVPYmo6IHRoaXMuZGF0YS50aXRsZU9iaixcbiAgICAgIG1vZGlmaWNhdGlvbkRhdGU6IHRoaXMuZGF0YS5tb2RpZmljYXRpb25EYXRlLFxuICAgICAgY29udGVudHNPYmo6IHRoaXMuZGF0YS5jb250ZW50c09iaixcbiAgICAgIHJpY2hUZXh0OiB0aGlzLmRhdGEucmljaFRleHRcbiAgICB9KTtcbiAgICBjb25zdCBwYWdlID0gdGhpcy5wYWdlO1xuXG4gICAgY29uc3QgcmVjdCA9IF91dGlsLlV0aWwubm9ybWFsaXplUmVjdChbdGhpcy5kYXRhLnBhcmVudFJlY3RbMF0sIHBhZ2Uudmlld1szXSAtIHRoaXMuZGF0YS5wYXJlbnRSZWN0WzFdICsgcGFnZS52aWV3WzFdLCB0aGlzLmRhdGEucGFyZW50UmVjdFsyXSwgcGFnZS52aWV3WzNdIC0gdGhpcy5kYXRhLnBhcmVudFJlY3RbM10gKyBwYWdlLnZpZXdbMV1dKTtcblxuICAgIGNvbnN0IHBvcHVwTGVmdCA9IHJlY3RbMF0gKyB0aGlzLmRhdGEucGFyZW50UmVjdFsyXSAtIHRoaXMuZGF0YS5wYXJlbnRSZWN0WzBdO1xuICAgIGNvbnN0IHBvcHVwVG9wID0gcmVjdFsxXTtcbiAgICB0aGlzLmNvbnRhaW5lci5zdHlsZS50cmFuc2Zvcm1PcmlnaW4gPSBgJHstcG9wdXBMZWZ0fXB4ICR7LXBvcHVwVG9wfXB4YDtcbiAgICB0aGlzLmNvbnRhaW5lci5zdHlsZS5sZWZ0ID0gYCR7cG9wdXBMZWZ0fXB4YDtcbiAgICB0aGlzLmNvbnRhaW5lci5zdHlsZS50b3AgPSBgJHtwb3B1cFRvcH1weGA7XG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQocG9wdXAucmVuZGVyKCkpO1xuICAgIHJldHVybiB0aGlzLmNvbnRhaW5lcjtcbiAgfVxuXG59XG5cbmNsYXNzIFBvcHVwRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICB0aGlzLmNvbnRhaW5lciA9IHBhcmFtZXRlcnMuY29udGFpbmVyO1xuICAgIHRoaXMudHJpZ2dlciA9IHBhcmFtZXRlcnMudHJpZ2dlcjtcbiAgICB0aGlzLmNvbG9yID0gcGFyYW1ldGVycy5jb2xvcjtcbiAgICB0aGlzLnRpdGxlT2JqID0gcGFyYW1ldGVycy50aXRsZU9iajtcbiAgICB0aGlzLm1vZGlmaWNhdGlvbkRhdGUgPSBwYXJhbWV0ZXJzLm1vZGlmaWNhdGlvbkRhdGU7XG4gICAgdGhpcy5jb250ZW50c09iaiA9IHBhcmFtZXRlcnMuY29udGVudHNPYmo7XG4gICAgdGhpcy5yaWNoVGV4dCA9IHBhcmFtZXRlcnMucmljaFRleHQ7XG4gICAgdGhpcy5oaWRlV3JhcHBlciA9IHBhcmFtZXRlcnMuaGlkZVdyYXBwZXIgfHwgZmFsc2U7XG4gICAgdGhpcy5waW5uZWQgPSBmYWxzZTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBjb25zdCBCQUNLR1JPVU5EX0VOTElHSFQgPSAwLjc7XG4gICAgY29uc3Qgd3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgd3JhcHBlci5jbGFzc05hbWUgPSBcInBvcHVwV3JhcHBlclwiO1xuICAgIHRoaXMuaGlkZUVsZW1lbnQgPSB0aGlzLmhpZGVXcmFwcGVyID8gd3JhcHBlciA6IHRoaXMuY29udGFpbmVyO1xuICAgIHRoaXMuaGlkZUVsZW1lbnQuaGlkZGVuID0gdHJ1ZTtcbiAgICBjb25zdCBwb3B1cCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgcG9wdXAuY2xhc3NOYW1lID0gXCJwb3B1cFwiO1xuICAgIGNvbnN0IGNvbG9yID0gdGhpcy5jb2xvcjtcblxuICAgIGlmIChjb2xvcikge1xuICAgICAgY29uc3QgciA9IEJBQ0tHUk9VTkRfRU5MSUdIVCAqICgyNTUgLSBjb2xvclswXSkgKyBjb2xvclswXTtcbiAgICAgIGNvbnN0IGcgPSBCQUNLR1JPVU5EX0VOTElHSFQgKiAoMjU1IC0gY29sb3JbMV0pICsgY29sb3JbMV07XG4gICAgICBjb25zdCBiID0gQkFDS0dST1VORF9FTkxJR0hUICogKDI1NSAtIGNvbG9yWzJdKSArIGNvbG9yWzJdO1xuICAgICAgcG9wdXAuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gX3V0aWwuVXRpbC5tYWtlSGV4Q29sb3IociB8IDAsIGcgfCAwLCBiIHwgMCk7XG4gICAgfVxuXG4gICAgY29uc3QgdGl0bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaDFcIik7XG4gICAgdGl0bGUuZGlyID0gdGhpcy50aXRsZU9iai5kaXI7XG4gICAgdGl0bGUudGV4dENvbnRlbnQgPSB0aGlzLnRpdGxlT2JqLnN0cjtcbiAgICBwb3B1cC5hcHBlbmRDaGlsZCh0aXRsZSk7XG5cbiAgICBjb25zdCBkYXRlT2JqZWN0ID0gX2Rpc3BsYXlfdXRpbHMuUERGRGF0ZVN0cmluZy50b0RhdGVPYmplY3QodGhpcy5tb2RpZmljYXRpb25EYXRlKTtcblxuICAgIGlmIChkYXRlT2JqZWN0KSB7XG4gICAgICBjb25zdCBtb2RpZmljYXRpb25EYXRlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNwYW5cIik7XG4gICAgICBtb2RpZmljYXRpb25EYXRlLmNsYXNzTmFtZSA9IFwicG9wdXBEYXRlXCI7XG4gICAgICBtb2RpZmljYXRpb25EYXRlLnRleHRDb250ZW50ID0gXCJ7e2RhdGV9fSwge3t0aW1lfX1cIjtcbiAgICAgIG1vZGlmaWNhdGlvbkRhdGUuZGF0YXNldC5sMTBuSWQgPSBcImFubm90YXRpb25fZGF0ZV9zdHJpbmdcIjtcbiAgICAgIG1vZGlmaWNhdGlvbkRhdGUuZGF0YXNldC5sMTBuQXJncyA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgZGF0ZTogZGF0ZU9iamVjdC50b0xvY2FsZURhdGVTdHJpbmcoKSxcbiAgICAgICAgdGltZTogZGF0ZU9iamVjdC50b0xvY2FsZVRpbWVTdHJpbmcoKVxuICAgICAgfSk7XG4gICAgICBwb3B1cC5hcHBlbmRDaGlsZChtb2RpZmljYXRpb25EYXRlKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5yaWNoVGV4dD8uc3RyICYmICghdGhpcy5jb250ZW50c09iaj8uc3RyIHx8IHRoaXMuY29udGVudHNPYmouc3RyID09PSB0aGlzLnJpY2hUZXh0LnN0cikpIHtcbiAgICAgIF94ZmFfbGF5ZXIuWGZhTGF5ZXIucmVuZGVyKHtcbiAgICAgICAgeGZhSHRtbDogdGhpcy5yaWNoVGV4dC5odG1sLFxuICAgICAgICBpbnRlbnQ6IFwicmljaFRleHRcIixcbiAgICAgICAgZGl2OiBwb3B1cFxuICAgICAgfSk7XG5cbiAgICAgIHBvcHVwLmxhc3RDaGlsZC5jbGFzc05hbWUgPSBcInJpY2hUZXh0IHBvcHVwQ29udGVudFwiO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBjb250ZW50cyA9IHRoaXMuX2Zvcm1hdENvbnRlbnRzKHRoaXMuY29udGVudHNPYmopO1xuXG4gICAgICBwb3B1cC5hcHBlbmRDaGlsZChjb250ZW50cyk7XG4gICAgfVxuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHRoaXMudHJpZ2dlcikpIHtcbiAgICAgIHRoaXMudHJpZ2dlciA9IFt0aGlzLnRyaWdnZXJdO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiB0aGlzLnRyaWdnZXIpIHtcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIHRoaXMuX3RvZ2dsZS5iaW5kKHRoaXMpKTtcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlb3ZlclwiLCB0aGlzLl9zaG93LmJpbmQodGhpcywgZmFsc2UpKTtcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlb3V0XCIsIHRoaXMuX2hpZGUuYmluZCh0aGlzLCBmYWxzZSkpO1xuICAgIH1cblxuICAgIHBvcHVwLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCB0aGlzLl9oaWRlLmJpbmQodGhpcywgdHJ1ZSkpO1xuICAgIHdyYXBwZXIuYXBwZW5kQ2hpbGQocG9wdXApO1xuICAgIHJldHVybiB3cmFwcGVyO1xuICB9XG5cbiAgX2Zvcm1hdENvbnRlbnRzKHtcbiAgICBzdHIsXG4gICAgZGlyXG4gIH0pIHtcbiAgICBjb25zdCBwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInBcIik7XG4gICAgcC5jbGFzc05hbWUgPSBcInBvcHVwQ29udGVudFwiO1xuICAgIHAuZGlyID0gZGlyO1xuICAgIGNvbnN0IGxpbmVzID0gc3RyLnNwbGl0KC8oPzpcXHJcXG4/fFxcbikvKTtcblxuICAgIGZvciAobGV0IGkgPSAwLCBpaSA9IGxpbmVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIGNvbnN0IGxpbmUgPSBsaW5lc1tpXTtcbiAgICAgIHAuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUobGluZSkpO1xuXG4gICAgICBpZiAoaSA8IGlpIC0gMSkge1xuICAgICAgICBwLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJiclwiKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHA7XG4gIH1cblxuICBfdG9nZ2xlKCkge1xuICAgIGlmICh0aGlzLnBpbm5lZCkge1xuICAgICAgdGhpcy5faGlkZSh0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fc2hvdyh0cnVlKTtcbiAgICB9XG4gIH1cblxuICBfc2hvdyhwaW4gPSBmYWxzZSkge1xuICAgIGlmIChwaW4pIHtcbiAgICAgIHRoaXMucGlubmVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5oaWRlRWxlbWVudC5oaWRkZW4pIHtcbiAgICAgIHRoaXMuaGlkZUVsZW1lbnQuaGlkZGVuID0gZmFsc2U7XG4gICAgICB0aGlzLmNvbnRhaW5lci5zdHlsZS56SW5kZXggKz0gMTtcbiAgICB9XG4gIH1cblxuICBfaGlkZSh1bnBpbiA9IHRydWUpIHtcbiAgICBpZiAodW5waW4pIHtcbiAgICAgIHRoaXMucGlubmVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmhpZGVFbGVtZW50LmhpZGRlbiAmJiAhdGhpcy5waW5uZWQpIHtcbiAgICAgIHRoaXMuaGlkZUVsZW1lbnQuaGlkZGVuID0gdHJ1ZTtcbiAgICAgIHRoaXMuY29udGFpbmVyLnN0eWxlLnpJbmRleCAtPSAxO1xuICAgIH1cbiAgfVxuXG59XG5cbmNsYXNzIEZyZWVUZXh0QW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCBpc1JlbmRlcmFibGUgPSAhIShwYXJhbWV0ZXJzLmRhdGEuaGFzUG9wdXAgfHwgcGFyYW1ldGVycy5kYXRhLnRpdGxlT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLmNvbnRlbnRzT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLnJpY2hUZXh0Py5zdHIpO1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlzUmVuZGVyYWJsZSxcbiAgICAgIGlnbm9yZUJvcmRlcjogdHJ1ZVxuICAgIH0pO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IFwiZnJlZVRleHRBbm5vdGF0aW9uXCI7XG5cbiAgICBpZiAoIXRoaXMuZGF0YS5oYXNQb3B1cCkge1xuICAgICAgdGhpcy5fY3JlYXRlUG9wdXAobnVsbCwgdGhpcy5kYXRhKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5jb250YWluZXI7XG4gIH1cblxufVxuXG5jbGFzcyBMaW5lQW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCBpc1JlbmRlcmFibGUgPSAhIShwYXJhbWV0ZXJzLmRhdGEuaGFzUG9wdXAgfHwgcGFyYW1ldGVycy5kYXRhLnRpdGxlT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLmNvbnRlbnRzT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLnJpY2hUZXh0Py5zdHIpO1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlzUmVuZGVyYWJsZSxcbiAgICAgIGlnbm9yZUJvcmRlcjogdHJ1ZVxuICAgIH0pO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IFwibGluZUFubm90YXRpb25cIjtcbiAgICBjb25zdCBkYXRhID0gdGhpcy5kYXRhO1xuICAgIGNvbnN0IHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0XG4gICAgfSA9IGdldFJlY3REaW1zKGRhdGEucmVjdCk7XG4gICAgY29uc3Qgc3ZnID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZSh3aWR0aCwgaGVpZ2h0KTtcbiAgICBjb25zdCBsaW5lID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZUVsZW1lbnQoXCJzdmc6bGluZVwiKTtcbiAgICBsaW5lLnNldEF0dHJpYnV0ZShcIngxXCIsIGRhdGEucmVjdFsyXSAtIGRhdGEubGluZUNvb3JkaW5hdGVzWzBdKTtcbiAgICBsaW5lLnNldEF0dHJpYnV0ZShcInkxXCIsIGRhdGEucmVjdFszXSAtIGRhdGEubGluZUNvb3JkaW5hdGVzWzFdKTtcbiAgICBsaW5lLnNldEF0dHJpYnV0ZShcIngyXCIsIGRhdGEucmVjdFsyXSAtIGRhdGEubGluZUNvb3JkaW5hdGVzWzJdKTtcbiAgICBsaW5lLnNldEF0dHJpYnV0ZShcInkyXCIsIGRhdGEucmVjdFszXSAtIGRhdGEubGluZUNvb3JkaW5hdGVzWzNdKTtcbiAgICBsaW5lLnNldEF0dHJpYnV0ZShcInN0cm9rZS13aWR0aFwiLCBkYXRhLmJvcmRlclN0eWxlLndpZHRoIHx8IDEpO1xuICAgIGxpbmUuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIFwidHJhbnNwYXJlbnRcIik7XG4gICAgbGluZS5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIFwidHJhbnNwYXJlbnRcIik7XG4gICAgc3ZnLmFwcGVuZENoaWxkKGxpbmUpO1xuICAgIHRoaXMuY29udGFpbmVyLmFwcGVuZChzdmcpO1xuXG4gICAgdGhpcy5fY3JlYXRlUG9wdXAobGluZSwgZGF0YSk7XG5cbiAgICByZXR1cm4gdGhpcy5jb250YWluZXI7XG4gIH1cblxufVxuXG5jbGFzcyBTcXVhcmVBbm5vdGF0aW9uRWxlbWVudCBleHRlbmRzIEFubm90YXRpb25FbGVtZW50IHtcbiAgY29uc3RydWN0b3IocGFyYW1ldGVycykge1xuICAgIGNvbnN0IGlzUmVuZGVyYWJsZSA9ICEhKHBhcmFtZXRlcnMuZGF0YS5oYXNQb3B1cCB8fCBwYXJhbWV0ZXJzLmRhdGEudGl0bGVPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEuY29udGVudHNPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEucmljaFRleHQ/LnN0cik7XG4gICAgc3VwZXIocGFyYW1ldGVycywge1xuICAgICAgaXNSZW5kZXJhYmxlLFxuICAgICAgaWdub3JlQm9yZGVyOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NOYW1lID0gXCJzcXVhcmVBbm5vdGF0aW9uXCI7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuZGF0YTtcbiAgICBjb25zdCB7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodFxuICAgIH0gPSBnZXRSZWN0RGltcyhkYXRhLnJlY3QpO1xuICAgIGNvbnN0IHN2ZyA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGUod2lkdGgsIGhlaWdodCk7XG4gICAgY29uc3QgYm9yZGVyV2lkdGggPSBkYXRhLmJvcmRlclN0eWxlLndpZHRoO1xuICAgIGNvbnN0IHNxdWFyZSA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOnJlY3RcIik7XG4gICAgc3F1YXJlLnNldEF0dHJpYnV0ZShcInhcIiwgYm9yZGVyV2lkdGggLyAyKTtcbiAgICBzcXVhcmUuc2V0QXR0cmlidXRlKFwieVwiLCBib3JkZXJXaWR0aCAvIDIpO1xuICAgIHNxdWFyZS5zZXRBdHRyaWJ1dGUoXCJ3aWR0aFwiLCB3aWR0aCAtIGJvcmRlcldpZHRoKTtcbiAgICBzcXVhcmUuc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIGhlaWdodCAtIGJvcmRlcldpZHRoKTtcbiAgICBzcXVhcmUuc2V0QXR0cmlidXRlKFwic3Ryb2tlLXdpZHRoXCIsIGJvcmRlcldpZHRoIHx8IDEpO1xuICAgIHNxdWFyZS5zZXRBdHRyaWJ1dGUoXCJzdHJva2VcIiwgXCJ0cmFuc3BhcmVudFwiKTtcbiAgICBzcXVhcmUuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBcInRyYW5zcGFyZW50XCIpO1xuICAgIHN2Zy5hcHBlbmRDaGlsZChzcXVhcmUpO1xuICAgIHRoaXMuY29udGFpbmVyLmFwcGVuZChzdmcpO1xuXG4gICAgdGhpcy5fY3JlYXRlUG9wdXAoc3F1YXJlLCBkYXRhKTtcblxuICAgIHJldHVybiB0aGlzLmNvbnRhaW5lcjtcbiAgfVxuXG59XG5cbmNsYXNzIENpcmNsZUFubm90YXRpb25FbGVtZW50IGV4dGVuZHMgQW5ub3RhdGlvbkVsZW1lbnQge1xuICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzKSB7XG4gICAgY29uc3QgaXNSZW5kZXJhYmxlID0gISEocGFyYW1ldGVycy5kYXRhLmhhc1BvcHVwIHx8IHBhcmFtZXRlcnMuZGF0YS50aXRsZU9iaj8uc3RyIHx8IHBhcmFtZXRlcnMuZGF0YS5jb250ZW50c09iaj8uc3RyIHx8IHBhcmFtZXRlcnMuZGF0YS5yaWNoVGV4dD8uc3RyKTtcbiAgICBzdXBlcihwYXJhbWV0ZXJzLCB7XG4gICAgICBpc1JlbmRlcmFibGUsXG4gICAgICBpZ25vcmVCb3JkZXI6IHRydWVcbiAgICB9KTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICB0aGlzLmNvbnRhaW5lci5jbGFzc05hbWUgPSBcImNpcmNsZUFubm90YXRpb25cIjtcbiAgICBjb25zdCBkYXRhID0gdGhpcy5kYXRhO1xuICAgIGNvbnN0IHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0XG4gICAgfSA9IGdldFJlY3REaW1zKGRhdGEucmVjdCk7XG4gICAgY29uc3Qgc3ZnID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZSh3aWR0aCwgaGVpZ2h0KTtcbiAgICBjb25zdCBib3JkZXJXaWR0aCA9IGRhdGEuYm9yZGVyU3R5bGUud2lkdGg7XG4gICAgY29uc3QgY2lyY2xlID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZUVsZW1lbnQoXCJzdmc6ZWxsaXBzZVwiKTtcbiAgICBjaXJjbGUuc2V0QXR0cmlidXRlKFwiY3hcIiwgd2lkdGggLyAyKTtcbiAgICBjaXJjbGUuc2V0QXR0cmlidXRlKFwiY3lcIiwgaGVpZ2h0IC8gMik7XG4gICAgY2lyY2xlLnNldEF0dHJpYnV0ZShcInJ4XCIsIHdpZHRoIC8gMiAtIGJvcmRlcldpZHRoIC8gMik7XG4gICAgY2lyY2xlLnNldEF0dHJpYnV0ZShcInJ5XCIsIGhlaWdodCAvIDIgLSBib3JkZXJXaWR0aCAvIDIpO1xuICAgIGNpcmNsZS5zZXRBdHRyaWJ1dGUoXCJzdHJva2Utd2lkdGhcIiwgYm9yZGVyV2lkdGggfHwgMSk7XG4gICAgY2lyY2xlLnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCBcInRyYW5zcGFyZW50XCIpO1xuICAgIGNpcmNsZS5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIFwidHJhbnNwYXJlbnRcIik7XG4gICAgc3ZnLmFwcGVuZENoaWxkKGNpcmNsZSk7XG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kKHN2Zyk7XG5cbiAgICB0aGlzLl9jcmVhdGVQb3B1cChjaXJjbGUsIGRhdGEpO1xuXG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgUG9seWxpbmVBbm5vdGF0aW9uRWxlbWVudCBleHRlbmRzIEFubm90YXRpb25FbGVtZW50IHtcbiAgY29uc3RydWN0b3IocGFyYW1ldGVycykge1xuICAgIGNvbnN0IGlzUmVuZGVyYWJsZSA9ICEhKHBhcmFtZXRlcnMuZGF0YS5oYXNQb3B1cCB8fCBwYXJhbWV0ZXJzLmRhdGEudGl0bGVPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEuY29udGVudHNPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEucmljaFRleHQ/LnN0cik7XG4gICAgc3VwZXIocGFyYW1ldGVycywge1xuICAgICAgaXNSZW5kZXJhYmxlLFxuICAgICAgaWdub3JlQm9yZGVyOiB0cnVlXG4gICAgfSk7XG4gICAgdGhpcy5jb250YWluZXJDbGFzc05hbWUgPSBcInBvbHlsaW5lQW5ub3RhdGlvblwiO1xuICAgIHRoaXMuc3ZnRWxlbWVudE5hbWUgPSBcInN2Zzpwb2x5bGluZVwiO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IHRoaXMuY29udGFpbmVyQ2xhc3NOYW1lO1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLmRhdGE7XG4gICAgY29uc3Qge1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHRcbiAgICB9ID0gZ2V0UmVjdERpbXMoZGF0YS5yZWN0KTtcbiAgICBjb25zdCBzdmcgPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlKHdpZHRoLCBoZWlnaHQpO1xuICAgIGxldCBwb2ludHMgPSBbXTtcblxuICAgIGZvciAoY29uc3QgY29vcmRpbmF0ZSBvZiBkYXRhLnZlcnRpY2VzKSB7XG4gICAgICBjb25zdCB4ID0gY29vcmRpbmF0ZS54IC0gZGF0YS5yZWN0WzBdO1xuICAgICAgY29uc3QgeSA9IGRhdGEucmVjdFszXSAtIGNvb3JkaW5hdGUueTtcbiAgICAgIHBvaW50cy5wdXNoKHggKyBcIixcIiArIHkpO1xuICAgIH1cblxuICAgIHBvaW50cyA9IHBvaW50cy5qb2luKFwiIFwiKTtcbiAgICBjb25zdCBwb2x5bGluZSA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KHRoaXMuc3ZnRWxlbWVudE5hbWUpO1xuICAgIHBvbHlsaW5lLnNldEF0dHJpYnV0ZShcInBvaW50c1wiLCBwb2ludHMpO1xuICAgIHBvbHlsaW5lLnNldEF0dHJpYnV0ZShcInN0cm9rZS13aWR0aFwiLCBkYXRhLmJvcmRlclN0eWxlLndpZHRoIHx8IDEpO1xuICAgIHBvbHlsaW5lLnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCBcInRyYW5zcGFyZW50XCIpO1xuICAgIHBvbHlsaW5lLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgXCJ0cmFuc3BhcmVudFwiKTtcbiAgICBzdmcuYXBwZW5kQ2hpbGQocG9seWxpbmUpO1xuICAgIHRoaXMuY29udGFpbmVyLmFwcGVuZChzdmcpO1xuXG4gICAgdGhpcy5fY3JlYXRlUG9wdXAocG9seWxpbmUsIGRhdGEpO1xuXG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgUG9seWdvbkFubm90YXRpb25FbGVtZW50IGV4dGVuZHMgUG9seWxpbmVBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB0aGlzLmNvbnRhaW5lckNsYXNzTmFtZSA9IFwicG9seWdvbkFubm90YXRpb25cIjtcbiAgICB0aGlzLnN2Z0VsZW1lbnROYW1lID0gXCJzdmc6cG9seWdvblwiO1xuICB9XG5cbn1cblxuY2xhc3MgQ2FyZXRBbm5vdGF0aW9uRWxlbWVudCBleHRlbmRzIEFubm90YXRpb25FbGVtZW50IHtcbiAgY29uc3RydWN0b3IocGFyYW1ldGVycykge1xuICAgIGNvbnN0IGlzUmVuZGVyYWJsZSA9ICEhKHBhcmFtZXRlcnMuZGF0YS5oYXNQb3B1cCB8fCBwYXJhbWV0ZXJzLmRhdGEudGl0bGVPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEuY29udGVudHNPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEucmljaFRleHQ/LnN0cik7XG4gICAgc3VwZXIocGFyYW1ldGVycywge1xuICAgICAgaXNSZW5kZXJhYmxlLFxuICAgICAgaWdub3JlQm9yZGVyOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NOYW1lID0gXCJjYXJldEFubm90YXRpb25cIjtcblxuICAgIGlmICghdGhpcy5kYXRhLmhhc1BvcHVwKSB7XG4gICAgICB0aGlzLl9jcmVhdGVQb3B1cChudWxsLCB0aGlzLmRhdGEpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbnRhaW5lcjtcbiAgfVxuXG59XG5cbmNsYXNzIElua0Fubm90YXRpb25FbGVtZW50IGV4dGVuZHMgQW5ub3RhdGlvbkVsZW1lbnQge1xuICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzKSB7XG4gICAgY29uc3QgaXNSZW5kZXJhYmxlID0gISEocGFyYW1ldGVycy5kYXRhLmhhc1BvcHVwIHx8IHBhcmFtZXRlcnMuZGF0YS50aXRsZU9iaj8uc3RyIHx8IHBhcmFtZXRlcnMuZGF0YS5jb250ZW50c09iaj8uc3RyIHx8IHBhcmFtZXRlcnMuZGF0YS5yaWNoVGV4dD8uc3RyKTtcbiAgICBzdXBlcihwYXJhbWV0ZXJzLCB7XG4gICAgICBpc1JlbmRlcmFibGUsXG4gICAgICBpZ25vcmVCb3JkZXI6IHRydWVcbiAgICB9KTtcbiAgICB0aGlzLmNvbnRhaW5lckNsYXNzTmFtZSA9IFwiaW5rQW5ub3RhdGlvblwiO1xuICAgIHRoaXMuc3ZnRWxlbWVudE5hbWUgPSBcInN2Zzpwb2x5bGluZVwiO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IHRoaXMuY29udGFpbmVyQ2xhc3NOYW1lO1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLmRhdGE7XG4gICAgY29uc3Qge1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHRcbiAgICB9ID0gZ2V0UmVjdERpbXMoZGF0YS5yZWN0KTtcbiAgICBjb25zdCBzdmcgPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlKHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgZm9yIChjb25zdCBpbmtMaXN0IG9mIGRhdGEuaW5rTGlzdHMpIHtcbiAgICAgIGxldCBwb2ludHMgPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBjb29yZGluYXRlIG9mIGlua0xpc3QpIHtcbiAgICAgICAgY29uc3QgeCA9IGNvb3JkaW5hdGUueCAtIGRhdGEucmVjdFswXTtcbiAgICAgICAgY29uc3QgeSA9IGRhdGEucmVjdFszXSAtIGNvb3JkaW5hdGUueTtcbiAgICAgICAgcG9pbnRzLnB1c2goYCR7eH0sJHt5fWApO1xuICAgICAgfVxuXG4gICAgICBwb2ludHMgPSBwb2ludHMuam9pbihcIiBcIik7XG4gICAgICBjb25zdCBwb2x5bGluZSA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KHRoaXMuc3ZnRWxlbWVudE5hbWUpO1xuICAgICAgcG9seWxpbmUuc2V0QXR0cmlidXRlKFwicG9pbnRzXCIsIHBvaW50cyk7XG4gICAgICBwb2x5bGluZS5zZXRBdHRyaWJ1dGUoXCJzdHJva2Utd2lkdGhcIiwgZGF0YS5ib3JkZXJTdHlsZS53aWR0aCB8fCAxKTtcbiAgICAgIHBvbHlsaW5lLnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCBcInRyYW5zcGFyZW50XCIpO1xuICAgICAgcG9seWxpbmUuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBcInRyYW5zcGFyZW50XCIpO1xuXG4gICAgICB0aGlzLl9jcmVhdGVQb3B1cChwb2x5bGluZSwgZGF0YSk7XG5cbiAgICAgIHN2Zy5hcHBlbmRDaGlsZChwb2x5bGluZSk7XG4gICAgfVxuXG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kKHN2Zyk7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgSGlnaGxpZ2h0QW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCBpc1JlbmRlcmFibGUgPSAhIShwYXJhbWV0ZXJzLmRhdGEuaGFzUG9wdXAgfHwgcGFyYW1ldGVycy5kYXRhLnRpdGxlT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLmNvbnRlbnRzT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLnJpY2hUZXh0Py5zdHIpO1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlzUmVuZGVyYWJsZSxcbiAgICAgIGlnbm9yZUJvcmRlcjogdHJ1ZSxcbiAgICAgIGNyZWF0ZVF1YWRyaWxhdGVyYWxzOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgaWYgKCF0aGlzLmRhdGEuaGFzUG9wdXApIHtcbiAgICAgIHRoaXMuX2NyZWF0ZVBvcHVwKG51bGwsIHRoaXMuZGF0YSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucXVhZHJpbGF0ZXJhbHMpIHtcbiAgICAgIHJldHVybiB0aGlzLl9yZW5kZXJRdWFkcmlsYXRlcmFscyhcImhpZ2hsaWdodEFubm90YXRpb25cIik7XG4gICAgfVxuXG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NOYW1lID0gXCJoaWdobGlnaHRBbm5vdGF0aW9uXCI7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgVW5kZXJsaW5lQW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCBpc1JlbmRlcmFibGUgPSAhIShwYXJhbWV0ZXJzLmRhdGEuaGFzUG9wdXAgfHwgcGFyYW1ldGVycy5kYXRhLnRpdGxlT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLmNvbnRlbnRzT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLnJpY2hUZXh0Py5zdHIpO1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlzUmVuZGVyYWJsZSxcbiAgICAgIGlnbm9yZUJvcmRlcjogdHJ1ZSxcbiAgICAgIGNyZWF0ZVF1YWRyaWxhdGVyYWxzOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgaWYgKCF0aGlzLmRhdGEuaGFzUG9wdXApIHtcbiAgICAgIHRoaXMuX2NyZWF0ZVBvcHVwKG51bGwsIHRoaXMuZGF0YSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucXVhZHJpbGF0ZXJhbHMpIHtcbiAgICAgIHJldHVybiB0aGlzLl9yZW5kZXJRdWFkcmlsYXRlcmFscyhcInVuZGVybGluZUFubm90YXRpb25cIik7XG4gICAgfVxuXG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NOYW1lID0gXCJ1bmRlcmxpbmVBbm5vdGF0aW9uXCI7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgU3F1aWdnbHlBbm5vdGF0aW9uRWxlbWVudCBleHRlbmRzIEFubm90YXRpb25FbGVtZW50IHtcbiAgY29uc3RydWN0b3IocGFyYW1ldGVycykge1xuICAgIGNvbnN0IGlzUmVuZGVyYWJsZSA9ICEhKHBhcmFtZXRlcnMuZGF0YS5oYXNQb3B1cCB8fCBwYXJhbWV0ZXJzLmRhdGEudGl0bGVPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEuY29udGVudHNPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEucmljaFRleHQ/LnN0cik7XG4gICAgc3VwZXIocGFyYW1ldGVycywge1xuICAgICAgaXNSZW5kZXJhYmxlLFxuICAgICAgaWdub3JlQm9yZGVyOiB0cnVlLFxuICAgICAgY3JlYXRlUXVhZHJpbGF0ZXJhbHM6IHRydWVcbiAgICB9KTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAoIXRoaXMuZGF0YS5oYXNQb3B1cCkge1xuICAgICAgdGhpcy5fY3JlYXRlUG9wdXAobnVsbCwgdGhpcy5kYXRhKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5xdWFkcmlsYXRlcmFscykge1xuICAgICAgcmV0dXJuIHRoaXMuX3JlbmRlclF1YWRyaWxhdGVyYWxzKFwic3F1aWdnbHlBbm5vdGF0aW9uXCIpO1xuICAgIH1cblxuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IFwic3F1aWdnbHlBbm5vdGF0aW9uXCI7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgU3RyaWtlT3V0QW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCBpc1JlbmRlcmFibGUgPSAhIShwYXJhbWV0ZXJzLmRhdGEuaGFzUG9wdXAgfHwgcGFyYW1ldGVycy5kYXRhLnRpdGxlT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLmNvbnRlbnRzT2JqPy5zdHIgfHwgcGFyYW1ldGVycy5kYXRhLnJpY2hUZXh0Py5zdHIpO1xuICAgIHN1cGVyKHBhcmFtZXRlcnMsIHtcbiAgICAgIGlzUmVuZGVyYWJsZSxcbiAgICAgIGlnbm9yZUJvcmRlcjogdHJ1ZSxcbiAgICAgIGNyZWF0ZVF1YWRyaWxhdGVyYWxzOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgaWYgKCF0aGlzLmRhdGEuaGFzUG9wdXApIHtcbiAgICAgIHRoaXMuX2NyZWF0ZVBvcHVwKG51bGwsIHRoaXMuZGF0YSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucXVhZHJpbGF0ZXJhbHMpIHtcbiAgICAgIHJldHVybiB0aGlzLl9yZW5kZXJRdWFkcmlsYXRlcmFscyhcInN0cmlrZW91dEFubm90YXRpb25cIik7XG4gICAgfVxuXG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NOYW1lID0gXCJzdHJpa2VvdXRBbm5vdGF0aW9uXCI7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbn1cblxuY2xhc3MgU3RhbXBBbm5vdGF0aW9uRWxlbWVudCBleHRlbmRzIEFubm90YXRpb25FbGVtZW50IHtcbiAgY29uc3RydWN0b3IocGFyYW1ldGVycykge1xuICAgIGNvbnN0IGlzUmVuZGVyYWJsZSA9ICEhKHBhcmFtZXRlcnMuZGF0YS5oYXNQb3B1cCB8fCBwYXJhbWV0ZXJzLmRhdGEudGl0bGVPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEuY29udGVudHNPYmo/LnN0ciB8fCBwYXJhbWV0ZXJzLmRhdGEucmljaFRleHQ/LnN0cik7XG4gICAgc3VwZXIocGFyYW1ldGVycywge1xuICAgICAgaXNSZW5kZXJhYmxlLFxuICAgICAgaWdub3JlQm9yZGVyOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NOYW1lID0gXCJzdGFtcEFubm90YXRpb25cIjtcblxuICAgIGlmICghdGhpcy5kYXRhLmhhc1BvcHVwKSB7XG4gICAgICB0aGlzLl9jcmVhdGVQb3B1cChudWxsLCB0aGlzLmRhdGEpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbnRhaW5lcjtcbiAgfVxuXG59XG5cbmNsYXNzIEZpbGVBdHRhY2htZW50QW5ub3RhdGlvbkVsZW1lbnQgZXh0ZW5kcyBBbm5vdGF0aW9uRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICBzdXBlcihwYXJhbWV0ZXJzLCB7XG4gICAgICBpc1JlbmRlcmFibGU6IHRydWVcbiAgICB9KTtcbiAgICBjb25zdCB7XG4gICAgICBmaWxlbmFtZSxcbiAgICAgIGNvbnRlbnRcbiAgICB9ID0gdGhpcy5kYXRhLmZpbGU7XG4gICAgdGhpcy5maWxlbmFtZSA9ICgwLCBfZGlzcGxheV91dGlscy5nZXRGaWxlbmFtZUZyb21VcmwpKGZpbGVuYW1lKTtcbiAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50O1xuICAgIHRoaXMubGlua1NlcnZpY2UuZXZlbnRCdXM/LmRpc3BhdGNoKFwiZmlsZWF0dGFjaG1lbnRhbm5vdGF0aW9uXCIsIHtcbiAgICAgIHNvdXJjZTogdGhpcyxcbiAgICAgIGZpbGVuYW1lLFxuICAgICAgY29udGVudFxuICAgIH0pO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTmFtZSA9IFwiZmlsZUF0dGFjaG1lbnRBbm5vdGF0aW9uXCI7XG4gICAgY29uc3QgdHJpZ2dlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgdHJpZ2dlci5zdHlsZS5oZWlnaHQgPSB0aGlzLmNvbnRhaW5lci5zdHlsZS5oZWlnaHQ7XG4gICAgdHJpZ2dlci5zdHlsZS53aWR0aCA9IHRoaXMuY29udGFpbmVyLnN0eWxlLndpZHRoO1xuICAgIHRyaWdnZXIuYWRkRXZlbnRMaXN0ZW5lcihcImRibGNsaWNrXCIsIHRoaXMuX2Rvd25sb2FkLmJpbmQodGhpcykpO1xuXG4gICAgaWYgKCF0aGlzLmRhdGEuaGFzUG9wdXAgJiYgKHRoaXMuZGF0YS50aXRsZU9iaj8uc3RyIHx8IHRoaXMuZGF0YS5jb250ZW50c09iaj8uc3RyIHx8IHRoaXMuZGF0YS5yaWNoVGV4dCkpIHtcbiAgICAgIHRoaXMuX2NyZWF0ZVBvcHVwKHRyaWdnZXIsIHRoaXMuZGF0YSk7XG4gICAgfVxuXG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQodHJpZ2dlcik7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9XG5cbiAgX2Rvd25sb2FkKCkge1xuICAgIHRoaXMuZG93bmxvYWRNYW5hZ2VyPy5vcGVuT3JEb3dubG9hZERhdGEodGhpcy5jb250YWluZXIsIHRoaXMuY29udGVudCwgdGhpcy5maWxlbmFtZSk7XG4gIH1cblxufVxuXG5jbGFzcyBBbm5vdGF0aW9uTGF5ZXIge1xuICBzdGF0aWMgcmVuZGVyKHBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCBzb3J0ZWRBbm5vdGF0aW9ucyA9IFtdLFxuICAgICAgICAgIHBvcHVwQW5ub3RhdGlvbnMgPSBbXTtcblxuICAgIGZvciAoY29uc3QgZGF0YSBvZiBwYXJhbWV0ZXJzLmFubm90YXRpb25zKSB7XG4gICAgICBpZiAoIWRhdGEpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHtcbiAgICAgICAgd2lkdGgsXG4gICAgICAgIGhlaWdodFxuICAgICAgfSA9IGdldFJlY3REaW1zKGRhdGEucmVjdCk7XG5cbiAgICAgIGlmICh3aWR0aCA8PSAwIHx8IGhlaWdodCA8PSAwKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZGF0YS5hbm5vdGF0aW9uVHlwZSA9PT0gX3V0aWwuQW5ub3RhdGlvblR5cGUuUE9QVVApIHtcbiAgICAgICAgcG9wdXBBbm5vdGF0aW9ucy5wdXNoKGRhdGEpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgc29ydGVkQW5ub3RhdGlvbnMucHVzaChkYXRhKTtcbiAgICB9XG5cbiAgICBpZiAocG9wdXBBbm5vdGF0aW9ucy5sZW5ndGgpIHtcbiAgICAgIHNvcnRlZEFubm90YXRpb25zLnB1c2goLi4ucG9wdXBBbm5vdGF0aW9ucyk7XG4gICAgfVxuXG4gICAgY29uc3QgZGl2ID0gcGFyYW1ldGVycy5kaXY7XG5cbiAgICBmb3IgKGNvbnN0IGRhdGEgb2Ygc29ydGVkQW5ub3RhdGlvbnMpIHtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSBBbm5vdGF0aW9uRWxlbWVudEZhY3RvcnkuY3JlYXRlKHtcbiAgICAgICAgZGF0YSxcbiAgICAgICAgbGF5ZXI6IGRpdixcbiAgICAgICAgcGFnZTogcGFyYW1ldGVycy5wYWdlLFxuICAgICAgICB2aWV3cG9ydDogcGFyYW1ldGVycy52aWV3cG9ydCxcbiAgICAgICAgbGlua1NlcnZpY2U6IHBhcmFtZXRlcnMubGlua1NlcnZpY2UsXG4gICAgICAgIGRvd25sb2FkTWFuYWdlcjogcGFyYW1ldGVycy5kb3dubG9hZE1hbmFnZXIsXG4gICAgICAgIGltYWdlUmVzb3VyY2VzUGF0aDogcGFyYW1ldGVycy5pbWFnZVJlc291cmNlc1BhdGggfHwgXCJcIixcbiAgICAgICAgcmVuZGVyRm9ybXM6IHBhcmFtZXRlcnMucmVuZGVyRm9ybXMgIT09IGZhbHNlLFxuICAgICAgICBzdmdGYWN0b3J5OiBuZXcgX2Rpc3BsYXlfdXRpbHMuRE9NU1ZHRmFjdG9yeSgpLFxuICAgICAgICBhbm5vdGF0aW9uU3RvcmFnZTogcGFyYW1ldGVycy5hbm5vdGF0aW9uU3RvcmFnZSB8fCBuZXcgX2Fubm90YXRpb25fc3RvcmFnZS5Bbm5vdGF0aW9uU3RvcmFnZSgpLFxuICAgICAgICBlbmFibGVTY3JpcHRpbmc6IHBhcmFtZXRlcnMuZW5hYmxlU2NyaXB0aW5nLFxuICAgICAgICBoYXNKU0FjdGlvbnM6IHBhcmFtZXRlcnMuaGFzSlNBY3Rpb25zLFxuICAgICAgICBmaWVsZE9iamVjdHM6IHBhcmFtZXRlcnMuZmllbGRPYmplY3RzLFxuICAgICAgICBtb3VzZVN0YXRlOiBwYXJhbWV0ZXJzLm1vdXNlU3RhdGUgfHwge1xuICAgICAgICAgIGlzRG93bjogZmFsc2VcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGlmIChlbGVtZW50LmlzUmVuZGVyYWJsZSkge1xuICAgICAgICBjb25zdCByZW5kZXJlZCA9IGVsZW1lbnQucmVuZGVyKCk7XG5cbiAgICAgICAgaWYgKGRhdGEuaGlkZGVuKSB7XG4gICAgICAgICAgcmVuZGVyZWQuc3R5bGUudmlzaWJpbGl0eSA9IFwiaGlkZGVuXCI7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShyZW5kZXJlZCkpIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IHJlbmRlcmVkRWxlbWVudCBvZiByZW5kZXJlZCkge1xuICAgICAgICAgICAgZGl2LmFwcGVuZENoaWxkKHJlbmRlcmVkRWxlbWVudCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgUG9wdXBBbm5vdGF0aW9uRWxlbWVudCkge1xuICAgICAgICAgICAgZGl2LnByZXBlbmQocmVuZGVyZWQpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkaXYuYXBwZW5kQ2hpbGQocmVuZGVyZWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuI3NldEFubm90YXRpb25DYW52YXNNYXAoZGl2LCBwYXJhbWV0ZXJzLmFubm90YXRpb25DYW52YXNNYXApO1xuICB9XG5cbiAgc3RhdGljIHVwZGF0ZShwYXJhbWV0ZXJzKSB7XG4gICAgY29uc3Qge1xuICAgICAgcGFnZSxcbiAgICAgIHZpZXdwb3J0LFxuICAgICAgYW5ub3RhdGlvbnMsXG4gICAgICBhbm5vdGF0aW9uQ2FudmFzTWFwLFxuICAgICAgZGl2XG4gICAgfSA9IHBhcmFtZXRlcnM7XG4gICAgY29uc3QgdHJhbnNmb3JtID0gdmlld3BvcnQudHJhbnNmb3JtO1xuICAgIGNvbnN0IG1hdHJpeCA9IGBtYXRyaXgoJHt0cmFuc2Zvcm0uam9pbihcIixcIil9KWA7XG4gICAgbGV0IHNjYWxlLCBvd25NYXRyaXg7XG5cbiAgICBmb3IgKGNvbnN0IGRhdGEgb2YgYW5ub3RhdGlvbnMpIHtcbiAgICAgIGNvbnN0IGVsZW1lbnRzID0gZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoYFtkYXRhLWFubm90YXRpb24taWQ9XCIke2RhdGEuaWR9XCJdYCk7XG5cbiAgICAgIGlmIChlbGVtZW50cykge1xuICAgICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgZWxlbWVudHMpIHtcbiAgICAgICAgICBpZiAoZGF0YS5oYXNPd25DYW52YXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlY3QgPSBfdXRpbC5VdGlsLm5vcm1hbGl6ZVJlY3QoW2RhdGEucmVjdFswXSwgcGFnZS52aWV3WzNdIC0gZGF0YS5yZWN0WzFdICsgcGFnZS52aWV3WzFdLCBkYXRhLnJlY3RbMl0sIHBhZ2Uudmlld1szXSAtIGRhdGEucmVjdFszXSArIHBhZ2Uudmlld1sxXV0pO1xuXG4gICAgICAgICAgICBpZiAoIW93bk1hdHJpeCkge1xuICAgICAgICAgICAgICBzY2FsZSA9IE1hdGguYWJzKHRyYW5zZm9ybVswXSB8fCB0cmFuc2Zvcm1bMV0pO1xuICAgICAgICAgICAgICBjb25zdCBvd25UcmFuc2Zvcm0gPSB0cmFuc2Zvcm0uc2xpY2UoKTtcblxuICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgICAgICAgICAgICAgIG93blRyYW5zZm9ybVtpXSA9IE1hdGguc2lnbihvd25UcmFuc2Zvcm1baV0pO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgb3duTWF0cml4ID0gYG1hdHJpeCgke293blRyYW5zZm9ybS5qb2luKFwiLFwiKX0pYDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgbGVmdCA9IHJlY3RbMF0gKiBzY2FsZTtcbiAgICAgICAgICAgIGNvbnN0IHRvcCA9IHJlY3RbMV0gKiBzY2FsZTtcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUubGVmdCA9IGAke2xlZnR9cHhgO1xuICAgICAgICAgICAgZWxlbWVudC5zdHlsZS50b3AgPSBgJHt0b3B9cHhgO1xuICAgICAgICAgICAgZWxlbWVudC5zdHlsZS50cmFuc2Zvcm1PcmlnaW4gPSBgJHstbGVmdH1weCAkey10b3B9cHhgO1xuICAgICAgICAgICAgZWxlbWVudC5zdHlsZS50cmFuc2Zvcm0gPSBvd25NYXRyaXg7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUudHJhbnNmb3JtID0gbWF0cml4O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuI3NldEFubm90YXRpb25DYW52YXNNYXAoZGl2LCBhbm5vdGF0aW9uQ2FudmFzTWFwKTtcbiAgICBkaXYuaGlkZGVuID0gZmFsc2U7XG4gIH1cblxuICBzdGF0aWMgI3NldEFubm90YXRpb25DYW52YXNNYXAoZGl2LCBhbm5vdGF0aW9uQ2FudmFzTWFwKSB7XG4gICAgaWYgKCFhbm5vdGF0aW9uQ2FudmFzTWFwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBbaWQsIGNhbnZhc10gb2YgYW5ub3RhdGlvbkNhbnZhc01hcCkge1xuICAgICAgY29uc3QgZWxlbWVudCA9IGRpdi5xdWVyeVNlbGVjdG9yKGBbZGF0YS1hbm5vdGF0aW9uLWlkPVwiJHtpZH1cIl1gKTtcblxuICAgICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7XG4gICAgICAgIGZpcnN0Q2hpbGRcbiAgICAgIH0gPSBlbGVtZW50O1xuXG4gICAgICBpZiAoZmlyc3RDaGlsZC5ub2RlTmFtZSA9PT0gXCJDQU5WQVNcIikge1xuICAgICAgICBlbGVtZW50LnJlcGxhY2VDaGlsZChjYW52YXMsIGZpcnN0Q2hpbGQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWxlbWVudC5pbnNlcnRCZWZvcmUoY2FudmFzLCBmaXJzdENoaWxkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBhbm5vdGF0aW9uQ2FudmFzTWFwLmNsZWFyKCk7XG4gIH1cblxufVxuXG5leHBvcnRzLkFubm90YXRpb25MYXllciA9IEFubm90YXRpb25MYXllcjtcblxuLyoqKi8gfSksXG4vKiAyMSAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5Db2xvckNvbnZlcnRlcnMgPSB2b2lkIDA7XG5cbmZ1bmN0aW9uIG1ha2VDb2xvckNvbXAobikge1xuICByZXR1cm4gTWF0aC5mbG9vcihNYXRoLm1heCgwLCBNYXRoLm1pbigxLCBuKSkgKiAyNTUpLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCBcIjBcIik7XG59XG5cbmNsYXNzIENvbG9yQ29udmVydGVycyB7XG4gIHN0YXRpYyBDTVlLX0coW2MsIHksIG0sIGtdKSB7XG4gICAgcmV0dXJuIFtcIkdcIiwgMSAtIE1hdGgubWluKDEsIDAuMyAqIGMgKyAwLjU5ICogbSArIDAuMTEgKiB5ICsgayldO1xuICB9XG5cbiAgc3RhdGljIEdfQ01ZSyhbZ10pIHtcbiAgICByZXR1cm4gW1wiQ01ZS1wiLCAwLCAwLCAwLCAxIC0gZ107XG4gIH1cblxuICBzdGF0aWMgR19SR0IoW2ddKSB7XG4gICAgcmV0dXJuIFtcIlJHQlwiLCBnLCBnLCBnXTtcbiAgfVxuXG4gIHN0YXRpYyBHX0hUTUwoW2ddKSB7XG4gICAgY29uc3QgRyA9IG1ha2VDb2xvckNvbXAoZyk7XG4gICAgcmV0dXJuIGAjJHtHfSR7R30ke0d9YDtcbiAgfVxuXG4gIHN0YXRpYyBSR0JfRyhbciwgZywgYl0pIHtcbiAgICByZXR1cm4gW1wiR1wiLCAwLjMgKiByICsgMC41OSAqIGcgKyAwLjExICogYl07XG4gIH1cblxuICBzdGF0aWMgUkdCX0hUTUwoW3IsIGcsIGJdKSB7XG4gICAgY29uc3QgUiA9IG1ha2VDb2xvckNvbXAocik7XG4gICAgY29uc3QgRyA9IG1ha2VDb2xvckNvbXAoZyk7XG4gICAgY29uc3QgQiA9IG1ha2VDb2xvckNvbXAoYik7XG4gICAgcmV0dXJuIGAjJHtSfSR7R30ke0J9YDtcbiAgfVxuXG4gIHN0YXRpYyBUX0hUTUwoKSB7XG4gICAgcmV0dXJuIFwiIzAwMDAwMDAwXCI7XG4gIH1cblxuICBzdGF0aWMgQ01ZS19SR0IoW2MsIHksIG0sIGtdKSB7XG4gICAgcmV0dXJuIFtcIlJHQlwiLCAxIC0gTWF0aC5taW4oMSwgYyArIGspLCAxIC0gTWF0aC5taW4oMSwgbSArIGspLCAxIC0gTWF0aC5taW4oMSwgeSArIGspXTtcbiAgfVxuXG4gIHN0YXRpYyBDTVlLX0hUTUwoY29tcG9uZW50cykge1xuICAgIHJldHVybiB0aGlzLlJHQl9IVE1MKHRoaXMuQ01ZS19SR0IoY29tcG9uZW50cykpO1xuICB9XG5cbiAgc3RhdGljIFJHQl9DTVlLKFtyLCBnLCBiXSkge1xuICAgIGNvbnN0IGMgPSAxIC0gcjtcbiAgICBjb25zdCBtID0gMSAtIGc7XG4gICAgY29uc3QgeSA9IDEgLSBiO1xuICAgIGNvbnN0IGsgPSBNYXRoLm1pbihjLCBtLCB5KTtcbiAgICByZXR1cm4gW1wiQ01ZS1wiLCBjLCBtLCB5LCBrXTtcbiAgfVxuXG59XG5cbmV4cG9ydHMuQ29sb3JDb252ZXJ0ZXJzID0gQ29sb3JDb252ZXJ0ZXJzO1xuXG4vKioqLyB9KSxcbi8qIDIyICovXG4vKioqLyAoKF9fdW51c2VkX3dlYnBhY2tfbW9kdWxlLCBleHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5leHBvcnRzLlhmYUxheWVyID0gdm9pZCAwO1xuXG52YXIgX3hmYV90ZXh0ID0gX193X3BkZmpzX3JlcXVpcmVfXygxOCk7XG5cbmNsYXNzIFhmYUxheWVyIHtcbiAgc3RhdGljIHNldHVwU3RvcmFnZShodG1sLCBpZCwgZWxlbWVudCwgc3RvcmFnZSwgaW50ZW50KSB7XG4gICAgY29uc3Qgc3RvcmVkRGF0YSA9IHN0b3JhZ2UuZ2V0VmFsdWUoaWQsIHtcbiAgICAgIHZhbHVlOiBudWxsXG4gICAgfSk7XG5cbiAgICBzd2l0Y2ggKGVsZW1lbnQubmFtZSkge1xuICAgICAgY2FzZSBcInRleHRhcmVhXCI6XG4gICAgICAgIGlmIChzdG9yZWREYXRhLnZhbHVlICE9PSBudWxsKSB7XG4gICAgICAgICAgaHRtbC50ZXh0Q29udGVudCA9IHN0b3JlZERhdGEudmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaW50ZW50ID09PSBcInByaW50XCIpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGh0bWwuYWRkRXZlbnRMaXN0ZW5lcihcImlucHV0XCIsIGV2ZW50ID0+IHtcbiAgICAgICAgICBzdG9yYWdlLnNldFZhbHVlKGlkLCB7XG4gICAgICAgICAgICB2YWx1ZTogZXZlbnQudGFyZ2V0LnZhbHVlXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcImlucHV0XCI6XG4gICAgICAgIGlmIChlbGVtZW50LmF0dHJpYnV0ZXMudHlwZSA9PT0gXCJyYWRpb1wiIHx8IGVsZW1lbnQuYXR0cmlidXRlcy50eXBlID09PSBcImNoZWNrYm94XCIpIHtcbiAgICAgICAgICBpZiAoc3RvcmVkRGF0YS52YWx1ZSA9PT0gZWxlbWVudC5hdHRyaWJ1dGVzLnhmYU9uKSB7XG4gICAgICAgICAgICBodG1sLnNldEF0dHJpYnV0ZShcImNoZWNrZWRcIiwgdHJ1ZSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChzdG9yZWREYXRhLnZhbHVlID09PSBlbGVtZW50LmF0dHJpYnV0ZXMueGZhT2ZmKSB7XG4gICAgICAgICAgICBodG1sLnJlbW92ZUF0dHJpYnV0ZShcImNoZWNrZWRcIik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGludGVudCA9PT0gXCJwcmludFwiKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBodG1sLmFkZEV2ZW50TGlzdGVuZXIoXCJjaGFuZ2VcIiwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgc3RvcmFnZS5zZXRWYWx1ZShpZCwge1xuICAgICAgICAgICAgICB2YWx1ZTogZXZlbnQudGFyZ2V0LmNoZWNrZWQgPyBldmVudC50YXJnZXQuZ2V0QXR0cmlidXRlKFwieGZhT25cIikgOiBldmVudC50YXJnZXQuZ2V0QXR0cmlidXRlKFwieGZhT2ZmXCIpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoc3RvcmVkRGF0YS52YWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaHRtbC5zZXRBdHRyaWJ1dGUoXCJ2YWx1ZVwiLCBzdG9yZWREYXRhLnZhbHVlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaW50ZW50ID09PSBcInByaW50XCIpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGh0bWwuYWRkRXZlbnRMaXN0ZW5lcihcImlucHV0XCIsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICAgICAgdmFsdWU6IGV2ZW50LnRhcmdldC52YWx1ZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcInNlbGVjdFwiOlxuICAgICAgICBpZiAoc3RvcmVkRGF0YS52YWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIGVsZW1lbnQuY2hpbGRyZW4pIHtcbiAgICAgICAgICAgIGlmIChvcHRpb24uYXR0cmlidXRlcy52YWx1ZSA9PT0gc3RvcmVkRGF0YS52YWx1ZSkge1xuICAgICAgICAgICAgICBvcHRpb24uYXR0cmlidXRlcy5zZWxlY3RlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaHRtbC5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIiwgZXZlbnQgPT4ge1xuICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSBldmVudC50YXJnZXQub3B0aW9ucztcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IG9wdGlvbnMuc2VsZWN0ZWRJbmRleCA9PT0gLTEgPyBcIlwiIDogb3B0aW9uc1tvcHRpb25zLnNlbGVjdGVkSW5kZXhdLnZhbHVlO1xuICAgICAgICAgIHN0b3JhZ2Uuc2V0VmFsdWUoaWQsIHtcbiAgICAgICAgICAgIHZhbHVlXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgc2V0QXR0cmlidXRlcyh7XG4gICAgaHRtbCxcbiAgICBlbGVtZW50LFxuICAgIHN0b3JhZ2UgPSBudWxsLFxuICAgIGludGVudCxcbiAgICBsaW5rU2VydmljZVxuICB9KSB7XG4gICAgY29uc3Qge1xuICAgICAgYXR0cmlidXRlc1xuICAgIH0gPSBlbGVtZW50O1xuICAgIGNvbnN0IGlzSFRNTEFuY2hvckVsZW1lbnQgPSBodG1sIGluc3RhbmNlb2YgSFRNTEFuY2hvckVsZW1lbnQ7XG5cbiAgICBpZiAoYXR0cmlidXRlcy50eXBlID09PSBcInJhZGlvXCIpIHtcbiAgICAgIGF0dHJpYnV0ZXMubmFtZSA9IGAke2F0dHJpYnV0ZXMubmFtZX0tJHtpbnRlbnR9YDtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhhdHRyaWJ1dGVzKSkge1xuICAgICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgfHwga2V5ID09PSBcImRhdGFJZFwiKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoa2V5ICE9PSBcInN0eWxlXCIpIHtcbiAgICAgICAgaWYgKGtleSA9PT0gXCJ0ZXh0Q29udGVudFwiKSB7XG4gICAgICAgICAgaHRtbC50ZXh0Q29udGVudCA9IHZhbHVlO1xuICAgICAgICB9IGVsc2UgaWYgKGtleSA9PT0gXCJjbGFzc1wiKSB7XG4gICAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCkge1xuICAgICAgICAgICAgaHRtbC5zZXRBdHRyaWJ1dGUoa2V5LCB2YWx1ZS5qb2luKFwiIFwiKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChpc0hUTUxBbmNob3JFbGVtZW50ICYmIChrZXkgPT09IFwiaHJlZlwiIHx8IGtleSA9PT0gXCJuZXdXaW5kb3dcIikpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGh0bWwuc2V0QXR0cmlidXRlKGtleSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBPYmplY3QuYXNzaWduKGh0bWwuc3R5bGUsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNIVE1MQW5jaG9yRWxlbWVudCkge1xuICAgICAgbGlua1NlcnZpY2UuYWRkTGlua0F0dHJpYnV0ZXMoaHRtbCwgYXR0cmlidXRlcy5ocmVmLCBhdHRyaWJ1dGVzLm5ld1dpbmRvdyk7XG4gICAgfVxuXG4gICAgaWYgKHN0b3JhZ2UgJiYgYXR0cmlidXRlcy5kYXRhSWQpIHtcbiAgICAgIHRoaXMuc2V0dXBTdG9yYWdlKGh0bWwsIGF0dHJpYnV0ZXMuZGF0YUlkLCBlbGVtZW50LCBzdG9yYWdlKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgcmVuZGVyKHBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCBzdG9yYWdlID0gcGFyYW1ldGVycy5hbm5vdGF0aW9uU3RvcmFnZTtcbiAgICBjb25zdCBsaW5rU2VydmljZSA9IHBhcmFtZXRlcnMubGlua1NlcnZpY2U7XG4gICAgY29uc3Qgcm9vdCA9IHBhcmFtZXRlcnMueGZhSHRtbDtcbiAgICBjb25zdCBpbnRlbnQgPSBwYXJhbWV0ZXJzLmludGVudCB8fCBcImRpc3BsYXlcIjtcbiAgICBjb25zdCByb290SHRtbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQocm9vdC5uYW1lKTtcblxuICAgIGlmIChyb290LmF0dHJpYnV0ZXMpIHtcbiAgICAgIHRoaXMuc2V0QXR0cmlidXRlcyh7XG4gICAgICAgIGh0bWw6IHJvb3RIdG1sLFxuICAgICAgICBlbGVtZW50OiByb290LFxuICAgICAgICBpbnRlbnQsXG4gICAgICAgIGxpbmtTZXJ2aWNlXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBzdGFjayA9IFtbcm9vdCwgLTEsIHJvb3RIdG1sXV07XG4gICAgY29uc3Qgcm9vdERpdiA9IHBhcmFtZXRlcnMuZGl2O1xuICAgIHJvb3REaXYuYXBwZW5kQ2hpbGQocm9vdEh0bWwpO1xuXG4gICAgaWYgKHBhcmFtZXRlcnMudmlld3BvcnQpIHtcbiAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IGBtYXRyaXgoJHtwYXJhbWV0ZXJzLnZpZXdwb3J0LnRyYW5zZm9ybS5qb2luKFwiLFwiKX0pYDtcbiAgICAgIHJvb3REaXYuc3R5bGUudHJhbnNmb3JtID0gdHJhbnNmb3JtO1xuICAgIH1cblxuICAgIGlmIChpbnRlbnQgIT09IFwicmljaFRleHRcIikge1xuICAgICAgcm9vdERpdi5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBcInhmYUxheWVyIHhmYUZvbnRcIik7XG4gICAgfVxuXG4gICAgY29uc3QgdGV4dERpdnMgPSBbXTtcblxuICAgIHdoaWxlIChzdGFjay5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBbcGFyZW50LCBpLCBodG1sXSA9IHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdO1xuXG4gICAgICBpZiAoaSArIDEgPT09IHBhcmVudC5jaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjaGlsZCA9IHBhcmVudC5jaGlsZHJlblsrK3N0YWNrW3N0YWNrLmxlbmd0aCAtIDFdWzFdXTtcblxuICAgICAgaWYgKGNoaWxkID09PSBudWxsKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7XG4gICAgICAgIG5hbWVcbiAgICAgIH0gPSBjaGlsZDtcblxuICAgICAgaWYgKG5hbWUgPT09IFwiI3RleHRcIikge1xuICAgICAgICBjb25zdCBub2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoY2hpbGQudmFsdWUpO1xuICAgICAgICB0ZXh0RGl2cy5wdXNoKG5vZGUpO1xuICAgICAgICBodG1sLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgbGV0IGNoaWxkSHRtbDtcblxuICAgICAgaWYgKGNoaWxkPy5hdHRyaWJ1dGVzPy54bWxucykge1xuICAgICAgICBjaGlsZEh0bWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoY2hpbGQuYXR0cmlidXRlcy54bWxucywgbmFtZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjaGlsZEh0bWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KG5hbWUpO1xuICAgICAgfVxuXG4gICAgICBodG1sLmFwcGVuZENoaWxkKGNoaWxkSHRtbCk7XG5cbiAgICAgIGlmIChjaGlsZC5hdHRyaWJ1dGVzKSB7XG4gICAgICAgIHRoaXMuc2V0QXR0cmlidXRlcyh7XG4gICAgICAgICAgaHRtbDogY2hpbGRIdG1sLFxuICAgICAgICAgIGVsZW1lbnQ6IGNoaWxkLFxuICAgICAgICAgIHN0b3JhZ2UsXG4gICAgICAgICAgaW50ZW50LFxuICAgICAgICAgIGxpbmtTZXJ2aWNlXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2hpbGQuY2hpbGRyZW4gJiYgY2hpbGQuY2hpbGRyZW4ubGVuZ3RoID4gMCkge1xuICAgICAgICBzdGFjay5wdXNoKFtjaGlsZCwgLTEsIGNoaWxkSHRtbF0pO1xuICAgICAgfSBlbHNlIGlmIChjaGlsZC52YWx1ZSkge1xuICAgICAgICBjb25zdCBub2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoY2hpbGQudmFsdWUpO1xuXG4gICAgICAgIGlmIChfeGZhX3RleHQuWGZhVGV4dC5zaG91bGRCdWlsZFRleHQobmFtZSkpIHtcbiAgICAgICAgICB0ZXh0RGl2cy5wdXNoKG5vZGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgY2hpbGRIdG1sLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZWwgb2Ygcm9vdERpdi5xdWVyeVNlbGVjdG9yQWxsKFwiLnhmYU5vbkludGVyYWN0aXZlIGlucHV0LCAueGZhTm9uSW50ZXJhY3RpdmUgdGV4dGFyZWFcIikpIHtcbiAgICAgIGVsLnNldEF0dHJpYnV0ZShcInJlYWRPbmx5XCIsIHRydWUpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB0ZXh0RGl2c1xuICAgIH07XG4gIH1cblxuICBzdGF0aWMgdXBkYXRlKHBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCB0cmFuc2Zvcm0gPSBgbWF0cml4KCR7cGFyYW1ldGVycy52aWV3cG9ydC50cmFuc2Zvcm0uam9pbihcIixcIil9KWA7XG4gICAgcGFyYW1ldGVycy5kaXYuc3R5bGUudHJhbnNmb3JtID0gdHJhbnNmb3JtO1xuICAgIHBhcmFtZXRlcnMuZGl2LmhpZGRlbiA9IGZhbHNlO1xuICB9XG5cbn1cblxuZXhwb3J0cy5YZmFMYXllciA9IFhmYUxheWVyO1xuXG4vKioqLyB9KSxcbi8qIDIzICovXG4vKioqLyAoKF9fdW51c2VkX3dlYnBhY2tfbW9kdWxlLCBleHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5leHBvcnRzLnJlbmRlclRleHRMYXllciA9IHJlbmRlclRleHRMYXllcjtcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxuY29uc3QgTUFYX1RFWFRfRElWU19UT19SRU5ERVIgPSAxMDAwMDA7XG5jb25zdCBERUZBVUxUX0ZPTlRfU0laRSA9IDMwO1xuY29uc3QgREVGQVVMVF9GT05UX0FTQ0VOVCA9IDAuODtcbmNvbnN0IGFzY2VudENhY2hlID0gbmV3IE1hcCgpO1xuY29uc3QgQWxsV2hpdGVzcGFjZVJlZ2V4cCA9IC9eXFxzKyQvZztcblxuZnVuY3Rpb24gZ2V0QXNjZW50KGZvbnRGYW1pbHksIGN0eCkge1xuICBjb25zdCBjYWNoZWRBc2NlbnQgPSBhc2NlbnRDYWNoZS5nZXQoZm9udEZhbWlseSk7XG5cbiAgaWYgKGNhY2hlZEFzY2VudCkge1xuICAgIHJldHVybiBjYWNoZWRBc2NlbnQ7XG4gIH1cblxuICBjdHguc2F2ZSgpO1xuICBjdHguZm9udCA9IGAke0RFRkFVTFRfRk9OVF9TSVpFfXB4ICR7Zm9udEZhbWlseX1gO1xuICBjb25zdCBtZXRyaWNzID0gY3R4Lm1lYXN1cmVUZXh0KFwiXCIpO1xuICBsZXQgYXNjZW50ID0gbWV0cmljcy5mb250Qm91bmRpbmdCb3hBc2NlbnQ7XG4gIGxldCBkZXNjZW50ID0gTWF0aC5hYnMobWV0cmljcy5mb250Qm91bmRpbmdCb3hEZXNjZW50KTtcblxuICBpZiAoYXNjZW50KSB7XG4gICAgY3R4LnJlc3RvcmUoKTtcbiAgICBjb25zdCByYXRpbyA9IGFzY2VudCAvIChhc2NlbnQgKyBkZXNjZW50KTtcbiAgICBhc2NlbnRDYWNoZS5zZXQoZm9udEZhbWlseSwgcmF0aW8pO1xuICAgIHJldHVybiByYXRpbztcbiAgfVxuXG4gIGN0eC5zdHJva2VTdHlsZSA9IFwicmVkXCI7XG4gIGN0eC5jbGVhclJlY3QoMCwgMCwgREVGQVVMVF9GT05UX1NJWkUsIERFRkFVTFRfRk9OVF9TSVpFKTtcbiAgY3R4LnN0cm9rZVRleHQoXCJnXCIsIDAsIDApO1xuICBsZXQgcGl4ZWxzID0gY3R4LmdldEltYWdlRGF0YSgwLCAwLCBERUZBVUxUX0ZPTlRfU0laRSwgREVGQVVMVF9GT05UX1NJWkUpLmRhdGE7XG4gIGRlc2NlbnQgPSAwO1xuXG4gIGZvciAobGV0IGkgPSBwaXhlbHMubGVuZ3RoIC0gMSAtIDM7IGkgPj0gMDsgaSAtPSA0KSB7XG4gICAgaWYgKHBpeGVsc1tpXSA+IDApIHtcbiAgICAgIGRlc2NlbnQgPSBNYXRoLmNlaWwoaSAvIDQgLyBERUZBVUxUX0ZPTlRfU0laRSk7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBjdHguY2xlYXJSZWN0KDAsIDAsIERFRkFVTFRfRk9OVF9TSVpFLCBERUZBVUxUX0ZPTlRfU0laRSk7XG4gIGN0eC5zdHJva2VUZXh0KFwiQVwiLCAwLCBERUZBVUxUX0ZPTlRfU0laRSk7XG4gIHBpeGVscyA9IGN0eC5nZXRJbWFnZURhdGEoMCwgMCwgREVGQVVMVF9GT05UX1NJWkUsIERFRkFVTFRfRk9OVF9TSVpFKS5kYXRhO1xuICBhc2NlbnQgPSAwO1xuXG4gIGZvciAobGV0IGkgPSAwLCBpaSA9IHBpeGVscy5sZW5ndGg7IGkgPCBpaTsgaSArPSA0KSB7XG4gICAgaWYgKHBpeGVsc1tpXSA+IDApIHtcbiAgICAgIGFzY2VudCA9IERFRkFVTFRfRk9OVF9TSVpFIC0gTWF0aC5mbG9vcihpIC8gNCAvIERFRkFVTFRfRk9OVF9TSVpFKTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGN0eC5yZXN0b3JlKCk7XG5cbiAgaWYgKGFzY2VudCkge1xuICAgIGNvbnN0IHJhdGlvID0gYXNjZW50IC8gKGFzY2VudCArIGRlc2NlbnQpO1xuICAgIGFzY2VudENhY2hlLnNldChmb250RmFtaWx5LCByYXRpbyk7XG4gICAgcmV0dXJuIHJhdGlvO1xuICB9XG5cbiAgYXNjZW50Q2FjaGUuc2V0KGZvbnRGYW1pbHksIERFRkFVTFRfRk9OVF9BU0NFTlQpO1xuICByZXR1cm4gREVGQVVMVF9GT05UX0FTQ0VOVDtcbn1cblxuZnVuY3Rpb24gYXBwZW5kVGV4dCh0YXNrLCBnZW9tLCBzdHlsZXMsIGN0eCkge1xuICBjb25zdCB0ZXh0RGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNwYW5cIik7XG4gIGNvbnN0IHRleHREaXZQcm9wZXJ0aWVzID0gdGFzay5fZW5oYW5jZVRleHRTZWxlY3Rpb24gPyB7XG4gICAgYW5nbGU6IDAsXG4gICAgY2FudmFzV2lkdGg6IDAsXG4gICAgaGFzVGV4dDogZ2VvbS5zdHIgIT09IFwiXCIsXG4gICAgaGFzRU9MOiBnZW9tLmhhc0VPTCxcbiAgICBvcmlnaW5hbFRyYW5zZm9ybTogbnVsbCxcbiAgICBwYWRkaW5nQm90dG9tOiAwLFxuICAgIHBhZGRpbmdMZWZ0OiAwLFxuICAgIHBhZGRpbmdSaWdodDogMCxcbiAgICBwYWRkaW5nVG9wOiAwLFxuICAgIHNjYWxlOiAxXG4gIH0gOiB7XG4gICAgYW5nbGU6IDAsXG4gICAgY2FudmFzV2lkdGg6IDAsXG4gICAgaGFzVGV4dDogZ2VvbS5zdHIgIT09IFwiXCIsXG4gICAgaGFzRU9MOiBnZW9tLmhhc0VPTFxuICB9O1xuXG4gIHRhc2suX3RleHREaXZzLnB1c2godGV4dERpdik7XG5cbiAgY29uc3QgdHggPSBfdXRpbC5VdGlsLnRyYW5zZm9ybSh0YXNrLl92aWV3cG9ydC50cmFuc2Zvcm0sIGdlb20udHJhbnNmb3JtKTtcblxuICBsZXQgYW5nbGUgPSBNYXRoLmF0YW4yKHR4WzFdLCB0eFswXSk7XG4gIGNvbnN0IHN0eWxlID0gc3R5bGVzW2dlb20uZm9udE5hbWVdO1xuXG4gIGlmIChzdHlsZS52ZXJ0aWNhbCkge1xuICAgIGFuZ2xlICs9IE1hdGguUEkgLyAyO1xuICB9XG5cbiAgY29uc3QgZm9udEhlaWdodCA9IE1hdGguaHlwb3QodHhbMl0sIHR4WzNdKTtcbiAgY29uc3QgZm9udEFzY2VudCA9IGZvbnRIZWlnaHQgKiBnZXRBc2NlbnQoc3R5bGUuZm9udEZhbWlseSwgY3R4KTtcbiAgbGV0IGxlZnQsIHRvcDtcblxuICBpZiAoYW5nbGUgPT09IDApIHtcbiAgICBsZWZ0ID0gdHhbNF07XG4gICAgdG9wID0gdHhbNV0gLSBmb250QXNjZW50O1xuICB9IGVsc2Uge1xuICAgIGxlZnQgPSB0eFs0XSArIGZvbnRBc2NlbnQgKiBNYXRoLnNpbihhbmdsZSk7XG4gICAgdG9wID0gdHhbNV0gLSBmb250QXNjZW50ICogTWF0aC5jb3MoYW5nbGUpO1xuICB9XG5cbiAgdGV4dERpdi5zdHlsZS5sZWZ0ID0gYCR7bGVmdH1weGA7XG4gIHRleHREaXYuc3R5bGUudG9wID0gYCR7dG9wfXB4YDtcbiAgdGV4dERpdi5zdHlsZS5mb250U2l6ZSA9IGAke2ZvbnRIZWlnaHR9cHhgO1xuICB0ZXh0RGl2LnN0eWxlLmZvbnRGYW1pbHkgPSBzdHlsZS5mb250RmFtaWx5O1xuICB0ZXh0RGl2LnNldEF0dHJpYnV0ZShcInJvbGVcIiwgXCJwcmVzZW50YXRpb25cIik7XG4gIHRleHREaXYudGV4dENvbnRlbnQgPSBnZW9tLnN0cjtcbiAgdGV4dERpdi5kaXIgPSBnZW9tLmRpcjtcblxuICBpZiAodGFzay5fZm9udEluc3BlY3RvckVuYWJsZWQpIHtcbiAgICB0ZXh0RGl2LmRhdGFzZXQuZm9udE5hbWUgPSBnZW9tLmZvbnROYW1lO1xuICB9XG5cbiAgaWYgKGFuZ2xlICE9PSAwKSB7XG4gICAgdGV4dERpdlByb3BlcnRpZXMuYW5nbGUgPSBhbmdsZSAqICgxODAgLyBNYXRoLlBJKTtcbiAgfVxuXG4gIGxldCBzaG91bGRTY2FsZVRleHQgPSBmYWxzZTtcblxuICBpZiAoZ2VvbS5zdHIubGVuZ3RoID4gMSB8fCB0YXNrLl9lbmhhbmNlVGV4dFNlbGVjdGlvbiAmJiBBbGxXaGl0ZXNwYWNlUmVnZXhwLnRlc3QoZ2VvbS5zdHIpKSB7XG4gICAgc2hvdWxkU2NhbGVUZXh0ID0gdHJ1ZTtcbiAgfSBlbHNlIGlmIChnZW9tLnN0ciAhPT0gXCIgXCIgJiYgZ2VvbS50cmFuc2Zvcm1bMF0gIT09IGdlb20udHJhbnNmb3JtWzNdKSB7XG4gICAgY29uc3QgYWJzU2NhbGVYID0gTWF0aC5hYnMoZ2VvbS50cmFuc2Zvcm1bMF0pLFxuICAgICAgICAgIGFic1NjYWxlWSA9IE1hdGguYWJzKGdlb20udHJhbnNmb3JtWzNdKTtcblxuICAgIGlmIChhYnNTY2FsZVggIT09IGFic1NjYWxlWSAmJiBNYXRoLm1heChhYnNTY2FsZVgsIGFic1NjYWxlWSkgLyBNYXRoLm1pbihhYnNTY2FsZVgsIGFic1NjYWxlWSkgPiAxLjUpIHtcbiAgICAgIHNob3VsZFNjYWxlVGV4dCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgaWYgKHNob3VsZFNjYWxlVGV4dCkge1xuICAgIGlmIChzdHlsZS52ZXJ0aWNhbCkge1xuICAgICAgdGV4dERpdlByb3BlcnRpZXMuY2FudmFzV2lkdGggPSBnZW9tLmhlaWdodCAqIHRhc2suX3ZpZXdwb3J0LnNjYWxlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0ZXh0RGl2UHJvcGVydGllcy5jYW52YXNXaWR0aCA9IGdlb20ud2lkdGggKiB0YXNrLl92aWV3cG9ydC5zY2FsZTtcbiAgICB9XG4gIH1cblxuICB0YXNrLl90ZXh0RGl2UHJvcGVydGllcy5zZXQodGV4dERpdiwgdGV4dERpdlByb3BlcnRpZXMpO1xuXG4gIGlmICh0YXNrLl90ZXh0Q29udGVudFN0cmVhbSkge1xuICAgIHRhc2suX2xheW91dFRleHQodGV4dERpdik7XG4gIH1cblxuICBpZiAodGFzay5fZW5oYW5jZVRleHRTZWxlY3Rpb24gJiYgdGV4dERpdlByb3BlcnRpZXMuaGFzVGV4dCkge1xuICAgIGxldCBhbmdsZUNvcyA9IDEsXG4gICAgICAgIGFuZ2xlU2luID0gMDtcblxuICAgIGlmIChhbmdsZSAhPT0gMCkge1xuICAgICAgYW5nbGVDb3MgPSBNYXRoLmNvcyhhbmdsZSk7XG4gICAgICBhbmdsZVNpbiA9IE1hdGguc2luKGFuZ2xlKTtcbiAgICB9XG5cbiAgICBjb25zdCBkaXZXaWR0aCA9IChzdHlsZS52ZXJ0aWNhbCA/IGdlb20uaGVpZ2h0IDogZ2VvbS53aWR0aCkgKiB0YXNrLl92aWV3cG9ydC5zY2FsZTtcbiAgICBjb25zdCBkaXZIZWlnaHQgPSBmb250SGVpZ2h0O1xuICAgIGxldCBtLCBiO1xuXG4gICAgaWYgKGFuZ2xlICE9PSAwKSB7XG4gICAgICBtID0gW2FuZ2xlQ29zLCBhbmdsZVNpbiwgLWFuZ2xlU2luLCBhbmdsZUNvcywgbGVmdCwgdG9wXTtcbiAgICAgIGIgPSBfdXRpbC5VdGlsLmdldEF4aWFsQWxpZ25lZEJvdW5kaW5nQm94KFswLCAwLCBkaXZXaWR0aCwgZGl2SGVpZ2h0XSwgbSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGIgPSBbbGVmdCwgdG9wLCBsZWZ0ICsgZGl2V2lkdGgsIHRvcCArIGRpdkhlaWdodF07XG4gICAgfVxuXG4gICAgdGFzay5fYm91bmRzLnB1c2goe1xuICAgICAgbGVmdDogYlswXSxcbiAgICAgIHRvcDogYlsxXSxcbiAgICAgIHJpZ2h0OiBiWzJdLFxuICAgICAgYm90dG9tOiBiWzNdLFxuICAgICAgZGl2OiB0ZXh0RGl2LFxuICAgICAgc2l6ZTogW2RpdldpZHRoLCBkaXZIZWlnaHRdLFxuICAgICAgbVxuICAgIH0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlbmRlcih0YXNrKSB7XG4gIGlmICh0YXNrLl9jYW5jZWxlZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHRleHREaXZzID0gdGFzay5fdGV4dERpdnM7XG4gIGNvbnN0IGNhcGFiaWxpdHkgPSB0YXNrLl9jYXBhYmlsaXR5O1xuICBjb25zdCB0ZXh0RGl2c0xlbmd0aCA9IHRleHREaXZzLmxlbmd0aDtcblxuICBpZiAodGV4dERpdnNMZW5ndGggPiBNQVhfVEVYVF9ESVZTX1RPX1JFTkRFUikge1xuICAgIHRhc2suX3JlbmRlcmluZ0RvbmUgPSB0cnVlO1xuICAgIGNhcGFiaWxpdHkucmVzb2x2ZSgpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICghdGFzay5fdGV4dENvbnRlbnRTdHJlYW0pIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRleHREaXZzTGVuZ3RoOyBpKyspIHtcbiAgICAgIHRhc2suX2xheW91dFRleHQodGV4dERpdnNbaV0pO1xuICAgIH1cbiAgfVxuXG4gIHRhc2suX3JlbmRlcmluZ0RvbmUgPSB0cnVlO1xuICBjYXBhYmlsaXR5LnJlc29sdmUoKTtcbn1cblxuZnVuY3Rpb24gZmluZFBvc2l0aXZlTWluKHRzLCBvZmZzZXQsIGNvdW50KSB7XG4gIGxldCByZXN1bHQgPSAwO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgIGNvbnN0IHQgPSB0c1tvZmZzZXQrK107XG5cbiAgICBpZiAodCA+IDApIHtcbiAgICAgIHJlc3VsdCA9IHJlc3VsdCA/IE1hdGgubWluKHQsIHJlc3VsdCkgOiB0O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGV4cGFuZCh0YXNrKSB7XG4gIGNvbnN0IGJvdW5kcyA9IHRhc2suX2JvdW5kcztcbiAgY29uc3Qgdmlld3BvcnQgPSB0YXNrLl92aWV3cG9ydDtcbiAgY29uc3QgZXhwYW5kZWQgPSBleHBhbmRCb3VuZHModmlld3BvcnQud2lkdGgsIHZpZXdwb3J0LmhlaWdodCwgYm91bmRzKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cGFuZGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgZGl2ID0gYm91bmRzW2ldLmRpdjtcblxuICAgIGNvbnN0IGRpdlByb3BlcnRpZXMgPSB0YXNrLl90ZXh0RGl2UHJvcGVydGllcy5nZXQoZGl2KTtcblxuICAgIGlmIChkaXZQcm9wZXJ0aWVzLmFuZ2xlID09PSAwKSB7XG4gICAgICBkaXZQcm9wZXJ0aWVzLnBhZGRpbmdMZWZ0ID0gYm91bmRzW2ldLmxlZnQgLSBleHBhbmRlZFtpXS5sZWZ0O1xuICAgICAgZGl2UHJvcGVydGllcy5wYWRkaW5nVG9wID0gYm91bmRzW2ldLnRvcCAtIGV4cGFuZGVkW2ldLnRvcDtcbiAgICAgIGRpdlByb3BlcnRpZXMucGFkZGluZ1JpZ2h0ID0gZXhwYW5kZWRbaV0ucmlnaHQgLSBib3VuZHNbaV0ucmlnaHQ7XG4gICAgICBkaXZQcm9wZXJ0aWVzLnBhZGRpbmdCb3R0b20gPSBleHBhbmRlZFtpXS5ib3R0b20gLSBib3VuZHNbaV0uYm90dG9tO1xuXG4gICAgICB0YXNrLl90ZXh0RGl2UHJvcGVydGllcy5zZXQoZGl2LCBkaXZQcm9wZXJ0aWVzKTtcblxuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY29uc3QgZSA9IGV4cGFuZGVkW2ldLFxuICAgICAgICAgIGIgPSBib3VuZHNbaV07XG4gICAgY29uc3QgbSA9IGIubSxcbiAgICAgICAgICBjID0gbVswXSxcbiAgICAgICAgICBzID0gbVsxXTtcbiAgICBjb25zdCBwb2ludHMgPSBbWzAsIDBdLCBbMCwgYi5zaXplWzFdXSwgW2Iuc2l6ZVswXSwgMF0sIGIuc2l6ZV07XG4gICAgY29uc3QgdHMgPSBuZXcgRmxvYXQ2NEFycmF5KDY0KTtcblxuICAgIGZvciAobGV0IGogPSAwLCBqaiA9IHBvaW50cy5sZW5ndGg7IGogPCBqajsgaisrKSB7XG4gICAgICBjb25zdCB0ID0gX3V0aWwuVXRpbC5hcHBseVRyYW5zZm9ybShwb2ludHNbal0sIG0pO1xuXG4gICAgICB0c1tqICsgMF0gPSBjICYmIChlLmxlZnQgLSB0WzBdKSAvIGM7XG4gICAgICB0c1tqICsgNF0gPSBzICYmIChlLnRvcCAtIHRbMV0pIC8gcztcbiAgICAgIHRzW2ogKyA4XSA9IGMgJiYgKGUucmlnaHQgLSB0WzBdKSAvIGM7XG4gICAgICB0c1tqICsgMTJdID0gcyAmJiAoZS5ib3R0b20gLSB0WzFdKSAvIHM7XG4gICAgICB0c1tqICsgMTZdID0gcyAmJiAoZS5sZWZ0IC0gdFswXSkgLyAtcztcbiAgICAgIHRzW2ogKyAyMF0gPSBjICYmIChlLnRvcCAtIHRbMV0pIC8gYztcbiAgICAgIHRzW2ogKyAyNF0gPSBzICYmIChlLnJpZ2h0IC0gdFswXSkgLyAtcztcbiAgICAgIHRzW2ogKyAyOF0gPSBjICYmIChlLmJvdHRvbSAtIHRbMV0pIC8gYztcbiAgICAgIHRzW2ogKyAzMl0gPSBjICYmIChlLmxlZnQgLSB0WzBdKSAvIC1jO1xuICAgICAgdHNbaiArIDM2XSA9IHMgJiYgKGUudG9wIC0gdFsxXSkgLyAtcztcbiAgICAgIHRzW2ogKyA0MF0gPSBjICYmIChlLnJpZ2h0IC0gdFswXSkgLyAtYztcbiAgICAgIHRzW2ogKyA0NF0gPSBzICYmIChlLmJvdHRvbSAtIHRbMV0pIC8gLXM7XG4gICAgICB0c1tqICsgNDhdID0gcyAmJiAoZS5sZWZ0IC0gdFswXSkgLyBzO1xuICAgICAgdHNbaiArIDUyXSA9IGMgJiYgKGUudG9wIC0gdFsxXSkgLyAtYztcbiAgICAgIHRzW2ogKyA1Nl0gPSBzICYmIChlLnJpZ2h0IC0gdFswXSkgLyBzO1xuICAgICAgdHNbaiArIDYwXSA9IGMgJiYgKGUuYm90dG9tIC0gdFsxXSkgLyAtYztcbiAgICB9XG5cbiAgICBjb25zdCBib3hTY2FsZSA9IDEgKyBNYXRoLm1pbihNYXRoLmFicyhjKSwgTWF0aC5hYnMocykpO1xuICAgIGRpdlByb3BlcnRpZXMucGFkZGluZ0xlZnQgPSBmaW5kUG9zaXRpdmVNaW4odHMsIDMyLCAxNikgLyBib3hTY2FsZTtcbiAgICBkaXZQcm9wZXJ0aWVzLnBhZGRpbmdUb3AgPSBmaW5kUG9zaXRpdmVNaW4odHMsIDQ4LCAxNikgLyBib3hTY2FsZTtcbiAgICBkaXZQcm9wZXJ0aWVzLnBhZGRpbmdSaWdodCA9IGZpbmRQb3NpdGl2ZU1pbih0cywgMCwgMTYpIC8gYm94U2NhbGU7XG4gICAgZGl2UHJvcGVydGllcy5wYWRkaW5nQm90dG9tID0gZmluZFBvc2l0aXZlTWluKHRzLCAxNiwgMTYpIC8gYm94U2NhbGU7XG5cbiAgICB0YXNrLl90ZXh0RGl2UHJvcGVydGllcy5zZXQoZGl2LCBkaXZQcm9wZXJ0aWVzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBleHBhbmRCb3VuZHMod2lkdGgsIGhlaWdodCwgYm94ZXMpIHtcbiAgY29uc3QgYm91bmRzID0gYm94ZXMubWFwKGZ1bmN0aW9uIChib3gsIGkpIHtcbiAgICByZXR1cm4ge1xuICAgICAgeDE6IGJveC5sZWZ0LFxuICAgICAgeTE6IGJveC50b3AsXG4gICAgICB4MjogYm94LnJpZ2h0LFxuICAgICAgeTI6IGJveC5ib3R0b20sXG4gICAgICBpbmRleDogaSxcbiAgICAgIHgxTmV3OiB1bmRlZmluZWQsXG4gICAgICB4Mk5ldzogdW5kZWZpbmVkXG4gICAgfTtcbiAgfSk7XG4gIGV4cGFuZEJvdW5kc0xUUih3aWR0aCwgYm91bmRzKTtcbiAgY29uc3QgZXhwYW5kZWQgPSBuZXcgQXJyYXkoYm94ZXMubGVuZ3RoKTtcblxuICBmb3IgKGNvbnN0IGIgb2YgYm91bmRzKSB7XG4gICAgY29uc3QgaSA9IGIuaW5kZXg7XG4gICAgZXhwYW5kZWRbaV0gPSB7XG4gICAgICBsZWZ0OiBiLngxTmV3LFxuICAgICAgdG9wOiAwLFxuICAgICAgcmlnaHQ6IGIueDJOZXcsXG4gICAgICBib3R0b206IDBcbiAgICB9O1xuICB9XG5cbiAgYm94ZXMubWFwKGZ1bmN0aW9uIChib3gsIGkpIHtcbiAgICBjb25zdCBlID0gZXhwYW5kZWRbaV0sXG4gICAgICAgICAgYiA9IGJvdW5kc1tpXTtcbiAgICBiLngxID0gYm94LnRvcDtcbiAgICBiLnkxID0gd2lkdGggLSBlLnJpZ2h0O1xuICAgIGIueDIgPSBib3guYm90dG9tO1xuICAgIGIueTIgPSB3aWR0aCAtIGUubGVmdDtcbiAgICBiLmluZGV4ID0gaTtcbiAgICBiLngxTmV3ID0gdW5kZWZpbmVkO1xuICAgIGIueDJOZXcgPSB1bmRlZmluZWQ7XG4gIH0pO1xuICBleHBhbmRCb3VuZHNMVFIoaGVpZ2h0LCBib3VuZHMpO1xuXG4gIGZvciAoY29uc3QgYiBvZiBib3VuZHMpIHtcbiAgICBjb25zdCBpID0gYi5pbmRleDtcbiAgICBleHBhbmRlZFtpXS50b3AgPSBiLngxTmV3O1xuICAgIGV4cGFuZGVkW2ldLmJvdHRvbSA9IGIueDJOZXc7XG4gIH1cblxuICByZXR1cm4gZXhwYW5kZWQ7XG59XG5cbmZ1bmN0aW9uIGV4cGFuZEJvdW5kc0xUUih3aWR0aCwgYm91bmRzKSB7XG4gIGJvdW5kcy5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgcmV0dXJuIGEueDEgLSBiLngxIHx8IGEuaW5kZXggLSBiLmluZGV4O1xuICB9KTtcbiAgY29uc3QgZmFrZUJvdW5kYXJ5ID0ge1xuICAgIHgxOiAtSW5maW5pdHksXG4gICAgeTE6IC1JbmZpbml0eSxcbiAgICB4MjogMCxcbiAgICB5MjogSW5maW5pdHksXG4gICAgaW5kZXg6IC0xLFxuICAgIHgxTmV3OiAwLFxuICAgIHgyTmV3OiAwXG4gIH07XG4gIGNvbnN0IGhvcml6b24gPSBbe1xuICAgIHN0YXJ0OiAtSW5maW5pdHksXG4gICAgZW5kOiBJbmZpbml0eSxcbiAgICBib3VuZGFyeTogZmFrZUJvdW5kYXJ5XG4gIH1dO1xuXG4gIGZvciAoY29uc3QgYm91bmRhcnkgb2YgYm91bmRzKSB7XG4gICAgbGV0IGkgPSAwO1xuXG4gICAgd2hpbGUgKGkgPCBob3Jpem9uLmxlbmd0aCAmJiBob3Jpem9uW2ldLmVuZCA8PSBib3VuZGFyeS55MSkge1xuICAgICAgaSsrO1xuICAgIH1cblxuICAgIGxldCBqID0gaG9yaXpvbi5sZW5ndGggLSAxO1xuXG4gICAgd2hpbGUgKGogPj0gMCAmJiBob3Jpem9uW2pdLnN0YXJ0ID49IGJvdW5kYXJ5LnkyKSB7XG4gICAgICBqLS07XG4gICAgfVxuXG4gICAgbGV0IGhvcml6b25QYXJ0LCBhZmZlY3RlZEJvdW5kYXJ5O1xuICAgIGxldCBxLFxuICAgICAgICBrLFxuICAgICAgICBtYXhYTmV3ID0gLUluZmluaXR5O1xuXG4gICAgZm9yIChxID0gaTsgcSA8PSBqOyBxKyspIHtcbiAgICAgIGhvcml6b25QYXJ0ID0gaG9yaXpvbltxXTtcbiAgICAgIGFmZmVjdGVkQm91bmRhcnkgPSBob3Jpem9uUGFydC5ib3VuZGFyeTtcbiAgICAgIGxldCB4TmV3O1xuXG4gICAgICBpZiAoYWZmZWN0ZWRCb3VuZGFyeS54MiA+IGJvdW5kYXJ5LngxKSB7XG4gICAgICAgIHhOZXcgPSBhZmZlY3RlZEJvdW5kYXJ5LmluZGV4ID4gYm91bmRhcnkuaW5kZXggPyBhZmZlY3RlZEJvdW5kYXJ5LngxTmV3IDogYm91bmRhcnkueDE7XG4gICAgICB9IGVsc2UgaWYgKGFmZmVjdGVkQm91bmRhcnkueDJOZXcgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB4TmV3ID0gKGFmZmVjdGVkQm91bmRhcnkueDIgKyBib3VuZGFyeS54MSkgLyAyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgeE5ldyA9IGFmZmVjdGVkQm91bmRhcnkueDJOZXc7XG4gICAgICB9XG5cbiAgICAgIGlmICh4TmV3ID4gbWF4WE5ldykge1xuICAgICAgICBtYXhYTmV3ID0geE5ldztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBib3VuZGFyeS54MU5ldyA9IG1heFhOZXc7XG5cbiAgICBmb3IgKHEgPSBpOyBxIDw9IGo7IHErKykge1xuICAgICAgaG9yaXpvblBhcnQgPSBob3Jpem9uW3FdO1xuICAgICAgYWZmZWN0ZWRCb3VuZGFyeSA9IGhvcml6b25QYXJ0LmJvdW5kYXJ5O1xuXG4gICAgICBpZiAoYWZmZWN0ZWRCb3VuZGFyeS54Mk5ldyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChhZmZlY3RlZEJvdW5kYXJ5LngyID4gYm91bmRhcnkueDEpIHtcbiAgICAgICAgICBpZiAoYWZmZWN0ZWRCb3VuZGFyeS5pbmRleCA+IGJvdW5kYXJ5LmluZGV4KSB7XG4gICAgICAgICAgICBhZmZlY3RlZEJvdW5kYXJ5LngyTmV3ID0gYWZmZWN0ZWRCb3VuZGFyeS54MjtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYWZmZWN0ZWRCb3VuZGFyeS54Mk5ldyA9IG1heFhOZXc7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoYWZmZWN0ZWRCb3VuZGFyeS54Mk5ldyA+IG1heFhOZXcpIHtcbiAgICAgICAgYWZmZWN0ZWRCb3VuZGFyeS54Mk5ldyA9IE1hdGgubWF4KG1heFhOZXcsIGFmZmVjdGVkQm91bmRhcnkueDIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGNoYW5nZWRIb3Jpem9uID0gW107XG4gICAgbGV0IGxhc3RCb3VuZGFyeSA9IG51bGw7XG5cbiAgICBmb3IgKHEgPSBpOyBxIDw9IGo7IHErKykge1xuICAgICAgaG9yaXpvblBhcnQgPSBob3Jpem9uW3FdO1xuICAgICAgYWZmZWN0ZWRCb3VuZGFyeSA9IGhvcml6b25QYXJ0LmJvdW5kYXJ5O1xuICAgICAgY29uc3QgdXNlQm91bmRhcnkgPSBhZmZlY3RlZEJvdW5kYXJ5LngyID4gYm91bmRhcnkueDIgPyBhZmZlY3RlZEJvdW5kYXJ5IDogYm91bmRhcnk7XG5cbiAgICAgIGlmIChsYXN0Qm91bmRhcnkgPT09IHVzZUJvdW5kYXJ5KSB7XG4gICAgICAgIGNoYW5nZWRIb3Jpem9uW2NoYW5nZWRIb3Jpem9uLmxlbmd0aCAtIDFdLmVuZCA9IGhvcml6b25QYXJ0LmVuZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNoYW5nZWRIb3Jpem9uLnB1c2goe1xuICAgICAgICAgIHN0YXJ0OiBob3Jpem9uUGFydC5zdGFydCxcbiAgICAgICAgICBlbmQ6IGhvcml6b25QYXJ0LmVuZCxcbiAgICAgICAgICBib3VuZGFyeTogdXNlQm91bmRhcnlcbiAgICAgICAgfSk7XG4gICAgICAgIGxhc3RCb3VuZGFyeSA9IHVzZUJvdW5kYXJ5O1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChob3Jpem9uW2ldLnN0YXJ0IDwgYm91bmRhcnkueTEpIHtcbiAgICAgIGNoYW5nZWRIb3Jpem9uWzBdLnN0YXJ0ID0gYm91bmRhcnkueTE7XG4gICAgICBjaGFuZ2VkSG9yaXpvbi51bnNoaWZ0KHtcbiAgICAgICAgc3RhcnQ6IGhvcml6b25baV0uc3RhcnQsXG4gICAgICAgIGVuZDogYm91bmRhcnkueTEsXG4gICAgICAgIGJvdW5kYXJ5OiBob3Jpem9uW2ldLmJvdW5kYXJ5XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoYm91bmRhcnkueTIgPCBob3Jpem9uW2pdLmVuZCkge1xuICAgICAgY2hhbmdlZEhvcml6b25bY2hhbmdlZEhvcml6b24ubGVuZ3RoIC0gMV0uZW5kID0gYm91bmRhcnkueTI7XG4gICAgICBjaGFuZ2VkSG9yaXpvbi5wdXNoKHtcbiAgICAgICAgc3RhcnQ6IGJvdW5kYXJ5LnkyLFxuICAgICAgICBlbmQ6IGhvcml6b25bal0uZW5kLFxuICAgICAgICBib3VuZGFyeTogaG9yaXpvbltqXS5ib3VuZGFyeVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgZm9yIChxID0gaTsgcSA8PSBqOyBxKyspIHtcbiAgICAgIGhvcml6b25QYXJ0ID0gaG9yaXpvbltxXTtcbiAgICAgIGFmZmVjdGVkQm91bmRhcnkgPSBob3Jpem9uUGFydC5ib3VuZGFyeTtcblxuICAgICAgaWYgKGFmZmVjdGVkQm91bmRhcnkueDJOZXcgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgbGV0IHVzZWQgPSBmYWxzZTtcblxuICAgICAgZm9yIChrID0gaSAtIDE7ICF1c2VkICYmIGsgPj0gMCAmJiBob3Jpem9uW2tdLnN0YXJ0ID49IGFmZmVjdGVkQm91bmRhcnkueTE7IGstLSkge1xuICAgICAgICB1c2VkID0gaG9yaXpvbltrXS5ib3VuZGFyeSA9PT0gYWZmZWN0ZWRCb3VuZGFyeTtcbiAgICAgIH1cblxuICAgICAgZm9yIChrID0gaiArIDE7ICF1c2VkICYmIGsgPCBob3Jpem9uLmxlbmd0aCAmJiBob3Jpem9uW2tdLmVuZCA8PSBhZmZlY3RlZEJvdW5kYXJ5LnkyOyBrKyspIHtcbiAgICAgICAgdXNlZCA9IGhvcml6b25ba10uYm91bmRhcnkgPT09IGFmZmVjdGVkQm91bmRhcnk7XG4gICAgICB9XG5cbiAgICAgIGZvciAoayA9IDA7ICF1c2VkICYmIGsgPCBjaGFuZ2VkSG9yaXpvbi5sZW5ndGg7IGsrKykge1xuICAgICAgICB1c2VkID0gY2hhbmdlZEhvcml6b25ba10uYm91bmRhcnkgPT09IGFmZmVjdGVkQm91bmRhcnk7XG4gICAgICB9XG5cbiAgICAgIGlmICghdXNlZCkge1xuICAgICAgICBhZmZlY3RlZEJvdW5kYXJ5LngyTmV3ID0gbWF4WE5ldztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBBcnJheS5wcm90b3R5cGUuc3BsaWNlLmFwcGx5KGhvcml6b24sIFtpLCBqIC0gaSArIDFdLmNvbmNhdChjaGFuZ2VkSG9yaXpvbikpO1xuICB9XG5cbiAgZm9yIChjb25zdCBob3Jpem9uUGFydCBvZiBob3Jpem9uKSB7XG4gICAgY29uc3QgYWZmZWN0ZWRCb3VuZGFyeSA9IGhvcml6b25QYXJ0LmJvdW5kYXJ5O1xuXG4gICAgaWYgKGFmZmVjdGVkQm91bmRhcnkueDJOZXcgPT09IHVuZGVmaW5lZCkge1xuICAgICAgYWZmZWN0ZWRCb3VuZGFyeS54Mk5ldyA9IE1hdGgubWF4KHdpZHRoLCBhZmZlY3RlZEJvdW5kYXJ5LngyKTtcbiAgICB9XG4gIH1cbn1cblxuY2xhc3MgVGV4dExheWVyUmVuZGVyVGFzayB7XG4gIGNvbnN0cnVjdG9yKHtcbiAgICB0ZXh0Q29udGVudCxcbiAgICB0ZXh0Q29udGVudFN0cmVhbSxcbiAgICBjb250YWluZXIsXG4gICAgdmlld3BvcnQsXG4gICAgdGV4dERpdnMsXG4gICAgdGV4dENvbnRlbnRJdGVtc1N0cixcbiAgICBlbmhhbmNlVGV4dFNlbGVjdGlvblxuICB9KSB7XG4gICAgdGhpcy5fdGV4dENvbnRlbnQgPSB0ZXh0Q29udGVudDtcbiAgICB0aGlzLl90ZXh0Q29udGVudFN0cmVhbSA9IHRleHRDb250ZW50U3RyZWFtO1xuICAgIHRoaXMuX2NvbnRhaW5lciA9IGNvbnRhaW5lcjtcbiAgICB0aGlzLl9kb2N1bWVudCA9IGNvbnRhaW5lci5vd25lckRvY3VtZW50O1xuICAgIHRoaXMuX3ZpZXdwb3J0ID0gdmlld3BvcnQ7XG4gICAgdGhpcy5fdGV4dERpdnMgPSB0ZXh0RGl2cyB8fCBbXTtcbiAgICB0aGlzLl90ZXh0Q29udGVudEl0ZW1zU3RyID0gdGV4dENvbnRlbnRJdGVtc1N0ciB8fCBbXTtcbiAgICB0aGlzLl9lbmhhbmNlVGV4dFNlbGVjdGlvbiA9ICEhZW5oYW5jZVRleHRTZWxlY3Rpb247XG4gICAgdGhpcy5fZm9udEluc3BlY3RvckVuYWJsZWQgPSAhIWdsb2JhbFRoaXMuRm9udEluc3BlY3Rvcj8uZW5hYmxlZDtcbiAgICB0aGlzLl9yZWFkZXIgPSBudWxsO1xuICAgIHRoaXMuX2xheW91dFRleHRMYXN0Rm9udFNpemUgPSBudWxsO1xuICAgIHRoaXMuX2xheW91dFRleHRMYXN0Rm9udEZhbWlseSA9IG51bGw7XG4gICAgdGhpcy5fbGF5b3V0VGV4dEN0eCA9IG51bGw7XG4gICAgdGhpcy5fdGV4dERpdlByb3BlcnRpZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgIHRoaXMuX3JlbmRlcmluZ0RvbmUgPSBmYWxzZTtcbiAgICB0aGlzLl9jYW5jZWxlZCA9IGZhbHNlO1xuICAgIHRoaXMuX2NhcGFiaWxpdHkgPSAoMCwgX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkpKCk7XG4gICAgdGhpcy5fcmVuZGVyVGltZXIgPSBudWxsO1xuICAgIHRoaXMuX2JvdW5kcyA9IFtdO1xuXG4gICAgdGhpcy5fY2FwYWJpbGl0eS5wcm9taXNlLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLl9lbmhhbmNlVGV4dFNlbGVjdGlvbikge1xuICAgICAgICB0aGlzLl90ZXh0RGl2UHJvcGVydGllcyA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLl9sYXlvdXRUZXh0Q3R4KSB7XG4gICAgICAgIHRoaXMuX2xheW91dFRleHRDdHguY2FudmFzLndpZHRoID0gMDtcbiAgICAgICAgdGhpcy5fbGF5b3V0VGV4dEN0eC5jYW52YXMuaGVpZ2h0ID0gMDtcbiAgICAgICAgdGhpcy5fbGF5b3V0VGV4dEN0eCA9IG51bGw7XG4gICAgICB9XG4gICAgfSkuY2F0Y2goKCkgPT4ge30pO1xuICB9XG5cbiAgZ2V0IHByb21pc2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxuXG4gIGNhbmNlbCgpIHtcbiAgICB0aGlzLl9jYW5jZWxlZCA9IHRydWU7XG5cbiAgICBpZiAodGhpcy5fcmVhZGVyKSB7XG4gICAgICB0aGlzLl9yZWFkZXIuY2FuY2VsKG5ldyBfdXRpbC5BYm9ydEV4Y2VwdGlvbihcIlRleHRMYXllciB0YXNrIGNhbmNlbGxlZC5cIikpLmNhdGNoKCgpID0+IHt9KTtcblxuICAgICAgdGhpcy5fcmVhZGVyID0gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fcmVuZGVyVGltZXIgIT09IG51bGwpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9yZW5kZXJUaW1lcik7XG4gICAgICB0aGlzLl9yZW5kZXJUaW1lciA9IG51bGw7XG4gICAgfVxuXG4gICAgdGhpcy5fY2FwYWJpbGl0eS5yZWplY3QobmV3IEVycm9yKFwiVGV4dExheWVyIHRhc2sgY2FuY2VsbGVkLlwiKSk7XG4gIH1cblxuICBfcHJvY2Vzc0l0ZW1zKGl0ZW1zLCBzdHlsZUNhY2hlKSB7XG4gICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGl0ZW1zLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBpZiAoaXRlbXNbaV0uc3RyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKGl0ZW1zW2ldLnR5cGUgPT09IFwiYmVnaW5NYXJrZWRDb250ZW50UHJvcHNcIiB8fCBpdGVtc1tpXS50eXBlID09PSBcImJlZ2luTWFya2VkQ29udGVudFwiKSB7XG4gICAgICAgICAgY29uc3QgcGFyZW50ID0gdGhpcy5fY29udGFpbmVyO1xuICAgICAgICAgIHRoaXMuX2NvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpO1xuXG4gICAgICAgICAgdGhpcy5fY29udGFpbmVyLmNsYXNzTGlzdC5hZGQoXCJtYXJrZWRDb250ZW50XCIpO1xuXG4gICAgICAgICAgaWYgKGl0ZW1zW2ldLmlkICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9jb250YWluZXIuc2V0QXR0cmlidXRlKFwiaWRcIiwgYCR7aXRlbXNbaV0uaWR9YCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcGFyZW50LmFwcGVuZENoaWxkKHRoaXMuX2NvbnRhaW5lcik7XG4gICAgICAgIH0gZWxzZSBpZiAoaXRlbXNbaV0udHlwZSA9PT0gXCJlbmRNYXJrZWRDb250ZW50XCIpIHtcbiAgICAgICAgICB0aGlzLl9jb250YWluZXIgPSB0aGlzLl9jb250YWluZXIucGFyZW50Tm9kZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl90ZXh0Q29udGVudEl0ZW1zU3RyLnB1c2goaXRlbXNbaV0uc3RyKTtcblxuICAgICAgYXBwZW5kVGV4dCh0aGlzLCBpdGVtc1tpXSwgc3R5bGVDYWNoZSwgdGhpcy5fbGF5b3V0VGV4dEN0eCk7XG4gICAgfVxuICB9XG5cbiAgX2xheW91dFRleHQodGV4dERpdikge1xuICAgIGNvbnN0IHRleHREaXZQcm9wZXJ0aWVzID0gdGhpcy5fdGV4dERpdlByb3BlcnRpZXMuZ2V0KHRleHREaXYpO1xuXG4gICAgbGV0IHRyYW5zZm9ybSA9IFwiXCI7XG5cbiAgICBpZiAodGV4dERpdlByb3BlcnRpZXMuY2FudmFzV2lkdGggIT09IDAgJiYgdGV4dERpdlByb3BlcnRpZXMuaGFzVGV4dCkge1xuICAgICAgY29uc3Qge1xuICAgICAgICBmb250U2l6ZSxcbiAgICAgICAgZm9udEZhbWlseVxuICAgICAgfSA9IHRleHREaXYuc3R5bGU7XG5cbiAgICAgIGlmIChmb250U2l6ZSAhPT0gdGhpcy5fbGF5b3V0VGV4dExhc3RGb250U2l6ZSB8fCBmb250RmFtaWx5ICE9PSB0aGlzLl9sYXlvdXRUZXh0TGFzdEZvbnRGYW1pbHkpIHtcbiAgICAgICAgdGhpcy5fbGF5b3V0VGV4dEN0eC5mb250ID0gYCR7Zm9udFNpemV9ICR7Zm9udEZhbWlseX1gO1xuICAgICAgICB0aGlzLl9sYXlvdXRUZXh0TGFzdEZvbnRTaXplID0gZm9udFNpemU7XG4gICAgICAgIHRoaXMuX2xheW91dFRleHRMYXN0Rm9udEZhbWlseSA9IGZvbnRGYW1pbHk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHtcbiAgICAgICAgd2lkdGhcbiAgICAgIH0gPSB0aGlzLl9sYXlvdXRUZXh0Q3R4Lm1lYXN1cmVUZXh0KHRleHREaXYudGV4dENvbnRlbnQpO1xuXG4gICAgICBpZiAod2lkdGggPiAwKSB7XG4gICAgICAgIGNvbnN0IHNjYWxlID0gdGV4dERpdlByb3BlcnRpZXMuY2FudmFzV2lkdGggLyB3aWR0aDtcblxuICAgICAgICBpZiAodGhpcy5fZW5oYW5jZVRleHRTZWxlY3Rpb24pIHtcbiAgICAgICAgICB0ZXh0RGl2UHJvcGVydGllcy5zY2FsZSA9IHNjYWxlO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJhbnNmb3JtID0gYHNjYWxlWCgke3NjYWxlfSlgO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0ZXh0RGl2UHJvcGVydGllcy5hbmdsZSAhPT0gMCkge1xuICAgICAgdHJhbnNmb3JtID0gYHJvdGF0ZSgke3RleHREaXZQcm9wZXJ0aWVzLmFuZ2xlfWRlZykgJHt0cmFuc2Zvcm19YDtcbiAgICB9XG5cbiAgICBpZiAodHJhbnNmb3JtLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmICh0aGlzLl9lbmhhbmNlVGV4dFNlbGVjdGlvbikge1xuICAgICAgICB0ZXh0RGl2UHJvcGVydGllcy5vcmlnaW5hbFRyYW5zZm9ybSA9IHRyYW5zZm9ybTtcbiAgICAgIH1cblxuICAgICAgdGV4dERpdi5zdHlsZS50cmFuc2Zvcm0gPSB0cmFuc2Zvcm07XG4gICAgfVxuXG4gICAgaWYgKHRleHREaXZQcm9wZXJ0aWVzLmhhc1RleHQpIHtcbiAgICAgIHRoaXMuX2NvbnRhaW5lci5hcHBlbmRDaGlsZCh0ZXh0RGl2KTtcbiAgICB9XG5cbiAgICBpZiAodGV4dERpdlByb3BlcnRpZXMuaGFzRU9MKSB7XG4gICAgICBjb25zdCBiciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJiclwiKTtcbiAgICAgIGJyLnNldEF0dHJpYnV0ZShcInJvbGVcIiwgXCJwcmVzZW50YXRpb25cIik7XG5cbiAgICAgIHRoaXMuX2NvbnRhaW5lci5hcHBlbmRDaGlsZChicik7XG4gICAgfVxuICB9XG5cbiAgX3JlbmRlcih0aW1lb3V0ID0gMCkge1xuICAgIGNvbnN0IGNhcGFiaWxpdHkgPSAoMCwgX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkpKCk7XG4gICAgbGV0IHN0eWxlQ2FjaGUgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4gICAgY29uc3QgY2FudmFzID0gdGhpcy5fZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcblxuICAgIGNhbnZhcy5oZWlnaHQgPSBjYW52YXMud2lkdGggPSBERUZBVUxUX0ZPTlRfU0laRTtcbiAgICB0aGlzLl9sYXlvdXRUZXh0Q3R4ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiLCB7XG4gICAgICBhbHBoYTogZmFsc2VcbiAgICB9KTtcblxuICAgIGlmICh0aGlzLl90ZXh0Q29udGVudCkge1xuICAgICAgY29uc3QgdGV4dEl0ZW1zID0gdGhpcy5fdGV4dENvbnRlbnQuaXRlbXM7XG4gICAgICBjb25zdCB0ZXh0U3R5bGVzID0gdGhpcy5fdGV4dENvbnRlbnQuc3R5bGVzO1xuXG4gICAgICB0aGlzLl9wcm9jZXNzSXRlbXModGV4dEl0ZW1zLCB0ZXh0U3R5bGVzKTtcblxuICAgICAgY2FwYWJpbGl0eS5yZXNvbHZlKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLl90ZXh0Q29udGVudFN0cmVhbSkge1xuICAgICAgY29uc3QgcHVtcCA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5fcmVhZGVyLnJlYWQoKS50aGVuKCh7XG4gICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgZG9uZVxuICAgICAgICB9KSA9PiB7XG4gICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgIGNhcGFiaWxpdHkucmVzb2x2ZSgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIE9iamVjdC5hc3NpZ24oc3R5bGVDYWNoZSwgdmFsdWUuc3R5bGVzKTtcblxuICAgICAgICAgIHRoaXMuX3Byb2Nlc3NJdGVtcyh2YWx1ZS5pdGVtcywgc3R5bGVDYWNoZSk7XG5cbiAgICAgICAgICBwdW1wKCk7XG4gICAgICAgIH0sIGNhcGFiaWxpdHkucmVqZWN0KTtcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuX3JlYWRlciA9IHRoaXMuX3RleHRDb250ZW50U3RyZWFtLmdldFJlYWRlcigpO1xuICAgICAgcHVtcCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05laXRoZXIgXCJ0ZXh0Q29udGVudFwiIG5vciBcInRleHRDb250ZW50U3RyZWFtXCIgcGFyYW1ldGVycyBzcGVjaWZpZWQuJyk7XG4gICAgfVxuXG4gICAgY2FwYWJpbGl0eS5wcm9taXNlLnRoZW4oKCkgPT4ge1xuICAgICAgc3R5bGVDYWNoZSA9IG51bGw7XG5cbiAgICAgIGlmICghdGltZW91dCkge1xuICAgICAgICByZW5kZXIodGhpcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9yZW5kZXJUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHJlbmRlcih0aGlzKTtcbiAgICAgICAgICB0aGlzLl9yZW5kZXJUaW1lciA9IG51bGw7XG4gICAgICAgIH0sIHRpbWVvdXQpO1xuICAgICAgfVxuICAgIH0sIHRoaXMuX2NhcGFiaWxpdHkucmVqZWN0KTtcbiAgfVxuXG4gIGV4cGFuZFRleHREaXZzKGV4cGFuZERpdnMgPSBmYWxzZSkge1xuICAgIGlmICghdGhpcy5fZW5oYW5jZVRleHRTZWxlY3Rpb24gfHwgIXRoaXMuX3JlbmRlcmluZ0RvbmUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fYm91bmRzICE9PSBudWxsKSB7XG4gICAgICBleHBhbmQodGhpcyk7XG4gICAgICB0aGlzLl9ib3VuZHMgPSBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHRyYW5zZm9ybUJ1ZiA9IFtdLFxuICAgICAgICAgIHBhZGRpbmdCdWYgPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwLCBpaSA9IHRoaXMuX3RleHREaXZzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgIGNvbnN0IGRpdiA9IHRoaXMuX3RleHREaXZzW2ldO1xuXG4gICAgICBjb25zdCBkaXZQcm9wcyA9IHRoaXMuX3RleHREaXZQcm9wZXJ0aWVzLmdldChkaXYpO1xuXG4gICAgICBpZiAoIWRpdlByb3BzLmhhc1RleHQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChleHBhbmREaXZzKSB7XG4gICAgICAgIHRyYW5zZm9ybUJ1Zi5sZW5ndGggPSAwO1xuICAgICAgICBwYWRkaW5nQnVmLmxlbmd0aCA9IDA7XG5cbiAgICAgICAgaWYgKGRpdlByb3BzLm9yaWdpbmFsVHJhbnNmb3JtKSB7XG4gICAgICAgICAgdHJhbnNmb3JtQnVmLnB1c2goZGl2UHJvcHMub3JpZ2luYWxUcmFuc2Zvcm0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRpdlByb3BzLnBhZGRpbmdUb3AgPiAwKSB7XG4gICAgICAgICAgcGFkZGluZ0J1Zi5wdXNoKGAke2RpdlByb3BzLnBhZGRpbmdUb3B9cHhgKTtcbiAgICAgICAgICB0cmFuc2Zvcm1CdWYucHVzaChgdHJhbnNsYXRlWSgkey1kaXZQcm9wcy5wYWRkaW5nVG9wfXB4KWApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBhZGRpbmdCdWYucHVzaCgwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkaXZQcm9wcy5wYWRkaW5nUmlnaHQgPiAwKSB7XG4gICAgICAgICAgcGFkZGluZ0J1Zi5wdXNoKGAke2RpdlByb3BzLnBhZGRpbmdSaWdodCAvIGRpdlByb3BzLnNjYWxlfXB4YCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcGFkZGluZ0J1Zi5wdXNoKDApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRpdlByb3BzLnBhZGRpbmdCb3R0b20gPiAwKSB7XG4gICAgICAgICAgcGFkZGluZ0J1Zi5wdXNoKGAke2RpdlByb3BzLnBhZGRpbmdCb3R0b219cHhgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwYWRkaW5nQnVmLnB1c2goMCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZGl2UHJvcHMucGFkZGluZ0xlZnQgPiAwKSB7XG4gICAgICAgICAgcGFkZGluZ0J1Zi5wdXNoKGAke2RpdlByb3BzLnBhZGRpbmdMZWZ0IC8gZGl2UHJvcHMuc2NhbGV9cHhgKTtcbiAgICAgICAgICB0cmFuc2Zvcm1CdWYucHVzaChgdHJhbnNsYXRlWCgkey1kaXZQcm9wcy5wYWRkaW5nTGVmdCAvIGRpdlByb3BzLnNjYWxlfXB4KWApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBhZGRpbmdCdWYucHVzaCgwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRpdi5zdHlsZS5wYWRkaW5nID0gcGFkZGluZ0J1Zi5qb2luKFwiIFwiKTtcblxuICAgICAgICBpZiAodHJhbnNmb3JtQnVmLmxlbmd0aCkge1xuICAgICAgICAgIGRpdi5zdHlsZS50cmFuc2Zvcm0gPSB0cmFuc2Zvcm1CdWYuam9pbihcIiBcIik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRpdi5zdHlsZS5wYWRkaW5nID0gbnVsbDtcbiAgICAgICAgZGl2LnN0eWxlLnRyYW5zZm9ybSA9IGRpdlByb3BzLm9yaWdpbmFsVHJhbnNmb3JtO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG59XG5cbmZ1bmN0aW9uIHJlbmRlclRleHRMYXllcihyZW5kZXJQYXJhbWV0ZXJzKSB7XG4gIGNvbnN0IHRhc2sgPSBuZXcgVGV4dExheWVyUmVuZGVyVGFzayh7XG4gICAgdGV4dENvbnRlbnQ6IHJlbmRlclBhcmFtZXRlcnMudGV4dENvbnRlbnQsXG4gICAgdGV4dENvbnRlbnRTdHJlYW06IHJlbmRlclBhcmFtZXRlcnMudGV4dENvbnRlbnRTdHJlYW0sXG4gICAgY29udGFpbmVyOiByZW5kZXJQYXJhbWV0ZXJzLmNvbnRhaW5lcixcbiAgICB2aWV3cG9ydDogcmVuZGVyUGFyYW1ldGVycy52aWV3cG9ydCxcbiAgICB0ZXh0RGl2czogcmVuZGVyUGFyYW1ldGVycy50ZXh0RGl2cyxcbiAgICB0ZXh0Q29udGVudEl0ZW1zU3RyOiByZW5kZXJQYXJhbWV0ZXJzLnRleHRDb250ZW50SXRlbXNTdHIsXG4gICAgZW5oYW5jZVRleHRTZWxlY3Rpb246IHJlbmRlclBhcmFtZXRlcnMuZW5oYW5jZVRleHRTZWxlY3Rpb25cbiAgfSk7XG5cbiAgdGFzay5fcmVuZGVyKHJlbmRlclBhcmFtZXRlcnMudGltZW91dCk7XG5cbiAgcmV0dXJuIHRhc2s7XG59XG5cbi8qKiovIH0pLFxuLyogMjQgKi9cbi8qKiovICgoX191bnVzZWRfd2VicGFja19tb2R1bGUsIGV4cG9ydHMsIF9fd19wZGZqc19yZXF1aXJlX18pID0+IHtcblxuXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgKHtcbiAgdmFsdWU6IHRydWVcbn0pKTtcbmV4cG9ydHMuU1ZHR3JhcGhpY3MgPSB2b2lkIDA7XG5cbnZhciBfdXRpbCA9IF9fd19wZGZqc19yZXF1aXJlX18oMSk7XG5cbnZhciBfZGlzcGxheV91dGlscyA9IF9fd19wZGZqc19yZXF1aXJlX18oNSk7XG5cbnZhciBfaXNfbm9kZSA9IF9fd19wZGZqc19yZXF1aXJlX18oMyk7XG5cbmxldCBTVkdHcmFwaGljcyA9IGNsYXNzIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgKDAsIF91dGlsLnVucmVhY2hhYmxlKShcIk5vdCBpbXBsZW1lbnRlZDogU1ZHR3JhcGhpY3NcIik7XG4gIH1cblxufTtcbmV4cG9ydHMuU1ZHR3JhcGhpY3MgPSBTVkdHcmFwaGljcztcbntcbiAgY29uc3QgU1ZHX0RFRkFVTFRTID0ge1xuICAgIGZvbnRTdHlsZTogXCJub3JtYWxcIixcbiAgICBmb250V2VpZ2h0OiBcIm5vcm1hbFwiLFxuICAgIGZpbGxDb2xvcjogXCIjMDAwMDAwXCJcbiAgfTtcbiAgY29uc3QgWE1MX05TID0gXCJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2VcIjtcbiAgY29uc3QgWExJTktfTlMgPSBcImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIjtcbiAgY29uc3QgTElORV9DQVBfU1RZTEVTID0gW1wiYnV0dFwiLCBcInJvdW5kXCIsIFwic3F1YXJlXCJdO1xuICBjb25zdCBMSU5FX0pPSU5fU1RZTEVTID0gW1wibWl0ZXJcIiwgXCJyb3VuZFwiLCBcImJldmVsXCJdO1xuXG4gIGNvbnN0IGNyZWF0ZU9iamVjdFVSTCA9IGZ1bmN0aW9uIChkYXRhLCBjb250ZW50VHlwZSA9IFwiXCIsIGZvcmNlRGF0YVNjaGVtYSA9IGZhbHNlKSB7XG4gICAgaWYgKFVSTC5jcmVhdGVPYmplY3RVUkwgJiYgdHlwZW9mIEJsb2IgIT09IFwidW5kZWZpbmVkXCIgJiYgIWZvcmNlRGF0YVNjaGVtYSkge1xuICAgICAgcmV0dXJuIFVSTC5jcmVhdGVPYmplY3RVUkwobmV3IEJsb2IoW2RhdGFdLCB7XG4gICAgICAgIHR5cGU6IGNvbnRlbnRUeXBlXG4gICAgICB9KSk7XG4gICAgfVxuXG4gICAgY29uc3QgZGlnaXRzID0gXCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPVwiO1xuICAgIGxldCBidWZmZXIgPSBgZGF0YToke2NvbnRlbnRUeXBlfTtiYXNlNjQsYDtcblxuICAgIGZvciAobGV0IGkgPSAwLCBpaSA9IGRhdGEubGVuZ3RoOyBpIDwgaWk7IGkgKz0gMykge1xuICAgICAgY29uc3QgYjEgPSBkYXRhW2ldICYgMHhmZjtcbiAgICAgIGNvbnN0IGIyID0gZGF0YVtpICsgMV0gJiAweGZmO1xuICAgICAgY29uc3QgYjMgPSBkYXRhW2kgKyAyXSAmIDB4ZmY7XG4gICAgICBjb25zdCBkMSA9IGIxID4+IDIsXG4gICAgICAgICAgICBkMiA9IChiMSAmIDMpIDw8IDQgfCBiMiA+PiA0O1xuICAgICAgY29uc3QgZDMgPSBpICsgMSA8IGlpID8gKGIyICYgMHhmKSA8PCAyIHwgYjMgPj4gNiA6IDY0O1xuICAgICAgY29uc3QgZDQgPSBpICsgMiA8IGlpID8gYjMgJiAweDNmIDogNjQ7XG4gICAgICBidWZmZXIgKz0gZGlnaXRzW2QxXSArIGRpZ2l0c1tkMl0gKyBkaWdpdHNbZDNdICsgZGlnaXRzW2Q0XTtcbiAgICB9XG5cbiAgICByZXR1cm4gYnVmZmVyO1xuICB9O1xuXG4gIGNvbnN0IGNvbnZlcnRJbWdEYXRhVG9QbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgUE5HX0hFQURFUiA9IG5ldyBVaW50OEFycmF5KFsweDg5LCAweDUwLCAweDRlLCAweDQ3LCAweDBkLCAweDBhLCAweDFhLCAweDBhXSk7XG4gICAgY29uc3QgQ0hVTktfV1JBUFBFUl9TSVpFID0gMTI7XG4gICAgY29uc3QgY3JjVGFibGUgPSBuZXcgSW50MzJBcnJheSgyNTYpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICAgICAgbGV0IGMgPSBpO1xuXG4gICAgICBmb3IgKGxldCBoID0gMDsgaCA8IDg7IGgrKykge1xuICAgICAgICBpZiAoYyAmIDEpIHtcbiAgICAgICAgICBjID0gMHhlZGI4ODMyMCBeIGMgPj4gMSAmIDB4N2ZmZmZmZmY7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYyA9IGMgPj4gMSAmIDB4N2ZmZmZmZmY7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY3JjVGFibGVbaV0gPSBjO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNyYzMyKGRhdGEsIHN0YXJ0LCBlbmQpIHtcbiAgICAgIGxldCBjcmMgPSAtMTtcblxuICAgICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICAgICAgY29uc3QgYSA9IChjcmMgXiBkYXRhW2ldKSAmIDB4ZmY7XG4gICAgICAgIGNvbnN0IGIgPSBjcmNUYWJsZVthXTtcbiAgICAgICAgY3JjID0gY3JjID4+PiA4IF4gYjtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNyYyBeIC0xO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHdyaXRlUG5nQ2h1bmsodHlwZSwgYm9keSwgZGF0YSwgb2Zmc2V0KSB7XG4gICAgICBsZXQgcCA9IG9mZnNldDtcbiAgICAgIGNvbnN0IGxlbiA9IGJvZHkubGVuZ3RoO1xuICAgICAgZGF0YVtwXSA9IGxlbiA+PiAyNCAmIDB4ZmY7XG4gICAgICBkYXRhW3AgKyAxXSA9IGxlbiA+PiAxNiAmIDB4ZmY7XG4gICAgICBkYXRhW3AgKyAyXSA9IGxlbiA+PiA4ICYgMHhmZjtcbiAgICAgIGRhdGFbcCArIDNdID0gbGVuICYgMHhmZjtcbiAgICAgIHAgKz0gNDtcbiAgICAgIGRhdGFbcF0gPSB0eXBlLmNoYXJDb2RlQXQoMCkgJiAweGZmO1xuICAgICAgZGF0YVtwICsgMV0gPSB0eXBlLmNoYXJDb2RlQXQoMSkgJiAweGZmO1xuICAgICAgZGF0YVtwICsgMl0gPSB0eXBlLmNoYXJDb2RlQXQoMikgJiAweGZmO1xuICAgICAgZGF0YVtwICsgM10gPSB0eXBlLmNoYXJDb2RlQXQoMykgJiAweGZmO1xuICAgICAgcCArPSA0O1xuICAgICAgZGF0YS5zZXQoYm9keSwgcCk7XG4gICAgICBwICs9IGJvZHkubGVuZ3RoO1xuICAgICAgY29uc3QgY3JjID0gY3JjMzIoZGF0YSwgb2Zmc2V0ICsgNCwgcCk7XG4gICAgICBkYXRhW3BdID0gY3JjID4+IDI0ICYgMHhmZjtcbiAgICAgIGRhdGFbcCArIDFdID0gY3JjID4+IDE2ICYgMHhmZjtcbiAgICAgIGRhdGFbcCArIDJdID0gY3JjID4+IDggJiAweGZmO1xuICAgICAgZGF0YVtwICsgM10gPSBjcmMgJiAweGZmO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkbGVyMzIoZGF0YSwgc3RhcnQsIGVuZCkge1xuICAgICAgbGV0IGEgPSAxO1xuICAgICAgbGV0IGIgPSAwO1xuXG4gICAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgICAgICBhID0gKGEgKyAoZGF0YVtpXSAmIDB4ZmYpKSAlIDY1NTIxO1xuICAgICAgICBiID0gKGIgKyBhKSAlIDY1NTIxO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYiA8PCAxNiB8IGE7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGVmbGF0ZVN5bmMobGl0ZXJhbHMpIHtcbiAgICAgIGlmICghX2lzX25vZGUuaXNOb2RlSlMpIHtcbiAgICAgICAgcmV0dXJuIGRlZmxhdGVTeW5jVW5jb21wcmVzc2VkKGxpdGVyYWxzKTtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgbGV0IGlucHV0O1xuXG4gICAgICAgIGlmIChwYXJzZUludChwcm9jZXNzLnZlcnNpb25zLm5vZGUpID49IDgpIHtcbiAgICAgICAgICBpbnB1dCA9IGxpdGVyYWxzO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlucHV0ID0gQnVmZmVyLmZyb20obGl0ZXJhbHMpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgb3V0cHV0ID0gcmVxdWlyZShcInpsaWJcIikuZGVmbGF0ZVN5bmMoaW5wdXQsIHtcbiAgICAgICAgICBsZXZlbDogOVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gb3V0cHV0IGluc3RhbmNlb2YgVWludDhBcnJheSA/IG91dHB1dCA6IG5ldyBVaW50OEFycmF5KG91dHB1dCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICgwLCBfdXRpbC53YXJuKShcIk5vdCBjb21wcmVzc2luZyBQTkcgYmVjYXVzZSB6bGliLmRlZmxhdGVTeW5jIGlzIHVuYXZhaWxhYmxlOiBcIiArIGUpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZGVmbGF0ZVN5bmNVbmNvbXByZXNzZWQobGl0ZXJhbHMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRlZmxhdGVTeW5jVW5jb21wcmVzc2VkKGxpdGVyYWxzKSB7XG4gICAgICBsZXQgbGVuID0gbGl0ZXJhbHMubGVuZ3RoO1xuICAgICAgY29uc3QgbWF4QmxvY2tMZW5ndGggPSAweGZmZmY7XG4gICAgICBjb25zdCBkZWZsYXRlQmxvY2tzID0gTWF0aC5jZWlsKGxlbiAvIG1heEJsb2NrTGVuZ3RoKTtcbiAgICAgIGNvbnN0IGlkYXQgPSBuZXcgVWludDhBcnJheSgyICsgbGVuICsgZGVmbGF0ZUJsb2NrcyAqIDUgKyA0KTtcbiAgICAgIGxldCBwaSA9IDA7XG4gICAgICBpZGF0W3BpKytdID0gMHg3ODtcbiAgICAgIGlkYXRbcGkrK10gPSAweDljO1xuICAgICAgbGV0IHBvcyA9IDA7XG5cbiAgICAgIHdoaWxlIChsZW4gPiBtYXhCbG9ja0xlbmd0aCkge1xuICAgICAgICBpZGF0W3BpKytdID0gMHgwMDtcbiAgICAgICAgaWRhdFtwaSsrXSA9IDB4ZmY7XG4gICAgICAgIGlkYXRbcGkrK10gPSAweGZmO1xuICAgICAgICBpZGF0W3BpKytdID0gMHgwMDtcbiAgICAgICAgaWRhdFtwaSsrXSA9IDB4MDA7XG4gICAgICAgIGlkYXQuc2V0KGxpdGVyYWxzLnN1YmFycmF5KHBvcywgcG9zICsgbWF4QmxvY2tMZW5ndGgpLCBwaSk7XG4gICAgICAgIHBpICs9IG1heEJsb2NrTGVuZ3RoO1xuICAgICAgICBwb3MgKz0gbWF4QmxvY2tMZW5ndGg7XG4gICAgICAgIGxlbiAtPSBtYXhCbG9ja0xlbmd0aDtcbiAgICAgIH1cblxuICAgICAgaWRhdFtwaSsrXSA9IDB4MDE7XG4gICAgICBpZGF0W3BpKytdID0gbGVuICYgMHhmZjtcbiAgICAgIGlkYXRbcGkrK10gPSBsZW4gPj4gOCAmIDB4ZmY7XG4gICAgICBpZGF0W3BpKytdID0gfmxlbiAmIDB4ZmZmZiAmIDB4ZmY7XG4gICAgICBpZGF0W3BpKytdID0gKH5sZW4gJiAweGZmZmYpID4+IDggJiAweGZmO1xuICAgICAgaWRhdC5zZXQobGl0ZXJhbHMuc3ViYXJyYXkocG9zKSwgcGkpO1xuICAgICAgcGkgKz0gbGl0ZXJhbHMubGVuZ3RoIC0gcG9zO1xuICAgICAgY29uc3QgYWRsZXIgPSBhZGxlcjMyKGxpdGVyYWxzLCAwLCBsaXRlcmFscy5sZW5ndGgpO1xuICAgICAgaWRhdFtwaSsrXSA9IGFkbGVyID4+IDI0ICYgMHhmZjtcbiAgICAgIGlkYXRbcGkrK10gPSBhZGxlciA+PiAxNiAmIDB4ZmY7XG4gICAgICBpZGF0W3BpKytdID0gYWRsZXIgPj4gOCAmIDB4ZmY7XG4gICAgICBpZGF0W3BpKytdID0gYWRsZXIgJiAweGZmO1xuICAgICAgcmV0dXJuIGlkYXQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZW5jb2RlKGltZ0RhdGEsIGtpbmQsIGZvcmNlRGF0YVNjaGVtYSwgaXNNYXNrKSB7XG4gICAgICBjb25zdCB3aWR0aCA9IGltZ0RhdGEud2lkdGg7XG4gICAgICBjb25zdCBoZWlnaHQgPSBpbWdEYXRhLmhlaWdodDtcbiAgICAgIGxldCBiaXREZXB0aCwgY29sb3JUeXBlLCBsaW5lU2l6ZTtcbiAgICAgIGNvbnN0IGJ5dGVzID0gaW1nRGF0YS5kYXRhO1xuXG4gICAgICBzd2l0Y2ggKGtpbmQpIHtcbiAgICAgICAgY2FzZSBfdXRpbC5JbWFnZUtpbmQuR1JBWVNDQUxFXzFCUFA6XG4gICAgICAgICAgY29sb3JUeXBlID0gMDtcbiAgICAgICAgICBiaXREZXB0aCA9IDE7XG4gICAgICAgICAgbGluZVNpemUgPSB3aWR0aCArIDcgPj4gMztcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIF91dGlsLkltYWdlS2luZC5SR0JfMjRCUFA6XG4gICAgICAgICAgY29sb3JUeXBlID0gMjtcbiAgICAgICAgICBiaXREZXB0aCA9IDg7XG4gICAgICAgICAgbGluZVNpemUgPSB3aWR0aCAqIDM7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBfdXRpbC5JbWFnZUtpbmQuUkdCQV8zMkJQUDpcbiAgICAgICAgICBjb2xvclR5cGUgPSA2O1xuICAgICAgICAgIGJpdERlcHRoID0gODtcbiAgICAgICAgICBsaW5lU2l6ZSA9IHdpZHRoICogNDtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgZm9ybWF0XCIpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBsaXRlcmFscyA9IG5ldyBVaW50OEFycmF5KCgxICsgbGluZVNpemUpICogaGVpZ2h0KTtcbiAgICAgIGxldCBvZmZzZXRMaXRlcmFscyA9IDAsXG4gICAgICAgICAgb2Zmc2V0Qnl0ZXMgPSAwO1xuXG4gICAgICBmb3IgKGxldCB5ID0gMDsgeSA8IGhlaWdodDsgKyt5KSB7XG4gICAgICAgIGxpdGVyYWxzW29mZnNldExpdGVyYWxzKytdID0gMDtcbiAgICAgICAgbGl0ZXJhbHMuc2V0KGJ5dGVzLnN1YmFycmF5KG9mZnNldEJ5dGVzLCBvZmZzZXRCeXRlcyArIGxpbmVTaXplKSwgb2Zmc2V0TGl0ZXJhbHMpO1xuICAgICAgICBvZmZzZXRCeXRlcyArPSBsaW5lU2l6ZTtcbiAgICAgICAgb2Zmc2V0TGl0ZXJhbHMgKz0gbGluZVNpemU7XG4gICAgICB9XG5cbiAgICAgIGlmIChraW5kID09PSBfdXRpbC5JbWFnZUtpbmQuR1JBWVNDQUxFXzFCUFAgJiYgaXNNYXNrKSB7XG4gICAgICAgIG9mZnNldExpdGVyYWxzID0gMDtcblxuICAgICAgICBmb3IgKGxldCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7XG4gICAgICAgICAgb2Zmc2V0TGl0ZXJhbHMrKztcblxuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZVNpemU7IGkrKykge1xuICAgICAgICAgICAgbGl0ZXJhbHNbb2Zmc2V0TGl0ZXJhbHMrK10gXj0gMHhmZjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgaWhkciA9IG5ldyBVaW50OEFycmF5KFt3aWR0aCA+PiAyNCAmIDB4ZmYsIHdpZHRoID4+IDE2ICYgMHhmZiwgd2lkdGggPj4gOCAmIDB4ZmYsIHdpZHRoICYgMHhmZiwgaGVpZ2h0ID4+IDI0ICYgMHhmZiwgaGVpZ2h0ID4+IDE2ICYgMHhmZiwgaGVpZ2h0ID4+IDggJiAweGZmLCBoZWlnaHQgJiAweGZmLCBiaXREZXB0aCwgY29sb3JUeXBlLCAweDAwLCAweDAwLCAweDAwXSk7XG4gICAgICBjb25zdCBpZGF0ID0gZGVmbGF0ZVN5bmMobGl0ZXJhbHMpO1xuICAgICAgY29uc3QgcG5nTGVuZ3RoID0gUE5HX0hFQURFUi5sZW5ndGggKyBDSFVOS19XUkFQUEVSX1NJWkUgKiAzICsgaWhkci5sZW5ndGggKyBpZGF0Lmxlbmd0aDtcbiAgICAgIGNvbnN0IGRhdGEgPSBuZXcgVWludDhBcnJheShwbmdMZW5ndGgpO1xuICAgICAgbGV0IG9mZnNldCA9IDA7XG4gICAgICBkYXRhLnNldChQTkdfSEVBREVSLCBvZmZzZXQpO1xuICAgICAgb2Zmc2V0ICs9IFBOR19IRUFERVIubGVuZ3RoO1xuICAgICAgd3JpdGVQbmdDaHVuayhcIklIRFJcIiwgaWhkciwgZGF0YSwgb2Zmc2V0KTtcbiAgICAgIG9mZnNldCArPSBDSFVOS19XUkFQUEVSX1NJWkUgKyBpaGRyLmxlbmd0aDtcbiAgICAgIHdyaXRlUG5nQ2h1bmsoXCJJREFUQVwiLCBpZGF0LCBkYXRhLCBvZmZzZXQpO1xuICAgICAgb2Zmc2V0ICs9IENIVU5LX1dSQVBQRVJfU0laRSArIGlkYXQubGVuZ3RoO1xuICAgICAgd3JpdGVQbmdDaHVuayhcIklFTkRcIiwgbmV3IFVpbnQ4QXJyYXkoMCksIGRhdGEsIG9mZnNldCk7XG4gICAgICByZXR1cm4gY3JlYXRlT2JqZWN0VVJMKGRhdGEsIFwiaW1hZ2UvcG5nXCIsIGZvcmNlRGF0YVNjaGVtYSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIGNvbnZlcnRJbWdEYXRhVG9QbmcoaW1nRGF0YSwgZm9yY2VEYXRhU2NoZW1hLCBpc01hc2spIHtcbiAgICAgIGNvbnN0IGtpbmQgPSBpbWdEYXRhLmtpbmQgPT09IHVuZGVmaW5lZCA/IF91dGlsLkltYWdlS2luZC5HUkFZU0NBTEVfMUJQUCA6IGltZ0RhdGEua2luZDtcbiAgICAgIHJldHVybiBlbmNvZGUoaW1nRGF0YSwga2luZCwgZm9yY2VEYXRhU2NoZW1hLCBpc01hc2spO1xuICAgIH07XG4gIH0oKTtcblxuICBjbGFzcyBTVkdFeHRyYVN0YXRlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgIHRoaXMuZm9udFNpemVTY2FsZSA9IDE7XG4gICAgICB0aGlzLmZvbnRXZWlnaHQgPSBTVkdfREVGQVVMVFMuZm9udFdlaWdodDtcbiAgICAgIHRoaXMuZm9udFNpemUgPSAwO1xuICAgICAgdGhpcy50ZXh0TWF0cml4ID0gX3V0aWwuSURFTlRJVFlfTUFUUklYO1xuICAgICAgdGhpcy5mb250TWF0cml4ID0gX3V0aWwuRk9OVF9JREVOVElUWV9NQVRSSVg7XG4gICAgICB0aGlzLmxlYWRpbmcgPSAwO1xuICAgICAgdGhpcy50ZXh0UmVuZGVyaW5nTW9kZSA9IF91dGlsLlRleHRSZW5kZXJpbmdNb2RlLkZJTEw7XG4gICAgICB0aGlzLnRleHRNYXRyaXhTY2FsZSA9IDE7XG4gICAgICB0aGlzLnggPSAwO1xuICAgICAgdGhpcy55ID0gMDtcbiAgICAgIHRoaXMubGluZVggPSAwO1xuICAgICAgdGhpcy5saW5lWSA9IDA7XG4gICAgICB0aGlzLmNoYXJTcGFjaW5nID0gMDtcbiAgICAgIHRoaXMud29yZFNwYWNpbmcgPSAwO1xuICAgICAgdGhpcy50ZXh0SFNjYWxlID0gMTtcbiAgICAgIHRoaXMudGV4dFJpc2UgPSAwO1xuICAgICAgdGhpcy5maWxsQ29sb3IgPSBTVkdfREVGQVVMVFMuZmlsbENvbG9yO1xuICAgICAgdGhpcy5zdHJva2VDb2xvciA9IFwiIzAwMDAwMFwiO1xuICAgICAgdGhpcy5maWxsQWxwaGEgPSAxO1xuICAgICAgdGhpcy5zdHJva2VBbHBoYSA9IDE7XG4gICAgICB0aGlzLmxpbmVXaWR0aCA9IDE7XG4gICAgICB0aGlzLmxpbmVKb2luID0gXCJcIjtcbiAgICAgIHRoaXMubGluZUNhcCA9IFwiXCI7XG4gICAgICB0aGlzLm1pdGVyTGltaXQgPSAwO1xuICAgICAgdGhpcy5kYXNoQXJyYXkgPSBbXTtcbiAgICAgIHRoaXMuZGFzaFBoYXNlID0gMDtcbiAgICAgIHRoaXMuZGVwZW5kZW5jaWVzID0gW107XG4gICAgICB0aGlzLmFjdGl2ZUNsaXBVcmwgPSBudWxsO1xuICAgICAgdGhpcy5jbGlwR3JvdXAgPSBudWxsO1xuICAgICAgdGhpcy5tYXNrSWQgPSBcIlwiO1xuICAgIH1cblxuICAgIGNsb25lKCkge1xuICAgICAgcmV0dXJuIE9iamVjdC5jcmVhdGUodGhpcyk7XG4gICAgfVxuXG4gICAgc2V0Q3VycmVudFBvaW50KHgsIHkpIHtcbiAgICAgIHRoaXMueCA9IHg7XG4gICAgICB0aGlzLnkgPSB5O1xuICAgIH1cblxuICB9XG5cbiAgZnVuY3Rpb24gb3BMaXN0VG9UcmVlKG9wTGlzdCkge1xuICAgIGxldCBvcFRyZWUgPSBbXTtcbiAgICBjb25zdCB0bXAgPSBbXTtcblxuICAgIGZvciAoY29uc3Qgb3BMaXN0RWxlbWVudCBvZiBvcExpc3QpIHtcbiAgICAgIGlmIChvcExpc3RFbGVtZW50LmZuID09PSBcInNhdmVcIikge1xuICAgICAgICBvcFRyZWUucHVzaCh7XG4gICAgICAgICAgZm5JZDogOTIsXG4gICAgICAgICAgZm46IFwiZ3JvdXBcIixcbiAgICAgICAgICBpdGVtczogW11cbiAgICAgICAgfSk7XG4gICAgICAgIHRtcC5wdXNoKG9wVHJlZSk7XG4gICAgICAgIG9wVHJlZSA9IG9wVHJlZVtvcFRyZWUubGVuZ3RoIC0gMV0uaXRlbXM7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAob3BMaXN0RWxlbWVudC5mbiA9PT0gXCJyZXN0b3JlXCIpIHtcbiAgICAgICAgb3BUcmVlID0gdG1wLnBvcCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3BUcmVlLnB1c2gob3BMaXN0RWxlbWVudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG9wVHJlZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBmKHZhbHVlKSB7XG4gICAgaWYgKE51bWJlci5pc0ludGVnZXIodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWUudG9TdHJpbmcoKTtcbiAgICB9XG5cbiAgICBjb25zdCBzID0gdmFsdWUudG9GaXhlZCgxMCk7XG4gICAgbGV0IGkgPSBzLmxlbmd0aCAtIDE7XG5cbiAgICBpZiAoc1tpXSAhPT0gXCIwXCIpIHtcbiAgICAgIHJldHVybiBzO1xuICAgIH1cblxuICAgIGRvIHtcbiAgICAgIGktLTtcbiAgICB9IHdoaWxlIChzW2ldID09PSBcIjBcIik7XG5cbiAgICByZXR1cm4gcy5zdWJzdHJpbmcoMCwgc1tpXSA9PT0gXCIuXCIgPyBpIDogaSArIDEpO1xuICB9XG5cbiAgZnVuY3Rpb24gcG0obSkge1xuICAgIGlmIChtWzRdID09PSAwICYmIG1bNV0gPT09IDApIHtcbiAgICAgIGlmIChtWzFdID09PSAwICYmIG1bMl0gPT09IDApIHtcbiAgICAgICAgaWYgKG1bMF0gPT09IDEgJiYgbVszXSA9PT0gMSkge1xuICAgICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGBzY2FsZSgke3BmKG1bMF0pfSAke3BmKG1bM10pfSlgO1xuICAgICAgfVxuXG4gICAgICBpZiAobVswXSA9PT0gbVszXSAmJiBtWzFdID09PSAtbVsyXSkge1xuICAgICAgICBjb25zdCBhID0gTWF0aC5hY29zKG1bMF0pICogMTgwIC8gTWF0aC5QSTtcbiAgICAgICAgcmV0dXJuIGByb3RhdGUoJHtwZihhKX0pYDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKG1bMF0gPT09IDEgJiYgbVsxXSA9PT0gMCAmJiBtWzJdID09PSAwICYmIG1bM10gPT09IDEpIHtcbiAgICAgICAgcmV0dXJuIGB0cmFuc2xhdGUoJHtwZihtWzRdKX0gJHtwZihtWzVdKX0pYDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gYG1hdHJpeCgke3BmKG1bMF0pfSAke3BmKG1bMV0pfSAke3BmKG1bMl0pfSAke3BmKG1bM10pfSAke3BmKG1bNF0pfSBgICsgYCR7cGYobVs1XSl9KWA7XG4gIH1cblxuICBsZXQgY2xpcENvdW50ID0gMDtcbiAgbGV0IG1hc2tDb3VudCA9IDA7XG4gIGxldCBzaGFkaW5nQ291bnQgPSAwO1xuICBleHBvcnRzLlNWR0dyYXBoaWNzID0gU1ZHR3JhcGhpY3MgPSBjbGFzcyB7XG4gICAgY29uc3RydWN0b3IoY29tbW9uT2Jqcywgb2JqcywgZm9yY2VEYXRhU2NoZW1hID0gZmFsc2UpIHtcbiAgICAgIHRoaXMuc3ZnRmFjdG9yeSA9IG5ldyBfZGlzcGxheV91dGlscy5ET01TVkdGYWN0b3J5KCk7XG4gICAgICB0aGlzLmN1cnJlbnQgPSBuZXcgU1ZHRXh0cmFTdGF0ZSgpO1xuICAgICAgdGhpcy50cmFuc2Zvcm1NYXRyaXggPSBfdXRpbC5JREVOVElUWV9NQVRSSVg7XG4gICAgICB0aGlzLnRyYW5zZm9ybVN0YWNrID0gW107XG4gICAgICB0aGlzLmV4dHJhU3RhY2sgPSBbXTtcbiAgICAgIHRoaXMuY29tbW9uT2JqcyA9IGNvbW1vbk9ianM7XG4gICAgICB0aGlzLm9ianMgPSBvYmpzO1xuICAgICAgdGhpcy5wZW5kaW5nQ2xpcCA9IG51bGw7XG4gICAgICB0aGlzLnBlbmRpbmdFT0ZpbGwgPSBmYWxzZTtcbiAgICAgIHRoaXMuZW1iZWRGb250cyA9IGZhbHNlO1xuICAgICAgdGhpcy5lbWJlZGRlZEZvbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgIHRoaXMuY3NzU3R5bGUgPSBudWxsO1xuICAgICAgdGhpcy5mb3JjZURhdGFTY2hlbWEgPSAhIWZvcmNlRGF0YVNjaGVtYTtcbiAgICAgIHRoaXMuX29wZXJhdG9ySWRNYXBwaW5nID0gW107XG5cbiAgICAgIGZvciAoY29uc3Qgb3AgaW4gX3V0aWwuT1BTKSB7XG4gICAgICAgIHRoaXMuX29wZXJhdG9ySWRNYXBwaW5nW191dGlsLk9QU1tvcF1dID0gb3A7XG4gICAgICB9XG4gICAgfVxuXG4gICAgc2F2ZSgpIHtcbiAgICAgIHRoaXMudHJhbnNmb3JtU3RhY2sucHVzaCh0aGlzLnRyYW5zZm9ybU1hdHJpeCk7XG4gICAgICBjb25zdCBvbGQgPSB0aGlzLmN1cnJlbnQ7XG4gICAgICB0aGlzLmV4dHJhU3RhY2sucHVzaChvbGQpO1xuICAgICAgdGhpcy5jdXJyZW50ID0gb2xkLmNsb25lKCk7XG4gICAgfVxuXG4gICAgcmVzdG9yZSgpIHtcbiAgICAgIHRoaXMudHJhbnNmb3JtTWF0cml4ID0gdGhpcy50cmFuc2Zvcm1TdGFjay5wb3AoKTtcbiAgICAgIHRoaXMuY3VycmVudCA9IHRoaXMuZXh0cmFTdGFjay5wb3AoKTtcbiAgICAgIHRoaXMucGVuZGluZ0NsaXAgPSBudWxsO1xuICAgICAgdGhpcy50Z3JwID0gbnVsbDtcbiAgICB9XG5cbiAgICBncm91cChpdGVtcykge1xuICAgICAgdGhpcy5zYXZlKCk7XG4gICAgICB0aGlzLmV4ZWN1dGVPcFRyZWUoaXRlbXMpO1xuICAgICAgdGhpcy5yZXN0b3JlKCk7XG4gICAgfVxuXG4gICAgbG9hZERlcGVuZGVuY2llcyhvcGVyYXRvckxpc3QpIHtcbiAgICAgIGNvbnN0IGZuQXJyYXkgPSBvcGVyYXRvckxpc3QuZm5BcnJheTtcbiAgICAgIGNvbnN0IGFyZ3NBcnJheSA9IG9wZXJhdG9yTGlzdC5hcmdzQXJyYXk7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwLCBpaSA9IGZuQXJyYXkubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICBpZiAoZm5BcnJheVtpXSAhPT0gX3V0aWwuT1BTLmRlcGVuZGVuY3kpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3Qgb2JqIG9mIGFyZ3NBcnJheVtpXSkge1xuICAgICAgICAgIGNvbnN0IG9ianNQb29sID0gb2JqLnN0YXJ0c1dpdGgoXCJnX1wiKSA/IHRoaXMuY29tbW9uT2JqcyA6IHRoaXMub2JqcztcbiAgICAgICAgICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgICBvYmpzUG9vbC5nZXQob2JqLCByZXNvbHZlKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB0aGlzLmN1cnJlbnQuZGVwZW5kZW5jaWVzLnB1c2gocHJvbWlzZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHRoaXMuY3VycmVudC5kZXBlbmRlbmNpZXMpO1xuICAgIH1cblxuICAgIHRyYW5zZm9ybShhLCBiLCBjLCBkLCBlLCBmKSB7XG4gICAgICBjb25zdCB0cmFuc2Zvcm1NYXRyaXggPSBbYSwgYiwgYywgZCwgZSwgZl07XG4gICAgICB0aGlzLnRyYW5zZm9ybU1hdHJpeCA9IF91dGlsLlV0aWwudHJhbnNmb3JtKHRoaXMudHJhbnNmb3JtTWF0cml4LCB0cmFuc2Zvcm1NYXRyaXgpO1xuICAgICAgdGhpcy50Z3JwID0gbnVsbDtcbiAgICB9XG5cbiAgICBnZXRTVkcob3BlcmF0b3JMaXN0LCB2aWV3cG9ydCkge1xuICAgICAgdGhpcy52aWV3cG9ydCA9IHZpZXdwb3J0O1xuXG4gICAgICBjb25zdCBzdmdFbGVtZW50ID0gdGhpcy5faW5pdGlhbGl6ZSh2aWV3cG9ydCk7XG5cbiAgICAgIHJldHVybiB0aGlzLmxvYWREZXBlbmRlbmNpZXMob3BlcmF0b3JMaXN0KS50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy50cmFuc2Zvcm1NYXRyaXggPSBfdXRpbC5JREVOVElUWV9NQVRSSVg7XG4gICAgICAgIHRoaXMuZXhlY3V0ZU9wVHJlZSh0aGlzLmNvbnZlcnRPcExpc3Qob3BlcmF0b3JMaXN0KSk7XG4gICAgICAgIHJldHVybiBzdmdFbGVtZW50O1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29udmVydE9wTGlzdChvcGVyYXRvckxpc3QpIHtcbiAgICAgIGNvbnN0IG9wZXJhdG9ySWRNYXBwaW5nID0gdGhpcy5fb3BlcmF0b3JJZE1hcHBpbmc7XG4gICAgICBjb25zdCBhcmdzQXJyYXkgPSBvcGVyYXRvckxpc3QuYXJnc0FycmF5O1xuICAgICAgY29uc3QgZm5BcnJheSA9IG9wZXJhdG9yTGlzdC5mbkFycmF5O1xuICAgICAgY29uc3Qgb3BMaXN0ID0gW107XG5cbiAgICAgIGZvciAobGV0IGkgPSAwLCBpaSA9IGZuQXJyYXkubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICBjb25zdCBmbklkID0gZm5BcnJheVtpXTtcbiAgICAgICAgb3BMaXN0LnB1c2goe1xuICAgICAgICAgIGZuSWQsXG4gICAgICAgICAgZm46IG9wZXJhdG9ySWRNYXBwaW5nW2ZuSWRdLFxuICAgICAgICAgIGFyZ3M6IGFyZ3NBcnJheVtpXVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG9wTGlzdFRvVHJlZShvcExpc3QpO1xuICAgIH1cblxuICAgIGV4ZWN1dGVPcFRyZWUob3BUcmVlKSB7XG4gICAgICBmb3IgKGNvbnN0IG9wVHJlZUVsZW1lbnQgb2Ygb3BUcmVlKSB7XG4gICAgICAgIGNvbnN0IGZuID0gb3BUcmVlRWxlbWVudC5mbjtcbiAgICAgICAgY29uc3QgZm5JZCA9IG9wVHJlZUVsZW1lbnQuZm5JZDtcbiAgICAgICAgY29uc3QgYXJncyA9IG9wVHJlZUVsZW1lbnQuYXJncztcblxuICAgICAgICBzd2l0Y2ggKGZuSWQgfCAwKSB7XG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuYmVnaW5UZXh0OlxuICAgICAgICAgICAgdGhpcy5iZWdpblRleHQoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuZGVwZW5kZW5jeTpcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0TGVhZGluZzpcbiAgICAgICAgICAgIHRoaXMuc2V0TGVhZGluZyhhcmdzKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0TGVhZGluZ01vdmVUZXh0OlxuICAgICAgICAgICAgdGhpcy5zZXRMZWFkaW5nTW92ZVRleHQoYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnNldEZvbnQ6XG4gICAgICAgICAgICB0aGlzLnNldEZvbnQoYXJncyk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnNob3dUZXh0OlxuICAgICAgICAgICAgdGhpcy5zaG93VGV4dChhcmdzWzBdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2hvd1NwYWNlZFRleHQ6XG4gICAgICAgICAgICB0aGlzLnNob3dUZXh0KGFyZ3NbMF0pO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5lbmRUZXh0OlxuICAgICAgICAgICAgdGhpcy5lbmRUZXh0KCk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLm1vdmVUZXh0OlxuICAgICAgICAgICAgdGhpcy5tb3ZlVGV4dChhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0Q2hhclNwYWNpbmc6XG4gICAgICAgICAgICB0aGlzLnNldENoYXJTcGFjaW5nKGFyZ3NbMF0pO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5zZXRXb3JkU3BhY2luZzpcbiAgICAgICAgICAgIHRoaXMuc2V0V29yZFNwYWNpbmcoYXJnc1swXSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnNldEhTY2FsZTpcbiAgICAgICAgICAgIHRoaXMuc2V0SFNjYWxlKGFyZ3NbMF0pO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5zZXRUZXh0TWF0cml4OlxuICAgICAgICAgICAgdGhpcy5zZXRUZXh0TWF0cml4KGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0sIGFyZ3NbNV0pO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5zZXRUZXh0UmlzZTpcbiAgICAgICAgICAgIHRoaXMuc2V0VGV4dFJpc2UoYXJnc1swXSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnNldFRleHRSZW5kZXJpbmdNb2RlOlxuICAgICAgICAgICAgdGhpcy5zZXRUZXh0UmVuZGVyaW5nTW9kZShhcmdzWzBdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0TGluZVdpZHRoOlxuICAgICAgICAgICAgdGhpcy5zZXRMaW5lV2lkdGgoYXJnc1swXSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnNldExpbmVKb2luOlxuICAgICAgICAgICAgdGhpcy5zZXRMaW5lSm9pbihhcmdzWzBdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0TGluZUNhcDpcbiAgICAgICAgICAgIHRoaXMuc2V0TGluZUNhcChhcmdzWzBdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0TWl0ZXJMaW1pdDpcbiAgICAgICAgICAgIHRoaXMuc2V0TWl0ZXJMaW1pdChhcmdzWzBdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0RmlsbFJHQkNvbG9yOlxuICAgICAgICAgICAgdGhpcy5zZXRGaWxsUkdCQ29sb3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnNldFN0cm9rZVJHQkNvbG9yOlxuICAgICAgICAgICAgdGhpcy5zZXRTdHJva2VSR0JDb2xvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0U3Ryb2tlQ29sb3JOOlxuICAgICAgICAgICAgdGhpcy5zZXRTdHJva2VDb2xvck4oYXJncyk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnNldEZpbGxDb2xvck46XG4gICAgICAgICAgICB0aGlzLnNldEZpbGxDb2xvck4oYXJncyk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnNoYWRpbmdGaWxsOlxuICAgICAgICAgICAgdGhpcy5zaGFkaW5nRmlsbChhcmdzWzBdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0RGFzaDpcbiAgICAgICAgICAgIHRoaXMuc2V0RGFzaChhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0UmVuZGVyaW5nSW50ZW50OlxuICAgICAgICAgICAgdGhpcy5zZXRSZW5kZXJpbmdJbnRlbnQoYXJnc1swXSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnNldEZsYXRuZXNzOlxuICAgICAgICAgICAgdGhpcy5zZXRGbGF0bmVzcyhhcmdzWzBdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc2V0R1N0YXRlOlxuICAgICAgICAgICAgdGhpcy5zZXRHU3RhdGUoYXJnc1swXSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLmZpbGw6XG4gICAgICAgICAgICB0aGlzLmZpbGwoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuZW9GaWxsOlxuICAgICAgICAgICAgdGhpcy5lb0ZpbGwoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuc3Ryb2tlOlxuICAgICAgICAgICAgdGhpcy5zdHJva2UoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuZmlsbFN0cm9rZTpcbiAgICAgICAgICAgIHRoaXMuZmlsbFN0cm9rZSgpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5lb0ZpbGxTdHJva2U6XG4gICAgICAgICAgICB0aGlzLmVvRmlsbFN0cm9rZSgpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5jbGlwOlxuICAgICAgICAgICAgdGhpcy5jbGlwKFwibm9uemVyb1wiKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuZW9DbGlwOlxuICAgICAgICAgICAgdGhpcy5jbGlwKFwiZXZlbm9kZFwiKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMucGFpbnRTb2xpZENvbG9ySW1hZ2VNYXNrOlxuICAgICAgICAgICAgdGhpcy5wYWludFNvbGlkQ29sb3JJbWFnZU1hc2soKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMucGFpbnRJbWFnZVhPYmplY3Q6XG4gICAgICAgICAgICB0aGlzLnBhaW50SW1hZ2VYT2JqZWN0KGFyZ3NbMF0pO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5wYWludElubGluZUltYWdlWE9iamVjdDpcbiAgICAgICAgICAgIHRoaXMucGFpbnRJbmxpbmVJbWFnZVhPYmplY3QoYXJnc1swXSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnBhaW50SW1hZ2VNYXNrWE9iamVjdDpcbiAgICAgICAgICAgIHRoaXMucGFpbnRJbWFnZU1hc2tYT2JqZWN0KGFyZ3NbMF0pO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5wYWludEZvcm1YT2JqZWN0QmVnaW46XG4gICAgICAgICAgICB0aGlzLnBhaW50Rm9ybVhPYmplY3RCZWdpbihhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMucGFpbnRGb3JtWE9iamVjdEVuZDpcbiAgICAgICAgICAgIHRoaXMucGFpbnRGb3JtWE9iamVjdEVuZCgpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5jbG9zZVBhdGg6XG4gICAgICAgICAgICB0aGlzLmNsb3NlUGF0aCgpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5jbG9zZVN0cm9rZTpcbiAgICAgICAgICAgIHRoaXMuY2xvc2VTdHJva2UoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuY2xvc2VGaWxsU3Ryb2tlOlxuICAgICAgICAgICAgdGhpcy5jbG9zZUZpbGxTdHJva2UoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuY2xvc2VFT0ZpbGxTdHJva2U6XG4gICAgICAgICAgICB0aGlzLmNsb3NlRU9GaWxsU3Ryb2tlKCk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLm5leHRMaW5lOlxuICAgICAgICAgICAgdGhpcy5uZXh0TGluZSgpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy50cmFuc2Zvcm06XG4gICAgICAgICAgICB0aGlzLnRyYW5zZm9ybShhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdLCBhcmdzWzVdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuY29uc3RydWN0UGF0aDpcbiAgICAgICAgICAgIHRoaXMuY29uc3RydWN0UGF0aChhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMuZW5kUGF0aDpcbiAgICAgICAgICAgIHRoaXMuZW5kUGF0aCgpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIDkyOlxuICAgICAgICAgICAgdGhpcy5ncm91cChvcFRyZWVFbGVtZW50Lml0ZW1zKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICgwLCBfdXRpbC53YXJuKShgVW5pbXBsZW1lbnRlZCBvcGVyYXRvciAke2ZufWApO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRXb3JkU3BhY2luZyh3b3JkU3BhY2luZykge1xuICAgICAgdGhpcy5jdXJyZW50LndvcmRTcGFjaW5nID0gd29yZFNwYWNpbmc7XG4gICAgfVxuXG4gICAgc2V0Q2hhclNwYWNpbmcoY2hhclNwYWNpbmcpIHtcbiAgICAgIHRoaXMuY3VycmVudC5jaGFyU3BhY2luZyA9IGNoYXJTcGFjaW5nO1xuICAgIH1cblxuICAgIG5leHRMaW5lKCkge1xuICAgICAgdGhpcy5tb3ZlVGV4dCgwLCB0aGlzLmN1cnJlbnQubGVhZGluZyk7XG4gICAgfVxuXG4gICAgc2V0VGV4dE1hdHJpeChhLCBiLCBjLCBkLCBlLCBmKSB7XG4gICAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5jdXJyZW50O1xuICAgICAgY3VycmVudC50ZXh0TWF0cml4ID0gY3VycmVudC5saW5lTWF0cml4ID0gW2EsIGIsIGMsIGQsIGUsIGZdO1xuICAgICAgY3VycmVudC50ZXh0TWF0cml4U2NhbGUgPSBNYXRoLmh5cG90KGEsIGIpO1xuICAgICAgY3VycmVudC54ID0gY3VycmVudC5saW5lWCA9IDA7XG4gICAgICBjdXJyZW50LnkgPSBjdXJyZW50LmxpbmVZID0gMDtcbiAgICAgIGN1cnJlbnQueGNvb3JkcyA9IFtdO1xuICAgICAgY3VycmVudC55Y29vcmRzID0gW107XG4gICAgICBjdXJyZW50LnRzcGFuID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZUVsZW1lbnQoXCJzdmc6dHNwYW5cIik7XG4gICAgICBjdXJyZW50LnRzcGFuLnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZm9udC1mYW1pbHlcIiwgY3VycmVudC5mb250RmFtaWx5KTtcbiAgICAgIGN1cnJlbnQudHNwYW4uc2V0QXR0cmlidXRlTlMobnVsbCwgXCJmb250LXNpemVcIiwgYCR7cGYoY3VycmVudC5mb250U2l6ZSl9cHhgKTtcbiAgICAgIGN1cnJlbnQudHNwYW4uc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ5XCIsIHBmKC1jdXJyZW50LnkpKTtcbiAgICAgIGN1cnJlbnQudHh0RWxlbWVudCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOnRleHRcIik7XG4gICAgICBjdXJyZW50LnR4dEVsZW1lbnQuYXBwZW5kQ2hpbGQoY3VycmVudC50c3Bhbik7XG4gICAgfVxuXG4gICAgYmVnaW5UZXh0KCkge1xuICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcbiAgICAgIGN1cnJlbnQueCA9IGN1cnJlbnQubGluZVggPSAwO1xuICAgICAgY3VycmVudC55ID0gY3VycmVudC5saW5lWSA9IDA7XG4gICAgICBjdXJyZW50LnRleHRNYXRyaXggPSBfdXRpbC5JREVOVElUWV9NQVRSSVg7XG4gICAgICBjdXJyZW50LmxpbmVNYXRyaXggPSBfdXRpbC5JREVOVElUWV9NQVRSSVg7XG4gICAgICBjdXJyZW50LnRleHRNYXRyaXhTY2FsZSA9IDE7XG4gICAgICBjdXJyZW50LnRzcGFuID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZUVsZW1lbnQoXCJzdmc6dHNwYW5cIik7XG4gICAgICBjdXJyZW50LnR4dEVsZW1lbnQgPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlRWxlbWVudChcInN2Zzp0ZXh0XCIpO1xuICAgICAgY3VycmVudC50eHRncnAgPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlRWxlbWVudChcInN2ZzpnXCIpO1xuICAgICAgY3VycmVudC54Y29vcmRzID0gW107XG4gICAgICBjdXJyZW50Lnljb29yZHMgPSBbXTtcbiAgICB9XG5cbiAgICBtb3ZlVGV4dCh4LCB5KSB7XG4gICAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5jdXJyZW50O1xuICAgICAgY3VycmVudC54ID0gY3VycmVudC5saW5lWCArPSB4O1xuICAgICAgY3VycmVudC55ID0gY3VycmVudC5saW5lWSArPSB5O1xuICAgICAgY3VycmVudC54Y29vcmRzID0gW107XG4gICAgICBjdXJyZW50Lnljb29yZHMgPSBbXTtcbiAgICAgIGN1cnJlbnQudHNwYW4gPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlRWxlbWVudChcInN2Zzp0c3BhblwiKTtcbiAgICAgIGN1cnJlbnQudHNwYW4uc2V0QXR0cmlidXRlTlMobnVsbCwgXCJmb250LWZhbWlseVwiLCBjdXJyZW50LmZvbnRGYW1pbHkpO1xuICAgICAgY3VycmVudC50c3Bhbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImZvbnQtc2l6ZVwiLCBgJHtwZihjdXJyZW50LmZvbnRTaXplKX1weGApO1xuICAgICAgY3VycmVudC50c3Bhbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInlcIiwgcGYoLWN1cnJlbnQueSkpO1xuICAgIH1cblxuICAgIHNob3dUZXh0KGdseXBocykge1xuICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcbiAgICAgIGNvbnN0IGZvbnQgPSBjdXJyZW50LmZvbnQ7XG4gICAgICBjb25zdCBmb250U2l6ZSA9IGN1cnJlbnQuZm9udFNpemU7XG5cbiAgICAgIGlmIChmb250U2l6ZSA9PT0gMCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZvbnRTaXplU2NhbGUgPSBjdXJyZW50LmZvbnRTaXplU2NhbGU7XG4gICAgICBjb25zdCBjaGFyU3BhY2luZyA9IGN1cnJlbnQuY2hhclNwYWNpbmc7XG4gICAgICBjb25zdCB3b3JkU3BhY2luZyA9IGN1cnJlbnQud29yZFNwYWNpbmc7XG4gICAgICBjb25zdCBmb250RGlyZWN0aW9uID0gY3VycmVudC5mb250RGlyZWN0aW9uO1xuICAgICAgY29uc3QgdGV4dEhTY2FsZSA9IGN1cnJlbnQudGV4dEhTY2FsZSAqIGZvbnREaXJlY3Rpb247XG4gICAgICBjb25zdCB2ZXJ0aWNhbCA9IGZvbnQudmVydGljYWw7XG4gICAgICBjb25zdCBzcGFjaW5nRGlyID0gdmVydGljYWwgPyAxIDogLTE7XG4gICAgICBjb25zdCBkZWZhdWx0Vk1ldHJpY3MgPSBmb250LmRlZmF1bHRWTWV0cmljcztcbiAgICAgIGNvbnN0IHdpZHRoQWR2YW5jZVNjYWxlID0gZm9udFNpemUgKiBjdXJyZW50LmZvbnRNYXRyaXhbMF07XG4gICAgICBsZXQgeCA9IDA7XG5cbiAgICAgIGZvciAoY29uc3QgZ2x5cGggb2YgZ2x5cGhzKSB7XG4gICAgICAgIGlmIChnbHlwaCA9PT0gbnVsbCkge1xuICAgICAgICAgIHggKz0gZm9udERpcmVjdGlvbiAqIHdvcmRTcGFjaW5nO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBnbHlwaCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgIHggKz0gc3BhY2luZ0RpciAqIGdseXBoICogZm9udFNpemUgLyAxMDAwO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc3BhY2luZyA9IChnbHlwaC5pc1NwYWNlID8gd29yZFNwYWNpbmcgOiAwKSArIGNoYXJTcGFjaW5nO1xuICAgICAgICBjb25zdCBjaGFyYWN0ZXIgPSBnbHlwaC5mb250Q2hhcjtcbiAgICAgICAgbGV0IHNjYWxlZFgsIHNjYWxlZFk7XG4gICAgICAgIGxldCB3aWR0aCA9IGdseXBoLndpZHRoO1xuXG4gICAgICAgIGlmICh2ZXJ0aWNhbCkge1xuICAgICAgICAgIGxldCB2eDtcbiAgICAgICAgICBjb25zdCB2bWV0cmljID0gZ2x5cGgudm1ldHJpYyB8fCBkZWZhdWx0Vk1ldHJpY3M7XG4gICAgICAgICAgdnggPSBnbHlwaC52bWV0cmljID8gdm1ldHJpY1sxXSA6IHdpZHRoICogMC41O1xuICAgICAgICAgIHZ4ID0gLXZ4ICogd2lkdGhBZHZhbmNlU2NhbGU7XG4gICAgICAgICAgY29uc3QgdnkgPSB2bWV0cmljWzJdICogd2lkdGhBZHZhbmNlU2NhbGU7XG4gICAgICAgICAgd2lkdGggPSB2bWV0cmljID8gLXZtZXRyaWNbMF0gOiB3aWR0aDtcbiAgICAgICAgICBzY2FsZWRYID0gdnggLyBmb250U2l6ZVNjYWxlO1xuICAgICAgICAgIHNjYWxlZFkgPSAoeCArIHZ5KSAvIGZvbnRTaXplU2NhbGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2NhbGVkWCA9IHggLyBmb250U2l6ZVNjYWxlO1xuICAgICAgICAgIHNjYWxlZFkgPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGdseXBoLmlzSW5Gb250IHx8IGZvbnQubWlzc2luZ0ZpbGUpIHtcbiAgICAgICAgICBjdXJyZW50Lnhjb29yZHMucHVzaChjdXJyZW50LnggKyBzY2FsZWRYKTtcblxuICAgICAgICAgIGlmICh2ZXJ0aWNhbCkge1xuICAgICAgICAgICAgY3VycmVudC55Y29vcmRzLnB1c2goLWN1cnJlbnQueSArIHNjYWxlZFkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGN1cnJlbnQudHNwYW4udGV4dENvbnRlbnQgKz0gY2hhcmFjdGVyO1xuICAgICAgICB9IGVsc2Uge31cblxuICAgICAgICBsZXQgY2hhcldpZHRoO1xuXG4gICAgICAgIGlmICh2ZXJ0aWNhbCkge1xuICAgICAgICAgIGNoYXJXaWR0aCA9IHdpZHRoICogd2lkdGhBZHZhbmNlU2NhbGUgLSBzcGFjaW5nICogZm9udERpcmVjdGlvbjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjaGFyV2lkdGggPSB3aWR0aCAqIHdpZHRoQWR2YW5jZVNjYWxlICsgc3BhY2luZyAqIGZvbnREaXJlY3Rpb247XG4gICAgICAgIH1cblxuICAgICAgICB4ICs9IGNoYXJXaWR0aDtcbiAgICAgIH1cblxuICAgICAgY3VycmVudC50c3Bhbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInhcIiwgY3VycmVudC54Y29vcmRzLm1hcChwZikuam9pbihcIiBcIikpO1xuXG4gICAgICBpZiAodmVydGljYWwpIHtcbiAgICAgICAgY3VycmVudC50c3Bhbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInlcIiwgY3VycmVudC55Y29vcmRzLm1hcChwZikuam9pbihcIiBcIikpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3VycmVudC50c3Bhbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInlcIiwgcGYoLWN1cnJlbnQueSkpO1xuICAgICAgfVxuXG4gICAgICBpZiAodmVydGljYWwpIHtcbiAgICAgICAgY3VycmVudC55IC09IHg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjdXJyZW50LnggKz0geCAqIHRleHRIU2NhbGU7XG4gICAgICB9XG5cbiAgICAgIGN1cnJlbnQudHNwYW4uc2V0QXR0cmlidXRlTlMobnVsbCwgXCJmb250LWZhbWlseVwiLCBjdXJyZW50LmZvbnRGYW1pbHkpO1xuICAgICAgY3VycmVudC50c3Bhbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImZvbnQtc2l6ZVwiLCBgJHtwZihjdXJyZW50LmZvbnRTaXplKX1weGApO1xuXG4gICAgICBpZiAoY3VycmVudC5mb250U3R5bGUgIT09IFNWR19ERUZBVUxUUy5mb250U3R5bGUpIHtcbiAgICAgICAgY3VycmVudC50c3Bhbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImZvbnQtc3R5bGVcIiwgY3VycmVudC5mb250U3R5bGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoY3VycmVudC5mb250V2VpZ2h0ICE9PSBTVkdfREVGQVVMVFMuZm9udFdlaWdodCkge1xuICAgICAgICBjdXJyZW50LnRzcGFuLnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZm9udC13ZWlnaHRcIiwgY3VycmVudC5mb250V2VpZ2h0KTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZmlsbFN0cm9rZU1vZGUgPSBjdXJyZW50LnRleHRSZW5kZXJpbmdNb2RlICYgX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuRklMTF9TVFJPS0VfTUFTSztcblxuICAgICAgaWYgKGZpbGxTdHJva2VNb2RlID09PSBfdXRpbC5UZXh0UmVuZGVyaW5nTW9kZS5GSUxMIHx8IGZpbGxTdHJva2VNb2RlID09PSBfdXRpbC5UZXh0UmVuZGVyaW5nTW9kZS5GSUxMX1NUUk9LRSkge1xuICAgICAgICBpZiAoY3VycmVudC5maWxsQ29sb3IgIT09IFNWR19ERUZBVUxUUy5maWxsQ29sb3IpIHtcbiAgICAgICAgICBjdXJyZW50LnRzcGFuLnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZmlsbFwiLCBjdXJyZW50LmZpbGxDb2xvcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY3VycmVudC5maWxsQWxwaGEgPCAxKSB7XG4gICAgICAgICAgY3VycmVudC50c3Bhbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImZpbGwtb3BhY2l0eVwiLCBjdXJyZW50LmZpbGxBbHBoYSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoY3VycmVudC50ZXh0UmVuZGVyaW5nTW9kZSA9PT0gX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuQUREX1RPX1BBVEgpIHtcbiAgICAgICAgY3VycmVudC50c3Bhbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImZpbGxcIiwgXCJ0cmFuc3BhcmVudFwiKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGN1cnJlbnQudHNwYW4uc2V0QXR0cmlidXRlTlMobnVsbCwgXCJmaWxsXCIsIFwibm9uZVwiKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGZpbGxTdHJva2VNb2RlID09PSBfdXRpbC5UZXh0UmVuZGVyaW5nTW9kZS5TVFJPS0UgfHwgZmlsbFN0cm9rZU1vZGUgPT09IF91dGlsLlRleHRSZW5kZXJpbmdNb2RlLkZJTExfU1RST0tFKSB7XG4gICAgICAgIGNvbnN0IGxpbmVXaWR0aFNjYWxlID0gMSAvIChjdXJyZW50LnRleHRNYXRyaXhTY2FsZSB8fCAxKTtcblxuICAgICAgICB0aGlzLl9zZXRTdHJva2VBdHRyaWJ1dGVzKGN1cnJlbnQudHNwYW4sIGxpbmVXaWR0aFNjYWxlKTtcbiAgICAgIH1cblxuICAgICAgbGV0IHRleHRNYXRyaXggPSBjdXJyZW50LnRleHRNYXRyaXg7XG5cbiAgICAgIGlmIChjdXJyZW50LnRleHRSaXNlICE9PSAwKSB7XG4gICAgICAgIHRleHRNYXRyaXggPSB0ZXh0TWF0cml4LnNsaWNlKCk7XG4gICAgICAgIHRleHRNYXRyaXhbNV0gKz0gY3VycmVudC50ZXh0UmlzZTtcbiAgICAgIH1cblxuICAgICAgY3VycmVudC50eHRFbGVtZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwidHJhbnNmb3JtXCIsIGAke3BtKHRleHRNYXRyaXgpfSBzY2FsZSgke3BmKHRleHRIU2NhbGUpfSwgLTEpYCk7XG4gICAgICBjdXJyZW50LnR4dEVsZW1lbnQuc2V0QXR0cmlidXRlTlMoWE1MX05TLCBcInhtbDpzcGFjZVwiLCBcInByZXNlcnZlXCIpO1xuICAgICAgY3VycmVudC50eHRFbGVtZW50LmFwcGVuZENoaWxkKGN1cnJlbnQudHNwYW4pO1xuICAgICAgY3VycmVudC50eHRncnAuYXBwZW5kQ2hpbGQoY3VycmVudC50eHRFbGVtZW50KTtcblxuICAgICAgdGhpcy5fZW5zdXJlVHJhbnNmb3JtR3JvdXAoKS5hcHBlbmRDaGlsZChjdXJyZW50LnR4dEVsZW1lbnQpO1xuICAgIH1cblxuICAgIHNldExlYWRpbmdNb3ZlVGV4dCh4LCB5KSB7XG4gICAgICB0aGlzLnNldExlYWRpbmcoLXkpO1xuICAgICAgdGhpcy5tb3ZlVGV4dCh4LCB5KTtcbiAgICB9XG5cbiAgICBhZGRGb250U3R5bGUoZm9udE9iaikge1xuICAgICAgaWYgKCFmb250T2JqLmRhdGEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiYWRkRm9udFN0eWxlOiBObyBmb250IGRhdGEgYXZhaWxhYmxlLCBcIiArICdlbnN1cmUgdGhhdCB0aGUgXCJmb250RXh0cmFQcm9wZXJ0aWVzXCIgQVBJIHBhcmFtZXRlciBpcyBzZXQuJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghdGhpcy5jc3NTdHlsZSkge1xuICAgICAgICB0aGlzLmNzc1N0eWxlID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZUVsZW1lbnQoXCJzdmc6c3R5bGVcIik7XG4gICAgICAgIHRoaXMuY3NzU3R5bGUuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ0eXBlXCIsIFwidGV4dC9jc3NcIik7XG4gICAgICAgIHRoaXMuZGVmcy5hcHBlbmRDaGlsZCh0aGlzLmNzc1N0eWxlKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdXJsID0gY3JlYXRlT2JqZWN0VVJMKGZvbnRPYmouZGF0YSwgZm9udE9iai5taW1ldHlwZSwgdGhpcy5mb3JjZURhdGFTY2hlbWEpO1xuICAgICAgdGhpcy5jc3NTdHlsZS50ZXh0Q29udGVudCArPSBgQGZvbnQtZmFjZSB7IGZvbnQtZmFtaWx5OiBcIiR7Zm9udE9iai5sb2FkZWROYW1lfVwiO2AgKyBgIHNyYzogdXJsKCR7dXJsfSk7IH1cXG5gO1xuICAgIH1cblxuICAgIHNldEZvbnQoZGV0YWlscykge1xuICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcbiAgICAgIGNvbnN0IGZvbnRPYmogPSB0aGlzLmNvbW1vbk9ianMuZ2V0KGRldGFpbHNbMF0pO1xuICAgICAgbGV0IHNpemUgPSBkZXRhaWxzWzFdO1xuICAgICAgY3VycmVudC5mb250ID0gZm9udE9iajtcblxuICAgICAgaWYgKHRoaXMuZW1iZWRGb250cyAmJiAhZm9udE9iai5taXNzaW5nRmlsZSAmJiAhdGhpcy5lbWJlZGRlZEZvbnRzW2ZvbnRPYmoubG9hZGVkTmFtZV0pIHtcbiAgICAgICAgdGhpcy5hZGRGb250U3R5bGUoZm9udE9iaik7XG4gICAgICAgIHRoaXMuZW1iZWRkZWRGb250c1tmb250T2JqLmxvYWRlZE5hbWVdID0gZm9udE9iajtcbiAgICAgIH1cblxuICAgICAgY3VycmVudC5mb250TWF0cml4ID0gZm9udE9iai5mb250TWF0cml4IHx8IF91dGlsLkZPTlRfSURFTlRJVFlfTUFUUklYO1xuICAgICAgbGV0IGJvbGQgPSBcIm5vcm1hbFwiO1xuXG4gICAgICBpZiAoZm9udE9iai5ibGFjaykge1xuICAgICAgICBib2xkID0gXCI5MDBcIjtcbiAgICAgIH0gZWxzZSBpZiAoZm9udE9iai5ib2xkKSB7XG4gICAgICAgIGJvbGQgPSBcImJvbGRcIjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaXRhbGljID0gZm9udE9iai5pdGFsaWMgPyBcIml0YWxpY1wiIDogXCJub3JtYWxcIjtcblxuICAgICAgaWYgKHNpemUgPCAwKSB7XG4gICAgICAgIHNpemUgPSAtc2l6ZTtcbiAgICAgICAgY3VycmVudC5mb250RGlyZWN0aW9uID0gLTE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjdXJyZW50LmZvbnREaXJlY3Rpb24gPSAxO1xuICAgICAgfVxuXG4gICAgICBjdXJyZW50LmZvbnRTaXplID0gc2l6ZTtcbiAgICAgIGN1cnJlbnQuZm9udEZhbWlseSA9IGZvbnRPYmoubG9hZGVkTmFtZTtcbiAgICAgIGN1cnJlbnQuZm9udFdlaWdodCA9IGJvbGQ7XG4gICAgICBjdXJyZW50LmZvbnRTdHlsZSA9IGl0YWxpYztcbiAgICAgIGN1cnJlbnQudHNwYW4gPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlRWxlbWVudChcInN2Zzp0c3BhblwiKTtcbiAgICAgIGN1cnJlbnQudHNwYW4uc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ5XCIsIHBmKC1jdXJyZW50LnkpKTtcbiAgICAgIGN1cnJlbnQueGNvb3JkcyA9IFtdO1xuICAgICAgY3VycmVudC55Y29vcmRzID0gW107XG4gICAgfVxuXG4gICAgZW5kVGV4dCgpIHtcbiAgICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmN1cnJlbnQ7XG5cbiAgICAgIGlmIChjdXJyZW50LnRleHRSZW5kZXJpbmdNb2RlICYgX3V0aWwuVGV4dFJlbmRlcmluZ01vZGUuQUREX1RPX1BBVEhfRkxBRyAmJiBjdXJyZW50LnR4dEVsZW1lbnQ/Lmhhc0NoaWxkTm9kZXMoKSkge1xuICAgICAgICBjdXJyZW50LmVsZW1lbnQgPSBjdXJyZW50LnR4dEVsZW1lbnQ7XG4gICAgICAgIHRoaXMuY2xpcChcIm5vbnplcm9cIik7XG4gICAgICAgIHRoaXMuZW5kUGF0aCgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHNldExpbmVXaWR0aCh3aWR0aCkge1xuICAgICAgaWYgKHdpZHRoID4gMCkge1xuICAgICAgICB0aGlzLmN1cnJlbnQubGluZVdpZHRoID0gd2lkdGg7XG4gICAgICB9XG4gICAgfVxuXG4gICAgc2V0TGluZUNhcChzdHlsZSkge1xuICAgICAgdGhpcy5jdXJyZW50LmxpbmVDYXAgPSBMSU5FX0NBUF9TVFlMRVNbc3R5bGVdO1xuICAgIH1cblxuICAgIHNldExpbmVKb2luKHN0eWxlKSB7XG4gICAgICB0aGlzLmN1cnJlbnQubGluZUpvaW4gPSBMSU5FX0pPSU5fU1RZTEVTW3N0eWxlXTtcbiAgICB9XG5cbiAgICBzZXRNaXRlckxpbWl0KGxpbWl0KSB7XG4gICAgICB0aGlzLmN1cnJlbnQubWl0ZXJMaW1pdCA9IGxpbWl0O1xuICAgIH1cblxuICAgIHNldFN0cm9rZUFscGhhKHN0cm9rZUFscGhhKSB7XG4gICAgICB0aGlzLmN1cnJlbnQuc3Ryb2tlQWxwaGEgPSBzdHJva2VBbHBoYTtcbiAgICB9XG5cbiAgICBzZXRTdHJva2VSR0JDb2xvcihyLCBnLCBiKSB7XG4gICAgICB0aGlzLmN1cnJlbnQuc3Ryb2tlQ29sb3IgPSBfdXRpbC5VdGlsLm1ha2VIZXhDb2xvcihyLCBnLCBiKTtcbiAgICB9XG5cbiAgICBzZXRGaWxsQWxwaGEoZmlsbEFscGhhKSB7XG4gICAgICB0aGlzLmN1cnJlbnQuZmlsbEFscGhhID0gZmlsbEFscGhhO1xuICAgIH1cblxuICAgIHNldEZpbGxSR0JDb2xvcihyLCBnLCBiKSB7XG4gICAgICB0aGlzLmN1cnJlbnQuZmlsbENvbG9yID0gX3V0aWwuVXRpbC5tYWtlSGV4Q29sb3IociwgZywgYik7XG4gICAgICB0aGlzLmN1cnJlbnQudHNwYW4gPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlRWxlbWVudChcInN2Zzp0c3BhblwiKTtcbiAgICAgIHRoaXMuY3VycmVudC54Y29vcmRzID0gW107XG4gICAgICB0aGlzLmN1cnJlbnQueWNvb3JkcyA9IFtdO1xuICAgIH1cblxuICAgIHNldFN0cm9rZUNvbG9yTihhcmdzKSB7XG4gICAgICB0aGlzLmN1cnJlbnQuc3Ryb2tlQ29sb3IgPSB0aGlzLl9tYWtlQ29sb3JOX1BhdHRlcm4oYXJncyk7XG4gICAgfVxuXG4gICAgc2V0RmlsbENvbG9yTihhcmdzKSB7XG4gICAgICB0aGlzLmN1cnJlbnQuZmlsbENvbG9yID0gdGhpcy5fbWFrZUNvbG9yTl9QYXR0ZXJuKGFyZ3MpO1xuICAgIH1cblxuICAgIHNoYWRpbmdGaWxsKGFyZ3MpIHtcbiAgICAgIGNvbnN0IHdpZHRoID0gdGhpcy52aWV3cG9ydC53aWR0aDtcbiAgICAgIGNvbnN0IGhlaWdodCA9IHRoaXMudmlld3BvcnQuaGVpZ2h0O1xuXG4gICAgICBjb25zdCBpbnYgPSBfdXRpbC5VdGlsLmludmVyc2VUcmFuc2Zvcm0odGhpcy50cmFuc2Zvcm1NYXRyaXgpO1xuXG4gICAgICBjb25zdCBibCA9IF91dGlsLlV0aWwuYXBwbHlUcmFuc2Zvcm0oWzAsIDBdLCBpbnYpO1xuXG4gICAgICBjb25zdCBiciA9IF91dGlsLlV0aWwuYXBwbHlUcmFuc2Zvcm0oWzAsIGhlaWdodF0sIGludik7XG5cbiAgICAgIGNvbnN0IHVsID0gX3V0aWwuVXRpbC5hcHBseVRyYW5zZm9ybShbd2lkdGgsIDBdLCBpbnYpO1xuXG4gICAgICBjb25zdCB1ciA9IF91dGlsLlV0aWwuYXBwbHlUcmFuc2Zvcm0oW3dpZHRoLCBoZWlnaHRdLCBpbnYpO1xuXG4gICAgICBjb25zdCB4MCA9IE1hdGgubWluKGJsWzBdLCBiclswXSwgdWxbMF0sIHVyWzBdKTtcbiAgICAgIGNvbnN0IHkwID0gTWF0aC5taW4oYmxbMV0sIGJyWzFdLCB1bFsxXSwgdXJbMV0pO1xuICAgICAgY29uc3QgeDEgPSBNYXRoLm1heChibFswXSwgYnJbMF0sIHVsWzBdLCB1clswXSk7XG4gICAgICBjb25zdCB5MSA9IE1hdGgubWF4KGJsWzFdLCBiclsxXSwgdWxbMV0sIHVyWzFdKTtcbiAgICAgIGNvbnN0IHJlY3QgPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlRWxlbWVudChcInN2ZzpyZWN0XCIpO1xuICAgICAgcmVjdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInhcIiwgeDApO1xuICAgICAgcmVjdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInlcIiwgeTApO1xuICAgICAgcmVjdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcIndpZHRoXCIsIHgxIC0geDApO1xuICAgICAgcmVjdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImhlaWdodFwiLCB5MSAtIHkwKTtcbiAgICAgIHJlY3Quc2V0QXR0cmlidXRlTlMobnVsbCwgXCJmaWxsXCIsIHRoaXMuX21ha2VTaGFkaW5nUGF0dGVybihhcmdzKSk7XG5cbiAgICAgIGlmICh0aGlzLmN1cnJlbnQuZmlsbEFscGhhIDwgMSkge1xuICAgICAgICByZWN0LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZmlsbC1vcGFjaXR5XCIsIHRoaXMuY3VycmVudC5maWxsQWxwaGEpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9lbnN1cmVUcmFuc2Zvcm1Hcm91cCgpLmFwcGVuZENoaWxkKHJlY3QpO1xuICAgIH1cblxuICAgIF9tYWtlQ29sb3JOX1BhdHRlcm4oYXJncykge1xuICAgICAgaWYgKGFyZ3NbMF0gPT09IFwiVGlsaW5nUGF0dGVyblwiKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYWtlVGlsaW5nUGF0dGVybihhcmdzKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuX21ha2VTaGFkaW5nUGF0dGVybihhcmdzKTtcbiAgICB9XG5cbiAgICBfbWFrZVRpbGluZ1BhdHRlcm4oYXJncykge1xuICAgICAgY29uc3QgY29sb3IgPSBhcmdzWzFdO1xuICAgICAgY29uc3Qgb3BlcmF0b3JMaXN0ID0gYXJnc1syXTtcbiAgICAgIGNvbnN0IG1hdHJpeCA9IGFyZ3NbM10gfHwgX3V0aWwuSURFTlRJVFlfTUFUUklYO1xuICAgICAgY29uc3QgW3gwLCB5MCwgeDEsIHkxXSA9IGFyZ3NbNF07XG4gICAgICBjb25zdCB4c3RlcCA9IGFyZ3NbNV07XG4gICAgICBjb25zdCB5c3RlcCA9IGFyZ3NbNl07XG4gICAgICBjb25zdCBwYWludFR5cGUgPSBhcmdzWzddO1xuICAgICAgY29uc3QgdGlsaW5nSWQgPSBgc2hhZGluZyR7c2hhZGluZ0NvdW50Kyt9YDtcblxuICAgICAgY29uc3QgW3R4MCwgdHkwLCB0eDEsIHR5MV0gPSBfdXRpbC5VdGlsLm5vcm1hbGl6ZVJlY3QoWy4uLl91dGlsLlV0aWwuYXBwbHlUcmFuc2Zvcm0oW3gwLCB5MF0sIG1hdHJpeCksIC4uLl91dGlsLlV0aWwuYXBwbHlUcmFuc2Zvcm0oW3gxLCB5MV0sIG1hdHJpeCldKTtcblxuICAgICAgY29uc3QgW3hzY2FsZSwgeXNjYWxlXSA9IF91dGlsLlV0aWwuc2luZ3VsYXJWYWx1ZURlY29tcG9zZTJkU2NhbGUobWF0cml4KTtcblxuICAgICAgY29uc3QgdHhzdGVwID0geHN0ZXAgKiB4c2NhbGU7XG4gICAgICBjb25zdCB0eXN0ZXAgPSB5c3RlcCAqIHlzY2FsZTtcbiAgICAgIGNvbnN0IHRpbGluZyA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOnBhdHRlcm5cIik7XG4gICAgICB0aWxpbmcuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJpZFwiLCB0aWxpbmdJZCk7XG4gICAgICB0aWxpbmcuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJwYXR0ZXJuVW5pdHNcIiwgXCJ1c2VyU3BhY2VPblVzZVwiKTtcbiAgICAgIHRpbGluZy5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcIndpZHRoXCIsIHR4c3RlcCk7XG4gICAgICB0aWxpbmcuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJoZWlnaHRcIiwgdHlzdGVwKTtcbiAgICAgIHRpbGluZy5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInhcIiwgYCR7dHgwfWApO1xuICAgICAgdGlsaW5nLnNldEF0dHJpYnV0ZU5TKG51bGwsIFwieVwiLCBgJHt0eTB9YCk7XG4gICAgICBjb25zdCBzdmcgPSB0aGlzLnN2ZztcbiAgICAgIGNvbnN0IHRyYW5zZm9ybU1hdHJpeCA9IHRoaXMudHJhbnNmb3JtTWF0cml4O1xuICAgICAgY29uc3QgZmlsbENvbG9yID0gdGhpcy5jdXJyZW50LmZpbGxDb2xvcjtcbiAgICAgIGNvbnN0IHN0cm9rZUNvbG9yID0gdGhpcy5jdXJyZW50LnN0cm9rZUNvbG9yO1xuICAgICAgY29uc3QgYmJveCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGUodHgxIC0gdHgwLCB0eTEgLSB0eTApO1xuICAgICAgdGhpcy5zdmcgPSBiYm94O1xuICAgICAgdGhpcy50cmFuc2Zvcm1NYXRyaXggPSBtYXRyaXg7XG5cbiAgICAgIGlmIChwYWludFR5cGUgPT09IDIpIHtcbiAgICAgICAgY29uc3QgY3NzQ29sb3IgPSBfdXRpbC5VdGlsLm1ha2VIZXhDb2xvciguLi5jb2xvcik7XG5cbiAgICAgICAgdGhpcy5jdXJyZW50LmZpbGxDb2xvciA9IGNzc0NvbG9yO1xuICAgICAgICB0aGlzLmN1cnJlbnQuc3Ryb2tlQ29sb3IgPSBjc3NDb2xvcjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5leGVjdXRlT3BUcmVlKHRoaXMuY29udmVydE9wTGlzdChvcGVyYXRvckxpc3QpKTtcbiAgICAgIHRoaXMuc3ZnID0gc3ZnO1xuICAgICAgdGhpcy50cmFuc2Zvcm1NYXRyaXggPSB0cmFuc2Zvcm1NYXRyaXg7XG4gICAgICB0aGlzLmN1cnJlbnQuZmlsbENvbG9yID0gZmlsbENvbG9yO1xuICAgICAgdGhpcy5jdXJyZW50LnN0cm9rZUNvbG9yID0gc3Ryb2tlQ29sb3I7XG4gICAgICB0aWxpbmcuYXBwZW5kQ2hpbGQoYmJveC5jaGlsZE5vZGVzWzBdKTtcbiAgICAgIHRoaXMuZGVmcy5hcHBlbmRDaGlsZCh0aWxpbmcpO1xuICAgICAgcmV0dXJuIGB1cmwoIyR7dGlsaW5nSWR9KWA7XG4gICAgfVxuXG4gICAgX21ha2VTaGFkaW5nUGF0dGVybihhcmdzKSB7XG4gICAgICBpZiAodHlwZW9mIGFyZ3MgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgYXJncyA9IHRoaXMub2Jqcy5nZXQoYXJncyk7XG4gICAgICB9XG5cbiAgICAgIHN3aXRjaCAoYXJnc1swXSkge1xuICAgICAgICBjYXNlIFwiUmFkaWFsQXhpYWxcIjpcbiAgICAgICAgICBjb25zdCBzaGFkaW5nSWQgPSBgc2hhZGluZyR7c2hhZGluZ0NvdW50Kyt9YDtcbiAgICAgICAgICBjb25zdCBjb2xvclN0b3BzID0gYXJnc1szXTtcbiAgICAgICAgICBsZXQgZ3JhZGllbnQ7XG5cbiAgICAgICAgICBzd2l0Y2ggKGFyZ3NbMV0pIHtcbiAgICAgICAgICAgIGNhc2UgXCJheGlhbFwiOlxuICAgICAgICAgICAgICBjb25zdCBwb2ludDAgPSBhcmdzWzRdO1xuICAgICAgICAgICAgICBjb25zdCBwb2ludDEgPSBhcmdzWzVdO1xuICAgICAgICAgICAgICBncmFkaWVudCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOmxpbmVhckdyYWRpZW50XCIpO1xuICAgICAgICAgICAgICBncmFkaWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImlkXCIsIHNoYWRpbmdJZCk7XG4gICAgICAgICAgICAgIGdyYWRpZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZ3JhZGllbnRVbml0c1wiLCBcInVzZXJTcGFjZU9uVXNlXCIpO1xuICAgICAgICAgICAgICBncmFkaWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcIngxXCIsIHBvaW50MFswXSk7XG4gICAgICAgICAgICAgIGdyYWRpZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwieTFcIiwgcG9pbnQwWzFdKTtcbiAgICAgICAgICAgICAgZ3JhZGllbnQuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ4MlwiLCBwb2ludDFbMF0pO1xuICAgICAgICAgICAgICBncmFkaWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInkyXCIsIHBvaW50MVsxXSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlIFwicmFkaWFsXCI6XG4gICAgICAgICAgICAgIGNvbnN0IGZvY2FsUG9pbnQgPSBhcmdzWzRdO1xuICAgICAgICAgICAgICBjb25zdCBjaXJjbGVQb2ludCA9IGFyZ3NbNV07XG4gICAgICAgICAgICAgIGNvbnN0IGZvY2FsUmFkaXVzID0gYXJnc1s2XTtcbiAgICAgICAgICAgICAgY29uc3QgY2lyY2xlUmFkaXVzID0gYXJnc1s3XTtcbiAgICAgICAgICAgICAgZ3JhZGllbnQgPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlRWxlbWVudChcInN2ZzpyYWRpYWxHcmFkaWVudFwiKTtcbiAgICAgICAgICAgICAgZ3JhZGllbnQuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJpZFwiLCBzaGFkaW5nSWQpO1xuICAgICAgICAgICAgICBncmFkaWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImdyYWRpZW50VW5pdHNcIiwgXCJ1c2VyU3BhY2VPblVzZVwiKTtcbiAgICAgICAgICAgICAgZ3JhZGllbnQuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJjeFwiLCBjaXJjbGVQb2ludFswXSk7XG4gICAgICAgICAgICAgIGdyYWRpZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiY3lcIiwgY2lyY2xlUG9pbnRbMV0pO1xuICAgICAgICAgICAgICBncmFkaWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInJcIiwgY2lyY2xlUmFkaXVzKTtcbiAgICAgICAgICAgICAgZ3JhZGllbnQuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJmeFwiLCBmb2NhbFBvaW50WzBdKTtcbiAgICAgICAgICAgICAgZ3JhZGllbnQuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJmeVwiLCBmb2NhbFBvaW50WzFdKTtcbiAgICAgICAgICAgICAgZ3JhZGllbnQuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJmclwiLCBmb2NhbFJhZGl1cyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gUmFkaWFsQXhpYWwgdHlwZTogJHthcmdzWzFdfWApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGZvciAoY29uc3QgY29sb3JTdG9wIG9mIGNvbG9yU3RvcHMpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0b3AgPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlRWxlbWVudChcInN2ZzpzdG9wXCIpO1xuICAgICAgICAgICAgc3RvcC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcIm9mZnNldFwiLCBjb2xvclN0b3BbMF0pO1xuICAgICAgICAgICAgc3RvcC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInN0b3AtY29sb3JcIiwgY29sb3JTdG9wWzFdKTtcbiAgICAgICAgICAgIGdyYWRpZW50LmFwcGVuZENoaWxkKHN0b3ApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuZGVmcy5hcHBlbmRDaGlsZChncmFkaWVudCk7XG4gICAgICAgICAgcmV0dXJuIGB1cmwoIyR7c2hhZGluZ0lkfSlgO1xuXG4gICAgICAgIGNhc2UgXCJNZXNoXCI6XG4gICAgICAgICAgKDAsIF91dGlsLndhcm4pKFwiVW5pbXBsZW1lbnRlZCBwYXR0ZXJuIE1lc2hcIik7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgY2FzZSBcIkR1bW15XCI6XG4gICAgICAgICAgcmV0dXJuIFwiaG90cGlua1wiO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIElSIHR5cGU6ICR7YXJnc1swXX1gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzZXREYXNoKGRhc2hBcnJheSwgZGFzaFBoYXNlKSB7XG4gICAgICB0aGlzLmN1cnJlbnQuZGFzaEFycmF5ID0gZGFzaEFycmF5O1xuICAgICAgdGhpcy5jdXJyZW50LmRhc2hQaGFzZSA9IGRhc2hQaGFzZTtcbiAgICB9XG5cbiAgICBjb25zdHJ1Y3RQYXRoKG9wcywgYXJncykge1xuICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcbiAgICAgIGxldCB4ID0gY3VycmVudC54LFxuICAgICAgICAgIHkgPSBjdXJyZW50Lnk7XG4gICAgICBsZXQgZCA9IFtdO1xuICAgICAgbGV0IGogPSAwO1xuXG4gICAgICBmb3IgKGNvbnN0IG9wIG9mIG9wcykge1xuICAgICAgICBzd2l0Y2ggKG9wIHwgMCkge1xuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLnJlY3RhbmdsZTpcbiAgICAgICAgICAgIHggPSBhcmdzW2orK107XG4gICAgICAgICAgICB5ID0gYXJnc1tqKytdO1xuICAgICAgICAgICAgY29uc3Qgd2lkdGggPSBhcmdzW2orK107XG4gICAgICAgICAgICBjb25zdCBoZWlnaHQgPSBhcmdzW2orK107XG4gICAgICAgICAgICBjb25zdCB4dyA9IHggKyB3aWR0aDtcbiAgICAgICAgICAgIGNvbnN0IHloID0geSArIGhlaWdodDtcbiAgICAgICAgICAgIGQucHVzaChcIk1cIiwgcGYoeCksIHBmKHkpLCBcIkxcIiwgcGYoeHcpLCBwZih5KSwgXCJMXCIsIHBmKHh3KSwgcGYoeWgpLCBcIkxcIiwgcGYoeCksIHBmKHloKSwgXCJaXCIpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5tb3ZlVG86XG4gICAgICAgICAgICB4ID0gYXJnc1tqKytdO1xuICAgICAgICAgICAgeSA9IGFyZ3NbaisrXTtcbiAgICAgICAgICAgIGQucHVzaChcIk1cIiwgcGYoeCksIHBmKHkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBfdXRpbC5PUFMubGluZVRvOlxuICAgICAgICAgICAgeCA9IGFyZ3NbaisrXTtcbiAgICAgICAgICAgIHkgPSBhcmdzW2orK107XG4gICAgICAgICAgICBkLnB1c2goXCJMXCIsIHBmKHgpLCBwZih5KSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLmN1cnZlVG86XG4gICAgICAgICAgICB4ID0gYXJnc1tqICsgNF07XG4gICAgICAgICAgICB5ID0gYXJnc1tqICsgNV07XG4gICAgICAgICAgICBkLnB1c2goXCJDXCIsIHBmKGFyZ3Nbal0pLCBwZihhcmdzW2ogKyAxXSksIHBmKGFyZ3NbaiArIDJdKSwgcGYoYXJnc1tqICsgM10pLCBwZih4KSwgcGYoeSkpO1xuICAgICAgICAgICAgaiArPSA2O1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIF91dGlsLk9QUy5jdXJ2ZVRvMjpcbiAgICAgICAgICAgIGQucHVzaChcIkNcIiwgcGYoeCksIHBmKHkpLCBwZihhcmdzW2pdKSwgcGYoYXJnc1tqICsgMV0pLCBwZihhcmdzW2ogKyAyXSksIHBmKGFyZ3NbaiArIDNdKSk7XG4gICAgICAgICAgICB4ID0gYXJnc1tqICsgMl07XG4gICAgICAgICAgICB5ID0gYXJnc1tqICsgM107XG4gICAgICAgICAgICBqICs9IDQ7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLmN1cnZlVG8zOlxuICAgICAgICAgICAgeCA9IGFyZ3NbaiArIDJdO1xuICAgICAgICAgICAgeSA9IGFyZ3NbaiArIDNdO1xuICAgICAgICAgICAgZC5wdXNoKFwiQ1wiLCBwZihhcmdzW2pdKSwgcGYoYXJnc1tqICsgMV0pLCBwZih4KSwgcGYoeSksIHBmKHgpLCBwZih5KSk7XG4gICAgICAgICAgICBqICs9IDQ7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgX3V0aWwuT1BTLmNsb3NlUGF0aDpcbiAgICAgICAgICAgIGQucHVzaChcIlpcIik7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBkID0gZC5qb2luKFwiIFwiKTtcblxuICAgICAgaWYgKGN1cnJlbnQucGF0aCAmJiBvcHMubGVuZ3RoID4gMCAmJiBvcHNbMF0gIT09IF91dGlsLk9QUy5yZWN0YW5nbGUgJiYgb3BzWzBdICE9PSBfdXRpbC5PUFMubW92ZVRvKSB7XG4gICAgICAgIGQgPSBjdXJyZW50LnBhdGguZ2V0QXR0cmlidXRlTlMobnVsbCwgXCJkXCIpICsgZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGN1cnJlbnQucGF0aCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOnBhdGhcIik7XG5cbiAgICAgICAgdGhpcy5fZW5zdXJlVHJhbnNmb3JtR3JvdXAoKS5hcHBlbmRDaGlsZChjdXJyZW50LnBhdGgpO1xuICAgICAgfVxuXG4gICAgICBjdXJyZW50LnBhdGguc2V0QXR0cmlidXRlTlMobnVsbCwgXCJkXCIsIGQpO1xuICAgICAgY3VycmVudC5wYXRoLnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZmlsbFwiLCBcIm5vbmVcIik7XG4gICAgICBjdXJyZW50LmVsZW1lbnQgPSBjdXJyZW50LnBhdGg7XG4gICAgICBjdXJyZW50LnNldEN1cnJlbnRQb2ludCh4LCB5KTtcbiAgICB9XG5cbiAgICBlbmRQYXRoKCkge1xuICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcbiAgICAgIGN1cnJlbnQucGF0aCA9IG51bGw7XG5cbiAgICAgIGlmICghdGhpcy5wZW5kaW5nQ2xpcCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICghY3VycmVudC5lbGVtZW50KSB7XG4gICAgICAgIHRoaXMucGVuZGluZ0NsaXAgPSBudWxsO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNsaXBJZCA9IGBjbGlwcGF0aCR7Y2xpcENvdW50Kyt9YDtcbiAgICAgIGNvbnN0IGNsaXBQYXRoID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZUVsZW1lbnQoXCJzdmc6Y2xpcFBhdGhcIik7XG4gICAgICBjbGlwUGF0aC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImlkXCIsIGNsaXBJZCk7XG4gICAgICBjbGlwUGF0aC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInRyYW5zZm9ybVwiLCBwbSh0aGlzLnRyYW5zZm9ybU1hdHJpeCkpO1xuICAgICAgY29uc3QgY2xpcEVsZW1lbnQgPSBjdXJyZW50LmVsZW1lbnQuY2xvbmVOb2RlKHRydWUpO1xuXG4gICAgICBpZiAodGhpcy5wZW5kaW5nQ2xpcCA9PT0gXCJldmVub2RkXCIpIHtcbiAgICAgICAgY2xpcEVsZW1lbnQuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJjbGlwLXJ1bGVcIiwgXCJldmVub2RkXCIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2xpcEVsZW1lbnQuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJjbGlwLXJ1bGVcIiwgXCJub256ZXJvXCIpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnBlbmRpbmdDbGlwID0gbnVsbDtcbiAgICAgIGNsaXBQYXRoLmFwcGVuZENoaWxkKGNsaXBFbGVtZW50KTtcbiAgICAgIHRoaXMuZGVmcy5hcHBlbmRDaGlsZChjbGlwUGF0aCk7XG5cbiAgICAgIGlmIChjdXJyZW50LmFjdGl2ZUNsaXBVcmwpIHtcbiAgICAgICAgY3VycmVudC5jbGlwR3JvdXAgPSBudWxsO1xuXG4gICAgICAgIGZvciAoY29uc3QgcHJldiBvZiB0aGlzLmV4dHJhU3RhY2spIHtcbiAgICAgICAgICBwcmV2LmNsaXBHcm91cCA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBjbGlwUGF0aC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImNsaXAtcGF0aFwiLCBjdXJyZW50LmFjdGl2ZUNsaXBVcmwpO1xuICAgICAgfVxuXG4gICAgICBjdXJyZW50LmFjdGl2ZUNsaXBVcmwgPSBgdXJsKCMke2NsaXBJZH0pYDtcbiAgICAgIHRoaXMudGdycCA9IG51bGw7XG4gICAgfVxuXG4gICAgY2xpcCh0eXBlKSB7XG4gICAgICB0aGlzLnBlbmRpbmdDbGlwID0gdHlwZTtcbiAgICB9XG5cbiAgICBjbG9zZVBhdGgoKSB7XG4gICAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5jdXJyZW50O1xuXG4gICAgICBpZiAoY3VycmVudC5wYXRoKSB7XG4gICAgICAgIGNvbnN0IGQgPSBgJHtjdXJyZW50LnBhdGguZ2V0QXR0cmlidXRlTlMobnVsbCwgXCJkXCIpfVpgO1xuICAgICAgICBjdXJyZW50LnBhdGguc2V0QXR0cmlidXRlTlMobnVsbCwgXCJkXCIsIGQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHNldExlYWRpbmcobGVhZGluZykge1xuICAgICAgdGhpcy5jdXJyZW50LmxlYWRpbmcgPSAtbGVhZGluZztcbiAgICB9XG5cbiAgICBzZXRUZXh0UmlzZSh0ZXh0UmlzZSkge1xuICAgICAgdGhpcy5jdXJyZW50LnRleHRSaXNlID0gdGV4dFJpc2U7XG4gICAgfVxuXG4gICAgc2V0VGV4dFJlbmRlcmluZ01vZGUodGV4dFJlbmRlcmluZ01vZGUpIHtcbiAgICAgIHRoaXMuY3VycmVudC50ZXh0UmVuZGVyaW5nTW9kZSA9IHRleHRSZW5kZXJpbmdNb2RlO1xuICAgIH1cblxuICAgIHNldEhTY2FsZShzY2FsZSkge1xuICAgICAgdGhpcy5jdXJyZW50LnRleHRIU2NhbGUgPSBzY2FsZSAvIDEwMDtcbiAgICB9XG5cbiAgICBzZXRSZW5kZXJpbmdJbnRlbnQoaW50ZW50KSB7fVxuXG4gICAgc2V0RmxhdG5lc3MoZmxhdG5lc3MpIHt9XG5cbiAgICBzZXRHU3RhdGUoc3RhdGVzKSB7XG4gICAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBzdGF0ZXMpIHtcbiAgICAgICAgc3dpdGNoIChrZXkpIHtcbiAgICAgICAgICBjYXNlIFwiTFdcIjpcbiAgICAgICAgICAgIHRoaXMuc2V0TGluZVdpZHRoKHZhbHVlKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBcIkxDXCI6XG4gICAgICAgICAgICB0aGlzLnNldExpbmVDYXAodmFsdWUpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFwiTEpcIjpcbiAgICAgICAgICAgIHRoaXMuc2V0TGluZUpvaW4odmFsdWUpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFwiTUxcIjpcbiAgICAgICAgICAgIHRoaXMuc2V0TWl0ZXJMaW1pdCh2YWx1ZSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgXCJEXCI6XG4gICAgICAgICAgICB0aGlzLnNldERhc2godmFsdWVbMF0sIHZhbHVlWzFdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBcIlJJXCI6XG4gICAgICAgICAgICB0aGlzLnNldFJlbmRlcmluZ0ludGVudCh2YWx1ZSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgXCJGTFwiOlxuICAgICAgICAgICAgdGhpcy5zZXRGbGF0bmVzcyh2YWx1ZSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgXCJGb250XCI6XG4gICAgICAgICAgICB0aGlzLnNldEZvbnQodmFsdWUpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFwiQ0FcIjpcbiAgICAgICAgICAgIHRoaXMuc2V0U3Ryb2tlQWxwaGEodmFsdWUpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFwiY2FcIjpcbiAgICAgICAgICAgIHRoaXMuc2V0RmlsbEFscGhhKHZhbHVlKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICgwLCBfdXRpbC53YXJuKShgVW5pbXBsZW1lbnRlZCBncmFwaGljIHN0YXRlIG9wZXJhdG9yICR7a2V5fWApO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBmaWxsKCkge1xuICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcblxuICAgICAgaWYgKGN1cnJlbnQuZWxlbWVudCkge1xuICAgICAgICBjdXJyZW50LmVsZW1lbnQuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJmaWxsXCIsIGN1cnJlbnQuZmlsbENvbG9yKTtcbiAgICAgICAgY3VycmVudC5lbGVtZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZmlsbC1vcGFjaXR5XCIsIGN1cnJlbnQuZmlsbEFscGhhKTtcbiAgICAgICAgdGhpcy5lbmRQYXRoKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgc3Ryb2tlKCkge1xuICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcblxuICAgICAgaWYgKGN1cnJlbnQuZWxlbWVudCkge1xuICAgICAgICB0aGlzLl9zZXRTdHJva2VBdHRyaWJ1dGVzKGN1cnJlbnQuZWxlbWVudCk7XG5cbiAgICAgICAgY3VycmVudC5lbGVtZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZmlsbFwiLCBcIm5vbmVcIik7XG4gICAgICAgIHRoaXMuZW5kUGF0aCgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIF9zZXRTdHJva2VBdHRyaWJ1dGVzKGVsZW1lbnQsIGxpbmVXaWR0aFNjYWxlID0gMSkge1xuICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcbiAgICAgIGxldCBkYXNoQXJyYXkgPSBjdXJyZW50LmRhc2hBcnJheTtcblxuICAgICAgaWYgKGxpbmVXaWR0aFNjYWxlICE9PSAxICYmIGRhc2hBcnJheS5sZW5ndGggPiAwKSB7XG4gICAgICAgIGRhc2hBcnJheSA9IGRhc2hBcnJheS5tYXAoZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgcmV0dXJuIGxpbmVXaWR0aFNjYWxlICogdmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwic3Ryb2tlXCIsIGN1cnJlbnQuc3Ryb2tlQ29sb3IpO1xuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInN0cm9rZS1vcGFjaXR5XCIsIGN1cnJlbnQuc3Ryb2tlQWxwaGEpO1xuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInN0cm9rZS1taXRlcmxpbWl0XCIsIHBmKGN1cnJlbnQubWl0ZXJMaW1pdCkpO1xuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInN0cm9rZS1saW5lY2FwXCIsIGN1cnJlbnQubGluZUNhcCk7XG4gICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwic3Ryb2tlLWxpbmVqb2luXCIsIGN1cnJlbnQubGluZUpvaW4pO1xuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInN0cm9rZS13aWR0aFwiLCBwZihsaW5lV2lkdGhTY2FsZSAqIGN1cnJlbnQubGluZVdpZHRoKSArIFwicHhcIik7XG4gICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwic3Ryb2tlLWRhc2hhcnJheVwiLCBkYXNoQXJyYXkubWFwKHBmKS5qb2luKFwiIFwiKSk7XG4gICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwic3Ryb2tlLWRhc2hvZmZzZXRcIiwgcGYobGluZVdpZHRoU2NhbGUgKiBjdXJyZW50LmRhc2hQaGFzZSkgKyBcInB4XCIpO1xuICAgIH1cblxuICAgIGVvRmlsbCgpIHtcbiAgICAgIGlmICh0aGlzLmN1cnJlbnQuZWxlbWVudCkge1xuICAgICAgICB0aGlzLmN1cnJlbnQuZWxlbWVudC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImZpbGwtcnVsZVwiLCBcImV2ZW5vZGRcIik7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuZmlsbCgpO1xuICAgIH1cblxuICAgIGZpbGxTdHJva2UoKSB7XG4gICAgICB0aGlzLnN0cm9rZSgpO1xuICAgICAgdGhpcy5maWxsKCk7XG4gICAgfVxuXG4gICAgZW9GaWxsU3Ryb2tlKCkge1xuICAgICAgaWYgKHRoaXMuY3VycmVudC5lbGVtZW50KSB7XG4gICAgICAgIHRoaXMuY3VycmVudC5lbGVtZW50LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZmlsbC1ydWxlXCIsIFwiZXZlbm9kZFwiKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5maWxsU3Ryb2tlKCk7XG4gICAgfVxuXG4gICAgY2xvc2VTdHJva2UoKSB7XG4gICAgICB0aGlzLmNsb3NlUGF0aCgpO1xuICAgICAgdGhpcy5zdHJva2UoKTtcbiAgICB9XG5cbiAgICBjbG9zZUZpbGxTdHJva2UoKSB7XG4gICAgICB0aGlzLmNsb3NlUGF0aCgpO1xuICAgICAgdGhpcy5maWxsU3Ryb2tlKCk7XG4gICAgfVxuXG4gICAgY2xvc2VFT0ZpbGxTdHJva2UoKSB7XG4gICAgICB0aGlzLmNsb3NlUGF0aCgpO1xuICAgICAgdGhpcy5lb0ZpbGxTdHJva2UoKTtcbiAgICB9XG5cbiAgICBwYWludFNvbGlkQ29sb3JJbWFnZU1hc2soKSB7XG4gICAgICBjb25zdCByZWN0ID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZUVsZW1lbnQoXCJzdmc6cmVjdFwiKTtcbiAgICAgIHJlY3Quc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ4XCIsIFwiMFwiKTtcbiAgICAgIHJlY3Quc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ5XCIsIFwiMFwiKTtcbiAgICAgIHJlY3Quc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ3aWR0aFwiLCBcIjFweFwiKTtcbiAgICAgIHJlY3Quc2V0QXR0cmlidXRlTlMobnVsbCwgXCJoZWlnaHRcIiwgXCIxcHhcIik7XG4gICAgICByZWN0LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZmlsbFwiLCB0aGlzLmN1cnJlbnQuZmlsbENvbG9yKTtcblxuICAgICAgdGhpcy5fZW5zdXJlVHJhbnNmb3JtR3JvdXAoKS5hcHBlbmRDaGlsZChyZWN0KTtcbiAgICB9XG5cbiAgICBwYWludEltYWdlWE9iamVjdChvYmpJZCkge1xuICAgICAgY29uc3QgaW1nRGF0YSA9IG9iaklkLnN0YXJ0c1dpdGgoXCJnX1wiKSA/IHRoaXMuY29tbW9uT2Jqcy5nZXQob2JqSWQpIDogdGhpcy5vYmpzLmdldChvYmpJZCk7XG5cbiAgICAgIGlmICghaW1nRGF0YSkge1xuICAgICAgICAoMCwgX3V0aWwud2FybikoYERlcGVuZGVudCBpbWFnZSB3aXRoIG9iamVjdCBJRCAke29iaklkfSBpcyBub3QgcmVhZHkgeWV0YCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5wYWludElubGluZUltYWdlWE9iamVjdChpbWdEYXRhKTtcbiAgICB9XG5cbiAgICBwYWludElubGluZUltYWdlWE9iamVjdChpbWdEYXRhLCBtYXNrKSB7XG4gICAgICBjb25zdCB3aWR0aCA9IGltZ0RhdGEud2lkdGg7XG4gICAgICBjb25zdCBoZWlnaHQgPSBpbWdEYXRhLmhlaWdodDtcbiAgICAgIGNvbnN0IGltZ1NyYyA9IGNvbnZlcnRJbWdEYXRhVG9QbmcoaW1nRGF0YSwgdGhpcy5mb3JjZURhdGFTY2hlbWEsICEhbWFzayk7XG4gICAgICBjb25zdCBjbGlwcmVjdCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOnJlY3RcIik7XG4gICAgICBjbGlwcmVjdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInhcIiwgXCIwXCIpO1xuICAgICAgY2xpcHJlY3Quc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ5XCIsIFwiMFwiKTtcbiAgICAgIGNsaXByZWN0LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwid2lkdGhcIiwgcGYod2lkdGgpKTtcbiAgICAgIGNsaXByZWN0LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiaGVpZ2h0XCIsIHBmKGhlaWdodCkpO1xuICAgICAgdGhpcy5jdXJyZW50LmVsZW1lbnQgPSBjbGlwcmVjdDtcbiAgICAgIHRoaXMuY2xpcChcIm5vbnplcm9cIik7XG4gICAgICBjb25zdCBpbWdFbCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOmltYWdlXCIpO1xuICAgICAgaW1nRWwuc2V0QXR0cmlidXRlTlMoWExJTktfTlMsIFwieGxpbms6aHJlZlwiLCBpbWdTcmMpO1xuICAgICAgaW1nRWwuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ4XCIsIFwiMFwiKTtcbiAgICAgIGltZ0VsLnNldEF0dHJpYnV0ZU5TKG51bGwsIFwieVwiLCBwZigtaGVpZ2h0KSk7XG4gICAgICBpbWdFbC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcIndpZHRoXCIsIHBmKHdpZHRoKSArIFwicHhcIik7XG4gICAgICBpbWdFbC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImhlaWdodFwiLCBwZihoZWlnaHQpICsgXCJweFwiKTtcbiAgICAgIGltZ0VsLnNldEF0dHJpYnV0ZU5TKG51bGwsIFwidHJhbnNmb3JtXCIsIGBzY2FsZSgke3BmKDEgLyB3aWR0aCl9ICR7cGYoLTEgLyBoZWlnaHQpfSlgKTtcblxuICAgICAgaWYgKG1hc2spIHtcbiAgICAgICAgbWFzay5hcHBlbmRDaGlsZChpbWdFbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9lbnN1cmVUcmFuc2Zvcm1Hcm91cCgpLmFwcGVuZENoaWxkKGltZ0VsKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwYWludEltYWdlTWFza1hPYmplY3QoaW1nRGF0YSkge1xuICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3VycmVudDtcbiAgICAgIGNvbnN0IHdpZHRoID0gaW1nRGF0YS53aWR0aDtcbiAgICAgIGNvbnN0IGhlaWdodCA9IGltZ0RhdGEuaGVpZ2h0O1xuICAgICAgY29uc3QgZmlsbENvbG9yID0gY3VycmVudC5maWxsQ29sb3I7XG4gICAgICBjdXJyZW50Lm1hc2tJZCA9IGBtYXNrJHttYXNrQ291bnQrK31gO1xuICAgICAgY29uc3QgbWFzayA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOm1hc2tcIik7XG4gICAgICBtYXNrLnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiaWRcIiwgY3VycmVudC5tYXNrSWQpO1xuICAgICAgY29uc3QgcmVjdCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOnJlY3RcIik7XG4gICAgICByZWN0LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwieFwiLCBcIjBcIik7XG4gICAgICByZWN0LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwieVwiLCBcIjBcIik7XG4gICAgICByZWN0LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwid2lkdGhcIiwgcGYod2lkdGgpKTtcbiAgICAgIHJlY3Quc2V0QXR0cmlidXRlTlMobnVsbCwgXCJoZWlnaHRcIiwgcGYoaGVpZ2h0KSk7XG4gICAgICByZWN0LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwiZmlsbFwiLCBmaWxsQ29sb3IpO1xuICAgICAgcmVjdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcIm1hc2tcIiwgYHVybCgjJHtjdXJyZW50Lm1hc2tJZH0pYCk7XG4gICAgICB0aGlzLmRlZnMuYXBwZW5kQ2hpbGQobWFzayk7XG5cbiAgICAgIHRoaXMuX2Vuc3VyZVRyYW5zZm9ybUdyb3VwKCkuYXBwZW5kQ2hpbGQocmVjdCk7XG5cbiAgICAgIHRoaXMucGFpbnRJbmxpbmVJbWFnZVhPYmplY3QoaW1nRGF0YSwgbWFzayk7XG4gICAgfVxuXG4gICAgcGFpbnRGb3JtWE9iamVjdEJlZ2luKG1hdHJpeCwgYmJveCkge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkobWF0cml4KSAmJiBtYXRyaXgubGVuZ3RoID09PSA2KSB7XG4gICAgICAgIHRoaXMudHJhbnNmb3JtKG1hdHJpeFswXSwgbWF0cml4WzFdLCBtYXRyaXhbMl0sIG1hdHJpeFszXSwgbWF0cml4WzRdLCBtYXRyaXhbNV0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoYmJveCkge1xuICAgICAgICBjb25zdCB3aWR0aCA9IGJib3hbMl0gLSBiYm94WzBdO1xuICAgICAgICBjb25zdCBoZWlnaHQgPSBiYm94WzNdIC0gYmJveFsxXTtcbiAgICAgICAgY29uc3QgY2xpcHJlY3QgPSB0aGlzLnN2Z0ZhY3RvcnkuY3JlYXRlRWxlbWVudChcInN2ZzpyZWN0XCIpO1xuICAgICAgICBjbGlwcmVjdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInhcIiwgYmJveFswXSk7XG4gICAgICAgIGNsaXByZWN0LnNldEF0dHJpYnV0ZU5TKG51bGwsIFwieVwiLCBiYm94WzFdKTtcbiAgICAgICAgY2xpcHJlY3Quc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ3aWR0aFwiLCBwZih3aWR0aCkpO1xuICAgICAgICBjbGlwcmVjdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImhlaWdodFwiLCBwZihoZWlnaHQpKTtcbiAgICAgICAgdGhpcy5jdXJyZW50LmVsZW1lbnQgPSBjbGlwcmVjdDtcbiAgICAgICAgdGhpcy5jbGlwKFwibm9uemVyb1wiKTtcbiAgICAgICAgdGhpcy5lbmRQYXRoKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcGFpbnRGb3JtWE9iamVjdEVuZCgpIHt9XG5cbiAgICBfaW5pdGlhbGl6ZSh2aWV3cG9ydCkge1xuICAgICAgY29uc3Qgc3ZnID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZSh2aWV3cG9ydC53aWR0aCwgdmlld3BvcnQuaGVpZ2h0KTtcbiAgICAgIGNvbnN0IGRlZmluaXRpb25zID0gdGhpcy5zdmdGYWN0b3J5LmNyZWF0ZUVsZW1lbnQoXCJzdmc6ZGVmc1wiKTtcbiAgICAgIHN2Zy5hcHBlbmRDaGlsZChkZWZpbml0aW9ucyk7XG4gICAgICB0aGlzLmRlZnMgPSBkZWZpbml0aW9ucztcbiAgICAgIGNvbnN0IHJvb3RHcm91cCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOmdcIik7XG4gICAgICByb290R3JvdXAuc2V0QXR0cmlidXRlTlMobnVsbCwgXCJ0cmFuc2Zvcm1cIiwgcG0odmlld3BvcnQudHJhbnNmb3JtKSk7XG4gICAgICBzdmcuYXBwZW5kQ2hpbGQocm9vdEdyb3VwKTtcbiAgICAgIHRoaXMuc3ZnID0gcm9vdEdyb3VwO1xuICAgICAgcmV0dXJuIHN2ZztcbiAgICB9XG5cbiAgICBfZW5zdXJlQ2xpcEdyb3VwKCkge1xuICAgICAgaWYgKCF0aGlzLmN1cnJlbnQuY2xpcEdyb3VwKSB7XG4gICAgICAgIGNvbnN0IGNsaXBHcm91cCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOmdcIik7XG4gICAgICAgIGNsaXBHcm91cC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcImNsaXAtcGF0aFwiLCB0aGlzLmN1cnJlbnQuYWN0aXZlQ2xpcFVybCk7XG4gICAgICAgIHRoaXMuc3ZnLmFwcGVuZENoaWxkKGNsaXBHcm91cCk7XG4gICAgICAgIHRoaXMuY3VycmVudC5jbGlwR3JvdXAgPSBjbGlwR3JvdXA7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLmN1cnJlbnQuY2xpcEdyb3VwO1xuICAgIH1cblxuICAgIF9lbnN1cmVUcmFuc2Zvcm1Hcm91cCgpIHtcbiAgICAgIGlmICghdGhpcy50Z3JwKSB7XG4gICAgICAgIHRoaXMudGdycCA9IHRoaXMuc3ZnRmFjdG9yeS5jcmVhdGVFbGVtZW50KFwic3ZnOmdcIik7XG4gICAgICAgIHRoaXMudGdycC5zZXRBdHRyaWJ1dGVOUyhudWxsLCBcInRyYW5zZm9ybVwiLCBwbSh0aGlzLnRyYW5zZm9ybU1hdHJpeCkpO1xuXG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnQuYWN0aXZlQ2xpcFVybCkge1xuICAgICAgICAgIHRoaXMuX2Vuc3VyZUNsaXBHcm91cCgpLmFwcGVuZENoaWxkKHRoaXMudGdycCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zdmcuYXBwZW5kQ2hpbGQodGhpcy50Z3JwKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy50Z3JwO1xuICAgIH1cblxuICB9O1xufVxuXG4vKioqLyB9KSxcbi8qIDI1ICovXG4vKioqLyAoKF9fdW51c2VkX3dlYnBhY2tfbW9kdWxlLCBleHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5leHBvcnRzLlBERk5vZGVTdHJlYW0gPSB2b2lkIDA7XG5cbnZhciBfdXRpbCA9IF9fd19wZGZqc19yZXF1aXJlX18oMSk7XG5cbnZhciBfbmV0d29ya191dGlscyA9IF9fd19wZGZqc19yZXF1aXJlX18oMjYpO1xuXG47XG5cbmNvbnN0IGZzID0gcmVxdWlyZShcImZzXCIpO1xuXG5jb25zdCBodHRwID0gcmVxdWlyZShcImh0dHBcIik7XG5cbmNvbnN0IGh0dHBzID0gcmVxdWlyZShcImh0dHBzXCIpO1xuXG5jb25zdCB1cmwgPSByZXF1aXJlKFwidXJsXCIpO1xuXG5jb25zdCBmaWxlVXJpUmVnZXggPSAvXmZpbGU6XFwvXFwvXFwvW2EtekEtWl06XFwvLztcblxuZnVuY3Rpb24gcGFyc2VVcmwoc291cmNlVXJsKSB7XG4gIGNvbnN0IHBhcnNlZFVybCA9IHVybC5wYXJzZShzb3VyY2VVcmwpO1xuXG4gIGlmIChwYXJzZWRVcmwucHJvdG9jb2wgPT09IFwiZmlsZTpcIiB8fCBwYXJzZWRVcmwuaG9zdCkge1xuICAgIHJldHVybiBwYXJzZWRVcmw7XG4gIH1cblxuICBpZiAoL15bYS16XTpbL1xcXFxdL2kudGVzdChzb3VyY2VVcmwpKSB7XG4gICAgcmV0dXJuIHVybC5wYXJzZShgZmlsZTovLy8ke3NvdXJjZVVybH1gKTtcbiAgfVxuXG4gIGlmICghcGFyc2VkVXJsLmhvc3QpIHtcbiAgICBwYXJzZWRVcmwucHJvdG9jb2wgPSBcImZpbGU6XCI7XG4gIH1cblxuICByZXR1cm4gcGFyc2VkVXJsO1xufVxuXG5jbGFzcyBQREZOb2RlU3RyZWFtIHtcbiAgY29uc3RydWN0b3Ioc291cmNlKSB7XG4gICAgdGhpcy5zb3VyY2UgPSBzb3VyY2U7XG4gICAgdGhpcy51cmwgPSBwYXJzZVVybChzb3VyY2UudXJsKTtcbiAgICB0aGlzLmlzSHR0cCA9IHRoaXMudXJsLnByb3RvY29sID09PSBcImh0dHA6XCIgfHwgdGhpcy51cmwucHJvdG9jb2wgPT09IFwiaHR0cHM6XCI7XG4gICAgdGhpcy5pc0ZzVXJsID0gdGhpcy51cmwucHJvdG9jb2wgPT09IFwiZmlsZTpcIjtcbiAgICB0aGlzLmh0dHBIZWFkZXJzID0gdGhpcy5pc0h0dHAgJiYgc291cmNlLmh0dHBIZWFkZXJzIHx8IHt9O1xuICAgIHRoaXMuX2Z1bGxSZXF1ZXN0UmVhZGVyID0gbnVsbDtcbiAgICB0aGlzLl9yYW5nZVJlcXVlc3RSZWFkZXJzID0gW107XG4gIH1cblxuICBnZXQgX3Byb2dyZXNzaXZlRGF0YUxlbmd0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZnVsbFJlcXVlc3RSZWFkZXI/Ll9sb2FkZWQgPz8gMDtcbiAgfVxuXG4gIGdldEZ1bGxSZWFkZXIoKSB7XG4gICAgKDAsIF91dGlsLmFzc2VydCkoIXRoaXMuX2Z1bGxSZXF1ZXN0UmVhZGVyLCBcIlBERk5vZGVTdHJlYW0uZ2V0RnVsbFJlYWRlciBjYW4gb25seSBiZSBjYWxsZWQgb25jZS5cIik7XG4gICAgdGhpcy5fZnVsbFJlcXVlc3RSZWFkZXIgPSB0aGlzLmlzRnNVcmwgPyBuZXcgUERGTm9kZVN0cmVhbUZzRnVsbFJlYWRlcih0aGlzKSA6IG5ldyBQREZOb2RlU3RyZWFtRnVsbFJlYWRlcih0aGlzKTtcbiAgICByZXR1cm4gdGhpcy5fZnVsbFJlcXVlc3RSZWFkZXI7XG4gIH1cblxuICBnZXRSYW5nZVJlYWRlcihzdGFydCwgZW5kKSB7XG4gICAgaWYgKGVuZCA8PSB0aGlzLl9wcm9ncmVzc2l2ZURhdGFMZW5ndGgpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHJhbmdlUmVhZGVyID0gdGhpcy5pc0ZzVXJsID8gbmV3IFBERk5vZGVTdHJlYW1Gc1JhbmdlUmVhZGVyKHRoaXMsIHN0YXJ0LCBlbmQpIDogbmV3IFBERk5vZGVTdHJlYW1SYW5nZVJlYWRlcih0aGlzLCBzdGFydCwgZW5kKTtcblxuICAgIHRoaXMuX3JhbmdlUmVxdWVzdFJlYWRlcnMucHVzaChyYW5nZVJlYWRlcik7XG5cbiAgICByZXR1cm4gcmFuZ2VSZWFkZXI7XG4gIH1cblxuICBjYW5jZWxBbGxSZXF1ZXN0cyhyZWFzb24pIHtcbiAgICBpZiAodGhpcy5fZnVsbFJlcXVlc3RSZWFkZXIpIHtcbiAgICAgIHRoaXMuX2Z1bGxSZXF1ZXN0UmVhZGVyLmNhbmNlbChyZWFzb24pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcmVhZGVyIG9mIHRoaXMuX3JhbmdlUmVxdWVzdFJlYWRlcnMuc2xpY2UoMCkpIHtcbiAgICAgIHJlYWRlci5jYW5jZWwocmVhc29uKTtcbiAgICB9XG4gIH1cblxufVxuXG5leHBvcnRzLlBERk5vZGVTdHJlYW0gPSBQREZOb2RlU3RyZWFtO1xuXG5jbGFzcyBCYXNlRnVsbFJlYWRlciB7XG4gIGNvbnN0cnVjdG9yKHN0cmVhbSkge1xuICAgIHRoaXMuX3VybCA9IHN0cmVhbS51cmw7XG4gICAgdGhpcy5fZG9uZSA9IGZhbHNlO1xuICAgIHRoaXMuX3N0b3JlZEVycm9yID0gbnVsbDtcbiAgICB0aGlzLm9uUHJvZ3Jlc3MgPSBudWxsO1xuICAgIGNvbnN0IHNvdXJjZSA9IHN0cmVhbS5zb3VyY2U7XG4gICAgdGhpcy5fY29udGVudExlbmd0aCA9IHNvdXJjZS5sZW5ndGg7XG4gICAgdGhpcy5fbG9hZGVkID0gMDtcbiAgICB0aGlzLl9maWxlbmFtZSA9IG51bGw7XG4gICAgdGhpcy5fZGlzYWJsZVJhbmdlID0gc291cmNlLmRpc2FibGVSYW5nZSB8fCBmYWxzZTtcbiAgICB0aGlzLl9yYW5nZUNodW5rU2l6ZSA9IHNvdXJjZS5yYW5nZUNodW5rU2l6ZTtcblxuICAgIGlmICghdGhpcy5fcmFuZ2VDaHVua1NpemUgJiYgIXRoaXMuX2Rpc2FibGVSYW5nZSkge1xuICAgICAgdGhpcy5fZGlzYWJsZVJhbmdlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB0aGlzLl9pc1N0cmVhbWluZ1N1cHBvcnRlZCA9ICFzb3VyY2UuZGlzYWJsZVN0cmVhbTtcbiAgICB0aGlzLl9pc1JhbmdlU3VwcG9ydGVkID0gIXNvdXJjZS5kaXNhYmxlUmFuZ2U7XG4gICAgdGhpcy5fcmVhZGFibGVTdHJlYW0gPSBudWxsO1xuICAgIHRoaXMuX3JlYWRDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgIHRoaXMuX2hlYWRlcnNDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICB9XG5cbiAgZ2V0IGhlYWRlcnNSZWFkeSgpIHtcbiAgICByZXR1cm4gdGhpcy5faGVhZGVyc0NhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxuXG4gIGdldCBmaWxlbmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fZmlsZW5hbWU7XG4gIH1cblxuICBnZXQgY29udGVudExlbmd0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5fY29udGVudExlbmd0aDtcbiAgfVxuXG4gIGdldCBpc1JhbmdlU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9pc1JhbmdlU3VwcG9ydGVkO1xuICB9XG5cbiAgZ2V0IGlzU3RyZWFtaW5nU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9pc1N0cmVhbWluZ1N1cHBvcnRlZDtcbiAgfVxuXG4gIGFzeW5jIHJlYWQoKSB7XG4gICAgYXdhaXQgdGhpcy5fcmVhZENhcGFiaWxpdHkucHJvbWlzZTtcblxuICAgIGlmICh0aGlzLl9kb25lKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWx1ZTogdW5kZWZpbmVkLFxuICAgICAgICBkb25lOiB0cnVlXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9zdG9yZWRFcnJvcikge1xuICAgICAgdGhyb3cgdGhpcy5fc3RvcmVkRXJyb3I7XG4gICAgfVxuXG4gICAgY29uc3QgY2h1bmsgPSB0aGlzLl9yZWFkYWJsZVN0cmVhbS5yZWFkKCk7XG5cbiAgICBpZiAoY2h1bmsgPT09IG51bGwpIHtcbiAgICAgIHRoaXMuX3JlYWRDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgICAgcmV0dXJuIHRoaXMucmVhZCgpO1xuICAgIH1cblxuICAgIHRoaXMuX2xvYWRlZCArPSBjaHVuay5sZW5ndGg7XG5cbiAgICBpZiAodGhpcy5vblByb2dyZXNzKSB7XG4gICAgICB0aGlzLm9uUHJvZ3Jlc3Moe1xuICAgICAgICBsb2FkZWQ6IHRoaXMuX2xvYWRlZCxcbiAgICAgICAgdG90YWw6IHRoaXMuX2NvbnRlbnRMZW5ndGhcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KGNodW5rKS5idWZmZXI7XG4gICAgcmV0dXJuIHtcbiAgICAgIHZhbHVlOiBidWZmZXIsXG4gICAgICBkb25lOiBmYWxzZVxuICAgIH07XG4gIH1cblxuICBjYW5jZWwocmVhc29uKSB7XG4gICAgaWYgKCF0aGlzLl9yZWFkYWJsZVN0cmVhbSkge1xuICAgICAgdGhpcy5fZXJyb3IocmVhc29uKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX3JlYWRhYmxlU3RyZWFtLmRlc3Ryb3kocmVhc29uKTtcbiAgfVxuXG4gIF9lcnJvcihyZWFzb24pIHtcbiAgICB0aGlzLl9zdG9yZWRFcnJvciA9IHJlYXNvbjtcblxuICAgIHRoaXMuX3JlYWRDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgfVxuXG4gIF9zZXRSZWFkYWJsZVN0cmVhbShyZWFkYWJsZVN0cmVhbSkge1xuICAgIHRoaXMuX3JlYWRhYmxlU3RyZWFtID0gcmVhZGFibGVTdHJlYW07XG4gICAgcmVhZGFibGVTdHJlYW0ub24oXCJyZWFkYWJsZVwiLCAoKSA9PiB7XG4gICAgICB0aGlzLl9yZWFkQ2FwYWJpbGl0eS5yZXNvbHZlKCk7XG4gICAgfSk7XG4gICAgcmVhZGFibGVTdHJlYW0ub24oXCJlbmRcIiwgKCkgPT4ge1xuICAgICAgcmVhZGFibGVTdHJlYW0uZGVzdHJveSgpO1xuICAgICAgdGhpcy5fZG9uZSA9IHRydWU7XG5cbiAgICAgIHRoaXMuX3JlYWRDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgICB9KTtcbiAgICByZWFkYWJsZVN0cmVhbS5vbihcImVycm9yXCIsIHJlYXNvbiA9PiB7XG4gICAgICB0aGlzLl9lcnJvcihyZWFzb24pO1xuICAgIH0pO1xuXG4gICAgaWYgKCF0aGlzLl9pc1N0cmVhbWluZ1N1cHBvcnRlZCAmJiB0aGlzLl9pc1JhbmdlU3VwcG9ydGVkKSB7XG4gICAgICB0aGlzLl9lcnJvcihuZXcgX3V0aWwuQWJvcnRFeGNlcHRpb24oXCJzdHJlYW1pbmcgaXMgZGlzYWJsZWRcIikpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9zdG9yZWRFcnJvcikge1xuICAgICAgdGhpcy5fcmVhZGFibGVTdHJlYW0uZGVzdHJveSh0aGlzLl9zdG9yZWRFcnJvcik7XG4gICAgfVxuICB9XG5cbn1cblxuY2xhc3MgQmFzZVJhbmdlUmVhZGVyIHtcbiAgY29uc3RydWN0b3Ioc3RyZWFtKSB7XG4gICAgdGhpcy5fdXJsID0gc3RyZWFtLnVybDtcbiAgICB0aGlzLl9kb25lID0gZmFsc2U7XG4gICAgdGhpcy5fc3RvcmVkRXJyb3IgPSBudWxsO1xuICAgIHRoaXMub25Qcm9ncmVzcyA9IG51bGw7XG4gICAgdGhpcy5fbG9hZGVkID0gMDtcbiAgICB0aGlzLl9yZWFkYWJsZVN0cmVhbSA9IG51bGw7XG4gICAgdGhpcy5fcmVhZENhcGFiaWxpdHkgPSAoMCwgX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHkpKCk7XG4gICAgY29uc3Qgc291cmNlID0gc3RyZWFtLnNvdXJjZTtcbiAgICB0aGlzLl9pc1N0cmVhbWluZ1N1cHBvcnRlZCA9ICFzb3VyY2UuZGlzYWJsZVN0cmVhbTtcbiAgfVxuXG4gIGdldCBpc1N0cmVhbWluZ1N1cHBvcnRlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5faXNTdHJlYW1pbmdTdXBwb3J0ZWQ7XG4gIH1cblxuICBhc3luYyByZWFkKCkge1xuICAgIGF3YWl0IHRoaXMuX3JlYWRDYXBhYmlsaXR5LnByb21pc2U7XG5cbiAgICBpZiAodGhpcy5fZG9uZSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgICAgZG9uZTogdHJ1ZVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fc3RvcmVkRXJyb3IpIHtcbiAgICAgIHRocm93IHRoaXMuX3N0b3JlZEVycm9yO1xuICAgIH1cblxuICAgIGNvbnN0IGNodW5rID0gdGhpcy5fcmVhZGFibGVTdHJlYW0ucmVhZCgpO1xuXG4gICAgaWYgKGNodW5rID09PSBudWxsKSB7XG4gICAgICB0aGlzLl9yZWFkQ2FwYWJpbGl0eSA9ICgwLCBfdXRpbC5jcmVhdGVQcm9taXNlQ2FwYWJpbGl0eSkoKTtcbiAgICAgIHJldHVybiB0aGlzLnJlYWQoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2FkZWQgKz0gY2h1bmsubGVuZ3RoO1xuXG4gICAgaWYgKHRoaXMub25Qcm9ncmVzcykge1xuICAgICAgdGhpcy5vblByb2dyZXNzKHtcbiAgICAgICAgbG9hZGVkOiB0aGlzLl9sb2FkZWRcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KGNodW5rKS5idWZmZXI7XG4gICAgcmV0dXJuIHtcbiAgICAgIHZhbHVlOiBidWZmZXIsXG4gICAgICBkb25lOiBmYWxzZVxuICAgIH07XG4gIH1cblxuICBjYW5jZWwocmVhc29uKSB7XG4gICAgaWYgKCF0aGlzLl9yZWFkYWJsZVN0cmVhbSkge1xuICAgICAgdGhpcy5fZXJyb3IocmVhc29uKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX3JlYWRhYmxlU3RyZWFtLmRlc3Ryb3kocmVhc29uKTtcbiAgfVxuXG4gIF9lcnJvcihyZWFzb24pIHtcbiAgICB0aGlzLl9zdG9yZWRFcnJvciA9IHJlYXNvbjtcblxuICAgIHRoaXMuX3JlYWRDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgfVxuXG4gIF9zZXRSZWFkYWJsZVN0cmVhbShyZWFkYWJsZVN0cmVhbSkge1xuICAgIHRoaXMuX3JlYWRhYmxlU3RyZWFtID0gcmVhZGFibGVTdHJlYW07XG4gICAgcmVhZGFibGVTdHJlYW0ub24oXCJyZWFkYWJsZVwiLCAoKSA9PiB7XG4gICAgICB0aGlzLl9yZWFkQ2FwYWJpbGl0eS5yZXNvbHZlKCk7XG4gICAgfSk7XG4gICAgcmVhZGFibGVTdHJlYW0ub24oXCJlbmRcIiwgKCkgPT4ge1xuICAgICAgcmVhZGFibGVTdHJlYW0uZGVzdHJveSgpO1xuICAgICAgdGhpcy5fZG9uZSA9IHRydWU7XG5cbiAgICAgIHRoaXMuX3JlYWRDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgICB9KTtcbiAgICByZWFkYWJsZVN0cmVhbS5vbihcImVycm9yXCIsIHJlYXNvbiA9PiB7XG4gICAgICB0aGlzLl9lcnJvcihyZWFzb24pO1xuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMuX3N0b3JlZEVycm9yKSB7XG4gICAgICB0aGlzLl9yZWFkYWJsZVN0cmVhbS5kZXN0cm95KHRoaXMuX3N0b3JlZEVycm9yKTtcbiAgICB9XG4gIH1cblxufVxuXG5mdW5jdGlvbiBjcmVhdGVSZXF1ZXN0T3B0aW9ucyhwYXJzZWRVcmwsIGhlYWRlcnMpIHtcbiAgcmV0dXJuIHtcbiAgICBwcm90b2NvbDogcGFyc2VkVXJsLnByb3RvY29sLFxuICAgIGF1dGg6IHBhcnNlZFVybC5hdXRoLFxuICAgIGhvc3Q6IHBhcnNlZFVybC5ob3N0bmFtZSxcbiAgICBwb3J0OiBwYXJzZWRVcmwucG9ydCxcbiAgICBwYXRoOiBwYXJzZWRVcmwucGF0aCxcbiAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgaGVhZGVyc1xuICB9O1xufVxuXG5jbGFzcyBQREZOb2RlU3RyZWFtRnVsbFJlYWRlciBleHRlbmRzIEJhc2VGdWxsUmVhZGVyIHtcbiAgY29uc3RydWN0b3Ioc3RyZWFtKSB7XG4gICAgc3VwZXIoc3RyZWFtKTtcblxuICAgIGNvbnN0IGhhbmRsZVJlc3BvbnNlID0gcmVzcG9uc2UgPT4ge1xuICAgICAgaWYgKHJlc3BvbnNlLnN0YXR1c0NvZGUgPT09IDQwNCkge1xuICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBfdXRpbC5NaXNzaW5nUERGRXhjZXB0aW9uKGBNaXNzaW5nIFBERiBcIiR7dGhpcy5fdXJsfVwiLmApO1xuICAgICAgICB0aGlzLl9zdG9yZWRFcnJvciA9IGVycm9yO1xuXG4gICAgICAgIHRoaXMuX2hlYWRlcnNDYXBhYmlsaXR5LnJlamVjdChlcnJvcik7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9oZWFkZXJzQ2FwYWJpbGl0eS5yZXNvbHZlKCk7XG5cbiAgICAgIHRoaXMuX3NldFJlYWRhYmxlU3RyZWFtKHJlc3BvbnNlKTtcblxuICAgICAgY29uc3QgZ2V0UmVzcG9uc2VIZWFkZXIgPSBuYW1lID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlYWRhYmxlU3RyZWFtLmhlYWRlcnNbbmFtZS50b0xvd2VyQ2FzZSgpXTtcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHtcbiAgICAgICAgYWxsb3dSYW5nZVJlcXVlc3RzLFxuICAgICAgICBzdWdnZXN0ZWRMZW5ndGhcbiAgICAgIH0gPSAoMCwgX25ldHdvcmtfdXRpbHMudmFsaWRhdGVSYW5nZVJlcXVlc3RDYXBhYmlsaXRpZXMpKHtcbiAgICAgICAgZ2V0UmVzcG9uc2VIZWFkZXIsXG4gICAgICAgIGlzSHR0cDogc3RyZWFtLmlzSHR0cCxcbiAgICAgICAgcmFuZ2VDaHVua1NpemU6IHRoaXMuX3JhbmdlQ2h1bmtTaXplLFxuICAgICAgICBkaXNhYmxlUmFuZ2U6IHRoaXMuX2Rpc2FibGVSYW5nZVxuICAgICAgfSk7XG4gICAgICB0aGlzLl9pc1JhbmdlU3VwcG9ydGVkID0gYWxsb3dSYW5nZVJlcXVlc3RzO1xuICAgICAgdGhpcy5fY29udGVudExlbmd0aCA9IHN1Z2dlc3RlZExlbmd0aCB8fCB0aGlzLl9jb250ZW50TGVuZ3RoO1xuICAgICAgdGhpcy5fZmlsZW5hbWUgPSAoMCwgX25ldHdvcmtfdXRpbHMuZXh0cmFjdEZpbGVuYW1lRnJvbUhlYWRlcikoZ2V0UmVzcG9uc2VIZWFkZXIpO1xuICAgIH07XG5cbiAgICB0aGlzLl9yZXF1ZXN0ID0gbnVsbDtcblxuICAgIGlmICh0aGlzLl91cmwucHJvdG9jb2wgPT09IFwiaHR0cDpcIikge1xuICAgICAgdGhpcy5fcmVxdWVzdCA9IGh0dHAucmVxdWVzdChjcmVhdGVSZXF1ZXN0T3B0aW9ucyh0aGlzLl91cmwsIHN0cmVhbS5odHRwSGVhZGVycyksIGhhbmRsZVJlc3BvbnNlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fcmVxdWVzdCA9IGh0dHBzLnJlcXVlc3QoY3JlYXRlUmVxdWVzdE9wdGlvbnModGhpcy5fdXJsLCBzdHJlYW0uaHR0cEhlYWRlcnMpLCBoYW5kbGVSZXNwb25zZSk7XG4gICAgfVxuXG4gICAgdGhpcy5fcmVxdWVzdC5vbihcImVycm9yXCIsIHJlYXNvbiA9PiB7XG4gICAgICB0aGlzLl9zdG9yZWRFcnJvciA9IHJlYXNvbjtcblxuICAgICAgdGhpcy5faGVhZGVyc0NhcGFiaWxpdHkucmVqZWN0KHJlYXNvbik7XG4gICAgfSk7XG5cbiAgICB0aGlzLl9yZXF1ZXN0LmVuZCgpO1xuICB9XG5cbn1cblxuY2xhc3MgUERGTm9kZVN0cmVhbVJhbmdlUmVhZGVyIGV4dGVuZHMgQmFzZVJhbmdlUmVhZGVyIHtcbiAgY29uc3RydWN0b3Ioc3RyZWFtLCBzdGFydCwgZW5kKSB7XG4gICAgc3VwZXIoc3RyZWFtKTtcbiAgICB0aGlzLl9odHRwSGVhZGVycyA9IHt9O1xuXG4gICAgZm9yIChjb25zdCBwcm9wZXJ0eSBpbiBzdHJlYW0uaHR0cEhlYWRlcnMpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gc3RyZWFtLmh0dHBIZWFkZXJzW3Byb3BlcnR5XTtcblxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5faHR0cEhlYWRlcnNbcHJvcGVydHldID0gdmFsdWU7XG4gICAgfVxuXG4gICAgdGhpcy5faHR0cEhlYWRlcnMuUmFuZ2UgPSBgYnl0ZXM9JHtzdGFydH0tJHtlbmQgLSAxfWA7XG5cbiAgICBjb25zdCBoYW5kbGVSZXNwb25zZSA9IHJlc3BvbnNlID0+IHtcbiAgICAgIGlmIChyZXNwb25zZS5zdGF0dXNDb2RlID09PSA0MDQpIHtcbiAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgX3V0aWwuTWlzc2luZ1BERkV4Y2VwdGlvbihgTWlzc2luZyBQREYgXCIke3RoaXMuX3VybH1cIi5gKTtcbiAgICAgICAgdGhpcy5fc3RvcmVkRXJyb3IgPSBlcnJvcjtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9zZXRSZWFkYWJsZVN0cmVhbShyZXNwb25zZSk7XG4gICAgfTtcblxuICAgIHRoaXMuX3JlcXVlc3QgPSBudWxsO1xuXG4gICAgaWYgKHRoaXMuX3VybC5wcm90b2NvbCA9PT0gXCJodHRwOlwiKSB7XG4gICAgICB0aGlzLl9yZXF1ZXN0ID0gaHR0cC5yZXF1ZXN0KGNyZWF0ZVJlcXVlc3RPcHRpb25zKHRoaXMuX3VybCwgdGhpcy5faHR0cEhlYWRlcnMpLCBoYW5kbGVSZXNwb25zZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3JlcXVlc3QgPSBodHRwcy5yZXF1ZXN0KGNyZWF0ZVJlcXVlc3RPcHRpb25zKHRoaXMuX3VybCwgdGhpcy5faHR0cEhlYWRlcnMpLCBoYW5kbGVSZXNwb25zZSk7XG4gICAgfVxuXG4gICAgdGhpcy5fcmVxdWVzdC5vbihcImVycm9yXCIsIHJlYXNvbiA9PiB7XG4gICAgICB0aGlzLl9zdG9yZWRFcnJvciA9IHJlYXNvbjtcbiAgICB9KTtcblxuICAgIHRoaXMuX3JlcXVlc3QuZW5kKCk7XG4gIH1cblxufVxuXG5jbGFzcyBQREZOb2RlU3RyZWFtRnNGdWxsUmVhZGVyIGV4dGVuZHMgQmFzZUZ1bGxSZWFkZXIge1xuICBjb25zdHJ1Y3RvcihzdHJlYW0pIHtcbiAgICBzdXBlcihzdHJlYW0pO1xuICAgIGxldCBwYXRoID0gZGVjb2RlVVJJQ29tcG9uZW50KHRoaXMuX3VybC5wYXRoKTtcblxuICAgIGlmIChmaWxlVXJpUmVnZXgudGVzdCh0aGlzLl91cmwuaHJlZikpIHtcbiAgICAgIHBhdGggPSBwYXRoLnJlcGxhY2UoL15cXC8vLCBcIlwiKTtcbiAgICB9XG5cbiAgICBmcy5sc3RhdChwYXRoLCAoZXJyb3IsIHN0YXQpID0+IHtcbiAgICAgIGlmIChlcnJvcikge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gXCJFTk9FTlRcIikge1xuICAgICAgICAgIGVycm9yID0gbmV3IF91dGlsLk1pc3NpbmdQREZFeGNlcHRpb24oYE1pc3NpbmcgUERGIFwiJHtwYXRofVwiLmApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fc3RvcmVkRXJyb3IgPSBlcnJvcjtcblxuICAgICAgICB0aGlzLl9oZWFkZXJzQ2FwYWJpbGl0eS5yZWplY3QoZXJyb3IpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fY29udGVudExlbmd0aCA9IHN0YXQuc2l6ZTtcblxuICAgICAgdGhpcy5fc2V0UmVhZGFibGVTdHJlYW0oZnMuY3JlYXRlUmVhZFN0cmVhbShwYXRoKSk7XG5cbiAgICAgIHRoaXMuX2hlYWRlcnNDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgICB9KTtcbiAgfVxuXG59XG5cbmNsYXNzIFBERk5vZGVTdHJlYW1Gc1JhbmdlUmVhZGVyIGV4dGVuZHMgQmFzZVJhbmdlUmVhZGVyIHtcbiAgY29uc3RydWN0b3Ioc3RyZWFtLCBzdGFydCwgZW5kKSB7XG4gICAgc3VwZXIoc3RyZWFtKTtcbiAgICBsZXQgcGF0aCA9IGRlY29kZVVSSUNvbXBvbmVudCh0aGlzLl91cmwucGF0aCk7XG5cbiAgICBpZiAoZmlsZVVyaVJlZ2V4LnRlc3QodGhpcy5fdXJsLmhyZWYpKSB7XG4gICAgICBwYXRoID0gcGF0aC5yZXBsYWNlKC9eXFwvLywgXCJcIik7XG4gICAgfVxuXG4gICAgdGhpcy5fc2V0UmVhZGFibGVTdHJlYW0oZnMuY3JlYXRlUmVhZFN0cmVhbShwYXRoLCB7XG4gICAgICBzdGFydCxcbiAgICAgIGVuZDogZW5kIC0gMVxuICAgIH0pKTtcbiAgfVxuXG59XG5cbi8qKiovIH0pLFxuLyogMjYgKi9cbi8qKiovICgoX191bnVzZWRfd2VicGFja19tb2R1bGUsIGV4cG9ydHMsIF9fd19wZGZqc19yZXF1aXJlX18pID0+IHtcblxuXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgKHtcbiAgdmFsdWU6IHRydWVcbn0pKTtcbmV4cG9ydHMuY3JlYXRlUmVzcG9uc2VTdGF0dXNFcnJvciA9IGNyZWF0ZVJlc3BvbnNlU3RhdHVzRXJyb3I7XG5leHBvcnRzLmV4dHJhY3RGaWxlbmFtZUZyb21IZWFkZXIgPSBleHRyYWN0RmlsZW5hbWVGcm9tSGVhZGVyO1xuZXhwb3J0cy52YWxpZGF0ZVJhbmdlUmVxdWVzdENhcGFiaWxpdGllcyA9IHZhbGlkYXRlUmFuZ2VSZXF1ZXN0Q2FwYWJpbGl0aWVzO1xuZXhwb3J0cy52YWxpZGF0ZVJlc3BvbnNlU3RhdHVzID0gdmFsaWRhdGVSZXNwb25zZVN0YXR1cztcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxudmFyIF9jb250ZW50X2Rpc3Bvc2l0aW9uID0gX193X3BkZmpzX3JlcXVpcmVfXygyNyk7XG5cbnZhciBfZGlzcGxheV91dGlscyA9IF9fd19wZGZqc19yZXF1aXJlX18oNSk7XG5cbmZ1bmN0aW9uIHZhbGlkYXRlUmFuZ2VSZXF1ZXN0Q2FwYWJpbGl0aWVzKHtcbiAgZ2V0UmVzcG9uc2VIZWFkZXIsXG4gIGlzSHR0cCxcbiAgcmFuZ2VDaHVua1NpemUsXG4gIGRpc2FibGVSYW5nZVxufSkge1xuICBjb25zdCByZXR1cm5WYWx1ZXMgPSB7XG4gICAgYWxsb3dSYW5nZVJlcXVlc3RzOiBmYWxzZSxcbiAgICBzdWdnZXN0ZWRMZW5ndGg6IHVuZGVmaW5lZFxuICB9O1xuICBjb25zdCBsZW5ndGggPSBwYXJzZUludChnZXRSZXNwb25zZUhlYWRlcihcIkNvbnRlbnQtTGVuZ3RoXCIpLCAxMCk7XG5cbiAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKGxlbmd0aCkpIHtcbiAgICByZXR1cm4gcmV0dXJuVmFsdWVzO1xuICB9XG5cbiAgcmV0dXJuVmFsdWVzLnN1Z2dlc3RlZExlbmd0aCA9IGxlbmd0aDtcblxuICBpZiAobGVuZ3RoIDw9IDIgKiByYW5nZUNodW5rU2l6ZSkge1xuICAgIHJldHVybiByZXR1cm5WYWx1ZXM7XG4gIH1cblxuICBpZiAoZGlzYWJsZVJhbmdlIHx8ICFpc0h0dHApIHtcbiAgICByZXR1cm4gcmV0dXJuVmFsdWVzO1xuICB9XG5cbiAgaWYgKGdldFJlc3BvbnNlSGVhZGVyKFwiQWNjZXB0LVJhbmdlc1wiKSAhPT0gXCJieXRlc1wiKSB7XG4gICAgcmV0dXJuIHJldHVyblZhbHVlcztcbiAgfVxuXG4gIGNvbnN0IGNvbnRlbnRFbmNvZGluZyA9IGdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1FbmNvZGluZ1wiKSB8fCBcImlkZW50aXR5XCI7XG5cbiAgaWYgKGNvbnRlbnRFbmNvZGluZyAhPT0gXCJpZGVudGl0eVwiKSB7XG4gICAgcmV0dXJuIHJldHVyblZhbHVlcztcbiAgfVxuXG4gIHJldHVyblZhbHVlcy5hbGxvd1JhbmdlUmVxdWVzdHMgPSB0cnVlO1xuICByZXR1cm4gcmV0dXJuVmFsdWVzO1xufVxuXG5mdW5jdGlvbiBleHRyYWN0RmlsZW5hbWVGcm9tSGVhZGVyKGdldFJlc3BvbnNlSGVhZGVyKSB7XG4gIGNvbnN0IGNvbnRlbnREaXNwb3NpdGlvbiA9IGdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1EaXNwb3NpdGlvblwiKTtcblxuICBpZiAoY29udGVudERpc3Bvc2l0aW9uKSB7XG4gICAgbGV0IGZpbGVuYW1lID0gKDAsIF9jb250ZW50X2Rpc3Bvc2l0aW9uLmdldEZpbGVuYW1lRnJvbUNvbnRlbnREaXNwb3NpdGlvbkhlYWRlcikoY29udGVudERpc3Bvc2l0aW9uKTtcblxuICAgIGlmIChmaWxlbmFtZS5pbmNsdWRlcyhcIiVcIikpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGZpbGVuYW1lID0gZGVjb2RlVVJJQ29tcG9uZW50KGZpbGVuYW1lKTtcbiAgICAgIH0gY2F0Y2ggKGV4KSB7fVxuICAgIH1cblxuICAgIGlmICgoMCwgX2Rpc3BsYXlfdXRpbHMuaXNQZGZGaWxlKShmaWxlbmFtZSkpIHtcbiAgICAgIHJldHVybiBmaWxlbmFtZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gY3JlYXRlUmVzcG9uc2VTdGF0dXNFcnJvcihzdGF0dXMsIHVybCkge1xuICBpZiAoc3RhdHVzID09PSA0MDQgfHwgc3RhdHVzID09PSAwICYmIHVybC5zdGFydHNXaXRoKFwiZmlsZTpcIikpIHtcbiAgICByZXR1cm4gbmV3IF91dGlsLk1pc3NpbmdQREZFeGNlcHRpb24oJ01pc3NpbmcgUERGIFwiJyArIHVybCArICdcIi4nKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgX3V0aWwuVW5leHBlY3RlZFJlc3BvbnNlRXhjZXB0aW9uKGBVbmV4cGVjdGVkIHNlcnZlciByZXNwb25zZSAoJHtzdGF0dXN9KSB3aGlsZSByZXRyaWV2aW5nIFBERiBcIiR7dXJsfVwiLmAsIHN0YXR1cyk7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlUmVzcG9uc2VTdGF0dXMoc3RhdHVzKSB7XG4gIHJldHVybiBzdGF0dXMgPT09IDIwMCB8fCBzdGF0dXMgPT09IDIwNjtcbn1cblxuLyoqKi8gfSksXG4vKiAyNyAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5nZXRGaWxlbmFtZUZyb21Db250ZW50RGlzcG9zaXRpb25IZWFkZXIgPSBnZXRGaWxlbmFtZUZyb21Db250ZW50RGlzcG9zaXRpb25IZWFkZXI7XG5cbnZhciBfdXRpbCA9IF9fd19wZGZqc19yZXF1aXJlX18oMSk7XG5cbmZ1bmN0aW9uIGdldEZpbGVuYW1lRnJvbUNvbnRlbnREaXNwb3NpdGlvbkhlYWRlcihjb250ZW50RGlzcG9zaXRpb24pIHtcbiAgbGV0IG5lZWRzRW5jb2RpbmdGaXh1cCA9IHRydWU7XG4gIGxldCB0bXAgPSB0b1BhcmFtUmVnRXhwKFwiZmlsZW5hbWVcXFxcKlwiLCBcImlcIikuZXhlYyhjb250ZW50RGlzcG9zaXRpb24pO1xuXG4gIGlmICh0bXApIHtcbiAgICB0bXAgPSB0bXBbMV07XG4gICAgbGV0IGZpbGVuYW1lID0gcmZjMjYxNnVucXVvdGUodG1wKTtcbiAgICBmaWxlbmFtZSA9IHVuZXNjYXBlKGZpbGVuYW1lKTtcbiAgICBmaWxlbmFtZSA9IHJmYzU5ODdkZWNvZGUoZmlsZW5hbWUpO1xuICAgIGZpbGVuYW1lID0gcmZjMjA0N2RlY29kZShmaWxlbmFtZSk7XG4gICAgcmV0dXJuIGZpeHVwRW5jb2RpbmcoZmlsZW5hbWUpO1xuICB9XG5cbiAgdG1wID0gcmZjMjIzMWdldHBhcmFtKGNvbnRlbnREaXNwb3NpdGlvbik7XG5cbiAgaWYgKHRtcCkge1xuICAgIGNvbnN0IGZpbGVuYW1lID0gcmZjMjA0N2RlY29kZSh0bXApO1xuICAgIHJldHVybiBmaXh1cEVuY29kaW5nKGZpbGVuYW1lKTtcbiAgfVxuXG4gIHRtcCA9IHRvUGFyYW1SZWdFeHAoXCJmaWxlbmFtZVwiLCBcImlcIikuZXhlYyhjb250ZW50RGlzcG9zaXRpb24pO1xuXG4gIGlmICh0bXApIHtcbiAgICB0bXAgPSB0bXBbMV07XG4gICAgbGV0IGZpbGVuYW1lID0gcmZjMjYxNnVucXVvdGUodG1wKTtcbiAgICBmaWxlbmFtZSA9IHJmYzIwNDdkZWNvZGUoZmlsZW5hbWUpO1xuICAgIHJldHVybiBmaXh1cEVuY29kaW5nKGZpbGVuYW1lKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRvUGFyYW1SZWdFeHAoYXR0cmlidXRlUGF0dGVybiwgZmxhZ3MpIHtcbiAgICByZXR1cm4gbmV3IFJlZ0V4cChcIig/Ol58OylcXFxccypcIiArIGF0dHJpYnV0ZVBhdHRlcm4gKyBcIlxcXFxzKj1cXFxccypcIiArIFwiKFwiICsgJ1teXCI7XFxcXHNdW147XFxcXHNdKicgKyBcInxcIiArICdcIig/OlteXCJcXFxcXFxcXF18XFxcXFxcXFxcIj8pK1wiPycgKyBcIilcIiwgZmxhZ3MpO1xuICB9XG5cbiAgZnVuY3Rpb24gdGV4dGRlY29kZShlbmNvZGluZywgdmFsdWUpIHtcbiAgICBpZiAoZW5jb2RpbmcpIHtcbiAgICAgIGlmICghL15bXFx4MDAtXFx4RkZdKyQvLnRlc3QodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcihlbmNvZGluZywge1xuICAgICAgICAgIGZhdGFsOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBidWZmZXIgPSAoMCwgX3V0aWwuc3RyaW5nVG9CeXRlcykodmFsdWUpO1xuICAgICAgICB2YWx1ZSA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlcik7XG4gICAgICAgIG5lZWRzRW5jb2RpbmdGaXh1cCA9IGZhbHNlO1xuICAgICAgfSBjYXRjaCAoZSkge31cbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBmdW5jdGlvbiBmaXh1cEVuY29kaW5nKHZhbHVlKSB7XG4gICAgaWYgKG5lZWRzRW5jb2RpbmdGaXh1cCAmJiAvW1xceDgwLVxceGZmXS8udGVzdCh2YWx1ZSkpIHtcbiAgICAgIHZhbHVlID0gdGV4dGRlY29kZShcInV0Zi04XCIsIHZhbHVlKTtcblxuICAgICAgaWYgKG5lZWRzRW5jb2RpbmdGaXh1cCkge1xuICAgICAgICB2YWx1ZSA9IHRleHRkZWNvZGUoXCJpc28tODg1OS0xXCIsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBmdW5jdGlvbiByZmMyMjMxZ2V0cGFyYW0oY29udGVudERpc3Bvc2l0aW9uU3RyKSB7XG4gICAgY29uc3QgbWF0Y2hlcyA9IFtdO1xuICAgIGxldCBtYXRjaDtcbiAgICBjb25zdCBpdGVyID0gdG9QYXJhbVJlZ0V4cChcImZpbGVuYW1lXFxcXCooKD8hMFxcXFxkKVxcXFxkKykoXFxcXCo/KVwiLCBcImlnXCIpO1xuXG4gICAgd2hpbGUgKChtYXRjaCA9IGl0ZXIuZXhlYyhjb250ZW50RGlzcG9zaXRpb25TdHIpKSAhPT0gbnVsbCkge1xuICAgICAgbGV0IFssIG4sIHF1b3QsIHBhcnRdID0gbWF0Y2g7XG4gICAgICBuID0gcGFyc2VJbnQobiwgMTApO1xuXG4gICAgICBpZiAobiBpbiBtYXRjaGVzKSB7XG4gICAgICAgIGlmIChuID09PSAwKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgbWF0Y2hlc1tuXSA9IFtxdW90LCBwYXJ0XTtcbiAgICB9XG5cbiAgICBjb25zdCBwYXJ0cyA9IFtdO1xuXG4gICAgZm9yIChsZXQgbiA9IDA7IG4gPCBtYXRjaGVzLmxlbmd0aDsgKytuKSB7XG4gICAgICBpZiAoIShuIGluIG1hdGNoZXMpKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBsZXQgW3F1b3QsIHBhcnRdID0gbWF0Y2hlc1tuXTtcbiAgICAgIHBhcnQgPSByZmMyNjE2dW5xdW90ZShwYXJ0KTtcblxuICAgICAgaWYgKHF1b3QpIHtcbiAgICAgICAgcGFydCA9IHVuZXNjYXBlKHBhcnQpO1xuXG4gICAgICAgIGlmIChuID09PSAwKSB7XG4gICAgICAgICAgcGFydCA9IHJmYzU5ODdkZWNvZGUocGFydCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcGFydHMucHVzaChwYXJ0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFydHMuam9pbihcIlwiKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJmYzI2MTZ1bnF1b3RlKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlLnN0YXJ0c1dpdGgoJ1wiJykpIHtcbiAgICAgIGNvbnN0IHBhcnRzID0gdmFsdWUuc2xpY2UoMSkuc3BsaXQoJ1xcXFxcIicpO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGNvbnN0IHF1b3RpbmRleCA9IHBhcnRzW2ldLmluZGV4T2YoJ1wiJyk7XG5cbiAgICAgICAgaWYgKHF1b3RpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICBwYXJ0c1tpXSA9IHBhcnRzW2ldLnNsaWNlKDAsIHF1b3RpbmRleCk7XG4gICAgICAgICAgcGFydHMubGVuZ3RoID0gaSArIDE7XG4gICAgICAgIH1cblxuICAgICAgICBwYXJ0c1tpXSA9IHBhcnRzW2ldLnJlcGxhY2UoL1xcXFwoLikvZywgXCIkMVwiKTtcbiAgICAgIH1cblxuICAgICAgdmFsdWUgPSBwYXJ0cy5qb2luKCdcIicpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJmYzU5ODdkZWNvZGUoZXh0dmFsdWUpIHtcbiAgICBjb25zdCBlbmNvZGluZ2VuZCA9IGV4dHZhbHVlLmluZGV4T2YoXCInXCIpO1xuXG4gICAgaWYgKGVuY29kaW5nZW5kID09PSAtMSkge1xuICAgICAgcmV0dXJuIGV4dHZhbHVlO1xuICAgIH1cblxuICAgIGNvbnN0IGVuY29kaW5nID0gZXh0dmFsdWUuc2xpY2UoMCwgZW5jb2RpbmdlbmQpO1xuICAgIGNvbnN0IGxhbmd2YWx1ZSA9IGV4dHZhbHVlLnNsaWNlKGVuY29kaW5nZW5kICsgMSk7XG4gICAgY29uc3QgdmFsdWUgPSBsYW5ndmFsdWUucmVwbGFjZSgvXlteJ10qJy8sIFwiXCIpO1xuICAgIHJldHVybiB0ZXh0ZGVjb2RlKGVuY29kaW5nLCB2YWx1ZSk7XG4gIH1cblxuICBmdW5jdGlvbiByZmMyMDQ3ZGVjb2RlKHZhbHVlKSB7XG4gICAgaWYgKCF2YWx1ZS5zdGFydHNXaXRoKFwiPT9cIikgfHwgL1tcXHgwMC1cXHgxOVxceDgwLVxceGZmXS8udGVzdCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWUucmVwbGFjZSgvPVxcPyhbXFx3LV0qKVxcPyhbUXFCYl0pXFw/KCg/OlteP118XFw/KD8hPSkpKilcXD89L2csIGZ1bmN0aW9uIChtYXRjaGVzLCBjaGFyc2V0LCBlbmNvZGluZywgdGV4dCkge1xuICAgICAgaWYgKGVuY29kaW5nID09PSBcInFcIiB8fCBlbmNvZGluZyA9PT0gXCJRXCIpIHtcbiAgICAgICAgdGV4dCA9IHRleHQucmVwbGFjZSgvXy9nLCBcIiBcIik7XG4gICAgICAgIHRleHQgPSB0ZXh0LnJlcGxhY2UoLz0oWzAtOWEtZkEtRl17Mn0pL2csIGZ1bmN0aW9uIChtYXRjaCwgaGV4KSB7XG4gICAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUocGFyc2VJbnQoaGV4LCAxNikpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRleHRkZWNvZGUoY2hhcnNldCwgdGV4dCk7XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHRleHQgPSBhdG9iKHRleHQpO1xuICAgICAgfSBjYXRjaCAoZSkge31cblxuICAgICAgcmV0dXJuIHRleHRkZWNvZGUoY2hhcnNldCwgdGV4dCk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gXCJcIjtcbn1cblxuLyoqKi8gfSksXG4vKiAyOCAqL1xuLyoqKi8gKChfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXykgPT4ge1xuXG5cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCAoe1xuICB2YWx1ZTogdHJ1ZVxufSkpO1xuZXhwb3J0cy5QREZOZXR3b3JrU3RyZWFtID0gdm9pZCAwO1xuXG52YXIgX3V0aWwgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDEpO1xuXG52YXIgX25ldHdvcmtfdXRpbHMgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDI2KTtcblxuO1xuY29uc3QgT0tfUkVTUE9OU0UgPSAyMDA7XG5jb25zdCBQQVJUSUFMX0NPTlRFTlRfUkVTUE9OU0UgPSAyMDY7XG5cbmZ1bmN0aW9uIGdldEFycmF5QnVmZmVyKHhocikge1xuICBjb25zdCBkYXRhID0geGhyLnJlc3BvbnNlO1xuXG4gIGlmICh0eXBlb2YgZGF0YSAhPT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgY29uc3QgYXJyYXkgPSAoMCwgX3V0aWwuc3RyaW5nVG9CeXRlcykoZGF0YSk7XG4gIHJldHVybiBhcnJheS5idWZmZXI7XG59XG5cbmNsYXNzIE5ldHdvcmtNYW5hZ2VyIHtcbiAgY29uc3RydWN0b3IodXJsLCBhcmdzID0ge30pIHtcbiAgICB0aGlzLnVybCA9IHVybDtcbiAgICB0aGlzLmlzSHR0cCA9IC9eaHR0cHM/Oi9pLnRlc3QodXJsKTtcbiAgICB0aGlzLmh0dHBIZWFkZXJzID0gdGhpcy5pc0h0dHAgJiYgYXJncy5odHRwSGVhZGVycyB8fCBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMud2l0aENyZWRlbnRpYWxzID0gYXJncy53aXRoQ3JlZGVudGlhbHMgfHwgZmFsc2U7XG5cbiAgICB0aGlzLmdldFhociA9IGFyZ3MuZ2V0WGhyIHx8IGZ1bmN0aW9uIE5ldHdvcmtNYW5hZ2VyX2dldFhocigpIHtcbiAgICAgIHJldHVybiBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICB9O1xuXG4gICAgdGhpcy5jdXJyWGhySWQgPSAwO1xuICAgIHRoaXMucGVuZGluZ1JlcXVlc3RzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgfVxuXG4gIHJlcXVlc3RSYW5nZShiZWdpbiwgZW5kLCBsaXN0ZW5lcnMpIHtcbiAgICBjb25zdCBhcmdzID0ge1xuICAgICAgYmVnaW4sXG4gICAgICBlbmRcbiAgICB9O1xuXG4gICAgZm9yIChjb25zdCBwcm9wIGluIGxpc3RlbmVycykge1xuICAgICAgYXJnc1twcm9wXSA9IGxpc3RlbmVyc1twcm9wXTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KGFyZ3MpO1xuICB9XG5cbiAgcmVxdWVzdEZ1bGwobGlzdGVuZXJzKSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdChsaXN0ZW5lcnMpO1xuICB9XG5cbiAgcmVxdWVzdChhcmdzKSB7XG4gICAgY29uc3QgeGhyID0gdGhpcy5nZXRYaHIoKTtcbiAgICBjb25zdCB4aHJJZCA9IHRoaXMuY3VyclhocklkKys7XG4gICAgY29uc3QgcGVuZGluZ1JlcXVlc3QgPSB0aGlzLnBlbmRpbmdSZXF1ZXN0c1t4aHJJZF0gPSB7XG4gICAgICB4aHJcbiAgICB9O1xuICAgIHhoci5vcGVuKFwiR0VUXCIsIHRoaXMudXJsKTtcbiAgICB4aHIud2l0aENyZWRlbnRpYWxzID0gdGhpcy53aXRoQ3JlZGVudGlhbHM7XG5cbiAgICBmb3IgKGNvbnN0IHByb3BlcnR5IGluIHRoaXMuaHR0cEhlYWRlcnMpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5odHRwSGVhZGVyc1twcm9wZXJ0eV07XG5cbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKHByb3BlcnR5LCB2YWx1ZSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNIdHRwICYmIFwiYmVnaW5cIiBpbiBhcmdzICYmIFwiZW5kXCIgaW4gYXJncykge1xuICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoXCJSYW5nZVwiLCBgYnl0ZXM9JHthcmdzLmJlZ2lufS0ke2FyZ3MuZW5kIC0gMX1gKTtcbiAgICAgIHBlbmRpbmdSZXF1ZXN0LmV4cGVjdGVkU3RhdHVzID0gUEFSVElBTF9DT05URU5UX1JFU1BPTlNFO1xuICAgIH0gZWxzZSB7XG4gICAgICBwZW5kaW5nUmVxdWVzdC5leHBlY3RlZFN0YXR1cyA9IE9LX1JFU1BPTlNFO1xuICAgIH1cblxuICAgIHhoci5yZXNwb25zZVR5cGUgPSBcImFycmF5YnVmZmVyXCI7XG5cbiAgICBpZiAoYXJncy5vbkVycm9yKSB7XG4gICAgICB4aHIub25lcnJvciA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgYXJncy5vbkVycm9yKHhoci5zdGF0dXMpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gdGhpcy5vblN0YXRlQ2hhbmdlLmJpbmQodGhpcywgeGhySWQpO1xuICAgIHhoci5vbnByb2dyZXNzID0gdGhpcy5vblByb2dyZXNzLmJpbmQodGhpcywgeGhySWQpO1xuICAgIHBlbmRpbmdSZXF1ZXN0Lm9uSGVhZGVyc1JlY2VpdmVkID0gYXJncy5vbkhlYWRlcnNSZWNlaXZlZDtcbiAgICBwZW5kaW5nUmVxdWVzdC5vbkRvbmUgPSBhcmdzLm9uRG9uZTtcbiAgICBwZW5kaW5nUmVxdWVzdC5vbkVycm9yID0gYXJncy5vbkVycm9yO1xuICAgIHBlbmRpbmdSZXF1ZXN0Lm9uUHJvZ3Jlc3MgPSBhcmdzLm9uUHJvZ3Jlc3M7XG4gICAgeGhyLnNlbmQobnVsbCk7XG4gICAgcmV0dXJuIHhocklkO1xuICB9XG5cbiAgb25Qcm9ncmVzcyh4aHJJZCwgZXZ0KSB7XG4gICAgY29uc3QgcGVuZGluZ1JlcXVlc3QgPSB0aGlzLnBlbmRpbmdSZXF1ZXN0c1t4aHJJZF07XG5cbiAgICBpZiAoIXBlbmRpbmdSZXF1ZXN0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcGVuZGluZ1JlcXVlc3Qub25Qcm9ncmVzcz8uKGV2dCk7XG4gIH1cblxuICBvblN0YXRlQ2hhbmdlKHhocklkLCBldnQpIHtcbiAgICBjb25zdCBwZW5kaW5nUmVxdWVzdCA9IHRoaXMucGVuZGluZ1JlcXVlc3RzW3hocklkXTtcblxuICAgIGlmICghcGVuZGluZ1JlcXVlc3QpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB4aHIgPSBwZW5kaW5nUmVxdWVzdC54aHI7XG5cbiAgICBpZiAoeGhyLnJlYWR5U3RhdGUgPj0gMiAmJiBwZW5kaW5nUmVxdWVzdC5vbkhlYWRlcnNSZWNlaXZlZCkge1xuICAgICAgcGVuZGluZ1JlcXVlc3Qub25IZWFkZXJzUmVjZWl2ZWQoKTtcbiAgICAgIGRlbGV0ZSBwZW5kaW5nUmVxdWVzdC5vbkhlYWRlcnNSZWNlaXZlZDtcbiAgICB9XG5cbiAgICBpZiAoeGhyLnJlYWR5U3RhdGUgIT09IDQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoISh4aHJJZCBpbiB0aGlzLnBlbmRpbmdSZXF1ZXN0cykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBkZWxldGUgdGhpcy5wZW5kaW5nUmVxdWVzdHNbeGhySWRdO1xuXG4gICAgaWYgKHhoci5zdGF0dXMgPT09IDAgJiYgdGhpcy5pc0h0dHApIHtcbiAgICAgIHBlbmRpbmdSZXF1ZXN0Lm9uRXJyb3I/Lih4aHIuc3RhdHVzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB4aHJTdGF0dXMgPSB4aHIuc3RhdHVzIHx8IE9LX1JFU1BPTlNFO1xuICAgIGNvbnN0IG9rX3Jlc3BvbnNlX29uX3JhbmdlX3JlcXVlc3QgPSB4aHJTdGF0dXMgPT09IE9LX1JFU1BPTlNFICYmIHBlbmRpbmdSZXF1ZXN0LmV4cGVjdGVkU3RhdHVzID09PSBQQVJUSUFMX0NPTlRFTlRfUkVTUE9OU0U7XG5cbiAgICBpZiAoIW9rX3Jlc3BvbnNlX29uX3JhbmdlX3JlcXVlc3QgJiYgeGhyU3RhdHVzICE9PSBwZW5kaW5nUmVxdWVzdC5leHBlY3RlZFN0YXR1cykge1xuICAgICAgcGVuZGluZ1JlcXVlc3Qub25FcnJvcj8uKHhoci5zdGF0dXMpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGNodW5rID0gZ2V0QXJyYXlCdWZmZXIoeGhyKTtcblxuICAgIGlmICh4aHJTdGF0dXMgPT09IFBBUlRJQUxfQ09OVEVOVF9SRVNQT05TRSkge1xuICAgICAgY29uc3QgcmFuZ2VIZWFkZXIgPSB4aHIuZ2V0UmVzcG9uc2VIZWFkZXIoXCJDb250ZW50LVJhbmdlXCIpO1xuICAgICAgY29uc3QgbWF0Y2hlcyA9IC9ieXRlcyAoXFxkKyktKFxcZCspXFwvKFxcZCspLy5leGVjKHJhbmdlSGVhZGVyKTtcbiAgICAgIHBlbmRpbmdSZXF1ZXN0Lm9uRG9uZSh7XG4gICAgICAgIGJlZ2luOiBwYXJzZUludChtYXRjaGVzWzFdLCAxMCksXG4gICAgICAgIGNodW5rXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKGNodW5rKSB7XG4gICAgICBwZW5kaW5nUmVxdWVzdC5vbkRvbmUoe1xuICAgICAgICBiZWdpbjogMCxcbiAgICAgICAgY2h1bmtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBwZW5kaW5nUmVxdWVzdC5vbkVycm9yPy4oeGhyLnN0YXR1cyk7XG4gICAgfVxuICB9XG5cbiAgZ2V0UmVxdWVzdFhocih4aHJJZCkge1xuICAgIHJldHVybiB0aGlzLnBlbmRpbmdSZXF1ZXN0c1t4aHJJZF0ueGhyO1xuICB9XG5cbiAgaXNQZW5kaW5nUmVxdWVzdCh4aHJJZCkge1xuICAgIHJldHVybiB4aHJJZCBpbiB0aGlzLnBlbmRpbmdSZXF1ZXN0cztcbiAgfVxuXG4gIGFib3J0UmVxdWVzdCh4aHJJZCkge1xuICAgIGNvbnN0IHhociA9IHRoaXMucGVuZGluZ1JlcXVlc3RzW3hocklkXS54aHI7XG4gICAgZGVsZXRlIHRoaXMucGVuZGluZ1JlcXVlc3RzW3hocklkXTtcbiAgICB4aHIuYWJvcnQoKTtcbiAgfVxuXG59XG5cbmNsYXNzIFBERk5ldHdvcmtTdHJlYW0ge1xuICBjb25zdHJ1Y3Rvcihzb3VyY2UpIHtcbiAgICB0aGlzLl9zb3VyY2UgPSBzb3VyY2U7XG4gICAgdGhpcy5fbWFuYWdlciA9IG5ldyBOZXR3b3JrTWFuYWdlcihzb3VyY2UudXJsLCB7XG4gICAgICBodHRwSGVhZGVyczogc291cmNlLmh0dHBIZWFkZXJzLFxuICAgICAgd2l0aENyZWRlbnRpYWxzOiBzb3VyY2Uud2l0aENyZWRlbnRpYWxzXG4gICAgfSk7XG4gICAgdGhpcy5fcmFuZ2VDaHVua1NpemUgPSBzb3VyY2UucmFuZ2VDaHVua1NpemU7XG4gICAgdGhpcy5fZnVsbFJlcXVlc3RSZWFkZXIgPSBudWxsO1xuICAgIHRoaXMuX3JhbmdlUmVxdWVzdFJlYWRlcnMgPSBbXTtcbiAgfVxuXG4gIF9vblJhbmdlUmVxdWVzdFJlYWRlckNsb3NlZChyZWFkZXIpIHtcbiAgICBjb25zdCBpID0gdGhpcy5fcmFuZ2VSZXF1ZXN0UmVhZGVycy5pbmRleE9mKHJlYWRlcik7XG5cbiAgICBpZiAoaSA+PSAwKSB7XG4gICAgICB0aGlzLl9yYW5nZVJlcXVlc3RSZWFkZXJzLnNwbGljZShpLCAxKTtcbiAgICB9XG4gIH1cblxuICBnZXRGdWxsUmVhZGVyKCkge1xuICAgICgwLCBfdXRpbC5hc3NlcnQpKCF0aGlzLl9mdWxsUmVxdWVzdFJlYWRlciwgXCJQREZOZXR3b3JrU3RyZWFtLmdldEZ1bGxSZWFkZXIgY2FuIG9ubHkgYmUgY2FsbGVkIG9uY2UuXCIpO1xuICAgIHRoaXMuX2Z1bGxSZXF1ZXN0UmVhZGVyID0gbmV3IFBERk5ldHdvcmtTdHJlYW1GdWxsUmVxdWVzdFJlYWRlcih0aGlzLl9tYW5hZ2VyLCB0aGlzLl9zb3VyY2UpO1xuICAgIHJldHVybiB0aGlzLl9mdWxsUmVxdWVzdFJlYWRlcjtcbiAgfVxuXG4gIGdldFJhbmdlUmVhZGVyKGJlZ2luLCBlbmQpIHtcbiAgICBjb25zdCByZWFkZXIgPSBuZXcgUERGTmV0d29ya1N0cmVhbVJhbmdlUmVxdWVzdFJlYWRlcih0aGlzLl9tYW5hZ2VyLCBiZWdpbiwgZW5kKTtcbiAgICByZWFkZXIub25DbG9zZWQgPSB0aGlzLl9vblJhbmdlUmVxdWVzdFJlYWRlckNsb3NlZC5iaW5kKHRoaXMpO1xuXG4gICAgdGhpcy5fcmFuZ2VSZXF1ZXN0UmVhZGVycy5wdXNoKHJlYWRlcik7XG5cbiAgICByZXR1cm4gcmVhZGVyO1xuICB9XG5cbiAgY2FuY2VsQWxsUmVxdWVzdHMocmVhc29uKSB7XG4gICAgdGhpcy5fZnVsbFJlcXVlc3RSZWFkZXI/LmNhbmNlbChyZWFzb24pO1xuXG4gICAgZm9yIChjb25zdCByZWFkZXIgb2YgdGhpcy5fcmFuZ2VSZXF1ZXN0UmVhZGVycy5zbGljZSgwKSkge1xuICAgICAgcmVhZGVyLmNhbmNlbChyZWFzb24pO1xuICAgIH1cbiAgfVxuXG59XG5cbmV4cG9ydHMuUERGTmV0d29ya1N0cmVhbSA9IFBERk5ldHdvcmtTdHJlYW07XG5cbmNsYXNzIFBERk5ldHdvcmtTdHJlYW1GdWxsUmVxdWVzdFJlYWRlciB7XG4gIGNvbnN0cnVjdG9yKG1hbmFnZXIsIHNvdXJjZSkge1xuICAgIHRoaXMuX21hbmFnZXIgPSBtYW5hZ2VyO1xuICAgIGNvbnN0IGFyZ3MgPSB7XG4gICAgICBvbkhlYWRlcnNSZWNlaXZlZDogdGhpcy5fb25IZWFkZXJzUmVjZWl2ZWQuYmluZCh0aGlzKSxcbiAgICAgIG9uRG9uZTogdGhpcy5fb25Eb25lLmJpbmQodGhpcyksXG4gICAgICBvbkVycm9yOiB0aGlzLl9vbkVycm9yLmJpbmQodGhpcyksXG4gICAgICBvblByb2dyZXNzOiB0aGlzLl9vblByb2dyZXNzLmJpbmQodGhpcylcbiAgICB9O1xuICAgIHRoaXMuX3VybCA9IHNvdXJjZS51cmw7XG4gICAgdGhpcy5fZnVsbFJlcXVlc3RJZCA9IG1hbmFnZXIucmVxdWVzdEZ1bGwoYXJncyk7XG4gICAgdGhpcy5faGVhZGVyc1JlY2VpdmVkQ2FwYWJpbGl0eSA9ICgwLCBfdXRpbC5jcmVhdGVQcm9taXNlQ2FwYWJpbGl0eSkoKTtcbiAgICB0aGlzLl9kaXNhYmxlUmFuZ2UgPSBzb3VyY2UuZGlzYWJsZVJhbmdlIHx8IGZhbHNlO1xuICAgIHRoaXMuX2NvbnRlbnRMZW5ndGggPSBzb3VyY2UubGVuZ3RoO1xuICAgIHRoaXMuX3JhbmdlQ2h1bmtTaXplID0gc291cmNlLnJhbmdlQ2h1bmtTaXplO1xuXG4gICAgaWYgKCF0aGlzLl9yYW5nZUNodW5rU2l6ZSAmJiAhdGhpcy5fZGlzYWJsZVJhbmdlKSB7XG4gICAgICB0aGlzLl9kaXNhYmxlUmFuZ2UgPSB0cnVlO1xuICAgIH1cblxuICAgIHRoaXMuX2lzU3RyZWFtaW5nU3VwcG9ydGVkID0gZmFsc2U7XG4gICAgdGhpcy5faXNSYW5nZVN1cHBvcnRlZCA9IGZhbHNlO1xuICAgIHRoaXMuX2NhY2hlZENodW5rcyA9IFtdO1xuICAgIHRoaXMuX3JlcXVlc3RzID0gW107XG4gICAgdGhpcy5fZG9uZSA9IGZhbHNlO1xuICAgIHRoaXMuX3N0b3JlZEVycm9yID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX2ZpbGVuYW1lID0gbnVsbDtcbiAgICB0aGlzLm9uUHJvZ3Jlc3MgPSBudWxsO1xuICB9XG5cbiAgX29uSGVhZGVyc1JlY2VpdmVkKCkge1xuICAgIGNvbnN0IGZ1bGxSZXF1ZXN0WGhySWQgPSB0aGlzLl9mdWxsUmVxdWVzdElkO1xuXG4gICAgY29uc3QgZnVsbFJlcXVlc3RYaHIgPSB0aGlzLl9tYW5hZ2VyLmdldFJlcXVlc3RYaHIoZnVsbFJlcXVlc3RYaHJJZCk7XG5cbiAgICBjb25zdCBnZXRSZXNwb25zZUhlYWRlciA9IG5hbWUgPT4ge1xuICAgICAgcmV0dXJuIGZ1bGxSZXF1ZXN0WGhyLmdldFJlc3BvbnNlSGVhZGVyKG5hbWUpO1xuICAgIH07XG5cbiAgICBjb25zdCB7XG4gICAgICBhbGxvd1JhbmdlUmVxdWVzdHMsXG4gICAgICBzdWdnZXN0ZWRMZW5ndGhcbiAgICB9ID0gKDAsIF9uZXR3b3JrX3V0aWxzLnZhbGlkYXRlUmFuZ2VSZXF1ZXN0Q2FwYWJpbGl0aWVzKSh7XG4gICAgICBnZXRSZXNwb25zZUhlYWRlcixcbiAgICAgIGlzSHR0cDogdGhpcy5fbWFuYWdlci5pc0h0dHAsXG4gICAgICByYW5nZUNodW5rU2l6ZTogdGhpcy5fcmFuZ2VDaHVua1NpemUsXG4gICAgICBkaXNhYmxlUmFuZ2U6IHRoaXMuX2Rpc2FibGVSYW5nZVxuICAgIH0pO1xuXG4gICAgaWYgKGFsbG93UmFuZ2VSZXF1ZXN0cykge1xuICAgICAgdGhpcy5faXNSYW5nZVN1cHBvcnRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgdGhpcy5fY29udGVudExlbmd0aCA9IHN1Z2dlc3RlZExlbmd0aCB8fCB0aGlzLl9jb250ZW50TGVuZ3RoO1xuICAgIHRoaXMuX2ZpbGVuYW1lID0gKDAsIF9uZXR3b3JrX3V0aWxzLmV4dHJhY3RGaWxlbmFtZUZyb21IZWFkZXIpKGdldFJlc3BvbnNlSGVhZGVyKTtcblxuICAgIGlmICh0aGlzLl9pc1JhbmdlU3VwcG9ydGVkKSB7XG4gICAgICB0aGlzLl9tYW5hZ2VyLmFib3J0UmVxdWVzdChmdWxsUmVxdWVzdFhocklkKTtcbiAgICB9XG5cbiAgICB0aGlzLl9oZWFkZXJzUmVjZWl2ZWRDYXBhYmlsaXR5LnJlc29sdmUoKTtcbiAgfVxuXG4gIF9vbkRvbmUoZGF0YSkge1xuICAgIGlmIChkYXRhKSB7XG4gICAgICBpZiAodGhpcy5fcmVxdWVzdHMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCByZXF1ZXN0Q2FwYWJpbGl0eSA9IHRoaXMuX3JlcXVlc3RzLnNoaWZ0KCk7XG5cbiAgICAgICAgcmVxdWVzdENhcGFiaWxpdHkucmVzb2x2ZSh7XG4gICAgICAgICAgdmFsdWU6IGRhdGEuY2h1bmssXG4gICAgICAgICAgZG9uZTogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9jYWNoZWRDaHVua3MucHVzaChkYXRhLmNodW5rKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9kb25lID0gdHJ1ZTtcblxuICAgIGlmICh0aGlzLl9jYWNoZWRDaHVua3MubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcmVxdWVzdENhcGFiaWxpdHkgb2YgdGhpcy5fcmVxdWVzdHMpIHtcbiAgICAgIHJlcXVlc3RDYXBhYmlsaXR5LnJlc29sdmUoe1xuICAgICAgICB2YWx1ZTogdW5kZWZpbmVkLFxuICAgICAgICBkb25lOiB0cnVlXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLl9yZXF1ZXN0cy5sZW5ndGggPSAwO1xuICB9XG5cbiAgX29uRXJyb3Ioc3RhdHVzKSB7XG4gICAgdGhpcy5fc3RvcmVkRXJyb3IgPSAoMCwgX25ldHdvcmtfdXRpbHMuY3JlYXRlUmVzcG9uc2VTdGF0dXNFcnJvcikoc3RhdHVzLCB0aGlzLl91cmwpO1xuXG4gICAgdGhpcy5faGVhZGVyc1JlY2VpdmVkQ2FwYWJpbGl0eS5yZWplY3QodGhpcy5fc3RvcmVkRXJyb3IpO1xuXG4gICAgZm9yIChjb25zdCByZXF1ZXN0Q2FwYWJpbGl0eSBvZiB0aGlzLl9yZXF1ZXN0cykge1xuICAgICAgcmVxdWVzdENhcGFiaWxpdHkucmVqZWN0KHRoaXMuX3N0b3JlZEVycm9yKTtcbiAgICB9XG5cbiAgICB0aGlzLl9yZXF1ZXN0cy5sZW5ndGggPSAwO1xuICAgIHRoaXMuX2NhY2hlZENodW5rcy5sZW5ndGggPSAwO1xuICB9XG5cbiAgX29uUHJvZ3Jlc3MoZXZ0KSB7XG4gICAgdGhpcy5vblByb2dyZXNzPy4oe1xuICAgICAgbG9hZGVkOiBldnQubG9hZGVkLFxuICAgICAgdG90YWw6IGV2dC5sZW5ndGhDb21wdXRhYmxlID8gZXZ0LnRvdGFsIDogdGhpcy5fY29udGVudExlbmd0aFxuICAgIH0pO1xuICB9XG5cbiAgZ2V0IGZpbGVuYW1lKCkge1xuICAgIHJldHVybiB0aGlzLl9maWxlbmFtZTtcbiAgfVxuXG4gIGdldCBpc1JhbmdlU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9pc1JhbmdlU3VwcG9ydGVkO1xuICB9XG5cbiAgZ2V0IGlzU3RyZWFtaW5nU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9pc1N0cmVhbWluZ1N1cHBvcnRlZDtcbiAgfVxuXG4gIGdldCBjb250ZW50TGVuZ3RoKCkge1xuICAgIHJldHVybiB0aGlzLl9jb250ZW50TGVuZ3RoO1xuICB9XG5cbiAgZ2V0IGhlYWRlcnNSZWFkeSgpIHtcbiAgICByZXR1cm4gdGhpcy5faGVhZGVyc1JlY2VpdmVkQ2FwYWJpbGl0eS5wcm9taXNlO1xuICB9XG5cbiAgYXN5bmMgcmVhZCgpIHtcbiAgICBpZiAodGhpcy5fc3RvcmVkRXJyb3IpIHtcbiAgICAgIHRocm93IHRoaXMuX3N0b3JlZEVycm9yO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9jYWNoZWRDaHVua3MubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgY2h1bmsgPSB0aGlzLl9jYWNoZWRDaHVua3Muc2hpZnQoKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWU6IGNodW5rLFxuICAgICAgICBkb25lOiBmYWxzZVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZG9uZSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgICAgZG9uZTogdHJ1ZVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCByZXF1ZXN0Q2FwYWJpbGl0eSA9ICgwLCBfdXRpbC5jcmVhdGVQcm9taXNlQ2FwYWJpbGl0eSkoKTtcblxuICAgIHRoaXMuX3JlcXVlc3RzLnB1c2gocmVxdWVzdENhcGFiaWxpdHkpO1xuXG4gICAgcmV0dXJuIHJlcXVlc3RDYXBhYmlsaXR5LnByb21pc2U7XG4gIH1cblxuICBjYW5jZWwocmVhc29uKSB7XG4gICAgdGhpcy5fZG9uZSA9IHRydWU7XG5cbiAgICB0aGlzLl9oZWFkZXJzUmVjZWl2ZWRDYXBhYmlsaXR5LnJlamVjdChyZWFzb24pO1xuXG4gICAgZm9yIChjb25zdCByZXF1ZXN0Q2FwYWJpbGl0eSBvZiB0aGlzLl9yZXF1ZXN0cykge1xuICAgICAgcmVxdWVzdENhcGFiaWxpdHkucmVzb2x2ZSh7XG4gICAgICAgIHZhbHVlOiB1bmRlZmluZWQsXG4gICAgICAgIGRvbmU6IHRydWVcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuX3JlcXVlc3RzLmxlbmd0aCA9IDA7XG5cbiAgICBpZiAodGhpcy5fbWFuYWdlci5pc1BlbmRpbmdSZXF1ZXN0KHRoaXMuX2Z1bGxSZXF1ZXN0SWQpKSB7XG4gICAgICB0aGlzLl9tYW5hZ2VyLmFib3J0UmVxdWVzdCh0aGlzLl9mdWxsUmVxdWVzdElkKTtcbiAgICB9XG5cbiAgICB0aGlzLl9mdWxsUmVxdWVzdFJlYWRlciA9IG51bGw7XG4gIH1cblxufVxuXG5jbGFzcyBQREZOZXR3b3JrU3RyZWFtUmFuZ2VSZXF1ZXN0UmVhZGVyIHtcbiAgY29uc3RydWN0b3IobWFuYWdlciwgYmVnaW4sIGVuZCkge1xuICAgIHRoaXMuX21hbmFnZXIgPSBtYW5hZ2VyO1xuICAgIGNvbnN0IGFyZ3MgPSB7XG4gICAgICBvbkRvbmU6IHRoaXMuX29uRG9uZS5iaW5kKHRoaXMpLFxuICAgICAgb25FcnJvcjogdGhpcy5fb25FcnJvci5iaW5kKHRoaXMpLFxuICAgICAgb25Qcm9ncmVzczogdGhpcy5fb25Qcm9ncmVzcy5iaW5kKHRoaXMpXG4gICAgfTtcbiAgICB0aGlzLl91cmwgPSBtYW5hZ2VyLnVybDtcbiAgICB0aGlzLl9yZXF1ZXN0SWQgPSBtYW5hZ2VyLnJlcXVlc3RSYW5nZShiZWdpbiwgZW5kLCBhcmdzKTtcbiAgICB0aGlzLl9yZXF1ZXN0cyA9IFtdO1xuICAgIHRoaXMuX3F1ZXVlZENodW5rID0gbnVsbDtcbiAgICB0aGlzLl9kb25lID0gZmFsc2U7XG4gICAgdGhpcy5fc3RvcmVkRXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5vblByb2dyZXNzID0gbnVsbDtcbiAgICB0aGlzLm9uQ2xvc2VkID0gbnVsbDtcbiAgfVxuXG4gIF9jbG9zZSgpIHtcbiAgICB0aGlzLm9uQ2xvc2VkPy4odGhpcyk7XG4gIH1cblxuICBfb25Eb25lKGRhdGEpIHtcbiAgICBjb25zdCBjaHVuayA9IGRhdGEuY2h1bms7XG5cbiAgICBpZiAodGhpcy5fcmVxdWVzdHMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgcmVxdWVzdENhcGFiaWxpdHkgPSB0aGlzLl9yZXF1ZXN0cy5zaGlmdCgpO1xuXG4gICAgICByZXF1ZXN0Q2FwYWJpbGl0eS5yZXNvbHZlKHtcbiAgICAgICAgdmFsdWU6IGNodW5rLFxuICAgICAgICBkb25lOiBmYWxzZVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3F1ZXVlZENodW5rID0gY2h1bms7XG4gICAgfVxuXG4gICAgdGhpcy5fZG9uZSA9IHRydWU7XG5cbiAgICBmb3IgKGNvbnN0IHJlcXVlc3RDYXBhYmlsaXR5IG9mIHRoaXMuX3JlcXVlc3RzKSB7XG4gICAgICByZXF1ZXN0Q2FwYWJpbGl0eS5yZXNvbHZlKHtcbiAgICAgICAgdmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgICAgZG9uZTogdHJ1ZVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5fcmVxdWVzdHMubGVuZ3RoID0gMDtcblxuICAgIHRoaXMuX2Nsb3NlKCk7XG4gIH1cblxuICBfb25FcnJvcihzdGF0dXMpIHtcbiAgICB0aGlzLl9zdG9yZWRFcnJvciA9ICgwLCBfbmV0d29ya191dGlscy5jcmVhdGVSZXNwb25zZVN0YXR1c0Vycm9yKShzdGF0dXMsIHRoaXMuX3VybCk7XG5cbiAgICBmb3IgKGNvbnN0IHJlcXVlc3RDYXBhYmlsaXR5IG9mIHRoaXMuX3JlcXVlc3RzKSB7XG4gICAgICByZXF1ZXN0Q2FwYWJpbGl0eS5yZWplY3QodGhpcy5fc3RvcmVkRXJyb3IpO1xuICAgIH1cblxuICAgIHRoaXMuX3JlcXVlc3RzLmxlbmd0aCA9IDA7XG4gICAgdGhpcy5fcXVldWVkQ2h1bmsgPSBudWxsO1xuICB9XG5cbiAgX29uUHJvZ3Jlc3MoZXZ0KSB7XG4gICAgaWYgKCF0aGlzLmlzU3RyZWFtaW5nU3VwcG9ydGVkKSB7XG4gICAgICB0aGlzLm9uUHJvZ3Jlc3M/Lih7XG4gICAgICAgIGxvYWRlZDogZXZ0LmxvYWRlZFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGlzU3RyZWFtaW5nU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGFzeW5jIHJlYWQoKSB7XG4gICAgaWYgKHRoaXMuX3N0b3JlZEVycm9yKSB7XG4gICAgICB0aHJvdyB0aGlzLl9zdG9yZWRFcnJvcjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fcXVldWVkQ2h1bmsgIT09IG51bGwpIHtcbiAgICAgIGNvbnN0IGNodW5rID0gdGhpcy5fcXVldWVkQ2h1bms7XG4gICAgICB0aGlzLl9xdWV1ZWRDaHVuayA9IG51bGw7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWx1ZTogY2h1bmssXG4gICAgICAgIGRvbmU6IGZhbHNlXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9kb25lKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWx1ZTogdW5kZWZpbmVkLFxuICAgICAgICBkb25lOiB0cnVlXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IHJlcXVlc3RDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuXG4gICAgdGhpcy5fcmVxdWVzdHMucHVzaChyZXF1ZXN0Q2FwYWJpbGl0eSk7XG5cbiAgICByZXR1cm4gcmVxdWVzdENhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxuXG4gIGNhbmNlbChyZWFzb24pIHtcbiAgICB0aGlzLl9kb25lID0gdHJ1ZTtcblxuICAgIGZvciAoY29uc3QgcmVxdWVzdENhcGFiaWxpdHkgb2YgdGhpcy5fcmVxdWVzdHMpIHtcbiAgICAgIHJlcXVlc3RDYXBhYmlsaXR5LnJlc29sdmUoe1xuICAgICAgICB2YWx1ZTogdW5kZWZpbmVkLFxuICAgICAgICBkb25lOiB0cnVlXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLl9yZXF1ZXN0cy5sZW5ndGggPSAwO1xuXG4gICAgaWYgKHRoaXMuX21hbmFnZXIuaXNQZW5kaW5nUmVxdWVzdCh0aGlzLl9yZXF1ZXN0SWQpKSB7XG4gICAgICB0aGlzLl9tYW5hZ2VyLmFib3J0UmVxdWVzdCh0aGlzLl9yZXF1ZXN0SWQpO1xuICAgIH1cblxuICAgIHRoaXMuX2Nsb3NlKCk7XG4gIH1cblxufVxuXG4vKioqLyB9KSxcbi8qIDI5ICovXG4vKioqLyAoKF9fdW51c2VkX3dlYnBhY2tfbW9kdWxlLCBleHBvcnRzLCBfX3dfcGRmanNfcmVxdWlyZV9fKSA9PiB7XG5cblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5leHBvcnRzLlBERkZldGNoU3RyZWFtID0gdm9pZCAwO1xuXG52YXIgX3V0aWwgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDEpO1xuXG52YXIgX25ldHdvcmtfdXRpbHMgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDI2KTtcblxuO1xuXG5mdW5jdGlvbiBjcmVhdGVGZXRjaE9wdGlvbnMoaGVhZGVycywgd2l0aENyZWRlbnRpYWxzLCBhYm9ydENvbnRyb2xsZXIpIHtcbiAgcmV0dXJuIHtcbiAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgaGVhZGVycyxcbiAgICBzaWduYWw6IGFib3J0Q29udHJvbGxlcj8uc2lnbmFsLFxuICAgIG1vZGU6IFwiY29yc1wiLFxuICAgIGNyZWRlbnRpYWxzOiB3aXRoQ3JlZGVudGlhbHMgPyBcImluY2x1ZGVcIiA6IFwic2FtZS1vcmlnaW5cIixcbiAgICByZWRpcmVjdDogXCJmb2xsb3dcIlxuICB9O1xufVxuXG5mdW5jdGlvbiBjcmVhdGVIZWFkZXJzKGh0dHBIZWFkZXJzKSB7XG4gIGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycygpO1xuXG4gIGZvciAoY29uc3QgcHJvcGVydHkgaW4gaHR0cEhlYWRlcnMpIHtcbiAgICBjb25zdCB2YWx1ZSA9IGh0dHBIZWFkZXJzW3Byb3BlcnR5XTtcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGhlYWRlcnMuYXBwZW5kKHByb3BlcnR5LCB2YWx1ZSk7XG4gIH1cblxuICByZXR1cm4gaGVhZGVycztcbn1cblxuY2xhc3MgUERGRmV0Y2hTdHJlYW0ge1xuICBjb25zdHJ1Y3Rvcihzb3VyY2UpIHtcbiAgICB0aGlzLnNvdXJjZSA9IHNvdXJjZTtcbiAgICB0aGlzLmlzSHR0cCA9IC9eaHR0cHM/Oi9pLnRlc3Qoc291cmNlLnVybCk7XG4gICAgdGhpcy5odHRwSGVhZGVycyA9IHRoaXMuaXNIdHRwICYmIHNvdXJjZS5odHRwSGVhZGVycyB8fCB7fTtcbiAgICB0aGlzLl9mdWxsUmVxdWVzdFJlYWRlciA9IG51bGw7XG4gICAgdGhpcy5fcmFuZ2VSZXF1ZXN0UmVhZGVycyA9IFtdO1xuICB9XG5cbiAgZ2V0IF9wcm9ncmVzc2l2ZURhdGFMZW5ndGgoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2Z1bGxSZXF1ZXN0UmVhZGVyPy5fbG9hZGVkID8/IDA7XG4gIH1cblxuICBnZXRGdWxsUmVhZGVyKCkge1xuICAgICgwLCBfdXRpbC5hc3NlcnQpKCF0aGlzLl9mdWxsUmVxdWVzdFJlYWRlciwgXCJQREZGZXRjaFN0cmVhbS5nZXRGdWxsUmVhZGVyIGNhbiBvbmx5IGJlIGNhbGxlZCBvbmNlLlwiKTtcbiAgICB0aGlzLl9mdWxsUmVxdWVzdFJlYWRlciA9IG5ldyBQREZGZXRjaFN0cmVhbVJlYWRlcih0aGlzKTtcbiAgICByZXR1cm4gdGhpcy5fZnVsbFJlcXVlc3RSZWFkZXI7XG4gIH1cblxuICBnZXRSYW5nZVJlYWRlcihiZWdpbiwgZW5kKSB7XG4gICAgaWYgKGVuZCA8PSB0aGlzLl9wcm9ncmVzc2l2ZURhdGFMZW5ndGgpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHJlYWRlciA9IG5ldyBQREZGZXRjaFN0cmVhbVJhbmdlUmVhZGVyKHRoaXMsIGJlZ2luLCBlbmQpO1xuXG4gICAgdGhpcy5fcmFuZ2VSZXF1ZXN0UmVhZGVycy5wdXNoKHJlYWRlcik7XG5cbiAgICByZXR1cm4gcmVhZGVyO1xuICB9XG5cbiAgY2FuY2VsQWxsUmVxdWVzdHMocmVhc29uKSB7XG4gICAgaWYgKHRoaXMuX2Z1bGxSZXF1ZXN0UmVhZGVyKSB7XG4gICAgICB0aGlzLl9mdWxsUmVxdWVzdFJlYWRlci5jYW5jZWwocmVhc29uKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHJlYWRlciBvZiB0aGlzLl9yYW5nZVJlcXVlc3RSZWFkZXJzLnNsaWNlKDApKSB7XG4gICAgICByZWFkZXIuY2FuY2VsKHJlYXNvbik7XG4gICAgfVxuICB9XG5cbn1cblxuZXhwb3J0cy5QREZGZXRjaFN0cmVhbSA9IFBERkZldGNoU3RyZWFtO1xuXG5jbGFzcyBQREZGZXRjaFN0cmVhbVJlYWRlciB7XG4gIGNvbnN0cnVjdG9yKHN0cmVhbSkge1xuICAgIHRoaXMuX3N0cmVhbSA9IHN0cmVhbTtcbiAgICB0aGlzLl9yZWFkZXIgPSBudWxsO1xuICAgIHRoaXMuX2xvYWRlZCA9IDA7XG4gICAgdGhpcy5fZmlsZW5hbWUgPSBudWxsO1xuICAgIGNvbnN0IHNvdXJjZSA9IHN0cmVhbS5zb3VyY2U7XG4gICAgdGhpcy5fd2l0aENyZWRlbnRpYWxzID0gc291cmNlLndpdGhDcmVkZW50aWFscyB8fCBmYWxzZTtcbiAgICB0aGlzLl9jb250ZW50TGVuZ3RoID0gc291cmNlLmxlbmd0aDtcbiAgICB0aGlzLl9oZWFkZXJzQ2FwYWJpbGl0eSA9ICgwLCBfdXRpbC5jcmVhdGVQcm9taXNlQ2FwYWJpbGl0eSkoKTtcbiAgICB0aGlzLl9kaXNhYmxlUmFuZ2UgPSBzb3VyY2UuZGlzYWJsZVJhbmdlIHx8IGZhbHNlO1xuICAgIHRoaXMuX3JhbmdlQ2h1bmtTaXplID0gc291cmNlLnJhbmdlQ2h1bmtTaXplO1xuXG4gICAgaWYgKCF0aGlzLl9yYW5nZUNodW5rU2l6ZSAmJiAhdGhpcy5fZGlzYWJsZVJhbmdlKSB7XG4gICAgICB0aGlzLl9kaXNhYmxlUmFuZ2UgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgQWJvcnRDb250cm9sbGVyICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICB0aGlzLl9hYm9ydENvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgfVxuXG4gICAgdGhpcy5faXNTdHJlYW1pbmdTdXBwb3J0ZWQgPSAhc291cmNlLmRpc2FibGVTdHJlYW07XG4gICAgdGhpcy5faXNSYW5nZVN1cHBvcnRlZCA9ICFzb3VyY2UuZGlzYWJsZVJhbmdlO1xuICAgIHRoaXMuX2hlYWRlcnMgPSBjcmVhdGVIZWFkZXJzKHRoaXMuX3N0cmVhbS5odHRwSGVhZGVycyk7XG4gICAgY29uc3QgdXJsID0gc291cmNlLnVybDtcbiAgICBmZXRjaCh1cmwsIGNyZWF0ZUZldGNoT3B0aW9ucyh0aGlzLl9oZWFkZXJzLCB0aGlzLl93aXRoQ3JlZGVudGlhbHMsIHRoaXMuX2Fib3J0Q29udHJvbGxlcikpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgaWYgKCEoMCwgX25ldHdvcmtfdXRpbHMudmFsaWRhdGVSZXNwb25zZVN0YXR1cykocmVzcG9uc2Uuc3RhdHVzKSkge1xuICAgICAgICB0aHJvdyAoMCwgX25ldHdvcmtfdXRpbHMuY3JlYXRlUmVzcG9uc2VTdGF0dXNFcnJvcikocmVzcG9uc2Uuc3RhdHVzLCB1cmwpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9yZWFkZXIgPSByZXNwb25zZS5ib2R5LmdldFJlYWRlcigpO1xuXG4gICAgICB0aGlzLl9oZWFkZXJzQ2FwYWJpbGl0eS5yZXNvbHZlKCk7XG5cbiAgICAgIGNvbnN0IGdldFJlc3BvbnNlSGVhZGVyID0gbmFtZSA9PiB7XG4gICAgICAgIHJldHVybiByZXNwb25zZS5oZWFkZXJzLmdldChuYW1lKTtcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHtcbiAgICAgICAgYWxsb3dSYW5nZVJlcXVlc3RzLFxuICAgICAgICBzdWdnZXN0ZWRMZW5ndGhcbiAgICAgIH0gPSAoMCwgX25ldHdvcmtfdXRpbHMudmFsaWRhdGVSYW5nZVJlcXVlc3RDYXBhYmlsaXRpZXMpKHtcbiAgICAgICAgZ2V0UmVzcG9uc2VIZWFkZXIsXG4gICAgICAgIGlzSHR0cDogdGhpcy5fc3RyZWFtLmlzSHR0cCxcbiAgICAgICAgcmFuZ2VDaHVua1NpemU6IHRoaXMuX3JhbmdlQ2h1bmtTaXplLFxuICAgICAgICBkaXNhYmxlUmFuZ2U6IHRoaXMuX2Rpc2FibGVSYW5nZVxuICAgICAgfSk7XG4gICAgICB0aGlzLl9pc1JhbmdlU3VwcG9ydGVkID0gYWxsb3dSYW5nZVJlcXVlc3RzO1xuICAgICAgdGhpcy5fY29udGVudExlbmd0aCA9IHN1Z2dlc3RlZExlbmd0aCB8fCB0aGlzLl9jb250ZW50TGVuZ3RoO1xuICAgICAgdGhpcy5fZmlsZW5hbWUgPSAoMCwgX25ldHdvcmtfdXRpbHMuZXh0cmFjdEZpbGVuYW1lRnJvbUhlYWRlcikoZ2V0UmVzcG9uc2VIZWFkZXIpO1xuXG4gICAgICBpZiAoIXRoaXMuX2lzU3RyZWFtaW5nU3VwcG9ydGVkICYmIHRoaXMuX2lzUmFuZ2VTdXBwb3J0ZWQpIHtcbiAgICAgICAgdGhpcy5jYW5jZWwobmV3IF91dGlsLkFib3J0RXhjZXB0aW9uKFwiU3RyZWFtaW5nIGlzIGRpc2FibGVkLlwiKSk7XG4gICAgICB9XG4gICAgfSkuY2F0Y2godGhpcy5faGVhZGVyc0NhcGFiaWxpdHkucmVqZWN0KTtcbiAgICB0aGlzLm9uUHJvZ3Jlc3MgPSBudWxsO1xuICB9XG5cbiAgZ2V0IGhlYWRlcnNSZWFkeSgpIHtcbiAgICByZXR1cm4gdGhpcy5faGVhZGVyc0NhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxuXG4gIGdldCBmaWxlbmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fZmlsZW5hbWU7XG4gIH1cblxuICBnZXQgY29udGVudExlbmd0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5fY29udGVudExlbmd0aDtcbiAgfVxuXG4gIGdldCBpc1JhbmdlU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9pc1JhbmdlU3VwcG9ydGVkO1xuICB9XG5cbiAgZ2V0IGlzU3RyZWFtaW5nU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9pc1N0cmVhbWluZ1N1cHBvcnRlZDtcbiAgfVxuXG4gIGFzeW5jIHJlYWQoKSB7XG4gICAgYXdhaXQgdGhpcy5faGVhZGVyc0NhcGFiaWxpdHkucHJvbWlzZTtcbiAgICBjb25zdCB7XG4gICAgICB2YWx1ZSxcbiAgICAgIGRvbmVcbiAgICB9ID0gYXdhaXQgdGhpcy5fcmVhZGVyLnJlYWQoKTtcblxuICAgIGlmIChkb25lKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWx1ZSxcbiAgICAgICAgZG9uZVxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2FkZWQgKz0gdmFsdWUuYnl0ZUxlbmd0aDtcblxuICAgIGlmICh0aGlzLm9uUHJvZ3Jlc3MpIHtcbiAgICAgIHRoaXMub25Qcm9ncmVzcyh7XG4gICAgICAgIGxvYWRlZDogdGhpcy5fbG9hZGVkLFxuICAgICAgICB0b3RhbDogdGhpcy5fY29udGVudExlbmd0aFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkodmFsdWUpLmJ1ZmZlcjtcbiAgICByZXR1cm4ge1xuICAgICAgdmFsdWU6IGJ1ZmZlcixcbiAgICAgIGRvbmU6IGZhbHNlXG4gICAgfTtcbiAgfVxuXG4gIGNhbmNlbChyZWFzb24pIHtcbiAgICBpZiAodGhpcy5fcmVhZGVyKSB7XG4gICAgICB0aGlzLl9yZWFkZXIuY2FuY2VsKHJlYXNvbik7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2Fib3J0Q29udHJvbGxlcikge1xuICAgICAgdGhpcy5fYWJvcnRDb250cm9sbGVyLmFib3J0KCk7XG4gICAgfVxuICB9XG5cbn1cblxuY2xhc3MgUERGRmV0Y2hTdHJlYW1SYW5nZVJlYWRlciB7XG4gIGNvbnN0cnVjdG9yKHN0cmVhbSwgYmVnaW4sIGVuZCkge1xuICAgIHRoaXMuX3N0cmVhbSA9IHN0cmVhbTtcbiAgICB0aGlzLl9yZWFkZXIgPSBudWxsO1xuICAgIHRoaXMuX2xvYWRlZCA9IDA7XG4gICAgY29uc3Qgc291cmNlID0gc3RyZWFtLnNvdXJjZTtcbiAgICB0aGlzLl93aXRoQ3JlZGVudGlhbHMgPSBzb3VyY2Uud2l0aENyZWRlbnRpYWxzIHx8IGZhbHNlO1xuICAgIHRoaXMuX3JlYWRDYXBhYmlsaXR5ID0gKDAsIF91dGlsLmNyZWF0ZVByb21pc2VDYXBhYmlsaXR5KSgpO1xuICAgIHRoaXMuX2lzU3RyZWFtaW5nU3VwcG9ydGVkID0gIXNvdXJjZS5kaXNhYmxlU3RyZWFtO1xuXG4gICAgaWYgKHR5cGVvZiBBYm9ydENvbnRyb2xsZXIgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgIHRoaXMuX2Fib3J0Q29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9oZWFkZXJzID0gY3JlYXRlSGVhZGVycyh0aGlzLl9zdHJlYW0uaHR0cEhlYWRlcnMpO1xuXG4gICAgdGhpcy5faGVhZGVycy5hcHBlbmQoXCJSYW5nZVwiLCBgYnl0ZXM9JHtiZWdpbn0tJHtlbmQgLSAxfWApO1xuXG4gICAgY29uc3QgdXJsID0gc291cmNlLnVybDtcbiAgICBmZXRjaCh1cmwsIGNyZWF0ZUZldGNoT3B0aW9ucyh0aGlzLl9oZWFkZXJzLCB0aGlzLl93aXRoQ3JlZGVudGlhbHMsIHRoaXMuX2Fib3J0Q29udHJvbGxlcikpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgaWYgKCEoMCwgX25ldHdvcmtfdXRpbHMudmFsaWRhdGVSZXNwb25zZVN0YXR1cykocmVzcG9uc2Uuc3RhdHVzKSkge1xuICAgICAgICB0aHJvdyAoMCwgX25ldHdvcmtfdXRpbHMuY3JlYXRlUmVzcG9uc2VTdGF0dXNFcnJvcikocmVzcG9uc2Uuc3RhdHVzLCB1cmwpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9yZWFkQ2FwYWJpbGl0eS5yZXNvbHZlKCk7XG5cbiAgICAgIHRoaXMuX3JlYWRlciA9IHJlc3BvbnNlLmJvZHkuZ2V0UmVhZGVyKCk7XG4gICAgfSkuY2F0Y2godGhpcy5fcmVhZENhcGFiaWxpdHkucmVqZWN0KTtcbiAgICB0aGlzLm9uUHJvZ3Jlc3MgPSBudWxsO1xuICB9XG5cbiAgZ2V0IGlzU3RyZWFtaW5nU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9pc1N0cmVhbWluZ1N1cHBvcnRlZDtcbiAgfVxuXG4gIGFzeW5jIHJlYWQoKSB7XG4gICAgYXdhaXQgdGhpcy5fcmVhZENhcGFiaWxpdHkucHJvbWlzZTtcbiAgICBjb25zdCB7XG4gICAgICB2YWx1ZSxcbiAgICAgIGRvbmVcbiAgICB9ID0gYXdhaXQgdGhpcy5fcmVhZGVyLnJlYWQoKTtcblxuICAgIGlmIChkb25lKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWx1ZSxcbiAgICAgICAgZG9uZVxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2FkZWQgKz0gdmFsdWUuYnl0ZUxlbmd0aDtcblxuICAgIGlmICh0aGlzLm9uUHJvZ3Jlc3MpIHtcbiAgICAgIHRoaXMub25Qcm9ncmVzcyh7XG4gICAgICAgIGxvYWRlZDogdGhpcy5fbG9hZGVkXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBidWZmZXIgPSBuZXcgVWludDhBcnJheSh2YWx1ZSkuYnVmZmVyO1xuICAgIHJldHVybiB7XG4gICAgICB2YWx1ZTogYnVmZmVyLFxuICAgICAgZG9uZTogZmFsc2VcbiAgICB9O1xuICB9XG5cbiAgY2FuY2VsKHJlYXNvbikge1xuICAgIGlmICh0aGlzLl9yZWFkZXIpIHtcbiAgICAgIHRoaXMuX3JlYWRlci5jYW5jZWwocmVhc29uKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fYWJvcnRDb250cm9sbGVyKSB7XG4gICAgICB0aGlzLl9hYm9ydENvbnRyb2xsZXIuYWJvcnQoKTtcbiAgICB9XG4gIH1cblxufVxuXG4vKioqLyB9KVxuLyoqKioqKi8gXHRdKTtcbi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKioqKioqLyBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbi8qKioqKiovIFx0dmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuLyoqKioqKi8gXHRcbi8qKioqKiovIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbi8qKioqKiovIFx0ZnVuY3Rpb24gX193X3BkZmpzX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuLyoqKioqKi8gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuLyoqKioqKi8gXHRcdHZhciBjYWNoZWRNb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdO1xuLyoqKioqKi8gXHRcdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuLyoqKioqKi8gXHRcdFx0cmV0dXJuIGNhY2hlZE1vZHVsZS5leHBvcnRzO1xuLyoqKioqKi8gXHRcdH1cbi8qKioqKiovIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuLyoqKioqKi8gXHRcdHZhciBtb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdID0ge1xuLyoqKioqKi8gXHRcdFx0Ly8gbm8gbW9kdWxlLmlkIG5lZWRlZFxuLyoqKioqKi8gXHRcdFx0Ly8gbm8gbW9kdWxlLmxvYWRlZCBuZWVkZWRcbi8qKioqKiovIFx0XHRcdGV4cG9ydHM6IHt9XG4vKioqKioqLyBcdFx0fTtcbi8qKioqKiovIFx0XG4vKioqKioqLyBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4vKioqKioqLyBcdFx0X193ZWJwYWNrX21vZHVsZXNfX1ttb2R1bGVJZF0obW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193X3BkZmpzX3JlcXVpcmVfXyk7XG4vKioqKioqLyBcdFxuLyoqKioqKi8gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4vKioqKioqLyBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuLyoqKioqKi8gXHR9XG4vKioqKioqLyBcdFxuLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbnZhciBfX3dlYnBhY2tfZXhwb3J0c19fID0ge307XG4vLyBUaGlzIGVudHJ5IG5lZWQgdG8gYmUgd3JhcHBlZCBpbiBhbiBJSUZFIGJlY2F1c2UgaXQgbmVlZCB0byBiZSBpc29sYXRlZCBhZ2FpbnN0IG90aGVyIG1vZHVsZXMgaW4gdGhlIGNodW5rLlxuKCgpID0+IHtcbnZhciBleHBvcnRzID0gX193ZWJwYWNrX2V4cG9ydHNfXztcblxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsICh7XG4gIHZhbHVlOiB0cnVlXG59KSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJBbm5vdGF0aW9uTGF5ZXJcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF9hbm5vdGF0aW9uX2xheWVyLkFubm90YXRpb25MYXllcjtcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQW5ub3RhdGlvbk1vZGVcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF91dGlsLkFubm90YXRpb25Nb2RlO1xuICB9XG59KSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJDTWFwQ29tcHJlc3Npb25UeXBlXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdXRpbC5DTWFwQ29tcHJlc3Npb25UeXBlO1xuICB9XG59KSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJHbG9iYWxXb3JrZXJPcHRpb25zXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfd29ya2VyX29wdGlvbnMuR2xvYmFsV29ya2VyT3B0aW9ucztcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiSW52YWxpZFBERkV4Y2VwdGlvblwiLCAoe1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3V0aWwuSW52YWxpZFBERkV4Y2VwdGlvbjtcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiTG9vcGJhY2tQb3J0XCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfYXBpLkxvb3BiYWNrUG9ydDtcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiTWlzc2luZ1BERkV4Y2VwdGlvblwiLCAoe1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3V0aWwuTWlzc2luZ1BERkV4Y2VwdGlvbjtcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiT1BTXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdXRpbC5PUFM7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlBERkRhdGFSYW5nZVRyYW5zcG9ydFwiLCAoe1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX2FwaS5QREZEYXRhUmFuZ2VUcmFuc3BvcnQ7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlBERkRhdGVTdHJpbmdcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF9kaXNwbGF5X3V0aWxzLlBERkRhdGVTdHJpbmc7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlBERldvcmtlclwiLCAoe1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX2FwaS5QREZXb3JrZXI7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlBhc3N3b3JkUmVzcG9uc2VzXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdXRpbC5QYXNzd29yZFJlc3BvbnNlcztcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiUGVybWlzc2lvbkZsYWdcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF91dGlsLlBlcm1pc3Npb25GbGFnO1xuICB9XG59KSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJQaXhlbHNQZXJJbmNoXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfZGlzcGxheV91dGlscy5QaXhlbHNQZXJJbmNoO1xuICB9XG59KSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJSZW5kZXJpbmdDYW5jZWxsZWRFeGNlcHRpb25cIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF9kaXNwbGF5X3V0aWxzLlJlbmRlcmluZ0NhbmNlbGxlZEV4Y2VwdGlvbjtcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiU1ZHR3JhcGhpY3NcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF9zdmcuU1ZHR3JhcGhpY3M7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlVOU1VQUE9SVEVEX0ZFQVRVUkVTXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdXRpbC5VTlNVUFBPUlRFRF9GRUFUVVJFUztcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiVW5leHBlY3RlZFJlc3BvbnNlRXhjZXB0aW9uXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdXRpbC5VbmV4cGVjdGVkUmVzcG9uc2VFeGNlcHRpb247XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlV0aWxcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF91dGlsLlV0aWw7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlZlcmJvc2l0eUxldmVsXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdXRpbC5WZXJib3NpdHlMZXZlbDtcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiWGZhTGF5ZXJcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF94ZmFfbGF5ZXIuWGZhTGF5ZXI7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImJ1aWxkXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfYXBpLmJ1aWxkO1xuICB9XG59KSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJjcmVhdGVQcm9taXNlQ2FwYWJpbGl0eVwiLCAoe1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3V0aWwuY3JlYXRlUHJvbWlzZUNhcGFiaWxpdHk7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImNyZWF0ZVZhbGlkQWJzb2x1dGVVcmxcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF91dGlsLmNyZWF0ZVZhbGlkQWJzb2x1dGVVcmw7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImdldERvY3VtZW50XCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfYXBpLmdldERvY3VtZW50O1xuICB9XG59KSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJnZXRGaWxlbmFtZUZyb21VcmxcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF9kaXNwbGF5X3V0aWxzLmdldEZpbGVuYW1lRnJvbVVybDtcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiZ2V0UGRmRmlsZW5hbWVGcm9tVXJsXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfZGlzcGxheV91dGlscy5nZXRQZGZGaWxlbmFtZUZyb21Vcmw7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImdldFhmYVBhZ2VWaWV3cG9ydFwiLCAoe1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX2Rpc3BsYXlfdXRpbHMuZ2V0WGZhUGFnZVZpZXdwb3J0O1xuICB9XG59KSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJpc1BkZkZpbGVcIiwgKHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF9kaXNwbGF5X3V0aWxzLmlzUGRmRmlsZTtcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwibG9hZFNjcmlwdFwiLCAoe1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX2Rpc3BsYXlfdXRpbHMubG9hZFNjcmlwdDtcbiAgfVxufSkpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicmVuZGVyVGV4dExheWVyXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdGV4dF9sYXllci5yZW5kZXJUZXh0TGF5ZXI7XG4gIH1cbn0pKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInNoYWRvd1wiLCAoe1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3V0aWwuc2hhZG93O1xuICB9XG59KSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ2ZXJzaW9uXCIsICh7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfYXBpLnZlcnNpb247XG4gIH1cbn0pKTtcblxudmFyIF91dGlsID0gX193X3BkZmpzX3JlcXVpcmVfXygxKTtcblxudmFyIF9hcGkgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDQpO1xuXG52YXIgX2Rpc3BsYXlfdXRpbHMgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDUpO1xuXG52YXIgX2Fubm90YXRpb25fbGF5ZXIgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDIwKTtcblxudmFyIF93b3JrZXJfb3B0aW9ucyA9IF9fd19wZGZqc19yZXF1aXJlX18oMTMpO1xuXG52YXIgX2lzX25vZGUgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDMpO1xuXG52YXIgX3RleHRfbGF5ZXIgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDIzKTtcblxudmFyIF9zdmcgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDI0KTtcblxudmFyIF94ZmFfbGF5ZXIgPSBfX3dfcGRmanNfcmVxdWlyZV9fKDIyKTtcblxuY29uc3QgcGRmanNWZXJzaW9uID0gJzIuMTQuMzA1JztcbmNvbnN0IHBkZmpzQnVpbGQgPSAnZWFhYThiNGFkJztcbntcbiAgaWYgKF9pc19ub2RlLmlzTm9kZUpTKSB7XG4gICAgY29uc3Qge1xuICAgICAgUERGTm9kZVN0cmVhbVxuICAgIH0gPSBfX3dfcGRmanNfcmVxdWlyZV9fKDI1KTtcblxuICAgICgwLCBfYXBpLnNldFBERk5ldHdvcmtTdHJlYW1GYWN0b3J5KShwYXJhbXMgPT4ge1xuICAgICAgcmV0dXJuIG5ldyBQREZOb2RlU3RyZWFtKHBhcmFtcyk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3Qge1xuICAgICAgUERGTmV0d29ya1N0cmVhbVxuICAgIH0gPSBfX3dfcGRmanNfcmVxdWlyZV9fKDI4KTtcblxuICAgIGNvbnN0IHtcbiAgICAgIFBERkZldGNoU3RyZWFtXG4gICAgfSA9IF9fd19wZGZqc19yZXF1aXJlX18oMjkpO1xuXG4gICAgKDAsIF9hcGkuc2V0UERGTmV0d29ya1N0cmVhbUZhY3RvcnkpKHBhcmFtcyA9PiB7XG4gICAgICBpZiAoKDAsIF9kaXNwbGF5X3V0aWxzLmlzVmFsaWRGZXRjaFVybCkocGFyYW1zLnVybCkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQREZGZXRjaFN0cmVhbShwYXJhbXMpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbmV3IFBERk5ldHdvcmtTdHJlYW0ocGFyYW1zKTtcbiAgICB9KTtcbiAgfVxufVxufSkoKTtcblxuLyoqKioqKi8gXHRyZXR1cm4gX193ZWJwYWNrX2V4cG9ydHNfXztcbi8qKioqKiovIH0pKClcbjtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGRmLmpzLm1hcCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///299\n')},703:(module,__unused_webpack_exports,__webpack_require__)=>{"use strict";eval("/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\n\nvar ReactPropTypesSecret = __webpack_require__(268);\n\nfunction emptyFunction() {}\nfunction emptyFunctionWithReset() {}\nemptyFunctionWithReset.resetWarningCache = emptyFunction;\n\nmodule.exports = function() {\n function shim(props, propName, componentName, location, propFullName, secret) {\n if (secret === ReactPropTypesSecret) {\n // It is still safe when called from React.\n return;\n }\n var err = new Error(\n 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +\n 'Use PropTypes.checkPropTypes() to call them. ' +\n 'Read more at http://fb.me/use-check-prop-types'\n );\n err.name = 'Invariant Violation';\n throw err;\n };\n shim.isRequired = shim;\n function getShim() {\n return shim;\n };\n // Important!\n // Keep this list in sync with production version in `./factoryWithTypeCheckers.js`.\n var ReactPropTypes = {\n array: shim,\n bool: shim,\n func: shim,\n number: shim,\n object: shim,\n string: shim,\n symbol: shim,\n\n any: shim,\n arrayOf: getShim,\n element: shim,\n elementType: shim,\n instanceOf: getShim,\n node: shim,\n objectOf: getShim,\n oneOf: getShim,\n oneOfType: getShim,\n shape: getShim,\n exact: getShim,\n\n checkPropTypes: emptyFunctionWithReset,\n resetWarningCache: emptyFunction\n };\n\n ReactPropTypes.PropTypes = ReactPropTypes;\n\n return ReactPropTypes;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9wcm9wLXR5cGVzL2ZhY3RvcnlXaXRoVGhyb3dpbmdTaGltcy5qcz9kN2EwIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFYTs7QUFFYiwyQkFBMkIsbUJBQU8sQ0FBQyxHQUE0Qjs7QUFFL0Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EiLCJmaWxlIjoiNzAzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtcHJlc2VudCwgRmFjZWJvb2ssIEluYy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBSZWFjdFByb3BUeXBlc1NlY3JldCA9IHJlcXVpcmUoJy4vbGliL1JlYWN0UHJvcFR5cGVzU2VjcmV0Jyk7XG5cbmZ1bmN0aW9uIGVtcHR5RnVuY3Rpb24oKSB7fVxuZnVuY3Rpb24gZW1wdHlGdW5jdGlvbldpdGhSZXNldCgpIHt9XG5lbXB0eUZ1bmN0aW9uV2l0aFJlc2V0LnJlc2V0V2FybmluZ0NhY2hlID0gZW1wdHlGdW5jdGlvbjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbigpIHtcbiAgZnVuY3Rpb24gc2hpbShwcm9wcywgcHJvcE5hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBwcm9wRnVsbE5hbWUsIHNlY3JldCkge1xuICAgIGlmIChzZWNyZXQgPT09IFJlYWN0UHJvcFR5cGVzU2VjcmV0KSB7XG4gICAgICAvLyBJdCBpcyBzdGlsbCBzYWZlIHdoZW4gY2FsbGVkIGZyb20gUmVhY3QuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoXG4gICAgICAnQ2FsbGluZyBQcm9wVHlwZXMgdmFsaWRhdG9ycyBkaXJlY3RseSBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBgcHJvcC10eXBlc2AgcGFja2FnZS4gJyArXG4gICAgICAnVXNlIFByb3BUeXBlcy5jaGVja1Byb3BUeXBlcygpIHRvIGNhbGwgdGhlbS4gJyArXG4gICAgICAnUmVhZCBtb3JlIGF0IGh0dHA6Ly9mYi5tZS91c2UtY2hlY2stcHJvcC10eXBlcydcbiAgICApO1xuICAgIGVyci5uYW1lID0gJ0ludmFyaWFudCBWaW9sYXRpb24nO1xuICAgIHRocm93IGVycjtcbiAgfTtcbiAgc2hpbS5pc1JlcXVpcmVkID0gc2hpbTtcbiAgZnVuY3Rpb24gZ2V0U2hpbSgpIHtcbiAgICByZXR1cm4gc2hpbTtcbiAgfTtcbiAgLy8gSW1wb3J0YW50IVxuICAvLyBLZWVwIHRoaXMgbGlzdCBpbiBzeW5jIHdpdGggcHJvZHVjdGlvbiB2ZXJzaW9uIGluIGAuL2ZhY3RvcnlXaXRoVHlwZUNoZWNrZXJzLmpzYC5cbiAgdmFyIFJlYWN0UHJvcFR5cGVzID0ge1xuICAgIGFycmF5OiBzaGltLFxuICAgIGJvb2w6IHNoaW0sXG4gICAgZnVuYzogc2hpbSxcbiAgICBudW1iZXI6IHNoaW0sXG4gICAgb2JqZWN0OiBzaGltLFxuICAgIHN0cmluZzogc2hpbSxcbiAgICBzeW1ib2w6IHNoaW0sXG5cbiAgICBhbnk6IHNoaW0sXG4gICAgYXJyYXlPZjogZ2V0U2hpbSxcbiAgICBlbGVtZW50OiBzaGltLFxuICAgIGVsZW1lbnRUeXBlOiBzaGltLFxuICAgIGluc3RhbmNlT2Y6IGdldFNoaW0sXG4gICAgbm9kZTogc2hpbSxcbiAgICBvYmplY3RPZjogZ2V0U2hpbSxcbiAgICBvbmVPZjogZ2V0U2hpbSxcbiAgICBvbmVPZlR5cGU6IGdldFNoaW0sXG4gICAgc2hhcGU6IGdldFNoaW0sXG4gICAgZXhhY3Q6IGdldFNoaW0sXG5cbiAgICBjaGVja1Byb3BUeXBlczogZW1wdHlGdW5jdGlvbldpdGhSZXNldCxcbiAgICByZXNldFdhcm5pbmdDYWNoZTogZW1wdHlGdW5jdGlvblxuICB9O1xuXG4gIFJlYWN0UHJvcFR5cGVzLlByb3BUeXBlcyA9IFJlYWN0UHJvcFR5cGVzO1xuXG4gIHJldHVybiBSZWFjdFByb3BUeXBlcztcbn07XG4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///703\n")},697:(module,__unused_webpack_exports,__webpack_require__)=>{eval("/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nif (false) { var throwOnDirectAccess, ReactIs; } else {\n // By explicitly using `prop-types` you are opting into new production behavior.\n // http://fb.me/prop-types-in-prod\n module.exports = __webpack_require__(703)();\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9wcm9wLXR5cGVzL2luZGV4LmpzP2Q3YmMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLElBQUksS0FBcUMsRUFBRSxxQ0FPMUM7QUFDRDtBQUNBO0FBQ0EsbUJBQW1CLG1CQUFPLENBQUMsR0FBNEI7QUFDdkQiLCJmaWxlIjoiNjk3LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtcHJlc2VudCwgRmFjZWJvb2ssIEluYy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICB2YXIgUmVhY3RJcyA9IHJlcXVpcmUoJ3JlYWN0LWlzJyk7XG5cbiAgLy8gQnkgZXhwbGljaXRseSB1c2luZyBgcHJvcC10eXBlc2AgeW91IGFyZSBvcHRpbmcgaW50byBuZXcgZGV2ZWxvcG1lbnQgYmVoYXZpb3IuXG4gIC8vIGh0dHA6Ly9mYi5tZS9wcm9wLXR5cGVzLWluLXByb2RcbiAgdmFyIHRocm93T25EaXJlY3RBY2Nlc3MgPSB0cnVlO1xuICBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZmFjdG9yeVdpdGhUeXBlQ2hlY2tlcnMnKShSZWFjdElzLmlzRWxlbWVudCwgdGhyb3dPbkRpcmVjdEFjY2Vzcyk7XG59IGVsc2Uge1xuICAvLyBCeSBleHBsaWNpdGx5IHVzaW5nIGBwcm9wLXR5cGVzYCB5b3UgYXJlIG9wdGluZyBpbnRvIG5ldyBwcm9kdWN0aW9uIGJlaGF2aW9yLlxuICAvLyBodHRwOi8vZmIubWUvcHJvcC10eXBlcy1pbi1wcm9kXG4gIG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9mYWN0b3J5V2l0aFRocm93aW5nU2hpbXMnKSgpO1xufVxuIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///697\n")},268:module=>{"use strict";eval("/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\n\nvar ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';\n\nmodule.exports = ReactPropTypesSecret;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9wcm9wLXR5cGVzL2xpYi9SZWFjdFByb3BUeXBlc1NlY3JldC5qcz81OWIwIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFYTs7QUFFYjs7QUFFQSIsImZpbGUiOiIyNjguanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvcHlyaWdodCAoYykgMjAxMy1wcmVzZW50LCBGYWNlYm9vaywgSW5jLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIFJlYWN0UHJvcFR5cGVzU2VjcmV0ID0gJ1NFQ1JFVF9ET19OT1RfUEFTU19USElTX09SX1lPVV9XSUxMX0JFX0ZJUkVEJztcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdFByb3BUeXBlc1NlY3JldDtcbiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///268\n")},188:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval('\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n "default": () => (/* binding */ index)\n});\n\n// UNUSED EXPORTS: BoundingBox, ContextProvider, DocumentContext, DocumentWrapper, DownloadButton, HighlightOverlay, Outline, OutlineItem, Overlay, PageNumberControl, PageWrapper, ScrollContext, TransformContext, UiContext, ZoomInButton, ZoomOutButton, computeBoundingBoxStyle, computePageStyle, generatePageIdFromIndex, getPageHeight, getPageWidth, isSideways, rotateClockwise, rotateCounterClockwise, scaleRawBoundingBox, scrollToId, scrollToPdfPageIndex\n\n// EXTERNAL MODULE: ./node_modules/classnames/index.js\nvar classnames = __webpack_require__(184);\nvar classnames_default = /*#__PURE__*/__webpack_require__.n(classnames);\n// EXTERNAL MODULE: external {"commonjs":"react","commonjs2":"react","amd":"react","root":"React"}\nvar external_commonjs_react_commonjs2_react_amd_react_root_React_ = __webpack_require__(888);\nvar external_commonjs_react_commonjs2_react_amd_react_root_React_default = /*#__PURE__*/__webpack_require__.n(external_commonjs_react_commonjs2_react_amd_react_root_React_);\n;// CONCATENATED MODULE: ./src/utils/provider.ts\nfunction logProviderWarning(functionName, providerName) {\n console.warn(`Unable to call ${functionName}. The ${providerName} Provider may not be set up correctly.`);\n}\n\n;// CONCATENATED MODULE: ./src/utils/rotate.ts\nvar PageRotation;\n(function (PageRotation) {\n PageRotation[PageRotation["Rotate0"] = 0] = "Rotate0";\n PageRotation[PageRotation["Rotate90"] = 90] = "Rotate90";\n PageRotation[PageRotation["Rotate180"] = 180] = "Rotate180";\n PageRotation[PageRotation["Rotate270"] = 270] = "Rotate270";\n})(PageRotation || (PageRotation = {}));\nfunction rotateClockwise(rotation) {\n switch (rotation) {\n case PageRotation.Rotate0:\n return PageRotation.Rotate90;\n case PageRotation.Rotate90:\n return PageRotation.Rotate180;\n case PageRotation.Rotate180:\n return PageRotation.Rotate270;\n default:\n return PageRotation.Rotate0;\n }\n}\nfunction rotateCounterClockwise(rotation) {\n switch (rotation) {\n case PageRotation.Rotate0:\n return PageRotation.Rotate270;\n case PageRotation.Rotate90:\n return PageRotation.Rotate0;\n case PageRotation.Rotate180:\n return PageRotation.Rotate90;\n default:\n return PageRotation.Rotate180;\n }\n}\n/**\n * Tests whether the page is rotated 90 degrees clockwise or counterclockwise from zero,\n * e.g. whether the page "is rotated sideways."\n */\nfunction isSideways(rotation) {\n return rotation === PageRotation.Rotate90 || rotation === PageRotation.Rotate270;\n}\n\n;// CONCATENATED MODULE: ./src/utils/scroll.ts\n\n// Each page div is ID\'d according to page index\n// e.g. reader_pg_0, reader_pg_1, etc.\nconst PAGE_NAV_TARGET_ID_ROOT = \'reader_pg_\';\nconst PDF_HEIGHT_POINTS = 792;\nconst PDF_WIDTH_POINTS = 612;\nfunction generatePageIdFromIndex(pageIndex) {\n return `${PAGE_NAV_TARGET_ID_ROOT}${pageIndex}`;\n}\nfunction scrollToId(id) {\n const element = document.getElementById(id);\n if (element) {\n element.scrollIntoView({ behavior: \'smooth\', block: \'start\', inline: \'center\' });\n }\n else {\n console.error(`Could not find scroll target with ID #${id}`);\n }\n}\nfunction scrollToPdfPageIndex(pageIndex) {\n scrollToId(generatePageIdFromIndex(pageIndex));\n}\n/**\n * Scroll PDF document to a specific position.\n * @param pageIndex The index of the page where the position locates at\n * @param leftPoints The horizontal distance between the origin and the position (in PDF coordinates)\n * @param bottomPoints The vertical distance between the origin and the position (in PDF coordinates)\n * @param rotation The rotation degree of the document\n */\nfunction scrollToPosition(pageIndex, leftPoints, bottomPoints, rotation = PageRotation.Rotate0) {\n /*\n Vertical scroll distance is calculated as\n = total number of previous pages * page height including top/down margins\n + the margin top of current page\n + the distance from the page top to the specified position\n \n Notice that the scroll distance is measured in pixels,\n so leftPoints/bottomPoints has to be transformed from points to pixels first.\n */\n const { width, height, marginTop, marginBottom, marginLeft, marginRight } = getPagePropertiesInPixels();\n const heightWithMargins = height + marginTop + marginBottom;\n // When a paper is rotated, its height and width would be switched automatically. However, leftPoints and bottomPoints remain the same.\n let marginTopPixels = marginTop;\n let bottomPixels = (height * bottomPoints) / PDF_HEIGHT_POINTS;\n let leftPixels = (width * leftPoints) / PDF_WIDTH_POINTS;\n if (rotation == PageRotation.Rotate90) {\n marginTopPixels = marginLeft;\n bottomPixels = (height * (PDF_WIDTH_POINTS - leftPoints)) / PDF_WIDTH_POINTS;\n leftPixels = (width * bottomPoints) / PDF_HEIGHT_POINTS;\n }\n else if (rotation == PageRotation.Rotate180) {\n marginTopPixels = marginBottom;\n bottomPixels = (height * (PDF_HEIGHT_POINTS - bottomPoints)) / PDF_HEIGHT_POINTS;\n leftPixels = (width * (PDF_WIDTH_POINTS - leftPoints)) / PDF_WIDTH_POINTS;\n }\n else if (rotation == PageRotation.Rotate270) {\n marginTopPixels = marginRight;\n bottomPixels = (height * leftPoints) / PDF_WIDTH_POINTS;\n leftPixels = (width * (PDF_HEIGHT_POINTS - bottomPoints)) / PDF_HEIGHT_POINTS;\n }\n // Find page element\n const pageId = generatePageIdFromIndex(pageIndex);\n const pageIdElement = document.getElementById(pageId);\n if (!pageIdElement) {\n return;\n }\n // Find first scrollable parent\n const parentElement = getScrollParent(pageIdElement);\n if (!parentElement) {\n return;\n }\n // Apply scroll\n parentElement.scrollTo({\n top: calculateTopPx({\n heightWithMarginsInPx: heightWithMargins,\n pageIndex: pageIndex,\n marginTopPx: marginTopPixels,\n heightPx: height,\n bottomPx: bottomPixels,\n }),\n left: Math.floor(leftPixels),\n behavior: \'smooth\',\n });\n}\nfunction getScrollParent(node) {\n if (typeof document === \'undefined\') {\n return null;\n }\n if (!node || node.nodeName.toLowerCase() === \'body\') {\n return document.documentElement;\n }\n if (node.scrollHeight > node.clientHeight && !isOverflowIsHidden(node)) {\n return node;\n }\n return getScrollParent(node.parentElement);\n}\nfunction isOverflowIsHidden(node) {\n const style = getComputedStyle(node);\n return (style.overflow.includes(\'hidden\') ||\n style.overflowX.includes(\'hidden\') ||\n style.overflowY.includes(\'hidden\'));\n}\nfunction calculateTopPx({ heightWithMarginsInPx, pageIndex, marginTopPx, heightPx, bottomPx, }) {\n return Math.floor(heightWithMarginsInPx * pageIndex + marginTopPx + (heightPx - bottomPx));\n}\n/**\n * Get lengths, widths, and margins of a page.\n * @returns a PageProperties object\n */\nfunction getPagePropertiesInPixels() {\n const firstPage = document.getElementById(generatePageIdFromIndex(0));\n if (!firstPage) {\n console.error(`Cannot get the first page of this document.`);\n const emptyPageProperties = {\n width: 0,\n height: 0,\n marginTop: 0,\n marginBottom: 0,\n marginLeft: 0,\n marginRight: 0,\n };\n return emptyPageProperties;\n }\n const style = getComputedStyle(firstPage);\n const pageProperties = {\n width: parseInt(style.width),\n height: parseInt(style.height),\n marginTop: parseInt(style.marginTop),\n marginBottom: parseInt(style.marginBottom),\n marginLeft: parseInt(style.marginLeft),\n marginRight: parseInt(style.marginRight),\n };\n return pageProperties;\n}\nfunction calculateTargetPosition({ scale, leftPoint, bottomPoint, pageDimensions, rotation = PageRotation.Rotate0, }) {\n switch (rotation) {\n default:\n case PageRotation.Rotate0: {\n const leftPx = (leftPoint / PDF_WIDTH_POINTS) * pageDimensions.width * scale;\n const topPx = (1 - bottomPoint / PDF_HEIGHT_POINTS) * pageDimensions.height * scale;\n return { leftPx, topPx };\n }\n }\n}\n\n;// CONCATENATED MODULE: ./src/context/DocumentContext.ts\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n\n\n\nconst DocumentContext_DocumentContext = external_commonjs_react_commonjs2_react_amd_react_root_React_.createContext({\n numPages: 0,\n outline: [],\n outlinePositions: null,\n pageDimensions: { height: 0, width: 0 },\n pdfDocProxy: undefined,\n getOutlineTargets: opts => {\n logProviderWarning(`getOutlineTargets(${JSON.stringify(opts)})`, \'DocumentContext\');\n return [];\n },\n setNumPages: numPages => {\n logProviderWarning(`setNumPages(${numPages})`, \'DocumentContext\');\n },\n setOutline: outline => {\n logProviderWarning(`setOutline(${outline})`, \'DocumentContext\');\n },\n setOutlinePositions: outline => {\n logProviderWarning(`setOutlinePositions(${outline})`, \'DocumentContext\');\n },\n setPageDimensions: pageDimensions => {\n logProviderWarning(`setPageDimensions(${pageDimensions})`, \'DocumentContext\');\n },\n setPdfDocProxy: pdfDocProxy => {\n logProviderWarning(`setPdfDocProxy(${pdfDocProxy})`, \'DocumentContext\');\n },\n});\nfunction useDocumentContextProps() {\n const [numPages, setNumPages] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(0);\n const [outline, setOutline] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(null);\n const [outlinePositions, setOutlinePositions] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(null);\n const [pageDimensions, setPageDimensions] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState({ height: 0, width: 0 });\n const [pdfDocProxy, setPdfDocProxy] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState();\n // Draw outline target into the pdf based on the args\n const getOutlineTargets = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(({ pageNumber, pageIndex, scale, rotation, pageDimensions, }) => {\n if (typeof pageIndex === \'number\') {\n pageNumber = pageIndex + 1;\n }\n if (typeof pageNumber !== \'number\') {\n return [];\n }\n const positions = (outlinePositions === null || outlinePositions === void 0 ? void 0 : outlinePositions.get(pageNumber)) || [];\n return positions.map(({ dest, leftPoint, bottomPoint }) => {\n const { leftPx, topPx } = calculateTargetPosition({\n scale,\n rotation,\n leftPoint,\n bottomPoint,\n pageDimensions,\n });\n return {\n dest,\n leftPx,\n topPx,\n };\n });\n }, [outlinePositions]);\n return {\n numPages,\n outline,\n outlinePositions,\n pageDimensions,\n pdfDocProxy,\n getOutlineTargets,\n setNumPages,\n setOutline,\n setOutlinePositions,\n setPageDimensions: setPageDimensions,\n setPdfDocProxy,\n };\n}\nfunction buildOutlinePositions(pdfDocProxy, outline) {\n var _a;\n return __awaiter(this, void 0, void 0, function* () {\n if (!outline) {\n outline = yield pdfDocProxy.getOutline();\n }\n // Depth first search through outline items\n const itemQueue = outline.slice();\n const proms = [];\n while (itemQueue.length > 0) {\n const item = itemQueue.pop();\n if (!item) {\n continue; // Not able to process\n }\n const { dest, items } = item;\n // Add child items to queue\n if (Array.isArray(items)) {\n itemQueue.push(...items);\n }\n // Fetch destinations for item\n if (Array.isArray(dest)) {\n proms.push(...dest.map(dest => getDestination(pdfDocProxy, dest)));\n }\n else if (typeof dest === \'string\') {\n proms.push(getDestination(pdfDocProxy, dest));\n }\n }\n // Collect results all at once, so we don\'t have to pay for the cost of\n // queueing messages sent to the worker\n const results = yield Promise.all(proms);\n // Split results into pages\n const map = new Map();\n for (const result of results) {\n if (!result) {\n continue; // Filter out null\n }\n const { pageNumber } = result;\n if (!map.has(pageNumber)) {\n map.set(pageNumber, []);\n }\n (_a = map.get(pageNumber)) === null || _a === void 0 ? void 0 : _a.push(result);\n }\n // Freeze objects so consumers cannot mutate\n for (const pagePos of map.values()) {\n for (const pos of pagePos) {\n Object.freeze(pos);\n }\n Object.freeze(pagePos);\n }\n Object.freeze(map);\n return map;\n });\n}\nfunction getDestination(pdfDocProxy, dest) {\n return __awaiter(this, void 0, void 0, function* () {\n const result = yield pdfDocProxy.getDestination(dest);\n if (!result) {\n return null;\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const [ref, _format, leftPoint, bottomPoint] = result;\n const pageIndex = yield pdfDocProxy.getPageIndex(ref);\n const pageNumber = pageIndex + 1;\n return { pageNumber, dest, leftPoint, bottomPoint };\n });\n}\n\n;// CONCATENATED MODULE: ./src/context/TransformContext.ts\n\n\n\nconst TransformContext = external_commonjs_react_commonjs2_react_amd_react_root_React_.createContext({\n rotation: PageRotation.Rotate0,\n scale: 1,\n zoomMultiplier: 1.2,\n isScaleChanged: false,\n setRotation: rotation => {\n logProviderWarning(`setRotation(${rotation})`, \'TransformContext\');\n },\n setScale: scale => {\n logProviderWarning(`setScale(${scale})`, \'TransformContext\');\n },\n setZoomMultiplier: zoom => {\n logProviderWarning(`setZoomMultiplier(${zoom})`, \'TransformContext\');\n },\n setIsScaleChanged: isScaleChange => {\n logProviderWarning(`setIsScaleChanged(${isScaleChange})`, \'TransformContext\');\n },\n});\nfunction useTransformContextProps() {\n const [rotation, setRotation] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(PageRotation.Rotate0);\n const [scale, setScale] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(1.0);\n const [zoomMultiplier, setZoomMultiplier] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(1.2);\n const [isScaleChanged, setIsScaleChanged] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(false);\n return {\n rotation,\n scale,\n isScaleChanged,\n setRotation,\n setScale,\n setZoomMultiplier,\n setIsScaleChanged,\n zoomMultiplier,\n };\n}\n\n;// CONCATENATED MODULE: ./src/utils/style.ts\n\n// Computes the style for a bounding box, accounting for page roation and page scaling/zoom\nfunction computeBoundingBoxStyle(boundingBoxSize, pageDimensions, rotation, scale) {\n const { top, left, height, width } = boundingBoxSize;\n switch (rotation) {\n case PageRotation.Rotate90:\n return {\n top: left * scale,\n left: (pageDimensions.height - height - top) * scale,\n height: width * scale,\n width: height * scale,\n };\n case PageRotation.Rotate180:\n return {\n top: (pageDimensions.height - height - top) * scale,\n left: (pageDimensions.width - width - left) * scale,\n height: height * scale,\n width: width * scale,\n };\n case PageRotation.Rotate270:\n return {\n top: (pageDimensions.width - width - left) * scale,\n left: top * scale,\n height: width * scale,\n width: height * scale,\n };\n default:\n return {\n top: top * scale,\n left: left * scale,\n height: height * scale,\n width: width * scale,\n };\n }\n}\n// Compute the style for a page, accounting for page rotation and page scaling/zoom\nfunction computePageStyle(pageDimensions, rotation, scale) {\n return {\n height: getPageHeight(pageDimensions, rotation) * scale,\n width: getPageWidth(pageDimensions, rotation) * scale,\n left: 0,\n top: 0,\n };\n}\n// Get page height accounting for page rotation- if the page is rotated on its side, its width becomes its height\nfunction getPageHeight(pageDimensions, rotation) {\n return isSideways(rotation) ? pageDimensions.width : pageDimensions.height;\n}\n// Get page width accounting for page rotation- if the page is rotated on its side, its height becomes its width\nfunction getPageWidth(pageDimensions, rotation) {\n return isSideways(rotation) ? pageDimensions.height : pageDimensions.width;\n}\n\n;// CONCATENATED MODULE: ./src/components/BoundingBox.tsx\nvar __rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\n\nconst BoundingBox = (_a) => {\n var { top, left, height, width, className, id, isHighlighted, onClick } = _a, extraProps = __rest(_a, ["top", "left", "height", "width", "className", "id", "isHighlighted", "onClick"]);\n const { pageDimensions } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(DocumentContext_DocumentContext);\n const { rotation, scale } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(TransformContext);\n const boxSize = { top, left, height, width };\n const componentClassName = classnames_default()(\'reader__page-overlay__bounding-box\', isHighlighted === true ? \'reader__page-overlay__bounding-box-highlighted\' : \'\', className);\n const getBoundingBoxStyle = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(() => {\n return computeBoundingBoxStyle(boxSize, pageDimensions, rotation, scale);\n }, [pageDimensions, rotation, scale]);\n const rotationClassName = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(() => {\n return `rotate${rotation}`;\n }, [rotation]);\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(external_commonjs_react_commonjs2_react_amd_react_root_React_.Fragment, null,\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("div", { className: `reader__page-overlay__bounding-box-underline ${rotationClassName()}`, style: getBoundingBoxStyle() }),\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("div", Object.assign({ id: id, className: `${componentClassName} ${rotationClassName()}`, style: getBoundingBoxStyle(), onClick: onClick }, extraProps))));\n};\n\n// EXTERNAL MODULE: ./node_modules/pdfjs-dist/build/pdf.js\nvar pdf = __webpack_require__(299);\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/extends.js\nfunction extends_extends() {\n extends_extends = Object.assign || function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n };\n\n return extends_extends.apply(this, arguments);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js\nfunction _objectWithoutPropertiesLoose(source, excluded) {\n if (source == null) return {};\n var target = {};\n var sourceKeys = Object.keys(source);\n var key, i;\n\n for (i = 0; i < sourceKeys.length; i++) {\n key = sourceKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n target[key] = source[key];\n }\n\n return target;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js\n\nfunction _objectWithoutProperties(source, excluded) {\n if (source == null) return {};\n var target = _objectWithoutPropertiesLoose(source, excluded);\n var key, i;\n\n if (Object.getOwnPropertySymbols) {\n var sourceSymbolKeys = Object.getOwnPropertySymbols(source);\n\n for (i = 0; i < sourceSymbolKeys.length; i++) {\n key = sourceSymbolKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;\n target[key] = source[key];\n }\n }\n\n return target;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/typeof.js\nfunction _typeof(obj) {\n "@babel/helpers - typeof";\n\n return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;\n }, _typeof(obj);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/classCallCheck.js\nfunction _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError("Cannot call a class as a function");\n }\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/createClass.js\nfunction _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if ("value" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nfunction _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n Object.defineProperty(Constructor, "prototype", {\n writable: false\n });\n return Constructor;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js\nfunction _assertThisInitialized(self) {\n if (self === void 0) {\n throw new ReferenceError("this hasn\'t been initialised - super() hasn\'t been called");\n }\n\n return self;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js\nfunction _setPrototypeOf(o, p) {\n _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n\n return _setPrototypeOf(o, p);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/inherits.js\n\nfunction _inherits(subClass, superClass) {\n if (typeof superClass !== "function" && superClass !== null) {\n throw new TypeError("Super expression must either be null or a function");\n }\n\n Object.defineProperty(subClass, "prototype", {\n value: Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n writable: true,\n configurable: true\n }\n }),\n writable: false\n });\n if (superClass) _setPrototypeOf(subClass, superClass);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js\n\n\nfunction _possibleConstructorReturn(self, call) {\n if (call && (_typeof(call) === "object" || typeof call === "function")) {\n return call;\n } else if (call !== void 0) {\n throw new TypeError("Derived constructors may only return object or undefined");\n }\n\n return _assertThisInitialized(self);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js\nfunction _getPrototypeOf(o) {\n _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {\n return o.__proto__ || Object.getPrototypeOf(o);\n };\n return _getPrototypeOf(o);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/defineProperty.js\nfunction _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}\n// EXTERNAL MODULE: ./node_modules/prop-types/index.js\nvar prop_types = __webpack_require__(697);\nvar prop_types_default = /*#__PURE__*/__webpack_require__.n(prop_types);\n;// CONCATENATED MODULE: ./node_modules/make-event-props/dist/esm/index.js\n// As defined on the list of supported events: https://reactjs.org/docs/events.html\nvar clipboardEvents = [\'onCopy\', \'onCut\', \'onPaste\'];\nvar compositionEvents = [\'onCompositionEnd\', \'onCompositionStart\', \'onCompositionUpdate\'];\nvar keyboardEvents = [\'onKeyDown\', \'onKeyPress\', \'onKeyUp\'];\nvar focusEvents = [\'onFocus\', \'onBlur\'];\nvar formEvents = [\'onChange\', \'onInput\', \'onInvalid\', \'onReset\', \'onSubmit\'];\nvar genericEvents = [\'onError\', \'onLoad\'];\nvar mouseEvents = [\'onClick\', \'onContextMenu\', \'onDoubleClick\', \'onDrag\', \'onDragEnd\', \'onDragEnter\', \'onDragExit\', \'onDragLeave\', \'onDragOver\', \'onDragStart\', \'onDrop\', \'onMouseDown\', \'onMouseEnter\', \'onMouseLeave\', \'onMouseMove\', \'onMouseOut\', \'onMouseOver\', \'onMouseUp\'];\nvar pointerEvents = [\'onPointerDown\', \'onPointerMove\', \'onPointerUp\', \'onPointerCancel\', \'onGotPointerCapture\', \'onLostPointerCapture\', \'onPointerEnter\', \'onPointerLeave\', \'onPointerOver\', \'onPointerOut\'];\nvar selectionEvents = [\'onSelect\'];\nvar touchEvents = [\'onTouchCancel\', \'onTouchEnd\', \'onTouchMove\', \'onTouchStart\'];\nvar uiEvents = [\'onScroll\'];\nvar wheelEvents = [\'onWheel\'];\nvar mediaEvents = [\'onAbort\', \'onCanPlay\', \'onCanPlayThrough\', \'onDurationChange\', \'onEmptied\', \'onEncrypted\', \'onEnded\', \'onError\', \'onLoadedData\', \'onLoadedMetadata\', \'onLoadStart\', \'onPause\', \'onPlay\', \'onPlaying\', \'onProgress\', \'onRateChange\', \'onSeeked\', \'onSeeking\', \'onStalled\', \'onSuspend\', \'onTimeUpdate\', \'onVolumeChange\', \'onWaiting\'];\nvar imageEvents = [\'onLoad\', \'onError\'];\nvar animationEvents = [\'onAnimationStart\', \'onAnimationEnd\', \'onAnimationIteration\'];\nvar transitionEvents = [\'onTransitionEnd\'];\nvar otherEvents = [\'onToggle\'];\nvar allEvents = [].concat(clipboardEvents, compositionEvents, keyboardEvents, focusEvents, formEvents, genericEvents, mouseEvents, pointerEvents, selectionEvents, touchEvents, uiEvents, wheelEvents, mediaEvents, imageEvents, animationEvents, transitionEvents, otherEvents);\n/**\n * Returns an object with on-event callback props curried with provided args.\n * @param {Object} props Props passed to a component.\n * @param {Function=} getArgs A function that returns argument(s) on-event callbacks\n * shall be curried with.\n */\n\nvar makeEventProps = function makeEventProps(props, getArgs) {\n var eventProps = {};\n allEvents.forEach(function (eventName) {\n if (!(eventName in props)) {\n return;\n }\n\n if (!getArgs) {\n eventProps[eventName] = props[eventName];\n return;\n }\n\n eventProps[eventName] = function (event) {\n return props[eventName](event, getArgs(eventName));\n };\n });\n return eventProps;\n};\n\n/* harmony default export */ const esm = (makeEventProps);\n;// CONCATENATED MODULE: ./node_modules/make-cancellable-promise/dist/esm/index.js\nfunction makeCancellablePromise(promise) {\n var isCancelled = false;\n var wrappedPromise = new Promise(function (resolve, reject) {\n promise.then(function () {\n return !isCancelled && resolve.apply(void 0, arguments);\n })["catch"](function (error) {\n return !isCancelled && reject(error);\n });\n });\n return {\n promise: wrappedPromise,\n cancel: function cancel() {\n isCancelled = true;\n }\n };\n}\n;// CONCATENATED MODULE: ./node_modules/merge-class-names/dist/esm/index.js\nfunction mergeClassNames() {\n return Array.prototype.slice.call(arguments).reduce(function (classList, arg) {\n return classList.concat(arg);\n }, []).filter(function (arg) {\n return typeof arg === \'string\';\n }).join(\' \');\n}\n;// CONCATENATED MODULE: ./node_modules/tiny-invariant/dist/tiny-invariant.esm.js\nvar isProduction = "production" === \'production\';\nvar prefix = \'Invariant failed\';\nfunction invariant(condition, message) {\n if (condition) {\n return;\n }\n if (isProduction) {\n throw new Error(prefix);\n }\n var provided = typeof message === \'function\' ? message() : message;\n var value = provided ? prefix + ": " + provided : prefix;\n throw new Error(value);\n}\n\n\n\n;// CONCATENATED MODULE: ./node_modules/tiny-warning/dist/tiny-warning.esm.js\nvar tiny_warning_esm_isProduction = "production" === \'production\';\nfunction warning(condition, message) {\n if (!tiny_warning_esm_isProduction) {\n if (condition) {\n return;\n }\n\n var text = "Warning: " + message;\n\n if (typeof console !== \'undefined\') {\n console.warn(text);\n }\n\n try {\n throw Error(text);\n } catch (x) {}\n }\n}\n\n/* harmony default export */ const tiny_warning_esm = (warning);\n\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/DocumentContext.js\n\n/* harmony default export */ const esm_DocumentContext = (/*#__PURE__*/(0,external_commonjs_react_commonjs2_react_amd_react_root_React_.createContext)(null));\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/Message.js\n\n\nfunction Message(_ref) {\n var children = _ref.children,\n type = _ref.type;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("div", {\n className: "react-pdf__message react-pdf__message--".concat(type)\n }, children);\n}\nMessage.propTypes = {\n children: (prop_types_default()).node,\n type: prop_types_default().oneOf([\'error\', \'loading\', \'no-data\']).isRequired\n};\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/LinkService.js\n\n\n\n/* Copyright 2015 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nvar DEFAULT_LINK_REL = \'noopener noreferrer nofollow\';\n\nvar LinkService = /*#__PURE__*/function () {\n function LinkService() {\n _classCallCheck(this, LinkService);\n\n this.externalLinkTarget = null;\n this.externalLinkRel = null;\n }\n\n _createClass(LinkService, [{\n key: "setDocument",\n value: function setDocument(pdfDocument) {\n this.pdfDocument = pdfDocument;\n }\n }, {\n key: "setViewer",\n value: function setViewer(pdfViewer) {\n this.pdfViewer = pdfViewer;\n }\n }, {\n key: "setExternalLinkRel",\n value: function setExternalLinkRel(externalLinkRel) {\n this.externalLinkRel = externalLinkRel;\n }\n }, {\n key: "setExternalLinkTarget",\n value: function setExternalLinkTarget(externalLinkTarget) {\n this.externalLinkTarget = externalLinkTarget;\n }\n }, {\n key: "setHistory",\n value: function setHistory() {}\n }, {\n key: "pagesCount",\n get: function get() {\n return this.pdfDocument ? this.pdfDocument.numPages : 0;\n }\n }, {\n key: "page",\n get: function get() {\n return this.pdfViewer.currentPageNumber;\n },\n set: function set(value) {\n this.pdfViewer.currentPageNumber = value;\n }\n }, {\n key: "rotation",\n get: function get() {\n return 0;\n },\n set: function set(value) {}\n }, {\n key: "goToDestination",\n value: function goToDestination(dest) {\n var _this = this;\n\n new Promise(function (resolve) {\n if (typeof dest === \'string\') {\n _this.pdfDocument.getDestination(dest).then(resolve);\n } else if (Array.isArray(dest)) {\n resolve(dest);\n } else {\n dest.then(resolve);\n }\n }).then(function (explicitDest) {\n invariant(Array.isArray(explicitDest), "\\"".concat(explicitDest, "\\" is not a valid destination array."));\n var destRef = explicitDest[0];\n new Promise(function (resolve) {\n if (destRef instanceof Object) {\n _this.pdfDocument.getPageIndex(destRef).then(function (pageIndex) {\n resolve(pageIndex);\n })["catch"](function () {\n invariant(false, "\\"".concat(destRef, "\\" is not a valid page reference."));\n });\n } else if (typeof destRef === \'number\') {\n resolve(destRef);\n } else {\n invariant(false, "\\"".concat(destRef, "\\" is not a valid destination reference."));\n }\n }).then(function (pageIndex) {\n var pageNumber = pageIndex + 1;\n invariant(pageNumber >= 1 && pageNumber <= _this.pagesCount, "\\"".concat(pageNumber, "\\" is not a valid page number."));\n\n _this.pdfViewer.scrollPageIntoView({\n dest: dest,\n pageIndex: pageIndex,\n pageNumber: pageNumber\n });\n });\n });\n }\n }, {\n key: "navigateTo",\n value: function navigateTo(dest) {\n this.goToDestination(dest);\n }\n }, {\n key: "goToPage",\n value: function goToPage() {}\n }, {\n key: "addLinkAttributes",\n value: function addLinkAttributes(link, url, newWindow) {\n link.href = url;\n link.rel = this.externalLinkRel || DEFAULT_LINK_REL;\n link.target = newWindow ? \'_blank\' : this.externalLinkTarget || \'\';\n }\n }, {\n key: "getDestinationHash",\n value: function getDestinationHash() {\n return \'#\';\n }\n }, {\n key: "getAnchorUrl",\n value: function getAnchorUrl() {\n return \'#\';\n }\n }, {\n key: "setHash",\n value: function setHash() {}\n }, {\n key: "executeNamedAction",\n value: function executeNamedAction() {}\n }, {\n key: "cachePageRef",\n value: function cachePageRef() {}\n }, {\n key: "isPageVisible",\n value: function isPageVisible() {\n return true;\n }\n }, {\n key: "isPageCached",\n value: function isPageCached() {\n return true;\n }\n }]);\n\n return LinkService;\n}();\n\n\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/PasswordResponses.js\n// As defined in https://github.com/mozilla/pdf.js/blob/d9fac3459609a807be6506fb3441b5da4b154d14/src/shared/util.js#L371-L374\nvar PasswordResponses = {\n NEED_PASSWORD: 1,\n INCORRECT_PASSWORD: 2\n};\n/* harmony default export */ const esm_PasswordResponses = (PasswordResponses);\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js\nfunction _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js\nfunction _iterableToArrayLimit(arr, i) {\n var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];\n\n if (_i == null) return;\n var _arr = [];\n var _n = true;\n var _d = false;\n\n var _s, _e;\n\n try {\n for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i["return"] != null) _i["return"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js\nfunction _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n\n for (var i = 0, arr2 = new Array(len); i < len; i++) {\n arr2[i] = arr[i];\n }\n\n return arr2;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js\n\nfunction _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === "string") return _arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === "Object" && o.constructor) n = o.constructor.name;\n if (n === "Map" || n === "Set") return Array.from(o);\n if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/nonIterableRest.js\nfunction _nonIterableRest() {\n throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/slicedToArray.js\n\n\n\n\nfunction _slicedToArray(arr, i) {\n return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();\n}\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/shared/utils.js\n\n\n\n/**\n * Checks if we\'re running in a browser environment.\n */\n\nvar isBrowser = typeof window !== \'undefined\';\n/**\n * Checks whether we\'re running from a local file system.\n */\n\nvar isLocalFileSystem = isBrowser && window.location.protocol === \'file:\';\n/**\n * Checks whether a variable is defined.\n *\n * @param {*} variable Variable to check\n */\n\nfunction isDefined(variable) {\n return typeof variable !== \'undefined\';\n}\n/**\n * Checks whether a variable is defined and not null.\n *\n * @param {*} variable Variable to check\n */\n\nfunction isProvided(variable) {\n return isDefined(variable) && variable !== null;\n}\n/**\n * Checkes whether a variable provided is a string.\n *\n * @param {*} variable Variable to check\n */\n\nfunction isString(variable) {\n return typeof variable === \'string\';\n}\n/**\n * Checks whether a variable provided is an ArrayBuffer.\n *\n * @param {*} variable Variable to check\n */\n\nfunction isArrayBuffer(variable) {\n return variable instanceof ArrayBuffer;\n}\n/**\n * Checkes whether a variable provided is a Blob.\n *\n * @param {*} variable Variable to check\n */\n\nfunction isBlob(variable) {\n invariant(isBrowser, \'isBlob can only be used in a browser environment\');\n return variable instanceof Blob;\n}\n/**\n * Checkes whether a variable provided is a File.\n *\n * @param {*} variable Variable to check\n */\n\nfunction isFile(variable) {\n invariant(isBrowser, \'isFile can only be used in a browser environment\');\n return variable instanceof File;\n}\n/**\n * Checks whether a string provided is a data URI.\n *\n * @param {string} str String to check\n */\n\nfunction isDataURI(str) {\n return isString(str) && /^data:/.test(str);\n}\nfunction dataURItoByteString(dataURI) {\n invariant(isDataURI(dataURI), \'Invalid data URI.\');\n\n var _dataURI$split = dataURI.split(\',\'),\n _dataURI$split2 = _slicedToArray(_dataURI$split, 2),\n headersString = _dataURI$split2[0],\n dataString = _dataURI$split2[1];\n\n var headers = headersString.split(\';\');\n\n if (headers.indexOf(\'base64\') !== -1) {\n return atob(dataString);\n }\n\n return unescape(dataString);\n}\nfunction getPixelRatio() {\n return isBrowser && window.devicePixelRatio || 1;\n}\nvar allowFileAccessFromFilesTip = \'On Chromium based browsers, you can use --allow-file-access-from-files flag for debugging purposes.\';\nfunction displayCORSWarning() {\n tiny_warning_esm(!isLocalFileSystem, "Loading PDF as base64 strings/URLs may not work on protocols other than HTTP/HTTPS. ".concat(allowFileAccessFromFilesTip));\n}\nfunction displayWorkerWarning() {\n tiny_warning_esm(!isLocalFileSystem, "Loading PDF.js worker may not work on protocols other than HTTP/HTTPS. ".concat(allowFileAccessFromFilesTip));\n}\nfunction cancelRunningTask(runningTask) {\n if (runningTask && runningTask.cancel) runningTask.cancel();\n}\nfunction makePageCallback(page, scale) {\n Object.defineProperty(page, \'width\', {\n get: function get() {\n return this.view[2] * scale;\n },\n configurable: true\n });\n Object.defineProperty(page, \'height\', {\n get: function get() {\n return this.view[3] * scale;\n },\n configurable: true\n });\n Object.defineProperty(page, \'originalWidth\', {\n get: function get() {\n return this.view[2];\n },\n configurable: true\n });\n Object.defineProperty(page, \'originalHeight\', {\n get: function get() {\n return this.view[3];\n },\n configurable: true\n });\n return page;\n}\nfunction isCancelException(error) {\n return error.name === \'RenderingCancelledException\';\n}\nfunction loadFromFile(file) {\n return new Promise(function (resolve, reject) {\n var reader = new FileReader();\n\n reader.onload = function () {\n return resolve(new Uint8Array(reader.result));\n };\n\n reader.onerror = function (event) {\n switch (event.target.error.code) {\n case event.target.error.NOT_FOUND_ERR:\n return reject(new Error(\'Error while reading a file: File not found.\'));\n\n case event.target.error.NOT_READABLE_ERR:\n return reject(new Error(\'Error while reading a file: File not readable.\'));\n\n case event.target.error.SECURITY_ERR:\n return reject(new Error(\'Error while reading a file: Security error.\'));\n\n case event.target.error.ABORT_ERR:\n return reject(new Error(\'Error while reading a file: Aborted.\'));\n\n default:\n return reject(new Error(\'Error while reading a file.\'));\n }\n };\n\n reader.readAsArrayBuffer(file);\n return null;\n });\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js\n\nfunction _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) return _arrayLikeToArray(arr);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/iterableToArray.js\nfunction _iterableToArray(iter) {\n if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js\nfunction _nonIterableSpread() {\n throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/toConsumableArray.js\n\n\n\n\nfunction _toConsumableArray(arr) {\n return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();\n}\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/shared/propTypes.js\n\n\n\n\n\n\nvar eventProps = function () {\n var result = {};\n [].concat(_toConsumableArray(mouseEvents), _toConsumableArray(touchEvents), _toConsumableArray(keyboardEvents)).forEach(function (eventName) {\n result[eventName] = (prop_types_default()).func;\n });\n return result;\n}();\nvar fileTypes = [(prop_types_default()).string, prop_types_default().instanceOf(ArrayBuffer), prop_types_default().shape({\n data: prop_types_default().oneOfType([(prop_types_default()).object, (prop_types_default()).string]),\n httpHeaders: (prop_types_default()).object,\n range: (prop_types_default()).object,\n url: (prop_types_default()).string,\n withCredentials: (prop_types_default()).bool\n})];\n\nif (typeof File !== \'undefined\') {\n fileTypes.push(prop_types_default().instanceOf(File));\n}\n\nif (typeof Blob !== \'undefined\') {\n fileTypes.push(prop_types_default().instanceOf(Blob));\n}\n\nvar isClassName = prop_types_default().oneOfType([(prop_types_default()).string, prop_types_default().arrayOf((prop_types_default()).string)]);\nvar propTypes_isFile = prop_types_default().oneOfType(fileTypes);\nvar isLinkService = prop_types_default().instanceOf(LinkService);\nvar isLinkTarget = prop_types_default().oneOf([\'_self\', \'_blank\', \'_parent\', \'_top\']);\nvar isPage = prop_types_default().shape({\n commonObjs: prop_types_default().shape({}).isRequired,\n getAnnotations: (prop_types_default()).func.isRequired,\n getTextContent: (prop_types_default()).func.isRequired,\n getViewport: (prop_types_default()).func.isRequired,\n render: (prop_types_default()).func.isRequired\n});\nvar isPageIndex = function isPageIndex(props, propName, componentName) {\n var pageIndex = props[propName],\n pageNumber = props.pageNumber,\n pdf = props.pdf;\n\n if (!isDefined(pdf)) {\n return null;\n }\n\n if (isDefined(pageIndex)) {\n if (typeof pageIndex !== \'number\') {\n return new Error("`".concat(propName, "` of type `").concat(_typeof(pageIndex), "` supplied to `").concat(componentName, "`, expected `number`."));\n }\n\n if (pageIndex < 0) {\n return new Error("Expected `".concat(propName, "` to be greater or equal to 0."));\n }\n\n var numPages = pdf.numPages;\n\n if (pageIndex + 1 > numPages) {\n return new Error("Expected `".concat(propName, "` to be less or equal to ").concat(numPages - 1, "."));\n }\n } else if (!isDefined(pageNumber)) {\n return new Error("`".concat(propName, "` not supplied. Either pageIndex or pageNumber must be supplied to `").concat(componentName, "`."));\n } // Everything is fine\n\n\n return null;\n};\nvar isPageNumber = function isPageNumber(props, propName, componentName) {\n var pageNumber = props[propName],\n pageIndex = props.pageIndex,\n pdf = props.pdf;\n\n if (!isDefined(pdf)) {\n return null;\n }\n\n if (isDefined(pageNumber)) {\n if (typeof pageNumber !== \'number\') {\n return new Error("`".concat(propName, "` of type `").concat(_typeof(pageNumber), "` supplied to `").concat(componentName, "`, expected `number`."));\n }\n\n if (pageNumber < 1) {\n return new Error("Expected `".concat(propName, "` to be greater or equal to 1."));\n }\n\n var numPages = pdf.numPages;\n\n if (pageNumber > numPages) {\n return new Error("Expected `".concat(propName, "` to be less or equal to ").concat(numPages, "."));\n }\n } else if (!isDefined(pageIndex)) {\n return new Error("`".concat(propName, "` not supplied. Either pageIndex or pageNumber must be supplied to `").concat(componentName, "`."));\n } // Everything is fine\n\n\n return null;\n};\nvar isPdf = prop_types_default().oneOfType([prop_types_default().shape({\n getDestination: (prop_types_default()).func.isRequired,\n getOutline: (prop_types_default()).func.isRequired,\n getPage: (prop_types_default()).func.isRequired,\n numPages: (prop_types_default()).number.isRequired\n}), (prop_types_default()).bool]);\nvar isRef = prop_types_default().oneOfType([(prop_types_default()).func, prop_types_default().shape({\n current: (prop_types_default()).any\n})]);\nvar isRenderMode = prop_types_default().oneOf([\'canvas\', \'none\', \'svg\']);\nvar isRotate = prop_types_default().oneOf([0, 90, 180, 270]);\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/Document.js\n\n\n\n\n\n\n\n\n\n\nvar _excluded = ["url"];\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\n/**\n * Loads a PDF document. Passes it to all children.\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar PDFDataRangeTransport = pdf.PDFDataRangeTransport;\n\nvar Document = /*#__PURE__*/function (_PureComponent) {\n _inherits(Document, _PureComponent);\n\n var _super = _createSuper(Document);\n\n function Document() {\n var _this;\n\n _classCallCheck(this, Document);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _super.call.apply(_super, [this].concat(args));\n\n _defineProperty(_assertThisInitialized(_this), "state", {\n pdf: null\n });\n\n _defineProperty(_assertThisInitialized(_this), "viewer", {\n scrollPageIntoView: function scrollPageIntoView(_ref) {\n var dest = _ref.dest,\n pageIndex = _ref.pageIndex,\n pageNumber = _ref.pageNumber;\n // Handling jumping to internal links target\n var onItemClick = _this.props.onItemClick; // First, check if custom handling of onItemClick was provided\n\n if (onItemClick) {\n onItemClick({\n dest: dest,\n pageIndex: pageIndex,\n pageNumber: pageNumber\n });\n return;\n } // If not, try to look for target page within the .\n\n\n var page = _this.pages[pageIndex];\n\n if (page) {\n // Scroll to the page automatically\n page.scrollIntoView();\n return;\n }\n\n tiny_warning_esm(false, "An internal link leading to page ".concat(pageNumber, " was clicked, but neither was provided with onItemClick nor it was able to find the page within itself. Either provide onItemClick to and handle navigating by yourself or ensure that all pages are rendered within ."));\n }\n });\n\n _defineProperty(_assertThisInitialized(_this), "linkService", new LinkService());\n\n _defineProperty(_assertThisInitialized(_this), "loadDocument", function () {\n // If another rendering is in progress, let\'s cancel it\n cancelRunningTask(_this.runningTask); // If another loading is in progress, let\'s destroy it\n\n if (_this.loadingTask) _this.loadingTask.destroy();\n var cancellable = makeCancellablePromise(_this.findDocumentSource());\n _this.runningTask = cancellable;\n cancellable.promise.then(function (source) {\n _this.onSourceSuccess();\n\n if (!source) {\n return;\n }\n\n _this.setState(function (prevState) {\n if (!prevState.pdf) {\n return null;\n }\n\n return {\n pdf: null\n };\n });\n\n var _this$props = _this.props,\n options = _this$props.options,\n onLoadProgress = _this$props.onLoadProgress,\n onPassword = _this$props.onPassword;\n _this.loadingTask = pdf.getDocument(_objectSpread(_objectSpread({}, source), options));\n _this.loadingTask.onPassword = onPassword;\n\n if (onLoadProgress) {\n _this.loadingTask.onProgress = onLoadProgress;\n }\n\n var cancellable = makeCancellablePromise(_this.loadingTask.promise);\n _this.runningTask = cancellable;\n cancellable.promise.then(function (pdf) {\n _this.setState(function (prevState) {\n if (prevState.pdf && prevState.pdf.fingerprint === pdf.fingerprint) {\n return null;\n }\n\n return {\n pdf: pdf\n };\n }, _this.onLoadSuccess);\n })["catch"](function (error) {\n _this.onLoadError(error);\n });\n })["catch"](function (error) {\n _this.onSourceError(error);\n });\n });\n\n _defineProperty(_assertThisInitialized(_this), "setupLinkService", function () {\n var _this$props2 = _this.props,\n externalLinkRel = _this$props2.externalLinkRel,\n externalLinkTarget = _this$props2.externalLinkTarget;\n\n _this.linkService.setViewer(_this.viewer);\n\n _this.linkService.setExternalLinkRel(externalLinkRel);\n\n _this.linkService.setExternalLinkTarget(externalLinkTarget);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onSourceSuccess", function () {\n var onSourceSuccess = _this.props.onSourceSuccess;\n if (onSourceSuccess) onSourceSuccess();\n });\n\n _defineProperty(_assertThisInitialized(_this), "onSourceError", function (error) {\n tiny_warning_esm(error);\n var onSourceError = _this.props.onSourceError;\n if (onSourceError) onSourceError(error);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onLoadSuccess", function () {\n var onLoadSuccess = _this.props.onLoadSuccess;\n var pdf = _this.state.pdf;\n if (onLoadSuccess) onLoadSuccess(pdf);\n _this.pages = new Array(pdf.numPages);\n\n _this.linkService.setDocument(pdf);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onLoadError", function (error) {\n _this.setState({\n pdf: false\n });\n\n tiny_warning_esm(error);\n var onLoadError = _this.props.onLoadError;\n if (onLoadError) onLoadError(error);\n });\n\n _defineProperty(_assertThisInitialized(_this), "findDocumentSource", function () {\n return new Promise(function (resolve) {\n var file = _this.props.file;\n\n if (!file) {\n resolve(null);\n } // File is a string\n\n\n if (typeof file === \'string\') {\n if (isDataURI(file)) {\n var fileByteString = dataURItoByteString(file);\n resolve({\n data: fileByteString\n });\n }\n\n displayCORSWarning();\n resolve({\n url: file\n });\n } // File is PDFDataRangeTransport\n\n\n if (file instanceof PDFDataRangeTransport) {\n resolve({\n range: file\n });\n } // File is an ArrayBuffer\n\n\n if (isArrayBuffer(file)) {\n resolve({\n data: file\n });\n }\n /**\n * The cases below are browser-only.\n * If you\'re running on a non-browser environment, these cases will be of no use.\n */\n\n\n if (isBrowser) {\n // File is a Blob\n if (isBlob(file) || isFile(file)) {\n loadFromFile(file).then(function (data) {\n resolve({\n data: data\n });\n });\n return;\n }\n } // At this point, file must be an object\n\n\n invariant(_typeof(file) === \'object\', \'Invalid parameter in file, need either Uint8Array, string or a parameter object\');\n invariant(file.url || file.data || file.range, \'Invalid parameter object: need either .data, .range or .url\'); // File .url is a string\n\n if (typeof file.url === \'string\') {\n if (isDataURI(file.url)) {\n var url = file.url,\n otherParams = _objectWithoutProperties(file, _excluded);\n\n var _fileByteString = dataURItoByteString(url);\n\n resolve(_objectSpread({\n data: _fileByteString\n }, otherParams));\n }\n\n displayCORSWarning();\n }\n\n resolve(file);\n });\n });\n\n _defineProperty(_assertThisInitialized(_this), "registerPage", function (pageIndex, ref) {\n _this.pages[pageIndex] = ref;\n });\n\n _defineProperty(_assertThisInitialized(_this), "unregisterPage", function (pageIndex) {\n delete _this.pages[pageIndex];\n });\n\n return _this;\n }\n\n _createClass(Document, [{\n key: "componentDidMount",\n value: function componentDidMount() {\n this.loadDocument();\n this.setupLinkService();\n }\n }, {\n key: "componentDidUpdate",\n value: function componentDidUpdate(prevProps) {\n var file = this.props.file;\n\n if (file !== prevProps.file) {\n this.loadDocument();\n }\n }\n }, {\n key: "componentWillUnmount",\n value: function componentWillUnmount() {\n // If rendering is in progress, let\'s cancel it\n cancelRunningTask(this.runningTask); // If loading is in progress, let\'s destroy it\n\n if (this.loadingTask) this.loadingTask.destroy();\n }\n }, {\n key: "childContext",\n get: function get() {\n var linkService = this.linkService,\n registerPage = this.registerPage,\n unregisterPage = this.unregisterPage;\n var _this$props3 = this.props,\n imageResourcesPath = _this$props3.imageResourcesPath,\n renderMode = _this$props3.renderMode,\n rotate = _this$props3.rotate;\n var pdf = this.state.pdf;\n return {\n imageResourcesPath: imageResourcesPath,\n linkService: linkService,\n pdf: pdf,\n registerPage: registerPage,\n renderMode: renderMode,\n rotate: rotate,\n unregisterPage: unregisterPage\n };\n }\n }, {\n key: "eventProps",\n get: function get() {\n var _this2 = this;\n\n return esm(this.props, function () {\n return _this2.state.pdf;\n });\n }\n /**\n * Called when a document source is resolved correctly\n */\n\n }, {\n key: "renderChildren",\n value: function renderChildren() {\n var children = this.props.children;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(esm_DocumentContext.Provider, {\n value: this.childContext\n }, children);\n }\n }, {\n key: "renderContent",\n value: function renderContent() {\n var file = this.props.file;\n var pdf = this.state.pdf;\n\n if (!file) {\n var noData = this.props.noData;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(Message, {\n type: "no-data"\n }, typeof noData === \'function\' ? noData() : noData);\n }\n\n if (pdf === null) {\n var loading = this.props.loading;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(Message, {\n type: "loading"\n }, typeof loading === \'function\' ? loading() : loading);\n }\n\n if (pdf === false) {\n var error = this.props.error;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(Message, {\n type: "error"\n }, typeof error === \'function\' ? error() : error);\n }\n\n return this.renderChildren();\n }\n }, {\n key: "render",\n value: function render() {\n var _this$props4 = this.props,\n className = _this$props4.className,\n inputRef = _this$props4.inputRef;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("div", extends_extends({\n className: mergeClassNames(\'react-pdf__Document\', className),\n ref: inputRef\n }, this.eventProps), this.renderContent());\n }\n }]);\n\n return Document;\n}(external_commonjs_react_commonjs2_react_amd_react_root_React_.PureComponent);\n\n\nDocument.defaultProps = {\n error: \'Failed to load PDF file.\',\n loading: \'Loading PDF…\',\n noData: \'No PDF file specified.\',\n onPassword: function onPassword(callback, reason) {\n switch (reason) {\n case esm_PasswordResponses.NEED_PASSWORD:\n {\n // eslint-disable-next-line no-alert\n var password = prompt(\'Enter the password to open this PDF file.\');\n callback(password);\n break;\n }\n\n case esm_PasswordResponses.INCORRECT_PASSWORD:\n {\n // eslint-disable-next-line no-alert\n var _password = prompt(\'Invalid password. Please try again.\');\n\n callback(_password);\n break;\n }\n\n default:\n }\n }\n};\nvar isFunctionOrNode = prop_types_default().oneOfType([(prop_types_default()).func, (prop_types_default()).node]);\nDocument.propTypes = _objectSpread(_objectSpread({}, eventProps), {}, {\n children: (prop_types_default()).node,\n className: isClassName,\n error: isFunctionOrNode,\n externalLinkRel: (prop_types_default()).string,\n externalLinkTarget: (prop_types_default()).string,\n file: propTypes_isFile,\n imageResourcesPath: (prop_types_default()).string,\n inputRef: isRef,\n loading: isFunctionOrNode,\n noData: isFunctionOrNode,\n onItemClick: (prop_types_default()).func,\n onLoadError: (prop_types_default()).func,\n onLoadProgress: (prop_types_default()).func,\n onLoadSuccess: (prop_types_default()).func,\n onPassword: (prop_types_default()).func,\n onSourceError: (prop_types_default()).func,\n onSourceSuccess: (prop_types_default()).func,\n rotate: (prop_types_default()).number\n});\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/OutlineContext.js\n\n/* harmony default export */ const OutlineContext = (/*#__PURE__*/(0,external_commonjs_react_commonjs2_react_amd_react_root_React_.createContext)(null));\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/Ref.js\n\n\n\nvar Ref = /*#__PURE__*/function () {\n function Ref(_ref) {\n var num = _ref.num,\n gen = _ref.gen;\n\n _classCallCheck(this, Ref);\n\n this.num = num;\n this.gen = gen;\n }\n\n _createClass(Ref, [{\n key: "toString",\n value: function toString() {\n var str = "".concat(this.num, "R");\n\n if (this.gen !== 0) {\n str += this.gen;\n }\n\n return str;\n }\n }]);\n\n return Ref;\n}();\n\n\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/OutlineItem.js\n\n\n\n\n\n\n\n\n\n\nvar OutlineItem_excluded = ["item"];\n\nfunction OutlineItem_createSuper(Derived) { var hasNativeReflectConstruct = OutlineItem_isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction OutlineItem_isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\n\n\n\n\n\n\n\nvar OutlineItemInternal = /*#__PURE__*/function (_PureComponent) {\n _inherits(OutlineItemInternal, _PureComponent);\n\n var _super = OutlineItem_createSuper(OutlineItemInternal);\n\n function OutlineItemInternal() {\n var _this;\n\n _classCallCheck(this, OutlineItemInternal);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _super.call.apply(_super, [this].concat(args));\n\n _defineProperty(_assertThisInitialized(_this), "getDestination", function () {\n return new Promise(function (resolve, reject) {\n var _this$props = _this.props,\n item = _this$props.item,\n pdf = _this$props.pdf;\n\n if (!isDefined(_this.destination)) {\n if (typeof item.dest === \'string\') {\n pdf.getDestination(item.dest).then(resolve)["catch"](reject);\n } else {\n resolve(item.dest);\n }\n }\n\n return _this.destination;\n }).then(function (destination) {\n _this.destination = destination;\n return destination;\n });\n });\n\n _defineProperty(_assertThisInitialized(_this), "getPageIndex", function () {\n return new Promise(function (resolve, reject) {\n var pdf = _this.props.pdf;\n\n if (isDefined(_this.pageIndex)) {\n resolve(_this.pageIndex);\n }\n\n _this.getDestination().then(function (destination) {\n if (!destination) {\n return;\n }\n\n var _destination = _slicedToArray(destination, 1),\n ref = _destination[0];\n\n pdf.getPageIndex(new Ref(ref)).then(resolve)["catch"](reject);\n });\n }).then(function (pageIndex) {\n _this.pageIndex = pageIndex;\n return _this.pageIndex;\n });\n });\n\n _defineProperty(_assertThisInitialized(_this), "getPageNumber", function () {\n return new Promise(function (resolve, reject) {\n if (isDefined(_this.pageNumber)) {\n resolve(_this.pageNumber);\n }\n\n _this.getPageIndex().then(function (pageIndex) {\n resolve(pageIndex + 1);\n })["catch"](reject);\n }).then(function (pageNumber) {\n _this.pageNumber = pageNumber;\n return pageNumber;\n });\n });\n\n _defineProperty(_assertThisInitialized(_this), "onClick", function (event) {\n var onClick = _this.props.onClick;\n event.preventDefault();\n\n if (!onClick) {\n return false;\n }\n\n return Promise.all([_this.getDestination(), _this.getPageIndex(), _this.getPageNumber()]).then(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 3),\n dest = _ref2[0],\n pageIndex = _ref2[1],\n pageNumber = _ref2[2];\n\n onClick({\n dest: dest,\n pageIndex: pageIndex,\n pageNumber: pageNumber\n });\n });\n });\n\n return _this;\n }\n\n _createClass(OutlineItemInternal, [{\n key: "renderSubitems",\n value: function renderSubitems() {\n var _this$props2 = this.props,\n item = _this$props2.item,\n otherProps = _objectWithoutProperties(_this$props2, OutlineItem_excluded);\n\n if (!item.items || !item.items.length) {\n return null;\n }\n\n var subitems = item.items;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("ul", null, subitems.map(function (subitem, subitemIndex) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(OutlineItemInternal, extends_extends({\n key: typeof subitem.destination === \'string\' ? subitem.destination : subitemIndex,\n item: subitem\n }, otherProps));\n }));\n }\n }, {\n key: "render",\n value: function render() {\n var item = this.props.item;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("li", null, /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("a", {\n href: "#",\n onClick: this.onClick\n }, item.title), this.renderSubitems());\n }\n }]);\n\n return OutlineItemInternal;\n}(external_commonjs_react_commonjs2_react_amd_react_root_React_.PureComponent);\nvar isDestination = prop_types_default().oneOfType([(prop_types_default()).string, prop_types_default().arrayOf((prop_types_default()).any)]);\nOutlineItemInternal.propTypes = {\n item: prop_types_default().shape({\n dest: isDestination,\n items: prop_types_default().arrayOf(prop_types_default().shape({\n dest: isDestination,\n title: (prop_types_default()).string\n })),\n title: (prop_types_default()).string\n }).isRequired,\n onClick: (prop_types_default()).func,\n pdf: isPdf.isRequired\n};\n\nvar OutlineItem = function OutlineItem(props) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(esm_DocumentContext.Consumer, null, function (documentContext) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(OutlineContext.Consumer, null, function (outlineContext) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(OutlineItemInternal, extends_extends({}, documentContext, outlineContext, props));\n });\n });\n};\n\n/* harmony default export */ const esm_OutlineItem = (OutlineItem);\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/Outline.js\n\n\n\n\n\n\n\n\n\nfunction Outline_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\n\nfunction Outline_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? Outline_ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : Outline_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\n\nfunction Outline_createSuper(Derived) { var hasNativeReflectConstruct = Outline_isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction Outline_isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar OutlineInternal = /*#__PURE__*/function (_PureComponent) {\n _inherits(OutlineInternal, _PureComponent);\n\n var _super = Outline_createSuper(OutlineInternal);\n\n function OutlineInternal() {\n var _this;\n\n _classCallCheck(this, OutlineInternal);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _super.call.apply(_super, [this].concat(args));\n\n _defineProperty(_assertThisInitialized(_this), "state", {\n outline: null\n });\n\n _defineProperty(_assertThisInitialized(_this), "loadOutline", function () {\n var pdf = _this.props.pdf;\n\n _this.setState(function (prevState) {\n if (!prevState.outline) {\n return null;\n }\n\n return {\n outline: null\n };\n });\n\n var cancellable = makeCancellablePromise(pdf.getOutline());\n _this.runningTask = cancellable;\n cancellable.promise.then(function (outline) {\n _this.setState({\n outline: outline\n }, _this.onLoadSuccess);\n })["catch"](function (error) {\n _this.onLoadError(error);\n });\n });\n\n _defineProperty(_assertThisInitialized(_this), "onLoadSuccess", function () {\n var onLoadSuccess = _this.props.onLoadSuccess;\n var outline = _this.state.outline;\n if (onLoadSuccess) onLoadSuccess(outline);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onLoadError", function (error) {\n _this.setState({\n outline: false\n });\n\n tiny_warning_esm(error);\n var onLoadError = _this.props.onLoadError;\n if (onLoadError) onLoadError(error);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onItemClick", function (_ref) {\n var dest = _ref.dest,\n pageIndex = _ref.pageIndex,\n pageNumber = _ref.pageNumber;\n var onItemClick = _this.props.onItemClick;\n\n if (onItemClick) {\n onItemClick({\n dest: dest,\n pageIndex: pageIndex,\n pageNumber: pageNumber\n });\n }\n });\n\n return _this;\n }\n\n _createClass(OutlineInternal, [{\n key: "componentDidMount",\n value: function componentDidMount() {\n var pdf = this.props.pdf;\n invariant(pdf, \'Attempted to load an outline, but no document was specified.\');\n this.loadOutline();\n }\n }, {\n key: "componentDidUpdate",\n value: function componentDidUpdate(prevProps) {\n var pdf = this.props.pdf;\n\n if (prevProps.pdf && pdf !== prevProps.pdf) {\n this.loadOutline();\n }\n }\n }, {\n key: "componentWillUnmount",\n value: function componentWillUnmount() {\n cancelRunningTask(this.runningTask);\n }\n }, {\n key: "childContext",\n get: function get() {\n return {\n onClick: this.onItemClick\n };\n }\n }, {\n key: "eventProps",\n get: function get() {\n var _this2 = this;\n\n return esm(this.props, function () {\n return _this2.state.outline;\n });\n }\n /**\n * Called when an outline is read successfully\n */\n\n }, {\n key: "renderOutline",\n value: function renderOutline() {\n var outline = this.state.outline;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("ul", null, outline.map(function (item, itemIndex) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(esm_OutlineItem, {\n key: typeof item.destination === \'string\' ? item.destination : itemIndex,\n item: item\n });\n }));\n }\n }, {\n key: "render",\n value: function render() {\n var pdf = this.props.pdf;\n var outline = this.state.outline;\n\n if (!pdf || !outline) {\n return null;\n }\n\n var _this$props = this.props,\n className = _this$props.className,\n inputRef = _this$props.inputRef;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("div", extends_extends({\n className: mergeClassNames(\'react-pdf__Outline\', className),\n ref: inputRef\n }, this.eventProps), /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(OutlineContext.Provider, {\n value: this.childContext\n }, this.renderOutline()));\n }\n }]);\n\n return OutlineInternal;\n}(external_commonjs_react_commonjs2_react_amd_react_root_React_.PureComponent);\nOutlineInternal.propTypes = Outline_objectSpread({\n className: isClassName,\n inputRef: isRef,\n onItemClick: (prop_types_default()).func,\n onLoadError: (prop_types_default()).func,\n onLoadSuccess: (prop_types_default()).func,\n pdf: isPdf\n}, eventProps);\n\nfunction Outline(props, ref) {\n return /*#__PURE__*/React.createElement(DocumentContext.Consumer, null, function (context) {\n return /*#__PURE__*/React.createElement(OutlineInternal, _extends({\n ref: ref\n }, context, props));\n });\n}\n\n/* harmony default export */ const esm_Outline = (/*#__PURE__*/(/* unused pure expression or super */ null && (React.forwardRef(Outline))));\n;// CONCATENATED MODULE: ./node_modules/merge-refs/dist/esm/index.js\n/**\n * A function that merges React refs into one.\n * Supports both functions and ref objects created using createRef() and useRef().\n *\n * Usage:\n * ```jsx\n *
\n * ```\n *\n * @param {...Array} inputRefs Array of refs\n * @returns {Function} Merged refs\n */\nfunction mergeRefs() {\n for (var _len = arguments.length, inputRefs = new Array(_len), _key = 0; _key < _len; _key++) {\n inputRefs[_key] = arguments[_key];\n }\n\n var filteredInputRefs = inputRefs.filter(Boolean);\n\n if (filteredInputRefs.length <= 1) {\n return filteredInputRefs[0];\n }\n\n return function mergedRefs(ref) {\n filteredInputRefs.forEach(function (inputRef) {\n if (typeof inputRef === \'function\') {\n inputRef(ref);\n } else {\n // eslint-disable-next-line no-param-reassign\n inputRef.current = ref;\n }\n });\n };\n}\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/PageContext.js\n\n/* harmony default export */ const PageContext = (/*#__PURE__*/(0,external_commonjs_react_commonjs2_react_amd_react_root_React_.createContext)(null));\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/Page/PageCanvas.js\n\n\n\n\n\n\n\n\n\nfunction PageCanvas_createSuper(Derived) { var hasNativeReflectConstruct = PageCanvas_isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction PageCanvas_isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\n\n\n\n\n\n\n\n\n\nvar ANNOTATION_MODE = pdf.AnnotationMode;\nvar PageCanvasInternal = /*#__PURE__*/function (_PureComponent) {\n _inherits(PageCanvasInternal, _PureComponent);\n\n var _super = PageCanvas_createSuper(PageCanvasInternal);\n\n function PageCanvasInternal() {\n var _this;\n\n _classCallCheck(this, PageCanvasInternal);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _super.call.apply(_super, [this].concat(args));\n\n _defineProperty(_assertThisInitialized(_this), "canvasElement", /*#__PURE__*/(0,external_commonjs_react_commonjs2_react_amd_react_root_React_.createRef)());\n\n _defineProperty(_assertThisInitialized(_this), "onRenderSuccess", function () {\n _this.renderer = null;\n var _this$props = _this.props,\n onRenderSuccess = _this$props.onRenderSuccess,\n page = _this$props.page,\n scale = _this$props.scale;\n if (onRenderSuccess) onRenderSuccess(makePageCallback(page, scale));\n });\n\n _defineProperty(_assertThisInitialized(_this), "onRenderError", function (error) {\n if (isCancelException(error)) {\n return;\n }\n\n tiny_warning_esm(error);\n var onRenderError = _this.props.onRenderError;\n if (onRenderError) onRenderError(error);\n });\n\n _defineProperty(_assertThisInitialized(_this), "drawPageOnCanvas", function () {\n var canvas = _this.canvasElement.current;\n\n if (!canvas) {\n return null;\n }\n\n var _assertThisInitialize = _assertThisInitialized(_this),\n renderViewport = _assertThisInitialize.renderViewport,\n viewport = _assertThisInitialize.viewport;\n\n var _this$props2 = _this.props,\n canvasBackground = _this$props2.canvasBackground,\n page = _this$props2.page,\n renderForms = _this$props2.renderForms;\n canvas.width = renderViewport.width;\n canvas.height = renderViewport.height;\n canvas.style.width = "".concat(Math.floor(viewport.width), "px");\n canvas.style.height = "".concat(Math.floor(viewport.height), "px");\n var renderContext = {\n annotationMode: renderForms ? ANNOTATION_MODE.ENABLE_FORMS : ANNOTATION_MODE.ENABLE,\n\n get canvasContext() {\n return canvas.getContext(\'2d\');\n },\n\n viewport: renderViewport\n };\n\n if (canvasBackground) {\n renderContext.background = canvasBackground;\n } // If another render is in progress, let\'s cancel it\n\n\n _this.cancelRenderingTask();\n\n _this.renderer = makeCancellablePromise(page.render(renderContext).promise);\n return _this.renderer.promise.then(_this.onRenderSuccess)["catch"](_this.onRenderError);\n });\n\n return _this;\n }\n\n _createClass(PageCanvasInternal, [{\n key: "componentDidMount",\n value: function componentDidMount() {\n this.drawPageOnCanvas();\n }\n }, {\n key: "componentDidUpdate",\n value: function componentDidUpdate(prevProps) {\n var _this$props3 = this.props,\n canvasBackground = _this$props3.canvasBackground,\n page = _this$props3.page,\n renderForms = _this$props3.renderForms;\n\n if (canvasBackground !== prevProps.canvasBackground || renderForms !== prevProps.renderForms) {\n // Ensures the canvas will be re-rendered from scratch. Otherwise all form data will stay.\n page.cleanup();\n this.drawPageOnCanvas();\n }\n }\n }, {\n key: "componentWillUnmount",\n value: function componentWillUnmount() {\n this.cancelRenderingTask();\n var canvas = this.canvasElement.current;\n /**\n * Zeroing the width and height cause most browsers to release graphics\n * resources immediately, which can greatly reduce memory consumption.\n */\n\n if (canvas) {\n canvas.width = 0;\n canvas.height = 0;\n }\n }\n }, {\n key: "cancelRenderingTask",\n value: function cancelRenderingTask() {\n if (this.renderer) {\n this.renderer.cancel();\n this.renderer = null;\n }\n }\n /**\n * Called when a page is rendered successfully.\n */\n\n }, {\n key: "renderViewport",\n get: function get() {\n var _this$props4 = this.props,\n page = _this$props4.page,\n rotate = _this$props4.rotate,\n scale = _this$props4.scale;\n var pixelRatio = getPixelRatio();\n return page.getViewport({\n scale: scale * pixelRatio,\n rotation: rotate\n });\n }\n }, {\n key: "viewport",\n get: function get() {\n var _this$props5 = this.props,\n page = _this$props5.page,\n rotate = _this$props5.rotate,\n scale = _this$props5.scale;\n return page.getViewport({\n scale: scale,\n rotation: rotate\n });\n }\n }, {\n key: "render",\n value: function render() {\n var canvasRef = this.props.canvasRef;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("canvas", {\n className: "react-pdf__Page__canvas",\n dir: "ltr",\n ref: mergeRefs(canvasRef, this.canvasElement),\n style: {\n display: \'block\',\n userSelect: \'none\'\n }\n });\n }\n }]);\n\n return PageCanvasInternal;\n}(external_commonjs_react_commonjs2_react_amd_react_root_React_.PureComponent);\nPageCanvasInternal.propTypes = {\n canvasBackground: (prop_types_default()).string,\n canvasRef: isRef,\n onRenderError: (prop_types_default()).func,\n onRenderSuccess: (prop_types_default()).func,\n page: isPage.isRequired,\n renderForms: (prop_types_default()).bool,\n rotate: isRotate,\n scale: (prop_types_default()).number.isRequired\n};\nfunction PageCanvas(props) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageContext.Consumer, null, function (context) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageCanvasInternal, extends_extends({}, context, props));\n });\n}\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/Page/PageSVG.js\n\n\n\n\n\n\n\n\n\nfunction PageSVG_createSuper(Derived) { var hasNativeReflectConstruct = PageSVG_isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction PageSVG_isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\n\n\n\n\n\n\n\nvar PageSVGInternal = /*#__PURE__*/function (_PureComponent) {\n _inherits(PageSVGInternal, _PureComponent);\n\n var _super = PageSVG_createSuper(PageSVGInternal);\n\n function PageSVGInternal() {\n var _this;\n\n _classCallCheck(this, PageSVGInternal);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _super.call.apply(_super, [this].concat(args));\n\n _defineProperty(_assertThisInitialized(_this), "state", {\n svg: null\n });\n\n _defineProperty(_assertThisInitialized(_this), "onRenderSuccess", function () {\n _this.renderer = null;\n var _this$props = _this.props,\n onRenderSuccess = _this$props.onRenderSuccess,\n page = _this$props.page,\n scale = _this$props.scale;\n if (onRenderSuccess) onRenderSuccess(makePageCallback(page, scale));\n });\n\n _defineProperty(_assertThisInitialized(_this), "onRenderError", function (error) {\n if (isCancelException(error)) {\n return;\n }\n\n tiny_warning_esm(error);\n var onRenderError = _this.props.onRenderError;\n if (onRenderError) onRenderError(error);\n });\n\n _defineProperty(_assertThisInitialized(_this), "renderSVG", function () {\n var page = _this.props.page;\n _this.renderer = page.getOperatorList();\n return _this.renderer.then(function (operatorList) {\n var svgGfx = new pdf.SVGGraphics(page.commonObjs, page.objs);\n _this.renderer = svgGfx.getSVG(operatorList, _this.viewport).then(function (svg) {\n _this.setState({\n svg: svg\n }, _this.onRenderSuccess);\n })["catch"](_this.onRenderError);\n })["catch"](_this.onRenderError);\n });\n\n _defineProperty(_assertThisInitialized(_this), "drawPageOnContainer", function (element) {\n var svg = _this.state.svg;\n\n if (!element || !svg) {\n return;\n } // Append SVG element to the main container, if this hasn\'t been done already\n\n\n if (!element.firstElementChild) {\n element.appendChild(svg);\n }\n\n var _this$viewport = _this.viewport,\n width = _this$viewport.width,\n height = _this$viewport.height;\n svg.setAttribute(\'width\', width);\n svg.setAttribute(\'height\', height);\n });\n\n return _this;\n }\n\n _createClass(PageSVGInternal, [{\n key: "componentDidMount",\n value: function componentDidMount() {\n this.renderSVG();\n }\n /**\n * Called when a page is rendered successfully.\n */\n\n }, {\n key: "viewport",\n get: function get() {\n var _this$props2 = this.props,\n page = _this$props2.page,\n rotate = _this$props2.rotate,\n scale = _this$props2.scale;\n return page.getViewport({\n scale: scale,\n rotation: rotate\n });\n }\n }, {\n key: "render",\n value: function render() {\n var _this2 = this;\n\n var _this$viewport2 = this.viewport,\n width = _this$viewport2.width,\n height = _this$viewport2.height;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("div", {\n className: "react-pdf__Page__svg" // Note: This cannot be shortened, as we need this function to be called with each render.\n ,\n ref: function ref(_ref) {\n return _this2.drawPageOnContainer(_ref);\n },\n style: {\n display: \'block\',\n backgroundColor: \'white\',\n overflow: \'hidden\',\n width: width,\n height: height,\n userSelect: \'none\'\n }\n });\n }\n }]);\n\n return PageSVGInternal;\n}(external_commonjs_react_commonjs2_react_amd_react_root_React_.PureComponent);\nPageSVGInternal.propTypes = {\n onRenderError: (prop_types_default()).func,\n onRenderSuccess: (prop_types_default()).func,\n page: isPage.isRequired,\n rotate: isRotate,\n scale: (prop_types_default()).number.isRequired\n};\nfunction PageSVG(props) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageContext.Consumer, null, function (context) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageSVGInternal, extends_extends({}, context, props));\n });\n}\n// EXTERNAL MODULE: ../demo/node_modules/react-dom/server.browser.js\nvar server_browser = __webpack_require__(190);\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/Page/TextLayer.js\n\n\n\n\n\n\n\n\n\nfunction TextLayer_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\n\nfunction TextLayer_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? TextLayer_ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : TextLayer_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\n\nfunction TextLayer_createSuper(Derived) { var hasNativeReflectConstruct = TextLayer_isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction TextLayer_isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\n\n\n\n\n\n\n\n\n\n\nvar TextLayerInternal = /*#__PURE__*/function (_PureComponent) {\n _inherits(TextLayerInternal, _PureComponent);\n\n var _super = TextLayer_createSuper(TextLayerInternal);\n\n function TextLayerInternal() {\n var _this;\n\n _classCallCheck(this, TextLayerInternal);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _super.call.apply(_super, [this].concat(args));\n\n _defineProperty(_assertThisInitialized(_this), "state", {\n textContent: null\n });\n\n _defineProperty(_assertThisInitialized(_this), "layerElement", /*#__PURE__*/(0,external_commonjs_react_commonjs2_react_amd_react_root_React_.createRef)());\n\n _defineProperty(_assertThisInitialized(_this), "loadTextContent", function () {\n var page = _this.props.page;\n var cancellable = makeCancellablePromise(page.getTextContent());\n _this.runningTask = cancellable;\n cancellable.promise.then(function (textContent) {\n _this.setState({\n textContent: textContent\n }, _this.onLoadSuccess);\n })["catch"](function (error) {\n _this.onLoadError(error);\n });\n });\n\n _defineProperty(_assertThisInitialized(_this), "onLoadSuccess", function () {\n var onGetTextSuccess = _this.props.onGetTextSuccess;\n var textContent = _this.state.textContent;\n if (onGetTextSuccess) onGetTextSuccess(textContent);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onLoadError", function (error) {\n _this.setState({\n textItems: false\n });\n\n tiny_warning_esm(error);\n var onGetTextError = _this.props.onGetTextError;\n if (onGetTextError) onGetTextError(error);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onRenderSuccess", function () {\n var onRenderTextLayerSuccess = _this.props.onRenderTextLayerSuccess;\n if (onRenderTextLayerSuccess) onRenderTextLayerSuccess();\n });\n\n _defineProperty(_assertThisInitialized(_this), "onRenderError", function (error) {\n tiny_warning_esm(error);\n var onRenderTextLayerError = _this.props.onRenderTextLayerError;\n if (onRenderTextLayerError) onRenderTextLayerError(error);\n });\n\n return _this;\n }\n\n _createClass(TextLayerInternal, [{\n key: "componentDidMount",\n value: function componentDidMount() {\n var page = this.props.page;\n invariant(page, \'Attempted to load page text content, but no page was specified.\');\n this.loadTextContent();\n }\n }, {\n key: "componentDidUpdate",\n value: function componentDidUpdate(prevProps) {\n var page = this.props.page;\n\n if (prevProps.page && page !== prevProps.page) {\n this.loadTextContent();\n }\n }\n }, {\n key: "componentWillUnmount",\n value: function componentWillUnmount() {\n cancelRunningTask(this.runningTask);\n }\n }, {\n key: "viewport",\n get: function get() {\n var _this$props = this.props,\n page = _this$props.page,\n rotate = _this$props.rotate,\n scale = _this$props.scale;\n return page.getViewport({\n scale: scale,\n rotation: rotate\n });\n }\n }, {\n key: "unrotatedViewport",\n get: function get() {\n var _this$props2 = this.props,\n page = _this$props2.page,\n scale = _this$props2.scale;\n return page.getViewport({\n scale: scale\n });\n }\n /**\n * It might happen that the page is rotated by default. In such cases, we shouldn\'t rotate\n * text content.\n */\n\n }, {\n key: "rotate",\n get: function get() {\n var _this$props3 = this.props,\n page = _this$props3.page,\n rotate = _this$props3.rotate;\n return rotate - page.rotate;\n }\n }, {\n key: "renderTextLayer",\n value: function renderTextLayer() {\n var _this2 = this;\n\n var textContent = this.state.textContent;\n\n if (!textContent) {\n return null;\n }\n\n var viewport = this.viewport;\n var _this$props4 = this.props,\n customTextRenderer = _this$props4.customTextRenderer,\n enhanceTextSelection = _this$props4.enhanceTextSelection; // If another rendering is in progress, let\'s cancel it\n\n cancelRunningTask(this.runningTask);\n var parameters = {\n container: this.layerElement.current,\n enhanceTextSelection: enhanceTextSelection,\n textContent: textContent,\n viewport: viewport\n };\n this.layerElement.current.innerHTML = \'\';\n this.runningTask = pdf.renderTextLayer(parameters);\n var cancellable = makeCancellablePromise(this.runningTask.promise);\n this.runningTask = cancellable;\n cancellable.promise.then(function () {\n if (customTextRenderer) {\n Array.from(_this2.layerElement.current.children).forEach(function (element, elementIndex) {\n var reactContent = customTextRenderer(TextLayer_objectSpread({\n itemIndex: elementIndex\n }, textContent.items[elementIndex]));\n element.innerHTML = (0,server_browser.renderToStaticMarkup)(reactContent);\n });\n }\n\n _this2.onRenderSuccess();\n })["catch"](function (error) {\n _this2.onRenderError(error);\n });\n }\n }, {\n key: "render",\n value: function render() {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("div", {\n className: "react-pdf__Page__textContent textLayer",\n ref: this.layerElement\n }, this.renderTextLayer());\n }\n }]);\n\n return TextLayerInternal;\n}(external_commonjs_react_commonjs2_react_amd_react_root_React_.PureComponent);\nTextLayerInternal.defaultProps = {\n enhanceTextSelection: true\n};\nTextLayerInternal.propTypes = {\n customTextRenderer: (prop_types_default()).func,\n enhanceTextSelection: (prop_types_default()).bool,\n onGetTextError: (prop_types_default()).func,\n onGetTextSuccess: (prop_types_default()).func,\n onRenderTextLayerError: (prop_types_default()).func,\n onRenderTextLayerSuccess: (prop_types_default()).func,\n page: isPage.isRequired,\n rotate: isRotate,\n scale: (prop_types_default()).number\n};\nfunction TextLayer(props) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageContext.Consumer, null, function (context) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(TextLayerInternal, extends_extends({}, context, props));\n });\n}\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/Page/AnnotationLayer.js\n\n\n\n\n\n\n\n\n\nfunction AnnotationLayer_createSuper(Derived) { var hasNativeReflectConstruct = AnnotationLayer_isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction AnnotationLayer_isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\n\n\n\n\n\n\n\n\n\n\nvar AnnotationLayerInternal = /*#__PURE__*/function (_PureComponent) {\n _inherits(AnnotationLayerInternal, _PureComponent);\n\n var _super = AnnotationLayer_createSuper(AnnotationLayerInternal);\n\n function AnnotationLayerInternal() {\n var _this;\n\n _classCallCheck(this, AnnotationLayerInternal);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _super.call.apply(_super, [this].concat(args));\n\n _defineProperty(_assertThisInitialized(_this), "state", {\n annotations: null\n });\n\n _defineProperty(_assertThisInitialized(_this), "layerElement", /*#__PURE__*/(0,external_commonjs_react_commonjs2_react_amd_react_root_React_.createRef)());\n\n _defineProperty(_assertThisInitialized(_this), "loadAnnotations", function () {\n var page = _this.props.page;\n var cancellable = makeCancellablePromise(page.getAnnotations());\n _this.runningTask = cancellable;\n cancellable.promise.then(function (annotations) {\n _this.setState({\n annotations: annotations\n }, _this.onLoadSuccess);\n })["catch"](function (error) {\n _this.onLoadError(error);\n });\n });\n\n _defineProperty(_assertThisInitialized(_this), "onLoadSuccess", function () {\n var onGetAnnotationsSuccess = _this.props.onGetAnnotationsSuccess;\n var annotations = _this.state.annotations;\n if (onGetAnnotationsSuccess) onGetAnnotationsSuccess(annotations);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onLoadError", function (error) {\n _this.setState({\n annotations: false\n });\n\n tiny_warning_esm(error);\n var onGetAnnotationsError = _this.props.onGetAnnotationsError;\n if (onGetAnnotationsError) onGetAnnotationsError(error);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onRenderSuccess", function () {\n var onRenderAnnotationLayerSuccess = _this.props.onRenderAnnotationLayerSuccess;\n if (onRenderAnnotationLayerSuccess) onRenderAnnotationLayerSuccess();\n });\n\n _defineProperty(_assertThisInitialized(_this), "onRenderError", function (error) {\n tiny_warning_esm(error);\n var onRenderAnnotationLayerError = _this.props.onRenderAnnotationLayerError;\n if (onRenderAnnotationLayerError) onRenderAnnotationLayerError(error);\n });\n\n return _this;\n }\n\n _createClass(AnnotationLayerInternal, [{\n key: "componentDidMount",\n value: function componentDidMount() {\n var page = this.props.page;\n invariant(page, \'Attempted to load page annotations, but no page was specified.\');\n this.loadAnnotations();\n }\n }, {\n key: "componentDidUpdate",\n value: function componentDidUpdate(prevProps) {\n var _this$props = this.props,\n page = _this$props.page,\n renderForms = _this$props.renderForms;\n\n if (prevProps.page && page !== prevProps.page || renderForms !== prevProps.renderForms) {\n this.loadAnnotations();\n }\n }\n }, {\n key: "componentWillUnmount",\n value: function componentWillUnmount() {\n cancelRunningTask(this.runningTask);\n }\n }, {\n key: "viewport",\n get: function get() {\n var _this$props2 = this.props,\n page = _this$props2.page,\n rotate = _this$props2.rotate,\n scale = _this$props2.scale;\n return page.getViewport({\n scale: scale,\n rotation: rotate\n });\n }\n }, {\n key: "renderAnnotationLayer",\n value: function renderAnnotationLayer() {\n var annotations = this.state.annotations;\n\n if (!annotations) {\n return;\n }\n\n var _this$props3 = this.props,\n imageResourcesPath = _this$props3.imageResourcesPath,\n linkService = _this$props3.linkService,\n page = _this$props3.page,\n renderForms = _this$props3.renderForms;\n var viewport = this.viewport.clone({\n dontFlip: true\n });\n var parameters = {\n annotations: annotations,\n div: this.layerElement.current,\n imageResourcesPath: imageResourcesPath,\n linkService: linkService,\n page: page,\n renderForms: renderForms,\n viewport: viewport\n };\n this.layerElement.current.innerHTML = \'\';\n\n try {\n pdf.AnnotationLayer.render(parameters);\n this.onRenderSuccess();\n } catch (error) {\n this.onRenderError(error);\n }\n }\n }, {\n key: "render",\n value: function render() {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("div", {\n className: "react-pdf__Page__annotations annotationLayer",\n ref: this.layerElement\n }, this.renderAnnotationLayer());\n }\n }]);\n\n return AnnotationLayerInternal;\n}(external_commonjs_react_commonjs2_react_amd_react_root_React_.PureComponent);\nAnnotationLayerInternal.propTypes = {\n imageResourcesPath: (prop_types_default()).string,\n linkService: isLinkService.isRequired,\n onGetAnnotationsError: (prop_types_default()).func,\n onGetAnnotationsSuccess: (prop_types_default()).func,\n onRenderAnnotationLayerError: (prop_types_default()).func,\n onRenderAnnotationLayerSuccess: (prop_types_default()).func,\n page: isPage,\n renderForms: (prop_types_default()).bool,\n rotate: isRotate,\n scale: (prop_types_default()).number\n};\n\nvar AnnotationLayer = function AnnotationLayer(props) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(esm_DocumentContext.Consumer, null, function (documentContext) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageContext.Consumer, null, function (pageContext) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(AnnotationLayerInternal, extends_extends({}, documentContext, pageContext, props));\n });\n });\n};\n\n/* harmony default export */ const Page_AnnotationLayer = (AnnotationLayer);\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/Page.js\n\n\n\n\n\n\n\n\n\nfunction Page_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\n\nfunction Page_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? Page_ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : Page_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\n\nfunction Page_createSuper(Derived) { var hasNativeReflectConstruct = Page_isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction Page_isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar defaultScale = 1;\nvar PageInternal = /*#__PURE__*/function (_PureComponent) {\n _inherits(PageInternal, _PureComponent);\n\n var _super = Page_createSuper(PageInternal);\n\n function PageInternal() {\n var _this;\n\n _classCallCheck(this, PageInternal);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _super.call.apply(_super, [this].concat(args));\n\n _defineProperty(_assertThisInitialized(_this), "state", {\n page: null\n });\n\n _defineProperty(_assertThisInitialized(_this), "pageElement", /*#__PURE__*/(0,external_commonjs_react_commonjs2_react_amd_react_root_React_.createRef)());\n\n _defineProperty(_assertThisInitialized(_this), "onLoadSuccess", function () {\n var _this$props = _this.props,\n onLoadSuccess = _this$props.onLoadSuccess,\n registerPage = _this$props.registerPage;\n var page = _this.state.page;\n if (onLoadSuccess) onLoadSuccess(makePageCallback(page, _this.scale));\n if (registerPage) registerPage(_this.pageIndex, _this.pageElement.current);\n });\n\n _defineProperty(_assertThisInitialized(_this), "onLoadError", function (error) {\n _this.setState({\n page: false\n });\n\n tiny_warning_esm(error);\n var onLoadError = _this.props.onLoadError;\n if (onLoadError) onLoadError(error);\n });\n\n _defineProperty(_assertThisInitialized(_this), "loadPage", function () {\n var pdf = _this.props.pdf;\n\n var pageNumber = _this.getPageNumber();\n\n if (!pageNumber) {\n return;\n }\n\n _this.setState(function (prevState) {\n if (!prevState.page) {\n return null;\n }\n\n return {\n page: null\n };\n });\n\n var cancellable = makeCancellablePromise(pdf.getPage(pageNumber));\n _this.runningTask = cancellable;\n cancellable.promise.then(function (page) {\n _this.setState({\n page: page\n }, _this.onLoadSuccess);\n })["catch"](function (error) {\n _this.onLoadError(error);\n });\n });\n\n return _this;\n }\n\n _createClass(PageInternal, [{\n key: "componentDidMount",\n value: function componentDidMount() {\n var pdf = this.props.pdf;\n invariant(pdf, \'Attempted to load a page, but no document was specified.\');\n this.loadPage();\n }\n }, {\n key: "componentDidUpdate",\n value: function componentDidUpdate(prevProps) {\n var pdf = this.props.pdf;\n\n if (prevProps.pdf && pdf !== prevProps.pdf || this.getPageNumber() !== this.getPageNumber(prevProps)) {\n var unregisterPage = this.props.unregisterPage;\n if (unregisterPage) unregisterPage(this.getPageIndex(prevProps));\n this.loadPage();\n }\n }\n }, {\n key: "componentWillUnmount",\n value: function componentWillUnmount() {\n var unregisterPage = this.props.unregisterPage;\n if (unregisterPage) unregisterPage(this.pageIndex);\n cancelRunningTask(this.runningTask);\n }\n }, {\n key: "childContext",\n get: function get() {\n var page = this.state.page;\n\n if (!page) {\n return {};\n }\n\n var _this$props2 = this.props,\n canvasBackground = _this$props2.canvasBackground,\n customTextRenderer = _this$props2.customTextRenderer,\n enhanceTextSelection = _this$props2.enhanceTextSelection,\n onGetAnnotationsError = _this$props2.onGetAnnotationsError,\n onGetAnnotationsSuccess = _this$props2.onGetAnnotationsSuccess,\n onGetTextError = _this$props2.onGetTextError,\n onGetTextSuccess = _this$props2.onGetTextSuccess,\n onRenderAnnotationLayerError = _this$props2.onRenderAnnotationLayerError,\n onRenderAnnotationLayerSuccess = _this$props2.onRenderAnnotationLayerSuccess,\n onRenderError = _this$props2.onRenderError,\n onRenderSuccess = _this$props2.onRenderSuccess,\n onRenderTextLayerError = _this$props2.onRenderTextLayerError,\n onRenderTextLayerSuccess = _this$props2.onRenderTextLayerSuccess,\n renderForms = _this$props2.renderForms,\n renderInteractiveForms = _this$props2.renderInteractiveForms;\n return {\n canvasBackground: canvasBackground,\n customTextRenderer: customTextRenderer,\n enhanceTextSelection: enhanceTextSelection,\n onGetAnnotationsError: onGetAnnotationsError,\n onGetAnnotationsSuccess: onGetAnnotationsSuccess,\n onGetTextError: onGetTextError,\n onGetTextSuccess: onGetTextSuccess,\n onRenderAnnotationLayerError: onRenderAnnotationLayerError,\n onRenderAnnotationLayerSuccess: onRenderAnnotationLayerSuccess,\n onRenderError: onRenderError,\n onRenderSuccess: onRenderSuccess,\n onRenderTextLayerError: onRenderTextLayerError,\n onRenderTextLayerSuccess: onRenderTextLayerSuccess,\n page: page,\n renderForms: renderForms !== null && renderForms !== void 0 ? renderForms : renderInteractiveForms,\n // For backward compatibility\n rotate: this.rotate,\n scale: this.scale\n };\n }\n /**\n * Called when a page is loaded successfully\n */\n\n }, {\n key: "getPageIndex",\n value: function getPageIndex() {\n var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props;\n\n if (isProvided(props.pageNumber)) {\n return props.pageNumber - 1;\n }\n\n if (isProvided(props.pageIndex)) {\n return props.pageIndex;\n }\n\n return null;\n }\n }, {\n key: "getPageNumber",\n value: function getPageNumber() {\n var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props;\n\n if (isProvided(props.pageNumber)) {\n return props.pageNumber;\n }\n\n if (isProvided(props.pageIndex)) {\n return props.pageIndex + 1;\n }\n\n return null;\n }\n }, {\n key: "pageIndex",\n get: function get() {\n return this.getPageIndex();\n }\n }, {\n key: "pageNumber",\n get: function get() {\n return this.getPageNumber();\n }\n }, {\n key: "rotate",\n get: function get() {\n var rotate = this.props.rotate;\n\n if (isProvided(rotate)) {\n return rotate;\n }\n\n var page = this.state.page;\n\n if (!page) {\n return null;\n }\n\n return page.rotate;\n }\n }, {\n key: "scale",\n get: function get() {\n var page = this.state.page;\n\n if (!page) {\n return null;\n }\n\n var _this$props3 = this.props,\n scale = _this$props3.scale,\n width = _this$props3.width,\n height = _this$props3.height;\n var rotate = this.rotate; // Be default, we\'ll render page at 100% * scale width.\n\n var pageScale = 1; // Passing scale explicitly null would cause the page not to render\n\n var scaleWithDefault = scale === null ? defaultScale : scale; // If width/height is defined, calculate the scale of the page so it could be of desired width.\n\n if (width || height) {\n var viewport = page.getViewport({\n scale: 1,\n rotation: rotate\n });\n pageScale = width ? width / viewport.width : height / viewport.height;\n }\n\n return scaleWithDefault * pageScale;\n }\n }, {\n key: "eventProps",\n get: function get() {\n var _this2 = this;\n\n return esm(this.props, function () {\n var page = _this2.state.page;\n\n if (!page) {\n return page;\n }\n\n return makePageCallback(page, _this2.scale);\n });\n }\n }, {\n key: "pageKey",\n get: function get() {\n var page = this.state.page;\n return "".concat(page.pageIndex, "@").concat(this.scale, "/").concat(this.rotate);\n }\n }, {\n key: "pageKeyNoScale",\n get: function get() {\n var page = this.state.page;\n return "".concat(page.pageIndex, "/").concat(this.rotate);\n }\n }, {\n key: "renderMainLayer",\n value: function renderMainLayer() {\n var _this$props4 = this.props,\n canvasRef = _this$props4.canvasRef,\n renderMode = _this$props4.renderMode;\n\n switch (renderMode) {\n case \'none\':\n return null;\n\n case \'svg\':\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageSVG, {\n key: "".concat(this.pageKeyNoScale, "_svg")\n });\n\n case \'canvas\':\n default:\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageCanvas, {\n key: "".concat(this.pageKey, "_canvas"),\n canvasRef: canvasRef\n });\n }\n }\n }, {\n key: "renderTextLayer",\n value: function renderTextLayer() {\n var renderTextLayer = this.props.renderTextLayer;\n\n if (!renderTextLayer) {\n return null;\n }\n\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(TextLayer, {\n key: "".concat(this.pageKey, "_text")\n });\n }\n }, {\n key: "renderAnnotationLayer",\n value: function renderAnnotationLayer() {\n var renderAnnotationLayer = this.props.renderAnnotationLayer;\n\n if (!renderAnnotationLayer) {\n return null;\n }\n /**\n * As of now, PDF.js 2.0.943 returns warnings on unimplemented annotations in SVG mode.\n * Therefore, as a fallback, we render "traditional" AnnotationLayer component.\n */\n\n\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(Page_AnnotationLayer, {\n key: "".concat(this.pageKey, "_annotations")\n });\n }\n }, {\n key: "renderChildren",\n value: function renderChildren() {\n var children = this.props.children;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageContext.Provider, {\n value: this.childContext\n }, this.renderMainLayer(), this.renderTextLayer(), this.renderAnnotationLayer(), children);\n }\n }, {\n key: "renderContent",\n value: function renderContent() {\n var pageNumber = this.pageNumber;\n var pdf = this.props.pdf;\n var page = this.state.page;\n\n if (!pageNumber) {\n var noData = this.props.noData;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(Message, {\n type: "no-data"\n }, typeof noData === \'function\' ? noData() : noData);\n }\n\n if (pdf === null || page === null) {\n var loading = this.props.loading;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(Message, {\n type: "loading"\n }, typeof loading === \'function\' ? loading() : loading);\n }\n\n if (pdf === false || page === false) {\n var error = this.props.error;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(Message, {\n type: "error"\n }, typeof error === \'function\' ? error() : error);\n }\n\n return this.renderChildren();\n }\n }, {\n key: "render",\n value: function render() {\n var pageNumber = this.pageNumber;\n var _this$props5 = this.props,\n className = _this$props5.className,\n inputRef = _this$props5.inputRef;\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement("div", extends_extends({\n className: mergeClassNames(\'react-pdf__Page\', className),\n "data-page-number": pageNumber,\n ref: mergeRefs(inputRef, this.pageElement),\n style: {\n position: \'relative\'\n }\n }, this.eventProps), this.renderContent());\n }\n }]);\n\n return PageInternal;\n}(external_commonjs_react_commonjs2_react_amd_react_root_React_.PureComponent);\nPageInternal.defaultProps = {\n error: \'Failed to load the page.\',\n loading: \'Loading page…\',\n noData: \'No page specified.\',\n renderAnnotationLayer: true,\n renderForms: false,\n renderMode: \'canvas\',\n renderTextLayer: true,\n scale: defaultScale\n};\nvar Page_isFunctionOrNode = prop_types_default().oneOfType([(prop_types_default()).func, (prop_types_default()).node]);\nPageInternal.propTypes = Page_objectSpread(Page_objectSpread({}, eventProps), {}, {\n canvasBackground: (prop_types_default()).string,\n children: (prop_types_default()).node,\n className: isClassName,\n customTextRenderer: (prop_types_default()).func,\n enhanceTextSelection: (prop_types_default()).bool,\n error: Page_isFunctionOrNode,\n height: (prop_types_default()).number,\n imageResourcesPath: (prop_types_default()).string,\n inputRef: isRef,\n loading: Page_isFunctionOrNode,\n noData: Page_isFunctionOrNode,\n onGetTextError: (prop_types_default()).func,\n onGetTextSuccess: (prop_types_default()).func,\n onLoadError: (prop_types_default()).func,\n onLoadSuccess: (prop_types_default()).func,\n onRenderError: (prop_types_default()).func,\n onRenderSuccess: (prop_types_default()).func,\n onRenderTextLayerError: (prop_types_default()).func,\n onRenderTextLayerSuccess: (prop_types_default()).func,\n pageIndex: isPageIndex,\n pageNumber: isPageNumber,\n pdf: isPdf,\n registerPage: (prop_types_default()).func,\n renderAnnotationLayer: (prop_types_default()).bool,\n renderForms: (prop_types_default()).bool,\n renderInteractiveForms: (prop_types_default()).bool,\n // For backward compatibility\n renderMode: isRenderMode,\n renderTextLayer: (prop_types_default()).bool,\n rotate: isRotate,\n scale: (prop_types_default()).number,\n unregisterPage: (prop_types_default()).func,\n width: (prop_types_default()).number\n});\n\nfunction Page(props, ref) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(esm_DocumentContext.Consumer, null, function (context) {\n return /*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().createElement(PageInternal, extends_extends({\n ref: ref\n }, context, props));\n });\n}\n\n/* harmony default export */ const esm_Page = (/*#__PURE__*/external_commonjs_react_commonjs2_react_amd_react_root_React_default().forwardRef(Page));\n;// CONCATENATED MODULE: ./node_modules/react-pdf/dist/esm/entry.js\n\n\n\n\n\ndisplayWorkerWarning();\npdf.GlobalWorkerOptions.workerSrc = \'pdf.worker.js\';\n\n;// CONCATENATED MODULE: ./src/utils/ScrollDirectionDetector.ts\nvar ScrollDirection;\n(function (ScrollDirection) {\n ScrollDirection["UP"] = "UP";\n ScrollDirection["DOWN"] = "DOWN";\n})(ScrollDirection || (ScrollDirection = {}));\nclass ScrollDetector {\n constructor(el, setScrollDirection, setIsAtTop, setScrollThresholdReachedInDirection, scrollThreshold) {\n this._onScroll = () => {\n const currScrollTop = this._el.scrollTop;\n if (this._isAtTop !== (currScrollTop === 0)) {\n this._isAtTop = currScrollTop === 0;\n this._setIsAtTop(currScrollTop === 0);\n }\n if (this._lastScrollTop === currScrollTop) {\n return;\n }\n // Determine direction\n const currScrollDirection = (() => {\n if (currScrollTop <= 0) {\n return ScrollDirection.DOWN;\n }\n return this._lastScrollTop < currScrollTop ? ScrollDirection.DOWN : ScrollDirection.UP;\n })();\n // Update state, if changed\n this._lastScrollTop = currScrollTop;\n if (this._lastScrollDirection !== currScrollDirection) {\n this._lastScrollDirection = currScrollDirection;\n this._setScrollDirection(currScrollDirection);\n this._lastScrollTopBeforeDirectionChange = currScrollTop;\n this._isScrollThresholdReachedInDirection = null;\n if (this._setScrollThresholdReachedInDirection && !this._isAtTop) {\n this._setScrollThresholdReachedInDirection(null);\n }\n }\n else {\n if (this._scrollThreshold && this._setScrollThresholdReachedInDirection) {\n const scrolledAmount = Math.abs(this._lastScrollTopBeforeDirectionChange - currScrollTop);\n if (scrolledAmount >= this._scrollThreshold) {\n this._isScrollThresholdReachedInDirection = this._lastScrollDirection;\n this._setScrollThresholdReachedInDirection(this._lastScrollDirection);\n }\n }\n }\n };\n this._el = el;\n this._lastScrollTop = this._el.scrollTop;\n this._lastScrollDirection = null;\n this._setScrollDirection = setScrollDirection;\n this._isAtTop = null;\n this._setIsAtTop = setIsAtTop;\n this._lastScrollTopBeforeDirectionChange = this._el.scrollTop;\n this._scrollThreshold = scrollThreshold;\n this._isScrollThresholdReachedInDirection = null;\n this._setScrollThresholdReachedInDirection = setScrollThresholdReachedInDirection;\n }\n attachScrollListener() {\n var _a, _b;\n if (((_b = (_a = this._el) === null || _a === void 0 ? void 0 : _a.tagName) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === \'html\') {\n window.addEventListener(\'scroll\', this._onScroll, false);\n return;\n }\n this._el.addEventListener(\'scroll\', this._onScroll, false);\n }\n detachScrollListener() {\n var _a, _b;\n if (((_b = (_a = this._el) === null || _a === void 0 ? void 0 : _a.tagName) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === \'html\') {\n window.removeEventListener(\'scroll\', this._onScroll, false);\n return;\n }\n this._el.removeEventListener(\'scroll\', this._onScroll, false);\n }\n}\n\n;// CONCATENATED MODULE: ./src/utils/VisibleEntriesDetector.ts\nconst DEFAULT_ROOT_MARGIN = \'50px\';\n// This array is a range from 0.0001 to 1 range of threshold. It will help with detecting\n// on scroll with a better % compare to a fix threshold but not firing too frequent that\n// can hamper our performance.\nconst DEFAULT_THRESHOLD = [0.0001, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.99];\nclass VisibleEntriesDetector {\n constructor({ root, thresHold, setVisibleEntries, onVisibleEntriesChange, }) {\n var _a;\n this._root = root;\n this._lastVisibleEntries = new Map();\n this._setVisibleEntries = setVisibleEntries;\n this._onVisibleEntriesChange = onVisibleEntriesChange;\n this._observer = new IntersectionObserver(entries => {\n // Collect visible and hidden elements\n const visibleEntries = entries.filter(entry => entry.isIntersecting);\n const hiddenEntries = entries.filter(entry => !entry.isIntersecting);\n // Determine what needs saved\n const newVisibleEntries = this._onVisibleEntriesChange({\n visibleEntries,\n hiddenEntries,\n lastEntries: this._lastVisibleEntries,\n });\n const frozenEntries = new Map(newVisibleEntries);\n Object.freeze(frozenEntries);\n this._lastVisibleEntries = frozenEntries;\n this._setVisibleEntries(frozenEntries);\n }, \n // Default setting for intersection observer\n {\n root: ((_a = this._root.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === \'html\' ? null : this._root,\n rootMargin: DEFAULT_ROOT_MARGIN,\n threshold: thresHold ? thresHold : DEFAULT_THRESHOLD,\n });\n }\n observeNodes(selector) {\n for (const node of this._root.querySelectorAll(selector)) {\n this._observer.observe(node);\n }\n }\n destroy() {\n this._observer.disconnect();\n }\n}\n\n;// CONCATENATED MODULE: ./src/context/ScrollContext.ts\n\n\n\n\n\nconst OUTLINE_ATTRIBUTE = \'data-outline-target-dest\';\nconst OUTLINE_SELECTOR = \'.reader__page__outline-target\';\nconst PAGE_NUMBER_ATTRIBUTE = \'data-page-number\';\nconst PAGE_NUMBER_SELECTOR = `.reader__page[${PAGE_NUMBER_ATTRIBUTE}]`;\nconst DEFAULT_CONTEXT = {\n scrollDirection: null,\n visibleOutlineTargets: new Map(),\n visiblePageRatios: new Map(),\n isOutlineTargetVisible: opts => {\n logProviderWarning(`isOutlineTargetVisible(${JSON.stringify(opts)})`, \'ScrollContext\');\n return false;\n },\n isPageVisible: opts => {\n logProviderWarning(`isPageVisible(${JSON.stringify(opts)})`, \'ScrollContext\');\n return false;\n },\n resetScrollObservers: () => {\n logProviderWarning(`resetScrollObservers()`, \'ScrollContext\');\n },\n setScrollRoot: (_el) => {\n logProviderWarning(`setScrollRoot(...)`, \'ScrollContext\');\n },\n scrollToOutlineTarget: dest => {\n logProviderWarning(`scrollToOutlineTarget(${dest})`, \'ScrollContext\');\n },\n setScrollThreshold: (scrollThreshold) => {\n logProviderWarning(`setScrollThreshold(${scrollThreshold})`, \'ScrollContext\');\n },\n scrollToPage: opts => {\n logProviderWarning(`scrollToPage(${JSON.stringify(opts)})`, \'ScrollContext\');\n },\n updateScrollPosition: zoomMultiplier => {\n logProviderWarning(`updateScrollPosition(${JSON.stringify(zoomMultiplier)})`, \'ScrollContext\');\n },\n setIsOutlineClicked: opts => {\n logProviderWarning(`setIsOutlineGetClicked(${JSON.stringify(opts)})`, \'ScrollContext\');\n },\n scrollThresholdReachedInDirection: null,\n isAtTop: null,\n isOutlineClicked: null,\n};\nconst ScrollContext = external_commonjs_react_commonjs2_react_amd_react_root_React_.createContext(DEFAULT_CONTEXT);\nfunction useScrollContextProps() {\n // Node used for observing the scroll position\n const [scrollRoot, setScrollRoot] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(null);\n // Determine scroll direction\n const [scrollDirection, setScrollDirection] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(null);\n const [scrollThreshold, setScrollThreshold] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(null);\n const [scrollThresholdReachedInDirection, setScrollThresholdReachedInDirection] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(null);\n const [isAtTop, setIsAtTop] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(null);\n const [isOutlineClicked, setIsOutlineClicked] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(null);\n external_commonjs_react_commonjs2_react_amd_react_root_React_.useEffect(() => {\n const scrollElem = scrollRoot || document.documentElement;\n if (!scrollElem) {\n return;\n }\n let scrollDirectionDetector;\n if (!scrollThreshold) {\n // scroll threshold is optional\n scrollDirectionDetector = new ScrollDetector(scrollElem, setScrollDirection, setIsAtTop);\n }\n else {\n scrollDirectionDetector = new ScrollDetector(scrollElem, setScrollDirection, setIsAtTop, setScrollThresholdReachedInDirection, scrollThreshold);\n }\n scrollDirectionDetector.attachScrollListener();\n return () => {\n scrollDirectionDetector.detachScrollListener();\n };\n }, [scrollRoot, scrollThreshold]);\n // Causes the IntersectionObservers to disconnect and be recreated (useful when DOM changes)\n const [observerIndex, setObserverIndex] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(0);\n const resetScrollObservers = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(() => {\n setObserverIndex(observerIndex + 1);\n }, [observerIndex]);\n const [visibleOutlineTargets, setVisibleOutlineNodes] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(() => {\n const map = new Map();\n Object.freeze(map);\n return map;\n });\n const [visiblePageRatios, setVisiblePageRatios] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(() => {\n const map = new Map();\n Object.freeze(map);\n return map;\n });\n const isOutlineTargetVisible = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((dest) => {\n return visibleOutlineTargets.has(dest);\n }, [visibleOutlineTargets]);\n const scrollToOutlineTarget = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((dest) => {\n var _a;\n setIsOutlineClicked(true);\n (_a = document\n .querySelector(`[data-outline-target-dest="${dest}"]`)) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: \'smooth\' });\n }, []);\n const isPageVisible = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(({ pageNumber, pageIndex }) => {\n if (typeof pageIndex === \'number\') {\n pageNumber = pageIndex + 1;\n }\n if (typeof pageNumber !== \'number\') {\n return false;\n }\n return visiblePageRatios.has(pageNumber);\n }, [visiblePageRatios]);\n const scrollToPage = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(({ pageNumber, pageIndex }) => {\n var _a;\n if (typeof pageNumber === \'number\') {\n pageIndex = pageNumber - 1;\n }\n if (typeof pageIndex !== \'number\') {\n return;\n }\n (_a = document\n .getElementById(generatePageIdFromIndex(pageIndex))) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: \'smooth\' });\n }, []);\n // Watch outline nodes\n external_commonjs_react_commonjs2_react_amd_react_root_React_.useEffect(() => {\n const root = scrollRoot || document.documentElement;\n const detector = new VisibleEntriesDetector({\n root: root,\n setVisibleEntries: setVisibleOutlineNodes,\n onVisibleEntriesChange: ({ visibleEntries, hiddenEntries, lastEntries }) => {\n hiddenEntries.map(entry => lastEntries.delete(entry.target.getAttribute(OUTLINE_ATTRIBUTE)));\n const newEntries = new Map(lastEntries);\n visibleEntries.map(entry => newEntries.set(entry.target.getAttribute(OUTLINE_ATTRIBUTE), entry.intersectionRatio));\n return newEntries;\n },\n });\n detector.observeNodes(OUTLINE_SELECTOR);\n return () => {\n detector.destroy();\n };\n }, [scrollRoot, observerIndex]);\n // Watch pages\n external_commonjs_react_commonjs2_react_amd_react_root_React_.useEffect(() => {\n const root = scrollRoot || document.documentElement;\n const detector = new VisibleEntriesDetector({\n root: root,\n setVisibleEntries: setVisiblePageRatios,\n onVisibleEntriesChange: ({ visibleEntries, hiddenEntries, lastEntries }) => {\n hiddenEntries.map(entry => { var _a; return lastEntries.delete(parseInt(((_a = entry.target) === null || _a === void 0 ? void 0 : _a.getAttribute(PAGE_NUMBER_ATTRIBUTE)) || \'\', 10)); });\n const newEntries = new Map(lastEntries);\n visibleEntries.map(entry => {\n var _a;\n return newEntries.set(parseInt(((_a = entry.target) === null || _a === void 0 ? void 0 : _a.getAttribute(PAGE_NUMBER_ATTRIBUTE)) || \'\', 10), entry.intersectionRatio);\n });\n return newEntries;\n },\n });\n detector.observeNodes(PAGE_NUMBER_SELECTOR);\n return () => {\n detector.destroy();\n };\n }, [scrollRoot, observerIndex]);\n // calculates a new scroll position after zooming in/out so user doesnt lose their position\n const updateScrollPosition = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((zoomMultiplier) => {\n const root = scrollRoot || document.documentElement;\n if (!root) {\n return;\n }\n const newScrollTop = Math.floor(root.scrollTop * zoomMultiplier);\n setTimeout(() => {\n root.scrollTop = newScrollTop;\n }, 0);\n }, [scrollRoot]);\n return {\n isOutlineTargetVisible,\n isPageVisible,\n scrollDirection,\n visibleOutlineTargets,\n visiblePageRatios,\n resetScrollObservers,\n setScrollRoot,\n scrollToOutlineTarget,\n setScrollThreshold,\n scrollToPage,\n updateScrollPosition,\n setIsOutlineClicked,\n scrollThresholdReachedInDirection,\n isAtTop,\n isOutlineClicked,\n };\n}\n\n;// CONCATENATED MODULE: ./src/context/UiContext.ts\n\n\nconst UiContext = external_commonjs_react_commonjs2_react_amd_react_root_React_.createContext({\n errorMessage: null,\n isLoading: false,\n isShowingHighlightOverlay: false,\n isShowingOutline: false,\n isShowingTextHighlight: false,\n setErrorMessage: errorMessage => {\n logProviderWarning(`setErrorMessage(${errorMessage})`, \'UiContext\');\n },\n setIsShowingOutline: isShowingOutline => {\n logProviderWarning(`setIsShowingOutline(${isShowingOutline})`, \'UiContext\');\n },\n setIsLoading: isLoading => {\n logProviderWarning(`setIsLoading(${isLoading})`, \'UiContext\');\n },\n setIsShowingHighlightOverlay: isShowingHighlightOverlay => {\n logProviderWarning(`setIsShowingHighlightOverlay(${isShowingHighlightOverlay})`, \'UiContext\');\n },\n setIsShowingTextHighlight: isShowingTextHighlight => {\n logProviderWarning(`setIsShowingTextHighlight(${isShowingTextHighlight})`, \'UiContext\');\n },\n});\nfunction useUiContextProps() {\n const [errorMessage, setErrorMessage] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(null);\n const [isLoading, setIsLoading] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(true);\n const [isShowingHighlightOverlay, setIsShowingHighlightOverlay] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(false);\n const [isShowingOutline, setIsShowingOutline] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(false);\n const [isShowingTextHighlight, setIsShowingTextHighlight] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(false);\n return {\n errorMessage,\n isLoading,\n isShowingHighlightOverlay,\n isShowingOutline,\n isShowingTextHighlight,\n setErrorMessage,\n setIsLoading,\n setIsShowingHighlightOverlay,\n setIsShowingOutline,\n setIsShowingTextHighlight,\n };\n}\n\n;// CONCATENATED MODULE: ./src/utils/errorMessage.ts\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction getErrorMessage(error) {\n if (!error) {\n return \'Unknown error\';\n }\n if (typeof error === \'string\') {\n return error;\n }\n if (error instanceof Error) {\n return error.message;\n }\n if (typeof error.error === \'string\') {\n return error.error;\n }\n return error.toString();\n}\n\n;// CONCATENATED MODULE: ./src/utils/pdfWorker.ts\n\n// Set PDFjs worker source or else PDF will not load when this library is imported as a package.\nfunction initPdfWorker() {\n pdf.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdf.version}/pdf.worker.min.js`;\n}\n\n;// CONCATENATED MODULE: ./src/utils/scale.ts\n// We assume 96 DPI for display\n// TODO: There are more accurate ways to do this, but this is what ScholarPhi does now\nconst DPI = 96;\n// PDF units are in 1/72nds of an inch\nconst USER_UNIT_DENOMINATOR = 72;\n/**\n * Given a PDFPageProxy, calculates the screen pixel size of the PDF page at 100% scale\n * @param page The PDFPageProxy to calculate size for\n * @returns Pixel size of a page at 100% scale assuming 96DPI display\n */\nfunction computePageDimensions(page) {\n const [leftPx, topPx, rightPx, bottomPx] = page.view;\n const PPI = (page.userUnit / USER_UNIT_DENOMINATOR) * DPI;\n return {\n height: (bottomPx - topPx) * PPI,\n width: (rightPx - leftPx) * PPI,\n };\n}\n\n;// CONCATENATED MODULE: ./src/components/types/destination.ts\n/**\n * This class is the definition of the first item when Destination is returned as an array.\n * It is created based on the same class in \'react-pdf\' library:\n * https://github.com/wojtekmaj/react-pdf/blob/ca4453f123af51e2faed39a8a62800901030459a/src/Ref.js\n */\nclass destination_Ref {\n constructor({ num, gen }) {\n this.num = num;\n this.gen = gen;\n }\n toString() {\n return this.gen !== 0 ? `${this.num}R${this.gen}` : `${this.num}R`;\n }\n}\n\n;// CONCATENATED MODULE: ./src/components/DocumentWrapper.tsx\nvar DocumentWrapper_rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\n\n\n\n\n\n\n\nconst DocumentWrapper = (_a) => {\n var { children } = _a, extraProps = DocumentWrapper_rest(_a, ["children"]);\n initPdfWorker();\n const { pdfDocProxy, setNumPages, setPageDimensions, setPdfDocProxy } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(DocumentContext_DocumentContext);\n const { resetScrollObservers } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(ScrollContext);\n const { rotation } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(TransformContext);\n const { setErrorMessage, setIsLoading } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(UiContext);\n function getFirstPage(pdfDoc) {\n // getPage uses 1-indexed pageNumber, not 0-indexed pageIndex\n return pdfDoc.getPage(1);\n }\n external_commonjs_react_commonjs2_react_amd_react_root_React_.useEffect(() => {\n resetScrollObservers();\n }, []);\n const onPdfLoadSuccess = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((pdfDoc) => {\n setNumPages(pdfDoc.numPages);\n getFirstPage(pdfDoc)\n .then(page => {\n setPageDimensions(computePageDimensions(page));\n setErrorMessage(null);\n })\n .catch(error => {\n setErrorMessage(getErrorMessage(error));\n })\n .finally(() => {\n setIsLoading(false);\n });\n if (!pdfDocProxy) {\n setPdfDocProxy(pdfDoc);\n }\n }, []);\n const onPdfLoadError = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((error) => {\n setErrorMessage(getErrorMessage(error));\n setIsLoading(false);\n }, []);\n const onItemClicked = (param) => {\n if (!pdfDocProxy) {\n return;\n }\n // Scroll to the destination of the item\n pdfDocProxy.getDestination(param.dest).then(destArray => {\n if (!destArray) {\n return;\n }\n const [ref, , , bottomPoints] = destArray;\n pdfDocProxy.getPageIndex(new destination_Ref(ref)).then(refInfo => {\n scrollToPosition(parseInt(refInfo.toString()), 0, bottomPoints, rotation);\n });\n });\n };\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(Document, Object.assign({ options: { cMapUrl: \'cmaps/\', cMapPacked: true }, onLoadError: onPdfLoadError, onLoadSuccess: onPdfLoadSuccess, externalLinkTarget: "_blank", renderMode: "none", \n // @ts-ignore: the arguments should be { dest, pageIndex, pageNumber }\n // @types/react-pdf hasn\'t updated the function signature\n // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/d73eb652e0ba8f89395a0ef2ba69cf1e640ce5be/types/react-pdf/dist/Document.d.ts#L72\n onItemClick: onItemClicked }, extraProps), children));\n};\n\n;// CONCATENATED MODULE: ./src/components/DownloadButton.tsx\nvar DownloadButton_rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n/**\n * HTML anchor tag allows you to download a file from the same origin.\n * This is a workaround to download a file served from a different origin\n */\nconst DownloadButton = (_a) => {\n var { pdfUrl, children, className } = _a, extraProps = DownloadButton_rest(_a, ["pdfUrl", "children", "className"]);\n const [fetching, setFetching] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(false);\n const download = () => {\n setFetching(true);\n fetch(pdfUrl)\n .then(response => response.blob())\n .then(blob => {\n setFetching(false);\n const blobURL = URL.createObjectURL(blob);\n const a = document.createElement(\'a\');\n a.href = blobURL;\n a.download = pdfUrl.split(\'/\').pop() || pdfUrl;\n document.body.appendChild(a);\n a.click();\n });\n };\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("button", Object.assign({ disabled: fetching, onClick: () => download(), "aria-label": "Download PDF", className: `reader__download-btn ${className}` }, extraProps), children ? children : \'Download\'));\n};\n\n;// CONCATENATED MODULE: ./src/components/HighlightOverlay.tsx\nvar HighlightOverlay_rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\nconst HighlightOverlay = (_a) => {\n var { children, pageIndex } = _a, extraProps = HighlightOverlay_rest(_a, ["children", "pageIndex"]);\n const { pageDimensions } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(DocumentContext_DocumentContext);\n const { rotation, scale } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(TransformContext);\n const maskId = `highlight-overlay-mask-${pageIndex}`;\n const getPageStyle = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(() => {\n return computePageStyle(pageDimensions, rotation, scale);\n }, [pageDimensions, rotation, scale]);\n const getUnmaskedArea = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((boundingBoxes) => {\n const boxes = Array.isArray(boundingBoxes) ? boundingBoxes : [boundingBoxes];\n return boxes.map((box, i) => {\n const boxStyle = computeBoundingBoxStyle(box.props, pageDimensions, rotation, scale);\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("rect", { style: boxStyle, x: boxStyle.left, y: boxStyle.top, key: i, fill: "black" }));\n });\n }, [pageDimensions, rotation, scale]);\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("div", Object.assign({ className: "reader__page-highlight-overlay", style: getPageStyle() }, extraProps),\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("svg", { className: "page-mask", style: getPageStyle() },\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("mask", { id: maskId },\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("rect", { style: getPageStyle(), fill: "white" }),\n children && getUnmaskedArea(children)),\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("rect", { style: getPageStyle(), fill: "white", opacity: "0.6", mask: `url(#${maskId})` }))));\n};\n\n;// CONCATENATED MODULE: ./src/components/outline/OutlineItem.tsx\n\n\n\nconst OutlineItem_OutlineItem = ({ items, onClick }) => {\n const { isOutlineTargetVisible } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(ScrollContext);\n if (!items || !items.length) {\n return null;\n }\n function renderItem(item) {\n var _a;\n const clickHandler = (event) => {\n event.preventDefault();\n if (onClick) {\n onClick(item.dest);\n }\n };\n // If an item has sub titles, render \n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("li", { key: ((_a = item.dest) === null || _a === void 0 ? void 0 : _a.toString()) || item.title, className: classnames_default()(\'reader__outline-item\', {\n \'reader__outline-item--target-visible\': isOutlineTargetVisible(item.dest),\n }) },\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("a", { href: "#", onClick: clickHandler }, item.title),\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(OutlineItem_OutlineItem, { items: item.items, onClick: onClick })));\n }\n return external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("ul", { className: "reader__outline-items" }, items.map(item => renderItem(item)));\n};\n\n;// CONCATENATED MODULE: ./src/components/outline/Outline.tsx\nvar Outline_rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\nconst Outline_Outline = (_a) => {\n var extraProps = Outline_rest(_a, []);\n const { outline, pdfDocProxy, setOutline, setOutlinePositions } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(DocumentContext_DocumentContext);\n const { scrollToOutlineTarget, resetScrollObservers } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(ScrollContext);\n external_commonjs_react_commonjs2_react_amd_react_root_React_.useEffect(() => {\n if (outline) {\n return;\n }\n if (!pdfDocProxy) {\n return;\n }\n pdfDocProxy\n .getOutline()\n .then((outlineArray) => {\n setOutline(outlineArray);\n return buildOutlinePositions(pdfDocProxy, outlineArray);\n })\n .then(outlinePositions => {\n setOutlinePositions(outlinePositions);\n })\n .then(() => {\n resetScrollObservers();\n });\n }, [outline]);\n const clickHandler = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((dest) => {\n if (!dest) {\n return;\n }\n scrollToOutlineTarget(dest);\n return;\n }, []);\n if (!pdfDocProxy) {\n return null;\n }\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("div", Object.assign({ className: "reader__outline" }, extraProps), !!outline && external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(OutlineItem_OutlineItem, { items: outline, onClick: clickHandler })));\n};\n\n;// CONCATENATED MODULE: ./src/components/Overlay.tsx\nvar Overlay_rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\nconst Overlay = (_a) => {\n var { children } = _a, extraProps = Overlay_rest(_a, ["children"]);\n const { pageDimensions } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(DocumentContext_DocumentContext);\n const { rotation, scale } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(TransformContext);\n const getOverlayStyle = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(() => {\n return computePageStyle(pageDimensions, rotation, scale);\n }, [pageDimensions, rotation, scale]);\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("div", Object.assign({ className: "reader__page-overlay", style: getOverlayStyle() }, extraProps), children));\n};\n\n;// CONCATENATED MODULE: ./src/utils/MaxVisibleElement.ts\nfunction getMaxVisibleElement(visibleElements) {\n let maxVisibleKey = null;\n let maxRatio = 0;\n for (const [visibleKey, ratio] of visibleElements) {\n if (maxRatio < ratio) {\n maxVisibleKey = visibleKey;\n maxRatio = ratio;\n }\n }\n return maxVisibleKey;\n}\n\n;// CONCATENATED MODULE: ./src/components/PageNumberControl.tsx\n\n\n\n\n\nconst DELAY_SCROLL_TIME_OUT_MS = 1000;\nconst PageNumberControl = ({ className }) => {\n const delayTimerRef = external_commonjs_react_commonjs2_react_amd_react_root_React_.useRef();\n const { numPages } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(DocumentContext_DocumentContext);\n const { scrollToPage, visiblePageRatios } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(ScrollContext);\n const [minPage, setMinPage] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(0);\n const [userInput, setUserInput] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(\'0\');\n // Initialize page control element\n external_commonjs_react_commonjs2_react_amd_react_root_React_.useEffect(() => {\n if (numPages != 0) {\n setMinPage(1);\n }\n }, [numPages]);\n // Everytime we scroll through the page this useEffect\n // will trigger and set current page based on our current\n // scroll position\n external_commonjs_react_commonjs2_react_amd_react_root_React_.useEffect(() => {\n if (visiblePageRatios.size !== 0) {\n const maxVisiblePageNumber = getMaxVisibleElement(visiblePageRatios);\n if (maxVisiblePageNumber) {\n setUserInput(maxVisiblePageNumber.toString());\n }\n }\n }, [visiblePageRatios]);\n const onPageNumberChange = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((event) => {\n const { value } = event.currentTarget;\n // Decimal case\n if (!Number.isInteger(value)) {\n setUserInput(parseInt(value, 10).toString());\n }\n setUserInput(value);\n if (delayTimerRef.current) {\n clearTimeout(delayTimerRef.current);\n }\n // After user input the page that they want to scroll to\n // our ref will start setting a delay around 1s before scroll\n // to the position that user desire\n const newPageNumber = parseInt(value, 10);\n if (newPageNumber >= minPage && newPageNumber <= numPages) {\n delayTimerRef.current = setTimeout(() => {\n scrollToPage({ pageNumber: newPageNumber });\n }, DELAY_SCROLL_TIME_OUT_MS);\n }\n }, [minPage, numPages, scrollToPage]);\n const handleBlur = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(() => {\n if (delayTimerRef.current) {\n clearTimeout(delayTimerRef.current);\n }\n const pageNumber = parseInt(userInput, 10);\n if (Number.isNaN(pageNumber)) {\n return;\n }\n delayTimerRef.current = setTimeout(() => {\n scrollToPage({ pageNumber: pageNumber });\n }, DELAY_SCROLL_TIME_OUT_MS);\n }, [userInput, scrollToPage]);\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("div", { className: classnames_default()(\'reader__page-number-control\', className) },\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("input", { "aria-label": "Current Page", className: "reader__page-number-control__current-page", type: "number", name: "currentPage", value: userInput, onChange: onPageNumberChange, onBlur: handleBlur }),\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("span", { className: "reader__page-number-control__separator" }, "/"),\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("span", { "aria-label": "Total Pages", className: "reader__page-number-control__total-pages" }, numPages)));\n};\n\n;// CONCATENATED MODULE: ./src/context/PageRenderContext.ts\nvar PageRenderContext_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n\n\n\n\nconst PageRenderContext = external_commonjs_react_commonjs2_react_amd_react_root_React_.createContext({\n pageRenderStates: new Map(),\n getObjectURLForPage: args => {\n logProviderWarning(`getObjectURLForPage(${JSON.stringify(args)})`, \'PageRenderContext\');\n return null;\n },\n isBuildingObjectURLForPage: args => {\n logProviderWarning(`isBuildingObjectURLForPage(${JSON.stringify(args)})`, \'PageRenderContext\');\n return false;\n },\n buildObjectURLForPage: args => {\n logProviderWarning(`buildObjectURLForPage(${JSON.stringify(args)})`, \'PageRenderContext\');\n return Promise.resolve(\'\');\n },\n});\nfunction usePageRenderContextProps({ pdfDocProxy, scale, rotation, zoomMultiplier, visiblePageRatios, }) {\n const [pageRenderStates, _setPageRenderStates] = external_commonjs_react_commonjs2_react_amd_react_root_React_.useState(() => {\n const map = new Map();\n Object.freeze(map);\n return map;\n });\n const { isScaleChanged } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(TransformContext);\n // Because rendering a page is async, we will lose the current pageRenderStates\n // This ref trick allows the latest to be accessible when the objectURL is ready\n const pageRenderStatesRef = external_commonjs_react_commonjs2_react_amd_react_root_React_.useRef(pageRenderStates);\n const setPageRenderStates = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((pageRenderStates) => {\n pageRenderStatesRef.current = pageRenderStates;\n _setPageRenderStates(pageRenderStates);\n }, [pageRenderStatesRef]);\n const isBuildingObjectURLForPage = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(({ pageNumber, pageIndex }) => {\n if (typeof pageIndex === \'number\') {\n pageNumber = pageIndex + 1;\n }\n if (typeof pageNumber !== \'number\') {\n return false;\n }\n const state = pageRenderStates.get(pageNumber);\n if (!state) {\n return false;\n }\n return !state.objectURL;\n }, [pageRenderStates]);\n const getObjectURLForPage = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(({ pageNumber, pageIndex }) => {\n var _a;\n if (typeof pageIndex === \'number\') {\n pageNumber = pageIndex + 1;\n }\n if (typeof pageNumber !== \'number\') {\n return null;\n }\n return ((_a = pageRenderStates.get(pageNumber)) === null || _a === void 0 ? void 0 : _a.objectURL) || null;\n }, [pageRenderStates]);\n const buildObjectURLForPage = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(({ pageNumber, pageIndex }) => {\n var _a;\n if (typeof pageIndex === \'number\') {\n pageNumber = pageIndex + 1;\n }\n if (typeof pageNumber !== \'number\') {\n throw new Error(\'prop "pageNumber" is not a number\');\n }\n if (!pdfDocProxy) {\n throw new Error(\'cannot build a page until a "pdfDocProxy" is set on DocumentContext\');\n }\n // Don\'t need to start another task if already rendered\n const existingPromise = (_a = pageRenderStates.get(pageNumber)) === null || _a === void 0 ? void 0 : _a.promise;\n if (existingPromise && !isScaleChanged) {\n return existingPromise;\n }\n const promise = buildPageObjectURL({\n pageNumber,\n pdfDocProxy,\n scale,\n rotation,\n zoomMultiplier,\n });\n const renderState = {\n promise,\n objectURL: null,\n };\n promise.then(objectURL => {\n renderState.objectURL = objectURL;\n const newPageRenderStates = new Map(pageRenderStatesRef.current);\n Object.freeze(newPageRenderStates);\n setPageRenderStates(newPageRenderStates);\n });\n const newPageRenderStates = new Map(pageRenderStatesRef.current);\n newPageRenderStates.set(pageNumber, renderState);\n Object.freeze(newPageRenderStates);\n setPageRenderStates(newPageRenderStates);\n return promise;\n }, [pageRenderStates, pdfDocProxy, scale, rotation, zoomMultiplier]);\n external_commonjs_react_commonjs2_react_amd_react_root_React_.useEffect(() => {\n for (const pageNumber of visiblePageRatios.keys()) {\n if (pageRenderStates.has(pageNumber) && !isScaleChanged) {\n return;\n }\n buildObjectURLForPage({ pageNumber });\n }\n }, [pageRenderStates, visiblePageRatios, scale, rotation, devicePixelRatio]);\n return {\n pageRenderStates,\n getObjectURLForPage,\n isBuildingObjectURLForPage,\n buildObjectURLForPage,\n };\n}\n// Generate an object url for a given page, rendered in a shared canvas\nfunction buildPageObjectURL({ pageNumber, pdfDocProxy, scale = 1, \n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nrotation = PageRotation.Rotate0, zoomMultiplier = 1.2, imageType = \'image/png\', imageQuality = 1.0, }) {\n return PageRenderContext_awaiter(this, void 0, void 0, function* () {\n const pageProxy = yield pdfDocProxy.getPage(pageNumber);\n const blob = yield useRenderCanvas((canvas) => PageRenderContext_awaiter(this, void 0, void 0, function* () {\n // Render page in a canvas\n const viewport = pageProxy.getViewport({ scale: scale * zoomMultiplier * devicePixelRatio });\n canvas.height = viewport.height;\n canvas.width = viewport.width;\n canvas.style.width = \'100%\'; //de-zoom canvas with style (maybe you can directly use CSS), reaching de-zoom of higher definition PDF\n const canvasContext = canvas.getContext(\'2d\');\n if (!canvasContext) {\n throw new Error(\'canvas was unable to get a context\');\n }\n const renderTask = pageProxy.render({\n canvasContext,\n viewport,\n });\n yield renderTask.promise;\n yield new Promise(resolve => setTimeout(resolve, 16));\n // Fetch a blob for an image of the canvas\n return new Promise((resolve, reject) => {\n try {\n canvas.toBlob(blob => resolve(blob), imageType, imageQuality);\n }\n catch (error) {\n reject(error);\n }\n });\n }));\n // Convert blob image to object url\n if (!blob) {\n throw new Error(\'unable to create image from page\');\n }\n return URL.createObjectURL(blob);\n });\n}\nlet renderCanvas = null;\n// Get or create a shared canvas for rendering pages in\nfunction getRenderCanvas() {\n if (!renderCanvas) {\n renderCanvas = document.createElement(\'canvas\');\n }\n return renderCanvas;\n}\nlet nextCanvasUse = Promise.resolve();\n// Use the shared canvas to render a page, using promises to create a queue\nfunction useRenderCanvas(callback) {\n return PageRenderContext_awaiter(this, void 0, void 0, function* () {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n let resolve = (_value) => { };\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n let reject = (_reason) => { };\n const prom = new Promise((_resolve, _reject) => {\n resolve = _resolve;\n reject = _reject;\n });\n nextCanvasUse = nextCanvasUse.then(() => callback(getRenderCanvas()).then(resolve, reject));\n const result = yield prom;\n yield new Promise(res => setTimeout(res, 16)); // Give some time between renders\n return result;\n });\n}\n\n;// CONCATENATED MODULE: ./src/components/PageWrapper.tsx\nvar PageWrapper_rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\n\n\n\n\nconst PageWrapper = (_a) => {\n var { children, error, loading, loadingContentForBuildingImage, noData, pageIndex } = _a, extraProps = PageWrapper_rest(_a, ["children", "error", "loading", "loadingContentForBuildingImage", "noData", "pageIndex"]);\n const { rotation, scale } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(TransformContext);\n const { pageDimensions, getOutlineTargets } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(DocumentContext_DocumentContext);\n const { getObjectURLForPage, isBuildingObjectURLForPage } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(PageRenderContext);\n const objectURLForPage = getObjectURLForPage({ pageIndex });\n const isBuildingPageImage = isBuildingObjectURLForPage({ pageIndex });\n // Don\'t display until we have page size data\n // TODO: Handle this nicer so we display either the loading or error treatment\n if (!pageDimensions) {\n return null;\n }\n const getPageStyle = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(() => {\n const styles = computePageStyle(pageDimensions, rotation, scale);\n if (objectURLForPage) {\n styles.backgroundImage = `url(${objectURLForPage})`;\n }\n return styles;\n }, [pageDimensions, rotation, scale, objectURLForPage]);\n const getWidth = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback(() => {\n return getPageWidth(pageDimensions, rotation);\n }, [pageDimensions, rotation]);\n const outlineTargets = getOutlineTargets({ pageIndex, scale, rotation, pageDimensions });\n // Width needs to be set to prevent the outermost Page div from extending to fit the parent,\n // and mis-aligning the text layer.\n // TODO: Can we CSS this to auto-shrink?\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("div", Object.assign({ id: generatePageIdFromIndex(pageIndex), className: classnames_default()(\'reader__page\', { \'reader__page--has-page-image\': objectURLForPage }, { \'reader__page--no-page-image\': !objectURLForPage }, { \'reader__page--is-building-page-image\': isBuildingPageImage }), "data-page-number": pageIndex + 1, style: getPageStyle() }, extraProps),\n children,\n isBuildingPageImage && (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("div", { className: classnames_default()(\'reader__page\', {\n \'reader__page--is-loading-image\': isBuildingPageImage,\n }) }, loadingContentForBuildingImage)),\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(esm_Page, { width: getWidth(), error: error, loading: loading, noData: noData, pageIndex: pageIndex, scale: scale, rotate: rotation, renderAnnotationLayer: true }),\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("div", { className: "reader__page__outline-targets" }, outlineTargets.map(({ dest, leftPx, topPx }) => (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("span", { key: dest, className: "reader__page__outline-target", "data-outline-target-dest": dest, style: { left: leftPx + \'px\', top: topPx + \'px\' } }))))));\n};\n\n;// CONCATENATED MODULE: ./src/components/types/boundingBox.ts\n// Calculate a bounding box\'s pixel coordinates from the raw bounding box\'s coorditate ratios scaled to the page size\nfunction scaleRawBoundingBox(boundingBoxRaw, pageHeight, pageWidth) {\n const boxScaled = {\n page: boundingBoxRaw.page,\n top: boundingBoxRaw.top * pageHeight,\n left: boundingBoxRaw.left * pageWidth,\n height: boundingBoxRaw.height * pageHeight,\n width: boundingBoxRaw.width * pageWidth,\n };\n return boxScaled;\n}\n\n;// CONCATENATED MODULE: ./src/utils/format.ts\nconst PercentFormatter = new Intl.NumberFormat(\'en-US\', {\n style: \'percent\',\n maximumSignificantDigits: 3,\n});\n\n;// CONCATENATED MODULE: ./src/components/ZoomInButton.tsx\nvar ZoomInButton_rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\nconst MAX_ZOOM_IN_SCALE = 500;\nconst ZoomInButton = (_a) => {\n var { children } = _a, extraProps = ZoomInButton_rest(_a, ["children"]);\n const { scale, setScale, zoomMultiplier, setIsScaleChanged } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(TransformContext);\n const { updateScrollPosition } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(ScrollContext);\n const handleZoomIn = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((event) => {\n event.preventDefault();\n event.stopPropagation();\n const zoomScale = Number(PercentFormatter.format(scale * zoomMultiplier).replace(\'%\', \'\'));\n if (zoomScale <= MAX_ZOOM_IN_SCALE) {\n setIsScaleChanged(true);\n updateScrollPosition(1 * zoomMultiplier);\n setScale(scale * zoomMultiplier);\n }\n }, [scale, zoomMultiplier, updateScrollPosition]);\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("button", Object.assign({ className: "reader__zoom-btn zoom-in", onClick: handleZoomIn }, extraProps), children ? children : \'+\'));\n};\n\n;// CONCATENATED MODULE: ./src/components/ZoomOutButton.tsx\nvar ZoomOutButton_rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\nconst MIN_ZOOM_OUT_SCALE = 25;\nconst ZoomOutButton = (_a) => {\n var { children } = _a, extraProps = ZoomOutButton_rest(_a, ["children"]);\n const { scale, setScale, zoomMultiplier, setIsScaleChanged } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(TransformContext);\n const { updateScrollPosition } = external_commonjs_react_commonjs2_react_amd_react_root_React_.useContext(ScrollContext);\n const handleZoomOut = external_commonjs_react_commonjs2_react_amd_react_root_React_.useCallback((event) => {\n event.preventDefault();\n event.stopPropagation();\n const zoomScale = Number(PercentFormatter.format(scale / zoomMultiplier).replace(\'%\', \'\'));\n if (zoomScale >= MIN_ZOOM_OUT_SCALE) {\n setIsScaleChanged(true);\n updateScrollPosition(1 / zoomMultiplier);\n setScale(scale / zoomMultiplier);\n }\n }, [scale, zoomMultiplier, updateScrollPosition]);\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement("button", Object.assign({ className: "reader__zoom-btn zoom-out", onClick: handleZoomOut }, extraProps), children ? children : \'-\'));\n};\n\n;// CONCATENATED MODULE: ./src/context/ContextProvider.tsx\n\n\n\n\n\n\nconst ContextProvider = ({ children }) => {\n const documentProps = useDocumentContextProps();\n const transformProps = useTransformContextProps();\n const uiProps = useUiContextProps();\n const scrollProps = useScrollContextProps();\n const pageRenderProps = usePageRenderContextProps({\n pdfDocProxy: documentProps.pdfDocProxy,\n scale: transformProps.scale,\n rotation: transformProps.rotation,\n zoomMultiplier: transformProps.zoomMultiplier,\n visiblePageRatios: scrollProps.visiblePageRatios,\n });\n return (external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(DocumentContext_DocumentContext.Provider, { value: documentProps },\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(TransformContext.Provider, { value: transformProps },\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(UiContext.Provider, { value: uiProps },\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(ScrollContext.Provider, { value: scrollProps },\n external_commonjs_react_commonjs2_react_amd_react_root_React_.createElement(PageRenderContext.Provider, { value: pageRenderProps }, children))))));\n};\n\n;// CONCATENATED MODULE: ./index.ts\n/*\n * PDF Component Library exports\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/* harmony default export */ const index = ({\n BoundingBox: BoundingBox,\n computeBoundingBoxStyle: computeBoundingBoxStyle,\n computePageStyle: computePageStyle,\n ContextProvider: ContextProvider,\n DocumentContext: DocumentContext_DocumentContext,\n DocumentWrapper: DocumentWrapper,\n DownloadButton: DownloadButton,\n generatePageIdFromIndex: generatePageIdFromIndex,\n getPageHeight: getPageHeight,\n getPageWidth: getPageWidth,\n HighlightOverlay: HighlightOverlay,\n isSideways: isSideways,\n Outline: Outline_Outline,\n OutlineItem: OutlineItem_OutlineItem,\n Overlay: Overlay,\n PageNumberControl: PageNumberControl,\n PageRotation: PageRotation,\n PageWrapper: PageWrapper,\n rotateClockwise: rotateClockwise,\n rotateCounterClockwise: rotateCounterClockwise,\n scaleRawBoundingBox: scaleRawBoundingBox,\n scrollToId: scrollToId,\n scrollToPdfPageIndex: scrollToPdfPageIndex,\n ScrollContext: ScrollContext,\n TransformContext: TransformContext,\n UiContext: UiContext,\n ZoomInButton: ZoomInButton,\n ZoomOutButton: ZoomOutButton,\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL3NyYy91dGlscy9wcm92aWRlci50cz84NWFhIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL3V0aWxzL3JvdGF0ZS50cz9jZGJiIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL3V0aWxzL3Njcm9sbC50cz83YjA1Iiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL2NvbnRleHQvRG9jdW1lbnRDb250ZXh0LnRzPzJmMDMiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvY29udGV4dC9UcmFuc2Zvcm1Db250ZXh0LnRzP2JlNjQiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvdXRpbHMvc3R5bGUudHM/ZTMxYiIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL3NyYy9jb21wb25lbnRzL0JvdW5kaW5nQm94LnRzeD81NmNmIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2V4dGVuZHMuanM/YzMxZCIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RXaXRob3V0UHJvcGVydGllc0xvb3NlLmpzP2NjYjUiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0V2l0aG91dFByb3BlcnRpZXMuanM/MTVmZCIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS90eXBlb2YuanM/NTNjYSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jbGFzc0NhbGxDaGVjay5qcz9kNGVjIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NyZWF0ZUNsYXNzLmpzP2JlZTIiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vYXNzZXJ0VGhpc0luaXRpYWxpemVkLmpzPzI1N2UiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vc2V0UHJvdG90eXBlT2YuanM/YjM4MCIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pbmhlcml0cy5qcz8yNjJlIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4uanM/OTlkZSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9nZXRQcm90b3R5cGVPZi5qcz83ZTg0Iiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2RlZmluZVByb3BlcnR5LmpzP2FkZTMiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvbWFrZS1ldmVudC1wcm9wcy9kaXN0L2VzbS9pbmRleC5qcz81NDA3Iiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL21ha2UtY2FuY2VsbGFibGUtcHJvbWlzZS9kaXN0L2VzbS9pbmRleC5qcz9hY2Y0Iiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL21lcmdlLWNsYXNzLW5hbWVzL2Rpc3QvZXNtL2luZGV4LmpzP2EyMWMiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvdGlueS1pbnZhcmlhbnQvZGlzdC90aW55LWludmFyaWFudC5lc20uanM/ZjUxZiIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy90aW55LXdhcm5pbmcvZGlzdC90aW55LXdhcm5pbmcuZXNtLmpzPzJkNDQiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvcmVhY3QtcGRmL2Rpc3QvZXNtL0RvY3VtZW50Q29udGV4dC5qcz8yZTIxIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL3JlYWN0LXBkZi9kaXN0L2VzbS9NZXNzYWdlLmpzP2NmNmYiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvcmVhY3QtcGRmL2Rpc3QvZXNtL0xpbmtTZXJ2aWNlLmpzPzk3NzgiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvcmVhY3QtcGRmL2Rpc3QvZXNtL1Bhc3N3b3JkUmVzcG9uc2VzLmpzPzE1ZjUiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vYXJyYXlXaXRoSG9sZXMuanM/MGQyMSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pdGVyYWJsZVRvQXJyYXlMaW1pdC5qcz8wOWYwIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2FycmF5TGlrZVRvQXJyYXkuanM/NmI3NSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheS5qcz8wNmM1Iiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL25vbkl0ZXJhYmxlUmVzdC5qcz8zZDhjIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3NsaWNlZFRvQXJyYXkuanM/MzgzNSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9yZWFjdC1wZGYvZGlzdC9lc20vc2hhcmVkL3V0aWxzLmpzPzM3Y2IiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vYXJyYXlXaXRob3V0SG9sZXMuanM/NjAwNSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pdGVyYWJsZVRvQXJyYXkuanM/ZGI5MCIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9ub25JdGVyYWJsZVNwcmVhZC5qcz8zNDI3Iiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3RvQ29uc3VtYWJsZUFycmF5LmpzPzI5MDkiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvcmVhY3QtcGRmL2Rpc3QvZXNtL3NoYXJlZC9wcm9wVHlwZXMuanM/OGIwNSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9yZWFjdC1wZGYvZGlzdC9lc20vRG9jdW1lbnQuanM/ODJiZCIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9yZWFjdC1wZGYvZGlzdC9lc20vT3V0bGluZUNvbnRleHQuanM/Y2RhNiIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9yZWFjdC1wZGYvZGlzdC9lc20vUmVmLmpzPzM2MGIiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvcmVhY3QtcGRmL2Rpc3QvZXNtL091dGxpbmVJdGVtLmpzPzU2ODciLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvcmVhY3QtcGRmL2Rpc3QvZXNtL091dGxpbmUuanM/Y2QzNSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9tZXJnZS1yZWZzL2Rpc3QvZXNtL2luZGV4LmpzP2FjMDkiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvcmVhY3QtcGRmL2Rpc3QvZXNtL1BhZ2VDb250ZXh0LmpzPzg4N2UiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9ub2RlX21vZHVsZXMvcmVhY3QtcGRmL2Rpc3QvZXNtL1BhZ2UvUGFnZUNhbnZhcy5qcz9jZTJlIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL3JlYWN0LXBkZi9kaXN0L2VzbS9QYWdlL1BhZ2VTVkcuanM/NDBlZCIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9yZWFjdC1wZGYvZGlzdC9lc20vUGFnZS9UZXh0TGF5ZXIuanM/ODMwMiIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9yZWFjdC1wZGYvZGlzdC9lc20vUGFnZS9Bbm5vdGF0aW9uTGF5ZXIuanM/MmNlYyIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL25vZGVfbW9kdWxlcy9yZWFjdC1wZGYvZGlzdC9lc20vUGFnZS5qcz84NWFiIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vbm9kZV9tb2R1bGVzL3JlYWN0LXBkZi9kaXN0L2VzbS9lbnRyeS5qcz9mNTY0Iiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL3V0aWxzL1Njcm9sbERpcmVjdGlvbkRldGVjdG9yLnRzP2FjZTYiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvdXRpbHMvVmlzaWJsZUVudHJpZXNEZXRlY3Rvci50cz9mZjZiIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL2NvbnRleHQvU2Nyb2xsQ29udGV4dC50cz9jZjkxIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL2NvbnRleHQvVWlDb250ZXh0LnRzPzZiYjMiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvdXRpbHMvZXJyb3JNZXNzYWdlLnRzPzMwYTUiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvdXRpbHMvcGRmV29ya2VyLnRzP2E1ZGUiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvdXRpbHMvc2NhbGUudHM/YTAwNSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL3NyYy9jb21wb25lbnRzL3R5cGVzL2Rlc3RpbmF0aW9uLnRzP2IxYTMiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvY29tcG9uZW50cy9Eb2N1bWVudFdyYXBwZXIudHN4PzUyMDQiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvY29tcG9uZW50cy9Eb3dubG9hZEJ1dHRvbi50c3g/ZTIzNSIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL3NyYy9jb21wb25lbnRzL0hpZ2hsaWdodE92ZXJsYXkudHN4PzIyMWEiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvY29tcG9uZW50cy9vdXRsaW5lL091dGxpbmVJdGVtLnRzeD82YTczIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL2NvbXBvbmVudHMvb3V0bGluZS9PdXRsaW5lLnRzeD8zM2NhIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL2NvbXBvbmVudHMvT3ZlcmxheS50c3g/ZTlmMyIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL3NyYy91dGlscy9NYXhWaXNpYmxlRWxlbWVudC50cz8zOWM5Iiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL2NvbXBvbmVudHMvUGFnZU51bWJlckNvbnRyb2wudHN4Pzc5MGMiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvY29udGV4dC9QYWdlUmVuZGVyQ29udGV4dC50cz9mMDdjIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL2NvbXBvbmVudHMvUGFnZVdyYXBwZXIudHN4P2M5YzUiLCJ3ZWJwYWNrOi8vQGFsbGVuYWkvcGRmLWNvbXBvbmVudHMvLi9zcmMvY29tcG9uZW50cy90eXBlcy9ib3VuZGluZ0JveC50cz84NjEwIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL3V0aWxzL2Zvcm1hdC50cz8yZDhjIiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL2NvbXBvbmVudHMvWm9vbUluQnV0dG9uLnRzeD84NmI5Iiwid2VicGFjazovL0BhbGxlbmFpL3BkZi1jb21wb25lbnRzLy4vc3JjL2NvbXBvbmVudHMvWm9vbU91dEJ1dHRvbi50c3g/NmJmMyIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL3NyYy9jb250ZXh0L0NvbnRleHRQcm92aWRlci50c3g/YmM4YiIsIndlYnBhY2s6Ly9AYWxsZW5haS9wZGYtY29tcG9uZW50cy8uL2luZGV4LnRzP2E5NTkiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7O0FBQU8sU0FBUyxrQkFBa0IsQ0FBQyxZQUFvQixFQUFFLFlBQW9CO0lBQzNFLE9BQU8sQ0FBQyxJQUFJLENBQ1Ysa0JBQWtCLFlBQVksU0FBUyxZQUFZLHdDQUF3QyxDQUM1RixDQUFDO0FBQ0osQ0FBQzs7O0FDSkQsSUFBWSxZQUtYO0FBTEQsV0FBWSxZQUFZO0lBQ3RCLHFEQUFXO0lBQ1gsd0RBQWE7SUFDYiwyREFBZTtJQUNmLDJEQUFlO0FBQ2pCLENBQUMsRUFMVyxZQUFZLEtBQVosWUFBWSxRQUt2QjtBQUVNLFNBQVMsZUFBZSxDQUFDLFFBQXNCO0lBQ3BELFFBQVEsUUFBUSxFQUFFO1FBQ2hCLEtBQUssWUFBWSxDQUFDLE9BQU87WUFDdkIsT0FBTyxZQUFZLENBQUMsUUFBUSxDQUFDO1FBQy9CLEtBQUssWUFBWSxDQUFDLFFBQVE7WUFDeEIsT0FBTyxZQUFZLENBQUMsU0FBUyxDQUFDO1FBQ2hDLEtBQUssWUFBWSxDQUFDLFNBQVM7WUFDekIsT0FBTyxZQUFZLENBQUMsU0FBUyxDQUFD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QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUCx3QkFBd0Isc0JBQWU7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsT0FBTztBQUNQO0FBQ0EsT0FBTztBQUNQLEtBQUs7O0FBRUw7QUFDQTs7QUFFQSxFQUFFLFlBQVk7QUFDZDtBQUNBO0FBQ0E7QUFDQSxNQUFNLFNBQVM7QUFDZjtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNLGlCQUFpQjtBQUN2QjtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUEsVUFBVSxVQUFVO0FBQ3BCO0FBQ0E7O0FBRUEsVUFBVSxVQUFVO0FBQ3BCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUEsVUFBVSxVQUFVO0FBQ3BCO0FBQ0E7O0FBRUEsVUFBVSxVQUFVO0FBQ3BCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUEsVUFBVSxVQUFVO0FBQ3BCO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFH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QUNQLGlCQUFpQjtJQUNqQixZQUFZO0lBQ1osV0FBVztJQUNYLGVBQWU7SUFDZixzQkFBc0I7SUFDdEIsbUJBQW1CO0lBQ25CLFVBQVU7SUFDVixvQkFBb0I7SUFDcEIsYUFBYTtJQUNiLGdCQUFnQjtJQUNoQixTQUFTO0lBQ1QsWUFBWTtJQUNaLGFBQWE7Q0FDZCxFQUFDIiwiZmlsZSI6IjE4OC5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBmdW5jdGlvbiBsb2dQcm92aWRlcldhcm5pbmcoZnVuY3Rpb25OYW1lOiBzdHJpbmcsIHByb3ZpZGVyTmFtZTogc3RyaW5nKTogdm9pZCB7XG4gIGNvbnNvbGUud2FybihcbiAgICBgVW5hYmxlIHRvIGNhbGwgJHtmdW5jdGlvbk5hbWV9LiBUaGUgJHtwcm92aWRlck5hbWV9IFByb3ZpZGVyIG1heSBub3QgYmUgc2V0IHVwIGNvcnJlY3RseS5gXG4gICk7XG59XG4iLCJleHBvcnQgZW51bSBQYWdlUm90YXRpb24ge1xuICBSb3RhdGUwID0gMCxcbiAgUm90YXRlOTAgPSA5MCxcbiAgUm90YXRlMTgwID0gMTgwLFxuICBSb3RhdGUyNzAgPSAyNzAsXG59XG5cbmV4cG9ydCBmdW5jdGlvbiByb3RhdGVDbG9ja3dpc2Uocm90YXRpb246IFBhZ2VSb3RhdGlvbik6IFBhZ2VSb3RhdGlvbiB7XG4gIHN3aXRjaCAocm90YXRpb24pIHtcbiAgICBjYXNlIFBhZ2VSb3RhdGlvbi5Sb3RhdGUwOlxuICAgICAgcmV0dXJuIFBhZ2VSb3RhdGlvbi5Sb3RhdGU5MDtcbiAgICBjYXNlIFBhZ2VSb3RhdGlvbi5Sb3RhdGU5MDpcbiAgICAgIHJldHVybiBQYWdlUm90YXRpb24uUm90YXRlMTgwO1xuICAgIGNhc2UgUGFnZVJvdGF0aW9uLlJvdGF0ZTE4MDpcbiAgICAgIHJldHVybiBQYWdlUm90YXRpb24uUm90YXRlMjcwO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gUGFnZVJvdGF0aW9uLlJvdGF0ZTA7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJvdGF0ZUNvdW50ZXJDbG9ja3dpc2Uocm90YXRpb246IFBhZ2VSb3RhdGlvbik6IFBhZ2VSb3RhdGlvbiB7XG4gIHN3aXRjaCAocm90YXRpb24pIHtcbiAgICBjYXNlIFBhZ2VSb3RhdGlvbi5Sb3RhdGUwOlxuICAgICAgcmV0dXJuIFBhZ2VSb3RhdGlvbi5Sb3RhdGUyNzA7XG4gICAgY2FzZSBQYWdlUm90YXRpb24uUm90YXRlOTA6XG4gICAgICByZXR1cm4gUGFnZVJvdGF0aW9uLlJvdGF0ZTA7XG4gICAgY2FzZSBQYWdlUm90YXRpb24uUm90YXRlMTgwOlxuICAgICAgcmV0dXJuIFBhZ2VSb3RhdGlvbi5Sb3RhdGU5MDtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIFBhZ2VSb3RhdGlvbi5Sb3RhdGUxODA7XG4gIH1cbn1cblxuLyoqXG4gKiBUZXN0cyB3aGV0aGVyIHRoZSBwYWdlIGlzIHJvdGF0ZWQgOTAgZGVncmVlcyBjbG9ja3dpc2Ugb3IgY291bnRlcmNsb2Nrd2lzZSBmcm9tIHplcm8sXG4gKiBlLmcuIHdoZXRoZXIgdGhlIHBhZ2UgXCJpcyByb3RhdGVkIHNpZGV3YXlzLlwiXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1NpZGV3YXlzKHJvdGF0aW9uOiBQYWdlUm90YXRpb24pOiBib29sZWFuIHtcbiAgcmV0dXJuIHJvdGF0aW9uID09PSBQYWdlUm90YXRpb24uUm90YXRlOTAgfHwgcm90YXRpb24gPT09IFBhZ2VSb3RhdGlvbi5Sb3RhdGUyNzA7XG59XG4iLCJpbXBvcnQgeyBEaW1lbnNpb25zIH0gZnJvbSAnLi4vY29tcG9uZW50cy90eXBlcy9ib3VuZGluZ0JveCc7XG5pbXBvcnQgeyBQYWdlUHJvcGVydGllcyB9IGZyb20gJy4uL2NvbXBvbmVudHMvdHlwZXMvcGFnZSc7XG5pbXBvcnQgeyBOdWxsYWJsZSB9IGZyb20gJy4uL2NvbXBvbmVudHMvdHlwZXMvdXRpbHMnO1xuaW1wb3J0IHsgUGFnZVJvdGF0aW9uIH0gZnJvbSAnLi4vdXRpbHMvcm90YXRlJztcblxuLy8gRWFjaCBwYWdlIGRpdiBpcyBJRCdkIGFjY29yZGluZyB0byBwYWdlIGluZGV4XG4vLyBlLmcuIHJlYWRlcl9wZ18wLCByZWFkZXJfcGdfMSwgZXRjLlxuZXhwb3J0IGNvbnN0IFBBR0VfTkFWX1RBUkdFVF9JRF9ST09UID0gJ3JlYWRlcl9wZ18nO1xuXG5jb25zdCBQREZfSEVJR0hUX1BPSU5UUyA9IDc5MjtcbmNvbnN0IFBERl9XSURUSF9QT0lOVFMgPSA2MTI7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVBhZ2VJZEZyb21JbmRleChwYWdlSW5kZXg6IG51bWJlciB8IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtQQUdFX05BVl9UQVJHRVRfSURfUk9PVH0ke3BhZ2VJbmRleH1gO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9JZChpZDogc3RyaW5nKTogdm9pZCB7XG4gIGNvbnN0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7XG4gIGlmIChlbGVtZW50KSB7XG4gICAgZWxlbWVudC5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiAnc21vb3RoJywgYmxvY2s6ICdzdGFydCcsIGlubGluZTogJ2NlbnRlcicgfSk7XG4gIH0gZWxzZSB7XG4gICAgY29uc29sZS5lcnJvcihgQ291bGQgbm90IGZpbmQgc2Nyb2xsIHRhcmdldCB3aXRoIElEICMke2lkfWApO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzY3JvbGxUb1BkZlBhZ2VJbmRleChwYWdlSW5kZXg6IG51bWJlciB8IHN0cmluZyk6IHZvaWQge1xuICBzY3JvbGxUb0lkKGdlbmVyYXRlUGFnZUlkRnJvbUluZGV4KHBhZ2VJbmRleCkpO1xufVxuXG4vKipcbiAqIFNjcm9sbCBQREYgZG9jdW1lbnQgdG8gYSBzcGVjaWZpYyBwb3NpdGlvbi5cbiAqIEBwYXJhbSBwYWdlSW5kZXggVGhlIGluZGV4IG9mIHRoZSBwYWdlIHdoZXJlIHRoZSBwb3NpdGlvbiBsb2NhdGVzIGF0XG4gKiBAcGFyYW0gbGVmdFBvaW50cyBUaGUgaG9yaXpvbnRhbCBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBvcmlnaW4gYW5kIHRoZSBwb3NpdGlvbiAoaW4gUERGIGNvb3JkaW5hdGVzKVxuICogQHBhcmFtIGJvdHRvbVBvaW50cyBUaGUgdmVydGljYWwgZGlzdGFuY2UgYmV0d2VlbiB0aGUgb3JpZ2luIGFuZCB0aGUgcG9zaXRpb24gKGluIFBERiBjb29yZGluYXRlcylcbiAqIEBwYXJhbSByb3RhdGlvbiBUaGUgcm90YXRpb24gZGVncmVlIG9mIHRoZSBkb2N1bWVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9Qb3NpdGlvbihcbiAgcGFnZUluZGV4OiBudW1iZXIsXG4gIGxlZnRQb2ludHM6IG51bWJlcixcbiAgYm90dG9tUG9pbnRzOiBudW1iZXIsXG4gIHJvdGF0aW9uOiBQYWdlUm90YXRpb24gPSBQYWdlUm90YXRpb24uUm90YXRlMFxuKTogdm9pZCB7XG4gIC8qXG4gICAgVmVydGljYWwgc2Nyb2xsIGRpc3RhbmNlIGlzIGNhbGN1bGF0ZWQgYXNcbiAgICA9IHRvdGFsIG51bWJlciBvZiBwcmV2aW91cyBwYWdlcyAqIHBhZ2UgaGVpZ2h0IGluY2x1ZGluZyB0b3AvZG93biBtYXJnaW5zXG4gICAgKyB0aGUgbWFyZ2luIHRvcCBvZiBjdXJyZW50IHBhZ2VcbiAgICArIHRoZSBkaXN0YW5jZSBmcm9tIHRoZSBwYWdlIHRvcCB0byB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uXG5cbiAgICBOb3RpY2UgdGhhdCB0aGUgc2Nyb2xsIGRpc3RhbmNlIGlzIG1lYXN1cmVkIGluIHBpeGVscyxcbiAgICBzbyBsZWZ0UG9pbnRzL2JvdHRvbVBvaW50cyBoYXMgdG8gYmUgdHJhbnNmb3JtZWQgZnJvbSBwb2ludHMgdG8gcGl4ZWxzIGZpcnN0LlxuICAqL1xuXG4gIGNvbnN0IHsgd2lkdGgsIGhlaWdodCwgbWFyZ2luVG9wLCBtYXJnaW5Cb3R0b20sIG1hcmdpbkxlZnQsIG1hcmdpblJpZ2h0IH0gPVxuICAgIGdldFBhZ2VQcm9wZXJ0aWVzSW5QaXhlbHMoKTtcbiAgY29uc3QgaGVpZ2h0V2l0aE1hcmdpbnMgPSBoZWlnaHQgKyBtYXJnaW5Ub3AgKyBtYXJnaW5Cb3R0b207XG5cbiAgLy8gV2hlbiBhIHBhcGVyIGlzIHJvdGF0ZWQsIGl0cyBoZWlnaHQgYW5kIHdpZHRoIHdvdWxkIGJlIHN3aXRjaGVkIGF1dG9tYXRpY2FsbHkuIEhvd2V2ZXIsIGxlZnRQb2ludHMgYW5kIGJvdHRvbVBvaW50cyByZW1haW4gdGhlIHNhbWUuXG4gIGxldCBtYXJnaW5Ub3BQaXhlbHMgPSBtYXJnaW5Ub3A7XG4gIGxldCBib3R0b21QaXhlbHMgPSAoaGVpZ2h0ICogYm90dG9tUG9pbnRzKSAvIFBERl9IRUlHSFRfUE9JTlRTO1xuICBsZXQgbGVmdFBpeGVscyA9ICh3aWR0aCAqIGxlZnRQb2ludHMpIC8gUERGX1dJRFRIX1BPSU5UUztcblxuICBpZiAocm90YXRpb24gPT0gUGFnZVJvdGF0aW9uLlJvdGF0ZTkwKSB7XG4gICAgbWFyZ2luVG9wUGl4ZWxzID0gbWFyZ2luTGVmdDtcbiAgICBib3R0b21QaXhlbHMgPSAoaGVpZ2h0ICogKFBERl9XSURUSF9QT0lOVFMgLSBsZWZ0UG9pbnRzKSkgLyBQREZfV0lEVEhfUE9JTlRTO1xuICAgIGxlZnRQaXhlbHMgPSAod2lkdGggKiBib3R0b21Qb2ludHMpIC8gUERGX0hFSUdIVF9QT0lOVFM7XG4gIH0gZWxzZSBpZiAocm90YXRpb24gPT0gUGFnZVJvdGF0aW9uLlJvdGF0ZTE4MCkge1xuICAgIG1hcmdpblRvcFBpeGVscyA9IG1hcmdpbkJvdHRvbTtcbiAgICBib3R0b21QaXhlbHMgPSAoaGVpZ2h0ICogKFBERl9IRUlHSFRfUE9JTlRTIC0gYm90dG9tUG9pbnRzKSkgLyBQREZfSEVJR0hUX1BPSU5UUztcbiAgICBsZWZ0UGl4ZWxzID0gKHdpZHRoICogKFBERl9XSURUSF9QT0lOVFMgLSBsZWZ0UG9pbnRzKSkgLyBQREZfV0lEVEhfUE9JTlRTO1xuICB9IGVsc2UgaWYgKHJvdGF0aW9uID09IFBhZ2VSb3RhdGlvbi5Sb3RhdGUyNzApIHtcbiAgICBtYXJnaW5Ub3BQaXhlbHMgPSBtYXJnaW5SaWdodDtcbiAgICBib3R0b21QaXhlbHMgPSAoaGVpZ2h0ICogbGVmdFBvaW50cykgLyBQREZfV0lEVEhfUE9JTlRTO1xuICAgIGxlZnRQaXhlbHMgPSAod2lkdGggKiAoUERGX0hFSUdIVF9QT0lOVFMgLSBib3R0b21Qb2ludHMpKSAvIFBERl9IRUlHSFRfUE9JTlRTO1xuICB9XG5cbiAgLy8gRmluZCBwYWdlIGVsZW1lbnRcbiAgY29uc3QgcGFnZUlkID0gZ2VuZXJhdGVQYWdlSWRGcm9tSW5kZXgocGFnZUluZGV4KTtcbiAgY29uc3QgcGFnZUlkRWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHBhZ2VJZCk7XG4gIGlmICghcGFnZUlkRWxlbWVudCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEZpbmQgZmlyc3Qgc2Nyb2xsYWJsZSBwYXJlbnRcbiAgY29uc3QgcGFyZW50RWxlbWVudCA9IGdldFNjcm9sbFBhcmVudChwYWdlSWRFbGVtZW50KTtcbiAgaWYgKCFwYXJlbnRFbGVtZW50KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gQXBwbHkgc2Nyb2xsXG4gIHBhcmVudEVsZW1lbnQuc2Nyb2xsVG8oe1xuICAgIHRvcDogY2FsY3VsYXRlVG9wUHgoe1xuICAgICAgaGVpZ2h0V2l0aE1hcmdpbnNJblB4OiBoZWlnaHRXaXRoTWFyZ2lucyxcbiAgICAgIHBhZ2VJbmRleDogcGFnZUluZGV4LFxuICAgICAgbWFyZ2luVG9wUHg6IG1hcmdpblRvcFBpeGVscyxcbiAgICAgIGhlaWdodFB4OiBoZWlnaHQsXG4gICAgICBib3R0b21QeDogYm90dG9tUGl4ZWxzLFxuICAgIH0pLFxuICAgIGxlZnQ6IE1hdGguZmxvb3IobGVmdFBpeGVscyksXG4gICAgYmVoYXZpb3I6ICdzbW9vdGgnLFxuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNjcm9sbFBhcmVudChub2RlOiBIVE1MRWxlbWVudCk6IE51bGxhYmxlPEhUTUxFbGVtZW50PiB7XG4gIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgaWYgKCFub2RlIHx8IG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ2JvZHknKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiAgfVxuICBpZiAobm9kZS5zY3JvbGxIZWlnaHQgPiBub2RlLmNsaWVudEhlaWdodCAmJiAhaXNPdmVyZmxvd0lzSGlkZGVuKG5vZGUpKSB7XG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cbiAgcmV0dXJuIGdldFNjcm9sbFBhcmVudChub2RlLnBhcmVudEVsZW1lbnQgYXMgSFRNTEVsZW1lbnQpO1xufVxuXG5mdW5jdGlvbiBpc092ZXJmbG93SXNIaWRkZW4obm9kZTogSFRNTEVsZW1lbnQpOiBib29sZWFuIHtcbiAgY29uc3Qgc3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKG5vZGUpO1xuICByZXR1cm4gKFxuICAgIHN0eWxlLm92ZXJmbG93LmluY2x1ZGVzKCdoaWRkZW4nKSB8fFxuICAgIHN0eWxlLm92ZXJmbG93WC5pbmNsdWRlcygnaGlkZGVuJykgfHxcbiAgICBzdHlsZS5vdmVyZmxvd1kuaW5jbHVkZXMoJ2hpZGRlbicpXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVUb3BQeCh7XG4gIGhlaWdodFdpdGhNYXJnaW5zSW5QeCxcbiAgcGFnZUluZGV4LFxuICBtYXJnaW5Ub3BQeCxcbiAgaGVpZ2h0UHgsXG4gIGJvdHRvbVB4LFxufToge1xuICBoZWlnaHRXaXRoTWFyZ2luc0luUHg6IG51bWJlcjtcbiAgcGFnZUluZGV4OiBudW1iZXI7XG4gIG1hcmdpblRvcFB4OiBudW1iZXI7XG4gIGhlaWdodFB4OiBudW1iZXI7XG4gIGJvdHRvbVB4OiBudW1iZXI7XG59KTogbnVtYmVyIHtcbiAgcmV0dXJuIE1hdGguZmxvb3IoaGVpZ2h0V2l0aE1hcmdpbnNJblB4ICogcGFnZUluZGV4ICsgbWFyZ2luVG9wUHggKyAoaGVpZ2h0UHggLSBib3R0b21QeCkpO1xufVxuXG4vKipcbiAqIEdldCBsZW5ndGhzLCB3aWR0aHMsIGFuZCBtYXJnaW5zIG9mIGEgcGFnZS5cbiAqIEByZXR1cm5zIGEgUGFnZVByb3BlcnRpZXMgb2JqZWN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQYWdlUHJvcGVydGllc0luUGl4ZWxzKCk6IFBhZ2VQcm9wZXJ0aWVzIHtcbiAgY29uc3QgZmlyc3RQYWdlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZ2VuZXJhdGVQYWdlSWRGcm9tSW5kZXgoMCkpO1xuICBpZiAoIWZpcnN0UGFnZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoYENhbm5vdCBnZXQgdGhlIGZpcnN0IHBhZ2Ugb2YgdGhpcyBkb2N1bWVudC5gKTtcbiAgICBjb25zdCBlbXB0eVBhZ2VQcm9wZXJ0aWVzOiBQYWdlUHJvcGVydGllcyA9IHtcbiAgICAgIHdpZHRoOiAwLFxuICAgICAgaGVpZ2h0OiAwLFxuICAgICAgbWFyZ2luVG9wOiAwLFxuICAgICAgbWFyZ2luQm90dG9tOiAwLFxuICAgICAgbWFyZ2luTGVmdDogMCxcbiAgICAgIG1hcmdpblJpZ2h0OiAwLFxuICAgIH07XG4gICAgcmV0dXJuIGVtcHR5UGFnZVByb3BlcnRpZXM7XG4gIH1cblxuICBjb25zdCBzdHlsZSA9IGdldENvbXB1dGVkU3R5bGUoZmlyc3RQYWdlIGFzIEVsZW1lbnQpO1xuICBjb25zdCBwYWdlUHJvcGVydGllczogUGFnZVByb3BlcnRpZXMgPSB7XG4gICAgd2lkdGg6IHBhcnNlSW50KHN0eWxlLndpZHRoKSxcbiAgICBoZWlnaHQ6IHBhcnNlSW50KHN0eWxlLmhlaWdodCksXG4gICAgbWFyZ2luVG9wOiBwYXJzZUludChzdHlsZS5tYXJnaW5Ub3ApLFxuICAgIG1hcmdpbkJvdHRvbTogcGFyc2VJbnQoc3R5bGUubWFyZ2luQm90dG9tKSxcbiAgICBtYXJnaW5MZWZ0OiBwYXJzZUludChzdHlsZS5tYXJnaW5MZWZ0KSxcbiAgICBtYXJnaW5SaWdodDogcGFyc2VJbnQoc3R5bGUubWFyZ2luUmlnaHQpLFxuICB9O1xuXG4gIHJldHVybiBwYWdlUHJvcGVydGllcztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZVRhcmdldFBvc2l0aW9uKHtcbiAgc2NhbGUsXG4gIGxlZnRQb2ludCxcbiAgYm90dG9tUG9pbnQsXG4gIHBhZ2VEaW1lbnNpb25zLFxuICByb3RhdGlvbiA9IFBhZ2VSb3RhdGlvbi5Sb3RhdGUwLFxufToge1xuICBzY2FsZTogbnVtYmVyO1xuICBsZWZ0UG9pbnQ6IG51bWJlcjtcbiAgYm90dG9tUG9pbnQ6IG51bWJlcjtcbiAgcGFnZURpbWVuc2lvbnM6IERpbWVuc2lvbnM7XG4gIHJvdGF0aW9uOiBQYWdlUm90YXRpb247XG59KTogeyBsZWZ0UHg6IG51bWJlcjsgdG9wUHg6IG51bWJlciB9IHtcbiAgc3dpdGNoIChyb3RhdGlvbikge1xuICAgIGRlZmF1bHQ6XG4gICAgY2FzZSBQYWdlUm90YXRpb24uUm90YXRlMDoge1xuICAgICAgY29uc3QgbGVmdFB4ID0gKGxlZnRQb2ludCAvIFBERl9XSURUSF9QT0lOVFMpICogcGFnZURpbWVuc2lvbnMud2lkdGggKiBzY2FsZTtcbiAgICAgIGNvbnN0IHRvcFB4ID0gKDEgLSBib3R0b21Qb2ludCAvIFBERl9IRUlHSFRfUE9JTlRTKSAqIHBhZ2VEaW1lbnNpb25zLmhlaWdodCAqIHNjYWxlO1xuICAgICAgcmV0dXJuIHsgbGVmdFB4LCB0b3BQeCB9O1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgcGRmanMgfSBmcm9tICdyZWFjdC1wZGYnO1xuXG5pbXBvcnQgeyBEaW1lbnNpb25zIH0gZnJvbSAnLi4vY29tcG9uZW50cy90eXBlcy9ib3VuZGluZ0JveCc7XG5pbXBvcnQge1xuICBPdXRsaW5lTm9kZSxcbiAgT3V0bGluZVBvc2l0aW9uLFxuICBPdXRsaW5lUG9zaXRpb25zQnlQYWdlTnVtYmVyTWFwLFxuICBPdXRsaW5lVGFyZ2V0LFxuICBPdXRsaW5lVGFyZ2V0QXJncyxcbn0gZnJvbSAnLi4vY29tcG9uZW50cy90eXBlcy9vdXRsaW5lJztcbmltcG9ydCB7IE51bGxhYmxlIH0gZnJvbSAnLi4vY29tcG9uZW50cy90eXBlcy91dGlscyc7XG5pbXBvcnQgeyBsb2dQcm92aWRlcldhcm5pbmcgfSBmcm9tICcuLi91dGlscy9wcm92aWRlcic7XG5pbXBvcnQgeyBjYWxjdWxhdGVUYXJnZXRQb3NpdGlvbiB9IGZyb20gJy4uL3V0aWxzL3Njcm9sbCc7XG5leHBvcnQgaW50ZXJmYWNlIElEb2N1bWVudENvbnRleHQge1xuICBudW1QYWdlczogbnVtYmVyO1xuICBvdXRsaW5lOiBOdWxsYWJsZTxBcnJheTxPdXRsaW5lTm9kZT4+O1xuICBvdXRsaW5lUG9zaXRpb25zOiBOdWxsYWJsZTxPdXRsaW5lUG9zaXRpb25zQnlQYWdlTnVtYmVyTWFwPjtcbiAgcGFnZURpbWVuc2lvbnM6IERpbWVuc2lvbnM7IC8vIFNjYWxlZCBhdCAxMDAlXG4gIHBkZkRvY1Byb3h5PzogcGRmanMuUERGRG9jdW1lbnRQcm94eTtcbiAgZ2V0T3V0bGluZVRhcmdldHM6IChvcHRzOiBPdXRsaW5lVGFyZ2V0QXJncykgPT4gT3V0bGluZVRhcmdldFtdO1xuICBzZXROdW1QYWdlczogKG51bVBhZ2VzOiBudW1iZXIpID0+IHZvaWQ7XG4gIHNldE91dGxpbmU6IChvdXRsaW5lOiBOdWxsYWJsZTxBcnJheTxPdXRsaW5lTm9kZT4+KSA9PiB2b2lkO1xuICBzZXRPdXRsaW5lUG9zaXRpb25zOiAob3V0bGluZVBvc2l0aW9uczogTnVsbGFibGU8T3V0bGluZVBvc2l0aW9uc0J5UGFnZU51bWJlck1hcD4pID0+IHZvaWQ7XG4gIHNldFBhZ2VEaW1lbnNpb25zOiAocGFnZURpbWVuc2lvbnM6IERpbWVuc2lvbnMpID0+IHZvaWQ7XG4gIHNldFBkZkRvY1Byb3h5OiAocGRmRG9jUHJveHk6IHBkZmpzLlBERkRvY3VtZW50UHJveHkpID0+IHZvaWQ7XG59XG5cbmV4cG9ydCBjb25zdCBEb2N1bWVudENvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PElEb2N1bWVudENvbnRleHQ+KHtcbiAgbnVtUGFnZXM6IDAsXG4gIG91dGxpbmU6IFtdLFxuICBvdXRsaW5lUG9zaXRpb25zOiBudWxsLFxuICBwYWdlRGltZW5zaW9uczogeyBoZWlnaHQ6IDAsIHdpZHRoOiAwIH0sXG4gIHBkZkRvY1Byb3h5OiB1bmRlZmluZWQsXG4gIGdldE91dGxpbmVUYXJnZXRzOiBvcHRzID0+IHtcbiAgICBsb2dQcm92aWRlcldhcm5pbmcoYGdldE91dGxpbmVUYXJnZXRzKCR7SlNPTi5zdHJpbmdpZnkob3B0cyl9KWAsICdEb2N1bWVudENvbnRleHQnKTtcbiAgICByZXR1cm4gW107XG4gIH0sXG4gIHNldE51bVBhZ2VzOiBudW1QYWdlcyA9PiB7XG4gICAgbG9nUHJvdmlkZXJXYXJuaW5nKGBzZXROdW1QYWdlcygke251bVBhZ2VzfSlgLCAnRG9jdW1lbnRDb250ZXh0Jyk7XG4gIH0sXG4gIHNldE91dGxpbmU6IG91dGxpbmUgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgc2V0T3V0bGluZSgke291dGxpbmV9KWAsICdEb2N1bWVudENvbnRleHQnKTtcbiAgfSxcbiAgc2V0T3V0bGluZVBvc2l0aW9uczogb3V0bGluZSA9PiB7XG4gICAgbG9nUHJvdmlkZXJXYXJuaW5nKGBzZXRPdXRsaW5lUG9zaXRpb25zKCR7b3V0bGluZX0pYCwgJ0RvY3VtZW50Q29udGV4dCcpO1xuICB9LFxuICBzZXRQYWdlRGltZW5zaW9uczogcGFnZURpbWVuc2lvbnMgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgc2V0UGFnZURpbWVuc2lvbnMoJHtwYWdlRGltZW5zaW9uc30pYCwgJ0RvY3VtZW50Q29udGV4dCcpO1xuICB9LFxuICBzZXRQZGZEb2NQcm94eTogcGRmRG9jUHJveHkgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgc2V0UGRmRG9jUHJveHkoJHtwZGZEb2NQcm94eX0pYCwgJ0RvY3VtZW50Q29udGV4dCcpO1xuICB9LFxufSk7XG5cbmV4cG9ydCBmdW5jdGlvbiB1c2VEb2N1bWVudENvbnRleHRQcm9wcygpOiBJRG9jdW1lbnRDb250ZXh0IHtcbiAgY29uc3QgW251bVBhZ2VzLCBzZXROdW1QYWdlc10gPSBSZWFjdC51c2VTdGF0ZTxudW1iZXI+KDApO1xuICBjb25zdCBbb3V0bGluZSwgc2V0T3V0bGluZV0gPSBSZWFjdC51c2VTdGF0ZTxOdWxsYWJsZTxBcnJheTxPdXRsaW5lTm9kZT4+PihudWxsKTtcbiAgY29uc3QgW291dGxpbmVQb3NpdGlvbnMsIHNldE91dGxpbmVQb3NpdGlvbnNdID1cbiAgICBSZWFjdC51c2VTdGF0ZTxOdWxsYWJsZTxPdXRsaW5lUG9zaXRpb25zQnlQYWdlTnVtYmVyTWFwPj4obnVsbCk7XG4gIGNvbnN0IFtwYWdlRGltZW5zaW9ucywgc2V0UGFnZURpbWVuc2lvbnNdID0gUmVhY3QudXNlU3RhdGU8RGltZW5zaW9ucz4oeyBoZWlnaHQ6IDAsIHdpZHRoOiAwIH0pO1xuICBjb25zdCBbcGRmRG9jUHJveHksIHNldFBkZkRvY1Byb3h5XSA9IFJlYWN0LnVzZVN0YXRlPHBkZmpzLlBERkRvY3VtZW50UHJveHk+KCk7XG5cbiAgLy8gRHJhdyBvdXRsaW5lIHRhcmdldCBpbnRvIHRoZSBwZGYgYmFzZWQgb24gdGhlIGFyZ3NcbiAgY29uc3QgZ2V0T3V0bGluZVRhcmdldHMgPSBSZWFjdC51c2VDYWxsYmFjayhcbiAgICAoe1xuICAgICAgcGFnZU51bWJlcixcbiAgICAgIHBhZ2VJbmRleCxcbiAgICAgIHNjYWxlLFxuICAgICAgcm90YXRpb24sXG4gICAgICBwYWdlRGltZW5zaW9ucyxcbiAgICB9OiBPdXRsaW5lVGFyZ2V0QXJncyk6IE91dGxpbmVUYXJnZXRbXSA9PiB7XG4gICAgICBpZiAodHlwZW9mIHBhZ2VJbmRleCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgcGFnZU51bWJlciA9IHBhZ2VJbmRleCArIDE7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHBhZ2VOdW1iZXIgIT09ICdudW1iZXInKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBvc2l0aW9ucyA9IG91dGxpbmVQb3NpdGlvbnM/LmdldChwYWdlTnVtYmVyKSB8fCBbXTtcbiAgICAgIHJldHVybiBwb3NpdGlvbnMubWFwKCh7IGRlc3QsIGxlZnRQb2ludCwgYm90dG9tUG9pbnQgfSkgPT4ge1xuICAgICAgICBjb25zdCB7IGxlZnRQeCwgdG9wUHggfSA9IGNhbGN1bGF0ZVRhcmdldFBvc2l0aW9uKHtcbiAgICAgICAgICBzY2FsZSxcbiAgICAgICAgICByb3RhdGlvbixcbiAgICAgICAgICBsZWZ0UG9pbnQsXG4gICAgICAgICAgYm90dG9tUG9pbnQsXG4gICAgICAgICAgcGFnZURpbWVuc2lvbnMsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGRlc3QsXG4gICAgICAgICAgbGVmdFB4LFxuICAgICAgICAgIHRvcFB4LFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgfSxcbiAgICBbb3V0bGluZVBvc2l0aW9uc11cbiAgKTtcblxuICByZXR1cm4ge1xuICAgIG51bVBhZ2VzLFxuICAgIG91dGxpbmUsXG4gICAgb3V0bGluZVBvc2l0aW9ucyxcbiAgICBwYWdlRGltZW5zaW9ucyxcbiAgICBwZGZEb2NQcm94eSxcbiAgICBnZXRPdXRsaW5lVGFyZ2V0cyxcbiAgICBzZXROdW1QYWdlcyxcbiAgICBzZXRPdXRsaW5lLFxuICAgIHNldE91dGxpbmVQb3NpdGlvbnMsXG4gICAgc2V0UGFnZURpbWVuc2lvbnM6IHNldFBhZ2VEaW1lbnNpb25zLFxuICAgIHNldFBkZkRvY1Byb3h5LFxuICB9O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYnVpbGRPdXRsaW5lUG9zaXRpb25zKFxuICBwZGZEb2NQcm94eTogcGRmanMuUERGRG9jdW1lbnRQcm94eSxcbiAgb3V0bGluZT86IE91dGxpbmVOb2RlW11cbik6IFByb21pc2U8T3V0bGluZVBvc2l0aW9uc0J5UGFnZU51bWJlck1hcD4ge1xuICBpZiAoIW91dGxpbmUpIHtcbiAgICBvdXRsaW5lID0gYXdhaXQgcGRmRG9jUHJveHkuZ2V0T3V0bGluZSgpO1xuICB9XG5cbiAgLy8gRGVwdGggZmlyc3Qgc2VhcmNoIHRocm91Z2ggb3V0bGluZSBpdGVtc1xuICBjb25zdCBpdGVtUXVldWUgPSBvdXRsaW5lLnNsaWNlKCk7XG4gIGNvbnN0IHByb21zOiBQcm9taXNlPE51bGxhYmxlPE91dGxpbmVQb3NpdGlvbj4+W10gPSBbXTtcbiAgd2hpbGUgKGl0ZW1RdWV1ZS5sZW5ndGggPiAwKSB7XG4gICAgY29uc3QgaXRlbSA9IGl0ZW1RdWV1ZS5wb3AoKTtcbiAgICBpZiAoIWl0ZW0pIHtcbiAgICAgIGNvbnRpbnVlOyAvLyBOb3QgYWJsZSB0byBwcm9jZXNzXG4gICAgfVxuICAgIGNvbnN0IHsgZGVzdCwgaXRlbXMgfSA9IGl0ZW07XG5cbiAgICAvLyBBZGQgY2hpbGQgaXRlbXMgdG8gcXVldWVcbiAgICBpZiAoQXJyYXkuaXNBcnJheShpdGVtcykpIHtcbiAgICAgIGl0ZW1RdWV1ZS5wdXNoKC4uLml0ZW1zKTtcbiAgICB9XG5cbiAgICAvLyBGZXRjaCBkZXN0aW5hdGlvbnMgZm9yIGl0ZW1cbiAgICBpZiAoQXJyYXkuaXNBcnJheShkZXN0KSkge1xuICAgICAgcHJvbXMucHVzaCguLi5kZXN0Lm1hcChkZXN0ID0+IGdldERlc3RpbmF0aW9uKHBkZkRvY1Byb3h5LCBkZXN0KSkpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGRlc3QgPT09ICdzdHJpbmcnKSB7XG4gICAgICBwcm9tcy5wdXNoKGdldERlc3RpbmF0aW9uKHBkZkRvY1Byb3h5LCBkZXN0KSk7XG4gICAgfVxuICB9XG5cbiAgLy8gQ29sbGVjdCByZXN1bHRzIGFsbCBhdCBvbmNlLCBzbyB3ZSBkb24ndCBoYXZlIHRvIHBheSBmb3IgdGhlIGNvc3Qgb2ZcbiAgLy8gcXVldWVpbmcgbWVzc2FnZXMgc2VudCB0byB0aGUgd29ya2VyXG4gIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChwcm9tcyk7XG5cbiAgLy8gU3BsaXQgcmVzdWx0cyBpbnRvIHBhZ2VzXG4gIGNvbnN0IG1hcCA9IG5ldyBNYXA8bnVtYmVyLCBPdXRsaW5lUG9zaXRpb25bXT4oKTtcbiAgZm9yIChjb25zdCByZXN1bHQgb2YgcmVzdWx0cykge1xuICAgIGlmICghcmVzdWx0KSB7XG4gICAgICBjb250aW51ZTsgLy8gRmlsdGVyIG91dCBudWxsXG4gICAgfVxuICAgIGNvbnN0IHsgcGFnZU51bWJlciB9ID0gcmVzdWx0O1xuICAgIGlmICghbWFwLmhhcyhwYWdlTnVtYmVyKSkge1xuICAgICAgbWFwLnNldChwYWdlTnVtYmVyLCBbXSk7XG4gICAgfVxuICAgIG1hcC5nZXQocGFnZU51bWJlcik/LnB1c2gocmVzdWx0KTtcbiAgfVxuXG4gIC8vIEZyZWV6ZSBvYmplY3RzIHNvIGNvbnN1bWVycyBjYW5ub3QgbXV0YXRlXG4gIGZvciAoY29uc3QgcGFnZVBvcyBvZiBtYXAudmFsdWVzKCkpIHtcbiAgICBmb3IgKGNvbnN0IHBvcyBvZiBwYWdlUG9zKSB7XG4gICAgICBPYmplY3QuZnJlZXplKHBvcyk7XG4gICAgfVxuICAgIE9iamVjdC5mcmVlemUocGFnZVBvcyk7XG4gIH1cbiAgT2JqZWN0LmZyZWV6ZShtYXApO1xuXG4gIHJldHVybiBtYXA7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldERlc3RpbmF0aW9uKFxuICBwZGZEb2NQcm94eTogcGRmanMuUERGRG9jdW1lbnRQcm94eSxcbiAgZGVzdDogc3RyaW5nXG4pOiBQcm9taXNlPE51bGxhYmxlPE91dGxpbmVQb3NpdGlvbj4+IHtcbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGRmRG9jUHJveHkuZ2V0RGVzdGluYXRpb24oZGVzdCk7XG4gIGlmICghcmVzdWx0KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGNvbnN0IFtyZWYsIF9mb3JtYXQsIGxlZnRQb2ludCwgYm90dG9tUG9pbnRdID0gcmVzdWx0O1xuICBjb25zdCBwYWdlSW5kZXggPSBhd2FpdCBwZGZEb2NQcm94eS5nZXRQYWdlSW5kZXgocmVmKTtcbiAgY29uc3QgcGFnZU51bWJlciA9IHBhZ2VJbmRleCArIDE7XG4gIHJldHVybiB7IHBhZ2VOdW1iZXIsIGRlc3QsIGxlZnRQb2ludCwgYm90dG9tUG9pbnQgfTtcbn1cbiIsImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcblxuaW1wb3J0IHsgbG9nUHJvdmlkZXJXYXJuaW5nIH0gZnJvbSAnLi4vdXRpbHMvcHJvdmlkZXInO1xuaW1wb3J0IHsgUGFnZVJvdGF0aW9uIH0gZnJvbSAnLi4vdXRpbHMvcm90YXRlJztcblxuZXhwb3J0IGludGVyZmFjZSBJVHJhbnNmb3JtQ29udGV4dCB7XG4gIHJvdGF0aW9uOiBQYWdlUm90YXRpb247XG4gIHNjYWxlOiBudW1iZXI7XG4gIHpvb21NdWx0aXBsaWVyOiBudW1iZXI7XG4gIGlzU2NhbGVDaGFuZ2VkOiBib29sZWFuO1xuICBzZXRSb3RhdGlvbjogKHJvdGF0aW9uOiBQYWdlUm90YXRpb24pID0+IHZvaWQ7XG4gIHNldFNjYWxlOiAoc2NhbGU6IG51bWJlcikgPT4gdm9pZDtcbiAgc2V0Wm9vbU11bHRpcGxpZXI6ICh6b29tOiBudW1iZXIpID0+IHZvaWQ7XG4gIHNldElzU2NhbGVDaGFuZ2VkOiAoaXNTY2FsZUNoYW5nZTogYm9vbGVhbikgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGNvbnN0IFRyYW5zZm9ybUNvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PElUcmFuc2Zvcm1Db250ZXh0Pih7XG4gIHJvdGF0aW9uOiBQYWdlUm90YXRpb24uUm90YXRlMCxcbiAgc2NhbGU6IDEsXG4gIHpvb21NdWx0aXBsaWVyOiAxLjIsXG4gIGlzU2NhbGVDaGFuZ2VkOiBmYWxzZSxcbiAgc2V0Um90YXRpb246IHJvdGF0aW9uID0+IHtcbiAgICBsb2dQcm92aWRlcldhcm5pbmcoYHNldFJvdGF0aW9uKCR7cm90YXRpb259KWAsICdUcmFuc2Zvcm1Db250ZXh0Jyk7XG4gIH0sXG4gIHNldFNjYWxlOiBzY2FsZSA9PiB7XG4gICAgbG9nUHJvdmlkZXJXYXJuaW5nKGBzZXRTY2FsZSgke3NjYWxlfSlgLCAnVHJhbnNmb3JtQ29udGV4dCcpO1xuICB9LFxuICBzZXRab29tTXVsdGlwbGllcjogem9vbSA9PiB7XG4gICAgbG9nUHJvdmlkZXJXYXJuaW5nKGBzZXRab29tTXVsdGlwbGllcigke3pvb219KWAsICdUcmFuc2Zvcm1Db250ZXh0Jyk7XG4gIH0sXG4gIHNldElzU2NhbGVDaGFuZ2VkOiBpc1NjYWxlQ2hhbmdlID0+IHtcbiAgICBsb2dQcm92aWRlcldhcm5pbmcoYHNldElzU2NhbGVDaGFuZ2VkKCR7aXNTY2FsZUNoYW5nZX0pYCwgJ1RyYW5zZm9ybUNvbnRleHQnKTtcbiAgfSxcbn0pO1xuXG5leHBvcnQgZnVuY3Rpb24gdXNlVHJhbnNmb3JtQ29udGV4dFByb3BzKCk6IElUcmFuc2Zvcm1Db250ZXh0IHtcbiAgY29uc3QgW3JvdGF0aW9uLCBzZXRSb3RhdGlvbl0gPSBSZWFjdC51c2VTdGF0ZTxQYWdlUm90YXRpb24+KFBhZ2VSb3RhdGlvbi5Sb3RhdGUwKTtcbiAgY29uc3QgW3NjYWxlLCBzZXRTY2FsZV0gPSBSZWFjdC51c2VTdGF0ZTxudW1iZXI+KDEuMCk7XG4gIGNvbnN0IFt6b29tTXVsdGlwbGllciwgc2V0Wm9vbU11bHRpcGxpZXJdID0gUmVhY3QudXNlU3RhdGU8bnVtYmVyPigxLjIpO1xuICBjb25zdCBbaXNTY2FsZUNoYW5nZWQsIHNldElzU2NhbGVDaGFuZ2VkXSA9IFJlYWN0LnVzZVN0YXRlPGJvb2xlYW4+KGZhbHNlKTtcblxuICByZXR1cm4ge1xuICAgIHJvdGF0aW9uLFxuICAgIHNjYWxlLFxuICAgIGlzU2NhbGVDaGFuZ2VkLFxuICAgIHNldFJvdGF0aW9uLFxuICAgIHNldFNjYWxlLFxuICAgIHNldFpvb21NdWx0aXBsaWVyLFxuICAgIHNldElzU2NhbGVDaGFuZ2VkLFxuICAgIHpvb21NdWx0aXBsaWVyLFxuICB9O1xufVxuIiwiaW1wb3J0IHsgRGltZW5zaW9ucywgU2l6ZSB9IGZyb20gJy4uL2NvbXBvbmVudHMvdHlwZXMvYm91bmRpbmdCb3gnO1xuaW1wb3J0IHsgaXNTaWRld2F5cywgUGFnZVJvdGF0aW9uIH0gZnJvbSAnLi9yb3RhdGUnO1xuXG4vLyBDb21wdXRlcyB0aGUgc3R5bGUgZm9yIGEgYm91bmRpbmcgYm94LCBhY2NvdW50aW5nIGZvciBwYWdlIHJvYXRpb24gYW5kIHBhZ2Ugc2NhbGluZy96b29tXG5leHBvcnQgZnVuY3Rpb24gY29tcHV0ZUJvdW5kaW5nQm94U3R5bGUoXG4gIGJvdW5kaW5nQm94U2l6ZTogU2l6ZSxcbiAgcGFnZURpbWVuc2lvbnM6IERpbWVuc2lvbnMsXG4gIHJvdGF0aW9uOiBQYWdlUm90YXRpb24sXG4gIHNjYWxlOiBudW1iZXJcbik6IFNpemUge1xuICBjb25zdCB7IHRvcCwgbGVmdCwgaGVpZ2h0LCB3aWR0aCB9ID0gYm91bmRpbmdCb3hTaXplO1xuXG4gIHN3aXRjaCAocm90YXRpb24pIHtcbiAgICBjYXNlIFBhZ2VSb3RhdGlvbi5Sb3RhdGU5MDpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRvcDogbGVmdCAqIHNjYWxlLFxuICAgICAgICBsZWZ0OiAocGFnZURpbWVuc2lvbnMuaGVpZ2h0IC0gaGVpZ2h0IC0gdG9wKSAqIHNjYWxlLFxuICAgICAgICBoZWlnaHQ6IHdpZHRoICogc2NhbGUsXG4gICAgICAgIHdpZHRoOiBoZWlnaHQgKiBzY2FsZSxcbiAgICAgIH07XG4gICAgY2FzZSBQYWdlUm90YXRpb24uUm90YXRlMTgwOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdG9wOiAocGFnZURpbWVuc2lvbnMuaGVpZ2h0IC0gaGVpZ2h0IC0gdG9wKSAqIHNjYWxlLFxuICAgICAgICBsZWZ0OiAocGFnZURpbWVuc2lvbnMud2lkdGggLSB3aWR0aCAtIGxlZnQpICogc2NhbGUsXG4gICAgICAgIGhlaWdodDogaGVpZ2h0ICogc2NhbGUsXG4gICAgICAgIHdpZHRoOiB3aWR0aCAqIHNjYWxlLFxuICAgICAgfTtcbiAgICBjYXNlIFBhZ2VSb3RhdGlvbi5Sb3RhdGUyNzA6XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0b3A6IChwYWdlRGltZW5zaW9ucy53aWR0aCAtIHdpZHRoIC0gbGVmdCkgKiBzY2FsZSxcbiAgICAgICAgbGVmdDogdG9wICogc2NhbGUsXG4gICAgICAgIGhlaWdodDogd2lkdGggKiBzY2FsZSxcbiAgICAgICAgd2lkdGg6IGhlaWdodCAqIHNjYWxlLFxuICAgICAgfTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdG9wOiB0b3AgKiBzY2FsZSxcbiAgICAgICAgbGVmdDogbGVmdCAqIHNjYWxlLFxuICAgICAgICBoZWlnaHQ6IGhlaWdodCAqIHNjYWxlLFxuICAgICAgICB3aWR0aDogd2lkdGggKiBzY2FsZSxcbiAgICAgIH07XG4gIH1cbn1cblxuLy8gQ29tcHV0ZSB0aGUgc3R5bGUgZm9yIGEgcGFnZSwgYWNjb3VudGluZyBmb3IgcGFnZSByb3RhdGlvbiBhbmQgcGFnZSBzY2FsaW5nL3pvb21cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlUGFnZVN0eWxlKFxuICBwYWdlRGltZW5zaW9uczogRGltZW5zaW9ucyxcbiAgcm90YXRpb246IFBhZ2VSb3RhdGlvbixcbiAgc2NhbGU6IG51bWJlclxuKTogU2l6ZSB7XG4gIHJldHVybiB7XG4gICAgaGVpZ2h0OiBnZXRQYWdlSGVpZ2h0KHBhZ2VEaW1lbnNpb25zLCByb3RhdGlvbikgKiBzY2FsZSxcbiAgICB3aWR0aDogZ2V0UGFnZVdpZHRoKHBhZ2VEaW1lbnNpb25zLCByb3RhdGlvbikgKiBzY2FsZSxcbiAgICBsZWZ0OiAwLFxuICAgIHRvcDogMCxcbiAgfTtcbn1cblxuLy8gR2V0IHBhZ2UgaGVpZ2h0IGFjY291bnRpbmcgZm9yIHBhZ2Ugcm90YXRpb24tIGlmIHRoZSBwYWdlIGlzIHJvdGF0ZWQgb24gaXRzIHNpZGUsIGl0cyB3aWR0aCBiZWNvbWVzIGl0cyBoZWlnaHRcbmV4cG9ydCBmdW5jdGlvbiBnZXRQYWdlSGVpZ2h0KHBhZ2VEaW1lbnNpb25zOiBEaW1lbnNpb25zLCByb3RhdGlvbjogUGFnZVJvdGF0aW9uKTogbnVtYmVyIHtcbiAgcmV0dXJuIGlzU2lkZXdheXMocm90YXRpb24pID8gcGFnZURpbWVuc2lvbnMud2lkdGggOiBwYWdlRGltZW5zaW9ucy5oZWlnaHQ7XG59XG5cbi8vIEdldCBwYWdlIHdpZHRoIGFjY291bnRpbmcgZm9yIHBhZ2Ugcm90YXRpb24tIGlmIHRoZSBwYWdlIGlzIHJvdGF0ZWQgb24gaXRzIHNpZGUsIGl0cyBoZWlnaHQgYmVjb21lcyBpdHMgd2lkdGhcbmV4cG9ydCBmdW5jdGlvbiBnZXRQYWdlV2lkdGgocGFnZURpbWVuc2lvbnM6IERpbWVuc2lvbnMsIHJvdGF0aW9uOiBQYWdlUm90YXRpb24pOiBudW1iZXIge1xuICByZXR1cm4gaXNTaWRld2F5cyhyb3RhdGlvbikgPyBwYWdlRGltZW5zaW9ucy5oZWlnaHQgOiBwYWdlRGltZW5zaW9ucy53aWR0aDtcbn1cbiIsImltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5pbXBvcnQgeyBEb2N1bWVudENvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L0RvY3VtZW50Q29udGV4dCc7XG5pbXBvcnQgeyBUcmFuc2Zvcm1Db250ZXh0IH0gZnJvbSAnLi4vY29udGV4dC9UcmFuc2Zvcm1Db250ZXh0JztcbmltcG9ydCB7IGNvbXB1dGVCb3VuZGluZ0JveFN0eWxlIH0gZnJvbSAnLi4vdXRpbHMvc3R5bGUnO1xuaW1wb3J0IHsgQm91bmRpbmdCb3ggYXMgQm91bmRpbmdCb3hUeXBlIH0gZnJvbSAnLi90eXBlcy9ib3VuZGluZ0JveCc7XG5cbmV4cG9ydCB0eXBlIFByb3BzID0ge1xuICBjbGFzc05hbWU/OiBzdHJpbmc7XG4gIGlkPzogc3RyaW5nO1xuICBpc0hpZ2hsaWdodGVkPzogYm9vbGVhbjtcbiAgb25DbGljaz86ICgpID0+IHZvaWQ7XG59ICYgQm91bmRpbmdCb3hUeXBlO1xuXG5leHBvcnQgY29uc3QgQm91bmRpbmdCb3g6IFJlYWN0LkZ1bmN0aW9uQ29tcG9uZW50PFByb3BzPiA9ICh7XG4gIHRvcCxcbiAgbGVmdCxcbiAgaGVpZ2h0LFxuICB3aWR0aCxcbiAgY2xhc3NOYW1lLFxuICBpZCxcbiAgaXNIaWdobGlnaHRlZCxcbiAgb25DbGljayxcbiAgLi4uZXh0cmFQcm9wc1xufTogUHJvcHMpID0+IHtcbiAgY29uc3QgeyBwYWdlRGltZW5zaW9ucyB9ID0gUmVhY3QudXNlQ29udGV4dChEb2N1bWVudENvbnRleHQpO1xuICBjb25zdCB7IHJvdGF0aW9uLCBzY2FsZSB9ID0gUmVhY3QudXNlQ29udGV4dChUcmFuc2Zvcm1Db250ZXh0KTtcbiAgY29uc3QgYm94U2l6ZSA9IHsgdG9wLCBsZWZ0LCBoZWlnaHQsIHdpZHRoIH07XG4gIGNvbnN0IGNvbXBvbmVudENsYXNzTmFtZSA9IGNsYXNzTmFtZXMoXG4gICAgJ3JlYWRlcl9fcGFnZS1vdmVybGF5X19ib3VuZGluZy1ib3gnLFxuICAgIGlzSGlnaGxpZ2h0ZWQgPT09IHRydWUgPyAncmVhZGVyX19wYWdlLW92ZXJsYXlfX2JvdW5kaW5nLWJveC1oaWdobGlnaHRlZCcgOiAnJyxcbiAgICBjbGFzc05hbWVcbiAgKTtcblxuICBjb25zdCBnZXRCb3VuZGluZ0JveFN0eWxlID0gUmVhY3QudXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIHJldHVybiBjb21wdXRlQm91bmRpbmdCb3hTdHlsZShib3hTaXplLCBwYWdlRGltZW5zaW9ucywgcm90YXRpb24sIHNjYWxlKTtcbiAgfSwgW3BhZ2VEaW1lbnNpb25zLCByb3RhdGlvbiwgc2NhbGVdKTtcblxuICBjb25zdCByb3RhdGlvbkNsYXNzTmFtZSA9IFJlYWN0LnVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICByZXR1cm4gYHJvdGF0ZSR7cm90YXRpb259YDtcbiAgfSwgW3JvdGF0aW9uXSk7XG5cbiAgcmV0dXJuIChcbiAgICA8UmVhY3QuRnJhZ21lbnQ+XG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzTmFtZT17YHJlYWRlcl9fcGFnZS1vdmVybGF5X19ib3VuZGluZy1ib3gtdW5kZXJsaW5lICR7cm90YXRpb25DbGFzc05hbWUoKX1gfVxuICAgICAgICBzdHlsZT17Z2V0Qm91bmRpbmdCb3hTdHlsZSgpfVxuICAgICAgLz5cbiAgICAgIDxkaXZcbiAgICAgICAgaWQ9e2lkfVxuICAgICAgICBjbGFzc05hbWU9e2Ake2NvbXBvbmVudENsYXNzTmFtZX0gJHtyb3RhdGlvbkNsYXNzTmFtZSgpfWB9XG4gICAgICAgIHN0eWxlPXtnZXRCb3VuZGluZ0JveFN0eWxlKCl9XG4gICAgICAgIG9uQ2xpY2s9e29uQ2xpY2t9XG4gICAgICAgIHsuLi5leHRyYVByb3BzfVxuICAgICAgLz5cbiAgICA8L1JlYWN0LkZyYWdtZW50PlxuICApO1xufTtcbiIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9leHRlbmRzKCkge1xuICBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkge1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldO1xuXG4gICAgICBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7XG4gICAgICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0YXJnZXQ7XG4gIH07XG5cbiAgcmV0dXJuIF9leHRlbmRzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzTG9vc2Uoc291cmNlLCBleGNsdWRlZCkge1xuICBpZiAoc291cmNlID09IG51bGwpIHJldHVybiB7fTtcbiAgdmFyIHRhcmdldCA9IHt9O1xuICB2YXIgc291cmNlS2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7XG4gIHZhciBrZXksIGk7XG5cbiAgZm9yIChpID0gMDsgaSA8IHNvdXJjZUtleXMubGVuZ3RoOyBpKyspIHtcbiAgICBrZXkgPSBzb3VyY2VLZXlzW2ldO1xuICAgIGlmIChleGNsdWRlZC5pbmRleE9mKGtleSkgPj0gMCkgY29udGludWU7XG4gICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgfVxuXG4gIHJldHVybiB0YXJnZXQ7XG59IiwiaW1wb3J0IG9iamVjdFdpdGhvdXRQcm9wZXJ0aWVzTG9vc2UgZnJvbSBcIi4vb2JqZWN0V2l0aG91dFByb3BlcnRpZXNMb29zZS5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzKHNvdXJjZSwgZXhjbHVkZWQpIHtcbiAgaWYgKHNvdXJjZSA9PSBudWxsKSByZXR1cm4ge307XG4gIHZhciB0YXJnZXQgPSBvYmplY3RXaXRob3V0UHJvcGVydGllc0xvb3NlKHNvdXJjZSwgZXhjbHVkZWQpO1xuICB2YXIga2V5LCBpO1xuXG4gIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKSB7XG4gICAgdmFyIHNvdXJjZVN5bWJvbEtleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHNvdXJjZSk7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgc291cmNlU3ltYm9sS2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAga2V5ID0gc291cmNlU3ltYm9sS2V5c1tpXTtcbiAgICAgIGlmIChleGNsdWRlZC5pbmRleE9mKGtleSkgPj0gMCkgY29udGludWU7XG4gICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzb3VyY2UsIGtleSkpIGNvbnRpbnVlO1xuICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7XG4gIFwiQGJhYmVsL2hlbHBlcnMgLSB0eXBlb2ZcIjtcblxuICByZXR1cm4gX3R5cGVvZiA9IFwiZnVuY3Rpb25cIiA9PSB0eXBlb2YgU3ltYm9sICYmIFwic3ltYm9sXCIgPT0gdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA/IGZ1bmN0aW9uIChvYmopIHtcbiAgICByZXR1cm4gdHlwZW9mIG9iajtcbiAgfSA6IGZ1bmN0aW9uIChvYmopIHtcbiAgICByZXR1cm4gb2JqICYmIFwiZnVuY3Rpb25cIiA9PSB0eXBlb2YgU3ltYm9sICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqO1xuICB9LCBfdHlwZW9mKG9iaik7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3Rvcikge1xuICBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7XG4gIH1cbn0iLCJmdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldO1xuICAgIGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTtcbiAgICBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7XG4gICAgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2NyZWF0ZUNsYXNzKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykge1xuICBpZiAocHJvdG9Qcm9wcykgX2RlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTtcbiAgaWYgKHN0YXRpY1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQ29uc3RydWN0b3IsIFwicHJvdG90eXBlXCIsIHtcbiAgICB3cml0YWJsZTogZmFsc2VcbiAgfSk7XG4gIHJldHVybiBDb25zdHJ1Y3Rvcjtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfYXNzZXJ0VGhpc0luaXRpYWxpemVkKHNlbGYpIHtcbiAgaWYgKHNlbGYgPT09IHZvaWQgMCkge1xuICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihcInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZFwiKTtcbiAgfVxuXG4gIHJldHVybiBzZWxmO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9zZXRQcm90b3R5cGVPZihvLCBwKSB7XG4gIF9zZXRQcm90b3R5cGVPZiA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCBmdW5jdGlvbiBfc2V0UHJvdG90eXBlT2YobywgcCkge1xuICAgIG8uX19wcm90b19fID0gcDtcbiAgICByZXR1cm4gbztcbiAgfTtcblxuICByZXR1cm4gX3NldFByb3RvdHlwZU9mKG8sIHApO1xufSIsImltcG9ydCBzZXRQcm90b3R5cGVPZiBmcm9tIFwiLi9zZXRQcm90b3R5cGVPZi5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7XG4gIGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gXCJmdW5jdGlvblwiICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb25cIik7XG4gIH1cblxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoc3ViQ2xhc3MsIFwicHJvdG90eXBlXCIsIHtcbiAgICB2YWx1ZTogT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogc3ViQ2xhc3MsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KSxcbiAgICB3cml0YWJsZTogZmFsc2VcbiAgfSk7XG4gIGlmIChzdXBlckNsYXNzKSBzZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcyk7XG59IiwiaW1wb3J0IF90eXBlb2YgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvdHlwZW9mXCI7XG5pbXBvcnQgYXNzZXJ0VGhpc0luaXRpYWxpemVkIGZyb20gXCIuL2Fzc2VydFRoaXNJbml0aWFsaXplZC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkge1xuICBpZiAoY2FsbCAmJiAoX3R5cGVvZihjYWxsKSA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgY2FsbCA9PT0gXCJmdW5jdGlvblwiKSkge1xuICAgIHJldHVybiBjYWxsO1xuICB9IGVsc2UgaWYgKGNhbGwgIT09IHZvaWQgMCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJEZXJpdmVkIGNvbnN0cnVjdG9ycyBtYXkgb25seSByZXR1cm4gb2JqZWN0IG9yIHVuZGVmaW5lZFwiKTtcbiAgfVxuXG4gIHJldHVybiBhc3NlcnRUaGlzSW5pdGlhbGl6ZWQoc2VsZik7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2dldFByb3RvdHlwZU9mKG8pIHtcbiAgX2dldFByb3RvdHlwZU9mID0gT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LmdldFByb3RvdHlwZU9mIDogZnVuY3Rpb24gX2dldFByb3RvdHlwZU9mKG8pIHtcbiAgICByZXR1cm4gby5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKG8pO1xuICB9O1xuICByZXR1cm4gX2dldFByb3RvdHlwZU9mKG8pO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwgdmFsdWUpIHtcbiAgaWYgKGtleSBpbiBvYmopIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHtcbiAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB3cml0YWJsZTogdHJ1ZVxuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIG9ialtrZXldID0gdmFsdWU7XG4gIH1cblxuICByZXR1cm4gb2JqO1xufSIsIi8vIEFzIGRlZmluZWQgb24gdGhlIGxpc3Qgb2Ygc3VwcG9ydGVkIGV2ZW50czogaHR0cHM6Ly9yZWFjdGpzLm9yZy9kb2NzL2V2ZW50cy5odG1sXG5leHBvcnQgdmFyIGNsaXBib2FyZEV2ZW50cyA9IFsnb25Db3B5JywgJ29uQ3V0JywgJ29uUGFzdGUnXTtcbmV4cG9ydCB2YXIgY29tcG9zaXRpb25FdmVudHMgPSBbJ29uQ29tcG9zaXRpb25FbmQnLCAnb25Db21wb3NpdGlvblN0YXJ0JywgJ29uQ29tcG9zaXRpb25VcGRhdGUnXTtcbmV4cG9ydCB2YXIga2V5Ym9hcmRFdmVudHMgPSBbJ29uS2V5RG93bicsICdvbktleVByZXNzJywgJ29uS2V5VXAnXTtcbmV4cG9ydCB2YXIgZm9jdXNFdmVudHMgPSBbJ29uRm9jdXMnLCAnb25CbHVyJ107XG5leHBvcnQgdmFyIGZvcm1FdmVudHMgPSBbJ29uQ2hhbmdlJywgJ29uSW5wdXQnLCAnb25JbnZhbGlkJywgJ29uUmVzZXQnLCAnb25TdWJtaXQnXTtcbmV4cG9ydCB2YXIgZ2VuZXJpY0V2ZW50cyA9IFsnb25FcnJvcicsICdvbkxvYWQnXTtcbmV4cG9ydCB2YXIgbW91c2VFdmVudHMgPSBbJ29uQ2xpY2snLCAnb25Db250ZXh0TWVudScsICdvbkRvdWJsZUNsaWNrJywgJ29uRHJhZycsICdvbkRyYWdFbmQnLCAnb25EcmFnRW50ZXInLCAnb25EcmFnRXhpdCcsICdvbkRyYWdMZWF2ZScsICdvbkRyYWdPdmVyJywgJ29uRHJhZ1N0YXJ0JywgJ29uRHJvcCcsICdvbk1vdXNlRG93bicsICdvbk1vdXNlRW50ZXInLCAnb25Nb3VzZUxlYXZlJywgJ29uTW91c2VNb3ZlJywgJ29uTW91c2VPdXQnLCAnb25Nb3VzZU92ZXInLCAnb25Nb3VzZVVwJ107XG5leHBvcnQgdmFyIHBvaW50ZXJFdmVudHMgPSBbJ29uUG9pbnRlckRvd24nLCAnb25Qb2ludGVyTW92ZScsICdvblBvaW50ZXJVcCcsICdvblBvaW50ZXJDYW5jZWwnLCAnb25Hb3RQb2ludGVyQ2FwdHVyZScsICdvbkxvc3RQb2ludGVyQ2FwdHVyZScsICdvblBvaW50ZXJFbnRlcicsICdvblBvaW50ZXJMZWF2ZScsICdvblBvaW50ZXJPdmVyJywgJ29uUG9pbnRlck91dCddO1xuZXhwb3J0IHZhciBzZWxlY3Rpb25FdmVudHMgPSBbJ29uU2VsZWN0J107XG5leHBvcnQgdmFyIHRvdWNoRXZlbnRzID0gWydvblRvdWNoQ2FuY2VsJywgJ29uVG91Y2hFbmQnLCAnb25Ub3VjaE1vdmUnLCAnb25Ub3VjaFN0YXJ0J107XG5leHBvcnQgdmFyIHVpRXZlbnRzID0gWydvblNjcm9sbCddO1xuZXhwb3J0IHZhciB3aGVlbEV2ZW50cyA9IFsnb25XaGVlbCddO1xuZXhwb3J0IHZhciBtZWRpYUV2ZW50cyA9IFsnb25BYm9ydCcsICdvbkNhblBsYXknLCAnb25DYW5QbGF5VGhyb3VnaCcsICdvbkR1cmF0aW9uQ2hhbmdlJywgJ29uRW1wdGllZCcsICdvbkVuY3J5cHRlZCcsICdvbkVuZGVkJywgJ29uRXJyb3InLCAnb25Mb2FkZWREYXRhJywgJ29uTG9hZGVkTWV0YWRhdGEnLCAnb25Mb2FkU3RhcnQnLCAnb25QYXVzZScsICdvblBsYXknLCAnb25QbGF5aW5nJywgJ29uUHJvZ3Jlc3MnLCAnb25SYXRlQ2hhbmdlJywgJ29uU2Vla2VkJywgJ29uU2Vla2luZycsICdvblN0YWxsZWQnLCAnb25TdXNwZW5kJywgJ29uVGltZVVwZGF0ZScsICdvblZvbHVtZUNoYW5nZScsICdvbldhaXRpbmcnXTtcbmV4cG9ydCB2YXIgaW1hZ2VFdmVudHMgPSBbJ29uTG9hZCcsICdvbkVycm9yJ107XG5leHBvcnQgdmFyIGFuaW1hdGlvbkV2ZW50cyA9IFsnb25BbmltYXRpb25TdGFydCcsICdvbkFuaW1hdGlvbkVuZCcsICdvbkFuaW1hdGlvbkl0ZXJhdGlvbiddO1xuZXhwb3J0IHZhciB0cmFuc2l0aW9uRXZlbnRzID0gWydvblRyYW5zaXRpb25FbmQnXTtcbmV4cG9ydCB2YXIgb3RoZXJFdmVudHMgPSBbJ29uVG9nZ2xlJ107XG5leHBvcnQgdmFyIGFsbEV2ZW50cyA9IFtdLmNvbmNhdChjbGlwYm9hcmRFdmVudHMsIGNvbXBvc2l0aW9uRXZlbnRzLCBrZXlib2FyZEV2ZW50cywgZm9jdXNFdmVudHMsIGZvcm1FdmVudHMsIGdlbmVyaWNFdmVudHMsIG1vdXNlRXZlbnRzLCBwb2ludGVyRXZlbnRzLCBzZWxlY3Rpb25FdmVudHMsIHRvdWNoRXZlbnRzLCB1aUV2ZW50cywgd2hlZWxFdmVudHMsIG1lZGlhRXZlbnRzLCBpbWFnZUV2ZW50cywgYW5pbWF0aW9uRXZlbnRzLCB0cmFuc2l0aW9uRXZlbnRzLCBvdGhlckV2ZW50cyk7XG4vKipcbiAqIFJldHVybnMgYW4gb2JqZWN0IHdpdGggb24tZXZlbnQgY2FsbGJhY2sgcHJvcHMgY3VycmllZCB3aXRoIHByb3ZpZGVkIGFyZ3MuXG4gKiBAcGFyYW0ge09iamVjdH0gcHJvcHMgUHJvcHMgcGFzc2VkIHRvIGEgY29tcG9uZW50LlxuICogQHBhcmFtIHtGdW5jdGlvbj19IGdldEFyZ3MgQSBmdW5jdGlvbiB0aGF0IHJldHVybnMgYXJndW1lbnQocykgb24tZXZlbnQgY2FsbGJhY2tzXG4gKiAgIHNoYWxsIGJlIGN1cnJpZWQgd2l0aC5cbiAqL1xuXG52YXIgbWFrZUV2ZW50UHJvcHMgPSBmdW5jdGlvbiBtYWtlRXZlbnRQcm9wcyhwcm9wcywgZ2V0QXJncykge1xuICB2YXIgZXZlbnRQcm9wcyA9IHt9O1xuICBhbGxFdmVudHMuZm9yRWFjaChmdW5jdGlvbiAoZXZlbnROYW1lKSB7XG4gICAgaWYgKCEoZXZlbnROYW1lIGluIHByb3BzKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghZ2V0QXJncykge1xuICAgICAgZXZlbnRQcm9wc1tldmVudE5hbWVdID0gcHJvcHNbZXZlbnROYW1lXTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBldmVudFByb3BzW2V2ZW50TmFtZV0gPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgIHJldHVybiBwcm9wc1tldmVudE5hbWVdKGV2ZW50LCBnZXRBcmdzKGV2ZW50TmFtZSkpO1xuICAgIH07XG4gIH0pO1xuICByZXR1cm4gZXZlbnRQcm9wcztcbn07XG5cbmV4cG9ydCBkZWZhdWx0IG1ha2VFdmVudFByb3BzOyIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIG1ha2VDYW5jZWxsYWJsZVByb21pc2UocHJvbWlzZSkge1xuICB2YXIgaXNDYW5jZWxsZWQgPSBmYWxzZTtcbiAgdmFyIHdyYXBwZWRQcm9taXNlID0gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIHByb21pc2UudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gIWlzQ2FuY2VsbGVkICYmIHJlc29sdmUuYXBwbHkodm9pZCAwLCBhcmd1bWVudHMpO1xuICAgIH0pW1wiY2F0Y2hcIl0oZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICByZXR1cm4gIWlzQ2FuY2VsbGVkICYmIHJlamVjdChlcnJvcik7XG4gICAgfSk7XG4gIH0pO1xuICByZXR1cm4ge1xuICAgIHByb21pc2U6IHdyYXBwZWRQcm9taXNlLFxuICAgIGNhbmNlbDogZnVuY3Rpb24gY2FuY2VsKCkge1xuICAgICAgaXNDYW5jZWxsZWQgPSB0cnVlO1xuICAgIH1cbiAgfTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBtZXJnZUNsYXNzTmFtZXMoKSB7XG4gIHJldHVybiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpLnJlZHVjZShmdW5jdGlvbiAoY2xhc3NMaXN0LCBhcmcpIHtcbiAgICByZXR1cm4gY2xhc3NMaXN0LmNvbmNhdChhcmcpO1xuICB9LCBbXSkuZmlsdGVyKGZ1bmN0aW9uIChhcmcpIHtcbiAgICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ3N0cmluZyc7XG4gIH0pLmpvaW4oJyAnKTtcbn0iLCJ2YXIgaXNQcm9kdWN0aW9uID0gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdwcm9kdWN0aW9uJztcbnZhciBwcmVmaXggPSAnSW52YXJpYW50IGZhaWxlZCc7XG5mdW5jdGlvbiBpbnZhcmlhbnQoY29uZGl0aW9uLCBtZXNzYWdlKSB7XG4gICAgaWYgKGNvbmRpdGlvbikge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChpc1Byb2R1Y3Rpb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKHByZWZpeCk7XG4gICAgfVxuICAgIHZhciBwcm92aWRlZCA9IHR5cGVvZiBtZXNzYWdlID09PSAnZnVuY3Rpb24nID8gbWVzc2FnZSgpIDogbWVzc2FnZTtcbiAgICB2YXIgdmFsdWUgPSBwcm92aWRlZCA/IHByZWZpeCArIFwiOiBcIiArIHByb3ZpZGVkIDogcHJlZml4O1xuICAgIHRocm93IG5ldyBFcnJvcih2YWx1ZSk7XG59XG5cbmV4cG9ydCB7IGludmFyaWFudCBhcyBkZWZhdWx0IH07XG4iLCJ2YXIgaXNQcm9kdWN0aW9uID0gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdwcm9kdWN0aW9uJztcbmZ1bmN0aW9uIHdhcm5pbmcoY29uZGl0aW9uLCBtZXNzYWdlKSB7XG4gIGlmICghaXNQcm9kdWN0aW9uKSB7XG4gICAgaWYgKGNvbmRpdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciB0ZXh0ID0gXCJXYXJuaW5nOiBcIiArIG1lc3NhZ2U7XG5cbiAgICBpZiAodHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBjb25zb2xlLndhcm4odGV4dCk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHRocm93IEVycm9yKHRleHQpO1xuICAgIH0gY2F0Y2ggKHgpIHt9XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgd2FybmluZztcbiIsImltcG9ydCB7IGNyZWF0ZUNvbnRleHQgfSBmcm9tICdyZWFjdCc7XG5leHBvcnQgZGVmYXVsdCAvKiNfX1BVUkVfXyovY3JlYXRlQ29udGV4dChudWxsKTsiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIE1lc3NhZ2UoX3JlZikge1xuICB2YXIgY2hpbGRyZW4gPSBfcmVmLmNoaWxkcmVuLFxuICAgICAgdHlwZSA9IF9yZWYudHlwZTtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICBjbGFzc05hbWU6IFwicmVhY3QtcGRmX19tZXNzYWdlIHJlYWN0LXBkZl9fbWVzc2FnZS0tXCIuY29uY2F0KHR5cGUpXG4gIH0sIGNoaWxkcmVuKTtcbn1cbk1lc3NhZ2UucHJvcFR5cGVzID0ge1xuICBjaGlsZHJlbjogUHJvcFR5cGVzLm5vZGUsXG4gIHR5cGU6IFByb3BUeXBlcy5vbmVPZihbJ2Vycm9yJywgJ2xvYWRpbmcnLCAnbm8tZGF0YSddKS5pc1JlcXVpcmVkXG59OyIsImltcG9ydCBfY2xhc3NDYWxsQ2hlY2sgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NsYXNzQ2FsbENoZWNrXCI7XG5pbXBvcnQgX2NyZWF0ZUNsYXNzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jcmVhdGVDbGFzc1wiO1xuXG4vKiBDb3B5cmlnaHQgMjAxNSBNb3ppbGxhIEZvdW5kYXRpb25cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmltcG9ydCBpbnZhcmlhbnQgZnJvbSAndGlueS1pbnZhcmlhbnQnO1xudmFyIERFRkFVTFRfTElOS19SRUwgPSAnbm9vcGVuZXIgbm9yZWZlcnJlciBub2ZvbGxvdyc7XG5cbnZhciBMaW5rU2VydmljZSA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIExpbmtTZXJ2aWNlKCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBMaW5rU2VydmljZSk7XG5cbiAgICB0aGlzLmV4dGVybmFsTGlua1RhcmdldCA9IG51bGw7XG4gICAgdGhpcy5leHRlcm5hbExpbmtSZWwgPSBudWxsO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzKExpbmtTZXJ2aWNlLCBbe1xuICAgIGtleTogXCJzZXREb2N1bWVudFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBzZXREb2N1bWVudChwZGZEb2N1bWVudCkge1xuICAgICAgdGhpcy5wZGZEb2N1bWVudCA9IHBkZkRvY3VtZW50O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJzZXRWaWV3ZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2V0Vmlld2VyKHBkZlZpZXdlcikge1xuICAgICAgdGhpcy5wZGZWaWV3ZXIgPSBwZGZWaWV3ZXI7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInNldEV4dGVybmFsTGlua1JlbFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRFeHRlcm5hbExpbmtSZWwoZXh0ZXJuYWxMaW5rUmVsKSB7XG4gICAgICB0aGlzLmV4dGVybmFsTGlua1JlbCA9IGV4dGVybmFsTGlua1JlbDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwic2V0RXh0ZXJuYWxMaW5rVGFyZ2V0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHNldEV4dGVybmFsTGlua1RhcmdldChleHRlcm5hbExpbmtUYXJnZXQpIHtcbiAgICAgIHRoaXMuZXh0ZXJuYWxMaW5rVGFyZ2V0ID0gZXh0ZXJuYWxMaW5rVGFyZ2V0O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJzZXRIaXN0b3J5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHNldEhpc3RvcnkoKSB7fVxuICB9LCB7XG4gICAga2V5OiBcInBhZ2VzQ291bnRcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiB0aGlzLnBkZkRvY3VtZW50ID8gdGhpcy5wZGZEb2N1bWVudC5udW1QYWdlcyA6IDA7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInBhZ2VcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiB0aGlzLnBkZlZpZXdlci5jdXJyZW50UGFnZU51bWJlcjtcbiAgICB9LFxuICAgIHNldDogZnVuY3Rpb24gc2V0KHZhbHVlKSB7XG4gICAgICB0aGlzLnBkZlZpZXdlci5jdXJyZW50UGFnZU51bWJlciA9IHZhbHVlO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyb3RhdGlvblwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uIHNldCh2YWx1ZSkge31cbiAgfSwge1xuICAgIGtleTogXCJnb1RvRGVzdGluYXRpb25cIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ29Ub0Rlc3RpbmF0aW9uKGRlc3QpIHtcbiAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgICAgIGlmICh0eXBlb2YgZGVzdCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBfdGhpcy5wZGZEb2N1bWVudC5nZXREZXN0aW5hdGlvbihkZXN0KS50aGVuKHJlc29sdmUpO1xuICAgICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoZGVzdCkpIHtcbiAgICAgICAgICByZXNvbHZlKGRlc3QpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRlc3QudGhlbihyZXNvbHZlKTtcbiAgICAgICAgfVxuICAgICAgfSkudGhlbihmdW5jdGlvbiAoZXhwbGljaXREZXN0KSB7XG4gICAgICAgIGludmFyaWFudChBcnJheS5pc0FycmF5KGV4cGxpY2l0RGVzdCksIFwiXFxcIlwiLmNvbmNhdChleHBsaWNpdERlc3QsIFwiXFxcIiBpcyBub3QgYSB2YWxpZCBkZXN0aW5hdGlvbiBhcnJheS5cIikpO1xuICAgICAgICB2YXIgZGVzdFJlZiA9IGV4cGxpY2l0RGVzdFswXTtcbiAgICAgICAgbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgICBpZiAoZGVzdFJlZiBpbnN0YW5jZW9mIE9iamVjdCkge1xuICAgICAgICAgICAgX3RoaXMucGRmRG9jdW1lbnQuZ2V0UGFnZUluZGV4KGRlc3RSZWYpLnRoZW4oZnVuY3Rpb24gKHBhZ2VJbmRleCkge1xuICAgICAgICAgICAgICByZXNvbHZlKHBhZ2VJbmRleCk7XG4gICAgICAgICAgICB9KVtcImNhdGNoXCJdKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgaW52YXJpYW50KGZhbHNlLCBcIlxcXCJcIi5jb25jYXQoZGVzdFJlZiwgXCJcXFwiIGlzIG5vdCBhIHZhbGlkIHBhZ2UgcmVmZXJlbmNlLlwiKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkZXN0UmVmID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgcmVzb2x2ZShkZXN0UmVmKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaW52YXJpYW50KGZhbHNlLCBcIlxcXCJcIi5jb25jYXQoZGVzdFJlZiwgXCJcXFwiIGlzIG5vdCBhIHZhbGlkIGRlc3RpbmF0aW9uIHJlZmVyZW5jZS5cIikpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkudGhlbihmdW5jdGlvbiAocGFnZUluZGV4KSB7XG4gICAgICAgICAgdmFyIHBhZ2VOdW1iZXIgPSBwYWdlSW5kZXggKyAxO1xuICAgICAgICAgIGludmFyaWFudChwYWdlTnVtYmVyID49IDEgJiYgcGFnZU51bWJlciA8PSBfdGhpcy5wYWdlc0NvdW50LCBcIlxcXCJcIi5jb25jYXQocGFnZU51bWJlciwgXCJcXFwiIGlzIG5vdCBhIHZhbGlkIHBhZ2UgbnVtYmVyLlwiKSk7XG5cbiAgICAgICAgICBfdGhpcy5wZGZWaWV3ZXIuc2Nyb2xsUGFnZUludG9WaWV3KHtcbiAgICAgICAgICAgIGRlc3Q6IGRlc3QsXG4gICAgICAgICAgICBwYWdlSW5kZXg6IHBhZ2VJbmRleCxcbiAgICAgICAgICAgIHBhZ2VOdW1iZXI6IHBhZ2VOdW1iZXJcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwibmF2aWdhdGVUb1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBuYXZpZ2F0ZVRvKGRlc3QpIHtcbiAgICAgIHRoaXMuZ29Ub0Rlc3RpbmF0aW9uKGRlc3QpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnb1RvUGFnZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnb1RvUGFnZSgpIHt9XG4gIH0sIHtcbiAgICBrZXk6IFwiYWRkTGlua0F0dHJpYnV0ZXNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gYWRkTGlua0F0dHJpYnV0ZXMobGluaywgdXJsLCBuZXdXaW5kb3cpIHtcbiAgICAgIGxpbmsuaHJlZiA9IHVybDtcbiAgICAgIGxpbmsucmVsID0gdGhpcy5leHRlcm5hbExpbmtSZWwgfHwgREVGQVVMVF9MSU5LX1JFTDtcbiAgICAgIGxpbmsudGFyZ2V0ID0gbmV3V2luZG93ID8gJ19ibGFuaycgOiB0aGlzLmV4dGVybmFsTGlua1RhcmdldCB8fCAnJztcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0RGVzdGluYXRpb25IYXNoXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldERlc3RpbmF0aW9uSGFzaCgpIHtcbiAgICAgIHJldHVybiAnIyc7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldEFuY2hvclVybFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRBbmNob3JVcmwoKSB7XG4gICAgICByZXR1cm4gJyMnO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJzZXRIYXNoXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHNldEhhc2goKSB7fVxuICB9LCB7XG4gICAga2V5OiBcImV4ZWN1dGVOYW1lZEFjdGlvblwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBleGVjdXRlTmFtZWRBY3Rpb24oKSB7fVxuICB9LCB7XG4gICAga2V5OiBcImNhY2hlUGFnZVJlZlwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjYWNoZVBhZ2VSZWYoKSB7fVxuICB9LCB7XG4gICAga2V5OiBcImlzUGFnZVZpc2libGVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gaXNQYWdlVmlzaWJsZSgpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJpc1BhZ2VDYWNoZWRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gaXNQYWdlQ2FjaGVkKCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIExpbmtTZXJ2aWNlO1xufSgpO1xuXG5leHBvcnQgeyBMaW5rU2VydmljZSBhcyBkZWZhdWx0IH07IiwiLy8gQXMgZGVmaW5lZCBpbiBodHRwczovL2dpdGh1Yi5jb20vbW96aWxsYS9wZGYuanMvYmxvYi9kOWZhYzM0NTk2MDlhODA3YmU2NTA2ZmIzNDQxYjVkYTRiMTU0ZDE0L3NyYy9zaGFyZWQvdXRpbC5qcyNMMzcxLUwzNzRcbnZhciBQYXNzd29yZFJlc3BvbnNlcyA9IHtcbiAgTkVFRF9QQVNTV09SRDogMSxcbiAgSU5DT1JSRUNUX1BBU1NXT1JEOiAyXG59O1xuZXhwb3J0IGRlZmF1bHQgUGFzc3dvcmRSZXNwb25zZXM7IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2FycmF5V2l0aEhvbGVzKGFycikge1xuICBpZiAoQXJyYXkuaXNBcnJheShhcnIpKSByZXR1cm4gYXJyO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9pdGVyYWJsZVRvQXJyYXlMaW1pdChhcnIsIGkpIHtcbiAgdmFyIF9pID0gYXJyID09IG51bGwgPyBudWxsIDogdHlwZW9mIFN5bWJvbCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBhcnJbU3ltYm9sLml0ZXJhdG9yXSB8fCBhcnJbXCJAQGl0ZXJhdG9yXCJdO1xuXG4gIGlmIChfaSA9PSBudWxsKSByZXR1cm47XG4gIHZhciBfYXJyID0gW107XG4gIHZhciBfbiA9IHRydWU7XG4gIHZhciBfZCA9IGZhbHNlO1xuXG4gIHZhciBfcywgX2U7XG5cbiAgdHJ5IHtcbiAgICBmb3IgKF9pID0gX2kuY2FsbChhcnIpOyAhKF9uID0gKF9zID0gX2kubmV4dCgpKS5kb25lKTsgX24gPSB0cnVlKSB7XG4gICAgICBfYXJyLnB1c2goX3MudmFsdWUpO1xuXG4gICAgICBpZiAoaSAmJiBfYXJyLmxlbmd0aCA9PT0gaSkgYnJlYWs7XG4gICAgfVxuICB9IGNhdGNoIChlcnIpIHtcbiAgICBfZCA9IHRydWU7XG4gICAgX2UgPSBlcnI7XG4gIH0gZmluYWxseSB7XG4gICAgdHJ5IHtcbiAgICAgIGlmICghX24gJiYgX2lbXCJyZXR1cm5cIl0gIT0gbnVsbCkgX2lbXCJyZXR1cm5cIl0oKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgaWYgKF9kKSB0aHJvdyBfZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gX2Fycjtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfYXJyYXlMaWtlVG9BcnJheShhcnIsIGxlbikge1xuICBpZiAobGVuID09IG51bGwgfHwgbGVuID4gYXJyLmxlbmd0aCkgbGVuID0gYXJyLmxlbmd0aDtcblxuICBmb3IgKHZhciBpID0gMCwgYXJyMiA9IG5ldyBBcnJheShsZW4pOyBpIDwgbGVuOyBpKyspIHtcbiAgICBhcnIyW2ldID0gYXJyW2ldO1xuICB9XG5cbiAgcmV0dXJuIGFycjI7XG59IiwiaW1wb3J0IGFycmF5TGlrZVRvQXJyYXkgZnJvbSBcIi4vYXJyYXlMaWtlVG9BcnJheS5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KG8sIG1pbkxlbikge1xuICBpZiAoIW8pIHJldHVybjtcbiAgaWYgKHR5cGVvZiBvID09PSBcInN0cmluZ1wiKSByZXR1cm4gYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pO1xuICB2YXIgbiA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKS5zbGljZSg4LCAtMSk7XG4gIGlmIChuID09PSBcIk9iamVjdFwiICYmIG8uY29uc3RydWN0b3IpIG4gPSBvLmNvbnN0cnVjdG9yLm5hbWU7XG4gIGlmIChuID09PSBcIk1hcFwiIHx8IG4gPT09IFwiU2V0XCIpIHJldHVybiBBcnJheS5mcm9tKG8pO1xuICBpZiAobiA9PT0gXCJBcmd1bWVudHNcIiB8fCAvXig/OlVpfEkpbnQoPzo4fDE2fDMyKSg/OkNsYW1wZWQpP0FycmF5JC8udGVzdChuKSkgcmV0dXJuIGFycmF5TGlrZVRvQXJyYXkobywgbWluTGVuKTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfbm9uSXRlcmFibGVSZXN0KCkge1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBhdHRlbXB0IHRvIGRlc3RydWN0dXJlIG5vbi1pdGVyYWJsZSBpbnN0YW5jZS5cXG5JbiBvcmRlciB0byBiZSBpdGVyYWJsZSwgbm9uLWFycmF5IG9iamVjdHMgbXVzdCBoYXZlIGEgW1N5bWJvbC5pdGVyYXRvcl0oKSBtZXRob2QuXCIpO1xufSIsImltcG9ydCBhcnJheVdpdGhIb2xlcyBmcm9tIFwiLi9hcnJheVdpdGhIb2xlcy5qc1wiO1xuaW1wb3J0IGl0ZXJhYmxlVG9BcnJheUxpbWl0IGZyb20gXCIuL2l0ZXJhYmxlVG9BcnJheUxpbWl0LmpzXCI7XG5pbXBvcnQgdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkgZnJvbSBcIi4vdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkuanNcIjtcbmltcG9ydCBub25JdGVyYWJsZVJlc3QgZnJvbSBcIi4vbm9uSXRlcmFibGVSZXN0LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfc2xpY2VkVG9BcnJheShhcnIsIGkpIHtcbiAgcmV0dXJuIGFycmF5V2l0aEhvbGVzKGFycikgfHwgaXRlcmFibGVUb0FycmF5TGltaXQoYXJyLCBpKSB8fCB1bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShhcnIsIGkpIHx8IG5vbkl0ZXJhYmxlUmVzdCgpO1xufSIsImltcG9ydCBfc2xpY2VkVG9BcnJheSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vc2xpY2VkVG9BcnJheVwiO1xuaW1wb3J0IGludmFyaWFudCBmcm9tICd0aW55LWludmFyaWFudCc7XG5pbXBvcnQgd2FybmluZyBmcm9tICd0aW55LXdhcm5pbmcnO1xuLyoqXG4gKiBDaGVja3MgaWYgd2UncmUgcnVubmluZyBpbiBhIGJyb3dzZXIgZW52aXJvbm1lbnQuXG4gKi9cblxuZXhwb3J0IHZhciBpc0Jyb3dzZXIgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJztcbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgd2UncmUgcnVubmluZyBmcm9tIGEgbG9jYWwgZmlsZSBzeXN0ZW0uXG4gKi9cblxuZXhwb3J0IHZhciBpc0xvY2FsRmlsZVN5c3RlbSA9IGlzQnJvd3NlciAmJiB3aW5kb3cubG9jYXRpb24ucHJvdG9jb2wgPT09ICdmaWxlOic7XG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgdmFyaWFibGUgaXMgZGVmaW5lZC5cbiAqXG4gKiBAcGFyYW0geyp9IHZhcmlhYmxlIFZhcmlhYmxlIHRvIGNoZWNrXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRGVmaW5lZCh2YXJpYWJsZSkge1xuICByZXR1cm4gdHlwZW9mIHZhcmlhYmxlICE9PSAndW5kZWZpbmVkJztcbn1cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSB2YXJpYWJsZSBpcyBkZWZpbmVkIGFuZCBub3QgbnVsbC5cbiAqXG4gKiBAcGFyYW0geyp9IHZhcmlhYmxlIFZhcmlhYmxlIHRvIGNoZWNrXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGlzUHJvdmlkZWQodmFyaWFibGUpIHtcbiAgcmV0dXJuIGlzRGVmaW5lZCh2YXJpYWJsZSkgJiYgdmFyaWFibGUgIT09IG51bGw7XG59XG4vKipcbiAqIENoZWNrZXMgd2hldGhlciBhIHZhcmlhYmxlIHByb3ZpZGVkIGlzIGEgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB7Kn0gdmFyaWFibGUgVmFyaWFibGUgdG8gY2hlY2tcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaXNTdHJpbmcodmFyaWFibGUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YXJpYWJsZSA9PT0gJ3N0cmluZyc7XG59XG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgdmFyaWFibGUgcHJvdmlkZWQgaXMgYW4gQXJyYXlCdWZmZXIuXG4gKlxuICogQHBhcmFtIHsqfSB2YXJpYWJsZSBWYXJpYWJsZSB0byBjaGVja1xuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBpc0FycmF5QnVmZmVyKHZhcmlhYmxlKSB7XG4gIHJldHVybiB2YXJpYWJsZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyO1xufVxuLyoqXG4gKiBDaGVja2VzIHdoZXRoZXIgYSB2YXJpYWJsZSBwcm92aWRlZCBpcyBhIEJsb2IuXG4gKlxuICogQHBhcmFtIHsqfSB2YXJpYWJsZSBWYXJpYWJsZSB0byBjaGVja1xuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBpc0Jsb2IodmFyaWFibGUpIHtcbiAgaW52YXJpYW50KGlzQnJvd3NlciwgJ2lzQmxvYiBjYW4gb25seSBiZSB1c2VkIGluIGEgYnJvd3NlciBlbnZpcm9ubWVudCcpO1xuICByZXR1cm4gdmFyaWFibGUgaW5zdGFuY2VvZiBCbG9iO1xufVxuLyoqXG4gKiBDaGVja2VzIHdoZXRoZXIgYSB2YXJpYWJsZSBwcm92aWRlZCBpcyBhIEZpbGUuXG4gKlxuICogQHBhcmFtIHsqfSB2YXJpYWJsZSBWYXJpYWJsZSB0byBjaGVja1xuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBpc0ZpbGUodmFyaWFibGUpIHtcbiAgaW52YXJpYW50KGlzQnJvd3NlciwgJ2lzRmlsZSBjYW4gb25seSBiZSB1c2VkIGluIGEgYnJvd3NlciBlbnZpcm9ubWVudCcpO1xuICByZXR1cm4gdmFyaWFibGUgaW5zdGFuY2VvZiBGaWxlO1xufVxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIHN0cmluZyBwcm92aWRlZCBpcyBhIGRhdGEgVVJJLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIGNoZWNrXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRGF0YVVSSShzdHIpIHtcbiAgcmV0dXJuIGlzU3RyaW5nKHN0cikgJiYgL15kYXRhOi8udGVzdChzdHIpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGRhdGFVUkl0b0J5dGVTdHJpbmcoZGF0YVVSSSkge1xuICBpbnZhcmlhbnQoaXNEYXRhVVJJKGRhdGFVUkkpLCAnSW52YWxpZCBkYXRhIFVSSS4nKTtcblxuICB2YXIgX2RhdGFVUkkkc3BsaXQgPSBkYXRhVVJJLnNwbGl0KCcsJyksXG4gICAgICBfZGF0YVVSSSRzcGxpdDIgPSBfc2xpY2VkVG9BcnJheShfZGF0YVVSSSRzcGxpdCwgMiksXG4gICAgICBoZWFkZXJzU3RyaW5nID0gX2RhdGFVUkkkc3BsaXQyWzBdLFxuICAgICAgZGF0YVN0cmluZyA9IF9kYXRhVVJJJHNwbGl0MlsxXTtcblxuICB2YXIgaGVhZGVycyA9IGhlYWRlcnNTdHJpbmcuc3BsaXQoJzsnKTtcblxuICBpZiAoaGVhZGVycy5pbmRleE9mKCdiYXNlNjQnKSAhPT0gLTEpIHtcbiAgICByZXR1cm4gYXRvYihkYXRhU3RyaW5nKTtcbiAgfVxuXG4gIHJldHVybiB1bmVzY2FwZShkYXRhU3RyaW5nKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnZXRQaXhlbFJhdGlvKCkge1xuICByZXR1cm4gaXNCcm93c2VyICYmIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvIHx8IDE7XG59XG52YXIgYWxsb3dGaWxlQWNjZXNzRnJvbUZpbGVzVGlwID0gJ09uIENocm9taXVtIGJhc2VkIGJyb3dzZXJzLCB5b3UgY2FuIHVzZSAtLWFsbG93LWZpbGUtYWNjZXNzLWZyb20tZmlsZXMgZmxhZyBmb3IgZGVidWdnaW5nIHB1cnBvc2VzLic7XG5leHBvcnQgZnVuY3Rpb24gZGlzcGxheUNPUlNXYXJuaW5nKCkge1xuICB3YXJuaW5nKCFpc0xvY2FsRmlsZVN5c3RlbSwgXCJMb2FkaW5nIFBERiBhcyBiYXNlNjQgc3RyaW5ncy9VUkxzIG1heSBub3Qgd29yayBvbiBwcm90b2NvbHMgb3RoZXIgdGhhbiBIVFRQL0hUVFBTLiBcIi5jb25jYXQoYWxsb3dGaWxlQWNjZXNzRnJvbUZpbGVzVGlwKSk7XG59XG5leHBvcnQgZnVuY3Rpb24gZGlzcGxheVdvcmtlcldhcm5pbmcoKSB7XG4gIHdhcm5pbmcoIWlzTG9jYWxGaWxlU3lzdGVtLCBcIkxvYWRpbmcgUERGLmpzIHdvcmtlciBtYXkgbm90IHdvcmsgb24gcHJvdG9jb2xzIG90aGVyIHRoYW4gSFRUUC9IVFRQUy4gXCIuY29uY2F0KGFsbG93RmlsZUFjY2Vzc0Zyb21GaWxlc1RpcCkpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGNhbmNlbFJ1bm5pbmdUYXNrKHJ1bm5pbmdUYXNrKSB7XG4gIGlmIChydW5uaW5nVGFzayAmJiBydW5uaW5nVGFzay5jYW5jZWwpIHJ1bm5pbmdUYXNrLmNhbmNlbCgpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIG1ha2VQYWdlQ2FsbGJhY2socGFnZSwgc2NhbGUpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHBhZ2UsICd3aWR0aCcsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiB0aGlzLnZpZXdbMl0gKiBzY2FsZTtcbiAgICB9LFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICB9KTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHBhZ2UsICdoZWlnaHQnLCB7XG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICByZXR1cm4gdGhpcy52aWV3WzNdICogc2NhbGU7XG4gICAgfSxcbiAgICBjb25maWd1cmFibGU6IHRydWVcbiAgfSk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwYWdlLCAnb3JpZ2luYWxXaWR0aCcsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiB0aGlzLnZpZXdbMl07XG4gICAgfSxcbiAgICBjb25maWd1cmFibGU6IHRydWVcbiAgfSk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwYWdlLCAnb3JpZ2luYWxIZWlnaHQnLCB7XG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICByZXR1cm4gdGhpcy52aWV3WzNdO1xuICAgIH0sXG4gICAgY29uZmlndXJhYmxlOiB0cnVlXG4gIH0pO1xuICByZXR1cm4gcGFnZTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBpc0NhbmNlbEV4Y2VwdGlvbihlcnJvcikge1xuICByZXR1cm4gZXJyb3IubmFtZSA9PT0gJ1JlbmRlcmluZ0NhbmNlbGxlZEV4Y2VwdGlvbic7XG59XG5leHBvcnQgZnVuY3Rpb24gbG9hZEZyb21GaWxlKGZpbGUpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcblxuICAgIHJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZShuZXcgVWludDhBcnJheShyZWFkZXIucmVzdWx0KSk7XG4gICAgfTtcblxuICAgIHJlYWRlci5vbmVycm9yID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICBzd2l0Y2ggKGV2ZW50LnRhcmdldC5lcnJvci5jb2RlKSB7XG4gICAgICAgIGNhc2UgZXZlbnQudGFyZ2V0LmVycm9yLk5PVF9GT1VORF9FUlI6XG4gICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoJ0Vycm9yIHdoaWxlIHJlYWRpbmcgYSBmaWxlOiBGaWxlIG5vdCBmb3VuZC4nKSk7XG5cbiAgICAgICAgY2FzZSBldmVudC50YXJnZXQuZXJyb3IuTk9UX1JFQURBQkxFX0VSUjpcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcignRXJyb3Igd2hpbGUgcmVhZGluZyBhIGZpbGU6IEZpbGUgbm90IHJlYWRhYmxlLicpKTtcblxuICAgICAgICBjYXNlIGV2ZW50LnRhcmdldC5lcnJvci5TRUNVUklUWV9FUlI6XG4gICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoJ0Vycm9yIHdoaWxlIHJlYWRpbmcgYSBmaWxlOiBTZWN1cml0eSBlcnJvci4nKSk7XG5cbiAgICAgICAgY2FzZSBldmVudC50YXJnZXQuZXJyb3IuQUJPUlRfRVJSOlxuICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCdFcnJvciB3aGlsZSByZWFkaW5nIGEgZmlsZTogQWJvcnRlZC4nKSk7XG5cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcignRXJyb3Igd2hpbGUgcmVhZGluZyBhIGZpbGUuJykpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoZmlsZSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH0pO1xufSIsImltcG9ydCBhcnJheUxpa2VUb0FycmF5IGZyb20gXCIuL2FycmF5TGlrZVRvQXJyYXkuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9hcnJheVdpdGhvdXRIb2xlcyhhcnIpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkgcmV0dXJuIGFycmF5TGlrZVRvQXJyYXkoYXJyKTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfaXRlcmFibGVUb0FycmF5KGl0ZXIpIHtcbiAgaWYgKHR5cGVvZiBTeW1ib2wgIT09IFwidW5kZWZpbmVkXCIgJiYgaXRlcltTeW1ib2wuaXRlcmF0b3JdICE9IG51bGwgfHwgaXRlcltcIkBAaXRlcmF0b3JcIl0gIT0gbnVsbCkgcmV0dXJuIEFycmF5LmZyb20oaXRlcik7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX25vbkl0ZXJhYmxlU3ByZWFkKCkge1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBhdHRlbXB0IHRvIHNwcmVhZCBub24taXRlcmFibGUgaW5zdGFuY2UuXFxuSW4gb3JkZXIgdG8gYmUgaXRlcmFibGUsIG5vbi1hcnJheSBvYmplY3RzIG11c3QgaGF2ZSBhIFtTeW1ib2wuaXRlcmF0b3JdKCkgbWV0aG9kLlwiKTtcbn0iLCJpbXBvcnQgYXJyYXlXaXRob3V0SG9sZXMgZnJvbSBcIi4vYXJyYXlXaXRob3V0SG9sZXMuanNcIjtcbmltcG9ydCBpdGVyYWJsZVRvQXJyYXkgZnJvbSBcIi4vaXRlcmFibGVUb0FycmF5LmpzXCI7XG5pbXBvcnQgdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkgZnJvbSBcIi4vdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkuanNcIjtcbmltcG9ydCBub25JdGVyYWJsZVNwcmVhZCBmcm9tIFwiLi9ub25JdGVyYWJsZVNwcmVhZC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX3RvQ29uc3VtYWJsZUFycmF5KGFycikge1xuICByZXR1cm4gYXJyYXlXaXRob3V0SG9sZXMoYXJyKSB8fCBpdGVyYWJsZVRvQXJyYXkoYXJyKSB8fCB1bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShhcnIpIHx8IG5vbkl0ZXJhYmxlU3ByZWFkKCk7XG59IiwiaW1wb3J0IF90eXBlb2YgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3R5cGVvZlwiO1xuaW1wb3J0IF90b0NvbnN1bWFibGVBcnJheSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vdG9Db25zdW1hYmxlQXJyYXlcIjtcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgeyBtb3VzZUV2ZW50cywgdG91Y2hFdmVudHMsIGtleWJvYXJkRXZlbnRzIH0gZnJvbSAnbWFrZS1ldmVudC1wcm9wcyc7XG5pbXBvcnQgeyBpc0RlZmluZWQgfSBmcm9tICcuL3V0aWxzJztcbmltcG9ydCBMaW5rU2VydmljZSBmcm9tICcuLi9MaW5rU2VydmljZSc7XG5leHBvcnQgdmFyIGV2ZW50UHJvcHMgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciByZXN1bHQgPSB7fTtcbiAgW10uY29uY2F0KF90b0NvbnN1bWFibGVBcnJheShtb3VzZUV2ZW50cyksIF90b0NvbnN1bWFibGVBcnJheSh0b3VjaEV2ZW50cyksIF90b0NvbnN1bWFibGVBcnJheShrZXlib2FyZEV2ZW50cykpLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50TmFtZSkge1xuICAgIHJlc3VsdFtldmVudE5hbWVdID0gUHJvcFR5cGVzLmZ1bmM7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufSgpO1xudmFyIGZpbGVUeXBlcyA9IFtQcm9wVHlwZXMuc3RyaW5nLCBQcm9wVHlwZXMuaW5zdGFuY2VPZihBcnJheUJ1ZmZlciksIFByb3BUeXBlcy5zaGFwZSh7XG4gIGRhdGE6IFByb3BUeXBlcy5vbmVPZlR5cGUoW1Byb3BUeXBlcy5vYmplY3QsIFByb3BUeXBlcy5zdHJpbmddKSxcbiAgaHR0cEhlYWRlcnM6IFByb3BUeXBlcy5vYmplY3QsXG4gIHJhbmdlOiBQcm9wVHlwZXMub2JqZWN0LFxuICB1cmw6IFByb3BUeXBlcy5zdHJpbmcsXG4gIHdpdGhDcmVkZW50aWFsczogUHJvcFR5cGVzLmJvb2xcbn0pXTtcblxuaWYgKHR5cGVvZiBGaWxlICE9PSAndW5kZWZpbmVkJykge1xuICBmaWxlVHlwZXMucHVzaChQcm9wVHlwZXMuaW5zdGFuY2VPZihGaWxlKSk7XG59XG5cbmlmICh0eXBlb2YgQmxvYiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgZmlsZVR5cGVzLnB1c2goUHJvcFR5cGVzLmluc3RhbmNlT2YoQmxvYikpO1xufVxuXG5leHBvcnQgdmFyIGlzQ2xhc3NOYW1lID0gUHJvcFR5cGVzLm9uZU9mVHlwZShbUHJvcFR5cGVzLnN0cmluZywgUHJvcFR5cGVzLmFycmF5T2YoUHJvcFR5cGVzLnN0cmluZyldKTtcbmV4cG9ydCB2YXIgaXNGaWxlID0gUHJvcFR5cGVzLm9uZU9mVHlwZShmaWxlVHlwZXMpO1xuZXhwb3J0IHZhciBpc0xpbmtTZXJ2aWNlID0gUHJvcFR5cGVzLmluc3RhbmNlT2YoTGlua1NlcnZpY2UpO1xuZXhwb3J0IHZhciBpc0xpbmtUYXJnZXQgPSBQcm9wVHlwZXMub25lT2YoWydfc2VsZicsICdfYmxhbmsnLCAnX3BhcmVudCcsICdfdG9wJ10pO1xuZXhwb3J0IHZhciBpc1BhZ2UgPSBQcm9wVHlwZXMuc2hhcGUoe1xuICBjb21tb25PYmpzOiBQcm9wVHlwZXMuc2hhcGUoe30pLmlzUmVxdWlyZWQsXG4gIGdldEFubm90YXRpb25zOiBQcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICBnZXRUZXh0Q29udGVudDogUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgZ2V0Vmlld3BvcnQ6IFByb3BUeXBlcy5mdW5jLmlzUmVxdWlyZWQsXG4gIHJlbmRlcjogUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZFxufSk7XG5leHBvcnQgdmFyIGlzUGFnZUluZGV4ID0gZnVuY3Rpb24gaXNQYWdlSW5kZXgocHJvcHMsIHByb3BOYW1lLCBjb21wb25lbnROYW1lKSB7XG4gIHZhciBwYWdlSW5kZXggPSBwcm9wc1twcm9wTmFtZV0sXG4gICAgICBwYWdlTnVtYmVyID0gcHJvcHMucGFnZU51bWJlcixcbiAgICAgIHBkZiA9IHByb3BzLnBkZjtcblxuICBpZiAoIWlzRGVmaW5lZChwZGYpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoaXNEZWZpbmVkKHBhZ2VJbmRleCkpIHtcbiAgICBpZiAodHlwZW9mIHBhZ2VJbmRleCAhPT0gJ251bWJlcicpIHtcbiAgICAgIHJldHVybiBuZXcgRXJyb3IoXCJgXCIuY29uY2F0KHByb3BOYW1lLCBcImAgb2YgdHlwZSBgXCIpLmNvbmNhdChfdHlwZW9mKHBhZ2VJbmRleCksIFwiYCBzdXBwbGllZCB0byBgXCIpLmNvbmNhdChjb21wb25lbnROYW1lLCBcImAsIGV4cGVjdGVkIGBudW1iZXJgLlwiKSk7XG4gICAgfVxuXG4gICAgaWYgKHBhZ2VJbmRleCA8IDApIHtcbiAgICAgIHJldHVybiBuZXcgRXJyb3IoXCJFeHBlY3RlZCBgXCIuY29uY2F0KHByb3BOYW1lLCBcImAgdG8gYmUgZ3JlYXRlciBvciBlcXVhbCB0byAwLlwiKSk7XG4gICAgfVxuXG4gICAgdmFyIG51bVBhZ2VzID0gcGRmLm51bVBhZ2VzO1xuXG4gICAgaWYgKHBhZ2VJbmRleCArIDEgPiBudW1QYWdlcykge1xuICAgICAgcmV0dXJuIG5ldyBFcnJvcihcIkV4cGVjdGVkIGBcIi5jb25jYXQocHJvcE5hbWUsIFwiYCB0byBiZSBsZXNzIG9yIGVxdWFsIHRvIFwiKS5jb25jYXQobnVtUGFnZXMgLSAxLCBcIi5cIikpO1xuICAgIH1cbiAgfSBlbHNlIGlmICghaXNEZWZpbmVkKHBhZ2VOdW1iZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBFcnJvcihcImBcIi5jb25jYXQocHJvcE5hbWUsIFwiYCBub3Qgc3VwcGxpZWQuIEVpdGhlciBwYWdlSW5kZXggb3IgcGFnZU51bWJlciBtdXN0IGJlIHN1cHBsaWVkIHRvIGBcIikuY29uY2F0KGNvbXBvbmVudE5hbWUsIFwiYC5cIikpO1xuICB9IC8vIEV2ZXJ5dGhpbmcgaXMgZmluZVxuXG5cbiAgcmV0dXJuIG51bGw7XG59O1xuZXhwb3J0IHZhciBpc1BhZ2VOdW1iZXIgPSBmdW5jdGlvbiBpc1BhZ2VOdW1iZXIocHJvcHMsIHByb3BOYW1lLCBjb21wb25lbnROYW1lKSB7XG4gIHZhciBwYWdlTnVtYmVyID0gcHJvcHNbcHJvcE5hbWVdLFxuICAgICAgcGFnZUluZGV4ID0gcHJvcHMucGFnZUluZGV4LFxuICAgICAgcGRmID0gcHJvcHMucGRmO1xuXG4gIGlmICghaXNEZWZpbmVkKHBkZikpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmIChpc0RlZmluZWQocGFnZU51bWJlcikpIHtcbiAgICBpZiAodHlwZW9mIHBhZ2VOdW1iZXIgIT09ICdudW1iZXInKSB7XG4gICAgICByZXR1cm4gbmV3IEVycm9yKFwiYFwiLmNvbmNhdChwcm9wTmFtZSwgXCJgIG9mIHR5cGUgYFwiKS5jb25jYXQoX3R5cGVvZihwYWdlTnVtYmVyKSwgXCJgIHN1cHBsaWVkIHRvIGBcIikuY29uY2F0KGNvbXBvbmVudE5hbWUsIFwiYCwgZXhwZWN0ZWQgYG51bWJlcmAuXCIpKTtcbiAgICB9XG5cbiAgICBpZiAocGFnZU51bWJlciA8IDEpIHtcbiAgICAgIHJldHVybiBuZXcgRXJyb3IoXCJFeHBlY3RlZCBgXCIuY29uY2F0KHByb3BOYW1lLCBcImAgdG8gYmUgZ3JlYXRlciBvciBlcXVhbCB0byAxLlwiKSk7XG4gICAgfVxuXG4gICAgdmFyIG51bVBhZ2VzID0gcGRmLm51bVBhZ2VzO1xuXG4gICAgaWYgKHBhZ2VOdW1iZXIgPiBudW1QYWdlcykge1xuICAgICAgcmV0dXJuIG5ldyBFcnJvcihcIkV4cGVjdGVkIGBcIi5jb25jYXQocHJvcE5hbWUsIFwiYCB0byBiZSBsZXNzIG9yIGVxdWFsIHRvIFwiKS5jb25jYXQobnVtUGFnZXMsIFwiLlwiKSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKCFpc0RlZmluZWQocGFnZUluZGV4KSkge1xuICAgIHJldHVybiBuZXcgRXJyb3IoXCJgXCIuY29uY2F0KHByb3BOYW1lLCBcImAgbm90IHN1cHBsaWVkLiBFaXRoZXIgcGFnZUluZGV4IG9yIHBhZ2VOdW1iZXIgbXVzdCBiZSBzdXBwbGllZCB0byBgXCIpLmNvbmNhdChjb21wb25lbnROYW1lLCBcImAuXCIpKTtcbiAgfSAvLyBFdmVyeXRoaW5nIGlzIGZpbmVcblxuXG4gIHJldHVybiBudWxsO1xufTtcbmV4cG9ydCB2YXIgaXNQZGYgPSBQcm9wVHlwZXMub25lT2ZUeXBlKFtQcm9wVHlwZXMuc2hhcGUoe1xuICBnZXREZXN0aW5hdGlvbjogUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgZ2V0T3V0bGluZTogUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgZ2V0UGFnZTogUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgbnVtUGFnZXM6IFByb3BUeXBlcy5udW1iZXIuaXNSZXF1aXJlZFxufSksIFByb3BUeXBlcy5ib29sXSk7XG5leHBvcnQgdmFyIGlzUmVmID0gUHJvcFR5cGVzLm9uZU9mVHlwZShbUHJvcFR5cGVzLmZ1bmMsIFByb3BUeXBlcy5zaGFwZSh7XG4gIGN1cnJlbnQ6IFByb3BUeXBlcy5hbnlcbn0pXSk7XG5leHBvcnQgdmFyIGlzUmVuZGVyTW9kZSA9IFByb3BUeXBlcy5vbmVPZihbJ2NhbnZhcycsICdub25lJywgJ3N2ZyddKTtcbmV4cG9ydCB2YXIgaXNSb3RhdGUgPSBQcm9wVHlwZXMub25lT2YoWzAsIDkwLCAxODAsIDI3MF0pOyIsImltcG9ydCBfZXh0ZW5kcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZXh0ZW5kc1wiO1xuaW1wb3J0IF9vYmplY3RXaXRob3V0UHJvcGVydGllcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0V2l0aG91dFByb3BlcnRpZXNcIjtcbmltcG9ydCBfdHlwZW9mIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS90eXBlb2ZcIjtcbmltcG9ydCBfY2xhc3NDYWxsQ2hlY2sgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NsYXNzQ2FsbENoZWNrXCI7XG5pbXBvcnQgX2NyZWF0ZUNsYXNzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jcmVhdGVDbGFzc1wiO1xuaW1wb3J0IF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2Fzc2VydFRoaXNJbml0aWFsaXplZFwiO1xuaW1wb3J0IF9pbmhlcml0cyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vaW5oZXJpdHNcIjtcbmltcG9ydCBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybiBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vcG9zc2libGVDb25zdHJ1Y3RvclJldHVyblwiO1xuaW1wb3J0IF9nZXRQcm90b3R5cGVPZiBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZ2V0UHJvdG90eXBlT2ZcIjtcbmltcG9ydCBfZGVmaW5lUHJvcGVydHkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2RlZmluZVByb3BlcnR5XCI7XG52YXIgX2V4Y2x1ZGVkID0gW1widXJsXCJdO1xuXG5mdW5jdGlvbiBvd25LZXlzKG9iamVjdCwgZW51bWVyYWJsZU9ubHkpIHsgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmplY3QpOyBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykgeyB2YXIgc3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMob2JqZWN0KTsgZW51bWVyYWJsZU9ubHkgJiYgKHN5bWJvbHMgPSBzeW1ib2xzLmZpbHRlcihmdW5jdGlvbiAoc3ltKSB7IHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgc3ltKS5lbnVtZXJhYmxlOyB9KSksIGtleXMucHVzaC5hcHBseShrZXlzLCBzeW1ib2xzKTsgfSByZXR1cm4ga2V5czsgfVxuXG5mdW5jdGlvbiBfb2JqZWN0U3ByZWFkKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gbnVsbCAhPSBhcmd1bWVudHNbaV0gPyBhcmd1bWVudHNbaV0gOiB7fTsgaSAlIDIgPyBvd25LZXlzKE9iamVjdChzb3VyY2UpLCAhMCkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7IF9kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgc291cmNlW2tleV0pOyB9KSA6IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzID8gT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhzb3VyY2UpKSA6IG93bktleXMoT2JqZWN0KHNvdXJjZSkpLmZvckVhY2goZnVuY3Rpb24gKGtleSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Ioc291cmNlLCBrZXkpKTsgfSk7IH0gcmV0dXJuIHRhcmdldDsgfVxuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2YoRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZih0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxuLyoqXG4gKiBMb2FkcyBhIFBERiBkb2N1bWVudC4gUGFzc2VzIGl0IHRvIGFsbCBjaGlsZHJlbi5cbiAqL1xuaW1wb3J0IFJlYWN0LCB7IFB1cmVDb21wb25lbnQgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuaW1wb3J0IG1ha2VFdmVudFByb3BzIGZyb20gJ21ha2UtZXZlbnQtcHJvcHMnO1xuaW1wb3J0IG1ha2VDYW5jZWxsYWJsZSBmcm9tICdtYWtlLWNhbmNlbGxhYmxlLXByb21pc2UnO1xuaW1wb3J0IG1lcmdlQ2xhc3NOYW1lcyBmcm9tICdtZXJnZS1jbGFzcy1uYW1lcyc7XG5pbXBvcnQgaW52YXJpYW50IGZyb20gJ3RpbnktaW52YXJpYW50JztcbmltcG9ydCB3YXJuaW5nIGZyb20gJ3Rpbnktd2FybmluZyc7XG5pbXBvcnQgKiBhcyBwZGZqcyBmcm9tICdwZGZqcy1kaXN0L2J1aWxkL3BkZic7XG5pbXBvcnQgRG9jdW1lbnRDb250ZXh0IGZyb20gJy4vRG9jdW1lbnRDb250ZXh0JztcbmltcG9ydCBNZXNzYWdlIGZyb20gJy4vTWVzc2FnZSc7XG5pbXBvcnQgTGlua1NlcnZpY2UgZnJvbSAnLi9MaW5rU2VydmljZSc7XG5pbXBvcnQgUGFzc3dvcmRSZXNwb25zZXMgZnJvbSAnLi9QYXNzd29yZFJlc3BvbnNlcyc7XG5pbXBvcnQgeyBjYW5jZWxSdW5uaW5nVGFzaywgZGF0YVVSSXRvQnl0ZVN0cmluZywgZGlzcGxheUNPUlNXYXJuaW5nLCBpc0FycmF5QnVmZmVyLCBpc0Jsb2IsIGlzQnJvd3NlciwgaXNEYXRhVVJJLCBpc0ZpbGUsIGxvYWRGcm9tRmlsZSB9IGZyb20gJy4vc2hhcmVkL3V0aWxzJztcbmltcG9ydCB7IGV2ZW50UHJvcHMsIGlzQ2xhc3NOYW1lLCBpc0ZpbGUgYXMgaXNGaWxlUHJvcCwgaXNSZWYgfSBmcm9tICcuL3NoYXJlZC9wcm9wVHlwZXMnO1xudmFyIFBERkRhdGFSYW5nZVRyYW5zcG9ydCA9IHBkZmpzLlBERkRhdGFSYW5nZVRyYW5zcG9ydDtcblxudmFyIERvY3VtZW50ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfUHVyZUNvbXBvbmVudCkge1xuICBfaW5oZXJpdHMoRG9jdW1lbnQsIF9QdXJlQ29tcG9uZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyKERvY3VtZW50KTtcblxuICBmdW5jdGlvbiBEb2N1bWVudCgpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgRG9jdW1lbnQpO1xuXG4gICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICAgIH1cblxuICAgIF90aGlzID0gX3N1cGVyLmNhbGwuYXBwbHkoX3N1cGVyLCBbdGhpc10uY29uY2F0KGFyZ3MpKTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJzdGF0ZVwiLCB7XG4gICAgICBwZGY6IG51bGxcbiAgICB9KTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJ2aWV3ZXJcIiwge1xuICAgICAgc2Nyb2xsUGFnZUludG9WaWV3OiBmdW5jdGlvbiBzY3JvbGxQYWdlSW50b1ZpZXcoX3JlZikge1xuICAgICAgICB2YXIgZGVzdCA9IF9yZWYuZGVzdCxcbiAgICAgICAgICAgIHBhZ2VJbmRleCA9IF9yZWYucGFnZUluZGV4LFxuICAgICAgICAgICAgcGFnZU51bWJlciA9IF9yZWYucGFnZU51bWJlcjtcbiAgICAgICAgLy8gSGFuZGxpbmcganVtcGluZyB0byBpbnRlcm5hbCBsaW5rcyB0YXJnZXRcbiAgICAgICAgdmFyIG9uSXRlbUNsaWNrID0gX3RoaXMucHJvcHMub25JdGVtQ2xpY2s7IC8vIEZpcnN0LCBjaGVjayBpZiBjdXN0b20gaGFuZGxpbmcgb2Ygb25JdGVtQ2xpY2sgd2FzIHByb3ZpZGVkXG5cbiAgICAgICAgaWYgKG9uSXRlbUNsaWNrKSB7XG4gICAgICAgICAgb25JdGVtQ2xpY2soe1xuICAgICAgICAgICAgZGVzdDogZGVzdCxcbiAgICAgICAgICAgIHBhZ2VJbmRleDogcGFnZUluZGV4LFxuICAgICAgICAgICAgcGFnZU51bWJlcjogcGFnZU51bWJlclxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSAvLyBJZiBub3QsIHRyeSB0byBsb29rIGZvciB0YXJnZXQgcGFnZSB3aXRoaW4gdGhlIDxEb2N1bWVudD4uXG5cblxuICAgICAgICB2YXIgcGFnZSA9IF90aGlzLnBhZ2VzW3BhZ2VJbmRleF07XG5cbiAgICAgICAgaWYgKHBhZ2UpIHtcbiAgICAgICAgICAvLyBTY3JvbGwgdG8gdGhlIHBhZ2UgYXV0b21hdGljYWxseVxuICAgICAgICAgIHBhZ2Uuc2Nyb2xsSW50b1ZpZXcoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB3YXJuaW5nKGZhbHNlLCBcIkFuIGludGVybmFsIGxpbmsgbGVhZGluZyB0byBwYWdlIFwiLmNvbmNhdChwYWdlTnVtYmVyLCBcIiB3YXMgY2xpY2tlZCwgYnV0IG5laXRoZXIgPERvY3VtZW50PiB3YXMgcHJvdmlkZWQgd2l0aCBvbkl0ZW1DbGljayBub3IgaXQgd2FzIGFibGUgdG8gZmluZCB0aGUgcGFnZSB3aXRoaW4gaXRzZWxmLiBFaXRoZXIgcHJvdmlkZSBvbkl0ZW1DbGljayB0byA8RG9jdW1lbnQ+IGFuZCBoYW5kbGUgbmF2aWdhdGluZyBieSB5b3Vyc2VsZiBvciBlbnN1cmUgdGhhdCBhbGwgcGFnZXMgYXJlIHJlbmRlcmVkIHdpdGhpbiA8RG9jdW1lbnQ+LlwiKSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwibGlua1NlcnZpY2VcIiwgbmV3IExpbmtTZXJ2aWNlKCkpO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcImxvYWREb2N1bWVudFwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBJZiBhbm90aGVyIHJlbmRlcmluZyBpcyBpbiBwcm9ncmVzcywgbGV0J3MgY2FuY2VsIGl0XG4gICAgICBjYW5jZWxSdW5uaW5nVGFzayhfdGhpcy5ydW5uaW5nVGFzayk7IC8vIElmIGFub3RoZXIgbG9hZGluZyBpcyBpbiBwcm9ncmVzcywgbGV0J3MgZGVzdHJveSBpdFxuXG4gICAgICBpZiAoX3RoaXMubG9hZGluZ1Rhc2spIF90aGlzLmxvYWRpbmdUYXNrLmRlc3Ryb3koKTtcbiAgICAgIHZhciBjYW5jZWxsYWJsZSA9IG1ha2VDYW5jZWxsYWJsZShfdGhpcy5maW5kRG9jdW1lbnRTb3VyY2UoKSk7XG4gICAgICBfdGhpcy5ydW5uaW5nVGFzayA9IGNhbmNlbGxhYmxlO1xuICAgICAgY2FuY2VsbGFibGUucHJvbWlzZS50aGVuKGZ1bmN0aW9uIChzb3VyY2UpIHtcbiAgICAgICAgX3RoaXMub25Tb3VyY2VTdWNjZXNzKCk7XG5cbiAgICAgICAgaWYgKCFzb3VyY2UpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBfdGhpcy5zZXRTdGF0ZShmdW5jdGlvbiAocHJldlN0YXRlKSB7XG4gICAgICAgICAgaWYgKCFwcmV2U3RhdGUucGRmKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcGRmOiBudWxsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdmFyIF90aGlzJHByb3BzID0gX3RoaXMucHJvcHMsXG4gICAgICAgICAgICBvcHRpb25zID0gX3RoaXMkcHJvcHMub3B0aW9ucyxcbiAgICAgICAgICAgIG9uTG9hZFByb2dyZXNzID0gX3RoaXMkcHJvcHMub25Mb2FkUHJvZ3Jlc3MsXG4gICAgICAgICAgICBvblBhc3N3b3JkID0gX3RoaXMkcHJvcHMub25QYXNzd29yZDtcbiAgICAgICAgX3RoaXMubG9hZGluZ1Rhc2sgPSBwZGZqcy5nZXREb2N1bWVudChfb2JqZWN0U3ByZWFkKF9vYmplY3RTcHJlYWQoe30sIHNvdXJjZSksIG9wdGlvbnMpKTtcbiAgICAgICAgX3RoaXMubG9hZGluZ1Rhc2sub25QYXNzd29yZCA9IG9uUGFzc3dvcmQ7XG5cbiAgICAgICAgaWYgKG9uTG9hZFByb2dyZXNzKSB7XG4gICAgICAgICAgX3RoaXMubG9hZGluZ1Rhc2sub25Qcm9ncmVzcyA9IG9uTG9hZFByb2dyZXNzO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNhbmNlbGxhYmxlID0gbWFrZUNhbmNlbGxhYmxlKF90aGlzLmxvYWRpbmdUYXNrLnByb21pc2UpO1xuICAgICAgICBfdGhpcy5ydW5uaW5nVGFzayA9IGNhbmNlbGxhYmxlO1xuICAgICAgICBjYW5jZWxsYWJsZS5wcm9taXNlLnRoZW4oZnVuY3Rpb24gKHBkZikge1xuICAgICAgICAgIF90aGlzLnNldFN0YXRlKGZ1bmN0aW9uIChwcmV2U3RhdGUpIHtcbiAgICAgICAgICAgIGlmIChwcmV2U3RhdGUucGRmICYmIHByZXZTdGF0ZS5wZGYuZmluZ2VycHJpbnQgPT09IHBkZi5maW5nZXJwcmludCkge1xuICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgcGRmOiBwZGZcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSwgX3RoaXMub25Mb2FkU3VjY2Vzcyk7XG4gICAgICAgIH0pW1wiY2F0Y2hcIl0oZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgICAgX3RoaXMub25Mb2FkRXJyb3IoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICAgIH0pW1wiY2F0Y2hcIl0oZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIF90aGlzLm9uU291cmNlRXJyb3IoZXJyb3IpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwic2V0dXBMaW5rU2VydmljZVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX3RoaXMkcHJvcHMyID0gX3RoaXMucHJvcHMsXG4gICAgICAgICAgZXh0ZXJuYWxMaW5rUmVsID0gX3RoaXMkcHJvcHMyLmV4dGVybmFsTGlua1JlbCxcbiAgICAgICAgICBleHRlcm5hbExpbmtUYXJnZXQgPSBfdGhpcyRwcm9wczIuZXh0ZXJuYWxMaW5rVGFyZ2V0O1xuXG4gICAgICBfdGhpcy5saW5rU2VydmljZS5zZXRWaWV3ZXIoX3RoaXMudmlld2VyKTtcblxuICAgICAgX3RoaXMubGlua1NlcnZpY2Uuc2V0RXh0ZXJuYWxMaW5rUmVsKGV4dGVybmFsTGlua1JlbCk7XG5cbiAgICAgIF90aGlzLmxpbmtTZXJ2aWNlLnNldEV4dGVybmFsTGlua1RhcmdldChleHRlcm5hbExpbmtUYXJnZXQpO1xuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcIm9uU291cmNlU3VjY2Vzc1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgb25Tb3VyY2VTdWNjZXNzID0gX3RoaXMucHJvcHMub25Tb3VyY2VTdWNjZXNzO1xuICAgICAgaWYgKG9uU291cmNlU3VjY2Vzcykgb25Tb3VyY2VTdWNjZXNzKCk7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25Tb3VyY2VFcnJvclwiLCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIHdhcm5pbmcoZXJyb3IpO1xuICAgICAgdmFyIG9uU291cmNlRXJyb3IgPSBfdGhpcy5wcm9wcy5vblNvdXJjZUVycm9yO1xuICAgICAgaWYgKG9uU291cmNlRXJyb3IpIG9uU291cmNlRXJyb3IoZXJyb3IpO1xuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcIm9uTG9hZFN1Y2Nlc3NcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIG9uTG9hZFN1Y2Nlc3MgPSBfdGhpcy5wcm9wcy5vbkxvYWRTdWNjZXNzO1xuICAgICAgdmFyIHBkZiA9IF90aGlzLnN0YXRlLnBkZjtcbiAgICAgIGlmIChvbkxvYWRTdWNjZXNzKSBvbkxvYWRTdWNjZXNzKHBkZik7XG4gICAgICBfdGhpcy5wYWdlcyA9IG5ldyBBcnJheShwZGYubnVtUGFnZXMpO1xuXG4gICAgICBfdGhpcy5saW5rU2VydmljZS5zZXREb2N1bWVudChwZGYpO1xuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcIm9uTG9hZEVycm9yXCIsIGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgX3RoaXMuc2V0U3RhdGUoe1xuICAgICAgICBwZGY6IGZhbHNlXG4gICAgICB9KTtcblxuICAgICAgd2FybmluZyhlcnJvcik7XG4gICAgICB2YXIgb25Mb2FkRXJyb3IgPSBfdGhpcy5wcm9wcy5vbkxvYWRFcnJvcjtcbiAgICAgIGlmIChvbkxvYWRFcnJvcikgb25Mb2FkRXJyb3IoZXJyb3IpO1xuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcImZpbmREb2N1bWVudFNvdXJjZVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgdmFyIGZpbGUgPSBfdGhpcy5wcm9wcy5maWxlO1xuXG4gICAgICAgIGlmICghZmlsZSkge1xuICAgICAgICAgIHJlc29sdmUobnVsbCk7XG4gICAgICAgIH0gLy8gRmlsZSBpcyBhIHN0cmluZ1xuXG5cbiAgICAgICAgaWYgKHR5cGVvZiBmaWxlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGlmIChpc0RhdGFVUkkoZmlsZSkpIHtcbiAgICAgICAgICAgIHZhciBmaWxlQnl0ZVN0cmluZyA9IGRhdGFVUkl0b0J5dGVTdHJpbmcoZmlsZSk7XG4gICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgZGF0YTogZmlsZUJ5dGVTdHJpbmdcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGRpc3BsYXlDT1JTV2FybmluZygpO1xuICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgdXJsOiBmaWxlXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gLy8gRmlsZSBpcyBQREZEYXRhUmFuZ2VUcmFuc3BvcnRcblxuXG4gICAgICAgIGlmIChmaWxlIGluc3RhbmNlb2YgUERGRGF0YVJhbmdlVHJhbnNwb3J0KSB7XG4gICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICByYW5nZTogZmlsZVxuICAgICAgICAgIH0pO1xuICAgICAgICB9IC8vIEZpbGUgaXMgYW4gQXJyYXlCdWZmZXJcblxuXG4gICAgICAgIGlmIChpc0FycmF5QnVmZmVyKGZpbGUpKSB7XG4gICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICBkYXRhOiBmaWxlXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBjYXNlcyBiZWxvdyBhcmUgYnJvd3Nlci1vbmx5LlxuICAgICAgICAgKiBJZiB5b3UncmUgcnVubmluZyBvbiBhIG5vbi1icm93c2VyIGVudmlyb25tZW50LCB0aGVzZSBjYXNlcyB3aWxsIGJlIG9mIG5vIHVzZS5cbiAgICAgICAgICovXG5cblxuICAgICAgICBpZiAoaXNCcm93c2VyKSB7XG4gICAgICAgICAgLy8gRmlsZSBpcyBhIEJsb2JcbiAgICAgICAgICBpZiAoaXNCbG9iKGZpbGUpIHx8IGlzRmlsZShmaWxlKSkge1xuICAgICAgICAgICAgbG9hZEZyb21GaWxlKGZpbGUpLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgZGF0YTogZGF0YVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfSAvLyBBdCB0aGlzIHBvaW50LCBmaWxlIG11c3QgYmUgYW4gb2JqZWN0XG5cblxuICAgICAgICBpbnZhcmlhbnQoX3R5cGVvZihmaWxlKSA9PT0gJ29iamVjdCcsICdJbnZhbGlkIHBhcmFtZXRlciBpbiBmaWxlLCBuZWVkIGVpdGhlciBVaW50OEFycmF5LCBzdHJpbmcgb3IgYSBwYXJhbWV0ZXIgb2JqZWN0Jyk7XG4gICAgICAgIGludmFyaWFudChmaWxlLnVybCB8fCBmaWxlLmRhdGEgfHwgZmlsZS5yYW5nZSwgJ0ludmFsaWQgcGFyYW1ldGVyIG9iamVjdDogbmVlZCBlaXRoZXIgLmRhdGEsIC5yYW5nZSBvciAudXJsJyk7IC8vIEZpbGUgLnVybCBpcyBhIHN0cmluZ1xuXG4gICAgICAgIGlmICh0eXBlb2YgZmlsZS51cmwgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgaWYgKGlzRGF0YVVSSShmaWxlLnVybCkpIHtcbiAgICAgICAgICAgIHZhciB1cmwgPSBmaWxlLnVybCxcbiAgICAgICAgICAgICAgICBvdGhlclBhcmFtcyA9IF9vYmplY3RXaXRob3V0UHJvcGVydGllcyhmaWxlLCBfZXhjbHVkZWQpO1xuXG4gICAgICAgICAgICB2YXIgX2ZpbGVCeXRlU3RyaW5nID0gZGF0YVVSSXRvQnl0ZVN0cmluZyh1cmwpO1xuXG4gICAgICAgICAgICByZXNvbHZlKF9vYmplY3RTcHJlYWQoe1xuICAgICAgICAgICAgICBkYXRhOiBfZmlsZUJ5dGVTdHJpbmdcbiAgICAgICAgICAgIH0sIG90aGVyUGFyYW1zKSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZGlzcGxheUNPUlNXYXJuaW5nKCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXNvbHZlKGZpbGUpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwicmVnaXN0ZXJQYWdlXCIsIGZ1bmN0aW9uIChwYWdlSW5kZXgsIHJlZikge1xuICAgICAgX3RoaXMucGFnZXNbcGFnZUluZGV4XSA9IHJlZjtcbiAgICB9KTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJ1bnJlZ2lzdGVyUGFnZVwiLCBmdW5jdGlvbiAocGFnZUluZGV4KSB7XG4gICAgICBkZWxldGUgX3RoaXMucGFnZXNbcGFnZUluZGV4XTtcbiAgICB9KTtcblxuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIF9jcmVhdGVDbGFzcyhEb2N1bWVudCwgW3tcbiAgICBrZXk6IFwiY29tcG9uZW50RGlkTW91bnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICB0aGlzLmxvYWREb2N1bWVudCgpO1xuICAgICAgdGhpcy5zZXR1cExpbmtTZXJ2aWNlKCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNvbXBvbmVudERpZFVwZGF0ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnREaWRVcGRhdGUocHJldlByb3BzKSB7XG4gICAgICB2YXIgZmlsZSA9IHRoaXMucHJvcHMuZmlsZTtcblxuICAgICAgaWYgKGZpbGUgIT09IHByZXZQcm9wcy5maWxlKSB7XG4gICAgICAgIHRoaXMubG9hZERvY3VtZW50KCk7XG4gICAgICB9XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNvbXBvbmVudFdpbGxVbm1vdW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgLy8gSWYgcmVuZGVyaW5nIGlzIGluIHByb2dyZXNzLCBsZXQncyBjYW5jZWwgaXRcbiAgICAgIGNhbmNlbFJ1bm5pbmdUYXNrKHRoaXMucnVubmluZ1Rhc2spOyAvLyBJZiBsb2FkaW5nIGlzIGluIHByb2dyZXNzLCBsZXQncyBkZXN0cm95IGl0XG5cbiAgICAgIGlmICh0aGlzLmxvYWRpbmdUYXNrKSB0aGlzLmxvYWRpbmdUYXNrLmRlc3Ryb3koKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY2hpbGRDb250ZXh0XCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICB2YXIgbGlua1NlcnZpY2UgPSB0aGlzLmxpbmtTZXJ2aWNlLFxuICAgICAgICAgIHJlZ2lzdGVyUGFnZSA9IHRoaXMucmVnaXN0ZXJQYWdlLFxuICAgICAgICAgIHVucmVnaXN0ZXJQYWdlID0gdGhpcy51bnJlZ2lzdGVyUGFnZTtcbiAgICAgIHZhciBfdGhpcyRwcm9wczMgPSB0aGlzLnByb3BzLFxuICAgICAgICAgIGltYWdlUmVzb3VyY2VzUGF0aCA9IF90aGlzJHByb3BzMy5pbWFnZVJlc291cmNlc1BhdGgsXG4gICAgICAgICAgcmVuZGVyTW9kZSA9IF90aGlzJHByb3BzMy5yZW5kZXJNb2RlLFxuICAgICAgICAgIHJvdGF0ZSA9IF90aGlzJHByb3BzMy5yb3RhdGU7XG4gICAgICB2YXIgcGRmID0gdGhpcy5zdGF0ZS5wZGY7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBpbWFnZVJlc291cmNlc1BhdGg6IGltYWdlUmVzb3VyY2VzUGF0aCxcbiAgICAgICAgbGlua1NlcnZpY2U6IGxpbmtTZXJ2aWNlLFxuICAgICAgICBwZGY6IHBkZixcbiAgICAgICAgcmVnaXN0ZXJQYWdlOiByZWdpc3RlclBhZ2UsXG4gICAgICAgIHJlbmRlck1vZGU6IHJlbmRlck1vZGUsXG4gICAgICAgIHJvdGF0ZTogcm90YXRlLFxuICAgICAgICB1bnJlZ2lzdGVyUGFnZTogdW5yZWdpc3RlclBhZ2VcbiAgICAgIH07XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImV2ZW50UHJvcHNcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICByZXR1cm4gbWFrZUV2ZW50UHJvcHModGhpcy5wcm9wcywgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gX3RoaXMyLnN0YXRlLnBkZjtcbiAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYWxsZWQgd2hlbiBhIGRvY3VtZW50IHNvdXJjZSBpcyByZXNvbHZlZCBjb3JyZWN0bHlcbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInJlbmRlckNoaWxkcmVuXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlckNoaWxkcmVuKCkge1xuICAgICAgdmFyIGNoaWxkcmVuID0gdGhpcy5wcm9wcy5jaGlsZHJlbjtcbiAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChEb2N1bWVudENvbnRleHQuUHJvdmlkZXIsIHtcbiAgICAgICAgdmFsdWU6IHRoaXMuY2hpbGRDb250ZXh0XG4gICAgICB9LCBjaGlsZHJlbik7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInJlbmRlckNvbnRlbnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyQ29udGVudCgpIHtcbiAgICAgIHZhciBmaWxlID0gdGhpcy5wcm9wcy5maWxlO1xuICAgICAgdmFyIHBkZiA9IHRoaXMuc3RhdGUucGRmO1xuXG4gICAgICBpZiAoIWZpbGUpIHtcbiAgICAgICAgdmFyIG5vRGF0YSA9IHRoaXMucHJvcHMubm9EYXRhO1xuICAgICAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoTWVzc2FnZSwge1xuICAgICAgICAgIHR5cGU6IFwibm8tZGF0YVwiXG4gICAgICAgIH0sIHR5cGVvZiBub0RhdGEgPT09ICdmdW5jdGlvbicgPyBub0RhdGEoKSA6IG5vRGF0YSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwZGYgPT09IG51bGwpIHtcbiAgICAgICAgdmFyIGxvYWRpbmcgPSB0aGlzLnByb3BzLmxvYWRpbmc7XG4gICAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChNZXNzYWdlLCB7XG4gICAgICAgICAgdHlwZTogXCJsb2FkaW5nXCJcbiAgICAgICAgfSwgdHlwZW9mIGxvYWRpbmcgPT09ICdmdW5jdGlvbicgPyBsb2FkaW5nKCkgOiBsb2FkaW5nKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHBkZiA9PT0gZmFsc2UpIHtcbiAgICAgICAgdmFyIGVycm9yID0gdGhpcy5wcm9wcy5lcnJvcjtcbiAgICAgICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KE1lc3NhZ2UsIHtcbiAgICAgICAgICB0eXBlOiBcImVycm9yXCJcbiAgICAgICAgfSwgdHlwZW9mIGVycm9yID09PSAnZnVuY3Rpb24nID8gZXJyb3IoKSA6IGVycm9yKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMucmVuZGVyQ2hpbGRyZW4oKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicmVuZGVyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgIHZhciBfdGhpcyRwcm9wczQgPSB0aGlzLnByb3BzLFxuICAgICAgICAgIGNsYXNzTmFtZSA9IF90aGlzJHByb3BzNC5jbGFzc05hbWUsXG4gICAgICAgICAgaW5wdXRSZWYgPSBfdGhpcyRwcm9wczQuaW5wdXRSZWY7XG4gICAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgX2V4dGVuZHMoe1xuICAgICAgICBjbGFzc05hbWU6IG1lcmdlQ2xhc3NOYW1lcygncmVhY3QtcGRmX19Eb2N1bWVudCcsIGNsYXNzTmFtZSksXG4gICAgICAgIHJlZjogaW5wdXRSZWZcbiAgICAgIH0sIHRoaXMuZXZlbnRQcm9wcyksIHRoaXMucmVuZGVyQ29udGVudCgpKTtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gRG9jdW1lbnQ7XG59KFB1cmVDb21wb25lbnQpO1xuXG5leHBvcnQgeyBEb2N1bWVudCBhcyBkZWZhdWx0IH07XG5Eb2N1bWVudC5kZWZhdWx0UHJvcHMgPSB7XG4gIGVycm9yOiAnRmFpbGVkIHRvIGxvYWQgUERGIGZpbGUuJyxcbiAgbG9hZGluZzogJ0xvYWRpbmcgUERG4oCmJyxcbiAgbm9EYXRhOiAnTm8gUERGIGZpbGUgc3BlY2lmaWVkLicsXG4gIG9uUGFzc3dvcmQ6IGZ1bmN0aW9uIG9uUGFzc3dvcmQoY2FsbGJhY2ssIHJlYXNvbikge1xuICAgIHN3aXRjaCAocmVhc29uKSB7XG4gICAgICBjYXNlIFBhc3N3b3JkUmVzcG9uc2VzLk5FRURfUEFTU1dPUkQ6XG4gICAgICAgIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYWxlcnRcbiAgICAgICAgICB2YXIgcGFzc3dvcmQgPSBwcm9tcHQoJ0VudGVyIHRoZSBwYXNzd29yZCB0byBvcGVuIHRoaXMgUERGIGZpbGUuJyk7XG4gICAgICAgICAgY2FsbGJhY2socGFzc3dvcmQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgUGFzc3dvcmRSZXNwb25zZXMuSU5DT1JSRUNUX1BBU1NXT1JEOlxuICAgICAgICB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWFsZXJ0XG4gICAgICAgICAgdmFyIF9wYXNzd29yZCA9IHByb21wdCgnSW52YWxpZCBwYXNzd29yZC4gUGxlYXNlIHRyeSBhZ2Fpbi4nKTtcblxuICAgICAgICAgIGNhbGxiYWNrKF9wYXNzd29yZCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgZGVmYXVsdDpcbiAgICB9XG4gIH1cbn07XG52YXIgaXNGdW5jdGlvbk9yTm9kZSA9IFByb3BUeXBlcy5vbmVPZlR5cGUoW1Byb3BUeXBlcy5mdW5jLCBQcm9wVHlwZXMubm9kZV0pO1xuRG9jdW1lbnQucHJvcFR5cGVzID0gX29iamVjdFNwcmVhZChfb2JqZWN0U3ByZWFkKHt9LCBldmVudFByb3BzKSwge30sIHtcbiAgY2hpbGRyZW46IFByb3BUeXBlcy5ub2RlLFxuICBjbGFzc05hbWU6IGlzQ2xhc3NOYW1lLFxuICBlcnJvcjogaXNGdW5jdGlvbk9yTm9kZSxcbiAgZXh0ZXJuYWxMaW5rUmVsOiBQcm9wVHlwZXMuc3RyaW5nLFxuICBleHRlcm5hbExpbmtUYXJnZXQ6IFByb3BUeXBlcy5zdHJpbmcsXG4gIGZpbGU6IGlzRmlsZVByb3AsXG4gIGltYWdlUmVzb3VyY2VzUGF0aDogUHJvcFR5cGVzLnN0cmluZyxcbiAgaW5wdXRSZWY6IGlzUmVmLFxuICBsb2FkaW5nOiBpc0Z1bmN0aW9uT3JOb2RlLFxuICBub0RhdGE6IGlzRnVuY3Rpb25Pck5vZGUsXG4gIG9uSXRlbUNsaWNrOiBQcm9wVHlwZXMuZnVuYyxcbiAgb25Mb2FkRXJyb3I6IFByb3BUeXBlcy5mdW5jLFxuICBvbkxvYWRQcm9ncmVzczogUHJvcFR5cGVzLmZ1bmMsXG4gIG9uTG9hZFN1Y2Nlc3M6IFByb3BUeXBlcy5mdW5jLFxuICBvblBhc3N3b3JkOiBQcm9wVHlwZXMuZnVuYyxcbiAgb25Tb3VyY2VFcnJvcjogUHJvcFR5cGVzLmZ1bmMsXG4gIG9uU291cmNlU3VjY2VzczogUHJvcFR5cGVzLmZ1bmMsXG4gIHJvdGF0ZTogUHJvcFR5cGVzLm51bWJlclxufSk7IiwiaW1wb3J0IHsgY3JlYXRlQ29udGV4dCB9IGZyb20gJ3JlYWN0JztcbmV4cG9ydCBkZWZhdWx0IC8qI19fUFVSRV9fKi9jcmVhdGVDb250ZXh0KG51bGwpOyIsImltcG9ydCBfY2xhc3NDYWxsQ2hlY2sgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NsYXNzQ2FsbENoZWNrXCI7XG5pbXBvcnQgX2NyZWF0ZUNsYXNzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jcmVhdGVDbGFzc1wiO1xuXG52YXIgUmVmID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gUmVmKF9yZWYpIHtcbiAgICB2YXIgbnVtID0gX3JlZi5udW0sXG4gICAgICAgIGdlbiA9IF9yZWYuZ2VuO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFJlZik7XG5cbiAgICB0aGlzLm51bSA9IG51bTtcbiAgICB0aGlzLmdlbiA9IGdlbjtcbiAgfVxuXG4gIF9jcmVhdGVDbGFzcyhSZWYsIFt7XG4gICAga2V5OiBcInRvU3RyaW5nXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgdmFyIHN0ciA9IFwiXCIuY29uY2F0KHRoaXMubnVtLCBcIlJcIik7XG5cbiAgICAgIGlmICh0aGlzLmdlbiAhPT0gMCkge1xuICAgICAgICBzdHIgKz0gdGhpcy5nZW47XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIFJlZjtcbn0oKTtcblxuZXhwb3J0IHsgUmVmIGFzIGRlZmF1bHQgfTsiLCJpbXBvcnQgX2V4dGVuZHMgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2V4dGVuZHNcIjtcbmltcG9ydCBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzXCI7XG5pbXBvcnQgX3NsaWNlZFRvQXJyYXkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3NsaWNlZFRvQXJyYXlcIjtcbmltcG9ydCBfY2xhc3NDYWxsQ2hlY2sgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NsYXNzQ2FsbENoZWNrXCI7XG5pbXBvcnQgX2NyZWF0ZUNsYXNzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jcmVhdGVDbGFzc1wiO1xuaW1wb3J0IF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2Fzc2VydFRoaXNJbml0aWFsaXplZFwiO1xuaW1wb3J0IF9pbmhlcml0cyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vaW5oZXJpdHNcIjtcbmltcG9ydCBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybiBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vcG9zc2libGVDb25zdHJ1Y3RvclJldHVyblwiO1xuaW1wb3J0IF9nZXRQcm90b3R5cGVPZiBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZ2V0UHJvdG90eXBlT2ZcIjtcbmltcG9ydCBfZGVmaW5lUHJvcGVydHkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2RlZmluZVByb3BlcnR5XCI7XG52YXIgX2V4Y2x1ZGVkID0gW1wiaXRlbVwiXTtcblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KCk7IHJldHVybiBmdW5jdGlvbiBfY3JlYXRlU3VwZXJJbnRlcm5hbCgpIHsgdmFyIFN1cGVyID0gX2dldFByb3RvdHlwZU9mKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2YodGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIHJlc3VsdCk7IH07IH1cblxuZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCgpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbmltcG9ydCBSZWFjdCwgeyBQdXJlQ29tcG9uZW50IH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcbmltcG9ydCBEb2N1bWVudENvbnRleHQgZnJvbSAnLi9Eb2N1bWVudENvbnRleHQnO1xuaW1wb3J0IE91dGxpbmVDb250ZXh0IGZyb20gJy4vT3V0bGluZUNvbnRleHQnO1xuaW1wb3J0IFJlZiBmcm9tICcuL1JlZic7XG5pbXBvcnQgeyBpc0RlZmluZWQgfSBmcm9tICcuL3NoYXJlZC91dGlscyc7XG5pbXBvcnQgeyBpc1BkZiB9IGZyb20gJy4vc2hhcmVkL3Byb3BUeXBlcyc7XG5leHBvcnQgdmFyIE91dGxpbmVJdGVtSW50ZXJuYWwgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9QdXJlQ29tcG9uZW50KSB7XG4gIF9pbmhlcml0cyhPdXRsaW5lSXRlbUludGVybmFsLCBfUHVyZUNvbXBvbmVudCk7XG5cbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlcihPdXRsaW5lSXRlbUludGVybmFsKTtcblxuICBmdW5jdGlvbiBPdXRsaW5lSXRlbUludGVybmFsKCkge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBPdXRsaW5lSXRlbUludGVybmFsKTtcblxuICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4pLCBfa2V5ID0gMDsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICB9XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsLmFwcGx5KF9zdXBlciwgW3RoaXNdLmNvbmNhdChhcmdzKSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwiZ2V0RGVzdGluYXRpb25cIiwgZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgdmFyIF90aGlzJHByb3BzID0gX3RoaXMucHJvcHMsXG4gICAgICAgICAgICBpdGVtID0gX3RoaXMkcHJvcHMuaXRlbSxcbiAgICAgICAgICAgIHBkZiA9IF90aGlzJHByb3BzLnBkZjtcblxuICAgICAgICBpZiAoIWlzRGVmaW5lZChfdGhpcy5kZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGl0ZW0uZGVzdCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHBkZi5nZXREZXN0aW5hdGlvbihpdGVtLmRlc3QpLnRoZW4ocmVzb2x2ZSlbXCJjYXRjaFwiXShyZWplY3QpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXNvbHZlKGl0ZW0uZGVzdCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIF90aGlzLmRlc3RpbmF0aW9uO1xuICAgICAgfSkudGhlbihmdW5jdGlvbiAoZGVzdGluYXRpb24pIHtcbiAgICAgICAgX3RoaXMuZGVzdGluYXRpb24gPSBkZXN0aW5hdGlvbjtcbiAgICAgICAgcmV0dXJuIGRlc3RpbmF0aW9uO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwiZ2V0UGFnZUluZGV4XCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHZhciBwZGYgPSBfdGhpcy5wcm9wcy5wZGY7XG5cbiAgICAgICAgaWYgKGlzRGVmaW5lZChfdGhpcy5wYWdlSW5kZXgpKSB7XG4gICAgICAgICAgcmVzb2x2ZShfdGhpcy5wYWdlSW5kZXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgX3RoaXMuZ2V0RGVzdGluYXRpb24oKS50aGVuKGZ1bmN0aW9uIChkZXN0aW5hdGlvbikge1xuICAgICAgICAgIGlmICghZGVzdGluYXRpb24pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgX2Rlc3RpbmF0aW9uID0gX3NsaWNlZFRvQXJyYXkoZGVzdGluYXRpb24sIDEpLFxuICAgICAgICAgICAgICByZWYgPSBfZGVzdGluYXRpb25bMF07XG5cbiAgICAgICAgICBwZGYuZ2V0UGFnZUluZGV4KG5ldyBSZWYocmVmKSkudGhlbihyZXNvbHZlKVtcImNhdGNoXCJdKHJlamVjdCk7XG4gICAgICAgIH0pO1xuICAgICAgfSkudGhlbihmdW5jdGlvbiAocGFnZUluZGV4KSB7XG4gICAgICAgIF90aGlzLnBhZ2VJbmRleCA9IHBhZ2VJbmRleDtcbiAgICAgICAgcmV0dXJuIF90aGlzLnBhZ2VJbmRleDtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcImdldFBhZ2VOdW1iZXJcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgaWYgKGlzRGVmaW5lZChfdGhpcy5wYWdlTnVtYmVyKSkge1xuICAgICAgICAgIHJlc29sdmUoX3RoaXMucGFnZU51bWJlcik7XG4gICAgICAgIH1cblxuICAgICAgICBfdGhpcy5nZXRQYWdlSW5kZXgoKS50aGVuKGZ1bmN0aW9uIChwYWdlSW5kZXgpIHtcbiAgICAgICAgICByZXNvbHZlKHBhZ2VJbmRleCArIDEpO1xuICAgICAgICB9KVtcImNhdGNoXCJdKHJlamVjdCk7XG4gICAgICB9KS50aGVuKGZ1bmN0aW9uIChwYWdlTnVtYmVyKSB7XG4gICAgICAgIF90aGlzLnBhZ2VOdW1iZXIgPSBwYWdlTnVtYmVyO1xuICAgICAgICByZXR1cm4gcGFnZU51bWJlcjtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcIm9uQ2xpY2tcIiwgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICB2YXIgb25DbGljayA9IF90aGlzLnByb3BzLm9uQ2xpY2s7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICBpZiAoIW9uQ2xpY2spIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW190aGlzLmdldERlc3RpbmF0aW9uKCksIF90aGlzLmdldFBhZ2VJbmRleCgpLCBfdGhpcy5nZXRQYWdlTnVtYmVyKCldKS50aGVuKGZ1bmN0aW9uIChfcmVmKSB7XG4gICAgICAgIHZhciBfcmVmMiA9IF9zbGljZWRUb0FycmF5KF9yZWYsIDMpLFxuICAgICAgICAgICAgZGVzdCA9IF9yZWYyWzBdLFxuICAgICAgICAgICAgcGFnZUluZGV4ID0gX3JlZjJbMV0sXG4gICAgICAgICAgICBwYWdlTnVtYmVyID0gX3JlZjJbMl07XG5cbiAgICAgICAgb25DbGljayh7XG4gICAgICAgICAgZGVzdDogZGVzdCxcbiAgICAgICAgICBwYWdlSW5kZXg6IHBhZ2VJbmRleCxcbiAgICAgICAgICBwYWdlTnVtYmVyOiBwYWdlTnVtYmVyXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3MoT3V0bGluZUl0ZW1JbnRlcm5hbCwgW3tcbiAgICBrZXk6IFwicmVuZGVyU3ViaXRlbXNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyU3ViaXRlbXMoKSB7XG4gICAgICB2YXIgX3RoaXMkcHJvcHMyID0gdGhpcy5wcm9wcyxcbiAgICAgICAgICBpdGVtID0gX3RoaXMkcHJvcHMyLml0ZW0sXG4gICAgICAgICAgb3RoZXJQcm9wcyA9IF9vYmplY3RXaXRob3V0UHJvcGVydGllcyhfdGhpcyRwcm9wczIsIF9leGNsdWRlZCk7XG5cbiAgICAgIGlmICghaXRlbS5pdGVtcyB8fCAhaXRlbS5pdGVtcy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIHZhciBzdWJpdGVtcyA9IGl0ZW0uaXRlbXM7XG4gICAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ1bFwiLCBudWxsLCBzdWJpdGVtcy5tYXAoZnVuY3Rpb24gKHN1Yml0ZW0sIHN1Yml0ZW1JbmRleCkge1xuICAgICAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoT3V0bGluZUl0ZW1JbnRlcm5hbCwgX2V4dGVuZHMoe1xuICAgICAgICAgIGtleTogdHlwZW9mIHN1Yml0ZW0uZGVzdGluYXRpb24gPT09ICdzdHJpbmcnID8gc3ViaXRlbS5kZXN0aW5hdGlvbiA6IHN1Yml0ZW1JbmRleCxcbiAgICAgICAgICBpdGVtOiBzdWJpdGVtXG4gICAgICAgIH0sIG90aGVyUHJvcHMpKTtcbiAgICAgIH0pKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicmVuZGVyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgIHZhciBpdGVtID0gdGhpcy5wcm9wcy5pdGVtO1xuICAgICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwibGlcIiwgbnVsbCwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJhXCIsIHtcbiAgICAgICAgaHJlZjogXCIjXCIsXG4gICAgICAgIG9uQ2xpY2s6IHRoaXMub25DbGlja1xuICAgICAgfSwgaXRlbS50aXRsZSksIHRoaXMucmVuZGVyU3ViaXRlbXMoKSk7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIE91dGxpbmVJdGVtSW50ZXJuYWw7XG59KFB1cmVDb21wb25lbnQpO1xudmFyIGlzRGVzdGluYXRpb24gPSBQcm9wVHlwZXMub25lT2ZUeXBlKFtQcm9wVHlwZXMuc3RyaW5nLCBQcm9wVHlwZXMuYXJyYXlPZihQcm9wVHlwZXMuYW55KV0pO1xuT3V0bGluZUl0ZW1JbnRlcm5hbC5wcm9wVHlwZXMgPSB7XG4gIGl0ZW06IFByb3BUeXBlcy5zaGFwZSh7XG4gICAgZGVzdDogaXNEZXN0aW5hdGlvbixcbiAgICBpdGVtczogUHJvcFR5cGVzLmFycmF5T2YoUHJvcFR5cGVzLnNoYXBlKHtcbiAgICAgIGRlc3Q6IGlzRGVzdGluYXRpb24sXG4gICAgICB0aXRsZTogUHJvcFR5cGVzLnN0cmluZ1xuICAgIH0pKSxcbiAgICB0aXRsZTogUHJvcFR5cGVzLnN0cmluZ1xuICB9KS5pc1JlcXVpcmVkLFxuICBvbkNsaWNrOiBQcm9wVHlwZXMuZnVuYyxcbiAgcGRmOiBpc1BkZi5pc1JlcXVpcmVkXG59O1xuXG52YXIgT3V0bGluZUl0ZW0gPSBmdW5jdGlvbiBPdXRsaW5lSXRlbShwcm9wcykge1xuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoRG9jdW1lbnRDb250ZXh0LkNvbnN1bWVyLCBudWxsLCBmdW5jdGlvbiAoZG9jdW1lbnRDb250ZXh0KSB7XG4gICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KE91dGxpbmVDb250ZXh0LkNvbnN1bWVyLCBudWxsLCBmdW5jdGlvbiAob3V0bGluZUNvbnRleHQpIHtcbiAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChPdXRsaW5lSXRlbUludGVybmFsLCBfZXh0ZW5kcyh7fSwgZG9jdW1lbnRDb250ZXh0LCBvdXRsaW5lQ29udGV4dCwgcHJvcHMpKTtcbiAgICB9KTtcbiAgfSk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBPdXRsaW5lSXRlbTsiLCJpbXBvcnQgX2V4dGVuZHMgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2V4dGVuZHNcIjtcbmltcG9ydCBfY2xhc3NDYWxsQ2hlY2sgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NsYXNzQ2FsbENoZWNrXCI7XG5pbXBvcnQgX2NyZWF0ZUNsYXNzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jcmVhdGVDbGFzc1wiO1xuaW1wb3J0IF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2Fzc2VydFRoaXNJbml0aWFsaXplZFwiO1xuaW1wb3J0IF9pbmhlcml0cyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vaW5oZXJpdHNcIjtcbmltcG9ydCBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybiBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vcG9zc2libGVDb25zdHJ1Y3RvclJldHVyblwiO1xuaW1wb3J0IF9nZXRQcm90b3R5cGVPZiBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZ2V0UHJvdG90eXBlT2ZcIjtcbmltcG9ydCBfZGVmaW5lUHJvcGVydHkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2RlZmluZVByb3BlcnR5XCI7XG5cbmZ1bmN0aW9uIG93bktleXMob2JqZWN0LCBlbnVtZXJhYmxlT25seSkgeyB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iamVjdCk7IGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKSB7IHZhciBzeW1ib2xzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhvYmplY3QpOyBlbnVtZXJhYmxlT25seSAmJiAoc3ltYm9scyA9IHN5bWJvbHMuZmlsdGVyKGZ1bmN0aW9uIChzeW0pIHsgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBzeW0pLmVudW1lcmFibGU7IH0pKSwga2V5cy5wdXNoLmFwcGx5KGtleXMsIHN5bWJvbHMpOyB9IHJldHVybiBrZXlzOyB9XG5cbmZ1bmN0aW9uIF9vYmplY3RTcHJlYWQodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBudWxsICE9IGFyZ3VtZW50c1tpXSA/IGFyZ3VtZW50c1tpXSA6IHt9OyBpICUgMiA/IG93bktleXMoT2JqZWN0KHNvdXJjZSksICEwKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsgX2RlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBzb3VyY2Vba2V5XSk7IH0pIDogT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMgPyBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKHNvdXJjZSkpIDogb3duS2V5cyhPYmplY3Qoc291cmNlKSkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihzb3VyY2UsIGtleSkpOyB9KTsgfSByZXR1cm4gdGFyZ2V0OyB9XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlcihEZXJpdmVkKSB7IHZhciBoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0ID0gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCgpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZihEZXJpdmVkKSwgcmVzdWx0OyBpZiAoaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCkgeyB2YXIgTmV3VGFyZ2V0ID0gX2dldFByb3RvdHlwZU9mKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG5pbXBvcnQgUmVhY3QsIHsgUHVyZUNvbXBvbmVudCB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgbWFrZUNhbmNlbGxhYmxlIGZyb20gJ21ha2UtY2FuY2VsbGFibGUtcHJvbWlzZSc7XG5pbXBvcnQgbWFrZUV2ZW50UHJvcHMgZnJvbSAnbWFrZS1ldmVudC1wcm9wcyc7XG5pbXBvcnQgbWVyZ2VDbGFzc05hbWVzIGZyb20gJ21lcmdlLWNsYXNzLW5hbWVzJztcbmltcG9ydCBpbnZhcmlhbnQgZnJvbSAndGlueS1pbnZhcmlhbnQnO1xuaW1wb3J0IHdhcm5pbmcgZnJvbSAndGlueS13YXJuaW5nJztcbmltcG9ydCBEb2N1bWVudENvbnRleHQgZnJvbSAnLi9Eb2N1bWVudENvbnRleHQnO1xuaW1wb3J0IE91dGxpbmVDb250ZXh0IGZyb20gJy4vT3V0bGluZUNvbnRleHQnO1xuaW1wb3J0IE91dGxpbmVJdGVtIGZyb20gJy4vT3V0bGluZUl0ZW0nO1xuaW1wb3J0IHsgY2FuY2VsUnVubmluZ1Rhc2sgfSBmcm9tICcuL3NoYXJlZC91dGlscyc7XG5pbXBvcnQgeyBldmVudFByb3BzLCBpc0NsYXNzTmFtZSwgaXNQZGYsIGlzUmVmIH0gZnJvbSAnLi9zaGFyZWQvcHJvcFR5cGVzJztcbmV4cG9ydCB2YXIgT3V0bGluZUludGVybmFsID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfUHVyZUNvbXBvbmVudCkge1xuICBfaW5oZXJpdHMoT3V0bGluZUludGVybmFsLCBfUHVyZUNvbXBvbmVudCk7XG5cbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlcihPdXRsaW5lSW50ZXJuYWwpO1xuXG4gIGZ1bmN0aW9uIE91dGxpbmVJbnRlcm5hbCgpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgT3V0bGluZUludGVybmFsKTtcblxuICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4pLCBfa2V5ID0gMDsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICB9XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsLmFwcGx5KF9zdXBlciwgW3RoaXNdLmNvbmNhdChhcmdzKSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwic3RhdGVcIiwge1xuICAgICAgb3V0bGluZTogbnVsbFxuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcImxvYWRPdXRsaW5lXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBwZGYgPSBfdGhpcy5wcm9wcy5wZGY7XG5cbiAgICAgIF90aGlzLnNldFN0YXRlKGZ1bmN0aW9uIChwcmV2U3RhdGUpIHtcbiAgICAgICAgaWYgKCFwcmV2U3RhdGUub3V0bGluZSkge1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBvdXRsaW5lOiBudWxsXG4gICAgICAgIH07XG4gICAgICB9KTtcblxuICAgICAgdmFyIGNhbmNlbGxhYmxlID0gbWFrZUNhbmNlbGxhYmxlKHBkZi5nZXRPdXRsaW5lKCkpO1xuICAgICAgX3RoaXMucnVubmluZ1Rhc2sgPSBjYW5jZWxsYWJsZTtcbiAgICAgIGNhbmNlbGxhYmxlLnByb21pc2UudGhlbihmdW5jdGlvbiAob3V0bGluZSkge1xuICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgb3V0bGluZTogb3V0bGluZVxuICAgICAgICB9LCBfdGhpcy5vbkxvYWRTdWNjZXNzKTtcbiAgICAgIH0pW1wiY2F0Y2hcIl0oZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIF90aGlzLm9uTG9hZEVycm9yKGVycm9yKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcIm9uTG9hZFN1Y2Nlc3NcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIG9uTG9hZFN1Y2Nlc3MgPSBfdGhpcy5wcm9wcy5vbkxvYWRTdWNjZXNzO1xuICAgICAgdmFyIG91dGxpbmUgPSBfdGhpcy5zdGF0ZS5vdXRsaW5lO1xuICAgICAgaWYgKG9uTG9hZFN1Y2Nlc3MpIG9uTG9hZFN1Y2Nlc3Mob3V0bGluZSk7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25Mb2FkRXJyb3JcIiwgZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICBfdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIG91dGxpbmU6IGZhbHNlXG4gICAgICB9KTtcblxuICAgICAgd2FybmluZyhlcnJvcik7XG4gICAgICB2YXIgb25Mb2FkRXJyb3IgPSBfdGhpcy5wcm9wcy5vbkxvYWRFcnJvcjtcbiAgICAgIGlmIChvbkxvYWRFcnJvcikgb25Mb2FkRXJyb3IoZXJyb3IpO1xuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcIm9uSXRlbUNsaWNrXCIsIGZ1bmN0aW9uIChfcmVmKSB7XG4gICAgICB2YXIgZGVzdCA9IF9yZWYuZGVzdCxcbiAgICAgICAgICBwYWdlSW5kZXggPSBfcmVmLnBhZ2VJbmRleCxcbiAgICAgICAgICBwYWdlTnVtYmVyID0gX3JlZi5wYWdlTnVtYmVyO1xuICAgICAgdmFyIG9uSXRlbUNsaWNrID0gX3RoaXMucHJvcHMub25JdGVtQ2xpY2s7XG5cbiAgICAgIGlmIChvbkl0ZW1DbGljaykge1xuICAgICAgICBvbkl0ZW1DbGljayh7XG4gICAgICAgICAgZGVzdDogZGVzdCxcbiAgICAgICAgICBwYWdlSW5kZXg6IHBhZ2VJbmRleCxcbiAgICAgICAgICBwYWdlTnVtYmVyOiBwYWdlTnVtYmVyXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzKE91dGxpbmVJbnRlcm5hbCwgW3tcbiAgICBrZXk6IFwiY29tcG9uZW50RGlkTW91bnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICB2YXIgcGRmID0gdGhpcy5wcm9wcy5wZGY7XG4gICAgICBpbnZhcmlhbnQocGRmLCAnQXR0ZW1wdGVkIHRvIGxvYWQgYW4gb3V0bGluZSwgYnV0IG5vIGRvY3VtZW50IHdhcyBzcGVjaWZpZWQuJyk7XG4gICAgICB0aGlzLmxvYWRPdXRsaW5lKCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNvbXBvbmVudERpZFVwZGF0ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnREaWRVcGRhdGUocHJldlByb3BzKSB7XG4gICAgICB2YXIgcGRmID0gdGhpcy5wcm9wcy5wZGY7XG5cbiAgICAgIGlmIChwcmV2UHJvcHMucGRmICYmIHBkZiAhPT0gcHJldlByb3BzLnBkZikge1xuICAgICAgICB0aGlzLmxvYWRPdXRsaW5lKCk7XG4gICAgICB9XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNvbXBvbmVudFdpbGxVbm1vdW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgY2FuY2VsUnVubmluZ1Rhc2sodGhpcy5ydW5uaW5nVGFzayk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNoaWxkQ29udGV4dFwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb25DbGljazogdGhpcy5vbkl0ZW1DbGlja1xuICAgICAgfTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZXZlbnRQcm9wc1wiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgIHJldHVybiBtYWtlRXZlbnRQcm9wcyh0aGlzLnByb3BzLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBfdGhpczIuc3RhdGUub3V0bGluZTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYWxsZWQgd2hlbiBhbiBvdXRsaW5lIGlzIHJlYWQgc3VjY2Vzc2Z1bGx5XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJPdXRsaW5lXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlck91dGxpbmUoKSB7XG4gICAgICB2YXIgb3V0bGluZSA9IHRoaXMuc3RhdGUub3V0bGluZTtcbiAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcInVsXCIsIG51bGwsIG91dGxpbmUubWFwKGZ1bmN0aW9uIChpdGVtLCBpdGVtSW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KE91dGxpbmVJdGVtLCB7XG4gICAgICAgICAga2V5OiB0eXBlb2YgaXRlbS5kZXN0aW5hdGlvbiA9PT0gJ3N0cmluZycgPyBpdGVtLmRlc3RpbmF0aW9uIDogaXRlbUluZGV4LFxuICAgICAgICAgIGl0ZW06IGl0ZW1cbiAgICAgICAgfSk7XG4gICAgICB9KSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInJlbmRlclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICB2YXIgcGRmID0gdGhpcy5wcm9wcy5wZGY7XG4gICAgICB2YXIgb3V0bGluZSA9IHRoaXMuc3RhdGUub3V0bGluZTtcblxuICAgICAgaWYgKCFwZGYgfHwgIW91dGxpbmUpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIHZhciBfdGhpcyRwcm9wcyA9IHRoaXMucHJvcHMsXG4gICAgICAgICAgY2xhc3NOYW1lID0gX3RoaXMkcHJvcHMuY2xhc3NOYW1lLFxuICAgICAgICAgIGlucHV0UmVmID0gX3RoaXMkcHJvcHMuaW5wdXRSZWY7XG4gICAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgX2V4dGVuZHMoe1xuICAgICAgICBjbGFzc05hbWU6IG1lcmdlQ2xhc3NOYW1lcygncmVhY3QtcGRmX19PdXRsaW5lJywgY2xhc3NOYW1lKSxcbiAgICAgICAgcmVmOiBpbnB1dFJlZlxuICAgICAgfSwgdGhpcy5ldmVudFByb3BzKSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoT3V0bGluZUNvbnRleHQuUHJvdmlkZXIsIHtcbiAgICAgICAgdmFsdWU6IHRoaXMuY2hpbGRDb250ZXh0XG4gICAgICB9LCB0aGlzLnJlbmRlck91dGxpbmUoKSkpO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBPdXRsaW5lSW50ZXJuYWw7XG59KFB1cmVDb21wb25lbnQpO1xuT3V0bGluZUludGVybmFsLnByb3BUeXBlcyA9IF9vYmplY3RTcHJlYWQoe1xuICBjbGFzc05hbWU6IGlzQ2xhc3NOYW1lLFxuICBpbnB1dFJlZjogaXNSZWYsXG4gIG9uSXRlbUNsaWNrOiBQcm9wVHlwZXMuZnVuYyxcbiAgb25Mb2FkRXJyb3I6IFByb3BUeXBlcy5mdW5jLFxuICBvbkxvYWRTdWNjZXNzOiBQcm9wVHlwZXMuZnVuYyxcbiAgcGRmOiBpc1BkZlxufSwgZXZlbnRQcm9wcyk7XG5cbmZ1bmN0aW9uIE91dGxpbmUocHJvcHMsIHJlZikge1xuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoRG9jdW1lbnRDb250ZXh0LkNvbnN1bWVyLCBudWxsLCBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChPdXRsaW5lSW50ZXJuYWwsIF9leHRlbmRzKHtcbiAgICAgIHJlZjogcmVmXG4gICAgfSwgY29udGV4dCwgcHJvcHMpKTtcbiAgfSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IC8qI19fUFVSRV9fKi9SZWFjdC5mb3J3YXJkUmVmKE91dGxpbmUpOyIsIi8qKlxuICogQSBmdW5jdGlvbiB0aGF0IG1lcmdlcyBSZWFjdCByZWZzIGludG8gb25lLlxuICogU3VwcG9ydHMgYm90aCBmdW5jdGlvbnMgYW5kIHJlZiBvYmplY3RzIGNyZWF0ZWQgdXNpbmcgY3JlYXRlUmVmKCkgYW5kIHVzZVJlZigpLlxuICpcbiAqIFVzYWdlOlxuICogYGBganN4XG4gKiA8ZGl2IHJlZj17bWVyZ2VSZWZzKHJlZjEsIHJlZjIsIHJlZjMpfSAvPlxuICogYGBgXG4gKlxuICogQHBhcmFtIHsuLi5BcnJheTxGdW5jdGlvbnxvYmplY3Q+fSBpbnB1dFJlZnMgQXJyYXkgb2YgcmVmc1xuICogQHJldHVybnMge0Z1bmN0aW9ufSBNZXJnZWQgcmVmc1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBtZXJnZVJlZnMoKSB7XG4gIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBpbnB1dFJlZnMgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgaW5wdXRSZWZzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICB9XG5cbiAgdmFyIGZpbHRlcmVkSW5wdXRSZWZzID0gaW5wdXRSZWZzLmZpbHRlcihCb29sZWFuKTtcblxuICBpZiAoZmlsdGVyZWRJbnB1dFJlZnMubGVuZ3RoIDw9IDEpIHtcbiAgICByZXR1cm4gZmlsdGVyZWRJbnB1dFJlZnNbMF07XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24gbWVyZ2VkUmVmcyhyZWYpIHtcbiAgICBmaWx0ZXJlZElucHV0UmVmcy5mb3JFYWNoKGZ1bmN0aW9uIChpbnB1dFJlZikge1xuICAgICAgaWYgKHR5cGVvZiBpbnB1dFJlZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBpbnB1dFJlZihyZWYpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG4gICAgICAgIGlucHV0UmVmLmN1cnJlbnQgPSByZWY7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG59IiwiaW1wb3J0IHsgY3JlYXRlQ29udGV4dCB9IGZyb20gJ3JlYWN0JztcbmV4cG9ydCBkZWZhdWx0IC8qI19fUFVSRV9fKi9jcmVhdGVDb250ZXh0KG51bGwpOyIsImltcG9ydCBfZXh0ZW5kcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZXh0ZW5kc1wiO1xuaW1wb3J0IF9jbGFzc0NhbGxDaGVjayBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY2xhc3NDYWxsQ2hlY2tcIjtcbmltcG9ydCBfY3JlYXRlQ2xhc3MgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NyZWF0ZUNsYXNzXCI7XG5pbXBvcnQgX2Fzc2VydFRoaXNJbml0aWFsaXplZCBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vYXNzZXJ0VGhpc0luaXRpYWxpemVkXCI7XG5pbXBvcnQgX2luaGVyaXRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pbmhlcml0c1wiO1xuaW1wb3J0IF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuXCI7XG5pbXBvcnQgX2dldFByb3RvdHlwZU9mIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9nZXRQcm90b3R5cGVPZlwiO1xuaW1wb3J0IF9kZWZpbmVQcm9wZXJ0eSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZGVmaW5lUHJvcGVydHlcIjtcblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KCk7IHJldHVybiBmdW5jdGlvbiBfY3JlYXRlU3VwZXJJbnRlcm5hbCgpIHsgdmFyIFN1cGVyID0gX2dldFByb3RvdHlwZU9mKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2YodGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIHJlc3VsdCk7IH07IH1cblxuZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCgpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbmltcG9ydCBSZWFjdCwgeyBjcmVhdGVSZWYsIFB1cmVDb21wb25lbnQgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuaW1wb3J0IG1ha2VDYW5jZWxsYWJsZSBmcm9tICdtYWtlLWNhbmNlbGxhYmxlLXByb21pc2UnO1xuaW1wb3J0IG1lcmdlUmVmcyBmcm9tICdtZXJnZS1yZWZzJztcbmltcG9ydCB3YXJuaW5nIGZyb20gJ3Rpbnktd2FybmluZyc7XG5pbXBvcnQgKiBhcyBwZGZqcyBmcm9tICdwZGZqcy1kaXN0L2J1aWxkL3BkZic7XG5pbXBvcnQgUGFnZUNvbnRleHQgZnJvbSAnLi4vUGFnZUNvbnRleHQnO1xuaW1wb3J0IHsgZ2V0UGl4ZWxSYXRpbywgaXNDYW5jZWxFeGNlcHRpb24sIG1ha2VQYWdlQ2FsbGJhY2sgfSBmcm9tICcuLi9zaGFyZWQvdXRpbHMnO1xuaW1wb3J0IHsgaXNQYWdlLCBpc1JlZiwgaXNSb3RhdGUgfSBmcm9tICcuLi9zaGFyZWQvcHJvcFR5cGVzJztcbnZhciBBTk5PVEFUSU9OX01PREUgPSBwZGZqcy5Bbm5vdGF0aW9uTW9kZTtcbmV4cG9ydCB2YXIgUGFnZUNhbnZhc0ludGVybmFsID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfUHVyZUNvbXBvbmVudCkge1xuICBfaW5oZXJpdHMoUGFnZUNhbnZhc0ludGVybmFsLCBfUHVyZUNvbXBvbmVudCk7XG5cbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlcihQYWdlQ2FudmFzSW50ZXJuYWwpO1xuXG4gIGZ1bmN0aW9uIFBhZ2VDYW52YXNJbnRlcm5hbCgpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgUGFnZUNhbnZhc0ludGVybmFsKTtcblxuICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4pLCBfa2V5ID0gMDsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICB9XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsLmFwcGx5KF9zdXBlciwgW3RoaXNdLmNvbmNhdChhcmdzKSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwiY2FudmFzRWxlbWVudFwiLCAvKiNfX1BVUkVfXyovY3JlYXRlUmVmKCkpO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcIm9uUmVuZGVyU3VjY2Vzc1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICBfdGhpcy5yZW5kZXJlciA9IG51bGw7XG4gICAgICB2YXIgX3RoaXMkcHJvcHMgPSBfdGhpcy5wcm9wcyxcbiAgICAgICAgICBvblJlbmRlclN1Y2Nlc3MgPSBfdGhpcyRwcm9wcy5vblJlbmRlclN1Y2Nlc3MsXG4gICAgICAgICAgcGFnZSA9IF90aGlzJHByb3BzLnBhZ2UsXG4gICAgICAgICAgc2NhbGUgPSBfdGhpcyRwcm9wcy5zY2FsZTtcbiAgICAgIGlmIChvblJlbmRlclN1Y2Nlc3MpIG9uUmVuZGVyU3VjY2VzcyhtYWtlUGFnZUNhbGxiYWNrKHBhZ2UsIHNjYWxlKSk7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25SZW5kZXJFcnJvclwiLCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIGlmIChpc0NhbmNlbEV4Y2VwdGlvbihlcnJvcikpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB3YXJuaW5nKGVycm9yKTtcbiAgICAgIHZhciBvblJlbmRlckVycm9yID0gX3RoaXMucHJvcHMub25SZW5kZXJFcnJvcjtcbiAgICAgIGlmIChvblJlbmRlckVycm9yKSBvblJlbmRlckVycm9yKGVycm9yKTtcbiAgICB9KTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJkcmF3UGFnZU9uQ2FudmFzXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBjYW52YXMgPSBfdGhpcy5jYW52YXNFbGVtZW50LmN1cnJlbnQ7XG5cbiAgICAgIGlmICghY2FudmFzKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICB2YXIgX2Fzc2VydFRoaXNJbml0aWFsaXplID0gX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksXG4gICAgICAgICAgcmVuZGVyVmlld3BvcnQgPSBfYXNzZXJ0VGhpc0luaXRpYWxpemUucmVuZGVyVmlld3BvcnQsXG4gICAgICAgICAgdmlld3BvcnQgPSBfYXNzZXJ0VGhpc0luaXRpYWxpemUudmlld3BvcnQ7XG5cbiAgICAgIHZhciBfdGhpcyRwcm9wczIgPSBfdGhpcy5wcm9wcyxcbiAgICAgICAgICBjYW52YXNCYWNrZ3JvdW5kID0gX3RoaXMkcHJvcHMyLmNhbnZhc0JhY2tncm91bmQsXG4gICAgICAgICAgcGFnZSA9IF90aGlzJHByb3BzMi5wYWdlLFxuICAgICAgICAgIHJlbmRlckZvcm1zID0gX3RoaXMkcHJvcHMyLnJlbmRlckZvcm1zO1xuICAgICAgY2FudmFzLndpZHRoID0gcmVuZGVyVmlld3BvcnQud2lkdGg7XG4gICAgICBjYW52YXMuaGVpZ2h0ID0gcmVuZGVyVmlld3BvcnQuaGVpZ2h0O1xuICAgICAgY2FudmFzLnN0eWxlLndpZHRoID0gXCJcIi5jb25jYXQoTWF0aC5mbG9vcih2aWV3cG9ydC53aWR0aCksIFwicHhcIik7XG4gICAgICBjYW52YXMuc3R5bGUuaGVpZ2h0ID0gXCJcIi5jb25jYXQoTWF0aC5mbG9vcih2aWV3cG9ydC5oZWlnaHQpLCBcInB4XCIpO1xuICAgICAgdmFyIHJlbmRlckNvbnRleHQgPSB7XG4gICAgICAgIGFubm90YXRpb25Nb2RlOiByZW5kZXJGb3JtcyA/IEFOTk9UQVRJT05fTU9ERS5FTkFCTEVfRk9STVMgOiBBTk5PVEFUSU9OX01PREUuRU5BQkxFLFxuXG4gICAgICAgIGdldCBjYW52YXNDb250ZXh0KCkge1xuICAgICAgICAgIHJldHVybiBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgICAgfSxcblxuICAgICAgICB2aWV3cG9ydDogcmVuZGVyVmlld3BvcnRcbiAgICAgIH07XG5cbiAgICAgIGlmIChjYW52YXNCYWNrZ3JvdW5kKSB7XG4gICAgICAgIHJlbmRlckNvbnRleHQuYmFja2dyb3VuZCA9IGNhbnZhc0JhY2tncm91bmQ7XG4gICAgICB9IC8vIElmIGFub3RoZXIgcmVuZGVyIGlzIGluIHByb2dyZXNzLCBsZXQncyBjYW5jZWwgaXRcblxuXG4gICAgICBfdGhpcy5jYW5jZWxSZW5kZXJpbmdUYXNrKCk7XG5cbiAgICAgIF90aGlzLnJlbmRlcmVyID0gbWFrZUNhbmNlbGxhYmxlKHBhZ2UucmVuZGVyKHJlbmRlckNvbnRleHQpLnByb21pc2UpO1xuICAgICAgcmV0dXJuIF90aGlzLnJlbmRlcmVyLnByb21pc2UudGhlbihfdGhpcy5vblJlbmRlclN1Y2Nlc3MpW1wiY2F0Y2hcIl0oX3RoaXMub25SZW5kZXJFcnJvcik7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3MoUGFnZUNhbnZhc0ludGVybmFsLCBbe1xuICAgIGtleTogXCJjb21wb25lbnREaWRNb3VudFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgIHRoaXMuZHJhd1BhZ2VPbkNhbnZhcygpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJjb21wb25lbnREaWRVcGRhdGVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wcykge1xuICAgICAgdmFyIF90aGlzJHByb3BzMyA9IHRoaXMucHJvcHMsXG4gICAgICAgICAgY2FudmFzQmFja2dyb3VuZCA9IF90aGlzJHByb3BzMy5jYW52YXNCYWNrZ3JvdW5kLFxuICAgICAgICAgIHBhZ2UgPSBfdGhpcyRwcm9wczMucGFnZSxcbiAgICAgICAgICByZW5kZXJGb3JtcyA9IF90aGlzJHByb3BzMy5yZW5kZXJGb3JtcztcblxuICAgICAgaWYgKGNhbnZhc0JhY2tncm91bmQgIT09IHByZXZQcm9wcy5jYW52YXNCYWNrZ3JvdW5kIHx8IHJlbmRlckZvcm1zICE9PSBwcmV2UHJvcHMucmVuZGVyRm9ybXMpIHtcbiAgICAgICAgLy8gRW5zdXJlcyB0aGUgY2FudmFzIHdpbGwgYmUgcmUtcmVuZGVyZWQgZnJvbSBzY3JhdGNoLiBPdGhlcndpc2UgYWxsIGZvcm0gZGF0YSB3aWxsIHN0YXkuXG4gICAgICAgIHBhZ2UuY2xlYW51cCgpO1xuICAgICAgICB0aGlzLmRyYXdQYWdlT25DYW52YXMoKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY29tcG9uZW50V2lsbFVubW91bnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICB0aGlzLmNhbmNlbFJlbmRlcmluZ1Rhc2soKTtcbiAgICAgIHZhciBjYW52YXMgPSB0aGlzLmNhbnZhc0VsZW1lbnQuY3VycmVudDtcbiAgICAgIC8qKlxuICAgICAgICogWmVyb2luZyB0aGUgd2lkdGggYW5kIGhlaWdodCBjYXVzZSBtb3N0IGJyb3dzZXJzIHRvIHJlbGVhc2UgZ3JhcGhpY3NcbiAgICAgICAqIHJlc291cmNlcyBpbW1lZGlhdGVseSwgd2hpY2ggY2FuIGdyZWF0bHkgcmVkdWNlIG1lbW9yeSBjb25zdW1wdGlvbi5cbiAgICAgICAqL1xuXG4gICAgICBpZiAoY2FudmFzKSB7XG4gICAgICAgIGNhbnZhcy53aWR0aCA9IDA7XG4gICAgICAgIGNhbnZhcy5oZWlnaHQgPSAwO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJjYW5jZWxSZW5kZXJpbmdUYXNrXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNhbmNlbFJlbmRlcmluZ1Rhc2soKSB7XG4gICAgICBpZiAodGhpcy5yZW5kZXJlcikge1xuICAgICAgICB0aGlzLnJlbmRlcmVyLmNhbmNlbCgpO1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FsbGVkIHdoZW4gYSBwYWdlIGlzIHJlbmRlcmVkIHN1Y2Nlc3NmdWxseS5cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInJlbmRlclZpZXdwb3J0XCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICB2YXIgX3RoaXMkcHJvcHM0ID0gdGhpcy5wcm9wcyxcbiAgICAgICAgICBwYWdlID0gX3RoaXMkcHJvcHM0LnBhZ2UsXG4gICAgICAgICAgcm90YXRlID0gX3RoaXMkcHJvcHM0LnJvdGF0ZSxcbiAgICAgICAgICBzY2FsZSA9IF90aGlzJHByb3BzNC5zY2FsZTtcbiAgICAgIHZhciBwaXhlbFJhdGlvID0gZ2V0UGl4ZWxSYXRpbygpO1xuICAgICAgcmV0dXJuIHBhZ2UuZ2V0Vmlld3BvcnQoe1xuICAgICAgICBzY2FsZTogc2NhbGUgKiBwaXhlbFJhdGlvLFxuICAgICAgICByb3RhdGlvbjogcm90YXRlXG4gICAgICB9KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwidmlld3BvcnRcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHZhciBfdGhpcyRwcm9wczUgPSB0aGlzLnByb3BzLFxuICAgICAgICAgIHBhZ2UgPSBfdGhpcyRwcm9wczUucGFnZSxcbiAgICAgICAgICByb3RhdGUgPSBfdGhpcyRwcm9wczUucm90YXRlLFxuICAgICAgICAgIHNjYWxlID0gX3RoaXMkcHJvcHM1LnNjYWxlO1xuICAgICAgcmV0dXJuIHBhZ2UuZ2V0Vmlld3BvcnQoe1xuICAgICAgICBzY2FsZTogc2NhbGUsXG4gICAgICAgIHJvdGF0aW9uOiByb3RhdGVcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgdmFyIGNhbnZhc1JlZiA9IHRoaXMucHJvcHMuY2FudmFzUmVmO1xuICAgICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIsIHtcbiAgICAgICAgY2xhc3NOYW1lOiBcInJlYWN0LXBkZl9fUGFnZV9fY2FudmFzXCIsXG4gICAgICAgIGRpcjogXCJsdHJcIixcbiAgICAgICAgcmVmOiBtZXJnZVJlZnMoY2FudmFzUmVmLCB0aGlzLmNhbnZhc0VsZW1lbnQpLFxuICAgICAgICBzdHlsZToge1xuICAgICAgICAgIGRpc3BsYXk6ICdibG9jaycsXG4gICAgICAgICAgdXNlclNlbGVjdDogJ25vbmUnXG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBQYWdlQ2FudmFzSW50ZXJuYWw7XG59KFB1cmVDb21wb25lbnQpO1xuUGFnZUNhbnZhc0ludGVybmFsLnByb3BUeXBlcyA9IHtcbiAgY2FudmFzQmFja2dyb3VuZDogUHJvcFR5cGVzLnN0cmluZyxcbiAgY2FudmFzUmVmOiBpc1JlZixcbiAgb25SZW5kZXJFcnJvcjogUHJvcFR5cGVzLmZ1bmMsXG4gIG9uUmVuZGVyU3VjY2VzczogUHJvcFR5cGVzLmZ1bmMsXG4gIHBhZ2U6IGlzUGFnZS5pc1JlcXVpcmVkLFxuICByZW5kZXJGb3JtczogUHJvcFR5cGVzLmJvb2wsXG4gIHJvdGF0ZTogaXNSb3RhdGUsXG4gIHNjYWxlOiBQcm9wVHlwZXMubnVtYmVyLmlzUmVxdWlyZWRcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBQYWdlQ2FudmFzKHByb3BzKSB7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChQYWdlQ29udGV4dC5Db25zdW1lciwgbnVsbCwgZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoUGFnZUNhbnZhc0ludGVybmFsLCBfZXh0ZW5kcyh7fSwgY29udGV4dCwgcHJvcHMpKTtcbiAgfSk7XG59IiwiaW1wb3J0IF9leHRlbmRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9leHRlbmRzXCI7XG5pbXBvcnQgX2NsYXNzQ2FsbENoZWNrIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jbGFzc0NhbGxDaGVja1wiO1xuaW1wb3J0IF9jcmVhdGVDbGFzcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY3JlYXRlQ2xhc3NcIjtcbmltcG9ydCBfYXNzZXJ0VGhpc0luaXRpYWxpemVkIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9hc3NlcnRUaGlzSW5pdGlhbGl6ZWRcIjtcbmltcG9ydCBfaW5oZXJpdHMgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2luaGVyaXRzXCI7XG5pbXBvcnQgX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4gZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5cIjtcbmltcG9ydCBfZ2V0UHJvdG90eXBlT2YgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2dldFByb3RvdHlwZU9mXCI7XG5pbXBvcnQgX2RlZmluZVByb3BlcnR5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9kZWZpbmVQcm9wZXJ0eVwiO1xuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2YoRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZih0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxuaW1wb3J0IFJlYWN0LCB7IFB1cmVDb21wb25lbnQgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuaW1wb3J0IHdhcm5pbmcgZnJvbSAndGlueS13YXJuaW5nJztcbmltcG9ydCAqIGFzIHBkZmpzIGZyb20gJ3BkZmpzLWRpc3QvYnVpbGQvcGRmJztcbmltcG9ydCBQYWdlQ29udGV4dCBmcm9tICcuLi9QYWdlQ29udGV4dCc7XG5pbXBvcnQgeyBpc0NhbmNlbEV4Y2VwdGlvbiwgbWFrZVBhZ2VDYWxsYmFjayB9IGZyb20gJy4uL3NoYXJlZC91dGlscyc7XG5pbXBvcnQgeyBpc1BhZ2UsIGlzUm90YXRlIH0gZnJvbSAnLi4vc2hhcmVkL3Byb3BUeXBlcyc7XG5leHBvcnQgdmFyIFBhZ2VTVkdJbnRlcm5hbCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX1B1cmVDb21wb25lbnQpIHtcbiAgX2luaGVyaXRzKFBhZ2VTVkdJbnRlcm5hbCwgX1B1cmVDb21wb25lbnQpO1xuXG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIoUGFnZVNWR0ludGVybmFsKTtcblxuICBmdW5jdGlvbiBQYWdlU1ZHSW50ZXJuYWwoKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFBhZ2VTVkdJbnRlcm5hbCk7XG5cbiAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgIGFyZ3NbX2tleV0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgfVxuXG4gICAgX3RoaXMgPSBfc3VwZXIuY2FsbC5hcHBseShfc3VwZXIsIFt0aGlzXS5jb25jYXQoYXJncykpO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcInN0YXRlXCIsIHtcbiAgICAgIHN2ZzogbnVsbFxuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcIm9uUmVuZGVyU3VjY2Vzc1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICBfdGhpcy5yZW5kZXJlciA9IG51bGw7XG4gICAgICB2YXIgX3RoaXMkcHJvcHMgPSBfdGhpcy5wcm9wcyxcbiAgICAgICAgICBvblJlbmRlclN1Y2Nlc3MgPSBfdGhpcyRwcm9wcy5vblJlbmRlclN1Y2Nlc3MsXG4gICAgICAgICAgcGFnZSA9IF90aGlzJHByb3BzLnBhZ2UsXG4gICAgICAgICAgc2NhbGUgPSBfdGhpcyRwcm9wcy5zY2FsZTtcbiAgICAgIGlmIChvblJlbmRlclN1Y2Nlc3MpIG9uUmVuZGVyU3VjY2VzcyhtYWtlUGFnZUNhbGxiYWNrKHBhZ2UsIHNjYWxlKSk7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25SZW5kZXJFcnJvclwiLCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIGlmIChpc0NhbmNlbEV4Y2VwdGlvbihlcnJvcikpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB3YXJuaW5nKGVycm9yKTtcbiAgICAgIHZhciBvblJlbmRlckVycm9yID0gX3RoaXMucHJvcHMub25SZW5kZXJFcnJvcjtcbiAgICAgIGlmIChvblJlbmRlckVycm9yKSBvblJlbmRlckVycm9yKGVycm9yKTtcbiAgICB9KTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJyZW5kZXJTVkdcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIHBhZ2UgPSBfdGhpcy5wcm9wcy5wYWdlO1xuICAgICAgX3RoaXMucmVuZGVyZXIgPSBwYWdlLmdldE9wZXJhdG9yTGlzdCgpO1xuICAgICAgcmV0dXJuIF90aGlzLnJlbmRlcmVyLnRoZW4oZnVuY3Rpb24gKG9wZXJhdG9yTGlzdCkge1xuICAgICAgICB2YXIgc3ZnR2Z4ID0gbmV3IHBkZmpzLlNWR0dyYXBoaWNzKHBhZ2UuY29tbW9uT2JqcywgcGFnZS5vYmpzKTtcbiAgICAgICAgX3RoaXMucmVuZGVyZXIgPSBzdmdHZnguZ2V0U1ZHKG9wZXJhdG9yTGlzdCwgX3RoaXMudmlld3BvcnQpLnRoZW4oZnVuY3Rpb24gKHN2Zykge1xuICAgICAgICAgIF90aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHN2Zzogc3ZnXG4gICAgICAgICAgfSwgX3RoaXMub25SZW5kZXJTdWNjZXNzKTtcbiAgICAgICAgfSlbXCJjYXRjaFwiXShfdGhpcy5vblJlbmRlckVycm9yKTtcbiAgICAgIH0pW1wiY2F0Y2hcIl0oX3RoaXMub25SZW5kZXJFcnJvcik7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwiZHJhd1BhZ2VPbkNvbnRhaW5lclwiLCBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgdmFyIHN2ZyA9IF90aGlzLnN0YXRlLnN2ZztcblxuICAgICAgaWYgKCFlbGVtZW50IHx8ICFzdmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSAvLyBBcHBlbmQgU1ZHIGVsZW1lbnQgdG8gdGhlIG1haW4gY29udGFpbmVyLCBpZiB0aGlzIGhhc24ndCBiZWVuIGRvbmUgYWxyZWFkeVxuXG5cbiAgICAgIGlmICghZWxlbWVudC5maXJzdEVsZW1lbnRDaGlsZCkge1xuICAgICAgICBlbGVtZW50LmFwcGVuZENoaWxkKHN2Zyk7XG4gICAgICB9XG5cbiAgICAgIHZhciBfdGhpcyR2aWV3cG9ydCA9IF90aGlzLnZpZXdwb3J0LFxuICAgICAgICAgIHdpZHRoID0gX3RoaXMkdmlld3BvcnQud2lkdGgsXG4gICAgICAgICAgaGVpZ2h0ID0gX3RoaXMkdmlld3BvcnQuaGVpZ2h0O1xuICAgICAgc3ZnLnNldEF0dHJpYnV0ZSgnd2lkdGgnLCB3aWR0aCk7XG4gICAgICBzdmcuc2V0QXR0cmlidXRlKCdoZWlnaHQnLCBoZWlnaHQpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzKFBhZ2VTVkdJbnRlcm5hbCwgW3tcbiAgICBrZXk6IFwiY29tcG9uZW50RGlkTW91bnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICB0aGlzLnJlbmRlclNWRygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYWxsZWQgd2hlbiBhIHBhZ2UgaXMgcmVuZGVyZWQgc3VjY2Vzc2Z1bGx5LlxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwidmlld3BvcnRcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHZhciBfdGhpcyRwcm9wczIgPSB0aGlzLnByb3BzLFxuICAgICAgICAgIHBhZ2UgPSBfdGhpcyRwcm9wczIucGFnZSxcbiAgICAgICAgICByb3RhdGUgPSBfdGhpcyRwcm9wczIucm90YXRlLFxuICAgICAgICAgIHNjYWxlID0gX3RoaXMkcHJvcHMyLnNjYWxlO1xuICAgICAgcmV0dXJuIHBhZ2UuZ2V0Vmlld3BvcnQoe1xuICAgICAgICBzY2FsZTogc2NhbGUsXG4gICAgICAgIHJvdGF0aW9uOiByb3RhdGVcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgIHZhciBfdGhpcyR2aWV3cG9ydDIgPSB0aGlzLnZpZXdwb3J0LFxuICAgICAgICAgIHdpZHRoID0gX3RoaXMkdmlld3BvcnQyLndpZHRoLFxuICAgICAgICAgIGhlaWdodCA9IF90aGlzJHZpZXdwb3J0Mi5oZWlnaHQ7XG4gICAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgICAgICBjbGFzc05hbWU6IFwicmVhY3QtcGRmX19QYWdlX19zdmdcIiAvLyBOb3RlOiBUaGlzIGNhbm5vdCBiZSBzaG9ydGVuZWQsIGFzIHdlIG5lZWQgdGhpcyBmdW5jdGlvbiB0byBiZSBjYWxsZWQgd2l0aCBlYWNoIHJlbmRlci5cbiAgICAgICAgLFxuICAgICAgICByZWY6IGZ1bmN0aW9uIHJlZihfcmVmKSB7XG4gICAgICAgICAgcmV0dXJuIF90aGlzMi5kcmF3UGFnZU9uQ29udGFpbmVyKF9yZWYpO1xuICAgICAgICB9LFxuICAgICAgICBzdHlsZToge1xuICAgICAgICAgIGRpc3BsYXk6ICdibG9jaycsXG4gICAgICAgICAgYmFja2dyb3VuZENvbG9yOiAnd2hpdGUnLFxuICAgICAgICAgIG92ZXJmbG93OiAnaGlkZGVuJyxcbiAgICAgICAgICB3aWR0aDogd2lkdGgsXG4gICAgICAgICAgaGVpZ2h0OiBoZWlnaHQsXG4gICAgICAgICAgdXNlclNlbGVjdDogJ25vbmUnXG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBQYWdlU1ZHSW50ZXJuYWw7XG59KFB1cmVDb21wb25lbnQpO1xuUGFnZVNWR0ludGVybmFsLnByb3BUeXBlcyA9IHtcbiAgb25SZW5kZXJFcnJvcjogUHJvcFR5cGVzLmZ1bmMsXG4gIG9uUmVuZGVyU3VjY2VzczogUHJvcFR5cGVzLmZ1bmMsXG4gIHBhZ2U6IGlzUGFnZS5pc1JlcXVpcmVkLFxuICByb3RhdGU6IGlzUm90YXRlLFxuICBzY2FsZTogUHJvcFR5cGVzLm51bWJlci5pc1JlcXVpcmVkXG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUGFnZVNWRyhwcm9wcykge1xuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoUGFnZUNvbnRleHQuQ29uc3VtZXIsIG51bGwsIGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFBhZ2VTVkdJbnRlcm5hbCwgX2V4dGVuZHMoe30sIGNvbnRleHQsIHByb3BzKSk7XG4gIH0pO1xufSIsImltcG9ydCBfZXh0ZW5kcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZXh0ZW5kc1wiO1xuaW1wb3J0IF9jbGFzc0NhbGxDaGVjayBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY2xhc3NDYWxsQ2hlY2tcIjtcbmltcG9ydCBfY3JlYXRlQ2xhc3MgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NyZWF0ZUNsYXNzXCI7XG5pbXBvcnQgX2Fzc2VydFRoaXNJbml0aWFsaXplZCBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vYXNzZXJ0VGhpc0luaXRpYWxpemVkXCI7XG5pbXBvcnQgX2luaGVyaXRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pbmhlcml0c1wiO1xuaW1wb3J0IF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuXCI7XG5pbXBvcnQgX2dldFByb3RvdHlwZU9mIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9nZXRQcm90b3R5cGVPZlwiO1xuaW1wb3J0IF9kZWZpbmVQcm9wZXJ0eSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZGVmaW5lUHJvcGVydHlcIjtcblxuZnVuY3Rpb24gb3duS2V5cyhvYmplY3QsIGVudW1lcmFibGVPbmx5KSB7IHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqZWN0KTsgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHsgdmFyIHN5bWJvbHMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKG9iamVjdCk7IGVudW1lcmFibGVPbmx5ICYmIChzeW1ib2xzID0gc3ltYm9scy5maWx0ZXIoZnVuY3Rpb24gKHN5bSkgeyByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmplY3QsIHN5bSkuZW51bWVyYWJsZTsgfSkpLCBrZXlzLnB1c2guYXBwbHkoa2V5cywgc3ltYm9scyk7IH0gcmV0dXJuIGtleXM7IH1cblxuZnVuY3Rpb24gX29iamVjdFNwcmVhZCh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IG51bGwgIT0gYXJndW1lbnRzW2ldID8gYXJndW1lbnRzW2ldIDoge307IGkgJSAyID8gb3duS2V5cyhPYmplY3Qoc291cmNlKSwgITApLmZvckVhY2goZnVuY3Rpb24gKGtleSkgeyBfZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHNvdXJjZVtrZXldKTsgfSkgOiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyA/IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoc291cmNlKSkgOiBvd25LZXlzKE9iamVjdChzb3VyY2UpKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHNvdXJjZSwga2V5KSk7IH0pOyB9IHJldHVybiB0YXJnZXQ7IH1cblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KCk7IHJldHVybiBmdW5jdGlvbiBfY3JlYXRlU3VwZXJJbnRlcm5hbCgpIHsgdmFyIFN1cGVyID0gX2dldFByb3RvdHlwZU9mKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2YodGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIHJlc3VsdCk7IH07IH1cblxuZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCgpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbmltcG9ydCBSZWFjdCwgeyBjcmVhdGVSZWYsIFB1cmVDb21wb25lbnQgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyByZW5kZXJUb1N0YXRpY01hcmt1cCB9IGZyb20gJ3JlYWN0LWRvbS9zZXJ2ZXInO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcbmltcG9ydCBtYWtlQ2FuY2VsbGFibGUgZnJvbSAnbWFrZS1jYW5jZWxsYWJsZS1wcm9taXNlJztcbmltcG9ydCBpbnZhcmlhbnQgZnJvbSAndGlueS1pbnZhcmlhbnQnO1xuaW1wb3J0IHdhcm5pbmcgZnJvbSAndGlueS13YXJuaW5nJztcbmltcG9ydCAqIGFzIHBkZmpzIGZyb20gJ3BkZmpzLWRpc3QvYnVpbGQvcGRmJztcbmltcG9ydCBQYWdlQ29udGV4dCBmcm9tICcuLi9QYWdlQ29udGV4dCc7XG5pbXBvcnQgeyBjYW5jZWxSdW5uaW5nVGFzayB9IGZyb20gJy4uL3NoYXJlZC91dGlscyc7XG5pbXBvcnQgeyBpc1BhZ2UsIGlzUm90YXRlIH0gZnJvbSAnLi4vc2hhcmVkL3Byb3BUeXBlcyc7XG5leHBvcnQgdmFyIFRleHRMYXllckludGVybmFsID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfUHVyZUNvbXBvbmVudCkge1xuICBfaW5oZXJpdHMoVGV4dExheWVySW50ZXJuYWwsIF9QdXJlQ29tcG9uZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyKFRleHRMYXllckludGVybmFsKTtcblxuICBmdW5jdGlvbiBUZXh0TGF5ZXJJbnRlcm5hbCgpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgVGV4dExheWVySW50ZXJuYWwpO1xuXG4gICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICAgIH1cblxuICAgIF90aGlzID0gX3N1cGVyLmNhbGwuYXBwbHkoX3N1cGVyLCBbdGhpc10uY29uY2F0KGFyZ3MpKTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJzdGF0ZVwiLCB7XG4gICAgICB0ZXh0Q29udGVudDogbnVsbFxuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcImxheWVyRWxlbWVudFwiLCAvKiNfX1BVUkVfXyovY3JlYXRlUmVmKCkpO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcImxvYWRUZXh0Q29udGVudFwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgcGFnZSA9IF90aGlzLnByb3BzLnBhZ2U7XG4gICAgICB2YXIgY2FuY2VsbGFibGUgPSBtYWtlQ2FuY2VsbGFibGUocGFnZS5nZXRUZXh0Q29udGVudCgpKTtcbiAgICAgIF90aGlzLnJ1bm5pbmdUYXNrID0gY2FuY2VsbGFibGU7XG4gICAgICBjYW5jZWxsYWJsZS5wcm9taXNlLnRoZW4oZnVuY3Rpb24gKHRleHRDb250ZW50KSB7XG4gICAgICAgIF90aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICB0ZXh0Q29udGVudDogdGV4dENvbnRlbnRcbiAgICAgICAgfSwgX3RoaXMub25Mb2FkU3VjY2Vzcyk7XG4gICAgICB9KVtcImNhdGNoXCJdKGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICBfdGhpcy5vbkxvYWRFcnJvcihlcnJvcik7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJvbkxvYWRTdWNjZXNzXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBvbkdldFRleHRTdWNjZXNzID0gX3RoaXMucHJvcHMub25HZXRUZXh0U3VjY2VzcztcbiAgICAgIHZhciB0ZXh0Q29udGVudCA9IF90aGlzLnN0YXRlLnRleHRDb250ZW50O1xuICAgICAgaWYgKG9uR2V0VGV4dFN1Y2Nlc3MpIG9uR2V0VGV4dFN1Y2Nlc3ModGV4dENvbnRlbnQpO1xuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcIm9uTG9hZEVycm9yXCIsIGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgX3RoaXMuc2V0U3RhdGUoe1xuICAgICAgICB0ZXh0SXRlbXM6IGZhbHNlXG4gICAgICB9KTtcblxuICAgICAgd2FybmluZyhlcnJvcik7XG4gICAgICB2YXIgb25HZXRUZXh0RXJyb3IgPSBfdGhpcy5wcm9wcy5vbkdldFRleHRFcnJvcjtcbiAgICAgIGlmIChvbkdldFRleHRFcnJvcikgb25HZXRUZXh0RXJyb3IoZXJyb3IpO1xuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcIm9uUmVuZGVyU3VjY2Vzc1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgb25SZW5kZXJUZXh0TGF5ZXJTdWNjZXNzID0gX3RoaXMucHJvcHMub25SZW5kZXJUZXh0TGF5ZXJTdWNjZXNzO1xuICAgICAgaWYgKG9uUmVuZGVyVGV4dExheWVyU3VjY2Vzcykgb25SZW5kZXJUZXh0TGF5ZXJTdWNjZXNzKCk7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25SZW5kZXJFcnJvclwiLCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIHdhcm5pbmcoZXJyb3IpO1xuICAgICAgdmFyIG9uUmVuZGVyVGV4dExheWVyRXJyb3IgPSBfdGhpcy5wcm9wcy5vblJlbmRlclRleHRMYXllckVycm9yO1xuICAgICAgaWYgKG9uUmVuZGVyVGV4dExheWVyRXJyb3IpIG9uUmVuZGVyVGV4dExheWVyRXJyb3IoZXJyb3IpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzKFRleHRMYXllckludGVybmFsLCBbe1xuICAgIGtleTogXCJjb21wb25lbnREaWRNb3VudFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgIHZhciBwYWdlID0gdGhpcy5wcm9wcy5wYWdlO1xuICAgICAgaW52YXJpYW50KHBhZ2UsICdBdHRlbXB0ZWQgdG8gbG9hZCBwYWdlIHRleHQgY29udGVudCwgYnV0IG5vIHBhZ2Ugd2FzIHNwZWNpZmllZC4nKTtcbiAgICAgIHRoaXMubG9hZFRleHRDb250ZW50KCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNvbXBvbmVudERpZFVwZGF0ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnREaWRVcGRhdGUocHJldlByb3BzKSB7XG4gICAgICB2YXIgcGFnZSA9IHRoaXMucHJvcHMucGFnZTtcblxuICAgICAgaWYgKHByZXZQcm9wcy5wYWdlICYmIHBhZ2UgIT09IHByZXZQcm9wcy5wYWdlKSB7XG4gICAgICAgIHRoaXMubG9hZFRleHRDb250ZW50KCk7XG4gICAgICB9XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNvbXBvbmVudFdpbGxVbm1vdW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgY2FuY2VsUnVubmluZ1Rhc2sodGhpcy5ydW5uaW5nVGFzayk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInZpZXdwb3J0XCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICB2YXIgX3RoaXMkcHJvcHMgPSB0aGlzLnByb3BzLFxuICAgICAgICAgIHBhZ2UgPSBfdGhpcyRwcm9wcy5wYWdlLFxuICAgICAgICAgIHJvdGF0ZSA9IF90aGlzJHByb3BzLnJvdGF0ZSxcbiAgICAgICAgICBzY2FsZSA9IF90aGlzJHByb3BzLnNjYWxlO1xuICAgICAgcmV0dXJuIHBhZ2UuZ2V0Vmlld3BvcnQoe1xuICAgICAgICBzY2FsZTogc2NhbGUsXG4gICAgICAgIHJvdGF0aW9uOiByb3RhdGVcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJ1bnJvdGF0ZWRWaWV3cG9ydFwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgdmFyIF90aGlzJHByb3BzMiA9IHRoaXMucHJvcHMsXG4gICAgICAgICAgcGFnZSA9IF90aGlzJHByb3BzMi5wYWdlLFxuICAgICAgICAgIHNjYWxlID0gX3RoaXMkcHJvcHMyLnNjYWxlO1xuICAgICAgcmV0dXJuIHBhZ2UuZ2V0Vmlld3BvcnQoe1xuICAgICAgICBzY2FsZTogc2NhbGVcbiAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdCBtaWdodCBoYXBwZW4gdGhhdCB0aGUgcGFnZSBpcyByb3RhdGVkIGJ5IGRlZmF1bHQuIEluIHN1Y2ggY2FzZXMsIHdlIHNob3VsZG4ndCByb3RhdGVcbiAgICAgKiB0ZXh0IGNvbnRlbnQuXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJyb3RhdGVcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHZhciBfdGhpcyRwcm9wczMgPSB0aGlzLnByb3BzLFxuICAgICAgICAgIHBhZ2UgPSBfdGhpcyRwcm9wczMucGFnZSxcbiAgICAgICAgICByb3RhdGUgPSBfdGhpcyRwcm9wczMucm90YXRlO1xuICAgICAgcmV0dXJuIHJvdGF0ZSAtIHBhZ2Uucm90YXRlO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJUZXh0TGF5ZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyVGV4dExheWVyKCkge1xuICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgIHZhciB0ZXh0Q29udGVudCA9IHRoaXMuc3RhdGUudGV4dENvbnRlbnQ7XG5cbiAgICAgIGlmICghdGV4dENvbnRlbnQpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIHZhciB2aWV3cG9ydCA9IHRoaXMudmlld3BvcnQ7XG4gICAgICB2YXIgX3RoaXMkcHJvcHM0ID0gdGhpcy5wcm9wcyxcbiAgICAgICAgICBjdXN0b21UZXh0UmVuZGVyZXIgPSBfdGhpcyRwcm9wczQuY3VzdG9tVGV4dFJlbmRlcmVyLFxuICAgICAgICAgIGVuaGFuY2VUZXh0U2VsZWN0aW9uID0gX3RoaXMkcHJvcHM0LmVuaGFuY2VUZXh0U2VsZWN0aW9uOyAvLyBJZiBhbm90aGVyIHJlbmRlcmluZyBpcyBpbiBwcm9ncmVzcywgbGV0J3MgY2FuY2VsIGl0XG5cbiAgICAgIGNhbmNlbFJ1bm5pbmdUYXNrKHRoaXMucnVubmluZ1Rhc2spO1xuICAgICAgdmFyIHBhcmFtZXRlcnMgPSB7XG4gICAgICAgIGNvbnRhaW5lcjogdGhpcy5sYXllckVsZW1lbnQuY3VycmVudCxcbiAgICAgICAgZW5oYW5jZVRleHRTZWxlY3Rpb246IGVuaGFuY2VUZXh0U2VsZWN0aW9uLFxuICAgICAgICB0ZXh0Q29udGVudDogdGV4dENvbnRlbnQsXG4gICAgICAgIHZpZXdwb3J0OiB2aWV3cG9ydFxuICAgICAgfTtcbiAgICAgIHRoaXMubGF5ZXJFbGVtZW50LmN1cnJlbnQuaW5uZXJIVE1MID0gJyc7XG4gICAgICB0aGlzLnJ1bm5pbmdUYXNrID0gcGRmanMucmVuZGVyVGV4dExheWVyKHBhcmFtZXRlcnMpO1xuICAgICAgdmFyIGNhbmNlbGxhYmxlID0gbWFrZUNhbmNlbGxhYmxlKHRoaXMucnVubmluZ1Rhc2sucHJvbWlzZSk7XG4gICAgICB0aGlzLnJ1bm5pbmdUYXNrID0gY2FuY2VsbGFibGU7XG4gICAgICBjYW5jZWxsYWJsZS5wcm9taXNlLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoY3VzdG9tVGV4dFJlbmRlcmVyKSB7XG4gICAgICAgICAgQXJyYXkuZnJvbShfdGhpczIubGF5ZXJFbGVtZW50LmN1cnJlbnQuY2hpbGRyZW4pLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQsIGVsZW1lbnRJbmRleCkge1xuICAgICAgICAgICAgdmFyIHJlYWN0Q29udGVudCA9IGN1c3RvbVRleHRSZW5kZXJlcihfb2JqZWN0U3ByZWFkKHtcbiAgICAgICAgICAgICAgaXRlbUluZGV4OiBlbGVtZW50SW5kZXhcbiAgICAgICAgICAgIH0sIHRleHRDb250ZW50Lml0ZW1zW2VsZW1lbnRJbmRleF0pKTtcbiAgICAgICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gcmVuZGVyVG9TdGF0aWNNYXJrdXAocmVhY3RDb250ZW50KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIF90aGlzMi5vblJlbmRlclN1Y2Nlc3MoKTtcbiAgICAgIH0pW1wiY2F0Y2hcIl0oZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIF90aGlzMi5vblJlbmRlckVycm9yKGVycm9yKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICAgICAgY2xhc3NOYW1lOiBcInJlYWN0LXBkZl9fUGFnZV9fdGV4dENvbnRlbnQgdGV4dExheWVyXCIsXG4gICAgICAgIHJlZjogdGhpcy5sYXllckVsZW1lbnRcbiAgICAgIH0sIHRoaXMucmVuZGVyVGV4dExheWVyKCkpO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBUZXh0TGF5ZXJJbnRlcm5hbDtcbn0oUHVyZUNvbXBvbmVudCk7XG5UZXh0TGF5ZXJJbnRlcm5hbC5kZWZhdWx0UHJvcHMgPSB7XG4gIGVuaGFuY2VUZXh0U2VsZWN0aW9uOiB0cnVlXG59O1xuVGV4dExheWVySW50ZXJuYWwucHJvcFR5cGVzID0ge1xuICBjdXN0b21UZXh0UmVuZGVyZXI6IFByb3BUeXBlcy5mdW5jLFxuICBlbmhhbmNlVGV4dFNlbGVjdGlvbjogUHJvcFR5cGVzLmJvb2wsXG4gIG9uR2V0VGV4dEVycm9yOiBQcm9wVHlwZXMuZnVuYyxcbiAgb25HZXRUZXh0U3VjY2VzczogUHJvcFR5cGVzLmZ1bmMsXG4gIG9uUmVuZGVyVGV4dExheWVyRXJyb3I6IFByb3BUeXBlcy5mdW5jLFxuICBvblJlbmRlclRleHRMYXllclN1Y2Nlc3M6IFByb3BUeXBlcy5mdW5jLFxuICBwYWdlOiBpc1BhZ2UuaXNSZXF1aXJlZCxcbiAgcm90YXRlOiBpc1JvdGF0ZSxcbiAgc2NhbGU6IFByb3BUeXBlcy5udW1iZXJcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBUZXh0TGF5ZXIocHJvcHMpIHtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFBhZ2VDb250ZXh0LkNvbnN1bWVyLCBudWxsLCBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChUZXh0TGF5ZXJJbnRlcm5hbCwgX2V4dGVuZHMoe30sIGNvbnRleHQsIHByb3BzKSk7XG4gIH0pO1xufSIsImltcG9ydCBfZXh0ZW5kcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZXh0ZW5kc1wiO1xuaW1wb3J0IF9jbGFzc0NhbGxDaGVjayBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY2xhc3NDYWxsQ2hlY2tcIjtcbmltcG9ydCBfY3JlYXRlQ2xhc3MgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NyZWF0ZUNsYXNzXCI7XG5pbXBvcnQgX2Fzc2VydFRoaXNJbml0aWFsaXplZCBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vYXNzZXJ0VGhpc0luaXRpYWxpemVkXCI7XG5pbXBvcnQgX2luaGVyaXRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pbmhlcml0c1wiO1xuaW1wb3J0IF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuXCI7XG5pbXBvcnQgX2dldFByb3RvdHlwZU9mIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9nZXRQcm90b3R5cGVPZlwiO1xuaW1wb3J0IF9kZWZpbmVQcm9wZXJ0eSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZGVmaW5lUHJvcGVydHlcIjtcblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KCk7IHJldHVybiBmdW5jdGlvbiBfY3JlYXRlU3VwZXJJbnRlcm5hbCgpIHsgdmFyIFN1cGVyID0gX2dldFByb3RvdHlwZU9mKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2YodGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIHJlc3VsdCk7IH07IH1cblxuZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCgpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbmltcG9ydCBSZWFjdCwgeyBjcmVhdGVSZWYsIFB1cmVDb21wb25lbnQgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuaW1wb3J0IG1ha2VDYW5jZWxsYWJsZSBmcm9tICdtYWtlLWNhbmNlbGxhYmxlLXByb21pc2UnO1xuaW1wb3J0IGludmFyaWFudCBmcm9tICd0aW55LWludmFyaWFudCc7XG5pbXBvcnQgd2FybmluZyBmcm9tICd0aW55LXdhcm5pbmcnO1xuaW1wb3J0ICogYXMgcGRmanMgZnJvbSAncGRmanMtZGlzdC9idWlsZC9wZGYnO1xuaW1wb3J0IERvY3VtZW50Q29udGV4dCBmcm9tICcuLi9Eb2N1bWVudENvbnRleHQnO1xuaW1wb3J0IFBhZ2VDb250ZXh0IGZyb20gJy4uL1BhZ2VDb250ZXh0JztcbmltcG9ydCB7IGNhbmNlbFJ1bm5pbmdUYXNrIH0gZnJvbSAnLi4vc2hhcmVkL3V0aWxzJztcbmltcG9ydCB7IGlzTGlua1NlcnZpY2UsIGlzUGFnZSwgaXNSb3RhdGUgfSBmcm9tICcuLi9zaGFyZWQvcHJvcFR5cGVzJztcbmV4cG9ydCB2YXIgQW5ub3RhdGlvbkxheWVySW50ZXJuYWwgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9QdXJlQ29tcG9uZW50KSB7XG4gIF9pbmhlcml0cyhBbm5vdGF0aW9uTGF5ZXJJbnRlcm5hbCwgX1B1cmVDb21wb25lbnQpO1xuXG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIoQW5ub3RhdGlvbkxheWVySW50ZXJuYWwpO1xuXG4gIGZ1bmN0aW9uIEFubm90YXRpb25MYXllckludGVybmFsKCkge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBBbm5vdGF0aW9uTGF5ZXJJbnRlcm5hbCk7XG5cbiAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgIGFyZ3NbX2tleV0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgfVxuXG4gICAgX3RoaXMgPSBfc3VwZXIuY2FsbC5hcHBseShfc3VwZXIsIFt0aGlzXS5jb25jYXQoYXJncykpO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcInN0YXRlXCIsIHtcbiAgICAgIGFubm90YXRpb25zOiBudWxsXG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwibGF5ZXJFbGVtZW50XCIsIC8qI19fUFVSRV9fKi9jcmVhdGVSZWYoKSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwibG9hZEFubm90YXRpb25zXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBwYWdlID0gX3RoaXMucHJvcHMucGFnZTtcbiAgICAgIHZhciBjYW5jZWxsYWJsZSA9IG1ha2VDYW5jZWxsYWJsZShwYWdlLmdldEFubm90YXRpb25zKCkpO1xuICAgICAgX3RoaXMucnVubmluZ1Rhc2sgPSBjYW5jZWxsYWJsZTtcbiAgICAgIGNhbmNlbGxhYmxlLnByb21pc2UudGhlbihmdW5jdGlvbiAoYW5ub3RhdGlvbnMpIHtcbiAgICAgICAgX3RoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIGFubm90YXRpb25zOiBhbm5vdGF0aW9uc1xuICAgICAgICB9LCBfdGhpcy5vbkxvYWRTdWNjZXNzKTtcbiAgICAgIH0pW1wiY2F0Y2hcIl0oZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIF90aGlzLm9uTG9hZEVycm9yKGVycm9yKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcIm9uTG9hZFN1Y2Nlc3NcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIG9uR2V0QW5ub3RhdGlvbnNTdWNjZXNzID0gX3RoaXMucHJvcHMub25HZXRBbm5vdGF0aW9uc1N1Y2Nlc3M7XG4gICAgICB2YXIgYW5ub3RhdGlvbnMgPSBfdGhpcy5zdGF0ZS5hbm5vdGF0aW9ucztcbiAgICAgIGlmIChvbkdldEFubm90YXRpb25zU3VjY2Vzcykgb25HZXRBbm5vdGF0aW9uc1N1Y2Nlc3MoYW5ub3RhdGlvbnMpO1xuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcIm9uTG9hZEVycm9yXCIsIGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgX3RoaXMuc2V0U3RhdGUoe1xuICAgICAgICBhbm5vdGF0aW9uczogZmFsc2VcbiAgICAgIH0pO1xuXG4gICAgICB3YXJuaW5nKGVycm9yKTtcbiAgICAgIHZhciBvbkdldEFubm90YXRpb25zRXJyb3IgPSBfdGhpcy5wcm9wcy5vbkdldEFubm90YXRpb25zRXJyb3I7XG4gICAgICBpZiAob25HZXRBbm5vdGF0aW9uc0Vycm9yKSBvbkdldEFubm90YXRpb25zRXJyb3IoZXJyb3IpO1xuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcIm9uUmVuZGVyU3VjY2Vzc1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgb25SZW5kZXJBbm5vdGF0aW9uTGF5ZXJTdWNjZXNzID0gX3RoaXMucHJvcHMub25SZW5kZXJBbm5vdGF0aW9uTGF5ZXJTdWNjZXNzO1xuICAgICAgaWYgKG9uUmVuZGVyQW5ub3RhdGlvbkxheWVyU3VjY2Vzcykgb25SZW5kZXJBbm5vdGF0aW9uTGF5ZXJTdWNjZXNzKCk7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25SZW5kZXJFcnJvclwiLCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIHdhcm5pbmcoZXJyb3IpO1xuICAgICAgdmFyIG9uUmVuZGVyQW5ub3RhdGlvbkxheWVyRXJyb3IgPSBfdGhpcy5wcm9wcy5vblJlbmRlckFubm90YXRpb25MYXllckVycm9yO1xuICAgICAgaWYgKG9uUmVuZGVyQW5ub3RhdGlvbkxheWVyRXJyb3IpIG9uUmVuZGVyQW5ub3RhdGlvbkxheWVyRXJyb3IoZXJyb3IpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzKEFubm90YXRpb25MYXllckludGVybmFsLCBbe1xuICAgIGtleTogXCJjb21wb25lbnREaWRNb3VudFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgIHZhciBwYWdlID0gdGhpcy5wcm9wcy5wYWdlO1xuICAgICAgaW52YXJpYW50KHBhZ2UsICdBdHRlbXB0ZWQgdG8gbG9hZCBwYWdlIGFubm90YXRpb25zLCBidXQgbm8gcGFnZSB3YXMgc3BlY2lmaWVkLicpO1xuICAgICAgdGhpcy5sb2FkQW5ub3RhdGlvbnMoKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY29tcG9uZW50RGlkVXBkYXRlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHMpIHtcbiAgICAgIHZhciBfdGhpcyRwcm9wcyA9IHRoaXMucHJvcHMsXG4gICAgICAgICAgcGFnZSA9IF90aGlzJHByb3BzLnBhZ2UsXG4gICAgICAgICAgcmVuZGVyRm9ybXMgPSBfdGhpcyRwcm9wcy5yZW5kZXJGb3JtcztcblxuICAgICAgaWYgKHByZXZQcm9wcy5wYWdlICYmIHBhZ2UgIT09IHByZXZQcm9wcy5wYWdlIHx8IHJlbmRlckZvcm1zICE9PSBwcmV2UHJvcHMucmVuZGVyRm9ybXMpIHtcbiAgICAgICAgdGhpcy5sb2FkQW5ub3RhdGlvbnMoKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY29tcG9uZW50V2lsbFVubW91bnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICBjYW5jZWxSdW5uaW5nVGFzayh0aGlzLnJ1bm5pbmdUYXNrKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwidmlld3BvcnRcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHZhciBfdGhpcyRwcm9wczIgPSB0aGlzLnByb3BzLFxuICAgICAgICAgIHBhZ2UgPSBfdGhpcyRwcm9wczIucGFnZSxcbiAgICAgICAgICByb3RhdGUgPSBfdGhpcyRwcm9wczIucm90YXRlLFxuICAgICAgICAgIHNjYWxlID0gX3RoaXMkcHJvcHMyLnNjYWxlO1xuICAgICAgcmV0dXJuIHBhZ2UuZ2V0Vmlld3BvcnQoe1xuICAgICAgICBzY2FsZTogc2NhbGUsXG4gICAgICAgIHJvdGF0aW9uOiByb3RhdGVcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJBbm5vdGF0aW9uTGF5ZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyQW5ub3RhdGlvbkxheWVyKCkge1xuICAgICAgdmFyIGFubm90YXRpb25zID0gdGhpcy5zdGF0ZS5hbm5vdGF0aW9ucztcblxuICAgICAgaWYgKCFhbm5vdGF0aW9ucykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBfdGhpcyRwcm9wczMgPSB0aGlzLnByb3BzLFxuICAgICAgICAgIGltYWdlUmVzb3VyY2VzUGF0aCA9IF90aGlzJHByb3BzMy5pbWFnZVJlc291cmNlc1BhdGgsXG4gICAgICAgICAgbGlua1NlcnZpY2UgPSBfdGhpcyRwcm9wczMubGlua1NlcnZpY2UsXG4gICAgICAgICAgcGFnZSA9IF90aGlzJHByb3BzMy5wYWdlLFxuICAgICAgICAgIHJlbmRlckZvcm1zID0gX3RoaXMkcHJvcHMzLnJlbmRlckZvcm1zO1xuICAgICAgdmFyIHZpZXdwb3J0ID0gdGhpcy52aWV3cG9ydC5jbG9uZSh7XG4gICAgICAgIGRvbnRGbGlwOiB0cnVlXG4gICAgICB9KTtcbiAgICAgIHZhciBwYXJhbWV0ZXJzID0ge1xuICAgICAgICBhbm5vdGF0aW9uczogYW5ub3RhdGlvbnMsXG4gICAgICAgIGRpdjogdGhpcy5sYXllckVsZW1lbnQuY3VycmVudCxcbiAgICAgICAgaW1hZ2VSZXNvdXJjZXNQYXRoOiBpbWFnZVJlc291cmNlc1BhdGgsXG4gICAgICAgIGxpbmtTZXJ2aWNlOiBsaW5rU2VydmljZSxcbiAgICAgICAgcGFnZTogcGFnZSxcbiAgICAgICAgcmVuZGVyRm9ybXM6IHJlbmRlckZvcm1zLFxuICAgICAgICB2aWV3cG9ydDogdmlld3BvcnRcbiAgICAgIH07XG4gICAgICB0aGlzLmxheWVyRWxlbWVudC5jdXJyZW50LmlubmVySFRNTCA9ICcnO1xuXG4gICAgICB0cnkge1xuICAgICAgICBwZGZqcy5Bbm5vdGF0aW9uTGF5ZXIucmVuZGVyKHBhcmFtZXRlcnMpO1xuICAgICAgICB0aGlzLm9uUmVuZGVyU3VjY2VzcygpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdGhpcy5vblJlbmRlckVycm9yKGVycm9yKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicmVuZGVyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgICAgIGNsYXNzTmFtZTogXCJyZWFjdC1wZGZfX1BhZ2VfX2Fubm90YXRpb25zIGFubm90YXRpb25MYXllclwiLFxuICAgICAgICByZWY6IHRoaXMubGF5ZXJFbGVtZW50XG4gICAgICB9LCB0aGlzLnJlbmRlckFubm90YXRpb25MYXllcigpKTtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gQW5ub3RhdGlvbkxheWVySW50ZXJuYWw7XG59KFB1cmVDb21wb25lbnQpO1xuQW5ub3RhdGlvbkxheWVySW50ZXJuYWwucHJvcFR5cGVzID0ge1xuICBpbWFnZVJlc291cmNlc1BhdGg6IFByb3BUeXBlcy5zdHJpbmcsXG4gIGxpbmtTZXJ2aWNlOiBpc0xpbmtTZXJ2aWNlLmlzUmVxdWlyZWQsXG4gIG9uR2V0QW5ub3RhdGlvbnNFcnJvcjogUHJvcFR5cGVzLmZ1bmMsXG4gIG9uR2V0QW5ub3RhdGlvbnNTdWNjZXNzOiBQcm9wVHlwZXMuZnVuYyxcbiAgb25SZW5kZXJBbm5vdGF0aW9uTGF5ZXJFcnJvcjogUHJvcFR5cGVzLmZ1bmMsXG4gIG9uUmVuZGVyQW5ub3RhdGlvbkxheWVyU3VjY2VzczogUHJvcFR5cGVzLmZ1bmMsXG4gIHBhZ2U6IGlzUGFnZSxcbiAgcmVuZGVyRm9ybXM6IFByb3BUeXBlcy5ib29sLFxuICByb3RhdGU6IGlzUm90YXRlLFxuICBzY2FsZTogUHJvcFR5cGVzLm51bWJlclxufTtcblxudmFyIEFubm90YXRpb25MYXllciA9IGZ1bmN0aW9uIEFubm90YXRpb25MYXllcihwcm9wcykge1xuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoRG9jdW1lbnRDb250ZXh0LkNvbnN1bWVyLCBudWxsLCBmdW5jdGlvbiAoZG9jdW1lbnRDb250ZXh0KSB7XG4gICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFBhZ2VDb250ZXh0LkNvbnN1bWVyLCBudWxsLCBmdW5jdGlvbiAocGFnZUNvbnRleHQpIHtcbiAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChBbm5vdGF0aW9uTGF5ZXJJbnRlcm5hbCwgX2V4dGVuZHMoe30sIGRvY3VtZW50Q29udGV4dCwgcGFnZUNvbnRleHQsIHByb3BzKSk7XG4gICAgfSk7XG4gIH0pO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgQW5ub3RhdGlvbkxheWVyOyIsImltcG9ydCBfZXh0ZW5kcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZXh0ZW5kc1wiO1xuaW1wb3J0IF9jbGFzc0NhbGxDaGVjayBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY2xhc3NDYWxsQ2hlY2tcIjtcbmltcG9ydCBfY3JlYXRlQ2xhc3MgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NyZWF0ZUNsYXNzXCI7XG5pbXBvcnQgX2Fzc2VydFRoaXNJbml0aWFsaXplZCBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vYXNzZXJ0VGhpc0luaXRpYWxpemVkXCI7XG5pbXBvcnQgX2luaGVyaXRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pbmhlcml0c1wiO1xuaW1wb3J0IF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuXCI7XG5pbXBvcnQgX2dldFByb3RvdHlwZU9mIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9nZXRQcm90b3R5cGVPZlwiO1xuaW1wb3J0IF9kZWZpbmVQcm9wZXJ0eSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZGVmaW5lUHJvcGVydHlcIjtcblxuZnVuY3Rpb24gb3duS2V5cyhvYmplY3QsIGVudW1lcmFibGVPbmx5KSB7IHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqZWN0KTsgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHsgdmFyIHN5bWJvbHMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKG9iamVjdCk7IGVudW1lcmFibGVPbmx5ICYmIChzeW1ib2xzID0gc3ltYm9scy5maWx0ZXIoZnVuY3Rpb24gKHN5bSkgeyByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmplY3QsIHN5bSkuZW51bWVyYWJsZTsgfSkpLCBrZXlzLnB1c2guYXBwbHkoa2V5cywgc3ltYm9scyk7IH0gcmV0dXJuIGtleXM7IH1cblxuZnVuY3Rpb24gX29iamVjdFNwcmVhZCh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IG51bGwgIT0gYXJndW1lbnRzW2ldID8gYXJndW1lbnRzW2ldIDoge307IGkgJSAyID8gb3duS2V5cyhPYmplY3Qoc291cmNlKSwgITApLmZvckVhY2goZnVuY3Rpb24gKGtleSkgeyBfZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHNvdXJjZVtrZXldKTsgfSkgOiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyA/IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoc291cmNlKSkgOiBvd25LZXlzKE9iamVjdChzb3VyY2UpKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHNvdXJjZSwga2V5KSk7IH0pOyB9IHJldHVybiB0YXJnZXQ7IH1cblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KCk7IHJldHVybiBmdW5jdGlvbiBfY3JlYXRlU3VwZXJJbnRlcm5hbCgpIHsgdmFyIFN1cGVyID0gX2dldFByb3RvdHlwZU9mKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2YodGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIHJlc3VsdCk7IH07IH1cblxuZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCgpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbmltcG9ydCBSZWFjdCwgeyBjcmVhdGVSZWYsIFB1cmVDb21wb25lbnQgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuaW1wb3J0IG1ha2VDYW5jZWxsYWJsZSBmcm9tICdtYWtlLWNhbmNlbGxhYmxlLXByb21pc2UnO1xuaW1wb3J0IG1ha2VFdmVudFByb3BzIGZyb20gJ21ha2UtZXZlbnQtcHJvcHMnO1xuaW1wb3J0IG1lcmdlQ2xhc3NOYW1lcyBmcm9tICdtZXJnZS1jbGFzcy1uYW1lcyc7XG5pbXBvcnQgbWVyZ2VSZWZzIGZyb20gJ21lcmdlLXJlZnMnO1xuaW1wb3J0IGludmFyaWFudCBmcm9tICd0aW55LWludmFyaWFudCc7XG5pbXBvcnQgd2FybmluZyBmcm9tICd0aW55LXdhcm5pbmcnO1xuaW1wb3J0IERvY3VtZW50Q29udGV4dCBmcm9tICcuL0RvY3VtZW50Q29udGV4dCc7XG5pbXBvcnQgUGFnZUNvbnRleHQgZnJvbSAnLi9QYWdlQ29udGV4dCc7XG5pbXBvcnQgTWVzc2FnZSBmcm9tICcuL01lc3NhZ2UnO1xuaW1wb3J0IFBhZ2VDYW52YXMgZnJvbSAnLi9QYWdlL1BhZ2VDYW52YXMnO1xuaW1wb3J0IFBhZ2VTVkcgZnJvbSAnLi9QYWdlL1BhZ2VTVkcnO1xuaW1wb3J0IFRleHRMYXllciBmcm9tICcuL1BhZ2UvVGV4dExheWVyJztcbmltcG9ydCBBbm5vdGF0aW9uTGF5ZXIgZnJvbSAnLi9QYWdlL0Fubm90YXRpb25MYXllcic7XG5pbXBvcnQgeyBjYW5jZWxSdW5uaW5nVGFzaywgaXNQcm92aWRlZCwgbWFrZVBhZ2VDYWxsYmFjayB9IGZyb20gJy4vc2hhcmVkL3V0aWxzJztcbmltcG9ydCB7IGV2ZW50UHJvcHMsIGlzQ2xhc3NOYW1lLCBpc1BhZ2VJbmRleCwgaXNQYWdlTnVtYmVyLCBpc1BkZiwgaXNSZWYsIGlzUmVuZGVyTW9kZSwgaXNSb3RhdGUgfSBmcm9tICcuL3NoYXJlZC9wcm9wVHlwZXMnO1xudmFyIGRlZmF1bHRTY2FsZSA9IDE7XG5leHBvcnQgdmFyIFBhZ2VJbnRlcm5hbCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX1B1cmVDb21wb25lbnQpIHtcbiAgX2luaGVyaXRzKFBhZ2VJbnRlcm5hbCwgX1B1cmVDb21wb25lbnQpO1xuXG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIoUGFnZUludGVybmFsKTtcblxuICBmdW5jdGlvbiBQYWdlSW50ZXJuYWwoKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFBhZ2VJbnRlcm5hbCk7XG5cbiAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgIGFyZ3NbX2tleV0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgfVxuXG4gICAgX3RoaXMgPSBfc3VwZXIuY2FsbC5hcHBseShfc3VwZXIsIFt0aGlzXS5jb25jYXQoYXJncykpO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcInN0YXRlXCIsIHtcbiAgICAgIHBhZ2U6IG51bGxcbiAgICB9KTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJwYWdlRWxlbWVudFwiLCAvKiNfX1BVUkVfXyovY3JlYXRlUmVmKCkpO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcIm9uTG9hZFN1Y2Nlc3NcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF90aGlzJHByb3BzID0gX3RoaXMucHJvcHMsXG4gICAgICAgICAgb25Mb2FkU3VjY2VzcyA9IF90aGlzJHByb3BzLm9uTG9hZFN1Y2Nlc3MsXG4gICAgICAgICAgcmVnaXN0ZXJQYWdlID0gX3RoaXMkcHJvcHMucmVnaXN0ZXJQYWdlO1xuICAgICAgdmFyIHBhZ2UgPSBfdGhpcy5zdGF0ZS5wYWdlO1xuICAgICAgaWYgKG9uTG9hZFN1Y2Nlc3MpIG9uTG9hZFN1Y2Nlc3MobWFrZVBhZ2VDYWxsYmFjayhwYWdlLCBfdGhpcy5zY2FsZSkpO1xuICAgICAgaWYgKHJlZ2lzdGVyUGFnZSkgcmVnaXN0ZXJQYWdlKF90aGlzLnBhZ2VJbmRleCwgX3RoaXMucGFnZUVsZW1lbnQuY3VycmVudCk7XG4gICAgfSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwib25Mb2FkRXJyb3JcIiwgZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICBfdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHBhZ2U6IGZhbHNlXG4gICAgICB9KTtcblxuICAgICAgd2FybmluZyhlcnJvcik7XG4gICAgICB2YXIgb25Mb2FkRXJyb3IgPSBfdGhpcy5wcm9wcy5vbkxvYWRFcnJvcjtcbiAgICAgIGlmIChvbkxvYWRFcnJvcikgb25Mb2FkRXJyb3IoZXJyb3IpO1xuICAgIH0pO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcImxvYWRQYWdlXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBwZGYgPSBfdGhpcy5wcm9wcy5wZGY7XG5cbiAgICAgIHZhciBwYWdlTnVtYmVyID0gX3RoaXMuZ2V0UGFnZU51bWJlcigpO1xuXG4gICAgICBpZiAoIXBhZ2VOdW1iZXIpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBfdGhpcy5zZXRTdGF0ZShmdW5jdGlvbiAocHJldlN0YXRlKSB7XG4gICAgICAgIGlmICghcHJldlN0YXRlLnBhZ2UpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcGFnZTogbnVsbFxuICAgICAgICB9O1xuICAgICAgfSk7XG5cbiAgICAgIHZhciBjYW5jZWxsYWJsZSA9IG1ha2VDYW5jZWxsYWJsZShwZGYuZ2V0UGFnZShwYWdlTnVtYmVyKSk7XG4gICAgICBfdGhpcy5ydW5uaW5nVGFzayA9IGNhbmNlbGxhYmxlO1xuICAgICAgY2FuY2VsbGFibGUucHJvbWlzZS50aGVuKGZ1bmN0aW9uIChwYWdlKSB7XG4gICAgICAgIF90aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBwYWdlOiBwYWdlXG4gICAgICAgIH0sIF90aGlzLm9uTG9hZFN1Y2Nlc3MpO1xuICAgICAgfSlbXCJjYXRjaFwiXShmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgX3RoaXMub25Mb2FkRXJyb3IoZXJyb3IpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3MoUGFnZUludGVybmFsLCBbe1xuICAgIGtleTogXCJjb21wb25lbnREaWRNb3VudFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgIHZhciBwZGYgPSB0aGlzLnByb3BzLnBkZjtcbiAgICAgIGludmFyaWFudChwZGYsICdBdHRlbXB0ZWQgdG8gbG9hZCBhIHBhZ2UsIGJ1dCBubyBkb2N1bWVudCB3YXMgc3BlY2lmaWVkLicpO1xuICAgICAgdGhpcy5sb2FkUGFnZSgpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJjb21wb25lbnREaWRVcGRhdGVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wcykge1xuICAgICAgdmFyIHBkZiA9IHRoaXMucHJvcHMucGRmO1xuXG4gICAgICBpZiAocHJldlByb3BzLnBkZiAmJiBwZGYgIT09IHByZXZQcm9wcy5wZGYgfHwgdGhpcy5nZXRQYWdlTnVtYmVyKCkgIT09IHRoaXMuZ2V0UGFnZU51bWJlcihwcmV2UHJvcHMpKSB7XG4gICAgICAgIHZhciB1bnJlZ2lzdGVyUGFnZSA9IHRoaXMucHJvcHMudW5yZWdpc3RlclBhZ2U7XG4gICAgICAgIGlmICh1bnJlZ2lzdGVyUGFnZSkgdW5yZWdpc3RlclBhZ2UodGhpcy5nZXRQYWdlSW5kZXgocHJldlByb3BzKSk7XG4gICAgICAgIHRoaXMubG9hZFBhZ2UoKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY29tcG9uZW50V2lsbFVubW91bnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICB2YXIgdW5yZWdpc3RlclBhZ2UgPSB0aGlzLnByb3BzLnVucmVnaXN0ZXJQYWdlO1xuICAgICAgaWYgKHVucmVnaXN0ZXJQYWdlKSB1bnJlZ2lzdGVyUGFnZSh0aGlzLnBhZ2VJbmRleCk7XG4gICAgICBjYW5jZWxSdW5uaW5nVGFzayh0aGlzLnJ1bm5pbmdUYXNrKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY2hpbGRDb250ZXh0XCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICB2YXIgcGFnZSA9IHRoaXMuc3RhdGUucGFnZTtcblxuICAgICAgaWYgKCFwYWdlKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICAgIH1cblxuICAgICAgdmFyIF90aGlzJHByb3BzMiA9IHRoaXMucHJvcHMsXG4gICAgICAgICAgY2FudmFzQmFja2dyb3VuZCA9IF90aGlzJHByb3BzMi5jYW52YXNCYWNrZ3JvdW5kLFxuICAgICAgICAgIGN1c3RvbVRleHRSZW5kZXJlciA9IF90aGlzJHByb3BzMi5jdXN0b21UZXh0UmVuZGVyZXIsXG4gICAgICAgICAgZW5oYW5jZVRleHRTZWxlY3Rpb24gPSBfdGhpcyRwcm9wczIuZW5oYW5jZVRleHRTZWxlY3Rpb24sXG4gICAgICAgICAgb25HZXRBbm5vdGF0aW9uc0Vycm9yID0gX3RoaXMkcHJvcHMyLm9uR2V0QW5ub3RhdGlvbnNFcnJvcixcbiAgICAgICAgICBvbkdldEFubm90YXRpb25zU3VjY2VzcyA9IF90aGlzJHByb3BzMi5vbkdldEFubm90YXRpb25zU3VjY2VzcyxcbiAgICAgICAgICBvbkdldFRleHRFcnJvciA9IF90aGlzJHByb3BzMi5vbkdldFRleHRFcnJvcixcbiAgICAgICAgICBvbkdldFRleHRTdWNjZXNzID0gX3RoaXMkcHJvcHMyLm9uR2V0VGV4dFN1Y2Nlc3MsXG4gICAgICAgICAgb25SZW5kZXJBbm5vdGF0aW9uTGF5ZXJFcnJvciA9IF90aGlzJHByb3BzMi5vblJlbmRlckFubm90YXRpb25MYXllckVycm9yLFxuICAgICAgICAgIG9uUmVuZGVyQW5ub3RhdGlvbkxheWVyU3VjY2VzcyA9IF90aGlzJHByb3BzMi5vblJlbmRlckFubm90YXRpb25MYXllclN1Y2Nlc3MsXG4gICAgICAgICAgb25SZW5kZXJFcnJvciA9IF90aGlzJHByb3BzMi5vblJlbmRlckVycm9yLFxuICAgICAgICAgIG9uUmVuZGVyU3VjY2VzcyA9IF90aGlzJHByb3BzMi5vblJlbmRlclN1Y2Nlc3MsXG4gICAgICAgICAgb25SZW5kZXJUZXh0TGF5ZXJFcnJvciA9IF90aGlzJHByb3BzMi5vblJlbmRlclRleHRMYXllckVycm9yLFxuICAgICAgICAgIG9uUmVuZGVyVGV4dExheWVyU3VjY2VzcyA9IF90aGlzJHByb3BzMi5vblJlbmRlclRleHRMYXllclN1Y2Nlc3MsXG4gICAgICAgICAgcmVuZGVyRm9ybXMgPSBfdGhpcyRwcm9wczIucmVuZGVyRm9ybXMsXG4gICAgICAgICAgcmVuZGVySW50ZXJhY3RpdmVGb3JtcyA9IF90aGlzJHByb3BzMi5yZW5kZXJJbnRlcmFjdGl2ZUZvcm1zO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY2FudmFzQmFja2dyb3VuZDogY2FudmFzQmFja2dyb3VuZCxcbiAgICAgICAgY3VzdG9tVGV4dFJlbmRlcmVyOiBjdXN0b21UZXh0UmVuZGVyZXIsXG4gICAgICAgIGVuaGFuY2VUZXh0U2VsZWN0aW9uOiBlbmhhbmNlVGV4dFNlbGVjdGlvbixcbiAgICAgICAgb25HZXRBbm5vdGF0aW9uc0Vycm9yOiBvbkdldEFubm90YXRpb25zRXJyb3IsXG4gICAgICAgIG9uR2V0QW5ub3RhdGlvbnNTdWNjZXNzOiBvbkdldEFubm90YXRpb25zU3VjY2VzcyxcbiAgICAgICAgb25HZXRUZXh0RXJyb3I6IG9uR2V0VGV4dEVycm9yLFxuICAgICAgICBvbkdldFRleHRTdWNjZXNzOiBvbkdldFRleHRTdWNjZXNzLFxuICAgICAgICBvblJlbmRlckFubm90YXRpb25MYXllckVycm9yOiBvblJlbmRlckFubm90YXRpb25MYXllckVycm9yLFxuICAgICAgICBvblJlbmRlckFubm90YXRpb25MYXllclN1Y2Nlc3M6IG9uUmVuZGVyQW5ub3RhdGlvbkxheWVyU3VjY2VzcyxcbiAgICAgICAgb25SZW5kZXJFcnJvcjogb25SZW5kZXJFcnJvcixcbiAgICAgICAgb25SZW5kZXJTdWNjZXNzOiBvblJlbmRlclN1Y2Nlc3MsXG4gICAgICAgIG9uUmVuZGVyVGV4dExheWVyRXJyb3I6IG9uUmVuZGVyVGV4dExheWVyRXJyb3IsXG4gICAgICAgIG9uUmVuZGVyVGV4dExheWVyU3VjY2Vzczogb25SZW5kZXJUZXh0TGF5ZXJTdWNjZXNzLFxuICAgICAgICBwYWdlOiBwYWdlLFxuICAgICAgICByZW5kZXJGb3JtczogcmVuZGVyRm9ybXMgIT09IG51bGwgJiYgcmVuZGVyRm9ybXMgIT09IHZvaWQgMCA/IHJlbmRlckZvcm1zIDogcmVuZGVySW50ZXJhY3RpdmVGb3JtcyxcbiAgICAgICAgLy8gRm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHlcbiAgICAgICAgcm90YXRlOiB0aGlzLnJvdGF0ZSxcbiAgICAgICAgc2NhbGU6IHRoaXMuc2NhbGVcbiAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbGxlZCB3aGVuIGEgcGFnZSBpcyBsb2FkZWQgc3VjY2Vzc2Z1bGx5XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJnZXRQYWdlSW5kZXhcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0UGFnZUluZGV4KCkge1xuICAgICAgdmFyIHByb3BzID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiB0aGlzLnByb3BzO1xuXG4gICAgICBpZiAoaXNQcm92aWRlZChwcm9wcy5wYWdlTnVtYmVyKSkge1xuICAgICAgICByZXR1cm4gcHJvcHMucGFnZU51bWJlciAtIDE7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc1Byb3ZpZGVkKHByb3BzLnBhZ2VJbmRleCkpIHtcbiAgICAgICAgcmV0dXJuIHByb3BzLnBhZ2VJbmRleDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldFBhZ2VOdW1iZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0UGFnZU51bWJlcigpIHtcbiAgICAgIHZhciBwcm9wcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogdGhpcy5wcm9wcztcblxuICAgICAgaWYgKGlzUHJvdmlkZWQocHJvcHMucGFnZU51bWJlcikpIHtcbiAgICAgICAgcmV0dXJuIHByb3BzLnBhZ2VOdW1iZXI7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc1Byb3ZpZGVkKHByb3BzLnBhZ2VJbmRleCkpIHtcbiAgICAgICAgcmV0dXJuIHByb3BzLnBhZ2VJbmRleCArIDE7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJwYWdlSW5kZXhcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldFBhZ2VJbmRleCgpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJwYWdlTnVtYmVyXCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRQYWdlTnVtYmVyKCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInJvdGF0ZVwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgdmFyIHJvdGF0ZSA9IHRoaXMucHJvcHMucm90YXRlO1xuXG4gICAgICBpZiAoaXNQcm92aWRlZChyb3RhdGUpKSB7XG4gICAgICAgIHJldHVybiByb3RhdGU7XG4gICAgICB9XG5cbiAgICAgIHZhciBwYWdlID0gdGhpcy5zdGF0ZS5wYWdlO1xuXG4gICAgICBpZiAoIXBhZ2UpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYWdlLnJvdGF0ZTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwic2NhbGVcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHZhciBwYWdlID0gdGhpcy5zdGF0ZS5wYWdlO1xuXG4gICAgICBpZiAoIXBhZ2UpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIHZhciBfdGhpcyRwcm9wczMgPSB0aGlzLnByb3BzLFxuICAgICAgICAgIHNjYWxlID0gX3RoaXMkcHJvcHMzLnNjYWxlLFxuICAgICAgICAgIHdpZHRoID0gX3RoaXMkcHJvcHMzLndpZHRoLFxuICAgICAgICAgIGhlaWdodCA9IF90aGlzJHByb3BzMy5oZWlnaHQ7XG4gICAgICB2YXIgcm90YXRlID0gdGhpcy5yb3RhdGU7IC8vIEJlIGRlZmF1bHQsIHdlJ2xsIHJlbmRlciBwYWdlIGF0IDEwMCUgKiBzY2FsZSB3aWR0aC5cblxuICAgICAgdmFyIHBhZ2VTY2FsZSA9IDE7IC8vIFBhc3Npbmcgc2NhbGUgZXhwbGljaXRseSBudWxsIHdvdWxkIGNhdXNlIHRoZSBwYWdlIG5vdCB0byByZW5kZXJcblxuICAgICAgdmFyIHNjYWxlV2l0aERlZmF1bHQgPSBzY2FsZSA9PT0gbnVsbCA/IGRlZmF1bHRTY2FsZSA6IHNjYWxlOyAvLyBJZiB3aWR0aC9oZWlnaHQgaXMgZGVmaW5lZCwgY2FsY3VsYXRlIHRoZSBzY2FsZSBvZiB0aGUgcGFnZSBzbyBpdCBjb3VsZCBiZSBvZiBkZXNpcmVkIHdpZHRoLlxuXG4gICAgICBpZiAod2lkdGggfHwgaGVpZ2h0KSB7XG4gICAgICAgIHZhciB2aWV3cG9ydCA9IHBhZ2UuZ2V0Vmlld3BvcnQoe1xuICAgICAgICAgIHNjYWxlOiAxLFxuICAgICAgICAgIHJvdGF0aW9uOiByb3RhdGVcbiAgICAgICAgfSk7XG4gICAgICAgIHBhZ2VTY2FsZSA9IHdpZHRoID8gd2lkdGggLyB2aWV3cG9ydC53aWR0aCA6IGhlaWdodCAvIHZpZXdwb3J0LmhlaWdodDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHNjYWxlV2l0aERlZmF1bHQgKiBwYWdlU2NhbGU7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImV2ZW50UHJvcHNcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICByZXR1cm4gbWFrZUV2ZW50UHJvcHModGhpcy5wcm9wcywgZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcGFnZSA9IF90aGlzMi5zdGF0ZS5wYWdlO1xuXG4gICAgICAgIGlmICghcGFnZSkge1xuICAgICAgICAgIHJldHVybiBwYWdlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1ha2VQYWdlQ2FsbGJhY2socGFnZSwgX3RoaXMyLnNjYWxlKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJwYWdlS2V5XCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICB2YXIgcGFnZSA9IHRoaXMuc3RhdGUucGFnZTtcbiAgICAgIHJldHVybiBcIlwiLmNvbmNhdChwYWdlLnBhZ2VJbmRleCwgXCJAXCIpLmNvbmNhdCh0aGlzLnNjYWxlLCBcIi9cIikuY29uY2F0KHRoaXMucm90YXRlKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicGFnZUtleU5vU2NhbGVcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHZhciBwYWdlID0gdGhpcy5zdGF0ZS5wYWdlO1xuICAgICAgcmV0dXJuIFwiXCIuY29uY2F0KHBhZ2UucGFnZUluZGV4LCBcIi9cIikuY29uY2F0KHRoaXMucm90YXRlKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicmVuZGVyTWFpbkxheWVyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlck1haW5MYXllcigpIHtcbiAgICAgIHZhciBfdGhpcyRwcm9wczQgPSB0aGlzLnByb3BzLFxuICAgICAgICAgIGNhbnZhc1JlZiA9IF90aGlzJHByb3BzNC5jYW52YXNSZWYsXG4gICAgICAgICAgcmVuZGVyTW9kZSA9IF90aGlzJHByb3BzNC5yZW5kZXJNb2RlO1xuXG4gICAgICBzd2l0Y2ggKHJlbmRlck1vZGUpIHtcbiAgICAgICAgY2FzZSAnbm9uZSc6XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgY2FzZSAnc3ZnJzpcbiAgICAgICAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoUGFnZVNWRywge1xuICAgICAgICAgICAga2V5OiBcIlwiLmNvbmNhdCh0aGlzLnBhZ2VLZXlOb1NjYWxlLCBcIl9zdmdcIilcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjYXNlICdjYW52YXMnOlxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChQYWdlQ2FudmFzLCB7XG4gICAgICAgICAgICBrZXk6IFwiXCIuY29uY2F0KHRoaXMucGFnZUtleSwgXCJfY2FudmFzXCIpLFxuICAgICAgICAgICAgY2FudmFzUmVmOiBjYW52YXNSZWZcbiAgICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicmVuZGVyVGV4dExheWVyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlclRleHRMYXllcigpIHtcbiAgICAgIHZhciByZW5kZXJUZXh0TGF5ZXIgPSB0aGlzLnByb3BzLnJlbmRlclRleHRMYXllcjtcblxuICAgICAgaWYgKCFyZW5kZXJUZXh0TGF5ZXIpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChUZXh0TGF5ZXIsIHtcbiAgICAgICAga2V5OiBcIlwiLmNvbmNhdCh0aGlzLnBhZ2VLZXksIFwiX3RleHRcIilcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJBbm5vdGF0aW9uTGF5ZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyQW5ub3RhdGlvbkxheWVyKCkge1xuICAgICAgdmFyIHJlbmRlckFubm90YXRpb25MYXllciA9IHRoaXMucHJvcHMucmVuZGVyQW5ub3RhdGlvbkxheWVyO1xuXG4gICAgICBpZiAoIXJlbmRlckFubm90YXRpb25MYXllcikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8qKlxuICAgICAgICogQXMgb2Ygbm93LCBQREYuanMgMi4wLjk0MyByZXR1cm5zIHdhcm5pbmdzIG9uIHVuaW1wbGVtZW50ZWQgYW5ub3RhdGlvbnMgaW4gU1ZHIG1vZGUuXG4gICAgICAgKiBUaGVyZWZvcmUsIGFzIGEgZmFsbGJhY2ssIHdlIHJlbmRlciBcInRyYWRpdGlvbmFsXCIgQW5ub3RhdGlvbkxheWVyIGNvbXBvbmVudC5cbiAgICAgICAqL1xuXG5cbiAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChBbm5vdGF0aW9uTGF5ZXIsIHtcbiAgICAgICAga2V5OiBcIlwiLmNvbmNhdCh0aGlzLnBhZ2VLZXksIFwiX2Fubm90YXRpb25zXCIpXG4gICAgICB9KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicmVuZGVyQ2hpbGRyZW5cIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyQ2hpbGRyZW4oKSB7XG4gICAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLnByb3BzLmNoaWxkcmVuO1xuICAgICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFBhZ2VDb250ZXh0LlByb3ZpZGVyLCB7XG4gICAgICAgIHZhbHVlOiB0aGlzLmNoaWxkQ29udGV4dFxuICAgICAgfSwgdGhpcy5yZW5kZXJNYWluTGF5ZXIoKSwgdGhpcy5yZW5kZXJUZXh0TGF5ZXIoKSwgdGhpcy5yZW5kZXJBbm5vdGF0aW9uTGF5ZXIoKSwgY2hpbGRyZW4pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJDb250ZW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlckNvbnRlbnQoKSB7XG4gICAgICB2YXIgcGFnZU51bWJlciA9IHRoaXMucGFnZU51bWJlcjtcbiAgICAgIHZhciBwZGYgPSB0aGlzLnByb3BzLnBkZjtcbiAgICAgIHZhciBwYWdlID0gdGhpcy5zdGF0ZS5wYWdlO1xuXG4gICAgICBpZiAoIXBhZ2VOdW1iZXIpIHtcbiAgICAgICAgdmFyIG5vRGF0YSA9IHRoaXMucHJvcHMubm9EYXRhO1xuICAgICAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoTWVzc2FnZSwge1xuICAgICAgICAgIHR5cGU6IFwibm8tZGF0YVwiXG4gICAgICAgIH0sIHR5cGVvZiBub0RhdGEgPT09ICdmdW5jdGlvbicgPyBub0RhdGEoKSA6IG5vRGF0YSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwZGYgPT09IG51bGwgfHwgcGFnZSA9PT0gbnVsbCkge1xuICAgICAgICB2YXIgbG9hZGluZyA9IHRoaXMucHJvcHMubG9hZGluZztcbiAgICAgICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KE1lc3NhZ2UsIHtcbiAgICAgICAgICB0eXBlOiBcImxvYWRpbmdcIlxuICAgICAgICB9LCB0eXBlb2YgbG9hZGluZyA9PT0gJ2Z1bmN0aW9uJyA/IGxvYWRpbmcoKSA6IGxvYWRpbmcpO1xuICAgICAgfVxuXG4gICAgICBpZiAocGRmID09PSBmYWxzZSB8fCBwYWdlID09PSBmYWxzZSkge1xuICAgICAgICB2YXIgZXJyb3IgPSB0aGlzLnByb3BzLmVycm9yO1xuICAgICAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoTWVzc2FnZSwge1xuICAgICAgICAgIHR5cGU6IFwiZXJyb3JcIlxuICAgICAgICB9LCB0eXBlb2YgZXJyb3IgPT09ICdmdW5jdGlvbicgPyBlcnJvcigpIDogZXJyb3IpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5yZW5kZXJDaGlsZHJlbigpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgdmFyIHBhZ2VOdW1iZXIgPSB0aGlzLnBhZ2VOdW1iZXI7XG4gICAgICB2YXIgX3RoaXMkcHJvcHM1ID0gdGhpcy5wcm9wcyxcbiAgICAgICAgICBjbGFzc05hbWUgPSBfdGhpcyRwcm9wczUuY2xhc3NOYW1lLFxuICAgICAgICAgIGlucHV0UmVmID0gX3RoaXMkcHJvcHM1LmlucHV0UmVmO1xuICAgICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIF9leHRlbmRzKHtcbiAgICAgICAgY2xhc3NOYW1lOiBtZXJnZUNsYXNzTmFtZXMoJ3JlYWN0LXBkZl9fUGFnZScsIGNsYXNzTmFtZSksXG4gICAgICAgIFwiZGF0YS1wYWdlLW51bWJlclwiOiBwYWdlTnVtYmVyLFxuICAgICAgICByZWY6IG1lcmdlUmVmcyhpbnB1dFJlZiwgdGhpcy5wYWdlRWxlbWVudCksXG4gICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgcG9zaXRpb246ICdyZWxhdGl2ZSdcbiAgICAgICAgfVxuICAgICAgfSwgdGhpcy5ldmVudFByb3BzKSwgdGhpcy5yZW5kZXJDb250ZW50KCkpO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBQYWdlSW50ZXJuYWw7XG59KFB1cmVDb21wb25lbnQpO1xuUGFnZUludGVybmFsLmRlZmF1bHRQcm9wcyA9IHtcbiAgZXJyb3I6ICdGYWlsZWQgdG8gbG9hZCB0aGUgcGFnZS4nLFxuICBsb2FkaW5nOiAnTG9hZGluZyBwYWdl4oCmJyxcbiAgbm9EYXRhOiAnTm8gcGFnZSBzcGVjaWZpZWQuJyxcbiAgcmVuZGVyQW5ub3RhdGlvbkxheWVyOiB0cnVlLFxuICByZW5kZXJGb3JtczogZmFsc2UsXG4gIHJlbmRlck1vZGU6ICdjYW52YXMnLFxuICByZW5kZXJUZXh0TGF5ZXI6IHRydWUsXG4gIHNjYWxlOiBkZWZhdWx0U2NhbGVcbn07XG52YXIgaXNGdW5jdGlvbk9yTm9kZSA9IFByb3BUeXBlcy5vbmVPZlR5cGUoW1Byb3BUeXBlcy5mdW5jLCBQcm9wVHlwZXMubm9kZV0pO1xuUGFnZUludGVybmFsLnByb3BUeXBlcyA9IF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwgZXZlbnRQcm9wcyksIHt9LCB7XG4gIGNhbnZhc0JhY2tncm91bmQ6IFByb3BUeXBlcy5zdHJpbmcsXG4gIGNoaWxkcmVuOiBQcm9wVHlwZXMubm9kZSxcbiAgY2xhc3NOYW1lOiBpc0NsYXNzTmFtZSxcbiAgY3VzdG9tVGV4dFJlbmRlcmVyOiBQcm9wVHlwZXMuZnVuYyxcbiAgZW5oYW5jZVRleHRTZWxlY3Rpb246IFByb3BUeXBlcy5ib29sLFxuICBlcnJvcjogaXNGdW5jdGlvbk9yTm9kZSxcbiAgaGVpZ2h0OiBQcm9wVHlwZXMubnVtYmVyLFxuICBpbWFnZVJlc291cmNlc1BhdGg6IFByb3BUeXBlcy5zdHJpbmcsXG4gIGlucHV0UmVmOiBpc1JlZixcbiAgbG9hZGluZzogaXNGdW5jdGlvbk9yTm9kZSxcbiAgbm9EYXRhOiBpc0Z1bmN0aW9uT3JOb2RlLFxuICBvbkdldFRleHRFcnJvcjogUHJvcFR5cGVzLmZ1bmMsXG4gIG9uR2V0VGV4dFN1Y2Nlc3M6IFByb3BUeXBlcy5mdW5jLFxuICBvbkxvYWRFcnJvcjogUHJvcFR5cGVzLmZ1bmMsXG4gIG9uTG9hZFN1Y2Nlc3M6IFByb3BUeXBlcy5mdW5jLFxuICBvblJlbmRlckVycm9yOiBQcm9wVHlwZXMuZnVuYyxcbiAgb25SZW5kZXJTdWNjZXNzOiBQcm9wVHlwZXMuZnVuYyxcbiAgb25SZW5kZXJUZXh0TGF5ZXJFcnJvcjogUHJvcFR5cGVzLmZ1bmMsXG4gIG9uUmVuZGVyVGV4dExheWVyU3VjY2VzczogUHJvcFR5cGVzLmZ1bmMsXG4gIHBhZ2VJbmRleDogaXNQYWdlSW5kZXgsXG4gIHBhZ2VOdW1iZXI6IGlzUGFnZU51bWJlcixcbiAgcGRmOiBpc1BkZixcbiAgcmVnaXN0ZXJQYWdlOiBQcm9wVHlwZXMuZnVuYyxcbiAgcmVuZGVyQW5ub3RhdGlvbkxheWVyOiBQcm9wVHlwZXMuYm9vbCxcbiAgcmVuZGVyRm9ybXM6IFByb3BUeXBlcy5ib29sLFxuICByZW5kZXJJbnRlcmFjdGl2ZUZvcm1zOiBQcm9wVHlwZXMuYm9vbCxcbiAgLy8gRm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHlcbiAgcmVuZGVyTW9kZTogaXNSZW5kZXJNb2RlLFxuICByZW5kZXJUZXh0TGF5ZXI6IFByb3BUeXBlcy5ib29sLFxuICByb3RhdGU6IGlzUm90YXRlLFxuICBzY2FsZTogUHJvcFR5cGVzLm51bWJlcixcbiAgdW5yZWdpc3RlclBhZ2U6IFByb3BUeXBlcy5mdW5jLFxuICB3aWR0aDogUHJvcFR5cGVzLm51bWJlclxufSk7XG5cbmZ1bmN0aW9uIFBhZ2UocHJvcHMsIHJlZikge1xuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoRG9jdW1lbnRDb250ZXh0LkNvbnN1bWVyLCBudWxsLCBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChQYWdlSW50ZXJuYWwsIF9leHRlbmRzKHtcbiAgICAgIHJlZjogcmVmXG4gICAgfSwgY29udGV4dCwgcHJvcHMpKTtcbiAgfSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IC8qI19fUFVSRV9fKi9SZWFjdC5mb3J3YXJkUmVmKFBhZ2UpOyIsImltcG9ydCAqIGFzIHBkZmpzIGZyb20gJ3BkZmpzLWRpc3QvYnVpbGQvcGRmJztcbmltcG9ydCBEb2N1bWVudCBmcm9tICcuL0RvY3VtZW50JztcbmltcG9ydCBPdXRsaW5lIGZyb20gJy4vT3V0bGluZSc7XG5pbXBvcnQgUGFnZSBmcm9tICcuL1BhZ2UnO1xuaW1wb3J0IHsgZGlzcGxheVdvcmtlcldhcm5pbmcgfSBmcm9tICcuL3NoYXJlZC91dGlscyc7XG5kaXNwbGF5V29ya2VyV2FybmluZygpO1xucGRmanMuR2xvYmFsV29ya2VyT3B0aW9ucy53b3JrZXJTcmMgPSAncGRmLndvcmtlci5qcyc7XG5leHBvcnQgeyBwZGZqcywgRG9jdW1lbnQsIE91dGxpbmUsIFBhZ2UgfTsiLCJpbXBvcnQgeyBOdWxsYWJsZSB9IGZyb20gJy4uL2NvbXBvbmVudHMvdHlwZXMvdXRpbHMnO1xuXG5leHBvcnQgZW51bSBTY3JvbGxEaXJlY3Rpb24ge1xuICBVUCA9ICdVUCcsXG4gIERPV04gPSAnRE9XTicsXG59XG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTY3JvbGxEZXRlY3RvciB7XG4gIF9sYXN0U2Nyb2xsVG9wOiBudW1iZXI7XG4gIF9sYXN0U2Nyb2xsRGlyZWN0aW9uOiBOdWxsYWJsZTxTY3JvbGxEaXJlY3Rpb24+O1xuICBfZWw6IEVsZW1lbnQ7XG4gIF9zZXRTY3JvbGxEaXJlY3Rpb246IChzY3JvbGxEaXJlY3Rpb246IFNjcm9sbERpcmVjdGlvbikgPT4gYW55O1xuICBfbGFzdFNjcm9sbFRvcEJlZm9yZURpcmVjdGlvbkNoYW5nZTogbnVtYmVyO1xuICBfc2Nyb2xsVGhyZXNob2xkPzogbnVtYmVyO1xuICBfaXNTY3JvbGxUaHJlc2hvbGRSZWFjaGVkSW5EaXJlY3Rpb246IE51bGxhYmxlPFNjcm9sbERpcmVjdGlvbj47XG4gIF9zZXRTY3JvbGxUaHJlc2hvbGRSZWFjaGVkSW5EaXJlY3Rpb24/OiAoc2Nyb2xsRGlyZWN0aW9uOiBOdWxsYWJsZTxTY3JvbGxEaXJlY3Rpb24+KSA9PiBhbnk7XG4gIF9pc0F0VG9wOiBOdWxsYWJsZTxib29sZWFuPjtcbiAgX3NldElzQXRUb3A6IChpc0F0VG9wOiBib29sZWFuKSA9PiBhbnk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgZWw6IEVsZW1lbnQsXG4gICAgc2V0U2Nyb2xsRGlyZWN0aW9uOiAoc2Nyb2xsRGlyZWN0aW9uOiBTY3JvbGxEaXJlY3Rpb24pID0+IGFueSxcbiAgICBzZXRJc0F0VG9wOiAoaXNBdFRvcDogYm9vbGVhbikgPT4gYW55LFxuICAgIHNldFNjcm9sbFRocmVzaG9sZFJlYWNoZWRJbkRpcmVjdGlvbj86IChzY3JvbGxEaXJlY3Rpb246IE51bGxhYmxlPFNjcm9sbERpcmVjdGlvbj4pID0+IGFueSxcbiAgICBzY3JvbGxUaHJlc2hvbGQ/OiBudW1iZXJcbiAgKSB7XG4gICAgdGhpcy5fZWwgPSBlbDtcbiAgICB0aGlzLl9sYXN0U2Nyb2xsVG9wID0gdGhpcy5fZWwuc2Nyb2xsVG9wO1xuICAgIHRoaXMuX2xhc3RTY3JvbGxEaXJlY3Rpb24gPSBudWxsO1xuICAgIHRoaXMuX3NldFNjcm9sbERpcmVjdGlvbiA9IHNldFNjcm9sbERpcmVjdGlvbjtcbiAgICB0aGlzLl9pc0F0VG9wID0gbnVsbDtcbiAgICB0aGlzLl9zZXRJc0F0VG9wID0gc2V0SXNBdFRvcDtcbiAgICB0aGlzLl9sYXN0U2Nyb2xsVG9wQmVmb3JlRGlyZWN0aW9uQ2hhbmdlID0gdGhpcy5fZWwuc2Nyb2xsVG9wO1xuICAgIHRoaXMuX3Njcm9sbFRocmVzaG9sZCA9IHNjcm9sbFRocmVzaG9sZDtcblxuICAgIHRoaXMuX2lzU2Nyb2xsVGhyZXNob2xkUmVhY2hlZEluRGlyZWN0aW9uID0gbnVsbDtcbiAgICB0aGlzLl9zZXRTY3JvbGxUaHJlc2hvbGRSZWFjaGVkSW5EaXJlY3Rpb24gPSBzZXRTY3JvbGxUaHJlc2hvbGRSZWFjaGVkSW5EaXJlY3Rpb247XG4gIH1cblxuICBhdHRhY2hTY3JvbGxMaXN0ZW5lcigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fZWw/LnRhZ05hbWU/LnRvTG93ZXJDYXNlKCkgPT09ICdodG1sJykge1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMuX29uU2Nyb2xsLCBmYWxzZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX2VsLmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMuX29uU2Nyb2xsLCBmYWxzZSk7XG4gIH1cblxuICBkZXRhY2hTY3JvbGxMaXN0ZW5lcigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fZWw/LnRhZ05hbWU/LnRvTG93ZXJDYXNlKCkgPT09ICdodG1sJykge1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMuX29uU2Nyb2xsLCBmYWxzZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX2VsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMuX29uU2Nyb2xsLCBmYWxzZSk7XG4gIH1cblxuICBfb25TY3JvbGwgPSAoKTogdm9pZCA9PiB7XG4gICAgY29uc3QgY3VyclNjcm9sbFRvcCA9IHRoaXMuX2VsLnNjcm9sbFRvcDtcbiAgICBpZiAodGhpcy5faXNBdFRvcCAhPT0gKGN1cnJTY3JvbGxUb3AgPT09IDApKSB7XG4gICAgICB0aGlzLl9pc0F0VG9wID0gY3VyclNjcm9sbFRvcCA9PT0gMDtcbiAgICAgIHRoaXMuX3NldElzQXRUb3AoY3VyclNjcm9sbFRvcCA9PT0gMCk7XG4gICAgfVxuICAgIGlmICh0aGlzLl9sYXN0U2Nyb2xsVG9wID09PSBjdXJyU2Nyb2xsVG9wKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gRGV0ZXJtaW5lIGRpcmVjdGlvblxuICAgIGNvbnN0IGN1cnJTY3JvbGxEaXJlY3Rpb24gPSAoKCkgPT4ge1xuICAgICAgaWYgKGN1cnJTY3JvbGxUb3AgPD0gMCkge1xuICAgICAgICByZXR1cm4gU2Nyb2xsRGlyZWN0aW9uLkRPV047XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5fbGFzdFNjcm9sbFRvcCA8IGN1cnJTY3JvbGxUb3AgPyBTY3JvbGxEaXJlY3Rpb24uRE9XTiA6IFNjcm9sbERpcmVjdGlvbi5VUDtcbiAgICB9KSgpO1xuXG4gICAgLy8gVXBkYXRlIHN0YXRlLCBpZiBjaGFuZ2VkXG4gICAgdGhpcy5fbGFzdFNjcm9sbFRvcCA9IGN1cnJTY3JvbGxUb3A7XG4gICAgaWYgKHRoaXMuX2xhc3RTY3JvbGxEaXJlY3Rpb24gIT09IGN1cnJTY3JvbGxEaXJlY3Rpb24pIHtcbiAgICAgIHRoaXMuX2xhc3RTY3JvbGxEaXJlY3Rpb24gPSBjdXJyU2Nyb2xsRGlyZWN0aW9uO1xuICAgICAgdGhpcy5fc2V0U2Nyb2xsRGlyZWN0aW9uKGN1cnJTY3JvbGxEaXJlY3Rpb24pO1xuXG4gICAgICB0aGlzLl9sYXN0U2Nyb2xsVG9wQmVmb3JlRGlyZWN0aW9uQ2hhbmdlID0gY3VyclNjcm9sbFRvcDtcbiAgICAgIHRoaXMuX2lzU2Nyb2xsVGhyZXNob2xkUmVhY2hlZEluRGlyZWN0aW9uID0gbnVsbDtcbiAgICAgIGlmICh0aGlzLl9zZXRTY3JvbGxUaHJlc2hvbGRSZWFjaGVkSW5EaXJlY3Rpb24gJiYgIXRoaXMuX2lzQXRUb3ApIHtcbiAgICAgICAgdGhpcy5fc2V0U2Nyb2xsVGhyZXNob2xkUmVhY2hlZEluRGlyZWN0aW9uKG51bGwpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5fc2Nyb2xsVGhyZXNob2xkICYmIHRoaXMuX3NldFNjcm9sbFRocmVzaG9sZFJlYWNoZWRJbkRpcmVjdGlvbikge1xuICAgICAgICBjb25zdCBzY3JvbGxlZEFtb3VudCA9IE1hdGguYWJzKHRoaXMuX2xhc3RTY3JvbGxUb3BCZWZvcmVEaXJlY3Rpb25DaGFuZ2UgLSBjdXJyU2Nyb2xsVG9wKTtcbiAgICAgICAgaWYgKHNjcm9sbGVkQW1vdW50ID49IHRoaXMuX3Njcm9sbFRocmVzaG9sZCkge1xuICAgICAgICAgIHRoaXMuX2lzU2Nyb2xsVGhyZXNob2xkUmVhY2hlZEluRGlyZWN0aW9uID0gdGhpcy5fbGFzdFNjcm9sbERpcmVjdGlvbjtcbiAgICAgICAgICB0aGlzLl9zZXRTY3JvbGxUaHJlc2hvbGRSZWFjaGVkSW5EaXJlY3Rpb24odGhpcy5fbGFzdFNjcm9sbERpcmVjdGlvbik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG59XG4iLCJjb25zdCBERUZBVUxUX1JPT1RfTUFSR0lOID0gJzUwcHgnO1xuLy8gVGhpcyBhcnJheSBpcyBhIHJhbmdlIGZyb20gMC4wMDAxIHRvIDEgcmFuZ2Ugb2YgdGhyZXNob2xkLiBJdCB3aWxsIGhlbHAgd2l0aCBkZXRlY3Rpbmdcbi8vIG9uIHNjcm9sbCB3aXRoIGEgYmV0dGVyICUgY29tcGFyZSB0byBhIGZpeCB0aHJlc2hvbGQgYnV0IG5vdCBmaXJpbmcgdG9vIGZyZXF1ZW50IHRoYXRcbi8vIGNhbiBoYW1wZXIgb3VyIHBlcmZvcm1hbmNlLlxuY29uc3QgREVGQVVMVF9USFJFU0hPTEQgPSBbMC4wMDAxLCAwLjEsIDAuMiwgMC4zLCAwLjQsIDAuNSwgMC42LCAwLjcsIDAuOCwgMC45LCAwLjk5XTtcblxuZXhwb3J0IHR5cGUgU2V0VmlzaWJsZUVudHJpZXNDYWxsYmFjazxURW50cnk+ID0gKHZpc2libGU6IE1hcDxURW50cnksIG51bWJlcj4pID0+IHZvaWQ7XG5leHBvcnQgdHlwZSBvblZpc2libGVFbnRyaWVzQ2hhbmdlQ2FsbGJhY2s8VEVudHJ5PiA9IChhcmdzOiB7XG4gIHZpc2libGVFbnRyaWVzOiBJbnRlcnNlY3Rpb25PYnNlcnZlckVudHJ5W107XG4gIGhpZGRlbkVudHJpZXM6IEludGVyc2VjdGlvbk9ic2VydmVyRW50cnlbXTtcbiAgbGFzdEVudHJpZXM6IE1hcDxURW50cnksIG51bWJlcj47XG59KSA9PiBNYXA8VEVudHJ5LCBudW1iZXI+O1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWaXNpYmxlRW50cmllc0RldGVjdG9yPFRFbnRyeT4ge1xuICBfcm9vdDogRWxlbWVudDtcbiAgX29ic2VydmVyOiBJbnRlcnNlY3Rpb25PYnNlcnZlcjtcbiAgX2xhc3RWaXNpYmxlRW50cmllczogTWFwPFRFbnRyeSwgbnVtYmVyPjtcbiAgX3NldFZpc2libGVFbnRyaWVzOiBTZXRWaXNpYmxlRW50cmllc0NhbGxiYWNrPFRFbnRyeT47XG4gIF9vblZpc2libGVFbnRyaWVzQ2hhbmdlOiBvblZpc2libGVFbnRyaWVzQ2hhbmdlQ2FsbGJhY2s8VEVudHJ5PjtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgcm9vdCxcbiAgICB0aHJlc0hvbGQsXG4gICAgc2V0VmlzaWJsZUVudHJpZXMsXG4gICAgb25WaXNpYmxlRW50cmllc0NoYW5nZSxcbiAgfToge1xuICAgIHJvb3Q6IEVsZW1lbnQ7XG4gICAgdGhyZXNIb2xkPzogbnVtYmVyIHwgQXJyYXk8bnVtYmVyPjtcbiAgICBzZXRWaXNpYmxlRW50cmllczogU2V0VmlzaWJsZUVudHJpZXNDYWxsYmFjazxURW50cnk+O1xuICAgIG9uVmlzaWJsZUVudHJpZXNDaGFuZ2U6IG9uVmlzaWJsZUVudHJpZXNDaGFuZ2VDYWxsYmFjazxURW50cnk+O1xuICB9KSB7XG4gICAgdGhpcy5fcm9vdCA9IHJvb3Q7XG4gICAgdGhpcy5fbGFzdFZpc2libGVFbnRyaWVzID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuX3NldFZpc2libGVFbnRyaWVzID0gc2V0VmlzaWJsZUVudHJpZXM7XG4gICAgdGhpcy5fb25WaXNpYmxlRW50cmllc0NoYW5nZSA9IG9uVmlzaWJsZUVudHJpZXNDaGFuZ2U7XG4gICAgdGhpcy5fb2JzZXJ2ZXIgPSBuZXcgSW50ZXJzZWN0aW9uT2JzZXJ2ZXIoXG4gICAgICBlbnRyaWVzID0+IHtcbiAgICAgICAgLy8gQ29sbGVjdCB2aXNpYmxlIGFuZCBoaWRkZW4gZWxlbWVudHNcbiAgICAgICAgY29uc3QgdmlzaWJsZUVudHJpZXMgPSBlbnRyaWVzLmZpbHRlcihlbnRyeSA9PiBlbnRyeS5pc0ludGVyc2VjdGluZyk7XG4gICAgICAgIGNvbnN0IGhpZGRlbkVudHJpZXMgPSBlbnRyaWVzLmZpbHRlcihlbnRyeSA9PiAhZW50cnkuaXNJbnRlcnNlY3RpbmcpO1xuXG4gICAgICAgIC8vIERldGVybWluZSB3aGF0IG5lZWRzIHNhdmVkXG4gICAgICAgIGNvbnN0IG5ld1Zpc2libGVFbnRyaWVzID0gdGhpcy5fb25WaXNpYmxlRW50cmllc0NoYW5nZSh7XG4gICAgICAgICAgdmlzaWJsZUVudHJpZXMsXG4gICAgICAgICAgaGlkZGVuRW50cmllcyxcbiAgICAgICAgICBsYXN0RW50cmllczogdGhpcy5fbGFzdFZpc2libGVFbnRyaWVzLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBmcm96ZW5FbnRyaWVzID0gbmV3IE1hcChuZXdWaXNpYmxlRW50cmllcyk7XG4gICAgICAgIE9iamVjdC5mcmVlemUoZnJvemVuRW50cmllcyk7XG4gICAgICAgIHRoaXMuX2xhc3RWaXNpYmxlRW50cmllcyA9IGZyb3plbkVudHJpZXM7XG4gICAgICAgIHRoaXMuX3NldFZpc2libGVFbnRyaWVzKGZyb3plbkVudHJpZXMpO1xuICAgICAgfSxcblxuICAgICAgLy8gRGVmYXVsdCBzZXR0aW5nIGZvciBpbnRlcnNlY3Rpb24gb2JzZXJ2ZXJcbiAgICAgIHtcbiAgICAgICAgcm9vdDogdGhpcy5fcm9vdC50YWdOYW1lPy50b0xvd2VyQ2FzZSgpID09PSAnaHRtbCcgPyBudWxsIDogdGhpcy5fcm9vdCxcbiAgICAgICAgcm9vdE1hcmdpbjogREVGQVVMVF9ST09UX01BUkdJTixcbiAgICAgICAgdGhyZXNob2xkOiB0aHJlc0hvbGQgPyB0aHJlc0hvbGQgOiBERUZBVUxUX1RIUkVTSE9MRCxcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgb2JzZXJ2ZU5vZGVzKHNlbGVjdG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2YgdGhpcy5fcm9vdC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSkge1xuICAgICAgdGhpcy5fb2JzZXJ2ZXIub2JzZXJ2ZShub2RlKTtcbiAgICB9XG4gIH1cblxuICBkZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuX29ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgfVxufVxuIiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5pbXBvcnQgeyBOb2RlRGVzdGluYXRpb24gfSBmcm9tICcuLi9jb21wb25lbnRzL3R5cGVzL291dGxpbmUnO1xuaW1wb3J0IHsgUGFnZU51bWJlciB9IGZyb20gJy4uL2NvbXBvbmVudHMvdHlwZXMvcGFnZSc7XG5pbXBvcnQgeyBOdWxsYWJsZSB9IGZyb20gJy4uL2NvbXBvbmVudHMvdHlwZXMvdXRpbHMnO1xuaW1wb3J0IHsgbG9nUHJvdmlkZXJXYXJuaW5nIH0gZnJvbSAnLi4vdXRpbHMvcHJvdmlkZXInO1xuaW1wb3J0IHsgZ2VuZXJhdGVQYWdlSWRGcm9tSW5kZXggfSBmcm9tICcuLi91dGlscy9zY3JvbGwnO1xuaW1wb3J0IFNjcm9sbERldGVjdG9yLCB7IFNjcm9sbERpcmVjdGlvbiB9IGZyb20gJy4uL3V0aWxzL1Njcm9sbERpcmVjdGlvbkRldGVjdG9yJztcbmltcG9ydCBWaXNpYmxlRW50cmllc0RldGVjdG9yIGZyb20gJy4uL3V0aWxzL1Zpc2libGVFbnRyaWVzRGV0ZWN0b3InO1xuXG5jb25zdCBPVVRMSU5FX0FUVFJJQlVURSA9ICdkYXRhLW91dGxpbmUtdGFyZ2V0LWRlc3QnO1xuXG5jb25zdCBPVVRMSU5FX1NFTEVDVE9SID0gJy5yZWFkZXJfX3BhZ2VfX291dGxpbmUtdGFyZ2V0JztcblxuY29uc3QgUEFHRV9OVU1CRVJfQVRUUklCVVRFID0gJ2RhdGEtcGFnZS1udW1iZXInO1xuXG5jb25zdCBQQUdFX05VTUJFUl9TRUxFQ1RPUiA9IGAucmVhZGVyX19wYWdlWyR7UEFHRV9OVU1CRVJfQVRUUklCVVRFfV1gO1xuXG5leHBvcnQgaW50ZXJmYWNlIElTY3JvbGxDb250ZXh0IHtcbiAgaXNPdXRsaW5lVGFyZ2V0VmlzaWJsZTogKGRlc3Q6IE5vZGVEZXN0aW5hdGlvbikgPT4gYm9vbGVhbjtcbiAgaXNQYWdlVmlzaWJsZTogKHBhZ2VOdW1iZXI6IFBhZ2VOdW1iZXIpID0+IGJvb2xlYW47XG4gIHNjcm9sbERpcmVjdGlvbjogTnVsbGFibGU8U2Nyb2xsRGlyZWN0aW9uPjtcbiAgdmlzaWJsZU91dGxpbmVUYXJnZXRzOiBNYXA8Tm9kZURlc3RpbmF0aW9uLCBudW1iZXI+OyAvLyBtYXBwaW5nIG5vZGUgZGVzdGluYXRpb24gd2l0aCB0aGVpciBpbnRlcnNlY3Rpb24gcmF0aW9cbiAgdmlzaWJsZVBhZ2VSYXRpb3M6IE1hcDxudW1iZXIsIG51bWJlcj47IC8vIG1hcHBpbmcgcGFnZSBudW1iZXIgd2l0aCB0aGVpciBpbnRlcnNlY3Rpb24gcmF0aW9cbiAgcmVzZXRTY3JvbGxPYnNlcnZlcnM6ICgpID0+IHZvaWQ7XG4gIHNldFNjcm9sbFJvb3Q6IChyb290OiBOdWxsYWJsZTxFbGVtZW50PikgPT4gdm9pZDtcbiAgc2Nyb2xsVG9PdXRsaW5lVGFyZ2V0OiAoZGVzdDogTm9kZURlc3RpbmF0aW9uKSA9PiB2b2lkO1xuICBzZXRTY3JvbGxUaHJlc2hvbGQ6IChzY3JvbGxUaHJlc2hvbGQ6IE51bGxhYmxlPG51bWJlcj4pID0+IHZvaWQ7XG4gIHNjcm9sbFRvUGFnZTogKHBhZ2VOdW1iZXI6IFBhZ2VOdW1iZXIpID0+IHZvaWQ7XG4gIHVwZGF0ZVNjcm9sbFBvc2l0aW9uOiAoem9vbU11bHRpcGxpZXI6IG51bWJlcikgPT4gdm9pZDtcbiAgc2V0SXNPdXRsaW5lQ2xpY2tlZDogKGlzT3V0bGluZUdldENsaWNrZWQ6IGJvb2xlYW4pID0+IHZvaWQ7XG4gIHNjcm9sbFRocmVzaG9sZFJlYWNoZWRJbkRpcmVjdGlvbjogTnVsbGFibGU8U2Nyb2xsRGlyZWN0aW9uPjtcbiAgaXNBdFRvcDogTnVsbGFibGU8Ym9vbGVhbj47XG4gIGlzT3V0bGluZUNsaWNrZWQ6IE51bGxhYmxlPGJvb2xlYW4+O1xufVxuXG5jb25zdCBERUZBVUxUX0NPTlRFWFQ6IElTY3JvbGxDb250ZXh0ID0ge1xuICBzY3JvbGxEaXJlY3Rpb246IG51bGwsXG4gIHZpc2libGVPdXRsaW5lVGFyZ2V0czogbmV3IE1hcCgpLFxuICB2aXNpYmxlUGFnZVJhdGlvczogbmV3IE1hcCgpLFxuICBpc091dGxpbmVUYXJnZXRWaXNpYmxlOiBvcHRzID0+IHtcbiAgICBsb2dQcm92aWRlcldhcm5pbmcoYGlzT3V0bGluZVRhcmdldFZpc2libGUoJHtKU09OLnN0cmluZ2lmeShvcHRzKX0pYCwgJ1Njcm9sbENvbnRleHQnKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0sXG4gIGlzUGFnZVZpc2libGU6IG9wdHMgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgaXNQYWdlVmlzaWJsZSgke0pTT04uc3RyaW5naWZ5KG9wdHMpfSlgLCAnU2Nyb2xsQ29udGV4dCcpO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSxcbiAgcmVzZXRTY3JvbGxPYnNlcnZlcnM6ICgpID0+IHtcbiAgICBsb2dQcm92aWRlcldhcm5pbmcoYHJlc2V0U2Nyb2xsT2JzZXJ2ZXJzKClgLCAnU2Nyb2xsQ29udGV4dCcpO1xuICB9LFxuICBzZXRTY3JvbGxSb290OiAoX2VsOiBOdWxsYWJsZTxFbGVtZW50PikgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgc2V0U2Nyb2xsUm9vdCguLi4pYCwgJ1Njcm9sbENvbnRleHQnKTtcbiAgfSxcbiAgc2Nyb2xsVG9PdXRsaW5lVGFyZ2V0OiBkZXN0ID0+IHtcbiAgICBsb2dQcm92aWRlcldhcm5pbmcoYHNjcm9sbFRvT3V0bGluZVRhcmdldCgke2Rlc3R9KWAsICdTY3JvbGxDb250ZXh0Jyk7XG4gIH0sXG4gIHNldFNjcm9sbFRocmVzaG9sZDogKHNjcm9sbFRocmVzaG9sZDogTnVsbGFibGU8bnVtYmVyPikgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgc2V0U2Nyb2xsVGhyZXNob2xkKCR7c2Nyb2xsVGhyZXNob2xkfSlgLCAnU2Nyb2xsQ29udGV4dCcpO1xuICB9LFxuICBzY3JvbGxUb1BhZ2U6IG9wdHMgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgc2Nyb2xsVG9QYWdlKCR7SlNPTi5zdHJpbmdpZnkob3B0cyl9KWAsICdTY3JvbGxDb250ZXh0Jyk7XG4gIH0sXG4gIHVwZGF0ZVNjcm9sbFBvc2l0aW9uOiB6b29tTXVsdGlwbGllciA9PiB7XG4gICAgbG9nUHJvdmlkZXJXYXJuaW5nKGB1cGRhdGVTY3JvbGxQb3NpdGlvbigke0pTT04uc3RyaW5naWZ5KHpvb21NdWx0aXBsaWVyKX0pYCwgJ1Njcm9sbENvbnRleHQnKTtcbiAgfSxcbiAgc2V0SXNPdXRsaW5lQ2xpY2tlZDogb3B0cyA9PiB7XG4gICAgbG9nUHJvdmlkZXJXYXJuaW5nKGBzZXRJc091dGxpbmVHZXRDbGlja2VkKCR7SlNPTi5zdHJpbmdpZnkob3B0cyl9KWAsICdTY3JvbGxDb250ZXh0Jyk7XG4gIH0sXG4gIHNjcm9sbFRocmVzaG9sZFJlYWNoZWRJbkRpcmVjdGlvbjogbnVsbCxcbiAgaXNBdFRvcDogbnVsbCxcbiAgaXNPdXRsaW5lQ2xpY2tlZDogbnVsbCxcbn07XG5cbmV4cG9ydCBjb25zdCBTY3JvbGxDb250ZXh0ID0gUmVhY3QuY3JlYXRlQ29udGV4dDxJU2Nyb2xsQ29udGV4dD4oREVGQVVMVF9DT05URVhUKTtcblxuZXhwb3J0IGZ1bmN0aW9uIHVzZVNjcm9sbENvbnRleHRQcm9wcygpOiBJU2Nyb2xsQ29udGV4dCB7XG4gIC8vIE5vZGUgdXNlZCBmb3Igb2JzZXJ2aW5nIHRoZSBzY3JvbGwgcG9zaXRpb25cbiAgY29uc3QgW3Njcm9sbFJvb3QsIHNldFNjcm9sbFJvb3RdID0gUmVhY3QudXNlU3RhdGU8TnVsbGFibGU8RWxlbWVudD4+KG51bGwpO1xuXG4gIC8vIERldGVybWluZSBzY3JvbGwgZGlyZWN0aW9uXG4gIGNvbnN0IFtzY3JvbGxEaXJlY3Rpb24sIHNldFNjcm9sbERpcmVjdGlvbl0gPSBSZWFjdC51c2VTdGF0ZTxOdWxsYWJsZTxTY3JvbGxEaXJlY3Rpb24+PihudWxsKTtcbiAgY29uc3QgW3Njcm9sbFRocmVzaG9sZCwgc2V0U2Nyb2xsVGhyZXNob2xkXSA9IFJlYWN0LnVzZVN0YXRlPE51bGxhYmxlPG51bWJlcj4+KG51bGwpO1xuICBjb25zdCBbc2Nyb2xsVGhyZXNob2xkUmVhY2hlZEluRGlyZWN0aW9uLCBzZXRTY3JvbGxUaHJlc2hvbGRSZWFjaGVkSW5EaXJlY3Rpb25dID1cbiAgICBSZWFjdC51c2VTdGF0ZTxOdWxsYWJsZTxTY3JvbGxEaXJlY3Rpb24+PihudWxsKTtcbiAgY29uc3QgW2lzQXRUb3AsIHNldElzQXRUb3BdID0gUmVhY3QudXNlU3RhdGU8TnVsbGFibGU8Ym9vbGVhbj4+KG51bGwpO1xuICBjb25zdCBbaXNPdXRsaW5lQ2xpY2tlZCwgc2V0SXNPdXRsaW5lQ2xpY2tlZF0gPSBSZWFjdC51c2VTdGF0ZTxOdWxsYWJsZTxib29sZWFuPj4obnVsbCk7XG5cbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCBzY3JvbGxFbGVtID0gc2Nyb2xsUm9vdCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gICAgaWYgKCFzY3JvbGxFbGVtKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IHNjcm9sbERpcmVjdGlvbkRldGVjdG9yOiBTY3JvbGxEZXRlY3RvcjtcbiAgICBpZiAoIXNjcm9sbFRocmVzaG9sZCkge1xuICAgICAgLy8gc2Nyb2xsIHRocmVzaG9sZCBpcyBvcHRpb25hbFxuICAgICAgc2Nyb2xsRGlyZWN0aW9uRGV0ZWN0b3IgPSBuZXcgU2Nyb2xsRGV0ZWN0b3Ioc2Nyb2xsRWxlbSwgc2V0U2Nyb2xsRGlyZWN0aW9uLCBzZXRJc0F0VG9wKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2Nyb2xsRGlyZWN0aW9uRGV0ZWN0b3IgPSBuZXcgU2Nyb2xsRGV0ZWN0b3IoXG4gICAgICAgIHNjcm9sbEVsZW0sXG4gICAgICAgIHNldFNjcm9sbERpcmVjdGlvbixcbiAgICAgICAgc2V0SXNBdFRvcCxcbiAgICAgICAgc2V0U2Nyb2xsVGhyZXNob2xkUmVhY2hlZEluRGlyZWN0aW9uLFxuICAgICAgICBzY3JvbGxUaHJlc2hvbGRcbiAgICAgICk7XG4gICAgfVxuXG4gICAgc2Nyb2xsRGlyZWN0aW9uRGV0ZWN0b3IuYXR0YWNoU2Nyb2xsTGlzdGVuZXIoKTtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgc2Nyb2xsRGlyZWN0aW9uRGV0ZWN0b3IuZGV0YWNoU2Nyb2xsTGlzdGVuZXIoKTtcbiAgICB9O1xuICB9LCBbc2Nyb2xsUm9vdCwgc2Nyb2xsVGhyZXNob2xkXSk7XG5cbiAgLy8gQ2F1c2VzIHRoZSBJbnRlcnNlY3Rpb25PYnNlcnZlcnMgdG8gZGlzY29ubmVjdCBhbmQgYmUgcmVjcmVhdGVkICh1c2VmdWwgd2hlbiBET00gY2hhbmdlcylcbiAgY29uc3QgW29ic2VydmVySW5kZXgsIHNldE9ic2VydmVySW5kZXhdID0gUmVhY3QudXNlU3RhdGUoMCk7XG4gIGNvbnN0IHJlc2V0U2Nyb2xsT2JzZXJ2ZXJzID0gUmVhY3QudXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIHNldE9ic2VydmVySW5kZXgob2JzZXJ2ZXJJbmRleCArIDEpO1xuICB9LCBbb2JzZXJ2ZXJJbmRleF0pO1xuXG4gIGNvbnN0IFt2aXNpYmxlT3V0bGluZVRhcmdldHMsIHNldFZpc2libGVPdXRsaW5lTm9kZXNdID0gUmVhY3QudXNlU3RhdGU8XG4gICAgTWFwPE5vZGVEZXN0aW5hdGlvbiwgbnVtYmVyPlxuICA+KCgpID0+IHtcbiAgICBjb25zdCBtYXAgPSBuZXcgTWFwPE5vZGVEZXN0aW5hdGlvbiwgbnVtYmVyPigpO1xuICAgIE9iamVjdC5mcmVlemUobWFwKTtcbiAgICByZXR1cm4gbWFwO1xuICB9KTtcblxuICBjb25zdCBbdmlzaWJsZVBhZ2VSYXRpb3MsIHNldFZpc2libGVQYWdlUmF0aW9zXSA9IFJlYWN0LnVzZVN0YXRlPE1hcDxudW1iZXIsIG51bWJlcj4+KCgpID0+IHtcbiAgICBjb25zdCBtYXAgPSBuZXcgTWFwPG51bWJlciwgbnVtYmVyPigpO1xuICAgIE9iamVjdC5mcmVlemUobWFwKTtcbiAgICByZXR1cm4gbWFwO1xuICB9KTtcblxuICBjb25zdCBpc091dGxpbmVUYXJnZXRWaXNpYmxlID0gUmVhY3QudXNlQ2FsbGJhY2soXG4gICAgKGRlc3Q6IE5vZGVEZXN0aW5hdGlvbik6IGJvb2xlYW4gPT4ge1xuICAgICAgcmV0dXJuIHZpc2libGVPdXRsaW5lVGFyZ2V0cy5oYXMoZGVzdCk7XG4gICAgfSxcbiAgICBbdmlzaWJsZU91dGxpbmVUYXJnZXRzXVxuICApO1xuXG4gIGNvbnN0IHNjcm9sbFRvT3V0bGluZVRhcmdldCA9IFJlYWN0LnVzZUNhbGxiYWNrKChkZXN0OiBOb2RlRGVzdGluYXRpb24pOiB2b2lkID0+IHtcbiAgICBzZXRJc091dGxpbmVDbGlja2VkKHRydWUpO1xuICAgIGRvY3VtZW50XG4gICAgICAucXVlcnlTZWxlY3RvcihgW2RhdGEtb3V0bGluZS10YXJnZXQtZGVzdD1cIiR7ZGVzdH1cIl1gKVxuICAgICAgPy5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiAnc21vb3RoJyB9KTtcbiAgfSwgW10pO1xuXG4gIGNvbnN0IGlzUGFnZVZpc2libGUgPSBSZWFjdC51c2VDYWxsYmFjayhcbiAgICAoeyBwYWdlTnVtYmVyLCBwYWdlSW5kZXggfTogUGFnZU51bWJlcik6IGJvb2xlYW4gPT4ge1xuICAgICAgaWYgKHR5cGVvZiBwYWdlSW5kZXggPT09ICdudW1iZXInKSB7XG4gICAgICAgIHBhZ2VOdW1iZXIgPSBwYWdlSW5kZXggKyAxO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBwYWdlTnVtYmVyICE9PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gdmlzaWJsZVBhZ2VSYXRpb3MuaGFzKHBhZ2VOdW1iZXIpO1xuICAgIH0sXG4gICAgW3Zpc2libGVQYWdlUmF0aW9zXVxuICApO1xuXG4gIGNvbnN0IHNjcm9sbFRvUGFnZSA9IFJlYWN0LnVzZUNhbGxiYWNrKCh7IHBhZ2VOdW1iZXIsIHBhZ2VJbmRleCB9OiBQYWdlTnVtYmVyKTogdm9pZCA9PiB7XG4gICAgaWYgKHR5cGVvZiBwYWdlTnVtYmVyID09PSAnbnVtYmVyJykge1xuICAgICAgcGFnZUluZGV4ID0gcGFnZU51bWJlciAtIDE7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgcGFnZUluZGV4ICE9PSAnbnVtYmVyJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkb2N1bWVudFxuICAgICAgLmdldEVsZW1lbnRCeUlkKGdlbmVyYXRlUGFnZUlkRnJvbUluZGV4KHBhZ2VJbmRleCkpXG4gICAgICA/LnNjcm9sbEludG9WaWV3KHsgYmVoYXZpb3I6ICdzbW9vdGgnIH0pO1xuICB9LCBbXSk7XG5cbiAgLy8gV2F0Y2ggb3V0bGluZSBub2Rlc1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IHJvb3QgPSBzY3JvbGxSb290IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiAgICBjb25zdCBkZXRlY3RvciA9IG5ldyBWaXNpYmxlRW50cmllc0RldGVjdG9yPE5vZGVEZXN0aW5hdGlvbj4oe1xuICAgICAgcm9vdDogcm9vdCxcbiAgICAgIHNldFZpc2libGVFbnRyaWVzOiBzZXRWaXNpYmxlT3V0bGluZU5vZGVzLFxuICAgICAgb25WaXNpYmxlRW50cmllc0NoYW5nZTogKHsgdmlzaWJsZUVudHJpZXMsIGhpZGRlbkVudHJpZXMsIGxhc3RFbnRyaWVzIH0pID0+IHtcbiAgICAgICAgaGlkZGVuRW50cmllcy5tYXAoZW50cnkgPT5cbiAgICAgICAgICBsYXN0RW50cmllcy5kZWxldGUoZW50cnkudGFyZ2V0LmdldEF0dHJpYnV0ZShPVVRMSU5FX0FUVFJJQlVURSkpXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IG5ld0VudHJpZXMgPSBuZXcgTWFwKGxhc3RFbnRyaWVzKTtcbiAgICAgICAgdmlzaWJsZUVudHJpZXMubWFwKGVudHJ5ID0+XG4gICAgICAgICAgbmV3RW50cmllcy5zZXQoZW50cnkudGFyZ2V0LmdldEF0dHJpYnV0ZShPVVRMSU5FX0FUVFJJQlVURSksIGVudHJ5LmludGVyc2VjdGlvblJhdGlvKVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gbmV3RW50cmllcztcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgZGV0ZWN0b3Iub2JzZXJ2ZU5vZGVzKE9VVExJTkVfU0VMRUNUT1IpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBkZXRlY3Rvci5kZXN0cm95KCk7XG4gICAgfTtcbiAgfSwgW3Njcm9sbFJvb3QsIG9ic2VydmVySW5kZXhdKTtcblxuICAvLyBXYXRjaCBwYWdlc1xuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IHJvb3QgPSBzY3JvbGxSb290IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiAgICBjb25zdCBkZXRlY3RvciA9IG5ldyBWaXNpYmxlRW50cmllc0RldGVjdG9yPG51bWJlcj4oe1xuICAgICAgcm9vdDogcm9vdCxcbiAgICAgIHNldFZpc2libGVFbnRyaWVzOiBzZXRWaXNpYmxlUGFnZVJhdGlvcyxcbiAgICAgIG9uVmlzaWJsZUVudHJpZXNDaGFuZ2U6ICh7IHZpc2libGVFbnRyaWVzLCBoaWRkZW5FbnRyaWVzLCBsYXN0RW50cmllcyB9KSA9PiB7XG4gICAgICAgIGhpZGRlbkVudHJpZXMubWFwKGVudHJ5ID0+XG4gICAgICAgICAgbGFzdEVudHJpZXMuZGVsZXRlKHBhcnNlSW50KGVudHJ5LnRhcmdldD8uZ2V0QXR0cmlidXRlKFBBR0VfTlVNQkVSX0FUVFJJQlVURSkgfHwgJycsIDEwKSlcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgbmV3RW50cmllcyA9IG5ldyBNYXAobGFzdEVudHJpZXMpO1xuICAgICAgICB2aXNpYmxlRW50cmllcy5tYXAoZW50cnkgPT5cbiAgICAgICAgICBuZXdFbnRyaWVzLnNldChcbiAgICAgICAgICAgIHBhcnNlSW50KGVudHJ5LnRhcmdldD8uZ2V0QXR0cmlidXRlKFBBR0VfTlVNQkVSX0FUVFJJQlVURSkgfHwgJycsIDEwKSxcbiAgICAgICAgICAgIGVudHJ5LmludGVyc2VjdGlvblJhdGlvXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gbmV3RW50cmllcztcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgZGV0ZWN0b3Iub2JzZXJ2ZU5vZGVzKFBBR0VfTlVNQkVSX1NFTEVDVE9SKTtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgZGV0ZWN0b3IuZGVzdHJveSgpO1xuICAgIH07XG4gIH0sIFtzY3JvbGxSb290LCBvYnNlcnZlckluZGV4XSk7XG5cbiAgLy8gY2FsY3VsYXRlcyBhIG5ldyBzY3JvbGwgcG9zaXRpb24gYWZ0ZXIgem9vbWluZyBpbi9vdXQgc28gdXNlciBkb2VzbnQgbG9zZSB0aGVpciBwb3NpdGlvblxuICBjb25zdCB1cGRhdGVTY3JvbGxQb3NpdGlvbiA9IFJlYWN0LnVzZUNhbGxiYWNrKFxuICAgICh6b29tTXVsdGlwbGllcjogbnVtYmVyKTogdm9pZCA9PiB7XG4gICAgICBjb25zdCByb290ID0gc2Nyb2xsUm9vdCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gICAgICBpZiAoIXJvb3QpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgbmV3U2Nyb2xsVG9wID0gTWF0aC5mbG9vcihyb290LnNjcm9sbFRvcCAqIHpvb21NdWx0aXBsaWVyKTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICByb290LnNjcm9sbFRvcCA9IG5ld1Njcm9sbFRvcDtcbiAgICAgIH0sIDApO1xuICAgIH0sXG4gICAgW3Njcm9sbFJvb3RdXG4gICk7XG5cbiAgcmV0dXJuIHtcbiAgICBpc091dGxpbmVUYXJnZXRWaXNpYmxlLFxuICAgIGlzUGFnZVZpc2libGUsXG4gICAgc2Nyb2xsRGlyZWN0aW9uLFxuICAgIHZpc2libGVPdXRsaW5lVGFyZ2V0cyxcbiAgICB2aXNpYmxlUGFnZVJhdGlvcyxcbiAgICByZXNldFNjcm9sbE9ic2VydmVycyxcbiAgICBzZXRTY3JvbGxSb290LFxuICAgIHNjcm9sbFRvT3V0bGluZVRhcmdldCxcbiAgICBzZXRTY3JvbGxUaHJlc2hvbGQsXG4gICAgc2Nyb2xsVG9QYWdlLFxuICAgIHVwZGF0ZVNjcm9sbFBvc2l0aW9uLFxuICAgIHNldElzT3V0bGluZUNsaWNrZWQsXG4gICAgc2Nyb2xsVGhyZXNob2xkUmVhY2hlZEluRGlyZWN0aW9uLFxuICAgIGlzQXRUb3AsXG4gICAgaXNPdXRsaW5lQ2xpY2tlZCxcbiAgfTtcbn1cbiIsImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcblxuaW1wb3J0IHsgTnVsbGFibGUgfSBmcm9tICcuLi9jb21wb25lbnRzL3R5cGVzL3V0aWxzJztcbmltcG9ydCB7IGxvZ1Byb3ZpZGVyV2FybmluZyB9IGZyb20gJy4uL3V0aWxzL3Byb3ZpZGVyJztcblxuZXhwb3J0IGludGVyZmFjZSBJVWlDb250ZXh0IHtcbiAgZXJyb3JNZXNzYWdlOiBOdWxsYWJsZTxzdHJpbmc+O1xuICBpc0xvYWRpbmc6IGJvb2xlYW47XG4gIGlzU2hvd2luZ0hpZ2hsaWdodE92ZXJsYXk6IGJvb2xlYW47XG4gIGlzU2hvd2luZ091dGxpbmU6IGJvb2xlYW47XG4gIGlzU2hvd2luZ1RleHRIaWdobGlnaHQ6IGJvb2xlYW47XG4gIHNldEVycm9yTWVzc2FnZTogKGVycm9yTWVzc2FnZTogTnVsbGFibGU8c3RyaW5nPikgPT4gdm9pZDtcbiAgc2V0SXNMb2FkaW5nOiAoaXNMb2FkaW5nOiBib29sZWFuKSA9PiB2b2lkO1xuICBzZXRJc1Nob3dpbmdIaWdobGlnaHRPdmVybGF5OiAoaXNTaG93aW5nSGlnaGxpZ2h0T3ZlcmxheTogYm9vbGVhbikgPT4gdm9pZDtcbiAgc2V0SXNTaG93aW5nT3V0bGluZTogKGlzU2hvd2luZ091dGxpbmU6IGJvb2xlYW4pID0+IHZvaWQ7XG4gIHNldElzU2hvd2luZ1RleHRIaWdobGlnaHQ6IChpc1Nob3dpbmdUZXh0SGlnaGxpZ2h0OiBib29sZWFuKSA9PiB2b2lkO1xufVxuXG5leHBvcnQgY29uc3QgVWlDb250ZXh0ID0gUmVhY3QuY3JlYXRlQ29udGV4dDxJVWlDb250ZXh0Pih7XG4gIGVycm9yTWVzc2FnZTogbnVsbCxcbiAgaXNMb2FkaW5nOiBmYWxzZSxcbiAgaXNTaG93aW5nSGlnaGxpZ2h0T3ZlcmxheTogZmFsc2UsXG4gIGlzU2hvd2luZ091dGxpbmU6IGZhbHNlLFxuICBpc1Nob3dpbmdUZXh0SGlnaGxpZ2h0OiBmYWxzZSxcbiAgc2V0RXJyb3JNZXNzYWdlOiBlcnJvck1lc3NhZ2UgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgc2V0RXJyb3JNZXNzYWdlKCR7ZXJyb3JNZXNzYWdlfSlgLCAnVWlDb250ZXh0Jyk7XG4gIH0sXG4gIHNldElzU2hvd2luZ091dGxpbmU6IGlzU2hvd2luZ091dGxpbmUgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgc2V0SXNTaG93aW5nT3V0bGluZSgke2lzU2hvd2luZ091dGxpbmV9KWAsICdVaUNvbnRleHQnKTtcbiAgfSxcbiAgc2V0SXNMb2FkaW5nOiBpc0xvYWRpbmcgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgc2V0SXNMb2FkaW5nKCR7aXNMb2FkaW5nfSlgLCAnVWlDb250ZXh0Jyk7XG4gIH0sXG4gIHNldElzU2hvd2luZ0hpZ2hsaWdodE92ZXJsYXk6IGlzU2hvd2luZ0hpZ2hsaWdodE92ZXJsYXkgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgc2V0SXNTaG93aW5nSGlnaGxpZ2h0T3ZlcmxheSgke2lzU2hvd2luZ0hpZ2hsaWdodE92ZXJsYXl9KWAsICdVaUNvbnRleHQnKTtcbiAgfSxcbiAgc2V0SXNTaG93aW5nVGV4dEhpZ2hsaWdodDogaXNTaG93aW5nVGV4dEhpZ2hsaWdodCA9PiB7XG4gICAgbG9nUHJvdmlkZXJXYXJuaW5nKGBzZXRJc1Nob3dpbmdUZXh0SGlnaGxpZ2h0KCR7aXNTaG93aW5nVGV4dEhpZ2hsaWdodH0pYCwgJ1VpQ29udGV4dCcpO1xuICB9LFxufSk7XG5cbmV4cG9ydCBmdW5jdGlvbiB1c2VVaUNvbnRleHRQcm9wcygpOiBJVWlDb250ZXh0IHtcbiAgY29uc3QgW2Vycm9yTWVzc2FnZSwgc2V0RXJyb3JNZXNzYWdlXSA9IFJlYWN0LnVzZVN0YXRlPE51bGxhYmxlPHN0cmluZz4+KG51bGwpO1xuICBjb25zdCBbaXNMb2FkaW5nLCBzZXRJc0xvYWRpbmddID0gUmVhY3QudXNlU3RhdGU8Ym9vbGVhbj4odHJ1ZSk7XG4gIGNvbnN0IFtpc1Nob3dpbmdIaWdobGlnaHRPdmVybGF5LCBzZXRJc1Nob3dpbmdIaWdobGlnaHRPdmVybGF5XSA9IFJlYWN0LnVzZVN0YXRlPGJvb2xlYW4+KGZhbHNlKTtcbiAgY29uc3QgW2lzU2hvd2luZ091dGxpbmUsIHNldElzU2hvd2luZ091dGxpbmVdID0gUmVhY3QudXNlU3RhdGU8Ym9vbGVhbj4oZmFsc2UpO1xuICBjb25zdCBbaXNTaG93aW5nVGV4dEhpZ2hsaWdodCwgc2V0SXNTaG93aW5nVGV4dEhpZ2hsaWdodF0gPSBSZWFjdC51c2VTdGF0ZTxib29sZWFuPihmYWxzZSk7XG5cbiAgcmV0dXJuIHtcbiAgICBlcnJvck1lc3NhZ2UsXG4gICAgaXNMb2FkaW5nLFxuICAgIGlzU2hvd2luZ0hpZ2hsaWdodE92ZXJsYXksXG4gICAgaXNTaG93aW5nT3V0bGluZSxcbiAgICBpc1Nob3dpbmdUZXh0SGlnaGxpZ2h0LFxuICAgIHNldEVycm9yTWVzc2FnZSxcbiAgICBzZXRJc0xvYWRpbmcsXG4gICAgc2V0SXNTaG93aW5nSGlnaGxpZ2h0T3ZlcmxheSxcbiAgICBzZXRJc1Nob3dpbmdPdXRsaW5lLFxuICAgIHNldElzU2hvd2luZ1RleHRIaWdobGlnaHQsXG4gIH07XG59XG4iLCIvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuZXhwb3J0IGZ1bmN0aW9uIGdldEVycm9yTWVzc2FnZShlcnJvcjogYW55KTogc3RyaW5nIHtcbiAgaWYgKCFlcnJvcikge1xuICAgIHJldHVybiAnVW5rbm93biBlcnJvcic7XG4gIH1cbiAgaWYgKHR5cGVvZiBlcnJvciA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZXJyb3I7XG4gIH1cbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICByZXR1cm4gZXJyb3IubWVzc2FnZTtcbiAgfVxuICBpZiAodHlwZW9mIGVycm9yLmVycm9yID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBlcnJvci5lcnJvcjtcbiAgfVxuICByZXR1cm4gZXJyb3IudG9TdHJpbmcoKTtcbn1cbiIsImltcG9ydCB7IHBkZmpzIH0gZnJvbSAncmVhY3QtcGRmJztcblxuLy8gU2V0IFBERmpzIHdvcmtlciBzb3VyY2Ugb3IgZWxzZSBQREYgd2lsbCBub3QgbG9hZCB3aGVuIHRoaXMgbGlicmFyeSBpcyBpbXBvcnRlZCBhcyBhIHBhY2thZ2UuXG5leHBvcnQgZnVuY3Rpb24gaW5pdFBkZldvcmtlcigpOiB2b2lkIHtcbiAgcGRmanMuR2xvYmFsV29ya2VyT3B0aW9ucy53b3JrZXJTcmMgPSBgLy9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvcGRmLmpzLyR7cGRmanMudmVyc2lvbn0vcGRmLndvcmtlci5taW4uanNgO1xufVxuIiwiaW1wb3J0IHsgRGltZW5zaW9ucyB9IGZyb20gJy4uL2NvbXBvbmVudHMvdHlwZXMvYm91bmRpbmdCb3gnO1xuXG4vLyBEYXRhIGZyb20gcmVhY3QtcGRmL3BkZmpzIHRoYXQgd2UgbmVlZCB0byBjb21wdXRlIHRoZSBwaXhlbCBzaXplIG9mIHRoZSBQREYncyBwYWdlKHMpLlxuZXhwb3J0IGludGVyZmFjZSBJUERGUGFnZVByb3h5IHtcbiAgdXNlclVuaXQ6IG51bWJlcjsgLy8gdGhlIGRlZmF1bHQgc2l6ZSBvZiB1bml0cyBpbiAxLzcybmRzIG9mIGFuIGluY2hcbiAgdmlldzogQXJyYXk8bnVtYmVyPjsgLy8gZm9ybWF0OiBbIHRvcCBsZWZ0IHggY29vcmRpbmF0ZSwgdG9wIGxlZnQgeSBjb29yZGluYXRlLCBib3R0b20gcmlnaHQgeCwgYm90dG9tIHJpZ2h0IHldXG59XG5cbi8vIFdlIGFzc3VtZSA5NiBEUEkgZm9yIGRpc3BsYXlcbi8vIFRPRE86IFRoZXJlIGFyZSBtb3JlIGFjY3VyYXRlIHdheXMgdG8gZG8gdGhpcywgYnV0IHRoaXMgaXMgd2hhdCBTY2hvbGFyUGhpIGRvZXMgbm93XG5jb25zdCBEUEkgPSA5NjtcblxuLy8gUERGIHVuaXRzIGFyZSBpbiAxLzcybmRzIG9mIGFuIGluY2hcbmNvbnN0IFVTRVJfVU5JVF9ERU5PTUlOQVRPUiA9IDcyO1xuXG4vKipcbiAqIEdpdmVuIGEgUERGUGFnZVByb3h5LCBjYWxjdWxhdGVzIHRoZSBzY3JlZW4gcGl4ZWwgc2l6ZSBvZiB0aGUgUERGIHBhZ2UgYXQgMTAwJSBzY2FsZVxuICogQHBhcmFtIHBhZ2UgVGhlIFBERlBhZ2VQcm94eSB0byBjYWxjdWxhdGUgc2l6ZSBmb3JcbiAqIEByZXR1cm5zIFBpeGVsIHNpemUgb2YgYSBwYWdlIGF0IDEwMCUgc2NhbGUgYXNzdW1pbmcgOTZEUEkgZGlzcGxheVxuICovXG5leHBvcnQgZnVuY3Rpb24gY29tcHV0ZVBhZ2VEaW1lbnNpb25zKHBhZ2U6IElQREZQYWdlUHJveHkpOiBEaW1lbnNpb25zIHtcbiAgY29uc3QgW2xlZnRQeCwgdG9wUHgsIHJpZ2h0UHgsIGJvdHRvbVB4XSA9IHBhZ2UudmlldztcbiAgY29uc3QgUFBJID0gKHBhZ2UudXNlclVuaXQgLyBVU0VSX1VOSVRfREVOT01JTkFUT1IpICogRFBJO1xuXG4gIHJldHVybiB7XG4gICAgaGVpZ2h0OiAoYm90dG9tUHggLSB0b3BQeCkgKiBQUEksXG4gICAgd2lkdGg6IChyaWdodFB4IC0gbGVmdFB4KSAqIFBQSSxcbiAgfTtcbn1cbiIsImltcG9ydCB7IFBhZ2VSZWZlcmVuY2UgfSBmcm9tICcuL3BhZ2UnO1xuXG5leHBvcnQgdHlwZSBEZXN0aW5hdGlvbiA9IHtcbiAgZGVzdDogc3RyaW5nO1xuICBwYWdlSW5kZXg6IG51bWJlcjtcbiAgcGFnZU51bWJlcjogbnVtYmVyO1xufTtcblxuLyoqXG4gKiBUaGlzIGNsYXNzIGlzIHRoZSBkZWZpbml0aW9uIG9mIHRoZSBmaXJzdCBpdGVtIHdoZW4gRGVzdGluYXRpb24gaXMgcmV0dXJuZWQgYXMgYW4gYXJyYXkuXG4gKiBJdCBpcyBjcmVhdGVkIGJhc2VkIG9uIHRoZSBzYW1lIGNsYXNzIGluICdyZWFjdC1wZGYnIGxpYnJhcnk6XG4gKiBodHRwczovL2dpdGh1Yi5jb20vd29qdGVrbWFqL3JlYWN0LXBkZi9ibG9iL2NhNDQ1M2YxMjNhZjUxZTJmYWVkMzlhOGE2MjgwMDkwMTAzMDQ1OWEvc3JjL1JlZi5qc1xuICovXG5leHBvcnQgY2xhc3MgUmVmIGltcGxlbWVudHMgUGFnZVJlZmVyZW5jZSB7XG4gIG51bTogbnVtYmVyO1xuICBnZW46IG51bWJlcjtcblxuICBjb25zdHJ1Y3Rvcih7IG51bSwgZ2VuIH06IFBhZ2VSZWZlcmVuY2UpIHtcbiAgICB0aGlzLm51bSA9IG51bTtcbiAgICB0aGlzLmdlbiA9IGdlbjtcbiAgfVxuXG4gIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuZ2VuICE9PSAwID8gYCR7dGhpcy5udW19UiR7dGhpcy5nZW59YCA6IGAke3RoaXMubnVtfVJgO1xuICB9XG59XG4iLCJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBEb2N1bWVudCwgRG9jdW1lbnRQcm9wcywgcGRmanMgfSBmcm9tICdyZWFjdC1wZGYnO1xuXG5pbXBvcnQgeyBEb2N1bWVudENvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L0RvY3VtZW50Q29udGV4dCc7XG5pbXBvcnQgeyBTY3JvbGxDb250ZXh0IH0gZnJvbSAnLi4vY29udGV4dC9TY3JvbGxDb250ZXh0JztcbmltcG9ydCB7IFRyYW5zZm9ybUNvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L1RyYW5zZm9ybUNvbnRleHQnO1xuaW1wb3J0IHsgVWlDb250ZXh0IH0gZnJvbSAnLi4vY29udGV4dC9VaUNvbnRleHQnO1xuaW1wb3J0IHsgZ2V0RXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vdXRpbHMvZXJyb3JNZXNzYWdlJztcbmltcG9ydCB7IGluaXRQZGZXb3JrZXIgfSBmcm9tICcuLi91dGlscy9wZGZXb3JrZXInO1xuaW1wb3J0IHsgY29tcHV0ZVBhZ2VEaW1lbnNpb25zLCBJUERGUGFnZVByb3h5IH0gZnJvbSAnLi4vdXRpbHMvc2NhbGUnO1xuaW1wb3J0IHsgc2Nyb2xsVG9Qb3NpdGlvbiB9IGZyb20gJy4uL3V0aWxzL3Njcm9sbCc7XG5pbXBvcnQgeyBEZXN0aW5hdGlvbiwgUmVmIH0gZnJvbSAnLi90eXBlcy9kZXN0aW5hdGlvbic7XG5cbmV4cG9ydCB0eXBlIFByb3BzID0ge1xuICBjaGlsZHJlbj86IFJlYWN0LlJlYWN0Tm9kZTtcbn0gJiBEb2N1bWVudFByb3BzO1xuXG5leHBvcnQgY29uc3QgRG9jdW1lbnRXcmFwcGVyOiBSZWFjdC5GdW5jdGlvbkNvbXBvbmVudDxQcm9wcz4gPSAoe1xuICBjaGlsZHJlbixcbiAgLi4uZXh0cmFQcm9wc1xufTogUHJvcHMpID0+IHtcbiAgaW5pdFBkZldvcmtlcigpO1xuXG4gIGNvbnN0IHsgcGRmRG9jUHJveHksIHNldE51bVBhZ2VzLCBzZXRQYWdlRGltZW5zaW9ucywgc2V0UGRmRG9jUHJveHkgfSA9XG4gICAgUmVhY3QudXNlQ29udGV4dChEb2N1bWVudENvbnRleHQpO1xuICBjb25zdCB7IHJlc2V0U2Nyb2xsT2JzZXJ2ZXJzIH0gPSBSZWFjdC51c2VDb250ZXh0KFNjcm9sbENvbnRleHQpO1xuICBjb25zdCB7IHJvdGF0aW9uIH0gPSBSZWFjdC51c2VDb250ZXh0KFRyYW5zZm9ybUNvbnRleHQpO1xuICBjb25zdCB7IHNldEVycm9yTWVzc2FnZSwgc2V0SXNMb2FkaW5nIH0gPSBSZWFjdC51c2VDb250ZXh0KFVpQ29udGV4dCk7XG5cbiAgZnVuY3Rpb24gZ2V0Rmlyc3RQYWdlKHBkZkRvYzogcGRmanMuUERGRG9jdW1lbnRQcm94eSk6IFByb21pc2U8SVBERlBhZ2VQcm94eT4ge1xuICAgIC8vIGdldFBhZ2UgdXNlcyAxLWluZGV4ZWQgcGFnZU51bWJlciwgbm90IDAtaW5kZXhlZCBwYWdlSW5kZXhcbiAgICByZXR1cm4gcGRmRG9jLmdldFBhZ2UoMSk7XG4gIH1cblxuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIHJlc2V0U2Nyb2xsT2JzZXJ2ZXJzKCk7XG4gIH0sIFtdKTtcblxuICBjb25zdCBvblBkZkxvYWRTdWNjZXNzID0gUmVhY3QudXNlQ2FsbGJhY2soKHBkZkRvYzogcGRmanMuUERGRG9jdW1lbnRQcm94eSk6IHZvaWQgPT4ge1xuICAgIHNldE51bVBhZ2VzKHBkZkRvYy5udW1QYWdlcyk7XG4gICAgZ2V0Rmlyc3RQYWdlKHBkZkRvYylcbiAgICAgIC50aGVuKHBhZ2UgPT4ge1xuICAgICAgICBzZXRQYWdlRGltZW5zaW9ucyhjb21wdXRlUGFnZURpbWVuc2lvbnMocGFnZSkpO1xuICAgICAgICBzZXRFcnJvck1lc3NhZ2UobnVsbCk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgc2V0RXJyb3JNZXNzYWdlKGdldEVycm9yTWVzc2FnZShlcnJvcikpO1xuICAgICAgfSlcbiAgICAgIC5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgc2V0SXNMb2FkaW5nKGZhbHNlKTtcbiAgICAgIH0pO1xuXG4gICAgaWYgKCFwZGZEb2NQcm94eSkge1xuICAgICAgc2V0UGRmRG9jUHJveHkocGRmRG9jKTtcbiAgICB9XG4gIH0sIFtdKTtcblxuICBjb25zdCBvblBkZkxvYWRFcnJvciA9IFJlYWN0LnVzZUNhbGxiYWNrKChlcnJvcjogdW5rbm93bik6IHZvaWQgPT4ge1xuICAgIHNldEVycm9yTWVzc2FnZShnZXRFcnJvck1lc3NhZ2UoZXJyb3IpKTtcbiAgICBzZXRJc0xvYWRpbmcoZmFsc2UpO1xuICB9LCBbXSk7XG5cbiAgY29uc3Qgb25JdGVtQ2xpY2tlZCA9IChwYXJhbTogRGVzdGluYXRpb24pOiB2b2lkID0+IHtcbiAgICBpZiAoIXBkZkRvY1Byb3h5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gU2Nyb2xsIHRvIHRoZSBkZXN0aW5hdGlvbiBvZiB0aGUgaXRlbVxuICAgIHBkZkRvY1Byb3h5LmdldERlc3RpbmF0aW9uKHBhcmFtLmRlc3QpLnRoZW4oZGVzdEFycmF5ID0+IHtcbiAgICAgIGlmICghZGVzdEFycmF5KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgW3JlZiwgLCAsIGJvdHRvbVBvaW50c10gPSBkZXN0QXJyYXk7XG4gICAgICBwZGZEb2NQcm94eS5nZXRQYWdlSW5kZXgobmV3IFJlZihyZWYpKS50aGVuKHJlZkluZm8gPT4ge1xuICAgICAgICBzY3JvbGxUb1Bvc2l0aW9uKHBhcnNlSW50KHJlZkluZm8udG9TdHJpbmcoKSksIDAsIGJvdHRvbVBvaW50cywgcm90YXRpb24pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgcmV0dXJuIChcbiAgICA8RG9jdW1lbnRcbiAgICAgIG9wdGlvbnM9e3sgY01hcFVybDogJ2NtYXBzLycsIGNNYXBQYWNrZWQ6IHRydWUgfX1cbiAgICAgIG9uTG9hZEVycm9yPXtvblBkZkxvYWRFcnJvcn1cbiAgICAgIG9uTG9hZFN1Y2Nlc3M9e29uUGRmTG9hZFN1Y2Nlc3N9XG4gICAgICBleHRlcm5hbExpbmtUYXJnZXQ9XCJfYmxhbmtcIlxuICAgICAgcmVuZGVyTW9kZT1cIm5vbmVcIlxuICAgICAgLy8gQHRzLWlnbm9yZTogdGhlIGFyZ3VtZW50cyBzaG91bGQgYmUgeyBkZXN0LCBwYWdlSW5kZXgsIHBhZ2VOdW1iZXIgfVxuICAgICAgLy8gQHR5cGVzL3JlYWN0LXBkZiBoYXNuJ3QgdXBkYXRlZCB0aGUgZnVuY3Rpb24gc2lnbmF0dXJlXG4gICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vRGVmaW5pdGVseVR5cGVkL0RlZmluaXRlbHlUeXBlZC9ibG9iL2Q3M2ViNjUyZTBiYThmODkzOTVhMGVmMmJhNjljZjFlNjQwY2U1YmUvdHlwZXMvcmVhY3QtcGRmL2Rpc3QvRG9jdW1lbnQuZC50cyNMNzJcbiAgICAgIG9uSXRlbUNsaWNrPXtvbkl0ZW1DbGlja2VkfVxuICAgICAgey4uLmV4dHJhUHJvcHN9PlxuICAgICAge2NoaWxkcmVufVxuICAgIDwvRG9jdW1lbnQ+XG4gICk7XG59O1xuIiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5leHBvcnQgdHlwZSBQcm9wcyA9IHtcbiAgY2xhc3NOYW1lPzogc3RyaW5nO1xuICBjaGlsZHJlbj86IFJlYWN0LlJlYWN0Tm9kZTtcbiAgcGRmVXJsOiBzdHJpbmc7XG59O1xuXG4vKipcbiAqIEhUTUwgYW5jaG9yIHRhZyBhbGxvd3MgeW91IHRvIGRvd25sb2FkIGEgZmlsZSBmcm9tIHRoZSBzYW1lIG9yaWdpbi5cbiAqIFRoaXMgaXMgYSB3b3JrYXJvdW5kIHRvIGRvd25sb2FkIGEgZmlsZSBzZXJ2ZWQgZnJvbSBhIGRpZmZlcmVudCBvcmlnaW5cbiAqL1xuZXhwb3J0IGNvbnN0IERvd25sb2FkQnV0dG9uOiBSZWFjdC5GdW5jdGlvbkNvbXBvbmVudDxQcm9wcz4gPSAoe1xuICBwZGZVcmwsXG4gIGNoaWxkcmVuLFxuICBjbGFzc05hbWUsXG4gIC4uLmV4dHJhUHJvcHNcbn06IFByb3BzKSA9PiB7XG4gIGNvbnN0IFtmZXRjaGluZywgc2V0RmV0Y2hpbmddID0gUmVhY3QudXNlU3RhdGUoZmFsc2UpO1xuXG4gIGNvbnN0IGRvd25sb2FkID0gKCkgPT4ge1xuICAgIHNldEZldGNoaW5nKHRydWUpO1xuXG4gICAgZmV0Y2gocGRmVXJsKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4gcmVzcG9uc2UuYmxvYigpKVxuICAgICAgLnRoZW4oYmxvYiA9PiB7XG4gICAgICAgIHNldEZldGNoaW5nKGZhbHNlKTtcbiAgICAgICAgY29uc3QgYmxvYlVSTCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICAgIGNvbnN0IGEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgICAgIGEuaHJlZiA9IGJsb2JVUkw7XG4gICAgICAgIGEuZG93bmxvYWQgPSBwZGZVcmwuc3BsaXQoJy8nKS5wb3AoKSB8fCBwZGZVcmw7XG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7XG4gICAgICAgIGEuY2xpY2soKTtcbiAgICAgIH0pO1xuICB9O1xuXG4gIHJldHVybiAoXG4gICAgPGJ1dHRvblxuICAgICAgZGlzYWJsZWQ9e2ZldGNoaW5nfVxuICAgICAgb25DbGljaz17KCkgPT4gZG93bmxvYWQoKX1cbiAgICAgIGFyaWEtbGFiZWw9XCJEb3dubG9hZCBQREZcIlxuICAgICAgY2xhc3NOYW1lPXtgcmVhZGVyX19kb3dubG9hZC1idG4gJHtjbGFzc05hbWV9YH1cbiAgICAgIHsuLi5leHRyYVByb3BzfT5cbiAgICAgIHtjaGlsZHJlbiA/IGNoaWxkcmVuIDogJ0Rvd25sb2FkJ31cbiAgICA8L2J1dHRvbj5cbiAgKTtcbn07XG4iLCJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5cbmltcG9ydCB7IERvY3VtZW50Q29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvRG9jdW1lbnRDb250ZXh0JztcbmltcG9ydCB7IFRyYW5zZm9ybUNvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L1RyYW5zZm9ybUNvbnRleHQnO1xuaW1wb3J0IHsgY29tcHV0ZUJvdW5kaW5nQm94U3R5bGUsIGNvbXB1dGVQYWdlU3R5bGUgfSBmcm9tICcuLi91dGlscy9zdHlsZSc7XG5pbXBvcnQgeyBQcm9wcyBhcyBCb3VuZGluZ0JveFByb3BzIH0gZnJvbSAnLi9Cb3VuZGluZ0JveCc7XG5cbmV4cG9ydCB0eXBlIFByb3BzID0ge1xuICBjaGlsZHJlbj86IFJlYWN0LlJlYWN0RWxlbWVudDxCb3VuZGluZ0JveFByb3BzPiB8IEFycmF5PFJlYWN0LlJlYWN0RWxlbWVudDxCb3VuZGluZ0JveFByb3BzPj47XG4gIHBhZ2VJbmRleDogbnVtYmVyO1xufTtcblxuZXhwb3J0IGNvbnN0IEhpZ2hsaWdodE92ZXJsYXk6IFJlYWN0LkZ1bmN0aW9uQ29tcG9uZW50PFByb3BzPiA9ICh7XG4gIGNoaWxkcmVuLFxuICBwYWdlSW5kZXgsXG4gIC4uLmV4dHJhUHJvcHNcbn06IFByb3BzKSA9PiB7XG4gIGNvbnN0IHsgcGFnZURpbWVuc2lvbnMgfSA9IFJlYWN0LnVzZUNvbnRleHQoRG9jdW1lbnRDb250ZXh0KTtcbiAgY29uc3QgeyByb3RhdGlvbiwgc2NhbGUgfSA9IFJlYWN0LnVzZUNvbnRleHQoVHJhbnNmb3JtQ29udGV4dCk7XG4gIGNvbnN0IG1hc2tJZCA9IGBoaWdobGlnaHQtb3ZlcmxheS1tYXNrLSR7cGFnZUluZGV4fWA7XG5cbiAgY29uc3QgZ2V0UGFnZVN0eWxlID0gUmVhY3QudXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIHJldHVybiBjb21wdXRlUGFnZVN0eWxlKHBhZ2VEaW1lbnNpb25zLCByb3RhdGlvbiwgc2NhbGUpO1xuICB9LCBbcGFnZURpbWVuc2lvbnMsIHJvdGF0aW9uLCBzY2FsZV0pO1xuXG4gIGNvbnN0IGdldFVubWFza2VkQXJlYSA9IFJlYWN0LnVzZUNhbGxiYWNrKFxuICAgIChcbiAgICAgIGJvdW5kaW5nQm94ZXM6XG4gICAgICAgIHwgUmVhY3QuUmVhY3RFbGVtZW50PEJvdW5kaW5nQm94UHJvcHM+XG4gICAgICAgIHwgQXJyYXk8UmVhY3QuUmVhY3RFbGVtZW50PEJvdW5kaW5nQm94UHJvcHM+PlxuICAgICkgPT4ge1xuICAgICAgY29uc3QgYm94ZXMgPSBBcnJheS5pc0FycmF5KGJvdW5kaW5nQm94ZXMpID8gYm91bmRpbmdCb3hlcyA6IFtib3VuZGluZ0JveGVzXTtcbiAgICAgIHJldHVybiBib3hlcy5tYXAoKGJveCwgaSkgPT4ge1xuICAgICAgICBjb25zdCBib3hTdHlsZSA9IGNvbXB1dGVCb3VuZGluZ0JveFN0eWxlKGJveC5wcm9wcywgcGFnZURpbWVuc2lvbnMsIHJvdGF0aW9uLCBzY2FsZSk7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgPHJlY3Qgc3R5bGU9e2JveFN0eWxlfSB4PXtib3hTdHlsZS5sZWZ0fSB5PXtib3hTdHlsZS50b3B9IGtleT17aX0gZmlsbD1cImJsYWNrXCI+PC9yZWN0PlxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSxcbiAgICBbcGFnZURpbWVuc2lvbnMsIHJvdGF0aW9uLCBzY2FsZV1cbiAgKTtcblxuICByZXR1cm4gKFxuICAgIDxkaXYgY2xhc3NOYW1lPVwicmVhZGVyX19wYWdlLWhpZ2hsaWdodC1vdmVybGF5XCIgc3R5bGU9e2dldFBhZ2VTdHlsZSgpfSB7Li4uZXh0cmFQcm9wc30+XG4gICAgICA8c3ZnIGNsYXNzTmFtZT1cInBhZ2UtbWFza1wiIHN0eWxlPXtnZXRQYWdlU3R5bGUoKX0+XG4gICAgICAgIDxtYXNrIGlkPXttYXNrSWR9PlxuICAgICAgICAgIDxyZWN0IHN0eWxlPXtnZXRQYWdlU3R5bGUoKX0gZmlsbD1cIndoaXRlXCI+PC9yZWN0PlxuICAgICAgICAgIHtjaGlsZHJlbiAmJiBnZXRVbm1hc2tlZEFyZWEoY2hpbGRyZW4pfVxuICAgICAgICA8L21hc2s+XG4gICAgICAgIDxyZWN0IHN0eWxlPXtnZXRQYWdlU3R5bGUoKX0gZmlsbD1cIndoaXRlXCIgb3BhY2l0eT1cIjAuNlwiIG1hc2s9e2B1cmwoIyR7bWFza0lkfSlgfT48L3JlY3Q+XG4gICAgICA8L3N2Zz5cbiAgICA8L2Rpdj5cbiAgKTtcbn07XG4iLCJpbXBvcnQgY2xhc3NuYW1lcyBmcm9tICdjbGFzc25hbWVzJztcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcblxuaW1wb3J0IHsgU2Nyb2xsQ29udGV4dCB9IGZyb20gJy4uLy4uL2NvbnRleHQvU2Nyb2xsQ29udGV4dCc7XG5pbXBvcnQgeyBOb2RlRGVzdGluYXRpb24sIE91dGxpbmVOb2RlIH0gZnJvbSAnLi4vdHlwZXMvb3V0bGluZSc7XG5cbnR5cGUgUHJvcHMgPSB7XG4gIGl0ZW1zPzogQXJyYXk8T3V0bGluZU5vZGU+O1xuICBvbkNsaWNrPzogKGRlc3Q6IE5vZGVEZXN0aW5hdGlvbikgPT4gdm9pZDtcbn07XG5cbmV4cG9ydCBjb25zdCBPdXRsaW5lSXRlbTogUmVhY3QuRnVuY3Rpb25Db21wb25lbnQ8UHJvcHM+ID0gKHsgaXRlbXMsIG9uQ2xpY2sgfTogUHJvcHMpID0+IHtcbiAgY29uc3QgeyBpc091dGxpbmVUYXJnZXRWaXNpYmxlIH0gPSBSZWFjdC51c2VDb250ZXh0KFNjcm9sbENvbnRleHQpO1xuXG4gIGlmICghaXRlbXMgfHwgIWl0ZW1zLmxlbmd0aCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVuZGVySXRlbShpdGVtOiBPdXRsaW5lTm9kZSkge1xuICAgIGNvbnN0IGNsaWNrSGFuZGxlciA9IChldmVudDogYW55KSA9PiB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgaWYgKG9uQ2xpY2spIHtcbiAgICAgICAgb25DbGljayhpdGVtLmRlc3QpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBJZiBhbiBpdGVtIGhhcyBzdWIgdGl0bGVzLCByZW5kZXIgPE91dGxpbmVJdGVtIC8+XG4gICAgcmV0dXJuIChcbiAgICAgIDxsaVxuICAgICAgICBrZXk9e2l0ZW0uZGVzdD8udG9TdHJpbmcoKSB8fCBpdGVtLnRpdGxlfVxuICAgICAgICBjbGFzc05hbWU9e2NsYXNzbmFtZXMoJ3JlYWRlcl9fb3V0bGluZS1pdGVtJywge1xuICAgICAgICAgICdyZWFkZXJfX291dGxpbmUtaXRlbS0tdGFyZ2V0LXZpc2libGUnOiBpc091dGxpbmVUYXJnZXRWaXNpYmxlKGl0ZW0uZGVzdCksXG4gICAgICAgIH0pfT5cbiAgICAgICAgPGEgaHJlZj1cIiNcIiBvbkNsaWNrPXtjbGlja0hhbmRsZXJ9PlxuICAgICAgICAgIHtpdGVtLnRpdGxlfVxuICAgICAgICA8L2E+XG4gICAgICAgIDxPdXRsaW5lSXRlbSBpdGVtcz17aXRlbS5pdGVtc30gb25DbGljaz17b25DbGlja30gLz5cbiAgICAgIDwvbGk+XG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiA8dWwgY2xhc3NOYW1lPVwicmVhZGVyX19vdXRsaW5lLWl0ZW1zXCI+e2l0ZW1zLm1hcChpdGVtID0+IHJlbmRlckl0ZW0oaXRlbSkpfTwvdWw+O1xufTtcbiIsImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcblxuaW1wb3J0IHsgYnVpbGRPdXRsaW5lUG9zaXRpb25zLCBEb2N1bWVudENvbnRleHQgfSBmcm9tICcuLi8uLi9jb250ZXh0L0RvY3VtZW50Q29udGV4dCc7XG5pbXBvcnQgeyBTY3JvbGxDb250ZXh0IH0gZnJvbSAnLi4vLi4vY29udGV4dC9TY3JvbGxDb250ZXh0JztcbmltcG9ydCB7IE5vZGVEZXN0aW5hdGlvbiwgT3V0bGluZU5vZGUgfSBmcm9tICcuLi90eXBlcy9vdXRsaW5lJztcbmltcG9ydCB7IE91dGxpbmVJdGVtIH0gZnJvbSAnLi9PdXRsaW5lSXRlbSc7XG5cbmV4cG9ydCBjb25zdCBPdXRsaW5lOiBSZWFjdC5GdW5jdGlvbkNvbXBvbmVudCA9ICh7IC4uLmV4dHJhUHJvcHMgfSkgPT4ge1xuICBjb25zdCB7IG91dGxpbmUsIHBkZkRvY1Byb3h5LCBzZXRPdXRsaW5lLCBzZXRPdXRsaW5lUG9zaXRpb25zIH0gPVxuICAgIFJlYWN0LnVzZUNvbnRleHQoRG9jdW1lbnRDb250ZXh0KTtcbiAgY29uc3QgeyBzY3JvbGxUb091dGxpbmVUYXJnZXQsIHJlc2V0U2Nyb2xsT2JzZXJ2ZXJzIH0gPSBSZWFjdC51c2VDb250ZXh0KFNjcm9sbENvbnRleHQpO1xuXG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKG91dGxpbmUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIXBkZkRvY1Byb3h5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcGRmRG9jUHJveHlcbiAgICAgIC5nZXRPdXRsaW5lKClcbiAgICAgIC50aGVuKChvdXRsaW5lQXJyYXk6IEFycmF5PE91dGxpbmVOb2RlPikgPT4ge1xuICAgICAgICBzZXRPdXRsaW5lKG91dGxpbmVBcnJheSk7XG4gICAgICAgIHJldHVybiBidWlsZE91dGxpbmVQb3NpdGlvbnMocGRmRG9jUHJveHksIG91dGxpbmVBcnJheSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4ob3V0bGluZVBvc2l0aW9ucyA9PiB7XG4gICAgICAgIHNldE91dGxpbmVQb3NpdGlvbnMob3V0bGluZVBvc2l0aW9ucyk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXNldFNjcm9sbE9ic2VydmVycygpO1xuICAgICAgfSk7XG4gIH0sIFtvdXRsaW5lXSk7XG5cbiAgY29uc3QgY2xpY2tIYW5kbGVyID0gUmVhY3QudXNlQ2FsbGJhY2soKGRlc3Q6IE5vZGVEZXN0aW5hdGlvbik6IHZvaWQgPT4ge1xuICAgIGlmICghZGVzdCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzY3JvbGxUb091dGxpbmVUYXJnZXQoZGVzdCk7XG4gICAgcmV0dXJuO1xuICB9LCBbXSk7XG5cbiAgaWYgKCFwZGZEb2NQcm94eSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIChcbiAgICA8ZGl2IGNsYXNzTmFtZT1cInJlYWRlcl9fb3V0bGluZVwiIHsuLi5leHRyYVByb3BzfT5cbiAgICAgIHshIW91dGxpbmUgJiYgPE91dGxpbmVJdGVtIGl0ZW1zPXtvdXRsaW5lfSBvbkNsaWNrPXtjbGlja0hhbmRsZXJ9IC8+fVxuICAgIDwvZGl2PlxuICApO1xufTtcbiIsImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcblxuaW1wb3J0IHsgRG9jdW1lbnRDb250ZXh0IH0gZnJvbSAnLi4vY29udGV4dC9Eb2N1bWVudENvbnRleHQnO1xuaW1wb3J0IHsgVHJhbnNmb3JtQ29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvVHJhbnNmb3JtQ29udGV4dCc7XG5pbXBvcnQgeyBjb21wdXRlUGFnZVN0eWxlIH0gZnJvbSAnLi4vdXRpbHMvc3R5bGUnO1xuaW1wb3J0IHsgQm91bmRpbmdCb3ggfSBmcm9tICcuL0JvdW5kaW5nQm94JztcblxuZXhwb3J0IHR5cGUgUHJvcHMgPSB7XG4gIGNoaWxkcmVuPzogUmVhY3QuUmVhY3RFbGVtZW50PHR5cGVvZiBCb3VuZGluZ0JveD4gfCBBcnJheTxSZWFjdC5SZWFjdEVsZW1lbnQ8dHlwZW9mIEJvdW5kaW5nQm94Pj47XG59O1xuXG5leHBvcnQgY29uc3QgT3ZlcmxheTogUmVhY3QuRnVuY3Rpb25Db21wb25lbnQ8UHJvcHM+ID0gKHsgY2hpbGRyZW4sIC4uLmV4dHJhUHJvcHMgfTogUHJvcHMpID0+IHtcbiAgY29uc3QgeyBwYWdlRGltZW5zaW9ucyB9ID0gUmVhY3QudXNlQ29udGV4dChEb2N1bWVudENvbnRleHQpO1xuICBjb25zdCB7IHJvdGF0aW9uLCBzY2FsZSB9ID0gUmVhY3QudXNlQ29udGV4dChUcmFuc2Zvcm1Db250ZXh0KTtcblxuICBjb25zdCBnZXRPdmVybGF5U3R5bGUgPSBSZWFjdC51c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgcmV0dXJuIGNvbXB1dGVQYWdlU3R5bGUocGFnZURpbWVuc2lvbnMsIHJvdGF0aW9uLCBzY2FsZSk7XG4gIH0sIFtwYWdlRGltZW5zaW9ucywgcm90YXRpb24sIHNjYWxlXSk7XG5cbiAgcmV0dXJuIChcbiAgICA8ZGl2IGNsYXNzTmFtZT1cInJlYWRlcl9fcGFnZS1vdmVybGF5XCIgc3R5bGU9e2dldE92ZXJsYXlTdHlsZSgpfSB7Li4uZXh0cmFQcm9wc30+XG4gICAgICB7Y2hpbGRyZW59XG4gICAgPC9kaXY+XG4gICk7XG59O1xuIiwiaW1wb3J0IHsgTnVsbGFibGUgfSBmcm9tICcuLi9jb21wb25lbnRzL3R5cGVzL3V0aWxzJztcblxudHlwZSBWaXNpYmxlRWxlbWVudCA9IE51bGxhYmxlPG51bWJlciB8IHN0cmluZz47XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRNYXhWaXNpYmxlRWxlbWVudCh2aXNpYmxlRWxlbWVudHM6IE1hcDxWaXNpYmxlRWxlbWVudCwgbnVtYmVyPik6IFZpc2libGVFbGVtZW50IHtcbiAgbGV0IG1heFZpc2libGVLZXkgPSBudWxsO1xuICBsZXQgbWF4UmF0aW8gPSAwO1xuICBmb3IgKGNvbnN0IFt2aXNpYmxlS2V5LCByYXRpb10gb2YgdmlzaWJsZUVsZW1lbnRzKSB7XG4gICAgaWYgKG1heFJhdGlvIDwgcmF0aW8pIHtcbiAgICAgIG1heFZpc2libGVLZXkgPSB2aXNpYmxlS2V5O1xuICAgICAgbWF4UmF0aW8gPSByYXRpbztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG1heFZpc2libGVLZXk7XG59XG4iLCJpbXBvcnQgY2xhc3NuYW1lcyBmcm9tICdjbGFzc25hbWVzJztcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcblxuaW1wb3J0IHsgRG9jdW1lbnRDb250ZXh0IH0gZnJvbSAnLi4vY29udGV4dC9Eb2N1bWVudENvbnRleHQnO1xuaW1wb3J0IHsgU2Nyb2xsQ29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvU2Nyb2xsQ29udGV4dCc7XG5pbXBvcnQgeyBnZXRNYXhWaXNpYmxlRWxlbWVudCB9IGZyb20gJy4uL3V0aWxzL01heFZpc2libGVFbGVtZW50JztcblxuZXhwb3J0IHR5cGUgUHJvcHMgPSB7XG4gIGNsYXNzTmFtZT86IHN0cmluZztcbn07XG5cbnR5cGUgVE9ET19fVElNRVIgPSBhbnk7XG5cbmNvbnN0IERFTEFZX1NDUk9MTF9USU1FX09VVF9NUyA9IDEwMDA7XG5cbmV4cG9ydCBjb25zdCBQYWdlTnVtYmVyQ29udHJvbDogUmVhY3QuRnVuY3Rpb25Db21wb25lbnQ8UHJvcHM+ID0gKHsgY2xhc3NOYW1lIH06IFByb3BzKSA9PiB7XG4gIGNvbnN0IGRlbGF5VGltZXJSZWYgPSBSZWFjdC51c2VSZWY8VE9ET19fVElNRVI+KCk7XG4gIGNvbnN0IHsgbnVtUGFnZXMgfSA9IFJlYWN0LnVzZUNvbnRleHQoRG9jdW1lbnRDb250ZXh0KTtcbiAgY29uc3QgeyBzY3JvbGxUb1BhZ2UsIHZpc2libGVQYWdlUmF0aW9zIH0gPSBSZWFjdC51c2VDb250ZXh0KFNjcm9sbENvbnRleHQpO1xuICBjb25zdCBbbWluUGFnZSwgc2V0TWluUGFnZV0gPSBSZWFjdC51c2VTdGF0ZTxudW1iZXI+KDApO1xuICBjb25zdCBbdXNlcklucHV0LCBzZXRVc2VySW5wdXRdID0gUmVhY3QudXNlU3RhdGU8c3RyaW5nPignMCcpO1xuXG4gIC8vIEluaXRpYWxpemUgcGFnZSBjb250cm9sIGVsZW1lbnRcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAobnVtUGFnZXMgIT0gMCkge1xuICAgICAgc2V0TWluUGFnZSgxKTtcbiAgICB9XG4gIH0sIFtudW1QYWdlc10pO1xuXG4gIC8vIEV2ZXJ5dGltZSB3ZSBzY3JvbGwgdGhyb3VnaCB0aGUgcGFnZSB0aGlzIHVzZUVmZmVjdFxuICAvLyB3aWxsIHRyaWdnZXIgYW5kIHNldCBjdXJyZW50IHBhZ2UgYmFzZWQgb24gb3VyIGN1cnJlbnRcbiAgLy8gc2Nyb2xsIHBvc2l0aW9uXG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKHZpc2libGVQYWdlUmF0aW9zLnNpemUgIT09IDApIHtcbiAgICAgIGNvbnN0IG1heFZpc2libGVQYWdlTnVtYmVyID0gZ2V0TWF4VmlzaWJsZUVsZW1lbnQodmlzaWJsZVBhZ2VSYXRpb3MpO1xuICAgICAgaWYgKG1heFZpc2libGVQYWdlTnVtYmVyKSB7XG4gICAgICAgIHNldFVzZXJJbnB1dChtYXhWaXNpYmxlUGFnZU51bWJlci50b1N0cmluZygpKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIFt2aXNpYmxlUGFnZVJhdGlvc10pO1xuXG4gIGNvbnN0IG9uUGFnZU51bWJlckNoYW5nZSA9IFJlYWN0LnVzZUNhbGxiYWNrKFxuICAgIChldmVudDogUmVhY3QuQ2hhbmdlRXZlbnQ8SFRNTElucHV0RWxlbWVudD4pID0+IHtcbiAgICAgIGNvbnN0IHsgdmFsdWUgfSA9IGV2ZW50LmN1cnJlbnRUYXJnZXQ7XG4gICAgICAvLyBEZWNpbWFsIGNhc2VcbiAgICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcih2YWx1ZSkpIHtcbiAgICAgICAgc2V0VXNlcklucHV0KHBhcnNlSW50KHZhbHVlLCAxMCkudG9TdHJpbmcoKSk7XG4gICAgICB9XG5cbiAgICAgIHNldFVzZXJJbnB1dCh2YWx1ZSk7XG4gICAgICBpZiAoZGVsYXlUaW1lclJlZi5jdXJyZW50KSB7XG4gICAgICAgIGNsZWFyVGltZW91dChkZWxheVRpbWVyUmVmLmN1cnJlbnQpO1xuICAgICAgfVxuXG4gICAgICAvLyBBZnRlciB1c2VyIGlucHV0IHRoZSBwYWdlIHRoYXQgdGhleSB3YW50IHRvIHNjcm9sbCB0b1xuICAgICAgLy8gb3VyIHJlZiB3aWxsIHN0YXJ0IHNldHRpbmcgYSBkZWxheSBhcm91bmQgMXMgYmVmb3JlIHNjcm9sbFxuICAgICAgLy8gdG8gdGhlIHBvc2l0aW9uIHRoYXQgdXNlciBkZXNpcmVcbiAgICAgIGNvbnN0IG5ld1BhZ2VOdW1iZXIgPSBwYXJzZUludCh2YWx1ZSwgMTApO1xuICAgICAgaWYgKG5ld1BhZ2VOdW1iZXIgPj0gbWluUGFnZSAmJiBuZXdQYWdlTnVtYmVyIDw9IG51bVBhZ2VzKSB7XG4gICAgICAgIGRlbGF5VGltZXJSZWYuY3VycmVudCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHNjcm9sbFRvUGFnZSh7IHBhZ2VOdW1iZXI6IG5ld1BhZ2VOdW1iZXIgfSk7XG4gICAgICAgIH0sIERFTEFZX1NDUk9MTF9USU1FX09VVF9NUyk7XG4gICAgICB9XG4gICAgfSxcbiAgICBbbWluUGFnZSwgbnVtUGFnZXMsIHNjcm9sbFRvUGFnZV1cbiAgKTtcblxuICBjb25zdCBoYW5kbGVCbHVyID0gUmVhY3QudXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIGlmIChkZWxheVRpbWVyUmVmLmN1cnJlbnQpIHtcbiAgICAgIGNsZWFyVGltZW91dChkZWxheVRpbWVyUmVmLmN1cnJlbnQpO1xuICAgIH1cbiAgICBjb25zdCBwYWdlTnVtYmVyID0gcGFyc2VJbnQodXNlcklucHV0LCAxMCk7XG4gICAgaWYgKE51bWJlci5pc05hTihwYWdlTnVtYmVyKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGRlbGF5VGltZXJSZWYuY3VycmVudCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgc2Nyb2xsVG9QYWdlKHsgcGFnZU51bWJlcjogcGFnZU51bWJlciB9KTtcbiAgICB9LCBERUxBWV9TQ1JPTExfVElNRV9PVVRfTVMpO1xuICB9LCBbdXNlcklucHV0LCBzY3JvbGxUb1BhZ2VdKTtcblxuICByZXR1cm4gKFxuICAgIDxkaXYgY2xhc3NOYW1lPXtjbGFzc25hbWVzKCdyZWFkZXJfX3BhZ2UtbnVtYmVyLWNvbnRyb2wnLCBjbGFzc05hbWUpfT5cbiAgICAgIDxpbnB1dFxuICAgICAgICBhcmlhLWxhYmVsPVwiQ3VycmVudCBQYWdlXCJcbiAgICAgICAgY2xhc3NOYW1lPVwicmVhZGVyX19wYWdlLW51bWJlci1jb250cm9sX19jdXJyZW50LXBhZ2VcIlxuICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgbmFtZT1cImN1cnJlbnRQYWdlXCJcbiAgICAgICAgdmFsdWU9e3VzZXJJbnB1dH1cbiAgICAgICAgb25DaGFuZ2U9e29uUGFnZU51bWJlckNoYW5nZX1cbiAgICAgICAgb25CbHVyPXtoYW5kbGVCbHVyfVxuICAgICAgLz5cbiAgICAgIDxzcGFuIGNsYXNzTmFtZT1cInJlYWRlcl9fcGFnZS1udW1iZXItY29udHJvbF9fc2VwYXJhdG9yXCI+Lzwvc3Bhbj5cbiAgICAgIDxzcGFuIGFyaWEtbGFiZWw9XCJUb3RhbCBQYWdlc1wiIGNsYXNzTmFtZT1cInJlYWRlcl9fcGFnZS1udW1iZXItY29udHJvbF9fdG90YWwtcGFnZXNcIj5cbiAgICAgICAge251bVBhZ2VzfVxuICAgICAgPC9zcGFuPlxuICAgIDwvZGl2PlxuICApO1xufTtcbiIsImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IHBkZmpzIH0gZnJvbSAncmVhY3QtcGRmJztcblxuaW1wb3J0IHsgUGFnZU51bWJlciB9IGZyb20gJy4uL2NvbXBvbmVudHMvdHlwZXMvcGFnZSc7XG5pbXBvcnQgeyBOdWxsYWJsZSB9IGZyb20gJy4uL2NvbXBvbmVudHMvdHlwZXMvdXRpbHMnO1xuaW1wb3J0IHsgbG9nUHJvdmlkZXJXYXJuaW5nIH0gZnJvbSAnLi4vdXRpbHMvcHJvdmlkZXInO1xuaW1wb3J0IHsgUGFnZVJvdGF0aW9uIH0gZnJvbSAnLi4vdXRpbHMvcm90YXRlJztcbmltcG9ydCB7IFRyYW5zZm9ybUNvbnRleHQgfSBmcm9tICcuL1RyYW5zZm9ybUNvbnRleHQnO1xuXG5leHBvcnQgdHlwZSBSZW5kZXJTdGF0ZSA9IHtcbiAgcHJvbWlzZTogUHJvbWlzZTxzdHJpbmc+O1xuICBvYmplY3RVUkw6IE51bGxhYmxlPHN0cmluZz47XG59O1xuXG5leHBvcnQgdHlwZSBQYWdlTnVtYmVyVG9SZW5kZXJTdGF0ZU1hcCA9IE1hcDxudW1iZXIsIFJlbmRlclN0YXRlPjtcblxuZXhwb3J0IGludGVyZmFjZSBJUGFnZVJlbmRlckNvbnRleHQge1xuICBwYWdlUmVuZGVyU3RhdGVzOiBQYWdlTnVtYmVyVG9SZW5kZXJTdGF0ZU1hcDtcbiAgZ2V0T2JqZWN0VVJMRm9yUGFnZTogKHBhZ2VOdW1iZXI6IFBhZ2VOdW1iZXIpID0+IE51bGxhYmxlPHN0cmluZz47XG4gIGlzQnVpbGRpbmdPYmplY3RVUkxGb3JQYWdlOiAocGFnZU51bWJlcjogUGFnZU51bWJlcikgPT4gYm9vbGVhbjtcbiAgYnVpbGRPYmplY3RVUkxGb3JQYWdlOiAocGFnZU51bWJlcjogUGFnZU51bWJlcikgPT4gUHJvbWlzZTxzdHJpbmc+O1xufVxuXG5leHBvcnQgY29uc3QgUGFnZVJlbmRlckNvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PElQYWdlUmVuZGVyQ29udGV4dD4oe1xuICBwYWdlUmVuZGVyU3RhdGVzOiBuZXcgTWFwKCksXG4gIGdldE9iamVjdFVSTEZvclBhZ2U6IGFyZ3MgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgZ2V0T2JqZWN0VVJMRm9yUGFnZSgke0pTT04uc3RyaW5naWZ5KGFyZ3MpfSlgLCAnUGFnZVJlbmRlckNvbnRleHQnKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfSxcbiAgaXNCdWlsZGluZ09iamVjdFVSTEZvclBhZ2U6IGFyZ3MgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgaXNCdWlsZGluZ09iamVjdFVSTEZvclBhZ2UoJHtKU09OLnN0cmluZ2lmeShhcmdzKX0pYCwgJ1BhZ2VSZW5kZXJDb250ZXh0Jyk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9LFxuICBidWlsZE9iamVjdFVSTEZvclBhZ2U6IGFyZ3MgPT4ge1xuICAgIGxvZ1Byb3ZpZGVyV2FybmluZyhgYnVpbGRPYmplY3RVUkxGb3JQYWdlKCR7SlNPTi5zdHJpbmdpZnkoYXJncyl9KWAsICdQYWdlUmVuZGVyQ29udGV4dCcpO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoJycpO1xuICB9LFxufSk7XG5cbmV4cG9ydCBmdW5jdGlvbiB1c2VQYWdlUmVuZGVyQ29udGV4dFByb3BzKHtcbiAgcGRmRG9jUHJveHksXG4gIHNjYWxlLFxuICByb3RhdGlvbixcbiAgem9vbU11bHRpcGxpZXIsXG4gIHZpc2libGVQYWdlUmF0aW9zLFxufToge1xuICBwZGZEb2NQcm94eT86IHBkZmpzLlBERkRvY3VtZW50UHJveHk7XG4gIHNjYWxlOiBudW1iZXI7XG4gIHJvdGF0aW9uOiBQYWdlUm90YXRpb247XG4gIHpvb21NdWx0aXBsaWVyOiBudW1iZXI7XG4gIHZpc2libGVQYWdlUmF0aW9zOiBNYXA8bnVtYmVyLCBudW1iZXI+O1xufSk6IElQYWdlUmVuZGVyQ29udGV4dCB7XG4gIGNvbnN0IFtwYWdlUmVuZGVyU3RhdGVzLCBfc2V0UGFnZVJlbmRlclN0YXRlc10gPSBSZWFjdC51c2VTdGF0ZTxQYWdlTnVtYmVyVG9SZW5kZXJTdGF0ZU1hcD4oXG4gICAgKCkgPT4ge1xuICAgICAgY29uc3QgbWFwID0gbmV3IE1hcCgpO1xuICAgICAgT2JqZWN0LmZyZWV6ZShtYXApO1xuICAgICAgcmV0dXJuIG1hcDtcbiAgICB9XG4gICk7XG5cbiAgY29uc3QgeyBpc1NjYWxlQ2hhbmdlZCB9ID0gUmVhY3QudXNlQ29udGV4dChUcmFuc2Zvcm1Db250ZXh0KTtcblxuICAvLyBCZWNhdXNlIHJlbmRlcmluZyBhIHBhZ2UgaXMgYXN5bmMsIHdlIHdpbGwgbG9zZSB0aGUgY3VycmVudCBwYWdlUmVuZGVyU3RhdGVzXG4gIC8vIFRoaXMgcmVmIHRyaWNrIGFsbG93cyB0aGUgbGF0ZXN0IHRvIGJlIGFjY2Vzc2libGUgd2hlbiB0aGUgb2JqZWN0VVJMIGlzIHJlYWR5XG4gIGNvbnN0IHBhZ2VSZW5kZXJTdGF0ZXNSZWYgPSBSZWFjdC51c2VSZWYocGFnZVJlbmRlclN0YXRlcyk7XG4gIGNvbnN0IHNldFBhZ2VSZW5kZXJTdGF0ZXMgPSBSZWFjdC51c2VDYWxsYmFjayhcbiAgICAocGFnZVJlbmRlclN0YXRlczogUGFnZU51bWJlclRvUmVuZGVyU3RhdGVNYXApID0+IHtcbiAgICAgIHBhZ2VSZW5kZXJTdGF0ZXNSZWYuY3VycmVudCA9IHBhZ2VSZW5kZXJTdGF0ZXM7XG4gICAgICBfc2V0UGFnZVJlbmRlclN0YXRlcyhwYWdlUmVuZGVyU3RhdGVzKTtcbiAgICB9LFxuICAgIFtwYWdlUmVuZGVyU3RhdGVzUmVmXVxuICApO1xuXG4gIGNvbnN0IGlzQnVpbGRpbmdPYmplY3RVUkxGb3JQYWdlID0gUmVhY3QudXNlQ2FsbGJhY2soXG4gICAgKHsgcGFnZU51bWJlciwgcGFnZUluZGV4IH06IFBhZ2VOdW1iZXIpOiBib29sZWFuID0+IHtcbiAgICAgIGlmICh0eXBlb2YgcGFnZUluZGV4ID09PSAnbnVtYmVyJykge1xuICAgICAgICBwYWdlTnVtYmVyID0gcGFnZUluZGV4ICsgMTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgcGFnZU51bWJlciAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgY29uc3Qgc3RhdGUgPSBwYWdlUmVuZGVyU3RhdGVzLmdldChwYWdlTnVtYmVyKTtcbiAgICAgIGlmICghc3RhdGUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuICFzdGF0ZS5vYmplY3RVUkw7XG4gICAgfSxcbiAgICBbcGFnZVJlbmRlclN0YXRlc11cbiAgKTtcblxuICBjb25zdCBnZXRPYmplY3RVUkxGb3JQYWdlID0gUmVhY3QudXNlQ2FsbGJhY2soXG4gICAgKHsgcGFnZU51bWJlciwgcGFnZUluZGV4IH06IFBhZ2VOdW1iZXIpOiBOdWxsYWJsZTxzdHJpbmc+ID0+IHtcbiAgICAgIGlmICh0eXBlb2YgcGFnZUluZGV4ID09PSAnbnVtYmVyJykge1xuICAgICAgICBwYWdlTnVtYmVyID0gcGFnZUluZGV4ICsgMTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgcGFnZU51bWJlciAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4gcGFnZVJlbmRlclN0YXRlcy5nZXQocGFnZU51bWJlcik/Lm9iamVjdFVSTCB8fCBudWxsO1xuICAgIH0sXG4gICAgW3BhZ2VSZW5kZXJTdGF0ZXNdXG4gICk7XG5cbiAgY29uc3QgYnVpbGRPYmplY3RVUkxGb3JQYWdlID0gUmVhY3QudXNlQ2FsbGJhY2soXG4gICAgKHsgcGFnZU51bWJlciwgcGFnZUluZGV4IH06IFBhZ2VOdW1iZXIpOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgICAgaWYgKHR5cGVvZiBwYWdlSW5kZXggPT09ICdudW1iZXInKSB7XG4gICAgICAgIHBhZ2VOdW1iZXIgPSBwYWdlSW5kZXggKyAxO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBwYWdlTnVtYmVyICE9PSAnbnVtYmVyJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb3AgXCJwYWdlTnVtYmVyXCIgaXMgbm90IGEgbnVtYmVyJyk7XG4gICAgICB9XG4gICAgICBpZiAoIXBkZkRvY1Byb3h5KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IGJ1aWxkIGEgcGFnZSB1bnRpbCBhIFwicGRmRG9jUHJveHlcIiBpcyBzZXQgb24gRG9jdW1lbnRDb250ZXh0Jyk7XG4gICAgICB9XG5cbiAgICAgIC8vIERvbid0IG5lZWQgdG8gc3RhcnQgYW5vdGhlciB0YXNrIGlmIGFscmVhZHkgcmVuZGVyZWRcbiAgICAgIGNvbnN0IGV4aXN0aW5nUHJvbWlzZSA9IHBhZ2VSZW5kZXJTdGF0ZXMuZ2V0KHBhZ2VOdW1iZXIpPy5wcm9taXNlO1xuICAgICAgaWYgKGV4aXN0aW5nUHJvbWlzZSAmJiAhaXNTY2FsZUNoYW5nZWQpIHtcbiAgICAgICAgcmV0dXJuIGV4aXN0aW5nUHJvbWlzZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcHJvbWlzZSA9IGJ1aWxkUGFnZU9iamVjdFVSTCh7XG4gICAgICAgIHBhZ2VOdW1iZXIsXG4gICAgICAgIHBkZkRvY1Byb3h5LFxuICAgICAgICBzY2FsZSxcbiAgICAgICAgcm90YXRpb24sXG4gICAgICAgIHpvb21NdWx0aXBsaWVyLFxuICAgICAgfSk7XG4gICAgICBjb25zdCByZW5kZXJTdGF0ZTogUmVuZGVyU3RhdGUgPSB7XG4gICAgICAgIHByb21pc2UsXG4gICAgICAgIG9iamVjdFVSTDogbnVsbCxcbiAgICAgIH07XG4gICAgICBwcm9taXNlLnRoZW4ob2JqZWN0VVJMID0+IHtcbiAgICAgICAgcmVuZGVyU3RhdGUub2JqZWN0VVJMID0gb2JqZWN0VVJMO1xuICAgICAgICBjb25zdCBuZXdQYWdlUmVuZGVyU3RhdGVzID0gbmV3IE1hcChwYWdlUmVuZGVyU3RhdGVzUmVmLmN1cnJlbnQpO1xuICAgICAgICBPYmplY3QuZnJlZXplKG5ld1BhZ2VSZW5kZXJTdGF0ZXMpO1xuICAgICAgICBzZXRQYWdlUmVuZGVyU3RhdGVzKG5ld1BhZ2VSZW5kZXJTdGF0ZXMpO1xuICAgICAgfSk7XG4gICAgICBjb25zdCBuZXdQYWdlUmVuZGVyU3RhdGVzID0gbmV3IE1hcChwYWdlUmVuZGVyU3RhdGVzUmVmLmN1cnJlbnQpO1xuICAgICAgbmV3UGFnZVJlbmRlclN0YXRlcy5zZXQocGFnZU51bWJlciwgcmVuZGVyU3RhdGUpO1xuICAgICAgT2JqZWN0LmZyZWV6ZShuZXdQYWdlUmVuZGVyU3RhdGVzKTtcbiAgICAgIHNldFBhZ2VSZW5kZXJTdGF0ZXMobmV3UGFnZVJlbmRlclN0YXRlcyk7XG4gICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9LFxuICAgIFtwYWdlUmVuZGVyU3RhdGVzLCBwZGZEb2NQcm94eSwgc2NhbGUsIHJvdGF0aW9uLCB6b29tTXVsdGlwbGllcl1cbiAgKTtcblxuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGZvciAoY29uc3QgcGFnZU51bWJlciBvZiB2aXNpYmxlUGFnZVJhdGlvcy5rZXlzKCkpIHtcbiAgICAgIGlmIChwYWdlUmVuZGVyU3RhdGVzLmhhcyhwYWdlTnVtYmVyKSAmJiAhaXNTY2FsZUNoYW5nZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgYnVpbGRPYmplY3RVUkxGb3JQYWdlKHsgcGFnZU51bWJlciB9KTtcbiAgICB9XG4gIH0sIFtwYWdlUmVuZGVyU3RhdGVzLCB2aXNpYmxlUGFnZVJhdGlvcywgc2NhbGUsIHJvdGF0aW9uLCBkZXZpY2VQaXhlbFJhdGlvXSk7XG5cbiAgcmV0dXJuIHtcbiAgICBwYWdlUmVuZGVyU3RhdGVzLFxuICAgIGdldE9iamVjdFVSTEZvclBhZ2UsXG4gICAgaXNCdWlsZGluZ09iamVjdFVSTEZvclBhZ2UsXG4gICAgYnVpbGRPYmplY3RVUkxGb3JQYWdlLFxuICB9O1xufVxuXG4vLyBHZW5lcmF0ZSBhbiBvYmplY3QgdXJsIGZvciBhIGdpdmVuIHBhZ2UsIHJlbmRlcmVkIGluIGEgc2hhcmVkIGNhbnZhc1xuYXN5bmMgZnVuY3Rpb24gYnVpbGRQYWdlT2JqZWN0VVJMKHtcbiAgcGFnZU51bWJlcixcbiAgcGRmRG9jUHJveHksXG4gIHNjYWxlID0gMSxcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICByb3RhdGlvbiA9IFBhZ2VSb3RhdGlvbi5Sb3RhdGUwLFxuICB6b29tTXVsdGlwbGllciA9IDEuMixcbiAgaW1hZ2VUeXBlID0gJ2ltYWdlL3BuZycsXG4gIGltYWdlUXVhbGl0eSA9IDEuMCxcbn06IHtcbiAgcGFnZU51bWJlcjogbnVtYmVyO1xuICBwZGZEb2NQcm94eTogcGRmanMuUERGRG9jdW1lbnRQcm94eTtcbiAgc2NhbGU/OiBudW1iZXI7XG4gIHJvdGF0aW9uPzogUGFnZVJvdGF0aW9uO1xuICB6b29tTXVsdGlwbGllcj86IG51bWJlcjtcbiAgaW1hZ2VUeXBlPzogc3RyaW5nO1xuICBpbWFnZVF1YWxpdHk/OiBudW1iZXI7XG59KTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgcGFnZVByb3h5ID0gYXdhaXQgcGRmRG9jUHJveHkuZ2V0UGFnZShwYWdlTnVtYmVyKTtcblxuICBjb25zdCBibG9iOiBOdWxsYWJsZTxCbG9iPiA9IGF3YWl0IHVzZVJlbmRlckNhbnZhcyhhc3luYyBjYW52YXMgPT4ge1xuICAgIC8vIFJlbmRlciBwYWdlIGluIGEgY2FudmFzXG4gICAgY29uc3Qgdmlld3BvcnQgPSBwYWdlUHJveHkuZ2V0Vmlld3BvcnQoeyBzY2FsZTogc2NhbGUgKiB6b29tTXVsdGlwbGllciAqIGRldmljZVBpeGVsUmF0aW8gfSk7XG4gICAgY2FudmFzLmhlaWdodCA9IHZpZXdwb3J0LmhlaWdodDtcbiAgICBjYW52YXMud2lkdGggPSB2aWV3cG9ydC53aWR0aDtcbiAgICBjYW52YXMuc3R5bGUud2lkdGggPSAnMTAwJSc7IC8vZGUtem9vbSBjYW52YXMgd2l0aCBzdHlsZSAobWF5YmUgeW91IGNhbiBkaXJlY3RseSB1c2UgQ1NTKSwgcmVhY2hpbmcgZGUtem9vbSBvZiBoaWdoZXIgZGVmaW5pdGlvbiBQREZcbiAgICBjb25zdCBjYW52YXNDb250ZXh0ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgaWYgKCFjYW52YXNDb250ZXh0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NhbnZhcyB3YXMgdW5hYmxlIHRvIGdldCBhIGNvbnRleHQnKTtcbiAgICB9XG5cbiAgICBjb25zdCByZW5kZXJUYXNrID0gcGFnZVByb3h5LnJlbmRlcih7XG4gICAgICBjYW52YXNDb250ZXh0LFxuICAgICAgdmlld3BvcnQsXG4gICAgfSk7XG4gICAgYXdhaXQgcmVuZGVyVGFzay5wcm9taXNlO1xuXG4gICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIDE2KSk7XG5cbiAgICAvLyBGZXRjaCBhIGJsb2IgZm9yIGFuIGltYWdlIG9mIHRoZSBjYW52YXNcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY2FudmFzLnRvQmxvYihibG9iID0+IHJlc29sdmUoYmxvYiksIGltYWdlVHlwZSwgaW1hZ2VRdWFsaXR5KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIENvbnZlcnQgYmxvYiBpbWFnZSB0byBvYmplY3QgdXJsXG4gIGlmICghYmxvYikge1xuICAgIHRocm93IG5ldyBFcnJvcigndW5hYmxlIHRvIGNyZWF0ZSBpbWFnZSBmcm9tIHBhZ2UnKTtcbiAgfVxuICByZXR1cm4gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbn1cblxubGV0IHJlbmRlckNhbnZhczogTnVsbGFibGU8SFRNTENhbnZhc0VsZW1lbnQ+ID0gbnVsbDtcblxuLy8gR2V0IG9yIGNyZWF0ZSBhIHNoYXJlZCBjYW52YXMgZm9yIHJlbmRlcmluZyBwYWdlcyBpblxuZnVuY3Rpb24gZ2V0UmVuZGVyQ2FudmFzKCk6IEhUTUxDYW52YXNFbGVtZW50IHtcbiAgaWYgKCFyZW5kZXJDYW52YXMpIHtcbiAgICByZW5kZXJDYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgfVxuICByZXR1cm4gcmVuZGVyQ2FudmFzO1xufVxuXG5sZXQgbmV4dENhbnZhc1VzZTogUHJvbWlzZTxhbnk+ID0gUHJvbWlzZS5yZXNvbHZlKCk7XG5cbi8vIFVzZSB0aGUgc2hhcmVkIGNhbnZhcyB0byByZW5kZXIgYSBwYWdlLCB1c2luZyBwcm9taXNlcyB0byBjcmVhdGUgYSBxdWV1ZVxuYXN5bmMgZnVuY3Rpb24gdXNlUmVuZGVyQ2FudmFzPFQ+KGNhbGxiYWNrOiAoY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCkgPT4gUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWVtcHR5LWZ1bmN0aW9uXG4gIGxldCByZXNvbHZlID0gKF92YWx1ZTogVCB8IFByb21pc2VMaWtlPFQ+KSA9PiB7fTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1lbXB0eS1mdW5jdGlvblxuICBsZXQgcmVqZWN0ID0gKF9yZWFzb246IGFueSkgPT4ge307XG4gIGNvbnN0IHByb20gPSBuZXcgUHJvbWlzZTxUPigoX3Jlc29sdmUsIF9yZWplY3QpID0+IHtcbiAgICByZXNvbHZlID0gX3Jlc29sdmU7XG4gICAgcmVqZWN0ID0gX3JlamVjdDtcbiAgfSk7XG4gIG5leHRDYW52YXNVc2UgPSBuZXh0Q2FudmFzVXNlLnRoZW4oKCkgPT4gY2FsbGJhY2soZ2V0UmVuZGVyQ2FudmFzKCkpLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KSk7XG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHByb207XG4gIGF3YWl0IG5ldyBQcm9taXNlKHJlcyA9PiBzZXRUaW1lb3V0KHJlcywgMTYpKTsgLy8gR2l2ZSBzb21lIHRpbWUgYmV0d2VlbiByZW5kZXJzXG4gIHJldHVybiByZXN1bHQ7XG59XG4iLCJpbXBvcnQgY2xhc3NuYW1lcyBmcm9tICdjbGFzc25hbWVzJztcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IFBhZ2UgfSBmcm9tICdyZWFjdC1wZGYnO1xuaW1wb3J0IHsgUmVuZGVyRnVuY3Rpb24gfSBmcm9tICdyZWFjdC1wZGYvZGlzdC9QYWdlJztcblxuaW1wb3J0IHsgRG9jdW1lbnRDb250ZXh0IH0gZnJvbSAnLi4vY29udGV4dC9Eb2N1bWVudENvbnRleHQnO1xuaW1wb3J0IHsgUGFnZVJlbmRlckNvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L1BhZ2VSZW5kZXJDb250ZXh0JztcbmltcG9ydCB7IFRyYW5zZm9ybUNvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L1RyYW5zZm9ybUNvbnRleHQnO1xuaW1wb3J0IHsgZ2VuZXJhdGVQYWdlSWRGcm9tSW5kZXggfSBmcm9tICcuLi91dGlscy9zY3JvbGwnO1xuaW1wb3J0IHsgY29tcHV0ZVBhZ2VTdHlsZSwgZ2V0UGFnZVdpZHRoIH0gZnJvbSAnLi4vdXRpbHMvc3R5bGUnO1xuaW1wb3J0IHsgSGlnaGxpZ2h0T3ZlcmxheSB9IGZyb20gJy4vSGlnaGxpZ2h0T3ZlcmxheSc7XG5pbXBvcnQgeyBPdmVybGF5IH0gZnJvbSAnLi9PdmVybGF5JztcblxuLyoqXG4gKiBBIHN1YnNldCBvZiByZWFjdC1wZGYncyBQYWdlIGNvbXBvbmVudCBwcm9wcyBleHBvc2VkIGJ5IHRoaXMgd3JhcHBlclxuICovXG5leHBvcnQgdHlwZSBQYWdlUHJvcHMgPSB7XG4gIGVycm9yPzogc3RyaW5nIHwgUmVhY3QuUmVhY3RFbGVtZW50IHwgUmVuZGVyRnVuY3Rpb247XG4gIGxvYWRpbmc/OiBzdHJpbmcgfCBSZWFjdC5SZWFjdEVsZW1lbnQgfCBSZW5kZXJGdW5jdGlvbjtcbiAgbm9EYXRhPzogc3RyaW5nIHwgUmVhY3QuUmVhY3RFbGVtZW50IHwgUmVuZGVyRnVuY3Rpb247XG4gIHBhZ2VJbmRleDogbnVtYmVyO1xufTtcblxuZXhwb3J0IHR5cGUgUHJvcHMgPSB7XG4gIGNsYXNzTmFtZT86IHN0cmluZztcbiAgbG9hZGluZ0NvbnRlbnRGb3JCdWlsZGluZ0ltYWdlPzogUmVhY3QuUmVhY3RFbGVtZW50O1xuICBjaGlsZHJlbj86IFJlYWN0LlJlYWN0RWxlbWVudDx0eXBlb2YgSGlnaGxpZ2h0T3ZlcmxheSB8IHR5cGVvZiBPdmVybGF5Pjtcbn0gJiBQYWdlUHJvcHM7XG5cbmV4cG9ydCBjb25zdCBQYWdlV3JhcHBlcjogUmVhY3QuRnVuY3Rpb25Db21wb25lbnQ8UHJvcHM+ID0gKHtcbiAgY2hpbGRyZW4sXG4gIGVycm9yLFxuICBsb2FkaW5nLFxuICBsb2FkaW5nQ29udGVudEZvckJ1aWxkaW5nSW1hZ2UsXG4gIG5vRGF0YSxcbiAgcGFnZUluZGV4LFxuICAuLi5leHRyYVByb3BzXG59OiBQcm9wcykgPT4ge1xuICBjb25zdCB7IHJvdGF0aW9uLCBzY2FsZSB9ID0gUmVhY3QudXNlQ29udGV4dChUcmFuc2Zvcm1Db250ZXh0KTtcbiAgY29uc3QgeyBwYWdlRGltZW5zaW9ucywgZ2V0T3V0bGluZVRhcmdldHMgfSA9IFJlYWN0LnVzZUNvbnRleHQoRG9jdW1lbnRDb250ZXh0KTtcbiAgY29uc3QgeyBnZXRPYmplY3RVUkxGb3JQYWdlLCBpc0J1aWxkaW5nT2JqZWN0VVJMRm9yUGFnZSB9ID0gUmVhY3QudXNlQ29udGV4dChQYWdlUmVuZGVyQ29udGV4dCk7XG5cbiAgY29uc3Qgb2JqZWN0VVJMRm9yUGFnZSA9IGdldE9iamVjdFVSTEZvclBhZ2UoeyBwYWdlSW5kZXggfSk7XG4gIGNvbnN0IGlzQnVpbGRpbmdQYWdlSW1hZ2UgPSBpc0J1aWxkaW5nT2JqZWN0VVJMRm9yUGFnZSh7IHBhZ2VJbmRleCB9KTtcblxuICAvLyBEb24ndCBkaXNwbGF5IHVudGlsIHdlIGhhdmUgcGFnZSBzaXplIGRhdGFcbiAgLy8gVE9ETzogSGFuZGxlIHRoaXMgbmljZXIgc28gd2UgZGlzcGxheSBlaXRoZXIgdGhlIGxvYWRpbmcgb3IgZXJyb3IgdHJlYXRtZW50XG4gIGlmICghcGFnZURpbWVuc2lvbnMpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGdldFBhZ2VTdHlsZSA9IFJlYWN0LnVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBjb25zdCBzdHlsZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0gY29tcHV0ZVBhZ2VTdHlsZShwYWdlRGltZW5zaW9ucywgcm90YXRpb24sIHNjYWxlKTtcbiAgICBpZiAob2JqZWN0VVJMRm9yUGFnZSkge1xuICAgICAgc3R5bGVzLmJhY2tncm91bmRJbWFnZSA9IGB1cmwoJHtvYmplY3RVUkxGb3JQYWdlfSlgO1xuICAgIH1cbiAgICByZXR1cm4gc3R5bGVzO1xuICB9LCBbcGFnZURpbWVuc2lvbnMsIHJvdGF0aW9uLCBzY2FsZSwgb2JqZWN0VVJMRm9yUGFnZV0pO1xuXG4gIGNvbnN0IGdldFdpZHRoID0gUmVhY3QudXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIHJldHVybiBnZXRQYWdlV2lkdGgocGFnZURpbWVuc2lvbnMsIHJvdGF0aW9uKTtcbiAgfSwgW3BhZ2VEaW1lbnNpb25zLCByb3RhdGlvbl0pO1xuXG4gIGNvbnN0IG91dGxpbmVUYXJnZXRzID0gZ2V0T3V0bGluZVRhcmdldHMoeyBwYWdlSW5kZXgsIHNjYWxlLCByb3RhdGlvbiwgcGFnZURpbWVuc2lvbnMgfSk7XG5cbiAgLy8gV2lkdGggbmVlZHMgdG8gYmUgc2V0IHRvIHByZXZlbnQgdGhlIG91dGVybW9zdCBQYWdlIGRpdiBmcm9tIGV4dGVuZGluZyB0byBmaXQgdGhlIHBhcmVudCxcbiAgLy8gYW5kIG1pcy1hbGlnbmluZyB0aGUgdGV4dCBsYXllci5cbiAgLy8gVE9ETzogQ2FuIHdlIENTUyB0aGlzIHRvIGF1dG8tc2hyaW5rP1xuICByZXR1cm4gKFxuICAgIDxkaXZcbiAgICAgIGlkPXtnZW5lcmF0ZVBhZ2VJZEZyb21JbmRleChwYWdlSW5kZXgpfVxuICAgICAgY2xhc3NOYW1lPXtjbGFzc25hbWVzKFxuICAgICAgICAncmVhZGVyX19wYWdlJyxcbiAgICAgICAgeyAncmVhZGVyX19wYWdlLS1oYXMtcGFnZS1pbWFnZSc6IG9iamVjdFVSTEZvclBhZ2UgfSxcbiAgICAgICAgeyAncmVhZGVyX19wYWdlLS1uby1wYWdlLWltYWdlJzogIW9iamVjdFVSTEZvclBhZ2UgfSxcbiAgICAgICAgeyAncmVhZGVyX19wYWdlLS1pcy1idWlsZGluZy1wYWdlLWltYWdlJzogaXNCdWlsZGluZ1BhZ2VJbWFnZSB9XG4gICAgICApfVxuICAgICAgZGF0YS1wYWdlLW51bWJlcj17cGFnZUluZGV4ICsgMX1cbiAgICAgIHN0eWxlPXtnZXRQYWdlU3R5bGUoKX1cbiAgICAgIHsuLi5leHRyYVByb3BzfT5cbiAgICAgIHtjaGlsZHJlbn1cbiAgICAgIHtpc0J1aWxkaW5nUGFnZUltYWdlICYmIChcbiAgICAgICAgPGRpdlxuICAgICAgICAgIGNsYXNzTmFtZT17Y2xhc3NuYW1lcygncmVhZGVyX19wYWdlJywge1xuICAgICAgICAgICAgJ3JlYWRlcl9fcGFnZS0taXMtbG9hZGluZy1pbWFnZSc6IGlzQnVpbGRpbmdQYWdlSW1hZ2UsXG4gICAgICAgICAgfSl9PlxuICAgICAgICAgIHtsb2FkaW5nQ29udGVudEZvckJ1aWxkaW5nSW1hZ2V9XG4gICAgICAgIDwvZGl2PlxuICAgICAgKX1cbiAgICAgIDxQYWdlXG4gICAgICAgIHdpZHRoPXtnZXRXaWR0aCgpfVxuICAgICAgICBlcnJvcj17ZXJyb3J9XG4gICAgICAgIGxvYWRpbmc9e2xvYWRpbmd9XG4gICAgICAgIG5vRGF0YT17bm9EYXRhfVxuICAgICAgICBwYWdlSW5kZXg9e3BhZ2VJbmRleH1cbiAgICAgICAgc2NhbGU9e3NjYWxlfVxuICAgICAgICByb3RhdGU9e3JvdGF0aW9ufVxuICAgICAgICByZW5kZXJBbm5vdGF0aW9uTGF5ZXI9e3RydWV9XG4gICAgICAvPlxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJyZWFkZXJfX3BhZ2VfX291dGxpbmUtdGFyZ2V0c1wiPlxuICAgICAgICB7b3V0bGluZVRhcmdldHMubWFwKCh7IGRlc3QsIGxlZnRQeCwgdG9wUHggfSkgPT4gKFxuICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICBrZXk9e2Rlc3R9XG4gICAgICAgICAgICBjbGFzc05hbWU9XCJyZWFkZXJfX3BhZ2VfX291dGxpbmUtdGFyZ2V0XCJcbiAgICAgICAgICAgIGRhdGEtb3V0bGluZS10YXJnZXQtZGVzdD17ZGVzdH1cbiAgICAgICAgICAgIHN0eWxlPXt7IGxlZnQ6IGxlZnRQeCArICdweCcsIHRvcDogdG9wUHggKyAncHgnIH19XG4gICAgICAgICAgLz5cbiAgICAgICAgKSl9XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgKTtcbn07XG4iLCIvLyBIZWlnaHQgYW5kIHdpZHRoIGFyZSBpbiBzY3JlZW4gcGl4ZWwgdW5pdHMgYXQgMTAwJSBzY2FsaW5nIG9mIHRoZSBwYWdlXG5leHBvcnQgdHlwZSBEaW1lbnNpb25zID0ge1xuICBoZWlnaHQ6IG51bWJlcjtcbiAgd2lkdGg6IG51bWJlcjtcbn07XG5cbi8vIFRvcCBhbmQgbGVmdCBhcmUgaW4gc2NyZWVuIHBpeGVsIHVuaXRzIGF0IDEwMCUgc2NhbGluZyBvZiB0aGUgcGFnZVxuZXhwb3J0IHR5cGUgT3JpZ2luID0ge1xuICB0b3A6IG51bWJlcjtcbiAgbGVmdDogbnVtYmVyO1xufTtcblxuZXhwb3J0IHR5cGUgU2l6ZSA9IERpbWVuc2lvbnMgJiBPcmlnaW47XG5cbmV4cG9ydCB0eXBlIEJvdW5kaW5nQm94ID0ge1xuICBwYWdlOiBudW1iZXI7XG59ICYgU2l6ZTtcblxuLy8gUmF3IEJvdW5kaW5nQm94ZXMgdG9wLCBsZWZ0LCBoZWlnaHQsIGFuZCB3aWR0aCBhdHRyaWJ1dGVzIGFyZSBleHByZXNzZWQgYXMgYSByYXRpbyBvZiB0aGVcbi8vIHBhZ2UgaGVpZ2h0L3dpZHRoIGFuZCBuZWVkIHRvIGJlIHNjYWxlZCBhY2NvcmRpbmcgdG8gcGFnZSBzaXplIGJlZm9yZSB0aGV5IGNhbiBiZSByZW5kZXJlZFxuZXhwb3J0IHR5cGUgUmF3Qm91bmRpbmdCb3ggPSBCb3VuZGluZ0JveDtcblxuLy8gQ2FsY3VsYXRlIGEgYm91bmRpbmcgYm94J3MgcGl4ZWwgY29vcmRpbmF0ZXMgZnJvbSB0aGUgcmF3IGJvdW5kaW5nIGJveCdzIGNvb3JkaXRhdGUgcmF0aW9zIHNjYWxlZCB0byB0aGUgcGFnZSBzaXplXG5leHBvcnQgZnVuY3Rpb24gc2NhbGVSYXdCb3VuZGluZ0JveChcbiAgYm91bmRpbmdCb3hSYXc6IFJhd0JvdW5kaW5nQm94LFxuICBwYWdlSGVpZ2h0OiBudW1iZXIsXG4gIHBhZ2VXaWR0aDogbnVtYmVyXG4pOiBCb3VuZGluZ0JveCB7XG4gIGNvbnN0IGJveFNjYWxlZDogQm91bmRpbmdCb3ggPSB7XG4gICAgcGFnZTogYm91bmRpbmdCb3hSYXcucGFnZSxcbiAgICB0b3A6IGJvdW5kaW5nQm94UmF3LnRvcCAqIHBhZ2VIZWlnaHQsXG4gICAgbGVmdDogYm91bmRpbmdCb3hSYXcubGVmdCAqIHBhZ2VXaWR0aCxcbiAgICBoZWlnaHQ6IGJvdW5kaW5nQm94UmF3LmhlaWdodCAqIHBhZ2VIZWlnaHQsXG4gICAgd2lkdGg6IGJvdW5kaW5nQm94UmF3LndpZHRoICogcGFnZVdpZHRoLFxuICB9O1xuXG4gIHJldHVybiBib3hTY2FsZWQ7XG59XG4iLCJleHBvcnQgY29uc3QgUGVyY2VudEZvcm1hdHRlciA9IG5ldyBJbnRsLk51bWJlckZvcm1hdCgnZW4tVVMnLCB7XG4gIHN0eWxlOiAncGVyY2VudCcsXG4gIG1heGltdW1TaWduaWZpY2FudERpZ2l0czogMyxcbn0pO1xuIiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5pbXBvcnQgeyBTY3JvbGxDb250ZXh0IH0gZnJvbSAnLi4vY29udGV4dC9TY3JvbGxDb250ZXh0JztcbmltcG9ydCB7IFRyYW5zZm9ybUNvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L1RyYW5zZm9ybUNvbnRleHQnO1xuaW1wb3J0IHsgUGVyY2VudEZvcm1hdHRlciB9IGZyb20gJy4uL3V0aWxzL2Zvcm1hdCc7XG5cbmV4cG9ydCB0eXBlIFByb3BzID0ge1xuICBjaGlsZHJlbj86IFJlYWN0LlJlYWN0Tm9kZTtcbn07XG5cbmNvbnN0IE1BWF9aT09NX0lOX1NDQUxFID0gNTAwO1xuXG5leHBvcnQgY29uc3QgWm9vbUluQnV0dG9uOiBSZWFjdC5GdW5jdGlvbkNvbXBvbmVudDxQcm9wcz4gPSAoe1xuICBjaGlsZHJlbixcbiAgLi4uZXh0cmFQcm9wc1xufTogUHJvcHMpID0+IHtcbiAgY29uc3QgeyBzY2FsZSwgc2V0U2NhbGUsIHpvb21NdWx0aXBsaWVyLCBzZXRJc1NjYWxlQ2hhbmdlZCB9ID0gUmVhY3QudXNlQ29udGV4dChUcmFuc2Zvcm1Db250ZXh0KTtcbiAgY29uc3QgeyB1cGRhdGVTY3JvbGxQb3NpdGlvbiB9ID0gUmVhY3QudXNlQ29udGV4dChTY3JvbGxDb250ZXh0KTtcblxuICBjb25zdCBoYW5kbGVab29tSW4gPSBSZWFjdC51c2VDYWxsYmFjayhcbiAgICAoZXZlbnQpOiB2b2lkID0+IHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGNvbnN0IHpvb21TY2FsZSA9IE51bWJlcihQZXJjZW50Rm9ybWF0dGVyLmZvcm1hdChzY2FsZSAqIHpvb21NdWx0aXBsaWVyKS5yZXBsYWNlKCclJywgJycpKTtcbiAgICAgIGlmICh6b29tU2NhbGUgPD0gTUFYX1pPT01fSU5fU0NBTEUpIHtcbiAgICAgICAgc2V0SXNTY2FsZUNoYW5nZWQodHJ1ZSk7XG4gICAgICAgIHVwZGF0ZVNjcm9sbFBvc2l0aW9uKDEgKiB6b29tTXVsdGlwbGllcik7XG4gICAgICAgIHNldFNjYWxlKHNjYWxlICogem9vbU11bHRpcGxpZXIpO1xuICAgICAgfVxuICAgIH0sXG4gICAgW3NjYWxlLCB6b29tTXVsdGlwbGllciwgdXBkYXRlU2Nyb2xsUG9zaXRpb25dXG4gICk7XG5cbiAgcmV0dXJuIChcbiAgICA8YnV0dG9uIGNsYXNzTmFtZT1cInJlYWRlcl9fem9vbS1idG4gem9vbS1pblwiIG9uQ2xpY2s9e2hhbmRsZVpvb21Jbn0gey4uLmV4dHJhUHJvcHN9PlxuICAgICAge2NoaWxkcmVuID8gY2hpbGRyZW4gOiAnKyd9XG4gICAgPC9idXR0b24+XG4gICk7XG59O1xuIiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5pbXBvcnQgeyBTY3JvbGxDb250ZXh0IH0gZnJvbSAnLi4vY29udGV4dC9TY3JvbGxDb250ZXh0JztcbmltcG9ydCB7IFRyYW5zZm9ybUNvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L1RyYW5zZm9ybUNvbnRleHQnO1xuaW1wb3J0IHsgUGVyY2VudEZvcm1hdHRlciB9IGZyb20gJy4uL3V0aWxzL2Zvcm1hdCc7XG5cbmV4cG9ydCB0eXBlIFByb3BzID0ge1xuICBjaGlsZHJlbj86IFJlYWN0LlJlYWN0Tm9kZTtcbn07XG5cbmNvbnN0IE1JTl9aT09NX09VVF9TQ0FMRSA9IDI1O1xuXG5leHBvcnQgY29uc3QgWm9vbU91dEJ1dHRvbjogUmVhY3QuRnVuY3Rpb25Db21wb25lbnQgPSAoeyBjaGlsZHJlbiwgLi4uZXh0cmFQcm9wcyB9OiBQcm9wcykgPT4ge1xuICBjb25zdCB7IHNjYWxlLCBzZXRTY2FsZSwgem9vbU11bHRpcGxpZXIsIHNldElzU2NhbGVDaGFuZ2VkIH0gPSBSZWFjdC51c2VDb250ZXh0KFRyYW5zZm9ybUNvbnRleHQpO1xuICBjb25zdCB7IHVwZGF0ZVNjcm9sbFBvc2l0aW9uIH0gPSBSZWFjdC51c2VDb250ZXh0KFNjcm9sbENvbnRleHQpO1xuXG4gIGNvbnN0IGhhbmRsZVpvb21PdXQgPSBSZWFjdC51c2VDYWxsYmFjayhcbiAgICAoZXZlbnQpOiB2b2lkID0+IHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGNvbnN0IHpvb21TY2FsZSA9IE51bWJlcihQZXJjZW50Rm9ybWF0dGVyLmZvcm1hdChzY2FsZSAvIHpvb21NdWx0aXBsaWVyKS5yZXBsYWNlKCclJywgJycpKTtcbiAgICAgIGlmICh6b29tU2NhbGUgPj0gTUlOX1pPT01fT1VUX1NDQUxFKSB7XG4gICAgICAgIHNldElzU2NhbGVDaGFuZ2VkKHRydWUpO1xuICAgICAgICB1cGRhdGVTY3JvbGxQb3NpdGlvbigxIC8gem9vbU11bHRpcGxpZXIpO1xuICAgICAgICBzZXRTY2FsZShzY2FsZSAvIHpvb21NdWx0aXBsaWVyKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIFtzY2FsZSwgem9vbU11bHRpcGxpZXIsIHVwZGF0ZVNjcm9sbFBvc2l0aW9uXVxuICApO1xuXG4gIHJldHVybiAoXG4gICAgPGJ1dHRvbiBjbGFzc05hbWU9XCJyZWFkZXJfX3pvb20tYnRuIHpvb20tb3V0XCIgb25DbGljaz17aGFuZGxlWm9vbU91dH0gey4uLmV4dHJhUHJvcHN9PlxuICAgICAge2NoaWxkcmVuID8gY2hpbGRyZW4gOiAnLSd9XG4gICAgPC9idXR0b24+XG4gICk7XG59O1xuIiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5pbXBvcnQgeyBEb2N1bWVudENvbnRleHQsIHVzZURvY3VtZW50Q29udGV4dFByb3BzIH0gZnJvbSAnLi9Eb2N1bWVudENvbnRleHQnO1xuaW1wb3J0IHsgUGFnZVJlbmRlckNvbnRleHQsIHVzZVBhZ2VSZW5kZXJDb250ZXh0UHJvcHMgfSBmcm9tICcuL1BhZ2VSZW5kZXJDb250ZXh0JztcbmltcG9ydCB7IFNjcm9sbENvbnRleHQsIHVzZVNjcm9sbENvbnRleHRQcm9wcyB9IGZyb20gJy4vU2Nyb2xsQ29udGV4dCc7XG5pbXBvcnQgeyBUcmFuc2Zvcm1Db250ZXh0LCB1c2VUcmFuc2Zvcm1Db250ZXh0UHJvcHMgfSBmcm9tICcuL1RyYW5zZm9ybUNvbnRleHQnO1xuaW1wb3J0IHsgVWlDb250ZXh0LCB1c2VVaUNvbnRleHRQcm9wcyB9IGZyb20gJy4vVWlDb250ZXh0JztcblxuZXhwb3J0IHR5cGUgUHJvcHMgPSB7XG4gIGNoaWxkcmVuPzogUmVhY3QuUmVhY3RFbGVtZW50IHwgQXJyYXk8UmVhY3QuUmVhY3RFbGVtZW50Pjtcbn07XG5cbmV4cG9ydCBjb25zdCBDb250ZXh0UHJvdmlkZXI6IFJlYWN0LkZ1bmN0aW9uQ29tcG9uZW50PFByb3BzPiA9ICh7IGNoaWxkcmVuIH06IFByb3BzKSA9PiB7XG4gIGNvbnN0IGRvY3VtZW50UHJvcHMgPSB1c2VEb2N1bWVudENvbnRleHRQcm9wcygpO1xuICBjb25zdCB0cmFuc2Zvcm1Qcm9wcyA9IHVzZVRyYW5zZm9ybUNvbnRleHRQcm9wcygpO1xuICBjb25zdCB1aVByb3BzID0gdXNlVWlDb250ZXh0UHJvcHMoKTtcbiAgY29uc3Qgc2Nyb2xsUHJvcHMgPSB1c2VTY3JvbGxDb250ZXh0UHJvcHMoKTtcbiAgY29uc3QgcGFnZVJlbmRlclByb3BzID0gdXNlUGFnZVJlbmRlckNvbnRleHRQcm9wcyh7XG4gICAgcGRmRG9jUHJveHk6IGRvY3VtZW50UHJvcHMucGRmRG9jUHJveHksXG4gICAgc2NhbGU6IHRyYW5zZm9ybVByb3BzLnNjYWxlLFxuICAgIHJvdGF0aW9uOiB0cmFuc2Zvcm1Qcm9wcy5yb3RhdGlvbixcbiAgICB6b29tTXVsdGlwbGllcjogdHJhbnNmb3JtUHJvcHMuem9vbU11bHRpcGxpZXIsXG4gICAgdmlzaWJsZVBhZ2VSYXRpb3M6IHNjcm9sbFByb3BzLnZpc2libGVQYWdlUmF0aW9zLFxuICB9KTtcblxuICByZXR1cm4gKFxuICAgIDxEb2N1bWVudENvbnRleHQuUHJvdmlkZXIgdmFsdWU9e2RvY3VtZW50UHJvcHN9PlxuICAgICAgPFRyYW5zZm9ybUNvbnRleHQuUHJvdmlkZXIgdmFsdWU9e3RyYW5zZm9ybVByb3BzfT5cbiAgICAgICAgPFVpQ29udGV4dC5Qcm92aWRlciB2YWx1ZT17dWlQcm9wc30+XG4gICAgICAgICAgPFNjcm9sbENvbnRleHQuUHJvdmlkZXIgdmFsdWU9e3Njcm9sbFByb3BzfT5cbiAgICAgICAgICAgIDxQYWdlUmVuZGVyQ29udGV4dC5Qcm92aWRlciB2YWx1ZT17cGFnZVJlbmRlclByb3BzfT5cbiAgICAgICAgICAgICAge2NoaWxkcmVufVxuICAgICAgICAgICAgPC9QYWdlUmVuZGVyQ29udGV4dC5Qcm92aWRlcj5cbiAgICAgICAgICA8L1Njcm9sbENvbnRleHQuUHJvdmlkZXI+XG4gICAgICAgIDwvVWlDb250ZXh0LlByb3ZpZGVyPlxuICAgICAgPC9UcmFuc2Zvcm1Db250ZXh0LlByb3ZpZGVyPlxuICAgIDwvRG9jdW1lbnRDb250ZXh0LlByb3ZpZGVyPlxuICApO1xufTtcbiIsIi8qXG4gKiBQREYgQ29tcG9uZW50IExpYnJhcnkgZXhwb3J0c1xuICovXG5cbmltcG9ydCAnLi9sZXNzL2luZGV4Lmxlc3MnO1xuXG5pbXBvcnQgeyBCb3VuZGluZ0JveCwgUHJvcHMgYXMgQm91bmRpbmdCb3hQcm9wcyB9IGZyb20gJy4vc3JjL2NvbXBvbmVudHMvQm91bmRpbmdCb3gnO1xuaW1wb3J0IHsgRG9jdW1lbnRXcmFwcGVyLCBQcm9wcyBhcyBEb2N1bWVudFdyYXBwZXJQcm9wcyB9IGZyb20gJy4vc3JjL2NvbXBvbmVudHMvRG9jdW1lbnRXcmFwcGVyJztcbmltcG9ydCB7IERvd25sb2FkQnV0dG9uLCBQcm9wcyBhcyBEb3dubG9hZEJ1dHRvblByb3BzIH0gZnJvbSAnLi9zcmMvY29tcG9uZW50cy9Eb3dubG9hZEJ1dHRvbic7XG5pbXBvcnQge1xuICBIaWdobGlnaHRPdmVybGF5LFxuICBQcm9wcyBhcyBIaWdobGlnaHRPdmVybGF5UHJvcHMsXG59IGZyb20gJy4vc3JjL2NvbXBvbmVudHMvSGlnaGxpZ2h0T3ZlcmxheSc7XG5pbXBvcnQgeyBPdXRsaW5lIH0gZnJvbSAnLi9zcmMvY29tcG9uZW50cy9vdXRsaW5lL091dGxpbmUnO1xuaW1wb3J0IHsgT3V0bGluZUl0ZW0gfSBmcm9tICcuL3NyYy9jb21wb25lbnRzL291dGxpbmUvT3V0bGluZUl0ZW0nO1xuaW1wb3J0IHsgT3ZlcmxheSwgUHJvcHMgYXMgT3ZlcmxheVByb3BzIH0gZnJvbSAnLi9zcmMvY29tcG9uZW50cy9PdmVybGF5JztcbmltcG9ydCB7IFBhZ2VOdW1iZXJDb250cm9sIH0gZnJvbSAnLi9zcmMvY29tcG9uZW50cy9QYWdlTnVtYmVyQ29udHJvbCc7XG5pbXBvcnQgeyBQYWdlUHJvcHMsIFBhZ2VXcmFwcGVyLCBQcm9wcyBhcyBQYWdlV3JhcHBlclByb3BzIH0gZnJvbSAnLi9zcmMvY29tcG9uZW50cy9QYWdlV3JhcHBlcic7XG5pbXBvcnQge1xuICBCb3VuZGluZ0JveCBhcyBCb3VuZGluZ0JveFR5cGUsXG4gIERpbWVuc2lvbnMsXG4gIE9yaWdpbixcbiAgUmF3Qm91bmRpbmdCb3gsXG4gIHNjYWxlUmF3Qm91bmRpbmdCb3gsXG4gIFNpemUsXG59IGZyb20gJy4vc3JjL2NvbXBvbmVudHMvdHlwZXMvYm91bmRpbmdCb3gnO1xuaW1wb3J0IHsgTm9kZURlc3RpbmF0aW9uLCBPdXRsaW5lTm9kZSB9IGZyb20gJy4vc3JjL2NvbXBvbmVudHMvdHlwZXMvb3V0bGluZSc7XG5pbXBvcnQgeyBQYWdlUHJvcGVydGllcywgUGFnZVJlZmVyZW5jZSB9IGZyb20gJy4vc3JjL2NvbXBvbmVudHMvdHlwZXMvcGFnZSc7XG5pbXBvcnQgeyBOdWxsYWJsZSB9IGZyb20gJy4vc3JjL2NvbXBvbmVudHMvdHlwZXMvdXRpbHMnO1xuaW1wb3J0IHsgWm9vbUluQnV0dG9uIH0gZnJvbSAnLi9zcmMvY29tcG9uZW50cy9ab29tSW5CdXR0b24nO1xuaW1wb3J0IHsgWm9vbU91dEJ1dHRvbiB9IGZyb20gJy4vc3JjL2NvbXBvbmVudHMvWm9vbU91dEJ1dHRvbic7XG5pbXBvcnQgeyBDb250ZXh0UHJvdmlkZXIsIFByb3BzIGFzIENvbnRleHRQcm92aWRlclByb3BzIH0gZnJvbSAnLi9zcmMvY29udGV4dC9Db250ZXh0UHJvdmlkZXInO1xuaW1wb3J0IHsgRG9jdW1lbnRDb250ZXh0LCBJRG9jdW1lbnRDb250ZXh0IH0gZnJvbSAnLi9zcmMvY29udGV4dC9Eb2N1bWVudENvbnRleHQnO1xuaW1wb3J0IHsgSVNjcm9sbENvbnRleHQsIFNjcm9sbENvbnRleHQgfSBmcm9tICcuL3NyYy9jb250ZXh0L1Njcm9sbENvbnRleHQnO1xuaW1wb3J0IHsgSVRyYW5zZm9ybUNvbnRleHQsIFRyYW5zZm9ybUNvbnRleHQgfSBmcm9tICcuL3NyYy9jb250ZXh0L1RyYW5zZm9ybUNvbnRleHQnO1xuaW1wb3J0IHsgSVVpQ29udGV4dCwgVWlDb250ZXh0IH0gZnJvbSAnLi9zcmMvY29udGV4dC9VaUNvbnRleHQnO1xuaW1wb3J0IHtcbiAgaXNTaWRld2F5cyxcbiAgUGFnZVJvdGF0aW9uLFxuICByb3RhdGVDbG9ja3dpc2UsXG4gIHJvdGF0ZUNvdW50ZXJDbG9ja3dpc2UsXG59IGZyb20gJy4vc3JjL3V0aWxzL3JvdGF0ZSc7XG5pbXBvcnQgeyBnZW5lcmF0ZVBhZ2VJZEZyb21JbmRleCwgc2Nyb2xsVG9JZCwgc2Nyb2xsVG9QZGZQYWdlSW5kZXggfSBmcm9tICcuL3NyYy91dGlscy9zY3JvbGwnO1xuaW1wb3J0IHtcbiAgY29tcHV0ZUJvdW5kaW5nQm94U3R5bGUsXG4gIGNvbXB1dGVQYWdlU3R5bGUsXG4gIGdldFBhZ2VIZWlnaHQsXG4gIGdldFBhZ2VXaWR0aCxcbn0gZnJvbSAnLi9zcmMvdXRpbHMvc3R5bGUnO1xuXG5leHBvcnQgdHlwZSB7XG4gIEJvdW5kaW5nQm94UHJvcHMsXG4gIEJvdW5kaW5nQm94VHlwZSxcbiAgQ29udGV4dFByb3ZpZGVyUHJvcHMsXG4gIERpbWVuc2lvbnMsXG4gIERvY3VtZW50V3JhcHBlclByb3BzLFxuICBEb3dubG9hZEJ1dHRvblByb3BzLFxuICBIaWdobGlnaHRPdmVybGF5UHJvcHMsXG4gIElEb2N1bWVudENvbnRleHQsXG4gIElTY3JvbGxDb250ZXh0LFxuICBJVHJhbnNmb3JtQ29udGV4dCxcbiAgSVVpQ29udGV4dCxcbiAgTm9kZURlc3RpbmF0aW9uLFxuICBOdWxsYWJsZSxcbiAgT3JpZ2luLFxuICBPdXRsaW5lTm9kZSxcbiAgT3ZlcmxheVByb3BzLFxuICBQYWdlUHJvcGVydGllcyxcbiAgUGFnZVByb3BzLFxuICBQYWdlUmVmZXJlbmNlLFxuICBQYWdlUm90YXRpb24sXG4gIFBhZ2VXcmFwcGVyUHJvcHMsXG4gIFJhd0JvdW5kaW5nQm94LFxuICBTaXplLFxufTtcblxuZXhwb3J0IHtcbiAgQm91bmRpbmdCb3gsXG4gIGNvbXB1dGVCb3VuZGluZ0JveFN0eWxlLFxuICBjb21wdXRlUGFnZVN0eWxlLFxuICBDb250ZXh0UHJvdmlkZXIsXG4gIERvY3VtZW50Q29udGV4dCxcbiAgRG9jdW1lbnRXcmFwcGVyLFxuICBEb3dubG9hZEJ1dHRvbixcbiAgZ2VuZXJhdGVQYWdlSWRGcm9tSW5kZXgsXG4gIGdldFBhZ2VIZWlnaHQsXG4gIGdldFBhZ2VXaWR0aCxcbiAgSGlnaGxpZ2h0T3ZlcmxheSxcbiAgaXNTaWRld2F5cyxcbiAgT3V0bGluZSxcbiAgT3V0bGluZUl0ZW0sXG4gIE92ZXJsYXksXG4gIFBhZ2VOdW1iZXJDb250cm9sLFxuICBQYWdlV3JhcHBlcixcbiAgcm90YXRlQ2xvY2t3aXNlLFxuICByb3RhdGVDb3VudGVyQ2xvY2t3aXNlLFxuICBzY2FsZVJhd0JvdW5kaW5nQm94LFxuICBTY3JvbGxDb250ZXh0LFxuICBzY3JvbGxUb0lkLFxuICBzY3JvbGxUb1BkZlBhZ2VJbmRleCxcbiAgVHJhbnNmb3JtQ29udGV4dCxcbiAgVWlDb250ZXh0LFxuICBab29tSW5CdXR0b24sXG4gIFpvb21PdXRCdXR0b24sXG59O1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIEJvdW5kaW5nQm94LFxuICBjb21wdXRlQm91bmRpbmdCb3hTdHlsZSxcbiAgY29tcHV0ZVBhZ2VTdHlsZSxcbiAgQ29udGV4dFByb3ZpZGVyLFxuICBEb2N1bWVudENvbnRleHQsXG4gIERvY3VtZW50V3JhcHBlcixcbiAgRG93bmxvYWRCdXR0b24sXG4gIGdlbmVyYXRlUGFnZUlkRnJvbUluZGV4LFxuICBnZXRQYWdlSGVpZ2h0LFxuICBnZXRQYWdlV2lkdGgsXG4gIEhpZ2hsaWdodE92ZXJsYXksXG4gIGlzU2lkZXdheXMsXG4gIE91dGxpbmUsXG4gIE91dGxpbmVJdGVtLFxuICBPdmVybGF5LFxuICBQYWdlTnVtYmVyQ29udHJvbCxcbiAgUGFnZVJvdGF0aW9uLFxuICBQYWdlV3JhcHBlcixcbiAgcm90YXRlQ2xvY2t3aXNlLFxuICByb3RhdGVDb3VudGVyQ2xvY2t3aXNlLFxuICBzY2FsZVJhd0JvdW5kaW5nQm94LFxuICBzY3JvbGxUb0lkLFxuICBzY3JvbGxUb1BkZlBhZ2VJbmRleCxcbiAgU2Nyb2xsQ29udGV4dCxcbiAgVHJhbnNmb3JtQ29udGV4dCxcbiAgVWlDb250ZXh0LFxuICBab29tSW5CdXR0b24sXG4gIFpvb21PdXRCdXR0b24sXG59O1xuIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///188\n')},888:n=>{"use strict";n.exports=__WEBPACK_EXTERNAL_MODULE__888__},414:()=>{},172:()=>{},1:()=>{},779:()=>{},558:()=>{},258:()=>{}},__webpack_module_cache__={};function __webpack_require__(n){var t=__webpack_module_cache__[n];if(void 0!==t)return t.exports;var g=__webpack_module_cache__[n]={exports:{}};return __webpack_modules__[n].call(g.exports,g,g.exports,__webpack_require__),g.exports}__webpack_require__.n=n=>{var t=n&&n.__esModule?()=>n.default:()=>n;return __webpack_require__.d(t,{a:t}),t},__webpack_require__.d=(n,t)=>{for(var g in t)__webpack_require__.o(t,g)&&!__webpack_require__.o(n,g)&&Object.defineProperty(n,g,{enumerable:!0,get:t[g]})},__webpack_require__.o=(n,t)=>Object.prototype.hasOwnProperty.call(n,t);var __webpack_exports__=__webpack_require__(188);return __webpack_exports__=__webpack_exports__.default,__webpack_exports__})()})); \ No newline at end of file diff --git a/ui/library/src/components/ZoomInButton.tsx b/ui/library/src/components/ZoomInButton.tsx index 2b159593..33d40cc2 100644 --- a/ui/library/src/components/ZoomInButton.tsx +++ b/ui/library/src/components/ZoomInButton.tsx @@ -14,7 +14,7 @@ export const ZoomInButton: React.FunctionComponent = ({ children, ...extraProps }: Props) => { - const { scale, setScale, zoomMultiplier } = React.useContext(TransformContext); + const { scale, setScale, zoomMultiplier, setIsScaleChanged } = React.useContext(TransformContext); const { updateScrollPosition } = React.useContext(ScrollContext); const handleZoomIn = React.useCallback( @@ -23,6 +23,7 @@ export const ZoomInButton: React.FunctionComponent = ({ event.stopPropagation(); const zoomScale = Number(PercentFormatter.format(scale * zoomMultiplier).replace('%', '')); if (zoomScale <= MAX_ZOOM_IN_SCALE) { + setIsScaleChanged(true); updateScrollPosition(1 * zoomMultiplier); setScale(scale * zoomMultiplier); } diff --git a/ui/library/src/components/ZoomOutButton.tsx b/ui/library/src/components/ZoomOutButton.tsx index 862eafe1..9f9acb53 100644 --- a/ui/library/src/components/ZoomOutButton.tsx +++ b/ui/library/src/components/ZoomOutButton.tsx @@ -11,7 +11,7 @@ export type Props = { const MIN_ZOOM_OUT_SCALE = 25; export const ZoomOutButton: React.FunctionComponent = ({ children, ...extraProps }: Props) => { - const { scale, setScale, zoomMultiplier } = React.useContext(TransformContext); + const { scale, setScale, zoomMultiplier, setIsScaleChanged } = React.useContext(TransformContext); const { updateScrollPosition } = React.useContext(ScrollContext); const handleZoomOut = React.useCallback( @@ -20,6 +20,7 @@ export const ZoomOutButton: React.FunctionComponent = ({ children, ...extraProps event.stopPropagation(); const zoomScale = Number(PercentFormatter.format(scale / zoomMultiplier).replace('%', '')); if (zoomScale >= MIN_ZOOM_OUT_SCALE) { + setIsScaleChanged(true); updateScrollPosition(1 / zoomMultiplier); setScale(scale / zoomMultiplier); } diff --git a/ui/library/src/context/PageRenderContext.ts b/ui/library/src/context/PageRenderContext.ts index 4f5ef58d..abee98b3 100644 --- a/ui/library/src/context/PageRenderContext.ts +++ b/ui/library/src/context/PageRenderContext.ts @@ -5,6 +5,7 @@ import { PageNumber } from '../components/types/page'; import { Nullable } from '../components/types/utils'; import { logProviderWarning } from '../utils/provider'; import { PageRotation } from '../utils/rotate'; +import { TransformContext } from './TransformContext'; export type RenderState = { promise: Promise; @@ -57,6 +58,8 @@ export function usePageRenderContextProps({ } ); + const { isScaleChanged } = React.useContext(TransformContext); + // Because rendering a page is async, we will lose the current pageRenderStates // This ref trick allows the latest to be accessible when the objectURL is ready const pageRenderStatesRef = React.useRef(pageRenderStates); @@ -112,7 +115,7 @@ export function usePageRenderContextProps({ // Don't need to start another task if already rendered const existingPromise = pageRenderStates.get(pageNumber)?.promise; - if (existingPromise) { + if (existingPromise && !isScaleChanged) { return existingPromise; } @@ -144,12 +147,12 @@ export function usePageRenderContextProps({ React.useEffect(() => { for (const pageNumber of visiblePageRatios.keys()) { - if (pageRenderStates.has(pageNumber)) { - continue; + if (pageRenderStates.has(pageNumber) && !isScaleChanged) { + return; } buildObjectURLForPage({ pageNumber }); } - }, [pageRenderStates, visiblePageRatios]); + }, [pageRenderStates, visiblePageRatios, scale, rotation, devicePixelRatio]); return { pageRenderStates, @@ -185,6 +188,7 @@ async function buildPageObjectURL({ const viewport = pageProxy.getViewport({ scale: scale * zoomMultiplier * devicePixelRatio }); canvas.height = viewport.height; canvas.width = viewport.width; + canvas.style.width = '100%'; //de-zoom canvas with style (maybe you can directly use CSS), reaching de-zoom of higher definition PDF const canvasContext = canvas.getContext('2d'); if (!canvasContext) { throw new Error('canvas was unable to get a context'); diff --git a/ui/library/src/context/TransformContext.ts b/ui/library/src/context/TransformContext.ts index 8e16b4ed..dd9d5f0c 100644 --- a/ui/library/src/context/TransformContext.ts +++ b/ui/library/src/context/TransformContext.ts @@ -7,15 +7,18 @@ export interface ITransformContext { rotation: PageRotation; scale: number; zoomMultiplier: number; + isScaleChanged: boolean; setRotation: (rotation: PageRotation) => void; setScale: (scale: number) => void; setZoomMultiplier: (zoom: number) => void; + setIsScaleChanged: (isScaleChange: boolean) => void; } export const TransformContext = React.createContext({ rotation: PageRotation.Rotate0, scale: 1, zoomMultiplier: 1.2, + isScaleChanged: false, setRotation: rotation => { logProviderWarning(`setRotation(${rotation})`, 'TransformContext'); }, @@ -25,19 +28,25 @@ export const TransformContext = React.createContext({ setZoomMultiplier: zoom => { logProviderWarning(`setZoomMultiplier(${zoom})`, 'TransformContext'); }, + setIsScaleChanged: isScaleChange => { + logProviderWarning(`setIsScaleChanged(${isScaleChange})`, 'TransformContext'); + }, }); export function useTransformContextProps(): ITransformContext { const [rotation, setRotation] = React.useState(PageRotation.Rotate0); const [scale, setScale] = React.useState(1.0); const [zoomMultiplier, setZoomMultiplier] = React.useState(1.2); + const [isScaleChanged, setIsScaleChanged] = React.useState(false); return { rotation, scale, + isScaleChanged, setRotation, setScale, setZoomMultiplier, + setIsScaleChanged, zoomMultiplier, }; }