2026-06-26 15:56:49 +08:00

25 lines
192 KiB
JavaScript

"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
exports.id = "vendor-chunks/saxes";
exports.ids = ["vendor-chunks/saxes"];
exports.modules = {
/***/ "(rsc)/./node_modules/saxes/saxes.js":
/*!*************************************!*\
!*** ./node_modules/saxes/saxes.js ***!
\*************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst ed5 = __webpack_require__(/*! xmlchars/xml/1.0/ed5 */ \"(rsc)/./node_modules/xmlchars/xml/1.0/ed5.js\");\nconst ed2 = __webpack_require__(/*! xmlchars/xml/1.1/ed2 */ \"(rsc)/./node_modules/xmlchars/xml/1.1/ed2.js\");\nconst NSed3 = __webpack_require__(/*! xmlchars/xmlns/1.0/ed3 */ \"(rsc)/./node_modules/xmlchars/xmlns/1.0/ed3.js\");\nvar isS = ed5.isS;\nvar isChar10 = ed5.isChar;\nvar isNameStartChar = ed5.isNameStartChar;\nvar isNameChar = ed5.isNameChar;\nvar S_LIST = ed5.S_LIST;\nvar NAME_RE = ed5.NAME_RE;\nvar isChar11 = ed2.isChar;\nvar isNCNameStartChar = NSed3.isNCNameStartChar;\nvar isNCNameChar = NSed3.isNCNameChar;\nvar NC_NAME_RE = NSed3.NC_NAME_RE;\nconst XML_NAMESPACE = \"http://www.w3.org/XML/1998/namespace\";\nconst XMLNS_NAMESPACE = \"http://www.w3.org/2000/xmlns/\";\nconst rootNS = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n __proto__: null,\n xml: XML_NAMESPACE,\n xmlns: XMLNS_NAMESPACE,\n};\nconst XML_ENTITIES = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n __proto__: null,\n amp: \"&\",\n gt: \">\",\n lt: \"<\",\n quot: \"\\\"\",\n apos: \"'\",\n};\n// EOC: end-of-chunk\nconst EOC = -1;\nconst NL_LIKE = -2;\nconst S_BEGIN = 0; // Initial state.\nconst S_BEGIN_WHITESPACE = 1; // leading whitespace\nconst S_DOCTYPE = 2; // <!DOCTYPE\nconst S_DOCTYPE_QUOTE = 3; // <!DOCTYPE \"//blah\nconst S_DTD = 4; // <!DOCTYPE \"//blah\" [ ...\nconst S_DTD_QUOTED = 5; // <!DOCTYPE \"//blah\" [ \"foo\nconst S_DTD_OPEN_WAKA = 6;\nconst S_DTD_OPEN_WAKA_BANG = 7;\nconst S_DTD_COMMENT = 8; // <!--\nconst S_DTD_COMMENT_ENDING = 9; // <!-- blah -\nconst S_DTD_COMMENT_ENDED = 10; // <!-- blah --\nconst S_DTD_PI = 11; // <?\nconst S_DTD_PI_ENDING = 12; // <?hi \"there\" ?\nconst S_TEXT = 13; // general stuff\nconst S_ENTITY = 14; // &amp and such\nconst S_OPEN_WAKA = 15; // <\nconst S_OPEN_WAKA_BANG = 16; // <!...\nconst S_COMMENT = 17; // <!--\nconst S_COMMENT_ENDING = 18; // <!-- blah -\nconst S_COMMENT_ENDED = 19; // <!-- blah --\nconst S_CDATA = 20; // <![CDATA[ something\nconst S_CDATA_ENDING = 21; // ]\nconst S_CDATA_ENDING_2 = 22; // ]]\nconst S_PI_FIRST_CHAR = 23; // <?hi, first char\nconst S_PI_REST = 24; // <?hi, rest of the name\nconst S_PI_BODY = 25; // <?hi there\nconst S_PI_ENDING = 26; // <?hi \"there\" ?\nconst S_XML_DECL_NAME_START = 27; // <?xml\nconst S_XML_DECL_NAME = 28; // <?xml foo\nconst S_XML_DECL_EQ = 29; // <?xml foo=\nconst S_XML_DECL_VALUE_START = 30; // <?xml foo=\nconst S_XML_DECL_VALUE = 31; // <?xml foo=\"bar\"\nconst S_XML_DECL_SEPARATOR = 32; // <?xml foo=\"bar\"\nconst S_XML_DECL_ENDING = 33; // <?xml ... ?\nconst S_OPEN_TAG = 34; // <strong\nconst S_OPEN_TAG_SLASH = 35; // <strong /\nconst S_ATTRIB = 36; // <a\nconst S_ATTRIB_NAME = 37; // <a foo\nconst S_ATTRIB_NAME_SAW_WHITE = 38; // <a foo _\nconst S_ATTRIB_VALUE = 39; // <a foo=\nconst S_ATTRIB_VALUE_QUOTED = 40; // <a foo=\"bar\nconst S_ATTRIB_VALUE_CLOSED = 41; // <a foo=\"bar\"\nconst S_ATTRIB_VALUE_UNQUOTED = 42; // <a foo=bar\nconst S_CLOSE_TAG = 43; // </a\nconst S_CLOSE_TAG_SAW_WHITE = 44; // </a >\nconst TAB = 9;\nconst NL = 0xA;\nconst CR = 0xD;\nconst SPACE = 0x20;\nconst BANG = 0x21;\nconst DQUOTE = 0x22;\nconst AMP = 0x26;\nconst SQUOTE = 0x27;\nconst MINUS = 0x2D;\nconst FORWARD_SLASH = 0x2F;\nconst SEMICOLON = 0x3B;\nconst LESS = 0x3C;\nconst EQUAL = 0x3D;\nconst GREATER = 0x3E;\nconst QUESTION = 0x3F;\nconst OPEN_BRACKET = 0x5B;\nconst CLOSE_BRACKET = 0x5D;\nconst NEL = 0x85;\nconst LS = 0x2028; // Line Separator\nconst isQuote = (c) => c === DQUOTE || c === SQUOTE;\nconst QUOTES = [DQUOTE, SQUOTE];\nconst DOCTYPE_TERMINATOR = [...QUOTES, OPEN_BRACKET, GREATER];\nconst DTD_TERMINATOR = [...QUOTES, LESS, CLOSE_BRACKET];\nconst XML_DECL_NAME_TERMINATOR = [EQUAL, QUESTION, ...S_LIST];\nconst ATTRIB_VALUE_UNQUOTED_TERMINATOR = [...S_LIST, GREATER, AMP, LESS];\nfunction nsPairCheck(parser, prefix, uri) {\n switch (prefix) {\n case \"xml\":\n if (uri !== XML_NAMESPACE) {\n parser.fail(`xml prefix must be bound to ${XML_NAMESPACE}.`);\n }\n break;\n case \"xmlns\":\n if (uri !== XMLNS_NAMESPACE) {\n parser.fail(`xmlns prefix must be bound to ${XMLNS_NAMESPACE}.`);\n }\n break;\n default:\n }\n switch (uri) {\n case XMLNS_NAMESPACE:\n parser.fail(prefix === \"\" ?\n `the default namespace may not be set to ${uri}.` :\n `may not assign a prefix (even \"xmlns\") to the URI \\\n${XMLNS_NAMESPACE}.`);\n break;\n case XML_NAMESPACE:\n switch (prefix) {\n case \"xml\":\n // Assinging the XML namespace to \"xml\" is fine.\n break;\n case \"\":\n parser.fail(`the default namespace may not be set to ${uri}.`);\n break;\n default:\n parser.fail(\"may not assign the xml namespace to another prefix.\");\n }\n break;\n default:\n }\n}\nfunction nsMappingCheck(parser, mapping) {\n for (const local of Object.keys(mapping)) {\n nsPairCheck(parser, local, mapping[local]);\n }\n}\nconst isNCName = (name) => NC_NAME_RE.test(name);\nconst isName = (name) => NAME_RE.test(name);\nconst FORBIDDEN_START = 0;\nconst FORBIDDEN_BRACKET = 1;\nconst FORBIDDEN_BRACKET_BRACKET = 2;\n/**\n * The list of supported events.\n */\nexports.EVENTS = [\n \"xmldecl\",\n \"text\",\n \"processinginstruction\",\n \"doctype\",\n \"comment\",\n \"opentagstart\",\n \"attribute\",\n \"opentag\",\n \"closetag\",\n \"cdata\",\n \"error\",\n \"end\",\n \"ready\",\n];\nconst EVENT_NAME_TO_HANDLER_NAME = {\n xmldecl: \"xmldeclHandler\",\n text: \"textHandler\",\n processinginstruction: \"piHandler\",\n doctype: \"doctypeHandler\",\n comment: \"commentHandler\",\n opentagstart: \"openTagStartHandler\",\n attribute: \"attributeHandler\",\n opentag: \"openTagHandler\",\n closetag: \"closeTagHandler\",\n cdata: \"cdataHandler\",\n error: \"errorHandler\",\n end: \"endHandler\",\n ready: \"readyHandler\",\n};\nclass SaxesParser {\n /**\n * @param opt The parser options.\n */\n constructor(opt) {\n this.opt = opt !== null && opt !== void 0 ? opt : {};\n this.fragmentOpt = !!this.opt.fragment;\n const xmlnsOpt = this.xmlnsOpt = !!this.opt.xmlns;\n this.trackPosition = this.opt.position !== false;\n this.fileName = this.opt.fileName;\n if (xmlnsOpt) {\n // This is the function we use to perform name checks on PIs and entities.\n // When namespaces are used, colons are not allowed in PI target names or\n // entity names. So the check depends on whether namespaces are used. See:\n //\n // https://www.w3.org/XML/xml-names-19990114-errata.html\n // NE08\n //\n this.nameStartCheck = isNCNameStartChar;\n this.nameCheck = isNCNameChar;\n this.isName = isNCName;\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.processAttribs = this.processAttribsNS;\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.pushAttrib = this.pushAttribNS;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.ns = Object.assign({ __proto__: null }, rootNS);\n const additional = this.opt.additionalNamespaces;\n if (additional != null) {\n nsMappingCheck(this, additional);\n Object.assign(this.ns, additional);\n }\n }\n else {\n this.nameStartCheck = isNameStartChar;\n this.nameCheck = isNameChar;\n this.isName = isName;\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.processAttribs = this.processAttribsPlain;\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.pushAttrib = this.pushAttribPlain;\n }\n //\n // The order of the members in this table needs to correspond to the state\n // numbers given to the states that correspond to the methods being recorded\n // here.\n //\n this.stateTable = [\n /* eslint-disable @typescript-eslint/unbound-method */\n this.sBegin,\n this.sBeginWhitespace,\n this.sDoctype,\n this.sDoctypeQuote,\n this.sDTD,\n this.sDTDQuoted,\n this.sDTDOpenWaka,\n this.sDTDOpenWakaBang,\n this.sDTDComment,\n this.sDTDCommentEnding,\n this.sDTDCommentEnded,\n this.sDTDPI,\n this.sDTDPIEnding,\n this.sText,\n this.sEntity,\n this.sOpenWaka,\n this.sOpenWakaBang,\n this.sComment,\n this.sCommentEnding,\n this.sCommentEnded,\n this.sCData,\n this.sCDataEnding,\n this.sCDataEnding2,\n this.sPIFirstChar,\n this.sPIRest,\n this.sPIBody,\n this.sPIEnding,\n this.sXMLDeclNameStart,\n this.sXMLDeclName,\n this.sXMLDeclEq,\n this.sXMLDeclValueStart,\n this.sXMLDeclValue,\n this.sXMLDeclSeparator,\n this.sXMLDeclEnding,\n this.sOpenTag,\n this.sOpenTagSlash,\n this.sAttrib,\n this.sAttribName,\n this.sAttribNameSawWhite,\n this.sAttribValue,\n this.sAttribValueQuoted,\n this.sAttribValueClosed,\n this.sAttribValueUnquoted,\n this.sCloseTag,\n this.sCloseTagSawWhite,\n ];\n this._init();\n }\n /**\n * Indicates whether or not the parser is closed. If ``true``, wait for\n * the ``ready`` event to write again.\n */\n get closed() {\n return this._closed;\n }\n _init() {\n var _a;\n this.openWakaBang = \"\";\n this.text = \"\";\n this.name = \"\";\n this.piTarget = \"\";\n this.entity = \"\";\n this.q = null;\n this.tags = [];\n this.tag = null;\n this.topNS = null;\n this.chunk = \"\";\n this.chunkPosition = 0;\n this.i = 0;\n this.prevI = 0;\n this.carriedFromPrevious = undefined;\n this.forbiddenState = FORBIDDEN_START;\n this.attribList = [];\n // The logic is organized so as to minimize the need to check\n // this.opt.fragment while parsing.\n const { fragmentOpt } = this;\n this.state = fragmentOpt ? S_TEXT : S_BEGIN;\n // We want these to be all true if we are dealing with a fragment.\n this.reportedTextBeforeRoot = this.reportedTextAfterRoot = this.closedRoot =\n this.sawRoot = fragmentOpt;\n // An XML declaration is intially possible only when parsing whole\n // documents.\n this.xmlDeclPossible = !fragmentOpt;\n this.xmlDeclExpects = [\"version\"];\n this.entityReturnState = undefined;\n let { defaultXMLVersion } = this.opt;\n if (defaultXMLVersion === undefined) {\n if (this.opt.forceXMLVersion === true) {\n throw new Error(\"forceXMLVersion set but defaultXMLVersion is not set\");\n }\n defaultXMLVersion = \"1.0\";\n }\n this.setXMLVersion(defaultXMLVersion);\n this.positionAtNewLine = 0;\n this.doctype = false;\n this._closed = false;\n this.xmlDecl = {\n version: undefined,\n encoding: undefined,\n standalone: undefined,\n };\n this.line = 1;\n this.column = 0;\n this.ENTITIES = Object.create(XML_ENTITIES);\n // eslint-disable-next-line no-unused-expressions\n (_a = this.readyHandler) === null || _a === void 0 ? void 0 : _a.call(this);\n }\n /**\n * The stream position the parser is currently looking at. This field is\n * zero-based.\n *\n * This field is not based on counting Unicode characters but is to be\n * interpreted as a plain index into a JavaScript string.\n */\n get position() {\n return this.chunkPosition + this.i;\n }\n /**\n * The column number of the next character to be read by the parser. *\n * This field is zero-based. (The first column in a line is 0.)\n *\n * This field reports the index at which the next character would be in the\n * line if the line were represented as a JavaScript string. Note that this\n * *can* be different to a count based on the number of *Unicode characters*\n * due to how JavaScript handles astral plane characters.\n *\n * See [[column]] for a number that corresponds to a count of Unicode\n * characters.\n */\n get columnIndex() {\n return this.position - this.positionAtNewLine;\n }\n /**\n * Set an event listener on an event. The parser supports one handler per\n * event type. If you try to set an event handler over an existing handler,\n * the old handler is silently overwritten.\n *\n * @param name The event to listen to.\n *\n * @param handler The handler to set.\n */\n on(name, handler) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this[EVENT_NAME_TO_HANDLER_NAME[name]] = handler;\n }\n /**\n * Unset an event handler.\n *\n * @parma name The event to stop listening to.\n */\n off(name) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this[EVENT_NAME_TO_HANDLER_NAME[name]] = undefined;\n }\n /**\n * Make an error object. The error object will have a message that contains\n * the ``fileName`` option passed at the creation of the parser. If position\n * tracking was turned on, it will also have line and column number\n * information.\n *\n * @param message The message describing the error to report.\n *\n * @returns An error object with a properly formatted message.\n */\n makeError(message) {\n var _a;\n let msg = (_a = this.fileName) !== null && _a !== void 0 ? _a : \"\";\n if (this.trackPosition) {\n if (msg.length > 0) {\n msg += \":\";\n }\n msg += `${this.line}:${this.column}`;\n }\n if (msg.length > 0) {\n msg += \": \";\n }\n return new Error(msg + message);\n }\n /**\n * Report a parsing error. This method is made public so that client code may\n * check for issues that are outside the scope of this project and can report\n * errors.\n *\n * @param message The error to report.\n *\n * @returns this\n */\n fail(message) {\n const err = this.makeError(message);\n const handler = this.errorHandler;\n if (handler === undefined) {\n throw err;\n }\n else {\n handler(err);\n }\n return this;\n }\n /**\n * Write a XML data to the parser.\n *\n * @param chunk The XML data to write.\n *\n * @returns this\n */\n write(chunk) {\n if (this.closed) {\n return this.fail(\"cannot write after close; assign an onready handler.\");\n }\n let end = false;\n if (chunk === null) {\n // We cannot return immediately because carriedFromPrevious may need\n // processing.\n end = true;\n chunk = \"\";\n }\n else if (typeof chunk === \"object\") {\n chunk = chunk.toString();\n }\n // We checked if performing a pre-decomposition of the string into an array\n // of single complete characters (``Array.from(chunk)``) would be faster\n // than the current repeated calls to ``charCodeAt``. As of August 2018, it\n // isn't. (There may be Node-specific code that would perform faster than\n // ``Array.from`` but don't want to be dependent on Node.)\n if (this.carriedFromPrevious !== undefined) {\n // The previous chunk had char we must carry over.\n chunk = `${this.carriedFromPrevious}${chunk}`;\n this.carriedFromPrevious = undefined;\n }\n let limit = chunk.length;\n const lastCode = chunk.charCodeAt(limit - 1);\n if (!end &&\n // A trailing CR or surrogate must be carried over to the next\n // chunk.\n (lastCode === CR || (lastCode >= 0xD800 && lastCode <= 0xDBFF))) {\n // The chunk ends with a character that must be carried over. We cannot\n // know how to handle it until we get the next chunk or the end of the\n // stream. So save it for later.\n this.carriedFromPrevious = chunk[limit - 1];\n limit--;\n chunk = chunk.slice(0, limit);\n }\n const { stateTable } = this;\n this.chunk = chunk;\n this.i = 0;\n while (this.i < limit) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stateTable[this.state].call(this);\n }\n this.chunkPosition += limit;\n return end ? this.end() : this;\n }\n /**\n * Close the current stream. Perform final well-formedness checks and reset\n * the parser tstate.\n *\n * @returns this\n */\n close() {\n return this.write(null);\n }\n /**\n * Get a single code point out of the current chunk. This updates the current\n * position if we do position tracking.\n *\n * This is the algorithm to use for XML 1.0.\n *\n * @returns The character read.\n */\n getCode10() {\n const { chunk, i } = this;\n this.prevI = i;\n // Yes, we do this instead of doing this.i++. Doing it this way, we do not\n // read this.i again, which is a bit faster.\n this.i = i + 1;\n if (i >= chunk.length) {\n return EOC;\n }\n // Using charCodeAt and handling the surrogates ourselves is faster\n // than using codePointAt.\n const code = chunk.charCodeAt(i);\n this.column++;\n if (code < 0xD800) {\n if (code >= SPACE || code === TAB) {\n return code;\n }\n switch (code) {\n case NL:\n this.line++;\n this.column = 0;\n this.positionAtNewLine = this.position;\n return NL;\n case CR:\n // We may get NaN if we read past the end of the chunk, which is fine.\n if (chunk.charCodeAt(i + 1) === NL) {\n // A \\r\\n sequence is converted to \\n so we have to skip over the\n // next character. We already know it has a size of 1 so ++ is fine\n // here.\n this.i = i + 2;\n }\n // Otherwise, a \\r is just converted to \\n, so we don't have to skip\n // ahead.\n // In either case, \\r becomes \\n.\n this.line++;\n this.column = 0;\n this.positionAtNewLine = this.position;\n return NL_LIKE;\n default:\n // If we get here, then code < SPACE and it is not NL CR or TAB.\n this.fail(\"disallowed character.\");\n return code;\n }\n }\n if (code > 0xDBFF) {\n // This is a specialized version of isChar10 that takes into account\n // that in this context code > 0xDBFF and code <= 0xFFFF. So it does not\n // test cases that don't need testing.\n if (!(code >= 0xE000 && code <= 0xFFFD)) {\n this.fail(\"disallowed character.\");\n }\n return code;\n }\n const final = 0x10000 + ((code - 0xD800) * 0x400) +\n (chunk.charCodeAt(i + 1) - 0xDC00);\n this.i = i + 2;\n // This is a specialized version of isChar10 that takes into account that in\n // this context necessarily final >= 0x10000.\n if (final > 0x10FFFF) {\n this.fail(\"disallowed character.\");\n }\n return final;\n }\n /**\n * Get a single code point out of the current chunk. This updates the current\n * position if we do position tracking.\n *\n * This is the algorithm to use for XML 1.1.\n *\n * @returns {number} The character read.\n */\n getCode11() {\n const { chunk, i } = this;\n this.prevI = i;\n // Yes, we do this instead of doing this.i++. Doing it this way, we do not\n // read this.i again, which is a bit faster.\n this.i = i + 1;\n if (i >= chunk.length) {\n return EOC;\n }\n // Using charCodeAt and handling the surrogates ourselves is faster\n // than using codePointAt.\n const code = chunk.charCodeAt(i);\n this.column++;\n if (code < 0xD800) {\n if ((code > 0x1F && code < 0x7F) || (code > 0x9F && code !== LS) ||\n code === TAB) {\n return code;\n }\n switch (code) {\n case NL: // 0xA\n this.line++;\n this.column = 0;\n this.positionAtNewLine = this.position;\n return NL;\n case CR: { // 0xD\n // We may get NaN if we read past the end of the chunk, which is\n // fine.\n const next = chunk.charCodeAt(i + 1);\n if (next === NL || next === NEL) {\n // A CR NL or CR NEL sequence is converted to NL so we have to skip\n // over the next character. We already know it has a size of 1.\n this.i = i + 2;\n }\n // Otherwise, a CR is just converted to NL, no skip.\n }\n /* yes, fall through */\n case NEL: // 0x85\n case LS: // Ox2028\n this.line++;\n this.column = 0;\n this.positionAtNewLine = this.position;\n return NL_LIKE;\n default:\n this.fail(\"disallowed character.\");\n return code;\n }\n }\n if (code > 0xDBFF) {\n // This is a specialized version of isCharAndNotRestricted that takes into\n // account that in this context code > 0xDBFF and code <= 0xFFFF. So it\n // does not test cases that don't need testing.\n if (!(code >= 0xE000 && code <= 0xFFFD)) {\n this.fail(\"disallowed character.\");\n }\n return code;\n }\n const final = 0x10000 + ((code - 0xD800) * 0x400) +\n (chunk.charCodeAt(i + 1) - 0xDC00);\n this.i = i + 2;\n // This is a specialized version of isCharAndNotRestricted that takes into\n // account that in this context necessarily final >= 0x10000.\n if (final > 0x10FFFF) {\n this.fail(\"disallowed character.\");\n }\n return final;\n }\n /**\n * Like ``getCode`` but with the return value normalized so that ``NL`` is\n * returned for ``NL_LIKE``.\n */\n getCodeNorm() {\n const c = this.getCode();\n return c === NL_LIKE ? NL : c;\n }\n unget() {\n this.i = this.prevI;\n this.column--;\n }\n /**\n * Capture characters into a buffer until encountering one of a set of\n * characters.\n *\n * @param chars An array of codepoints. Encountering a character in the array\n * ends the capture. (``chars`` may safely contain ``NL``.)\n *\n * @return The character code that made the capture end, or ``EOC`` if we hit\n * the end of the chunk. The return value cannot be NL_LIKE: NL is returned\n * instead.\n */\n captureTo(chars) {\n let { i: start } = this;\n const { chunk } = this;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const c = this.getCode();\n const isNLLike = c === NL_LIKE;\n const final = isNLLike ? NL : c;\n if (final === EOC || chars.includes(final)) {\n this.text += chunk.slice(start, this.prevI);\n return final;\n }\n if (isNLLike) {\n this.text += `${chunk.slice(start, this.prevI)}\\n`;\n start = this.i;\n }\n }\n }\n /**\n * Capture characters into a buffer until encountering a character.\n *\n * @param char The codepoint that ends the capture. **NOTE ``char`` MAY NOT\n * CONTAIN ``NL``.** Passing ``NL`` will result in buggy behavior.\n *\n * @return ``true`` if we ran into the character. Otherwise, we ran into the\n * end of the current chunk.\n */\n captureToChar(char) {\n let { i: start } = this;\n const { chunk } = this;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n let c = this.getCode();\n switch (c) {\n case NL_LIKE:\n this.text += `${chunk.slice(start, this.prevI)}\\n`;\n start = this.i;\n c = NL;\n break;\n case EOC:\n this.text += chunk.slice(start);\n return false;\n default:\n }\n if (c === char) {\n this.text += chunk.slice(start, this.prevI);\n return true;\n }\n }\n }\n /**\n * Capture characters that satisfy ``isNameChar`` into the ``name`` field of\n * this parser.\n *\n * @return The character code that made the test fail, or ``EOC`` if we hit\n * the end of the chunk. The return value cannot be NL_LIKE: NL is returned\n * instead.\n */\n captureNameChars() {\n const { chunk, i: start } = this;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const c = this.getCode();\n if (c === EOC) {\n this.name += chunk.slice(start);\n return EOC;\n }\n // NL is not a name char so we don't have to test specifically for it.\n if (!isNameChar(c)) {\n this.name += chunk.slice(start, this.prevI);\n return c === NL_LIKE ? NL : c;\n }\n }\n }\n /**\n * Skip white spaces.\n *\n * @return The character that ended the skip, or ``EOC`` if we hit\n * the end of the chunk. The return value cannot be NL_LIKE: NL is returned\n * instead.\n */\n skipSpaces() {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const c = this.getCodeNorm();\n if (c === EOC || !isS(c)) {\n return c;\n }\n }\n }\n setXMLVersion(version) {\n this.currentXMLVersion = version;\n /* eslint-disable @typescript-eslint/unbound-method */\n if (version === \"1.0\") {\n this.isChar = isChar10;\n this.getCode = this.getCode10;\n }\n else {\n this.isChar = isChar11;\n this.getCode = this.getCode11;\n }\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n // STATE ENGINE METHODS\n // This needs to be a state separate from S_BEGIN_WHITESPACE because we want\n // to be sure never to come back to this state later.\n sBegin() {\n // We are essentially peeking at the first character of the chunk. Since\n // S_BEGIN can be in effect only when we start working on the first chunk,\n // the index at which we must look is necessarily 0. Note also that the\n // following test does not depend on decoding surrogates.\n // If the initial character is 0xFEFF, ignore it.\n if (this.chunk.charCodeAt(0) === 0xFEFF) {\n this.i++;\n this.column++;\n }\n this.state = S_BEGIN_WHITESPACE;\n }\n sBeginWhitespace() {\n // We need to know whether we've encountered spaces or not because as soon\n // as we run into a space, an XML declaration is no longer possible. Rather\n // than slow down skipSpaces even in places where we don't care whether it\n // skipped anything or not, we check whether prevI is equal to the value of\n // i from before we skip spaces.\n const iBefore = this.i;\n const c = this.skipSpaces();\n if (this.prevI !== iBefore) {\n this.xmlDeclPossible = false;\n }\n switch (c) {\n case LESS:\n this.state = S_OPEN_WAKA;\n // We could naively call closeText but in this state, it is not normal\n // to have text be filled with any data.\n if (this.text.length !== 0) {\n throw new Error(\"no-empty text at start\");\n }\n break;\n case EOC:\n break;\n default:\n this.unget();\n this.state = S_TEXT;\n this.xmlDeclPossible = false;\n }\n }\n sDoctype() {\n var _a;\n const c = this.captureTo(DOCTYPE_TERMINATOR);\n switch (c) {\n case GREATER: {\n // eslint-disable-next-line no-unused-expressions\n (_a = this.doctypeHandler) === null || _a === void 0 ? void 0 : _a.call(this, this.text);\n this.text = \"\";\n this.state = S_TEXT;\n this.doctype = true; // just remember that we saw it.\n break;\n }\n case EOC:\n break;\n default:\n this.text += String.fromCodePoint(c);\n if (c === OPEN_BRACKET) {\n this.state = S_DTD;\n }\n else if (isQuote(c)) {\n this.state = S_DOCTYPE_QUOTE;\n this.q = c;\n }\n }\n }\n sDoctypeQuote() {\n const q = this.q;\n if (this.captureToChar(q)) {\n this.text += String.fromCodePoint(q);\n this.q = null;\n this.state = S_DOCTYPE;\n }\n }\n sDTD() {\n const c = this.captureTo(DTD_TERMINATOR);\n if (c === EOC) {\n return;\n }\n this.text += String.fromCodePoint(c);\n if (c === CLOSE_BRACKET) {\n this.state = S_DOCTYPE;\n }\n else if (c === LESS) {\n this.state = S_DTD_OPEN_WAKA;\n }\n else if (isQuote(c)) {\n this.state = S_DTD_QUOTED;\n this.q = c;\n }\n }\n sDTDQuoted() {\n const q = this.q;\n if (this.captureToChar(q)) {\n this.text += String.fromCodePoint(q);\n this.state = S_DTD;\n this.q = null;\n }\n }\n sDTDOpenWaka() {\n const c = this.getCodeNorm();\n this.text += String.fromCodePoint(c);\n switch (c) {\n case BANG:\n this.state = S_DTD_OPEN_WAKA_BANG;\n this.openWakaBang = \"\";\n break;\n case QUESTION:\n this.state = S_DTD_PI;\n break;\n default:\n this.state = S_DTD;\n }\n }\n sDTDOpenWakaBang() {\n const char = String.fromCodePoint(this.getCodeNorm());\n const owb = this.openWakaBang += char;\n this.text += char;\n if (owb !== \"-\") {\n this.state = owb === \"--\" ? S_DTD_COMMENT : S_DTD;\n this.openWakaBang = \"\";\n }\n }\n sDTDComment() {\n if (this.captureToChar(MINUS)) {\n this.text += \"-\";\n this.state = S_DTD_COMMENT_ENDING;\n }\n }\n sDTDCommentEnding() {\n const c = this.getCodeNorm();\n this.text += String.fromCodePoint(c);\n this.state = c === MINUS ? S_DTD_COMMENT_ENDED : S_DTD_COMMENT;\n }\n sDTDCommentEnded() {\n const c = this.getCodeNorm();\n this.text += String.fromCodePoint(c);\n if (c === GREATER) {\n this.state = S_DTD;\n }\n else {\n this.fail(\"malformed comment.\");\n // <!-- blah -- bloo --> will be recorded as\n // a comment of \" blah -- bloo \"\n this.state = S_DTD_COMMENT;\n }\n }\n sDTDPI() {\n if (this.captureToChar(QUESTION)) {\n this.text += \"?\";\n this.state = S_DTD_PI_ENDING;\n }\n }\n sDTDPIEnding() {\n const c = this.getCodeNorm();\n this.text += String.fromCodePoint(c);\n if (c === GREATER) {\n this.state = S_DTD;\n }\n }\n sText() {\n //\n // We did try a version of saxes where the S_TEXT state was split in two\n // states: one for text inside the root element, and one for text\n // outside. This was avoiding having to test this.tags.length to decide\n // what implementation to actually use.\n //\n // Peformance testing on gigabyte-size files did not show any advantage to\n // using the two states solution instead of the current one. Conversely, it\n // made the code a bit more complicated elsewhere. For instance, a comment\n // can appear before the root element so when a comment ended it was\n // necessary to determine whether to return to the S_TEXT state or to the\n // new text-outside-root state.\n //\n if (this.tags.length !== 0) {\n this.handleTextInRoot();\n }\n else {\n this.handleTextOutsideRoot();\n }\n }\n sEntity() {\n // This is essentially a specialized version of captureToChar(SEMICOLON...)\n let { i: start } = this;\n const { chunk } = this;\n // eslint-disable-next-line no-labels, no-restricted-syntax\n loop: \n // eslint-disable-next-line no-constant-condition\n while (true) {\n switch (this.getCode()) {\n case NL_LIKE:\n this.entity += `${chunk.slice(start, this.prevI)}\\n`;\n start = this.i;\n break;\n case SEMICOLON: {\n const { entityReturnState } = this;\n const entity = this.entity + chunk.slice(start, this.prevI);\n this.state = entityReturnState;\n let parsed;\n if (entity === \"\") {\n this.fail(\"empty entity name.\");\n parsed = \"&;\";\n }\n else {\n parsed = this.parseEntity(entity);\n this.entity = \"\";\n }\n if (entityReturnState !== S_TEXT || this.textHandler !== undefined) {\n this.text += parsed;\n }\n // eslint-disable-next-line no-labels\n break loop;\n }\n case EOC:\n this.entity += chunk.slice(start);\n // eslint-disable-next-line no-labels\n break loop;\n default:\n }\n }\n }\n sOpenWaka() {\n // Reminder: a state handler is called with at least one character\n // available in the current chunk. So the first call to get code inside of\n // a state handler cannot return ``EOC``. That's why we don't test\n // for it.\n const c = this.getCode();\n // either a /, ?, !, or text is coming next.\n if (isNameStartChar(c)) {\n this.state = S_OPEN_TAG;\n this.unget();\n this.xmlDeclPossible = false;\n }\n else {\n switch (c) {\n case FORWARD_SLASH:\n this.state = S_CLOSE_TAG;\n this.xmlDeclPossible = false;\n break;\n case BANG:\n this.state = S_OPEN_WAKA_BANG;\n this.openWakaBang = \"\";\n this.xmlDeclPossible = false;\n break;\n case QUESTION:\n this.state = S_PI_FIRST_CHAR;\n break;\n default:\n this.fail(\"disallowed character in tag name\");\n this.state = S_TEXT;\n this.xmlDeclPossible = false;\n }\n }\n }\n sOpenWakaBang() {\n this.openWakaBang += String.fromCodePoint(this.getCodeNorm());\n switch (this.openWakaBang) {\n case \"[CDATA[\":\n if (!this.sawRoot && !this.reportedTextBeforeRoot) {\n this.fail(\"text data outside of root node.\");\n this.reportedTextBeforeRoot = true;\n }\n if (this.closedRoot && !this.reportedTextAfterRoot) {\n this.fail(\"text data outside of root node.\");\n this.reportedTextAfterRoot = true;\n }\n this.state = S_CDATA;\n this.openWakaBang = \"\";\n break;\n case \"--\":\n this.state = S_COMMENT;\n this.openWakaBang = \"\";\n break;\n case \"DOCTYPE\":\n this.state = S_DOCTYPE;\n if (this.doctype || this.sawRoot) {\n this.fail(\"inappropriately located doctype declaration.\");\n }\n this.openWakaBang = \"\";\n break;\n default:\n // 7 happens to be the maximum length of the string that can possibly\n // match one of the cases above.\n if (this.openWakaBang.length >= 7) {\n this.fail(\"incorrect syntax.\");\n }\n }\n }\n sComment() {\n if (this.captureToChar(MINUS)) {\n this.state = S_COMMENT_ENDING;\n }\n }\n sCommentEnding() {\n var _a;\n const c = this.getCodeNorm();\n if (c === MINUS) {\n this.state = S_COMMENT_ENDED;\n // eslint-disable-next-line no-unused-expressions\n (_a = this.commentHandler) === null || _a === void 0 ? void 0 : _a.call(this, this.text);\n this.text = \"\";\n }\n else {\n this.text += `-${String.fromCodePoint(c)}`;\n this.state = S_COMMENT;\n }\n }\n sCommentEnded() {\n const c = this.getCodeNorm();\n if (c !== GREATER) {\n this.fail(\"malformed comment.\");\n // <!-- blah -- bloo --> will be recorded as\n // a comment of \" blah -- bloo \"\n this.text += `--${String.fromCodePoint(c)}`;\n this.state = S_COMMENT;\n }\n else {\n this.state = S_TEXT;\n }\n }\n sCData() {\n if (this.captureToChar(CLOSE_BRACKET)) {\n this.state = S_CDATA_ENDING;\n }\n }\n sCDataEnding() {\n const c = this.getCodeNorm();\n if (c === CLOSE_BRACKET) {\n this.state = S_CDATA_ENDING_2;\n }\n else {\n this.text += `]${String.fromCodePoint(c)}`;\n this.state = S_CDATA;\n }\n }\n sCDataEnding2() {\n var _a;\n const c = this.getCodeNorm();\n switch (c) {\n case GREATER: {\n // eslint-disable-next-line no-unused-expressions\n (_a = this.cdataHandler) === null || _a === void 0 ? void 0 : _a.call(this, this.text);\n this.text = \"\";\n this.state = S_TEXT;\n break;\n }\n case CLOSE_BRACKET:\n this.text += \"]\";\n break;\n default:\n this.text += `]]${String.fromCodePoint(c)}`;\n this.state = S_CDATA;\n }\n }\n // We need this separate state to check the first character fo the pi target\n // with this.nameStartCheck which allows less characters than this.nameCheck.\n sPIFirstChar() {\n const c = this.getCodeNorm();\n // This is first because in the case where the file is well-formed this is\n // the branch taken. We optimize for well-formedness.\n if (this.nameStartCheck(c)) {\n this.piTarget += String.fromCodePoint(c);\n this.state = S_PI_REST;\n }\n else if (c === QUESTION || isS(c)) {\n this.fail(\"processing instruction without a target.\");\n this.state = c === QUESTION ? S_PI_ENDING : S_PI_BODY;\n }\n else {\n this.fail(\"disallowed character in processing instruction name.\");\n this.piTarget += String.fromCodePoint(c);\n this.state = S_PI_REST;\n }\n }\n sPIRest() {\n // Capture characters into a piTarget while ``this.nameCheck`` run on the\n // character read returns true.\n const { chunk, i: start } = this;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const c = this.getCodeNorm();\n if (c === EOC) {\n this.piTarget += chunk.slice(start);\n return;\n }\n // NL cannot satisfy this.nameCheck so we don't have to test specifically\n // for it.\n if (!this.nameCheck(c)) {\n this.piTarget += chunk.slice(start, this.prevI);\n const isQuestion = c === QUESTION;\n if (isQuestion || isS(c)) {\n if (this.piTarget === \"xml\") {\n if (!this.xmlDeclPossible) {\n this.fail(\"an XML declaration must be at the start of the document.\");\n }\n this.state = isQuestion ? S_XML_DECL_ENDING : S_XML_DECL_NAME_START;\n }\n else {\n this.state = isQuestion ? S_PI_ENDING : S_PI_BODY;\n }\n }\n else {\n this.fail(\"disallowed character in processing instruction name.\");\n this.piTarget += String.fromCodePoint(c);\n }\n break;\n }\n }\n }\n sPIBody() {\n if (this.text.length === 0) {\n const c = this.getCodeNorm();\n if (c === QUESTION) {\n this.state = S_PI_ENDING;\n }\n else if (!isS(c)) {\n this.text = String.fromCodePoint(c);\n }\n }\n // The question mark character is not valid inside any of the XML\n // declaration name/value pairs.\n else if (this.captureToChar(QUESTION)) {\n this.state = S_PI_ENDING;\n }\n }\n sPIEnding() {\n var _a;\n const c = this.getCodeNorm();\n if (c === GREATER) {\n const { piTarget } = this;\n if (piTarget.toLowerCase() === \"xml\") {\n this.fail(\"the XML declaration must appear at the start of the document.\");\n }\n // eslint-disable-next-line no-unused-expressions\n (_a = this.piHandler) === null || _a === void 0 ? void 0 : _a.call(this, {\n target: piTarget,\n body: this.text,\n });\n this.piTarget = this.text = \"\";\n this.state = S_TEXT;\n }\n else if (c === QUESTION) {\n // We ran into ?? as part of a processing instruction. We initially took\n // the first ? as a sign that the PI was ending, but it is not. So we have\n // to add it to the body but we take the new ? as a sign that the PI is\n // ending.\n this.text += \"?\";\n }\n else {\n this.text += `?${String.fromCodePoint(c)}`;\n this.state = S_PI_BODY;\n }\n this.xmlDeclPossible = false;\n }\n sXMLDeclNameStart() {\n const c = this.skipSpaces();\n // The question mark character is not valid inside any of the XML\n // declaration name/value pairs.\n if (c === QUESTION) {\n // It is valid to go to S_XML_DECL_ENDING from this state.\n this.state = S_XML_DECL_ENDING;\n return;\n }\n if (c !== EOC) {\n this.state = S_XML_DECL_NAME;\n this.name = String.fromCodePoint(c);\n }\n }\n sXMLDeclName() {\n const c = this.captureTo(XML_DECL_NAME_TERMINATOR);\n // The question mark character is not valid inside any of the XML\n // declaration name/value pairs.\n if (c === QUESTION) {\n this.state = S_XML_DECL_ENDING;\n this.name += this.text;\n this.text = \"\";\n this.fail(\"XML declaration is incomplete.\");\n return;\n }\n if (!(isS(c) || c === EQUAL)) {\n return;\n }\n this.name += this.text;\n this.text = \"\";\n if (!this.xmlDeclExpects.includes(this.name)) {\n switch (this.name.length) {\n case 0:\n this.fail(\"did not expect any more name/value pairs.\");\n break;\n case 1:\n this.fail(`expected the name ${this.xmlDeclExpects[0]}.`);\n break;\n default:\n this.fail(`expected one of ${this.xmlDeclExpects.join(\", \")}`);\n }\n }\n this.state = c === EQUAL ? S_XML_DECL_VALUE_START : S_XML_DECL_EQ;\n }\n sXMLDeclEq() {\n const c = this.getCodeNorm();\n // The question mark character is not valid inside any of the XML\n // declaration name/value pairs.\n if (c === QUESTION) {\n this.state = S_XML_DECL_ENDING;\n this.fail(\"XML declaration is incomplete.\");\n return;\n }\n if (isS(c)) {\n return;\n }\n if (c !== EQUAL) {\n this.fail(\"value required.\");\n }\n this.state = S_XML_DECL_VALUE_START;\n }\n sXMLDeclValueStart() {\n const c = this.getCodeNorm();\n // The question mark character is not valid inside any of the XML\n // declaration name/value pairs.\n if (c === QUESTION) {\n this.state = S_XML_DECL_ENDING;\n this.fail(\"XML declaration is incomplete.\");\n return;\n }\n if (isS(c)) {\n return;\n }\n if (!isQuote(c)) {\n this.fail(\"value must be quoted.\");\n this.q = SPACE;\n }\n else {\n this.q = c;\n }\n this.state = S_XML_DECL_VALUE;\n }\n sXMLDeclValue() {\n const c = this.captureTo([this.q, QUESTION]);\n // The question mark character is not valid inside any of the XML\n // declaration name/value pairs.\n if (c === QUESTION) {\n this.state = S_XML_DECL_ENDING;\n this.text = \"\";\n this.fail(\"XML declaration is incomplete.\");\n return;\n }\n if (c === EOC) {\n return;\n }\n const value = this.text;\n this.text = \"\";\n switch (this.name) {\n case \"version\": {\n this.xmlDeclExpects = [\"encoding\", \"standalone\"];\n const version = value;\n this.xmlDecl.version = version;\n // This is the test specified by XML 1.0 but it is fine for XML 1.1.\n if (!/^1\\.[0-9]+$/.test(version)) {\n this.fail(\"version number must match /^1\\\\.[0-9]+$/.\");\n }\n // When forceXMLVersion is set, the XML declaration is ignored.\n else if (!this.opt.forceXMLVersion) {\n this.setXMLVersion(version);\n }\n break;\n }\n case \"encoding\":\n if (!/^[A-Za-z][A-Za-z0-9._-]*$/.test(value)) {\n this.fail(\"encoding value must match \\\n/^[A-Za-z0-9][A-Za-z0-9._-]*$/.\");\n }\n this.xmlDeclExpects = [\"standalone\"];\n this.xmlDecl.encoding = value;\n break;\n case \"standalone\":\n if (value !== \"yes\" && value !== \"no\") {\n this.fail(\"standalone value must match \\\"yes\\\" or \\\"no\\\".\");\n }\n this.xmlDeclExpects = [];\n this.xmlDecl.standalone = value;\n break;\n default:\n // We don't need to raise an error here since we've already raised one\n // when checking what name was expected.\n }\n this.name = \"\";\n this.state = S_XML_DECL_SEPARATOR;\n }\n sXMLDeclSeparator() {\n const c = this.getCodeNorm();\n // The question mark character is not valid inside any of the XML\n // declaration name/value pairs.\n if (c === QUESTION) {\n // It is valid to go to S_XML_DECL_ENDING from this state.\n this.state = S_XML_DECL_ENDING;\n return;\n }\n if (!isS(c)) {\n this.fail(\"whitespace required.\");\n this.unget();\n }\n this.state = S_XML_DECL_NAME_START;\n }\n sXMLDeclEnding() {\n var _a;\n const c = this.getCodeNorm();\n if (c === GREATER) {\n if (this.piTarget !== \"xml\") {\n this.fail(\"processing instructions are not allowed before root.\");\n }\n else if (this.name !== \"version\" &&\n this.xmlDeclExpects.includes(\"version\")) {\n this.fail(\"XML declaration must contain a version.\");\n }\n // eslint-disable-next-line no-unused-expressions\n (_a = this.xmldeclHandler) === null || _a === void 0 ? void 0 : _a.call(this, this.xmlDecl);\n this.name = \"\";\n this.piTarget = this.text = \"\";\n this.state = S_TEXT;\n }\n else {\n // We got here because the previous character was a ?, but the question\n // mark character is not valid inside any of the XML declaration\n // name/value pairs.\n this.fail(\"The character ? is disallowed anywhere in XML declarations.\");\n }\n this.xmlDeclPossible = false;\n }\n sOpenTag() {\n var _a;\n const c = this.captureNameChars();\n if (c === EOC) {\n return;\n }\n const tag = this.tag = {\n name: this.name,\n attributes: Object.create(null),\n };\n this.name = \"\";\n if (this.xmlnsOpt) {\n this.topNS = tag.ns = Object.create(null);\n }\n // eslint-disable-next-line no-unused-expressions\n (_a = this.openTagStartHandler) === null || _a === void 0 ? void 0 : _a.call(this, tag);\n this.sawRoot = true;\n if (!this.fragmentOpt && this.closedRoot) {\n this.fail(\"documents may contain only one root.\");\n }\n switch (c) {\n case GREATER:\n this.openTag();\n break;\n case FORWARD_SLASH:\n this.state = S_OPEN_TAG_SLASH;\n break;\n default:\n if (!isS(c)) {\n this.fail(\"disallowed character in tag name.\");\n }\n this.state = S_ATTRIB;\n }\n }\n sOpenTagSlash() {\n if (this.getCode() === GREATER) {\n this.openSelfClosingTag();\n }\n else {\n this.fail(\"forward-slash in opening tag not followed by >.\");\n this.state = S_ATTRIB;\n }\n }\n sAttrib() {\n const c = this.skipSpaces();\n if (c === EOC) {\n return;\n }\n if (isNameStartChar(c)) {\n this.unget();\n this.state = S_ATTRIB_NAME;\n }\n else if (c === GREATER) {\n this.openTag();\n }\n else if (c === FORWARD_SLASH) {\n this.state = S_OPEN_TAG_SLASH;\n }\n else {\n this.fail(\"disallowed character in attribute name.\");\n }\n }\n sAttribName() {\n const c = this.captureNameChars();\n if (c === EQUAL) {\n this.state = S_ATTRIB_VALUE;\n }\n else if (isS(c)) {\n this.state = S_ATTRIB_NAME_SAW_WHITE;\n }\n else if (c === GREATER) {\n this.fail(\"attribute without value.\");\n this.pushAttrib(this.name, this.name);\n this.name = this.text = \"\";\n this.openTag();\n }\n else if (c !== EOC) {\n this.fail(\"disallowed character in attribute name.\");\n }\n }\n sAttribNameSawWhite() {\n const c = this.skipSpaces();\n switch (c) {\n case EOC:\n return;\n case EQUAL:\n this.state = S_ATTRIB_VALUE;\n break;\n default:\n this.fail(\"attribute without value.\");\n // Should we do this???\n // this.tag.attributes[this.name] = \"\";\n this.text = \"\";\n this.name = \"\";\n if (c === GREATER) {\n this.openTag();\n }\n else if (isNameStartChar(c)) {\n this.unget();\n this.state = S_ATTRIB_NAME;\n }\n else {\n this.fail(\"disallowed character in attribute name.\");\n this.state = S_ATTRIB;\n }\n }\n }\n sAttribValue() {\n const c = this.getCodeNorm();\n if (isQuote(c)) {\n this.q = c;\n this.state = S_ATTRIB_VALUE_QUOTED;\n }\n else if (!isS(c)) {\n this.fail(\"unquoted attribute value.\");\n this.state = S_ATTRIB_VALUE_UNQUOTED;\n this.unget();\n }\n }\n sAttribValueQuoted() {\n // We deliberately do not use captureTo here. The specialized code we use\n // here is faster than using captureTo.\n const { q, chunk } = this;\n let { i: start } = this;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n switch (this.getCode()) {\n case q:\n this.pushAttrib(this.name, this.text + chunk.slice(start, this.prevI));\n this.name = this.text = \"\";\n this.q = null;\n this.state = S_ATTRIB_VALUE_CLOSED;\n return;\n case AMP:\n this.text += chunk.slice(start, this.prevI);\n this.state = S_ENTITY;\n this.entityReturnState = S_ATTRIB_VALUE_QUOTED;\n return;\n case NL:\n case NL_LIKE:\n case TAB:\n this.text += `${chunk.slice(start, this.prevI)} `;\n start = this.i;\n break;\n case LESS:\n this.text += chunk.slice(start, this.prevI);\n this.fail(\"disallowed character.\");\n return;\n case EOC:\n this.text += chunk.slice(start);\n return;\n default:\n }\n }\n }\n sAttribValueClosed() {\n const c = this.getCodeNorm();\n if (isS(c)) {\n this.state = S_ATTRIB;\n }\n else if (c === GREATER) {\n this.openTag();\n }\n else if (c === FORWARD_SLASH) {\n this.state = S_OPEN_TAG_SLASH;\n }\n else if (isNameStartChar(c)) {\n this.fail(\"no whitespace between attributes.\");\n this.unget();\n this.state = S_ATTRIB_NAME;\n }\n else {\n this.fail(\"disallowed character in attribute name.\");\n }\n }\n sAttribValueUnquoted() {\n // We don't do anything regarding EOL or space handling for unquoted\n // attributes. We already have failed by the time we get here, and the\n // contract that saxes upholds states that upon failure, it is not safe to\n // rely on the data passed to event handlers (other than\n // ``onerror``). Passing \"bad\" data is not a problem.\n const c = this.captureTo(ATTRIB_VALUE_UNQUOTED_TERMINATOR);\n switch (c) {\n case AMP:\n this.state = S_ENTITY;\n this.entityReturnState = S_ATTRIB_VALUE_UNQUOTED;\n break;\n case LESS:\n this.fail(\"disallowed character.\");\n break;\n case EOC:\n break;\n default:\n if (this.text.includes(\"]]>\")) {\n this.fail(\"the string \\\"]]>\\\" is disallowed in char data.\");\n }\n this.pushAttrib(this.name, this.text);\n this.name = this.text = \"\";\n if (c === GREATER) {\n this.openTag();\n }\n else {\n this.state = S_ATTRIB;\n }\n }\n }\n sCloseTag() {\n const c = this.captureNameChars();\n if (c === GREATER) {\n this.closeTag();\n }\n else if (isS(c)) {\n this.state = S_CLOSE_TAG_SAW_WHITE;\n }\n else if (c !== EOC) {\n this.fail(\"disallowed character in closing tag.\");\n }\n }\n sCloseTagSawWhite() {\n switch (this.skipSpaces()) {\n case GREATER:\n this.closeTag();\n break;\n case EOC:\n break;\n default:\n this.fail(\"disallowed character in closing tag.\");\n }\n }\n // END OF STATE ENGINE METHODS\n handleTextInRoot() {\n // This is essentially a specialized version of captureTo which is optimized\n // for performing the ]]> check. A previous version of this code, checked\n // ``this.text`` for the presence of ]]>. It simplified the code but was\n // very costly when character data contained a lot of entities to be parsed.\n //\n // Since we are using a specialized loop, we also keep track of the presence\n // of ]]> in text data. The sequence ]]> is forbidden to appear as-is.\n //\n let { i: start, forbiddenState } = this;\n const { chunk, textHandler: handler } = this;\n // eslint-disable-next-line no-labels, no-restricted-syntax\n scanLoop: \n // eslint-disable-next-line no-constant-condition\n while (true) {\n switch (this.getCode()) {\n case LESS: {\n this.state = S_OPEN_WAKA;\n if (handler !== undefined) {\n const { text } = this;\n const slice = chunk.slice(start, this.prevI);\n if (text.length !== 0) {\n handler(text + slice);\n this.text = \"\";\n }\n else if (slice.length !== 0) {\n handler(slice);\n }\n }\n forbiddenState = FORBIDDEN_START;\n // eslint-disable-next-line no-labels\n break scanLoop;\n }\n case AMP:\n this.state = S_ENTITY;\n this.entityReturnState = S_TEXT;\n if (handler !== undefined) {\n this.text += chunk.slice(start, this.prevI);\n }\n forbiddenState = FORBIDDEN_START;\n // eslint-disable-next-line no-labels\n break scanLoop;\n case CLOSE_BRACKET:\n switch (forbiddenState) {\n case FORBIDDEN_START:\n forbiddenState = FORBIDDEN_BRACKET;\n break;\n case FORBIDDEN_BRACKET:\n forbiddenState = FORBIDDEN_BRACKET_BRACKET;\n break;\n case FORBIDDEN_BRACKET_BRACKET:\n break;\n default:\n throw new Error(\"impossible state\");\n }\n break;\n case GREATER:\n if (forbiddenState === FORBIDDEN_BRACKET_BRACKET) {\n this.fail(\"the string \\\"]]>\\\" is disallowed in char data.\");\n }\n forbiddenState = FORBIDDEN_START;\n break;\n case NL_LIKE:\n if (handler !== undefined) {\n this.text += `${chunk.slice(start, this.prevI)}\\n`;\n }\n start = this.i;\n forbiddenState = FORBIDDEN_START;\n break;\n case EOC:\n if (handler !== undefined) {\n this.text += chunk.slice(start);\n }\n // eslint-disable-next-line no-labels\n break scanLoop;\n default:\n forbiddenState = FORBIDDEN_START;\n }\n }\n this.forbiddenState = forbiddenState;\n }\n handleTextOutsideRoot() {\n // This is essentially a specialized version of captureTo which is optimized\n // for a specialized task. We keep track of the presence of non-space\n // characters in the text since these are errors when appearing outside the\n // document root element.\n let { i: start } = this;\n const { chunk, textHandler: handler } = this;\n let nonSpace = false;\n // eslint-disable-next-line no-labels, no-restricted-syntax\n outRootLoop: \n // eslint-disable-next-line no-constant-condition\n while (true) {\n const code = this.getCode();\n switch (code) {\n case LESS: {\n this.state = S_OPEN_WAKA;\n if (handler !== undefined) {\n const { text } = this;\n const slice = chunk.slice(start, this.prevI);\n if (text.length !== 0) {\n handler(text + slice);\n this.text = \"\";\n }\n else if (slice.length !== 0) {\n handler(slice);\n }\n }\n // eslint-disable-next-line no-labels\n break outRootLoop;\n }\n case AMP:\n this.state = S_ENTITY;\n this.entityReturnState = S_TEXT;\n if (handler !== undefined) {\n this.text += chunk.slice(start, this.prevI);\n }\n nonSpace = true;\n // eslint-disable-next-line no-labels\n break outRootLoop;\n case NL_LIKE:\n if (handler !== undefined) {\n this.text += `${chunk.slice(start, this.prevI)}\\n`;\n }\n start = this.i;\n break;\n case EOC:\n if (handler !== undefined) {\n this.text += chunk.slice(start);\n }\n // eslint-disable-next-line no-labels\n break outRootLoop;\n default:\n if (!isS(code)) {\n nonSpace = true;\n }\n }\n }\n if (!nonSpace) {\n return;\n }\n // We use the reportedTextBeforeRoot and reportedTextAfterRoot flags\n // to avoid reporting errors for every single character that is out of\n // place.\n if (!this.sawRoot && !this.reportedTextBeforeRoot) {\n this.fail(\"text data outside of root node.\");\n this.reportedTextBeforeRoot = true;\n }\n if (this.closedRoot && !this.reportedTextAfterRoot) {\n this.fail(\"text data outside of root node.\");\n this.reportedTextAfterRoot = true;\n }\n }\n pushAttribNS(name, value) {\n var _a;\n const { prefix, local } = this.qname(name);\n const attr = { name, prefix, local, value };\n this.attribList.push(attr);\n // eslint-disable-next-line no-unused-expressions\n (_a = this.attributeHandler) === null || _a === void 0 ? void 0 : _a.call(this, attr);\n if (prefix === \"xmlns\") {\n const trimmed = value.trim();\n if (this.currentXMLVersion === \"1.0\" && trimmed === \"\") {\n this.fail(\"invalid attempt to undefine prefix in XML 1.0\");\n }\n this.topNS[local] = trimmed;\n nsPairCheck(this, local, trimmed);\n }\n else if (name === \"xmlns\") {\n const trimmed = value.trim();\n this.topNS[\"\"] = trimmed;\n nsPairCheck(this, \"\", trimmed);\n }\n }\n pushAttribPlain(name, value) {\n var _a;\n const attr = { name, value };\n this.attribList.push(attr);\n // eslint-disable-next-line no-unused-expressions\n (_a = this.attributeHandler) === null || _a === void 0 ? void 0 : _a.call(this, attr);\n }\n /**\n * End parsing. This performs final well-formedness checks and resets the\n * parser to a clean state.\n *\n * @returns this\n */\n end() {\n var _a, _b;\n if (!this.sawRoot) {\n this.fail(\"document must contain a root element.\");\n }\n const { tags } = this;\n while (tags.length > 0) {\n const tag = tags.pop();\n this.fail(`unclosed tag: ${tag.name}`);\n }\n if ((this.state !== S_BEGIN) && (this.state !== S_TEXT)) {\n this.fail(\"unexpected end.\");\n }\n const { text } = this;\n if (text.length !== 0) {\n // eslint-disable-next-line no-unused-expressions\n (_a = this.textHandler) === null || _a === void 0 ? void 0 : _a.call(this, text);\n this.text = \"\";\n }\n this._closed = true;\n // eslint-disable-next-line no-unused-expressions\n (_b = this.endHandler) === null || _b === void 0 ? void 0 : _b.call(this);\n this._init();\n return this;\n }\n /**\n * Resolve a namespace prefix.\n *\n * @param prefix The prefix to resolve.\n *\n * @returns The namespace URI or ``undefined`` if the prefix is not defined.\n */\n resolve(prefix) {\n var _a, _b;\n let uri = this.topNS[prefix];\n if (uri !== undefined) {\n return uri;\n }\n const { tags } = this;\n for (let index = tags.length - 1; index >= 0; index--) {\n uri = tags[index].ns[prefix];\n if (uri !== undefined) {\n return uri;\n }\n }\n uri = this.ns[prefix];\n if (uri !== undefined) {\n return uri;\n }\n return (_b = (_a = this.opt).resolvePrefix) === null || _b === void 0 ? void 0 : _b.call(_a, prefix);\n }\n /**\n * Parse a qname into its prefix and local name parts.\n *\n * @param name The name to parse\n *\n * @returns\n */\n qname(name) {\n // This is faster than using name.split(\":\").\n const colon = name.indexOf(\":\");\n if (colon === -1) {\n return { prefix: \"\", local: name };\n }\n const local = name.slice(colon + 1);\n const prefix = name.slice(0, colon);\n if (prefix === \"\" || local === \"\" || local.includes(\":\")) {\n this.fail(`malformed name: ${name}.`);\n }\n return { prefix, local };\n }\n processAttribsNS() {\n var _a;\n const { attribList } = this;\n const tag = this.tag;\n {\n // add namespace info to tag\n const { prefix, local } = this.qname(tag.name);\n tag.prefix = prefix;\n tag.local = local;\n const uri = tag.uri = (_a = this.resolve(prefix)) !== null && _a !== void 0 ? _a : \"\";\n if (prefix !== \"\") {\n if (prefix === \"xmlns\") {\n this.fail(\"tags may not have \\\"xmlns\\\" as prefix.\");\n }\n if (uri === \"\") {\n this.fail(`unbound namespace prefix: ${JSON.stringify(prefix)}.`);\n tag.uri = prefix;\n }\n }\n }\n if (attribList.length === 0) {\n return;\n }\n const { attributes } = tag;\n const seen = new Set();\n // Note: do not apply default ns to attributes:\n // http://www.w3.org/TR/REC-xml-names/#defaulting\n for (const attr of attribList) {\n const { name, prefix, local } = attr;\n let uri;\n let eqname;\n if (prefix === \"\") {\n uri = name === \"xmlns\" ? XMLNS_NAMESPACE : \"\";\n eqname = name;\n }\n else {\n uri = this.resolve(prefix);\n // if there's any attributes with an undefined namespace,\n // then fail on them now.\n if (uri === undefined) {\n this.fail(`unbound namespace prefix: ${JSON.stringify(prefix)}.`);\n uri = prefix;\n }\n eqname = `{${uri}}${local}`;\n }\n if (seen.has(eqname)) {\n this.fail(`duplicate attribute: ${eqname}.`);\n }\n seen.add(eqname);\n attr.uri = uri;\n attributes[name] = attr;\n }\n this.attribList = [];\n }\n processAttribsPlain() {\n const { attribList } = this;\n // eslint-disable-next-line prefer-destructuring\n const attributes = this.tag.attributes;\n for (const { name, value } of attribList) {\n if (attributes[name] !== undefined) {\n this.fail(`duplicate attribute: ${name}.`);\n }\n attributes[name] = value;\n }\n this.attribList = [];\n }\n /**\n * Handle a complete open tag. This parser code calls this once it has seen\n * the whole tag. This method checks for well-formeness and then emits\n * ``onopentag``.\n */\n openTag() {\n var _a;\n this.processAttribs();\n const { tags } = this;\n const tag = this.tag;\n tag.isSelfClosing = false;\n // There cannot be any pending text here due to the onopentagstart that was\n // necessarily emitted before we get here. So we do not check text.\n // eslint-disable-next-line no-unused-expressions\n (_a = this.openTagHandler) === null || _a === void 0 ? void 0 : _a.call(this, tag);\n tags.push(tag);\n this.state = S_TEXT;\n this.name = \"\";\n }\n /**\n * Handle a complete self-closing tag. This parser code calls this once it has\n * seen the whole tag. This method checks for well-formeness and then emits\n * ``onopentag`` and ``onclosetag``.\n */\n openSelfClosingTag() {\n var _a, _b, _c;\n this.processAttribs();\n const { tags } = this;\n const tag = this.tag;\n tag.isSelfClosing = true;\n // There cannot be any pending text here due to the onopentagstart that was\n // necessarily emitted before we get here. So we do not check text.\n // eslint-disable-next-line no-unused-expressions\n (_a = this.openTagHandler) === null || _a === void 0 ? void 0 : _a.call(this, tag);\n // eslint-disable-next-line no-unused-expressions\n (_b = this.closeTagHandler) === null || _b === void 0 ? void 0 : _b.call(this, tag);\n const top = this.tag = (_c = tags[tags.length - 1]) !== null && _c !== void 0 ? _c : null;\n if (top === null) {\n this.closedRoot = true;\n }\n this.state = S_TEXT;\n this.name = \"\";\n }\n /**\n * Handle a complete close tag. This parser code calls this once it has seen\n * the whole tag. This method checks for well-formeness and then emits\n * ``onclosetag``.\n */\n closeTag() {\n const { tags, name } = this;\n // Our state after this will be S_TEXT, no matter what, and we can clear\n // tagName now.\n this.state = S_TEXT;\n this.name = \"\";\n if (name === \"\") {\n this.fail(\"weird empty close tag.\");\n this.text += \"</>\";\n return;\n }\n const handler = this.closeTagHandler;\n let l = tags.length;\n while (l-- > 0) {\n const tag = this.tag = tags.pop();\n this.topNS = tag.ns;\n // eslint-disable-next-line no-unused-expressions\n handler === null || handler === void 0 ? void 0 : handler(tag);\n if (tag.name === name) {\n break;\n }\n this.fail(\"unexpected close tag.\");\n }\n if (l === 0) {\n this.closedRoot = true;\n }\n else if (l < 0) {\n this.fail(`unmatched closing tag: ${name}.`);\n this.text += `</${name}>`;\n }\n }\n /**\n * Resolves an entity. Makes any necessary well-formedness checks.\n *\n * @param entity The entity to resolve.\n *\n * @returns The parsed entity.\n */\n parseEntity(entity) {\n // startsWith would be significantly slower for this test.\n // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with\n if (entity[0] !== \"#\") {\n const defined = this.ENTITIES[entity];\n if (defined !== undefined) {\n return defined;\n }\n this.fail(this.isName(entity) ? \"undefined entity.\" :\n \"disallowed character in entity name.\");\n return `&${entity};`;\n }\n let num = NaN;\n if (entity[1] === \"x\" && /^#x[0-9a-f]+$/i.test(entity)) {\n num = parseInt(entity.slice(2), 16);\n }\n else if (/^#[0-9]+$/.test(entity)) {\n num = parseInt(entity.slice(1), 10);\n }\n // The character reference is required to match the CHAR production.\n if (!this.isChar(num)) {\n this.fail(\"malformed character entity.\");\n return `&${entity};`;\n }\n return String.fromCodePoint(num);\n }\n}\nexports.SaxesParser = SaxesParser;\n//# sourceMappingURL=saxes.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixjQUFjO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsb0JBQW9CO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLFVBQVUsR0FBRyxZQUFZO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FB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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsV0FBVztBQUN6QixnQkFBZ0IsUUFBUTtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0MsK0JBQStCO0FBQ3JFO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QixvQkFBb0I7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQztBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLHdCQUF3QjtBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEIsd0JBQXdCO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsd0JBQXdCO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyx3QkFBd0I7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixrQkFBa0I7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLFdBQVc7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2Qix3QkFBd0I7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtREFBbUQsdUJBQXVCO0FBQzFFO0FBQ0E7QUFDQSxpREFBaUQsK0JBQStCO0FBQ2hGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFdBQVc7QUFDM0IsY0FBYyxXQUFXO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0MsZ0NBQWdDO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixRQUFRO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsUUFBUTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQjtBQUNuQiIsInNvdXJjZXMiOlsid2VicGFjazovL2NvbnRyYWN0LWFwcHJvdmFsLXN5c3RlbS8uL25vZGVfbW9kdWxlcy9zYXhlcy9zYXhlcy5qcz8wYWE4Il0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuY29uc3QgZWQ1ID0gcmVxdWlyZShcInhtbGNoYXJzL3htbC8xLjAvZWQ1XCIpO1xuY29uc3QgZWQyID0gcmVxdWlyZShcInhtbGNoYXJzL3htbC8xLjEvZWQyXCIpO1xuY29uc3QgTlNlZDMgPSByZXF1aXJlKFwieG1sY2hhcnMveG1sbnMvMS4wL2VkM1wiKTtcbnZhciBpc1MgPSBlZDUuaXNTO1xudmFyIGlzQ2hhcjEwID0gZWQ1LmlzQ2hhcjtcbnZhciBpc05hbWVTdGFydENoYXIgPSBlZDUuaXNOYW1lU3RhcnRDaGFyO1xudmFyIGlzTmFtZUNoYXIgPSBlZDUuaXNOYW1lQ2hhcjtcbnZhciBTX0xJU1QgPSBlZDUuU19MSVNUO1xudmFyIE5BTUVfUkUgPSBlZDUuTkFNRV9SRTtcbnZhciBpc0NoYXIxMSA9IGVkMi5pc0NoYXI7XG52YXIgaXNOQ05hbWVTdGFydENoYXIgPSBOU2VkMy5pc05DTmFtZVN0YXJ0Q2hhcjtcbnZhciBpc05DTmFtZUNoYXIgPSBOU2VkMy5pc05DTmFtZUNoYXI7XG52YXIgTkNfTkFNRV9SRSA9IE5TZWQzLk5DX05BTUVfUkU7XG5jb25zdCBYTUxfTkFNRVNQQUNFID0gXCJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2VcIjtcbmNvbnN0IFhNTE5TX05BTUVTUEFDRSA9IFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy9cIjtcbmNvbnN0IHJvb3ROUyA9IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIF9fcHJvdG9fXzogbnVsbCxcbiAgICB4bWw6IFhNTF9OQU1FU1BBQ0UsXG4gICAgeG1sbnM6IFhNTE5TX05BTUVTUEFDRSxcbn07XG5jb25zdCBYTUxfRU5USVRJRVMgPSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBfX3Byb3RvX186IG51bGwsXG4gICAgYW1wOiBcIiZcIixcbiAgICBndDogXCI+XCIsXG4gICAgbHQ6IFwiPFwiLFxuICAgIHF1b3Q6IFwiXFxcIlwiLFxuICAgIGFwb3M6IFwiJ1wiLFxufTtcbi8vIEVPQzogZW5kLW9mLWNodW5rXG5jb25zdCBFT0MgPSAtMTtcbmNvbnN0IE5MX0xJS0UgPSAtMjtcbmNvbnN0IFNfQkVHSU4gPSAwOyAvLyBJbml0aWFsIHN0YXRlLlxuY29uc3QgU19CRUdJTl9XSElURVNQQUNFID0gMTsgLy8gbGVhZGluZyB3aGl0ZXNwYWNlXG5jb25zdCBTX0RPQ1RZUEUgPSAyOyAvLyA8IURPQ1RZUEVcbmNvbnN0IFNfRE9DVFlQRV9RVU9URSA9IDM7IC8vIDwhRE9DVFlQRSBcIi8vYmxhaFxuY29uc3QgU19EVEQgPSA0OyAvLyA8IURPQ1RZUEUgXCIvL2JsYWhcIiBbIC4uLlxuY29uc3QgU19EVERfUVVPVEVEID0gNTsgLy8gPCFET0NUWVBFIFwiLy9ibGFoXCIgWyBcImZvb1xuY29uc3QgU19EVERfT1BFTl9XQUtBID0gNjtcbmNvbnN0IFNfRFREX09QRU5fV0FLQV9CQU5HID0gNztcbmNvbnN0IFNfRFREX0NPTU1FTlQgPSA4OyAvLyA8IS0tXG5jb25zdCBTX0RURF9DT01NRU5UX0VORElORyA9IDk7IC8vIDwhLS0gYmxhaCAtXG5jb25zdCBTX0RURF9DT01NRU5UX0VOREVEID0gMTA7IC8vIDwhLS0gYmxhaCAtLVxuY29uc3QgU19EVERfUEkgPSAxMTsgLy8gPD9cbmNvbnN0IFNfRFREX1BJX0VORElORyA9IDEyOyAvLyA8P2hpIFwidGhlcmVcIiA/XG5jb25zdCBTX1RFWFQgPSAxMzsgLy8gZ2VuZXJhbCBzdHVmZlxuY29uc3QgU19FTlRJVFkgPSAxNDsgLy8gJmFtcCBhbmQgc3VjaFxuY29uc3QgU19PUEVOX1dBS0EgPSAxNTsgLy8gPFxuY29uc3QgU19PUEVOX1dBS0FfQkFORyA9IDE2OyAvLyA8IS4uLlxuY29uc3QgU19DT01NRU5UID0gMTc7IC8vIDwhLS1cbmNvbnN0IFNfQ09NTUVOVF9FTkRJTkcgPSAxODsgLy8gPCEtLSBibGFoIC1cbmNvbnN0IFNfQ09NTUVOVF9FTkRFRCA9IDE5OyAvLyA8IS0tIGJsYWggLS1cbmNvbnN0IFNfQ0RBVEEgPSAyMDsgLy8gPCFbQ0RBVEFbIHNvbWV0aGluZ1xuY29uc3QgU19DREFUQV9FTkRJTkcgPSAyMTsgLy8gXVxuY29uc3QgU19DREFUQV9FTkRJTkdfMiA9IDIyOyAvLyBdXVxuY29uc3QgU19QSV9GSVJTVF9DSEFSID0gMjM7IC8vIDw/aGksIGZpcnN0IGNoYXJcbmNvbnN0IFNfUElfUkVTVCA9IDI0OyAvLyA8P2hpLCByZXN0IG9mIHRoZSBuYW1lXG5jb25zdCBTX1BJX0JPRFkgPSAyNTsgLy8gPD9oaSB0aGVyZVxuY29uc3QgU19QSV9FTkRJTkcgPSAyNjsgLy8gPD9oaSBcInRoZXJlXCIgP1xuY29uc3QgU19YTUxfREVDTF9OQU1FX1NUQVJUID0gMjc7IC8vIDw/eG1sXG5jb25zdCBTX1hNTF9ERUNMX05BTUUgPSAyODsgLy8gPD94bWwgZm9vXG5jb25zdCBTX1hNTF9ERUNMX0VRID0gMjk7IC8vIDw/eG1sIGZvbz1cbmNvbnN0IFNfWE1MX0RFQ0xfVkFMVUVfU1RBUlQgPSAzMDsgLy8gPD94bWwgZm9vPVxuY29uc3QgU19YTUxfREVDTF9WQUxVRSA9IDMxOyAvLyA8P3htbCBmb289XCJiYXJcIlxuY29uc3QgU19YTUxfREVDTF9TRVBBUkFUT1IgPSAzMjsgLy8gPD94bWwgZm9vPVwiYmFyXCJcbmNvbnN0IFNfWE1MX0RFQ0xfRU5ESU5HID0gMzM7IC8vIDw/eG1sIC4uLiA/XG5jb25zdCBTX09QRU5fVEFHID0gMzQ7IC8vIDxzdHJvbmdcbmNvbnN0IFNfT1BFTl9UQUdfU0xBU0ggPSAzNTsgLy8gPHN0cm9uZyAvXG5jb25zdCBTX0FUVFJJQiA9IDM2OyAvLyA8YVxuY29uc3QgU19BVFRSSUJfTkFNRSA9IDM3OyAvLyA8YSBmb29cbmNvbnN0IFNfQVRUUklCX05BTUVfU0FXX1dISVRFID0gMzg7IC8vIDxhIGZvbyBfXG5jb25zdCBTX0FUVFJJQl9WQUxVRSA9IDM5OyAvLyA8YSBmb289XG5jb25zdCBTX0FUVFJJQl9WQUxVRV9RVU9URUQgPSA0MDsgLy8gPGEgZm9vPVwiYmFyXG5jb25zdCBTX0FUVFJJQl9WQUxVRV9DTE9TRUQgPSA0MTsgLy8gPGEgZm9vPVwiYmFyXCJcbmNvbnN0IFNfQVRUUklCX1ZBTFVFX1VOUVVPVEVEID0gNDI7IC8vIDxhIGZvbz1iYXJcbmNvbnN0IFNfQ0xPU0VfVEFHID0gNDM7IC8vIDwvYVxuY29uc3QgU19DTE9TRV9UQUdfU0FXX1dISVRFID0gNDQ7IC8vIDwvYSAgID5cbmNvbnN0IFRBQiA9IDk7XG5jb25zdCBOTCA9IDB4QTtcbmNvbnN0IENSID0gMHhEO1xuY29uc3QgU1BBQ0UgPSAweDIwO1xuY29uc3QgQkFORyA9IDB4MjE7XG5jb25zdCBEUVVPVEUgPSAweDIyO1xuY29uc3QgQU1QID0gMHgyNjtcbmNvbnN0IFNRVU9URSA9IDB4Mjc7XG5jb25zdCBNSU5VUyA9IDB4MkQ7XG5jb25zdCBGT1JXQVJEX1NMQVNIID0gMHgyRjtcbmNvbnN0IFNFTUlDT0xPTiA9IDB4M0I7XG5jb25zdCBMRVNTID0gMHgzQztcbmNvbnN0IEVRVUFMID0gMHgzRDtcbmNvbnN0IEdSRUFURVIgPSAweDNFO1xuY29uc3QgUVVFU1RJT04gPSAweDNGO1xuY29uc3QgT1BFTl9CUkFDS0VUID0gMHg1QjtcbmNvbnN0IENMT1NFX0JSQUNLRVQgPSAweDVEO1xuY29uc3QgTkVMID0gMHg4NTtcbmNvbnN0IExTID0gMHgyMDI4OyAvLyBMaW5lIFNlcGFyYXRvclxuY29uc3QgaXNRdW90ZSA9IChjKSA9PiBjID09PSBEUVVPVEUgfHwgYyA9PT0gU1FVT1RFO1xuY29uc3QgUVVPVEVTID0gW0RRVU9URSwgU1FVT1RFXTtcbmNvbnN0IERPQ1RZUEVfVEVSTUlOQVRPUiA9IFsuLi5RVU9URVMsIE9QRU5fQlJBQ0tFVCwgR1JFQVRFUl07XG5jb25zdCBEVERfVEVSTUlOQVRPUiA9IFsuLi5RVU9URVMsIExFU1MsIENMT1NFX0JSQUNLRVRdO1xuY29uc3QgWE1MX0RFQ0xfTkFNRV9URVJNSU5BVE9SID0gW0VRVUFMLCBRVUVTVElPTiwgLi4uU19MSVNUXTtcbmNvbnN0IEFUVFJJQl9WQUxVRV9VTlFVT1RFRF9URVJNSU5BVE9SID0gWy4uLlNfTElTVCwgR1JFQVRFUiwgQU1QLCBMRVNTXTtcbmZ1bmN0aW9uIG5zUGFpckNoZWNrKHBhcnNlciwgcHJlZml4LCB1cmkpIHtcbiAgICBzd2l0Y2ggKHByZWZpeCkge1xuICAgICAgICBjYXNlIFwieG1sXCI6XG4gICAgICAgICAgICBpZiAodXJpICE9PSBYTUxfTkFNRVNQQUNFKSB7XG4gICAgICAgICAgICAgICAgcGFyc2VyLmZhaWwoYHhtbCBwcmVmaXggbXVzdCBiZSBib3VuZCB0byAke1hNTF9OQU1FU1BBQ0V9LmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJ4bWxuc1wiOlxuICAgICAgICAgICAgaWYgKHVyaSAhPT0gWE1MTlNfTkFNRVNQQUNFKSB7XG4gICAgICAgICAgICAgICAgcGFyc2VyLmZhaWwoYHhtbG5zIHByZWZpeCBtdXN0IGJlIGJvdW5kIHRvICR7WE1MTlNfTkFNRVNQQUNFfS5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgIH1cbiAgICBzd2l0Y2ggKHVyaSkge1xuICAgICAgICBjYXNlIFhNTE5TX05BTUVTUEFDRTpcbiAgICAgICAgICAgIHBhcnNlci5mYWlsKHByZWZpeCA9PT0gXCJcIiA/XG4gICAgICAgICAgICAgICAgYHRoZSBkZWZhdWx0IG5hbWVzcGFjZSBtYXkgbm90IGJlIHNldCB0byAke3VyaX0uYCA6XG4gICAgICAgICAgICAgICAgYG1heSBub3QgYXNzaWduIGEgcHJlZml4IChldmVuIFwieG1sbnNcIikgdG8gdGhlIFVSSSBcXFxuJHtYTUxOU19OQU1FU1BBQ0V9LmApO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgWE1MX05BTUVTUEFDRTpcbiAgICAgICAgICAgIHN3aXRjaCAocHJlZml4KSB7XG4gICAgICAgICAgICAgICAgY2FzZSBcInhtbFwiOlxuICAgICAgICAgICAgICAgICAgICAvLyBBc3NpbmdpbmcgdGhlIFhNTCBuYW1lc3BhY2UgdG8gXCJ4bWxcIiBpcyBmaW5lLlxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIFwiXCI6XG4gICAgICAgICAgICAgICAgICAgIHBhcnNlci5mYWlsKGB0aGUgZGVmYXVsdCBuYW1lc3BhY2UgbWF5IG5vdCBiZSBzZXQgdG8gJHt1cml9LmApO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICBwYXJzZXIuZmFpbChcIm1heSBub3QgYXNzaWduIHRoZSB4bWwgbmFtZXNwYWNlIHRvIGFub3RoZXIgcHJlZml4LlwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgIH1cbn1cbmZ1bmN0aW9uIG5zTWFwcGluZ0NoZWNrKHBhcnNlciwgbWFwcGluZykge1xuICAgIGZvciAoY29uc3QgbG9jYWwgb2YgT2JqZWN0LmtleXMobWFwcGluZykpIHtcbiAgICAgICAgbnNQYWlyQ2hlY2socGFyc2VyLCBsb2NhbCwgbWFwcGluZ1tsb2NhbF0pO1xuICAgIH1cbn1cbmNvbnN0IGlzTkNOYW1lID0gKG5hbWUpID0+IE5DX05BTUVfUkUudGVzdChuYW1lKTtcbmNvbnN0IGlzTmFtZSA9IChuYW1lKSA9PiBOQU1FX1JFLnRlc3QobmFtZSk7XG5jb25zdCBGT1JCSURERU5fU1RBUlQgPSAwO1xuY29uc3QgRk9SQklEREVOX0JSQUNLRVQgPSAxO1xuY29uc3QgRk9SQklEREVOX0JSQUNLRVRfQlJBQ0tFVCA9IDI7XG4vKipcbiAqIFRoZSBsaXN0IG9mIHN1cHBvcnRlZCBldmVudHMuXG4gKi9cbmV4cG9ydHMuRVZFTlRTID0gW1xuICAgIFwieG1sZGVjbFwiLFxuICAgIFwidGV4dFwiLFxuICAgIFwicHJvY2Vzc2luZ2luc3RydWN0aW9uXCIsXG4gICAgXCJkb2N0eXBlXCIsXG4gICAgXCJjb21tZW50XCIsXG4gICAgXCJvcGVudGFnc3RhcnRcIixcbiAgICBcImF0dHJpYnV0ZVwiLFxuICAgIFwib3BlbnRhZ1wiLFxuICAgIFwiY2xvc2V0YWdcIixcbiAgICBcImNkYXRhXCIsXG4gICAgXCJlcnJvclwiLFxuICAgIFwiZW5kXCIsXG4gICAgXCJyZWFkeVwiLFxuXTtcbmNvbnN0IEVWRU5UX05BTUVfVE9fSEFORExFUl9OQU1FID0ge1xuICAgIHhtbGRlY2w6IFwieG1sZGVjbEhhbmRsZXJcIixcbiAgICB0ZXh0OiBcInRleHRIYW5kbGVyXCIsXG4gICAgcHJvY2Vzc2luZ2luc3RydWN0aW9uOiBcInBpSGFuZGxlclwiLFxuICAgIGRvY3R5cGU6IFwiZG9jdHlwZUhhbmRsZXJcIixcbiAgICBjb21tZW50OiBcImNvbW1lbnRIYW5kbGVyXCIsXG4gICAgb3BlbnRhZ3N0YXJ0OiBcIm9wZW5UYWdTdGFydEhhbmRsZXJcIixcbiAgICBhdHRyaWJ1dGU6IFwiYXR0cmlidXRlSGFuZGxlclwiLFxuICAgIG9wZW50YWc6IFwib3BlblRhZ0hhbmRsZXJcIixcbiAgICBjbG9zZXRhZzogXCJjbG9zZVRhZ0hhbmRsZXJcIixcbiAgICBjZGF0YTogXCJjZGF0YUhhbmRsZXJcIixcbiAgICBlcnJvcjogXCJlcnJvckhhbmRsZXJcIixcbiAgICBlbmQ6IFwiZW5kSGFuZGxlclwiLFxuICAgIHJlYWR5OiBcInJlYWR5SGFuZGxlclwiLFxufTtcbmNsYXNzIFNheGVzUGFyc2VyIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gb3B0IFRoZSBwYXJzZXIgb3B0aW9ucy5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcHQpIHtcbiAgICAgICAgdGhpcy5vcHQgPSBvcHQgIT09IG51bGwgJiYgb3B0ICE9PSB2b2lkIDAgPyBvcHQgOiB7fTtcbiAgICAgICAgdGhpcy5mcmFnbWVudE9wdCA9ICEhdGhpcy5vcHQuZnJhZ21lbnQ7XG4gICAgICAgIGNvbnN0IHhtbG5zT3B0ID0gdGhpcy54bWxuc09wdCA9ICEhdGhpcy5vcHQueG1sbnM7XG4gICAgICAgIHRoaXMudHJhY2tQb3NpdGlvbiA9IHRoaXMub3B0LnBvc2l0aW9uICE9PSBmYWxzZTtcbiAgICAgICAgdGhpcy5maWxlTmFtZSA9IHRoaXMub3B0LmZpbGVOYW1lO1xuICAgICAgICBpZiAoeG1sbnNPcHQpIHtcbiAgICAgICAgICAgIC8vIFRoaXMgaXMgdGhlIGZ1bmN0aW9uIHdlIHVzZSB0byBwZXJmb3JtIG5hbWUgY2hlY2tzIG9uIFBJcyBhbmQgZW50aXRpZXMuXG4gICAgICAgICAgICAvLyBXaGVuIG5hbWVzcGFjZXMgYXJlIHVzZWQsIGNvbG9ucyBhcmUgbm90IGFsbG93ZWQgaW4gUEkgdGFyZ2V0IG5hbWVzIG9yXG4gICAgICAgICAgICAvLyBlbnRpdHkgbmFtZXMuIFNvIHRoZSBjaGVjayBkZXBlbmRzIG9uIHdoZXRoZXIgbmFtZXNwYWNlcyBhcmUgdXNlZC4gU2VlOlxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIGh0dHBzOi8vd3d3LnczLm9yZy9YTUwveG1sLW5hbWVzLTE5OTkwMTE0LWVycmF0YS5odG1sXG4gICAgICAgICAgICAvLyBORTA4XG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgdGhpcy5uYW1lU3RhcnRDaGVjayA9IGlzTkNOYW1lU3RhcnRDaGFyO1xuICAgICAgICAgICAgdGhpcy5uYW1lQ2hlY2sgPSBpc05DTmFtZUNoYXI7XG4gICAgICAgICAgICB0aGlzLmlzTmFtZSA9IGlzTkNOYW1lO1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC91bmJvdW5kLW1ldGhvZFxuICAgICAgICAgICAgdGhpcy5wcm9jZXNzQXR0cmlicyA9IHRoaXMucHJvY2Vzc0F0dHJpYnNOUztcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvdW5ib3VuZC1tZXRob2RcbiAgICAgICAgICAgIHRoaXMucHVzaEF0dHJpYiA9IHRoaXMucHVzaEF0dHJpYk5TO1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgICAgICAgIHRoaXMubnMgPSBPYmplY3QuYXNzaWduKHsgX19wcm90b19fOiBudWxsIH0sIHJvb3ROUyk7XG4gICAgICAgICAgICBjb25zdCBhZGRpdGlvbmFsID0gdGhpcy5vcHQuYWRkaXRpb25hbE5hbWVzcGFjZXM7XG4gICAgICAgICAgICBpZiAoYWRkaXRpb25hbCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgbnNNYXBwaW5nQ2hlY2sodGhpcywgYWRkaXRpb25hbCk7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLm5zLCBhZGRpdGlvbmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubmFtZVN0YXJ0Q2hlY2sgPSBpc05hbWVTdGFydENoYXI7XG4gICAgICAgICAgICB0aGlzLm5hbWVDaGVjayA9IGlzTmFtZUNoYXI7XG4gICAgICAgICAgICB0aGlzLmlzTmFtZSA9IGlzTmFtZTtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvdW5ib3VuZC1tZXRob2RcbiAgICAgICAgICAgIHRoaXMucHJvY2Vzc0F0dHJpYnMgPSB0aGlzLnByb2Nlc3NBdHRyaWJzUGxhaW47XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L3VuYm91bmQtbWV0aG9kXG4gICAgICAgICAgICB0aGlzLnB1c2hBdHRyaWIgPSB0aGlzLnB1c2hBdHRyaWJQbGFpbjtcbiAgICAgICAgfVxuICAgICAgICAvL1xuICAgICAgICAvLyBUaGUgb3JkZXIgb2YgdGhlIG1lbWJlcnMgaW4gdGhpcyB0YWJsZSBuZWVkcyB0byBjb3JyZXNwb25kIHRvIHRoZSBzdGF0ZVxuICAgICAgICAvLyBudW1iZXJzIGdpdmVuIHRvIHRoZSBzdGF0ZXMgdGhhdCBjb3JyZXNwb25kIHRvIHRoZSBtZXRob2RzIGJlaW5nIHJlY29yZGVkXG4gICAgICAgIC8vIGhlcmUuXG4gICAgICAgIC8vXG4gICAgICAgIHRoaXMuc3RhdGVUYWJsZSA9IFtcbiAgICAgICAgICAgIC8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC91bmJvdW5kLW1ldGhvZCAqL1xuICAgICAgICAgICAgdGhpcy5zQmVnaW4sXG4gICAgICAgICAgICB0aGlzLnNCZWdpbldoaXRlc3BhY2UsXG4gICAgICAgICAgICB0aGlzLnNEb2N0eXBlLFxuICAgICAgICAgICAgdGhpcy5zRG9jdHlwZVF1b3RlLFxuICAgICAgICAgICAgdGhpcy5zRFRELFxuICAgICAgICAgICAgdGhpcy5zRFREUXVvdGVkLFxuICAgICAgICAgICAgdGhpcy5zRFRET3Blbldha2EsXG4gICAgICAgICAgICB0aGlzLnNEVERPcGVuV2FrYUJhbmcsXG4gICAgICAgICAgICB0aGlzLnNEVERDb21tZW50LFxuICAgICAgICAgICAgdGhpcy5zRFREQ29tbWVudEVuZGluZyxcbiAgICAgICAgICAgIHRoaXMuc0RURENvbW1lbnRFbmRlZCxcbiAgICAgICAgICAgIHRoaXMuc0RURFBJLFxuICAgICAgICAgICAgdGhpcy5zRFREUElFbmRpbmcsXG4gICAgICAgICAgICB0aGlzLnNUZXh0LFxuICAgICAgICAgICAgdGhpcy5zRW50aXR5LFxuICAgICAgICAgICAgdGhpcy5zT3Blbldha2EsXG4gICAgICAgICAgICB0aGlzLnNPcGVuV2FrYUJhbmcsXG4gICAgICAgICAgICB0aGlzLnNDb21tZW50LFxuICAgICAgICAgICAgdGhpcy5zQ29tbWVudEVuZGluZyxcbiAgICAgICAgICAgIHRoaXMuc0NvbW1lbnRFbmRlZCxcbiAgICAgICAgICAgIHRoaXMuc0NEYXRhLFxuICAgICAgICAgICAgdGhpcy5zQ0RhdGFFbmRpbmcsXG4gICAgICAgICAgICB0aGlzLnNDRGF0YUVuZGluZzIsXG4gICAgICAgICAgICB0aGlzLnNQSUZpcnN0Q2hhcixcbiAgICAgICAgICAgIHRoaXMuc1BJUmVzdCxcbiAgICAgICAgICAgIHRoaXMuc1BJQm9keSxcbiAgICAgICAgICAgIHRoaXMuc1BJRW5kaW5nLFxuICAgICAgICAgICAgdGhpcy5zWE1MRGVjbE5hbWVTdGFydCxcbiAgICAgICAgICAgIHRoaXMuc1hNTERlY2xOYW1lLFxuICAgICAgICAgICAgdGhpcy5zWE1MRGVjbEVxLFxuICAgICAgICAgICAgdGhpcy5zWE1MRGVjbFZhbHVlU3RhcnQsXG4gICAgICAgICAgICB0aGlzLnNYTUxEZWNsVmFsdWUsXG4gICAgICAgICAgICB0aGlzLnNYTUxEZWNsU2VwYXJhdG9yLFxuICAgICAgICAgICAgdGhpcy5zWE1MRGVjbEVuZGluZyxcbiAgICAgICAgICAgIHRoaXMuc09wZW5UYWcsXG4gICAgICAgICAgICB0aGlzLnNPcGVuVGFnU2xhc2gsXG4gICAgICAgICAgICB0aGlzLnNBdHRyaWIsXG4gICAgICAgICAgICB0aGlzLnNBdHRyaWJOYW1lLFxuICAgICAgICAgICAgdGhpcy5zQXR0cmliTmFtZVNhd1doaXRlLFxuICAgICAgICAgICAgdGhpcy5zQXR0cmliVmFsdWUsXG4gICAgICAgICAgICB0aGlzLnNBdHRyaWJWYWx1ZVF1b3RlZCxcbiAgICAgICAgICAgIHRoaXMuc0F0dHJpYlZhbHVlQ2xvc2VkLFxuICAgICAgICAgICAgdGhpcy5zQXR0cmliVmFsdWVVbnF1b3RlZCxcbiAgICAgICAgICAgIHRoaXMuc0Nsb3NlVGFnLFxuICAgICAgICAgICAgdGhpcy5zQ2xvc2VUYWdTYXdXaGl0ZSxcbiAgICAgICAgXTtcbiAgICAgICAgdGhpcy5faW5pdCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhlIHBhcnNlciBpcyBjbG9zZWQuIElmIGBgdHJ1ZWBgLCB3YWl0IGZvclxuICAgICAqIHRoZSBgYHJlYWR5YGAgZXZlbnQgdG8gd3JpdGUgYWdhaW4uXG4gICAgICovXG4gICAgZ2V0IGNsb3NlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb3NlZDtcbiAgICB9XG4gICAgX2luaXQoKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgdGhpcy5vcGVuV2FrYUJhbmcgPSBcIlwiO1xuICAgICAgICB0aGlzLnRleHQgPSBcIlwiO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlwiO1xuICAgICAgICB0aGlzLnBpVGFyZ2V0ID0gXCJcIjtcbiAgICAgICAgdGhpcy5lbnRpdHkgPSBcIlwiO1xuICAgICAgICB0aGlzLnEgPSBudWxsO1xuICAgICAgICB0aGlzLnRhZ3MgPSBbXTtcbiAgICAgICAgdGhpcy50YWcgPSBudWxsO1xuICAgICAgICB0aGlzLnRvcE5TID0gbnVsbDtcbiAgICAgICAgdGhpcy5jaHVuayA9IFwiXCI7XG4gICAgICAgIHRoaXMuY2h1bmtQb3NpdGlvbiA9IDA7XG4gICAgICAgIHRoaXMuaSA9IDA7XG4gICAgICAgIHRoaXMucHJldkkgPSAwO1xuICAgICAgICB0aGlzLmNhcnJpZWRGcm9tUHJldmlvdXMgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuZm9yYmlkZGVuU3RhdGUgPSBGT1JCSURERU5fU1RBUlQ7XG4gICAgICAgIHRoaXMuYXR0cmliTGlzdCA9IFtdO1xuICAgICAgICAvLyBUaGUgbG9naWMgaXMgb3JnYW5pemVkIHNvIGFzIHRvIG1pbmltaXplIHRoZSBuZWVkIHRvIGNoZWNrXG4gICAgICAgIC8vIHRoaXMub3B0LmZyYWdtZW50IHdoaWxlIHBhcnNpbmcuXG4gICAgICAgIGNvbnN0IHsgZnJhZ21lbnRPcHQgfSA9IHRoaXM7XG4gICAgICAgIHRoaXMuc3RhdGUgPSBmcmFnbWVudE9wdCA/IFNfVEVYVCA6IFNfQkVHSU47XG4gICAgICAgIC8vIFdlIHdhbnQgdGhlc2UgdG8gYmUgYWxsIHRydWUgaWYgd2UgYXJlIGRlYWxpbmcgd2l0aCBhIGZyYWdtZW50LlxuICAgICAgICB0aGlzLnJlcG9ydGVkVGV4dEJlZm9yZVJvb3QgPSB0aGlzLnJlcG9ydGVkVGV4dEFmdGVyUm9vdCA9IHRoaXMuY2xvc2VkUm9vdCA9XG4gICAgICAgICAgICB0aGlzLnNhd1Jvb3QgPSBmcmFnbWVudE9wdDtcbiAgICAgICAgLy8gQW4gWE1MIGRlY2xhcmF0aW9uIGlzIGludGlhbGx5IHBvc3NpYmxlIG9ubHkgd2hlbiBwYXJzaW5nIHdob2xlXG4gICAgICAgIC8vIGRvY3VtZW50cy5cbiAgICAgICAgdGhpcy54bWxEZWNsUG9zc2libGUgPSAhZnJhZ21lbnRPcHQ7XG4gICAgICAgIHRoaXMueG1sRGVjbEV4cGVjdHMgPSBbXCJ2ZXJzaW9uXCJdO1xuICAgICAgICB0aGlzLmVudGl0eVJldHVyblN0YXRlID0gdW5kZWZpbmVkO1xuICAgICAgICBsZXQgeyBkZWZhdWx0WE1MVmVyc2lvbiB9ID0gdGhpcy5vcHQ7XG4gICAgICAgIGlmIChkZWZhdWx0WE1MVmVyc2lvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5vcHQuZm9yY2VYTUxWZXJzaW9uID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZm9yY2VYTUxWZXJzaW9uIHNldCBidXQgZGVmYXVsdFhNTFZlcnNpb24gaXMgbm90IHNldFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmF1bHRYTUxWZXJzaW9uID0gXCIxLjBcIjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFhNTFZlcnNpb24oZGVmYXVsdFhNTFZlcnNpb24pO1xuICAgICAgICB0aGlzLnBvc2l0aW9uQXROZXdMaW5lID0gMDtcbiAgICAgICAgdGhpcy5kb2N0eXBlID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX2Nsb3NlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnhtbERlY2wgPSB7XG4gICAgICAgICAgICB2ZXJzaW9uOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBlbmNvZGluZzogdW5kZWZpbmVkLFxuICAgICAgICAgICAgc3RhbmRhbG9uZTogdW5kZWZpbmVkLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmxpbmUgPSAxO1xuICAgICAgICB0aGlzLmNvbHVtbiA9IDA7XG4gICAgICAgIHRoaXMuRU5USVRJRVMgPSBPYmplY3QuY3JlYXRlKFhNTF9FTlRJVElFUyk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtZXhwcmVzc2lvbnNcbiAgICAgICAgKF9hID0gdGhpcy5yZWFkeUhhbmRsZXIpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5jYWxsKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc3RyZWFtIHBvc2l0aW9uIHRoZSBwYXJzZXIgaXMgY3VycmVudGx5IGxvb2tpbmcgYXQuIFRoaXMgZmllbGQgaXNcbiAgICAgKiB6ZXJvLWJhc2VkLlxuICAgICAqXG4gICAgICogVGhpcyBmaWVsZCBpcyBub3QgYmFzZWQgb24gY291bnRpbmcgVW5pY29kZSBjaGFyYWN0ZXJzIGJ1dCBpcyB0byBiZVxuICAgICAqIGludGVycHJldGVkIGFzIGEgcGxhaW4gaW5kZXggaW50byBhIEphdmFTY3JpcHQgc3RyaW5nLlxuICAgICAqL1xuICAgIGdldCBwb3NpdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2h1bmtQb3NpdGlvbiArIHRoaXMuaTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGNvbHVtbiBudW1iZXIgb2YgdGhlIG5leHQgY2hhcmFjdGVyIHRvIGJlIHJlYWQgYnkgdGhlIHBhcnNlci4gICpcbiAgICAgKiBUaGlzIGZpZWxkIGlzIHplcm8tYmFzZWQuIChUaGUgZmlyc3QgY29sdW1uIGluIGEgbGluZSBpcyAwLilcbiAgICAgKlxuICAgICAqIFRoaXMgZmllbGQgcmVwb3J0cyB0aGUgaW5kZXggYXQgd2hpY2ggdGhlIG5leHQgY2hhcmFjdGVyIHdvdWxkIGJlIGluIHRoZVxuICAgICAqIGxpbmUgaWYgdGhlIGxpbmUgd2VyZSByZXByZXNlbnRlZCBhcyBhIEphdmFTY3JpcHQgc3RyaW5nLiAgTm90ZSB0aGF0IHRoaXNcbiAgICAgKiAqY2FuKiBiZSBkaWZmZXJlbnQgdG8gYSBjb3VudCBiYXNlZCBvbiB0aGUgbnVtYmVyIG9mICpVbmljb2RlIGNoYXJhY3RlcnMqXG4gICAgICogZHVlIHRvIGhvdyBKYXZhU2NyaXB0IGhhbmRsZXMgYXN0cmFsIHBsYW5lIGNoYXJhY3RlcnMuXG4gICAgICpcbiAgICAgKiBTZWUgW1tjb2x1bW5dXSBmb3IgYSBudW1iZXIgdGhhdCBjb3JyZXNwb25kcyB0byBhIGNvdW50IG9mIFVuaWNvZGVcbiAgICAgKiBjaGFyYWN0ZXJzLlxuICAgICAqL1xuICAgIGdldCBjb2x1bW5JbmRleCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucG9zaXRpb24gLSB0aGlzLnBvc2l0aW9uQXROZXdMaW5lO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgYW4gZXZlbnQgbGlzdGVuZXIgb24gYW4gZXZlbnQuIFRoZSBwYXJzZXIgc3VwcG9ydHMgb25lIGhhbmRsZXIgcGVyXG4gICAgICogZXZlbnQgdHlwZS4gSWYgeW91IHRyeSB0byBzZXQgYW4gZXZlbnQgaGFuZGxlciBvdmVyIGFuIGV4aXN0aW5nIGhhbmRsZXIsXG4gICAgICogdGhlIG9sZCBoYW5kbGVyIGlzIHNpbGVudGx5IG92ZXJ3cml0dGVuLlxuICAgICAqXG4gICAgICogQHBhcmFtIG5hbWUgVGhlIGV2ZW50IHRvIGxpc3RlbiB0by5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBoYW5kbGVyIHRvIHNldC5cbiAgICAgKi9cbiAgICBvbihuYW1lLCBoYW5kbGVyKSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgIHRoaXNbRVZFTlRfTkFNRV9UT19IQU5ETEVSX05BTUVbbmFtZV1dID0gaGFuZGxlcjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5zZXQgYW4gZXZlbnQgaGFuZGxlci5cbiAgICAgKlxuICAgICAqIEBwYXJtYSBuYW1lIFRoZSBldmVudCB0byBzdG9wIGxpc3RlbmluZyB0by5cbiAgICAgKi9cbiAgICBvZmYobmFtZSkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICB0aGlzW0VWRU5UX05BTUVfVE9fSEFORExFUl9OQU1FW25hbWVdXSA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTWFrZSBhbiBlcnJvciBvYmplY3QuIFRoZSBlcnJvciBvYmplY3Qgd2lsbCBoYXZlIGEgbWVzc2FnZSB0aGF0IGNvbnRhaW5zXG4gICAgICogdGhlIGBgZmlsZU5hbWVgYCBvcHRpb24gcGFzc2VkIGF0IHRoZSBjcmVhdGlvbiBvZiB0aGUgcGFyc2VyLiBJZiBwb3NpdGlvblxuICAgICAqIHRyYWNraW5nIHdhcyB0dXJuZWQgb24sIGl0IHdpbGwgYWxzbyBoYXZlIGxpbmUgYW5kIGNvbHVtbiBudW1iZXJcbiAgICAgKiBpbmZvcm1hdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBtZXNzYWdlIGRlc2NyaWJpbmcgdGhlIGVycm9yIHRvIHJlcG9ydC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEFuIGVycm9yIG9iamVjdCB3aXRoIGEgcHJvcGVybHkgZm9ybWF0dGVkIG1lc3NhZ2UuXG4gICAgICovXG4gICAgbWFrZUVycm9yKG1lc3NhZ2UpIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICBsZXQgbXNnID0gKF9hID0gdGhpcy5maWxlTmFtZSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogXCJcIjtcbiAgICAgICAgaWYgKHRoaXMudHJhY2tQb3NpdGlvbikge1xuICAgICAgICAgICAgaWYgKG1zZy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgbXNnICs9IFwiOlwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbXNnICs9IGAke3RoaXMubGluZX06JHt0aGlzLmNvbHVtbn1gO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtc2cubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgbXNnICs9IFwiOiBcIjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IEVycm9yKG1zZyArIG1lc3NhZ2UpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXBvcnQgYSBwYXJzaW5nIGVycm9yLiBUaGlzIG1ldGhvZCBpcyBtYWRlIHB1YmxpYyBzbyB0aGF0IGNsaWVudCBjb2RlIG1heVxuICAgICAqIGNoZWNrIGZvciBpc3N1ZXMgdGhhdCBhcmUgb3V0c2lkZSB0aGUgc2NvcGUgb2YgdGhpcyBwcm9qZWN0IGFuZCBjYW4gcmVwb3J0XG4gICAgICogZXJyb3JzLlxuICAgICAqXG4gICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIHRvIHJlcG9ydC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHRoaXNcbiAgICAgKi9cbiAgICBmYWlsKG1lc3NhZ2UpIHtcbiAgICAgICAgY29uc3QgZXJyID0gdGhpcy5tYWtlRXJyb3IobWVzc2FnZSk7XG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPSB0aGlzLmVycm9ySGFuZGxlcjtcbiAgICAgICAgaWYgKGhhbmRsZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaGFuZGxlcihlcnIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXcml0ZSBhIFhNTCBkYXRhIHRvIHRoZSBwYXJzZXIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY2h1bmsgVGhlIFhNTCBkYXRhIHRvIHdyaXRlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgdGhpc1xuICAgICAqL1xuICAgIHdyaXRlKGNodW5rKSB7XG4gICAgICAgIGlmICh0aGlzLmNsb3NlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmFpbChcImNhbm5vdCB3cml0ZSBhZnRlciBjbG9zZTsgYXNzaWduIGFuIG9ucmVhZHkgaGFuZGxlci5cIik7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGVuZCA9IGZhbHNlO1xuICAgICAgICBpZiAoY2h1bmsgPT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIFdlIGNhbm5vdCByZXR1cm4gaW1tZWRpYXRlbHkgYmVjYXVzZSBjYXJyaWVkRnJvbVByZXZpb3VzIG1heSBuZWVkXG4gICAgICAgICAgICAvLyBwcm9jZXNzaW5nLlxuICAgICAgICAgICAgZW5kID0gdHJ1ZTtcbiAgICAgICAgICAgIGNodW5rID0gXCJcIjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlb2YgY2h1bmsgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgIGNodW5rID0gY2h1bmsudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBXZSBjaGVja2VkIGlmIHBlcmZvcm1pbmcgYSBwcmUtZGVjb21wb3NpdGlvbiBvZiB0aGUgc3RyaW5nIGludG8gYW4gYXJyYXlcbiAgICAgICAgLy8gb2Ygc2luZ2xlIGNvbXBsZXRlIGNoYXJhY3RlcnMgKGBgQXJyYXkuZnJvbShjaHVuaylgYCkgd291bGQgYmUgZmFzdGVyXG4gICAgICAgIC8vIHRoYW4gdGhlIGN1cnJlbnQgcmVwZWF0ZWQgY2FsbHMgdG8gYGBjaGFyQ29kZUF0YGAuIEFzIG9mIEF1Z3VzdCAyMDE4LCBpdFxuICAgICAgICAvLyBpc24ndC4gKFRoZXJlIG1heSBiZSBOb2RlLXNwZWNpZmljIGNvZGUgdGhhdCB3b3VsZCBwZXJmb3JtIGZhc3RlciB0aGFuXG4gICAgICAgIC8vIGBgQXJyYXkuZnJvbWBgIGJ1dCBkb24ndCB3YW50IHRvIGJlIGRlcGVuZGVudCBvbiBOb2RlLilcbiAgICAgICAgaWYgKHRoaXMuY2FycmllZEZyb21QcmV2aW91cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAvLyBUaGUgcHJldmlvdXMgY2h1bmsgaGFkIGNoYXIgd2UgbXVzdCBjYXJyeSBvdmVyLlxuICAgICAgICAgICAgY2h1bmsgPSBgJHt0aGlzLmNhcnJpZWRGcm9tUHJldmlvdXN9JHtjaHVua31gO1xuICAgICAgICAgICAgdGhpcy5jYXJyaWVkRnJvbVByZXZpb3VzID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIGxldCBsaW1pdCA9IGNodW5rLmxlbmd0aDtcbiAgICAgICAgY29uc3QgbGFzdENvZGUgPSBjaHVuay5jaGFyQ29kZUF0KGxpbWl0IC0gMSk7XG4gICAgICAgIGlmICghZW5kICYmXG4gICAgICAgICAgICAvLyBBIHRyYWlsaW5nIENSIG9yIHN1cnJvZ2F0ZSBtdXN0IGJlIGNhcnJpZWQgb3ZlciB0byB0aGUgbmV4dFxuICAgICAgICAgICAgLy8gY2h1bmsuXG4gICAgICAgICAgICAobGFzdENvZGUgPT09IENSIHx8IChsYXN0Q29kZSA+PSAweEQ4MDAgJiYgbGFzdENvZGUgPD0gMHhEQkZGKSkpIHtcbiAgICAgICAgICAgIC8vIFRoZSBjaHVuayBlbmRzIHdpdGggYSBjaGFyYWN0ZXIgdGhhdCBtdXN0IGJlIGNhcnJpZWQgb3Zlci4gV2UgY2Fubm90XG4gICAgICAgICAgICAvLyBrbm93IGhvdyB0byBoYW5kbGUgaXQgdW50aWwgd2UgZ2V0IHRoZSBuZXh0IGNodW5rIG9yIHRoZSBlbmQgb2YgdGhlXG4gICAgICAgICAgICAvLyBzdHJlYW0uIFNvIHNhdmUgaXQgZm9yIGxhdGVyLlxuICAgICAgICAgICAgdGhpcy5jYXJyaWVkRnJvbVByZXZpb3VzID0gY2h1bmtbbGltaXQgLSAxXTtcbiAgICAgICAgICAgIGxpbWl0LS07XG4gICAgICAgICAgICBjaHVuayA9IGNodW5rLnNsaWNlKDAsIGxpbWl0KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IHN0YXRlVGFibGUgfSA9IHRoaXM7XG4gICAgICAgIHRoaXMuY2h1bmsgPSBjaHVuaztcbiAgICAgICAgdGhpcy5pID0gMDtcbiAgICAgICAgd2hpbGUgKHRoaXMuaSA8IGxpbWl0KSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICAgICAgc3RhdGVUYWJsZVt0aGlzLnN0YXRlXS5jYWxsKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2h1bmtQb3NpdGlvbiArPSBsaW1pdDtcbiAgICAgICAgcmV0dXJuIGVuZCA/IHRoaXMuZW5kKCkgOiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbG9zZSB0aGUgY3VycmVudCBzdHJlYW0uIFBlcmZvcm0gZmluYWwgd2VsbC1mb3JtZWRuZXNzIGNoZWNrcyBhbmQgcmVzZXRcbiAgICAgKiB0aGUgcGFyc2VyIHRzdGF0ZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHRoaXNcbiAgICAgKi9cbiAgICBjbG9zZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud3JpdGUobnVsbCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBhIHNpbmdsZSBjb2RlIHBvaW50IG91dCBvZiB0aGUgY3VycmVudCBjaHVuay4gVGhpcyB1cGRhdGVzIHRoZSBjdXJyZW50XG4gICAgICogcG9zaXRpb24gaWYgd2UgZG8gcG9zaXRpb24gdHJhY2tpbmcuXG4gICAgICpcbiAgICAgKiBUaGlzIGlzIHRoZSBhbGdvcml0aG0gdG8gdXNlIGZvciBYTUwgMS4wLlxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIGNoYXJhY3RlciByZWFkLlxuICAgICAqL1xuICAgIGdldENvZGUxMCgpIHtcbiAgICAgICAgY29uc3QgeyBjaHVuaywgaSB9ID0gdGhpcztcbiAgICAgICAgdGhpcy5wcmV2SSA9IGk7XG4gICAgICAgIC8vIFllcywgd2UgZG8gdGhpcyBpbnN0ZWFkIG9mIGRvaW5nIHRoaXMuaSsrLiBEb2luZyBpdCB0aGlzIHdheSwgd2UgZG8gbm90XG4gICAgICAgIC8vIHJlYWQgdGhpcy5pIGFnYWluLCB3aGljaCBpcyBhIGJpdCBmYXN0ZXIuXG4gICAgICAgIHRoaXMuaSA9IGkgKyAxO1xuICAgICAgICBpZiAoaSA+PSBjaHVuay5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBFT0M7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVXNpbmcgY2hhckNvZGVBdCBhbmQgaGFuZGxpbmcgdGhlIHN1cnJvZ2F0ZXMgb3Vyc2VsdmVzIGlzIGZhc3RlclxuICAgICAgICAvLyB0aGFuIHVzaW5nIGNvZGVQb2ludEF0LlxuICAgICAgICBjb25zdCBjb2RlID0gY2h1bmsuY2hhckNvZGVBdChpKTtcbiAgICAgICAgdGhpcy5jb2x1bW4rKztcbiAgICAgICAgaWYgKGNvZGUgPCAweEQ4MDApIHtcbiAgICAgICAgICAgIGlmIChjb2RlID49IFNQQUNFIHx8IGNvZGUgPT09IFRBQikge1xuICAgICAgICAgICAgICAgIHJldHVybiBjb2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3dpdGNoIChjb2RlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSBOTDpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5saW5lKys7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29sdW1uID0gMDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3NpdGlvbkF0TmV3TGluZSA9IHRoaXMucG9zaXRpb247XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOTDtcbiAgICAgICAgICAgICAgICBjYXNlIENSOlxuICAgICAgICAgICAgICAgICAgICAvLyBXZSBtYXkgZ2V0IE5hTiBpZiB3ZSByZWFkIHBhc3QgdGhlIGVuZCBvZiB0aGUgY2h1bmssIHdoaWNoIGlzIGZpbmUuXG4gICAgICAgICAgICAgICAgICAgIGlmIChjaHVuay5jaGFyQ29kZUF0KGkgKyAxKSA9PT0gTkwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEEgXFxyXFxuIHNlcXVlbmNlIGlzIGNvbnZlcnRlZCB0byBcXG4gc28gd2UgaGF2ZSB0byBza2lwIG92ZXIgdGhlXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBuZXh0IGNoYXJhY3Rlci4gV2UgYWxyZWFkeSBrbm93IGl0IGhhcyBhIHNpemUgb2YgMSBzbyArKyBpcyBmaW5lXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBoZXJlLlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pID0gaSArIDI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gT3RoZXJ3aXNlLCBhIFxcciBpcyBqdXN0IGNvbnZlcnRlZCB0byBcXG4sIHNvIHdlIGRvbid0IGhhdmUgdG8gc2tpcFxuICAgICAgICAgICAgICAgICAgICAvLyBhaGVhZC5cbiAgICAgICAgICAgICAgICAgICAgLy8gSW4gZWl0aGVyIGNhc2UsIFxcciBiZWNvbWVzIFxcbi5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5saW5lKys7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29sdW1uID0gMDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3NpdGlvbkF0TmV3TGluZSA9IHRoaXMucG9zaXRpb247XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOTF9MSUtFO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIC8vIElmIHdlIGdldCBoZXJlLCB0aGVuIGNvZGUgPCBTUEFDRSBhbmQgaXQgaXMgbm90IE5MIENSIG9yIFRBQi5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mYWlsKFwiZGlzYWxsb3dlZCBjaGFyYWN0ZXIuXCIpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoY29kZSA+IDB4REJGRikge1xuICAgICAgICAgICAgLy8gVGhpcyBpcyBhIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgaXNDaGFyMTAgdGhhdCB0YWtlcyBpbnRvIGFjY291bnRcbiAgICAgICAgICAgIC8vIHRoYXQgaW4gdGhpcyBjb250ZXh0IGNvZGUgPiAweERCRkYgYW5kIGNvZGUgPD0gMHhGRkZGLiBTbyBpdCBkb2VzIG5vdFxuICAgICAgICAgICAgLy8gdGVzdCBjYXNlcyB0aGF0IGRvbid0IG5lZWQgdGVzdGluZy5cbiAgICAgICAgICAgIGlmICghKGNvZGUgPj0gMHhFMDAwICYmIGNvZGUgPD0gMHhGRkZEKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZmFpbChcImRpc2FsbG93ZWQgY2hhcmFjdGVyLlwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBjb2RlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGZpbmFsID0gMHgxMDAwMCArICgoY29kZSAtIDB4RDgwMCkgKiAweDQwMCkgK1xuICAgICAgICAgICAgKGNodW5rLmNoYXJDb2RlQXQoaSArIDEpIC0gMHhEQzAwKTtcbiAgICAgICAgdGhpcy5pID0gaSArIDI7XG4gICAgICAgIC8vIFRoaXMgaXMgYSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGlzQ2hhcjEwIHRoYXQgdGFrZXMgaW50byBhY2NvdW50IHRoYXQgaW5cbiAgICAgICAgLy8gdGhpcyBjb250ZXh0IG5lY2Vzc2FyaWx5IGZpbmFsID49IDB4MTAwMDAuXG4gICAgICAgIGlmIChmaW5hbCA+IDB4MTBGRkZGKSB7XG4gICAgICAgICAgICB0aGlzLmZhaWwoXCJkaXNhbGxvd2VkIGNoYXJhY3Rlci5cIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZpbmFsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYSBzaW5nbGUgY29kZSBwb2ludCBvdXQgb2YgdGhlIGN1cnJlbnQgY2h1bmsuIFRoaXMgdXBkYXRlcyB0aGUgY3VycmVudFxuICAgICAqIHBvc2l0aW9uIGlmIHdlIGRvIHBvc2l0aW9uIHRyYWNraW5nLlxuICAgICAqXG4gICAgICogVGhpcyBpcyB0aGUgYWxnb3JpdGhtIHRvIHVzZSBmb3IgWE1MIDEuMS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFRoZSBjaGFyYWN0ZXIgcmVhZC5cbiAgICAgKi9cbiAgICBnZXRDb2RlMTEoKSB7XG4gICAgICAgIGNvbnN0IHsgY2h1bmssIGkgfSA9IHRoaXM7XG4gICAgICAgIHRoaXMucHJldkkgPSBpO1xuICAgICAgICAvLyBZZXMsIHdlIGRvIHRoaXMgaW5zdGVhZCBvZiBkb2luZyB0aGlzLmkrKy4gRG9pbmcgaXQgdGhpcyB3YXksIHdlIGRvIG5vdFxuICAgICAgICAvLyByZWFkIHRoaXMuaSBhZ2Fpbiwgd2hpY2ggaXMgYSBiaXQgZmFzdGVyLlxuICAgICAgICB0aGlzLmkgPSBpICsgMTtcbiAgICAgICAgaWYgKGkgPj0gY2h1bmsubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gRU9DO1xuICAgICAgICB9XG4gICAgICAgIC8vIFVzaW5nIGNoYXJDb2RlQXQgYW5kIGhhbmRsaW5nIHRoZSBzdXJyb2dhdGVzIG91cnNlbHZlcyBpcyBmYXN0ZXJcbiAgICAgICAgLy8gdGhhbiB1c2luZyBjb2RlUG9pbnRBdC5cbiAgICAgICAgY29uc3QgY29kZSA9IGNodW5rLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIHRoaXMuY29sdW1uKys7XG4gICAgICAgIGlmIChjb2RlIDwgMHhEODAwKSB7XG4gICAgICAgICAgICBpZiAoKGNvZGUgPiAweDFGICYmIGNvZGUgPCAweDdGKSB8fCAoY29kZSA+IDB4OUYgJiYgY29kZSAhPT0gTFMpIHx8XG4gICAgICAgICAgICAgICAgY29kZSA9PT0gVEFCKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzd2l0Y2ggKGNvZGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlIE5MOiAvLyAweEFcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5saW5lKys7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29sdW1uID0gMDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3NpdGlvbkF0TmV3TGluZSA9IHRoaXMucG9zaXRpb247XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOTDtcbiAgICAgICAgICAgICAgICBjYXNlIENSOiB7IC8vIDB4RFxuICAgICAgICAgICAgICAgICAgICAvLyBXZSBtYXkgZ2V0IE5hTiBpZiB3ZSByZWFkIHBhc3QgdGhlIGVuZCBvZiB0aGUgY2h1bmssIHdoaWNoIGlzXG4gICAgICAgICAgICAgICAgICAgIC8vIGZpbmUuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5leHQgPSBjaHVuay5jaGFyQ29kZUF0KGkgKyAxKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5leHQgPT09IE5MIHx8IG5leHQgPT09IE5FTCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQSBDUiBOTCBvciBDUiBORUwgc2VxdWVuY2UgaXMgY29udmVydGVkIHRvIE5MIHNvIHdlIGhhdmUgdG8gc2tpcFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3ZlciB0aGUgbmV4dCBjaGFyYWN0ZXIuIFdlIGFscmVhZHkga25vdyBpdCBoYXMgYSBzaXplIG9mIDEuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmkgPSBpICsgMjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UsIGEgQ1IgaXMganVzdCBjb252ZXJ0ZWQgdG8gTkwsIG5vIHNraXAuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8qIHllcywgZmFsbCB0aHJvdWdoICovXG4gICAgICAgICAgICAgICAgY2FzZSBORUw6IC8vIDB4ODVcbiAgICAgICAgICAgICAgICBjYXNlIExTOiAvLyBPeDIwMjhcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5saW5lKys7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29sdW1uID0gMDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3NpdGlvbkF0TmV3TGluZSA9IHRoaXMucG9zaXRpb247XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOTF9MSUtFO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmFpbChcImRpc2FsbG93ZWQgY2hhcmFjdGVyLlwiKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvZGUgPiAweERCRkYpIHtcbiAgICAgICAgICAgIC8vIFRoaXMgaXMgYSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGlzQ2hhckFuZE5vdFJlc3RyaWN0ZWQgdGhhdCB0YWtlcyBpbnRvXG4gICAgICAgICAgICAvLyBhY2NvdW50IHRoYXQgaW4gdGhpcyBjb250ZXh0IGNvZGUgPiAweERCRkYgYW5kIGNvZGUgPD0gMHhGRkZGLiBTbyBpdFxuICAgICAgICAgICAgLy8gZG9lcyBub3QgdGVzdCBjYXNlcyB0aGF0IGRvbid0IG5lZWQgdGVzdGluZy5cbiAgICAgICAgICAgIGlmICghKGNvZGUgPj0gMHhFMDAwICYmIGNvZGUgPD0gMHhGRkZEKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZmFpbChcImRpc2FsbG93ZWQgY2hhcmFjdGVyLlwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBjb2RlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGZpbmFsID0gMHgxMDAwMCArICgoY29kZSAtIDB4RDgwMCkgKiAweDQwMCkgK1xuICAgICAgICAgICAgKGNodW5rLmNoYXJDb2RlQXQoaSArIDEpIC0gMHhEQzAwKTtcbiAgICAgICAgdGhpcy5pID0gaSArIDI7XG4gICAgICAgIC8vIFRoaXMgaXMgYSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGlzQ2hhckFuZE5vdFJlc3RyaWN0ZWQgdGhhdCB0YWtlcyBpbnRvXG4gICAgICAgIC8vIGFjY291bnQgdGhhdCBpbiB0aGlzIGNvbnRleHQgbmVjZXNzYXJpbHkgZmluYWwgPj0gMHgxMDAwMC5cbiAgICAgICAgaWYgKGZpbmFsID4gMHgxMEZGRkYpIHtcbiAgICAgICAgICAgIHRoaXMuZmFpbChcImRpc2FsbG93ZWQgY2hhcmFjdGVyLlwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmluYWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIExpa2UgYGBnZXRDb2RlYGAgYnV0IHdpdGggdGhlIHJldHVybiB2YWx1ZSBub3JtYWxpemVkIHNvIHRoYXQgYGBOTGBgIGlzXG4gICAgICogcmV0dXJuZWQgZm9yIGBgTkxfTElLRWBgLlxuICAgICAqL1xuICAgIGdldENvZGVOb3JtKCkge1xuICAgICAgICBjb25zdCBjID0gdGhpcy5nZXRDb2RlKCk7XG4gICAgICAgIHJldHVybiBjID09PSBOTF9MSUtFID8gTkwgOiBjO1xuICAgIH1cbiAgICB1bmdldCgpIHtcbiAgICAgICAgdGhpcy5pID0gdGhpcy5wcmV2STtcbiAgICAgICAgdGhpcy5jb2x1bW4tLTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FwdHVyZSBjaGFyYWN0ZXJzIGludG8gYSBidWZmZXIgdW50aWwgZW5jb3VudGVyaW5nIG9uZSBvZiBhIHNldCBvZlxuICAgICAqIGNoYXJhY3RlcnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY2hhcnMgQW4gYXJyYXkgb2YgY29kZXBvaW50cy4gRW5jb3VudGVyaW5nIGEgY2hhcmFjdGVyIGluIHRoZSBhcnJheVxuICAgICAqIGVuZHMgdGhlIGNhcHR1cmUuIChgYGNoYXJzYGAgbWF5IHNhZmVseSBjb250YWluIGBgTkxgYC4pXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIFRoZSBjaGFyYWN0ZXIgY29kZSB0aGF0IG1hZGUgdGhlIGNhcHR1cmUgZW5kLCBvciBgYEVPQ2BgIGlmIHdlIGhpdFxuICAgICAqIHRoZSBlbmQgb2YgdGhlIGNodW5rLiBUaGUgcmV0dXJuIHZhbHVlIGNhbm5vdCBiZSBOTF9MSUtFOiBOTCBpcyByZXR1cm5lZFxuICAgICAqIGluc3RlYWQuXG4gICAgICovXG4gICAgY2FwdHVyZVRvKGNoYXJzKSB7XG4gICAgICAgIGxldCB7IGk6IHN0YXJ0IH0gPSB0aGlzO1xuICAgICAgICBjb25zdCB7IGNodW5rIH0gPSB0aGlzO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc3RhbnQtY29uZGl0aW9uXG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICBjb25zdCBjID0gdGhpcy5nZXRDb2RlKCk7XG4gICAgICAgICAgICBjb25zdCBpc05MTGlrZSA9IGMgPT09IE5MX0xJS0U7XG4gICAgICAgICAgICBjb25zdCBmaW5hbCA9IGlzTkxMaWtlID8gTkwgOiBjO1xuICAgICAgICAgICAgaWYgKGZpbmFsID09PSBFT0MgfHwgY2hhcnMuaW5jbHVkZXMoZmluYWwpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50ZXh0ICs9IGNodW5rLnNsaWNlKHN0YXJ0LCB0aGlzLnByZXZJKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmluYWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNOTExpa2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRleHQgKz0gYCR7Y2h1bmsuc2xpY2Uoc3RhcnQsIHRoaXMucHJldkkpfVxcbmA7XG4gICAgICAgICAgICAgICAgc3RhcnQgPSB0aGlzLmk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FwdHVyZSBjaGFyYWN0ZXJzIGludG8gYSBidWZmZXIgdW50aWwgZW5jb3VudGVyaW5nIGEgY2hhcmFjdGVyLlxuICAgICAqXG4gICAgICogQHBhcmFtIGNoYXIgVGhlIGNvZGVwb2ludCB0aGF0IGVuZHMgdGhlIGNhcHR1cmUuICoqTk9URSBgYGNoYXJgYCBNQVkgTk9UXG4gICAgICogQ09OVEFJTiBgYE5MYGAuKiogUGFzc2luZyBgYE5MYGAgd2lsbCByZXN1bHQgaW4gYnVnZ3kgYmVoYXZpb3IuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIGBgdHJ1ZWBgIGlmIHdlIHJhbiBpbnRvIHRoZSBjaGFyYWN0ZXIuIE90aGVyd2lzZSwgd2UgcmFuIGludG8gdGhlXG4gICAgICogZW5kIG9mIHRoZSBjdXJyZW50IGNodW5rLlxuICAgICAqL1xuICAgIGNhcHR1cmVUb0NoYXIoY2hhcikge1xuICAgICAgICBsZXQgeyBpOiBzdGFydCB9ID0gdGhpcztcbiAgICAgICAgY29uc3QgeyBjaHVuayB9ID0gdGhpcztcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnN0YW50LWNvbmRpdGlvblxuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgbGV0IGMgPSB0aGlzLmdldENvZGUoKTtcbiAgICAgICAgICAgIHN3aXRjaCAoYykge1xuICAgICAgICAgICAgICAgIGNhc2UgTkxfTElLRTpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50ZXh0ICs9IGAke2NodW5rLnNsaWNlKHN0YXJ0LCB0aGlzLnByZXZJKX1cXG5gO1xuICAgICAgICAgICAgICAgICAgICBzdGFydCA9IHRoaXMuaTtcbiAgICAgICAgICAgICAgICAgICAgYyA9IE5MO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIEVPQzpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50ZXh0ICs9IGNodW5rLnNsaWNlKHN0YXJ0KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYyA9PT0gY2hhcikge1xuICAgICAgICAgICAgICAgIHRoaXMudGV4dCArPSBjaHVuay5zbGljZShzdGFydCwgdGhpcy5wcmV2SSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FwdHVyZSBjaGFyYWN0ZXJzIHRoYXQgc2F0aXNmeSBgYGlzTmFtZUNoYXJgYCBpbnRvIHRoZSBgYG5hbWVgYCBmaWVsZCBvZlxuICAgICAqIHRoaXMgcGFyc2VyLlxuICAgICAqXG4gICAgICogQHJldHVybiBUaGUgY2hhcmFjdGVyIGNvZGUgdGhhdCBtYWRlIHRoZSB0ZXN0IGZhaWwsIG9yIGBgRU9DYGAgaWYgd2UgaGl0XG4gICAgICogdGhlIGVuZCBvZiB0aGUgY2h1bmsuIFRoZSByZXR1cm4gdmFsdWUgY2Fubm90IGJlIE5MX0xJS0U6IE5MIGlzIHJldHVybmVkXG4gICAgICogaW5zdGVhZC5cbiAgICAgKi9cbiAgICBjYXB0dXJlTmFtZUNoYXJzKCkge1xuICAgICAgICBjb25zdCB7IGNodW5rLCBpOiBzdGFydCB9ID0gdGhpcztcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnN0YW50LWNvbmRpdGlvblxuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgY29uc3QgYyA9IHRoaXMuZ2V0Q29kZSgpO1xuICAgICAgICAgICAgaWYgKGMgPT09IEVPQykge1xuICAgICAgICAgICAgICAgIHRoaXMubmFtZSArPSBjaHVuay5zbGljZShzdGFydCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEVPQztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIE5MIGlzIG5vdCBhIG5hbWUgY2hhciBzbyB3ZSBkb24ndCBoYXZlIHRvIHRlc3Qgc3BlY2lmaWNhbGx5IGZvciBpdC5cbiAgICAgICAgICAgIGlmICghaXNOYW1lQ2hhcihjKSkge1xuICAgICAgICAgICAgICAgIHRoaXMubmFtZSArPSBjaHVuay5zbGljZShzdGFydCwgdGhpcy5wcmV2SSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGMgPT09IE5MX0xJS0UgPyBOTCA6IGM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU2tpcCB3aGl0ZSBzcGFjZXMuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIFRoZSBjaGFyYWN0ZXIgdGhhdCBlbmRlZCB0aGUgc2tpcCwgb3IgYGBFT0NgYCBpZiB3ZSBoaXRcbiAgICAgKiB0aGUgZW5kIG9mIHRoZSBjaHVuay4gVGhlIHJldHVybiB2YWx1ZSBjYW5ub3QgYmUgTkxfTElLRTogTkwgaXMgcmV0dXJuZWRcbiAgICAgKiBpbnN0ZWFkLlxuICAgICAqL1xuICAgIHNraXBTcGFjZXMoKSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zdGFudC1jb25kaXRpb25cbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIGNvbnN0IGMgPSB0aGlzLmdldENvZGVOb3JtKCk7XG4gICAgICAgICAgICBpZiAoYyA9PT0gRU9DIHx8ICFpc1MoYykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBzZXRYTUxWZXJzaW9uKHZlcnNpb24pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50WE1MVmVyc2lvbiA9IHZlcnNpb247XG4gICAgICAgIC8qICBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvdW5ib3VuZC1tZXRob2QgKi9cbiAgICAgICAgaWYgKHZlcnNpb24gPT09IFwiMS4wXCIpIHtcbiAgICAgICAgICAgIHRoaXMuaXNDaGFyID0gaXNDaGFyMTA7XG4gICAgICAgICAgICB0aGlzLmdldENvZGUgPSB0aGlzLmdldENvZGUxMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaXNDaGFyID0gaXNDaGFyMTE7XG4gICAgICAgICAgICB0aGlzLmdldENvZGUgPSB0aGlzLmdldENvZGUxMTtcbiAgICAgICAgfVxuICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIEB0eXBlc2NyaXB0LWVzbGludC91bmJvdW5kLW1ldGhvZCAqL1xuICAgIH1cbiAgICAvLyBTVEFURSBFTkdJTkUgTUVUSE9EU1xuICAgIC8vIFRoaXMgbmVlZHMgdG8gYmUgYSBzdGF0ZSBzZXBhcmF0ZSBmcm9tIFNfQkVHSU5fV0hJVEVTUEFDRSBiZWNhdXNlIHdlIHdhbnRcbiAgICAvLyB0byBiZSBzdXJlIG5ldmVyIHRvIGNvbWUgYmFjayB0byB0aGlzIHN0YXRlIGxhdGVyLlxuICAgIHNCZWdpbigpIHtcbiAgICAgICAgLy8gV2UgYXJlIGVzc2VudGlhbGx5IHBlZWtpbmcgYXQgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgY2h1bmsuIFNpbmNlXG4gICAgICAgIC8vIFNfQkVHSU4gY2FuIGJlIGluIGVmZmVjdCBvbmx5IHdoZW4gd2Ugc3RhcnQgd29ya2luZyBvbiB0aGUgZmlyc3QgY2h1bmssXG4gICAgICAgIC8vIHRoZSBpbmRleCBhdCB3aGljaCB3ZSBtdXN0IGxvb2sgaXMgbmVjZXNzYXJpbHkgMC4gTm90ZSBhbHNvIHRoYXQgdGhlXG4gICAgICAgIC8vIGZvbGxvd2luZyB0ZXN0IGRvZXMgbm90IGRlcGVuZCBvbiBkZWNvZGluZyBzdXJyb2dhdGVzLlxuICAgICAgICAvLyBJZiB0aGUgaW5pdGlhbCBjaGFyYWN0ZXIgaXMgMHhGRUZGLCBpZ25vcmUgaXQuXG4gICAgICAgIGlmICh0aGlzLmNodW5rLmNoYXJDb2RlQXQoMCkgPT09IDB4RkVGRikge1xuICAgICAgICAgICAgdGhpcy5pKys7XG4gICAgICAgICAgICB0aGlzLmNvbHVtbisrO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RhdGUgPSBTX0JFR0lOX1dISVRFU1BBQ0U7XG4gICAgfVxuICAgIHNCZWdpbldoaXRlc3BhY2UoKSB7XG4gICAgICAgIC8vIFdlIG5lZWQgdG8ga25vdyB3aGV0aGVyIHdlJ3ZlIGVuY291bnRlcmVkIHNwYWNlcyBvciBub3QgYmVjYXVzZSBhcyBzb29uXG4gICAgICAgIC8vIGFzIHdlIHJ1biBpbnRvIGEgc3BhY2UsIGFuIFhNTCBkZWNsYXJhdGlvbiBpcyBubyBsb25nZXIgcG9zc2libGUuIFJhdGhlclxuICAgICAgICAvLyB0aGFuIHNsb3cgZG93biBza2lwU3BhY2VzIGV2ZW4gaW4gcGxhY2VzIHdoZXJlIHdlIGRvbid0IGNhcmUgd2hldGhlciBpdFxuICAgICAgICAvLyBza2lwcGVkIGFueXRoaW5nIG9yIG5vdCwgd2UgY2hlY2sgd2hldGhlciBwcmV2SSBpcyBlcXVhbCB0byB0aGUgdmFsdWUgb2ZcbiAgICAgICAgLy8gaSBmcm9tIGJlZm9yZSB3ZSBza2lwIHNwYWNlcy5cbiAgICAgICAgY29uc3QgaUJlZm9yZSA9IHRoaXMuaTtcbiAgICAgICAgY29uc3QgYyA9IHRoaXMuc2tpcFNwYWNlcygpO1xuICAgICAgICBpZiAodGhpcy5wcmV2SSAhPT0gaUJlZm9yZSkge1xuICAgICAgICAgICAgdGhpcy54bWxEZWNsUG9zc2libGUgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKGMpIHtcbiAgICAgICAgICAgIGNhc2UgTEVTUzpcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gU19PUEVOX1dBS0E7XG4gICAgICAgICAgICAgICAgLy8gV2UgY291bGQgbmFpdmVseSBjYWxsIGNsb3NlVGV4dCBidXQgaW4gdGhpcyBzdGF0ZSwgaXQgaXMgbm90IG5vcm1hbFxuICAgICAgICAgICAgICAgIC8vIHRvIGhhdmUgdGV4dCBiZSBmaWxsZWQgd2l0aCBhbnkgZGF0YS5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy50ZXh0Lmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJuby1lbXB0eSB0ZXh0IGF0IHN0YXJ0XCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRU9DOlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aGlzLnVuZ2V0KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfVEVYVDtcbiAgICAgICAgICAgICAgICB0aGlzLnhtbERlY2xQb3NzaWJsZSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNEb2N0eXBlKCkge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIGNvbnN0IGMgPSB0aGlzLmNhcHR1cmVUbyhET0NUWVBFX1RFUk1JTkFUT1IpO1xuICAgICAgICBzd2l0Y2ggKGMpIHtcbiAgICAgICAgICAgIGNhc2UgR1JFQVRFUjoge1xuICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtZXhwcmVzc2lvbnNcbiAgICAgICAgICAgICAgICAoX2EgPSB0aGlzLmRvY3R5cGVIYW5kbGVyKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EuY2FsbCh0aGlzLCB0aGlzLnRleHQpO1xuICAgICAgICAgICAgICAgIHRoaXMudGV4dCA9IFwiXCI7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfVEVYVDtcbiAgICAgICAgICAgICAgICB0aGlzLmRvY3R5cGUgPSB0cnVlOyAvLyBqdXN0IHJlbWVtYmVyIHRoYXQgd2Ugc2F3IGl0LlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBFT0M6XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRoaXMudGV4dCArPSBTdHJpbmcuZnJvbUNvZGVQb2ludChjKTtcbiAgICAgICAgICAgICAgICBpZiAoYyA9PT0gT1BFTl9CUkFDS0VUKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX0RURDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoaXNRdW90ZShjKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gU19ET0NUWVBFX1FVT1RFO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnEgPSBjO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBzRG9jdHlwZVF1b3RlKCkge1xuICAgICAgICBjb25zdCBxID0gdGhpcy5xO1xuICAgICAgICBpZiAodGhpcy5jYXB0dXJlVG9DaGFyKHEpKSB7XG4gICAgICAgICAgICB0aGlzLnRleHQgKz0gU3RyaW5nLmZyb21Db2RlUG9pbnQocSk7XG4gICAgICAgICAgICB0aGlzLnEgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfRE9DVFlQRTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzRFREKCkge1xuICAgICAgICBjb25zdCBjID0gdGhpcy5jYXB0dXJlVG8oRFREX1RFUk1JTkFUT1IpO1xuICAgICAgICBpZiAoYyA9PT0gRU9DKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50ZXh0ICs9IFN0cmluZy5mcm9tQ29kZVBvaW50KGMpO1xuICAgICAgICBpZiAoYyA9PT0gQ0xPU0VfQlJBQ0tFVCkge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfRE9DVFlQRTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjID09PSBMRVNTKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gU19EVERfT1BFTl9XQUtBO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzUXVvdGUoYykpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX0RURF9RVU9URUQ7XG4gICAgICAgICAgICB0aGlzLnEgPSBjO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNEVERRdW90ZWQoKSB7XG4gICAgICAgIGNvbnN0IHEgPSB0aGlzLnE7XG4gICAgICAgIGlmICh0aGlzLmNhcHR1cmVUb0NoYXIocSkpIHtcbiAgICAgICAgICAgIHRoaXMudGV4dCArPSBTdHJpbmcuZnJvbUNvZGVQb2ludChxKTtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX0RURDtcbiAgICAgICAgICAgIHRoaXMucSA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc0RURE9wZW5XYWthKCkge1xuICAgICAgICBjb25zdCBjID0gdGhpcy5nZXRDb2RlTm9ybSgpO1xuICAgICAgICB0aGlzLnRleHQgKz0gU3RyaW5nLmZyb21Db2RlUG9pbnQoYyk7XG4gICAgICAgIHN3aXRjaCAoYykge1xuICAgICAgICAgICAgY2FzZSBCQU5HOlxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX0RURF9PUEVOX1dBS0FfQkFORztcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW5XYWthQmFuZyA9IFwiXCI7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFFVRVNUSU9OOlxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX0RURF9QSTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfRFREO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNEVERPcGVuV2FrYUJhbmcoKSB7XG4gICAgICAgIGNvbnN0IGNoYXIgPSBTdHJpbmcuZnJvbUNvZGVQb2ludCh0aGlzLmdldENvZGVOb3JtKCkpO1xuICAgICAgICBjb25zdCBvd2IgPSB0aGlzLm9wZW5XYWthQmFuZyArPSBjaGFyO1xuICAgICAgICB0aGlzLnRleHQgKz0gY2hhcjtcbiAgICAgICAgaWYgKG93YiAhPT0gXCItXCIpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBvd2IgPT09IFwiLS1cIiA/IFNfRFREX0NPTU1FTlQgOiBTX0RURDtcbiAgICAgICAgICAgIHRoaXMub3Blbldha2FCYW5nID0gXCJcIjtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzRFREQ29tbWVudCgpIHtcbiAgICAgICAgaWYgKHRoaXMuY2FwdHVyZVRvQ2hhcihNSU5VUykpIHtcbiAgICAgICAgICAgIHRoaXMudGV4dCArPSBcIi1cIjtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX0RURF9DT01NRU5UX0VORElORztcbiAgICAgICAgfVxuICAgIH1cbiAgICBzRFREQ29tbWVudEVuZGluZygpIHtcbiAgICAgICAgY29uc3QgYyA9IHRoaXMuZ2V0Q29kZU5vcm0oKTtcbiAgICAgICAgdGhpcy50ZXh0ICs9IFN0cmluZy5mcm9tQ29kZVBvaW50KGMpO1xuICAgICAgICB0aGlzLnN0YXRlID0gYyA9PT0gTUlOVVMgPyBTX0RURF9DT01NRU5UX0VOREVEIDogU19EVERfQ09NTUVOVDtcbiAgICB9XG4gICAgc0RURENvbW1lbnRFbmRlZCgpIHtcbiAgICAgICAgY29uc3QgYyA9IHRoaXMuZ2V0Q29kZU5vcm0oKTtcbiAgICAgICAgdGhpcy50ZXh0ICs9IFN0cmluZy5mcm9tQ29kZVBvaW50KGMpO1xuICAgICAgICBpZiAoYyA9PT0gR1JFQVRFUikge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfRFREO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5mYWlsKFwibWFsZm9ybWVkIGNvbW1lbnQuXCIpO1xuICAgICAgICAgICAgLy8gPCEtLSBibGFoIC0tIGJsb28gLS0+IHdpbGwgYmUgcmVjb3JkZWQgYXNcbiAgICAgICAgICAgIC8vIGEgY29tbWVudCBvZiBcIiBibGFoIC0tIGJsb28gXCJcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX0RURF9DT01NRU5UO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNEVERQSSgpIHtcbiAgICAgICAgaWYgKHRoaXMuY2FwdHVyZVRvQ2hhcihRVUVTVElPTikpIHtcbiAgICAgICAgICAgIHRoaXMudGV4dCArPSBcIj9cIjtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX0RURF9QSV9FTkRJTkc7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc0RURFBJRW5kaW5nKCkge1xuICAgICAgICBjb25zdCBjID0gdGhpcy5nZXRDb2RlTm9ybSgpO1xuICAgICAgICB0aGlzLnRleHQgKz0gU3RyaW5nLmZyb21Db2RlUG9pbnQoYyk7XG4gICAgICAgIGlmIChjID09PSBHUkVBVEVSKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gU19EVEQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc1RleHQoKSB7XG4gICAgICAgIC8vXG4gICAgICAgIC8vIFdlIGRpZCB0cnkgYSB2ZXJzaW9uIG9mIHNheGVzIHdoZXJlIHRoZSBTX1RFWFQgc3RhdGUgd2FzIHNwbGl0IGluIHR3b1xuICAgICAgICAvLyBzdGF0ZXM6IG9uZSBmb3IgdGV4dCBpbnNpZGUgdGhlIHJvb3QgZWxlbWVudCwgYW5kIG9uZSBmb3IgdGV4dFxuICAgICAgICAvLyBvdXRzaWRlLiBUaGlzIHdhcyBhdm9pZGluZyBoYXZpbmcgdG8gdGVzdCB0aGlzLnRhZ3MubGVuZ3RoIHRvIGRlY2lkZVxuICAgICAgICAvLyB3aGF0IGltcGxlbWVudGF0aW9uIHRvIGFjdHVhbGx5IHVzZS5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gUGVmb3JtYW5jZSB0ZXN0aW5nIG9uIGdpZ2FieXRlLXNpemUgZmlsZXMgZGlkIG5vdCBzaG93IGFueSBhZHZhbnRhZ2UgdG9cbiAgICAgICAgLy8gdXNpbmcgdGhlIHR3byBzdGF0ZXMgc29sdXRpb24gaW5zdGVhZCBvZiB0aGUgY3VycmVudCBvbmUuIENvbnZlcnNlbHksIGl0XG4gICAgICAgIC8vIG1hZGUgdGhlIGNvZGUgYSBiaXQgbW9yZSBjb21wbGljYXRlZCBlbHNld2hlcmUuIEZvciBpbnN0YW5jZSwgYSBjb21tZW50XG4gICAgICAgIC8vIGNhbiBhcHBlYXIgYmVmb3JlIHRoZSByb290IGVsZW1lbnQgc28gd2hlbiBhIGNvbW1lbnQgZW5kZWQgaXQgd2FzXG4gICAgICAgIC8vIG5lY2Vzc2FyeSB0byBkZXRlcm1pbmUgd2hldGhlciB0byByZXR1cm4gdG8gdGhlIFNfVEVYVCBzdGF0ZSBvciB0byB0aGVcbiAgICAgICAgLy8gbmV3IHRleHQtb3V0c2lkZS1yb290IHN0YXRlLlxuICAgICAgICAvL1xuICAgICAgICBpZiAodGhpcy50YWdzLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVUZXh0SW5Sb290KCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZVRleHRPdXRzaWRlUm9vdCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNFbnRpdHkoKSB7XG4gICAgICAgIC8vIFRoaXMgaXMgZXNzZW50aWFsbHkgYSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGNhcHR1cmVUb0NoYXIoU0VNSUNPTE9OLi4uKVxuICAgICAgICBsZXQgeyBpOiBzdGFydCB9ID0gdGhpcztcbiAgICAgICAgY29uc3QgeyBjaHVuayB9ID0gdGhpcztcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWxhYmVscywgbm8tcmVzdHJpY3RlZC1zeW50YXhcbiAgICAgICAgbG9vcDogXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zdGFudC1jb25kaXRpb25cbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIHN3aXRjaCAodGhpcy5nZXRDb2RlKCkpIHtcbiAgICAgICAgICAgICAgICBjYXNlIE5MX0xJS0U6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW50aXR5ICs9IGAke2NodW5rLnNsaWNlKHN0YXJ0LCB0aGlzLnByZXZJKX1cXG5gO1xuICAgICAgICAgICAgICAgICAgICBzdGFydCA9IHRoaXMuaTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBTRU1JQ09MT046IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBlbnRpdHlSZXR1cm5TdGF0ZSB9ID0gdGhpcztcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gdGhpcy5lbnRpdHkgKyBjaHVuay5zbGljZShzdGFydCwgdGhpcy5wcmV2SSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBlbnRpdHlSZXR1cm5TdGF0ZTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHBhcnNlZDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVudGl0eSA9PT0gXCJcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5mYWlsKFwiZW1wdHkgZW50aXR5IG5hbWUuXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VkID0gXCImO1wiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VkID0gdGhpcy5wYXJzZUVudGl0eShlbnRpdHkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbnRpdHkgPSBcIlwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChlbnRpdHlSZXR1cm5TdGF0ZSAhPT0gU19URVhUIHx8IHRoaXMudGV4dEhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50ZXh0ICs9IHBhcnNlZDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbGFiZWxzXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrIGxvb3A7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgRU9DOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVudGl0eSArPSBjaHVuay5zbGljZShzdGFydCk7XG4gICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1sYWJlbHNcbiAgICAgICAgICAgICAgICAgICAgYnJlYWsgbG9vcDtcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHNPcGVuV2FrYSgpIHtcbiAgICAgICAgLy8gUmVtaW5kZXI6IGEgc3RhdGUgaGFuZGxlciBpcyBjYWxsZWQgd2l0aCBhdCBsZWFzdCBvbmUgY2hhcmFjdGVyXG4gICAgICAgIC8vIGF2YWlsYWJsZSBpbiB0aGUgY3VycmVudCBjaHVuay4gU28gdGhlIGZpcnN0IGNhbGwgdG8gZ2V0IGNvZGUgaW5zaWRlIG9mXG4gICAgICAgIC8vIGEgc3RhdGUgaGFuZGxlciBjYW5ub3QgcmV0dXJuIGBgRU9DYGAuIFRoYXQncyB3aHkgd2UgZG9uJ3QgdGVzdFxuICAgICAgICAvLyBmb3IgaXQuXG4gICAgICAgIGNvbnN0IGMgPSB0aGlzLmdldENvZGUoKTtcbiAgICAgICAgLy8gZWl0aGVyIGEgLywgPywgISwgb3IgdGV4dCBpcyBjb21pbmcgbmV4dC5cbiAgICAgICAgaWYgKGlzTmFtZVN0YXJ0Q2hhcihjKSkge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfT1BFTl9UQUc7XG4gICAgICAgICAgICB0aGlzLnVuZ2V0KCk7XG4gICAgICAgICAgICB0aGlzLnhtbERlY2xQb3NzaWJsZSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgc3dpdGNoIChjKSB7XG4gICAgICAgICAgICAgICAgY2FzZSBGT1JXQVJEX1NMQVNIOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gU19DTE9TRV9UQUc7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMueG1sRGVjbFBvc3NpYmxlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgQkFORzpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfT1BFTl9XQUtBX0JBTkc7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3Blbldha2FCYW5nID0gXCJcIjtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy54bWxEZWNsUG9zc2libGUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBRVUVTVElPTjpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfUElfRklSU1RfQ0hBUjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mYWlsKFwiZGlzYWxsb3dlZCBjaGFyYWN0ZXIgaW4gdGFnIG5hbWVcIik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX1RFWFQ7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMueG1sRGVjbFBvc3NpYmxlID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgc09wZW5XYWthQmFuZygpIHtcbiAgICAgICAgdGhpcy5vcGVuV2FrYUJhbmcgKz0gU3RyaW5nLmZyb21Db2RlUG9pbnQodGhpcy5nZXRDb2RlTm9ybSgpKTtcbiAgICAgICAgc3dpdGNoICh0aGlzLm9wZW5XYWthQmFuZykge1xuICAgICAgICAgICAgY2FzZSBcIltDREFUQVtcIjpcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc2F3Um9vdCAmJiAhdGhpcy5yZXBvcnRlZFRleHRCZWZvcmVSb290KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmFpbChcInRleHQgZGF0YSBvdXRzaWRlIG9mIHJvb3Qgbm9kZS5cIik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVwb3J0ZWRUZXh0QmVmb3JlUm9vdCA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNsb3NlZFJvb3QgJiYgIXRoaXMucmVwb3J0ZWRUZXh0QWZ0ZXJSb290KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmFpbChcInRleHQgZGF0YSBvdXRzaWRlIG9mIHJvb3Qgbm9kZS5cIik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVwb3J0ZWRUZXh0QWZ0ZXJSb290ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfQ0RBVEE7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVuV2FrYUJhbmcgPSBcIlwiO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIi0tXCI6XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfQ09NTUVOVDtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW5XYWthQmFuZyA9IFwiXCI7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiRE9DVFlQRVwiOlxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX0RPQ1RZUEU7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZG9jdHlwZSB8fCB0aGlzLnNhd1Jvb3QpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mYWlsKFwiaW5hcHByb3ByaWF0ZWx5IGxvY2F0ZWQgZG9jdHlwZSBkZWNsYXJhdGlvbi5cIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMub3Blbldha2FCYW5nID0gXCJcIjtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgLy8gNyBoYXBwZW5zIHRvIGJlIHRoZSBtYXhpbXVtIGxlbmd0aCBvZiB0aGUgc3RyaW5nIHRoYXQgY2FuIHBvc3NpYmx5XG4gICAgICAgICAgICAgICAgLy8gbWF0Y2ggb25lIG9mIHRoZSBjYXNlcyBhYm92ZS5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5vcGVuV2FrYUJhbmcubGVuZ3RoID49IDcpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mYWlsKFwiaW5jb3JyZWN0IHN5bnRheC5cIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHNDb21tZW50KCkge1xuICAgICAgICBpZiAodGhpcy5jYXB0dXJlVG9DaGFyKE1JTlVTKSkge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfQ09NTUVOVF9FTkRJTkc7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc0NvbW1lbnRFbmRpbmcoKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgY29uc3QgYyA9IHRoaXMuZ2V0Q29kZU5vcm0oKTtcbiAgICAgICAgaWYgKGMgPT09IE1JTlVTKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gU19DT01NRU5UX0VOREVEO1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC1leHByZXNzaW9uc1xuICAgICAgICAgICAgKF9hID0gdGhpcy5jb21tZW50SGFuZGxlcikgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmNhbGwodGhpcywgdGhpcy50ZXh0KTtcbiAgICAgICAgICAgIHRoaXMudGV4dCA9IFwiXCI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnRleHQgKz0gYC0ke1N0cmluZy5mcm9tQ29kZVBvaW50KGMpfWA7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gU19DT01NRU5UO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNDb21tZW50RW5kZWQoKSB7XG4gICAgICAgIGNvbnN0IGMgPSB0aGlzLmdldENvZGVOb3JtKCk7XG4gICAgICAgIGlmIChjICE9PSBHUkVBVEVSKSB7XG4gICAgICAgICAgICB0aGlzLmZhaWwoXCJtYWxmb3JtZWQgY29tbWVudC5cIik7XG4gICAgICAgICAgICAvLyA8IS0tIGJsYWggLS0gYmxvbyAtLT4gd2lsbCBiZSByZWNvcmRlZCBhc1xuICAgICAgICAgICAgLy8gYSBjb21tZW50IG9mIFwiIGJsYWggLS0gYmxvbyBcIlxuICAgICAgICAgICAgdGhpcy50ZXh0ICs9IGAtLSR7U3RyaW5nLmZyb21Db2RlUG9pbnQoYyl9YDtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX0NPTU1FTlQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gU19URVhUO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNDRGF0YSgpIHtcbiAgICAgICAgaWYgKHRoaXMuY2FwdHVyZVRvQ2hhcihDTE9TRV9CUkFDS0VUKSkge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfQ0RBVEFfRU5ESU5HO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNDRGF0YUVuZGluZygpIHtcbiAgICAgICAgY29uc3QgYyA9IHRoaXMuZ2V0Q29kZU5vcm0oKTtcbiAgICAgICAgaWYgKGMgPT09IENMT1NFX0JSQUNLRVQpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX0NEQVRBX0VORElOR18yO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy50ZXh0ICs9IGBdJHtTdHJpbmcuZnJvbUNvZGVQb2ludChjKX1gO1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfQ0RBVEE7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc0NEYXRhRW5kaW5nMigpIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICBjb25zdCBjID0gdGhpcy5nZXRDb2RlTm9ybSgpO1xuICAgICAgICBzd2l0Y2ggKGMpIHtcbiAgICAgICAgICAgIGNhc2UgR1JFQVRFUjoge1xuICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtZXhwcmVzc2lvbnNcbiAgICAgICAgICAgICAgICAoX2EgPSB0aGlzLmNkYXRhSGFuZGxlcikgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmNhbGwodGhpcywgdGhpcy50ZXh0KTtcbiAgICAgICAgICAgICAgICB0aGlzLnRleHQgPSBcIlwiO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX1RFWFQ7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIENMT1NFX0JSQUNLRVQ6XG4gICAgICAgICAgICAgICAgdGhpcy50ZXh0ICs9IFwiXVwiO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aGlzLnRleHQgKz0gYF1dJHtTdHJpbmcuZnJvbUNvZGVQb2ludChjKX1gO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX0NEQVRBO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIFdlIG5lZWQgdGhpcyBzZXBhcmF0ZSBzdGF0ZSB0byBjaGVjayB0aGUgZmlyc3QgY2hhcmFjdGVyIGZvIHRoZSBwaSB0YXJnZXRcbiAgICAvLyB3aXRoIHRoaXMubmFtZVN0YXJ0Q2hlY2sgd2hpY2ggYWxsb3dzIGxlc3MgY2hhcmFjdGVycyB0aGFuIHRoaXMubmFtZUNoZWNrLlxuICAgIHNQSUZpcnN0Q2hhcigpIHtcbiAgICAgICAgY29uc3QgYyA9IHRoaXMuZ2V0Q29kZU5vcm0oKTtcbiAgICAgICAgLy8gVGhpcyBpcyBmaXJzdCBiZWNhdXNlIGluIHRoZSBjYXNlIHdoZXJlIHRoZSBmaWxlIGlzIHdlbGwtZm9ybWVkIHRoaXMgaXNcbiAgICAgICAgLy8gdGhlIGJyYW5jaCB0YWtlbi4gV2Ugb3B0aW1pemUgZm9yIHdlbGwtZm9ybWVkbmVzcy5cbiAgICAgICAgaWYgKHRoaXMubmFtZVN0YXJ0Q2hlY2soYykpIHtcbiAgICAgICAgICAgIHRoaXMucGlUYXJnZXQgKz0gU3RyaW5nLmZyb21Db2RlUG9pbnQoYyk7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gU19QSV9SRVNUO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGMgPT09IFFVRVNUSU9OIHx8IGlzUyhjKSkge1xuICAgICAgICAgICAgdGhpcy5mYWlsKFwicHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB3aXRob3V0IGEgdGFyZ2V0LlwiKTtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBjID09PSBRVUVTVElPTiA/IFNfUElfRU5ESU5HIDogU19QSV9CT0RZO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5mYWlsKFwiZGlzYWxsb3dlZCBjaGFyYWN0ZXIgaW4gcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBuYW1lLlwiKTtcbiAgICAgICAgICAgIHRoaXMucGlUYXJnZXQgKz0gU3RyaW5nLmZyb21Db2RlUG9pbnQoYyk7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gU19QSV9SRVNUO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNQSVJlc3QoKSB7XG4gICAgICAgIC8vIENhcHR1cmUgY2hhcmFjdGVycyBpbnRvIGEgcGlUYXJnZXQgd2hpbGUgYGB0aGlzLm5hbWVDaGVja2BgIHJ1biBvbiB0aGVcbiAgICAgICAgLy8gY2hhcmFjdGVyIHJlYWQgcmV0dXJucyB0cnVlLlxuICAgICAgICBjb25zdCB7IGNodW5rLCBpOiBzdGFydCB9ID0gdGhpcztcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnN0YW50LWNvbmRpdGlvblxuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgY29uc3QgYyA9IHRoaXMuZ2V0Q29kZU5vcm0oKTtcbiAgICAgICAgICAgIGlmIChjID09PSBFT0MpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBpVGFyZ2V0ICs9IGNodW5rLnNsaWNlKHN0YXJ0KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBOTCBjYW5ub3Qgc2F0aXNmeSB0aGlzLm5hbWVDaGVjayBzbyB3ZSBkb24ndCBoYXZlIHRvIHRlc3Qgc3BlY2lmaWNhbGx5XG4gICAgICAgICAgICAvLyBmb3IgaXQuXG4gICAgICAgICAgICBpZiAoIXRoaXMubmFtZUNoZWNrKGMpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5waVRhcmdldCArPSBjaHVuay5zbGljZShzdGFydCwgdGhpcy5wcmV2SSk7XG4gICAgICAgICAgICAgICAgY29uc3QgaXNRdWVzdGlvbiA9IGMgPT09IFFVRVNUSU9OO1xuICAgICAgICAgICAgICAgIGlmIChpc1F1ZXN0aW9uIHx8IGlzUyhjKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5waVRhcmdldCA9PT0gXCJ4bWxcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLnhtbERlY2xQb3NzaWJsZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZmFpbChcImFuIFhNTCBkZWNsYXJhdGlvbiBtdXN0IGJlIGF0IHRoZSBzdGFydCBvZiB0aGUgZG9jdW1lbnQuXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IGlzUXVlc3Rpb24gPyBTX1hNTF9ERUNMX0VORElORyA6IFNfWE1MX0RFQ0xfTkFNRV9TVEFSVDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBpc1F1ZXN0aW9uID8gU19QSV9FTkRJTkcgOiBTX1BJX0JPRFk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmFpbChcImRpc2FsbG93ZWQgY2hhcmFjdGVyIGluIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gbmFtZS5cIik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGlUYXJnZXQgKz0gU3RyaW5nLmZyb21Db2RlUG9pbnQoYyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHNQSUJvZHkoKSB7XG4gICAgICAgIGlmICh0aGlzLnRleHQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBjb25zdCBjID0gdGhpcy5nZXRDb2RlTm9ybSgpO1xuICAgICAgICAgICAgaWYgKGMgPT09IFFVRVNUSU9OKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfUElfRU5ESU5HO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIWlzUyhjKSkge1xuICAgICAgICAgICAgICAgIHRoaXMudGV4dCA9IFN0cmluZy5mcm9tQ29kZVBvaW50KGMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIFRoZSBxdWVzdGlvbiBtYXJrIGNoYXJhY3RlciBpcyBub3QgdmFsaWQgaW5zaWRlIGFueSBvZiB0aGUgWE1MXG4gICAgICAgIC8vIGRlY2xhcmF0aW9uIG5hbWUvdmFsdWUgcGFpcnMuXG4gICAgICAgIGVsc2UgaWYgKHRoaXMuY2FwdHVyZVRvQ2hhcihRVUVTVElPTikpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX1BJX0VORElORztcbiAgICAgICAgfVxuICAgIH1cbiAgICBzUElFbmRpbmcoKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgY29uc3QgYyA9IHRoaXMuZ2V0Q29kZU5vcm0oKTtcbiAgICAgICAgaWYgKGMgPT09IEdSRUFURVIpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgcGlUYXJnZXQgfSA9IHRoaXM7XG4gICAgICAgICAgICBpZiAocGlUYXJnZXQudG9Mb3dlckNhc2UoKSA9PT0gXCJ4bWxcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuZmFpbChcInRoZSBYTUwgZGVjbGFyYXRpb24gbXVzdCBhcHBlYXIgYXQgdGhlIHN0YXJ0IG9mIHRoZSBkb2N1bWVudC5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zXG4gICAgICAgICAgICAoX2EgPSB0aGlzLnBpSGFuZGxlcikgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmNhbGwodGhpcywge1xuICAgICAgICAgICAgICAgIHRhcmdldDogcGlUYXJnZXQsXG4gICAgICAgICAgICAgICAgYm9keTogdGhpcy50ZXh0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLnBpVGFyZ2V0ID0gdGhpcy50ZXh0ID0gXCJcIjtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX1RFWFQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYyA9PT0gUVVFU1RJT04pIHtcbiAgICAgICAgICAgIC8vIFdlIHJhbiBpbnRvID8/IGFzIHBhcnQgb2YgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uLiBXZSBpbml0aWFsbHkgdG9va1xuICAgICAgICAgICAgLy8gdGhlIGZpcnN0ID8gYXMgYSBzaWduIHRoYXQgdGhlIFBJIHdhcyBlbmRpbmcsIGJ1dCBpdCBpcyBub3QuIFNvIHdlIGhhdmVcbiAgICAgICAgICAgIC8vIHRvIGFkZCBpdCB0byB0aGUgYm9keSBidXQgd2UgdGFrZSB0aGUgbmV3ID8gYXMgYSBzaWduIHRoYXQgdGhlIFBJIGlzXG4gICAgICAgICAgICAvLyBlbmRpbmcuXG4gICAgICAgICAgICB0aGlzLnRleHQgKz0gXCI/XCI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnRleHQgKz0gYD8ke1N0cmluZy5mcm9tQ29kZVBvaW50KGMpfWA7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gU19QSV9CT0RZO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMueG1sRGVjbFBvc3NpYmxlID0gZmFsc2U7XG4gICAgfVxuICAgIHNYTUxEZWNsTmFtZVN0YXJ0KCkge1xuICAgICAgICBjb25zdCBjID0gdGhpcy5za2lwU3BhY2VzKCk7XG4gICAgICAgIC8vIFRoZSBxdWVzdGlvbiBtYXJrIGNoYXJhY3RlciBpcyBub3QgdmFsaWQgaW5zaWRlIGFueSBvZiB0aGUgWE1MXG4gICAgICAgIC8vIGRlY2xhcmF0aW9uIG5hbWUvdmFsdWUgcGFpcnMuXG4gICAgICAgIGlmIChjID09PSBRVUVTVElPTikge1xuICAgICAgICAgICAgLy8gSXQgaXMgdmFsaWQgdG8gZ28gdG8gU19YTUxfREVDTF9FTkRJTkcgZnJvbSB0aGlzIHN0YXRlLlxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfWE1MX0RFQ0xfRU5ESU5HO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjICE9PSBFT0MpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX1hNTF9ERUNMX05BTUU7XG4gICAgICAgICAgICB0aGlzLm5hbWUgPSBTdHJpbmcuZnJvbUNvZGVQb2ludChjKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzWE1MRGVjbE5hbWUoKSB7XG4gICAgICAgIGNvbnN0IGMgPSB0aGlzLmNhcHR1cmVUbyhYTUxfREVDTF9OQU1FX1RFUk1JTkFUT1IpO1xuICAgICAgICAvLyBUaGUgcXVlc3Rpb24gbWFyayBjaGFyYWN0ZXIgaXMgbm90IHZhbGlkIGluc2lkZSBhbnkgb2YgdGhlIFhNTFxuICAgICAgICAvLyBkZWNsYXJhdGlvbiBuYW1lL3ZhbHVlIHBhaXJzLlxuICAgICAgICBpZiAoYyA9PT0gUVVFU1RJT04pIHtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX1hNTF9ERUNMX0VORElORztcbiAgICAgICAgICAgIHRoaXMubmFtZSArPSB0aGlzLnRleHQ7XG4gICAgICAgICAgICB0aGlzLnRleHQgPSBcIlwiO1xuICAgICAgICAgICAgdGhpcy5mYWlsKFwiWE1MIGRlY2xhcmF0aW9uIGlzIGluY29tcGxldGUuXCIpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICghKGlzUyhjKSB8fCBjID09PSBFUVVBTCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm5hbWUgKz0gdGhpcy50ZXh0O1xuICAgICAgICB0aGlzLnRleHQgPSBcIlwiO1xuICAgICAgICBpZiAoIXRoaXMueG1sRGVjbEV4cGVjdHMuaW5jbHVkZXModGhpcy5uYW1lKSkge1xuICAgICAgICAgICAgc3dpdGNoICh0aGlzLm5hbWUubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZhaWwoXCJkaWQgbm90IGV4cGVjdCBhbnkgbW9yZSBuYW1lL3ZhbHVlIHBhaXJzLlwiKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZhaWwoYGV4cGVjdGVkIHRoZSBuYW1lICR7dGhpcy54bWxEZWNsRXhwZWN0c1swXX0uYCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmFpbChgZXhwZWN0ZWQgb25lIG9mICR7dGhpcy54bWxEZWNsRXhwZWN0cy5qb2luKFwiLCBcIil9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdGF0ZSA9IGMgPT09IEVRVUFMID8gU19YTUxfREVDTF9WQUxVRV9TVEFSVCA6IFNfWE1MX0RFQ0xfRVE7XG4gICAgfVxuICAgIHNYTUxEZWNsRXEoKSB7XG4gICAgICAgIGNvbnN0IGMgPSB0aGlzLmdldENvZGVOb3JtKCk7XG4gICAgICAgIC8vIFRoZSBxdWVzdGlvbiBtYXJrIGNoYXJhY3RlciBpcyBub3QgdmFsaWQgaW5zaWRlIGFueSBvZiB0aGUgWE1MXG4gICAgICAgIC8vIGRlY2xhcmF0aW9uIG5hbWUvdmFsdWUgcGFpcnMuXG4gICAgICAgIGlmIChjID09PSBRVUVTVElPTikge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfWE1MX0RFQ0xfRU5ESU5HO1xuICAgICAgICAgICAgdGhpcy5mYWlsKFwiWE1MIGRlY2xhcmF0aW9uIGlzIGluY29tcGxldGUuXCIpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc1MoYykpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYyAhPT0gRVFVQUwpIHtcbiAgICAgICAgICAgIHRoaXMuZmFpbChcInZhbHVlIHJlcXVpcmVkLlwiKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0YXRlID0gU19YTUxfREVDTF9WQUxVRV9TVEFSVDtcbiAgICB9XG4gICAgc1hNTERlY2xWYWx1ZVN0YXJ0KCkge1xuICAgICAgICBjb25zdCBjID0gdGhpcy5nZXRDb2RlTm9ybSgpO1xuICAgICAgICAvLyBUaGUgcXVlc3Rpb24gbWFyayBjaGFyYWN0ZXIgaXMgbm90IHZhbGlkIGluc2lkZSBhbnkgb2YgdGhlIFhNTFxuICAgICAgICAvLyBkZWNsYXJhdGlvbiBuYW1lL3ZhbHVlIHBhaXJzLlxuICAgICAgICBpZiAoYyA9PT0gUVVFU1RJT04pIHtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX1hNTF9ERUNMX0VORElORztcbiAgICAgICAgICAgIHRoaXMuZmFpbChcIlhNTCBkZWNsYXJhdGlvbiBpcyBpbmNvbXBsZXRlLlwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNTKGMpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc1F1b3RlKGMpKSB7XG4gICAgICAgICAgICB0aGlzLmZhaWwoXCJ2YWx1ZSBtdXN0IGJlIHF1b3RlZC5cIik7XG4gICAgICAgICAgICB0aGlzLnEgPSBTUEFDRTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucSA9IGM7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNfWE1MX0RFQ0xfVkFMVUU7XG4gICAgfVxuICAgIHNYTUxEZWNsVmFsdWUoKSB7XG4gICAgICAgIGNvbnN0IGMgPSB0aGlzLmNhcHR1cmVUbyhbdGhpcy5xLCBRVUVTVElPTl0pO1xuICAgICAgICAvLyBUaGUgcXVlc3Rpb24gbWFyayBjaGFyYWN0ZXIgaXMgbm90IHZhbGlkIGluc2lkZSBhbnkgb2YgdGhlIFhNTFxuICAgICAgICAvLyBkZWNsYXJhdGlvbiBuYW1lL3ZhbHVlIHBhaXJzLlxuICAgICAgICBpZiAoYyA9PT0gUVVFU1RJT04pIHtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX1hNTF9ERUNMX0VORElORztcbiAgICAgICAgICAgIHRoaXMudGV4dCA9IFwiXCI7XG4gICAgICAgICAgICB0aGlzLmZhaWwoXCJYTUwgZGVjbGFyYXRpb24gaXMgaW5jb21wbGV0ZS5cIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGMgPT09IEVPQykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy50ZXh0O1xuICAgICAgICB0aGlzLnRleHQgPSBcIlwiO1xuICAgICAgICBzd2l0Y2ggKHRoaXMubmFtZSkge1xuICAgICAgICAgICAgY2FzZSBcInZlcnNpb25cIjoge1xuICAgICAgICAgICAgICAgIHRoaXMueG1sRGVjbEV4cGVjdHMgPSBbXCJlbmNvZGluZ1wiLCBcInN0YW5kYWxvbmVcIl07XG4gICAgICAgICAgICAgICAgY29uc3QgdmVyc2lvbiA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHRoaXMueG1sRGVjbC52ZXJzaW9uID0gdmVyc2lvbjtcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSB0ZXN0IHNwZWNpZmllZCBieSBYTUwgMS4wIGJ1dCBpdCBpcyBmaW5lIGZvciBYTUwgMS4xLlxuICAgICAgICAgICAgICAgIGlmICghL14xXFwuWzAtOV0rJC8udGVzdCh2ZXJzaW9uKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZhaWwoXCJ2ZXJzaW9uIG51bWJlciBtdXN0IG1hdGNoIC9eMVxcXFwuWzAtOV0rJC8uXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBXaGVuIGZvcmNlWE1MVmVyc2lvbiBpcyBzZXQsIHRoZSBYTUwgZGVjbGFyYXRpb24gaXMgaWdub3JlZC5cbiAgICAgICAgICAgICAgICBlbHNlIGlmICghdGhpcy5vcHQuZm9yY2VYTUxWZXJzaW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0WE1MVmVyc2lvbih2ZXJzaW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiZW5jb2RpbmdcIjpcbiAgICAgICAgICAgICAgICBpZiAoIS9eW0EtWmEtel1bQS1aYS16MC05Ll8tXSokLy50ZXN0KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZhaWwoXCJlbmNvZGluZyB2YWx1ZSBtdXN0IG1hdGNoIFxcXG4vXltBLVphLXowLTldW0EtWmEtejAtOS5fLV0qJC8uXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnhtbERlY2xFeHBlY3RzID0gW1wic3RhbmRhbG9uZVwiXTtcbiAgICAgICAgICAgICAgICB0aGlzLnhtbERlY2wuZW5jb2RpbmcgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJzdGFuZGFsb25lXCI6XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBcInllc1wiICYmIHZhbHVlICE9PSBcIm5vXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mYWlsKFwic3RhbmRhbG9uZSB2YWx1ZSBtdXN0IG1hdGNoIFxcXCJ5ZXNcXFwiIG9yIFxcXCJub1xcXCIuXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnhtbERlY2xFeHBlY3RzID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy54bWxEZWNsLnN0YW5kYWxvbmUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAvLyBXZSBkb24ndCBuZWVkIHRvIHJhaXNlIGFuIGVycm9yIGhlcmUgc2luY2Ugd2UndmUgYWxyZWFkeSByYWlzZWQgb25lXG4gICAgICAgICAgICAvLyB3aGVuIGNoZWNraW5nIHdoYXQgbmFtZSB3YXMgZXhwZWN0ZWQuXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5uYW1lID0gXCJcIjtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNfWE1MX0RFQ0xfU0VQQVJBVE9SO1xuICAgIH1cbiAgICBzWE1MRGVjbFNlcGFyYXRvcigpIHtcbiAgICAgICAgY29uc3QgYyA9IHRoaXMuZ2V0Q29kZU5vcm0oKTtcbiAgICAgICAgLy8gVGhlIHF1ZXN0aW9uIG1hcmsgY2hhcmFjdGVyIGlzIG5vdCB2YWxpZCBpbnNpZGUgYW55IG9mIHRoZSBYTUxcbiAgICAgICAgLy8gZGVjbGFyYXRpb24gbmFtZS92YWx1ZSBwYWlycy5cbiAgICAgICAgaWYgKGMgPT09IFFVRVNUSU9OKSB7XG4gICAgICAgICAgICAvLyBJdCBpcyB2YWxpZCB0byBnbyB0byBTX1hNTF9ERUNMX0VORElORyBmcm9tIHRoaXMgc3RhdGUuXG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gU19YTUxfREVDTF9FTkRJTkc7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc1MoYykpIHtcbiAgICAgICAgICAgIHRoaXMuZmFpbChcIndoaXRlc3BhY2UgcmVxdWlyZWQuXCIpO1xuICAgICAgICAgICAgdGhpcy51bmdldCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RhdGUgPSBTX1hNTF9ERUNMX05BTUVfU1RBUlQ7XG4gICAgfVxuICAgIHNYTUxEZWNsRW5kaW5nKCkge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIGNvbnN0IGMgPSB0aGlzLmdldENvZGVOb3JtKCk7XG4gICAgICAgIGlmIChjID09PSBHUkVBVEVSKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5waVRhcmdldCAhPT0gXCJ4bWxcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuZmFpbChcInByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zIGFyZSBub3QgYWxsb3dlZCBiZWZvcmUgcm9vdC5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLm5hbWUgIT09IFwidmVyc2lvblwiICYmXG4gICAgICAgICAgICAgICAgdGhpcy54bWxEZWNsRXhwZWN0cy5pbmNsdWRlcyhcInZlcnNpb25cIikpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZhaWwoXCJYTUwgZGVjbGFyYXRpb24gbXVzdCBjb250YWluIGEgdmVyc2lvbi5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zXG4gICAgICAgICAgICAoX2EgPSB0aGlzLnhtbGRlY2xIYW5kbGVyKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EuY2FsbCh0aGlzLCB0aGlzLnhtbERlY2wpO1xuICAgICAgICAgICAgdGhpcy5uYW1lID0gXCJcIjtcbiAgICAgICAgICAgIHRoaXMucGlUYXJnZXQgPSB0aGlzLnRleHQgPSBcIlwiO1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfVEVYVDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFdlIGdvdCBoZXJlIGJlY2F1c2UgdGhlIHByZXZpb3VzIGNoYXJhY3RlciB3YXMgYSA/LCBidXQgdGhlIHF1ZXN0aW9uXG4gICAgICAgICAgICAvLyBtYXJrIGNoYXJhY3RlciBpcyBub3QgdmFsaWQgaW5zaWRlIGFueSBvZiB0aGUgWE1MIGRlY2xhcmF0aW9uXG4gICAgICAgICAgICAvLyBuYW1lL3ZhbHVlIHBhaXJzLlxuICAgICAgICAgICAgdGhpcy5mYWlsKFwiVGhlIGNoYXJhY3RlciA/IGlzIGRpc2FsbG93ZWQgYW55d2hlcmUgaW4gWE1MIGRlY2xhcmF0aW9ucy5cIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy54bWxEZWNsUG9zc2libGUgPSBmYWxzZTtcbiAgICB9XG4gICAgc09wZW5UYWcoKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgY29uc3QgYyA9IHRoaXMuY2FwdHVyZU5hbWVDaGFycygpO1xuICAgICAgICBpZiAoYyA9PT0gRU9DKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGFnID0gdGhpcy50YWcgPSB7XG4gICAgICAgICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICAgICAgICBhdHRyaWJ1dGVzOiBPYmplY3QuY3JlYXRlKG51bGwpLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlwiO1xuICAgICAgICBpZiAodGhpcy54bWxuc09wdCkge1xuICAgICAgICAgICAgdGhpcy50b3BOUyA9IHRhZy5ucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC1leHByZXNzaW9uc1xuICAgICAgICAoX2EgPSB0aGlzLm9wZW5UYWdTdGFydEhhbmRsZXIpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5jYWxsKHRoaXMsIHRhZyk7XG4gICAgICAgIHRoaXMuc2F3Um9vdCA9IHRydWU7XG4gICAgICAgIGlmICghdGhpcy5mcmFnbWVudE9wdCAmJiB0aGlzLmNsb3NlZFJvb3QpIHtcbiAgICAgICAgICAgIHRoaXMuZmFpbChcImRvY3VtZW50cyBtYXkgY29udGFpbiBvbmx5IG9uZSByb290LlwiKTtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKGMpIHtcbiAgICAgICAgICAgIGNhc2UgR1JFQVRFUjpcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW5UYWcoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRk9SV0FSRF9TTEFTSDpcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gU19PUEVOX1RBR19TTEFTSDtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgaWYgKCFpc1MoYykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mYWlsKFwiZGlzYWxsb3dlZCBjaGFyYWN0ZXIgaW4gdGFnIG5hbWUuXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gU19BVFRSSUI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc09wZW5UYWdTbGFzaCgpIHtcbiAgICAgICAgaWYgKHRoaXMuZ2V0Q29kZSgpID09PSBHUkVBVEVSKSB7XG4gICAgICAgICAgICB0aGlzLm9wZW5TZWxmQ2xvc2luZ1RhZygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5mYWlsKFwiZm9yd2FyZC1zbGFzaCBpbiBvcGVuaW5nIHRhZyBub3QgZm9sbG93ZWQgYnkgPi5cIik7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gU19BVFRSSUI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc0F0dHJpYigpIHtcbiAgICAgICAgY29uc3QgYyA9IHRoaXMuc2tpcFNwYWNlcygpO1xuICAgICAgICBpZiAoYyA9PT0gRU9DKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzTmFtZVN0YXJ0Q2hhcihjKSkge1xuICAgICAgICAgICAgdGhpcy51bmdldCgpO1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfQVRUUklCX05BTUU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYyA9PT0gR1JFQVRFUikge1xuICAgICAgICAgICAgdGhpcy5vcGVuVGFnKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYyA9PT0gRk9SV0FSRF9TTEFTSCkge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfT1BFTl9UQUdfU0xBU0g7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmZhaWwoXCJkaXNhbGxvd2VkIGNoYXJhY3RlciBpbiBhdHRyaWJ1dGUgbmFtZS5cIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc0F0dHJpYk5hbWUoKSB7XG4gICAgICAgIGNvbnN0IGMgPSB0aGlzLmNhcHR1cmVOYW1lQ2hhcnMoKTtcbiAgICAgICAgaWYgKGMgPT09IEVRVUFMKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gU19BVFRSSUJfVkFMVUU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNTKGMpKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gU19BVFRSSUJfTkFNRV9TQVdfV0hJVEU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYyA9PT0gR1JFQVRFUikge1xuICAgICAgICAgICAgdGhpcy5mYWlsKFwiYXR0cmlidXRlIHdpdGhvdXQgdmFsdWUuXCIpO1xuICAgICAgICAgICAgdGhpcy5wdXNoQXR0cmliKHRoaXMubmFtZSwgdGhpcy5uYW1lKTtcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IHRoaXMudGV4dCA9IFwiXCI7XG4gICAgICAgICAgICB0aGlzLm9wZW5UYWcoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjICE9PSBFT0MpIHtcbiAgICAgICAgICAgIHRoaXMuZmFpbChcImRpc2FsbG93ZWQgY2hhcmFjdGVyIGluIGF0dHJpYnV0ZSBuYW1lLlwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzQXR0cmliTmFtZVNhd1doaXRlKCkge1xuICAgICAgICBjb25zdCBjID0gdGhpcy5za2lwU3BhY2VzKCk7XG4gICAgICAgIHN3aXRjaCAoYykge1xuICAgICAgICAgICAgY2FzZSBFT0M6XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgY2FzZSBFUVVBTDpcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gU19BVFRSSUJfVkFMVUU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRoaXMuZmFpbChcImF0dHJpYnV0ZSB3aXRob3V0IHZhbHVlLlwiKTtcbiAgICAgICAgICAgICAgICAvLyBTaG91bGQgd2UgZG8gdGhpcz8/P1xuICAgICAgICAgICAgICAgIC8vIHRoaXMudGFnLmF0dHJpYnV0ZXNbdGhpcy5uYW1lXSA9IFwiXCI7XG4gICAgICAgICAgICAgICAgdGhpcy50ZXh0ID0gXCJcIjtcbiAgICAgICAgICAgICAgICB0aGlzLm5hbWUgPSBcIlwiO1xuICAgICAgICAgICAgICAgIGlmIChjID09PSBHUkVBVEVSKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3BlblRhZygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChpc05hbWVTdGFydENoYXIoYykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51bmdldCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gU19BVFRSSUJfTkFNRTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmFpbChcImRpc2FsbG93ZWQgY2hhcmFjdGVyIGluIGF0dHJpYnV0ZSBuYW1lLlwiKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfQVRUUklCO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBzQXR0cmliVmFsdWUoKSB7XG4gICAgICAgIGNvbnN0IGMgPSB0aGlzLmdldENvZGVOb3JtKCk7XG4gICAgICAgIGlmIChpc1F1b3RlKGMpKSB7XG4gICAgICAgICAgICB0aGlzLnEgPSBjO1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfQVRUUklCX1ZBTFVFX1FVT1RFRDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghaXNTKGMpKSB7XG4gICAgICAgICAgICB0aGlzLmZhaWwoXCJ1bnF1b3RlZCBhdHRyaWJ1dGUgdmFsdWUuXCIpO1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfQVRUUklCX1ZBTFVFX1VOUVVPVEVEO1xuICAgICAgICAgICAgdGhpcy51bmdldCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNBdHRyaWJWYWx1ZVF1b3RlZCgpIHtcbiAgICAgICAgLy8gV2UgZGVsaWJlcmF0ZWx5IGRvIG5vdCB1c2UgY2FwdHVyZVRvIGhlcmUuIFRoZSBzcGVjaWFsaXplZCBjb2RlIHdlIHVzZVxuICAgICAgICAvLyBoZXJlIGlzIGZhc3RlciB0aGFuIHVzaW5nIGNhcHR1cmVUby5cbiAgICAgICAgY29uc3QgeyBxLCBjaHVuayB9ID0gdGhpcztcbiAgICAgICAgbGV0IHsgaTogc3RhcnQgfSA9IHRoaXM7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zdGFudC1jb25kaXRpb25cbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIHN3aXRjaCAodGhpcy5nZXRDb2RlKCkpIHtcbiAgICAgICAgICAgICAgICBjYXNlIHE6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHVzaEF0dHJpYih0aGlzLm5hbWUsIHRoaXMudGV4dCArIGNodW5rLnNsaWNlKHN0YXJ0LCB0aGlzLnByZXZJKSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubmFtZSA9IHRoaXMudGV4dCA9IFwiXCI7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX0FUVFJJQl9WQUxVRV9DTE9TRUQ7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICBjYXNlIEFNUDpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50ZXh0ICs9IGNodW5rLnNsaWNlKHN0YXJ0LCB0aGlzLnByZXZJKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfRU5USVRZO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVudGl0eVJldHVyblN0YXRlID0gU19BVFRSSUJfVkFMVUVfUVVPVEVEO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgY2FzZSBOTDpcbiAgICAgICAgICAgICAgICBjYXNlIE5MX0xJS0U6XG4gICAgICAgICAgICAgICAgY2FzZSBUQUI6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudGV4dCArPSBgJHtjaHVuay5zbGljZShzdGFydCwgdGhpcy5wcmV2SSl9IGA7XG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0ID0gdGhpcy5pO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIExFU1M6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudGV4dCArPSBjaHVuay5zbGljZShzdGFydCwgdGhpcy5wcmV2SSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmFpbChcImRpc2FsbG93ZWQgY2hhcmFjdGVyLlwiKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIGNhc2UgRU9DOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRleHQgKz0gY2h1bmsuc2xpY2Uoc3RhcnQpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBzQXR0cmliVmFsdWVDbG9zZWQoKSB7XG4gICAgICAgIGNvbnN0IGMgPSB0aGlzLmdldENvZGVOb3JtKCk7XG4gICAgICAgIGlmIChpc1MoYykpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX0FUVFJJQjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjID09PSBHUkVBVEVSKSB7XG4gICAgICAgICAgICB0aGlzLm9wZW5UYWcoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjID09PSBGT1JXQVJEX1NMQVNIKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gU19PUEVOX1RBR19TTEFTSDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc05hbWVTdGFydENoYXIoYykpIHtcbiAgICAgICAgICAgIHRoaXMuZmFpbChcIm5vIHdoaXRlc3BhY2UgYmV0d2VlbiBhdHRyaWJ1dGVzLlwiKTtcbiAgICAgICAgICAgIHRoaXMudW5nZXQoKTtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX0FUVFJJQl9OQU1FO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5mYWlsKFwiZGlzYWxsb3dlZCBjaGFyYWN0ZXIgaW4gYXR0cmlidXRlIG5hbWUuXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNBdHRyaWJWYWx1ZVVucXVvdGVkKCkge1xuICAgICAgICAvLyBXZSBkb24ndCBkbyBhbnl0aGluZyByZWdhcmRpbmcgRU9MIG9yIHNwYWNlIGhhbmRsaW5nIGZvciB1bnF1b3RlZFxuICAgICAgICAvLyBhdHRyaWJ1dGVzLiBXZSBhbHJlYWR5IGhhdmUgZmFpbGVkIGJ5IHRoZSB0aW1lIHdlIGdldCBoZXJlLCBhbmQgdGhlXG4gICAgICAgIC8vIGNvbnRyYWN0IHRoYXQgc2F4ZXMgdXBob2xkcyBzdGF0ZXMgdGhhdCB1cG9uIGZhaWx1cmUsIGl0IGlzIG5vdCBzYWZlIHRvXG4gICAgICAgIC8vIHJlbHkgb24gdGhlIGRhdGEgcGFzc2VkIHRvIGV2ZW50IGhhbmRsZXJzIChvdGhlciB0aGFuXG4gICAgICAgIC8vIGBgb25lcnJvcmBgKS4gUGFzc2luZyBcImJhZFwiIGRhdGEgaXMgbm90IGEgcHJvYmxlbS5cbiAgICAgICAgY29uc3QgYyA9IHRoaXMuY2FwdHVyZVRvKEFUVFJJQl9WQUxVRV9VTlFVT1RFRF9URVJNSU5BVE9SKTtcbiAgICAgICAgc3dpdGNoIChjKSB7XG4gICAgICAgICAgICBjYXNlIEFNUDpcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gU19FTlRJVFk7XG4gICAgICAgICAgICAgICAgdGhpcy5lbnRpdHlSZXR1cm5TdGF0ZSA9IFNfQVRUUklCX1ZBTFVFX1VOUVVPVEVEO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBMRVNTOlxuICAgICAgICAgICAgICAgIHRoaXMuZmFpbChcImRpc2FsbG93ZWQgY2hhcmFjdGVyLlwiKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRU9DOlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpZiAodGhpcy50ZXh0LmluY2x1ZGVzKFwiXV0+XCIpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmFpbChcInRoZSBzdHJpbmcgXFxcIl1dPlxcXCIgaXMgZGlzYWxsb3dlZCBpbiBjaGFyIGRhdGEuXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnB1c2hBdHRyaWIodGhpcy5uYW1lLCB0aGlzLnRleHQpO1xuICAgICAgICAgICAgICAgIHRoaXMubmFtZSA9IHRoaXMudGV4dCA9IFwiXCI7XG4gICAgICAgICAgICAgICAgaWYgKGMgPT09IEdSRUFURVIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVuVGFnKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gU19BVFRSSUI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHNDbG9zZVRhZygpIHtcbiAgICAgICAgY29uc3QgYyA9IHRoaXMuY2FwdHVyZU5hbWVDaGFycygpO1xuICAgICAgICBpZiAoYyA9PT0gR1JFQVRFUikge1xuICAgICAgICAgICAgdGhpcy5jbG9zZVRhZygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzUyhjKSkge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfQ0xPU0VfVEFHX1NBV19XSElURTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjICE9PSBFT0MpIHtcbiAgICAgICAgICAgIHRoaXMuZmFpbChcImRpc2FsbG93ZWQgY2hhcmFjdGVyIGluIGNsb3NpbmcgdGFnLlwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzQ2xvc2VUYWdTYXdXaGl0ZSgpIHtcbiAgICAgICAgc3dpdGNoICh0aGlzLnNraXBTcGFjZXMoKSkge1xuICAgICAgICAgICAgY2FzZSBHUkVBVEVSOlxuICAgICAgICAgICAgICAgIHRoaXMuY2xvc2VUYWcoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRU9DOlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aGlzLmZhaWwoXCJkaXNhbGxvd2VkIGNoYXJhY3RlciBpbiBjbG9zaW5nIHRhZy5cIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gRU5EIE9GIFNUQVRFIEVOR0lORSBNRVRIT0RTXG4gICAgaGFuZGxlVGV4dEluUm9vdCgpIHtcbiAgICAgICAgLy8gVGhpcyBpcyBlc3NlbnRpYWxseSBhIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgY2FwdHVyZVRvIHdoaWNoIGlzIG9wdGltaXplZFxuICAgICAgICAvLyBmb3IgcGVyZm9ybWluZyB0aGUgXV0+IGNoZWNrLiBBIHByZXZpb3VzIHZlcnNpb24gb2YgdGhpcyBjb2RlLCBjaGVja2VkXG4gICAgICAgIC8vIGBgdGhpcy50ZXh0YGAgZm9yIHRoZSBwcmVzZW5jZSBvZiBdXT4uIEl0IHNpbXBsaWZpZWQgdGhlIGNvZGUgYnV0IHdhc1xuICAgICAgICAvLyB2ZXJ5IGNvc3RseSB3aGVuIGNoYXJhY3RlciBkYXRhIGNvbnRhaW5lZCBhIGxvdCBvZiBlbnRpdGllcyB0byBiZSBwYXJzZWQuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFNpbmNlIHdlIGFyZSB1c2luZyBhIHNwZWNpYWxpemVkIGxvb3AsIHdlIGFsc28ga2VlcCB0cmFjayBvZiB0aGUgcHJlc2VuY2VcbiAgICAgICAgLy8gb2YgXV0+IGluIHRleHQgZGF0YS4gVGhlIHNlcXVlbmNlIF1dPiBpcyBmb3JiaWRkZW4gdG8gYXBwZWFyIGFzLWlzLlxuICAgICAgICAvL1xuICAgICAgICBsZXQgeyBpOiBzdGFydCwgZm9yYmlkZGVuU3RhdGUgfSA9IHRoaXM7XG4gICAgICAgIGNvbnN0IHsgY2h1bmssIHRleHRIYW5kbGVyOiBoYW5kbGVyIH0gPSB0aGlzO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbGFiZWxzLCBuby1yZXN0cmljdGVkLXN5bnRheFxuICAgICAgICBzY2FuTG9vcDogXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zdGFudC1jb25kaXRpb25cbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIHN3aXRjaCAodGhpcy5nZXRDb2RlKCkpIHtcbiAgICAgICAgICAgICAgICBjYXNlIExFU1M6IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNfT1BFTl9XQUtBO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaGFuZGxlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IHRleHQgfSA9IHRoaXM7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzbGljZSA9IGNodW5rLnNsaWNlKHN0YXJ0LCB0aGlzLnByZXZJKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZXh0Lmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIodGV4dCArIHNsaWNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRleHQgPSBcIlwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoc2xpY2UubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlcihzbGljZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZm9yYmlkZGVuU3RhdGUgPSBGT1JCSURERU5fU1RBUlQ7XG4gICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1sYWJlbHNcbiAgICAgICAgICAgICAgICAgICAgYnJlYWsgc2Nhbkxvb3A7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgQU1QOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gU19FTlRJVFk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW50aXR5UmV0dXJuU3RhdGUgPSBTX1RFWFQ7XG4gICAgICAgICAgICAgICAgICAgIGlmIChoYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudGV4dCArPSBjaHVuay5zbGljZShzdGFydCwgdGhpcy5wcmV2SSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZm9yYmlkZGVuU3RhdGUgPSBGT1JCSURERU5fU1RBUlQ7XG4gICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1sYWJlbHNcbiAgICAgICAgICAgICAgICAgICAgYnJlYWsgc2Nhbkxvb3A7XG4gICAgICAgICAgICAgICAgY2FzZSBDTE9TRV9CUkFDS0VUOlxuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGZvcmJpZGRlblN0YXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEZPUkJJRERFTl9TVEFSVDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JiaWRkZW5TdGF0ZSA9IEZPUkJJRERFTl9CUkFDS0VUO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBGT1JCSURERU5fQlJBQ0tFVDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JiaWRkZW5TdGF0ZSA9IEZPUkJJRERFTl9CUkFDS0VUX0JSQUNLRVQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEZPUkJJRERFTl9CUkFDS0VUX0JSQUNLRVQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImltcG9zc2libGUgc3RhdGVcIik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBHUkVBVEVSOlxuICAgICAgICAgICAgICAgICAgICBpZiAoZm9yYmlkZGVuU3RhdGUgPT09IEZPUkJJRERFTl9CUkFDS0VUX0JSQUNLRVQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZmFpbChcInRoZSBzdHJpbmcgXFxcIl1dPlxcXCIgaXMgZGlzYWxsb3dlZCBpbiBjaGFyIGRhdGEuXCIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZvcmJpZGRlblN0YXRlID0gRk9SQklEREVOX1NUQVJUO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIE5MX0xJS0U6XG4gICAgICAgICAgICAgICAgICAgIGlmIChoYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudGV4dCArPSBgJHtjaHVuay5zbGljZShzdGFydCwgdGhpcy5wcmV2SSl9XFxuYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBzdGFydCA9IHRoaXMuaTtcbiAgICAgICAgICAgICAgICAgICAgZm9yYmlkZGVuU3RhdGUgPSBGT1JCSURERU5fU1RBUlQ7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgRU9DOlxuICAgICAgICAgICAgICAgICAgICBpZiAoaGFuZGxlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRleHQgKz0gY2h1bmsuc2xpY2Uoc3RhcnQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1sYWJlbHNcbiAgICAgICAgICAgICAgICAgICAgYnJlYWsgc2Nhbkxvb3A7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgZm9yYmlkZGVuU3RhdGUgPSBGT1JCSURERU5fU1RBUlQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5mb3JiaWRkZW5TdGF0ZSA9IGZvcmJpZGRlblN0YXRlO1xuICAgIH1cbiAgICBoYW5kbGVUZXh0T3V0c2lkZVJvb3QoKSB7XG4gICAgICAgIC8vIFRoaXMgaXMgZXNzZW50aWFsbHkgYSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGNhcHR1cmVUbyB3aGljaCBpcyBvcHRpbWl6ZWRcbiAgICAgICAgLy8gZm9yIGEgc3BlY2lhbGl6ZWQgdGFzay4gV2Uga2VlcCB0cmFjayBvZiB0aGUgcHJlc2VuY2Ugb2Ygbm9uLXNwYWNlXG4gICAgICAgIC8vIGNoYXJhY3RlcnMgaW4gdGhlIHRleHQgc2luY2UgdGhlc2UgYXJlIGVycm9ycyB3aGVuIGFwcGVhcmluZyBvdXRzaWRlIHRoZVxuICAgICAgICAvLyBkb2N1bWVudCByb290IGVsZW1lbnQuXG4gICAgICAgIGxldCB7IGk6IHN0YXJ0IH0gPSB0aGlzO1xuICAgICAgICBjb25zdCB7IGNodW5rLCB0ZXh0SGFuZGxlcjogaGFuZGxlciB9ID0gdGhpcztcbiAgICAgICAgbGV0IG5vblNwYWNlID0gZmFsc2U7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1sYWJlbHMsIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG4gICAgICAgIG91dFJvb3RMb29wOiBcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnN0YW50LWNvbmRpdGlvblxuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgY29uc3QgY29kZSA9IHRoaXMuZ2V0Q29kZSgpO1xuICAgICAgICAgICAgc3dpdGNoIChjb2RlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSBMRVNTOiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTX09QRU5fV0FLQTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeyB0ZXh0IH0gPSB0aGlzO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2xpY2UgPSBjaHVuay5zbGljZShzdGFydCwgdGhpcy5wcmV2SSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGV4dC5sZW5ndGggIT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyKHRleHQgKyBzbGljZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50ZXh0ID0gXCJcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHNsaWNlLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIoc2xpY2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1sYWJlbHNcbiAgICAgICAgICAgICAgICAgICAgYnJlYWsgb3V0Um9vdExvb3A7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgQU1QOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gU19FTlRJVFk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW50aXR5UmV0dXJuU3RhdGUgPSBTX1RFWFQ7XG4gICAgICAgICAgICAgICAgICAgIGlmIChoYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudGV4dCArPSBjaHVuay5zbGljZShzdGFydCwgdGhpcy5wcmV2SSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbm9uU3BhY2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbGFiZWxzXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dFJvb3RMb29wO1xuICAgICAgICAgICAgICAgIGNhc2UgTkxfTElLRTpcbiAgICAgICAgICAgICAgICAgICAgaWYgKGhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50ZXh0ICs9IGAke2NodW5rLnNsaWNlKHN0YXJ0LCB0aGlzLnByZXZJKX1cXG5gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0ID0gdGhpcy5pO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIEVPQzpcbiAgICAgICAgICAgICAgICAgICAgaWYgKGhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50ZXh0ICs9IGNodW5rLnNsaWNlKHN0YXJ0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbGFiZWxzXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dFJvb3RMb29wO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGlmICghaXNTKGNvZGUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBub25TcGFjZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIW5vblNwYWNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gV2UgdXNlIHRoZSByZXBvcnRlZFRleHRCZWZvcmVSb290IGFuZCByZXBvcnRlZFRleHRBZnRlclJvb3QgZmxhZ3NcbiAgICAgICAgLy8gdG8gYXZvaWQgcmVwb3J0aW5nIGVycm9ycyBmb3IgZXZlcnkgc2luZ2xlIGNoYXJhY3RlciB0aGF0IGlzIG91dCBvZlxuICAgICAgICAvLyBwbGFjZS5cbiAgICAgICAgaWYgKCF0aGlzLnNhd1Jvb3QgJiYgIXRoaXMucmVwb3J0ZWRUZXh0QmVmb3JlUm9vdCkge1xuICAgICAgICAgICAgdGhpcy5mYWlsKFwidGV4dCBkYXRhIG91dHNpZGUgb2Ygcm9vdCBub2RlLlwiKTtcbiAgICAgICAgICAgIHRoaXMucmVwb3J0ZWRUZXh0QmVmb3JlUm9vdCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuY2xvc2VkUm9vdCAmJiAhdGhpcy5yZXBvcnRlZFRleHRBZnRlclJvb3QpIHtcbiAgICAgICAgICAgIHRoaXMuZmFpbChcInRleHQgZGF0YSBvdXRzaWRlIG9mIHJvb3Qgbm9kZS5cIik7XG4gICAgICAgICAgICB0aGlzLnJlcG9ydGVkVGV4dEFmdGVyUm9vdCA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcHVzaEF0dHJpYk5TKG5hbWUsIHZhbHVlKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgY29uc3QgeyBwcmVmaXgsIGxvY2FsIH0gPSB0aGlzLnFuYW1lKG5hbWUpO1xuICAgICAgICBjb25zdCBhdHRyID0geyBuYW1lLCBwcmVmaXgsIGxvY2FsLCB2YWx1ZSB9O1xuICAgICAgICB0aGlzLmF0dHJpYkxpc3QucHVzaChhdHRyKTtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC1leHByZXNzaW9uc1xuICAgICAgICAoX2EgPSB0aGlzLmF0dHJpYnV0ZUhhbmRsZXIpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5jYWxsKHRoaXMsIGF0dHIpO1xuICAgICAgICBpZiAocHJlZml4ID09PSBcInhtbG5zXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IHRyaW1tZWQgPSB2YWx1ZS50cmltKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5jdXJyZW50WE1MVmVyc2lvbiA9PT0gXCIxLjBcIiAmJiB0cmltbWVkID09PSBcIlwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mYWlsKFwiaW52YWxpZCBhdHRlbXB0IHRvIHVuZGVmaW5lIHByZWZpeCBpbiBYTUwgMS4wXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy50b3BOU1tsb2NhbF0gPSB0cmltbWVkO1xuICAgICAgICAgICAgbnNQYWlyQ2hlY2sodGhpcywgbG9jYWwsIHRyaW1tZWQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG5hbWUgPT09IFwieG1sbnNcIikge1xuICAgICAgICAgICAgY29uc3QgdHJpbW1lZCA9IHZhbHVlLnRyaW0oKTtcbiAgICAgICAgICAgIHRoaXMudG9wTlNbXCJcIl0gPSB0cmltbWVkO1xuICAgICAgICAgICAgbnNQYWlyQ2hlY2sodGhpcywgXCJcIiwgdHJpbW1lZCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcHVzaEF0dHJpYlBsYWluKG5hbWUsIHZhbHVlKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgY29uc3QgYXR0ciA9IHsgbmFtZSwgdmFsdWUgfTtcbiAgICAgICAgdGhpcy5hdHRyaWJMaXN0LnB1c2goYXR0cik7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtZXhwcmVzc2lvbnNcbiAgICAgICAgKF9hID0gdGhpcy5hdHRyaWJ1dGVIYW5kbGVyKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EuY2FsbCh0aGlzLCBhdHRyKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRW5kIHBhcnNpbmcuIFRoaXMgcGVyZm9ybXMgZmluYWwgd2VsbC1mb3JtZWRuZXNzIGNoZWNrcyBhbmQgcmVzZXRzIHRoZVxuICAgICAqIHBhcnNlciB0byBhIGNsZWFuIHN0YXRlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgdGhpc1xuICAgICAqL1xuICAgIGVuZCgpIHtcbiAgICAgICAgdmFyIF9hLCBfYjtcbiAgICAgICAgaWYgKCF0aGlzLnNhd1Jvb3QpIHtcbiAgICAgICAgICAgIHRoaXMuZmFpbChcImRvY3VtZW50IG11c3QgY29udGFpbiBhIHJvb3QgZWxlbWVudC5cIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyB0YWdzIH0gPSB0aGlzO1xuICAgICAgICB3aGlsZSAodGFncy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zdCB0YWcgPSB0YWdzLnBvcCgpO1xuICAgICAgICAgICAgdGhpcy5mYWlsKGB1bmNsb3NlZCB0YWc6ICR7dGFnLm5hbWV9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCh0aGlzLnN0YXRlICE9PSBTX0JFR0lOKSAmJiAodGhpcy5zdGF0ZSAhPT0gU19URVhUKSkge1xuICAgICAgICAgICAgdGhpcy5mYWlsKFwidW5leHBlY3RlZCBlbmQuXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgdGV4dCB9ID0gdGhpcztcbiAgICAgICAgaWYgKHRleHQubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zXG4gICAgICAgICAgICAoX2EgPSB0aGlzLnRleHRIYW5kbGVyKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EuY2FsbCh0aGlzLCB0ZXh0KTtcbiAgICAgICAgICAgIHRoaXMudGV4dCA9IFwiXCI7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fY2xvc2VkID0gdHJ1ZTtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC1leHByZXNzaW9uc1xuICAgICAgICAoX2IgPSB0aGlzLmVuZEhhbmRsZXIpID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi5jYWxsKHRoaXMpO1xuICAgICAgICB0aGlzLl9pbml0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXNvbHZlIGEgbmFtZXNwYWNlIHByZWZpeC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBwcmVmaXggVGhlIHByZWZpeCB0byByZXNvbHZlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIG5hbWVzcGFjZSBVUkkgb3IgYGB1bmRlZmluZWRgYCBpZiB0aGUgcHJlZml4IGlzIG5vdCBkZWZpbmVkLlxuICAgICAqL1xuICAgIHJlc29sdmUocHJlZml4KSB7XG4gICAgICAgIHZhciBfYSwgX2I7XG4gICAgICAgIGxldCB1cmkgPSB0aGlzLnRvcE5TW3ByZWZpeF07XG4gICAgICAgIGlmICh1cmkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHVyaTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IHRhZ3MgfSA9IHRoaXM7XG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gdGFncy5sZW5ndGggLSAxOyBpbmRleCA+PSAwOyBpbmRleC0tKSB7XG4gICAgICAgICAgICB1cmkgPSB0YWdzW2luZGV4XS5uc1twcmVmaXhdO1xuICAgICAgICAgICAgaWYgKHVyaSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVyaTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB1cmkgPSB0aGlzLm5zW3ByZWZpeF07XG4gICAgICAgIGlmICh1cmkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHVyaTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKF9iID0gKF9hID0gdGhpcy5vcHQpLnJlc29sdmVQcmVmaXgpID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi5jYWxsKF9hLCBwcmVmaXgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQYXJzZSBhIHFuYW1lIGludG8gaXRzIHByZWZpeCBhbmQgbG9jYWwgbmFtZSBwYXJ0cy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIHRvIHBhcnNlXG4gICAgICpcbiAgICAgKiBAcmV0dXJuc1xuICAgICAqL1xuICAgIHFuYW1lKG5hbWUpIHtcbiAgICAgICAgLy8gVGhpcyBpcyBmYXN0ZXIgdGhhbiB1c2luZyBuYW1lLnNwbGl0KFwiOlwiKS5cbiAgICAgICAgY29uc3QgY29sb24gPSBuYW1lLmluZGV4T2YoXCI6XCIpO1xuICAgICAgICBpZiAoY29sb24gPT09IC0xKSB7XG4gICAgICAgICAgICByZXR1cm4geyBwcmVmaXg6IFwiXCIsIGxvY2FsOiBuYW1lIH07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbG9jYWwgPSBuYW1lLnNsaWNlKGNvbG9uICsgMSk7XG4gICAgICAgIGNvbnN0IHByZWZpeCA9IG5hbWUuc2xpY2UoMCwgY29sb24pO1xuICAgICAgICBpZiAocHJlZml4ID09PSBcIlwiIHx8IGxvY2FsID09PSBcIlwiIHx8IGxvY2FsLmluY2x1ZGVzKFwiOlwiKSkge1xuICAgICAgICAgICAgdGhpcy5mYWlsKGBtYWxmb3JtZWQgbmFtZTogJHtuYW1lfS5gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBwcmVmaXgsIGxvY2FsIH07XG4gICAgfVxuICAgIHByb2Nlc3NBdHRyaWJzTlMoKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgY29uc3QgeyBhdHRyaWJMaXN0IH0gPSB0aGlzO1xuICAgICAgICBjb25zdCB0YWcgPSB0aGlzLnRhZztcbiAgICAgICAge1xuICAgICAgICAgICAgLy8gYWRkIG5hbWVzcGFjZSBpbmZvIHRvIHRhZ1xuICAgICAgICAgICAgY29uc3QgeyBwcmVmaXgsIGxvY2FsIH0gPSB0aGlzLnFuYW1lKHRhZy5uYW1lKTtcbiAgICAgICAgICAgIHRhZy5wcmVmaXggPSBwcmVmaXg7XG4gICAgICAgICAgICB0YWcubG9jYWwgPSBsb2NhbDtcbiAgICAgICAgICAgIGNvbnN0IHVyaSA9IHRhZy51cmkgPSAoX2EgPSB0aGlzLnJlc29sdmUocHJlZml4KSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogXCJcIjtcbiAgICAgICAgICAgIGlmIChwcmVmaXggIT09IFwiXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAocHJlZml4ID09PSBcInhtbG5zXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mYWlsKFwidGFncyBtYXkgbm90IGhhdmUgXFxcInhtbG5zXFxcIiBhcyBwcmVmaXguXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodXJpID09PSBcIlwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmFpbChgdW5ib3VuZCBuYW1lc3BhY2UgcHJlZml4OiAke0pTT04uc3RyaW5naWZ5KHByZWZpeCl9LmApO1xuICAgICAgICAgICAgICAgICAgICB0YWcudXJpID0gcHJlZml4O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoYXR0cmliTGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IGF0dHJpYnV0ZXMgfSA9IHRhZztcbiAgICAgICAgY29uc3Qgc2VlbiA9IG5ldyBTZXQoKTtcbiAgICAgICAgLy8gTm90ZTogZG8gbm90IGFwcGx5IGRlZmF1bHQgbnMgdG8gYXR0cmlidXRlczpcbiAgICAgICAgLy8gICBodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLW5hbWVzLyNkZWZhdWx0aW5nXG4gICAgICAgIGZvciAoY29uc3QgYXR0ciBvZiBhdHRyaWJMaXN0KSB7XG4gICAgICAgICAgICBjb25zdCB7IG5hbWUsIHByZWZpeCwgbG9jYWwgfSA9IGF0dHI7XG4gICAgICAgICAgICBsZXQgdXJpO1xuICAgICAgICAgICAgbGV0IGVxbmFtZTtcbiAgICAgICAgICAgIGlmIChwcmVmaXggPT09IFwiXCIpIHtcbiAgICAgICAgICAgICAgICB1cmkgPSBuYW1lID09PSBcInhtbG5zXCIgPyBYTUxOU19OQU1FU1BBQ0UgOiBcIlwiO1xuICAgICAgICAgICAgICAgIGVxbmFtZSA9IG5hbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB1cmkgPSB0aGlzLnJlc29sdmUocHJlZml4KTtcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGVyZSdzIGFueSBhdHRyaWJ1dGVzIHdpdGggYW4gdW5kZWZpbmVkIG5hbWVzcGFjZSxcbiAgICAgICAgICAgICAgICAvLyB0aGVuIGZhaWwgb24gdGhlbSBub3cuXG4gICAgICAgICAgICAgICAgaWYgKHVyaSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmFpbChgdW5ib3VuZCBuYW1lc3BhY2UgcHJlZml4OiAke0pTT04uc3RyaW5naWZ5KHByZWZpeCl9LmApO1xuICAgICAgICAgICAgICAgICAgICB1cmkgPSBwcmVmaXg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVxbmFtZSA9IGB7JHt1cml9fSR7bG9jYWx9YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzZWVuLmhhcyhlcW5hbWUpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mYWlsKGBkdXBsaWNhdGUgYXR0cmlidXRlOiAke2VxbmFtZX0uYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZWVuLmFkZChlcW5hbWUpO1xuICAgICAgICAgICAgYXR0ci51cmkgPSB1cmk7XG4gICAgICAgICAgICBhdHRyaWJ1dGVzW25hbWVdID0gYXR0cjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmF0dHJpYkxpc3QgPSBbXTtcbiAgICB9XG4gICAgcHJvY2Vzc0F0dHJpYnNQbGFpbigpIHtcbiAgICAgICAgY29uc3QgeyBhdHRyaWJMaXN0IH0gPSB0aGlzO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLWRlc3RydWN0dXJpbmdcbiAgICAgICAgY29uc3QgYXR0cmlidXRlcyA9IHRoaXMudGFnLmF0dHJpYnV0ZXM7XG4gICAgICAgIGZvciAoY29uc3QgeyBuYW1lLCB2YWx1ZSB9IG9mIGF0dHJpYkxpc3QpIHtcbiAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzW25hbWVdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZhaWwoYGR1cGxpY2F0ZSBhdHRyaWJ1dGU6ICR7bmFtZX0uYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhdHRyaWJ1dGVzW25hbWVdID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hdHRyaWJMaXN0ID0gW107XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEhhbmRsZSBhIGNvbXBsZXRlIG9wZW4gdGFnLiBUaGlzIHBhcnNlciBjb2RlIGNhbGxzIHRoaXMgb25jZSBpdCBoYXMgc2VlblxuICAgICAqIHRoZSB3aG9sZSB0YWcuIFRoaXMgbWV0aG9kIGNoZWNrcyBmb3Igd2VsbC1mb3JtZW5lc3MgYW5kIHRoZW4gZW1pdHNcbiAgICAgKiBgYG9ub3BlbnRhZ2BgLlxuICAgICAqL1xuICAgIG9wZW5UYWcoKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgdGhpcy5wcm9jZXNzQXR0cmlicygpO1xuICAgICAgICBjb25zdCB7IHRhZ3MgfSA9IHRoaXM7XG4gICAgICAgIGNvbnN0IHRhZyA9IHRoaXMudGFnO1xuICAgICAgICB0YWcuaXNTZWxmQ2xvc2luZyA9IGZhbHNlO1xuICAgICAgICAvLyBUaGVyZSBjYW5ub3QgYmUgYW55IHBlbmRpbmcgdGV4dCBoZXJlIGR1ZSB0byB0aGUgb25vcGVudGFnc3RhcnQgdGhhdCB3YXNcbiAgICAgICAgLy8gbmVjZXNzYXJpbHkgZW1pdHRlZCBiZWZvcmUgd2UgZ2V0IGhlcmUuIFNvIHdlIGRvIG5vdCBjaGVjayB0ZXh0LlxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zXG4gICAgICAgIChfYSA9IHRoaXMub3BlblRhZ0hhbmRsZXIpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5jYWxsKHRoaXMsIHRhZyk7XG4gICAgICAgIHRhZ3MucHVzaCh0YWcpO1xuICAgICAgICB0aGlzLnN0YXRlID0gU19URVhUO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBIYW5kbGUgYSBjb21wbGV0ZSBzZWxmLWNsb3NpbmcgdGFnLiBUaGlzIHBhcnNlciBjb2RlIGNhbGxzIHRoaXMgb25jZSBpdCBoYXNcbiAgICAgKiBzZWVuIHRoZSB3aG9sZSB0YWcuIFRoaXMgbWV0aG9kIGNoZWNrcyBmb3Igd2VsbC1mb3JtZW5lc3MgYW5kIHRoZW4gZW1pdHNcbiAgICAgKiBgYG9ub3BlbnRhZ2BgIGFuZCBgYG9uY2xvc2V0YWdgYC5cbiAgICAgKi9cbiAgICBvcGVuU2VsZkNsb3NpbmdUYWcoKSB7XG4gICAgICAgIHZhciBfYSwgX2IsIF9jO1xuICAgICAgICB0aGlzLnByb2Nlc3NBdHRyaWJzKCk7XG4gICAgICAgIGNvbnN0IHsgdGFncyB9ID0gdGhpcztcbiAgICAgICAgY29uc3QgdGFnID0gdGhpcy50YWc7XG4gICAgICAgIHRhZy5pc1NlbGZDbG9zaW5nID0gdHJ1ZTtcbiAgICAgICAgLy8gVGhlcmUgY2Fubm90IGJlIGFueSBwZW5kaW5nIHRleHQgaGVyZSBkdWUgdG8gdGhlIG9ub3BlbnRhZ3N0YXJ0IHRoYXQgd2FzXG4gICAgICAgIC8vIG5lY2Vzc2FyaWx5IGVtaXR0ZWQgYmVmb3JlIHdlIGdldCBoZXJlLiBTbyB3ZSBkbyBub3QgY2hlY2sgdGV4dC5cbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC1leHByZXNzaW9uc1xuICAgICAgICAoX2EgPSB0aGlzLm9wZW5UYWdIYW5kbGVyKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EuY2FsbCh0aGlzLCB0YWcpO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zXG4gICAgICAgIChfYiA9IHRoaXMuY2xvc2VUYWdIYW5kbGVyKSA9PT0gbnVsbCB8fCBfYiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2IuY2FsbCh0aGlzLCB0YWcpO1xuICAgICAgICBjb25zdCB0b3AgPSB0aGlzLnRhZyA9IChfYyA9IHRhZ3NbdGFncy5sZW5ndGggLSAxXSkgIT09IG51bGwgJiYgX2MgIT09IHZvaWQgMCA/IF9jIDogbnVsbDtcbiAgICAgICAgaWYgKHRvcCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5jbG9zZWRSb290ID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0YXRlID0gU19URVhUO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBIYW5kbGUgYSBjb21wbGV0ZSBjbG9zZSB0YWcuIFRoaXMgcGFyc2VyIGNvZGUgY2FsbHMgdGhpcyBvbmNlIGl0IGhhcyBzZWVuXG4gICAgICogdGhlIHdob2xlIHRhZy4gVGhpcyBtZXRob2QgY2hlY2tzIGZvciB3ZWxsLWZvcm1lbmVzcyBhbmQgdGhlbiBlbWl0c1xuICAgICAqIGBgb25jbG9zZXRhZ2BgLlxuICAgICAqL1xuICAgIGNsb3NlVGFnKCkge1xuICAgICAgICBjb25zdCB7IHRhZ3MsIG5hbWUgfSA9IHRoaXM7XG4gICAgICAgIC8vIE91ciBzdGF0ZSBhZnRlciB0aGlzIHdpbGwgYmUgU19URVhULCBubyBtYXR0ZXIgd2hhdCwgYW5kIHdlIGNhbiBjbGVhclxuICAgICAgICAvLyB0YWdOYW1lIG5vdy5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNfVEVYVDtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJcIjtcbiAgICAgICAgaWYgKG5hbWUgPT09IFwiXCIpIHtcbiAgICAgICAgICAgIHRoaXMuZmFpbChcIndlaXJkIGVtcHR5IGNsb3NlIHRhZy5cIik7XG4gICAgICAgICAgICB0aGlzLnRleHQgKz0gXCI8Lz5cIjtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBoYW5kbGVyID0gdGhpcy5jbG9zZVRhZ0hhbmRsZXI7XG4gICAgICAgIGxldCBsID0gdGFncy5sZW5ndGg7XG4gICAgICAgIHdoaWxlIChsLS0gPiAwKSB7XG4gICAgICAgICAgICBjb25zdCB0YWcgPSB0aGlzLnRhZyA9IHRhZ3MucG9wKCk7XG4gICAgICAgICAgICB0aGlzLnRvcE5TID0gdGFnLm5zO1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC1leHByZXNzaW9uc1xuICAgICAgICAgICAgaGFuZGxlciA9PT0gbnVsbCB8fCBoYW5kbGVyID09PSB2b2lkIDAgPyB2b2lkIDAgOiBoYW5kbGVyKHRhZyk7XG4gICAgICAgICAgICBpZiAodGFnLm5hbWUgPT09IG5hbWUpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZmFpbChcInVuZXhwZWN0ZWQgY2xvc2UgdGFnLlwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobCA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5jbG9zZWRSb290ID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChsIDwgMCkge1xuICAgICAgICAgICAgdGhpcy5mYWlsKGB1bm1hdGNoZWQgY2xvc2luZyB0YWc6ICR7bmFtZX0uYCk7XG4gICAgICAgICAgICB0aGlzLnRleHQgKz0gYDwvJHtuYW1lfT5gO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc29sdmVzIGFuIGVudGl0eS4gTWFrZXMgYW55IG5lY2Vzc2FyeSB3ZWxsLWZvcm1lZG5lc3MgY2hlY2tzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGVudGl0eSBUaGUgZW50aXR5IHRvIHJlc29sdmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBUaGUgcGFyc2VkIGVudGl0eS5cbiAgICAgKi9cbiAgICBwYXJzZUVudGl0eShlbnRpdHkpIHtcbiAgICAgICAgLy8gc3RhcnRzV2l0aCB3b3VsZCBiZSBzaWduaWZpY2FudGx5IHNsb3dlciBmb3IgdGhpcyB0ZXN0LlxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L3ByZWZlci1zdHJpbmctc3RhcnRzLWVuZHMtd2l0aFxuICAgICAgICBpZiAoZW50aXR5WzBdICE9PSBcIiNcIikge1xuICAgICAgICAgICAgY29uc3QgZGVmaW5lZCA9IHRoaXMuRU5USVRJRVNbZW50aXR5XTtcbiAgICAgICAgICAgIGlmIChkZWZpbmVkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZmFpbCh0aGlzLmlzTmFtZShlbnRpdHkpID8gXCJ1bmRlZmluZWQgZW50aXR5LlwiIDpcbiAgICAgICAgICAgICAgICBcImRpc2FsbG93ZWQgY2hhcmFjdGVyIGluIGVudGl0eSBuYW1lLlwiKTtcbiAgICAgICAgICAgIHJldHVybiBgJiR7ZW50aXR5fTtgO1xuICAgICAgICB9XG4gICAgICAgIGxldCBudW0gPSBOYU47XG4gICAgICAgIGlmIChlbnRpdHlbMV0gPT09IFwieFwiICYmIC9eI3hbMC05YS1mXSskL2kudGVzdChlbnRpdHkpKSB7XG4gICAgICAgICAgICBudW0gPSBwYXJzZUludChlbnRpdHkuc2xpY2UoMiksIDE2KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICgvXiNbMC05XSskLy50ZXN0KGVudGl0eSkpIHtcbiAgICAgICAgICAgIG51bSA9IHBhcnNlSW50KGVudGl0eS5zbGljZSgxKSwgMTApO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRoZSBjaGFyYWN0ZXIgcmVmZXJlbmNlIGlzIHJlcXVpcmVkIHRvIG1hdGNoIHRoZSBDSEFSIHByb2R1Y3Rpb24uXG4gICAgICAgIGlmICghdGhpcy5pc0NoYXIobnVtKSkge1xuICAgICAgICAgICAgdGhpcy5mYWlsKFwibWFsZm9ybWVkIGNoYXJhY3RlciBlbnRpdHkuXCIpO1xuICAgICAgICAgICAgcmV0dXJuIGAmJHtlbnRpdHl9O2A7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ29kZVBvaW50KG51bSk7XG4gICAgfVxufVxuZXhwb3J0cy5TYXhlc1BhcnNlciA9IFNheGVzUGFyc2VyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2F4ZXMuanMubWFwIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///(rsc)/./node_modules/saxes/saxes.js\n");
/***/ })
};
;