module.exports = /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = "./src/tasks/gitreleasemanager/create.ts"); /******/ }) /************************************************************************/ /******/ ({ /***/ "./node_modules/@actions/core/lib/command.js": /*!***************************************************!*\ !*** ./node_modules/@actions/core/lib/command.js ***! \***************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const os = __importStar(__webpack_require__(/*! os */ "os")); /** * Commands * * Command Format: * ::name key=value,key=value::message * * Examples: * ::warning::This is the message * ::set-env name=MY_VAR::some value */ function issueCommand(command, properties, message) { const cmd = new Command(command, properties, message); process.stdout.write(cmd.toString() + os.EOL); } exports.issueCommand = issueCommand; function issue(name, message = '') { issueCommand(name, {}, message); } exports.issue = issue; const CMD_STRING = '::'; class Command { constructor(command, properties, message) { if (!command) { command = 'missing.command'; } this.command = command; this.properties = properties; this.message = message; } toString() { let cmdStr = CMD_STRING + this.command; if (this.properties && Object.keys(this.properties).length > 0) { cmdStr += ' '; let first = true; for (const key in this.properties) { if (this.properties.hasOwnProperty(key)) { const val = this.properties[key]; if (val) { if (first) { first = false; } else { cmdStr += ','; } cmdStr += `${key}=${escapeProperty(val)}`; } } } } cmdStr += `${CMD_STRING}${escapeData(this.message)}`; return cmdStr; } } function escapeData(s) { return (s || '') .replace(/%/g, '%25') .replace(/\r/g, '%0D') .replace(/\n/g, '%0A'); } function escapeProperty(s) { return (s || '') .replace(/%/g, '%25') .replace(/\r/g, '%0D') .replace(/\n/g, '%0A') .replace(/:/g, '%3A') .replace(/,/g, '%2C'); } //# sourceMappingURL=command.js.map /***/ }), /***/ "./node_modules/@actions/core/lib/core.js": /*!************************************************!*\ !*** ./node_modules/@actions/core/lib/core.js ***! \************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const command_1 = __webpack_require__(/*! ./command */ "./node_modules/@actions/core/lib/command.js"); const os = __importStar(__webpack_require__(/*! os */ "os")); const path = __importStar(__webpack_require__(/*! path */ "path")); /** * The code to exit an action */ var ExitCode; (function (ExitCode) { /** * A code indicating that the action was successful */ ExitCode[ExitCode["Success"] = 0] = "Success"; /** * A code indicating that the action was a failure */ ExitCode[ExitCode["Failure"] = 1] = "Failure"; })(ExitCode = exports.ExitCode || (exports.ExitCode = {})); //----------------------------------------------------------------------- // Variables //----------------------------------------------------------------------- /** * Sets env variable for this action and future actions in the job * @param name the name of the variable to set * @param val the value of the variable */ function exportVariable(name, val) { process.env[name] = val; command_1.issueCommand('set-env', { name }, val); } exports.exportVariable = exportVariable; /** * Registers a secret which will get masked from logs * @param secret value of the secret */ function setSecret(secret) { command_1.issueCommand('add-mask', {}, secret); } exports.setSecret = setSecret; /** * Prepends inputPath to the PATH (for this action and future actions) * @param inputPath */ function addPath(inputPath) { command_1.issueCommand('add-path', {}, inputPath); process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; } exports.addPath = addPath; /** * Gets the value of an input. The value is also trimmed. * * @param name name of the input to get * @param options optional. See InputOptions. * @returns string */ function getInput(name, options) { const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; if (options && options.required && !val) { throw new Error(`Input required and not supplied: ${name}`); } return val.trim(); } exports.getInput = getInput; /** * Sets the value of an output. * * @param name name of the output to set * @param value value to store */ function setOutput(name, value) { command_1.issueCommand('set-output', { name }, value); } exports.setOutput = setOutput; //----------------------------------------------------------------------- // Results //----------------------------------------------------------------------- /** * Sets the action status to failed. * When the action exits it will be with an exit code of 1 * @param message add error issue message */ function setFailed(message) { process.exitCode = ExitCode.Failure; error(message); } exports.setFailed = setFailed; //----------------------------------------------------------------------- // Logging Commands //----------------------------------------------------------------------- /** * Writes debug message to user log * @param message debug message */ function debug(message) { command_1.issueCommand('debug', {}, message); } exports.debug = debug; /** * Adds an error issue * @param message error issue message */ function error(message) { command_1.issue('error', message); } exports.error = error; /** * Adds an warning issue * @param message warning issue message */ function warning(message) { command_1.issue('warning', message); } exports.warning = warning; /** * Writes info to log with console.log. * @param message info message */ function info(message) { process.stdout.write(message + os.EOL); } exports.info = info; /** * Begin an output group. * * Output until the next `groupEnd` will be foldable in this group * * @param name The name of the output group */ function startGroup(name) { command_1.issue('group', name); } exports.startGroup = startGroup; /** * End an output group. */ function endGroup() { command_1.issue('endgroup'); } exports.endGroup = endGroup; /** * Wrap an asynchronous function call in a group. * * Returns the same type as the function itself. * * @param name The name of the group * @param fn The function to wrap in the group */ function group(name, fn) { return __awaiter(this, void 0, void 0, function* () { startGroup(name); let result; try { result = yield fn(); } finally { endGroup(); } return result; }); } exports.group = group; //----------------------------------------------------------------------- // Wrapper action state //----------------------------------------------------------------------- /** * Saves state for current action, the state can only be retrieved by this action's post job execution. * * @param name name of the state to store * @param value value to store */ function saveState(name, value) { command_1.issueCommand('save-state', { name }, value); } exports.saveState = saveState; /** * Gets the value of an state set by this action's main execution. * * @param name name of the state to get * @returns string */ function getState(name) { return process.env[`STATE_${name}`] || ''; } exports.getState = getState; //# sourceMappingURL=core.js.map /***/ }), /***/ "./node_modules/@actions/exec/lib/exec.js": /*!************************************************!*\ !*** ./node_modules/@actions/exec/lib/exec.js ***! \************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const tr = __webpack_require__(/*! ./toolrunner */ "./node_modules/@actions/exec/lib/toolrunner.js"); /** * Exec a command. * Output will be streamed to the live console. * Returns promise with return code * * @param commandLine command to execute (can include additional args). Must be correctly escaped. * @param args optional arguments for tool. Escaping is handled by the lib. * @param options optional exec options. See ExecOptions * @returns Promise exit code */ function exec(commandLine, args, options) { return __awaiter(this, void 0, void 0, function* () { const commandArgs = tr.argStringToArray(commandLine); if (commandArgs.length === 0) { throw new Error(`Parameter 'commandLine' cannot be null or empty.`); } // Path to tool to execute should be first arg const toolPath = commandArgs[0]; args = commandArgs.slice(1).concat(args || []); const runner = new tr.ToolRunner(toolPath, args, options); return runner.exec(); }); } exports.exec = exec; //# sourceMappingURL=exec.js.map /***/ }), /***/ "./node_modules/@actions/exec/lib/toolrunner.js": /*!******************************************************!*\ !*** ./node_modules/@actions/exec/lib/toolrunner.js ***! \******************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const os = __webpack_require__(/*! os */ "os"); const events = __webpack_require__(/*! events */ "events"); const child = __webpack_require__(/*! child_process */ "child_process"); const path = __webpack_require__(/*! path */ "path"); const io = __webpack_require__(/*! @actions/io */ "./node_modules/@actions/io/lib/io.js"); const ioUtil = __webpack_require__(/*! @actions/io/lib/io-util */ "./node_modules/@actions/io/lib/io-util.js"); /* eslint-disable @typescript-eslint/unbound-method */ const IS_WINDOWS = process.platform === 'win32'; /* * Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way. */ class ToolRunner extends events.EventEmitter { constructor(toolPath, args, options) { super(); if (!toolPath) { throw new Error("Parameter 'toolPath' cannot be null or empty."); } this.toolPath = toolPath; this.args = args || []; this.options = options || {}; } _debug(message) { if (this.options.listeners && this.options.listeners.debug) { this.options.listeners.debug(message); } } _getCommandString(options, noPrefix) { const toolPath = this._getSpawnFileName(); const args = this._getSpawnArgs(options); let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool if (IS_WINDOWS) { // Windows + cmd file if (this._isCmdFile()) { cmd += toolPath; for (const a of args) { cmd += ` ${a}`; } } // Windows + verbatim else if (options.windowsVerbatimArguments) { cmd += `"${toolPath}"`; for (const a of args) { cmd += ` ${a}`; } } // Windows (regular) else { cmd += this._windowsQuoteCmdArg(toolPath); for (const a of args) { cmd += ` ${this._windowsQuoteCmdArg(a)}`; } } } else { // OSX/Linux - this can likely be improved with some form of quoting. // creating processes on Unix is fundamentally different than Windows. // on Unix, execvp() takes an arg array. cmd += toolPath; for (const a of args) { cmd += ` ${a}`; } } return cmd; } _processLineBuffer(data, strBuffer, onLine) { try { let s = strBuffer + data.toString(); let n = s.indexOf(os.EOL); while (n > -1) { const line = s.substring(0, n); onLine(line); // the rest of the string ... s = s.substring(n + os.EOL.length); n = s.indexOf(os.EOL); } strBuffer = s; } catch (err) { // streaming lines to console is best effort. Don't fail a build. this._debug(`error processing line. Failed with error ${err}`); } } _getSpawnFileName() { if (IS_WINDOWS) { if (this._isCmdFile()) { return process.env['COMSPEC'] || 'cmd.exe'; } } return this.toolPath; } _getSpawnArgs(options) { if (IS_WINDOWS) { if (this._isCmdFile()) { let argline = `/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`; for (const a of this.args) { argline += ' '; argline += options.windowsVerbatimArguments ? a : this._windowsQuoteCmdArg(a); } argline += '"'; return [argline]; } } return this.args; } _endsWith(str, end) { return str.endsWith(end); } _isCmdFile() { const upperToolPath = this.toolPath.toUpperCase(); return (this._endsWith(upperToolPath, '.CMD') || this._endsWith(upperToolPath, '.BAT')); } _windowsQuoteCmdArg(arg) { // for .exe, apply the normal quoting rules that libuv applies if (!this._isCmdFile()) { return this._uvQuoteCmdArg(arg); } // otherwise apply quoting rules specific to the cmd.exe command line parser. // the libuv rules are generic and are not designed specifically for cmd.exe // command line parser. // // for a detailed description of the cmd.exe command line parser, refer to // http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912 // need quotes for empty arg if (!arg) { return '""'; } // determine whether the arg needs to be quoted const cmdSpecialChars = [ ' ', '\t', '&', '(', ')', '[', ']', '{', '}', '^', '=', ';', '!', "'", '+', ',', '`', '~', '|', '<', '>', '"' ]; let needsQuotes = false; for (const char of arg) { if (cmdSpecialChars.some(x => x === char)) { needsQuotes = true; break; } } // short-circuit if quotes not needed if (!needsQuotes) { return arg; } // the following quoting rules are very similar to the rules that by libuv applies. // // 1) wrap the string in quotes // // 2) double-up quotes - i.e. " => "" // // this is different from the libuv quoting rules. libuv replaces " with \", which unfortunately // doesn't work well with a cmd.exe command line. // // note, replacing " with "" also works well if the arg is passed to a downstream .NET console app. // for example, the command line: // foo.exe "myarg:""my val""" // is parsed by a .NET console app into an arg array: // [ "myarg:\"my val\"" ] // which is the same end result when applying libuv quoting rules. although the actual // command line from libuv quoting rules would look like: // foo.exe "myarg:\"my val\"" // // 3) double-up slashes that precede a quote, // e.g. hello \world => "hello \world" // hello\"world => "hello\\""world" // hello\\"world => "hello\\\\""world" // hello world\ => "hello world\\" // // technically this is not required for a cmd.exe command line, or the batch argument parser. // the reasons for including this as a .cmd quoting rule are: // // a) this is optimized for the scenario where the argument is passed from the .cmd file to an // external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule. // // b) it's what we've been doing previously (by deferring to node default behavior) and we // haven't heard any complaints about that aspect. // // note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be // escaped when used on the command line directly - even though within a .cmd file % can be escaped // by using %%. // // the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts // the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing. // // one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would // often work, since it is unlikely that var^ would exist, and the ^ character is removed when the // variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args // to an external program. // // an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file. // % can be escaped within a .cmd file. let reverse = '"'; let quoteHit = true; for (let i = arg.length; i > 0; i--) { // walk the string in reverse reverse += arg[i - 1]; if (quoteHit && arg[i - 1] === '\\') { reverse += '\\'; // double the slash } else if (arg[i - 1] === '"') { quoteHit = true; reverse += '"'; // double the quote } else { quoteHit = false; } } reverse += '"'; return reverse .split('') .reverse() .join(''); } _uvQuoteCmdArg(arg) { // Tool runner wraps child_process.spawn() and needs to apply the same quoting as // Node in certain cases where the undocumented spawn option windowsVerbatimArguments // is used. // // Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV, // see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details), // pasting copyright notice from Node within this function: // // Copyright Joyent, Inc. and other Node contributors. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. if (!arg) { // Need double quotation for empty argument return '""'; } if (!arg.includes(' ') && !arg.includes('\t') && !arg.includes('"')) { // No quotation needed return arg; } if (!arg.includes('"') && !arg.includes('\\')) { // No embedded double quotes or backslashes, so I can just wrap // quote marks around the whole thing. return `"${arg}"`; } // Expected input/output: // input : hello"world // output: "hello\"world" // input : hello""world // output: "hello\"\"world" // input : hello\world // output: hello\world // input : hello\\world // output: hello\\world // input : hello\"world // output: "hello\\\"world" // input : hello\\"world // output: "hello\\\\\"world" // input : hello world\ // output: "hello world\\" - note the comment in libuv actually reads "hello world\" // but it appears the comment is wrong, it should be "hello world\\" let reverse = '"'; let quoteHit = true; for (let i = arg.length; i > 0; i--) { // walk the string in reverse reverse += arg[i - 1]; if (quoteHit && arg[i - 1] === '\\') { reverse += '\\'; } else if (arg[i - 1] === '"') { quoteHit = true; reverse += '\\'; } else { quoteHit = false; } } reverse += '"'; return reverse .split('') .reverse() .join(''); } _cloneExecOptions(options) { options = options || {}; const result = { cwd: options.cwd || process.cwd(), env: options.env || process.env, silent: options.silent || false, windowsVerbatimArguments: options.windowsVerbatimArguments || false, failOnStdErr: options.failOnStdErr || false, ignoreReturnCode: options.ignoreReturnCode || false, delay: options.delay || 10000 }; result.outStream = options.outStream || process.stdout; result.errStream = options.errStream || process.stderr; return result; } _getSpawnOptions(options, toolPath) { options = options || {}; const result = {}; result.cwd = options.cwd; result.env = options.env; result['windowsVerbatimArguments'] = options.windowsVerbatimArguments || this._isCmdFile(); if (options.windowsVerbatimArguments) { result.argv0 = `"${toolPath}"`; } return result; } /** * Exec a tool. * Output will be streamed to the live console. * Returns promise with return code * * @param tool path to tool to exec * @param options optional exec options. See ExecOptions * @returns number */ exec() { return __awaiter(this, void 0, void 0, function* () { // root the tool path if it is unrooted and contains relative pathing if (!ioUtil.isRooted(this.toolPath) && (this.toolPath.includes('/') || (IS_WINDOWS && this.toolPath.includes('\\')))) { // prefer options.cwd if it is specified, however options.cwd may also need to be rooted this.toolPath = path.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath); } // if the tool is only a file name, then resolve it from the PATH // otherwise verify it exists (add extension on Windows if necessary) this.toolPath = yield io.which(this.toolPath, true); return new Promise((resolve, reject) => { this._debug(`exec tool: ${this.toolPath}`); this._debug('arguments:'); for (const arg of this.args) { this._debug(` ${arg}`); } const optionsNonNull = this._cloneExecOptions(this.options); if (!optionsNonNull.silent && optionsNonNull.outStream) { optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL); } const state = new ExecState(optionsNonNull, this.toolPath); state.on('debug', (message) => { this._debug(message); }); const fileName = this._getSpawnFileName(); const cp = child.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName)); const stdbuffer = ''; if (cp.stdout) { cp.stdout.on('data', (data) => { if (this.options.listeners && this.options.listeners.stdout) { this.options.listeners.stdout(data); } if (!optionsNonNull.silent && optionsNonNull.outStream) { optionsNonNull.outStream.write(data); } this._processLineBuffer(data, stdbuffer, (line) => { if (this.options.listeners && this.options.listeners.stdline) { this.options.listeners.stdline(line); } }); }); } const errbuffer = ''; if (cp.stderr) { cp.stderr.on('data', (data) => { state.processStderr = true; if (this.options.listeners && this.options.listeners.stderr) { this.options.listeners.stderr(data); } if (!optionsNonNull.silent && optionsNonNull.errStream && optionsNonNull.outStream) { const s = optionsNonNull.failOnStdErr ? optionsNonNull.errStream : optionsNonNull.outStream; s.write(data); } this._processLineBuffer(data, errbuffer, (line) => { if (this.options.listeners && this.options.listeners.errline) { this.options.listeners.errline(line); } }); }); } cp.on('error', (err) => { state.processError = err.message; state.processExited = true; state.processClosed = true; state.CheckComplete(); }); cp.on('exit', (code) => { state.processExitCode = code; state.processExited = true; this._debug(`Exit code ${code} received from tool '${this.toolPath}'`); state.CheckComplete(); }); cp.on('close', (code) => { state.processExitCode = code; state.processExited = true; state.processClosed = true; this._debug(`STDIO streams have closed for tool '${this.toolPath}'`); state.CheckComplete(); }); state.on('done', (error, exitCode) => { if (stdbuffer.length > 0) { this.emit('stdline', stdbuffer); } if (errbuffer.length > 0) { this.emit('errline', errbuffer); } cp.removeAllListeners(); if (error) { reject(error); } else { resolve(exitCode); } }); }); }); } } exports.ToolRunner = ToolRunner; /** * Convert an arg string to an array of args. Handles escaping * * @param argString string of arguments * @returns string[] array of arguments */ function argStringToArray(argString) { const args = []; let inQuotes = false; let escaped = false; let arg = ''; function append(c) { // we only escape double quotes. if (escaped && c !== '"') { arg += '\\'; } arg += c; escaped = false; } for (let i = 0; i < argString.length; i++) { const c = argString.charAt(i); if (c === '"') { if (!escaped) { inQuotes = !inQuotes; } else { append(c); } continue; } if (c === '\\' && escaped) { append(c); continue; } if (c === '\\' && inQuotes) { escaped = true; continue; } if (c === ' ' && !inQuotes) { if (arg.length > 0) { args.push(arg); arg = ''; } continue; } append(c); } if (arg.length > 0) { args.push(arg.trim()); } return args; } exports.argStringToArray = argStringToArray; class ExecState extends events.EventEmitter { constructor(options, toolPath) { super(); this.processClosed = false; // tracks whether the process has exited and stdio is closed this.processError = ''; this.processExitCode = 0; this.processExited = false; // tracks whether the process has exited this.processStderr = false; // tracks whether stderr was written to this.delay = 10000; // 10 seconds this.done = false; this.timeout = null; if (!toolPath) { throw new Error('toolPath must not be empty'); } this.options = options; this.toolPath = toolPath; if (options.delay) { this.delay = options.delay; } } CheckComplete() { if (this.done) { return; } if (this.processClosed) { this._setResult(); } else if (this.processExited) { this.timeout = setTimeout(ExecState.HandleTimeout, this.delay, this); } } _debug(message) { this.emit('debug', message); } _setResult() { // determine whether there is an error let error; if (this.processExited) { if (this.processError) { error = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`); } else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) { error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`); } else if (this.processStderr && this.options.failOnStdErr) { error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`); } } // clear the timeout if (this.timeout) { clearTimeout(this.timeout); this.timeout = null; } this.done = true; this.emit('done', error, this.processExitCode); } static HandleTimeout(state) { if (state.done) { return; } if (!state.processClosed && state.processExited) { const message = `The STDIO streams did not close within ${state.delay / 1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`; state._debug(message); } state._setResult(); } } //# sourceMappingURL=toolrunner.js.map /***/ }), /***/ "./node_modules/@actions/http-client/index.js": /*!****************************************************!*\ !*** ./node_modules/@actions/http-client/index.js ***! \****************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const url = __webpack_require__(/*! url */ "url"); const http = __webpack_require__(/*! http */ "http"); const https = __webpack_require__(/*! https */ "https"); const pm = __webpack_require__(/*! ./proxy */ "./node_modules/@actions/http-client/proxy.js"); let tunnel; var HttpCodes; (function (HttpCodes) { HttpCodes[HttpCodes["OK"] = 200] = "OK"; HttpCodes[HttpCodes["MultipleChoices"] = 300] = "MultipleChoices"; HttpCodes[HttpCodes["MovedPermanently"] = 301] = "MovedPermanently"; HttpCodes[HttpCodes["ResourceMoved"] = 302] = "ResourceMoved"; HttpCodes[HttpCodes["SeeOther"] = 303] = "SeeOther"; HttpCodes[HttpCodes["NotModified"] = 304] = "NotModified"; HttpCodes[HttpCodes["UseProxy"] = 305] = "UseProxy"; HttpCodes[HttpCodes["SwitchProxy"] = 306] = "SwitchProxy"; HttpCodes[HttpCodes["TemporaryRedirect"] = 307] = "TemporaryRedirect"; HttpCodes[HttpCodes["PermanentRedirect"] = 308] = "PermanentRedirect"; HttpCodes[HttpCodes["BadRequest"] = 400] = "BadRequest"; HttpCodes[HttpCodes["Unauthorized"] = 401] = "Unauthorized"; HttpCodes[HttpCodes["PaymentRequired"] = 402] = "PaymentRequired"; HttpCodes[HttpCodes["Forbidden"] = 403] = "Forbidden"; HttpCodes[HttpCodes["NotFound"] = 404] = "NotFound"; HttpCodes[HttpCodes["MethodNotAllowed"] = 405] = "MethodNotAllowed"; HttpCodes[HttpCodes["NotAcceptable"] = 406] = "NotAcceptable"; HttpCodes[HttpCodes["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired"; HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout"; HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict"; HttpCodes[HttpCodes["Gone"] = 410] = "Gone"; HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError"; HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented"; HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway"; HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable"; HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout"; })(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {})); /** * Returns the proxy URL, depending upon the supplied url and proxy environment variables. * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com */ function getProxyUrl(serverUrl) { let proxyUrl = pm.getProxyUrl(url.parse(serverUrl)); return proxyUrl ? proxyUrl.href : ''; } exports.getProxyUrl = getProxyUrl; const HttpRedirectCodes = [HttpCodes.MovedPermanently, HttpCodes.ResourceMoved, HttpCodes.SeeOther, HttpCodes.TemporaryRedirect, HttpCodes.PermanentRedirect]; const HttpResponseRetryCodes = [HttpCodes.BadGateway, HttpCodes.ServiceUnavailable, HttpCodes.GatewayTimeout]; const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD']; const ExponentialBackoffCeiling = 10; const ExponentialBackoffTimeSlice = 5; class HttpClientResponse { constructor(message) { this.message = message; } readBody() { return new Promise(async (resolve, reject) => { let output = Buffer.alloc(0); this.message.on('data', (chunk) => { output = Buffer.concat([output, chunk]); }); this.message.on('end', () => { resolve(output.toString()); }); }); } } exports.HttpClientResponse = HttpClientResponse; function isHttps(requestUrl) { let parsedUrl = url.parse(requestUrl); return parsedUrl.protocol === 'https:'; } exports.isHttps = isHttps; class HttpClient { constructor(userAgent, handlers, requestOptions) { this._ignoreSslError = false; this._allowRedirects = true; this._allowRedirectDowngrade = false; this._maxRedirects = 50; this._allowRetries = false; this._maxRetries = 1; this._keepAlive = false; this._disposed = false; this.userAgent = userAgent; this.handlers = handlers || []; this.requestOptions = requestOptions; if (requestOptions) { if (requestOptions.ignoreSslError != null) { this._ignoreSslError = requestOptions.ignoreSslError; } this._socketTimeout = requestOptions.socketTimeout; if (requestOptions.allowRedirects != null) { this._allowRedirects = requestOptions.allowRedirects; } if (requestOptions.allowRedirectDowngrade != null) { this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade; } if (requestOptions.maxRedirects != null) { this._maxRedirects = Math.max(requestOptions.maxRedirects, 0); } if (requestOptions.keepAlive != null) { this._keepAlive = requestOptions.keepAlive; } if (requestOptions.allowRetries != null) { this._allowRetries = requestOptions.allowRetries; } if (requestOptions.maxRetries != null) { this._maxRetries = requestOptions.maxRetries; } } } options(requestUrl, additionalHeaders) { return this.request('OPTIONS', requestUrl, null, additionalHeaders || {}); } get(requestUrl, additionalHeaders) { return this.request('GET', requestUrl, null, additionalHeaders || {}); } del(requestUrl, additionalHeaders) { return this.request('DELETE', requestUrl, null, additionalHeaders || {}); } post(requestUrl, data, additionalHeaders) { return this.request('POST', requestUrl, data, additionalHeaders || {}); } patch(requestUrl, data, additionalHeaders) { return this.request('PATCH', requestUrl, data, additionalHeaders || {}); } put(requestUrl, data, additionalHeaders) { return this.request('PUT', requestUrl, data, additionalHeaders || {}); } head(requestUrl, additionalHeaders) { return this.request('HEAD', requestUrl, null, additionalHeaders || {}); } sendStream(verb, requestUrl, stream, additionalHeaders) { return this.request(verb, requestUrl, stream, additionalHeaders); } /** * Makes a raw http request. * All other methods such as get, post, patch, and request ultimately call this. * Prefer get, del, post and patch */ async request(verb, requestUrl, data, headers) { if (this._disposed) { throw new Error("Client has already been disposed."); } let parsedUrl = url.parse(requestUrl); let info = this._prepareRequest(verb, parsedUrl, headers); // Only perform retries on reads since writes may not be idempotent. let maxTries = (this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1) ? this._maxRetries + 1 : 1; let numTries = 0; let response; while (numTries < maxTries) { response = await this.requestRaw(info, data); // Check if it's an authentication challenge if (response && response.message && response.message.statusCode === HttpCodes.Unauthorized) { let authenticationHandler; for (let i = 0; i < this.handlers.length; i++) { if (this.handlers[i].canHandleAuthentication(response)) { authenticationHandler = this.handlers[i]; break; } } if (authenticationHandler) { return authenticationHandler.handleAuthentication(this, info, data); } else { // We have received an unauthorized response but have no handlers to handle it. // Let the response return to the caller. return response; } } let redirectsRemaining = this._maxRedirects; while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1 && this._allowRedirects && redirectsRemaining > 0) { const redirectUrl = response.message.headers["location"]; if (!redirectUrl) { // if there's no location to redirect to, we won't break; } let parsedRedirectUrl = url.parse(redirectUrl); if (parsedUrl.protocol == 'https:' && parsedUrl.protocol != parsedRedirectUrl.protocol && !this._allowRedirectDowngrade) { throw new Error("Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true."); } // we need to finish reading the response before reassigning response // which will leak the open socket. await response.readBody(); // let's make the request with the new redirectUrl info = this._prepareRequest(verb, parsedRedirectUrl, headers); response = await this.requestRaw(info, data); redirectsRemaining--; } if (HttpResponseRetryCodes.indexOf(response.message.statusCode) == -1) { // If not a retry code, return immediately instead of retrying return response; } numTries += 1; if (numTries < maxTries) { await response.readBody(); await this._performExponentialBackoff(numTries); } } return response; } /** * Needs to be called if keepAlive is set to true in request options. */ dispose() { if (this._agent) { this._agent.destroy(); } this._disposed = true; } /** * Raw request. * @param info * @param data */ requestRaw(info, data) { return new Promise((resolve, reject) => { let callbackForResult = function (err, res) { if (err) { reject(err); } resolve(res); }; this.requestRawWithCallback(info, data, callbackForResult); }); } /** * Raw request with callback. * @param info * @param data * @param onResult */ requestRawWithCallback(info, data, onResult) { let socket; if (typeof (data) === 'string') { info.options.headers["Content-Length"] = Buffer.byteLength(data, 'utf8'); } let callbackCalled = false; let handleResult = (err, res) => { if (!callbackCalled) { callbackCalled = true; onResult(err, res); } }; let req = info.httpModule.request(info.options, (msg) => { let res = new HttpClientResponse(msg); handleResult(null, res); }); req.on('socket', (sock) => { socket = sock; }); // If we ever get disconnected, we want the socket to timeout eventually req.setTimeout(this._socketTimeout || 3 * 60000, () => { if (socket) { socket.end(); } handleResult(new Error('Request timeout: ' + info.options.path), null); }); req.on('error', function (err) { // err has statusCode property // res should have headers handleResult(err, null); }); if (data && typeof (data) === 'string') { req.write(data, 'utf8'); } if (data && typeof (data) !== 'string') { data.on('close', function () { req.end(); }); data.pipe(req); } else { req.end(); } } /** * Gets an http agent. This function is useful when you need an http agent that handles * routing through a proxy server - depending upon the url and proxy environment variables. * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com */ getAgent(serverUrl) { let parsedUrl = url.parse(serverUrl); return this._getAgent(parsedUrl); } _prepareRequest(method, requestUrl, headers) { const info = {}; info.parsedUrl = requestUrl; const usingSsl = info.parsedUrl.protocol === 'https:'; info.httpModule = usingSsl ? https : http; const defaultPort = usingSsl ? 443 : 80; info.options = {}; info.options.host = info.parsedUrl.hostname; info.options.port = info.parsedUrl.port ? parseInt(info.parsedUrl.port) : defaultPort; info.options.path = (info.parsedUrl.pathname || '') + (info.parsedUrl.search || ''); info.options.method = method; info.options.headers = this._mergeHeaders(headers); if (this.userAgent != null) { info.options.headers["user-agent"] = this.userAgent; } info.options.agent = this._getAgent(info.parsedUrl); // gives handlers an opportunity to participate if (this.handlers) { this.handlers.forEach((handler) => { handler.prepareRequest(info.options); }); } return info; } _mergeHeaders(headers) { const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => (c[k.toLowerCase()] = obj[k], c), {}); if (this.requestOptions && this.requestOptions.headers) { return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers)); } return lowercaseKeys(headers || {}); } _getAgent(parsedUrl) { let agent; let proxyUrl = pm.getProxyUrl(parsedUrl); let useProxy = proxyUrl && proxyUrl.hostname; if (this._keepAlive && useProxy) { agent = this._proxyAgent; } if (this._keepAlive && !useProxy) { agent = this._agent; } // if agent is already assigned use that agent. if (!!agent) { return agent; } const usingSsl = parsedUrl.protocol === 'https:'; let maxSockets = 100; if (!!this.requestOptions) { maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets; } if (useProxy) { // If using proxy, need tunnel if (!tunnel) { tunnel = __webpack_require__(/*! tunnel */ "./node_modules/@actions/http-client/node_modules/tunnel/index.js"); } const agentOptions = { maxSockets: maxSockets, keepAlive: this._keepAlive, proxy: { proxyAuth: proxyUrl.auth, host: proxyUrl.hostname, port: proxyUrl.port }, }; let tunnelAgent; const overHttps = proxyUrl.protocol === 'https:'; if (usingSsl) { tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp; } else { tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp; } agent = tunnelAgent(agentOptions); this._proxyAgent = agent; } // if reusing agent across request and tunneling agent isn't assigned create a new agent if (this._keepAlive && !agent) { const options = { keepAlive: this._keepAlive, maxSockets: maxSockets }; agent = usingSsl ? new https.Agent(options) : new http.Agent(options); this._agent = agent; } // if not using private agent and tunnel agent isn't setup then use global agent if (!agent) { agent = usingSsl ? https.globalAgent : http.globalAgent; } if (usingSsl && this._ignoreSslError) { // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options // we have to cast it to any and change it directly agent.options = Object.assign(agent.options || {}, { rejectUnauthorized: false }); } return agent; } _performExponentialBackoff(retryNumber) { retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); return new Promise(resolve => setTimeout(() => resolve(), ms)); } } exports.HttpClient = HttpClient; /***/ }), /***/ "./node_modules/@actions/http-client/node_modules/tunnel/index.js": /*!************************************************************************!*\ !*** ./node_modules/@actions/http-client/node_modules/tunnel/index.js ***! \************************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = __webpack_require__(/*! ./lib/tunnel */ "./node_modules/@actions/http-client/node_modules/tunnel/lib/tunnel.js"); /***/ }), /***/ "./node_modules/@actions/http-client/node_modules/tunnel/lib/tunnel.js": /*!*****************************************************************************!*\ !*** ./node_modules/@actions/http-client/node_modules/tunnel/lib/tunnel.js ***! \*****************************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var net = __webpack_require__(/*! net */ "net"); var tls = __webpack_require__(/*! tls */ "tls"); var http = __webpack_require__(/*! http */ "http"); var https = __webpack_require__(/*! https */ "https"); var events = __webpack_require__(/*! events */ "events"); var assert = __webpack_require__(/*! assert */ "assert"); var util = __webpack_require__(/*! util */ "util"); exports.httpOverHttp = httpOverHttp; exports.httpsOverHttp = httpsOverHttp; exports.httpOverHttps = httpOverHttps; exports.httpsOverHttps = httpsOverHttps; function httpOverHttp(options) { var agent = new TunnelingAgent(options); agent.request = http.request; return agent; } function httpsOverHttp(options) { var agent = new TunnelingAgent(options); agent.request = http.request; agent.createSocket = createSecureSocket; agent.defaultPort = 443; return agent; } function httpOverHttps(options) { var agent = new TunnelingAgent(options); agent.request = https.request; return agent; } function httpsOverHttps(options) { var agent = new TunnelingAgent(options); agent.request = https.request; agent.createSocket = createSecureSocket; agent.defaultPort = 443; return agent; } function TunnelingAgent(options) { var self = this; self.options = options || {}; self.proxyOptions = self.options.proxy || {}; self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; self.requests = []; self.sockets = []; self.on('free', function onFree(socket, host, port, localAddress) { var options = toOptions(host, port, localAddress); for (var i = 0, len = self.requests.length; i < len; ++i) { var pending = self.requests[i]; if (pending.host === options.host && pending.port === options.port) { // Detect the request to connect same origin server, // reuse the connection. self.requests.splice(i, 1); pending.request.onSocket(socket); return; } } socket.destroy(); self.removeSocket(socket); }); } util.inherits(TunnelingAgent, events.EventEmitter); TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { var self = this; var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); if (self.sockets.length >= this.maxSockets) { // We are over limit so we'll add it to the queue. self.requests.push(options); return; } // If we are under maxSockets create a new one. self.createSocket(options, function(socket) { socket.on('free', onFree); socket.on('close', onCloseOrRemove); socket.on('agentRemove', onCloseOrRemove); req.onSocket(socket); function onFree() { self.emit('free', socket, options); } function onCloseOrRemove(err) { self.removeSocket(socket); socket.removeListener('free', onFree); socket.removeListener('close', onCloseOrRemove); socket.removeListener('agentRemove', onCloseOrRemove); } }); }; TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { var self = this; var placeholder = {}; self.sockets.push(placeholder); var connectOptions = mergeOptions({}, self.proxyOptions, { method: 'CONNECT', path: options.host + ':' + options.port, agent: false, headers: { host: options.host + ':' + options.port } }); if (options.localAddress) { connectOptions.localAddress = options.localAddress; } if (connectOptions.proxyAuth) { connectOptions.headers = connectOptions.headers || {}; connectOptions.headers['Proxy-Authorization'] = 'Basic ' + new Buffer(connectOptions.proxyAuth).toString('base64'); } debug('making CONNECT request'); var connectReq = self.request(connectOptions); connectReq.useChunkedEncodingByDefault = false; // for v0.6 connectReq.once('response', onResponse); // for v0.6 connectReq.once('upgrade', onUpgrade); // for v0.6 connectReq.once('connect', onConnect); // for v0.7 or later connectReq.once('error', onError); connectReq.end(); function onResponse(res) { // Very hacky. This is necessary to avoid http-parser leaks. res.upgrade = true; } function onUpgrade(res, socket, head) { // Hacky. process.nextTick(function() { onConnect(res, socket, head); }); } function onConnect(res, socket, head) { connectReq.removeAllListeners(); socket.removeAllListeners(); if (res.statusCode !== 200) { debug('tunneling socket could not be established, statusCode=%d', res.statusCode); socket.destroy(); var error = new Error('tunneling socket could not be established, ' + 'statusCode=' + res.statusCode); error.code = 'ECONNRESET'; options.request.emit('error', error); self.removeSocket(placeholder); return; } if (head.length > 0) { debug('got illegal response body from proxy'); socket.destroy(); var error = new Error('got illegal response body from proxy'); error.code = 'ECONNRESET'; options.request.emit('error', error); self.removeSocket(placeholder); return; } debug('tunneling connection has established'); self.sockets[self.sockets.indexOf(placeholder)] = socket; return cb(socket); } function onError(cause) { connectReq.removeAllListeners(); debug('tunneling socket could not be established, cause=%s\n', cause.message, cause.stack); var error = new Error('tunneling socket could not be established, ' + 'cause=' + cause.message); error.code = 'ECONNRESET'; options.request.emit('error', error); self.removeSocket(placeholder); } }; TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { var pos = this.sockets.indexOf(socket) if (pos === -1) { return; } this.sockets.splice(pos, 1); var pending = this.requests.shift(); if (pending) { // If we have pending requests and a socket gets closed a new one // needs to be created to take over in the pool for the one that closed. this.createSocket(pending, function(socket) { pending.request.onSocket(socket); }); } }; function createSecureSocket(options, cb) { var self = this; TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { var hostHeader = options.request.getHeader('host'); var tlsOptions = mergeOptions({}, self.options, { socket: socket, servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host }); // 0 is dummy port for v0.6 var secureSocket = tls.connect(0, tlsOptions); self.sockets[self.sockets.indexOf(socket)] = secureSocket; cb(secureSocket); }); } function toOptions(host, port, localAddress) { if (typeof host === 'string') { // since v0.10 return { host: host, port: port, localAddress: localAddress }; } return host; // for v0.11 or later } function mergeOptions(target) { for (var i = 1, len = arguments.length; i < len; ++i) { var overrides = arguments[i]; if (typeof overrides === 'object') { var keys = Object.keys(overrides); for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { var k = keys[j]; if (overrides[k] !== undefined) { target[k] = overrides[k]; } } } } return target; } var debug; if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { debug = function() { var args = Array.prototype.slice.call(arguments); if (typeof args[0] === 'string') { args[0] = 'TUNNEL: ' + args[0]; } else { args.unshift('TUNNEL:'); } console.error.apply(console, args); } } else { debug = function() {}; } exports.debug = debug; // for test /***/ }), /***/ "./node_modules/@actions/http-client/proxy.js": /*!****************************************************!*\ !*** ./node_modules/@actions/http-client/proxy.js ***! \****************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const url = __webpack_require__(/*! url */ "url"); function getProxyUrl(reqUrl) { let usingSsl = reqUrl.protocol === 'https:'; let proxyUrl; if (checkBypass(reqUrl)) { return proxyUrl; } let proxyVar; if (usingSsl) { proxyVar = process.env["https_proxy"] || process.env["HTTPS_PROXY"]; } else { proxyVar = process.env["http_proxy"] || process.env["HTTP_PROXY"]; } if (proxyVar) { proxyUrl = url.parse(proxyVar); } return proxyUrl; } exports.getProxyUrl = getProxyUrl; function checkBypass(reqUrl) { if (!reqUrl.hostname) { return false; } let noProxy = process.env["no_proxy"] || process.env["NO_PROXY"] || ''; if (!noProxy) { return false; } // Determine the request port let reqPort; if (reqUrl.port) { reqPort = Number(reqUrl.port); } else if (reqUrl.protocol === 'http:') { reqPort = 80; } else if (reqUrl.protocol === 'https:') { reqPort = 443; } // Format the request hostname and hostname with port let upperReqHosts = [reqUrl.hostname.toUpperCase()]; if (typeof reqPort === 'number') { upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`); } // Compare request host against noproxy for (let upperNoProxyItem of noProxy.split(',').map(x => x.trim().toUpperCase()).filter(x => x)) { if (upperReqHosts.some(x => x === upperNoProxyItem)) { return true; } } return false; } exports.checkBypass = checkBypass; /***/ }), /***/ "./node_modules/@actions/io/lib/io-util.js": /*!*************************************************!*\ !*** ./node_modules/@actions/io/lib/io-util.js ***! \*************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var _a; Object.defineProperty(exports, "__esModule", { value: true }); const assert_1 = __webpack_require__(/*! assert */ "assert"); const fs = __webpack_require__(/*! fs */ "fs"); const path = __webpack_require__(/*! path */ "path"); _a = fs.promises, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink; exports.IS_WINDOWS = process.platform === 'win32'; function exists(fsPath) { return __awaiter(this, void 0, void 0, function* () { try { yield exports.stat(fsPath); } catch (err) { if (err.code === 'ENOENT') { return false; } throw err; } return true; }); } exports.exists = exists; function isDirectory(fsPath, useStat = false) { return __awaiter(this, void 0, void 0, function* () { const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath); return stats.isDirectory(); }); } exports.isDirectory = isDirectory; /** * On OSX/Linux, true if path starts with '/'. On Windows, true for paths like: * \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases). */ function isRooted(p) { p = normalizeSeparators(p); if (!p) { throw new Error('isRooted() parameter "p" cannot be empty'); } if (exports.IS_WINDOWS) { return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello ); // e.g. C: or C:\hello } return p.startsWith('/'); } exports.isRooted = isRooted; /** * Recursively create a directory at `fsPath`. * * This implementation is optimistic, meaning it attempts to create the full * path first, and backs up the path stack from there. * * @param fsPath The path to create * @param maxDepth The maximum recursion depth * @param depth The current recursion depth */ function mkdirP(fsPath, maxDepth = 1000, depth = 1) { return __awaiter(this, void 0, void 0, function* () { assert_1.ok(fsPath, 'a path argument must be provided'); fsPath = path.resolve(fsPath); if (depth >= maxDepth) return exports.mkdir(fsPath); try { yield exports.mkdir(fsPath); return; } catch (err) { switch (err.code) { case 'ENOENT': { yield mkdirP(path.dirname(fsPath), maxDepth, depth + 1); yield exports.mkdir(fsPath); return; } default: { let stats; try { stats = yield exports.stat(fsPath); } catch (err2) { throw err; } if (!stats.isDirectory()) throw err; } } } }); } exports.mkdirP = mkdirP; /** * Best effort attempt to determine whether a file exists and is executable. * @param filePath file path to check * @param extensions additional file extensions to try * @return if file exists and is executable, returns the file path. otherwise empty string. */ function tryGetExecutablePath(filePath, extensions) { return __awaiter(this, void 0, void 0, function* () { let stats = undefined; try { // test file exists stats = yield exports.stat(filePath); } catch (err) { if (err.code !== 'ENOENT') { // eslint-disable-next-line no-console console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`); } } if (stats && stats.isFile()) { if (exports.IS_WINDOWS) { // on Windows, test for valid extension const upperExt = path.extname(filePath).toUpperCase(); if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) { return filePath; } } else { if (isUnixExecutable(stats)) { return filePath; } } } // try each extension const originalFilePath = filePath; for (const extension of extensions) { filePath = originalFilePath + extension; stats = undefined; try { stats = yield exports.stat(filePath); } catch (err) { if (err.code !== 'ENOENT') { // eslint-disable-next-line no-console console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`); } } if (stats && stats.isFile()) { if (exports.IS_WINDOWS) { // preserve the case of the actual file (since an extension was appended) try { const directory = path.dirname(filePath); const upperName = path.basename(filePath).toUpperCase(); for (const actualName of yield exports.readdir(directory)) { if (upperName === actualName.toUpperCase()) { filePath = path.join(directory, actualName); break; } } } catch (err) { // eslint-disable-next-line no-console console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`); } return filePath; } else { if (isUnixExecutable(stats)) { return filePath; } } } } return ''; }); } exports.tryGetExecutablePath = tryGetExecutablePath; function normalizeSeparators(p) { p = p || ''; if (exports.IS_WINDOWS) { // convert slashes on Windows p = p.replace(/\//g, '\\'); // remove redundant slashes return p.replace(/\\\\+/g, '\\'); } // remove redundant slashes return p.replace(/\/\/+/g, '/'); } // on Mac/Linux, test the execute bit // R W X R W X R W X // 256 128 64 32 16 8 4 2 1 function isUnixExecutable(stats) { return ((stats.mode & 1) > 0 || ((stats.mode & 8) > 0 && stats.gid === process.getgid()) || ((stats.mode & 64) > 0 && stats.uid === process.getuid())); } //# sourceMappingURL=io-util.js.map /***/ }), /***/ "./node_modules/@actions/io/lib/io.js": /*!********************************************!*\ !*** ./node_modules/@actions/io/lib/io.js ***! \********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const childProcess = __webpack_require__(/*! child_process */ "child_process"); const path = __webpack_require__(/*! path */ "path"); const util_1 = __webpack_require__(/*! util */ "util"); const ioUtil = __webpack_require__(/*! ./io-util */ "./node_modules/@actions/io/lib/io-util.js"); const exec = util_1.promisify(childProcess.exec); /** * Copies a file or folder. * Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js * * @param source source path * @param dest destination path * @param options optional. See CopyOptions. */ function cp(source, dest, options = {}) { return __awaiter(this, void 0, void 0, function* () { const { force, recursive } = readCopyOptions(options); const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null; // Dest is an existing file, but not forcing if (destStat && destStat.isFile() && !force) { return; } // If dest is an existing directory, should copy inside. const newDest = destStat && destStat.isDirectory() ? path.join(dest, path.basename(source)) : dest; if (!(yield ioUtil.exists(source))) { throw new Error(`no such file or directory: ${source}`); } const sourceStat = yield ioUtil.stat(source); if (sourceStat.isDirectory()) { if (!recursive) { throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`); } else { yield cpDirRecursive(source, newDest, 0, force); } } else { if (path.relative(source, newDest) === '') { // a file cannot be copied to itself throw new Error(`'${newDest}' and '${source}' are the same file`); } yield copyFile(source, newDest, force); } }); } exports.cp = cp; /** * Moves a path. * * @param source source path * @param dest destination path * @param options optional. See MoveOptions. */ function mv(source, dest, options = {}) { return __awaiter(this, void 0, void 0, function* () { if (yield ioUtil.exists(dest)) { let destExists = true; if (yield ioUtil.isDirectory(dest)) { // If dest is directory copy src into dest dest = path.join(dest, path.basename(source)); destExists = yield ioUtil.exists(dest); } if (destExists) { if (options.force == null || options.force) { yield rmRF(dest); } else { throw new Error('Destination already exists'); } } } yield mkdirP(path.dirname(dest)); yield ioUtil.rename(source, dest); }); } exports.mv = mv; /** * Remove a path recursively with force * * @param inputPath path to remove */ function rmRF(inputPath) { return __awaiter(this, void 0, void 0, function* () { if (ioUtil.IS_WINDOWS) { // Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another // program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del. try { if (yield ioUtil.isDirectory(inputPath, true)) { yield exec(`rd /s /q "${inputPath}"`); } else { yield exec(`del /f /a "${inputPath}"`); } } catch (err) { // if you try to delete a file that doesn't exist, desired result is achieved // other errors are valid if (err.code !== 'ENOENT') throw err; } // Shelling out fails to remove a symlink folder with missing source, this unlink catches that try { yield ioUtil.unlink(inputPath); } catch (err) { // if you try to delete a file that doesn't exist, desired result is achieved // other errors are valid if (err.code !== 'ENOENT') throw err; } } else { let isDir = false; try { isDir = yield ioUtil.isDirectory(inputPath); } catch (err) { // if you try to delete a file that doesn't exist, desired result is achieved // other errors are valid if (err.code !== 'ENOENT') throw err; return; } if (isDir) { yield exec(`rm -rf "${inputPath}"`); } else { yield ioUtil.unlink(inputPath); } } }); } exports.rmRF = rmRF; /** * Make a directory. Creates the full path with folders in between * Will throw if it fails * * @param fsPath path to create * @returns Promise */ function mkdirP(fsPath) { return __awaiter(this, void 0, void 0, function* () { yield ioUtil.mkdirP(fsPath); }); } exports.mkdirP = mkdirP; /** * Returns path of a tool had the tool actually been invoked. Resolves via paths. * If you check and the tool does not exist, it will throw. * * @param tool name of the tool * @param check whether to check if tool exists * @returns Promise path to tool */ function which(tool, check) { return __awaiter(this, void 0, void 0, function* () { if (!tool) { throw new Error("parameter 'tool' is required"); } // recursive when check=true if (check) { const result = yield which(tool, false); if (!result) { if (ioUtil.IS_WINDOWS) { throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`); } else { throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`); } } } try { // build the list of extensions to try const extensions = []; if (ioUtil.IS_WINDOWS && process.env.PATHEXT) { for (const extension of process.env.PATHEXT.split(path.delimiter)) { if (extension) { extensions.push(extension); } } } // if it's rooted, return it if exists. otherwise return empty. if (ioUtil.isRooted(tool)) { const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions); if (filePath) { return filePath; } return ''; } // if any path separators, return empty if (tool.includes('/') || (ioUtil.IS_WINDOWS && tool.includes('\\'))) { return ''; } // build the list of directories // // Note, technically "where" checks the current directory on Windows. From a toolkit perspective, // it feels like we should not do this. Checking the current directory seems like more of a use // case of a shell, and the which() function exposed by the toolkit should strive for consistency // across platforms. const directories = []; if (process.env.PATH) { for (const p of process.env.PATH.split(path.delimiter)) { if (p) { directories.push(p); } } } // return the first match for (const directory of directories) { const filePath = yield ioUtil.tryGetExecutablePath(directory + path.sep + tool, extensions); if (filePath) { return filePath; } } return ''; } catch (err) { throw new Error(`which failed with message ${err.message}`); } }); } exports.which = which; function readCopyOptions(options) { const force = options.force == null ? true : options.force; const recursive = Boolean(options.recursive); return { force, recursive }; } function cpDirRecursive(sourceDir, destDir, currentDepth, force) { return __awaiter(this, void 0, void 0, function* () { // Ensure there is not a run away recursive copy if (currentDepth >= 255) return; currentDepth++; yield mkdirP(destDir); const files = yield ioUtil.readdir(sourceDir); for (const fileName of files) { const srcFile = `${sourceDir}/${fileName}`; const destFile = `${destDir}/${fileName}`; const srcFileStat = yield ioUtil.lstat(srcFile); if (srcFileStat.isDirectory()) { // Recurse yield cpDirRecursive(srcFile, destFile, currentDepth, force); } else { yield copyFile(srcFile, destFile, force); } } // Change the mode for the newly created directory yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode); }); } // Buffered file copy function copyFile(srcFile, destFile, force) { return __awaiter(this, void 0, void 0, function* () { if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) { // unlink/re-link it try { yield ioUtil.lstat(destFile); yield ioUtil.unlink(destFile); } catch (e) { // Try to override file permission if (e.code === 'EPERM') { yield ioUtil.chmod(destFile, '0666'); yield ioUtil.unlink(destFile); } // other errors = it doesn't exist, no work to do } // Copy over symlink const symlinkFull = yield ioUtil.readlink(srcFile); yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null); } else if (!(yield ioUtil.exists(destFile)) || force) { yield ioUtil.copyFile(srcFile, destFile); } }); } //# sourceMappingURL=io.js.map /***/ }), /***/ "./node_modules/@actions/tool-cache/lib/tool-cache.js": /*!************************************************************!*\ !*** ./node_modules/@actions/tool-cache/lib/tool-cache.js ***! \************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(__dirname) { var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const core = __importStar(__webpack_require__(/*! @actions/core */ "./node_modules/@actions/core/lib/core.js")); const io = __importStar(__webpack_require__(/*! @actions/io */ "./node_modules/@actions/io/lib/io.js")); const fs = __importStar(__webpack_require__(/*! fs */ "fs")); const os = __importStar(__webpack_require__(/*! os */ "os")); const path = __importStar(__webpack_require__(/*! path */ "path")); const httpm = __importStar(__webpack_require__(/*! @actions/http-client */ "./node_modules/@actions/http-client/index.js")); const semver = __importStar(__webpack_require__(/*! semver */ "./node_modules/@actions/tool-cache/node_modules/semver/semver.js")); const v4_1 = __importDefault(__webpack_require__(/*! uuid/v4 */ "./node_modules/uuid/v4.js")); const exec_1 = __webpack_require__(/*! @actions/exec/lib/exec */ "./node_modules/@actions/exec/lib/exec.js"); const assert_1 = __webpack_require__(/*! assert */ "assert"); class HTTPError extends Error { constructor(httpStatusCode) { super(`Unexpected HTTP response: ${httpStatusCode}`); this.httpStatusCode = httpStatusCode; Object.setPrototypeOf(this, new.target.prototype); } } exports.HTTPError = HTTPError; const IS_WINDOWS = process.platform === 'win32'; const userAgent = 'actions/tool-cache'; // On load grab temp directory and cache directory and remove them from env (currently don't want to expose this) let tempDirectory = process.env['RUNNER_TEMP'] || ''; let cacheRoot = process.env['RUNNER_TOOL_CACHE'] || ''; // If directories not found, place them in common temp locations if (!tempDirectory || !cacheRoot) { let baseLocation; if (IS_WINDOWS) { // On windows use the USERPROFILE env variable baseLocation = process.env['USERPROFILE'] || 'C:\\'; } else { if (process.platform === 'darwin') { baseLocation = '/Users'; } else { baseLocation = '/home'; } } if (!tempDirectory) { tempDirectory = path.join(baseLocation, 'actions', 'temp'); } if (!cacheRoot) { cacheRoot = path.join(baseLocation, 'actions', 'cache'); } } /** * Download a tool from an url and stream it into a file * * @param url url of tool to download * @param dest path to download tool * @returns path to downloaded tool */ function downloadTool(url, dest) { return __awaiter(this, void 0, void 0, function* () { // Wrap in a promise so that we can resolve from within stream callbacks return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { try { const http = new httpm.HttpClient(userAgent, [], { allowRetries: true, maxRetries: 3 }); dest = dest || path.join(tempDirectory, v4_1.default()); yield io.mkdirP(path.dirname(dest)); core.debug(`Downloading ${url}`); core.debug(`Downloading ${dest}`); if (fs.existsSync(dest)) { throw new Error(`Destination file path ${dest} already exists`); } const response = yield http.get(url); if (response.message.statusCode !== 200) { const err = new HTTPError(response.message.statusCode); core.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); throw err; } const file = fs.createWriteStream(dest); file.on('open', () => __awaiter(this, void 0, void 0, function* () { try { const stream = response.message.pipe(file); stream.on('close', () => { core.debug('download complete'); resolve(dest); }); } catch (err) { core.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); reject(err); } })); file.on('error', err => { file.end(); reject(err); }); } catch (err) { reject(err); } })); }); } exports.downloadTool = downloadTool; /** * Extract a .7z file * * @param file path to the .7z file * @param dest destination directory. Optional. * @param _7zPath path to 7zr.exe. Optional, for long path support. Most .7z archives do not have this * problem. If your .7z archive contains very long paths, you can pass the path to 7zr.exe which will * gracefully handle long paths. By default 7zdec.exe is used because it is a very small program and is * bundled with the tool lib. However it does not support long paths. 7zr.exe is the reduced command line * interface, it is smaller than the full command line interface, and it does support long paths. At the * time of this writing, it is freely available from the LZMA SDK that is available on the 7zip website. * Be sure to check the current license agreement. If 7zr.exe is bundled with your action, then the path * to 7zr.exe can be pass to this function. * @returns path to the destination directory */ function extract7z(file, dest, _7zPath) { return __awaiter(this, void 0, void 0, function* () { assert_1.ok(IS_WINDOWS, 'extract7z() not supported on current OS'); assert_1.ok(file, 'parameter "file" is required'); dest = yield _createExtractFolder(dest); const originalCwd = process.cwd(); process.chdir(dest); if (_7zPath) { try { const args = [ 'x', '-bb1', '-bd', '-sccUTF-8', file ]; const options = { silent: true }; yield exec_1.exec(`"${_7zPath}"`, args, options); } finally { process.chdir(originalCwd); } } else { const escapedScript = path .join(__dirname, '..', 'scripts', 'Invoke-7zdec.ps1') .replace(/'/g, "''") .replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); const escapedTarget = dest.replace(/'/g, "''").replace(/"|\n|\r/g, ''); const command = `& '${escapedScript}' -Source '${escapedFile}' -Target '${escapedTarget}'`; const args = [ '-NoLogo', '-Sta', '-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Unrestricted', '-Command', command ]; const options = { silent: true }; try { const powershellPath = yield io.which('powershell', true); yield exec_1.exec(`"${powershellPath}"`, args, options); } finally { process.chdir(originalCwd); } } return dest; }); } exports.extract7z = extract7z; /** * Extract a compressed tar archive * * @param file path to the tar * @param dest destination directory. Optional. * @param flags flags for the tar command to use for extraction. Defaults to 'xz' (extracting gzipped tars). Optional. * @returns path to the destination directory */ function extractTar(file, dest, flags = 'xz') { return __awaiter(this, void 0, void 0, function* () { if (!file) { throw new Error("parameter 'file' is required"); } // Create dest dest = yield _createExtractFolder(dest); // Determine whether GNU tar let versionOutput = ''; yield exec_1.exec('tar --version', [], { ignoreReturnCode: true, listeners: { stdout: (data) => (versionOutput += data.toString()), stderr: (data) => (versionOutput += data.toString()) } }); const isGnuTar = versionOutput.toUpperCase().includes('GNU TAR'); // Initialize args const args = [flags]; let destArg = dest; let fileArg = file; if (IS_WINDOWS && isGnuTar) { args.push('--force-local'); destArg = dest.replace(/\\/g, '/'); // Technically only the dest needs to have `/` but for aesthetic consistency // convert slashes in the file arg too. fileArg = file.replace(/\\/g, '/'); } if (isGnuTar) { // Suppress warnings when using GNU tar to extract archives created by BSD tar args.push('--warning=no-unknown-keyword'); } args.push('-C', destArg, '-f', fileArg); yield exec_1.exec(`tar`, args); return dest; }); } exports.extractTar = extractTar; /** * Extract a zip * * @param file path to the zip * @param dest destination directory. Optional. * @returns path to the destination directory */ function extractZip(file, dest) { return __awaiter(this, void 0, void 0, function* () { if (!file) { throw new Error("parameter 'file' is required"); } dest = yield _createExtractFolder(dest); if (IS_WINDOWS) { yield extractZipWin(file, dest); } else { yield extractZipNix(file, dest); } return dest; }); } exports.extractZip = extractZip; function extractZipWin(file, dest) { return __awaiter(this, void 0, void 0, function* () { // build the powershell command const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines const escapedDest = dest.replace(/'/g, "''").replace(/"|\n|\r/g, ''); const command = `$ErrorActionPreference = 'Stop' ; try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}')`; // run powershell const powershellPath = yield io.which('powershell'); const args = [ '-NoLogo', '-Sta', '-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Unrestricted', '-Command', command ]; yield exec_1.exec(`"${powershellPath}"`, args); }); } function extractZipNix(file, dest) { return __awaiter(this, void 0, void 0, function* () { const unzipPath = yield io.which('unzip'); yield exec_1.exec(`"${unzipPath}"`, [file], { cwd: dest }); }); } /** * Caches a directory and installs it into the tool cacheDir * * @param sourceDir the directory to cache into tools * @param tool tool name * @param version version of the tool. semver format * @param arch architecture of the tool. Optional. Defaults to machine architecture */ function cacheDir(sourceDir, tool, version, arch) { return __awaiter(this, void 0, void 0, function* () { version = semver.clean(version) || version; arch = arch || os.arch(); core.debug(`Caching tool ${tool} ${version} ${arch}`); core.debug(`source dir: ${sourceDir}`); if (!fs.statSync(sourceDir).isDirectory()) { throw new Error('sourceDir is not a directory'); } // Create the tool dir const destPath = yield _createToolPath(tool, version, arch); // copy each child item. do not move. move can fail on Windows // due to anti-virus software having an open handle on a file. for (const itemName of fs.readdirSync(sourceDir)) { const s = path.join(sourceDir, itemName); yield io.cp(s, destPath, { recursive: true }); } // write .complete _completeToolPath(tool, version, arch); return destPath; }); } exports.cacheDir = cacheDir; /** * Caches a downloaded file (GUID) and installs it * into the tool cache with a given targetName * * @param sourceFile the file to cache into tools. Typically a result of downloadTool which is a guid. * @param targetFile the name of the file name in the tools directory * @param tool tool name * @param version version of the tool. semver format * @param arch architecture of the tool. Optional. Defaults to machine architecture */ function cacheFile(sourceFile, targetFile, tool, version, arch) { return __awaiter(this, void 0, void 0, function* () { version = semver.clean(version) || version; arch = arch || os.arch(); core.debug(`Caching tool ${tool} ${version} ${arch}`); core.debug(`source file: ${sourceFile}`); if (!fs.statSync(sourceFile).isFile()) { throw new Error('sourceFile is not a file'); } // create the tool dir const destFolder = yield _createToolPath(tool, version, arch); // copy instead of move. move can fail on Windows due to // anti-virus software having an open handle on a file. const destPath = path.join(destFolder, targetFile); core.debug(`destination file ${destPath}`); yield io.cp(sourceFile, destPath); // write .complete _completeToolPath(tool, version, arch); return destFolder; }); } exports.cacheFile = cacheFile; /** * Finds the path to a tool version in the local installed tool cache * * @param toolName name of the tool * @param versionSpec version of the tool * @param arch optional arch. defaults to arch of computer */ function find(toolName, versionSpec, arch) { if (!toolName) { throw new Error('toolName parameter is required'); } if (!versionSpec) { throw new Error('versionSpec parameter is required'); } arch = arch || os.arch(); // attempt to resolve an explicit version if (!_isExplicitVersion(versionSpec)) { const localVersions = findAllVersions(toolName, arch); const match = _evaluateVersions(localVersions, versionSpec); versionSpec = match; } // check for the explicit version in the cache let toolPath = ''; if (versionSpec) { versionSpec = semver.clean(versionSpec) || ''; const cachePath = path.join(cacheRoot, toolName, versionSpec, arch); core.debug(`checking cache: ${cachePath}`); if (fs.existsSync(cachePath) && fs.existsSync(`${cachePath}.complete`)) { core.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch}`); toolPath = cachePath; } else { core.debug('not found'); } } return toolPath; } exports.find = find; /** * Finds the paths to all versions of a tool that are installed in the local tool cache * * @param toolName name of the tool * @param arch optional arch. defaults to arch of computer */ function findAllVersions(toolName, arch) { const versions = []; arch = arch || os.arch(); const toolPath = path.join(cacheRoot, toolName); if (fs.existsSync(toolPath)) { const children = fs.readdirSync(toolPath); for (const child of children) { if (_isExplicitVersion(child)) { const fullPath = path.join(toolPath, child, arch || ''); if (fs.existsSync(fullPath) && fs.existsSync(`${fullPath}.complete`)) { versions.push(child); } } } } return versions; } exports.findAllVersions = findAllVersions; function _createExtractFolder(dest) { return __awaiter(this, void 0, void 0, function* () { if (!dest) { // create a temp dir dest = path.join(tempDirectory, v4_1.default()); } yield io.mkdirP(dest); return dest; }); } function _createToolPath(tool, version, arch) { return __awaiter(this, void 0, void 0, function* () { const folderPath = path.join(cacheRoot, tool, semver.clean(version) || version, arch || ''); core.debug(`destination ${folderPath}`); const markerPath = `${folderPath}.complete`; yield io.rmRF(folderPath); yield io.rmRF(markerPath); yield io.mkdirP(folderPath); return folderPath; }); } function _completeToolPath(tool, version, arch) { const folderPath = path.join(cacheRoot, tool, semver.clean(version) || version, arch || ''); const markerPath = `${folderPath}.complete`; fs.writeFileSync(markerPath, ''); core.debug('finished caching tool'); } function _isExplicitVersion(versionSpec) { const c = semver.clean(versionSpec) || ''; core.debug(`isExplicit: ${c}`); const valid = semver.valid(c) != null; core.debug(`explicit? ${valid}`); return valid; } function _evaluateVersions(versions, versionSpec) { let version = ''; core.debug(`evaluating ${versions.length} versions`); versions = versions.sort((a, b) => { if (semver.gt(a, b)) { return 1; } return -1; }); for (let i = versions.length - 1; i >= 0; i--) { const potential = versions[i]; const satisfied = semver.satisfies(potential, versionSpec); if (satisfied) { version = potential; break; } } if (version) { core.debug(`matched: ${version}`); } else { core.debug('match not found'); } return version; } //# sourceMappingURL=tool-cache.js.map /* WEBPACK VAR INJECTION */}.call(this, __dirname)) /***/ }), /***/ "./node_modules/@actions/tool-cache/node_modules/semver/semver.js": /*!************************************************************************!*\ !*** ./node_modules/@actions/tool-cache/node_modules/semver/semver.js ***! \************************************************************************/ /*! no static exports found */ /***/ (function(module, exports) { exports = module.exports = SemVer var debug /* istanbul ignore next */ if (typeof process === 'object' && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG)) { debug = function () { var args = Array.prototype.slice.call(arguments, 0) args.unshift('SEMVER') console.log.apply(console, args) } } else { debug = function () {} } // Note: this is the semver.org version of the spec that it implements // Not necessarily the package version of this code. exports.SEMVER_SPEC_VERSION = '2.0.0' var MAX_LENGTH = 256 var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || /* istanbul ignore next */ 9007199254740991 // Max safe segment length for coercion. var MAX_SAFE_COMPONENT_LENGTH = 16 // The actual regexps go on exports.re var re = exports.re = [] var src = exports.src = [] var t = exports.tokens = {} var R = 0 function tok (n) { t[n] = R++ } // The following Regular Expressions can be used for tokenizing, // validating, and parsing SemVer version strings. // ## Numeric Identifier // A single `0`, or a non-zero digit followed by zero or more digits. tok('NUMERICIDENTIFIER') src[t.NUMERICIDENTIFIER] = '0|[1-9]\\d*' tok('NUMERICIDENTIFIERLOOSE') src[t.NUMERICIDENTIFIERLOOSE] = '[0-9]+' // ## Non-numeric Identifier // Zero or more digits, followed by a letter or hyphen, and then zero or // more letters, digits, or hyphens. tok('NONNUMERICIDENTIFIER') src[t.NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*' // ## Main Version // Three dot-separated numeric identifiers. tok('MAINVERSION') src[t.MAINVERSION] = '(' + src[t.NUMERICIDENTIFIER] + ')\\.' + '(' + src[t.NUMERICIDENTIFIER] + ')\\.' + '(' + src[t.NUMERICIDENTIFIER] + ')' tok('MAINVERSIONLOOSE') src[t.MAINVERSIONLOOSE] = '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' + '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' + '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')' // ## Pre-release Version Identifier // A numeric identifier, or a non-numeric identifier. tok('PRERELEASEIDENTIFIER') src[t.PRERELEASEIDENTIFIER] = '(?:' + src[t.NUMERICIDENTIFIER] + '|' + src[t.NONNUMERICIDENTIFIER] + ')' tok('PRERELEASEIDENTIFIERLOOSE') src[t.PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[t.NUMERICIDENTIFIERLOOSE] + '|' + src[t.NONNUMERICIDENTIFIER] + ')' // ## Pre-release Version // Hyphen, followed by one or more dot-separated pre-release version // identifiers. tok('PRERELEASE') src[t.PRERELEASE] = '(?:-(' + src[t.PRERELEASEIDENTIFIER] + '(?:\\.' + src[t.PRERELEASEIDENTIFIER] + ')*))' tok('PRERELEASELOOSE') src[t.PRERELEASELOOSE] = '(?:-?(' + src[t.PRERELEASEIDENTIFIERLOOSE] + '(?:\\.' + src[t.PRERELEASEIDENTIFIERLOOSE] + ')*))' // ## Build Metadata Identifier // Any combination of digits, letters, or hyphens. tok('BUILDIDENTIFIER') src[t.BUILDIDENTIFIER] = '[0-9A-Za-z-]+' // ## Build Metadata // Plus sign, followed by one or more period-separated build metadata // identifiers. tok('BUILD') src[t.BUILD] = '(?:\\+(' + src[t.BUILDIDENTIFIER] + '(?:\\.' + src[t.BUILDIDENTIFIER] + ')*))' // ## Full Version String // A main version, followed optionally by a pre-release version and // build metadata. // Note that the only major, minor, patch, and pre-release sections of // the version string are capturing groups. The build metadata is not a // capturing group, because it should not ever be used in version // comparison. tok('FULL') tok('FULLPLAIN') src[t.FULLPLAIN] = 'v?' + src[t.MAINVERSION] + src[t.PRERELEASE] + '?' + src[t.BUILD] + '?' src[t.FULL] = '^' + src[t.FULLPLAIN] + '$' // like full, but allows v1.2.3 and =1.2.3, which people do sometimes. // also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty // common in the npm registry. tok('LOOSEPLAIN') src[t.LOOSEPLAIN] = '[v=\\s]*' + src[t.MAINVERSIONLOOSE] + src[t.PRERELEASELOOSE] + '?' + src[t.BUILD] + '?' tok('LOOSE') src[t.LOOSE] = '^' + src[t.LOOSEPLAIN] + '$' tok('GTLT') src[t.GTLT] = '((?:<|>)?=?)' // Something like "2.*" or "1.2.x". // Note that "x.x" is a valid xRange identifer, meaning "any version" // Only the first item is strictly required. tok('XRANGEIDENTIFIERLOOSE') src[t.XRANGEIDENTIFIERLOOSE] = src[t.NUMERICIDENTIFIERLOOSE] + '|x|X|\\*' tok('XRANGEIDENTIFIER') src[t.XRANGEIDENTIFIER] = src[t.NUMERICIDENTIFIER] + '|x|X|\\*' tok('XRANGEPLAIN') src[t.XRANGEPLAIN] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIER] + ')' + '(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' + '(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' + '(?:' + src[t.PRERELEASE] + ')?' + src[t.BUILD] + '?' + ')?)?' tok('XRANGEPLAINLOOSE') src[t.XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + '(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + '(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + '(?:' + src[t.PRERELEASELOOSE] + ')?' + src[t.BUILD] + '?' + ')?)?' tok('XRANGE') src[t.XRANGE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAIN] + '$' tok('XRANGELOOSE') src[t.XRANGELOOSE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAINLOOSE] + '$' // Coercion. // Extract anything that could conceivably be a part of a valid semver tok('COERCE') src[t.COERCE] = '(^|[^\\d])' + '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + '(?:$|[^\\d])' tok('COERCERTL') re[t.COERCERTL] = new RegExp(src[t.COERCE], 'g') // Tilde ranges. // Meaning is "reasonably at or greater than" tok('LONETILDE') src[t.LONETILDE] = '(?:~>?)' tok('TILDETRIM') src[t.TILDETRIM] = '(\\s*)' + src[t.LONETILDE] + '\\s+' re[t.TILDETRIM] = new RegExp(src[t.TILDETRIM], 'g') var tildeTrimReplace = '$1~' tok('TILDE') src[t.TILDE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAIN] + '$' tok('TILDELOOSE') src[t.TILDELOOSE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAINLOOSE] + '$' // Caret ranges. // Meaning is "at least and backwards compatible with" tok('LONECARET') src[t.LONECARET] = '(?:\\^)' tok('CARETTRIM') src[t.CARETTRIM] = '(\\s*)' + src[t.LONECARET] + '\\s+' re[t.CARETTRIM] = new RegExp(src[t.CARETTRIM], 'g') var caretTrimReplace = '$1^' tok('CARET') src[t.CARET] = '^' + src[t.LONECARET] + src[t.XRANGEPLAIN] + '$' tok('CARETLOOSE') src[t.CARETLOOSE] = '^' + src[t.LONECARET] + src[t.XRANGEPLAINLOOSE] + '$' // A simple gt/lt/eq thing, or just "" to indicate "any version" tok('COMPARATORLOOSE') src[t.COMPARATORLOOSE] = '^' + src[t.GTLT] + '\\s*(' + src[t.LOOSEPLAIN] + ')$|^$' tok('COMPARATOR') src[t.COMPARATOR] = '^' + src[t.GTLT] + '\\s*(' + src[t.FULLPLAIN] + ')$|^$' // An expression to strip any whitespace between the gtlt and the thing // it modifies, so that `> 1.2.3` ==> `>1.2.3` tok('COMPARATORTRIM') src[t.COMPARATORTRIM] = '(\\s*)' + src[t.GTLT] + '\\s*(' + src[t.LOOSEPLAIN] + '|' + src[t.XRANGEPLAIN] + ')' // this one has to use the /g flag re[t.COMPARATORTRIM] = new RegExp(src[t.COMPARATORTRIM], 'g') var comparatorTrimReplace = '$1$2$3' // Something like `1.2.3 - 1.2.4` // Note that these all use the loose form, because they'll be // checked against either the strict or loose comparator form // later. tok('HYPHENRANGE') src[t.HYPHENRANGE] = '^\\s*(' + src[t.XRANGEPLAIN] + ')' + '\\s+-\\s+' + '(' + src[t.XRANGEPLAIN] + ')' + '\\s*$' tok('HYPHENRANGELOOSE') src[t.HYPHENRANGELOOSE] = '^\\s*(' + src[t.XRANGEPLAINLOOSE] + ')' + '\\s+-\\s+' + '(' + src[t.XRANGEPLAINLOOSE] + ')' + '\\s*$' // Star ranges basically just allow anything at all. tok('STAR') src[t.STAR] = '(<|>)?=?\\s*\\*' // Compile to actual regexp objects. // All are flag-free, unless they were created above with a flag. for (var i = 0; i < R; i++) { debug(i, src[i]) if (!re[i]) { re[i] = new RegExp(src[i]) } } exports.parse = parse function parse (version, options) { if (!options || typeof options !== 'object') { options = { loose: !!options, includePrerelease: false } } if (version instanceof SemVer) { return version } if (typeof version !== 'string') { return null } if (version.length > MAX_LENGTH) { return null } var r = options.loose ? re[t.LOOSE] : re[t.FULL] if (!r.test(version)) { return null } try { return new SemVer(version, options) } catch (er) { return null } } exports.valid = valid function valid (version, options) { var v = parse(version, options) return v ? v.version : null } exports.clean = clean function clean (version, options) { var s = parse(version.trim().replace(/^[=v]+/, ''), options) return s ? s.version : null } exports.SemVer = SemVer function SemVer (version, options) { if (!options || typeof options !== 'object') { options = { loose: !!options, includePrerelease: false } } if (version instanceof SemVer) { if (version.loose === options.loose) { return version } else { version = version.version } } else if (typeof version !== 'string') { throw new TypeError('Invalid Version: ' + version) } if (version.length > MAX_LENGTH) { throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') } if (!(this instanceof SemVer)) { return new SemVer(version, options) } debug('SemVer', version, options) this.options = options this.loose = !!options.loose var m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]) if (!m) { throw new TypeError('Invalid Version: ' + version) } this.raw = version // these are actually numbers this.major = +m[1] this.minor = +m[2] this.patch = +m[3] if (this.major > MAX_SAFE_INTEGER || this.major < 0) { throw new TypeError('Invalid major version') } if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { throw new TypeError('Invalid minor version') } if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { throw new TypeError('Invalid patch version') } // numberify any prerelease numeric ids if (!m[4]) { this.prerelease = [] } else { this.prerelease = m[4].split('.').map(function (id) { if (/^[0-9]+$/.test(id)) { var num = +id if (num >= 0 && num < MAX_SAFE_INTEGER) { return num } } return id }) } this.build = m[5] ? m[5].split('.') : [] this.format() } SemVer.prototype.format = function () { this.version = this.major + '.' + this.minor + '.' + this.patch if (this.prerelease.length) { this.version += '-' + this.prerelease.join('.') } return this.version } SemVer.prototype.toString = function () { return this.version } SemVer.prototype.compare = function (other) { debug('SemVer.compare', this.version, this.options, other) if (!(other instanceof SemVer)) { other = new SemVer(other, this.options) } return this.compareMain(other) || this.comparePre(other) } SemVer.prototype.compareMain = function (other) { if (!(other instanceof SemVer)) { other = new SemVer(other, this.options) } return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch) } SemVer.prototype.comparePre = function (other) { if (!(other instanceof SemVer)) { other = new SemVer(other, this.options) } // NOT having a prerelease is > having one if (this.prerelease.length && !other.prerelease.length) { return -1 } else if (!this.prerelease.length && other.prerelease.length) { return 1 } else if (!this.prerelease.length && !other.prerelease.length) { return 0 } var i = 0 do { var a = this.prerelease[i] var b = other.prerelease[i] debug('prerelease compare', i, a, b) if (a === undefined && b === undefined) { return 0 } else if (b === undefined) { return 1 } else if (a === undefined) { return -1 } else if (a === b) { continue } else { return compareIdentifiers(a, b) } } while (++i) } SemVer.prototype.compareBuild = function (other) { if (!(other instanceof SemVer)) { other = new SemVer(other, this.options) } var i = 0 do { var a = this.build[i] var b = other.build[i] debug('prerelease compare', i, a, b) if (a === undefined && b === undefined) { return 0 } else if (b === undefined) { return 1 } else if (a === undefined) { return -1 } else if (a === b) { continue } else { return compareIdentifiers(a, b) } } while (++i) } // preminor will bump the version up to the next minor release, and immediately // down to pre-release. premajor and prepatch work the same way. SemVer.prototype.inc = function (release, identifier) { switch (release) { case 'premajor': this.prerelease.length = 0 this.patch = 0 this.minor = 0 this.major++ this.inc('pre', identifier) break case 'preminor': this.prerelease.length = 0 this.patch = 0 this.minor++ this.inc('pre', identifier) break case 'prepatch': // If this is already a prerelease, it will bump to the next version // drop any prereleases that might already exist, since they are not // relevant at this point. this.prerelease.length = 0 this.inc('patch', identifier) this.inc('pre', identifier) break // If the input is a non-prerelease version, this acts the same as // prepatch. case 'prerelease': if (this.prerelease.length === 0) { this.inc('patch', identifier) } this.inc('pre', identifier) break case 'major': // If this is a pre-major version, bump up to the same major version. // Otherwise increment major. // 1.0.0-5 bumps to 1.0.0 // 1.1.0 bumps to 2.0.0 if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) { this.major++ } this.minor = 0 this.patch = 0 this.prerelease = [] break case 'minor': // If this is a pre-minor version, bump up to the same minor version. // Otherwise increment minor. // 1.2.0-5 bumps to 1.2.0 // 1.2.1 bumps to 1.3.0 if (this.patch !== 0 || this.prerelease.length === 0) { this.minor++ } this.patch = 0 this.prerelease = [] break case 'patch': // If this is not a pre-release version, it will increment the patch. // If it is a pre-release it will bump up to the same patch version. // 1.2.0-5 patches to 1.2.0 // 1.2.0 patches to 1.2.1 if (this.prerelease.length === 0) { this.patch++ } this.prerelease = [] break // This probably shouldn't be used publicly. // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. case 'pre': if (this.prerelease.length === 0) { this.prerelease = [0] } else { var i = this.prerelease.length while (--i >= 0) { if (typeof this.prerelease[i] === 'number') { this.prerelease[i]++ i = -2 } } if (i === -1) { // didn't increment anything this.prerelease.push(0) } } if (identifier) { // 1.2.0-beta.1 bumps to 1.2.0-beta.2, // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 if (this.prerelease[0] === identifier) { if (isNaN(this.prerelease[1])) { this.prerelease = [identifier, 0] } } else { this.prerelease = [identifier, 0] } } break default: throw new Error('invalid increment argument: ' + release) } this.format() this.raw = this.version return this } exports.inc = inc function inc (version, release, loose, identifier) { if (typeof (loose) === 'string') { identifier = loose loose = undefined } try { return new SemVer(version, loose).inc(release, identifier).version } catch (er) { return null } } exports.diff = diff function diff (version1, version2) { if (eq(version1, version2)) { return null } else { var v1 = parse(version1) var v2 = parse(version2) var prefix = '' if (v1.prerelease.length || v2.prerelease.length) { prefix = 'pre' var defaultResult = 'prerelease' } for (var key in v1) { if (key === 'major' || key === 'minor' || key === 'patch') { if (v1[key] !== v2[key]) { return prefix + key } } } return defaultResult // may be undefined } } exports.compareIdentifiers = compareIdentifiers var numeric = /^[0-9]+$/ function compareIdentifiers (a, b) { var anum = numeric.test(a) var bnum = numeric.test(b) if (anum && bnum) { a = +a b = +b } return a === b ? 0 : (anum && !bnum) ? -1 : (bnum && !anum) ? 1 : a < b ? -1 : 1 } exports.rcompareIdentifiers = rcompareIdentifiers function rcompareIdentifiers (a, b) { return compareIdentifiers(b, a) } exports.major = major function major (a, loose) { return new SemVer(a, loose).major } exports.minor = minor function minor (a, loose) { return new SemVer(a, loose).minor } exports.patch = patch function patch (a, loose) { return new SemVer(a, loose).patch } exports.compare = compare function compare (a, b, loose) { return new SemVer(a, loose).compare(new SemVer(b, loose)) } exports.compareLoose = compareLoose function compareLoose (a, b) { return compare(a, b, true) } exports.compareBuild = compareBuild function compareBuild (a, b, loose) { var versionA = new SemVer(a, loose) var versionB = new SemVer(b, loose) return versionA.compare(versionB) || versionA.compareBuild(versionB) } exports.rcompare = rcompare function rcompare (a, b, loose) { return compare(b, a, loose) } exports.sort = sort function sort (list, loose) { return list.sort(function (a, b) { return exports.compareBuild(a, b, loose) }) } exports.rsort = rsort function rsort (list, loose) { return list.sort(function (a, b) { return exports.compareBuild(b, a, loose) }) } exports.gt = gt function gt (a, b, loose) { return compare(a, b, loose) > 0 } exports.lt = lt function lt (a, b, loose) { return compare(a, b, loose) < 0 } exports.eq = eq function eq (a, b, loose) { return compare(a, b, loose) === 0 } exports.neq = neq function neq (a, b, loose) { return compare(a, b, loose) !== 0 } exports.gte = gte function gte (a, b, loose) { return compare(a, b, loose) >= 0 } exports.lte = lte function lte (a, b, loose) { return compare(a, b, loose) <= 0 } exports.cmp = cmp function cmp (a, op, b, loose) { switch (op) { case '===': if (typeof a === 'object') a = a.version if (typeof b === 'object') b = b.version return a === b case '!==': if (typeof a === 'object') a = a.version if (typeof b === 'object') b = b.version return a !== b case '': case '=': case '==': return eq(a, b, loose) case '!=': return neq(a, b, loose) case '>': return gt(a, b, loose) case '>=': return gte(a, b, loose) case '<': return lt(a, b, loose) case '<=': return lte(a, b, loose) default: throw new TypeError('Invalid operator: ' + op) } } exports.Comparator = Comparator function Comparator (comp, options) { if (!options || typeof options !== 'object') { options = { loose: !!options, includePrerelease: false } } if (comp instanceof Comparator) { if (comp.loose === !!options.loose) { return comp } else { comp = comp.value } } if (!(this instanceof Comparator)) { return new Comparator(comp, options) } debug('comparator', comp, options) this.options = options this.loose = !!options.loose this.parse(comp) if (this.semver === ANY) { this.value = '' } else { this.value = this.operator + this.semver.version } debug('comp', this) } var ANY = {} Comparator.prototype.parse = function (comp) { var r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR] var m = comp.match(r) if (!m) { throw new TypeError('Invalid comparator: ' + comp) } this.operator = m[1] !== undefined ? m[1] : '' if (this.operator === '=') { this.operator = '' } // if it literally is just '>' or '' then allow anything. if (!m[2]) { this.semver = ANY } else { this.semver = new SemVer(m[2], this.options.loose) } } Comparator.prototype.toString = function () { return this.value } Comparator.prototype.test = function (version) { debug('Comparator.test', version, this.options.loose) if (this.semver === ANY || version === ANY) { return true } if (typeof version === 'string') { try { version = new SemVer(version, this.options) } catch (er) { return false } } return cmp(version, this.operator, this.semver, this.options) } Comparator.prototype.intersects = function (comp, options) { if (!(comp instanceof Comparator)) { throw new TypeError('a Comparator is required') } if (!options || typeof options !== 'object') { options = { loose: !!options, includePrerelease: false } } var rangeTmp if (this.operator === '') { if (this.value === '') { return true } rangeTmp = new Range(comp.value, options) return satisfies(this.value, rangeTmp, options) } else if (comp.operator === '') { if (comp.value === '') { return true } rangeTmp = new Range(this.value, options) return satisfies(comp.semver, rangeTmp, options) } var sameDirectionIncreasing = (this.operator === '>=' || this.operator === '>') && (comp.operator === '>=' || comp.operator === '>') var sameDirectionDecreasing = (this.operator === '<=' || this.operator === '<') && (comp.operator === '<=' || comp.operator === '<') var sameSemVer = this.semver.version === comp.semver.version var differentDirectionsInclusive = (this.operator === '>=' || this.operator === '<=') && (comp.operator === '>=' || comp.operator === '<=') var oppositeDirectionsLessThan = cmp(this.semver, '<', comp.semver, options) && ((this.operator === '>=' || this.operator === '>') && (comp.operator === '<=' || comp.operator === '<')) var oppositeDirectionsGreaterThan = cmp(this.semver, '>', comp.semver, options) && ((this.operator === '<=' || this.operator === '<') && (comp.operator === '>=' || comp.operator === '>')) return sameDirectionIncreasing || sameDirectionDecreasing || (sameSemVer && differentDirectionsInclusive) || oppositeDirectionsLessThan || oppositeDirectionsGreaterThan } exports.Range = Range function Range (range, options) { if (!options || typeof options !== 'object') { options = { loose: !!options, includePrerelease: false } } if (range instanceof Range) { if (range.loose === !!options.loose && range.includePrerelease === !!options.includePrerelease) { return range } else { return new Range(range.raw, options) } } if (range instanceof Comparator) { return new Range(range.value, options) } if (!(this instanceof Range)) { return new Range(range, options) } this.options = options this.loose = !!options.loose this.includePrerelease = !!options.includePrerelease // First, split based on boolean or || this.raw = range this.set = range.split(/\s*\|\|\s*/).map(function (range) { return this.parseRange(range.trim()) }, this).filter(function (c) { // throw out any that are not relevant for whatever reason return c.length }) if (!this.set.length) { throw new TypeError('Invalid SemVer Range: ' + range) } this.format() } Range.prototype.format = function () { this.range = this.set.map(function (comps) { return comps.join(' ').trim() }).join('||').trim() return this.range } Range.prototype.toString = function () { return this.range } Range.prototype.parseRange = function (range) { var loose = this.options.loose range = range.trim() // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` var hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE] range = range.replace(hr, hyphenReplace) debug('hyphen replace', range) // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace) debug('comparator trim', range, re[t.COMPARATORTRIM]) // `~ 1.2.3` => `~1.2.3` range = range.replace(re[t.TILDETRIM], tildeTrimReplace) // `^ 1.2.3` => `^1.2.3` range = range.replace(re[t.CARETTRIM], caretTrimReplace) // normalize spaces range = range.split(/\s+/).join(' ') // At this point, the range is completely trimmed and // ready to be split into comparators. var compRe = loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR] var set = range.split(' ').map(function (comp) { return parseComparator(comp, this.options) }, this).join(' ').split(/\s+/) if (this.options.loose) { // in loose mode, throw out any that are not valid comparators set = set.filter(function (comp) { return !!comp.match(compRe) }) } set = set.map(function (comp) { return new Comparator(comp, this.options) }, this) return set } Range.prototype.intersects = function (range, options) { if (!(range instanceof Range)) { throw new TypeError('a Range is required') } return this.set.some(function (thisComparators) { return ( isSatisfiable(thisComparators, options) && range.set.some(function (rangeComparators) { return ( isSatisfiable(rangeComparators, options) && thisComparators.every(function (thisComparator) { return rangeComparators.every(function (rangeComparator) { return thisComparator.intersects(rangeComparator, options) }) }) ) }) ) }) } // take a set of comparators and determine whether there // exists a version which can satisfy it function isSatisfiable (comparators, options) { var result = true var remainingComparators = comparators.slice() var testComparator = remainingComparators.pop() while (result && remainingComparators.length) { result = remainingComparators.every(function (otherComparator) { return testComparator.intersects(otherComparator, options) }) testComparator = remainingComparators.pop() } return result } // Mostly just for testing and legacy API reasons exports.toComparators = toComparators function toComparators (range, options) { return new Range(range, options).set.map(function (comp) { return comp.map(function (c) { return c.value }).join(' ').trim().split(' ') }) } // comprised of xranges, tildes, stars, and gtlt's at this point. // already replaced the hyphen ranges // turn into a set of JUST comparators. function parseComparator (comp, options) { debug('comp', comp, options) comp = replaceCarets(comp, options) debug('caret', comp) comp = replaceTildes(comp, options) debug('tildes', comp) comp = replaceXRanges(comp, options) debug('xrange', comp) comp = replaceStars(comp, options) debug('stars', comp) return comp } function isX (id) { return !id || id.toLowerCase() === 'x' || id === '*' } // ~, ~> --> * (any, kinda silly) // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 function replaceTildes (comp, options) { return comp.trim().split(/\s+/).map(function (comp) { return replaceTilde(comp, options) }).join(' ') } function replaceTilde (comp, options) { var r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE] return comp.replace(r, function (_, M, m, p, pr) { debug('tilde', comp, _, M, m, p, pr) var ret if (isX(M)) { ret = '' } else if (isX(m)) { ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' } else if (isX(p)) { // ~1.2 == >=1.2.0 <1.3.0 ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' } else if (pr) { debug('replaceTilde pr', pr) ret = '>=' + M + '.' + m + '.' + p + '-' + pr + ' <' + M + '.' + (+m + 1) + '.0' } else { // ~1.2.3 == >=1.2.3 <1.3.0 ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + (+m + 1) + '.0' } debug('tilde return', ret) return ret }) } // ^ --> * (any, kinda silly) // ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 // ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 // ^1.2.3 --> >=1.2.3 <2.0.0 // ^1.2.0 --> >=1.2.0 <2.0.0 function replaceCarets (comp, options) { return comp.trim().split(/\s+/).map(function (comp) { return replaceCaret(comp, options) }).join(' ') } function replaceCaret (comp, options) { debug('caret', comp, options) var r = options.loose ? re[t.CARETLOOSE] : re[t.CARET] return comp.replace(r, function (_, M, m, p, pr) { debug('caret', comp, _, M, m, p, pr) var ret if (isX(M)) { ret = '' } else if (isX(m)) { ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' } else if (isX(p)) { if (M === '0') { ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' } else { ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0' } } else if (pr) { debug('replaceCaret pr', pr) if (M === '0') { if (m === '0') { ret = '>=' + M + '.' + m + '.' + p + '-' + pr + ' <' + M + '.' + m + '.' + (+p + 1) } else { ret = '>=' + M + '.' + m + '.' + p + '-' + pr + ' <' + M + '.' + (+m + 1) + '.0' } } else { ret = '>=' + M + '.' + m + '.' + p + '-' + pr + ' <' + (+M + 1) + '.0.0' } } else { debug('no pr') if (M === '0') { if (m === '0') { ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + m + '.' + (+p + 1) } else { ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + (+m + 1) + '.0' } } else { ret = '>=' + M + '.' + m + '.' + p + ' <' + (+M + 1) + '.0.0' } } debug('caret return', ret) return ret }) } function replaceXRanges (comp, options) { debug('replaceXRanges', comp, options) return comp.split(/\s+/).map(function (comp) { return replaceXRange(comp, options) }).join(' ') } function replaceXRange (comp, options) { comp = comp.trim() var r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE] return comp.replace(r, function (ret, gtlt, M, m, p, pr) { debug('xRange', comp, ret, gtlt, M, m, p, pr) var xM = isX(M) var xm = xM || isX(m) var xp = xm || isX(p) var anyX = xp if (gtlt === '=' && anyX) { gtlt = '' } // if we're including prereleases in the match, then we need // to fix this to -0, the lowest possible prerelease value pr = options.includePrerelease ? '-0' : '' if (xM) { if (gtlt === '>' || gtlt === '<') { // nothing is allowed ret = '<0.0.0-0' } else { // nothing is forbidden ret = '*' } } else if (gtlt && anyX) { // we know patch is an x, because we have any x at all. // replace X with 0 if (xm) { m = 0 } p = 0 if (gtlt === '>') { // >1 => >=2.0.0 // >1.2 => >=1.3.0 // >1.2.3 => >= 1.2.4 gtlt = '>=' if (xm) { M = +M + 1 m = 0 p = 0 } else { m = +m + 1 p = 0 } } else if (gtlt === '<=') { // <=0.7.x is actually <0.8.0, since any 0.7.x should // pass. Similarly, <=7.x is actually <8.0.0, etc. gtlt = '<' if (xm) { M = +M + 1 } else { m = +m + 1 } } ret = gtlt + M + '.' + m + '.' + p + pr } else if (xm) { ret = '>=' + M + '.0.0' + pr + ' <' + (+M + 1) + '.0.0' + pr } else if (xp) { ret = '>=' + M + '.' + m + '.0' + pr + ' <' + M + '.' + (+m + 1) + '.0' + pr } debug('xRange return', ret) return ret }) } // Because * is AND-ed with everything else in the comparator, // and '' means "any version", just remove the *s entirely. function replaceStars (comp, options) { debug('replaceStars', comp, options) // Looseness is ignored here. star is always as loose as it gets! return comp.trim().replace(re[t.STAR], '') } // This function is passed to string.replace(re[t.HYPHENRANGE]) // M, m, patch, prerelease, build // 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 // 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do // 1.2 - 3.4 => >=1.2.0 <3.5.0 function hyphenReplace ($0, from, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr, tb) { if (isX(fM)) { from = '' } else if (isX(fm)) { from = '>=' + fM + '.0.0' } else if (isX(fp)) { from = '>=' + fM + '.' + fm + '.0' } else { from = '>=' + from } if (isX(tM)) { to = '' } else if (isX(tm)) { to = '<' + (+tM + 1) + '.0.0' } else if (isX(tp)) { to = '<' + tM + '.' + (+tm + 1) + '.0' } else if (tpr) { to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr } else { to = '<=' + to } return (from + ' ' + to).trim() } // if ANY of the sets match ALL of its comparators, then pass Range.prototype.test = function (version) { if (!version) { return false } if (typeof version === 'string') { try { version = new SemVer(version, this.options) } catch (er) { return false } } for (var i = 0; i < this.set.length; i++) { if (testSet(this.set[i], version, this.options)) { return true } } return false } function testSet (set, version, options) { for (var i = 0; i < set.length; i++) { if (!set[i].test(version)) { return false } } if (version.prerelease.length && !options.includePrerelease) { // Find the set of versions that are allowed to have prereleases // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 // That should allow `1.2.3-pr.2` to pass. // However, `1.2.4-alpha.notready` should NOT be allowed, // even though it's within the range set by the comparators. for (i = 0; i < set.length; i++) { debug(set[i].semver) if (set[i].semver === ANY) { continue } if (set[i].semver.prerelease.length > 0) { var allowed = set[i].semver if (allowed.major === version.major && allowed.minor === version.minor && allowed.patch === version.patch) { return true } } } // Version has a -pre, but it's not one of the ones we like. return false } return true } exports.satisfies = satisfies function satisfies (version, range, options) { try { range = new Range(range, options) } catch (er) { return false } return range.test(version) } exports.maxSatisfying = maxSatisfying function maxSatisfying (versions, range, options) { var max = null var maxSV = null try { var rangeObj = new Range(range, options) } catch (er) { return null } versions.forEach(function (v) { if (rangeObj.test(v)) { // satisfies(v, range, options) if (!max || maxSV.compare(v) === -1) { // compare(max, v, true) max = v maxSV = new SemVer(max, options) } } }) return max } exports.minSatisfying = minSatisfying function minSatisfying (versions, range, options) { var min = null var minSV = null try { var rangeObj = new Range(range, options) } catch (er) { return null } versions.forEach(function (v) { if (rangeObj.test(v)) { // satisfies(v, range, options) if (!min || minSV.compare(v) === 1) { // compare(min, v, true) min = v minSV = new SemVer(min, options) } } }) return min } exports.minVersion = minVersion function minVersion (range, loose) { range = new Range(range, loose) var minver = new SemVer('0.0.0') if (range.test(minver)) { return minver } minver = new SemVer('0.0.0-0') if (range.test(minver)) { return minver } minver = null for (var i = 0; i < range.set.length; ++i) { var comparators = range.set[i] comparators.forEach(function (comparator) { // Clone to avoid manipulating the comparator's semver object. var compver = new SemVer(comparator.semver.version) switch (comparator.operator) { case '>': if (compver.prerelease.length === 0) { compver.patch++ } else { compver.prerelease.push(0) } compver.raw = compver.format() /* fallthrough */ case '': case '>=': if (!minver || gt(minver, compver)) { minver = compver } break case '<': case '<=': /* Ignore maximum versions */ break /* istanbul ignore next */ default: throw new Error('Unexpected operation: ' + comparator.operator) } }) } if (minver && range.test(minver)) { return minver } return null } exports.validRange = validRange function validRange (range, options) { try { // Return '*' instead of '' so that truthiness works. // This will throw if it's invalid anyway return new Range(range, options).range || '*' } catch (er) { return null } } // Determine if version is less than all the versions possible in the range exports.ltr = ltr function ltr (version, range, options) { return outside(version, range, '<', options) } // Determine if version is greater than all the versions possible in the range. exports.gtr = gtr function gtr (version, range, options) { return outside(version, range, '>', options) } exports.outside = outside function outside (version, range, hilo, options) { version = new SemVer(version, options) range = new Range(range, options) var gtfn, ltefn, ltfn, comp, ecomp switch (hilo) { case '>': gtfn = gt ltefn = lte ltfn = lt comp = '>' ecomp = '>=' break case '<': gtfn = lt ltefn = gte ltfn = gt comp = '<' ecomp = '<=' break default: throw new TypeError('Must provide a hilo val of "<" or ">"') } // If it satisifes the range it is not outside if (satisfies(version, range, options)) { return false } // From now on, variable terms are as if we're in "gtr" mode. // but note that everything is flipped for the "ltr" function. for (var i = 0; i < range.set.length; ++i) { var comparators = range.set[i] var high = null var low = null comparators.forEach(function (comparator) { if (comparator.semver === ANY) { comparator = new Comparator('>=0.0.0') } high = high || comparator low = low || comparator if (gtfn(comparator.semver, high.semver, options)) { high = comparator } else if (ltfn(comparator.semver, low.semver, options)) { low = comparator } }) // If the edge version comparator has a operator then our version // isn't outside it if (high.operator === comp || high.operator === ecomp) { return false } // If the lowest version comparator has an operator and our version // is less than it then it isn't higher than the range if ((!low.operator || low.operator === comp) && ltefn(version, low.semver)) { return false } else if (low.operator === ecomp && ltfn(version, low.semver)) { return false } } return true } exports.prerelease = prerelease function prerelease (version, options) { var parsed = parse(version, options) return (parsed && parsed.prerelease.length) ? parsed.prerelease : null } exports.intersects = intersects function intersects (r1, r2, options) { r1 = new Range(r1, options) r2 = new Range(r2, options) return r1.intersects(r2) } exports.coerce = coerce function coerce (version, options) { if (version instanceof SemVer) { return version } if (typeof version === 'number') { version = String(version) } if (typeof version !== 'string') { return null } options = options || {} var match = null if (!options.rtl) { match = version.match(re[t.COERCE]) } else { // Find the right-most coercible string that does not share // a terminus with a more left-ward coercible string. // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4' // // Walk through the string checking with a /g regexp // Manually set the index so as to pick up overlapping matches. // Stop when we get a match that ends at the string end, since no // coercible string can be more right-ward without the same terminus. var next while ((next = re[t.COERCERTL].exec(version)) && (!match || match.index + match[0].length !== version.length) ) { if (!match || next.index + next[0].length !== match.index + match[0].length) { match = next } re[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length } // leave it in a clean state re[t.COERCERTL].lastIndex = -1 } if (match === null) { return null } return parse(match[2] + '.' + (match[3] || '0') + '.' + (match[4] || '0'), options) } /***/ }), /***/ "./node_modules/inversify/lib/annotation/decorator_utils.js": /*!******************************************************************!*\ !*** ./node_modules/inversify/lib/annotation/decorator_utils.js ***! \******************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var ERROR_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js"); var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js"); function tagParameter(annotationTarget, propertyName, parameterIndex, metadata) { var metadataKey = METADATA_KEY.TAGGED; _tagParameterOrProperty(metadataKey, annotationTarget, propertyName, metadata, parameterIndex); } exports.tagParameter = tagParameter; function tagProperty(annotationTarget, propertyName, metadata) { var metadataKey = METADATA_KEY.TAGGED_PROP; _tagParameterOrProperty(metadataKey, annotationTarget.constructor, propertyName, metadata); } exports.tagProperty = tagProperty; function _tagParameterOrProperty(metadataKey, annotationTarget, propertyName, metadata, parameterIndex) { var paramsOrPropertiesMetadata = {}; var isParameterDecorator = (typeof parameterIndex === "number"); var key = (parameterIndex !== undefined && isParameterDecorator) ? parameterIndex.toString() : propertyName; if (isParameterDecorator && propertyName !== undefined) { throw new Error(ERROR_MSGS.INVALID_DECORATOR_OPERATION); } if (Reflect.hasOwnMetadata(metadataKey, annotationTarget)) { paramsOrPropertiesMetadata = Reflect.getMetadata(metadataKey, annotationTarget); } var paramOrPropertyMetadata = paramsOrPropertiesMetadata[key]; if (!Array.isArray(paramOrPropertyMetadata)) { paramOrPropertyMetadata = []; } else { for (var _i = 0, paramOrPropertyMetadata_1 = paramOrPropertyMetadata; _i < paramOrPropertyMetadata_1.length; _i++) { var m = paramOrPropertyMetadata_1[_i]; if (m.key === metadata.key) { throw new Error(ERROR_MSGS.DUPLICATED_METADATA + " " + m.key.toString()); } } } paramOrPropertyMetadata.push(metadata); paramsOrPropertiesMetadata[key] = paramOrPropertyMetadata; Reflect.defineMetadata(metadataKey, paramsOrPropertiesMetadata, annotationTarget); } function _decorate(decorators, target) { Reflect.decorate(decorators, target); } function _param(paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); }; } function decorate(decorator, target, parameterIndex) { if (typeof parameterIndex === "number") { _decorate([_param(parameterIndex, decorator)], target); } else if (typeof parameterIndex === "string") { Reflect.decorate([decorator], target, parameterIndex); } else { _decorate([decorator], target); } } exports.decorate = decorate; /***/ }), /***/ "./node_modules/inversify/lib/annotation/inject.js": /*!*********************************************************!*\ !*** ./node_modules/inversify/lib/annotation/inject.js ***! \*********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var error_msgs_1 = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js"); var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js"); var metadata_1 = __webpack_require__(/*! ../planning/metadata */ "./node_modules/inversify/lib/planning/metadata.js"); var decorator_utils_1 = __webpack_require__(/*! ./decorator_utils */ "./node_modules/inversify/lib/annotation/decorator_utils.js"); var LazyServiceIdentifer = (function () { function LazyServiceIdentifer(cb) { this._cb = cb; } LazyServiceIdentifer.prototype.unwrap = function () { return this._cb(); }; return LazyServiceIdentifer; }()); exports.LazyServiceIdentifer = LazyServiceIdentifer; function inject(serviceIdentifier) { return function (target, targetKey, index) { if (serviceIdentifier === undefined) { throw new Error(error_msgs_1.UNDEFINED_INJECT_ANNOTATION(target.name)); } var metadata = new metadata_1.Metadata(METADATA_KEY.INJECT_TAG, serviceIdentifier); if (typeof index === "number") { decorator_utils_1.tagParameter(target, targetKey, index, metadata); } else { decorator_utils_1.tagProperty(target, targetKey, metadata); } }; } exports.inject = inject; /***/ }), /***/ "./node_modules/inversify/lib/annotation/injectable.js": /*!*************************************************************!*\ !*** ./node_modules/inversify/lib/annotation/injectable.js ***! \*************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var ERRORS_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js"); var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js"); function injectable() { return function (target) { if (Reflect.hasOwnMetadata(METADATA_KEY.PARAM_TYPES, target)) { throw new Error(ERRORS_MSGS.DUPLICATED_INJECTABLE_DECORATOR); } var types = Reflect.getMetadata(METADATA_KEY.DESIGN_PARAM_TYPES, target) || []; Reflect.defineMetadata(METADATA_KEY.PARAM_TYPES, types, target); return target; }; } exports.injectable = injectable; /***/ }), /***/ "./node_modules/inversify/lib/annotation/multi_inject.js": /*!***************************************************************!*\ !*** ./node_modules/inversify/lib/annotation/multi_inject.js ***! \***************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js"); var metadata_1 = __webpack_require__(/*! ../planning/metadata */ "./node_modules/inversify/lib/planning/metadata.js"); var decorator_utils_1 = __webpack_require__(/*! ./decorator_utils */ "./node_modules/inversify/lib/annotation/decorator_utils.js"); function multiInject(serviceIdentifier) { return function (target, targetKey, index) { var metadata = new metadata_1.Metadata(METADATA_KEY.MULTI_INJECT_TAG, serviceIdentifier); if (typeof index === "number") { decorator_utils_1.tagParameter(target, targetKey, index, metadata); } else { decorator_utils_1.tagProperty(target, targetKey, metadata); } }; } exports.multiInject = multiInject; /***/ }), /***/ "./node_modules/inversify/lib/annotation/named.js": /*!********************************************************!*\ !*** ./node_modules/inversify/lib/annotation/named.js ***! \********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js"); var metadata_1 = __webpack_require__(/*! ../planning/metadata */ "./node_modules/inversify/lib/planning/metadata.js"); var decorator_utils_1 = __webpack_require__(/*! ./decorator_utils */ "./node_modules/inversify/lib/annotation/decorator_utils.js"); function named(name) { return function (target, targetKey, index) { var metadata = new metadata_1.Metadata(METADATA_KEY.NAMED_TAG, name); if (typeof index === "number") { decorator_utils_1.tagParameter(target, targetKey, index, metadata); } else { decorator_utils_1.tagProperty(target, targetKey, metadata); } }; } exports.named = named; /***/ }), /***/ "./node_modules/inversify/lib/annotation/optional.js": /*!***********************************************************!*\ !*** ./node_modules/inversify/lib/annotation/optional.js ***! \***********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js"); var metadata_1 = __webpack_require__(/*! ../planning/metadata */ "./node_modules/inversify/lib/planning/metadata.js"); var decorator_utils_1 = __webpack_require__(/*! ./decorator_utils */ "./node_modules/inversify/lib/annotation/decorator_utils.js"); function optional() { return function (target, targetKey, index) { var metadata = new metadata_1.Metadata(METADATA_KEY.OPTIONAL_TAG, true); if (typeof index === "number") { decorator_utils_1.tagParameter(target, targetKey, index, metadata); } else { decorator_utils_1.tagProperty(target, targetKey, metadata); } }; } exports.optional = optional; /***/ }), /***/ "./node_modules/inversify/lib/annotation/post_construct.js": /*!*****************************************************************!*\ !*** ./node_modules/inversify/lib/annotation/post_construct.js ***! \*****************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var ERRORS_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js"); var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js"); var metadata_1 = __webpack_require__(/*! ../planning/metadata */ "./node_modules/inversify/lib/planning/metadata.js"); function postConstruct() { return function (target, propertyKey, descriptor) { var metadata = new metadata_1.Metadata(METADATA_KEY.POST_CONSTRUCT, propertyKey); if (Reflect.hasOwnMetadata(METADATA_KEY.POST_CONSTRUCT, target.constructor)) { throw new Error(ERRORS_MSGS.MULTIPLE_POST_CONSTRUCT_METHODS); } Reflect.defineMetadata(METADATA_KEY.POST_CONSTRUCT, metadata, target.constructor); }; } exports.postConstruct = postConstruct; /***/ }), /***/ "./node_modules/inversify/lib/annotation/tagged.js": /*!*********************************************************!*\ !*** ./node_modules/inversify/lib/annotation/tagged.js ***! \*********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var metadata_1 = __webpack_require__(/*! ../planning/metadata */ "./node_modules/inversify/lib/planning/metadata.js"); var decorator_utils_1 = __webpack_require__(/*! ./decorator_utils */ "./node_modules/inversify/lib/annotation/decorator_utils.js"); function tagged(metadataKey, metadataValue) { return function (target, targetKey, index) { var metadata = new metadata_1.Metadata(metadataKey, metadataValue); if (typeof index === "number") { decorator_utils_1.tagParameter(target, targetKey, index, metadata); } else { decorator_utils_1.tagProperty(target, targetKey, metadata); } }; } exports.tagged = tagged; /***/ }), /***/ "./node_modules/inversify/lib/annotation/target_name.js": /*!**************************************************************!*\ !*** ./node_modules/inversify/lib/annotation/target_name.js ***! \**************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js"); var metadata_1 = __webpack_require__(/*! ../planning/metadata */ "./node_modules/inversify/lib/planning/metadata.js"); var decorator_utils_1 = __webpack_require__(/*! ./decorator_utils */ "./node_modules/inversify/lib/annotation/decorator_utils.js"); function targetName(name) { return function (target, targetKey, index) { var metadata = new metadata_1.Metadata(METADATA_KEY.NAME_TAG, name); decorator_utils_1.tagParameter(target, targetKey, index, metadata); }; } exports.targetName = targetName; /***/ }), /***/ "./node_modules/inversify/lib/annotation/unmanaged.js": /*!************************************************************!*\ !*** ./node_modules/inversify/lib/annotation/unmanaged.js ***! \************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js"); var metadata_1 = __webpack_require__(/*! ../planning/metadata */ "./node_modules/inversify/lib/planning/metadata.js"); var decorator_utils_1 = __webpack_require__(/*! ./decorator_utils */ "./node_modules/inversify/lib/annotation/decorator_utils.js"); function unmanaged() { return function (target, targetKey, index) { var metadata = new metadata_1.Metadata(METADATA_KEY.UNMANAGED_TAG, true); decorator_utils_1.tagParameter(target, targetKey, index, metadata); }; } exports.unmanaged = unmanaged; /***/ }), /***/ "./node_modules/inversify/lib/bindings/binding.js": /*!********************************************************!*\ !*** ./node_modules/inversify/lib/bindings/binding.js ***! \********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var literal_types_1 = __webpack_require__(/*! ../constants/literal_types */ "./node_modules/inversify/lib/constants/literal_types.js"); var id_1 = __webpack_require__(/*! ../utils/id */ "./node_modules/inversify/lib/utils/id.js"); var Binding = (function () { function Binding(serviceIdentifier, scope) { this.id = id_1.id(); this.activated = false; this.serviceIdentifier = serviceIdentifier; this.scope = scope; this.type = literal_types_1.BindingTypeEnum.Invalid; this.constraint = function (request) { return true; }; this.implementationType = null; this.cache = null; this.factory = null; this.provider = null; this.onActivation = null; this.dynamicValue = null; } Binding.prototype.clone = function () { var clone = new Binding(this.serviceIdentifier, this.scope); clone.activated = false; clone.implementationType = this.implementationType; clone.dynamicValue = this.dynamicValue; clone.scope = this.scope; clone.type = this.type; clone.factory = this.factory; clone.provider = this.provider; clone.constraint = this.constraint; clone.onActivation = this.onActivation; clone.cache = this.cache; return clone; }; return Binding; }()); exports.Binding = Binding; /***/ }), /***/ "./node_modules/inversify/lib/bindings/binding_count.js": /*!**************************************************************!*\ !*** ./node_modules/inversify/lib/bindings/binding_count.js ***! \**************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var BindingCount = { MultipleBindingsAvailable: 2, NoBindingsAvailable: 0, OnlyOneBindingAvailable: 1 }; exports.BindingCount = BindingCount; /***/ }), /***/ "./node_modules/inversify/lib/constants/error_msgs.js": /*!************************************************************!*\ !*** ./node_modules/inversify/lib/constants/error_msgs.js ***! \************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DUPLICATED_INJECTABLE_DECORATOR = "Cannot apply @injectable decorator multiple times."; exports.DUPLICATED_METADATA = "Metadata key was used more than once in a parameter:"; exports.NULL_ARGUMENT = "NULL argument"; exports.KEY_NOT_FOUND = "Key Not Found"; exports.AMBIGUOUS_MATCH = "Ambiguous match found for serviceIdentifier:"; exports.CANNOT_UNBIND = "Could not unbind serviceIdentifier:"; exports.NOT_REGISTERED = "No matching bindings found for serviceIdentifier:"; exports.MISSING_INJECTABLE_ANNOTATION = "Missing required @injectable annotation in:"; exports.MISSING_INJECT_ANNOTATION = "Missing required @inject or @multiInject annotation in:"; exports.UNDEFINED_INJECT_ANNOTATION = function (name) { return "@inject called with undefined this could mean that the class " + name + " has " + "a circular dependency problem. You can use a LazyServiceIdentifer to " + "overcome this limitation."; }; exports.CIRCULAR_DEPENDENCY = "Circular dependency found:"; exports.NOT_IMPLEMENTED = "Sorry, this feature is not fully implemented yet."; exports.INVALID_BINDING_TYPE = "Invalid binding type:"; exports.NO_MORE_SNAPSHOTS_AVAILABLE = "No snapshot available to restore."; exports.INVALID_MIDDLEWARE_RETURN = "Invalid return type in middleware. Middleware must return!"; exports.INVALID_FUNCTION_BINDING = "Value provided to function binding must be a function!"; exports.INVALID_TO_SELF_VALUE = "The toSelf function can only be applied when a constructor is " + "used as service identifier"; exports.INVALID_DECORATOR_OPERATION = "The @inject @multiInject @tagged and @named decorators " + "must be applied to the parameters of a class constructor or a class property."; exports.ARGUMENTS_LENGTH_MISMATCH = function () { var values = []; for (var _i = 0; _i < arguments.length; _i++) { values[_i] = arguments[_i]; } return "The number of constructor arguments in the derived class " + (values[0] + " must be >= than the number of constructor arguments of its base class."); }; exports.CONTAINER_OPTIONS_MUST_BE_AN_OBJECT = "Invalid Container constructor argument. Container options " + "must be an object."; exports.CONTAINER_OPTIONS_INVALID_DEFAULT_SCOPE = "Invalid Container option. Default scope must " + "be a string ('singleton' or 'transient')."; exports.CONTAINER_OPTIONS_INVALID_AUTO_BIND_INJECTABLE = "Invalid Container option. Auto bind injectable must " + "be a boolean"; exports.CONTAINER_OPTIONS_INVALID_SKIP_BASE_CHECK = "Invalid Container option. Skip base check must " + "be a boolean"; exports.MULTIPLE_POST_CONSTRUCT_METHODS = "Cannot apply @postConstruct decorator multiple times in the same class"; exports.POST_CONSTRUCT_ERROR = function () { var values = []; for (var _i = 0; _i < arguments.length; _i++) { values[_i] = arguments[_i]; } return "@postConstruct error in class " + values[0] + ": " + values[1]; }; exports.CIRCULAR_DEPENDENCY_IN_FACTORY = function () { var values = []; for (var _i = 0; _i < arguments.length; _i++) { values[_i] = arguments[_i]; } return "It looks like there is a circular dependency " + ("in one of the '" + values[0] + "' bindings. Please investigate bindings with") + ("service identifier '" + values[1] + "'."); }; exports.STACK_OVERFLOW = "Maximum call stack size exceeded"; /***/ }), /***/ "./node_modules/inversify/lib/constants/literal_types.js": /*!***************************************************************!*\ !*** ./node_modules/inversify/lib/constants/literal_types.js ***! \***************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var BindingScopeEnum = { Request: "Request", Singleton: "Singleton", Transient: "Transient" }; exports.BindingScopeEnum = BindingScopeEnum; var BindingTypeEnum = { ConstantValue: "ConstantValue", Constructor: "Constructor", DynamicValue: "DynamicValue", Factory: "Factory", Function: "Function", Instance: "Instance", Invalid: "Invalid", Provider: "Provider" }; exports.BindingTypeEnum = BindingTypeEnum; var TargetTypeEnum = { ClassProperty: "ClassProperty", ConstructorArgument: "ConstructorArgument", Variable: "Variable" }; exports.TargetTypeEnum = TargetTypeEnum; /***/ }), /***/ "./node_modules/inversify/lib/constants/metadata_keys.js": /*!***************************************************************!*\ !*** ./node_modules/inversify/lib/constants/metadata_keys.js ***! \***************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NAMED_TAG = "named"; exports.NAME_TAG = "name"; exports.UNMANAGED_TAG = "unmanaged"; exports.OPTIONAL_TAG = "optional"; exports.INJECT_TAG = "inject"; exports.MULTI_INJECT_TAG = "multi_inject"; exports.TAGGED = "inversify:tagged"; exports.TAGGED_PROP = "inversify:tagged_props"; exports.PARAM_TYPES = "inversify:paramtypes"; exports.DESIGN_PARAM_TYPES = "design:paramtypes"; exports.POST_CONSTRUCT = "post_construct"; /***/ }), /***/ "./node_modules/inversify/lib/container/container.js": /*!***********************************************************!*\ !*** ./node_modules/inversify/lib/container/container.js ***! \***********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [0, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); var binding_1 = __webpack_require__(/*! ../bindings/binding */ "./node_modules/inversify/lib/bindings/binding.js"); var ERROR_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js"); var literal_types_1 = __webpack_require__(/*! ../constants/literal_types */ "./node_modules/inversify/lib/constants/literal_types.js"); var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js"); var metadata_reader_1 = __webpack_require__(/*! ../planning/metadata_reader */ "./node_modules/inversify/lib/planning/metadata_reader.js"); var planner_1 = __webpack_require__(/*! ../planning/planner */ "./node_modules/inversify/lib/planning/planner.js"); var resolver_1 = __webpack_require__(/*! ../resolution/resolver */ "./node_modules/inversify/lib/resolution/resolver.js"); var binding_to_syntax_1 = __webpack_require__(/*! ../syntax/binding_to_syntax */ "./node_modules/inversify/lib/syntax/binding_to_syntax.js"); var id_1 = __webpack_require__(/*! ../utils/id */ "./node_modules/inversify/lib/utils/id.js"); var serialization_1 = __webpack_require__(/*! ../utils/serialization */ "./node_modules/inversify/lib/utils/serialization.js"); var container_snapshot_1 = __webpack_require__(/*! ./container_snapshot */ "./node_modules/inversify/lib/container/container_snapshot.js"); var lookup_1 = __webpack_require__(/*! ./lookup */ "./node_modules/inversify/lib/container/lookup.js"); var Container = (function () { function Container(containerOptions) { var options = containerOptions || {}; if (typeof options !== "object") { throw new Error("" + ERROR_MSGS.CONTAINER_OPTIONS_MUST_BE_AN_OBJECT); } if (options.defaultScope === undefined) { options.defaultScope = literal_types_1.BindingScopeEnum.Transient; } else if (options.defaultScope !== literal_types_1.BindingScopeEnum.Singleton && options.defaultScope !== literal_types_1.BindingScopeEnum.Transient && options.defaultScope !== literal_types_1.BindingScopeEnum.Request) { throw new Error("" + ERROR_MSGS.CONTAINER_OPTIONS_INVALID_DEFAULT_SCOPE); } if (options.autoBindInjectable === undefined) { options.autoBindInjectable = false; } else if (typeof options.autoBindInjectable !== "boolean") { throw new Error("" + ERROR_MSGS.CONTAINER_OPTIONS_INVALID_AUTO_BIND_INJECTABLE); } if (options.skipBaseClassChecks === undefined) { options.skipBaseClassChecks = false; } else if (typeof options.skipBaseClassChecks !== "boolean") { throw new Error("" + ERROR_MSGS.CONTAINER_OPTIONS_INVALID_SKIP_BASE_CHECK); } this.options = { autoBindInjectable: options.autoBindInjectable, defaultScope: options.defaultScope, skipBaseClassChecks: options.skipBaseClassChecks }; this.id = id_1.id(); this._bindingDictionary = new lookup_1.Lookup(); this._snapshots = []; this._middleware = null; this.parent = null; this._metadataReader = new metadata_reader_1.MetadataReader(); } Container.merge = function (container1, container2) { var container = new Container(); var bindingDictionary = planner_1.getBindingDictionary(container); var bindingDictionary1 = planner_1.getBindingDictionary(container1); var bindingDictionary2 = planner_1.getBindingDictionary(container2); function copyDictionary(origin, destination) { origin.traverse(function (key, value) { value.forEach(function (binding) { destination.add(binding.serviceIdentifier, binding.clone()); }); }); } copyDictionary(bindingDictionary1, bindingDictionary); copyDictionary(bindingDictionary2, bindingDictionary); return container; }; Container.prototype.load = function () { var modules = []; for (var _i = 0; _i < arguments.length; _i++) { modules[_i] = arguments[_i]; } var getHelpers = this._getContainerModuleHelpersFactory(); for (var _a = 0, modules_1 = modules; _a < modules_1.length; _a++) { var currentModule = modules_1[_a]; var containerModuleHelpers = getHelpers(currentModule.id); currentModule.registry(containerModuleHelpers.bindFunction, containerModuleHelpers.unbindFunction, containerModuleHelpers.isboundFunction, containerModuleHelpers.rebindFunction); } }; Container.prototype.loadAsync = function () { var modules = []; for (var _i = 0; _i < arguments.length; _i++) { modules[_i] = arguments[_i]; } return __awaiter(this, void 0, void 0, function () { var getHelpers, _a, modules_2, currentModule, containerModuleHelpers; return __generator(this, function (_b) { switch (_b.label) { case 0: getHelpers = this._getContainerModuleHelpersFactory(); _a = 0, modules_2 = modules; _b.label = 1; case 1: if (!(_a < modules_2.length)) return [3, 4]; currentModule = modules_2[_a]; containerModuleHelpers = getHelpers(currentModule.id); return [4, currentModule.registry(containerModuleHelpers.bindFunction, containerModuleHelpers.unbindFunction, containerModuleHelpers.isboundFunction, containerModuleHelpers.rebindFunction)]; case 2: _b.sent(); _b.label = 3; case 3: _a++; return [3, 1]; case 4: return [2]; } }); }); }; Container.prototype.unload = function () { var _this = this; var modules = []; for (var _i = 0; _i < arguments.length; _i++) { modules[_i] = arguments[_i]; } var conditionFactory = function (expected) { return function (item) { return item.moduleId === expected; }; }; modules.forEach(function (module) { var condition = conditionFactory(module.id); _this._bindingDictionary.removeByCondition(condition); }); }; Container.prototype.bind = function (serviceIdentifier) { var scope = this.options.defaultScope || literal_types_1.BindingScopeEnum.Transient; var binding = new binding_1.Binding(serviceIdentifier, scope); this._bindingDictionary.add(serviceIdentifier, binding); return new binding_to_syntax_1.BindingToSyntax(binding); }; Container.prototype.rebind = function (serviceIdentifier) { this.unbind(serviceIdentifier); return this.bind(serviceIdentifier); }; Container.prototype.unbind = function (serviceIdentifier) { try { this._bindingDictionary.remove(serviceIdentifier); } catch (e) { throw new Error(ERROR_MSGS.CANNOT_UNBIND + " " + serialization_1.getServiceIdentifierAsString(serviceIdentifier)); } }; Container.prototype.unbindAll = function () { this._bindingDictionary = new lookup_1.Lookup(); }; Container.prototype.isBound = function (serviceIdentifier) { var bound = this._bindingDictionary.hasKey(serviceIdentifier); if (!bound && this.parent) { bound = this.parent.isBound(serviceIdentifier); } return bound; }; Container.prototype.isBoundNamed = function (serviceIdentifier, named) { return this.isBoundTagged(serviceIdentifier, METADATA_KEY.NAMED_TAG, named); }; Container.prototype.isBoundTagged = function (serviceIdentifier, key, value) { var bound = false; if (this._bindingDictionary.hasKey(serviceIdentifier)) { var bindings = this._bindingDictionary.get(serviceIdentifier); var request_1 = planner_1.createMockRequest(this, serviceIdentifier, key, value); bound = bindings.some(function (b) { return b.constraint(request_1); }); } if (!bound && this.parent) { bound = this.parent.isBoundTagged(serviceIdentifier, key, value); } return bound; }; Container.prototype.snapshot = function () { this._snapshots.push(container_snapshot_1.ContainerSnapshot.of(this._bindingDictionary.clone(), this._middleware)); }; Container.prototype.restore = function () { var snapshot = this._snapshots.pop(); if (snapshot === undefined) { throw new Error(ERROR_MSGS.NO_MORE_SNAPSHOTS_AVAILABLE); } this._bindingDictionary = snapshot.bindings; this._middleware = snapshot.middleware; }; Container.prototype.createChild = function (containerOptions) { var child = new Container(containerOptions || this.options); child.parent = this; return child; }; Container.prototype.applyMiddleware = function () { var middlewares = []; for (var _i = 0; _i < arguments.length; _i++) { middlewares[_i] = arguments[_i]; } var initial = (this._middleware) ? this._middleware : this._planAndResolve(); this._middleware = middlewares.reduce(function (prev, curr) { return curr(prev); }, initial); }; Container.prototype.applyCustomMetadataReader = function (metadataReader) { this._metadataReader = metadataReader; }; Container.prototype.get = function (serviceIdentifier) { return this._get(false, false, literal_types_1.TargetTypeEnum.Variable, serviceIdentifier); }; Container.prototype.getTagged = function (serviceIdentifier, key, value) { return this._get(false, false, literal_types_1.TargetTypeEnum.Variable, serviceIdentifier, key, value); }; Container.prototype.getNamed = function (serviceIdentifier, named) { return this.getTagged(serviceIdentifier, METADATA_KEY.NAMED_TAG, named); }; Container.prototype.getAll = function (serviceIdentifier) { return this._get(true, true, literal_types_1.TargetTypeEnum.Variable, serviceIdentifier); }; Container.prototype.getAllTagged = function (serviceIdentifier, key, value) { return this._get(false, true, literal_types_1.TargetTypeEnum.Variable, serviceIdentifier, key, value); }; Container.prototype.getAllNamed = function (serviceIdentifier, named) { return this.getAllTagged(serviceIdentifier, METADATA_KEY.NAMED_TAG, named); }; Container.prototype.resolve = function (constructorFunction) { var tempContainer = this.createChild(); tempContainer.bind(constructorFunction).toSelf(); return tempContainer.get(constructorFunction); }; Container.prototype._getContainerModuleHelpersFactory = function () { var _this = this; var setModuleId = function (bindingToSyntax, moduleId) { bindingToSyntax._binding.moduleId = moduleId; }; var getBindFunction = function (moduleId) { return function (serviceIdentifier) { var _bind = _this.bind.bind(_this); var bindingToSyntax = _bind(serviceIdentifier); setModuleId(bindingToSyntax, moduleId); return bindingToSyntax; }; }; var getUnbindFunction = function (moduleId) { return function (serviceIdentifier) { var _unbind = _this.unbind.bind(_this); _unbind(serviceIdentifier); }; }; var getIsboundFunction = function (moduleId) { return function (serviceIdentifier) { var _isBound = _this.isBound.bind(_this); return _isBound(serviceIdentifier); }; }; var getRebindFunction = function (moduleId) { return function (serviceIdentifier) { var _rebind = _this.rebind.bind(_this); var bindingToSyntax = _rebind(serviceIdentifier); setModuleId(bindingToSyntax, moduleId); return bindingToSyntax; }; }; return function (mId) { return ({ bindFunction: getBindFunction(mId), isboundFunction: getIsboundFunction(mId), rebindFunction: getRebindFunction(mId), unbindFunction: getUnbindFunction(mId) }); }; }; Container.prototype._get = function (avoidConstraints, isMultiInject, targetType, serviceIdentifier, key, value) { var result = null; var defaultArgs = { avoidConstraints: avoidConstraints, contextInterceptor: function (context) { return context; }, isMultiInject: isMultiInject, key: key, serviceIdentifier: serviceIdentifier, targetType: targetType, value: value }; if (this._middleware) { result = this._middleware(defaultArgs); if (result === undefined || result === null) { throw new Error(ERROR_MSGS.INVALID_MIDDLEWARE_RETURN); } } else { result = this._planAndResolve()(defaultArgs); } return result; }; Container.prototype._planAndResolve = function () { var _this = this; return function (args) { var context = planner_1.plan(_this._metadataReader, _this, args.isMultiInject, args.targetType, args.serviceIdentifier, args.key, args.value, args.avoidConstraints); context = args.contextInterceptor(context); var result = resolver_1.resolve(context); return result; }; }; return Container; }()); exports.Container = Container; /***/ }), /***/ "./node_modules/inversify/lib/container/container_module.js": /*!******************************************************************!*\ !*** ./node_modules/inversify/lib/container/container_module.js ***! \******************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var id_1 = __webpack_require__(/*! ../utils/id */ "./node_modules/inversify/lib/utils/id.js"); var ContainerModule = (function () { function ContainerModule(registry) { this.id = id_1.id(); this.registry = registry; } return ContainerModule; }()); exports.ContainerModule = ContainerModule; var AsyncContainerModule = (function () { function AsyncContainerModule(registry) { this.id = id_1.id(); this.registry = registry; } return AsyncContainerModule; }()); exports.AsyncContainerModule = AsyncContainerModule; /***/ }), /***/ "./node_modules/inversify/lib/container/container_snapshot.js": /*!********************************************************************!*\ !*** ./node_modules/inversify/lib/container/container_snapshot.js ***! \********************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var ContainerSnapshot = (function () { function ContainerSnapshot() { } ContainerSnapshot.of = function (bindings, middleware) { var snapshot = new ContainerSnapshot(); snapshot.bindings = bindings; snapshot.middleware = middleware; return snapshot; }; return ContainerSnapshot; }()); exports.ContainerSnapshot = ContainerSnapshot; /***/ }), /***/ "./node_modules/inversify/lib/container/lookup.js": /*!********************************************************!*\ !*** ./node_modules/inversify/lib/container/lookup.js ***! \********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var ERROR_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js"); var Lookup = (function () { function Lookup() { this._map = new Map(); } Lookup.prototype.getMap = function () { return this._map; }; Lookup.prototype.add = function (serviceIdentifier, value) { if (serviceIdentifier === null || serviceIdentifier === undefined) { throw new Error(ERROR_MSGS.NULL_ARGUMENT); } if (value === null || value === undefined) { throw new Error(ERROR_MSGS.NULL_ARGUMENT); } var entry = this._map.get(serviceIdentifier); if (entry !== undefined) { entry.push(value); this._map.set(serviceIdentifier, entry); } else { this._map.set(serviceIdentifier, [value]); } }; Lookup.prototype.get = function (serviceIdentifier) { if (serviceIdentifier === null || serviceIdentifier === undefined) { throw new Error(ERROR_MSGS.NULL_ARGUMENT); } var entry = this._map.get(serviceIdentifier); if (entry !== undefined) { return entry; } else { throw new Error(ERROR_MSGS.KEY_NOT_FOUND); } }; Lookup.prototype.remove = function (serviceIdentifier) { if (serviceIdentifier === null || serviceIdentifier === undefined) { throw new Error(ERROR_MSGS.NULL_ARGUMENT); } if (!this._map.delete(serviceIdentifier)) { throw new Error(ERROR_MSGS.KEY_NOT_FOUND); } }; Lookup.prototype.removeByCondition = function (condition) { var _this = this; this._map.forEach(function (entries, key) { var updatedEntries = entries.filter(function (entry) { return !condition(entry); }); if (updatedEntries.length > 0) { _this._map.set(key, updatedEntries); } else { _this._map.delete(key); } }); }; Lookup.prototype.hasKey = function (serviceIdentifier) { if (serviceIdentifier === null || serviceIdentifier === undefined) { throw new Error(ERROR_MSGS.NULL_ARGUMENT); } return this._map.has(serviceIdentifier); }; Lookup.prototype.clone = function () { var copy = new Lookup(); this._map.forEach(function (value, key) { value.forEach(function (b) { return copy.add(key, b.clone()); }); }); return copy; }; Lookup.prototype.traverse = function (func) { this._map.forEach(function (value, key) { func(key, value); }); }; return Lookup; }()); exports.Lookup = Lookup; /***/ }), /***/ "./node_modules/inversify/lib/inversify.js": /*!*************************************************!*\ !*** ./node_modules/inversify/lib/inversify.js ***! \*************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var keys = __webpack_require__(/*! ./constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js"); exports.METADATA_KEY = keys; var container_1 = __webpack_require__(/*! ./container/container */ "./node_modules/inversify/lib/container/container.js"); exports.Container = container_1.Container; var literal_types_1 = __webpack_require__(/*! ./constants/literal_types */ "./node_modules/inversify/lib/constants/literal_types.js"); exports.BindingScopeEnum = literal_types_1.BindingScopeEnum; exports.BindingTypeEnum = literal_types_1.BindingTypeEnum; exports.TargetTypeEnum = literal_types_1.TargetTypeEnum; var container_module_1 = __webpack_require__(/*! ./container/container_module */ "./node_modules/inversify/lib/container/container_module.js"); exports.AsyncContainerModule = container_module_1.AsyncContainerModule; exports.ContainerModule = container_module_1.ContainerModule; var injectable_1 = __webpack_require__(/*! ./annotation/injectable */ "./node_modules/inversify/lib/annotation/injectable.js"); exports.injectable = injectable_1.injectable; var tagged_1 = __webpack_require__(/*! ./annotation/tagged */ "./node_modules/inversify/lib/annotation/tagged.js"); exports.tagged = tagged_1.tagged; var named_1 = __webpack_require__(/*! ./annotation/named */ "./node_modules/inversify/lib/annotation/named.js"); exports.named = named_1.named; var inject_1 = __webpack_require__(/*! ./annotation/inject */ "./node_modules/inversify/lib/annotation/inject.js"); exports.inject = inject_1.inject; exports.LazyServiceIdentifer = inject_1.LazyServiceIdentifer; var optional_1 = __webpack_require__(/*! ./annotation/optional */ "./node_modules/inversify/lib/annotation/optional.js"); exports.optional = optional_1.optional; var unmanaged_1 = __webpack_require__(/*! ./annotation/unmanaged */ "./node_modules/inversify/lib/annotation/unmanaged.js"); exports.unmanaged = unmanaged_1.unmanaged; var multi_inject_1 = __webpack_require__(/*! ./annotation/multi_inject */ "./node_modules/inversify/lib/annotation/multi_inject.js"); exports.multiInject = multi_inject_1.multiInject; var target_name_1 = __webpack_require__(/*! ./annotation/target_name */ "./node_modules/inversify/lib/annotation/target_name.js"); exports.targetName = target_name_1.targetName; var post_construct_1 = __webpack_require__(/*! ./annotation/post_construct */ "./node_modules/inversify/lib/annotation/post_construct.js"); exports.postConstruct = post_construct_1.postConstruct; var metadata_reader_1 = __webpack_require__(/*! ./planning/metadata_reader */ "./node_modules/inversify/lib/planning/metadata_reader.js"); exports.MetadataReader = metadata_reader_1.MetadataReader; var id_1 = __webpack_require__(/*! ./utils/id */ "./node_modules/inversify/lib/utils/id.js"); exports.id = id_1.id; var decorator_utils_1 = __webpack_require__(/*! ./annotation/decorator_utils */ "./node_modules/inversify/lib/annotation/decorator_utils.js"); exports.decorate = decorator_utils_1.decorate; var constraint_helpers_1 = __webpack_require__(/*! ./syntax/constraint_helpers */ "./node_modules/inversify/lib/syntax/constraint_helpers.js"); exports.traverseAncerstors = constraint_helpers_1.traverseAncerstors; exports.taggedConstraint = constraint_helpers_1.taggedConstraint; exports.namedConstraint = constraint_helpers_1.namedConstraint; exports.typeConstraint = constraint_helpers_1.typeConstraint; var serialization_1 = __webpack_require__(/*! ./utils/serialization */ "./node_modules/inversify/lib/utils/serialization.js"); exports.getServiceIdentifierAsString = serialization_1.getServiceIdentifierAsString; var binding_utils_1 = __webpack_require__(/*! ./utils/binding_utils */ "./node_modules/inversify/lib/utils/binding_utils.js"); exports.multiBindToService = binding_utils_1.multiBindToService; /***/ }), /***/ "./node_modules/inversify/lib/planning/context.js": /*!********************************************************!*\ !*** ./node_modules/inversify/lib/planning/context.js ***! \********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var id_1 = __webpack_require__(/*! ../utils/id */ "./node_modules/inversify/lib/utils/id.js"); var Context = (function () { function Context(container) { this.id = id_1.id(); this.container = container; } Context.prototype.addPlan = function (plan) { this.plan = plan; }; Context.prototype.setCurrentRequest = function (currentRequest) { this.currentRequest = currentRequest; }; return Context; }()); exports.Context = Context; /***/ }), /***/ "./node_modules/inversify/lib/planning/metadata.js": /*!*********************************************************!*\ !*** ./node_modules/inversify/lib/planning/metadata.js ***! \*********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js"); var Metadata = (function () { function Metadata(key, value) { this.key = key; this.value = value; } Metadata.prototype.toString = function () { if (this.key === METADATA_KEY.NAMED_TAG) { return "named: " + this.value.toString() + " "; } else { return "tagged: { key:" + this.key.toString() + ", value: " + this.value + " }"; } }; return Metadata; }()); exports.Metadata = Metadata; /***/ }), /***/ "./node_modules/inversify/lib/planning/metadata_reader.js": /*!****************************************************************!*\ !*** ./node_modules/inversify/lib/planning/metadata_reader.js ***! \****************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js"); var MetadataReader = (function () { function MetadataReader() { } MetadataReader.prototype.getConstructorMetadata = function (constructorFunc) { var compilerGeneratedMetadata = Reflect.getMetadata(METADATA_KEY.PARAM_TYPES, constructorFunc); var userGeneratedMetadata = Reflect.getMetadata(METADATA_KEY.TAGGED, constructorFunc); return { compilerGeneratedMetadata: compilerGeneratedMetadata, userGeneratedMetadata: userGeneratedMetadata || {} }; }; MetadataReader.prototype.getPropertiesMetadata = function (constructorFunc) { var userGeneratedMetadata = Reflect.getMetadata(METADATA_KEY.TAGGED_PROP, constructorFunc) || []; return userGeneratedMetadata; }; return MetadataReader; }()); exports.MetadataReader = MetadataReader; /***/ }), /***/ "./node_modules/inversify/lib/planning/plan.js": /*!*****************************************************!*\ !*** ./node_modules/inversify/lib/planning/plan.js ***! \*****************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var Plan = (function () { function Plan(parentContext, rootRequest) { this.parentContext = parentContext; this.rootRequest = rootRequest; } return Plan; }()); exports.Plan = Plan; /***/ }), /***/ "./node_modules/inversify/lib/planning/planner.js": /*!********************************************************!*\ !*** ./node_modules/inversify/lib/planning/planner.js ***! \********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var binding_count_1 = __webpack_require__(/*! ../bindings/binding_count */ "./node_modules/inversify/lib/bindings/binding_count.js"); var ERROR_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js"); var literal_types_1 = __webpack_require__(/*! ../constants/literal_types */ "./node_modules/inversify/lib/constants/literal_types.js"); var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js"); var exceptions_1 = __webpack_require__(/*! ../utils/exceptions */ "./node_modules/inversify/lib/utils/exceptions.js"); var serialization_1 = __webpack_require__(/*! ../utils/serialization */ "./node_modules/inversify/lib/utils/serialization.js"); var context_1 = __webpack_require__(/*! ./context */ "./node_modules/inversify/lib/planning/context.js"); var metadata_1 = __webpack_require__(/*! ./metadata */ "./node_modules/inversify/lib/planning/metadata.js"); var plan_1 = __webpack_require__(/*! ./plan */ "./node_modules/inversify/lib/planning/plan.js"); var reflection_utils_1 = __webpack_require__(/*! ./reflection_utils */ "./node_modules/inversify/lib/planning/reflection_utils.js"); var request_1 = __webpack_require__(/*! ./request */ "./node_modules/inversify/lib/planning/request.js"); var target_1 = __webpack_require__(/*! ./target */ "./node_modules/inversify/lib/planning/target.js"); function getBindingDictionary(cntnr) { return cntnr._bindingDictionary; } exports.getBindingDictionary = getBindingDictionary; function _createTarget(isMultiInject, targetType, serviceIdentifier, name, key, value) { var metadataKey = isMultiInject ? METADATA_KEY.MULTI_INJECT_TAG : METADATA_KEY.INJECT_TAG; var injectMetadata = new metadata_1.Metadata(metadataKey, serviceIdentifier); var target = new target_1.Target(targetType, name, serviceIdentifier, injectMetadata); if (key !== undefined) { var tagMetadata = new metadata_1.Metadata(key, value); target.metadata.push(tagMetadata); } return target; } function _getActiveBindings(metadataReader, avoidConstraints, context, parentRequest, target) { var bindings = getBindings(context.container, target.serviceIdentifier); var activeBindings = []; if (bindings.length === binding_count_1.BindingCount.NoBindingsAvailable && context.container.options.autoBindInjectable && typeof target.serviceIdentifier === "function" && metadataReader.getConstructorMetadata(target.serviceIdentifier).compilerGeneratedMetadata) { context.container.bind(target.serviceIdentifier).toSelf(); bindings = getBindings(context.container, target.serviceIdentifier); } if (!avoidConstraints) { activeBindings = bindings.filter(function (binding) { var request = new request_1.Request(binding.serviceIdentifier, context, parentRequest, binding, target); return binding.constraint(request); }); } else { activeBindings = bindings; } _validateActiveBindingCount(target.serviceIdentifier, activeBindings, target, context.container); return activeBindings; } function _validateActiveBindingCount(serviceIdentifier, bindings, target, container) { switch (bindings.length) { case binding_count_1.BindingCount.NoBindingsAvailable: if (target.isOptional()) { return bindings; } else { var serviceIdentifierString = serialization_1.getServiceIdentifierAsString(serviceIdentifier); var msg = ERROR_MSGS.NOT_REGISTERED; msg += serialization_1.listMetadataForTarget(serviceIdentifierString, target); msg += serialization_1.listRegisteredBindingsForServiceIdentifier(container, serviceIdentifierString, getBindings); throw new Error(msg); } case binding_count_1.BindingCount.OnlyOneBindingAvailable: if (!target.isArray()) { return bindings; } case binding_count_1.BindingCount.MultipleBindingsAvailable: default: if (!target.isArray()) { var serviceIdentifierString = serialization_1.getServiceIdentifierAsString(serviceIdentifier); var msg = ERROR_MSGS.AMBIGUOUS_MATCH + " " + serviceIdentifierString; msg += serialization_1.listRegisteredBindingsForServiceIdentifier(container, serviceIdentifierString, getBindings); throw new Error(msg); } else { return bindings; } } } function _createSubRequests(metadataReader, avoidConstraints, serviceIdentifier, context, parentRequest, target) { var activeBindings; var childRequest; if (parentRequest === null) { activeBindings = _getActiveBindings(metadataReader, avoidConstraints, context, null, target); childRequest = new request_1.Request(serviceIdentifier, context, null, activeBindings, target); var thePlan = new plan_1.Plan(context, childRequest); context.addPlan(thePlan); } else { activeBindings = _getActiveBindings(metadataReader, avoidConstraints, context, parentRequest, target); childRequest = parentRequest.addChildRequest(target.serviceIdentifier, activeBindings, target); } activeBindings.forEach(function (binding) { var subChildRequest = null; if (target.isArray()) { subChildRequest = childRequest.addChildRequest(binding.serviceIdentifier, binding, target); } else { if (binding.cache) { return; } subChildRequest = childRequest; } if (binding.type === literal_types_1.BindingTypeEnum.Instance && binding.implementationType !== null) { var dependencies = reflection_utils_1.getDependencies(metadataReader, binding.implementationType); if (!context.container.options.skipBaseClassChecks) { var baseClassDependencyCount = reflection_utils_1.getBaseClassDependencyCount(metadataReader, binding.implementationType); if (dependencies.length < baseClassDependencyCount) { var error = ERROR_MSGS.ARGUMENTS_LENGTH_MISMATCH(reflection_utils_1.getFunctionName(binding.implementationType)); throw new Error(error); } } dependencies.forEach(function (dependency) { _createSubRequests(metadataReader, false, dependency.serviceIdentifier, context, subChildRequest, dependency); }); } }); } function getBindings(container, serviceIdentifier) { var bindings = []; var bindingDictionary = getBindingDictionary(container); if (bindingDictionary.hasKey(serviceIdentifier)) { bindings = bindingDictionary.get(serviceIdentifier); } else if (container.parent !== null) { bindings = getBindings(container.parent, serviceIdentifier); } return bindings; } function plan(metadataReader, container, isMultiInject, targetType, serviceIdentifier, key, value, avoidConstraints) { if (avoidConstraints === void 0) { avoidConstraints = false; } var context = new context_1.Context(container); var target = _createTarget(isMultiInject, targetType, serviceIdentifier, "", key, value); try { _createSubRequests(metadataReader, avoidConstraints, serviceIdentifier, context, null, target); return context; } catch (error) { if (exceptions_1.isStackOverflowExeption(error)) { if (context.plan) { serialization_1.circularDependencyToException(context.plan.rootRequest); } } throw error; } } exports.plan = plan; function createMockRequest(container, serviceIdentifier, key, value) { var target = new target_1.Target(literal_types_1.TargetTypeEnum.Variable, "", serviceIdentifier, new metadata_1.Metadata(key, value)); var context = new context_1.Context(container); var request = new request_1.Request(serviceIdentifier, context, null, [], target); return request; } exports.createMockRequest = createMockRequest; /***/ }), /***/ "./node_modules/inversify/lib/planning/queryable_string.js": /*!*****************************************************************!*\ !*** ./node_modules/inversify/lib/planning/queryable_string.js ***! \*****************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var QueryableString = (function () { function QueryableString(str) { this.str = str; } QueryableString.prototype.startsWith = function (searchString) { return this.str.indexOf(searchString) === 0; }; QueryableString.prototype.endsWith = function (searchString) { var reverseString = ""; var reverseSearchString = searchString.split("").reverse().join(""); reverseString = this.str.split("").reverse().join(""); return this.startsWith.call({ str: reverseString }, reverseSearchString); }; QueryableString.prototype.contains = function (searchString) { return (this.str.indexOf(searchString) !== -1); }; QueryableString.prototype.equals = function (compareString) { return this.str === compareString; }; QueryableString.prototype.value = function () { return this.str; }; return QueryableString; }()); exports.QueryableString = QueryableString; /***/ }), /***/ "./node_modules/inversify/lib/planning/reflection_utils.js": /*!*****************************************************************!*\ !*** ./node_modules/inversify/lib/planning/reflection_utils.js ***! \*****************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var inject_1 = __webpack_require__(/*! ../annotation/inject */ "./node_modules/inversify/lib/annotation/inject.js"); var ERROR_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js"); var literal_types_1 = __webpack_require__(/*! ../constants/literal_types */ "./node_modules/inversify/lib/constants/literal_types.js"); var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js"); var serialization_1 = __webpack_require__(/*! ../utils/serialization */ "./node_modules/inversify/lib/utils/serialization.js"); exports.getFunctionName = serialization_1.getFunctionName; var target_1 = __webpack_require__(/*! ./target */ "./node_modules/inversify/lib/planning/target.js"); function getDependencies(metadataReader, func) { var constructorName = serialization_1.getFunctionName(func); var targets = getTargets(metadataReader, constructorName, func, false); return targets; } exports.getDependencies = getDependencies; function getTargets(metadataReader, constructorName, func, isBaseClass) { var metadata = metadataReader.getConstructorMetadata(func); var serviceIdentifiers = metadata.compilerGeneratedMetadata; if (serviceIdentifiers === undefined) { var msg = ERROR_MSGS.MISSING_INJECTABLE_ANNOTATION + " " + constructorName + "."; throw new Error(msg); } var constructorArgsMetadata = metadata.userGeneratedMetadata; var keys = Object.keys(constructorArgsMetadata); var hasUserDeclaredUnknownInjections = (func.length === 0 && keys.length > 0); var iterations = (hasUserDeclaredUnknownInjections) ? keys.length : func.length; var constructorTargets = getConstructorArgsAsTargets(isBaseClass, constructorName, serviceIdentifiers, constructorArgsMetadata, iterations); var propertyTargets = getClassPropsAsTargets(metadataReader, func); var targets = constructorTargets.concat(propertyTargets); return targets; } function getConstructorArgsAsTarget(index, isBaseClass, constructorName, serviceIdentifiers, constructorArgsMetadata) { var targetMetadata = constructorArgsMetadata[index.toString()] || []; var metadata = formatTargetMetadata(targetMetadata); var isManaged = metadata.unmanaged !== true; var serviceIdentifier = serviceIdentifiers[index]; var injectIdentifier = (metadata.inject || metadata.multiInject); serviceIdentifier = (injectIdentifier) ? (injectIdentifier) : serviceIdentifier; if (serviceIdentifier instanceof inject_1.LazyServiceIdentifer) { serviceIdentifier = serviceIdentifier.unwrap(); } if (isManaged) { var isObject = serviceIdentifier === Object; var isFunction = serviceIdentifier === Function; var isUndefined = serviceIdentifier === undefined; var isUnknownType = (isObject || isFunction || isUndefined); if (!isBaseClass && isUnknownType) { var msg = ERROR_MSGS.MISSING_INJECT_ANNOTATION + " argument " + index + " in class " + constructorName + "."; throw new Error(msg); } var target = new target_1.Target(literal_types_1.TargetTypeEnum.ConstructorArgument, metadata.targetName, serviceIdentifier); target.metadata = targetMetadata; return target; } return null; } function getConstructorArgsAsTargets(isBaseClass, constructorName, serviceIdentifiers, constructorArgsMetadata, iterations) { var targets = []; for (var i = 0; i < iterations; i++) { var index = i; var target = getConstructorArgsAsTarget(index, isBaseClass, constructorName, serviceIdentifiers, constructorArgsMetadata); if (target !== null) { targets.push(target); } } return targets; } function getClassPropsAsTargets(metadataReader, constructorFunc) { var classPropsMetadata = metadataReader.getPropertiesMetadata(constructorFunc); var targets = []; var keys = Object.keys(classPropsMetadata); for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) { var key = keys_1[_i]; var targetMetadata = classPropsMetadata[key]; var metadata = formatTargetMetadata(classPropsMetadata[key]); var targetName = metadata.targetName || key; var serviceIdentifier = (metadata.inject || metadata.multiInject); var target = new target_1.Target(literal_types_1.TargetTypeEnum.ClassProperty, targetName, serviceIdentifier); target.metadata = targetMetadata; targets.push(target); } var baseConstructor = Object.getPrototypeOf(constructorFunc.prototype).constructor; if (baseConstructor !== Object) { var baseTargets = getClassPropsAsTargets(metadataReader, baseConstructor); targets = targets.concat(baseTargets); } return targets; } function getBaseClassDependencyCount(metadataReader, func) { var baseConstructor = Object.getPrototypeOf(func.prototype).constructor; if (baseConstructor !== Object) { var baseConstructorName = serialization_1.getFunctionName(baseConstructor); var targets = getTargets(metadataReader, baseConstructorName, baseConstructor, true); var metadata = targets.map(function (t) { return t.metadata.filter(function (m) { return m.key === METADATA_KEY.UNMANAGED_TAG; }); }); var unmanagedCount = [].concat.apply([], metadata).length; var dependencyCount = targets.length - unmanagedCount; if (dependencyCount > 0) { return dependencyCount; } else { return getBaseClassDependencyCount(metadataReader, baseConstructor); } } else { return 0; } } exports.getBaseClassDependencyCount = getBaseClassDependencyCount; function formatTargetMetadata(targetMetadata) { var targetMetadataMap = {}; targetMetadata.forEach(function (m) { targetMetadataMap[m.key.toString()] = m.value; }); return { inject: targetMetadataMap[METADATA_KEY.INJECT_TAG], multiInject: targetMetadataMap[METADATA_KEY.MULTI_INJECT_TAG], targetName: targetMetadataMap[METADATA_KEY.NAME_TAG], unmanaged: targetMetadataMap[METADATA_KEY.UNMANAGED_TAG] }; } /***/ }), /***/ "./node_modules/inversify/lib/planning/request.js": /*!********************************************************!*\ !*** ./node_modules/inversify/lib/planning/request.js ***! \********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var id_1 = __webpack_require__(/*! ../utils/id */ "./node_modules/inversify/lib/utils/id.js"); var Request = (function () { function Request(serviceIdentifier, parentContext, parentRequest, bindings, target) { this.id = id_1.id(); this.serviceIdentifier = serviceIdentifier; this.parentContext = parentContext; this.parentRequest = parentRequest; this.target = target; this.childRequests = []; this.bindings = (Array.isArray(bindings) ? bindings : [bindings]); this.requestScope = parentRequest === null ? new Map() : null; } Request.prototype.addChildRequest = function (serviceIdentifier, bindings, target) { var child = new Request(serviceIdentifier, this.parentContext, this, bindings, target); this.childRequests.push(child); return child; }; return Request; }()); exports.Request = Request; /***/ }), /***/ "./node_modules/inversify/lib/planning/target.js": /*!*******************************************************!*\ !*** ./node_modules/inversify/lib/planning/target.js ***! \*******************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js"); var id_1 = __webpack_require__(/*! ../utils/id */ "./node_modules/inversify/lib/utils/id.js"); var metadata_1 = __webpack_require__(/*! ./metadata */ "./node_modules/inversify/lib/planning/metadata.js"); var queryable_string_1 = __webpack_require__(/*! ./queryable_string */ "./node_modules/inversify/lib/planning/queryable_string.js"); var Target = (function () { function Target(type, name, serviceIdentifier, namedOrTagged) { this.id = id_1.id(); this.type = type; this.serviceIdentifier = serviceIdentifier; this.name = new queryable_string_1.QueryableString(name || ""); this.metadata = new Array(); var metadataItem = null; if (typeof namedOrTagged === "string") { metadataItem = new metadata_1.Metadata(METADATA_KEY.NAMED_TAG, namedOrTagged); } else if (namedOrTagged instanceof metadata_1.Metadata) { metadataItem = namedOrTagged; } if (metadataItem !== null) { this.metadata.push(metadataItem); } } Target.prototype.hasTag = function (key) { for (var _i = 0, _a = this.metadata; _i < _a.length; _i++) { var m = _a[_i]; if (m.key === key) { return true; } } return false; }; Target.prototype.isArray = function () { return this.hasTag(METADATA_KEY.MULTI_INJECT_TAG); }; Target.prototype.matchesArray = function (name) { return this.matchesTag(METADATA_KEY.MULTI_INJECT_TAG)(name); }; Target.prototype.isNamed = function () { return this.hasTag(METADATA_KEY.NAMED_TAG); }; Target.prototype.isTagged = function () { return this.metadata.some(function (m) { return (m.key !== METADATA_KEY.INJECT_TAG) && (m.key !== METADATA_KEY.MULTI_INJECT_TAG) && (m.key !== METADATA_KEY.NAME_TAG) && (m.key !== METADATA_KEY.UNMANAGED_TAG) && (m.key !== METADATA_KEY.NAMED_TAG); }); }; Target.prototype.isOptional = function () { return this.matchesTag(METADATA_KEY.OPTIONAL_TAG)(true); }; Target.prototype.getNamedTag = function () { if (this.isNamed()) { return this.metadata.filter(function (m) { return m.key === METADATA_KEY.NAMED_TAG; })[0]; } return null; }; Target.prototype.getCustomTags = function () { if (this.isTagged()) { return this.metadata.filter(function (m) { return (m.key !== METADATA_KEY.INJECT_TAG) && (m.key !== METADATA_KEY.MULTI_INJECT_TAG) && (m.key !== METADATA_KEY.NAME_TAG) && (m.key !== METADATA_KEY.UNMANAGED_TAG) && (m.key !== METADATA_KEY.NAMED_TAG); }); } return null; }; Target.prototype.matchesNamedTag = function (name) { return this.matchesTag(METADATA_KEY.NAMED_TAG)(name); }; Target.prototype.matchesTag = function (key) { var _this = this; return function (value) { for (var _i = 0, _a = _this.metadata; _i < _a.length; _i++) { var m = _a[_i]; if (m.key === key && m.value === value) { return true; } } return false; }; }; return Target; }()); exports.Target = Target; /***/ }), /***/ "./node_modules/inversify/lib/resolution/instantiation.js": /*!****************************************************************!*\ !*** ./node_modules/inversify/lib/resolution/instantiation.js ***! \****************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var error_msgs_1 = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js"); var literal_types_1 = __webpack_require__(/*! ../constants/literal_types */ "./node_modules/inversify/lib/constants/literal_types.js"); var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js"); function _injectProperties(instance, childRequests, resolveRequest) { var propertyInjectionsRequests = childRequests.filter(function (childRequest) { return (childRequest.target !== null && childRequest.target.type === literal_types_1.TargetTypeEnum.ClassProperty); }); var propertyInjections = propertyInjectionsRequests.map(resolveRequest); propertyInjectionsRequests.forEach(function (r, index) { var propertyName = ""; propertyName = r.target.name.value(); var injection = propertyInjections[index]; instance[propertyName] = injection; }); return instance; } function _createInstance(Func, injections) { return new (Func.bind.apply(Func, [void 0].concat(injections)))(); } function _postConstruct(constr, result) { if (Reflect.hasMetadata(METADATA_KEY.POST_CONSTRUCT, constr)) { var data = Reflect.getMetadata(METADATA_KEY.POST_CONSTRUCT, constr); try { result[data.value](); } catch (e) { throw new Error(error_msgs_1.POST_CONSTRUCT_ERROR(constr.name, e.message)); } } } function resolveInstance(constr, childRequests, resolveRequest) { var result = null; if (childRequests.length > 0) { var constructorInjectionsRequests = childRequests.filter(function (childRequest) { return (childRequest.target !== null && childRequest.target.type === literal_types_1.TargetTypeEnum.ConstructorArgument); }); var constructorInjections = constructorInjectionsRequests.map(resolveRequest); result = _createInstance(constr, constructorInjections); result = _injectProperties(result, childRequests, resolveRequest); } else { result = new constr(); } _postConstruct(constr, result); return result; } exports.resolveInstance = resolveInstance; /***/ }), /***/ "./node_modules/inversify/lib/resolution/resolver.js": /*!***********************************************************!*\ !*** ./node_modules/inversify/lib/resolution/resolver.js ***! \***********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var ERROR_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js"); var literal_types_1 = __webpack_require__(/*! ../constants/literal_types */ "./node_modules/inversify/lib/constants/literal_types.js"); var exceptions_1 = __webpack_require__(/*! ../utils/exceptions */ "./node_modules/inversify/lib/utils/exceptions.js"); var serialization_1 = __webpack_require__(/*! ../utils/serialization */ "./node_modules/inversify/lib/utils/serialization.js"); var instantiation_1 = __webpack_require__(/*! ./instantiation */ "./node_modules/inversify/lib/resolution/instantiation.js"); var invokeFactory = function (factoryType, serviceIdentifier, fn) { try { return fn(); } catch (error) { if (exceptions_1.isStackOverflowExeption(error)) { throw new Error(ERROR_MSGS.CIRCULAR_DEPENDENCY_IN_FACTORY(factoryType, serviceIdentifier.toString())); } else { throw error; } } }; var _resolveRequest = function (requestScope) { return function (request) { request.parentContext.setCurrentRequest(request); var bindings = request.bindings; var childRequests = request.childRequests; var targetIsAnArray = request.target && request.target.isArray(); var targetParentIsNotAnArray = !request.parentRequest || !request.parentRequest.target || !request.target || !request.parentRequest.target.matchesArray(request.target.serviceIdentifier); if (targetIsAnArray && targetParentIsNotAnArray) { return childRequests.map(function (childRequest) { var _f = _resolveRequest(requestScope); return _f(childRequest); }); } else { var result = null; if (request.target.isOptional() && bindings.length === 0) { return undefined; } var binding_1 = bindings[0]; var isSingleton = binding_1.scope === literal_types_1.BindingScopeEnum.Singleton; var isRequestSingleton = binding_1.scope === literal_types_1.BindingScopeEnum.Request; if (isSingleton && binding_1.activated) { return binding_1.cache; } if (isRequestSingleton && requestScope !== null && requestScope.has(binding_1.id)) { return requestScope.get(binding_1.id); } if (binding_1.type === literal_types_1.BindingTypeEnum.ConstantValue) { result = binding_1.cache; } else if (binding_1.type === literal_types_1.BindingTypeEnum.Function) { result = binding_1.cache; } else if (binding_1.type === literal_types_1.BindingTypeEnum.Constructor) { result = binding_1.implementationType; } else if (binding_1.type === literal_types_1.BindingTypeEnum.DynamicValue && binding_1.dynamicValue !== null) { result = invokeFactory("toDynamicValue", binding_1.serviceIdentifier, function () { return binding_1.dynamicValue(request.parentContext); }); } else if (binding_1.type === literal_types_1.BindingTypeEnum.Factory && binding_1.factory !== null) { result = invokeFactory("toFactory", binding_1.serviceIdentifier, function () { return binding_1.factory(request.parentContext); }); } else if (binding_1.type === literal_types_1.BindingTypeEnum.Provider && binding_1.provider !== null) { result = invokeFactory("toProvider", binding_1.serviceIdentifier, function () { return binding_1.provider(request.parentContext); }); } else if (binding_1.type === literal_types_1.BindingTypeEnum.Instance && binding_1.implementationType !== null) { result = instantiation_1.resolveInstance(binding_1.implementationType, childRequests, _resolveRequest(requestScope)); } else { var serviceIdentifier = serialization_1.getServiceIdentifierAsString(request.serviceIdentifier); throw new Error(ERROR_MSGS.INVALID_BINDING_TYPE + " " + serviceIdentifier); } if (typeof binding_1.onActivation === "function") { result = binding_1.onActivation(request.parentContext, result); } if (isSingleton) { binding_1.cache = result; binding_1.activated = true; } if (isRequestSingleton && requestScope !== null && !requestScope.has(binding_1.id)) { requestScope.set(binding_1.id, result); } return result; } }; }; function resolve(context) { var _f = _resolveRequest(context.plan.rootRequest.requestScope); return _f(context.plan.rootRequest); } exports.resolve = resolve; /***/ }), /***/ "./node_modules/inversify/lib/syntax/binding_in_syntax.js": /*!****************************************************************!*\ !*** ./node_modules/inversify/lib/syntax/binding_in_syntax.js ***! \****************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var literal_types_1 = __webpack_require__(/*! ../constants/literal_types */ "./node_modules/inversify/lib/constants/literal_types.js"); var binding_when_on_syntax_1 = __webpack_require__(/*! ./binding_when_on_syntax */ "./node_modules/inversify/lib/syntax/binding_when_on_syntax.js"); var BindingInSyntax = (function () { function BindingInSyntax(binding) { this._binding = binding; } BindingInSyntax.prototype.inRequestScope = function () { this._binding.scope = literal_types_1.BindingScopeEnum.Request; return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding); }; BindingInSyntax.prototype.inSingletonScope = function () { this._binding.scope = literal_types_1.BindingScopeEnum.Singleton; return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding); }; BindingInSyntax.prototype.inTransientScope = function () { this._binding.scope = literal_types_1.BindingScopeEnum.Transient; return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding); }; return BindingInSyntax; }()); exports.BindingInSyntax = BindingInSyntax; /***/ }), /***/ "./node_modules/inversify/lib/syntax/binding_in_when_on_syntax.js": /*!************************************************************************!*\ !*** ./node_modules/inversify/lib/syntax/binding_in_when_on_syntax.js ***! \************************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var binding_in_syntax_1 = __webpack_require__(/*! ./binding_in_syntax */ "./node_modules/inversify/lib/syntax/binding_in_syntax.js"); var binding_on_syntax_1 = __webpack_require__(/*! ./binding_on_syntax */ "./node_modules/inversify/lib/syntax/binding_on_syntax.js"); var binding_when_syntax_1 = __webpack_require__(/*! ./binding_when_syntax */ "./node_modules/inversify/lib/syntax/binding_when_syntax.js"); var BindingInWhenOnSyntax = (function () { function BindingInWhenOnSyntax(binding) { this._binding = binding; this._bindingWhenSyntax = new binding_when_syntax_1.BindingWhenSyntax(this._binding); this._bindingOnSyntax = new binding_on_syntax_1.BindingOnSyntax(this._binding); this._bindingInSyntax = new binding_in_syntax_1.BindingInSyntax(binding); } BindingInWhenOnSyntax.prototype.inRequestScope = function () { return this._bindingInSyntax.inRequestScope(); }; BindingInWhenOnSyntax.prototype.inSingletonScope = function () { return this._bindingInSyntax.inSingletonScope(); }; BindingInWhenOnSyntax.prototype.inTransientScope = function () { return this._bindingInSyntax.inTransientScope(); }; BindingInWhenOnSyntax.prototype.when = function (constraint) { return this._bindingWhenSyntax.when(constraint); }; BindingInWhenOnSyntax.prototype.whenTargetNamed = function (name) { return this._bindingWhenSyntax.whenTargetNamed(name); }; BindingInWhenOnSyntax.prototype.whenTargetIsDefault = function () { return this._bindingWhenSyntax.whenTargetIsDefault(); }; BindingInWhenOnSyntax.prototype.whenTargetTagged = function (tag, value) { return this._bindingWhenSyntax.whenTargetTagged(tag, value); }; BindingInWhenOnSyntax.prototype.whenInjectedInto = function (parent) { return this._bindingWhenSyntax.whenInjectedInto(parent); }; BindingInWhenOnSyntax.prototype.whenParentNamed = function (name) { return this._bindingWhenSyntax.whenParentNamed(name); }; BindingInWhenOnSyntax.prototype.whenParentTagged = function (tag, value) { return this._bindingWhenSyntax.whenParentTagged(tag, value); }; BindingInWhenOnSyntax.prototype.whenAnyAncestorIs = function (ancestor) { return this._bindingWhenSyntax.whenAnyAncestorIs(ancestor); }; BindingInWhenOnSyntax.prototype.whenNoAncestorIs = function (ancestor) { return this._bindingWhenSyntax.whenNoAncestorIs(ancestor); }; BindingInWhenOnSyntax.prototype.whenAnyAncestorNamed = function (name) { return this._bindingWhenSyntax.whenAnyAncestorNamed(name); }; BindingInWhenOnSyntax.prototype.whenAnyAncestorTagged = function (tag, value) { return this._bindingWhenSyntax.whenAnyAncestorTagged(tag, value); }; BindingInWhenOnSyntax.prototype.whenNoAncestorNamed = function (name) { return this._bindingWhenSyntax.whenNoAncestorNamed(name); }; BindingInWhenOnSyntax.prototype.whenNoAncestorTagged = function (tag, value) { return this._bindingWhenSyntax.whenNoAncestorTagged(tag, value); }; BindingInWhenOnSyntax.prototype.whenAnyAncestorMatches = function (constraint) { return this._bindingWhenSyntax.whenAnyAncestorMatches(constraint); }; BindingInWhenOnSyntax.prototype.whenNoAncestorMatches = function (constraint) { return this._bindingWhenSyntax.whenNoAncestorMatches(constraint); }; BindingInWhenOnSyntax.prototype.onActivation = function (handler) { return this._bindingOnSyntax.onActivation(handler); }; return BindingInWhenOnSyntax; }()); exports.BindingInWhenOnSyntax = BindingInWhenOnSyntax; /***/ }), /***/ "./node_modules/inversify/lib/syntax/binding_on_syntax.js": /*!****************************************************************!*\ !*** ./node_modules/inversify/lib/syntax/binding_on_syntax.js ***! \****************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var binding_when_syntax_1 = __webpack_require__(/*! ./binding_when_syntax */ "./node_modules/inversify/lib/syntax/binding_when_syntax.js"); var BindingOnSyntax = (function () { function BindingOnSyntax(binding) { this._binding = binding; } BindingOnSyntax.prototype.onActivation = function (handler) { this._binding.onActivation = handler; return new binding_when_syntax_1.BindingWhenSyntax(this._binding); }; return BindingOnSyntax; }()); exports.BindingOnSyntax = BindingOnSyntax; /***/ }), /***/ "./node_modules/inversify/lib/syntax/binding_to_syntax.js": /*!****************************************************************!*\ !*** ./node_modules/inversify/lib/syntax/binding_to_syntax.js ***! \****************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var ERROR_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js"); var literal_types_1 = __webpack_require__(/*! ../constants/literal_types */ "./node_modules/inversify/lib/constants/literal_types.js"); var binding_in_when_on_syntax_1 = __webpack_require__(/*! ./binding_in_when_on_syntax */ "./node_modules/inversify/lib/syntax/binding_in_when_on_syntax.js"); var binding_when_on_syntax_1 = __webpack_require__(/*! ./binding_when_on_syntax */ "./node_modules/inversify/lib/syntax/binding_when_on_syntax.js"); var BindingToSyntax = (function () { function BindingToSyntax(binding) { this._binding = binding; } BindingToSyntax.prototype.to = function (constructor) { this._binding.type = literal_types_1.BindingTypeEnum.Instance; this._binding.implementationType = constructor; return new binding_in_when_on_syntax_1.BindingInWhenOnSyntax(this._binding); }; BindingToSyntax.prototype.toSelf = function () { if (typeof this._binding.serviceIdentifier !== "function") { throw new Error("" + ERROR_MSGS.INVALID_TO_SELF_VALUE); } var self = this._binding.serviceIdentifier; return this.to(self); }; BindingToSyntax.prototype.toConstantValue = function (value) { this._binding.type = literal_types_1.BindingTypeEnum.ConstantValue; this._binding.cache = value; this._binding.dynamicValue = null; this._binding.implementationType = null; return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding); }; BindingToSyntax.prototype.toDynamicValue = function (func) { this._binding.type = literal_types_1.BindingTypeEnum.DynamicValue; this._binding.cache = null; this._binding.dynamicValue = func; this._binding.implementationType = null; return new binding_in_when_on_syntax_1.BindingInWhenOnSyntax(this._binding); }; BindingToSyntax.prototype.toConstructor = function (constructor) { this._binding.type = literal_types_1.BindingTypeEnum.Constructor; this._binding.implementationType = constructor; return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding); }; BindingToSyntax.prototype.toFactory = function (factory) { this._binding.type = literal_types_1.BindingTypeEnum.Factory; this._binding.factory = factory; return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding); }; BindingToSyntax.prototype.toFunction = function (func) { if (typeof func !== "function") { throw new Error(ERROR_MSGS.INVALID_FUNCTION_BINDING); } var bindingWhenOnSyntax = this.toConstantValue(func); this._binding.type = literal_types_1.BindingTypeEnum.Function; return bindingWhenOnSyntax; }; BindingToSyntax.prototype.toAutoFactory = function (serviceIdentifier) { this._binding.type = literal_types_1.BindingTypeEnum.Factory; this._binding.factory = function (context) { var autofactory = function () { return context.container.get(serviceIdentifier); }; return autofactory; }; return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding); }; BindingToSyntax.prototype.toProvider = function (provider) { this._binding.type = literal_types_1.BindingTypeEnum.Provider; this._binding.provider = provider; return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding); }; BindingToSyntax.prototype.toService = function (service) { this.toDynamicValue(function (context) { return context.container.get(service); }); }; return BindingToSyntax; }()); exports.BindingToSyntax = BindingToSyntax; /***/ }), /***/ "./node_modules/inversify/lib/syntax/binding_when_on_syntax.js": /*!*********************************************************************!*\ !*** ./node_modules/inversify/lib/syntax/binding_when_on_syntax.js ***! \*********************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var binding_on_syntax_1 = __webpack_require__(/*! ./binding_on_syntax */ "./node_modules/inversify/lib/syntax/binding_on_syntax.js"); var binding_when_syntax_1 = __webpack_require__(/*! ./binding_when_syntax */ "./node_modules/inversify/lib/syntax/binding_when_syntax.js"); var BindingWhenOnSyntax = (function () { function BindingWhenOnSyntax(binding) { this._binding = binding; this._bindingWhenSyntax = new binding_when_syntax_1.BindingWhenSyntax(this._binding); this._bindingOnSyntax = new binding_on_syntax_1.BindingOnSyntax(this._binding); } BindingWhenOnSyntax.prototype.when = function (constraint) { return this._bindingWhenSyntax.when(constraint); }; BindingWhenOnSyntax.prototype.whenTargetNamed = function (name) { return this._bindingWhenSyntax.whenTargetNamed(name); }; BindingWhenOnSyntax.prototype.whenTargetIsDefault = function () { return this._bindingWhenSyntax.whenTargetIsDefault(); }; BindingWhenOnSyntax.prototype.whenTargetTagged = function (tag, value) { return this._bindingWhenSyntax.whenTargetTagged(tag, value); }; BindingWhenOnSyntax.prototype.whenInjectedInto = function (parent) { return this._bindingWhenSyntax.whenInjectedInto(parent); }; BindingWhenOnSyntax.prototype.whenParentNamed = function (name) { return this._bindingWhenSyntax.whenParentNamed(name); }; BindingWhenOnSyntax.prototype.whenParentTagged = function (tag, value) { return this._bindingWhenSyntax.whenParentTagged(tag, value); }; BindingWhenOnSyntax.prototype.whenAnyAncestorIs = function (ancestor) { return this._bindingWhenSyntax.whenAnyAncestorIs(ancestor); }; BindingWhenOnSyntax.prototype.whenNoAncestorIs = function (ancestor) { return this._bindingWhenSyntax.whenNoAncestorIs(ancestor); }; BindingWhenOnSyntax.prototype.whenAnyAncestorNamed = function (name) { return this._bindingWhenSyntax.whenAnyAncestorNamed(name); }; BindingWhenOnSyntax.prototype.whenAnyAncestorTagged = function (tag, value) { return this._bindingWhenSyntax.whenAnyAncestorTagged(tag, value); }; BindingWhenOnSyntax.prototype.whenNoAncestorNamed = function (name) { return this._bindingWhenSyntax.whenNoAncestorNamed(name); }; BindingWhenOnSyntax.prototype.whenNoAncestorTagged = function (tag, value) { return this._bindingWhenSyntax.whenNoAncestorTagged(tag, value); }; BindingWhenOnSyntax.prototype.whenAnyAncestorMatches = function (constraint) { return this._bindingWhenSyntax.whenAnyAncestorMatches(constraint); }; BindingWhenOnSyntax.prototype.whenNoAncestorMatches = function (constraint) { return this._bindingWhenSyntax.whenNoAncestorMatches(constraint); }; BindingWhenOnSyntax.prototype.onActivation = function (handler) { return this._bindingOnSyntax.onActivation(handler); }; return BindingWhenOnSyntax; }()); exports.BindingWhenOnSyntax = BindingWhenOnSyntax; /***/ }), /***/ "./node_modules/inversify/lib/syntax/binding_when_syntax.js": /*!******************************************************************!*\ !*** ./node_modules/inversify/lib/syntax/binding_when_syntax.js ***! \******************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var binding_on_syntax_1 = __webpack_require__(/*! ./binding_on_syntax */ "./node_modules/inversify/lib/syntax/binding_on_syntax.js"); var constraint_helpers_1 = __webpack_require__(/*! ./constraint_helpers */ "./node_modules/inversify/lib/syntax/constraint_helpers.js"); var BindingWhenSyntax = (function () { function BindingWhenSyntax(binding) { this._binding = binding; } BindingWhenSyntax.prototype.when = function (constraint) { this._binding.constraint = constraint; return new binding_on_syntax_1.BindingOnSyntax(this._binding); }; BindingWhenSyntax.prototype.whenTargetNamed = function (name) { this._binding.constraint = constraint_helpers_1.namedConstraint(name); return new binding_on_syntax_1.BindingOnSyntax(this._binding); }; BindingWhenSyntax.prototype.whenTargetIsDefault = function () { this._binding.constraint = function (request) { var targetIsDefault = (request.target !== null) && (!request.target.isNamed()) && (!request.target.isTagged()); return targetIsDefault; }; return new binding_on_syntax_1.BindingOnSyntax(this._binding); }; BindingWhenSyntax.prototype.whenTargetTagged = function (tag, value) { this._binding.constraint = constraint_helpers_1.taggedConstraint(tag)(value); return new binding_on_syntax_1.BindingOnSyntax(this._binding); }; BindingWhenSyntax.prototype.whenInjectedInto = function (parent) { this._binding.constraint = function (request) { return constraint_helpers_1.typeConstraint(parent)(request.parentRequest); }; return new binding_on_syntax_1.BindingOnSyntax(this._binding); }; BindingWhenSyntax.prototype.whenParentNamed = function (name) { this._binding.constraint = function (request) { return constraint_helpers_1.namedConstraint(name)(request.parentRequest); }; return new binding_on_syntax_1.BindingOnSyntax(this._binding); }; BindingWhenSyntax.prototype.whenParentTagged = function (tag, value) { this._binding.constraint = function (request) { return constraint_helpers_1.taggedConstraint(tag)(value)(request.parentRequest); }; return new binding_on_syntax_1.BindingOnSyntax(this._binding); }; BindingWhenSyntax.prototype.whenAnyAncestorIs = function (ancestor) { this._binding.constraint = function (request) { return constraint_helpers_1.traverseAncerstors(request, constraint_helpers_1.typeConstraint(ancestor)); }; return new binding_on_syntax_1.BindingOnSyntax(this._binding); }; BindingWhenSyntax.prototype.whenNoAncestorIs = function (ancestor) { this._binding.constraint = function (request) { return !constraint_helpers_1.traverseAncerstors(request, constraint_helpers_1.typeConstraint(ancestor)); }; return new binding_on_syntax_1.BindingOnSyntax(this._binding); }; BindingWhenSyntax.prototype.whenAnyAncestorNamed = function (name) { this._binding.constraint = function (request) { return constraint_helpers_1.traverseAncerstors(request, constraint_helpers_1.namedConstraint(name)); }; return new binding_on_syntax_1.BindingOnSyntax(this._binding); }; BindingWhenSyntax.prototype.whenNoAncestorNamed = function (name) { this._binding.constraint = function (request) { return !constraint_helpers_1.traverseAncerstors(request, constraint_helpers_1.namedConstraint(name)); }; return new binding_on_syntax_1.BindingOnSyntax(this._binding); }; BindingWhenSyntax.prototype.whenAnyAncestorTagged = function (tag, value) { this._binding.constraint = function (request) { return constraint_helpers_1.traverseAncerstors(request, constraint_helpers_1.taggedConstraint(tag)(value)); }; return new binding_on_syntax_1.BindingOnSyntax(this._binding); }; BindingWhenSyntax.prototype.whenNoAncestorTagged = function (tag, value) { this._binding.constraint = function (request) { return !constraint_helpers_1.traverseAncerstors(request, constraint_helpers_1.taggedConstraint(tag)(value)); }; return new binding_on_syntax_1.BindingOnSyntax(this._binding); }; BindingWhenSyntax.prototype.whenAnyAncestorMatches = function (constraint) { this._binding.constraint = function (request) { return constraint_helpers_1.traverseAncerstors(request, constraint); }; return new binding_on_syntax_1.BindingOnSyntax(this._binding); }; BindingWhenSyntax.prototype.whenNoAncestorMatches = function (constraint) { this._binding.constraint = function (request) { return !constraint_helpers_1.traverseAncerstors(request, constraint); }; return new binding_on_syntax_1.BindingOnSyntax(this._binding); }; return BindingWhenSyntax; }()); exports.BindingWhenSyntax = BindingWhenSyntax; /***/ }), /***/ "./node_modules/inversify/lib/syntax/constraint_helpers.js": /*!*****************************************************************!*\ !*** ./node_modules/inversify/lib/syntax/constraint_helpers.js ***! \*****************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js"); var metadata_1 = __webpack_require__(/*! ../planning/metadata */ "./node_modules/inversify/lib/planning/metadata.js"); var traverseAncerstors = function (request, constraint) { var parent = request.parentRequest; if (parent !== null) { return constraint(parent) ? true : traverseAncerstors(parent, constraint); } else { return false; } }; exports.traverseAncerstors = traverseAncerstors; var taggedConstraint = function (key) { return function (value) { var constraint = function (request) { return request !== null && request.target !== null && request.target.matchesTag(key)(value); }; constraint.metaData = new metadata_1.Metadata(key, value); return constraint; }; }; exports.taggedConstraint = taggedConstraint; var namedConstraint = taggedConstraint(METADATA_KEY.NAMED_TAG); exports.namedConstraint = namedConstraint; var typeConstraint = function (type) { return function (request) { var binding = null; if (request !== null) { binding = request.bindings[0]; if (typeof type === "string") { var serviceIdentifier = binding.serviceIdentifier; return serviceIdentifier === type; } else { var constructor = request.bindings[0].implementationType; return type === constructor; } } return false; }; }; exports.typeConstraint = typeConstraint; /***/ }), /***/ "./node_modules/inversify/lib/utils/binding_utils.js": /*!***********************************************************!*\ !*** ./node_modules/inversify/lib/utils/binding_utils.js ***! \***********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.multiBindToService = function (container) { return function (service) { return function () { var types = []; for (var _i = 0; _i < arguments.length; _i++) { types[_i] = arguments[_i]; } return types.forEach(function (t) { return container.bind(t).toService(service); }); }; }; }; /***/ }), /***/ "./node_modules/inversify/lib/utils/exceptions.js": /*!********************************************************!*\ !*** ./node_modules/inversify/lib/utils/exceptions.js ***! \********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var ERROR_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js"); function isStackOverflowExeption(error) { return (error instanceof RangeError || error.message === ERROR_MSGS.STACK_OVERFLOW); } exports.isStackOverflowExeption = isStackOverflowExeption; /***/ }), /***/ "./node_modules/inversify/lib/utils/id.js": /*!************************************************!*\ !*** ./node_modules/inversify/lib/utils/id.js ***! \************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var idCounter = 0; function id() { return idCounter++; } exports.id = id; /***/ }), /***/ "./node_modules/inversify/lib/utils/serialization.js": /*!***********************************************************!*\ !*** ./node_modules/inversify/lib/utils/serialization.js ***! \***********************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var ERROR_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js"); function getServiceIdentifierAsString(serviceIdentifier) { if (typeof serviceIdentifier === "function") { var _serviceIdentifier = serviceIdentifier; return _serviceIdentifier.name; } else if (typeof serviceIdentifier === "symbol") { return serviceIdentifier.toString(); } else { var _serviceIdentifier = serviceIdentifier; return _serviceIdentifier; } } exports.getServiceIdentifierAsString = getServiceIdentifierAsString; function listRegisteredBindingsForServiceIdentifier(container, serviceIdentifier, getBindings) { var registeredBindingsList = ""; var registeredBindings = getBindings(container, serviceIdentifier); if (registeredBindings.length !== 0) { registeredBindingsList = "\nRegistered bindings:"; registeredBindings.forEach(function (binding) { var name = "Object"; if (binding.implementationType !== null) { name = getFunctionName(binding.implementationType); } registeredBindingsList = registeredBindingsList + "\n " + name; if (binding.constraint.metaData) { registeredBindingsList = registeredBindingsList + " - " + binding.constraint.metaData; } }); } return registeredBindingsList; } exports.listRegisteredBindingsForServiceIdentifier = listRegisteredBindingsForServiceIdentifier; function alreadyDependencyChain(request, serviceIdentifier) { if (request.parentRequest === null) { return false; } else if (request.parentRequest.serviceIdentifier === serviceIdentifier) { return true; } else { return alreadyDependencyChain(request.parentRequest, serviceIdentifier); } } function dependencyChainToString(request) { function _createStringArr(req, result) { if (result === void 0) { result = []; } var serviceIdentifier = getServiceIdentifierAsString(req.serviceIdentifier); result.push(serviceIdentifier); if (req.parentRequest !== null) { return _createStringArr(req.parentRequest, result); } return result; } var stringArr = _createStringArr(request); return stringArr.reverse().join(" --> "); } function circularDependencyToException(request) { request.childRequests.forEach(function (childRequest) { if (alreadyDependencyChain(childRequest, childRequest.serviceIdentifier)) { var services = dependencyChainToString(childRequest); throw new Error(ERROR_MSGS.CIRCULAR_DEPENDENCY + " " + services); } else { circularDependencyToException(childRequest); } }); } exports.circularDependencyToException = circularDependencyToException; function listMetadataForTarget(serviceIdentifierString, target) { if (target.isTagged() || target.isNamed()) { var m_1 = ""; var namedTag = target.getNamedTag(); var otherTags = target.getCustomTags(); if (namedTag !== null) { m_1 += namedTag.toString() + "\n"; } if (otherTags !== null) { otherTags.forEach(function (tag) { m_1 += tag.toString() + "\n"; }); } return " " + serviceIdentifierString + "\n " + serviceIdentifierString + " - " + m_1; } else { return " " + serviceIdentifierString; } } exports.listMetadataForTarget = listMetadataForTarget; function getFunctionName(v) { if (v.name) { return v.name; } else { var name_1 = v.toString(); var match = name_1.match(/^function\s*([^\s(]+)/); return match ? match[1] : "Anonymous function: " + name_1; } } exports.getFunctionName = getFunctionName; /***/ }), /***/ "./node_modules/qs/lib/formats.js": /*!****************************************!*\ !*** ./node_modules/qs/lib/formats.js ***! \****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var replace = String.prototype.replace; var percentTwenties = /%20/g; var util = __webpack_require__(/*! ./utils */ "./node_modules/qs/lib/utils.js"); var Format = { RFC1738: 'RFC1738', RFC3986: 'RFC3986' }; module.exports = util.assign( { 'default': Format.RFC3986, formatters: { RFC1738: function (value) { return replace.call(value, percentTwenties, '+'); }, RFC3986: function (value) { return String(value); } } }, Format ); /***/ }), /***/ "./node_modules/qs/lib/index.js": /*!**************************************!*\ !*** ./node_modules/qs/lib/index.js ***! \**************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var stringify = __webpack_require__(/*! ./stringify */ "./node_modules/qs/lib/stringify.js"); var parse = __webpack_require__(/*! ./parse */ "./node_modules/qs/lib/parse.js"); var formats = __webpack_require__(/*! ./formats */ "./node_modules/qs/lib/formats.js"); module.exports = { formats: formats, parse: parse, stringify: stringify }; /***/ }), /***/ "./node_modules/qs/lib/parse.js": /*!**************************************!*\ !*** ./node_modules/qs/lib/parse.js ***! \**************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var utils = __webpack_require__(/*! ./utils */ "./node_modules/qs/lib/utils.js"); var has = Object.prototype.hasOwnProperty; var isArray = Array.isArray; var defaults = { allowDots: false, allowPrototypes: false, arrayLimit: 20, charset: 'utf-8', charsetSentinel: false, comma: false, decoder: utils.decode, delimiter: '&', depth: 5, ignoreQueryPrefix: false, interpretNumericEntities: false, parameterLimit: 1000, parseArrays: true, plainObjects: false, strictNullHandling: false }; var interpretNumericEntities = function (str) { return str.replace(/&#(\d+);/g, function ($0, numberStr) { return String.fromCharCode(parseInt(numberStr, 10)); }); }; // This is what browsers will submit when the ✓ character occurs in an // application/x-www-form-urlencoded body and the encoding of the page containing // the form is iso-8859-1, or when the submitted form has an accept-charset // attribute of iso-8859-1. Presumably also with other charsets that do not contain // the ✓ character, such as us-ascii. var isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('✓') // These are the percent-encoded utf-8 octets representing a checkmark, indicating that the request actually is utf-8 encoded. var charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓') var parseValues = function parseQueryStringValues(str, options) { var obj = {}; var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str; var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit; var parts = cleanStr.split(options.delimiter, limit); var skipIndex = -1; // Keep track of where the utf8 sentinel was found var i; var charset = options.charset; if (options.charsetSentinel) { for (i = 0; i < parts.length; ++i) { if (parts[i].indexOf('utf8=') === 0) { if (parts[i] === charsetSentinel) { charset = 'utf-8'; } else if (parts[i] === isoSentinel) { charset = 'iso-8859-1'; } skipIndex = i; i = parts.length; // The eslint settings do not allow break; } } } for (i = 0; i < parts.length; ++i) { if (i === skipIndex) { continue; } var part = parts[i]; var bracketEqualsPos = part.indexOf(']='); var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1; var key, val; if (pos === -1) { key = options.decoder(part, defaults.decoder, charset, 'key'); val = options.strictNullHandling ? null : ''; } else { key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key'); val = options.decoder(part.slice(pos + 1), defaults.decoder, charset, 'value'); } if (val && options.interpretNumericEntities && charset === 'iso-8859-1') { val = interpretNumericEntities(val); } if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) { val = val.split(','); } if (part.indexOf('[]=') > -1) { val = isArray(val) ? [val] : val; } if (has.call(obj, key)) { obj[key] = utils.combine(obj[key], val); } else { obj[key] = val; } } return obj; }; var parseObject = function (chain, val, options) { var leaf = val; for (var i = chain.length - 1; i >= 0; --i) { var obj; var root = chain[i]; if (root === '[]' && options.parseArrays) { obj = [].concat(leaf); } else { obj = options.plainObjects ? Object.create(null) : {}; var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root; var index = parseInt(cleanRoot, 10); if (!options.parseArrays && cleanRoot === '') { obj = { 0: leaf }; } else if ( !isNaN(index) && root !== cleanRoot && String(index) === cleanRoot && index >= 0 && (options.parseArrays && index <= options.arrayLimit) ) { obj = []; obj[index] = leaf; } else { obj[cleanRoot] = leaf; } } leaf = obj; } return leaf; }; var parseKeys = function parseQueryStringKeys(givenKey, val, options) { if (!givenKey) { return; } // Transform dot notation to bracket notation var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey; // The regex chunks var brackets = /(\[[^[\]]*])/; var child = /(\[[^[\]]*])/g; // Get the parent var segment = options.depth > 0 && brackets.exec(key); var parent = segment ? key.slice(0, segment.index) : key; // Stash the parent if it exists var keys = []; if (parent) { // If we aren't using plain objects, optionally prefix keys that would overwrite object prototype properties if (!options.plainObjects && has.call(Object.prototype, parent)) { if (!options.allowPrototypes) { return; } } keys.push(parent); } // Loop through children appending to the array until we hit depth var i = 0; while (options.depth > 0 && (segment = child.exec(key)) !== null && i < options.depth) { i += 1; if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) { if (!options.allowPrototypes) { return; } } keys.push(segment[1]); } // If there's a remainder, just add whatever is left if (segment) { keys.push('[' + key.slice(segment.index) + ']'); } return parseObject(keys, val, options); }; var normalizeParseOptions = function normalizeParseOptions(opts) { if (!opts) { return defaults; } if (opts.decoder !== null && opts.decoder !== undefined && typeof opts.decoder !== 'function') { throw new TypeError('Decoder has to be a function.'); } if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') { throw new Error('The charset option must be either utf-8, iso-8859-1, or undefined'); } var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset; return { allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots, allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes, arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit, charset: charset, charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel, comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma, decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder, delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter, // eslint-disable-next-line no-implicit-coercion, no-extra-parens depth: (typeof opts.depth === 'number' || opts.depth === false) ? +opts.depth : defaults.depth, ignoreQueryPrefix: opts.ignoreQueryPrefix === true, interpretNumericEntities: typeof opts.interpretNumericEntities === 'boolean' ? opts.interpretNumericEntities : defaults.interpretNumericEntities, parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit, parseArrays: opts.parseArrays !== false, plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects, strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling }; }; module.exports = function (str, opts) { var options = normalizeParseOptions(opts); if (str === '' || str === null || typeof str === 'undefined') { return options.plainObjects ? Object.create(null) : {}; } var tempObj = typeof str === 'string' ? parseValues(str, options) : str; var obj = options.plainObjects ? Object.create(null) : {}; // Iterate over the keys and setup the new object var keys = Object.keys(tempObj); for (var i = 0; i < keys.length; ++i) { var key = keys[i]; var newObj = parseKeys(key, tempObj[key], options); obj = utils.merge(obj, newObj, options); } return utils.compact(obj); }; /***/ }), /***/ "./node_modules/qs/lib/stringify.js": /*!******************************************!*\ !*** ./node_modules/qs/lib/stringify.js ***! \******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var utils = __webpack_require__(/*! ./utils */ "./node_modules/qs/lib/utils.js"); var formats = __webpack_require__(/*! ./formats */ "./node_modules/qs/lib/formats.js"); var has = Object.prototype.hasOwnProperty; var arrayPrefixGenerators = { brackets: function brackets(prefix) { return prefix + '[]'; }, comma: 'comma', indices: function indices(prefix, key) { return prefix + '[' + key + ']'; }, repeat: function repeat(prefix) { return prefix; } }; var isArray = Array.isArray; var push = Array.prototype.push; var pushToArray = function (arr, valueOrArray) { push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]); }; var toISO = Date.prototype.toISOString; var defaultFormat = formats['default']; var defaults = { addQueryPrefix: false, allowDots: false, charset: 'utf-8', charsetSentinel: false, delimiter: '&', encode: true, encoder: utils.encode, encodeValuesOnly: false, format: defaultFormat, formatter: formats.formatters[defaultFormat], // deprecated indices: false, serializeDate: function serializeDate(date) { return toISO.call(date); }, skipNulls: false, strictNullHandling: false }; var isNonNullishPrimitive = function isNonNullishPrimitive(v) { return typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean' || typeof v === 'symbol' || typeof v === 'bigint'; }; var stringify = function stringify( object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots, serializeDate, formatter, encodeValuesOnly, charset ) { var obj = object; if (typeof filter === 'function') { obj = filter(prefix, obj); } else if (obj instanceof Date) { obj = serializeDate(obj); } else if (generateArrayPrefix === 'comma' && isArray(obj)) { obj = obj.join(','); } if (obj === null) { if (strictNullHandling) { return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key') : prefix; } obj = ''; } if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) { if (encoder) { var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key'); return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value'))]; } return [formatter(prefix) + '=' + formatter(String(obj))]; } var values = []; if (typeof obj === 'undefined') { return values; } var objKeys; if (isArray(filter)) { objKeys = filter; } else { var keys = Object.keys(obj); objKeys = sort ? keys.sort(sort) : keys; } for (var i = 0; i < objKeys.length; ++i) { var key = objKeys[i]; if (skipNulls && obj[key] === null) { continue; } if (isArray(obj)) { pushToArray(values, stringify( obj[key], typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots, serializeDate, formatter, encodeValuesOnly, charset )); } else { pushToArray(values, stringify( obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots, serializeDate, formatter, encodeValuesOnly, charset )); } } return values; }; var normalizeStringifyOptions = function normalizeStringifyOptions(opts) { if (!opts) { return defaults; } if (opts.encoder !== null && opts.encoder !== undefined && typeof opts.encoder !== 'function') { throw new TypeError('Encoder has to be a function.'); } var charset = opts.charset || defaults.charset; if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') { throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined'); } var format = formats['default']; if (typeof opts.format !== 'undefined') { if (!has.call(formats.formatters, opts.format)) { throw new TypeError('Unknown format option provided.'); } format = opts.format; } var formatter = formats.formatters[format]; var filter = defaults.filter; if (typeof opts.filter === 'function' || isArray(opts.filter)) { filter = opts.filter; } return { addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix, allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots, charset: charset, charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel, delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter, encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode, encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder, encodeValuesOnly: typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly, filter: filter, formatter: formatter, serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate, skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls, sort: typeof opts.sort === 'function' ? opts.sort : null, strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling }; }; module.exports = function (object, opts) { var obj = object; var options = normalizeStringifyOptions(opts); var objKeys; var filter; if (typeof options.filter === 'function') { filter = options.filter; obj = filter('', obj); } else if (isArray(options.filter)) { filter = options.filter; objKeys = filter; } var keys = []; if (typeof obj !== 'object' || obj === null) { return ''; } var arrayFormat; if (opts && opts.arrayFormat in arrayPrefixGenerators) { arrayFormat = opts.arrayFormat; } else if (opts && 'indices' in opts) { arrayFormat = opts.indices ? 'indices' : 'repeat'; } else { arrayFormat = 'indices'; } var generateArrayPrefix = arrayPrefixGenerators[arrayFormat]; if (!objKeys) { objKeys = Object.keys(obj); } if (options.sort) { objKeys.sort(options.sort); } for (var i = 0; i < objKeys.length; ++i) { var key = objKeys[i]; if (options.skipNulls && obj[key] === null) { continue; } pushToArray(keys, stringify( obj[key], key, generateArrayPrefix, options.strictNullHandling, options.skipNulls, options.encode ? options.encoder : null, options.filter, options.sort, options.allowDots, options.serializeDate, options.formatter, options.encodeValuesOnly, options.charset )); } var joined = keys.join(options.delimiter); var prefix = options.addQueryPrefix === true ? '?' : ''; if (options.charsetSentinel) { if (options.charset === 'iso-8859-1') { // encodeURIComponent('✓'), the "numeric entity" representation of a checkmark prefix += 'utf8=%26%2310003%3B&'; } else { // encodeURIComponent('✓') prefix += 'utf8=%E2%9C%93&'; } } return joined.length > 0 ? prefix + joined : ''; }; /***/ }), /***/ "./node_modules/qs/lib/utils.js": /*!**************************************!*\ !*** ./node_modules/qs/lib/utils.js ***! \**************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var has = Object.prototype.hasOwnProperty; var isArray = Array.isArray; var hexTable = (function () { var array = []; for (var i = 0; i < 256; ++i) { array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase()); } return array; }()); var compactQueue = function compactQueue(queue) { while (queue.length > 1) { var item = queue.pop(); var obj = item.obj[item.prop]; if (isArray(obj)) { var compacted = []; for (var j = 0; j < obj.length; ++j) { if (typeof obj[j] !== 'undefined') { compacted.push(obj[j]); } } item.obj[item.prop] = compacted; } } }; var arrayToObject = function arrayToObject(source, options) { var obj = options && options.plainObjects ? Object.create(null) : {}; for (var i = 0; i < source.length; ++i) { if (typeof source[i] !== 'undefined') { obj[i] = source[i]; } } return obj; }; var merge = function merge(target, source, options) { /* eslint no-param-reassign: 0 */ if (!source) { return target; } if (typeof source !== 'object') { if (isArray(target)) { target.push(source); } else if (target && typeof target === 'object') { if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) { target[source] = true; } } else { return [target, source]; } return target; } if (!target || typeof target !== 'object') { return [target].concat(source); } var mergeTarget = target; if (isArray(target) && !isArray(source)) { mergeTarget = arrayToObject(target, options); } if (isArray(target) && isArray(source)) { source.forEach(function (item, i) { if (has.call(target, i)) { var targetItem = target[i]; if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') { target[i] = merge(targetItem, item, options); } else { target.push(item); } } else { target[i] = item; } }); return target; } return Object.keys(source).reduce(function (acc, key) { var value = source[key]; if (has.call(acc, key)) { acc[key] = merge(acc[key], value, options); } else { acc[key] = value; } return acc; }, mergeTarget); }; var assign = function assignSingleSource(target, source) { return Object.keys(source).reduce(function (acc, key) { acc[key] = source[key]; return acc; }, target); }; var decode = function (str, decoder, charset) { var strWithoutPlus = str.replace(/\+/g, ' '); if (charset === 'iso-8859-1') { // unescape never throws, no try...catch needed: return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape); } // utf-8 try { return decodeURIComponent(strWithoutPlus); } catch (e) { return strWithoutPlus; } }; var encode = function encode(str, defaultEncoder, charset) { // This code was originally written by Brian White (mscdex) for the io.js core querystring library. // It has been adapted here for stricter adherence to RFC 3986 if (str.length === 0) { return str; } var string = str; if (typeof str === 'symbol') { string = Symbol.prototype.toString.call(str); } else if (typeof str !== 'string') { string = String(str); } if (charset === 'iso-8859-1') { return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) { return '%26%23' + parseInt($0.slice(2), 16) + '%3B'; }); } var out = ''; for (var i = 0; i < string.length; ++i) { var c = string.charCodeAt(i); if ( c === 0x2D // - || c === 0x2E // . || c === 0x5F // _ || c === 0x7E // ~ || (c >= 0x30 && c <= 0x39) // 0-9 || (c >= 0x41 && c <= 0x5A) // a-z || (c >= 0x61 && c <= 0x7A) // A-Z ) { out += string.charAt(i); continue; } if (c < 0x80) { out = out + hexTable[c]; continue; } if (c < 0x800) { out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]); continue; } if (c < 0xD800 || c >= 0xE000) { out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]); continue; } i += 1; c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF)); out += hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]; } return out; }; var compact = function compact(value) { var queue = [{ obj: { o: value }, prop: 'o' }]; var refs = []; for (var i = 0; i < queue.length; ++i) { var item = queue[i]; var obj = item.obj[item.prop]; var keys = Object.keys(obj); for (var j = 0; j < keys.length; ++j) { var key = keys[j]; var val = obj[key]; if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) { queue.push({ obj: obj, prop: key }); refs.push(val); } } } compactQueue(queue); return value; }; var isRegExp = function isRegExp(obj) { return Object.prototype.toString.call(obj) === '[object RegExp]'; }; var isBuffer = function isBuffer(obj) { if (!obj || typeof obj !== 'object') { return false; } return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj)); }; var combine = function combine(a, b) { return [].concat(a, b); }; module.exports = { arrayToObject: arrayToObject, assign: assign, combine: combine, compact: compact, decode: decode, encode: encode, isBuffer: isBuffer, isRegExp: isRegExp, merge: merge }; /***/ }), /***/ "./node_modules/reflect-metadata/Reflect.js": /*!**************************************************!*\ !*** ./node_modules/reflect-metadata/Reflect.js ***! \**************************************************/ /*! no static exports found */ /***/ (function(module, exports) { /*! ***************************************************************************** Copyright (C) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ var Reflect; (function (Reflect) { // Metadata Proposal // https://rbuckton.github.io/reflect-metadata/ (function (factory) { var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : Function("return this;")(); var exporter = makeExporter(Reflect); if (typeof root.Reflect === "undefined") { root.Reflect = Reflect; } else { exporter = makeExporter(root.Reflect, exporter); } factory(exporter); function makeExporter(target, previous) { return function (key, value) { if (typeof target[key] !== "function") { Object.defineProperty(target, key, { configurable: true, writable: true, value: value }); } if (previous) previous(key, value); }; } })(function (exporter) { var hasOwn = Object.prototype.hasOwnProperty; // feature test for Symbol support var supportsSymbol = typeof Symbol === "function"; var toPrimitiveSymbol = supportsSymbol && typeof Symbol.toPrimitive !== "undefined" ? Symbol.toPrimitive : "@@toPrimitive"; var iteratorSymbol = supportsSymbol && typeof Symbol.iterator !== "undefined" ? Symbol.iterator : "@@iterator"; var supportsCreate = typeof Object.create === "function"; // feature test for Object.create support var supportsProto = { __proto__: [] } instanceof Array; // feature test for __proto__ support var downLevel = !supportsCreate && !supportsProto; var HashMap = { // create an object in dictionary mode (a.k.a. "slow" mode in v8) create: supportsCreate ? function () { return MakeDictionary(Object.create(null)); } : supportsProto ? function () { return MakeDictionary({ __proto__: null }); } : function () { return MakeDictionary({}); }, has: downLevel ? function (map, key) { return hasOwn.call(map, key); } : function (map, key) { return key in map; }, get: downLevel ? function (map, key) { return hasOwn.call(map, key) ? map[key] : undefined; } : function (map, key) { return map[key]; }, }; // Load global or shim versions of Map, Set, and WeakMap var functionPrototype = Object.getPrototypeOf(Function); var usePolyfill = typeof process === "object" && process.env && process.env["REFLECT_METADATA_USE_MAP_POLYFILL"] === "true"; var _Map = !usePolyfill && typeof Map === "function" && typeof Map.prototype.entries === "function" ? Map : CreateMapPolyfill(); var _Set = !usePolyfill && typeof Set === "function" && typeof Set.prototype.entries === "function" ? Set : CreateSetPolyfill(); var _WeakMap = !usePolyfill && typeof WeakMap === "function" ? WeakMap : CreateWeakMapPolyfill(); // [[Metadata]] internal slot // https://rbuckton.github.io/reflect-metadata/#ordinary-object-internal-methods-and-internal-slots var Metadata = new _WeakMap(); /** * Applies a set of decorators to a property of a target object. * @param decorators An array of decorators. * @param target The target object. * @param propertyKey (Optional) The property key to decorate. * @param attributes (Optional) The property descriptor for the target key. * @remarks Decorators are applied in reverse order. * @example * * class Example { * // property declarations are not part of ES6, though they are valid in TypeScript: * // static staticProperty; * // property; * * constructor(p) { } * static staticMethod(p) { } * method(p) { } * } * * // constructor * Example = Reflect.decorate(decoratorsArray, Example); * * // property (on constructor) * Reflect.decorate(decoratorsArray, Example, "staticProperty"); * * // property (on prototype) * Reflect.decorate(decoratorsArray, Example.prototype, "property"); * * // method (on constructor) * Object.defineProperty(Example, "staticMethod", * Reflect.decorate(decoratorsArray, Example, "staticMethod", * Object.getOwnPropertyDescriptor(Example, "staticMethod"))); * * // method (on prototype) * Object.defineProperty(Example.prototype, "method", * Reflect.decorate(decoratorsArray, Example.prototype, "method", * Object.getOwnPropertyDescriptor(Example.prototype, "method"))); * */ function decorate(decorators, target, propertyKey, attributes) { if (!IsUndefined(propertyKey)) { if (!IsArray(decorators)) throw new TypeError(); if (!IsObject(target)) throw new TypeError(); if (!IsObject(attributes) && !IsUndefined(attributes) && !IsNull(attributes)) throw new TypeError(); if (IsNull(attributes)) attributes = undefined; propertyKey = ToPropertyKey(propertyKey); return DecorateProperty(decorators, target, propertyKey, attributes); } else { if (!IsArray(decorators)) throw new TypeError(); if (!IsConstructor(target)) throw new TypeError(); return DecorateConstructor(decorators, target); } } exporter("decorate", decorate); // 4.1.2 Reflect.metadata(metadataKey, metadataValue) // https://rbuckton.github.io/reflect-metadata/#reflect.metadata /** * A default metadata decorator factory that can be used on a class, class member, or parameter. * @param metadataKey The key for the metadata entry. * @param metadataValue The value for the metadata entry. * @returns A decorator function. * @remarks * If `metadataKey` is already defined for the target and target key, the * metadataValue for that key will be overwritten. * @example * * // constructor * @Reflect.metadata(key, value) * class Example { * } * * // property (on constructor, TypeScript only) * class Example { * @Reflect.metadata(key, value) * static staticProperty; * } * * // property (on prototype, TypeScript only) * class Example { * @Reflect.metadata(key, value) * property; * } * * // method (on constructor) * class Example { * @Reflect.metadata(key, value) * static staticMethod() { } * } * * // method (on prototype) * class Example { * @Reflect.metadata(key, value) * method() { } * } * */ function metadata(metadataKey, metadataValue) { function decorator(target, propertyKey) { if (!IsObject(target)) throw new TypeError(); if (!IsUndefined(propertyKey) && !IsPropertyKey(propertyKey)) throw new TypeError(); OrdinaryDefineOwnMetadata(metadataKey, metadataValue, target, propertyKey); } return decorator; } exporter("metadata", metadata); /** * Define a unique metadata entry on the target. * @param metadataKey A key used to store and retrieve metadata. * @param metadataValue A value that contains attached metadata. * @param target The target object on which to define metadata. * @param propertyKey (Optional) The property key for the target. * @example * * class Example { * // property declarations are not part of ES6, though they are valid in TypeScript: * // static staticProperty; * // property; * * constructor(p) { } * static staticMethod(p) { } * method(p) { } * } * * // constructor * Reflect.defineMetadata("custom:annotation", options, Example); * * // property (on constructor) * Reflect.defineMetadata("custom:annotation", options, Example, "staticProperty"); * * // property (on prototype) * Reflect.defineMetadata("custom:annotation", options, Example.prototype, "property"); * * // method (on constructor) * Reflect.defineMetadata("custom:annotation", options, Example, "staticMethod"); * * // method (on prototype) * Reflect.defineMetadata("custom:annotation", options, Example.prototype, "method"); * * // decorator factory as metadata-producing annotation. * function MyAnnotation(options): Decorator { * return (target, key?) => Reflect.defineMetadata("custom:annotation", options, target, key); * } * */ function defineMetadata(metadataKey, metadataValue, target, propertyKey) { if (!IsObject(target)) throw new TypeError(); if (!IsUndefined(propertyKey)) propertyKey = ToPropertyKey(propertyKey); return OrdinaryDefineOwnMetadata(metadataKey, metadataValue, target, propertyKey); } exporter("defineMetadata", defineMetadata); /** * Gets a value indicating whether the target object or its prototype chain has the provided metadata key defined. * @param metadataKey A key used to store and retrieve metadata. * @param target The target object on which the metadata is defined. * @param propertyKey (Optional) The property key for the target. * @returns `true` if the metadata key was defined on the target object or its prototype chain; otherwise, `false`. * @example * * class Example { * // property declarations are not part of ES6, though they are valid in TypeScript: * // static staticProperty; * // property; * * constructor(p) { } * static staticMethod(p) { } * method(p) { } * } * * // constructor * result = Reflect.hasMetadata("custom:annotation", Example); * * // property (on constructor) * result = Reflect.hasMetadata("custom:annotation", Example, "staticProperty"); * * // property (on prototype) * result = Reflect.hasMetadata("custom:annotation", Example.prototype, "property"); * * // method (on constructor) * result = Reflect.hasMetadata("custom:annotation", Example, "staticMethod"); * * // method (on prototype) * result = Reflect.hasMetadata("custom:annotation", Example.prototype, "method"); * */ function hasMetadata(metadataKey, target, propertyKey) { if (!IsObject(target)) throw new TypeError(); if (!IsUndefined(propertyKey)) propertyKey = ToPropertyKey(propertyKey); return OrdinaryHasMetadata(metadataKey, target, propertyKey); } exporter("hasMetadata", hasMetadata); /** * Gets a value indicating whether the target object has the provided metadata key defined. * @param metadataKey A key used to store and retrieve metadata. * @param target The target object on which the metadata is defined. * @param propertyKey (Optional) The property key for the target. * @returns `true` if the metadata key was defined on the target object; otherwise, `false`. * @example * * class Example { * // property declarations are not part of ES6, though they are valid in TypeScript: * // static staticProperty; * // property; * * constructor(p) { } * static staticMethod(p) { } * method(p) { } * } * * // constructor * result = Reflect.hasOwnMetadata("custom:annotation", Example); * * // property (on constructor) * result = Reflect.hasOwnMetadata("custom:annotation", Example, "staticProperty"); * * // property (on prototype) * result = Reflect.hasOwnMetadata("custom:annotation", Example.prototype, "property"); * * // method (on constructor) * result = Reflect.hasOwnMetadata("custom:annotation", Example, "staticMethod"); * * // method (on prototype) * result = Reflect.hasOwnMetadata("custom:annotation", Example.prototype, "method"); * */ function hasOwnMetadata(metadataKey, target, propertyKey) { if (!IsObject(target)) throw new TypeError(); if (!IsUndefined(propertyKey)) propertyKey = ToPropertyKey(propertyKey); return OrdinaryHasOwnMetadata(metadataKey, target, propertyKey); } exporter("hasOwnMetadata", hasOwnMetadata); /** * Gets the metadata value for the provided metadata key on the target object or its prototype chain. * @param metadataKey A key used to store and retrieve metadata. * @param target The target object on which the metadata is defined. * @param propertyKey (Optional) The property key for the target. * @returns The metadata value for the metadata key if found; otherwise, `undefined`. * @example * * class Example { * // property declarations are not part of ES6, though they are valid in TypeScript: * // static staticProperty; * // property; * * constructor(p) { } * static staticMethod(p) { } * method(p) { } * } * * // constructor * result = Reflect.getMetadata("custom:annotation", Example); * * // property (on constructor) * result = Reflect.getMetadata("custom:annotation", Example, "staticProperty"); * * // property (on prototype) * result = Reflect.getMetadata("custom:annotation", Example.prototype, "property"); * * // method (on constructor) * result = Reflect.getMetadata("custom:annotation", Example, "staticMethod"); * * // method (on prototype) * result = Reflect.getMetadata("custom:annotation", Example.prototype, "method"); * */ function getMetadata(metadataKey, target, propertyKey) { if (!IsObject(target)) throw new TypeError(); if (!IsUndefined(propertyKey)) propertyKey = ToPropertyKey(propertyKey); return OrdinaryGetMetadata(metadataKey, target, propertyKey); } exporter("getMetadata", getMetadata); /** * Gets the metadata value for the provided metadata key on the target object. * @param metadataKey A key used to store and retrieve metadata. * @param target The target object on which the metadata is defined. * @param propertyKey (Optional) The property key for the target. * @returns The metadata value for the metadata key if found; otherwise, `undefined`. * @example * * class Example { * // property declarations are not part of ES6, though they are valid in TypeScript: * // static staticProperty; * // property; * * constructor(p) { } * static staticMethod(p) { } * method(p) { } * } * * // constructor * result = Reflect.getOwnMetadata("custom:annotation", Example); * * // property (on constructor) * result = Reflect.getOwnMetadata("custom:annotation", Example, "staticProperty"); * * // property (on prototype) * result = Reflect.getOwnMetadata("custom:annotation", Example.prototype, "property"); * * // method (on constructor) * result = Reflect.getOwnMetadata("custom:annotation", Example, "staticMethod"); * * // method (on prototype) * result = Reflect.getOwnMetadata("custom:annotation", Example.prototype, "method"); * */ function getOwnMetadata(metadataKey, target, propertyKey) { if (!IsObject(target)) throw new TypeError(); if (!IsUndefined(propertyKey)) propertyKey = ToPropertyKey(propertyKey); return OrdinaryGetOwnMetadata(metadataKey, target, propertyKey); } exporter("getOwnMetadata", getOwnMetadata); /** * Gets the metadata keys defined on the target object or its prototype chain. * @param target The target object on which the metadata is defined. * @param propertyKey (Optional) The property key for the target. * @returns An array of unique metadata keys. * @example * * class Example { * // property declarations are not part of ES6, though they are valid in TypeScript: * // static staticProperty; * // property; * * constructor(p) { } * static staticMethod(p) { } * method(p) { } * } * * // constructor * result = Reflect.getMetadataKeys(Example); * * // property (on constructor) * result = Reflect.getMetadataKeys(Example, "staticProperty"); * * // property (on prototype) * result = Reflect.getMetadataKeys(Example.prototype, "property"); * * // method (on constructor) * result = Reflect.getMetadataKeys(Example, "staticMethod"); * * // method (on prototype) * result = Reflect.getMetadataKeys(Example.prototype, "method"); * */ function getMetadataKeys(target, propertyKey) { if (!IsObject(target)) throw new TypeError(); if (!IsUndefined(propertyKey)) propertyKey = ToPropertyKey(propertyKey); return OrdinaryMetadataKeys(target, propertyKey); } exporter("getMetadataKeys", getMetadataKeys); /** * Gets the unique metadata keys defined on the target object. * @param target The target object on which the metadata is defined. * @param propertyKey (Optional) The property key for the target. * @returns An array of unique metadata keys. * @example * * class Example { * // property declarations are not part of ES6, though they are valid in TypeScript: * // static staticProperty; * // property; * * constructor(p) { } * static staticMethod(p) { } * method(p) { } * } * * // constructor * result = Reflect.getOwnMetadataKeys(Example); * * // property (on constructor) * result = Reflect.getOwnMetadataKeys(Example, "staticProperty"); * * // property (on prototype) * result = Reflect.getOwnMetadataKeys(Example.prototype, "property"); * * // method (on constructor) * result = Reflect.getOwnMetadataKeys(Example, "staticMethod"); * * // method (on prototype) * result = Reflect.getOwnMetadataKeys(Example.prototype, "method"); * */ function getOwnMetadataKeys(target, propertyKey) { if (!IsObject(target)) throw new TypeError(); if (!IsUndefined(propertyKey)) propertyKey = ToPropertyKey(propertyKey); return OrdinaryOwnMetadataKeys(target, propertyKey); } exporter("getOwnMetadataKeys", getOwnMetadataKeys); /** * Deletes the metadata entry from the target object with the provided key. * @param metadataKey A key used to store and retrieve metadata. * @param target The target object on which the metadata is defined. * @param propertyKey (Optional) The property key for the target. * @returns `true` if the metadata entry was found and deleted; otherwise, false. * @example * * class Example { * // property declarations are not part of ES6, though they are valid in TypeScript: * // static staticProperty; * // property; * * constructor(p) { } * static staticMethod(p) { } * method(p) { } * } * * // constructor * result = Reflect.deleteMetadata("custom:annotation", Example); * * // property (on constructor) * result = Reflect.deleteMetadata("custom:annotation", Example, "staticProperty"); * * // property (on prototype) * result = Reflect.deleteMetadata("custom:annotation", Example.prototype, "property"); * * // method (on constructor) * result = Reflect.deleteMetadata("custom:annotation", Example, "staticMethod"); * * // method (on prototype) * result = Reflect.deleteMetadata("custom:annotation", Example.prototype, "method"); * */ function deleteMetadata(metadataKey, target, propertyKey) { if (!IsObject(target)) throw new TypeError(); if (!IsUndefined(propertyKey)) propertyKey = ToPropertyKey(propertyKey); var metadataMap = GetOrCreateMetadataMap(target, propertyKey, /*Create*/ false); if (IsUndefined(metadataMap)) return false; if (!metadataMap.delete(metadataKey)) return false; if (metadataMap.size > 0) return true; var targetMetadata = Metadata.get(target); targetMetadata.delete(propertyKey); if (targetMetadata.size > 0) return true; Metadata.delete(target); return true; } exporter("deleteMetadata", deleteMetadata); function DecorateConstructor(decorators, target) { for (var i = decorators.length - 1; i >= 0; --i) { var decorator = decorators[i]; var decorated = decorator(target); if (!IsUndefined(decorated) && !IsNull(decorated)) { if (!IsConstructor(decorated)) throw new TypeError(); target = decorated; } } return target; } function DecorateProperty(decorators, target, propertyKey, descriptor) { for (var i = decorators.length - 1; i >= 0; --i) { var decorator = decorators[i]; var decorated = decorator(target, propertyKey, descriptor); if (!IsUndefined(decorated) && !IsNull(decorated)) { if (!IsObject(decorated)) throw new TypeError(); descriptor = decorated; } } return descriptor; } function GetOrCreateMetadataMap(O, P, Create) { var targetMetadata = Metadata.get(O); if (IsUndefined(targetMetadata)) { if (!Create) return undefined; targetMetadata = new _Map(); Metadata.set(O, targetMetadata); } var metadataMap = targetMetadata.get(P); if (IsUndefined(metadataMap)) { if (!Create) return undefined; metadataMap = new _Map(); targetMetadata.set(P, metadataMap); } return metadataMap; } // 3.1.1.1 OrdinaryHasMetadata(MetadataKey, O, P) // https://rbuckton.github.io/reflect-metadata/#ordinaryhasmetadata function OrdinaryHasMetadata(MetadataKey, O, P) { var hasOwn = OrdinaryHasOwnMetadata(MetadataKey, O, P); if (hasOwn) return true; var parent = OrdinaryGetPrototypeOf(O); if (!IsNull(parent)) return OrdinaryHasMetadata(MetadataKey, parent, P); return false; } // 3.1.2.1 OrdinaryHasOwnMetadata(MetadataKey, O, P) // https://rbuckton.github.io/reflect-metadata/#ordinaryhasownmetadata function OrdinaryHasOwnMetadata(MetadataKey, O, P) { var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ false); if (IsUndefined(metadataMap)) return false; return ToBoolean(metadataMap.has(MetadataKey)); } // 3.1.3.1 OrdinaryGetMetadata(MetadataKey, O, P) // https://rbuckton.github.io/reflect-metadata/#ordinarygetmetadata function OrdinaryGetMetadata(MetadataKey, O, P) { var hasOwn = OrdinaryHasOwnMetadata(MetadataKey, O, P); if (hasOwn) return OrdinaryGetOwnMetadata(MetadataKey, O, P); var parent = OrdinaryGetPrototypeOf(O); if (!IsNull(parent)) return OrdinaryGetMetadata(MetadataKey, parent, P); return undefined; } // 3.1.4.1 OrdinaryGetOwnMetadata(MetadataKey, O, P) // https://rbuckton.github.io/reflect-metadata/#ordinarygetownmetadata function OrdinaryGetOwnMetadata(MetadataKey, O, P) { var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ false); if (IsUndefined(metadataMap)) return undefined; return metadataMap.get(MetadataKey); } // 3.1.5.1 OrdinaryDefineOwnMetadata(MetadataKey, MetadataValue, O, P) // https://rbuckton.github.io/reflect-metadata/#ordinarydefineownmetadata function OrdinaryDefineOwnMetadata(MetadataKey, MetadataValue, O, P) { var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ true); metadataMap.set(MetadataKey, MetadataValue); } // 3.1.6.1 OrdinaryMetadataKeys(O, P) // https://rbuckton.github.io/reflect-metadata/#ordinarymetadatakeys function OrdinaryMetadataKeys(O, P) { var ownKeys = OrdinaryOwnMetadataKeys(O, P); var parent = OrdinaryGetPrototypeOf(O); if (parent === null) return ownKeys; var parentKeys = OrdinaryMetadataKeys(parent, P); if (parentKeys.length <= 0) return ownKeys; if (ownKeys.length <= 0) return parentKeys; var set = new _Set(); var keys = []; for (var _i = 0, ownKeys_1 = ownKeys; _i < ownKeys_1.length; _i++) { var key = ownKeys_1[_i]; var hasKey = set.has(key); if (!hasKey) { set.add(key); keys.push(key); } } for (var _a = 0, parentKeys_1 = parentKeys; _a < parentKeys_1.length; _a++) { var key = parentKeys_1[_a]; var hasKey = set.has(key); if (!hasKey) { set.add(key); keys.push(key); } } return keys; } // 3.1.7.1 OrdinaryOwnMetadataKeys(O, P) // https://rbuckton.github.io/reflect-metadata/#ordinaryownmetadatakeys function OrdinaryOwnMetadataKeys(O, P) { var keys = []; var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ false); if (IsUndefined(metadataMap)) return keys; var keysObj = metadataMap.keys(); var iterator = GetIterator(keysObj); var k = 0; while (true) { var next = IteratorStep(iterator); if (!next) { keys.length = k; return keys; } var nextValue = IteratorValue(next); try { keys[k] = nextValue; } catch (e) { try { IteratorClose(iterator); } finally { throw e; } } k++; } } // 6 ECMAScript Data Typ0es and Values // https://tc39.github.io/ecma262/#sec-ecmascript-data-types-and-values function Type(x) { if (x === null) return 1 /* Null */; switch (typeof x) { case "undefined": return 0 /* Undefined */; case "boolean": return 2 /* Boolean */; case "string": return 3 /* String */; case "symbol": return 4 /* Symbol */; case "number": return 5 /* Number */; case "object": return x === null ? 1 /* Null */ : 6 /* Object */; default: return 6 /* Object */; } } // 6.1.1 The Undefined Type // https://tc39.github.io/ecma262/#sec-ecmascript-language-types-undefined-type function IsUndefined(x) { return x === undefined; } // 6.1.2 The Null Type // https://tc39.github.io/ecma262/#sec-ecmascript-language-types-null-type function IsNull(x) { return x === null; } // 6.1.5 The Symbol Type // https://tc39.github.io/ecma262/#sec-ecmascript-language-types-symbol-type function IsSymbol(x) { return typeof x === "symbol"; } // 6.1.7 The Object Type // https://tc39.github.io/ecma262/#sec-object-type function IsObject(x) { return typeof x === "object" ? x !== null : typeof x === "function"; } // 7.1 Type Conversion // https://tc39.github.io/ecma262/#sec-type-conversion // 7.1.1 ToPrimitive(input [, PreferredType]) // https://tc39.github.io/ecma262/#sec-toprimitive function ToPrimitive(input, PreferredType) { switch (Type(input)) { case 0 /* Undefined */: return input; case 1 /* Null */: return input; case 2 /* Boolean */: return input; case 3 /* String */: return input; case 4 /* Symbol */: return input; case 5 /* Number */: return input; } var hint = PreferredType === 3 /* String */ ? "string" : PreferredType === 5 /* Number */ ? "number" : "default"; var exoticToPrim = GetMethod(input, toPrimitiveSymbol); if (exoticToPrim !== undefined) { var result = exoticToPrim.call(input, hint); if (IsObject(result)) throw new TypeError(); return result; } return OrdinaryToPrimitive(input, hint === "default" ? "number" : hint); } // 7.1.1.1 OrdinaryToPrimitive(O, hint) // https://tc39.github.io/ecma262/#sec-ordinarytoprimitive function OrdinaryToPrimitive(O, hint) { if (hint === "string") { var toString_1 = O.toString; if (IsCallable(toString_1)) { var result = toString_1.call(O); if (!IsObject(result)) return result; } var valueOf = O.valueOf; if (IsCallable(valueOf)) { var result = valueOf.call(O); if (!IsObject(result)) return result; } } else { var valueOf = O.valueOf; if (IsCallable(valueOf)) { var result = valueOf.call(O); if (!IsObject(result)) return result; } var toString_2 = O.toString; if (IsCallable(toString_2)) { var result = toString_2.call(O); if (!IsObject(result)) return result; } } throw new TypeError(); } // 7.1.2 ToBoolean(argument) // https://tc39.github.io/ecma262/2016/#sec-toboolean function ToBoolean(argument) { return !!argument; } // 7.1.12 ToString(argument) // https://tc39.github.io/ecma262/#sec-tostring function ToString(argument) { return "" + argument; } // 7.1.14 ToPropertyKey(argument) // https://tc39.github.io/ecma262/#sec-topropertykey function ToPropertyKey(argument) { var key = ToPrimitive(argument, 3 /* String */); if (IsSymbol(key)) return key; return ToString(key); } // 7.2 Testing and Comparison Operations // https://tc39.github.io/ecma262/#sec-testing-and-comparison-operations // 7.2.2 IsArray(argument) // https://tc39.github.io/ecma262/#sec-isarray function IsArray(argument) { return Array.isArray ? Array.isArray(argument) : argument instanceof Object ? argument instanceof Array : Object.prototype.toString.call(argument) === "[object Array]"; } // 7.2.3 IsCallable(argument) // https://tc39.github.io/ecma262/#sec-iscallable function IsCallable(argument) { // NOTE: This is an approximation as we cannot check for [[Call]] internal method. return typeof argument === "function"; } // 7.2.4 IsConstructor(argument) // https://tc39.github.io/ecma262/#sec-isconstructor function IsConstructor(argument) { // NOTE: This is an approximation as we cannot check for [[Construct]] internal method. return typeof argument === "function"; } // 7.2.7 IsPropertyKey(argument) // https://tc39.github.io/ecma262/#sec-ispropertykey function IsPropertyKey(argument) { switch (Type(argument)) { case 3 /* String */: return true; case 4 /* Symbol */: return true; default: return false; } } // 7.3 Operations on Objects // https://tc39.github.io/ecma262/#sec-operations-on-objects // 7.3.9 GetMethod(V, P) // https://tc39.github.io/ecma262/#sec-getmethod function GetMethod(V, P) { var func = V[P]; if (func === undefined || func === null) return undefined; if (!IsCallable(func)) throw new TypeError(); return func; } // 7.4 Operations on Iterator Objects // https://tc39.github.io/ecma262/#sec-operations-on-iterator-objects function GetIterator(obj) { var method = GetMethod(obj, iteratorSymbol); if (!IsCallable(method)) throw new TypeError(); // from Call var iterator = method.call(obj); if (!IsObject(iterator)) throw new TypeError(); return iterator; } // 7.4.4 IteratorValue(iterResult) // https://tc39.github.io/ecma262/2016/#sec-iteratorvalue function IteratorValue(iterResult) { return iterResult.value; } // 7.4.5 IteratorStep(iterator) // https://tc39.github.io/ecma262/#sec-iteratorstep function IteratorStep(iterator) { var result = iterator.next(); return result.done ? false : result; } // 7.4.6 IteratorClose(iterator, completion) // https://tc39.github.io/ecma262/#sec-iteratorclose function IteratorClose(iterator) { var f = iterator["return"]; if (f) f.call(iterator); } // 9.1 Ordinary Object Internal Methods and Internal Slots // https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots // 9.1.1.1 OrdinaryGetPrototypeOf(O) // https://tc39.github.io/ecma262/#sec-ordinarygetprototypeof function OrdinaryGetPrototypeOf(O) { var proto = Object.getPrototypeOf(O); if (typeof O !== "function" || O === functionPrototype) return proto; // TypeScript doesn't set __proto__ in ES5, as it's non-standard. // Try to determine the superclass constructor. Compatible implementations // must either set __proto__ on a subclass constructor to the superclass constructor, // or ensure each class has a valid `constructor` property on its prototype that // points back to the constructor. // If this is not the same as Function.[[Prototype]], then this is definately inherited. // This is the case when in ES6 or when using __proto__ in a compatible browser. if (proto !== functionPrototype) return proto; // If the super prototype is Object.prototype, null, or undefined, then we cannot determine the heritage. var prototype = O.prototype; var prototypeProto = prototype && Object.getPrototypeOf(prototype); if (prototypeProto == null || prototypeProto === Object.prototype) return proto; // If the constructor was not a function, then we cannot determine the heritage. var constructor = prototypeProto.constructor; if (typeof constructor !== "function") return proto; // If we have some kind of self-reference, then we cannot determine the heritage. if (constructor === O) return proto; // we have a pretty good guess at the heritage. return constructor; } // naive Map shim function CreateMapPolyfill() { var cacheSentinel = {}; var arraySentinel = []; var MapIterator = /** @class */ (function () { function MapIterator(keys, values, selector) { this._index = 0; this._keys = keys; this._values = values; this._selector = selector; } MapIterator.prototype["@@iterator"] = function () { return this; }; MapIterator.prototype[iteratorSymbol] = function () { return this; }; MapIterator.prototype.next = function () { var index = this._index; if (index >= 0 && index < this._keys.length) { var result = this._selector(this._keys[index], this._values[index]); if (index + 1 >= this._keys.length) { this._index = -1; this._keys = arraySentinel; this._values = arraySentinel; } else { this._index++; } return { value: result, done: false }; } return { value: undefined, done: true }; }; MapIterator.prototype.throw = function (error) { if (this._index >= 0) { this._index = -1; this._keys = arraySentinel; this._values = arraySentinel; } throw error; }; MapIterator.prototype.return = function (value) { if (this._index >= 0) { this._index = -1; this._keys = arraySentinel; this._values = arraySentinel; } return { value: value, done: true }; }; return MapIterator; }()); return /** @class */ (function () { function Map() { this._keys = []; this._values = []; this._cacheKey = cacheSentinel; this._cacheIndex = -2; } Object.defineProperty(Map.prototype, "size", { get: function () { return this._keys.length; }, enumerable: true, configurable: true }); Map.prototype.has = function (key) { return this._find(key, /*insert*/ false) >= 0; }; Map.prototype.get = function (key) { var index = this._find(key, /*insert*/ false); return index >= 0 ? this._values[index] : undefined; }; Map.prototype.set = function (key, value) { var index = this._find(key, /*insert*/ true); this._values[index] = value; return this; }; Map.prototype.delete = function (key) { var index = this._find(key, /*insert*/ false); if (index >= 0) { var size = this._keys.length; for (var i = index + 1; i < size; i++) { this._keys[i - 1] = this._keys[i]; this._values[i - 1] = this._values[i]; } this._keys.length--; this._values.length--; if (key === this._cacheKey) { this._cacheKey = cacheSentinel; this._cacheIndex = -2; } return true; } return false; }; Map.prototype.clear = function () { this._keys.length = 0; this._values.length = 0; this._cacheKey = cacheSentinel; this._cacheIndex = -2; }; Map.prototype.keys = function () { return new MapIterator(this._keys, this._values, getKey); }; Map.prototype.values = function () { return new MapIterator(this._keys, this._values, getValue); }; Map.prototype.entries = function () { return new MapIterator(this._keys, this._values, getEntry); }; Map.prototype["@@iterator"] = function () { return this.entries(); }; Map.prototype[iteratorSymbol] = function () { return this.entries(); }; Map.prototype._find = function (key, insert) { if (this._cacheKey !== key) { this._cacheIndex = this._keys.indexOf(this._cacheKey = key); } if (this._cacheIndex < 0 && insert) { this._cacheIndex = this._keys.length; this._keys.push(key); this._values.push(undefined); } return this._cacheIndex; }; return Map; }()); function getKey(key, _) { return key; } function getValue(_, value) { return value; } function getEntry(key, value) { return [key, value]; } } // naive Set shim function CreateSetPolyfill() { return /** @class */ (function () { function Set() { this._map = new _Map(); } Object.defineProperty(Set.prototype, "size", { get: function () { return this._map.size; }, enumerable: true, configurable: true }); Set.prototype.has = function (value) { return this._map.has(value); }; Set.prototype.add = function (value) { return this._map.set(value, value), this; }; Set.prototype.delete = function (value) { return this._map.delete(value); }; Set.prototype.clear = function () { this._map.clear(); }; Set.prototype.keys = function () { return this._map.keys(); }; Set.prototype.values = function () { return this._map.values(); }; Set.prototype.entries = function () { return this._map.entries(); }; Set.prototype["@@iterator"] = function () { return this.keys(); }; Set.prototype[iteratorSymbol] = function () { return this.keys(); }; return Set; }()); } // naive WeakMap shim function CreateWeakMapPolyfill() { var UUID_SIZE = 16; var keys = HashMap.create(); var rootKey = CreateUniqueKey(); return /** @class */ (function () { function WeakMap() { this._key = CreateUniqueKey(); } WeakMap.prototype.has = function (target) { var table = GetOrCreateWeakMapTable(target, /*create*/ false); return table !== undefined ? HashMap.has(table, this._key) : false; }; WeakMap.prototype.get = function (target) { var table = GetOrCreateWeakMapTable(target, /*create*/ false); return table !== undefined ? HashMap.get(table, this._key) : undefined; }; WeakMap.prototype.set = function (target, value) { var table = GetOrCreateWeakMapTable(target, /*create*/ true); table[this._key] = value; return this; }; WeakMap.prototype.delete = function (target) { var table = GetOrCreateWeakMapTable(target, /*create*/ false); return table !== undefined ? delete table[this._key] : false; }; WeakMap.prototype.clear = function () { // NOTE: not a real clear, just makes the previous data unreachable this._key = CreateUniqueKey(); }; return WeakMap; }()); function CreateUniqueKey() { var key; do key = "@@WeakMap@@" + CreateUUID(); while (HashMap.has(keys, key)); keys[key] = true; return key; } function GetOrCreateWeakMapTable(target, create) { if (!hasOwn.call(target, rootKey)) { if (!create) return undefined; Object.defineProperty(target, rootKey, { value: HashMap.create() }); } return target[rootKey]; } function FillRandomBytes(buffer, size) { for (var i = 0; i < size; ++i) buffer[i] = Math.random() * 0xff | 0; return buffer; } function GenRandomBytes(size) { if (typeof Uint8Array === "function") { if (typeof crypto !== "undefined") return crypto.getRandomValues(new Uint8Array(size)); if (typeof msCrypto !== "undefined") return msCrypto.getRandomValues(new Uint8Array(size)); return FillRandomBytes(new Uint8Array(size), size); } return FillRandomBytes(new Array(size), size); } function CreateUUID() { var data = GenRandomBytes(UUID_SIZE); // mark as random - RFC 4122 § 4.4 data[6] = data[6] & 0x4f | 0x40; data[8] = data[8] & 0xbf | 0x80; var result = ""; for (var offset = 0; offset < UUID_SIZE; ++offset) { var byte = data[offset]; if (offset === 4 || offset === 6 || offset === 8) result += "-"; if (byte < 16) result += "0"; result += byte.toString(16).toLowerCase(); } return result; } } // uses a heuristic used by v8 and chakra to force an object into dictionary mode. function MakeDictionary(obj) { obj.__ = undefined; delete obj.__; return obj; } }); })(Reflect || (Reflect = {})); /***/ }), /***/ "./node_modules/semver-compare/index.js": /*!**********************************************!*\ !*** ./node_modules/semver-compare/index.js ***! \**********************************************/ /*! no static exports found */ /***/ (function(module, exports) { module.exports = function cmp (a, b) { var pa = a.split('.'); var pb = b.split('.'); for (var i = 0; i < 3; i++) { var na = Number(pa[i]); var nb = Number(pb[i]); if (na > nb) return 1; if (nb > na) return -1; if (!isNaN(na) && isNaN(nb)) return 1; if (isNaN(na) && !isNaN(nb)) return -1; } return 0; }; /***/ }), /***/ "./node_modules/semver/semver.js": /*!***************************************!*\ !*** ./node_modules/semver/semver.js ***! \***************************************/ /*! no static exports found */ /***/ (function(module, exports) { exports = module.exports = SemVer var debug /* istanbul ignore next */ if (typeof process === 'object' && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG)) { debug = function () { var args = Array.prototype.slice.call(arguments, 0) args.unshift('SEMVER') console.log.apply(console, args) } } else { debug = function () {} } // Note: this is the semver.org version of the spec that it implements // Not necessarily the package version of this code. exports.SEMVER_SPEC_VERSION = '2.0.0' var MAX_LENGTH = 256 var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || /* istanbul ignore next */ 9007199254740991 // Max safe segment length for coercion. var MAX_SAFE_COMPONENT_LENGTH = 16 // The actual regexps go on exports.re var re = exports.re = [] var src = exports.src = [] var R = 0 // The following Regular Expressions can be used for tokenizing, // validating, and parsing SemVer version strings. // ## Numeric Identifier // A single `0`, or a non-zero digit followed by zero or more digits. var NUMERICIDENTIFIER = R++ src[NUMERICIDENTIFIER] = '0|[1-9]\\d*' var NUMERICIDENTIFIERLOOSE = R++ src[NUMERICIDENTIFIERLOOSE] = '[0-9]+' // ## Non-numeric Identifier // Zero or more digits, followed by a letter or hyphen, and then zero or // more letters, digits, or hyphens. var NONNUMERICIDENTIFIER = R++ src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*' // ## Main Version // Three dot-separated numeric identifiers. var MAINVERSION = R++ src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' + '(' + src[NUMERICIDENTIFIER] + ')\\.' + '(' + src[NUMERICIDENTIFIER] + ')' var MAINVERSIONLOOSE = R++ src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + '(' + src[NUMERICIDENTIFIERLOOSE] + ')' // ## Pre-release Version Identifier // A numeric identifier, or a non-numeric identifier. var PRERELEASEIDENTIFIER = R++ src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] + '|' + src[NONNUMERICIDENTIFIER] + ')' var PRERELEASEIDENTIFIERLOOSE = R++ src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] + '|' + src[NONNUMERICIDENTIFIER] + ')' // ## Pre-release Version // Hyphen, followed by one or more dot-separated pre-release version // identifiers. var PRERELEASE = R++ src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] + '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))' var PRERELEASELOOSE = R++ src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] + '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))' // ## Build Metadata Identifier // Any combination of digits, letters, or hyphens. var BUILDIDENTIFIER = R++ src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+' // ## Build Metadata // Plus sign, followed by one or more period-separated build metadata // identifiers. var BUILD = R++ src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] + '(?:\\.' + src[BUILDIDENTIFIER] + ')*))' // ## Full Version String // A main version, followed optionally by a pre-release version and // build metadata. // Note that the only major, minor, patch, and pre-release sections of // the version string are capturing groups. The build metadata is not a // capturing group, because it should not ever be used in version // comparison. var FULL = R++ var FULLPLAIN = 'v?' + src[MAINVERSION] + src[PRERELEASE] + '?' + src[BUILD] + '?' src[FULL] = '^' + FULLPLAIN + '$' // like full, but allows v1.2.3 and =1.2.3, which people do sometimes. // also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty // common in the npm registry. var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] + src[PRERELEASELOOSE] + '?' + src[BUILD] + '?' var LOOSE = R++ src[LOOSE] = '^' + LOOSEPLAIN + '$' var GTLT = R++ src[GTLT] = '((?:<|>)?=?)' // Something like "2.*" or "1.2.x". // Note that "x.x" is a valid xRange identifer, meaning "any version" // Only the first item is strictly required. var XRANGEIDENTIFIERLOOSE = R++ src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*' var XRANGEIDENTIFIER = R++ src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*' var XRANGEPLAIN = R++ src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + '(?:' + src[PRERELEASE] + ')?' + src[BUILD] + '?' + ')?)?' var XRANGEPLAINLOOSE = R++ src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + '(?:' + src[PRERELEASELOOSE] + ')?' + src[BUILD] + '?' + ')?)?' var XRANGE = R++ src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$' var XRANGELOOSE = R++ src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$' // Coercion. // Extract anything that could conceivably be a part of a valid semver var COERCE = R++ src[COERCE] = '(?:^|[^\\d])' + '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + '(?:$|[^\\d])' // Tilde ranges. // Meaning is "reasonably at or greater than" var LONETILDE = R++ src[LONETILDE] = '(?:~>?)' var TILDETRIM = R++ src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+' re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g') var tildeTrimReplace = '$1~' var TILDE = R++ src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$' var TILDELOOSE = R++ src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$' // Caret ranges. // Meaning is "at least and backwards compatible with" var LONECARET = R++ src[LONECARET] = '(?:\\^)' var CARETTRIM = R++ src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+' re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g') var caretTrimReplace = '$1^' var CARET = R++ src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$' var CARETLOOSE = R++ src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$' // A simple gt/lt/eq thing, or just "" to indicate "any version" var COMPARATORLOOSE = R++ src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$' var COMPARATOR = R++ src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$' // An expression to strip any whitespace between the gtlt and the thing // it modifies, so that `> 1.2.3` ==> `>1.2.3` var COMPARATORTRIM = R++ src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] + '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')' // this one has to use the /g flag re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g') var comparatorTrimReplace = '$1$2$3' // Something like `1.2.3 - 1.2.4` // Note that these all use the loose form, because they'll be // checked against either the strict or loose comparator form // later. var HYPHENRANGE = R++ src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' + '\\s+-\\s+' + '(' + src[XRANGEPLAIN] + ')' + '\\s*$' var HYPHENRANGELOOSE = R++ src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' + '\\s+-\\s+' + '(' + src[XRANGEPLAINLOOSE] + ')' + '\\s*$' // Star ranges basically just allow anything at all. var STAR = R++ src[STAR] = '(<|>)?=?\\s*\\*' // Compile to actual regexp objects. // All are flag-free, unless they were created above with a flag. for (var i = 0; i < R; i++) { debug(i, src[i]) if (!re[i]) { re[i] = new RegExp(src[i]) } } exports.parse = parse function parse (version, options) { if (!options || typeof options !== 'object') { options = { loose: !!options, includePrerelease: false } } if (version instanceof SemVer) { return version } if (typeof version !== 'string') { return null } if (version.length > MAX_LENGTH) { return null } var r = options.loose ? re[LOOSE] : re[FULL] if (!r.test(version)) { return null } try { return new SemVer(version, options) } catch (er) { return null } } exports.valid = valid function valid (version, options) { var v = parse(version, options) return v ? v.version : null } exports.clean = clean function clean (version, options) { var s = parse(version.trim().replace(/^[=v]+/, ''), options) return s ? s.version : null } exports.SemVer = SemVer function SemVer (version, options) { if (!options || typeof options !== 'object') { options = { loose: !!options, includePrerelease: false } } if (version instanceof SemVer) { if (version.loose === options.loose) { return version } else { version = version.version } } else if (typeof version !== 'string') { throw new TypeError('Invalid Version: ' + version) } if (version.length > MAX_LENGTH) { throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') } if (!(this instanceof SemVer)) { return new SemVer(version, options) } debug('SemVer', version, options) this.options = options this.loose = !!options.loose var m = version.trim().match(options.loose ? re[LOOSE] : re[FULL]) if (!m) { throw new TypeError('Invalid Version: ' + version) } this.raw = version // these are actually numbers this.major = +m[1] this.minor = +m[2] this.patch = +m[3] if (this.major > MAX_SAFE_INTEGER || this.major < 0) { throw new TypeError('Invalid major version') } if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { throw new TypeError('Invalid minor version') } if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { throw new TypeError('Invalid patch version') } // numberify any prerelease numeric ids if (!m[4]) { this.prerelease = [] } else { this.prerelease = m[4].split('.').map(function (id) { if (/^[0-9]+$/.test(id)) { var num = +id if (num >= 0 && num < MAX_SAFE_INTEGER) { return num } } return id }) } this.build = m[5] ? m[5].split('.') : [] this.format() } SemVer.prototype.format = function () { this.version = this.major + '.' + this.minor + '.' + this.patch if (this.prerelease.length) { this.version += '-' + this.prerelease.join('.') } return this.version } SemVer.prototype.toString = function () { return this.version } SemVer.prototype.compare = function (other) { debug('SemVer.compare', this.version, this.options, other) if (!(other instanceof SemVer)) { other = new SemVer(other, this.options) } return this.compareMain(other) || this.comparePre(other) } SemVer.prototype.compareMain = function (other) { if (!(other instanceof SemVer)) { other = new SemVer(other, this.options) } return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch) } SemVer.prototype.comparePre = function (other) { if (!(other instanceof SemVer)) { other = new SemVer(other, this.options) } // NOT having a prerelease is > having one if (this.prerelease.length && !other.prerelease.length) { return -1 } else if (!this.prerelease.length && other.prerelease.length) { return 1 } else if (!this.prerelease.length && !other.prerelease.length) { return 0 } var i = 0 do { var a = this.prerelease[i] var b = other.prerelease[i] debug('prerelease compare', i, a, b) if (a === undefined && b === undefined) { return 0 } else if (b === undefined) { return 1 } else if (a === undefined) { return -1 } else if (a === b) { continue } else { return compareIdentifiers(a, b) } } while (++i) } // preminor will bump the version up to the next minor release, and immediately // down to pre-release. premajor and prepatch work the same way. SemVer.prototype.inc = function (release, identifier) { switch (release) { case 'premajor': this.prerelease.length = 0 this.patch = 0 this.minor = 0 this.major++ this.inc('pre', identifier) break case 'preminor': this.prerelease.length = 0 this.patch = 0 this.minor++ this.inc('pre', identifier) break case 'prepatch': // If this is already a prerelease, it will bump to the next version // drop any prereleases that might already exist, since they are not // relevant at this point. this.prerelease.length = 0 this.inc('patch', identifier) this.inc('pre', identifier) break // If the input is a non-prerelease version, this acts the same as // prepatch. case 'prerelease': if (this.prerelease.length === 0) { this.inc('patch', identifier) } this.inc('pre', identifier) break case 'major': // If this is a pre-major version, bump up to the same major version. // Otherwise increment major. // 1.0.0-5 bumps to 1.0.0 // 1.1.0 bumps to 2.0.0 if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) { this.major++ } this.minor = 0 this.patch = 0 this.prerelease = [] break case 'minor': // If this is a pre-minor version, bump up to the same minor version. // Otherwise increment minor. // 1.2.0-5 bumps to 1.2.0 // 1.2.1 bumps to 1.3.0 if (this.patch !== 0 || this.prerelease.length === 0) { this.minor++ } this.patch = 0 this.prerelease = [] break case 'patch': // If this is not a pre-release version, it will increment the patch. // If it is a pre-release it will bump up to the same patch version. // 1.2.0-5 patches to 1.2.0 // 1.2.0 patches to 1.2.1 if (this.prerelease.length === 0) { this.patch++ } this.prerelease = [] break // This probably shouldn't be used publicly. // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. case 'pre': if (this.prerelease.length === 0) { this.prerelease = [0] } else { var i = this.prerelease.length while (--i >= 0) { if (typeof this.prerelease[i] === 'number') { this.prerelease[i]++ i = -2 } } if (i === -1) { // didn't increment anything this.prerelease.push(0) } } if (identifier) { // 1.2.0-beta.1 bumps to 1.2.0-beta.2, // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 if (this.prerelease[0] === identifier) { if (isNaN(this.prerelease[1])) { this.prerelease = [identifier, 0] } } else { this.prerelease = [identifier, 0] } } break default: throw new Error('invalid increment argument: ' + release) } this.format() this.raw = this.version return this } exports.inc = inc function inc (version, release, loose, identifier) { if (typeof (loose) === 'string') { identifier = loose loose = undefined } try { return new SemVer(version, loose).inc(release, identifier).version } catch (er) { return null } } exports.diff = diff function diff (version1, version2) { if (eq(version1, version2)) { return null } else { var v1 = parse(version1) var v2 = parse(version2) var prefix = '' if (v1.prerelease.length || v2.prerelease.length) { prefix = 'pre' var defaultResult = 'prerelease' } for (var key in v1) { if (key === 'major' || key === 'minor' || key === 'patch') { if (v1[key] !== v2[key]) { return prefix + key } } } return defaultResult // may be undefined } } exports.compareIdentifiers = compareIdentifiers var numeric = /^[0-9]+$/ function compareIdentifiers (a, b) { var anum = numeric.test(a) var bnum = numeric.test(b) if (anum && bnum) { a = +a b = +b } return a === b ? 0 : (anum && !bnum) ? -1 : (bnum && !anum) ? 1 : a < b ? -1 : 1 } exports.rcompareIdentifiers = rcompareIdentifiers function rcompareIdentifiers (a, b) { return compareIdentifiers(b, a) } exports.major = major function major (a, loose) { return new SemVer(a, loose).major } exports.minor = minor function minor (a, loose) { return new SemVer(a, loose).minor } exports.patch = patch function patch (a, loose) { return new SemVer(a, loose).patch } exports.compare = compare function compare (a, b, loose) { return new SemVer(a, loose).compare(new SemVer(b, loose)) } exports.compareLoose = compareLoose function compareLoose (a, b) { return compare(a, b, true) } exports.rcompare = rcompare function rcompare (a, b, loose) { return compare(b, a, loose) } exports.sort = sort function sort (list, loose) { return list.sort(function (a, b) { return exports.compare(a, b, loose) }) } exports.rsort = rsort function rsort (list, loose) { return list.sort(function (a, b) { return exports.rcompare(a, b, loose) }) } exports.gt = gt function gt (a, b, loose) { return compare(a, b, loose) > 0 } exports.lt = lt function lt (a, b, loose) { return compare(a, b, loose) < 0 } exports.eq = eq function eq (a, b, loose) { return compare(a, b, loose) === 0 } exports.neq = neq function neq (a, b, loose) { return compare(a, b, loose) !== 0 } exports.gte = gte function gte (a, b, loose) { return compare(a, b, loose) >= 0 } exports.lte = lte function lte (a, b, loose) { return compare(a, b, loose) <= 0 } exports.cmp = cmp function cmp (a, op, b, loose) { switch (op) { case '===': if (typeof a === 'object') a = a.version if (typeof b === 'object') b = b.version return a === b case '!==': if (typeof a === 'object') a = a.version if (typeof b === 'object') b = b.version return a !== b case '': case '=': case '==': return eq(a, b, loose) case '!=': return neq(a, b, loose) case '>': return gt(a, b, loose) case '>=': return gte(a, b, loose) case '<': return lt(a, b, loose) case '<=': return lte(a, b, loose) default: throw new TypeError('Invalid operator: ' + op) } } exports.Comparator = Comparator function Comparator (comp, options) { if (!options || typeof options !== 'object') { options = { loose: !!options, includePrerelease: false } } if (comp instanceof Comparator) { if (comp.loose === !!options.loose) { return comp } else { comp = comp.value } } if (!(this instanceof Comparator)) { return new Comparator(comp, options) } debug('comparator', comp, options) this.options = options this.loose = !!options.loose this.parse(comp) if (this.semver === ANY) { this.value = '' } else { this.value = this.operator + this.semver.version } debug('comp', this) } var ANY = {} Comparator.prototype.parse = function (comp) { var r = this.options.loose ? re[COMPARATORLOOSE] : re[COMPARATOR] var m = comp.match(r) if (!m) { throw new TypeError('Invalid comparator: ' + comp) } this.operator = m[1] if (this.operator === '=') { this.operator = '' } // if it literally is just '>' or '' then allow anything. if (!m[2]) { this.semver = ANY } else { this.semver = new SemVer(m[2], this.options.loose) } } Comparator.prototype.toString = function () { return this.value } Comparator.prototype.test = function (version) { debug('Comparator.test', version, this.options.loose) if (this.semver === ANY) { return true } if (typeof version === 'string') { version = new SemVer(version, this.options) } return cmp(version, this.operator, this.semver, this.options) } Comparator.prototype.intersects = function (comp, options) { if (!(comp instanceof Comparator)) { throw new TypeError('a Comparator is required') } if (!options || typeof options !== 'object') { options = { loose: !!options, includePrerelease: false } } var rangeTmp if (this.operator === '') { rangeTmp = new Range(comp.value, options) return satisfies(this.value, rangeTmp, options) } else if (comp.operator === '') { rangeTmp = new Range(this.value, options) return satisfies(comp.semver, rangeTmp, options) } var sameDirectionIncreasing = (this.operator === '>=' || this.operator === '>') && (comp.operator === '>=' || comp.operator === '>') var sameDirectionDecreasing = (this.operator === '<=' || this.operator === '<') && (comp.operator === '<=' || comp.operator === '<') var sameSemVer = this.semver.version === comp.semver.version var differentDirectionsInclusive = (this.operator === '>=' || this.operator === '<=') && (comp.operator === '>=' || comp.operator === '<=') var oppositeDirectionsLessThan = cmp(this.semver, '<', comp.semver, options) && ((this.operator === '>=' || this.operator === '>') && (comp.operator === '<=' || comp.operator === '<')) var oppositeDirectionsGreaterThan = cmp(this.semver, '>', comp.semver, options) && ((this.operator === '<=' || this.operator === '<') && (comp.operator === '>=' || comp.operator === '>')) return sameDirectionIncreasing || sameDirectionDecreasing || (sameSemVer && differentDirectionsInclusive) || oppositeDirectionsLessThan || oppositeDirectionsGreaterThan } exports.Range = Range function Range (range, options) { if (!options || typeof options !== 'object') { options = { loose: !!options, includePrerelease: false } } if (range instanceof Range) { if (range.loose === !!options.loose && range.includePrerelease === !!options.includePrerelease) { return range } else { return new Range(range.raw, options) } } if (range instanceof Comparator) { return new Range(range.value, options) } if (!(this instanceof Range)) { return new Range(range, options) } this.options = options this.loose = !!options.loose this.includePrerelease = !!options.includePrerelease // First, split based on boolean or || this.raw = range this.set = range.split(/\s*\|\|\s*/).map(function (range) { return this.parseRange(range.trim()) }, this).filter(function (c) { // throw out any that are not relevant for whatever reason return c.length }) if (!this.set.length) { throw new TypeError('Invalid SemVer Range: ' + range) } this.format() } Range.prototype.format = function () { this.range = this.set.map(function (comps) { return comps.join(' ').trim() }).join('||').trim() return this.range } Range.prototype.toString = function () { return this.range } Range.prototype.parseRange = function (range) { var loose = this.options.loose range = range.trim() // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE] range = range.replace(hr, hyphenReplace) debug('hyphen replace', range) // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace) debug('comparator trim', range, re[COMPARATORTRIM]) // `~ 1.2.3` => `~1.2.3` range = range.replace(re[TILDETRIM], tildeTrimReplace) // `^ 1.2.3` => `^1.2.3` range = range.replace(re[CARETTRIM], caretTrimReplace) // normalize spaces range = range.split(/\s+/).join(' ') // At this point, the range is completely trimmed and // ready to be split into comparators. var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR] var set = range.split(' ').map(function (comp) { return parseComparator(comp, this.options) }, this).join(' ').split(/\s+/) if (this.options.loose) { // in loose mode, throw out any that are not valid comparators set = set.filter(function (comp) { return !!comp.match(compRe) }) } set = set.map(function (comp) { return new Comparator(comp, this.options) }, this) return set } Range.prototype.intersects = function (range, options) { if (!(range instanceof Range)) { throw new TypeError('a Range is required') } return this.set.some(function (thisComparators) { return thisComparators.every(function (thisComparator) { return range.set.some(function (rangeComparators) { return rangeComparators.every(function (rangeComparator) { return thisComparator.intersects(rangeComparator, options) }) }) }) }) } // Mostly just for testing and legacy API reasons exports.toComparators = toComparators function toComparators (range, options) { return new Range(range, options).set.map(function (comp) { return comp.map(function (c) { return c.value }).join(' ').trim().split(' ') }) } // comprised of xranges, tildes, stars, and gtlt's at this point. // already replaced the hyphen ranges // turn into a set of JUST comparators. function parseComparator (comp, options) { debug('comp', comp, options) comp = replaceCarets(comp, options) debug('caret', comp) comp = replaceTildes(comp, options) debug('tildes', comp) comp = replaceXRanges(comp, options) debug('xrange', comp) comp = replaceStars(comp, options) debug('stars', comp) return comp } function isX (id) { return !id || id.toLowerCase() === 'x' || id === '*' } // ~, ~> --> * (any, kinda silly) // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 function replaceTildes (comp, options) { return comp.trim().split(/\s+/).map(function (comp) { return replaceTilde(comp, options) }).join(' ') } function replaceTilde (comp, options) { var r = options.loose ? re[TILDELOOSE] : re[TILDE] return comp.replace(r, function (_, M, m, p, pr) { debug('tilde', comp, _, M, m, p, pr) var ret if (isX(M)) { ret = '' } else if (isX(m)) { ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' } else if (isX(p)) { // ~1.2 == >=1.2.0 <1.3.0 ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' } else if (pr) { debug('replaceTilde pr', pr) ret = '>=' + M + '.' + m + '.' + p + '-' + pr + ' <' + M + '.' + (+m + 1) + '.0' } else { // ~1.2.3 == >=1.2.3 <1.3.0 ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + (+m + 1) + '.0' } debug('tilde return', ret) return ret }) } // ^ --> * (any, kinda silly) // ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 // ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 // ^1.2.3 --> >=1.2.3 <2.0.0 // ^1.2.0 --> >=1.2.0 <2.0.0 function replaceCarets (comp, options) { return comp.trim().split(/\s+/).map(function (comp) { return replaceCaret(comp, options) }).join(' ') } function replaceCaret (comp, options) { debug('caret', comp, options) var r = options.loose ? re[CARETLOOSE] : re[CARET] return comp.replace(r, function (_, M, m, p, pr) { debug('caret', comp, _, M, m, p, pr) var ret if (isX(M)) { ret = '' } else if (isX(m)) { ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' } else if (isX(p)) { if (M === '0') { ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' } else { ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0' } } else if (pr) { debug('replaceCaret pr', pr) if (M === '0') { if (m === '0') { ret = '>=' + M + '.' + m + '.' + p + '-' + pr + ' <' + M + '.' + m + '.' + (+p + 1) } else { ret = '>=' + M + '.' + m + '.' + p + '-' + pr + ' <' + M + '.' + (+m + 1) + '.0' } } else { ret = '>=' + M + '.' + m + '.' + p + '-' + pr + ' <' + (+M + 1) + '.0.0' } } else { debug('no pr') if (M === '0') { if (m === '0') { ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + m + '.' + (+p + 1) } else { ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + (+m + 1) + '.0' } } else { ret = '>=' + M + '.' + m + '.' + p + ' <' + (+M + 1) + '.0.0' } } debug('caret return', ret) return ret }) } function replaceXRanges (comp, options) { debug('replaceXRanges', comp, options) return comp.split(/\s+/).map(function (comp) { return replaceXRange(comp, options) }).join(' ') } function replaceXRange (comp, options) { comp = comp.trim() var r = options.loose ? re[XRANGELOOSE] : re[XRANGE] return comp.replace(r, function (ret, gtlt, M, m, p, pr) { debug('xRange', comp, ret, gtlt, M, m, p, pr) var xM = isX(M) var xm = xM || isX(m) var xp = xm || isX(p) var anyX = xp if (gtlt === '=' && anyX) { gtlt = '' } if (xM) { if (gtlt === '>' || gtlt === '<') { // nothing is allowed ret = '<0.0.0' } else { // nothing is forbidden ret = '*' } } else if (gtlt && anyX) { // we know patch is an x, because we have any x at all. // replace X with 0 if (xm) { m = 0 } p = 0 if (gtlt === '>') { // >1 => >=2.0.0 // >1.2 => >=1.3.0 // >1.2.3 => >= 1.2.4 gtlt = '>=' if (xm) { M = +M + 1 m = 0 p = 0 } else { m = +m + 1 p = 0 } } else if (gtlt === '<=') { // <=0.7.x is actually <0.8.0, since any 0.7.x should // pass. Similarly, <=7.x is actually <8.0.0, etc. gtlt = '<' if (xm) { M = +M + 1 } else { m = +m + 1 } } ret = gtlt + M + '.' + m + '.' + p } else if (xm) { ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' } else if (xp) { ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' } debug('xRange return', ret) return ret }) } // Because * is AND-ed with everything else in the comparator, // and '' means "any version", just remove the *s entirely. function replaceStars (comp, options) { debug('replaceStars', comp, options) // Looseness is ignored here. star is always as loose as it gets! return comp.trim().replace(re[STAR], '') } // This function is passed to string.replace(re[HYPHENRANGE]) // M, m, patch, prerelease, build // 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 // 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do // 1.2 - 3.4 => >=1.2.0 <3.5.0 function hyphenReplace ($0, from, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr, tb) { if (isX(fM)) { from = '' } else if (isX(fm)) { from = '>=' + fM + '.0.0' } else if (isX(fp)) { from = '>=' + fM + '.' + fm + '.0' } else { from = '>=' + from } if (isX(tM)) { to = '' } else if (isX(tm)) { to = '<' + (+tM + 1) + '.0.0' } else if (isX(tp)) { to = '<' + tM + '.' + (+tm + 1) + '.0' } else if (tpr) { to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr } else { to = '<=' + to } return (from + ' ' + to).trim() } // if ANY of the sets match ALL of its comparators, then pass Range.prototype.test = function (version) { if (!version) { return false } if (typeof version === 'string') { version = new SemVer(version, this.options) } for (var i = 0; i < this.set.length; i++) { if (testSet(this.set[i], version, this.options)) { return true } } return false } function testSet (set, version, options) { for (var i = 0; i < set.length; i++) { if (!set[i].test(version)) { return false } } if (version.prerelease.length && !options.includePrerelease) { // Find the set of versions that are allowed to have prereleases // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 // That should allow `1.2.3-pr.2` to pass. // However, `1.2.4-alpha.notready` should NOT be allowed, // even though it's within the range set by the comparators. for (i = 0; i < set.length; i++) { debug(set[i].semver) if (set[i].semver === ANY) { continue } if (set[i].semver.prerelease.length > 0) { var allowed = set[i].semver if (allowed.major === version.major && allowed.minor === version.minor && allowed.patch === version.patch) { return true } } } // Version has a -pre, but it's not one of the ones we like. return false } return true } exports.satisfies = satisfies function satisfies (version, range, options) { try { range = new Range(range, options) } catch (er) { return false } return range.test(version) } exports.maxSatisfying = maxSatisfying function maxSatisfying (versions, range, options) { var max = null var maxSV = null try { var rangeObj = new Range(range, options) } catch (er) { return null } versions.forEach(function (v) { if (rangeObj.test(v)) { // satisfies(v, range, options) if (!max || maxSV.compare(v) === -1) { // compare(max, v, true) max = v maxSV = new SemVer(max, options) } } }) return max } exports.minSatisfying = minSatisfying function minSatisfying (versions, range, options) { var min = null var minSV = null try { var rangeObj = new Range(range, options) } catch (er) { return null } versions.forEach(function (v) { if (rangeObj.test(v)) { // satisfies(v, range, options) if (!min || minSV.compare(v) === 1) { // compare(min, v, true) min = v minSV = new SemVer(min, options) } } }) return min } exports.minVersion = minVersion function minVersion (range, loose) { range = new Range(range, loose) var minver = new SemVer('0.0.0') if (range.test(minver)) { return minver } minver = new SemVer('0.0.0-0') if (range.test(minver)) { return minver } minver = null for (var i = 0; i < range.set.length; ++i) { var comparators = range.set[i] comparators.forEach(function (comparator) { // Clone to avoid manipulating the comparator's semver object. var compver = new SemVer(comparator.semver.version) switch (comparator.operator) { case '>': if (compver.prerelease.length === 0) { compver.patch++ } else { compver.prerelease.push(0) } compver.raw = compver.format() /* fallthrough */ case '': case '>=': if (!minver || gt(minver, compver)) { minver = compver } break case '<': case '<=': /* Ignore maximum versions */ break /* istanbul ignore next */ default: throw new Error('Unexpected operation: ' + comparator.operator) } }) } if (minver && range.test(minver)) { return minver } return null } exports.validRange = validRange function validRange (range, options) { try { // Return '*' instead of '' so that truthiness works. // This will throw if it's invalid anyway return new Range(range, options).range || '*' } catch (er) { return null } } // Determine if version is less than all the versions possible in the range exports.ltr = ltr function ltr (version, range, options) { return outside(version, range, '<', options) } // Determine if version is greater than all the versions possible in the range. exports.gtr = gtr function gtr (version, range, options) { return outside(version, range, '>', options) } exports.outside = outside function outside (version, range, hilo, options) { version = new SemVer(version, options) range = new Range(range, options) var gtfn, ltefn, ltfn, comp, ecomp switch (hilo) { case '>': gtfn = gt ltefn = lte ltfn = lt comp = '>' ecomp = '>=' break case '<': gtfn = lt ltefn = gte ltfn = gt comp = '<' ecomp = '<=' break default: throw new TypeError('Must provide a hilo val of "<" or ">"') } // If it satisifes the range it is not outside if (satisfies(version, range, options)) { return false } // From now on, variable terms are as if we're in "gtr" mode. // but note that everything is flipped for the "ltr" function. for (var i = 0; i < range.set.length; ++i) { var comparators = range.set[i] var high = null var low = null comparators.forEach(function (comparator) { if (comparator.semver === ANY) { comparator = new Comparator('>=0.0.0') } high = high || comparator low = low || comparator if (gtfn(comparator.semver, high.semver, options)) { high = comparator } else if (ltfn(comparator.semver, low.semver, options)) { low = comparator } }) // If the edge version comparator has a operator then our version // isn't outside it if (high.operator === comp || high.operator === ecomp) { return false } // If the lowest version comparator has an operator and our version // is less than it then it isn't higher than the range if ((!low.operator || low.operator === comp) && ltefn(version, low.semver)) { return false } else if (low.operator === ecomp && ltfn(version, low.semver)) { return false } } return true } exports.prerelease = prerelease function prerelease (version, options) { var parsed = parse(version, options) return (parsed && parsed.prerelease.length) ? parsed.prerelease : null } exports.intersects = intersects function intersects (r1, r2, options) { r1 = new Range(r1, options) r2 = new Range(r2, options) return r1.intersects(r2) } exports.coerce = coerce function coerce (version) { if (version instanceof SemVer) { return version } if (typeof version !== 'string') { return null } var match = version.match(re[COERCE]) if (match == null) { return null } return parse(match[1] + '.' + (match[2] || '0') + '.' + (match[3] || '0')) } /***/ }), /***/ "./node_modules/tunnel/index.js": /*!**************************************!*\ !*** ./node_modules/tunnel/index.js ***! \**************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { module.exports = __webpack_require__(/*! ./lib/tunnel */ "./node_modules/tunnel/lib/tunnel.js"); /***/ }), /***/ "./node_modules/tunnel/lib/tunnel.js": /*!*******************************************!*\ !*** ./node_modules/tunnel/lib/tunnel.js ***! \*******************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var net = __webpack_require__(/*! net */ "net"); var tls = __webpack_require__(/*! tls */ "tls"); var http = __webpack_require__(/*! http */ "http"); var https = __webpack_require__(/*! https */ "https"); var events = __webpack_require__(/*! events */ "events"); var assert = __webpack_require__(/*! assert */ "assert"); var util = __webpack_require__(/*! util */ "util"); exports.httpOverHttp = httpOverHttp; exports.httpsOverHttp = httpsOverHttp; exports.httpOverHttps = httpOverHttps; exports.httpsOverHttps = httpsOverHttps; function httpOverHttp(options) { var agent = new TunnelingAgent(options); agent.request = http.request; return agent; } function httpsOverHttp(options) { var agent = new TunnelingAgent(options); agent.request = http.request; agent.createSocket = createSecureSocket; return agent; } function httpOverHttps(options) { var agent = new TunnelingAgent(options); agent.request = https.request; return agent; } function httpsOverHttps(options) { var agent = new TunnelingAgent(options); agent.request = https.request; agent.createSocket = createSecureSocket; return agent; } function TunnelingAgent(options) { var self = this; self.options = options || {}; self.proxyOptions = self.options.proxy || {}; self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; self.requests = []; self.sockets = []; self.on('free', function onFree(socket, host, port, localAddress) { var options = toOptions(host, port, localAddress); for (var i = 0, len = self.requests.length; i < len; ++i) { var pending = self.requests[i]; if (pending.host === options.host && pending.port === options.port) { // Detect the request to connect same origin server, // reuse the connection. self.requests.splice(i, 1); pending.request.onSocket(socket); return; } } socket.destroy(); self.removeSocket(socket); }); } util.inherits(TunnelingAgent, events.EventEmitter); TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { var self = this; var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); if (self.sockets.length >= this.maxSockets) { // We are over limit so we'll add it to the queue. self.requests.push(options); return; } // If we are under maxSockets create a new one. self.createSocket(options, function(socket) { socket.on('free', onFree); socket.on('close', onCloseOrRemove); socket.on('agentRemove', onCloseOrRemove); req.onSocket(socket); function onFree() { self.emit('free', socket, options); } function onCloseOrRemove(err) { self.removeSocket(socket); socket.removeListener('free', onFree); socket.removeListener('close', onCloseOrRemove); socket.removeListener('agentRemove', onCloseOrRemove); } }); }; TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { var self = this; var placeholder = {}; self.sockets.push(placeholder); var connectOptions = mergeOptions({}, self.proxyOptions, { method: 'CONNECT', path: options.host + ':' + options.port, agent: false }); if (connectOptions.proxyAuth) { connectOptions.headers = connectOptions.headers || {}; connectOptions.headers['Proxy-Authorization'] = 'Basic ' + new Buffer(connectOptions.proxyAuth).toString('base64'); } debug('making CONNECT request'); var connectReq = self.request(connectOptions); connectReq.useChunkedEncodingByDefault = false; // for v0.6 connectReq.once('response', onResponse); // for v0.6 connectReq.once('upgrade', onUpgrade); // for v0.6 connectReq.once('connect', onConnect); // for v0.7 or later connectReq.once('error', onError); connectReq.end(); function onResponse(res) { // Very hacky. This is necessary to avoid http-parser leaks. res.upgrade = true; } function onUpgrade(res, socket, head) { // Hacky. process.nextTick(function() { onConnect(res, socket, head); }); } function onConnect(res, socket, head) { connectReq.removeAllListeners(); socket.removeAllListeners(); if (res.statusCode === 200) { assert.equal(head.length, 0); debug('tunneling connection has established'); self.sockets[self.sockets.indexOf(placeholder)] = socket; cb(socket); } else { debug('tunneling socket could not be established, statusCode=%d', res.statusCode); var error = new Error('tunneling socket could not be established, ' + 'statusCode=' + res.statusCode); error.code = 'ECONNRESET'; options.request.emit('error', error); self.removeSocket(placeholder); } } function onError(cause) { connectReq.removeAllListeners(); debug('tunneling socket could not be established, cause=%s\n', cause.message, cause.stack); var error = new Error('tunneling socket could not be established, ' + 'cause=' + cause.message); error.code = 'ECONNRESET'; options.request.emit('error', error); self.removeSocket(placeholder); } }; TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { var pos = this.sockets.indexOf(socket) if (pos === -1) { return; } this.sockets.splice(pos, 1); var pending = this.requests.shift(); if (pending) { // If we have pending requests and a socket gets closed a new one // needs to be created to take over in the pool for the one that closed. this.createSocket(pending, function(socket) { pending.request.onSocket(socket); }); } }; function createSecureSocket(options, cb) { var self = this; TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { var hostHeader = options.request.getHeader('host'); var tlsOptions = mergeOptions({}, self.options, { socket: socket, servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host }); // 0 is dummy port for v0.6 var secureSocket = tls.connect(0, tlsOptions); self.sockets[self.sockets.indexOf(socket)] = secureSocket; cb(secureSocket); }); } function toOptions(host, port, localAddress) { if (typeof host === 'string') { // since v0.10 return { host: host, port: port, localAddress: localAddress }; } return host; // for v0.11 or later } function mergeOptions(target) { for (var i = 1, len = arguments.length; i < len; ++i) { var overrides = arguments[i]; if (typeof overrides === 'object') { var keys = Object.keys(overrides); for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { var k = keys[j]; if (overrides[k] !== undefined) { target[k] = overrides[k]; } } } } return target; } var debug; if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { debug = function() { var args = Array.prototype.slice.call(arguments); if (typeof args[0] === 'string') { args[0] = 'TUNNEL: ' + args[0]; } else { args.unshift('TUNNEL:'); } console.error.apply(console, args); } } else { debug = function() {}; } exports.debug = debug; // for test /***/ }), /***/ "./node_modules/typed-rest-client/HttpClient.js": /*!******************************************************!*\ !*** ./node_modules/typed-rest-client/HttpClient.js ***! \******************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const url = __webpack_require__(/*! url */ "url"); const http = __webpack_require__(/*! http */ "http"); const https = __webpack_require__(/*! https */ "https"); const util = __webpack_require__(/*! ./Util */ "./node_modules/typed-rest-client/Util.js"); let fs; let tunnel; var HttpCodes; (function (HttpCodes) { HttpCodes[HttpCodes["OK"] = 200] = "OK"; HttpCodes[HttpCodes["MultipleChoices"] = 300] = "MultipleChoices"; HttpCodes[HttpCodes["MovedPermanently"] = 301] = "MovedPermanently"; HttpCodes[HttpCodes["ResourceMoved"] = 302] = "ResourceMoved"; HttpCodes[HttpCodes["SeeOther"] = 303] = "SeeOther"; HttpCodes[HttpCodes["NotModified"] = 304] = "NotModified"; HttpCodes[HttpCodes["UseProxy"] = 305] = "UseProxy"; HttpCodes[HttpCodes["SwitchProxy"] = 306] = "SwitchProxy"; HttpCodes[HttpCodes["TemporaryRedirect"] = 307] = "TemporaryRedirect"; HttpCodes[HttpCodes["PermanentRedirect"] = 308] = "PermanentRedirect"; HttpCodes[HttpCodes["BadRequest"] = 400] = "BadRequest"; HttpCodes[HttpCodes["Unauthorized"] = 401] = "Unauthorized"; HttpCodes[HttpCodes["PaymentRequired"] = 402] = "PaymentRequired"; HttpCodes[HttpCodes["Forbidden"] = 403] = "Forbidden"; HttpCodes[HttpCodes["NotFound"] = 404] = "NotFound"; HttpCodes[HttpCodes["MethodNotAllowed"] = 405] = "MethodNotAllowed"; HttpCodes[HttpCodes["NotAcceptable"] = 406] = "NotAcceptable"; HttpCodes[HttpCodes["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired"; HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout"; HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict"; HttpCodes[HttpCodes["Gone"] = 410] = "Gone"; HttpCodes[HttpCodes["TooManyRequests"] = 429] = "TooManyRequests"; HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError"; HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented"; HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway"; HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable"; HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout"; })(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {})); const HttpRedirectCodes = [HttpCodes.MovedPermanently, HttpCodes.ResourceMoved, HttpCodes.SeeOther, HttpCodes.TemporaryRedirect, HttpCodes.PermanentRedirect]; const HttpResponseRetryCodes = [HttpCodes.BadGateway, HttpCodes.ServiceUnavailable, HttpCodes.GatewayTimeout]; const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD']; const ExponentialBackoffCeiling = 10; const ExponentialBackoffTimeSlice = 5; class HttpClientResponse { constructor(message) { this.message = message; } readBody() { return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { let buffer = Buffer.alloc(0); const encodingCharset = util.obtainContentCharset(this); // Extract Encoding from header: 'content-encoding' // Match `gzip`, `gzip, deflate` variations of GZIP encoding const contentEncoding = this.message.headers['content-encoding'] || ''; const isGzippedEncoded = new RegExp('(gzip$)|(gzip, *deflate)').test(contentEncoding); this.message.on('data', function (data) { const chunk = (typeof data === 'string') ? Buffer.from(data, encodingCharset) : data; buffer = Buffer.concat([buffer, chunk]); }).on('end', function () { return __awaiter(this, void 0, void 0, function* () { if (isGzippedEncoded) { // Process GZipped Response Body HERE const gunzippedBody = yield util.decompressGzippedContent(buffer, encodingCharset); resolve(gunzippedBody); } resolve(buffer.toString(encodingCharset)); }); }).on('error', function (err) { reject(err); }); })); } } exports.HttpClientResponse = HttpClientResponse; function isHttps(requestUrl) { let parsedUrl = url.parse(requestUrl); return parsedUrl.protocol === 'https:'; } exports.isHttps = isHttps; var EnvironmentVariables; (function (EnvironmentVariables) { EnvironmentVariables["HTTP_PROXY"] = "HTTP_PROXY"; EnvironmentVariables["HTTPS_PROXY"] = "HTTPS_PROXY"; EnvironmentVariables["NO_PROXY"] = "NO_PROXY"; })(EnvironmentVariables || (EnvironmentVariables = {})); class HttpClient { constructor(userAgent, handlers, requestOptions) { this._ignoreSslError = false; this._allowRedirects = true; this._allowRedirectDowngrade = false; this._maxRedirects = 50; this._allowRetries = false; this._maxRetries = 1; this._keepAlive = false; this._disposed = false; this.userAgent = userAgent; this.handlers = handlers || []; let no_proxy = process.env[EnvironmentVariables.NO_PROXY]; if (no_proxy) { this._httpProxyBypassHosts = []; no_proxy.split(',').forEach(bypass => { this._httpProxyBypassHosts.push(new RegExp(bypass, 'i')); }); } this.requestOptions = requestOptions; if (requestOptions) { if (requestOptions.ignoreSslError != null) { this._ignoreSslError = requestOptions.ignoreSslError; } this._socketTimeout = requestOptions.socketTimeout; this._httpProxy = requestOptions.proxy; if (requestOptions.proxy && requestOptions.proxy.proxyBypassHosts) { this._httpProxyBypassHosts = []; requestOptions.proxy.proxyBypassHosts.forEach(bypass => { this._httpProxyBypassHosts.push(new RegExp(bypass, 'i')); }); } this._certConfig = requestOptions.cert; if (this._certConfig) { // If using cert, need fs fs = __webpack_require__(/*! fs */ "fs"); // cache the cert content into memory, so we don't have to read it from disk every time if (this._certConfig.caFile && fs.existsSync(this._certConfig.caFile)) { this._ca = fs.readFileSync(this._certConfig.caFile, 'utf8'); } if (this._certConfig.certFile && fs.existsSync(this._certConfig.certFile)) { this._cert = fs.readFileSync(this._certConfig.certFile, 'utf8'); } if (this._certConfig.keyFile && fs.existsSync(this._certConfig.keyFile)) { this._key = fs.readFileSync(this._certConfig.keyFile, 'utf8'); } } if (requestOptions.allowRedirects != null) { this._allowRedirects = requestOptions.allowRedirects; } if (requestOptions.allowRedirectDowngrade != null) { this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade; } if (requestOptions.maxRedirects != null) { this._maxRedirects = Math.max(requestOptions.maxRedirects, 0); } if (requestOptions.keepAlive != null) { this._keepAlive = requestOptions.keepAlive; } if (requestOptions.allowRetries != null) { this._allowRetries = requestOptions.allowRetries; } if (requestOptions.maxRetries != null) { this._maxRetries = requestOptions.maxRetries; } } } options(requestUrl, additionalHeaders) { return this.request('OPTIONS', requestUrl, null, additionalHeaders || {}); } get(requestUrl, additionalHeaders) { return this.request('GET', requestUrl, null, additionalHeaders || {}); } del(requestUrl, additionalHeaders) { return this.request('DELETE', requestUrl, null, additionalHeaders || {}); } post(requestUrl, data, additionalHeaders) { return this.request('POST', requestUrl, data, additionalHeaders || {}); } patch(requestUrl, data, additionalHeaders) { return this.request('PATCH', requestUrl, data, additionalHeaders || {}); } put(requestUrl, data, additionalHeaders) { return this.request('PUT', requestUrl, data, additionalHeaders || {}); } head(requestUrl, additionalHeaders) { return this.request('HEAD', requestUrl, null, additionalHeaders || {}); } sendStream(verb, requestUrl, stream, additionalHeaders) { return this.request(verb, requestUrl, stream, additionalHeaders); } /** * Makes a raw http request. * All other methods such as get, post, patch, and request ultimately call this. * Prefer get, del, post and patch */ request(verb, requestUrl, data, headers) { return __awaiter(this, void 0, void 0, function* () { if (this._disposed) { throw new Error("Client has already been disposed."); } let parsedUrl = url.parse(requestUrl); let info = this._prepareRequest(verb, parsedUrl, headers); // Only perform retries on reads since writes may not be idempotent. let maxTries = (this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1) ? this._maxRetries + 1 : 1; let numTries = 0; let response; while (numTries < maxTries) { response = yield this.requestRaw(info, data); // Check if it's an authentication challenge if (response && response.message && response.message.statusCode === HttpCodes.Unauthorized) { let authenticationHandler; for (let i = 0; i < this.handlers.length; i++) { if (this.handlers[i].canHandleAuthentication(response)) { authenticationHandler = this.handlers[i]; break; } } if (authenticationHandler) { return authenticationHandler.handleAuthentication(this, info, data); } else { // We have received an unauthorized response but have no handlers to handle it. // Let the response return to the caller. return response; } } let redirectsRemaining = this._maxRedirects; while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1 && this._allowRedirects && redirectsRemaining > 0) { const redirectUrl = response.message.headers["location"]; if (!redirectUrl) { // if there's no location to redirect to, we won't break; } let parsedRedirectUrl = url.parse(redirectUrl); if (parsedUrl.protocol == 'https:' && parsedUrl.protocol != parsedRedirectUrl.protocol && !this._allowRedirectDowngrade) { throw new Error("Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true."); } // we need to finish reading the response before reassigning response // which will leak the open socket. yield response.readBody(); // let's make the request with the new redirectUrl info = this._prepareRequest(verb, parsedRedirectUrl, headers); response = yield this.requestRaw(info, data); redirectsRemaining--; } if (HttpResponseRetryCodes.indexOf(response.message.statusCode) == -1) { // If not a retry code, return immediately instead of retrying return response; } numTries += 1; if (numTries < maxTries) { yield response.readBody(); yield this._performExponentialBackoff(numTries); } } return response; }); } /** * Needs to be called if keepAlive is set to true in request options. */ dispose() { if (this._agent) { this._agent.destroy(); } this._disposed = true; } /** * Raw request. * @param info * @param data */ requestRaw(info, data) { return new Promise((resolve, reject) => { let callbackForResult = function (err, res) { if (err) { reject(err); } resolve(res); }; this.requestRawWithCallback(info, data, callbackForResult); }); } /** * Raw request with callback. * @param info * @param data * @param onResult */ requestRawWithCallback(info, data, onResult) { let socket; let isDataString = typeof (data) === 'string'; if (typeof (data) === 'string') { info.options.headers["Content-Length"] = Buffer.byteLength(data, 'utf8'); } let callbackCalled = false; let handleResult = (err, res) => { if (!callbackCalled) { callbackCalled = true; onResult(err, res); } }; let req = info.httpModule.request(info.options, (msg) => { let res = new HttpClientResponse(msg); handleResult(null, res); }); req.on('socket', (sock) => { socket = sock; }); // If we ever get disconnected, we want the socket to timeout eventually req.setTimeout(this._socketTimeout || 3 * 60000, () => { if (socket) { socket.end(); } handleResult(new Error('Request timeout: ' + info.options.path), null); }); req.on('error', function (err) { // err has statusCode property // res should have headers handleResult(err, null); }); if (data && typeof (data) === 'string') { req.write(data, 'utf8'); } if (data && typeof (data) !== 'string') { data.on('close', function () { req.end(); }); data.pipe(req); } else { req.end(); } } _prepareRequest(method, requestUrl, headers) { const info = {}; info.parsedUrl = requestUrl; const usingSsl = info.parsedUrl.protocol === 'https:'; info.httpModule = usingSsl ? https : http; const defaultPort = usingSsl ? 443 : 80; info.options = {}; info.options.host = info.parsedUrl.hostname; info.options.port = info.parsedUrl.port ? parseInt(info.parsedUrl.port) : defaultPort; info.options.path = (info.parsedUrl.pathname || '') + (info.parsedUrl.search || ''); info.options.method = method; info.options.headers = this._mergeHeaders(headers); if (this.userAgent != null) { info.options.headers["user-agent"] = this.userAgent; } info.options.agent = this._getAgent(info.parsedUrl); // gives handlers an opportunity to participate if (this.handlers && !this._isPresigned(url.format(requestUrl))) { this.handlers.forEach((handler) => { handler.prepareRequest(info.options); }); } return info; } _isPresigned(requestUrl) { if (this.requestOptions && this.requestOptions.presignedUrlPatterns) { const patterns = this.requestOptions.presignedUrlPatterns; for (let i = 0; i < patterns.length; i++) { if (requestUrl.match(patterns[i])) { return true; } } } return false; } _mergeHeaders(headers) { const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => (c[k.toLowerCase()] = obj[k], c), {}); if (this.requestOptions && this.requestOptions.headers) { return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers)); } return lowercaseKeys(headers || {}); } _getAgent(parsedUrl) { let agent; let proxy = this._getProxy(parsedUrl); let useProxy = proxy.proxyUrl && proxy.proxyUrl.hostname && !this._isMatchInBypassProxyList(parsedUrl); if (this._keepAlive && useProxy) { agent = this._proxyAgent; } if (this._keepAlive && !useProxy) { agent = this._agent; } // if agent is already assigned use that agent. if (!!agent) { return agent; } const usingSsl = parsedUrl.protocol === 'https:'; let maxSockets = 100; if (!!this.requestOptions) { maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets; } if (useProxy) { // If using proxy, need tunnel if (!tunnel) { tunnel = __webpack_require__(/*! tunnel */ "./node_modules/tunnel/index.js"); } const agentOptions = { maxSockets: maxSockets, keepAlive: this._keepAlive, proxy: { proxyAuth: proxy.proxyAuth, host: proxy.proxyUrl.hostname, port: proxy.proxyUrl.port }, }; let tunnelAgent; const overHttps = proxy.proxyUrl.protocol === 'https:'; if (usingSsl) { tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp; } else { tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp; } agent = tunnelAgent(agentOptions); this._proxyAgent = agent; } // if reusing agent across request and tunneling agent isn't assigned create a new agent if (this._keepAlive && !agent) { const options = { keepAlive: this._keepAlive, maxSockets: maxSockets }; agent = usingSsl ? new https.Agent(options) : new http.Agent(options); this._agent = agent; } // if not using private agent and tunnel agent isn't setup then use global agent if (!agent) { agent = usingSsl ? https.globalAgent : http.globalAgent; } if (usingSsl && this._ignoreSslError) { // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options // we have to cast it to any and change it directly agent.options = Object.assign(agent.options || {}, { rejectUnauthorized: false }); } if (usingSsl && this._certConfig) { agent.options = Object.assign(agent.options || {}, { ca: this._ca, cert: this._cert, key: this._key, passphrase: this._certConfig.passphrase }); } return agent; } _getProxy(parsedUrl) { let usingSsl = parsedUrl.protocol === 'https:'; let proxyConfig = this._httpProxy; // fallback to http_proxy and https_proxy env let https_proxy = process.env[EnvironmentVariables.HTTPS_PROXY]; let http_proxy = process.env[EnvironmentVariables.HTTP_PROXY]; if (!proxyConfig) { if (https_proxy && usingSsl) { proxyConfig = { proxyUrl: https_proxy }; } else if (http_proxy) { proxyConfig = { proxyUrl: http_proxy }; } } let proxyUrl; let proxyAuth; if (proxyConfig) { if (proxyConfig.proxyUrl.length > 0) { proxyUrl = url.parse(proxyConfig.proxyUrl); } if (proxyConfig.proxyUsername || proxyConfig.proxyPassword) { proxyAuth = proxyConfig.proxyUsername + ":" + proxyConfig.proxyPassword; } } return { proxyUrl: proxyUrl, proxyAuth: proxyAuth }; } _isMatchInBypassProxyList(parsedUrl) { if (!this._httpProxyBypassHosts) { return false; } let bypass = false; this._httpProxyBypassHosts.forEach(bypassHost => { if (bypassHost.test(parsedUrl.href)) { bypass = true; } }); return bypass; } _performExponentialBackoff(retryNumber) { retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); return new Promise(resolve => setTimeout(() => resolve(), ms)); } } exports.HttpClient = HttpClient; /***/ }), /***/ "./node_modules/typed-rest-client/Util.js": /*!************************************************!*\ !*** ./node_modules/typed-rest-client/Util.js ***! \************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const qs = __webpack_require__(/*! qs */ "./node_modules/qs/lib/index.js"); const url = __webpack_require__(/*! url */ "url"); const path = __webpack_require__(/*! path */ "path"); const zlib = __webpack_require__(/*! zlib */ "zlib"); /** * creates an url from a request url and optional base url (http://server:8080) * @param {string} resource - a fully qualified url or relative path * @param {string} baseUrl - an optional baseUrl (http://server:8080) * @param {IRequestOptions} options - an optional options object, could include QueryParameters e.g. * @return {string} - resultant url */ function getUrl(resource, baseUrl, queryParams) { const pathApi = path.posix || path; let requestUrl = ''; if (!baseUrl) { requestUrl = resource; } else if (!resource) { requestUrl = baseUrl; } else { const base = url.parse(baseUrl); const resultantUrl = url.parse(resource); // resource (specific per request) elements take priority resultantUrl.protocol = resultantUrl.protocol || base.protocol; resultantUrl.auth = resultantUrl.auth || base.auth; resultantUrl.host = resultantUrl.host || base.host; resultantUrl.pathname = pathApi.resolve(base.pathname, resultantUrl.pathname); if (!resultantUrl.pathname.endsWith('/') && resource.endsWith('/')) { resultantUrl.pathname += '/'; } requestUrl = url.format(resultantUrl); } return queryParams ? getUrlWithParsedQueryParams(requestUrl, queryParams) : requestUrl; } exports.getUrl = getUrl; /** * * @param {string} requestUrl * @param {IRequestQueryParams} queryParams * @return {string} - Request's URL with Query Parameters appended/parsed. */ function getUrlWithParsedQueryParams(requestUrl, queryParams) { const url = requestUrl.replace(/\?$/g, ''); // Clean any extra end-of-string "?" character const parsedQueryParams = qs.stringify(queryParams.params, buildParamsStringifyOptions(queryParams)); return `${url}${parsedQueryParams}`; } /** * Build options for QueryParams Stringifying. * * @param {IRequestQueryParams} queryParams * @return {object} */ function buildParamsStringifyOptions(queryParams) { let options = { addQueryPrefix: true, delimiter: (queryParams.options || {}).separator || '&', allowDots: (queryParams.options || {}).shouldAllowDots || false, arrayFormat: (queryParams.options || {}).arrayFormat || 'repeat', encodeValuesOnly: (queryParams.options || {}).shouldOnlyEncodeValues || true }; return options; } /** * Decompress/Decode gzip encoded JSON * Using Node.js built-in zlib module * * @param {Buffer} buffer * @param {string} charset? - optional; defaults to 'utf-8' * @return {Promise} */ function decompressGzippedContent(buffer, charset) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { zlib.gunzip(buffer, function (error, buffer) { if (error) { reject(error); } resolve(buffer.toString(charset || 'utf-8')); }); })); }); } exports.decompressGzippedContent = decompressGzippedContent; /** * Obtain Response's Content Charset. * Through inspecting `content-type` response header. * It Returns 'utf-8' if NO charset specified/matched. * * @param {IHttpClientResponse} response * @return {string} - Content Encoding Charset; Default=utf-8 */ function obtainContentCharset(response) { // Find the charset, if specified. // Search for the `charset=CHARSET` string, not including `;,\r\n` // Example: content-type: 'application/json;charset=utf-8' // |__ matches would be ['charset=utf-8', 'utf-8', index: 18, input: 'application/json; charset=utf-8'] // |_____ matches[1] would have the charset :tada: , in our example it's utf-8 // However, if the matches Array was empty or no charset found, 'utf-8' would be returned by default. const contentType = response.message.headers['content-type'] || ''; const matches = contentType.match(/charset=([^;,\r\n]+)/i); return (matches && matches[1]) ? matches[1] : 'utf-8'; } exports.obtainContentCharset = obtainContentCharset; /***/ }), /***/ "./node_modules/uuid/index.js": /*!************************************!*\ !*** ./node_modules/uuid/index.js ***! \************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { var v1 = __webpack_require__(/*! ./v1 */ "./node_modules/uuid/v1.js"); var v4 = __webpack_require__(/*! ./v4 */ "./node_modules/uuid/v4.js"); var uuid = v4; uuid.v1 = v1; uuid.v4 = v4; module.exports = uuid; /***/ }), /***/ "./node_modules/uuid/lib/bytesToUuid.js": /*!**********************************************!*\ !*** ./node_modules/uuid/lib/bytesToUuid.js ***! \**********************************************/ /*! no static exports found */ /***/ (function(module, exports) { /** * Convert array of 16 byte values to UUID string format of the form: * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX */ var byteToHex = []; for (var i = 0; i < 256; ++i) { byteToHex[i] = (i + 0x100).toString(16).substr(1); } function bytesToUuid(buf, offset) { var i = offset || 0; var bth = byteToHex; // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 return ([ bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]] ]).join(''); } module.exports = bytesToUuid; /***/ }), /***/ "./node_modules/uuid/lib/rng.js": /*!**************************************!*\ !*** ./node_modules/uuid/lib/rng.js ***! \**************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { // Unique ID creation requires a high quality random # generator. In node.js // this is pretty straight-forward - we use the crypto API. var crypto = __webpack_require__(/*! crypto */ "crypto"); module.exports = function nodeRNG() { return crypto.randomBytes(16); }; /***/ }), /***/ "./node_modules/uuid/v1.js": /*!*********************************!*\ !*** ./node_modules/uuid/v1.js ***! \*********************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { var rng = __webpack_require__(/*! ./lib/rng */ "./node_modules/uuid/lib/rng.js"); var bytesToUuid = __webpack_require__(/*! ./lib/bytesToUuid */ "./node_modules/uuid/lib/bytesToUuid.js"); // **`v1()` - Generate time-based UUID** // // Inspired by https://github.com/LiosK/UUID.js // and http://docs.python.org/library/uuid.html var _nodeId; var _clockseq; // Previous uuid creation time var _lastMSecs = 0; var _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details function v1(options, buf, offset) { var i = buf && offset || 0; var b = buf || []; options = options || {}; var node = options.node || _nodeId; var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not // specified. We do this lazily to minimize issues related to insufficient // system entropy. See #189 if (node == null || clockseq == null) { var seedBytes = rng(); if (node == null) { // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) node = _nodeId = [ seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] ]; } if (clockseq == null) { // Per 4.2.2, randomize (14 bit) clockseq clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; } } // UUID timestamps are 100 nano-second units since the Gregorian epoch, // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); // Per 4.2.1.2, use count of uuid's generated during the current clock // cycle to simulate higher resolution clock var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; // Per 4.2.1.2, Bump clockseq on clock regression if (dt < 0 && options.clockseq === undefined) { clockseq = clockseq + 1 & 0x3fff; } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new // time interval if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { nsecs = 0; } // Per 4.2.1.2 Throw error if too many uuids are requested if (nsecs >= 10000) { throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); } _lastMSecs = msecs; _lastNSecs = nsecs; _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch msecs += 12219292800000; // `time_low` var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; b[i++] = tl >>> 24 & 0xff; b[i++] = tl >>> 16 & 0xff; b[i++] = tl >>> 8 & 0xff; b[i++] = tl & 0xff; // `time_mid` var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; b[i++] = tmh >>> 8 & 0xff; b[i++] = tmh & 0xff; // `time_high_and_version` b[i++] = tmh >>> 24 & 0xf | 0x10; // include version b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` b[i++] = clockseq & 0xff; // `node` for (var n = 0; n < 6; ++n) { b[i + n] = node[n]; } return buf ? buf : bytesToUuid(b); } module.exports = v1; /***/ }), /***/ "./node_modules/uuid/v4.js": /*!*********************************!*\ !*** ./node_modules/uuid/v4.js ***! \*********************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { var rng = __webpack_require__(/*! ./lib/rng */ "./node_modules/uuid/lib/rng.js"); var bytesToUuid = __webpack_require__(/*! ./lib/bytesToUuid */ "./node_modules/uuid/lib/bytesToUuid.js"); function v4(options, buf, offset) { var i = buf && offset || 0; if (typeof(options) == 'string') { buf = options === 'binary' ? new Array(16) : null; options = null; } options = options || {}; var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` rnds[6] = (rnds[6] & 0x0f) | 0x40; rnds[8] = (rnds[8] & 0x3f) | 0x80; // Copy bytes to buffer, if provided if (buf) { for (var ii = 0; ii < 16; ++ii) { buf[i + ii] = rnds[ii]; } } return buf || bytesToUuid(rnds); } module.exports = v4; /***/ }), /***/ "./src/agent/github/build-agent.ts": /*!*****************************************!*\ !*** ./src/agent/github/build-agent.ts ***! \*****************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs = __importStar(__webpack_require__(/*! fs */ "fs")); const path = __importStar(__webpack_require__(/*! path */ "path")); const uuid_1 = __importDefault(__webpack_require__(/*! uuid */ "./node_modules/uuid/index.js")); const core = __importStar(__webpack_require__(/*! @actions/core */ "./node_modules/@actions/core/lib/core.js")); const exe = __importStar(__webpack_require__(/*! @actions/exec */ "./node_modules/@actions/exec/lib/exec.js")); const io = __importStar(__webpack_require__(/*! @actions/io */ "./node_modules/@actions/io/lib/io.js")); const toolCache = __importStar(__webpack_require__(/*! @actions/tool-cache */ "./node_modules/@actions/tool-cache/lib/tool-cache.js")); const inversify_1 = __webpack_require__(/*! inversify */ "./node_modules/inversify/lib/inversify.js"); let BuildAgent = class BuildAgent { get agentName() { return "GitHub Actions"; } find(toolName, versionSpec, arch) { return toolCache.find(toolName, versionSpec, arch); } cacheDir(sourceDir, tool, version, arch) { return toolCache.cacheDir(sourceDir, tool, version, arch); } createTempDir() { return __awaiter(this, void 0, void 0, function* () { const IS_WINDOWS = process.platform === "win32"; let tempDirectory = process.env.RUNNER_TEMP || ""; if (!tempDirectory) { let baseLocation; if (IS_WINDOWS) { // On Windows use the USERPROFILE env variable baseLocation = process.env.USERPROFILE || "C:\\"; } else { if (process.platform === "darwin") { baseLocation = "/Users"; } else { baseLocation = "/home"; } } tempDirectory = path.join(baseLocation, "actions", "temp"); } const dest = path.join(tempDirectory, uuid_1.default()); yield io.mkdirP(dest); return dest; }); } debug(message) { core.debug(message); } setFailed(message, done) { core.setFailed(message); } setSucceeded(message, done) { // } exportVariable(name, val) { core.exportVariable(name, val); } getVariable(name) { return process.env[name]; } addPath(inputPath) { core.addPath(inputPath); } which(tool, check) { return io.which(tool, check); } exec(exec, args) { return __awaiter(this, void 0, void 0, function* () { const dotnetPath = yield io.which(exec, true); let resultCode = 0; let stdout = ""; let stderr = ""; resultCode = yield exe.exec(`"${dotnetPath}"`, args, { listeners: { stderr: (data) => { stderr += data.toString(); }, stdout: (data) => { stdout += data.toString(); }, }, }); return { code: resultCode, error: null, stderr, stdout, }; }); } getSourceDir() { return this.getVariable("GITHUB_WORKSPACE"); } setOutput(name, value) { core.setOutput(name, value); } getInput(input, required) { return core.getInput(input, { required }); } getBooleanInput(input, required) { const inputValue = this.getInput(input, required); return (inputValue || "false").toLowerCase() === "true"; } isValidInputFile(input, file) { return this.filePathSupplied(input) && this.fileExists(file); } filePathSupplied(file) { const pathValue = path.resolve(this.getInput(file) || ""); const repoRoot = this.getSourceDir(); return pathValue !== repoRoot; } fileExists(file) { return this._exist(file) && this._stats(file).isFile(); } directoryExists(file) { return this._exist(file) && this._stats(file).isDirectory(); } _exist(file) { let exist = false; try { exist = !!(file && fs.statSync(file) != null); } catch (err) { if (err && err.code === "ENOENT") { exist = false; } else { throw err; } } return exist; } _stats(file) { return fs.statSync(file); } }; BuildAgent = __decorate([ inversify_1.injectable() ], BuildAgent); exports.BuildAgent = BuildAgent; /***/ }), /***/ "./src/core/common.ts": /*!****************************!*\ !*** ./src/core/common.ts ***! \****************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TYPES = { IBuildAgent: Symbol.for("BuildAgent"), IDotnetTool: Symbol.for("DotnetTool"), IGitVersionTool: Symbol.for("GitVersionTool"), IGitReleaseManagerTool: Symbol.for("GitReleaseManagerTool"), IVersionManager: Symbol.for("VersionManager"), }; exports.SetupOptions = { includePrerelease: "includePrerelease", versionSpec: "versionSpec", }; /***/ }), /***/ "./src/core/dotnet-tool.ts": /*!*********************************!*\ !*** ./src/core/dotnet-tool.ts ***! \*********************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs = __importStar(__webpack_require__(/*! fs */ "fs")); const os = __importStar(__webpack_require__(/*! os */ "os")); const path = __importStar(__webpack_require__(/*! path */ "path")); const http = __importStar(__webpack_require__(/*! typed-rest-client/HttpClient */ "./node_modules/typed-rest-client/HttpClient.js")); const inversify_1 = __webpack_require__(/*! inversify */ "./node_modules/inversify/lib/inversify.js"); const common_1 = __webpack_require__(/*! ./common */ "./src/core/common.ts"); let DotnetTool = class DotnetTool { constructor(buildAgent, versionManager) { this.buildAgent = buildAgent; this.versionManager = versionManager; this.httpClient = new http.HttpClient("dotnet"); } run(args) { return this.buildAgent.exec("dotnet", args); } toolInstall(toolName, versionSpec, checkLatest, includePre) { return __awaiter(this, void 0, void 0, function* () { console.log(""); console.log("--------------------------"); console.log(`Installing ${toolName} version ` + versionSpec); console.log("--------------------------"); if (this.versionManager.isExplicitVersion(versionSpec)) { checkLatest = false; // check latest doesn't make sense when explicit version } let toolPath; if (!checkLatest) { // // Let's try and resolve the version spec locally first // toolPath = this.buildAgent.find(toolName, versionSpec); } if (!toolPath) { let version; if (this.versionManager.isExplicitVersion(versionSpec)) { // // Explicit version was specified. No need to query for list of versions. // version = versionSpec; } else { // // Let's query and resolve the latest version for the versionSpec. // If the version is an explicit version (1.1.1 or v1.1.1) then no need to query. // If your tool doesn't offer a mechanism to query, // then it can only support exact version inputs. // version = yield this.queryLatestMatch(toolName, versionSpec, includePre); if (!version) { throw new Error(`Unable to find ${toolName} version '${versionSpec}'.`); } // // Check the cache for the resolved version. // toolPath = this.buildAgent.find(toolName, version); } if (!toolPath) { // // Download, extract, cache // toolPath = yield this.acquireTool(toolName, version); } } // // Prepend the tools path. This prepends the PATH for the current process and // instructs the agent to prepend for each task that follows. // this.buildAgent.debug(`toolPath: ${toolPath}`); if (os.platform() !== "win32") { const dotnetRoot = path.dirname(fs.readlinkSync(yield this.buildAgent.which("dotnet"))); this.buildAgent.exportVariable("DOTNET_ROOT", dotnetRoot); } this.buildAgent.addPath(toolPath); return toolPath; }); } queryLatestMatch(toolName, versionSpec, includePrerelease) { return __awaiter(this, void 0, void 0, function* () { this.buildAgent.debug(`querying tool versions for ${toolName}${versionSpec ? `@${versionSpec}` : ""} ${includePrerelease ? "including pre-releases" : ""}`); const downloadPath = `https://api-v2v3search-0.nuget.org/query?q=${encodeURIComponent(toolName.toLowerCase())}&prerelease=${includePrerelease ? "true" : "false"}&semVerLevel=2.0.0`; const res = yield this.httpClient.get(downloadPath); if (!res || res.message.statusCode !== 200) { return null; } const body = yield res.readBody(); const data = JSON.parse(body).data; const versions = data[0].versions.map((x) => x.version); if (!versions || !versions.length) { return null; } this.buildAgent.debug(`got versions: ${versions.join(", ")}`); return this.versionManager.evaluateVersions(versions, versionSpec); }); } acquireTool(toolName, version) { return __awaiter(this, void 0, void 0, function* () { const tempDirectory = yield this.buildAgent.createTempDir(); let args = ["tool", "install", toolName, "--tool-path", tempDirectory]; if (version) { version = this.versionManager.cleanVersion(version); args = args.concat(["--version", version]); } const result = yield this.run(args); const status = result.code === 0 ? "success" : "failure"; const message = result.code === 0 ? result.stdout : result.stderr; this.buildAgent.debug(`tool install result: ${status} ${message}`); if (result.code) { throw new Error("Error installing tool"); } return yield this.buildAgent.cacheDir(tempDirectory, toolName, version); }); } }; DotnetTool = __decorate([ inversify_1.injectable(), __param(0, inversify_1.inject(common_1.TYPES.IBuildAgent)), __param(1, inversify_1.inject(common_1.TYPES.IVersionManager)), __metadata("design:paramtypes", [Object, Object]) ], DotnetTool); exports.DotnetTool = DotnetTool; /***/ }), /***/ "./src/core/ioc.ts": /*!*************************!*\ !*** ./src/core/ioc.ts ***! \*************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const inversify_1 = __webpack_require__(/*! inversify */ "./node_modules/inversify/lib/inversify.js"); const versionManager_1 = __webpack_require__(/*! ./versionManager */ "./src/core/versionManager.ts"); const common_1 = __webpack_require__(/*! ./common */ "./src/core/common.ts"); const build_agent_1 = __webpack_require__(/*! ../agent/mock/build-agent */ "./src/agent/github/build-agent.ts"); const dotnet_tool_1 = __webpack_require__(/*! ./dotnet-tool */ "./src/core/dotnet-tool.ts"); const container = new inversify_1.Container(); container.bind(common_1.TYPES.IVersionManager).to(versionManager_1.VersionManager); container.bind(common_1.TYPES.IBuildAgent).to(build_agent_1.BuildAgent); container.bind(common_1.TYPES.IDotnetTool).to(dotnet_tool_1.DotnetTool); exports.default = container; /***/ }), /***/ "./src/core/versionManager.ts": /*!************************************!*\ !*** ./src/core/versionManager.ts ***! \************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const semver_compare_1 = __importDefault(__webpack_require__(/*! semver-compare */ "./node_modules/semver-compare/index.js")); const semver = __importStar(__webpack_require__(/*! semver */ "./node_modules/semver/semver.js")); const inversify_1 = __webpack_require__(/*! inversify */ "./node_modules/inversify/lib/inversify.js"); const common_1 = __webpack_require__(/*! ./common */ "./src/core/common.ts"); let VersionManager = class VersionManager { constructor(buildAgent) { this.buildAgent = buildAgent; } isExplicitVersion(versionSpec) { const c = semver.clean(versionSpec); this.buildAgent.debug("isExplicit: " + c); const valid = semver.valid(c) != null; this.buildAgent.debug("explicit? " + valid); return valid; } evaluateVersions(versions, versionSpec) { let version; this.buildAgent.debug("evaluating " + versions.length + " versions"); versions = versions.sort(semver_compare_1.default); for (let i = versions.length - 1; i >= 0; i--) { const potential = versions[i]; const satisfied = semver.satisfies(potential, versionSpec); if (satisfied) { version = potential; break; } } if (version) { this.buildAgent.debug("matched: " + version); } else { this.buildAgent.debug("match not found"); } return version; } cleanVersion(version) { this.buildAgent.debug("cleaning: " + version); return semver.clean(version); } }; VersionManager = __decorate([ inversify_1.injectable(), __param(0, inversify_1.inject(common_1.TYPES.IBuildAgent)), __metadata("design:paramtypes", [Object]) ], VersionManager); exports.VersionManager = VersionManager; /***/ }), /***/ "./src/tasks/gitreleasemanager/create.ts": /*!***********************************************!*\ !*** ./src/tasks/gitreleasemanager/create.ts ***! \***********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); __webpack_require__(/*! reflect-metadata */ "./node_modules/reflect-metadata/Reflect.js"); const main_1 = __webpack_require__(/*! ./main */ "./src/tasks/gitreleasemanager/main.ts"); main_1.create(); /***/ }), /***/ "./src/tasks/gitreleasemanager/main.ts": /*!*********************************************!*\ !*** ./src/tasks/gitreleasemanager/main.ts ***! \*********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const common_1 = __webpack_require__(/*! ../../core/common */ "./src/core/common.ts"); const gitreleasemanager_tool_1 = __webpack_require__(/*! ../../tools/gitreleasemanager/gitreleasemanager-tool */ "./src/tools/gitreleasemanager/gitreleasemanager-tool.ts"); const ioc_1 = __importDefault(__webpack_require__(/*! ../../core/ioc */ "./src/core/ioc.ts")); const settings_1 = __webpack_require__(/*! ../../tools/gitreleasemanager/settings */ "./src/tools/gitreleasemanager/settings.ts"); ioc_1.default.bind(common_1.TYPES.IGitReleaseManagerTool).to(gitreleasemanager_tool_1.GitReleaseManagerTool); const gitReleaseManagerTool = ioc_1.default.get(common_1.TYPES.IGitReleaseManagerTool); const buildAgent = ioc_1.default.get(common_1.TYPES.IBuildAgent); function setup() { return __awaiter(this, void 0, void 0, function* () { try { buildAgent.exportVariable("DOTNET_CLI_TELEMETRY_OPTOUT", "1"); const versionSpec = buildAgent.getInput(common_1.SetupOptions.versionSpec); const includePrerelease = buildAgent.getBooleanInput(common_1.SetupOptions.includePrerelease); yield gitReleaseManagerTool.install(versionSpec, includePrerelease); buildAgent.setSucceeded("GitVersionManager installed successfully", true); } catch (error) { buildAgent.setFailed(error.message, true); } }); } exports.setup = setup; function create() { return __awaiter(this, void 0, void 0, function* () { try { buildAgent.exportVariable("DOTNET_CLI_TELEMETRY_OPTOUT", "1"); const settings = settings_1.Settings.getCreateSettings(buildAgent); yield gitReleaseManagerTool.create(settings); buildAgent.setSucceeded("GitVersionManager created release successfully", true); } catch (error) { buildAgent.setFailed(error.message, true); } }); } exports.create = create; /***/ }), /***/ "./src/tools/gitreleasemanager/gitreleasemanager-tool.ts": /*!***************************************************************!*\ !*** ./src/tools/gitreleasemanager/gitreleasemanager-tool.ts ***! \***************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const common_1 = __webpack_require__(/*! ../../core/common */ "./src/core/common.ts"); const inversify_1 = __webpack_require__(/*! inversify */ "./node_modules/inversify/lib/inversify.js"); let GitReleaseManagerTool = class GitReleaseManagerTool { constructor(buildAgent, dotnetTool) { this.dotnetTool = dotnetTool; } install(versionSpec, includePrerelease) { return __awaiter(this, void 0, void 0, function* () { yield this.dotnetTool.toolInstall("GitReleaseManager.Tool", versionSpec, false, includePrerelease); }); } create(settings) { const args = this.getCreateArguments(settings); console.log(args); return Promise.resolve(null); // return this.buildAgent.exec("dotnet-gitreleasemanager", args); } getCommonArguments(settings) { const args = []; args.push("--owner", settings.owner); args.push("--repository", settings.repository); args.push("--token", settings.token); return args; } getCreateArguments(settings) { const args = [...this.getCommonArguments(settings)]; args.push("--milestone", settings.milestone); args.push("--name", settings.releaseName); args.push("--targetcommitish", settings.commit); args.push("--targetDirectory", settings.targetDirectory); if (this.buildAgent.fileExists(settings.inputFileName)) { args.push("--inputFilePath", settings.inputFileName); } else { throw new Error("GitReleaseManager inputFilePath not found at " + settings.inputFileName); } if (settings.isPreRelease) { args.push("--pre"); } return args; } }; GitReleaseManagerTool = __decorate([ inversify_1.injectable(), __param(0, inversify_1.inject(common_1.TYPES.IBuildAgent)), __param(1, inversify_1.inject(common_1.TYPES.IDotnetTool)), __metadata("design:paramtypes", [Object, Object]) ], GitReleaseManagerTool); exports.GitReleaseManagerTool = GitReleaseManagerTool; /***/ }), /***/ "./src/tools/gitreleasemanager/models.ts": /*!***********************************************!*\ !*** ./src/tools/gitreleasemanager/models.ts ***! \***********************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var CommonFields; (function (CommonFields) { CommonFields["repository"] = "repository"; CommonFields["owner"] = "owner"; CommonFields["token"] = "token"; })(CommonFields = exports.CommonFields || (exports.CommonFields = {})); var CreateFields; (function (CreateFields) { CreateFields["milestone"] = "milestone"; CreateFields["releaseName"] = "releaseName"; CreateFields["inputFileName"] = "inputFileName"; CreateFields["isPreRelease"] = "isPreRelease"; CreateFields["commit"] = "commit"; CreateFields["targetDirectory"] = "targetDirectory"; CreateFields["assets"] = "assets"; })(CreateFields = exports.CreateFields || (exports.CreateFields = {})); /***/ }), /***/ "./src/tools/gitreleasemanager/settings.ts": /*!*************************************************!*\ !*** ./src/tools/gitreleasemanager/settings.ts ***! \*************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const models_1 = __webpack_require__(/*! ./models */ "./src/tools/gitreleasemanager/models.ts"); class Settings { static getCreateSettings(buildAgent) { const milestone = buildAgent.getInput(models_1.CreateFields.milestone); const releaseName = buildAgent.getInput(models_1.CreateFields.releaseName); const inputFileName = buildAgent.getInput(models_1.CreateFields.inputFileName); const isPreRelease = buildAgent.getBooleanInput(models_1.CreateFields.isPreRelease); const commit = buildAgent.getInput(models_1.CreateFields.commit); const targetDirectory = buildAgent.getInput(models_1.CreateFields.targetDirectory); const commonSettings = Settings.getCommonSettings(buildAgent); return Object.assign(Object.assign({}, commonSettings), { milestone, releaseName, inputFileName, isPreRelease, commit, targetDirectory }); } static getCommonSettings(buildAgent) { const owner = buildAgent.getInput(models_1.CommonFields.owner, true); const repository = buildAgent.getInput(models_1.CommonFields.repository, true); const token = buildAgent.getInput(models_1.CommonFields.token, true); return { owner, repository, token }; } } exports.Settings = Settings; /***/ }), /***/ "assert": /*!*************************!*\ !*** external "assert" ***! \*************************/ /*! no static exports found */ /***/ (function(module, exports) { module.exports = require("assert"); /***/ }), /***/ "child_process": /*!********************************!*\ !*** external "child_process" ***! \********************************/ /*! no static exports found */ /***/ (function(module, exports) { module.exports = require("child_process"); /***/ }), /***/ "crypto": /*!*************************!*\ !*** external "crypto" ***! \*************************/ /*! no static exports found */ /***/ (function(module, exports) { module.exports = require("crypto"); /***/ }), /***/ "events": /*!*************************!*\ !*** external "events" ***! \*************************/ /*! no static exports found */ /***/ (function(module, exports) { module.exports = require("events"); /***/ }), /***/ "fs": /*!*********************!*\ !*** external "fs" ***! \*********************/ /*! no static exports found */ /***/ (function(module, exports) { module.exports = require("fs"); /***/ }), /***/ "http": /*!***********************!*\ !*** external "http" ***! \***********************/ /*! no static exports found */ /***/ (function(module, exports) { module.exports = require("http"); /***/ }), /***/ "https": /*!************************!*\ !*** external "https" ***! \************************/ /*! no static exports found */ /***/ (function(module, exports) { module.exports = require("https"); /***/ }), /***/ "net": /*!**********************!*\ !*** external "net" ***! \**********************/ /*! no static exports found */ /***/ (function(module, exports) { module.exports = require("net"); /***/ }), /***/ "os": /*!*********************!*\ !*** external "os" ***! \*********************/ /*! no static exports found */ /***/ (function(module, exports) { module.exports = require("os"); /***/ }), /***/ "path": /*!***********************!*\ !*** external "path" ***! \***********************/ /*! no static exports found */ /***/ (function(module, exports) { module.exports = require("path"); /***/ }), /***/ "tls": /*!**********************!*\ !*** external "tls" ***! \**********************/ /*! no static exports found */ /***/ (function(module, exports) { module.exports = require("tls"); /***/ }), /***/ "url": /*!**********************!*\ !*** external "url" ***! \**********************/ /*! no static exports found */ /***/ (function(module, exports) { module.exports = require("url"); /***/ }), /***/ "util": /*!***********************!*\ !*** external "util" ***! \***********************/ /*! no static exports found */ /***/ (function(module, exports) { module.exports = require("util"); /***/ }), /***/ "zlib": /*!***********************!*\ !*** external "zlib" ***! \***********************/ /*! no static exports found */ /***/ (function(module, exports) { module.exports = require("zlib"); /***/ }) /******/ }); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhY3Rpb25zL2NvcmUvbGliL2NvbW1hbmQuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhY3Rpb25zL2NvcmUvbGliL2NvcmUuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhY3Rpb25zL2V4ZWMvbGliL2V4ZWMuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhY3Rpb25zL2V4ZWMvbGliL3Rvb2xydW5uZXIuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhY3Rpb25zL2h0dHAtY2xpZW50L2luZGV4LmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYWN0aW9ucy9odHRwLWNsaWVudC9ub2RlX21vZHVsZXMvdHVubmVsL2luZGV4LmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYWN0aW9ucy9odHRwLWNsaWVudC9ub2RlX21vZHVsZXMvdHVubmVsL2xpYi90dW5uZWwuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhY3Rpb25zL2h0dHAtY2xpZW50L3Byb3h5LmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYWN0aW9ucy9pby9saWIvaW8tdXRpbC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFjdGlvbnMvaW8vbGliL2lvLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYWN0aW9ucy90b29sLWNhY2hlL2xpYi90b29sLWNhY2hlLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYWN0aW9ucy90b29sLWNhY2hlL25vZGVfbW9kdWxlcy9zZW12ZXIvc2VtdmVyLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2Fubm90YXRpb24vZGVjb3JhdG9yX3V0aWxzLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2Fubm90YXRpb24vaW5qZWN0LmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2Fubm90YXRpb24vaW5qZWN0YWJsZS5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9hbm5vdGF0aW9uL211bHRpX2luamVjdC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9hbm5vdGF0aW9uL25hbWVkLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2Fubm90YXRpb24vb3B0aW9uYWwuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvYW5ub3RhdGlvbi9wb3N0X2NvbnN0cnVjdC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9hbm5vdGF0aW9uL3RhZ2dlZC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9hbm5vdGF0aW9uL3RhcmdldF9uYW1lLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2Fubm90YXRpb24vdW5tYW5hZ2VkLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2JpbmRpbmdzL2JpbmRpbmcuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvYmluZGluZ3MvYmluZGluZ19jb3VudC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9jb25zdGFudHMvZXJyb3JfbXNncy5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9jb25zdGFudHMvbGl0ZXJhbF90eXBlcy5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9jb25zdGFudHMvbWV0YWRhdGFfa2V5cy5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9jb250YWluZXIvY29udGFpbmVyLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2NvbnRhaW5lci9jb250YWluZXJfbW9kdWxlLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2NvbnRhaW5lci9jb250YWluZXJfc25hcHNob3QuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvY29udGFpbmVyL2xvb2t1cC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9pbnZlcnNpZnkuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvcGxhbm5pbmcvY29udGV4dC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9tZXRhZGF0YS5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9tZXRhZGF0YV9yZWFkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvcGxhbm5pbmcvcGxhbi5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9wbGFubmVyLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL3BsYW5uaW5nL3F1ZXJ5YWJsZV9zdHJpbmcuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvcGxhbm5pbmcvcmVmbGVjdGlvbl91dGlscy5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9yZXF1ZXN0LmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL3BsYW5uaW5nL3RhcmdldC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9yZXNvbHV0aW9uL2luc3RhbnRpYXRpb24uanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvcmVzb2x1dGlvbi9yZXNvbHZlci5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9zeW50YXgvYmluZGluZ19pbl9zeW50YXguanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvc3ludGF4L2JpbmRpbmdfaW5fd2hlbl9vbl9zeW50YXguanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvc3ludGF4L2JpbmRpbmdfb25fc3ludGF4LmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL3N5bnRheC9iaW5kaW5nX3RvX3N5bnRheC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9zeW50YXgvYmluZGluZ193aGVuX29uX3N5bnRheC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9zeW50YXgvYmluZGluZ193aGVuX3N5bnRheC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9zeW50YXgvY29uc3RyYWludF9oZWxwZXJzLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL3V0aWxzL2JpbmRpbmdfdXRpbHMuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvdXRpbHMvZXhjZXB0aW9ucy5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi91dGlscy9pZC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi91dGlscy9zZXJpYWxpemF0aW9uLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9xcy9saWIvZm9ybWF0cy5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvcXMvbGliL2luZGV4LmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9xcy9saWIvcGFyc2UuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL3FzL2xpYi9zdHJpbmdpZnkuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL3FzL2xpYi91dGlscy5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvcmVmbGVjdC1tZXRhZGF0YS9SZWZsZWN0LmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zZW12ZXItY29tcGFyZS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvc2VtdmVyL3NlbXZlci5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvdHVubmVsL2luZGV4LmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy90dW5uZWwvbGliL3R1bm5lbC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvdHlwZWQtcmVzdC1jbGllbnQvSHR0cENsaWVudC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvdHlwZWQtcmVzdC1jbGllbnQvVXRpbC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvdXVpZC9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvdXVpZC9saWIvYnl0ZXNUb1V1aWQuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvdXVpZC92MS5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvYWdlbnQvZ2l0aHViL2J1aWxkLWFnZW50LnRzIiwid2VicGFjazovLy8uL3NyYy9jb3JlL2NvbW1vbi50cyIsIndlYnBhY2s6Ly8vLi9zcmMvY29yZS9kb3RuZXQtdG9vbC50cyIsIndlYnBhY2s6Ly8vLi9zcmMvY29yZS9pb2MudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvcmUvdmVyc2lvbk1hbmFnZXIudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3Rhc2tzL2dpdHJlbGVhc2VtYW5hZ2VyL2NyZWF0ZS50cyIsIndlYnBhY2s6Ly8vLi9zcmMvdGFza3MvZ2l0cmVsZWFzZW1hbmFnZXIvbWFpbi50cyIsIndlYnBhY2s6Ly8vLi9zcmMvdG9vbHMvZ2l0cmVsZWFzZW1hbmFnZXIvZ2l0cmVsZWFzZW1hbmFnZXItdG9vbC50cyIsIndlYnBhY2s6Ly8vLi9zcmMvdG9vbHMvZ2l0cmVsZWFzZW1hbmFnZXIvbW9kZWxzLnRzIiwid2VicGFjazovLy8uL3NyYy90b29scy9naXRyZWxlYXNlbWFuYWdlci9zZXR0aW5ncy50cyIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJhc3NlcnRcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJjaGlsZF9wcm9jZXNzXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiY3J5cHRvXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiZXZlbnRzXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiZnNcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJodHRwXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiaHR0cHNcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJuZXRcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJvc1wiIiwid2VicGFjazovLy9leHRlcm5hbCBcInBhdGhcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJ0bHNcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJ1cmxcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJ1dGlsXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiemxpYlwiIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O1FBQUE7UUFDQTs7UUFFQTtRQUNBOztRQUVBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtR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QTtBQUNBLDJDQUEyQyx3Q0FBd0M7QUFDbkY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZCxjQUFjO0FBQ2Q7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLE9BQU87QUFDdkM7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBLCtCQUErQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QUNBLDhFQUE4RTtBQUM5RTtBQUNBO0FBQ0EsNEVBQTRFO0FBQzVFO0FBQ0E7QUFDQSw2RUFBNkU7QUFDN0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLDBCQUEwQjtBQUN6RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJHQUEyRztBQUMzRztBQUNBLG1DQUFtQztBQUNuQztBQUNBLDBDQUEwQztBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLG1CQUFPLENBQUMsZ0ZBQVE7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2REFBNkQsR0FBRyw0QkFBNEI7QUFDNUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ2pZQSxpQkFBaUIsbUJBQU8sQ0FBQywyRkFBYzs7Ozs7Ozs7Ozs7OztBQ0ExQjs7QUFFYixVQUFVLG1CQUFPLENBQUMsZ0JBQUs7QUFDdkIsVUFBVSxtQkFBTyxDQUFDLGdCQUFLO0FBQ3ZCLFdBQVcsbUJBQU8sQ0FBQyxrQkFBTTtBQUN6QixZQUFZLG1CQUFPLENBQUMsb0JBQU87QUFDM0IsYUFBYSxtQkFBTyxDQUFDLHNCQUFRO0FBQzdCLGFBQWEsbUJBQU8sQ0FBQyxzQkFBUTtBQUM3QixXQUFXLG1CQUFPLENBQUMsa0JBQU07OztBQUd6QjtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsK0NBQStDLFNBQVM7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQSw4QkFBOEIsYUFBYTs7QUFFM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGlEQUFpRDtBQUNqRCwwQ0FBMEM7QUFDMUMsd0NBQXdDO0FBQ3hDLHdDQUF3QztBQUN4QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFD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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0Q0FBNEMsVUFBVTtBQUN0RDtBQUNBO0FBQ0EsNkNBQTZDLFVBQVU7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQyxVQUFVO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5RUFBeUUsS0FBSztBQUM5RTtBQUNBO0FBQ0EseUVBQXlFLEtBQUs7QUFDOUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5REFBeUQsWUFBWTtBQUNyRTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FB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Q0EsOEJBQThCLEVBQUU7QUFDaEM7QUFDQSw0QkFBNEIsTUFBTTtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixnQkFBZ0I7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxxQ0FBcUMsUUFBUTtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLFFBQVE7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0M7Ozs7Ozs7Ozs7OztBQzFkQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0Isb0NBQW9DO0FBQ3hELDBCQUEwQixvQ0FBb0M7QUFDOUQsMEJBQTBCLG9DQUFvQztBQUM5RDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsV0FBVztBQUNYO0FBQ0EsT0FBTztBQUNQO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIscUJBQXFCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQixnQkFBZ0I7QUFDakM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxnQkFBZ0I7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUIsc0JBQXNCO0FBQ3ZDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGlCQUFpQixzQkFBc0I7QUFDdkM7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7OztBQzNqRGE7QUFDYiw4Q0FBOEMsY0FBYztBQUM1RCxpQkFBaUIsbUJBQU8sQ0FBQyxxRkFBeUI7QUFDbEQsbUJBQW1CLG1CQUFPLENBQUMsMkZBQTRCO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkVBQTZFLHVDQUF1QztBQUNwSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLG9DQUFvQztBQUN2RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7OztBQ3pEYTtBQUNiLDhDQUE4QyxjQUFjO0FBQzVELG1CQUFtQixtQkFBTyxDQUFDLHFGQUF5QjtBQUNwRCxtQkFBbUIsbUJBQU8sQ0FBQywyRkFBNEI7QUFDdkQsaUJBQWlCLG1CQUFPLENBQUMsK0VBQXNCO0FBQy9DLHdCQUF3QixtQkFBTyxDQUFDLHFGQUFtQjtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDOUJhO0FBQ2IsOENBQThDLGNBQWM7QUFDNUQsa0JBQWtCLG1CQUFPLENBQUMscUZBQXlCO0FBQ25ELG1CQUFtQixtQkFBTyxDQUFDLDJGQUE0QjtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDZGE7QUFDYiw4Q0FBOEMsY0FBYztBQUM1RCxtQkFBbUIsbUJBQU8sQ0FBQywyRkFBNEI7QUFDdkQsaUJBQWlCLG1CQUFPLENBQUMsK0VBQXNCO0FBQy9DLHdCQUF3QixtQkFBTyxDQUFDLHFGQUFtQjtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7QUNoQmE7QUFDYiw4Q0FBOEMsY0FBYztBQUM1RCxtQkFBbUIsbUJBQU8sQ0FBQywyRkFBNEI7QUFDdkQsaUJBQWlCLG1CQUFPLENBQUMsK0VBQXNCO0FBQy9DLHdCQUF3QixtQkFBTyxDQUFDLHFGQUFtQjtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7QUNoQmE7QUFDYiw4Q0FBOEMsY0FBYztBQUM1RCxtQkFBbUIsbUJBQU8sQ0FBQywyRkFBNEI7QUFDdkQsaUJBQWlCLG1CQUFPLENBQUMsK0VBQXNCO0FBQy9DLHdCQUF3QixtQkFBTyxDQUFDLHFGQUFtQjtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7QUNoQmE7QUFDYiw4Q0FBOEMsY0FBYztBQUM1RCxrQkFBa0IsbUJBQU8sQ0FBQyxxRkFBeUI7QUFDbkQsbUJBQW1CLG1CQUFPLENBQUMsMkZBQTRCO0FBQ3ZELGlCQUFpQixtQkFBTyxDQUFDLCtFQUFzQjtBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7OztBQ2RhO0FBQ2IsOENBQThDLGNBQWM7QUFDNUQsaUJBQWlCLG1CQUFPLENBQUMsK0VBQXNCO0FBQy9DLHdCQUF3QixtQkFBTyxDQUFDLHFGQUFtQjtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7QUNmYTtBQUNiLDhDQUE4QyxjQUFjO0FBQzVELG1CQUFtQixtQkFBTyxDQUFDLDJGQUE0QjtBQUN2RCxpQkFBaUIsbUJBQU8sQ0FBQywrRUFBc0I7QUFDL0Msd0JBQXdCLG1CQUFPLENBQUMscUZBQW1CO0FBQ25EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDWGE7QUFDYiw4Q0FBOEMsY0FBYztBQUM1RCxtQkFBbUIsbUJBQU8sQ0FBQywyRkFBNEI7QUFDdkQsaUJBQWlCLG1CQUFPLENBQUMsK0VBQXNCO0FBQy9DLHdCQUF3QixtQkFBTyxDQUFDLHFGQUFtQjtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7OztBQ1hhO0FBQ2IsOENBQThDLGNBQWM7QUFDNUQsc0JBQXNCLG1CQUFPLENBQUMsMkZBQTRCO0FBQzFELFdBQVcsbUJBQU8sQ0FBQyw2REFBYTtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhDQUE4QyxhQUFhO0FBQzNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEOzs7Ozs7Ozs7Ozs7O0FDbkNhO0FBQ2IsOENBQThDLGNBQWM7QUFDNUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDUGE7QUFDYiw4Q0FBOEMsY0FBYztBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLHVCQUF1QjtBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQix1QkFBdUI7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLHVCQUF1QjtBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7OztBQzNEYTtBQUNiLDhDQUE4QyxjQUFjO0FBQzVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7QUN4QmE7QUFDYiw4Q0FBOEMsY0FBYztBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDWmE7QUFDYjtBQUNBO0FBQ0EsbUNBQW1DLE1BQU0sNkJBQTZCLEVBQUUsWUFBWSxXQUFXLEVBQUU7QUFDakcsa0NBQWtDLE1BQU0saUNBQWlDLEVBQUUsWUFBWSxXQUFXLEVBQUU7QUFDcEcsK0JBQStCLGlFQUFpRSx1QkFBdUIsRUFBRSw0QkFBNEI7QUFDcko7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLGFBQWEsNkJBQTZCLDBCQUEwQixhQUFhLEVBQUUscUJBQXFCO0FBQ3hHLGdCQUFnQixxREFBcUQsb0VBQW9FLGFBQWEsRUFBRTtBQUN4SixzQkFBc0Isc0JBQXNCLHFCQUFxQixHQUFHO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1QztBQUN2QyxrQ0FBa0MsU0FBUztBQUMzQyxrQ0FBa0MsV0FBVyxVQUFVO0FBQ3ZELHlDQUF5QyxjQUFjO0FBQ3ZEO0FBQ0EsNkdBQTZHLE9BQU8sVUFBVTtBQUM5SCxnRkFBZ0YsaUJBQWlCLE9BQU87QUFDeEcsd0RBQXdELGdCQUFnQixRQUFRLE9BQU87QUFDdkYsOENBQThDLGdCQUFnQixnQkFBZ0IsT0FBTztBQUNyRjtBQUNBLGlDQUFpQztBQUNqQztBQUNBO0FBQ0EsU0FBUyxZQUFZLGFBQWEsT0FBTyxFQUFFLFVBQVUsV0FBVztBQUNoRSxtQ0FBbUMsU0FBUztBQUM1QztBQUNBO0FBQ0EsOENBQThDLGNBQWM7QUFDNUQsZ0JBQWdCLG1CQUFPLENBQUMsNkVBQXFCO0FBQzdDLGlCQUFpQixtQkFBTyxDQUFDLHFGQUF5QjtBQUNsRCxzQkFBc0IsbUJBQU8sQ0FBQywyRkFBNEI7QUFDMUQsbUJBQW1CLG1CQUFPLENBQUMsMkZBQTRCO0FBQ3ZELHdCQUF3QixtQkFBTyxDQUFDLDZGQUE2QjtBQUM3RCxnQkFBZ0IsbUJBQU8sQ0FBQyw2RUFBcUI7QUFDN0MsaUJBQWlCLG1CQUFPLENBQUMsbUZBQXdCO0FBQ2pELDBCQUEwQixtQkFBTyxDQUFDLDZGQUE2QjtBQUMvRCxXQUFXLG1CQUFPLENBQUMsNkRBQWE7QUFDaEMsc0JBQXNCLG1CQUFPLENBQUMsbUZBQXdCO0FBQ3RELDJCQUEyQixtQkFBTyxDQUFDLDBGQUFzQjtBQUN6RCxlQUFlLG1CQUFPLENBQUMsa0VBQVU7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQixhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsdUJBQXVCO0FBQy9DO0FBQ0E7QUFDQTtBQUNBLDZDQUE2Qyx1QkFBdUI7QUFDcEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsdUJBQXVCO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLHVCQUF1QjtBQUMvQztBQUNBO0FBQ0Esb0RBQW9EO0FBQ3BEO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRCxnQ0FBZ0MsRUFBRTtBQUNsRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsdUJBQXVCO0FBQy9DO0FBQ0E7QUFDQTtBQUNBLHFFQUFxRSxtQkFBbUIsRUFBRTtBQUMxRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0I7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLEVBQUU7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0RBQW9ELGdCQUFnQixFQUFFO0FBQ3RFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDs7Ozs7Ozs7Ozs7OztBQ3BVYTtBQUNiLDhDQUE4QyxjQUFjO0FBQzVELFdBQVcsbUJBQU8sQ0FBQyw2REFBYTtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7Ozs7Ozs7Ozs7Ozs7QUNsQmE7QUFDYiw4Q0FBOEMsY0FBYztBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDs7Ozs7Ozs7Ozs7OztBQ2JhO0FBQ2IsOENBQThDLGNBQWM7QUFDNUQsaUJBQWlCLG1CQUFPLENBQUMscUZBQXlCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0VBQWtFLDBCQUEwQixFQUFFO0FBQzlGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxpQ0FBaUMsRUFBRTtBQUMzRSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsQ0FBQztBQUNEOzs7Ozs7Ozs7Ozs7O0FDOUVhO0FBQ2IsOENBQThDLGNBQWM7QUFDNUQsV0FBVyxtQkFBTyxDQUFDLDBGQUEyQjtBQUM5QztBQUNBLGtCQUFrQixtQkFBTyxDQUFDLGtGQUF1QjtBQUNqRDtBQUNBLHNCQUFzQixtQkFBTyxDQUFDLDBGQUEyQjtBQUN6RDtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsbUJBQU8sQ0FBQyxnR0FBOEI7QUFDL0Q7QUFDQTtBQUNBLG1CQUFtQixtQkFBTyxDQUFDLHNGQUF5QjtBQUNwRDtBQUNBLGVBQWUsbUJBQU8sQ0FBQyw4RUFBcUI7QUFDNUM7QUFDQSxjQUFjLG1CQUFPLENBQUMsNEVBQW9CO0FBQzFDO0FBQ0EsZUFBZSxtQkFBTyxDQUFDLDhFQUFxQjtBQUM1QztBQUNBO0FBQ0EsaUJBQWlCLG1CQUFPLENBQUMsa0ZBQXVCO0FBQ2hEO0FBQ0Esa0JBQWtCLG1CQUFPLENBQUMsb0ZBQXdCO0FBQ2xEO0FBQ0EscUJBQXFCLG1CQUFPLENBQUMsMEZBQTJCO0FBQ3hEO0FBQ0Esb0JBQW9CLG1CQUFPLENBQUMsd0ZBQTBCO0FBQ3REO0FBQ0EsdUJBQXVCLG1CQUFPLENBQUMsOEZBQTZCO0FBQzVEO0FBQ0Esd0JBQXdCLG1CQUFPLENBQUMsNEZBQTRCO0FBQzVEO0FBQ0EsV0FBVyxtQkFBTyxDQUFDLDREQUFZO0FBQy9CO0FBQ0Esd0JBQXdCLG1CQUFPLENBQUMsZ0dBQThCO0FBQzlEO0FBQ0EsMkJBQTJCLG1CQUFPLENBQUMsOEZBQTZCO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLG1CQUFPLENBQUMsa0ZBQXVCO0FBQ3JEO0FBQ0Esc0JBQXNCLG1CQUFPLENBQUMsa0ZBQXVCO0FBQ3JEOzs7Ozs7Ozs7Ozs7O0FDOUNhO0FBQ2IsOENBQThDLGNBQWM7QUFDNUQsV0FBVyxtQkFBTyxDQUFDLDZEQUFhO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDs7Ozs7Ozs7Ozs7OztBQ2hCYTtBQUNiLDhDQUE4QyxjQUFjO0FBQzVELG1CQUFtQixtQkFBTyxDQUFDLDJGQUE0QjtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2Qiw2REFBNkQ7QUFDMUY7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEOzs7Ozs7Ozs7Ozs7O0FDbEJhO0FBQ2IsOENBQThDLGNBQWM7QUFDNUQsbUJBQW1CLG1CQUFPLENBQUMsMkZBQTRCO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEOzs7Ozs7Ozs7Ozs7O0FDcEJhO0FBQ2IsOENBQThDLGNBQWM7QUFDNUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEOzs7Ozs7Ozs7Ozs7O0FDVGE7QUFDYiw4Q0FBOEMsY0FBYztBQUM1RCxzQkFBc0IsbUJBQU8sQ0FBQyx5RkFBMkI7QUFDekQsaUJBQWlCLG1CQUFPLENBQUMscUZBQXlCO0FBQ2xELHNCQUFzQixtQkFBTyxDQUFDLDJGQUE0QjtBQUMxRCxtQkFBbUIsbUJBQU8sQ0FBQywyRkFBNEI7QUFDdkQsbUJBQW1CLG1CQUFPLENBQUMsNkVBQXFCO0FBQ2hELHNCQUFzQixtQkFBTyxDQUFDLG1GQUF3QjtBQUN0RCxnQkFBZ0IsbUJBQU8sQ0FBQyxtRUFBVztBQUNuQyxpQkFBaUIsbUJBQU8sQ0FBQyxxRUFBWTtBQUNyQyxhQUFhLG1CQUFPLENBQUMsNkRBQVE7QUFDN0IseUJBQXlCLG1CQUFPLENBQUMscUZBQW9CO0FBQ3JELGdCQUFnQixtQkFBTyxDQUFDLG1FQUFXO0FBQ25DLGVBQWUsbUJBQU8sQ0FBQyxpRUFBVTtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0MsMEJBQTBCO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7QUMxSmE7QUFDYiw4Q0FBOEMsY0FBYztBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDLHFCQUFxQjtBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEOzs7Ozs7Ozs7Ozs7O0FDMUJhO0FBQ2IsOENBQThDLGNBQWM7QUFDNUQsZUFBZSxtQkFBTyxDQUFDLCtFQUFzQjtBQUM3QyxpQkFBaUIsbUJBQU8sQ0FBQyxxRkFBeUI7QUFDbEQsc0JBQXNCLG1CQUFPLENBQUMsMkZBQTRCO0FBQzFELG1CQUFtQixtQkFBTyxDQUFDLDJGQUE0QjtBQUN2RCxzQkFBc0IsbUJBQU8sQ0FBQyxtRkFBd0I7QUFDdEQ7QUFDQSxlQUFlLG1CQUFPLENBQUMsaUVBQVU7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsZ0JBQWdCO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyxvQkFBb0I7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7QUMzSGE7QUFDYiw4Q0FBOEMsY0FBYztBQUM1RCxXQUFXLG1CQUFPLENBQUMsNkRBQWE7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7Ozs7Ozs7Ozs7Ozs7QUN2QmE7QUFDYiw4Q0FBOEMsY0FBYztBQUM1RCxtQkFBbUIsbUJBQU8sQ0FBQywyRkFBNEI7QUFDdkQsV0FBVyxtQkFBTyxDQUFDLDZEQUFhO0FBQ2hDLGlCQUFpQixtQkFBTyxDQUFDLHFFQUFZO0FBQ3JDLHlCQUF5QixtQkFBTyxDQUFDLHFGQUFvQjtBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRDQUE0QyxnQkFBZ0I7QUFDNUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzREFBc0QseUNBQXlDLEVBQUU7QUFDakc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpREFBaUQsZ0JBQWdCO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDs7Ozs7Ozs7Ozs7OztBQ3pGYTtBQUNiLDhDQUE4QyxjQUFjO0FBQzVELG1CQUFtQixtQkFBTyxDQUFDLHFGQUF5QjtBQUNwRCxzQkFBc0IsbUJBQU8sQ0FBQywyRkFBNEI7QUFDMUQsbUJBQW1CLG1CQUFPLENBQUMsMkZBQTRCO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7OztBQ2pEYTtBQUNiLDhDQUE4QyxjQUFjO0FBQzVELGlCQUFpQixtQkFBTyxDQUFDLHFGQUF5QjtBQUNsRCxzQkFBc0IsbUJBQU8sQ0FBQywyRkFBNEI7QUFDMUQsbUJBQW1CLG1CQUFPLENBQUMsNkVBQXFCO0FBQ2hELHNCQUFzQixtQkFBTyxDQUFDLG1GQUF3QjtBQUN0RCxzQkFBc0IsbUJBQU8sQ0FBQyxpRkFBaUI7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1HQUFtRyxzREFBc0QsRUFBRTtBQUMzSjtBQUNBO0FBQ0EsOEZBQThGLGlEQUFpRCxFQUFFO0FBQ2pKO0FBQ0E7QUFDQSwrRkFBK0Ysa0RBQWtELEVBQUU7QUFDbko7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7OztBQ2pHYTtBQUNiLDhDQUE4QyxjQUFjO0FBQzVELHNCQUFzQixtQkFBTyxDQUFDLDJGQUE0QjtBQUMxRCwrQkFBK0IsbUJBQU8sQ0FBQywrRkFBMEI7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDs7Ozs7Ozs7Ozs7OztBQ3RCYTtBQUNiLDhDQUE4QyxjQUFjO0FBQzVELDBCQUEwQixtQkFBTyxDQUFDLHFGQUFxQjtBQUN2RCwwQkFBMEIsbUJBQU8sQ0FBQyxxRkFBcUI7QUFDdkQsNEJBQTRCLG1CQUFPLENBQUMseUZBQXVCO0FBQzNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7Ozs7Ozs7Ozs7Ozs7QUN2RWE7QUFDYiw4Q0FBOEMsY0FBYztBQUM1RCw0QkFBNEIsbUJBQU8sQ0FBQyx5RkFBdUI7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEOzs7Ozs7Ozs7Ozs7O0FDYmE7QUFDYiw4Q0FBOEMsY0FBYztBQUM1RCxpQkFBaUIsbUJBQU8sQ0FBQyxxRkFBeUI7QUFDbEQsc0JBQXNCLG1CQUFPLENBQUMsMkZBQTRCO0FBQzFELGtDQUFrQyxtQkFBTyxDQUFDLHFHQUE2QjtBQUN2RSwrQkFBK0IsbUJBQU8sQ0FBQywrRkFBMEI7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDLGlEQUFpRDtBQUM1RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRCx1Q0FBdUMsRUFBRTtBQUN6RjtBQUNBO0FBQ0EsQ0FBQztBQUNEOzs7Ozs7Ozs7Ozs7O0FDeEVhO0FBQ2IsOENBQThDLGNBQWM7QUFDNUQsMEJBQTBCLG1CQUFPLENBQUMscUZBQXFCO0FBQ3ZELDRCQUE0QixtQkFBTyxDQUFDLHlGQUF1QjtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDs7Ozs7Ozs7Ozs7OztBQzVEYTtBQUNiLDhDQUE4QyxjQUFjO0FBQzVELDBCQUEwQixtQkFBTyxDQUFDLHFGQUFxQjtBQUN2RCwyQkFBMkIsbUJBQU8sQ0FBQyx1RkFBc0I7QUFDekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDs7Ozs7Ozs7Ozs7OztBQ2pHYTtBQUNiLDhDQUE4QyxjQUFjO0FBQzVELG1CQUFtQixtQkFBTyxDQUFDLDJGQUE0QjtBQUN2RCxpQkFBaUIsbUJBQU8sQ0FBQywrRUFBc0I7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUM7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7Ozs7Ozs7Ozs7Ozs7QUN2Q2E7QUFDYiw4Q0FBOEMsY0FBYztBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0Qix1QkFBdUI7QUFDbkQ7QUFDQTtBQUNBLCtDQUErQyw2Q0FBNkMsRUFBRTtBQUM5RjtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7QUNaYTtBQUNiLDhDQUE4QyxjQUFjO0FBQzVELGlCQUFpQixtQkFBTyxDQUFDLHFGQUF5QjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDUGE7QUFDYiw4Q0FBOEMsY0FBYztBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDTmE7QUFDYiw4Q0FBOEMsY0FBYztBQUM1RCxpQkFBaUIsbUJBQU8sQ0FBQyxxRkFBeUI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxhQUFhO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDdEdhOztBQUViO0FBQ0E7O0FBRUEsV0FBVyxtQkFBTyxDQUFDLCtDQUFTOztBQUU1QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7Ozs7Ozs7Ozs7OztBQ3pCYTs7QUFFYixnQkFBZ0IsbUJBQU8sQ0FBQyx1REFBYTtBQUNyQyxZQUFZLG1CQUFPLENBQUMsK0NBQVM7QUFDN0IsY0FBYyxtQkFBTyxDQUFDLG1EQUFXOztBQUVqQztBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDVmE7O0FBRWIsWUFBWSxtQkFBTyxDQUFDLCtDQUFTOztBQUU3QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxnQ0FBZ0M7O0FBRXhFO0FBQ0EsdUNBQXVDOztBQUV2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCOztBQUVBO0FBQ0E7QUFDQSxtQkFBbUIsa0JBQWtCO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBOztBQUVBLGVBQWUsa0JBQWtCO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxrQ0FBa0MsUUFBUTtBQUMxQztBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkIsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxtQkFBbUIsaUJBQWlCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7QUN2UGE7O0FBRWIsWUFBWSxtQkFBTyxDQUFDLCtDQUFTO0FBQzdCLGNBQWMsbUJBQU8sQ0FBQyxtREFBVztBQUNqQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUEsbUJBQW1CLG9CQUFvQjtBQUN2Qzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUIsb0JBQW9CO0FBQ3ZDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDJDQUEyQztBQUMzQztBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDdFJhOztBQUViO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1CQUFtQixTQUFTO0FBQzVCO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBOztBQUVB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QTJDO0FBQzNDLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQztBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQywyQ0FBMkM7QUFDM0MsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVHQUF1RztBQUN2RztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQywyQ0FBMkM7QUFDM0MsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0ZBQWdGO0FBQ2hGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLDJDQUEyQztBQUMzQyw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxRUFBcUU7QUFDckU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkMsMkNBQTJDO0FBQzNDLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFFQUFxRTtBQUNyRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQywyQ0FBMkM7QUFDM0MsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkMsMkNBQTJDO0FBQzNDLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLDJDQUEyQztBQUMzQyw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1RUFBdUU7QUFDdkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkMsMkNBQTJDO0FBQzNDLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQ0FBK0MsUUFBUTtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0NBQStDLFFBQVE7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpREFBaUQsdUJBQXVCO0FBQ3hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdURBQXVELDBCQUEwQjtBQUNqRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUVBQW1FLGFBQWE7QUFDaEYscUVBQXFFLGFBQWE7QUFDbEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0Isb0NBQW9DO0FBQ3hELDBCQUEwQixvQ0FBb0M7QUFDOUQsMEJBQTBCLG9DQUFvQztBQUM5RDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1AsS0FBSztBQUNMLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FB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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkIscUJBQXFCO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyR0FBMkc7QUFDM0c7QUFDQSxtQ0FBbUM7QUFDbkM7QUFDQSwwQ0FBMEM7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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QUFDO0lBRU8sTUFBTSxDQUFDLGlCQUFpQixDQUFDLFVBQXVCO1FBQ3BELE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUMscUJBQVksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDNUQsTUFBTSxVQUFVLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FBQyxxQkFBWSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN0RSxNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsUUFBUSxDQUFDLHFCQUFZLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRTVELE9BQU87WUFDSCxLQUFLO1lBQ0wsVUFBVTtZQUNWLEtBQUs7U0FDUixDQUFDO0lBQ04sQ0FBQztDQUNKO0FBaENELDRCQWdDQzs7Ozs7Ozs7Ozs7O0FDbkNELG1DOzs7Ozs7Ozs7OztBQ0FBLDBDOzs7Ozs7Ozs7OztBQ0FBLG1DOzs7Ozs7Ozs7OztBQ0FBLG1DOzs7Ozs7Ozs7OztBQ0FBLCtCOzs7Ozs7Ozs7OztBQ0FBLGlDOzs7Ozs7Ozs7OztBQ0FBLGtDOzs7Ozs7Ozs7OztBQ0FBLGdDOzs7Ozs7Ozs7OztBQ0FBLCtCOzs7Ozs7Ozs7OztBQ0FBLGlDOzs7Ozs7Ozs7OztBQ0FBLGdDOzs7Ozs7Ozs7OztBQ0FBLGdDOzs7Ozs7Ozs7OztBQ0FBLGlDOzs7Ozs7Ozs7OztBQ0FBLGlDIiwiZmlsZSI6ImdpdHJlbGVhc2VtYW5hZ2VyL2NyZWF0ZS9idW5kbGUuanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBnZXR0ZXIgfSk7XG4gXHRcdH1cbiBcdH07XG5cbiBcdC8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uciA9IGZ1bmN0aW9uKGV4cG9ydHMpIHtcbiBcdFx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG4gXHRcdH1cbiBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbiBcdH07XG5cbiBcdC8vIGNyZWF0ZSBhIGZha2UgbmFtZXNwYWNlIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDE6IHZhbHVlIGlzIGEgbW9kdWxlIGlkLCByZXF1aXJlIGl0XG4gXHQvLyBtb2RlICYgMjogbWVyZ2UgYWxsIHByb3BlcnRpZXMgb2YgdmFsdWUgaW50byB0aGUgbnNcbiBcdC8vIG1vZGUgJiA0OiByZXR1cm4gdmFsdWUgd2hlbiBhbHJlYWR5IG5zIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDh8MTogYmVoYXZlIGxpa2UgcmVxdWlyZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy50ID0gZnVuY3Rpb24odmFsdWUsIG1vZGUpIHtcbiBcdFx0aWYobW9kZSAmIDEpIHZhbHVlID0gX193ZWJwYWNrX3JlcXVpcmVfXyh2YWx1ZSk7XG4gXHRcdGlmKG1vZGUgJiA4KSByZXR1cm4gdmFsdWU7XG4gXHRcdGlmKChtb2RlICYgNCkgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAmJiB2YWx1ZS5fX2VzTW9kdWxlKSByZXR1cm4gdmFsdWU7XG4gXHRcdHZhciBucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18ucihucyk7XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShucywgJ2RlZmF1bHQnLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2YWx1ZSB9KTtcbiBcdFx0aWYobW9kZSAmIDIgJiYgdHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSBmb3IodmFyIGtleSBpbiB2YWx1ZSkgX193ZWJwYWNrX3JlcXVpcmVfXy5kKG5zLCBrZXksIGZ1bmN0aW9uKGtleSkgeyByZXR1cm4gdmFsdWVba2V5XTsgfS5iaW5kKG51bGwsIGtleSkpO1xuIFx0XHRyZXR1cm4gbnM7XG4gXHR9O1xuXG4gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XG4gXHRcdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgJ2EnLCBnZXR0ZXIpO1xuIFx0XHRyZXR1cm4gZ2V0dGVyO1xuIFx0fTtcblxuIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG5cbiBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xuXG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gXCIuL3NyYy90YXNrcy9naXRyZWxlYXNlbWFuYWdlci9jcmVhdGUudHNcIik7XG4iLCJcInVzZSBzdHJpY3RcIjtcbnZhciBfX2ltcG9ydFN0YXIgPSAodGhpcyAmJiB0aGlzLl9faW1wb3J0U3RhcikgfHwgZnVuY3Rpb24gKG1vZCkge1xuICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XG4gICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayBpbiBtb2QpIGlmIChPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSByZXN1bHRba10gPSBtb2Rba107XG4gICAgcmVzdWx0W1wiZGVmYXVsdFwiXSA9IG1vZDtcbiAgICByZXR1cm4gcmVzdWx0O1xufTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNvbnN0IG9zID0gX19pbXBvcnRTdGFyKHJlcXVpcmUoXCJvc1wiKSk7XG4vKipcbiAqIENvbW1hbmRzXG4gKlxuICogQ29tbWFuZCBGb3JtYXQ6XG4gKiAgIDo6bmFtZSBrZXk9dmFsdWUsa2V5PXZhbHVlOjptZXNzYWdlXG4gKlxuICogRXhhbXBsZXM6XG4gKiAgIDo6d2FybmluZzo6VGhpcyBpcyB0aGUgbWVzc2FnZVxuICogICA6OnNldC1lbnYgbmFtZT1NWV9WQVI6OnNvbWUgdmFsdWVcbiAqL1xuZnVuY3Rpb24gaXNzdWVDb21tYW5kKGNvbW1hbmQsIHByb3BlcnRpZXMsIG1lc3NhZ2UpIHtcbiAgICBjb25zdCBjbWQgPSBuZXcgQ29tbWFuZChjb21tYW5kLCBwcm9wZXJ0aWVzLCBtZXNzYWdlKTtcbiAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShjbWQudG9TdHJpbmcoKSArIG9zLkVPTCk7XG59XG5leHBvcnRzLmlzc3VlQ29tbWFuZCA9IGlzc3VlQ29tbWFuZDtcbmZ1bmN0aW9uIGlzc3VlKG5hbWUsIG1lc3NhZ2UgPSAnJykge1xuICAgIGlzc3VlQ29tbWFuZChuYW1lLCB7fSwgbWVzc2FnZSk7XG59XG5leHBvcnRzLmlzc3VlID0gaXNzdWU7XG5jb25zdCBDTURfU1RSSU5HID0gJzo6JztcbmNsYXNzIENvbW1hbmQge1xuICAgIGNvbnN0cnVjdG9yKGNvbW1hbmQsIHByb3BlcnRpZXMsIG1lc3NhZ2UpIHtcbiAgICAgICAgaWYgKCFjb21tYW5kKSB7XG4gICAgICAgICAgICBjb21tYW5kID0gJ21pc3NpbmcuY29tbWFuZCc7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb21tYW5kID0gY29tbWFuZDtcbiAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllcztcbiAgICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgICB9XG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIGxldCBjbWRTdHIgPSBDTURfU1RSSU5HICsgdGhpcy5jb21tYW5kO1xuICAgICAgICBpZiAodGhpcy5wcm9wZXJ0aWVzICYmIE9iamVjdC5rZXlzKHRoaXMucHJvcGVydGllcykubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY21kU3RyICs9ICcgJztcbiAgICAgICAgICAgIGxldCBmaXJzdCA9IHRydWU7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiB0aGlzLnByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wcm9wZXJ0aWVzLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsID0gdGhpcy5wcm9wZXJ0aWVzW2tleV07XG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbWRTdHIgKz0gJywnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgY21kU3RyICs9IGAke2tleX09JHtlc2NhcGVQcm9wZXJ0eSh2YWwpfWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY21kU3RyICs9IGAke0NNRF9TVFJJTkd9JHtlc2NhcGVEYXRhKHRoaXMubWVzc2FnZSl9YDtcbiAgICAgICAgcmV0dXJuIGNtZFN0cjtcbiAgICB9XG59XG5mdW5jdGlvbiBlc2NhcGVEYXRhKHMpIHtcbiAgICByZXR1cm4gKHMgfHwgJycpXG4gICAgICAgIC5yZXBsYWNlKC8lL2csICclMjUnKVxuICAgICAgICAucmVwbGFjZSgvXFxyL2csICclMEQnKVxuICAgICAgICAucmVwbGFjZSgvXFxuL2csICclMEEnKTtcbn1cbmZ1bmN0aW9uIGVzY2FwZVByb3BlcnR5KHMpIHtcbiAgICByZXR1cm4gKHMgfHwgJycpXG4gICAgICAgIC5yZXBsYWNlKC8lL2csICclMjUnKVxuICAgICAgICAucmVwbGFjZSgvXFxyL2csICclMEQnKVxuICAgICAgICAucmVwbGFjZSgvXFxuL2csICclMEEnKVxuICAgICAgICAucmVwbGFjZSgvOi9nLCAnJTNBJylcbiAgICAgICAgLnJlcGxhY2UoLywvZywgJyUyQycpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29tbWFuZC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbnZhciBfX2F3YWl0ZXIgPSAodGhpcyAmJiB0aGlzLl9fYXdhaXRlcikgfHwgZnVuY3Rpb24gKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xuICAgIGZ1bmN0aW9uIGFkb3B0KHZhbHVlKSB7IHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFAgPyB2YWx1ZSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUodmFsdWUpOyB9KTsgfVxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XG4gICAgfSk7XG59O1xudmFyIF9faW1wb3J0U3RhciA9ICh0aGlzICYmIHRoaXMuX19pbXBvcnRTdGFyKSB8fCBmdW5jdGlvbiAobW9kKSB7XG4gICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcbiAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZCwgaykpIHJlc3VsdFtrXSA9IG1vZFtrXTtcbiAgICByZXN1bHRbXCJkZWZhdWx0XCJdID0gbW9kO1xuICAgIHJldHVybiByZXN1bHQ7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuY29uc3QgY29tbWFuZF8xID0gcmVxdWlyZShcIi4vY29tbWFuZFwiKTtcbmNvbnN0IG9zID0gX19pbXBvcnRTdGFyKHJlcXVpcmUoXCJvc1wiKSk7XG5jb25zdCBwYXRoID0gX19pbXBvcnRTdGFyKHJlcXVpcmUoXCJwYXRoXCIpKTtcbi8qKlxuICogVGhlIGNvZGUgdG8gZXhpdCBhbiBhY3Rpb25cbiAqL1xudmFyIEV4aXRDb2RlO1xuKGZ1bmN0aW9uIChFeGl0Q29kZSkge1xuICAgIC8qKlxuICAgICAqIEEgY29kZSBpbmRpY2F0aW5nIHRoYXQgdGhlIGFjdGlvbiB3YXMgc3VjY2Vzc2Z1bFxuICAgICAqL1xuICAgIEV4aXRDb2RlW0V4aXRDb2RlW1wiU3VjY2Vzc1wiXSA9IDBdID0gXCJTdWNjZXNzXCI7XG4gICAgLyoqXG4gICAgICogQSBjb2RlIGluZGljYXRpbmcgdGhhdCB0aGUgYWN0aW9uIHdhcyBhIGZhaWx1cmVcbiAgICAgKi9cbiAgICBFeGl0Q29kZVtFeGl0Q29kZVtcIkZhaWx1cmVcIl0gPSAxXSA9IFwiRmFpbHVyZVwiO1xufSkoRXhpdENvZGUgPSBleHBvcnRzLkV4aXRDb2RlIHx8IChleHBvcnRzLkV4aXRDb2RlID0ge30pKTtcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFZhcmlhYmxlc1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLyoqXG4gKiBTZXRzIGVudiB2YXJpYWJsZSBmb3IgdGhpcyBhY3Rpb24gYW5kIGZ1dHVyZSBhY3Rpb25zIGluIHRoZSBqb2JcbiAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIHRoZSB2YXJpYWJsZSB0byBzZXRcbiAqIEBwYXJhbSB2YWwgdGhlIHZhbHVlIG9mIHRoZSB2YXJpYWJsZVxuICovXG5mdW5jdGlvbiBleHBvcnRWYXJpYWJsZShuYW1lLCB2YWwpIHtcbiAgICBwcm9jZXNzLmVudltuYW1lXSA9IHZhbDtcbiAgICBjb21tYW5kXzEuaXNzdWVDb21tYW5kKCdzZXQtZW52JywgeyBuYW1lIH0sIHZhbCk7XG59XG5leHBvcnRzLmV4cG9ydFZhcmlhYmxlID0gZXhwb3J0VmFyaWFibGU7XG4vKipcbiAqIFJlZ2lzdGVycyBhIHNlY3JldCB3aGljaCB3aWxsIGdldCBtYXNrZWQgZnJvbSBsb2dzXG4gKiBAcGFyYW0gc2VjcmV0IHZhbHVlIG9mIHRoZSBzZWNyZXRcbiAqL1xuZnVuY3Rpb24gc2V0U2VjcmV0KHNlY3JldCkge1xuICAgIGNvbW1hbmRfMS5pc3N1ZUNvbW1hbmQoJ2FkZC1tYXNrJywge30sIHNlY3JldCk7XG59XG5leHBvcnRzLnNldFNlY3JldCA9IHNldFNlY3JldDtcbi8qKlxuICogUHJlcGVuZHMgaW5wdXRQYXRoIHRvIHRoZSBQQVRIIChmb3IgdGhpcyBhY3Rpb24gYW5kIGZ1dHVyZSBhY3Rpb25zKVxuICogQHBhcmFtIGlucHV0UGF0aFxuICovXG5mdW5jdGlvbiBhZGRQYXRoKGlucHV0UGF0aCkge1xuICAgIGNvbW1hbmRfMS5pc3N1ZUNvbW1hbmQoJ2FkZC1wYXRoJywge30sIGlucHV0UGF0aCk7XG4gICAgcHJvY2Vzcy5lbnZbJ1BBVEgnXSA9IGAke2lucHV0UGF0aH0ke3BhdGguZGVsaW1pdGVyfSR7cHJvY2Vzcy5lbnZbJ1BBVEgnXX1gO1xufVxuZXhwb3J0cy5hZGRQYXRoID0gYWRkUGF0aDtcbi8qKlxuICogR2V0cyB0aGUgdmFsdWUgb2YgYW4gaW5wdXQuICBUaGUgdmFsdWUgaXMgYWxzbyB0cmltbWVkLlxuICpcbiAqIEBwYXJhbSAgICAgbmFtZSAgICAgbmFtZSBvZiB0aGUgaW5wdXQgdG8gZ2V0XG4gKiBAcGFyYW0gICAgIG9wdGlvbnMgIG9wdGlvbmFsLiBTZWUgSW5wdXRPcHRpb25zLlxuICogQHJldHVybnMgICBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gZ2V0SW5wdXQobmFtZSwgb3B0aW9ucykge1xuICAgIGNvbnN0IHZhbCA9IHByb2Nlc3MuZW52W2BJTlBVVF8ke25hbWUucmVwbGFjZSgvIC9nLCAnXycpLnRvVXBwZXJDYXNlKCl9YF0gfHwgJyc7XG4gICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5yZXF1aXJlZCAmJiAhdmFsKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW5wdXQgcmVxdWlyZWQgYW5kIG5vdCBzdXBwbGllZDogJHtuYW1lfWApO1xuICAgIH1cbiAgICByZXR1cm4gdmFsLnRyaW0oKTtcbn1cbmV4cG9ydHMuZ2V0SW5wdXQgPSBnZXRJbnB1dDtcbi8qKlxuICogU2V0cyB0aGUgdmFsdWUgb2YgYW4gb3V0cHV0LlxuICpcbiAqIEBwYXJhbSAgICAgbmFtZSAgICAgbmFtZSBvZiB0aGUgb3V0cHV0IHRvIHNldFxuICogQHBhcmFtICAgICB2YWx1ZSAgICB2YWx1ZSB0byBzdG9yZVxuICovXG5mdW5jdGlvbiBzZXRPdXRwdXQobmFtZSwgdmFsdWUpIHtcbiAgICBjb21tYW5kXzEuaXNzdWVDb21tYW5kKCdzZXQtb3V0cHV0JywgeyBuYW1lIH0sIHZhbHVlKTtcbn1cbmV4cG9ydHMuc2V0T3V0cHV0ID0gc2V0T3V0cHV0O1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUmVzdWx0c1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLyoqXG4gKiBTZXRzIHRoZSBhY3Rpb24gc3RhdHVzIHRvIGZhaWxlZC5cbiAqIFdoZW4gdGhlIGFjdGlvbiBleGl0cyBpdCB3aWxsIGJlIHdpdGggYW4gZXhpdCBjb2RlIG9mIDFcbiAqIEBwYXJhbSBtZXNzYWdlIGFkZCBlcnJvciBpc3N1ZSBtZXNzYWdlXG4gKi9cbmZ1bmN0aW9uIHNldEZhaWxlZChtZXNzYWdlKSB7XG4gICAgcHJvY2Vzcy5leGl0Q29kZSA9IEV4aXRDb2RlLkZhaWx1cmU7XG4gICAgZXJyb3IobWVzc2FnZSk7XG59XG5leHBvcnRzLnNldEZhaWxlZCA9IHNldEZhaWxlZDtcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIExvZ2dpbmcgQ29tbWFuZHNcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8qKlxuICogV3JpdGVzIGRlYnVnIG1lc3NhZ2UgdG8gdXNlciBsb2dcbiAqIEBwYXJhbSBtZXNzYWdlIGRlYnVnIG1lc3NhZ2VcbiAqL1xuZnVuY3Rpb24gZGVidWcobWVzc2FnZSkge1xuICAgIGNvbW1hbmRfMS5pc3N1ZUNvbW1hbmQoJ2RlYnVnJywge30sIG1lc3NhZ2UpO1xufVxuZXhwb3J0cy5kZWJ1ZyA9IGRlYnVnO1xuLyoqXG4gKiBBZGRzIGFuIGVycm9yIGlzc3VlXG4gKiBAcGFyYW0gbWVzc2FnZSBlcnJvciBpc3N1ZSBtZXNzYWdlXG4gKi9cbmZ1bmN0aW9uIGVycm9yKG1lc3NhZ2UpIHtcbiAgICBjb21tYW5kXzEuaXNzdWUoJ2Vycm9yJywgbWVzc2FnZSk7XG59XG5leHBvcnRzLmVycm9yID0gZXJyb3I7XG4vKipcbiAqIEFkZHMgYW4gd2FybmluZyBpc3N1ZVxuICogQHBhcmFtIG1lc3NhZ2Ugd2FybmluZyBpc3N1ZSBtZXNzYWdlXG4gKi9cbmZ1bmN0aW9uIHdhcm5pbmcobWVzc2FnZSkge1xuICAgIGNvbW1hbmRfMS5pc3N1ZSgnd2FybmluZycsIG1lc3NhZ2UpO1xufVxuZXhwb3J0cy53YXJuaW5nID0gd2FybmluZztcbi8qKlxuICogV3JpdGVzIGluZm8gdG8gbG9nIHdpdGggY29uc29sZS5sb2cuXG4gKiBAcGFyYW0gbWVzc2FnZSBpbmZvIG1lc3NhZ2VcbiAqL1xuZnVuY3Rpb24gaW5mbyhtZXNzYWdlKSB7XG4gICAgcHJvY2Vzcy5zdGRvdXQud3JpdGUobWVzc2FnZSArIG9zLkVPTCk7XG59XG5leHBvcnRzLmluZm8gPSBpbmZvO1xuLyoqXG4gKiBCZWdpbiBhbiBvdXRwdXQgZ3JvdXAuXG4gKlxuICogT3V0cHV0IHVudGlsIHRoZSBuZXh0IGBncm91cEVuZGAgd2lsbCBiZSBmb2xkYWJsZSBpbiB0aGlzIGdyb3VwXG4gKlxuICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIG91dHB1dCBncm91cFxuICovXG5mdW5jdGlvbiBzdGFydEdyb3VwKG5hbWUpIHtcbiAgICBjb21tYW5kXzEuaXNzdWUoJ2dyb3VwJywgbmFtZSk7XG59XG5leHBvcnRzLnN0YXJ0R3JvdXAgPSBzdGFydEdyb3VwO1xuLyoqXG4gKiBFbmQgYW4gb3V0cHV0IGdyb3VwLlxuICovXG5mdW5jdGlvbiBlbmRHcm91cCgpIHtcbiAgICBjb21tYW5kXzEuaXNzdWUoJ2VuZGdyb3VwJyk7XG59XG5leHBvcnRzLmVuZEdyb3VwID0gZW5kR3JvdXA7XG4vKipcbiAqIFdyYXAgYW4gYXN5bmNocm9ub3VzIGZ1bmN0aW9uIGNhbGwgaW4gYSBncm91cC5cbiAqXG4gKiBSZXR1cm5zIHRoZSBzYW1lIHR5cGUgYXMgdGhlIGZ1bmN0aW9uIGl0c2VsZi5cbiAqXG4gKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZ3JvdXBcbiAqIEBwYXJhbSBmbiBUaGUgZnVuY3Rpb24gdG8gd3JhcCBpbiB0aGUgZ3JvdXBcbiAqL1xuZnVuY3Rpb24gZ3JvdXAobmFtZSwgZm4pIHtcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICBzdGFydEdyb3VwKG5hbWUpO1xuICAgICAgICBsZXQgcmVzdWx0O1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmVzdWx0ID0geWllbGQgZm4oKTtcbiAgICAgICAgfVxuICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgIGVuZEdyb3VwKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KTtcbn1cbmV4cG9ydHMuZ3JvdXAgPSBncm91cDtcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFdyYXBwZXIgYWN0aW9uIHN0YXRlXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vKipcbiAqIFNhdmVzIHN0YXRlIGZvciBjdXJyZW50IGFjdGlvbiwgdGhlIHN0YXRlIGNhbiBvbmx5IGJlIHJldHJpZXZlZCBieSB0aGlzIGFjdGlvbidzIHBvc3Qgam9iIGV4ZWN1dGlvbi5cbiAqXG4gKiBAcGFyYW0gICAgIG5hbWUgICAgIG5hbWUgb2YgdGhlIHN0YXRlIHRvIHN0b3JlXG4gKiBAcGFyYW0gICAgIHZhbHVlICAgIHZhbHVlIHRvIHN0b3JlXG4gKi9cbmZ1bmN0aW9uIHNhdmVTdGF0ZShuYW1lLCB2YWx1ZSkge1xuICAgIGNvbW1hbmRfMS5pc3N1ZUNvbW1hbmQoJ3NhdmUtc3RhdGUnLCB7IG5hbWUgfSwgdmFsdWUpO1xufVxuZXhwb3J0cy5zYXZlU3RhdGUgPSBzYXZlU3RhdGU7XG4vKipcbiAqIEdldHMgdGhlIHZhbHVlIG9mIGFuIHN0YXRlIHNldCBieSB0aGlzIGFjdGlvbidzIG1haW4gZXhlY3V0aW9uLlxuICpcbiAqIEBwYXJhbSAgICAgbmFtZSAgICAgbmFtZSBvZiB0aGUgc3RhdGUgdG8gZ2V0XG4gKiBAcmV0dXJucyAgIHN0cmluZ1xuICovXG5mdW5jdGlvbiBnZXRTdGF0ZShuYW1lKSB7XG4gICAgcmV0dXJuIHByb2Nlc3MuZW52W2BTVEFURV8ke25hbWV9YF0gfHwgJyc7XG59XG5leHBvcnRzLmdldFN0YXRlID0gZ2V0U3RhdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb3JlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xudmFyIF9fYXdhaXRlciA9ICh0aGlzICYmIHRoaXMuX19hd2FpdGVyKSB8fCBmdW5jdGlvbiAodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogYWRvcHQocmVzdWx0LnZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcbiAgICB9KTtcbn07XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5jb25zdCB0ciA9IHJlcXVpcmUoXCIuL3Rvb2xydW5uZXJcIik7XG4vKipcbiAqIEV4ZWMgYSBjb21tYW5kLlxuICogT3V0cHV0IHdpbGwgYmUgc3RyZWFtZWQgdG8gdGhlIGxpdmUgY29uc29sZS5cbiAqIFJldHVybnMgcHJvbWlzZSB3aXRoIHJldHVybiBjb2RlXG4gKlxuICogQHBhcmFtICAgICBjb21tYW5kTGluZSAgICAgICAgY29tbWFuZCB0byBleGVjdXRlIChjYW4gaW5jbHVkZSBhZGRpdGlvbmFsIGFyZ3MpLiBNdXN0IGJlIGNvcnJlY3RseSBlc2NhcGVkLlxuICogQHBhcmFtICAgICBhcmdzICAgICAgICAgICAgICAgb3B0aW9uYWwgYXJndW1lbnRzIGZvciB0b29sLiBFc2NhcGluZyBpcyBoYW5kbGVkIGJ5IHRoZSBsaWIuXG4gKiBAcGFyYW0gICAgIG9wdGlvbnMgICAgICAgICAgICBvcHRpb25hbCBleGVjIG9wdGlvbnMuICBTZWUgRXhlY09wdGlvbnNcbiAqIEByZXR1cm5zICAgUHJvbWlzZTxudW1iZXI+ICAgIGV4aXQgY29kZVxuICovXG5mdW5jdGlvbiBleGVjKGNvbW1hbmRMaW5lLCBhcmdzLCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgY29uc3QgY29tbWFuZEFyZ3MgPSB0ci5hcmdTdHJpbmdUb0FycmF5KGNvbW1hbmRMaW5lKTtcbiAgICAgICAgaWYgKGNvbW1hbmRBcmdzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBQYXJhbWV0ZXIgJ2NvbW1hbmRMaW5lJyBjYW5ub3QgYmUgbnVsbCBvciBlbXB0eS5gKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBQYXRoIHRvIHRvb2wgdG8gZXhlY3V0ZSBzaG91bGQgYmUgZmlyc3QgYXJnXG4gICAgICAgIGNvbnN0IHRvb2xQYXRoID0gY29tbWFuZEFyZ3NbMF07XG4gICAgICAgIGFyZ3MgPSBjb21tYW5kQXJncy5zbGljZSgxKS5jb25jYXQoYXJncyB8fCBbXSk7XG4gICAgICAgIGNvbnN0IHJ1bm5lciA9IG5ldyB0ci5Ub29sUnVubmVyKHRvb2xQYXRoLCBhcmdzLCBvcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIHJ1bm5lci5leGVjKCk7XG4gICAgfSk7XG59XG5leHBvcnRzLmV4ZWMgPSBleGVjO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZXhlYy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbnZhciBfX2F3YWl0ZXIgPSAodGhpcyAmJiB0aGlzLl9fYXdhaXRlcikgfHwgZnVuY3Rpb24gKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xuICAgIGZ1bmN0aW9uIGFkb3B0KHZhbHVlKSB7IHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFAgPyB2YWx1ZSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUodmFsdWUpOyB9KTsgfVxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XG4gICAgfSk7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuY29uc3Qgb3MgPSByZXF1aXJlKFwib3NcIik7XG5jb25zdCBldmVudHMgPSByZXF1aXJlKFwiZXZlbnRzXCIpO1xuY29uc3QgY2hpbGQgPSByZXF1aXJlKFwiY2hpbGRfcHJvY2Vzc1wiKTtcbmNvbnN0IHBhdGggPSByZXF1aXJlKFwicGF0aFwiKTtcbmNvbnN0IGlvID0gcmVxdWlyZShcIkBhY3Rpb25zL2lvXCIpO1xuY29uc3QgaW9VdGlsID0gcmVxdWlyZShcIkBhY3Rpb25zL2lvL2xpYi9pby11dGlsXCIpO1xuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L3VuYm91bmQtbWV0aG9kICovXG5jb25zdCBJU19XSU5ET1dTID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJztcbi8qXG4gKiBDbGFzcyBmb3IgcnVubmluZyBjb21tYW5kIGxpbmUgdG9vbHMuIEhhbmRsZXMgcXVvdGluZyBhbmQgYXJnIHBhcnNpbmcgaW4gYSBwbGF0Zm9ybSBhZ25vc3RpYyB3YXkuXG4gKi9cbmNsYXNzIFRvb2xSdW5uZXIgZXh0ZW5kcyBldmVudHMuRXZlbnRFbWl0dGVyIHtcbiAgICBjb25zdHJ1Y3Rvcih0b29sUGF0aCwgYXJncywgb3B0aW9ucykge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICBpZiAoIXRvb2xQYXRoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJQYXJhbWV0ZXIgJ3Rvb2xQYXRoJyBjYW5ub3QgYmUgbnVsbCBvciBlbXB0eS5cIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50b29sUGF0aCA9IHRvb2xQYXRoO1xuICAgICAgICB0aGlzLmFyZ3MgPSBhcmdzIHx8IFtdO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICAgIH1cbiAgICBfZGVidWcobWVzc2FnZSkge1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmxpc3RlbmVycyAmJiB0aGlzLm9wdGlvbnMubGlzdGVuZXJzLmRlYnVnKSB7XG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMubGlzdGVuZXJzLmRlYnVnKG1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgfVxuICAgIF9nZXRDb21tYW5kU3RyaW5nKG9wdGlvbnMsIG5vUHJlZml4KSB7XG4gICAgICAgIGNvbnN0IHRvb2xQYXRoID0gdGhpcy5fZ2V0U3Bhd25GaWxlTmFtZSgpO1xuICAgICAgICBjb25zdCBhcmdzID0gdGhpcy5fZ2V0U3Bhd25BcmdzKG9wdGlvbnMpO1xuICAgICAgICBsZXQgY21kID0gbm9QcmVmaXggPyAnJyA6ICdbY29tbWFuZF0nOyAvLyBvbWl0IHByZWZpeCB3aGVuIHBpcGVkIHRvIGEgc2Vjb25kIHRvb2xcbiAgICAgICAgaWYgKElTX1dJTkRPV1MpIHtcbiAgICAgICAgICAgIC8vIFdpbmRvd3MgKyBjbWQgZmlsZVxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzQ21kRmlsZSgpKSB7XG4gICAgICAgICAgICAgICAgY21kICs9IHRvb2xQYXRoO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYSBvZiBhcmdzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNtZCArPSBgICR7YX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFdpbmRvd3MgKyB2ZXJiYXRpbVxuICAgICAgICAgICAgZWxzZSBpZiAob3B0aW9ucy53aW5kb3dzVmVyYmF0aW1Bcmd1bWVudHMpIHtcbiAgICAgICAgICAgICAgICBjbWQgKz0gYFwiJHt0b29sUGF0aH1cImA7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBhIG9mIGFyZ3MpIHtcbiAgICAgICAgICAgICAgICAgICAgY21kICs9IGAgJHthfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gV2luZG93cyAocmVndWxhcilcbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNtZCArPSB0aGlzLl93aW5kb3dzUXVvdGVDbWRBcmcodG9vbFBhdGgpO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYSBvZiBhcmdzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNtZCArPSBgICR7dGhpcy5fd2luZG93c1F1b3RlQ21kQXJnKGEpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gT1NYL0xpbnV4IC0gdGhpcyBjYW4gbGlrZWx5IGJlIGltcHJvdmVkIHdpdGggc29tZSBmb3JtIG9mIHF1b3RpbmcuXG4gICAgICAgICAgICAvLyBjcmVhdGluZyBwcm9jZXNzZXMgb24gVW5peCBpcyBmdW5kYW1lbnRhbGx5IGRpZmZlcmVudCB0aGFuIFdpbmRvd3MuXG4gICAgICAgICAgICAvLyBvbiBVbml4LCBleGVjdnAoKSB0YWtlcyBhbiBhcmcgYXJyYXkuXG4gICAgICAgICAgICBjbWQgKz0gdG9vbFBhdGg7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGEgb2YgYXJncykge1xuICAgICAgICAgICAgICAgIGNtZCArPSBgICR7YX1gO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjbWQ7XG4gICAgfVxuICAgIF9wcm9jZXNzTGluZUJ1ZmZlcihkYXRhLCBzdHJCdWZmZXIsIG9uTGluZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IHMgPSBzdHJCdWZmZXIgKyBkYXRhLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICBsZXQgbiA9IHMuaW5kZXhPZihvcy5FT0wpO1xuICAgICAgICAgICAgd2hpbGUgKG4gPiAtMSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGxpbmUgPSBzLnN1YnN0cmluZygwLCBuKTtcbiAgICAgICAgICAgICAgICBvbkxpbmUobGluZSk7XG4gICAgICAgICAgICAgICAgLy8gdGhlIHJlc3Qgb2YgdGhlIHN0cmluZyAuLi5cbiAgICAgICAgICAgICAgICBzID0gcy5zdWJzdHJpbmcobiArIG9zLkVPTC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgIG4gPSBzLmluZGV4T2Yob3MuRU9MKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN0ckJ1ZmZlciA9IHM7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgLy8gc3RyZWFtaW5nIGxpbmVzIHRvIGNvbnNvbGUgaXMgYmVzdCBlZmZvcnQuICBEb24ndCBmYWlsIGEgYnVpbGQuXG4gICAgICAgICAgICB0aGlzLl9kZWJ1ZyhgZXJyb3IgcHJvY2Vzc2luZyBsaW5lLiBGYWlsZWQgd2l0aCBlcnJvciAke2Vycn1gKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBfZ2V0U3Bhd25GaWxlTmFtZSgpIHtcbiAgICAgICAgaWYgKElTX1dJTkRPV1MpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc0NtZEZpbGUoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwcm9jZXNzLmVudlsnQ09NU1BFQyddIHx8ICdjbWQuZXhlJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy50b29sUGF0aDtcbiAgICB9XG4gICAgX2dldFNwYXduQXJncyhvcHRpb25zKSB7XG4gICAgICAgIGlmIChJU19XSU5ET1dTKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5faXNDbWRGaWxlKCkpIHtcbiAgICAgICAgICAgICAgICBsZXQgYXJnbGluZSA9IGAvRCAvUyAvQyBcIiR7dGhpcy5fd2luZG93c1F1b3RlQ21kQXJnKHRoaXMudG9vbFBhdGgpfWA7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBhIG9mIHRoaXMuYXJncykge1xuICAgICAgICAgICAgICAgICAgICBhcmdsaW5lICs9ICcgJztcbiAgICAgICAgICAgICAgICAgICAgYXJnbGluZSArPSBvcHRpb25zLndpbmRvd3NWZXJiYXRpbUFyZ3VtZW50c1xuICAgICAgICAgICAgICAgICAgICAgICAgPyBhXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHRoaXMuX3dpbmRvd3NRdW90ZUNtZEFyZyhhKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXJnbGluZSArPSAnXCInO1xuICAgICAgICAgICAgICAgIHJldHVybiBbYXJnbGluZV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuYXJncztcbiAgICB9XG4gICAgX2VuZHNXaXRoKHN0ciwgZW5kKSB7XG4gICAgICAgIHJldHVybiBzdHIuZW5kc1dpdGgoZW5kKTtcbiAgICB9XG4gICAgX2lzQ21kRmlsZSgpIHtcbiAgICAgICAgY29uc3QgdXBwZXJUb29sUGF0aCA9IHRoaXMudG9vbFBhdGgudG9VcHBlckNhc2UoKTtcbiAgICAgICAgcmV0dXJuICh0aGlzLl9lbmRzV2l0aCh1cHBlclRvb2xQYXRoLCAnLkNNRCcpIHx8XG4gICAgICAgICAgICB0aGlzLl9lbmRzV2l0aCh1cHBlclRvb2xQYXRoLCAnLkJBVCcpKTtcbiAgICB9XG4gICAgX3dpbmRvd3NRdW90ZUNtZEFyZyhhcmcpIHtcbiAgICAgICAgLy8gZm9yIC5leGUsIGFwcGx5IHRoZSBub3JtYWwgcXVvdGluZyBydWxlcyB0aGF0IGxpYnV2IGFwcGxpZXNcbiAgICAgICAgaWYgKCF0aGlzLl9pc0NtZEZpbGUoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3V2UXVvdGVDbWRBcmcoYXJnKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBvdGhlcndpc2UgYXBwbHkgcXVvdGluZyBydWxlcyBzcGVjaWZpYyB0byB0aGUgY21kLmV4ZSBjb21tYW5kIGxpbmUgcGFyc2VyLlxuICAgICAgICAvLyB0aGUgbGlidXYgcnVsZXMgYXJlIGdlbmVyaWMgYW5kIGFyZSBub3QgZGVzaWduZWQgc3BlY2lmaWNhbGx5IGZvciBjbWQuZXhlXG4gICAgICAgIC8vIGNvbW1hbmQgbGluZSBwYXJzZXIuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIGZvciBhIGRldGFpbGVkIGRlc2NyaXB0aW9uIG9mIHRoZSBjbWQuZXhlIGNvbW1hbmQgbGluZSBwYXJzZXIsIHJlZmVyIHRvXG4gICAgICAgIC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDA5NDY5OS9ob3ctZG9lcy10aGUtd2luZG93cy1jb21tYW5kLWludGVycHJldGVyLWNtZC1leGUtcGFyc2Utc2NyaXB0cy83OTcwOTEyIzc5NzA5MTJcbiAgICAgICAgLy8gbmVlZCBxdW90ZXMgZm9yIGVtcHR5IGFyZ1xuICAgICAgICBpZiAoIWFyZykge1xuICAgICAgICAgICAgcmV0dXJuICdcIlwiJztcbiAgICAgICAgfVxuICAgICAgICAvLyBkZXRlcm1pbmUgd2hldGhlciB0aGUgYXJnIG5lZWRzIHRvIGJlIHF1b3RlZFxuICAgICAgICBjb25zdCBjbWRTcGVjaWFsQ2hhcnMgPSBbXG4gICAgICAgICAgICAnICcsXG4gICAgICAgICAgICAnXFx0JyxcbiAgICAgICAgICAgICcmJyxcbiAgICAgICAgICAgICcoJyxcbiAgICAgICAgICAgICcpJyxcbiAgICAgICAgICAgICdbJyxcbiAgICAgICAgICAgICddJyxcbiAgICAgICAgICAgICd7JyxcbiAgICAgICAgICAgICd9JyxcbiAgICAgICAgICAgICdeJyxcbiAgICAgICAgICAgICc9JyxcbiAgICAgICAgICAgICc7JyxcbiAgICAgICAgICAgICchJyxcbiAgICAgICAgICAgIFwiJ1wiLFxuICAgICAgICAgICAgJysnLFxuICAgICAgICAgICAgJywnLFxuICAgICAgICAgICAgJ2AnLFxuICAgICAgICAgICAgJ34nLFxuICAgICAgICAgICAgJ3wnLFxuICAgICAgICAgICAgJzwnLFxuICAgICAgICAgICAgJz4nLFxuICAgICAgICAgICAgJ1wiJ1xuICAgICAgICBdO1xuICAgICAgICBsZXQgbmVlZHNRdW90ZXMgPSBmYWxzZTtcbiAgICAgICAgZm9yIChjb25zdCBjaGFyIG9mIGFyZykge1xuICAgICAgICAgICAgaWYgKGNtZFNwZWNpYWxDaGFycy5zb21lKHggPT4geCA9PT0gY2hhcikpIHtcbiAgICAgICAgICAgICAgICBuZWVkc1F1b3RlcyA9IHRydWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gc2hvcnQtY2lyY3VpdCBpZiBxdW90ZXMgbm90IG5lZWRlZFxuICAgICAgICBpZiAoIW5lZWRzUXVvdGVzKSB7XG4gICAgICAgICAgICByZXR1cm4gYXJnO1xuICAgICAgICB9XG4gICAgICAgIC8vIHRoZSBmb2xsb3dpbmcgcXVvdGluZyBydWxlcyBhcmUgdmVyeSBzaW1pbGFyIHRvIHRoZSBydWxlcyB0aGF0IGJ5IGxpYnV2IGFwcGxpZXMuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIDEpIHdyYXAgdGhlIHN0cmluZyBpbiBxdW90ZXNcbiAgICAgICAgLy9cbiAgICAgICAgLy8gMikgZG91YmxlLXVwIHF1b3RlcyAtIGkuZS4gXCIgPT4gXCJcIlxuICAgICAgICAvL1xuICAgICAgICAvLyAgICB0aGlzIGlzIGRpZmZlcmVudCBmcm9tIHRoZSBsaWJ1diBxdW90aW5nIHJ1bGVzLiBsaWJ1diByZXBsYWNlcyBcIiB3aXRoIFxcXCIsIHdoaWNoIHVuZm9ydHVuYXRlbHlcbiAgICAgICAgLy8gICAgZG9lc24ndCB3b3JrIHdlbGwgd2l0aCBhIGNtZC5leGUgY29tbWFuZCBsaW5lLlxuICAgICAgICAvL1xuICAgICAgICAvLyAgICBub3RlLCByZXBsYWNpbmcgXCIgd2l0aCBcIlwiIGFsc28gd29ya3Mgd2VsbCBpZiB0aGUgYXJnIGlzIHBhc3NlZCB0byBhIGRvd25zdHJlYW0gLk5FVCBjb25zb2xlIGFwcC5cbiAgICAgICAgLy8gICAgZm9yIGV4YW1wbGUsIHRoZSBjb21tYW5kIGxpbmU6XG4gICAgICAgIC8vICAgICAgICAgIGZvby5leGUgXCJteWFyZzpcIlwibXkgdmFsXCJcIlwiXG4gICAgICAgIC8vICAgIGlzIHBhcnNlZCBieSBhIC5ORVQgY29uc29sZSBhcHAgaW50byBhbiBhcmcgYXJyYXk6XG4gICAgICAgIC8vICAgICAgICAgIFsgXCJteWFyZzpcXFwibXkgdmFsXFxcIlwiIF1cbiAgICAgICAgLy8gICAgd2hpY2ggaXMgdGhlIHNhbWUgZW5kIHJlc3VsdCB3aGVuIGFwcGx5aW5nIGxpYnV2IHF1b3RpbmcgcnVsZXMuIGFsdGhvdWdoIHRoZSBhY3R1YWxcbiAgICAgICAgLy8gICAgY29tbWFuZCBsaW5lIGZyb20gbGlidXYgcXVvdGluZyBydWxlcyB3b3VsZCBsb29rIGxpa2U6XG4gICAgICAgIC8vICAgICAgICAgIGZvby5leGUgXCJteWFyZzpcXFwibXkgdmFsXFxcIlwiXG4gICAgICAgIC8vXG4gICAgICAgIC8vIDMpIGRvdWJsZS11cCBzbGFzaGVzIHRoYXQgcHJlY2VkZSBhIHF1b3RlLFxuICAgICAgICAvLyAgICBlLmcuICBoZWxsbyBcXHdvcmxkICAgID0+IFwiaGVsbG8gXFx3b3JsZFwiXG4gICAgICAgIC8vICAgICAgICAgIGhlbGxvXFxcIndvcmxkICAgID0+IFwiaGVsbG9cXFxcXCJcIndvcmxkXCJcbiAgICAgICAgLy8gICAgICAgICAgaGVsbG9cXFxcXCJ3b3JsZCAgID0+IFwiaGVsbG9cXFxcXFxcXFwiXCJ3b3JsZFwiXG4gICAgICAgIC8vICAgICAgICAgIGhlbGxvIHdvcmxkXFwgICAgPT4gXCJoZWxsbyB3b3JsZFxcXFxcIlxuICAgICAgICAvL1xuICAgICAgICAvLyAgICB0ZWNobmljYWxseSB0aGlzIGlzIG5vdCByZXF1aXJlZCBmb3IgYSBjbWQuZXhlIGNvbW1hbmQgbGluZSwgb3IgdGhlIGJhdGNoIGFyZ3VtZW50IHBhcnNlci5cbiAgICAgICAgLy8gICAgdGhlIHJlYXNvbnMgZm9yIGluY2x1ZGluZyB0aGlzIGFzIGEgLmNtZCBxdW90aW5nIHJ1bGUgYXJlOlxuICAgICAgICAvL1xuICAgICAgICAvLyAgICBhKSB0aGlzIGlzIG9wdGltaXplZCBmb3IgdGhlIHNjZW5hcmlvIHdoZXJlIHRoZSBhcmd1bWVudCBpcyBwYXNzZWQgZnJvbSB0aGUgLmNtZCBmaWxlIHRvIGFuXG4gICAgICAgIC8vICAgICAgIGV4dGVybmFsIHByb2dyYW0uIG1hbnkgcHJvZ3JhbXMgKGUuZy4gLk5FVCBjb25zb2xlIGFwcHMpIHJlbHkgb24gdGhlIHNsYXNoLWRvdWJsaW5nIHJ1bGUuXG4gICAgICAgIC8vXG4gICAgICAgIC8vICAgIGIpIGl0J3Mgd2hhdCB3ZSd2ZSBiZWVuIGRvaW5nIHByZXZpb3VzbHkgKGJ5IGRlZmVycmluZyB0byBub2RlIGRlZmF1bHQgYmVoYXZpb3IpIGFuZCB3ZVxuICAgICAgICAvLyAgICAgICBoYXZlbid0IGhlYXJkIGFueSBjb21wbGFpbnRzIGFib3V0IHRoYXQgYXNwZWN0LlxuICAgICAgICAvL1xuICAgICAgICAvLyBub3RlLCBhIHdlYWtuZXNzIG9mIHRoZSBxdW90aW5nIHJ1bGVzIGNob3NlbiBoZXJlLCBpcyB0aGF0ICUgaXMgbm90IGVzY2FwZWQuIGluIGZhY3QsICUgY2Fubm90IGJlXG4gICAgICAgIC8vIGVzY2FwZWQgd2hlbiB1c2VkIG9uIHRoZSBjb21tYW5kIGxpbmUgZGlyZWN0bHkgLSBldmVuIHRob3VnaCB3aXRoaW4gYSAuY21kIGZpbGUgJSBjYW4gYmUgZXNjYXBlZFxuICAgICAgICAvLyBieSB1c2luZyAlJS5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gdGhlIHNhdmluZyBncmFjZSBpcywgb24gdGhlIGNvbW1hbmQgbGluZSwgJXZhciUgaXMgbGVmdCBhcy1pcyBpZiB2YXIgaXMgbm90IGRlZmluZWQuIHRoaXMgY29udHJhc3RzXG4gICAgICAgIC8vIHRoZSBsaW5lIHBhcnNpbmcgcnVsZXMgd2l0aGluIGEgLmNtZCBmaWxlLCB3aGVyZSBpZiB2YXIgaXMgbm90IGRlZmluZWQgaXQgaXMgcmVwbGFjZWQgd2l0aCBub3RoaW5nLlxuICAgICAgICAvL1xuICAgICAgICAvLyBvbmUgb3B0aW9uIHRoYXQgd2FzIGV4cGxvcmVkIHdhcyByZXBsYWNpbmcgJSB3aXRoIF4lIC0gaS5lLiAldmFyJSA9PiBeJXZhcl4lLiB0aGlzIGhhY2sgd291bGRcbiAgICAgICAgLy8gb2Z0ZW4gd29yaywgc2luY2UgaXQgaXMgdW5saWtlbHkgdGhhdCB2YXJeIHdvdWxkIGV4aXN0LCBhbmQgdGhlIF4gY2hhcmFjdGVyIGlzIHJlbW92ZWQgd2hlbiB0aGVcbiAgICAgICAgLy8gdmFyaWFibGUgaXMgdXNlZC4gdGhlIHByb2JsZW0sIGhvd2V2ZXIsIGlzIHRoYXQgXiBpcyBub3QgcmVtb3ZlZCB3aGVuICUqIGlzIHVzZWQgdG8gcGFzcyB0aGUgYXJnc1xuICAgICAgICAvLyB0byBhbiBleHRlcm5hbCBwcm9ncmFtLlxuICAgICAgICAvL1xuICAgICAgICAvLyBhbiB1bmV4cGxvcmVkIHBvdGVudGlhbCBzb2x1dGlvbiBmb3IgdGhlICUgZXNjYXBpbmcgcHJvYmxlbSwgaXMgdG8gY3JlYXRlIGEgd3JhcHBlciAuY21kIGZpbGUuXG4gICAgICAgIC8vICUgY2FuIGJlIGVzY2FwZWQgd2l0aGluIGEgLmNtZCBmaWxlLlxuICAgICAgICBsZXQgcmV2ZXJzZSA9ICdcIic7XG4gICAgICAgIGxldCBxdW90ZUhpdCA9IHRydWU7XG4gICAgICAgIGZvciAobGV0IGkgPSBhcmcubGVuZ3RoOyBpID4gMDsgaS0tKSB7XG4gICAgICAgICAgICAvLyB3YWxrIHRoZSBzdHJpbmcgaW4gcmV2ZXJzZVxuICAgICAgICAgICAgcmV2ZXJzZSArPSBhcmdbaSAtIDFdO1xuICAgICAgICAgICAgaWYgKHF1b3RlSGl0ICYmIGFyZ1tpIC0gMV0gPT09ICdcXFxcJykge1xuICAgICAgICAgICAgICAgIHJldmVyc2UgKz0gJ1xcXFwnOyAvLyBkb3VibGUgdGhlIHNsYXNoXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChhcmdbaSAtIDFdID09PSAnXCInKSB7XG4gICAgICAgICAgICAgICAgcXVvdGVIaXQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHJldmVyc2UgKz0gJ1wiJzsgLy8gZG91YmxlIHRoZSBxdW90ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcXVvdGVIaXQgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXZlcnNlICs9ICdcIic7XG4gICAgICAgIHJldHVybiByZXZlcnNlXG4gICAgICAgICAgICAuc3BsaXQoJycpXG4gICAgICAgICAgICAucmV2ZXJzZSgpXG4gICAgICAgICAgICAuam9pbignJyk7XG4gICAgfVxuICAgIF91dlF1b3RlQ21kQXJnKGFyZykge1xuICAgICAgICAvLyBUb29sIHJ1bm5lciB3cmFwcyBjaGlsZF9wcm9jZXNzLnNwYXduKCkgYW5kIG5lZWRzIHRvIGFwcGx5IHRoZSBzYW1lIHF1b3RpbmcgYXNcbiAgICAgICAgLy8gTm9kZSBpbiBjZXJ0YWluIGNhc2VzIHdoZXJlIHRoZSB1bmRvY3VtZW50ZWQgc3Bhd24gb3B0aW9uIHdpbmRvd3NWZXJiYXRpbUFyZ3VtZW50c1xuICAgICAgICAvLyBpcyB1c2VkLlxuICAgICAgICAvL1xuICAgICAgICAvLyBTaW5jZSB0aGlzIGZ1bmN0aW9uIGlzIGEgcG9ydCBvZiBxdW90ZV9jbWRfYXJnIGZyb20gTm9kZSA0LnggKHRlY2huaWNhbGx5LCBsaWIgVVYsXG4gICAgICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vbm9kZWpzL25vZGUvYmxvYi92NC54L2RlcHMvdXYvc3JjL3dpbi9wcm9jZXNzLmMgZm9yIGRldGFpbHMpLFxuICAgICAgICAvLyBwYXN0aW5nIGNvcHlyaWdodCBub3RpY2UgZnJvbSBOb2RlIHdpdGhpbiB0aGlzIGZ1bmN0aW9uOlxuICAgICAgICAvL1xuICAgICAgICAvLyAgICAgIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICAgICAgICAvL1xuICAgICAgICAvLyAgICAgIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiAgICAgICAgLy8gICAgICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuICAgICAgICAvLyAgICAgIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4gICAgICAgIC8vICAgICAgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4gICAgICAgIC8vICAgICAgc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAgICAgICAgLy8gICAgICBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICAgICAgICAvL1xuICAgICAgICAvLyAgICAgIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4gICAgICAgIC8vICAgICAgYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gICAgICAgIC8vXG4gICAgICAgIC8vICAgICAgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICAgICAgICAvLyAgICAgIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuICAgICAgICAvLyAgICAgIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuICAgICAgICAvLyAgICAgIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAgICAgICAgLy8gICAgICBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuICAgICAgICAvLyAgICAgIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1NcbiAgICAgICAgLy8gICAgICBJTiBUSEUgU09GVFdBUkUuXG4gICAgICAgIGlmICghYXJnKSB7XG4gICAgICAgICAgICAvLyBOZWVkIGRvdWJsZSBxdW90YXRpb24gZm9yIGVtcHR5IGFyZ3VtZW50XG4gICAgICAgICAgICByZXR1cm4gJ1wiXCInO1xuICAgICAgICB9XG4gICAgICAgIGlmICghYXJnLmluY2x1ZGVzKCcgJykgJiYgIWFyZy5pbmNsdWRlcygnXFx0JykgJiYgIWFyZy5pbmNsdWRlcygnXCInKSkge1xuICAgICAgICAgICAgLy8gTm8gcXVvdGF0aW9uIG5lZWRlZFxuICAgICAgICAgICAgcmV0dXJuIGFyZztcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWFyZy5pbmNsdWRlcygnXCInKSAmJiAhYXJnLmluY2x1ZGVzKCdcXFxcJykpIHtcbiAgICAgICAgICAgIC8vIE5vIGVtYmVkZGVkIGRvdWJsZSBxdW90ZXMgb3IgYmFja3NsYXNoZXMsIHNvIEkgY2FuIGp1c3Qgd3JhcFxuICAgICAgICAgICAgLy8gcXVvdGUgbWFya3MgYXJvdW5kIHRoZSB3aG9sZSB0aGluZy5cbiAgICAgICAgICAgIHJldHVybiBgXCIke2FyZ31cImA7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRXhwZWN0ZWQgaW5wdXQvb3V0cHV0OlxuICAgICAgICAvLyAgIGlucHV0IDogaGVsbG9cIndvcmxkXG4gICAgICAgIC8vICAgb3V0cHV0OiBcImhlbGxvXFxcIndvcmxkXCJcbiAgICAgICAgLy8gICBpbnB1dCA6IGhlbGxvXCJcIndvcmxkXG4gICAgICAgIC8vICAgb3V0cHV0OiBcImhlbGxvXFxcIlxcXCJ3b3JsZFwiXG4gICAgICAgIC8vICAgaW5wdXQgOiBoZWxsb1xcd29ybGRcbiAgICAgICAgLy8gICBvdXRwdXQ6IGhlbGxvXFx3b3JsZFxuICAgICAgICAvLyAgIGlucHV0IDogaGVsbG9cXFxcd29ybGRcbiAgICAgICAgLy8gICBvdXRwdXQ6IGhlbGxvXFxcXHdvcmxkXG4gICAgICAgIC8vICAgaW5wdXQgOiBoZWxsb1xcXCJ3b3JsZFxuICAgICAgICAvLyAgIG91dHB1dDogXCJoZWxsb1xcXFxcXFwid29ybGRcIlxuICAgICAgICAvLyAgIGlucHV0IDogaGVsbG9cXFxcXCJ3b3JsZFxuICAgICAgICAvLyAgIG91dHB1dDogXCJoZWxsb1xcXFxcXFxcXFxcIndvcmxkXCJcbiAgICAgICAgLy8gICBpbnB1dCA6IGhlbGxvIHdvcmxkXFxcbiAgICAgICAgLy8gICBvdXRwdXQ6IFwiaGVsbG8gd29ybGRcXFxcXCIgLSBub3RlIHRoZSBjb21tZW50IGluIGxpYnV2IGFjdHVhbGx5IHJlYWRzIFwiaGVsbG8gd29ybGRcXFwiXG4gICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXQgaXQgYXBwZWFycyB0aGUgY29tbWVudCBpcyB3cm9uZywgaXQgc2hvdWxkIGJlIFwiaGVsbG8gd29ybGRcXFxcXCJcbiAgICAgICAgbGV0IHJldmVyc2UgPSAnXCInO1xuICAgICAgICBsZXQgcXVvdGVIaXQgPSB0cnVlO1xuICAgICAgICBmb3IgKGxldCBpID0gYXJnLmxlbmd0aDsgaSA+IDA7IGktLSkge1xuICAgICAgICAgICAgLy8gd2FsayB0aGUgc3RyaW5nIGluIHJldmVyc2VcbiAgICAgICAgICAgIHJldmVyc2UgKz0gYXJnW2kgLSAxXTtcbiAgICAgICAgICAgIGlmIChxdW90ZUhpdCAmJiBhcmdbaSAtIDFdID09PSAnXFxcXCcpIHtcbiAgICAgICAgICAgICAgICByZXZlcnNlICs9ICdcXFxcJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGFyZ1tpIC0gMV0gPT09ICdcIicpIHtcbiAgICAgICAgICAgICAgICBxdW90ZUhpdCA9IHRydWU7XG4gICAgICAgICAgICAgICAgcmV2ZXJzZSArPSAnXFxcXCc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBxdW90ZUhpdCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldmVyc2UgKz0gJ1wiJztcbiAgICAgICAgcmV0dXJuIHJldmVyc2VcbiAgICAgICAgICAgIC5zcGxpdCgnJylcbiAgICAgICAgICAgIC5yZXZlcnNlKClcbiAgICAgICAgICAgIC5qb2luKCcnKTtcbiAgICB9XG4gICAgX2Nsb25lRXhlY09wdGlvbnMob3B0aW9ucykge1xuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0ge1xuICAgICAgICAgICAgY3dkOiBvcHRpb25zLmN3ZCB8fCBwcm9jZXNzLmN3ZCgpLFxuICAgICAgICAgICAgZW52OiBvcHRpb25zLmVudiB8fCBwcm9jZXNzLmVudixcbiAgICAgICAgICAgIHNpbGVudDogb3B0aW9ucy5zaWxlbnQgfHwgZmFsc2UsXG4gICAgICAgICAgICB3aW5kb3dzVmVyYmF0aW1Bcmd1bWVudHM6IG9wdGlvbnMud2luZG93c1ZlcmJhdGltQXJndW1lbnRzIHx8IGZhbHNlLFxuICAgICAgICAgICAgZmFpbE9uU3RkRXJyOiBvcHRpb25zLmZhaWxPblN0ZEVyciB8fCBmYWxzZSxcbiAgICAgICAgICAgIGlnbm9yZVJldHVybkNvZGU6IG9wdGlvbnMuaWdub3JlUmV0dXJuQ29kZSB8fCBmYWxzZSxcbiAgICAgICAgICAgIGRlbGF5OiBvcHRpb25zLmRlbGF5IHx8IDEwMDAwXG4gICAgICAgIH07XG4gICAgICAgIHJlc3VsdC5vdXRTdHJlYW0gPSBvcHRpb25zLm91dFN0cmVhbSB8fCBwcm9jZXNzLnN0ZG91dDtcbiAgICAgICAgcmVzdWx0LmVyclN0cmVhbSA9IG9wdGlvbnMuZXJyU3RyZWFtIHx8IHByb2Nlc3Muc3RkZXJyO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICBfZ2V0U3Bhd25PcHRpb25zKG9wdGlvbnMsIHRvb2xQYXRoKSB7XG4gICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICAgICAgICBjb25zdCByZXN1bHQgPSB7fTtcbiAgICAgICAgcmVzdWx0LmN3ZCA9IG9wdGlvbnMuY3dkO1xuICAgICAgICByZXN1bHQuZW52ID0gb3B0aW9ucy5lbnY7XG4gICAgICAgIHJlc3VsdFsnd2luZG93c1ZlcmJhdGltQXJndW1lbnRzJ10gPVxuICAgICAgICAgICAgb3B0aW9ucy53aW5kb3dzVmVyYmF0aW1Bcmd1bWVudHMgfHwgdGhpcy5faXNDbWRGaWxlKCk7XG4gICAgICAgIGlmIChvcHRpb25zLndpbmRvd3NWZXJiYXRpbUFyZ3VtZW50cykge1xuICAgICAgICAgICAgcmVzdWx0LmFyZ3YwID0gYFwiJHt0b29sUGF0aH1cImA7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRXhlYyBhIHRvb2wuXG4gICAgICogT3V0cHV0IHdpbGwgYmUgc3RyZWFtZWQgdG8gdGhlIGxpdmUgY29uc29sZS5cbiAgICAgKiBSZXR1cm5zIHByb21pc2Ugd2l0aCByZXR1cm4gY29kZVxuICAgICAqXG4gICAgICogQHBhcmFtICAgICB0b29sICAgICBwYXRoIHRvIHRvb2wgdG8gZXhlY1xuICAgICAqIEBwYXJhbSAgICAgb3B0aW9ucyAgb3B0aW9uYWwgZXhlYyBvcHRpb25zLiAgU2VlIEV4ZWNPcHRpb25zXG4gICAgICogQHJldHVybnMgICBudW1iZXJcbiAgICAgKi9cbiAgICBleGVjKCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgLy8gcm9vdCB0aGUgdG9vbCBwYXRoIGlmIGl0IGlzIHVucm9vdGVkIGFuZCBjb250YWlucyByZWxhdGl2ZSBwYXRoaW5nXG4gICAgICAgICAgICBpZiAoIWlvVXRpbC5pc1Jvb3RlZCh0aGlzLnRvb2xQYXRoKSAmJlxuICAgICAgICAgICAgICAgICh0aGlzLnRvb2xQYXRoLmluY2x1ZGVzKCcvJykgfHxcbiAgICAgICAgICAgICAgICAgICAgKElTX1dJTkRPV1MgJiYgdGhpcy50b29sUGF0aC5pbmNsdWRlcygnXFxcXCcpKSkpIHtcbiAgICAgICAgICAgICAgICAvLyBwcmVmZXIgb3B0aW9ucy5jd2QgaWYgaXQgaXMgc3BlY2lmaWVkLCBob3dldmVyIG9wdGlvbnMuY3dkIG1heSBhbHNvIG5lZWQgdG8gYmUgcm9vdGVkXG4gICAgICAgICAgICAgICAgdGhpcy50b29sUGF0aCA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCB0aGlzLm9wdGlvbnMuY3dkIHx8IHByb2Nlc3MuY3dkKCksIHRoaXMudG9vbFBhdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gaWYgdGhlIHRvb2wgaXMgb25seSBhIGZpbGUgbmFtZSwgdGhlbiByZXNvbHZlIGl0IGZyb20gdGhlIFBBVEhcbiAgICAgICAgICAgIC8vIG90aGVyd2lzZSB2ZXJpZnkgaXQgZXhpc3RzIChhZGQgZXh0ZW5zaW9uIG9uIFdpbmRvd3MgaWYgbmVjZXNzYXJ5KVxuICAgICAgICAgICAgdGhpcy50b29sUGF0aCA9IHlpZWxkIGlvLndoaWNoKHRoaXMudG9vbFBhdGgsIHRydWUpO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9kZWJ1ZyhgZXhlYyB0b29sOiAke3RoaXMudG9vbFBhdGh9YCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fZGVidWcoJ2FyZ3VtZW50czonKTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGFyZyBvZiB0aGlzLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZGVidWcoYCAgICR7YXJnfWApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zTm9uTnVsbCA9IHRoaXMuX2Nsb25lRXhlY09wdGlvbnModGhpcy5vcHRpb25zKTtcbiAgICAgICAgICAgICAgICBpZiAoIW9wdGlvbnNOb25OdWxsLnNpbGVudCAmJiBvcHRpb25zTm9uTnVsbC5vdXRTdHJlYW0pIHtcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9uc05vbk51bGwub3V0U3RyZWFtLndyaXRlKHRoaXMuX2dldENvbW1hbmRTdHJpbmcob3B0aW9uc05vbk51bGwpICsgb3MuRU9MKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RhdGUgPSBuZXcgRXhlY1N0YXRlKG9wdGlvbnNOb25OdWxsLCB0aGlzLnRvb2xQYXRoKTtcbiAgICAgICAgICAgICAgICBzdGF0ZS5vbignZGVidWcnLCAobWVzc2FnZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9kZWJ1ZyhtZXNzYWdlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjb25zdCBmaWxlTmFtZSA9IHRoaXMuX2dldFNwYXduRmlsZU5hbWUoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjcCA9IGNoaWxkLnNwYXduKGZpbGVOYW1lLCB0aGlzLl9nZXRTcGF3bkFyZ3Mob3B0aW9uc05vbk51bGwpLCB0aGlzLl9nZXRTcGF3bk9wdGlvbnModGhpcy5vcHRpb25zLCBmaWxlTmFtZSkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0ZGJ1ZmZlciA9ICcnO1xuICAgICAgICAgICAgICAgIGlmIChjcC5zdGRvdXQpIHtcbiAgICAgICAgICAgICAgICAgICAgY3Auc3Rkb3V0Lm9uKCdkYXRhJywgKGRhdGEpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMubGlzdGVuZXJzICYmIHRoaXMub3B0aW9ucy5saXN0ZW5lcnMuc3Rkb3V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLmxpc3RlbmVycy5zdGRvdXQoZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW9wdGlvbnNOb25OdWxsLnNpbGVudCAmJiBvcHRpb25zTm9uTnVsbC5vdXRTdHJlYW0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zTm9uTnVsbC5vdXRTdHJlYW0ud3JpdGUoZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9wcm9jZXNzTGluZUJ1ZmZlcihkYXRhLCBzdGRidWZmZXIsIChsaW5lKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5saXN0ZW5lcnMgJiYgdGhpcy5vcHRpb25zLmxpc3RlbmVycy5zdGRsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5saXN0ZW5lcnMuc3RkbGluZShsaW5lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGVycmJ1ZmZlciA9ICcnO1xuICAgICAgICAgICAgICAgIGlmIChjcC5zdGRlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgY3Auc3RkZXJyLm9uKCdkYXRhJywgKGRhdGEpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlLnByb2Nlc3NTdGRlcnIgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5saXN0ZW5lcnMgJiYgdGhpcy5vcHRpb25zLmxpc3RlbmVycy5zdGRlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMubGlzdGVuZXJzLnN0ZGVycihkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghb3B0aW9uc05vbk51bGwuc2lsZW50ICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uc05vbk51bGwuZXJyU3RyZWFtICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uc05vbk51bGwub3V0U3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcyA9IG9wdGlvbnNOb25OdWxsLmZhaWxPblN0ZEVyclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IG9wdGlvbnNOb25OdWxsLmVyclN0cmVhbVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG9wdGlvbnNOb25OdWxsLm91dFN0cmVhbTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzLndyaXRlKGRhdGEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcHJvY2Vzc0xpbmVCdWZmZXIoZGF0YSwgZXJyYnVmZmVyLCAobGluZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMubGlzdGVuZXJzICYmIHRoaXMub3B0aW9ucy5saXN0ZW5lcnMuZXJybGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMubGlzdGVuZXJzLmVycmxpbmUobGluZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjcC5vbignZXJyb3InLCAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLnByb2Nlc3NFcnJvciA9IGVyci5tZXNzYWdlO1xuICAgICAgICAgICAgICAgICAgICBzdGF0ZS5wcm9jZXNzRXhpdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUucHJvY2Vzc0Nsb3NlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLkNoZWNrQ29tcGxldGUoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjcC5vbignZXhpdCcsIChjb2RlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLnByb2Nlc3NFeGl0Q29kZSA9IGNvZGU7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLnByb2Nlc3NFeGl0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9kZWJ1ZyhgRXhpdCBjb2RlICR7Y29kZX0gcmVjZWl2ZWQgZnJvbSB0b29sICcke3RoaXMudG9vbFBhdGh9J2ApO1xuICAgICAgICAgICAgICAgICAgICBzdGF0ZS5DaGVja0NvbXBsZXRlKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY3Aub24oJ2Nsb3NlJywgKGNvZGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUucHJvY2Vzc0V4aXRDb2RlID0gY29kZTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUucHJvY2Vzc0V4aXRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLnByb2Nlc3NDbG9zZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9kZWJ1ZyhgU1RESU8gc3RyZWFtcyBoYXZlIGNsb3NlZCBmb3IgdG9vbCAnJHt0aGlzLnRvb2xQYXRofSdgKTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUuQ2hlY2tDb21wbGV0ZSgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHN0YXRlLm9uKCdkb25lJywgKGVycm9yLCBleGl0Q29kZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RkYnVmZmVyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdCgnc3RkbGluZScsIHN0ZGJ1ZmZlcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycmJ1ZmZlci5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2VycmxpbmUnLCBlcnJidWZmZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNwLnJlbW92ZUFsbExpc3RlbmVycygpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGV4aXRDb2RlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmV4cG9ydHMuVG9vbFJ1bm5lciA9IFRvb2xSdW5uZXI7XG4vKipcbiAqIENvbnZlcnQgYW4gYXJnIHN0cmluZyB0byBhbiBhcnJheSBvZiBhcmdzLiBIYW5kbGVzIGVzY2FwaW5nXG4gKlxuICogQHBhcmFtICAgIGFyZ1N0cmluZyAgIHN0cmluZyBvZiBhcmd1bWVudHNcbiAqIEByZXR1cm5zICBzdHJpbmdbXSAgICBhcnJheSBvZiBhcmd1bWVudHNcbiAqL1xuZnVuY3Rpb24gYXJnU3RyaW5nVG9BcnJheShhcmdTdHJpbmcpIHtcbiAgICBjb25zdCBhcmdzID0gW107XG4gICAgbGV0IGluUXVvdGVzID0gZmFsc2U7XG4gICAgbGV0IGVzY2FwZWQgPSBmYWxzZTtcbiAgICBsZXQgYXJnID0gJyc7XG4gICAgZnVuY3Rpb24gYXBwZW5kKGMpIHtcbiAgICAgICAgLy8gd2Ugb25seSBlc2NhcGUgZG91YmxlIHF1b3Rlcy5cbiAgICAgICAgaWYgKGVzY2FwZWQgJiYgYyAhPT0gJ1wiJykge1xuICAgICAgICAgICAgYXJnICs9ICdcXFxcJztcbiAgICAgICAgfVxuICAgICAgICBhcmcgKz0gYztcbiAgICAgICAgZXNjYXBlZCA9IGZhbHNlO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyZ1N0cmluZy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBjID0gYXJnU3RyaW5nLmNoYXJBdChpKTtcbiAgICAgICAgaWYgKGMgPT09ICdcIicpIHtcbiAgICAgICAgICAgIGlmICghZXNjYXBlZCkge1xuICAgICAgICAgICAgICAgIGluUXVvdGVzID0gIWluUXVvdGVzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXBwZW5kKGMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGMgPT09ICdcXFxcJyAmJiBlc2NhcGVkKSB7XG4gICAgICAgICAgICBhcHBlbmQoYyk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYyA9PT0gJ1xcXFwnICYmIGluUXVvdGVzKSB7XG4gICAgICAgICAgICBlc2NhcGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjID09PSAnICcgJiYgIWluUXVvdGVzKSB7XG4gICAgICAgICAgICBpZiAoYXJnLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBhcmdzLnB1c2goYXJnKTtcbiAgICAgICAgICAgICAgICBhcmcgPSAnJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGFwcGVuZChjKTtcbiAgICB9XG4gICAgaWYgKGFyZy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGFyZ3MucHVzaChhcmcudHJpbSgpKTtcbiAgICB9XG4gICAgcmV0dXJuIGFyZ3M7XG59XG5leHBvcnRzLmFyZ1N0cmluZ1RvQXJyYXkgPSBhcmdTdHJpbmdUb0FycmF5O1xuY2xhc3MgRXhlY1N0YXRlIGV4dGVuZHMgZXZlbnRzLkV2ZW50RW1pdHRlciB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucywgdG9vbFBhdGgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5wcm9jZXNzQ2xvc2VkID0gZmFsc2U7IC8vIHRyYWNrcyB3aGV0aGVyIHRoZSBwcm9jZXNzIGhhcyBleGl0ZWQgYW5kIHN0ZGlvIGlzIGNsb3NlZFxuICAgICAgICB0aGlzLnByb2Nlc3NFcnJvciA9ICcnO1xuICAgICAgICB0aGlzLnByb2Nlc3NFeGl0Q29kZSA9IDA7XG4gICAgICAgIHRoaXMucHJvY2Vzc0V4aXRlZCA9IGZhbHNlOyAvLyB0cmFja3Mgd2hldGhlciB0aGUgcHJvY2VzcyBoYXMgZXhpdGVkXG4gICAgICAgIHRoaXMucHJvY2Vzc1N0ZGVyciA9IGZhbHNlOyAvLyB0cmFja3Mgd2hldGhlciBzdGRlcnIgd2FzIHdyaXR0ZW4gdG9cbiAgICAgICAgdGhpcy5kZWxheSA9IDEwMDAwOyAvLyAxMCBzZWNvbmRzXG4gICAgICAgIHRoaXMuZG9uZSA9IGZhbHNlO1xuICAgICAgICB0aGlzLnRpbWVvdXQgPSBudWxsO1xuICAgICAgICBpZiAoIXRvb2xQYXRoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Rvb2xQYXRoIG11c3Qgbm90IGJlIGVtcHR5Jyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICAgICAgdGhpcy50b29sUGF0aCA9IHRvb2xQYXRoO1xuICAgICAgICBpZiAob3B0aW9ucy5kZWxheSkge1xuICAgICAgICAgICAgdGhpcy5kZWxheSA9IG9wdGlvbnMuZGVsYXk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgQ2hlY2tDb21wbGV0ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuZG9uZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnByb2Nlc3NDbG9zZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3NldFJlc3VsdCgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMucHJvY2Vzc0V4aXRlZCkge1xuICAgICAgICAgICAgdGhpcy50aW1lb3V0ID0gc2V0VGltZW91dChFeGVjU3RhdGUuSGFuZGxlVGltZW91dCwgdGhpcy5kZWxheSwgdGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgX2RlYnVnKG1lc3NhZ2UpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdkZWJ1ZycsIG1lc3NhZ2UpO1xuICAgIH1cbiAgICBfc2V0UmVzdWx0KCkge1xuICAgICAgICAvLyBkZXRlcm1pbmUgd2hldGhlciB0aGVyZSBpcyBhbiBlcnJvclxuICAgICAgICBsZXQgZXJyb3I7XG4gICAgICAgIGlmICh0aGlzLnByb2Nlc3NFeGl0ZWQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb2Nlc3NFcnJvcikge1xuICAgICAgICAgICAgICAgIGVycm9yID0gbmV3IEVycm9yKGBUaGVyZSB3YXMgYW4gZXJyb3Igd2hlbiBhdHRlbXB0aW5nIHRvIGV4ZWN1dGUgdGhlIHByb2Nlc3MgJyR7dGhpcy50b29sUGF0aH0nLiBUaGlzIG1heSBpbmRpY2F0ZSB0aGUgcHJvY2VzcyBmYWlsZWQgdG8gc3RhcnQuIEVycm9yOiAke3RoaXMucHJvY2Vzc0Vycm9yfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5wcm9jZXNzRXhpdENvZGUgIT09IDAgJiYgIXRoaXMub3B0aW9ucy5pZ25vcmVSZXR1cm5Db2RlKSB7XG4gICAgICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IoYFRoZSBwcm9jZXNzICcke3RoaXMudG9vbFBhdGh9JyBmYWlsZWQgd2l0aCBleGl0IGNvZGUgJHt0aGlzLnByb2Nlc3NFeGl0Q29kZX1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMucHJvY2Vzc1N0ZGVyciAmJiB0aGlzLm9wdGlvbnMuZmFpbE9uU3RkRXJyKSB7XG4gICAgICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IoYFRoZSBwcm9jZXNzICcke3RoaXMudG9vbFBhdGh9JyBmYWlsZWQgYmVjYXVzZSBvbmUgb3IgbW9yZSBsaW5lcyB3ZXJlIHdyaXR0ZW4gdG8gdGhlIFNUREVSUiBzdHJlYW1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBjbGVhciB0aGUgdGltZW91dFxuICAgICAgICBpZiAodGhpcy50aW1lb3V0KSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lb3V0KTtcbiAgICAgICAgICAgIHRoaXMudGltZW91dCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kb25lID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5lbWl0KCdkb25lJywgZXJyb3IsIHRoaXMucHJvY2Vzc0V4aXRDb2RlKTtcbiAgICB9XG4gICAgc3RhdGljIEhhbmRsZVRpbWVvdXQoc3RhdGUpIHtcbiAgICAgICAgaWYgKHN0YXRlLmRvbmUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXN0YXRlLnByb2Nlc3NDbG9zZWQgJiYgc3RhdGUucHJvY2Vzc0V4aXRlZCkge1xuICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9IGBUaGUgU1RESU8gc3RyZWFtcyBkaWQgbm90IGNsb3NlIHdpdGhpbiAke3N0YXRlLmRlbGF5IC9cbiAgICAgICAgICAgICAgICAxMDAwfSBzZWNvbmRzIG9mIHRoZSBleGl0IGV2ZW50IGZyb20gcHJvY2VzcyAnJHtzdGF0ZS50b29sUGF0aH0nLiBUaGlzIG1heSBpbmRpY2F0ZSBhIGNoaWxkIHByb2Nlc3MgaW5oZXJpdGVkIHRoZSBTVERJTyBzdHJlYW1zIGFuZCBoYXMgbm90IHlldCBleGl0ZWQuYDtcbiAgICAgICAgICAgIHN0YXRlLl9kZWJ1ZyhtZXNzYWdlKTtcbiAgICAgICAgfVxuICAgICAgICBzdGF0ZS5fc2V0UmVzdWx0KCk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dG9vbHJ1bm5lci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNvbnN0IHVybCA9IHJlcXVpcmUoXCJ1cmxcIik7XG5jb25zdCBodHRwID0gcmVxdWlyZShcImh0dHBcIik7XG5jb25zdCBodHRwcyA9IHJlcXVpcmUoXCJodHRwc1wiKTtcbmNvbnN0IHBtID0gcmVxdWlyZShcIi4vcHJveHlcIik7XG5sZXQgdHVubmVsO1xudmFyIEh0dHBDb2RlcztcbihmdW5jdGlvbiAoSHR0cENvZGVzKSB7XG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIk9LXCJdID0gMjAwXSA9IFwiT0tcIjtcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiTXVsdGlwbGVDaG9pY2VzXCJdID0gMzAwXSA9IFwiTXVsdGlwbGVDaG9pY2VzXCI7XG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIk1vdmVkUGVybWFuZW50bHlcIl0gPSAzMDFdID0gXCJNb3ZlZFBlcm1hbmVudGx5XCI7XG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlJlc291cmNlTW92ZWRcIl0gPSAzMDJdID0gXCJSZXNvdXJjZU1vdmVkXCI7XG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlNlZU90aGVyXCJdID0gMzAzXSA9IFwiU2VlT3RoZXJcIjtcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiTm90TW9kaWZpZWRcIl0gPSAzMDRdID0gXCJOb3RNb2RpZmllZFwiO1xuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJVc2VQcm94eVwiXSA9IDMwNV0gPSBcIlVzZVByb3h5XCI7XG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlN3aXRjaFByb3h5XCJdID0gMzA2XSA9IFwiU3dpdGNoUHJveHlcIjtcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiVGVtcG9yYXJ5UmVkaXJlY3RcIl0gPSAzMDddID0gXCJUZW1wb3JhcnlSZWRpcmVjdFwiO1xuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJQZXJtYW5lbnRSZWRpcmVjdFwiXSA9IDMwOF0gPSBcIlBlcm1hbmVudFJlZGlyZWN0XCI7XG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIkJhZFJlcXVlc3RcIl0gPSA0MDBdID0gXCJCYWRSZXF1ZXN0XCI7XG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlVuYXV0aG9yaXplZFwiXSA9IDQwMV0gPSBcIlVuYXV0aG9yaXplZFwiO1xuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJQYXltZW50UmVxdWlyZWRcIl0gPSA0MDJdID0gXCJQYXltZW50UmVxdWlyZWRcIjtcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiRm9yYmlkZGVuXCJdID0gNDAzXSA9IFwiRm9yYmlkZGVuXCI7XG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIk5vdEZvdW5kXCJdID0gNDA0XSA9IFwiTm90Rm91bmRcIjtcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiTWV0aG9kTm90QWxsb3dlZFwiXSA9IDQwNV0gPSBcIk1ldGhvZE5vdEFsbG93ZWRcIjtcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiTm90QWNjZXB0YWJsZVwiXSA9IDQwNl0gPSBcIk5vdEFjY2VwdGFibGVcIjtcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiUHJveHlBdXRoZW50aWNhdGlvblJlcXVpcmVkXCJdID0gNDA3XSA9IFwiUHJveHlBdXRoZW50aWNhdGlvblJlcXVpcmVkXCI7XG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlJlcXVlc3RUaW1lb3V0XCJdID0gNDA4XSA9IFwiUmVxdWVzdFRpbWVvdXRcIjtcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiQ29uZmxpY3RcIl0gPSA0MDldID0gXCJDb25mbGljdFwiO1xuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJHb25lXCJdID0gNDEwXSA9IFwiR29uZVwiO1xuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJJbnRlcm5hbFNlcnZlckVycm9yXCJdID0gNTAwXSA9IFwiSW50ZXJuYWxTZXJ2ZXJFcnJvclwiO1xuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJOb3RJbXBsZW1lbnRlZFwiXSA9IDUwMV0gPSBcIk5vdEltcGxlbWVudGVkXCI7XG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIkJhZEdhdGV3YXlcIl0gPSA1MDJdID0gXCJCYWRHYXRld2F5XCI7XG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlNlcnZpY2VVbmF2YWlsYWJsZVwiXSA9IDUwM10gPSBcIlNlcnZpY2VVbmF2YWlsYWJsZVwiO1xuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJHYXRld2F5VGltZW91dFwiXSA9IDUwNF0gPSBcIkdhdGV3YXlUaW1lb3V0XCI7XG59KShIdHRwQ29kZXMgPSBleHBvcnRzLkh0dHBDb2RlcyB8fCAoZXhwb3J0cy5IdHRwQ29kZXMgPSB7fSkpO1xuLyoqXG4gKiBSZXR1cm5zIHRoZSBwcm94eSBVUkwsIGRlcGVuZGluZyB1cG9uIHRoZSBzdXBwbGllZCB1cmwgYW5kIHByb3h5IGVudmlyb25tZW50IHZhcmlhYmxlcy5cbiAqIEBwYXJhbSBzZXJ2ZXJVcmwgIFRoZSBzZXJ2ZXIgVVJMIHdoZXJlIHRoZSByZXF1ZXN0IHdpbGwgYmUgc2VudC4gRm9yIGV4YW1wbGUsIGh0dHBzOi8vYXBpLmdpdGh1Yi5jb21cbiAqL1xuZnVuY3Rpb24gZ2V0UHJveHlVcmwoc2VydmVyVXJsKSB7XG4gICAgbGV0IHByb3h5VXJsID0gcG0uZ2V0UHJveHlVcmwodXJsLnBhcnNlKHNlcnZlclVybCkpO1xuICAgIHJldHVybiBwcm94eVVybCA/IHByb3h5VXJsLmhyZWYgOiAnJztcbn1cbmV4cG9ydHMuZ2V0UHJveHlVcmwgPSBnZXRQcm94eVVybDtcbmNvbnN0IEh0dHBSZWRpcmVjdENvZGVzID0gW0h0dHBDb2Rlcy5Nb3ZlZFBlcm1hbmVudGx5LCBIdHRwQ29kZXMuUmVzb3VyY2VNb3ZlZCwgSHR0cENvZGVzLlNlZU90aGVyLCBIdHRwQ29kZXMuVGVtcG9yYXJ5UmVkaXJlY3QsIEh0dHBDb2Rlcy5QZXJtYW5lbnRSZWRpcmVjdF07XG5jb25zdCBIdHRwUmVzcG9uc2VSZXRyeUNvZGVzID0gW0h0dHBDb2Rlcy5CYWRHYXRld2F5LCBIdHRwQ29kZXMuU2VydmljZVVuYXZhaWxhYmxlLCBIdHRwQ29kZXMuR2F0ZXdheVRpbWVvdXRdO1xuY29uc3QgUmV0cnlhYmxlSHR0cFZlcmJzID0gWydPUFRJT05TJywgJ0dFVCcsICdERUxFVEUnLCAnSEVBRCddO1xuY29uc3QgRXhwb25lbnRpYWxCYWNrb2ZmQ2VpbGluZyA9IDEwO1xuY29uc3QgRXhwb25lbnRpYWxCYWNrb2ZmVGltZVNsaWNlID0gNTtcbmNsYXNzIEh0dHBDbGllbnRSZXNwb25zZSB7XG4gICAgY29uc3RydWN0b3IobWVzc2FnZSkge1xuICAgICAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIH1cbiAgICByZWFkQm9keSgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGxldCBvdXRwdXQgPSBCdWZmZXIuYWxsb2MoMCk7XG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2Uub24oJ2RhdGEnLCAoY2h1bmspID0+IHtcbiAgICAgICAgICAgICAgICBvdXRwdXQgPSBCdWZmZXIuY29uY2F0KFtvdXRwdXQsIGNodW5rXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZS5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlc29sdmUob3V0cHV0LnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmV4cG9ydHMuSHR0cENsaWVudFJlc3BvbnNlID0gSHR0cENsaWVudFJlc3BvbnNlO1xuZnVuY3Rpb24gaXNIdHRwcyhyZXF1ZXN0VXJsKSB7XG4gICAgbGV0IHBhcnNlZFVybCA9IHVybC5wYXJzZShyZXF1ZXN0VXJsKTtcbiAgICByZXR1cm4gcGFyc2VkVXJsLnByb3RvY29sID09PSAnaHR0cHM6Jztcbn1cbmV4cG9ydHMuaXNIdHRwcyA9IGlzSHR0cHM7XG5jbGFzcyBIdHRwQ2xpZW50IHtcbiAgICBjb25zdHJ1Y3Rvcih1c2VyQWdlbnQsIGhhbmRsZXJzLCByZXF1ZXN0T3B0aW9ucykge1xuICAgICAgICB0aGlzLl9pZ25vcmVTc2xFcnJvciA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9hbGxvd1JlZGlyZWN0cyA9IHRydWU7XG4gICAgICAgIHRoaXMuX2FsbG93UmVkaXJlY3REb3duZ3JhZGUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fbWF4UmVkaXJlY3RzID0gNTA7XG4gICAgICAgIHRoaXMuX2FsbG93UmV0cmllcyA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9tYXhSZXRyaWVzID0gMTtcbiAgICAgICAgdGhpcy5fa2VlcEFsaXZlID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX2Rpc3Bvc2VkID0gZmFsc2U7XG4gICAgICAgIHRoaXMudXNlckFnZW50ID0gdXNlckFnZW50O1xuICAgICAgICB0aGlzLmhhbmRsZXJzID0gaGFuZGxlcnMgfHwgW107XG4gICAgICAgIHRoaXMucmVxdWVzdE9wdGlvbnMgPSByZXF1ZXN0T3B0aW9ucztcbiAgICAgICAgaWYgKHJlcXVlc3RPcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAocmVxdWVzdE9wdGlvbnMuaWdub3JlU3NsRXJyb3IgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2lnbm9yZVNzbEVycm9yID0gcmVxdWVzdE9wdGlvbnMuaWdub3JlU3NsRXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9zb2NrZXRUaW1lb3V0ID0gcmVxdWVzdE9wdGlvbnMuc29ja2V0VGltZW91dDtcbiAgICAgICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5hbGxvd1JlZGlyZWN0cyAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fYWxsb3dSZWRpcmVjdHMgPSByZXF1ZXN0T3B0aW9ucy5hbGxvd1JlZGlyZWN0cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5hbGxvd1JlZGlyZWN0RG93bmdyYWRlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9hbGxvd1JlZGlyZWN0RG93bmdyYWRlID0gcmVxdWVzdE9wdGlvbnMuYWxsb3dSZWRpcmVjdERvd25ncmFkZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5tYXhSZWRpcmVjdHMgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX21heFJlZGlyZWN0cyA9IE1hdGgubWF4KHJlcXVlc3RPcHRpb25zLm1heFJlZGlyZWN0cywgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVxdWVzdE9wdGlvbnMua2VlcEFsaXZlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9rZWVwQWxpdmUgPSByZXF1ZXN0T3B0aW9ucy5rZWVwQWxpdmU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVxdWVzdE9wdGlvbnMuYWxsb3dSZXRyaWVzICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9hbGxvd1JldHJpZXMgPSByZXF1ZXN0T3B0aW9ucy5hbGxvd1JldHJpZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVxdWVzdE9wdGlvbnMubWF4UmV0cmllcyAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbWF4UmV0cmllcyA9IHJlcXVlc3RPcHRpb25zLm1heFJldHJpZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgb3B0aW9ucyhyZXF1ZXN0VXJsLCBhZGRpdGlvbmFsSGVhZGVycykge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KCdPUFRJT05TJywgcmVxdWVzdFVybCwgbnVsbCwgYWRkaXRpb25hbEhlYWRlcnMgfHwge30pO1xuICAgIH1cbiAgICBnZXQocmVxdWVzdFVybCwgYWRkaXRpb25hbEhlYWRlcnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdCgnR0VUJywgcmVxdWVzdFVybCwgbnVsbCwgYWRkaXRpb25hbEhlYWRlcnMgfHwge30pO1xuICAgIH1cbiAgICBkZWwocmVxdWVzdFVybCwgYWRkaXRpb25hbEhlYWRlcnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdCgnREVMRVRFJywgcmVxdWVzdFVybCwgbnVsbCwgYWRkaXRpb25hbEhlYWRlcnMgfHwge30pO1xuICAgIH1cbiAgICBwb3N0KHJlcXVlc3RVcmwsIGRhdGEsIGFkZGl0aW9uYWxIZWFkZXJzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QoJ1BPU1QnLCByZXF1ZXN0VXJsLCBkYXRhLCBhZGRpdGlvbmFsSGVhZGVycyB8fCB7fSk7XG4gICAgfVxuICAgIHBhdGNoKHJlcXVlc3RVcmwsIGRhdGEsIGFkZGl0aW9uYWxIZWFkZXJzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QoJ1BBVENIJywgcmVxdWVzdFVybCwgZGF0YSwgYWRkaXRpb25hbEhlYWRlcnMgfHwge30pO1xuICAgIH1cbiAgICBwdXQocmVxdWVzdFVybCwgZGF0YSwgYWRkaXRpb25hbEhlYWRlcnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdCgnUFVUJywgcmVxdWVzdFVybCwgZGF0YSwgYWRkaXRpb25hbEhlYWRlcnMgfHwge30pO1xuICAgIH1cbiAgICBoZWFkKHJlcXVlc3RVcmwsIGFkZGl0aW9uYWxIZWFkZXJzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QoJ0hFQUQnLCByZXF1ZXN0VXJsLCBudWxsLCBhZGRpdGlvbmFsSGVhZGVycyB8fCB7fSk7XG4gICAgfVxuICAgIHNlbmRTdHJlYW0odmVyYiwgcmVxdWVzdFVybCwgc3RyZWFtLCBhZGRpdGlvbmFsSGVhZGVycykge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KHZlcmIsIHJlcXVlc3RVcmwsIHN0cmVhbSwgYWRkaXRpb25hbEhlYWRlcnMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNYWtlcyBhIHJhdyBodHRwIHJlcXVlc3QuXG4gICAgICogQWxsIG90aGVyIG1ldGhvZHMgc3VjaCBhcyBnZXQsIHBvc3QsIHBhdGNoLCBhbmQgcmVxdWVzdCB1bHRpbWF0ZWx5IGNhbGwgdGhpcy5cbiAgICAgKiBQcmVmZXIgZ2V0LCBkZWwsIHBvc3QgYW5kIHBhdGNoXG4gICAgICovXG4gICAgYXN5bmMgcmVxdWVzdCh2ZXJiLCByZXF1ZXN0VXJsLCBkYXRhLCBoZWFkZXJzKSB7XG4gICAgICAgIGlmICh0aGlzLl9kaXNwb3NlZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2xpZW50IGhhcyBhbHJlYWR5IGJlZW4gZGlzcG9zZWQuXCIpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBwYXJzZWRVcmwgPSB1cmwucGFyc2UocmVxdWVzdFVybCk7XG4gICAgICAgIGxldCBpbmZvID0gdGhpcy5fcHJlcGFyZVJlcXVlc3QodmVyYiwgcGFyc2VkVXJsLCBoZWFkZXJzKTtcbiAgICAgICAgLy8gT25seSBwZXJmb3JtIHJldHJpZXMgb24gcmVhZHMgc2luY2Ugd3JpdGVzIG1heSBub3QgYmUgaWRlbXBvdGVudC5cbiAgICAgICAgbGV0IG1heFRyaWVzID0gKHRoaXMuX2FsbG93UmV0cmllcyAmJiBSZXRyeWFibGVIdHRwVmVyYnMuaW5kZXhPZih2ZXJiKSAhPSAtMSkgPyB0aGlzLl9tYXhSZXRyaWVzICsgMSA6IDE7XG4gICAgICAgIGxldCBudW1UcmllcyA9IDA7XG4gICAgICAgIGxldCByZXNwb25zZTtcbiAgICAgICAgd2hpbGUgKG51bVRyaWVzIDwgbWF4VHJpZXMpIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0gYXdhaXQgdGhpcy5yZXF1ZXN0UmF3KGluZm8sIGRhdGEpO1xuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgaXQncyBhbiBhdXRoZW50aWNhdGlvbiBjaGFsbGVuZ2VcbiAgICAgICAgICAgIGlmIChyZXNwb25zZSAmJiByZXNwb25zZS5tZXNzYWdlICYmIHJlc3BvbnNlLm1lc3NhZ2Uuc3RhdHVzQ29kZSA9PT0gSHR0cENvZGVzLlVuYXV0aG9yaXplZCkge1xuICAgICAgICAgICAgICAgIGxldCBhdXRoZW50aWNhdGlvbkhhbmRsZXI7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmhhbmRsZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmhhbmRsZXJzW2ldLmNhbkhhbmRsZUF1dGhlbnRpY2F0aW9uKHJlc3BvbnNlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXV0aGVudGljYXRpb25IYW5kbGVyID0gdGhpcy5oYW5kbGVyc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChhdXRoZW50aWNhdGlvbkhhbmRsZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF1dGhlbnRpY2F0aW9uSGFuZGxlci5oYW5kbGVBdXRoZW50aWNhdGlvbih0aGlzLCBpbmZvLCBkYXRhKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdlIGhhdmUgcmVjZWl2ZWQgYW4gdW5hdXRob3JpemVkIHJlc3BvbnNlIGJ1dCBoYXZlIG5vIGhhbmRsZXJzIHRvIGhhbmRsZSBpdC5cbiAgICAgICAgICAgICAgICAgICAgLy8gTGV0IHRoZSByZXNwb25zZSByZXR1cm4gdG8gdGhlIGNhbGxlci5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCByZWRpcmVjdHNSZW1haW5pbmcgPSB0aGlzLl9tYXhSZWRpcmVjdHM7XG4gICAgICAgICAgICB3aGlsZSAoSHR0cFJlZGlyZWN0Q29kZXMuaW5kZXhPZihyZXNwb25zZS5tZXNzYWdlLnN0YXR1c0NvZGUpICE9IC0xXG4gICAgICAgICAgICAgICAgJiYgdGhpcy5fYWxsb3dSZWRpcmVjdHNcbiAgICAgICAgICAgICAgICAmJiByZWRpcmVjdHNSZW1haW5pbmcgPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVkaXJlY3RVcmwgPSByZXNwb25zZS5tZXNzYWdlLmhlYWRlcnNbXCJsb2NhdGlvblwiXTtcbiAgICAgICAgICAgICAgICBpZiAoIXJlZGlyZWN0VXJsKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoZXJlJ3Mgbm8gbG9jYXRpb24gdG8gcmVkaXJlY3QgdG8sIHdlIHdvbid0XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgcGFyc2VkUmVkaXJlY3RVcmwgPSB1cmwucGFyc2UocmVkaXJlY3RVcmwpO1xuICAgICAgICAgICAgICAgIGlmIChwYXJzZWRVcmwucHJvdG9jb2wgPT0gJ2h0dHBzOicgJiYgcGFyc2VkVXJsLnByb3RvY29sICE9IHBhcnNlZFJlZGlyZWN0VXJsLnByb3RvY29sICYmICF0aGlzLl9hbGxvd1JlZGlyZWN0RG93bmdyYWRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlZGlyZWN0IGZyb20gSFRUUFMgdG8gSFRUUCBwcm90b2NvbC4gVGhpcyBkb3duZ3JhZGUgaXMgbm90IGFsbG93ZWQgZm9yIHNlY3VyaXR5IHJlYXNvbnMuIElmIHlvdSB3YW50IHRvIGFsbG93IHRoaXMgYmVoYXZpb3IsIHNldCB0aGUgYWxsb3dSZWRpcmVjdERvd25ncmFkZSBvcHRpb24gdG8gdHJ1ZS5cIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIHdlIG5lZWQgdG8gZmluaXNoIHJlYWRpbmcgdGhlIHJlc3BvbnNlIGJlZm9yZSByZWFzc2lnbmluZyByZXNwb25zZVxuICAgICAgICAgICAgICAgIC8vIHdoaWNoIHdpbGwgbGVhayB0aGUgb3BlbiBzb2NrZXQuXG4gICAgICAgICAgICAgICAgYXdhaXQgcmVzcG9uc2UucmVhZEJvZHkoKTtcbiAgICAgICAgICAgICAgICAvLyBsZXQncyBtYWtlIHRoZSByZXF1ZXN0IHdpdGggdGhlIG5ldyByZWRpcmVjdFVybFxuICAgICAgICAgICAgICAgIGluZm8gPSB0aGlzLl9wcmVwYXJlUmVxdWVzdCh2ZXJiLCBwYXJzZWRSZWRpcmVjdFVybCwgaGVhZGVycyk7XG4gICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnJlcXVlc3RSYXcoaW5mbywgZGF0YSk7XG4gICAgICAgICAgICAgICAgcmVkaXJlY3RzUmVtYWluaW5nLS07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoSHR0cFJlc3BvbnNlUmV0cnlDb2Rlcy5pbmRleE9mKHJlc3BvbnNlLm1lc3NhZ2Uuc3RhdHVzQ29kZSkgPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiBub3QgYSByZXRyeSBjb2RlLCByZXR1cm4gaW1tZWRpYXRlbHkgaW5zdGVhZCBvZiByZXRyeWluZ1xuICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG51bVRyaWVzICs9IDE7XG4gICAgICAgICAgICBpZiAobnVtVHJpZXMgPCBtYXhUcmllcykge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlc3BvbnNlLnJlYWRCb2R5KCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5fcGVyZm9ybUV4cG9uZW50aWFsQmFja29mZihudW1Ucmllcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBOZWVkcyB0byBiZSBjYWxsZWQgaWYga2VlcEFsaXZlIGlzIHNldCB0byB0cnVlIGluIHJlcXVlc3Qgb3B0aW9ucy5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBpZiAodGhpcy5fYWdlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX2FnZW50LmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9kaXNwb3NlZCA9IHRydWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJhdyByZXF1ZXN0LlxuICAgICAqIEBwYXJhbSBpbmZvXG4gICAgICogQHBhcmFtIGRhdGFcbiAgICAgKi9cbiAgICByZXF1ZXN0UmF3KGluZm8sIGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGxldCBjYWxsYmFja0ZvclJlc3VsdCA9IGZ1bmN0aW9uIChlcnIsIHJlcykge1xuICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUocmVzKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLnJlcXVlc3RSYXdXaXRoQ2FsbGJhY2soaW5mbywgZGF0YSwgY2FsbGJhY2tGb3JSZXN1bHQpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmF3IHJlcXVlc3Qgd2l0aCBjYWxsYmFjay5cbiAgICAgKiBAcGFyYW0gaW5mb1xuICAgICAqIEBwYXJhbSBkYXRhXG4gICAgICogQHBhcmFtIG9uUmVzdWx0XG4gICAgICovXG4gICAgcmVxdWVzdFJhd1dpdGhDYWxsYmFjayhpbmZvLCBkYXRhLCBvblJlc3VsdCkge1xuICAgICAgICBsZXQgc29ja2V0O1xuICAgICAgICBpZiAodHlwZW9mIChkYXRhKSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGluZm8ub3B0aW9ucy5oZWFkZXJzW1wiQ29udGVudC1MZW5ndGhcIl0gPSBCdWZmZXIuYnl0ZUxlbmd0aChkYXRhLCAndXRmOCcpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBjYWxsYmFja0NhbGxlZCA9IGZhbHNlO1xuICAgICAgICBsZXQgaGFuZGxlUmVzdWx0ID0gKGVyciwgcmVzKSA9PiB7XG4gICAgICAgICAgICBpZiAoIWNhbGxiYWNrQ2FsbGVkKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2tDYWxsZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIG9uUmVzdWx0KGVyciwgcmVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgbGV0IHJlcSA9IGluZm8uaHR0cE1vZHVsZS5yZXF1ZXN0KGluZm8ub3B0aW9ucywgKG1zZykgPT4ge1xuICAgICAgICAgICAgbGV0IHJlcyA9IG5ldyBIdHRwQ2xpZW50UmVzcG9uc2UobXNnKTtcbiAgICAgICAgICAgIGhhbmRsZVJlc3VsdChudWxsLCByZXMpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVxLm9uKCdzb2NrZXQnLCAoc29jaykgPT4ge1xuICAgICAgICAgICAgc29ja2V0ID0gc29jaztcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIElmIHdlIGV2ZXIgZ2V0IGRpc2Nvbm5lY3RlZCwgd2Ugd2FudCB0aGUgc29ja2V0IHRvIHRpbWVvdXQgZXZlbnR1YWxseVxuICAgICAgICByZXEuc2V0VGltZW91dCh0aGlzLl9zb2NrZXRUaW1lb3V0IHx8IDMgKiA2MDAwMCwgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHNvY2tldCkge1xuICAgICAgICAgICAgICAgIHNvY2tldC5lbmQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZVJlc3VsdChuZXcgRXJyb3IoJ1JlcXVlc3QgdGltZW91dDogJyArIGluZm8ub3B0aW9ucy5wYXRoKSwgbnVsbCk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXEub24oJ2Vycm9yJywgZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgLy8gZXJyIGhhcyBzdGF0dXNDb2RlIHByb3BlcnR5XG4gICAgICAgICAgICAvLyByZXMgc2hvdWxkIGhhdmUgaGVhZGVyc1xuICAgICAgICAgICAgaGFuZGxlUmVzdWx0KGVyciwgbnVsbCk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoZGF0YSAmJiB0eXBlb2YgKGRhdGEpID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmVxLndyaXRlKGRhdGEsICd1dGY4Jyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRhdGEgJiYgdHlwZW9mIChkYXRhKSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGRhdGEub24oJ2Nsb3NlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJlcS5lbmQoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZGF0YS5waXBlKHJlcSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXEuZW5kKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0cyBhbiBodHRwIGFnZW50LiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWZ1bCB3aGVuIHlvdSBuZWVkIGFuIGh0dHAgYWdlbnQgdGhhdCBoYW5kbGVzXG4gICAgICogcm91dGluZyB0aHJvdWdoIGEgcHJveHkgc2VydmVyIC0gZGVwZW5kaW5nIHVwb24gdGhlIHVybCBhbmQgcHJveHkgZW52aXJvbm1lbnQgdmFyaWFibGVzLlxuICAgICAqIEBwYXJhbSBzZXJ2ZXJVcmwgIFRoZSBzZXJ2ZXIgVVJMIHdoZXJlIHRoZSByZXF1ZXN0IHdpbGwgYmUgc2VudC4gRm9yIGV4YW1wbGUsIGh0dHBzOi8vYXBpLmdpdGh1Yi5jb21cbiAgICAgKi9cbiAgICBnZXRBZ2VudChzZXJ2ZXJVcmwpIHtcbiAgICAgICAgbGV0IHBhcnNlZFVybCA9IHVybC5wYXJzZShzZXJ2ZXJVcmwpO1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0QWdlbnQocGFyc2VkVXJsKTtcbiAgICB9XG4gICAgX3ByZXBhcmVSZXF1ZXN0KG1ldGhvZCwgcmVxdWVzdFVybCwgaGVhZGVycykge1xuICAgICAgICBjb25zdCBpbmZvID0ge307XG4gICAgICAgIGluZm8ucGFyc2VkVXJsID0gcmVxdWVzdFVybDtcbiAgICAgICAgY29uc3QgdXNpbmdTc2wgPSBpbmZvLnBhcnNlZFVybC5wcm90b2NvbCA9PT0gJ2h0dHBzOic7XG4gICAgICAgIGluZm8uaHR0cE1vZHVsZSA9IHVzaW5nU3NsID8gaHR0cHMgOiBodHRwO1xuICAgICAgICBjb25zdCBkZWZhdWx0UG9ydCA9IHVzaW5nU3NsID8gNDQzIDogODA7XG4gICAgICAgIGluZm8ub3B0aW9ucyA9IHt9O1xuICAgICAgICBpbmZvLm9wdGlvbnMuaG9zdCA9IGluZm8ucGFyc2VkVXJsLmhvc3RuYW1lO1xuICAgICAgICBpbmZvLm9wdGlvbnMucG9ydCA9IGluZm8ucGFyc2VkVXJsLnBvcnQgPyBwYXJzZUludChpbmZvLnBhcnNlZFVybC5wb3J0KSA6IGRlZmF1bHRQb3J0O1xuICAgICAgICBpbmZvLm9wdGlvbnMucGF0aCA9IChpbmZvLnBhcnNlZFVybC5wYXRobmFtZSB8fCAnJykgKyAoaW5mby5wYXJzZWRVcmwuc2VhcmNoIHx8ICcnKTtcbiAgICAgICAgaW5mby5vcHRpb25zLm1ldGhvZCA9IG1ldGhvZDtcbiAgICAgICAgaW5mby5vcHRpb25zLmhlYWRlcnMgPSB0aGlzLl9tZXJnZUhlYWRlcnMoaGVhZGVycyk7XG4gICAgICAgIGlmICh0aGlzLnVzZXJBZ2VudCAhPSBudWxsKSB7XG4gICAgICAgICAgICBpbmZvLm9wdGlvbnMuaGVhZGVyc1tcInVzZXItYWdlbnRcIl0gPSB0aGlzLnVzZXJBZ2VudDtcbiAgICAgICAgfVxuICAgICAgICBpbmZvLm9wdGlvbnMuYWdlbnQgPSB0aGlzLl9nZXRBZ2VudChpbmZvLnBhcnNlZFVybCk7XG4gICAgICAgIC8vIGdpdmVzIGhhbmRsZXJzIGFuIG9wcG9ydHVuaXR5IHRvIHBhcnRpY2lwYXRlXG4gICAgICAgIGlmICh0aGlzLmhhbmRsZXJzKSB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZXJzLmZvckVhY2goKGhhbmRsZXIpID0+IHtcbiAgICAgICAgICAgICAgICBoYW5kbGVyLnByZXBhcmVSZXF1ZXN0KGluZm8ub3B0aW9ucyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaW5mbztcbiAgICB9XG4gICAgX21lcmdlSGVhZGVycyhoZWFkZXJzKSB7XG4gICAgICAgIGNvbnN0IGxvd2VyY2FzZUtleXMgPSBvYmogPT4gT2JqZWN0LmtleXMob2JqKS5yZWR1Y2UoKGMsIGspID0+IChjW2sudG9Mb3dlckNhc2UoKV0gPSBvYmpba10sIGMpLCB7fSk7XG4gICAgICAgIGlmICh0aGlzLnJlcXVlc3RPcHRpb25zICYmIHRoaXMucmVxdWVzdE9wdGlvbnMuaGVhZGVycykge1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIGxvd2VyY2FzZUtleXModGhpcy5yZXF1ZXN0T3B0aW9ucy5oZWFkZXJzKSwgbG93ZXJjYXNlS2V5cyhoZWFkZXJzKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGxvd2VyY2FzZUtleXMoaGVhZGVycyB8fCB7fSk7XG4gICAgfVxuICAgIF9nZXRBZ2VudChwYXJzZWRVcmwpIHtcbiAgICAgICAgbGV0IGFnZW50O1xuICAgICAgICBsZXQgcHJveHlVcmwgPSBwbS5nZXRQcm94eVVybChwYXJzZWRVcmwpO1xuICAgICAgICBsZXQgdXNlUHJveHkgPSBwcm94eVVybCAmJiBwcm94eVVybC5ob3N0bmFtZTtcbiAgICAgICAgaWYgKHRoaXMuX2tlZXBBbGl2ZSAmJiB1c2VQcm94eSkge1xuICAgICAgICAgICAgYWdlbnQgPSB0aGlzLl9wcm94eUFnZW50O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9rZWVwQWxpdmUgJiYgIXVzZVByb3h5KSB7XG4gICAgICAgICAgICBhZ2VudCA9IHRoaXMuX2FnZW50O1xuICAgICAgICB9XG4gICAgICAgIC8vIGlmIGFnZW50IGlzIGFscmVhZHkgYXNzaWduZWQgdXNlIHRoYXQgYWdlbnQuXG4gICAgICAgIGlmICghIWFnZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gYWdlbnQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXNpbmdTc2wgPSBwYXJzZWRVcmwucHJvdG9jb2wgPT09ICdodHRwczonO1xuICAgICAgICBsZXQgbWF4U29ja2V0cyA9IDEwMDtcbiAgICAgICAgaWYgKCEhdGhpcy5yZXF1ZXN0T3B0aW9ucykge1xuICAgICAgICAgICAgbWF4U29ja2V0cyA9IHRoaXMucmVxdWVzdE9wdGlvbnMubWF4U29ja2V0cyB8fCBodHRwLmdsb2JhbEFnZW50Lm1heFNvY2tldHM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHVzZVByb3h5KSB7XG4gICAgICAgICAgICAvLyBJZiB1c2luZyBwcm94eSwgbmVlZCB0dW5uZWxcbiAgICAgICAgICAgIGlmICghdHVubmVsKSB7XG4gICAgICAgICAgICAgICAgdHVubmVsID0gcmVxdWlyZSgndHVubmVsJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBhZ2VudE9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgbWF4U29ja2V0czogbWF4U29ja2V0cyxcbiAgICAgICAgICAgICAgICBrZWVwQWxpdmU6IHRoaXMuX2tlZXBBbGl2ZSxcbiAgICAgICAgICAgICAgICBwcm94eToge1xuICAgICAgICAgICAgICAgICAgICBwcm94eUF1dGg6IHByb3h5VXJsLmF1dGgsXG4gICAgICAgICAgICAgICAgICAgIGhvc3Q6IHByb3h5VXJsLmhvc3RuYW1lLFxuICAgICAgICAgICAgICAgICAgICBwb3J0OiBwcm94eVVybC5wb3J0XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBsZXQgdHVubmVsQWdlbnQ7XG4gICAgICAgICAgICBjb25zdCBvdmVySHR0cHMgPSBwcm94eVVybC5wcm90b2NvbCA9PT0gJ2h0dHBzOic7XG4gICAgICAgICAgICBpZiAodXNpbmdTc2wpIHtcbiAgICAgICAgICAgICAgICB0dW5uZWxBZ2VudCA9IG92ZXJIdHRwcyA/IHR1bm5lbC5odHRwc092ZXJIdHRwcyA6IHR1bm5lbC5odHRwc092ZXJIdHRwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdHVubmVsQWdlbnQgPSBvdmVySHR0cHMgPyB0dW5uZWwuaHR0cE92ZXJIdHRwcyA6IHR1bm5lbC5odHRwT3Zlckh0dHA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhZ2VudCA9IHR1bm5lbEFnZW50KGFnZW50T3B0aW9ucyk7XG4gICAgICAgICAgICB0aGlzLl9wcm94eUFnZW50ID0gYWdlbnQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYgcmV1c2luZyBhZ2VudCBhY3Jvc3MgcmVxdWVzdCBhbmQgdHVubmVsaW5nIGFnZW50IGlzbid0IGFzc2lnbmVkIGNyZWF0ZSBhIG5ldyBhZ2VudFxuICAgICAgICBpZiAodGhpcy5fa2VlcEFsaXZlICYmICFhZ2VudCkge1xuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHsga2VlcEFsaXZlOiB0aGlzLl9rZWVwQWxpdmUsIG1heFNvY2tldHM6IG1heFNvY2tldHMgfTtcbiAgICAgICAgICAgIGFnZW50ID0gdXNpbmdTc2wgPyBuZXcgaHR0cHMuQWdlbnQob3B0aW9ucykgOiBuZXcgaHR0cC5BZ2VudChvcHRpb25zKTtcbiAgICAgICAgICAgIHRoaXMuX2FnZW50ID0gYWdlbnQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYgbm90IHVzaW5nIHByaXZhdGUgYWdlbnQgYW5kIHR1bm5lbCBhZ2VudCBpc24ndCBzZXR1cCB0aGVuIHVzZSBnbG9iYWwgYWdlbnRcbiAgICAgICAgaWYgKCFhZ2VudCkge1xuICAgICAgICAgICAgYWdlbnQgPSB1c2luZ1NzbCA/IGh0dHBzLmdsb2JhbEFnZW50IDogaHR0cC5nbG9iYWxBZ2VudDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodXNpbmdTc2wgJiYgdGhpcy5faWdub3JlU3NsRXJyb3IpIHtcbiAgICAgICAgICAgIC8vIHdlIGRvbid0IHdhbnQgdG8gc2V0IE5PREVfVExTX1JFSkVDVF9VTkFVVEhPUklaRUQ9MCBzaW5jZSB0aGF0IHdpbGwgYWZmZWN0IHJlcXVlc3QgZm9yIGVudGlyZSBwcm9jZXNzXG4gICAgICAgICAgICAvLyBodHRwLlJlcXVlc3RPcHRpb25zIGRvZXNuJ3QgZXhwb3NlIGEgd2F5IHRvIG1vZGlmeSBSZXF1ZXN0T3B0aW9ucy5hZ2VudC5vcHRpb25zXG4gICAgICAgICAgICAvLyB3ZSBoYXZlIHRvIGNhc3QgaXQgdG8gYW55IGFuZCBjaGFuZ2UgaXQgZGlyZWN0bHlcbiAgICAgICAgICAgIGFnZW50Lm9wdGlvbnMgPSBPYmplY3QuYXNzaWduKGFnZW50Lm9wdGlvbnMgfHwge30sIHsgcmVqZWN0VW5hdXRob3JpemVkOiBmYWxzZSB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWdlbnQ7XG4gICAgfVxuICAgIF9wZXJmb3JtRXhwb25lbnRpYWxCYWNrb2ZmKHJldHJ5TnVtYmVyKSB7XG4gICAgICAgIHJldHJ5TnVtYmVyID0gTWF0aC5taW4oRXhwb25lbnRpYWxCYWNrb2ZmQ2VpbGluZywgcmV0cnlOdW1iZXIpO1xuICAgICAgICBjb25zdCBtcyA9IEV4cG9uZW50aWFsQmFja29mZlRpbWVTbGljZSAqIE1hdGgucG93KDIsIHJldHJ5TnVtYmVyKTtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dCgoKSA9PiByZXNvbHZlKCksIG1zKSk7XG4gICAgfVxufVxuZXhwb3J0cy5IdHRwQ2xpZW50ID0gSHR0cENsaWVudDtcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9saWIvdHVubmVsJyk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBuZXQgPSByZXF1aXJlKCduZXQnKTtcbnZhciB0bHMgPSByZXF1aXJlKCd0bHMnKTtcbnZhciBodHRwID0gcmVxdWlyZSgnaHR0cCcpO1xudmFyIGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKTtcbnZhciBldmVudHMgPSByZXF1aXJlKCdldmVudHMnKTtcbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuXG5cbmV4cG9ydHMuaHR0cE92ZXJIdHRwID0gaHR0cE92ZXJIdHRwO1xuZXhwb3J0cy5odHRwc092ZXJIdHRwID0gaHR0cHNPdmVySHR0cDtcbmV4cG9ydHMuaHR0cE92ZXJIdHRwcyA9IGh0dHBPdmVySHR0cHM7XG5leHBvcnRzLmh0dHBzT3Zlckh0dHBzID0gaHR0cHNPdmVySHR0cHM7XG5cblxuZnVuY3Rpb24gaHR0cE92ZXJIdHRwKG9wdGlvbnMpIHtcbiAgdmFyIGFnZW50ID0gbmV3IFR1bm5lbGluZ0FnZW50KG9wdGlvbnMpO1xuICBhZ2VudC5yZXF1ZXN0ID0gaHR0cC5yZXF1ZXN0O1xuICByZXR1cm4gYWdlbnQ7XG59XG5cbmZ1bmN0aW9uIGh0dHBzT3Zlckh0dHAob3B0aW9ucykge1xuICB2YXIgYWdlbnQgPSBuZXcgVHVubmVsaW5nQWdlbnQob3B0aW9ucyk7XG4gIGFnZW50LnJlcXVlc3QgPSBodHRwLnJlcXVlc3Q7XG4gIGFnZW50LmNyZWF0ZVNvY2tldCA9IGNyZWF0ZVNlY3VyZVNvY2tldDtcbiAgYWdlbnQuZGVmYXVsdFBvcnQgPSA0NDM7XG4gIHJldHVybiBhZ2VudDtcbn1cblxuZnVuY3Rpb24gaHR0cE92ZXJIdHRwcyhvcHRpb25zKSB7XG4gIHZhciBhZ2VudCA9IG5ldyBUdW5uZWxpbmdBZ2VudChvcHRpb25zKTtcbiAgYWdlbnQucmVxdWVzdCA9IGh0dHBzLnJlcXVlc3Q7XG4gIHJldHVybiBhZ2VudDtcbn1cblxuZnVuY3Rpb24gaHR0cHNPdmVySHR0cHMob3B0aW9ucykge1xuICB2YXIgYWdlbnQgPSBuZXcgVHVubmVsaW5nQWdlbnQob3B0aW9ucyk7XG4gIGFnZW50LnJlcXVlc3QgPSBodHRwcy5yZXF1ZXN0O1xuICBhZ2VudC5jcmVhdGVTb2NrZXQgPSBjcmVhdGVTZWN1cmVTb2NrZXQ7XG4gIGFnZW50LmRlZmF1bHRQb3J0ID0gNDQzO1xuICByZXR1cm4gYWdlbnQ7XG59XG5cblxuZnVuY3Rpb24gVHVubmVsaW5nQWdlbnQob3B0aW9ucykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHNlbGYub3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHNlbGYucHJveHlPcHRpb25zID0gc2VsZi5vcHRpb25zLnByb3h5IHx8IHt9O1xuICBzZWxmLm1heFNvY2tldHMgPSBzZWxmLm9wdGlvbnMubWF4U29ja2V0cyB8fCBodHRwLkFnZW50LmRlZmF1bHRNYXhTb2NrZXRzO1xuICBzZWxmLnJlcXVlc3RzID0gW107XG4gIHNlbGYuc29ja2V0cyA9IFtdO1xuXG4gIHNlbGYub24oJ2ZyZWUnLCBmdW5jdGlvbiBvbkZyZWUoc29ja2V0LCBob3N0LCBwb3J0LCBsb2NhbEFkZHJlc3MpIHtcbiAgICB2YXIgb3B0aW9ucyA9IHRvT3B0aW9ucyhob3N0LCBwb3J0LCBsb2NhbEFkZHJlc3MpO1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBzZWxmLnJlcXVlc3RzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICB2YXIgcGVuZGluZyA9IHNlbGYucmVxdWVzdHNbaV07XG4gICAgICBpZiAocGVuZGluZy5ob3N0ID09PSBvcHRpb25zLmhvc3QgJiYgcGVuZGluZy5wb3J0ID09PSBvcHRpb25zLnBvcnQpIHtcbiAgICAgICAgLy8gRGV0ZWN0IHRoZSByZXF1ZXN0IHRvIGNvbm5lY3Qgc2FtZSBvcmlnaW4gc2VydmVyLFxuICAgICAgICAvLyByZXVzZSB0aGUgY29ubmVjdGlvbi5cbiAgICAgICAgc2VsZi5yZXF1ZXN0cy5zcGxpY2UoaSwgMSk7XG4gICAgICAgIHBlbmRpbmcucmVxdWVzdC5vblNvY2tldChzb2NrZXQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIHNvY2tldC5kZXN0cm95KCk7XG4gICAgc2VsZi5yZW1vdmVTb2NrZXQoc29ja2V0KTtcbiAgfSk7XG59XG51dGlsLmluaGVyaXRzKFR1bm5lbGluZ0FnZW50LCBldmVudHMuRXZlbnRFbWl0dGVyKTtcblxuVHVubmVsaW5nQWdlbnQucHJvdG90eXBlLmFkZFJlcXVlc3QgPSBmdW5jdGlvbiBhZGRSZXF1ZXN0KHJlcSwgaG9zdCwgcG9ydCwgbG9jYWxBZGRyZXNzKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIG9wdGlvbnMgPSBtZXJnZU9wdGlvbnMoe3JlcXVlc3Q6IHJlcX0sIHNlbGYub3B0aW9ucywgdG9PcHRpb25zKGhvc3QsIHBvcnQsIGxvY2FsQWRkcmVzcykpO1xuXG4gIGlmIChzZWxmLnNvY2tldHMubGVuZ3RoID49IHRoaXMubWF4U29ja2V0cykge1xuICAgIC8vIFdlIGFyZSBvdmVyIGxpbWl0IHNvIHdlJ2xsIGFkZCBpdCB0byB0aGUgcXVldWUuXG4gICAgc2VsZi5yZXF1ZXN0cy5wdXNoKG9wdGlvbnMpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIElmIHdlIGFyZSB1bmRlciBtYXhTb2NrZXRzIGNyZWF0ZSBhIG5ldyBvbmUuXG4gIHNlbGYuY3JlYXRlU29ja2V0KG9wdGlvbnMsIGZ1bmN0aW9uKHNvY2tldCkge1xuICAgIHNvY2tldC5vbignZnJlZScsIG9uRnJlZSk7XG4gICAgc29ja2V0Lm9uKCdjbG9zZScsIG9uQ2xvc2VPclJlbW92ZSk7XG4gICAgc29ja2V0Lm9uKCdhZ2VudFJlbW92ZScsIG9uQ2xvc2VPclJlbW92ZSk7XG4gICAgcmVxLm9uU29ja2V0KHNvY2tldCk7XG5cbiAgICBmdW5jdGlvbiBvbkZyZWUoKSB7XG4gICAgICBzZWxmLmVtaXQoJ2ZyZWUnLCBzb2NrZXQsIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG9uQ2xvc2VPclJlbW92ZShlcnIpIHtcbiAgICAgIHNlbGYucmVtb3ZlU29ja2V0KHNvY2tldCk7XG4gICAgICBzb2NrZXQucmVtb3ZlTGlzdGVuZXIoJ2ZyZWUnLCBvbkZyZWUpO1xuICAgICAgc29ja2V0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uQ2xvc2VPclJlbW92ZSk7XG4gICAgICBzb2NrZXQucmVtb3ZlTGlzdGVuZXIoJ2FnZW50UmVtb3ZlJywgb25DbG9zZU9yUmVtb3ZlKTtcbiAgICB9XG4gIH0pO1xufTtcblxuVHVubmVsaW5nQWdlbnQucHJvdG90eXBlLmNyZWF0ZVNvY2tldCA9IGZ1bmN0aW9uIGNyZWF0ZVNvY2tldChvcHRpb25zLCBjYikge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBwbGFjZWhvbGRlciA9IHt9O1xuICBzZWxmLnNvY2tldHMucHVzaChwbGFjZWhvbGRlcik7XG5cbiAgdmFyIGNvbm5lY3RPcHRpb25zID0gbWVyZ2VPcHRpb25zKHt9LCBzZWxmLnByb3h5T3B0aW9ucywge1xuICAgIG1ldGhvZDogJ0NPTk5FQ1QnLFxuICAgIHBhdGg6IG9wdGlvbnMuaG9zdCArICc6JyArIG9wdGlvbnMucG9ydCxcbiAgICBhZ2VudDogZmFsc2UsXG4gICAgaGVhZGVyczoge1xuICAgICAgaG9zdDogb3B0aW9ucy5ob3N0ICsgJzonICsgb3B0aW9ucy5wb3J0XG4gICAgfVxuICB9KTtcbiAgaWYgKG9wdGlvbnMubG9jYWxBZGRyZXNzKSB7XG4gICAgY29ubmVjdE9wdGlvbnMubG9jYWxBZGRyZXNzID0gb3B0aW9ucy5sb2NhbEFkZHJlc3M7XG4gIH1cbiAgaWYgKGNvbm5lY3RPcHRpb25zLnByb3h5QXV0aCkge1xuICAgIGNvbm5lY3RPcHRpb25zLmhlYWRlcnMgPSBjb25uZWN0T3B0aW9ucy5oZWFkZXJzIHx8IHt9O1xuICAgIGNvbm5lY3RPcHRpb25zLmhlYWRlcnNbJ1Byb3h5LUF1dGhvcml6YXRpb24nXSA9ICdCYXNpYyAnICtcbiAgICAgICAgbmV3IEJ1ZmZlcihjb25uZWN0T3B0aW9ucy5wcm94eUF1dGgpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgfVxuXG4gIGRlYnVnKCdtYWtpbmcgQ09OTkVDVCByZXF1ZXN0Jyk7XG4gIHZhciBjb25uZWN0UmVxID0gc2VsZi5yZXF1ZXN0KGNvbm5lY3RPcHRpb25zKTtcbiAgY29ubmVjdFJlcS51c2VDaHVua2VkRW5jb2RpbmdCeURlZmF1bHQgPSBmYWxzZTsgLy8gZm9yIHYwLjZcbiAgY29ubmVjdFJlcS5vbmNlKCdyZXNwb25zZScsIG9uUmVzcG9uc2UpOyAvLyBmb3IgdjAuNlxuICBjb25uZWN0UmVxLm9uY2UoJ3VwZ3JhZGUnLCBvblVwZ3JhZGUpOyAgIC8vIGZvciB2MC42XG4gIGNvbm5lY3RSZXEub25jZSgnY29ubmVjdCcsIG9uQ29ubmVjdCk7ICAgLy8gZm9yIHYwLjcgb3IgbGF0ZXJcbiAgY29ubmVjdFJlcS5vbmNlKCdlcnJvcicsIG9uRXJyb3IpO1xuICBjb25uZWN0UmVxLmVuZCgpO1xuXG4gIGZ1bmN0aW9uIG9uUmVzcG9uc2UocmVzKSB7XG4gICAgLy8gVmVyeSBoYWNreS4gVGhpcyBpcyBuZWNlc3NhcnkgdG8gYXZvaWQgaHR0cC1wYXJzZXIgbGVha3MuXG4gICAgcmVzLnVwZ3JhZGUgPSB0cnVlO1xuICB9XG5cbiAgZnVuY3Rpb24gb25VcGdyYWRlKHJlcywgc29ja2V0LCBoZWFkKSB7XG4gICAgLy8gSGFja3kuXG4gICAgcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbigpIHtcbiAgICAgIG9uQ29ubmVjdChyZXMsIHNvY2tldCwgaGVhZCk7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBvbkNvbm5lY3QocmVzLCBzb2NrZXQsIGhlYWQpIHtcbiAgICBjb25uZWN0UmVxLnJlbW92ZUFsbExpc3RlbmVycygpO1xuICAgIHNvY2tldC5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcblxuICAgIGlmIChyZXMuc3RhdHVzQ29kZSAhPT0gMjAwKSB7XG4gICAgICBkZWJ1ZygndHVubmVsaW5nIHNvY2tldCBjb3VsZCBub3QgYmUgZXN0YWJsaXNoZWQsIHN0YXR1c0NvZGU9JWQnLFxuICAgICAgICByZXMuc3RhdHVzQ29kZSk7XG4gICAgICBzb2NrZXQuZGVzdHJveSgpO1xuICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCd0dW5uZWxpbmcgc29ja2V0IGNvdWxkIG5vdCBiZSBlc3RhYmxpc2hlZCwgJyArXG4gICAgICAgICdzdGF0dXNDb2RlPScgKyByZXMuc3RhdHVzQ29kZSk7XG4gICAgICBlcnJvci5jb2RlID0gJ0VDT05OUkVTRVQnO1xuICAgICAgb3B0aW9ucy5yZXF1ZXN0LmVtaXQoJ2Vycm9yJywgZXJyb3IpO1xuICAgICAgc2VsZi5yZW1vdmVTb2NrZXQocGxhY2Vob2xkZXIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoaGVhZC5sZW5ndGggPiAwKSB7XG4gICAgICBkZWJ1ZygnZ290IGlsbGVnYWwgcmVzcG9uc2UgYm9keSBmcm9tIHByb3h5Jyk7XG4gICAgICBzb2NrZXQuZGVzdHJveSgpO1xuICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdnb3QgaWxsZWdhbCByZXNwb25zZSBib2R5IGZyb20gcHJveHknKTtcbiAgICAgIGVycm9yLmNvZGUgPSAnRUNPTk5SRVNFVCc7XG4gICAgICBvcHRpb25zLnJlcXVlc3QuZW1pdCgnZXJyb3InLCBlcnJvcik7XG4gICAgICBzZWxmLnJlbW92ZVNvY2tldChwbGFjZWhvbGRlcik7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGRlYnVnKCd0dW5uZWxpbmcgY29ubmVjdGlvbiBoYXMgZXN0YWJsaXNoZWQnKTtcbiAgICBzZWxmLnNvY2tldHNbc2VsZi5zb2NrZXRzLmluZGV4T2YocGxhY2Vob2xkZXIpXSA9IHNvY2tldDtcbiAgICByZXR1cm4gY2Ioc29ja2V0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uRXJyb3IoY2F1c2UpIHtcbiAgICBjb25uZWN0UmVxLnJlbW92ZUFsbExpc3RlbmVycygpO1xuXG4gICAgZGVidWcoJ3R1bm5lbGluZyBzb2NrZXQgY291bGQgbm90IGJlIGVzdGFibGlzaGVkLCBjYXVzZT0lc1xcbicsXG4gICAgICAgICAgY2F1c2UubWVzc2FnZSwgY2F1c2Uuc3RhY2spO1xuICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcigndHVubmVsaW5nIHNvY2tldCBjb3VsZCBub3QgYmUgZXN0YWJsaXNoZWQsICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAnY2F1c2U9JyArIGNhdXNlLm1lc3NhZ2UpO1xuICAgIGVycm9yLmNvZGUgPSAnRUNPTk5SRVNFVCc7XG4gICAgb3B0aW9ucy5yZXF1ZXN0LmVtaXQoJ2Vycm9yJywgZXJyb3IpO1xuICAgIHNlbGYucmVtb3ZlU29ja2V0KHBsYWNlaG9sZGVyKTtcbiAgfVxufTtcblxuVHVubmVsaW5nQWdlbnQucHJvdG90eXBlLnJlbW92ZVNvY2tldCA9IGZ1bmN0aW9uIHJlbW92ZVNvY2tldChzb2NrZXQpIHtcbiAgdmFyIHBvcyA9IHRoaXMuc29ja2V0cy5pbmRleE9mKHNvY2tldClcbiAgaWYgKHBvcyA9PT0gLTEpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdGhpcy5zb2NrZXRzLnNwbGljZShwb3MsIDEpO1xuXG4gIHZhciBwZW5kaW5nID0gdGhpcy5yZXF1ZXN0cy5zaGlmdCgpO1xuICBpZiAocGVuZGluZykge1xuICAgIC8vIElmIHdlIGhhdmUgcGVuZGluZyByZXF1ZXN0cyBhbmQgYSBzb2NrZXQgZ2V0cyBjbG9zZWQgYSBuZXcgb25lXG4gICAgLy8gbmVlZHMgdG8gYmUgY3JlYXRlZCB0byB0YWtlIG92ZXIgaW4gdGhlIHBvb2wgZm9yIHRoZSBvbmUgdGhhdCBjbG9zZWQuXG4gICAgdGhpcy5jcmVhdGVTb2NrZXQocGVuZGluZywgZnVuY3Rpb24oc29ja2V0KSB7XG4gICAgICBwZW5kaW5nLnJlcXVlc3Qub25Tb2NrZXQoc29ja2V0KTtcbiAgICB9KTtcbiAgfVxufTtcblxuZnVuY3Rpb24gY3JlYXRlU2VjdXJlU29ja2V0KG9wdGlvbnMsIGNiKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgVHVubmVsaW5nQWdlbnQucHJvdG90eXBlLmNyZWF0ZVNvY2tldC5jYWxsKHNlbGYsIG9wdGlvbnMsIGZ1bmN0aW9uKHNvY2tldCkge1xuICAgIHZhciBob3N0SGVhZGVyID0gb3B0aW9ucy5yZXF1ZXN0LmdldEhlYWRlcignaG9zdCcpO1xuICAgIHZhciB0bHNPcHRpb25zID0gbWVyZ2VPcHRpb25zKHt9LCBzZWxmLm9wdGlvbnMsIHtcbiAgICAgIHNvY2tldDogc29ja2V0LFxuICAgICAgc2VydmVybmFtZTogaG9zdEhlYWRlciA/IGhvc3RIZWFkZXIucmVwbGFjZSgvOi4qJC8sICcnKSA6IG9wdGlvbnMuaG9zdFxuICAgIH0pO1xuXG4gICAgLy8gMCBpcyBkdW1teSBwb3J0IGZvciB2MC42XG4gICAgdmFyIHNlY3VyZVNvY2tldCA9IHRscy5jb25uZWN0KDAsIHRsc09wdGlvbnMpO1xuICAgIHNlbGYuc29ja2V0c1tzZWxmLnNvY2tldHMuaW5kZXhPZihzb2NrZXQpXSA9IHNlY3VyZVNvY2tldDtcbiAgICBjYihzZWN1cmVTb2NrZXQpO1xuICB9KTtcbn1cblxuXG5mdW5jdGlvbiB0b09wdGlvbnMoaG9zdCwgcG9ydCwgbG9jYWxBZGRyZXNzKSB7XG4gIGlmICh0eXBlb2YgaG9zdCA9PT0gJ3N0cmluZycpIHsgLy8gc2luY2UgdjAuMTBcbiAgICByZXR1cm4ge1xuICAgICAgaG9zdDogaG9zdCxcbiAgICAgIHBvcnQ6IHBvcnQsXG4gICAgICBsb2NhbEFkZHJlc3M6IGxvY2FsQWRkcmVzc1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGhvc3Q7IC8vIGZvciB2MC4xMSBvciBsYXRlclxufVxuXG5mdW5jdGlvbiBtZXJnZU9wdGlvbnModGFyZ2V0KSB7XG4gIGZvciAodmFyIGkgPSAxLCBsZW4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICB2YXIgb3ZlcnJpZGVzID0gYXJndW1lbnRzW2ldO1xuICAgIGlmICh0eXBlb2Ygb3ZlcnJpZGVzID09PSAnb2JqZWN0Jykge1xuICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvdmVycmlkZXMpO1xuICAgICAgZm9yICh2YXIgaiA9IDAsIGtleUxlbiA9IGtleXMubGVuZ3RoOyBqIDwga2V5TGVuOyArK2opIHtcbiAgICAgICAgdmFyIGsgPSBrZXlzW2pdO1xuICAgICAgICBpZiAob3ZlcnJpZGVzW2tdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0YXJnZXRba10gPSBvdmVycmlkZXNba107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuXG52YXIgZGVidWc7XG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9ERUJVRyAmJiAvXFxidHVubmVsXFxiLy50ZXN0KHByb2Nlc3MuZW52Lk5PREVfREVCVUcpKSB7XG4gIGRlYnVnID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgIGlmICh0eXBlb2YgYXJnc1swXSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGFyZ3NbMF0gPSAnVFVOTkVMOiAnICsgYXJnc1swXTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXJncy51bnNoaWZ0KCdUVU5ORUw6Jyk7XG4gICAgfVxuICAgIGNvbnNvbGUuZXJyb3IuYXBwbHkoY29uc29sZSwgYXJncyk7XG4gIH1cbn0gZWxzZSB7XG4gIGRlYnVnID0gZnVuY3Rpb24oKSB7fTtcbn1cbmV4cG9ydHMuZGVidWcgPSBkZWJ1ZzsgLy8gZm9yIHRlc3RcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuY29uc3QgdXJsID0gcmVxdWlyZShcInVybFwiKTtcbmZ1bmN0aW9uIGdldFByb3h5VXJsKHJlcVVybCkge1xuICAgIGxldCB1c2luZ1NzbCA9IHJlcVVybC5wcm90b2NvbCA9PT0gJ2h0dHBzOic7XG4gICAgbGV0IHByb3h5VXJsO1xuICAgIGlmIChjaGVja0J5cGFzcyhyZXFVcmwpKSB7XG4gICAgICAgIHJldHVybiBwcm94eVVybDtcbiAgICB9XG4gICAgbGV0IHByb3h5VmFyO1xuICAgIGlmICh1c2luZ1NzbCkge1xuICAgICAgICBwcm94eVZhciA9IHByb2Nlc3MuZW52W1wiaHR0cHNfcHJveHlcIl0gfHxcbiAgICAgICAgICAgIHByb2Nlc3MuZW52W1wiSFRUUFNfUFJPWFlcIl07XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBwcm94eVZhciA9IHByb2Nlc3MuZW52W1wiaHR0cF9wcm94eVwiXSB8fFxuICAgICAgICAgICAgcHJvY2Vzcy5lbnZbXCJIVFRQX1BST1hZXCJdO1xuICAgIH1cbiAgICBpZiAocHJveHlWYXIpIHtcbiAgICAgICAgcHJveHlVcmwgPSB1cmwucGFyc2UocHJveHlWYXIpO1xuICAgIH1cbiAgICByZXR1cm4gcHJveHlVcmw7XG59XG5leHBvcnRzLmdldFByb3h5VXJsID0gZ2V0UHJveHlVcmw7XG5mdW5jdGlvbiBjaGVja0J5cGFzcyhyZXFVcmwpIHtcbiAgICBpZiAoIXJlcVVybC5ob3N0bmFtZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGxldCBub1Byb3h5ID0gcHJvY2Vzcy5lbnZbXCJub19wcm94eVwiXSB8fCBwcm9jZXNzLmVudltcIk5PX1BST1hZXCJdIHx8ICcnO1xuICAgIGlmICghbm9Qcm94eSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8vIERldGVybWluZSB0aGUgcmVxdWVzdCBwb3J0XG4gICAgbGV0IHJlcVBvcnQ7XG4gICAgaWYgKHJlcVVybC5wb3J0KSB7XG4gICAgICAgIHJlcVBvcnQgPSBOdW1iZXIocmVxVXJsLnBvcnQpO1xuICAgIH1cbiAgICBlbHNlIGlmIChyZXFVcmwucHJvdG9jb2wgPT09ICdodHRwOicpIHtcbiAgICAgICAgcmVxUG9ydCA9IDgwO1xuICAgIH1cbiAgICBlbHNlIGlmIChyZXFVcmwucHJvdG9jb2wgPT09ICdodHRwczonKSB7XG4gICAgICAgIHJlcVBvcnQgPSA0NDM7XG4gICAgfVxuICAgIC8vIEZvcm1hdCB0aGUgcmVxdWVzdCBob3N0bmFtZSBhbmQgaG9zdG5hbWUgd2l0aCBwb3J0XG4gICAgbGV0IHVwcGVyUmVxSG9zdHMgPSBbcmVxVXJsLmhvc3RuYW1lLnRvVXBwZXJDYXNlKCldO1xuICAgIGlmICh0eXBlb2YgcmVxUG9ydCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgdXBwZXJSZXFIb3N0cy5wdXNoKGAke3VwcGVyUmVxSG9zdHNbMF19OiR7cmVxUG9ydH1gKTtcbiAgICB9XG4gICAgLy8gQ29tcGFyZSByZXF1ZXN0IGhvc3QgYWdhaW5zdCBub3Byb3h5XG4gICAgZm9yIChsZXQgdXBwZXJOb1Byb3h5SXRlbSBvZiBub1Byb3h5LnNwbGl0KCcsJykubWFwKHggPT4geC50cmltKCkudG9VcHBlckNhc2UoKSkuZmlsdGVyKHggPT4geCkpIHtcbiAgICAgICAgaWYgKHVwcGVyUmVxSG9zdHMuc29tZSh4ID0+IHggPT09IHVwcGVyTm9Qcm94eUl0ZW0pKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5leHBvcnRzLmNoZWNrQnlwYXNzID0gY2hlY2tCeXBhc3M7XG4iLCJcInVzZSBzdHJpY3RcIjtcbnZhciBfX2F3YWl0ZXIgPSAodGhpcyAmJiB0aGlzLl9fYXdhaXRlcikgfHwgZnVuY3Rpb24gKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xuICAgIGZ1bmN0aW9uIGFkb3B0KHZhbHVlKSB7IHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFAgPyB2YWx1ZSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUodmFsdWUpOyB9KTsgfVxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XG4gICAgfSk7XG59O1xudmFyIF9hO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuY29uc3QgYXNzZXJ0XzEgPSByZXF1aXJlKFwiYXNzZXJ0XCIpO1xuY29uc3QgZnMgPSByZXF1aXJlKFwiZnNcIik7XG5jb25zdCBwYXRoID0gcmVxdWlyZShcInBhdGhcIik7XG5fYSA9IGZzLnByb21pc2VzLCBleHBvcnRzLmNobW9kID0gX2EuY2htb2QsIGV4cG9ydHMuY29weUZpbGUgPSBfYS5jb3B5RmlsZSwgZXhwb3J0cy5sc3RhdCA9IF9hLmxzdGF0LCBleHBvcnRzLm1rZGlyID0gX2EubWtkaXIsIGV4cG9ydHMucmVhZGRpciA9IF9hLnJlYWRkaXIsIGV4cG9ydHMucmVhZGxpbmsgPSBfYS5yZWFkbGluaywgZXhwb3J0cy5yZW5hbWUgPSBfYS5yZW5hbWUsIGV4cG9ydHMucm1kaXIgPSBfYS5ybWRpciwgZXhwb3J0cy5zdGF0ID0gX2Euc3RhdCwgZXhwb3J0cy5zeW1saW5rID0gX2Euc3ltbGluaywgZXhwb3J0cy51bmxpbmsgPSBfYS51bmxpbms7XG5leHBvcnRzLklTX1dJTkRPV1MgPSBwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInO1xuZnVuY3Rpb24gZXhpc3RzKGZzUGF0aCkge1xuICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB5aWVsZCBleHBvcnRzLnN0YXQoZnNQYXRoKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT09ICdFTk9FTlQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0pO1xufVxuZXhwb3J0cy5leGlzdHMgPSBleGlzdHM7XG5mdW5jdGlvbiBpc0RpcmVjdG9yeShmc1BhdGgsIHVzZVN0YXQgPSBmYWxzZSkge1xuICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGNvbnN0IHN0YXRzID0gdXNlU3RhdCA/IHlpZWxkIGV4cG9ydHMuc3RhdChmc1BhdGgpIDogeWllbGQgZXhwb3J0cy5sc3RhdChmc1BhdGgpO1xuICAgICAgICByZXR1cm4gc3RhdHMuaXNEaXJlY3RvcnkoKTtcbiAgICB9KTtcbn1cbmV4cG9ydHMuaXNEaXJlY3RvcnkgPSBpc0RpcmVjdG9yeTtcbi8qKlxuICogT24gT1NYL0xpbnV4LCB0cnVlIGlmIHBhdGggc3RhcnRzIHdpdGggJy8nLiBPbiBXaW5kb3dzLCB0cnVlIGZvciBwYXRocyBsaWtlOlxuICogXFwsIFxcaGVsbG8sIFxcXFxoZWxsb1xcc2hhcmUsIEM6LCBhbmQgQzpcXGhlbGxvIChhbmQgY29ycmVzcG9uZGluZyBhbHRlcm5hdGUgc2VwYXJhdG9yIGNhc2VzKS5cbiAqL1xuZnVuY3Rpb24gaXNSb290ZWQocCkge1xuICAgIHAgPSBub3JtYWxpemVTZXBhcmF0b3JzKHApO1xuICAgIGlmICghcCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2lzUm9vdGVkKCkgcGFyYW1ldGVyIFwicFwiIGNhbm5vdCBiZSBlbXB0eScpO1xuICAgIH1cbiAgICBpZiAoZXhwb3J0cy5JU19XSU5ET1dTKSB7XG4gICAgICAgIHJldHVybiAocC5zdGFydHNXaXRoKCdcXFxcJykgfHwgL15bQS1aXTovaS50ZXN0KHApIC8vIGUuZy4gXFwgb3IgXFxoZWxsbyBvciBcXFxcaGVsbG9cbiAgICAgICAgKTsgLy8gZS5nLiBDOiBvciBDOlxcaGVsbG9cbiAgICB9XG4gICAgcmV0dXJuIHAuc3RhcnRzV2l0aCgnLycpO1xufVxuZXhwb3J0cy5pc1Jvb3RlZCA9IGlzUm9vdGVkO1xuLyoqXG4gKiBSZWN1cnNpdmVseSBjcmVhdGUgYSBkaXJlY3RvcnkgYXQgYGZzUGF0aGAuXG4gKlxuICogVGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBvcHRpbWlzdGljLCBtZWFuaW5nIGl0IGF0dGVtcHRzIHRvIGNyZWF0ZSB0aGUgZnVsbFxuICogcGF0aCBmaXJzdCwgYW5kIGJhY2tzIHVwIHRoZSBwYXRoIHN0YWNrIGZyb20gdGhlcmUuXG4gKlxuICogQHBhcmFtIGZzUGF0aCBUaGUgcGF0aCB0byBjcmVhdGVcbiAqIEBwYXJhbSBtYXhEZXB0aCBUaGUgbWF4aW11bSByZWN1cnNpb24gZGVwdGhcbiAqIEBwYXJhbSBkZXB0aCBUaGUgY3VycmVudCByZWN1cnNpb24gZGVwdGhcbiAqL1xuZnVuY3Rpb24gbWtkaXJQKGZzUGF0aCwgbWF4RGVwdGggPSAxMDAwLCBkZXB0aCA9IDEpIHtcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICBhc3NlcnRfMS5vayhmc1BhdGgsICdhIHBhdGggYXJndW1lbnQgbXVzdCBiZSBwcm92aWRlZCcpO1xuICAgICAgICBmc1BhdGggPSBwYXRoLnJlc29sdmUoZnNQYXRoKTtcbiAgICAgICAgaWYgKGRlcHRoID49IG1heERlcHRoKVxuICAgICAgICAgICAgcmV0dXJuIGV4cG9ydHMubWtkaXIoZnNQYXRoKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHlpZWxkIGV4cG9ydHMubWtkaXIoZnNQYXRoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKGVyci5jb2RlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnRU5PRU5UJzoge1xuICAgICAgICAgICAgICAgICAgICB5aWVsZCBta2RpclAocGF0aC5kaXJuYW1lKGZzUGF0aCksIG1heERlcHRoLCBkZXB0aCArIDEpO1xuICAgICAgICAgICAgICAgICAgICB5aWVsZCBleHBvcnRzLm1rZGlyKGZzUGF0aCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICBsZXQgc3RhdHM7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0cyA9IHlpZWxkIGV4cG9ydHMuc3RhdChmc1BhdGgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhdGNoIChlcnIyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzdGF0cy5pc0RpcmVjdG9yeSgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xufVxuZXhwb3J0cy5ta2RpclAgPSBta2RpclA7XG4vKipcbiAqIEJlc3QgZWZmb3J0IGF0dGVtcHQgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgYSBmaWxlIGV4aXN0cyBhbmQgaXMgZXhlY3V0YWJsZS5cbiAqIEBwYXJhbSBmaWxlUGF0aCAgICBmaWxlIHBhdGggdG8gY2hlY2tcbiAqIEBwYXJhbSBleHRlbnNpb25zICBhZGRpdGlvbmFsIGZpbGUgZXh0ZW5zaW9ucyB0byB0cnlcbiAqIEByZXR1cm4gaWYgZmlsZSBleGlzdHMgYW5kIGlzIGV4ZWN1dGFibGUsIHJldHVybnMgdGhlIGZpbGUgcGF0aC4gb3RoZXJ3aXNlIGVtcHR5IHN0cmluZy5cbiAqL1xuZnVuY3Rpb24gdHJ5R2V0RXhlY3V0YWJsZVBhdGgoZmlsZVBhdGgsIGV4dGVuc2lvbnMpIHtcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICBsZXQgc3RhdHMgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyB0ZXN0IGZpbGUgZXhpc3RzXG4gICAgICAgICAgICBzdGF0cyA9IHlpZWxkIGV4cG9ydHMuc3RhdChmaWxlUGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgaWYgKGVyci5jb2RlICE9PSAnRU5PRU5UJykge1xuICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFVuZXhwZWN0ZWQgZXJyb3IgYXR0ZW1wdGluZyB0byBkZXRlcm1pbmUgaWYgZXhlY3V0YWJsZSBmaWxlIGV4aXN0cyAnJHtmaWxlUGF0aH0nOiAke2Vycn1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RhdHMgJiYgc3RhdHMuaXNGaWxlKCkpIHtcbiAgICAgICAgICAgIGlmIChleHBvcnRzLklTX1dJTkRPV1MpIHtcbiAgICAgICAgICAgICAgICAvLyBvbiBXaW5kb3dzLCB0ZXN0IGZvciB2YWxpZCBleHRlbnNpb25cbiAgICAgICAgICAgICAgICBjb25zdCB1cHBlckV4dCA9IHBhdGguZXh0bmFtZShmaWxlUGF0aCkudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICAgICAgICBpZiAoZXh0ZW5zaW9ucy5zb21lKHZhbGlkRXh0ID0+IHZhbGlkRXh0LnRvVXBwZXJDYXNlKCkgPT09IHVwcGVyRXh0KSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlsZVBhdGg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzVW5peEV4ZWN1dGFibGUoc3RhdHMpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmaWxlUGF0aDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gdHJ5IGVhY2ggZXh0ZW5zaW9uXG4gICAgICAgIGNvbnN0IG9yaWdpbmFsRmlsZVBhdGggPSBmaWxlUGF0aDtcbiAgICAgICAgZm9yIChjb25zdCBleHRlbnNpb24gb2YgZXh0ZW5zaW9ucykge1xuICAgICAgICAgICAgZmlsZVBhdGggPSBvcmlnaW5hbEZpbGVQYXRoICsgZXh0ZW5zaW9uO1xuICAgICAgICAgICAgc3RhdHMgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHN0YXRzID0geWllbGQgZXhwb3J0cy5zdGF0KGZpbGVQYXRoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgIT09ICdFTk9FTlQnKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBVbmV4cGVjdGVkIGVycm9yIGF0dGVtcHRpbmcgdG8gZGV0ZXJtaW5lIGlmIGV4ZWN1dGFibGUgZmlsZSBleGlzdHMgJyR7ZmlsZVBhdGh9JzogJHtlcnJ9YCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHN0YXRzICYmIHN0YXRzLmlzRmlsZSgpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV4cG9ydHMuSVNfV0lORE9XUykge1xuICAgICAgICAgICAgICAgICAgICAvLyBwcmVzZXJ2ZSB0aGUgY2FzZSBvZiB0aGUgYWN0dWFsIGZpbGUgKHNpbmNlIGFuIGV4dGVuc2lvbiB3YXMgYXBwZW5kZWQpXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkaXJlY3RvcnkgPSBwYXRoLmRpcm5hbWUoZmlsZVBhdGgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBwZXJOYW1lID0gcGF0aC5iYXNlbmFtZShmaWxlUGF0aCkudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYWN0dWFsTmFtZSBvZiB5aWVsZCBleHBvcnRzLnJlYWRkaXIoZGlyZWN0b3J5KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1cHBlck5hbWUgPT09IGFjdHVhbE5hbWUudG9VcHBlckNhc2UoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlUGF0aCA9IHBhdGguam9pbihkaXJlY3RvcnksIGFjdHVhbE5hbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBVbmV4cGVjdGVkIGVycm9yIGF0dGVtcHRpbmcgdG8gZGV0ZXJtaW5lIHRoZSBhY3R1YWwgY2FzZSBvZiB0aGUgZmlsZSAnJHtmaWxlUGF0aH0nOiAke2Vycn1gKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlsZVBhdGg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNVbml4RXhlY3V0YWJsZShzdGF0cykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmaWxlUGF0aDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJyc7XG4gICAgfSk7XG59XG5leHBvcnRzLnRyeUdldEV4ZWN1dGFibGVQYXRoID0gdHJ5R2V0RXhlY3V0YWJsZVBhdGg7XG5mdW5jdGlvbiBub3JtYWxpemVTZXBhcmF0b3JzKHApIHtcbiAgICBwID0gcCB8fCAnJztcbiAgICBpZiAoZXhwb3J0cy5JU19XSU5ET1dTKSB7XG4gICAgICAgIC8vIGNvbnZlcnQgc2xhc2hlcyBvbiBXaW5kb3dzXG4gICAgICAgIHAgPSBwLnJlcGxhY2UoL1xcLy9nLCAnXFxcXCcpO1xuICAgICAgICAvLyByZW1vdmUgcmVkdW5kYW50IHNsYXNoZXNcbiAgICAgICAgcmV0dXJuIHAucmVwbGFjZSgvXFxcXFxcXFwrL2csICdcXFxcJyk7XG4gICAgfVxuICAgIC8vIHJlbW92ZSByZWR1bmRhbnQgc2xhc2hlc1xuICAgIHJldHVybiBwLnJlcGxhY2UoL1xcL1xcLysvZywgJy8nKTtcbn1cbi8vIG9uIE1hYy9MaW51eCwgdGVzdCB0aGUgZXhlY3V0ZSBiaXRcbi8vICAgICBSICAgVyAgWCAgUiAgVyBYIFIgVyBYXG4vLyAgIDI1NiAxMjggNjQgMzIgMTYgOCA0IDIgMVxuZnVuY3Rpb24gaXNVbml4RXhlY3V0YWJsZShzdGF0cykge1xuICAgIHJldHVybiAoKHN0YXRzLm1vZGUgJiAxKSA+IDAgfHxcbiAgICAgICAgKChzdGF0cy5tb2RlICYgOCkgPiAwICYmIHN0YXRzLmdpZCA9PT0gcHJvY2Vzcy5nZXRnaWQoKSkgfHxcbiAgICAgICAgKChzdGF0cy5tb2RlICYgNjQpID4gMCAmJiBzdGF0cy51aWQgPT09IHByb2Nlc3MuZ2V0dWlkKCkpKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlvLXV0aWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgX19hd2FpdGVyID0gKHRoaXMgJiYgdGhpcy5fX2F3YWl0ZXIpIHx8IGZ1bmN0aW9uICh0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcbiAgICBmdW5jdGlvbiBhZG9wdCh2YWx1ZSkgeyByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBQID8gdmFsdWUgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHZhbHVlKTsgfSk7IH1cbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cbiAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xuICAgIH0pO1xufTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNvbnN0IGNoaWxkUHJvY2VzcyA9IHJlcXVpcmUoXCJjaGlsZF9wcm9jZXNzXCIpO1xuY29uc3QgcGF0aCA9IHJlcXVpcmUoXCJwYXRoXCIpO1xuY29uc3QgdXRpbF8xID0gcmVxdWlyZShcInV0aWxcIik7XG5jb25zdCBpb1V0aWwgPSByZXF1aXJlKFwiLi9pby11dGlsXCIpO1xuY29uc3QgZXhlYyA9IHV0aWxfMS5wcm9taXNpZnkoY2hpbGRQcm9jZXNzLmV4ZWMpO1xuLyoqXG4gKiBDb3BpZXMgYSBmaWxlIG9yIGZvbGRlci5cbiAqIEJhc2VkIG9mZiBvZiBzaGVsbGpzIC0gaHR0cHM6Ly9naXRodWIuY29tL3NoZWxsanMvc2hlbGxqcy9ibG9iLzkyMzdmNjZjNTJlNWRhYTQwNDU4Zjk0Zjk1NjVlMThlODEzMmY1YTYvc3JjL2NwLmpzXG4gKlxuICogQHBhcmFtICAgICBzb3VyY2UgICAgc291cmNlIHBhdGhcbiAqIEBwYXJhbSAgICAgZGVzdCAgICAgIGRlc3RpbmF0aW9uIHBhdGhcbiAqIEBwYXJhbSAgICAgb3B0aW9ucyAgIG9wdGlvbmFsLiBTZWUgQ29weU9wdGlvbnMuXG4gKi9cbmZ1bmN0aW9uIGNwKHNvdXJjZSwgZGVzdCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgY29uc3QgeyBmb3JjZSwgcmVjdXJzaXZlIH0gPSByZWFkQ29weU9wdGlvbnMob3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGRlc3RTdGF0ID0gKHlpZWxkIGlvVXRpbC5leGlzdHMoZGVzdCkpID8geWllbGQgaW9VdGlsLnN0YXQoZGVzdCkgOiBudWxsO1xuICAgICAgICAvLyBEZXN0IGlzIGFuIGV4aXN0aW5nIGZpbGUsIGJ1dCBub3QgZm9yY2luZ1xuICAgICAgICBpZiAoZGVzdFN0YXQgJiYgZGVzdFN0YXQuaXNGaWxlKCkgJiYgIWZvcmNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgZGVzdCBpcyBhbiBleGlzdGluZyBkaXJlY3RvcnksIHNob3VsZCBjb3B5IGluc2lkZS5cbiAgICAgICAgY29uc3QgbmV3RGVzdCA9IGRlc3RTdGF0ICYmIGRlc3RTdGF0LmlzRGlyZWN0b3J5KClcbiAgICAgICAgICAgID8gcGF0aC5qb2luKGRlc3QsIHBhdGguYmFzZW5hbWUoc291cmNlKSlcbiAgICAgICAgICAgIDogZGVzdDtcbiAgICAgICAgaWYgKCEoeWllbGQgaW9VdGlsLmV4aXN0cyhzb3VyY2UpKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5OiAke3NvdXJjZX1gKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzb3VyY2VTdGF0ID0geWllbGQgaW9VdGlsLnN0YXQoc291cmNlKTtcbiAgICAgICAgaWYgKHNvdXJjZVN0YXQuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICAgICAgaWYgKCFyZWN1cnNpdmUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBjb3B5LiAke3NvdXJjZX0gaXMgYSBkaXJlY3RvcnksIGJ1dCB0cmllZCB0byBjb3B5IHdpdGhvdXQgcmVjdXJzaXZlIGZsYWcuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB5aWVsZCBjcERpclJlY3Vyc2l2ZShzb3VyY2UsIG5ld0Rlc3QsIDAsIGZvcmNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChwYXRoLnJlbGF0aXZlKHNvdXJjZSwgbmV3RGVzdCkgPT09ICcnKSB7XG4gICAgICAgICAgICAgICAgLy8gYSBmaWxlIGNhbm5vdCBiZSBjb3BpZWQgdG8gaXRzZWxmXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAnJHtuZXdEZXN0fScgYW5kICcke3NvdXJjZX0nIGFyZSB0aGUgc2FtZSBmaWxlYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB5aWVsZCBjb3B5RmlsZShzb3VyY2UsIG5ld0Rlc3QsIGZvcmNlKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuZXhwb3J0cy5jcCA9IGNwO1xuLyoqXG4gKiBNb3ZlcyBhIHBhdGguXG4gKlxuICogQHBhcmFtICAgICBzb3VyY2UgICAgc291cmNlIHBhdGhcbiAqIEBwYXJhbSAgICAgZGVzdCAgICAgIGRlc3RpbmF0aW9uIHBhdGhcbiAqIEBwYXJhbSAgICAgb3B0aW9ucyAgIG9wdGlvbmFsLiBTZWUgTW92ZU9wdGlvbnMuXG4gKi9cbmZ1bmN0aW9uIG12KHNvdXJjZSwgZGVzdCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgaWYgKHlpZWxkIGlvVXRpbC5leGlzdHMoZGVzdCkpIHtcbiAgICAgICAgICAgIGxldCBkZXN0RXhpc3RzID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmICh5aWVsZCBpb1V0aWwuaXNEaXJlY3RvcnkoZGVzdCkpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiBkZXN0IGlzIGRpcmVjdG9yeSBjb3B5IHNyYyBpbnRvIGRlc3RcbiAgICAgICAgICAgICAgICBkZXN0ID0gcGF0aC5qb2luKGRlc3QsIHBhdGguYmFzZW5hbWUoc291cmNlKSk7XG4gICAgICAgICAgICAgICAgZGVzdEV4aXN0cyA9IHlpZWxkIGlvVXRpbC5leGlzdHMoZGVzdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZGVzdEV4aXN0cykge1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmZvcmNlID09IG51bGwgfHwgb3B0aW9ucy5mb3JjZSkge1xuICAgICAgICAgICAgICAgICAgICB5aWVsZCBybVJGKGRlc3QpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEZXN0aW5hdGlvbiBhbHJlYWR5IGV4aXN0cycpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB5aWVsZCBta2RpclAocGF0aC5kaXJuYW1lKGRlc3QpKTtcbiAgICAgICAgeWllbGQgaW9VdGlsLnJlbmFtZShzb3VyY2UsIGRlc3QpO1xuICAgIH0pO1xufVxuZXhwb3J0cy5tdiA9IG12O1xuLyoqXG4gKiBSZW1vdmUgYSBwYXRoIHJlY3Vyc2l2ZWx5IHdpdGggZm9yY2VcbiAqXG4gKiBAcGFyYW0gaW5wdXRQYXRoIHBhdGggdG8gcmVtb3ZlXG4gKi9cbmZ1bmN0aW9uIHJtUkYoaW5wdXRQYXRoKSB7XG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgaWYgKGlvVXRpbC5JU19XSU5ET1dTKSB7XG4gICAgICAgICAgICAvLyBOb2RlIGRvZXNuJ3QgcHJvdmlkZSBhIGRlbGV0ZSBvcGVyYXRpb24sIG9ubHkgYW4gdW5saW5rIGZ1bmN0aW9uLiBUaGlzIG1lYW5zIHRoYXQgaWYgdGhlIGZpbGUgaXMgYmVpbmcgdXNlZCBieSBhbm90aGVyXG4gICAgICAgICAgICAvLyBwcm9ncmFtIChlLmcuIGFudGl2aXJ1cyksIGl0IHdvbid0IGJlIGRlbGV0ZWQuIFRvIGFkZHJlc3MgdGhpcywgd2Ugc2hlbGwgb3V0IHRoZSB3b3JrIHRvIHJkL2RlbC5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHlpZWxkIGlvVXRpbC5pc0RpcmVjdG9yeShpbnB1dFBhdGgsIHRydWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHlpZWxkIGV4ZWMoYHJkIC9zIC9xIFwiJHtpbnB1dFBhdGh9XCJgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHlpZWxkIGV4ZWMoYGRlbCAvZiAvYSBcIiR7aW5wdXRQYXRofVwiYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIC8vIGlmIHlvdSB0cnkgdG8gZGVsZXRlIGEgZmlsZSB0aGF0IGRvZXNuJ3QgZXhpc3QsIGRlc2lyZWQgcmVzdWx0IGlzIGFjaGlldmVkXG4gICAgICAgICAgICAgICAgLy8gb3RoZXIgZXJyb3JzIGFyZSB2YWxpZFxuICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSAhPT0gJ0VOT0VOVCcpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFNoZWxsaW5nIG91dCBmYWlscyB0byByZW1vdmUgYSBzeW1saW5rIGZvbGRlciB3aXRoIG1pc3Npbmcgc291cmNlLCB0aGlzIHVubGluayBjYXRjaGVzIHRoYXRcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgeWllbGQgaW9VdGlsLnVubGluayhpbnB1dFBhdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIC8vIGlmIHlvdSB0cnkgdG8gZGVsZXRlIGEgZmlsZSB0aGF0IGRvZXNuJ3QgZXhpc3QsIGRlc2lyZWQgcmVzdWx0IGlzIGFjaGlldmVkXG4gICAgICAgICAgICAgICAgLy8gb3RoZXIgZXJyb3JzIGFyZSB2YWxpZFxuICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSAhPT0gJ0VOT0VOVCcpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCBpc0RpciA9IGZhbHNlO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpc0RpciA9IHlpZWxkIGlvVXRpbC5pc0RpcmVjdG9yeShpbnB1dFBhdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIC8vIGlmIHlvdSB0cnkgdG8gZGVsZXRlIGEgZmlsZSB0aGF0IGRvZXNuJ3QgZXhpc3QsIGRlc2lyZWQgcmVzdWx0IGlzIGFjaGlldmVkXG4gICAgICAgICAgICAgICAgLy8gb3RoZXIgZXJyb3JzIGFyZSB2YWxpZFxuICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSAhPT0gJ0VOT0VOVCcpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNEaXIpIHtcbiAgICAgICAgICAgICAgICB5aWVsZCBleGVjKGBybSAtcmYgXCIke2lucHV0UGF0aH1cImApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgeWllbGQgaW9VdGlsLnVubGluayhpbnB1dFBhdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG59XG5leHBvcnRzLnJtUkYgPSBybVJGO1xuLyoqXG4gKiBNYWtlIGEgZGlyZWN0b3J5LiAgQ3JlYXRlcyB0aGUgZnVsbCBwYXRoIHdpdGggZm9sZGVycyBpbiBiZXR3ZWVuXG4gKiBXaWxsIHRocm93IGlmIGl0IGZhaWxzXG4gKlxuICogQHBhcmFtICAgZnNQYXRoICAgICAgICBwYXRoIHRvIGNyZWF0ZVxuICogQHJldHVybnMgUHJvbWlzZTx2b2lkPlxuICovXG5mdW5jdGlvbiBta2RpclAoZnNQYXRoKSB7XG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgeWllbGQgaW9VdGlsLm1rZGlyUChmc1BhdGgpO1xuICAgIH0pO1xufVxuZXhwb3J0cy5ta2RpclAgPSBta2RpclA7XG4vKipcbiAqIFJldHVybnMgcGF0aCBvZiBhIHRvb2wgaGFkIHRoZSB0b29sIGFjdHVhbGx5IGJlZW4gaW52b2tlZC4gIFJlc29sdmVzIHZpYSBwYXRocy5cbiAqIElmIHlvdSBjaGVjayBhbmQgdGhlIHRvb2wgZG9lcyBub3QgZXhpc3QsIGl0IHdpbGwgdGhyb3cuXG4gKlxuICogQHBhcmFtICAgICB0b29sICAgICAgICAgICAgICBuYW1lIG9mIHRoZSB0b29sXG4gKiBAcGFyYW0gICAgIGNoZWNrICAgICAgICAgICAgIHdoZXRoZXIgdG8gY2hlY2sgaWYgdG9vbCBleGlzdHNcbiAqIEByZXR1cm5zICAgUHJvbWlzZTxzdHJpbmc+ICAgcGF0aCB0byB0b29sXG4gKi9cbmZ1bmN0aW9uIHdoaWNoKHRvb2wsIGNoZWNrKSB7XG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgaWYgKCF0b29sKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJwYXJhbWV0ZXIgJ3Rvb2wnIGlzIHJlcXVpcmVkXCIpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHJlY3Vyc2l2ZSB3aGVuIGNoZWNrPXRydWVcbiAgICAgICAgaWYgKGNoZWNrKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSB5aWVsZCB3aGljaCh0b29sLCBmYWxzZSk7XG4gICAgICAgICAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgICAgICAgICAgIGlmIChpb1V0aWwuSVNfV0lORE9XUykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBsb2NhdGUgZXhlY3V0YWJsZSBmaWxlOiAke3Rvb2x9LiBQbGVhc2UgdmVyaWZ5IGVpdGhlciB0aGUgZmlsZSBwYXRoIGV4aXN0cyBvciB0aGUgZmlsZSBjYW4gYmUgZm91bmQgd2l0aGluIGEgZGlyZWN0b3J5IHNwZWNpZmllZCBieSB0aGUgUEFUSCBlbnZpcm9ubWVudCB2YXJpYWJsZS4gQWxzbyB2ZXJpZnkgdGhlIGZpbGUgaGFzIGEgdmFsaWQgZXh0ZW5zaW9uIGZvciBhbiBleGVjdXRhYmxlIGZpbGUuYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBsb2NhdGUgZXhlY3V0YWJsZSBmaWxlOiAke3Rvb2x9LiBQbGVhc2UgdmVyaWZ5IGVpdGhlciB0aGUgZmlsZSBwYXRoIGV4aXN0cyBvciB0aGUgZmlsZSBjYW4gYmUgZm91bmQgd2l0aGluIGEgZGlyZWN0b3J5IHNwZWNpZmllZCBieSB0aGUgUEFUSCBlbnZpcm9ubWVudCB2YXJpYWJsZS4gQWxzbyBjaGVjayB0aGUgZmlsZSBtb2RlIHRvIHZlcmlmeSB0aGUgZmlsZSBpcyBleGVjdXRhYmxlLmApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gYnVpbGQgdGhlIGxpc3Qgb2YgZXh0ZW5zaW9ucyB0byB0cnlcbiAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvbnMgPSBbXTtcbiAgICAgICAgICAgIGlmIChpb1V0aWwuSVNfV0lORE9XUyAmJiBwcm9jZXNzLmVudi5QQVRIRVhUKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBleHRlbnNpb24gb2YgcHJvY2Vzcy5lbnYuUEFUSEVYVC5zcGxpdChwYXRoLmRlbGltaXRlcikpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV4dGVuc2lvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9ucy5wdXNoKGV4dGVuc2lvbik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBpZiBpdCdzIHJvb3RlZCwgcmV0dXJuIGl0IGlmIGV4aXN0cy4gb3RoZXJ3aXNlIHJldHVybiBlbXB0eS5cbiAgICAgICAgICAgIGlmIChpb1V0aWwuaXNSb290ZWQodG9vbCkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmaWxlUGF0aCA9IHlpZWxkIGlvVXRpbC50cnlHZXRFeGVjdXRhYmxlUGF0aCh0b29sLCBleHRlbnNpb25zKTtcbiAgICAgICAgICAgICAgICBpZiAoZmlsZVBhdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbGVQYXRoO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gJyc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBpZiBhbnkgcGF0aCBzZXBhcmF0b3JzLCByZXR1cm4gZW1wdHlcbiAgICAgICAgICAgIGlmICh0b29sLmluY2x1ZGVzKCcvJykgfHwgKGlvVXRpbC5JU19XSU5ET1dTICYmIHRvb2wuaW5jbHVkZXMoJ1xcXFwnKSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gJyc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBidWlsZCB0aGUgbGlzdCBvZiBkaXJlY3Rvcmllc1xuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIE5vdGUsIHRlY2huaWNhbGx5IFwid2hlcmVcIiBjaGVja3MgdGhlIGN1cnJlbnQgZGlyZWN0b3J5IG9uIFdpbmRvd3MuIEZyb20gYSB0b29sa2l0IHBlcnNwZWN0aXZlLFxuICAgICAgICAgICAgLy8gaXQgZmVlbHMgbGlrZSB3ZSBzaG91bGQgbm90IGRvIHRoaXMuIENoZWNraW5nIHRoZSBjdXJyZW50IGRpcmVjdG9yeSBzZWVtcyBsaWtlIG1vcmUgb2YgYSB1c2VcbiAgICAgICAgICAgIC8vIGNhc2Ugb2YgYSBzaGVsbCwgYW5kIHRoZSB3aGljaCgpIGZ1bmN0aW9uIGV4cG9zZWQgYnkgdGhlIHRvb2xraXQgc2hvdWxkIHN0cml2ZSBmb3IgY29uc2lzdGVuY3lcbiAgICAgICAgICAgIC8vIGFjcm9zcyBwbGF0Zm9ybXMuXG4gICAgICAgICAgICBjb25zdCBkaXJlY3RvcmllcyA9IFtdO1xuICAgICAgICAgICAgaWYgKHByb2Nlc3MuZW52LlBBVEgpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHAgb2YgcHJvY2Vzcy5lbnYuUEFUSC5zcGxpdChwYXRoLmRlbGltaXRlcikpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdG9yaWVzLnB1c2gocCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyByZXR1cm4gdGhlIGZpcnN0IG1hdGNoXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGRpcmVjdG9yeSBvZiBkaXJlY3Rvcmllcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpbGVQYXRoID0geWllbGQgaW9VdGlsLnRyeUdldEV4ZWN1dGFibGVQYXRoKGRpcmVjdG9yeSArIHBhdGguc2VwICsgdG9vbCwgZXh0ZW5zaW9ucyk7XG4gICAgICAgICAgICAgICAgaWYgKGZpbGVQYXRoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmaWxlUGF0aDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gJyc7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB3aGljaCBmYWlsZWQgd2l0aCBtZXNzYWdlICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbmV4cG9ydHMud2hpY2ggPSB3aGljaDtcbmZ1bmN0aW9uIHJlYWRDb3B5T3B0aW9ucyhvcHRpb25zKSB7XG4gICAgY29uc3QgZm9yY2UgPSBvcHRpb25zLmZvcmNlID09IG51bGwgPyB0cnVlIDogb3B0aW9ucy5mb3JjZTtcbiAgICBjb25zdCByZWN1cnNpdmUgPSBCb29sZWFuKG9wdGlvbnMucmVjdXJzaXZlKTtcbiAgICByZXR1cm4geyBmb3JjZSwgcmVjdXJzaXZlIH07XG59XG5mdW5jdGlvbiBjcERpclJlY3Vyc2l2ZShzb3VyY2VEaXIsIGRlc3REaXIsIGN1cnJlbnREZXB0aCwgZm9yY2UpIHtcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAvLyBFbnN1cmUgdGhlcmUgaXMgbm90IGEgcnVuIGF3YXkgcmVjdXJzaXZlIGNvcHlcbiAgICAgICAgaWYgKGN1cnJlbnREZXB0aCA+PSAyNTUpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGN1cnJlbnREZXB0aCsrO1xuICAgICAgICB5aWVsZCBta2RpclAoZGVzdERpcik7XG4gICAgICAgIGNvbnN0IGZpbGVzID0geWllbGQgaW9VdGlsLnJlYWRkaXIoc291cmNlRGlyKTtcbiAgICAgICAgZm9yIChjb25zdCBmaWxlTmFtZSBvZiBmaWxlcykge1xuICAgICAgICAgICAgY29uc3Qgc3JjRmlsZSA9IGAke3NvdXJjZURpcn0vJHtmaWxlTmFtZX1gO1xuICAgICAgICAgICAgY29uc3QgZGVzdEZpbGUgPSBgJHtkZXN0RGlyfS8ke2ZpbGVOYW1lfWA7XG4gICAgICAgICAgICBjb25zdCBzcmNGaWxlU3RhdCA9IHlpZWxkIGlvVXRpbC5sc3RhdChzcmNGaWxlKTtcbiAgICAgICAgICAgIGlmIChzcmNGaWxlU3RhdC5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgICAgICAgICAgLy8gUmVjdXJzZVxuICAgICAgICAgICAgICAgIHlpZWxkIGNwRGlyUmVjdXJzaXZlKHNyY0ZpbGUsIGRlc3RGaWxlLCBjdXJyZW50RGVwdGgsIGZvcmNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHlpZWxkIGNvcHlGaWxlKHNyY0ZpbGUsIGRlc3RGaWxlLCBmb3JjZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2hhbmdlIHRoZSBtb2RlIGZvciB0aGUgbmV3bHkgY3JlYXRlZCBkaXJlY3RvcnlcbiAgICAgICAgeWllbGQgaW9VdGlsLmNobW9kKGRlc3REaXIsICh5aWVsZCBpb1V0aWwuc3RhdChzb3VyY2VEaXIpKS5tb2RlKTtcbiAgICB9KTtcbn1cbi8vIEJ1ZmZlcmVkIGZpbGUgY29weVxuZnVuY3Rpb24gY29weUZpbGUoc3JjRmlsZSwgZGVzdEZpbGUsIGZvcmNlKSB7XG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgaWYgKCh5aWVsZCBpb1V0aWwubHN0YXQoc3JjRmlsZSkpLmlzU3ltYm9saWNMaW5rKCkpIHtcbiAgICAgICAgICAgIC8vIHVubGluay9yZS1saW5rIGl0XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHlpZWxkIGlvVXRpbC5sc3RhdChkZXN0RmlsZSk7XG4gICAgICAgICAgICAgICAgeWllbGQgaW9VdGlsLnVubGluayhkZXN0RmlsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIC8vIFRyeSB0byBvdmVycmlkZSBmaWxlIHBlcm1pc3Npb25cbiAgICAgICAgICAgICAgICBpZiAoZS5jb2RlID09PSAnRVBFUk0nKSB7XG4gICAgICAgICAgICAgICAgICAgIHlpZWxkIGlvVXRpbC5jaG1vZChkZXN0RmlsZSwgJzA2NjYnKTtcbiAgICAgICAgICAgICAgICAgICAgeWllbGQgaW9VdGlsLnVubGluayhkZXN0RmlsZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIG90aGVyIGVycm9ycyA9IGl0IGRvZXNuJ3QgZXhpc3QsIG5vIHdvcmsgdG8gZG9cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIENvcHkgb3ZlciBzeW1saW5rXG4gICAgICAgICAgICBjb25zdCBzeW1saW5rRnVsbCA9IHlpZWxkIGlvVXRpbC5yZWFkbGluayhzcmNGaWxlKTtcbiAgICAgICAgICAgIHlpZWxkIGlvVXRpbC5zeW1saW5rKHN5bWxpbmtGdWxsLCBkZXN0RmlsZSwgaW9VdGlsLklTX1dJTkRPV1MgPyAnanVuY3Rpb24nIDogbnVsbCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoISh5aWVsZCBpb1V0aWwuZXhpc3RzKGRlc3RGaWxlKSkgfHwgZm9yY2UpIHtcbiAgICAgICAgICAgIHlpZWxkIGlvVXRpbC5jb3B5RmlsZShzcmNGaWxlLCBkZXN0RmlsZSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlvLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xudmFyIF9fYXdhaXRlciA9ICh0aGlzICYmIHRoaXMuX19hd2FpdGVyKSB8fCBmdW5jdGlvbiAodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogYWRvcHQocmVzdWx0LnZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcbiAgICB9KTtcbn07XG52YXIgX19pbXBvcnRTdGFyID0gKHRoaXMgJiYgdGhpcy5fX2ltcG9ydFN0YXIpIHx8IGZ1bmN0aW9uIChtb2QpIHtcbiAgICBpZiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSByZXR1cm4gbW9kO1xuICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICBpZiAobW9kICE9IG51bGwpIGZvciAodmFyIGsgaW4gbW9kKSBpZiAoT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobW9kLCBrKSkgcmVzdWx0W2tdID0gbW9kW2tdO1xuICAgIHJlc3VsdFtcImRlZmF1bHRcIl0gPSBtb2Q7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn07XG52YXIgX19pbXBvcnREZWZhdWx0ID0gKHRoaXMgJiYgdGhpcy5fX2ltcG9ydERlZmF1bHQpIHx8IGZ1bmN0aW9uIChtb2QpIHtcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IFwiZGVmYXVsdFwiOiBtb2QgfTtcbn07XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5jb25zdCBjb3JlID0gX19pbXBvcnRTdGFyKHJlcXVpcmUoXCJAYWN0aW9ucy9jb3JlXCIpKTtcbmNvbnN0IGlvID0gX19pbXBvcnRTdGFyKHJlcXVpcmUoXCJAYWN0aW9ucy9pb1wiKSk7XG5jb25zdCBmcyA9IF9faW1wb3J0U3RhcihyZXF1aXJlKFwiZnNcIikpO1xuY29uc3Qgb3MgPSBfX2ltcG9ydFN0YXIocmVxdWlyZShcIm9zXCIpKTtcbmNvbnN0IHBhdGggPSBfX2ltcG9ydFN0YXIocmVxdWlyZShcInBhdGhcIikpO1xuY29uc3QgaHR0cG0gPSBfX2ltcG9ydFN0YXIocmVxdWlyZShcIkBhY3Rpb25zL2h0dHAtY2xpZW50XCIpKTtcbmNvbnN0IHNlbXZlciA9IF9faW1wb3J0U3RhcihyZXF1aXJlKFwic2VtdmVyXCIpKTtcbmNvbnN0IHY0XzEgPSBfX2ltcG9ydERlZmF1bHQocmVxdWlyZShcInV1aWQvdjRcIikpO1xuY29uc3QgZXhlY18xID0gcmVxdWlyZShcIkBhY3Rpb25zL2V4ZWMvbGliL2V4ZWNcIik7XG5jb25zdCBhc3NlcnRfMSA9IHJlcXVpcmUoXCJhc3NlcnRcIik7XG5jbGFzcyBIVFRQRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgY29uc3RydWN0b3IoaHR0cFN0YXR1c0NvZGUpIHtcbiAgICAgICAgc3VwZXIoYFVuZXhwZWN0ZWQgSFRUUCByZXNwb25zZTogJHtodHRwU3RhdHVzQ29kZX1gKTtcbiAgICAgICAgdGhpcy5odHRwU3RhdHVzQ29kZSA9IGh0dHBTdGF0dXNDb2RlO1xuICAgICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgbmV3LnRhcmdldC5wcm90b3R5cGUpO1xuICAgIH1cbn1cbmV4cG9ydHMuSFRUUEVycm9yID0gSFRUUEVycm9yO1xuY29uc3QgSVNfV0lORE9XUyA9IHByb2Nlc3MucGxhdGZvcm0gPT09ICd3aW4zMic7XG5jb25zdCB1c2VyQWdlbnQgPSAnYWN0aW9ucy90b29sLWNhY2hlJztcbi8vIE9uIGxvYWQgZ3JhYiB0ZW1wIGRpcmVjdG9yeSBhbmQgY2FjaGUgZGlyZWN0b3J5IGFuZCByZW1vdmUgdGhlbSBmcm9tIGVudiAoY3VycmVudGx5IGRvbid0IHdhbnQgdG8gZXhwb3NlIHRoaXMpXG5sZXQgdGVtcERpcmVjdG9yeSA9IHByb2Nlc3MuZW52WydSVU5ORVJfVEVNUCddIHx8ICcnO1xubGV0IGNhY2hlUm9vdCA9IHByb2Nlc3MuZW52WydSVU5ORVJfVE9PTF9DQUNIRSddIHx8ICcnO1xuLy8gSWYgZGlyZWN0b3JpZXMgbm90IGZvdW5kLCBwbGFjZSB0aGVtIGluIGNvbW1vbiB0ZW1wIGxvY2F0aW9uc1xuaWYgKCF0ZW1wRGlyZWN0b3J5IHx8ICFjYWNoZVJvb3QpIHtcbiAgICBsZXQgYmFzZUxvY2F0aW9uO1xuICAgIGlmIChJU19XSU5ET1dTKSB7XG4gICAgICAgIC8vIE9uIHdpbmRvd3MgdXNlIHRoZSBVU0VSUFJPRklMRSBlbnYgdmFyaWFibGVcbiAgICAgICAgYmFzZUxvY2F0aW9uID0gcHJvY2Vzcy5lbnZbJ1VTRVJQUk9GSUxFJ10gfHwgJ0M6XFxcXCc7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ2RhcndpbicpIHtcbiAgICAgICAgICAgIGJhc2VMb2NhdGlvbiA9ICcvVXNlcnMnO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgYmFzZUxvY2F0aW9uID0gJy9ob21lJztcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoIXRlbXBEaXJlY3RvcnkpIHtcbiAgICAgICAgdGVtcERpcmVjdG9yeSA9IHBhdGguam9pbihiYXNlTG9jYXRpb24sICdhY3Rpb25zJywgJ3RlbXAnKTtcbiAgICB9XG4gICAgaWYgKCFjYWNoZVJvb3QpIHtcbiAgICAgICAgY2FjaGVSb290ID0gcGF0aC5qb2luKGJhc2VMb2NhdGlvbiwgJ2FjdGlvbnMnLCAnY2FjaGUnKTtcbiAgICB9XG59XG4vKipcbiAqIERvd25sb2FkIGEgdG9vbCBmcm9tIGFuIHVybCBhbmQgc3RyZWFtIGl0IGludG8gYSBmaWxlXG4gKlxuICogQHBhcmFtIHVybCAgICAgICB1cmwgb2YgdG9vbCB0byBkb3dubG9hZFxuICogQHBhcmFtIGRlc3QgICAgICBwYXRoIHRvIGRvd25sb2FkIHRvb2xcbiAqIEByZXR1cm5zICAgICAgICAgcGF0aCB0byBkb3dubG9hZGVkIHRvb2xcbiAqL1xuZnVuY3Rpb24gZG93bmxvYWRUb29sKHVybCwgZGVzdCkge1xuICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIC8vIFdyYXAgaW4gYSBwcm9taXNlIHNvIHRoYXQgd2UgY2FuIHJlc29sdmUgZnJvbSB3aXRoaW4gc3RyZWFtIGNhbGxiYWNrc1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCBodHRwID0gbmV3IGh0dHBtLkh0dHBDbGllbnQodXNlckFnZW50LCBbXSwge1xuICAgICAgICAgICAgICAgICAgICBhbGxvd1JldHJpZXM6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIG1heFJldHJpZXM6IDNcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBkZXN0ID0gZGVzdCB8fCBwYXRoLmpvaW4odGVtcERpcmVjdG9yeSwgdjRfMS5kZWZhdWx0KCkpO1xuICAgICAgICAgICAgICAgIHlpZWxkIGlvLm1rZGlyUChwYXRoLmRpcm5hbWUoZGVzdCkpO1xuICAgICAgICAgICAgICAgIGNvcmUuZGVidWcoYERvd25sb2FkaW5nICR7dXJsfWApO1xuICAgICAgICAgICAgICAgIGNvcmUuZGVidWcoYERvd25sb2FkaW5nICR7ZGVzdH1gKTtcbiAgICAgICAgICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhkZXN0KSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYERlc3RpbmF0aW9uIGZpbGUgcGF0aCAke2Rlc3R9IGFscmVhZHkgZXhpc3RzYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0geWllbGQgaHR0cC5nZXQodXJsKTtcbiAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UubWVzc2FnZS5zdGF0dXNDb2RlICE9PSAyMDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyID0gbmV3IEhUVFBFcnJvcihyZXNwb25zZS5tZXNzYWdlLnN0YXR1c0NvZGUpO1xuICAgICAgICAgICAgICAgICAgICBjb3JlLmRlYnVnKGBGYWlsZWQgdG8gZG93bmxvYWQgZnJvbSBcIiR7dXJsfVwiLiBDb2RlKCR7cmVzcG9uc2UubWVzc2FnZS5zdGF0dXNDb2RlfSkgTWVzc2FnZSgke3Jlc3BvbnNlLm1lc3NhZ2Uuc3RhdHVzTWVzc2FnZX0pYCk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgZmlsZSA9IGZzLmNyZWF0ZVdyaXRlU3RyZWFtKGRlc3QpO1xuICAgICAgICAgICAgICAgIGZpbGUub24oJ29wZW4nLCAoKSA9PiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSByZXNwb25zZS5tZXNzYWdlLnBpcGUoZmlsZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0ub24oJ2Nsb3NlJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmUuZGVidWcoJ2Rvd25sb2FkIGNvbXBsZXRlJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShkZXN0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvcmUuZGVidWcoYEZhaWxlZCB0byBkb3dubG9hZCBmcm9tIFwiJHt1cmx9XCIuIENvZGUoJHtyZXNwb25zZS5tZXNzYWdlLnN0YXR1c0NvZGV9KSBNZXNzYWdlKCR7cmVzcG9uc2UubWVzc2FnZS5zdGF0dXNNZXNzYWdlfSlgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIGZpbGUub24oJ2Vycm9yJywgZXJyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZmlsZS5lbmQoKTtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pKTtcbiAgICB9KTtcbn1cbmV4cG9ydHMuZG93bmxvYWRUb29sID0gZG93bmxvYWRUb29sO1xuLyoqXG4gKiBFeHRyYWN0IGEgLjd6IGZpbGVcbiAqXG4gKiBAcGFyYW0gZmlsZSAgICAgcGF0aCB0byB0aGUgLjd6IGZpbGVcbiAqIEBwYXJhbSBkZXN0ICAgICBkZXN0aW5hdGlvbiBkaXJlY3RvcnkuIE9wdGlvbmFsLlxuICogQHBhcmFtIF83elBhdGggIHBhdGggdG8gN3pyLmV4ZS4gT3B0aW9uYWwsIGZvciBsb25nIHBhdGggc3VwcG9ydC4gTW9zdCAuN3ogYXJjaGl2ZXMgZG8gbm90IGhhdmUgdGhpc1xuICogcHJvYmxlbS4gSWYgeW91ciAuN3ogYXJjaGl2ZSBjb250YWlucyB2ZXJ5IGxvbmcgcGF0aHMsIHlvdSBjYW4gcGFzcyB0aGUgcGF0aCB0byA3enIuZXhlIHdoaWNoIHdpbGxcbiAqIGdyYWNlZnVsbHkgaGFuZGxlIGxvbmcgcGF0aHMuIEJ5IGRlZmF1bHQgN3pkZWMuZXhlIGlzIHVzZWQgYmVjYXVzZSBpdCBpcyBhIHZlcnkgc21hbGwgcHJvZ3JhbSBhbmQgaXNcbiAqIGJ1bmRsZWQgd2l0aCB0aGUgdG9vbCBsaWIuIEhvd2V2ZXIgaXQgZG9lcyBub3Qgc3VwcG9ydCBsb25nIHBhdGhzLiA3enIuZXhlIGlzIHRoZSByZWR1Y2VkIGNvbW1hbmQgbGluZVxuICogaW50ZXJmYWNlLCBpdCBpcyBzbWFsbGVyIHRoYW4gdGhlIGZ1bGwgY29tbWFuZCBsaW5lIGludGVyZmFjZSwgYW5kIGl0IGRvZXMgc3VwcG9ydCBsb25nIHBhdGhzLiBBdCB0aGVcbiAqIHRpbWUgb2YgdGhpcyB3cml0aW5nLCBpdCBpcyBmcmVlbHkgYXZhaWxhYmxlIGZyb20gdGhlIExaTUEgU0RLIHRoYXQgaXMgYXZhaWxhYmxlIG9uIHRoZSA3emlwIHdlYnNpdGUuXG4gKiBCZSBzdXJlIHRvIGNoZWNrIHRoZSBjdXJyZW50IGxpY2Vuc2UgYWdyZWVtZW50LiBJZiA3enIuZXhlIGlzIGJ1bmRsZWQgd2l0aCB5b3VyIGFjdGlvbiwgdGhlbiB0aGUgcGF0aFxuICogdG8gN3pyLmV4ZSBjYW4gYmUgcGFzcyB0byB0aGlzIGZ1bmN0aW9uLlxuICogQHJldHVybnMgICAgICAgIHBhdGggdG8gdGhlIGRlc3RpbmF0aW9uIGRpcmVjdG9yeVxuICovXG5mdW5jdGlvbiBleHRyYWN0N3ooZmlsZSwgZGVzdCwgXzd6UGF0aCkge1xuICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGFzc2VydF8xLm9rKElTX1dJTkRPV1MsICdleHRyYWN0N3ooKSBub3Qgc3VwcG9ydGVkIG9uIGN1cnJlbnQgT1MnKTtcbiAgICAgICAgYXNzZXJ0XzEub2soZmlsZSwgJ3BhcmFtZXRlciBcImZpbGVcIiBpcyByZXF1aXJlZCcpO1xuICAgICAgICBkZXN0ID0geWllbGQgX2NyZWF0ZUV4dHJhY3RGb2xkZXIoZGVzdCk7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsQ3dkID0gcHJvY2Vzcy5jd2QoKTtcbiAgICAgICAgcHJvY2Vzcy5jaGRpcihkZXN0KTtcbiAgICAgICAgaWYgKF83elBhdGgpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYXJncyA9IFtcbiAgICAgICAgICAgICAgICAgICAgJ3gnLFxuICAgICAgICAgICAgICAgICAgICAnLWJiMScsXG4gICAgICAgICAgICAgICAgICAgICctYmQnLFxuICAgICAgICAgICAgICAgICAgICAnLXNjY1VURi04JyxcbiAgICAgICAgICAgICAgICAgICAgZmlsZVxuICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgc2lsZW50OiB0cnVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB5aWVsZCBleGVjXzEuZXhlYyhgXCIke183elBhdGh9XCJgLCBhcmdzLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHByb2Nlc3MuY2hkaXIob3JpZ2luYWxDd2QpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgZXNjYXBlZFNjcmlwdCA9IHBhdGhcbiAgICAgICAgICAgICAgICAuam9pbihfX2Rpcm5hbWUsICcuLicsICdzY3JpcHRzJywgJ0ludm9rZS03emRlYy5wczEnKVxuICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8nL2csIFwiJydcIilcbiAgICAgICAgICAgICAgICAucmVwbGFjZSgvXCJ8XFxufFxcci9nLCAnJyk7IC8vIGRvdWJsZS11cCBzaW5nbGUgcXVvdGVzLCByZW1vdmUgZG91YmxlIHF1b3RlcyBhbmQgbmV3bGluZXNcbiAgICAgICAgICAgIGNvbnN0IGVzY2FwZWRGaWxlID0gZmlsZS5yZXBsYWNlKC8nL2csIFwiJydcIikucmVwbGFjZSgvXCJ8XFxufFxcci9nLCAnJyk7XG4gICAgICAgICAgICBjb25zdCBlc2NhcGVkVGFyZ2V0ID0gZGVzdC5yZXBsYWNlKC8nL2csIFwiJydcIikucmVwbGFjZSgvXCJ8XFxufFxcci9nLCAnJyk7XG4gICAgICAgICAgICBjb25zdCBjb21tYW5kID0gYCYgJyR7ZXNjYXBlZFNjcmlwdH0nIC1Tb3VyY2UgJyR7ZXNjYXBlZEZpbGV9JyAtVGFyZ2V0ICcke2VzY2FwZWRUYXJnZXR9J2A7XG4gICAgICAgICAgICBjb25zdCBhcmdzID0gW1xuICAgICAgICAgICAgICAgICctTm9Mb2dvJyxcbiAgICAgICAgICAgICAgICAnLVN0YScsXG4gICAgICAgICAgICAgICAgJy1Ob1Byb2ZpbGUnLFxuICAgICAgICAgICAgICAgICctTm9uSW50ZXJhY3RpdmUnLFxuICAgICAgICAgICAgICAgICctRXhlY3V0aW9uUG9saWN5JyxcbiAgICAgICAgICAgICAgICAnVW5yZXN0cmljdGVkJyxcbiAgICAgICAgICAgICAgICAnLUNvbW1hbmQnLFxuICAgICAgICAgICAgICAgIGNvbW1hbmRcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIHNpbGVudDogdHJ1ZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcG93ZXJzaGVsbFBhdGggPSB5aWVsZCBpby53aGljaCgncG93ZXJzaGVsbCcsIHRydWUpO1xuICAgICAgICAgICAgICAgIHlpZWxkIGV4ZWNfMS5leGVjKGBcIiR7cG93ZXJzaGVsbFBhdGh9XCJgLCBhcmdzLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHByb2Nlc3MuY2hkaXIob3JpZ2luYWxDd2QpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkZXN0O1xuICAgIH0pO1xufVxuZXhwb3J0cy5leHRyYWN0N3ogPSBleHRyYWN0N3o7XG4vKipcbiAqIEV4dHJhY3QgYSBjb21wcmVzc2VkIHRhciBhcmNoaXZlXG4gKlxuICogQHBhcmFtIGZpbGUgICAgIHBhdGggdG8gdGhlIHRhclxuICogQHBhcmFtIGRlc3QgICAgIGRlc3RpbmF0aW9uIGRpcmVjdG9yeS4gT3B0aW9uYWwuXG4gKiBAcGFyYW0gZmxhZ3MgICAgZmxhZ3MgZm9yIHRoZSB0YXIgY29tbWFuZCB0byB1c2UgZm9yIGV4dHJhY3Rpb24uIERlZmF1bHRzIHRvICd4eicgKGV4dHJhY3RpbmcgZ3ppcHBlZCB0YXJzKS4gT3B0aW9uYWwuXG4gKiBAcmV0dXJucyAgICAgICAgcGF0aCB0byB0aGUgZGVzdGluYXRpb24gZGlyZWN0b3J5XG4gKi9cbmZ1bmN0aW9uIGV4dHJhY3RUYXIoZmlsZSwgZGVzdCwgZmxhZ3MgPSAneHonKSB7XG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgaWYgKCFmaWxlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJwYXJhbWV0ZXIgJ2ZpbGUnIGlzIHJlcXVpcmVkXCIpO1xuICAgICAgICB9XG4gICAgICAgIC8vIENyZWF0ZSBkZXN0XG4gICAgICAgIGRlc3QgPSB5aWVsZCBfY3JlYXRlRXh0cmFjdEZvbGRlcihkZXN0KTtcbiAgICAgICAgLy8gRGV0ZXJtaW5lIHdoZXRoZXIgR05VIHRhclxuICAgICAgICBsZXQgdmVyc2lvbk91dHB1dCA9ICcnO1xuICAgICAgICB5aWVsZCBleGVjXzEuZXhlYygndGFyIC0tdmVyc2lvbicsIFtdLCB7XG4gICAgICAgICAgICBpZ25vcmVSZXR1cm5Db2RlOiB0cnVlLFxuICAgICAgICAgICAgbGlzdGVuZXJzOiB7XG4gICAgICAgICAgICAgICAgc3Rkb3V0OiAoZGF0YSkgPT4gKHZlcnNpb25PdXRwdXQgKz0gZGF0YS50b1N0cmluZygpKSxcbiAgICAgICAgICAgICAgICBzdGRlcnI6IChkYXRhKSA9PiAodmVyc2lvbk91dHB1dCArPSBkYXRhLnRvU3RyaW5nKCkpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBpc0dudVRhciA9IHZlcnNpb25PdXRwdXQudG9VcHBlckNhc2UoKS5pbmNsdWRlcygnR05VIFRBUicpO1xuICAgICAgICAvLyBJbml0aWFsaXplIGFyZ3NcbiAgICAgICAgY29uc3QgYXJncyA9IFtmbGFnc107XG4gICAgICAgIGxldCBkZXN0QXJnID0gZGVzdDtcbiAgICAgICAgbGV0IGZpbGVBcmcgPSBmaWxlO1xuICAgICAgICBpZiAoSVNfV0lORE9XUyAmJiBpc0dudVRhcikge1xuICAgICAgICAgICAgYXJncy5wdXNoKCctLWZvcmNlLWxvY2FsJyk7XG4gICAgICAgICAgICBkZXN0QXJnID0gZGVzdC5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG4gICAgICAgICAgICAvLyBUZWNobmljYWxseSBvbmx5IHRoZSBkZXN0IG5lZWRzIHRvIGhhdmUgYC9gIGJ1dCBmb3IgYWVzdGhldGljIGNvbnNpc3RlbmN5XG4gICAgICAgICAgICAvLyBjb252ZXJ0IHNsYXNoZXMgaW4gdGhlIGZpbGUgYXJnIHRvby5cbiAgICAgICAgICAgIGZpbGVBcmcgPSBmaWxlLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNHbnVUYXIpIHtcbiAgICAgICAgICAgIC8vIFN1cHByZXNzIHdhcm5pbmdzIHdoZW4gdXNpbmcgR05VIHRhciB0byBleHRyYWN0IGFyY2hpdmVzIGNyZWF0ZWQgYnkgQlNEIHRhclxuICAgICAgICAgICAgYXJncy5wdXNoKCctLXdhcm5pbmc9bm8tdW5rbm93bi1rZXl3b3JkJyk7XG4gICAgICAgIH1cbiAgICAgICAgYXJncy5wdXNoKCctQycsIGRlc3RBcmcsICctZicsIGZpbGVBcmcpO1xuICAgICAgICB5aWVsZCBleGVjXzEuZXhlYyhgdGFyYCwgYXJncyk7XG4gICAgICAgIHJldHVybiBkZXN0O1xuICAgIH0pO1xufVxuZXhwb3J0cy5leHRyYWN0VGFyID0gZXh0cmFjdFRhcjtcbi8qKlxuICogRXh0cmFjdCBhIHppcFxuICpcbiAqIEBwYXJhbSBmaWxlICAgICBwYXRoIHRvIHRoZSB6aXBcbiAqIEBwYXJhbSBkZXN0ICAgICBkZXN0aW5hdGlvbiBkaXJlY3RvcnkuIE9wdGlvbmFsLlxuICogQHJldHVybnMgICAgICAgIHBhdGggdG8gdGhlIGRlc3RpbmF0aW9uIGRpcmVjdG9yeVxuICovXG5mdW5jdGlvbiBleHRyYWN0WmlwKGZpbGUsIGRlc3QpIHtcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICBpZiAoIWZpbGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInBhcmFtZXRlciAnZmlsZScgaXMgcmVxdWlyZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgZGVzdCA9IHlpZWxkIF9jcmVhdGVFeHRyYWN0Rm9sZGVyKGRlc3QpO1xuICAgICAgICBpZiAoSVNfV0lORE9XUykge1xuICAgICAgICAgICAgeWllbGQgZXh0cmFjdFppcFdpbihmaWxlLCBkZXN0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHlpZWxkIGV4dHJhY3RaaXBOaXgoZmlsZSwgZGVzdCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRlc3Q7XG4gICAgfSk7XG59XG5leHBvcnRzLmV4dHJhY3RaaXAgPSBleHRyYWN0WmlwO1xuZnVuY3Rpb24gZXh0cmFjdFppcFdpbihmaWxlLCBkZXN0KSB7XG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgLy8gYnVpbGQgdGhlIHBvd2Vyc2hlbGwgY29tbWFuZFxuICAgICAgICBjb25zdCBlc2NhcGVkRmlsZSA9IGZpbGUucmVwbGFjZSgvJy9nLCBcIicnXCIpLnJlcGxhY2UoL1wifFxcbnxcXHIvZywgJycpOyAvLyBkb3VibGUtdXAgc2luZ2xlIHF1b3RlcywgcmVtb3ZlIGRvdWJsZSBxdW90ZXMgYW5kIG5ld2xpbmVzXG4gICAgICAgIGNvbnN0IGVzY2FwZWREZXN0ID0gZGVzdC5yZXBsYWNlKC8nL2csIFwiJydcIikucmVwbGFjZSgvXCJ8XFxufFxcci9nLCAnJyk7XG4gICAgICAgIGNvbnN0IGNvbW1hbmQgPSBgJEVycm9yQWN0aW9uUHJlZmVyZW5jZSA9ICdTdG9wJyA7IHRyeSB7IEFkZC1UeXBlIC1Bc3NlbWJseU5hbWUgU3lzdGVtLklPLkNvbXByZXNzaW9uLkZpbGVTeXN0ZW0gfSBjYXRjaCB7IH0gOyBbU3lzdGVtLklPLkNvbXByZXNzaW9uLlppcEZpbGVdOjpFeHRyYWN0VG9EaXJlY3RvcnkoJyR7ZXNjYXBlZEZpbGV9JywgJyR7ZXNjYXBlZERlc3R9JylgO1xuICAgICAgICAvLyBydW4gcG93ZXJzaGVsbFxuICAgICAgICBjb25zdCBwb3dlcnNoZWxsUGF0aCA9IHlpZWxkIGlvLndoaWNoKCdwb3dlcnNoZWxsJyk7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSBbXG4gICAgICAgICAgICAnLU5vTG9nbycsXG4gICAgICAgICAgICAnLVN0YScsXG4gICAgICAgICAgICAnLU5vUHJvZmlsZScsXG4gICAgICAgICAgICAnLU5vbkludGVyYWN0aXZlJyxcbiAgICAgICAgICAgICctRXhlY3V0aW9uUG9saWN5JyxcbiAgICAgICAgICAgICdVbnJlc3RyaWN0ZWQnLFxuICAgICAgICAgICAgJy1Db21tYW5kJyxcbiAgICAgICAgICAgIGNvbW1hbmRcbiAgICAgICAgXTtcbiAgICAgICAgeWllbGQgZXhlY18xLmV4ZWMoYFwiJHtwb3dlcnNoZWxsUGF0aH1cImAsIGFyZ3MpO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gZXh0cmFjdFppcE5peChmaWxlLCBkZXN0KSB7XG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgY29uc3QgdW56aXBQYXRoID0geWllbGQgaW8ud2hpY2goJ3VuemlwJyk7XG4gICAgICAgIHlpZWxkIGV4ZWNfMS5leGVjKGBcIiR7dW56aXBQYXRofVwiYCwgW2ZpbGVdLCB7IGN3ZDogZGVzdCB9KTtcbiAgICB9KTtcbn1cbi8qKlxuICogQ2FjaGVzIGEgZGlyZWN0b3J5IGFuZCBpbnN0YWxscyBpdCBpbnRvIHRoZSB0b29sIGNhY2hlRGlyXG4gKlxuICogQHBhcmFtIHNvdXJjZURpciAgICB0aGUgZGlyZWN0b3J5IHRvIGNhY2hlIGludG8gdG9vbHNcbiAqIEBwYXJhbSB0b29sICAgICAgICAgIHRvb2wgbmFtZVxuICogQHBhcmFtIHZlcnNpb24gICAgICAgdmVyc2lvbiBvZiB0aGUgdG9vbC4gIHNlbXZlciBmb3JtYXRcbiAqIEBwYXJhbSBhcmNoICAgICAgICAgIGFyY2hpdGVjdHVyZSBvZiB0aGUgdG9vbC4gIE9wdGlvbmFsLiAgRGVmYXVsdHMgdG8gbWFjaGluZSBhcmNoaXRlY3R1cmVcbiAqL1xuZnVuY3Rpb24gY2FjaGVEaXIoc291cmNlRGlyLCB0b29sLCB2ZXJzaW9uLCBhcmNoKSB7XG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgdmVyc2lvbiA9IHNlbXZlci5jbGVhbih2ZXJzaW9uKSB8fCB2ZXJzaW9uO1xuICAgICAgICBhcmNoID0gYXJjaCB8fCBvcy5hcmNoKCk7XG4gICAgICAgIGNvcmUuZGVidWcoYENhY2hpbmcgdG9vbCAke3Rvb2x9ICR7dmVyc2lvbn0gJHthcmNofWApO1xuICAgICAgICBjb3JlLmRlYnVnKGBzb3VyY2UgZGlyOiAke3NvdXJjZURpcn1gKTtcbiAgICAgICAgaWYgKCFmcy5zdGF0U3luYyhzb3VyY2VEaXIpLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlRGlyIGlzIG5vdCBhIGRpcmVjdG9yeScpO1xuICAgICAgICB9XG4gICAgICAgIC8vIENyZWF0ZSB0aGUgdG9vbCBkaXJcbiAgICAgICAgY29uc3QgZGVzdFBhdGggPSB5aWVsZCBfY3JlYXRlVG9vbFBhdGgodG9vbCwgdmVyc2lvbiwgYXJjaCk7XG4gICAgICAgIC8vIGNvcHkgZWFjaCBjaGlsZCBpdGVtLiBkbyBub3QgbW92ZS4gbW92ZSBjYW4gZmFpbCBvbiBXaW5kb3dzXG4gICAgICAgIC8vIGR1ZSB0byBhbnRpLXZpcnVzIHNvZnR3YXJlIGhhdmluZyBhbiBvcGVuIGhhbmRsZSBvbiBhIGZpbGUuXG4gICAgICAgIGZvciAoY29uc3QgaXRlbU5hbWUgb2YgZnMucmVhZGRpclN5bmMoc291cmNlRGlyKSkge1xuICAgICAgICAgICAgY29uc3QgcyA9IHBhdGguam9pbihzb3VyY2VEaXIsIGl0ZW1OYW1lKTtcbiAgICAgICAgICAgIHlpZWxkIGlvLmNwKHMsIGRlc3RQYXRoLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgICAgfVxuICAgICAgICAvLyB3cml0ZSAuY29tcGxldGVcbiAgICAgICAgX2NvbXBsZXRlVG9vbFBhdGgodG9vbCwgdmVyc2lvbiwgYXJjaCk7XG4gICAgICAgIHJldHVybiBkZXN0UGF0aDtcbiAgICB9KTtcbn1cbmV4cG9ydHMuY2FjaGVEaXIgPSBjYWNoZURpcjtcbi8qKlxuICogQ2FjaGVzIGEgZG93bmxvYWRlZCBmaWxlIChHVUlEKSBhbmQgaW5zdGFsbHMgaXRcbiAqIGludG8gdGhlIHRvb2wgY2FjaGUgd2l0aCBhIGdpdmVuIHRhcmdldE5hbWVcbiAqXG4gKiBAcGFyYW0gc291cmNlRmlsZSAgICB0aGUgZmlsZSB0byBjYWNoZSBpbnRvIHRvb2xzLiAgVHlwaWNhbGx5IGEgcmVzdWx0IG9mIGRvd25sb2FkVG9vbCB3aGljaCBpcyBhIGd1aWQuXG4gKiBAcGFyYW0gdGFyZ2V0RmlsZSAgICB0aGUgbmFtZSBvZiB0aGUgZmlsZSBuYW1lIGluIHRoZSB0b29scyBkaXJlY3RvcnlcbiAqIEBwYXJhbSB0b29sICAgICAgICAgIHRvb2wgbmFtZVxuICogQHBhcmFtIHZlcnNpb24gICAgICAgdmVyc2lvbiBvZiB0aGUgdG9vbC4gIHNlbXZlciBmb3JtYXRcbiAqIEBwYXJhbSBhcmNoICAgICAgICAgIGFyY2hpdGVjdHVyZSBvZiB0aGUgdG9vbC4gIE9wdGlvbmFsLiAgRGVmYXVsdHMgdG8gbWFjaGluZSBhcmNoaXRlY3R1cmVcbiAqL1xuZnVuY3Rpb24gY2FjaGVGaWxlKHNvdXJjZUZpbGUsIHRhcmdldEZpbGUsIHRvb2wsIHZlcnNpb24sIGFyY2gpIHtcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICB2ZXJzaW9uID0gc2VtdmVyLmNsZWFuKHZlcnNpb24pIHx8IHZlcnNpb247XG4gICAgICAgIGFyY2ggPSBhcmNoIHx8IG9zLmFyY2goKTtcbiAgICAgICAgY29yZS5kZWJ1ZyhgQ2FjaGluZyB0b29sICR7dG9vbH0gJHt2ZXJzaW9ufSAke2FyY2h9YCk7XG4gICAgICAgIGNvcmUuZGVidWcoYHNvdXJjZSBmaWxlOiAke3NvdXJjZUZpbGV9YCk7XG4gICAgICAgIGlmICghZnMuc3RhdFN5bmMoc291cmNlRmlsZSkuaXNGaWxlKCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlRmlsZSBpcyBub3QgYSBmaWxlJyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gY3JlYXRlIHRoZSB0b29sIGRpclxuICAgICAgICBjb25zdCBkZXN0Rm9sZGVyID0geWllbGQgX2NyZWF0ZVRvb2xQYXRoKHRvb2wsIHZlcnNpb24sIGFyY2gpO1xuICAgICAgICAvLyBjb3B5IGluc3RlYWQgb2YgbW92ZS4gbW92ZSBjYW4gZmFpbCBvbiBXaW5kb3dzIGR1ZSB0b1xuICAgICAgICAvLyBhbnRpLXZpcnVzIHNvZnR3YXJlIGhhdmluZyBhbiBvcGVuIGhhbmRsZSBvbiBhIGZpbGUuXG4gICAgICAgIGNvbnN0IGRlc3RQYXRoID0gcGF0aC5qb2luKGRlc3RGb2xkZXIsIHRhcmdldEZpbGUpO1xuICAgICAgICBjb3JlLmRlYnVnKGBkZXN0aW5hdGlvbiBmaWxlICR7ZGVzdFBhdGh9YCk7XG4gICAgICAgIHlpZWxkIGlvLmNwKHNvdXJjZUZpbGUsIGRlc3RQYXRoKTtcbiAgICAgICAgLy8gd3JpdGUgLmNvbXBsZXRlXG4gICAgICAgIF9jb21wbGV0ZVRvb2xQYXRoKHRvb2wsIHZlcnNpb24sIGFyY2gpO1xuICAgICAgICByZXR1cm4gZGVzdEZvbGRlcjtcbiAgICB9KTtcbn1cbmV4cG9ydHMuY2FjaGVGaWxlID0gY2FjaGVGaWxlO1xuLyoqXG4gKiBGaW5kcyB0aGUgcGF0aCB0byBhIHRvb2wgdmVyc2lvbiBpbiB0aGUgbG9jYWwgaW5zdGFsbGVkIHRvb2wgY2FjaGVcbiAqXG4gKiBAcGFyYW0gdG9vbE5hbWUgICAgICBuYW1lIG9mIHRoZSB0b29sXG4gKiBAcGFyYW0gdmVyc2lvblNwZWMgICB2ZXJzaW9uIG9mIHRoZSB0b29sXG4gKiBAcGFyYW0gYXJjaCAgICAgICAgICBvcHRpb25hbCBhcmNoLiAgZGVmYXVsdHMgdG8gYXJjaCBvZiBjb21wdXRlclxuICovXG5mdW5jdGlvbiBmaW5kKHRvb2xOYW1lLCB2ZXJzaW9uU3BlYywgYXJjaCkge1xuICAgIGlmICghdG9vbE5hbWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0b29sTmFtZSBwYXJhbWV0ZXIgaXMgcmVxdWlyZWQnKTtcbiAgICB9XG4gICAgaWYgKCF2ZXJzaW9uU3BlYykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3ZlcnNpb25TcGVjIHBhcmFtZXRlciBpcyByZXF1aXJlZCcpO1xuICAgIH1cbiAgICBhcmNoID0gYXJjaCB8fCBvcy5hcmNoKCk7XG4gICAgLy8gYXR0ZW1wdCB0byByZXNvbHZlIGFuIGV4cGxpY2l0IHZlcnNpb25cbiAgICBpZiAoIV9pc0V4cGxpY2l0VmVyc2lvbih2ZXJzaW9uU3BlYykpIHtcbiAgICAgICAgY29uc3QgbG9jYWxWZXJzaW9ucyA9IGZpbmRBbGxWZXJzaW9ucyh0b29sTmFtZSwgYXJjaCk7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gX2V2YWx1YXRlVmVyc2lvbnMobG9jYWxWZXJzaW9ucywgdmVyc2lvblNwZWMpO1xuICAgICAgICB2ZXJzaW9uU3BlYyA9IG1hdGNoO1xuICAgIH1cbiAgICAvLyBjaGVjayBmb3IgdGhlIGV4cGxpY2l0IHZlcnNpb24gaW4gdGhlIGNhY2hlXG4gICAgbGV0IHRvb2xQYXRoID0gJyc7XG4gICAgaWYgKHZlcnNpb25TcGVjKSB7XG4gICAgICAgIHZlcnNpb25TcGVjID0gc2VtdmVyLmNsZWFuKHZlcnNpb25TcGVjKSB8fCAnJztcbiAgICAgICAgY29uc3QgY2FjaGVQYXRoID0gcGF0aC5qb2luKGNhY2hlUm9vdCwgdG9vbE5hbWUsIHZlcnNpb25TcGVjLCBhcmNoKTtcbiAgICAgICAgY29yZS5kZWJ1ZyhgY2hlY2tpbmcgY2FjaGU6ICR7Y2FjaGVQYXRofWApO1xuICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhjYWNoZVBhdGgpICYmIGZzLmV4aXN0c1N5bmMoYCR7Y2FjaGVQYXRofS5jb21wbGV0ZWApKSB7XG4gICAgICAgICAgICBjb3JlLmRlYnVnKGBGb3VuZCB0b29sIGluIGNhY2hlICR7dG9vbE5hbWV9ICR7dmVyc2lvblNwZWN9ICR7YXJjaH1gKTtcbiAgICAgICAgICAgIHRvb2xQYXRoID0gY2FjaGVQYXRoO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29yZS5kZWJ1Zygnbm90IGZvdW5kJyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRvb2xQYXRoO1xufVxuZXhwb3J0cy5maW5kID0gZmluZDtcbi8qKlxuICogRmluZHMgdGhlIHBhdGhzIHRvIGFsbCB2ZXJzaW9ucyBvZiBhIHRvb2wgdGhhdCBhcmUgaW5zdGFsbGVkIGluIHRoZSBsb2NhbCB0b29sIGNhY2hlXG4gKlxuICogQHBhcmFtIHRvb2xOYW1lICBuYW1lIG9mIHRoZSB0b29sXG4gKiBAcGFyYW0gYXJjaCAgICAgIG9wdGlvbmFsIGFyY2guICBkZWZhdWx0cyB0byBhcmNoIG9mIGNvbXB1dGVyXG4gKi9cbmZ1bmN0aW9uIGZpbmRBbGxWZXJzaW9ucyh0b29sTmFtZSwgYXJjaCkge1xuICAgIGNvbnN0IHZlcnNpb25zID0gW107XG4gICAgYXJjaCA9IGFyY2ggfHwgb3MuYXJjaCgpO1xuICAgIGNvbnN0IHRvb2xQYXRoID0gcGF0aC5qb2luKGNhY2hlUm9vdCwgdG9vbE5hbWUpO1xuICAgIGlmIChmcy5leGlzdHNTeW5jKHRvb2xQYXRoKSkge1xuICAgICAgICBjb25zdCBjaGlsZHJlbiA9IGZzLnJlYWRkaXJTeW5jKHRvb2xQYXRoKTtcbiAgICAgICAgZm9yIChjb25zdCBjaGlsZCBvZiBjaGlsZHJlbikge1xuICAgICAgICAgICAgaWYgKF9pc0V4cGxpY2l0VmVyc2lvbihjaGlsZCkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGguam9pbih0b29sUGF0aCwgY2hpbGQsIGFyY2ggfHwgJycpO1xuICAgICAgICAgICAgICAgIGlmIChmcy5leGlzdHNTeW5jKGZ1bGxQYXRoKSAmJiBmcy5leGlzdHNTeW5jKGAke2Z1bGxQYXRofS5jb21wbGV0ZWApKSB7XG4gICAgICAgICAgICAgICAgICAgIHZlcnNpb25zLnB1c2goY2hpbGQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdmVyc2lvbnM7XG59XG5leHBvcnRzLmZpbmRBbGxWZXJzaW9ucyA9IGZpbmRBbGxWZXJzaW9ucztcbmZ1bmN0aW9uIF9jcmVhdGVFeHRyYWN0Rm9sZGVyKGRlc3QpIHtcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICBpZiAoIWRlc3QpIHtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBhIHRlbXAgZGlyXG4gICAgICAgICAgICBkZXN0ID0gcGF0aC5qb2luKHRlbXBEaXJlY3RvcnksIHY0XzEuZGVmYXVsdCgpKTtcbiAgICAgICAgfVxuICAgICAgICB5aWVsZCBpby5ta2RpclAoZGVzdCk7XG4gICAgICAgIHJldHVybiBkZXN0O1xuICAgIH0pO1xufVxuZnVuY3Rpb24gX2NyZWF0ZVRvb2xQYXRoKHRvb2wsIHZlcnNpb24sIGFyY2gpIHtcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICBjb25zdCBmb2xkZXJQYXRoID0gcGF0aC5qb2luKGNhY2hlUm9vdCwgdG9vbCwgc2VtdmVyLmNsZWFuKHZlcnNpb24pIHx8IHZlcnNpb24sIGFyY2ggfHwgJycpO1xuICAgICAgICBjb3JlLmRlYnVnKGBkZXN0aW5hdGlvbiAke2ZvbGRlclBhdGh9YCk7XG4gICAgICAgIGNvbnN0IG1hcmtlclBhdGggPSBgJHtmb2xkZXJQYXRofS5jb21wbGV0ZWA7XG4gICAgICAgIHlpZWxkIGlvLnJtUkYoZm9sZGVyUGF0aCk7XG4gICAgICAgIHlpZWxkIGlvLnJtUkYobWFya2VyUGF0aCk7XG4gICAgICAgIHlpZWxkIGlvLm1rZGlyUChmb2xkZXJQYXRoKTtcbiAgICAgICAgcmV0dXJuIGZvbGRlclBhdGg7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBfY29tcGxldGVUb29sUGF0aCh0b29sLCB2ZXJzaW9uLCBhcmNoKSB7XG4gICAgY29uc3QgZm9sZGVyUGF0aCA9IHBhdGguam9pbihjYWNoZVJvb3QsIHRvb2wsIHNlbXZlci5jbGVhbih2ZXJzaW9uKSB8fCB2ZXJzaW9uLCBhcmNoIHx8ICcnKTtcbiAgICBjb25zdCBtYXJrZXJQYXRoID0gYCR7Zm9sZGVyUGF0aH0uY29tcGxldGVgO1xuICAgIGZzLndyaXRlRmlsZVN5bmMobWFya2VyUGF0aCwgJycpO1xuICAgIGNvcmUuZGVidWcoJ2ZpbmlzaGVkIGNhY2hpbmcgdG9vbCcpO1xufVxuZnVuY3Rpb24gX2lzRXhwbGljaXRWZXJzaW9uKHZlcnNpb25TcGVjKSB7XG4gICAgY29uc3QgYyA9IHNlbXZlci5jbGVhbih2ZXJzaW9uU3BlYykgfHwgJyc7XG4gICAgY29yZS5kZWJ1ZyhgaXNFeHBsaWNpdDogJHtjfWApO1xuICAgIGNvbnN0IHZhbGlkID0gc2VtdmVyLnZhbGlkKGMpICE9IG51bGw7XG4gICAgY29yZS5kZWJ1ZyhgZXhwbGljaXQ/ICR7dmFsaWR9YCk7XG4gICAgcmV0dXJuIHZhbGlkO1xufVxuZnVuY3Rpb24gX2V2YWx1YXRlVmVyc2lvbnModmVyc2lvbnMsIHZlcnNpb25TcGVjKSB7XG4gICAgbGV0IHZlcnNpb24gPSAnJztcbiAgICBjb3JlLmRlYnVnKGBldmFsdWF0aW5nICR7dmVyc2lvbnMubGVuZ3RofSB2ZXJzaW9uc2ApO1xuICAgIHZlcnNpb25zID0gdmVyc2lvbnMuc29ydCgoYSwgYikgPT4ge1xuICAgICAgICBpZiAoc2VtdmVyLmd0KGEsIGIpKSB7XG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfSk7XG4gICAgZm9yIChsZXQgaSA9IHZlcnNpb25zLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGNvbnN0IHBvdGVudGlhbCA9IHZlcnNpb25zW2ldO1xuICAgICAgICBjb25zdCBzYXRpc2ZpZWQgPSBzZW12ZXIuc2F0aXNmaWVzKHBvdGVudGlhbCwgdmVyc2lvblNwZWMpO1xuICAgICAgICBpZiAoc2F0aXNmaWVkKSB7XG4gICAgICAgICAgICB2ZXJzaW9uID0gcG90ZW50aWFsO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKHZlcnNpb24pIHtcbiAgICAgICAgY29yZS5kZWJ1ZyhgbWF0Y2hlZDogJHt2ZXJzaW9ufWApO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgY29yZS5kZWJ1ZygnbWF0Y2ggbm90IGZvdW5kJyk7XG4gICAgfVxuICAgIHJldHVybiB2ZXJzaW9uO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dG9vbC1jYWNoZS5qcy5tYXAiLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBTZW1WZXJcblxudmFyIGRlYnVnXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuaWYgKHR5cGVvZiBwcm9jZXNzID09PSAnb2JqZWN0JyAmJlxuICAgIHByb2Nlc3MuZW52ICYmXG4gICAgcHJvY2Vzcy5lbnYuTk9ERV9ERUJVRyAmJlxuICAgIC9cXGJzZW12ZXJcXGIvaS50ZXN0KHByb2Nlc3MuZW52Lk5PREVfREVCVUcpKSB7XG4gIGRlYnVnID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKVxuICAgIGFyZ3MudW5zaGlmdCgnU0VNVkVSJylcbiAgICBjb25zb2xlLmxvZy5hcHBseShjb25zb2xlLCBhcmdzKVxuICB9XG59IGVsc2Uge1xuICBkZWJ1ZyA9IGZ1bmN0aW9uICgpIHt9XG59XG5cbi8vIE5vdGU6IHRoaXMgaXMgdGhlIHNlbXZlci5vcmcgdmVyc2lvbiBvZiB0aGUgc3BlYyB0aGF0IGl0IGltcGxlbWVudHNcbi8vIE5vdCBuZWNlc3NhcmlseSB0aGUgcGFja2FnZSB2ZXJzaW9uIG9mIHRoaXMgY29kZS5cbmV4cG9ydHMuU0VNVkVSX1NQRUNfVkVSU0lPTiA9ICcyLjAuMCdcblxudmFyIE1BWF9MRU5HVEggPSAyNTZcbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIgfHxcbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gOTAwNzE5OTI1NDc0MDk5MVxuXG4vLyBNYXggc2FmZSBzZWdtZW50IGxlbmd0aCBmb3IgY29lcmNpb24uXG52YXIgTUFYX1NBRkVfQ09NUE9ORU5UX0xFTkdUSCA9IDE2XG5cbi8vIFRoZSBhY3R1YWwgcmVnZXhwcyBnbyBvbiBleHBvcnRzLnJlXG52YXIgcmUgPSBleHBvcnRzLnJlID0gW11cbnZhciBzcmMgPSBleHBvcnRzLnNyYyA9IFtdXG52YXIgdCA9IGV4cG9ydHMudG9rZW5zID0ge31cbnZhciBSID0gMFxuXG5mdW5jdGlvbiB0b2sgKG4pIHtcbiAgdFtuXSA9IFIrK1xufVxuXG4vLyBUaGUgZm9sbG93aW5nIFJlZ3VsYXIgRXhwcmVzc2lvbnMgY2FuIGJlIHVzZWQgZm9yIHRva2VuaXppbmcsXG4vLyB2YWxpZGF0aW5nLCBhbmQgcGFyc2luZyBTZW1WZXIgdmVyc2lvbiBzdHJpbmdzLlxuXG4vLyAjIyBOdW1lcmljIElkZW50aWZpZXJcbi8vIEEgc2luZ2xlIGAwYCwgb3IgYSBub24temVybyBkaWdpdCBmb2xsb3dlZCBieSB6ZXJvIG9yIG1vcmUgZGlnaXRzLlxuXG50b2soJ05VTUVSSUNJREVOVElGSUVSJylcbnNyY1t0Lk5VTUVSSUNJREVOVElGSUVSXSA9ICcwfFsxLTldXFxcXGQqJ1xudG9rKCdOVU1FUklDSURFTlRJRklFUkxPT1NFJylcbnNyY1t0Lk5VTUVSSUNJREVOVElGSUVSTE9PU0VdID0gJ1swLTldKydcblxuLy8gIyMgTm9uLW51bWVyaWMgSWRlbnRpZmllclxuLy8gWmVybyBvciBtb3JlIGRpZ2l0cywgZm9sbG93ZWQgYnkgYSBsZXR0ZXIgb3IgaHlwaGVuLCBhbmQgdGhlbiB6ZXJvIG9yXG4vLyBtb3JlIGxldHRlcnMsIGRpZ2l0cywgb3IgaHlwaGVucy5cblxudG9rKCdOT05OVU1FUklDSURFTlRJRklFUicpXG5zcmNbdC5OT05OVU1FUklDSURFTlRJRklFUl0gPSAnXFxcXGQqW2EtekEtWi1dW2EtekEtWjAtOS1dKidcblxuLy8gIyMgTWFpbiBWZXJzaW9uXG4vLyBUaHJlZSBkb3Qtc2VwYXJhdGVkIG51bWVyaWMgaWRlbnRpZmllcnMuXG5cbnRvaygnTUFJTlZFUlNJT04nKVxuc3JjW3QuTUFJTlZFUlNJT05dID0gJygnICsgc3JjW3QuTlVNRVJJQ0lERU5USUZJRVJdICsgJylcXFxcLicgK1xuICAgICAgICAgICAgICAgICAgICcoJyArIHNyY1t0Lk5VTUVSSUNJREVOVElGSUVSXSArICcpXFxcXC4nICtcbiAgICAgICAgICAgICAgICAgICAnKCcgKyBzcmNbdC5OVU1FUklDSURFTlRJRklFUl0gKyAnKSdcblxudG9rKCdNQUlOVkVSU0lPTkxPT1NFJylcbnNyY1t0Lk1BSU5WRVJTSU9OTE9PU0VdID0gJygnICsgc3JjW3QuTlVNRVJJQ0lERU5USUZJRVJMT09TRV0gKyAnKVxcXFwuJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKCcgKyBzcmNbdC5OVU1FUklDSURFTlRJRklFUkxPT1NFXSArICcpXFxcXC4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcoJyArIHNyY1t0Lk5VTUVSSUNJREVOVElGSUVSTE9PU0VdICsgJyknXG5cbi8vICMjIFByZS1yZWxlYXNlIFZlcnNpb24gSWRlbnRpZmllclxuLy8gQSBudW1lcmljIGlkZW50aWZpZXIsIG9yIGEgbm9uLW51bWVyaWMgaWRlbnRpZmllci5cblxudG9rKCdQUkVSRUxFQVNFSURFTlRJRklFUicpXG5zcmNbdC5QUkVSRUxFQVNFSURFTlRJRklFUl0gPSAnKD86JyArIHNyY1t0Lk5VTUVSSUNJREVOVElGSUVSXSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3wnICsgc3JjW3QuTk9OTlVNRVJJQ0lERU5USUZJRVJdICsgJyknXG5cbnRvaygnUFJFUkVMRUFTRUlERU5USUZJRVJMT09TRScpXG5zcmNbdC5QUkVSRUxFQVNFSURFTlRJRklFUkxPT1NFXSA9ICcoPzonICsgc3JjW3QuTlVNRVJJQ0lERU5USUZJRVJMT09TRV0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3wnICsgc3JjW3QuTk9OTlVNRVJJQ0lERU5USUZJRVJdICsgJyknXG5cbi8vICMjIFByZS1yZWxlYXNlIFZlcnNpb25cbi8vIEh5cGhlbiwgZm9sbG93ZWQgYnkgb25lIG9yIG1vcmUgZG90LXNlcGFyYXRlZCBwcmUtcmVsZWFzZSB2ZXJzaW9uXG4vLyBpZGVudGlmaWVycy5cblxudG9rKCdQUkVSRUxFQVNFJylcbnNyY1t0LlBSRVJFTEVBU0VdID0gJyg/Oi0oJyArIHNyY1t0LlBSRVJFTEVBU0VJREVOVElGSUVSXSArXG4gICAgICAgICAgICAgICAgICAnKD86XFxcXC4nICsgc3JjW3QuUFJFUkVMRUFTRUlERU5USUZJRVJdICsgJykqKSknXG5cbnRvaygnUFJFUkVMRUFTRUxPT1NFJylcbnNyY1t0LlBSRVJFTEVBU0VMT09TRV0gPSAnKD86LT8oJyArIHNyY1t0LlBSRVJFTEVBU0VJREVOVElGSUVSTE9PU0VdICtcbiAgICAgICAgICAgICAgICAgICAgICAgJyg/OlxcXFwuJyArIHNyY1t0LlBSRVJFTEVBU0VJREVOVElGSUVSTE9PU0VdICsgJykqKSknXG5cbi8vICMjIEJ1aWxkIE1ldGFkYXRhIElkZW50aWZpZXJcbi8vIEFueSBjb21iaW5hdGlvbiBvZiBkaWdpdHMsIGxldHRlcnMsIG9yIGh5cGhlbnMuXG5cbnRvaygnQlVJTERJREVOVElGSUVSJylcbnNyY1t0LkJVSUxESURFTlRJRklFUl0gPSAnWzAtOUEtWmEtei1dKydcblxuLy8gIyMgQnVpbGQgTWV0YWRhdGFcbi8vIFBsdXMgc2lnbiwgZm9sbG93ZWQgYnkgb25lIG9yIG1vcmUgcGVyaW9kLXNlcGFyYXRlZCBidWlsZCBtZXRhZGF0YVxuLy8gaWRlbnRpZmllcnMuXG5cbnRvaygnQlVJTEQnKVxuc3JjW3QuQlVJTERdID0gJyg/OlxcXFwrKCcgKyBzcmNbdC5CVUlMRElERU5USUZJRVJdICtcbiAgICAgICAgICAgICAnKD86XFxcXC4nICsgc3JjW3QuQlVJTERJREVOVElGSUVSXSArICcpKikpJ1xuXG4vLyAjIyBGdWxsIFZlcnNpb24gU3RyaW5nXG4vLyBBIG1haW4gdmVyc2lvbiwgZm9sbG93ZWQgb3B0aW9uYWxseSBieSBhIHByZS1yZWxlYXNlIHZlcnNpb24gYW5kXG4vLyBidWlsZCBtZXRhZGF0YS5cblxuLy8gTm90ZSB0aGF0IHRoZSBvbmx5IG1ham9yLCBtaW5vciwgcGF0Y2gsIGFuZCBwcmUtcmVsZWFzZSBzZWN0aW9ucyBvZlxuLy8gdGhlIHZlcnNpb24gc3RyaW5nIGFyZSBjYXB0dXJpbmcgZ3JvdXBzLiAgVGhlIGJ1aWxkIG1ldGFkYXRhIGlzIG5vdCBhXG4vLyBjYXB0dXJpbmcgZ3JvdXAsIGJlY2F1c2UgaXQgc2hvdWxkIG5vdCBldmVyIGJlIHVzZWQgaW4gdmVyc2lvblxuLy8gY29tcGFyaXNvbi5cblxudG9rKCdGVUxMJylcbnRvaygnRlVMTFBMQUlOJylcbnNyY1t0LkZVTExQTEFJTl0gPSAndj8nICsgc3JjW3QuTUFJTlZFUlNJT05dICtcbiAgICAgICAgICAgICAgICAgIHNyY1t0LlBSRVJFTEVBU0VdICsgJz8nICtcbiAgICAgICAgICAgICAgICAgIHNyY1t0LkJVSUxEXSArICc/J1xuXG5zcmNbdC5GVUxMXSA9ICdeJyArIHNyY1t0LkZVTExQTEFJTl0gKyAnJCdcblxuLy8gbGlrZSBmdWxsLCBidXQgYWxsb3dzIHYxLjIuMyBhbmQgPTEuMi4zLCB3aGljaCBwZW9wbGUgZG8gc29tZXRpbWVzLlxuLy8gYWxzbywgMS4wLjBhbHBoYTEgKHByZXJlbGVhc2Ugd2l0aG91dCB0aGUgaHlwaGVuKSB3aGljaCBpcyBwcmV0dHlcbi8vIGNvbW1vbiBpbiB0aGUgbnBtIHJlZ2lzdHJ5LlxudG9rKCdMT09TRVBMQUlOJylcbnNyY1t0LkxPT1NFUExBSU5dID0gJ1t2PVxcXFxzXSonICsgc3JjW3QuTUFJTlZFUlNJT05MT09TRV0gK1xuICAgICAgICAgICAgICAgICAgc3JjW3QuUFJFUkVMRUFTRUxPT1NFXSArICc/JyArXG4gICAgICAgICAgICAgICAgICBzcmNbdC5CVUlMRF0gKyAnPydcblxudG9rKCdMT09TRScpXG5zcmNbdC5MT09TRV0gPSAnXicgKyBzcmNbdC5MT09TRVBMQUlOXSArICckJ1xuXG50b2soJ0dUTFQnKVxuc3JjW3QuR1RMVF0gPSAnKCg/Ojx8Pik/PT8pJ1xuXG4vLyBTb21ldGhpbmcgbGlrZSBcIjIuKlwiIG9yIFwiMS4yLnhcIi5cbi8vIE5vdGUgdGhhdCBcIngueFwiIGlzIGEgdmFsaWQgeFJhbmdlIGlkZW50aWZlciwgbWVhbmluZyBcImFueSB2ZXJzaW9uXCJcbi8vIE9ubHkgdGhlIGZpcnN0IGl0ZW0gaXMgc3RyaWN0bHkgcmVxdWlyZWQuXG50b2soJ1hSQU5HRUlERU5USUZJRVJMT09TRScpXG5zcmNbdC5YUkFOR0VJREVOVElGSUVSTE9PU0VdID0gc3JjW3QuTlVNRVJJQ0lERU5USUZJRVJMT09TRV0gKyAnfHh8WHxcXFxcKidcbnRvaygnWFJBTkdFSURFTlRJRklFUicpXG5zcmNbdC5YUkFOR0VJREVOVElGSUVSXSA9IHNyY1t0Lk5VTUVSSUNJREVOVElGSUVSXSArICd8eHxYfFxcXFwqJ1xuXG50b2soJ1hSQU5HRVBMQUlOJylcbnNyY1t0LlhSQU5HRVBMQUlOXSA9ICdbdj1cXFxcc10qKCcgKyBzcmNbdC5YUkFOR0VJREVOVElGSUVSXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgJyg/OlxcXFwuKCcgKyBzcmNbdC5YUkFOR0VJREVOVElGSUVSXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgJyg/OlxcXFwuKCcgKyBzcmNbdC5YUkFOR0VJREVOVElGSUVSXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgJyg/OicgKyBzcmNbdC5QUkVSRUxFQVNFXSArICcpPycgK1xuICAgICAgICAgICAgICAgICAgIHNyY1t0LkJVSUxEXSArICc/JyArXG4gICAgICAgICAgICAgICAgICAgJyk/KT8nXG5cbnRvaygnWFJBTkdFUExBSU5MT09TRScpXG5zcmNbdC5YUkFOR0VQTEFJTkxPT1NFXSA9ICdbdj1cXFxcc10qKCcgKyBzcmNbdC5YUkFOR0VJREVOVElGSUVSTE9PU0VdICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcoPzpcXFxcLignICsgc3JjW3QuWFJBTkdFSURFTlRJRklFUkxPT1NFXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKD86XFxcXC4oJyArIHNyY1t0LlhSQU5HRUlERU5USUZJRVJMT09TRV0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJyg/OicgKyBzcmNbdC5QUkVSRUxFQVNFTE9PU0VdICsgJyk/JyArXG4gICAgICAgICAgICAgICAgICAgICAgICBzcmNbdC5CVUlMRF0gKyAnPycgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJyk/KT8nXG5cbnRvaygnWFJBTkdFJylcbnNyY1t0LlhSQU5HRV0gPSAnXicgKyBzcmNbdC5HVExUXSArICdcXFxccyonICsgc3JjW3QuWFJBTkdFUExBSU5dICsgJyQnXG50b2soJ1hSQU5HRUxPT1NFJylcbnNyY1t0LlhSQU5HRUxPT1NFXSA9ICdeJyArIHNyY1t0LkdUTFRdICsgJ1xcXFxzKicgKyBzcmNbdC5YUkFOR0VQTEFJTkxPT1NFXSArICckJ1xuXG4vLyBDb2VyY2lvbi5cbi8vIEV4dHJhY3QgYW55dGhpbmcgdGhhdCBjb3VsZCBjb25jZWl2YWJseSBiZSBhIHBhcnQgb2YgYSB2YWxpZCBzZW12ZXJcbnRvaygnQ09FUkNFJylcbnNyY1t0LkNPRVJDRV0gPSAnKF58W15cXFxcZF0pJyArXG4gICAgICAgICAgICAgICcoXFxcXGR7MSwnICsgTUFYX1NBRkVfQ09NUE9ORU5UX0xFTkdUSCArICd9KScgK1xuICAgICAgICAgICAgICAnKD86XFxcXC4oXFxcXGR7MSwnICsgTUFYX1NBRkVfQ09NUE9ORU5UX0xFTkdUSCArICd9KSk/JyArXG4gICAgICAgICAgICAgICcoPzpcXFxcLihcXFxcZHsxLCcgKyBNQVhfU0FGRV9DT01QT05FTlRfTEVOR1RIICsgJ30pKT8nICtcbiAgICAgICAgICAgICAgJyg/OiR8W15cXFxcZF0pJ1xudG9rKCdDT0VSQ0VSVEwnKVxucmVbdC5DT0VSQ0VSVExdID0gbmV3IFJlZ0V4cChzcmNbdC5DT0VSQ0VdLCAnZycpXG5cbi8vIFRpbGRlIHJhbmdlcy5cbi8vIE1lYW5pbmcgaXMgXCJyZWFzb25hYmx5IGF0IG9yIGdyZWF0ZXIgdGhhblwiXG50b2soJ0xPTkVUSUxERScpXG5zcmNbdC5MT05FVElMREVdID0gJyg/On4+PyknXG5cbnRvaygnVElMREVUUklNJylcbnNyY1t0LlRJTERFVFJJTV0gPSAnKFxcXFxzKiknICsgc3JjW3QuTE9ORVRJTERFXSArICdcXFxccysnXG5yZVt0LlRJTERFVFJJTV0gPSBuZXcgUmVnRXhwKHNyY1t0LlRJTERFVFJJTV0sICdnJylcbnZhciB0aWxkZVRyaW1SZXBsYWNlID0gJyQxfidcblxudG9rKCdUSUxERScpXG5zcmNbdC5USUxERV0gPSAnXicgKyBzcmNbdC5MT05FVElMREVdICsgc3JjW3QuWFJBTkdFUExBSU5dICsgJyQnXG50b2soJ1RJTERFTE9PU0UnKVxuc3JjW3QuVElMREVMT09TRV0gPSAnXicgKyBzcmNbdC5MT05FVElMREVdICsgc3JjW3QuWFJBTkdFUExBSU5MT09TRV0gKyAnJCdcblxuLy8gQ2FyZXQgcmFuZ2VzLlxuLy8gTWVhbmluZyBpcyBcImF0IGxlYXN0IGFuZCBiYWNrd2FyZHMgY29tcGF0aWJsZSB3aXRoXCJcbnRvaygnTE9ORUNBUkVUJylcbnNyY1t0LkxPTkVDQVJFVF0gPSAnKD86XFxcXF4pJ1xuXG50b2soJ0NBUkVUVFJJTScpXG5zcmNbdC5DQVJFVFRSSU1dID0gJyhcXFxccyopJyArIHNyY1t0LkxPTkVDQVJFVF0gKyAnXFxcXHMrJ1xucmVbdC5DQVJFVFRSSU1dID0gbmV3IFJlZ0V4cChzcmNbdC5DQVJFVFRSSU1dLCAnZycpXG52YXIgY2FyZXRUcmltUmVwbGFjZSA9ICckMV4nXG5cbnRvaygnQ0FSRVQnKVxuc3JjW3QuQ0FSRVRdID0gJ14nICsgc3JjW3QuTE9ORUNBUkVUXSArIHNyY1t0LlhSQU5HRVBMQUlOXSArICckJ1xudG9rKCdDQVJFVExPT1NFJylcbnNyY1t0LkNBUkVUTE9PU0VdID0gJ14nICsgc3JjW3QuTE9ORUNBUkVUXSArIHNyY1t0LlhSQU5HRVBMQUlOTE9PU0VdICsgJyQnXG5cbi8vIEEgc2ltcGxlIGd0L2x0L2VxIHRoaW5nLCBvciBqdXN0IFwiXCIgdG8gaW5kaWNhdGUgXCJhbnkgdmVyc2lvblwiXG50b2soJ0NPTVBBUkFUT1JMT09TRScpXG5zcmNbdC5DT01QQVJBVE9STE9PU0VdID0gJ14nICsgc3JjW3QuR1RMVF0gKyAnXFxcXHMqKCcgKyBzcmNbdC5MT09TRVBMQUlOXSArICcpJHxeJCdcbnRvaygnQ09NUEFSQVRPUicpXG5zcmNbdC5DT01QQVJBVE9SXSA9ICdeJyArIHNyY1t0LkdUTFRdICsgJ1xcXFxzKignICsgc3JjW3QuRlVMTFBMQUlOXSArICcpJHxeJCdcblxuLy8gQW4gZXhwcmVzc2lvbiB0byBzdHJpcCBhbnkgd2hpdGVzcGFjZSBiZXR3ZWVuIHRoZSBndGx0IGFuZCB0aGUgdGhpbmdcbi8vIGl0IG1vZGlmaWVzLCBzbyB0aGF0IGA+IDEuMi4zYCA9PT4gYD4xLjIuM2BcbnRvaygnQ09NUEFSQVRPUlRSSU0nKVxuc3JjW3QuQ09NUEFSQVRPUlRSSU1dID0gJyhcXFxccyopJyArIHNyY1t0LkdUTFRdICtcbiAgICAgICAgICAgICAgICAgICAgICAnXFxcXHMqKCcgKyBzcmNbdC5MT09TRVBMQUlOXSArICd8JyArIHNyY1t0LlhSQU5HRVBMQUlOXSArICcpJ1xuXG4vLyB0aGlzIG9uZSBoYXMgdG8gdXNlIHRoZSAvZyBmbGFnXG5yZVt0LkNPTVBBUkFUT1JUUklNXSA9IG5ldyBSZWdFeHAoc3JjW3QuQ09NUEFSQVRPUlRSSU1dLCAnZycpXG52YXIgY29tcGFyYXRvclRyaW1SZXBsYWNlID0gJyQxJDIkMydcblxuLy8gU29tZXRoaW5nIGxpa2UgYDEuMi4zIC0gMS4yLjRgXG4vLyBOb3RlIHRoYXQgdGhlc2UgYWxsIHVzZSB0aGUgbG9vc2UgZm9ybSwgYmVjYXVzZSB0aGV5J2xsIGJlXG4vLyBjaGVja2VkIGFnYWluc3QgZWl0aGVyIHRoZSBzdHJpY3Qgb3IgbG9vc2UgY29tcGFyYXRvciBmb3JtXG4vLyBsYXRlci5cbnRvaygnSFlQSEVOUkFOR0UnKVxuc3JjW3QuSFlQSEVOUkFOR0VdID0gJ15cXFxccyooJyArIHNyY1t0LlhSQU5HRVBMQUlOXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgJ1xcXFxzKy1cXFxccysnICtcbiAgICAgICAgICAgICAgICAgICAnKCcgKyBzcmNbdC5YUkFOR0VQTEFJTl0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICdcXFxccyokJ1xuXG50b2soJ0hZUEhFTlJBTkdFTE9PU0UnKVxuc3JjW3QuSFlQSEVOUkFOR0VMT09TRV0gPSAnXlxcXFxzKignICsgc3JjW3QuWFJBTkdFUExBSU5MT09TRV0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJ1xcXFxzKy1cXFxccysnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcoJyArIHNyY1t0LlhSQU5HRVBMQUlOTE9PU0VdICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAgICAgICdcXFxccyokJ1xuXG4vLyBTdGFyIHJhbmdlcyBiYXNpY2FsbHkganVzdCBhbGxvdyBhbnl0aGluZyBhdCBhbGwuXG50b2soJ1NUQVInKVxuc3JjW3QuU1RBUl0gPSAnKDx8Pik/PT9cXFxccypcXFxcKidcblxuLy8gQ29tcGlsZSB0byBhY3R1YWwgcmVnZXhwIG9iamVjdHMuXG4vLyBBbGwgYXJlIGZsYWctZnJlZSwgdW5sZXNzIHRoZXkgd2VyZSBjcmVhdGVkIGFib3ZlIHdpdGggYSBmbGFnLlxuZm9yICh2YXIgaSA9IDA7IGkgPCBSOyBpKyspIHtcbiAgZGVidWcoaSwgc3JjW2ldKVxuICBpZiAoIXJlW2ldKSB7XG4gICAgcmVbaV0gPSBuZXcgUmVnRXhwKHNyY1tpXSlcbiAgfVxufVxuXG5leHBvcnRzLnBhcnNlID0gcGFyc2VcbmZ1bmN0aW9uIHBhcnNlICh2ZXJzaW9uLCBvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucyB8fCB0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgbG9vc2U6ICEhb3B0aW9ucyxcbiAgICAgIGluY2x1ZGVQcmVyZWxlYXNlOiBmYWxzZVxuICAgIH1cbiAgfVxuXG4gIGlmICh2ZXJzaW9uIGluc3RhbmNlb2YgU2VtVmVyKSB7XG4gICAgcmV0dXJuIHZlcnNpb25cbiAgfVxuXG4gIGlmICh0eXBlb2YgdmVyc2lvbiAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgaWYgKHZlcnNpb24ubGVuZ3RoID4gTUFYX0xFTkdUSCkge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICB2YXIgciA9IG9wdGlvbnMubG9vc2UgPyByZVt0LkxPT1NFXSA6IHJlW3QuRlVMTF1cbiAgaWYgKCFyLnRlc3QodmVyc2lvbikpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gbmV3IFNlbVZlcih2ZXJzaW9uLCBvcHRpb25zKVxuICB9IGNhdGNoIChlcikge1xuICAgIHJldHVybiBudWxsXG4gIH1cbn1cblxuZXhwb3J0cy52YWxpZCA9IHZhbGlkXG5mdW5jdGlvbiB2YWxpZCAodmVyc2lvbiwgb3B0aW9ucykge1xuICB2YXIgdiA9IHBhcnNlKHZlcnNpb24sIG9wdGlvbnMpXG4gIHJldHVybiB2ID8gdi52ZXJzaW9uIDogbnVsbFxufVxuXG5leHBvcnRzLmNsZWFuID0gY2xlYW5cbmZ1bmN0aW9uIGNsZWFuICh2ZXJzaW9uLCBvcHRpb25zKSB7XG4gIHZhciBzID0gcGFyc2UodmVyc2lvbi50cmltKCkucmVwbGFjZSgvXls9dl0rLywgJycpLCBvcHRpb25zKVxuICByZXR1cm4gcyA/IHMudmVyc2lvbiA6IG51bGxcbn1cblxuZXhwb3J0cy5TZW1WZXIgPSBTZW1WZXJcblxuZnVuY3Rpb24gU2VtVmVyICh2ZXJzaW9uLCBvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucyB8fCB0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgbG9vc2U6ICEhb3B0aW9ucyxcbiAgICAgIGluY2x1ZGVQcmVyZWxlYXNlOiBmYWxzZVxuICAgIH1cbiAgfVxuICBpZiAodmVyc2lvbiBpbnN0YW5jZW9mIFNlbVZlcikge1xuICAgIGlmICh2ZXJzaW9uLmxvb3NlID09PSBvcHRpb25zLmxvb3NlKSB7XG4gICAgICByZXR1cm4gdmVyc2lvblxuICAgIH0gZWxzZSB7XG4gICAgICB2ZXJzaW9uID0gdmVyc2lvbi52ZXJzaW9uXG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2ZXJzaW9uICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgVmVyc2lvbjogJyArIHZlcnNpb24pXG4gIH1cblxuICBpZiAodmVyc2lvbi5sZW5ndGggPiBNQVhfTEVOR1RIKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmVyc2lvbiBpcyBsb25nZXIgdGhhbiAnICsgTUFYX0xFTkdUSCArICcgY2hhcmFjdGVycycpXG4gIH1cblxuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU2VtVmVyKSkge1xuICAgIHJldHVybiBuZXcgU2VtVmVyKHZlcnNpb24sIG9wdGlvbnMpXG4gIH1cblxuICBkZWJ1ZygnU2VtVmVyJywgdmVyc2lvbiwgb3B0aW9ucylcbiAgdGhpcy5vcHRpb25zID0gb3B0aW9uc1xuICB0aGlzLmxvb3NlID0gISFvcHRpb25zLmxvb3NlXG5cbiAgdmFyIG0gPSB2ZXJzaW9uLnRyaW0oKS5tYXRjaChvcHRpb25zLmxvb3NlID8gcmVbdC5MT09TRV0gOiByZVt0LkZVTExdKVxuXG4gIGlmICghbSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgVmVyc2lvbjogJyArIHZlcnNpb24pXG4gIH1cblxuICB0aGlzLnJhdyA9IHZlcnNpb25cblxuICAvLyB0aGVzZSBhcmUgYWN0dWFsbHkgbnVtYmVyc1xuICB0aGlzLm1ham9yID0gK21bMV1cbiAgdGhpcy5taW5vciA9ICttWzJdXG4gIHRoaXMucGF0Y2ggPSArbVszXVxuXG4gIGlmICh0aGlzLm1ham9yID4gTUFYX1NBRkVfSU5URUdFUiB8fCB0aGlzLm1ham9yIDwgMCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgbWFqb3IgdmVyc2lvbicpXG4gIH1cblxuICBpZiAodGhpcy5taW5vciA+IE1BWF9TQUZFX0lOVEVHRVIgfHwgdGhpcy5taW5vciA8IDApIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG1pbm9yIHZlcnNpb24nKVxuICB9XG5cbiAgaWYgKHRoaXMucGF0Y2ggPiBNQVhfU0FGRV9JTlRFR0VSIHx8IHRoaXMucGF0Y2ggPCAwKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBwYXRjaCB2ZXJzaW9uJylcbiAgfVxuXG4gIC8vIG51bWJlcmlmeSBhbnkgcHJlcmVsZWFzZSBudW1lcmljIGlkc1xuICBpZiAoIW1bNF0pIHtcbiAgICB0aGlzLnByZXJlbGVhc2UgPSBbXVxuICB9IGVsc2Uge1xuICAgIHRoaXMucHJlcmVsZWFzZSA9IG1bNF0uc3BsaXQoJy4nKS5tYXAoZnVuY3Rpb24gKGlkKSB7XG4gICAgICBpZiAoL15bMC05XSskLy50ZXN0KGlkKSkge1xuICAgICAgICB2YXIgbnVtID0gK2lkXG4gICAgICAgIGlmIChudW0gPj0gMCAmJiBudW0gPCBNQVhfU0FGRV9JTlRFR0VSKSB7XG4gICAgICAgICAgcmV0dXJuIG51bVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gaWRcbiAgICB9KVxuICB9XG5cbiAgdGhpcy5idWlsZCA9IG1bNV0gPyBtWzVdLnNwbGl0KCcuJykgOiBbXVxuICB0aGlzLmZvcm1hdCgpXG59XG5cblNlbVZlci5wcm90b3R5cGUuZm9ybWF0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLnZlcnNpb24gPSB0aGlzLm1ham9yICsgJy4nICsgdGhpcy5taW5vciArICcuJyArIHRoaXMucGF0Y2hcbiAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGgpIHtcbiAgICB0aGlzLnZlcnNpb24gKz0gJy0nICsgdGhpcy5wcmVyZWxlYXNlLmpvaW4oJy4nKVxuICB9XG4gIHJldHVybiB0aGlzLnZlcnNpb25cbn1cblxuU2VtVmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMudmVyc2lvblxufVxuXG5TZW1WZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgZGVidWcoJ1NlbVZlci5jb21wYXJlJywgdGhpcy52ZXJzaW9uLCB0aGlzLm9wdGlvbnMsIG90aGVyKVxuICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIFNlbVZlcikpIHtcbiAgICBvdGhlciA9IG5ldyBTZW1WZXIob3RoZXIsIHRoaXMub3B0aW9ucylcbiAgfVxuXG4gIHJldHVybiB0aGlzLmNvbXBhcmVNYWluKG90aGVyKSB8fCB0aGlzLmNvbXBhcmVQcmUob3RoZXIpXG59XG5cblNlbVZlci5wcm90b3R5cGUuY29tcGFyZU1haW4gPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBTZW1WZXIpKSB7XG4gICAgb3RoZXIgPSBuZXcgU2VtVmVyKG90aGVyLCB0aGlzLm9wdGlvbnMpXG4gIH1cblxuICByZXR1cm4gY29tcGFyZUlkZW50aWZpZXJzKHRoaXMubWFqb3IsIG90aGVyLm1ham9yKSB8fFxuICAgICAgICAgY29tcGFyZUlkZW50aWZpZXJzKHRoaXMubWlub3IsIG90aGVyLm1pbm9yKSB8fFxuICAgICAgICAgY29tcGFyZUlkZW50aWZpZXJzKHRoaXMucGF0Y2gsIG90aGVyLnBhdGNoKVxufVxuXG5TZW1WZXIucHJvdG90eXBlLmNvbXBhcmVQcmUgPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBTZW1WZXIpKSB7XG4gICAgb3RoZXIgPSBuZXcgU2VtVmVyKG90aGVyLCB0aGlzLm9wdGlvbnMpXG4gIH1cblxuICAvLyBOT1QgaGF2aW5nIGEgcHJlcmVsZWFzZSBpcyA+IGhhdmluZyBvbmVcbiAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggJiYgIW90aGVyLnByZXJlbGVhc2UubGVuZ3RoKSB7XG4gICAgcmV0dXJuIC0xXG4gIH0gZWxzZSBpZiAoIXRoaXMucHJlcmVsZWFzZS5sZW5ndGggJiYgb3RoZXIucHJlcmVsZWFzZS5sZW5ndGgpIHtcbiAgICByZXR1cm4gMVxuICB9IGVsc2UgaWYgKCF0aGlzLnByZXJlbGVhc2UubGVuZ3RoICYmICFvdGhlci5wcmVyZWxlYXNlLmxlbmd0aCkge1xuICAgIHJldHVybiAwXG4gIH1cblxuICB2YXIgaSA9IDBcbiAgZG8ge1xuICAgIHZhciBhID0gdGhpcy5wcmVyZWxlYXNlW2ldXG4gICAgdmFyIGIgPSBvdGhlci5wcmVyZWxlYXNlW2ldXG4gICAgZGVidWcoJ3ByZXJlbGVhc2UgY29tcGFyZScsIGksIGEsIGIpXG4gICAgaWYgKGEgPT09IHVuZGVmaW5lZCAmJiBiID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAwXG4gICAgfSBlbHNlIGlmIChiID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAxXG4gICAgfSBlbHNlIGlmIChhID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAtMVxuICAgIH0gZWxzZSBpZiAoYSA9PT0gYikge1xuICAgICAgY29udGludWVcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNvbXBhcmVJZGVudGlmaWVycyhhLCBiKVxuICAgIH1cbiAgfSB3aGlsZSAoKytpKVxufVxuXG5TZW1WZXIucHJvdG90eXBlLmNvbXBhcmVCdWlsZCA9IGZ1bmN0aW9uIChvdGhlcikge1xuICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIFNlbVZlcikpIHtcbiAgICBvdGhlciA9IG5ldyBTZW1WZXIob3RoZXIsIHRoaXMub3B0aW9ucylcbiAgfVxuXG4gIHZhciBpID0gMFxuICBkbyB7XG4gICAgdmFyIGEgPSB0aGlzLmJ1aWxkW2ldXG4gICAgdmFyIGIgPSBvdGhlci5idWlsZFtpXVxuICAgIGRlYnVnKCdwcmVyZWxlYXNlIGNvbXBhcmUnLCBpLCBhLCBiKVxuICAgIGlmIChhID09PSB1bmRlZmluZWQgJiYgYiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gMFxuICAgIH0gZWxzZSBpZiAoYiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gMVxuICAgIH0gZWxzZSBpZiAoYSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gLTFcbiAgICB9IGVsc2UgaWYgKGEgPT09IGIpIHtcbiAgICAgIGNvbnRpbnVlXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBjb21wYXJlSWRlbnRpZmllcnMoYSwgYilcbiAgICB9XG4gIH0gd2hpbGUgKCsraSlcbn1cblxuLy8gcHJlbWlub3Igd2lsbCBidW1wIHRoZSB2ZXJzaW9uIHVwIHRvIHRoZSBuZXh0IG1pbm9yIHJlbGVhc2UsIGFuZCBpbW1lZGlhdGVseVxuLy8gZG93biB0byBwcmUtcmVsZWFzZS4gcHJlbWFqb3IgYW5kIHByZXBhdGNoIHdvcmsgdGhlIHNhbWUgd2F5LlxuU2VtVmVyLnByb3RvdHlwZS5pbmMgPSBmdW5jdGlvbiAocmVsZWFzZSwgaWRlbnRpZmllcikge1xuICBzd2l0Y2ggKHJlbGVhc2UpIHtcbiAgICBjYXNlICdwcmVtYWpvcic6XG4gICAgICB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID0gMFxuICAgICAgdGhpcy5wYXRjaCA9IDBcbiAgICAgIHRoaXMubWlub3IgPSAwXG4gICAgICB0aGlzLm1ham9yKytcbiAgICAgIHRoaXMuaW5jKCdwcmUnLCBpZGVudGlmaWVyKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdwcmVtaW5vcic6XG4gICAgICB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID0gMFxuICAgICAgdGhpcy5wYXRjaCA9IDBcbiAgICAgIHRoaXMubWlub3IrK1xuICAgICAgdGhpcy5pbmMoJ3ByZScsIGlkZW50aWZpZXIpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3ByZXBhdGNoJzpcbiAgICAgIC8vIElmIHRoaXMgaXMgYWxyZWFkeSBhIHByZXJlbGVhc2UsIGl0IHdpbGwgYnVtcCB0byB0aGUgbmV4dCB2ZXJzaW9uXG4gICAgICAvLyBkcm9wIGFueSBwcmVyZWxlYXNlcyB0aGF0IG1pZ2h0IGFscmVhZHkgZXhpc3QsIHNpbmNlIHRoZXkgYXJlIG5vdFxuICAgICAgLy8gcmVsZXZhbnQgYXQgdGhpcyBwb2ludC5cbiAgICAgIHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPSAwXG4gICAgICB0aGlzLmluYygncGF0Y2gnLCBpZGVudGlmaWVyKVxuICAgICAgdGhpcy5pbmMoJ3ByZScsIGlkZW50aWZpZXIpXG4gICAgICBicmVha1xuICAgIC8vIElmIHRoZSBpbnB1dCBpcyBhIG5vbi1wcmVyZWxlYXNlIHZlcnNpb24sIHRoaXMgYWN0cyB0aGUgc2FtZSBhc1xuICAgIC8vIHByZXBhdGNoLlxuICAgIGNhc2UgJ3ByZXJlbGVhc2UnOlxuICAgICAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy5pbmMoJ3BhdGNoJywgaWRlbnRpZmllcilcbiAgICAgIH1cbiAgICAgIHRoaXMuaW5jKCdwcmUnLCBpZGVudGlmaWVyKVxuICAgICAgYnJlYWtcblxuICAgIGNhc2UgJ21ham9yJzpcbiAgICAgIC8vIElmIHRoaXMgaXMgYSBwcmUtbWFqb3IgdmVyc2lvbiwgYnVtcCB1cCB0byB0aGUgc2FtZSBtYWpvciB2ZXJzaW9uLlxuICAgICAgLy8gT3RoZXJ3aXNlIGluY3JlbWVudCBtYWpvci5cbiAgICAgIC8vIDEuMC4wLTUgYnVtcHMgdG8gMS4wLjBcbiAgICAgIC8vIDEuMS4wIGJ1bXBzIHRvIDIuMC4wXG4gICAgICBpZiAodGhpcy5taW5vciAhPT0gMCB8fFxuICAgICAgICAgIHRoaXMucGF0Y2ggIT09IDAgfHxcbiAgICAgICAgICB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMubWFqb3IrK1xuICAgICAgfVxuICAgICAgdGhpcy5taW5vciA9IDBcbiAgICAgIHRoaXMucGF0Y2ggPSAwXG4gICAgICB0aGlzLnByZXJlbGVhc2UgPSBbXVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdtaW5vcic6XG4gICAgICAvLyBJZiB0aGlzIGlzIGEgcHJlLW1pbm9yIHZlcnNpb24sIGJ1bXAgdXAgdG8gdGhlIHNhbWUgbWlub3IgdmVyc2lvbi5cbiAgICAgIC8vIE90aGVyd2lzZSBpbmNyZW1lbnQgbWlub3IuXG4gICAgICAvLyAxLjIuMC01IGJ1bXBzIHRvIDEuMi4wXG4gICAgICAvLyAxLjIuMSBidW1wcyB0byAxLjMuMFxuICAgICAgaWYgKHRoaXMucGF0Y2ggIT09IDAgfHwgdGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLm1pbm9yKytcbiAgICAgIH1cbiAgICAgIHRoaXMucGF0Y2ggPSAwXG4gICAgICB0aGlzLnByZXJlbGVhc2UgPSBbXVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdwYXRjaCc6XG4gICAgICAvLyBJZiB0aGlzIGlzIG5vdCBhIHByZS1yZWxlYXNlIHZlcnNpb24sIGl0IHdpbGwgaW5jcmVtZW50IHRoZSBwYXRjaC5cbiAgICAgIC8vIElmIGl0IGlzIGEgcHJlLXJlbGVhc2UgaXQgd2lsbCBidW1wIHVwIHRvIHRoZSBzYW1lIHBhdGNoIHZlcnNpb24uXG4gICAgICAvLyAxLjIuMC01IHBhdGNoZXMgdG8gMS4yLjBcbiAgICAgIC8vIDEuMi4wIHBhdGNoZXMgdG8gMS4yLjFcbiAgICAgIGlmICh0aGlzLnByZXJlbGVhc2UubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMucGF0Y2grK1xuICAgICAgfVxuICAgICAgdGhpcy5wcmVyZWxlYXNlID0gW11cbiAgICAgIGJyZWFrXG4gICAgLy8gVGhpcyBwcm9iYWJseSBzaG91bGRuJ3QgYmUgdXNlZCBwdWJsaWNseS5cbiAgICAvLyAxLjAuMCBcInByZVwiIHdvdWxkIGJlY29tZSAxLjAuMC0wIHdoaWNoIGlzIHRoZSB3cm9uZyBkaXJlY3Rpb24uXG4gICAgY2FzZSAncHJlJzpcbiAgICAgIGlmICh0aGlzLnByZXJlbGVhc2UubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFswXVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGkgPSB0aGlzLnByZXJlbGVhc2UubGVuZ3RoXG4gICAgICAgIHdoaWxlICgtLWkgPj0gMCkge1xuICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcmVyZWxlYXNlW2ldID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgdGhpcy5wcmVyZWxlYXNlW2ldKytcbiAgICAgICAgICAgIGkgPSAtMlxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoaSA9PT0gLTEpIHtcbiAgICAgICAgICAvLyBkaWRuJ3QgaW5jcmVtZW50IGFueXRoaW5nXG4gICAgICAgICAgdGhpcy5wcmVyZWxlYXNlLnB1c2goMClcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGlkZW50aWZpZXIpIHtcbiAgICAgICAgLy8gMS4yLjAtYmV0YS4xIGJ1bXBzIHRvIDEuMi4wLWJldGEuMixcbiAgICAgICAgLy8gMS4yLjAtYmV0YS5mb29ibHogb3IgMS4yLjAtYmV0YSBidW1wcyB0byAxLjIuMC1iZXRhLjBcbiAgICAgICAgaWYgKHRoaXMucHJlcmVsZWFzZVswXSA9PT0gaWRlbnRpZmllcikge1xuICAgICAgICAgIGlmIChpc05hTih0aGlzLnByZXJlbGVhc2VbMV0pKSB7XG4gICAgICAgICAgICB0aGlzLnByZXJlbGVhc2UgPSBbaWRlbnRpZmllciwgMF1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5wcmVyZWxlYXNlID0gW2lkZW50aWZpZXIsIDBdXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJyZWFrXG5cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGluY3JlbWVudCBhcmd1bWVudDogJyArIHJlbGVhc2UpXG4gIH1cbiAgdGhpcy5mb3JtYXQoKVxuICB0aGlzLnJhdyA9IHRoaXMudmVyc2lvblxuICByZXR1cm4gdGhpc1xufVxuXG5leHBvcnRzLmluYyA9IGluY1xuZnVuY3Rpb24gaW5jICh2ZXJzaW9uLCByZWxlYXNlLCBsb29zZSwgaWRlbnRpZmllcikge1xuICBpZiAodHlwZW9mIChsb29zZSkgPT09ICdzdHJpbmcnKSB7XG4gICAgaWRlbnRpZmllciA9IGxvb3NlXG4gICAgbG9vc2UgPSB1bmRlZmluZWRcbiAgfVxuXG4gIHRyeSB7XG4gICAgcmV0dXJuIG5ldyBTZW1WZXIodmVyc2lvbiwgbG9vc2UpLmluYyhyZWxlYXNlLCBpZGVudGlmaWVyKS52ZXJzaW9uXG4gIH0gY2F0Y2ggKGVyKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxufVxuXG5leHBvcnRzLmRpZmYgPSBkaWZmXG5mdW5jdGlvbiBkaWZmICh2ZXJzaW9uMSwgdmVyc2lvbjIpIHtcbiAgaWYgKGVxKHZlcnNpb24xLCB2ZXJzaW9uMikpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9IGVsc2Uge1xuICAgIHZhciB2MSA9IHBhcnNlKHZlcnNpb24xKVxuICAgIHZhciB2MiA9IHBhcnNlKHZlcnNpb24yKVxuICAgIHZhciBwcmVmaXggPSAnJ1xuICAgIGlmICh2MS5wcmVyZWxlYXNlLmxlbmd0aCB8fCB2Mi5wcmVyZWxlYXNlLmxlbmd0aCkge1xuICAgICAgcHJlZml4ID0gJ3ByZSdcbiAgICAgIHZhciBkZWZhdWx0UmVzdWx0ID0gJ3ByZXJlbGVhc2UnXG4gICAgfVxuICAgIGZvciAodmFyIGtleSBpbiB2MSkge1xuICAgICAgaWYgKGtleSA9PT0gJ21ham9yJyB8fCBrZXkgPT09ICdtaW5vcicgfHwga2V5ID09PSAncGF0Y2gnKSB7XG4gICAgICAgIGlmICh2MVtrZXldICE9PSB2MltrZXldKSB7XG4gICAgICAgICAgcmV0dXJuIHByZWZpeCArIGtleVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkZWZhdWx0UmVzdWx0IC8vIG1heSBiZSB1bmRlZmluZWRcbiAgfVxufVxuXG5leHBvcnRzLmNvbXBhcmVJZGVudGlmaWVycyA9IGNvbXBhcmVJZGVudGlmaWVyc1xuXG52YXIgbnVtZXJpYyA9IC9eWzAtOV0rJC9cbmZ1bmN0aW9uIGNvbXBhcmVJZGVudGlmaWVycyAoYSwgYikge1xuICB2YXIgYW51bSA9IG51bWVyaWMudGVzdChhKVxuICB2YXIgYm51bSA9IG51bWVyaWMudGVzdChiKVxuXG4gIGlmIChhbnVtICYmIGJudW0pIHtcbiAgICBhID0gK2FcbiAgICBiID0gK2JcbiAgfVxuXG4gIHJldHVybiBhID09PSBiID8gMFxuICAgIDogKGFudW0gJiYgIWJudW0pID8gLTFcbiAgICA6IChibnVtICYmICFhbnVtKSA/IDFcbiAgICA6IGEgPCBiID8gLTFcbiAgICA6IDFcbn1cblxuZXhwb3J0cy5yY29tcGFyZUlkZW50aWZpZXJzID0gcmNvbXBhcmVJZGVudGlmaWVyc1xuZnVuY3Rpb24gcmNvbXBhcmVJZGVudGlmaWVycyAoYSwgYikge1xuICByZXR1cm4gY29tcGFyZUlkZW50aWZpZXJzKGIsIGEpXG59XG5cbmV4cG9ydHMubWFqb3IgPSBtYWpvclxuZnVuY3Rpb24gbWFqb3IgKGEsIGxvb3NlKSB7XG4gIHJldHVybiBuZXcgU2VtVmVyKGEsIGxvb3NlKS5tYWpvclxufVxuXG5leHBvcnRzLm1pbm9yID0gbWlub3JcbmZ1bmN0aW9uIG1pbm9yIChhLCBsb29zZSkge1xuICByZXR1cm4gbmV3IFNlbVZlcihhLCBsb29zZSkubWlub3Jcbn1cblxuZXhwb3J0cy5wYXRjaCA9IHBhdGNoXG5mdW5jdGlvbiBwYXRjaCAoYSwgbG9vc2UpIHtcbiAgcmV0dXJuIG5ldyBTZW1WZXIoYSwgbG9vc2UpLnBhdGNoXG59XG5cbmV4cG9ydHMuY29tcGFyZSA9IGNvbXBhcmVcbmZ1bmN0aW9uIGNvbXBhcmUgKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBuZXcgU2VtVmVyKGEsIGxvb3NlKS5jb21wYXJlKG5ldyBTZW1WZXIoYiwgbG9vc2UpKVxufVxuXG5leHBvcnRzLmNvbXBhcmVMb29zZSA9IGNvbXBhcmVMb29zZVxuZnVuY3Rpb24gY29tcGFyZUxvb3NlIChhLCBiKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIHRydWUpXG59XG5cbmV4cG9ydHMuY29tcGFyZUJ1aWxkID0gY29tcGFyZUJ1aWxkXG5mdW5jdGlvbiBjb21wYXJlQnVpbGQgKGEsIGIsIGxvb3NlKSB7XG4gIHZhciB2ZXJzaW9uQSA9IG5ldyBTZW1WZXIoYSwgbG9vc2UpXG4gIHZhciB2ZXJzaW9uQiA9IG5ldyBTZW1WZXIoYiwgbG9vc2UpXG4gIHJldHVybiB2ZXJzaW9uQS5jb21wYXJlKHZlcnNpb25CKSB8fCB2ZXJzaW9uQS5jb21wYXJlQnVpbGQodmVyc2lvbkIpXG59XG5cbmV4cG9ydHMucmNvbXBhcmUgPSByY29tcGFyZVxuZnVuY3Rpb24gcmNvbXBhcmUgKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGIsIGEsIGxvb3NlKVxufVxuXG5leHBvcnRzLnNvcnQgPSBzb3J0XG5mdW5jdGlvbiBzb3J0IChsaXN0LCBsb29zZSkge1xuICByZXR1cm4gbGlzdC5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgcmV0dXJuIGV4cG9ydHMuY29tcGFyZUJ1aWxkKGEsIGIsIGxvb3NlKVxuICB9KVxufVxuXG5leHBvcnRzLnJzb3J0ID0gcnNvcnRcbmZ1bmN0aW9uIHJzb3J0IChsaXN0LCBsb29zZSkge1xuICByZXR1cm4gbGlzdC5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgcmV0dXJuIGV4cG9ydHMuY29tcGFyZUJ1aWxkKGIsIGEsIGxvb3NlKVxuICB9KVxufVxuXG5leHBvcnRzLmd0ID0gZ3RcbmZ1bmN0aW9uIGd0IChhLCBiLCBsb29zZSkge1xuICByZXR1cm4gY29tcGFyZShhLCBiLCBsb29zZSkgPiAwXG59XG5cbmV4cG9ydHMubHQgPSBsdFxuZnVuY3Rpb24gbHQgKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIGxvb3NlKSA8IDBcbn1cblxuZXhwb3J0cy5lcSA9IGVxXG5mdW5jdGlvbiBlcSAoYSwgYiwgbG9vc2UpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYSwgYiwgbG9vc2UpID09PSAwXG59XG5cbmV4cG9ydHMubmVxID0gbmVxXG5mdW5jdGlvbiBuZXEgKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIGxvb3NlKSAhPT0gMFxufVxuXG5leHBvcnRzLmd0ZSA9IGd0ZVxuZnVuY3Rpb24gZ3RlIChhLCBiLCBsb29zZSkge1xuICByZXR1cm4gY29tcGFyZShhLCBiLCBsb29zZSkgPj0gMFxufVxuXG5leHBvcnRzLmx0ZSA9IGx0ZVxuZnVuY3Rpb24gbHRlIChhLCBiLCBsb29zZSkge1xuICByZXR1cm4gY29tcGFyZShhLCBiLCBsb29zZSkgPD0gMFxufVxuXG5leHBvcnRzLmNtcCA9IGNtcFxuZnVuY3Rpb24gY21wIChhLCBvcCwgYiwgbG9vc2UpIHtcbiAgc3dpdGNoIChvcCkge1xuICAgIGNhc2UgJz09PSc6XG4gICAgICBpZiAodHlwZW9mIGEgPT09ICdvYmplY3QnKVxuICAgICAgICBhID0gYS52ZXJzaW9uXG4gICAgICBpZiAodHlwZW9mIGIgPT09ICdvYmplY3QnKVxuICAgICAgICBiID0gYi52ZXJzaW9uXG4gICAgICByZXR1cm4gYSA9PT0gYlxuXG4gICAgY2FzZSAnIT09JzpcbiAgICAgIGlmICh0eXBlb2YgYSA9PT0gJ29iamVjdCcpXG4gICAgICAgIGEgPSBhLnZlcnNpb25cbiAgICAgIGlmICh0eXBlb2YgYiA9PT0gJ29iamVjdCcpXG4gICAgICAgIGIgPSBiLnZlcnNpb25cbiAgICAgIHJldHVybiBhICE9PSBiXG5cbiAgICBjYXNlICcnOlxuICAgIGNhc2UgJz0nOlxuICAgIGNhc2UgJz09JzpcbiAgICAgIHJldHVybiBlcShhLCBiLCBsb29zZSlcblxuICAgIGNhc2UgJyE9JzpcbiAgICAgIHJldHVybiBuZXEoYSwgYiwgbG9vc2UpXG5cbiAgICBjYXNlICc+JzpcbiAgICAgIHJldHVybiBndChhLCBiLCBsb29zZSlcblxuICAgIGNhc2UgJz49JzpcbiAgICAgIHJldHVybiBndGUoYSwgYiwgbG9vc2UpXG5cbiAgICBjYXNlICc8JzpcbiAgICAgIHJldHVybiBsdChhLCBiLCBsb29zZSlcblxuICAgIGNhc2UgJzw9JzpcbiAgICAgIHJldHVybiBsdGUoYSwgYiwgbG9vc2UpXG5cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBvcGVyYXRvcjogJyArIG9wKVxuICB9XG59XG5cbmV4cG9ydHMuQ29tcGFyYXRvciA9IENvbXBhcmF0b3JcbmZ1bmN0aW9uIENvbXBhcmF0b3IgKGNvbXAsIG9wdGlvbnMpIHtcbiAgaWYgKCFvcHRpb25zIHx8IHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0Jykge1xuICAgIG9wdGlvbnMgPSB7XG4gICAgICBsb29zZTogISFvcHRpb25zLFxuICAgICAgaW5jbHVkZVByZXJlbGVhc2U6IGZhbHNlXG4gICAgfVxuICB9XG5cbiAgaWYgKGNvbXAgaW5zdGFuY2VvZiBDb21wYXJhdG9yKSB7XG4gICAgaWYgKGNvbXAubG9vc2UgPT09ICEhb3B0aW9ucy5sb29zZSkge1xuICAgICAgcmV0dXJuIGNvbXBcbiAgICB9IGVsc2Uge1xuICAgICAgY29tcCA9IGNvbXAudmFsdWVcbiAgICB9XG4gIH1cblxuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQ29tcGFyYXRvcikpIHtcbiAgICByZXR1cm4gbmV3IENvbXBhcmF0b3IoY29tcCwgb3B0aW9ucylcbiAgfVxuXG4gIGRlYnVnKCdjb21wYXJhdG9yJywgY29tcCwgb3B0aW9ucylcbiAgdGhpcy5vcHRpb25zID0gb3B0aW9uc1xuICB0aGlzLmxvb3NlID0gISFvcHRpb25zLmxvb3NlXG4gIHRoaXMucGFyc2UoY29tcClcblxuICBpZiAodGhpcy5zZW12ZXIgPT09IEFOWSkge1xuICAgIHRoaXMudmFsdWUgPSAnJ1xuICB9IGVsc2Uge1xuICAgIHRoaXMudmFsdWUgPSB0aGlzLm9wZXJhdG9yICsgdGhpcy5zZW12ZXIudmVyc2lvblxuICB9XG5cbiAgZGVidWcoJ2NvbXAnLCB0aGlzKVxufVxuXG52YXIgQU5ZID0ge31cbkNvbXBhcmF0b3IucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24gKGNvbXApIHtcbiAgdmFyIHIgPSB0aGlzLm9wdGlvbnMubG9vc2UgPyByZVt0LkNPTVBBUkFUT1JMT09TRV0gOiByZVt0LkNPTVBBUkFUT1JdXG4gIHZhciBtID0gY29tcC5tYXRjaChyKVxuXG4gIGlmICghbSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgY29tcGFyYXRvcjogJyArIGNvbXApXG4gIH1cblxuICB0aGlzLm9wZXJhdG9yID0gbVsxXSAhPT0gdW5kZWZpbmVkID8gbVsxXSA6ICcnXG4gIGlmICh0aGlzLm9wZXJhdG9yID09PSAnPScpIHtcbiAgICB0aGlzLm9wZXJhdG9yID0gJydcbiAgfVxuXG4gIC8vIGlmIGl0IGxpdGVyYWxseSBpcyBqdXN0ICc+JyBvciAnJyB0aGVuIGFsbG93IGFueXRoaW5nLlxuICBpZiAoIW1bMl0pIHtcbiAgICB0aGlzLnNlbXZlciA9IEFOWVxuICB9IGVsc2Uge1xuICAgIHRoaXMuc2VtdmVyID0gbmV3IFNlbVZlcihtWzJdLCB0aGlzLm9wdGlvbnMubG9vc2UpXG4gIH1cbn1cblxuQ29tcGFyYXRvci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLnZhbHVlXG59XG5cbkNvbXBhcmF0b3IucHJvdG90eXBlLnRlc3QgPSBmdW5jdGlvbiAodmVyc2lvbikge1xuICBkZWJ1ZygnQ29tcGFyYXRvci50ZXN0JywgdmVyc2lvbiwgdGhpcy5vcHRpb25zLmxvb3NlKVxuXG4gIGlmICh0aGlzLnNlbXZlciA9PT0gQU5ZIHx8IHZlcnNpb24gPT09IEFOWSkge1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBpZiAodHlwZW9mIHZlcnNpb24gPT09ICdzdHJpbmcnKSB7XG4gICAgdHJ5IHtcbiAgICAgIHZlcnNpb24gPSBuZXcgU2VtVmVyKHZlcnNpb24sIHRoaXMub3B0aW9ucylcbiAgICB9IGNhdGNoIChlcikge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNtcCh2ZXJzaW9uLCB0aGlzLm9wZXJhdG9yLCB0aGlzLnNlbXZlciwgdGhpcy5vcHRpb25zKVxufVxuXG5Db21wYXJhdG9yLnByb3RvdHlwZS5pbnRlcnNlY3RzID0gZnVuY3Rpb24gKGNvbXAsIG9wdGlvbnMpIHtcbiAgaWYgKCEoY29tcCBpbnN0YW5jZW9mIENvbXBhcmF0b3IpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYSBDb21wYXJhdG9yIGlzIHJlcXVpcmVkJylcbiAgfVxuXG4gIGlmICghb3B0aW9ucyB8fCB0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgbG9vc2U6ICEhb3B0aW9ucyxcbiAgICAgIGluY2x1ZGVQcmVyZWxlYXNlOiBmYWxzZVxuICAgIH1cbiAgfVxuXG4gIHZhciByYW5nZVRtcFxuXG4gIGlmICh0aGlzLm9wZXJhdG9yID09PSAnJykge1xuICAgIGlmICh0aGlzLnZhbHVlID09PSAnJykge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gICAgcmFuZ2VUbXAgPSBuZXcgUmFuZ2UoY29tcC52YWx1ZSwgb3B0aW9ucylcbiAgICByZXR1cm4gc2F0aXNmaWVzKHRoaXMudmFsdWUsIHJhbmdlVG1wLCBvcHRpb25zKVxuICB9IGVsc2UgaWYgKGNvbXAub3BlcmF0b3IgPT09ICcnKSB7XG4gICAgaWYgKGNvbXAudmFsdWUgPT09ICcnKSB7XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cbiAgICByYW5nZVRtcCA9IG5ldyBSYW5nZSh0aGlzLnZhbHVlLCBvcHRpb25zKVxuICAgIHJldHVybiBzYXRpc2ZpZXMoY29tcC5zZW12ZXIsIHJhbmdlVG1wLCBvcHRpb25zKVxuICB9XG5cbiAgdmFyIHNhbWVEaXJlY3Rpb25JbmNyZWFzaW5nID1cbiAgICAodGhpcy5vcGVyYXRvciA9PT0gJz49JyB8fCB0aGlzLm9wZXJhdG9yID09PSAnPicpICYmXG4gICAgKGNvbXAub3BlcmF0b3IgPT09ICc+PScgfHwgY29tcC5vcGVyYXRvciA9PT0gJz4nKVxuICB2YXIgc2FtZURpcmVjdGlvbkRlY3JlYXNpbmcgPVxuICAgICh0aGlzLm9wZXJhdG9yID09PSAnPD0nIHx8IHRoaXMub3BlcmF0b3IgPT09ICc8JykgJiZcbiAgICAoY29tcC5vcGVyYXRvciA9PT0gJzw9JyB8fCBjb21wLm9wZXJhdG9yID09PSAnPCcpXG4gIHZhciBzYW1lU2VtVmVyID0gdGhpcy5zZW12ZXIudmVyc2lvbiA9PT0gY29tcC5zZW12ZXIudmVyc2lvblxuICB2YXIgZGlmZmVyZW50RGlyZWN0aW9uc0luY2x1c2l2ZSA9XG4gICAgKHRoaXMub3BlcmF0b3IgPT09ICc+PScgfHwgdGhpcy5vcGVyYXRvciA9PT0gJzw9JykgJiZcbiAgICAoY29tcC5vcGVyYXRvciA9PT0gJz49JyB8fCBjb21wLm9wZXJhdG9yID09PSAnPD0nKVxuICB2YXIgb3Bwb3NpdGVEaXJlY3Rpb25zTGVzc1RoYW4gPVxuICAgIGNtcCh0aGlzLnNlbXZlciwgJzwnLCBjb21wLnNlbXZlciwgb3B0aW9ucykgJiZcbiAgICAoKHRoaXMub3BlcmF0b3IgPT09ICc+PScgfHwgdGhpcy5vcGVyYXRvciA9PT0gJz4nKSAmJlxuICAgIChjb21wLm9wZXJhdG9yID09PSAnPD0nIHx8IGNvbXAub3BlcmF0b3IgPT09ICc8JykpXG4gIHZhciBvcHBvc2l0ZURpcmVjdGlvbnNHcmVhdGVyVGhhbiA9XG4gICAgY21wKHRoaXMuc2VtdmVyLCAnPicsIGNvbXAuc2VtdmVyLCBvcHRpb25zKSAmJlxuICAgICgodGhpcy5vcGVyYXRvciA9PT0gJzw9JyB8fCB0aGlzLm9wZXJhdG9yID09PSAnPCcpICYmXG4gICAgKGNvbXAub3BlcmF0b3IgPT09ICc+PScgfHwgY29tcC5vcGVyYXRvciA9PT0gJz4nKSlcblxuICByZXR1cm4gc2FtZURpcmVjdGlvbkluY3JlYXNpbmcgfHwgc2FtZURpcmVjdGlvbkRlY3JlYXNpbmcgfHxcbiAgICAoc2FtZVNlbVZlciAmJiBkaWZmZXJlbnREaXJlY3Rpb25zSW5jbHVzaXZlKSB8fFxuICAgIG9wcG9zaXRlRGlyZWN0aW9uc0xlc3NUaGFuIHx8IG9wcG9zaXRlRGlyZWN0aW9uc0dyZWF0ZXJUaGFuXG59XG5cbmV4cG9ydHMuUmFuZ2UgPSBSYW5nZVxuZnVuY3Rpb24gUmFuZ2UgKHJhbmdlLCBvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucyB8fCB0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgbG9vc2U6ICEhb3B0aW9ucyxcbiAgICAgIGluY2x1ZGVQcmVyZWxlYXNlOiBmYWxzZVxuICAgIH1cbiAgfVxuXG4gIGlmIChyYW5nZSBpbnN0YW5jZW9mIFJhbmdlKSB7XG4gICAgaWYgKHJhbmdlLmxvb3NlID09PSAhIW9wdGlvbnMubG9vc2UgJiZcbiAgICAgICAgcmFuZ2UuaW5jbHVkZVByZXJlbGVhc2UgPT09ICEhb3B0aW9ucy5pbmNsdWRlUHJlcmVsZWFzZSkge1xuICAgICAgcmV0dXJuIHJhbmdlXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgUmFuZ2UocmFuZ2UucmF3LCBvcHRpb25zKVxuICAgIH1cbiAgfVxuXG4gIGlmIChyYW5nZSBpbnN0YW5jZW9mIENvbXBhcmF0b3IpIHtcbiAgICByZXR1cm4gbmV3IFJhbmdlKHJhbmdlLnZhbHVlLCBvcHRpb25zKVxuICB9XG5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJhbmdlKSkge1xuICAgIHJldHVybiBuZXcgUmFuZ2UocmFuZ2UsIG9wdGlvbnMpXG4gIH1cblxuICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zXG4gIHRoaXMubG9vc2UgPSAhIW9wdGlvbnMubG9vc2VcbiAgdGhpcy5pbmNsdWRlUHJlcmVsZWFzZSA9ICEhb3B0aW9ucy5pbmNsdWRlUHJlcmVsZWFzZVxuXG4gIC8vIEZpcnN0LCBzcGxpdCBiYXNlZCBvbiBib29sZWFuIG9yIHx8XG4gIHRoaXMucmF3ID0gcmFuZ2VcbiAgdGhpcy5zZXQgPSByYW5nZS5zcGxpdCgvXFxzKlxcfFxcfFxccyovKS5tYXAoZnVuY3Rpb24gKHJhbmdlKSB7XG4gICAgcmV0dXJuIHRoaXMucGFyc2VSYW5nZShyYW5nZS50cmltKCkpXG4gIH0sIHRoaXMpLmZpbHRlcihmdW5jdGlvbiAoYykge1xuICAgIC8vIHRocm93IG91dCBhbnkgdGhhdCBhcmUgbm90IHJlbGV2YW50IGZvciB3aGF0ZXZlciByZWFzb25cbiAgICByZXR1cm4gYy5sZW5ndGhcbiAgfSlcblxuICBpZiAoIXRoaXMuc2V0Lmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgU2VtVmVyIFJhbmdlOiAnICsgcmFuZ2UpXG4gIH1cblxuICB0aGlzLmZvcm1hdCgpXG59XG5cblJhbmdlLnByb3RvdHlwZS5mb3JtYXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMucmFuZ2UgPSB0aGlzLnNldC5tYXAoZnVuY3Rpb24gKGNvbXBzKSB7XG4gICAgcmV0dXJuIGNvbXBzLmpvaW4oJyAnKS50cmltKClcbiAgfSkuam9pbignfHwnKS50cmltKClcbiAgcmV0dXJuIHRoaXMucmFuZ2Vcbn1cblxuUmFuZ2UucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5yYW5nZVxufVxuXG5SYW5nZS5wcm90b3R5cGUucGFyc2VSYW5nZSA9IGZ1bmN0aW9uIChyYW5nZSkge1xuICB2YXIgbG9vc2UgPSB0aGlzLm9wdGlvbnMubG9vc2VcbiAgcmFuZ2UgPSByYW5nZS50cmltKClcbiAgLy8gYDEuMi4zIC0gMS4yLjRgID0+IGA+PTEuMi4zIDw9MS4yLjRgXG4gIHZhciBociA9IGxvb3NlID8gcmVbdC5IWVBIRU5SQU5HRUxPT1NFXSA6IHJlW3QuSFlQSEVOUkFOR0VdXG4gIHJhbmdlID0gcmFuZ2UucmVwbGFjZShociwgaHlwaGVuUmVwbGFjZSlcbiAgZGVidWcoJ2h5cGhlbiByZXBsYWNlJywgcmFuZ2UpXG4gIC8vIGA+IDEuMi4zIDwgMS4yLjVgID0+IGA+MS4yLjMgPDEuMi41YFxuICByYW5nZSA9IHJhbmdlLnJlcGxhY2UocmVbdC5DT01QQVJBVE9SVFJJTV0sIGNvbXBhcmF0b3JUcmltUmVwbGFjZSlcbiAgZGVidWcoJ2NvbXBhcmF0b3IgdHJpbScsIHJhbmdlLCByZVt0LkNPTVBBUkFUT1JUUklNXSlcblxuICAvLyBgfiAxLjIuM2AgPT4gYH4xLjIuM2BcbiAgcmFuZ2UgPSByYW5nZS5yZXBsYWNlKHJlW3QuVElMREVUUklNXSwgdGlsZGVUcmltUmVwbGFjZSlcblxuICAvLyBgXiAxLjIuM2AgPT4gYF4xLjIuM2BcbiAgcmFuZ2UgPSByYW5nZS5yZXBsYWNlKHJlW3QuQ0FSRVRUUklNXSwgY2FyZXRUcmltUmVwbGFjZSlcblxuICAvLyBub3JtYWxpemUgc3BhY2VzXG4gIHJhbmdlID0gcmFuZ2Uuc3BsaXQoL1xccysvKS5qb2luKCcgJylcblxuICAvLyBBdCB0aGlzIHBvaW50LCB0aGUgcmFuZ2UgaXMgY29tcGxldGVseSB0cmltbWVkIGFuZFxuICAvLyByZWFkeSB0byBiZSBzcGxpdCBpbnRvIGNvbXBhcmF0b3JzLlxuXG4gIHZhciBjb21wUmUgPSBsb29zZSA/IHJlW3QuQ09NUEFSQVRPUkxPT1NFXSA6IHJlW3QuQ09NUEFSQVRPUl1cbiAgdmFyIHNldCA9IHJhbmdlLnNwbGl0KCcgJykubWFwKGZ1bmN0aW9uIChjb21wKSB7XG4gICAgcmV0dXJuIHBhcnNlQ29tcGFyYXRvcihjb21wLCB0aGlzLm9wdGlvbnMpXG4gIH0sIHRoaXMpLmpvaW4oJyAnKS5zcGxpdCgvXFxzKy8pXG4gIGlmICh0aGlzLm9wdGlvbnMubG9vc2UpIHtcbiAgICAvLyBpbiBsb29zZSBtb2RlLCB0aHJvdyBvdXQgYW55IHRoYXQgYXJlIG5vdCB2YWxpZCBjb21wYXJhdG9yc1xuICAgIHNldCA9IHNldC5maWx0ZXIoZnVuY3Rpb24gKGNvbXApIHtcbiAgICAgIHJldHVybiAhIWNvbXAubWF0Y2goY29tcFJlKVxuICAgIH0pXG4gIH1cbiAgc2V0ID0gc2V0Lm1hcChmdW5jdGlvbiAoY29tcCkge1xuICAgIHJldHVybiBuZXcgQ29tcGFyYXRvcihjb21wLCB0aGlzLm9wdGlvbnMpXG4gIH0sIHRoaXMpXG5cbiAgcmV0dXJuIHNldFxufVxuXG5SYW5nZS5wcm90b3R5cGUuaW50ZXJzZWN0cyA9IGZ1bmN0aW9uIChyYW5nZSwgb3B0aW9ucykge1xuICBpZiAoIShyYW5nZSBpbnN0YW5jZW9mIFJhbmdlKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2EgUmFuZ2UgaXMgcmVxdWlyZWQnKVxuICB9XG5cbiAgcmV0dXJuIHRoaXMuc2V0LnNvbWUoZnVuY3Rpb24gKHRoaXNDb21wYXJhdG9ycykge1xuICAgIHJldHVybiAoXG4gICAgICBpc1NhdGlzZmlhYmxlKHRoaXNDb21wYXJhdG9ycywgb3B0aW9ucykgJiZcbiAgICAgIHJhbmdlLnNldC5zb21lKGZ1bmN0aW9uIChyYW5nZUNvbXBhcmF0b3JzKSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgaXNTYXRpc2ZpYWJsZShyYW5nZUNvbXBhcmF0b3JzLCBvcHRpb25zKSAmJlxuICAgICAgICAgIHRoaXNDb21wYXJhdG9ycy5ldmVyeShmdW5jdGlvbiAodGhpc0NvbXBhcmF0b3IpIHtcbiAgICAgICAgICAgIHJldHVybiByYW5nZUNvbXBhcmF0b3JzLmV2ZXJ5KGZ1bmN0aW9uIChyYW5nZUNvbXBhcmF0b3IpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRoaXNDb21wYXJhdG9yLmludGVyc2VjdHMocmFuZ2VDb21wYXJhdG9yLCBvcHRpb25zKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9KVxuICAgICAgICApXG4gICAgICB9KVxuICAgIClcbiAgfSlcbn1cblxuLy8gdGFrZSBhIHNldCBvZiBjb21wYXJhdG9ycyBhbmQgZGV0ZXJtaW5lIHdoZXRoZXIgdGhlcmVcbi8vIGV4aXN0cyBhIHZlcnNpb24gd2hpY2ggY2FuIHNhdGlzZnkgaXRcbmZ1bmN0aW9uIGlzU2F0aXNmaWFibGUgKGNvbXBhcmF0b3JzLCBvcHRpb25zKSB7XG4gIHZhciByZXN1bHQgPSB0cnVlXG4gIHZhciByZW1haW5pbmdDb21wYXJhdG9ycyA9IGNvbXBhcmF0b3JzLnNsaWNlKClcbiAgdmFyIHRlc3RDb21wYXJhdG9yID0gcmVtYWluaW5nQ29tcGFyYXRvcnMucG9wKClcblxuICB3aGlsZSAocmVzdWx0ICYmIHJlbWFpbmluZ0NvbXBhcmF0b3JzLmxlbmd0aCkge1xuICAgIHJlc3VsdCA9IHJlbWFpbmluZ0NvbXBhcmF0b3JzLmV2ZXJ5KGZ1bmN0aW9uIChvdGhlckNvbXBhcmF0b3IpIHtcbiAgICAgIHJldHVybiB0ZXN0Q29tcGFyYXRvci5pbnRlcnNlY3RzKG90aGVyQ29tcGFyYXRvciwgb3B0aW9ucylcbiAgICB9KVxuXG4gICAgdGVzdENvbXBhcmF0b3IgPSByZW1haW5pbmdDb21wYXJhdG9ycy5wb3AoKVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdFxufVxuXG4vLyBNb3N0bHkganVzdCBmb3IgdGVzdGluZyBhbmQgbGVnYWN5IEFQSSByZWFzb25zXG5leHBvcnRzLnRvQ29tcGFyYXRvcnMgPSB0b0NvbXBhcmF0b3JzXG5mdW5jdGlvbiB0b0NvbXBhcmF0b3JzIChyYW5nZSwgb3B0aW9ucykge1xuICByZXR1cm4gbmV3IFJhbmdlKHJhbmdlLCBvcHRpb25zKS5zZXQubWFwKGZ1bmN0aW9uIChjb21wKSB7XG4gICAgcmV0dXJuIGNvbXAubWFwKGZ1bmN0aW9uIChjKSB7XG4gICAgICByZXR1cm4gYy52YWx1ZVxuICAgIH0pLmpvaW4oJyAnKS50cmltKCkuc3BsaXQoJyAnKVxuICB9KVxufVxuXG4vLyBjb21wcmlzZWQgb2YgeHJhbmdlcywgdGlsZGVzLCBzdGFycywgYW5kIGd0bHQncyBhdCB0aGlzIHBvaW50LlxuLy8gYWxyZWFkeSByZXBsYWNlZCB0aGUgaHlwaGVuIHJhbmdlc1xuLy8gdHVybiBpbnRvIGEgc2V0IG9mIEpVU1QgY29tcGFyYXRvcnMuXG5mdW5jdGlvbiBwYXJzZUNvbXBhcmF0b3IgKGNvbXAsIG9wdGlvbnMpIHtcbiAgZGVidWcoJ2NvbXAnLCBjb21wLCBvcHRpb25zKVxuICBjb21wID0gcmVwbGFjZUNhcmV0cyhjb21wLCBvcHRpb25zKVxuICBkZWJ1ZygnY2FyZXQnLCBjb21wKVxuICBjb21wID0gcmVwbGFjZVRpbGRlcyhjb21wLCBvcHRpb25zKVxuICBkZWJ1ZygndGlsZGVzJywgY29tcClcbiAgY29tcCA9IHJlcGxhY2VYUmFuZ2VzKGNvbXAsIG9wdGlvbnMpXG4gIGRlYnVnKCd4cmFuZ2UnLCBjb21wKVxuICBjb21wID0gcmVwbGFjZVN0YXJzKGNvbXAsIG9wdGlvbnMpXG4gIGRlYnVnKCdzdGFycycsIGNvbXApXG4gIHJldHVybiBjb21wXG59XG5cbmZ1bmN0aW9uIGlzWCAoaWQpIHtcbiAgcmV0dXJuICFpZCB8fCBpZC50b0xvd2VyQ2FzZSgpID09PSAneCcgfHwgaWQgPT09ICcqJ1xufVxuXG4vLyB+LCB+PiAtLT4gKiAoYW55LCBraW5kYSBzaWxseSlcbi8vIH4yLCB+Mi54LCB+Mi54LngsIH4+Miwgfj4yLnggfj4yLngueCAtLT4gPj0yLjAuMCA8My4wLjBcbi8vIH4yLjAsIH4yLjAueCwgfj4yLjAsIH4+Mi4wLnggLS0+ID49Mi4wLjAgPDIuMS4wXG4vLyB+MS4yLCB+MS4yLngsIH4+MS4yLCB+PjEuMi54IC0tPiA+PTEuMi4wIDwxLjMuMFxuLy8gfjEuMi4zLCB+PjEuMi4zIC0tPiA+PTEuMi4zIDwxLjMuMFxuLy8gfjEuMi4wLCB+PjEuMi4wIC0tPiA+PTEuMi4wIDwxLjMuMFxuZnVuY3Rpb24gcmVwbGFjZVRpbGRlcyAoY29tcCwgb3B0aW9ucykge1xuICByZXR1cm4gY29tcC50cmltKCkuc3BsaXQoL1xccysvKS5tYXAoZnVuY3Rpb24gKGNvbXApIHtcbiAgICByZXR1cm4gcmVwbGFjZVRpbGRlKGNvbXAsIG9wdGlvbnMpXG4gIH0pLmpvaW4oJyAnKVxufVxuXG5mdW5jdGlvbiByZXBsYWNlVGlsZGUgKGNvbXAsIG9wdGlvbnMpIHtcbiAgdmFyIHIgPSBvcHRpb25zLmxvb3NlID8gcmVbdC5USUxERUxPT1NFXSA6IHJlW3QuVElMREVdXG4gIHJldHVybiBjb21wLnJlcGxhY2UociwgZnVuY3Rpb24gKF8sIE0sIG0sIHAsIHByKSB7XG4gICAgZGVidWcoJ3RpbGRlJywgY29tcCwgXywgTSwgbSwgcCwgcHIpXG4gICAgdmFyIHJldFxuXG4gICAgaWYgKGlzWChNKSkge1xuICAgICAgcmV0ID0gJydcbiAgICB9IGVsc2UgaWYgKGlzWChtKSkge1xuICAgICAgcmV0ID0gJz49JyArIE0gKyAnLjAuMCA8JyArICgrTSArIDEpICsgJy4wLjAnXG4gICAgfSBlbHNlIGlmIChpc1gocCkpIHtcbiAgICAgIC8vIH4xLjIgPT0gPj0xLjIuMCA8MS4zLjBcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuMCA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCdcbiAgICB9IGVsc2UgaWYgKHByKSB7XG4gICAgICBkZWJ1ZygncmVwbGFjZVRpbGRlIHByJywgcHIpXG4gICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICsgJy0nICsgcHIgK1xuICAgICAgICAgICAgJyA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCdcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gfjEuMi4zID09ID49MS4yLjMgPDEuMy4wXG4gICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICtcbiAgICAgICAgICAgICcgPCcgKyBNICsgJy4nICsgKCttICsgMSkgKyAnLjAnXG4gICAgfVxuXG4gICAgZGVidWcoJ3RpbGRlIHJldHVybicsIHJldClcbiAgICByZXR1cm4gcmV0XG4gIH0pXG59XG5cbi8vIF4gLS0+ICogKGFueSwga2luZGEgc2lsbHkpXG4vLyBeMiwgXjIueCwgXjIueC54IC0tPiA+PTIuMC4wIDwzLjAuMFxuLy8gXjIuMCwgXjIuMC54IC0tPiA+PTIuMC4wIDwzLjAuMFxuLy8gXjEuMiwgXjEuMi54IC0tPiA+PTEuMi4wIDwyLjAuMFxuLy8gXjEuMi4zIC0tPiA+PTEuMi4zIDwyLjAuMFxuLy8gXjEuMi4wIC0tPiA+PTEuMi4wIDwyLjAuMFxuZnVuY3Rpb24gcmVwbGFjZUNhcmV0cyAoY29tcCwgb3B0aW9ucykge1xuICByZXR1cm4gY29tcC50cmltKCkuc3BsaXQoL1xccysvKS5tYXAoZnVuY3Rpb24gKGNvbXApIHtcbiAgICByZXR1cm4gcmVwbGFjZUNhcmV0KGNvbXAsIG9wdGlvbnMpXG4gIH0pLmpvaW4oJyAnKVxufVxuXG5mdW5jdGlvbiByZXBsYWNlQ2FyZXQgKGNvbXAsIG9wdGlvbnMpIHtcbiAgZGVidWcoJ2NhcmV0JywgY29tcCwgb3B0aW9ucylcbiAgdmFyIHIgPSBvcHRpb25zLmxvb3NlID8gcmVbdC5DQVJFVExPT1NFXSA6IHJlW3QuQ0FSRVRdXG4gIHJldHVybiBjb21wLnJlcGxhY2UociwgZnVuY3Rpb24gKF8sIE0sIG0sIHAsIHByKSB7XG4gICAgZGVidWcoJ2NhcmV0JywgY29tcCwgXywgTSwgbSwgcCwgcHIpXG4gICAgdmFyIHJldFxuXG4gICAgaWYgKGlzWChNKSkge1xuICAgICAgcmV0ID0gJydcbiAgICB9IGVsc2UgaWYgKGlzWChtKSkge1xuICAgICAgcmV0ID0gJz49JyArIE0gKyAnLjAuMCA8JyArICgrTSArIDEpICsgJy4wLjAnXG4gICAgfSBlbHNlIGlmIChpc1gocCkpIHtcbiAgICAgIGlmIChNID09PSAnMCcpIHtcbiAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4wIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJ1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4wIDwnICsgKCtNICsgMSkgKyAnLjAuMCdcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHByKSB7XG4gICAgICBkZWJ1ZygncmVwbGFjZUNhcmV0IHByJywgcHIpXG4gICAgICBpZiAoTSA9PT0gJzAnKSB7XG4gICAgICAgIGlmIChtID09PSAnMCcpIHtcbiAgICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICsgJy0nICsgcHIgK1xuICAgICAgICAgICAgICAgICcgPCcgKyBNICsgJy4nICsgbSArICcuJyArICgrcCArIDEpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArICctJyArIHByICtcbiAgICAgICAgICAgICAgICAnIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJ1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICsgJy0nICsgcHIgK1xuICAgICAgICAgICAgICAnIDwnICsgKCtNICsgMSkgKyAnLjAuMCdcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZGVidWcoJ25vIHByJylcbiAgICAgIGlmIChNID09PSAnMCcpIHtcbiAgICAgICAgaWYgKG0gPT09ICcwJykge1xuICAgICAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgK1xuICAgICAgICAgICAgICAgICcgPCcgKyBNICsgJy4nICsgbSArICcuJyArICgrcCArIDEpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArXG4gICAgICAgICAgICAgICAgJyA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCdcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArXG4gICAgICAgICAgICAgICcgPCcgKyAoK00gKyAxKSArICcuMC4wJ1xuICAgICAgfVxuICAgIH1cblxuICAgIGRlYnVnKCdjYXJldCByZXR1cm4nLCByZXQpXG4gICAgcmV0dXJuIHJldFxuICB9KVxufVxuXG5mdW5jdGlvbiByZXBsYWNlWFJhbmdlcyAoY29tcCwgb3B0aW9ucykge1xuICBkZWJ1ZygncmVwbGFjZVhSYW5nZXMnLCBjb21wLCBvcHRpb25zKVxuICByZXR1cm4gY29tcC5zcGxpdCgvXFxzKy8pLm1hcChmdW5jdGlvbiAoY29tcCkge1xuICAgIHJldHVybiByZXBsYWNlWFJhbmdlKGNvbXAsIG9wdGlvbnMpXG4gIH0pLmpvaW4oJyAnKVxufVxuXG5mdW5jdGlvbiByZXBsYWNlWFJhbmdlIChjb21wLCBvcHRpb25zKSB7XG4gIGNvbXAgPSBjb21wLnRyaW0oKVxuICB2YXIgciA9IG9wdGlvbnMubG9vc2UgPyByZVt0LlhSQU5HRUxPT1NFXSA6IHJlW3QuWFJBTkdFXVxuICByZXR1cm4gY29tcC5yZXBsYWNlKHIsIGZ1bmN0aW9uIChyZXQsIGd0bHQsIE0sIG0sIHAsIHByKSB7XG4gICAgZGVidWcoJ3hSYW5nZScsIGNvbXAsIHJldCwgZ3RsdCwgTSwgbSwgcCwgcHIpXG4gICAgdmFyIHhNID0gaXNYKE0pXG4gICAgdmFyIHhtID0geE0gfHwgaXNYKG0pXG4gICAgdmFyIHhwID0geG0gfHwgaXNYKHApXG4gICAgdmFyIGFueVggPSB4cFxuXG4gICAgaWYgKGd0bHQgPT09ICc9JyAmJiBhbnlYKSB7XG4gICAgICBndGx0ID0gJydcbiAgICB9XG5cbiAgICAvLyBpZiB3ZSdyZSBpbmNsdWRpbmcgcHJlcmVsZWFzZXMgaW4gdGhlIG1hdGNoLCB0aGVuIHdlIG5lZWRcbiAgICAvLyB0byBmaXggdGhpcyB0byAtMCwgdGhlIGxvd2VzdCBwb3NzaWJsZSBwcmVyZWxlYXNlIHZhbHVlXG4gICAgcHIgPSBvcHRpb25zLmluY2x1ZGVQcmVyZWxlYXNlID8gJy0wJyA6ICcnXG5cbiAgICBpZiAoeE0pIHtcbiAgICAgIGlmIChndGx0ID09PSAnPicgfHwgZ3RsdCA9PT0gJzwnKSB7XG4gICAgICAgIC8vIG5vdGhpbmcgaXMgYWxsb3dlZFxuICAgICAgICByZXQgPSAnPDAuMC4wLTAnXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBub3RoaW5nIGlzIGZvcmJpZGRlblxuICAgICAgICByZXQgPSAnKidcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGd0bHQgJiYgYW55WCkge1xuICAgICAgLy8gd2Uga25vdyBwYXRjaCBpcyBhbiB4LCBiZWNhdXNlIHdlIGhhdmUgYW55IHggYXQgYWxsLlxuICAgICAgLy8gcmVwbGFjZSBYIHdpdGggMFxuICAgICAgaWYgKHhtKSB7XG4gICAgICAgIG0gPSAwXG4gICAgICB9XG4gICAgICBwID0gMFxuXG4gICAgICBpZiAoZ3RsdCA9PT0gJz4nKSB7XG4gICAgICAgIC8vID4xID0+ID49Mi4wLjBcbiAgICAgICAgLy8gPjEuMiA9PiA+PTEuMy4wXG4gICAgICAgIC8vID4xLjIuMyA9PiA+PSAxLjIuNFxuICAgICAgICBndGx0ID0gJz49J1xuICAgICAgICBpZiAoeG0pIHtcbiAgICAgICAgICBNID0gK00gKyAxXG4gICAgICAgICAgbSA9IDBcbiAgICAgICAgICBwID0gMFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG0gPSArbSArIDFcbiAgICAgICAgICBwID0gMFxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGd0bHQgPT09ICc8PScpIHtcbiAgICAgICAgLy8gPD0wLjcueCBpcyBhY3R1YWxseSA8MC44LjAsIHNpbmNlIGFueSAwLjcueCBzaG91bGRcbiAgICAgICAgLy8gcGFzcy4gIFNpbWlsYXJseSwgPD03LnggaXMgYWN0dWFsbHkgPDguMC4wLCBldGMuXG4gICAgICAgIGd0bHQgPSAnPCdcbiAgICAgICAgaWYgKHhtKSB7XG4gICAgICAgICAgTSA9ICtNICsgMVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG0gPSArbSArIDFcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXQgPSBndGx0ICsgTSArICcuJyArIG0gKyAnLicgKyBwICsgcHJcbiAgICB9IGVsc2UgaWYgKHhtKSB7XG4gICAgICByZXQgPSAnPj0nICsgTSArICcuMC4wJyArIHByICsgJyA8JyArICgrTSArIDEpICsgJy4wLjAnICsgcHJcbiAgICB9IGVsc2UgaWYgKHhwKSB7XG4gICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLjAnICsgcHIgK1xuICAgICAgICAnIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJyArIHByXG4gICAgfVxuXG4gICAgZGVidWcoJ3hSYW5nZSByZXR1cm4nLCByZXQpXG5cbiAgICByZXR1cm4gcmV0XG4gIH0pXG59XG5cbi8vIEJlY2F1c2UgKiBpcyBBTkQtZWQgd2l0aCBldmVyeXRoaW5nIGVsc2UgaW4gdGhlIGNvbXBhcmF0b3IsXG4vLyBhbmQgJycgbWVhbnMgXCJhbnkgdmVyc2lvblwiLCBqdXN0IHJlbW92ZSB0aGUgKnMgZW50aXJlbHkuXG5mdW5jdGlvbiByZXBsYWNlU3RhcnMgKGNvbXAsIG9wdGlvbnMpIHtcbiAgZGVidWcoJ3JlcGxhY2VTdGFycycsIGNvbXAsIG9wdGlvbnMpXG4gIC8vIExvb3NlbmVzcyBpcyBpZ25vcmVkIGhlcmUuICBzdGFyIGlzIGFsd2F5cyBhcyBsb29zZSBhcyBpdCBnZXRzIVxuICByZXR1cm4gY29tcC50cmltKCkucmVwbGFjZShyZVt0LlNUQVJdLCAnJylcbn1cblxuLy8gVGhpcyBmdW5jdGlvbiBpcyBwYXNzZWQgdG8gc3RyaW5nLnJlcGxhY2UocmVbdC5IWVBIRU5SQU5HRV0pXG4vLyBNLCBtLCBwYXRjaCwgcHJlcmVsZWFzZSwgYnVpbGRcbi8vIDEuMiAtIDMuNC41ID0+ID49MS4yLjAgPD0zLjQuNVxuLy8gMS4yLjMgLSAzLjQgPT4gPj0xLjIuMCA8My41LjAgQW55IDMuNC54IHdpbGwgZG9cbi8vIDEuMiAtIDMuNCA9PiA+PTEuMi4wIDwzLjUuMFxuZnVuY3Rpb24gaHlwaGVuUmVwbGFjZSAoJDAsXG4gIGZyb20sIGZNLCBmbSwgZnAsIGZwciwgZmIsXG4gIHRvLCB0TSwgdG0sIHRwLCB0cHIsIHRiKSB7XG4gIGlmIChpc1goZk0pKSB7XG4gICAgZnJvbSA9ICcnXG4gIH0gZWxzZSBpZiAoaXNYKGZtKSkge1xuICAgIGZyb20gPSAnPj0nICsgZk0gKyAnLjAuMCdcbiAgfSBlbHNlIGlmIChpc1goZnApKSB7XG4gICAgZnJvbSA9ICc+PScgKyBmTSArICcuJyArIGZtICsgJy4wJ1xuICB9IGVsc2Uge1xuICAgIGZyb20gPSAnPj0nICsgZnJvbVxuICB9XG5cbiAgaWYgKGlzWCh0TSkpIHtcbiAgICB0byA9ICcnXG4gIH0gZWxzZSBpZiAoaXNYKHRtKSkge1xuICAgIHRvID0gJzwnICsgKCt0TSArIDEpICsgJy4wLjAnXG4gIH0gZWxzZSBpZiAoaXNYKHRwKSkge1xuICAgIHRvID0gJzwnICsgdE0gKyAnLicgKyAoK3RtICsgMSkgKyAnLjAnXG4gIH0gZWxzZSBpZiAodHByKSB7XG4gICAgdG8gPSAnPD0nICsgdE0gKyAnLicgKyB0bSArICcuJyArIHRwICsgJy0nICsgdHByXG4gIH0gZWxzZSB7XG4gICAgdG8gPSAnPD0nICsgdG9cbiAgfVxuXG4gIHJldHVybiAoZnJvbSArICcgJyArIHRvKS50cmltKClcbn1cblxuLy8gaWYgQU5ZIG9mIHRoZSBzZXRzIG1hdGNoIEFMTCBvZiBpdHMgY29tcGFyYXRvcnMsIHRoZW4gcGFzc1xuUmFuZ2UucHJvdG90eXBlLnRlc3QgPSBmdW5jdGlvbiAodmVyc2lvbikge1xuICBpZiAoIXZlcnNpb24pIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIGlmICh0eXBlb2YgdmVyc2lvbiA9PT0gJ3N0cmluZycpIHtcbiAgICB0cnkge1xuICAgICAgdmVyc2lvbiA9IG5ldyBTZW1WZXIodmVyc2lvbiwgdGhpcy5vcHRpb25zKVxuICAgIH0gY2F0Y2ggKGVyKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gIH1cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuc2V0Lmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHRlc3RTZXQodGhpcy5zZXRbaV0sIHZlcnNpb24sIHRoaXMub3B0aW9ucykpIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZVxufVxuXG5mdW5jdGlvbiB0ZXN0U2V0IChzZXQsIHZlcnNpb24sIG9wdGlvbnMpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZXQubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoIXNldFtpXS50ZXN0KHZlcnNpb24pKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gIH1cblxuICBpZiAodmVyc2lvbi5wcmVyZWxlYXNlLmxlbmd0aCAmJiAhb3B0aW9ucy5pbmNsdWRlUHJlcmVsZWFzZSkge1xuICAgIC8vIEZpbmQgdGhlIHNldCBvZiB2ZXJzaW9ucyB0aGF0IGFyZSBhbGxvd2VkIHRvIGhhdmUgcHJlcmVsZWFzZXNcbiAgICAvLyBGb3IgZXhhbXBsZSwgXjEuMi4zLXByLjEgZGVzdWdhcnMgdG8gPj0xLjIuMy1wci4xIDwyLjAuMFxuICAgIC8vIFRoYXQgc2hvdWxkIGFsbG93IGAxLjIuMy1wci4yYCB0byBwYXNzLlxuICAgIC8vIEhvd2V2ZXIsIGAxLjIuNC1hbHBoYS5ub3RyZWFkeWAgc2hvdWxkIE5PVCBiZSBhbGxvd2VkLFxuICAgIC8vIGV2ZW4gdGhvdWdoIGl0J3Mgd2l0aGluIHRoZSByYW5nZSBzZXQgYnkgdGhlIGNvbXBhcmF0b3JzLlxuICAgIGZvciAoaSA9IDA7IGkgPCBzZXQubGVuZ3RoOyBpKyspIHtcbiAgICAgIGRlYnVnKHNldFtpXS5zZW12ZXIpXG4gICAgICBpZiAoc2V0W2ldLnNlbXZlciA9PT0gQU5ZKSB7XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChzZXRbaV0uc2VtdmVyLnByZXJlbGVhc2UubGVuZ3RoID4gMCkge1xuICAgICAgICB2YXIgYWxsb3dlZCA9IHNldFtpXS5zZW12ZXJcbiAgICAgICAgaWYgKGFsbG93ZWQubWFqb3IgPT09IHZlcnNpb24ubWFqb3IgJiZcbiAgICAgICAgICAgIGFsbG93ZWQubWlub3IgPT09IHZlcnNpb24ubWlub3IgJiZcbiAgICAgICAgICAgIGFsbG93ZWQucGF0Y2ggPT09IHZlcnNpb24ucGF0Y2gpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVmVyc2lvbiBoYXMgYSAtcHJlLCBidXQgaXQncyBub3Qgb25lIG9mIHRoZSBvbmVzIHdlIGxpa2UuXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICByZXR1cm4gdHJ1ZVxufVxuXG5leHBvcnRzLnNhdGlzZmllcyA9IHNhdGlzZmllc1xuZnVuY3Rpb24gc2F0aXNmaWVzICh2ZXJzaW9uLCByYW5nZSwgb3B0aW9ucykge1xuICB0cnkge1xuICAgIHJhbmdlID0gbmV3IFJhbmdlKHJhbmdlLCBvcHRpb25zKVxuICB9IGNhdGNoIChlcikge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIHJldHVybiByYW5nZS50ZXN0KHZlcnNpb24pXG59XG5cbmV4cG9ydHMubWF4U2F0aXNmeWluZyA9IG1heFNhdGlzZnlpbmdcbmZ1bmN0aW9uIG1heFNhdGlzZnlpbmcgKHZlcnNpb25zLCByYW5nZSwgb3B0aW9ucykge1xuICB2YXIgbWF4ID0gbnVsbFxuICB2YXIgbWF4U1YgPSBudWxsXG4gIHRyeSB7XG4gICAgdmFyIHJhbmdlT2JqID0gbmV3IFJhbmdlKHJhbmdlLCBvcHRpb25zKVxuICB9IGNhdGNoIChlcikge1xuICAgIHJldHVybiBudWxsXG4gIH1cbiAgdmVyc2lvbnMuZm9yRWFjaChmdW5jdGlvbiAodikge1xuICAgIGlmIChyYW5nZU9iai50ZXN0KHYpKSB7XG4gICAgICAvLyBzYXRpc2ZpZXModiwgcmFuZ2UsIG9wdGlvbnMpXG4gICAgICBpZiAoIW1heCB8fCBtYXhTVi5jb21wYXJlKHYpID09PSAtMSkge1xuICAgICAgICAvLyBjb21wYXJlKG1heCwgdiwgdHJ1ZSlcbiAgICAgICAgbWF4ID0gdlxuICAgICAgICBtYXhTViA9IG5ldyBTZW1WZXIobWF4LCBvcHRpb25zKVxuICAgICAgfVxuICAgIH1cbiAgfSlcbiAgcmV0dXJuIG1heFxufVxuXG5leHBvcnRzLm1pblNhdGlzZnlpbmcgPSBtaW5TYXRpc2Z5aW5nXG5mdW5jdGlvbiBtaW5TYXRpc2Z5aW5nICh2ZXJzaW9ucywgcmFuZ2UsIG9wdGlvbnMpIHtcbiAgdmFyIG1pbiA9IG51bGxcbiAgdmFyIG1pblNWID0gbnVsbFxuICB0cnkge1xuICAgIHZhciByYW5nZU9iaiA9IG5ldyBSYW5nZShyYW5nZSwgb3B0aW9ucylcbiAgfSBjYXRjaCAoZXIpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG4gIHZlcnNpb25zLmZvckVhY2goZnVuY3Rpb24gKHYpIHtcbiAgICBpZiAocmFuZ2VPYmoudGVzdCh2KSkge1xuICAgICAgLy8gc2F0aXNmaWVzKHYsIHJhbmdlLCBvcHRpb25zKVxuICAgICAgaWYgKCFtaW4gfHwgbWluU1YuY29tcGFyZSh2KSA9PT0gMSkge1xuICAgICAgICAvLyBjb21wYXJlKG1pbiwgdiwgdHJ1ZSlcbiAgICAgICAgbWluID0gdlxuICAgICAgICBtaW5TViA9IG5ldyBTZW1WZXIobWluLCBvcHRpb25zKVxuICAgICAgfVxuICAgIH1cbiAgfSlcbiAgcmV0dXJuIG1pblxufVxuXG5leHBvcnRzLm1pblZlcnNpb24gPSBtaW5WZXJzaW9uXG5mdW5jdGlvbiBtaW5WZXJzaW9uIChyYW5nZSwgbG9vc2UpIHtcbiAgcmFuZ2UgPSBuZXcgUmFuZ2UocmFuZ2UsIGxvb3NlKVxuXG4gIHZhciBtaW52ZXIgPSBuZXcgU2VtVmVyKCcwLjAuMCcpXG4gIGlmIChyYW5nZS50ZXN0KG1pbnZlcikpIHtcbiAgICByZXR1cm4gbWludmVyXG4gIH1cblxuICBtaW52ZXIgPSBuZXcgU2VtVmVyKCcwLjAuMC0wJylcbiAgaWYgKHJhbmdlLnRlc3QobWludmVyKSkge1xuICAgIHJldHVybiBtaW52ZXJcbiAgfVxuXG4gIG1pbnZlciA9IG51bGxcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCByYW5nZS5zZXQubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgY29tcGFyYXRvcnMgPSByYW5nZS5zZXRbaV1cblxuICAgIGNvbXBhcmF0b3JzLmZvckVhY2goZnVuY3Rpb24gKGNvbXBhcmF0b3IpIHtcbiAgICAgIC8vIENsb25lIHRvIGF2b2lkIG1hbmlwdWxhdGluZyB0aGUgY29tcGFyYXRvcidzIHNlbXZlciBvYmplY3QuXG4gICAgICB2YXIgY29tcHZlciA9IG5ldyBTZW1WZXIoY29tcGFyYXRvci5zZW12ZXIudmVyc2lvbilcbiAgICAgIHN3aXRjaCAoY29tcGFyYXRvci5vcGVyYXRvcikge1xuICAgICAgICBjYXNlICc+JzpcbiAgICAgICAgICBpZiAoY29tcHZlci5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgY29tcHZlci5wYXRjaCsrXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbXB2ZXIucHJlcmVsZWFzZS5wdXNoKDApXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbXB2ZXIucmF3ID0gY29tcHZlci5mb3JtYXQoKVxuICAgICAgICAgIC8qIGZhbGx0aHJvdWdoICovXG4gICAgICAgIGNhc2UgJyc6XG4gICAgICAgIGNhc2UgJz49JzpcbiAgICAgICAgICBpZiAoIW1pbnZlciB8fCBndChtaW52ZXIsIGNvbXB2ZXIpKSB7XG4gICAgICAgICAgICBtaW52ZXIgPSBjb21wdmVyXG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgJzwnOlxuICAgICAgICBjYXNlICc8PSc6XG4gICAgICAgICAgLyogSWdub3JlIG1heGltdW0gdmVyc2lvbnMgKi9cbiAgICAgICAgICBicmVha1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCBvcGVyYXRpb246ICcgKyBjb21wYXJhdG9yLm9wZXJhdG9yKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICBpZiAobWludmVyICYmIHJhbmdlLnRlc3QobWludmVyKSkge1xuICAgIHJldHVybiBtaW52ZXJcbiAgfVxuXG4gIHJldHVybiBudWxsXG59XG5cbmV4cG9ydHMudmFsaWRSYW5nZSA9IHZhbGlkUmFuZ2VcbmZ1bmN0aW9uIHZhbGlkUmFuZ2UgKHJhbmdlLCBvcHRpb25zKSB7XG4gIHRyeSB7XG4gICAgLy8gUmV0dXJuICcqJyBpbnN0ZWFkIG9mICcnIHNvIHRoYXQgdHJ1dGhpbmVzcyB3b3Jrcy5cbiAgICAvLyBUaGlzIHdpbGwgdGhyb3cgaWYgaXQncyBpbnZhbGlkIGFueXdheVxuICAgIHJldHVybiBuZXcgUmFuZ2UocmFuZ2UsIG9wdGlvbnMpLnJhbmdlIHx8ICcqJ1xuICB9IGNhdGNoIChlcikge1xuICAgIHJldHVybiBudWxsXG4gIH1cbn1cblxuLy8gRGV0ZXJtaW5lIGlmIHZlcnNpb24gaXMgbGVzcyB0aGFuIGFsbCB0aGUgdmVyc2lvbnMgcG9zc2libGUgaW4gdGhlIHJhbmdlXG5leHBvcnRzLmx0ciA9IGx0clxuZnVuY3Rpb24gbHRyICh2ZXJzaW9uLCByYW5nZSwgb3B0aW9ucykge1xuICByZXR1cm4gb3V0c2lkZSh2ZXJzaW9uLCByYW5nZSwgJzwnLCBvcHRpb25zKVxufVxuXG4vLyBEZXRlcm1pbmUgaWYgdmVyc2lvbiBpcyBncmVhdGVyIHRoYW4gYWxsIHRoZSB2ZXJzaW9ucyBwb3NzaWJsZSBpbiB0aGUgcmFuZ2UuXG5leHBvcnRzLmd0ciA9IGd0clxuZnVuY3Rpb24gZ3RyICh2ZXJzaW9uLCByYW5nZSwgb3B0aW9ucykge1xuICByZXR1cm4gb3V0c2lkZSh2ZXJzaW9uLCByYW5nZSwgJz4nLCBvcHRpb25zKVxufVxuXG5leHBvcnRzLm91dHNpZGUgPSBvdXRzaWRlXG5mdW5jdGlvbiBvdXRzaWRlICh2ZXJzaW9uLCByYW5nZSwgaGlsbywgb3B0aW9ucykge1xuICB2ZXJzaW9uID0gbmV3IFNlbVZlcih2ZXJzaW9uLCBvcHRpb25zKVxuICByYW5nZSA9IG5ldyBSYW5nZShyYW5nZSwgb3B0aW9ucylcblxuICB2YXIgZ3RmbiwgbHRlZm4sIGx0Zm4sIGNvbXAsIGVjb21wXG4gIHN3aXRjaCAoaGlsbykge1xuICAgIGNhc2UgJz4nOlxuICAgICAgZ3RmbiA9IGd0XG4gICAgICBsdGVmbiA9IGx0ZVxuICAgICAgbHRmbiA9IGx0XG4gICAgICBjb21wID0gJz4nXG4gICAgICBlY29tcCA9ICc+PSdcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnPCc6XG4gICAgICBndGZuID0gbHRcbiAgICAgIGx0ZWZuID0gZ3RlXG4gICAgICBsdGZuID0gZ3RcbiAgICAgIGNvbXAgPSAnPCdcbiAgICAgIGVjb21wID0gJzw9J1xuICAgICAgYnJlYWtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignTXVzdCBwcm92aWRlIGEgaGlsbyB2YWwgb2YgXCI8XCIgb3IgXCI+XCInKVxuICB9XG5cbiAgLy8gSWYgaXQgc2F0aXNpZmVzIHRoZSByYW5nZSBpdCBpcyBub3Qgb3V0c2lkZVxuICBpZiAoc2F0aXNmaWVzKHZlcnNpb24sIHJhbmdlLCBvcHRpb25zKSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLy8gRnJvbSBub3cgb24sIHZhcmlhYmxlIHRlcm1zIGFyZSBhcyBpZiB3ZSdyZSBpbiBcImd0clwiIG1vZGUuXG4gIC8vIGJ1dCBub3RlIHRoYXQgZXZlcnl0aGluZyBpcyBmbGlwcGVkIGZvciB0aGUgXCJsdHJcIiBmdW5jdGlvbi5cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHJhbmdlLnNldC5sZW5ndGg7ICsraSkge1xuICAgIHZhciBjb21wYXJhdG9ycyA9IHJhbmdlLnNldFtpXVxuXG4gICAgdmFyIGhpZ2ggPSBudWxsXG4gICAgdmFyIGxvdyA9IG51bGxcblxuICAgIGNvbXBhcmF0b3JzLmZvckVhY2goZnVuY3Rpb24gKGNvbXBhcmF0b3IpIHtcbiAgICAgIGlmIChjb21wYXJhdG9yLnNlbXZlciA9PT0gQU5ZKSB7XG4gICAgICAgIGNvbXBhcmF0b3IgPSBuZXcgQ29tcGFyYXRvcignPj0wLjAuMCcpXG4gICAgICB9XG4gICAgICBoaWdoID0gaGlnaCB8fCBjb21wYXJhdG9yXG4gICAgICBsb3cgPSBsb3cgfHwgY29tcGFyYXRvclxuICAgICAgaWYgKGd0Zm4oY29tcGFyYXRvci5zZW12ZXIsIGhpZ2guc2VtdmVyLCBvcHRpb25zKSkge1xuICAgICAgICBoaWdoID0gY29tcGFyYXRvclxuICAgICAgfSBlbHNlIGlmIChsdGZuKGNvbXBhcmF0b3Iuc2VtdmVyLCBsb3cuc2VtdmVyLCBvcHRpb25zKSkge1xuICAgICAgICBsb3cgPSBjb21wYXJhdG9yXG4gICAgICB9XG4gICAgfSlcblxuICAgIC8vIElmIHRoZSBlZGdlIHZlcnNpb24gY29tcGFyYXRvciBoYXMgYSBvcGVyYXRvciB0aGVuIG91ciB2ZXJzaW9uXG4gICAgLy8gaXNuJ3Qgb3V0c2lkZSBpdFxuICAgIGlmIChoaWdoLm9wZXJhdG9yID09PSBjb21wIHx8IGhpZ2gub3BlcmF0b3IgPT09IGVjb21wKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgbG93ZXN0IHZlcnNpb24gY29tcGFyYXRvciBoYXMgYW4gb3BlcmF0b3IgYW5kIG91ciB2ZXJzaW9uXG4gICAgLy8gaXMgbGVzcyB0aGFuIGl0IHRoZW4gaXQgaXNuJ3QgaGlnaGVyIHRoYW4gdGhlIHJhbmdlXG4gICAgaWYgKCghbG93Lm9wZXJhdG9yIHx8IGxvdy5vcGVyYXRvciA9PT0gY29tcCkgJiZcbiAgICAgICAgbHRlZm4odmVyc2lvbiwgbG93LnNlbXZlcikpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH0gZWxzZSBpZiAobG93Lm9wZXJhdG9yID09PSBlY29tcCAmJiBsdGZuKHZlcnNpb24sIGxvdy5zZW12ZXIpKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWVcbn1cblxuZXhwb3J0cy5wcmVyZWxlYXNlID0gcHJlcmVsZWFzZVxuZnVuY3Rpb24gcHJlcmVsZWFzZSAodmVyc2lvbiwgb3B0aW9ucykge1xuICB2YXIgcGFyc2VkID0gcGFyc2UodmVyc2lvbiwgb3B0aW9ucylcbiAgcmV0dXJuIChwYXJzZWQgJiYgcGFyc2VkLnByZXJlbGVhc2UubGVuZ3RoKSA/IHBhcnNlZC5wcmVyZWxlYXNlIDogbnVsbFxufVxuXG5leHBvcnRzLmludGVyc2VjdHMgPSBpbnRlcnNlY3RzXG5mdW5jdGlvbiBpbnRlcnNlY3RzIChyMSwgcjIsIG9wdGlvbnMpIHtcbiAgcjEgPSBuZXcgUmFuZ2UocjEsIG9wdGlvbnMpXG4gIHIyID0gbmV3IFJhbmdlKHIyLCBvcHRpb25zKVxuICByZXR1cm4gcjEuaW50ZXJzZWN0cyhyMilcbn1cblxuZXhwb3J0cy5jb2VyY2UgPSBjb2VyY2VcbmZ1bmN0aW9uIGNvZXJjZSAodmVyc2lvbiwgb3B0aW9ucykge1xuICBpZiAodmVyc2lvbiBpbnN0YW5jZW9mIFNlbVZlcikge1xuICAgIHJldHVybiB2ZXJzaW9uXG4gIH1cblxuICBpZiAodHlwZW9mIHZlcnNpb24gPT09ICdudW1iZXInKSB7XG4gICAgdmVyc2lvbiA9IFN0cmluZyh2ZXJzaW9uKVxuICB9XG5cbiAgaWYgKHR5cGVvZiB2ZXJzaW9uICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuXG4gIHZhciBtYXRjaCA9IG51bGxcbiAgaWYgKCFvcHRpb25zLnJ0bCkge1xuICAgIG1hdGNoID0gdmVyc2lvbi5tYXRjaChyZVt0LkNPRVJDRV0pXG4gIH0gZWxzZSB7XG4gICAgLy8gRmluZCB0aGUgcmlnaHQtbW9zdCBjb2VyY2libGUgc3RyaW5nIHRoYXQgZG9lcyBub3Qgc2hhcmVcbiAgICAvLyBhIHRlcm1pbnVzIHdpdGggYSBtb3JlIGxlZnQtd2FyZCBjb2VyY2libGUgc3RyaW5nLlxuICAgIC8vIEVnLCAnMS4yLjMuNCcgd2FudHMgdG8gY29lcmNlICcyLjMuNCcsIG5vdCAnMy40JyBvciAnNCdcbiAgICAvL1xuICAgIC8vIFdhbGsgdGhyb3VnaCB0aGUgc3RyaW5nIGNoZWNraW5nIHdpdGggYSAvZyByZWdleHBcbiAgICAvLyBNYW51YWxseSBzZXQgdGhlIGluZGV4IHNvIGFzIHRvIHBpY2sgdXAgb3ZlcmxhcHBpbmcgbWF0Y2hlcy5cbiAgICAvLyBTdG9wIHdoZW4gd2UgZ2V0IGEgbWF0Y2ggdGhhdCBlbmRzIGF0IHRoZSBzdHJpbmcgZW5kLCBzaW5jZSBub1xuICAgIC8vIGNvZXJjaWJsZSBzdHJpbmcgY2FuIGJlIG1vcmUgcmlnaHQtd2FyZCB3aXRob3V0IHRoZSBzYW1lIHRlcm1pbnVzLlxuICAgIHZhciBuZXh0XG4gICAgd2hpbGUgKChuZXh0ID0gcmVbdC5DT0VSQ0VSVExdLmV4ZWModmVyc2lvbikpICYmXG4gICAgICAoIW1hdGNoIHx8IG1hdGNoLmluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoICE9PSB2ZXJzaW9uLmxlbmd0aClcbiAgICApIHtcbiAgICAgIGlmICghbWF0Y2ggfHxcbiAgICAgICAgICBuZXh0LmluZGV4ICsgbmV4dFswXS5sZW5ndGggIT09IG1hdGNoLmluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoKSB7XG4gICAgICAgIG1hdGNoID0gbmV4dFxuICAgICAgfVxuICAgICAgcmVbdC5DT0VSQ0VSVExdLmxhc3RJbmRleCA9IG5leHQuaW5kZXggKyBuZXh0WzFdLmxlbmd0aCArIG5leHRbMl0ubGVuZ3RoXG4gICAgfVxuICAgIC8vIGxlYXZlIGl0IGluIGEgY2xlYW4gc3RhdGVcbiAgICByZVt0LkNPRVJDRVJUTF0ubGFzdEluZGV4ID0gLTFcbiAgfVxuXG4gIGlmIChtYXRjaCA9PT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICByZXR1cm4gcGFyc2UobWF0Y2hbMl0gK1xuICAgICcuJyArIChtYXRjaFszXSB8fCAnMCcpICtcbiAgICAnLicgKyAobWF0Y2hbNF0gfHwgJzAnKSwgb3B0aW9ucylcbn1cbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIEVSUk9SX01TR1MgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2Vycm9yX21zZ3NcIik7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xuZnVuY3Rpb24gdGFnUGFyYW1ldGVyKGFubm90YXRpb25UYXJnZXQsIHByb3BlcnR5TmFtZSwgcGFyYW1ldGVySW5kZXgsIG1ldGFkYXRhKSB7XG4gICAgdmFyIG1ldGFkYXRhS2V5ID0gTUVUQURBVEFfS0VZLlRBR0dFRDtcbiAgICBfdGFnUGFyYW1ldGVyT3JQcm9wZXJ0eShtZXRhZGF0YUtleSwgYW5ub3RhdGlvblRhcmdldCwgcHJvcGVydHlOYW1lLCBtZXRhZGF0YSwgcGFyYW1ldGVySW5kZXgpO1xufVxuZXhwb3J0cy50YWdQYXJhbWV0ZXIgPSB0YWdQYXJhbWV0ZXI7XG5mdW5jdGlvbiB0YWdQcm9wZXJ0eShhbm5vdGF0aW9uVGFyZ2V0LCBwcm9wZXJ0eU5hbWUsIG1ldGFkYXRhKSB7XG4gICAgdmFyIG1ldGFkYXRhS2V5ID0gTUVUQURBVEFfS0VZLlRBR0dFRF9QUk9QO1xuICAgIF90YWdQYXJhbWV0ZXJPclByb3BlcnR5KG1ldGFkYXRhS2V5LCBhbm5vdGF0aW9uVGFyZ2V0LmNvbnN0cnVjdG9yLCBwcm9wZXJ0eU5hbWUsIG1ldGFkYXRhKTtcbn1cbmV4cG9ydHMudGFnUHJvcGVydHkgPSB0YWdQcm9wZXJ0eTtcbmZ1bmN0aW9uIF90YWdQYXJhbWV0ZXJPclByb3BlcnR5KG1ldGFkYXRhS2V5LCBhbm5vdGF0aW9uVGFyZ2V0LCBwcm9wZXJ0eU5hbWUsIG1ldGFkYXRhLCBwYXJhbWV0ZXJJbmRleCkge1xuICAgIHZhciBwYXJhbXNPclByb3BlcnRpZXNNZXRhZGF0YSA9IHt9O1xuICAgIHZhciBpc1BhcmFtZXRlckRlY29yYXRvciA9ICh0eXBlb2YgcGFyYW1ldGVySW5kZXggPT09IFwibnVtYmVyXCIpO1xuICAgIHZhciBrZXkgPSAocGFyYW1ldGVySW5kZXggIT09IHVuZGVmaW5lZCAmJiBpc1BhcmFtZXRlckRlY29yYXRvcikgPyBwYXJhbWV0ZXJJbmRleC50b1N0cmluZygpIDogcHJvcGVydHlOYW1lO1xuICAgIGlmIChpc1BhcmFtZXRlckRlY29yYXRvciAmJiBwcm9wZXJ0eU5hbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTVNHUy5JTlZBTElEX0RFQ09SQVRPUl9PUEVSQVRJT04pO1xuICAgIH1cbiAgICBpZiAoUmVmbGVjdC5oYXNPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgYW5ub3RhdGlvblRhcmdldCkpIHtcbiAgICAgICAgcGFyYW1zT3JQcm9wZXJ0aWVzTWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKG1ldGFkYXRhS2V5LCBhbm5vdGF0aW9uVGFyZ2V0KTtcbiAgICB9XG4gICAgdmFyIHBhcmFtT3JQcm9wZXJ0eU1ldGFkYXRhID0gcGFyYW1zT3JQcm9wZXJ0aWVzTWV0YWRhdGFba2V5XTtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkocGFyYW1PclByb3BlcnR5TWV0YWRhdGEpKSB7XG4gICAgICAgIHBhcmFtT3JQcm9wZXJ0eU1ldGFkYXRhID0gW107XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBmb3IgKHZhciBfaSA9IDAsIHBhcmFtT3JQcm9wZXJ0eU1ldGFkYXRhXzEgPSBwYXJhbU9yUHJvcGVydHlNZXRhZGF0YTsgX2kgPCBwYXJhbU9yUHJvcGVydHlNZXRhZGF0YV8xLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgdmFyIG0gPSBwYXJhbU9yUHJvcGVydHlNZXRhZGF0YV8xW19pXTtcbiAgICAgICAgICAgIGlmIChtLmtleSA9PT0gbWV0YWRhdGEua2V5KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuRFVQTElDQVRFRF9NRVRBREFUQSArIFwiIFwiICsgbS5rZXkudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcGFyYW1PclByb3BlcnR5TWV0YWRhdGEucHVzaChtZXRhZGF0YSk7XG4gICAgcGFyYW1zT3JQcm9wZXJ0aWVzTWV0YWRhdGFba2V5XSA9IHBhcmFtT3JQcm9wZXJ0eU1ldGFkYXRhO1xuICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEobWV0YWRhdGFLZXksIHBhcmFtc09yUHJvcGVydGllc01ldGFkYXRhLCBhbm5vdGF0aW9uVGFyZ2V0KTtcbn1cbmZ1bmN0aW9uIF9kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQpIHtcbiAgICBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCk7XG59XG5mdW5jdGlvbiBfcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9O1xufVxuZnVuY3Rpb24gZGVjb3JhdGUoZGVjb3JhdG9yLCB0YXJnZXQsIHBhcmFtZXRlckluZGV4KSB7XG4gICAgaWYgKHR5cGVvZiBwYXJhbWV0ZXJJbmRleCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICBfZGVjb3JhdGUoW19wYXJhbShwYXJhbWV0ZXJJbmRleCwgZGVjb3JhdG9yKV0sIHRhcmdldCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBwYXJhbWV0ZXJJbmRleCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICBSZWZsZWN0LmRlY29yYXRlKFtkZWNvcmF0b3JdLCB0YXJnZXQsIHBhcmFtZXRlckluZGV4KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIF9kZWNvcmF0ZShbZGVjb3JhdG9yXSwgdGFyZ2V0KTtcbiAgICB9XG59XG5leHBvcnRzLmRlY29yYXRlID0gZGVjb3JhdGU7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBlcnJvcl9tc2dzXzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2Vycm9yX21zZ3NcIik7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvbWV0YWRhdGFcIik7XG52YXIgZGVjb3JhdG9yX3V0aWxzXzEgPSByZXF1aXJlKFwiLi9kZWNvcmF0b3JfdXRpbHNcIik7XG52YXIgTGF6eVNlcnZpY2VJZGVudGlmZXIgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIExhenlTZXJ2aWNlSWRlbnRpZmVyKGNiKSB7XG4gICAgICAgIHRoaXMuX2NiID0gY2I7XG4gICAgfVxuICAgIExhenlTZXJ2aWNlSWRlbnRpZmVyLnByb3RvdHlwZS51bndyYXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYigpO1xuICAgIH07XG4gICAgcmV0dXJuIExhenlTZXJ2aWNlSWRlbnRpZmVyO1xufSgpKTtcbmV4cG9ydHMuTGF6eVNlcnZpY2VJZGVudGlmZXIgPSBMYXp5U2VydmljZUlkZW50aWZlcjtcbmZ1bmN0aW9uIGluamVjdChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCB0YXJnZXRLZXksIGluZGV4KSB7XG4gICAgICAgIGlmIChzZXJ2aWNlSWRlbnRpZmllciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JfbXNnc18xLlVOREVGSU5FRF9JTkpFQ1RfQU5OT1RBVElPTih0YXJnZXQubmFtZSkpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBtZXRhZGF0YSA9IG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKE1FVEFEQVRBX0tFWS5JTkpFQ1RfVEFHLCBzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIGlmICh0eXBlb2YgaW5kZXggPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIGRlY29yYXRvcl91dGlsc18xLnRhZ1BhcmFtZXRlcih0YXJnZXQsIHRhcmdldEtleSwgaW5kZXgsIG1ldGFkYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRlY29yYXRvcl91dGlsc18xLnRhZ1Byb3BlcnR5KHRhcmdldCwgdGFyZ2V0S2V5LCBtZXRhZGF0YSk7XG4gICAgICAgIH1cbiAgICB9O1xufVxuZXhwb3J0cy5pbmplY3QgPSBpbmplY3Q7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBFUlJPUlNfTVNHUyA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbnZhciBNRVRBREFUQV9LRVkgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG5mdW5jdGlvbiBpbmplY3RhYmxlKCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0KSB7XG4gICAgICAgIGlmIChSZWZsZWN0Lmhhc093bk1ldGFkYXRhKE1FVEFEQVRBX0tFWS5QQVJBTV9UWVBFUywgdGFyZ2V0KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SU19NU0dTLkRVUExJQ0FURURfSU5KRUNUQUJMRV9ERUNPUkFUT1IpO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0eXBlcyA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoTUVUQURBVEFfS0VZLkRFU0lHTl9QQVJBTV9UWVBFUywgdGFyZ2V0KSB8fCBbXTtcbiAgICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShNRVRBREFUQV9LRVkuUEFSQU1fVFlQRVMsIHR5cGVzLCB0YXJnZXQpO1xuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH07XG59XG5leHBvcnRzLmluamVjdGFibGUgPSBpbmplY3RhYmxlO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvbWV0YWRhdGFcIik7XG52YXIgZGVjb3JhdG9yX3V0aWxzXzEgPSByZXF1aXJlKFwiLi9kZWNvcmF0b3JfdXRpbHNcIik7XG5mdW5jdGlvbiBtdWx0aUluamVjdChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCB0YXJnZXRLZXksIGluZGV4KSB7XG4gICAgICAgIHZhciBtZXRhZGF0YSA9IG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKE1FVEFEQVRBX0tFWS5NVUxUSV9JTkpFQ1RfVEFHLCBzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIGlmICh0eXBlb2YgaW5kZXggPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIGRlY29yYXRvcl91dGlsc18xLnRhZ1BhcmFtZXRlcih0YXJnZXQsIHRhcmdldEtleSwgaW5kZXgsIG1ldGFkYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRlY29yYXRvcl91dGlsc18xLnRhZ1Byb3BlcnR5KHRhcmdldCwgdGFyZ2V0S2V5LCBtZXRhZGF0YSk7XG4gICAgICAgIH1cbiAgICB9O1xufVxuZXhwb3J0cy5tdWx0aUluamVjdCA9IG11bHRpSW5qZWN0O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvbWV0YWRhdGFcIik7XG52YXIgZGVjb3JhdG9yX3V0aWxzXzEgPSByZXF1aXJlKFwiLi9kZWNvcmF0b3JfdXRpbHNcIik7XG5mdW5jdGlvbiBuYW1lZChuYW1lKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIHRhcmdldEtleSwgaW5kZXgpIHtcbiAgICAgICAgdmFyIG1ldGFkYXRhID0gbmV3IG1ldGFkYXRhXzEuTWV0YWRhdGEoTUVUQURBVEFfS0VZLk5BTUVEX1RBRywgbmFtZSk7XG4gICAgICAgIGlmICh0eXBlb2YgaW5kZXggPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIGRlY29yYXRvcl91dGlsc18xLnRhZ1BhcmFtZXRlcih0YXJnZXQsIHRhcmdldEtleSwgaW5kZXgsIG1ldGFkYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRlY29yYXRvcl91dGlsc18xLnRhZ1Byb3BlcnR5KHRhcmdldCwgdGFyZ2V0S2V5LCBtZXRhZGF0YSk7XG4gICAgICAgIH1cbiAgICB9O1xufVxuZXhwb3J0cy5uYW1lZCA9IG5hbWVkO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvbWV0YWRhdGFcIik7XG52YXIgZGVjb3JhdG9yX3V0aWxzXzEgPSByZXF1aXJlKFwiLi9kZWNvcmF0b3JfdXRpbHNcIik7XG5mdW5jdGlvbiBvcHRpb25hbCgpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwgdGFyZ2V0S2V5LCBpbmRleCkge1xuICAgICAgICB2YXIgbWV0YWRhdGEgPSBuZXcgbWV0YWRhdGFfMS5NZXRhZGF0YShNRVRBREFUQV9LRVkuT1BUSU9OQUxfVEFHLCB0cnVlKTtcbiAgICAgICAgaWYgKHR5cGVvZiBpbmRleCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgZGVjb3JhdG9yX3V0aWxzXzEudGFnUGFyYW1ldGVyKHRhcmdldCwgdGFyZ2V0S2V5LCBpbmRleCwgbWV0YWRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGVjb3JhdG9yX3V0aWxzXzEudGFnUHJvcGVydHkodGFyZ2V0LCB0YXJnZXRLZXksIG1ldGFkYXRhKTtcbiAgICAgICAgfVxuICAgIH07XG59XG5leHBvcnRzLm9wdGlvbmFsID0gb3B0aW9uYWw7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBFUlJPUlNfTVNHUyA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbnZhciBNRVRBREFUQV9LRVkgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG52YXIgbWV0YWRhdGFfMSA9IHJlcXVpcmUoXCIuLi9wbGFubmluZy9tZXRhZGF0YVwiKTtcbmZ1bmN0aW9uIHBvc3RDb25zdHJ1Y3QoKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIHByb3BlcnR5S2V5LCBkZXNjcmlwdG9yKSB7XG4gICAgICAgIHZhciBtZXRhZGF0YSA9IG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKE1FVEFEQVRBX0tFWS5QT1NUX0NPTlNUUlVDVCwgcHJvcGVydHlLZXkpO1xuICAgICAgICBpZiAoUmVmbGVjdC5oYXNPd25NZXRhZGF0YShNRVRBREFUQV9LRVkuUE9TVF9DT05TVFJVQ1QsIHRhcmdldC5jb25zdHJ1Y3RvcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUlNfTVNHUy5NVUxUSVBMRV9QT1NUX0NPTlNUUlVDVF9NRVRIT0RTKTtcbiAgICAgICAgfVxuICAgICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKE1FVEFEQVRBX0tFWS5QT1NUX0NPTlNUUlVDVCwgbWV0YWRhdGEsIHRhcmdldC5jb25zdHJ1Y3Rvcik7XG4gICAgfTtcbn1cbmV4cG9ydHMucG9zdENvbnN0cnVjdCA9IHBvc3RDb25zdHJ1Y3Q7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBtZXRhZGF0YV8xID0gcmVxdWlyZShcIi4uL3BsYW5uaW5nL21ldGFkYXRhXCIpO1xudmFyIGRlY29yYXRvcl91dGlsc18xID0gcmVxdWlyZShcIi4vZGVjb3JhdG9yX3V0aWxzXCIpO1xuZnVuY3Rpb24gdGFnZ2VkKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIHRhcmdldEtleSwgaW5kZXgpIHtcbiAgICAgICAgdmFyIG1ldGFkYXRhID0gbmV3IG1ldGFkYXRhXzEuTWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xuICAgICAgICBpZiAodHlwZW9mIGluZGV4ID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICBkZWNvcmF0b3JfdXRpbHNfMS50YWdQYXJhbWV0ZXIodGFyZ2V0LCB0YXJnZXRLZXksIGluZGV4LCBtZXRhZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkZWNvcmF0b3JfdXRpbHNfMS50YWdQcm9wZXJ0eSh0YXJnZXQsIHRhcmdldEtleSwgbWV0YWRhdGEpO1xuICAgICAgICB9XG4gICAgfTtcbn1cbmV4cG9ydHMudGFnZ2VkID0gdGFnZ2VkO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvbWV0YWRhdGFcIik7XG52YXIgZGVjb3JhdG9yX3V0aWxzXzEgPSByZXF1aXJlKFwiLi9kZWNvcmF0b3JfdXRpbHNcIik7XG5mdW5jdGlvbiB0YXJnZXROYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwgdGFyZ2V0S2V5LCBpbmRleCkge1xuICAgICAgICB2YXIgbWV0YWRhdGEgPSBuZXcgbWV0YWRhdGFfMS5NZXRhZGF0YShNRVRBREFUQV9LRVkuTkFNRV9UQUcsIG5hbWUpO1xuICAgICAgICBkZWNvcmF0b3JfdXRpbHNfMS50YWdQYXJhbWV0ZXIodGFyZ2V0LCB0YXJnZXRLZXksIGluZGV4LCBtZXRhZGF0YSk7XG4gICAgfTtcbn1cbmV4cG9ydHMudGFyZ2V0TmFtZSA9IHRhcmdldE5hbWU7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBNRVRBREFUQV9LRVkgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG52YXIgbWV0YWRhdGFfMSA9IHJlcXVpcmUoXCIuLi9wbGFubmluZy9tZXRhZGF0YVwiKTtcbnZhciBkZWNvcmF0b3JfdXRpbHNfMSA9IHJlcXVpcmUoXCIuL2RlY29yYXRvcl91dGlsc1wiKTtcbmZ1bmN0aW9uIHVubWFuYWdlZCgpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwgdGFyZ2V0S2V5LCBpbmRleCkge1xuICAgICAgICB2YXIgbWV0YWRhdGEgPSBuZXcgbWV0YWRhdGFfMS5NZXRhZGF0YShNRVRBREFUQV9LRVkuVU5NQU5BR0VEX1RBRywgdHJ1ZSk7XG4gICAgICAgIGRlY29yYXRvcl91dGlsc18xLnRhZ1BhcmFtZXRlcih0YXJnZXQsIHRhcmdldEtleSwgaW5kZXgsIG1ldGFkYXRhKTtcbiAgICB9O1xufVxuZXhwb3J0cy51bm1hbmFnZWQgPSB1bm1hbmFnZWQ7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBsaXRlcmFsX3R5cGVzXzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2xpdGVyYWxfdHlwZXNcIik7XG52YXIgaWRfMSA9IHJlcXVpcmUoXCIuLi91dGlscy9pZFwiKTtcbnZhciBCaW5kaW5nID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBCaW5kaW5nKHNlcnZpY2VJZGVudGlmaWVyLCBzY29wZSkge1xuICAgICAgICB0aGlzLmlkID0gaWRfMS5pZCgpO1xuICAgICAgICB0aGlzLmFjdGl2YXRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnNlcnZpY2VJZGVudGlmaWVyID0gc2VydmljZUlkZW50aWZpZXI7XG4gICAgICAgIHRoaXMuc2NvcGUgPSBzY29wZTtcbiAgICAgICAgdGhpcy50eXBlID0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5JbnZhbGlkO1xuICAgICAgICB0aGlzLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkgeyByZXR1cm4gdHJ1ZTsgfTtcbiAgICAgICAgdGhpcy5pbXBsZW1lbnRhdGlvblR5cGUgPSBudWxsO1xuICAgICAgICB0aGlzLmNhY2hlID0gbnVsbDtcbiAgICAgICAgdGhpcy5mYWN0b3J5ID0gbnVsbDtcbiAgICAgICAgdGhpcy5wcm92aWRlciA9IG51bGw7XG4gICAgICAgIHRoaXMub25BY3RpdmF0aW9uID0gbnVsbDtcbiAgICAgICAgdGhpcy5keW5hbWljVmFsdWUgPSBudWxsO1xuICAgIH1cbiAgICBCaW5kaW5nLnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNsb25lID0gbmV3IEJpbmRpbmcodGhpcy5zZXJ2aWNlSWRlbnRpZmllciwgdGhpcy5zY29wZSk7XG4gICAgICAgIGNsb25lLmFjdGl2YXRlZCA9IGZhbHNlO1xuICAgICAgICBjbG9uZS5pbXBsZW1lbnRhdGlvblR5cGUgPSB0aGlzLmltcGxlbWVudGF0aW9uVHlwZTtcbiAgICAgICAgY2xvbmUuZHluYW1pY1ZhbHVlID0gdGhpcy5keW5hbWljVmFsdWU7XG4gICAgICAgIGNsb25lLnNjb3BlID0gdGhpcy5zY29wZTtcbiAgICAgICAgY2xvbmUudHlwZSA9IHRoaXMudHlwZTtcbiAgICAgICAgY2xvbmUuZmFjdG9yeSA9IHRoaXMuZmFjdG9yeTtcbiAgICAgICAgY2xvbmUucHJvdmlkZXIgPSB0aGlzLnByb3ZpZGVyO1xuICAgICAgICBjbG9uZS5jb25zdHJhaW50ID0gdGhpcy5jb25zdHJhaW50O1xuICAgICAgICBjbG9uZS5vbkFjdGl2YXRpb24gPSB0aGlzLm9uQWN0aXZhdGlvbjtcbiAgICAgICAgY2xvbmUuY2FjaGUgPSB0aGlzLmNhY2hlO1xuICAgICAgICByZXR1cm4gY2xvbmU7XG4gICAgfTtcbiAgICByZXR1cm4gQmluZGluZztcbn0oKSk7XG5leHBvcnRzLkJpbmRpbmcgPSBCaW5kaW5nO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgQmluZGluZ0NvdW50ID0ge1xuICAgIE11bHRpcGxlQmluZGluZ3NBdmFpbGFibGU6IDIsXG4gICAgTm9CaW5kaW5nc0F2YWlsYWJsZTogMCxcbiAgICBPbmx5T25lQmluZGluZ0F2YWlsYWJsZTogMVxufTtcbmV4cG9ydHMuQmluZGluZ0NvdW50ID0gQmluZGluZ0NvdW50O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkRVUExJQ0FURURfSU5KRUNUQUJMRV9ERUNPUkFUT1IgPSBcIkNhbm5vdCBhcHBseSBAaW5qZWN0YWJsZSBkZWNvcmF0b3IgbXVsdGlwbGUgdGltZXMuXCI7XG5leHBvcnRzLkRVUExJQ0FURURfTUVUQURBVEEgPSBcIk1ldGFkYXRhIGtleSB3YXMgdXNlZCBtb3JlIHRoYW4gb25jZSBpbiBhIHBhcmFtZXRlcjpcIjtcbmV4cG9ydHMuTlVMTF9BUkdVTUVOVCA9IFwiTlVMTCBhcmd1bWVudFwiO1xuZXhwb3J0cy5LRVlfTk9UX0ZPVU5EID0gXCJLZXkgTm90IEZvdW5kXCI7XG5leHBvcnRzLkFNQklHVU9VU19NQVRDSCA9IFwiQW1iaWd1b3VzIG1hdGNoIGZvdW5kIGZvciBzZXJ2aWNlSWRlbnRpZmllcjpcIjtcbmV4cG9ydHMuQ0FOTk9UX1VOQklORCA9IFwiQ291bGQgbm90IHVuYmluZCBzZXJ2aWNlSWRlbnRpZmllcjpcIjtcbmV4cG9ydHMuTk9UX1JFR0lTVEVSRUQgPSBcIk5vIG1hdGNoaW5nIGJpbmRpbmdzIGZvdW5kIGZvciBzZXJ2aWNlSWRlbnRpZmllcjpcIjtcbmV4cG9ydHMuTUlTU0lOR19JTkpFQ1RBQkxFX0FOTk9UQVRJT04gPSBcIk1pc3NpbmcgcmVxdWlyZWQgQGluamVjdGFibGUgYW5ub3RhdGlvbiBpbjpcIjtcbmV4cG9ydHMuTUlTU0lOR19JTkpFQ1RfQU5OT1RBVElPTiA9IFwiTWlzc2luZyByZXF1aXJlZCBAaW5qZWN0IG9yIEBtdWx0aUluamVjdCBhbm5vdGF0aW9uIGluOlwiO1xuZXhwb3J0cy5VTkRFRklORURfSU5KRUNUX0FOTk9UQVRJT04gPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHJldHVybiBcIkBpbmplY3QgY2FsbGVkIHdpdGggdW5kZWZpbmVkIHRoaXMgY291bGQgbWVhbiB0aGF0IHRoZSBjbGFzcyBcIiArIG5hbWUgKyBcIiBoYXMgXCIgK1xuICAgICAgICBcImEgY2lyY3VsYXIgZGVwZW5kZW5jeSBwcm9ibGVtLiBZb3UgY2FuIHVzZSBhIExhenlTZXJ2aWNlSWRlbnRpZmVyIHRvICBcIiArXG4gICAgICAgIFwib3ZlcmNvbWUgdGhpcyBsaW1pdGF0aW9uLlwiO1xufTtcbmV4cG9ydHMuQ0lSQ1VMQVJfREVQRU5ERU5DWSA9IFwiQ2lyY3VsYXIgZGVwZW5kZW5jeSBmb3VuZDpcIjtcbmV4cG9ydHMuTk9UX0lNUExFTUVOVEVEID0gXCJTb3JyeSwgdGhpcyBmZWF0dXJlIGlzIG5vdCBmdWxseSBpbXBsZW1lbnRlZCB5ZXQuXCI7XG5leHBvcnRzLklOVkFMSURfQklORElOR19UWVBFID0gXCJJbnZhbGlkIGJpbmRpbmcgdHlwZTpcIjtcbmV4cG9ydHMuTk9fTU9SRV9TTkFQU0hPVFNfQVZBSUxBQkxFID0gXCJObyBzbmFwc2hvdCBhdmFpbGFibGUgdG8gcmVzdG9yZS5cIjtcbmV4cG9ydHMuSU5WQUxJRF9NSURETEVXQVJFX1JFVFVSTiA9IFwiSW52YWxpZCByZXR1cm4gdHlwZSBpbiBtaWRkbGV3YXJlLiBNaWRkbGV3YXJlIG11c3QgcmV0dXJuIVwiO1xuZXhwb3J0cy5JTlZBTElEX0ZVTkNUSU9OX0JJTkRJTkcgPSBcIlZhbHVlIHByb3ZpZGVkIHRvIGZ1bmN0aW9uIGJpbmRpbmcgbXVzdCBiZSBhIGZ1bmN0aW9uIVwiO1xuZXhwb3J0cy5JTlZBTElEX1RPX1NFTEZfVkFMVUUgPSBcIlRoZSB0b1NlbGYgZnVuY3Rpb24gY2FuIG9ubHkgYmUgYXBwbGllZCB3aGVuIGEgY29uc3RydWN0b3IgaXMgXCIgK1xuICAgIFwidXNlZCBhcyBzZXJ2aWNlIGlkZW50aWZpZXJcIjtcbmV4cG9ydHMuSU5WQUxJRF9ERUNPUkFUT1JfT1BFUkFUSU9OID0gXCJUaGUgQGluamVjdCBAbXVsdGlJbmplY3QgQHRhZ2dlZCBhbmQgQG5hbWVkIGRlY29yYXRvcnMgXCIgK1xuICAgIFwibXVzdCBiZSBhcHBsaWVkIHRvIHRoZSBwYXJhbWV0ZXJzIG9mIGEgY2xhc3MgY29uc3RydWN0b3Igb3IgYSBjbGFzcyBwcm9wZXJ0eS5cIjtcbmV4cG9ydHMuQVJHVU1FTlRTX0xFTkdUSF9NSVNNQVRDSCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdmFsdWVzID0gW107XG4gICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgdmFsdWVzW19pXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgfVxuICAgIHJldHVybiBcIlRoZSBudW1iZXIgb2YgY29uc3RydWN0b3IgYXJndW1lbnRzIGluIHRoZSBkZXJpdmVkIGNsYXNzIFwiICtcbiAgICAgICAgKHZhbHVlc1swXSArIFwiIG11c3QgYmUgPj0gdGhhbiB0aGUgbnVtYmVyIG9mIGNvbnN0cnVjdG9yIGFyZ3VtZW50cyBvZiBpdHMgYmFzZSBjbGFzcy5cIik7XG59O1xuZXhwb3J0cy5DT05UQUlORVJfT1BUSU9OU19NVVNUX0JFX0FOX09CSkVDVCA9IFwiSW52YWxpZCBDb250YWluZXIgY29uc3RydWN0b3IgYXJndW1lbnQuIENvbnRhaW5lciBvcHRpb25zIFwiICtcbiAgICBcIm11c3QgYmUgYW4gb2JqZWN0LlwiO1xuZXhwb3J0cy5DT05UQUlORVJfT1BUSU9OU19JTlZBTElEX0RFRkFVTFRfU0NPUEUgPSBcIkludmFsaWQgQ29udGFpbmVyIG9wdGlvbi4gRGVmYXVsdCBzY29wZSBtdXN0IFwiICtcbiAgICBcImJlIGEgc3RyaW5nICgnc2luZ2xldG9uJyBvciAndHJhbnNpZW50JykuXCI7XG5leHBvcnRzLkNPTlRBSU5FUl9PUFRJT05TX0lOVkFMSURfQVVUT19CSU5EX0lOSkVDVEFCTEUgPSBcIkludmFsaWQgQ29udGFpbmVyIG9wdGlvbi4gQXV0byBiaW5kIGluamVjdGFibGUgbXVzdCBcIiArXG4gICAgXCJiZSBhIGJvb2xlYW5cIjtcbmV4cG9ydHMuQ09OVEFJTkVSX09QVElPTlNfSU5WQUxJRF9TS0lQX0JBU0VfQ0hFQ0sgPSBcIkludmFsaWQgQ29udGFpbmVyIG9wdGlvbi4gU2tpcCBiYXNlIGNoZWNrIG11c3QgXCIgK1xuICAgIFwiYmUgYSBib29sZWFuXCI7XG5leHBvcnRzLk1VTFRJUExFX1BPU1RfQ09OU1RSVUNUX01FVEhPRFMgPSBcIkNhbm5vdCBhcHBseSBAcG9zdENvbnN0cnVjdCBkZWNvcmF0b3IgbXVsdGlwbGUgdGltZXMgaW4gdGhlIHNhbWUgY2xhc3NcIjtcbmV4cG9ydHMuUE9TVF9DT05TVFJVQ1RfRVJST1IgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIHZhbHVlc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgIH1cbiAgICByZXR1cm4gXCJAcG9zdENvbnN0cnVjdCBlcnJvciBpbiBjbGFzcyBcIiArIHZhbHVlc1swXSArIFwiOiBcIiArIHZhbHVlc1sxXTtcbn07XG5leHBvcnRzLkNJUkNVTEFSX0RFUEVOREVOQ1lfSU5fRkFDVE9SWSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdmFsdWVzID0gW107XG4gICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgdmFsdWVzW19pXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgfVxuICAgIHJldHVybiBcIkl0IGxvb2tzIGxpa2UgdGhlcmUgaXMgYSBjaXJjdWxhciBkZXBlbmRlbmN5IFwiICtcbiAgICAgICAgKFwiaW4gb25lIG9mIHRoZSAnXCIgKyB2YWx1ZXNbMF0gKyBcIicgYmluZGluZ3MuIFBsZWFzZSBpbnZlc3RpZ2F0ZSBiaW5kaW5ncyB3aXRoXCIpICtcbiAgICAgICAgKFwic2VydmljZSBpZGVudGlmaWVyICdcIiArIHZhbHVlc1sxXSArIFwiJy5cIik7XG59O1xuZXhwb3J0cy5TVEFDS19PVkVSRkxPVyA9IFwiTWF4aW11bSBjYWxsIHN0YWNrIHNpemUgZXhjZWVkZWRcIjtcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIEJpbmRpbmdTY29wZUVudW0gPSB7XG4gICAgUmVxdWVzdDogXCJSZXF1ZXN0XCIsXG4gICAgU2luZ2xldG9uOiBcIlNpbmdsZXRvblwiLFxuICAgIFRyYW5zaWVudDogXCJUcmFuc2llbnRcIlxufTtcbmV4cG9ydHMuQmluZGluZ1Njb3BlRW51bSA9IEJpbmRpbmdTY29wZUVudW07XG52YXIgQmluZGluZ1R5cGVFbnVtID0ge1xuICAgIENvbnN0YW50VmFsdWU6IFwiQ29uc3RhbnRWYWx1ZVwiLFxuICAgIENvbnN0cnVjdG9yOiBcIkNvbnN0cnVjdG9yXCIsXG4gICAgRHluYW1pY1ZhbHVlOiBcIkR5bmFtaWNWYWx1ZVwiLFxuICAgIEZhY3Rvcnk6IFwiRmFjdG9yeVwiLFxuICAgIEZ1bmN0aW9uOiBcIkZ1bmN0aW9uXCIsXG4gICAgSW5zdGFuY2U6IFwiSW5zdGFuY2VcIixcbiAgICBJbnZhbGlkOiBcIkludmFsaWRcIixcbiAgICBQcm92aWRlcjogXCJQcm92aWRlclwiXG59O1xuZXhwb3J0cy5CaW5kaW5nVHlwZUVudW0gPSBCaW5kaW5nVHlwZUVudW07XG52YXIgVGFyZ2V0VHlwZUVudW0gPSB7XG4gICAgQ2xhc3NQcm9wZXJ0eTogXCJDbGFzc1Byb3BlcnR5XCIsXG4gICAgQ29uc3RydWN0b3JBcmd1bWVudDogXCJDb25zdHJ1Y3RvckFyZ3VtZW50XCIsXG4gICAgVmFyaWFibGU6IFwiVmFyaWFibGVcIlxufTtcbmV4cG9ydHMuVGFyZ2V0VHlwZUVudW0gPSBUYXJnZXRUeXBlRW51bTtcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5OQU1FRF9UQUcgPSBcIm5hbWVkXCI7XG5leHBvcnRzLk5BTUVfVEFHID0gXCJuYW1lXCI7XG5leHBvcnRzLlVOTUFOQUdFRF9UQUcgPSBcInVubWFuYWdlZFwiO1xuZXhwb3J0cy5PUFRJT05BTF9UQUcgPSBcIm9wdGlvbmFsXCI7XG5leHBvcnRzLklOSkVDVF9UQUcgPSBcImluamVjdFwiO1xuZXhwb3J0cy5NVUxUSV9JTkpFQ1RfVEFHID0gXCJtdWx0aV9pbmplY3RcIjtcbmV4cG9ydHMuVEFHR0VEID0gXCJpbnZlcnNpZnk6dGFnZ2VkXCI7XG5leHBvcnRzLlRBR0dFRF9QUk9QID0gXCJpbnZlcnNpZnk6dGFnZ2VkX3Byb3BzXCI7XG5leHBvcnRzLlBBUkFNX1RZUEVTID0gXCJpbnZlcnNpZnk6cGFyYW10eXBlc1wiO1xuZXhwb3J0cy5ERVNJR05fUEFSQU1fVFlQRVMgPSBcImRlc2lnbjpwYXJhbXR5cGVzXCI7XG5leHBvcnRzLlBPU1RfQ09OU1RSVUNUID0gXCJwb3N0X2NvbnN0cnVjdFwiO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgX19hd2FpdGVyID0gKHRoaXMgJiYgdGhpcy5fX2F3YWl0ZXIpIHx8IGZ1bmN0aW9uICh0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHJlc3VsdC52YWx1ZSk7IH0pLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cbiAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xuICAgIH0pO1xufTtcbnZhciBfX2dlbmVyYXRvciA9ICh0aGlzICYmIHRoaXMuX19nZW5lcmF0b3IpIHx8IGZ1bmN0aW9uICh0aGlzQXJnLCBib2R5KSB7XG4gICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZztcbiAgICByZXR1cm4gZyA9IHsgbmV4dDogdmVyYigwKSwgXCJ0aHJvd1wiOiB2ZXJiKDEpLCBcInJldHVyblwiOiB2ZXJiKDIpIH0sIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XG4gICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcbiAgICAgICAgd2hpbGUgKF8pIHRyeSB7XG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSB5W29wWzBdICYgMiA/IFwicmV0dXJuXCIgOiBvcFswXSA/IFwidGhyb3dcIiA6IFwibmV4dFwiXSkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gWzAsIHQudmFsdWVdO1xuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xuICAgICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XG4gICAgfVxufTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBiaW5kaW5nXzEgPSByZXF1aXJlKFwiLi4vYmluZGluZ3MvYmluZGluZ1wiKTtcbnZhciBFUlJPUl9NU0dTID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9lcnJvcl9tc2dzXCIpO1xudmFyIGxpdGVyYWxfdHlwZXNfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbGl0ZXJhbF90eXBlc1wiKTtcbnZhciBNRVRBREFUQV9LRVkgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG52YXIgbWV0YWRhdGFfcmVhZGVyXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvbWV0YWRhdGFfcmVhZGVyXCIpO1xudmFyIHBsYW5uZXJfMSA9IHJlcXVpcmUoXCIuLi9wbGFubmluZy9wbGFubmVyXCIpO1xudmFyIHJlc29sdmVyXzEgPSByZXF1aXJlKFwiLi4vcmVzb2x1dGlvbi9yZXNvbHZlclwiKTtcbnZhciBiaW5kaW5nX3RvX3N5bnRheF8xID0gcmVxdWlyZShcIi4uL3N5bnRheC9iaW5kaW5nX3RvX3N5bnRheFwiKTtcbnZhciBpZF8xID0gcmVxdWlyZShcIi4uL3V0aWxzL2lkXCIpO1xudmFyIHNlcmlhbGl6YXRpb25fMSA9IHJlcXVpcmUoXCIuLi91dGlscy9zZXJpYWxpemF0aW9uXCIpO1xudmFyIGNvbnRhaW5lcl9zbmFwc2hvdF8xID0gcmVxdWlyZShcIi4vY29udGFpbmVyX3NuYXBzaG90XCIpO1xudmFyIGxvb2t1cF8xID0gcmVxdWlyZShcIi4vbG9va3VwXCIpO1xudmFyIENvbnRhaW5lciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQ29udGFpbmVyKGNvbnRhaW5lck9wdGlvbnMpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSBjb250YWluZXJPcHRpb25zIHx8IHt9O1xuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlwiICsgRVJST1JfTVNHUy5DT05UQUlORVJfT1BUSU9OU19NVVNUX0JFX0FOX09CSkVDVCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdFNjb3BlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG9wdGlvbnMuZGVmYXVsdFNjb3BlID0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdTY29wZUVudW0uVHJhbnNpZW50O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG9wdGlvbnMuZGVmYXVsdFNjb3BlICE9PSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5TaW5nbGV0b24gJiZcbiAgICAgICAgICAgIG9wdGlvbnMuZGVmYXVsdFNjb3BlICE9PSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5UcmFuc2llbnQgJiZcbiAgICAgICAgICAgIG9wdGlvbnMuZGVmYXVsdFNjb3BlICE9PSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5SZXF1ZXN0KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJcIiArIEVSUk9SX01TR1MuQ09OVEFJTkVSX09QVElPTlNfSU5WQUxJRF9ERUZBVUxUX1NDT1BFKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0aW9ucy5hdXRvQmluZEluamVjdGFibGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgb3B0aW9ucy5hdXRvQmluZEluamVjdGFibGUgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb3B0aW9ucy5hdXRvQmluZEluamVjdGFibGUgIT09IFwiYm9vbGVhblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJcIiArIEVSUk9SX01TR1MuQ09OVEFJTkVSX09QVElPTlNfSU5WQUxJRF9BVVRPX0JJTkRfSU5KRUNUQUJMRSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMuc2tpcEJhc2VDbGFzc0NoZWNrcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBvcHRpb25zLnNraXBCYXNlQ2xhc3NDaGVja3MgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb3B0aW9ucy5za2lwQmFzZUNsYXNzQ2hlY2tzICE9PSBcImJvb2xlYW5cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiXCIgKyBFUlJPUl9NU0dTLkNPTlRBSU5FUl9PUFRJT05TX0lOVkFMSURfU0tJUF9CQVNFX0NIRUNLKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICAgICAgICBhdXRvQmluZEluamVjdGFibGU6IG9wdGlvbnMuYXV0b0JpbmRJbmplY3RhYmxlLFxuICAgICAgICAgICAgZGVmYXVsdFNjb3BlOiBvcHRpb25zLmRlZmF1bHRTY29wZSxcbiAgICAgICAgICAgIHNraXBCYXNlQ2xhc3NDaGVja3M6IG9wdGlvbnMuc2tpcEJhc2VDbGFzc0NoZWNrc1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmlkID0gaWRfMS5pZCgpO1xuICAgICAgICB0aGlzLl9iaW5kaW5nRGljdGlvbmFyeSA9IG5ldyBsb29rdXBfMS5Mb29rdXAoKTtcbiAgICAgICAgdGhpcy5fc25hcHNob3RzID0gW107XG4gICAgICAgIHRoaXMuX21pZGRsZXdhcmUgPSBudWxsO1xuICAgICAgICB0aGlzLnBhcmVudCA9IG51bGw7XG4gICAgICAgIHRoaXMuX21ldGFkYXRhUmVhZGVyID0gbmV3IG1ldGFkYXRhX3JlYWRlcl8xLk1ldGFkYXRhUmVhZGVyKCk7XG4gICAgfVxuICAgIENvbnRhaW5lci5tZXJnZSA9IGZ1bmN0aW9uIChjb250YWluZXIxLCBjb250YWluZXIyKSB7XG4gICAgICAgIHZhciBjb250YWluZXIgPSBuZXcgQ29udGFpbmVyKCk7XG4gICAgICAgIHZhciBiaW5kaW5nRGljdGlvbmFyeSA9IHBsYW5uZXJfMS5nZXRCaW5kaW5nRGljdGlvbmFyeShjb250YWluZXIpO1xuICAgICAgICB2YXIgYmluZGluZ0RpY3Rpb25hcnkxID0gcGxhbm5lcl8xLmdldEJpbmRpbmdEaWN0aW9uYXJ5KGNvbnRhaW5lcjEpO1xuICAgICAgICB2YXIgYmluZGluZ0RpY3Rpb25hcnkyID0gcGxhbm5lcl8xLmdldEJpbmRpbmdEaWN0aW9uYXJ5KGNvbnRhaW5lcjIpO1xuICAgICAgICBmdW5jdGlvbiBjb3B5RGljdGlvbmFyeShvcmlnaW4sIGRlc3RpbmF0aW9uKSB7XG4gICAgICAgICAgICBvcmlnaW4udHJhdmVyc2UoZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZS5mb3JFYWNoKGZ1bmN0aW9uIChiaW5kaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uLmFkZChiaW5kaW5nLnNlcnZpY2VJZGVudGlmaWVyLCBiaW5kaW5nLmNsb25lKCkpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY29weURpY3Rpb25hcnkoYmluZGluZ0RpY3Rpb25hcnkxLCBiaW5kaW5nRGljdGlvbmFyeSk7XG4gICAgICAgIGNvcHlEaWN0aW9uYXJ5KGJpbmRpbmdEaWN0aW9uYXJ5MiwgYmluZGluZ0RpY3Rpb25hcnkpO1xuICAgICAgICByZXR1cm4gY29udGFpbmVyO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbW9kdWxlcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgbW9kdWxlc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICB9XG4gICAgICAgIHZhciBnZXRIZWxwZXJzID0gdGhpcy5fZ2V0Q29udGFpbmVyTW9kdWxlSGVscGVyc0ZhY3RvcnkoKTtcbiAgICAgICAgZm9yICh2YXIgX2EgPSAwLCBtb2R1bGVzXzEgPSBtb2R1bGVzOyBfYSA8IG1vZHVsZXNfMS5sZW5ndGg7IF9hKyspIHtcbiAgICAgICAgICAgIHZhciBjdXJyZW50TW9kdWxlID0gbW9kdWxlc18xW19hXTtcbiAgICAgICAgICAgIHZhciBjb250YWluZXJNb2R1bGVIZWxwZXJzID0gZ2V0SGVscGVycyhjdXJyZW50TW9kdWxlLmlkKTtcbiAgICAgICAgICAgIGN1cnJlbnRNb2R1bGUucmVnaXN0cnkoY29udGFpbmVyTW9kdWxlSGVscGVycy5iaW5kRnVuY3Rpb24sIGNvbnRhaW5lck1vZHVsZUhlbHBlcnMudW5iaW5kRnVuY3Rpb24sIGNvbnRhaW5lck1vZHVsZUhlbHBlcnMuaXNib3VuZEZ1bmN0aW9uLCBjb250YWluZXJNb2R1bGVIZWxwZXJzLnJlYmluZEZ1bmN0aW9uKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5sb2FkQXN5bmMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtb2R1bGVzID0gW107XG4gICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICBtb2R1bGVzW19pXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGdldEhlbHBlcnMsIF9hLCBtb2R1bGVzXzIsIGN1cnJlbnRNb2R1bGUsIGNvbnRhaW5lck1vZHVsZUhlbHBlcnM7XG4gICAgICAgICAgICByZXR1cm4gX19nZW5lcmF0b3IodGhpcywgZnVuY3Rpb24gKF9iKSB7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChfYi5sYWJlbCkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRIZWxwZXJzID0gdGhpcy5fZ2V0Q29udGFpbmVyTW9kdWxlSGVscGVyc0ZhY3RvcnkoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hID0gMCwgbW9kdWxlc18yID0gbW9kdWxlcztcbiAgICAgICAgICAgICAgICAgICAgICAgIF9iLmxhYmVsID0gMTtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEoX2EgPCBtb2R1bGVzXzIubGVuZ3RoKSkgcmV0dXJuIFszLCA0XTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNb2R1bGUgPSBtb2R1bGVzXzJbX2FdO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyTW9kdWxlSGVscGVycyA9IGdldEhlbHBlcnMoY3VycmVudE1vZHVsZS5pZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQsIGN1cnJlbnRNb2R1bGUucmVnaXN0cnkoY29udGFpbmVyTW9kdWxlSGVscGVycy5iaW5kRnVuY3Rpb24sIGNvbnRhaW5lck1vZHVsZUhlbHBlcnMudW5iaW5kRnVuY3Rpb24sIGNvbnRhaW5lck1vZHVsZUhlbHBlcnMuaXNib3VuZEZ1bmN0aW9uLCBjb250YWluZXJNb2R1bGVIZWxwZXJzLnJlYmluZEZ1bmN0aW9uKV07XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICAgICAgICAgIF9iLnNlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIF9iLmxhYmVsID0gMztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgICAgICAgICAgX2ErKztcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMywgMV07XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNDogcmV0dXJuIFsyXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLnVubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIG1vZHVsZXMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIG1vZHVsZXNbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgY29uZGl0aW9uRmFjdG9yeSA9IGZ1bmN0aW9uIChleHBlY3RlZCkgeyByZXR1cm4gZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgIHJldHVybiBpdGVtLm1vZHVsZUlkID09PSBleHBlY3RlZDtcbiAgICAgICAgfTsgfTtcbiAgICAgICAgbW9kdWxlcy5mb3JFYWNoKGZ1bmN0aW9uIChtb2R1bGUpIHtcbiAgICAgICAgICAgIHZhciBjb25kaXRpb24gPSBjb25kaXRpb25GYWN0b3J5KG1vZHVsZS5pZCk7XG4gICAgICAgICAgICBfdGhpcy5fYmluZGluZ0RpY3Rpb25hcnkucmVtb3ZlQnlDb25kaXRpb24oY29uZGl0aW9uKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmJpbmQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgdmFyIHNjb3BlID0gdGhpcy5vcHRpb25zLmRlZmF1bHRTY29wZSB8fCBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5UcmFuc2llbnQ7XG4gICAgICAgIHZhciBiaW5kaW5nID0gbmV3IGJpbmRpbmdfMS5CaW5kaW5nKHNlcnZpY2VJZGVudGlmaWVyLCBzY29wZSk7XG4gICAgICAgIHRoaXMuX2JpbmRpbmdEaWN0aW9uYXJ5LmFkZChzZXJ2aWNlSWRlbnRpZmllciwgYmluZGluZyk7XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ190b19zeW50YXhfMS5CaW5kaW5nVG9TeW50YXgoYmluZGluZyk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLnJlYmluZCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICB0aGlzLnVuYmluZChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIHJldHVybiB0aGlzLmJpbmQoc2VydmljZUlkZW50aWZpZXIpO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS51bmJpbmQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuX2JpbmRpbmdEaWN0aW9uYXJ5LnJlbW92ZShzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUl9NU0dTLkNBTk5PVF9VTkJJTkQgKyBcIiBcIiArIHNlcmlhbGl6YXRpb25fMS5nZXRTZXJ2aWNlSWRlbnRpZmllckFzU3RyaW5nKHNlcnZpY2VJZGVudGlmaWVyKSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUudW5iaW5kQWxsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nRGljdGlvbmFyeSA9IG5ldyBsb29rdXBfMS5Mb29rdXAoKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuaXNCb3VuZCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICB2YXIgYm91bmQgPSB0aGlzLl9iaW5kaW5nRGljdGlvbmFyeS5oYXNLZXkoc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICBpZiAoIWJvdW5kICYmIHRoaXMucGFyZW50KSB7XG4gICAgICAgICAgICBib3VuZCA9IHRoaXMucGFyZW50LmlzQm91bmQoc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBib3VuZDtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuaXNCb3VuZE5hbWVkID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyLCBuYW1lZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pc0JvdW5kVGFnZ2VkKHNlcnZpY2VJZGVudGlmaWVyLCBNRVRBREFUQV9LRVkuTkFNRURfVEFHLCBuYW1lZCk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmlzQm91bmRUYWdnZWQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUpIHtcbiAgICAgICAgdmFyIGJvdW5kID0gZmFsc2U7XG4gICAgICAgIGlmICh0aGlzLl9iaW5kaW5nRGljdGlvbmFyeS5oYXNLZXkoc2VydmljZUlkZW50aWZpZXIpKSB7XG4gICAgICAgICAgICB2YXIgYmluZGluZ3MgPSB0aGlzLl9iaW5kaW5nRGljdGlvbmFyeS5nZXQoc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICAgICAgdmFyIHJlcXVlc3RfMSA9IHBsYW5uZXJfMS5jcmVhdGVNb2NrUmVxdWVzdCh0aGlzLCBzZXJ2aWNlSWRlbnRpZmllciwga2V5LCB2YWx1ZSk7XG4gICAgICAgICAgICBib3VuZCA9IGJpbmRpbmdzLnNvbWUoZnVuY3Rpb24gKGIpIHsgcmV0dXJuIGIuY29uc3RyYWludChyZXF1ZXN0XzEpOyB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWJvdW5kICYmIHRoaXMucGFyZW50KSB7XG4gICAgICAgICAgICBib3VuZCA9IHRoaXMucGFyZW50LmlzQm91bmRUYWdnZWQoc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBib3VuZDtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuc25hcHNob3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX3NuYXBzaG90cy5wdXNoKGNvbnRhaW5lcl9zbmFwc2hvdF8xLkNvbnRhaW5lclNuYXBzaG90Lm9mKHRoaXMuX2JpbmRpbmdEaWN0aW9uYXJ5LmNsb25lKCksIHRoaXMuX21pZGRsZXdhcmUpKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUucmVzdG9yZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHNuYXBzaG90ID0gdGhpcy5fc25hcHNob3RzLnBvcCgpO1xuICAgICAgICBpZiAoc25hcHNob3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuTk9fTU9SRV9TTkFQU0hPVFNfQVZBSUxBQkxFKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9iaW5kaW5nRGljdGlvbmFyeSA9IHNuYXBzaG90LmJpbmRpbmdzO1xuICAgICAgICB0aGlzLl9taWRkbGV3YXJlID0gc25hcHNob3QubWlkZGxld2FyZTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuY3JlYXRlQ2hpbGQgPSBmdW5jdGlvbiAoY29udGFpbmVyT3B0aW9ucykge1xuICAgICAgICB2YXIgY2hpbGQgPSBuZXcgQ29udGFpbmVyKGNvbnRhaW5lck9wdGlvbnMgfHwgdGhpcy5vcHRpb25zKTtcbiAgICAgICAgY2hpbGQucGFyZW50ID0gdGhpcztcbiAgICAgICAgcmV0dXJuIGNoaWxkO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5hcHBseU1pZGRsZXdhcmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtaWRkbGV3YXJlcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgbWlkZGxld2FyZXNbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaW5pdGlhbCA9ICh0aGlzLl9taWRkbGV3YXJlKSA/IHRoaXMuX21pZGRsZXdhcmUgOiB0aGlzLl9wbGFuQW5kUmVzb2x2ZSgpO1xuICAgICAgICB0aGlzLl9taWRkbGV3YXJlID0gbWlkZGxld2FyZXMucmVkdWNlKGZ1bmN0aW9uIChwcmV2LCBjdXJyKSB7IHJldHVybiBjdXJyKHByZXYpOyB9LCBpbml0aWFsKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuYXBwbHlDdXN0b21NZXRhZGF0YVJlYWRlciA9IGZ1bmN0aW9uIChtZXRhZGF0YVJlYWRlcikge1xuICAgICAgICB0aGlzLl9tZXRhZGF0YVJlYWRlciA9IG1ldGFkYXRhUmVhZGVyO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldChmYWxzZSwgZmFsc2UsIGxpdGVyYWxfdHlwZXNfMS5UYXJnZXRUeXBlRW51bS5WYXJpYWJsZSwgc2VydmljZUlkZW50aWZpZXIpO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5nZXRUYWdnZWQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldChmYWxzZSwgZmFsc2UsIGxpdGVyYWxfdHlwZXNfMS5UYXJnZXRUeXBlRW51bS5WYXJpYWJsZSwgc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUpO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5nZXROYW1lZCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllciwgbmFtZWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VGFnZ2VkKHNlcnZpY2VJZGVudGlmaWVyLCBNRVRBREFUQV9LRVkuTkFNRURfVEFHLCBuYW1lZCk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmdldEFsbCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0KHRydWUsIHRydWUsIGxpdGVyYWxfdHlwZXNfMS5UYXJnZXRUeXBlRW51bS5WYXJpYWJsZSwgc2VydmljZUlkZW50aWZpZXIpO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5nZXRBbGxUYWdnZWQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldChmYWxzZSwgdHJ1ZSwgbGl0ZXJhbF90eXBlc18xLlRhcmdldFR5cGVFbnVtLlZhcmlhYmxlLCBzZXJ2aWNlSWRlbnRpZmllciwga2V5LCB2YWx1ZSk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmdldEFsbE5hbWVkID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyLCBuYW1lZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRBbGxUYWdnZWQoc2VydmljZUlkZW50aWZpZXIsIE1FVEFEQVRBX0tFWS5OQU1FRF9UQUcsIG5hbWVkKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUucmVzb2x2ZSA9IGZ1bmN0aW9uIChjb25zdHJ1Y3RvckZ1bmN0aW9uKSB7XG4gICAgICAgIHZhciB0ZW1wQ29udGFpbmVyID0gdGhpcy5jcmVhdGVDaGlsZCgpO1xuICAgICAgICB0ZW1wQ29udGFpbmVyLmJpbmQoY29uc3RydWN0b3JGdW5jdGlvbikudG9TZWxmKCk7XG4gICAgICAgIHJldHVybiB0ZW1wQ29udGFpbmVyLmdldChjb25zdHJ1Y3RvckZ1bmN0aW9uKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuX2dldENvbnRhaW5lck1vZHVsZUhlbHBlcnNGYWN0b3J5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgc2V0TW9kdWxlSWQgPSBmdW5jdGlvbiAoYmluZGluZ1RvU3ludGF4LCBtb2R1bGVJZCkge1xuICAgICAgICAgICAgYmluZGluZ1RvU3ludGF4Ll9iaW5kaW5nLm1vZHVsZUlkID0gbW9kdWxlSWQ7XG4gICAgICAgIH07XG4gICAgICAgIHZhciBnZXRCaW5kRnVuY3Rpb24gPSBmdW5jdGlvbiAobW9kdWxlSWQpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgICAgICAgICB2YXIgX2JpbmQgPSBfdGhpcy5iaW5kLmJpbmQoX3RoaXMpO1xuICAgICAgICAgICAgICAgIHZhciBiaW5kaW5nVG9TeW50YXggPSBfYmluZChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgICAgICAgICAgc2V0TW9kdWxlSWQoYmluZGluZ1RvU3ludGF4LCBtb2R1bGVJZCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGJpbmRpbmdUb1N5bnRheDtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICAgIHZhciBnZXRVbmJpbmRGdW5jdGlvbiA9IGZ1bmN0aW9uIChtb2R1bGVJZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICAgICAgICAgIHZhciBfdW5iaW5kID0gX3RoaXMudW5iaW5kLmJpbmQoX3RoaXMpO1xuICAgICAgICAgICAgICAgIF91bmJpbmQoc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIGdldElzYm91bmRGdW5jdGlvbiA9IGZ1bmN0aW9uIChtb2R1bGVJZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICAgICAgICAgIHZhciBfaXNCb3VuZCA9IF90aGlzLmlzQm91bmQuYmluZChfdGhpcyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9pc0JvdW5kKHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICAgIHZhciBnZXRSZWJpbmRGdW5jdGlvbiA9IGZ1bmN0aW9uIChtb2R1bGVJZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICAgICAgICAgIHZhciBfcmViaW5kID0gX3RoaXMucmViaW5kLmJpbmQoX3RoaXMpO1xuICAgICAgICAgICAgICAgIHZhciBiaW5kaW5nVG9TeW50YXggPSBfcmViaW5kKHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgICAgICAgICBzZXRNb2R1bGVJZChiaW5kaW5nVG9TeW50YXgsIG1vZHVsZUlkKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYmluZGluZ1RvU3ludGF4O1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChtSWQpIHsgcmV0dXJuICh7XG4gICAgICAgICAgICBiaW5kRnVuY3Rpb246IGdldEJpbmRGdW5jdGlvbihtSWQpLFxuICAgICAgICAgICAgaXNib3VuZEZ1bmN0aW9uOiBnZXRJc2JvdW5kRnVuY3Rpb24obUlkKSxcbiAgICAgICAgICAgIHJlYmluZEZ1bmN0aW9uOiBnZXRSZWJpbmRGdW5jdGlvbihtSWQpLFxuICAgICAgICAgICAgdW5iaW5kRnVuY3Rpb246IGdldFVuYmluZEZ1bmN0aW9uKG1JZClcbiAgICAgICAgfSk7IH07XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLl9nZXQgPSBmdW5jdGlvbiAoYXZvaWRDb25zdHJhaW50cywgaXNNdWx0aUluamVjdCwgdGFyZ2V0VHlwZSwgc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IG51bGw7XG4gICAgICAgIHZhciBkZWZhdWx0QXJncyA9IHtcbiAgICAgICAgICAgIGF2b2lkQ29uc3RyYWludHM6IGF2b2lkQ29uc3RyYWludHMsXG4gICAgICAgICAgICBjb250ZXh0SW50ZXJjZXB0b3I6IGZ1bmN0aW9uIChjb250ZXh0KSB7IHJldHVybiBjb250ZXh0OyB9LFxuICAgICAgICAgICAgaXNNdWx0aUluamVjdDogaXNNdWx0aUluamVjdCxcbiAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgc2VydmljZUlkZW50aWZpZXI6IHNlcnZpY2VJZGVudGlmaWVyLFxuICAgICAgICAgICAgdGFyZ2V0VHlwZTogdGFyZ2V0VHlwZSxcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5fbWlkZGxld2FyZSkge1xuICAgICAgICAgICAgcmVzdWx0ID0gdGhpcy5fbWlkZGxld2FyZShkZWZhdWx0QXJncyk7XG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSB1bmRlZmluZWQgfHwgcmVzdWx0ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuSU5WQUxJRF9NSURETEVXQVJFX1JFVFVSTik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXN1bHQgPSB0aGlzLl9wbGFuQW5kUmVzb2x2ZSgpKGRlZmF1bHRBcmdzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5fcGxhbkFuZFJlc29sdmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoYXJncykge1xuICAgICAgICAgICAgdmFyIGNvbnRleHQgPSBwbGFubmVyXzEucGxhbihfdGhpcy5fbWV0YWRhdGFSZWFkZXIsIF90aGlzLCBhcmdzLmlzTXVsdGlJbmplY3QsIGFyZ3MudGFyZ2V0VHlwZSwgYXJncy5zZXJ2aWNlSWRlbnRpZmllciwgYXJncy5rZXksIGFyZ3MudmFsdWUsIGFyZ3MuYXZvaWRDb25zdHJhaW50cyk7XG4gICAgICAgICAgICBjb250ZXh0ID0gYXJncy5jb250ZXh0SW50ZXJjZXB0b3IoY29udGV4dCk7XG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gcmVzb2x2ZXJfMS5yZXNvbHZlKGNvbnRleHQpO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIHJldHVybiBDb250YWluZXI7XG59KCkpO1xuZXhwb3J0cy5Db250YWluZXIgPSBDb250YWluZXI7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpZF8xID0gcmVxdWlyZShcIi4uL3V0aWxzL2lkXCIpO1xudmFyIENvbnRhaW5lck1vZHVsZSA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQ29udGFpbmVyTW9kdWxlKHJlZ2lzdHJ5KSB7XG4gICAgICAgIHRoaXMuaWQgPSBpZF8xLmlkKCk7XG4gICAgICAgIHRoaXMucmVnaXN0cnkgPSByZWdpc3RyeTtcbiAgICB9XG4gICAgcmV0dXJuIENvbnRhaW5lck1vZHVsZTtcbn0oKSk7XG5leHBvcnRzLkNvbnRhaW5lck1vZHVsZSA9IENvbnRhaW5lck1vZHVsZTtcbnZhciBBc3luY0NvbnRhaW5lck1vZHVsZSA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQXN5bmNDb250YWluZXJNb2R1bGUocmVnaXN0cnkpIHtcbiAgICAgICAgdGhpcy5pZCA9IGlkXzEuaWQoKTtcbiAgICAgICAgdGhpcy5yZWdpc3RyeSA9IHJlZ2lzdHJ5O1xuICAgIH1cbiAgICByZXR1cm4gQXN5bmNDb250YWluZXJNb2R1bGU7XG59KCkpO1xuZXhwb3J0cy5Bc3luY0NvbnRhaW5lck1vZHVsZSA9IEFzeW5jQ29udGFpbmVyTW9kdWxlO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgQ29udGFpbmVyU25hcHNob3QgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIENvbnRhaW5lclNuYXBzaG90KCkge1xuICAgIH1cbiAgICBDb250YWluZXJTbmFwc2hvdC5vZiA9IGZ1bmN0aW9uIChiaW5kaW5ncywgbWlkZGxld2FyZSkge1xuICAgICAgICB2YXIgc25hcHNob3QgPSBuZXcgQ29udGFpbmVyU25hcHNob3QoKTtcbiAgICAgICAgc25hcHNob3QuYmluZGluZ3MgPSBiaW5kaW5ncztcbiAgICAgICAgc25hcHNob3QubWlkZGxld2FyZSA9IG1pZGRsZXdhcmU7XG4gICAgICAgIHJldHVybiBzbmFwc2hvdDtcbiAgICB9O1xuICAgIHJldHVybiBDb250YWluZXJTbmFwc2hvdDtcbn0oKSk7XG5leHBvcnRzLkNvbnRhaW5lclNuYXBzaG90ID0gQ29udGFpbmVyU25hcHNob3Q7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBFUlJPUl9NU0dTID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9lcnJvcl9tc2dzXCIpO1xudmFyIExvb2t1cCA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gTG9va3VwKCkge1xuICAgICAgICB0aGlzLl9tYXAgPSBuZXcgTWFwKCk7XG4gICAgfVxuICAgIExvb2t1cC5wcm90b3R5cGUuZ2V0TWFwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwO1xuICAgIH07XG4gICAgTG9va3VwLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIsIHZhbHVlKSB7XG4gICAgICAgIGlmIChzZXJ2aWNlSWRlbnRpZmllciA9PT0gbnVsbCB8fCBzZXJ2aWNlSWRlbnRpZmllciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTVNHUy5OVUxMX0FSR1VNRU5UKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuTlVMTF9BUkdVTUVOVCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy5fbWFwLmdldChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIGlmIChlbnRyeSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBlbnRyeS5wdXNoKHZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuX21hcC5zZXQoc2VydmljZUlkZW50aWZpZXIsIGVudHJ5KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX21hcC5zZXQoc2VydmljZUlkZW50aWZpZXIsIFt2YWx1ZV0pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBMb29rdXAucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICBpZiAoc2VydmljZUlkZW50aWZpZXIgPT09IG51bGwgfHwgc2VydmljZUlkZW50aWZpZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuTlVMTF9BUkdVTUVOVCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy5fbWFwLmdldChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIGlmIChlbnRyeSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gZW50cnk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTVNHUy5LRVlfTk9UX0ZPVU5EKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgTG9va3VwLnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgaWYgKHNlcnZpY2VJZGVudGlmaWVyID09PSBudWxsIHx8IHNlcnZpY2VJZGVudGlmaWVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUl9NU0dTLk5VTExfQVJHVU1FTlQpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5fbWFwLmRlbGV0ZShzZXJ2aWNlSWRlbnRpZmllcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUl9NU0dTLktFWV9OT1RfRk9VTkQpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBMb29rdXAucHJvdG90eXBlLnJlbW92ZUJ5Q29uZGl0aW9uID0gZnVuY3Rpb24gKGNvbmRpdGlvbikge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLl9tYXAuZm9yRWFjaChmdW5jdGlvbiAoZW50cmllcywga2V5KSB7XG4gICAgICAgICAgICB2YXIgdXBkYXRlZEVudHJpZXMgPSBlbnRyaWVzLmZpbHRlcihmdW5jdGlvbiAoZW50cnkpIHsgcmV0dXJuICFjb25kaXRpb24oZW50cnkpOyB9KTtcbiAgICAgICAgICAgIGlmICh1cGRhdGVkRW50cmllcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuX21hcC5zZXQoa2V5LCB1cGRhdGVkRW50cmllcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5fbWFwLmRlbGV0ZShrZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIExvb2t1cC5wcm90b3R5cGUuaGFzS2V5ID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgICAgIGlmIChzZXJ2aWNlSWRlbnRpZmllciA9PT0gbnVsbCB8fCBzZXJ2aWNlSWRlbnRpZmllciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTVNHUy5OVUxMX0FSR1VNRU5UKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fbWFwLmhhcyhzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgfTtcbiAgICBMb29rdXAucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29weSA9IG5ldyBMb29rdXAoKTtcbiAgICAgICAgdGhpcy5fbWFwLmZvckVhY2goZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcbiAgICAgICAgICAgIHZhbHVlLmZvckVhY2goZnVuY3Rpb24gKGIpIHsgcmV0dXJuIGNvcHkuYWRkKGtleSwgYi5jbG9uZSgpKTsgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gY29weTtcbiAgICB9O1xuICAgIExvb2t1cC5wcm90b3R5cGUudHJhdmVyc2UgPSBmdW5jdGlvbiAoZnVuYykge1xuICAgICAgICB0aGlzLl9tYXAuZm9yRWFjaChmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgICAgICAgICAgZnVuYyhrZXksIHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gTG9va3VwO1xufSgpKTtcbmV4cG9ydHMuTG9va3VwID0gTG9va3VwO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIga2V5cyA9IHJlcXVpcmUoXCIuL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xuZXhwb3J0cy5NRVRBREFUQV9LRVkgPSBrZXlzO1xudmFyIGNvbnRhaW5lcl8xID0gcmVxdWlyZShcIi4vY29udGFpbmVyL2NvbnRhaW5lclwiKTtcbmV4cG9ydHMuQ29udGFpbmVyID0gY29udGFpbmVyXzEuQ29udGFpbmVyO1xudmFyIGxpdGVyYWxfdHlwZXNfMSA9IHJlcXVpcmUoXCIuL2NvbnN0YW50cy9saXRlcmFsX3R5cGVzXCIpO1xuZXhwb3J0cy5CaW5kaW5nU2NvcGVFbnVtID0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdTY29wZUVudW07XG5leHBvcnRzLkJpbmRpbmdUeXBlRW51bSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW07XG5leHBvcnRzLlRhcmdldFR5cGVFbnVtID0gbGl0ZXJhbF90eXBlc18xLlRhcmdldFR5cGVFbnVtO1xudmFyIGNvbnRhaW5lcl9tb2R1bGVfMSA9IHJlcXVpcmUoXCIuL2NvbnRhaW5lci9jb250YWluZXJfbW9kdWxlXCIpO1xuZXhwb3J0cy5Bc3luY0NvbnRhaW5lck1vZHVsZSA9IGNvbnRhaW5lcl9tb2R1bGVfMS5Bc3luY0NvbnRhaW5lck1vZHVsZTtcbmV4cG9ydHMuQ29udGFpbmVyTW9kdWxlID0gY29udGFpbmVyX21vZHVsZV8xLkNvbnRhaW5lck1vZHVsZTtcbnZhciBpbmplY3RhYmxlXzEgPSByZXF1aXJlKFwiLi9hbm5vdGF0aW9uL2luamVjdGFibGVcIik7XG5leHBvcnRzLmluamVjdGFibGUgPSBpbmplY3RhYmxlXzEuaW5qZWN0YWJsZTtcbnZhciB0YWdnZWRfMSA9IHJlcXVpcmUoXCIuL2Fubm90YXRpb24vdGFnZ2VkXCIpO1xuZXhwb3J0cy50YWdnZWQgPSB0YWdnZWRfMS50YWdnZWQ7XG52YXIgbmFtZWRfMSA9IHJlcXVpcmUoXCIuL2Fubm90YXRpb24vbmFtZWRcIik7XG5leHBvcnRzLm5hbWVkID0gbmFtZWRfMS5uYW1lZDtcbnZhciBpbmplY3RfMSA9IHJlcXVpcmUoXCIuL2Fubm90YXRpb24vaW5qZWN0XCIpO1xuZXhwb3J0cy5pbmplY3QgPSBpbmplY3RfMS5pbmplY3Q7XG5leHBvcnRzLkxhenlTZXJ2aWNlSWRlbnRpZmVyID0gaW5qZWN0XzEuTGF6eVNlcnZpY2VJZGVudGlmZXI7XG52YXIgb3B0aW9uYWxfMSA9IHJlcXVpcmUoXCIuL2Fubm90YXRpb24vb3B0aW9uYWxcIik7XG5leHBvcnRzLm9wdGlvbmFsID0gb3B0aW9uYWxfMS5vcHRpb25hbDtcbnZhciB1bm1hbmFnZWRfMSA9IHJlcXVpcmUoXCIuL2Fubm90YXRpb24vdW5tYW5hZ2VkXCIpO1xuZXhwb3J0cy51bm1hbmFnZWQgPSB1bm1hbmFnZWRfMS51bm1hbmFnZWQ7XG52YXIgbXVsdGlfaW5qZWN0XzEgPSByZXF1aXJlKFwiLi9hbm5vdGF0aW9uL211bHRpX2luamVjdFwiKTtcbmV4cG9ydHMubXVsdGlJbmplY3QgPSBtdWx0aV9pbmplY3RfMS5tdWx0aUluamVjdDtcbnZhciB0YXJnZXRfbmFtZV8xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi90YXJnZXRfbmFtZVwiKTtcbmV4cG9ydHMudGFyZ2V0TmFtZSA9IHRhcmdldF9uYW1lXzEudGFyZ2V0TmFtZTtcbnZhciBwb3N0X2NvbnN0cnVjdF8xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi9wb3N0X2NvbnN0cnVjdFwiKTtcbmV4cG9ydHMucG9zdENvbnN0cnVjdCA9IHBvc3RfY29uc3RydWN0XzEucG9zdENvbnN0cnVjdDtcbnZhciBtZXRhZGF0YV9yZWFkZXJfMSA9IHJlcXVpcmUoXCIuL3BsYW5uaW5nL21ldGFkYXRhX3JlYWRlclwiKTtcbmV4cG9ydHMuTWV0YWRhdGFSZWFkZXIgPSBtZXRhZGF0YV9yZWFkZXJfMS5NZXRhZGF0YVJlYWRlcjtcbnZhciBpZF8xID0gcmVxdWlyZShcIi4vdXRpbHMvaWRcIik7XG5leHBvcnRzLmlkID0gaWRfMS5pZDtcbnZhciBkZWNvcmF0b3JfdXRpbHNfMSA9IHJlcXVpcmUoXCIuL2Fubm90YXRpb24vZGVjb3JhdG9yX3V0aWxzXCIpO1xuZXhwb3J0cy5kZWNvcmF0ZSA9IGRlY29yYXRvcl91dGlsc18xLmRlY29yYXRlO1xudmFyIGNvbnN0cmFpbnRfaGVscGVyc18xID0gcmVxdWlyZShcIi4vc3ludGF4L2NvbnN0cmFpbnRfaGVscGVyc1wiKTtcbmV4cG9ydHMudHJhdmVyc2VBbmNlcnN0b3JzID0gY29uc3RyYWludF9oZWxwZXJzXzEudHJhdmVyc2VBbmNlcnN0b3JzO1xuZXhwb3J0cy50YWdnZWRDb25zdHJhaW50ID0gY29uc3RyYWludF9oZWxwZXJzXzEudGFnZ2VkQ29uc3RyYWludDtcbmV4cG9ydHMubmFtZWRDb25zdHJhaW50ID0gY29uc3RyYWludF9oZWxwZXJzXzEubmFtZWRDb25zdHJhaW50O1xuZXhwb3J0cy50eXBlQ29uc3RyYWludCA9IGNvbnN0cmFpbnRfaGVscGVyc18xLnR5cGVDb25zdHJhaW50O1xudmFyIHNlcmlhbGl6YXRpb25fMSA9IHJlcXVpcmUoXCIuL3V0aWxzL3NlcmlhbGl6YXRpb25cIik7XG5leHBvcnRzLmdldFNlcnZpY2VJZGVudGlmaWVyQXNTdHJpbmcgPSBzZXJpYWxpemF0aW9uXzEuZ2V0U2VydmljZUlkZW50aWZpZXJBc1N0cmluZztcbnZhciBiaW5kaW5nX3V0aWxzXzEgPSByZXF1aXJlKFwiLi91dGlscy9iaW5kaW5nX3V0aWxzXCIpO1xuZXhwb3J0cy5tdWx0aUJpbmRUb1NlcnZpY2UgPSBiaW5kaW5nX3V0aWxzXzEubXVsdGlCaW5kVG9TZXJ2aWNlO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgaWRfMSA9IHJlcXVpcmUoXCIuLi91dGlscy9pZFwiKTtcbnZhciBDb250ZXh0ID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBDb250ZXh0KGNvbnRhaW5lcikge1xuICAgICAgICB0aGlzLmlkID0gaWRfMS5pZCgpO1xuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IGNvbnRhaW5lcjtcbiAgICB9XG4gICAgQ29udGV4dC5wcm90b3R5cGUuYWRkUGxhbiA9IGZ1bmN0aW9uIChwbGFuKSB7XG4gICAgICAgIHRoaXMucGxhbiA9IHBsYW47XG4gICAgfTtcbiAgICBDb250ZXh0LnByb3RvdHlwZS5zZXRDdXJyZW50UmVxdWVzdCA9IGZ1bmN0aW9uIChjdXJyZW50UmVxdWVzdCkge1xuICAgICAgICB0aGlzLmN1cnJlbnRSZXF1ZXN0ID0gY3VycmVudFJlcXVlc3Q7XG4gICAgfTtcbiAgICByZXR1cm4gQ29udGV4dDtcbn0oKSk7XG5leHBvcnRzLkNvbnRleHQgPSBDb250ZXh0O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIE1ldGFkYXRhID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBNZXRhZGF0YShrZXksIHZhbHVlKSB7XG4gICAgICAgIHRoaXMua2V5ID0ga2V5O1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgfVxuICAgIE1ldGFkYXRhLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMua2V5ID09PSBNRVRBREFUQV9LRVkuTkFNRURfVEFHKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJuYW1lZDogXCIgKyB0aGlzLnZhbHVlLnRvU3RyaW5nKCkgKyBcIiBcIjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBcInRhZ2dlZDogeyBrZXk6XCIgKyB0aGlzLmtleS50b1N0cmluZygpICsgXCIsIHZhbHVlOiBcIiArIHRoaXMudmFsdWUgKyBcIiB9XCI7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBNZXRhZGF0YTtcbn0oKSk7XG5leHBvcnRzLk1ldGFkYXRhID0gTWV0YWRhdGE7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBNRVRBREFUQV9LRVkgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG52YXIgTWV0YWRhdGFSZWFkZXIgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIE1ldGFkYXRhUmVhZGVyKCkge1xuICAgIH1cbiAgICBNZXRhZGF0YVJlYWRlci5wcm90b3R5cGUuZ2V0Q29uc3RydWN0b3JNZXRhZGF0YSA9IGZ1bmN0aW9uIChjb25zdHJ1Y3RvckZ1bmMpIHtcbiAgICAgICAgdmFyIGNvbXBpbGVyR2VuZXJhdGVkTWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKE1FVEFEQVRBX0tFWS5QQVJBTV9UWVBFUywgY29uc3RydWN0b3JGdW5jKTtcbiAgICAgICAgdmFyIHVzZXJHZW5lcmF0ZWRNZXRhZGF0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoTUVUQURBVEFfS0VZLlRBR0dFRCwgY29uc3RydWN0b3JGdW5jKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbXBpbGVyR2VuZXJhdGVkTWV0YWRhdGE6IGNvbXBpbGVyR2VuZXJhdGVkTWV0YWRhdGEsXG4gICAgICAgICAgICB1c2VyR2VuZXJhdGVkTWV0YWRhdGE6IHVzZXJHZW5lcmF0ZWRNZXRhZGF0YSB8fCB7fVxuICAgICAgICB9O1xuICAgIH07XG4gICAgTWV0YWRhdGFSZWFkZXIucHJvdG90eXBlLmdldFByb3BlcnRpZXNNZXRhZGF0YSA9IGZ1bmN0aW9uIChjb25zdHJ1Y3RvckZ1bmMpIHtcbiAgICAgICAgdmFyIHVzZXJHZW5lcmF0ZWRNZXRhZGF0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoTUVUQURBVEFfS0VZLlRBR0dFRF9QUk9QLCBjb25zdHJ1Y3RvckZ1bmMpIHx8IFtdO1xuICAgICAgICByZXR1cm4gdXNlckdlbmVyYXRlZE1ldGFkYXRhO1xuICAgIH07XG4gICAgcmV0dXJuIE1ldGFkYXRhUmVhZGVyO1xufSgpKTtcbmV4cG9ydHMuTWV0YWRhdGFSZWFkZXIgPSBNZXRhZGF0YVJlYWRlcjtcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIFBsYW4gPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFBsYW4ocGFyZW50Q29udGV4dCwgcm9vdFJlcXVlc3QpIHtcbiAgICAgICAgdGhpcy5wYXJlbnRDb250ZXh0ID0gcGFyZW50Q29udGV4dDtcbiAgICAgICAgdGhpcy5yb290UmVxdWVzdCA9IHJvb3RSZXF1ZXN0O1xuICAgIH1cbiAgICByZXR1cm4gUGxhbjtcbn0oKSk7XG5leHBvcnRzLlBsYW4gPSBQbGFuO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgYmluZGluZ19jb3VudF8xID0gcmVxdWlyZShcIi4uL2JpbmRpbmdzL2JpbmRpbmdfY291bnRcIik7XG52YXIgRVJST1JfTVNHUyA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbnZhciBsaXRlcmFsX3R5cGVzXzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2xpdGVyYWxfdHlwZXNcIik7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIGV4Y2VwdGlvbnNfMSA9IHJlcXVpcmUoXCIuLi91dGlscy9leGNlcHRpb25zXCIpO1xudmFyIHNlcmlhbGl6YXRpb25fMSA9IHJlcXVpcmUoXCIuLi91dGlscy9zZXJpYWxpemF0aW9uXCIpO1xudmFyIGNvbnRleHRfMSA9IHJlcXVpcmUoXCIuL2NvbnRleHRcIik7XG52YXIgbWV0YWRhdGFfMSA9IHJlcXVpcmUoXCIuL21ldGFkYXRhXCIpO1xudmFyIHBsYW5fMSA9IHJlcXVpcmUoXCIuL3BsYW5cIik7XG52YXIgcmVmbGVjdGlvbl91dGlsc18xID0gcmVxdWlyZShcIi4vcmVmbGVjdGlvbl91dGlsc1wiKTtcbnZhciByZXF1ZXN0XzEgPSByZXF1aXJlKFwiLi9yZXF1ZXN0XCIpO1xudmFyIHRhcmdldF8xID0gcmVxdWlyZShcIi4vdGFyZ2V0XCIpO1xuZnVuY3Rpb24gZ2V0QmluZGluZ0RpY3Rpb25hcnkoY250bnIpIHtcbiAgICByZXR1cm4gY250bnIuX2JpbmRpbmdEaWN0aW9uYXJ5O1xufVxuZXhwb3J0cy5nZXRCaW5kaW5nRGljdGlvbmFyeSA9IGdldEJpbmRpbmdEaWN0aW9uYXJ5O1xuZnVuY3Rpb24gX2NyZWF0ZVRhcmdldChpc011bHRpSW5qZWN0LCB0YXJnZXRUeXBlLCBzZXJ2aWNlSWRlbnRpZmllciwgbmFtZSwga2V5LCB2YWx1ZSkge1xuICAgIHZhciBtZXRhZGF0YUtleSA9IGlzTXVsdGlJbmplY3QgPyBNRVRBREFUQV9LRVkuTVVMVElfSU5KRUNUX1RBRyA6IE1FVEFEQVRBX0tFWS5JTkpFQ1RfVEFHO1xuICAgIHZhciBpbmplY3RNZXRhZGF0YSA9IG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKG1ldGFkYXRhS2V5LCBzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgdmFyIHRhcmdldCA9IG5ldyB0YXJnZXRfMS5UYXJnZXQodGFyZ2V0VHlwZSwgbmFtZSwgc2VydmljZUlkZW50aWZpZXIsIGluamVjdE1ldGFkYXRhKTtcbiAgICBpZiAoa2V5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFyIHRhZ01ldGFkYXRhID0gbmV3IG1ldGFkYXRhXzEuTWV0YWRhdGEoa2V5LCB2YWx1ZSk7XG4gICAgICAgIHRhcmdldC5tZXRhZGF0YS5wdXNoKHRhZ01ldGFkYXRhKTtcbiAgICB9XG4gICAgcmV0dXJuIHRhcmdldDtcbn1cbmZ1bmN0aW9uIF9nZXRBY3RpdmVCaW5kaW5ncyhtZXRhZGF0YVJlYWRlciwgYXZvaWRDb25zdHJhaW50cywgY29udGV4dCwgcGFyZW50UmVxdWVzdCwgdGFyZ2V0KSB7XG4gICAgdmFyIGJpbmRpbmdzID0gZ2V0QmluZGluZ3MoY29udGV4dC5jb250YWluZXIsIHRhcmdldC5zZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgdmFyIGFjdGl2ZUJpbmRpbmdzID0gW107XG4gICAgaWYgKGJpbmRpbmdzLmxlbmd0aCA9PT0gYmluZGluZ19jb3VudF8xLkJpbmRpbmdDb3VudC5Ob0JpbmRpbmdzQXZhaWxhYmxlICYmXG4gICAgICAgIGNvbnRleHQuY29udGFpbmVyLm9wdGlvbnMuYXV0b0JpbmRJbmplY3RhYmxlICYmXG4gICAgICAgIHR5cGVvZiB0YXJnZXQuc2VydmljZUlkZW50aWZpZXIgPT09IFwiZnVuY3Rpb25cIiAmJlxuICAgICAgICBtZXRhZGF0YVJlYWRlci5nZXRDb25zdHJ1Y3Rvck1ldGFkYXRhKHRhcmdldC5zZXJ2aWNlSWRlbnRpZmllcikuY29tcGlsZXJHZW5lcmF0ZWRNZXRhZGF0YSkge1xuICAgICAgICBjb250ZXh0LmNvbnRhaW5lci5iaW5kKHRhcmdldC5zZXJ2aWNlSWRlbnRpZmllcikudG9TZWxmKCk7XG4gICAgICAgIGJpbmRpbmdzID0gZ2V0QmluZGluZ3MoY29udGV4dC5jb250YWluZXIsIHRhcmdldC5zZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgfVxuICAgIGlmICghYXZvaWRDb25zdHJhaW50cykge1xuICAgICAgICBhY3RpdmVCaW5kaW5ncyA9IGJpbmRpbmdzLmZpbHRlcihmdW5jdGlvbiAoYmluZGluZykge1xuICAgICAgICAgICAgdmFyIHJlcXVlc3QgPSBuZXcgcmVxdWVzdF8xLlJlcXVlc3QoYmluZGluZy5zZXJ2aWNlSWRlbnRpZmllciwgY29udGV4dCwgcGFyZW50UmVxdWVzdCwgYmluZGluZywgdGFyZ2V0KTtcbiAgICAgICAgICAgIHJldHVybiBiaW5kaW5nLmNvbnN0cmFpbnQocmVxdWVzdCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgYWN0aXZlQmluZGluZ3MgPSBiaW5kaW5ncztcbiAgICB9XG4gICAgX3ZhbGlkYXRlQWN0aXZlQmluZGluZ0NvdW50KHRhcmdldC5zZXJ2aWNlSWRlbnRpZmllciwgYWN0aXZlQmluZGluZ3MsIHRhcmdldCwgY29udGV4dC5jb250YWluZXIpO1xuICAgIHJldHVybiBhY3RpdmVCaW5kaW5ncztcbn1cbmZ1bmN0aW9uIF92YWxpZGF0ZUFjdGl2ZUJpbmRpbmdDb3VudChzZXJ2aWNlSWRlbnRpZmllciwgYmluZGluZ3MsIHRhcmdldCwgY29udGFpbmVyKSB7XG4gICAgc3dpdGNoIChiaW5kaW5ncy5sZW5ndGgpIHtcbiAgICAgICAgY2FzZSBiaW5kaW5nX2NvdW50XzEuQmluZGluZ0NvdW50Lk5vQmluZGluZ3NBdmFpbGFibGU6XG4gICAgICAgICAgICBpZiAodGFyZ2V0LmlzT3B0aW9uYWwoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBiaW5kaW5ncztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBzZXJ2aWNlSWRlbnRpZmllclN0cmluZyA9IHNlcmlhbGl6YXRpb25fMS5nZXRTZXJ2aWNlSWRlbnRpZmllckFzU3RyaW5nKHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgICAgICAgICB2YXIgbXNnID0gRVJST1JfTVNHUy5OT1RfUkVHSVNURVJFRDtcbiAgICAgICAgICAgICAgICBtc2cgKz0gc2VyaWFsaXphdGlvbl8xLmxpc3RNZXRhZGF0YUZvclRhcmdldChzZXJ2aWNlSWRlbnRpZmllclN0cmluZywgdGFyZ2V0KTtcbiAgICAgICAgICAgICAgICBtc2cgKz0gc2VyaWFsaXphdGlvbl8xLmxpc3RSZWdpc3RlcmVkQmluZGluZ3NGb3JTZXJ2aWNlSWRlbnRpZmllcihjb250YWluZXIsIHNlcnZpY2VJZGVudGlmaWVyU3RyaW5nLCBnZXRCaW5kaW5ncyk7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgYmluZGluZ19jb3VudF8xLkJpbmRpbmdDb3VudC5Pbmx5T25lQmluZGluZ0F2YWlsYWJsZTpcbiAgICAgICAgICAgIGlmICghdGFyZ2V0LmlzQXJyYXkoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBiaW5kaW5ncztcbiAgICAgICAgICAgIH1cbiAgICAgICAgY2FzZSBiaW5kaW5nX2NvdW50XzEuQmluZGluZ0NvdW50Lk11bHRpcGxlQmluZGluZ3NBdmFpbGFibGU6XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBpZiAoIXRhcmdldC5pc0FycmF5KCkpIHtcbiAgICAgICAgICAgICAgICB2YXIgc2VydmljZUlkZW50aWZpZXJTdHJpbmcgPSBzZXJpYWxpemF0aW9uXzEuZ2V0U2VydmljZUlkZW50aWZpZXJBc1N0cmluZyhzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgICAgICAgICAgdmFyIG1zZyA9IEVSUk9SX01TR1MuQU1CSUdVT1VTX01BVENIICsgXCIgXCIgKyBzZXJ2aWNlSWRlbnRpZmllclN0cmluZztcbiAgICAgICAgICAgICAgICBtc2cgKz0gc2VyaWFsaXphdGlvbl8xLmxpc3RSZWdpc3RlcmVkQmluZGluZ3NGb3JTZXJ2aWNlSWRlbnRpZmllcihjb250YWluZXIsIHNlcnZpY2VJZGVudGlmaWVyU3RyaW5nLCBnZXRCaW5kaW5ncyk7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYmluZGluZ3M7XG4gICAgICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gX2NyZWF0ZVN1YlJlcXVlc3RzKG1ldGFkYXRhUmVhZGVyLCBhdm9pZENvbnN0cmFpbnRzLCBzZXJ2aWNlSWRlbnRpZmllciwgY29udGV4dCwgcGFyZW50UmVxdWVzdCwgdGFyZ2V0KSB7XG4gICAgdmFyIGFjdGl2ZUJpbmRpbmdzO1xuICAgIHZhciBjaGlsZFJlcXVlc3Q7XG4gICAgaWYgKHBhcmVudFJlcXVlc3QgPT09IG51bGwpIHtcbiAgICAgICAgYWN0aXZlQmluZGluZ3MgPSBfZ2V0QWN0aXZlQmluZGluZ3MobWV0YWRhdGFSZWFkZXIsIGF2b2lkQ29uc3RyYWludHMsIGNvbnRleHQsIG51bGwsIHRhcmdldCk7XG4gICAgICAgIGNoaWxkUmVxdWVzdCA9IG5ldyByZXF1ZXN0XzEuUmVxdWVzdChzZXJ2aWNlSWRlbnRpZmllciwgY29udGV4dCwgbnVsbCwgYWN0aXZlQmluZGluZ3MsIHRhcmdldCk7XG4gICAgICAgIHZhciB0aGVQbGFuID0gbmV3IHBsYW5fMS5QbGFuKGNvbnRleHQsIGNoaWxkUmVxdWVzdCk7XG4gICAgICAgIGNvbnRleHQuYWRkUGxhbih0aGVQbGFuKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGFjdGl2ZUJpbmRpbmdzID0gX2dldEFjdGl2ZUJpbmRpbmdzKG1ldGFkYXRhUmVhZGVyLCBhdm9pZENvbnN0cmFpbnRzLCBjb250ZXh0LCBwYXJlbnRSZXF1ZXN0LCB0YXJnZXQpO1xuICAgICAgICBjaGlsZFJlcXVlc3QgPSBwYXJlbnRSZXF1ZXN0LmFkZENoaWxkUmVxdWVzdCh0YXJnZXQuc2VydmljZUlkZW50aWZpZXIsIGFjdGl2ZUJpbmRpbmdzLCB0YXJnZXQpO1xuICAgIH1cbiAgICBhY3RpdmVCaW5kaW5ncy5mb3JFYWNoKGZ1bmN0aW9uIChiaW5kaW5nKSB7XG4gICAgICAgIHZhciBzdWJDaGlsZFJlcXVlc3QgPSBudWxsO1xuICAgICAgICBpZiAodGFyZ2V0LmlzQXJyYXkoKSkge1xuICAgICAgICAgICAgc3ViQ2hpbGRSZXF1ZXN0ID0gY2hpbGRSZXF1ZXN0LmFkZENoaWxkUmVxdWVzdChiaW5kaW5nLnNlcnZpY2VJZGVudGlmaWVyLCBiaW5kaW5nLCB0YXJnZXQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKGJpbmRpbmcuY2FjaGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdWJDaGlsZFJlcXVlc3QgPSBjaGlsZFJlcXVlc3Q7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJpbmRpbmcudHlwZSA9PT0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5JbnN0YW5jZSAmJiBiaW5kaW5nLmltcGxlbWVudGF0aW9uVHlwZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGRlcGVuZGVuY2llcyA9IHJlZmxlY3Rpb25fdXRpbHNfMS5nZXREZXBlbmRlbmNpZXMobWV0YWRhdGFSZWFkZXIsIGJpbmRpbmcuaW1wbGVtZW50YXRpb25UeXBlKTtcbiAgICAgICAgICAgIGlmICghY29udGV4dC5jb250YWluZXIub3B0aW9ucy5za2lwQmFzZUNsYXNzQ2hlY2tzKSB7XG4gICAgICAgICAgICAgICAgdmFyIGJhc2VDbGFzc0RlcGVuZGVuY3lDb3VudCA9IHJlZmxlY3Rpb25fdXRpbHNfMS5nZXRCYXNlQ2xhc3NEZXBlbmRlbmN5Q291bnQobWV0YWRhdGFSZWFkZXIsIGJpbmRpbmcuaW1wbGVtZW50YXRpb25UeXBlKTtcbiAgICAgICAgICAgICAgICBpZiAoZGVwZW5kZW5jaWVzLmxlbmd0aCA8IGJhc2VDbGFzc0RlcGVuZGVuY3lDb3VudCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSBFUlJPUl9NU0dTLkFSR1VNRU5UU19MRU5HVEhfTUlTTUFUQ0gocmVmbGVjdGlvbl91dGlsc18xLmdldEZ1bmN0aW9uTmFtZShiaW5kaW5nLmltcGxlbWVudGF0aW9uVHlwZSkpO1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlcGVuZGVuY2llcy5mb3JFYWNoKGZ1bmN0aW9uIChkZXBlbmRlbmN5KSB7XG4gICAgICAgICAgICAgICAgX2NyZWF0ZVN1YlJlcXVlc3RzKG1ldGFkYXRhUmVhZGVyLCBmYWxzZSwgZGVwZW5kZW5jeS5zZXJ2aWNlSWRlbnRpZmllciwgY29udGV4dCwgc3ViQ2hpbGRSZXF1ZXN0LCBkZXBlbmRlbmN5KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5mdW5jdGlvbiBnZXRCaW5kaW5ncyhjb250YWluZXIsIHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgdmFyIGJpbmRpbmdzID0gW107XG4gICAgdmFyIGJpbmRpbmdEaWN0aW9uYXJ5ID0gZ2V0QmluZGluZ0RpY3Rpb25hcnkoY29udGFpbmVyKTtcbiAgICBpZiAoYmluZGluZ0RpY3Rpb25hcnkuaGFzS2V5KHNlcnZpY2VJZGVudGlmaWVyKSkge1xuICAgICAgICBiaW5kaW5ncyA9IGJpbmRpbmdEaWN0aW9uYXJ5LmdldChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgfVxuICAgIGVsc2UgaWYgKGNvbnRhaW5lci5wYXJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgYmluZGluZ3MgPSBnZXRCaW5kaW5ncyhjb250YWluZXIucGFyZW50LCBzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgfVxuICAgIHJldHVybiBiaW5kaW5ncztcbn1cbmZ1bmN0aW9uIHBsYW4obWV0YWRhdGFSZWFkZXIsIGNvbnRhaW5lciwgaXNNdWx0aUluamVjdCwgdGFyZ2V0VHlwZSwgc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUsIGF2b2lkQ29uc3RyYWludHMpIHtcbiAgICBpZiAoYXZvaWRDb25zdHJhaW50cyA9PT0gdm9pZCAwKSB7IGF2b2lkQ29uc3RyYWludHMgPSBmYWxzZTsgfVxuICAgIHZhciBjb250ZXh0ID0gbmV3IGNvbnRleHRfMS5Db250ZXh0KGNvbnRhaW5lcik7XG4gICAgdmFyIHRhcmdldCA9IF9jcmVhdGVUYXJnZXQoaXNNdWx0aUluamVjdCwgdGFyZ2V0VHlwZSwgc2VydmljZUlkZW50aWZpZXIsIFwiXCIsIGtleSwgdmFsdWUpO1xuICAgIHRyeSB7XG4gICAgICAgIF9jcmVhdGVTdWJSZXF1ZXN0cyhtZXRhZGF0YVJlYWRlciwgYXZvaWRDb25zdHJhaW50cywgc2VydmljZUlkZW50aWZpZXIsIGNvbnRleHQsIG51bGwsIHRhcmdldCk7XG4gICAgICAgIHJldHVybiBjb250ZXh0O1xuICAgIH1cbiAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKGV4Y2VwdGlvbnNfMS5pc1N0YWNrT3ZlcmZsb3dFeGVwdGlvbihlcnJvcikpIHtcbiAgICAgICAgICAgIGlmIChjb250ZXh0LnBsYW4pIHtcbiAgICAgICAgICAgICAgICBzZXJpYWxpemF0aW9uXzEuY2lyY3VsYXJEZXBlbmRlbmN5VG9FeGNlcHRpb24oY29udGV4dC5wbGFuLnJvb3RSZXF1ZXN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG59XG5leHBvcnRzLnBsYW4gPSBwbGFuO1xuZnVuY3Rpb24gY3JlYXRlTW9ja1JlcXVlc3QoY29udGFpbmVyLCBzZXJ2aWNlSWRlbnRpZmllciwga2V5LCB2YWx1ZSkge1xuICAgIHZhciB0YXJnZXQgPSBuZXcgdGFyZ2V0XzEuVGFyZ2V0KGxpdGVyYWxfdHlwZXNfMS5UYXJnZXRUeXBlRW51bS5WYXJpYWJsZSwgXCJcIiwgc2VydmljZUlkZW50aWZpZXIsIG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKGtleSwgdmFsdWUpKTtcbiAgICB2YXIgY29udGV4dCA9IG5ldyBjb250ZXh0XzEuQ29udGV4dChjb250YWluZXIpO1xuICAgIHZhciByZXF1ZXN0ID0gbmV3IHJlcXVlc3RfMS5SZXF1ZXN0KHNlcnZpY2VJZGVudGlmaWVyLCBjb250ZXh0LCBudWxsLCBbXSwgdGFyZ2V0KTtcbiAgICByZXR1cm4gcmVxdWVzdDtcbn1cbmV4cG9ydHMuY3JlYXRlTW9ja1JlcXVlc3QgPSBjcmVhdGVNb2NrUmVxdWVzdDtcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIFF1ZXJ5YWJsZVN0cmluZyA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gUXVlcnlhYmxlU3RyaW5nKHN0cikge1xuICAgICAgICB0aGlzLnN0ciA9IHN0cjtcbiAgICB9XG4gICAgUXVlcnlhYmxlU3RyaW5nLnByb3RvdHlwZS5zdGFydHNXaXRoID0gZnVuY3Rpb24gKHNlYXJjaFN0cmluZykge1xuICAgICAgICByZXR1cm4gdGhpcy5zdHIuaW5kZXhPZihzZWFyY2hTdHJpbmcpID09PSAwO1xuICAgIH07XG4gICAgUXVlcnlhYmxlU3RyaW5nLnByb3RvdHlwZS5lbmRzV2l0aCA9IGZ1bmN0aW9uIChzZWFyY2hTdHJpbmcpIHtcbiAgICAgICAgdmFyIHJldmVyc2VTdHJpbmcgPSBcIlwiO1xuICAgICAgICB2YXIgcmV2ZXJzZVNlYXJjaFN0cmluZyA9IHNlYXJjaFN0cmluZy5zcGxpdChcIlwiKS5yZXZlcnNlKCkuam9pbihcIlwiKTtcbiAgICAgICAgcmV2ZXJzZVN0cmluZyA9IHRoaXMuc3RyLnNwbGl0KFwiXCIpLnJldmVyc2UoKS5qb2luKFwiXCIpO1xuICAgICAgICByZXR1cm4gdGhpcy5zdGFydHNXaXRoLmNhbGwoeyBzdHI6IHJldmVyc2VTdHJpbmcgfSwgcmV2ZXJzZVNlYXJjaFN0cmluZyk7XG4gICAgfTtcbiAgICBRdWVyeWFibGVTdHJpbmcucHJvdG90eXBlLmNvbnRhaW5zID0gZnVuY3Rpb24gKHNlYXJjaFN0cmluZykge1xuICAgICAgICByZXR1cm4gKHRoaXMuc3RyLmluZGV4T2Yoc2VhcmNoU3RyaW5nKSAhPT0gLTEpO1xuICAgIH07XG4gICAgUXVlcnlhYmxlU3RyaW5nLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiAoY29tcGFyZVN0cmluZykge1xuICAgICAgICByZXR1cm4gdGhpcy5zdHIgPT09IGNvbXBhcmVTdHJpbmc7XG4gICAgfTtcbiAgICBRdWVyeWFibGVTdHJpbmcucHJvdG90eXBlLnZhbHVlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zdHI7XG4gICAgfTtcbiAgICByZXR1cm4gUXVlcnlhYmxlU3RyaW5nO1xufSgpKTtcbmV4cG9ydHMuUXVlcnlhYmxlU3RyaW5nID0gUXVlcnlhYmxlU3RyaW5nO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgaW5qZWN0XzEgPSByZXF1aXJlKFwiLi4vYW5ub3RhdGlvbi9pbmplY3RcIik7XG52YXIgRVJST1JfTVNHUyA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbnZhciBsaXRlcmFsX3R5cGVzXzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2xpdGVyYWxfdHlwZXNcIik7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIHNlcmlhbGl6YXRpb25fMSA9IHJlcXVpcmUoXCIuLi91dGlscy9zZXJpYWxpemF0aW9uXCIpO1xuZXhwb3J0cy5nZXRGdW5jdGlvbk5hbWUgPSBzZXJpYWxpemF0aW9uXzEuZ2V0RnVuY3Rpb25OYW1lO1xudmFyIHRhcmdldF8xID0gcmVxdWlyZShcIi4vdGFyZ2V0XCIpO1xuZnVuY3Rpb24gZ2V0RGVwZW5kZW5jaWVzKG1ldGFkYXRhUmVhZGVyLCBmdW5jKSB7XG4gICAgdmFyIGNvbnN0cnVjdG9yTmFtZSA9IHNlcmlhbGl6YXRpb25fMS5nZXRGdW5jdGlvbk5hbWUoZnVuYyk7XG4gICAgdmFyIHRhcmdldHMgPSBnZXRUYXJnZXRzKG1ldGFkYXRhUmVhZGVyLCBjb25zdHJ1Y3Rvck5hbWUsIGZ1bmMsIGZhbHNlKTtcbiAgICByZXR1cm4gdGFyZ2V0cztcbn1cbmV4cG9ydHMuZ2V0RGVwZW5kZW5jaWVzID0gZ2V0RGVwZW5kZW5jaWVzO1xuZnVuY3Rpb24gZ2V0VGFyZ2V0cyhtZXRhZGF0YVJlYWRlciwgY29uc3RydWN0b3JOYW1lLCBmdW5jLCBpc0Jhc2VDbGFzcykge1xuICAgIHZhciBtZXRhZGF0YSA9IG1ldGFkYXRhUmVhZGVyLmdldENvbnN0cnVjdG9yTWV0YWRhdGEoZnVuYyk7XG4gICAgdmFyIHNlcnZpY2VJZGVudGlmaWVycyA9IG1ldGFkYXRhLmNvbXBpbGVyR2VuZXJhdGVkTWV0YWRhdGE7XG4gICAgaWYgKHNlcnZpY2VJZGVudGlmaWVycyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhciBtc2cgPSBFUlJPUl9NU0dTLk1JU1NJTkdfSU5KRUNUQUJMRV9BTk5PVEFUSU9OICsgXCIgXCIgKyBjb25zdHJ1Y3Rvck5hbWUgKyBcIi5cIjtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgfVxuICAgIHZhciBjb25zdHJ1Y3RvckFyZ3NNZXRhZGF0YSA9IG1ldGFkYXRhLnVzZXJHZW5lcmF0ZWRNZXRhZGF0YTtcbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGNvbnN0cnVjdG9yQXJnc01ldGFkYXRhKTtcbiAgICB2YXIgaGFzVXNlckRlY2xhcmVkVW5rbm93bkluamVjdGlvbnMgPSAoZnVuYy5sZW5ndGggPT09IDAgJiYga2V5cy5sZW5ndGggPiAwKTtcbiAgICB2YXIgaXRlcmF0aW9ucyA9IChoYXNVc2VyRGVjbGFyZWRVbmtub3duSW5qZWN0aW9ucykgPyBrZXlzLmxlbmd0aCA6IGZ1bmMubGVuZ3RoO1xuICAgIHZhciBjb25zdHJ1Y3RvclRhcmdldHMgPSBnZXRDb25zdHJ1Y3RvckFyZ3NBc1RhcmdldHMoaXNCYXNlQ2xhc3MsIGNvbnN0cnVjdG9yTmFtZSwgc2VydmljZUlkZW50aWZpZXJzLCBjb25zdHJ1Y3RvckFyZ3NNZXRhZGF0YSwgaXRlcmF0aW9ucyk7XG4gICAgdmFyIHByb3BlcnR5VGFyZ2V0cyA9IGdldENsYXNzUHJvcHNBc1RhcmdldHMobWV0YWRhdGFSZWFkZXIsIGZ1bmMpO1xuICAgIHZhciB0YXJnZXRzID0gY29uc3RydWN0b3JUYXJnZXRzLmNvbmNhdChwcm9wZXJ0eVRhcmdldHMpO1xuICAgIHJldHVybiB0YXJnZXRzO1xufVxuZnVuY3Rpb24gZ2V0Q29uc3RydWN0b3JBcmdzQXNUYXJnZXQoaW5kZXgsIGlzQmFzZUNsYXNzLCBjb25zdHJ1Y3Rvck5hbWUsIHNlcnZpY2VJZGVudGlmaWVycywgY29uc3RydWN0b3JBcmdzTWV0YWRhdGEpIHtcbiAgICB2YXIgdGFyZ2V0TWV0YWRhdGEgPSBjb25zdHJ1Y3RvckFyZ3NNZXRhZGF0YVtpbmRleC50b1N0cmluZygpXSB8fCBbXTtcbiAgICB2YXIgbWV0YWRhdGEgPSBmb3JtYXRUYXJnZXRNZXRhZGF0YSh0YXJnZXRNZXRhZGF0YSk7XG4gICAgdmFyIGlzTWFuYWdlZCA9IG1ldGFkYXRhLnVubWFuYWdlZCAhPT0gdHJ1ZTtcbiAgICB2YXIgc2VydmljZUlkZW50aWZpZXIgPSBzZXJ2aWNlSWRlbnRpZmllcnNbaW5kZXhdO1xuICAgIHZhciBpbmplY3RJZGVudGlmaWVyID0gKG1ldGFkYXRhLmluamVjdCB8fCBtZXRhZGF0YS5tdWx0aUluamVjdCk7XG4gICAgc2VydmljZUlkZW50aWZpZXIgPSAoaW5qZWN0SWRlbnRpZmllcikgPyAoaW5qZWN0SWRlbnRpZmllcikgOiBzZXJ2aWNlSWRlbnRpZmllcjtcbiAgICBpZiAoc2VydmljZUlkZW50aWZpZXIgaW5zdGFuY2VvZiBpbmplY3RfMS5MYXp5U2VydmljZUlkZW50aWZlcikge1xuICAgICAgICBzZXJ2aWNlSWRlbnRpZmllciA9IHNlcnZpY2VJZGVudGlmaWVyLnVud3JhcCgpO1xuICAgIH1cbiAgICBpZiAoaXNNYW5hZ2VkKSB7XG4gICAgICAgIHZhciBpc09iamVjdCA9IHNlcnZpY2VJZGVudGlmaWVyID09PSBPYmplY3Q7XG4gICAgICAgIHZhciBpc0Z1bmN0aW9uID0gc2VydmljZUlkZW50aWZpZXIgPT09IEZ1bmN0aW9uO1xuICAgICAgICB2YXIgaXNVbmRlZmluZWQgPSBzZXJ2aWNlSWRlbnRpZmllciA9PT0gdW5kZWZpbmVkO1xuICAgICAgICB2YXIgaXNVbmtub3duVHlwZSA9IChpc09iamVjdCB8fCBpc0Z1bmN0aW9uIHx8IGlzVW5kZWZpbmVkKTtcbiAgICAgICAgaWYgKCFpc0Jhc2VDbGFzcyAmJiBpc1Vua25vd25UeXBlKSB7XG4gICAgICAgICAgICB2YXIgbXNnID0gRVJST1JfTVNHUy5NSVNTSU5HX0lOSkVDVF9BTk5PVEFUSU9OICsgXCIgYXJndW1lbnQgXCIgKyBpbmRleCArIFwiIGluIGNsYXNzIFwiICsgY29uc3RydWN0b3JOYW1lICsgXCIuXCI7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdGFyZ2V0ID0gbmV3IHRhcmdldF8xLlRhcmdldChsaXRlcmFsX3R5cGVzXzEuVGFyZ2V0VHlwZUVudW0uQ29uc3RydWN0b3JBcmd1bWVudCwgbWV0YWRhdGEudGFyZ2V0TmFtZSwgc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICB0YXJnZXQubWV0YWRhdGEgPSB0YXJnZXRNZXRhZGF0YTtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiBnZXRDb25zdHJ1Y3RvckFyZ3NBc1RhcmdldHMoaXNCYXNlQ2xhc3MsIGNvbnN0cnVjdG9yTmFtZSwgc2VydmljZUlkZW50aWZpZXJzLCBjb25zdHJ1Y3RvckFyZ3NNZXRhZGF0YSwgaXRlcmF0aW9ucykge1xuICAgIHZhciB0YXJnZXRzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpdGVyYXRpb25zOyBpKyspIHtcbiAgICAgICAgdmFyIGluZGV4ID0gaTtcbiAgICAgICAgdmFyIHRhcmdldCA9IGdldENvbnN0cnVjdG9yQXJnc0FzVGFyZ2V0KGluZGV4LCBpc0Jhc2VDbGFzcywgY29uc3RydWN0b3JOYW1lLCBzZXJ2aWNlSWRlbnRpZmllcnMsIGNvbnN0cnVjdG9yQXJnc01ldGFkYXRhKTtcbiAgICAgICAgaWYgKHRhcmdldCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGFyZ2V0cy5wdXNoKHRhcmdldCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRhcmdldHM7XG59XG5mdW5jdGlvbiBnZXRDbGFzc1Byb3BzQXNUYXJnZXRzKG1ldGFkYXRhUmVhZGVyLCBjb25zdHJ1Y3RvckZ1bmMpIHtcbiAgICB2YXIgY2xhc3NQcm9wc01ldGFkYXRhID0gbWV0YWRhdGFSZWFkZXIuZ2V0UHJvcGVydGllc01ldGFkYXRhKGNvbnN0cnVjdG9yRnVuYyk7XG4gICAgdmFyIHRhcmdldHMgPSBbXTtcbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGNsYXNzUHJvcHNNZXRhZGF0YSk7XG4gICAgZm9yICh2YXIgX2kgPSAwLCBrZXlzXzEgPSBrZXlzOyBfaSA8IGtleXNfMS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgdmFyIGtleSA9IGtleXNfMVtfaV07XG4gICAgICAgIHZhciB0YXJnZXRNZXRhZGF0YSA9IGNsYXNzUHJvcHNNZXRhZGF0YVtrZXldO1xuICAgICAgICB2YXIgbWV0YWRhdGEgPSBmb3JtYXRUYXJnZXRNZXRhZGF0YShjbGFzc1Byb3BzTWV0YWRhdGFba2V5XSk7XG4gICAgICAgIHZhciB0YXJnZXROYW1lID0gbWV0YWRhdGEudGFyZ2V0TmFtZSB8fCBrZXk7XG4gICAgICAgIHZhciBzZXJ2aWNlSWRlbnRpZmllciA9IChtZXRhZGF0YS5pbmplY3QgfHwgbWV0YWRhdGEubXVsdGlJbmplY3QpO1xuICAgICAgICB2YXIgdGFyZ2V0ID0gbmV3IHRhcmdldF8xLlRhcmdldChsaXRlcmFsX3R5cGVzXzEuVGFyZ2V0VHlwZUVudW0uQ2xhc3NQcm9wZXJ0eSwgdGFyZ2V0TmFtZSwgc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICB0YXJnZXQubWV0YWRhdGEgPSB0YXJnZXRNZXRhZGF0YTtcbiAgICAgICAgdGFyZ2V0cy5wdXNoKHRhcmdldCk7XG4gICAgfVxuICAgIHZhciBiYXNlQ29uc3RydWN0b3IgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoY29uc3RydWN0b3JGdW5jLnByb3RvdHlwZSkuY29uc3RydWN0b3I7XG4gICAgaWYgKGJhc2VDb25zdHJ1Y3RvciAhPT0gT2JqZWN0KSB7XG4gICAgICAgIHZhciBiYXNlVGFyZ2V0cyA9IGdldENsYXNzUHJvcHNBc1RhcmdldHMobWV0YWRhdGFSZWFkZXIsIGJhc2VDb25zdHJ1Y3Rvcik7XG4gICAgICAgIHRhcmdldHMgPSB0YXJnZXRzLmNvbmNhdChiYXNlVGFyZ2V0cyk7XG4gICAgfVxuICAgIHJldHVybiB0YXJnZXRzO1xufVxuZnVuY3Rpb24gZ2V0QmFzZUNsYXNzRGVwZW5kZW5jeUNvdW50KG1ldGFkYXRhUmVhZGVyLCBmdW5jKSB7XG4gICAgdmFyIGJhc2VDb25zdHJ1Y3RvciA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihmdW5jLnByb3RvdHlwZSkuY29uc3RydWN0b3I7XG4gICAgaWYgKGJhc2VDb25zdHJ1Y3RvciAhPT0gT2JqZWN0KSB7XG4gICAgICAgIHZhciBiYXNlQ29uc3RydWN0b3JOYW1lID0gc2VyaWFsaXphdGlvbl8xLmdldEZ1bmN0aW9uTmFtZShiYXNlQ29uc3RydWN0b3IpO1xuICAgICAgICB2YXIgdGFyZ2V0cyA9IGdldFRhcmdldHMobWV0YWRhdGFSZWFkZXIsIGJhc2VDb25zdHJ1Y3Rvck5hbWUsIGJhc2VDb25zdHJ1Y3RvciwgdHJ1ZSk7XG4gICAgICAgIHZhciBtZXRhZGF0YSA9IHRhcmdldHMubWFwKGZ1bmN0aW9uICh0KSB7XG4gICAgICAgICAgICByZXR1cm4gdC5tZXRhZGF0YS5maWx0ZXIoZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbS5rZXkgPT09IE1FVEFEQVRBX0tFWS5VTk1BTkFHRURfVEFHO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgdW5tYW5hZ2VkQ291bnQgPSBbXS5jb25jYXQuYXBwbHkoW10sIG1ldGFkYXRhKS5sZW5ndGg7XG4gICAgICAgIHZhciBkZXBlbmRlbmN5Q291bnQgPSB0YXJnZXRzLmxlbmd0aCAtIHVubWFuYWdlZENvdW50O1xuICAgICAgICBpZiAoZGVwZW5kZW5jeUNvdW50ID4gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGRlcGVuZGVuY3lDb3VudDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBnZXRCYXNlQ2xhc3NEZXBlbmRlbmN5Q291bnQobWV0YWRhdGFSZWFkZXIsIGJhc2VDb25zdHJ1Y3Rvcik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbn1cbmV4cG9ydHMuZ2V0QmFzZUNsYXNzRGVwZW5kZW5jeUNvdW50ID0gZ2V0QmFzZUNsYXNzRGVwZW5kZW5jeUNvdW50O1xuZnVuY3Rpb24gZm9ybWF0VGFyZ2V0TWV0YWRhdGEodGFyZ2V0TWV0YWRhdGEpIHtcbiAgICB2YXIgdGFyZ2V0TWV0YWRhdGFNYXAgPSB7fTtcbiAgICB0YXJnZXRNZXRhZGF0YS5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgIHRhcmdldE1ldGFkYXRhTWFwW20ua2V5LnRvU3RyaW5nKCldID0gbS52YWx1ZTtcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgICBpbmplY3Q6IHRhcmdldE1ldGFkYXRhTWFwW01FVEFEQVRBX0tFWS5JTkpFQ1RfVEFHXSxcbiAgICAgICAgbXVsdGlJbmplY3Q6IHRhcmdldE1ldGFkYXRhTWFwW01FVEFEQVRBX0tFWS5NVUxUSV9JTkpFQ1RfVEFHXSxcbiAgICAgICAgdGFyZ2V0TmFtZTogdGFyZ2V0TWV0YWRhdGFNYXBbTUVUQURBVEFfS0VZLk5BTUVfVEFHXSxcbiAgICAgICAgdW5tYW5hZ2VkOiB0YXJnZXRNZXRhZGF0YU1hcFtNRVRBREFUQV9LRVkuVU5NQU5BR0VEX1RBR11cbiAgICB9O1xufVxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgaWRfMSA9IHJlcXVpcmUoXCIuLi91dGlscy9pZFwiKTtcbnZhciBSZXF1ZXN0ID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBSZXF1ZXN0KHNlcnZpY2VJZGVudGlmaWVyLCBwYXJlbnRDb250ZXh0LCBwYXJlbnRSZXF1ZXN0LCBiaW5kaW5ncywgdGFyZ2V0KSB7XG4gICAgICAgIHRoaXMuaWQgPSBpZF8xLmlkKCk7XG4gICAgICAgIHRoaXMuc2VydmljZUlkZW50aWZpZXIgPSBzZXJ2aWNlSWRlbnRpZmllcjtcbiAgICAgICAgdGhpcy5wYXJlbnRDb250ZXh0ID0gcGFyZW50Q29udGV4dDtcbiAgICAgICAgdGhpcy5wYXJlbnRSZXF1ZXN0ID0gcGFyZW50UmVxdWVzdDtcbiAgICAgICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7XG4gICAgICAgIHRoaXMuY2hpbGRSZXF1ZXN0cyA9IFtdO1xuICAgICAgICB0aGlzLmJpbmRpbmdzID0gKEFycmF5LmlzQXJyYXkoYmluZGluZ3MpID8gYmluZGluZ3MgOiBbYmluZGluZ3NdKTtcbiAgICAgICAgdGhpcy5yZXF1ZXN0U2NvcGUgPSBwYXJlbnRSZXF1ZXN0ID09PSBudWxsXG4gICAgICAgICAgICA/IG5ldyBNYXAoKVxuICAgICAgICAgICAgOiBudWxsO1xuICAgIH1cbiAgICBSZXF1ZXN0LnByb3RvdHlwZS5hZGRDaGlsZFJlcXVlc3QgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIsIGJpbmRpbmdzLCB0YXJnZXQpIHtcbiAgICAgICAgdmFyIGNoaWxkID0gbmV3IFJlcXVlc3Qoc2VydmljZUlkZW50aWZpZXIsIHRoaXMucGFyZW50Q29udGV4dCwgdGhpcywgYmluZGluZ3MsIHRhcmdldCk7XG4gICAgICAgIHRoaXMuY2hpbGRSZXF1ZXN0cy5wdXNoKGNoaWxkKTtcbiAgICAgICAgcmV0dXJuIGNoaWxkO1xuICAgIH07XG4gICAgcmV0dXJuIFJlcXVlc3Q7XG59KCkpO1xuZXhwb3J0cy5SZXF1ZXN0ID0gUmVxdWVzdDtcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudmFyIE1FVEFEQVRBX0tFWSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbWV0YWRhdGFfa2V5c1wiKTtcbnZhciBpZF8xID0gcmVxdWlyZShcIi4uL3V0aWxzL2lkXCIpO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi9tZXRhZGF0YVwiKTtcbnZhciBxdWVyeWFibGVfc3RyaW5nXzEgPSByZXF1aXJlKFwiLi9xdWVyeWFibGVfc3RyaW5nXCIpO1xudmFyIFRhcmdldCA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gVGFyZ2V0KHR5cGUsIG5hbWUsIHNlcnZpY2VJZGVudGlmaWVyLCBuYW1lZE9yVGFnZ2VkKSB7XG4gICAgICAgIHRoaXMuaWQgPSBpZF8xLmlkKCk7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuc2VydmljZUlkZW50aWZpZXIgPSBzZXJ2aWNlSWRlbnRpZmllcjtcbiAgICAgICAgdGhpcy5uYW1lID0gbmV3IHF1ZXJ5YWJsZV9zdHJpbmdfMS5RdWVyeWFibGVTdHJpbmcobmFtZSB8fCBcIlwiKTtcbiAgICAgICAgdGhpcy5tZXRhZGF0YSA9IG5ldyBBcnJheSgpO1xuICAgICAgICB2YXIgbWV0YWRhdGFJdGVtID0gbnVsbDtcbiAgICAgICAgaWYgKHR5cGVvZiBuYW1lZE9yVGFnZ2VkID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICBtZXRhZGF0YUl0ZW0gPSBuZXcgbWV0YWRhdGFfMS5NZXRhZGF0YShNRVRBREFUQV9LRVkuTkFNRURfVEFHLCBuYW1lZE9yVGFnZ2VkKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChuYW1lZE9yVGFnZ2VkIGluc3RhbmNlb2YgbWV0YWRhdGFfMS5NZXRhZGF0YSkge1xuICAgICAgICAgICAgbWV0YWRhdGFJdGVtID0gbmFtZWRPclRhZ2dlZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWV0YWRhdGFJdGVtICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLm1ldGFkYXRhLnB1c2gobWV0YWRhdGFJdGVtKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBUYXJnZXQucHJvdG90eXBlLmhhc1RhZyA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHRoaXMubWV0YWRhdGE7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICB2YXIgbSA9IF9hW19pXTtcbiAgICAgICAgICAgIGlmIChtLmtleSA9PT0ga2V5KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG4gICAgVGFyZ2V0LnByb3RvdHlwZS5pc0FycmF5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5oYXNUYWcoTUVUQURBVEFfS0VZLk1VTFRJX0lOSkVDVF9UQUcpO1xuICAgIH07XG4gICAgVGFyZ2V0LnByb3RvdHlwZS5tYXRjaGVzQXJyYXkgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXRjaGVzVGFnKE1FVEFEQVRBX0tFWS5NVUxUSV9JTkpFQ1RfVEFHKShuYW1lKTtcbiAgICB9O1xuICAgIFRhcmdldC5wcm90b3R5cGUuaXNOYW1lZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzVGFnKE1FVEFEQVRBX0tFWS5OQU1FRF9UQUcpO1xuICAgIH07XG4gICAgVGFyZ2V0LnByb3RvdHlwZS5pc1RhZ2dlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGEuc29tZShmdW5jdGlvbiAobSkge1xuICAgICAgICAgICAgcmV0dXJuIChtLmtleSAhPT0gTUVUQURBVEFfS0VZLklOSkVDVF9UQUcpICYmXG4gICAgICAgICAgICAgICAgKG0ua2V5ICE9PSBNRVRBREFUQV9LRVkuTVVMVElfSU5KRUNUX1RBRykgJiZcbiAgICAgICAgICAgICAgICAobS5rZXkgIT09IE1FVEFEQVRBX0tFWS5OQU1FX1RBRykgJiZcbiAgICAgICAgICAgICAgICAobS5rZXkgIT09IE1FVEFEQVRBX0tFWS5VTk1BTkFHRURfVEFHKSAmJlxuICAgICAgICAgICAgICAgIChtLmtleSAhPT0gTUVUQURBVEFfS0VZLk5BTUVEX1RBRyk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgVGFyZ2V0LnByb3RvdHlwZS5pc09wdGlvbmFsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXRjaGVzVGFnKE1FVEFEQVRBX0tFWS5PUFRJT05BTF9UQUcpKHRydWUpO1xuICAgIH07XG4gICAgVGFyZ2V0LnByb3RvdHlwZS5nZXROYW1lZFRhZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNOYW1lZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5tZXRhZGF0YS5maWx0ZXIoZnVuY3Rpb24gKG0pIHsgcmV0dXJuIG0ua2V5ID09PSBNRVRBREFUQV9LRVkuTkFNRURfVEFHOyB9KVswXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICAgIFRhcmdldC5wcm90b3R5cGUuZ2V0Q3VzdG9tVGFncyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNUYWdnZWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGEuZmlsdGVyKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChtLmtleSAhPT0gTUVUQURBVEFfS0VZLklOSkVDVF9UQUcpICYmXG4gICAgICAgICAgICAgICAgICAgIChtLmtleSAhPT0gTUVUQURBVEFfS0VZLk1VTFRJX0lOSkVDVF9UQUcpICYmXG4gICAgICAgICAgICAgICAgICAgIChtLmtleSAhPT0gTUVUQURBVEFfS0VZLk5BTUVfVEFHKSAmJlxuICAgICAgICAgICAgICAgICAgICAobS5rZXkgIT09IE1FVEFEQVRBX0tFWS5VTk1BTkFHRURfVEFHKSAmJlxuICAgICAgICAgICAgICAgICAgICAobS5rZXkgIT09IE1FVEFEQVRBX0tFWS5OQU1FRF9UQUcpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgICBUYXJnZXQucHJvdG90eXBlLm1hdGNoZXNOYW1lZFRhZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hdGNoZXNUYWcoTUVUQURBVEFfS0VZLk5BTUVEX1RBRykobmFtZSk7XG4gICAgfTtcbiAgICBUYXJnZXQucHJvdG90eXBlLm1hdGNoZXNUYWcgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSBfdGhpcy5tZXRhZGF0YTsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgbSA9IF9hW19pXTtcbiAgICAgICAgICAgICAgICBpZiAobS5rZXkgPT09IGtleSAmJiBtLnZhbHVlID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICByZXR1cm4gVGFyZ2V0O1xufSgpKTtcbmV4cG9ydHMuVGFyZ2V0ID0gVGFyZ2V0O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgZXJyb3JfbXNnc18xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9lcnJvcl9tc2dzXCIpO1xudmFyIGxpdGVyYWxfdHlwZXNfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbGl0ZXJhbF90eXBlc1wiKTtcbnZhciBNRVRBREFUQV9LRVkgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG5mdW5jdGlvbiBfaW5qZWN0UHJvcGVydGllcyhpbnN0YW5jZSwgY2hpbGRSZXF1ZXN0cywgcmVzb2x2ZVJlcXVlc3QpIHtcbiAgICB2YXIgcHJvcGVydHlJbmplY3Rpb25zUmVxdWVzdHMgPSBjaGlsZFJlcXVlc3RzLmZpbHRlcihmdW5jdGlvbiAoY2hpbGRSZXF1ZXN0KSB7XG4gICAgICAgIHJldHVybiAoY2hpbGRSZXF1ZXN0LnRhcmdldCAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgY2hpbGRSZXF1ZXN0LnRhcmdldC50eXBlID09PSBsaXRlcmFsX3R5cGVzXzEuVGFyZ2V0VHlwZUVudW0uQ2xhc3NQcm9wZXJ0eSk7XG4gICAgfSk7XG4gICAgdmFyIHByb3BlcnR5SW5qZWN0aW9ucyA9IHByb3BlcnR5SW5qZWN0aW9uc1JlcXVlc3RzLm1hcChyZXNvbHZlUmVxdWVzdCk7XG4gICAgcHJvcGVydHlJbmplY3Rpb25zUmVxdWVzdHMuZm9yRWFjaChmdW5jdGlvbiAociwgaW5kZXgpIHtcbiAgICAgICAgdmFyIHByb3BlcnR5TmFtZSA9IFwiXCI7XG4gICAgICAgIHByb3BlcnR5TmFtZSA9IHIudGFyZ2V0Lm5hbWUudmFsdWUoKTtcbiAgICAgICAgdmFyIGluamVjdGlvbiA9IHByb3BlcnR5SW5qZWN0aW9uc1tpbmRleF07XG4gICAgICAgIGluc3RhbmNlW3Byb3BlcnR5TmFtZV0gPSBpbmplY3Rpb247XG4gICAgfSk7XG4gICAgcmV0dXJuIGluc3RhbmNlO1xufVxuZnVuY3Rpb24gX2NyZWF0ZUluc3RhbmNlKEZ1bmMsIGluamVjdGlvbnMpIHtcbiAgICByZXR1cm4gbmV3IChGdW5jLmJpbmQuYXBwbHkoRnVuYywgW3ZvaWQgMF0uY29uY2F0KGluamVjdGlvbnMpKSkoKTtcbn1cbmZ1bmN0aW9uIF9wb3N0Q29uc3RydWN0KGNvbnN0ciwgcmVzdWx0KSB7XG4gICAgaWYgKFJlZmxlY3QuaGFzTWV0YWRhdGEoTUVUQURBVEFfS0VZLlBPU1RfQ09OU1RSVUNULCBjb25zdHIpKSB7XG4gICAgICAgIHZhciBkYXRhID0gUmVmbGVjdC5nZXRNZXRhZGF0YShNRVRBREFUQV9LRVkuUE9TVF9DT05TVFJVQ1QsIGNvbnN0cik7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXN1bHRbZGF0YS52YWx1ZV0oKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yX21zZ3NfMS5QT1NUX0NPTlNUUlVDVF9FUlJPUihjb25zdHIubmFtZSwgZS5tZXNzYWdlKSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiByZXNvbHZlSW5zdGFuY2UoY29uc3RyLCBjaGlsZFJlcXVlc3RzLCByZXNvbHZlUmVxdWVzdCkge1xuICAgIHZhciByZXN1bHQgPSBudWxsO1xuICAgIGlmIChjaGlsZFJlcXVlc3RzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdmFyIGNvbnN0cnVjdG9ySW5qZWN0aW9uc1JlcXVlc3RzID0gY2hpbGRSZXF1ZXN0cy5maWx0ZXIoZnVuY3Rpb24gKGNoaWxkUmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuIChjaGlsZFJlcXVlc3QudGFyZ2V0ICE9PSBudWxsICYmIGNoaWxkUmVxdWVzdC50YXJnZXQudHlwZSA9PT0gbGl0ZXJhbF90eXBlc18xLlRhcmdldFR5cGVFbnVtLkNvbnN0cnVjdG9yQXJndW1lbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGNvbnN0cnVjdG9ySW5qZWN0aW9ucyA9IGNvbnN0cnVjdG9ySW5qZWN0aW9uc1JlcXVlc3RzLm1hcChyZXNvbHZlUmVxdWVzdCk7XG4gICAgICAgIHJlc3VsdCA9IF9jcmVhdGVJbnN0YW5jZShjb25zdHIsIGNvbnN0cnVjdG9ySW5qZWN0aW9ucyk7XG4gICAgICAgIHJlc3VsdCA9IF9pbmplY3RQcm9wZXJ0aWVzKHJlc3VsdCwgY2hpbGRSZXF1ZXN0cywgcmVzb2x2ZVJlcXVlc3QpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmVzdWx0ID0gbmV3IGNvbnN0cigpO1xuICAgIH1cbiAgICBfcG9zdENvbnN0cnVjdChjb25zdHIsIHJlc3VsdCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmV4cG9ydHMucmVzb2x2ZUluc3RhbmNlID0gcmVzb2x2ZUluc3RhbmNlO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgRVJST1JfTVNHUyA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbnZhciBsaXRlcmFsX3R5cGVzXzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2xpdGVyYWxfdHlwZXNcIik7XG52YXIgZXhjZXB0aW9uc18xID0gcmVxdWlyZShcIi4uL3V0aWxzL2V4Y2VwdGlvbnNcIik7XG52YXIgc2VyaWFsaXphdGlvbl8xID0gcmVxdWlyZShcIi4uL3V0aWxzL3NlcmlhbGl6YXRpb25cIik7XG52YXIgaW5zdGFudGlhdGlvbl8xID0gcmVxdWlyZShcIi4vaW5zdGFudGlhdGlvblwiKTtcbnZhciBpbnZva2VGYWN0b3J5ID0gZnVuY3Rpb24gKGZhY3RvcnlUeXBlLCBzZXJ2aWNlSWRlbnRpZmllciwgZm4pIHtcbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gZm4oKTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmIChleGNlcHRpb25zXzEuaXNTdGFja092ZXJmbG93RXhlcHRpb24oZXJyb3IpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTVNHUy5DSVJDVUxBUl9ERVBFTkRFTkNZX0lOX0ZBQ1RPUlkoZmFjdG9yeVR5cGUsIHNlcnZpY2VJZGVudGlmaWVyLnRvU3RyaW5nKCkpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgfVxufTtcbnZhciBfcmVzb2x2ZVJlcXVlc3QgPSBmdW5jdGlvbiAocmVxdWVzdFNjb3BlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG4gICAgICAgIHJlcXVlc3QucGFyZW50Q29udGV4dC5zZXRDdXJyZW50UmVxdWVzdChyZXF1ZXN0KTtcbiAgICAgICAgdmFyIGJpbmRpbmdzID0gcmVxdWVzdC5iaW5kaW5ncztcbiAgICAgICAgdmFyIGNoaWxkUmVxdWVzdHMgPSByZXF1ZXN0LmNoaWxkUmVxdWVzdHM7XG4gICAgICAgIHZhciB0YXJnZXRJc0FuQXJyYXkgPSByZXF1ZXN0LnRhcmdldCAmJiByZXF1ZXN0LnRhcmdldC5pc0FycmF5KCk7XG4gICAgICAgIHZhciB0YXJnZXRQYXJlbnRJc05vdEFuQXJyYXkgPSAhcmVxdWVzdC5wYXJlbnRSZXF1ZXN0IHx8XG4gICAgICAgICAgICAhcmVxdWVzdC5wYXJlbnRSZXF1ZXN0LnRhcmdldCB8fFxuICAgICAgICAgICAgIXJlcXVlc3QudGFyZ2V0IHx8XG4gICAgICAgICAgICAhcmVxdWVzdC5wYXJlbnRSZXF1ZXN0LnRhcmdldC5tYXRjaGVzQXJyYXkocmVxdWVzdC50YXJnZXQuc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICBpZiAodGFyZ2V0SXNBbkFycmF5ICYmIHRhcmdldFBhcmVudElzTm90QW5BcnJheSkge1xuICAgICAgICAgICAgcmV0dXJuIGNoaWxkUmVxdWVzdHMubWFwKGZ1bmN0aW9uIChjaGlsZFJlcXVlc3QpIHtcbiAgICAgICAgICAgICAgICB2YXIgX2YgPSBfcmVzb2x2ZVJlcXVlc3QocmVxdWVzdFNjb3BlKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2YoY2hpbGRSZXF1ZXN0KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IG51bGw7XG4gICAgICAgICAgICBpZiAocmVxdWVzdC50YXJnZXQuaXNPcHRpb25hbCgpICYmIGJpbmRpbmdzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgYmluZGluZ18xID0gYmluZGluZ3NbMF07XG4gICAgICAgICAgICB2YXIgaXNTaW5nbGV0b24gPSBiaW5kaW5nXzEuc2NvcGUgPT09IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nU2NvcGVFbnVtLlNpbmdsZXRvbjtcbiAgICAgICAgICAgIHZhciBpc1JlcXVlc3RTaW5nbGV0b24gPSBiaW5kaW5nXzEuc2NvcGUgPT09IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nU2NvcGVFbnVtLlJlcXVlc3Q7XG4gICAgICAgICAgICBpZiAoaXNTaW5nbGV0b24gJiYgYmluZGluZ18xLmFjdGl2YXRlZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBiaW5kaW5nXzEuY2FjaGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNSZXF1ZXN0U2luZ2xldG9uICYmXG4gICAgICAgICAgICAgICAgcmVxdWVzdFNjb3BlICE9PSBudWxsICYmXG4gICAgICAgICAgICAgICAgcmVxdWVzdFNjb3BlLmhhcyhiaW5kaW5nXzEuaWQpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3RTY29wZS5nZXQoYmluZGluZ18xLmlkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChiaW5kaW5nXzEudHlwZSA9PT0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5Db25zdGFudFZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gYmluZGluZ18xLmNhY2hlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoYmluZGluZ18xLnR5cGUgPT09IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uRnVuY3Rpb24pIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBiaW5kaW5nXzEuY2FjaGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChiaW5kaW5nXzEudHlwZSA9PT0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5Db25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGJpbmRpbmdfMS5pbXBsZW1lbnRhdGlvblR5cGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChiaW5kaW5nXzEudHlwZSA9PT0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5EeW5hbWljVmFsdWUgJiYgYmluZGluZ18xLmR5bmFtaWNWYWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGludm9rZUZhY3RvcnkoXCJ0b0R5bmFtaWNWYWx1ZVwiLCBiaW5kaW5nXzEuc2VydmljZUlkZW50aWZpZXIsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJpbmRpbmdfMS5keW5hbWljVmFsdWUocmVxdWVzdC5wYXJlbnRDb250ZXh0KTsgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChiaW5kaW5nXzEudHlwZSA9PT0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5GYWN0b3J5ICYmIGJpbmRpbmdfMS5mYWN0b3J5ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gaW52b2tlRmFjdG9yeShcInRvRmFjdG9yeVwiLCBiaW5kaW5nXzEuc2VydmljZUlkZW50aWZpZXIsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJpbmRpbmdfMS5mYWN0b3J5KHJlcXVlc3QucGFyZW50Q29udGV4dCk7IH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoYmluZGluZ18xLnR5cGUgPT09IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uUHJvdmlkZXIgJiYgYmluZGluZ18xLnByb3ZpZGVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gaW52b2tlRmFjdG9yeShcInRvUHJvdmlkZXJcIiwgYmluZGluZ18xLnNlcnZpY2VJZGVudGlmaWVyLCBmdW5jdGlvbiAoKSB7IHJldHVybiBiaW5kaW5nXzEucHJvdmlkZXIocmVxdWVzdC5wYXJlbnRDb250ZXh0KTsgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChiaW5kaW5nXzEudHlwZSA9PT0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5JbnN0YW5jZSAmJiBiaW5kaW5nXzEuaW1wbGVtZW50YXRpb25UeXBlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gaW5zdGFudGlhdGlvbl8xLnJlc29sdmVJbnN0YW5jZShiaW5kaW5nXzEuaW1wbGVtZW50YXRpb25UeXBlLCBjaGlsZFJlcXVlc3RzLCBfcmVzb2x2ZVJlcXVlc3QocmVxdWVzdFNjb3BlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgc2VydmljZUlkZW50aWZpZXIgPSBzZXJpYWxpemF0aW9uXzEuZ2V0U2VydmljZUlkZW50aWZpZXJBc1N0cmluZyhyZXF1ZXN0LnNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTVNHUy5JTlZBTElEX0JJTkRJTkdfVFlQRSArIFwiIFwiICsgc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBiaW5kaW5nXzEub25BY3RpdmF0aW9uID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBiaW5kaW5nXzEub25BY3RpdmF0aW9uKHJlcXVlc3QucGFyZW50Q29udGV4dCwgcmVzdWx0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc1NpbmdsZXRvbikge1xuICAgICAgICAgICAgICAgIGJpbmRpbmdfMS5jYWNoZSA9IHJlc3VsdDtcbiAgICAgICAgICAgICAgICBiaW5kaW5nXzEuYWN0aXZhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc1JlcXVlc3RTaW5nbGV0b24gJiZcbiAgICAgICAgICAgICAgICByZXF1ZXN0U2NvcGUgIT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICAhcmVxdWVzdFNjb3BlLmhhcyhiaW5kaW5nXzEuaWQpKSB7XG4gICAgICAgICAgICAgICAgcmVxdWVzdFNjb3BlLnNldChiaW5kaW5nXzEuaWQsIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgfTtcbn07XG5mdW5jdGlvbiByZXNvbHZlKGNvbnRleHQpIHtcbiAgICB2YXIgX2YgPSBfcmVzb2x2ZVJlcXVlc3QoY29udGV4dC5wbGFuLnJvb3RSZXF1ZXN0LnJlcXVlc3RTY29wZSk7XG4gICAgcmV0dXJuIF9mKGNvbnRleHQucGxhbi5yb290UmVxdWVzdCk7XG59XG5leHBvcnRzLnJlc29sdmUgPSByZXNvbHZlO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgbGl0ZXJhbF90eXBlc18xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9saXRlcmFsX3R5cGVzXCIpO1xudmFyIGJpbmRpbmdfd2hlbl9vbl9zeW50YXhfMSA9IHJlcXVpcmUoXCIuL2JpbmRpbmdfd2hlbl9vbl9zeW50YXhcIik7XG52YXIgQmluZGluZ0luU3ludGF4ID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBCaW5kaW5nSW5TeW50YXgoYmluZGluZykge1xuICAgICAgICB0aGlzLl9iaW5kaW5nID0gYmluZGluZztcbiAgICB9XG4gICAgQmluZGluZ0luU3ludGF4LnByb3RvdHlwZS5pblJlcXVlc3RTY29wZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5zY29wZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nU2NvcGVFbnVtLlJlcXVlc3Q7XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ193aGVuX29uX3N5bnRheF8xLkJpbmRpbmdXaGVuT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5TeW50YXgucHJvdG90eXBlLmluU2luZ2xldG9uU2NvcGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuc2NvcGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5TaW5nbGV0b247XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ193aGVuX29uX3N5bnRheF8xLkJpbmRpbmdXaGVuT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5TeW50YXgucHJvdG90eXBlLmluVHJhbnNpZW50U2NvcGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuc2NvcGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5UcmFuc2llbnQ7XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ193aGVuX29uX3N5bnRheF8xLkJpbmRpbmdXaGVuT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICByZXR1cm4gQmluZGluZ0luU3ludGF4O1xufSgpKTtcbmV4cG9ydHMuQmluZGluZ0luU3ludGF4ID0gQmluZGluZ0luU3ludGF4O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgYmluZGluZ19pbl9zeW50YXhfMSA9IHJlcXVpcmUoXCIuL2JpbmRpbmdfaW5fc3ludGF4XCIpO1xudmFyIGJpbmRpbmdfb25fc3ludGF4XzEgPSByZXF1aXJlKFwiLi9iaW5kaW5nX29uX3N5bnRheFwiKTtcbnZhciBiaW5kaW5nX3doZW5fc3ludGF4XzEgPSByZXF1aXJlKFwiLi9iaW5kaW5nX3doZW5fc3ludGF4XCIpO1xudmFyIEJpbmRpbmdJbldoZW5PblN5bnRheCA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQmluZGluZ0luV2hlbk9uU3ludGF4KGJpbmRpbmcpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZyA9IGJpbmRpbmc7XG4gICAgICAgIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4ID0gbmV3IGJpbmRpbmdfd2hlbl9zeW50YXhfMS5CaW5kaW5nV2hlblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICAgICAgdGhpcy5fYmluZGluZ09uU3ludGF4ID0gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgICAgICB0aGlzLl9iaW5kaW5nSW5TeW50YXggPSBuZXcgYmluZGluZ19pbl9zeW50YXhfMS5CaW5kaW5nSW5TeW50YXgoYmluZGluZyk7XG4gICAgfVxuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUuaW5SZXF1ZXN0U2NvcGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nSW5TeW50YXguaW5SZXF1ZXN0U2NvcGUoKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUuaW5TaW5nbGV0b25TY29wZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdJblN5bnRheC5pblNpbmdsZXRvblNjb3BlKCk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLmluVHJhbnNpZW50U2NvcGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nSW5TeW50YXguaW5UcmFuc2llbnRTY29wZSgpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuID0gZnVuY3Rpb24gKGNvbnN0cmFpbnQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW4oY29uc3RyYWludCk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5UYXJnZXROYW1lZCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuVGFyZ2V0TmFtZWQobmFtZSk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5UYXJnZXRJc0RlZmF1bHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuVGFyZ2V0SXNEZWZhdWx0KCk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5UYXJnZXRUYWdnZWQgPSBmdW5jdGlvbiAodGFnLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlblRhcmdldFRhZ2dlZCh0YWcsIHZhbHVlKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlbkluamVjdGVkSW50byA9IGZ1bmN0aW9uIChwYXJlbnQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5JbmplY3RlZEludG8ocGFyZW50KTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlblBhcmVudE5hbWVkID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5QYXJlbnROYW1lZChuYW1lKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlblBhcmVudFRhZ2dlZCA9IGZ1bmN0aW9uICh0YWcsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuUGFyZW50VGFnZ2VkKHRhZywgdmFsdWUpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuQW55QW5jZXN0b3JJcyA9IGZ1bmN0aW9uIChhbmNlc3Rvcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbkFueUFuY2VzdG9ySXMoYW5jZXN0b3IpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuTm9BbmNlc3RvcklzID0gZnVuY3Rpb24gKGFuY2VzdG9yKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuTm9BbmNlc3RvcklzKGFuY2VzdG9yKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlbkFueUFuY2VzdG9yTmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbkFueUFuY2VzdG9yTmFtZWQobmFtZSk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5BbnlBbmNlc3RvclRhZ2dlZCA9IGZ1bmN0aW9uICh0YWcsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuQW55QW5jZXN0b3JUYWdnZWQodGFnLCB2YWx1ZSk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5Ob0FuY2VzdG9yTmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbk5vQW5jZXN0b3JOYW1lZChuYW1lKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlbk5vQW5jZXN0b3JUYWdnZWQgPSBmdW5jdGlvbiAodGFnLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbk5vQW5jZXN0b3JUYWdnZWQodGFnLCB2YWx1ZSk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5BbnlBbmNlc3Rvck1hdGNoZXMgPSBmdW5jdGlvbiAoY29uc3RyYWludCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbkFueUFuY2VzdG9yTWF0Y2hlcyhjb25zdHJhaW50KTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlbk5vQW5jZXN0b3JNYXRjaGVzID0gZnVuY3Rpb24gKGNvbnN0cmFpbnQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5Ob0FuY2VzdG9yTWF0Y2hlcyhjb25zdHJhaW50KTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUub25BY3RpdmF0aW9uID0gZnVuY3Rpb24gKGhhbmRsZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdPblN5bnRheC5vbkFjdGl2YXRpb24oaGFuZGxlcik7XG4gICAgfTtcbiAgICByZXR1cm4gQmluZGluZ0luV2hlbk9uU3ludGF4O1xufSgpKTtcbmV4cG9ydHMuQmluZGluZ0luV2hlbk9uU3ludGF4ID0gQmluZGluZ0luV2hlbk9uU3ludGF4O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgYmluZGluZ193aGVuX3N5bnRheF8xID0gcmVxdWlyZShcIi4vYmluZGluZ193aGVuX3N5bnRheFwiKTtcbnZhciBCaW5kaW5nT25TeW50YXggPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEJpbmRpbmdPblN5bnRheChiaW5kaW5nKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcgPSBiaW5kaW5nO1xuICAgIH1cbiAgICBCaW5kaW5nT25TeW50YXgucHJvdG90eXBlLm9uQWN0aXZhdGlvbiA9IGZ1bmN0aW9uIChoYW5kbGVyKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcub25BY3RpdmF0aW9uID0gaGFuZGxlcjtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX3doZW5fc3ludGF4XzEuQmluZGluZ1doZW5TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICByZXR1cm4gQmluZGluZ09uU3ludGF4O1xufSgpKTtcbmV4cG9ydHMuQmluZGluZ09uU3ludGF4ID0gQmluZGluZ09uU3ludGF4O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgRVJST1JfTVNHUyA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbnZhciBsaXRlcmFsX3R5cGVzXzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2xpdGVyYWxfdHlwZXNcIik7XG52YXIgYmluZGluZ19pbl93aGVuX29uX3N5bnRheF8xID0gcmVxdWlyZShcIi4vYmluZGluZ19pbl93aGVuX29uX3N5bnRheFwiKTtcbnZhciBiaW5kaW5nX3doZW5fb25fc3ludGF4XzEgPSByZXF1aXJlKFwiLi9iaW5kaW5nX3doZW5fb25fc3ludGF4XCIpO1xudmFyIEJpbmRpbmdUb1N5bnRheCA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQmluZGluZ1RvU3ludGF4KGJpbmRpbmcpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZyA9IGJpbmRpbmc7XG4gICAgfVxuICAgIEJpbmRpbmdUb1N5bnRheC5wcm90b3R5cGUudG8gPSBmdW5jdGlvbiAoY29uc3RydWN0b3IpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy50eXBlID0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5JbnN0YW5jZTtcbiAgICAgICAgdGhpcy5fYmluZGluZy5pbXBsZW1lbnRhdGlvblR5cGUgPSBjb25zdHJ1Y3RvcjtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX2luX3doZW5fb25fc3ludGF4XzEuQmluZGluZ0luV2hlbk9uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1RvU3ludGF4LnByb3RvdHlwZS50b1NlbGYgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fYmluZGluZy5zZXJ2aWNlSWRlbnRpZmllciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJcIiArIEVSUk9SX01TR1MuSU5WQUxJRF9UT19TRUxGX1ZBTFVFKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc2VsZiA9IHRoaXMuX2JpbmRpbmcuc2VydmljZUlkZW50aWZpZXI7XG4gICAgICAgIHJldHVybiB0aGlzLnRvKHNlbGYpO1xuICAgIH07XG4gICAgQmluZGluZ1RvU3ludGF4LnByb3RvdHlwZS50b0NvbnN0YW50VmFsdWUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy50eXBlID0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5Db25zdGFudFZhbHVlO1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNhY2hlID0gdmFsdWU7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuZHluYW1pY1ZhbHVlID0gbnVsbDtcbiAgICAgICAgdGhpcy5fYmluZGluZy5pbXBsZW1lbnRhdGlvblR5cGUgPSBudWxsO1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfd2hlbl9vbl9zeW50YXhfMS5CaW5kaW5nV2hlbk9uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1RvU3ludGF4LnByb3RvdHlwZS50b0R5bmFtaWNWYWx1ZSA9IGZ1bmN0aW9uIChmdW5jKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcudHlwZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uRHluYW1pY1ZhbHVlO1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNhY2hlID0gbnVsbDtcbiAgICAgICAgdGhpcy5fYmluZGluZy5keW5hbWljVmFsdWUgPSBmdW5jO1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmltcGxlbWVudGF0aW9uVHlwZSA9IG51bGw7XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19pbl93aGVuX29uX3N5bnRheF8xLkJpbmRpbmdJbldoZW5PblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdUb1N5bnRheC5wcm90b3R5cGUudG9Db25zdHJ1Y3RvciA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLnR5cGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1R5cGVFbnVtLkNvbnN0cnVjdG9yO1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmltcGxlbWVudGF0aW9uVHlwZSA9IGNvbnN0cnVjdG9yO1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfd2hlbl9vbl9zeW50YXhfMS5CaW5kaW5nV2hlbk9uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1RvU3ludGF4LnByb3RvdHlwZS50b0ZhY3RvcnkgPSBmdW5jdGlvbiAoZmFjdG9yeSkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLnR5cGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1R5cGVFbnVtLkZhY3Rvcnk7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuZmFjdG9yeSA9IGZhY3Rvcnk7XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ193aGVuX29uX3N5bnRheF8xLkJpbmRpbmdXaGVuT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nVG9TeW50YXgucHJvdG90eXBlLnRvRnVuY3Rpb24gPSBmdW5jdGlvbiAoZnVuYykge1xuICAgICAgICBpZiAodHlwZW9mIGZ1bmMgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuSU5WQUxJRF9GVU5DVElPTl9CSU5ESU5HKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgYmluZGluZ1doZW5PblN5bnRheCA9IHRoaXMudG9Db25zdGFudFZhbHVlKGZ1bmMpO1xuICAgICAgICB0aGlzLl9iaW5kaW5nLnR5cGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1R5cGVFbnVtLkZ1bmN0aW9uO1xuICAgICAgICByZXR1cm4gYmluZGluZ1doZW5PblN5bnRheDtcbiAgICB9O1xuICAgIEJpbmRpbmdUb1N5bnRheC5wcm90b3R5cGUudG9BdXRvRmFjdG9yeSA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLnR5cGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1R5cGVFbnVtLkZhY3Rvcnk7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuZmFjdG9yeSA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICAgICAgICB2YXIgYXV0b2ZhY3RvcnkgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBjb250ZXh0LmNvbnRhaW5lci5nZXQoc2VydmljZUlkZW50aWZpZXIpOyB9O1xuICAgICAgICAgICAgcmV0dXJuIGF1dG9mYWN0b3J5O1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfd2hlbl9vbl9zeW50YXhfMS5CaW5kaW5nV2hlbk9uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1RvU3ludGF4LnByb3RvdHlwZS50b1Byb3ZpZGVyID0gZnVuY3Rpb24gKHByb3ZpZGVyKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcudHlwZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uUHJvdmlkZXI7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcucHJvdmlkZXIgPSBwcm92aWRlcjtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX3doZW5fb25fc3ludGF4XzEuQmluZGluZ1doZW5PblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdUb1N5bnRheC5wcm90b3R5cGUudG9TZXJ2aWNlID0gZnVuY3Rpb24gKHNlcnZpY2UpIHtcbiAgICAgICAgdGhpcy50b0R5bmFtaWNWYWx1ZShmdW5jdGlvbiAoY29udGV4dCkgeyByZXR1cm4gY29udGV4dC5jb250YWluZXIuZ2V0KHNlcnZpY2UpOyB9KTtcbiAgICB9O1xuICAgIHJldHVybiBCaW5kaW5nVG9TeW50YXg7XG59KCkpO1xuZXhwb3J0cy5CaW5kaW5nVG9TeW50YXggPSBCaW5kaW5nVG9TeW50YXg7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBiaW5kaW5nX29uX3N5bnRheF8xID0gcmVxdWlyZShcIi4vYmluZGluZ19vbl9zeW50YXhcIik7XG52YXIgYmluZGluZ193aGVuX3N5bnRheF8xID0gcmVxdWlyZShcIi4vYmluZGluZ193aGVuX3N5bnRheFwiKTtcbnZhciBCaW5kaW5nV2hlbk9uU3ludGF4ID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBCaW5kaW5nV2hlbk9uU3ludGF4KGJpbmRpbmcpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZyA9IGJpbmRpbmc7XG4gICAgICAgIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4ID0gbmV3IGJpbmRpbmdfd2hlbl9zeW50YXhfMS5CaW5kaW5nV2hlblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICAgICAgdGhpcy5fYmluZGluZ09uU3ludGF4ID0gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH1cbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuID0gZnVuY3Rpb24gKGNvbnN0cmFpbnQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW4oY29uc3RyYWludCk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuVGFyZ2V0TmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlblRhcmdldE5hbWVkKG5hbWUpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlblRhcmdldElzRGVmYXVsdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5UYXJnZXRJc0RlZmF1bHQoKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5UYXJnZXRUYWdnZWQgPSBmdW5jdGlvbiAodGFnLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlblRhcmdldFRhZ2dlZCh0YWcsIHZhbHVlKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5JbmplY3RlZEludG8gPSBmdW5jdGlvbiAocGFyZW50KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuSW5qZWN0ZWRJbnRvKHBhcmVudCk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuUGFyZW50TmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlblBhcmVudE5hbWVkKG5hbWUpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlblBhcmVudFRhZ2dlZCA9IGZ1bmN0aW9uICh0YWcsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuUGFyZW50VGFnZ2VkKHRhZywgdmFsdWUpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlbkFueUFuY2VzdG9ySXMgPSBmdW5jdGlvbiAoYW5jZXN0b3IpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5BbnlBbmNlc3RvcklzKGFuY2VzdG9yKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5Ob0FuY2VzdG9ySXMgPSBmdW5jdGlvbiAoYW5jZXN0b3IpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5Ob0FuY2VzdG9ySXMoYW5jZXN0b3IpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlbkFueUFuY2VzdG9yTmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbkFueUFuY2VzdG9yTmFtZWQobmFtZSk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuQW55QW5jZXN0b3JUYWdnZWQgPSBmdW5jdGlvbiAodGFnLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbkFueUFuY2VzdG9yVGFnZ2VkKHRhZywgdmFsdWUpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlbk5vQW5jZXN0b3JOYW1lZCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuTm9BbmNlc3Rvck5hbWVkKG5hbWUpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlbk5vQW5jZXN0b3JUYWdnZWQgPSBmdW5jdGlvbiAodGFnLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbk5vQW5jZXN0b3JUYWdnZWQodGFnLCB2YWx1ZSk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuQW55QW5jZXN0b3JNYXRjaGVzID0gZnVuY3Rpb24gKGNvbnN0cmFpbnQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5BbnlBbmNlc3Rvck1hdGNoZXMoY29uc3RyYWludCk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuTm9BbmNlc3Rvck1hdGNoZXMgPSBmdW5jdGlvbiAoY29uc3RyYWludCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbk5vQW5jZXN0b3JNYXRjaGVzKGNvbnN0cmFpbnQpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUub25BY3RpdmF0aW9uID0gZnVuY3Rpb24gKGhhbmRsZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdPblN5bnRheC5vbkFjdGl2YXRpb24oaGFuZGxlcik7XG4gICAgfTtcbiAgICByZXR1cm4gQmluZGluZ1doZW5PblN5bnRheDtcbn0oKSk7XG5leHBvcnRzLkJpbmRpbmdXaGVuT25TeW50YXggPSBCaW5kaW5nV2hlbk9uU3ludGF4O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgYmluZGluZ19vbl9zeW50YXhfMSA9IHJlcXVpcmUoXCIuL2JpbmRpbmdfb25fc3ludGF4XCIpO1xudmFyIGNvbnN0cmFpbnRfaGVscGVyc18xID0gcmVxdWlyZShcIi4vY29uc3RyYWludF9oZWxwZXJzXCIpO1xudmFyIEJpbmRpbmdXaGVuU3ludGF4ID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBCaW5kaW5nV2hlblN5bnRheChiaW5kaW5nKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcgPSBiaW5kaW5nO1xuICAgIH1cbiAgICBCaW5kaW5nV2hlblN5bnRheC5wcm90b3R5cGUud2hlbiA9IGZ1bmN0aW9uIChjb25zdHJhaW50KSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuY29uc3RyYWludCA9IGNvbnN0cmFpbnQ7XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlblN5bnRheC5wcm90b3R5cGUud2hlblRhcmdldE5hbWVkID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jb25zdHJhaW50ID0gY29uc3RyYWludF9oZWxwZXJzXzEubmFtZWRDb25zdHJhaW50KG5hbWUpO1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW5UYXJnZXRJc0RlZmF1bHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuY29uc3RyYWludCA9IGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG4gICAgICAgICAgICB2YXIgdGFyZ2V0SXNEZWZhdWx0ID0gKHJlcXVlc3QudGFyZ2V0ICE9PSBudWxsKSAmJlxuICAgICAgICAgICAgICAgICghcmVxdWVzdC50YXJnZXQuaXNOYW1lZCgpKSAmJlxuICAgICAgICAgICAgICAgICghcmVxdWVzdC50YXJnZXQuaXNUYWdnZWQoKSk7XG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0SXNEZWZhdWx0O1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW5UYXJnZXRUYWdnZWQgPSBmdW5jdGlvbiAodGFnLCB2YWx1ZSkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBjb25zdHJhaW50X2hlbHBlcnNfMS50YWdnZWRDb25zdHJhaW50KHRhZykodmFsdWUpO1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW5JbmplY3RlZEludG8gPSBmdW5jdGlvbiAocGFyZW50KSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuY29uc3RyYWludCA9IGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gY29uc3RyYWludF9oZWxwZXJzXzEudHlwZUNvbnN0cmFpbnQocGFyZW50KShyZXF1ZXN0LnBhcmVudFJlcXVlc3QpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW5QYXJlbnROYW1lZCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuY29uc3RyYWludCA9IGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gY29uc3RyYWludF9oZWxwZXJzXzEubmFtZWRDb25zdHJhaW50KG5hbWUpKHJlcXVlc3QucGFyZW50UmVxdWVzdCk7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlblN5bnRheC5wcm90b3R5cGUud2hlblBhcmVudFRhZ2dlZCA9IGZ1bmN0aW9uICh0YWcsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuY29uc3RyYWludCA9IGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gY29uc3RyYWludF9oZWxwZXJzXzEudGFnZ2VkQ29uc3RyYWludCh0YWcpKHZhbHVlKShyZXF1ZXN0LnBhcmVudFJlcXVlc3QpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW5BbnlBbmNlc3RvcklzID0gZnVuY3Rpb24gKGFuY2VzdG9yKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuY29uc3RyYWludCA9IGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gY29uc3RyYWludF9oZWxwZXJzXzEudHJhdmVyc2VBbmNlcnN0b3JzKHJlcXVlc3QsIGNvbnN0cmFpbnRfaGVscGVyc18xLnR5cGVDb25zdHJhaW50KGFuY2VzdG9yKSk7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlblN5bnRheC5wcm90b3R5cGUud2hlbk5vQW5jZXN0b3JJcyA9IGZ1bmN0aW9uIChhbmNlc3Rvcikge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuICFjb25zdHJhaW50X2hlbHBlcnNfMS50cmF2ZXJzZUFuY2Vyc3RvcnMocmVxdWVzdCwgY29uc3RyYWludF9oZWxwZXJzXzEudHlwZUNvbnN0cmFpbnQoYW5jZXN0b3IpKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuQW55QW5jZXN0b3JOYW1lZCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuY29uc3RyYWludCA9IGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gY29uc3RyYWludF9oZWxwZXJzXzEudHJhdmVyc2VBbmNlcnN0b3JzKHJlcXVlc3QsIGNvbnN0cmFpbnRfaGVscGVyc18xLm5hbWVkQ29uc3RyYWludChuYW1lKSk7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlblN5bnRheC5wcm90b3R5cGUud2hlbk5vQW5jZXN0b3JOYW1lZCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuY29uc3RyYWludCA9IGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gIWNvbnN0cmFpbnRfaGVscGVyc18xLnRyYXZlcnNlQW5jZXJzdG9ycyhyZXF1ZXN0LCBjb25zdHJhaW50X2hlbHBlcnNfMS5uYW1lZENvbnN0cmFpbnQobmFtZSkpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW5BbnlBbmNlc3RvclRhZ2dlZCA9IGZ1bmN0aW9uICh0YWcsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuY29uc3RyYWludCA9IGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gY29uc3RyYWludF9oZWxwZXJzXzEudHJhdmVyc2VBbmNlcnN0b3JzKHJlcXVlc3QsIGNvbnN0cmFpbnRfaGVscGVyc18xLnRhZ2dlZENvbnN0cmFpbnQodGFnKSh2YWx1ZSkpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW5Ob0FuY2VzdG9yVGFnZ2VkID0gZnVuY3Rpb24gKHRhZywgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jb25zdHJhaW50ID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgICAgIHJldHVybiAhY29uc3RyYWludF9oZWxwZXJzXzEudHJhdmVyc2VBbmNlcnN0b3JzKHJlcXVlc3QsIGNvbnN0cmFpbnRfaGVscGVyc18xLnRhZ2dlZENvbnN0cmFpbnQodGFnKSh2YWx1ZSkpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW5BbnlBbmNlc3Rvck1hdGNoZXMgPSBmdW5jdGlvbiAoY29uc3RyYWludCkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnRfaGVscGVyc18xLnRyYXZlcnNlQW5jZXJzdG9ycyhyZXF1ZXN0LCBjb25zdHJhaW50KTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuTm9BbmNlc3Rvck1hdGNoZXMgPSBmdW5jdGlvbiAoY29uc3RyYWludCkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuICFjb25zdHJhaW50X2hlbHBlcnNfMS50cmF2ZXJzZUFuY2Vyc3RvcnMocmVxdWVzdCwgY29uc3RyYWludCk7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICByZXR1cm4gQmluZGluZ1doZW5TeW50YXg7XG59KCkpO1xuZXhwb3J0cy5CaW5kaW5nV2hlblN5bnRheCA9IEJpbmRpbmdXaGVuU3ludGF4O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvbWV0YWRhdGFcIik7XG52YXIgdHJhdmVyc2VBbmNlcnN0b3JzID0gZnVuY3Rpb24gKHJlcXVlc3QsIGNvbnN0cmFpbnQpIHtcbiAgICB2YXIgcGFyZW50ID0gcmVxdWVzdC5wYXJlbnRSZXF1ZXN0O1xuICAgIGlmIChwYXJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnQocGFyZW50KSA/IHRydWUgOiB0cmF2ZXJzZUFuY2Vyc3RvcnMocGFyZW50LCBjb25zdHJhaW50KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59O1xuZXhwb3J0cy50cmF2ZXJzZUFuY2Vyc3RvcnMgPSB0cmF2ZXJzZUFuY2Vyc3RvcnM7XG52YXIgdGFnZ2VkQ29uc3RyYWludCA9IGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHZhciBjb25zdHJhaW50ID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgcmV0dXJuIHJlcXVlc3QgIT09IG51bGwgJiYgcmVxdWVzdC50YXJnZXQgIT09IG51bGwgJiYgcmVxdWVzdC50YXJnZXQubWF0Y2hlc1RhZyhrZXkpKHZhbHVlKTtcbiAgICB9O1xuICAgIGNvbnN0cmFpbnQubWV0YURhdGEgPSBuZXcgbWV0YWRhdGFfMS5NZXRhZGF0YShrZXksIHZhbHVlKTtcbiAgICByZXR1cm4gY29uc3RyYWludDtcbn07IH07XG5leHBvcnRzLnRhZ2dlZENvbnN0cmFpbnQgPSB0YWdnZWRDb25zdHJhaW50O1xudmFyIG5hbWVkQ29uc3RyYWludCA9IHRhZ2dlZENvbnN0cmFpbnQoTUVUQURBVEFfS0VZLk5BTUVEX1RBRyk7XG5leHBvcnRzLm5hbWVkQ29uc3RyYWludCA9IG5hbWVkQ29uc3RyYWludDtcbnZhciB0eXBlQ29uc3RyYWludCA9IGZ1bmN0aW9uICh0eXBlKSB7IHJldHVybiBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgIHZhciBiaW5kaW5nID0gbnVsbDtcbiAgICBpZiAocmVxdWVzdCAhPT0gbnVsbCkge1xuICAgICAgICBiaW5kaW5nID0gcmVxdWVzdC5iaW5kaW5nc1swXTtcbiAgICAgICAgaWYgKHR5cGVvZiB0eXBlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB2YXIgc2VydmljZUlkZW50aWZpZXIgPSBiaW5kaW5nLnNlcnZpY2VJZGVudGlmaWVyO1xuICAgICAgICAgICAgcmV0dXJuIHNlcnZpY2VJZGVudGlmaWVyID09PSB0eXBlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIGNvbnN0cnVjdG9yID0gcmVxdWVzdC5iaW5kaW5nc1swXS5pbXBsZW1lbnRhdGlvblR5cGU7XG4gICAgICAgICAgICByZXR1cm4gdHlwZSA9PT0gY29uc3RydWN0b3I7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTsgfTtcbmV4cG9ydHMudHlwZUNvbnN0cmFpbnQgPSB0eXBlQ29uc3RyYWludDtcbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5tdWx0aUJpbmRUb1NlcnZpY2UgPSBmdW5jdGlvbiAoY29udGFpbmVyKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChzZXJ2aWNlKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgdHlwZXMgPSBbXTtcbiAgICAgICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICAgICAgdHlwZXNbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0eXBlcy5mb3JFYWNoKGZ1bmN0aW9uICh0KSB7IHJldHVybiBjb250YWluZXIuYmluZCh0KS50b1NlcnZpY2Uoc2VydmljZSk7IH0pO1xuICAgICAgICB9O1xuICAgIH07XG59O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgRVJST1JfTVNHUyA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbmZ1bmN0aW9uIGlzU3RhY2tPdmVyZmxvd0V4ZXB0aW9uKGVycm9yKSB7XG4gICAgcmV0dXJuIChlcnJvciBpbnN0YW5jZW9mIFJhbmdlRXJyb3IgfHxcbiAgICAgICAgZXJyb3IubWVzc2FnZSA9PT0gRVJST1JfTVNHUy5TVEFDS19PVkVSRkxPVyk7XG59XG5leHBvcnRzLmlzU3RhY2tPdmVyZmxvd0V4ZXB0aW9uID0gaXNTdGFja092ZXJmbG93RXhlcHRpb247XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBpZENvdW50ZXIgPSAwO1xuZnVuY3Rpb24gaWQoKSB7XG4gICAgcmV0dXJuIGlkQ291bnRlcisrO1xufVxuZXhwb3J0cy5pZCA9IGlkO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgRVJST1JfTVNHUyA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbmZ1bmN0aW9uIGdldFNlcnZpY2VJZGVudGlmaWVyQXNTdHJpbmcoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICBpZiAodHlwZW9mIHNlcnZpY2VJZGVudGlmaWVyID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdmFyIF9zZXJ2aWNlSWRlbnRpZmllciA9IHNlcnZpY2VJZGVudGlmaWVyO1xuICAgICAgICByZXR1cm4gX3NlcnZpY2VJZGVudGlmaWVyLm5hbWU7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBzZXJ2aWNlSWRlbnRpZmllciA9PT0gXCJzeW1ib2xcIikge1xuICAgICAgICByZXR1cm4gc2VydmljZUlkZW50aWZpZXIudG9TdHJpbmcoKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHZhciBfc2VydmljZUlkZW50aWZpZXIgPSBzZXJ2aWNlSWRlbnRpZmllcjtcbiAgICAgICAgcmV0dXJuIF9zZXJ2aWNlSWRlbnRpZmllcjtcbiAgICB9XG59XG5leHBvcnRzLmdldFNlcnZpY2VJZGVudGlmaWVyQXNTdHJpbmcgPSBnZXRTZXJ2aWNlSWRlbnRpZmllckFzU3RyaW5nO1xuZnVuY3Rpb24gbGlzdFJlZ2lzdGVyZWRCaW5kaW5nc0ZvclNlcnZpY2VJZGVudGlmaWVyKGNvbnRhaW5lciwgc2VydmljZUlkZW50aWZpZXIsIGdldEJpbmRpbmdzKSB7XG4gICAgdmFyIHJlZ2lzdGVyZWRCaW5kaW5nc0xpc3QgPSBcIlwiO1xuICAgIHZhciByZWdpc3RlcmVkQmluZGluZ3MgPSBnZXRCaW5kaW5ncyhjb250YWluZXIsIHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICBpZiAocmVnaXN0ZXJlZEJpbmRpbmdzLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICByZWdpc3RlcmVkQmluZGluZ3NMaXN0ID0gXCJcXG5SZWdpc3RlcmVkIGJpbmRpbmdzOlwiO1xuICAgICAgICByZWdpc3RlcmVkQmluZGluZ3MuZm9yRWFjaChmdW5jdGlvbiAoYmluZGluZykge1xuICAgICAgICAgICAgdmFyIG5hbWUgPSBcIk9iamVjdFwiO1xuICAgICAgICAgICAgaWYgKGJpbmRpbmcuaW1wbGVtZW50YXRpb25UeXBlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgbmFtZSA9IGdldEZ1bmN0aW9uTmFtZShiaW5kaW5nLmltcGxlbWVudGF0aW9uVHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZWdpc3RlcmVkQmluZGluZ3NMaXN0ID0gcmVnaXN0ZXJlZEJpbmRpbmdzTGlzdCArIFwiXFxuIFwiICsgbmFtZTtcbiAgICAgICAgICAgIGlmIChiaW5kaW5nLmNvbnN0cmFpbnQubWV0YURhdGEpIHtcbiAgICAgICAgICAgICAgICByZWdpc3RlcmVkQmluZGluZ3NMaXN0ID0gcmVnaXN0ZXJlZEJpbmRpbmdzTGlzdCArIFwiIC0gXCIgKyBiaW5kaW5nLmNvbnN0cmFpbnQubWV0YURhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVnaXN0ZXJlZEJpbmRpbmdzTGlzdDtcbn1cbmV4cG9ydHMubGlzdFJlZ2lzdGVyZWRCaW5kaW5nc0ZvclNlcnZpY2VJZGVudGlmaWVyID0gbGlzdFJlZ2lzdGVyZWRCaW5kaW5nc0ZvclNlcnZpY2VJZGVudGlmaWVyO1xuZnVuY3Rpb24gYWxyZWFkeURlcGVuZGVuY3lDaGFpbihyZXF1ZXN0LCBzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgIGlmIChyZXF1ZXN0LnBhcmVudFJlcXVlc3QgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBlbHNlIGlmIChyZXF1ZXN0LnBhcmVudFJlcXVlc3Quc2VydmljZUlkZW50aWZpZXIgPT09IHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGFscmVhZHlEZXBlbmRlbmN5Q2hhaW4ocmVxdWVzdC5wYXJlbnRSZXF1ZXN0LCBzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgfVxufVxuZnVuY3Rpb24gZGVwZW5kZW5jeUNoYWluVG9TdHJpbmcocmVxdWVzdCkge1xuICAgIGZ1bmN0aW9uIF9jcmVhdGVTdHJpbmdBcnIocmVxLCByZXN1bHQpIHtcbiAgICAgICAgaWYgKHJlc3VsdCA9PT0gdm9pZCAwKSB7IHJlc3VsdCA9IFtdOyB9XG4gICAgICAgIHZhciBzZXJ2aWNlSWRlbnRpZmllciA9IGdldFNlcnZpY2VJZGVudGlmaWVyQXNTdHJpbmcocmVxLnNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgcmVzdWx0LnB1c2goc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICBpZiAocmVxLnBhcmVudFJlcXVlc3QgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBfY3JlYXRlU3RyaW5nQXJyKHJlcS5wYXJlbnRSZXF1ZXN0LCByZXN1bHQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIHZhciBzdHJpbmdBcnIgPSBfY3JlYXRlU3RyaW5nQXJyKHJlcXVlc3QpO1xuICAgIHJldHVybiBzdHJpbmdBcnIucmV2ZXJzZSgpLmpvaW4oXCIgLS0+IFwiKTtcbn1cbmZ1bmN0aW9uIGNpcmN1bGFyRGVwZW5kZW5jeVRvRXhjZXB0aW9uKHJlcXVlc3QpIHtcbiAgICByZXF1ZXN0LmNoaWxkUmVxdWVzdHMuZm9yRWFjaChmdW5jdGlvbiAoY2hpbGRSZXF1ZXN0KSB7XG4gICAgICAgIGlmIChhbHJlYWR5RGVwZW5kZW5jeUNoYWluKGNoaWxkUmVxdWVzdCwgY2hpbGRSZXF1ZXN0LnNlcnZpY2VJZGVudGlmaWVyKSkge1xuICAgICAgICAgICAgdmFyIHNlcnZpY2VzID0gZGVwZW5kZW5jeUNoYWluVG9TdHJpbmcoY2hpbGRSZXF1ZXN0KTtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUl9NU0dTLkNJUkNVTEFSX0RFUEVOREVOQ1kgKyBcIiBcIiArIHNlcnZpY2VzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNpcmN1bGFyRGVwZW5kZW5jeVRvRXhjZXB0aW9uKGNoaWxkUmVxdWVzdCk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbmV4cG9ydHMuY2lyY3VsYXJEZXBlbmRlbmN5VG9FeGNlcHRpb24gPSBjaXJjdWxhckRlcGVuZGVuY3lUb0V4Y2VwdGlvbjtcbmZ1bmN0aW9uIGxpc3RNZXRhZGF0YUZvclRhcmdldChzZXJ2aWNlSWRlbnRpZmllclN0cmluZywgdGFyZ2V0KSB7XG4gICAgaWYgKHRhcmdldC5pc1RhZ2dlZCgpIHx8IHRhcmdldC5pc05hbWVkKCkpIHtcbiAgICAgICAgdmFyIG1fMSA9IFwiXCI7XG4gICAgICAgIHZhciBuYW1lZFRhZyA9IHRhcmdldC5nZXROYW1lZFRhZygpO1xuICAgICAgICB2YXIgb3RoZXJUYWdzID0gdGFyZ2V0LmdldEN1c3RvbVRhZ3MoKTtcbiAgICAgICAgaWYgKG5hbWVkVGFnICE9PSBudWxsKSB7XG4gICAgICAgICAgICBtXzEgKz0gbmFtZWRUYWcudG9TdHJpbmcoKSArIFwiXFxuXCI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG90aGVyVGFncyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgb3RoZXJUYWdzLmZvckVhY2goZnVuY3Rpb24gKHRhZykge1xuICAgICAgICAgICAgICAgIG1fMSArPSB0YWcudG9TdHJpbmcoKSArIFwiXFxuXCI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gXCIgXCIgKyBzZXJ2aWNlSWRlbnRpZmllclN0cmluZyArIFwiXFxuIFwiICsgc2VydmljZUlkZW50aWZpZXJTdHJpbmcgKyBcIiAtIFwiICsgbV8xO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFwiIFwiICsgc2VydmljZUlkZW50aWZpZXJTdHJpbmc7XG4gICAgfVxufVxuZXhwb3J0cy5saXN0TWV0YWRhdGFGb3JUYXJnZXQgPSBsaXN0TWV0YWRhdGFGb3JUYXJnZXQ7XG5mdW5jdGlvbiBnZXRGdW5jdGlvbk5hbWUodikge1xuICAgIGlmICh2Lm5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHYubmFtZTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHZhciBuYW1lXzEgPSB2LnRvU3RyaW5nKCk7XG4gICAgICAgIHZhciBtYXRjaCA9IG5hbWVfMS5tYXRjaCgvXmZ1bmN0aW9uXFxzKihbXlxccyhdKykvKTtcbiAgICAgICAgcmV0dXJuIG1hdGNoID8gbWF0Y2hbMV0gOiBcIkFub255bW91cyBmdW5jdGlvbjogXCIgKyBuYW1lXzE7XG4gICAgfVxufVxuZXhwb3J0cy5nZXRGdW5jdGlvbk5hbWUgPSBnZXRGdW5jdGlvbk5hbWU7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciByZXBsYWNlID0gU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlO1xudmFyIHBlcmNlbnRUd2VudGllcyA9IC8lMjAvZztcblxudmFyIHV0aWwgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG5cbnZhciBGb3JtYXQgPSB7XG4gICAgUkZDMTczODogJ1JGQzE3MzgnLFxuICAgIFJGQzM5ODY6ICdSRkMzOTg2J1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB1dGlsLmFzc2lnbihcbiAgICB7XG4gICAgICAgICdkZWZhdWx0JzogRm9ybWF0LlJGQzM5ODYsXG4gICAgICAgIGZvcm1hdHRlcnM6IHtcbiAgICAgICAgICAgIFJGQzE3Mzg6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXBsYWNlLmNhbGwodmFsdWUsIHBlcmNlbnRUd2VudGllcywgJysnKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBSRkMzOTg2OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sXG4gICAgRm9ybWF0XG4pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgc3RyaW5naWZ5ID0gcmVxdWlyZSgnLi9zdHJpbmdpZnknKTtcbnZhciBwYXJzZSA9IHJlcXVpcmUoJy4vcGFyc2UnKTtcbnZhciBmb3JtYXRzID0gcmVxdWlyZSgnLi9mb3JtYXRzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIGZvcm1hdHM6IGZvcm1hdHMsXG4gICAgcGFyc2U6IHBhcnNlLFxuICAgIHN0cmluZ2lmeTogc3RyaW5naWZ5XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG5cbnZhciBoYXMgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xuXG52YXIgZGVmYXVsdHMgPSB7XG4gICAgYWxsb3dEb3RzOiBmYWxzZSxcbiAgICBhbGxvd1Byb3RvdHlwZXM6IGZhbHNlLFxuICAgIGFycmF5TGltaXQ6IDIwLFxuICAgIGNoYXJzZXQ6ICd1dGYtOCcsXG4gICAgY2hhcnNldFNlbnRpbmVsOiBmYWxzZSxcbiAgICBjb21tYTogZmFsc2UsXG4gICAgZGVjb2RlcjogdXRpbHMuZGVjb2RlLFxuICAgIGRlbGltaXRlcjogJyYnLFxuICAgIGRlcHRoOiA1LFxuICAgIGlnbm9yZVF1ZXJ5UHJlZml4OiBmYWxzZSxcbiAgICBpbnRlcnByZXROdW1lcmljRW50aXRpZXM6IGZhbHNlLFxuICAgIHBhcmFtZXRlckxpbWl0OiAxMDAwLFxuICAgIHBhcnNlQXJyYXlzOiB0cnVlLFxuICAgIHBsYWluT2JqZWN0czogZmFsc2UsXG4gICAgc3RyaWN0TnVsbEhhbmRsaW5nOiBmYWxzZVxufTtcblxudmFyIGludGVycHJldE51bWVyaWNFbnRpdGllcyA9IGZ1bmN0aW9uIChzdHIpIHtcbiAgICByZXR1cm4gc3RyLnJlcGxhY2UoLyYjKFxcZCspOy9nLCBmdW5jdGlvbiAoJDAsIG51bWJlclN0cikge1xuICAgICAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShwYXJzZUludChudW1iZXJTdHIsIDEwKSk7XG4gICAgfSk7XG59O1xuXG4vLyBUaGlzIGlzIHdoYXQgYnJvd3NlcnMgd2lsbCBzdWJtaXQgd2hlbiB0aGUg4pyTIGNoYXJhY3RlciBvY2N1cnMgaW4gYW5cbi8vIGFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCBib2R5IGFuZCB0aGUgZW5jb2Rpbmcgb2YgdGhlIHBhZ2UgY29udGFpbmluZ1xuLy8gdGhlIGZvcm0gaXMgaXNvLTg4NTktMSwgb3Igd2hlbiB0aGUgc3VibWl0dGVkIGZvcm0gaGFzIGFuIGFjY2VwdC1jaGFyc2V0XG4vLyBhdHRyaWJ1dGUgb2YgaXNvLTg4NTktMS4gUHJlc3VtYWJseSBhbHNvIHdpdGggb3RoZXIgY2hhcnNldHMgdGhhdCBkbyBub3QgY29udGFpblxuLy8gdGhlIOKckyBjaGFyYWN0ZXIsIHN1Y2ggYXMgdXMtYXNjaWkuXG52YXIgaXNvU2VudGluZWwgPSAndXRmOD0lMjYlMjMxMDAwMyUzQic7IC8vIGVuY29kZVVSSUNvbXBvbmVudCgnJiMxMDAwMzsnKVxuXG4vLyBUaGVzZSBhcmUgdGhlIHBlcmNlbnQtZW5jb2RlZCB1dGYtOCBvY3RldHMgcmVwcmVzZW50aW5nIGEgY2hlY2ttYXJrLCBpbmRpY2F0aW5nIHRoYXQgdGhlIHJlcXVlc3QgYWN0dWFsbHkgaXMgdXRmLTggZW5jb2RlZC5cbnZhciBjaGFyc2V0U2VudGluZWwgPSAndXRmOD0lRTIlOUMlOTMnOyAvLyBlbmNvZGVVUklDb21wb25lbnQoJ+KckycpXG5cbnZhciBwYXJzZVZhbHVlcyA9IGZ1bmN0aW9uIHBhcnNlUXVlcnlTdHJpbmdWYWx1ZXMoc3RyLCBvcHRpb25zKSB7XG4gICAgdmFyIG9iaiA9IHt9O1xuICAgIHZhciBjbGVhblN0ciA9IG9wdGlvbnMuaWdub3JlUXVlcnlQcmVmaXggPyBzdHIucmVwbGFjZSgvXlxcPy8sICcnKSA6IHN0cjtcbiAgICB2YXIgbGltaXQgPSBvcHRpb25zLnBhcmFtZXRlckxpbWl0ID09PSBJbmZpbml0eSA/IHVuZGVmaW5lZCA6IG9wdGlvbnMucGFyYW1ldGVyTGltaXQ7XG4gICAgdmFyIHBhcnRzID0gY2xlYW5TdHIuc3BsaXQob3B0aW9ucy5kZWxpbWl0ZXIsIGxpbWl0KTtcbiAgICB2YXIgc2tpcEluZGV4ID0gLTE7IC8vIEtlZXAgdHJhY2sgb2Ygd2hlcmUgdGhlIHV0Zjggc2VudGluZWwgd2FzIGZvdW5kXG4gICAgdmFyIGk7XG5cbiAgICB2YXIgY2hhcnNldCA9IG9wdGlvbnMuY2hhcnNldDtcbiAgICBpZiAob3B0aW9ucy5jaGFyc2V0U2VudGluZWwpIHtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBpZiAocGFydHNbaV0uaW5kZXhPZigndXRmOD0nKSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGlmIChwYXJ0c1tpXSA9PT0gY2hhcnNldFNlbnRpbmVsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYXJzZXQgPSAndXRmLTgnO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocGFydHNbaV0gPT09IGlzb1NlbnRpbmVsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYXJzZXQgPSAnaXNvLTg4NTktMSc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNraXBJbmRleCA9IGk7XG4gICAgICAgICAgICAgICAgaSA9IHBhcnRzLmxlbmd0aDsgLy8gVGhlIGVzbGludCBzZXR0aW5ncyBkbyBub3QgYWxsb3cgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgaWYgKGkgPT09IHNraXBJbmRleCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHBhcnQgPSBwYXJ0c1tpXTtcblxuICAgICAgICB2YXIgYnJhY2tldEVxdWFsc1BvcyA9IHBhcnQuaW5kZXhPZignXT0nKTtcbiAgICAgICAgdmFyIHBvcyA9IGJyYWNrZXRFcXVhbHNQb3MgPT09IC0xID8gcGFydC5pbmRleE9mKCc9JykgOiBicmFja2V0RXF1YWxzUG9zICsgMTtcblxuICAgICAgICB2YXIga2V5LCB2YWw7XG4gICAgICAgIGlmIChwb3MgPT09IC0xKSB7XG4gICAgICAgICAgICBrZXkgPSBvcHRpb25zLmRlY29kZXIocGFydCwgZGVmYXVsdHMuZGVjb2RlciwgY2hhcnNldCwgJ2tleScpO1xuICAgICAgICAgICAgdmFsID0gb3B0aW9ucy5zdHJpY3ROdWxsSGFuZGxpbmcgPyBudWxsIDogJyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBrZXkgPSBvcHRpb25zLmRlY29kZXIocGFydC5zbGljZSgwLCBwb3MpLCBkZWZhdWx0cy5kZWNvZGVyLCBjaGFyc2V0LCAna2V5Jyk7XG4gICAgICAgICAgICB2YWwgPSBvcHRpb25zLmRlY29kZXIocGFydC5zbGljZShwb3MgKyAxKSwgZGVmYXVsdHMuZGVjb2RlciwgY2hhcnNldCwgJ3ZhbHVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodmFsICYmIG9wdGlvbnMuaW50ZXJwcmV0TnVtZXJpY0VudGl0aWVzICYmIGNoYXJzZXQgPT09ICdpc28tODg1OS0xJykge1xuICAgICAgICAgICAgdmFsID0gaW50ZXJwcmV0TnVtZXJpY0VudGl0aWVzKHZhbCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodmFsICYmIHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnICYmIG9wdGlvbnMuY29tbWEgJiYgdmFsLmluZGV4T2YoJywnKSA+IC0xKSB7XG4gICAgICAgICAgICB2YWwgPSB2YWwuc3BsaXQoJywnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJ0LmluZGV4T2YoJ1tdPScpID4gLTEpIHtcbiAgICAgICAgICAgIHZhbCA9IGlzQXJyYXkodmFsKSA/IFt2YWxdIDogdmFsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGhhcy5jYWxsKG9iaiwga2V5KSkge1xuICAgICAgICAgICAgb2JqW2tleV0gPSB1dGlscy5jb21iaW5lKG9ialtrZXldLCB2YWwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb2JqW2tleV0gPSB2YWw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb2JqO1xufTtcblxudmFyIHBhcnNlT2JqZWN0ID0gZnVuY3Rpb24gKGNoYWluLCB2YWwsIG9wdGlvbnMpIHtcbiAgICB2YXIgbGVhZiA9IHZhbDtcblxuICAgIGZvciAodmFyIGkgPSBjaGFpbi5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICB2YXIgb2JqO1xuICAgICAgICB2YXIgcm9vdCA9IGNoYWluW2ldO1xuXG4gICAgICAgIGlmIChyb290ID09PSAnW10nICYmIG9wdGlvbnMucGFyc2VBcnJheXMpIHtcbiAgICAgICAgICAgIG9iaiA9IFtdLmNvbmNhdChsZWFmKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG9iaiA9IG9wdGlvbnMucGxhaW5PYmplY3RzID8gT2JqZWN0LmNyZWF0ZShudWxsKSA6IHt9O1xuICAgICAgICAgICAgdmFyIGNsZWFuUm9vdCA9IHJvb3QuY2hhckF0KDApID09PSAnWycgJiYgcm9vdC5jaGFyQXQocm9vdC5sZW5ndGggLSAxKSA9PT0gJ10nID8gcm9vdC5zbGljZSgxLCAtMSkgOiByb290O1xuICAgICAgICAgICAgdmFyIGluZGV4ID0gcGFyc2VJbnQoY2xlYW5Sb290LCAxMCk7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMucGFyc2VBcnJheXMgJiYgY2xlYW5Sb290ID09PSAnJykge1xuICAgICAgICAgICAgICAgIG9iaiA9IHsgMDogbGVhZiB9O1xuICAgICAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgICAgICAhaXNOYU4oaW5kZXgpXG4gICAgICAgICAgICAgICAgJiYgcm9vdCAhPT0gY2xlYW5Sb290XG4gICAgICAgICAgICAgICAgJiYgU3RyaW5nKGluZGV4KSA9PT0gY2xlYW5Sb290XG4gICAgICAgICAgICAgICAgJiYgaW5kZXggPj0gMFxuICAgICAgICAgICAgICAgICYmIChvcHRpb25zLnBhcnNlQXJyYXlzICYmIGluZGV4IDw9IG9wdGlvbnMuYXJyYXlMaW1pdClcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIG9iaiA9IFtdO1xuICAgICAgICAgICAgICAgIG9ialtpbmRleF0gPSBsZWFmO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBvYmpbY2xlYW5Sb290XSA9IGxlYWY7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsZWFmID0gb2JqO1xuICAgIH1cblxuICAgIHJldHVybiBsZWFmO1xufTtcblxudmFyIHBhcnNlS2V5cyA9IGZ1bmN0aW9uIHBhcnNlUXVlcnlTdHJpbmdLZXlzKGdpdmVuS2V5LCB2YWwsIG9wdGlvbnMpIHtcbiAgICBpZiAoIWdpdmVuS2V5KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBUcmFuc2Zvcm0gZG90IG5vdGF0aW9uIHRvIGJyYWNrZXQgbm90YXRpb25cbiAgICB2YXIga2V5ID0gb3B0aW9ucy5hbGxvd0RvdHMgPyBnaXZlbktleS5yZXBsYWNlKC9cXC4oW14uW10rKS9nLCAnWyQxXScpIDogZ2l2ZW5LZXk7XG5cbiAgICAvLyBUaGUgcmVnZXggY2h1bmtzXG5cbiAgICB2YXIgYnJhY2tldHMgPSAvKFxcW1teW1xcXV0qXSkvO1xuICAgIHZhciBjaGlsZCA9IC8oXFxbW15bXFxdXSpdKS9nO1xuXG4gICAgLy8gR2V0IHRoZSBwYXJlbnRcblxuICAgIHZhciBzZWdtZW50ID0gb3B0aW9ucy5kZXB0aCA+IDAgJiYgYnJhY2tldHMuZXhlYyhrZXkpO1xuICAgIHZhciBwYXJlbnQgPSBzZWdtZW50ID8ga2V5LnNsaWNlKDAsIHNlZ21lbnQuaW5kZXgpIDoga2V5O1xuXG4gICAgLy8gU3Rhc2ggdGhlIHBhcmVudCBpZiBpdCBleGlzdHNcblxuICAgIHZhciBrZXlzID0gW107XG4gICAgaWYgKHBhcmVudCkge1xuICAgICAgICAvLyBJZiB3ZSBhcmVuJ3QgdXNpbmcgcGxhaW4gb2JqZWN0cywgb3B0aW9uYWxseSBwcmVmaXgga2V5cyB0aGF0IHdvdWxkIG92ZXJ3cml0ZSBvYmplY3QgcHJvdG90eXBlIHByb3BlcnRpZXNcbiAgICAgICAgaWYgKCFvcHRpb25zLnBsYWluT2JqZWN0cyAmJiBoYXMuY2FsbChPYmplY3QucHJvdG90eXBlLCBwYXJlbnQpKSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMuYWxsb3dQcm90b3R5cGVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAga2V5cy5wdXNoKHBhcmVudCk7XG4gICAgfVxuXG4gICAgLy8gTG9vcCB0aHJvdWdoIGNoaWxkcmVuIGFwcGVuZGluZyB0byB0aGUgYXJyYXkgdW50aWwgd2UgaGl0IGRlcHRoXG5cbiAgICB2YXIgaSA9IDA7XG4gICAgd2hpbGUgKG9wdGlvbnMuZGVwdGggPiAwICYmIChzZWdtZW50ID0gY2hpbGQuZXhlYyhrZXkpKSAhPT0gbnVsbCAmJiBpIDwgb3B0aW9ucy5kZXB0aCkge1xuICAgICAgICBpICs9IDE7XG4gICAgICAgIGlmICghb3B0aW9ucy5wbGFpbk9iamVjdHMgJiYgaGFzLmNhbGwoT2JqZWN0LnByb3RvdHlwZSwgc2VnbWVudFsxXS5zbGljZSgxLCAtMSkpKSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMuYWxsb3dQcm90b3R5cGVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGtleXMucHVzaChzZWdtZW50WzFdKTtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGVyZSdzIGEgcmVtYWluZGVyLCBqdXN0IGFkZCB3aGF0ZXZlciBpcyBsZWZ0XG5cbiAgICBpZiAoc2VnbWVudCkge1xuICAgICAgICBrZXlzLnB1c2goJ1snICsga2V5LnNsaWNlKHNlZ21lbnQuaW5kZXgpICsgJ10nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFyc2VPYmplY3Qoa2V5cywgdmFsLCBvcHRpb25zKTtcbn07XG5cbnZhciBub3JtYWxpemVQYXJzZU9wdGlvbnMgPSBmdW5jdGlvbiBub3JtYWxpemVQYXJzZU9wdGlvbnMob3B0cykge1xuICAgIGlmICghb3B0cykge1xuICAgICAgICByZXR1cm4gZGVmYXVsdHM7XG4gICAgfVxuXG4gICAgaWYgKG9wdHMuZGVjb2RlciAhPT0gbnVsbCAmJiBvcHRzLmRlY29kZXIgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb3B0cy5kZWNvZGVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0RlY29kZXIgaGFzIHRvIGJlIGEgZnVuY3Rpb24uJyk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRzLmNoYXJzZXQgIT09ICd1bmRlZmluZWQnICYmIG9wdHMuY2hhcnNldCAhPT0gJ3V0Zi04JyAmJiBvcHRzLmNoYXJzZXQgIT09ICdpc28tODg1OS0xJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjaGFyc2V0IG9wdGlvbiBtdXN0IGJlIGVpdGhlciB1dGYtOCwgaXNvLTg4NTktMSwgb3IgdW5kZWZpbmVkJyk7XG4gICAgfVxuICAgIHZhciBjaGFyc2V0ID0gdHlwZW9mIG9wdHMuY2hhcnNldCA9PT0gJ3VuZGVmaW5lZCcgPyBkZWZhdWx0cy5jaGFyc2V0IDogb3B0cy5jaGFyc2V0O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgYWxsb3dEb3RzOiB0eXBlb2Ygb3B0cy5hbGxvd0RvdHMgPT09ICd1bmRlZmluZWQnID8gZGVmYXVsdHMuYWxsb3dEb3RzIDogISFvcHRzLmFsbG93RG90cyxcbiAgICAgICAgYWxsb3dQcm90b3R5cGVzOiB0eXBlb2Ygb3B0cy5hbGxvd1Byb3RvdHlwZXMgPT09ICdib29sZWFuJyA/IG9wdHMuYWxsb3dQcm90b3R5cGVzIDogZGVmYXVsdHMuYWxsb3dQcm90b3R5cGVzLFxuICAgICAgICBhcnJheUxpbWl0OiB0eXBlb2Ygb3B0cy5hcnJheUxpbWl0ID09PSAnbnVtYmVyJyA/IG9wdHMuYXJyYXlMaW1pdCA6IGRlZmF1bHRzLmFycmF5TGltaXQsXG4gICAgICAgIGNoYXJzZXQ6IGNoYXJzZXQsXG4gICAgICAgIGNoYXJzZXRTZW50aW5lbDogdHlwZW9mIG9wdHMuY2hhcnNldFNlbnRpbmVsID09PSAnYm9vbGVhbicgPyBvcHRzLmNoYXJzZXRTZW50aW5lbCA6IGRlZmF1bHRzLmNoYXJzZXRTZW50aW5lbCxcbiAgICAgICAgY29tbWE6IHR5cGVvZiBvcHRzLmNvbW1hID09PSAnYm9vbGVhbicgPyBvcHRzLmNvbW1hIDogZGVmYXVsdHMuY29tbWEsXG4gICAgICAgIGRlY29kZXI6IHR5cGVvZiBvcHRzLmRlY29kZXIgPT09ICdmdW5jdGlvbicgPyBvcHRzLmRlY29kZXIgOiBkZWZhdWx0cy5kZWNvZGVyLFxuICAgICAgICBkZWxpbWl0ZXI6IHR5cGVvZiBvcHRzLmRlbGltaXRlciA9PT0gJ3N0cmluZycgfHwgdXRpbHMuaXNSZWdFeHAob3B0cy5kZWxpbWl0ZXIpID8gb3B0cy5kZWxpbWl0ZXIgOiBkZWZhdWx0cy5kZWxpbWl0ZXIsXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1pbXBsaWNpdC1jb2VyY2lvbiwgbm8tZXh0cmEtcGFyZW5zXG4gICAgICAgIGRlcHRoOiAodHlwZW9mIG9wdHMuZGVwdGggPT09ICdudW1iZXInIHx8IG9wdHMuZGVwdGggPT09IGZhbHNlKSA/ICtvcHRzLmRlcHRoIDogZGVmYXVsdHMuZGVwdGgsXG4gICAgICAgIGlnbm9yZVF1ZXJ5UHJlZml4OiBvcHRzLmlnbm9yZVF1ZXJ5UHJlZml4ID09PSB0cnVlLFxuICAgICAgICBpbnRlcnByZXROdW1lcmljRW50aXRpZXM6IHR5cGVvZiBvcHRzLmludGVycHJldE51bWVyaWNFbnRpdGllcyA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5pbnRlcnByZXROdW1lcmljRW50aXRpZXMgOiBkZWZhdWx0cy5pbnRlcnByZXROdW1lcmljRW50aXRpZXMsXG4gICAgICAgIHBhcmFtZXRlckxpbWl0OiB0eXBlb2Ygb3B0cy5wYXJhbWV0ZXJMaW1pdCA9PT0gJ251bWJlcicgPyBvcHRzLnBhcmFtZXRlckxpbWl0IDogZGVmYXVsdHMucGFyYW1ldGVyTGltaXQsXG4gICAgICAgIHBhcnNlQXJyYXlzOiBvcHRzLnBhcnNlQXJyYXlzICE9PSBmYWxzZSxcbiAgICAgICAgcGxhaW5PYmplY3RzOiB0eXBlb2Ygb3B0cy5wbGFpbk9iamVjdHMgPT09ICdib29sZWFuJyA/IG9wdHMucGxhaW5PYmplY3RzIDogZGVmYXVsdHMucGxhaW5PYmplY3RzLFxuICAgICAgICBzdHJpY3ROdWxsSGFuZGxpbmc6IHR5cGVvZiBvcHRzLnN0cmljdE51bGxIYW5kbGluZyA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5zdHJpY3ROdWxsSGFuZGxpbmcgOiBkZWZhdWx0cy5zdHJpY3ROdWxsSGFuZGxpbmdcbiAgICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoc3RyLCBvcHRzKSB7XG4gICAgdmFyIG9wdGlvbnMgPSBub3JtYWxpemVQYXJzZU9wdGlvbnMob3B0cyk7XG5cbiAgICBpZiAoc3RyID09PSAnJyB8fCBzdHIgPT09IG51bGwgfHwgdHlwZW9mIHN0ciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIG9wdGlvbnMucGxhaW5PYmplY3RzID8gT2JqZWN0LmNyZWF0ZShudWxsKSA6IHt9O1xuICAgIH1cblxuICAgIHZhciB0ZW1wT2JqID0gdHlwZW9mIHN0ciA9PT0gJ3N0cmluZycgPyBwYXJzZVZhbHVlcyhzdHIsIG9wdGlvbnMpIDogc3RyO1xuICAgIHZhciBvYmogPSBvcHRpb25zLnBsYWluT2JqZWN0cyA/IE9iamVjdC5jcmVhdGUobnVsbCkgOiB7fTtcblxuICAgIC8vIEl0ZXJhdGUgb3ZlciB0aGUga2V5cyBhbmQgc2V0dXAgdGhlIG5ldyBvYmplY3RcblxuICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXModGVtcE9iaik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgICAgICB2YXIgbmV3T2JqID0gcGFyc2VLZXlzKGtleSwgdGVtcE9ialtrZXldLCBvcHRpb25zKTtcbiAgICAgICAgb2JqID0gdXRpbHMubWVyZ2Uob2JqLCBuZXdPYmosIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIHJldHVybiB1dGlscy5jb21wYWN0KG9iaik7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgZm9ybWF0cyA9IHJlcXVpcmUoJy4vZm9ybWF0cycpO1xudmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbnZhciBhcnJheVByZWZpeEdlbmVyYXRvcnMgPSB7XG4gICAgYnJhY2tldHM6IGZ1bmN0aW9uIGJyYWNrZXRzKHByZWZpeCkge1xuICAgICAgICByZXR1cm4gcHJlZml4ICsgJ1tdJztcbiAgICB9LFxuICAgIGNvbW1hOiAnY29tbWEnLFxuICAgIGluZGljZXM6IGZ1bmN0aW9uIGluZGljZXMocHJlZml4LCBrZXkpIHtcbiAgICAgICAgcmV0dXJuIHByZWZpeCArICdbJyArIGtleSArICddJztcbiAgICB9LFxuICAgIHJlcGVhdDogZnVuY3Rpb24gcmVwZWF0KHByZWZpeCkge1xuICAgICAgICByZXR1cm4gcHJlZml4O1xuICAgIH1cbn07XG5cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheTtcbnZhciBwdXNoID0gQXJyYXkucHJvdG90eXBlLnB1c2g7XG52YXIgcHVzaFRvQXJyYXkgPSBmdW5jdGlvbiAoYXJyLCB2YWx1ZU9yQXJyYXkpIHtcbiAgICBwdXNoLmFwcGx5KGFyciwgaXNBcnJheSh2YWx1ZU9yQXJyYXkpID8gdmFsdWVPckFycmF5IDogW3ZhbHVlT3JBcnJheV0pO1xufTtcblxudmFyIHRvSVNPID0gRGF0ZS5wcm90b3R5cGUudG9JU09TdHJpbmc7XG5cbnZhciBkZWZhdWx0Rm9ybWF0ID0gZm9ybWF0c1snZGVmYXVsdCddO1xudmFyIGRlZmF1bHRzID0ge1xuICAgIGFkZFF1ZXJ5UHJlZml4OiBmYWxzZSxcbiAgICBhbGxvd0RvdHM6IGZhbHNlLFxuICAgIGNoYXJzZXQ6ICd1dGYtOCcsXG4gICAgY2hhcnNldFNlbnRpbmVsOiBmYWxzZSxcbiAgICBkZWxpbWl0ZXI6ICcmJyxcbiAgICBlbmNvZGU6IHRydWUsXG4gICAgZW5jb2RlcjogdXRpbHMuZW5jb2RlLFxuICAgIGVuY29kZVZhbHVlc09ubHk6IGZhbHNlLFxuICAgIGZvcm1hdDogZGVmYXVsdEZvcm1hdCxcbiAgICBmb3JtYXR0ZXI6IGZvcm1hdHMuZm9ybWF0dGVyc1tkZWZhdWx0Rm9ybWF0XSxcbiAgICAvLyBkZXByZWNhdGVkXG4gICAgaW5kaWNlczogZmFsc2UsXG4gICAgc2VyaWFsaXplRGF0ZTogZnVuY3Rpb24gc2VyaWFsaXplRGF0ZShkYXRlKSB7XG4gICAgICAgIHJldHVybiB0b0lTTy5jYWxsKGRhdGUpO1xuICAgIH0sXG4gICAgc2tpcE51bGxzOiBmYWxzZSxcbiAgICBzdHJpY3ROdWxsSGFuZGxpbmc6IGZhbHNlXG59O1xuXG52YXIgaXNOb25OdWxsaXNoUHJpbWl0aXZlID0gZnVuY3Rpb24gaXNOb25OdWxsaXNoUHJpbWl0aXZlKHYpIHtcbiAgICByZXR1cm4gdHlwZW9mIHYgPT09ICdzdHJpbmcnXG4gICAgICAgIHx8IHR5cGVvZiB2ID09PSAnbnVtYmVyJ1xuICAgICAgICB8fCB0eXBlb2YgdiA9PT0gJ2Jvb2xlYW4nXG4gICAgICAgIHx8IHR5cGVvZiB2ID09PSAnc3ltYm9sJ1xuICAgICAgICB8fCB0eXBlb2YgdiA9PT0gJ2JpZ2ludCc7XG59O1xuXG52YXIgc3RyaW5naWZ5ID0gZnVuY3Rpb24gc3RyaW5naWZ5KFxuICAgIG9iamVjdCxcbiAgICBwcmVmaXgsXG4gICAgZ2VuZXJhdGVBcnJheVByZWZpeCxcbiAgICBzdHJpY3ROdWxsSGFuZGxpbmcsXG4gICAgc2tpcE51bGxzLFxuICAgIGVuY29kZXIsXG4gICAgZmlsdGVyLFxuICAgIHNvcnQsXG4gICAgYWxsb3dEb3RzLFxuICAgIHNlcmlhbGl6ZURhdGUsXG4gICAgZm9ybWF0dGVyLFxuICAgIGVuY29kZVZhbHVlc09ubHksXG4gICAgY2hhcnNldFxuKSB7XG4gICAgdmFyIG9iaiA9IG9iamVjdDtcbiAgICBpZiAodHlwZW9mIGZpbHRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBvYmogPSBmaWx0ZXIocHJlZml4LCBvYmopO1xuICAgIH0gZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICBvYmogPSBzZXJpYWxpemVEYXRlKG9iaik7XG4gICAgfSBlbHNlIGlmIChnZW5lcmF0ZUFycmF5UHJlZml4ID09PSAnY29tbWEnICYmIGlzQXJyYXkob2JqKSkge1xuICAgICAgICBvYmogPSBvYmouam9pbignLCcpO1xuICAgIH1cblxuICAgIGlmIChvYmogPT09IG51bGwpIHtcbiAgICAgICAgaWYgKHN0cmljdE51bGxIYW5kbGluZykge1xuICAgICAgICAgICAgcmV0dXJuIGVuY29kZXIgJiYgIWVuY29kZVZhbHVlc09ubHkgPyBlbmNvZGVyKHByZWZpeCwgZGVmYXVsdHMuZW5jb2RlciwgY2hhcnNldCwgJ2tleScpIDogcHJlZml4O1xuICAgICAgICB9XG5cbiAgICAgICAgb2JqID0gJyc7XG4gICAgfVxuXG4gICAgaWYgKGlzTm9uTnVsbGlzaFByaW1pdGl2ZShvYmopIHx8IHV0aWxzLmlzQnVmZmVyKG9iaikpIHtcbiAgICAgICAgaWYgKGVuY29kZXIpIHtcbiAgICAgICAgICAgIHZhciBrZXlWYWx1ZSA9IGVuY29kZVZhbHVlc09ubHkgPyBwcmVmaXggOiBlbmNvZGVyKHByZWZpeCwgZGVmYXVsdHMuZW5jb2RlciwgY2hhcnNldCwgJ2tleScpO1xuICAgICAgICAgICAgcmV0dXJuIFtmb3JtYXR0ZXIoa2V5VmFsdWUpICsgJz0nICsgZm9ybWF0dGVyKGVuY29kZXIob2JqLCBkZWZhdWx0cy5lbmNvZGVyLCBjaGFyc2V0LCAndmFsdWUnKSldO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbZm9ybWF0dGVyKHByZWZpeCkgKyAnPScgKyBmb3JtYXR0ZXIoU3RyaW5nKG9iaikpXTtcbiAgICB9XG5cbiAgICB2YXIgdmFsdWVzID0gW107XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICB9XG5cbiAgICB2YXIgb2JqS2V5cztcbiAgICBpZiAoaXNBcnJheShmaWx0ZXIpKSB7XG4gICAgICAgIG9iaktleXMgPSBmaWx0ZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmopO1xuICAgICAgICBvYmpLZXlzID0gc29ydCA/IGtleXMuc29ydChzb3J0KSA6IGtleXM7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmpLZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBrZXkgPSBvYmpLZXlzW2ldO1xuXG4gICAgICAgIGlmIChza2lwTnVsbHMgJiYgb2JqW2tleV0gPT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzQXJyYXkob2JqKSkge1xuICAgICAgICAgICAgcHVzaFRvQXJyYXkodmFsdWVzLCBzdHJpbmdpZnkoXG4gICAgICAgICAgICAgICAgb2JqW2tleV0sXG4gICAgICAgICAgICAgICAgdHlwZW9mIGdlbmVyYXRlQXJyYXlQcmVmaXggPT09ICdmdW5jdGlvbicgPyBnZW5lcmF0ZUFycmF5UHJlZml4KHByZWZpeCwga2V5KSA6IHByZWZpeCxcbiAgICAgICAgICAgICAgICBnZW5lcmF0ZUFycmF5UHJlZml4LFxuICAgICAgICAgICAgICAgIHN0cmljdE51bGxIYW5kbGluZyxcbiAgICAgICAgICAgICAgICBza2lwTnVsbHMsXG4gICAgICAgICAgICAgICAgZW5jb2RlcixcbiAgICAgICAgICAgICAgICBmaWx0ZXIsXG4gICAgICAgICAgICAgICAgc29ydCxcbiAgICAgICAgICAgICAgICBhbGxvd0RvdHMsXG4gICAgICAgICAgICAgICAgc2VyaWFsaXplRGF0ZSxcbiAgICAgICAgICAgICAgICBmb3JtYXR0ZXIsXG4gICAgICAgICAgICAgICAgZW5jb2RlVmFsdWVzT25seSxcbiAgICAgICAgICAgICAgICBjaGFyc2V0XG4gICAgICAgICAgICApKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHB1c2hUb0FycmF5KHZhbHVlcywgc3RyaW5naWZ5KFxuICAgICAgICAgICAgICAgIG9ialtrZXldLFxuICAgICAgICAgICAgICAgIHByZWZpeCArIChhbGxvd0RvdHMgPyAnLicgKyBrZXkgOiAnWycgKyBrZXkgKyAnXScpLFxuICAgICAgICAgICAgICAgIGdlbmVyYXRlQXJyYXlQcmVmaXgsXG4gICAgICAgICAgICAgICAgc3RyaWN0TnVsbEhhbmRsaW5nLFxuICAgICAgICAgICAgICAgIHNraXBOdWxscyxcbiAgICAgICAgICAgICAgICBlbmNvZGVyLFxuICAgICAgICAgICAgICAgIGZpbHRlcixcbiAgICAgICAgICAgICAgICBzb3J0LFxuICAgICAgICAgICAgICAgIGFsbG93RG90cyxcbiAgICAgICAgICAgICAgICBzZXJpYWxpemVEYXRlLFxuICAgICAgICAgICAgICAgIGZvcm1hdHRlcixcbiAgICAgICAgICAgICAgICBlbmNvZGVWYWx1ZXNPbmx5LFxuICAgICAgICAgICAgICAgIGNoYXJzZXRcbiAgICAgICAgICAgICkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlcztcbn07XG5cbnZhciBub3JtYWxpemVTdHJpbmdpZnlPcHRpb25zID0gZnVuY3Rpb24gbm9ybWFsaXplU3RyaW5naWZ5T3B0aW9ucyhvcHRzKSB7XG4gICAgaWYgKCFvcHRzKSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0cztcbiAgICB9XG5cbiAgICBpZiAob3B0cy5lbmNvZGVyICE9PSBudWxsICYmIG9wdHMuZW5jb2RlciAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvcHRzLmVuY29kZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRW5jb2RlciBoYXMgdG8gYmUgYSBmdW5jdGlvbi4nKTtcbiAgICB9XG5cbiAgICB2YXIgY2hhcnNldCA9IG9wdHMuY2hhcnNldCB8fCBkZWZhdWx0cy5jaGFyc2V0O1xuICAgIGlmICh0eXBlb2Ygb3B0cy5jaGFyc2V0ICE9PSAndW5kZWZpbmVkJyAmJiBvcHRzLmNoYXJzZXQgIT09ICd1dGYtOCcgJiYgb3B0cy5jaGFyc2V0ICE9PSAnaXNvLTg4NTktMScpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIGNoYXJzZXQgb3B0aW9uIG11c3QgYmUgZWl0aGVyIHV0Zi04LCBpc28tODg1OS0xLCBvciB1bmRlZmluZWQnKTtcbiAgICB9XG5cbiAgICB2YXIgZm9ybWF0ID0gZm9ybWF0c1snZGVmYXVsdCddO1xuICAgIGlmICh0eXBlb2Ygb3B0cy5mb3JtYXQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGlmICghaGFzLmNhbGwoZm9ybWF0cy5mb3JtYXR0ZXJzLCBvcHRzLmZvcm1hdCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZm9ybWF0IG9wdGlvbiBwcm92aWRlZC4nKTtcbiAgICAgICAgfVxuICAgICAgICBmb3JtYXQgPSBvcHRzLmZvcm1hdDtcbiAgICB9XG4gICAgdmFyIGZvcm1hdHRlciA9IGZvcm1hdHMuZm9ybWF0dGVyc1tmb3JtYXRdO1xuXG4gICAgdmFyIGZpbHRlciA9IGRlZmF1bHRzLmZpbHRlcjtcbiAgICBpZiAodHlwZW9mIG9wdHMuZmlsdGVyID09PSAnZnVuY3Rpb24nIHx8IGlzQXJyYXkob3B0cy5maWx0ZXIpKSB7XG4gICAgICAgIGZpbHRlciA9IG9wdHMuZmlsdGVyO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIGFkZFF1ZXJ5UHJlZml4OiB0eXBlb2Ygb3B0cy5hZGRRdWVyeVByZWZpeCA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5hZGRRdWVyeVByZWZpeCA6IGRlZmF1bHRzLmFkZFF1ZXJ5UHJlZml4LFxuICAgICAgICBhbGxvd0RvdHM6IHR5cGVvZiBvcHRzLmFsbG93RG90cyA9PT0gJ3VuZGVmaW5lZCcgPyBkZWZhdWx0cy5hbGxvd0RvdHMgOiAhIW9wdHMuYWxsb3dEb3RzLFxuICAgICAgICBjaGFyc2V0OiBjaGFyc2V0LFxuICAgICAgICBjaGFyc2V0U2VudGluZWw6IHR5cGVvZiBvcHRzLmNoYXJzZXRTZW50aW5lbCA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5jaGFyc2V0U2VudGluZWwgOiBkZWZhdWx0cy5jaGFyc2V0U2VudGluZWwsXG4gICAgICAgIGRlbGltaXRlcjogdHlwZW9mIG9wdHMuZGVsaW1pdGVyID09PSAndW5kZWZpbmVkJyA/IGRlZmF1bHRzLmRlbGltaXRlciA6IG9wdHMuZGVsaW1pdGVyLFxuICAgICAgICBlbmNvZGU6IHR5cGVvZiBvcHRzLmVuY29kZSA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5lbmNvZGUgOiBkZWZhdWx0cy5lbmNvZGUsXG4gICAgICAgIGVuY29kZXI6IHR5cGVvZiBvcHRzLmVuY29kZXIgPT09ICdmdW5jdGlvbicgPyBvcHRzLmVuY29kZXIgOiBkZWZhdWx0cy5lbmNvZGVyLFxuICAgICAgICBlbmNvZGVWYWx1ZXNPbmx5OiB0eXBlb2Ygb3B0cy5lbmNvZGVWYWx1ZXNPbmx5ID09PSAnYm9vbGVhbicgPyBvcHRzLmVuY29kZVZhbHVlc09ubHkgOiBkZWZhdWx0cy5lbmNvZGVWYWx1ZXNPbmx5LFxuICAgICAgICBmaWx0ZXI6IGZpbHRlcixcbiAgICAgICAgZm9ybWF0dGVyOiBmb3JtYXR0ZXIsXG4gICAgICAgIHNlcmlhbGl6ZURhdGU6IHR5cGVvZiBvcHRzLnNlcmlhbGl6ZURhdGUgPT09ICdmdW5jdGlvbicgPyBvcHRzLnNlcmlhbGl6ZURhdGUgOiBkZWZhdWx0cy5zZXJpYWxpemVEYXRlLFxuICAgICAgICBza2lwTnVsbHM6IHR5cGVvZiBvcHRzLnNraXBOdWxscyA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5za2lwTnVsbHMgOiBkZWZhdWx0cy5za2lwTnVsbHMsXG4gICAgICAgIHNvcnQ6IHR5cGVvZiBvcHRzLnNvcnQgPT09ICdmdW5jdGlvbicgPyBvcHRzLnNvcnQgOiBudWxsLFxuICAgICAgICBzdHJpY3ROdWxsSGFuZGxpbmc6IHR5cGVvZiBvcHRzLnN0cmljdE51bGxIYW5kbGluZyA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5zdHJpY3ROdWxsSGFuZGxpbmcgOiBkZWZhdWx0cy5zdHJpY3ROdWxsSGFuZGxpbmdcbiAgICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqZWN0LCBvcHRzKSB7XG4gICAgdmFyIG9iaiA9IG9iamVjdDtcbiAgICB2YXIgb3B0aW9ucyA9IG5vcm1hbGl6ZVN0cmluZ2lmeU9wdGlvbnMob3B0cyk7XG5cbiAgICB2YXIgb2JqS2V5cztcbiAgICB2YXIgZmlsdGVyO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmZpbHRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmaWx0ZXIgPSBvcHRpb25zLmZpbHRlcjtcbiAgICAgICAgb2JqID0gZmlsdGVyKCcnLCBvYmopO1xuICAgIH0gZWxzZSBpZiAoaXNBcnJheShvcHRpb25zLmZpbHRlcikpIHtcbiAgICAgICAgZmlsdGVyID0gb3B0aW9ucy5maWx0ZXI7XG4gICAgICAgIG9iaktleXMgPSBmaWx0ZXI7XG4gICAgfVxuXG4gICAgdmFyIGtleXMgPSBbXTtcblxuICAgIGlmICh0eXBlb2Ygb2JqICE9PSAnb2JqZWN0JyB8fCBvYmogPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIHZhciBhcnJheUZvcm1hdDtcbiAgICBpZiAob3B0cyAmJiBvcHRzLmFycmF5Rm9ybWF0IGluIGFycmF5UHJlZml4R2VuZXJhdG9ycykge1xuICAgICAgICBhcnJheUZvcm1hdCA9IG9wdHMuYXJyYXlGb3JtYXQ7XG4gICAgfSBlbHNlIGlmIChvcHRzICYmICdpbmRpY2VzJyBpbiBvcHRzKSB7XG4gICAgICAgIGFycmF5Rm9ybWF0ID0gb3B0cy5pbmRpY2VzID8gJ2luZGljZXMnIDogJ3JlcGVhdCc7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgYXJyYXlGb3JtYXQgPSAnaW5kaWNlcyc7XG4gICAgfVxuXG4gICAgdmFyIGdlbmVyYXRlQXJyYXlQcmVmaXggPSBhcnJheVByZWZpeEdlbmVyYXRvcnNbYXJyYXlGb3JtYXRdO1xuXG4gICAgaWYgKCFvYmpLZXlzKSB7XG4gICAgICAgIG9iaktleXMgPSBPYmplY3Qua2V5cyhvYmopO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLnNvcnQpIHtcbiAgICAgICAgb2JqS2V5cy5zb3J0KG9wdGlvbnMuc29ydCk7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmpLZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBrZXkgPSBvYmpLZXlzW2ldO1xuXG4gICAgICAgIGlmIChvcHRpb25zLnNraXBOdWxscyAmJiBvYmpba2V5XSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgcHVzaFRvQXJyYXkoa2V5cywgc3RyaW5naWZ5KFxuICAgICAgICAgICAgb2JqW2tleV0sXG4gICAgICAgICAgICBrZXksXG4gICAgICAgICAgICBnZW5lcmF0ZUFycmF5UHJlZml4LFxuICAgICAgICAgICAgb3B0aW9ucy5zdHJpY3ROdWxsSGFuZGxpbmcsXG4gICAgICAgICAgICBvcHRpb25zLnNraXBOdWxscyxcbiAgICAgICAgICAgIG9wdGlvbnMuZW5jb2RlID8gb3B0aW9ucy5lbmNvZGVyIDogbnVsbCxcbiAgICAgICAgICAgIG9wdGlvbnMuZmlsdGVyLFxuICAgICAgICAgICAgb3B0aW9ucy5zb3J0LFxuICAgICAgICAgICAgb3B0aW9ucy5hbGxvd0RvdHMsXG4gICAgICAgICAgICBvcHRpb25zLnNlcmlhbGl6ZURhdGUsXG4gICAgICAgICAgICBvcHRpb25zLmZvcm1hdHRlcixcbiAgICAgICAgICAgIG9wdGlvbnMuZW5jb2RlVmFsdWVzT25seSxcbiAgICAgICAgICAgIG9wdGlvbnMuY2hhcnNldFxuICAgICAgICApKTtcbiAgICB9XG5cbiAgICB2YXIgam9pbmVkID0ga2V5cy5qb2luKG9wdGlvbnMuZGVsaW1pdGVyKTtcbiAgICB2YXIgcHJlZml4ID0gb3B0aW9ucy5hZGRRdWVyeVByZWZpeCA9PT0gdHJ1ZSA/ICc/JyA6ICcnO1xuXG4gICAgaWYgKG9wdGlvbnMuY2hhcnNldFNlbnRpbmVsKSB7XG4gICAgICAgIGlmIChvcHRpb25zLmNoYXJzZXQgPT09ICdpc28tODg1OS0xJykge1xuICAgICAgICAgICAgLy8gZW5jb2RlVVJJQ29tcG9uZW50KCcmIzEwMDAzOycpLCB0aGUgXCJudW1lcmljIGVudGl0eVwiIHJlcHJlc2VudGF0aW9uIG9mIGEgY2hlY2ttYXJrXG4gICAgICAgICAgICBwcmVmaXggKz0gJ3V0Zjg9JTI2JTIzMTAwMDMlM0ImJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGVuY29kZVVSSUNvbXBvbmVudCgn4pyTJylcbiAgICAgICAgICAgIHByZWZpeCArPSAndXRmOD0lRTIlOUMlOTMmJztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBqb2luZWQubGVuZ3RoID4gMCA/IHByZWZpeCArIGpvaW5lZCA6ICcnO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG5cbnZhciBoZXhUYWJsZSA9IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGFycmF5ID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICAgICAgICBhcnJheS5wdXNoKCclJyArICgoaSA8IDE2ID8gJzAnIDogJycpICsgaS50b1N0cmluZygxNikpLnRvVXBwZXJDYXNlKCkpO1xuICAgIH1cblxuICAgIHJldHVybiBhcnJheTtcbn0oKSk7XG5cbnZhciBjb21wYWN0UXVldWUgPSBmdW5jdGlvbiBjb21wYWN0UXVldWUocXVldWUpIHtcbiAgICB3aGlsZSAocXVldWUubGVuZ3RoID4gMSkge1xuICAgICAgICB2YXIgaXRlbSA9IHF1ZXVlLnBvcCgpO1xuICAgICAgICB2YXIgb2JqID0gaXRlbS5vYmpbaXRlbS5wcm9wXTtcblxuICAgICAgICBpZiAoaXNBcnJheShvYmopKSB7XG4gICAgICAgICAgICB2YXIgY29tcGFjdGVkID0gW107XG5cbiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgb2JqLmxlbmd0aDsgKytqKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmpbal0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBhY3RlZC5wdXNoKG9ialtqXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpdGVtLm9ialtpdGVtLnByb3BdID0gY29tcGFjdGVkO1xuICAgICAgICB9XG4gICAgfVxufTtcblxudmFyIGFycmF5VG9PYmplY3QgPSBmdW5jdGlvbiBhcnJheVRvT2JqZWN0KHNvdXJjZSwgb3B0aW9ucykge1xuICAgIHZhciBvYmogPSBvcHRpb25zICYmIG9wdGlvbnMucGxhaW5PYmplY3RzID8gT2JqZWN0LmNyZWF0ZShudWxsKSA6IHt9O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc291cmNlLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc291cmNlW2ldICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgb2JqW2ldID0gc291cmNlW2ldO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG9iajtcbn07XG5cbnZhciBtZXJnZSA9IGZ1bmN0aW9uIG1lcmdlKHRhcmdldCwgc291cmNlLCBvcHRpb25zKSB7XG4gICAgLyogZXNsaW50IG5vLXBhcmFtLXJlYXNzaWduOiAwICovXG4gICAgaWYgKCFzb3VyY2UpIHtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHNvdXJjZSAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgaWYgKGlzQXJyYXkodGFyZ2V0KSkge1xuICAgICAgICAgICAgdGFyZ2V0LnB1c2goc291cmNlKTtcbiAgICAgICAgfSBlbHNlIGlmICh0YXJnZXQgJiYgdHlwZW9mIHRhcmdldCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlmICgob3B0aW9ucyAmJiAob3B0aW9ucy5wbGFpbk9iamVjdHMgfHwgb3B0aW9ucy5hbGxvd1Byb3RvdHlwZXMpKSB8fCAhaGFzLmNhbGwoT2JqZWN0LnByb3RvdHlwZSwgc291cmNlKSkge1xuICAgICAgICAgICAgICAgIHRhcmdldFtzb3VyY2VdID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBbdGFyZ2V0LCBzb3VyY2VdO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG5cbiAgICBpZiAoIXRhcmdldCB8fCB0eXBlb2YgdGFyZ2V0ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gW3RhcmdldF0uY29uY2F0KHNvdXJjZSk7XG4gICAgfVxuXG4gICAgdmFyIG1lcmdlVGFyZ2V0ID0gdGFyZ2V0O1xuICAgIGlmIChpc0FycmF5KHRhcmdldCkgJiYgIWlzQXJyYXkoc291cmNlKSkge1xuICAgICAgICBtZXJnZVRhcmdldCA9IGFycmF5VG9PYmplY3QodGFyZ2V0LCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICBpZiAoaXNBcnJheSh0YXJnZXQpICYmIGlzQXJyYXkoc291cmNlKSkge1xuICAgICAgICBzb3VyY2UuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSwgaSkge1xuICAgICAgICAgICAgaWYgKGhhcy5jYWxsKHRhcmdldCwgaSkpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGFyZ2V0SXRlbSA9IHRhcmdldFtpXTtcbiAgICAgICAgICAgICAgICBpZiAodGFyZ2V0SXRlbSAmJiB0eXBlb2YgdGFyZ2V0SXRlbSA9PT0gJ29iamVjdCcgJiYgaXRlbSAmJiB0eXBlb2YgaXRlbSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W2ldID0gbWVyZ2UodGFyZ2V0SXRlbSwgaXRlbSwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LnB1c2goaXRlbSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0YXJnZXRbaV0gPSBpdGVtO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG5cbiAgICByZXR1cm4gT2JqZWN0LmtleXMoc291cmNlKS5yZWR1Y2UoZnVuY3Rpb24gKGFjYywga2V5KSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHNvdXJjZVtrZXldO1xuXG4gICAgICAgIGlmIChoYXMuY2FsbChhY2MsIGtleSkpIHtcbiAgICAgICAgICAgIGFjY1trZXldID0gbWVyZ2UoYWNjW2tleV0sIHZhbHVlLCBvcHRpb25zKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFjY1trZXldID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCBtZXJnZVRhcmdldCk7XG59O1xuXG52YXIgYXNzaWduID0gZnVuY3Rpb24gYXNzaWduU2luZ2xlU291cmNlKHRhcmdldCwgc291cmNlKSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHNvdXJjZSkucmVkdWNlKGZ1bmN0aW9uIChhY2MsIGtleSkge1xuICAgICAgICBhY2Nba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHRhcmdldCk7XG59O1xuXG52YXIgZGVjb2RlID0gZnVuY3Rpb24gKHN0ciwgZGVjb2RlciwgY2hhcnNldCkge1xuICAgIHZhciBzdHJXaXRob3V0UGx1cyA9IHN0ci5yZXBsYWNlKC9cXCsvZywgJyAnKTtcbiAgICBpZiAoY2hhcnNldCA9PT0gJ2lzby04ODU5LTEnKSB7XG4gICAgICAgIC8vIHVuZXNjYXBlIG5ldmVyIHRocm93cywgbm8gdHJ5Li4uY2F0Y2ggbmVlZGVkOlxuICAgICAgICByZXR1cm4gc3RyV2l0aG91dFBsdXMucmVwbGFjZSgvJVswLTlhLWZdezJ9L2dpLCB1bmVzY2FwZSk7XG4gICAgfVxuICAgIC8vIHV0Zi04XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChzdHJXaXRob3V0UGx1cyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gc3RyV2l0aG91dFBsdXM7XG4gICAgfVxufTtcblxudmFyIGVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShzdHIsIGRlZmF1bHRFbmNvZGVyLCBjaGFyc2V0KSB7XG4gICAgLy8gVGhpcyBjb2RlIHdhcyBvcmlnaW5hbGx5IHdyaXR0ZW4gYnkgQnJpYW4gV2hpdGUgKG1zY2RleCkgZm9yIHRoZSBpby5qcyBjb3JlIHF1ZXJ5c3RyaW5nIGxpYnJhcnkuXG4gICAgLy8gSXQgaGFzIGJlZW4gYWRhcHRlZCBoZXJlIGZvciBzdHJpY3RlciBhZGhlcmVuY2UgdG8gUkZDIDM5ODZcbiAgICBpZiAoc3RyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gc3RyO1xuICAgIH1cblxuICAgIHZhciBzdHJpbmcgPSBzdHI7XG4gICAgaWYgKHR5cGVvZiBzdHIgPT09ICdzeW1ib2wnKSB7XG4gICAgICAgIHN0cmluZyA9IFN5bWJvbC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChzdHIpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHN0ciAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgc3RyaW5nID0gU3RyaW5nKHN0cik7XG4gICAgfVxuXG4gICAgaWYgKGNoYXJzZXQgPT09ICdpc28tODg1OS0xJykge1xuICAgICAgICByZXR1cm4gZXNjYXBlKHN0cmluZykucmVwbGFjZSgvJXVbMC05YS1mXXs0fS9naSwgZnVuY3Rpb24gKCQwKSB7XG4gICAgICAgICAgICByZXR1cm4gJyUyNiUyMycgKyBwYXJzZUludCgkMC5zbGljZSgyKSwgMTYpICsgJyUzQic7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHZhciBvdXQgPSAnJztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmluZy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgYyA9IHN0cmluZy5jaGFyQ29kZUF0KGkpO1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIGMgPT09IDB4MkQgLy8gLVxuICAgICAgICAgICAgfHwgYyA9PT0gMHgyRSAvLyAuXG4gICAgICAgICAgICB8fCBjID09PSAweDVGIC8vIF9cbiAgICAgICAgICAgIHx8IGMgPT09IDB4N0UgLy8gflxuICAgICAgICAgICAgfHwgKGMgPj0gMHgzMCAmJiBjIDw9IDB4MzkpIC8vIDAtOVxuICAgICAgICAgICAgfHwgKGMgPj0gMHg0MSAmJiBjIDw9IDB4NUEpIC8vIGEtelxuICAgICAgICAgICAgfHwgKGMgPj0gMHg2MSAmJiBjIDw9IDB4N0EpIC8vIEEtWlxuICAgICAgICApIHtcbiAgICAgICAgICAgIG91dCArPSBzdHJpbmcuY2hhckF0KGkpO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYyA8IDB4ODApIHtcbiAgICAgICAgICAgIG91dCA9IG91dCArIGhleFRhYmxlW2NdO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYyA8IDB4ODAwKSB7XG4gICAgICAgICAgICBvdXQgPSBvdXQgKyAoaGV4VGFibGVbMHhDMCB8IChjID4+IDYpXSArIGhleFRhYmxlWzB4ODAgfCAoYyAmIDB4M0YpXSk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjIDwgMHhEODAwIHx8IGMgPj0gMHhFMDAwKSB7XG4gICAgICAgICAgICBvdXQgPSBvdXQgKyAoaGV4VGFibGVbMHhFMCB8IChjID4+IDEyKV0gKyBoZXhUYWJsZVsweDgwIHwgKChjID4+IDYpICYgMHgzRildICsgaGV4VGFibGVbMHg4MCB8IChjICYgMHgzRildKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaSArPSAxO1xuICAgICAgICBjID0gMHgxMDAwMCArICgoKGMgJiAweDNGRikgPDwgMTApIHwgKHN0cmluZy5jaGFyQ29kZUF0KGkpICYgMHgzRkYpKTtcbiAgICAgICAgb3V0ICs9IGhleFRhYmxlWzB4RjAgfCAoYyA+PiAxOCldXG4gICAgICAgICAgICArIGhleFRhYmxlWzB4ODAgfCAoKGMgPj4gMTIpICYgMHgzRildXG4gICAgICAgICAgICArIGhleFRhYmxlWzB4ODAgfCAoKGMgPj4gNikgJiAweDNGKV1cbiAgICAgICAgICAgICsgaGV4VGFibGVbMHg4MCB8IChjICYgMHgzRildO1xuICAgIH1cblxuICAgIHJldHVybiBvdXQ7XG59O1xuXG52YXIgY29tcGFjdCA9IGZ1bmN0aW9uIGNvbXBhY3QodmFsdWUpIHtcbiAgICB2YXIgcXVldWUgPSBbeyBvYmo6IHsgbzogdmFsdWUgfSwgcHJvcDogJ28nIH1dO1xuICAgIHZhciByZWZzID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHF1ZXVlLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBpdGVtID0gcXVldWVbaV07XG4gICAgICAgIHZhciBvYmogPSBpdGVtLm9ialtpdGVtLnByb3BdO1xuXG4gICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqKTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBrZXlzLmxlbmd0aDsgKytqKSB7XG4gICAgICAgICAgICB2YXIga2V5ID0ga2V5c1tqXTtcbiAgICAgICAgICAgIHZhciB2YWwgPSBvYmpba2V5XTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsID09PSAnb2JqZWN0JyAmJiB2YWwgIT09IG51bGwgJiYgcmVmcy5pbmRleE9mKHZhbCkgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgcXVldWUucHVzaCh7IG9iajogb2JqLCBwcm9wOiBrZXkgfSk7XG4gICAgICAgICAgICAgICAgcmVmcy5wdXNoKHZhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb21wYWN0UXVldWUocXVldWUpO1xuXG4gICAgcmV0dXJuIHZhbHVlO1xufTtcblxudmFyIGlzUmVnRXhwID0gZnVuY3Rpb24gaXNSZWdFeHAob2JqKSB7XG4gICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCBSZWdFeHBdJztcbn07XG5cbnZhciBpc0J1ZmZlciA9IGZ1bmN0aW9uIGlzQnVmZmVyKG9iaikge1xuICAgIGlmICghb2JqIHx8IHR5cGVvZiBvYmogIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gISEob2JqLmNvbnN0cnVjdG9yICYmIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlciAmJiBvYmouY29uc3RydWN0b3IuaXNCdWZmZXIob2JqKSk7XG59O1xuXG52YXIgY29tYmluZSA9IGZ1bmN0aW9uIGNvbWJpbmUoYSwgYikge1xuICAgIHJldHVybiBbXS5jb25jYXQoYSwgYik7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBhcnJheVRvT2JqZWN0OiBhcnJheVRvT2JqZWN0LFxuICAgIGFzc2lnbjogYXNzaWduLFxuICAgIGNvbWJpbmU6IGNvbWJpbmUsXG4gICAgY29tcGFjdDogY29tcGFjdCxcbiAgICBkZWNvZGU6IGRlY29kZSxcbiAgICBlbmNvZGU6IGVuY29kZSxcbiAgICBpc0J1ZmZlcjogaXNCdWZmZXIsXG4gICAgaXNSZWdFeHA6IGlzUmVnRXhwLFxuICAgIG1lcmdlOiBtZXJnZVxufTtcbiIsIi8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuQ29weXJpZ2h0IChDKSBNaWNyb3NvZnQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2VcbnRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlXG5MaWNlbnNlIGF0IGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5USElTIENPREUgSVMgUFJPVklERUQgT04gQU4gKkFTIElTKiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXG5LSU5ELCBFSVRIRVIgRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgV0lUSE9VVCBMSU1JVEFUSU9OIEFOWSBJTVBMSUVEXG5XQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgVElUTEUsIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLFxuTUVSQ0hBTlRBQkxJVFkgT1IgTk9OLUlORlJJTkdFTUVOVC5cblxuU2VlIHRoZSBBcGFjaGUgVmVyc2lvbiAyLjAgTGljZW5zZSBmb3Igc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zXG5hbmQgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xudmFyIFJlZmxlY3Q7XG4oZnVuY3Rpb24gKFJlZmxlY3QpIHtcbiAgICAvLyBNZXRhZGF0YSBQcm9wb3NhbFxuICAgIC8vIGh0dHBzOi8vcmJ1Y2t0b24uZ2l0aHViLmlvL3JlZmxlY3QtbWV0YWRhdGEvXG4gICAgKGZ1bmN0aW9uIChmYWN0b3J5KSB7XG4gICAgICAgIHZhciByb290ID0gdHlwZW9mIGdsb2JhbCA9PT0gXCJvYmplY3RcIiA/IGdsb2JhbCA6XG4gICAgICAgICAgICB0eXBlb2Ygc2VsZiA9PT0gXCJvYmplY3RcIiA/IHNlbGYgOlxuICAgICAgICAgICAgICAgIHR5cGVvZiB0aGlzID09PSBcIm9iamVjdFwiID8gdGhpcyA6XG4gICAgICAgICAgICAgICAgICAgIEZ1bmN0aW9uKFwicmV0dXJuIHRoaXM7XCIpKCk7XG4gICAgICAgIHZhciBleHBvcnRlciA9IG1ha2VFeHBvcnRlcihSZWZsZWN0KTtcbiAgICAgICAgaWYgKHR5cGVvZiByb290LlJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIHJvb3QuUmVmbGVjdCA9IFJlZmxlY3Q7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBleHBvcnRlciA9IG1ha2VFeHBvcnRlcihyb290LlJlZmxlY3QsIGV4cG9ydGVyKTtcbiAgICAgICAgfVxuICAgICAgICBmYWN0b3J5KGV4cG9ydGVyKTtcbiAgICAgICAgZnVuY3Rpb24gbWFrZUV4cG9ydGVyKHRhcmdldCwgcHJldmlvdXMpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdGFyZ2V0W2tleV0gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHsgY29uZmlndXJhYmxlOiB0cnVlLCB3cml0YWJsZTogdHJ1ZSwgdmFsdWU6IHZhbHVlIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocHJldmlvdXMpXG4gICAgICAgICAgICAgICAgICAgIHByZXZpb3VzKGtleSwgdmFsdWUpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH0pKGZ1bmN0aW9uIChleHBvcnRlcikge1xuICAgICAgICB2YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbiAgICAgICAgLy8gZmVhdHVyZSB0ZXN0IGZvciBTeW1ib2wgc3VwcG9ydFxuICAgICAgICB2YXIgc3VwcG9ydHNTeW1ib2wgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCI7XG4gICAgICAgIHZhciB0b1ByaW1pdGl2ZVN5bWJvbCA9IHN1cHBvcnRzU3ltYm9sICYmIHR5cGVvZiBTeW1ib2wudG9QcmltaXRpdmUgIT09IFwidW5kZWZpbmVkXCIgPyBTeW1ib2wudG9QcmltaXRpdmUgOiBcIkBAdG9QcmltaXRpdmVcIjtcbiAgICAgICAgdmFyIGl0ZXJhdG9yU3ltYm9sID0gc3VwcG9ydHNTeW1ib2wgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciAhPT0gXCJ1bmRlZmluZWRcIiA/IFN5bWJvbC5pdGVyYXRvciA6IFwiQEBpdGVyYXRvclwiO1xuICAgICAgICB2YXIgc3VwcG9ydHNDcmVhdGUgPSB0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gXCJmdW5jdGlvblwiOyAvLyBmZWF0dXJlIHRlc3QgZm9yIE9iamVjdC5jcmVhdGUgc3VwcG9ydFxuICAgICAgICB2YXIgc3VwcG9ydHNQcm90byA9IHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXk7IC8vIGZlYXR1cmUgdGVzdCBmb3IgX19wcm90b19fIHN1cHBvcnRcbiAgICAgICAgdmFyIGRvd25MZXZlbCA9ICFzdXBwb3J0c0NyZWF0ZSAmJiAhc3VwcG9ydHNQcm90bztcbiAgICAgICAgdmFyIEhhc2hNYXAgPSB7XG4gICAgICAgICAgICAvLyBjcmVhdGUgYW4gb2JqZWN0IGluIGRpY3Rpb25hcnkgbW9kZSAoYS5rLmEuIFwic2xvd1wiIG1vZGUgaW4gdjgpXG4gICAgICAgICAgICBjcmVhdGU6IHN1cHBvcnRzQ3JlYXRlXG4gICAgICAgICAgICAgICAgPyBmdW5jdGlvbiAoKSB7IHJldHVybiBNYWtlRGljdGlvbmFyeShPYmplY3QuY3JlYXRlKG51bGwpKTsgfVxuICAgICAgICAgICAgICAgIDogc3VwcG9ydHNQcm90b1xuICAgICAgICAgICAgICAgICAgICA/IGZ1bmN0aW9uICgpIHsgcmV0dXJuIE1ha2VEaWN0aW9uYXJ5KHsgX19wcm90b19fOiBudWxsIH0pOyB9XG4gICAgICAgICAgICAgICAgICAgIDogZnVuY3Rpb24gKCkgeyByZXR1cm4gTWFrZURpY3Rpb25hcnkoe30pOyB9LFxuICAgICAgICAgICAgaGFzOiBkb3duTGV2ZWxcbiAgICAgICAgICAgICAgICA/IGZ1bmN0aW9uIChtYXAsIGtleSkgeyByZXR1cm4gaGFzT3duLmNhbGwobWFwLCBrZXkpOyB9XG4gICAgICAgICAgICAgICAgOiBmdW5jdGlvbiAobWFwLCBrZXkpIHsgcmV0dXJuIGtleSBpbiBtYXA7IH0sXG4gICAgICAgICAgICBnZXQ6IGRvd25MZXZlbFxuICAgICAgICAgICAgICAgID8gZnVuY3Rpb24gKG1hcCwga2V5KSB7IHJldHVybiBoYXNPd24uY2FsbChtYXAsIGtleSkgPyBtYXBba2V5XSA6IHVuZGVmaW5lZDsgfVxuICAgICAgICAgICAgICAgIDogZnVuY3Rpb24gKG1hcCwga2V5KSB7IHJldHVybiBtYXBba2V5XTsgfSxcbiAgICAgICAgfTtcbiAgICAgICAgLy8gTG9hZCBnbG9iYWwgb3Igc2hpbSB2ZXJzaW9ucyBvZiBNYXAsIFNldCwgYW5kIFdlYWtNYXBcbiAgICAgICAgdmFyIGZ1bmN0aW9uUHJvdG90eXBlID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKEZ1bmN0aW9uKTtcbiAgICAgICAgdmFyIHVzZVBvbHlmaWxsID0gdHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgcHJvY2Vzcy5lbnYgJiYgcHJvY2Vzcy5lbnZbXCJSRUZMRUNUX01FVEFEQVRBX1VTRV9NQVBfUE9MWUZJTExcIl0gPT09IFwidHJ1ZVwiO1xuICAgICAgICB2YXIgX01hcCA9ICF1c2VQb2x5ZmlsbCAmJiB0eXBlb2YgTWFwID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIE1hcC5wcm90b3R5cGUuZW50cmllcyA9PT0gXCJmdW5jdGlvblwiID8gTWFwIDogQ3JlYXRlTWFwUG9seWZpbGwoKTtcbiAgICAgICAgdmFyIF9TZXQgPSAhdXNlUG9seWZpbGwgJiYgdHlwZW9mIFNldCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTZXQucHJvdG90eXBlLmVudHJpZXMgPT09IFwiZnVuY3Rpb25cIiA/IFNldCA6IENyZWF0ZVNldFBvbHlmaWxsKCk7XG4gICAgICAgIHZhciBfV2Vha01hcCA9ICF1c2VQb2x5ZmlsbCAmJiB0eXBlb2YgV2Vha01hcCA9PT0gXCJmdW5jdGlvblwiID8gV2Vha01hcCA6IENyZWF0ZVdlYWtNYXBQb2x5ZmlsbCgpO1xuICAgICAgICAvLyBbW01ldGFkYXRhXV0gaW50ZXJuYWwgc2xvdFxuICAgICAgICAvLyBodHRwczovL3JidWNrdG9uLmdpdGh1Yi5pby9yZWZsZWN0LW1ldGFkYXRhLyNvcmRpbmFyeS1vYmplY3QtaW50ZXJuYWwtbWV0aG9kcy1hbmQtaW50ZXJuYWwtc2xvdHNcbiAgICAgICAgdmFyIE1ldGFkYXRhID0gbmV3IF9XZWFrTWFwKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBcHBsaWVzIGEgc2V0IG9mIGRlY29yYXRvcnMgdG8gYSBwcm9wZXJ0eSBvZiBhIHRhcmdldCBvYmplY3QuXG4gICAgICAgICAqIEBwYXJhbSBkZWNvcmF0b3JzIEFuIGFycmF5IG9mIGRlY29yYXRvcnMuXG4gICAgICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldCBvYmplY3QuXG4gICAgICAgICAqIEBwYXJhbSBwcm9wZXJ0eUtleSAoT3B0aW9uYWwpIFRoZSBwcm9wZXJ0eSBrZXkgdG8gZGVjb3JhdGUuXG4gICAgICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzIChPcHRpb25hbCkgVGhlIHByb3BlcnR5IGRlc2NyaXB0b3IgZm9yIHRoZSB0YXJnZXQga2V5LlxuICAgICAgICAgKiBAcmVtYXJrcyBEZWNvcmF0b3JzIGFyZSBhcHBsaWVkIGluIHJldmVyc2Ugb3JkZXIuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eSBkZWNsYXJhdGlvbnMgYXJlIG5vdCBwYXJ0IG9mIEVTNiwgdGhvdWdoIHRoZXkgYXJlIHZhbGlkIGluIFR5cGVTY3JpcHQ6XG4gICAgICAgICAqICAgICAgICAgLy8gc3RhdGljIHN0YXRpY1Byb3BlcnR5O1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5O1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgICAgIGNvbnN0cnVjdG9yKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIHN0YXRpYyBzdGF0aWNNZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgbWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gY29uc3RydWN0b3JcbiAgICAgICAgICogICAgIEV4YW1wbGUgPSBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnNBcnJheSwgRXhhbXBsZSk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnNBcnJheSwgRXhhbXBsZSwgXCJzdGF0aWNQcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnNBcnJheSwgRXhhbXBsZS5wcm90b3R5cGUsIFwicHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEV4YW1wbGUsIFwic3RhdGljTWV0aG9kXCIsXG4gICAgICAgICAqICAgICAgICAgUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzQXJyYXksIEV4YW1wbGUsIFwic3RhdGljTWV0aG9kXCIsXG4gICAgICAgICAqICAgICAgICAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoRXhhbXBsZSwgXCJzdGF0aWNNZXRob2RcIikpKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEV4YW1wbGUucHJvdG90eXBlLCBcIm1ldGhvZFwiLFxuICAgICAgICAgKiAgICAgICAgIFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9yc0FycmF5LCBFeGFtcGxlLnByb3RvdHlwZSwgXCJtZXRob2RcIixcbiAgICAgICAgICogICAgICAgICAgICAgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihFeGFtcGxlLnByb3RvdHlwZSwgXCJtZXRob2RcIikpKTtcbiAgICAgICAgICpcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGRlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwgcHJvcGVydHlLZXksIGF0dHJpYnV0ZXMpIHtcbiAgICAgICAgICAgIGlmICghSXNVbmRlZmluZWQocHJvcGVydHlLZXkpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFJc0FycmF5KGRlY29yYXRvcnMpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgaWYgKCFJc09iamVjdCh0YXJnZXQpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgaWYgKCFJc09iamVjdChhdHRyaWJ1dGVzKSAmJiAhSXNVbmRlZmluZWQoYXR0cmlidXRlcykgJiYgIUlzTnVsbChhdHRyaWJ1dGVzKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIGlmIChJc051bGwoYXR0cmlidXRlcykpXG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgcHJvcGVydHlLZXkgPSBUb1Byb3BlcnR5S2V5KHByb3BlcnR5S2V5KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gRGVjb3JhdGVQcm9wZXJ0eShkZWNvcmF0b3JzLCB0YXJnZXQsIHByb3BlcnR5S2V5LCBhdHRyaWJ1dGVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICghSXNBcnJheShkZWNvcmF0b3JzKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIGlmICghSXNDb25zdHJ1Y3Rvcih0YXJnZXQpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIERlY29yYXRlQ29uc3RydWN0b3IoZGVjb3JhdG9ycywgdGFyZ2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBleHBvcnRlcihcImRlY29yYXRlXCIsIGRlY29yYXRlKTtcbiAgICAgICAgLy8gNC4xLjIgUmVmbGVjdC5tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSlcbiAgICAgICAgLy8gaHR0cHM6Ly9yYnVja3Rvbi5naXRodWIuaW8vcmVmbGVjdC1tZXRhZGF0YS8jcmVmbGVjdC5tZXRhZGF0YVxuICAgICAgICAvKipcbiAgICAgICAgICogQSBkZWZhdWx0IG1ldGFkYXRhIGRlY29yYXRvciBmYWN0b3J5IHRoYXQgY2FuIGJlIHVzZWQgb24gYSBjbGFzcywgY2xhc3MgbWVtYmVyLCBvciBwYXJhbWV0ZXIuXG4gICAgICAgICAqIEBwYXJhbSBtZXRhZGF0YUtleSBUaGUga2V5IGZvciB0aGUgbWV0YWRhdGEgZW50cnkuXG4gICAgICAgICAqIEBwYXJhbSBtZXRhZGF0YVZhbHVlIFRoZSB2YWx1ZSBmb3IgdGhlIG1ldGFkYXRhIGVudHJ5LlxuICAgICAgICAgKiBAcmV0dXJucyBBIGRlY29yYXRvciBmdW5jdGlvbi5cbiAgICAgICAgICogQHJlbWFya3NcbiAgICAgICAgICogSWYgYG1ldGFkYXRhS2V5YCBpcyBhbHJlYWR5IGRlZmluZWQgZm9yIHRoZSB0YXJnZXQgYW5kIHRhcmdldCBrZXksIHRoZVxuICAgICAgICAgKiBtZXRhZGF0YVZhbHVlIGZvciB0aGF0IGtleSB3aWxsIGJlIG92ZXJ3cml0dGVuLlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gY29uc3RydWN0b3JcbiAgICAgICAgICogICAgIEBSZWZsZWN0Lm1ldGFkYXRhKGtleSwgdmFsdWUpXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgIH1cbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBjb25zdHJ1Y3RvciwgVHlwZVNjcmlwdCBvbmx5KVxuICAgICAgICAgKiAgICAgY2xhc3MgRXhhbXBsZSB7XG4gICAgICAgICAqICAgICAgICAgQFJlZmxlY3QubWV0YWRhdGEoa2V5LCB2YWx1ZSlcbiAgICAgICAgICogICAgICAgICBzdGF0aWMgc3RhdGljUHJvcGVydHk7XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gcHJvdG90eXBlLCBUeXBlU2NyaXB0IG9ubHkpXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgICAgICBAUmVmbGVjdC5tZXRhZGF0YShrZXksIHZhbHVlKVxuICAgICAgICAgKiAgICAgICAgIHByb3BlcnR5O1xuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIGNsYXNzIEV4YW1wbGUge1xuICAgICAgICAgKiAgICAgICAgIEBSZWZsZWN0Lm1ldGFkYXRhKGtleSwgdmFsdWUpXG4gICAgICAgICAqICAgICAgICAgc3RhdGljIHN0YXRpY01ldGhvZCgpIHsgfVxuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgICAgICBAUmVmbGVjdC5tZXRhZGF0YShrZXksIHZhbHVlKVxuICAgICAgICAgKiAgICAgICAgIG1ldGhvZCgpIHsgfVxuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gbWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcbiAgICAgICAgICAgIGZ1bmN0aW9uIGRlY29yYXRvcih0YXJnZXQsIHByb3BlcnR5S2V5KSB7XG4gICAgICAgICAgICAgICAgaWYgKCFJc09iamVjdCh0YXJnZXQpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgaWYgKCFJc1VuZGVmaW5lZChwcm9wZXJ0eUtleSkgJiYgIUlzUHJvcGVydHlLZXkocHJvcGVydHlLZXkpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgT3JkaW5hcnlEZWZpbmVPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSwgdGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZGVjb3JhdG9yO1xuICAgICAgICB9XG4gICAgICAgIGV4cG9ydGVyKFwibWV0YWRhdGFcIiwgbWV0YWRhdGEpO1xuICAgICAgICAvKipcbiAgICAgICAgICogRGVmaW5lIGEgdW5pcXVlIG1ldGFkYXRhIGVudHJ5IG9uIHRoZSB0YXJnZXQuXG4gICAgICAgICAqIEBwYXJhbSBtZXRhZGF0YUtleSBBIGtleSB1c2VkIHRvIHN0b3JlIGFuZCByZXRyaWV2ZSBtZXRhZGF0YS5cbiAgICAgICAgICogQHBhcmFtIG1ldGFkYXRhVmFsdWUgQSB2YWx1ZSB0aGF0IGNvbnRhaW5zIGF0dGFjaGVkIG1ldGFkYXRhLlxuICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQgb2JqZWN0IG9uIHdoaWNoIHRvIGRlZmluZSBtZXRhZGF0YS5cbiAgICAgICAgICogQHBhcmFtIHByb3BlcnR5S2V5IChPcHRpb25hbCkgVGhlIHByb3BlcnR5IGtleSBmb3IgdGhlIHRhcmdldC5cbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIGNsYXNzIEV4YW1wbGUge1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5IGRlY2xhcmF0aW9ucyBhcmUgbm90IHBhcnQgb2YgRVM2LCB0aG91Z2ggdGhleSBhcmUgdmFsaWQgaW4gVHlwZVNjcmlwdDpcbiAgICAgICAgICogICAgICAgICAvLyBzdGF0aWMgc3RhdGljUHJvcGVydHk7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAgICAgY29uc3RydWN0b3IocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgc3RhdGljIHN0YXRpY01ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgICAgICBtZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBjb25zdHJ1Y3RvclxuICAgICAgICAgKiAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIG9wdGlvbnMsIEV4YW1wbGUpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIG9wdGlvbnMsIEV4YW1wbGUsIFwic3RhdGljUHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIG9wdGlvbnMsIEV4YW1wbGUucHJvdG90eXBlLCBcInByb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBvcHRpb25zLCBFeGFtcGxlLCBcInN0YXRpY01ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIG9wdGlvbnMsIEV4YW1wbGUucHJvdG90eXBlLCBcIm1ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIGRlY29yYXRvciBmYWN0b3J5IGFzIG1ldGFkYXRhLXByb2R1Y2luZyBhbm5vdGF0aW9uLlxuICAgICAgICAgKiAgICAgZnVuY3Rpb24gTXlBbm5vdGF0aW9uKG9wdGlvbnMpOiBEZWNvcmF0b3Ige1xuICAgICAgICAgKiAgICAgICAgIHJldHVybiAodGFyZ2V0LCBrZXk/KSA9PiBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgb3B0aW9ucywgdGFyZ2V0LCBrZXkpO1xuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gZGVmaW5lTWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUsIHRhcmdldCwgcHJvcGVydHlLZXkpIHtcbiAgICAgICAgICAgIGlmICghSXNPYmplY3QodGFyZ2V0KSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICBpZiAoIUlzVW5kZWZpbmVkKHByb3BlcnR5S2V5KSlcbiAgICAgICAgICAgICAgICBwcm9wZXJ0eUtleSA9IFRvUHJvcGVydHlLZXkocHJvcGVydHlLZXkpO1xuICAgICAgICAgICAgcmV0dXJuIE9yZGluYXJ5RGVmaW5lT3duTWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUsIHRhcmdldCwgcHJvcGVydHlLZXkpO1xuICAgICAgICB9XG4gICAgICAgIGV4cG9ydGVyKFwiZGVmaW5lTWV0YWRhdGFcIiwgZGVmaW5lTWV0YWRhdGEpO1xuICAgICAgICAvKipcbiAgICAgICAgICogR2V0cyBhIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciB0aGUgdGFyZ2V0IG9iamVjdCBvciBpdHMgcHJvdG90eXBlIGNoYWluIGhhcyB0aGUgcHJvdmlkZWQgbWV0YWRhdGEga2V5IGRlZmluZWQuXG4gICAgICAgICAqIEBwYXJhbSBtZXRhZGF0YUtleSBBIGtleSB1c2VkIHRvIHN0b3JlIGFuZCByZXRyaWV2ZSBtZXRhZGF0YS5cbiAgICAgICAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0IG9iamVjdCBvbiB3aGljaCB0aGUgbWV0YWRhdGEgaXMgZGVmaW5lZC5cbiAgICAgICAgICogQHBhcmFtIHByb3BlcnR5S2V5IChPcHRpb25hbCkgVGhlIHByb3BlcnR5IGtleSBmb3IgdGhlIHRhcmdldC5cbiAgICAgICAgICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBtZXRhZGF0YSBrZXkgd2FzIGRlZmluZWQgb24gdGhlIHRhcmdldCBvYmplY3Qgb3IgaXRzIHByb3RvdHlwZSBjaGFpbjsgb3RoZXJ3aXNlLCBgZmFsc2VgLlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgY2xhc3MgRXhhbXBsZSB7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHkgZGVjbGFyYXRpb25zIGFyZSBub3QgcGFydCBvZiBFUzYsIHRob3VnaCB0aGV5IGFyZSB2YWxpZCBpbiBUeXBlU2NyaXB0OlxuICAgICAgICAgKiAgICAgICAgIC8vIHN0YXRpYyBzdGF0aWNQcm9wZXJ0eTtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgICAgICBjb25zdHJ1Y3RvcihwKSB7IH1cbiAgICAgICAgICogICAgICAgICBzdGF0aWMgc3RhdGljTWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIG1ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgIH1cbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIGNvbnN0cnVjdG9yXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0Lmhhc01ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZSk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0Lmhhc01ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZSwgXCJzdGF0aWNQcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0Lmhhc01ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZS5wcm90b3R5cGUsIFwicHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5oYXNNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUsIFwic3RhdGljTWV0aG9kXCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0Lmhhc01ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZS5wcm90b3R5cGUsIFwibWV0aG9kXCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gaGFzTWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCwgcHJvcGVydHlLZXkpIHtcbiAgICAgICAgICAgIGlmICghSXNPYmplY3QodGFyZ2V0KSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICBpZiAoIUlzVW5kZWZpbmVkKHByb3BlcnR5S2V5KSlcbiAgICAgICAgICAgICAgICBwcm9wZXJ0eUtleSA9IFRvUHJvcGVydHlLZXkocHJvcGVydHlLZXkpO1xuICAgICAgICAgICAgcmV0dXJuIE9yZGluYXJ5SGFzTWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCwgcHJvcGVydHlLZXkpO1xuICAgICAgICB9XG4gICAgICAgIGV4cG9ydGVyKFwiaGFzTWV0YWRhdGFcIiwgaGFzTWV0YWRhdGEpO1xuICAgICAgICAvKipcbiAgICAgICAgICogR2V0cyBhIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciB0aGUgdGFyZ2V0IG9iamVjdCBoYXMgdGhlIHByb3ZpZGVkIG1ldGFkYXRhIGtleSBkZWZpbmVkLlxuICAgICAgICAgKiBAcGFyYW0gbWV0YWRhdGFLZXkgQSBrZXkgdXNlZCB0byBzdG9yZSBhbmQgcmV0cmlldmUgbWV0YWRhdGEuXG4gICAgICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldCBvYmplY3Qgb24gd2hpY2ggdGhlIG1ldGFkYXRhIGlzIGRlZmluZWQuXG4gICAgICAgICAqIEBwYXJhbSBwcm9wZXJ0eUtleSAoT3B0aW9uYWwpIFRoZSBwcm9wZXJ0eSBrZXkgZm9yIHRoZSB0YXJnZXQuXG4gICAgICAgICAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgbWV0YWRhdGEga2V5IHdhcyBkZWZpbmVkIG9uIHRoZSB0YXJnZXQgb2JqZWN0OyBvdGhlcndpc2UsIGBmYWxzZWAuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eSBkZWNsYXJhdGlvbnMgYXJlIG5vdCBwYXJ0IG9mIEVTNiwgdGhvdWdoIHRoZXkgYXJlIHZhbGlkIGluIFR5cGVTY3JpcHQ6XG4gICAgICAgICAqICAgICAgICAgLy8gc3RhdGljIHN0YXRpY1Byb3BlcnR5O1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5O1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgICAgIGNvbnN0cnVjdG9yKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIHN0YXRpYyBzdGF0aWNNZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgbWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gY29uc3RydWN0b3JcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuaGFzT3duTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuaGFzT3duTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLCBcInN0YXRpY1Byb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuaGFzT3duTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLnByb3RvdHlwZSwgXCJwcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0Lmhhc093bk1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZSwgXCJzdGF0aWNNZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuaGFzT3duTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLnByb3RvdHlwZSwgXCJtZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBoYXNPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgdGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgICAgICAgICAgaWYgKCFJc09iamVjdCh0YXJnZXQpKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgIGlmICghSXNVbmRlZmluZWQocHJvcGVydHlLZXkpKVxuICAgICAgICAgICAgICAgIHByb3BlcnR5S2V5ID0gVG9Qcm9wZXJ0eUtleShwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICByZXR1cm4gT3JkaW5hcnlIYXNPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgdGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4gICAgICAgIH1cbiAgICAgICAgZXhwb3J0ZXIoXCJoYXNPd25NZXRhZGF0YVwiLCBoYXNPd25NZXRhZGF0YSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZXRzIHRoZSBtZXRhZGF0YSB2YWx1ZSBmb3IgdGhlIHByb3ZpZGVkIG1ldGFkYXRhIGtleSBvbiB0aGUgdGFyZ2V0IG9iamVjdCBvciBpdHMgcHJvdG90eXBlIGNoYWluLlxuICAgICAgICAgKiBAcGFyYW0gbWV0YWRhdGFLZXkgQSBrZXkgdXNlZCB0byBzdG9yZSBhbmQgcmV0cmlldmUgbWV0YWRhdGEuXG4gICAgICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldCBvYmplY3Qgb24gd2hpY2ggdGhlIG1ldGFkYXRhIGlzIGRlZmluZWQuXG4gICAgICAgICAqIEBwYXJhbSBwcm9wZXJ0eUtleSAoT3B0aW9uYWwpIFRoZSBwcm9wZXJ0eSBrZXkgZm9yIHRoZSB0YXJnZXQuXG4gICAgICAgICAqIEByZXR1cm5zIFRoZSBtZXRhZGF0YSB2YWx1ZSBmb3IgdGhlIG1ldGFkYXRhIGtleSBpZiBmb3VuZDsgb3RoZXJ3aXNlLCBgdW5kZWZpbmVkYC5cbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIGNsYXNzIEV4YW1wbGUge1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5IGRlY2xhcmF0aW9ucyBhcmUgbm90IHBhcnQgb2YgRVM2LCB0aG91Z2ggdGhleSBhcmUgdmFsaWQgaW4gVHlwZVNjcmlwdDpcbiAgICAgICAgICogICAgICAgICAvLyBzdGF0aWMgc3RhdGljUHJvcGVydHk7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAgICAgY29uc3RydWN0b3IocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgc3RhdGljIHN0YXRpY01ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgICAgICBtZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBjb25zdHJ1Y3RvclxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUsIFwic3RhdGljUHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUucHJvdG90eXBlLCBcInByb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLCBcInN0YXRpY01ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUucHJvdG90eXBlLCBcIm1ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGdldE1ldGFkYXRhKG1ldGFkYXRhS2V5LCB0YXJnZXQsIHByb3BlcnR5S2V5KSB7XG4gICAgICAgICAgICBpZiAoIUlzT2JqZWN0KHRhcmdldCkpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgaWYgKCFJc1VuZGVmaW5lZChwcm9wZXJ0eUtleSkpXG4gICAgICAgICAgICAgICAgcHJvcGVydHlLZXkgPSBUb1Byb3BlcnR5S2V5KHByb3BlcnR5S2V5KTtcbiAgICAgICAgICAgIHJldHVybiBPcmRpbmFyeUdldE1ldGFkYXRhKG1ldGFkYXRhS2V5LCB0YXJnZXQsIHByb3BlcnR5S2V5KTtcbiAgICAgICAgfVxuICAgICAgICBleHBvcnRlcihcImdldE1ldGFkYXRhXCIsIGdldE1ldGFkYXRhKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldHMgdGhlIG1ldGFkYXRhIHZhbHVlIGZvciB0aGUgcHJvdmlkZWQgbWV0YWRhdGEga2V5IG9uIHRoZSB0YXJnZXQgb2JqZWN0LlxuICAgICAgICAgKiBAcGFyYW0gbWV0YWRhdGFLZXkgQSBrZXkgdXNlZCB0byBzdG9yZSBhbmQgcmV0cmlldmUgbWV0YWRhdGEuXG4gICAgICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldCBvYmplY3Qgb24gd2hpY2ggdGhlIG1ldGFkYXRhIGlzIGRlZmluZWQuXG4gICAgICAgICAqIEBwYXJhbSBwcm9wZXJ0eUtleSAoT3B0aW9uYWwpIFRoZSBwcm9wZXJ0eSBrZXkgZm9yIHRoZSB0YXJnZXQuXG4gICAgICAgICAqIEByZXR1cm5zIFRoZSBtZXRhZGF0YSB2YWx1ZSBmb3IgdGhlIG1ldGFkYXRhIGtleSBpZiBmb3VuZDsgb3RoZXJ3aXNlLCBgdW5kZWZpbmVkYC5cbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIGNsYXNzIEV4YW1wbGUge1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5IGRlY2xhcmF0aW9ucyBhcmUgbm90IHBhcnQgb2YgRVM2LCB0aG91Z2ggdGhleSBhcmUgdmFsaWQgaW4gVHlwZVNjcmlwdDpcbiAgICAgICAgICogICAgICAgICAvLyBzdGF0aWMgc3RhdGljUHJvcGVydHk7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAgICAgY29uc3RydWN0b3IocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgc3RhdGljIHN0YXRpY01ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgICAgICBtZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBjb25zdHJ1Y3RvclxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRPd25NZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRPd25NZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUsIFwic3RhdGljUHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRPd25NZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUucHJvdG90eXBlLCBcInByb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0T3duTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLCBcInN0YXRpY01ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRPd25NZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUucHJvdG90eXBlLCBcIm1ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGdldE93bk1ldGFkYXRhKG1ldGFkYXRhS2V5LCB0YXJnZXQsIHByb3BlcnR5S2V5KSB7XG4gICAgICAgICAgICBpZiAoIUlzT2JqZWN0KHRhcmdldCkpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgaWYgKCFJc1VuZGVmaW5lZChwcm9wZXJ0eUtleSkpXG4gICAgICAgICAgICAgICAgcHJvcGVydHlLZXkgPSBUb1Byb3BlcnR5S2V5KHByb3BlcnR5S2V5KTtcbiAgICAgICAgICAgIHJldHVybiBPcmRpbmFyeUdldE93bk1ldGFkYXRhKG1ldGFkYXRhS2V5LCB0YXJnZXQsIHByb3BlcnR5S2V5KTtcbiAgICAgICAgfVxuICAgICAgICBleHBvcnRlcihcImdldE93bk1ldGFkYXRhXCIsIGdldE93bk1ldGFkYXRhKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldHMgdGhlIG1ldGFkYXRhIGtleXMgZGVmaW5lZCBvbiB0aGUgdGFyZ2V0IG9iamVjdCBvciBpdHMgcHJvdG90eXBlIGNoYWluLlxuICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQgb2JqZWN0IG9uIHdoaWNoIHRoZSBtZXRhZGF0YSBpcyBkZWZpbmVkLlxuICAgICAgICAgKiBAcGFyYW0gcHJvcGVydHlLZXkgKE9wdGlvbmFsKSBUaGUgcHJvcGVydHkga2V5IGZvciB0aGUgdGFyZ2V0LlxuICAgICAgICAgKiBAcmV0dXJucyBBbiBhcnJheSBvZiB1bmlxdWUgbWV0YWRhdGEga2V5cy5cbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIGNsYXNzIEV4YW1wbGUge1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5IGRlY2xhcmF0aW9ucyBhcmUgbm90IHBhcnQgb2YgRVM2LCB0aG91Z2ggdGhleSBhcmUgdmFsaWQgaW4gVHlwZVNjcmlwdDpcbiAgICAgICAgICogICAgICAgICAvLyBzdGF0aWMgc3RhdGljUHJvcGVydHk7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAgICAgY29uc3RydWN0b3IocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgc3RhdGljIHN0YXRpY01ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgICAgICBtZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBjb25zdHJ1Y3RvclxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRNZXRhZGF0YUtleXMoRXhhbXBsZSk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE1ldGFkYXRhS2V5cyhFeGFtcGxlLCBcInN0YXRpY1Byb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0TWV0YWRhdGFLZXlzKEV4YW1wbGUucHJvdG90eXBlLCBcInByb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0TWV0YWRhdGFLZXlzKEV4YW1wbGUsIFwic3RhdGljTWV0aG9kXCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE1ldGFkYXRhS2V5cyhFeGFtcGxlLnByb3RvdHlwZSwgXCJtZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBnZXRNZXRhZGF0YUtleXModGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgICAgICAgICAgaWYgKCFJc09iamVjdCh0YXJnZXQpKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgIGlmICghSXNVbmRlZmluZWQocHJvcGVydHlLZXkpKVxuICAgICAgICAgICAgICAgIHByb3BlcnR5S2V5ID0gVG9Qcm9wZXJ0eUtleShwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICByZXR1cm4gT3JkaW5hcnlNZXRhZGF0YUtleXModGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4gICAgICAgIH1cbiAgICAgICAgZXhwb3J0ZXIoXCJnZXRNZXRhZGF0YUtleXNcIiwgZ2V0TWV0YWRhdGFLZXlzKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldHMgdGhlIHVuaXF1ZSBtZXRhZGF0YSBrZXlzIGRlZmluZWQgb24gdGhlIHRhcmdldCBvYmplY3QuXG4gICAgICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldCBvYmplY3Qgb24gd2hpY2ggdGhlIG1ldGFkYXRhIGlzIGRlZmluZWQuXG4gICAgICAgICAqIEBwYXJhbSBwcm9wZXJ0eUtleSAoT3B0aW9uYWwpIFRoZSBwcm9wZXJ0eSBrZXkgZm9yIHRoZSB0YXJnZXQuXG4gICAgICAgICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIHVuaXF1ZSBtZXRhZGF0YSBrZXlzLlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgY2xhc3MgRXhhbXBsZSB7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHkgZGVjbGFyYXRpb25zIGFyZSBub3QgcGFydCBvZiBFUzYsIHRob3VnaCB0aGV5IGFyZSB2YWxpZCBpbiBUeXBlU2NyaXB0OlxuICAgICAgICAgKiAgICAgICAgIC8vIHN0YXRpYyBzdGF0aWNQcm9wZXJ0eTtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgICAgICBjb25zdHJ1Y3RvcihwKSB7IH1cbiAgICAgICAgICogICAgICAgICBzdGF0aWMgc3RhdGljTWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIG1ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgIH1cbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIGNvbnN0cnVjdG9yXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE93bk1ldGFkYXRhS2V5cyhFeGFtcGxlKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0T3duTWV0YWRhdGFLZXlzKEV4YW1wbGUsIFwic3RhdGljUHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRPd25NZXRhZGF0YUtleXMoRXhhbXBsZS5wcm90b3R5cGUsIFwicHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRPd25NZXRhZGF0YUtleXMoRXhhbXBsZSwgXCJzdGF0aWNNZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0T3duTWV0YWRhdGFLZXlzKEV4YW1wbGUucHJvdG90eXBlLCBcIm1ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGdldE93bk1ldGFkYXRhS2V5cyh0YXJnZXQsIHByb3BlcnR5S2V5KSB7XG4gICAgICAgICAgICBpZiAoIUlzT2JqZWN0KHRhcmdldCkpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgaWYgKCFJc1VuZGVmaW5lZChwcm9wZXJ0eUtleSkpXG4gICAgICAgICAgICAgICAgcHJvcGVydHlLZXkgPSBUb1Byb3BlcnR5S2V5KHByb3BlcnR5S2V5KTtcbiAgICAgICAgICAgIHJldHVybiBPcmRpbmFyeU93bk1ldGFkYXRhS2V5cyh0YXJnZXQsIHByb3BlcnR5S2V5KTtcbiAgICAgICAgfVxuICAgICAgICBleHBvcnRlcihcImdldE93bk1ldGFkYXRhS2V5c1wiLCBnZXRPd25NZXRhZGF0YUtleXMpO1xuICAgICAgICAvKipcbiAgICAgICAgICogRGVsZXRlcyB0aGUgbWV0YWRhdGEgZW50cnkgZnJvbSB0aGUgdGFyZ2V0IG9iamVjdCB3aXRoIHRoZSBwcm92aWRlZCBrZXkuXG4gICAgICAgICAqIEBwYXJhbSBtZXRhZGF0YUtleSBBIGtleSB1c2VkIHRvIHN0b3JlIGFuZCByZXRyaWV2ZSBtZXRhZGF0YS5cbiAgICAgICAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0IG9iamVjdCBvbiB3aGljaCB0aGUgbWV0YWRhdGEgaXMgZGVmaW5lZC5cbiAgICAgICAgICogQHBhcmFtIHByb3BlcnR5S2V5IChPcHRpb25hbCkgVGhlIHByb3BlcnR5IGtleSBmb3IgdGhlIHRhcmdldC5cbiAgICAgICAgICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBtZXRhZGF0YSBlbnRyeSB3YXMgZm91bmQgYW5kIGRlbGV0ZWQ7IG90aGVyd2lzZSwgZmFsc2UuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eSBkZWNsYXJhdGlvbnMgYXJlIG5vdCBwYXJ0IG9mIEVTNiwgdGhvdWdoIHRoZXkgYXJlIHZhbGlkIGluIFR5cGVTY3JpcHQ6XG4gICAgICAgICAqICAgICAgICAgLy8gc3RhdGljIHN0YXRpY1Byb3BlcnR5O1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5O1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgICAgIGNvbnN0cnVjdG9yKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIHN0YXRpYyBzdGF0aWNNZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgbWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gY29uc3RydWN0b3JcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZGVsZXRlTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZGVsZXRlTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLCBcInN0YXRpY1Byb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZGVsZXRlTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLnByb3RvdHlwZSwgXCJwcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmRlbGV0ZU1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZSwgXCJzdGF0aWNNZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZGVsZXRlTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLnByb3RvdHlwZSwgXCJtZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBkZWxldGVNZXRhZGF0YShtZXRhZGF0YUtleSwgdGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgICAgICAgICAgaWYgKCFJc09iamVjdCh0YXJnZXQpKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgIGlmICghSXNVbmRlZmluZWQocHJvcGVydHlLZXkpKVxuICAgICAgICAgICAgICAgIHByb3BlcnR5S2V5ID0gVG9Qcm9wZXJ0eUtleShwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICB2YXIgbWV0YWRhdGFNYXAgPSBHZXRPckNyZWF0ZU1ldGFkYXRhTWFwKHRhcmdldCwgcHJvcGVydHlLZXksIC8qQ3JlYXRlKi8gZmFsc2UpO1xuICAgICAgICAgICAgaWYgKElzVW5kZWZpbmVkKG1ldGFkYXRhTWFwKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBpZiAoIW1ldGFkYXRhTWFwLmRlbGV0ZShtZXRhZGF0YUtleSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgaWYgKG1ldGFkYXRhTWFwLnNpemUgPiAwKVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgdmFyIHRhcmdldE1ldGFkYXRhID0gTWV0YWRhdGEuZ2V0KHRhcmdldCk7XG4gICAgICAgICAgICB0YXJnZXRNZXRhZGF0YS5kZWxldGUocHJvcGVydHlLZXkpO1xuICAgICAgICAgICAgaWYgKHRhcmdldE1ldGFkYXRhLnNpemUgPiAwKVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgTWV0YWRhdGEuZGVsZXRlKHRhcmdldCk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBleHBvcnRlcihcImRlbGV0ZU1ldGFkYXRhXCIsIGRlbGV0ZU1ldGFkYXRhKTtcbiAgICAgICAgZnVuY3Rpb24gRGVjb3JhdGVDb25zdHJ1Y3RvcihkZWNvcmF0b3JzLCB0YXJnZXQpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICAgICAgdmFyIGRlY29yYXRvciA9IGRlY29yYXRvcnNbaV07XG4gICAgICAgICAgICAgICAgdmFyIGRlY29yYXRlZCA9IGRlY29yYXRvcih0YXJnZXQpO1xuICAgICAgICAgICAgICAgIGlmICghSXNVbmRlZmluZWQoZGVjb3JhdGVkKSAmJiAhSXNOdWxsKGRlY29yYXRlZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFJc0NvbnN0cnVjdG9yKGRlY29yYXRlZCkpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldCA9IGRlY29yYXRlZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIERlY29yYXRlUHJvcGVydHkoZGVjb3JhdG9ycywgdGFyZ2V0LCBwcm9wZXJ0eUtleSwgZGVzY3JpcHRvcikge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGVjb3JhdG9yID0gZGVjb3JhdG9yc1tpXTtcbiAgICAgICAgICAgICAgICB2YXIgZGVjb3JhdGVkID0gZGVjb3JhdG9yKHRhcmdldCwgcHJvcGVydHlLZXksIGRlc2NyaXB0b3IpO1xuICAgICAgICAgICAgICAgIGlmICghSXNVbmRlZmluZWQoZGVjb3JhdGVkKSAmJiAhSXNOdWxsKGRlY29yYXRlZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFJc09iamVjdChkZWNvcmF0ZWQpKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yID0gZGVjb3JhdGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBkZXNjcmlwdG9yO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIEdldE9yQ3JlYXRlTWV0YWRhdGFNYXAoTywgUCwgQ3JlYXRlKSB7XG4gICAgICAgICAgICB2YXIgdGFyZ2V0TWV0YWRhdGEgPSBNZXRhZGF0YS5nZXQoTyk7XG4gICAgICAgICAgICBpZiAoSXNVbmRlZmluZWQodGFyZ2V0TWV0YWRhdGEpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFDcmVhdGUpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgdGFyZ2V0TWV0YWRhdGEgPSBuZXcgX01hcCgpO1xuICAgICAgICAgICAgICAgIE1ldGFkYXRhLnNldChPLCB0YXJnZXRNZXRhZGF0YSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgbWV0YWRhdGFNYXAgPSB0YXJnZXRNZXRhZGF0YS5nZXQoUCk7XG4gICAgICAgICAgICBpZiAoSXNVbmRlZmluZWQobWV0YWRhdGFNYXApKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFDcmVhdGUpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgbWV0YWRhdGFNYXAgPSBuZXcgX01hcCgpO1xuICAgICAgICAgICAgICAgIHRhcmdldE1ldGFkYXRhLnNldChQLCBtZXRhZGF0YU1hcCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWV0YWRhdGFNYXA7XG4gICAgICAgIH1cbiAgICAgICAgLy8gMy4xLjEuMSBPcmRpbmFyeUhhc01ldGFkYXRhKE1ldGFkYXRhS2V5LCBPLCBQKVxuICAgICAgICAvLyBodHRwczovL3JidWNrdG9uLmdpdGh1Yi5pby9yZWZsZWN0LW1ldGFkYXRhLyNvcmRpbmFyeWhhc21ldGFkYXRhXG4gICAgICAgIGZ1bmN0aW9uIE9yZGluYXJ5SGFzTWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApIHtcbiAgICAgICAgICAgIHZhciBoYXNPd24gPSBPcmRpbmFyeUhhc093bk1ldGFkYXRhKE1ldGFkYXRhS2V5LCBPLCBQKTtcbiAgICAgICAgICAgIGlmIChoYXNPd24pXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB2YXIgcGFyZW50ID0gT3JkaW5hcnlHZXRQcm90b3R5cGVPZihPKTtcbiAgICAgICAgICAgIGlmICghSXNOdWxsKHBhcmVudCkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIE9yZGluYXJ5SGFzTWV0YWRhdGEoTWV0YWRhdGFLZXksIHBhcmVudCwgUCk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgLy8gMy4xLjIuMSBPcmRpbmFyeUhhc093bk1ldGFkYXRhKE1ldGFkYXRhS2V5LCBPLCBQKVxuICAgICAgICAvLyBodHRwczovL3JidWNrdG9uLmdpdGh1Yi5pby9yZWZsZWN0LW1ldGFkYXRhLyNvcmRpbmFyeWhhc293bm1ldGFkYXRhXG4gICAgICAgIGZ1bmN0aW9uIE9yZGluYXJ5SGFzT3duTWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApIHtcbiAgICAgICAgICAgIHZhciBtZXRhZGF0YU1hcCA9IEdldE9yQ3JlYXRlTWV0YWRhdGFNYXAoTywgUCwgLypDcmVhdGUqLyBmYWxzZSk7XG4gICAgICAgICAgICBpZiAoSXNVbmRlZmluZWQobWV0YWRhdGFNYXApKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybiBUb0Jvb2xlYW4obWV0YWRhdGFNYXAuaGFzKE1ldGFkYXRhS2V5KSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gMy4xLjMuMSBPcmRpbmFyeUdldE1ldGFkYXRhKE1ldGFkYXRhS2V5LCBPLCBQKVxuICAgICAgICAvLyBodHRwczovL3JidWNrdG9uLmdpdGh1Yi5pby9yZWZsZWN0LW1ldGFkYXRhLyNvcmRpbmFyeWdldG1ldGFkYXRhXG4gICAgICAgIGZ1bmN0aW9uIE9yZGluYXJ5R2V0TWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApIHtcbiAgICAgICAgICAgIHZhciBoYXNPd24gPSBPcmRpbmFyeUhhc093bk1ldGFkYXRhKE1ldGFkYXRhS2V5LCBPLCBQKTtcbiAgICAgICAgICAgIGlmIChoYXNPd24pXG4gICAgICAgICAgICAgICAgcmV0dXJuIE9yZGluYXJ5R2V0T3duTWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApO1xuICAgICAgICAgICAgdmFyIHBhcmVudCA9IE9yZGluYXJ5R2V0UHJvdG90eXBlT2YoTyk7XG4gICAgICAgICAgICBpZiAoIUlzTnVsbChwYXJlbnQpKVxuICAgICAgICAgICAgICAgIHJldHVybiBPcmRpbmFyeUdldE1ldGFkYXRhKE1ldGFkYXRhS2V5LCBwYXJlbnQsIFApO1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICAvLyAzLjEuNC4xIE9yZGluYXJ5R2V0T3duTWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApXG4gICAgICAgIC8vIGh0dHBzOi8vcmJ1Y2t0b24uZ2l0aHViLmlvL3JlZmxlY3QtbWV0YWRhdGEvI29yZGluYXJ5Z2V0b3dubWV0YWRhdGFcbiAgICAgICAgZnVuY3Rpb24gT3JkaW5hcnlHZXRPd25NZXRhZGF0YShNZXRhZGF0YUtleSwgTywgUCkge1xuICAgICAgICAgICAgdmFyIG1ldGFkYXRhTWFwID0gR2V0T3JDcmVhdGVNZXRhZGF0YU1hcChPLCBQLCAvKkNyZWF0ZSovIGZhbHNlKTtcbiAgICAgICAgICAgIGlmIChJc1VuZGVmaW5lZChtZXRhZGF0YU1hcCkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHJldHVybiBtZXRhZGF0YU1hcC5nZXQoTWV0YWRhdGFLZXkpO1xuICAgICAgICB9XG4gICAgICAgIC8vIDMuMS41LjEgT3JkaW5hcnlEZWZpbmVPd25NZXRhZGF0YShNZXRhZGF0YUtleSwgTWV0YWRhdGFWYWx1ZSwgTywgUClcbiAgICAgICAgLy8gaHR0cHM6Ly9yYnVja3Rvbi5naXRodWIuaW8vcmVmbGVjdC1tZXRhZGF0YS8jb3JkaW5hcnlkZWZpbmVvd25tZXRhZGF0YVxuICAgICAgICBmdW5jdGlvbiBPcmRpbmFyeURlZmluZU93bk1ldGFkYXRhKE1ldGFkYXRhS2V5LCBNZXRhZGF0YVZhbHVlLCBPLCBQKSB7XG4gICAgICAgICAgICB2YXIgbWV0YWRhdGFNYXAgPSBHZXRPckNyZWF0ZU1ldGFkYXRhTWFwKE8sIFAsIC8qQ3JlYXRlKi8gdHJ1ZSk7XG4gICAgICAgICAgICBtZXRhZGF0YU1hcC5zZXQoTWV0YWRhdGFLZXksIE1ldGFkYXRhVmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIDMuMS42LjEgT3JkaW5hcnlNZXRhZGF0YUtleXMoTywgUClcbiAgICAgICAgLy8gaHR0cHM6Ly9yYnVja3Rvbi5naXRodWIuaW8vcmVmbGVjdC1tZXRhZGF0YS8jb3JkaW5hcnltZXRhZGF0YWtleXNcbiAgICAgICAgZnVuY3Rpb24gT3JkaW5hcnlNZXRhZGF0YUtleXMoTywgUCkge1xuICAgICAgICAgICAgdmFyIG93bktleXMgPSBPcmRpbmFyeU93bk1ldGFkYXRhS2V5cyhPLCBQKTtcbiAgICAgICAgICAgIHZhciBwYXJlbnQgPSBPcmRpbmFyeUdldFByb3RvdHlwZU9mKE8pO1xuICAgICAgICAgICAgaWYgKHBhcmVudCA9PT0gbnVsbClcbiAgICAgICAgICAgICAgICByZXR1cm4gb3duS2V5cztcbiAgICAgICAgICAgIHZhciBwYXJlbnRLZXlzID0gT3JkaW5hcnlNZXRhZGF0YUtleXMocGFyZW50LCBQKTtcbiAgICAgICAgICAgIGlmIChwYXJlbnRLZXlzLmxlbmd0aCA8PSAwKVxuICAgICAgICAgICAgICAgIHJldHVybiBvd25LZXlzO1xuICAgICAgICAgICAgaWYgKG93bktleXMubGVuZ3RoIDw9IDApXG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcmVudEtleXM7XG4gICAgICAgICAgICB2YXIgc2V0ID0gbmV3IF9TZXQoKTtcbiAgICAgICAgICAgIHZhciBrZXlzID0gW107XG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIG93bktleXNfMSA9IG93bktleXM7IF9pIDwgb3duS2V5c18xLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgICAgIHZhciBrZXkgPSBvd25LZXlzXzFbX2ldO1xuICAgICAgICAgICAgICAgIHZhciBoYXNLZXkgPSBzZXQuaGFzKGtleSk7XG4gICAgICAgICAgICAgICAgaWYgKCFoYXNLZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0LmFkZChrZXkpO1xuICAgICAgICAgICAgICAgICAgICBrZXlzLnB1c2goa2V5KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKHZhciBfYSA9IDAsIHBhcmVudEtleXNfMSA9IHBhcmVudEtleXM7IF9hIDwgcGFyZW50S2V5c18xLmxlbmd0aDsgX2ErKykge1xuICAgICAgICAgICAgICAgIHZhciBrZXkgPSBwYXJlbnRLZXlzXzFbX2FdO1xuICAgICAgICAgICAgICAgIHZhciBoYXNLZXkgPSBzZXQuaGFzKGtleSk7XG4gICAgICAgICAgICAgICAgaWYgKCFoYXNLZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0LmFkZChrZXkpO1xuICAgICAgICAgICAgICAgICAgICBrZXlzLnB1c2goa2V5KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4ga2V5cztcbiAgICAgICAgfVxuICAgICAgICAvLyAzLjEuNy4xIE9yZGluYXJ5T3duTWV0YWRhdGFLZXlzKE8sIFApXG4gICAgICAgIC8vIGh0dHBzOi8vcmJ1Y2t0b24uZ2l0aHViLmlvL3JlZmxlY3QtbWV0YWRhdGEvI29yZGluYXJ5b3dubWV0YWRhdGFrZXlzXG4gICAgICAgIGZ1bmN0aW9uIE9yZGluYXJ5T3duTWV0YWRhdGFLZXlzKE8sIFApIHtcbiAgICAgICAgICAgIHZhciBrZXlzID0gW107XG4gICAgICAgICAgICB2YXIgbWV0YWRhdGFNYXAgPSBHZXRPckNyZWF0ZU1ldGFkYXRhTWFwKE8sIFAsIC8qQ3JlYXRlKi8gZmFsc2UpO1xuICAgICAgICAgICAgaWYgKElzVW5kZWZpbmVkKG1ldGFkYXRhTWFwKSlcbiAgICAgICAgICAgICAgICByZXR1cm4ga2V5cztcbiAgICAgICAgICAgIHZhciBrZXlzT2JqID0gbWV0YWRhdGFNYXAua2V5cygpO1xuICAgICAgICAgICAgdmFyIGl0ZXJhdG9yID0gR2V0SXRlcmF0b3Ioa2V5c09iaik7XG4gICAgICAgICAgICB2YXIgayA9IDA7XG4gICAgICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgICAgIHZhciBuZXh0ID0gSXRlcmF0b3JTdGVwKGl0ZXJhdG9yKTtcbiAgICAgICAgICAgICAgICBpZiAoIW5leHQpIHtcbiAgICAgICAgICAgICAgICAgICAga2V5cy5sZW5ndGggPSBrO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ga2V5cztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIG5leHRWYWx1ZSA9IEl0ZXJhdG9yVmFsdWUobmV4dCk7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAga2V5c1trXSA9IG5leHRWYWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEl0ZXJhdG9yQ2xvc2UoaXRlcmF0b3IpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBrKys7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gNiBFQ01BU2NyaXB0IERhdGEgVHlwMGVzIGFuZCBWYWx1ZXNcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtZWNtYXNjcmlwdC1kYXRhLXR5cGVzLWFuZC12YWx1ZXNcbiAgICAgICAgZnVuY3Rpb24gVHlwZSh4KSB7XG4gICAgICAgICAgICBpZiAoeCA9PT0gbnVsbClcbiAgICAgICAgICAgICAgICByZXR1cm4gMSAvKiBOdWxsICovO1xuICAgICAgICAgICAgc3dpdGNoICh0eXBlb2YgeCkge1xuICAgICAgICAgICAgICAgIGNhc2UgXCJ1bmRlZmluZWRcIjogcmV0dXJuIDAgLyogVW5kZWZpbmVkICovO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJib29sZWFuXCI6IHJldHVybiAyIC8qIEJvb2xlYW4gKi87XG4gICAgICAgICAgICAgICAgY2FzZSBcInN0cmluZ1wiOiByZXR1cm4gMyAvKiBTdHJpbmcgKi87XG4gICAgICAgICAgICAgICAgY2FzZSBcInN5bWJvbFwiOiByZXR1cm4gNCAvKiBTeW1ib2wgKi87XG4gICAgICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOiByZXR1cm4gNSAvKiBOdW1iZXIgKi87XG4gICAgICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOiByZXR1cm4geCA9PT0gbnVsbCA/IDEgLyogTnVsbCAqLyA6IDYgLyogT2JqZWN0ICovO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiA2IC8qIE9iamVjdCAqLztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyA2LjEuMSBUaGUgVW5kZWZpbmVkIFR5cGVcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtZWNtYXNjcmlwdC1sYW5ndWFnZS10eXBlcy11bmRlZmluZWQtdHlwZVxuICAgICAgICBmdW5jdGlvbiBJc1VuZGVmaW5lZCh4KSB7XG4gICAgICAgICAgICByZXR1cm4geCA9PT0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIC8vIDYuMS4yIFRoZSBOdWxsIFR5cGVcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtZWNtYXNjcmlwdC1sYW5ndWFnZS10eXBlcy1udWxsLXR5cGVcbiAgICAgICAgZnVuY3Rpb24gSXNOdWxsKHgpIHtcbiAgICAgICAgICAgIHJldHVybiB4ID09PSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIC8vIDYuMS41IFRoZSBTeW1ib2wgVHlwZVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1lY21hc2NyaXB0LWxhbmd1YWdlLXR5cGVzLXN5bWJvbC10eXBlXG4gICAgICAgIGZ1bmN0aW9uIElzU3ltYm9sKHgpIHtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgeCA9PT0gXCJzeW1ib2xcIjtcbiAgICAgICAgfVxuICAgICAgICAvLyA2LjEuNyBUaGUgT2JqZWN0IFR5cGVcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtb2JqZWN0LXR5cGVcbiAgICAgICAgZnVuY3Rpb24gSXNPYmplY3QoeCkge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiB4ID09PSBcIm9iamVjdFwiID8geCAhPT0gbnVsbCA6IHR5cGVvZiB4ID09PSBcImZ1bmN0aW9uXCI7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy4xIFR5cGUgQ29udmVyc2lvblxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy10eXBlLWNvbnZlcnNpb25cbiAgICAgICAgLy8gNy4xLjEgVG9QcmltaXRpdmUoaW5wdXQgWywgUHJlZmVycmVkVHlwZV0pXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXRvcHJpbWl0aXZlXG4gICAgICAgIGZ1bmN0aW9uIFRvUHJpbWl0aXZlKGlucHV0LCBQcmVmZXJyZWRUeXBlKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKFR5cGUoaW5wdXQpKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAwIC8qIFVuZGVmaW5lZCAqLzogcmV0dXJuIGlucHV0O1xuICAgICAgICAgICAgICAgIGNhc2UgMSAvKiBOdWxsICovOiByZXR1cm4gaW5wdXQ7XG4gICAgICAgICAgICAgICAgY2FzZSAyIC8qIEJvb2xlYW4gKi86IHJldHVybiBpbnB1dDtcbiAgICAgICAgICAgICAgICBjYXNlIDMgLyogU3RyaW5nICovOiByZXR1cm4gaW5wdXQ7XG4gICAgICAgICAgICAgICAgY2FzZSA0IC8qIFN5bWJvbCAqLzogcmV0dXJuIGlucHV0O1xuICAgICAgICAgICAgICAgIGNhc2UgNSAvKiBOdW1iZXIgKi86IHJldHVybiBpbnB1dDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBoaW50ID0gUHJlZmVycmVkVHlwZSA9PT0gMyAvKiBTdHJpbmcgKi8gPyBcInN0cmluZ1wiIDogUHJlZmVycmVkVHlwZSA9PT0gNSAvKiBOdW1iZXIgKi8gPyBcIm51bWJlclwiIDogXCJkZWZhdWx0XCI7XG4gICAgICAgICAgICB2YXIgZXhvdGljVG9QcmltID0gR2V0TWV0aG9kKGlucHV0LCB0b1ByaW1pdGl2ZVN5bWJvbCk7XG4gICAgICAgICAgICBpZiAoZXhvdGljVG9QcmltICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gZXhvdGljVG9QcmltLmNhbGwoaW5wdXQsIGhpbnQpO1xuICAgICAgICAgICAgICAgIGlmIChJc09iamVjdChyZXN1bHQpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBPcmRpbmFyeVRvUHJpbWl0aXZlKGlucHV0LCBoaW50ID09PSBcImRlZmF1bHRcIiA/IFwibnVtYmVyXCIgOiBoaW50KTtcbiAgICAgICAgfVxuICAgICAgICAvLyA3LjEuMS4xIE9yZGluYXJ5VG9QcmltaXRpdmUoTywgaGludClcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtb3JkaW5hcnl0b3ByaW1pdGl2ZVxuICAgICAgICBmdW5jdGlvbiBPcmRpbmFyeVRvUHJpbWl0aXZlKE8sIGhpbnQpIHtcbiAgICAgICAgICAgIGlmIChoaW50ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgdmFyIHRvU3RyaW5nXzEgPSBPLnRvU3RyaW5nO1xuICAgICAgICAgICAgICAgIGlmIChJc0NhbGxhYmxlKHRvU3RyaW5nXzEpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSB0b1N0cmluZ18xLmNhbGwoTyk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghSXNPYmplY3QocmVzdWx0KSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciB2YWx1ZU9mID0gTy52YWx1ZU9mO1xuICAgICAgICAgICAgICAgIGlmIChJc0NhbGxhYmxlKHZhbHVlT2YpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSB2YWx1ZU9mLmNhbGwoTyk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghSXNPYmplY3QocmVzdWx0KSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlT2YgPSBPLnZhbHVlT2Y7XG4gICAgICAgICAgICAgICAgaWYgKElzQ2FsbGFibGUodmFsdWVPZikpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHZhbHVlT2YuY2FsbChPKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFJc09iamVjdChyZXN1bHQpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIHRvU3RyaW5nXzIgPSBPLnRvU3RyaW5nO1xuICAgICAgICAgICAgICAgIGlmIChJc0NhbGxhYmxlKHRvU3RyaW5nXzIpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSB0b1N0cmluZ18yLmNhbGwoTyk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghSXNPYmplY3QocmVzdWx0KSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIC8vIDcuMS4yIFRvQm9vbGVhbihhcmd1bWVudClcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLzIwMTYvI3NlYy10b2Jvb2xlYW5cbiAgICAgICAgZnVuY3Rpb24gVG9Cb29sZWFuKGFyZ3VtZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gISFhcmd1bWVudDtcbiAgICAgICAgfVxuICAgICAgICAvLyA3LjEuMTIgVG9TdHJpbmcoYXJndW1lbnQpXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXRvc3RyaW5nXG4gICAgICAgIGZ1bmN0aW9uIFRvU3RyaW5nKGFyZ3VtZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gXCJcIiArIGFyZ3VtZW50O1xuICAgICAgICB9XG4gICAgICAgIC8vIDcuMS4xNCBUb1Byb3BlcnR5S2V5KGFyZ3VtZW50KVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy10b3Byb3BlcnR5a2V5XG4gICAgICAgIGZ1bmN0aW9uIFRvUHJvcGVydHlLZXkoYXJndW1lbnQpIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBUb1ByaW1pdGl2ZShhcmd1bWVudCwgMyAvKiBTdHJpbmcgKi8pO1xuICAgICAgICAgICAgaWYgKElzU3ltYm9sKGtleSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGtleTtcbiAgICAgICAgICAgIHJldHVybiBUb1N0cmluZyhrZXkpO1xuICAgICAgICB9XG4gICAgICAgIC8vIDcuMiBUZXN0aW5nIGFuZCBDb21wYXJpc29uIE9wZXJhdGlvbnNcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtdGVzdGluZy1hbmQtY29tcGFyaXNvbi1vcGVyYXRpb25zXG4gICAgICAgIC8vIDcuMi4yIElzQXJyYXkoYXJndW1lbnQpXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWlzYXJyYXlcbiAgICAgICAgZnVuY3Rpb24gSXNBcnJheShhcmd1bWVudCkge1xuICAgICAgICAgICAgcmV0dXJuIEFycmF5LmlzQXJyYXlcbiAgICAgICAgICAgICAgICA/IEFycmF5LmlzQXJyYXkoYXJndW1lbnQpXG4gICAgICAgICAgICAgICAgOiBhcmd1bWVudCBpbnN0YW5jZW9mIE9iamVjdFxuICAgICAgICAgICAgICAgICAgICA/IGFyZ3VtZW50IGluc3RhbmNlb2YgQXJyYXlcbiAgICAgICAgICAgICAgICAgICAgOiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJndW1lbnQpID09PSBcIltvYmplY3QgQXJyYXldXCI7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy4yLjMgSXNDYWxsYWJsZShhcmd1bWVudClcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtaXNjYWxsYWJsZVxuICAgICAgICBmdW5jdGlvbiBJc0NhbGxhYmxlKGFyZ3VtZW50KSB7XG4gICAgICAgICAgICAvLyBOT1RFOiBUaGlzIGlzIGFuIGFwcHJveGltYXRpb24gYXMgd2UgY2Fubm90IGNoZWNrIGZvciBbW0NhbGxdXSBpbnRlcm5hbCBtZXRob2QuXG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIGFyZ3VtZW50ID09PSBcImZ1bmN0aW9uXCI7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy4yLjQgSXNDb25zdHJ1Y3Rvcihhcmd1bWVudClcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtaXNjb25zdHJ1Y3RvclxuICAgICAgICBmdW5jdGlvbiBJc0NvbnN0cnVjdG9yKGFyZ3VtZW50KSB7XG4gICAgICAgICAgICAvLyBOT1RFOiBUaGlzIGlzIGFuIGFwcHJveGltYXRpb24gYXMgd2UgY2Fubm90IGNoZWNrIGZvciBbW0NvbnN0cnVjdF1dIGludGVybmFsIG1ldGhvZC5cbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgYXJndW1lbnQgPT09IFwiZnVuY3Rpb25cIjtcbiAgICAgICAgfVxuICAgICAgICAvLyA3LjIuNyBJc1Byb3BlcnR5S2V5KGFyZ3VtZW50KVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1pc3Byb3BlcnR5a2V5XG4gICAgICAgIGZ1bmN0aW9uIElzUHJvcGVydHlLZXkoYXJndW1lbnQpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoVHlwZShhcmd1bWVudCkpIHtcbiAgICAgICAgICAgICAgICBjYXNlIDMgLyogU3RyaW5nICovOiByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjYXNlIDQgLyogU3ltYm9sICovOiByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy4zIE9wZXJhdGlvbnMgb24gT2JqZWN0c1xuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1vcGVyYXRpb25zLW9uLW9iamVjdHNcbiAgICAgICAgLy8gNy4zLjkgR2V0TWV0aG9kKFYsIFApXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWdldG1ldGhvZFxuICAgICAgICBmdW5jdGlvbiBHZXRNZXRob2QoViwgUCkge1xuICAgICAgICAgICAgdmFyIGZ1bmMgPSBWW1BdO1xuICAgICAgICAgICAgaWYgKGZ1bmMgPT09IHVuZGVmaW5lZCB8fCBmdW5jID09PSBudWxsKVxuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICBpZiAoIUlzQ2FsbGFibGUoZnVuYykpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmM7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy40IE9wZXJhdGlvbnMgb24gSXRlcmF0b3IgT2JqZWN0c1xuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1vcGVyYXRpb25zLW9uLWl0ZXJhdG9yLW9iamVjdHNcbiAgICAgICAgZnVuY3Rpb24gR2V0SXRlcmF0b3Iob2JqKSB7XG4gICAgICAgICAgICB2YXIgbWV0aG9kID0gR2V0TWV0aG9kKG9iaiwgaXRlcmF0b3JTeW1ib2wpO1xuICAgICAgICAgICAgaWYgKCFJc0NhbGxhYmxlKG1ldGhvZCkpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpOyAvLyBmcm9tIENhbGxcbiAgICAgICAgICAgIHZhciBpdGVyYXRvciA9IG1ldGhvZC5jYWxsKG9iaik7XG4gICAgICAgICAgICBpZiAoIUlzT2JqZWN0KGl0ZXJhdG9yKSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICByZXR1cm4gaXRlcmF0b3I7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy40LjQgSXRlcmF0b3JWYWx1ZShpdGVyUmVzdWx0KVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvMjAxNi8jc2VjLWl0ZXJhdG9ydmFsdWVcbiAgICAgICAgZnVuY3Rpb24gSXRlcmF0b3JWYWx1ZShpdGVyUmVzdWx0KSB7XG4gICAgICAgICAgICByZXR1cm4gaXRlclJlc3VsdC52YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICAvLyA3LjQuNSBJdGVyYXRvclN0ZXAoaXRlcmF0b3IpXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWl0ZXJhdG9yc3RlcFxuICAgICAgICBmdW5jdGlvbiBJdGVyYXRvclN0ZXAoaXRlcmF0b3IpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0LmRvbmUgPyBmYWxzZSA6IHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgICAvLyA3LjQuNiBJdGVyYXRvckNsb3NlKGl0ZXJhdG9yLCBjb21wbGV0aW9uKVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1pdGVyYXRvcmNsb3NlXG4gICAgICAgIGZ1bmN0aW9uIEl0ZXJhdG9yQ2xvc2UoaXRlcmF0b3IpIHtcbiAgICAgICAgICAgIHZhciBmID0gaXRlcmF0b3JbXCJyZXR1cm5cIl07XG4gICAgICAgICAgICBpZiAoZilcbiAgICAgICAgICAgICAgICBmLmNhbGwoaXRlcmF0b3IpO1xuICAgICAgICB9XG4gICAgICAgIC8vIDkuMSBPcmRpbmFyeSBPYmplY3QgSW50ZXJuYWwgTWV0aG9kcyBhbmQgSW50ZXJuYWwgU2xvdHNcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtb3JkaW5hcnktb2JqZWN0LWludGVybmFsLW1ldGhvZHMtYW5kLWludGVybmFsLXNsb3RzXG4gICAgICAgIC8vIDkuMS4xLjEgT3JkaW5hcnlHZXRQcm90b3R5cGVPZihPKVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1vcmRpbmFyeWdldHByb3RvdHlwZW9mXG4gICAgICAgIGZ1bmN0aW9uIE9yZGluYXJ5R2V0UHJvdG90eXBlT2YoTykge1xuICAgICAgICAgICAgdmFyIHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKE8pO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBPICE9PSBcImZ1bmN0aW9uXCIgfHwgTyA9PT0gZnVuY3Rpb25Qcm90b3R5cGUpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb3RvO1xuICAgICAgICAgICAgLy8gVHlwZVNjcmlwdCBkb2Vzbid0IHNldCBfX3Byb3RvX18gaW4gRVM1LCBhcyBpdCdzIG5vbi1zdGFuZGFyZC5cbiAgICAgICAgICAgIC8vIFRyeSB0byBkZXRlcm1pbmUgdGhlIHN1cGVyY2xhc3MgY29uc3RydWN0b3IuIENvbXBhdGlibGUgaW1wbGVtZW50YXRpb25zXG4gICAgICAgICAgICAvLyBtdXN0IGVpdGhlciBzZXQgX19wcm90b19fIG9uIGEgc3ViY2xhc3MgY29uc3RydWN0b3IgdG8gdGhlIHN1cGVyY2xhc3MgY29uc3RydWN0b3IsXG4gICAgICAgICAgICAvLyBvciBlbnN1cmUgZWFjaCBjbGFzcyBoYXMgYSB2YWxpZCBgY29uc3RydWN0b3JgIHByb3BlcnR5IG9uIGl0cyBwcm90b3R5cGUgdGhhdFxuICAgICAgICAgICAgLy8gcG9pbnRzIGJhY2sgdG8gdGhlIGNvbnN0cnVjdG9yLlxuICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBub3QgdGhlIHNhbWUgYXMgRnVuY3Rpb24uW1tQcm90b3R5cGVdXSwgdGhlbiB0aGlzIGlzIGRlZmluYXRlbHkgaW5oZXJpdGVkLlxuICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgY2FzZSB3aGVuIGluIEVTNiBvciB3aGVuIHVzaW5nIF9fcHJvdG9fXyBpbiBhIGNvbXBhdGlibGUgYnJvd3Nlci5cbiAgICAgICAgICAgIGlmIChwcm90byAhPT0gZnVuY3Rpb25Qcm90b3R5cGUpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb3RvO1xuICAgICAgICAgICAgLy8gSWYgdGhlIHN1cGVyIHByb3RvdHlwZSBpcyBPYmplY3QucHJvdG90eXBlLCBudWxsLCBvciB1bmRlZmluZWQsIHRoZW4gd2UgY2Fubm90IGRldGVybWluZSB0aGUgaGVyaXRhZ2UuXG4gICAgICAgICAgICB2YXIgcHJvdG90eXBlID0gTy5wcm90b3R5cGU7XG4gICAgICAgICAgICB2YXIgcHJvdG90eXBlUHJvdG8gPSBwcm90b3R5cGUgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvdHlwZSk7XG4gICAgICAgICAgICBpZiAocHJvdG90eXBlUHJvdG8gPT0gbnVsbCB8fCBwcm90b3R5cGVQcm90byA9PT0gT2JqZWN0LnByb3RvdHlwZSlcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvdG87XG4gICAgICAgICAgICAvLyBJZiB0aGUgY29uc3RydWN0b3Igd2FzIG5vdCBhIGZ1bmN0aW9uLCB0aGVuIHdlIGNhbm5vdCBkZXRlcm1pbmUgdGhlIGhlcml0YWdlLlxuICAgICAgICAgICAgdmFyIGNvbnN0cnVjdG9yID0gcHJvdG90eXBlUHJvdG8uY29uc3RydWN0b3I7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGNvbnN0cnVjdG9yICE9PSBcImZ1bmN0aW9uXCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb3RvO1xuICAgICAgICAgICAgLy8gSWYgd2UgaGF2ZSBzb21lIGtpbmQgb2Ygc2VsZi1yZWZlcmVuY2UsIHRoZW4gd2UgY2Fubm90IGRldGVybWluZSB0aGUgaGVyaXRhZ2UuXG4gICAgICAgICAgICBpZiAoY29uc3RydWN0b3IgPT09IE8pXG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb3RvO1xuICAgICAgICAgICAgLy8gd2UgaGF2ZSBhIHByZXR0eSBnb29kIGd1ZXNzIGF0IHRoZSBoZXJpdGFnZS5cbiAgICAgICAgICAgIHJldHVybiBjb25zdHJ1Y3RvcjtcbiAgICAgICAgfVxuICAgICAgICAvLyBuYWl2ZSBNYXAgc2hpbVxuICAgICAgICBmdW5jdGlvbiBDcmVhdGVNYXBQb2x5ZmlsbCgpIHtcbiAgICAgICAgICAgIHZhciBjYWNoZVNlbnRpbmVsID0ge307XG4gICAgICAgICAgICB2YXIgYXJyYXlTZW50aW5lbCA9IFtdO1xuICAgICAgICAgICAgdmFyIE1hcEl0ZXJhdG9yID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIE1hcEl0ZXJhdG9yKGtleXMsIHZhbHVlcywgc2VsZWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5faW5kZXggPSAwO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXlzID0ga2V5cztcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdmFsdWVzID0gdmFsdWVzO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zZWxlY3RvciA9IHNlbGVjdG9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBNYXBJdGVyYXRvci5wcm90b3R5cGVbXCJAQGl0ZXJhdG9yXCJdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfTtcbiAgICAgICAgICAgICAgICBNYXBJdGVyYXRvci5wcm90b3R5cGVbaXRlcmF0b3JTeW1ib2xdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfTtcbiAgICAgICAgICAgICAgICBNYXBJdGVyYXRvci5wcm90b3R5cGUubmV4dCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5faW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgdGhpcy5fa2V5cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSB0aGlzLl9zZWxlY3Rvcih0aGlzLl9rZXlzW2luZGV4XSwgdGhpcy5fdmFsdWVzW2luZGV4XSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggKyAxID49IHRoaXMuX2tleXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5faW5kZXggPSAtMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXlzID0gYXJyYXlTZW50aW5lbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZXMgPSBhcnJheVNlbnRpbmVsO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5faW5kZXgrKztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiByZXN1bHQsIGRvbmU6IGZhbHNlIH07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9O1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgTWFwSXRlcmF0b3IucHJvdG90eXBlLnRocm93ID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9pbmRleCA+PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbmRleCA9IC0xO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fa2V5cyA9IGFycmF5U2VudGluZWw7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZXMgPSBhcnJheVNlbnRpbmVsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgTWFwSXRlcmF0b3IucHJvdG90eXBlLnJldHVybiA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5faW5kZXggPj0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5faW5kZXggPSAtMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2tleXMgPSBhcnJheVNlbnRpbmVsO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdmFsdWVzID0gYXJyYXlTZW50aW5lbDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogdmFsdWUsIGRvbmU6IHRydWUgfTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJldHVybiBNYXBJdGVyYXRvcjtcbiAgICAgICAgICAgIH0oKSk7XG4gICAgICAgICAgICByZXR1cm4gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIE1hcCgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fa2V5cyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZXMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2FjaGVLZXkgPSBjYWNoZVNlbnRpbmVsO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZUluZGV4ID0gLTI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShNYXAucHJvdG90eXBlLCBcInNpemVcIiwge1xuICAgICAgICAgICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuX2tleXMubGVuZ3RoOyB9LFxuICAgICAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBNYXAucHJvdG90eXBlLmhhcyA9IGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIHRoaXMuX2ZpbmQoa2V5LCAvKmluc2VydCovIGZhbHNlKSA+PSAwOyB9O1xuICAgICAgICAgICAgICAgIE1hcC5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSB0aGlzLl9maW5kKGtleSwgLyppbnNlcnQqLyBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpbmRleCA+PSAwID8gdGhpcy5fdmFsdWVzW2luZGV4XSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIE1hcC5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5fZmluZChrZXksIC8qaW5zZXJ0Ki8gdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3ZhbHVlc1tpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBNYXAucHJvdG90eXBlLmRlbGV0ZSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5fZmluZChrZXksIC8qaW5zZXJ0Ki8gZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNpemUgPSB0aGlzLl9rZXlzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSBpbmRleCArIDE7IGkgPCBzaXplOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXlzW2kgLSAxXSA9IHRoaXMuX2tleXNbaV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdmFsdWVzW2kgLSAxXSA9IHRoaXMuX3ZhbHVlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2tleXMubGVuZ3RoLS07XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZXMubGVuZ3RoLS07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoa2V5ID09PSB0aGlzLl9jYWNoZUtleSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2NhY2hlS2V5ID0gY2FjaGVTZW50aW5lbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZUluZGV4ID0gLTI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBNYXAucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXlzLmxlbmd0aCA9IDA7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3ZhbHVlcy5sZW5ndGggPSAwO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZUtleSA9IGNhY2hlU2VudGluZWw7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NhY2hlSW5kZXggPSAtMjtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIE1hcC5wcm90b3R5cGUua2V5cyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIG5ldyBNYXBJdGVyYXRvcih0aGlzLl9rZXlzLCB0aGlzLl92YWx1ZXMsIGdldEtleSk7IH07XG4gICAgICAgICAgICAgICAgTWFwLnByb3RvdHlwZS52YWx1ZXMgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBuZXcgTWFwSXRlcmF0b3IodGhpcy5fa2V5cywgdGhpcy5fdmFsdWVzLCBnZXRWYWx1ZSk7IH07XG4gICAgICAgICAgICAgICAgTWFwLnByb3RvdHlwZS5lbnRyaWVzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gbmV3IE1hcEl0ZXJhdG9yKHRoaXMuX2tleXMsIHRoaXMuX3ZhbHVlcywgZ2V0RW50cnkpOyB9O1xuICAgICAgICAgICAgICAgIE1hcC5wcm90b3R5cGVbXCJAQGl0ZXJhdG9yXCJdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5lbnRyaWVzKCk7IH07XG4gICAgICAgICAgICAgICAgTWFwLnByb3RvdHlwZVtpdGVyYXRvclN5bWJvbF0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLmVudHJpZXMoKTsgfTtcbiAgICAgICAgICAgICAgICBNYXAucHJvdG90eXBlLl9maW5kID0gZnVuY3Rpb24gKGtleSwgaW5zZXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9jYWNoZUtleSAhPT0ga2V5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZUluZGV4ID0gdGhpcy5fa2V5cy5pbmRleE9mKHRoaXMuX2NhY2hlS2V5ID0ga2V5KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fY2FjaGVJbmRleCA8IDAgJiYgaW5zZXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZUluZGV4ID0gdGhpcy5fa2V5cy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXlzLnB1c2goa2V5KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3ZhbHVlcy5wdXNoKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlSW5kZXg7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gTWFwO1xuICAgICAgICAgICAgfSgpKTtcbiAgICAgICAgICAgIGZ1bmN0aW9uIGdldEtleShrZXksIF8pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ga2V5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZnVuY3Rpb24gZ2V0VmFsdWUoXywgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmdW5jdGlvbiBnZXRFbnRyeShrZXksIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtrZXksIHZhbHVlXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBuYWl2ZSBTZXQgc2hpbVxuICAgICAgICBmdW5jdGlvbiBDcmVhdGVTZXRQb2x5ZmlsbCgpIHtcbiAgICAgICAgICAgIHJldHVybiAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gU2V0KCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYXAgPSBuZXcgX01hcCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoU2V0LnByb3RvdHlwZSwgXCJzaXplXCIsIHtcbiAgICAgICAgICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLl9tYXAuc2l6ZTsgfSxcbiAgICAgICAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgU2V0LnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIHRoaXMuX21hcC5oYXModmFsdWUpOyB9O1xuICAgICAgICAgICAgICAgIFNldC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiB0aGlzLl9tYXAuc2V0KHZhbHVlLCB2YWx1ZSksIHRoaXM7IH07XG4gICAgICAgICAgICAgICAgU2V0LnByb3RvdHlwZS5kZWxldGUgPSBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIHRoaXMuX21hcC5kZWxldGUodmFsdWUpOyB9O1xuICAgICAgICAgICAgICAgIFNldC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7IHRoaXMuX21hcC5jbGVhcigpOyB9O1xuICAgICAgICAgICAgICAgIFNldC5wcm90b3R5cGUua2V5cyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuX21hcC5rZXlzKCk7IH07XG4gICAgICAgICAgICAgICAgU2V0LnByb3RvdHlwZS52YWx1ZXMgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLl9tYXAudmFsdWVzKCk7IH07XG4gICAgICAgICAgICAgICAgU2V0LnByb3RvdHlwZS5lbnRyaWVzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5fbWFwLmVudHJpZXMoKTsgfTtcbiAgICAgICAgICAgICAgICBTZXQucHJvdG90eXBlW1wiQEBpdGVyYXRvclwiXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMua2V5cygpOyB9O1xuICAgICAgICAgICAgICAgIFNldC5wcm90b3R5cGVbaXRlcmF0b3JTeW1ib2xdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5rZXlzKCk7IH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIFNldDtcbiAgICAgICAgICAgIH0oKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gbmFpdmUgV2Vha01hcCBzaGltXG4gICAgICAgIGZ1bmN0aW9uIENyZWF0ZVdlYWtNYXBQb2x5ZmlsbCgpIHtcbiAgICAgICAgICAgIHZhciBVVUlEX1NJWkUgPSAxNjtcbiAgICAgICAgICAgIHZhciBrZXlzID0gSGFzaE1hcC5jcmVhdGUoKTtcbiAgICAgICAgICAgIHZhciByb290S2V5ID0gQ3JlYXRlVW5pcXVlS2V5KCk7XG4gICAgICAgICAgICByZXR1cm4gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIFdlYWtNYXAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2tleSA9IENyZWF0ZVVuaXF1ZUtleSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBXZWFrTWFwLnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiAodGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0YWJsZSA9IEdldE9yQ3JlYXRlV2Vha01hcFRhYmxlKHRhcmdldCwgLypjcmVhdGUqLyBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0YWJsZSAhPT0gdW5kZWZpbmVkID8gSGFzaE1hcC5oYXModGFibGUsIHRoaXMuX2tleSkgOiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIFdlYWtNYXAucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uICh0YXJnZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRhYmxlID0gR2V0T3JDcmVhdGVXZWFrTWFwVGFibGUodGFyZ2V0LCAvKmNyZWF0ZSovIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRhYmxlICE9PSB1bmRlZmluZWQgPyBIYXNoTWFwLmdldCh0YWJsZSwgdGhpcy5fa2V5KSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIFdlYWtNYXAucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uICh0YXJnZXQsIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0YWJsZSA9IEdldE9yQ3JlYXRlV2Vha01hcFRhYmxlKHRhcmdldCwgLypjcmVhdGUqLyB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgdGFibGVbdGhpcy5fa2V5XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIFdlYWtNYXAucHJvdG90eXBlLmRlbGV0ZSA9IGZ1bmN0aW9uICh0YXJnZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRhYmxlID0gR2V0T3JDcmVhdGVXZWFrTWFwVGFibGUodGFyZ2V0LCAvKmNyZWF0ZSovIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRhYmxlICE9PSB1bmRlZmluZWQgPyBkZWxldGUgdGFibGVbdGhpcy5fa2V5XSA6IGZhbHNlO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgV2Vha01hcC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIE5PVEU6IG5vdCBhIHJlYWwgY2xlYXIsIGp1c3QgbWFrZXMgdGhlIHByZXZpb3VzIGRhdGEgdW5yZWFjaGFibGVcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fa2V5ID0gQ3JlYXRlVW5pcXVlS2V5KCk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gV2Vha01hcDtcbiAgICAgICAgICAgIH0oKSk7XG4gICAgICAgICAgICBmdW5jdGlvbiBDcmVhdGVVbmlxdWVLZXkoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGtleTtcbiAgICAgICAgICAgICAgICBkb1xuICAgICAgICAgICAgICAgICAgICBrZXkgPSBcIkBAV2Vha01hcEBAXCIgKyBDcmVhdGVVVUlEKCk7XG4gICAgICAgICAgICAgICAgd2hpbGUgKEhhc2hNYXAuaGFzKGtleXMsIGtleSkpO1xuICAgICAgICAgICAgICAgIGtleXNba2V5XSA9IHRydWU7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGtleTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZ1bmN0aW9uIEdldE9yQ3JlYXRlV2Vha01hcFRhYmxlKHRhcmdldCwgY3JlYXRlKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFoYXNPd24uY2FsbCh0YXJnZXQsIHJvb3RLZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghY3JlYXRlKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcm9vdEtleSwgeyB2YWx1ZTogSGFzaE1hcC5jcmVhdGUoKSB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRhcmdldFtyb290S2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZ1bmN0aW9uIEZpbGxSYW5kb21CeXRlcyhidWZmZXIsIHNpemUpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpemU7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyW2ldID0gTWF0aC5yYW5kb20oKSAqIDB4ZmYgfCAwO1xuICAgICAgICAgICAgICAgIHJldHVybiBidWZmZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmdW5jdGlvbiBHZW5SYW5kb21CeXRlcyhzaXplKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBVaW50OEFycmF5ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBjcnlwdG8gIT09IFwidW5kZWZpbmVkXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhuZXcgVWludDhBcnJheShzaXplKSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbXNDcnlwdG8gIT09IFwidW5kZWZpbmVkXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbXNDcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKG5ldyBVaW50OEFycmF5KHNpemUpKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEZpbGxSYW5kb21CeXRlcyhuZXcgVWludDhBcnJheShzaXplKSwgc2l6ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBGaWxsUmFuZG9tQnl0ZXMobmV3IEFycmF5KHNpemUpLCBzaXplKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZ1bmN0aW9uIENyZWF0ZVVVSUQoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGRhdGEgPSBHZW5SYW5kb21CeXRlcyhVVUlEX1NJWkUpO1xuICAgICAgICAgICAgICAgIC8vIG1hcmsgYXMgcmFuZG9tIC0gUkZDIDQxMjIgwqcgNC40XG4gICAgICAgICAgICAgICAgZGF0YVs2XSA9IGRhdGFbNl0gJiAweDRmIHwgMHg0MDtcbiAgICAgICAgICAgICAgICBkYXRhWzhdID0gZGF0YVs4XSAmIDB4YmYgfCAweDgwO1xuICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBcIlwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIG9mZnNldCA9IDA7IG9mZnNldCA8IFVVSURfU0laRTsgKytvZmZzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJ5dGUgPSBkYXRhW29mZnNldF07XG4gICAgICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPT09IDQgfHwgb2Zmc2V0ID09PSA2IHx8IG9mZnNldCA9PT0gOClcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCArPSBcIi1cIjtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJ5dGUgPCAxNilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCArPSBcIjBcIjtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ICs9IGJ5dGUudG9TdHJpbmcoMTYpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gdXNlcyBhIGhldXJpc3RpYyB1c2VkIGJ5IHY4IGFuZCBjaGFrcmEgdG8gZm9yY2UgYW4gb2JqZWN0IGludG8gZGljdGlvbmFyeSBtb2RlLlxuICAgICAgICBmdW5jdGlvbiBNYWtlRGljdGlvbmFyeShvYmopIHtcbiAgICAgICAgICAgIG9iai5fXyA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGRlbGV0ZSBvYmouX187XG4gICAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICB9XG4gICAgfSk7XG59KShSZWZsZWN0IHx8IChSZWZsZWN0ID0ge30pKTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY21wIChhLCBiKSB7XG4gICAgdmFyIHBhID0gYS5zcGxpdCgnLicpO1xuICAgIHZhciBwYiA9IGIuc3BsaXQoJy4nKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDM7IGkrKykge1xuICAgICAgICB2YXIgbmEgPSBOdW1iZXIocGFbaV0pO1xuICAgICAgICB2YXIgbmIgPSBOdW1iZXIocGJbaV0pO1xuICAgICAgICBpZiAobmEgPiBuYikgcmV0dXJuIDE7XG4gICAgICAgIGlmIChuYiA+IG5hKSByZXR1cm4gLTE7XG4gICAgICAgIGlmICghaXNOYU4obmEpICYmIGlzTmFOKG5iKSkgcmV0dXJuIDE7XG4gICAgICAgIGlmIChpc05hTihuYSkgJiYgIWlzTmFOKG5iKSkgcmV0dXJuIC0xO1xuICAgIH1cbiAgICByZXR1cm4gMDtcbn07XG4iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBTZW1WZXJcblxudmFyIGRlYnVnXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuaWYgKHR5cGVvZiBwcm9jZXNzID09PSAnb2JqZWN0JyAmJlxuICAgIHByb2Nlc3MuZW52ICYmXG4gICAgcHJvY2Vzcy5lbnYuTk9ERV9ERUJVRyAmJlxuICAgIC9cXGJzZW12ZXJcXGIvaS50ZXN0KHByb2Nlc3MuZW52Lk5PREVfREVCVUcpKSB7XG4gIGRlYnVnID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKVxuICAgIGFyZ3MudW5zaGlmdCgnU0VNVkVSJylcbiAgICBjb25zb2xlLmxvZy5hcHBseShjb25zb2xlLCBhcmdzKVxuICB9XG59IGVsc2Uge1xuICBkZWJ1ZyA9IGZ1bmN0aW9uICgpIHt9XG59XG5cbi8vIE5vdGU6IHRoaXMgaXMgdGhlIHNlbXZlci5vcmcgdmVyc2lvbiBvZiB0aGUgc3BlYyB0aGF0IGl0IGltcGxlbWVudHNcbi8vIE5vdCBuZWNlc3NhcmlseSB0aGUgcGFja2FnZSB2ZXJzaW9uIG9mIHRoaXMgY29kZS5cbmV4cG9ydHMuU0VNVkVSX1NQRUNfVkVSU0lPTiA9ICcyLjAuMCdcblxudmFyIE1BWF9MRU5HVEggPSAyNTZcbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIgfHxcbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gOTAwNzE5OTI1NDc0MDk5MVxuXG4vLyBNYXggc2FmZSBzZWdtZW50IGxlbmd0aCBmb3IgY29lcmNpb24uXG52YXIgTUFYX1NBRkVfQ09NUE9ORU5UX0xFTkdUSCA9IDE2XG5cbi8vIFRoZSBhY3R1YWwgcmVnZXhwcyBnbyBvbiBleHBvcnRzLnJlXG52YXIgcmUgPSBleHBvcnRzLnJlID0gW11cbnZhciBzcmMgPSBleHBvcnRzLnNyYyA9IFtdXG52YXIgUiA9IDBcblxuLy8gVGhlIGZvbGxvd2luZyBSZWd1bGFyIEV4cHJlc3Npb25zIGNhbiBiZSB1c2VkIGZvciB0b2tlbml6aW5nLFxuLy8gdmFsaWRhdGluZywgYW5kIHBhcnNpbmcgU2VtVmVyIHZlcnNpb24gc3RyaW5ncy5cblxuLy8gIyMgTnVtZXJpYyBJZGVudGlmaWVyXG4vLyBBIHNpbmdsZSBgMGAsIG9yIGEgbm9uLXplcm8gZGlnaXQgZm9sbG93ZWQgYnkgemVybyBvciBtb3JlIGRpZ2l0cy5cblxudmFyIE5VTUVSSUNJREVOVElGSUVSID0gUisrXG5zcmNbTlVNRVJJQ0lERU5USUZJRVJdID0gJzB8WzEtOV1cXFxcZConXG52YXIgTlVNRVJJQ0lERU5USUZJRVJMT09TRSA9IFIrK1xuc3JjW05VTUVSSUNJREVOVElGSUVSTE9PU0VdID0gJ1swLTldKydcblxuLy8gIyMgTm9uLW51bWVyaWMgSWRlbnRpZmllclxuLy8gWmVybyBvciBtb3JlIGRpZ2l0cywgZm9sbG93ZWQgYnkgYSBsZXR0ZXIgb3IgaHlwaGVuLCBhbmQgdGhlbiB6ZXJvIG9yXG4vLyBtb3JlIGxldHRlcnMsIGRpZ2l0cywgb3IgaHlwaGVucy5cblxudmFyIE5PTk5VTUVSSUNJREVOVElGSUVSID0gUisrXG5zcmNbTk9OTlVNRVJJQ0lERU5USUZJRVJdID0gJ1xcXFxkKlthLXpBLVotXVthLXpBLVowLTktXSonXG5cbi8vICMjIE1haW4gVmVyc2lvblxuLy8gVGhyZWUgZG90LXNlcGFyYXRlZCBudW1lcmljIGlkZW50aWZpZXJzLlxuXG52YXIgTUFJTlZFUlNJT04gPSBSKytcbnNyY1tNQUlOVkVSU0lPTl0gPSAnKCcgKyBzcmNbTlVNRVJJQ0lERU5USUZJRVJdICsgJylcXFxcLicgK1xuICAgICAgICAgICAgICAgICAgICcoJyArIHNyY1tOVU1FUklDSURFTlRJRklFUl0gKyAnKVxcXFwuJyArXG4gICAgICAgICAgICAgICAgICAgJygnICsgc3JjW05VTUVSSUNJREVOVElGSUVSXSArICcpJ1xuXG52YXIgTUFJTlZFUlNJT05MT09TRSA9IFIrK1xuc3JjW01BSU5WRVJTSU9OTE9PU0VdID0gJygnICsgc3JjW05VTUVSSUNJREVOVElGSUVSTE9PU0VdICsgJylcXFxcLicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJygnICsgc3JjW05VTUVSSUNJREVOVElGSUVSTE9PU0VdICsgJylcXFxcLicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJygnICsgc3JjW05VTUVSSUNJREVOVElGSUVSTE9PU0VdICsgJyknXG5cbi8vICMjIFByZS1yZWxlYXNlIFZlcnNpb24gSWRlbnRpZmllclxuLy8gQSBudW1lcmljIGlkZW50aWZpZXIsIG9yIGEgbm9uLW51bWVyaWMgaWRlbnRpZmllci5cblxudmFyIFBSRVJFTEVBU0VJREVOVElGSUVSID0gUisrXG5zcmNbUFJFUkVMRUFTRUlERU5USUZJRVJdID0gJyg/OicgKyBzcmNbTlVNRVJJQ0lERU5USUZJRVJdICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnfCcgKyBzcmNbTk9OTlVNRVJJQ0lERU5USUZJRVJdICsgJyknXG5cbnZhciBQUkVSRUxFQVNFSURFTlRJRklFUkxPT1NFID0gUisrXG5zcmNbUFJFUkVMRUFTRUlERU5USUZJRVJMT09TRV0gPSAnKD86JyArIHNyY1tOVU1FUklDSURFTlRJRklFUkxPT1NFXSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnfCcgKyBzcmNbTk9OTlVNRVJJQ0lERU5USUZJRVJdICsgJyknXG5cbi8vICMjIFByZS1yZWxlYXNlIFZlcnNpb25cbi8vIEh5cGhlbiwgZm9sbG93ZWQgYnkgb25lIG9yIG1vcmUgZG90LXNlcGFyYXRlZCBwcmUtcmVsZWFzZSB2ZXJzaW9uXG4vLyBpZGVudGlmaWVycy5cblxudmFyIFBSRVJFTEVBU0UgPSBSKytcbnNyY1tQUkVSRUxFQVNFXSA9ICcoPzotKCcgKyBzcmNbUFJFUkVMRUFTRUlERU5USUZJRVJdICtcbiAgICAgICAgICAgICAgICAgICcoPzpcXFxcLicgKyBzcmNbUFJFUkVMRUFTRUlERU5USUZJRVJdICsgJykqKSknXG5cbnZhciBQUkVSRUxFQVNFTE9PU0UgPSBSKytcbnNyY1tQUkVSRUxFQVNFTE9PU0VdID0gJyg/Oi0/KCcgKyBzcmNbUFJFUkVMRUFTRUlERU5USUZJRVJMT09TRV0gK1xuICAgICAgICAgICAgICAgICAgICAgICAnKD86XFxcXC4nICsgc3JjW1BSRVJFTEVBU0VJREVOVElGSUVSTE9PU0VdICsgJykqKSknXG5cbi8vICMjIEJ1aWxkIE1ldGFkYXRhIElkZW50aWZpZXJcbi8vIEFueSBjb21iaW5hdGlvbiBvZiBkaWdpdHMsIGxldHRlcnMsIG9yIGh5cGhlbnMuXG5cbnZhciBCVUlMRElERU5USUZJRVIgPSBSKytcbnNyY1tCVUlMRElERU5USUZJRVJdID0gJ1swLTlBLVphLXotXSsnXG5cbi8vICMjIEJ1aWxkIE1ldGFkYXRhXG4vLyBQbHVzIHNpZ24sIGZvbGxvd2VkIGJ5IG9uZSBvciBtb3JlIHBlcmlvZC1zZXBhcmF0ZWQgYnVpbGQgbWV0YWRhdGFcbi8vIGlkZW50aWZpZXJzLlxuXG52YXIgQlVJTEQgPSBSKytcbnNyY1tCVUlMRF0gPSAnKD86XFxcXCsoJyArIHNyY1tCVUlMRElERU5USUZJRVJdICtcbiAgICAgICAgICAgICAnKD86XFxcXC4nICsgc3JjW0JVSUxESURFTlRJRklFUl0gKyAnKSopKSdcblxuLy8gIyMgRnVsbCBWZXJzaW9uIFN0cmluZ1xuLy8gQSBtYWluIHZlcnNpb24sIGZvbGxvd2VkIG9wdGlvbmFsbHkgYnkgYSBwcmUtcmVsZWFzZSB2ZXJzaW9uIGFuZFxuLy8gYnVpbGQgbWV0YWRhdGEuXG5cbi8vIE5vdGUgdGhhdCB0aGUgb25seSBtYWpvciwgbWlub3IsIHBhdGNoLCBhbmQgcHJlLXJlbGVhc2Ugc2VjdGlvbnMgb2Zcbi8vIHRoZSB2ZXJzaW9uIHN0cmluZyBhcmUgY2FwdHVyaW5nIGdyb3Vwcy4gIFRoZSBidWlsZCBtZXRhZGF0YSBpcyBub3QgYVxuLy8gY2FwdHVyaW5nIGdyb3VwLCBiZWNhdXNlIGl0IHNob3VsZCBub3QgZXZlciBiZSB1c2VkIGluIHZlcnNpb25cbi8vIGNvbXBhcmlzb24uXG5cbnZhciBGVUxMID0gUisrXG52YXIgRlVMTFBMQUlOID0gJ3Y/JyArIHNyY1tNQUlOVkVSU0lPTl0gK1xuICAgICAgICAgICAgICAgIHNyY1tQUkVSRUxFQVNFXSArICc/JyArXG4gICAgICAgICAgICAgICAgc3JjW0JVSUxEXSArICc/J1xuXG5zcmNbRlVMTF0gPSAnXicgKyBGVUxMUExBSU4gKyAnJCdcblxuLy8gbGlrZSBmdWxsLCBidXQgYWxsb3dzIHYxLjIuMyBhbmQgPTEuMi4zLCB3aGljaCBwZW9wbGUgZG8gc29tZXRpbWVzLlxuLy8gYWxzbywgMS4wLjBhbHBoYTEgKHByZXJlbGVhc2Ugd2l0aG91dCB0aGUgaHlwaGVuKSB3aGljaCBpcyBwcmV0dHlcbi8vIGNvbW1vbiBpbiB0aGUgbnBtIHJlZ2lzdHJ5LlxudmFyIExPT1NFUExBSU4gPSAnW3Y9XFxcXHNdKicgKyBzcmNbTUFJTlZFUlNJT05MT09TRV0gK1xuICAgICAgICAgICAgICAgICBzcmNbUFJFUkVMRUFTRUxPT1NFXSArICc/JyArXG4gICAgICAgICAgICAgICAgIHNyY1tCVUlMRF0gKyAnPydcblxudmFyIExPT1NFID0gUisrXG5zcmNbTE9PU0VdID0gJ14nICsgTE9PU0VQTEFJTiArICckJ1xuXG52YXIgR1RMVCA9IFIrK1xuc3JjW0dUTFRdID0gJygoPzo8fD4pPz0/KSdcblxuLy8gU29tZXRoaW5nIGxpa2UgXCIyLipcIiBvciBcIjEuMi54XCIuXG4vLyBOb3RlIHRoYXQgXCJ4LnhcIiBpcyBhIHZhbGlkIHhSYW5nZSBpZGVudGlmZXIsIG1lYW5pbmcgXCJhbnkgdmVyc2lvblwiXG4vLyBPbmx5IHRoZSBmaXJzdCBpdGVtIGlzIHN0cmljdGx5IHJlcXVpcmVkLlxudmFyIFhSQU5HRUlERU5USUZJRVJMT09TRSA9IFIrK1xuc3JjW1hSQU5HRUlERU5USUZJRVJMT09TRV0gPSBzcmNbTlVNRVJJQ0lERU5USUZJRVJMT09TRV0gKyAnfHh8WHxcXFxcKidcbnZhciBYUkFOR0VJREVOVElGSUVSID0gUisrXG5zcmNbWFJBTkdFSURFTlRJRklFUl0gPSBzcmNbTlVNRVJJQ0lERU5USUZJRVJdICsgJ3x4fFh8XFxcXConXG5cbnZhciBYUkFOR0VQTEFJTiA9IFIrK1xuc3JjW1hSQU5HRVBMQUlOXSA9ICdbdj1cXFxcc10qKCcgKyBzcmNbWFJBTkdFSURFTlRJRklFUl0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICcoPzpcXFxcLignICsgc3JjW1hSQU5HRUlERU5USUZJRVJdICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAnKD86XFxcXC4oJyArIHNyY1tYUkFOR0VJREVOVElGSUVSXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgJyg/OicgKyBzcmNbUFJFUkVMRUFTRV0gKyAnKT8nICtcbiAgICAgICAgICAgICAgICAgICBzcmNbQlVJTERdICsgJz8nICtcbiAgICAgICAgICAgICAgICAgICAnKT8pPydcblxudmFyIFhSQU5HRVBMQUlOTE9PU0UgPSBSKytcbnNyY1tYUkFOR0VQTEFJTkxPT1NFXSA9ICdbdj1cXFxcc10qKCcgKyBzcmNbWFJBTkdFSURFTlRJRklFUkxPT1NFXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKD86XFxcXC4oJyArIHNyY1tYUkFOR0VJREVOVElGSUVSTE9PU0VdICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcoPzpcXFxcLignICsgc3JjW1hSQU5HRUlERU5USUZJRVJMT09TRV0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJyg/OicgKyBzcmNbUFJFUkVMRUFTRUxPT1NFXSArICcpPycgK1xuICAgICAgICAgICAgICAgICAgICAgICAgc3JjW0JVSUxEXSArICc/JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKT8pPydcblxudmFyIFhSQU5HRSA9IFIrK1xuc3JjW1hSQU5HRV0gPSAnXicgKyBzcmNbR1RMVF0gKyAnXFxcXHMqJyArIHNyY1tYUkFOR0VQTEFJTl0gKyAnJCdcbnZhciBYUkFOR0VMT09TRSA9IFIrK1xuc3JjW1hSQU5HRUxPT1NFXSA9ICdeJyArIHNyY1tHVExUXSArICdcXFxccyonICsgc3JjW1hSQU5HRVBMQUlOTE9PU0VdICsgJyQnXG5cbi8vIENvZXJjaW9uLlxuLy8gRXh0cmFjdCBhbnl0aGluZyB0aGF0IGNvdWxkIGNvbmNlaXZhYmx5IGJlIGEgcGFydCBvZiBhIHZhbGlkIHNlbXZlclxudmFyIENPRVJDRSA9IFIrK1xuc3JjW0NPRVJDRV0gPSAnKD86XnxbXlxcXFxkXSknICtcbiAgICAgICAgICAgICAgJyhcXFxcZHsxLCcgKyBNQVhfU0FGRV9DT01QT05FTlRfTEVOR1RIICsgJ30pJyArXG4gICAgICAgICAgICAgICcoPzpcXFxcLihcXFxcZHsxLCcgKyBNQVhfU0FGRV9DT01QT05FTlRfTEVOR1RIICsgJ30pKT8nICtcbiAgICAgICAgICAgICAgJyg/OlxcXFwuKFxcXFxkezEsJyArIE1BWF9TQUZFX0NPTVBPTkVOVF9MRU5HVEggKyAnfSkpPycgK1xuICAgICAgICAgICAgICAnKD86JHxbXlxcXFxkXSknXG5cbi8vIFRpbGRlIHJhbmdlcy5cbi8vIE1lYW5pbmcgaXMgXCJyZWFzb25hYmx5IGF0IG9yIGdyZWF0ZXIgdGhhblwiXG52YXIgTE9ORVRJTERFID0gUisrXG5zcmNbTE9ORVRJTERFXSA9ICcoPzp+Pj8pJ1xuXG52YXIgVElMREVUUklNID0gUisrXG5zcmNbVElMREVUUklNXSA9ICcoXFxcXHMqKScgKyBzcmNbTE9ORVRJTERFXSArICdcXFxccysnXG5yZVtUSUxERVRSSU1dID0gbmV3IFJlZ0V4cChzcmNbVElMREVUUklNXSwgJ2cnKVxudmFyIHRpbGRlVHJpbVJlcGxhY2UgPSAnJDF+J1xuXG52YXIgVElMREUgPSBSKytcbnNyY1tUSUxERV0gPSAnXicgKyBzcmNbTE9ORVRJTERFXSArIHNyY1tYUkFOR0VQTEFJTl0gKyAnJCdcbnZhciBUSUxERUxPT1NFID0gUisrXG5zcmNbVElMREVMT09TRV0gPSAnXicgKyBzcmNbTE9ORVRJTERFXSArIHNyY1tYUkFOR0VQTEFJTkxPT1NFXSArICckJ1xuXG4vLyBDYXJldCByYW5nZXMuXG4vLyBNZWFuaW5nIGlzIFwiYXQgbGVhc3QgYW5kIGJhY2t3YXJkcyBjb21wYXRpYmxlIHdpdGhcIlxudmFyIExPTkVDQVJFVCA9IFIrK1xuc3JjW0xPTkVDQVJFVF0gPSAnKD86XFxcXF4pJ1xuXG52YXIgQ0FSRVRUUklNID0gUisrXG5zcmNbQ0FSRVRUUklNXSA9ICcoXFxcXHMqKScgKyBzcmNbTE9ORUNBUkVUXSArICdcXFxccysnXG5yZVtDQVJFVFRSSU1dID0gbmV3IFJlZ0V4cChzcmNbQ0FSRVRUUklNXSwgJ2cnKVxudmFyIGNhcmV0VHJpbVJlcGxhY2UgPSAnJDFeJ1xuXG52YXIgQ0FSRVQgPSBSKytcbnNyY1tDQVJFVF0gPSAnXicgKyBzcmNbTE9ORUNBUkVUXSArIHNyY1tYUkFOR0VQTEFJTl0gKyAnJCdcbnZhciBDQVJFVExPT1NFID0gUisrXG5zcmNbQ0FSRVRMT09TRV0gPSAnXicgKyBzcmNbTE9ORUNBUkVUXSArIHNyY1tYUkFOR0VQTEFJTkxPT1NFXSArICckJ1xuXG4vLyBBIHNpbXBsZSBndC9sdC9lcSB0aGluZywgb3IganVzdCBcIlwiIHRvIGluZGljYXRlIFwiYW55IHZlcnNpb25cIlxudmFyIENPTVBBUkFUT1JMT09TRSA9IFIrK1xuc3JjW0NPTVBBUkFUT1JMT09TRV0gPSAnXicgKyBzcmNbR1RMVF0gKyAnXFxcXHMqKCcgKyBMT09TRVBMQUlOICsgJykkfF4kJ1xudmFyIENPTVBBUkFUT1IgPSBSKytcbnNyY1tDT01QQVJBVE9SXSA9ICdeJyArIHNyY1tHVExUXSArICdcXFxccyooJyArIEZVTExQTEFJTiArICcpJHxeJCdcblxuLy8gQW4gZXhwcmVzc2lvbiB0byBzdHJpcCBhbnkgd2hpdGVzcGFjZSBiZXR3ZWVuIHRoZSBndGx0IGFuZCB0aGUgdGhpbmdcbi8vIGl0IG1vZGlmaWVzLCBzbyB0aGF0IGA+IDEuMi4zYCA9PT4gYD4xLjIuM2BcbnZhciBDT01QQVJBVE9SVFJJTSA9IFIrK1xuc3JjW0NPTVBBUkFUT1JUUklNXSA9ICcoXFxcXHMqKScgKyBzcmNbR1RMVF0gK1xuICAgICAgICAgICAgICAgICAgICAgICdcXFxccyooJyArIExPT1NFUExBSU4gKyAnfCcgKyBzcmNbWFJBTkdFUExBSU5dICsgJyknXG5cbi8vIHRoaXMgb25lIGhhcyB0byB1c2UgdGhlIC9nIGZsYWdcbnJlW0NPTVBBUkFUT1JUUklNXSA9IG5ldyBSZWdFeHAoc3JjW0NPTVBBUkFUT1JUUklNXSwgJ2cnKVxudmFyIGNvbXBhcmF0b3JUcmltUmVwbGFjZSA9ICckMSQyJDMnXG5cbi8vIFNvbWV0aGluZyBsaWtlIGAxLjIuMyAtIDEuMi40YFxuLy8gTm90ZSB0aGF0IHRoZXNlIGFsbCB1c2UgdGhlIGxvb3NlIGZvcm0sIGJlY2F1c2UgdGhleSdsbCBiZVxuLy8gY2hlY2tlZCBhZ2FpbnN0IGVpdGhlciB0aGUgc3RyaWN0IG9yIGxvb3NlIGNvbXBhcmF0b3IgZm9ybVxuLy8gbGF0ZXIuXG52YXIgSFlQSEVOUkFOR0UgPSBSKytcbnNyY1tIWVBIRU5SQU5HRV0gPSAnXlxcXFxzKignICsgc3JjW1hSQU5HRVBMQUlOXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgJ1xcXFxzKy1cXFxccysnICtcbiAgICAgICAgICAgICAgICAgICAnKCcgKyBzcmNbWFJBTkdFUExBSU5dICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAnXFxcXHMqJCdcblxudmFyIEhZUEhFTlJBTkdFTE9PU0UgPSBSKytcbnNyY1tIWVBIRU5SQU5HRUxPT1NFXSA9ICdeXFxcXHMqKCcgKyBzcmNbWFJBTkdFUExBSU5MT09TRV0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJ1xcXFxzKy1cXFxccysnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcoJyArIHNyY1tYUkFOR0VQTEFJTkxPT1NFXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnXFxcXHMqJCdcblxuLy8gU3RhciByYW5nZXMgYmFzaWNhbGx5IGp1c3QgYWxsb3cgYW55dGhpbmcgYXQgYWxsLlxudmFyIFNUQVIgPSBSKytcbnNyY1tTVEFSXSA9ICcoPHw+KT89P1xcXFxzKlxcXFwqJ1xuXG4vLyBDb21waWxlIHRvIGFjdHVhbCByZWdleHAgb2JqZWN0cy5cbi8vIEFsbCBhcmUgZmxhZy1mcmVlLCB1bmxlc3MgdGhleSB3ZXJlIGNyZWF0ZWQgYWJvdmUgd2l0aCBhIGZsYWcuXG5mb3IgKHZhciBpID0gMDsgaSA8IFI7IGkrKykge1xuICBkZWJ1ZyhpLCBzcmNbaV0pXG4gIGlmICghcmVbaV0pIHtcbiAgICByZVtpXSA9IG5ldyBSZWdFeHAoc3JjW2ldKVxuICB9XG59XG5cbmV4cG9ydHMucGFyc2UgPSBwYXJzZVxuZnVuY3Rpb24gcGFyc2UgKHZlcnNpb24sIG9wdGlvbnMpIHtcbiAgaWYgKCFvcHRpb25zIHx8IHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0Jykge1xuICAgIG9wdGlvbnMgPSB7XG4gICAgICBsb29zZTogISFvcHRpb25zLFxuICAgICAgaW5jbHVkZVByZXJlbGVhc2U6IGZhbHNlXG4gICAgfVxuICB9XG5cbiAgaWYgKHZlcnNpb24gaW5zdGFuY2VvZiBTZW1WZXIpIHtcbiAgICByZXR1cm4gdmVyc2lvblxuICB9XG5cbiAgaWYgKHR5cGVvZiB2ZXJzaW9uICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICBpZiAodmVyc2lvbi5sZW5ndGggPiBNQVhfTEVOR1RIKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIHZhciByID0gb3B0aW9ucy5sb29zZSA/IHJlW0xPT1NFXSA6IHJlW0ZVTExdXG4gIGlmICghci50ZXN0KHZlcnNpb24pKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIHRyeSB7XG4gICAgcmV0dXJuIG5ldyBTZW1WZXIodmVyc2lvbiwgb3B0aW9ucylcbiAgfSBjYXRjaCAoZXIpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG59XG5cbmV4cG9ydHMudmFsaWQgPSB2YWxpZFxuZnVuY3Rpb24gdmFsaWQgKHZlcnNpb24sIG9wdGlvbnMpIHtcbiAgdmFyIHYgPSBwYXJzZSh2ZXJzaW9uLCBvcHRpb25zKVxuICByZXR1cm4gdiA/IHYudmVyc2lvbiA6IG51bGxcbn1cblxuZXhwb3J0cy5jbGVhbiA9IGNsZWFuXG5mdW5jdGlvbiBjbGVhbiAodmVyc2lvbiwgb3B0aW9ucykge1xuICB2YXIgcyA9IHBhcnNlKHZlcnNpb24udHJpbSgpLnJlcGxhY2UoL15bPXZdKy8sICcnKSwgb3B0aW9ucylcbiAgcmV0dXJuIHMgPyBzLnZlcnNpb24gOiBudWxsXG59XG5cbmV4cG9ydHMuU2VtVmVyID0gU2VtVmVyXG5cbmZ1bmN0aW9uIFNlbVZlciAodmVyc2lvbiwgb3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMgfHwgdHlwZW9mIG9wdGlvbnMgIT09ICdvYmplY3QnKSB7XG4gICAgb3B0aW9ucyA9IHtcbiAgICAgIGxvb3NlOiAhIW9wdGlvbnMsXG4gICAgICBpbmNsdWRlUHJlcmVsZWFzZTogZmFsc2VcbiAgICB9XG4gIH1cbiAgaWYgKHZlcnNpb24gaW5zdGFuY2VvZiBTZW1WZXIpIHtcbiAgICBpZiAodmVyc2lvbi5sb29zZSA9PT0gb3B0aW9ucy5sb29zZSkge1xuICAgICAgcmV0dXJuIHZlcnNpb25cbiAgICB9IGVsc2Uge1xuICAgICAgdmVyc2lvbiA9IHZlcnNpb24udmVyc2lvblxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgdmVyc2lvbiAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIFZlcnNpb246ICcgKyB2ZXJzaW9uKVxuICB9XG5cbiAgaWYgKHZlcnNpb24ubGVuZ3RoID4gTUFYX0xFTkdUSCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3ZlcnNpb24gaXMgbG9uZ2VyIHRoYW4gJyArIE1BWF9MRU5HVEggKyAnIGNoYXJhY3RlcnMnKVxuICB9XG5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNlbVZlcikpIHtcbiAgICByZXR1cm4gbmV3IFNlbVZlcih2ZXJzaW9uLCBvcHRpb25zKVxuICB9XG5cbiAgZGVidWcoJ1NlbVZlcicsIHZlcnNpb24sIG9wdGlvbnMpXG4gIHRoaXMub3B0aW9ucyA9IG9wdGlvbnNcbiAgdGhpcy5sb29zZSA9ICEhb3B0aW9ucy5sb29zZVxuXG4gIHZhciBtID0gdmVyc2lvbi50cmltKCkubWF0Y2gob3B0aW9ucy5sb29zZSA/IHJlW0xPT1NFXSA6IHJlW0ZVTExdKVxuXG4gIGlmICghbSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgVmVyc2lvbjogJyArIHZlcnNpb24pXG4gIH1cblxuICB0aGlzLnJhdyA9IHZlcnNpb25cblxuICAvLyB0aGVzZSBhcmUgYWN0dWFsbHkgbnVtYmVyc1xuICB0aGlzLm1ham9yID0gK21bMV1cbiAgdGhpcy5taW5vciA9ICttWzJdXG4gIHRoaXMucGF0Y2ggPSArbVszXVxuXG4gIGlmICh0aGlzLm1ham9yID4gTUFYX1NBRkVfSU5URUdFUiB8fCB0aGlzLm1ham9yIDwgMCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgbWFqb3IgdmVyc2lvbicpXG4gIH1cblxuICBpZiAodGhpcy5taW5vciA+IE1BWF9TQUZFX0lOVEVHRVIgfHwgdGhpcy5taW5vciA8IDApIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG1pbm9yIHZlcnNpb24nKVxuICB9XG5cbiAgaWYgKHRoaXMucGF0Y2ggPiBNQVhfU0FGRV9JTlRFR0VSIHx8IHRoaXMucGF0Y2ggPCAwKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBwYXRjaCB2ZXJzaW9uJylcbiAgfVxuXG4gIC8vIG51bWJlcmlmeSBhbnkgcHJlcmVsZWFzZSBudW1lcmljIGlkc1xuICBpZiAoIW1bNF0pIHtcbiAgICB0aGlzLnByZXJlbGVhc2UgPSBbXVxuICB9IGVsc2Uge1xuICAgIHRoaXMucHJlcmVsZWFzZSA9IG1bNF0uc3BsaXQoJy4nKS5tYXAoZnVuY3Rpb24gKGlkKSB7XG4gICAgICBpZiAoL15bMC05XSskLy50ZXN0KGlkKSkge1xuICAgICAgICB2YXIgbnVtID0gK2lkXG4gICAgICAgIGlmIChudW0gPj0gMCAmJiBudW0gPCBNQVhfU0FGRV9JTlRFR0VSKSB7XG4gICAgICAgICAgcmV0dXJuIG51bVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gaWRcbiAgICB9KVxuICB9XG5cbiAgdGhpcy5idWlsZCA9IG1bNV0gPyBtWzVdLnNwbGl0KCcuJykgOiBbXVxuICB0aGlzLmZvcm1hdCgpXG59XG5cblNlbVZlci5wcm90b3R5cGUuZm9ybWF0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLnZlcnNpb24gPSB0aGlzLm1ham9yICsgJy4nICsgdGhpcy5taW5vciArICcuJyArIHRoaXMucGF0Y2hcbiAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGgpIHtcbiAgICB0aGlzLnZlcnNpb24gKz0gJy0nICsgdGhpcy5wcmVyZWxlYXNlLmpvaW4oJy4nKVxuICB9XG4gIHJldHVybiB0aGlzLnZlcnNpb25cbn1cblxuU2VtVmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMudmVyc2lvblxufVxuXG5TZW1WZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgZGVidWcoJ1NlbVZlci5jb21wYXJlJywgdGhpcy52ZXJzaW9uLCB0aGlzLm9wdGlvbnMsIG90aGVyKVxuICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIFNlbVZlcikpIHtcbiAgICBvdGhlciA9IG5ldyBTZW1WZXIob3RoZXIsIHRoaXMub3B0aW9ucylcbiAgfVxuXG4gIHJldHVybiB0aGlzLmNvbXBhcmVNYWluKG90aGVyKSB8fCB0aGlzLmNvbXBhcmVQcmUob3RoZXIpXG59XG5cblNlbVZlci5wcm90b3R5cGUuY29tcGFyZU1haW4gPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBTZW1WZXIpKSB7XG4gICAgb3RoZXIgPSBuZXcgU2VtVmVyKG90aGVyLCB0aGlzLm9wdGlvbnMpXG4gIH1cblxuICByZXR1cm4gY29tcGFyZUlkZW50aWZpZXJzKHRoaXMubWFqb3IsIG90aGVyLm1ham9yKSB8fFxuICAgICAgICAgY29tcGFyZUlkZW50aWZpZXJzKHRoaXMubWlub3IsIG90aGVyLm1pbm9yKSB8fFxuICAgICAgICAgY29tcGFyZUlkZW50aWZpZXJzKHRoaXMucGF0Y2gsIG90aGVyLnBhdGNoKVxufVxuXG5TZW1WZXIucHJvdG90eXBlLmNvbXBhcmVQcmUgPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBTZW1WZXIpKSB7XG4gICAgb3RoZXIgPSBuZXcgU2VtVmVyKG90aGVyLCB0aGlzLm9wdGlvbnMpXG4gIH1cblxuICAvLyBOT1QgaGF2aW5nIGEgcHJlcmVsZWFzZSBpcyA+IGhhdmluZyBvbmVcbiAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggJiYgIW90aGVyLnByZXJlbGVhc2UubGVuZ3RoKSB7XG4gICAgcmV0dXJuIC0xXG4gIH0gZWxzZSBpZiAoIXRoaXMucHJlcmVsZWFzZS5sZW5ndGggJiYgb3RoZXIucHJlcmVsZWFzZS5sZW5ndGgpIHtcbiAgICByZXR1cm4gMVxuICB9IGVsc2UgaWYgKCF0aGlzLnByZXJlbGVhc2UubGVuZ3RoICYmICFvdGhlci5wcmVyZWxlYXNlLmxlbmd0aCkge1xuICAgIHJldHVybiAwXG4gIH1cblxuICB2YXIgaSA9IDBcbiAgZG8ge1xuICAgIHZhciBhID0gdGhpcy5wcmVyZWxlYXNlW2ldXG4gICAgdmFyIGIgPSBvdGhlci5wcmVyZWxlYXNlW2ldXG4gICAgZGVidWcoJ3ByZXJlbGVhc2UgY29tcGFyZScsIGksIGEsIGIpXG4gICAgaWYgKGEgPT09IHVuZGVmaW5lZCAmJiBiID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAwXG4gICAgfSBlbHNlIGlmIChiID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAxXG4gICAgfSBlbHNlIGlmIChhID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAtMVxuICAgIH0gZWxzZSBpZiAoYSA9PT0gYikge1xuICAgICAgY29udGludWVcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNvbXBhcmVJZGVudGlmaWVycyhhLCBiKVxuICAgIH1cbiAgfSB3aGlsZSAoKytpKVxufVxuXG4vLyBwcmVtaW5vciB3aWxsIGJ1bXAgdGhlIHZlcnNpb24gdXAgdG8gdGhlIG5leHQgbWlub3IgcmVsZWFzZSwgYW5kIGltbWVkaWF0ZWx5XG4vLyBkb3duIHRvIHByZS1yZWxlYXNlLiBwcmVtYWpvciBhbmQgcHJlcGF0Y2ggd29yayB0aGUgc2FtZSB3YXkuXG5TZW1WZXIucHJvdG90eXBlLmluYyA9IGZ1bmN0aW9uIChyZWxlYXNlLCBpZGVudGlmaWVyKSB7XG4gIHN3aXRjaCAocmVsZWFzZSkge1xuICAgIGNhc2UgJ3ByZW1ham9yJzpcbiAgICAgIHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPSAwXG4gICAgICB0aGlzLnBhdGNoID0gMFxuICAgICAgdGhpcy5taW5vciA9IDBcbiAgICAgIHRoaXMubWFqb3IrK1xuICAgICAgdGhpcy5pbmMoJ3ByZScsIGlkZW50aWZpZXIpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3ByZW1pbm9yJzpcbiAgICAgIHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPSAwXG4gICAgICB0aGlzLnBhdGNoID0gMFxuICAgICAgdGhpcy5taW5vcisrXG4gICAgICB0aGlzLmluYygncHJlJywgaWRlbnRpZmllcilcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAncHJlcGF0Y2gnOlxuICAgICAgLy8gSWYgdGhpcyBpcyBhbHJlYWR5IGEgcHJlcmVsZWFzZSwgaXQgd2lsbCBidW1wIHRvIHRoZSBuZXh0IHZlcnNpb25cbiAgICAgIC8vIGRyb3AgYW55IHByZXJlbGVhc2VzIHRoYXQgbWlnaHQgYWxyZWFkeSBleGlzdCwgc2luY2UgdGhleSBhcmUgbm90XG4gICAgICAvLyByZWxldmFudCBhdCB0aGlzIHBvaW50LlxuICAgICAgdGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9IDBcbiAgICAgIHRoaXMuaW5jKCdwYXRjaCcsIGlkZW50aWZpZXIpXG4gICAgICB0aGlzLmluYygncHJlJywgaWRlbnRpZmllcilcbiAgICAgIGJyZWFrXG4gICAgLy8gSWYgdGhlIGlucHV0IGlzIGEgbm9uLXByZXJlbGVhc2UgdmVyc2lvbiwgdGhpcyBhY3RzIHRoZSBzYW1lIGFzXG4gICAgLy8gcHJlcGF0Y2guXG4gICAgY2FzZSAncHJlcmVsZWFzZSc6XG4gICAgICBpZiAodGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLmluYygncGF0Y2gnLCBpZGVudGlmaWVyKVxuICAgICAgfVxuICAgICAgdGhpcy5pbmMoJ3ByZScsIGlkZW50aWZpZXIpXG4gICAgICBicmVha1xuXG4gICAgY2FzZSAnbWFqb3InOlxuICAgICAgLy8gSWYgdGhpcyBpcyBhIHByZS1tYWpvciB2ZXJzaW9uLCBidW1wIHVwIHRvIHRoZSBzYW1lIG1ham9yIHZlcnNpb24uXG4gICAgICAvLyBPdGhlcndpc2UgaW5jcmVtZW50IG1ham9yLlxuICAgICAgLy8gMS4wLjAtNSBidW1wcyB0byAxLjAuMFxuICAgICAgLy8gMS4xLjAgYnVtcHMgdG8gMi4wLjBcbiAgICAgIGlmICh0aGlzLm1pbm9yICE9PSAwIHx8XG4gICAgICAgICAgdGhpcy5wYXRjaCAhPT0gMCB8fFxuICAgICAgICAgIHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy5tYWpvcisrXG4gICAgICB9XG4gICAgICB0aGlzLm1pbm9yID0gMFxuICAgICAgdGhpcy5wYXRjaCA9IDBcbiAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFtdXG4gICAgICBicmVha1xuICAgIGNhc2UgJ21pbm9yJzpcbiAgICAgIC8vIElmIHRoaXMgaXMgYSBwcmUtbWlub3IgdmVyc2lvbiwgYnVtcCB1cCB0byB0aGUgc2FtZSBtaW5vciB2ZXJzaW9uLlxuICAgICAgLy8gT3RoZXJ3aXNlIGluY3JlbWVudCBtaW5vci5cbiAgICAgIC8vIDEuMi4wLTUgYnVtcHMgdG8gMS4yLjBcbiAgICAgIC8vIDEuMi4xIGJ1bXBzIHRvIDEuMy4wXG4gICAgICBpZiAodGhpcy5wYXRjaCAhPT0gMCB8fCB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMubWlub3IrK1xuICAgICAgfVxuICAgICAgdGhpcy5wYXRjaCA9IDBcbiAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFtdXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3BhdGNoJzpcbiAgICAgIC8vIElmIHRoaXMgaXMgbm90IGEgcHJlLXJlbGVhc2UgdmVyc2lvbiwgaXQgd2lsbCBpbmNyZW1lbnQgdGhlIHBhdGNoLlxuICAgICAgLy8gSWYgaXQgaXMgYSBwcmUtcmVsZWFzZSBpdCB3aWxsIGJ1bXAgdXAgdG8gdGhlIHNhbWUgcGF0Y2ggdmVyc2lvbi5cbiAgICAgIC8vIDEuMi4wLTUgcGF0Y2hlcyB0byAxLjIuMFxuICAgICAgLy8gMS4yLjAgcGF0Y2hlcyB0byAxLjIuMVxuICAgICAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy5wYXRjaCsrXG4gICAgICB9XG4gICAgICB0aGlzLnByZXJlbGVhc2UgPSBbXVxuICAgICAgYnJlYWtcbiAgICAvLyBUaGlzIHByb2JhYmx5IHNob3VsZG4ndCBiZSB1c2VkIHB1YmxpY2x5LlxuICAgIC8vIDEuMC4wIFwicHJlXCIgd291bGQgYmVjb21lIDEuMC4wLTAgd2hpY2ggaXMgdGhlIHdyb25nIGRpcmVjdGlvbi5cbiAgICBjYXNlICdwcmUnOlxuICAgICAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy5wcmVyZWxlYXNlID0gWzBdXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgaSA9IHRoaXMucHJlcmVsZWFzZS5sZW5ndGhcbiAgICAgICAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnByZXJlbGVhc2VbaV0gPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICB0aGlzLnByZXJlbGVhc2VbaV0rK1xuICAgICAgICAgICAgaSA9IC0yXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChpID09PSAtMSkge1xuICAgICAgICAgIC8vIGRpZG4ndCBpbmNyZW1lbnQgYW55dGhpbmdcbiAgICAgICAgICB0aGlzLnByZXJlbGVhc2UucHVzaCgwKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaWRlbnRpZmllcikge1xuICAgICAgICAvLyAxLjIuMC1iZXRhLjEgYnVtcHMgdG8gMS4yLjAtYmV0YS4yLFxuICAgICAgICAvLyAxLjIuMC1iZXRhLmZvb2JseiBvciAxLjIuMC1iZXRhIGJ1bXBzIHRvIDEuMi4wLWJldGEuMFxuICAgICAgICBpZiAodGhpcy5wcmVyZWxlYXNlWzBdID09PSBpZGVudGlmaWVyKSB7XG4gICAgICAgICAgaWYgKGlzTmFOKHRoaXMucHJlcmVsZWFzZVsxXSkpIHtcbiAgICAgICAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFtpZGVudGlmaWVyLCAwXVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnByZXJlbGVhc2UgPSBbaWRlbnRpZmllciwgMF1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYnJlYWtcblxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgaW5jcmVtZW50IGFyZ3VtZW50OiAnICsgcmVsZWFzZSlcbiAgfVxuICB0aGlzLmZvcm1hdCgpXG4gIHRoaXMucmF3ID0gdGhpcy52ZXJzaW9uXG4gIHJldHVybiB0aGlzXG59XG5cbmV4cG9ydHMuaW5jID0gaW5jXG5mdW5jdGlvbiBpbmMgKHZlcnNpb24sIHJlbGVhc2UsIGxvb3NlLCBpZGVudGlmaWVyKSB7XG4gIGlmICh0eXBlb2YgKGxvb3NlKSA9PT0gJ3N0cmluZycpIHtcbiAgICBpZGVudGlmaWVyID0gbG9vc2VcbiAgICBsb29zZSA9IHVuZGVmaW5lZFxuICB9XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gbmV3IFNlbVZlcih2ZXJzaW9uLCBsb29zZSkuaW5jKHJlbGVhc2UsIGlkZW50aWZpZXIpLnZlcnNpb25cbiAgfSBjYXRjaCAoZXIpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG59XG5cbmV4cG9ydHMuZGlmZiA9IGRpZmZcbmZ1bmN0aW9uIGRpZmYgKHZlcnNpb24xLCB2ZXJzaW9uMikge1xuICBpZiAoZXEodmVyc2lvbjEsIHZlcnNpb24yKSkge1xuICAgIHJldHVybiBudWxsXG4gIH0gZWxzZSB7XG4gICAgdmFyIHYxID0gcGFyc2UodmVyc2lvbjEpXG4gICAgdmFyIHYyID0gcGFyc2UodmVyc2lvbjIpXG4gICAgdmFyIHByZWZpeCA9ICcnXG4gICAgaWYgKHYxLnByZXJlbGVhc2UubGVuZ3RoIHx8IHYyLnByZXJlbGVhc2UubGVuZ3RoKSB7XG4gICAgICBwcmVmaXggPSAncHJlJ1xuICAgICAgdmFyIGRlZmF1bHRSZXN1bHQgPSAncHJlcmVsZWFzZSdcbiAgICB9XG4gICAgZm9yICh2YXIga2V5IGluIHYxKSB7XG4gICAgICBpZiAoa2V5ID09PSAnbWFqb3InIHx8IGtleSA9PT0gJ21pbm9yJyB8fCBrZXkgPT09ICdwYXRjaCcpIHtcbiAgICAgICAgaWYgKHYxW2tleV0gIT09IHYyW2tleV0pIHtcbiAgICAgICAgICByZXR1cm4gcHJlZml4ICsga2V5XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRlZmF1bHRSZXN1bHQgLy8gbWF5IGJlIHVuZGVmaW5lZFxuICB9XG59XG5cbmV4cG9ydHMuY29tcGFyZUlkZW50aWZpZXJzID0gY29tcGFyZUlkZW50aWZpZXJzXG5cbnZhciBudW1lcmljID0gL15bMC05XSskL1xuZnVuY3Rpb24gY29tcGFyZUlkZW50aWZpZXJzIChhLCBiKSB7XG4gIHZhciBhbnVtID0gbnVtZXJpYy50ZXN0KGEpXG4gIHZhciBibnVtID0gbnVtZXJpYy50ZXN0KGIpXG5cbiAgaWYgKGFudW0gJiYgYm51bSkge1xuICAgIGEgPSArYVxuICAgIGIgPSArYlxuICB9XG5cbiAgcmV0dXJuIGEgPT09IGIgPyAwXG4gICAgOiAoYW51bSAmJiAhYm51bSkgPyAtMVxuICAgIDogKGJudW0gJiYgIWFudW0pID8gMVxuICAgIDogYSA8IGIgPyAtMVxuICAgIDogMVxufVxuXG5leHBvcnRzLnJjb21wYXJlSWRlbnRpZmllcnMgPSByY29tcGFyZUlkZW50aWZpZXJzXG5mdW5jdGlvbiByY29tcGFyZUlkZW50aWZpZXJzIChhLCBiKSB7XG4gIHJldHVybiBjb21wYXJlSWRlbnRpZmllcnMoYiwgYSlcbn1cblxuZXhwb3J0cy5tYWpvciA9IG1ham9yXG5mdW5jdGlvbiBtYWpvciAoYSwgbG9vc2UpIHtcbiAgcmV0dXJuIG5ldyBTZW1WZXIoYSwgbG9vc2UpLm1ham9yXG59XG5cbmV4cG9ydHMubWlub3IgPSBtaW5vclxuZnVuY3Rpb24gbWlub3IgKGEsIGxvb3NlKSB7XG4gIHJldHVybiBuZXcgU2VtVmVyKGEsIGxvb3NlKS5taW5vclxufVxuXG5leHBvcnRzLnBhdGNoID0gcGF0Y2hcbmZ1bmN0aW9uIHBhdGNoIChhLCBsb29zZSkge1xuICByZXR1cm4gbmV3IFNlbVZlcihhLCBsb29zZSkucGF0Y2hcbn1cblxuZXhwb3J0cy5jb21wYXJlID0gY29tcGFyZVxuZnVuY3Rpb24gY29tcGFyZSAoYSwgYiwgbG9vc2UpIHtcbiAgcmV0dXJuIG5ldyBTZW1WZXIoYSwgbG9vc2UpLmNvbXBhcmUobmV3IFNlbVZlcihiLCBsb29zZSkpXG59XG5cbmV4cG9ydHMuY29tcGFyZUxvb3NlID0gY29tcGFyZUxvb3NlXG5mdW5jdGlvbiBjb21wYXJlTG9vc2UgKGEsIGIpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYSwgYiwgdHJ1ZSlcbn1cblxuZXhwb3J0cy5yY29tcGFyZSA9IHJjb21wYXJlXG5mdW5jdGlvbiByY29tcGFyZSAoYSwgYiwgbG9vc2UpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYiwgYSwgbG9vc2UpXG59XG5cbmV4cG9ydHMuc29ydCA9IHNvcnRcbmZ1bmN0aW9uIHNvcnQgKGxpc3QsIGxvb3NlKSB7XG4gIHJldHVybiBsaXN0LnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICByZXR1cm4gZXhwb3J0cy5jb21wYXJlKGEsIGIsIGxvb3NlKVxuICB9KVxufVxuXG5leHBvcnRzLnJzb3J0ID0gcnNvcnRcbmZ1bmN0aW9uIHJzb3J0IChsaXN0LCBsb29zZSkge1xuICByZXR1cm4gbGlzdC5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgcmV0dXJuIGV4cG9ydHMucmNvbXBhcmUoYSwgYiwgbG9vc2UpXG4gIH0pXG59XG5cbmV4cG9ydHMuZ3QgPSBndFxuZnVuY3Rpb24gZ3QgKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIGxvb3NlKSA+IDBcbn1cblxuZXhwb3J0cy5sdCA9IGx0XG5mdW5jdGlvbiBsdCAoYSwgYiwgbG9vc2UpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYSwgYiwgbG9vc2UpIDwgMFxufVxuXG5leHBvcnRzLmVxID0gZXFcbmZ1bmN0aW9uIGVxIChhLCBiLCBsb29zZSkge1xuICByZXR1cm4gY29tcGFyZShhLCBiLCBsb29zZSkgPT09IDBcbn1cblxuZXhwb3J0cy5uZXEgPSBuZXFcbmZ1bmN0aW9uIG5lcSAoYSwgYiwgbG9vc2UpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYSwgYiwgbG9vc2UpICE9PSAwXG59XG5cbmV4cG9ydHMuZ3RlID0gZ3RlXG5mdW5jdGlvbiBndGUgKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIGxvb3NlKSA+PSAwXG59XG5cbmV4cG9ydHMubHRlID0gbHRlXG5mdW5jdGlvbiBsdGUgKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIGxvb3NlKSA8PSAwXG59XG5cbmV4cG9ydHMuY21wID0gY21wXG5mdW5jdGlvbiBjbXAgKGEsIG9wLCBiLCBsb29zZSkge1xuICBzd2l0Y2ggKG9wKSB7XG4gICAgY2FzZSAnPT09JzpcbiAgICAgIGlmICh0eXBlb2YgYSA9PT0gJ29iamVjdCcpXG4gICAgICAgIGEgPSBhLnZlcnNpb25cbiAgICAgIGlmICh0eXBlb2YgYiA9PT0gJ29iamVjdCcpXG4gICAgICAgIGIgPSBiLnZlcnNpb25cbiAgICAgIHJldHVybiBhID09PSBiXG5cbiAgICBjYXNlICchPT0nOlxuICAgICAgaWYgKHR5cGVvZiBhID09PSAnb2JqZWN0JylcbiAgICAgICAgYSA9IGEudmVyc2lvblxuICAgICAgaWYgKHR5cGVvZiBiID09PSAnb2JqZWN0JylcbiAgICAgICAgYiA9IGIudmVyc2lvblxuICAgICAgcmV0dXJuIGEgIT09IGJcblxuICAgIGNhc2UgJyc6XG4gICAgY2FzZSAnPSc6XG4gICAgY2FzZSAnPT0nOlxuICAgICAgcmV0dXJuIGVxKGEsIGIsIGxvb3NlKVxuXG4gICAgY2FzZSAnIT0nOlxuICAgICAgcmV0dXJuIG5lcShhLCBiLCBsb29zZSlcblxuICAgIGNhc2UgJz4nOlxuICAgICAgcmV0dXJuIGd0KGEsIGIsIGxvb3NlKVxuXG4gICAgY2FzZSAnPj0nOlxuICAgICAgcmV0dXJuIGd0ZShhLCBiLCBsb29zZSlcblxuICAgIGNhc2UgJzwnOlxuICAgICAgcmV0dXJuIGx0KGEsIGIsIGxvb3NlKVxuXG4gICAgY2FzZSAnPD0nOlxuICAgICAgcmV0dXJuIGx0ZShhLCBiLCBsb29zZSlcblxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG9wZXJhdG9yOiAnICsgb3ApXG4gIH1cbn1cblxuZXhwb3J0cy5Db21wYXJhdG9yID0gQ29tcGFyYXRvclxuZnVuY3Rpb24gQ29tcGFyYXRvciAoY29tcCwgb3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMgfHwgdHlwZW9mIG9wdGlvbnMgIT09ICdvYmplY3QnKSB7XG4gICAgb3B0aW9ucyA9IHtcbiAgICAgIGxvb3NlOiAhIW9wdGlvbnMsXG4gICAgICBpbmNsdWRlUHJlcmVsZWFzZTogZmFsc2VcbiAgICB9XG4gIH1cblxuICBpZiAoY29tcCBpbnN0YW5jZW9mIENvbXBhcmF0b3IpIHtcbiAgICBpZiAoY29tcC5sb29zZSA9PT0gISFvcHRpb25zLmxvb3NlKSB7XG4gICAgICByZXR1cm4gY29tcFxuICAgIH0gZWxzZSB7XG4gICAgICBjb21wID0gY29tcC52YWx1ZVxuICAgIH1cbiAgfVxuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBDb21wYXJhdG9yKSkge1xuICAgIHJldHVybiBuZXcgQ29tcGFyYXRvcihjb21wLCBvcHRpb25zKVxuICB9XG5cbiAgZGVidWcoJ2NvbXBhcmF0b3InLCBjb21wLCBvcHRpb25zKVxuICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zXG4gIHRoaXMubG9vc2UgPSAhIW9wdGlvbnMubG9vc2VcbiAgdGhpcy5wYXJzZShjb21wKVxuXG4gIGlmICh0aGlzLnNlbXZlciA9PT0gQU5ZKSB7XG4gICAgdGhpcy52YWx1ZSA9ICcnXG4gIH0gZWxzZSB7XG4gICAgdGhpcy52YWx1ZSA9IHRoaXMub3BlcmF0b3IgKyB0aGlzLnNlbXZlci52ZXJzaW9uXG4gIH1cblxuICBkZWJ1ZygnY29tcCcsIHRoaXMpXG59XG5cbnZhciBBTlkgPSB7fVxuQ29tcGFyYXRvci5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbiAoY29tcCkge1xuICB2YXIgciA9IHRoaXMub3B0aW9ucy5sb29zZSA/IHJlW0NPTVBBUkFUT1JMT09TRV0gOiByZVtDT01QQVJBVE9SXVxuICB2YXIgbSA9IGNvbXAubWF0Y2gocilcblxuICBpZiAoIW0pIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIGNvbXBhcmF0b3I6ICcgKyBjb21wKVxuICB9XG5cbiAgdGhpcy5vcGVyYXRvciA9IG1bMV1cbiAgaWYgKHRoaXMub3BlcmF0b3IgPT09ICc9Jykge1xuICAgIHRoaXMub3BlcmF0b3IgPSAnJ1xuICB9XG5cbiAgLy8gaWYgaXQgbGl0ZXJhbGx5IGlzIGp1c3QgJz4nIG9yICcnIHRoZW4gYWxsb3cgYW55dGhpbmcuXG4gIGlmICghbVsyXSkge1xuICAgIHRoaXMuc2VtdmVyID0gQU5ZXG4gIH0gZWxzZSB7XG4gICAgdGhpcy5zZW12ZXIgPSBuZXcgU2VtVmVyKG1bMl0sIHRoaXMub3B0aW9ucy5sb29zZSlcbiAgfVxufVxuXG5Db21wYXJhdG9yLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMudmFsdWVcbn1cblxuQ29tcGFyYXRvci5wcm90b3R5cGUudGVzdCA9IGZ1bmN0aW9uICh2ZXJzaW9uKSB7XG4gIGRlYnVnKCdDb21wYXJhdG9yLnRlc3QnLCB2ZXJzaW9uLCB0aGlzLm9wdGlvbnMubG9vc2UpXG5cbiAgaWYgKHRoaXMuc2VtdmVyID09PSBBTlkpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgaWYgKHR5cGVvZiB2ZXJzaW9uID09PSAnc3RyaW5nJykge1xuICAgIHZlcnNpb24gPSBuZXcgU2VtVmVyKHZlcnNpb24sIHRoaXMub3B0aW9ucylcbiAgfVxuXG4gIHJldHVybiBjbXAodmVyc2lvbiwgdGhpcy5vcGVyYXRvciwgdGhpcy5zZW12ZXIsIHRoaXMub3B0aW9ucylcbn1cblxuQ29tcGFyYXRvci5wcm90b3R5cGUuaW50ZXJzZWN0cyA9IGZ1bmN0aW9uIChjb21wLCBvcHRpb25zKSB7XG4gIGlmICghKGNvbXAgaW5zdGFuY2VvZiBDb21wYXJhdG9yKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2EgQ29tcGFyYXRvciBpcyByZXF1aXJlZCcpXG4gIH1cblxuICBpZiAoIW9wdGlvbnMgfHwgdHlwZW9mIG9wdGlvbnMgIT09ICdvYmplY3QnKSB7XG4gICAgb3B0aW9ucyA9IHtcbiAgICAgIGxvb3NlOiAhIW9wdGlvbnMsXG4gICAgICBpbmNsdWRlUHJlcmVsZWFzZTogZmFsc2VcbiAgICB9XG4gIH1cblxuICB2YXIgcmFuZ2VUbXBcblxuICBpZiAodGhpcy5vcGVyYXRvciA9PT0gJycpIHtcbiAgICByYW5nZVRtcCA9IG5ldyBSYW5nZShjb21wLnZhbHVlLCBvcHRpb25zKVxuICAgIHJldHVybiBzYXRpc2ZpZXModGhpcy52YWx1ZSwgcmFuZ2VUbXAsIG9wdGlvbnMpXG4gIH0gZWxzZSBpZiAoY29tcC5vcGVyYXRvciA9PT0gJycpIHtcbiAgICByYW5nZVRtcCA9IG5ldyBSYW5nZSh0aGlzLnZhbHVlLCBvcHRpb25zKVxuICAgIHJldHVybiBzYXRpc2ZpZXMoY29tcC5zZW12ZXIsIHJhbmdlVG1wLCBvcHRpb25zKVxuICB9XG5cbiAgdmFyIHNhbWVEaXJlY3Rpb25JbmNyZWFzaW5nID1cbiAgICAodGhpcy5vcGVyYXRvciA9PT0gJz49JyB8fCB0aGlzLm9wZXJhdG9yID09PSAnPicpICYmXG4gICAgKGNvbXAub3BlcmF0b3IgPT09ICc+PScgfHwgY29tcC5vcGVyYXRvciA9PT0gJz4nKVxuICB2YXIgc2FtZURpcmVjdGlvbkRlY3JlYXNpbmcgPVxuICAgICh0aGlzLm9wZXJhdG9yID09PSAnPD0nIHx8IHRoaXMub3BlcmF0b3IgPT09ICc8JykgJiZcbiAgICAoY29tcC5vcGVyYXRvciA9PT0gJzw9JyB8fCBjb21wLm9wZXJhdG9yID09PSAnPCcpXG4gIHZhciBzYW1lU2VtVmVyID0gdGhpcy5zZW12ZXIudmVyc2lvbiA9PT0gY29tcC5zZW12ZXIudmVyc2lvblxuICB2YXIgZGlmZmVyZW50RGlyZWN0aW9uc0luY2x1c2l2ZSA9XG4gICAgKHRoaXMub3BlcmF0b3IgPT09ICc+PScgfHwgdGhpcy5vcGVyYXRvciA9PT0gJzw9JykgJiZcbiAgICAoY29tcC5vcGVyYXRvciA9PT0gJz49JyB8fCBjb21wLm9wZXJhdG9yID09PSAnPD0nKVxuICB2YXIgb3Bwb3NpdGVEaXJlY3Rpb25zTGVzc1RoYW4gPVxuICAgIGNtcCh0aGlzLnNlbXZlciwgJzwnLCBjb21wLnNlbXZlciwgb3B0aW9ucykgJiZcbiAgICAoKHRoaXMub3BlcmF0b3IgPT09ICc+PScgfHwgdGhpcy5vcGVyYXRvciA9PT0gJz4nKSAmJlxuICAgIChjb21wLm9wZXJhdG9yID09PSAnPD0nIHx8IGNvbXAub3BlcmF0b3IgPT09ICc8JykpXG4gIHZhciBvcHBvc2l0ZURpcmVjdGlvbnNHcmVhdGVyVGhhbiA9XG4gICAgY21wKHRoaXMuc2VtdmVyLCAnPicsIGNvbXAuc2VtdmVyLCBvcHRpb25zKSAmJlxuICAgICgodGhpcy5vcGVyYXRvciA9PT0gJzw9JyB8fCB0aGlzLm9wZXJhdG9yID09PSAnPCcpICYmXG4gICAgKGNvbXAub3BlcmF0b3IgPT09ICc+PScgfHwgY29tcC5vcGVyYXRvciA9PT0gJz4nKSlcblxuICByZXR1cm4gc2FtZURpcmVjdGlvbkluY3JlYXNpbmcgfHwgc2FtZURpcmVjdGlvbkRlY3JlYXNpbmcgfHxcbiAgICAoc2FtZVNlbVZlciAmJiBkaWZmZXJlbnREaXJlY3Rpb25zSW5jbHVzaXZlKSB8fFxuICAgIG9wcG9zaXRlRGlyZWN0aW9uc0xlc3NUaGFuIHx8IG9wcG9zaXRlRGlyZWN0aW9uc0dyZWF0ZXJUaGFuXG59XG5cbmV4cG9ydHMuUmFuZ2UgPSBSYW5nZVxuZnVuY3Rpb24gUmFuZ2UgKHJhbmdlLCBvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucyB8fCB0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgbG9vc2U6ICEhb3B0aW9ucyxcbiAgICAgIGluY2x1ZGVQcmVyZWxlYXNlOiBmYWxzZVxuICAgIH1cbiAgfVxuXG4gIGlmIChyYW5nZSBpbnN0YW5jZW9mIFJhbmdlKSB7XG4gICAgaWYgKHJhbmdlLmxvb3NlID09PSAhIW9wdGlvbnMubG9vc2UgJiZcbiAgICAgICAgcmFuZ2UuaW5jbHVkZVByZXJlbGVhc2UgPT09ICEhb3B0aW9ucy5pbmNsdWRlUHJlcmVsZWFzZSkge1xuICAgICAgcmV0dXJuIHJhbmdlXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgUmFuZ2UocmFuZ2UucmF3LCBvcHRpb25zKVxuICAgIH1cbiAgfVxuXG4gIGlmIChyYW5nZSBpbnN0YW5jZW9mIENvbXBhcmF0b3IpIHtcbiAgICByZXR1cm4gbmV3IFJhbmdlKHJhbmdlLnZhbHVlLCBvcHRpb25zKVxuICB9XG5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJhbmdlKSkge1xuICAgIHJldHVybiBuZXcgUmFuZ2UocmFuZ2UsIG9wdGlvbnMpXG4gIH1cblxuICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zXG4gIHRoaXMubG9vc2UgPSAhIW9wdGlvbnMubG9vc2VcbiAgdGhpcy5pbmNsdWRlUHJlcmVsZWFzZSA9ICEhb3B0aW9ucy5pbmNsdWRlUHJlcmVsZWFzZVxuXG4gIC8vIEZpcnN0LCBzcGxpdCBiYXNlZCBvbiBib29sZWFuIG9yIHx8XG4gIHRoaXMucmF3ID0gcmFuZ2VcbiAgdGhpcy5zZXQgPSByYW5nZS5zcGxpdCgvXFxzKlxcfFxcfFxccyovKS5tYXAoZnVuY3Rpb24gKHJhbmdlKSB7XG4gICAgcmV0dXJuIHRoaXMucGFyc2VSYW5nZShyYW5nZS50cmltKCkpXG4gIH0sIHRoaXMpLmZpbHRlcihmdW5jdGlvbiAoYykge1xuICAgIC8vIHRocm93IG91dCBhbnkgdGhhdCBhcmUgbm90IHJlbGV2YW50IGZvciB3aGF0ZXZlciByZWFzb25cbiAgICByZXR1cm4gYy5sZW5ndGhcbiAgfSlcblxuICBpZiAoIXRoaXMuc2V0Lmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgU2VtVmVyIFJhbmdlOiAnICsgcmFuZ2UpXG4gIH1cblxuICB0aGlzLmZvcm1hdCgpXG59XG5cblJhbmdlLnByb3RvdHlwZS5mb3JtYXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMucmFuZ2UgPSB0aGlzLnNldC5tYXAoZnVuY3Rpb24gKGNvbXBzKSB7XG4gICAgcmV0dXJuIGNvbXBzLmpvaW4oJyAnKS50cmltKClcbiAgfSkuam9pbignfHwnKS50cmltKClcbiAgcmV0dXJuIHRoaXMucmFuZ2Vcbn1cblxuUmFuZ2UucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5yYW5nZVxufVxuXG5SYW5nZS5wcm90b3R5cGUucGFyc2VSYW5nZSA9IGZ1bmN0aW9uIChyYW5nZSkge1xuICB2YXIgbG9vc2UgPSB0aGlzLm9wdGlvbnMubG9vc2VcbiAgcmFuZ2UgPSByYW5nZS50cmltKClcbiAgLy8gYDEuMi4zIC0gMS4yLjRgID0+IGA+PTEuMi4zIDw9MS4yLjRgXG4gIHZhciBociA9IGxvb3NlID8gcmVbSFlQSEVOUkFOR0VMT09TRV0gOiByZVtIWVBIRU5SQU5HRV1cbiAgcmFuZ2UgPSByYW5nZS5yZXBsYWNlKGhyLCBoeXBoZW5SZXBsYWNlKVxuICBkZWJ1ZygnaHlwaGVuIHJlcGxhY2UnLCByYW5nZSlcbiAgLy8gYD4gMS4yLjMgPCAxLjIuNWAgPT4gYD4xLjIuMyA8MS4yLjVgXG4gIHJhbmdlID0gcmFuZ2UucmVwbGFjZShyZVtDT01QQVJBVE9SVFJJTV0sIGNvbXBhcmF0b3JUcmltUmVwbGFjZSlcbiAgZGVidWcoJ2NvbXBhcmF0b3IgdHJpbScsIHJhbmdlLCByZVtDT01QQVJBVE9SVFJJTV0pXG5cbiAgLy8gYH4gMS4yLjNgID0+IGB+MS4yLjNgXG4gIHJhbmdlID0gcmFuZ2UucmVwbGFjZShyZVtUSUxERVRSSU1dLCB0aWxkZVRyaW1SZXBsYWNlKVxuXG4gIC8vIGBeIDEuMi4zYCA9PiBgXjEuMi4zYFxuICByYW5nZSA9IHJhbmdlLnJlcGxhY2UocmVbQ0FSRVRUUklNXSwgY2FyZXRUcmltUmVwbGFjZSlcblxuICAvLyBub3JtYWxpemUgc3BhY2VzXG4gIHJhbmdlID0gcmFuZ2Uuc3BsaXQoL1xccysvKS5qb2luKCcgJylcblxuICAvLyBBdCB0aGlzIHBvaW50LCB0aGUgcmFuZ2UgaXMgY29tcGxldGVseSB0cmltbWVkIGFuZFxuICAvLyByZWFkeSB0byBiZSBzcGxpdCBpbnRvIGNvbXBhcmF0b3JzLlxuXG4gIHZhciBjb21wUmUgPSBsb29zZSA/IHJlW0NPTVBBUkFUT1JMT09TRV0gOiByZVtDT01QQVJBVE9SXVxuICB2YXIgc2V0ID0gcmFuZ2Uuc3BsaXQoJyAnKS5tYXAoZnVuY3Rpb24gKGNvbXApIHtcbiAgICByZXR1cm4gcGFyc2VDb21wYXJhdG9yKGNvbXAsIHRoaXMub3B0aW9ucylcbiAgfSwgdGhpcykuam9pbignICcpLnNwbGl0KC9cXHMrLylcbiAgaWYgKHRoaXMub3B0aW9ucy5sb29zZSkge1xuICAgIC8vIGluIGxvb3NlIG1vZGUsIHRocm93IG91dCBhbnkgdGhhdCBhcmUgbm90IHZhbGlkIGNvbXBhcmF0b3JzXG4gICAgc2V0ID0gc2V0LmZpbHRlcihmdW5jdGlvbiAoY29tcCkge1xuICAgICAgcmV0dXJuICEhY29tcC5tYXRjaChjb21wUmUpXG4gICAgfSlcbiAgfVxuICBzZXQgPSBzZXQubWFwKGZ1bmN0aW9uIChjb21wKSB7XG4gICAgcmV0dXJuIG5ldyBDb21wYXJhdG9yKGNvbXAsIHRoaXMub3B0aW9ucylcbiAgfSwgdGhpcylcblxuICByZXR1cm4gc2V0XG59XG5cblJhbmdlLnByb3RvdHlwZS5pbnRlcnNlY3RzID0gZnVuY3Rpb24gKHJhbmdlLCBvcHRpb25zKSB7XG4gIGlmICghKHJhbmdlIGluc3RhbmNlb2YgUmFuZ2UpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYSBSYW5nZSBpcyByZXF1aXJlZCcpXG4gIH1cblxuICByZXR1cm4gdGhpcy5zZXQuc29tZShmdW5jdGlvbiAodGhpc0NvbXBhcmF0b3JzKSB7XG4gICAgcmV0dXJuIHRoaXNDb21wYXJhdG9ycy5ldmVyeShmdW5jdGlvbiAodGhpc0NvbXBhcmF0b3IpIHtcbiAgICAgIHJldHVybiByYW5nZS5zZXQuc29tZShmdW5jdGlvbiAocmFuZ2VDb21wYXJhdG9ycykge1xuICAgICAgICByZXR1cm4gcmFuZ2VDb21wYXJhdG9ycy5ldmVyeShmdW5jdGlvbiAocmFuZ2VDb21wYXJhdG9yKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXNDb21wYXJhdG9yLmludGVyc2VjdHMocmFuZ2VDb21wYXJhdG9yLCBvcHRpb25zKVxuICAgICAgICB9KVxuICAgICAgfSlcbiAgICB9KVxuICB9KVxufVxuXG4vLyBNb3N0bHkganVzdCBmb3IgdGVzdGluZyBhbmQgbGVnYWN5IEFQSSByZWFzb25zXG5leHBvcnRzLnRvQ29tcGFyYXRvcnMgPSB0b0NvbXBhcmF0b3JzXG5mdW5jdGlvbiB0b0NvbXBhcmF0b3JzIChyYW5nZSwgb3B0aW9ucykge1xuICByZXR1cm4gbmV3IFJhbmdlKHJhbmdlLCBvcHRpb25zKS5zZXQubWFwKGZ1bmN0aW9uIChjb21wKSB7XG4gICAgcmV0dXJuIGNvbXAubWFwKGZ1bmN0aW9uIChjKSB7XG4gICAgICByZXR1cm4gYy52YWx1ZVxuICAgIH0pLmpvaW4oJyAnKS50cmltKCkuc3BsaXQoJyAnKVxuICB9KVxufVxuXG4vLyBjb21wcmlzZWQgb2YgeHJhbmdlcywgdGlsZGVzLCBzdGFycywgYW5kIGd0bHQncyBhdCB0aGlzIHBvaW50LlxuLy8gYWxyZWFkeSByZXBsYWNlZCB0aGUgaHlwaGVuIHJhbmdlc1xuLy8gdHVybiBpbnRvIGEgc2V0IG9mIEpVU1QgY29tcGFyYXRvcnMuXG5mdW5jdGlvbiBwYXJzZUNvbXBhcmF0b3IgKGNvbXAsIG9wdGlvbnMpIHtcbiAgZGVidWcoJ2NvbXAnLCBjb21wLCBvcHRpb25zKVxuICBjb21wID0gcmVwbGFjZUNhcmV0cyhjb21wLCBvcHRpb25zKVxuICBkZWJ1ZygnY2FyZXQnLCBjb21wKVxuICBjb21wID0gcmVwbGFjZVRpbGRlcyhjb21wLCBvcHRpb25zKVxuICBkZWJ1ZygndGlsZGVzJywgY29tcClcbiAgY29tcCA9IHJlcGxhY2VYUmFuZ2VzKGNvbXAsIG9wdGlvbnMpXG4gIGRlYnVnKCd4cmFuZ2UnLCBjb21wKVxuICBjb21wID0gcmVwbGFjZVN0YXJzKGNvbXAsIG9wdGlvbnMpXG4gIGRlYnVnKCdzdGFycycsIGNvbXApXG4gIHJldHVybiBjb21wXG59XG5cbmZ1bmN0aW9uIGlzWCAoaWQpIHtcbiAgcmV0dXJuICFpZCB8fCBpZC50b0xvd2VyQ2FzZSgpID09PSAneCcgfHwgaWQgPT09ICcqJ1xufVxuXG4vLyB+LCB+PiAtLT4gKiAoYW55LCBraW5kYSBzaWxseSlcbi8vIH4yLCB+Mi54LCB+Mi54LngsIH4+Miwgfj4yLnggfj4yLngueCAtLT4gPj0yLjAuMCA8My4wLjBcbi8vIH4yLjAsIH4yLjAueCwgfj4yLjAsIH4+Mi4wLnggLS0+ID49Mi4wLjAgPDIuMS4wXG4vLyB+MS4yLCB+MS4yLngsIH4+MS4yLCB+PjEuMi54IC0tPiA+PTEuMi4wIDwxLjMuMFxuLy8gfjEuMi4zLCB+PjEuMi4zIC0tPiA+PTEuMi4zIDwxLjMuMFxuLy8gfjEuMi4wLCB+PjEuMi4wIC0tPiA+PTEuMi4wIDwxLjMuMFxuZnVuY3Rpb24gcmVwbGFjZVRpbGRlcyAoY29tcCwgb3B0aW9ucykge1xuICByZXR1cm4gY29tcC50cmltKCkuc3BsaXQoL1xccysvKS5tYXAoZnVuY3Rpb24gKGNvbXApIHtcbiAgICByZXR1cm4gcmVwbGFjZVRpbGRlKGNvbXAsIG9wdGlvbnMpXG4gIH0pLmpvaW4oJyAnKVxufVxuXG5mdW5jdGlvbiByZXBsYWNlVGlsZGUgKGNvbXAsIG9wdGlvbnMpIHtcbiAgdmFyIHIgPSBvcHRpb25zLmxvb3NlID8gcmVbVElMREVMT09TRV0gOiByZVtUSUxERV1cbiAgcmV0dXJuIGNvbXAucmVwbGFjZShyLCBmdW5jdGlvbiAoXywgTSwgbSwgcCwgcHIpIHtcbiAgICBkZWJ1ZygndGlsZGUnLCBjb21wLCBfLCBNLCBtLCBwLCBwcilcbiAgICB2YXIgcmV0XG5cbiAgICBpZiAoaXNYKE0pKSB7XG4gICAgICByZXQgPSAnJ1xuICAgIH0gZWxzZSBpZiAoaXNYKG0pKSB7XG4gICAgICByZXQgPSAnPj0nICsgTSArICcuMC4wIDwnICsgKCtNICsgMSkgKyAnLjAuMCdcbiAgICB9IGVsc2UgaWYgKGlzWChwKSkge1xuICAgICAgLy8gfjEuMiA9PSA+PTEuMi4wIDwxLjMuMFxuICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4wIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJ1xuICAgIH0gZWxzZSBpZiAocHIpIHtcbiAgICAgIGRlYnVnKCdyZXBsYWNlVGlsZGUgcHInLCBwcilcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgKyAnLScgKyBwciArXG4gICAgICAgICAgICAnIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJ1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyB+MS4yLjMgPT0gPj0xLjIuMyA8MS4zLjBcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgK1xuICAgICAgICAgICAgJyA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCdcbiAgICB9XG5cbiAgICBkZWJ1ZygndGlsZGUgcmV0dXJuJywgcmV0KVxuICAgIHJldHVybiByZXRcbiAgfSlcbn1cblxuLy8gXiAtLT4gKiAoYW55LCBraW5kYSBzaWxseSlcbi8vIF4yLCBeMi54LCBeMi54LnggLS0+ID49Mi4wLjAgPDMuMC4wXG4vLyBeMi4wLCBeMi4wLnggLS0+ID49Mi4wLjAgPDMuMC4wXG4vLyBeMS4yLCBeMS4yLnggLS0+ID49MS4yLjAgPDIuMC4wXG4vLyBeMS4yLjMgLS0+ID49MS4yLjMgPDIuMC4wXG4vLyBeMS4yLjAgLS0+ID49MS4yLjAgPDIuMC4wXG5mdW5jdGlvbiByZXBsYWNlQ2FyZXRzIChjb21wLCBvcHRpb25zKSB7XG4gIHJldHVybiBjb21wLnRyaW0oKS5zcGxpdCgvXFxzKy8pLm1hcChmdW5jdGlvbiAoY29tcCkge1xuICAgIHJldHVybiByZXBsYWNlQ2FyZXQoY29tcCwgb3B0aW9ucylcbiAgfSkuam9pbignICcpXG59XG5cbmZ1bmN0aW9uIHJlcGxhY2VDYXJldCAoY29tcCwgb3B0aW9ucykge1xuICBkZWJ1ZygnY2FyZXQnLCBjb21wLCBvcHRpb25zKVxuICB2YXIgciA9IG9wdGlvbnMubG9vc2UgPyByZVtDQVJFVExPT1NFXSA6IHJlW0NBUkVUXVxuICByZXR1cm4gY29tcC5yZXBsYWNlKHIsIGZ1bmN0aW9uIChfLCBNLCBtLCBwLCBwcikge1xuICAgIGRlYnVnKCdjYXJldCcsIGNvbXAsIF8sIE0sIG0sIHAsIHByKVxuICAgIHZhciByZXRcblxuICAgIGlmIChpc1goTSkpIHtcbiAgICAgIHJldCA9ICcnXG4gICAgfSBlbHNlIGlmIChpc1gobSkpIHtcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4wLjAgPCcgKyAoK00gKyAxKSArICcuMC4wJ1xuICAgIH0gZWxzZSBpZiAoaXNYKHApKSB7XG4gICAgICBpZiAoTSA9PT0gJzAnKSB7XG4gICAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuMCA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCdcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuMCA8JyArICgrTSArIDEpICsgJy4wLjAnXG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChwcikge1xuICAgICAgZGVidWcoJ3JlcGxhY2VDYXJldCBwcicsIHByKVxuICAgICAgaWYgKE0gPT09ICcwJykge1xuICAgICAgICBpZiAobSA9PT0gJzAnKSB7XG4gICAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArICctJyArIHByICtcbiAgICAgICAgICAgICAgICAnIDwnICsgTSArICcuJyArIG0gKyAnLicgKyAoK3AgKyAxKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgKyAnLScgKyBwciArXG4gICAgICAgICAgICAgICAgJyA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCdcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArICctJyArIHByICtcbiAgICAgICAgICAgICAgJyA8JyArICgrTSArIDEpICsgJy4wLjAnXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlYnVnKCdubyBwcicpXG4gICAgICBpZiAoTSA9PT0gJzAnKSB7XG4gICAgICAgIGlmIChtID09PSAnMCcpIHtcbiAgICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICtcbiAgICAgICAgICAgICAgICAnIDwnICsgTSArICcuJyArIG0gKyAnLicgKyAoK3AgKyAxKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgK1xuICAgICAgICAgICAgICAgICcgPCcgKyBNICsgJy4nICsgKCttICsgMSkgKyAnLjAnXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgK1xuICAgICAgICAgICAgICAnIDwnICsgKCtNICsgMSkgKyAnLjAuMCdcbiAgICAgIH1cbiAgICB9XG5cbiAgICBkZWJ1ZygnY2FyZXQgcmV0dXJuJywgcmV0KVxuICAgIHJldHVybiByZXRcbiAgfSlcbn1cblxuZnVuY3Rpb24gcmVwbGFjZVhSYW5nZXMgKGNvbXAsIG9wdGlvbnMpIHtcbiAgZGVidWcoJ3JlcGxhY2VYUmFuZ2VzJywgY29tcCwgb3B0aW9ucylcbiAgcmV0dXJuIGNvbXAuc3BsaXQoL1xccysvKS5tYXAoZnVuY3Rpb24gKGNvbXApIHtcbiAgICByZXR1cm4gcmVwbGFjZVhSYW5nZShjb21wLCBvcHRpb25zKVxuICB9KS5qb2luKCcgJylcbn1cblxuZnVuY3Rpb24gcmVwbGFjZVhSYW5nZSAoY29tcCwgb3B0aW9ucykge1xuICBjb21wID0gY29tcC50cmltKClcbiAgdmFyIHIgPSBvcHRpb25zLmxvb3NlID8gcmVbWFJBTkdFTE9PU0VdIDogcmVbWFJBTkdFXVxuICByZXR1cm4gY29tcC5yZXBsYWNlKHIsIGZ1bmN0aW9uIChyZXQsIGd0bHQsIE0sIG0sIHAsIHByKSB7XG4gICAgZGVidWcoJ3hSYW5nZScsIGNvbXAsIHJldCwgZ3RsdCwgTSwgbSwgcCwgcHIpXG4gICAgdmFyIHhNID0gaXNYKE0pXG4gICAgdmFyIHhtID0geE0gfHwgaXNYKG0pXG4gICAgdmFyIHhwID0geG0gfHwgaXNYKHApXG4gICAgdmFyIGFueVggPSB4cFxuXG4gICAgaWYgKGd0bHQgPT09ICc9JyAmJiBhbnlYKSB7XG4gICAgICBndGx0ID0gJydcbiAgICB9XG5cbiAgICBpZiAoeE0pIHtcbiAgICAgIGlmIChndGx0ID09PSAnPicgfHwgZ3RsdCA9PT0gJzwnKSB7XG4gICAgICAgIC8vIG5vdGhpbmcgaXMgYWxsb3dlZFxuICAgICAgICByZXQgPSAnPDAuMC4wJ1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gbm90aGluZyBpcyBmb3JiaWRkZW5cbiAgICAgICAgcmV0ID0gJyonXG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChndGx0ICYmIGFueVgpIHtcbiAgICAgIC8vIHdlIGtub3cgcGF0Y2ggaXMgYW4geCwgYmVjYXVzZSB3ZSBoYXZlIGFueSB4IGF0IGFsbC5cbiAgICAgIC8vIHJlcGxhY2UgWCB3aXRoIDBcbiAgICAgIGlmICh4bSkge1xuICAgICAgICBtID0gMFxuICAgICAgfVxuICAgICAgcCA9IDBcblxuICAgICAgaWYgKGd0bHQgPT09ICc+Jykge1xuICAgICAgICAvLyA+MSA9PiA+PTIuMC4wXG4gICAgICAgIC8vID4xLjIgPT4gPj0xLjMuMFxuICAgICAgICAvLyA+MS4yLjMgPT4gPj0gMS4yLjRcbiAgICAgICAgZ3RsdCA9ICc+PSdcbiAgICAgICAgaWYgKHhtKSB7XG4gICAgICAgICAgTSA9ICtNICsgMVxuICAgICAgICAgIG0gPSAwXG4gICAgICAgICAgcCA9IDBcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtID0gK20gKyAxXG4gICAgICAgICAgcCA9IDBcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChndGx0ID09PSAnPD0nKSB7XG4gICAgICAgIC8vIDw9MC43LnggaXMgYWN0dWFsbHkgPDAuOC4wLCBzaW5jZSBhbnkgMC43Lnggc2hvdWxkXG4gICAgICAgIC8vIHBhc3MuICBTaW1pbGFybHksIDw9Ny54IGlzIGFjdHVhbGx5IDw4LjAuMCwgZXRjLlxuICAgICAgICBndGx0ID0gJzwnXG4gICAgICAgIGlmICh4bSkge1xuICAgICAgICAgIE0gPSArTSArIDFcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtID0gK20gKyAxXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0ID0gZ3RsdCArIE0gKyAnLicgKyBtICsgJy4nICsgcFxuICAgIH0gZWxzZSBpZiAoeG0pIHtcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4wLjAgPCcgKyAoK00gKyAxKSArICcuMC4wJ1xuICAgIH0gZWxzZSBpZiAoeHApIHtcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuMCA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCdcbiAgICB9XG5cbiAgICBkZWJ1ZygneFJhbmdlIHJldHVybicsIHJldClcblxuICAgIHJldHVybiByZXRcbiAgfSlcbn1cblxuLy8gQmVjYXVzZSAqIGlzIEFORC1lZCB3aXRoIGV2ZXJ5dGhpbmcgZWxzZSBpbiB0aGUgY29tcGFyYXRvcixcbi8vIGFuZCAnJyBtZWFucyBcImFueSB2ZXJzaW9uXCIsIGp1c3QgcmVtb3ZlIHRoZSAqcyBlbnRpcmVseS5cbmZ1bmN0aW9uIHJlcGxhY2VTdGFycyAoY29tcCwgb3B0aW9ucykge1xuICBkZWJ1ZygncmVwbGFjZVN0YXJzJywgY29tcCwgb3B0aW9ucylcbiAgLy8gTG9vc2VuZXNzIGlzIGlnbm9yZWQgaGVyZS4gIHN0YXIgaXMgYWx3YXlzIGFzIGxvb3NlIGFzIGl0IGdldHMhXG4gIHJldHVybiBjb21wLnRyaW0oKS5yZXBsYWNlKHJlW1NUQVJdLCAnJylcbn1cblxuLy8gVGhpcyBmdW5jdGlvbiBpcyBwYXNzZWQgdG8gc3RyaW5nLnJlcGxhY2UocmVbSFlQSEVOUkFOR0VdKVxuLy8gTSwgbSwgcGF0Y2gsIHByZXJlbGVhc2UsIGJ1aWxkXG4vLyAxLjIgLSAzLjQuNSA9PiA+PTEuMi4wIDw9My40LjVcbi8vIDEuMi4zIC0gMy40ID0+ID49MS4yLjAgPDMuNS4wIEFueSAzLjQueCB3aWxsIGRvXG4vLyAxLjIgLSAzLjQgPT4gPj0xLjIuMCA8My41LjBcbmZ1bmN0aW9uIGh5cGhlblJlcGxhY2UgKCQwLFxuICBmcm9tLCBmTSwgZm0sIGZwLCBmcHIsIGZiLFxuICB0bywgdE0sIHRtLCB0cCwgdHByLCB0Yikge1xuICBpZiAoaXNYKGZNKSkge1xuICAgIGZyb20gPSAnJ1xuICB9IGVsc2UgaWYgKGlzWChmbSkpIHtcbiAgICBmcm9tID0gJz49JyArIGZNICsgJy4wLjAnXG4gIH0gZWxzZSBpZiAoaXNYKGZwKSkge1xuICAgIGZyb20gPSAnPj0nICsgZk0gKyAnLicgKyBmbSArICcuMCdcbiAgfSBlbHNlIHtcbiAgICBmcm9tID0gJz49JyArIGZyb21cbiAgfVxuXG4gIGlmIChpc1godE0pKSB7XG4gICAgdG8gPSAnJ1xuICB9IGVsc2UgaWYgKGlzWCh0bSkpIHtcbiAgICB0byA9ICc8JyArICgrdE0gKyAxKSArICcuMC4wJ1xuICB9IGVsc2UgaWYgKGlzWCh0cCkpIHtcbiAgICB0byA9ICc8JyArIHRNICsgJy4nICsgKCt0bSArIDEpICsgJy4wJ1xuICB9IGVsc2UgaWYgKHRwcikge1xuICAgIHRvID0gJzw9JyArIHRNICsgJy4nICsgdG0gKyAnLicgKyB0cCArICctJyArIHRwclxuICB9IGVsc2Uge1xuICAgIHRvID0gJzw9JyArIHRvXG4gIH1cblxuICByZXR1cm4gKGZyb20gKyAnICcgKyB0bykudHJpbSgpXG59XG5cbi8vIGlmIEFOWSBvZiB0aGUgc2V0cyBtYXRjaCBBTEwgb2YgaXRzIGNvbXBhcmF0b3JzLCB0aGVuIHBhc3NcblJhbmdlLnByb3RvdHlwZS50ZXN0ID0gZnVuY3Rpb24gKHZlcnNpb24pIHtcbiAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBpZiAodHlwZW9mIHZlcnNpb24gPT09ICdzdHJpbmcnKSB7XG4gICAgdmVyc2lvbiA9IG5ldyBTZW1WZXIodmVyc2lvbiwgdGhpcy5vcHRpb25zKVxuICB9XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnNldC5sZW5ndGg7IGkrKykge1xuICAgIGlmICh0ZXN0U2V0KHRoaXMuc2V0W2ldLCB2ZXJzaW9uLCB0aGlzLm9wdGlvbnMpKSB7XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2Vcbn1cblxuZnVuY3Rpb24gdGVzdFNldCAoc2V0LCB2ZXJzaW9uLCBvcHRpb25zKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc2V0Lmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCFzZXRbaV0udGVzdCh2ZXJzaW9uKSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICB9XG5cbiAgaWYgKHZlcnNpb24ucHJlcmVsZWFzZS5sZW5ndGggJiYgIW9wdGlvbnMuaW5jbHVkZVByZXJlbGVhc2UpIHtcbiAgICAvLyBGaW5kIHRoZSBzZXQgb2YgdmVyc2lvbnMgdGhhdCBhcmUgYWxsb3dlZCB0byBoYXZlIHByZXJlbGVhc2VzXG4gICAgLy8gRm9yIGV4YW1wbGUsIF4xLjIuMy1wci4xIGRlc3VnYXJzIHRvID49MS4yLjMtcHIuMSA8Mi4wLjBcbiAgICAvLyBUaGF0IHNob3VsZCBhbGxvdyBgMS4yLjMtcHIuMmAgdG8gcGFzcy5cbiAgICAvLyBIb3dldmVyLCBgMS4yLjQtYWxwaGEubm90cmVhZHlgIHNob3VsZCBOT1QgYmUgYWxsb3dlZCxcbiAgICAvLyBldmVuIHRob3VnaCBpdCdzIHdpdGhpbiB0aGUgcmFuZ2Ugc2V0IGJ5IHRoZSBjb21wYXJhdG9ycy5cbiAgICBmb3IgKGkgPSAwOyBpIDwgc2V0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBkZWJ1ZyhzZXRbaV0uc2VtdmVyKVxuICAgICAgaWYgKHNldFtpXS5zZW12ZXIgPT09IEFOWSkge1xuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBpZiAoc2V0W2ldLnNlbXZlci5wcmVyZWxlYXNlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdmFyIGFsbG93ZWQgPSBzZXRbaV0uc2VtdmVyXG4gICAgICAgIGlmIChhbGxvd2VkLm1ham9yID09PSB2ZXJzaW9uLm1ham9yICYmXG4gICAgICAgICAgICBhbGxvd2VkLm1pbm9yID09PSB2ZXJzaW9uLm1pbm9yICYmXG4gICAgICAgICAgICBhbGxvd2VkLnBhdGNoID09PSB2ZXJzaW9uLnBhdGNoKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFZlcnNpb24gaGFzIGEgLXByZSwgYnV0IGl0J3Mgbm90IG9uZSBvZiB0aGUgb25lcyB3ZSBsaWtlLlxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgcmV0dXJuIHRydWVcbn1cblxuZXhwb3J0cy5zYXRpc2ZpZXMgPSBzYXRpc2ZpZXNcbmZ1bmN0aW9uIHNhdGlzZmllcyAodmVyc2lvbiwgcmFuZ2UsIG9wdGlvbnMpIHtcbiAgdHJ5IHtcbiAgICByYW5nZSA9IG5ldyBSYW5nZShyYW5nZSwgb3B0aW9ucylcbiAgfSBjYXRjaCAoZXIpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuICByZXR1cm4gcmFuZ2UudGVzdCh2ZXJzaW9uKVxufVxuXG5leHBvcnRzLm1heFNhdGlzZnlpbmcgPSBtYXhTYXRpc2Z5aW5nXG5mdW5jdGlvbiBtYXhTYXRpc2Z5aW5nICh2ZXJzaW9ucywgcmFuZ2UsIG9wdGlvbnMpIHtcbiAgdmFyIG1heCA9IG51bGxcbiAgdmFyIG1heFNWID0gbnVsbFxuICB0cnkge1xuICAgIHZhciByYW5nZU9iaiA9IG5ldyBSYW5nZShyYW5nZSwgb3B0aW9ucylcbiAgfSBjYXRjaCAoZXIpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG4gIHZlcnNpb25zLmZvckVhY2goZnVuY3Rpb24gKHYpIHtcbiAgICBpZiAocmFuZ2VPYmoudGVzdCh2KSkge1xuICAgICAgLy8gc2F0aXNmaWVzKHYsIHJhbmdlLCBvcHRpb25zKVxuICAgICAgaWYgKCFtYXggfHwgbWF4U1YuY29tcGFyZSh2KSA9PT0gLTEpIHtcbiAgICAgICAgLy8gY29tcGFyZShtYXgsIHYsIHRydWUpXG4gICAgICAgIG1heCA9IHZcbiAgICAgICAgbWF4U1YgPSBuZXcgU2VtVmVyKG1heCwgb3B0aW9ucylcbiAgICAgIH1cbiAgICB9XG4gIH0pXG4gIHJldHVybiBtYXhcbn1cblxuZXhwb3J0cy5taW5TYXRpc2Z5aW5nID0gbWluU2F0aXNmeWluZ1xuZnVuY3Rpb24gbWluU2F0aXNmeWluZyAodmVyc2lvbnMsIHJhbmdlLCBvcHRpb25zKSB7XG4gIHZhciBtaW4gPSBudWxsXG4gIHZhciBtaW5TViA9IG51bGxcbiAgdHJ5IHtcbiAgICB2YXIgcmFuZ2VPYmogPSBuZXcgUmFuZ2UocmFuZ2UsIG9wdGlvbnMpXG4gIH0gY2F0Y2ggKGVyKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuICB2ZXJzaW9ucy5mb3JFYWNoKGZ1bmN0aW9uICh2KSB7XG4gICAgaWYgKHJhbmdlT2JqLnRlc3QodikpIHtcbiAgICAgIC8vIHNhdGlzZmllcyh2LCByYW5nZSwgb3B0aW9ucylcbiAgICAgIGlmICghbWluIHx8IG1pblNWLmNvbXBhcmUodikgPT09IDEpIHtcbiAgICAgICAgLy8gY29tcGFyZShtaW4sIHYsIHRydWUpXG4gICAgICAgIG1pbiA9IHZcbiAgICAgICAgbWluU1YgPSBuZXcgU2VtVmVyKG1pbiwgb3B0aW9ucylcbiAgICAgIH1cbiAgICB9XG4gIH0pXG4gIHJldHVybiBtaW5cbn1cblxuZXhwb3J0cy5taW5WZXJzaW9uID0gbWluVmVyc2lvblxuZnVuY3Rpb24gbWluVmVyc2lvbiAocmFuZ2UsIGxvb3NlKSB7XG4gIHJhbmdlID0gbmV3IFJhbmdlKHJhbmdlLCBsb29zZSlcblxuICB2YXIgbWludmVyID0gbmV3IFNlbVZlcignMC4wLjAnKVxuICBpZiAocmFuZ2UudGVzdChtaW52ZXIpKSB7XG4gICAgcmV0dXJuIG1pbnZlclxuICB9XG5cbiAgbWludmVyID0gbmV3IFNlbVZlcignMC4wLjAtMCcpXG4gIGlmIChyYW5nZS50ZXN0KG1pbnZlcikpIHtcbiAgICByZXR1cm4gbWludmVyXG4gIH1cblxuICBtaW52ZXIgPSBudWxsXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmFuZ2Uuc2V0Lmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIGNvbXBhcmF0b3JzID0gcmFuZ2Uuc2V0W2ldXG5cbiAgICBjb21wYXJhdG9ycy5mb3JFYWNoKGZ1bmN0aW9uIChjb21wYXJhdG9yKSB7XG4gICAgICAvLyBDbG9uZSB0byBhdm9pZCBtYW5pcHVsYXRpbmcgdGhlIGNvbXBhcmF0b3IncyBzZW12ZXIgb2JqZWN0LlxuICAgICAgdmFyIGNvbXB2ZXIgPSBuZXcgU2VtVmVyKGNvbXBhcmF0b3Iuc2VtdmVyLnZlcnNpb24pXG4gICAgICBzd2l0Y2ggKGNvbXBhcmF0b3Iub3BlcmF0b3IpIHtcbiAgICAgICAgY2FzZSAnPic6XG4gICAgICAgICAgaWYgKGNvbXB2ZXIucHJlcmVsZWFzZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGNvbXB2ZXIucGF0Y2grK1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb21wdmVyLnByZXJlbGVhc2UucHVzaCgwKVxuICAgICAgICAgIH1cbiAgICAgICAgICBjb21wdmVyLnJhdyA9IGNvbXB2ZXIuZm9ybWF0KClcbiAgICAgICAgICAvKiBmYWxsdGhyb3VnaCAqL1xuICAgICAgICBjYXNlICcnOlxuICAgICAgICBjYXNlICc+PSc6XG4gICAgICAgICAgaWYgKCFtaW52ZXIgfHwgZ3QobWludmVyLCBjb21wdmVyKSkge1xuICAgICAgICAgICAgbWludmVyID0gY29tcHZlclxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlICc8JzpcbiAgICAgICAgY2FzZSAnPD0nOlxuICAgICAgICAgIC8qIElnbm9yZSBtYXhpbXVtIHZlcnNpb25zICovXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgb3BlcmF0aW9uOiAnICsgY29tcGFyYXRvci5vcGVyYXRvcilcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgaWYgKG1pbnZlciAmJiByYW5nZS50ZXN0KG1pbnZlcikpIHtcbiAgICByZXR1cm4gbWludmVyXG4gIH1cblxuICByZXR1cm4gbnVsbFxufVxuXG5leHBvcnRzLnZhbGlkUmFuZ2UgPSB2YWxpZFJhbmdlXG5mdW5jdGlvbiB2YWxpZFJhbmdlIChyYW5nZSwgb3B0aW9ucykge1xuICB0cnkge1xuICAgIC8vIFJldHVybiAnKicgaW5zdGVhZCBvZiAnJyBzbyB0aGF0IHRydXRoaW5lc3Mgd29ya3MuXG4gICAgLy8gVGhpcyB3aWxsIHRocm93IGlmIGl0J3MgaW52YWxpZCBhbnl3YXlcbiAgICByZXR1cm4gbmV3IFJhbmdlKHJhbmdlLCBvcHRpb25zKS5yYW5nZSB8fCAnKidcbiAgfSBjYXRjaCAoZXIpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG59XG5cbi8vIERldGVybWluZSBpZiB2ZXJzaW9uIGlzIGxlc3MgdGhhbiBhbGwgdGhlIHZlcnNpb25zIHBvc3NpYmxlIGluIHRoZSByYW5nZVxuZXhwb3J0cy5sdHIgPSBsdHJcbmZ1bmN0aW9uIGx0ciAodmVyc2lvbiwgcmFuZ2UsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIG91dHNpZGUodmVyc2lvbiwgcmFuZ2UsICc8Jywgb3B0aW9ucylcbn1cblxuLy8gRGV0ZXJtaW5lIGlmIHZlcnNpb24gaXMgZ3JlYXRlciB0aGFuIGFsbCB0aGUgdmVyc2lvbnMgcG9zc2libGUgaW4gdGhlIHJhbmdlLlxuZXhwb3J0cy5ndHIgPSBndHJcbmZ1bmN0aW9uIGd0ciAodmVyc2lvbiwgcmFuZ2UsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIG91dHNpZGUodmVyc2lvbiwgcmFuZ2UsICc+Jywgb3B0aW9ucylcbn1cblxuZXhwb3J0cy5vdXRzaWRlID0gb3V0c2lkZVxuZnVuY3Rpb24gb3V0c2lkZSAodmVyc2lvbiwgcmFuZ2UsIGhpbG8sIG9wdGlvbnMpIHtcbiAgdmVyc2lvbiA9IG5ldyBTZW1WZXIodmVyc2lvbiwgb3B0aW9ucylcbiAgcmFuZ2UgPSBuZXcgUmFuZ2UocmFuZ2UsIG9wdGlvbnMpXG5cbiAgdmFyIGd0Zm4sIGx0ZWZuLCBsdGZuLCBjb21wLCBlY29tcFxuICBzd2l0Y2ggKGhpbG8pIHtcbiAgICBjYXNlICc+JzpcbiAgICAgIGd0Zm4gPSBndFxuICAgICAgbHRlZm4gPSBsdGVcbiAgICAgIGx0Zm4gPSBsdFxuICAgICAgY29tcCA9ICc+J1xuICAgICAgZWNvbXAgPSAnPj0nXG4gICAgICBicmVha1xuICAgIGNhc2UgJzwnOlxuICAgICAgZ3RmbiA9IGx0XG4gICAgICBsdGVmbiA9IGd0ZVxuICAgICAgbHRmbiA9IGd0XG4gICAgICBjb21wID0gJzwnXG4gICAgICBlY29tcCA9ICc8PSdcbiAgICAgIGJyZWFrXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ011c3QgcHJvdmlkZSBhIGhpbG8gdmFsIG9mIFwiPFwiIG9yIFwiPlwiJylcbiAgfVxuXG4gIC8vIElmIGl0IHNhdGlzaWZlcyB0aGUgcmFuZ2UgaXQgaXMgbm90IG91dHNpZGVcbiAgaWYgKHNhdGlzZmllcyh2ZXJzaW9uLCByYW5nZSwgb3B0aW9ucykpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8vIEZyb20gbm93IG9uLCB2YXJpYWJsZSB0ZXJtcyBhcmUgYXMgaWYgd2UncmUgaW4gXCJndHJcIiBtb2RlLlxuICAvLyBidXQgbm90ZSB0aGF0IGV2ZXJ5dGhpbmcgaXMgZmxpcHBlZCBmb3IgdGhlIFwibHRyXCIgZnVuY3Rpb24uXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCByYW5nZS5zZXQubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgY29tcGFyYXRvcnMgPSByYW5nZS5zZXRbaV1cblxuICAgIHZhciBoaWdoID0gbnVsbFxuICAgIHZhciBsb3cgPSBudWxsXG5cbiAgICBjb21wYXJhdG9ycy5mb3JFYWNoKGZ1bmN0aW9uIChjb21wYXJhdG9yKSB7XG4gICAgICBpZiAoY29tcGFyYXRvci5zZW12ZXIgPT09IEFOWSkge1xuICAgICAgICBjb21wYXJhdG9yID0gbmV3IENvbXBhcmF0b3IoJz49MC4wLjAnKVxuICAgICAgfVxuICAgICAgaGlnaCA9IGhpZ2ggfHwgY29tcGFyYXRvclxuICAgICAgbG93ID0gbG93IHx8IGNvbXBhcmF0b3JcbiAgICAgIGlmIChndGZuKGNvbXBhcmF0b3Iuc2VtdmVyLCBoaWdoLnNlbXZlciwgb3B0aW9ucykpIHtcbiAgICAgICAgaGlnaCA9IGNvbXBhcmF0b3JcbiAgICAgIH0gZWxzZSBpZiAobHRmbihjb21wYXJhdG9yLnNlbXZlciwgbG93LnNlbXZlciwgb3B0aW9ucykpIHtcbiAgICAgICAgbG93ID0gY29tcGFyYXRvclxuICAgICAgfVxuICAgIH0pXG5cbiAgICAvLyBJZiB0aGUgZWRnZSB2ZXJzaW9uIGNvbXBhcmF0b3IgaGFzIGEgb3BlcmF0b3IgdGhlbiBvdXIgdmVyc2lvblxuICAgIC8vIGlzbid0IG91dHNpZGUgaXRcbiAgICBpZiAoaGlnaC5vcGVyYXRvciA9PT0gY29tcCB8fCBoaWdoLm9wZXJhdG9yID09PSBlY29tcCkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gSWYgdGhlIGxvd2VzdCB2ZXJzaW9uIGNvbXBhcmF0b3IgaGFzIGFuIG9wZXJhdG9yIGFuZCBvdXIgdmVyc2lvblxuICAgIC8vIGlzIGxlc3MgdGhhbiBpdCB0aGVuIGl0IGlzbid0IGhpZ2hlciB0aGFuIHRoZSByYW5nZVxuICAgIGlmICgoIWxvdy5vcGVyYXRvciB8fCBsb3cub3BlcmF0b3IgPT09IGNvbXApICYmXG4gICAgICAgIGx0ZWZuKHZlcnNpb24sIGxvdy5zZW12ZXIpKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9IGVsc2UgaWYgKGxvdy5vcGVyYXRvciA9PT0gZWNvbXAgJiYgbHRmbih2ZXJzaW9uLCBsb3cuc2VtdmVyKSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlXG59XG5cbmV4cG9ydHMucHJlcmVsZWFzZSA9IHByZXJlbGVhc2VcbmZ1bmN0aW9uIHByZXJlbGVhc2UgKHZlcnNpb24sIG9wdGlvbnMpIHtcbiAgdmFyIHBhcnNlZCA9IHBhcnNlKHZlcnNpb24sIG9wdGlvbnMpXG4gIHJldHVybiAocGFyc2VkICYmIHBhcnNlZC5wcmVyZWxlYXNlLmxlbmd0aCkgPyBwYXJzZWQucHJlcmVsZWFzZSA6IG51bGxcbn1cblxuZXhwb3J0cy5pbnRlcnNlY3RzID0gaW50ZXJzZWN0c1xuZnVuY3Rpb24gaW50ZXJzZWN0cyAocjEsIHIyLCBvcHRpb25zKSB7XG4gIHIxID0gbmV3IFJhbmdlKHIxLCBvcHRpb25zKVxuICByMiA9IG5ldyBSYW5nZShyMiwgb3B0aW9ucylcbiAgcmV0dXJuIHIxLmludGVyc2VjdHMocjIpXG59XG5cbmV4cG9ydHMuY29lcmNlID0gY29lcmNlXG5mdW5jdGlvbiBjb2VyY2UgKHZlcnNpb24pIHtcbiAgaWYgKHZlcnNpb24gaW5zdGFuY2VvZiBTZW1WZXIpIHtcbiAgICByZXR1cm4gdmVyc2lvblxuICB9XG5cbiAgaWYgKHR5cGVvZiB2ZXJzaW9uICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICB2YXIgbWF0Y2ggPSB2ZXJzaW9uLm1hdGNoKHJlW0NPRVJDRV0pXG5cbiAgaWYgKG1hdGNoID09IG51bGwpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgcmV0dXJuIHBhcnNlKG1hdGNoWzFdICtcbiAgICAnLicgKyAobWF0Y2hbMl0gfHwgJzAnKSArXG4gICAgJy4nICsgKG1hdGNoWzNdIHx8ICcwJykpXG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliL3R1bm5lbCcpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgbmV0ID0gcmVxdWlyZSgnbmV0Jyk7XG52YXIgdGxzID0gcmVxdWlyZSgndGxzJyk7XG52YXIgaHR0cCA9IHJlcXVpcmUoJ2h0dHAnKTtcbnZhciBodHRwcyA9IHJlcXVpcmUoJ2h0dHBzJyk7XG52YXIgZXZlbnRzID0gcmVxdWlyZSgnZXZlbnRzJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcblxuXG5leHBvcnRzLmh0dHBPdmVySHR0cCA9IGh0dHBPdmVySHR0cDtcbmV4cG9ydHMuaHR0cHNPdmVySHR0cCA9IGh0dHBzT3Zlckh0dHA7XG5leHBvcnRzLmh0dHBPdmVySHR0cHMgPSBodHRwT3Zlckh0dHBzO1xuZXhwb3J0cy5odHRwc092ZXJIdHRwcyA9IGh0dHBzT3Zlckh0dHBzO1xuXG5cbmZ1bmN0aW9uIGh0dHBPdmVySHR0cChvcHRpb25zKSB7XG4gIHZhciBhZ2VudCA9IG5ldyBUdW5uZWxpbmdBZ2VudChvcHRpb25zKTtcbiAgYWdlbnQucmVxdWVzdCA9IGh0dHAucmVxdWVzdDtcbiAgcmV0dXJuIGFnZW50O1xufVxuXG5mdW5jdGlvbiBodHRwc092ZXJIdHRwKG9wdGlvbnMpIHtcbiAgdmFyIGFnZW50ID0gbmV3IFR1bm5lbGluZ0FnZW50KG9wdGlvbnMpO1xuICBhZ2VudC5yZXF1ZXN0ID0gaHR0cC5yZXF1ZXN0O1xuICBhZ2VudC5jcmVhdGVTb2NrZXQgPSBjcmVhdGVTZWN1cmVTb2NrZXQ7XG4gIHJldHVybiBhZ2VudDtcbn1cblxuZnVuY3Rpb24gaHR0cE92ZXJIdHRwcyhvcHRpb25zKSB7XG4gIHZhciBhZ2VudCA9IG5ldyBUdW5uZWxpbmdBZ2VudChvcHRpb25zKTtcbiAgYWdlbnQucmVxdWVzdCA9IGh0dHBzLnJlcXVlc3Q7XG4gIHJldHVybiBhZ2VudDtcbn1cblxuZnVuY3Rpb24gaHR0cHNPdmVySHR0cHMob3B0aW9ucykge1xuICB2YXIgYWdlbnQgPSBuZXcgVHVubmVsaW5nQWdlbnQob3B0aW9ucyk7XG4gIGFnZW50LnJlcXVlc3QgPSBodHRwcy5yZXF1ZXN0O1xuICBhZ2VudC5jcmVhdGVTb2NrZXQgPSBjcmVhdGVTZWN1cmVTb2NrZXQ7XG4gIHJldHVybiBhZ2VudDtcbn1cblxuXG5mdW5jdGlvbiBUdW5uZWxpbmdBZ2VudChvcHRpb25zKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgc2VsZi5vcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgc2VsZi5wcm94eU9wdGlvbnMgPSBzZWxmLm9wdGlvbnMucHJveHkgfHwge307XG4gIHNlbGYubWF4U29ja2V0cyA9IHNlbGYub3B0aW9ucy5tYXhTb2NrZXRzIHx8IGh0dHAuQWdlbnQuZGVmYXVsdE1heFNvY2tldHM7XG4gIHNlbGYucmVxdWVzdHMgPSBbXTtcbiAgc2VsZi5zb2NrZXRzID0gW107XG5cbiAgc2VsZi5vbignZnJlZScsIGZ1bmN0aW9uIG9uRnJlZShzb2NrZXQsIGhvc3QsIHBvcnQsIGxvY2FsQWRkcmVzcykge1xuICAgIHZhciBvcHRpb25zID0gdG9PcHRpb25zKGhvc3QsIHBvcnQsIGxvY2FsQWRkcmVzcyk7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHNlbGYucmVxdWVzdHMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgIHZhciBwZW5kaW5nID0gc2VsZi5yZXF1ZXN0c1tpXTtcbiAgICAgIGlmIChwZW5kaW5nLmhvc3QgPT09IG9wdGlvbnMuaG9zdCAmJiBwZW5kaW5nLnBvcnQgPT09IG9wdGlvbnMucG9ydCkge1xuICAgICAgICAvLyBEZXRlY3QgdGhlIHJlcXVlc3QgdG8gY29ubmVjdCBzYW1lIG9yaWdpbiBzZXJ2ZXIsXG4gICAgICAgIC8vIHJldXNlIHRoZSBjb25uZWN0aW9uLlxuICAgICAgICBzZWxmLnJlcXVlc3RzLnNwbGljZShpLCAxKTtcbiAgICAgICAgcGVuZGluZy5yZXF1ZXN0Lm9uU29ja2V0KHNvY2tldCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gICAgc29ja2V0LmRlc3Ryb3koKTtcbiAgICBzZWxmLnJlbW92ZVNvY2tldChzb2NrZXQpO1xuICB9KTtcbn1cbnV0aWwuaW5oZXJpdHMoVHVubmVsaW5nQWdlbnQsIGV2ZW50cy5FdmVudEVtaXR0ZXIpO1xuXG5UdW5uZWxpbmdBZ2VudC5wcm90b3R5cGUuYWRkUmVxdWVzdCA9IGZ1bmN0aW9uIGFkZFJlcXVlc3QocmVxLCBob3N0LCBwb3J0LCBsb2NhbEFkZHJlc3MpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgb3B0aW9ucyA9IG1lcmdlT3B0aW9ucyh7cmVxdWVzdDogcmVxfSwgc2VsZi5vcHRpb25zLCB0b09wdGlvbnMoaG9zdCwgcG9ydCwgbG9jYWxBZGRyZXNzKSk7XG5cbiAgaWYgKHNlbGYuc29ja2V0cy5sZW5ndGggPj0gdGhpcy5tYXhTb2NrZXRzKSB7XG4gICAgLy8gV2UgYXJlIG92ZXIgbGltaXQgc28gd2UnbGwgYWRkIGl0IHRvIHRoZSBxdWV1ZS5cbiAgICBzZWxmLnJlcXVlc3RzLnB1c2gob3B0aW9ucyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gSWYgd2UgYXJlIHVuZGVyIG1heFNvY2tldHMgY3JlYXRlIGEgbmV3IG9uZS5cbiAgc2VsZi5jcmVhdGVTb2NrZXQob3B0aW9ucywgZnVuY3Rpb24oc29ja2V0KSB7XG4gICAgc29ja2V0Lm9uKCdmcmVlJywgb25GcmVlKTtcbiAgICBzb2NrZXQub24oJ2Nsb3NlJywgb25DbG9zZU9yUmVtb3ZlKTtcbiAgICBzb2NrZXQub24oJ2FnZW50UmVtb3ZlJywgb25DbG9zZU9yUmVtb3ZlKTtcbiAgICByZXEub25Tb2NrZXQoc29ja2V0KTtcblxuICAgIGZ1bmN0aW9uIG9uRnJlZSgpIHtcbiAgICAgIHNlbGYuZW1pdCgnZnJlZScsIHNvY2tldCwgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gb25DbG9zZU9yUmVtb3ZlKGVycikge1xuICAgICAgc2VsZi5yZW1vdmVTb2NrZXQoc29ja2V0KTtcbiAgICAgIHNvY2tldC5yZW1vdmVMaXN0ZW5lcignZnJlZScsIG9uRnJlZSk7XG4gICAgICBzb2NrZXQucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25DbG9zZU9yUmVtb3ZlKTtcbiAgICAgIHNvY2tldC5yZW1vdmVMaXN0ZW5lcignYWdlbnRSZW1vdmUnLCBvbkNsb3NlT3JSZW1vdmUpO1xuICAgIH1cbiAgfSk7XG59O1xuXG5UdW5uZWxpbmdBZ2VudC5wcm90b3R5cGUuY3JlYXRlU29ja2V0ID0gZnVuY3Rpb24gY3JlYXRlU29ja2V0KG9wdGlvbnMsIGNiKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIHBsYWNlaG9sZGVyID0ge307XG4gIHNlbGYuc29ja2V0cy5wdXNoKHBsYWNlaG9sZGVyKTtcblxuICB2YXIgY29ubmVjdE9wdGlvbnMgPSBtZXJnZU9wdGlvbnMoe30sIHNlbGYucHJveHlPcHRpb25zLCB7XG4gICAgbWV0aG9kOiAnQ09OTkVDVCcsXG4gICAgcGF0aDogb3B0aW9ucy5ob3N0ICsgJzonICsgb3B0aW9ucy5wb3J0LFxuICAgIGFnZW50OiBmYWxzZVxuICB9KTtcbiAgaWYgKGNvbm5lY3RPcHRpb25zLnByb3h5QXV0aCkge1xuICAgIGNvbm5lY3RPcHRpb25zLmhlYWRlcnMgPSBjb25uZWN0T3B0aW9ucy5oZWFkZXJzIHx8IHt9O1xuICAgIGNvbm5lY3RPcHRpb25zLmhlYWRlcnNbJ1Byb3h5LUF1dGhvcml6YXRpb24nXSA9ICdCYXNpYyAnICtcbiAgICAgICAgbmV3IEJ1ZmZlcihjb25uZWN0T3B0aW9ucy5wcm94eUF1dGgpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgfVxuXG4gIGRlYnVnKCdtYWtpbmcgQ09OTkVDVCByZXF1ZXN0Jyk7XG4gIHZhciBjb25uZWN0UmVxID0gc2VsZi5yZXF1ZXN0KGNvbm5lY3RPcHRpb25zKTtcbiAgY29ubmVjdFJlcS51c2VDaHVua2VkRW5jb2RpbmdCeURlZmF1bHQgPSBmYWxzZTsgLy8gZm9yIHYwLjZcbiAgY29ubmVjdFJlcS5vbmNlKCdyZXNwb25zZScsIG9uUmVzcG9uc2UpOyAvLyBmb3IgdjAuNlxuICBjb25uZWN0UmVxLm9uY2UoJ3VwZ3JhZGUnLCBvblVwZ3JhZGUpOyAgIC8vIGZvciB2MC42XG4gIGNvbm5lY3RSZXEub25jZSgnY29ubmVjdCcsIG9uQ29ubmVjdCk7ICAgLy8gZm9yIHYwLjcgb3IgbGF0ZXJcbiAgY29ubmVjdFJlcS5vbmNlKCdlcnJvcicsIG9uRXJyb3IpO1xuICBjb25uZWN0UmVxLmVuZCgpO1xuXG4gIGZ1bmN0aW9uIG9uUmVzcG9uc2UocmVzKSB7XG4gICAgLy8gVmVyeSBoYWNreS4gVGhpcyBpcyBuZWNlc3NhcnkgdG8gYXZvaWQgaHR0cC1wYXJzZXIgbGVha3MuXG4gICAgcmVzLnVwZ3JhZGUgPSB0cnVlO1xuICB9XG5cbiAgZnVuY3Rpb24gb25VcGdyYWRlKHJlcywgc29ja2V0LCBoZWFkKSB7XG4gICAgLy8gSGFja3kuXG4gICAgcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbigpIHtcbiAgICAgIG9uQ29ubmVjdChyZXMsIHNvY2tldCwgaGVhZCk7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBvbkNvbm5lY3QocmVzLCBzb2NrZXQsIGhlYWQpIHtcbiAgICBjb25uZWN0UmVxLnJlbW92ZUFsbExpc3RlbmVycygpO1xuICAgIHNvY2tldC5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcblxuICAgIGlmIChyZXMuc3RhdHVzQ29kZSA9PT0gMjAwKSB7XG4gICAgICBhc3NlcnQuZXF1YWwoaGVhZC5sZW5ndGgsIDApO1xuICAgICAgZGVidWcoJ3R1bm5lbGluZyBjb25uZWN0aW9uIGhhcyBlc3RhYmxpc2hlZCcpO1xuICAgICAgc2VsZi5zb2NrZXRzW3NlbGYuc29ja2V0cy5pbmRleE9mKHBsYWNlaG9sZGVyKV0gPSBzb2NrZXQ7XG4gICAgICBjYihzb2NrZXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWJ1ZygndHVubmVsaW5nIHNvY2tldCBjb3VsZCBub3QgYmUgZXN0YWJsaXNoZWQsIHN0YXR1c0NvZGU9JWQnLFxuICAgICAgICAgICAgcmVzLnN0YXR1c0NvZGUpO1xuICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCd0dW5uZWxpbmcgc29ja2V0IGNvdWxkIG5vdCBiZSBlc3RhYmxpc2hlZCwgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0YXR1c0NvZGU9JyArIHJlcy5zdGF0dXNDb2RlKTtcbiAgICAgIGVycm9yLmNvZGUgPSAnRUNPTk5SRVNFVCc7XG4gICAgICBvcHRpb25zLnJlcXVlc3QuZW1pdCgnZXJyb3InLCBlcnJvcik7XG4gICAgICBzZWxmLnJlbW92ZVNvY2tldChwbGFjZWhvbGRlcik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb25FcnJvcihjYXVzZSkge1xuICAgIGNvbm5lY3RSZXEucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG5cbiAgICBkZWJ1ZygndHVubmVsaW5nIHNvY2tldCBjb3VsZCBub3QgYmUgZXN0YWJsaXNoZWQsIGNhdXNlPSVzXFxuJyxcbiAgICAgICAgICBjYXVzZS5tZXNzYWdlLCBjYXVzZS5zdGFjayk7XG4gICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCd0dW5uZWxpbmcgc29ja2V0IGNvdWxkIG5vdCBiZSBlc3RhYmxpc2hlZCwgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdjYXVzZT0nICsgY2F1c2UubWVzc2FnZSk7XG4gICAgZXJyb3IuY29kZSA9ICdFQ09OTlJFU0VUJztcbiAgICBvcHRpb25zLnJlcXVlc3QuZW1pdCgnZXJyb3InLCBlcnJvcik7XG4gICAgc2VsZi5yZW1vdmVTb2NrZXQocGxhY2Vob2xkZXIpO1xuICB9XG59O1xuXG5UdW5uZWxpbmdBZ2VudC5wcm90b3R5cGUucmVtb3ZlU29ja2V0ID0gZnVuY3Rpb24gcmVtb3ZlU29ja2V0KHNvY2tldCkge1xuICB2YXIgcG9zID0gdGhpcy5zb2NrZXRzLmluZGV4T2Yoc29ja2V0KVxuICBpZiAocG9zID09PSAtMSkge1xuICAgIHJldHVybjtcbiAgfVxuICB0aGlzLnNvY2tldHMuc3BsaWNlKHBvcywgMSk7XG5cbiAgdmFyIHBlbmRpbmcgPSB0aGlzLnJlcXVlc3RzLnNoaWZ0KCk7XG4gIGlmIChwZW5kaW5nKSB7XG4gICAgLy8gSWYgd2UgaGF2ZSBwZW5kaW5nIHJlcXVlc3RzIGFuZCBhIHNvY2tldCBnZXRzIGNsb3NlZCBhIG5ldyBvbmVcbiAgICAvLyBuZWVkcyB0byBiZSBjcmVhdGVkIHRvIHRha2Ugb3ZlciBpbiB0aGUgcG9vbCBmb3IgdGhlIG9uZSB0aGF0IGNsb3NlZC5cbiAgICB0aGlzLmNyZWF0ZVNvY2tldChwZW5kaW5nLCBmdW5jdGlvbihzb2NrZXQpIHtcbiAgICAgIHBlbmRpbmcucmVxdWVzdC5vblNvY2tldChzb2NrZXQpO1xuICAgIH0pO1xuICB9XG59O1xuXG5mdW5jdGlvbiBjcmVhdGVTZWN1cmVTb2NrZXQob3B0aW9ucywgY2IpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBUdW5uZWxpbmdBZ2VudC5wcm90b3R5cGUuY3JlYXRlU29ja2V0LmNhbGwoc2VsZiwgb3B0aW9ucywgZnVuY3Rpb24oc29ja2V0KSB7XG4gICAgdmFyIGhvc3RIZWFkZXIgPSBvcHRpb25zLnJlcXVlc3QuZ2V0SGVhZGVyKCdob3N0Jyk7XG4gICAgdmFyIHRsc09wdGlvbnMgPSBtZXJnZU9wdGlvbnMoe30sIHNlbGYub3B0aW9ucywge1xuICAgICAgc29ja2V0OiBzb2NrZXQsXG4gICAgICBzZXJ2ZXJuYW1lOiBob3N0SGVhZGVyID8gaG9zdEhlYWRlci5yZXBsYWNlKC86LiokLywgJycpIDogb3B0aW9ucy5ob3N0XG4gICAgfSk7XG5cbiAgICAvLyAwIGlzIGR1bW15IHBvcnQgZm9yIHYwLjZcbiAgICB2YXIgc2VjdXJlU29ja2V0ID0gdGxzLmNvbm5lY3QoMCwgdGxzT3B0aW9ucyk7XG4gICAgc2VsZi5zb2NrZXRzW3NlbGYuc29ja2V0cy5pbmRleE9mKHNvY2tldCldID0gc2VjdXJlU29ja2V0O1xuICAgIGNiKHNlY3VyZVNvY2tldCk7XG4gIH0pO1xufVxuXG5cbmZ1bmN0aW9uIHRvT3B0aW9ucyhob3N0LCBwb3J0LCBsb2NhbEFkZHJlc3MpIHtcbiAgaWYgKHR5cGVvZiBob3N0ID09PSAnc3RyaW5nJykgeyAvLyBzaW5jZSB2MC4xMFxuICAgIHJldHVybiB7XG4gICAgICBob3N0OiBob3N0LFxuICAgICAgcG9ydDogcG9ydCxcbiAgICAgIGxvY2FsQWRkcmVzczogbG9jYWxBZGRyZXNzXG4gICAgfTtcbiAgfVxuICByZXR1cm4gaG9zdDsgLy8gZm9yIHYwLjExIG9yIGxhdGVyXG59XG5cbmZ1bmN0aW9uIG1lcmdlT3B0aW9ucyh0YXJnZXQpIHtcbiAgZm9yICh2YXIgaSA9IDEsIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgIHZhciBvdmVycmlkZXMgPSBhcmd1bWVudHNbaV07XG4gICAgaWYgKHR5cGVvZiBvdmVycmlkZXMgPT09ICdvYmplY3QnKSB7XG4gICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG92ZXJyaWRlcyk7XG4gICAgICBmb3IgKHZhciBqID0gMCwga2V5TGVuID0ga2V5cy5sZW5ndGg7IGogPCBrZXlMZW47ICsraikge1xuICAgICAgICB2YXIgayA9IGtleXNbal07XG4gICAgICAgIGlmIChvdmVycmlkZXNba10gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRhcmdldFtrXSA9IG92ZXJyaWRlc1trXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5cbnZhciBkZWJ1ZztcbmlmIChwcm9jZXNzLmVudi5OT0RFX0RFQlVHICYmIC9cXGJ0dW5uZWxcXGIvLnRlc3QocHJvY2Vzcy5lbnYuTk9ERV9ERUJVRykpIHtcbiAgZGVidWcgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgaWYgKHR5cGVvZiBhcmdzWzBdID09PSAnc3RyaW5nJykge1xuICAgICAgYXJnc1swXSA9ICdUVU5ORUw6ICcgKyBhcmdzWzBdO1xuICAgIH0gZWxzZSB7XG4gICAgICBhcmdzLnVuc2hpZnQoJ1RVTk5FTDonKTtcbiAgICB9XG4gICAgY29uc29sZS5lcnJvci5hcHBseShjb25zb2xlLCBhcmdzKTtcbiAgfVxufSBlbHNlIHtcbiAgZGVidWcgPSBmdW5jdGlvbigpIHt9O1xufVxuZXhwb3J0cy5kZWJ1ZyA9IGRlYnVnOyAvLyBmb3IgdGVzdFxuIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0LiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuIFNlZSBMSUNFTlNFIGZpbGUgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgZnVsbCBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG52YXIgX19hd2FpdGVyID0gKHRoaXMgJiYgdGhpcy5fX2F3YWl0ZXIpIHx8IGZ1bmN0aW9uICh0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUocmVzdWx0LnZhbHVlKTsgfSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59O1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbmNvbnN0IHVybCA9IHJlcXVpcmUoXCJ1cmxcIik7XHJcbmNvbnN0IGh0dHAgPSByZXF1aXJlKFwiaHR0cFwiKTtcclxuY29uc3QgaHR0cHMgPSByZXF1aXJlKFwiaHR0cHNcIik7XHJcbmNvbnN0IHV0aWwgPSByZXF1aXJlKFwiLi9VdGlsXCIpO1xyXG5sZXQgZnM7XHJcbmxldCB0dW5uZWw7XHJcbnZhciBIdHRwQ29kZXM7XHJcbihmdW5jdGlvbiAoSHR0cENvZGVzKSB7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiT0tcIl0gPSAyMDBdID0gXCJPS1wiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIk11bHRpcGxlQ2hvaWNlc1wiXSA9IDMwMF0gPSBcIk11bHRpcGxlQ2hvaWNlc1wiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIk1vdmVkUGVybWFuZW50bHlcIl0gPSAzMDFdID0gXCJNb3ZlZFBlcm1hbmVudGx5XCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiUmVzb3VyY2VNb3ZlZFwiXSA9IDMwMl0gPSBcIlJlc291cmNlTW92ZWRcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJTZWVPdGhlclwiXSA9IDMwM10gPSBcIlNlZU90aGVyXCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiTm90TW9kaWZpZWRcIl0gPSAzMDRdID0gXCJOb3RNb2RpZmllZFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlVzZVByb3h5XCJdID0gMzA1XSA9IFwiVXNlUHJveHlcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJTd2l0Y2hQcm94eVwiXSA9IDMwNl0gPSBcIlN3aXRjaFByb3h5XCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiVGVtcG9yYXJ5UmVkaXJlY3RcIl0gPSAzMDddID0gXCJUZW1wb3JhcnlSZWRpcmVjdFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlBlcm1hbmVudFJlZGlyZWN0XCJdID0gMzA4XSA9IFwiUGVybWFuZW50UmVkaXJlY3RcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJCYWRSZXF1ZXN0XCJdID0gNDAwXSA9IFwiQmFkUmVxdWVzdFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlVuYXV0aG9yaXplZFwiXSA9IDQwMV0gPSBcIlVuYXV0aG9yaXplZFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlBheW1lbnRSZXF1aXJlZFwiXSA9IDQwMl0gPSBcIlBheW1lbnRSZXF1aXJlZFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIkZvcmJpZGRlblwiXSA9IDQwM10gPSBcIkZvcmJpZGRlblwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIk5vdEZvdW5kXCJdID0gNDA0XSA9IFwiTm90Rm91bmRcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJNZXRob2ROb3RBbGxvd2VkXCJdID0gNDA1XSA9IFwiTWV0aG9kTm90QWxsb3dlZFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIk5vdEFjY2VwdGFibGVcIl0gPSA0MDZdID0gXCJOb3RBY2NlcHRhYmxlXCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiUHJveHlBdXRoZW50aWNhdGlvblJlcXVpcmVkXCJdID0gNDA3XSA9IFwiUHJveHlBdXRoZW50aWNhdGlvblJlcXVpcmVkXCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiUmVxdWVzdFRpbWVvdXRcIl0gPSA0MDhdID0gXCJSZXF1ZXN0VGltZW91dFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIkNvbmZsaWN0XCJdID0gNDA5XSA9IFwiQ29uZmxpY3RcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJHb25lXCJdID0gNDEwXSA9IFwiR29uZVwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlRvb01hbnlSZXF1ZXN0c1wiXSA9IDQyOV0gPSBcIlRvb01hbnlSZXF1ZXN0c1wiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIkludGVybmFsU2VydmVyRXJyb3JcIl0gPSA1MDBdID0gXCJJbnRlcm5hbFNlcnZlckVycm9yXCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiTm90SW1wbGVtZW50ZWRcIl0gPSA1MDFdID0gXCJOb3RJbXBsZW1lbnRlZFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIkJhZEdhdGV3YXlcIl0gPSA1MDJdID0gXCJCYWRHYXRld2F5XCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiU2VydmljZVVuYXZhaWxhYmxlXCJdID0gNTAzXSA9IFwiU2VydmljZVVuYXZhaWxhYmxlXCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiR2F0ZXdheVRpbWVvdXRcIl0gPSA1MDRdID0gXCJHYXRld2F5VGltZW91dFwiO1xyXG59KShIdHRwQ29kZXMgPSBleHBvcnRzLkh0dHBDb2RlcyB8fCAoZXhwb3J0cy5IdHRwQ29kZXMgPSB7fSkpO1xyXG5jb25zdCBIdHRwUmVkaXJlY3RDb2RlcyA9IFtIdHRwQ29kZXMuTW92ZWRQZXJtYW5lbnRseSwgSHR0cENvZGVzLlJlc291cmNlTW92ZWQsIEh0dHBDb2Rlcy5TZWVPdGhlciwgSHR0cENvZGVzLlRlbXBvcmFyeVJlZGlyZWN0LCBIdHRwQ29kZXMuUGVybWFuZW50UmVkaXJlY3RdO1xyXG5jb25zdCBIdHRwUmVzcG9uc2VSZXRyeUNvZGVzID0gW0h0dHBDb2Rlcy5CYWRHYXRld2F5LCBIdHRwQ29kZXMuU2VydmljZVVuYXZhaWxhYmxlLCBIdHRwQ29kZXMuR2F0ZXdheVRpbWVvdXRdO1xyXG5jb25zdCBSZXRyeWFibGVIdHRwVmVyYnMgPSBbJ09QVElPTlMnLCAnR0VUJywgJ0RFTEVURScsICdIRUFEJ107XHJcbmNvbnN0IEV4cG9uZW50aWFsQmFja29mZkNlaWxpbmcgPSAxMDtcclxuY29uc3QgRXhwb25lbnRpYWxCYWNrb2ZmVGltZVNsaWNlID0gNTtcclxuY2xhc3MgSHR0cENsaWVudFJlc3BvbnNlIHtcclxuICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UpIHtcclxuICAgICAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xyXG4gICAgfVxyXG4gICAgcmVhZEJvZHkoKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcclxuICAgICAgICAgICAgbGV0IGJ1ZmZlciA9IEJ1ZmZlci5hbGxvYygwKTtcclxuICAgICAgICAgICAgY29uc3QgZW5jb2RpbmdDaGFyc2V0ID0gdXRpbC5vYnRhaW5Db250ZW50Q2hhcnNldCh0aGlzKTtcclxuICAgICAgICAgICAgLy8gRXh0cmFjdCBFbmNvZGluZyBmcm9tIGhlYWRlcjogJ2NvbnRlbnQtZW5jb2RpbmcnXHJcbiAgICAgICAgICAgIC8vIE1hdGNoIGBnemlwYCwgYGd6aXAsIGRlZmxhdGVgIHZhcmlhdGlvbnMgb2YgR1pJUCBlbmNvZGluZ1xyXG4gICAgICAgICAgICBjb25zdCBjb250ZW50RW5jb2RpbmcgPSB0aGlzLm1lc3NhZ2UuaGVhZGVyc1snY29udGVudC1lbmNvZGluZyddIHx8ICcnO1xyXG4gICAgICAgICAgICBjb25zdCBpc0d6aXBwZWRFbmNvZGVkID0gbmV3IFJlZ0V4cCgnKGd6aXAkKXwoZ3ppcCwgKmRlZmxhdGUpJykudGVzdChjb250ZW50RW5jb2RpbmcpO1xyXG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2Uub24oJ2RhdGEnLCBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY2h1bmsgPSAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSA/IEJ1ZmZlci5mcm9tKGRhdGEsIGVuY29kaW5nQ2hhcnNldCkgOiBkYXRhO1xyXG4gICAgICAgICAgICAgICAgYnVmZmVyID0gQnVmZmVyLmNvbmNhdChbYnVmZmVyLCBjaHVua10pO1xyXG4gICAgICAgICAgICB9KS5vbignZW5kJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNHemlwcGVkRW5jb2RlZCkgeyAvLyBQcm9jZXNzIEdaaXBwZWQgUmVzcG9uc2UgQm9keSBIRVJFXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGd1bnppcHBlZEJvZHkgPSB5aWVsZCB1dGlsLmRlY29tcHJlc3NHemlwcGVkQ29udGVudChidWZmZXIsIGVuY29kaW5nQ2hhcnNldCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoZ3VuemlwcGVkQm9keSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoYnVmZmVyLnRvU3RyaW5nKGVuY29kaW5nQ2hhcnNldCkpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pLm9uKCdlcnJvcicsIGZ1bmN0aW9uIChlcnIpIHtcclxuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KSk7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy5IdHRwQ2xpZW50UmVzcG9uc2UgPSBIdHRwQ2xpZW50UmVzcG9uc2U7XHJcbmZ1bmN0aW9uIGlzSHR0cHMocmVxdWVzdFVybCkge1xyXG4gICAgbGV0IHBhcnNlZFVybCA9IHVybC5wYXJzZShyZXF1ZXN0VXJsKTtcclxuICAgIHJldHVybiBwYXJzZWRVcmwucHJvdG9jb2wgPT09ICdodHRwczonO1xyXG59XHJcbmV4cG9ydHMuaXNIdHRwcyA9IGlzSHR0cHM7XHJcbnZhciBFbnZpcm9ubWVudFZhcmlhYmxlcztcclxuKGZ1bmN0aW9uIChFbnZpcm9ubWVudFZhcmlhYmxlcykge1xyXG4gICAgRW52aXJvbm1lbnRWYXJpYWJsZXNbXCJIVFRQX1BST1hZXCJdID0gXCJIVFRQX1BST1hZXCI7XHJcbiAgICBFbnZpcm9ubWVudFZhcmlhYmxlc1tcIkhUVFBTX1BST1hZXCJdID0gXCJIVFRQU19QUk9YWVwiO1xyXG4gICAgRW52aXJvbm1lbnRWYXJpYWJsZXNbXCJOT19QUk9YWVwiXSA9IFwiTk9fUFJPWFlcIjtcclxufSkoRW52aXJvbm1lbnRWYXJpYWJsZXMgfHwgKEVudmlyb25tZW50VmFyaWFibGVzID0ge30pKTtcclxuY2xhc3MgSHR0cENsaWVudCB7XHJcbiAgICBjb25zdHJ1Y3Rvcih1c2VyQWdlbnQsIGhhbmRsZXJzLCByZXF1ZXN0T3B0aW9ucykge1xyXG4gICAgICAgIHRoaXMuX2lnbm9yZVNzbEVycm9yID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5fYWxsb3dSZWRpcmVjdHMgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuX2FsbG93UmVkaXJlY3REb3duZ3JhZGUgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLl9tYXhSZWRpcmVjdHMgPSA1MDtcclxuICAgICAgICB0aGlzLl9hbGxvd1JldHJpZXMgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLl9tYXhSZXRyaWVzID0gMTtcclxuICAgICAgICB0aGlzLl9rZWVwQWxpdmUgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLl9kaXNwb3NlZCA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMudXNlckFnZW50ID0gdXNlckFnZW50O1xyXG4gICAgICAgIHRoaXMuaGFuZGxlcnMgPSBoYW5kbGVycyB8fCBbXTtcclxuICAgICAgICBsZXQgbm9fcHJveHkgPSBwcm9jZXNzLmVudltFbnZpcm9ubWVudFZhcmlhYmxlcy5OT19QUk9YWV07XHJcbiAgICAgICAgaWYgKG5vX3Byb3h5KSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2h0dHBQcm94eUJ5cGFzc0hvc3RzID0gW107XHJcbiAgICAgICAgICAgIG5vX3Byb3h5LnNwbGl0KCcsJykuZm9yRWFjaChieXBhc3MgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5faHR0cFByb3h5QnlwYXNzSG9zdHMucHVzaChuZXcgUmVnRXhwKGJ5cGFzcywgJ2knKSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnJlcXVlc3RPcHRpb25zID0gcmVxdWVzdE9wdGlvbnM7XHJcbiAgICAgICAgaWYgKHJlcXVlc3RPcHRpb25zKSB7XHJcbiAgICAgICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5pZ25vcmVTc2xFcnJvciAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9pZ25vcmVTc2xFcnJvciA9IHJlcXVlc3RPcHRpb25zLmlnbm9yZVNzbEVycm9yO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuX3NvY2tldFRpbWVvdXQgPSByZXF1ZXN0T3B0aW9ucy5zb2NrZXRUaW1lb3V0O1xyXG4gICAgICAgICAgICB0aGlzLl9odHRwUHJveHkgPSByZXF1ZXN0T3B0aW9ucy5wcm94eTtcclxuICAgICAgICAgICAgaWYgKHJlcXVlc3RPcHRpb25zLnByb3h5ICYmIHJlcXVlc3RPcHRpb25zLnByb3h5LnByb3h5QnlwYXNzSG9zdHMpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2h0dHBQcm94eUJ5cGFzc0hvc3RzID0gW107XHJcbiAgICAgICAgICAgICAgICByZXF1ZXN0T3B0aW9ucy5wcm94eS5wcm94eUJ5cGFzc0hvc3RzLmZvckVhY2goYnlwYXNzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9odHRwUHJveHlCeXBhc3NIb3N0cy5wdXNoKG5ldyBSZWdFeHAoYnlwYXNzLCAnaScpKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuX2NlcnRDb25maWcgPSByZXF1ZXN0T3B0aW9ucy5jZXJ0O1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fY2VydENvbmZpZykge1xyXG4gICAgICAgICAgICAgICAgLy8gSWYgdXNpbmcgY2VydCwgbmVlZCBmc1xyXG4gICAgICAgICAgICAgICAgZnMgPSByZXF1aXJlKCdmcycpO1xyXG4gICAgICAgICAgICAgICAgLy8gY2FjaGUgdGhlIGNlcnQgY29udGVudCBpbnRvIG1lbW9yeSwgc28gd2UgZG9uJ3QgaGF2ZSB0byByZWFkIGl0IGZyb20gZGlzayBldmVyeSB0aW1lXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fY2VydENvbmZpZy5jYUZpbGUgJiYgZnMuZXhpc3RzU3luYyh0aGlzLl9jZXJ0Q29uZmlnLmNhRmlsZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jYSA9IGZzLnJlYWRGaWxlU3luYyh0aGlzLl9jZXJ0Q29uZmlnLmNhRmlsZSwgJ3V0ZjgnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9jZXJ0Q29uZmlnLmNlcnRGaWxlICYmIGZzLmV4aXN0c1N5bmModGhpcy5fY2VydENvbmZpZy5jZXJ0RmlsZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jZXJ0ID0gZnMucmVhZEZpbGVTeW5jKHRoaXMuX2NlcnRDb25maWcuY2VydEZpbGUsICd1dGY4Jyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fY2VydENvbmZpZy5rZXlGaWxlICYmIGZzLmV4aXN0c1N5bmModGhpcy5fY2VydENvbmZpZy5rZXlGaWxlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2tleSA9IGZzLnJlYWRGaWxlU3luYyh0aGlzLl9jZXJ0Q29uZmlnLmtleUZpbGUsICd1dGY4Jyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHJlcXVlc3RPcHRpb25zLmFsbG93UmVkaXJlY3RzICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2FsbG93UmVkaXJlY3RzID0gcmVxdWVzdE9wdGlvbnMuYWxsb3dSZWRpcmVjdHM7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHJlcXVlc3RPcHRpb25zLmFsbG93UmVkaXJlY3REb3duZ3JhZGUgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fYWxsb3dSZWRpcmVjdERvd25ncmFkZSA9IHJlcXVlc3RPcHRpb25zLmFsbG93UmVkaXJlY3REb3duZ3JhZGU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHJlcXVlc3RPcHRpb25zLm1heFJlZGlyZWN0cyAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9tYXhSZWRpcmVjdHMgPSBNYXRoLm1heChyZXF1ZXN0T3B0aW9ucy5tYXhSZWRpcmVjdHMsIDApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5rZWVwQWxpdmUgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fa2VlcEFsaXZlID0gcmVxdWVzdE9wdGlvbnMua2VlcEFsaXZlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5hbGxvd1JldHJpZXMgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fYWxsb3dSZXRyaWVzID0gcmVxdWVzdE9wdGlvbnMuYWxsb3dSZXRyaWVzO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5tYXhSZXRyaWVzICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX21heFJldHJpZXMgPSByZXF1ZXN0T3B0aW9ucy5tYXhSZXRyaWVzO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgb3B0aW9ucyhyZXF1ZXN0VXJsLCBhZGRpdGlvbmFsSGVhZGVycykge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QoJ09QVElPTlMnLCByZXF1ZXN0VXJsLCBudWxsLCBhZGRpdGlvbmFsSGVhZGVycyB8fCB7fSk7XHJcbiAgICB9XHJcbiAgICBnZXQocmVxdWVzdFVybCwgYWRkaXRpb25hbEhlYWRlcnMpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KCdHRVQnLCByZXF1ZXN0VXJsLCBudWxsLCBhZGRpdGlvbmFsSGVhZGVycyB8fCB7fSk7XHJcbiAgICB9XHJcbiAgICBkZWwocmVxdWVzdFVybCwgYWRkaXRpb25hbEhlYWRlcnMpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KCdERUxFVEUnLCByZXF1ZXN0VXJsLCBudWxsLCBhZGRpdGlvbmFsSGVhZGVycyB8fCB7fSk7XHJcbiAgICB9XHJcbiAgICBwb3N0KHJlcXVlc3RVcmwsIGRhdGEsIGFkZGl0aW9uYWxIZWFkZXJzKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdCgnUE9TVCcsIHJlcXVlc3RVcmwsIGRhdGEsIGFkZGl0aW9uYWxIZWFkZXJzIHx8IHt9KTtcclxuICAgIH1cclxuICAgIHBhdGNoKHJlcXVlc3RVcmwsIGRhdGEsIGFkZGl0aW9uYWxIZWFkZXJzKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdCgnUEFUQ0gnLCByZXF1ZXN0VXJsLCBkYXRhLCBhZGRpdGlvbmFsSGVhZGVycyB8fCB7fSk7XHJcbiAgICB9XHJcbiAgICBwdXQocmVxdWVzdFVybCwgZGF0YSwgYWRkaXRpb25hbEhlYWRlcnMpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KCdQVVQnLCByZXF1ZXN0VXJsLCBkYXRhLCBhZGRpdGlvbmFsSGVhZGVycyB8fCB7fSk7XHJcbiAgICB9XHJcbiAgICBoZWFkKHJlcXVlc3RVcmwsIGFkZGl0aW9uYWxIZWFkZXJzKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdCgnSEVBRCcsIHJlcXVlc3RVcmwsIG51bGwsIGFkZGl0aW9uYWxIZWFkZXJzIHx8IHt9KTtcclxuICAgIH1cclxuICAgIHNlbmRTdHJlYW0odmVyYiwgcmVxdWVzdFVybCwgc3RyZWFtLCBhZGRpdGlvbmFsSGVhZGVycykge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QodmVyYiwgcmVxdWVzdFVybCwgc3RyZWFtLCBhZGRpdGlvbmFsSGVhZGVycyk7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIE1ha2VzIGEgcmF3IGh0dHAgcmVxdWVzdC5cclxuICAgICAqIEFsbCBvdGhlciBtZXRob2RzIHN1Y2ggYXMgZ2V0LCBwb3N0LCBwYXRjaCwgYW5kIHJlcXVlc3QgdWx0aW1hdGVseSBjYWxsIHRoaXMuXHJcbiAgICAgKiBQcmVmZXIgZ2V0LCBkZWwsIHBvc3QgYW5kIHBhdGNoXHJcbiAgICAgKi9cclxuICAgIHJlcXVlc3QodmVyYiwgcmVxdWVzdFVybCwgZGF0YSwgaGVhZGVycykge1xyXG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9kaXNwb3NlZCkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2xpZW50IGhhcyBhbHJlYWR5IGJlZW4gZGlzcG9zZWQuXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGxldCBwYXJzZWRVcmwgPSB1cmwucGFyc2UocmVxdWVzdFVybCk7XHJcbiAgICAgICAgICAgIGxldCBpbmZvID0gdGhpcy5fcHJlcGFyZVJlcXVlc3QodmVyYiwgcGFyc2VkVXJsLCBoZWFkZXJzKTtcclxuICAgICAgICAgICAgLy8gT25seSBwZXJmb3JtIHJldHJpZXMgb24gcmVhZHMgc2luY2Ugd3JpdGVzIG1heSBub3QgYmUgaWRlbXBvdGVudC5cclxuICAgICAgICAgICAgbGV0IG1heFRyaWVzID0gKHRoaXMuX2FsbG93UmV0cmllcyAmJiBSZXRyeWFibGVIdHRwVmVyYnMuaW5kZXhPZih2ZXJiKSAhPSAtMSkgPyB0aGlzLl9tYXhSZXRyaWVzICsgMSA6IDE7XHJcbiAgICAgICAgICAgIGxldCBudW1UcmllcyA9IDA7XHJcbiAgICAgICAgICAgIGxldCByZXNwb25zZTtcclxuICAgICAgICAgICAgd2hpbGUgKG51bVRyaWVzIDwgbWF4VHJpZXMpIHtcclxuICAgICAgICAgICAgICAgIHJlc3BvbnNlID0geWllbGQgdGhpcy5yZXF1ZXN0UmF3KGluZm8sIGRhdGEpO1xyXG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgaXQncyBhbiBhdXRoZW50aWNhdGlvbiBjaGFsbGVuZ2VcclxuICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZSAmJiByZXNwb25zZS5tZXNzYWdlICYmIHJlc3BvbnNlLm1lc3NhZ2Uuc3RhdHVzQ29kZSA9PT0gSHR0cENvZGVzLlVuYXV0aG9yaXplZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBhdXRoZW50aWNhdGlvbkhhbmRsZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmhhbmRsZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmhhbmRsZXJzW2ldLmNhbkhhbmRsZUF1dGhlbnRpY2F0aW9uKHJlc3BvbnNlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXV0aGVudGljYXRpb25IYW5kbGVyID0gdGhpcy5oYW5kbGVyc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhdXRoZW50aWNhdGlvbkhhbmRsZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF1dGhlbnRpY2F0aW9uSGFuZGxlci5oYW5kbGVBdXRoZW50aWNhdGlvbih0aGlzLCBpbmZvLCBkYXRhKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIGhhdmUgcmVjZWl2ZWQgYW4gdW5hdXRob3JpemVkIHJlc3BvbnNlIGJ1dCBoYXZlIG5vIGhhbmRsZXJzIHRvIGhhbmRsZSBpdC5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gTGV0IHRoZSByZXNwb25zZSByZXR1cm4gdG8gdGhlIGNhbGxlci5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxldCByZWRpcmVjdHNSZW1haW5pbmcgPSB0aGlzLl9tYXhSZWRpcmVjdHM7XHJcbiAgICAgICAgICAgICAgICB3aGlsZSAoSHR0cFJlZGlyZWN0Q29kZXMuaW5kZXhPZihyZXNwb25zZS5tZXNzYWdlLnN0YXR1c0NvZGUpICE9IC0xXHJcbiAgICAgICAgICAgICAgICAgICAgJiYgdGhpcy5fYWxsb3dSZWRpcmVjdHNcclxuICAgICAgICAgICAgICAgICAgICAmJiByZWRpcmVjdHNSZW1haW5pbmcgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVkaXJlY3RVcmwgPSByZXNwb25zZS5tZXNzYWdlLmhlYWRlcnNbXCJsb2NhdGlvblwiXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXJlZGlyZWN0VXJsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoZXJlJ3Mgbm8gbG9jYXRpb24gdG8gcmVkaXJlY3QgdG8sIHdlIHdvbid0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBsZXQgcGFyc2VkUmVkaXJlY3RVcmwgPSB1cmwucGFyc2UocmVkaXJlY3RVcmwpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZWRVcmwucHJvdG9jb2wgPT0gJ2h0dHBzOicgJiYgcGFyc2VkVXJsLnByb3RvY29sICE9IHBhcnNlZFJlZGlyZWN0VXJsLnByb3RvY29sICYmICF0aGlzLl9hbGxvd1JlZGlyZWN0RG93bmdyYWRlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlZGlyZWN0IGZyb20gSFRUUFMgdG8gSFRUUCBwcm90b2NvbC4gVGhpcyBkb3duZ3JhZGUgaXMgbm90IGFsbG93ZWQgZm9yIHNlY3VyaXR5IHJlYXNvbnMuIElmIHlvdSB3YW50IHRvIGFsbG93IHRoaXMgYmVoYXZpb3IsIHNldCB0aGUgYWxsb3dSZWRpcmVjdERvd25ncmFkZSBvcHRpb24gdG8gdHJ1ZS5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHdlIG5lZWQgdG8gZmluaXNoIHJlYWRpbmcgdGhlIHJlc3BvbnNlIGJlZm9yZSByZWFzc2lnbmluZyByZXNwb25zZVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHdoaWNoIHdpbGwgbGVhayB0aGUgb3BlbiBzb2NrZXQuXHJcbiAgICAgICAgICAgICAgICAgICAgeWllbGQgcmVzcG9uc2UucmVhZEJvZHkoKTtcclxuICAgICAgICAgICAgICAgICAgICAvLyBsZXQncyBtYWtlIHRoZSByZXF1ZXN0IHdpdGggdGhlIG5ldyByZWRpcmVjdFVybFxyXG4gICAgICAgICAgICAgICAgICAgIGluZm8gPSB0aGlzLl9wcmVwYXJlUmVxdWVzdCh2ZXJiLCBwYXJzZWRSZWRpcmVjdFVybCwgaGVhZGVycyk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSB5aWVsZCB0aGlzLnJlcXVlc3RSYXcoaW5mbywgZGF0YSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVkaXJlY3RzUmVtYWluaW5nLS07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoSHR0cFJlc3BvbnNlUmV0cnlDb2Rlcy5pbmRleE9mKHJlc3BvbnNlLm1lc3NhZ2Uuc3RhdHVzQ29kZSkgPT0gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBJZiBub3QgYSByZXRyeSBjb2RlLCByZXR1cm4gaW1tZWRpYXRlbHkgaW5zdGVhZCBvZiByZXRyeWluZ1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIG51bVRyaWVzICs9IDE7XHJcbiAgICAgICAgICAgICAgICBpZiAobnVtVHJpZXMgPCBtYXhUcmllcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHlpZWxkIHJlc3BvbnNlLnJlYWRCb2R5KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgeWllbGQgdGhpcy5fcGVyZm9ybUV4cG9uZW50aWFsQmFja29mZihudW1Ucmllcyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBOZWVkcyB0byBiZSBjYWxsZWQgaWYga2VlcEFsaXZlIGlzIHNldCB0byB0cnVlIGluIHJlcXVlc3Qgb3B0aW9ucy5cclxuICAgICAqL1xyXG4gICAgZGlzcG9zZSgpIHtcclxuICAgICAgICBpZiAodGhpcy5fYWdlbnQpIHtcclxuICAgICAgICAgICAgdGhpcy5fYWdlbnQuZGVzdHJveSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9kaXNwb3NlZCA9IHRydWU7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIFJhdyByZXF1ZXN0LlxyXG4gICAgICogQHBhcmFtIGluZm9cclxuICAgICAqIEBwYXJhbSBkYXRhXHJcbiAgICAgKi9cclxuICAgIHJlcXVlc3RSYXcoaW5mbywgZGF0YSkge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgIGxldCBjYWxsYmFja0ZvclJlc3VsdCA9IGZ1bmN0aW9uIChlcnIsIHJlcykge1xyXG4gICAgICAgICAgICAgICAgaWYgKGVycikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShyZXMpO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB0aGlzLnJlcXVlc3RSYXdXaXRoQ2FsbGJhY2soaW5mbywgZGF0YSwgY2FsbGJhY2tGb3JSZXN1bHQpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBSYXcgcmVxdWVzdCB3aXRoIGNhbGxiYWNrLlxyXG4gICAgICogQHBhcmFtIGluZm9cclxuICAgICAqIEBwYXJhbSBkYXRhXHJcbiAgICAgKiBAcGFyYW0gb25SZXN1bHRcclxuICAgICAqL1xyXG4gICAgcmVxdWVzdFJhd1dpdGhDYWxsYmFjayhpbmZvLCBkYXRhLCBvblJlc3VsdCkge1xyXG4gICAgICAgIGxldCBzb2NrZXQ7XHJcbiAgICAgICAgbGV0IGlzRGF0YVN0cmluZyA9IHR5cGVvZiAoZGF0YSkgPT09ICdzdHJpbmcnO1xyXG4gICAgICAgIGlmICh0eXBlb2YgKGRhdGEpID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICBpbmZvLm9wdGlvbnMuaGVhZGVyc1tcIkNvbnRlbnQtTGVuZ3RoXCJdID0gQnVmZmVyLmJ5dGVMZW5ndGgoZGF0YSwgJ3V0ZjgnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgbGV0IGNhbGxiYWNrQ2FsbGVkID0gZmFsc2U7XHJcbiAgICAgICAgbGV0IGhhbmRsZVJlc3VsdCA9IChlcnIsIHJlcykgPT4ge1xyXG4gICAgICAgICAgICBpZiAoIWNhbGxiYWNrQ2FsbGVkKSB7XHJcbiAgICAgICAgICAgICAgICBjYWxsYmFja0NhbGxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBvblJlc3VsdChlcnIsIHJlcyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIGxldCByZXEgPSBpbmZvLmh0dHBNb2R1bGUucmVxdWVzdChpbmZvLm9wdGlvbnMsIChtc2cpID0+IHtcclxuICAgICAgICAgICAgbGV0IHJlcyA9IG5ldyBIdHRwQ2xpZW50UmVzcG9uc2UobXNnKTtcclxuICAgICAgICAgICAgaGFuZGxlUmVzdWx0KG51bGwsIHJlcyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmVxLm9uKCdzb2NrZXQnLCAoc29jaykgPT4ge1xyXG4gICAgICAgICAgICBzb2NrZXQgPSBzb2NrO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIElmIHdlIGV2ZXIgZ2V0IGRpc2Nvbm5lY3RlZCwgd2Ugd2FudCB0aGUgc29ja2V0IHRvIHRpbWVvdXQgZXZlbnR1YWxseVxyXG4gICAgICAgIHJlcS5zZXRUaW1lb3V0KHRoaXMuX3NvY2tldFRpbWVvdXQgfHwgMyAqIDYwMDAwLCAoKSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChzb2NrZXQpIHtcclxuICAgICAgICAgICAgICAgIHNvY2tldC5lbmQoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBoYW5kbGVSZXN1bHQobmV3IEVycm9yKCdSZXF1ZXN0IHRpbWVvdXQ6ICcgKyBpbmZvLm9wdGlvbnMucGF0aCksIG51bGwpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJlcS5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyKSB7XHJcbiAgICAgICAgICAgIC8vIGVyciBoYXMgc3RhdHVzQ29kZSBwcm9wZXJ0eVxyXG4gICAgICAgICAgICAvLyByZXMgc2hvdWxkIGhhdmUgaGVhZGVyc1xyXG4gICAgICAgICAgICBoYW5kbGVSZXN1bHQoZXJyLCBudWxsKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBpZiAoZGF0YSAmJiB0eXBlb2YgKGRhdGEpID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICByZXEud3JpdGUoZGF0YSwgJ3V0ZjgnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGRhdGEgJiYgdHlwZW9mIChkYXRhKSAhPT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgZGF0YS5vbignY2xvc2UnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICByZXEuZW5kKCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBkYXRhLnBpcGUocmVxKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHJlcS5lbmQoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBfcHJlcGFyZVJlcXVlc3QobWV0aG9kLCByZXF1ZXN0VXJsLCBoZWFkZXJzKSB7XHJcbiAgICAgICAgY29uc3QgaW5mbyA9IHt9O1xyXG4gICAgICAgIGluZm8ucGFyc2VkVXJsID0gcmVxdWVzdFVybDtcclxuICAgICAgICBjb25zdCB1c2luZ1NzbCA9IGluZm8ucGFyc2VkVXJsLnByb3RvY29sID09PSAnaHR0cHM6JztcclxuICAgICAgICBpbmZvLmh0dHBNb2R1bGUgPSB1c2luZ1NzbCA/IGh0dHBzIDogaHR0cDtcclxuICAgICAgICBjb25zdCBkZWZhdWx0UG9ydCA9IHVzaW5nU3NsID8gNDQzIDogODA7XHJcbiAgICAgICAgaW5mby5vcHRpb25zID0ge307XHJcbiAgICAgICAgaW5mby5vcHRpb25zLmhvc3QgPSBpbmZvLnBhcnNlZFVybC5ob3N0bmFtZTtcclxuICAgICAgICBpbmZvLm9wdGlvbnMucG9ydCA9IGluZm8ucGFyc2VkVXJsLnBvcnQgPyBwYXJzZUludChpbmZvLnBhcnNlZFVybC5wb3J0KSA6IGRlZmF1bHRQb3J0O1xyXG4gICAgICAgIGluZm8ub3B0aW9ucy5wYXRoID0gKGluZm8ucGFyc2VkVXJsLnBhdGhuYW1lIHx8ICcnKSArIChpbmZvLnBhcnNlZFVybC5zZWFyY2ggfHwgJycpO1xyXG4gICAgICAgIGluZm8ub3B0aW9ucy5tZXRob2QgPSBtZXRob2Q7XHJcbiAgICAgICAgaW5mby5vcHRpb25zLmhlYWRlcnMgPSB0aGlzLl9tZXJnZUhlYWRlcnMoaGVhZGVycyk7XHJcbiAgICAgICAgaWYgKHRoaXMudXNlckFnZW50ICE9IG51bGwpIHtcclxuICAgICAgICAgICAgaW5mby5vcHRpb25zLmhlYWRlcnNbXCJ1c2VyLWFnZW50XCJdID0gdGhpcy51c2VyQWdlbnQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGluZm8ub3B0aW9ucy5hZ2VudCA9IHRoaXMuX2dldEFnZW50KGluZm8ucGFyc2VkVXJsKTtcclxuICAgICAgICAvLyBnaXZlcyBoYW5kbGVycyBhbiBvcHBvcnR1bml0eSB0byBwYXJ0aWNpcGF0ZVxyXG4gICAgICAgIGlmICh0aGlzLmhhbmRsZXJzICYmICF0aGlzLl9pc1ByZXNpZ25lZCh1cmwuZm9ybWF0KHJlcXVlc3RVcmwpKSkge1xyXG4gICAgICAgICAgICB0aGlzLmhhbmRsZXJzLmZvckVhY2goKGhhbmRsZXIpID0+IHtcclxuICAgICAgICAgICAgICAgIGhhbmRsZXIucHJlcGFyZVJlcXVlc3QoaW5mby5vcHRpb25zKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBpbmZvO1xyXG4gICAgfVxyXG4gICAgX2lzUHJlc2lnbmVkKHJlcXVlc3RVcmwpIHtcclxuICAgICAgICBpZiAodGhpcy5yZXF1ZXN0T3B0aW9ucyAmJiB0aGlzLnJlcXVlc3RPcHRpb25zLnByZXNpZ25lZFVybFBhdHRlcm5zKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHBhdHRlcm5zID0gdGhpcy5yZXF1ZXN0T3B0aW9ucy5wcmVzaWduZWRVcmxQYXR0ZXJucztcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXR0ZXJucy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlcXVlc3RVcmwubWF0Y2gocGF0dGVybnNbaV0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgX21lcmdlSGVhZGVycyhoZWFkZXJzKSB7XHJcbiAgICAgICAgY29uc3QgbG93ZXJjYXNlS2V5cyA9IG9iaiA9PiBPYmplY3Qua2V5cyhvYmopLnJlZHVjZSgoYywgaykgPT4gKGNbay50b0xvd2VyQ2FzZSgpXSA9IG9ialtrXSwgYyksIHt9KTtcclxuICAgICAgICBpZiAodGhpcy5yZXF1ZXN0T3B0aW9ucyAmJiB0aGlzLnJlcXVlc3RPcHRpb25zLmhlYWRlcnMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIGxvd2VyY2FzZUtleXModGhpcy5yZXF1ZXN0T3B0aW9ucy5oZWFkZXJzKSwgbG93ZXJjYXNlS2V5cyhoZWFkZXJzKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBsb3dlcmNhc2VLZXlzKGhlYWRlcnMgfHwge30pO1xyXG4gICAgfVxyXG4gICAgX2dldEFnZW50KHBhcnNlZFVybCkge1xyXG4gICAgICAgIGxldCBhZ2VudDtcclxuICAgICAgICBsZXQgcHJveHkgPSB0aGlzLl9nZXRQcm94eShwYXJzZWRVcmwpO1xyXG4gICAgICAgIGxldCB1c2VQcm94eSA9IHByb3h5LnByb3h5VXJsICYmIHByb3h5LnByb3h5VXJsLmhvc3RuYW1lICYmICF0aGlzLl9pc01hdGNoSW5CeXBhc3NQcm94eUxpc3QocGFyc2VkVXJsKTtcclxuICAgICAgICBpZiAodGhpcy5fa2VlcEFsaXZlICYmIHVzZVByb3h5KSB7XHJcbiAgICAgICAgICAgIGFnZW50ID0gdGhpcy5fcHJveHlBZ2VudDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMuX2tlZXBBbGl2ZSAmJiAhdXNlUHJveHkpIHtcclxuICAgICAgICAgICAgYWdlbnQgPSB0aGlzLl9hZ2VudDtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gaWYgYWdlbnQgaXMgYWxyZWFkeSBhc3NpZ25lZCB1c2UgdGhhdCBhZ2VudC5cclxuICAgICAgICBpZiAoISFhZ2VudCkge1xyXG4gICAgICAgICAgICByZXR1cm4gYWdlbnQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHVzaW5nU3NsID0gcGFyc2VkVXJsLnByb3RvY29sID09PSAnaHR0cHM6JztcclxuICAgICAgICBsZXQgbWF4U29ja2V0cyA9IDEwMDtcclxuICAgICAgICBpZiAoISF0aGlzLnJlcXVlc3RPcHRpb25zKSB7XHJcbiAgICAgICAgICAgIG1heFNvY2tldHMgPSB0aGlzLnJlcXVlc3RPcHRpb25zLm1heFNvY2tldHMgfHwgaHR0cC5nbG9iYWxBZ2VudC5tYXhTb2NrZXRzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodXNlUHJveHkpIHtcclxuICAgICAgICAgICAgLy8gSWYgdXNpbmcgcHJveHksIG5lZWQgdHVubmVsXHJcbiAgICAgICAgICAgIGlmICghdHVubmVsKSB7XHJcbiAgICAgICAgICAgICAgICB0dW5uZWwgPSByZXF1aXJlKCd0dW5uZWwnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb25zdCBhZ2VudE9wdGlvbnMgPSB7XHJcbiAgICAgICAgICAgICAgICBtYXhTb2NrZXRzOiBtYXhTb2NrZXRzLFxyXG4gICAgICAgICAgICAgICAga2VlcEFsaXZlOiB0aGlzLl9rZWVwQWxpdmUsXHJcbiAgICAgICAgICAgICAgICBwcm94eToge1xyXG4gICAgICAgICAgICAgICAgICAgIHByb3h5QXV0aDogcHJveHkucHJveHlBdXRoLFxyXG4gICAgICAgICAgICAgICAgICAgIGhvc3Q6IHByb3h5LnByb3h5VXJsLmhvc3RuYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgIHBvcnQ6IHByb3h5LnByb3h5VXJsLnBvcnRcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIGxldCB0dW5uZWxBZ2VudDtcclxuICAgICAgICAgICAgY29uc3Qgb3Zlckh0dHBzID0gcHJveHkucHJveHlVcmwucHJvdG9jb2wgPT09ICdodHRwczonO1xyXG4gICAgICAgICAgICBpZiAodXNpbmdTc2wpIHtcclxuICAgICAgICAgICAgICAgIHR1bm5lbEFnZW50ID0gb3Zlckh0dHBzID8gdHVubmVsLmh0dHBzT3Zlckh0dHBzIDogdHVubmVsLmh0dHBzT3Zlckh0dHA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0dW5uZWxBZ2VudCA9IG92ZXJIdHRwcyA/IHR1bm5lbC5odHRwT3Zlckh0dHBzIDogdHVubmVsLmh0dHBPdmVySHR0cDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBhZ2VudCA9IHR1bm5lbEFnZW50KGFnZW50T3B0aW9ucyk7XHJcbiAgICAgICAgICAgIHRoaXMuX3Byb3h5QWdlbnQgPSBhZ2VudDtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gaWYgcmV1c2luZyBhZ2VudCBhY3Jvc3MgcmVxdWVzdCBhbmQgdHVubmVsaW5nIGFnZW50IGlzbid0IGFzc2lnbmVkIGNyZWF0ZSBhIG5ldyBhZ2VudFxyXG4gICAgICAgIGlmICh0aGlzLl9rZWVwQWxpdmUgJiYgIWFnZW50KSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7IGtlZXBBbGl2ZTogdGhpcy5fa2VlcEFsaXZlLCBtYXhTb2NrZXRzOiBtYXhTb2NrZXRzIH07XHJcbiAgICAgICAgICAgIGFnZW50ID0gdXNpbmdTc2wgPyBuZXcgaHR0cHMuQWdlbnQob3B0aW9ucykgOiBuZXcgaHR0cC5BZ2VudChvcHRpb25zKTtcclxuICAgICAgICAgICAgdGhpcy5fYWdlbnQgPSBhZ2VudDtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gaWYgbm90IHVzaW5nIHByaXZhdGUgYWdlbnQgYW5kIHR1bm5lbCBhZ2VudCBpc24ndCBzZXR1cCB0aGVuIHVzZSBnbG9iYWwgYWdlbnRcclxuICAgICAgICBpZiAoIWFnZW50KSB7XHJcbiAgICAgICAgICAgIGFnZW50ID0gdXNpbmdTc2wgPyBodHRwcy5nbG9iYWxBZ2VudCA6IGh0dHAuZ2xvYmFsQWdlbnQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh1c2luZ1NzbCAmJiB0aGlzLl9pZ25vcmVTc2xFcnJvcikge1xyXG4gICAgICAgICAgICAvLyB3ZSBkb24ndCB3YW50IHRvIHNldCBOT0RFX1RMU19SRUpFQ1RfVU5BVVRIT1JJWkVEPTAgc2luY2UgdGhhdCB3aWxsIGFmZmVjdCByZXF1ZXN0IGZvciBlbnRpcmUgcHJvY2Vzc1xyXG4gICAgICAgICAgICAvLyBodHRwLlJlcXVlc3RPcHRpb25zIGRvZXNuJ3QgZXhwb3NlIGEgd2F5IHRvIG1vZGlmeSBSZXF1ZXN0T3B0aW9ucy5hZ2VudC5vcHRpb25zXHJcbiAgICAgICAgICAgIC8vIHdlIGhhdmUgdG8gY2FzdCBpdCB0byBhbnkgYW5kIGNoYW5nZSBpdCBkaXJlY3RseVxyXG4gICAgICAgICAgICBhZ2VudC5vcHRpb25zID0gT2JqZWN0LmFzc2lnbihhZ2VudC5vcHRpb25zIHx8IHt9LCB7IHJlamVjdFVuYXV0aG9yaXplZDogZmFsc2UgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh1c2luZ1NzbCAmJiB0aGlzLl9jZXJ0Q29uZmlnKSB7XHJcbiAgICAgICAgICAgIGFnZW50Lm9wdGlvbnMgPSBPYmplY3QuYXNzaWduKGFnZW50Lm9wdGlvbnMgfHwge30sIHsgY2E6IHRoaXMuX2NhLCBjZXJ0OiB0aGlzLl9jZXJ0LCBrZXk6IHRoaXMuX2tleSwgcGFzc3BocmFzZTogdGhpcy5fY2VydENvbmZpZy5wYXNzcGhyYXNlIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYWdlbnQ7XHJcbiAgICB9XHJcbiAgICBfZ2V0UHJveHkocGFyc2VkVXJsKSB7XHJcbiAgICAgICAgbGV0IHVzaW5nU3NsID0gcGFyc2VkVXJsLnByb3RvY29sID09PSAnaHR0cHM6JztcclxuICAgICAgICBsZXQgcHJveHlDb25maWcgPSB0aGlzLl9odHRwUHJveHk7XHJcbiAgICAgICAgLy8gZmFsbGJhY2sgdG8gaHR0cF9wcm94eSBhbmQgaHR0cHNfcHJveHkgZW52XHJcbiAgICAgICAgbGV0IGh0dHBzX3Byb3h5ID0gcHJvY2Vzcy5lbnZbRW52aXJvbm1lbnRWYXJpYWJsZXMuSFRUUFNfUFJPWFldO1xyXG4gICAgICAgIGxldCBodHRwX3Byb3h5ID0gcHJvY2Vzcy5lbnZbRW52aXJvbm1lbnRWYXJpYWJsZXMuSFRUUF9QUk9YWV07XHJcbiAgICAgICAgaWYgKCFwcm94eUNvbmZpZykge1xyXG4gICAgICAgICAgICBpZiAoaHR0cHNfcHJveHkgJiYgdXNpbmdTc2wpIHtcclxuICAgICAgICAgICAgICAgIHByb3h5Q29uZmlnID0ge1xyXG4gICAgICAgICAgICAgICAgICAgIHByb3h5VXJsOiBodHRwc19wcm94eVxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChodHRwX3Byb3h5KSB7XHJcbiAgICAgICAgICAgICAgICBwcm94eUNvbmZpZyA9IHtcclxuICAgICAgICAgICAgICAgICAgICBwcm94eVVybDogaHR0cF9wcm94eVxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBsZXQgcHJveHlVcmw7XHJcbiAgICAgICAgbGV0IHByb3h5QXV0aDtcclxuICAgICAgICBpZiAocHJveHlDb25maWcpIHtcclxuICAgICAgICAgICAgaWYgKHByb3h5Q29uZmlnLnByb3h5VXJsLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIHByb3h5VXJsID0gdXJsLnBhcnNlKHByb3h5Q29uZmlnLnByb3h5VXJsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocHJveHlDb25maWcucHJveHlVc2VybmFtZSB8fCBwcm94eUNvbmZpZy5wcm94eVBhc3N3b3JkKSB7XHJcbiAgICAgICAgICAgICAgICBwcm94eUF1dGggPSBwcm94eUNvbmZpZy5wcm94eVVzZXJuYW1lICsgXCI6XCIgKyBwcm94eUNvbmZpZy5wcm94eVBhc3N3b3JkO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB7IHByb3h5VXJsOiBwcm94eVVybCwgcHJveHlBdXRoOiBwcm94eUF1dGggfTtcclxuICAgIH1cclxuICAgIF9pc01hdGNoSW5CeXBhc3NQcm94eUxpc3QocGFyc2VkVXJsKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLl9odHRwUHJveHlCeXBhc3NIb3N0cykge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxldCBieXBhc3MgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLl9odHRwUHJveHlCeXBhc3NIb3N0cy5mb3JFYWNoKGJ5cGFzc0hvc3QgPT4ge1xyXG4gICAgICAgICAgICBpZiAoYnlwYXNzSG9zdC50ZXN0KHBhcnNlZFVybC5ocmVmKSkge1xyXG4gICAgICAgICAgICAgICAgYnlwYXNzID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiBieXBhc3M7XHJcbiAgICB9XHJcbiAgICBfcGVyZm9ybUV4cG9uZW50aWFsQmFja29mZihyZXRyeU51bWJlcikge1xyXG4gICAgICAgIHJldHJ5TnVtYmVyID0gTWF0aC5taW4oRXhwb25lbnRpYWxCYWNrb2ZmQ2VpbGluZywgcmV0cnlOdW1iZXIpO1xyXG4gICAgICAgIGNvbnN0IG1zID0gRXhwb25lbnRpYWxCYWNrb2ZmVGltZVNsaWNlICogTWF0aC5wb3coMiwgcmV0cnlOdW1iZXIpO1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQoKCkgPT4gcmVzb2x2ZSgpLCBtcykpO1xyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMuSHR0cENsaWVudCA9IEh0dHBDbGllbnQ7XHJcbiIsIlwidXNlIHN0cmljdFwiO1xyXG4vLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdC4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLiBTZWUgTElDRU5TRSBmaWxlIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGZ1bGwgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxudmFyIF9fYXdhaXRlciA9ICh0aGlzICYmIHRoaXMuX19hd2FpdGVyKSB8fCBmdW5jdGlvbiAodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHJlc3VsdC52YWx1ZSk7IH0pLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG5jb25zdCBxcyA9IHJlcXVpcmUoXCJxc1wiKTtcclxuY29uc3QgdXJsID0gcmVxdWlyZShcInVybFwiKTtcclxuY29uc3QgcGF0aCA9IHJlcXVpcmUoXCJwYXRoXCIpO1xyXG5jb25zdCB6bGliID0gcmVxdWlyZShcInpsaWJcIik7XHJcbi8qKlxyXG4gKiBjcmVhdGVzIGFuIHVybCBmcm9tIGEgcmVxdWVzdCB1cmwgYW5kIG9wdGlvbmFsIGJhc2UgdXJsIChodHRwOi8vc2VydmVyOjgwODApXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSByZXNvdXJjZSAtIGEgZnVsbHkgcXVhbGlmaWVkIHVybCBvciByZWxhdGl2ZSBwYXRoXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlVXJsIC0gYW4gb3B0aW9uYWwgYmFzZVVybCAoaHR0cDovL3NlcnZlcjo4MDgwKVxyXG4gKiBAcGFyYW0ge0lSZXF1ZXN0T3B0aW9uc30gb3B0aW9ucyAtIGFuIG9wdGlvbmFsIG9wdGlvbnMgb2JqZWN0LCBjb3VsZCBpbmNsdWRlIFF1ZXJ5UGFyYW1ldGVycyBlLmcuXHJcbiAqIEByZXR1cm4ge3N0cmluZ30gLSByZXN1bHRhbnQgdXJsXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRVcmwocmVzb3VyY2UsIGJhc2VVcmwsIHF1ZXJ5UGFyYW1zKSB7XHJcbiAgICBjb25zdCBwYXRoQXBpID0gcGF0aC5wb3NpeCB8fCBwYXRoO1xyXG4gICAgbGV0IHJlcXVlc3RVcmwgPSAnJztcclxuICAgIGlmICghYmFzZVVybCkge1xyXG4gICAgICAgIHJlcXVlc3RVcmwgPSByZXNvdXJjZTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKCFyZXNvdXJjZSkge1xyXG4gICAgICAgIHJlcXVlc3RVcmwgPSBiYXNlVXJsO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgY29uc3QgYmFzZSA9IHVybC5wYXJzZShiYXNlVXJsKTtcclxuICAgICAgICBjb25zdCByZXN1bHRhbnRVcmwgPSB1cmwucGFyc2UocmVzb3VyY2UpO1xyXG4gICAgICAgIC8vIHJlc291cmNlIChzcGVjaWZpYyBwZXIgcmVxdWVzdCkgZWxlbWVudHMgdGFrZSBwcmlvcml0eVxyXG4gICAgICAgIHJlc3VsdGFudFVybC5wcm90b2NvbCA9IHJlc3VsdGFudFVybC5wcm90b2NvbCB8fCBiYXNlLnByb3RvY29sO1xyXG4gICAgICAgIHJlc3VsdGFudFVybC5hdXRoID0gcmVzdWx0YW50VXJsLmF1dGggfHwgYmFzZS5hdXRoO1xyXG4gICAgICAgIHJlc3VsdGFudFVybC5ob3N0ID0gcmVzdWx0YW50VXJsLmhvc3QgfHwgYmFzZS5ob3N0O1xyXG4gICAgICAgIHJlc3VsdGFudFVybC5wYXRobmFtZSA9IHBhdGhBcGkucmVzb2x2ZShiYXNlLnBhdGhuYW1lLCByZXN1bHRhbnRVcmwucGF0aG5hbWUpO1xyXG4gICAgICAgIGlmICghcmVzdWx0YW50VXJsLnBhdGhuYW1lLmVuZHNXaXRoKCcvJykgJiYgcmVzb3VyY2UuZW5kc1dpdGgoJy8nKSkge1xyXG4gICAgICAgICAgICByZXN1bHRhbnRVcmwucGF0aG5hbWUgKz0gJy8nO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXF1ZXN0VXJsID0gdXJsLmZvcm1hdChyZXN1bHRhbnRVcmwpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHF1ZXJ5UGFyYW1zID9cclxuICAgICAgICBnZXRVcmxXaXRoUGFyc2VkUXVlcnlQYXJhbXMocmVxdWVzdFVybCwgcXVlcnlQYXJhbXMpIDpcclxuICAgICAgICByZXF1ZXN0VXJsO1xyXG59XHJcbmV4cG9ydHMuZ2V0VXJsID0gZ2V0VXJsO1xyXG4vKipcclxuICpcclxuICogQHBhcmFtIHtzdHJpbmd9IHJlcXVlc3RVcmxcclxuICogQHBhcmFtIHtJUmVxdWVzdFF1ZXJ5UGFyYW1zfSBxdWVyeVBhcmFtc1xyXG4gKiBAcmV0dXJuIHtzdHJpbmd9IC0gUmVxdWVzdCdzIFVSTCB3aXRoIFF1ZXJ5IFBhcmFtZXRlcnMgYXBwZW5kZWQvcGFyc2VkLlxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0VXJsV2l0aFBhcnNlZFF1ZXJ5UGFyYW1zKHJlcXVlc3RVcmwsIHF1ZXJ5UGFyYW1zKSB7XHJcbiAgICBjb25zdCB1cmwgPSByZXF1ZXN0VXJsLnJlcGxhY2UoL1xcPyQvZywgJycpOyAvLyBDbGVhbiBhbnkgZXh0cmEgZW5kLW9mLXN0cmluZyBcIj9cIiBjaGFyYWN0ZXJcclxuICAgIGNvbnN0IHBhcnNlZFF1ZXJ5UGFyYW1zID0gcXMuc3RyaW5naWZ5KHF1ZXJ5UGFyYW1zLnBhcmFtcywgYnVpbGRQYXJhbXNTdHJpbmdpZnlPcHRpb25zKHF1ZXJ5UGFyYW1zKSk7XHJcbiAgICByZXR1cm4gYCR7dXJsfSR7cGFyc2VkUXVlcnlQYXJhbXN9YDtcclxufVxyXG4vKipcclxuICogQnVpbGQgb3B0aW9ucyBmb3IgUXVlcnlQYXJhbXMgU3RyaW5naWZ5aW5nLlxyXG4gKlxyXG4gKiBAcGFyYW0ge0lSZXF1ZXN0UXVlcnlQYXJhbXN9IHF1ZXJ5UGFyYW1zXHJcbiAqIEByZXR1cm4ge29iamVjdH1cclxuICovXHJcbmZ1bmN0aW9uIGJ1aWxkUGFyYW1zU3RyaW5naWZ5T3B0aW9ucyhxdWVyeVBhcmFtcykge1xyXG4gICAgbGV0IG9wdGlvbnMgPSB7XHJcbiAgICAgICAgYWRkUXVlcnlQcmVmaXg6IHRydWUsXHJcbiAgICAgICAgZGVsaW1pdGVyOiAocXVlcnlQYXJhbXMub3B0aW9ucyB8fCB7fSkuc2VwYXJhdG9yIHx8ICcmJyxcclxuICAgICAgICBhbGxvd0RvdHM6IChxdWVyeVBhcmFtcy5vcHRpb25zIHx8IHt9KS5zaG91bGRBbGxvd0RvdHMgfHwgZmFsc2UsXHJcbiAgICAgICAgYXJyYXlGb3JtYXQ6IChxdWVyeVBhcmFtcy5vcHRpb25zIHx8IHt9KS5hcnJheUZvcm1hdCB8fCAncmVwZWF0JyxcclxuICAgICAgICBlbmNvZGVWYWx1ZXNPbmx5OiAocXVlcnlQYXJhbXMub3B0aW9ucyB8fCB7fSkuc2hvdWxkT25seUVuY29kZVZhbHVlcyB8fCB0cnVlXHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIG9wdGlvbnM7XHJcbn1cclxuLyoqXHJcbiAqIERlY29tcHJlc3MvRGVjb2RlIGd6aXAgZW5jb2RlZCBKU09OXHJcbiAqIFVzaW5nIE5vZGUuanMgYnVpbHQtaW4gemxpYiBtb2R1bGVcclxuICpcclxuICogQHBhcmFtIHtCdWZmZXJ9IGJ1ZmZlclxyXG4gKiBAcGFyYW0ge3N0cmluZ30gY2hhcnNldD8gLSBvcHRpb25hbDsgZGVmYXVsdHMgdG8gJ3V0Zi04J1xyXG4gKiBAcmV0dXJuIHtQcm9taXNlPHN0cmluZz59XHJcbiAqL1xyXG5mdW5jdGlvbiBkZWNvbXByZXNzR3ppcHBlZENvbnRlbnQoYnVmZmVyLCBjaGFyc2V0KSB7XHJcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XHJcbiAgICAgICAgICAgIHpsaWIuZ3VuemlwKGJ1ZmZlciwgZnVuY3Rpb24gKGVycm9yLCBidWZmZXIpIHtcclxuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXNvbHZlKGJ1ZmZlci50b1N0cmluZyhjaGFyc2V0IHx8ICd1dGYtOCcpKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSkpO1xyXG4gICAgfSk7XHJcbn1cclxuZXhwb3J0cy5kZWNvbXByZXNzR3ppcHBlZENvbnRlbnQgPSBkZWNvbXByZXNzR3ppcHBlZENvbnRlbnQ7XHJcbi8qKlxyXG4gKiBPYnRhaW4gUmVzcG9uc2UncyBDb250ZW50IENoYXJzZXQuXHJcbiAqIFRocm91Z2ggaW5zcGVjdGluZyBgY29udGVudC10eXBlYCByZXNwb25zZSBoZWFkZXIuXHJcbiAqIEl0IFJldHVybnMgJ3V0Zi04JyBpZiBOTyBjaGFyc2V0IHNwZWNpZmllZC9tYXRjaGVkLlxyXG4gKlxyXG4gKiBAcGFyYW0ge0lIdHRwQ2xpZW50UmVzcG9uc2V9IHJlc3BvbnNlXHJcbiAqIEByZXR1cm4ge3N0cmluZ30gLSBDb250ZW50IEVuY29kaW5nIENoYXJzZXQ7IERlZmF1bHQ9dXRmLThcclxuICovXHJcbmZ1bmN0aW9uIG9idGFpbkNvbnRlbnRDaGFyc2V0KHJlc3BvbnNlKSB7XHJcbiAgICAvLyBGaW5kIHRoZSBjaGFyc2V0LCBpZiBzcGVjaWZpZWQuXHJcbiAgICAvLyBTZWFyY2ggZm9yIHRoZSBgY2hhcnNldD1DSEFSU0VUYCBzdHJpbmcsIG5vdCBpbmNsdWRpbmcgYDssXFxyXFxuYFxyXG4gICAgLy8gRXhhbXBsZTogY29udGVudC10eXBlOiAnYXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04J1xyXG4gICAgLy8gfF9fIG1hdGNoZXMgd291bGQgYmUgWydjaGFyc2V0PXV0Zi04JywgJ3V0Zi04JywgaW5kZXg6IDE4LCBpbnB1dDogJ2FwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9dXRmLTgnXVxyXG4gICAgLy8gfF9fX19fIG1hdGNoZXNbMV0gd291bGQgaGF2ZSB0aGUgY2hhcnNldCA6dGFkYTogLCBpbiBvdXIgZXhhbXBsZSBpdCdzIHV0Zi04XHJcbiAgICAvLyBIb3dldmVyLCBpZiB0aGUgbWF0Y2hlcyBBcnJheSB3YXMgZW1wdHkgb3Igbm8gY2hhcnNldCBmb3VuZCwgJ3V0Zi04JyB3b3VsZCBiZSByZXR1cm5lZCBieSBkZWZhdWx0LlxyXG4gICAgY29uc3QgY29udGVudFR5cGUgPSByZXNwb25zZS5tZXNzYWdlLmhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddIHx8ICcnO1xyXG4gICAgY29uc3QgbWF0Y2hlcyA9IGNvbnRlbnRUeXBlLm1hdGNoKC9jaGFyc2V0PShbXjssXFxyXFxuXSspL2kpO1xyXG4gICAgcmV0dXJuIChtYXRjaGVzICYmIG1hdGNoZXNbMV0pID8gbWF0Y2hlc1sxXSA6ICd1dGYtOCc7XHJcbn1cclxuZXhwb3J0cy5vYnRhaW5Db250ZW50Q2hhcnNldCA9IG9idGFpbkNvbnRlbnRDaGFyc2V0O1xyXG4iLCJ2YXIgdjEgPSByZXF1aXJlKCcuL3YxJyk7XG52YXIgdjQgPSByZXF1aXJlKCcuL3Y0Jyk7XG5cbnZhciB1dWlkID0gdjQ7XG51dWlkLnYxID0gdjE7XG51dWlkLnY0ID0gdjQ7XG5cbm1vZHVsZS5leHBvcnRzID0gdXVpZDtcbiIsIi8qKlxuICogQ29udmVydCBhcnJheSBvZiAxNiBieXRlIHZhbHVlcyB0byBVVUlEIHN0cmluZyBmb3JtYXQgb2YgdGhlIGZvcm06XG4gKiBYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFhcbiAqL1xudmFyIGJ5dGVUb0hleCA9IFtdO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXhbaV0gPSAoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpO1xufVxuXG5mdW5jdGlvbiBieXRlc1RvVXVpZChidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IG9mZnNldCB8fCAwO1xuICB2YXIgYnRoID0gYnl0ZVRvSGV4O1xuICAvLyBqb2luIHVzZWQgdG8gZml4IG1lbW9yeSBpc3N1ZSBjYXVzZWQgYnkgY29uY2F0ZW5hdGlvbjogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzE3NSNjNFxuICByZXR1cm4gKFtcbiAgICBidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuICAgIGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcbiAgICBidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG4gICAgYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuICAgIGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcbiAgICBidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuICAgIGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sXG4gICAgYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXVxuICBdKS5qb2luKCcnKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBieXRlc1RvVXVpZDtcbiIsIi8vIFVuaXF1ZSBJRCBjcmVhdGlvbiByZXF1aXJlcyBhIGhpZ2ggcXVhbGl0eSByYW5kb20gIyBnZW5lcmF0b3IuICBJbiBub2RlLmpzXG4vLyB0aGlzIGlzIHByZXR0eSBzdHJhaWdodC1mb3J3YXJkIC0gd2UgdXNlIHRoZSBjcnlwdG8gQVBJLlxuXG52YXIgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gbm9kZVJORygpIHtcbiAgcmV0dXJuIGNyeXB0by5yYW5kb21CeXRlcygxNik7XG59O1xuIiwidmFyIHJuZyA9IHJlcXVpcmUoJy4vbGliL3JuZycpO1xudmFyIGJ5dGVzVG9VdWlkID0gcmVxdWlyZSgnLi9saWIvYnl0ZXNUb1V1aWQnKTtcblxuLy8gKipgdjEoKWAgLSBHZW5lcmF0ZSB0aW1lLWJhc2VkIFVVSUQqKlxuLy9cbi8vIEluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9MaW9zSy9VVUlELmpzXG4vLyBhbmQgaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3V1aWQuaHRtbFxuXG52YXIgX25vZGVJZDtcbnZhciBfY2xvY2tzZXE7XG5cbi8vIFByZXZpb3VzIHV1aWQgY3JlYXRpb24gdGltZVxudmFyIF9sYXN0TVNlY3MgPSAwO1xudmFyIF9sYXN0TlNlY3MgPSAwO1xuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3V1aWRqcy91dWlkIGZvciBBUEkgZGV0YWlsc1xuZnVuY3Rpb24gdjEob3B0aW9ucywgYnVmLCBvZmZzZXQpIHtcbiAgdmFyIGkgPSBidWYgJiYgb2Zmc2V0IHx8IDA7XG4gIHZhciBiID0gYnVmIHx8IFtdO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICB2YXIgbm9kZSA9IG9wdGlvbnMubm9kZSB8fCBfbm9kZUlkO1xuICB2YXIgY2xvY2tzZXEgPSBvcHRpb25zLmNsb2Nrc2VxICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNsb2Nrc2VxIDogX2Nsb2Nrc2VxO1xuXG4gIC8vIG5vZGUgYW5kIGNsb2Nrc2VxIG5lZWQgdG8gYmUgaW5pdGlhbGl6ZWQgdG8gcmFuZG9tIHZhbHVlcyBpZiB0aGV5J3JlIG5vdFxuICAvLyBzcGVjaWZpZWQuICBXZSBkbyB0aGlzIGxhemlseSB0byBtaW5pbWl6ZSBpc3N1ZXMgcmVsYXRlZCB0byBpbnN1ZmZpY2llbnRcbiAgLy8gc3lzdGVtIGVudHJvcHkuICBTZWUgIzE4OVxuICBpZiAobm9kZSA9PSBudWxsIHx8IGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICB2YXIgc2VlZEJ5dGVzID0gcm5nKCk7XG4gICAgaWYgKG5vZGUgPT0gbnVsbCkge1xuICAgICAgLy8gUGVyIDQuNSwgY3JlYXRlIGFuZCA0OC1iaXQgbm9kZSBpZCwgKDQ3IHJhbmRvbSBiaXRzICsgbXVsdGljYXN0IGJpdCA9IDEpXG4gICAgICBub2RlID0gX25vZGVJZCA9IFtcbiAgICAgICAgc2VlZEJ5dGVzWzBdIHwgMHgwMSxcbiAgICAgICAgc2VlZEJ5dGVzWzFdLCBzZWVkQnl0ZXNbMl0sIHNlZWRCeXRlc1szXSwgc2VlZEJ5dGVzWzRdLCBzZWVkQnl0ZXNbNV1cbiAgICAgIF07XG4gICAgfVxuICAgIGlmIChjbG9ja3NlcSA9PSBudWxsKSB7XG4gICAgICAvLyBQZXIgNC4yLjIsIHJhbmRvbWl6ZSAoMTQgYml0KSBjbG9ja3NlcVxuICAgICAgY2xvY2tzZXEgPSBfY2xvY2tzZXEgPSAoc2VlZEJ5dGVzWzZdIDw8IDggfCBzZWVkQnl0ZXNbN10pICYgMHgzZmZmO1xuICAgIH1cbiAgfVxuXG4gIC8vIFVVSUQgdGltZXN0YW1wcyBhcmUgMTAwIG5hbm8tc2Vjb25kIHVuaXRzIHNpbmNlIHRoZSBHcmVnb3JpYW4gZXBvY2gsXG4gIC8vICgxNTgyLTEwLTE1IDAwOjAwKS4gIEpTTnVtYmVycyBhcmVuJ3QgcHJlY2lzZSBlbm91Z2ggZm9yIHRoaXMsIHNvXG4gIC8vIHRpbWUgaXMgaGFuZGxlZCBpbnRlcm5hbGx5IGFzICdtc2VjcycgKGludGVnZXIgbWlsbGlzZWNvbmRzKSBhbmQgJ25zZWNzJ1xuICAvLyAoMTAwLW5hbm9zZWNvbmRzIG9mZnNldCBmcm9tIG1zZWNzKSBzaW5jZSB1bml4IGVwb2NoLCAxOTcwLTAxLTAxIDAwOjAwLlxuICB2YXIgbXNlY3MgPSBvcHRpb25zLm1zZWNzICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm1zZWNzIDogbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cbiAgLy8gUGVyIDQuMi4xLjIsIHVzZSBjb3VudCBvZiB1dWlkJ3MgZ2VuZXJhdGVkIGR1cmluZyB0aGUgY3VycmVudCBjbG9ja1xuICAvLyBjeWNsZSB0byBzaW11bGF0ZSBoaWdoZXIgcmVzb2x1dGlvbiBjbG9ja1xuICB2YXIgbnNlY3MgPSBvcHRpb25zLm5zZWNzICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm5zZWNzIDogX2xhc3ROU2VjcyArIDE7XG5cbiAgLy8gVGltZSBzaW5jZSBsYXN0IHV1aWQgY3JlYXRpb24gKGluIG1zZWNzKVxuICB2YXIgZHQgPSAobXNlY3MgLSBfbGFzdE1TZWNzKSArIChuc2VjcyAtIF9sYXN0TlNlY3MpLzEwMDAwO1xuXG4gIC8vIFBlciA0LjIuMS4yLCBCdW1wIGNsb2Nrc2VxIG9uIGNsb2NrIHJlZ3Jlc3Npb25cbiAgaWYgKGR0IDwgMCAmJiBvcHRpb25zLmNsb2Nrc2VxID09PSB1bmRlZmluZWQpIHtcbiAgICBjbG9ja3NlcSA9IGNsb2Nrc2VxICsgMSAmIDB4M2ZmZjtcbiAgfVxuXG4gIC8vIFJlc2V0IG5zZWNzIGlmIGNsb2NrIHJlZ3Jlc3NlcyAobmV3IGNsb2Nrc2VxKSBvciB3ZSd2ZSBtb3ZlZCBvbnRvIGEgbmV3XG4gIC8vIHRpbWUgaW50ZXJ2YWxcbiAgaWYgKChkdCA8IDAgfHwgbXNlY3MgPiBfbGFzdE1TZWNzKSAmJiBvcHRpb25zLm5zZWNzID09PSB1bmRlZmluZWQpIHtcbiAgICBuc2VjcyA9IDA7XG4gIH1cblxuICAvLyBQZXIgNC4yLjEuMiBUaHJvdyBlcnJvciBpZiB0b28gbWFueSB1dWlkcyBhcmUgcmVxdWVzdGVkXG4gIGlmIChuc2VjcyA+PSAxMDAwMCkge1xuICAgIHRocm93IG5ldyBFcnJvcigndXVpZC52MSgpOiBDYW5cXCd0IGNyZWF0ZSBtb3JlIHRoYW4gMTBNIHV1aWRzL3NlYycpO1xuICB9XG5cbiAgX2xhc3RNU2VjcyA9IG1zZWNzO1xuICBfbGFzdE5TZWNzID0gbnNlY3M7XG4gIF9jbG9ja3NlcSA9IGNsb2Nrc2VxO1xuXG4gIC8vIFBlciA0LjEuNCAtIENvbnZlcnQgZnJvbSB1bml4IGVwb2NoIHRvIEdyZWdvcmlhbiBlcG9jaFxuICBtc2VjcyArPSAxMjIxOTI5MjgwMDAwMDtcblxuICAvLyBgdGltZV9sb3dgXG4gIHZhciB0bCA9ICgobXNlY3MgJiAweGZmZmZmZmYpICogMTAwMDAgKyBuc2VjcykgJSAweDEwMDAwMDAwMDtcbiAgYltpKytdID0gdGwgPj4+IDI0ICYgMHhmZjtcbiAgYltpKytdID0gdGwgPj4+IDE2ICYgMHhmZjtcbiAgYltpKytdID0gdGwgPj4+IDggJiAweGZmO1xuICBiW2krK10gPSB0bCAmIDB4ZmY7XG5cbiAgLy8gYHRpbWVfbWlkYFxuICB2YXIgdG1oID0gKG1zZWNzIC8gMHgxMDAwMDAwMDAgKiAxMDAwMCkgJiAweGZmZmZmZmY7XG4gIGJbaSsrXSA9IHRtaCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRtaCAmIDB4ZmY7XG5cbiAgLy8gYHRpbWVfaGlnaF9hbmRfdmVyc2lvbmBcbiAgYltpKytdID0gdG1oID4+PiAyNCAmIDB4ZiB8IDB4MTA7IC8vIGluY2x1ZGUgdmVyc2lvblxuICBiW2krK10gPSB0bWggPj4+IDE2ICYgMHhmZjtcblxuICAvLyBgY2xvY2tfc2VxX2hpX2FuZF9yZXNlcnZlZGAgKFBlciA0LjIuMiAtIGluY2x1ZGUgdmFyaWFudClcbiAgYltpKytdID0gY2xvY2tzZXEgPj4+IDggfCAweDgwO1xuXG4gIC8vIGBjbG9ja19zZXFfbG93YFxuICBiW2krK10gPSBjbG9ja3NlcSAmIDB4ZmY7XG5cbiAgLy8gYG5vZGVgXG4gIGZvciAodmFyIG4gPSAwOyBuIDwgNjsgKytuKSB7XG4gICAgYltpICsgbl0gPSBub2RlW25dO1xuICB9XG5cbiAgcmV0dXJuIGJ1ZiA/IGJ1ZiA6IGJ5dGVzVG9VdWlkKGIpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHYxO1xuIiwidmFyIHJuZyA9IHJlcXVpcmUoJy4vbGliL3JuZycpO1xudmFyIGJ5dGVzVG9VdWlkID0gcmVxdWlyZSgnLi9saWIvYnl0ZXNUb1V1aWQnKTtcblxuZnVuY3Rpb24gdjQob3B0aW9ucywgYnVmLCBvZmZzZXQpIHtcbiAgdmFyIGkgPSBidWYgJiYgb2Zmc2V0IHx8IDA7XG5cbiAgaWYgKHR5cGVvZihvcHRpb25zKSA9PSAnc3RyaW5nJykge1xuICAgIGJ1ZiA9IG9wdGlvbnMgPT09ICdiaW5hcnknID8gbmV3IEFycmF5KDE2KSA6IG51bGw7XG4gICAgb3B0aW9ucyA9IG51bGw7XG4gIH1cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgdmFyIHJuZHMgPSBvcHRpb25zLnJhbmRvbSB8fCAob3B0aW9ucy5ybmcgfHwgcm5nKSgpO1xuXG4gIC8vIFBlciA0LjQsIHNldCBiaXRzIGZvciB2ZXJzaW9uIGFuZCBgY2xvY2tfc2VxX2hpX2FuZF9yZXNlcnZlZGBcbiAgcm5kc1s2XSA9IChybmRzWzZdICYgMHgwZikgfCAweDQwO1xuICBybmRzWzhdID0gKHJuZHNbOF0gJiAweDNmKSB8IDB4ODA7XG5cbiAgLy8gQ29weSBieXRlcyB0byBidWZmZXIsIGlmIHByb3ZpZGVkXG4gIGlmIChidWYpIHtcbiAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgMTY7ICsraWkpIHtcbiAgICAgIGJ1ZltpICsgaWldID0gcm5kc1tpaV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ1ZiB8fCBieXRlc1RvVXVpZChybmRzKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB2NDtcbiIsImltcG9ydCAqIGFzIGZzIGZyb20gXCJmc1wiO1xyXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCI7XHJcblxyXG5pbXBvcnQgdXVpZHY0IGZyb20gXCJ1dWlkXCI7XHJcblxyXG5pbXBvcnQgKiBhcyBjb3JlIGZyb20gXCJAYWN0aW9ucy9jb3JlXCI7XHJcbmltcG9ydCAqIGFzIGV4ZSBmcm9tIFwiQGFjdGlvbnMvZXhlY1wiO1xyXG5pbXBvcnQgKiBhcyBpbyBmcm9tIFwiQGFjdGlvbnMvaW9cIjtcclxuaW1wb3J0ICogYXMgdG9vbENhY2hlIGZyb20gXCJAYWN0aW9ucy90b29sLWNhY2hlXCI7XHJcblxyXG5pbXBvcnQgeyBpbmplY3RhYmxlIH0gZnJvbSBcImludmVyc2lmeVwiO1xyXG5cclxuaW1wb3J0IHsgSUJ1aWxkQWdlbnQsIElFeGVjUmVzdWx0IH0gZnJvbSBcIi4uLy4uL2NvcmUvY29tbW9uXCI7XHJcblxyXG5AaW5qZWN0YWJsZSgpXHJcbmNsYXNzIEJ1aWxkQWdlbnQgaW1wbGVtZW50cyBJQnVpbGRBZ2VudCB7XHJcblxyXG4gICAgcHVibGljIGdldCBhZ2VudE5hbWUoKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gXCJHaXRIdWIgQWN0aW9uc1wiO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBmaW5kKHRvb2xOYW1lOiBzdHJpbmcsIHZlcnNpb25TcGVjOiBzdHJpbmcsIGFyY2g/OiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiB0b29sQ2FjaGUuZmluZCh0b29sTmFtZSwgdmVyc2lvblNwZWMsIGFyY2gpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBjYWNoZURpcihzb3VyY2VEaXI6IHN0cmluZywgdG9vbDogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcsIGFyY2g/OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xyXG4gICAgICAgIHJldHVybiB0b29sQ2FjaGUuY2FjaGVEaXIoc291cmNlRGlyLCB0b29sLCB2ZXJzaW9uLCBhcmNoKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgY3JlYXRlVGVtcERpcigpOiBQcm9taXNlPHN0cmluZz4ge1xyXG4gICAgICAgIGNvbnN0IElTX1dJTkRPV1MgPSBwcm9jZXNzLnBsYXRmb3JtID09PSBcIndpbjMyXCI7XHJcblxyXG4gICAgICAgIGxldCB0ZW1wRGlyZWN0b3J5OiBzdHJpbmcgPSBwcm9jZXNzLmVudi5SVU5ORVJfVEVNUCB8fCBcIlwiO1xyXG5cclxuICAgICAgICBpZiAoIXRlbXBEaXJlY3RvcnkpIHtcclxuICAgICAgICAgICAgbGV0IGJhc2VMb2NhdGlvbjogc3RyaW5nO1xyXG4gICAgICAgICAgICBpZiAoSVNfV0lORE9XUykge1xyXG4gICAgICAgICAgICAgICAgLy8gT24gV2luZG93cyB1c2UgdGhlIFVTRVJQUk9GSUxFIGVudiB2YXJpYWJsZVxyXG4gICAgICAgICAgICAgICAgYmFzZUxvY2F0aW9uID0gcHJvY2Vzcy5lbnYuVVNFUlBST0ZJTEUgfHwgXCJDOlxcXFxcIjtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzLnBsYXRmb3JtID09PSBcImRhcndpblwiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFzZUxvY2F0aW9uID0gXCIvVXNlcnNcIjtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFzZUxvY2F0aW9uID0gXCIvaG9tZVwiO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRlbXBEaXJlY3RvcnkgPSBwYXRoLmpvaW4oYmFzZUxvY2F0aW9uLCBcImFjdGlvbnNcIiwgXCJ0ZW1wXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBkZXN0ID0gcGF0aC5qb2luKHRlbXBEaXJlY3RvcnksIHV1aWR2NCgpKTtcclxuICAgICAgICBhd2FpdCBpby5ta2RpclAoZGVzdCk7XHJcbiAgICAgICAgcmV0dXJuIGRlc3Q7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGRlYnVnKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIGNvcmUuZGVidWcobWVzc2FnZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHNldEZhaWxlZChtZXNzYWdlOiBzdHJpbmcsIGRvbmU/OiBib29sZWFuKTogdm9pZCB7XHJcbiAgICAgICAgY29yZS5zZXRGYWlsZWQobWVzc2FnZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHNldFN1Y2NlZWRlZChtZXNzYWdlOiBzdHJpbmcsIGRvbmU/OiBib29sZWFuKTogdm9pZCB7XHJcbiAgICAgICAgLy9cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZXhwb3J0VmFyaWFibGUobmFtZTogc3RyaW5nLCB2YWw6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIGNvcmUuZXhwb3J0VmFyaWFibGUobmFtZSwgdmFsKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZ2V0VmFyaWFibGUobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gcHJvY2Vzcy5lbnZbbmFtZV07XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFkZFBhdGgoaW5wdXRQYXRoOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgICAgICBjb3JlLmFkZFBhdGgoaW5wdXRQYXRoKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgd2hpY2godG9vbDogc3RyaW5nLCBjaGVjaz86IGJvb2xlYW4pOiBQcm9taXNlPHN0cmluZz4ge1xyXG4gICAgICAgIHJldHVybiBpby53aGljaCh0b29sLCBjaGVjayk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGV4ZWMoZXhlYzogc3RyaW5nLCBhcmdzOiBzdHJpbmdbXSk6IFByb21pc2U8SUV4ZWNSZXN1bHQ+IHtcclxuICAgICAgICBjb25zdCBkb3RuZXRQYXRoID0gYXdhaXQgaW8ud2hpY2goZXhlYywgdHJ1ZSk7XHJcbiAgICAgICAgbGV0IHJlc3VsdENvZGUgPSAwO1xyXG4gICAgICAgIGxldCBzdGRvdXQgPSBcIlwiO1xyXG4gICAgICAgIGxldCBzdGRlcnIgPSBcIlwiO1xyXG4gICAgICAgIHJlc3VsdENvZGUgPSBhd2FpdCBleGUuZXhlYyhcclxuICAgICAgICAgICAgYFwiJHtkb3RuZXRQYXRofVwiYCxcclxuICAgICAgICAgICAgYXJncyxcclxuICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RkZXJyOiAoZGF0YTogQnVmZmVyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0ZGVyciArPSBkYXRhLnRvU3RyaW5nKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICBzdGRvdXQ6IChkYXRhOiBCdWZmZXIpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3Rkb3V0ICs9IGRhdGEudG9TdHJpbmcoKTtcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgY29kZTogcmVzdWx0Q29kZSxcclxuICAgICAgICAgICAgZXJyb3I6IG51bGwsXHJcbiAgICAgICAgICAgIHN0ZGVycixcclxuICAgICAgICAgICAgc3Rkb3V0LFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldFNvdXJjZURpcigpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmdldFZhcmlhYmxlKFwiR0lUSFVCX1dPUktTUEFDRVwiKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc2V0T3V0cHV0KG5hbWU6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIGNvcmUuc2V0T3V0cHV0KG5hbWUsIHZhbHVlKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZ2V0SW5wdXQoaW5wdXQ6IHN0cmluZywgcmVxdWlyZWQ/OiBib29sZWFuKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gY29yZS5nZXRJbnB1dChpbnB1dCwgIHsgcmVxdWlyZWQgfSBhcyBjb3JlLklucHV0T3B0aW9ucyk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldEJvb2xlYW5JbnB1dChpbnB1dDogc3RyaW5nLCByZXF1aXJlZD86IGJvb2xlYW4pOiBib29sZWFuIHtcclxuICAgICAgICBjb25zdCBpbnB1dFZhbHVlID0gdGhpcy5nZXRJbnB1dChpbnB1dCwgcmVxdWlyZWQpO1xyXG4gICAgICAgIHJldHVybiAoaW5wdXRWYWx1ZSB8fCBcImZhbHNlXCIpLnRvTG93ZXJDYXNlKCkgPT09IFwidHJ1ZVwiO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBpc1ZhbGlkSW5wdXRGaWxlKGlucHV0OiBzdHJpbmcsIGZpbGU6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmZpbGVQYXRoU3VwcGxpZWQoaW5wdXQpICYmIHRoaXMuZmlsZUV4aXN0cyhmaWxlKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZmlsZVBhdGhTdXBwbGllZChmaWxlOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgICAgICBjb25zdCBwYXRoVmFsdWUgPSBwYXRoLnJlc29sdmUodGhpcy5nZXRJbnB1dChmaWxlKSB8fCBcIlwiKTtcclxuICAgICAgICBjb25zdCByZXBvUm9vdCA9IHRoaXMuZ2V0U291cmNlRGlyKCk7XHJcbiAgICAgICAgcmV0dXJuIHBhdGhWYWx1ZSAhPT0gcmVwb1Jvb3Q7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGZpbGVFeGlzdHMoZmlsZTogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V4aXN0KGZpbGUpICYmIHRoaXMuX3N0YXRzKGZpbGUpLmlzRmlsZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBkaXJlY3RvcnlFeGlzdHMoZmlsZTogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V4aXN0KGZpbGUpICYmIHRoaXMuX3N0YXRzKGZpbGUpLmlzRGlyZWN0b3J5KCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZXhpc3QoZmlsZTogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICAgICAgbGV0IGV4aXN0ID0gZmFsc2U7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgZXhpc3QgPSAhIShmaWxlICYmIGZzLnN0YXRTeW5jKGZpbGUpICE9IG51bGwpO1xyXG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICBpZiAoZXJyICYmIGVyci5jb2RlID09PSBcIkVOT0VOVFwiKSB7XHJcbiAgICAgICAgICAgICAgICBleGlzdCA9IGZhbHNlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBleGlzdDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9zdGF0cyhmaWxlOiBzdHJpbmcpOiBmcy5TdGF0cyB7XHJcbiAgICAgICAgcmV0dXJuIGZzLnN0YXRTeW5jKGZpbGUpO1xyXG4gICAgfVxyXG4gfVxyXG5cclxuZXhwb3J0IHtcclxuICAgIEJ1aWxkQWdlbnQsXHJcbn07XHJcbiIsImV4cG9ydCBjb25zdCBUWVBFUyA9IHtcclxuICAgIElCdWlsZEFnZW50OiBTeW1ib2wuZm9yKFwiQnVpbGRBZ2VudFwiKSxcclxuICAgIElEb3RuZXRUb29sOiBTeW1ib2wuZm9yKFwiRG90bmV0VG9vbFwiKSxcclxuICAgIElHaXRWZXJzaW9uVG9vbDogU3ltYm9sLmZvcihcIkdpdFZlcnNpb25Ub29sXCIpLFxyXG4gICAgSUdpdFJlbGVhc2VNYW5hZ2VyVG9vbDogU3ltYm9sLmZvcihcIkdpdFJlbGVhc2VNYW5hZ2VyVG9vbFwiKSxcclxuICAgIElWZXJzaW9uTWFuYWdlcjogU3ltYm9sLmZvcihcIlZlcnNpb25NYW5hZ2VyXCIpLFxyXG59O1xyXG5cclxuZXhwb3J0IGNvbnN0IFNldHVwT3B0aW9ucyA9IHtcclxuICAgIGluY2x1ZGVQcmVyZWxlYXNlOiBcImluY2x1ZGVQcmVyZWxlYXNlXCIsXHJcbiAgICB2ZXJzaW9uU3BlYzogXCJ2ZXJzaW9uU3BlY1wiLFxyXG59O1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBJRXhlY1Jlc3VsdCB7XHJcbiAgICBzdGRvdXQ6IHN0cmluZztcclxuICAgIHN0ZGVycjogc3RyaW5nO1xyXG4gICAgY29kZTogbnVtYmVyO1xyXG4gICAgZXJyb3I6IEVycm9yO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIElCdWlsZEFnZW50IHtcclxuICAgIGFnZW50TmFtZTogc3RyaW5nO1xyXG4gICAgZmluZCh0b29sTmFtZTogc3RyaW5nLCB2ZXJzaW9uU3BlYzogc3RyaW5nLCBhcmNoPzogc3RyaW5nKTogc3RyaW5nO1xyXG4gICAgY2FjaGVEaXIoc291cmNlRGlyOiBzdHJpbmcsIHRvb2w6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nLCBhcmNoPzogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+O1xyXG4gICAgY3JlYXRlVGVtcERpcigpOiBQcm9taXNlPHN0cmluZz47XHJcbiAgICBkZWJ1ZyhtZXNzYWdlOiBzdHJpbmcpOiB2b2lkO1xyXG4gICAgc2V0RmFpbGVkKG1lc3NhZ2U6IHN0cmluZywgZG9uZT86IGJvb2xlYW4pOiB2b2lkO1xyXG4gICAgc2V0U3VjY2VlZGVkKG1lc3NhZ2U6IHN0cmluZywgZG9uZT86IGJvb2xlYW4pOiB2b2lkO1xyXG4gICAgZXhwb3J0VmFyaWFibGUobmFtZTogc3RyaW5nLCB2YWw6IHN0cmluZyk6IHZvaWQ7XHJcbiAgICBnZXRWYXJpYWJsZShuYW1lOiBzdHJpbmcpOiBzdHJpbmc7XHJcbiAgICBhZGRQYXRoKGlucHV0UGF0aDogc3RyaW5nKTogdm9pZDtcclxuICAgIHdoaWNoKHRvb2w6IHN0cmluZywgY2hlY2s/OiBib29sZWFuKTogUHJvbWlzZTxzdHJpbmc+O1xyXG4gICAgZXhlYyhleGVjOiBzdHJpbmcsIGFyZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD47XHJcblxyXG4gICAgZ2V0U291cmNlRGlyKCk6IHN0cmluZztcclxuICAgIGlzVmFsaWRJbnB1dEZpbGUoaW5wdXQ6IHN0cmluZywgZmlsZTogc3RyaW5nKTogYm9vbGVhbjtcclxuICAgIGZpbGVFeGlzdHMoZmlsZTogc3RyaW5nKTogYm9vbGVhbjtcclxuICAgIGRpcmVjdG9yeUV4aXN0cyhmaWxlOiBzdHJpbmcpOiBib29sZWFuO1xyXG5cclxuICAgIHNldE91dHB1dChuYW1lOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiB2b2lkO1xyXG4gICAgZ2V0SW5wdXQoaW5wdXQ6IHN0cmluZywgcmVxdWlyZWQ/OiBib29sZWFuKTogc3RyaW5nO1xyXG4gICAgZ2V0Qm9vbGVhbklucHV0KGlucHV0OiBzdHJpbmcsIHJlcXVpcmVkPzogYm9vbGVhbik6IGJvb2xlYW47XHJcbn0iLCJpbXBvcnQgKiBhcyBmcyBmcm9tIFwiZnNcIjtcclxuaW1wb3J0ICogYXMgb3MgZnJvbSBcIm9zXCI7XHJcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIjtcclxuaW1wb3J0ICogYXMgaHR0cCBmcm9tIFwidHlwZWQtcmVzdC1jbGllbnQvSHR0cENsaWVudFwiO1xyXG5cclxuaW1wb3J0IHsgaW5qZWN0LCBpbmplY3RhYmxlIH0gZnJvbSBcImludmVyc2lmeVwiO1xyXG5pbXBvcnQgeyBUWVBFUywgSUV4ZWNSZXN1bHQsIElCdWlsZEFnZW50IH0gZnJvbSBcIi4vY29tbW9uXCI7XHJcbmltcG9ydCB7IElWZXJzaW9uTWFuYWdlciB9IGZyb20gXCIuL3ZlcnNpb25NYW5hZ2VyXCI7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIElEb3RuZXRUb29sIHtcclxuICAgIHJ1bihhcmdzOiBzdHJpbmdbXSk6IFByb21pc2U8SUV4ZWNSZXN1bHQ+O1xyXG4gICAgdG9vbEluc3RhbGwodG9vbE5hbWU6IHN0cmluZywgdmVyc2lvblNwZWM6IHN0cmluZywgY2hlY2tMYXRlc3Q6IGJvb2xlYW4sIGluY2x1ZGVQcmU6IGJvb2xlYW4pOiBQcm9taXNlPHN0cmluZz47XHJcbn1cclxuXHJcbkBpbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIERvdG5ldFRvb2wgaW1wbGVtZW50cyBJRG90bmV0VG9vbCB7XHJcblxyXG4gICAgcHJpdmF0ZSBidWlsZEFnZW50OiBJQnVpbGRBZ2VudDtcclxuICAgIHByaXZhdGUgdmVyc2lvbk1hbmFnZXI6IElWZXJzaW9uTWFuYWdlcjtcclxuICAgIHByaXZhdGUgaHR0cENsaWVudDogaHR0cC5IdHRwQ2xpZW50O1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIEBpbmplY3QoVFlQRVMuSUJ1aWxkQWdlbnQpIGJ1aWxkQWdlbnQ6IElCdWlsZEFnZW50LFxyXG4gICAgICAgIEBpbmplY3QoVFlQRVMuSVZlcnNpb25NYW5hZ2VyKSB2ZXJzaW9uTWFuYWdlcjogSVZlcnNpb25NYW5hZ2VyLFxyXG4gICAgKSB7XHJcbiAgICAgICAgdGhpcy5idWlsZEFnZW50ID0gYnVpbGRBZ2VudDtcclxuICAgICAgICB0aGlzLnZlcnNpb25NYW5hZ2VyID0gdmVyc2lvbk1hbmFnZXI7XHJcbiAgICAgICAgdGhpcy5odHRwQ2xpZW50ID0gbmV3IGh0dHAuSHR0cENsaWVudChcImRvdG5ldFwiKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgcnVuKGFyZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmJ1aWxkQWdlbnQuZXhlYyhcImRvdG5ldFwiLCBhcmdzKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgdG9vbEluc3RhbGwodG9vbE5hbWU6IHN0cmluZywgdmVyc2lvblNwZWM6IHN0cmluZywgY2hlY2tMYXRlc3Q6IGJvb2xlYW4sIGluY2x1ZGVQcmU6IGJvb2xlYW4pXHJcbiAgICA6IFByb21pc2U8c3RyaW5nPiB7XHJcbiAgICAgICAgY29uc29sZS5sb2coXCJcIik7XHJcbiAgICAgICAgY29uc29sZS5sb2coXCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVwiKTtcclxuICAgICAgICBjb25zb2xlLmxvZyhgSW5zdGFsbGluZyAke3Rvb2xOYW1lfSB2ZXJzaW9uIGAgKyB2ZXJzaW9uU3BlYyk7XHJcbiAgICAgICAgY29uc29sZS5sb2coXCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVwiKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMudmVyc2lvbk1hbmFnZXIuaXNFeHBsaWNpdFZlcnNpb24odmVyc2lvblNwZWMpKSB7XHJcbiAgICAgICAgICAgIGNoZWNrTGF0ZXN0ID0gZmFsc2U7IC8vIGNoZWNrIGxhdGVzdCBkb2Vzbid0IG1ha2Ugc2Vuc2Ugd2hlbiBleHBsaWNpdCB2ZXJzaW9uXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsZXQgdG9vbFBhdGg6IHN0cmluZztcclxuICAgICAgICBpZiAoIWNoZWNrTGF0ZXN0KSB7XHJcbiAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgIC8vIExldCdzIHRyeSBhbmQgcmVzb2x2ZSB0aGUgdmVyc2lvbiBzcGVjIGxvY2FsbHkgZmlyc3RcclxuICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgdG9vbFBhdGggPSB0aGlzLmJ1aWxkQWdlbnQuZmluZCh0b29sTmFtZSwgdmVyc2lvblNwZWMpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCF0b29sUGF0aCkge1xyXG4gICAgICAgICAgICBsZXQgdmVyc2lvbjogc3RyaW5nO1xyXG4gICAgICAgICAgICBpZiAodGhpcy52ZXJzaW9uTWFuYWdlci5pc0V4cGxpY2l0VmVyc2lvbih2ZXJzaW9uU3BlYykpIHtcclxuICAgICAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgICAgICAvLyBFeHBsaWNpdCB2ZXJzaW9uIHdhcyBzcGVjaWZpZWQuIE5vIG5lZWQgdG8gcXVlcnkgZm9yIGxpc3Qgb2YgdmVyc2lvbnMuXHJcbiAgICAgICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAgICAgdmVyc2lvbiA9IHZlcnNpb25TcGVjO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgICAgIC8vIExldCdzIHF1ZXJ5IGFuZCByZXNvbHZlIHRoZSBsYXRlc3QgdmVyc2lvbiBmb3IgdGhlIHZlcnNpb25TcGVjLlxyXG4gICAgICAgICAgICAgICAgLy8gSWYgdGhlIHZlcnNpb24gaXMgYW4gZXhwbGljaXQgdmVyc2lvbiAoMS4xLjEgb3IgdjEuMS4xKSB0aGVuIG5vIG5lZWQgdG8gcXVlcnkuXHJcbiAgICAgICAgICAgICAgICAvLyBJZiB5b3VyIHRvb2wgZG9lc24ndCBvZmZlciBhIG1lY2hhbmlzbSB0byBxdWVyeSxcclxuICAgICAgICAgICAgICAgIC8vIHRoZW4gaXQgY2FuIG9ubHkgc3VwcG9ydCBleGFjdCB2ZXJzaW9uIGlucHV0cy5cclxuICAgICAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgICAgICB2ZXJzaW9uID0gYXdhaXQgdGhpcy5xdWVyeUxhdGVzdE1hdGNoKHRvb2xOYW1lLCB2ZXJzaW9uU3BlYywgaW5jbHVkZVByZSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXZlcnNpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBmaW5kICR7dG9vbE5hbWV9IHZlcnNpb24gJyR7dmVyc2lvblNwZWN9Jy5gKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgdGhlIGNhY2hlIGZvciB0aGUgcmVzb2x2ZWQgdmVyc2lvbi5cclxuICAgICAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgICAgICB0b29sUGF0aCA9IHRoaXMuYnVpbGRBZ2VudC5maW5kKHRvb2xOYW1lLCB2ZXJzaW9uKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoIXRvb2xQYXRoKSB7XHJcbiAgICAgICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAgICAgLy8gRG93bmxvYWQsIGV4dHJhY3QsIGNhY2hlXHJcbiAgICAgICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAgICAgdG9vbFBhdGggPSBhd2FpdCB0aGlzLmFjcXVpcmVUb29sKHRvb2xOYW1lLCB2ZXJzaW9uKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBQcmVwZW5kIHRoZSB0b29scyBwYXRoLiBUaGlzIHByZXBlbmRzIHRoZSBQQVRIIGZvciB0aGUgY3VycmVudCBwcm9jZXNzIGFuZFxyXG4gICAgICAgIC8vIGluc3RydWN0cyB0aGUgYWdlbnQgdG8gcHJlcGVuZCBmb3IgZWFjaCB0YXNrIHRoYXQgZm9sbG93cy5cclxuICAgICAgICAvL1xyXG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZyhgdG9vbFBhdGg6ICR7dG9vbFBhdGh9YCk7XHJcblxyXG4gICAgICAgIGlmIChvcy5wbGF0Zm9ybSgpICE9PSBcIndpbjMyXCIpIHtcclxuICAgICAgICAgICAgY29uc3QgZG90bmV0Um9vdCA9IHBhdGguZGlybmFtZShmcy5yZWFkbGlua1N5bmMoYXdhaXQgdGhpcy5idWlsZEFnZW50LndoaWNoKFwiZG90bmV0XCIpKSk7XHJcbiAgICAgICAgICAgIHRoaXMuYnVpbGRBZ2VudC5leHBvcnRWYXJpYWJsZShcIkRPVE5FVF9ST09UXCIsIGRvdG5ldFJvb3QpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmJ1aWxkQWdlbnQuYWRkUGF0aCh0b29sUGF0aCk7XHJcblxyXG4gICAgICAgIHJldHVybiB0b29sUGF0aDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFzeW5jIHF1ZXJ5TGF0ZXN0TWF0Y2godG9vbE5hbWU6IHN0cmluZywgdmVyc2lvblNwZWM6IHN0cmluZywgaW5jbHVkZVByZXJlbGVhc2U6IGJvb2xlYW4pOiBQcm9taXNlPHN0cmluZz4ge1xyXG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZyhgcXVlcnlpbmcgdG9vbCB2ZXJzaW9ucyBmb3IgJHt0b29sTmFtZX0ke3ZlcnNpb25TcGVjID8gYEAke3ZlcnNpb25TcGVjfWAgOiBcIlwifSAke2luY2x1ZGVQcmVyZWxlYXNlID8gXCJpbmNsdWRpbmcgcHJlLXJlbGVhc2VzXCIgOiBcIlwifWApO1xyXG5cclxuICAgICAgICBjb25zdCBkb3dubG9hZFBhdGggPSBgaHR0cHM6Ly9hcGktdjJ2M3NlYXJjaC0wLm51Z2V0Lm9yZy9xdWVyeT9xPSR7ZW5jb2RlVVJJQ29tcG9uZW50KHRvb2xOYW1lLnRvTG93ZXJDYXNlKCkpfSZwcmVyZWxlYXNlPSR7aW5jbHVkZVByZXJlbGVhc2UgPyBcInRydWVcIiA6IFwiZmFsc2VcIn0mc2VtVmVyTGV2ZWw9Mi4wLjBgO1xyXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMuaHR0cENsaWVudC5nZXQoZG93bmxvYWRQYXRoKTtcclxuXHJcbiAgICAgICAgaWYgKCFyZXMgfHwgcmVzLm1lc3NhZ2Uuc3RhdHVzQ29kZSAhPT0gMjAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgYm9keTogc3RyaW5nID0gYXdhaXQgcmVzLnJlYWRCb2R5KCk7XHJcbiAgICAgICAgY29uc3QgZGF0YSA9IEpTT04ucGFyc2UoYm9keSkuZGF0YTtcclxuXHJcbiAgICAgICAgY29uc3QgdmVyc2lvbnMgPSAoZGF0YVswXS52ZXJzaW9ucyBhcyB7IHZlcnNpb246IHN0cmluZyB9W10pLm1hcCgoeCkgPT4geC52ZXJzaW9uKTtcclxuICAgICAgICBpZiAoIXZlcnNpb25zIHx8ICF2ZXJzaW9ucy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmJ1aWxkQWdlbnQuZGVidWcoYGdvdCB2ZXJzaW9uczogJHt2ZXJzaW9ucy5qb2luKFwiLCBcIil9YCk7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLnZlcnNpb25NYW5hZ2VyLmV2YWx1YXRlVmVyc2lvbnModmVyc2lvbnMsIHZlcnNpb25TcGVjKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFzeW5jIGFjcXVpcmVUb29sKHRvb2xOYW1lOiBzdHJpbmcsIHZlcnNpb246IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XHJcblxyXG4gICAgICAgIGNvbnN0IHRlbXBEaXJlY3RvcnkgPSBhd2FpdCB0aGlzLmJ1aWxkQWdlbnQuY3JlYXRlVGVtcERpcigpO1xyXG4gICAgICAgIGxldCBhcmdzID0gW1widG9vbFwiLCBcImluc3RhbGxcIiwgdG9vbE5hbWUsIFwiLS10b29sLXBhdGhcIiwgdGVtcERpcmVjdG9yeV07XHJcblxyXG4gICAgICAgIGlmICh2ZXJzaW9uKSB7XHJcbiAgICAgICAgICAgIHZlcnNpb24gPSB0aGlzLnZlcnNpb25NYW5hZ2VyLmNsZWFuVmVyc2lvbih2ZXJzaW9uKTtcclxuICAgICAgICAgICAgYXJncyA9IGFyZ3MuY29uY2F0KFtcIi0tdmVyc2lvblwiLCB2ZXJzaW9uXSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnJ1bihhcmdzKTtcclxuICAgICAgICBjb25zdCBzdGF0dXMgPSByZXN1bHQuY29kZSA9PT0gMCA/IFwic3VjY2Vzc1wiIDogXCJmYWlsdXJlXCI7XHJcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IHJlc3VsdC5jb2RlID09PSAwID8gcmVzdWx0LnN0ZG91dCA6IHJlc3VsdC5zdGRlcnI7XHJcblxyXG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZyhgdG9vbCBpbnN0YWxsIHJlc3VsdDogJHtzdGF0dXN9ICR7bWVzc2FnZX1gKTtcclxuXHJcbiAgICAgICAgaWYgKHJlc3VsdC5jb2RlKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkVycm9yIGluc3RhbGxpbmcgdG9vbFwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmJ1aWxkQWdlbnQuY2FjaGVEaXIodGVtcERpcmVjdG9yeSwgdG9vbE5hbWUsIHZlcnNpb24pO1xyXG4gICAgfVxyXG59IiwiaW1wb3J0IHsgQ29udGFpbmVyIH0gZnJvbSBcImludmVyc2lmeVwiO1xyXG5pbXBvcnQgeyBJVmVyc2lvbk1hbmFnZXIsIFZlcnNpb25NYW5hZ2VyIH0gZnJvbSBcIi4vdmVyc2lvbk1hbmFnZXJcIjtcclxuaW1wb3J0IHsgVFlQRVMsIElCdWlsZEFnZW50IH0gZnJvbSBcIi4vY29tbW9uXCI7XHJcbmltcG9ydCB7IEJ1aWxkQWdlbnQgfSBmcm9tIFwiLi4vYWdlbnQvbW9jay9idWlsZC1hZ2VudFwiO1xyXG5pbXBvcnQgeyBJRG90bmV0VG9vbCwgRG90bmV0VG9vbCB9IGZyb20gXCIuL2RvdG5ldC10b29sXCI7XHJcblxyXG5jb25zdCBjb250YWluZXIgPSBuZXcgQ29udGFpbmVyKCk7XHJcblxyXG5jb250YWluZXIuYmluZDxJVmVyc2lvbk1hbmFnZXI+KFRZUEVTLklWZXJzaW9uTWFuYWdlcikudG8oVmVyc2lvbk1hbmFnZXIpO1xyXG5jb250YWluZXIuYmluZDxJQnVpbGRBZ2VudD4oVFlQRVMuSUJ1aWxkQWdlbnQpLnRvKEJ1aWxkQWdlbnQpO1xyXG5jb250YWluZXIuYmluZDxJRG90bmV0VG9vbD4oVFlQRVMuSURvdG5ldFRvb2wpLnRvKERvdG5ldFRvb2wpO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgY29udGFpbmVyO1xyXG4iLCJpbXBvcnQgY21wIGZyb20gXCJzZW12ZXItY29tcGFyZVwiO1xyXG5pbXBvcnQgKiBhcyBzZW12ZXIgZnJvbSBcInNlbXZlclwiO1xyXG5pbXBvcnQgeyBpbmplY3RhYmxlLCBpbmplY3QgfSBmcm9tIFwiaW52ZXJzaWZ5XCI7XHJcblxyXG5pbXBvcnQgeyBJQnVpbGRBZ2VudCwgVFlQRVMgfSBmcm9tIFwiLi9jb21tb25cIjtcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgSVZlcnNpb25NYW5hZ2VyIHtcclxuICAgIGlzRXhwbGljaXRWZXJzaW9uKHZlcnNpb25TcGVjOiBzdHJpbmcpOiBib29sZWFuO1xyXG4gICAgZXZhbHVhdGVWZXJzaW9ucyh2ZXJzaW9uczogc3RyaW5nW10sIHZlcnNpb25TcGVjOiBzdHJpbmcpOiBzdHJpbmc7XHJcbiAgICBjbGVhblZlcnNpb24odmVyc2lvbjogc3RyaW5nKTogc3RyaW5nO1xyXG59XHJcblxyXG5AaW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBWZXJzaW9uTWFuYWdlciBpbXBsZW1lbnRzIElWZXJzaW9uTWFuYWdlciB7XHJcblxyXG4gICAgcHJpdmF0ZSBidWlsZEFnZW50OiBJQnVpbGRBZ2VudDtcclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIEBpbmplY3QoVFlQRVMuSUJ1aWxkQWdlbnQpIGJ1aWxkQWdlbnQ6IElCdWlsZEFnZW50LFxyXG4gICAgKSB7XHJcbiAgICAgICAgdGhpcy5idWlsZEFnZW50ID0gYnVpbGRBZ2VudDtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgaXNFeHBsaWNpdFZlcnNpb24odmVyc2lvblNwZWM6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgICAgIGNvbnN0IGMgPSBzZW12ZXIuY2xlYW4odmVyc2lvblNwZWMpO1xyXG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZyhcImlzRXhwbGljaXQ6IFwiICsgYyk7XHJcblxyXG4gICAgICAgIGNvbnN0IHZhbGlkID0gc2VtdmVyLnZhbGlkKGMpICE9IG51bGw7XHJcbiAgICAgICAgdGhpcy5idWlsZEFnZW50LmRlYnVnKFwiZXhwbGljaXQ/IFwiICsgdmFsaWQpO1xyXG5cclxuICAgICAgICByZXR1cm4gdmFsaWQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGV2YWx1YXRlVmVyc2lvbnModmVyc2lvbnM6IHN0cmluZ1tdLCB2ZXJzaW9uU3BlYzogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICBsZXQgdmVyc2lvbjogc3RyaW5nO1xyXG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZyhcImV2YWx1YXRpbmcgXCIgKyB2ZXJzaW9ucy5sZW5ndGggKyBcIiB2ZXJzaW9uc1wiKTtcclxuICAgICAgICB2ZXJzaW9ucyA9IHZlcnNpb25zLnNvcnQoY21wKTtcclxuICAgICAgICBmb3IgKGxldCBpID0gdmVyc2lvbnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICBjb25zdCBwb3RlbnRpYWw6IHN0cmluZyA9IHZlcnNpb25zW2ldO1xyXG4gICAgICAgIGNvbnN0IHNhdGlzZmllZDogYm9vbGVhbiA9IHNlbXZlci5zYXRpc2ZpZXMocG90ZW50aWFsLCB2ZXJzaW9uU3BlYyk7XHJcbiAgICAgICAgaWYgKHNhdGlzZmllZCkge1xyXG4gICAgICAgICAgICB2ZXJzaW9uID0gcG90ZW50aWFsO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgICAgIGlmICh2ZXJzaW9uKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZyhcIm1hdGNoZWQ6IFwiICsgdmVyc2lvbik7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZyhcIm1hdGNoIG5vdCBmb3VuZFwiKTtcclxuICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHZlcnNpb247XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGNsZWFuVmVyc2lvbih2ZXJzaW9uOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZyhcImNsZWFuaW5nOiBcIiArIHZlcnNpb24pO1xyXG4gICAgICAgIHJldHVybiBzZW12ZXIuY2xlYW4odmVyc2lvbik7XHJcbiAgICB9XHJcbn0iLCJpbXBvcnQgXCJyZWZsZWN0LW1ldGFkYXRhXCI7XHJcbmltcG9ydCB7IGNyZWF0ZSB9IGZyb20gXCIuL21haW5cIjtcclxuXHJcbmNyZWF0ZSgpO1xyXG4iLCJpbXBvcnQgeyBJQnVpbGRBZ2VudCwgVFlQRVMsIFNldHVwT3B0aW9ucyB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbW1vblwiO1xyXG5pbXBvcnQgeyBJR2l0UmVsZWFzZU1hbmFnZXJUb29sLCBHaXRSZWxlYXNlTWFuYWdlclRvb2wgfSBmcm9tIFwiLi4vLi4vdG9vbHMvZ2l0cmVsZWFzZW1hbmFnZXIvZ2l0cmVsZWFzZW1hbmFnZXItdG9vbFwiO1xyXG5cclxuaW1wb3J0IGNvbnRhaW5lciBmcm9tIFwiLi4vLi4vY29yZS9pb2NcIjtcclxuaW1wb3J0IHsgU2V0dGluZ3MgfSBmcm9tIFwiLi4vLi4vdG9vbHMvZ2l0cmVsZWFzZW1hbmFnZXIvc2V0dGluZ3NcIjtcclxuXHJcbmNvbnRhaW5lci5iaW5kPElHaXRSZWxlYXNlTWFuYWdlclRvb2w+KFRZUEVTLklHaXRSZWxlYXNlTWFuYWdlclRvb2wpLnRvKEdpdFJlbGVhc2VNYW5hZ2VyVG9vbCk7XHJcblxyXG5jb25zdCBnaXRSZWxlYXNlTWFuYWdlclRvb2wgPSBjb250YWluZXIuZ2V0PElHaXRSZWxlYXNlTWFuYWdlclRvb2w+KFRZUEVTLklHaXRSZWxlYXNlTWFuYWdlclRvb2wpO1xyXG5jb25zdCBidWlsZEFnZW50ID0gY29udGFpbmVyLmdldDxJQnVpbGRBZ2VudD4oVFlQRVMuSUJ1aWxkQWdlbnQpO1xyXG5cclxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNldHVwKCkge1xyXG4gICAgdHJ5IHtcclxuXHJcbiAgICAgICAgYnVpbGRBZ2VudC5leHBvcnRWYXJpYWJsZShcIkRPVE5FVF9DTElfVEVMRU1FVFJZX09QVE9VVFwiLCBcIjFcIik7XHJcblxyXG4gICAgICAgIGNvbnN0IHZlcnNpb25TcGVjID0gYnVpbGRBZ2VudC5nZXRJbnB1dChTZXR1cE9wdGlvbnMudmVyc2lvblNwZWMpO1xyXG4gICAgICAgIGNvbnN0IGluY2x1ZGVQcmVyZWxlYXNlID0gYnVpbGRBZ2VudC5nZXRCb29sZWFuSW5wdXQoU2V0dXBPcHRpb25zLmluY2x1ZGVQcmVyZWxlYXNlKTtcclxuXHJcbiAgICAgICAgYXdhaXQgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLmluc3RhbGwodmVyc2lvblNwZWMsIGluY2x1ZGVQcmVyZWxlYXNlKTtcclxuXHJcbiAgICAgICAgYnVpbGRBZ2VudC5zZXRTdWNjZWVkZWQoXCJHaXRWZXJzaW9uTWFuYWdlciBpbnN0YWxsZWQgc3VjY2Vzc2Z1bGx5XCIsIHRydWUpO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICBidWlsZEFnZW50LnNldEZhaWxlZChlcnJvci5tZXNzYWdlLCB0cnVlKTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZSgpIHtcclxuICAgIHRyeSB7XHJcblxyXG4gICAgICAgIGJ1aWxkQWdlbnQuZXhwb3J0VmFyaWFibGUoXCJET1RORVRfQ0xJX1RFTEVNRVRSWV9PUFRPVVRcIiwgXCIxXCIpO1xyXG5cclxuICAgICAgICBjb25zdCBzZXR0aW5ncyA9IFNldHRpbmdzLmdldENyZWF0ZVNldHRpbmdzKGJ1aWxkQWdlbnQpO1xyXG5cclxuICAgICAgICBhd2FpdCBnaXRSZWxlYXNlTWFuYWdlclRvb2wuY3JlYXRlKHNldHRpbmdzKTtcclxuXHJcbiAgICAgICAgYnVpbGRBZ2VudC5zZXRTdWNjZWVkZWQoXCJHaXRWZXJzaW9uTWFuYWdlciBjcmVhdGVkIHJlbGVhc2Ugc3VjY2Vzc2Z1bGx5XCIsIHRydWUpO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICBidWlsZEFnZW50LnNldEZhaWxlZChlcnJvci5tZXNzYWdlLCB0cnVlKTtcclxuICAgIH1cclxufSIsImltcG9ydCBwYXRoID0gcmVxdWlyZShcInBhdGhcIik7XHJcblxyXG5pbXBvcnQgeyBUWVBFUywgSUJ1aWxkQWdlbnQsIElFeGVjUmVzdWx0IH0gZnJvbSBcIi4uLy4uL2NvcmUvY29tbW9uXCI7XHJcbmltcG9ydCB7IGluamVjdGFibGUsIGluamVjdCB9IGZyb20gXCJpbnZlcnNpZnlcIjtcclxuaW1wb3J0IHsgSURvdG5ldFRvb2wgfSBmcm9tIFwiLi4vLi4vY29yZS9kb3RuZXQtdG9vbFwiO1xyXG5pbXBvcnQgeyBHaXRSZWxlYXNlTWFuYWdlckNyZWF0ZVNldHRpbmdzLCBHaXRSZWxlYXNlTWFuYWdlclNldHRpbmdzLCBDcmVhdGVGaWVsZHMsIENvbW1vbkZpZWxkcyB9IGZyb20gXCIuL21vZGVsc1wiO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBJR2l0UmVsZWFzZU1hbmFnZXJUb29sIHtcclxuICAgIGluc3RhbGwodmVyc2lvblNwZWM6IHN0cmluZywgaW5jbHVkZVByZXJlbGVhc2U6IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+O1xyXG4gICAgY3JlYXRlKHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlckNyZWF0ZVNldHRpbmdzKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD47XHJcbn1cclxuXHJcbkBpbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIEdpdFJlbGVhc2VNYW5hZ2VyVG9vbCBpbXBsZW1lbnRzIElHaXRSZWxlYXNlTWFuYWdlclRvb2wge1xyXG5cclxuICAgIHByaXZhdGUgYnVpbGRBZ2VudDogSUJ1aWxkQWdlbnQ7XHJcbiAgICBwcml2YXRlIGRvdG5ldFRvb2w6IElEb3RuZXRUb29sO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIEBpbmplY3QoVFlQRVMuSUJ1aWxkQWdlbnQpIGJ1aWxkQWdlbnQ6IElCdWlsZEFnZW50LFxyXG4gICAgICAgIEBpbmplY3QoVFlQRVMuSURvdG5ldFRvb2wpIGRvdG5ldFRvb2w6IElEb3RuZXRUb29sLFxyXG4gICAgKSB7XHJcbiAgICAgICAgdGhpcy5kb3RuZXRUb29sID0gZG90bmV0VG9vbDtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgaW5zdGFsbCh2ZXJzaW9uU3BlYzogc3RyaW5nLCBpbmNsdWRlUHJlcmVsZWFzZTogYm9vbGVhbik6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGF3YWl0IHRoaXMuZG90bmV0VG9vbC50b29sSW5zdGFsbChcIkdpdFJlbGVhc2VNYW5hZ2VyLlRvb2xcIiwgdmVyc2lvblNwZWMsIGZhbHNlLCBpbmNsdWRlUHJlcmVsZWFzZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGNyZWF0ZShzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJDcmVhdGVTZXR0aW5ncyk6IFByb21pc2U8SUV4ZWNSZXN1bHQ+IHtcclxuICAgICAgICBjb25zdCBhcmdzID0gdGhpcy5nZXRDcmVhdGVBcmd1bWVudHMoc2V0dGluZ3MpO1xyXG5cclxuICAgICAgICBjb25zb2xlLmxvZyhhcmdzKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShudWxsKTtcclxuXHJcbiAgICAgICAgLy8gcmV0dXJuIHRoaXMuYnVpbGRBZ2VudC5leGVjKFwiZG90bmV0LWdpdHJlbGVhc2VtYW5hZ2VyXCIsIGFyZ3MpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldENvbW1vbkFyZ3VtZW50cyhzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJTZXR0aW5ncyk6IHN0cmluZ1tdIHtcclxuICAgICAgICBjb25zdCBhcmdzOiBzdHJpbmdbXSA9IFtdO1xyXG5cclxuICAgICAgICBhcmdzLnB1c2goXCItLW93bmVyXCIsIHNldHRpbmdzLm93bmVyKTtcclxuICAgICAgICBhcmdzLnB1c2goXCItLXJlcG9zaXRvcnlcIiwgc2V0dGluZ3MucmVwb3NpdG9yeSk7XHJcbiAgICAgICAgYXJncy5wdXNoKFwiLS10b2tlblwiLCBzZXR0aW5ncy50b2tlbik7XHJcblxyXG4gICAgICAgIHJldHVybiBhcmdzO1xyXG4gICAgfVxyXG5cclxuICAgIGdldENyZWF0ZUFyZ3VtZW50cyhzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJDcmVhdGVTZXR0aW5ncyk6IHN0cmluZ1tdIHtcclxuICAgICAgICBjb25zdCBhcmdzOiBzdHJpbmdbXSA9IFsuLi50aGlzLmdldENvbW1vbkFyZ3VtZW50cyhzZXR0aW5ncyldO1xyXG5cclxuICAgICAgICBhcmdzLnB1c2goXCItLW1pbGVzdG9uZVwiLCBzZXR0aW5ncy5taWxlc3RvbmUpO1xyXG4gICAgICAgIGFyZ3MucHVzaChcIi0tbmFtZVwiLCBzZXR0aW5ncy5yZWxlYXNlTmFtZSk7XHJcbiAgICAgICAgYXJncy5wdXNoKFwiLS10YXJnZXRjb21taXRpc2hcIiwgc2V0dGluZ3MuY29tbWl0KTtcclxuICAgICAgICBhcmdzLnB1c2goXCItLXRhcmdldERpcmVjdG9yeVwiLCBzZXR0aW5ncy50YXJnZXREaXJlY3RvcnkpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5idWlsZEFnZW50LmZpbGVFeGlzdHMoc2V0dGluZ3MuaW5wdXRGaWxlTmFtZSkpIHtcclxuICAgICAgICAgICAgYXJncy5wdXNoKFwiLS1pbnB1dEZpbGVQYXRoXCIsIHNldHRpbmdzLmlucHV0RmlsZU5hbWUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkdpdFJlbGVhc2VNYW5hZ2VyIGlucHV0RmlsZVBhdGggbm90IGZvdW5kIGF0IFwiICsgc2V0dGluZ3MuaW5wdXRGaWxlTmFtZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChzZXR0aW5ncy5pc1ByZVJlbGVhc2UpIHtcclxuICAgICAgICAgICAgYXJncy5wdXNoKFwiLS1wcmVcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gYXJncztcclxuICAgIH1cclxufVxyXG4iLCJleHBvcnQgZW51bSBDb21tb25GaWVsZHMge1xyXG4gICAgcmVwb3NpdG9yeSA9IFwicmVwb3NpdG9yeVwiLFxyXG4gICAgb3duZXIgPSBcIm93bmVyXCIsXHJcbiAgICB0b2tlbiA9IFwidG9rZW5cIixcclxufVxyXG5cclxuZXhwb3J0IGVudW0gQ3JlYXRlRmllbGRzIHtcclxuICAgIG1pbGVzdG9uZSA9IFwibWlsZXN0b25lXCIsXHJcbiAgICByZWxlYXNlTmFtZSA9IFwicmVsZWFzZU5hbWVcIixcclxuICAgIGlucHV0RmlsZU5hbWUgPSBcImlucHV0RmlsZU5hbWVcIixcclxuICAgIGlzUHJlUmVsZWFzZSA9IFwiaXNQcmVSZWxlYXNlXCIsXHJcbiAgICBjb21taXQgPSBcImNvbW1pdFwiLFxyXG4gICAgdGFyZ2V0RGlyZWN0b3J5ID0gXCJ0YXJnZXREaXJlY3RvcnlcIixcclxuICAgIGFzc2V0cyA9IFwiYXNzZXRzXCIsXHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgR2l0UmVsZWFzZU1hbmFnZXJTZXR0aW5ncyB7XHJcbiAgICBbQ29tbW9uRmllbGRzLnJlcG9zaXRvcnldOiBzdHJpbmc7XHJcbiAgICBbQ29tbW9uRmllbGRzLm93bmVyXTogc3RyaW5nO1xyXG4gICAgW0NvbW1vbkZpZWxkcy50b2tlbl06IHN0cmluZztcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBHaXRSZWxlYXNlTWFuYWdlckNyZWF0ZVNldHRpbmdzIGV4dGVuZHMgR2l0UmVsZWFzZU1hbmFnZXJTZXR0aW5ncyB7XHJcbiAgICBbQ3JlYXRlRmllbGRzLm1pbGVzdG9uZV06IHN0cmluZztcclxuICAgIFtDcmVhdGVGaWVsZHMucmVsZWFzZU5hbWVdOiBzdHJpbmc7XHJcbiAgICBbQ3JlYXRlRmllbGRzLmlucHV0RmlsZU5hbWVdOiBzdHJpbmc7XHJcbiAgICBbQ3JlYXRlRmllbGRzLmlzUHJlUmVsZWFzZV06IGJvb2xlYW47XHJcbiAgICBbQ3JlYXRlRmllbGRzLmNvbW1pdF06IHN0cmluZztcclxuICAgIFtDcmVhdGVGaWVsZHMudGFyZ2V0RGlyZWN0b3J5XTogc3RyaW5nO1xyXG4gICAgW0NyZWF0ZUZpZWxkcy5hc3NldHNdPzogc3RyaW5nW107XHJcbn0iLCJpbXBvcnQgeyBJQnVpbGRBZ2VudCB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbW1vblwiO1xyXG5pbXBvcnQgeyBHaXRSZWxlYXNlTWFuYWdlclNldHRpbmdzLCBDb21tb25GaWVsZHMsIENyZWF0ZUZpZWxkcyB9IGZyb20gXCIuL21vZGVsc1wiO1xyXG5cclxuZXhwb3J0IGNsYXNzIFNldHRpbmdzIHtcclxuICAgIHB1YmxpYyBzdGF0aWMgZ2V0Q3JlYXRlU2V0dGluZ3MoYnVpbGRBZ2VudDogSUJ1aWxkQWdlbnQpIHtcclxuICAgICAgICBjb25zdCBtaWxlc3RvbmUgPSBidWlsZEFnZW50LmdldElucHV0KENyZWF0ZUZpZWxkcy5taWxlc3RvbmUpO1xyXG4gICAgICAgIGNvbnN0IHJlbGVhc2VOYW1lID0gYnVpbGRBZ2VudC5nZXRJbnB1dChDcmVhdGVGaWVsZHMucmVsZWFzZU5hbWUpO1xyXG4gICAgICAgIGNvbnN0IGlucHV0RmlsZU5hbWUgPSBidWlsZEFnZW50LmdldElucHV0KENyZWF0ZUZpZWxkcy5pbnB1dEZpbGVOYW1lKTtcclxuICAgICAgICBjb25zdCBpc1ByZVJlbGVhc2UgPSBidWlsZEFnZW50LmdldEJvb2xlYW5JbnB1dChDcmVhdGVGaWVsZHMuaXNQcmVSZWxlYXNlKTtcclxuICAgICAgICBjb25zdCBjb21taXQgPSBidWlsZEFnZW50LmdldElucHV0KENyZWF0ZUZpZWxkcy5jb21taXQpO1xyXG4gICAgICAgIGNvbnN0IHRhcmdldERpcmVjdG9yeSA9IGJ1aWxkQWdlbnQuZ2V0SW5wdXQoQ3JlYXRlRmllbGRzLnRhcmdldERpcmVjdG9yeSk7XHJcblxyXG4gICAgICAgIGNvbnN0IGNvbW1vblNldHRpbmdzID0gU2V0dGluZ3MuZ2V0Q29tbW9uU2V0dGluZ3MoYnVpbGRBZ2VudCk7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgLi4uY29tbW9uU2V0dGluZ3MsXHJcbiAgICAgICAgICAgIG1pbGVzdG9uZSxcclxuICAgICAgICAgICAgcmVsZWFzZU5hbWUsXHJcbiAgICAgICAgICAgIGlucHV0RmlsZU5hbWUsXHJcbiAgICAgICAgICAgIGlzUHJlUmVsZWFzZSxcclxuICAgICAgICAgICAgY29tbWl0LFxyXG4gICAgICAgICAgICB0YXJnZXREaXJlY3RvcnlcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdGF0aWMgZ2V0Q29tbW9uU2V0dGluZ3MoYnVpbGRBZ2VudDogSUJ1aWxkQWdlbnQpOiBHaXRSZWxlYXNlTWFuYWdlclNldHRpbmdzIHtcclxuICAgICAgICBjb25zdCBvd25lciA9IGJ1aWxkQWdlbnQuZ2V0SW5wdXQoQ29tbW9uRmllbGRzLm93bmVyLCB0cnVlKTtcclxuICAgICAgICBjb25zdCByZXBvc2l0b3J5ID0gYnVpbGRBZ2VudC5nZXRJbnB1dChDb21tb25GaWVsZHMucmVwb3NpdG9yeSwgdHJ1ZSk7XHJcbiAgICAgICAgY29uc3QgdG9rZW4gPSBidWlsZEFnZW50LmdldElucHV0KENvbW1vbkZpZWxkcy50b2tlbiwgdHJ1ZSk7XHJcblxyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIG93bmVyLFxyXG4gICAgICAgICAgICByZXBvc2l0b3J5LFxyXG4gICAgICAgICAgICB0b2tlblxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbn0iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJhc3NlcnRcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiY2hpbGRfcHJvY2Vzc1wiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJjcnlwdG9cIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiZXZlbnRzXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImZzXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImh0dHBcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiaHR0cHNcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwibmV0XCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIm9zXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInBhdGhcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwidGxzXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInVybFwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ1dGlsXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInpsaWJcIik7Il0sInNvdXJjZVJvb3QiOiIifQ==