22337 lines
1.9 MiB
22337 lines
1.9 MiB
/******/ (() => { // webpackBootstrap
|
||
/******/ var __webpack_modules__ = ({
|
||
|
||
/***/ "./node_modules/azure-pipelines-task-lib/internal.js":
|
||
/*!***********************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-task-lib/internal.js ***!
|
||
\***********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports._exposeCertSettings = exports._exposeProxySettings = exports._normalizeSeparators = exports._isRooted = exports._getDirectoryName = exports._ensureRooted = exports._loadData = exports._ensurePatternRooted = exports._getFindInfoFromPattern = exports._cloneMatchOptions = exports._legacyFindFiles_convertPatternToRegExp = exports._which = exports._checkPath = exports._exist = exports._debug = exports._error = exports._warning = exports._command = exports._getVariableKey = exports._getVariable = exports._loc = exports._setResourcePath = exports._setErrStream = exports._setStdStream = exports._writeLine = exports._endsWith = exports._startsWith = exports._vault = exports._knownVariableMap = void 0;
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var os = __webpack_require__(/*! os */ "os");
|
||
var minimatch = __webpack_require__(/*! minimatch */ "./node_modules/minimatch/minimatch.js");
|
||
var util = __webpack_require__(/*! util */ "util");
|
||
var tcm = __webpack_require__(/*! ./taskcommand */ "./node_modules/azure-pipelines-task-lib/taskcommand.js");
|
||
var vm = __webpack_require__(/*! ./vault */ "./node_modules/azure-pipelines-task-lib/vault.js");
|
||
var semver = __webpack_require__(/*! semver */ "./node_modules/semver/semver.js");
|
||
var crypto = __webpack_require__(/*! crypto */ "crypto");
|
||
/**
|
||
* Hash table of known variable info. The formatted env var name is the lookup key.
|
||
*
|
||
* The purpose of this hash table is to keep track of known variables. The hash table
|
||
* needs to be maintained for multiple reasons:
|
||
* 1) to distinguish between env vars and job vars
|
||
* 2) to distinguish between secret vars and public
|
||
* 3) to know the real variable name and not just the formatted env var name.
|
||
*/
|
||
exports._knownVariableMap = {};
|
||
//-----------------------------------------------------
|
||
// Validation Checks
|
||
//-----------------------------------------------------
|
||
// async await needs generators in node 4.x+
|
||
if (semver.lt(process.versions.node, '4.2.0')) {
|
||
_warning('Tasks require a new agent. Upgrade your agent or node to 4.2.0 or later');
|
||
}
|
||
//-----------------------------------------------------
|
||
// String convenience
|
||
//-----------------------------------------------------
|
||
function _startsWith(str, start) {
|
||
return str.slice(0, start.length) == start;
|
||
}
|
||
exports._startsWith = _startsWith;
|
||
function _endsWith(str, end) {
|
||
return str.slice(-end.length) == end;
|
||
}
|
||
exports._endsWith = _endsWith;
|
||
//-----------------------------------------------------
|
||
// General Helpers
|
||
//-----------------------------------------------------
|
||
var _outStream = process.stdout;
|
||
var _errStream = process.stderr;
|
||
function _writeLine(str) {
|
||
_outStream.write(str + os.EOL);
|
||
}
|
||
exports._writeLine = _writeLine;
|
||
function _setStdStream(stdStream) {
|
||
_outStream = stdStream;
|
||
}
|
||
exports._setStdStream = _setStdStream;
|
||
function _setErrStream(errStream) {
|
||
_errStream = errStream;
|
||
}
|
||
exports._setErrStream = _setErrStream;
|
||
//-----------------------------------------------------
|
||
// Loc Helpers
|
||
//-----------------------------------------------------
|
||
var _locStringCache = {};
|
||
var _resourceFiles = {};
|
||
var _libResourceFileLoaded = false;
|
||
var _resourceCulture = 'en-US';
|
||
function _loadResJson(resjsonFile) {
|
||
var resJson;
|
||
if (_exist(resjsonFile)) {
|
||
var resjsonContent = fs.readFileSync(resjsonFile, 'utf8').toString();
|
||
// remove BOM
|
||
if (resjsonContent.indexOf('\uFEFF') == 0) {
|
||
resjsonContent = resjsonContent.slice(1);
|
||
}
|
||
try {
|
||
resJson = JSON.parse(resjsonContent);
|
||
}
|
||
catch (err) {
|
||
_debug('unable to parse resjson with err: ' + err.message);
|
||
}
|
||
}
|
||
else {
|
||
_debug('.resjson file not found: ' + resjsonFile);
|
||
}
|
||
return resJson;
|
||
}
|
||
function _loadLocStrings(resourceFile, culture) {
|
||
var locStrings = {};
|
||
if (_exist(resourceFile)) {
|
||
var resourceJson = _loadResJson(resourceFile);
|
||
if (resourceJson && resourceJson.hasOwnProperty('messages')) {
|
||
var locResourceJson;
|
||
// load up resource resjson for different culture
|
||
var localizedResourceFile = path.join(path.dirname(resourceFile), 'Strings', 'resources.resjson');
|
||
var upperCulture = culture.toUpperCase();
|
||
var cultures = [];
|
||
try {
|
||
cultures = fs.readdirSync(localizedResourceFile);
|
||
}
|
||
catch (ex) { }
|
||
for (var i = 0; i < cultures.length; i++) {
|
||
if (cultures[i].toUpperCase() == upperCulture) {
|
||
localizedResourceFile = path.join(localizedResourceFile, cultures[i], 'resources.resjson');
|
||
if (_exist(localizedResourceFile)) {
|
||
locResourceJson = _loadResJson(localizedResourceFile);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
for (var key in resourceJson.messages) {
|
||
if (locResourceJson && locResourceJson.hasOwnProperty('loc.messages.' + key)) {
|
||
locStrings[key] = locResourceJson['loc.messages.' + key];
|
||
}
|
||
else {
|
||
locStrings[key] = resourceJson.messages[key];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
_warning('LIB_ResourceFile does not exist');
|
||
}
|
||
return locStrings;
|
||
}
|
||
/**
|
||
* Sets the location of the resources json. This is typically the task.json file.
|
||
* Call once at the beginning of the script before any calls to loc.
|
||
* @param path Full path to the json.
|
||
* @param ignoreWarnings Won't throw warnings if path already set.
|
||
* @returns void
|
||
*/
|
||
function _setResourcePath(path, ignoreWarnings) {
|
||
if (ignoreWarnings === void 0) { ignoreWarnings = false; }
|
||
if (process.env['TASKLIB_INPROC_UNITS']) {
|
||
_resourceFiles = {};
|
||
_libResourceFileLoaded = false;
|
||
_locStringCache = {};
|
||
_resourceCulture = 'en-US';
|
||
}
|
||
if (!_resourceFiles[path]) {
|
||
_checkPath(path, 'resource file path');
|
||
_resourceFiles[path] = path;
|
||
_debug('adding resource file: ' + path);
|
||
_resourceCulture = _getVariable('system.culture') || _resourceCulture;
|
||
var locStrs = _loadLocStrings(path, _resourceCulture);
|
||
for (var key in locStrs) {
|
||
//cache loc string
|
||
_locStringCache[key] = locStrs[key];
|
||
}
|
||
}
|
||
else {
|
||
if (ignoreWarnings) {
|
||
_debug(_loc('LIB_ResourceFileAlreadySet', path));
|
||
}
|
||
else {
|
||
_warning(_loc('LIB_ResourceFileAlreadySet', path));
|
||
}
|
||
}
|
||
}
|
||
exports._setResourcePath = _setResourcePath;
|
||
/**
|
||
* Gets the localized string from the json resource file. Optionally formats with additional params.
|
||
*
|
||
* @param key key of the resources string in the resource file
|
||
* @param param additional params for formatting the string
|
||
* @returns string
|
||
*/
|
||
function _loc(key) {
|
||
var param = [];
|
||
for (var _i = 1; _i < arguments.length; _i++) {
|
||
param[_i - 1] = arguments[_i];
|
||
}
|
||
if (!_libResourceFileLoaded) {
|
||
// merge loc strings from azure-pipelines-task-lib.
|
||
var libResourceFile = path.join(__dirname, 'lib.json');
|
||
var libLocStrs = _loadLocStrings(libResourceFile, _resourceCulture);
|
||
for (var libKey in libLocStrs) {
|
||
//cache azure-pipelines-task-lib loc string
|
||
_locStringCache[libKey] = libLocStrs[libKey];
|
||
}
|
||
_libResourceFileLoaded = true;
|
||
}
|
||
var locString;
|
||
;
|
||
if (_locStringCache.hasOwnProperty(key)) {
|
||
locString = _locStringCache[key];
|
||
}
|
||
else {
|
||
if (Object.keys(_resourceFiles).length <= 0) {
|
||
_warning(_loc('LIB_ResourceFileNotSet', key));
|
||
}
|
||
else {
|
||
_warning(_loc('LIB_LocStringNotFound', key));
|
||
}
|
||
locString = key;
|
||
}
|
||
if (param.length > 0) {
|
||
return util.format.apply(this, [locString].concat(param));
|
||
}
|
||
else {
|
||
return locString;
|
||
}
|
||
}
|
||
exports._loc = _loc;
|
||
//-----------------------------------------------------
|
||
// Input Helpers
|
||
//-----------------------------------------------------
|
||
/**
|
||
* Gets a variable value that is defined on the build/release definition or set at runtime.
|
||
*
|
||
* @param name name of the variable to get
|
||
* @returns string
|
||
*/
|
||
function _getVariable(name) {
|
||
var varval;
|
||
// get the metadata
|
||
var info;
|
||
var key = _getVariableKey(name);
|
||
if (exports._knownVariableMap.hasOwnProperty(key)) {
|
||
info = exports._knownVariableMap[key];
|
||
}
|
||
if (info && info.secret) {
|
||
// get the secret value
|
||
varval = exports._vault.retrieveSecret('SECRET_' + key);
|
||
}
|
||
else {
|
||
// get the public value
|
||
varval = process.env[key];
|
||
// fallback for pre 2.104.1 agent
|
||
if (!varval && name.toUpperCase() == 'AGENT.JOBSTATUS') {
|
||
varval = process.env['agent.jobstatus'];
|
||
}
|
||
}
|
||
_debug(name + '=' + varval);
|
||
return varval;
|
||
}
|
||
exports._getVariable = _getVariable;
|
||
function _getVariableKey(name) {
|
||
if (!name) {
|
||
throw new Error(_loc('LIB_ParameterIsRequired', 'name'));
|
||
}
|
||
return name.replace(/\./g, '_').replace(/ /g, '_').toUpperCase();
|
||
}
|
||
exports._getVariableKey = _getVariableKey;
|
||
//-----------------------------------------------------
|
||
// Cmd Helpers
|
||
//-----------------------------------------------------
|
||
function _command(command, properties, message) {
|
||
var taskCmd = new tcm.TaskCommand(command, properties, message);
|
||
_writeLine(taskCmd.toString());
|
||
}
|
||
exports._command = _command;
|
||
function _warning(message) {
|
||
_command('task.issue', { 'type': 'warning' }, message);
|
||
}
|
||
exports._warning = _warning;
|
||
function _error(message) {
|
||
_command('task.issue', { 'type': 'error' }, message);
|
||
}
|
||
exports._error = _error;
|
||
function _debug(message) {
|
||
_command('task.debug', null, message);
|
||
}
|
||
exports._debug = _debug;
|
||
// //-----------------------------------------------------
|
||
// // Disk Functions
|
||
// //-----------------------------------------------------
|
||
/**
|
||
* Returns whether a path exists.
|
||
*
|
||
* @param path path to check
|
||
* @returns boolean
|
||
*/
|
||
function _exist(path) {
|
||
var exist = false;
|
||
try {
|
||
exist = !!(path && fs.statSync(path) != null);
|
||
}
|
||
catch (err) {
|
||
if (err && err.code === 'ENOENT') {
|
||
exist = false;
|
||
}
|
||
else {
|
||
throw err;
|
||
}
|
||
}
|
||
return exist;
|
||
}
|
||
exports._exist = _exist;
|
||
/**
|
||
* Checks whether a path exists.
|
||
* If the path does not exist, it will throw.
|
||
*
|
||
* @param p path to check
|
||
* @param name name only used in error message to identify the path
|
||
* @returns void
|
||
*/
|
||
function _checkPath(p, name) {
|
||
_debug('check path : ' + p);
|
||
if (!_exist(p)) {
|
||
throw new Error(_loc('LIB_PathNotFound', name, p));
|
||
}
|
||
}
|
||
exports._checkPath = _checkPath;
|
||
/**
|
||
* 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 string
|
||
*/
|
||
function _which(tool, check) {
|
||
if (!tool) {
|
||
throw new Error('parameter \'tool\' is required');
|
||
}
|
||
// recursive when check=true
|
||
if (check) {
|
||
var result = _which(tool, false);
|
||
if (result) {
|
||
return result;
|
||
}
|
||
else {
|
||
if (process.platform == 'win32') {
|
||
throw new Error(_loc('LIB_WhichNotFound_Win', tool));
|
||
}
|
||
else {
|
||
throw new Error(_loc('LIB_WhichNotFound_Linux', tool));
|
||
}
|
||
}
|
||
}
|
||
_debug("which '" + tool + "'");
|
||
try {
|
||
// build the list of extensions to try
|
||
var extensions = [];
|
||
if (process.platform == 'win32' && process.env['PATHEXT']) {
|
||
for (var _i = 0, _a = process.env['PATHEXT'].split(path.delimiter); _i < _a.length; _i++) {
|
||
var extension = _a[_i];
|
||
if (extension) {
|
||
extensions.push(extension);
|
||
}
|
||
}
|
||
}
|
||
// if it's rooted, return it if exists. otherwise return empty.
|
||
if (_isRooted(tool)) {
|
||
var filePath = _tryGetExecutablePath(tool, extensions);
|
||
if (filePath) {
|
||
_debug("found: '" + filePath + "'");
|
||
return filePath;
|
||
}
|
||
_debug('not found');
|
||
return '';
|
||
}
|
||
// if any path separators, return empty
|
||
if (tool.indexOf('/') >= 0 || (process.platform == 'win32' && tool.indexOf('\\') >= 0)) {
|
||
_debug('not found');
|
||
return '';
|
||
}
|
||
// build the list of directories
|
||
//
|
||
// Note, technically "where" checks the current directory on Windows. From a task lib 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 task lib should strive for consistency
|
||
// across platforms.
|
||
var directories = [];
|
||
if (process.env['PATH']) {
|
||
for (var _b = 0, _c = process.env['PATH'].split(path.delimiter); _b < _c.length; _b++) {
|
||
var p = _c[_b];
|
||
if (p) {
|
||
directories.push(p);
|
||
}
|
||
}
|
||
}
|
||
// return the first match
|
||
for (var _d = 0, directories_1 = directories; _d < directories_1.length; _d++) {
|
||
var directory = directories_1[_d];
|
||
var filePath = _tryGetExecutablePath(directory + path.sep + tool, extensions);
|
||
if (filePath) {
|
||
_debug("found: '" + filePath + "'");
|
||
return filePath;
|
||
}
|
||
}
|
||
_debug('not found');
|
||
return '';
|
||
}
|
||
catch (err) {
|
||
throw new Error(_loc('LIB_OperationFailed', 'which', err.message));
|
||
}
|
||
}
|
||
exports._which = _which;
|
||
/**
|
||
* 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) {
|
||
try {
|
||
// test file exists
|
||
var stats = fs.statSync(filePath);
|
||
if (stats.isFile()) {
|
||
if (process.platform == 'win32') {
|
||
// on Windows, test for valid extension
|
||
var isExecutable = false;
|
||
var fileName = path.basename(filePath);
|
||
var dotIndex = fileName.lastIndexOf('.');
|
||
if (dotIndex >= 0) {
|
||
var upperExt_1 = fileName.substr(dotIndex).toUpperCase();
|
||
if (extensions.some(function (validExt) { return validExt.toUpperCase() == upperExt_1; })) {
|
||
return filePath;
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
if (isUnixExecutable(stats)) {
|
||
return filePath;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (err) {
|
||
if (err.code != 'ENOENT') {
|
||
_debug("Unexpected error attempting to determine if executable file exists '" + filePath + "': " + err);
|
||
}
|
||
}
|
||
// try each extension
|
||
var originalFilePath = filePath;
|
||
for (var _i = 0, extensions_1 = extensions; _i < extensions_1.length; _i++) {
|
||
var extension = extensions_1[_i];
|
||
var found = false;
|
||
var filePath_1 = originalFilePath + extension;
|
||
try {
|
||
var stats = fs.statSync(filePath_1);
|
||
if (stats.isFile()) {
|
||
if (process.platform == 'win32') {
|
||
// preserve the case of the actual file (since an extension was appended)
|
||
try {
|
||
var directory = path.dirname(filePath_1);
|
||
var upperName = path.basename(filePath_1).toUpperCase();
|
||
for (var _a = 0, _b = fs.readdirSync(directory); _a < _b.length; _a++) {
|
||
var actualName = _b[_a];
|
||
if (upperName == actualName.toUpperCase()) {
|
||
filePath_1 = path.join(directory, actualName);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
catch (err) {
|
||
_debug("Unexpected error attempting to determine the actual case of the file '" + filePath_1 + "': " + err);
|
||
}
|
||
return filePath_1;
|
||
}
|
||
else {
|
||
if (isUnixExecutable(stats)) {
|
||
return filePath_1;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (err) {
|
||
if (err.code != 'ENOENT') {
|
||
_debug("Unexpected error attempting to determine if executable file exists '" + filePath_1 + "': " + err);
|
||
}
|
||
}
|
||
}
|
||
return '';
|
||
}
|
||
// 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());
|
||
}
|
||
function _legacyFindFiles_convertPatternToRegExp(pattern) {
|
||
pattern = (process.platform == 'win32' ? pattern.replace(/\\/g, '/') : pattern) // normalize separator on Windows
|
||
.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') // regex escape - from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
|
||
.replace(/\\\/\\\*\\\*\\\//g, '((\/.+/)|(\/))') // replace directory globstar, e.g. /hello/**/world
|
||
.replace(/\\\*\\\*/g, '.*') // replace remaining globstars with a wildcard that can span directory separators, e.g. /hello/**dll
|
||
.replace(/\\\*/g, '[^\/]*') // replace asterisks with a wildcard that cannot span directory separators, e.g. /hello/*.dll
|
||
.replace(/\\\?/g, '[^\/]'); // replace single character wildcards, e.g. /hello/log?.dll
|
||
pattern = "^" + pattern + "$";
|
||
var flags = process.platform == 'win32' ? 'i' : '';
|
||
return new RegExp(pattern, flags);
|
||
}
|
||
exports._legacyFindFiles_convertPatternToRegExp = _legacyFindFiles_convertPatternToRegExp;
|
||
function _cloneMatchOptions(matchOptions) {
|
||
return {
|
||
debug: matchOptions.debug,
|
||
nobrace: matchOptions.nobrace,
|
||
noglobstar: matchOptions.noglobstar,
|
||
dot: matchOptions.dot,
|
||
noext: matchOptions.noext,
|
||
nocase: matchOptions.nocase,
|
||
nonull: matchOptions.nonull,
|
||
matchBase: matchOptions.matchBase,
|
||
nocomment: matchOptions.nocomment,
|
||
nonegate: matchOptions.nonegate,
|
||
flipNegate: matchOptions.flipNegate
|
||
};
|
||
}
|
||
exports._cloneMatchOptions = _cloneMatchOptions;
|
||
function _getFindInfoFromPattern(defaultRoot, pattern, matchOptions) {
|
||
// parameter validation
|
||
if (!defaultRoot) {
|
||
throw new Error('getFindRootFromPattern() parameter defaultRoot cannot be empty');
|
||
}
|
||
if (!pattern) {
|
||
throw new Error('getFindRootFromPattern() parameter pattern cannot be empty');
|
||
}
|
||
if (!matchOptions.nobrace) {
|
||
throw new Error('getFindRootFromPattern() expected matchOptions.nobrace to be true');
|
||
}
|
||
// for the sake of determining the findPath, pretend nocase=false
|
||
matchOptions = _cloneMatchOptions(matchOptions);
|
||
matchOptions.nocase = false;
|
||
// check if basename only and matchBase=true
|
||
if (matchOptions.matchBase &&
|
||
!_isRooted(pattern) &&
|
||
(process.platform == 'win32' ? pattern.replace(/\\/g, '/') : pattern).indexOf('/') < 0) {
|
||
return {
|
||
adjustedPattern: pattern,
|
||
findPath: defaultRoot,
|
||
statOnly: false,
|
||
};
|
||
}
|
||
// the technique applied by this function is to use the information on the Minimatch object determine
|
||
// the findPath. Minimatch breaks the pattern into path segments, and exposes information about which
|
||
// segments are literal vs patterns.
|
||
//
|
||
// note, the technique currently imposes a limitation for drive-relative paths with a glob in the
|
||
// first segment, e.g. C:hello*/world. it's feasible to overcome this limitation, but is left unsolved
|
||
// for now.
|
||
var minimatchObj = new minimatch.Minimatch(pattern, matchOptions);
|
||
// the "set" property is an array of arrays of parsed path segment info. the outer array should only
|
||
// contain one item, otherwise something went wrong. brace expansion can result in multiple arrays,
|
||
// but that should be turned off by the time this function is reached.
|
||
if (minimatchObj.set.length != 1) {
|
||
throw new Error('getFindRootFromPattern() expected Minimatch(...).set.length to be 1. Actual: ' + minimatchObj.set.length);
|
||
}
|
||
var literalSegments = [];
|
||
for (var _i = 0, _a = minimatchObj.set[0]; _i < _a.length; _i++) {
|
||
var parsedSegment = _a[_i];
|
||
if (typeof parsedSegment == 'string') {
|
||
// the item is a string when the original input for the path segment does not contain any
|
||
// unescaped glob characters.
|
||
//
|
||
// note, the string here is already unescaped (i.e. glob escaping removed), so it is ready
|
||
// to pass to find() as-is. for example, an input string 'hello\\*world' => 'hello*world'.
|
||
literalSegments.push(parsedSegment);
|
||
continue;
|
||
}
|
||
break;
|
||
}
|
||
// join the literal segments back together. Minimatch converts '\' to '/' on Windows, then squashes
|
||
// consequetive slashes, and finally splits on slash. this means that UNC format is lost, but can
|
||
// be detected from the original pattern.
|
||
var joinedSegments = literalSegments.join('/');
|
||
if (joinedSegments && process.platform == 'win32' && _startsWith(pattern.replace(/\\/g, '/'), '//')) {
|
||
joinedSegments = '/' + joinedSegments; // restore UNC format
|
||
}
|
||
// determine the find path
|
||
var findPath;
|
||
if (_isRooted(pattern)) { // the pattern was rooted
|
||
findPath = joinedSegments;
|
||
}
|
||
else if (joinedSegments) { // the pattern was not rooted, and literal segments were found
|
||
findPath = _ensureRooted(defaultRoot, joinedSegments);
|
||
}
|
||
else { // the pattern was not rooted, and no literal segments were found
|
||
findPath = defaultRoot;
|
||
}
|
||
// clean up the path
|
||
if (findPath) {
|
||
findPath = _getDirectoryName(_ensureRooted(findPath, '_')); // hack to remove unnecessary trailing slash
|
||
findPath = _normalizeSeparators(findPath); // normalize slashes
|
||
}
|
||
return {
|
||
adjustedPattern: _ensurePatternRooted(defaultRoot, pattern),
|
||
findPath: findPath,
|
||
statOnly: literalSegments.length == minimatchObj.set[0].length,
|
||
};
|
||
}
|
||
exports._getFindInfoFromPattern = _getFindInfoFromPattern;
|
||
function _ensurePatternRooted(root, p) {
|
||
if (!root) {
|
||
throw new Error('ensurePatternRooted() parameter "root" cannot be empty');
|
||
}
|
||
if (!p) {
|
||
throw new Error('ensurePatternRooted() parameter "p" cannot be empty');
|
||
}
|
||
if (_isRooted(p)) {
|
||
return p;
|
||
}
|
||
// normalize root
|
||
root = _normalizeSeparators(root);
|
||
// escape special glob characters
|
||
root = (process.platform == 'win32' ? root : root.replace(/\\/g, '\\\\')) // escape '\' on OSX/Linux
|
||
.replace(/(\[)(?=[^\/]+\])/g, '[[]') // escape '[' when ']' follows within the path segment
|
||
.replace(/\?/g, '[?]') // escape '?'
|
||
.replace(/\*/g, '[*]') // escape '*'
|
||
.replace(/\+\(/g, '[+](') // escape '+('
|
||
.replace(/@\(/g, '[@](') // escape '@('
|
||
.replace(/!\(/g, '[!]('); // escape '!('
|
||
return _ensureRooted(root, p);
|
||
}
|
||
exports._ensurePatternRooted = _ensurePatternRooted;
|
||
//-------------------------------------------------------------------
|
||
// Populate the vault with sensitive data. Inputs and Endpoints
|
||
//-------------------------------------------------------------------
|
||
function _loadData() {
|
||
// in agent, prefer TempDirectory then workFolder.
|
||
// In interactive dev mode, it won't be
|
||
var keyPath = _getVariable("agent.TempDirectory") || _getVariable("agent.workFolder") || process.cwd();
|
||
exports._vault = new vm.Vault(keyPath);
|
||
exports._knownVariableMap = {};
|
||
_debug('loading inputs and endpoints');
|
||
var loaded = 0;
|
||
for (var envvar in process.env) {
|
||
if (_startsWith(envvar, 'INPUT_') ||
|
||
_startsWith(envvar, 'ENDPOINT_AUTH_') ||
|
||
_startsWith(envvar, 'SECUREFILE_TICKET_') ||
|
||
_startsWith(envvar, 'SECRET_') ||
|
||
_startsWith(envvar, 'VSTS_TASKVARIABLE_')) {
|
||
// Record the secret variable metadata. This is required by getVariable to know whether
|
||
// to retrieve the value from the vault. In a 2.104.1 agent or higher, this metadata will
|
||
// be overwritten when the VSTS_SECRET_VARIABLES env var is processed below.
|
||
if (_startsWith(envvar, 'SECRET_')) {
|
||
var variableName = envvar.substring('SECRET_'.length);
|
||
if (variableName) {
|
||
// This is technically not the variable name (has underscores instead of dots),
|
||
// but it's good enough to make getVariable work in a pre-2.104.1 agent where
|
||
// the VSTS_SECRET_VARIABLES env var is not defined.
|
||
exports._knownVariableMap[_getVariableKey(variableName)] = { name: variableName, secret: true };
|
||
}
|
||
}
|
||
// store the secret
|
||
var value = process.env[envvar];
|
||
if (value) {
|
||
++loaded;
|
||
_debug('loading ' + envvar);
|
||
exports._vault.storeSecret(envvar, value);
|
||
delete process.env[envvar];
|
||
}
|
||
}
|
||
}
|
||
_debug('loaded ' + loaded);
|
||
// store public variable metadata
|
||
var names;
|
||
try {
|
||
names = JSON.parse(process.env['VSTS_PUBLIC_VARIABLES'] || '[]');
|
||
}
|
||
catch (err) {
|
||
throw new Error('Failed to parse VSTS_PUBLIC_VARIABLES as JSON. ' + err); // may occur during interactive testing
|
||
}
|
||
names.forEach(function (name) {
|
||
exports._knownVariableMap[_getVariableKey(name)] = { name: name, secret: false };
|
||
});
|
||
delete process.env['VSTS_PUBLIC_VARIABLES'];
|
||
// store secret variable metadata
|
||
try {
|
||
names = JSON.parse(process.env['VSTS_SECRET_VARIABLES'] || '[]');
|
||
}
|
||
catch (err) {
|
||
throw new Error('Failed to parse VSTS_SECRET_VARIABLES as JSON. ' + err); // may occur during interactive testing
|
||
}
|
||
names.forEach(function (name) {
|
||
exports._knownVariableMap[_getVariableKey(name)] = { name: name, secret: true };
|
||
});
|
||
delete process.env['VSTS_SECRET_VARIABLES'];
|
||
// avoid loading twice (overwrites .taskkey)
|
||
global['_vsts_task_lib_loaded'] = true;
|
||
}
|
||
exports._loadData = _loadData;
|
||
//--------------------------------------------------------------------------------
|
||
// Internal path helpers.
|
||
//--------------------------------------------------------------------------------
|
||
function _ensureRooted(root, p) {
|
||
if (!root) {
|
||
throw new Error('ensureRooted() parameter "root" cannot be empty');
|
||
}
|
||
if (!p) {
|
||
throw new Error('ensureRooted() parameter "p" cannot be empty');
|
||
}
|
||
if (_isRooted(p)) {
|
||
return p;
|
||
}
|
||
if (process.platform == 'win32' && root.match(/^[A-Z]:$/i)) { // e.g. C:
|
||
return root + p;
|
||
}
|
||
// ensure root ends with a separator
|
||
if (_endsWith(root, '/') || (process.platform == 'win32' && _endsWith(root, '\\'))) {
|
||
// root already ends with a separator
|
||
}
|
||
else {
|
||
root += path.sep; // append separator
|
||
}
|
||
return root + p;
|
||
}
|
||
exports._ensureRooted = _ensureRooted;
|
||
/**
|
||
* Determines the parent path and trims trailing slashes (when safe). Path separators are normalized
|
||
* in the result. This function works similar to the .NET System.IO.Path.GetDirectoryName() method.
|
||
* For example, C:\hello\world\ returns C:\hello\world (trailing slash removed). Returns empty when
|
||
* no higher directory can be determined.
|
||
*/
|
||
function _getDirectoryName(p) {
|
||
// short-circuit if empty
|
||
if (!p) {
|
||
return '';
|
||
}
|
||
// normalize separators
|
||
p = _normalizeSeparators(p);
|
||
// on Windows, the goal of this function is to match the behavior of
|
||
// [System.IO.Path]::GetDirectoryName(), e.g.
|
||
// C:/ =>
|
||
// C:/hello => C:\
|
||
// C:/hello/ => C:\hello
|
||
// C:/hello/world => C:\hello
|
||
// C:/hello/world/ => C:\hello\world
|
||
// C: =>
|
||
// C:hello => C:
|
||
// C:hello/ => C:hello
|
||
// / =>
|
||
// /hello => \
|
||
// /hello/ => \hello
|
||
// //hello =>
|
||
// //hello/ =>
|
||
// //hello/world =>
|
||
// //hello/world/ => \\hello\world
|
||
//
|
||
// unfortunately, path.dirname() can't simply be used. for example, on Windows
|
||
// it yields different results from Path.GetDirectoryName:
|
||
// C:/ => C:/
|
||
// C:/hello => C:/
|
||
// C:/hello/ => C:/
|
||
// C:/hello/world => C:/hello
|
||
// C:/hello/world/ => C:/hello
|
||
// C: => C:
|
||
// C:hello => C:
|
||
// C:hello/ => C:
|
||
// / => /
|
||
// /hello => /
|
||
// /hello/ => /
|
||
// //hello => /
|
||
// //hello/ => /
|
||
// //hello/world => //hello/world
|
||
// //hello/world/ => //hello/world/
|
||
// //hello/world/again => //hello/world/
|
||
// //hello/world/again/ => //hello/world/
|
||
// //hello/world/again/again => //hello/world/again
|
||
// //hello/world/again/again/ => //hello/world/again
|
||
if (process.platform == 'win32') {
|
||
if (/^[A-Z]:\\?[^\\]+$/i.test(p)) { // e.g. C:\hello or C:hello
|
||
return p.charAt(2) == '\\' ? p.substring(0, 3) : p.substring(0, 2);
|
||
}
|
||
else if (/^[A-Z]:\\?$/i.test(p)) { // e.g. C:\ or C:
|
||
return '';
|
||
}
|
||
var lastSlashIndex = p.lastIndexOf('\\');
|
||
if (lastSlashIndex < 0) { // file name only
|
||
return '';
|
||
}
|
||
else if (p == '\\') { // relative root
|
||
return '';
|
||
}
|
||
else if (lastSlashIndex == 0) { // e.g. \\hello
|
||
return '\\';
|
||
}
|
||
else if (/^\\\\[^\\]+(\\[^\\]*)?$/.test(p)) { // UNC root, e.g. \\hello or \\hello\ or \\hello\world
|
||
return '';
|
||
}
|
||
return p.substring(0, lastSlashIndex); // e.g. hello\world => hello or hello\world\ => hello\world
|
||
// note, this means trailing slashes for non-root directories
|
||
// (i.e. not C:\, \, or \\unc\) will simply be removed.
|
||
}
|
||
// OSX/Linux
|
||
if (p.indexOf('/') < 0) { // file name only
|
||
return '';
|
||
}
|
||
else if (p == '/') {
|
||
return '';
|
||
}
|
||
else if (_endsWith(p, '/')) {
|
||
return p.substring(0, p.length - 1);
|
||
}
|
||
return path.dirname(p);
|
||
}
|
||
exports._getDirectoryName = _getDirectoryName;
|
||
/**
|
||
* 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 (process.platform == 'win32') {
|
||
return _startsWith(p, '\\') || // e.g. \ or \hello or \\hello
|
||
/^[A-Z]:/i.test(p); // e.g. C: or C:\hello
|
||
}
|
||
return _startsWith(p, '/'); // e.g. /hello
|
||
}
|
||
exports._isRooted = _isRooted;
|
||
function _normalizeSeparators(p) {
|
||
p = p || '';
|
||
if (process.platform == 'win32') {
|
||
// convert slashes on Windows
|
||
p = p.replace(/\//g, '\\');
|
||
// remove redundant slashes
|
||
var isUnc = /^\\\\+[^\\]/.test(p); // e.g. \\hello
|
||
return (isUnc ? '\\' : '') + p.replace(/\\\\+/g, '\\'); // preserve leading // for UNC
|
||
}
|
||
// remove redundant slashes
|
||
return p.replace(/\/\/+/g, '/');
|
||
}
|
||
exports._normalizeSeparators = _normalizeSeparators;
|
||
//-----------------------------------------------------
|
||
// Expose proxy information to vsts-node-api
|
||
//-----------------------------------------------------
|
||
function _exposeProxySettings() {
|
||
var proxyUrl = _getVariable('Agent.ProxyUrl');
|
||
if (proxyUrl && proxyUrl.length > 0) {
|
||
var proxyUsername = _getVariable('Agent.ProxyUsername');
|
||
var proxyPassword = _getVariable('Agent.ProxyPassword');
|
||
var proxyBypassHostsJson = _getVariable('Agent.ProxyBypassList');
|
||
global['_vsts_task_lib_proxy_url'] = proxyUrl;
|
||
global['_vsts_task_lib_proxy_username'] = proxyUsername;
|
||
global['_vsts_task_lib_proxy_bypass'] = proxyBypassHostsJson;
|
||
global['_vsts_task_lib_proxy_password'] = _exposeTaskLibSecret('proxy', proxyPassword || '');
|
||
_debug('expose agent proxy configuration.');
|
||
global['_vsts_task_lib_proxy'] = true;
|
||
}
|
||
}
|
||
exports._exposeProxySettings = _exposeProxySettings;
|
||
//-----------------------------------------------------
|
||
// Expose certificate information to vsts-node-api
|
||
//-----------------------------------------------------
|
||
function _exposeCertSettings() {
|
||
var ca = _getVariable('Agent.CAInfo');
|
||
if (ca) {
|
||
global['_vsts_task_lib_cert_ca'] = ca;
|
||
}
|
||
var clientCert = _getVariable('Agent.ClientCert');
|
||
if (clientCert) {
|
||
var clientCertKey = _getVariable('Agent.ClientCertKey');
|
||
var clientCertArchive = _getVariable('Agent.ClientCertArchive');
|
||
var clientCertPassword = _getVariable('Agent.ClientCertPassword');
|
||
global['_vsts_task_lib_cert_clientcert'] = clientCert;
|
||
global['_vsts_task_lib_cert_key'] = clientCertKey;
|
||
global['_vsts_task_lib_cert_archive'] = clientCertArchive;
|
||
global['_vsts_task_lib_cert_passphrase'] = _exposeTaskLibSecret('cert', clientCertPassword || '');
|
||
}
|
||
if (ca || clientCert) {
|
||
_debug('expose agent certificate configuration.');
|
||
global['_vsts_task_lib_cert'] = true;
|
||
}
|
||
var skipCertValidation = _getVariable('Agent.SkipCertValidation') || 'false';
|
||
if (skipCertValidation) {
|
||
global['_vsts_task_lib_skip_cert_validation'] = skipCertValidation.toUpperCase() === 'TRUE';
|
||
}
|
||
}
|
||
exports._exposeCertSettings = _exposeCertSettings;
|
||
// We store the encryption key on disk and hold the encrypted content and key file in memory
|
||
// return base64encoded<keyFilePath>:base64encoded<encryptedContent>
|
||
// downstream vsts-node-api will retrieve the secret later
|
||
function _exposeTaskLibSecret(keyFile, secret) {
|
||
if (secret) {
|
||
var encryptKey = crypto.randomBytes(256);
|
||
var cipher = crypto.createCipher("aes-256-ctr", encryptKey);
|
||
var encryptedContent = cipher.update(secret, "utf8", "hex");
|
||
encryptedContent += cipher.final("hex");
|
||
var storageFile = path.join(_getVariable('Agent.TempDirectory') || _getVariable("agent.workFolder") || process.cwd(), keyFile);
|
||
fs.writeFileSync(storageFile, encryptKey.toString('base64'), { encoding: 'utf8' });
|
||
return new Buffer(storageFile).toString('base64') + ':' + new Buffer(encryptedContent).toString('base64');
|
||
}
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-task-lib/node_modules/uuid/lib/bytesToUuid.js":
|
||
/*!************************************************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-task-lib/node_modules/uuid/lib/bytesToUuid.js ***!
|
||
\************************************************************************************/
|
||
/***/ ((module) => {
|
||
|
||
/**
|
||
* 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/azure-pipelines-task-lib/node_modules/uuid/lib/rng.js":
|
||
/*!****************************************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-task-lib/node_modules/uuid/lib/rng.js ***!
|
||
\****************************************************************************/
|
||
/***/ ((module, __unused_webpack_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/azure-pipelines-task-lib/node_modules/uuid/v4.js":
|
||
/*!***********************************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-task-lib/node_modules/uuid/v4.js ***!
|
||
\***********************************************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var rng = __webpack_require__(/*! ./lib/rng */ "./node_modules/azure-pipelines-task-lib/node_modules/uuid/lib/rng.js");
|
||
var bytesToUuid = __webpack_require__(/*! ./lib/bytesToUuid */ "./node_modules/azure-pipelines-task-lib/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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-task-lib/task.js":
|
||
/*!*******************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-task-lib/task.js ***!
|
||
\*******************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.updateReleaseName = exports.addBuildTag = exports.updateBuildNumber = exports.uploadBuildLog = exports.associateArtifact = exports.uploadArtifact = exports.logIssue = exports.logDetail = exports.setProgress = exports.setEndpoint = exports.addAttachment = exports.uploadSummary = exports.prependPath = exports.uploadFile = exports.CodeCoverageEnabler = exports.CodeCoveragePublisher = exports.TestPublisher = exports.getHttpCertConfiguration = exports.getHttpProxyConfiguration = exports.findMatch = exports.filter = exports.match = exports.tool = exports.execSync = exports.exec = exports.rmRF = exports.legacyFindFiles = exports.find = exports.mv = exports.cp = exports.ls = exports.which = exports.resolve = exports.mkdirP = exports.popd = exports.pushd = exports.cd = exports.checkPath = exports.cwd = exports.getPlatform = exports.osType = exports.writeFile = exports.exist = exports.stats = exports.debug = exports.error = exports.warning = exports.command = exports.setTaskVariable = exports.getTaskVariable = exports.getSecureFileTicket = exports.getSecureFileName = exports.getEndpointAuthorization = exports.getEndpointAuthorizationParameter = exports.getEndpointAuthorizationScheme = exports.getEndpointDataParameter = exports.getEndpointUrl = exports.getPathInput = exports.filePathSupplied = exports.getDelimitedInput = exports.getBoolInput = exports.getInput = exports.setSecret = exports.setVariable = exports.getVariables = exports.assertAgent = exports.getVariable = exports.loc = exports.setResourcePath = exports.setResult = exports.setErrStream = exports.setStdStream = exports.Platform = exports.FieldType = exports.ArtifactType = exports.IssueType = exports.TaskState = exports.TaskResult = void 0;
|
||
var shell = __webpack_require__(/*! shelljs */ "./node_modules/shelljs/shell.js");
|
||
var childProcess = __webpack_require__(/*! child_process */ "child_process");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var os = __webpack_require__(/*! os */ "os");
|
||
var minimatch = __webpack_require__(/*! minimatch */ "./node_modules/minimatch/minimatch.js");
|
||
var im = __webpack_require__(/*! ./internal */ "./node_modules/azure-pipelines-task-lib/internal.js");
|
||
var tcm = __webpack_require__(/*! ./taskcommand */ "./node_modules/azure-pipelines-task-lib/taskcommand.js");
|
||
var trm = __webpack_require__(/*! ./toolrunner */ "./node_modules/azure-pipelines-task-lib/toolrunner.js");
|
||
var semver = __webpack_require__(/*! semver */ "./node_modules/semver/semver.js");
|
||
var TaskResult;
|
||
(function (TaskResult) {
|
||
TaskResult[TaskResult["Succeeded"] = 0] = "Succeeded";
|
||
TaskResult[TaskResult["SucceededWithIssues"] = 1] = "SucceededWithIssues";
|
||
TaskResult[TaskResult["Failed"] = 2] = "Failed";
|
||
TaskResult[TaskResult["Cancelled"] = 3] = "Cancelled";
|
||
TaskResult[TaskResult["Skipped"] = 4] = "Skipped";
|
||
})(TaskResult = exports.TaskResult || (exports.TaskResult = {}));
|
||
var TaskState;
|
||
(function (TaskState) {
|
||
TaskState[TaskState["Unknown"] = 0] = "Unknown";
|
||
TaskState[TaskState["Initialized"] = 1] = "Initialized";
|
||
TaskState[TaskState["InProgress"] = 2] = "InProgress";
|
||
TaskState[TaskState["Completed"] = 3] = "Completed";
|
||
})(TaskState = exports.TaskState || (exports.TaskState = {}));
|
||
var IssueType;
|
||
(function (IssueType) {
|
||
IssueType[IssueType["Error"] = 0] = "Error";
|
||
IssueType[IssueType["Warning"] = 1] = "Warning";
|
||
})(IssueType = exports.IssueType || (exports.IssueType = {}));
|
||
var ArtifactType;
|
||
(function (ArtifactType) {
|
||
ArtifactType[ArtifactType["Container"] = 0] = "Container";
|
||
ArtifactType[ArtifactType["FilePath"] = 1] = "FilePath";
|
||
ArtifactType[ArtifactType["VersionControl"] = 2] = "VersionControl";
|
||
ArtifactType[ArtifactType["GitRef"] = 3] = "GitRef";
|
||
ArtifactType[ArtifactType["TfvcLabel"] = 4] = "TfvcLabel";
|
||
})(ArtifactType = exports.ArtifactType || (exports.ArtifactType = {}));
|
||
var FieldType;
|
||
(function (FieldType) {
|
||
FieldType[FieldType["AuthParameter"] = 0] = "AuthParameter";
|
||
FieldType[FieldType["DataParameter"] = 1] = "DataParameter";
|
||
FieldType[FieldType["Url"] = 2] = "Url";
|
||
})(FieldType = exports.FieldType || (exports.FieldType = {}));
|
||
/** Platforms supported by our build agent */
|
||
var Platform;
|
||
(function (Platform) {
|
||
Platform[Platform["Windows"] = 0] = "Windows";
|
||
Platform[Platform["MacOS"] = 1] = "MacOS";
|
||
Platform[Platform["Linux"] = 2] = "Linux";
|
||
})(Platform = exports.Platform || (exports.Platform = {}));
|
||
//-----------------------------------------------------
|
||
// General Helpers
|
||
//-----------------------------------------------------
|
||
exports.setStdStream = im._setStdStream;
|
||
exports.setErrStream = im._setErrStream;
|
||
//-----------------------------------------------------
|
||
// Results
|
||
//-----------------------------------------------------
|
||
/**
|
||
* Sets the result of the task.
|
||
* Execution will continue.
|
||
* If not set, task will be Succeeded.
|
||
* If multiple calls are made to setResult the most pessimistic call wins (Failed) regardless of the order of calls.
|
||
*
|
||
* @param result TaskResult enum of Succeeded, SucceededWithIssues, Failed, Cancelled or Skipped.
|
||
* @param message A message which will be logged as an error issue if the result is Failed.
|
||
* @param done Optional. Instructs the agent the task is done. This is helpful when child processes
|
||
* may still be running and prevent node from fully exiting. This argument is supported
|
||
* from agent version 2.142.0 or higher (otherwise will no-op).
|
||
* @returns void
|
||
*/
|
||
function setResult(result, message, done) {
|
||
exports.debug('task result: ' + TaskResult[result]);
|
||
// add an error issue
|
||
if (result == TaskResult.Failed && message) {
|
||
exports.error(message);
|
||
}
|
||
else if (result == TaskResult.SucceededWithIssues && message) {
|
||
exports.warning(message);
|
||
}
|
||
// task.complete
|
||
var properties = { 'result': TaskResult[result] };
|
||
if (done) {
|
||
properties['done'] = 'true';
|
||
}
|
||
exports.command('task.complete', properties, message);
|
||
}
|
||
exports.setResult = setResult;
|
||
//
|
||
// Catching all exceptions
|
||
//
|
||
process.on('uncaughtException', function (err) {
|
||
setResult(TaskResult.Failed, exports.loc('LIB_UnhandledEx', err.message));
|
||
});
|
||
//-----------------------------------------------------
|
||
// Loc Helpers
|
||
//-----------------------------------------------------
|
||
exports.setResourcePath = im._setResourcePath;
|
||
exports.loc = im._loc;
|
||
//-----------------------------------------------------
|
||
// Input Helpers
|
||
//-----------------------------------------------------
|
||
exports.getVariable = im._getVariable;
|
||
/**
|
||
* Asserts the agent version is at least the specified minimum.
|
||
*
|
||
* @param minimum minimum version version - must be 2.104.1 or higher
|
||
*/
|
||
function assertAgent(minimum) {
|
||
if (semver.lt(minimum, '2.104.1')) {
|
||
throw new Error('assertAgent() requires the parameter to be 2.104.1 or higher');
|
||
}
|
||
var agent = exports.getVariable('Agent.Version');
|
||
if (agent && semver.lt(agent, minimum)) {
|
||
throw new Error("Agent version " + minimum + " or higher is required");
|
||
}
|
||
}
|
||
exports.assertAgent = assertAgent;
|
||
/**
|
||
* Gets a snapshot of the current state of all job variables available to the task.
|
||
* Requires a 2.104.1 agent or higher for full functionality.
|
||
*
|
||
* Limitations on an agent prior to 2.104.1:
|
||
* 1) The return value does not include all public variables. Only public variables
|
||
* that have been added using setVariable are returned.
|
||
* 2) The name returned for each secret variable is the formatted environment variable
|
||
* name, not the actual variable name (unless it was set explicitly at runtime using
|
||
* setVariable).
|
||
*
|
||
* @returns VariableInfo[]
|
||
*/
|
||
function getVariables() {
|
||
return Object.keys(im._knownVariableMap)
|
||
.map(function (key) {
|
||
var info = im._knownVariableMap[key];
|
||
return { name: info.name, value: exports.getVariable(info.name), secret: info.secret };
|
||
});
|
||
}
|
||
exports.getVariables = getVariables;
|
||
/**
|
||
* Sets a variable which will be available to subsequent tasks as well.
|
||
*
|
||
* @param name name of the variable to set
|
||
* @param val value to set
|
||
* @param secret whether variable is secret. Multi-line secrets are not allowed. Optional, defaults to false
|
||
* @param isOutput whether variable is an output variable. Optional, defaults to false
|
||
* @returns void
|
||
*/
|
||
function setVariable(name, val, secret, isOutput) {
|
||
if (secret === void 0) { secret = false; }
|
||
if (isOutput === void 0) { isOutput = false; }
|
||
// once a secret always a secret
|
||
var key = im._getVariableKey(name);
|
||
if (im._knownVariableMap.hasOwnProperty(key)) {
|
||
secret = secret || im._knownVariableMap[key].secret;
|
||
}
|
||
// store the value
|
||
var varValue = val || '';
|
||
exports.debug('set ' + name + '=' + (secret && varValue ? '********' : varValue));
|
||
if (secret) {
|
||
if (varValue && varValue.match(/\r|\n/) && ("" + process.env['SYSTEM_UNSAFEALLOWMULTILINESECRET']).toUpperCase() != 'TRUE') {
|
||
throw new Error(exports.loc('LIB_MultilineSecret'));
|
||
}
|
||
im._vault.storeSecret('SECRET_' + key, varValue);
|
||
delete process.env[key];
|
||
}
|
||
else {
|
||
process.env[key] = varValue;
|
||
}
|
||
// store the metadata
|
||
im._knownVariableMap[key] = { name: name, secret: secret };
|
||
// write the setvariable command
|
||
exports.command('task.setvariable', { 'variable': name || '', isOutput: (isOutput || false).toString(), 'issecret': (secret || false).toString() }, varValue);
|
||
}
|
||
exports.setVariable = setVariable;
|
||
/**
|
||
* Registers a value with the logger, so the value will be masked from the logs. Multi-line secrets are not allowed.
|
||
*
|
||
* @param val value to register
|
||
*/
|
||
function setSecret(val) {
|
||
if (val) {
|
||
if (val.match(/\r|\n/) && ("" + process.env['SYSTEM_UNSAFEALLOWMULTILINESECRET']).toUpperCase() !== 'TRUE') {
|
||
throw new Error(exports.loc('LIB_MultilineSecret'));
|
||
}
|
||
exports.command('task.setsecret', {}, val);
|
||
}
|
||
}
|
||
exports.setSecret = setSecret;
|
||
/**
|
||
* Gets the value of an input.
|
||
* If required is true and the value is not set, it will throw.
|
||
*
|
||
* @param name name of the input to get
|
||
* @param required whether input is required. optional, defaults to false
|
||
* @returns string
|
||
*/
|
||
function getInput(name, required) {
|
||
var inval = im._vault.retrieveSecret('INPUT_' + im._getVariableKey(name));
|
||
if (required && !inval) {
|
||
throw new Error(exports.loc('LIB_InputRequired', name));
|
||
}
|
||
exports.debug(name + '=' + inval);
|
||
return inval;
|
||
}
|
||
exports.getInput = getInput;
|
||
/**
|
||
* Gets the value of an input and converts to a bool. Convenience.
|
||
* If required is true and the value is not set, it will throw.
|
||
* If required is false and the value is not set, returns false.
|
||
*
|
||
* @param name name of the bool input to get
|
||
* @param required whether input is required. optional, defaults to false
|
||
* @returns boolean
|
||
*/
|
||
function getBoolInput(name, required) {
|
||
return (getInput(name, required) || '').toUpperCase() == "TRUE";
|
||
}
|
||
exports.getBoolInput = getBoolInput;
|
||
/**
|
||
* Gets the value of an input and splits the value using a delimiter (space, comma, etc).
|
||
* Empty values are removed. This function is useful for splitting an input containing a simple
|
||
* list of items - such as build targets.
|
||
* IMPORTANT: Do not use this function for splitting additional args! Instead use argString(), which
|
||
* follows normal argument splitting rules and handles values encapsulated by quotes.
|
||
* If required is true and the value is not set, it will throw.
|
||
*
|
||
* @param name name of the input to get
|
||
* @param delim delimiter to split on
|
||
* @param required whether input is required. optional, defaults to false
|
||
* @returns string[]
|
||
*/
|
||
function getDelimitedInput(name, delim, required) {
|
||
var inputVal = getInput(name, required);
|
||
if (!inputVal) {
|
||
return [];
|
||
}
|
||
var result = [];
|
||
inputVal.split(delim).forEach(function (x) {
|
||
if (x) {
|
||
result.push(x);
|
||
}
|
||
});
|
||
return result;
|
||
}
|
||
exports.getDelimitedInput = getDelimitedInput;
|
||
/**
|
||
* Checks whether a path inputs value was supplied by the user
|
||
* File paths are relative with a picker, so an empty path is the root of the repo.
|
||
* Useful if you need to condition work (like append an arg) if a value was supplied
|
||
*
|
||
* @param name name of the path input to check
|
||
* @returns boolean
|
||
*/
|
||
function filePathSupplied(name) {
|
||
// normalize paths
|
||
var pathValue = this.resolve(this.getPathInput(name) || '');
|
||
var repoRoot = this.resolve(exports.getVariable('build.sourcesDirectory') || exports.getVariable('system.defaultWorkingDirectory') || '');
|
||
var supplied = pathValue !== repoRoot;
|
||
exports.debug(name + 'path supplied :' + supplied);
|
||
return supplied;
|
||
}
|
||
exports.filePathSupplied = filePathSupplied;
|
||
/**
|
||
* Gets the value of a path input
|
||
* It will be quoted for you if it isn't already and contains spaces
|
||
* If required is true and the value is not set, it will throw.
|
||
* If check is true and the path does not exist, it will throw.
|
||
*
|
||
* @param name name of the input to get
|
||
* @param required whether input is required. optional, defaults to false
|
||
* @param check whether path is checked. optional, defaults to false
|
||
* @returns string
|
||
*/
|
||
function getPathInput(name, required, check) {
|
||
var inval = getInput(name, required);
|
||
if (inval) {
|
||
if (check) {
|
||
exports.checkPath(inval, name);
|
||
}
|
||
}
|
||
return inval;
|
||
}
|
||
exports.getPathInput = getPathInput;
|
||
//-----------------------------------------------------
|
||
// Endpoint Helpers
|
||
//-----------------------------------------------------
|
||
/**
|
||
* Gets the url for a service endpoint
|
||
* If the url was not set and is not optional, it will throw.
|
||
*
|
||
* @param id name of the service endpoint
|
||
* @param optional whether the url is optional
|
||
* @returns string
|
||
*/
|
||
function getEndpointUrl(id, optional) {
|
||
var urlval = process.env['ENDPOINT_URL_' + id];
|
||
if (!optional && !urlval) {
|
||
throw new Error(exports.loc('LIB_EndpointNotExist', id));
|
||
}
|
||
exports.debug(id + '=' + urlval);
|
||
return urlval;
|
||
}
|
||
exports.getEndpointUrl = getEndpointUrl;
|
||
/*
|
||
* Gets the endpoint data parameter value with specified key for a service endpoint
|
||
* If the endpoint data parameter was not set and is not optional, it will throw.
|
||
*
|
||
* @param id name of the service endpoint
|
||
* @param key of the parameter
|
||
* @param optional whether the endpoint data is optional
|
||
* @returns {string} value of the endpoint data parameter
|
||
*/
|
||
function getEndpointDataParameter(id, key, optional) {
|
||
var dataParamVal = process.env['ENDPOINT_DATA_' + id + '_' + key.toUpperCase()];
|
||
if (!optional && !dataParamVal) {
|
||
throw new Error(exports.loc('LIB_EndpointDataNotExist', id, key));
|
||
}
|
||
exports.debug(id + ' data ' + key + ' = ' + dataParamVal);
|
||
return dataParamVal;
|
||
}
|
||
exports.getEndpointDataParameter = getEndpointDataParameter;
|
||
/**
|
||
* Gets the endpoint authorization scheme for a service endpoint
|
||
* If the endpoint authorization scheme is not set and is not optional, it will throw.
|
||
*
|
||
* @param id name of the service endpoint
|
||
* @param optional whether the endpoint authorization scheme is optional
|
||
* @returns {string} value of the endpoint authorization scheme
|
||
*/
|
||
function getEndpointAuthorizationScheme(id, optional) {
|
||
var authScheme = im._vault.retrieveSecret('ENDPOINT_AUTH_SCHEME_' + id);
|
||
if (!optional && !authScheme) {
|
||
throw new Error(exports.loc('LIB_EndpointAuthNotExist', id));
|
||
}
|
||
exports.debug(id + ' auth scheme = ' + authScheme);
|
||
return authScheme;
|
||
}
|
||
exports.getEndpointAuthorizationScheme = getEndpointAuthorizationScheme;
|
||
/**
|
||
* Gets the endpoint authorization parameter value for a service endpoint with specified key
|
||
* If the endpoint authorization parameter is not set and is not optional, it will throw.
|
||
*
|
||
* @param id name of the service endpoint
|
||
* @param key key to find the endpoint authorization parameter
|
||
* @param optional optional whether the endpoint authorization scheme is optional
|
||
* @returns {string} value of the endpoint authorization parameter value
|
||
*/
|
||
function getEndpointAuthorizationParameter(id, key, optional) {
|
||
var authParam = im._vault.retrieveSecret('ENDPOINT_AUTH_PARAMETER_' + id + '_' + key.toUpperCase());
|
||
if (!optional && !authParam) {
|
||
throw new Error(exports.loc('LIB_EndpointAuthNotExist', id));
|
||
}
|
||
exports.debug(id + ' auth param ' + key + ' = ' + authParam);
|
||
return authParam;
|
||
}
|
||
exports.getEndpointAuthorizationParameter = getEndpointAuthorizationParameter;
|
||
/**
|
||
* Gets the authorization details for a service endpoint
|
||
* If the authorization was not set and is not optional, it will throw.
|
||
*
|
||
* @param id name of the service endpoint
|
||
* @param optional whether the url is optional
|
||
* @returns string
|
||
*/
|
||
function getEndpointAuthorization(id, optional) {
|
||
var aval = im._vault.retrieveSecret('ENDPOINT_AUTH_' + id);
|
||
if (!optional && !aval) {
|
||
setResult(TaskResult.Failed, exports.loc('LIB_EndpointAuthNotExist', id));
|
||
}
|
||
exports.debug(id + ' exists ' + (aval !== null));
|
||
var auth;
|
||
try {
|
||
if (aval) {
|
||
auth = JSON.parse(aval);
|
||
}
|
||
}
|
||
catch (err) {
|
||
throw new Error(exports.loc('LIB_InvalidEndpointAuth', aval));
|
||
}
|
||
return auth;
|
||
}
|
||
exports.getEndpointAuthorization = getEndpointAuthorization;
|
||
//-----------------------------------------------------
|
||
// SecureFile Helpers
|
||
//-----------------------------------------------------
|
||
/**
|
||
* Gets the name for a secure file
|
||
*
|
||
* @param id secure file id
|
||
* @returns string
|
||
*/
|
||
function getSecureFileName(id) {
|
||
var name = process.env['SECUREFILE_NAME_' + id];
|
||
exports.debug('secure file name for id ' + id + ' = ' + name);
|
||
return name;
|
||
}
|
||
exports.getSecureFileName = getSecureFileName;
|
||
/**
|
||
* Gets the secure file ticket that can be used to download the secure file contents
|
||
*
|
||
* @param id name of the secure file
|
||
* @returns {string} secure file ticket
|
||
*/
|
||
function getSecureFileTicket(id) {
|
||
var ticket = im._vault.retrieveSecret('SECUREFILE_TICKET_' + id);
|
||
exports.debug('secure file ticket for id ' + id + ' = ' + ticket);
|
||
return ticket;
|
||
}
|
||
exports.getSecureFileTicket = getSecureFileTicket;
|
||
//-----------------------------------------------------
|
||
// Task Variable Helpers
|
||
//-----------------------------------------------------
|
||
/**
|
||
* Gets a variable value that is set by previous step from the same wrapper task.
|
||
* Requires a 2.115.0 agent or higher.
|
||
*
|
||
* @param name name of the variable to get
|
||
* @returns string
|
||
*/
|
||
function getTaskVariable(name) {
|
||
assertAgent('2.115.0');
|
||
var inval = im._vault.retrieveSecret('VSTS_TASKVARIABLE_' + im._getVariableKey(name));
|
||
if (inval) {
|
||
inval = inval.trim();
|
||
}
|
||
exports.debug('task variable: ' + name + '=' + inval);
|
||
return inval;
|
||
}
|
||
exports.getTaskVariable = getTaskVariable;
|
||
/**
|
||
* Sets a task variable which will only be available to subsequent steps belong to the same wrapper task.
|
||
* Requires a 2.115.0 agent or higher.
|
||
*
|
||
* @param name name of the variable to set
|
||
* @param val value to set
|
||
* @param secret whether variable is secret. optional, defaults to false
|
||
* @returns void
|
||
*/
|
||
function setTaskVariable(name, val, secret) {
|
||
if (secret === void 0) { secret = false; }
|
||
assertAgent('2.115.0');
|
||
var key = im._getVariableKey(name);
|
||
// store the value
|
||
var varValue = val || '';
|
||
exports.debug('set task variable: ' + name + '=' + (secret && varValue ? '********' : varValue));
|
||
im._vault.storeSecret('VSTS_TASKVARIABLE_' + key, varValue);
|
||
delete process.env[key];
|
||
// write the command
|
||
exports.command('task.settaskvariable', { 'variable': name || '', 'issecret': (secret || false).toString() }, varValue);
|
||
}
|
||
exports.setTaskVariable = setTaskVariable;
|
||
//-----------------------------------------------------
|
||
// Cmd Helpers
|
||
//-----------------------------------------------------
|
||
exports.command = im._command;
|
||
exports.warning = im._warning;
|
||
exports.error = im._error;
|
||
exports.debug = im._debug;
|
||
//-----------------------------------------------------
|
||
// Disk Functions
|
||
//-----------------------------------------------------
|
||
function _checkShell(cmd, continueOnError) {
|
||
var se = shell.error();
|
||
if (se) {
|
||
exports.debug(cmd + ' failed');
|
||
var errMsg = exports.loc('LIB_OperationFailed', cmd, se);
|
||
exports.debug(errMsg);
|
||
if (!continueOnError) {
|
||
throw new Error(errMsg);
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* Get's stat on a path.
|
||
* Useful for checking whether a file or directory. Also getting created, modified and accessed time.
|
||
* see [fs.stat](https://nodejs.org/api/fs.html#fs_class_fs_stats)
|
||
*
|
||
* @param path path to check
|
||
* @returns fsStat
|
||
*/
|
||
function stats(path) {
|
||
return fs.statSync(path);
|
||
}
|
||
exports.stats = stats;
|
||
exports.exist = im._exist;
|
||
function writeFile(file, data, options) {
|
||
if (typeof (options) === 'string') {
|
||
fs.writeFileSync(file, data, { encoding: options });
|
||
}
|
||
else {
|
||
fs.writeFileSync(file, data, options);
|
||
}
|
||
}
|
||
exports.writeFile = writeFile;
|
||
/**
|
||
* @deprecated Use `getPlatform`
|
||
* Useful for determining the host operating system.
|
||
* see [os.type](https://nodejs.org/api/os.html#os_os_type)
|
||
*
|
||
* @return the name of the operating system
|
||
*/
|
||
function osType() {
|
||
return os.type();
|
||
}
|
||
exports.osType = osType;
|
||
/**
|
||
* Determine the operating system the build agent is running on.
|
||
* @returns {Platform}
|
||
* @throws {Error} Platform is not supported by our agent
|
||
*/
|
||
function getPlatform() {
|
||
switch (process.platform) {
|
||
case 'win32': return Platform.Windows;
|
||
case 'darwin': return Platform.MacOS;
|
||
case 'linux': return Platform.Linux;
|
||
default: throw Error(exports.loc('LIB_PlatformNotSupported', process.platform));
|
||
}
|
||
}
|
||
exports.getPlatform = getPlatform;
|
||
/**
|
||
* Returns the process's current working directory.
|
||
* see [process.cwd](https://nodejs.org/api/process.html#process_process_cwd)
|
||
*
|
||
* @return the path to the current working directory of the process
|
||
*/
|
||
function cwd() {
|
||
return process.cwd();
|
||
}
|
||
exports.cwd = cwd;
|
||
exports.checkPath = im._checkPath;
|
||
/**
|
||
* Change working directory.
|
||
*
|
||
* @param path new working directory path
|
||
* @returns void
|
||
*/
|
||
function cd(path) {
|
||
if (path) {
|
||
shell.cd(path);
|
||
_checkShell('cd');
|
||
}
|
||
}
|
||
exports.cd = cd;
|
||
/**
|
||
* Change working directory and push it on the stack
|
||
*
|
||
* @param path new working directory path
|
||
* @returns void
|
||
*/
|
||
function pushd(path) {
|
||
shell.pushd(path);
|
||
_checkShell('pushd');
|
||
}
|
||
exports.pushd = pushd;
|
||
/**
|
||
* Change working directory back to previously pushed directory
|
||
*
|
||
* @returns void
|
||
*/
|
||
function popd() {
|
||
shell.popd();
|
||
_checkShell('popd');
|
||
}
|
||
exports.popd = popd;
|
||
/**
|
||
* Make a directory. Creates the full path with folders in between
|
||
* Will throw if it fails
|
||
*
|
||
* @param p path to create
|
||
* @returns void
|
||
*/
|
||
function mkdirP(p) {
|
||
if (!p) {
|
||
throw new Error(exports.loc('LIB_ParameterIsRequired', 'p'));
|
||
}
|
||
// build a stack of directories to create
|
||
var stack = [];
|
||
var testDir = p;
|
||
while (true) {
|
||
// validate the loop is not out of control
|
||
if (stack.length >= (process.env['TASKLIB_TEST_MKDIRP_FAILSAFE'] || 1000)) {
|
||
// let the framework throw
|
||
exports.debug('loop is out of control');
|
||
fs.mkdirSync(p);
|
||
return;
|
||
}
|
||
exports.debug("testing directory '" + testDir + "'");
|
||
var stats_1 = void 0;
|
||
try {
|
||
stats_1 = fs.statSync(testDir);
|
||
}
|
||
catch (err) {
|
||
if (err.code == 'ENOENT') {
|
||
// validate the directory is not the drive root
|
||
var parentDir = path.dirname(testDir);
|
||
if (testDir == parentDir) {
|
||
throw new Error(exports.loc('LIB_MkdirFailedInvalidDriveRoot', p, testDir)); // Unable to create directory '{p}'. Root directory does not exist: '{testDir}'
|
||
}
|
||
// push the dir and test the parent
|
||
stack.push(testDir);
|
||
testDir = parentDir;
|
||
continue;
|
||
}
|
||
else if (err.code == 'UNKNOWN') {
|
||
throw new Error(exports.loc('LIB_MkdirFailedInvalidShare', p, testDir)); // Unable to create directory '{p}'. Unable to verify the directory exists: '{testDir}'. If directory is a file share, please verify the share name is correct, the share is online, and the current process has permission to access the share.
|
||
}
|
||
else {
|
||
throw err;
|
||
}
|
||
}
|
||
if (!stats_1.isDirectory()) {
|
||
throw new Error(exports.loc('LIB_MkdirFailedFileExists', p, testDir)); // Unable to create directory '{p}'. Conflicting file exists: '{testDir}'
|
||
}
|
||
// testDir exists
|
||
break;
|
||
}
|
||
// create each directory
|
||
while (stack.length) {
|
||
var dir = stack.pop(); // non-null because `stack.length` was truthy
|
||
exports.debug("mkdir '" + dir + "'");
|
||
try {
|
||
fs.mkdirSync(dir);
|
||
}
|
||
catch (err) {
|
||
throw new Error(exports.loc('LIB_MkdirFailed', p, err.message)); // Unable to create directory '{p}'. {err.message}
|
||
}
|
||
}
|
||
}
|
||
exports.mkdirP = mkdirP;
|
||
/**
|
||
* Resolves a sequence of paths or path segments into an absolute path.
|
||
* Calls node.js path.resolve()
|
||
* Allows L0 testing with consistent path formats on Mac/Linux and Windows in the mock implementation
|
||
* @param pathSegments
|
||
* @returns {string}
|
||
*/
|
||
function resolve() {
|
||
var pathSegments = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
pathSegments[_i] = arguments[_i];
|
||
}
|
||
var absolutePath = path.resolve.apply(this, pathSegments);
|
||
exports.debug('Absolute path for pathSegments: ' + pathSegments + ' = ' + absolutePath);
|
||
return absolutePath;
|
||
}
|
||
exports.resolve = resolve;
|
||
exports.which = im._which;
|
||
/**
|
||
* Returns array of files in the given path, or in current directory if no path provided. See shelljs.ls
|
||
* @param {string} options Available options: -R (recursive), -A (all files, include files beginning with ., except for . and ..)
|
||
* @param {string[]} paths Paths to search.
|
||
* @return {string[]} An array of files in the given path(s).
|
||
*/
|
||
function ls(options, paths) {
|
||
if (options) {
|
||
return shell.ls(options, paths);
|
||
}
|
||
else {
|
||
return shell.ls(paths);
|
||
}
|
||
}
|
||
exports.ls = ls;
|
||
/**
|
||
* Copies a file or folder.
|
||
*
|
||
* @param source source path
|
||
* @param dest destination path
|
||
* @param options string -r, -f or -rf for recursive and force
|
||
* @param continueOnError optional. whether to continue on error
|
||
* @param retryCount optional. Retry count to copy the file. It might help to resolve intermittent issues e.g. with UNC target paths on a remote host.
|
||
*/
|
||
function cp(source, dest, options, continueOnError, retryCount) {
|
||
if (retryCount === void 0) { retryCount = 0; }
|
||
while (retryCount >= 0) {
|
||
try {
|
||
if (options) {
|
||
shell.cp(options, source, dest);
|
||
}
|
||
else {
|
||
shell.cp(source, dest);
|
||
}
|
||
_checkShell('cp', false);
|
||
break;
|
||
}
|
||
catch (e) {
|
||
if (retryCount <= 0) {
|
||
if (continueOnError) {
|
||
exports.warning(e);
|
||
break;
|
||
}
|
||
else {
|
||
throw e;
|
||
}
|
||
}
|
||
else {
|
||
console.log(exports.loc('LIB_CopyFileFailed', retryCount));
|
||
retryCount--;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
exports.cp = cp;
|
||
/**
|
||
* Moves a path.
|
||
*
|
||
* @param source source path
|
||
* @param dest destination path
|
||
* @param options string -f or -n for force and no clobber
|
||
* @param continueOnError optional. whether to continue on error
|
||
*/
|
||
function mv(source, dest, options, continueOnError) {
|
||
if (options) {
|
||
shell.mv(options, source, dest);
|
||
}
|
||
else {
|
||
shell.mv(source, dest);
|
||
}
|
||
_checkShell('mv', continueOnError);
|
||
}
|
||
exports.mv = mv;
|
||
/**
|
||
* Recursively finds all paths a given path. Returns an array of paths.
|
||
*
|
||
* @param findPath path to search
|
||
* @param options optional. defaults to { followSymbolicLinks: true }. following soft links is generally appropriate unless deleting files.
|
||
* @returns string[]
|
||
*/
|
||
function find(findPath, options) {
|
||
if (!findPath) {
|
||
exports.debug('no path specified');
|
||
return [];
|
||
}
|
||
// normalize the path, otherwise the first result is inconsistently formatted from the rest of the results
|
||
// because path.join() performs normalization.
|
||
findPath = path.normalize(findPath);
|
||
// debug trace the parameters
|
||
exports.debug("findPath: '" + findPath + "'");
|
||
options = options || _getDefaultFindOptions();
|
||
_debugFindOptions(options);
|
||
// return empty if not exists
|
||
try {
|
||
fs.lstatSync(findPath);
|
||
}
|
||
catch (err) {
|
||
if (err.code == 'ENOENT') {
|
||
exports.debug('0 results');
|
||
return [];
|
||
}
|
||
throw err;
|
||
}
|
||
try {
|
||
var result = [];
|
||
// push the first item
|
||
var stack = [new _FindItem(findPath, 1)];
|
||
var traversalChain = []; // used to detect cycles
|
||
var _loop_1 = function () {
|
||
// pop the next item and push to the result array
|
||
var item = stack.pop(); // non-null because `stack.length` was truthy
|
||
result.push(item.path);
|
||
// stat the item. the stat info is used further below to determine whether to traverse deeper
|
||
//
|
||
// stat returns info about the target of a symlink (or symlink chain),
|
||
// lstat returns info about a symlink itself
|
||
var stats_2 = void 0;
|
||
if (options.followSymbolicLinks) {
|
||
try {
|
||
// use stat (following all symlinks)
|
||
stats_2 = fs.statSync(item.path);
|
||
}
|
||
catch (err) {
|
||
if (err.code == 'ENOENT' && options.allowBrokenSymbolicLinks) {
|
||
// fallback to lstat (broken symlinks allowed)
|
||
stats_2 = fs.lstatSync(item.path);
|
||
exports.debug(" " + item.path + " (broken symlink)");
|
||
}
|
||
else {
|
||
throw err;
|
||
}
|
||
}
|
||
}
|
||
else if (options.followSpecifiedSymbolicLink && result.length == 1) {
|
||
try {
|
||
// use stat (following symlinks for the specified path and this is the specified path)
|
||
stats_2 = fs.statSync(item.path);
|
||
}
|
||
catch (err) {
|
||
if (err.code == 'ENOENT' && options.allowBrokenSymbolicLinks) {
|
||
// fallback to lstat (broken symlinks allowed)
|
||
stats_2 = fs.lstatSync(item.path);
|
||
exports.debug(" " + item.path + " (broken symlink)");
|
||
}
|
||
else {
|
||
throw err;
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
// use lstat (not following symlinks)
|
||
stats_2 = fs.lstatSync(item.path);
|
||
}
|
||
// note, isDirectory() returns false for the lstat of a symlink
|
||
if (stats_2.isDirectory()) {
|
||
exports.debug(" " + item.path + " (directory)");
|
||
if (options.followSymbolicLinks) {
|
||
// get the realpath
|
||
var realPath_1 = fs.realpathSync(item.path);
|
||
// fixup the traversal chain to match the item level
|
||
while (traversalChain.length >= item.level) {
|
||
traversalChain.pop();
|
||
}
|
||
// test for a cycle
|
||
if (traversalChain.some(function (x) { return x == realPath_1; })) {
|
||
exports.debug(' cycle detected');
|
||
return "continue";
|
||
}
|
||
// update the traversal chain
|
||
traversalChain.push(realPath_1);
|
||
}
|
||
// push the child items in reverse onto the stack
|
||
var childLevel_1 = item.level + 1;
|
||
var childItems = fs.readdirSync(item.path)
|
||
.map(function (childName) { return new _FindItem(path.join(item.path, childName), childLevel_1); });
|
||
for (var i = childItems.length - 1; i >= 0; i--) {
|
||
stack.push(childItems[i]);
|
||
}
|
||
}
|
||
else {
|
||
exports.debug(" " + item.path + " (file)");
|
||
}
|
||
};
|
||
while (stack.length) {
|
||
_loop_1();
|
||
}
|
||
exports.debug(result.length + " results");
|
||
return result;
|
||
}
|
||
catch (err) {
|
||
throw new Error(exports.loc('LIB_OperationFailed', 'find', err.message));
|
||
}
|
||
}
|
||
exports.find = find;
|
||
var _FindItem = /** @class */ (function () {
|
||
function _FindItem(path, level) {
|
||
this.path = path;
|
||
this.level = level;
|
||
}
|
||
return _FindItem;
|
||
}());
|
||
function _debugFindOptions(options) {
|
||
exports.debug("findOptions.allowBrokenSymbolicLinks: '" + options.allowBrokenSymbolicLinks + "'");
|
||
exports.debug("findOptions.followSpecifiedSymbolicLink: '" + options.followSpecifiedSymbolicLink + "'");
|
||
exports.debug("findOptions.followSymbolicLinks: '" + options.followSymbolicLinks + "'");
|
||
}
|
||
function _getDefaultFindOptions() {
|
||
return {
|
||
allowBrokenSymbolicLinks: false,
|
||
followSpecifiedSymbolicLink: true,
|
||
followSymbolicLinks: true
|
||
};
|
||
}
|
||
/**
|
||
* Prefer tl.find() and tl.match() instead. This function is for backward compatibility
|
||
* when porting tasks to Node from the PowerShell or PowerShell3 execution handler.
|
||
*
|
||
* @param rootDirectory path to root unrooted patterns with
|
||
* @param pattern include and exclude patterns
|
||
* @param includeFiles whether to include files in the result. defaults to true when includeFiles and includeDirectories are both false
|
||
* @param includeDirectories whether to include directories in the result
|
||
* @returns string[]
|
||
*/
|
||
function legacyFindFiles(rootDirectory, pattern, includeFiles, includeDirectories) {
|
||
if (!pattern) {
|
||
throw new Error('pattern parameter cannot be empty');
|
||
}
|
||
exports.debug("legacyFindFiles rootDirectory: '" + rootDirectory + "'");
|
||
exports.debug("pattern: '" + pattern + "'");
|
||
exports.debug("includeFiles: '" + includeFiles + "'");
|
||
exports.debug("includeDirectories: '" + includeDirectories + "'");
|
||
if (!includeFiles && !includeDirectories) {
|
||
includeFiles = true;
|
||
}
|
||
// organize the patterns into include patterns and exclude patterns
|
||
var includePatterns = [];
|
||
var excludePatterns = [];
|
||
pattern = pattern.replace(/;;/g, '\0');
|
||
for (var _i = 0, _a = pattern.split(';'); _i < _a.length; _i++) {
|
||
var pat = _a[_i];
|
||
if (!pat) {
|
||
continue;
|
||
}
|
||
pat = pat.replace(/\0/g, ';');
|
||
// determine whether include pattern and remove any include/exclude prefix.
|
||
// include patterns start with +: or anything other than -:
|
||
// exclude patterns start with -:
|
||
var isIncludePattern = void 0;
|
||
if (im._startsWith(pat, '+:')) {
|
||
pat = pat.substring(2);
|
||
isIncludePattern = true;
|
||
}
|
||
else if (im._startsWith(pat, '-:')) {
|
||
pat = pat.substring(2);
|
||
isIncludePattern = false;
|
||
}
|
||
else {
|
||
isIncludePattern = true;
|
||
}
|
||
// validate pattern does not end with a slash
|
||
if (im._endsWith(pat, '/') || (process.platform == 'win32' && im._endsWith(pat, '\\'))) {
|
||
throw new Error(exports.loc('LIB_InvalidPattern', pat));
|
||
}
|
||
// root the pattern
|
||
if (rootDirectory && !path.isAbsolute(pat)) {
|
||
pat = path.join(rootDirectory, pat);
|
||
// remove trailing slash sometimes added by path.join() on Windows, e.g.
|
||
// path.join('\\\\hello', 'world') => '\\\\hello\\world\\'
|
||
// path.join('//hello', 'world') => '\\\\hello\\world\\'
|
||
if (im._endsWith(pat, '\\')) {
|
||
pat = pat.substring(0, pat.length - 1);
|
||
}
|
||
}
|
||
if (isIncludePattern) {
|
||
includePatterns.push(pat);
|
||
}
|
||
else {
|
||
excludePatterns.push(im._legacyFindFiles_convertPatternToRegExp(pat));
|
||
}
|
||
}
|
||
// find and apply patterns
|
||
var count = 0;
|
||
var result = _legacyFindFiles_getMatchingItems(includePatterns, excludePatterns, !!includeFiles, !!includeDirectories);
|
||
exports.debug('all matches:');
|
||
for (var _b = 0, result_1 = result; _b < result_1.length; _b++) {
|
||
var resultItem = result_1[_b];
|
||
exports.debug(' ' + resultItem);
|
||
}
|
||
exports.debug('total matched: ' + result.length);
|
||
return result;
|
||
}
|
||
exports.legacyFindFiles = legacyFindFiles;
|
||
function _legacyFindFiles_getMatchingItems(includePatterns, excludePatterns, includeFiles, includeDirectories) {
|
||
exports.debug('getMatchingItems()');
|
||
for (var _i = 0, includePatterns_1 = includePatterns; _i < includePatterns_1.length; _i++) {
|
||
var pattern = includePatterns_1[_i];
|
||
exports.debug("includePattern: '" + pattern + "'");
|
||
}
|
||
for (var _a = 0, excludePatterns_1 = excludePatterns; _a < excludePatterns_1.length; _a++) {
|
||
var pattern = excludePatterns_1[_a];
|
||
exports.debug("excludePattern: " + pattern);
|
||
}
|
||
exports.debug('includeFiles: ' + includeFiles);
|
||
exports.debug('includeDirectories: ' + includeDirectories);
|
||
var allFiles = {};
|
||
var _loop_2 = function (pattern) {
|
||
// determine the directory to search
|
||
//
|
||
// note, getDirectoryName removes redundant path separators
|
||
var findPath = void 0;
|
||
var starIndex = pattern.indexOf('*');
|
||
var questionIndex = pattern.indexOf('?');
|
||
if (starIndex < 0 && questionIndex < 0) {
|
||
// if no wildcards are found, use the directory name portion of the path.
|
||
// if there is no directory name (file name only in pattern or drive root),
|
||
// this will return empty string.
|
||
findPath = im._getDirectoryName(pattern);
|
||
}
|
||
else {
|
||
// extract the directory prior to the first wildcard
|
||
var index = Math.min(starIndex >= 0 ? starIndex : questionIndex, questionIndex >= 0 ? questionIndex : starIndex);
|
||
findPath = im._getDirectoryName(pattern.substring(0, index));
|
||
}
|
||
// note, due to this short-circuit and the above usage of getDirectoryName, this
|
||
// function has the same limitations regarding drive roots as the powershell
|
||
// implementation.
|
||
//
|
||
// also note, since getDirectoryName eliminates slash redundancies, some additional
|
||
// work may be required if removal of this limitation is attempted.
|
||
if (!findPath) {
|
||
return "continue";
|
||
}
|
||
var patternRegex = im._legacyFindFiles_convertPatternToRegExp(pattern);
|
||
// find files/directories
|
||
var items = find(findPath, { followSymbolicLinks: true })
|
||
.filter(function (item) {
|
||
if (includeFiles && includeDirectories) {
|
||
return true;
|
||
}
|
||
var isDir = fs.statSync(item).isDirectory();
|
||
return (includeFiles && !isDir) || (includeDirectories && isDir);
|
||
})
|
||
.forEach(function (item) {
|
||
var normalizedPath = process.platform == 'win32' ? item.replace(/\\/g, '/') : item; // normalize separators
|
||
// **/times/** will not match C:/fun/times because there isn't a trailing slash
|
||
// so try both if including directories
|
||
var alternatePath = normalizedPath + "/"; // potential bug: it looks like this will result in a false
|
||
// positive if the item is a regular file and not a directory
|
||
var isMatch = false;
|
||
if (patternRegex.test(normalizedPath) || (includeDirectories && patternRegex.test(alternatePath))) {
|
||
isMatch = true;
|
||
// test whether the path should be excluded
|
||
for (var _i = 0, excludePatterns_2 = excludePatterns; _i < excludePatterns_2.length; _i++) {
|
||
var regex = excludePatterns_2[_i];
|
||
if (regex.test(normalizedPath) || (includeDirectories && regex.test(alternatePath))) {
|
||
isMatch = false;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if (isMatch) {
|
||
allFiles[item] = item;
|
||
}
|
||
});
|
||
};
|
||
for (var _b = 0, includePatterns_2 = includePatterns; _b < includePatterns_2.length; _b++) {
|
||
var pattern = includePatterns_2[_b];
|
||
_loop_2(pattern);
|
||
}
|
||
return Object.keys(allFiles).sort();
|
||
}
|
||
/**
|
||
* Remove a path recursively with force
|
||
*
|
||
* @param inputPath path to remove
|
||
* @throws when the file or directory exists but could not be deleted.
|
||
*/
|
||
function rmRF(inputPath) {
|
||
exports.debug('rm -rf ' + inputPath);
|
||
if (getPlatform() == Platform.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 (fs.statSync(inputPath).isDirectory()) {
|
||
exports.debug('removing directory ' + inputPath);
|
||
childProcess.execSync("rd /s /q \"" + inputPath + "\"");
|
||
}
|
||
else {
|
||
exports.debug('removing file ' + inputPath);
|
||
childProcess.execSync("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 new Error(exports.loc('LIB_OperationFailed', 'rmRF', err.message));
|
||
}
|
||
}
|
||
// Shelling out fails to remove a symlink folder with missing source, this unlink catches that
|
||
try {
|
||
fs.unlinkSync(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 new Error(exports.loc('LIB_OperationFailed', 'rmRF', err.message));
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
// get the lstats in order to workaround a bug in shelljs@0.3.0 where symlinks
|
||
// with missing targets are not handled correctly by "rm('-rf', path)"
|
||
var lstats = void 0;
|
||
try {
|
||
lstats = fs.lstatSync(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') {
|
||
return;
|
||
}
|
||
throw new Error(exports.loc('LIB_OperationFailed', 'rmRF', err.message));
|
||
}
|
||
if (lstats.isDirectory()) {
|
||
exports.debug('removing directory');
|
||
shell.rm('-rf', inputPath);
|
||
var errMsg = shell.error();
|
||
if (errMsg) {
|
||
throw new Error(exports.loc('LIB_OperationFailed', 'rmRF', errMsg));
|
||
}
|
||
return;
|
||
}
|
||
exports.debug('removing file');
|
||
try {
|
||
fs.unlinkSync(inputPath);
|
||
}
|
||
catch (err) {
|
||
throw new Error(exports.loc('LIB_OperationFailed', 'rmRF', err.message));
|
||
}
|
||
}
|
||
}
|
||
exports.rmRF = rmRF;
|
||
/**
|
||
* Exec a tool. Convenience wrapper over ToolRunner to exec with args in one call.
|
||
* Output will be streamed to the live console.
|
||
* Returns promise with return code
|
||
*
|
||
* @param tool path to tool to exec
|
||
* @param args an arg string or array of args
|
||
* @param options optional exec options. See IExecOptions
|
||
* @returns number
|
||
*/
|
||
function exec(tool, args, options) {
|
||
var tr = this.tool(tool);
|
||
tr.on('debug', function (data) {
|
||
exports.debug(data);
|
||
});
|
||
if (args) {
|
||
if (args instanceof Array) {
|
||
tr.arg(args);
|
||
}
|
||
else if (typeof (args) === 'string') {
|
||
tr.line(args);
|
||
}
|
||
}
|
||
return tr.exec(options);
|
||
}
|
||
exports.exec = exec;
|
||
/**
|
||
* Exec a tool synchronously. Convenience wrapper over ToolRunner to execSync with args in one call.
|
||
* Output will be *not* be streamed to the live console. It will be returned after execution is complete.
|
||
* Appropriate for short running tools
|
||
* Returns IExecResult with output and return code
|
||
*
|
||
* @param tool path to tool to exec
|
||
* @param args an arg string or array of args
|
||
* @param options optional exec options. See IExecSyncOptions
|
||
* @returns IExecSyncResult
|
||
*/
|
||
function execSync(tool, args, options) {
|
||
var tr = this.tool(tool);
|
||
tr.on('debug', function (data) {
|
||
exports.debug(data);
|
||
});
|
||
if (args) {
|
||
if (args instanceof Array) {
|
||
tr.arg(args);
|
||
}
|
||
else if (typeof (args) === 'string') {
|
||
tr.line(args);
|
||
}
|
||
}
|
||
return tr.execSync(options);
|
||
}
|
||
exports.execSync = execSync;
|
||
/**
|
||
* Convenience factory to create a ToolRunner.
|
||
*
|
||
* @param tool path to tool to exec
|
||
* @returns ToolRunner
|
||
*/
|
||
function tool(tool) {
|
||
var tr = new trm.ToolRunner(tool);
|
||
tr.on('debug', function (message) {
|
||
exports.debug(message);
|
||
});
|
||
return tr;
|
||
}
|
||
exports.tool = tool;
|
||
/**
|
||
* Applies glob patterns to a list of paths. Supports interleaved exclude patterns.
|
||
*
|
||
* @param list array of paths
|
||
* @param patterns patterns to apply. supports interleaved exclude patterns.
|
||
* @param patternRoot optional. default root to apply to unrooted patterns. not applied to basename-only patterns when matchBase:true.
|
||
* @param options optional. defaults to { dot: true, nobrace: true, nocase: process.platform == 'win32' }.
|
||
*/
|
||
function match(list, patterns, patternRoot, options) {
|
||
// trace parameters
|
||
exports.debug("patternRoot: '" + patternRoot + "'");
|
||
options = options || _getDefaultMatchOptions(); // default match options
|
||
_debugMatchOptions(options);
|
||
// convert pattern to an array
|
||
if (typeof patterns == 'string') {
|
||
patterns = [patterns];
|
||
}
|
||
// hashtable to keep track of matches
|
||
var map = {};
|
||
var originalOptions = options;
|
||
for (var _i = 0, patterns_1 = patterns; _i < patterns_1.length; _i++) {
|
||
var pattern = patterns_1[_i];
|
||
exports.debug("pattern: '" + pattern + "'");
|
||
// trim and skip empty
|
||
pattern = (pattern || '').trim();
|
||
if (!pattern) {
|
||
exports.debug('skipping empty pattern');
|
||
continue;
|
||
}
|
||
// clone match options
|
||
var options_1 = im._cloneMatchOptions(originalOptions);
|
||
// skip comments
|
||
if (!options_1.nocomment && im._startsWith(pattern, '#')) {
|
||
exports.debug('skipping comment');
|
||
continue;
|
||
}
|
||
// set nocomment - brace expansion could result in a leading '#'
|
||
options_1.nocomment = true;
|
||
// determine whether pattern is include or exclude
|
||
var negateCount = 0;
|
||
if (!options_1.nonegate) {
|
||
while (pattern.charAt(negateCount) == '!') {
|
||
negateCount++;
|
||
}
|
||
pattern = pattern.substring(negateCount); // trim leading '!'
|
||
if (negateCount) {
|
||
exports.debug("trimmed leading '!'. pattern: '" + pattern + "'");
|
||
}
|
||
}
|
||
var isIncludePattern = negateCount == 0 ||
|
||
(negateCount % 2 == 0 && !options_1.flipNegate) ||
|
||
(negateCount % 2 == 1 && options_1.flipNegate);
|
||
// set nonegate - brace expansion could result in a leading '!'
|
||
options_1.nonegate = true;
|
||
options_1.flipNegate = false;
|
||
// expand braces - required to accurately root patterns
|
||
var expanded = void 0;
|
||
var preExpanded = pattern;
|
||
if (options_1.nobrace) {
|
||
expanded = [pattern];
|
||
}
|
||
else {
|
||
// convert slashes on Windows before calling braceExpand(). unfortunately this means braces cannot
|
||
// be escaped on Windows, this limitation is consistent with current limitations of minimatch (3.0.3).
|
||
exports.debug('expanding braces');
|
||
var convertedPattern = process.platform == 'win32' ? pattern.replace(/\\/g, '/') : pattern;
|
||
expanded = minimatch.braceExpand(convertedPattern);
|
||
}
|
||
// set nobrace
|
||
options_1.nobrace = true;
|
||
for (var _a = 0, expanded_1 = expanded; _a < expanded_1.length; _a++) {
|
||
var pattern_1 = expanded_1[_a];
|
||
if (expanded.length != 1 || pattern_1 != preExpanded) {
|
||
exports.debug("pattern: '" + pattern_1 + "'");
|
||
}
|
||
// trim and skip empty
|
||
pattern_1 = (pattern_1 || '').trim();
|
||
if (!pattern_1) {
|
||
exports.debug('skipping empty pattern');
|
||
continue;
|
||
}
|
||
// root the pattern when all of the following conditions are true:
|
||
if (patternRoot && // patternRoot supplied
|
||
!im._isRooted(pattern_1) && // AND pattern not rooted
|
||
// AND matchBase:false or not basename only
|
||
(!options_1.matchBase || (process.platform == 'win32' ? pattern_1.replace(/\\/g, '/') : pattern_1).indexOf('/') >= 0)) {
|
||
pattern_1 = im._ensureRooted(patternRoot, pattern_1);
|
||
exports.debug("rooted pattern: '" + pattern_1 + "'");
|
||
}
|
||
if (isIncludePattern) {
|
||
// apply the pattern
|
||
exports.debug('applying include pattern against original list');
|
||
var matchResults = minimatch.match(list, pattern_1, options_1);
|
||
exports.debug(matchResults.length + ' matches');
|
||
// union the results
|
||
for (var _b = 0, matchResults_1 = matchResults; _b < matchResults_1.length; _b++) {
|
||
var matchResult = matchResults_1[_b];
|
||
map[matchResult] = true;
|
||
}
|
||
}
|
||
else {
|
||
// apply the pattern
|
||
exports.debug('applying exclude pattern against original list');
|
||
var matchResults = minimatch.match(list, pattern_1, options_1);
|
||
exports.debug(matchResults.length + ' matches');
|
||
// substract the results
|
||
for (var _c = 0, matchResults_2 = matchResults; _c < matchResults_2.length; _c++) {
|
||
var matchResult = matchResults_2[_c];
|
||
delete map[matchResult];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// return a filtered version of the original list (preserves order and prevents duplication)
|
||
var result = list.filter(function (item) { return map.hasOwnProperty(item); });
|
||
exports.debug(result.length + ' final results');
|
||
return result;
|
||
}
|
||
exports.match = match;
|
||
/**
|
||
* Filter to apply glob patterns
|
||
*
|
||
* @param pattern pattern to apply
|
||
* @param options optional. defaults to { dot: true, nobrace: true, nocase: process.platform == 'win32' }.
|
||
*/
|
||
function filter(pattern, options) {
|
||
options = options || _getDefaultMatchOptions();
|
||
return minimatch.filter(pattern, options);
|
||
}
|
||
exports.filter = filter;
|
||
function _debugMatchOptions(options) {
|
||
exports.debug("matchOptions.debug: '" + options.debug + "'");
|
||
exports.debug("matchOptions.nobrace: '" + options.nobrace + "'");
|
||
exports.debug("matchOptions.noglobstar: '" + options.noglobstar + "'");
|
||
exports.debug("matchOptions.dot: '" + options.dot + "'");
|
||
exports.debug("matchOptions.noext: '" + options.noext + "'");
|
||
exports.debug("matchOptions.nocase: '" + options.nocase + "'");
|
||
exports.debug("matchOptions.nonull: '" + options.nonull + "'");
|
||
exports.debug("matchOptions.matchBase: '" + options.matchBase + "'");
|
||
exports.debug("matchOptions.nocomment: '" + options.nocomment + "'");
|
||
exports.debug("matchOptions.nonegate: '" + options.nonegate + "'");
|
||
exports.debug("matchOptions.flipNegate: '" + options.flipNegate + "'");
|
||
}
|
||
function _getDefaultMatchOptions() {
|
||
return {
|
||
debug: false,
|
||
nobrace: true,
|
||
noglobstar: false,
|
||
dot: true,
|
||
noext: false,
|
||
nocase: process.platform == 'win32',
|
||
nonull: false,
|
||
matchBase: false,
|
||
nocomment: false,
|
||
nonegate: false,
|
||
flipNegate: false
|
||
};
|
||
}
|
||
/**
|
||
* Determines the find root from a list of patterns. Performs the find and then applies the glob patterns.
|
||
* Supports interleaved exclude patterns. Unrooted patterns are rooted using defaultRoot, unless
|
||
* matchOptions.matchBase is specified and the pattern is a basename only. For matchBase cases, the
|
||
* defaultRoot is used as the find root.
|
||
*
|
||
* @param defaultRoot default path to root unrooted patterns. falls back to System.DefaultWorkingDirectory or process.cwd().
|
||
* @param patterns pattern or array of patterns to apply
|
||
* @param findOptions defaults to { followSymbolicLinks: true }. following soft links is generally appropriate unless deleting files.
|
||
* @param matchOptions defaults to { dot: true, nobrace: true, nocase: process.platform == 'win32' }
|
||
*/
|
||
function findMatch(defaultRoot, patterns, findOptions, matchOptions) {
|
||
// apply defaults for parameters and trace
|
||
defaultRoot = defaultRoot || this.getVariable('system.defaultWorkingDirectory') || process.cwd();
|
||
exports.debug("defaultRoot: '" + defaultRoot + "'");
|
||
patterns = patterns || [];
|
||
patterns = typeof patterns == 'string' ? [patterns] : patterns;
|
||
findOptions = findOptions || _getDefaultFindOptions();
|
||
_debugFindOptions(findOptions);
|
||
matchOptions = matchOptions || _getDefaultMatchOptions();
|
||
_debugMatchOptions(matchOptions);
|
||
// normalize slashes for root dir
|
||
defaultRoot = im._normalizeSeparators(defaultRoot);
|
||
var results = {};
|
||
var originalMatchOptions = matchOptions;
|
||
for (var _i = 0, _a = (patterns || []); _i < _a.length; _i++) {
|
||
var pattern = _a[_i];
|
||
exports.debug("pattern: '" + pattern + "'");
|
||
// trim and skip empty
|
||
pattern = (pattern || '').trim();
|
||
if (!pattern) {
|
||
exports.debug('skipping empty pattern');
|
||
continue;
|
||
}
|
||
// clone match options
|
||
var matchOptions_1 = im._cloneMatchOptions(originalMatchOptions);
|
||
// skip comments
|
||
if (!matchOptions_1.nocomment && im._startsWith(pattern, '#')) {
|
||
exports.debug('skipping comment');
|
||
continue;
|
||
}
|
||
// set nocomment - brace expansion could result in a leading '#'
|
||
matchOptions_1.nocomment = true;
|
||
// determine whether pattern is include or exclude
|
||
var negateCount = 0;
|
||
if (!matchOptions_1.nonegate) {
|
||
while (pattern.charAt(negateCount) == '!') {
|
||
negateCount++;
|
||
}
|
||
pattern = pattern.substring(negateCount); // trim leading '!'
|
||
if (negateCount) {
|
||
exports.debug("trimmed leading '!'. pattern: '" + pattern + "'");
|
||
}
|
||
}
|
||
var isIncludePattern = negateCount == 0 ||
|
||
(negateCount % 2 == 0 && !matchOptions_1.flipNegate) ||
|
||
(negateCount % 2 == 1 && matchOptions_1.flipNegate);
|
||
// set nonegate - brace expansion could result in a leading '!'
|
||
matchOptions_1.nonegate = true;
|
||
matchOptions_1.flipNegate = false;
|
||
// expand braces - required to accurately interpret findPath
|
||
var expanded = void 0;
|
||
var preExpanded = pattern;
|
||
if (matchOptions_1.nobrace) {
|
||
expanded = [pattern];
|
||
}
|
||
else {
|
||
// convert slashes on Windows before calling braceExpand(). unfortunately this means braces cannot
|
||
// be escaped on Windows, this limitation is consistent with current limitations of minimatch (3.0.3).
|
||
exports.debug('expanding braces');
|
||
var convertedPattern = process.platform == 'win32' ? pattern.replace(/\\/g, '/') : pattern;
|
||
expanded = minimatch.braceExpand(convertedPattern);
|
||
}
|
||
// set nobrace
|
||
matchOptions_1.nobrace = true;
|
||
for (var _b = 0, expanded_2 = expanded; _b < expanded_2.length; _b++) {
|
||
var pattern_2 = expanded_2[_b];
|
||
if (expanded.length != 1 || pattern_2 != preExpanded) {
|
||
exports.debug("pattern: '" + pattern_2 + "'");
|
||
}
|
||
// trim and skip empty
|
||
pattern_2 = (pattern_2 || '').trim();
|
||
if (!pattern_2) {
|
||
exports.debug('skipping empty pattern');
|
||
continue;
|
||
}
|
||
if (isIncludePattern) {
|
||
// determine the findPath
|
||
var findInfo = im._getFindInfoFromPattern(defaultRoot, pattern_2, matchOptions_1);
|
||
var findPath = findInfo.findPath;
|
||
exports.debug("findPath: '" + findPath + "'");
|
||
if (!findPath) {
|
||
exports.debug('skipping empty path');
|
||
continue;
|
||
}
|
||
// perform the find
|
||
exports.debug("statOnly: '" + findInfo.statOnly + "'");
|
||
var findResults = [];
|
||
if (findInfo.statOnly) {
|
||
// simply stat the path - all path segments were used to build the path
|
||
try {
|
||
fs.statSync(findPath);
|
||
findResults.push(findPath);
|
||
}
|
||
catch (err) {
|
||
if (err.code != 'ENOENT') {
|
||
throw err;
|
||
}
|
||
exports.debug('ENOENT');
|
||
}
|
||
}
|
||
else {
|
||
findResults = find(findPath, findOptions);
|
||
}
|
||
exports.debug("found " + findResults.length + " paths");
|
||
// apply the pattern
|
||
exports.debug('applying include pattern');
|
||
if (findInfo.adjustedPattern != pattern_2) {
|
||
exports.debug("adjustedPattern: '" + findInfo.adjustedPattern + "'");
|
||
pattern_2 = findInfo.adjustedPattern;
|
||
}
|
||
var matchResults = minimatch.match(findResults, pattern_2, matchOptions_1);
|
||
exports.debug(matchResults.length + ' matches');
|
||
// union the results
|
||
for (var _c = 0, matchResults_3 = matchResults; _c < matchResults_3.length; _c++) {
|
||
var matchResult = matchResults_3[_c];
|
||
var key = process.platform == 'win32' ? matchResult.toUpperCase() : matchResult;
|
||
results[key] = matchResult;
|
||
}
|
||
}
|
||
else {
|
||
// check if basename only and matchBase=true
|
||
if (matchOptions_1.matchBase &&
|
||
!im._isRooted(pattern_2) &&
|
||
(process.platform == 'win32' ? pattern_2.replace(/\\/g, '/') : pattern_2).indexOf('/') < 0) {
|
||
// do not root the pattern
|
||
exports.debug('matchBase and basename only');
|
||
}
|
||
else {
|
||
// root the exclude pattern
|
||
pattern_2 = im._ensurePatternRooted(defaultRoot, pattern_2);
|
||
exports.debug("after ensurePatternRooted, pattern: '" + pattern_2 + "'");
|
||
}
|
||
// apply the pattern
|
||
exports.debug('applying exclude pattern');
|
||
var matchResults = minimatch.match(Object.keys(results).map(function (key) { return results[key]; }), pattern_2, matchOptions_1);
|
||
exports.debug(matchResults.length + ' matches');
|
||
// substract the results
|
||
for (var _d = 0, matchResults_4 = matchResults; _d < matchResults_4.length; _d++) {
|
||
var matchResult = matchResults_4[_d];
|
||
var key = process.platform == 'win32' ? matchResult.toUpperCase() : matchResult;
|
||
delete results[key];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
var finalResult = Object.keys(results)
|
||
.map(function (key) { return results[key]; })
|
||
.sort();
|
||
exports.debug(finalResult.length + ' final results');
|
||
return finalResult;
|
||
}
|
||
exports.findMatch = findMatch;
|
||
/**
|
||
* Gets http proxy configuration used by Build/Release agent
|
||
*
|
||
* @return ProxyConfiguration
|
||
*/
|
||
function getHttpProxyConfiguration(requestUrl) {
|
||
var proxyUrl = exports.getVariable('Agent.ProxyUrl');
|
||
if (proxyUrl && proxyUrl.length > 0) {
|
||
var proxyUsername = exports.getVariable('Agent.ProxyUsername');
|
||
var proxyPassword = exports.getVariable('Agent.ProxyPassword');
|
||
var proxyBypassHosts = JSON.parse(exports.getVariable('Agent.ProxyBypassList') || '[]');
|
||
var bypass_1 = false;
|
||
if (requestUrl) {
|
||
proxyBypassHosts.forEach(function (bypassHost) {
|
||
if (new RegExp(bypassHost, 'i').test(requestUrl)) {
|
||
bypass_1 = true;
|
||
}
|
||
});
|
||
}
|
||
if (bypass_1) {
|
||
return null;
|
||
}
|
||
else {
|
||
return {
|
||
proxyUrl: proxyUrl,
|
||
proxyUsername: proxyUsername,
|
||
proxyPassword: proxyPassword,
|
||
proxyBypassHosts: proxyBypassHosts
|
||
};
|
||
}
|
||
}
|
||
else {
|
||
return null;
|
||
}
|
||
}
|
||
exports.getHttpProxyConfiguration = getHttpProxyConfiguration;
|
||
/**
|
||
* Gets http certificate configuration used by Build/Release agent
|
||
*
|
||
* @return CertConfiguration
|
||
*/
|
||
function getHttpCertConfiguration() {
|
||
var ca = exports.getVariable('Agent.CAInfo');
|
||
var clientCert = exports.getVariable('Agent.ClientCert');
|
||
if (ca || clientCert) {
|
||
var certConfig = {};
|
||
certConfig.caFile = ca;
|
||
certConfig.certFile = clientCert;
|
||
if (clientCert) {
|
||
var clientCertKey = exports.getVariable('Agent.ClientCertKey');
|
||
var clientCertArchive = exports.getVariable('Agent.ClientCertArchive');
|
||
var clientCertPassword = exports.getVariable('Agent.ClientCertPassword');
|
||
certConfig.keyFile = clientCertKey;
|
||
certConfig.certArchiveFile = clientCertArchive;
|
||
certConfig.passphrase = clientCertPassword;
|
||
}
|
||
return certConfig;
|
||
}
|
||
else {
|
||
return null;
|
||
}
|
||
}
|
||
exports.getHttpCertConfiguration = getHttpCertConfiguration;
|
||
//-----------------------------------------------------
|
||
// Test Publisher
|
||
//-----------------------------------------------------
|
||
var TestPublisher = /** @class */ (function () {
|
||
function TestPublisher(testRunner) {
|
||
this.testRunner = testRunner;
|
||
}
|
||
TestPublisher.prototype.publish = function (resultFiles, mergeResults, platform, config, runTitle, publishRunAttachments, testRunSystem) {
|
||
// Could have used an initializer, but wanted to avoid reordering parameters when converting to strict null checks
|
||
// (A parameter cannot both be optional and have an initializer)
|
||
testRunSystem = testRunSystem || "VSTSTask";
|
||
var properties = {};
|
||
properties['type'] = this.testRunner;
|
||
if (mergeResults) {
|
||
properties['mergeResults'] = mergeResults;
|
||
}
|
||
if (platform) {
|
||
properties['platform'] = platform;
|
||
}
|
||
if (config) {
|
||
properties['config'] = config;
|
||
}
|
||
if (runTitle) {
|
||
properties['runTitle'] = runTitle;
|
||
}
|
||
if (publishRunAttachments) {
|
||
properties['publishRunAttachments'] = publishRunAttachments;
|
||
}
|
||
if (resultFiles) {
|
||
properties['resultFiles'] = Array.isArray(resultFiles) ? resultFiles.join() : resultFiles;
|
||
}
|
||
properties['testRunSystem'] = testRunSystem;
|
||
exports.command('results.publish', properties, '');
|
||
};
|
||
return TestPublisher;
|
||
}());
|
||
exports.TestPublisher = TestPublisher;
|
||
//-----------------------------------------------------
|
||
// Code coverage Publisher
|
||
//-----------------------------------------------------
|
||
var CodeCoveragePublisher = /** @class */ (function () {
|
||
function CodeCoveragePublisher() {
|
||
}
|
||
CodeCoveragePublisher.prototype.publish = function (codeCoverageTool, summaryFileLocation, reportDirectory, additionalCodeCoverageFiles) {
|
||
var properties = {};
|
||
if (codeCoverageTool) {
|
||
properties['codecoveragetool'] = codeCoverageTool;
|
||
}
|
||
if (summaryFileLocation) {
|
||
properties['summaryfile'] = summaryFileLocation;
|
||
}
|
||
if (reportDirectory) {
|
||
properties['reportdirectory'] = reportDirectory;
|
||
}
|
||
if (additionalCodeCoverageFiles) {
|
||
properties['additionalcodecoveragefiles'] = Array.isArray(additionalCodeCoverageFiles) ? additionalCodeCoverageFiles.join() : additionalCodeCoverageFiles;
|
||
}
|
||
exports.command('codecoverage.publish', properties, "");
|
||
};
|
||
return CodeCoveragePublisher;
|
||
}());
|
||
exports.CodeCoveragePublisher = CodeCoveragePublisher;
|
||
//-----------------------------------------------------
|
||
// Code coverage Publisher
|
||
//-----------------------------------------------------
|
||
var CodeCoverageEnabler = /** @class */ (function () {
|
||
function CodeCoverageEnabler(buildTool, ccTool) {
|
||
this.buildTool = buildTool;
|
||
this.ccTool = ccTool;
|
||
}
|
||
CodeCoverageEnabler.prototype.enableCodeCoverage = function (buildProps) {
|
||
buildProps['buildtool'] = this.buildTool;
|
||
buildProps['codecoveragetool'] = this.ccTool;
|
||
exports.command('codecoverage.enable', buildProps, "");
|
||
};
|
||
return CodeCoverageEnabler;
|
||
}());
|
||
exports.CodeCoverageEnabler = CodeCoverageEnabler;
|
||
//-----------------------------------------------------
|
||
// Task Logging Commands
|
||
//-----------------------------------------------------
|
||
/**
|
||
* Upload user interested file as additional log information
|
||
* to the current timeline record.
|
||
*
|
||
* The file shall be available for download along with task logs.
|
||
*
|
||
* @param path Path to the file that should be uploaded.
|
||
* @returns void
|
||
*/
|
||
function uploadFile(path) {
|
||
exports.command("task.uploadfile", null, path);
|
||
}
|
||
exports.uploadFile = uploadFile;
|
||
/**
|
||
* Instruction for the agent to update the PATH environment variable.
|
||
* The specified directory is prepended to the PATH.
|
||
* The updated environment variable will be reflected in subsequent tasks.
|
||
*
|
||
* @param path Local directory path.
|
||
* @returns void
|
||
*/
|
||
function prependPath(path) {
|
||
assertAgent("2.115.0");
|
||
exports.command("task.prependpath", null, path);
|
||
}
|
||
exports.prependPath = prependPath;
|
||
/**
|
||
* Upload and attach summary markdown to current timeline record.
|
||
* This summary shall be added to the build/release summary and
|
||
* not available for download with logs.
|
||
*
|
||
* @param path Local directory path.
|
||
* @returns void
|
||
*/
|
||
function uploadSummary(path) {
|
||
exports.command("task.uploadsummary", null, path);
|
||
}
|
||
exports.uploadSummary = uploadSummary;
|
||
/**
|
||
* Upload and attach attachment to current timeline record.
|
||
* These files are not available for download with logs.
|
||
* These can only be referred to by extensions using the type or name values.
|
||
*
|
||
* @param type Attachment type.
|
||
* @param name Attachment name.
|
||
* @param path Attachment path.
|
||
* @returns void
|
||
*/
|
||
function addAttachment(type, name, path) {
|
||
exports.command("task.addattachment", { "type": type, "name": name }, path);
|
||
}
|
||
exports.addAttachment = addAttachment;
|
||
/**
|
||
* Set an endpoint field with given value.
|
||
* Value updated will be retained in the endpoint for
|
||
* the subsequent tasks that execute within the same job.
|
||
*
|
||
* @param id Endpoint id.
|
||
* @param field FieldType enum of AuthParameter, DataParameter or Url.
|
||
* @param key Key.
|
||
* @param value Value for key or url.
|
||
* @returns void
|
||
*/
|
||
function setEndpoint(id, field, key, value) {
|
||
exports.command("task.setendpoint", { "id": id, "field": FieldType[field].toLowerCase(), "key": key }, value);
|
||
}
|
||
exports.setEndpoint = setEndpoint;
|
||
/**
|
||
* Set progress and current operation for current task.
|
||
*
|
||
* @param percent Percentage of completion.
|
||
* @param currentOperation Current pperation.
|
||
* @returns void
|
||
*/
|
||
function setProgress(percent, currentOperation) {
|
||
exports.command("task.setprogress", { "value": "" + percent }, currentOperation);
|
||
}
|
||
exports.setProgress = setProgress;
|
||
/**
|
||
* Indicates whether to write the logging command directly to the host or to the output pipeline.
|
||
*
|
||
* @param id Timeline record Guid.
|
||
* @param parentId Parent timeline record Guid.
|
||
* @param recordType Record type.
|
||
* @param recordName Record name.
|
||
* @param order Order of timeline record.
|
||
* @param startTime Start time.
|
||
* @param finishTime End time.
|
||
* @param progress Percentage of completion.
|
||
* @param state TaskState enum of Unknown, Initialized, InProgress or Completed.
|
||
* @param result TaskResult enum of Succeeded, SucceededWithIssues, Failed, Cancelled or Skipped.
|
||
* @param message current operation
|
||
* @returns void
|
||
*/
|
||
function logDetail(id, message, parentId, recordType, recordName, order, startTime, finishTime, progress, state, result) {
|
||
var properties = {
|
||
"id": id,
|
||
"parentid": parentId,
|
||
"type": recordType,
|
||
"name": recordName,
|
||
"order": order ? order.toString() : undefined,
|
||
"starttime": startTime,
|
||
"finishtime": finishTime,
|
||
"progress": progress ? progress.toString() : undefined,
|
||
"state": state ? TaskState[state] : undefined,
|
||
"result": result ? TaskResult[result] : undefined
|
||
};
|
||
exports.command("task.logdetail", properties, message);
|
||
}
|
||
exports.logDetail = logDetail;
|
||
/**
|
||
* Log error or warning issue to timeline record of current task.
|
||
*
|
||
* @param type IssueType enum of Error or Warning.
|
||
* @param sourcePath Source file location.
|
||
* @param lineNumber Line number.
|
||
* @param columnNumber Column number.
|
||
* @param code Error or warning code.
|
||
* @param message Error or warning message.
|
||
* @returns void
|
||
*/
|
||
function logIssue(type, message, sourcePath, lineNumber, columnNumber, errorCode) {
|
||
var properties = {
|
||
"type": IssueType[type].toLowerCase(),
|
||
"code": errorCode,
|
||
"sourcepath": sourcePath,
|
||
"linenumber": lineNumber ? lineNumber.toString() : undefined,
|
||
"columnnumber": columnNumber ? columnNumber.toString() : undefined,
|
||
};
|
||
exports.command("task.logissue", properties, message);
|
||
}
|
||
exports.logIssue = logIssue;
|
||
//-----------------------------------------------------
|
||
// Artifact Logging Commands
|
||
//-----------------------------------------------------
|
||
/**
|
||
* Upload user interested file as additional log information
|
||
* to the current timeline record.
|
||
*
|
||
* The file shall be available for download along with task logs.
|
||
*
|
||
* @param containerFolder Folder that the file will upload to, folder will be created if needed.
|
||
* @param path Path to the file that should be uploaded.
|
||
* @param name Artifact name.
|
||
* @returns void
|
||
*/
|
||
function uploadArtifact(containerFolder, path, name) {
|
||
exports.command("artifact.upload", { "containerfolder": containerFolder, "artifactname": name }, path);
|
||
}
|
||
exports.uploadArtifact = uploadArtifact;
|
||
/**
|
||
* Create an artifact link, artifact location is required to be
|
||
* a file container path, VC path or UNC share path.
|
||
*
|
||
* The file shall be available for download along with task logs.
|
||
*
|
||
* @param name Artifact name.
|
||
* @param path Path to the file that should be associated.
|
||
* @param artifactType ArtifactType enum of Container, FilePath, VersionControl, GitRef or TfvcLabel.
|
||
* @returns void
|
||
*/
|
||
function associateArtifact(name, path, artifactType) {
|
||
exports.command("artifact.associate", { "type": ArtifactType[artifactType].toLowerCase(), "artifactname": name }, path);
|
||
}
|
||
exports.associateArtifact = associateArtifact;
|
||
//-----------------------------------------------------
|
||
// Build Logging Commands
|
||
//-----------------------------------------------------
|
||
/**
|
||
* Upload user interested log to build’s container “logs\tool” folder.
|
||
*
|
||
* @param path Path to the file that should be uploaded.
|
||
* @returns void
|
||
*/
|
||
function uploadBuildLog(path) {
|
||
exports.command("build.uploadlog", null, path);
|
||
}
|
||
exports.uploadBuildLog = uploadBuildLog;
|
||
/**
|
||
* Update build number for current build.
|
||
*
|
||
* @param value Value to be assigned as the build number.
|
||
* @returns void
|
||
*/
|
||
function updateBuildNumber(value) {
|
||
exports.command("build.updatebuildnumber", null, value);
|
||
}
|
||
exports.updateBuildNumber = updateBuildNumber;
|
||
/**
|
||
* Add a tag for current build.
|
||
*
|
||
* @param value Tag value.
|
||
* @returns void
|
||
*/
|
||
function addBuildTag(value) {
|
||
exports.command("build.addbuildtag", null, value);
|
||
}
|
||
exports.addBuildTag = addBuildTag;
|
||
//-----------------------------------------------------
|
||
// Release Logging Commands
|
||
//-----------------------------------------------------
|
||
/**
|
||
* Update release name for current release.
|
||
*
|
||
* @param value Value to be assigned as the release name.
|
||
* @returns void
|
||
*/
|
||
function updateReleaseName(name) {
|
||
assertAgent("2.132");
|
||
exports.command("release.updatereleasename", null, name);
|
||
}
|
||
exports.updateReleaseName = updateReleaseName;
|
||
//-----------------------------------------------------
|
||
// Tools
|
||
//-----------------------------------------------------
|
||
exports.TaskCommand = tcm.TaskCommand;
|
||
exports.commandFromString = tcm.commandFromString;
|
||
exports.ToolRunner = trm.ToolRunner;
|
||
//-----------------------------------------------------
|
||
// Validation Checks
|
||
//-----------------------------------------------------
|
||
// async await needs generators in node 4.x+
|
||
if (semver.lt(process.versions.node, '4.2.0')) {
|
||
exports.warning('Tasks require a new agent. Upgrade your agent or node to 4.2.0 or later');
|
||
}
|
||
//-------------------------------------------------------------------
|
||
// Populate the vault with sensitive data. Inputs and Endpoints
|
||
//-------------------------------------------------------------------
|
||
// avoid loading twice (overwrites .taskkey)
|
||
if (!global['_vsts_task_lib_loaded']) {
|
||
im._loadData();
|
||
im._exposeProxySettings();
|
||
im._exposeCertSettings();
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-task-lib/taskcommand.js":
|
||
/*!**************************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-task-lib/taskcommand.js ***!
|
||
\**************************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.commandFromString = exports.TaskCommand = void 0;
|
||
//
|
||
// Command Format:
|
||
// ##vso[artifact.command key=value;key=value]user message
|
||
//
|
||
// Examples:
|
||
// ##vso[task.progress value=58]
|
||
// ##vso[task.issue type=warning;]This is the user warning message
|
||
//
|
||
var CMD_PREFIX = '##vso[';
|
||
var TaskCommand = /** @class */ (function () {
|
||
function TaskCommand(command, properties, message) {
|
||
if (!command) {
|
||
command = 'missing.command';
|
||
}
|
||
this.command = command;
|
||
this.properties = properties;
|
||
this.message = message;
|
||
}
|
||
TaskCommand.prototype.toString = function () {
|
||
var cmdStr = CMD_PREFIX + this.command;
|
||
if (this.properties && Object.keys(this.properties).length > 0) {
|
||
cmdStr += ' ';
|
||
for (var key in this.properties) {
|
||
if (this.properties.hasOwnProperty(key)) {
|
||
var val = this.properties[key];
|
||
if (val) {
|
||
// safely append the val - avoid blowing up when attempting to
|
||
// call .replace() if message is not a string for some reason
|
||
cmdStr += key + '=' + escape('' + (val || '')) + ';';
|
||
}
|
||
}
|
||
}
|
||
}
|
||
cmdStr += ']';
|
||
// safely append the message - avoid blowing up when attempting to
|
||
// call .replace() if message is not a string for some reason
|
||
var message = '' + (this.message || '');
|
||
cmdStr += escapedata(message);
|
||
return cmdStr;
|
||
};
|
||
return TaskCommand;
|
||
}());
|
||
exports.TaskCommand = TaskCommand;
|
||
function commandFromString(commandLine) {
|
||
var preLen = CMD_PREFIX.length;
|
||
var lbPos = commandLine.indexOf('[');
|
||
var rbPos = commandLine.indexOf(']');
|
||
if (lbPos == -1 || rbPos == -1 || rbPos - lbPos < 3) {
|
||
throw new Error('Invalid command brackets');
|
||
}
|
||
var cmdInfo = commandLine.substring(lbPos + 1, rbPos);
|
||
var spaceIdx = cmdInfo.indexOf(' ');
|
||
var command = cmdInfo;
|
||
var properties = {};
|
||
if (spaceIdx > 0) {
|
||
command = cmdInfo.trim().substring(0, spaceIdx);
|
||
var propSection = cmdInfo.trim().substring(spaceIdx + 1);
|
||
var propLines = propSection.split(';');
|
||
propLines.forEach(function (propLine) {
|
||
propLine = propLine.trim();
|
||
if (propLine.length > 0) {
|
||
var eqIndex = propLine.indexOf('=');
|
||
if (eqIndex == -1) {
|
||
throw new Error('Invalid property: ' + propLine);
|
||
}
|
||
var key = propLine.substring(0, eqIndex);
|
||
var val = propLine.substring(eqIndex + 1);
|
||
properties[key] = unescape(val);
|
||
}
|
||
});
|
||
}
|
||
var msg = unescapedata(commandLine.substring(rbPos + 1));
|
||
var cmd = new TaskCommand(command, properties, msg);
|
||
return cmd;
|
||
}
|
||
exports.commandFromString = commandFromString;
|
||
function escapedata(s) {
|
||
return s.replace(/%/g, '%AZP25')
|
||
.replace(/\r/g, '%0D')
|
||
.replace(/\n/g, '%0A');
|
||
}
|
||
function unescapedata(s) {
|
||
return s.replace(/%0D/g, '\r')
|
||
.replace(/%0A/g, '\n')
|
||
.replace(/%AZP25/g, '%');
|
||
}
|
||
function escape(s) {
|
||
return s.replace(/%/g, '%AZP25')
|
||
.replace(/\r/g, '%0D')
|
||
.replace(/\n/g, '%0A')
|
||
.replace(/]/g, '%5D')
|
||
.replace(/;/g, '%3B');
|
||
}
|
||
function unescape(s) {
|
||
return s.replace(/%0D/g, '\r')
|
||
.replace(/%0A/g, '\n')
|
||
.replace(/%5D/g, ']')
|
||
.replace(/%3B/g, ';')
|
||
.replace(/%AZP25/g, '%');
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-task-lib/toolrunner.js":
|
||
/*!*************************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-task-lib/toolrunner.js ***!
|
||
\*************************************************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var __extends = (this && this.__extends) || (function () {
|
||
var extendStatics = function (d, b) {
|
||
extendStatics = Object.setPrototypeOf ||
|
||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||
return extendStatics(d, b);
|
||
};
|
||
return function (d, b) {
|
||
extendStatics(d, b);
|
||
function __() { this.constructor = d; }
|
||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||
};
|
||
})();
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.ToolRunner = void 0;
|
||
var Q = __webpack_require__(/*! q */ "./node_modules/q/q.js");
|
||
var os = __webpack_require__(/*! os */ "os");
|
||
var events = __webpack_require__(/*! events */ "events");
|
||
var child = __webpack_require__(/*! child_process */ "child_process");
|
||
var im = __webpack_require__(/*! ./internal */ "./node_modules/azure-pipelines-task-lib/internal.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var ToolRunner = /** @class */ (function (_super) {
|
||
__extends(ToolRunner, _super);
|
||
function ToolRunner(toolPath) {
|
||
var _this = _super.call(this) || this;
|
||
_this.cmdSpecialChars = [' ', '\t', '&', '(', ')', '[', ']', '{', '}', '^', '=', ';', '!', '\'', '+', ',', '`', '~', '|', '<', '>', '"'];
|
||
if (!toolPath) {
|
||
throw new Error('Parameter \'toolPath\' cannot be null or empty.');
|
||
}
|
||
_this.toolPath = im._which(toolPath, true);
|
||
_this.args = [];
|
||
_this._debug('toolRunner toolPath: ' + toolPath);
|
||
return _this;
|
||
}
|
||
ToolRunner.prototype._debug = function (message) {
|
||
this.emit('debug', message);
|
||
};
|
||
ToolRunner.prototype._argStringToArray = function (argString) {
|
||
var args = [];
|
||
var inQuotes = false;
|
||
var escaped = false;
|
||
var lastCharWasSpace = true;
|
||
var arg = '';
|
||
var append = function (c) {
|
||
// we only escape double quotes.
|
||
if (escaped) {
|
||
if (c !== '"') {
|
||
arg += '\\';
|
||
}
|
||
else {
|
||
arg.slice(0, -1);
|
||
}
|
||
}
|
||
arg += c;
|
||
escaped = false;
|
||
};
|
||
for (var i = 0; i < argString.length; i++) {
|
||
var c = argString.charAt(i);
|
||
if (c === ' ' && !inQuotes) {
|
||
if (!lastCharWasSpace) {
|
||
args.push(arg);
|
||
arg = '';
|
||
}
|
||
lastCharWasSpace = true;
|
||
continue;
|
||
}
|
||
else {
|
||
lastCharWasSpace = false;
|
||
}
|
||
if (c === '"') {
|
||
if (!escaped) {
|
||
inQuotes = !inQuotes;
|
||
}
|
||
else {
|
||
append(c);
|
||
}
|
||
continue;
|
||
}
|
||
if (c === "\\" && escaped) {
|
||
append(c);
|
||
continue;
|
||
}
|
||
if (c === "\\" && inQuotes) {
|
||
escaped = true;
|
||
continue;
|
||
}
|
||
append(c);
|
||
lastCharWasSpace = false;
|
||
}
|
||
if (!lastCharWasSpace) {
|
||
args.push(arg.trim());
|
||
}
|
||
return args;
|
||
};
|
||
ToolRunner.prototype._getCommandString = function (options, noPrefix) {
|
||
var _this = this;
|
||
var toolPath = this._getSpawnFileName();
|
||
var args = this._getSpawnArgs(options);
|
||
var cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool
|
||
var commandParts = [];
|
||
if (process.platform == 'win32') {
|
||
// Windows + cmd file
|
||
if (this._isCmdFile()) {
|
||
commandParts.push(toolPath);
|
||
commandParts = commandParts.concat(args);
|
||
}
|
||
// Windows + verbatim
|
||
else if (options.windowsVerbatimArguments) {
|
||
commandParts.push("\"" + toolPath + "\"");
|
||
commandParts = commandParts.concat(args);
|
||
}
|
||
else if (options.shell) {
|
||
commandParts.push(this._windowsQuoteCmdArg(toolPath));
|
||
commandParts = commandParts.concat(args);
|
||
}
|
||
// Windows (regular)
|
||
else {
|
||
commandParts.push(this._windowsQuoteCmdArg(toolPath));
|
||
commandParts = commandParts.concat(args.map(function (arg) { return _this._windowsQuoteCmdArg(arg); }));
|
||
}
|
||
}
|
||
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.
|
||
commandParts.push(toolPath);
|
||
commandParts = commandParts.concat(args);
|
||
}
|
||
cmd += commandParts.join(' ');
|
||
// append second tool
|
||
if (this.pipeOutputToTool) {
|
||
cmd += ' | ' + this.pipeOutputToTool._getCommandString(options, /*noPrefix:*/ true);
|
||
}
|
||
return cmd;
|
||
};
|
||
ToolRunner.prototype._processLineBuffer = function (data, strBuffer, onLine) {
|
||
try {
|
||
var s = strBuffer + data.toString();
|
||
var n = s.indexOf(os.EOL);
|
||
while (n > -1) {
|
||
var 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');
|
||
}
|
||
};
|
||
/**
|
||
* Wraps an arg string with specified char if it's not already wrapped
|
||
* @returns {string} Arg wrapped with specified char
|
||
* @param {string} arg Input argument string
|
||
* @param {string} wrapChar A char input string should be wrapped with
|
||
*/
|
||
ToolRunner.prototype._wrapArg = function (arg, wrapChar) {
|
||
if (!this._isWrapped(arg, wrapChar)) {
|
||
return "" + wrapChar + arg + wrapChar;
|
||
}
|
||
return arg;
|
||
};
|
||
/**
|
||
* Unwraps an arg string wrapped with specified char
|
||
* @param arg Arg wrapped with specified char
|
||
* @param wrapChar A char to be removed
|
||
*/
|
||
ToolRunner.prototype._unwrapArg = function (arg, wrapChar) {
|
||
if (this._isWrapped(arg, wrapChar)) {
|
||
var pattern = new RegExp("(^\\\\?" + wrapChar + ")|(\\\\?" + wrapChar + "$)", 'g');
|
||
return arg.trim().replace(pattern, '');
|
||
}
|
||
return arg;
|
||
};
|
||
/**
|
||
* Determine if arg string is wrapped with specified char
|
||
* @param arg Input arg string
|
||
*/
|
||
ToolRunner.prototype._isWrapped = function (arg, wrapChar) {
|
||
var pattern = new RegExp("^\\\\?" + wrapChar + ".+\\\\?" + wrapChar + "$");
|
||
return pattern.test(arg.trim());
|
||
};
|
||
ToolRunner.prototype._getSpawnFileName = function (options) {
|
||
if (process.platform == 'win32') {
|
||
if (this._isCmdFile()) {
|
||
return process.env['COMSPEC'] || 'cmd.exe';
|
||
}
|
||
}
|
||
if (options && options.shell) {
|
||
return this._wrapArg(this.toolPath, '"');
|
||
}
|
||
return this.toolPath;
|
||
};
|
||
ToolRunner.prototype._getSpawnArgs = function (options) {
|
||
var _this = this;
|
||
if (process.platform == 'win32') {
|
||
if (this._isCmdFile()) {
|
||
var argline = "/D /S /C \"" + this._windowsQuoteCmdArg(this.toolPath);
|
||
for (var i = 0; i < this.args.length; i++) {
|
||
argline += ' ';
|
||
argline += options.windowsVerbatimArguments ? this.args[i] : this._windowsQuoteCmdArg(this.args[i]);
|
||
}
|
||
argline += '"';
|
||
return [argline];
|
||
}
|
||
if (options.windowsVerbatimArguments) {
|
||
// note, in Node 6.x options.argv0 can be used instead of overriding args.slice and args.unshift.
|
||
// for more details, refer to https://github.com/nodejs/node/blob/v6.x/lib/child_process.js
|
||
var args_1 = this.args.slice(0); // copy the array
|
||
// override slice to prevent Node from creating a copy of the arg array.
|
||
// we need Node to use the "unshift" override below.
|
||
args_1.slice = function () {
|
||
if (arguments.length != 1 || arguments[0] != 0) {
|
||
throw new Error('Unexpected arguments passed to args.slice when windowsVerbatimArguments flag is set.');
|
||
}
|
||
return args_1;
|
||
};
|
||
// override unshift
|
||
//
|
||
// when using the windowsVerbatimArguments option, Node does not quote the tool path when building
|
||
// the cmdline parameter for the win32 function CreateProcess(). an unquoted space in the tool path
|
||
// causes problems for tools when attempting to parse their own command line args. tools typically
|
||
// assume their arguments begin after arg 0.
|
||
//
|
||
// by hijacking unshift, we can quote the tool path when it pushed onto the args array. Node builds
|
||
// the cmdline parameter from the args array.
|
||
//
|
||
// note, we can't simply pass a quoted tool path to Node for multiple reasons:
|
||
// 1) Node verifies the file exists (calls win32 function GetFileAttributesW) and the check returns
|
||
// false if the path is quoted.
|
||
// 2) Node passes the tool path as the application parameter to CreateProcess, which expects the
|
||
// path to be unquoted.
|
||
//
|
||
// also note, in addition to the tool path being embedded within the cmdline parameter, Node also
|
||
// passes the tool path to CreateProcess via the application parameter (optional parameter). when
|
||
// present, Windows uses the application parameter to determine which file to run, instead of
|
||
// interpreting the file from the cmdline parameter.
|
||
args_1.unshift = function () {
|
||
if (arguments.length != 1) {
|
||
throw new Error('Unexpected arguments passed to args.unshift when windowsVerbatimArguments flag is set.');
|
||
}
|
||
return Array.prototype.unshift.call(args_1, "\"" + arguments[0] + "\""); // quote the file name
|
||
};
|
||
return args_1;
|
||
}
|
||
else if (options.shell) {
|
||
var args = [];
|
||
for (var _i = 0, _a = this.args; _i < _a.length; _i++) {
|
||
var arg = _a[_i];
|
||
if (this._needQuotesForCmd(arg, '%')) {
|
||
args.push(this._wrapArg(arg, '"'));
|
||
}
|
||
else {
|
||
args.push(arg);
|
||
}
|
||
}
|
||
return args;
|
||
}
|
||
}
|
||
else if (options.shell) {
|
||
return this.args.map(function (arg) {
|
||
if (_this._isWrapped(arg, "'")) {
|
||
return arg;
|
||
}
|
||
// remove wrapping double quotes to avoid escaping
|
||
arg = _this._unwrapArg(arg, '"');
|
||
arg = _this._escapeChar(arg, '"');
|
||
return _this._wrapArg(arg, '"');
|
||
});
|
||
}
|
||
return this.args;
|
||
};
|
||
/**
|
||
* Escape specified character.
|
||
* @param arg String to escape char in
|
||
* @param charToEscape Char should be escaped
|
||
*/
|
||
ToolRunner.prototype._escapeChar = function (arg, charToEscape) {
|
||
var escChar = "\\";
|
||
var output = '';
|
||
var charIsEscaped = false;
|
||
for (var _i = 0, arg_1 = arg; _i < arg_1.length; _i++) {
|
||
var char = arg_1[_i];
|
||
if (char === charToEscape && !charIsEscaped) {
|
||
output += escChar + char;
|
||
}
|
||
else {
|
||
output += char;
|
||
}
|
||
charIsEscaped = char === escChar && !charIsEscaped;
|
||
}
|
||
return output;
|
||
};
|
||
ToolRunner.prototype._isCmdFile = function () {
|
||
var upperToolPath = this.toolPath.toUpperCase();
|
||
return im._endsWith(upperToolPath, '.CMD') || im._endsWith(upperToolPath, '.BAT');
|
||
};
|
||
/**
|
||
* Determine whether the cmd arg needs to be quoted. Returns true if arg contains any of special chars array.
|
||
* @param arg The cmd command arg.
|
||
* @param additionalChars Additional chars which should be also checked.
|
||
*/
|
||
ToolRunner.prototype._needQuotesForCmd = function (arg, additionalChars) {
|
||
var specialChars = this.cmdSpecialChars;
|
||
if (additionalChars) {
|
||
specialChars = this.cmdSpecialChars.concat(additionalChars);
|
||
}
|
||
var _loop_1 = function (char) {
|
||
if (specialChars.some(function (x) { return x === char; })) {
|
||
return { value: true };
|
||
}
|
||
};
|
||
for (var _i = 0, arg_2 = arg; _i < arg_2.length; _i++) {
|
||
var char = arg_2[_i];
|
||
var state_1 = _loop_1(char);
|
||
if (typeof state_1 === "object")
|
||
return state_1.value;
|
||
}
|
||
return false;
|
||
};
|
||
ToolRunner.prototype._windowsQuoteCmdArg = function (arg) {
|
||
// for .exe, apply the normal quoting rules that libuv applies
|
||
if (!this._isCmdFile()) {
|
||
return this._uv_quote_cmd_arg(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
|
||
var needsQuotes = this._needQuotesForCmd(arg);
|
||
// 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 preceed 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.
|
||
var reverse = '"';
|
||
var quote_hit = true;
|
||
for (var i = arg.length; i > 0; i--) { // walk the string in reverse
|
||
reverse += arg[i - 1];
|
||
if (quote_hit && arg[i - 1] == '\\') {
|
||
reverse += '\\'; // double the slash
|
||
}
|
||
else if (arg[i - 1] == '"') {
|
||
quote_hit = true;
|
||
reverse += '"'; // double the quote
|
||
}
|
||
else {
|
||
quote_hit = false;
|
||
}
|
||
}
|
||
reverse += '"';
|
||
return reverse.split('').reverse().join('');
|
||
};
|
||
ToolRunner.prototype._uv_quote_cmd_arg = function (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.indexOf(' ') < 0 && arg.indexOf('\t') < 0 && arg.indexOf('"') < 0) {
|
||
// No quotation needed
|
||
return arg;
|
||
}
|
||
if (arg.indexOf('"') < 0 && arg.indexOf('\\') < 0) {
|
||
// 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\\"
|
||
var reverse = '"';
|
||
var quote_hit = true;
|
||
for (var i = arg.length; i > 0; i--) { // walk the string in reverse
|
||
reverse += arg[i - 1];
|
||
if (quote_hit && arg[i - 1] == '\\') {
|
||
reverse += '\\';
|
||
}
|
||
else if (arg[i - 1] == '"') {
|
||
quote_hit = true;
|
||
reverse += '\\';
|
||
}
|
||
else {
|
||
quote_hit = false;
|
||
}
|
||
}
|
||
reverse += '"';
|
||
return reverse.split('').reverse().join('');
|
||
};
|
||
ToolRunner.prototype._cloneExecOptions = function (options) {
|
||
options = options || {};
|
||
var result = {
|
||
cwd: options.cwd || process.cwd(),
|
||
env: options.env || process.env,
|
||
silent: options.silent || false,
|
||
failOnStdErr: options.failOnStdErr || false,
|
||
ignoreReturnCode: options.ignoreReturnCode || false,
|
||
windowsVerbatimArguments: options.windowsVerbatimArguments || false,
|
||
shell: options.shell || false
|
||
};
|
||
result.outStream = options.outStream || process.stdout;
|
||
result.errStream = options.errStream || process.stderr;
|
||
return result;
|
||
};
|
||
ToolRunner.prototype._getSpawnOptions = function (options) {
|
||
options = options || {};
|
||
var result = {};
|
||
result.cwd = options.cwd;
|
||
result.env = options.env;
|
||
result.shell = options.shell;
|
||
result['windowsVerbatimArguments'] = options.windowsVerbatimArguments || this._isCmdFile();
|
||
return result;
|
||
};
|
||
ToolRunner.prototype._getSpawnSyncOptions = function (options) {
|
||
var result = {};
|
||
result.cwd = options.cwd;
|
||
result.env = options.env;
|
||
result.shell = options.shell;
|
||
result['windowsVerbatimArguments'] = options.windowsVerbatimArguments || this._isCmdFile();
|
||
return result;
|
||
};
|
||
ToolRunner.prototype.execWithPiping = function (pipeOutputToTool, options) {
|
||
var _this = this;
|
||
var _a, _b, _c, _d;
|
||
var defer = Q.defer();
|
||
this._debug('exec tool: ' + this.toolPath);
|
||
this._debug('arguments:');
|
||
this.args.forEach(function (arg) {
|
||
_this._debug(' ' + arg);
|
||
});
|
||
var success = true;
|
||
var optionsNonNull = this._cloneExecOptions(options);
|
||
if (!optionsNonNull.silent) {
|
||
optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL);
|
||
}
|
||
var cp;
|
||
var toolPath = pipeOutputToTool.toolPath;
|
||
var toolPathFirst;
|
||
var successFirst = true;
|
||
var returnCodeFirst;
|
||
var fileStream;
|
||
var waitingEvents = 0; // number of process or stream events we are waiting on to complete
|
||
var returnCode = 0;
|
||
var error;
|
||
toolPathFirst = this.toolPath;
|
||
// Following node documentation example from this link on how to pipe output of one process to another
|
||
// https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options
|
||
//start the child process for both tools
|
||
waitingEvents++;
|
||
var cpFirst = child.spawn(this._getSpawnFileName(optionsNonNull), this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(optionsNonNull));
|
||
waitingEvents++;
|
||
cp = child.spawn(pipeOutputToTool._getSpawnFileName(optionsNonNull), pipeOutputToTool._getSpawnArgs(optionsNonNull), pipeOutputToTool._getSpawnOptions(optionsNonNull));
|
||
fileStream = this.pipeOutputToFile ? fs.createWriteStream(this.pipeOutputToFile) : null;
|
||
if (fileStream) {
|
||
waitingEvents++;
|
||
fileStream.on('finish', function () {
|
||
waitingEvents--; //file write is complete
|
||
fileStream = null;
|
||
if (waitingEvents == 0) {
|
||
if (error) {
|
||
defer.reject(error);
|
||
}
|
||
else {
|
||
defer.resolve(returnCode);
|
||
}
|
||
}
|
||
});
|
||
fileStream.on('error', function (err) {
|
||
waitingEvents--; //there were errors writing to the file, write is done
|
||
_this._debug("Failed to pipe output of " + toolPathFirst + " to file " + _this.pipeOutputToFile + ". Error = " + err);
|
||
fileStream = null;
|
||
if (waitingEvents == 0) {
|
||
if (error) {
|
||
defer.reject(error);
|
||
}
|
||
else {
|
||
defer.resolve(returnCode);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
//pipe stdout of first tool to stdin of second tool
|
||
(_a = cpFirst.stdout) === null || _a === void 0 ? void 0 : _a.on('data', function (data) {
|
||
var _a;
|
||
try {
|
||
if (fileStream) {
|
||
fileStream.write(data);
|
||
}
|
||
(_a = cp.stdin) === null || _a === void 0 ? void 0 : _a.write(data);
|
||
}
|
||
catch (err) {
|
||
_this._debug('Failed to pipe output of ' + toolPathFirst + ' to ' + toolPath);
|
||
_this._debug(toolPath + ' might have exited due to errors prematurely. Verify the arguments passed are valid.');
|
||
}
|
||
});
|
||
(_b = cpFirst.stderr) === null || _b === void 0 ? void 0 : _b.on('data', function (data) {
|
||
if (fileStream) {
|
||
fileStream.write(data);
|
||
}
|
||
successFirst = !optionsNonNull.failOnStdErr;
|
||
if (!optionsNonNull.silent) {
|
||
var s = optionsNonNull.failOnStdErr ? optionsNonNull.errStream : optionsNonNull.outStream;
|
||
s.write(data);
|
||
}
|
||
});
|
||
cpFirst.on('error', function (err) {
|
||
var _a;
|
||
waitingEvents--; //first process is complete with errors
|
||
if (fileStream) {
|
||
fileStream.end();
|
||
}
|
||
(_a = cp.stdin) === null || _a === void 0 ? void 0 : _a.end();
|
||
error = new Error(toolPathFirst + ' failed. ' + err.message);
|
||
if (waitingEvents == 0) {
|
||
defer.reject(error);
|
||
}
|
||
});
|
||
cpFirst.on('close', function (code, signal) {
|
||
var _a;
|
||
waitingEvents--; //first process is complete
|
||
if (code != 0 && !optionsNonNull.ignoreReturnCode) {
|
||
successFirst = false;
|
||
returnCodeFirst = code;
|
||
returnCode = returnCodeFirst;
|
||
}
|
||
_this._debug('success of first tool:' + successFirst);
|
||
if (fileStream) {
|
||
fileStream.end();
|
||
}
|
||
(_a = cp.stdin) === null || _a === void 0 ? void 0 : _a.end();
|
||
if (waitingEvents == 0) {
|
||
if (error) {
|
||
defer.reject(error);
|
||
}
|
||
else {
|
||
defer.resolve(returnCode);
|
||
}
|
||
}
|
||
});
|
||
var stdbuffer = '';
|
||
(_c = cp.stdout) === null || _c === void 0 ? void 0 : _c.on('data', function (data) {
|
||
_this.emit('stdout', data);
|
||
if (!optionsNonNull.silent) {
|
||
optionsNonNull.outStream.write(data);
|
||
}
|
||
_this._processLineBuffer(data, stdbuffer, function (line) {
|
||
_this.emit('stdline', line);
|
||
});
|
||
});
|
||
var errbuffer = '';
|
||
(_d = cp.stderr) === null || _d === void 0 ? void 0 : _d.on('data', function (data) {
|
||
_this.emit('stderr', data);
|
||
success = !optionsNonNull.failOnStdErr;
|
||
if (!optionsNonNull.silent) {
|
||
var s = optionsNonNull.failOnStdErr ? optionsNonNull.errStream : optionsNonNull.outStream;
|
||
s.write(data);
|
||
}
|
||
_this._processLineBuffer(data, errbuffer, function (line) {
|
||
_this.emit('errline', line);
|
||
});
|
||
});
|
||
cp.on('error', function (err) {
|
||
waitingEvents--; //process is done with errors
|
||
error = new Error(toolPath + ' failed. ' + err.message);
|
||
if (waitingEvents == 0) {
|
||
defer.reject(error);
|
||
}
|
||
});
|
||
cp.on('close', function (code, signal) {
|
||
waitingEvents--; //process is complete
|
||
_this._debug('rc:' + code);
|
||
returnCode = code;
|
||
if (stdbuffer.length > 0) {
|
||
_this.emit('stdline', stdbuffer);
|
||
}
|
||
if (errbuffer.length > 0) {
|
||
_this.emit('errline', errbuffer);
|
||
}
|
||
if (code != 0 && !optionsNonNull.ignoreReturnCode) {
|
||
success = false;
|
||
}
|
||
_this._debug('success:' + success);
|
||
if (!successFirst) { //in the case output is piped to another tool, check exit code of both tools
|
||
error = new Error(toolPathFirst + ' failed with return code: ' + returnCodeFirst);
|
||
}
|
||
else if (!success) {
|
||
error = new Error(toolPath + ' failed with return code: ' + code);
|
||
}
|
||
if (waitingEvents == 0) {
|
||
if (error) {
|
||
defer.reject(error);
|
||
}
|
||
else {
|
||
defer.resolve(returnCode);
|
||
}
|
||
}
|
||
});
|
||
return defer.promise;
|
||
};
|
||
/**
|
||
* Add argument
|
||
* Append an argument or an array of arguments
|
||
* returns ToolRunner for chaining
|
||
*
|
||
* @param val string cmdline or array of strings
|
||
* @returns ToolRunner
|
||
*/
|
||
ToolRunner.prototype.arg = function (val) {
|
||
if (!val) {
|
||
return this;
|
||
}
|
||
if (val instanceof Array) {
|
||
this._debug(this.toolPath + ' arg: ' + JSON.stringify(val));
|
||
this.args = this.args.concat(val);
|
||
}
|
||
else if (typeof (val) === 'string') {
|
||
this._debug(this.toolPath + ' arg: ' + val);
|
||
this.args = this.args.concat(val.trim());
|
||
}
|
||
return this;
|
||
};
|
||
/**
|
||
* Parses an argument line into one or more arguments
|
||
* e.g. .line('"arg one" two -z') is equivalent to .arg(['arg one', 'two', '-z'])
|
||
* returns ToolRunner for chaining
|
||
*
|
||
* @param val string argument line
|
||
* @returns ToolRunner
|
||
*/
|
||
ToolRunner.prototype.line = function (val) {
|
||
if (!val) {
|
||
return this;
|
||
}
|
||
this._debug(this.toolPath + ' arg: ' + val);
|
||
this.args = this.args.concat(this._argStringToArray(val));
|
||
return this;
|
||
};
|
||
/**
|
||
* Add argument(s) if a condition is met
|
||
* Wraps arg(). See arg for details
|
||
* returns ToolRunner for chaining
|
||
*
|
||
* @param condition boolean condition
|
||
* @param val string cmdline or array of strings
|
||
* @returns ToolRunner
|
||
*/
|
||
ToolRunner.prototype.argIf = function (condition, val) {
|
||
if (condition) {
|
||
this.arg(val);
|
||
}
|
||
return this;
|
||
};
|
||
/**
|
||
* Pipe output of exec() to another tool
|
||
* @param tool
|
||
* @param file optional filename to additionally stream the output to.
|
||
* @returns {ToolRunner}
|
||
*/
|
||
ToolRunner.prototype.pipeExecOutputToTool = function (tool, file) {
|
||
this.pipeOutputToTool = tool;
|
||
this.pipeOutputToFile = file;
|
||
return this;
|
||
};
|
||
/**
|
||
* 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 IExecOptions
|
||
* @returns number
|
||
*/
|
||
ToolRunner.prototype.exec = function (options) {
|
||
var _this = this;
|
||
var _a, _b, _c;
|
||
if (this.pipeOutputToTool) {
|
||
return this.execWithPiping(this.pipeOutputToTool, options);
|
||
}
|
||
var defer = Q.defer();
|
||
this._debug('exec tool: ' + this.toolPath);
|
||
this._debug('arguments:');
|
||
this.args.forEach(function (arg) {
|
||
_this._debug(' ' + arg);
|
||
});
|
||
var optionsNonNull = this._cloneExecOptions(options);
|
||
if (!optionsNonNull.silent) {
|
||
optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL);
|
||
}
|
||
var state = new ExecState(optionsNonNull, this.toolPath);
|
||
state.on('debug', function (message) {
|
||
_this._debug(message);
|
||
});
|
||
var cp = child.spawn(this._getSpawnFileName(options), this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(options));
|
||
this.childProcess = cp;
|
||
// it is possible for the child process to end its last line without a new line.
|
||
// because stdout is buffered, this causes the last line to not get sent to the parent
|
||
// stream. Adding this event forces a flush before the child streams are closed.
|
||
(_a = cp.stdout) === null || _a === void 0 ? void 0 : _a.on('finish', function () {
|
||
if (!optionsNonNull.silent) {
|
||
optionsNonNull.outStream.write(os.EOL);
|
||
}
|
||
});
|
||
var stdbuffer = '';
|
||
(_b = cp.stdout) === null || _b === void 0 ? void 0 : _b.on('data', function (data) {
|
||
_this.emit('stdout', data);
|
||
if (!optionsNonNull.silent) {
|
||
optionsNonNull.outStream.write(data);
|
||
}
|
||
_this._processLineBuffer(data, stdbuffer, function (line) {
|
||
_this.emit('stdline', line);
|
||
});
|
||
});
|
||
var errbuffer = '';
|
||
(_c = cp.stderr) === null || _c === void 0 ? void 0 : _c.on('data', function (data) {
|
||
state.processStderr = true;
|
||
_this.emit('stderr', data);
|
||
if (!optionsNonNull.silent) {
|
||
var s = optionsNonNull.failOnStdErr ? optionsNonNull.errStream : optionsNonNull.outStream;
|
||
s.write(data);
|
||
}
|
||
_this._processLineBuffer(data, errbuffer, function (line) {
|
||
_this.emit('errline', line);
|
||
});
|
||
});
|
||
cp.on('error', function (err) {
|
||
state.processError = err.message;
|
||
state.processExited = true;
|
||
state.processClosed = true;
|
||
state.CheckComplete();
|
||
});
|
||
cp.on('exit', function (code, signal) {
|
||
state.processExitCode = code;
|
||
state.processExited = true;
|
||
_this._debug("Exit code " + code + " received from tool '" + _this.toolPath + "'");
|
||
state.CheckComplete();
|
||
});
|
||
cp.on('close', function (code, signal) {
|
||
state.processExitCode = code;
|
||
state.processExited = true;
|
||
state.processClosed = true;
|
||
_this._debug("STDIO streams have closed for tool '" + _this.toolPath + "'");
|
||
state.CheckComplete();
|
||
});
|
||
state.on('done', function (error, exitCode) {
|
||
if (stdbuffer.length > 0) {
|
||
_this.emit('stdline', stdbuffer);
|
||
}
|
||
if (errbuffer.length > 0) {
|
||
_this.emit('errline', errbuffer);
|
||
}
|
||
cp.removeAllListeners();
|
||
if (error) {
|
||
defer.reject(error);
|
||
}
|
||
else {
|
||
defer.resolve(exitCode);
|
||
}
|
||
});
|
||
return defer.promise;
|
||
};
|
||
/**
|
||
* Exec a tool synchronously.
|
||
* Output will be *not* be streamed to the live console. It will be returned after execution is complete.
|
||
* Appropriate for short running tools
|
||
* Returns IExecSyncResult with output and return code
|
||
*
|
||
* @param tool path to tool to exec
|
||
* @param options optional exec options. See IExecSyncOptions
|
||
* @returns IExecSyncResult
|
||
*/
|
||
ToolRunner.prototype.execSync = function (options) {
|
||
var _this = this;
|
||
this._debug('exec tool: ' + this.toolPath);
|
||
this._debug('arguments:');
|
||
this.args.forEach(function (arg) {
|
||
_this._debug(' ' + arg);
|
||
});
|
||
var success = true;
|
||
options = this._cloneExecOptions(options);
|
||
if (!options.silent) {
|
||
options.outStream.write(this._getCommandString(options) + os.EOL);
|
||
}
|
||
var r = child.spawnSync(this._getSpawnFileName(options), this._getSpawnArgs(options), this._getSpawnSyncOptions(options));
|
||
if (!options.silent && r.stdout && r.stdout.length > 0) {
|
||
options.outStream.write(r.stdout);
|
||
}
|
||
if (!options.silent && r.stderr && r.stderr.length > 0) {
|
||
options.errStream.write(r.stderr);
|
||
}
|
||
var res = { code: r.status, error: r.error };
|
||
res.stdout = (r.stdout) ? r.stdout.toString() : '';
|
||
res.stderr = (r.stderr) ? r.stderr.toString() : '';
|
||
return res;
|
||
};
|
||
/**
|
||
* Used to close child process by sending SIGNINT signal.
|
||
* It allows executed script to have some additional logic on SIGINT, before exiting.
|
||
*/
|
||
ToolRunner.prototype.killChildProcess = function () {
|
||
if (this.childProcess) {
|
||
this.childProcess.kill();
|
||
}
|
||
};
|
||
return ToolRunner;
|
||
}(events.EventEmitter));
|
||
exports.ToolRunner = ToolRunner;
|
||
var ExecState = /** @class */ (function (_super) {
|
||
__extends(ExecState, _super);
|
||
function ExecState(options, toolPath) {
|
||
var _this = _super.call(this) || this;
|
||
_this.delay = 10000; // 10 seconds
|
||
_this.timeout = null;
|
||
if (!toolPath) {
|
||
throw new Error('toolPath must not be empty');
|
||
}
|
||
_this.options = options;
|
||
_this.toolPath = toolPath;
|
||
var delay = process.env['TASKLIB_TEST_TOOLRUNNER_EXITDELAY'];
|
||
if (delay) {
|
||
_this.delay = parseInt(delay);
|
||
}
|
||
return _this;
|
||
}
|
||
ExecState.prototype.CheckComplete = function () {
|
||
if (this.done) {
|
||
return;
|
||
}
|
||
if (this.processClosed) {
|
||
this._setResult();
|
||
}
|
||
else if (this.processExited) {
|
||
this.timeout = setTimeout(ExecState.HandleTimeout, this.delay, this);
|
||
}
|
||
};
|
||
ExecState.prototype._debug = function (message) {
|
||
this.emit('debug', message);
|
||
};
|
||
ExecState.prototype._setResult = function () {
|
||
// determine whether there is an error
|
||
var error;
|
||
if (this.processExited) {
|
||
if (this.processError) {
|
||
error = new Error(im._loc('LIB_ProcessError', this.toolPath, this.processError));
|
||
}
|
||
else if (this.processExitCode != 0 && !this.options.ignoreReturnCode) {
|
||
error = new Error(im._loc('LIB_ProcessExitCode', this.toolPath, this.processExitCode));
|
||
}
|
||
else if (this.processStderr && this.options.failOnStdErr) {
|
||
error = new Error(im._loc('LIB_ProcessStderr', this.toolPath));
|
||
}
|
||
}
|
||
// clear the timeout
|
||
if (this.timeout) {
|
||
clearTimeout(this.timeout);
|
||
this.timeout = null;
|
||
}
|
||
this.done = true;
|
||
this.emit('done', error, this.processExitCode);
|
||
};
|
||
ExecState.HandleTimeout = function (state) {
|
||
if (state.done) {
|
||
return;
|
||
}
|
||
if (!state.processClosed && state.processExited) {
|
||
console.log(im._loc('LIB_StdioNotClosed', state.delay / 1000, state.toolPath));
|
||
state._debug(im._loc('LIB_StdioNotClosed', state.delay / 1000, state.toolPath));
|
||
}
|
||
state._setResult();
|
||
};
|
||
return ExecState;
|
||
}(events.EventEmitter));
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-task-lib/vault.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-task-lib/vault.js ***!
|
||
\********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Vault = void 0;
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var crypto = __webpack_require__(/*! crypto */ "crypto");
|
||
var uuidV4 = __webpack_require__(/*! uuid/v4 */ "./node_modules/azure-pipelines-task-lib/node_modules/uuid/v4.js");
|
||
var algorithm = "aes-256-ctr";
|
||
var encryptEncoding = 'hex';
|
||
var unencryptedEncoding = 'utf8';
|
||
//
|
||
// Store sensitive data in proc.
|
||
// Main goal: Protects tasks which would dump envvars from leaking secrets inadvertently
|
||
// the task lib clears after storing.
|
||
// Also protects against a dump of a process getting the secrets
|
||
// The secret is generated and stored externally for the lifetime of the task.
|
||
//
|
||
var Vault = /** @class */ (function () {
|
||
function Vault(keyPath) {
|
||
this._keyFile = path.join(keyPath, '.taskkey');
|
||
this._store = {};
|
||
this.genKey();
|
||
}
|
||
Vault.prototype.initialize = function () {
|
||
};
|
||
Vault.prototype.storeSecret = function (name, data) {
|
||
if (!name || name.length == 0) {
|
||
return false;
|
||
}
|
||
name = name.toLowerCase();
|
||
if (!data || data.length == 0) {
|
||
if (this._store.hasOwnProperty(name)) {
|
||
delete this._store[name];
|
||
}
|
||
return false;
|
||
}
|
||
var key = this.getKey();
|
||
var iv = crypto.randomBytes(16);
|
||
var cipher = crypto.createCipheriv(algorithm, key, iv);
|
||
var crypted = cipher.update(data, unencryptedEncoding, encryptEncoding);
|
||
var cryptedFinal = cipher.final(encryptEncoding);
|
||
this._store[name] = iv.toString(encryptEncoding) + crypted + cryptedFinal;
|
||
return true;
|
||
};
|
||
Vault.prototype.retrieveSecret = function (name) {
|
||
var secret;
|
||
name = (name || '').toLowerCase();
|
||
if (this._store.hasOwnProperty(name)) {
|
||
var key = this.getKey();
|
||
var data = this._store[name];
|
||
var ivDataBuffer = Buffer.from(data, encryptEncoding);
|
||
var iv = ivDataBuffer.slice(0, 16);
|
||
var encryptedText = ivDataBuffer.slice(16);
|
||
var decipher = crypto.createDecipheriv(algorithm, key, iv);
|
||
var dec = decipher.update(encryptedText, encryptEncoding, unencryptedEncoding);
|
||
var decFinal = decipher.final(unencryptedEncoding);
|
||
secret = dec + decFinal;
|
||
}
|
||
return secret;
|
||
};
|
||
Vault.prototype.getKey = function () {
|
||
var key = fs.readFileSync(this._keyFile).toString('utf8');
|
||
// Key needs to be hashed to correct length to match algorithm (aes-256-ctr)
|
||
return crypto.createHash('sha256').update(key).digest();
|
||
};
|
||
Vault.prototype.genKey = function () {
|
||
fs.writeFileSync(this._keyFile, uuidV4(), { encoding: 'utf8' });
|
||
};
|
||
return Vault;
|
||
}());
|
||
exports.Vault = Vault;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-task-lib sync recursive":
|
||
/*!*****************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-task-lib/ sync ***!
|
||
\*****************************************************/
|
||
/***/ ((module) => {
|
||
|
||
function webpackEmptyContext(req) {
|
||
var e = new Error("Cannot find module '" + req + "'");
|
||
e.code = 'MODULE_NOT_FOUND';
|
||
throw e;
|
||
}
|
||
webpackEmptyContext.keys = () => ([]);
|
||
webpackEmptyContext.resolve = webpackEmptyContext;
|
||
webpackEmptyContext.id = "./node_modules/azure-pipelines-task-lib sync recursive";
|
||
module.exports = webpackEmptyContext;
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-tool-lib/node_modules/uuid/lib/bytesToUuid.js":
|
||
/*!************************************************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-tool-lib/node_modules/uuid/lib/bytesToUuid.js ***!
|
||
\************************************************************************************/
|
||
/***/ ((module) => {
|
||
|
||
/**
|
||
* 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/azure-pipelines-tool-lib/node_modules/uuid/lib/rng.js":
|
||
/*!****************************************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-tool-lib/node_modules/uuid/lib/rng.js ***!
|
||
\****************************************************************************/
|
||
/***/ ((module, __unused_webpack_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/azure-pipelines-tool-lib/node_modules/uuid/v4.js":
|
||
/*!***********************************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-tool-lib/node_modules/uuid/v4.js ***!
|
||
\***********************************************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var rng = __webpack_require__(/*! ./lib/rng */ "./node_modules/azure-pipelines-tool-lib/node_modules/uuid/lib/rng.js");
|
||
var bytesToUuid = __webpack_require__(/*! ./lib/bytesToUuid */ "./node_modules/azure-pipelines-tool-lib/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;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-tool-lib/tool.js":
|
||
/*!*******************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-tool-lib/tool.js ***!
|
||
\*******************************************************/
|
||
/***/ (function(__unused_webpack_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 }));
|
||
exports.scrape = exports.extractZip = exports.extractTar = exports.extract7z = exports.cacheFile = exports.cacheDir = exports.downloadTool = exports.findLocalToolVersions = exports.findLocalTool = exports.evaluateVersions = exports.cleanVersion = exports.isExplicitVersion = exports.prependPath = exports.debug = void 0;
|
||
const httpm = __webpack_require__(/*! typed-rest-client/HttpClient */ "./node_modules/typed-rest-client/HttpClient.js");
|
||
const path = __webpack_require__(/*! path */ "path");
|
||
const os = __webpack_require__(/*! os */ "os");
|
||
const process = __webpack_require__(/*! process */ "process");
|
||
const fs = __webpack_require__(/*! fs */ "fs");
|
||
const semver = __webpack_require__(/*! semver */ "./node_modules/semver/semver.js");
|
||
const tl = __webpack_require__(/*! azure-pipelines-task-lib/task */ "./node_modules/azure-pipelines-task-lib/task.js");
|
||
const cmp = __webpack_require__(/*! semver-compare */ "./node_modules/semver-compare/index.js");
|
||
const uuidV4 = __webpack_require__(/*! uuid/v4 */ "./node_modules/azure-pipelines-tool-lib/node_modules/uuid/v4.js");
|
||
let pkg = { version: "1.2.3" };
|
||
let userAgent = 'vsts-task-installer/' + pkg.version;
|
||
let requestOptions = {
|
||
// ignoreSslError: true,
|
||
proxy: tl.getHttpProxyConfiguration(),
|
||
cert: tl.getHttpCertConfiguration(),
|
||
allowRedirects: true,
|
||
allowRetries: true,
|
||
maxRetries: 2
|
||
};
|
||
tl.setResourcePath(path.join(__dirname, 'lib.json'));
|
||
function debug(message) {
|
||
tl.debug(message);
|
||
}
|
||
exports.debug = debug;
|
||
function prependPath(toolPath) {
|
||
tl.assertAgent('2.115.0');
|
||
if (!toolPath) {
|
||
throw new Error('Parameter toolPath must not be null or empty');
|
||
}
|
||
else if (!tl.exist(toolPath) || !tl.stats(toolPath).isDirectory()) {
|
||
throw new Error('Directory does not exist: ' + toolPath);
|
||
}
|
||
// todo: add a test for path
|
||
console.log(tl.loc('TOOL_LIB_PrependPath', toolPath));
|
||
let newPath = toolPath + path.delimiter + process.env['PATH'];
|
||
tl.debug('new Path: ' + newPath);
|
||
process.env['PATH'] = newPath;
|
||
// instruct the agent to set this path on future tasks
|
||
console.log('##vso[task.prependpath]' + toolPath);
|
||
}
|
||
exports.prependPath = prependPath;
|
||
function delay(ms) {
|
||
return new Promise(resolve => setTimeout(resolve, ms));
|
||
}
|
||
//-----------------------------
|
||
// Version Functions
|
||
//-----------------------------
|
||
/**
|
||
* Checks if a version spec is an explicit version (e.g. 1.0.1 or v1.0.1)
|
||
* As opposed to a version spec like 1.x
|
||
*
|
||
* @param versionSpec
|
||
*/
|
||
function isExplicitVersion(versionSpec) {
|
||
let c = semver.clean(versionSpec);
|
||
tl.debug('isExplicit: ' + c);
|
||
let valid = semver.valid(c) != null;
|
||
tl.debug('explicit? ' + valid);
|
||
return valid;
|
||
}
|
||
exports.isExplicitVersion = isExplicitVersion;
|
||
/**
|
||
* Returns cleaned (removed leading/trailing whitespace, remove '=v' prefix)
|
||
* and parsed version, or null if version is invalid.
|
||
*/
|
||
function cleanVersion(version) {
|
||
tl.debug('cleaning: ' + version);
|
||
return semver.clean(version);
|
||
}
|
||
exports.cleanVersion = cleanVersion;
|
||
/**
|
||
* evaluates a list of versions and returns the latest version matching the version spec
|
||
*
|
||
* @param versions an array of versions to evaluate
|
||
* @param versionSpec a version spec (e.g. 1.x)
|
||
*/
|
||
function evaluateVersions(versions, versionSpec) {
|
||
let version;
|
||
tl.debug('evaluating ' + versions.length + ' versions');
|
||
versions = versions.sort(cmp);
|
||
for (let i = versions.length - 1; i >= 0; i--) {
|
||
let potential = versions[i];
|
||
let satisfied = semver.satisfies(potential, versionSpec);
|
||
if (satisfied) {
|
||
version = potential;
|
||
break;
|
||
}
|
||
}
|
||
if (version) {
|
||
tl.debug('matched: ' + version);
|
||
}
|
||
else {
|
||
tl.debug('match not found');
|
||
}
|
||
return version;
|
||
}
|
||
exports.evaluateVersions = evaluateVersions;
|
||
//-----------------------------
|
||
// Local Tool Cache Functions
|
||
//-----------------------------
|
||
/**
|
||
* finds the path to a tool 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 findLocalTool(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)) {
|
||
let localVersions = findLocalToolVersions(toolName, arch);
|
||
let match = evaluateVersions(localVersions, versionSpec);
|
||
versionSpec = match;
|
||
}
|
||
// check for the explicit version in the cache
|
||
let toolPath;
|
||
if (versionSpec) {
|
||
versionSpec = semver.clean(versionSpec);
|
||
let cacheRoot = _getCacheRoot();
|
||
let cachePath = path.join(cacheRoot, toolName, versionSpec, arch);
|
||
tl.debug('checking cache: ' + cachePath);
|
||
if (tl.exist(cachePath) && tl.exist(`${cachePath}.complete`)) {
|
||
console.log(tl.loc('TOOL_LIB_FoundInCache', toolName, versionSpec, arch));
|
||
toolPath = cachePath;
|
||
}
|
||
else {
|
||
tl.debug('not found');
|
||
}
|
||
}
|
||
return toolPath;
|
||
}
|
||
exports.findLocalTool = findLocalTool;
|
||
/**
|
||
* Retrieves the versions of a tool that is intalled in the local tool cache
|
||
*
|
||
* @param toolName name of the tool
|
||
* @param arch optional arch. defaults to arch of computer
|
||
*/
|
||
function findLocalToolVersions(toolName, arch) {
|
||
let versions = [];
|
||
arch = arch || os.arch();
|
||
let toolPath = path.join(_getCacheRoot(), toolName);
|
||
if (tl.exist(toolPath)) {
|
||
let children = tl.ls('', [toolPath]);
|
||
children.forEach((child) => {
|
||
if (isExplicitVersion(child)) {
|
||
let fullPath = path.join(toolPath, child, arch);
|
||
if (tl.exist(fullPath) && tl.exist(`${fullPath}.complete`)) {
|
||
versions.push(child);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
return versions;
|
||
}
|
||
exports.findLocalToolVersions = findLocalToolVersions;
|
||
//---------------------
|
||
// Download Functions
|
||
//---------------------
|
||
//
|
||
// TODO: keep extension intact
|
||
//
|
||
/**
|
||
* Download a tool from an url and stream it into a file
|
||
*
|
||
* @param url url of tool to download
|
||
* @param fileName optional fileName. Should typically not use (will be a guid for reliability). Can pass fileName with an absolute path.
|
||
* @param handlers optional handlers array. Auth handlers to pass to the HttpClient for the tool download.
|
||
*/
|
||
function downloadTool(url, fileName, handlers) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
||
try {
|
||
handlers = handlers || null;
|
||
let http = new httpm.HttpClient(userAgent, handlers, requestOptions);
|
||
tl.debug(fileName);
|
||
fileName = fileName || uuidV4();
|
||
// check if it's an absolute path already
|
||
var destPath;
|
||
if (path.isAbsolute(fileName)) {
|
||
destPath = fileName;
|
||
}
|
||
else {
|
||
destPath = path.join(_getAgentTemp(), fileName);
|
||
}
|
||
// make sure that the folder exists
|
||
tl.mkdirP(path.dirname(destPath));
|
||
console.log(tl.loc('TOOL_LIB_Downloading', url));
|
||
tl.debug('destination ' + destPath);
|
||
if (fs.existsSync(destPath)) {
|
||
throw new Error("Destination file path already exists");
|
||
}
|
||
tl.debug('downloading');
|
||
let response = yield http.get(url);
|
||
if (response.message.statusCode != 200) {
|
||
let err = new Error('Unexpected HTTP response: ' + response.message.statusCode);
|
||
err['httpStatusCode'] = response.message.statusCode;
|
||
tl.debug(`Failed to download "${fileName}" from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`);
|
||
throw err;
|
||
}
|
||
tl.debug('creating stream');
|
||
let file = fs.createWriteStream(destPath);
|
||
file.on('open', (fd) => __awaiter(this, void 0, void 0, function* () {
|
||
try {
|
||
let stream = response.message.pipe(file);
|
||
stream.on('close', () => {
|
||
tl.debug('download complete');
|
||
resolve(destPath);
|
||
});
|
||
}
|
||
catch (err) {
|
||
reject(err);
|
||
}
|
||
}));
|
||
file.on('error', (err) => {
|
||
file.end();
|
||
reject(err);
|
||
});
|
||
}
|
||
catch (error) {
|
||
reject(error);
|
||
}
|
||
}));
|
||
});
|
||
}
|
||
exports.downloadTool = downloadTool;
|
||
//---------------------
|
||
// Install Functions
|
||
//---------------------
|
||
function _createToolPath(tool, version, arch) {
|
||
// todo: add test for clean
|
||
let folderPath = path.join(_getCacheRoot(), tool, semver.clean(version), arch);
|
||
tl.debug('destination ' + folderPath);
|
||
let markerPath = `${folderPath}.complete`;
|
||
tl.rmRF(folderPath);
|
||
tl.rmRF(markerPath);
|
||
tl.mkdirP(folderPath);
|
||
return folderPath;
|
||
}
|
||
function _completeToolPath(tool, version, arch) {
|
||
let folderPath = path.join(_getCacheRoot(), tool, semver.clean(version), arch);
|
||
let markerPath = `${folderPath}.complete`;
|
||
tl.writeFile(markerPath, '');
|
||
tl.debug('finished caching tool');
|
||
}
|
||
/**
|
||
* 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);
|
||
arch = arch || os.arch();
|
||
console.log(tl.loc('TOOL_LIB_CachingTool', tool, version, arch));
|
||
tl.debug('source dir: ' + sourceDir);
|
||
if (!tl.stats(sourceDir).isDirectory()) {
|
||
throw new Error('sourceDir is not a directory');
|
||
}
|
||
// create the tool dir
|
||
let destPath = _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 (let itemName of fs.readdirSync(sourceDir)) {
|
||
let s = path.join(sourceDir, itemName);
|
||
tl.cp(s, destPath + '/', '-r');
|
||
}
|
||
// 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);
|
||
arch = arch || os.arch();
|
||
console.log(tl.loc('TOOL_LIB_CachingTool', tool, version, arch));
|
||
tl.debug('source file:' + sourceFile);
|
||
if (!tl.stats(sourceFile).isFile()) {
|
||
throw new Error('sourceFile is not a file');
|
||
}
|
||
// create the tool dir
|
||
let destFolder = _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.
|
||
let destPath = path.join(destFolder, targetFile);
|
||
tl.debug('destination file' + destPath);
|
||
tl.cp(sourceFile, destPath);
|
||
// write .complete
|
||
_completeToolPath(tool, version, arch);
|
||
return destFolder;
|
||
});
|
||
}
|
||
exports.cacheFile = cacheFile;
|
||
//---------------------
|
||
// Extract Functions
|
||
//---------------------
|
||
/**
|
||
* 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 task, 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* () {
|
||
if (process.platform != 'win32') {
|
||
throw new Error('extract7z() not supported on current OS');
|
||
}
|
||
if (!file) {
|
||
throw new Error("parameter 'file' is required");
|
||
}
|
||
console.log(tl.loc('TOOL_LIB_ExtractingArchive'));
|
||
dest = _createExtractFolder(dest);
|
||
let originalCwd = process.cwd();
|
||
try {
|
||
process.chdir(dest);
|
||
if (_7zPath) {
|
||
// extract
|
||
let _7z = tl.tool(_7zPath)
|
||
.arg('x') // eXtract files with full paths
|
||
.arg('-bb1') // -bb[0-3] : set output log level
|
||
.arg('-bd') // disable progress indicator
|
||
.arg('-sccUTF-8') // set charset for for console input/output
|
||
.arg(file);
|
||
yield _7z.exec();
|
||
}
|
||
else {
|
||
// extract
|
||
let escapedScript = path.join(__dirname, 'Invoke-7zdec.ps1').replace(/'/g, "''").replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines
|
||
let escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, '');
|
||
let escapedTarget = dest.replace(/'/g, "''").replace(/"|\n|\r/g, '');
|
||
let command = `& '${escapedScript}' -Source '${escapedFile}' -Target '${escapedTarget}'`;
|
||
let powershellPath = tl.which('powershell', true);
|
||
let powershell = tl.tool(powershellPath)
|
||
.line('-NoLogo -Sta -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command')
|
||
.arg(command);
|
||
powershell.on('stdout', (buffer) => {
|
||
process.stdout.write(buffer);
|
||
});
|
||
powershell.on('stderr', (buffer) => {
|
||
process.stderr.write(buffer);
|
||
});
|
||
yield powershell.exec({ silent: true });
|
||
}
|
||
}
|
||
finally {
|
||
process.chdir(originalCwd);
|
||
}
|
||
return dest;
|
||
});
|
||
}
|
||
exports.extract7z = extract7z;
|
||
/**
|
||
* installs a tool from a tar by extracting the tar and installing it into the tool cache
|
||
*
|
||
* @param file file path of the tar
|
||
* @param tool name of tool in the tool cache
|
||
* @param version version of the tool
|
||
* @param arch arch of the tool. optional. defaults to the arch of the machine
|
||
* @param options IExtractOptions
|
||
* @param destination destination directory. optional.
|
||
*/
|
||
function extractTar(file, destination) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
// mkdir -p node/4.7.0/x64
|
||
// tar xzC ./node/4.7.0/x64 -f node-v4.7.0-darwin-x64.tar.gz --strip-components 1
|
||
console.log(tl.loc('TOOL_LIB_ExtractingArchive'));
|
||
let dest = _createExtractFolder(destination);
|
||
let tr = tl.tool('tar');
|
||
tr.arg(['xC', dest, '-f', file]);
|
||
yield tr.exec();
|
||
return dest;
|
||
});
|
||
}
|
||
exports.extractTar = extractTar;
|
||
function extractZip(file, destination) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
if (!file) {
|
||
throw new Error("parameter 'file' is required");
|
||
}
|
||
console.log(tl.loc('TOOL_LIB_ExtractingArchive'));
|
||
let dest = _createExtractFolder(destination);
|
||
if (process.platform == 'win32') {
|
||
// build the powershell command
|
||
let escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines
|
||
let escapedDest = dest.replace(/'/g, "''").replace(/"|\n|\r/g, '');
|
||
let command = `$ErrorActionPreference = 'Stop' ; try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}')`;
|
||
// change the console output code page to UTF-8.
|
||
// TODO: FIX WHICH: let chcpPath = tl.which('chcp.com', true);
|
||
let chcpPath = path.join(process.env.windir, "system32", "chcp.com");
|
||
yield tl.exec(chcpPath, '65001');
|
||
// run powershell
|
||
let powershell = tl.tool('powershell')
|
||
.line('-NoLogo -Sta -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command')
|
||
.arg(command);
|
||
yield powershell.exec();
|
||
}
|
||
else {
|
||
let unzip = tl.tool('unzip')
|
||
.arg(file);
|
||
yield unzip.exec({ cwd: dest });
|
||
}
|
||
return dest;
|
||
});
|
||
}
|
||
exports.extractZip = extractZip;
|
||
function _createExtractFolder(dest) {
|
||
if (!dest) {
|
||
// create a temp dir
|
||
dest = path.join(_getAgentTemp(), uuidV4());
|
||
}
|
||
tl.mkdirP(dest);
|
||
return dest;
|
||
}
|
||
//---------------------
|
||
// Query Functions
|
||
//---------------------
|
||
// default input will be >= LTS version. drop label different than value.
|
||
// v4 (LTS) would have a value of 4.x
|
||
// option to always download? (not cache), TTL?
|
||
/**
|
||
* Scrape a web page for versions by regex
|
||
*
|
||
* @param url url to scrape
|
||
* @param regex regex to use for version matches
|
||
* @param handlers optional handlers array. Auth handlers to pass to the HttpClient for the tool download.
|
||
*/
|
||
function scrape(url, regex, handlers) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
handlers = handlers || null;
|
||
let http = new httpm.HttpClient(userAgent, handlers, requestOptions);
|
||
let output = yield (yield http.get(url)).readBody();
|
||
let matches = output.match(regex);
|
||
let seen = {};
|
||
let versions = [];
|
||
for (let i = 0; i < matches.length; i++) {
|
||
let ver = semver.clean(matches[i]);
|
||
if (!seen.hasOwnProperty(ver)) {
|
||
seen[ver] = true;
|
||
versions.push(ver);
|
||
}
|
||
}
|
||
return versions;
|
||
});
|
||
}
|
||
exports.scrape = scrape;
|
||
function _getCacheRoot() {
|
||
tl.assertAgent('2.115.0');
|
||
let cacheRoot = tl.getVariable('Agent.ToolsDirectory');
|
||
if (!cacheRoot) {
|
||
throw new Error('Agent.ToolsDirectory is not set');
|
||
}
|
||
return cacheRoot;
|
||
}
|
||
function _getAgentTemp() {
|
||
tl.assertAgent('2.115.0');
|
||
let tempDirectory = tl.getVariable('Agent.TempDirectory');
|
||
if (!tempDirectory) {
|
||
throw new Error('Agent.TempDirectory is not set');
|
||
}
|
||
return tempDirectory;
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-tool-lib sync recursive":
|
||
/*!*****************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-tool-lib/ sync ***!
|
||
\*****************************************************/
|
||
/***/ ((module) => {
|
||
|
||
function webpackEmptyContext(req) {
|
||
var e = new Error("Cannot find module '" + req + "'");
|
||
e.code = 'MODULE_NOT_FOUND';
|
||
throw e;
|
||
}
|
||
webpackEmptyContext.keys = () => ([]);
|
||
webpackEmptyContext.resolve = webpackEmptyContext;
|
||
webpackEmptyContext.id = "./node_modules/azure-pipelines-tool-lib sync recursive";
|
||
module.exports = webpackEmptyContext;
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/balanced-match/index.js":
|
||
/*!**********************************************!*\
|
||
!*** ./node_modules/balanced-match/index.js ***!
|
||
\**********************************************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
|
||
module.exports = balanced;
|
||
function balanced(a, b, str) {
|
||
if (a instanceof RegExp) a = maybeMatch(a, str);
|
||
if (b instanceof RegExp) b = maybeMatch(b, str);
|
||
|
||
var r = range(a, b, str);
|
||
|
||
return r && {
|
||
start: r[0],
|
||
end: r[1],
|
||
pre: str.slice(0, r[0]),
|
||
body: str.slice(r[0] + a.length, r[1]),
|
||
post: str.slice(r[1] + b.length)
|
||
};
|
||
}
|
||
|
||
function maybeMatch(reg, str) {
|
||
var m = str.match(reg);
|
||
return m ? m[0] : null;
|
||
}
|
||
|
||
balanced.range = range;
|
||
function range(a, b, str) {
|
||
var begs, beg, left, right, result;
|
||
var ai = str.indexOf(a);
|
||
var bi = str.indexOf(b, ai + 1);
|
||
var i = ai;
|
||
|
||
if (ai >= 0 && bi > 0) {
|
||
begs = [];
|
||
left = str.length;
|
||
|
||
while (i >= 0 && !result) {
|
||
if (i == ai) {
|
||
begs.push(i);
|
||
ai = str.indexOf(a, i + 1);
|
||
} else if (begs.length == 1) {
|
||
result = [ begs.pop(), bi ];
|
||
} else {
|
||
beg = begs.pop();
|
||
if (beg < left) {
|
||
left = beg;
|
||
right = bi;
|
||
}
|
||
|
||
bi = str.indexOf(b, i + 1);
|
||
}
|
||
|
||
i = ai < bi && ai >= 0 ? ai : bi;
|
||
}
|
||
|
||
if (begs.length) {
|
||
result = [ left, right ];
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/brace-expansion/index.js":
|
||
/*!***********************************************!*\
|
||
!*** ./node_modules/brace-expansion/index.js ***!
|
||
\***********************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var concatMap = __webpack_require__(/*! concat-map */ "./node_modules/concat-map/index.js");
|
||
var balanced = __webpack_require__(/*! balanced-match */ "./node_modules/balanced-match/index.js");
|
||
|
||
module.exports = expandTop;
|
||
|
||
var escSlash = '\0SLASH'+Math.random()+'\0';
|
||
var escOpen = '\0OPEN'+Math.random()+'\0';
|
||
var escClose = '\0CLOSE'+Math.random()+'\0';
|
||
var escComma = '\0COMMA'+Math.random()+'\0';
|
||
var escPeriod = '\0PERIOD'+Math.random()+'\0';
|
||
|
||
function numeric(str) {
|
||
return parseInt(str, 10) == str
|
||
? parseInt(str, 10)
|
||
: str.charCodeAt(0);
|
||
}
|
||
|
||
function escapeBraces(str) {
|
||
return str.split('\\\\').join(escSlash)
|
||
.split('\\{').join(escOpen)
|
||
.split('\\}').join(escClose)
|
||
.split('\\,').join(escComma)
|
||
.split('\\.').join(escPeriod);
|
||
}
|
||
|
||
function unescapeBraces(str) {
|
||
return str.split(escSlash).join('\\')
|
||
.split(escOpen).join('{')
|
||
.split(escClose).join('}')
|
||
.split(escComma).join(',')
|
||
.split(escPeriod).join('.');
|
||
}
|
||
|
||
|
||
// Basically just str.split(","), but handling cases
|
||
// where we have nested braced sections, which should be
|
||
// treated as individual members, like {a,{b,c},d}
|
||
function parseCommaParts(str) {
|
||
if (!str)
|
||
return [''];
|
||
|
||
var parts = [];
|
||
var m = balanced('{', '}', str);
|
||
|
||
if (!m)
|
||
return str.split(',');
|
||
|
||
var pre = m.pre;
|
||
var body = m.body;
|
||
var post = m.post;
|
||
var p = pre.split(',');
|
||
|
||
p[p.length-1] += '{' + body + '}';
|
||
var postParts = parseCommaParts(post);
|
||
if (post.length) {
|
||
p[p.length-1] += postParts.shift();
|
||
p.push.apply(p, postParts);
|
||
}
|
||
|
||
parts.push.apply(parts, p);
|
||
|
||
return parts;
|
||
}
|
||
|
||
function expandTop(str) {
|
||
if (!str)
|
||
return [];
|
||
|
||
// I don't know why Bash 4.3 does this, but it does.
|
||
// Anything starting with {} will have the first two bytes preserved
|
||
// but *only* at the top level, so {},a}b will not expand to anything,
|
||
// but a{},b}c will be expanded to [a}c,abc].
|
||
// One could argue that this is a bug in Bash, but since the goal of
|
||
// this module is to match Bash's rules, we escape a leading {}
|
||
if (str.substr(0, 2) === '{}') {
|
||
str = '\\{\\}' + str.substr(2);
|
||
}
|
||
|
||
return expand(escapeBraces(str), true).map(unescapeBraces);
|
||
}
|
||
|
||
function identity(e) {
|
||
return e;
|
||
}
|
||
|
||
function embrace(str) {
|
||
return '{' + str + '}';
|
||
}
|
||
function isPadded(el) {
|
||
return /^-?0\d/.test(el);
|
||
}
|
||
|
||
function lte(i, y) {
|
||
return i <= y;
|
||
}
|
||
function gte(i, y) {
|
||
return i >= y;
|
||
}
|
||
|
||
function expand(str, isTop) {
|
||
var expansions = [];
|
||
|
||
var m = balanced('{', '}', str);
|
||
if (!m || /\$$/.test(m.pre)) return [str];
|
||
|
||
var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
|
||
var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
|
||
var isSequence = isNumericSequence || isAlphaSequence;
|
||
var isOptions = m.body.indexOf(',') >= 0;
|
||
if (!isSequence && !isOptions) {
|
||
// {a},b}
|
||
if (m.post.match(/,.*\}/)) {
|
||
str = m.pre + '{' + m.body + escClose + m.post;
|
||
return expand(str);
|
||
}
|
||
return [str];
|
||
}
|
||
|
||
var n;
|
||
if (isSequence) {
|
||
n = m.body.split(/\.\./);
|
||
} else {
|
||
n = parseCommaParts(m.body);
|
||
if (n.length === 1) {
|
||
// x{{a,b}}y ==> x{a}y x{b}y
|
||
n = expand(n[0], false).map(embrace);
|
||
if (n.length === 1) {
|
||
var post = m.post.length
|
||
? expand(m.post, false)
|
||
: [''];
|
||
return post.map(function(p) {
|
||
return m.pre + n[0] + p;
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
// at this point, n is the parts, and we know it's not a comma set
|
||
// with a single entry.
|
||
|
||
// no need to expand pre, since it is guaranteed to be free of brace-sets
|
||
var pre = m.pre;
|
||
var post = m.post.length
|
||
? expand(m.post, false)
|
||
: [''];
|
||
|
||
var N;
|
||
|
||
if (isSequence) {
|
||
var x = numeric(n[0]);
|
||
var y = numeric(n[1]);
|
||
var width = Math.max(n[0].length, n[1].length)
|
||
var incr = n.length == 3
|
||
? Math.abs(numeric(n[2]))
|
||
: 1;
|
||
var test = lte;
|
||
var reverse = y < x;
|
||
if (reverse) {
|
||
incr *= -1;
|
||
test = gte;
|
||
}
|
||
var pad = n.some(isPadded);
|
||
|
||
N = [];
|
||
|
||
for (var i = x; test(i, y); i += incr) {
|
||
var c;
|
||
if (isAlphaSequence) {
|
||
c = String.fromCharCode(i);
|
||
if (c === '\\')
|
||
c = '';
|
||
} else {
|
||
c = String(i);
|
||
if (pad) {
|
||
var need = width - c.length;
|
||
if (need > 0) {
|
||
var z = new Array(need + 1).join('0');
|
||
if (i < 0)
|
||
c = '-' + z + c.slice(1);
|
||
else
|
||
c = z + c;
|
||
}
|
||
}
|
||
}
|
||
N.push(c);
|
||
}
|
||
} else {
|
||
N = concatMap(n, function(el) { return expand(el, false) });
|
||
}
|
||
|
||
for (var j = 0; j < N.length; j++) {
|
||
for (var k = 0; k < post.length; k++) {
|
||
var expansion = pre + N[j] + post[k];
|
||
if (!isTop || isSequence || expansion)
|
||
expansions.push(expansion);
|
||
}
|
||
}
|
||
|
||
return expansions;
|
||
}
|
||
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/concat-map/index.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/concat-map/index.js ***!
|
||
\******************************************/
|
||
/***/ ((module) => {
|
||
|
||
module.exports = function (xs, fn) {
|
||
var res = [];
|
||
for (var i = 0; i < xs.length; i++) {
|
||
var x = fn(xs[i], i);
|
||
if (isArray(x)) res.push.apply(res, x);
|
||
else res.push(x);
|
||
}
|
||
return res;
|
||
};
|
||
|
||
var isArray = Array.isArray || function (xs) {
|
||
return Object.prototype.toString.call(xs) === '[object Array]';
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/fs.realpath/index.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/fs.realpath/index.js ***!
|
||
\*******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
module.exports = realpath
|
||
realpath.realpath = realpath
|
||
realpath.sync = realpathSync
|
||
realpath.realpathSync = realpathSync
|
||
realpath.monkeypatch = monkeypatch
|
||
realpath.unmonkeypatch = unmonkeypatch
|
||
|
||
var fs = __webpack_require__(/*! fs */ "fs")
|
||
var origRealpath = fs.realpath
|
||
var origRealpathSync = fs.realpathSync
|
||
|
||
var version = process.version
|
||
var ok = /^v[0-5]\./.test(version)
|
||
var old = __webpack_require__(/*! ./old.js */ "./node_modules/fs.realpath/old.js")
|
||
|
||
function newError (er) {
|
||
return er && er.syscall === 'realpath' && (
|
||
er.code === 'ELOOP' ||
|
||
er.code === 'ENOMEM' ||
|
||
er.code === 'ENAMETOOLONG'
|
||
)
|
||
}
|
||
|
||
function realpath (p, cache, cb) {
|
||
if (ok) {
|
||
return origRealpath(p, cache, cb)
|
||
}
|
||
|
||
if (typeof cache === 'function') {
|
||
cb = cache
|
||
cache = null
|
||
}
|
||
origRealpath(p, cache, function (er, result) {
|
||
if (newError(er)) {
|
||
old.realpath(p, cache, cb)
|
||
} else {
|
||
cb(er, result)
|
||
}
|
||
})
|
||
}
|
||
|
||
function realpathSync (p, cache) {
|
||
if (ok) {
|
||
return origRealpathSync(p, cache)
|
||
}
|
||
|
||
try {
|
||
return origRealpathSync(p, cache)
|
||
} catch (er) {
|
||
if (newError(er)) {
|
||
return old.realpathSync(p, cache)
|
||
} else {
|
||
throw er
|
||
}
|
||
}
|
||
}
|
||
|
||
function monkeypatch () {
|
||
fs.realpath = realpath
|
||
fs.realpathSync = realpathSync
|
||
}
|
||
|
||
function unmonkeypatch () {
|
||
fs.realpath = origRealpath
|
||
fs.realpathSync = origRealpathSync
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/fs.realpath/old.js":
|
||
/*!*****************************************!*\
|
||
!*** ./node_modules/fs.realpath/old.js ***!
|
||
\*****************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
// Copyright Joyent, Inc. and other Node contributors.
|
||
//
|
||
// 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.
|
||
|
||
var pathModule = __webpack_require__(/*! path */ "path");
|
||
var isWindows = process.platform === 'win32';
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
// JavaScript implementation of realpath, ported from node pre-v6
|
||
|
||
var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG);
|
||
|
||
function rethrow() {
|
||
// Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and
|
||
// is fairly slow to generate.
|
||
var callback;
|
||
if (DEBUG) {
|
||
var backtrace = new Error;
|
||
callback = debugCallback;
|
||
} else
|
||
callback = missingCallback;
|
||
|
||
return callback;
|
||
|
||
function debugCallback(err) {
|
||
if (err) {
|
||
backtrace.message = err.message;
|
||
err = backtrace;
|
||
missingCallback(err);
|
||
}
|
||
}
|
||
|
||
function missingCallback(err) {
|
||
if (err) {
|
||
if (process.throwDeprecation)
|
||
throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs
|
||
else if (!process.noDeprecation) {
|
||
var msg = 'fs: missing callback ' + (err.stack || err.message);
|
||
if (process.traceDeprecation)
|
||
console.trace(msg);
|
||
else
|
||
console.error(msg);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function maybeCallback(cb) {
|
||
return typeof cb === 'function' ? cb : rethrow();
|
||
}
|
||
|
||
var normalize = pathModule.normalize;
|
||
|
||
// Regexp that finds the next partion of a (partial) path
|
||
// result is [base_with_slash, base], e.g. ['somedir/', 'somedir']
|
||
if (isWindows) {
|
||
var nextPartRe = /(.*?)(?:[\/\\]+|$)/g;
|
||
} else {
|
||
var nextPartRe = /(.*?)(?:[\/]+|$)/g;
|
||
}
|
||
|
||
// Regex to find the device root, including trailing slash. E.g. 'c:\\'.
|
||
if (isWindows) {
|
||
var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/;
|
||
} else {
|
||
var splitRootRe = /^[\/]*/;
|
||
}
|
||
|
||
exports.realpathSync = function realpathSync(p, cache) {
|
||
// make p is absolute
|
||
p = pathModule.resolve(p);
|
||
|
||
if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
|
||
return cache[p];
|
||
}
|
||
|
||
var original = p,
|
||
seenLinks = {},
|
||
knownHard = {};
|
||
|
||
// current character position in p
|
||
var pos;
|
||
// the partial path so far, including a trailing slash if any
|
||
var current;
|
||
// the partial path without a trailing slash (except when pointing at a root)
|
||
var base;
|
||
// the partial path scanned in the previous round, with slash
|
||
var previous;
|
||
|
||
start();
|
||
|
||
function start() {
|
||
// Skip over roots
|
||
var m = splitRootRe.exec(p);
|
||
pos = m[0].length;
|
||
current = m[0];
|
||
base = m[0];
|
||
previous = '';
|
||
|
||
// On windows, check that the root exists. On unix there is no need.
|
||
if (isWindows && !knownHard[base]) {
|
||
fs.lstatSync(base);
|
||
knownHard[base] = true;
|
||
}
|
||
}
|
||
|
||
// walk down the path, swapping out linked pathparts for their real
|
||
// values
|
||
// NB: p.length changes.
|
||
while (pos < p.length) {
|
||
// find the next part
|
||
nextPartRe.lastIndex = pos;
|
||
var result = nextPartRe.exec(p);
|
||
previous = current;
|
||
current += result[0];
|
||
base = previous + result[1];
|
||
pos = nextPartRe.lastIndex;
|
||
|
||
// continue if not a symlink
|
||
if (knownHard[base] || (cache && cache[base] === base)) {
|
||
continue;
|
||
}
|
||
|
||
var resolvedLink;
|
||
if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
|
||
// some known symbolic link. no need to stat again.
|
||
resolvedLink = cache[base];
|
||
} else {
|
||
var stat = fs.lstatSync(base);
|
||
if (!stat.isSymbolicLink()) {
|
||
knownHard[base] = true;
|
||
if (cache) cache[base] = base;
|
||
continue;
|
||
}
|
||
|
||
// read the link if it wasn't read before
|
||
// dev/ino always return 0 on windows, so skip the check.
|
||
var linkTarget = null;
|
||
if (!isWindows) {
|
||
var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
|
||
if (seenLinks.hasOwnProperty(id)) {
|
||
linkTarget = seenLinks[id];
|
||
}
|
||
}
|
||
if (linkTarget === null) {
|
||
fs.statSync(base);
|
||
linkTarget = fs.readlinkSync(base);
|
||
}
|
||
resolvedLink = pathModule.resolve(previous, linkTarget);
|
||
// track this, if given a cache.
|
||
if (cache) cache[base] = resolvedLink;
|
||
if (!isWindows) seenLinks[id] = linkTarget;
|
||
}
|
||
|
||
// resolve the link, then start over
|
||
p = pathModule.resolve(resolvedLink, p.slice(pos));
|
||
start();
|
||
}
|
||
|
||
if (cache) cache[original] = p;
|
||
|
||
return p;
|
||
};
|
||
|
||
|
||
exports.realpath = function realpath(p, cache, cb) {
|
||
if (typeof cb !== 'function') {
|
||
cb = maybeCallback(cache);
|
||
cache = null;
|
||
}
|
||
|
||
// make p is absolute
|
||
p = pathModule.resolve(p);
|
||
|
||
if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
|
||
return process.nextTick(cb.bind(null, null, cache[p]));
|
||
}
|
||
|
||
var original = p,
|
||
seenLinks = {},
|
||
knownHard = {};
|
||
|
||
// current character position in p
|
||
var pos;
|
||
// the partial path so far, including a trailing slash if any
|
||
var current;
|
||
// the partial path without a trailing slash (except when pointing at a root)
|
||
var base;
|
||
// the partial path scanned in the previous round, with slash
|
||
var previous;
|
||
|
||
start();
|
||
|
||
function start() {
|
||
// Skip over roots
|
||
var m = splitRootRe.exec(p);
|
||
pos = m[0].length;
|
||
current = m[0];
|
||
base = m[0];
|
||
previous = '';
|
||
|
||
// On windows, check that the root exists. On unix there is no need.
|
||
if (isWindows && !knownHard[base]) {
|
||
fs.lstat(base, function(err) {
|
||
if (err) return cb(err);
|
||
knownHard[base] = true;
|
||
LOOP();
|
||
});
|
||
} else {
|
||
process.nextTick(LOOP);
|
||
}
|
||
}
|
||
|
||
// walk down the path, swapping out linked pathparts for their real
|
||
// values
|
||
function LOOP() {
|
||
// stop if scanned past end of path
|
||
if (pos >= p.length) {
|
||
if (cache) cache[original] = p;
|
||
return cb(null, p);
|
||
}
|
||
|
||
// find the next part
|
||
nextPartRe.lastIndex = pos;
|
||
var result = nextPartRe.exec(p);
|
||
previous = current;
|
||
current += result[0];
|
||
base = previous + result[1];
|
||
pos = nextPartRe.lastIndex;
|
||
|
||
// continue if not a symlink
|
||
if (knownHard[base] || (cache && cache[base] === base)) {
|
||
return process.nextTick(LOOP);
|
||
}
|
||
|
||
if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
|
||
// known symbolic link. no need to stat again.
|
||
return gotResolvedLink(cache[base]);
|
||
}
|
||
|
||
return fs.lstat(base, gotStat);
|
||
}
|
||
|
||
function gotStat(err, stat) {
|
||
if (err) return cb(err);
|
||
|
||
// if not a symlink, skip to the next path part
|
||
if (!stat.isSymbolicLink()) {
|
||
knownHard[base] = true;
|
||
if (cache) cache[base] = base;
|
||
return process.nextTick(LOOP);
|
||
}
|
||
|
||
// stat & read the link if not read before
|
||
// call gotTarget as soon as the link target is known
|
||
// dev/ino always return 0 on windows, so skip the check.
|
||
if (!isWindows) {
|
||
var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
|
||
if (seenLinks.hasOwnProperty(id)) {
|
||
return gotTarget(null, seenLinks[id], base);
|
||
}
|
||
}
|
||
fs.stat(base, function(err) {
|
||
if (err) return cb(err);
|
||
|
||
fs.readlink(base, function(err, target) {
|
||
if (!isWindows) seenLinks[id] = target;
|
||
gotTarget(err, target);
|
||
});
|
||
});
|
||
}
|
||
|
||
function gotTarget(err, target, base) {
|
||
if (err) return cb(err);
|
||
|
||
var resolvedLink = pathModule.resolve(previous, target);
|
||
if (cache) cache[base] = resolvedLink;
|
||
gotResolvedLink(resolvedLink);
|
||
}
|
||
|
||
function gotResolvedLink(resolvedLink) {
|
||
// resolve the link, then start over
|
||
p = pathModule.resolve(resolvedLink, p.slice(pos));
|
||
start();
|
||
}
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/glob/common.js":
|
||
/*!*************************************!*\
|
||
!*** ./node_modules/glob/common.js ***!
|
||
\*************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
exports.alphasort = alphasort
|
||
exports.alphasorti = alphasorti
|
||
exports.setopts = setopts
|
||
exports.ownProp = ownProp
|
||
exports.makeAbs = makeAbs
|
||
exports.finish = finish
|
||
exports.mark = mark
|
||
exports.isIgnored = isIgnored
|
||
exports.childrenIgnored = childrenIgnored
|
||
|
||
function ownProp (obj, field) {
|
||
return Object.prototype.hasOwnProperty.call(obj, field)
|
||
}
|
||
|
||
var path = __webpack_require__(/*! path */ "path")
|
||
var minimatch = __webpack_require__(/*! minimatch */ "./node_modules/minimatch/minimatch.js")
|
||
var isAbsolute = __webpack_require__(/*! path-is-absolute */ "./node_modules/path-is-absolute/index.js")
|
||
var Minimatch = minimatch.Minimatch
|
||
|
||
function alphasorti (a, b) {
|
||
return a.toLowerCase().localeCompare(b.toLowerCase())
|
||
}
|
||
|
||
function alphasort (a, b) {
|
||
return a.localeCompare(b)
|
||
}
|
||
|
||
function setupIgnores (self, options) {
|
||
self.ignore = options.ignore || []
|
||
|
||
if (!Array.isArray(self.ignore))
|
||
self.ignore = [self.ignore]
|
||
|
||
if (self.ignore.length) {
|
||
self.ignore = self.ignore.map(ignoreMap)
|
||
}
|
||
}
|
||
|
||
// ignore patterns are always in dot:true mode.
|
||
function ignoreMap (pattern) {
|
||
var gmatcher = null
|
||
if (pattern.slice(-3) === '/**') {
|
||
var gpattern = pattern.replace(/(\/\*\*)+$/, '')
|
||
gmatcher = new Minimatch(gpattern, { dot: true })
|
||
}
|
||
|
||
return {
|
||
matcher: new Minimatch(pattern, { dot: true }),
|
||
gmatcher: gmatcher
|
||
}
|
||
}
|
||
|
||
function setopts (self, pattern, options) {
|
||
if (!options)
|
||
options = {}
|
||
|
||
// base-matching: just use globstar for that.
|
||
if (options.matchBase && -1 === pattern.indexOf("/")) {
|
||
if (options.noglobstar) {
|
||
throw new Error("base matching requires globstar")
|
||
}
|
||
pattern = "**/" + pattern
|
||
}
|
||
|
||
self.silent = !!options.silent
|
||
self.pattern = pattern
|
||
self.strict = options.strict !== false
|
||
self.realpath = !!options.realpath
|
||
self.realpathCache = options.realpathCache || Object.create(null)
|
||
self.follow = !!options.follow
|
||
self.dot = !!options.dot
|
||
self.mark = !!options.mark
|
||
self.nodir = !!options.nodir
|
||
if (self.nodir)
|
||
self.mark = true
|
||
self.sync = !!options.sync
|
||
self.nounique = !!options.nounique
|
||
self.nonull = !!options.nonull
|
||
self.nosort = !!options.nosort
|
||
self.nocase = !!options.nocase
|
||
self.stat = !!options.stat
|
||
self.noprocess = !!options.noprocess
|
||
self.absolute = !!options.absolute
|
||
|
||
self.maxLength = options.maxLength || Infinity
|
||
self.cache = options.cache || Object.create(null)
|
||
self.statCache = options.statCache || Object.create(null)
|
||
self.symlinks = options.symlinks || Object.create(null)
|
||
|
||
setupIgnores(self, options)
|
||
|
||
self.changedCwd = false
|
||
var cwd = process.cwd()
|
||
if (!ownProp(options, "cwd"))
|
||
self.cwd = cwd
|
||
else {
|
||
self.cwd = path.resolve(options.cwd)
|
||
self.changedCwd = self.cwd !== cwd
|
||
}
|
||
|
||
self.root = options.root || path.resolve(self.cwd, "/")
|
||
self.root = path.resolve(self.root)
|
||
if (process.platform === "win32")
|
||
self.root = self.root.replace(/\\/g, "/")
|
||
|
||
// TODO: is an absolute `cwd` supposed to be resolved against `root`?
|
||
// e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test')
|
||
self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd)
|
||
if (process.platform === "win32")
|
||
self.cwdAbs = self.cwdAbs.replace(/\\/g, "/")
|
||
self.nomount = !!options.nomount
|
||
|
||
// disable comments and negation in Minimatch.
|
||
// Note that they are not supported in Glob itself anyway.
|
||
options.nonegate = true
|
||
options.nocomment = true
|
||
|
||
self.minimatch = new Minimatch(pattern, options)
|
||
self.options = self.minimatch.options
|
||
}
|
||
|
||
function finish (self) {
|
||
var nou = self.nounique
|
||
var all = nou ? [] : Object.create(null)
|
||
|
||
for (var i = 0, l = self.matches.length; i < l; i ++) {
|
||
var matches = self.matches[i]
|
||
if (!matches || Object.keys(matches).length === 0) {
|
||
if (self.nonull) {
|
||
// do like the shell, and spit out the literal glob
|
||
var literal = self.minimatch.globSet[i]
|
||
if (nou)
|
||
all.push(literal)
|
||
else
|
||
all[literal] = true
|
||
}
|
||
} else {
|
||
// had matches
|
||
var m = Object.keys(matches)
|
||
if (nou)
|
||
all.push.apply(all, m)
|
||
else
|
||
m.forEach(function (m) {
|
||
all[m] = true
|
||
})
|
||
}
|
||
}
|
||
|
||
if (!nou)
|
||
all = Object.keys(all)
|
||
|
||
if (!self.nosort)
|
||
all = all.sort(self.nocase ? alphasorti : alphasort)
|
||
|
||
// at *some* point we statted all of these
|
||
if (self.mark) {
|
||
for (var i = 0; i < all.length; i++) {
|
||
all[i] = self._mark(all[i])
|
||
}
|
||
if (self.nodir) {
|
||
all = all.filter(function (e) {
|
||
var notDir = !(/\/$/.test(e))
|
||
var c = self.cache[e] || self.cache[makeAbs(self, e)]
|
||
if (notDir && c)
|
||
notDir = c !== 'DIR' && !Array.isArray(c)
|
||
return notDir
|
||
})
|
||
}
|
||
}
|
||
|
||
if (self.ignore.length)
|
||
all = all.filter(function(m) {
|
||
return !isIgnored(self, m)
|
||
})
|
||
|
||
self.found = all
|
||
}
|
||
|
||
function mark (self, p) {
|
||
var abs = makeAbs(self, p)
|
||
var c = self.cache[abs]
|
||
var m = p
|
||
if (c) {
|
||
var isDir = c === 'DIR' || Array.isArray(c)
|
||
var slash = p.slice(-1) === '/'
|
||
|
||
if (isDir && !slash)
|
||
m += '/'
|
||
else if (!isDir && slash)
|
||
m = m.slice(0, -1)
|
||
|
||
if (m !== p) {
|
||
var mabs = makeAbs(self, m)
|
||
self.statCache[mabs] = self.statCache[abs]
|
||
self.cache[mabs] = self.cache[abs]
|
||
}
|
||
}
|
||
|
||
return m
|
||
}
|
||
|
||
// lotta situps...
|
||
function makeAbs (self, f) {
|
||
var abs = f
|
||
if (f.charAt(0) === '/') {
|
||
abs = path.join(self.root, f)
|
||
} else if (isAbsolute(f) || f === '') {
|
||
abs = f
|
||
} else if (self.changedCwd) {
|
||
abs = path.resolve(self.cwd, f)
|
||
} else {
|
||
abs = path.resolve(f)
|
||
}
|
||
|
||
if (process.platform === 'win32')
|
||
abs = abs.replace(/\\/g, '/')
|
||
|
||
return abs
|
||
}
|
||
|
||
|
||
// Return true, if pattern ends with globstar '**', for the accompanying parent directory.
|
||
// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents
|
||
function isIgnored (self, path) {
|
||
if (!self.ignore.length)
|
||
return false
|
||
|
||
return self.ignore.some(function(item) {
|
||
return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path))
|
||
})
|
||
}
|
||
|
||
function childrenIgnored (self, path) {
|
||
if (!self.ignore.length)
|
||
return false
|
||
|
||
return self.ignore.some(function(item) {
|
||
return !!(item.gmatcher && item.gmatcher.match(path))
|
||
})
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/glob/glob.js":
|
||
/*!***********************************!*\
|
||
!*** ./node_modules/glob/glob.js ***!
|
||
\***********************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
// Approach:
|
||
//
|
||
// 1. Get the minimatch set
|
||
// 2. For each pattern in the set, PROCESS(pattern, false)
|
||
// 3. Store matches per-set, then uniq them
|
||
//
|
||
// PROCESS(pattern, inGlobStar)
|
||
// Get the first [n] items from pattern that are all strings
|
||
// Join these together. This is PREFIX.
|
||
// If there is no more remaining, then stat(PREFIX) and
|
||
// add to matches if it succeeds. END.
|
||
//
|
||
// If inGlobStar and PREFIX is symlink and points to dir
|
||
// set ENTRIES = []
|
||
// else readdir(PREFIX) as ENTRIES
|
||
// If fail, END
|
||
//
|
||
// with ENTRIES
|
||
// If pattern[n] is GLOBSTAR
|
||
// // handle the case where the globstar match is empty
|
||
// // by pruning it out, and testing the resulting pattern
|
||
// PROCESS(pattern[0..n] + pattern[n+1 .. $], false)
|
||
// // handle other cases.
|
||
// for ENTRY in ENTRIES (not dotfiles)
|
||
// // attach globstar + tail onto the entry
|
||
// // Mark that this entry is a globstar match
|
||
// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true)
|
||
//
|
||
// else // not globstar
|
||
// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot)
|
||
// Test ENTRY against pattern[n]
|
||
// If fails, continue
|
||
// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $])
|
||
//
|
||
// Caveat:
|
||
// Cache all stats and readdirs results to minimize syscall. Since all
|
||
// we ever care about is existence and directory-ness, we can just keep
|
||
// `true` for files, and [children,...] for directories, or `false` for
|
||
// things that don't exist.
|
||
|
||
module.exports = glob
|
||
|
||
var fs = __webpack_require__(/*! fs */ "fs")
|
||
var rp = __webpack_require__(/*! fs.realpath */ "./node_modules/fs.realpath/index.js")
|
||
var minimatch = __webpack_require__(/*! minimatch */ "./node_modules/minimatch/minimatch.js")
|
||
var Minimatch = minimatch.Minimatch
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits.js")
|
||
var EE = __webpack_require__(/*! events */ "events").EventEmitter
|
||
var path = __webpack_require__(/*! path */ "path")
|
||
var assert = __webpack_require__(/*! assert */ "assert")
|
||
var isAbsolute = __webpack_require__(/*! path-is-absolute */ "./node_modules/path-is-absolute/index.js")
|
||
var globSync = __webpack_require__(/*! ./sync.js */ "./node_modules/glob/sync.js")
|
||
var common = __webpack_require__(/*! ./common.js */ "./node_modules/glob/common.js")
|
||
var alphasort = common.alphasort
|
||
var alphasorti = common.alphasorti
|
||
var setopts = common.setopts
|
||
var ownProp = common.ownProp
|
||
var inflight = __webpack_require__(/*! inflight */ "./node_modules/inflight/inflight.js")
|
||
var util = __webpack_require__(/*! util */ "util")
|
||
var childrenIgnored = common.childrenIgnored
|
||
var isIgnored = common.isIgnored
|
||
|
||
var once = __webpack_require__(/*! once */ "./node_modules/once/once.js")
|
||
|
||
function glob (pattern, options, cb) {
|
||
if (typeof options === 'function') cb = options, options = {}
|
||
if (!options) options = {}
|
||
|
||
if (options.sync) {
|
||
if (cb)
|
||
throw new TypeError('callback provided to sync glob')
|
||
return globSync(pattern, options)
|
||
}
|
||
|
||
return new Glob(pattern, options, cb)
|
||
}
|
||
|
||
glob.sync = globSync
|
||
var GlobSync = glob.GlobSync = globSync.GlobSync
|
||
|
||
// old api surface
|
||
glob.glob = glob
|
||
|
||
function extend (origin, add) {
|
||
if (add === null || typeof add !== 'object') {
|
||
return origin
|
||
}
|
||
|
||
var keys = Object.keys(add)
|
||
var i = keys.length
|
||
while (i--) {
|
||
origin[keys[i]] = add[keys[i]]
|
||
}
|
||
return origin
|
||
}
|
||
|
||
glob.hasMagic = function (pattern, options_) {
|
||
var options = extend({}, options_)
|
||
options.noprocess = true
|
||
|
||
var g = new Glob(pattern, options)
|
||
var set = g.minimatch.set
|
||
|
||
if (!pattern)
|
||
return false
|
||
|
||
if (set.length > 1)
|
||
return true
|
||
|
||
for (var j = 0; j < set[0].length; j++) {
|
||
if (typeof set[0][j] !== 'string')
|
||
return true
|
||
}
|
||
|
||
return false
|
||
}
|
||
|
||
glob.Glob = Glob
|
||
inherits(Glob, EE)
|
||
function Glob (pattern, options, cb) {
|
||
if (typeof options === 'function') {
|
||
cb = options
|
||
options = null
|
||
}
|
||
|
||
if (options && options.sync) {
|
||
if (cb)
|
||
throw new TypeError('callback provided to sync glob')
|
||
return new GlobSync(pattern, options)
|
||
}
|
||
|
||
if (!(this instanceof Glob))
|
||
return new Glob(pattern, options, cb)
|
||
|
||
setopts(this, pattern, options)
|
||
this._didRealPath = false
|
||
|
||
// process each pattern in the minimatch set
|
||
var n = this.minimatch.set.length
|
||
|
||
// The matches are stored as {<filename>: true,...} so that
|
||
// duplicates are automagically pruned.
|
||
// Later, we do an Object.keys() on these.
|
||
// Keep them as a list so we can fill in when nonull is set.
|
||
this.matches = new Array(n)
|
||
|
||
if (typeof cb === 'function') {
|
||
cb = once(cb)
|
||
this.on('error', cb)
|
||
this.on('end', function (matches) {
|
||
cb(null, matches)
|
||
})
|
||
}
|
||
|
||
var self = this
|
||
this._processing = 0
|
||
|
||
this._emitQueue = []
|
||
this._processQueue = []
|
||
this.paused = false
|
||
|
||
if (this.noprocess)
|
||
return this
|
||
|
||
if (n === 0)
|
||
return done()
|
||
|
||
var sync = true
|
||
for (var i = 0; i < n; i ++) {
|
||
this._process(this.minimatch.set[i], i, false, done)
|
||
}
|
||
sync = false
|
||
|
||
function done () {
|
||
--self._processing
|
||
if (self._processing <= 0) {
|
||
if (sync) {
|
||
process.nextTick(function () {
|
||
self._finish()
|
||
})
|
||
} else {
|
||
self._finish()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Glob.prototype._finish = function () {
|
||
assert(this instanceof Glob)
|
||
if (this.aborted)
|
||
return
|
||
|
||
if (this.realpath && !this._didRealpath)
|
||
return this._realpath()
|
||
|
||
common.finish(this)
|
||
this.emit('end', this.found)
|
||
}
|
||
|
||
Glob.prototype._realpath = function () {
|
||
if (this._didRealpath)
|
||
return
|
||
|
||
this._didRealpath = true
|
||
|
||
var n = this.matches.length
|
||
if (n === 0)
|
||
return this._finish()
|
||
|
||
var self = this
|
||
for (var i = 0; i < this.matches.length; i++)
|
||
this._realpathSet(i, next)
|
||
|
||
function next () {
|
||
if (--n === 0)
|
||
self._finish()
|
||
}
|
||
}
|
||
|
||
Glob.prototype._realpathSet = function (index, cb) {
|
||
var matchset = this.matches[index]
|
||
if (!matchset)
|
||
return cb()
|
||
|
||
var found = Object.keys(matchset)
|
||
var self = this
|
||
var n = found.length
|
||
|
||
if (n === 0)
|
||
return cb()
|
||
|
||
var set = this.matches[index] = Object.create(null)
|
||
found.forEach(function (p, i) {
|
||
// If there's a problem with the stat, then it means that
|
||
// one or more of the links in the realpath couldn't be
|
||
// resolved. just return the abs value in that case.
|
||
p = self._makeAbs(p)
|
||
rp.realpath(p, self.realpathCache, function (er, real) {
|
||
if (!er)
|
||
set[real] = true
|
||
else if (er.syscall === 'stat')
|
||
set[p] = true
|
||
else
|
||
self.emit('error', er) // srsly wtf right here
|
||
|
||
if (--n === 0) {
|
||
self.matches[index] = set
|
||
cb()
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|
||
Glob.prototype._mark = function (p) {
|
||
return common.mark(this, p)
|
||
}
|
||
|
||
Glob.prototype._makeAbs = function (f) {
|
||
return common.makeAbs(this, f)
|
||
}
|
||
|
||
Glob.prototype.abort = function () {
|
||
this.aborted = true
|
||
this.emit('abort')
|
||
}
|
||
|
||
Glob.prototype.pause = function () {
|
||
if (!this.paused) {
|
||
this.paused = true
|
||
this.emit('pause')
|
||
}
|
||
}
|
||
|
||
Glob.prototype.resume = function () {
|
||
if (this.paused) {
|
||
this.emit('resume')
|
||
this.paused = false
|
||
if (this._emitQueue.length) {
|
||
var eq = this._emitQueue.slice(0)
|
||
this._emitQueue.length = 0
|
||
for (var i = 0; i < eq.length; i ++) {
|
||
var e = eq[i]
|
||
this._emitMatch(e[0], e[1])
|
||
}
|
||
}
|
||
if (this._processQueue.length) {
|
||
var pq = this._processQueue.slice(0)
|
||
this._processQueue.length = 0
|
||
for (var i = 0; i < pq.length; i ++) {
|
||
var p = pq[i]
|
||
this._processing--
|
||
this._process(p[0], p[1], p[2], p[3])
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Glob.prototype._process = function (pattern, index, inGlobStar, cb) {
|
||
assert(this instanceof Glob)
|
||
assert(typeof cb === 'function')
|
||
|
||
if (this.aborted)
|
||
return
|
||
|
||
this._processing++
|
||
if (this.paused) {
|
||
this._processQueue.push([pattern, index, inGlobStar, cb])
|
||
return
|
||
}
|
||
|
||
//console.error('PROCESS %d', this._processing, pattern)
|
||
|
||
// Get the first [n] parts of pattern that are all strings.
|
||
var n = 0
|
||
while (typeof pattern[n] === 'string') {
|
||
n ++
|
||
}
|
||
// now n is the index of the first one that is *not* a string.
|
||
|
||
// see if there's anything else
|
||
var prefix
|
||
switch (n) {
|
||
// if not, then this is rather simple
|
||
case pattern.length:
|
||
this._processSimple(pattern.join('/'), index, cb)
|
||
return
|
||
|
||
case 0:
|
||
// pattern *starts* with some non-trivial item.
|
||
// going to readdir(cwd), but not include the prefix in matches.
|
||
prefix = null
|
||
break
|
||
|
||
default:
|
||
// pattern has some string bits in the front.
|
||
// whatever it starts with, whether that's 'absolute' like /foo/bar,
|
||
// or 'relative' like '../baz'
|
||
prefix = pattern.slice(0, n).join('/')
|
||
break
|
||
}
|
||
|
||
var remain = pattern.slice(n)
|
||
|
||
// get the list of entries.
|
||
var read
|
||
if (prefix === null)
|
||
read = '.'
|
||
else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) {
|
||
if (!prefix || !isAbsolute(prefix))
|
||
prefix = '/' + prefix
|
||
read = prefix
|
||
} else
|
||
read = prefix
|
||
|
||
var abs = this._makeAbs(read)
|
||
|
||
//if ignored, skip _processing
|
||
if (childrenIgnored(this, read))
|
||
return cb()
|
||
|
||
var isGlobStar = remain[0] === minimatch.GLOBSTAR
|
||
if (isGlobStar)
|
||
this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb)
|
||
else
|
||
this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb)
|
||
}
|
||
|
||
Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) {
|
||
var self = this
|
||
this._readdir(abs, inGlobStar, function (er, entries) {
|
||
return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb)
|
||
})
|
||
}
|
||
|
||
Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) {
|
||
|
||
// if the abs isn't a dir, then nothing can match!
|
||
if (!entries)
|
||
return cb()
|
||
|
||
// It will only match dot entries if it starts with a dot, or if
|
||
// dot is set. Stuff like @(.foo|.bar) isn't allowed.
|
||
var pn = remain[0]
|
||
var negate = !!this.minimatch.negate
|
||
var rawGlob = pn._glob
|
||
var dotOk = this.dot || rawGlob.charAt(0) === '.'
|
||
|
||
var matchedEntries = []
|
||
for (var i = 0; i < entries.length; i++) {
|
||
var e = entries[i]
|
||
if (e.charAt(0) !== '.' || dotOk) {
|
||
var m
|
||
if (negate && !prefix) {
|
||
m = !e.match(pn)
|
||
} else {
|
||
m = e.match(pn)
|
||
}
|
||
if (m)
|
||
matchedEntries.push(e)
|
||
}
|
||
}
|
||
|
||
//console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries)
|
||
|
||
var len = matchedEntries.length
|
||
// If there are no matched entries, then nothing matches.
|
||
if (len === 0)
|
||
return cb()
|
||
|
||
// if this is the last remaining pattern bit, then no need for
|
||
// an additional stat *unless* the user has specified mark or
|
||
// stat explicitly. We know they exist, since readdir returned
|
||
// them.
|
||
|
||
if (remain.length === 1 && !this.mark && !this.stat) {
|
||
if (!this.matches[index])
|
||
this.matches[index] = Object.create(null)
|
||
|
||
for (var i = 0; i < len; i ++) {
|
||
var e = matchedEntries[i]
|
||
if (prefix) {
|
||
if (prefix !== '/')
|
||
e = prefix + '/' + e
|
||
else
|
||
e = prefix + e
|
||
}
|
||
|
||
if (e.charAt(0) === '/' && !this.nomount) {
|
||
e = path.join(this.root, e)
|
||
}
|
||
this._emitMatch(index, e)
|
||
}
|
||
// This was the last one, and no stats were needed
|
||
return cb()
|
||
}
|
||
|
||
// now test all matched entries as stand-ins for that part
|
||
// of the pattern.
|
||
remain.shift()
|
||
for (var i = 0; i < len; i ++) {
|
||
var e = matchedEntries[i]
|
||
var newPattern
|
||
if (prefix) {
|
||
if (prefix !== '/')
|
||
e = prefix + '/' + e
|
||
else
|
||
e = prefix + e
|
||
}
|
||
this._process([e].concat(remain), index, inGlobStar, cb)
|
||
}
|
||
cb()
|
||
}
|
||
|
||
Glob.prototype._emitMatch = function (index, e) {
|
||
if (this.aborted)
|
||
return
|
||
|
||
if (isIgnored(this, e))
|
||
return
|
||
|
||
if (this.paused) {
|
||
this._emitQueue.push([index, e])
|
||
return
|
||
}
|
||
|
||
var abs = isAbsolute(e) ? e : this._makeAbs(e)
|
||
|
||
if (this.mark)
|
||
e = this._mark(e)
|
||
|
||
if (this.absolute)
|
||
e = abs
|
||
|
||
if (this.matches[index][e])
|
||
return
|
||
|
||
if (this.nodir) {
|
||
var c = this.cache[abs]
|
||
if (c === 'DIR' || Array.isArray(c))
|
||
return
|
||
}
|
||
|
||
this.matches[index][e] = true
|
||
|
||
var st = this.statCache[abs]
|
||
if (st)
|
||
this.emit('stat', e, st)
|
||
|
||
this.emit('match', e)
|
||
}
|
||
|
||
Glob.prototype._readdirInGlobStar = function (abs, cb) {
|
||
if (this.aborted)
|
||
return
|
||
|
||
// follow all symlinked directories forever
|
||
// just proceed as if this is a non-globstar situation
|
||
if (this.follow)
|
||
return this._readdir(abs, false, cb)
|
||
|
||
var lstatkey = 'lstat\0' + abs
|
||
var self = this
|
||
var lstatcb = inflight(lstatkey, lstatcb_)
|
||
|
||
if (lstatcb)
|
||
fs.lstat(abs, lstatcb)
|
||
|
||
function lstatcb_ (er, lstat) {
|
||
if (er && er.code === 'ENOENT')
|
||
return cb()
|
||
|
||
var isSym = lstat && lstat.isSymbolicLink()
|
||
self.symlinks[abs] = isSym
|
||
|
||
// If it's not a symlink or a dir, then it's definitely a regular file.
|
||
// don't bother doing a readdir in that case.
|
||
if (!isSym && lstat && !lstat.isDirectory()) {
|
||
self.cache[abs] = 'FILE'
|
||
cb()
|
||
} else
|
||
self._readdir(abs, false, cb)
|
||
}
|
||
}
|
||
|
||
Glob.prototype._readdir = function (abs, inGlobStar, cb) {
|
||
if (this.aborted)
|
||
return
|
||
|
||
cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb)
|
||
if (!cb)
|
||
return
|
||
|
||
//console.error('RD %j %j', +inGlobStar, abs)
|
||
if (inGlobStar && !ownProp(this.symlinks, abs))
|
||
return this._readdirInGlobStar(abs, cb)
|
||
|
||
if (ownProp(this.cache, abs)) {
|
||
var c = this.cache[abs]
|
||
if (!c || c === 'FILE')
|
||
return cb()
|
||
|
||
if (Array.isArray(c))
|
||
return cb(null, c)
|
||
}
|
||
|
||
var self = this
|
||
fs.readdir(abs, readdirCb(this, abs, cb))
|
||
}
|
||
|
||
function readdirCb (self, abs, cb) {
|
||
return function (er, entries) {
|
||
if (er)
|
||
self._readdirError(abs, er, cb)
|
||
else
|
||
self._readdirEntries(abs, entries, cb)
|
||
}
|
||
}
|
||
|
||
Glob.prototype._readdirEntries = function (abs, entries, cb) {
|
||
if (this.aborted)
|
||
return
|
||
|
||
// if we haven't asked to stat everything, then just
|
||
// assume that everything in there exists, so we can avoid
|
||
// having to stat it a second time.
|
||
if (!this.mark && !this.stat) {
|
||
for (var i = 0; i < entries.length; i ++) {
|
||
var e = entries[i]
|
||
if (abs === '/')
|
||
e = abs + e
|
||
else
|
||
e = abs + '/' + e
|
||
this.cache[e] = true
|
||
}
|
||
}
|
||
|
||
this.cache[abs] = entries
|
||
return cb(null, entries)
|
||
}
|
||
|
||
Glob.prototype._readdirError = function (f, er, cb) {
|
||
if (this.aborted)
|
||
return
|
||
|
||
// handle errors, and cache the information
|
||
switch (er.code) {
|
||
case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205
|
||
case 'ENOTDIR': // totally normal. means it *does* exist.
|
||
var abs = this._makeAbs(f)
|
||
this.cache[abs] = 'FILE'
|
||
if (abs === this.cwdAbs) {
|
||
var error = new Error(er.code + ' invalid cwd ' + this.cwd)
|
||
error.path = this.cwd
|
||
error.code = er.code
|
||
this.emit('error', error)
|
||
this.abort()
|
||
}
|
||
break
|
||
|
||
case 'ENOENT': // not terribly unusual
|
||
case 'ELOOP':
|
||
case 'ENAMETOOLONG':
|
||
case 'UNKNOWN':
|
||
this.cache[this._makeAbs(f)] = false
|
||
break
|
||
|
||
default: // some unusual error. Treat as failure.
|
||
this.cache[this._makeAbs(f)] = false
|
||
if (this.strict) {
|
||
this.emit('error', er)
|
||
// If the error is handled, then we abort
|
||
// if not, we threw out of here
|
||
this.abort()
|
||
}
|
||
if (!this.silent)
|
||
console.error('glob error', er)
|
||
break
|
||
}
|
||
|
||
return cb()
|
||
}
|
||
|
||
Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) {
|
||
var self = this
|
||
this._readdir(abs, inGlobStar, function (er, entries) {
|
||
self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb)
|
||
})
|
||
}
|
||
|
||
|
||
Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) {
|
||
//console.error('pgs2', prefix, remain[0], entries)
|
||
|
||
// no entries means not a dir, so it can never have matches
|
||
// foo.txt/** doesn't match foo.txt
|
||
if (!entries)
|
||
return cb()
|
||
|
||
// test without the globstar, and with every child both below
|
||
// and replacing the globstar.
|
||
var remainWithoutGlobStar = remain.slice(1)
|
||
var gspref = prefix ? [ prefix ] : []
|
||
var noGlobStar = gspref.concat(remainWithoutGlobStar)
|
||
|
||
// the noGlobStar pattern exits the inGlobStar state
|
||
this._process(noGlobStar, index, false, cb)
|
||
|
||
var isSym = this.symlinks[abs]
|
||
var len = entries.length
|
||
|
||
// If it's a symlink, and we're in a globstar, then stop
|
||
if (isSym && inGlobStar)
|
||
return cb()
|
||
|
||
for (var i = 0; i < len; i++) {
|
||
var e = entries[i]
|
||
if (e.charAt(0) === '.' && !this.dot)
|
||
continue
|
||
|
||
// these two cases enter the inGlobStar state
|
||
var instead = gspref.concat(entries[i], remainWithoutGlobStar)
|
||
this._process(instead, index, true, cb)
|
||
|
||
var below = gspref.concat(entries[i], remain)
|
||
this._process(below, index, true, cb)
|
||
}
|
||
|
||
cb()
|
||
}
|
||
|
||
Glob.prototype._processSimple = function (prefix, index, cb) {
|
||
// XXX review this. Shouldn't it be doing the mounting etc
|
||
// before doing stat? kinda weird?
|
||
var self = this
|
||
this._stat(prefix, function (er, exists) {
|
||
self._processSimple2(prefix, index, er, exists, cb)
|
||
})
|
||
}
|
||
Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) {
|
||
|
||
//console.error('ps2', prefix, exists)
|
||
|
||
if (!this.matches[index])
|
||
this.matches[index] = Object.create(null)
|
||
|
||
// If it doesn't exist, then just mark the lack of results
|
||
if (!exists)
|
||
return cb()
|
||
|
||
if (prefix && isAbsolute(prefix) && !this.nomount) {
|
||
var trail = /[\/\\]$/.test(prefix)
|
||
if (prefix.charAt(0) === '/') {
|
||
prefix = path.join(this.root, prefix)
|
||
} else {
|
||
prefix = path.resolve(this.root, prefix)
|
||
if (trail)
|
||
prefix += '/'
|
||
}
|
||
}
|
||
|
||
if (process.platform === 'win32')
|
||
prefix = prefix.replace(/\\/g, '/')
|
||
|
||
// Mark this as a match
|
||
this._emitMatch(index, prefix)
|
||
cb()
|
||
}
|
||
|
||
// Returns either 'DIR', 'FILE', or false
|
||
Glob.prototype._stat = function (f, cb) {
|
||
var abs = this._makeAbs(f)
|
||
var needDir = f.slice(-1) === '/'
|
||
|
||
if (f.length > this.maxLength)
|
||
return cb()
|
||
|
||
if (!this.stat && ownProp(this.cache, abs)) {
|
||
var c = this.cache[abs]
|
||
|
||
if (Array.isArray(c))
|
||
c = 'DIR'
|
||
|
||
// It exists, but maybe not how we need it
|
||
if (!needDir || c === 'DIR')
|
||
return cb(null, c)
|
||
|
||
if (needDir && c === 'FILE')
|
||
return cb()
|
||
|
||
// otherwise we have to stat, because maybe c=true
|
||
// if we know it exists, but not what it is.
|
||
}
|
||
|
||
var exists
|
||
var stat = this.statCache[abs]
|
||
if (stat !== undefined) {
|
||
if (stat === false)
|
||
return cb(null, stat)
|
||
else {
|
||
var type = stat.isDirectory() ? 'DIR' : 'FILE'
|
||
if (needDir && type === 'FILE')
|
||
return cb()
|
||
else
|
||
return cb(null, type, stat)
|
||
}
|
||
}
|
||
|
||
var self = this
|
||
var statcb = inflight('stat\0' + abs, lstatcb_)
|
||
if (statcb)
|
||
fs.lstat(abs, statcb)
|
||
|
||
function lstatcb_ (er, lstat) {
|
||
if (lstat && lstat.isSymbolicLink()) {
|
||
// If it's a symlink, then treat it as the target, unless
|
||
// the target does not exist, then treat it as a file.
|
||
return fs.stat(abs, function (er, stat) {
|
||
if (er)
|
||
self._stat2(f, abs, null, lstat, cb)
|
||
else
|
||
self._stat2(f, abs, er, stat, cb)
|
||
})
|
||
} else {
|
||
self._stat2(f, abs, er, lstat, cb)
|
||
}
|
||
}
|
||
}
|
||
|
||
Glob.prototype._stat2 = function (f, abs, er, stat, cb) {
|
||
if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) {
|
||
this.statCache[abs] = false
|
||
return cb()
|
||
}
|
||
|
||
var needDir = f.slice(-1) === '/'
|
||
this.statCache[abs] = stat
|
||
|
||
if (abs.slice(-1) === '/' && stat && !stat.isDirectory())
|
||
return cb(null, false, stat)
|
||
|
||
var c = true
|
||
if (stat)
|
||
c = stat.isDirectory() ? 'DIR' : 'FILE'
|
||
this.cache[abs] = this.cache[abs] || c
|
||
|
||
if (needDir && c === 'FILE')
|
||
return cb()
|
||
|
||
return cb(null, c, stat)
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/glob/sync.js":
|
||
/*!***********************************!*\
|
||
!*** ./node_modules/glob/sync.js ***!
|
||
\***********************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
module.exports = globSync
|
||
globSync.GlobSync = GlobSync
|
||
|
||
var fs = __webpack_require__(/*! fs */ "fs")
|
||
var rp = __webpack_require__(/*! fs.realpath */ "./node_modules/fs.realpath/index.js")
|
||
var minimatch = __webpack_require__(/*! minimatch */ "./node_modules/minimatch/minimatch.js")
|
||
var Minimatch = minimatch.Minimatch
|
||
var Glob = __webpack_require__(/*! ./glob.js */ "./node_modules/glob/glob.js").Glob
|
||
var util = __webpack_require__(/*! util */ "util")
|
||
var path = __webpack_require__(/*! path */ "path")
|
||
var assert = __webpack_require__(/*! assert */ "assert")
|
||
var isAbsolute = __webpack_require__(/*! path-is-absolute */ "./node_modules/path-is-absolute/index.js")
|
||
var common = __webpack_require__(/*! ./common.js */ "./node_modules/glob/common.js")
|
||
var alphasort = common.alphasort
|
||
var alphasorti = common.alphasorti
|
||
var setopts = common.setopts
|
||
var ownProp = common.ownProp
|
||
var childrenIgnored = common.childrenIgnored
|
||
var isIgnored = common.isIgnored
|
||
|
||
function globSync (pattern, options) {
|
||
if (typeof options === 'function' || arguments.length === 3)
|
||
throw new TypeError('callback provided to sync glob\n'+
|
||
'See: https://github.com/isaacs/node-glob/issues/167')
|
||
|
||
return new GlobSync(pattern, options).found
|
||
}
|
||
|
||
function GlobSync (pattern, options) {
|
||
if (!pattern)
|
||
throw new Error('must provide pattern')
|
||
|
||
if (typeof options === 'function' || arguments.length === 3)
|
||
throw new TypeError('callback provided to sync glob\n'+
|
||
'See: https://github.com/isaacs/node-glob/issues/167')
|
||
|
||
if (!(this instanceof GlobSync))
|
||
return new GlobSync(pattern, options)
|
||
|
||
setopts(this, pattern, options)
|
||
|
||
if (this.noprocess)
|
||
return this
|
||
|
||
var n = this.minimatch.set.length
|
||
this.matches = new Array(n)
|
||
for (var i = 0; i < n; i ++) {
|
||
this._process(this.minimatch.set[i], i, false)
|
||
}
|
||
this._finish()
|
||
}
|
||
|
||
GlobSync.prototype._finish = function () {
|
||
assert(this instanceof GlobSync)
|
||
if (this.realpath) {
|
||
var self = this
|
||
this.matches.forEach(function (matchset, index) {
|
||
var set = self.matches[index] = Object.create(null)
|
||
for (var p in matchset) {
|
||
try {
|
||
p = self._makeAbs(p)
|
||
var real = rp.realpathSync(p, self.realpathCache)
|
||
set[real] = true
|
||
} catch (er) {
|
||
if (er.syscall === 'stat')
|
||
set[self._makeAbs(p)] = true
|
||
else
|
||
throw er
|
||
}
|
||
}
|
||
})
|
||
}
|
||
common.finish(this)
|
||
}
|
||
|
||
|
||
GlobSync.prototype._process = function (pattern, index, inGlobStar) {
|
||
assert(this instanceof GlobSync)
|
||
|
||
// Get the first [n] parts of pattern that are all strings.
|
||
var n = 0
|
||
while (typeof pattern[n] === 'string') {
|
||
n ++
|
||
}
|
||
// now n is the index of the first one that is *not* a string.
|
||
|
||
// See if there's anything else
|
||
var prefix
|
||
switch (n) {
|
||
// if not, then this is rather simple
|
||
case pattern.length:
|
||
this._processSimple(pattern.join('/'), index)
|
||
return
|
||
|
||
case 0:
|
||
// pattern *starts* with some non-trivial item.
|
||
// going to readdir(cwd), but not include the prefix in matches.
|
||
prefix = null
|
||
break
|
||
|
||
default:
|
||
// pattern has some string bits in the front.
|
||
// whatever it starts with, whether that's 'absolute' like /foo/bar,
|
||
// or 'relative' like '../baz'
|
||
prefix = pattern.slice(0, n).join('/')
|
||
break
|
||
}
|
||
|
||
var remain = pattern.slice(n)
|
||
|
||
// get the list of entries.
|
||
var read
|
||
if (prefix === null)
|
||
read = '.'
|
||
else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) {
|
||
if (!prefix || !isAbsolute(prefix))
|
||
prefix = '/' + prefix
|
||
read = prefix
|
||
} else
|
||
read = prefix
|
||
|
||
var abs = this._makeAbs(read)
|
||
|
||
//if ignored, skip processing
|
||
if (childrenIgnored(this, read))
|
||
return
|
||
|
||
var isGlobStar = remain[0] === minimatch.GLOBSTAR
|
||
if (isGlobStar)
|
||
this._processGlobStar(prefix, read, abs, remain, index, inGlobStar)
|
||
else
|
||
this._processReaddir(prefix, read, abs, remain, index, inGlobStar)
|
||
}
|
||
|
||
|
||
GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) {
|
||
var entries = this._readdir(abs, inGlobStar)
|
||
|
||
// if the abs isn't a dir, then nothing can match!
|
||
if (!entries)
|
||
return
|
||
|
||
// It will only match dot entries if it starts with a dot, or if
|
||
// dot is set. Stuff like @(.foo|.bar) isn't allowed.
|
||
var pn = remain[0]
|
||
var negate = !!this.minimatch.negate
|
||
var rawGlob = pn._glob
|
||
var dotOk = this.dot || rawGlob.charAt(0) === '.'
|
||
|
||
var matchedEntries = []
|
||
for (var i = 0; i < entries.length; i++) {
|
||
var e = entries[i]
|
||
if (e.charAt(0) !== '.' || dotOk) {
|
||
var m
|
||
if (negate && !prefix) {
|
||
m = !e.match(pn)
|
||
} else {
|
||
m = e.match(pn)
|
||
}
|
||
if (m)
|
||
matchedEntries.push(e)
|
||
}
|
||
}
|
||
|
||
var len = matchedEntries.length
|
||
// If there are no matched entries, then nothing matches.
|
||
if (len === 0)
|
||
return
|
||
|
||
// if this is the last remaining pattern bit, then no need for
|
||
// an additional stat *unless* the user has specified mark or
|
||
// stat explicitly. We know they exist, since readdir returned
|
||
// them.
|
||
|
||
if (remain.length === 1 && !this.mark && !this.stat) {
|
||
if (!this.matches[index])
|
||
this.matches[index] = Object.create(null)
|
||
|
||
for (var i = 0; i < len; i ++) {
|
||
var e = matchedEntries[i]
|
||
if (prefix) {
|
||
if (prefix.slice(-1) !== '/')
|
||
e = prefix + '/' + e
|
||
else
|
||
e = prefix + e
|
||
}
|
||
|
||
if (e.charAt(0) === '/' && !this.nomount) {
|
||
e = path.join(this.root, e)
|
||
}
|
||
this._emitMatch(index, e)
|
||
}
|
||
// This was the last one, and no stats were needed
|
||
return
|
||
}
|
||
|
||
// now test all matched entries as stand-ins for that part
|
||
// of the pattern.
|
||
remain.shift()
|
||
for (var i = 0; i < len; i ++) {
|
||
var e = matchedEntries[i]
|
||
var newPattern
|
||
if (prefix)
|
||
newPattern = [prefix, e]
|
||
else
|
||
newPattern = [e]
|
||
this._process(newPattern.concat(remain), index, inGlobStar)
|
||
}
|
||
}
|
||
|
||
|
||
GlobSync.prototype._emitMatch = function (index, e) {
|
||
if (isIgnored(this, e))
|
||
return
|
||
|
||
var abs = this._makeAbs(e)
|
||
|
||
if (this.mark)
|
||
e = this._mark(e)
|
||
|
||
if (this.absolute) {
|
||
e = abs
|
||
}
|
||
|
||
if (this.matches[index][e])
|
||
return
|
||
|
||
if (this.nodir) {
|
||
var c = this.cache[abs]
|
||
if (c === 'DIR' || Array.isArray(c))
|
||
return
|
||
}
|
||
|
||
this.matches[index][e] = true
|
||
|
||
if (this.stat)
|
||
this._stat(e)
|
||
}
|
||
|
||
|
||
GlobSync.prototype._readdirInGlobStar = function (abs) {
|
||
// follow all symlinked directories forever
|
||
// just proceed as if this is a non-globstar situation
|
||
if (this.follow)
|
||
return this._readdir(abs, false)
|
||
|
||
var entries
|
||
var lstat
|
||
var stat
|
||
try {
|
||
lstat = fs.lstatSync(abs)
|
||
} catch (er) {
|
||
if (er.code === 'ENOENT') {
|
||
// lstat failed, doesn't exist
|
||
return null
|
||
}
|
||
}
|
||
|
||
var isSym = lstat && lstat.isSymbolicLink()
|
||
this.symlinks[abs] = isSym
|
||
|
||
// If it's not a symlink or a dir, then it's definitely a regular file.
|
||
// don't bother doing a readdir in that case.
|
||
if (!isSym && lstat && !lstat.isDirectory())
|
||
this.cache[abs] = 'FILE'
|
||
else
|
||
entries = this._readdir(abs, false)
|
||
|
||
return entries
|
||
}
|
||
|
||
GlobSync.prototype._readdir = function (abs, inGlobStar) {
|
||
var entries
|
||
|
||
if (inGlobStar && !ownProp(this.symlinks, abs))
|
||
return this._readdirInGlobStar(abs)
|
||
|
||
if (ownProp(this.cache, abs)) {
|
||
var c = this.cache[abs]
|
||
if (!c || c === 'FILE')
|
||
return null
|
||
|
||
if (Array.isArray(c))
|
||
return c
|
||
}
|
||
|
||
try {
|
||
return this._readdirEntries(abs, fs.readdirSync(abs))
|
||
} catch (er) {
|
||
this._readdirError(abs, er)
|
||
return null
|
||
}
|
||
}
|
||
|
||
GlobSync.prototype._readdirEntries = function (abs, entries) {
|
||
// if we haven't asked to stat everything, then just
|
||
// assume that everything in there exists, so we can avoid
|
||
// having to stat it a second time.
|
||
if (!this.mark && !this.stat) {
|
||
for (var i = 0; i < entries.length; i ++) {
|
||
var e = entries[i]
|
||
if (abs === '/')
|
||
e = abs + e
|
||
else
|
||
e = abs + '/' + e
|
||
this.cache[e] = true
|
||
}
|
||
}
|
||
|
||
this.cache[abs] = entries
|
||
|
||
// mark and cache dir-ness
|
||
return entries
|
||
}
|
||
|
||
GlobSync.prototype._readdirError = function (f, er) {
|
||
// handle errors, and cache the information
|
||
switch (er.code) {
|
||
case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205
|
||
case 'ENOTDIR': // totally normal. means it *does* exist.
|
||
var abs = this._makeAbs(f)
|
||
this.cache[abs] = 'FILE'
|
||
if (abs === this.cwdAbs) {
|
||
var error = new Error(er.code + ' invalid cwd ' + this.cwd)
|
||
error.path = this.cwd
|
||
error.code = er.code
|
||
throw error
|
||
}
|
||
break
|
||
|
||
case 'ENOENT': // not terribly unusual
|
||
case 'ELOOP':
|
||
case 'ENAMETOOLONG':
|
||
case 'UNKNOWN':
|
||
this.cache[this._makeAbs(f)] = false
|
||
break
|
||
|
||
default: // some unusual error. Treat as failure.
|
||
this.cache[this._makeAbs(f)] = false
|
||
if (this.strict)
|
||
throw er
|
||
if (!this.silent)
|
||
console.error('glob error', er)
|
||
break
|
||
}
|
||
}
|
||
|
||
GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) {
|
||
|
||
var entries = this._readdir(abs, inGlobStar)
|
||
|
||
// no entries means not a dir, so it can never have matches
|
||
// foo.txt/** doesn't match foo.txt
|
||
if (!entries)
|
||
return
|
||
|
||
// test without the globstar, and with every child both below
|
||
// and replacing the globstar.
|
||
var remainWithoutGlobStar = remain.slice(1)
|
||
var gspref = prefix ? [ prefix ] : []
|
||
var noGlobStar = gspref.concat(remainWithoutGlobStar)
|
||
|
||
// the noGlobStar pattern exits the inGlobStar state
|
||
this._process(noGlobStar, index, false)
|
||
|
||
var len = entries.length
|
||
var isSym = this.symlinks[abs]
|
||
|
||
// If it's a symlink, and we're in a globstar, then stop
|
||
if (isSym && inGlobStar)
|
||
return
|
||
|
||
for (var i = 0; i < len; i++) {
|
||
var e = entries[i]
|
||
if (e.charAt(0) === '.' && !this.dot)
|
||
continue
|
||
|
||
// these two cases enter the inGlobStar state
|
||
var instead = gspref.concat(entries[i], remainWithoutGlobStar)
|
||
this._process(instead, index, true)
|
||
|
||
var below = gspref.concat(entries[i], remain)
|
||
this._process(below, index, true)
|
||
}
|
||
}
|
||
|
||
GlobSync.prototype._processSimple = function (prefix, index) {
|
||
// XXX review this. Shouldn't it be doing the mounting etc
|
||
// before doing stat? kinda weird?
|
||
var exists = this._stat(prefix)
|
||
|
||
if (!this.matches[index])
|
||
this.matches[index] = Object.create(null)
|
||
|
||
// If it doesn't exist, then just mark the lack of results
|
||
if (!exists)
|
||
return
|
||
|
||
if (prefix && isAbsolute(prefix) && !this.nomount) {
|
||
var trail = /[\/\\]$/.test(prefix)
|
||
if (prefix.charAt(0) === '/') {
|
||
prefix = path.join(this.root, prefix)
|
||
} else {
|
||
prefix = path.resolve(this.root, prefix)
|
||
if (trail)
|
||
prefix += '/'
|
||
}
|
||
}
|
||
|
||
if (process.platform === 'win32')
|
||
prefix = prefix.replace(/\\/g, '/')
|
||
|
||
// Mark this as a match
|
||
this._emitMatch(index, prefix)
|
||
}
|
||
|
||
// Returns either 'DIR', 'FILE', or false
|
||
GlobSync.prototype._stat = function (f) {
|
||
var abs = this._makeAbs(f)
|
||
var needDir = f.slice(-1) === '/'
|
||
|
||
if (f.length > this.maxLength)
|
||
return false
|
||
|
||
if (!this.stat && ownProp(this.cache, abs)) {
|
||
var c = this.cache[abs]
|
||
|
||
if (Array.isArray(c))
|
||
c = 'DIR'
|
||
|
||
// It exists, but maybe not how we need it
|
||
if (!needDir || c === 'DIR')
|
||
return c
|
||
|
||
if (needDir && c === 'FILE')
|
||
return false
|
||
|
||
// otherwise we have to stat, because maybe c=true
|
||
// if we know it exists, but not what it is.
|
||
}
|
||
|
||
var exists
|
||
var stat = this.statCache[abs]
|
||
if (!stat) {
|
||
var lstat
|
||
try {
|
||
lstat = fs.lstatSync(abs)
|
||
} catch (er) {
|
||
if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) {
|
||
this.statCache[abs] = false
|
||
return false
|
||
}
|
||
}
|
||
|
||
if (lstat && lstat.isSymbolicLink()) {
|
||
try {
|
||
stat = fs.statSync(abs)
|
||
} catch (er) {
|
||
stat = lstat
|
||
}
|
||
} else {
|
||
stat = lstat
|
||
}
|
||
}
|
||
|
||
this.statCache[abs] = stat
|
||
|
||
var c = true
|
||
if (stat)
|
||
c = stat.isDirectory() ? 'DIR' : 'FILE'
|
||
|
||
this.cache[abs] = this.cache[abs] || c
|
||
|
||
if (needDir && c === 'FILE')
|
||
return false
|
||
|
||
return c
|
||
}
|
||
|
||
GlobSync.prototype._mark = function (p) {
|
||
return common.mark(this, p)
|
||
}
|
||
|
||
GlobSync.prototype._makeAbs = function (f) {
|
||
return common.makeAbs(this, f)
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inflight/inflight.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/inflight/inflight.js ***!
|
||
\*******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var wrappy = __webpack_require__(/*! wrappy */ "./node_modules/wrappy/wrappy.js")
|
||
var reqs = Object.create(null)
|
||
var once = __webpack_require__(/*! once */ "./node_modules/once/once.js")
|
||
|
||
module.exports = wrappy(inflight)
|
||
|
||
function inflight (key, cb) {
|
||
if (reqs[key]) {
|
||
reqs[key].push(cb)
|
||
return null
|
||
} else {
|
||
reqs[key] = [cb]
|
||
return makeres(key)
|
||
}
|
||
}
|
||
|
||
function makeres (key) {
|
||
return once(function RES () {
|
||
var cbs = reqs[key]
|
||
var len = cbs.length
|
||
var args = slice(arguments)
|
||
|
||
// XXX It's somewhat ambiguous whether a new callback added in this
|
||
// pass should be queued for later execution if something in the
|
||
// list of callbacks throws, or if it should just be discarded.
|
||
// However, it's such an edge case that it hardly matters, and either
|
||
// choice is likely as surprising as the other.
|
||
// As it happens, we do go ahead and schedule it for later execution.
|
||
try {
|
||
for (var i = 0; i < len; i++) {
|
||
cbs[i].apply(null, args)
|
||
}
|
||
} finally {
|
||
if (cbs.length > len) {
|
||
// added more in the interim.
|
||
// de-zalgo, just in case, but don't call again.
|
||
cbs.splice(0, len)
|
||
process.nextTick(function () {
|
||
RES.apply(null, args)
|
||
})
|
||
} else {
|
||
delete reqs[key]
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
function slice (args) {
|
||
var length = args.length
|
||
var array = []
|
||
|
||
for (var i = 0; i < length; i++) array[i] = args[i]
|
||
return array
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inherits/inherits.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/inherits/inherits.js ***!
|
||
\*******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
try {
|
||
var util = __webpack_require__(/*! util */ "util");
|
||
/* istanbul ignore next */
|
||
if (typeof util.inherits !== 'function') throw '';
|
||
module.exports = util.inherits;
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
module.exports = __webpack_require__(/*! ./inherits_browser.js */ "./node_modules/inherits/inherits_browser.js");
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inherits/inherits_browser.js":
|
||
/*!***************************************************!*\
|
||
!*** ./node_modules/inherits/inherits_browser.js ***!
|
||
\***************************************************/
|
||
/***/ ((module) => {
|
||
|
||
if (typeof Object.create === 'function') {
|
||
// implementation from standard node.js 'util' module
|
||
module.exports = function inherits(ctor, superCtor) {
|
||
if (superCtor) {
|
||
ctor.super_ = superCtor
|
||
ctor.prototype = Object.create(superCtor.prototype, {
|
||
constructor: {
|
||
value: ctor,
|
||
enumerable: false,
|
||
writable: true,
|
||
configurable: true
|
||
}
|
||
})
|
||
}
|
||
};
|
||
} else {
|
||
// old school shim for old browsers
|
||
module.exports = function inherits(ctor, superCtor) {
|
||
if (superCtor) {
|
||
ctor.super_ = superCtor
|
||
var TempCtor = function () {}
|
||
TempCtor.prototype = superCtor.prototype
|
||
ctor.prototype = new TempCtor()
|
||
ctor.prototype.constructor = ctor
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/decorator_utils.js":
|
||
/*!******************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/decorator_utils.js ***!
|
||
\******************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.tagProperty = exports.tagParameter = exports.decorate = void 0;
|
||
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;
|
||
//# sourceMappingURL=decorator_utils.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/inject.js":
|
||
/*!*********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/inject.js ***!
|
||
\*********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.inject = exports.LazyServiceIdentifer = void 0;
|
||
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;
|
||
//# sourceMappingURL=inject.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/injectable.js":
|
||
/*!*************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/injectable.js ***!
|
||
\*************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.injectable = void 0;
|
||
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;
|
||
//# sourceMappingURL=injectable.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/multi_inject.js":
|
||
/*!***************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/multi_inject.js ***!
|
||
\***************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.multiInject = void 0;
|
||
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;
|
||
//# sourceMappingURL=multi_inject.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/named.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/named.js ***!
|
||
\********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.named = void 0;
|
||
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;
|
||
//# sourceMappingURL=named.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/optional.js":
|
||
/*!***********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/optional.js ***!
|
||
\***********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.optional = void 0;
|
||
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;
|
||
//# sourceMappingURL=optional.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/post_construct.js":
|
||
/*!*****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/post_construct.js ***!
|
||
\*****************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.postConstruct = void 0;
|
||
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;
|
||
//# sourceMappingURL=post_construct.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/tagged.js":
|
||
/*!*********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/tagged.js ***!
|
||
\*********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.tagged = void 0;
|
||
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;
|
||
//# sourceMappingURL=tagged.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/target_name.js":
|
||
/*!**************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/target_name.js ***!
|
||
\**************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.targetName = void 0;
|
||
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;
|
||
//# sourceMappingURL=target_name.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/unmanaged.js":
|
||
/*!************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/unmanaged.js ***!
|
||
\************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.unmanaged = void 0;
|
||
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;
|
||
//# sourceMappingURL=unmanaged.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/bindings/binding.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/bindings/binding.js ***!
|
||
\********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Binding = void 0;
|
||
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 = (clone.scope === literal_types_1.BindingScopeEnum.Singleton) ? this.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;
|
||
//# sourceMappingURL=binding.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/bindings/binding_count.js":
|
||
/*!**************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/bindings/binding_count.js ***!
|
||
\**************************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.BindingCount = void 0;
|
||
var BindingCount = {
|
||
MultipleBindingsAvailable: 2,
|
||
NoBindingsAvailable: 0,
|
||
OnlyOneBindingAvailable: 1
|
||
};
|
||
exports.BindingCount = BindingCount;
|
||
//# sourceMappingURL=binding_count.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/constants/error_msgs.js":
|
||
/*!************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/constants/error_msgs.js ***!
|
||
\************************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.STACK_OVERFLOW = exports.CIRCULAR_DEPENDENCY_IN_FACTORY = exports.POST_CONSTRUCT_ERROR = exports.MULTIPLE_POST_CONSTRUCT_METHODS = exports.CONTAINER_OPTIONS_INVALID_SKIP_BASE_CHECK = exports.CONTAINER_OPTIONS_INVALID_AUTO_BIND_INJECTABLE = exports.CONTAINER_OPTIONS_INVALID_DEFAULT_SCOPE = exports.CONTAINER_OPTIONS_MUST_BE_AN_OBJECT = exports.ARGUMENTS_LENGTH_MISMATCH = exports.INVALID_DECORATOR_OPERATION = exports.INVALID_TO_SELF_VALUE = exports.INVALID_FUNCTION_BINDING = exports.INVALID_MIDDLEWARE_RETURN = exports.NO_MORE_SNAPSHOTS_AVAILABLE = exports.INVALID_BINDING_TYPE = exports.NOT_IMPLEMENTED = exports.CIRCULAR_DEPENDENCY = exports.UNDEFINED_INJECT_ANNOTATION = exports.MISSING_INJECT_ANNOTATION = exports.MISSING_INJECTABLE_ANNOTATION = exports.NOT_REGISTERED = exports.CANNOT_UNBIND = exports.AMBIGUOUS_MATCH = exports.KEY_NOT_FOUND = exports.NULL_ARGUMENT = exports.DUPLICATED_METADATA = exports.DUPLICATED_INJECTABLE_DECORATOR = void 0;
|
||
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:";
|
||
var 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.UNDEFINED_INJECT_ANNOTATION = UNDEFINED_INJECT_ANNOTATION;
|
||
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.";
|
||
var 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.ARGUMENTS_LENGTH_MISMATCH = ARGUMENTS_LENGTH_MISMATCH;
|
||
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";
|
||
var 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.POST_CONSTRUCT_ERROR = POST_CONSTRUCT_ERROR;
|
||
var 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.CIRCULAR_DEPENDENCY_IN_FACTORY = CIRCULAR_DEPENDENCY_IN_FACTORY;
|
||
exports.STACK_OVERFLOW = "Maximum call stack size exceeded";
|
||
//# sourceMappingURL=error_msgs.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/constants/literal_types.js":
|
||
/*!***************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/constants/literal_types.js ***!
|
||
\***************************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.TargetTypeEnum = exports.BindingTypeEnum = exports.BindingScopeEnum = void 0;
|
||
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;
|
||
//# sourceMappingURL=literal_types.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/constants/metadata_keys.js":
|
||
/*!***************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/constants/metadata_keys.js ***!
|
||
\***************************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.NON_CUSTOM_TAG_KEYS = exports.POST_CONSTRUCT = exports.DESIGN_PARAM_TYPES = exports.PARAM_TYPES = exports.TAGGED_PROP = exports.TAGGED = exports.MULTI_INJECT_TAG = exports.INJECT_TAG = exports.OPTIONAL_TAG = exports.UNMANAGED_TAG = exports.NAME_TAG = exports.NAMED_TAG = void 0;
|
||
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";
|
||
function getNonCustomTagKeys() {
|
||
return [
|
||
exports.INJECT_TAG,
|
||
exports.MULTI_INJECT_TAG,
|
||
exports.NAME_TAG,
|
||
exports.UNMANAGED_TAG,
|
||
exports.NAMED_TAG,
|
||
exports.OPTIONAL_TAG,
|
||
];
|
||
}
|
||
exports.NON_CUSTOM_TAG_KEYS = getNonCustomTagKeys();
|
||
//# sourceMappingURL=metadata_keys.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/container/container.js":
|
||
/*!***********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/container/container.js ***!
|
||
\***********************************************************/
|
||
/***/ (function(__unused_webpack_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 __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 = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||
if (y = 0, t) op = [op[0] & 2, 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 };
|
||
}
|
||
};
|
||
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
||
to[j] = from[i];
|
||
return to;
|
||
};
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Container = void 0;
|
||
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) {
|
||
this._appliedMiddleware = [];
|
||
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 container3 = [];
|
||
for (var _i = 2; _i < arguments.length; _i++) {
|
||
container3[_i - 2] = arguments[_i];
|
||
}
|
||
var container = new Container();
|
||
var targetContainers = __spreadArray([container1, container2], container3).map(function (targetContainer) { return planner_1.getBindingDictionary(targetContainer); });
|
||
var bindingDictionary = planner_1.getBindingDictionary(container);
|
||
function copyDictionary(origin, destination) {
|
||
origin.traverse(function (key, value) {
|
||
value.forEach(function (binding) {
|
||
destination.add(binding.serviceIdentifier, binding.clone());
|
||
});
|
||
});
|
||
}
|
||
targetContainers.forEach(function (targetBindingDictionary) {
|
||
copyDictionary(targetBindingDictionary, 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];
|
||
}
|
||
this._appliedMiddleware = this._appliedMiddleware.concat(middlewares);
|
||
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();
|
||
this._appliedMiddleware.forEach(function (m) {
|
||
tempContainer.applyMiddleware(m);
|
||
});
|
||
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;
|
||
//# sourceMappingURL=container.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/container/container_module.js":
|
||
/*!******************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/container/container_module.js ***!
|
||
\******************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.AsyncContainerModule = exports.ContainerModule = void 0;
|
||
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;
|
||
//# sourceMappingURL=container_module.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/container/container_snapshot.js":
|
||
/*!********************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/container/container_snapshot.js ***!
|
||
\********************************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.ContainerSnapshot = void 0;
|
||
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;
|
||
//# sourceMappingURL=container_snapshot.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/container/lookup.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/container/lookup.js ***!
|
||
\********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Lookup = void 0;
|
||
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;
|
||
//# sourceMappingURL=lookup.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/inversify.js":
|
||
/*!*************************************************!*\
|
||
!*** ./node_modules/inversify/lib/inversify.js ***!
|
||
\*************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.multiBindToService = exports.getServiceIdentifierAsString = exports.typeConstraint = exports.namedConstraint = exports.taggedConstraint = exports.traverseAncerstors = exports.decorate = exports.id = exports.MetadataReader = exports.postConstruct = exports.targetName = exports.multiInject = exports.unmanaged = exports.optional = exports.LazyServiceIdentifer = exports.inject = exports.named = exports.tagged = exports.injectable = exports.ContainerModule = exports.AsyncContainerModule = exports.TargetTypeEnum = exports.BindingTypeEnum = exports.BindingScopeEnum = exports.Container = exports.METADATA_KEY = void 0;
|
||
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");
|
||
Object.defineProperty(exports, "Container", ({ enumerable: true, get: function () { return container_1.Container; } }));
|
||
var literal_types_1 = __webpack_require__(/*! ./constants/literal_types */ "./node_modules/inversify/lib/constants/literal_types.js");
|
||
Object.defineProperty(exports, "BindingScopeEnum", ({ enumerable: true, get: function () { return literal_types_1.BindingScopeEnum; } }));
|
||
Object.defineProperty(exports, "BindingTypeEnum", ({ enumerable: true, get: function () { return literal_types_1.BindingTypeEnum; } }));
|
||
Object.defineProperty(exports, "TargetTypeEnum", ({ enumerable: true, get: function () { return literal_types_1.TargetTypeEnum; } }));
|
||
var container_module_1 = __webpack_require__(/*! ./container/container_module */ "./node_modules/inversify/lib/container/container_module.js");
|
||
Object.defineProperty(exports, "AsyncContainerModule", ({ enumerable: true, get: function () { return container_module_1.AsyncContainerModule; } }));
|
||
Object.defineProperty(exports, "ContainerModule", ({ enumerable: true, get: function () { return container_module_1.ContainerModule; } }));
|
||
var injectable_1 = __webpack_require__(/*! ./annotation/injectable */ "./node_modules/inversify/lib/annotation/injectable.js");
|
||
Object.defineProperty(exports, "injectable", ({ enumerable: true, get: function () { return injectable_1.injectable; } }));
|
||
var tagged_1 = __webpack_require__(/*! ./annotation/tagged */ "./node_modules/inversify/lib/annotation/tagged.js");
|
||
Object.defineProperty(exports, "tagged", ({ enumerable: true, get: function () { return tagged_1.tagged; } }));
|
||
var named_1 = __webpack_require__(/*! ./annotation/named */ "./node_modules/inversify/lib/annotation/named.js");
|
||
Object.defineProperty(exports, "named", ({ enumerable: true, get: function () { return named_1.named; } }));
|
||
var inject_1 = __webpack_require__(/*! ./annotation/inject */ "./node_modules/inversify/lib/annotation/inject.js");
|
||
Object.defineProperty(exports, "inject", ({ enumerable: true, get: function () { return inject_1.inject; } }));
|
||
Object.defineProperty(exports, "LazyServiceIdentifer", ({ enumerable: true, get: function () { return inject_1.LazyServiceIdentifer; } }));
|
||
var optional_1 = __webpack_require__(/*! ./annotation/optional */ "./node_modules/inversify/lib/annotation/optional.js");
|
||
Object.defineProperty(exports, "optional", ({ enumerable: true, get: function () { return optional_1.optional; } }));
|
||
var unmanaged_1 = __webpack_require__(/*! ./annotation/unmanaged */ "./node_modules/inversify/lib/annotation/unmanaged.js");
|
||
Object.defineProperty(exports, "unmanaged", ({ enumerable: true, get: function () { return unmanaged_1.unmanaged; } }));
|
||
var multi_inject_1 = __webpack_require__(/*! ./annotation/multi_inject */ "./node_modules/inversify/lib/annotation/multi_inject.js");
|
||
Object.defineProperty(exports, "multiInject", ({ enumerable: true, get: function () { return multi_inject_1.multiInject; } }));
|
||
var target_name_1 = __webpack_require__(/*! ./annotation/target_name */ "./node_modules/inversify/lib/annotation/target_name.js");
|
||
Object.defineProperty(exports, "targetName", ({ enumerable: true, get: function () { return target_name_1.targetName; } }));
|
||
var post_construct_1 = __webpack_require__(/*! ./annotation/post_construct */ "./node_modules/inversify/lib/annotation/post_construct.js");
|
||
Object.defineProperty(exports, "postConstruct", ({ enumerable: true, get: function () { return post_construct_1.postConstruct; } }));
|
||
var metadata_reader_1 = __webpack_require__(/*! ./planning/metadata_reader */ "./node_modules/inversify/lib/planning/metadata_reader.js");
|
||
Object.defineProperty(exports, "MetadataReader", ({ enumerable: true, get: function () { return metadata_reader_1.MetadataReader; } }));
|
||
var id_1 = __webpack_require__(/*! ./utils/id */ "./node_modules/inversify/lib/utils/id.js");
|
||
Object.defineProperty(exports, "id", ({ enumerable: true, get: function () { return id_1.id; } }));
|
||
var decorator_utils_1 = __webpack_require__(/*! ./annotation/decorator_utils */ "./node_modules/inversify/lib/annotation/decorator_utils.js");
|
||
Object.defineProperty(exports, "decorate", ({ enumerable: true, get: function () { return decorator_utils_1.decorate; } }));
|
||
var constraint_helpers_1 = __webpack_require__(/*! ./syntax/constraint_helpers */ "./node_modules/inversify/lib/syntax/constraint_helpers.js");
|
||
Object.defineProperty(exports, "traverseAncerstors", ({ enumerable: true, get: function () { return constraint_helpers_1.traverseAncerstors; } }));
|
||
Object.defineProperty(exports, "taggedConstraint", ({ enumerable: true, get: function () { return constraint_helpers_1.taggedConstraint; } }));
|
||
Object.defineProperty(exports, "namedConstraint", ({ enumerable: true, get: function () { return constraint_helpers_1.namedConstraint; } }));
|
||
Object.defineProperty(exports, "typeConstraint", ({ enumerable: true, get: function () { return constraint_helpers_1.typeConstraint; } }));
|
||
var serialization_1 = __webpack_require__(/*! ./utils/serialization */ "./node_modules/inversify/lib/utils/serialization.js");
|
||
Object.defineProperty(exports, "getServiceIdentifierAsString", ({ enumerable: true, get: function () { return serialization_1.getServiceIdentifierAsString; } }));
|
||
var binding_utils_1 = __webpack_require__(/*! ./utils/binding_utils */ "./node_modules/inversify/lib/utils/binding_utils.js");
|
||
Object.defineProperty(exports, "multiBindToService", ({ enumerable: true, get: function () { return binding_utils_1.multiBindToService; } }));
|
||
//# sourceMappingURL=inversify.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/planning/context.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/planning/context.js ***!
|
||
\********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Context = void 0;
|
||
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;
|
||
//# sourceMappingURL=context.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/planning/metadata.js":
|
||
/*!*********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/planning/metadata.js ***!
|
||
\*********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Metadata = void 0;
|
||
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;
|
||
//# sourceMappingURL=metadata.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/planning/metadata_reader.js":
|
||
/*!****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/planning/metadata_reader.js ***!
|
||
\****************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.MetadataReader = void 0;
|
||
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;
|
||
//# sourceMappingURL=metadata_reader.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/planning/plan.js":
|
||
/*!*****************************************************!*\
|
||
!*** ./node_modules/inversify/lib/planning/plan.js ***!
|
||
\*****************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Plan = void 0;
|
||
var Plan = (function () {
|
||
function Plan(parentContext, rootRequest) {
|
||
this.parentContext = parentContext;
|
||
this.rootRequest = rootRequest;
|
||
}
|
||
return Plan;
|
||
}());
|
||
exports.Plan = Plan;
|
||
//# sourceMappingURL=plan.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/planning/planner.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/planning/planner.js ***!
|
||
\********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.getBindingDictionary = exports.createMockRequest = exports.plan = void 0;
|
||
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;
|
||
//# sourceMappingURL=planner.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/planning/queryable_string.js":
|
||
/*!*****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/planning/queryable_string.js ***!
|
||
\*****************************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.QueryableString = void 0;
|
||
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;
|
||
//# sourceMappingURL=queryable_string.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/planning/reflection_utils.js":
|
||
/*!*****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/planning/reflection_utils.js ***!
|
||
\*****************************************************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
||
to[j] = from[i];
|
||
return to;
|
||
};
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.getFunctionName = exports.getBaseClassDependencyCount = exports.getDependencies = void 0;
|
||
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");
|
||
Object.defineProperty(exports, "getFunctionName", ({ enumerable: true, get: function () { return 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 hasOptionalParameters = keys.length > func.length;
|
||
var iterations = (hasUserDeclaredUnknownInjections || hasOptionalParameters) ? keys.length : func.length;
|
||
var constructorTargets = getConstructorArgsAsTargets(isBaseClass, constructorName, serviceIdentifiers, constructorArgsMetadata, iterations);
|
||
var propertyTargets = getClassPropsAsTargets(metadataReader, func);
|
||
var targets = __spreadArray(__spreadArray([], constructorTargets), 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 = __spreadArray(__spreadArray([], targets), 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]
|
||
};
|
||
}
|
||
//# sourceMappingURL=reflection_utils.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/planning/request.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/planning/request.js ***!
|
||
\********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Request = void 0;
|
||
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;
|
||
//# sourceMappingURL=request.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/planning/target.js":
|
||
/*!*******************************************************!*\
|
||
!*** ./node_modules/inversify/lib/planning/target.js ***!
|
||
\*******************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Target = void 0;
|
||
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 (metadata) { return METADATA_KEY.NON_CUSTOM_TAG_KEYS.every(function (key) { return metadata.key !== key; }); });
|
||
};
|
||
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 (metadata) { return METADATA_KEY.NON_CUSTOM_TAG_KEYS.every(function (key) { return metadata.key !== key; }); });
|
||
}
|
||
else {
|
||
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;
|
||
//# sourceMappingURL=target.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/resolution/instantiation.js":
|
||
/*!****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/resolution/instantiation.js ***!
|
||
\****************************************************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
||
to[j] = from[i];
|
||
return to;
|
||
};
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.resolveInstance = void 0;
|
||
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, __spreadArray([void 0], 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;
|
||
//# sourceMappingURL=instantiation.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/resolution/resolver.js":
|
||
/*!***********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/resolution/resolver.js ***!
|
||
\***********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.resolve = void 0;
|
||
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;
|
||
binding_1.activated = true;
|
||
}
|
||
else if (binding_1.type === literal_types_1.BindingTypeEnum.Function) {
|
||
result = binding_1.cache;
|
||
binding_1.activated = true;
|
||
}
|
||
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;
|
||
//# sourceMappingURL=resolver.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/syntax/binding_in_syntax.js":
|
||
/*!****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/syntax/binding_in_syntax.js ***!
|
||
\****************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.BindingInSyntax = void 0;
|
||
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;
|
||
//# sourceMappingURL=binding_in_syntax.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/syntax/binding_in_when_on_syntax.js":
|
||
/*!************************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/syntax/binding_in_when_on_syntax.js ***!
|
||
\************************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.BindingInWhenOnSyntax = void 0;
|
||
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;
|
||
//# sourceMappingURL=binding_in_when_on_syntax.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/syntax/binding_on_syntax.js":
|
||
/*!****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/syntax/binding_on_syntax.js ***!
|
||
\****************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.BindingOnSyntax = void 0;
|
||
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;
|
||
//# sourceMappingURL=binding_on_syntax.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/syntax/binding_to_syntax.js":
|
||
/*!****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/syntax/binding_to_syntax.js ***!
|
||
\****************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.BindingToSyntax = void 0;
|
||
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;
|
||
this._binding.scope = literal_types_1.BindingScopeEnum.Singleton;
|
||
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;
|
||
this._binding.scope = literal_types_1.BindingScopeEnum.Singleton;
|
||
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;
|
||
this._binding.scope = literal_types_1.BindingScopeEnum.Singleton;
|
||
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;
|
||
this._binding.scope = literal_types_1.BindingScopeEnum.Singleton;
|
||
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;
|
||
};
|
||
this._binding.scope = literal_types_1.BindingScopeEnum.Singleton;
|
||
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;
|
||
this._binding.scope = literal_types_1.BindingScopeEnum.Singleton;
|
||
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;
|
||
//# sourceMappingURL=binding_to_syntax.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/syntax/binding_when_on_syntax.js":
|
||
/*!*********************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/syntax/binding_when_on_syntax.js ***!
|
||
\*********************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.BindingWhenOnSyntax = void 0;
|
||
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;
|
||
//# sourceMappingURL=binding_when_on_syntax.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/syntax/binding_when_syntax.js":
|
||
/*!******************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/syntax/binding_when_syntax.js ***!
|
||
\******************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.BindingWhenSyntax = void 0;
|
||
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;
|
||
//# sourceMappingURL=binding_when_syntax.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/syntax/constraint_helpers.js":
|
||
/*!*****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/syntax/constraint_helpers.js ***!
|
||
\*****************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.typeConstraint = exports.namedConstraint = exports.taggedConstraint = exports.traverseAncerstors = void 0;
|
||
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;
|
||
//# sourceMappingURL=constraint_helpers.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/utils/binding_utils.js":
|
||
/*!***********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/utils/binding_utils.js ***!
|
||
\***********************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.multiBindToService = void 0;
|
||
var 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); });
|
||
};
|
||
};
|
||
};
|
||
exports.multiBindToService = multiBindToService;
|
||
//# sourceMappingURL=binding_utils.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/utils/exceptions.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/utils/exceptions.js ***!
|
||
\********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.isStackOverflowExeption = void 0;
|
||
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;
|
||
//# sourceMappingURL=exceptions.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/utils/id.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/inversify/lib/utils/id.js ***!
|
||
\************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.id = void 0;
|
||
var idCounter = 0;
|
||
function id() {
|
||
return idCounter++;
|
||
}
|
||
exports.id = id;
|
||
//# sourceMappingURL=id.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/utils/serialization.js":
|
||
/*!***********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/utils/serialization.js ***!
|
||
\***********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.circularDependencyToException = exports.listMetadataForTarget = exports.listRegisteredBindingsForServiceIdentifier = exports.getServiceIdentifierAsString = exports.getFunctionName = void 0;
|
||
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;
|
||
//# sourceMappingURL=serialization.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/minimatch/minimatch.js":
|
||
/*!*********************************************!*\
|
||
!*** ./node_modules/minimatch/minimatch.js ***!
|
||
\*********************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
module.exports = minimatch
|
||
minimatch.Minimatch = Minimatch
|
||
|
||
var path = { sep: '/' }
|
||
try {
|
||
path = __webpack_require__(/*! path */ "path")
|
||
} catch (er) {}
|
||
|
||
var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
|
||
var expand = __webpack_require__(/*! brace-expansion */ "./node_modules/brace-expansion/index.js")
|
||
|
||
var plTypes = {
|
||
'!': { open: '(?:(?!(?:', close: '))[^/]*?)'},
|
||
'?': { open: '(?:', close: ')?' },
|
||
'+': { open: '(?:', close: ')+' },
|
||
'*': { open: '(?:', close: ')*' },
|
||
'@': { open: '(?:', close: ')' }
|
||
}
|
||
|
||
// any single thing other than /
|
||
// don't need to escape / when using new RegExp()
|
||
var qmark = '[^/]'
|
||
|
||
// * => any number of characters
|
||
var star = qmark + '*?'
|
||
|
||
// ** when dots are allowed. Anything goes, except .. and .
|
||
// not (^ or / followed by one or two dots followed by $ or /),
|
||
// followed by anything, any number of times.
|
||
var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'
|
||
|
||
// not a ^ or / followed by a dot,
|
||
// followed by anything, any number of times.
|
||
var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'
|
||
|
||
// characters that need to be escaped in RegExp.
|
||
var reSpecials = charSet('().*{}+?[]^$\\!')
|
||
|
||
// "abc" -> { a:true, b:true, c:true }
|
||
function charSet (s) {
|
||
return s.split('').reduce(function (set, c) {
|
||
set[c] = true
|
||
return set
|
||
}, {})
|
||
}
|
||
|
||
// normalizes slashes.
|
||
var slashSplit = /\/+/
|
||
|
||
minimatch.filter = filter
|
||
function filter (pattern, options) {
|
||
options = options || {}
|
||
return function (p, i, list) {
|
||
return minimatch(p, pattern, options)
|
||
}
|
||
}
|
||
|
||
function ext (a, b) {
|
||
a = a || {}
|
||
b = b || {}
|
||
var t = {}
|
||
Object.keys(b).forEach(function (k) {
|
||
t[k] = b[k]
|
||
})
|
||
Object.keys(a).forEach(function (k) {
|
||
t[k] = a[k]
|
||
})
|
||
return t
|
||
}
|
||
|
||
minimatch.defaults = function (def) {
|
||
if (!def || !Object.keys(def).length) return minimatch
|
||
|
||
var orig = minimatch
|
||
|
||
var m = function minimatch (p, pattern, options) {
|
||
return orig.minimatch(p, pattern, ext(def, options))
|
||
}
|
||
|
||
m.Minimatch = function Minimatch (pattern, options) {
|
||
return new orig.Minimatch(pattern, ext(def, options))
|
||
}
|
||
|
||
return m
|
||
}
|
||
|
||
Minimatch.defaults = function (def) {
|
||
if (!def || !Object.keys(def).length) return Minimatch
|
||
return minimatch.defaults(def).Minimatch
|
||
}
|
||
|
||
function minimatch (p, pattern, options) {
|
||
if (typeof pattern !== 'string') {
|
||
throw new TypeError('glob pattern string required')
|
||
}
|
||
|
||
if (!options) options = {}
|
||
|
||
// shortcut: comments match nothing.
|
||
if (!options.nocomment && pattern.charAt(0) === '#') {
|
||
return false
|
||
}
|
||
|
||
// "" only matches ""
|
||
if (pattern.trim() === '') return p === ''
|
||
|
||
return new Minimatch(pattern, options).match(p)
|
||
}
|
||
|
||
function Minimatch (pattern, options) {
|
||
if (!(this instanceof Minimatch)) {
|
||
return new Minimatch(pattern, options)
|
||
}
|
||
|
||
if (typeof pattern !== 'string') {
|
||
throw new TypeError('glob pattern string required')
|
||
}
|
||
|
||
if (!options) options = {}
|
||
pattern = pattern.trim()
|
||
|
||
// windows support: need to use /, not \
|
||
if (path.sep !== '/') {
|
||
pattern = pattern.split(path.sep).join('/')
|
||
}
|
||
|
||
this.options = options
|
||
this.set = []
|
||
this.pattern = pattern
|
||
this.regexp = null
|
||
this.negate = false
|
||
this.comment = false
|
||
this.empty = false
|
||
|
||
// make the set of regexps etc.
|
||
this.make()
|
||
}
|
||
|
||
Minimatch.prototype.debug = function () {}
|
||
|
||
Minimatch.prototype.make = make
|
||
function make () {
|
||
// don't do it more than once.
|
||
if (this._made) return
|
||
|
||
var pattern = this.pattern
|
||
var options = this.options
|
||
|
||
// empty patterns and comments match nothing.
|
||
if (!options.nocomment && pattern.charAt(0) === '#') {
|
||
this.comment = true
|
||
return
|
||
}
|
||
if (!pattern) {
|
||
this.empty = true
|
||
return
|
||
}
|
||
|
||
// step 1: figure out negation, etc.
|
||
this.parseNegate()
|
||
|
||
// step 2: expand braces
|
||
var set = this.globSet = this.braceExpand()
|
||
|
||
if (options.debug) this.debug = console.error
|
||
|
||
this.debug(this.pattern, set)
|
||
|
||
// step 3: now we have a set, so turn each one into a series of path-portion
|
||
// matching patterns.
|
||
// These will be regexps, except in the case of "**", which is
|
||
// set to the GLOBSTAR object for globstar behavior,
|
||
// and will not contain any / characters
|
||
set = this.globParts = set.map(function (s) {
|
||
return s.split(slashSplit)
|
||
})
|
||
|
||
this.debug(this.pattern, set)
|
||
|
||
// glob --> regexps
|
||
set = set.map(function (s, si, set) {
|
||
return s.map(this.parse, this)
|
||
}, this)
|
||
|
||
this.debug(this.pattern, set)
|
||
|
||
// filter out everything that didn't compile properly.
|
||
set = set.filter(function (s) {
|
||
return s.indexOf(false) === -1
|
||
})
|
||
|
||
this.debug(this.pattern, set)
|
||
|
||
this.set = set
|
||
}
|
||
|
||
Minimatch.prototype.parseNegate = parseNegate
|
||
function parseNegate () {
|
||
var pattern = this.pattern
|
||
var negate = false
|
||
var options = this.options
|
||
var negateOffset = 0
|
||
|
||
if (options.nonegate) return
|
||
|
||
for (var i = 0, l = pattern.length
|
||
; i < l && pattern.charAt(i) === '!'
|
||
; i++) {
|
||
negate = !negate
|
||
negateOffset++
|
||
}
|
||
|
||
if (negateOffset) this.pattern = pattern.substr(negateOffset)
|
||
this.negate = negate
|
||
}
|
||
|
||
// Brace expansion:
|
||
// a{b,c}d -> abd acd
|
||
// a{b,}c -> abc ac
|
||
// a{0..3}d -> a0d a1d a2d a3d
|
||
// a{b,c{d,e}f}g -> abg acdfg acefg
|
||
// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
|
||
//
|
||
// Invalid sets are not expanded.
|
||
// a{2..}b -> a{2..}b
|
||
// a{b}c -> a{b}c
|
||
minimatch.braceExpand = function (pattern, options) {
|
||
return braceExpand(pattern, options)
|
||
}
|
||
|
||
Minimatch.prototype.braceExpand = braceExpand
|
||
|
||
function braceExpand (pattern, options) {
|
||
if (!options) {
|
||
if (this instanceof Minimatch) {
|
||
options = this.options
|
||
} else {
|
||
options = {}
|
||
}
|
||
}
|
||
|
||
pattern = typeof pattern === 'undefined'
|
||
? this.pattern : pattern
|
||
|
||
if (typeof pattern === 'undefined') {
|
||
throw new TypeError('undefined pattern')
|
||
}
|
||
|
||
if (options.nobrace ||
|
||
!pattern.match(/\{.*\}/)) {
|
||
// shortcut. no need to expand.
|
||
return [pattern]
|
||
}
|
||
|
||
return expand(pattern)
|
||
}
|
||
|
||
// parse a component of the expanded set.
|
||
// At this point, no pattern may contain "/" in it
|
||
// so we're going to return a 2d array, where each entry is the full
|
||
// pattern, split on '/', and then turned into a regular expression.
|
||
// A regexp is made at the end which joins each array with an
|
||
// escaped /, and another full one which joins each regexp with |.
|
||
//
|
||
// Following the lead of Bash 4.1, note that "**" only has special meaning
|
||
// when it is the *only* thing in a path portion. Otherwise, any series
|
||
// of * is equivalent to a single *. Globstar behavior is enabled by
|
||
// default, and can be disabled by setting options.noglobstar.
|
||
Minimatch.prototype.parse = parse
|
||
var SUBPARSE = {}
|
||
function parse (pattern, isSub) {
|
||
if (pattern.length > 1024 * 64) {
|
||
throw new TypeError('pattern is too long')
|
||
}
|
||
|
||
var options = this.options
|
||
|
||
// shortcuts
|
||
if (!options.noglobstar && pattern === '**') return GLOBSTAR
|
||
if (pattern === '') return ''
|
||
|
||
var re = ''
|
||
var hasMagic = !!options.nocase
|
||
var escaping = false
|
||
// ? => one single character
|
||
var patternListStack = []
|
||
var negativeLists = []
|
||
var stateChar
|
||
var inClass = false
|
||
var reClassStart = -1
|
||
var classStart = -1
|
||
// . and .. never match anything that doesn't start with .,
|
||
// even when options.dot is set.
|
||
var patternStart = pattern.charAt(0) === '.' ? '' // anything
|
||
// not (start or / followed by . or .. followed by / or end)
|
||
: options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))'
|
||
: '(?!\\.)'
|
||
var self = this
|
||
|
||
function clearStateChar () {
|
||
if (stateChar) {
|
||
// we had some state-tracking character
|
||
// that wasn't consumed by this pass.
|
||
switch (stateChar) {
|
||
case '*':
|
||
re += star
|
||
hasMagic = true
|
||
break
|
||
case '?':
|
||
re += qmark
|
||
hasMagic = true
|
||
break
|
||
default:
|
||
re += '\\' + stateChar
|
||
break
|
||
}
|
||
self.debug('clearStateChar %j %j', stateChar, re)
|
||
stateChar = false
|
||
}
|
||
}
|
||
|
||
for (var i = 0, len = pattern.length, c
|
||
; (i < len) && (c = pattern.charAt(i))
|
||
; i++) {
|
||
this.debug('%s\t%s %s %j', pattern, i, re, c)
|
||
|
||
// skip over any that are escaped.
|
||
if (escaping && reSpecials[c]) {
|
||
re += '\\' + c
|
||
escaping = false
|
||
continue
|
||
}
|
||
|
||
switch (c) {
|
||
case '/':
|
||
// completely not allowed, even escaped.
|
||
// Should already be path-split by now.
|
||
return false
|
||
|
||
case '\\':
|
||
clearStateChar()
|
||
escaping = true
|
||
continue
|
||
|
||
// the various stateChar values
|
||
// for the "extglob" stuff.
|
||
case '?':
|
||
case '*':
|
||
case '+':
|
||
case '@':
|
||
case '!':
|
||
this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c)
|
||
|
||
// all of those are literals inside a class, except that
|
||
// the glob [!a] means [^a] in regexp
|
||
if (inClass) {
|
||
this.debug(' in class')
|
||
if (c === '!' && i === classStart + 1) c = '^'
|
||
re += c
|
||
continue
|
||
}
|
||
|
||
// if we already have a stateChar, then it means
|
||
// that there was something like ** or +? in there.
|
||
// Handle the stateChar, then proceed with this one.
|
||
self.debug('call clearStateChar %j', stateChar)
|
||
clearStateChar()
|
||
stateChar = c
|
||
// if extglob is disabled, then +(asdf|foo) isn't a thing.
|
||
// just clear the statechar *now*, rather than even diving into
|
||
// the patternList stuff.
|
||
if (options.noext) clearStateChar()
|
||
continue
|
||
|
||
case '(':
|
||
if (inClass) {
|
||
re += '('
|
||
continue
|
||
}
|
||
|
||
if (!stateChar) {
|
||
re += '\\('
|
||
continue
|
||
}
|
||
|
||
patternListStack.push({
|
||
type: stateChar,
|
||
start: i - 1,
|
||
reStart: re.length,
|
||
open: plTypes[stateChar].open,
|
||
close: plTypes[stateChar].close
|
||
})
|
||
// negation is (?:(?!js)[^/]*)
|
||
re += stateChar === '!' ? '(?:(?!(?:' : '(?:'
|
||
this.debug('plType %j %j', stateChar, re)
|
||
stateChar = false
|
||
continue
|
||
|
||
case ')':
|
||
if (inClass || !patternListStack.length) {
|
||
re += '\\)'
|
||
continue
|
||
}
|
||
|
||
clearStateChar()
|
||
hasMagic = true
|
||
var pl = patternListStack.pop()
|
||
// negation is (?:(?!js)[^/]*)
|
||
// The others are (?:<pattern>)<type>
|
||
re += pl.close
|
||
if (pl.type === '!') {
|
||
negativeLists.push(pl)
|
||
}
|
||
pl.reEnd = re.length
|
||
continue
|
||
|
||
case '|':
|
||
if (inClass || !patternListStack.length || escaping) {
|
||
re += '\\|'
|
||
escaping = false
|
||
continue
|
||
}
|
||
|
||
clearStateChar()
|
||
re += '|'
|
||
continue
|
||
|
||
// these are mostly the same in regexp and glob
|
||
case '[':
|
||
// swallow any state-tracking char before the [
|
||
clearStateChar()
|
||
|
||
if (inClass) {
|
||
re += '\\' + c
|
||
continue
|
||
}
|
||
|
||
inClass = true
|
||
classStart = i
|
||
reClassStart = re.length
|
||
re += c
|
||
continue
|
||
|
||
case ']':
|
||
// a right bracket shall lose its special
|
||
// meaning and represent itself in
|
||
// a bracket expression if it occurs
|
||
// first in the list. -- POSIX.2 2.8.3.2
|
||
if (i === classStart + 1 || !inClass) {
|
||
re += '\\' + c
|
||
escaping = false
|
||
continue
|
||
}
|
||
|
||
// handle the case where we left a class open.
|
||
// "[z-a]" is valid, equivalent to "\[z-a\]"
|
||
if (inClass) {
|
||
// split where the last [ was, make sure we don't have
|
||
// an invalid re. if so, re-walk the contents of the
|
||
// would-be class to re-translate any characters that
|
||
// were passed through as-is
|
||
// TODO: It would probably be faster to determine this
|
||
// without a try/catch and a new RegExp, but it's tricky
|
||
// to do safely. For now, this is safe and works.
|
||
var cs = pattern.substring(classStart + 1, i)
|
||
try {
|
||
RegExp('[' + cs + ']')
|
||
} catch (er) {
|
||
// not a valid class!
|
||
var sp = this.parse(cs, SUBPARSE)
|
||
re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]'
|
||
hasMagic = hasMagic || sp[1]
|
||
inClass = false
|
||
continue
|
||
}
|
||
}
|
||
|
||
// finish up the class.
|
||
hasMagic = true
|
||
inClass = false
|
||
re += c
|
||
continue
|
||
|
||
default:
|
||
// swallow any state char that wasn't consumed
|
||
clearStateChar()
|
||
|
||
if (escaping) {
|
||
// no need
|
||
escaping = false
|
||
} else if (reSpecials[c]
|
||
&& !(c === '^' && inClass)) {
|
||
re += '\\'
|
||
}
|
||
|
||
re += c
|
||
|
||
} // switch
|
||
} // for
|
||
|
||
// handle the case where we left a class open.
|
||
// "[abc" is valid, equivalent to "\[abc"
|
||
if (inClass) {
|
||
// split where the last [ was, and escape it
|
||
// this is a huge pita. We now have to re-walk
|
||
// the contents of the would-be class to re-translate
|
||
// any characters that were passed through as-is
|
||
cs = pattern.substr(classStart + 1)
|
||
sp = this.parse(cs, SUBPARSE)
|
||
re = re.substr(0, reClassStart) + '\\[' + sp[0]
|
||
hasMagic = hasMagic || sp[1]
|
||
}
|
||
|
||
// handle the case where we had a +( thing at the *end*
|
||
// of the pattern.
|
||
// each pattern list stack adds 3 chars, and we need to go through
|
||
// and escape any | chars that were passed through as-is for the regexp.
|
||
// Go through and escape them, taking care not to double-escape any
|
||
// | chars that were already escaped.
|
||
for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) {
|
||
var tail = re.slice(pl.reStart + pl.open.length)
|
||
this.debug('setting tail', re, pl)
|
||
// maybe some even number of \, then maybe 1 \, followed by a |
|
||
tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) {
|
||
if (!$2) {
|
||
// the | isn't already escaped, so escape it.
|
||
$2 = '\\'
|
||
}
|
||
|
||
// need to escape all those slashes *again*, without escaping the
|
||
// one that we need for escaping the | character. As it works out,
|
||
// escaping an even number of slashes can be done by simply repeating
|
||
// it exactly after itself. That's why this trick works.
|
||
//
|
||
// I am sorry that you have to see this.
|
||
return $1 + $1 + $2 + '|'
|
||
})
|
||
|
||
this.debug('tail=%j\n %s', tail, tail, pl, re)
|
||
var t = pl.type === '*' ? star
|
||
: pl.type === '?' ? qmark
|
||
: '\\' + pl.type
|
||
|
||
hasMagic = true
|
||
re = re.slice(0, pl.reStart) + t + '\\(' + tail
|
||
}
|
||
|
||
// handle trailing things that only matter at the very end.
|
||
clearStateChar()
|
||
if (escaping) {
|
||
// trailing \\
|
||
re += '\\\\'
|
||
}
|
||
|
||
// only need to apply the nodot start if the re starts with
|
||
// something that could conceivably capture a dot
|
||
var addPatternStart = false
|
||
switch (re.charAt(0)) {
|
||
case '.':
|
||
case '[':
|
||
case '(': addPatternStart = true
|
||
}
|
||
|
||
// Hack to work around lack of negative lookbehind in JS
|
||
// A pattern like: *.!(x).!(y|z) needs to ensure that a name
|
||
// like 'a.xyz.yz' doesn't match. So, the first negative
|
||
// lookahead, has to look ALL the way ahead, to the end of
|
||
// the pattern.
|
||
for (var n = negativeLists.length - 1; n > -1; n--) {
|
||
var nl = negativeLists[n]
|
||
|
||
var nlBefore = re.slice(0, nl.reStart)
|
||
var nlFirst = re.slice(nl.reStart, nl.reEnd - 8)
|
||
var nlLast = re.slice(nl.reEnd - 8, nl.reEnd)
|
||
var nlAfter = re.slice(nl.reEnd)
|
||
|
||
nlLast += nlAfter
|
||
|
||
// Handle nested stuff like *(*.js|!(*.json)), where open parens
|
||
// mean that we should *not* include the ) in the bit that is considered
|
||
// "after" the negated section.
|
||
var openParensBefore = nlBefore.split('(').length - 1
|
||
var cleanAfter = nlAfter
|
||
for (i = 0; i < openParensBefore; i++) {
|
||
cleanAfter = cleanAfter.replace(/\)[+*?]?/, '')
|
||
}
|
||
nlAfter = cleanAfter
|
||
|
||
var dollar = ''
|
||
if (nlAfter === '' && isSub !== SUBPARSE) {
|
||
dollar = '$'
|
||
}
|
||
var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast
|
||
re = newRe
|
||
}
|
||
|
||
// if the re is not "" at this point, then we need to make sure
|
||
// it doesn't match against an empty path part.
|
||
// Otherwise a/* will match a/, which it should not.
|
||
if (re !== '' && hasMagic) {
|
||
re = '(?=.)' + re
|
||
}
|
||
|
||
if (addPatternStart) {
|
||
re = patternStart + re
|
||
}
|
||
|
||
// parsing just a piece of a larger pattern.
|
||
if (isSub === SUBPARSE) {
|
||
return [re, hasMagic]
|
||
}
|
||
|
||
// skip the regexp for non-magical patterns
|
||
// unescape anything in it, though, so that it'll be
|
||
// an exact match against a file etc.
|
||
if (!hasMagic) {
|
||
return globUnescape(pattern)
|
||
}
|
||
|
||
var flags = options.nocase ? 'i' : ''
|
||
try {
|
||
var regExp = new RegExp('^' + re + '$', flags)
|
||
} catch (er) {
|
||
// If it was an invalid regular expression, then it can't match
|
||
// anything. This trick looks for a character after the end of
|
||
// the string, which is of course impossible, except in multi-line
|
||
// mode, but it's not a /m regex.
|
||
return new RegExp('$.')
|
||
}
|
||
|
||
regExp._glob = pattern
|
||
regExp._src = re
|
||
|
||
return regExp
|
||
}
|
||
|
||
minimatch.makeRe = function (pattern, options) {
|
||
return new Minimatch(pattern, options || {}).makeRe()
|
||
}
|
||
|
||
Minimatch.prototype.makeRe = makeRe
|
||
function makeRe () {
|
||
if (this.regexp || this.regexp === false) return this.regexp
|
||
|
||
// at this point, this.set is a 2d array of partial
|
||
// pattern strings, or "**".
|
||
//
|
||
// It's better to use .match(). This function shouldn't
|
||
// be used, really, but it's pretty convenient sometimes,
|
||
// when you just want to work with a regex.
|
||
var set = this.set
|
||
|
||
if (!set.length) {
|
||
this.regexp = false
|
||
return this.regexp
|
||
}
|
||
var options = this.options
|
||
|
||
var twoStar = options.noglobstar ? star
|
||
: options.dot ? twoStarDot
|
||
: twoStarNoDot
|
||
var flags = options.nocase ? 'i' : ''
|
||
|
||
var re = set.map(function (pattern) {
|
||
return pattern.map(function (p) {
|
||
return (p === GLOBSTAR) ? twoStar
|
||
: (typeof p === 'string') ? regExpEscape(p)
|
||
: p._src
|
||
}).join('\\\/')
|
||
}).join('|')
|
||
|
||
// must match entire pattern
|
||
// ending in a * or ** will make it less strict.
|
||
re = '^(?:' + re + ')$'
|
||
|
||
// can match anything, as long as it's not this.
|
||
if (this.negate) re = '^(?!' + re + ').*$'
|
||
|
||
try {
|
||
this.regexp = new RegExp(re, flags)
|
||
} catch (ex) {
|
||
this.regexp = false
|
||
}
|
||
return this.regexp
|
||
}
|
||
|
||
minimatch.match = function (list, pattern, options) {
|
||
options = options || {}
|
||
var mm = new Minimatch(pattern, options)
|
||
list = list.filter(function (f) {
|
||
return mm.match(f)
|
||
})
|
||
if (mm.options.nonull && !list.length) {
|
||
list.push(pattern)
|
||
}
|
||
return list
|
||
}
|
||
|
||
Minimatch.prototype.match = match
|
||
function match (f, partial) {
|
||
this.debug('match', f, this.pattern)
|
||
// short-circuit in the case of busted things.
|
||
// comments, etc.
|
||
if (this.comment) return false
|
||
if (this.empty) return f === ''
|
||
|
||
if (f === '/' && partial) return true
|
||
|
||
var options = this.options
|
||
|
||
// windows: need to use /, not \
|
||
if (path.sep !== '/') {
|
||
f = f.split(path.sep).join('/')
|
||
}
|
||
|
||
// treat the test path as a set of pathparts.
|
||
f = f.split(slashSplit)
|
||
this.debug(this.pattern, 'split', f)
|
||
|
||
// just ONE of the pattern sets in this.set needs to match
|
||
// in order for it to be valid. If negating, then just one
|
||
// match means that we have failed.
|
||
// Either way, return on the first hit.
|
||
|
||
var set = this.set
|
||
this.debug(this.pattern, 'set', set)
|
||
|
||
// Find the basename of the path by looking for the last non-empty segment
|
||
var filename
|
||
var i
|
||
for (i = f.length - 1; i >= 0; i--) {
|
||
filename = f[i]
|
||
if (filename) break
|
||
}
|
||
|
||
for (i = 0; i < set.length; i++) {
|
||
var pattern = set[i]
|
||
var file = f
|
||
if (options.matchBase && pattern.length === 1) {
|
||
file = [filename]
|
||
}
|
||
var hit = this.matchOne(file, pattern, partial)
|
||
if (hit) {
|
||
if (options.flipNegate) return true
|
||
return !this.negate
|
||
}
|
||
}
|
||
|
||
// didn't get any hits. this is success if it's a negative
|
||
// pattern, failure otherwise.
|
||
if (options.flipNegate) return false
|
||
return this.negate
|
||
}
|
||
|
||
// set partial to true to test if, for example,
|
||
// "/a/b" matches the start of "/*/b/*/d"
|
||
// Partial means, if you run out of file before you run
|
||
// out of pattern, then that's fine, as long as all
|
||
// the parts match.
|
||
Minimatch.prototype.matchOne = function (file, pattern, partial) {
|
||
var options = this.options
|
||
|
||
this.debug('matchOne',
|
||
{ 'this': this, file: file, pattern: pattern })
|
||
|
||
this.debug('matchOne', file.length, pattern.length)
|
||
|
||
for (var fi = 0,
|
||
pi = 0,
|
||
fl = file.length,
|
||
pl = pattern.length
|
||
; (fi < fl) && (pi < pl)
|
||
; fi++, pi++) {
|
||
this.debug('matchOne loop')
|
||
var p = pattern[pi]
|
||
var f = file[fi]
|
||
|
||
this.debug(pattern, p, f)
|
||
|
||
// should be impossible.
|
||
// some invalid regexp stuff in the set.
|
||
if (p === false) return false
|
||
|
||
if (p === GLOBSTAR) {
|
||
this.debug('GLOBSTAR', [pattern, p, f])
|
||
|
||
// "**"
|
||
// a/**/b/**/c would match the following:
|
||
// a/b/x/y/z/c
|
||
// a/x/y/z/b/c
|
||
// a/b/x/b/x/c
|
||
// a/b/c
|
||
// To do this, take the rest of the pattern after
|
||
// the **, and see if it would match the file remainder.
|
||
// If so, return success.
|
||
// If not, the ** "swallows" a segment, and try again.
|
||
// This is recursively awful.
|
||
//
|
||
// a/**/b/**/c matching a/b/x/y/z/c
|
||
// - a matches a
|
||
// - doublestar
|
||
// - matchOne(b/x/y/z/c, b/**/c)
|
||
// - b matches b
|
||
// - doublestar
|
||
// - matchOne(x/y/z/c, c) -> no
|
||
// - matchOne(y/z/c, c) -> no
|
||
// - matchOne(z/c, c) -> no
|
||
// - matchOne(c, c) yes, hit
|
||
var fr = fi
|
||
var pr = pi + 1
|
||
if (pr === pl) {
|
||
this.debug('** at the end')
|
||
// a ** at the end will just swallow the rest.
|
||
// We have found a match.
|
||
// however, it will not swallow /.x, unless
|
||
// options.dot is set.
|
||
// . and .. are *never* matched by **, for explosively
|
||
// exponential reasons.
|
||
for (; fi < fl; fi++) {
|
||
if (file[fi] === '.' || file[fi] === '..' ||
|
||
(!options.dot && file[fi].charAt(0) === '.')) return false
|
||
}
|
||
return true
|
||
}
|
||
|
||
// ok, let's see if we can swallow whatever we can.
|
||
while (fr < fl) {
|
||
var swallowee = file[fr]
|
||
|
||
this.debug('\nglobstar while', file, fr, pattern, pr, swallowee)
|
||
|
||
// XXX remove this slice. Just pass the start index.
|
||
if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
|
||
this.debug('globstar found match!', fr, fl, swallowee)
|
||
// found a match.
|
||
return true
|
||
} else {
|
||
// can't swallow "." or ".." ever.
|
||
// can only swallow ".foo" when explicitly asked.
|
||
if (swallowee === '.' || swallowee === '..' ||
|
||
(!options.dot && swallowee.charAt(0) === '.')) {
|
||
this.debug('dot detected!', file, fr, pattern, pr)
|
||
break
|
||
}
|
||
|
||
// ** swallows a segment, and continue.
|
||
this.debug('globstar swallow a segment, and continue')
|
||
fr++
|
||
}
|
||
}
|
||
|
||
// no match was found.
|
||
// However, in partial mode, we can't say this is necessarily over.
|
||
// If there's more *pattern* left, then
|
||
if (partial) {
|
||
// ran out of file
|
||
this.debug('\n>>> no match, partial?', file, fr, pattern, pr)
|
||
if (fr === fl) return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
// something other than **
|
||
// non-magic patterns just have to match exactly
|
||
// patterns with magic have been turned into regexps.
|
||
var hit
|
||
if (typeof p === 'string') {
|
||
if (options.nocase) {
|
||
hit = f.toLowerCase() === p.toLowerCase()
|
||
} else {
|
||
hit = f === p
|
||
}
|
||
this.debug('string match', p, f, hit)
|
||
} else {
|
||
hit = f.match(p)
|
||
this.debug('pattern match', p, f, hit)
|
||
}
|
||
|
||
if (!hit) return false
|
||
}
|
||
|
||
// Note: ending in / means that we'll get a final ""
|
||
// at the end of the pattern. This can only match a
|
||
// corresponding "" at the end of the file.
|
||
// If the file ends in /, then it can only match a
|
||
// a pattern that ends in /, unless the pattern just
|
||
// doesn't have any more for it. But, a/b/ should *not*
|
||
// match "a/b/*", even though "" matches against the
|
||
// [^/]*? pattern, except in partial mode, where it might
|
||
// simply not be reached yet.
|
||
// However, a/b/ should still satisfy a/*
|
||
|
||
// now either we fell off the end of the pattern, or we're done.
|
||
if (fi === fl && pi === pl) {
|
||
// ran out of pattern and filename at the same time.
|
||
// an exact hit!
|
||
return true
|
||
} else if (fi === fl) {
|
||
// ran out of file, but still had pattern left.
|
||
// this is ok if we're doing the match as part of
|
||
// a glob fs traversal.
|
||
return partial
|
||
} else if (pi === pl) {
|
||
// ran out of pattern, still have file left.
|
||
// this is only acceptable if we're on the very last
|
||
// empty segment of a file with a trailing slash.
|
||
// a/* should match a/b/
|
||
var emptyFileEnd = (fi === fl - 1) && (file[fi] === '')
|
||
return emptyFileEnd
|
||
}
|
||
|
||
// should be unreachable.
|
||
throw new Error('wtf?')
|
||
}
|
||
|
||
// replace stuff like \* with *
|
||
function globUnescape (s) {
|
||
return s.replace(/\\(.)/g, '$1')
|
||
}
|
||
|
||
function regExpEscape (s) {
|
||
return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/once/once.js":
|
||
/*!***********************************!*\
|
||
!*** ./node_modules/once/once.js ***!
|
||
\***********************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var wrappy = __webpack_require__(/*! wrappy */ "./node_modules/wrappy/wrappy.js")
|
||
module.exports = wrappy(once)
|
||
module.exports.strict = wrappy(onceStrict)
|
||
|
||
once.proto = once(function () {
|
||
Object.defineProperty(Function.prototype, 'once', {
|
||
value: function () {
|
||
return once(this)
|
||
},
|
||
configurable: true
|
||
})
|
||
|
||
Object.defineProperty(Function.prototype, 'onceStrict', {
|
||
value: function () {
|
||
return onceStrict(this)
|
||
},
|
||
configurable: true
|
||
})
|
||
})
|
||
|
||
function once (fn) {
|
||
var f = function () {
|
||
if (f.called) return f.value
|
||
f.called = true
|
||
return f.value = fn.apply(this, arguments)
|
||
}
|
||
f.called = false
|
||
return f
|
||
}
|
||
|
||
function onceStrict (fn) {
|
||
var f = function () {
|
||
if (f.called)
|
||
throw new Error(f.onceError)
|
||
f.called = true
|
||
return f.value = fn.apply(this, arguments)
|
||
}
|
||
var name = fn.name || 'Function wrapped with `once`'
|
||
f.onceError = name + " shouldn't be called more than once"
|
||
f.called = false
|
||
return f
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/path-is-absolute/index.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/path-is-absolute/index.js ***!
|
||
\************************************************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
|
||
|
||
function posix(path) {
|
||
return path.charAt(0) === '/';
|
||
}
|
||
|
||
function win32(path) {
|
||
// https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56
|
||
var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/;
|
||
var result = splitDeviceRe.exec(path);
|
||
var device = result[1] || '';
|
||
var isUnc = Boolean(device && device.charAt(1) !== ':');
|
||
|
||
// UNC paths are always absolute
|
||
return Boolean(result[2] || isUnc);
|
||
}
|
||
|
||
module.exports = process.platform === 'win32' ? win32 : posix;
|
||
module.exports.posix = posix;
|
||
module.exports.win32 = win32;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/q/q.js":
|
||
/*!*****************************!*\
|
||
!*** ./node_modules/q/q.js ***!
|
||
\*****************************/
|
||
/***/ ((module) => {
|
||
|
||
// vim:ts=4:sts=4:sw=4:
|
||
/*!
|
||
*
|
||
* Copyright 2009-2017 Kris Kowal under the terms of the MIT
|
||
* license found at https://github.com/kriskowal/q/blob/v1/LICENSE
|
||
*
|
||
* With parts by Tyler Close
|
||
* Copyright 2007-2009 Tyler Close under the terms of the MIT X license found
|
||
* at http://www.opensource.org/licenses/mit-license.html
|
||
* Forked at ref_send.js version: 2009-05-11
|
||
*
|
||
* With parts by Mark Miller
|
||
* Copyright (C) 2011 Google Inc.
|
||
*
|
||
* 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
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software
|
||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
* See the License for the specific language governing permissions and
|
||
* limitations under the License.
|
||
*
|
||
*/
|
||
|
||
(function (definition) {
|
||
"use strict";
|
||
|
||
// This file will function properly as a <script> tag, or a module
|
||
// using CommonJS and NodeJS or RequireJS module formats. In
|
||
// Common/Node/RequireJS, the module exports the Q API and when
|
||
// executed as a simple <script>, it creates a Q global instead.
|
||
|
||
// Montage Require
|
||
if (typeof bootstrap === "function") {
|
||
bootstrap("promise", definition);
|
||
|
||
// CommonJS
|
||
} else if (true) {
|
||
module.exports = definition();
|
||
|
||
// RequireJS
|
||
} else { var previousQ, global; }
|
||
|
||
})(function () {
|
||
"use strict";
|
||
|
||
var hasStacks = false;
|
||
try {
|
||
throw new Error();
|
||
} catch (e) {
|
||
hasStacks = !!e.stack;
|
||
}
|
||
|
||
// All code after this point will be filtered from stack traces reported
|
||
// by Q.
|
||
var qStartingLine = captureLine();
|
||
var qFileName;
|
||
|
||
// shims
|
||
|
||
// used for fallback in "allResolved"
|
||
var noop = function () {};
|
||
|
||
// Use the fastest possible means to execute a task in a future turn
|
||
// of the event loop.
|
||
var nextTick =(function () {
|
||
// linked list of tasks (single, with head node)
|
||
var head = {task: void 0, next: null};
|
||
var tail = head;
|
||
var flushing = false;
|
||
var requestTick = void 0;
|
||
var isNodeJS = false;
|
||
// queue for late tasks, used by unhandled rejection tracking
|
||
var laterQueue = [];
|
||
|
||
function flush() {
|
||
/* jshint loopfunc: true */
|
||
var task, domain;
|
||
|
||
while (head.next) {
|
||
head = head.next;
|
||
task = head.task;
|
||
head.task = void 0;
|
||
domain = head.domain;
|
||
|
||
if (domain) {
|
||
head.domain = void 0;
|
||
domain.enter();
|
||
}
|
||
runSingle(task, domain);
|
||
|
||
}
|
||
while (laterQueue.length) {
|
||
task = laterQueue.pop();
|
||
runSingle(task);
|
||
}
|
||
flushing = false;
|
||
}
|
||
// runs a single function in the async queue
|
||
function runSingle(task, domain) {
|
||
try {
|
||
task();
|
||
|
||
} catch (e) {
|
||
if (isNodeJS) {
|
||
// In node, uncaught exceptions are considered fatal errors.
|
||
// Re-throw them synchronously to interrupt flushing!
|
||
|
||
// Ensure continuation if the uncaught exception is suppressed
|
||
// listening "uncaughtException" events (as domains does).
|
||
// Continue in next event to avoid tick recursion.
|
||
if (domain) {
|
||
domain.exit();
|
||
}
|
||
setTimeout(flush, 0);
|
||
if (domain) {
|
||
domain.enter();
|
||
}
|
||
|
||
throw e;
|
||
|
||
} else {
|
||
// In browsers, uncaught exceptions are not fatal.
|
||
// Re-throw them asynchronously to avoid slow-downs.
|
||
setTimeout(function () {
|
||
throw e;
|
||
}, 0);
|
||
}
|
||
}
|
||
|
||
if (domain) {
|
||
domain.exit();
|
||
}
|
||
}
|
||
|
||
nextTick = function (task) {
|
||
tail = tail.next = {
|
||
task: task,
|
||
domain: isNodeJS && process.domain,
|
||
next: null
|
||
};
|
||
|
||
if (!flushing) {
|
||
flushing = true;
|
||
requestTick();
|
||
}
|
||
};
|
||
|
||
if (typeof process === "object" &&
|
||
process.toString() === "[object process]" && process.nextTick) {
|
||
// Ensure Q is in a real Node environment, with a `process.nextTick`.
|
||
// To see through fake Node environments:
|
||
// * Mocha test runner - exposes a `process` global without a `nextTick`
|
||
// * Browserify - exposes a `process.nexTick` function that uses
|
||
// `setTimeout`. In this case `setImmediate` is preferred because
|
||
// it is faster. Browserify's `process.toString()` yields
|
||
// "[object Object]", while in a real Node environment
|
||
// `process.toString()` yields "[object process]".
|
||
isNodeJS = true;
|
||
|
||
requestTick = function () {
|
||
process.nextTick(flush);
|
||
};
|
||
|
||
} else if (typeof setImmediate === "function") {
|
||
// In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate
|
||
if (typeof window !== "undefined") {
|
||
requestTick = setImmediate.bind(window, flush);
|
||
} else {
|
||
requestTick = function () {
|
||
setImmediate(flush);
|
||
};
|
||
}
|
||
|
||
} else if (typeof MessageChannel !== "undefined") {
|
||
// modern browsers
|
||
// http://www.nonblocking.io/2011/06/windownexttick.html
|
||
var channel = new MessageChannel();
|
||
// At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create
|
||
// working message ports the first time a page loads.
|
||
channel.port1.onmessage = function () {
|
||
requestTick = requestPortTick;
|
||
channel.port1.onmessage = flush;
|
||
flush();
|
||
};
|
||
var requestPortTick = function () {
|
||
// Opera requires us to provide a message payload, regardless of
|
||
// whether we use it.
|
||
channel.port2.postMessage(0);
|
||
};
|
||
requestTick = function () {
|
||
setTimeout(flush, 0);
|
||
requestPortTick();
|
||
};
|
||
|
||
} else {
|
||
// old browsers
|
||
requestTick = function () {
|
||
setTimeout(flush, 0);
|
||
};
|
||
}
|
||
// runs a task after all other tasks have been run
|
||
// this is useful for unhandled rejection tracking that needs to happen
|
||
// after all `then`d tasks have been run.
|
||
nextTick.runAfter = function (task) {
|
||
laterQueue.push(task);
|
||
if (!flushing) {
|
||
flushing = true;
|
||
requestTick();
|
||
}
|
||
};
|
||
return nextTick;
|
||
})();
|
||
|
||
// Attempt to make generics safe in the face of downstream
|
||
// modifications.
|
||
// There is no situation where this is necessary.
|
||
// If you need a security guarantee, these primordials need to be
|
||
// deeply frozen anyway, and if you don’t need a security guarantee,
|
||
// this is just plain paranoid.
|
||
// However, this **might** have the nice side-effect of reducing the size of
|
||
// the minified code by reducing x.call() to merely x()
|
||
// See Mark Miller’s explanation of what this does.
|
||
// http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming
|
||
var call = Function.call;
|
||
function uncurryThis(f) {
|
||
return function () {
|
||
return call.apply(f, arguments);
|
||
};
|
||
}
|
||
// This is equivalent, but slower:
|
||
// uncurryThis = Function_bind.bind(Function_bind.call);
|
||
// http://jsperf.com/uncurrythis
|
||
|
||
var array_slice = uncurryThis(Array.prototype.slice);
|
||
|
||
var array_reduce = uncurryThis(
|
||
Array.prototype.reduce || function (callback, basis) {
|
||
var index = 0,
|
||
length = this.length;
|
||
// concerning the initial value, if one is not provided
|
||
if (arguments.length === 1) {
|
||
// seek to the first value in the array, accounting
|
||
// for the possibility that is is a sparse array
|
||
do {
|
||
if (index in this) {
|
||
basis = this[index++];
|
||
break;
|
||
}
|
||
if (++index >= length) {
|
||
throw new TypeError();
|
||
}
|
||
} while (1);
|
||
}
|
||
// reduce
|
||
for (; index < length; index++) {
|
||
// account for the possibility that the array is sparse
|
||
if (index in this) {
|
||
basis = callback(basis, this[index], index);
|
||
}
|
||
}
|
||
return basis;
|
||
}
|
||
);
|
||
|
||
var array_indexOf = uncurryThis(
|
||
Array.prototype.indexOf || function (value) {
|
||
// not a very good shim, but good enough for our one use of it
|
||
for (var i = 0; i < this.length; i++) {
|
||
if (this[i] === value) {
|
||
return i;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
);
|
||
|
||
var array_map = uncurryThis(
|
||
Array.prototype.map || function (callback, thisp) {
|
||
var self = this;
|
||
var collect = [];
|
||
array_reduce(self, function (undefined, value, index) {
|
||
collect.push(callback.call(thisp, value, index, self));
|
||
}, void 0);
|
||
return collect;
|
||
}
|
||
);
|
||
|
||
var object_create = Object.create || function (prototype) {
|
||
function Type() { }
|
||
Type.prototype = prototype;
|
||
return new Type();
|
||
};
|
||
|
||
var object_defineProperty = Object.defineProperty || function (obj, prop, descriptor) {
|
||
obj[prop] = descriptor.value;
|
||
return obj;
|
||
};
|
||
|
||
var object_hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);
|
||
|
||
var object_keys = Object.keys || function (object) {
|
||
var keys = [];
|
||
for (var key in object) {
|
||
if (object_hasOwnProperty(object, key)) {
|
||
keys.push(key);
|
||
}
|
||
}
|
||
return keys;
|
||
};
|
||
|
||
var object_toString = uncurryThis(Object.prototype.toString);
|
||
|
||
function isObject(value) {
|
||
return value === Object(value);
|
||
}
|
||
|
||
// generator related shims
|
||
|
||
// FIXME: Remove this function once ES6 generators are in SpiderMonkey.
|
||
function isStopIteration(exception) {
|
||
return (
|
||
object_toString(exception) === "[object StopIteration]" ||
|
||
exception instanceof QReturnValue
|
||
);
|
||
}
|
||
|
||
// FIXME: Remove this helper and Q.return once ES6 generators are in
|
||
// SpiderMonkey.
|
||
var QReturnValue;
|
||
if (typeof ReturnValue !== "undefined") {
|
||
QReturnValue = ReturnValue;
|
||
} else {
|
||
QReturnValue = function (value) {
|
||
this.value = value;
|
||
};
|
||
}
|
||
|
||
// long stack traces
|
||
|
||
var STACK_JUMP_SEPARATOR = "From previous event:";
|
||
|
||
function makeStackTraceLong(error, promise) {
|
||
// If possible, transform the error stack trace by removing Node and Q
|
||
// cruft, then concatenating with the stack trace of `promise`. See #57.
|
||
if (hasStacks &&
|
||
promise.stack &&
|
||
typeof error === "object" &&
|
||
error !== null &&
|
||
error.stack
|
||
) {
|
||
var stacks = [];
|
||
for (var p = promise; !!p; p = p.source) {
|
||
if (p.stack && (!error.__minimumStackCounter__ || error.__minimumStackCounter__ > p.stackCounter)) {
|
||
object_defineProperty(error, "__minimumStackCounter__", {value: p.stackCounter, configurable: true});
|
||
stacks.unshift(p.stack);
|
||
}
|
||
}
|
||
stacks.unshift(error.stack);
|
||
|
||
var concatedStacks = stacks.join("\n" + STACK_JUMP_SEPARATOR + "\n");
|
||
var stack = filterStackString(concatedStacks);
|
||
object_defineProperty(error, "stack", {value: stack, configurable: true});
|
||
}
|
||
}
|
||
|
||
function filterStackString(stackString) {
|
||
var lines = stackString.split("\n");
|
||
var desiredLines = [];
|
||
for (var i = 0; i < lines.length; ++i) {
|
||
var line = lines[i];
|
||
|
||
if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
|
||
desiredLines.push(line);
|
||
}
|
||
}
|
||
return desiredLines.join("\n");
|
||
}
|
||
|
||
function isNodeFrame(stackLine) {
|
||
return stackLine.indexOf("(module.js:") !== -1 ||
|
||
stackLine.indexOf("(node.js:") !== -1;
|
||
}
|
||
|
||
function getFileNameAndLineNumber(stackLine) {
|
||
// Named functions: "at functionName (filename:lineNumber:columnNumber)"
|
||
// In IE10 function name can have spaces ("Anonymous function") O_o
|
||
var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
|
||
if (attempt1) {
|
||
return [attempt1[1], Number(attempt1[2])];
|
||
}
|
||
|
||
// Anonymous functions: "at filename:lineNumber:columnNumber"
|
||
var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
|
||
if (attempt2) {
|
||
return [attempt2[1], Number(attempt2[2])];
|
||
}
|
||
|
||
// Firefox style: "function@filename:lineNumber or @filename:lineNumber"
|
||
var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
|
||
if (attempt3) {
|
||
return [attempt3[1], Number(attempt3[2])];
|
||
}
|
||
}
|
||
|
||
function isInternalFrame(stackLine) {
|
||
var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
|
||
|
||
if (!fileNameAndLineNumber) {
|
||
return false;
|
||
}
|
||
|
||
var fileName = fileNameAndLineNumber[0];
|
||
var lineNumber = fileNameAndLineNumber[1];
|
||
|
||
return fileName === qFileName &&
|
||
lineNumber >= qStartingLine &&
|
||
lineNumber <= qEndingLine;
|
||
}
|
||
|
||
// discover own file name and line number range for filtering stack
|
||
// traces
|
||
function captureLine() {
|
||
if (!hasStacks) {
|
||
return;
|
||
}
|
||
|
||
try {
|
||
throw new Error();
|
||
} catch (e) {
|
||
var lines = e.stack.split("\n");
|
||
var firstLine = lines[0].indexOf("@") > 0 ? lines[1] : lines[2];
|
||
var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
|
||
if (!fileNameAndLineNumber) {
|
||
return;
|
||
}
|
||
|
||
qFileName = fileNameAndLineNumber[0];
|
||
return fileNameAndLineNumber[1];
|
||
}
|
||
}
|
||
|
||
function deprecate(callback, name, alternative) {
|
||
return function () {
|
||
if (typeof console !== "undefined" &&
|
||
typeof console.warn === "function") {
|
||
console.warn(name + " is deprecated, use " + alternative +
|
||
" instead.", new Error("").stack);
|
||
}
|
||
return callback.apply(callback, arguments);
|
||
};
|
||
}
|
||
|
||
// end of shims
|
||
// beginning of real work
|
||
|
||
/**
|
||
* Constructs a promise for an immediate reference, passes promises through, or
|
||
* coerces promises from different systems.
|
||
* @param value immediate reference or promise
|
||
*/
|
||
function Q(value) {
|
||
// If the object is already a Promise, return it directly. This enables
|
||
// the resolve function to both be used to created references from objects,
|
||
// but to tolerably coerce non-promises to promises.
|
||
if (value instanceof Promise) {
|
||
return value;
|
||
}
|
||
|
||
// assimilate thenables
|
||
if (isPromiseAlike(value)) {
|
||
return coerce(value);
|
||
} else {
|
||
return fulfill(value);
|
||
}
|
||
}
|
||
Q.resolve = Q;
|
||
|
||
/**
|
||
* Performs a task in a future turn of the event loop.
|
||
* @param {Function} task
|
||
*/
|
||
Q.nextTick = nextTick;
|
||
|
||
/**
|
||
* Controls whether or not long stack traces will be on
|
||
*/
|
||
Q.longStackSupport = false;
|
||
|
||
/**
|
||
* The counter is used to determine the stopping point for building
|
||
* long stack traces. In makeStackTraceLong we walk backwards through
|
||
* the linked list of promises, only stacks which were created before
|
||
* the rejection are concatenated.
|
||
*/
|
||
var longStackCounter = 1;
|
||
|
||
// enable long stacks if Q_DEBUG is set
|
||
if (typeof process === "object" && process && process.env && process.env.Q_DEBUG) {
|
||
Q.longStackSupport = true;
|
||
}
|
||
|
||
/**
|
||
* Constructs a {promise, resolve, reject} object.
|
||
*
|
||
* `resolve` is a callback to invoke with a more resolved value for the
|
||
* promise. To fulfill the promise, invoke `resolve` with any value that is
|
||
* not a thenable. To reject the promise, invoke `resolve` with a rejected
|
||
* thenable, or invoke `reject` with the reason directly. To resolve the
|
||
* promise to another thenable, thus putting it in the same state, invoke
|
||
* `resolve` with that other thenable.
|
||
*/
|
||
Q.defer = defer;
|
||
function defer() {
|
||
// if "messages" is an "Array", that indicates that the promise has not yet
|
||
// been resolved. If it is "undefined", it has been resolved. Each
|
||
// element of the messages array is itself an array of complete arguments to
|
||
// forward to the resolved promise. We coerce the resolution value to a
|
||
// promise using the `resolve` function because it handles both fully
|
||
// non-thenable values and other thenables gracefully.
|
||
var messages = [], progressListeners = [], resolvedPromise;
|
||
|
||
var deferred = object_create(defer.prototype);
|
||
var promise = object_create(Promise.prototype);
|
||
|
||
promise.promiseDispatch = function (resolve, op, operands) {
|
||
var args = array_slice(arguments);
|
||
if (messages) {
|
||
messages.push(args);
|
||
if (op === "when" && operands[1]) { // progress operand
|
||
progressListeners.push(operands[1]);
|
||
}
|
||
} else {
|
||
Q.nextTick(function () {
|
||
resolvedPromise.promiseDispatch.apply(resolvedPromise, args);
|
||
});
|
||
}
|
||
};
|
||
|
||
// XXX deprecated
|
||
promise.valueOf = function () {
|
||
if (messages) {
|
||
return promise;
|
||
}
|
||
var nearerValue = nearer(resolvedPromise);
|
||
if (isPromise(nearerValue)) {
|
||
resolvedPromise = nearerValue; // shorten chain
|
||
}
|
||
return nearerValue;
|
||
};
|
||
|
||
promise.inspect = function () {
|
||
if (!resolvedPromise) {
|
||
return { state: "pending" };
|
||
}
|
||
return resolvedPromise.inspect();
|
||
};
|
||
|
||
if (Q.longStackSupport && hasStacks) {
|
||
try {
|
||
throw new Error();
|
||
} catch (e) {
|
||
// NOTE: don't try to use `Error.captureStackTrace` or transfer the
|
||
// accessor around; that causes memory leaks as per GH-111. Just
|
||
// reify the stack trace as a string ASAP.
|
||
//
|
||
// At the same time, cut off the first line; it's always just
|
||
// "[object Promise]\n", as per the `toString`.
|
||
promise.stack = e.stack.substring(e.stack.indexOf("\n") + 1);
|
||
promise.stackCounter = longStackCounter++;
|
||
}
|
||
}
|
||
|
||
// NOTE: we do the checks for `resolvedPromise` in each method, instead of
|
||
// consolidating them into `become`, since otherwise we'd create new
|
||
// promises with the lines `become(whatever(value))`. See e.g. GH-252.
|
||
|
||
function become(newPromise) {
|
||
resolvedPromise = newPromise;
|
||
|
||
if (Q.longStackSupport && hasStacks) {
|
||
// Only hold a reference to the new promise if long stacks
|
||
// are enabled to reduce memory usage
|
||
promise.source = newPromise;
|
||
}
|
||
|
||
array_reduce(messages, function (undefined, message) {
|
||
Q.nextTick(function () {
|
||
newPromise.promiseDispatch.apply(newPromise, message);
|
||
});
|
||
}, void 0);
|
||
|
||
messages = void 0;
|
||
progressListeners = void 0;
|
||
}
|
||
|
||
deferred.promise = promise;
|
||
deferred.resolve = function (value) {
|
||
if (resolvedPromise) {
|
||
return;
|
||
}
|
||
|
||
become(Q(value));
|
||
};
|
||
|
||
deferred.fulfill = function (value) {
|
||
if (resolvedPromise) {
|
||
return;
|
||
}
|
||
|
||
become(fulfill(value));
|
||
};
|
||
deferred.reject = function (reason) {
|
||
if (resolvedPromise) {
|
||
return;
|
||
}
|
||
|
||
become(reject(reason));
|
||
};
|
||
deferred.notify = function (progress) {
|
||
if (resolvedPromise) {
|
||
return;
|
||
}
|
||
|
||
array_reduce(progressListeners, function (undefined, progressListener) {
|
||
Q.nextTick(function () {
|
||
progressListener(progress);
|
||
});
|
||
}, void 0);
|
||
};
|
||
|
||
return deferred;
|
||
}
|
||
|
||
/**
|
||
* Creates a Node-style callback that will resolve or reject the deferred
|
||
* promise.
|
||
* @returns a nodeback
|
||
*/
|
||
defer.prototype.makeNodeResolver = function () {
|
||
var self = this;
|
||
return function (error, value) {
|
||
if (error) {
|
||
self.reject(error);
|
||
} else if (arguments.length > 2) {
|
||
self.resolve(array_slice(arguments, 1));
|
||
} else {
|
||
self.resolve(value);
|
||
}
|
||
};
|
||
};
|
||
|
||
/**
|
||
* @param resolver {Function} a function that returns nothing and accepts
|
||
* the resolve, reject, and notify functions for a deferred.
|
||
* @returns a promise that may be resolved with the given resolve and reject
|
||
* functions, or rejected by a thrown exception in resolver
|
||
*/
|
||
Q.Promise = promise; // ES6
|
||
Q.promise = promise;
|
||
function promise(resolver) {
|
||
if (typeof resolver !== "function") {
|
||
throw new TypeError("resolver must be a function.");
|
||
}
|
||
var deferred = defer();
|
||
try {
|
||
resolver(deferred.resolve, deferred.reject, deferred.notify);
|
||
} catch (reason) {
|
||
deferred.reject(reason);
|
||
}
|
||
return deferred.promise;
|
||
}
|
||
|
||
promise.race = race; // ES6
|
||
promise.all = all; // ES6
|
||
promise.reject = reject; // ES6
|
||
promise.resolve = Q; // ES6
|
||
|
||
// XXX experimental. This method is a way to denote that a local value is
|
||
// serializable and should be immediately dispatched to a remote upon request,
|
||
// instead of passing a reference.
|
||
Q.passByCopy = function (object) {
|
||
//freeze(object);
|
||
//passByCopies.set(object, true);
|
||
return object;
|
||
};
|
||
|
||
Promise.prototype.passByCopy = function () {
|
||
//freeze(object);
|
||
//passByCopies.set(object, true);
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* If two promises eventually fulfill to the same value, promises that value,
|
||
* but otherwise rejects.
|
||
* @param x {Any*}
|
||
* @param y {Any*}
|
||
* @returns {Any*} a promise for x and y if they are the same, but a rejection
|
||
* otherwise.
|
||
*
|
||
*/
|
||
Q.join = function (x, y) {
|
||
return Q(x).join(y);
|
||
};
|
||
|
||
Promise.prototype.join = function (that) {
|
||
return Q([this, that]).spread(function (x, y) {
|
||
if (x === y) {
|
||
// TODO: "===" should be Object.is or equiv
|
||
return x;
|
||
} else {
|
||
throw new Error("Q can't join: not the same: " + x + " " + y);
|
||
}
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Returns a promise for the first of an array of promises to become settled.
|
||
* @param answers {Array[Any*]} promises to race
|
||
* @returns {Any*} the first promise to be settled
|
||
*/
|
||
Q.race = race;
|
||
function race(answerPs) {
|
||
return promise(function (resolve, reject) {
|
||
// Switch to this once we can assume at least ES5
|
||
// answerPs.forEach(function (answerP) {
|
||
// Q(answerP).then(resolve, reject);
|
||
// });
|
||
// Use this in the meantime
|
||
for (var i = 0, len = answerPs.length; i < len; i++) {
|
||
Q(answerPs[i]).then(resolve, reject);
|
||
}
|
||
});
|
||
}
|
||
|
||
Promise.prototype.race = function () {
|
||
return this.then(Q.race);
|
||
};
|
||
|
||
/**
|
||
* Constructs a Promise with a promise descriptor object and optional fallback
|
||
* function. The descriptor contains methods like when(rejected), get(name),
|
||
* set(name, value), post(name, args), and delete(name), which all
|
||
* return either a value, a promise for a value, or a rejection. The fallback
|
||
* accepts the operation name, a resolver, and any further arguments that would
|
||
* have been forwarded to the appropriate method above had a method been
|
||
* provided with the proper name. The API makes no guarantees about the nature
|
||
* of the returned object, apart from that it is usable whereever promises are
|
||
* bought and sold.
|
||
*/
|
||
Q.makePromise = Promise;
|
||
function Promise(descriptor, fallback, inspect) {
|
||
if (fallback === void 0) {
|
||
fallback = function (op) {
|
||
return reject(new Error(
|
||
"Promise does not support operation: " + op
|
||
));
|
||
};
|
||
}
|
||
if (inspect === void 0) {
|
||
inspect = function () {
|
||
return {state: "unknown"};
|
||
};
|
||
}
|
||
|
||
var promise = object_create(Promise.prototype);
|
||
|
||
promise.promiseDispatch = function (resolve, op, args) {
|
||
var result;
|
||
try {
|
||
if (descriptor[op]) {
|
||
result = descriptor[op].apply(promise, args);
|
||
} else {
|
||
result = fallback.call(promise, op, args);
|
||
}
|
||
} catch (exception) {
|
||
result = reject(exception);
|
||
}
|
||
if (resolve) {
|
||
resolve(result);
|
||
}
|
||
};
|
||
|
||
promise.inspect = inspect;
|
||
|
||
// XXX deprecated `valueOf` and `exception` support
|
||
if (inspect) {
|
||
var inspected = inspect();
|
||
if (inspected.state === "rejected") {
|
||
promise.exception = inspected.reason;
|
||
}
|
||
|
||
promise.valueOf = function () {
|
||
var inspected = inspect();
|
||
if (inspected.state === "pending" ||
|
||
inspected.state === "rejected") {
|
||
return promise;
|
||
}
|
||
return inspected.value;
|
||
};
|
||
}
|
||
|
||
return promise;
|
||
}
|
||
|
||
Promise.prototype.toString = function () {
|
||
return "[object Promise]";
|
||
};
|
||
|
||
Promise.prototype.then = function (fulfilled, rejected, progressed) {
|
||
var self = this;
|
||
var deferred = defer();
|
||
var done = false; // ensure the untrusted promise makes at most a
|
||
// single call to one of the callbacks
|
||
|
||
function _fulfilled(value) {
|
||
try {
|
||
return typeof fulfilled === "function" ? fulfilled(value) : value;
|
||
} catch (exception) {
|
||
return reject(exception);
|
||
}
|
||
}
|
||
|
||
function _rejected(exception) {
|
||
if (typeof rejected === "function") {
|
||
makeStackTraceLong(exception, self);
|
||
try {
|
||
return rejected(exception);
|
||
} catch (newException) {
|
||
return reject(newException);
|
||
}
|
||
}
|
||
return reject(exception);
|
||
}
|
||
|
||
function _progressed(value) {
|
||
return typeof progressed === "function" ? progressed(value) : value;
|
||
}
|
||
|
||
Q.nextTick(function () {
|
||
self.promiseDispatch(function (value) {
|
||
if (done) {
|
||
return;
|
||
}
|
||
done = true;
|
||
|
||
deferred.resolve(_fulfilled(value));
|
||
}, "when", [function (exception) {
|
||
if (done) {
|
||
return;
|
||
}
|
||
done = true;
|
||
|
||
deferred.resolve(_rejected(exception));
|
||
}]);
|
||
});
|
||
|
||
// Progress propagator need to be attached in the current tick.
|
||
self.promiseDispatch(void 0, "when", [void 0, function (value) {
|
||
var newValue;
|
||
var threw = false;
|
||
try {
|
||
newValue = _progressed(value);
|
||
} catch (e) {
|
||
threw = true;
|
||
if (Q.onerror) {
|
||
Q.onerror(e);
|
||
} else {
|
||
throw e;
|
||
}
|
||
}
|
||
|
||
if (!threw) {
|
||
deferred.notify(newValue);
|
||
}
|
||
}]);
|
||
|
||
return deferred.promise;
|
||
};
|
||
|
||
Q.tap = function (promise, callback) {
|
||
return Q(promise).tap(callback);
|
||
};
|
||
|
||
/**
|
||
* Works almost like "finally", but not called for rejections.
|
||
* Original resolution value is passed through callback unaffected.
|
||
* Callback may return a promise that will be awaited for.
|
||
* @param {Function} callback
|
||
* @returns {Q.Promise}
|
||
* @example
|
||
* doSomething()
|
||
* .then(...)
|
||
* .tap(console.log)
|
||
* .then(...);
|
||
*/
|
||
Promise.prototype.tap = function (callback) {
|
||
callback = Q(callback);
|
||
|
||
return this.then(function (value) {
|
||
return callback.fcall(value).thenResolve(value);
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Registers an observer on a promise.
|
||
*
|
||
* Guarantees:
|
||
*
|
||
* 1. that fulfilled and rejected will be called only once.
|
||
* 2. that either the fulfilled callback or the rejected callback will be
|
||
* called, but not both.
|
||
* 3. that fulfilled and rejected will not be called in this turn.
|
||
*
|
||
* @param value promise or immediate reference to observe
|
||
* @param fulfilled function to be called with the fulfilled value
|
||
* @param rejected function to be called with the rejection exception
|
||
* @param progressed function to be called on any progress notifications
|
||
* @return promise for the return value from the invoked callback
|
||
*/
|
||
Q.when = when;
|
||
function when(value, fulfilled, rejected, progressed) {
|
||
return Q(value).then(fulfilled, rejected, progressed);
|
||
}
|
||
|
||
Promise.prototype.thenResolve = function (value) {
|
||
return this.then(function () { return value; });
|
||
};
|
||
|
||
Q.thenResolve = function (promise, value) {
|
||
return Q(promise).thenResolve(value);
|
||
};
|
||
|
||
Promise.prototype.thenReject = function (reason) {
|
||
return this.then(function () { throw reason; });
|
||
};
|
||
|
||
Q.thenReject = function (promise, reason) {
|
||
return Q(promise).thenReject(reason);
|
||
};
|
||
|
||
/**
|
||
* If an object is not a promise, it is as "near" as possible.
|
||
* If a promise is rejected, it is as "near" as possible too.
|
||
* If it’s a fulfilled promise, the fulfillment value is nearer.
|
||
* If it’s a deferred promise and the deferred has been resolved, the
|
||
* resolution is "nearer".
|
||
* @param object
|
||
* @returns most resolved (nearest) form of the object
|
||
*/
|
||
|
||
// XXX should we re-do this?
|
||
Q.nearer = nearer;
|
||
function nearer(value) {
|
||
if (isPromise(value)) {
|
||
var inspected = value.inspect();
|
||
if (inspected.state === "fulfilled") {
|
||
return inspected.value;
|
||
}
|
||
}
|
||
return value;
|
||
}
|
||
|
||
/**
|
||
* @returns whether the given object is a promise.
|
||
* Otherwise it is a fulfilled value.
|
||
*/
|
||
Q.isPromise = isPromise;
|
||
function isPromise(object) {
|
||
return object instanceof Promise;
|
||
}
|
||
|
||
Q.isPromiseAlike = isPromiseAlike;
|
||
function isPromiseAlike(object) {
|
||
return isObject(object) && typeof object.then === "function";
|
||
}
|
||
|
||
/**
|
||
* @returns whether the given object is a pending promise, meaning not
|
||
* fulfilled or rejected.
|
||
*/
|
||
Q.isPending = isPending;
|
||
function isPending(object) {
|
||
return isPromise(object) && object.inspect().state === "pending";
|
||
}
|
||
|
||
Promise.prototype.isPending = function () {
|
||
return this.inspect().state === "pending";
|
||
};
|
||
|
||
/**
|
||
* @returns whether the given object is a value or fulfilled
|
||
* promise.
|
||
*/
|
||
Q.isFulfilled = isFulfilled;
|
||
function isFulfilled(object) {
|
||
return !isPromise(object) || object.inspect().state === "fulfilled";
|
||
}
|
||
|
||
Promise.prototype.isFulfilled = function () {
|
||
return this.inspect().state === "fulfilled";
|
||
};
|
||
|
||
/**
|
||
* @returns whether the given object is a rejected promise.
|
||
*/
|
||
Q.isRejected = isRejected;
|
||
function isRejected(object) {
|
||
return isPromise(object) && object.inspect().state === "rejected";
|
||
}
|
||
|
||
Promise.prototype.isRejected = function () {
|
||
return this.inspect().state === "rejected";
|
||
};
|
||
|
||
//// BEGIN UNHANDLED REJECTION TRACKING
|
||
|
||
// This promise library consumes exceptions thrown in handlers so they can be
|
||
// handled by a subsequent promise. The exceptions get added to this array when
|
||
// they are created, and removed when they are handled. Note that in ES6 or
|
||
// shimmed environments, this would naturally be a `Set`.
|
||
var unhandledReasons = [];
|
||
var unhandledRejections = [];
|
||
var reportedUnhandledRejections = [];
|
||
var trackUnhandledRejections = true;
|
||
|
||
function resetUnhandledRejections() {
|
||
unhandledReasons.length = 0;
|
||
unhandledRejections.length = 0;
|
||
|
||
if (!trackUnhandledRejections) {
|
||
trackUnhandledRejections = true;
|
||
}
|
||
}
|
||
|
||
function trackRejection(promise, reason) {
|
||
if (!trackUnhandledRejections) {
|
||
return;
|
||
}
|
||
if (typeof process === "object" && typeof process.emit === "function") {
|
||
Q.nextTick.runAfter(function () {
|
||
if (array_indexOf(unhandledRejections, promise) !== -1) {
|
||
process.emit("unhandledRejection", reason, promise);
|
||
reportedUnhandledRejections.push(promise);
|
||
}
|
||
});
|
||
}
|
||
|
||
unhandledRejections.push(promise);
|
||
if (reason && typeof reason.stack !== "undefined") {
|
||
unhandledReasons.push(reason.stack);
|
||
} else {
|
||
unhandledReasons.push("(no stack) " + reason);
|
||
}
|
||
}
|
||
|
||
function untrackRejection(promise) {
|
||
if (!trackUnhandledRejections) {
|
||
return;
|
||
}
|
||
|
||
var at = array_indexOf(unhandledRejections, promise);
|
||
if (at !== -1) {
|
||
if (typeof process === "object" && typeof process.emit === "function") {
|
||
Q.nextTick.runAfter(function () {
|
||
var atReport = array_indexOf(reportedUnhandledRejections, promise);
|
||
if (atReport !== -1) {
|
||
process.emit("rejectionHandled", unhandledReasons[at], promise);
|
||
reportedUnhandledRejections.splice(atReport, 1);
|
||
}
|
||
});
|
||
}
|
||
unhandledRejections.splice(at, 1);
|
||
unhandledReasons.splice(at, 1);
|
||
}
|
||
}
|
||
|
||
Q.resetUnhandledRejections = resetUnhandledRejections;
|
||
|
||
Q.getUnhandledReasons = function () {
|
||
// Make a copy so that consumers can't interfere with our internal state.
|
||
return unhandledReasons.slice();
|
||
};
|
||
|
||
Q.stopUnhandledRejectionTracking = function () {
|
||
resetUnhandledRejections();
|
||
trackUnhandledRejections = false;
|
||
};
|
||
|
||
resetUnhandledRejections();
|
||
|
||
//// END UNHANDLED REJECTION TRACKING
|
||
|
||
/**
|
||
* Constructs a rejected promise.
|
||
* @param reason value describing the failure
|
||
*/
|
||
Q.reject = reject;
|
||
function reject(reason) {
|
||
var rejection = Promise({
|
||
"when": function (rejected) {
|
||
// note that the error has been handled
|
||
if (rejected) {
|
||
untrackRejection(this);
|
||
}
|
||
return rejected ? rejected(reason) : this;
|
||
}
|
||
}, function fallback() {
|
||
return this;
|
||
}, function inspect() {
|
||
return { state: "rejected", reason: reason };
|
||
});
|
||
|
||
// Note that the reason has not been handled.
|
||
trackRejection(rejection, reason);
|
||
|
||
return rejection;
|
||
}
|
||
|
||
/**
|
||
* Constructs a fulfilled promise for an immediate reference.
|
||
* @param value immediate reference
|
||
*/
|
||
Q.fulfill = fulfill;
|
||
function fulfill(value) {
|
||
return Promise({
|
||
"when": function () {
|
||
return value;
|
||
},
|
||
"get": function (name) {
|
||
return value[name];
|
||
},
|
||
"set": function (name, rhs) {
|
||
value[name] = rhs;
|
||
},
|
||
"delete": function (name) {
|
||
delete value[name];
|
||
},
|
||
"post": function (name, args) {
|
||
// Mark Miller proposes that post with no name should apply a
|
||
// promised function.
|
||
if (name === null || name === void 0) {
|
||
return value.apply(void 0, args);
|
||
} else {
|
||
return value[name].apply(value, args);
|
||
}
|
||
},
|
||
"apply": function (thisp, args) {
|
||
return value.apply(thisp, args);
|
||
},
|
||
"keys": function () {
|
||
return object_keys(value);
|
||
}
|
||
}, void 0, function inspect() {
|
||
return { state: "fulfilled", value: value };
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Converts thenables to Q promises.
|
||
* @param promise thenable promise
|
||
* @returns a Q promise
|
||
*/
|
||
function coerce(promise) {
|
||
var deferred = defer();
|
||
Q.nextTick(function () {
|
||
try {
|
||
promise.then(deferred.resolve, deferred.reject, deferred.notify);
|
||
} catch (exception) {
|
||
deferred.reject(exception);
|
||
}
|
||
});
|
||
return deferred.promise;
|
||
}
|
||
|
||
/**
|
||
* Annotates an object such that it will never be
|
||
* transferred away from this process over any promise
|
||
* communication channel.
|
||
* @param object
|
||
* @returns promise a wrapping of that object that
|
||
* additionally responds to the "isDef" message
|
||
* without a rejection.
|
||
*/
|
||
Q.master = master;
|
||
function master(object) {
|
||
return Promise({
|
||
"isDef": function () {}
|
||
}, function fallback(op, args) {
|
||
return dispatch(object, op, args);
|
||
}, function () {
|
||
return Q(object).inspect();
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Spreads the values of a promised array of arguments into the
|
||
* fulfillment callback.
|
||
* @param fulfilled callback that receives variadic arguments from the
|
||
* promised array
|
||
* @param rejected callback that receives the exception if the promise
|
||
* is rejected.
|
||
* @returns a promise for the return value or thrown exception of
|
||
* either callback.
|
||
*/
|
||
Q.spread = spread;
|
||
function spread(value, fulfilled, rejected) {
|
||
return Q(value).spread(fulfilled, rejected);
|
||
}
|
||
|
||
Promise.prototype.spread = function (fulfilled, rejected) {
|
||
return this.all().then(function (array) {
|
||
return fulfilled.apply(void 0, array);
|
||
}, rejected);
|
||
};
|
||
|
||
/**
|
||
* The async function is a decorator for generator functions, turning
|
||
* them into asynchronous generators. Although generators are only part
|
||
* of the newest ECMAScript 6 drafts, this code does not cause syntax
|
||
* errors in older engines. This code should continue to work and will
|
||
* in fact improve over time as the language improves.
|
||
*
|
||
* ES6 generators are currently part of V8 version 3.19 with the
|
||
* --harmony-generators runtime flag enabled. SpiderMonkey has had them
|
||
* for longer, but under an older Python-inspired form. This function
|
||
* works on both kinds of generators.
|
||
*
|
||
* Decorates a generator function such that:
|
||
* - it may yield promises
|
||
* - execution will continue when that promise is fulfilled
|
||
* - the value of the yield expression will be the fulfilled value
|
||
* - it returns a promise for the return value (when the generator
|
||
* stops iterating)
|
||
* - the decorated function returns a promise for the return value
|
||
* of the generator or the first rejected promise among those
|
||
* yielded.
|
||
* - if an error is thrown in the generator, it propagates through
|
||
* every following yield until it is caught, or until it escapes
|
||
* the generator function altogether, and is translated into a
|
||
* rejection for the promise returned by the decorated generator.
|
||
*/
|
||
Q.async = async;
|
||
function async(makeGenerator) {
|
||
return function () {
|
||
// when verb is "send", arg is a value
|
||
// when verb is "throw", arg is an exception
|
||
function continuer(verb, arg) {
|
||
var result;
|
||
|
||
// Until V8 3.19 / Chromium 29 is released, SpiderMonkey is the only
|
||
// engine that has a deployed base of browsers that support generators.
|
||
// However, SM's generators use the Python-inspired semantics of
|
||
// outdated ES6 drafts. We would like to support ES6, but we'd also
|
||
// like to make it possible to use generators in deployed browsers, so
|
||
// we also support Python-style generators. At some point we can remove
|
||
// this block.
|
||
|
||
if (typeof StopIteration === "undefined") {
|
||
// ES6 Generators
|
||
try {
|
||
result = generator[verb](arg);
|
||
} catch (exception) {
|
||
return reject(exception);
|
||
}
|
||
if (result.done) {
|
||
return Q(result.value);
|
||
} else {
|
||
return when(result.value, callback, errback);
|
||
}
|
||
} else {
|
||
// SpiderMonkey Generators
|
||
// FIXME: Remove this case when SM does ES6 generators.
|
||
try {
|
||
result = generator[verb](arg);
|
||
} catch (exception) {
|
||
if (isStopIteration(exception)) {
|
||
return Q(exception.value);
|
||
} else {
|
||
return reject(exception);
|
||
}
|
||
}
|
||
return when(result, callback, errback);
|
||
}
|
||
}
|
||
var generator = makeGenerator.apply(this, arguments);
|
||
var callback = continuer.bind(continuer, "next");
|
||
var errback = continuer.bind(continuer, "throw");
|
||
return callback();
|
||
};
|
||
}
|
||
|
||
/**
|
||
* The spawn function is a small wrapper around async that immediately
|
||
* calls the generator and also ends the promise chain, so that any
|
||
* unhandled errors are thrown instead of forwarded to the error
|
||
* handler. This is useful because it's extremely common to run
|
||
* generators at the top-level to work with libraries.
|
||
*/
|
||
Q.spawn = spawn;
|
||
function spawn(makeGenerator) {
|
||
Q.done(Q.async(makeGenerator)());
|
||
}
|
||
|
||
// FIXME: Remove this interface once ES6 generators are in SpiderMonkey.
|
||
/**
|
||
* Throws a ReturnValue exception to stop an asynchronous generator.
|
||
*
|
||
* This interface is a stop-gap measure to support generator return
|
||
* values in older Firefox/SpiderMonkey. In browsers that support ES6
|
||
* generators like Chromium 29, just use "return" in your generator
|
||
* functions.
|
||
*
|
||
* @param value the return value for the surrounding generator
|
||
* @throws ReturnValue exception with the value.
|
||
* @example
|
||
* // ES6 style
|
||
* Q.async(function* () {
|
||
* var foo = yield getFooPromise();
|
||
* var bar = yield getBarPromise();
|
||
* return foo + bar;
|
||
* })
|
||
* // Older SpiderMonkey style
|
||
* Q.async(function () {
|
||
* var foo = yield getFooPromise();
|
||
* var bar = yield getBarPromise();
|
||
* Q.return(foo + bar);
|
||
* })
|
||
*/
|
||
Q["return"] = _return;
|
||
function _return(value) {
|
||
throw new QReturnValue(value);
|
||
}
|
||
|
||
/**
|
||
* The promised function decorator ensures that any promise arguments
|
||
* are settled and passed as values (`this` is also settled and passed
|
||
* as a value). It will also ensure that the result of a function is
|
||
* always a promise.
|
||
*
|
||
* @example
|
||
* var add = Q.promised(function (a, b) {
|
||
* return a + b;
|
||
* });
|
||
* add(Q(a), Q(B));
|
||
*
|
||
* @param {function} callback The function to decorate
|
||
* @returns {function} a function that has been decorated.
|
||
*/
|
||
Q.promised = promised;
|
||
function promised(callback) {
|
||
return function () {
|
||
return spread([this, all(arguments)], function (self, args) {
|
||
return callback.apply(self, args);
|
||
});
|
||
};
|
||
}
|
||
|
||
/**
|
||
* sends a message to a value in a future turn
|
||
* @param object* the recipient
|
||
* @param op the name of the message operation, e.g., "when",
|
||
* @param args further arguments to be forwarded to the operation
|
||
* @returns result {Promise} a promise for the result of the operation
|
||
*/
|
||
Q.dispatch = dispatch;
|
||
function dispatch(object, op, args) {
|
||
return Q(object).dispatch(op, args);
|
||
}
|
||
|
||
Promise.prototype.dispatch = function (op, args) {
|
||
var self = this;
|
||
var deferred = defer();
|
||
Q.nextTick(function () {
|
||
self.promiseDispatch(deferred.resolve, op, args);
|
||
});
|
||
return deferred.promise;
|
||
};
|
||
|
||
/**
|
||
* Gets the value of a property in a future turn.
|
||
* @param object promise or immediate reference for target object
|
||
* @param name name of property to get
|
||
* @return promise for the property value
|
||
*/
|
||
Q.get = function (object, key) {
|
||
return Q(object).dispatch("get", [key]);
|
||
};
|
||
|
||
Promise.prototype.get = function (key) {
|
||
return this.dispatch("get", [key]);
|
||
};
|
||
|
||
/**
|
||
* Sets the value of a property in a future turn.
|
||
* @param object promise or immediate reference for object object
|
||
* @param name name of property to set
|
||
* @param value new value of property
|
||
* @return promise for the return value
|
||
*/
|
||
Q.set = function (object, key, value) {
|
||
return Q(object).dispatch("set", [key, value]);
|
||
};
|
||
|
||
Promise.prototype.set = function (key, value) {
|
||
return this.dispatch("set", [key, value]);
|
||
};
|
||
|
||
/**
|
||
* Deletes a property in a future turn.
|
||
* @param object promise or immediate reference for target object
|
||
* @param name name of property to delete
|
||
* @return promise for the return value
|
||
*/
|
||
Q.del = // XXX legacy
|
||
Q["delete"] = function (object, key) {
|
||
return Q(object).dispatch("delete", [key]);
|
||
};
|
||
|
||
Promise.prototype.del = // XXX legacy
|
||
Promise.prototype["delete"] = function (key) {
|
||
return this.dispatch("delete", [key]);
|
||
};
|
||
|
||
/**
|
||
* Invokes a method in a future turn.
|
||
* @param object promise or immediate reference for target object
|
||
* @param name name of method to invoke
|
||
* @param value a value to post, typically an array of
|
||
* invocation arguments for promises that
|
||
* are ultimately backed with `resolve` values,
|
||
* as opposed to those backed with URLs
|
||
* wherein the posted value can be any
|
||
* JSON serializable object.
|
||
* @return promise for the return value
|
||
*/
|
||
// bound locally because it is used by other methods
|
||
Q.mapply = // XXX As proposed by "Redsandro"
|
||
Q.post = function (object, name, args) {
|
||
return Q(object).dispatch("post", [name, args]);
|
||
};
|
||
|
||
Promise.prototype.mapply = // XXX As proposed by "Redsandro"
|
||
Promise.prototype.post = function (name, args) {
|
||
return this.dispatch("post", [name, args]);
|
||
};
|
||
|
||
/**
|
||
* Invokes a method in a future turn.
|
||
* @param object promise or immediate reference for target object
|
||
* @param name name of method to invoke
|
||
* @param ...args array of invocation arguments
|
||
* @return promise for the return value
|
||
*/
|
||
Q.send = // XXX Mark Miller's proposed parlance
|
||
Q.mcall = // XXX As proposed by "Redsandro"
|
||
Q.invoke = function (object, name /*...args*/) {
|
||
return Q(object).dispatch("post", [name, array_slice(arguments, 2)]);
|
||
};
|
||
|
||
Promise.prototype.send = // XXX Mark Miller's proposed parlance
|
||
Promise.prototype.mcall = // XXX As proposed by "Redsandro"
|
||
Promise.prototype.invoke = function (name /*...args*/) {
|
||
return this.dispatch("post", [name, array_slice(arguments, 1)]);
|
||
};
|
||
|
||
/**
|
||
* Applies the promised function in a future turn.
|
||
* @param object promise or immediate reference for target function
|
||
* @param args array of application arguments
|
||
*/
|
||
Q.fapply = function (object, args) {
|
||
return Q(object).dispatch("apply", [void 0, args]);
|
||
};
|
||
|
||
Promise.prototype.fapply = function (args) {
|
||
return this.dispatch("apply", [void 0, args]);
|
||
};
|
||
|
||
/**
|
||
* Calls the promised function in a future turn.
|
||
* @param object promise or immediate reference for target function
|
||
* @param ...args array of application arguments
|
||
*/
|
||
Q["try"] =
|
||
Q.fcall = function (object /* ...args*/) {
|
||
return Q(object).dispatch("apply", [void 0, array_slice(arguments, 1)]);
|
||
};
|
||
|
||
Promise.prototype.fcall = function (/*...args*/) {
|
||
return this.dispatch("apply", [void 0, array_slice(arguments)]);
|
||
};
|
||
|
||
/**
|
||
* Binds the promised function, transforming return values into a fulfilled
|
||
* promise and thrown errors into a rejected one.
|
||
* @param object promise or immediate reference for target function
|
||
* @param ...args array of application arguments
|
||
*/
|
||
Q.fbind = function (object /*...args*/) {
|
||
var promise = Q(object);
|
||
var args = array_slice(arguments, 1);
|
||
return function fbound() {
|
||
return promise.dispatch("apply", [
|
||
this,
|
||
args.concat(array_slice(arguments))
|
||
]);
|
||
};
|
||
};
|
||
Promise.prototype.fbind = function (/*...args*/) {
|
||
var promise = this;
|
||
var args = array_slice(arguments);
|
||
return function fbound() {
|
||
return promise.dispatch("apply", [
|
||
this,
|
||
args.concat(array_slice(arguments))
|
||
]);
|
||
};
|
||
};
|
||
|
||
/**
|
||
* Requests the names of the owned properties of a promised
|
||
* object in a future turn.
|
||
* @param object promise or immediate reference for target object
|
||
* @return promise for the keys of the eventually settled object
|
||
*/
|
||
Q.keys = function (object) {
|
||
return Q(object).dispatch("keys", []);
|
||
};
|
||
|
||
Promise.prototype.keys = function () {
|
||
return this.dispatch("keys", []);
|
||
};
|
||
|
||
/**
|
||
* Turns an array of promises into a promise for an array. If any of
|
||
* the promises gets rejected, the whole array is rejected immediately.
|
||
* @param {Array*} an array (or promise for an array) of values (or
|
||
* promises for values)
|
||
* @returns a promise for an array of the corresponding values
|
||
*/
|
||
// By Mark Miller
|
||
// http://wiki.ecmascript.org/doku.php?id=strawman:concurrency&rev=1308776521#allfulfilled
|
||
Q.all = all;
|
||
function all(promises) {
|
||
return when(promises, function (promises) {
|
||
var pendingCount = 0;
|
||
var deferred = defer();
|
||
array_reduce(promises, function (undefined, promise, index) {
|
||
var snapshot;
|
||
if (
|
||
isPromise(promise) &&
|
||
(snapshot = promise.inspect()).state === "fulfilled"
|
||
) {
|
||
promises[index] = snapshot.value;
|
||
} else {
|
||
++pendingCount;
|
||
when(
|
||
promise,
|
||
function (value) {
|
||
promises[index] = value;
|
||
if (--pendingCount === 0) {
|
||
deferred.resolve(promises);
|
||
}
|
||
},
|
||
deferred.reject,
|
||
function (progress) {
|
||
deferred.notify({ index: index, value: progress });
|
||
}
|
||
);
|
||
}
|
||
}, void 0);
|
||
if (pendingCount === 0) {
|
||
deferred.resolve(promises);
|
||
}
|
||
return deferred.promise;
|
||
});
|
||
}
|
||
|
||
Promise.prototype.all = function () {
|
||
return all(this);
|
||
};
|
||
|
||
/**
|
||
* Returns the first resolved promise of an array. Prior rejected promises are
|
||
* ignored. Rejects only if all promises are rejected.
|
||
* @param {Array*} an array containing values or promises for values
|
||
* @returns a promise fulfilled with the value of the first resolved promise,
|
||
* or a rejected promise if all promises are rejected.
|
||
*/
|
||
Q.any = any;
|
||
|
||
function any(promises) {
|
||
if (promises.length === 0) {
|
||
return Q.resolve();
|
||
}
|
||
|
||
var deferred = Q.defer();
|
||
var pendingCount = 0;
|
||
array_reduce(promises, function (prev, current, index) {
|
||
var promise = promises[index];
|
||
|
||
pendingCount++;
|
||
|
||
when(promise, onFulfilled, onRejected, onProgress);
|
||
function onFulfilled(result) {
|
||
deferred.resolve(result);
|
||
}
|
||
function onRejected(err) {
|
||
pendingCount--;
|
||
if (pendingCount === 0) {
|
||
var rejection = err || new Error("" + err);
|
||
|
||
rejection.message = ("Q can't get fulfillment value from any promise, all " +
|
||
"promises were rejected. Last error message: " + rejection.message);
|
||
|
||
deferred.reject(rejection);
|
||
}
|
||
}
|
||
function onProgress(progress) {
|
||
deferred.notify({
|
||
index: index,
|
||
value: progress
|
||
});
|
||
}
|
||
}, undefined);
|
||
|
||
return deferred.promise;
|
||
}
|
||
|
||
Promise.prototype.any = function () {
|
||
return any(this);
|
||
};
|
||
|
||
/**
|
||
* Waits for all promises to be settled, either fulfilled or
|
||
* rejected. This is distinct from `all` since that would stop
|
||
* waiting at the first rejection. The promise returned by
|
||
* `allResolved` will never be rejected.
|
||
* @param promises a promise for an array (or an array) of promises
|
||
* (or values)
|
||
* @return a promise for an array of promises
|
||
*/
|
||
Q.allResolved = deprecate(allResolved, "allResolved", "allSettled");
|
||
function allResolved(promises) {
|
||
return when(promises, function (promises) {
|
||
promises = array_map(promises, Q);
|
||
return when(all(array_map(promises, function (promise) {
|
||
return when(promise, noop, noop);
|
||
})), function () {
|
||
return promises;
|
||
});
|
||
});
|
||
}
|
||
|
||
Promise.prototype.allResolved = function () {
|
||
return allResolved(this);
|
||
};
|
||
|
||
/**
|
||
* @see Promise#allSettled
|
||
*/
|
||
Q.allSettled = allSettled;
|
||
function allSettled(promises) {
|
||
return Q(promises).allSettled();
|
||
}
|
||
|
||
/**
|
||
* Turns an array of promises into a promise for an array of their states (as
|
||
* returned by `inspect`) when they have all settled.
|
||
* @param {Array[Any*]} values an array (or promise for an array) of values (or
|
||
* promises for values)
|
||
* @returns {Array[State]} an array of states for the respective values.
|
||
*/
|
||
Promise.prototype.allSettled = function () {
|
||
return this.then(function (promises) {
|
||
return all(array_map(promises, function (promise) {
|
||
promise = Q(promise);
|
||
function regardless() {
|
||
return promise.inspect();
|
||
}
|
||
return promise.then(regardless, regardless);
|
||
}));
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Captures the failure of a promise, giving an oportunity to recover
|
||
* with a callback. If the given promise is fulfilled, the returned
|
||
* promise is fulfilled.
|
||
* @param {Any*} promise for something
|
||
* @param {Function} callback to fulfill the returned promise if the
|
||
* given promise is rejected
|
||
* @returns a promise for the return value of the callback
|
||
*/
|
||
Q.fail = // XXX legacy
|
||
Q["catch"] = function (object, rejected) {
|
||
return Q(object).then(void 0, rejected);
|
||
};
|
||
|
||
Promise.prototype.fail = // XXX legacy
|
||
Promise.prototype["catch"] = function (rejected) {
|
||
return this.then(void 0, rejected);
|
||
};
|
||
|
||
/**
|
||
* Attaches a listener that can respond to progress notifications from a
|
||
* promise's originating deferred. This listener receives the exact arguments
|
||
* passed to ``deferred.notify``.
|
||
* @param {Any*} promise for something
|
||
* @param {Function} callback to receive any progress notifications
|
||
* @returns the given promise, unchanged
|
||
*/
|
||
Q.progress = progress;
|
||
function progress(object, progressed) {
|
||
return Q(object).then(void 0, void 0, progressed);
|
||
}
|
||
|
||
Promise.prototype.progress = function (progressed) {
|
||
return this.then(void 0, void 0, progressed);
|
||
};
|
||
|
||
/**
|
||
* Provides an opportunity to observe the settling of a promise,
|
||
* regardless of whether the promise is fulfilled or rejected. Forwards
|
||
* the resolution to the returned promise when the callback is done.
|
||
* The callback can return a promise to defer completion.
|
||
* @param {Any*} promise
|
||
* @param {Function} callback to observe the resolution of the given
|
||
* promise, takes no arguments.
|
||
* @returns a promise for the resolution of the given promise when
|
||
* ``fin`` is done.
|
||
*/
|
||
Q.fin = // XXX legacy
|
||
Q["finally"] = function (object, callback) {
|
||
return Q(object)["finally"](callback);
|
||
};
|
||
|
||
Promise.prototype.fin = // XXX legacy
|
||
Promise.prototype["finally"] = function (callback) {
|
||
if (!callback || typeof callback.apply !== "function") {
|
||
throw new Error("Q can't apply finally callback");
|
||
}
|
||
callback = Q(callback);
|
||
return this.then(function (value) {
|
||
return callback.fcall().then(function () {
|
||
return value;
|
||
});
|
||
}, function (reason) {
|
||
// TODO attempt to recycle the rejection with "this".
|
||
return callback.fcall().then(function () {
|
||
throw reason;
|
||
});
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Terminates a chain of promises, forcing rejections to be
|
||
* thrown as exceptions.
|
||
* @param {Any*} promise at the end of a chain of promises
|
||
* @returns nothing
|
||
*/
|
||
Q.done = function (object, fulfilled, rejected, progress) {
|
||
return Q(object).done(fulfilled, rejected, progress);
|
||
};
|
||
|
||
Promise.prototype.done = function (fulfilled, rejected, progress) {
|
||
var onUnhandledError = function (error) {
|
||
// forward to a future turn so that ``when``
|
||
// does not catch it and turn it into a rejection.
|
||
Q.nextTick(function () {
|
||
makeStackTraceLong(error, promise);
|
||
if (Q.onerror) {
|
||
Q.onerror(error);
|
||
} else {
|
||
throw error;
|
||
}
|
||
});
|
||
};
|
||
|
||
// Avoid unnecessary `nextTick`ing via an unnecessary `when`.
|
||
var promise = fulfilled || rejected || progress ?
|
||
this.then(fulfilled, rejected, progress) :
|
||
this;
|
||
|
||
if (typeof process === "object" && process && process.domain) {
|
||
onUnhandledError = process.domain.bind(onUnhandledError);
|
||
}
|
||
|
||
promise.then(void 0, onUnhandledError);
|
||
};
|
||
|
||
/**
|
||
* Causes a promise to be rejected if it does not get fulfilled before
|
||
* some milliseconds time out.
|
||
* @param {Any*} promise
|
||
* @param {Number} milliseconds timeout
|
||
* @param {Any*} custom error message or Error object (optional)
|
||
* @returns a promise for the resolution of the given promise if it is
|
||
* fulfilled before the timeout, otherwise rejected.
|
||
*/
|
||
Q.timeout = function (object, ms, error) {
|
||
return Q(object).timeout(ms, error);
|
||
};
|
||
|
||
Promise.prototype.timeout = function (ms, error) {
|
||
var deferred = defer();
|
||
var timeoutId = setTimeout(function () {
|
||
if (!error || "string" === typeof error) {
|
||
error = new Error(error || "Timed out after " + ms + " ms");
|
||
error.code = "ETIMEDOUT";
|
||
}
|
||
deferred.reject(error);
|
||
}, ms);
|
||
|
||
this.then(function (value) {
|
||
clearTimeout(timeoutId);
|
||
deferred.resolve(value);
|
||
}, function (exception) {
|
||
clearTimeout(timeoutId);
|
||
deferred.reject(exception);
|
||
}, deferred.notify);
|
||
|
||
return deferred.promise;
|
||
};
|
||
|
||
/**
|
||
* Returns a promise for the given value (or promised value), some
|
||
* milliseconds after it resolved. Passes rejections immediately.
|
||
* @param {Any*} promise
|
||
* @param {Number} milliseconds
|
||
* @returns a promise for the resolution of the given promise after milliseconds
|
||
* time has elapsed since the resolution of the given promise.
|
||
* If the given promise rejects, that is passed immediately.
|
||
*/
|
||
Q.delay = function (object, timeout) {
|
||
if (timeout === void 0) {
|
||
timeout = object;
|
||
object = void 0;
|
||
}
|
||
return Q(object).delay(timeout);
|
||
};
|
||
|
||
Promise.prototype.delay = function (timeout) {
|
||
return this.then(function (value) {
|
||
var deferred = defer();
|
||
setTimeout(function () {
|
||
deferred.resolve(value);
|
||
}, timeout);
|
||
return deferred.promise;
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Passes a continuation to a Node function, which is called with the given
|
||
* arguments provided as an array, and returns a promise.
|
||
*
|
||
* Q.nfapply(FS.readFile, [__filename])
|
||
* .then(function (content) {
|
||
* })
|
||
*
|
||
*/
|
||
Q.nfapply = function (callback, args) {
|
||
return Q(callback).nfapply(args);
|
||
};
|
||
|
||
Promise.prototype.nfapply = function (args) {
|
||
var deferred = defer();
|
||
var nodeArgs = array_slice(args);
|
||
nodeArgs.push(deferred.makeNodeResolver());
|
||
this.fapply(nodeArgs).fail(deferred.reject);
|
||
return deferred.promise;
|
||
};
|
||
|
||
/**
|
||
* Passes a continuation to a Node function, which is called with the given
|
||
* arguments provided individually, and returns a promise.
|
||
* @example
|
||
* Q.nfcall(FS.readFile, __filename)
|
||
* .then(function (content) {
|
||
* })
|
||
*
|
||
*/
|
||
Q.nfcall = function (callback /*...args*/) {
|
||
var args = array_slice(arguments, 1);
|
||
return Q(callback).nfapply(args);
|
||
};
|
||
|
||
Promise.prototype.nfcall = function (/*...args*/) {
|
||
var nodeArgs = array_slice(arguments);
|
||
var deferred = defer();
|
||
nodeArgs.push(deferred.makeNodeResolver());
|
||
this.fapply(nodeArgs).fail(deferred.reject);
|
||
return deferred.promise;
|
||
};
|
||
|
||
/**
|
||
* Wraps a NodeJS continuation passing function and returns an equivalent
|
||
* version that returns a promise.
|
||
* @example
|
||
* Q.nfbind(FS.readFile, __filename)("utf-8")
|
||
* .then(console.log)
|
||
* .done()
|
||
*/
|
||
Q.nfbind =
|
||
Q.denodeify = function (callback /*...args*/) {
|
||
if (callback === undefined) {
|
||
throw new Error("Q can't wrap an undefined function");
|
||
}
|
||
var baseArgs = array_slice(arguments, 1);
|
||
return function () {
|
||
var nodeArgs = baseArgs.concat(array_slice(arguments));
|
||
var deferred = defer();
|
||
nodeArgs.push(deferred.makeNodeResolver());
|
||
Q(callback).fapply(nodeArgs).fail(deferred.reject);
|
||
return deferred.promise;
|
||
};
|
||
};
|
||
|
||
Promise.prototype.nfbind =
|
||
Promise.prototype.denodeify = function (/*...args*/) {
|
||
var args = array_slice(arguments);
|
||
args.unshift(this);
|
||
return Q.denodeify.apply(void 0, args);
|
||
};
|
||
|
||
Q.nbind = function (callback, thisp /*...args*/) {
|
||
var baseArgs = array_slice(arguments, 2);
|
||
return function () {
|
||
var nodeArgs = baseArgs.concat(array_slice(arguments));
|
||
var deferred = defer();
|
||
nodeArgs.push(deferred.makeNodeResolver());
|
||
function bound() {
|
||
return callback.apply(thisp, arguments);
|
||
}
|
||
Q(bound).fapply(nodeArgs).fail(deferred.reject);
|
||
return deferred.promise;
|
||
};
|
||
};
|
||
|
||
Promise.prototype.nbind = function (/*thisp, ...args*/) {
|
||
var args = array_slice(arguments, 0);
|
||
args.unshift(this);
|
||
return Q.nbind.apply(void 0, args);
|
||
};
|
||
|
||
/**
|
||
* Calls a method of a Node-style object that accepts a Node-style
|
||
* callback with a given array of arguments, plus a provided callback.
|
||
* @param object an object that has the named method
|
||
* @param {String} name name of the method of object
|
||
* @param {Array} args arguments to pass to the method; the callback
|
||
* will be provided by Q and appended to these arguments.
|
||
* @returns a promise for the value or error
|
||
*/
|
||
Q.nmapply = // XXX As proposed by "Redsandro"
|
||
Q.npost = function (object, name, args) {
|
||
return Q(object).npost(name, args);
|
||
};
|
||
|
||
Promise.prototype.nmapply = // XXX As proposed by "Redsandro"
|
||
Promise.prototype.npost = function (name, args) {
|
||
var nodeArgs = array_slice(args || []);
|
||
var deferred = defer();
|
||
nodeArgs.push(deferred.makeNodeResolver());
|
||
this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
|
||
return deferred.promise;
|
||
};
|
||
|
||
/**
|
||
* Calls a method of a Node-style object that accepts a Node-style
|
||
* callback, forwarding the given variadic arguments, plus a provided
|
||
* callback argument.
|
||
* @param object an object that has the named method
|
||
* @param {String} name name of the method of object
|
||
* @param ...args arguments to pass to the method; the callback will
|
||
* be provided by Q and appended to these arguments.
|
||
* @returns a promise for the value or error
|
||
*/
|
||
Q.nsend = // XXX Based on Mark Miller's proposed "send"
|
||
Q.nmcall = // XXX Based on "Redsandro's" proposal
|
||
Q.ninvoke = function (object, name /*...args*/) {
|
||
var nodeArgs = array_slice(arguments, 2);
|
||
var deferred = defer();
|
||
nodeArgs.push(deferred.makeNodeResolver());
|
||
Q(object).dispatch("post", [name, nodeArgs]).fail(deferred.reject);
|
||
return deferred.promise;
|
||
};
|
||
|
||
Promise.prototype.nsend = // XXX Based on Mark Miller's proposed "send"
|
||
Promise.prototype.nmcall = // XXX Based on "Redsandro's" proposal
|
||
Promise.prototype.ninvoke = function (name /*...args*/) {
|
||
var nodeArgs = array_slice(arguments, 1);
|
||
var deferred = defer();
|
||
nodeArgs.push(deferred.makeNodeResolver());
|
||
this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
|
||
return deferred.promise;
|
||
};
|
||
|
||
/**
|
||
* If a function would like to support both Node continuation-passing-style and
|
||
* promise-returning-style, it can end its internal promise chain with
|
||
* `nodeify(nodeback)`, forwarding the optional nodeback argument. If the user
|
||
* elects to use a nodeback, the result will be sent there. If they do not
|
||
* pass a nodeback, they will receive the result promise.
|
||
* @param object a result (or a promise for a result)
|
||
* @param {Function} nodeback a Node.js-style callback
|
||
* @returns either the promise or nothing
|
||
*/
|
||
Q.nodeify = nodeify;
|
||
function nodeify(object, nodeback) {
|
||
return Q(object).nodeify(nodeback);
|
||
}
|
||
|
||
Promise.prototype.nodeify = function (nodeback) {
|
||
if (nodeback) {
|
||
this.then(function (value) {
|
||
Q.nextTick(function () {
|
||
nodeback(null, value);
|
||
});
|
||
}, function (error) {
|
||
Q.nextTick(function () {
|
||
nodeback(error);
|
||
});
|
||
});
|
||
} else {
|
||
return this;
|
||
}
|
||
};
|
||
|
||
Q.noConflict = function() {
|
||
throw new Error("Q.noConflict only works when Q is used as a global");
|
||
};
|
||
|
||
// All code before this point will be filtered from stack traces.
|
||
var qEndingLine = captureLine();
|
||
|
||
return Q;
|
||
|
||
});
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/qs/lib/formats.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/qs/lib/formats.js ***!
|
||
\****************************************/
|
||
/***/ ((module, __unused_webpack_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 ***!
|
||
\**************************************/
|
||
/***/ ((module, __unused_webpack_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 ***!
|
||
\**************************************/
|
||
/***/ ((module, __unused_webpack_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));
|
||
});
|
||
};
|
||
|
||
var parseArrayValue = function (val, options) {
|
||
if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) {
|
||
return val.split(',');
|
||
}
|
||
|
||
return val;
|
||
};
|
||
|
||
var maybeMap = function maybeMap(val, fn) {
|
||
if (isArray(val)) {
|
||
var mapped = [];
|
||
for (var i = 0; i < val.length; i += 1) {
|
||
mapped.push(fn(val[i]));
|
||
}
|
||
return mapped;
|
||
}
|
||
return fn(val);
|
||
};
|
||
|
||
// 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 = maybeMap(
|
||
parseArrayValue(part.slice(pos + 1), options),
|
||
function (encodedVal) {
|
||
return options.decoder(encodedVal, defaults.decoder, charset, 'value');
|
||
}
|
||
);
|
||
}
|
||
|
||
if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {
|
||
val = interpretNumericEntities(val);
|
||
}
|
||
|
||
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, valuesParsed) {
|
||
var leaf = valuesParsed ? val : parseArrayValue(val, options);
|
||
|
||
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; // eslint-disable-line no-param-reassign
|
||
}
|
||
|
||
return leaf;
|
||
};
|
||
|
||
var parseKeys = function parseQueryStringKeys(givenKey, val, options, valuesParsed) {
|
||
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, valuesParsed);
|
||
};
|
||
|
||
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 TypeError('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, typeof str === 'string');
|
||
obj = utils.merge(obj, newObj, options);
|
||
}
|
||
|
||
return utils.compact(obj);
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/qs/lib/stringify.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/qs/lib/stringify.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_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 ***!
|
||
\**************************************/
|
||
/***/ ((module) => {
|
||
|
||
"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 ***!
|
||
\**************************************************/
|
||
/***/ (() => {
|
||
|
||
/*! *****************************************************************************
|
||
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 ***!
|
||
\**********************************************/
|
||
/***/ ((module) => {
|
||
|
||
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 ***!
|
||
\***************************************/
|
||
/***/ ((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/shelljs/commands.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/commands.js ***!
|
||
\******************************************/
|
||
/***/ ((module) => {
|
||
|
||
module.exports = [
|
||
'cat',
|
||
'cd',
|
||
'chmod',
|
||
'cp',
|
||
'dirs',
|
||
'echo',
|
||
'exec',
|
||
'find',
|
||
'grep',
|
||
'head',
|
||
'ln',
|
||
'ls',
|
||
'mkdir',
|
||
'mv',
|
||
'pwd',
|
||
'rm',
|
||
'sed',
|
||
'set',
|
||
'sort',
|
||
'tail',
|
||
'tempdir',
|
||
'test',
|
||
'to',
|
||
'toEnd',
|
||
'touch',
|
||
'uniq',
|
||
'which',
|
||
];
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/shell.js":
|
||
/*!***************************************!*\
|
||
!*** ./node_modules/shelljs/shell.js ***!
|
||
\***************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
//
|
||
// ShellJS
|
||
// Unix shell commands on top of Node's API
|
||
//
|
||
// Copyright (c) 2012 Artur Adib
|
||
// http://github.com/shelljs/shelljs
|
||
//
|
||
|
||
var common = __webpack_require__(/*! ./src/common */ "./node_modules/shelljs/src/common.js");
|
||
|
||
//@
|
||
//@ All commands run synchronously, unless otherwise stated.
|
||
//@ All commands accept standard bash globbing characters (`*`, `?`, etc.),
|
||
//@ compatible with the [node `glob` module](https://github.com/isaacs/node-glob).
|
||
//@
|
||
//@ For less-commonly used commands and features, please check out our [wiki
|
||
//@ page](https://github.com/shelljs/shelljs/wiki).
|
||
//@
|
||
|
||
// Include the docs for all the default commands
|
||
//@commands
|
||
|
||
// Load all default commands
|
||
__webpack_require__(/*! ./commands */ "./node_modules/shelljs/commands.js").forEach(function (command) {
|
||
__webpack_require__("./node_modules/shelljs/src sync recursive ^\\.\\/.*$")("./" + command);
|
||
});
|
||
|
||
//@
|
||
//@ ### exit(code)
|
||
//@
|
||
//@ Exits the current process with the given exit `code`.
|
||
exports.exit = process.exit;
|
||
|
||
//@include ./src/error
|
||
exports.error = __webpack_require__(/*! ./src/error */ "./node_modules/shelljs/src/error.js");
|
||
|
||
//@include ./src/common
|
||
exports.ShellString = common.ShellString;
|
||
|
||
//@
|
||
//@ ### env['VAR_NAME']
|
||
//@
|
||
//@ Object containing environment variables (both getter and setter). Shortcut
|
||
//@ to `process.env`.
|
||
exports.env = process.env;
|
||
|
||
//@
|
||
//@ ### Pipes
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ grep('foo', 'file1.txt', 'file2.txt').sed(/o/g, 'a').to('output.txt');
|
||
//@ echo('files with o\'s in the name:\n' + ls().grep('o'));
|
||
//@ cat('test.js').exec('node'); // pipe to exec() call
|
||
//@ ```
|
||
//@
|
||
//@ Commands can send their output to another command in a pipe-like fashion.
|
||
//@ `sed`, `grep`, `cat`, `exec`, `to`, and `toEnd` can appear on the right-hand
|
||
//@ side of a pipe. Pipes can be chained.
|
||
|
||
//@
|
||
//@ ## Configuration
|
||
//@
|
||
|
||
exports.config = common.config;
|
||
|
||
//@
|
||
//@ ### config.silent
|
||
//@
|
||
//@ Example:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var sh = require('shelljs');
|
||
//@ var silentState = sh.config.silent; // save old silent state
|
||
//@ sh.config.silent = true;
|
||
//@ /* ... */
|
||
//@ sh.config.silent = silentState; // restore old silent state
|
||
//@ ```
|
||
//@
|
||
//@ Suppresses all command output if `true`, except for `echo()` calls.
|
||
//@ Default is `false`.
|
||
|
||
//@
|
||
//@ ### config.fatal
|
||
//@
|
||
//@ Example:
|
||
//@
|
||
//@ ```javascript
|
||
//@ require('shelljs/global');
|
||
//@ config.fatal = true; // or set('-e');
|
||
//@ cp('this_file_does_not_exist', '/dev/null'); // throws Error here
|
||
//@ /* more commands... */
|
||
//@ ```
|
||
//@
|
||
//@ If `true`, the script will throw a Javascript error when any shell.js
|
||
//@ command encounters an error. Default is `false`. This is analogous to
|
||
//@ Bash's `set -e`.
|
||
|
||
//@
|
||
//@ ### config.verbose
|
||
//@
|
||
//@ Example:
|
||
//@
|
||
//@ ```javascript
|
||
//@ config.verbose = true; // or set('-v');
|
||
//@ cd('dir/');
|
||
//@ rm('-rf', 'foo.txt', 'bar.txt');
|
||
//@ exec('echo hello');
|
||
//@ ```
|
||
//@
|
||
//@ Will print each command as follows:
|
||
//@
|
||
//@ ```
|
||
//@ cd dir/
|
||
//@ rm -rf foo.txt bar.txt
|
||
//@ exec echo hello
|
||
//@ ```
|
||
|
||
//@
|
||
//@ ### config.globOptions
|
||
//@
|
||
//@ Example:
|
||
//@
|
||
//@ ```javascript
|
||
//@ config.globOptions = {nodir: true};
|
||
//@ ```
|
||
//@
|
||
//@ Use this value for calls to `glob.sync()` instead of the default options.
|
||
|
||
//@
|
||
//@ ### config.reset()
|
||
//@
|
||
//@ Example:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var shell = require('shelljs');
|
||
//@ // Make changes to shell.config, and do stuff...
|
||
//@ /* ... */
|
||
//@ shell.config.reset(); // reset to original state
|
||
//@ // Do more stuff, but with original settings
|
||
//@ /* ... */
|
||
//@ ```
|
||
//@
|
||
//@ Reset `shell.config` to the defaults:
|
||
//@
|
||
//@ ```javascript
|
||
//@ {
|
||
//@ fatal: false,
|
||
//@ globOptions: {},
|
||
//@ maxdepth: 255,
|
||
//@ noglob: false,
|
||
//@ silent: false,
|
||
//@ verbose: false,
|
||
//@ }
|
||
//@ ```
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/cat.js":
|
||
/*!*****************************************!*\
|
||
!*** ./node_modules/shelljs/src/cat.js ***!
|
||
\*****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('cat', _cat, {
|
||
canReceivePipe: true,
|
||
cmdOptions: {
|
||
'n': 'number',
|
||
},
|
||
});
|
||
|
||
//@
|
||
//@ ### cat([options,] file [, file ...])
|
||
//@ ### cat([options,] file_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-n`: number all output lines
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var str = cat('file*.txt');
|
||
//@ var str = cat('file1', 'file2');
|
||
//@ var str = cat(['file1', 'file2']); // same as above
|
||
//@ ```
|
||
//@
|
||
//@ Returns a string containing the given file, or a concatenated string
|
||
//@ containing the files if more than one file is given (a new line character is
|
||
//@ introduced between each file).
|
||
function _cat(options, files) {
|
||
var cat = common.readFromPipe();
|
||
|
||
if (!files && !cat) common.error('no paths given');
|
||
|
||
files = [].slice.call(arguments, 1);
|
||
|
||
files.forEach(function (file) {
|
||
if (!fs.existsSync(file)) {
|
||
common.error('no such file or directory: ' + file);
|
||
} else if (common.statFollowLinks(file).isDirectory()) {
|
||
common.error(file + ': Is a directory');
|
||
}
|
||
|
||
cat += fs.readFileSync(file, 'utf8');
|
||
});
|
||
|
||
if (options.number) {
|
||
cat = addNumbers(cat);
|
||
}
|
||
|
||
return cat;
|
||
}
|
||
module.exports = _cat;
|
||
|
||
function addNumbers(cat) {
|
||
var lines = cat.split('\n');
|
||
var lastLine = lines.pop();
|
||
|
||
lines = lines.map(function (line, i) {
|
||
return numberedLine(i + 1, line);
|
||
});
|
||
|
||
if (lastLine.length) {
|
||
lastLine = numberedLine(lines.length + 1, lastLine);
|
||
}
|
||
lines.push(lastLine);
|
||
|
||
return lines.join('\n');
|
||
}
|
||
|
||
function numberedLine(n, line) {
|
||
// GNU cat use six pad start number + tab. See http://lingrok.org/xref/coreutils/src/cat.c#57
|
||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
|
||
var number = (' ' + n).slice(-6) + '\t';
|
||
return number + line;
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/cd.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/shelljs/src/cd.js ***!
|
||
\****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var os = __webpack_require__(/*! os */ "os");
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
|
||
common.register('cd', _cd, {});
|
||
|
||
//@
|
||
//@ ### cd([dir])
|
||
//@
|
||
//@ Changes to directory `dir` for the duration of the script. Changes to home
|
||
//@ directory if no argument is supplied.
|
||
function _cd(options, dir) {
|
||
if (!dir) dir = os.homedir();
|
||
|
||
if (dir === '-') {
|
||
if (!process.env.OLDPWD) {
|
||
common.error('could not find previous directory');
|
||
} else {
|
||
dir = process.env.OLDPWD;
|
||
}
|
||
}
|
||
|
||
try {
|
||
var curDir = process.cwd();
|
||
process.chdir(dir);
|
||
process.env.OLDPWD = curDir;
|
||
} catch (e) {
|
||
// something went wrong, let's figure out the error
|
||
var err;
|
||
try {
|
||
common.statFollowLinks(dir); // if this succeeds, it must be some sort of file
|
||
err = 'not a directory: ' + dir;
|
||
} catch (e2) {
|
||
err = 'no such file or directory: ' + dir;
|
||
}
|
||
if (err) common.error(err);
|
||
}
|
||
return '';
|
||
}
|
||
module.exports = _cd;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/chmod.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/shelljs/src/chmod.js ***!
|
||
\*******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
|
||
var PERMS = (function (base) {
|
||
return {
|
||
OTHER_EXEC: base.EXEC,
|
||
OTHER_WRITE: base.WRITE,
|
||
OTHER_READ: base.READ,
|
||
|
||
GROUP_EXEC: base.EXEC << 3,
|
||
GROUP_WRITE: base.WRITE << 3,
|
||
GROUP_READ: base.READ << 3,
|
||
|
||
OWNER_EXEC: base.EXEC << 6,
|
||
OWNER_WRITE: base.WRITE << 6,
|
||
OWNER_READ: base.READ << 6,
|
||
|
||
// Literal octal numbers are apparently not allowed in "strict" javascript.
|
||
STICKY: parseInt('01000', 8),
|
||
SETGID: parseInt('02000', 8),
|
||
SETUID: parseInt('04000', 8),
|
||
|
||
TYPE_MASK: parseInt('0770000', 8),
|
||
};
|
||
}({
|
||
EXEC: 1,
|
||
WRITE: 2,
|
||
READ: 4,
|
||
}));
|
||
|
||
common.register('chmod', _chmod, {
|
||
});
|
||
|
||
//@
|
||
//@ ### chmod([options,] octal_mode || octal_string, file)
|
||
//@ ### chmod([options,] symbolic_mode, file)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-v`: output a diagnostic for every file processed//@
|
||
//@ + `-c`: like verbose, but report only when a change is made//@
|
||
//@ + `-R`: change files and directories recursively//@
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ chmod(755, '/Users/brandon');
|
||
//@ chmod('755', '/Users/brandon'); // same as above
|
||
//@ chmod('u+x', '/Users/brandon');
|
||
//@ chmod('-R', 'a-w', '/Users/brandon');
|
||
//@ ```
|
||
//@
|
||
//@ Alters the permissions of a file or directory by either specifying the
|
||
//@ absolute permissions in octal form or expressing the changes in symbols.
|
||
//@ This command tries to mimic the POSIX behavior as much as possible.
|
||
//@ Notable exceptions:
|
||
//@
|
||
//@ + In symbolic modes, `a-r` and `-r` are identical. No consideration is
|
||
//@ given to the `umask`.
|
||
//@ + There is no "quiet" option, since default behavior is to run silent.
|
||
function _chmod(options, mode, filePattern) {
|
||
if (!filePattern) {
|
||
if (options.length > 0 && options.charAt(0) === '-') {
|
||
// Special case where the specified file permissions started with - to subtract perms, which
|
||
// get picked up by the option parser as command flags.
|
||
// If we are down by one argument and options starts with -, shift everything over.
|
||
[].unshift.call(arguments, '');
|
||
} else {
|
||
common.error('You must specify a file.');
|
||
}
|
||
}
|
||
|
||
options = common.parseOptions(options, {
|
||
'R': 'recursive',
|
||
'c': 'changes',
|
||
'v': 'verbose',
|
||
});
|
||
|
||
filePattern = [].slice.call(arguments, 2);
|
||
|
||
var files;
|
||
|
||
// TODO: replace this with a call to common.expand()
|
||
if (options.recursive) {
|
||
files = [];
|
||
filePattern.forEach(function addFile(expandedFile) {
|
||
var stat = common.statNoFollowLinks(expandedFile);
|
||
|
||
if (!stat.isSymbolicLink()) {
|
||
files.push(expandedFile);
|
||
|
||
if (stat.isDirectory()) { // intentionally does not follow symlinks.
|
||
fs.readdirSync(expandedFile).forEach(function (child) {
|
||
addFile(expandedFile + '/' + child);
|
||
});
|
||
}
|
||
}
|
||
});
|
||
} else {
|
||
files = filePattern;
|
||
}
|
||
|
||
files.forEach(function innerChmod(file) {
|
||
file = path.resolve(file);
|
||
if (!fs.existsSync(file)) {
|
||
common.error('File not found: ' + file);
|
||
}
|
||
|
||
// When recursing, don't follow symlinks.
|
||
if (options.recursive && common.statNoFollowLinks(file).isSymbolicLink()) {
|
||
return;
|
||
}
|
||
|
||
var stat = common.statFollowLinks(file);
|
||
var isDir = stat.isDirectory();
|
||
var perms = stat.mode;
|
||
var type = perms & PERMS.TYPE_MASK;
|
||
|
||
var newPerms = perms;
|
||
|
||
if (isNaN(parseInt(mode, 8))) {
|
||
// parse options
|
||
mode.split(',').forEach(function (symbolicMode) {
|
||
var pattern = /([ugoa]*)([=\+-])([rwxXst]*)/i;
|
||
var matches = pattern.exec(symbolicMode);
|
||
|
||
if (matches) {
|
||
var applyTo = matches[1];
|
||
var operator = matches[2];
|
||
var change = matches[3];
|
||
|
||
var changeOwner = applyTo.indexOf('u') !== -1 || applyTo === 'a' || applyTo === '';
|
||
var changeGroup = applyTo.indexOf('g') !== -1 || applyTo === 'a' || applyTo === '';
|
||
var changeOther = applyTo.indexOf('o') !== -1 || applyTo === 'a' || applyTo === '';
|
||
|
||
var changeRead = change.indexOf('r') !== -1;
|
||
var changeWrite = change.indexOf('w') !== -1;
|
||
var changeExec = change.indexOf('x') !== -1;
|
||
var changeExecDir = change.indexOf('X') !== -1;
|
||
var changeSticky = change.indexOf('t') !== -1;
|
||
var changeSetuid = change.indexOf('s') !== -1;
|
||
|
||
if (changeExecDir && isDir) {
|
||
changeExec = true;
|
||
}
|
||
|
||
var mask = 0;
|
||
if (changeOwner) {
|
||
mask |= (changeRead ? PERMS.OWNER_READ : 0) + (changeWrite ? PERMS.OWNER_WRITE : 0) + (changeExec ? PERMS.OWNER_EXEC : 0) + (changeSetuid ? PERMS.SETUID : 0);
|
||
}
|
||
if (changeGroup) {
|
||
mask |= (changeRead ? PERMS.GROUP_READ : 0) + (changeWrite ? PERMS.GROUP_WRITE : 0) + (changeExec ? PERMS.GROUP_EXEC : 0) + (changeSetuid ? PERMS.SETGID : 0);
|
||
}
|
||
if (changeOther) {
|
||
mask |= (changeRead ? PERMS.OTHER_READ : 0) + (changeWrite ? PERMS.OTHER_WRITE : 0) + (changeExec ? PERMS.OTHER_EXEC : 0);
|
||
}
|
||
|
||
// Sticky bit is special - it's not tied to user, group or other.
|
||
if (changeSticky) {
|
||
mask |= PERMS.STICKY;
|
||
}
|
||
|
||
switch (operator) {
|
||
case '+':
|
||
newPerms |= mask;
|
||
break;
|
||
|
||
case '-':
|
||
newPerms &= ~mask;
|
||
break;
|
||
|
||
case '=':
|
||
newPerms = type + mask;
|
||
|
||
// According to POSIX, when using = to explicitly set the
|
||
// permissions, setuid and setgid can never be cleared.
|
||
if (common.statFollowLinks(file).isDirectory()) {
|
||
newPerms |= (PERMS.SETUID + PERMS.SETGID) & perms;
|
||
}
|
||
break;
|
||
default:
|
||
common.error('Could not recognize operator: `' + operator + '`');
|
||
}
|
||
|
||
if (options.verbose) {
|
||
console.log(file + ' -> ' + newPerms.toString(8));
|
||
}
|
||
|
||
if (perms !== newPerms) {
|
||
if (!options.verbose && options.changes) {
|
||
console.log(file + ' -> ' + newPerms.toString(8));
|
||
}
|
||
fs.chmodSync(file, newPerms);
|
||
perms = newPerms; // for the next round of changes!
|
||
}
|
||
} else {
|
||
common.error('Invalid symbolic mode change: ' + symbolicMode);
|
||
}
|
||
});
|
||
} else {
|
||
// they gave us a full number
|
||
newPerms = type + parseInt(mode, 8);
|
||
|
||
// POSIX rules are that setuid and setgid can only be added using numeric
|
||
// form, but not cleared.
|
||
if (common.statFollowLinks(file).isDirectory()) {
|
||
newPerms |= (PERMS.SETUID + PERMS.SETGID) & perms;
|
||
}
|
||
|
||
fs.chmodSync(file, newPerms);
|
||
}
|
||
});
|
||
return '';
|
||
}
|
||
module.exports = _chmod;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/common.js":
|
||
/*!********************************************!*\
|
||
!*** ./node_modules/shelljs/src/common.js ***!
|
||
\********************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
// Ignore warning about 'new String()'
|
||
/* eslint no-new-wrappers: 0 */
|
||
|
||
|
||
var os = __webpack_require__(/*! os */ "os");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var glob = __webpack_require__(/*! glob */ "./node_modules/glob/glob.js");
|
||
var shell = __webpack_require__(/*! .. */ "./node_modules/shelljs/shell.js");
|
||
|
||
var shellMethods = Object.create(shell);
|
||
|
||
exports.extend = Object.assign;
|
||
|
||
// Check if we're running under electron
|
||
var isElectron = Boolean(process.versions.electron);
|
||
|
||
// Module globals (assume no execPath by default)
|
||
var DEFAULT_CONFIG = {
|
||
fatal: false,
|
||
globOptions: {},
|
||
maxdepth: 255,
|
||
noglob: false,
|
||
silent: false,
|
||
verbose: false,
|
||
execPath: null,
|
||
bufLength: 64 * 1024, // 64KB
|
||
};
|
||
|
||
var config = {
|
||
reset: function () {
|
||
Object.assign(this, DEFAULT_CONFIG);
|
||
if (!isElectron) {
|
||
this.execPath = process.execPath;
|
||
}
|
||
},
|
||
resetForTesting: function () {
|
||
this.reset();
|
||
this.silent = true;
|
||
},
|
||
};
|
||
|
||
config.reset();
|
||
exports.config = config;
|
||
|
||
// Note: commands should generally consider these as read-only values.
|
||
var state = {
|
||
error: null,
|
||
errorCode: 0,
|
||
currentCmd: 'shell.js',
|
||
};
|
||
exports.state = state;
|
||
|
||
delete process.env.OLDPWD; // initially, there's no previous directory
|
||
|
||
// Reliably test if something is any sort of javascript object
|
||
function isObject(a) {
|
||
return typeof a === 'object' && a !== null;
|
||
}
|
||
exports.isObject = isObject;
|
||
|
||
function log() {
|
||
/* istanbul ignore next */
|
||
if (!config.silent) {
|
||
console.error.apply(console, arguments);
|
||
}
|
||
}
|
||
exports.log = log;
|
||
|
||
// Converts strings to be equivalent across all platforms. Primarily responsible
|
||
// for making sure we use '/' instead of '\' as path separators, but this may be
|
||
// expanded in the future if necessary
|
||
function convertErrorOutput(msg) {
|
||
if (typeof msg !== 'string') {
|
||
throw new TypeError('input must be a string');
|
||
}
|
||
return msg.replace(/\\/g, '/');
|
||
}
|
||
exports.convertErrorOutput = convertErrorOutput;
|
||
|
||
// Shows error message. Throws if config.fatal is true
|
||
function error(msg, _code, options) {
|
||
// Validate input
|
||
if (typeof msg !== 'string') throw new Error('msg must be a string');
|
||
|
||
var DEFAULT_OPTIONS = {
|
||
continue: false,
|
||
code: 1,
|
||
prefix: state.currentCmd + ': ',
|
||
silent: false,
|
||
};
|
||
|
||
if (typeof _code === 'number' && isObject(options)) {
|
||
options.code = _code;
|
||
} else if (isObject(_code)) { // no 'code'
|
||
options = _code;
|
||
} else if (typeof _code === 'number') { // no 'options'
|
||
options = { code: _code };
|
||
} else if (typeof _code !== 'number') { // only 'msg'
|
||
options = {};
|
||
}
|
||
options = Object.assign({}, DEFAULT_OPTIONS, options);
|
||
|
||
if (!state.errorCode) state.errorCode = options.code;
|
||
|
||
var logEntry = convertErrorOutput(options.prefix + msg);
|
||
state.error = state.error ? state.error + '\n' : '';
|
||
state.error += logEntry;
|
||
|
||
// Throw an error, or log the entry
|
||
if (config.fatal) throw new Error(logEntry);
|
||
if (msg.length > 0 && !options.silent) log(logEntry);
|
||
|
||
if (!options.continue) {
|
||
throw {
|
||
msg: 'earlyExit',
|
||
retValue: (new ShellString('', state.error, state.errorCode)),
|
||
};
|
||
}
|
||
}
|
||
exports.error = error;
|
||
|
||
//@
|
||
//@ ### ShellString(str)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var foo = ShellString('hello world');
|
||
//@ ```
|
||
//@
|
||
//@ Turns a regular string into a string-like object similar to what each
|
||
//@ command returns. This has special methods, like `.to()` and `.toEnd()`.
|
||
function ShellString(stdout, stderr, code) {
|
||
var that;
|
||
if (stdout instanceof Array) {
|
||
that = stdout;
|
||
that.stdout = stdout.join('\n');
|
||
if (stdout.length > 0) that.stdout += '\n';
|
||
} else {
|
||
that = new String(stdout);
|
||
that.stdout = stdout;
|
||
}
|
||
that.stderr = stderr;
|
||
that.code = code;
|
||
// A list of all commands that can appear on the right-hand side of a pipe
|
||
// (populated by calls to common.wrap())
|
||
pipeMethods.forEach(function (cmd) {
|
||
that[cmd] = shellMethods[cmd].bind(that);
|
||
});
|
||
return that;
|
||
}
|
||
|
||
exports.ShellString = ShellString;
|
||
|
||
// Returns {'alice': true, 'bob': false} when passed a string and dictionary as follows:
|
||
// parseOptions('-a', {'a':'alice', 'b':'bob'});
|
||
// Returns {'reference': 'string-value', 'bob': false} when passed two dictionaries of the form:
|
||
// parseOptions({'-r': 'string-value'}, {'r':'reference', 'b':'bob'});
|
||
// Throws an error when passed a string that does not start with '-':
|
||
// parseOptions('a', {'a':'alice'}); // throws
|
||
function parseOptions(opt, map, errorOptions) {
|
||
// Validate input
|
||
if (typeof opt !== 'string' && !isObject(opt)) {
|
||
throw new Error('options must be strings or key-value pairs');
|
||
} else if (!isObject(map)) {
|
||
throw new Error('parseOptions() internal error: map must be an object');
|
||
} else if (errorOptions && !isObject(errorOptions)) {
|
||
throw new Error('parseOptions() internal error: errorOptions must be object');
|
||
}
|
||
|
||
if (opt === '--') {
|
||
// This means there are no options.
|
||
return {};
|
||
}
|
||
|
||
// All options are false by default
|
||
var options = {};
|
||
Object.keys(map).forEach(function (letter) {
|
||
var optName = map[letter];
|
||
if (optName[0] !== '!') {
|
||
options[optName] = false;
|
||
}
|
||
});
|
||
|
||
if (opt === '') return options; // defaults
|
||
|
||
if (typeof opt === 'string') {
|
||
if (opt[0] !== '-') {
|
||
throw new Error("Options string must start with a '-'");
|
||
}
|
||
|
||
// e.g. chars = ['R', 'f']
|
||
var chars = opt.slice(1).split('');
|
||
|
||
chars.forEach(function (c) {
|
||
if (c in map) {
|
||
var optionName = map[c];
|
||
if (optionName[0] === '!') {
|
||
options[optionName.slice(1)] = false;
|
||
} else {
|
||
options[optionName] = true;
|
||
}
|
||
} else {
|
||
error('option not recognized: ' + c, errorOptions || {});
|
||
}
|
||
});
|
||
} else { // opt is an Object
|
||
Object.keys(opt).forEach(function (key) {
|
||
// key is a string of the form '-r', '-d', etc.
|
||
var c = key[1];
|
||
if (c in map) {
|
||
var optionName = map[c];
|
||
options[optionName] = opt[key]; // assign the given value
|
||
} else {
|
||
error('option not recognized: ' + c, errorOptions || {});
|
||
}
|
||
});
|
||
}
|
||
return options;
|
||
}
|
||
exports.parseOptions = parseOptions;
|
||
|
||
// Expands wildcards with matching (ie. existing) file names.
|
||
// For example:
|
||
// expand(['file*.js']) = ['file1.js', 'file2.js', ...]
|
||
// (if the files 'file1.js', 'file2.js', etc, exist in the current dir)
|
||
function expand(list) {
|
||
if (!Array.isArray(list)) {
|
||
throw new TypeError('must be an array');
|
||
}
|
||
var expanded = [];
|
||
list.forEach(function (listEl) {
|
||
// Don't expand non-strings
|
||
if (typeof listEl !== 'string') {
|
||
expanded.push(listEl);
|
||
} else {
|
||
var ret;
|
||
try {
|
||
ret = glob.sync(listEl, config.globOptions);
|
||
// if nothing matched, interpret the string literally
|
||
ret = ret.length > 0 ? ret : [listEl];
|
||
} catch (e) {
|
||
// if glob fails, interpret the string literally
|
||
ret = [listEl];
|
||
}
|
||
expanded = expanded.concat(ret);
|
||
}
|
||
});
|
||
return expanded;
|
||
}
|
||
exports.expand = expand;
|
||
|
||
// Normalizes Buffer creation, using Buffer.alloc if possible.
|
||
// Also provides a good default buffer length for most use cases.
|
||
var buffer = typeof Buffer.alloc === 'function' ?
|
||
function (len) {
|
||
return Buffer.alloc(len || config.bufLength);
|
||
} :
|
||
function (len) {
|
||
return new Buffer(len || config.bufLength);
|
||
};
|
||
exports.buffer = buffer;
|
||
|
||
// Normalizes _unlinkSync() across platforms to match Unix behavior, i.e.
|
||
// file can be unlinked even if it's read-only, see https://github.com/joyent/node/issues/3006
|
||
function unlinkSync(file) {
|
||
try {
|
||
fs.unlinkSync(file);
|
||
} catch (e) {
|
||
// Try to override file permission
|
||
/* istanbul ignore next */
|
||
if (e.code === 'EPERM') {
|
||
fs.chmodSync(file, '0666');
|
||
fs.unlinkSync(file);
|
||
} else {
|
||
throw e;
|
||
}
|
||
}
|
||
}
|
||
exports.unlinkSync = unlinkSync;
|
||
|
||
// wrappers around common.statFollowLinks and common.statNoFollowLinks that clarify intent
|
||
// and improve readability
|
||
function statFollowLinks() {
|
||
return fs.statSync.apply(fs, arguments);
|
||
}
|
||
exports.statFollowLinks = statFollowLinks;
|
||
|
||
function statNoFollowLinks() {
|
||
return fs.lstatSync.apply(fs, arguments);
|
||
}
|
||
exports.statNoFollowLinks = statNoFollowLinks;
|
||
|
||
// e.g. 'shelljs_a5f185d0443ca...'
|
||
function randomFileName() {
|
||
function randomHash(count) {
|
||
if (count === 1) {
|
||
return parseInt(16 * Math.random(), 10).toString(16);
|
||
}
|
||
var hash = '';
|
||
for (var i = 0; i < count; i++) {
|
||
hash += randomHash(1);
|
||
}
|
||
return hash;
|
||
}
|
||
|
||
return 'shelljs_' + randomHash(20);
|
||
}
|
||
exports.randomFileName = randomFileName;
|
||
|
||
// Common wrapper for all Unix-like commands that performs glob expansion,
|
||
// command-logging, and other nice things
|
||
function wrap(cmd, fn, options) {
|
||
options = options || {};
|
||
return function () {
|
||
var retValue = null;
|
||
|
||
state.currentCmd = cmd;
|
||
state.error = null;
|
||
state.errorCode = 0;
|
||
|
||
try {
|
||
var args = [].slice.call(arguments, 0);
|
||
|
||
// Log the command to stderr, if appropriate
|
||
if (config.verbose) {
|
||
console.error.apply(console, [cmd].concat(args));
|
||
}
|
||
|
||
// If this is coming from a pipe, let's set the pipedValue (otherwise, set
|
||
// it to the empty string)
|
||
state.pipedValue = (this && typeof this.stdout === 'string') ? this.stdout : '';
|
||
|
||
if (options.unix === false) { // this branch is for exec()
|
||
retValue = fn.apply(this, args);
|
||
} else { // and this branch is for everything else
|
||
if (isObject(args[0]) && args[0].constructor.name === 'Object') {
|
||
// a no-op, allowing the syntax `touch({'-r': file}, ...)`
|
||
} else if (args.length === 0 || typeof args[0] !== 'string' || args[0].length <= 1 || args[0][0] !== '-') {
|
||
args.unshift(''); // only add dummy option if '-option' not already present
|
||
}
|
||
|
||
// flatten out arrays that are arguments, to make the syntax:
|
||
// `cp([file1, file2, file3], dest);`
|
||
// equivalent to:
|
||
// `cp(file1, file2, file3, dest);`
|
||
args = args.reduce(function (accum, cur) {
|
||
if (Array.isArray(cur)) {
|
||
return accum.concat(cur);
|
||
}
|
||
accum.push(cur);
|
||
return accum;
|
||
}, []);
|
||
|
||
// Convert ShellStrings (basically just String objects) to regular strings
|
||
args = args.map(function (arg) {
|
||
if (isObject(arg) && arg.constructor.name === 'String') {
|
||
return arg.toString();
|
||
}
|
||
return arg;
|
||
});
|
||
|
||
// Expand the '~' if appropriate
|
||
var homeDir = os.homedir();
|
||
args = args.map(function (arg) {
|
||
if (typeof arg === 'string' && arg.slice(0, 2) === '~/' || arg === '~') {
|
||
return arg.replace(/^~/, homeDir);
|
||
}
|
||
return arg;
|
||
});
|
||
|
||
// Perform glob-expansion on all arguments after globStart, but preserve
|
||
// the arguments before it (like regexes for sed and grep)
|
||
if (!config.noglob && options.allowGlobbing === true) {
|
||
args = args.slice(0, options.globStart).concat(expand(args.slice(options.globStart)));
|
||
}
|
||
|
||
try {
|
||
// parse options if options are provided
|
||
if (isObject(options.cmdOptions)) {
|
||
args[0] = parseOptions(args[0], options.cmdOptions);
|
||
}
|
||
|
||
retValue = fn.apply(this, args);
|
||
} catch (e) {
|
||
/* istanbul ignore else */
|
||
if (e.msg === 'earlyExit') {
|
||
retValue = e.retValue;
|
||
} else {
|
||
throw e; // this is probably a bug that should be thrown up the call stack
|
||
}
|
||
}
|
||
}
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
if (!state.error) {
|
||
// If state.error hasn't been set it's an error thrown by Node, not us - probably a bug...
|
||
e.name = 'ShellJSInternalError';
|
||
throw e;
|
||
}
|
||
if (config.fatal) throw e;
|
||
}
|
||
|
||
if (options.wrapOutput &&
|
||
(typeof retValue === 'string' || Array.isArray(retValue))) {
|
||
retValue = new ShellString(retValue, state.error, state.errorCode);
|
||
}
|
||
|
||
state.currentCmd = 'shell.js';
|
||
return retValue;
|
||
};
|
||
} // wrap
|
||
exports.wrap = wrap;
|
||
|
||
// This returns all the input that is piped into the current command (or the
|
||
// empty string, if this isn't on the right-hand side of a pipe
|
||
function _readFromPipe() {
|
||
return state.pipedValue;
|
||
}
|
||
exports.readFromPipe = _readFromPipe;
|
||
|
||
var DEFAULT_WRAP_OPTIONS = {
|
||
allowGlobbing: true,
|
||
canReceivePipe: false,
|
||
cmdOptions: null,
|
||
globStart: 1,
|
||
pipeOnly: false,
|
||
wrapOutput: true,
|
||
unix: true,
|
||
};
|
||
|
||
// This is populated during plugin registration
|
||
var pipeMethods = [];
|
||
|
||
// Register a new ShellJS command
|
||
function _register(name, implementation, wrapOptions) {
|
||
wrapOptions = wrapOptions || {};
|
||
|
||
// Validate options
|
||
Object.keys(wrapOptions).forEach(function (option) {
|
||
if (!DEFAULT_WRAP_OPTIONS.hasOwnProperty(option)) {
|
||
throw new Error("Unknown option '" + option + "'");
|
||
}
|
||
if (typeof wrapOptions[option] !== typeof DEFAULT_WRAP_OPTIONS[option]) {
|
||
throw new TypeError("Unsupported type '" + typeof wrapOptions[option] +
|
||
"' for option '" + option + "'");
|
||
}
|
||
});
|
||
|
||
// If an option isn't specified, use the default
|
||
wrapOptions = Object.assign({}, DEFAULT_WRAP_OPTIONS, wrapOptions);
|
||
|
||
if (shell.hasOwnProperty(name)) {
|
||
throw new Error('Command `' + name + '` already exists');
|
||
}
|
||
|
||
if (wrapOptions.pipeOnly) {
|
||
wrapOptions.canReceivePipe = true;
|
||
shellMethods[name] = wrap(name, implementation, wrapOptions);
|
||
} else {
|
||
shell[name] = wrap(name, implementation, wrapOptions);
|
||
}
|
||
|
||
if (wrapOptions.canReceivePipe) {
|
||
pipeMethods.push(name);
|
||
}
|
||
}
|
||
exports.register = _register;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/cp.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/shelljs/src/cp.js ***!
|
||
\****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
|
||
common.register('cp', _cp, {
|
||
cmdOptions: {
|
||
'f': '!no_force',
|
||
'n': 'no_force',
|
||
'u': 'update',
|
||
'R': 'recursive',
|
||
'r': 'recursive',
|
||
'L': 'followsymlink',
|
||
'P': 'noFollowsymlink',
|
||
},
|
||
wrapOutput: false,
|
||
});
|
||
|
||
// Buffered file copy, synchronous
|
||
// (Using readFileSync() + writeFileSync() could easily cause a memory overflow
|
||
// with large files)
|
||
function copyFileSync(srcFile, destFile, options) {
|
||
if (!fs.existsSync(srcFile)) {
|
||
common.error('copyFileSync: no such file or directory: ' + srcFile);
|
||
}
|
||
|
||
var isWindows = process.platform === 'win32';
|
||
|
||
// Check the mtimes of the files if the '-u' flag is provided
|
||
try {
|
||
if (options.update && common.statFollowLinks(srcFile).mtime < fs.statSync(destFile).mtime) {
|
||
return;
|
||
}
|
||
} catch (e) {
|
||
// If we're here, destFile probably doesn't exist, so just do a normal copy
|
||
}
|
||
|
||
if (common.statNoFollowLinks(srcFile).isSymbolicLink() && !options.followsymlink) {
|
||
try {
|
||
common.statNoFollowLinks(destFile);
|
||
common.unlinkSync(destFile); // re-link it
|
||
} catch (e) {
|
||
// it doesn't exist, so no work needs to be done
|
||
}
|
||
|
||
var symlinkFull = fs.readlinkSync(srcFile);
|
||
fs.symlinkSync(symlinkFull, destFile, isWindows ? 'junction' : null);
|
||
} else {
|
||
var buf = common.buffer();
|
||
var bufLength = buf.length;
|
||
var bytesRead = bufLength;
|
||
var pos = 0;
|
||
var fdr = null;
|
||
var fdw = null;
|
||
|
||
try {
|
||
fdr = fs.openSync(srcFile, 'r');
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
common.error('copyFileSync: could not read src file (' + srcFile + ')');
|
||
}
|
||
|
||
try {
|
||
fdw = fs.openSync(destFile, 'w');
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
common.error('copyFileSync: could not write to dest file (code=' + e.code + '):' + destFile);
|
||
}
|
||
|
||
while (bytesRead === bufLength) {
|
||
bytesRead = fs.readSync(fdr, buf, 0, bufLength, pos);
|
||
fs.writeSync(fdw, buf, 0, bytesRead);
|
||
pos += bytesRead;
|
||
}
|
||
|
||
fs.closeSync(fdr);
|
||
fs.closeSync(fdw);
|
||
|
||
fs.chmodSync(destFile, common.statFollowLinks(srcFile).mode);
|
||
}
|
||
}
|
||
|
||
// Recursively copies 'sourceDir' into 'destDir'
|
||
// Adapted from https://github.com/ryanmcgrath/wrench-js
|
||
//
|
||
// Copyright (c) 2010 Ryan McGrath
|
||
// Copyright (c) 2012 Artur Adib
|
||
//
|
||
// Licensed under the MIT License
|
||
// http://www.opensource.org/licenses/mit-license.php
|
||
function cpdirSyncRecursive(sourceDir, destDir, currentDepth, opts) {
|
||
if (!opts) opts = {};
|
||
|
||
// Ensure there is not a run away recursive copy
|
||
if (currentDepth >= common.config.maxdepth) return;
|
||
currentDepth++;
|
||
|
||
var isWindows = process.platform === 'win32';
|
||
|
||
// Create the directory where all our junk is moving to; read the mode of the
|
||
// source directory and mirror it
|
||
try {
|
||
fs.mkdirSync(destDir);
|
||
} catch (e) {
|
||
// if the directory already exists, that's okay
|
||
if (e.code !== 'EEXIST') throw e;
|
||
}
|
||
|
||
var files = fs.readdirSync(sourceDir);
|
||
|
||
for (var i = 0; i < files.length; i++) {
|
||
var srcFile = sourceDir + '/' + files[i];
|
||
var destFile = destDir + '/' + files[i];
|
||
var srcFileStat = common.statNoFollowLinks(srcFile);
|
||
|
||
var symlinkFull;
|
||
if (opts.followsymlink) {
|
||
if (cpcheckcycle(sourceDir, srcFile)) {
|
||
// Cycle link found.
|
||
console.error('Cycle link found.');
|
||
symlinkFull = fs.readlinkSync(srcFile);
|
||
fs.symlinkSync(symlinkFull, destFile, isWindows ? 'junction' : null);
|
||
continue;
|
||
}
|
||
}
|
||
if (srcFileStat.isDirectory()) {
|
||
/* recursion this thing right on back. */
|
||
cpdirSyncRecursive(srcFile, destFile, currentDepth, opts);
|
||
} else if (srcFileStat.isSymbolicLink() && !opts.followsymlink) {
|
||
symlinkFull = fs.readlinkSync(srcFile);
|
||
try {
|
||
common.statNoFollowLinks(destFile);
|
||
common.unlinkSync(destFile); // re-link it
|
||
} catch (e) {
|
||
// it doesn't exist, so no work needs to be done
|
||
}
|
||
fs.symlinkSync(symlinkFull, destFile, isWindows ? 'junction' : null);
|
||
} else if (srcFileStat.isSymbolicLink() && opts.followsymlink) {
|
||
srcFileStat = common.statFollowLinks(srcFile);
|
||
if (srcFileStat.isDirectory()) {
|
||
cpdirSyncRecursive(srcFile, destFile, currentDepth, opts);
|
||
} else {
|
||
copyFileSync(srcFile, destFile, opts);
|
||
}
|
||
} else {
|
||
/* At this point, we've hit a file actually worth copying... so copy it on over. */
|
||
if (fs.existsSync(destFile) && opts.no_force) {
|
||
common.log('skipping existing file: ' + files[i]);
|
||
} else {
|
||
copyFileSync(srcFile, destFile, opts);
|
||
}
|
||
}
|
||
} // for files
|
||
|
||
// finally change the mode for the newly created directory (otherwise, we
|
||
// couldn't add files to a read-only directory).
|
||
var checkDir = common.statFollowLinks(sourceDir);
|
||
fs.chmodSync(destDir, checkDir.mode);
|
||
} // cpdirSyncRecursive
|
||
|
||
// Checks if cureent file was created recently
|
||
function checkRecentCreated(sources, index) {
|
||
var lookedSource = sources[index];
|
||
return sources.slice(0, index).some(function (src) {
|
||
return path.basename(src) === path.basename(lookedSource);
|
||
});
|
||
}
|
||
|
||
function cpcheckcycle(sourceDir, srcFile) {
|
||
var srcFileStat = common.statNoFollowLinks(srcFile);
|
||
if (srcFileStat.isSymbolicLink()) {
|
||
// Do cycle check. For example:
|
||
// $ mkdir -p 1/2/3/4
|
||
// $ cd 1/2/3/4
|
||
// $ ln -s ../../3 link
|
||
// $ cd ../../../..
|
||
// $ cp -RL 1 copy
|
||
var cyclecheck = common.statFollowLinks(srcFile);
|
||
if (cyclecheck.isDirectory()) {
|
||
var sourcerealpath = fs.realpathSync(sourceDir);
|
||
var symlinkrealpath = fs.realpathSync(srcFile);
|
||
var re = new RegExp(symlinkrealpath);
|
||
if (re.test(sourcerealpath)) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
//@
|
||
//@ ### cp([options,] source [, source ...], dest)
|
||
//@ ### cp([options,] source_array, dest)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-f`: force (default behavior)
|
||
//@ + `-n`: no-clobber
|
||
//@ + `-u`: only copy if `source` is newer than `dest`
|
||
//@ + `-r`, `-R`: recursive
|
||
//@ + `-L`: follow symlinks
|
||
//@ + `-P`: don't follow symlinks
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ cp('file1', 'dir1');
|
||
//@ cp('-R', 'path/to/dir/', '~/newCopy/');
|
||
//@ cp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp');
|
||
//@ cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above
|
||
//@ ```
|
||
//@
|
||
//@ Copies files.
|
||
function _cp(options, sources, dest) {
|
||
// If we're missing -R, it actually implies -L (unless -P is explicit)
|
||
if (options.followsymlink) {
|
||
options.noFollowsymlink = false;
|
||
}
|
||
if (!options.recursive && !options.noFollowsymlink) {
|
||
options.followsymlink = true;
|
||
}
|
||
|
||
// Get sources, dest
|
||
if (arguments.length < 3) {
|
||
common.error('missing <source> and/or <dest>');
|
||
} else {
|
||
sources = [].slice.call(arguments, 1, arguments.length - 1);
|
||
dest = arguments[arguments.length - 1];
|
||
}
|
||
|
||
var destExists = fs.existsSync(dest);
|
||
var destStat = destExists && common.statFollowLinks(dest);
|
||
|
||
// Dest is not existing dir, but multiple sources given
|
||
if ((!destExists || !destStat.isDirectory()) && sources.length > 1) {
|
||
common.error('dest is not a directory (too many sources)');
|
||
}
|
||
|
||
// Dest is an existing file, but -n is given
|
||
if (destExists && destStat.isFile() && options.no_force) {
|
||
return new common.ShellString('', '', 0);
|
||
}
|
||
|
||
sources.forEach(function (src, srcIndex) {
|
||
if (!fs.existsSync(src)) {
|
||
if (src === '') src = "''"; // if src was empty string, display empty string
|
||
common.error('no such file or directory: ' + src, { continue: true });
|
||
return; // skip file
|
||
}
|
||
var srcStat = common.statFollowLinks(src);
|
||
if (!options.noFollowsymlink && srcStat.isDirectory()) {
|
||
if (!options.recursive) {
|
||
// Non-Recursive
|
||
common.error("omitting directory '" + src + "'", { continue: true });
|
||
} else {
|
||
// Recursive
|
||
// 'cp /a/source dest' should create 'source' in 'dest'
|
||
var newDest = (destStat && destStat.isDirectory()) ?
|
||
path.join(dest, path.basename(src)) :
|
||
dest;
|
||
|
||
try {
|
||
common.statFollowLinks(path.dirname(dest));
|
||
cpdirSyncRecursive(src, newDest, 0, { no_force: options.no_force, followsymlink: options.followsymlink });
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
common.error("cannot create directory '" + dest + "': No such file or directory");
|
||
}
|
||
}
|
||
} else {
|
||
// If here, src is a file
|
||
|
||
// When copying to '/path/dir':
|
||
// thisDest = '/path/dir/file1'
|
||
var thisDest = dest;
|
||
if (destStat && destStat.isDirectory()) {
|
||
thisDest = path.normalize(dest + '/' + path.basename(src));
|
||
}
|
||
|
||
var thisDestExists = fs.existsSync(thisDest);
|
||
if (thisDestExists && checkRecentCreated(sources, srcIndex)) {
|
||
// cannot overwrite file created recently in current execution, but we want to continue copying other files
|
||
if (!options.no_force) {
|
||
common.error("will not overwrite just-created '" + thisDest + "' with '" + src + "'", { continue: true });
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (thisDestExists && options.no_force) {
|
||
return; // skip file
|
||
}
|
||
|
||
if (path.relative(src, thisDest) === '') {
|
||
// a file cannot be copied to itself, but we want to continue copying other files
|
||
common.error("'" + thisDest + "' and '" + src + "' are the same file", { continue: true });
|
||
return;
|
||
}
|
||
|
||
copyFileSync(src, thisDest, options);
|
||
}
|
||
}); // forEach(src)
|
||
|
||
return new common.ShellString('', common.state.error, common.state.errorCode);
|
||
}
|
||
module.exports = _cp;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/dirs.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/dirs.js ***!
|
||
\******************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var _cd = __webpack_require__(/*! ./cd */ "./node_modules/shelljs/src/cd.js");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
|
||
common.register('dirs', _dirs, {
|
||
wrapOutput: false,
|
||
});
|
||
common.register('pushd', _pushd, {
|
||
wrapOutput: false,
|
||
});
|
||
common.register('popd', _popd, {
|
||
wrapOutput: false,
|
||
});
|
||
|
||
// Pushd/popd/dirs internals
|
||
var _dirStack = [];
|
||
|
||
function _isStackIndex(index) {
|
||
return (/^[\-+]\d+$/).test(index);
|
||
}
|
||
|
||
function _parseStackIndex(index) {
|
||
if (_isStackIndex(index)) {
|
||
if (Math.abs(index) < _dirStack.length + 1) { // +1 for pwd
|
||
return (/^-/).test(index) ? Number(index) - 1 : Number(index);
|
||
}
|
||
common.error(index + ': directory stack index out of range');
|
||
} else {
|
||
common.error(index + ': invalid number');
|
||
}
|
||
}
|
||
|
||
function _actualDirStack() {
|
||
return [process.cwd()].concat(_dirStack);
|
||
}
|
||
|
||
//@
|
||
//@ ### pushd([options,] [dir | '-N' | '+N'])
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-n`: Suppresses the normal change of directory when adding directories to the stack, so that only the stack is manipulated.
|
||
//@ + `-q`: Supresses output to the console.
|
||
//@
|
||
//@ Arguments:
|
||
//@
|
||
//@ + `dir`: Sets the current working directory to the top of the stack, then executes the equivalent of `cd dir`.
|
||
//@ + `+N`: Brings the Nth directory (counting from the left of the list printed by dirs, starting with zero) to the top of the list by rotating the stack.
|
||
//@ + `-N`: Brings the Nth directory (counting from the right of the list printed by dirs, starting with zero) to the top of the list by rotating the stack.
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ // process.cwd() === '/usr'
|
||
//@ pushd('/etc'); // Returns /etc /usr
|
||
//@ pushd('+1'); // Returns /usr /etc
|
||
//@ ```
|
||
//@
|
||
//@ Save the current directory on the top of the directory stack and then `cd` to `dir`. With no arguments, `pushd` exchanges the top two directories. Returns an array of paths in the stack.
|
||
function _pushd(options, dir) {
|
||
if (_isStackIndex(options)) {
|
||
dir = options;
|
||
options = '';
|
||
}
|
||
|
||
options = common.parseOptions(options, {
|
||
'n': 'no-cd',
|
||
'q': 'quiet',
|
||
});
|
||
|
||
var dirs = _actualDirStack();
|
||
|
||
if (dir === '+0') {
|
||
return dirs; // +0 is a noop
|
||
} else if (!dir) {
|
||
if (dirs.length > 1) {
|
||
dirs = dirs.splice(1, 1).concat(dirs);
|
||
} else {
|
||
return common.error('no other directory');
|
||
}
|
||
} else if (_isStackIndex(dir)) {
|
||
var n = _parseStackIndex(dir);
|
||
dirs = dirs.slice(n).concat(dirs.slice(0, n));
|
||
} else {
|
||
if (options['no-cd']) {
|
||
dirs.splice(1, 0, dir);
|
||
} else {
|
||
dirs.unshift(dir);
|
||
}
|
||
}
|
||
|
||
if (options['no-cd']) {
|
||
dirs = dirs.slice(1);
|
||
} else {
|
||
dir = path.resolve(dirs.shift());
|
||
_cd('', dir);
|
||
}
|
||
|
||
_dirStack = dirs;
|
||
return _dirs(options.quiet ? '-q' : '');
|
||
}
|
||
exports.pushd = _pushd;
|
||
|
||
//@
|
||
//@
|
||
//@ ### popd([options,] ['-N' | '+N'])
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-n`: Suppress the normal directory change when removing directories from the stack, so that only the stack is manipulated.
|
||
//@ + `-q`: Supresses output to the console.
|
||
//@
|
||
//@ Arguments:
|
||
//@
|
||
//@ + `+N`: Removes the Nth directory (counting from the left of the list printed by dirs), starting with zero.
|
||
//@ + `-N`: Removes the Nth directory (counting from the right of the list printed by dirs), starting with zero.
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ echo(process.cwd()); // '/usr'
|
||
//@ pushd('/etc'); // '/etc /usr'
|
||
//@ echo(process.cwd()); // '/etc'
|
||
//@ popd(); // '/usr'
|
||
//@ echo(process.cwd()); // '/usr'
|
||
//@ ```
|
||
//@
|
||
//@ When no arguments are given, `popd` removes the top directory from the stack and performs a `cd` to the new top directory. The elements are numbered from 0, starting at the first directory listed with dirs (i.e., `popd` is equivalent to `popd +0`). Returns an array of paths in the stack.
|
||
function _popd(options, index) {
|
||
if (_isStackIndex(options)) {
|
||
index = options;
|
||
options = '';
|
||
}
|
||
|
||
options = common.parseOptions(options, {
|
||
'n': 'no-cd',
|
||
'q': 'quiet',
|
||
});
|
||
|
||
if (!_dirStack.length) {
|
||
return common.error('directory stack empty');
|
||
}
|
||
|
||
index = _parseStackIndex(index || '+0');
|
||
|
||
if (options['no-cd'] || index > 0 || _dirStack.length + index === 0) {
|
||
index = index > 0 ? index - 1 : index;
|
||
_dirStack.splice(index, 1);
|
||
} else {
|
||
var dir = path.resolve(_dirStack.shift());
|
||
_cd('', dir);
|
||
}
|
||
|
||
return _dirs(options.quiet ? '-q' : '');
|
||
}
|
||
exports.popd = _popd;
|
||
|
||
//@
|
||
//@
|
||
//@ ### dirs([options | '+N' | '-N'])
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-c`: Clears the directory stack by deleting all of the elements.
|
||
//@ + `-q`: Supresses output to the console.
|
||
//@
|
||
//@ Arguments:
|
||
//@
|
||
//@ + `+N`: Displays the Nth directory (counting from the left of the list printed by dirs when invoked without options), starting with zero.
|
||
//@ + `-N`: Displays the Nth directory (counting from the right of the list printed by dirs when invoked without options), starting with zero.
|
||
//@
|
||
//@ Display the list of currently remembered directories. Returns an array of paths in the stack, or a single path if `+N` or `-N` was specified.
|
||
//@
|
||
//@ See also: `pushd`, `popd`
|
||
function _dirs(options, index) {
|
||
if (_isStackIndex(options)) {
|
||
index = options;
|
||
options = '';
|
||
}
|
||
|
||
options = common.parseOptions(options, {
|
||
'c': 'clear',
|
||
'q': 'quiet',
|
||
});
|
||
|
||
if (options.clear) {
|
||
_dirStack = [];
|
||
return _dirStack;
|
||
}
|
||
|
||
var stack = _actualDirStack();
|
||
|
||
if (index) {
|
||
index = _parseStackIndex(index);
|
||
|
||
if (index < 0) {
|
||
index = stack.length + index;
|
||
}
|
||
|
||
if (!options.quiet) {
|
||
common.log(stack[index]);
|
||
}
|
||
return stack[index];
|
||
}
|
||
|
||
if (!options.quiet) {
|
||
common.log(stack.join(' '));
|
||
}
|
||
|
||
return stack;
|
||
}
|
||
exports.dirs = _dirs;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/echo.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/echo.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var format = __webpack_require__(/*! util */ "util").format;
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
|
||
common.register('echo', _echo, {
|
||
allowGlobbing: false,
|
||
});
|
||
|
||
//@
|
||
//@ ### echo([options,] string [, string ...])
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-e`: interpret backslash escapes (default)
|
||
//@ + `-n`: remove trailing newline from output
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ echo('hello world');
|
||
//@ var str = echo('hello world');
|
||
//@ echo('-n', 'no newline at end');
|
||
//@ ```
|
||
//@
|
||
//@ Prints `string` to stdout, and returns string with additional utility methods
|
||
//@ like `.to()`.
|
||
function _echo(opts) {
|
||
// allow strings starting with '-', see issue #20
|
||
var messages = [].slice.call(arguments, opts ? 0 : 1);
|
||
var options = {};
|
||
|
||
// If the first argument starts with '-', parse it as options string.
|
||
// If parseOptions throws, it wasn't an options string.
|
||
try {
|
||
options = common.parseOptions(messages[0], {
|
||
'e': 'escapes',
|
||
'n': 'no_newline',
|
||
}, {
|
||
silent: true,
|
||
});
|
||
|
||
// Allow null to be echoed
|
||
if (messages[0]) {
|
||
messages.shift();
|
||
}
|
||
} catch (_) {
|
||
// Clear out error if an error occurred
|
||
common.state.error = null;
|
||
}
|
||
|
||
var output = format.apply(null, messages);
|
||
|
||
// Add newline if -n is not passed.
|
||
if (!options.no_newline) {
|
||
output += '\n';
|
||
}
|
||
|
||
process.stdout.write(output);
|
||
|
||
return output;
|
||
}
|
||
|
||
module.exports = _echo;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/error.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/shelljs/src/error.js ***!
|
||
\*******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
|
||
//@
|
||
//@ ### error()
|
||
//@
|
||
//@ Tests if error occurred in the last command. Returns a truthy value if an
|
||
//@ error returned, or a falsy value otherwise.
|
||
//@
|
||
//@ **Note**: do not rely on the
|
||
//@ return value to be an error message. If you need the last error message, use
|
||
//@ the `.stderr` attribute from the last command's return value instead.
|
||
function error() {
|
||
return common.state.error;
|
||
}
|
||
module.exports = error;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/exec-child.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/shelljs/src/exec-child.js ***!
|
||
\************************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
/* module decorator */ module = __webpack_require__.nmd(module);
|
||
if (__webpack_require__.c[__webpack_require__.s] !== module) {
|
||
throw new Error('This file should not be required');
|
||
}
|
||
|
||
var childProcess = __webpack_require__(/*! child_process */ "child_process");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
var paramFilePath = process.argv[2];
|
||
|
||
var serializedParams = fs.readFileSync(paramFilePath, 'utf8');
|
||
var params = JSON.parse(serializedParams);
|
||
|
||
var cmd = params.command;
|
||
var execOptions = params.execOptions;
|
||
var pipe = params.pipe;
|
||
var stdoutFile = params.stdoutFile;
|
||
var stderrFile = params.stderrFile;
|
||
|
||
var c = childProcess.exec(cmd, execOptions, function (err) {
|
||
if (!err) {
|
||
process.exitCode = 0;
|
||
} else if (err.code === undefined) {
|
||
process.exitCode = 1;
|
||
} else {
|
||
process.exitCode = err.code;
|
||
}
|
||
});
|
||
|
||
var stdoutStream = fs.createWriteStream(stdoutFile);
|
||
var stderrStream = fs.createWriteStream(stderrFile);
|
||
|
||
c.stdout.pipe(stdoutStream);
|
||
c.stderr.pipe(stderrStream);
|
||
c.stdout.pipe(process.stdout);
|
||
c.stderr.pipe(process.stderr);
|
||
|
||
if (pipe) {
|
||
c.stdin.end(pipe);
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/exec.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/exec.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var _tempDir = __webpack_require__(/*! ./tempdir */ "./node_modules/shelljs/src/tempdir.js").tempDir;
|
||
var _pwd = __webpack_require__(/*! ./pwd */ "./node_modules/shelljs/src/pwd.js");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var child = __webpack_require__(/*! child_process */ "child_process");
|
||
|
||
var DEFAULT_MAXBUFFER_SIZE = 20 * 1024 * 1024;
|
||
var DEFAULT_ERROR_CODE = 1;
|
||
|
||
common.register('exec', _exec, {
|
||
unix: false,
|
||
canReceivePipe: true,
|
||
wrapOutput: false,
|
||
});
|
||
|
||
// We use this function to run `exec` synchronously while also providing realtime
|
||
// output.
|
||
function execSync(cmd, opts, pipe) {
|
||
if (!common.config.execPath) {
|
||
common.error('Unable to find a path to the node binary. Please manually set config.execPath');
|
||
}
|
||
|
||
var tempDir = _tempDir();
|
||
var paramsFile = path.resolve(tempDir + '/' + common.randomFileName());
|
||
var stderrFile = path.resolve(tempDir + '/' + common.randomFileName());
|
||
var stdoutFile = path.resolve(tempDir + '/' + common.randomFileName());
|
||
|
||
opts = common.extend({
|
||
silent: common.config.silent,
|
||
cwd: _pwd().toString(),
|
||
env: process.env,
|
||
maxBuffer: DEFAULT_MAXBUFFER_SIZE,
|
||
encoding: 'utf8',
|
||
}, opts);
|
||
|
||
if (fs.existsSync(paramsFile)) common.unlinkSync(paramsFile);
|
||
if (fs.existsSync(stderrFile)) common.unlinkSync(stderrFile);
|
||
if (fs.existsSync(stdoutFile)) common.unlinkSync(stdoutFile);
|
||
|
||
opts.cwd = path.resolve(opts.cwd);
|
||
|
||
var paramsToSerialize = {
|
||
command: cmd,
|
||
execOptions: opts,
|
||
pipe: pipe,
|
||
stdoutFile: stdoutFile,
|
||
stderrFile: stderrFile,
|
||
};
|
||
|
||
fs.writeFileSync(paramsFile, JSON.stringify(paramsToSerialize), 'utf8');
|
||
|
||
var execArgs = [
|
||
path.join(__dirname, 'exec-child.js'),
|
||
paramsFile,
|
||
];
|
||
|
||
/* istanbul ignore else */
|
||
if (opts.silent) {
|
||
opts.stdio = 'ignore';
|
||
} else {
|
||
opts.stdio = [0, 1, 2];
|
||
}
|
||
|
||
var code = 0;
|
||
|
||
// Welcome to the future
|
||
try {
|
||
// Bad things if we pass in a `shell` option to child_process.execFileSync,
|
||
// so we need to explicitly remove it here.
|
||
delete opts.shell;
|
||
|
||
child.execFileSync(common.config.execPath, execArgs, opts);
|
||
} catch (e) {
|
||
// Commands with non-zero exit code raise an exception.
|
||
code = e.status || DEFAULT_ERROR_CODE;
|
||
}
|
||
|
||
// fs.readFileSync uses buffer encoding by default, so call
|
||
// it without the encoding option if the encoding is 'buffer'.
|
||
// Also, if the exec timeout is too short for node to start up,
|
||
// the files will not be created, so these calls will throw.
|
||
var stdout = '';
|
||
var stderr = '';
|
||
if (opts.encoding === 'buffer') {
|
||
stdout = fs.readFileSync(stdoutFile);
|
||
stderr = fs.readFileSync(stderrFile);
|
||
} else {
|
||
stdout = fs.readFileSync(stdoutFile, opts.encoding);
|
||
stderr = fs.readFileSync(stderrFile, opts.encoding);
|
||
}
|
||
|
||
// No biggie if we can't erase the files now -- they're in a temp dir anyway
|
||
try { common.unlinkSync(paramsFile); } catch (e) {}
|
||
try { common.unlinkSync(stderrFile); } catch (e) {}
|
||
try { common.unlinkSync(stdoutFile); } catch (e) {}
|
||
|
||
if (code !== 0) {
|
||
// Note: `silent` should be unconditionally true to avoid double-printing
|
||
// the command's stderr, and to avoid printing any stderr when the user has
|
||
// set `shell.config.silent`.
|
||
common.error(stderr, code, { continue: true, silent: true });
|
||
}
|
||
var obj = common.ShellString(stdout, stderr, code);
|
||
return obj;
|
||
} // execSync()
|
||
|
||
// Wrapper around exec() to enable echoing output to console in real time
|
||
function execAsync(cmd, opts, pipe, callback) {
|
||
opts = common.extend({
|
||
silent: common.config.silent,
|
||
cwd: _pwd().toString(),
|
||
env: process.env,
|
||
maxBuffer: DEFAULT_MAXBUFFER_SIZE,
|
||
encoding: 'utf8',
|
||
}, opts);
|
||
|
||
var c = child.exec(cmd, opts, function (err, stdout, stderr) {
|
||
if (callback) {
|
||
if (!err) {
|
||
callback(0, stdout, stderr);
|
||
} else if (err.code === undefined) {
|
||
// See issue #536
|
||
/* istanbul ignore next */
|
||
callback(1, stdout, stderr);
|
||
} else {
|
||
callback(err.code, stdout, stderr);
|
||
}
|
||
}
|
||
});
|
||
|
||
if (pipe) c.stdin.end(pipe);
|
||
|
||
if (!opts.silent) {
|
||
c.stdout.pipe(process.stdout);
|
||
c.stderr.pipe(process.stderr);
|
||
}
|
||
|
||
return c;
|
||
}
|
||
|
||
//@
|
||
//@ ### exec(command [, options] [, callback])
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `async`: Asynchronous execution. If a callback is provided, it will be set to
|
||
//@ `true`, regardless of the passed value (default: `false`).
|
||
//@ + `silent`: Do not echo program output to console (default: `false`).
|
||
//@ + `encoding`: Character encoding to use. Affects the values returned to stdout and stderr, and
|
||
//@ what is written to stdout and stderr when not in silent mode (default: `'utf8'`).
|
||
//@ + and any option available to Node.js's
|
||
//@ [`child_process.exec()`](https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var version = exec('node --version', {silent:true}).stdout;
|
||
//@
|
||
//@ var child = exec('some_long_running_process', {async:true});
|
||
//@ child.stdout.on('data', function(data) {
|
||
//@ /* ... do something with data ... */
|
||
//@ });
|
||
//@
|
||
//@ exec('some_long_running_process', function(code, stdout, stderr) {
|
||
//@ console.log('Exit code:', code);
|
||
//@ console.log('Program output:', stdout);
|
||
//@ console.log('Program stderr:', stderr);
|
||
//@ });
|
||
//@ ```
|
||
//@
|
||
//@ Executes the given `command` _synchronously_, unless otherwise specified. When in synchronous
|
||
//@ mode, this returns a `ShellString` (compatible with ShellJS v0.6.x, which returns an object
|
||
//@ of the form `{ code:..., stdout:... , stderr:... }`). Otherwise, this returns the child process
|
||
//@ object, and the `callback` receives the arguments `(code, stdout, stderr)`.
|
||
//@
|
||
//@ Not seeing the behavior you want? `exec()` runs everything through `sh`
|
||
//@ by default (or `cmd.exe` on Windows), which differs from `bash`. If you
|
||
//@ need bash-specific behavior, try out the `{shell: 'path/to/bash'}` option.
|
||
function _exec(command, options, callback) {
|
||
options = options || {};
|
||
if (!command) common.error('must specify command');
|
||
|
||
var pipe = common.readFromPipe();
|
||
|
||
// Callback is defined instead of options.
|
||
if (typeof options === 'function') {
|
||
callback = options;
|
||
options = { async: true };
|
||
}
|
||
|
||
// Callback is defined with options.
|
||
if (typeof options === 'object' && typeof callback === 'function') {
|
||
options.async = true;
|
||
}
|
||
|
||
options = common.extend({
|
||
silent: common.config.silent,
|
||
async: false,
|
||
}, options);
|
||
|
||
if (options.async) {
|
||
return execAsync(command, options, pipe, callback);
|
||
} else {
|
||
return execSync(command, options, pipe);
|
||
}
|
||
}
|
||
module.exports = _exec;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/find.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/find.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var _ls = __webpack_require__(/*! ./ls */ "./node_modules/shelljs/src/ls.js");
|
||
|
||
common.register('find', _find, {});
|
||
|
||
//@
|
||
//@ ### find(path [, path ...])
|
||
//@ ### find(path_array)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ find('src', 'lib');
|
||
//@ find(['src', 'lib']); // same as above
|
||
//@ find('.').filter(function(file) { return file.match(/\.js$/); });
|
||
//@ ```
|
||
//@
|
||
//@ Returns array of all files (however deep) in the given paths.
|
||
//@
|
||
//@ The main difference from `ls('-R', path)` is that the resulting file names
|
||
//@ include the base directories (e.g., `lib/resources/file1` instead of just `file1`).
|
||
function _find(options, paths) {
|
||
if (!paths) {
|
||
common.error('no path specified');
|
||
} else if (typeof paths === 'string') {
|
||
paths = [].slice.call(arguments, 1);
|
||
}
|
||
|
||
var list = [];
|
||
|
||
function pushFile(file) {
|
||
if (process.platform === 'win32') {
|
||
file = file.replace(/\\/g, '/');
|
||
}
|
||
list.push(file);
|
||
}
|
||
|
||
// why not simply do `ls('-R', paths)`? because the output wouldn't give the base dirs
|
||
// to get the base dir in the output, we need instead `ls('-R', 'dir/*')` for every directory
|
||
|
||
paths.forEach(function (file) {
|
||
var stat;
|
||
try {
|
||
stat = common.statFollowLinks(file);
|
||
} catch (e) {
|
||
common.error('no such file or directory: ' + file);
|
||
}
|
||
|
||
pushFile(file);
|
||
|
||
if (stat.isDirectory()) {
|
||
_ls({ recursive: true, all: true }, file).forEach(function (subfile) {
|
||
pushFile(path.join(file, subfile));
|
||
});
|
||
}
|
||
});
|
||
|
||
return list;
|
||
}
|
||
module.exports = _find;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/grep.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/grep.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('grep', _grep, {
|
||
globStart: 2, // don't glob-expand the regex
|
||
canReceivePipe: true,
|
||
cmdOptions: {
|
||
'v': 'inverse',
|
||
'l': 'nameOnly',
|
||
'i': 'ignoreCase',
|
||
},
|
||
});
|
||
|
||
//@
|
||
//@ ### grep([options,] regex_filter, file [, file ...])
|
||
//@ ### grep([options,] regex_filter, file_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-v`: Invert `regex_filter` (only print non-matching lines).
|
||
//@ + `-l`: Print only filenames of matching files.
|
||
//@ + `-i`: Ignore case.
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ grep('-v', 'GLOBAL_VARIABLE', '*.js');
|
||
//@ grep('GLOBAL_VARIABLE', '*.js');
|
||
//@ ```
|
||
//@
|
||
//@ Reads input string from given files and returns a string containing all lines of the
|
||
//@ file that match the given `regex_filter`.
|
||
function _grep(options, regex, files) {
|
||
// Check if this is coming from a pipe
|
||
var pipe = common.readFromPipe();
|
||
|
||
if (!files && !pipe) common.error('no paths given', 2);
|
||
|
||
files = [].slice.call(arguments, 2);
|
||
|
||
if (pipe) {
|
||
files.unshift('-');
|
||
}
|
||
|
||
var grep = [];
|
||
if (options.ignoreCase) {
|
||
regex = new RegExp(regex, 'i');
|
||
}
|
||
files.forEach(function (file) {
|
||
if (!fs.existsSync(file) && file !== '-') {
|
||
common.error('no such file or directory: ' + file, 2, { continue: true });
|
||
return;
|
||
}
|
||
|
||
var contents = file === '-' ? pipe : fs.readFileSync(file, 'utf8');
|
||
if (options.nameOnly) {
|
||
if (contents.match(regex)) {
|
||
grep.push(file);
|
||
}
|
||
} else {
|
||
var lines = contents.split('\n');
|
||
lines.forEach(function (line) {
|
||
var matched = line.match(regex);
|
||
if ((options.inverse && !matched) || (!options.inverse && matched)) {
|
||
grep.push(line);
|
||
}
|
||
});
|
||
}
|
||
});
|
||
|
||
return grep.join('\n') + '\n';
|
||
}
|
||
module.exports = _grep;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/head.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/head.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('head', _head, {
|
||
canReceivePipe: true,
|
||
cmdOptions: {
|
||
'n': 'numLines',
|
||
},
|
||
});
|
||
|
||
// Reads |numLines| lines or the entire file, whichever is less.
|
||
function readSomeLines(file, numLines) {
|
||
var buf = common.buffer();
|
||
var bufLength = buf.length;
|
||
var bytesRead = bufLength;
|
||
var pos = 0;
|
||
|
||
var fdr = fs.openSync(file, 'r');
|
||
var numLinesRead = 0;
|
||
var ret = '';
|
||
while (bytesRead === bufLength && numLinesRead < numLines) {
|
||
bytesRead = fs.readSync(fdr, buf, 0, bufLength, pos);
|
||
var bufStr = buf.toString('utf8', 0, bytesRead);
|
||
numLinesRead += bufStr.split('\n').length - 1;
|
||
ret += bufStr;
|
||
pos += bytesRead;
|
||
}
|
||
|
||
fs.closeSync(fdr);
|
||
return ret;
|
||
}
|
||
|
||
//@
|
||
//@ ### head([{'-n': \<num\>},] file [, file ...])
|
||
//@ ### head([{'-n': \<num\>},] file_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-n <num>`: Show the first `<num>` lines of the files
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var str = head({'-n': 1}, 'file*.txt');
|
||
//@ var str = head('file1', 'file2');
|
||
//@ var str = head(['file1', 'file2']); // same as above
|
||
//@ ```
|
||
//@
|
||
//@ Read the start of a file.
|
||
function _head(options, files) {
|
||
var head = [];
|
||
var pipe = common.readFromPipe();
|
||
|
||
if (!files && !pipe) common.error('no paths given');
|
||
|
||
var idx = 1;
|
||
if (options.numLines === true) {
|
||
idx = 2;
|
||
options.numLines = Number(arguments[1]);
|
||
} else if (options.numLines === false) {
|
||
options.numLines = 10;
|
||
}
|
||
files = [].slice.call(arguments, idx);
|
||
|
||
if (pipe) {
|
||
files.unshift('-');
|
||
}
|
||
|
||
var shouldAppendNewline = false;
|
||
files.forEach(function (file) {
|
||
if (file !== '-') {
|
||
if (!fs.existsSync(file)) {
|
||
common.error('no such file or directory: ' + file, { continue: true });
|
||
return;
|
||
} else if (common.statFollowLinks(file).isDirectory()) {
|
||
common.error("error reading '" + file + "': Is a directory", {
|
||
continue: true,
|
||
});
|
||
return;
|
||
}
|
||
}
|
||
|
||
var contents;
|
||
if (file === '-') {
|
||
contents = pipe;
|
||
} else if (options.numLines < 0) {
|
||
contents = fs.readFileSync(file, 'utf8');
|
||
} else {
|
||
contents = readSomeLines(file, options.numLines);
|
||
}
|
||
|
||
var lines = contents.split('\n');
|
||
var hasTrailingNewline = (lines[lines.length - 1] === '');
|
||
if (hasTrailingNewline) {
|
||
lines.pop();
|
||
}
|
||
shouldAppendNewline = (hasTrailingNewline || options.numLines < lines.length);
|
||
|
||
head = head.concat(lines.slice(0, options.numLines));
|
||
});
|
||
|
||
if (shouldAppendNewline) {
|
||
head.push(''); // to add a trailing newline once we join
|
||
}
|
||
return head.join('\n');
|
||
}
|
||
module.exports = _head;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/ln.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/shelljs/src/ln.js ***!
|
||
\****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
|
||
common.register('ln', _ln, {
|
||
cmdOptions: {
|
||
's': 'symlink',
|
||
'f': 'force',
|
||
},
|
||
});
|
||
|
||
//@
|
||
//@ ### ln([options,] source, dest)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-s`: symlink
|
||
//@ + `-f`: force
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ ln('file', 'newlink');
|
||
//@ ln('-sf', 'file', 'existing');
|
||
//@ ```
|
||
//@
|
||
//@ Links `source` to `dest`. Use `-f` to force the link, should `dest` already exist.
|
||
function _ln(options, source, dest) {
|
||
if (!source || !dest) {
|
||
common.error('Missing <source> and/or <dest>');
|
||
}
|
||
|
||
source = String(source);
|
||
var sourcePath = path.normalize(source).replace(RegExp(path.sep + '$'), '');
|
||
var isAbsolute = (path.resolve(source) === sourcePath);
|
||
dest = path.resolve(process.cwd(), String(dest));
|
||
|
||
if (fs.existsSync(dest)) {
|
||
if (!options.force) {
|
||
common.error('Destination file exists', { continue: true });
|
||
}
|
||
|
||
fs.unlinkSync(dest);
|
||
}
|
||
|
||
if (options.symlink) {
|
||
var isWindows = process.platform === 'win32';
|
||
var linkType = isWindows ? 'file' : null;
|
||
var resolvedSourcePath = isAbsolute ? sourcePath : path.resolve(process.cwd(), path.dirname(dest), source);
|
||
if (!fs.existsSync(resolvedSourcePath)) {
|
||
common.error('Source file does not exist', { continue: true });
|
||
} else if (isWindows && common.statFollowLinks(resolvedSourcePath).isDirectory()) {
|
||
linkType = 'junction';
|
||
}
|
||
|
||
try {
|
||
fs.symlinkSync(linkType === 'junction' ? resolvedSourcePath : source, dest, linkType);
|
||
} catch (err) {
|
||
common.error(err.message);
|
||
}
|
||
} else {
|
||
if (!fs.existsSync(source)) {
|
||
common.error('Source file does not exist', { continue: true });
|
||
}
|
||
try {
|
||
fs.linkSync(source, dest);
|
||
} catch (err) {
|
||
common.error(err.message);
|
||
}
|
||
}
|
||
return '';
|
||
}
|
||
module.exports = _ln;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/ls.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/shelljs/src/ls.js ***!
|
||
\****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var glob = __webpack_require__(/*! glob */ "./node_modules/glob/glob.js");
|
||
|
||
var globPatternRecursive = path.sep + '**';
|
||
|
||
common.register('ls', _ls, {
|
||
cmdOptions: {
|
||
'R': 'recursive',
|
||
'A': 'all',
|
||
'L': 'link',
|
||
'a': 'all_deprecated',
|
||
'd': 'directory',
|
||
'l': 'long',
|
||
},
|
||
});
|
||
|
||
//@
|
||
//@ ### ls([options,] [path, ...])
|
||
//@ ### ls([options,] path_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-R`: recursive
|
||
//@ + `-A`: all files (include files beginning with `.`, except for `.` and `..`)
|
||
//@ + `-L`: follow symlinks
|
||
//@ + `-d`: list directories themselves, not their contents
|
||
//@ + `-l`: list objects representing each file, each with fields containing `ls
|
||
//@ -l` output fields. See
|
||
//@ [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats)
|
||
//@ for more info
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ ls('projs/*.js');
|
||
//@ ls('-R', '/users/me', '/tmp');
|
||
//@ ls('-R', ['/users/me', '/tmp']); // same as above
|
||
//@ ls('-l', 'file.txt'); // { name: 'file.txt', mode: 33188, nlink: 1, ...}
|
||
//@ ```
|
||
//@
|
||
//@ Returns array of files in the given `path`, or files in
|
||
//@ the current directory if no `path` is provided.
|
||
function _ls(options, paths) {
|
||
if (options.all_deprecated) {
|
||
// We won't support the -a option as it's hard to image why it's useful
|
||
// (it includes '.' and '..' in addition to '.*' files)
|
||
// For backwards compatibility we'll dump a deprecated message and proceed as before
|
||
common.log('ls: Option -a is deprecated. Use -A instead');
|
||
options.all = true;
|
||
}
|
||
|
||
if (!paths) {
|
||
paths = ['.'];
|
||
} else {
|
||
paths = [].slice.call(arguments, 1);
|
||
}
|
||
|
||
var list = [];
|
||
|
||
function pushFile(abs, relName, stat) {
|
||
if (process.platform === 'win32') {
|
||
relName = relName.replace(/\\/g, '/');
|
||
}
|
||
if (options.long) {
|
||
stat = stat || (options.link ? common.statFollowLinks(abs) : common.statNoFollowLinks(abs));
|
||
list.push(addLsAttributes(relName, stat));
|
||
} else {
|
||
// list.push(path.relative(rel || '.', file));
|
||
list.push(relName);
|
||
}
|
||
}
|
||
|
||
paths.forEach(function (p) {
|
||
var stat;
|
||
|
||
try {
|
||
stat = options.link ? common.statFollowLinks(p) : common.statNoFollowLinks(p);
|
||
// follow links to directories by default
|
||
if (stat.isSymbolicLink()) {
|
||
/* istanbul ignore next */
|
||
// workaround for https://github.com/shelljs/shelljs/issues/795
|
||
// codecov seems to have a bug that miscalculate this block as uncovered.
|
||
// but according to nyc report this block does get covered.
|
||
try {
|
||
var _stat = common.statFollowLinks(p);
|
||
if (_stat.isDirectory()) {
|
||
stat = _stat;
|
||
}
|
||
} catch (_) {} // bad symlink, treat it like a file
|
||
}
|
||
} catch (e) {
|
||
common.error('no such file or directory: ' + p, 2, { continue: true });
|
||
return;
|
||
}
|
||
|
||
// If the stat succeeded
|
||
if (stat.isDirectory() && !options.directory) {
|
||
if (options.recursive) {
|
||
// use glob, because it's simple
|
||
glob.sync(p + globPatternRecursive, { dot: options.all, follow: options.link })
|
||
.forEach(function (item) {
|
||
// Glob pattern returns the directory itself and needs to be filtered out.
|
||
if (path.relative(p, item)) {
|
||
pushFile(item, path.relative(p, item));
|
||
}
|
||
});
|
||
} else if (options.all) {
|
||
// use fs.readdirSync, because it's fast
|
||
fs.readdirSync(p).forEach(function (item) {
|
||
pushFile(path.join(p, item), item);
|
||
});
|
||
} else {
|
||
// use fs.readdirSync and then filter out secret files
|
||
fs.readdirSync(p).forEach(function (item) {
|
||
if (item[0] !== '.') {
|
||
pushFile(path.join(p, item), item);
|
||
}
|
||
});
|
||
}
|
||
} else {
|
||
pushFile(p, p, stat);
|
||
}
|
||
});
|
||
|
||
// Add methods, to make this more compatible with ShellStrings
|
||
return list;
|
||
}
|
||
|
||
function addLsAttributes(pathName, stats) {
|
||
// Note: this object will contain more information than .toString() returns
|
||
stats.name = pathName;
|
||
stats.toString = function () {
|
||
// Return a string resembling unix's `ls -l` format
|
||
return [this.mode, this.nlink, this.uid, this.gid, this.size, this.mtime, this.name].join(' ');
|
||
};
|
||
return stats;
|
||
}
|
||
|
||
module.exports = _ls;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/mkdir.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/shelljs/src/mkdir.js ***!
|
||
\*******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
|
||
common.register('mkdir', _mkdir, {
|
||
cmdOptions: {
|
||
'p': 'fullpath',
|
||
},
|
||
});
|
||
|
||
// Recursively creates `dir`
|
||
function mkdirSyncRecursive(dir) {
|
||
var baseDir = path.dirname(dir);
|
||
|
||
// Prevents some potential problems arising from malformed UNCs or
|
||
// insufficient permissions.
|
||
/* istanbul ignore next */
|
||
if (baseDir === dir) {
|
||
common.error('dirname() failed: [' + dir + ']');
|
||
}
|
||
|
||
// Base dir exists, no recursion necessary
|
||
if (fs.existsSync(baseDir)) {
|
||
fs.mkdirSync(dir, parseInt('0777', 8));
|
||
return;
|
||
}
|
||
|
||
// Base dir does not exist, go recursive
|
||
mkdirSyncRecursive(baseDir);
|
||
|
||
// Base dir created, can create dir
|
||
fs.mkdirSync(dir, parseInt('0777', 8));
|
||
}
|
||
|
||
//@
|
||
//@ ### mkdir([options,] dir [, dir ...])
|
||
//@ ### mkdir([options,] dir_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-p`: full path (and create intermediate directories, if necessary)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ mkdir('-p', '/tmp/a/b/c/d', '/tmp/e/f/g');
|
||
//@ mkdir('-p', ['/tmp/a/b/c/d', '/tmp/e/f/g']); // same as above
|
||
//@ ```
|
||
//@
|
||
//@ Creates directories.
|
||
function _mkdir(options, dirs) {
|
||
if (!dirs) common.error('no paths given');
|
||
|
||
if (typeof dirs === 'string') {
|
||
dirs = [].slice.call(arguments, 1);
|
||
}
|
||
// if it's array leave it as it is
|
||
|
||
dirs.forEach(function (dir) {
|
||
try {
|
||
var stat = common.statNoFollowLinks(dir);
|
||
if (!options.fullpath) {
|
||
common.error('path already exists: ' + dir, { continue: true });
|
||
} else if (stat.isFile()) {
|
||
common.error('cannot create directory ' + dir + ': File exists', { continue: true });
|
||
}
|
||
return; // skip dir
|
||
} catch (e) {
|
||
// do nothing
|
||
}
|
||
|
||
// Base dir does not exist, and no -p option given
|
||
var baseDir = path.dirname(dir);
|
||
if (!fs.existsSync(baseDir) && !options.fullpath) {
|
||
common.error('no such file or directory: ' + baseDir, { continue: true });
|
||
return; // skip dir
|
||
}
|
||
|
||
try {
|
||
if (options.fullpath) {
|
||
mkdirSyncRecursive(path.resolve(dir));
|
||
} else {
|
||
fs.mkdirSync(dir, parseInt('0777', 8));
|
||
}
|
||
} catch (e) {
|
||
var reason;
|
||
if (e.code === 'EACCES') {
|
||
reason = 'Permission denied';
|
||
} else if (e.code === 'ENOTDIR' || e.code === 'ENOENT') {
|
||
reason = 'Not a directory';
|
||
} else {
|
||
/* istanbul ignore next */
|
||
throw e;
|
||
}
|
||
common.error('cannot create directory ' + dir + ': ' + reason, { continue: true });
|
||
}
|
||
});
|
||
return '';
|
||
} // mkdir
|
||
module.exports = _mkdir;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/mv.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/shelljs/src/mv.js ***!
|
||
\****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var cp = __webpack_require__(/*! ./cp */ "./node_modules/shelljs/src/cp.js");
|
||
var rm = __webpack_require__(/*! ./rm */ "./node_modules/shelljs/src/rm.js");
|
||
|
||
common.register('mv', _mv, {
|
||
cmdOptions: {
|
||
'f': '!no_force',
|
||
'n': 'no_force',
|
||
},
|
||
});
|
||
|
||
// Checks if cureent file was created recently
|
||
function checkRecentCreated(sources, index) {
|
||
var lookedSource = sources[index];
|
||
return sources.slice(0, index).some(function (src) {
|
||
return path.basename(src) === path.basename(lookedSource);
|
||
});
|
||
}
|
||
|
||
//@
|
||
//@ ### mv([options ,] source [, source ...], dest')
|
||
//@ ### mv([options ,] source_array, dest')
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-f`: force (default behavior)
|
||
//@ + `-n`: no-clobber
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ mv('-n', 'file', 'dir/');
|
||
//@ mv('file1', 'file2', 'dir/');
|
||
//@ mv(['file1', 'file2'], 'dir/'); // same as above
|
||
//@ ```
|
||
//@
|
||
//@ Moves `source` file(s) to `dest`.
|
||
function _mv(options, sources, dest) {
|
||
// Get sources, dest
|
||
if (arguments.length < 3) {
|
||
common.error('missing <source> and/or <dest>');
|
||
} else if (arguments.length > 3) {
|
||
sources = [].slice.call(arguments, 1, arguments.length - 1);
|
||
dest = arguments[arguments.length - 1];
|
||
} else if (typeof sources === 'string') {
|
||
sources = [sources];
|
||
} else {
|
||
// TODO(nate): figure out if we actually need this line
|
||
common.error('invalid arguments');
|
||
}
|
||
|
||
var exists = fs.existsSync(dest);
|
||
var stats = exists && common.statFollowLinks(dest);
|
||
|
||
// Dest is not existing dir, but multiple sources given
|
||
if ((!exists || !stats.isDirectory()) && sources.length > 1) {
|
||
common.error('dest is not a directory (too many sources)');
|
||
}
|
||
|
||
// Dest is an existing file, but no -f given
|
||
if (exists && stats.isFile() && options.no_force) {
|
||
common.error('dest file already exists: ' + dest);
|
||
}
|
||
|
||
sources.forEach(function (src, srcIndex) {
|
||
if (!fs.existsSync(src)) {
|
||
common.error('no such file or directory: ' + src, { continue: true });
|
||
return; // skip file
|
||
}
|
||
|
||
// If here, src exists
|
||
|
||
// When copying to '/path/dir':
|
||
// thisDest = '/path/dir/file1'
|
||
var thisDest = dest;
|
||
if (fs.existsSync(dest) && common.statFollowLinks(dest).isDirectory()) {
|
||
thisDest = path.normalize(dest + '/' + path.basename(src));
|
||
}
|
||
|
||
var thisDestExists = fs.existsSync(thisDest);
|
||
|
||
if (thisDestExists && checkRecentCreated(sources, srcIndex)) {
|
||
// cannot overwrite file created recently in current execution, but we want to continue copying other files
|
||
if (!options.no_force) {
|
||
common.error("will not overwrite just-created '" + thisDest + "' with '" + src + "'", { continue: true });
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (fs.existsSync(thisDest) && options.no_force) {
|
||
common.error('dest file already exists: ' + thisDest, { continue: true });
|
||
return; // skip file
|
||
}
|
||
|
||
if (path.resolve(src) === path.dirname(path.resolve(thisDest))) {
|
||
common.error('cannot move to self: ' + src, { continue: true });
|
||
return; // skip file
|
||
}
|
||
|
||
try {
|
||
fs.renameSync(src, thisDest);
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
if (e.code === 'EXDEV') {
|
||
// If we're trying to `mv` to an external partition, we'll actually need
|
||
// to perform a copy and then clean up the original file. If either the
|
||
// copy or the rm fails with an exception, we should allow this
|
||
// exception to pass up to the top level.
|
||
cp('-r', src, thisDest);
|
||
rm('-rf', src);
|
||
}
|
||
}
|
||
}); // forEach(src)
|
||
return '';
|
||
} // mv
|
||
module.exports = _mv;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/popd.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/popd.js ***!
|
||
\******************************************/
|
||
/***/ (() => {
|
||
|
||
// see dirs.js
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/pushd.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/shelljs/src/pushd.js ***!
|
||
\*******************************************/
|
||
/***/ (() => {
|
||
|
||
// see dirs.js
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/pwd.js":
|
||
/*!*****************************************!*\
|
||
!*** ./node_modules/shelljs/src/pwd.js ***!
|
||
\*****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
|
||
common.register('pwd', _pwd, {
|
||
allowGlobbing: false,
|
||
});
|
||
|
||
//@
|
||
//@ ### pwd()
|
||
//@
|
||
//@ Returns the current directory.
|
||
function _pwd() {
|
||
var pwd = path.resolve(process.cwd());
|
||
return pwd;
|
||
}
|
||
module.exports = _pwd;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/rm.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/shelljs/src/rm.js ***!
|
||
\****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('rm', _rm, {
|
||
cmdOptions: {
|
||
'f': 'force',
|
||
'r': 'recursive',
|
||
'R': 'recursive',
|
||
},
|
||
});
|
||
|
||
// Recursively removes 'dir'
|
||
// Adapted from https://github.com/ryanmcgrath/wrench-js
|
||
//
|
||
// Copyright (c) 2010 Ryan McGrath
|
||
// Copyright (c) 2012 Artur Adib
|
||
//
|
||
// Licensed under the MIT License
|
||
// http://www.opensource.org/licenses/mit-license.php
|
||
function rmdirSyncRecursive(dir, force, fromSymlink) {
|
||
var files;
|
||
|
||
files = fs.readdirSync(dir);
|
||
|
||
// Loop through and delete everything in the sub-tree after checking it
|
||
for (var i = 0; i < files.length; i++) {
|
||
var file = dir + '/' + files[i];
|
||
var currFile = common.statNoFollowLinks(file);
|
||
|
||
if (currFile.isDirectory()) { // Recursive function back to the beginning
|
||
rmdirSyncRecursive(file, force);
|
||
} else { // Assume it's a file - perhaps a try/catch belongs here?
|
||
if (force || isWriteable(file)) {
|
||
try {
|
||
common.unlinkSync(file);
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
common.error('could not remove file (code ' + e.code + '): ' + file, {
|
||
continue: true,
|
||
});
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// if was directory was referenced through a symbolic link,
|
||
// the contents should be removed, but not the directory itself
|
||
if (fromSymlink) return;
|
||
|
||
// Now that we know everything in the sub-tree has been deleted, we can delete the main directory.
|
||
// Huzzah for the shopkeep.
|
||
|
||
var result;
|
||
try {
|
||
// Retry on windows, sometimes it takes a little time before all the files in the directory are gone
|
||
var start = Date.now();
|
||
|
||
// TODO: replace this with a finite loop
|
||
for (;;) {
|
||
try {
|
||
result = fs.rmdirSync(dir);
|
||
if (fs.existsSync(dir)) throw { code: 'EAGAIN' };
|
||
break;
|
||
} catch (er) {
|
||
/* istanbul ignore next */
|
||
// In addition to error codes, also check if the directory still exists and loop again if true
|
||
if (process.platform === 'win32' && (er.code === 'ENOTEMPTY' || er.code === 'EBUSY' || er.code === 'EPERM' || er.code === 'EAGAIN')) {
|
||
if (Date.now() - start > 1000) throw er;
|
||
} else if (er.code === 'ENOENT') {
|
||
// Directory did not exist, deletion was successful
|
||
break;
|
||
} else {
|
||
throw er;
|
||
}
|
||
}
|
||
}
|
||
} catch (e) {
|
||
common.error('could not remove directory (code ' + e.code + '): ' + dir, { continue: true });
|
||
}
|
||
|
||
return result;
|
||
} // rmdirSyncRecursive
|
||
|
||
// Hack to determine if file has write permissions for current user
|
||
// Avoids having to check user, group, etc, but it's probably slow
|
||
function isWriteable(file) {
|
||
var writePermission = true;
|
||
try {
|
||
var __fd = fs.openSync(file, 'a');
|
||
fs.closeSync(__fd);
|
||
} catch (e) {
|
||
writePermission = false;
|
||
}
|
||
|
||
return writePermission;
|
||
}
|
||
|
||
function handleFile(file, options) {
|
||
if (options.force || isWriteable(file)) {
|
||
// -f was passed, or file is writable, so it can be removed
|
||
common.unlinkSync(file);
|
||
} else {
|
||
common.error('permission denied: ' + file, { continue: true });
|
||
}
|
||
}
|
||
|
||
function handleDirectory(file, options) {
|
||
if (options.recursive) {
|
||
// -r was passed, so directory can be removed
|
||
rmdirSyncRecursive(file, options.force);
|
||
} else {
|
||
common.error('path is a directory', { continue: true });
|
||
}
|
||
}
|
||
|
||
function handleSymbolicLink(file, options) {
|
||
var stats;
|
||
try {
|
||
stats = common.statFollowLinks(file);
|
||
} catch (e) {
|
||
// symlink is broken, so remove the symlink itself
|
||
common.unlinkSync(file);
|
||
return;
|
||
}
|
||
|
||
if (stats.isFile()) {
|
||
common.unlinkSync(file);
|
||
} else if (stats.isDirectory()) {
|
||
if (file[file.length - 1] === '/') {
|
||
// trailing separator, so remove the contents, not the link
|
||
if (options.recursive) {
|
||
// -r was passed, so directory can be removed
|
||
var fromSymlink = true;
|
||
rmdirSyncRecursive(file, options.force, fromSymlink);
|
||
} else {
|
||
common.error('path is a directory', { continue: true });
|
||
}
|
||
} else {
|
||
// no trailing separator, so remove the link
|
||
common.unlinkSync(file);
|
||
}
|
||
}
|
||
}
|
||
|
||
function handleFIFO(file) {
|
||
common.unlinkSync(file);
|
||
}
|
||
|
||
//@
|
||
//@ ### rm([options,] file [, file ...])
|
||
//@ ### rm([options,] file_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-f`: force
|
||
//@ + `-r, -R`: recursive
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ rm('-rf', '/tmp/*');
|
||
//@ rm('some_file.txt', 'another_file.txt');
|
||
//@ rm(['some_file.txt', 'another_file.txt']); // same as above
|
||
//@ ```
|
||
//@
|
||
//@ Removes files.
|
||
function _rm(options, files) {
|
||
if (!files) common.error('no paths given');
|
||
|
||
// Convert to array
|
||
files = [].slice.call(arguments, 1);
|
||
|
||
files.forEach(function (file) {
|
||
var lstats;
|
||
try {
|
||
var filepath = (file[file.length - 1] === '/')
|
||
? file.slice(0, -1) // remove the '/' so lstatSync can detect symlinks
|
||
: file;
|
||
lstats = common.statNoFollowLinks(filepath); // test for existence
|
||
} catch (e) {
|
||
// Path does not exist, no force flag given
|
||
if (!options.force) {
|
||
common.error('no such file or directory: ' + file, { continue: true });
|
||
}
|
||
return; // skip file
|
||
}
|
||
|
||
// If here, path exists
|
||
if (lstats.isFile()) {
|
||
handleFile(file, options);
|
||
} else if (lstats.isDirectory()) {
|
||
handleDirectory(file, options);
|
||
} else if (lstats.isSymbolicLink()) {
|
||
handleSymbolicLink(file, options);
|
||
} else if (lstats.isFIFO()) {
|
||
handleFIFO(file);
|
||
}
|
||
}); // forEach(file)
|
||
return '';
|
||
} // rm
|
||
module.exports = _rm;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/sed.js":
|
||
/*!*****************************************!*\
|
||
!*** ./node_modules/shelljs/src/sed.js ***!
|
||
\*****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('sed', _sed, {
|
||
globStart: 3, // don't glob-expand regexes
|
||
canReceivePipe: true,
|
||
cmdOptions: {
|
||
'i': 'inplace',
|
||
},
|
||
});
|
||
|
||
//@
|
||
//@ ### sed([options,] search_regex, replacement, file [, file ...])
|
||
//@ ### sed([options,] search_regex, replacement, file_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-i`: Replace contents of `file` in-place. _Note that no backups will be created!_
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ sed('-i', 'PROGRAM_VERSION', 'v0.1.3', 'source.js');
|
||
//@ sed(/.*DELETE_THIS_LINE.*\n/, '', 'source.js');
|
||
//@ ```
|
||
//@
|
||
//@ Reads an input string from `file`s, and performs a JavaScript `replace()` on the input
|
||
//@ using the given `search_regex` and `replacement` string or function. Returns the new string after replacement.
|
||
//@
|
||
//@ Note:
|
||
//@
|
||
//@ Like unix `sed`, ShellJS `sed` supports capture groups. Capture groups are specified
|
||
//@ using the `$n` syntax:
|
||
//@
|
||
//@ ```javascript
|
||
//@ sed(/(\w+)\s(\w+)/, '$2, $1', 'file.txt');
|
||
//@ ```
|
||
function _sed(options, regex, replacement, files) {
|
||
// Check if this is coming from a pipe
|
||
var pipe = common.readFromPipe();
|
||
|
||
if (typeof replacement !== 'string' && typeof replacement !== 'function') {
|
||
if (typeof replacement === 'number') {
|
||
replacement = replacement.toString(); // fallback
|
||
} else {
|
||
common.error('invalid replacement string');
|
||
}
|
||
}
|
||
|
||
// Convert all search strings to RegExp
|
||
if (typeof regex === 'string') {
|
||
regex = RegExp(regex);
|
||
}
|
||
|
||
if (!files && !pipe) {
|
||
common.error('no files given');
|
||
}
|
||
|
||
files = [].slice.call(arguments, 3);
|
||
|
||
if (pipe) {
|
||
files.unshift('-');
|
||
}
|
||
|
||
var sed = [];
|
||
files.forEach(function (file) {
|
||
if (!fs.existsSync(file) && file !== '-') {
|
||
common.error('no such file or directory: ' + file, 2, { continue: true });
|
||
return;
|
||
}
|
||
|
||
var contents = file === '-' ? pipe : fs.readFileSync(file, 'utf8');
|
||
var lines = contents.split('\n');
|
||
var result = lines.map(function (line) {
|
||
return line.replace(regex, replacement);
|
||
}).join('\n');
|
||
|
||
sed.push(result);
|
||
|
||
if (options.inplace) {
|
||
fs.writeFileSync(file, result, 'utf8');
|
||
}
|
||
});
|
||
|
||
return sed.join('\n');
|
||
}
|
||
module.exports = _sed;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/set.js":
|
||
/*!*****************************************!*\
|
||
!*** ./node_modules/shelljs/src/set.js ***!
|
||
\*****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
|
||
common.register('set', _set, {
|
||
allowGlobbing: false,
|
||
wrapOutput: false,
|
||
});
|
||
|
||
//@
|
||
//@ ### set(options)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `+/-e`: exit upon error (`config.fatal`)
|
||
//@ + `+/-v`: verbose: show all commands (`config.verbose`)
|
||
//@ + `+/-f`: disable filename expansion (globbing)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ set('-e'); // exit upon first error
|
||
//@ set('+e'); // this undoes a "set('-e')"
|
||
//@ ```
|
||
//@
|
||
//@ Sets global configuration variables.
|
||
function _set(options) {
|
||
if (!options) {
|
||
var args = [].slice.call(arguments, 0);
|
||
if (args.length < 2) common.error('must provide an argument');
|
||
options = args[1];
|
||
}
|
||
var negate = (options[0] === '+');
|
||
if (negate) {
|
||
options = '-' + options.slice(1); // parseOptions needs a '-' prefix
|
||
}
|
||
options = common.parseOptions(options, {
|
||
'e': 'fatal',
|
||
'v': 'verbose',
|
||
'f': 'noglob',
|
||
});
|
||
|
||
if (negate) {
|
||
Object.keys(options).forEach(function (key) {
|
||
options[key] = !options[key];
|
||
});
|
||
}
|
||
|
||
Object.keys(options).forEach(function (key) {
|
||
// Only change the global config if `negate` is false and the option is true
|
||
// or if `negate` is true and the option is false (aka negate !== option)
|
||
if (negate !== options[key]) {
|
||
common.config[key] = options[key];
|
||
}
|
||
});
|
||
return;
|
||
}
|
||
module.exports = _set;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/sort.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/sort.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('sort', _sort, {
|
||
canReceivePipe: true,
|
||
cmdOptions: {
|
||
'r': 'reverse',
|
||
'n': 'numerical',
|
||
},
|
||
});
|
||
|
||
// parse out the number prefix of a line
|
||
function parseNumber(str) {
|
||
var match = str.match(/^\s*(\d*)\s*(.*)$/);
|
||
return { num: Number(match[1]), value: match[2] };
|
||
}
|
||
|
||
// compare two strings case-insensitively, but examine case for strings that are
|
||
// case-insensitive equivalent
|
||
function unixCmp(a, b) {
|
||
var aLower = a.toLowerCase();
|
||
var bLower = b.toLowerCase();
|
||
return (aLower === bLower ?
|
||
-1 * a.localeCompare(b) : // unix sort treats case opposite how javascript does
|
||
aLower.localeCompare(bLower));
|
||
}
|
||
|
||
// compare two strings in the fashion that unix sort's -n option works
|
||
function numericalCmp(a, b) {
|
||
var objA = parseNumber(a);
|
||
var objB = parseNumber(b);
|
||
if (objA.hasOwnProperty('num') && objB.hasOwnProperty('num')) {
|
||
return ((objA.num !== objB.num) ?
|
||
(objA.num - objB.num) :
|
||
unixCmp(objA.value, objB.value));
|
||
} else {
|
||
return unixCmp(objA.value, objB.value);
|
||
}
|
||
}
|
||
|
||
//@
|
||
//@ ### sort([options,] file [, file ...])
|
||
//@ ### sort([options,] file_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-r`: Reverse the results
|
||
//@ + `-n`: Compare according to numerical value
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ sort('foo.txt', 'bar.txt');
|
||
//@ sort('-r', 'foo.txt');
|
||
//@ ```
|
||
//@
|
||
//@ Return the contents of the `file`s, sorted line-by-line. Sorting multiple
|
||
//@ files mixes their content (just as unix `sort` does).
|
||
function _sort(options, files) {
|
||
// Check if this is coming from a pipe
|
||
var pipe = common.readFromPipe();
|
||
|
||
if (!files && !pipe) common.error('no files given');
|
||
|
||
files = [].slice.call(arguments, 1);
|
||
|
||
if (pipe) {
|
||
files.unshift('-');
|
||
}
|
||
|
||
var lines = files.reduce(function (accum, file) {
|
||
if (file !== '-') {
|
||
if (!fs.existsSync(file)) {
|
||
common.error('no such file or directory: ' + file, { continue: true });
|
||
return accum;
|
||
} else if (common.statFollowLinks(file).isDirectory()) {
|
||
common.error('read failed: ' + file + ': Is a directory', {
|
||
continue: true,
|
||
});
|
||
return accum;
|
||
}
|
||
}
|
||
|
||
var contents = file === '-' ? pipe : fs.readFileSync(file, 'utf8');
|
||
return accum.concat(contents.trimRight().split('\n'));
|
||
}, []);
|
||
|
||
var sorted = lines.sort(options.numerical ? numericalCmp : unixCmp);
|
||
|
||
if (options.reverse) {
|
||
sorted = sorted.reverse();
|
||
}
|
||
|
||
return sorted.join('\n') + '\n';
|
||
}
|
||
|
||
module.exports = _sort;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/tail.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/tail.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('tail', _tail, {
|
||
canReceivePipe: true,
|
||
cmdOptions: {
|
||
'n': 'numLines',
|
||
},
|
||
});
|
||
|
||
//@
|
||
//@ ### tail([{'-n': \<num\>},] file [, file ...])
|
||
//@ ### tail([{'-n': \<num\>},] file_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-n <num>`: Show the last `<num>` lines of `file`s
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var str = tail({'-n': 1}, 'file*.txt');
|
||
//@ var str = tail('file1', 'file2');
|
||
//@ var str = tail(['file1', 'file2']); // same as above
|
||
//@ ```
|
||
//@
|
||
//@ Read the end of a `file`.
|
||
function _tail(options, files) {
|
||
var tail = [];
|
||
var pipe = common.readFromPipe();
|
||
|
||
if (!files && !pipe) common.error('no paths given');
|
||
|
||
var idx = 1;
|
||
if (options.numLines === true) {
|
||
idx = 2;
|
||
options.numLines = Number(arguments[1]);
|
||
} else if (options.numLines === false) {
|
||
options.numLines = 10;
|
||
}
|
||
options.numLines = -1 * Math.abs(options.numLines);
|
||
files = [].slice.call(arguments, idx);
|
||
|
||
if (pipe) {
|
||
files.unshift('-');
|
||
}
|
||
|
||
var shouldAppendNewline = false;
|
||
files.forEach(function (file) {
|
||
if (file !== '-') {
|
||
if (!fs.existsSync(file)) {
|
||
common.error('no such file or directory: ' + file, { continue: true });
|
||
return;
|
||
} else if (common.statFollowLinks(file).isDirectory()) {
|
||
common.error("error reading '" + file + "': Is a directory", {
|
||
continue: true,
|
||
});
|
||
return;
|
||
}
|
||
}
|
||
|
||
var contents = file === '-' ? pipe : fs.readFileSync(file, 'utf8');
|
||
|
||
var lines = contents.split('\n');
|
||
if (lines[lines.length - 1] === '') {
|
||
lines.pop();
|
||
shouldAppendNewline = true;
|
||
} else {
|
||
shouldAppendNewline = false;
|
||
}
|
||
|
||
tail = tail.concat(lines.slice(options.numLines));
|
||
});
|
||
|
||
if (shouldAppendNewline) {
|
||
tail.push(''); // to add a trailing newline once we join
|
||
}
|
||
return tail.join('\n');
|
||
}
|
||
module.exports = _tail;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/tempdir.js":
|
||
/*!*********************************************!*\
|
||
!*** ./node_modules/shelljs/src/tempdir.js ***!
|
||
\*********************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var os = __webpack_require__(/*! os */ "os");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('tempdir', _tempDir, {
|
||
allowGlobbing: false,
|
||
wrapOutput: false,
|
||
});
|
||
|
||
// Returns false if 'dir' is not a writeable directory, 'dir' otherwise
|
||
function writeableDir(dir) {
|
||
if (!dir || !fs.existsSync(dir)) return false;
|
||
|
||
if (!common.statFollowLinks(dir).isDirectory()) return false;
|
||
|
||
var testFile = dir + '/' + common.randomFileName();
|
||
try {
|
||
fs.writeFileSync(testFile, ' ');
|
||
common.unlinkSync(testFile);
|
||
return dir;
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// Variable to cache the tempdir value for successive lookups.
|
||
var cachedTempDir;
|
||
|
||
//@
|
||
//@ ### tempdir()
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var tmp = tempdir(); // "/tmp" for most *nix platforms
|
||
//@ ```
|
||
//@
|
||
//@ Searches and returns string containing a writeable, platform-dependent temporary directory.
|
||
//@ Follows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.html#tempfile.tempdir).
|
||
function _tempDir() {
|
||
if (cachedTempDir) return cachedTempDir;
|
||
|
||
cachedTempDir = writeableDir(os.tmpdir()) ||
|
||
writeableDir(process.env.TMPDIR) ||
|
||
writeableDir(process.env.TEMP) ||
|
||
writeableDir(process.env.TMP) ||
|
||
writeableDir(process.env.Wimp$ScrapDir) || // RiscOS
|
||
writeableDir('C:\\TEMP') || // Windows
|
||
writeableDir('C:\\TMP') || // Windows
|
||
writeableDir('\\TEMP') || // Windows
|
||
writeableDir('\\TMP') || // Windows
|
||
writeableDir('/tmp') ||
|
||
writeableDir('/var/tmp') ||
|
||
writeableDir('/usr/tmp') ||
|
||
writeableDir('.'); // last resort
|
||
|
||
return cachedTempDir;
|
||
}
|
||
|
||
// Indicates if the tempdir value is currently cached. This is exposed for tests
|
||
// only. The return value should only be tested for truthiness.
|
||
function isCached() {
|
||
return cachedTempDir;
|
||
}
|
||
|
||
// Clears the cached tempDir value, if one is cached. This is exposed for tests
|
||
// only.
|
||
function clearCache() {
|
||
cachedTempDir = undefined;
|
||
}
|
||
|
||
module.exports.tempDir = _tempDir;
|
||
module.exports.isCached = isCached;
|
||
module.exports.clearCache = clearCache;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/test.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/test.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('test', _test, {
|
||
cmdOptions: {
|
||
'b': 'block',
|
||
'c': 'character',
|
||
'd': 'directory',
|
||
'e': 'exists',
|
||
'f': 'file',
|
||
'L': 'link',
|
||
'p': 'pipe',
|
||
'S': 'socket',
|
||
},
|
||
wrapOutput: false,
|
||
allowGlobbing: false,
|
||
});
|
||
|
||
|
||
//@
|
||
//@ ### test(expression)
|
||
//@
|
||
//@ Available expression primaries:
|
||
//@
|
||
//@ + `'-b', 'path'`: true if path is a block device
|
||
//@ + `'-c', 'path'`: true if path is a character device
|
||
//@ + `'-d', 'path'`: true if path is a directory
|
||
//@ + `'-e', 'path'`: true if path exists
|
||
//@ + `'-f', 'path'`: true if path is a regular file
|
||
//@ + `'-L', 'path'`: true if path is a symbolic link
|
||
//@ + `'-p', 'path'`: true if path is a pipe (FIFO)
|
||
//@ + `'-S', 'path'`: true if path is a socket
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ if (test('-d', path)) { /* do something with dir */ };
|
||
//@ if (!test('-f', path)) continue; // skip if it's a regular file
|
||
//@ ```
|
||
//@
|
||
//@ Evaluates `expression` using the available primaries and returns corresponding value.
|
||
function _test(options, path) {
|
||
if (!path) common.error('no path given');
|
||
|
||
var canInterpret = false;
|
||
Object.keys(options).forEach(function (key) {
|
||
if (options[key] === true) {
|
||
canInterpret = true;
|
||
}
|
||
});
|
||
|
||
if (!canInterpret) common.error('could not interpret expression');
|
||
|
||
if (options.link) {
|
||
try {
|
||
return common.statNoFollowLinks(path).isSymbolicLink();
|
||
} catch (e) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
if (!fs.existsSync(path)) return false;
|
||
|
||
if (options.exists) return true;
|
||
|
||
var stats = common.statFollowLinks(path);
|
||
|
||
if (options.block) return stats.isBlockDevice();
|
||
|
||
if (options.character) return stats.isCharacterDevice();
|
||
|
||
if (options.directory) return stats.isDirectory();
|
||
|
||
if (options.file) return stats.isFile();
|
||
|
||
/* istanbul ignore next */
|
||
if (options.pipe) return stats.isFIFO();
|
||
|
||
/* istanbul ignore next */
|
||
if (options.socket) return stats.isSocket();
|
||
|
||
/* istanbul ignore next */
|
||
return false; // fallback
|
||
} // test
|
||
module.exports = _test;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/to.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/shelljs/src/to.js ***!
|
||
\****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
|
||
common.register('to', _to, {
|
||
pipeOnly: true,
|
||
wrapOutput: false,
|
||
});
|
||
|
||
//@
|
||
//@ ### ShellString.prototype.to(file)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ cat('input.txt').to('output.txt');
|
||
//@ ```
|
||
//@
|
||
//@ Analogous to the redirection operator `>` in Unix, but works with
|
||
//@ `ShellStrings` (such as those returned by `cat`, `grep`, etc.). _Like Unix
|
||
//@ redirections, `to()` will overwrite any existing file!_
|
||
function _to(options, file) {
|
||
if (!file) common.error('wrong arguments');
|
||
|
||
if (!fs.existsSync(path.dirname(file))) {
|
||
common.error('no such file or directory: ' + path.dirname(file));
|
||
}
|
||
|
||
try {
|
||
fs.writeFileSync(file, this.stdout || this.toString(), 'utf8');
|
||
return this;
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
common.error('could not write to file (code ' + e.code + '): ' + file, { continue: true });
|
||
}
|
||
}
|
||
module.exports = _to;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/toEnd.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/shelljs/src/toEnd.js ***!
|
||
\*******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
|
||
common.register('toEnd', _toEnd, {
|
||
pipeOnly: true,
|
||
wrapOutput: false,
|
||
});
|
||
|
||
//@
|
||
//@ ### ShellString.prototype.toEnd(file)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ cat('input.txt').toEnd('output.txt');
|
||
//@ ```
|
||
//@
|
||
//@ Analogous to the redirect-and-append operator `>>` in Unix, but works with
|
||
//@ `ShellStrings` (such as those returned by `cat`, `grep`, etc.).
|
||
function _toEnd(options, file) {
|
||
if (!file) common.error('wrong arguments');
|
||
|
||
if (!fs.existsSync(path.dirname(file))) {
|
||
common.error('no such file or directory: ' + path.dirname(file));
|
||
}
|
||
|
||
try {
|
||
fs.appendFileSync(file, this.stdout || this.toString(), 'utf8');
|
||
return this;
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
common.error('could not append to file (code ' + e.code + '): ' + file, { continue: true });
|
||
}
|
||
}
|
||
module.exports = _toEnd;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/touch.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/shelljs/src/touch.js ***!
|
||
\*******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('touch', _touch, {
|
||
cmdOptions: {
|
||
'a': 'atime_only',
|
||
'c': 'no_create',
|
||
'd': 'date',
|
||
'm': 'mtime_only',
|
||
'r': 'reference',
|
||
},
|
||
});
|
||
|
||
//@
|
||
//@ ### touch([options,] file [, file ...])
|
||
//@ ### touch([options,] file_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-a`: Change only the access time
|
||
//@ + `-c`: Do not create any files
|
||
//@ + `-m`: Change only the modification time
|
||
//@ + `-d DATE`: Parse `DATE` and use it instead of current time
|
||
//@ + `-r FILE`: Use `FILE`'s times instead of current time
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ touch('source.js');
|
||
//@ touch('-c', '/path/to/some/dir/source.js');
|
||
//@ touch({ '-r': FILE }, '/path/to/some/dir/source.js');
|
||
//@ ```
|
||
//@
|
||
//@ Update the access and modification times of each `FILE` to the current time.
|
||
//@ A `FILE` argument that does not exist is created empty, unless `-c` is supplied.
|
||
//@ This is a partial implementation of [`touch(1)`](http://linux.die.net/man/1/touch).
|
||
function _touch(opts, files) {
|
||
if (!files) {
|
||
common.error('no files given');
|
||
} else if (typeof files === 'string') {
|
||
files = [].slice.call(arguments, 1);
|
||
} else {
|
||
common.error('file arg should be a string file path or an Array of string file paths');
|
||
}
|
||
|
||
files.forEach(function (f) {
|
||
touchFile(opts, f);
|
||
});
|
||
return '';
|
||
}
|
||
|
||
function touchFile(opts, file) {
|
||
var stat = tryStatFile(file);
|
||
|
||
if (stat && stat.isDirectory()) {
|
||
// don't error just exit
|
||
return;
|
||
}
|
||
|
||
// if the file doesn't already exist and the user has specified --no-create then
|
||
// this script is finished
|
||
if (!stat && opts.no_create) {
|
||
return;
|
||
}
|
||
|
||
// open the file and then close it. this will create it if it doesn't exist but will
|
||
// not truncate the file
|
||
fs.closeSync(fs.openSync(file, 'a'));
|
||
|
||
//
|
||
// Set timestamps
|
||
//
|
||
|
||
// setup some defaults
|
||
var now = new Date();
|
||
var mtime = opts.date || now;
|
||
var atime = opts.date || now;
|
||
|
||
// use reference file
|
||
if (opts.reference) {
|
||
var refStat = tryStatFile(opts.reference);
|
||
if (!refStat) {
|
||
common.error('failed to get attributess of ' + opts.reference);
|
||
}
|
||
mtime = refStat.mtime;
|
||
atime = refStat.atime;
|
||
} else if (opts.date) {
|
||
mtime = opts.date;
|
||
atime = opts.date;
|
||
}
|
||
|
||
if (opts.atime_only && opts.mtime_only) {
|
||
// keep the new values of mtime and atime like GNU
|
||
} else if (opts.atime_only) {
|
||
mtime = stat.mtime;
|
||
} else if (opts.mtime_only) {
|
||
atime = stat.atime;
|
||
}
|
||
|
||
fs.utimesSync(file, atime, mtime);
|
||
}
|
||
|
||
module.exports = _touch;
|
||
|
||
function tryStatFile(filePath) {
|
||
try {
|
||
return common.statFollowLinks(filePath);
|
||
} catch (e) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/uniq.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/uniq.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
// add c spaces to the left of str
|
||
function lpad(c, str) {
|
||
var res = '' + str;
|
||
if (res.length < c) {
|
||
res = Array((c - res.length) + 1).join(' ') + res;
|
||
}
|
||
return res;
|
||
}
|
||
|
||
common.register('uniq', _uniq, {
|
||
canReceivePipe: true,
|
||
cmdOptions: {
|
||
'i': 'ignoreCase',
|
||
'c': 'count',
|
||
'd': 'duplicates',
|
||
},
|
||
});
|
||
|
||
//@
|
||
//@ ### uniq([options,] [input, [output]])
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-i`: Ignore case while comparing
|
||
//@ + `-c`: Prefix lines by the number of occurrences
|
||
//@ + `-d`: Only print duplicate lines, one for each group of identical lines
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ uniq('foo.txt');
|
||
//@ uniq('-i', 'foo.txt');
|
||
//@ uniq('-cd', 'foo.txt', 'bar.txt');
|
||
//@ ```
|
||
//@
|
||
//@ Filter adjacent matching lines from `input`.
|
||
function _uniq(options, input, output) {
|
||
// Check if this is coming from a pipe
|
||
var pipe = common.readFromPipe();
|
||
|
||
if (!pipe) {
|
||
if (!input) common.error('no input given');
|
||
|
||
if (!fs.existsSync(input)) {
|
||
common.error(input + ': No such file or directory');
|
||
} else if (common.statFollowLinks(input).isDirectory()) {
|
||
common.error("error reading '" + input + "'");
|
||
}
|
||
}
|
||
if (output && fs.existsSync(output) && common.statFollowLinks(output).isDirectory()) {
|
||
common.error(output + ': Is a directory');
|
||
}
|
||
|
||
var lines = (input ? fs.readFileSync(input, 'utf8') : pipe).
|
||
trimRight().
|
||
split('\n');
|
||
|
||
var compare = function (a, b) {
|
||
return options.ignoreCase ?
|
||
a.toLocaleLowerCase().localeCompare(b.toLocaleLowerCase()) :
|
||
a.localeCompare(b);
|
||
};
|
||
var uniqed = lines.reduceRight(function (res, e) {
|
||
// Perform uniq -c on the input
|
||
if (res.length === 0) {
|
||
return [{ count: 1, ln: e }];
|
||
} else if (compare(res[0].ln, e) === 0) {
|
||
return [{ count: res[0].count + 1, ln: e }].concat(res.slice(1));
|
||
} else {
|
||
return [{ count: 1, ln: e }].concat(res);
|
||
}
|
||
}, []).filter(function (obj) {
|
||
// Do we want only duplicated objects?
|
||
return options.duplicates ? obj.count > 1 : true;
|
||
}).map(function (obj) {
|
||
// Are we tracking the counts of each line?
|
||
return (options.count ? (lpad(7, obj.count) + ' ') : '') + obj.ln;
|
||
}).join('\n') + '\n';
|
||
|
||
if (output) {
|
||
(new common.ShellString(uniqed)).to(output);
|
||
// if uniq writes to output, nothing is passed to the next command in the pipeline (if any)
|
||
return '';
|
||
} else {
|
||
return uniqed;
|
||
}
|
||
}
|
||
|
||
module.exports = _uniq;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/which.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/shelljs/src/which.js ***!
|
||
\*******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
|
||
common.register('which', _which, {
|
||
allowGlobbing: false,
|
||
cmdOptions: {
|
||
'a': 'all',
|
||
},
|
||
});
|
||
|
||
// XP's system default value for `PATHEXT` system variable, just in case it's not
|
||
// set on Windows.
|
||
var XP_DEFAULT_PATHEXT = '.com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh';
|
||
|
||
// For earlier versions of NodeJS that doesn't have a list of constants (< v6)
|
||
var FILE_EXECUTABLE_MODE = 1;
|
||
|
||
function isWindowsPlatform() {
|
||
return process.platform === 'win32';
|
||
}
|
||
|
||
// Cross-platform method for splitting environment `PATH` variables
|
||
function splitPath(p) {
|
||
return p ? p.split(path.delimiter) : [];
|
||
}
|
||
|
||
// Tests are running all cases for this func but it stays uncovered by codecov due to unknown reason
|
||
/* istanbul ignore next */
|
||
function isExecutable(pathName) {
|
||
try {
|
||
// TODO(node-support): replace with fs.constants.X_OK once remove support for node < v6
|
||
fs.accessSync(pathName, FILE_EXECUTABLE_MODE);
|
||
} catch (err) {
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
function checkPath(pathName) {
|
||
return fs.existsSync(pathName) && !common.statFollowLinks(pathName).isDirectory()
|
||
&& (isWindowsPlatform() || isExecutable(pathName));
|
||
}
|
||
|
||
//@
|
||
//@ ### which(command)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var nodeExec = which('node');
|
||
//@ ```
|
||
//@
|
||
//@ Searches for `command` in the system's `PATH`. On Windows, this uses the
|
||
//@ `PATHEXT` variable to append the extension if it's not already executable.
|
||
//@ Returns string containing the absolute path to `command`.
|
||
function _which(options, cmd) {
|
||
if (!cmd) common.error('must specify command');
|
||
|
||
var isWindows = isWindowsPlatform();
|
||
var pathArray = splitPath(process.env.PATH);
|
||
|
||
var queryMatches = [];
|
||
|
||
// No relative/absolute paths provided?
|
||
if (cmd.indexOf('/') === -1) {
|
||
// Assume that there are no extensions to append to queries (this is the
|
||
// case for unix)
|
||
var pathExtArray = [''];
|
||
if (isWindows) {
|
||
// In case the PATHEXT variable is somehow not set (e.g.
|
||
// child_process.spawn with an empty environment), use the XP default.
|
||
var pathExtEnv = process.env.PATHEXT || XP_DEFAULT_PATHEXT;
|
||
pathExtArray = splitPath(pathExtEnv.toUpperCase());
|
||
}
|
||
|
||
// Search for command in PATH
|
||
for (var k = 0; k < pathArray.length; k++) {
|
||
// already found it
|
||
if (queryMatches.length > 0 && !options.all) break;
|
||
|
||
var attempt = path.resolve(pathArray[k], cmd);
|
||
|
||
if (isWindows) {
|
||
attempt = attempt.toUpperCase();
|
||
}
|
||
|
||
var match = attempt.match(/\.[^<>:"/\|?*.]+$/);
|
||
if (match && pathExtArray.indexOf(match[0]) >= 0) { // this is Windows-only
|
||
// The user typed a query with the file extension, like
|
||
// `which('node.exe')`
|
||
if (checkPath(attempt)) {
|
||
queryMatches.push(attempt);
|
||
break;
|
||
}
|
||
} else { // All-platforms
|
||
// Cycle through the PATHEXT array, and check each extension
|
||
// Note: the array is always [''] on Unix
|
||
for (var i = 0; i < pathExtArray.length; i++) {
|
||
var ext = pathExtArray[i];
|
||
var newAttempt = attempt + ext;
|
||
if (checkPath(newAttempt)) {
|
||
queryMatches.push(newAttempt);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} else if (checkPath(cmd)) { // a valid absolute or relative path
|
||
queryMatches.push(path.resolve(cmd));
|
||
}
|
||
|
||
if (queryMatches.length > 0) {
|
||
return options.all ? queryMatches : queryMatches[0];
|
||
}
|
||
return options.all ? [] : null;
|
||
}
|
||
module.exports = _which;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src sync recursive ^\\.\\/.*$":
|
||
/*!*************************************************!*\
|
||
!*** ./node_modules/shelljs/src/ sync ^\.\/.*$ ***!
|
||
\*************************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var map = {
|
||
"./cat": "./node_modules/shelljs/src/cat.js",
|
||
"./cat.js": "./node_modules/shelljs/src/cat.js",
|
||
"./cd": "./node_modules/shelljs/src/cd.js",
|
||
"./cd.js": "./node_modules/shelljs/src/cd.js",
|
||
"./chmod": "./node_modules/shelljs/src/chmod.js",
|
||
"./chmod.js": "./node_modules/shelljs/src/chmod.js",
|
||
"./common": "./node_modules/shelljs/src/common.js",
|
||
"./common.js": "./node_modules/shelljs/src/common.js",
|
||
"./cp": "./node_modules/shelljs/src/cp.js",
|
||
"./cp.js": "./node_modules/shelljs/src/cp.js",
|
||
"./dirs": "./node_modules/shelljs/src/dirs.js",
|
||
"./dirs.js": "./node_modules/shelljs/src/dirs.js",
|
||
"./echo": "./node_modules/shelljs/src/echo.js",
|
||
"./echo.js": "./node_modules/shelljs/src/echo.js",
|
||
"./error": "./node_modules/shelljs/src/error.js",
|
||
"./error.js": "./node_modules/shelljs/src/error.js",
|
||
"./exec": "./node_modules/shelljs/src/exec.js",
|
||
"./exec-child": "./node_modules/shelljs/src/exec-child.js",
|
||
"./exec-child.js": "./node_modules/shelljs/src/exec-child.js",
|
||
"./exec.js": "./node_modules/shelljs/src/exec.js",
|
||
"./find": "./node_modules/shelljs/src/find.js",
|
||
"./find.js": "./node_modules/shelljs/src/find.js",
|
||
"./grep": "./node_modules/shelljs/src/grep.js",
|
||
"./grep.js": "./node_modules/shelljs/src/grep.js",
|
||
"./head": "./node_modules/shelljs/src/head.js",
|
||
"./head.js": "./node_modules/shelljs/src/head.js",
|
||
"./ln": "./node_modules/shelljs/src/ln.js",
|
||
"./ln.js": "./node_modules/shelljs/src/ln.js",
|
||
"./ls": "./node_modules/shelljs/src/ls.js",
|
||
"./ls.js": "./node_modules/shelljs/src/ls.js",
|
||
"./mkdir": "./node_modules/shelljs/src/mkdir.js",
|
||
"./mkdir.js": "./node_modules/shelljs/src/mkdir.js",
|
||
"./mv": "./node_modules/shelljs/src/mv.js",
|
||
"./mv.js": "./node_modules/shelljs/src/mv.js",
|
||
"./popd": "./node_modules/shelljs/src/popd.js",
|
||
"./popd.js": "./node_modules/shelljs/src/popd.js",
|
||
"./pushd": "./node_modules/shelljs/src/pushd.js",
|
||
"./pushd.js": "./node_modules/shelljs/src/pushd.js",
|
||
"./pwd": "./node_modules/shelljs/src/pwd.js",
|
||
"./pwd.js": "./node_modules/shelljs/src/pwd.js",
|
||
"./rm": "./node_modules/shelljs/src/rm.js",
|
||
"./rm.js": "./node_modules/shelljs/src/rm.js",
|
||
"./sed": "./node_modules/shelljs/src/sed.js",
|
||
"./sed.js": "./node_modules/shelljs/src/sed.js",
|
||
"./set": "./node_modules/shelljs/src/set.js",
|
||
"./set.js": "./node_modules/shelljs/src/set.js",
|
||
"./sort": "./node_modules/shelljs/src/sort.js",
|
||
"./sort.js": "./node_modules/shelljs/src/sort.js",
|
||
"./tail": "./node_modules/shelljs/src/tail.js",
|
||
"./tail.js": "./node_modules/shelljs/src/tail.js",
|
||
"./tempdir": "./node_modules/shelljs/src/tempdir.js",
|
||
"./tempdir.js": "./node_modules/shelljs/src/tempdir.js",
|
||
"./test": "./node_modules/shelljs/src/test.js",
|
||
"./test.js": "./node_modules/shelljs/src/test.js",
|
||
"./to": "./node_modules/shelljs/src/to.js",
|
||
"./to.js": "./node_modules/shelljs/src/to.js",
|
||
"./toEnd": "./node_modules/shelljs/src/toEnd.js",
|
||
"./toEnd.js": "./node_modules/shelljs/src/toEnd.js",
|
||
"./touch": "./node_modules/shelljs/src/touch.js",
|
||
"./touch.js": "./node_modules/shelljs/src/touch.js",
|
||
"./uniq": "./node_modules/shelljs/src/uniq.js",
|
||
"./uniq.js": "./node_modules/shelljs/src/uniq.js",
|
||
"./which": "./node_modules/shelljs/src/which.js",
|
||
"./which.js": "./node_modules/shelljs/src/which.js"
|
||
};
|
||
|
||
|
||
function webpackContext(req) {
|
||
var id = webpackContextResolve(req);
|
||
return __webpack_require__(id);
|
||
}
|
||
function webpackContextResolve(req) {
|
||
if(!__webpack_require__.o(map, req)) {
|
||
var e = new Error("Cannot find module '" + req + "'");
|
||
e.code = 'MODULE_NOT_FOUND';
|
||
throw e;
|
||
}
|
||
return map[req];
|
||
}
|
||
webpackContext.keys = function webpackContextKeys() {
|
||
return Object.keys(map);
|
||
};
|
||
webpackContext.resolve = webpackContextResolve;
|
||
module.exports = webpackContext;
|
||
webpackContext.id = "./node_modules/shelljs/src sync recursive ^\\.\\/.*$";
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/agent/azure/build-agent.ts":
|
||
/*!****************************************!*\
|
||
!*** ./src/agent/azure/build-agent.ts ***!
|
||
\****************************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
if (k2 === undefined) k2 = k;
|
||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||
}) : (function(o, m, k, k2) {
|
||
if (k2 === undefined) k2 = k;
|
||
o[k2] = m[k];
|
||
}));
|
||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
}) : function(o, v) {
|
||
o["default"] = v;
|
||
});
|
||
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 __importStar = (this && this.__importStar) || function (mod) {
|
||
if (mod && mod.__esModule) return mod;
|
||
var result = {};
|
||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
__setModuleDefault(result, mod);
|
||
return result;
|
||
};
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.BuildAgent = void 0;
|
||
const inversify_1 = __webpack_require__(/*! inversify */ "./node_modules/inversify/lib/inversify.js");
|
||
const taskLib = __importStar(__webpack_require__(/*! azure-pipelines-task-lib/task */ "./node_modules/azure-pipelines-task-lib/task.js"));
|
||
const toolLib = __importStar(__webpack_require__(/*! azure-pipelines-tool-lib/tool */ "./node_modules/azure-pipelines-tool-lib/tool.js"));
|
||
let BuildAgent = class BuildAgent {
|
||
get agentName() {
|
||
return 'Azure Pipelines';
|
||
}
|
||
proxyConfiguration(url) {
|
||
return {
|
||
proxy: taskLib.getHttpProxyConfiguration(url),
|
||
cert: taskLib.getHttpCertConfiguration(),
|
||
ignoreSslError: !!taskLib.getVariable('Agent.SkipCertValidation')
|
||
};
|
||
}
|
||
find(toolName, versionSpec, arch) {
|
||
return toolLib.findLocalTool(toolName, versionSpec, arch);
|
||
}
|
||
cacheDir(sourceDir, tool, version, arch) {
|
||
return toolLib.cacheDir(sourceDir, tool, version, arch);
|
||
}
|
||
createTempDir() {
|
||
return Promise.resolve(taskLib.getVariable('Agent.TempDirectory'));
|
||
}
|
||
debug(message) {
|
||
taskLib.debug(message);
|
||
}
|
||
setFailed(message, done) {
|
||
taskLib.setResult(taskLib.TaskResult.Failed, message, done);
|
||
}
|
||
setSucceeded(message, done) {
|
||
taskLib.setResult(taskLib.TaskResult.Succeeded, message, done);
|
||
}
|
||
exportVariable(name, val) {
|
||
taskLib.setVariable(name, val);
|
||
}
|
||
getVariable(name) {
|
||
return taskLib.getVariable(name);
|
||
}
|
||
addPath(inputPath) {
|
||
toolLib.prependPath(inputPath);
|
||
}
|
||
which(tool, check) {
|
||
return Promise.resolve(taskLib.which(tool, check));
|
||
}
|
||
exec(exec, args) {
|
||
const tr = taskLib.tool(exec);
|
||
tr.arg(args);
|
||
const result = tr.execSync();
|
||
return Promise.resolve({
|
||
code: result.code,
|
||
error: result.error,
|
||
stderr: result.stderr,
|
||
stdout: result.stdout
|
||
});
|
||
}
|
||
getSourceDir() {
|
||
return this.getVariable('Build.SourcesDirectory');
|
||
}
|
||
setOutput(name, value) {
|
||
taskLib.setVariable(name, value);
|
||
}
|
||
getInput(input, required) {
|
||
var _a;
|
||
return (_a = taskLib.getInput(input, required)) === null || _a === void 0 ? void 0 : _a.trim();
|
||
}
|
||
getListInput(input, required) {
|
||
return taskLib
|
||
.getInput(input, required)
|
||
.split('\n')
|
||
.filter(x => x !== '');
|
||
}
|
||
getBooleanInput(input, required) {
|
||
return taskLib.getBoolInput(input, required);
|
||
}
|
||
isValidInputFile(input, file) {
|
||
return taskLib.filePathSupplied(input) && this.fileExists(file);
|
||
}
|
||
fileExists(file) {
|
||
return taskLib.exist(file) && taskLib.stats(file).isFile();
|
||
}
|
||
directoryExists(file) {
|
||
return taskLib.exist(file) && taskLib.stats(file).isDirectory();
|
||
}
|
||
};
|
||
BuildAgent = __decorate([
|
||
inversify_1.injectable()
|
||
], BuildAgent);
|
||
exports.BuildAgent = BuildAgent;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/core/dotnet-tool.ts":
|
||
/*!*********************************!*\
|
||
!*** ./src/core/dotnet-tool.ts ***!
|
||
\*********************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
if (k2 === undefined) k2 = k;
|
||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||
}) : (function(o, m, k, k2) {
|
||
if (k2 === undefined) k2 = k;
|
||
o[k2] = m[k];
|
||
}));
|
||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
}) : function(o, v) {
|
||
o["default"] = v;
|
||
});
|
||
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 __importStar = (this && this.__importStar) || function (mod) {
|
||
if (mod && mod.__esModule) return mod;
|
||
var result = {};
|
||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
__setModuleDefault(result, mod);
|
||
return result;
|
||
};
|
||
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 DotnetTool_1;
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.DotnetTool = void 0;
|
||
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 models_1 = __webpack_require__(/*! ./models */ "./src/core/models.ts");
|
||
let DotnetTool = DotnetTool_1 = class DotnetTool {
|
||
constructor(buildAgent, versionManager) {
|
||
this.buildAgent = buildAgent;
|
||
this.versionManager = versionManager;
|
||
this.httpClient = new http.HttpClient('dotnet', undefined, this.buildAgent.proxyConfiguration(DotnetTool_1.nugetRoot));
|
||
}
|
||
disableTelemetry() {
|
||
this.buildAgent.exportVariable('DOTNET_CLI_TELEMETRY_OPTOUT', 'true');
|
||
this.buildAgent.exportVariable('DOTNET_NOLOGO', 'true');
|
||
}
|
||
execute(cmd, args) {
|
||
console.log(`Command: ${cmd} ${args.join(' ')}`);
|
||
return this.buildAgent.exec(cmd, 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' &&
|
||
!this.buildAgent.getVariable('DOTNET_ROOT')) {
|
||
let dotnetPath = yield this.buildAgent.which('dotnet');
|
||
dotnetPath = fs.readlinkSync(dotnetPath) || dotnetPath;
|
||
const dotnetRoot = path.dirname(dotnetPath);
|
||
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 = `${DotnetTool_1.nugetRoot}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.execute('dotnet', 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.nugetRoot = 'https://api-v2v3search-0.nuget.org/';
|
||
DotnetTool = DotnetTool_1 = __decorate([
|
||
inversify_1.injectable(),
|
||
__param(0, inversify_1.inject(models_1.TYPES.IBuildAgent)),
|
||
__param(1, inversify_1.inject(models_1.TYPES.IVersionManager)),
|
||
__metadata("design:paramtypes", [Object, Object])
|
||
], DotnetTool);
|
||
exports.DotnetTool = DotnetTool;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/core/ioc.ts":
|
||
/*!*************************!*\
|
||
!*** ./src/core/ioc.ts ***!
|
||
\*************************/
|
||
/***/ ((__unused_webpack_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 models_1 = __webpack_require__(/*! ./models */ "./src/core/models.ts");
|
||
const build_agent_1 = __webpack_require__(/*! ../agent/mock/build-agent */ "./src/agent/azure/build-agent.ts");
|
||
const container = new inversify_1.Container();
|
||
container.bind(models_1.TYPES.IVersionManager).to(versionManager_1.VersionManager);
|
||
container.bind(models_1.TYPES.IBuildAgent).to(build_agent_1.BuildAgent);
|
||
exports.default = container;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/core/models.ts":
|
||
/*!****************************!*\
|
||
!*** ./src/core/models.ts ***!
|
||
\****************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.SetupFields = exports.TYPES = void 0;
|
||
exports.TYPES = {
|
||
IBuildAgent: Symbol.for('BuildAgent'),
|
||
IDotnetTool: Symbol.for('DotnetTool'),
|
||
IGitVersionTool: Symbol.for('GitVersionTool'),
|
||
IGitReleaseManagerTool: Symbol.for('GitReleaseManagerTool'),
|
||
IVersionManager: Symbol.for('VersionManager')
|
||
};
|
||
var SetupFields;
|
||
(function (SetupFields) {
|
||
SetupFields["includePrerelease"] = "includePrerelease";
|
||
SetupFields["versionSpec"] = "versionSpec";
|
||
})(SetupFields = exports.SetupFields || (exports.SetupFields = {}));
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/core/settings.ts":
|
||
/*!******************************!*\
|
||
!*** ./src/core/settings.ts ***!
|
||
\******************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Settings = void 0;
|
||
const models_1 = __webpack_require__(/*! ./models */ "./src/core/models.ts");
|
||
class Settings {
|
||
static getSetupSettings(buildAgent) {
|
||
const versionSpec = buildAgent.getInput(models_1.SetupFields.versionSpec);
|
||
const includePrerelease = buildAgent.getBooleanInput(models_1.SetupFields.includePrerelease);
|
||
return {
|
||
versionSpec,
|
||
includePrerelease
|
||
};
|
||
}
|
||
}
|
||
exports.Settings = Settings;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/core/versionManager.ts":
|
||
/*!************************************!*\
|
||
!*** ./src/core/versionManager.ts ***!
|
||
\************************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
if (k2 === undefined) k2 = k;
|
||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||
}) : (function(o, m, k, k2) {
|
||
if (k2 === undefined) k2 = k;
|
||
o[k2] = m[k];
|
||
}));
|
||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
}) : function(o, v) {
|
||
o["default"] = v;
|
||
});
|
||
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 __importStar = (this && this.__importStar) || function (mod) {
|
||
if (mod && mod.__esModule) return mod;
|
||
var result = {};
|
||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
__setModuleDefault(result, mod);
|
||
return result;
|
||
};
|
||
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 };
|
||
};
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.VersionManager = void 0;
|
||
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 models_1 = __webpack_require__(/*! ./models */ "./src/core/models.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(models_1.TYPES.IBuildAgent)),
|
||
__metadata("design:paramtypes", [Object])
|
||
], VersionManager);
|
||
exports.VersionManager = VersionManager;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/tasks/gitreleasemanager/close.ts":
|
||
/*!**********************************************!*\
|
||
!*** ./src/tasks/gitreleasemanager/close.ts ***!
|
||
\**********************************************/
|
||
/***/ ((__unused_webpack_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.close();
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/tasks/gitreleasemanager/main.ts":
|
||
/*!*********************************************!*\
|
||
!*** ./src/tasks/gitreleasemanager/main.ts ***!
|
||
\*********************************************/
|
||
/***/ (function(__unused_webpack_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 }));
|
||
exports.addAsset = exports.publish = exports.open = exports.close = exports.discard = exports.create = exports.setup = void 0;
|
||
const models_1 = __webpack_require__(/*! ../../core/models */ "./src/core/models.ts");
|
||
const tool_1 = __webpack_require__(/*! ../../tools/gitreleasemanager/tool */ "./src/tools/gitreleasemanager/tool.ts");
|
||
const settings_1 = __webpack_require__(/*! ../../core/settings */ "./src/core/settings.ts");
|
||
const settings_2 = __webpack_require__(/*! ../../tools/gitreleasemanager/settings */ "./src/tools/gitreleasemanager/settings.ts");
|
||
const ioc_1 = __importDefault(__webpack_require__(/*! ../../core/ioc */ "./src/core/ioc.ts"));
|
||
ioc_1.default
|
||
.bind(models_1.TYPES.IGitReleaseManagerTool)
|
||
.to(tool_1.GitReleaseManagerTool);
|
||
const gitReleaseManagerTool = ioc_1.default.get(models_1.TYPES.IGitReleaseManagerTool);
|
||
const buildAgent = ioc_1.default.get(models_1.TYPES.IBuildAgent);
|
||
function setup() {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
try {
|
||
gitReleaseManagerTool.disableTelemetry();
|
||
const settings = settings_1.Settings.getSetupSettings(buildAgent);
|
||
yield gitReleaseManagerTool.install(settings.versionSpec, settings.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 {
|
||
gitReleaseManagerTool.disableTelemetry();
|
||
const settings = settings_2.Settings.getCreateSettings(buildAgent);
|
||
yield gitReleaseManagerTool.create(settings);
|
||
buildAgent.setSucceeded('GitVersionManager created release successfully', true);
|
||
}
|
||
catch (error) {
|
||
buildAgent.setFailed(error.message, true);
|
||
}
|
||
});
|
||
}
|
||
exports.create = create;
|
||
function discard() {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
try {
|
||
gitReleaseManagerTool.disableTelemetry();
|
||
const settings = settings_2.Settings.getDiscardSettings(buildAgent);
|
||
yield gitReleaseManagerTool.discard(settings);
|
||
buildAgent.setSucceeded('GitVersionManager discarded release successfully', true);
|
||
}
|
||
catch (error) {
|
||
buildAgent.setFailed(error.message, true);
|
||
}
|
||
});
|
||
}
|
||
exports.discard = discard;
|
||
function close() {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
try {
|
||
gitReleaseManagerTool.disableTelemetry();
|
||
const settings = settings_2.Settings.getCloseSettings(buildAgent);
|
||
yield gitReleaseManagerTool.close(settings);
|
||
buildAgent.setSucceeded('GitVersionManager closed release successfully', true);
|
||
}
|
||
catch (error) {
|
||
buildAgent.setFailed(error.message, true);
|
||
}
|
||
});
|
||
}
|
||
exports.close = close;
|
||
function open() {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
try {
|
||
gitReleaseManagerTool.disableTelemetry();
|
||
const settings = settings_2.Settings.getOpenSettings(buildAgent);
|
||
yield gitReleaseManagerTool.open(settings);
|
||
buildAgent.setSucceeded('GitVersionManager opened release successfully', true);
|
||
}
|
||
catch (error) {
|
||
buildAgent.setFailed(error.message, true);
|
||
}
|
||
});
|
||
}
|
||
exports.open = open;
|
||
function publish() {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
try {
|
||
gitReleaseManagerTool.disableTelemetry();
|
||
const settings = settings_2.Settings.getPublishSettings(buildAgent);
|
||
yield gitReleaseManagerTool.publish(settings);
|
||
buildAgent.setSucceeded('GitVersionManager published release successfully', true);
|
||
}
|
||
catch (error) {
|
||
buildAgent.setFailed(error.message, true);
|
||
}
|
||
});
|
||
}
|
||
exports.publish = publish;
|
||
function addAsset() {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
try {
|
||
gitReleaseManagerTool.disableTelemetry();
|
||
const settings = settings_2.Settings.getAddAssetSettings(buildAgent);
|
||
yield gitReleaseManagerTool.addAsset(settings);
|
||
buildAgent.setSucceeded('GitVersionManager added assets to release successfully', true);
|
||
}
|
||
catch (error) {
|
||
buildAgent.setFailed(error.message, true);
|
||
}
|
||
});
|
||
}
|
||
exports.addAsset = addAsset;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/tools/gitreleasemanager/models.ts":
|
||
/*!***********************************************!*\
|
||
!*** ./src/tools/gitreleasemanager/models.ts ***!
|
||
\***********************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.AddAssetFields = exports.PublishFields = exports.OpenFields = exports.CloseFields = exports.DiscardFields = exports.CreateFields = exports.CommonFields = void 0;
|
||
var CommonFields;
|
||
(function (CommonFields) {
|
||
CommonFields["repository"] = "repository";
|
||
CommonFields["owner"] = "owner";
|
||
CommonFields["token"] = "token";
|
||
CommonFields["targetDirectory"] = "targetDirectory";
|
||
})(CommonFields = exports.CommonFields || (exports.CommonFields = {}));
|
||
var CreateFields;
|
||
(function (CreateFields) {
|
||
CreateFields["milestone"] = "milestone";
|
||
CreateFields["name"] = "name";
|
||
CreateFields["inputFileName"] = "inputFileName";
|
||
CreateFields["isPreRelease"] = "isPreRelease";
|
||
CreateFields["commit"] = "commit";
|
||
CreateFields["assets"] = "assets";
|
||
})(CreateFields = exports.CreateFields || (exports.CreateFields = {}));
|
||
var DiscardFields;
|
||
(function (DiscardFields) {
|
||
DiscardFields["milestone"] = "milestone";
|
||
})(DiscardFields = exports.DiscardFields || (exports.DiscardFields = {}));
|
||
var CloseFields;
|
||
(function (CloseFields) {
|
||
CloseFields["milestone"] = "milestone";
|
||
})(CloseFields = exports.CloseFields || (exports.CloseFields = {}));
|
||
var OpenFields;
|
||
(function (OpenFields) {
|
||
OpenFields["milestone"] = "milestone";
|
||
})(OpenFields = exports.OpenFields || (exports.OpenFields = {}));
|
||
var PublishFields;
|
||
(function (PublishFields) {
|
||
PublishFields["tagName"] = "tagName";
|
||
})(PublishFields = exports.PublishFields || (exports.PublishFields = {}));
|
||
var AddAssetFields;
|
||
(function (AddAssetFields) {
|
||
AddAssetFields["tagName"] = "tagName";
|
||
AddAssetFields["assets"] = "assets";
|
||
})(AddAssetFields = exports.AddAssetFields || (exports.AddAssetFields = {}));
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/tools/gitreleasemanager/settings.ts":
|
||
/*!*************************************************!*\
|
||
!*** ./src/tools/gitreleasemanager/settings.ts ***!
|
||
\*************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Settings = void 0;
|
||
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 name = buildAgent.getInput(models_1.CreateFields.name);
|
||
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 assets = buildAgent.getListInput(models_1.CreateFields.assets);
|
||
const commonSettings = Settings.getCommonSettings(buildAgent);
|
||
return Object.assign(Object.assign({}, commonSettings), { milestone,
|
||
name,
|
||
inputFileName,
|
||
isPreRelease,
|
||
commit,
|
||
assets });
|
||
}
|
||
static getDiscardSettings(buildAgent) {
|
||
const milestone = buildAgent.getInput(models_1.DiscardFields.milestone);
|
||
const commonSettings = Settings.getCommonSettings(buildAgent);
|
||
return Object.assign(Object.assign({}, commonSettings), { milestone });
|
||
}
|
||
static getCloseSettings(buildAgent) {
|
||
const milestone = buildAgent.getInput(models_1.CloseFields.milestone);
|
||
const commonSettings = Settings.getCommonSettings(buildAgent);
|
||
return Object.assign(Object.assign({}, commonSettings), { milestone });
|
||
}
|
||
static getOpenSettings(buildAgent) {
|
||
const milestone = buildAgent.getInput(models_1.OpenFields.milestone);
|
||
const commonSettings = Settings.getCommonSettings(buildAgent);
|
||
return Object.assign(Object.assign({}, commonSettings), { milestone });
|
||
}
|
||
static getPublishSettings(buildAgent) {
|
||
const tagName = buildAgent.getInput(models_1.PublishFields.tagName);
|
||
const commonSettings = Settings.getCommonSettings(buildAgent);
|
||
return Object.assign(Object.assign({}, commonSettings), { tagName });
|
||
}
|
||
static getAddAssetSettings(buildAgent) {
|
||
const tagName = buildAgent.getInput(models_1.AddAssetFields.tagName);
|
||
const assets = buildAgent.getListInput(models_1.AddAssetFields.assets);
|
||
const commonSettings = Settings.getCommonSettings(buildAgent);
|
||
return Object.assign(Object.assign({}, commonSettings), { tagName,
|
||
assets });
|
||
}
|
||
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);
|
||
const targetDirectory = buildAgent.getInput(models_1.CommonFields.targetDirectory);
|
||
return {
|
||
owner,
|
||
repository,
|
||
token,
|
||
targetDirectory
|
||
};
|
||
}
|
||
}
|
||
exports.Settings = Settings;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/tools/gitreleasemanager/tool.ts":
|
||
/*!*********************************************!*\
|
||
!*** ./src/tools/gitreleasemanager/tool.ts ***!
|
||
\*********************************************/
|
||
/***/ (function(__unused_webpack_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 }));
|
||
exports.GitReleaseManagerTool = void 0;
|
||
const path = __webpack_require__(/*! path */ "path");
|
||
const models_1 = __webpack_require__(/*! ../../core/models */ "./src/core/models.ts");
|
||
const inversify_1 = __webpack_require__(/*! inversify */ "./node_modules/inversify/lib/inversify.js");
|
||
const dotnet_tool_1 = __webpack_require__(/*! ../../core/dotnet-tool */ "./src/core/dotnet-tool.ts");
|
||
let GitReleaseManagerTool = class GitReleaseManagerTool extends dotnet_tool_1.DotnetTool {
|
||
constructor(buildAgent, versionManager) {
|
||
super(buildAgent, versionManager);
|
||
}
|
||
install(versionSpec, includePrerelease) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
yield this.toolInstall('GitReleaseManager.Tool', versionSpec, false, includePrerelease);
|
||
});
|
||
}
|
||
create(settings) {
|
||
const args = this.getCreateArguments(settings);
|
||
return this.execute('dotnet-gitreleasemanager', args);
|
||
}
|
||
discard(settings) {
|
||
const args = this.getDiscardArguments(settings);
|
||
return this.execute('dotnet-gitreleasemanager', args);
|
||
}
|
||
close(settings) {
|
||
const args = this.getCloseArguments(settings);
|
||
return this.execute('dotnet-gitreleasemanager', args);
|
||
}
|
||
open(settings) {
|
||
const args = this.getOpenArguments(settings);
|
||
return this.execute('dotnet-gitreleasemanager', args);
|
||
}
|
||
publish(settings) {
|
||
const args = this.getPublishArguments(settings);
|
||
return this.execute('dotnet-gitreleasemanager', args);
|
||
}
|
||
addAsset(settings) {
|
||
const args = this.getAddAssetArguments(settings);
|
||
return this.execute('dotnet-gitreleasemanager', args);
|
||
}
|
||
getCommonArguments(settings) {
|
||
const args = [];
|
||
args.push('--owner', settings.owner);
|
||
args.push('--repository', settings.repository);
|
||
args.push('--token', settings.token);
|
||
settings.targetDirectory = this.getRepoDir(settings.targetDirectory);
|
||
args.push('--targetDirectory', settings.targetDirectory);
|
||
return args;
|
||
}
|
||
getCreateArguments(settings) {
|
||
const args = ['create', ...this.getCommonArguments(settings)];
|
||
if (settings.milestone) {
|
||
args.push('--milestone', settings.milestone);
|
||
}
|
||
if (settings.name) {
|
||
args.push('--name', settings.name);
|
||
}
|
||
if (settings.commit) {
|
||
args.push('--targetcommitish', settings.commit);
|
||
}
|
||
if (settings.inputFileName) {
|
||
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');
|
||
}
|
||
if (settings.assets && settings.assets.length > 0) {
|
||
settings.assets = settings.assets.map(asset => {
|
||
return path.join(settings.targetDirectory, asset);
|
||
});
|
||
args.push('--assets', settings.assets.join(','));
|
||
}
|
||
return args;
|
||
}
|
||
getDiscardArguments(settings) {
|
||
const args = ['discard', ...this.getCommonArguments(settings)];
|
||
if (settings.milestone) {
|
||
args.push('--milestone', settings.milestone);
|
||
}
|
||
return args;
|
||
}
|
||
getCloseArguments(settings) {
|
||
const args = ['close', ...this.getCommonArguments(settings)];
|
||
if (settings.milestone) {
|
||
args.push('--milestone', settings.milestone);
|
||
}
|
||
return args;
|
||
}
|
||
getOpenArguments(settings) {
|
||
const args = ['open', ...this.getCommonArguments(settings)];
|
||
if (settings.milestone) {
|
||
args.push('--milestone', settings.milestone);
|
||
}
|
||
return args;
|
||
}
|
||
getPublishArguments(settings) {
|
||
const args = ['publish', ...this.getCommonArguments(settings)];
|
||
if (settings.tagName) {
|
||
args.push('--tagName', settings.tagName);
|
||
}
|
||
return args;
|
||
}
|
||
getAddAssetArguments(settings) {
|
||
const args = [
|
||
'addasset',
|
||
...this.getCommonArguments(settings)
|
||
];
|
||
if (settings.tagName) {
|
||
args.push('--tagName', settings.tagName);
|
||
}
|
||
if (settings.assets && settings.assets.length > 0) {
|
||
settings.assets = settings.assets.map(asset => {
|
||
return path.join(settings.targetDirectory, asset);
|
||
});
|
||
args.push('--assets', settings.assets.join(','));
|
||
}
|
||
return args;
|
||
}
|
||
getRepoDir(targetPath) {
|
||
let workDir;
|
||
const srcDir = this.buildAgent.getSourceDir();
|
||
if (!targetPath) {
|
||
workDir = srcDir;
|
||
}
|
||
else {
|
||
if (this.buildAgent.directoryExists(targetPath)) {
|
||
workDir = path.join(srcDir, targetPath);
|
||
}
|
||
else {
|
||
throw new Error('Directory not found at ' + targetPath);
|
||
}
|
||
}
|
||
return workDir.replace(/\\/g, '/');
|
||
}
|
||
};
|
||
GitReleaseManagerTool = __decorate([
|
||
inversify_1.injectable(),
|
||
__param(0, inversify_1.inject(models_1.TYPES.IBuildAgent)),
|
||
__param(1, inversify_1.inject(models_1.TYPES.IVersionManager)),
|
||
__metadata("design:paramtypes", [Object, Object])
|
||
], GitReleaseManagerTool);
|
||
exports.GitReleaseManagerTool = GitReleaseManagerTool;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/typed-rest-client/HttpClient.js":
|
||
/*!******************************************************!*\
|
||
!*** ./node_modules/typed-rest-client/HttpClient.js ***!
|
||
\******************************************************/
|
||
/***/ (function(__unused_webpack_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 NetworkRetryErrors = ['ECONNRESET', 'ENOTFOUND', 'ESOCKETTIMEDOUT', 'ETIMEDOUT', 'ECONNREFUSED'];
|
||
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);
|
||
}
|
||
else {
|
||
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(util.buildProxyBypassRegexFromEnv(bypass));
|
||
});
|
||
}
|
||
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) {
|
||
try {
|
||
response = yield this.requestRaw(info, data);
|
||
}
|
||
catch (err) {
|
||
numTries++;
|
||
if (err && err.code && NetworkRetryErrors.indexOf(err.code) > -1 && numTries < maxTries) {
|
||
yield this._performExponentialBackoff(numTries);
|
||
continue;
|
||
}
|
||
throw err;
|
||
}
|
||
// 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;
|
||
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.destroy();
|
||
}
|
||
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.timeout = (this.requestOptions && this.requestOptions.socketTimeout) || this._socketTimeout;
|
||
this._socketTimeout = info.options.timeout;
|
||
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/typed-rest-client/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 ***!
|
||
\************************************************/
|
||
/***/ (function(__unused_webpack_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<string>}
|
||
*/
|
||
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;
|
||
/**
|
||
* Builds a RegExp to test urls against for deciding
|
||
* wether to bypass proxy from an entry of the
|
||
* environment variable setting NO_PROXY
|
||
*
|
||
* @param {string} bypass
|
||
* @return {RegExp}
|
||
*/
|
||
function buildProxyBypassRegexFromEnv(bypass) {
|
||
try {
|
||
// We need to keep this around for back-compat purposes
|
||
return new RegExp(bypass, 'i');
|
||
}
|
||
catch (err) {
|
||
if (err instanceof SyntaxError && (bypass || "").startsWith("*")) {
|
||
let wildcardEscaped = bypass.replace('*', '(.*)');
|
||
return new RegExp(wildcardEscaped, 'i');
|
||
}
|
||
throw err;
|
||
}
|
||
}
|
||
exports.buildProxyBypassRegexFromEnv = buildProxyBypassRegexFromEnv;
|
||
/**
|
||
* 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 nodeSupportedEncodings = ['ascii', 'utf8', 'utf16le', 'ucs2', 'base64', 'binary', 'hex'];
|
||
const contentType = response.message.headers['content-type'] || '';
|
||
const matches = contentType.match(/charset=([^;,\r\n]+)/i);
|
||
return (matches && matches[1] && nodeSupportedEncodings.indexOf(matches[1]) != -1) ? matches[1] : 'utf-8';
|
||
}
|
||
exports.obtainContentCharset = obtainContentCharset;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/typed-rest-client/node_modules/tunnel/index.js":
|
||
/*!*********************************************************************!*\
|
||
!*** ./node_modules/typed-rest-client/node_modules/tunnel/index.js ***!
|
||
\*********************************************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
module.exports = __webpack_require__(/*! ./lib/tunnel */ "./node_modules/typed-rest-client/node_modules/tunnel/lib/tunnel.js");
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/typed-rest-client/node_modules/tunnel/lib/tunnel.js":
|
||
/*!**************************************************************************!*\
|
||
!*** ./node_modules/typed-rest-client/node_modules/tunnel/lib/tunnel.js ***!
|
||
\**************************************************************************/
|
||
/***/ ((__unused_webpack_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/wrappy/wrappy.js":
|
||
/*!***************************************!*\
|
||
!*** ./node_modules/wrappy/wrappy.js ***!
|
||
\***************************************/
|
||
/***/ ((module) => {
|
||
|
||
// Returns a wrapper function that returns a wrapped callback
|
||
// The wrapper function should do some stuff, and return a
|
||
// presumably different callback function.
|
||
// This makes sure that own properties are retained, so that
|
||
// decorations and such are not lost along the way.
|
||
module.exports = wrappy
|
||
function wrappy (fn, cb) {
|
||
if (fn && cb) return wrappy(fn)(cb)
|
||
|
||
if (typeof fn !== 'function')
|
||
throw new TypeError('need wrapper function')
|
||
|
||
Object.keys(fn).forEach(function (k) {
|
||
wrapper[k] = fn[k]
|
||
})
|
||
|
||
return wrapper
|
||
|
||
function wrapper() {
|
||
var args = new Array(arguments.length)
|
||
for (var i = 0; i < args.length; i++) {
|
||
args[i] = arguments[i]
|
||
}
|
||
var ret = fn.apply(this, args)
|
||
var cb = args[args.length-1]
|
||
if (typeof ret === 'function' && ret !== cb) {
|
||
Object.keys(cb).forEach(function (k) {
|
||
ret[k] = cb[k]
|
||
})
|
||
}
|
||
return ret
|
||
}
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "assert":
|
||
/*!*************************!*\
|
||
!*** external "assert" ***!
|
||
\*************************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("assert");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "child_process":
|
||
/*!********************************!*\
|
||
!*** external "child_process" ***!
|
||
\********************************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("child_process");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "crypto":
|
||
/*!*************************!*\
|
||
!*** external "crypto" ***!
|
||
\*************************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("crypto");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "events":
|
||
/*!*************************!*\
|
||
!*** external "events" ***!
|
||
\*************************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("events");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "fs":
|
||
/*!*********************!*\
|
||
!*** external "fs" ***!
|
||
\*********************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("fs");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "http":
|
||
/*!***********************!*\
|
||
!*** external "http" ***!
|
||
\***********************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("http");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "https":
|
||
/*!************************!*\
|
||
!*** external "https" ***!
|
||
\************************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("https");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "net":
|
||
/*!**********************!*\
|
||
!*** external "net" ***!
|
||
\**********************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("net");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "os":
|
||
/*!*********************!*\
|
||
!*** external "os" ***!
|
||
\*********************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("os");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "path":
|
||
/*!***********************!*\
|
||
!*** external "path" ***!
|
||
\***********************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("path");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "process":
|
||
/*!**************************!*\
|
||
!*** external "process" ***!
|
||
\**************************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("process");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "tls":
|
||
/*!**********************!*\
|
||
!*** external "tls" ***!
|
||
\**********************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("tls");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "url":
|
||
/*!**********************!*\
|
||
!*** external "url" ***!
|
||
\**********************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("url");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "util":
|
||
/*!***********************!*\
|
||
!*** external "util" ***!
|
||
\***********************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("util");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "zlib":
|
||
/*!***********************!*\
|
||
!*** external "zlib" ***!
|
||
\***********************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("zlib");
|
||
|
||
/***/ })
|
||
|
||
/******/ });
|
||
/************************************************************************/
|
||
/******/ // The module cache
|
||
/******/ var __webpack_module_cache__ = {};
|
||
/******/
|
||
/******/ // The require function
|
||
/******/ function __webpack_require__(moduleId) {
|
||
/******/ // Check if module is in cache
|
||
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
||
/******/ if (cachedModule !== undefined) {
|
||
/******/ return cachedModule.exports;
|
||
/******/ }
|
||
/******/ // Create a new module (and put it into the cache)
|
||
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||
/******/ id: moduleId,
|
||
/******/ loaded: false,
|
||
/******/ exports: {}
|
||
/******/ };
|
||
/******/
|
||
/******/ // Execute the module function
|
||
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||
/******/
|
||
/******/ // Flag the module as loaded
|
||
/******/ module.loaded = true;
|
||
/******/
|
||
/******/ // Return the exports of the module
|
||
/******/ return module.exports;
|
||
/******/ }
|
||
/******/
|
||
/******/ // expose the module cache
|
||
/******/ __webpack_require__.c = __webpack_module_cache__;
|
||
/******/
|
||
/************************************************************************/
|
||
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
||
/******/ (() => {
|
||
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
||
/******/ })();
|
||
/******/
|
||
/******/ /* webpack/runtime/node module decorator */
|
||
/******/ (() => {
|
||
/******/ __webpack_require__.nmd = (module) => {
|
||
/******/ module.paths = [];
|
||
/******/ if (!module.children) module.children = [];
|
||
/******/ return module;
|
||
/******/ };
|
||
/******/ })();
|
||
/******/
|
||
/************************************************************************/
|
||
/******/
|
||
/******/ // module cache are used so entry inlining is disabled
|
||
/******/ // startup
|
||
/******/ // Load entry module and return exports
|
||
/******/ var __webpack_exports__ = __webpack_require__(__webpack_require__.s = "./src/tasks/gitreleasemanager/close.ts");
|
||
/******/ module.exports = __webpack_exports__;
|
||
/******/
|
||
/******/ })()
|
||
;
|
||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10YXNrLWxpYi9pbnRlcm5hbC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10YXNrLWxpYi9ub2RlX21vZHVsZXMvdXVpZC9saWIvYnl0ZXNUb1V1aWQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9henVyZS1waXBlbGluZXMtdGFzay1saWIvbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10YXNrLWxpYi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10YXNrLWxpYi90YXNrLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvYXp1cmUtcGlwZWxpbmVzLXRhc2stbGliL3Rhc2tjb21tYW5kLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvYXp1cmUtcGlwZWxpbmVzLXRhc2stbGliL3Rvb2xydW5uZXIuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9henVyZS1waXBlbGluZXMtdGFzay1saWIvdmF1bHQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9henVyZS1waXBlbGluZXMtdGFzay1saWJ8c3luYyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10b29sLWxpYi9ub2RlX21vZHVsZXMvdXVpZC9saWIvYnl0ZXNUb1V1aWQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9henVyZS1waXBlbGluZXMtdG9vbC1saWIvbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10b29sLWxpYi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10b29sLWxpYi90b29sLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvYXp1cmUtcGlwZWxpbmVzLXRvb2wtbGlifHN5bmMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9iYWxhbmNlZC1tYXRjaC9pbmRleC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2JyYWNlLWV4cGFuc2lvbi9pbmRleC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2NvbmNhdC1tYXAvaW5kZXguanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9mcy5yZWFscGF0aC9pbmRleC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ZzLnJlYWxwYXRoL29sZC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2dsb2IvY29tbW9uLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvZ2xvYi9nbG9iLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvZ2xvYi9zeW5jLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW5mbGlnaHQvaW5mbGlnaHQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0cy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2Fubm90YXRpb24vZGVjb3JhdG9yX3V0aWxzLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9hbm5vdGF0aW9uL2luamVjdC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvYW5ub3RhdGlvbi9pbmplY3RhYmxlLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9hbm5vdGF0aW9uL211bHRpX2luamVjdC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvYW5ub3RhdGlvbi9uYW1lZC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvYW5ub3RhdGlvbi9vcHRpb25hbC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvYW5ub3RhdGlvbi9wb3N0X2NvbnN0cnVjdC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvYW5ub3RhdGlvbi90YWdnZWQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2Fubm90YXRpb24vdGFyZ2V0X25hbWUuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2Fubm90YXRpb24vdW5tYW5hZ2VkLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9iaW5kaW5ncy9iaW5kaW5nLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9iaW5kaW5ncy9iaW5kaW5nX2NvdW50LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9jb25zdGFudHMvZXJyb3JfbXNncy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvY29uc3RhbnRzL2xpdGVyYWxfdHlwZXMuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9jb250YWluZXIvY29udGFpbmVyLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9jb250YWluZXIvY29udGFpbmVyX21vZHVsZS5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvY29udGFpbmVyL2NvbnRhaW5lcl9zbmFwc2hvdC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvY29udGFpbmVyL2xvb2t1cC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvaW52ZXJzaWZ5LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9jb250ZXh0LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9tZXRhZGF0YS5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvcGxhbm5pbmcvbWV0YWRhdGFfcmVhZGVyLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9wbGFuLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9wbGFubmVyLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9xdWVyeWFibGVfc3RyaW5nLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9yZWZsZWN0aW9uX3V0aWxzLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9yZXF1ZXN0LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy90YXJnZXQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL3Jlc29sdXRpb24vaW5zdGFudGlhdGlvbi5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvcmVzb2x1dGlvbi9yZXNvbHZlci5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvc3ludGF4L2JpbmRpbmdfaW5fc3ludGF4LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9zeW50YXgvYmluZGluZ19pbl93aGVuX29uX3N5bnRheC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvc3ludGF4L2JpbmRpbmdfb25fc3ludGF4LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9zeW50YXgvYmluZGluZ190b19zeW50YXguanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL3N5bnRheC9iaW5kaW5nX3doZW5fb25fc3ludGF4LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9zeW50YXgvYmluZGluZ193aGVuX3N5bnRheC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvc3ludGF4L2NvbnN0cmFpbnRfaGVscGVycy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvdXRpbHMvYmluZGluZ191dGlscy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvdXRpbHMvZXhjZXB0aW9ucy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvdXRpbHMvaWQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL3V0aWxzL3NlcmlhbGl6YXRpb24uanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9taW5pbWF0Y2gvbWluaW1hdGNoLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvb25jZS9vbmNlLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvcGF0aC1pcy1hYnNvbHV0ZS9pbmRleC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3EvcS5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3FzL2xpYi9mb3JtYXRzLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvcXMvbGliL2luZGV4LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvcXMvbGliL3BhcnNlLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvcXMvbGliL3N0cmluZ2lmeS5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3FzL2xpYi91dGlscy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3JlZmxlY3QtbWV0YWRhdGEvUmVmbGVjdC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NlbXZlci1jb21wYXJlL2luZGV4LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2VtdmVyL3NlbXZlci5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvY29tbWFuZHMuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NoZWxsLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvY2F0LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvY2QuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9jaG1vZC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2NvbW1vbi5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2NwLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvZGlycy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2VjaG8uanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9lcnJvci5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2V4ZWMtY2hpbGQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9leGVjLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvZmluZC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2dyZXAuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9oZWFkLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvbG4uanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9scy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL21rZGlyLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvbXYuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9wb3BkLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvcHVzaGQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9wd2QuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9ybS5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3NlZC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3NldC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3NvcnQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy90YWlsLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvdGVtcGRpci5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3Rlc3QuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy90by5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3RvRW5kLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvdG91Y2guanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy91bmlxLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvd2hpY2guanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyY3xzeW5jfC9eLy4qJCIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vc3JjL2FnZW50L2F6dXJlL2J1aWxkLWFnZW50LnRzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9zcmMvY29yZS9kb3RuZXQtdG9vbC50cyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vc3JjL2NvcmUvaW9jLnRzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9zcmMvY29yZS9tb2RlbHMudHMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL3NyYy9jb3JlL3NldHRpbmdzLnRzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9zcmMvY29yZS92ZXJzaW9uTWFuYWdlci50cyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vc3JjL3Rhc2tzL2dpdHJlbGVhc2VtYW5hZ2VyL2Nsb3NlLnRzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9zcmMvdGFza3MvZ2l0cmVsZWFzZW1hbmFnZXIvbWFpbi50cyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vc3JjL3Rvb2xzL2dpdHJlbGVhc2VtYW5hZ2VyL21vZGVscy50cyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vc3JjL3Rvb2xzL2dpdHJlbGVhc2VtYW5hZ2VyL3NldHRpbmdzLnRzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9zcmMvdG9vbHMvZ2l0cmVsZWFzZW1hbmFnZXIvdG9vbC50cyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3R5cGVkLXJlc3QtY2xpZW50L0h0dHBDbGllbnQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy90eXBlZC1yZXN0LWNsaWVudC9VdGlsLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvdHlwZWQtcmVzdC1jbGllbnQvbm9kZV9tb2R1bGVzL3R1bm5lbC9pbmRleC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3R5cGVkLXJlc3QtY2xpZW50L25vZGVfbW9kdWxlcy90dW5uZWwvbGliL3R1bm5lbC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3dyYXBweS93cmFwcHkuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy9leHRlcm5hbCBcImFzc2VydFwiIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvZXh0ZXJuYWwgXCJjaGlsZF9wcm9jZXNzXCIiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy9leHRlcm5hbCBcImNyeXB0b1wiIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvZXh0ZXJuYWwgXCJldmVudHNcIiIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zL2V4dGVybmFsIFwiZnNcIiIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zL2V4dGVybmFsIFwiaHR0cFwiIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvZXh0ZXJuYWwgXCJodHRwc1wiIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvZXh0ZXJuYWwgXCJuZXRcIiIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zL2V4dGVybmFsIFwib3NcIiIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zL2V4dGVybmFsIFwicGF0aFwiIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvZXh0ZXJuYWwgXCJwcm9jZXNzXCIiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy9leHRlcm5hbCBcInRsc1wiIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvZXh0ZXJuYWwgXCJ1cmxcIiIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zL2V4dGVybmFsIFwidXRpbFwiIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvZXh0ZXJuYWwgXCJ6bGliXCIiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zL3dlYnBhY2svcnVudGltZS9oYXNPd25Qcm9wZXJ0eSBzaG9ydGhhbmQiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy93ZWJwYWNrL3J1bnRpbWUvbm9kZSBtb2R1bGUgZGVjb3JhdG9yIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvd2VicGFjay9zdGFydHVwIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBYTtBQUNiLDhDQUE2QyxDQUFDLGNBQWMsRUFBQztBQUM3RCwyQkFBMkIsR0FBRyw0QkFBNEIsR0FBRyw0QkFBNEIsR0FBRyxpQkFBaUIsR0FBRyx5QkFBeUIsR0FBRyxxQkFBcUIsR0FBRyxpQkFBaUIsR0FBRyw0QkFBNEIsR0FBRywrQkFBK0IsR0FBRywwQkFBMEIsR0FBRywrQ0FBK0MsR0FBRyxjQUFjLEdBQUcsa0JBQWtCLEdBQUcsY0FBYyxHQUFHLGNBQWMsR0FBRyxjQUFjLEdBQUcsZ0JBQWdCLEdBQUcsZ0JBQWdCLEdBQUcsdUJBQXVCLEdBQUcsb0JBQW9CLEdBQUcsWUFBWSxHQUFHLHdCQUF3QixHQUFHLHFCQUFxQixHQUFHLHFCQUFxQixHQUFHLGtCQUFrQixHQUFHLGlCQUFpQixHQUFHLG1CQUFtQixH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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtFQUErRSxnQkFBZ0I7QUFDL0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRFQUE0RSxnQkFBZ0I7QUFDNUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxREFBcUQsMkJBQTJCO0FBQ2hGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkRBQTZELDZDQUE2QyxFQUFFO0FBQzVHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtDQUErQywwQkFBMEI7QUFDekU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLHNCQUFzQjtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOENBQThDO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEVBQTRFLHVDQUF1QyxFQUFFO0FBQ3JIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixPQUFPO0FBQ3hCLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0Isc0JBQXNCO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRDtBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEZBQTRGO0FBQzVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBZ0QsZ0JBQWdCO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDLG1CQUFtQjtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELG1CQUFtQixFQUFFO0FBQ3JFLHdCQUF3QjtBQUN4QjtBQUNBO0FBQ0EscUNBQXFDLG1CQUFtQjtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLE9BQU8sT0FBTztBQUM5QztBQUNBO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBLCtCQUErQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxPQUFPLE9BQU87QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBLGdDQUFnQztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsNEJBQTRCO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsU0FBUztBQUNUO0FBQ0EsNEJBQTRCO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsNEJBQTRCO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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QTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUIsb0JBQW9CO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUIsU0FBUztBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLG9CQUFvQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7QUNyeEJBO0FBQ0E7O0FBRUEsU0FBUyxtQkFBTyxDQUFDLGNBQUk7QUFDckIsU0FBUyxtQkFBTyxDQUFDLHdEQUFhO0FBQzlCLGdCQUFnQixtQkFBTyxDQUFDLHdEQUFXO0FBQ25DO0FBQ0EsV0FBVyx3RUFBeUI7QUFDcEMsV0FBVyxtQkFBTyxDQUFDLGtCQUFNO0FBQ3pCLFdBQVcsbUJBQU8sQ0FBQyxrQkFBTTtBQUN6QixhQUFhLG1CQUFPLENBQUMsc0JBQVE7QUFDN0IsaUJBQWlCLG1CQUFPLENBQUMsa0VBQWtCO0FBQzNDLGFBQWEsbUJBQU8sQ0FBQyxrREFBYTtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUJBQWlCLE9BQU87QUFDeEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCLG9CQUFvQjtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsbUJBQW1CLFNBQVM7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLG9CQUFvQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtB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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyxJQUFJO0FBQ3hDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBOztBQUVBLEtBQUs7QUFDTCxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsSUFBSTtBQUN2QztBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsRUFBRSxFQUFFLEtBQUs7QUFDekM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDLFFBQVE7QUFDaEQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsc0JBQXNCO0FBQ3JDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDZDQUE2QztBQUM3Qzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLEdBQUc7O0FBRUg7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLFFBQVE7QUFDaEM7QUFDQTtBQUNBOztBQUVBLGFBQWEsZ0JBQWdCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUssNkNBQTZDOztBQUVsRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLFNBQVM7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJCQUEyQjtBQUMzQjs7Ozs7Ozs7Ozs7QUMxNUJBLGFBQWEsbUJBQU8sQ0FBQywrQ0FBUTtBQUM3QjtBQUNBLHFCQUFxQjs7QUFFckI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEdBQUc7QUFDSCxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ3pDYTs7QUFFYjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHlDQUF5QyxFQUFFO0FBQzNDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxvQkFBb0I7QUFDcEIsb0JBQW9COzs7Ozs7Ozs7OztBQ25CcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSyxVQUFVLElBQXlEO0FBQ3hFOztBQUVBO0FBQ0EsS0FBSyxNQUFNLDBCQStCTjs7QUFFTCxDQUFDO0FBQ0Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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QUNBLFdBQVcsU0FBUztBQUNwQixhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxrQ0FBa0MsY0FBYyxFQUFFO0FBQ2xEOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtDQUFrQyxjQUFjLEVBQUU7QUFDbEQ7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTCxnQkFBZ0I7QUFDaEIsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxnQkFBZ0I7QUFDaEIsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsU0FBUztBQUNULEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxZQUFZO0FBQ3ZCO0FBQ0EsYUFBYSxhQUFhO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLEtBQUs7QUFDaEIsV0FBVyxTQUFTO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxLQUFLO0FBQ2hCLFdBQVcsU0FBUztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLEtBQUs7QUFDaEIsV0FBVyxTQUFTO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsS0FBSztBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLEtBQUs7QUFDaEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsS0FBSztBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxLQUFLO0FBQ2hCLFdBQVcsT0FBTztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQixXQUFXLE1BQU0sc0NBQXNDO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQixrREFBa0Q7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsU0FBUztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixTQUFTO0FBQ1Q7QUFDQTtBQUNBLGFBQWE7QUFDYixTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQSxDQUFDOzs7Ozs7Ozs7Ozs7QUMzaEVZOztBQUViO0FBQ0E7O0FBRUEsV0FBVyxtQkFBTyxDQUFDLCtDQUFTOztBQUU1QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7Ozs7Ozs7Ozs7O0FDekJhOztBQUViLGdCQUFnQixtQkFBTyxDQUFDLHVEQUFhO0FBQ3JDLFlBQVksbUJBQU8sQ0FBQywrQ0FBUztBQUM3QixjQUFjLG1CQUFPLENBQUMsbURBQVc7O0FBRWpDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ1ZhOztBQUViLFlBQVksbUJBQU8sQ0FBQywrQ0FBUzs7QUFFN0I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLGdCQUFnQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxnQ0FBZ0M7O0FBRXhFO0FBQ0EsdUNBQXVDOztBQUV2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCOztBQUVBO0FBQ0E7QUFDQSxtQkFBbUIsa0JBQWtCO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBOztBQUVBLGVBQWUsa0JBQWtCO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxrQ0FBa0MsUUFBUTtBQUMxQztBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkIsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBOztBQUVBLG1CQUFtQjtBQUNuQjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLG1CQUFtQixpQkFBaUI7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7O0FDM1FhOztBQUViLFlBQVksbUJBQU8sQ0FBQywrQ0FBUztBQUM3QixjQUFjLG1CQUFPLENBQUMsbURBQVc7QUFDakM7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixvQkFBb0I7QUFDdkM7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsbUJBQW1CLG9CQUFvQjtBQUN2Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwyQ0FBMkM7QUFDM0M7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7O0FDdFJhOztBQUViO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1CQUFtQixTQUFTO0FBQzVCO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsMkJBQTJCLGdCQUFnQjtBQUMzQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsbUJBQW1CLG1CQUFtQjtBQUN0QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQWlELEVBQUU7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBLGtEQUFrRCxFQUFFO0FBQ3BEO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0EsbUJBQW1CLG1CQUFtQjtBQUN0Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQixPQUFPLFdBQVcsYUFBYTtBQUNqRDs7QUFFQSxtQkFBbUIsa0JBQWtCO0FBQ3JDO0FBQ0E7O0FBRUE7QUFDQSx1QkFBdUIsaUJBQWlCO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QixzQkFBc0I7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7QUMzT0E7QUFDQTtBQUNBLCtEQUErRDtBQUMvRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQ0FBMEM7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdEQUF3RCxtREFBbUQ7QUFDM0c7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUVBQWlFO0FBQ2pFLDZCQUE2QixnQkFBZ0Isa0JBQWtCO0FBQy9EO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLDRDQUE0QztBQUMzRTtBQUNBLG1DQUFtQyx3QkFBd0Isa0JBQWtCLEVBQUU7QUFDL0UsbUNBQW1DLHlCQUF5QixFQUFFLEVBQUU7QUFDaEU7QUFDQSx1Q0FBdUMsOEJBQThCO0FBQ3JFLHVDQUF1QyxtQkFBbUIsRUFBRTtBQUM1RDtBQUNBLHVDQUF1QyxxREFBcUQ7QUFDNUYsdUNBQXVDLGlCQUFpQixFQUFFO0FBQzFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQywyQ0FBMkM7QUFDM0MsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLDJDQUEyQztBQUMzQyw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUdBQXVHO0FBQ3ZHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLDJDQUEyQztBQUMzQyw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnRkFBZ0Y7QUFDaEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkMsMkNBQTJDO0FBQzNDLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFFQUFxRTtBQUNyRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQywyQ0FBMkM7QUFDM0MsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUVBQXFFO0FBQ3JFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLDJDQUEyQztBQUMzQyw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQywyQ0FBMkM7QUFDM0MsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkMsMkNBQTJDO0FBQzNDLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVFQUF1RTtBQUN2RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQywyQ0FBMkM7QUFDM0MsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtDQUErQyxRQUFRO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQ0FBK0MsUUFBUTtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlEQUFpRCx1QkFBdUI7QUFDeEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1REFBdUQsMEJBQTBCO0FBQ2pGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQztBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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QUFDQSwyQkFBMkI7O0FBRTNCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsU0FBUyxVQUFVO0FBQ25CLFVBQVUsV0FBVztBQUNyQjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0Isb0NBQW9DO0FBQ3hELDBCQUEwQixvQ0FBb0M7QUFDOUQsMEJBQTBCLG9DQUFvQztBQUM5RDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsY0FBYzs7QUFFZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwwQkFBMEI7O0FBRTFCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwyQkFBMkI7QUFDM0I7QUFDQTtBQUNBOztBQUVBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7O0FBRUEsYUFBYTtBQUNiO0FBQ0E7QUFDQTs7QUFFQSxhQUFhO0FBQ2I7QUFDQTtBQUNBOztBQUVBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7O0FBRUEsb0JBQW9CO0FBQ3BCO0FBQ0E7QUFDQTs7QUFFQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBOztBQUVBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUEsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBOztBQUVBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7O0FBRUEsVUFBVTtBQUNWO0FBQ0E7QUFDQTs7QUFFQSxXQUFXO0FBQ1g7QUFDQTtBQUNBOztBQUVBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7O0FBRUEsV0FBVztBQUNYO0FBQ0E7QUFDQTs7QUFFQSxXQUFXO0FBQ1g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULE9BQU87QUFDUCxLQUFLO0FBQ0wsR0FBRztBQUNIOztBQUVBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQywwQkFBMEI7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLGFBQWEsU0FBUzs7Ozs7Ozs7Ozs7QUN2UXRCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDs7QUFFQTtBQUNBO0FBQ0EsbUJBQW1CLGlCQUFpQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDaENBLG1DOzs7Ozs7Ozs7OztBQ0FBLDBDOzs7Ozs7Ozs7OztBQ0FBLG1DOzs7Ozs7Ozs7OztBQ0FBLG1DOzs7Ozs7Ozs7OztBQ0FBLCtCOzs7Ozs7Ozs7OztBQ0FBLGlDOzs7Ozs7Ozs7OztBQ0FBLGtDOzs7Ozs7Ozs7OztBQ0FBLGdDOzs7Ozs7Ozs7OztBQ0FBLCtCOzs7Ozs7Ozs7OztBQ0FBLGlDOzs7Ozs7Ozs7OztBQ0FBLG9DOzs7Ozs7Ozs7OztBQ0FBLGdDOzs7Ozs7Ozs7OztBQ0FBLGdDOzs7Ozs7Ozs7OztBQ0FBLGlDOzs7Ozs7Ozs7OztBQ0FBLGlDOzs7Ozs7VUNBQTtVQUNBOztVQUVBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBOztVQUVBO1VBQ0E7O1VBRUE7VUFDQTs7VUFFQTtVQUNBO1VBQ0E7O1VBRUE7VUFDQTs7Ozs7V0M1QkEsd0Y7Ozs7O1dDQUE7V0FDQTtXQUNBO1dBQ0E7V0FDQSxFOzs7OztVQ0pBO1VBQ0E7VUFDQTtVQUNBIiwiZmlsZSI6ImdpdHJlbGVhc2VtYW5hZ2VyL2Nsb3NlL2J1bmRsZS5qcyIsInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbmV4cG9ydHMuX2V4cG9zZUNlcnRTZXR0aW5ncyA9IGV4cG9ydHMuX2V4cG9zZVByb3h5U2V0dGluZ3MgPSBleHBvcnRzLl9ub3JtYWxpemVTZXBhcmF0b3JzID0gZXhwb3J0cy5faXNSb290ZWQgPSBleHBvcnRzLl9nZXREaXJlY3RvcnlOYW1lID0gZXhwb3J0cy5fZW5zdXJlUm9vdGVkID0gZXhwb3J0cy5fbG9hZERhdGEgPSBleHBvcnRzLl9lbnN1cmVQYXR0ZXJuUm9vdGVkID0gZXhwb3J0cy5fZ2V0RmluZEluZm9Gcm9tUGF0dGVybiA9IGV4cG9ydHMuX2Nsb25lTWF0Y2hPcHRpb25zID0gZXhwb3J0cy5fbGVnYWN5RmluZEZpbGVzX2NvbnZlcnRQYXR0ZXJuVG9SZWdFeHAgPSBleHBvcnRzLl93aGljaCA9IGV4cG9ydHMuX2NoZWNrUGF0aCA9IGV4cG9ydHMuX2V4aXN0ID0gZXhwb3J0cy5fZGVidWcgPSBleHBvcnRzLl9lcnJvciA9IGV4cG9ydHMuX3dhcm5pbmcgPSBleHBvcnRzLl9jb21tYW5kID0gZXhwb3J0cy5fZ2V0VmFyaWFibGVLZXkgPSBleHBvcnRzLl9nZXRWYXJpYWJsZSA9IGV4cG9ydHMuX2xvYyA9IGV4cG9ydHMuX3NldFJlc291cmNlUGF0aCA9IGV4cG9ydHMuX3NldEVyclN0cmVhbSA9IGV4cG9ydHMuX3NldFN0ZFN0cmVhbSA9IGV4cG9ydHMuX3dyaXRlTGluZSA9IGV4cG9ydHMuX2VuZHNXaXRoID0gZXhwb3J0cy5fc3RhcnRzV2l0aCA9IGV4cG9ydHMuX3ZhdWx0ID0gZXhwb3J0cy5fa25vd25WYXJpYWJsZU1hcCA9IHZvaWQgMDtcclxudmFyIGZzID0gcmVxdWlyZShcImZzXCIpO1xyXG52YXIgcGF0aCA9IHJlcXVpcmUoXCJwYXRoXCIpO1xyXG52YXIgb3MgPSByZXF1aXJlKFwib3NcIik7XHJcbnZhciBtaW5pbWF0Y2ggPSByZXF1aXJlKFwibWluaW1hdGNoXCIpO1xyXG52YXIgdXRpbCA9IHJlcXVpcmUoXCJ1dGlsXCIpO1xyXG52YXIgdGNtID0gcmVxdWlyZShcIi4vdGFza2NvbW1hbmRcIik7XHJcbnZhciB2bSA9IHJlcXVpcmUoXCIuL3ZhdWx0XCIpO1xyXG52YXIgc2VtdmVyID0gcmVxdWlyZShcInNlbXZlclwiKTtcclxudmFyIGNyeXB0byA9IHJlcXVpcmUoXCJjcnlwdG9cIik7XHJcbi8qKlxyXG4gKiBIYXNoIHRhYmxlIG9mIGtub3duIHZhcmlhYmxlIGluZm8uIFRoZSBmb3JtYXR0ZWQgZW52IHZhciBuYW1lIGlzIHRoZSBsb29rdXAga2V5LlxyXG4gKlxyXG4gKiBUaGUgcHVycG9zZSBvZiB0aGlzIGhhc2ggdGFibGUgaXMgdG8ga2VlcCB0cmFjayBvZiBrbm93biB2YXJpYWJsZXMuIFRoZSBoYXNoIHRhYmxlXHJcbiAqIG5lZWRzIHRvIGJlIG1haW50YWluZWQgZm9yIG11bHRpcGxlIHJlYXNvbnM6XHJcbiAqICAxKSB0byBkaXN0aW5ndWlzaCBiZXR3ZWVuIGVudiB2YXJzIGFuZCBqb2IgdmFyc1xyXG4gKiAgMikgdG8gZGlzdGluZ3Vpc2ggYmV0d2VlbiBzZWNyZXQgdmFycyBhbmQgcHVibGljXHJcbiAqICAzKSB0byBrbm93IHRoZSByZWFsIHZhcmlhYmxlIG5hbWUgYW5kIG5vdCBqdXN0IHRoZSBmb3JtYXR0ZWQgZW52IHZhciBuYW1lLlxyXG4gKi9cclxuZXhwb3J0cy5fa25vd25WYXJpYWJsZU1hcCA9IHt9O1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIFZhbGlkYXRpb24gQ2hlY2tzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gYXN5bmMgYXdhaXQgbmVlZHMgZ2VuZXJhdG9ycyBpbiBub2RlIDQueCtcclxuaWYgKHNlbXZlci5sdChwcm9jZXNzLnZlcnNpb25zLm5vZGUsICc0LjIuMCcpKSB7XHJcbiAgICBfd2FybmluZygnVGFza3MgcmVxdWlyZSBhIG5ldyBhZ2VudC4gIFVwZ3JhZGUgeW91ciBhZ2VudCBvciBub2RlIHRvIDQuMi4wIG9yIGxhdGVyJyk7XHJcbn1cclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBTdHJpbmcgY29udmVuaWVuY2VcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5mdW5jdGlvbiBfc3RhcnRzV2l0aChzdHIsIHN0YXJ0KSB7XHJcbiAgICByZXR1cm4gc3RyLnNsaWNlKDAsIHN0YXJ0Lmxlbmd0aCkgPT0gc3RhcnQ7XHJcbn1cclxuZXhwb3J0cy5fc3RhcnRzV2l0aCA9IF9zdGFydHNXaXRoO1xyXG5mdW5jdGlvbiBfZW5kc1dpdGgoc3RyLCBlbmQpIHtcclxuICAgIHJldHVybiBzdHIuc2xpY2UoLWVuZC5sZW5ndGgpID09IGVuZDtcclxufVxyXG5leHBvcnRzLl9lbmRzV2l0aCA9IF9lbmRzV2l0aDtcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBHZW5lcmFsIEhlbHBlcnNcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG52YXIgX291dFN0cmVhbSA9IHByb2Nlc3Muc3Rkb3V0O1xyXG52YXIgX2VyclN0cmVhbSA9IHByb2Nlc3Muc3RkZXJyO1xyXG5mdW5jdGlvbiBfd3JpdGVMaW5lKHN0cikge1xyXG4gICAgX291dFN0cmVhbS53cml0ZShzdHIgKyBvcy5FT0wpO1xyXG59XHJcbmV4cG9ydHMuX3dyaXRlTGluZSA9IF93cml0ZUxpbmU7XHJcbmZ1bmN0aW9uIF9zZXRTdGRTdHJlYW0oc3RkU3RyZWFtKSB7XHJcbiAgICBfb3V0U3RyZWFtID0gc3RkU3RyZWFtO1xyXG59XHJcbmV4cG9ydHMuX3NldFN0ZFN0cmVhbSA9IF9zZXRTdGRTdHJlYW07XHJcbmZ1bmN0aW9uIF9zZXRFcnJTdHJlYW0oZXJyU3RyZWFtKSB7XHJcbiAgICBfZXJyU3RyZWFtID0gZXJyU3RyZWFtO1xyXG59XHJcbmV4cG9ydHMuX3NldEVyclN0cmVhbSA9IF9zZXRFcnJTdHJlYW07XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gTG9jIEhlbHBlcnNcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG52YXIgX2xvY1N0cmluZ0NhY2hlID0ge307XHJcbnZhciBfcmVzb3VyY2VGaWxlcyA9IHt9O1xyXG52YXIgX2xpYlJlc291cmNlRmlsZUxvYWRlZCA9IGZhbHNlO1xyXG52YXIgX3Jlc291cmNlQ3VsdHVyZSA9ICdlbi1VUyc7XHJcbmZ1bmN0aW9uIF9sb2FkUmVzSnNvbihyZXNqc29uRmlsZSkge1xyXG4gICAgdmFyIHJlc0pzb247XHJcbiAgICBpZiAoX2V4aXN0KHJlc2pzb25GaWxlKSkge1xyXG4gICAgICAgIHZhciByZXNqc29uQ29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhyZXNqc29uRmlsZSwgJ3V0ZjgnKS50b1N0cmluZygpO1xyXG4gICAgICAgIC8vIHJlbW92ZSBCT01cclxuICAgICAgICBpZiAocmVzanNvbkNvbnRlbnQuaW5kZXhPZignXFx1RkVGRicpID09IDApIHtcclxuICAgICAgICAgICAgcmVzanNvbkNvbnRlbnQgPSByZXNqc29uQ29udGVudC5zbGljZSgxKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgcmVzSnNvbiA9IEpTT04ucGFyc2UocmVzanNvbkNvbnRlbnQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgIF9kZWJ1ZygndW5hYmxlIHRvIHBhcnNlIHJlc2pzb24gd2l0aCBlcnI6ICcgKyBlcnIubWVzc2FnZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgX2RlYnVnKCcucmVzanNvbiBmaWxlIG5vdCBmb3VuZDogJyArIHJlc2pzb25GaWxlKTtcclxuICAgIH1cclxuICAgIHJldHVybiByZXNKc29uO1xyXG59XHJcbmZ1bmN0aW9uIF9sb2FkTG9jU3RyaW5ncyhyZXNvdXJjZUZpbGUsIGN1bHR1cmUpIHtcclxuICAgIHZhciBsb2NTdHJpbmdzID0ge307XHJcbiAgICBpZiAoX2V4aXN0KHJlc291cmNlRmlsZSkpIHtcclxuICAgICAgICB2YXIgcmVzb3VyY2VKc29uID0gcmVxdWlyZShyZXNvdXJjZUZpbGUpO1xyXG4gICAgICAgIGlmIChyZXNvdXJjZUpzb24gJiYgcmVzb3VyY2VKc29uLmhhc093blByb3BlcnR5KCdtZXNzYWdlcycpKSB7XHJcbiAgICAgICAgICAgIHZhciBsb2NSZXNvdXJjZUpzb247XHJcbiAgICAgICAgICAgIC8vIGxvYWQgdXAgcmVzb3VyY2UgcmVzanNvbiBmb3IgZGlmZmVyZW50IGN1bHR1cmVcclxuICAgICAgICAgICAgdmFyIGxvY2FsaXplZFJlc291cmNlRmlsZSA9IHBhdGguam9pbihwYXRoLmRpcm5hbWUocmVzb3VyY2VGaWxlKSwgJ1N0cmluZ3MnLCAncmVzb3VyY2VzLnJlc2pzb24nKTtcclxuICAgICAgICAgICAgdmFyIHVwcGVyQ3VsdHVyZSA9IGN1bHR1cmUudG9VcHBlckNhc2UoKTtcclxuICAgICAgICAgICAgdmFyIGN1bHR1cmVzID0gW107XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBjdWx0dXJlcyA9IGZzLnJlYWRkaXJTeW5jKGxvY2FsaXplZFJlc291cmNlRmlsZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGV4KSB7IH1cclxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjdWx0dXJlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgaWYgKGN1bHR1cmVzW2ldLnRvVXBwZXJDYXNlKCkgPT0gdXBwZXJDdWx0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9jYWxpemVkUmVzb3VyY2VGaWxlID0gcGF0aC5qb2luKGxvY2FsaXplZFJlc291cmNlRmlsZSwgY3VsdHVyZXNbaV0sICdyZXNvdXJjZXMucmVzanNvbicpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfZXhpc3QobG9jYWxpemVkUmVzb3VyY2VGaWxlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsb2NSZXNvdXJjZUpzb24gPSBfbG9hZFJlc0pzb24obG9jYWxpemVkUmVzb3VyY2VGaWxlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIHJlc291cmNlSnNvbi5tZXNzYWdlcykge1xyXG4gICAgICAgICAgICAgICAgaWYgKGxvY1Jlc291cmNlSnNvbiAmJiBsb2NSZXNvdXJjZUpzb24uaGFzT3duUHJvcGVydHkoJ2xvYy5tZXNzYWdlcy4nICsga2V5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxvY1N0cmluZ3Nba2V5XSA9IGxvY1Jlc291cmNlSnNvblsnbG9jLm1lc3NhZ2VzLicgKyBrZXldO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9jU3RyaW5nc1trZXldID0gcmVzb3VyY2VKc29uLm1lc3NhZ2VzW2tleV07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBfd2FybmluZygnTElCX1Jlc291cmNlRmlsZSBkb2VzIG5vdCBleGlzdCcpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGxvY1N0cmluZ3M7XHJcbn1cclxuLyoqXHJcbiAqIFNldHMgdGhlIGxvY2F0aW9uIG9mIHRoZSByZXNvdXJjZXMganNvbi4gIFRoaXMgaXMgdHlwaWNhbGx5IHRoZSB0YXNrLmpzb24gZmlsZS5cclxuICogQ2FsbCBvbmNlIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNjcmlwdCBiZWZvcmUgYW55IGNhbGxzIHRvIGxvYy5cclxuICogQHBhcmFtICAgICBwYXRoICAgICAgRnVsbCBwYXRoIHRvIHRoZSBqc29uLlxyXG4gKiBAcGFyYW0gICAgIGlnbm9yZVdhcm5pbmdzICBXb24ndCB0aHJvdyB3YXJuaW5ncyBpZiBwYXRoIGFscmVhZHkgc2V0LlxyXG4gKiBAcmV0dXJucyAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIF9zZXRSZXNvdXJjZVBhdGgocGF0aCwgaWdub3JlV2FybmluZ3MpIHtcclxuICAgIGlmIChpZ25vcmVXYXJuaW5ncyA9PT0gdm9pZCAwKSB7IGlnbm9yZVdhcm5pbmdzID0gZmFsc2U7IH1cclxuICAgIGlmIChwcm9jZXNzLmVudlsnVEFTS0xJQl9JTlBST0NfVU5JVFMnXSkge1xyXG4gICAgICAgIF9yZXNvdXJjZUZpbGVzID0ge307XHJcbiAgICAgICAgX2xpYlJlc291cmNlRmlsZUxvYWRlZCA9IGZhbHNlO1xyXG4gICAgICAgIF9sb2NTdHJpbmdDYWNoZSA9IHt9O1xyXG4gICAgICAgIF9yZXNvdXJjZUN1bHR1cmUgPSAnZW4tVVMnO1xyXG4gICAgfVxyXG4gICAgaWYgKCFfcmVzb3VyY2VGaWxlc1twYXRoXSkge1xyXG4gICAgICAgIF9jaGVja1BhdGgocGF0aCwgJ3Jlc291cmNlIGZpbGUgcGF0aCcpO1xyXG4gICAgICAgIF9yZXNvdXJjZUZpbGVzW3BhdGhdID0gcGF0aDtcclxuICAgICAgICBfZGVidWcoJ2FkZGluZyByZXNvdXJjZSBmaWxlOiAnICsgcGF0aCk7XHJcbiAgICAgICAgX3Jlc291cmNlQ3VsdHVyZSA9IF9nZXRWYXJpYWJsZSgnc3lzdGVtLmN1bHR1cmUnKSB8fCBfcmVzb3VyY2VDdWx0dXJlO1xyXG4gICAgICAgIHZhciBsb2NTdHJzID0gX2xvYWRMb2NTdHJpbmdzKHBhdGgsIF9yZXNvdXJjZUN1bHR1cmUpO1xyXG4gICAgICAgIGZvciAodmFyIGtleSBpbiBsb2NTdHJzKSB7XHJcbiAgICAgICAgICAgIC8vY2FjaGUgbG9jIHN0cmluZ1xyXG4gICAgICAgICAgICBfbG9jU3RyaW5nQ2FjaGVba2V5XSA9IGxvY1N0cnNba2V5XTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBpZiAoaWdub3JlV2FybmluZ3MpIHtcclxuICAgICAgICAgICAgX2RlYnVnKF9sb2MoJ0xJQl9SZXNvdXJjZUZpbGVBbHJlYWR5U2V0JywgcGF0aCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgX3dhcm5pbmcoX2xvYygnTElCX1Jlc291cmNlRmlsZUFscmVhZHlTZXQnLCBwYXRoKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMuX3NldFJlc291cmNlUGF0aCA9IF9zZXRSZXNvdXJjZVBhdGg7XHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBsb2NhbGl6ZWQgc3RyaW5nIGZyb20gdGhlIGpzb24gcmVzb3VyY2UgZmlsZS4gIE9wdGlvbmFsbHkgZm9ybWF0cyB3aXRoIGFkZGl0aW9uYWwgcGFyYW1zLlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIGtleSAgICAgIGtleSBvZiB0aGUgcmVzb3VyY2VzIHN0cmluZyBpbiB0aGUgcmVzb3VyY2UgZmlsZVxyXG4gKiBAcGFyYW0gICAgIHBhcmFtICAgIGFkZGl0aW9uYWwgcGFyYW1zIGZvciBmb3JtYXR0aW5nIHRoZSBzdHJpbmdcclxuICogQHJldHVybnMgICBzdHJpbmdcclxuICovXHJcbmZ1bmN0aW9uIF9sb2Moa2V5KSB7XHJcbiAgICB2YXIgcGFyYW0gPSBbXTtcclxuICAgIGZvciAodmFyIF9pID0gMTsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgcGFyYW1bX2kgLSAxXSA9IGFyZ3VtZW50c1tfaV07XHJcbiAgICB9XHJcbiAgICBpZiAoIV9saWJSZXNvdXJjZUZpbGVMb2FkZWQpIHtcclxuICAgICAgICAvLyBtZXJnZSBsb2Mgc3RyaW5ncyBmcm9tIGF6dXJlLXBpcGVsaW5lcy10YXNrLWxpYi5cclxuICAgICAgICB2YXIgbGliUmVzb3VyY2VGaWxlID0gcGF0aC5qb2luKF9fZGlybmFtZSwgJ2xpYi5qc29uJyk7XHJcbiAgICAgICAgdmFyIGxpYkxvY1N0cnMgPSBfbG9hZExvY1N0cmluZ3MobGliUmVzb3VyY2VGaWxlLCBfcmVzb3VyY2VDdWx0dXJlKTtcclxuICAgICAgICBmb3IgKHZhciBsaWJLZXkgaW4gbGliTG9jU3Rycykge1xyXG4gICAgICAgICAgICAvL2NhY2hlIGF6dXJlLXBpcGVsaW5lcy10YXNrLWxpYiBsb2Mgc3RyaW5nXHJcbiAgICAgICAgICAgIF9sb2NTdHJpbmdDYWNoZVtsaWJLZXldID0gbGliTG9jU3Ryc1tsaWJLZXldO1xyXG4gICAgICAgIH1cclxuICAgICAgICBfbGliUmVzb3VyY2VGaWxlTG9hZGVkID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIHZhciBsb2NTdHJpbmc7XHJcbiAgICA7XHJcbiAgICBpZiAoX2xvY1N0cmluZ0NhY2hlLmhhc093blByb3BlcnR5KGtleSkpIHtcclxuICAgICAgICBsb2NTdHJpbmcgPSBfbG9jU3RyaW5nQ2FjaGVba2V5XTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGlmIChPYmplY3Qua2V5cyhfcmVzb3VyY2VGaWxlcykubGVuZ3RoIDw9IDApIHtcclxuICAgICAgICAgICAgX3dhcm5pbmcoX2xvYygnTElCX1Jlc291cmNlRmlsZU5vdFNldCcsIGtleSkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgX3dhcm5pbmcoX2xvYygnTElCX0xvY1N0cmluZ05vdEZvdW5kJywga2V5KSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxvY1N0cmluZyA9IGtleTtcclxuICAgIH1cclxuICAgIGlmIChwYXJhbS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgcmV0dXJuIHV0aWwuZm9ybWF0LmFwcGx5KHRoaXMsIFtsb2NTdHJpbmddLmNvbmNhdChwYXJhbSkpO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIGxvY1N0cmluZztcclxuICAgIH1cclxufVxyXG5leHBvcnRzLl9sb2MgPSBfbG9jO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIElucHV0IEhlbHBlcnNcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vKipcclxuICogR2V0cyBhIHZhcmlhYmxlIHZhbHVlIHRoYXQgaXMgZGVmaW5lZCBvbiB0aGUgYnVpbGQvcmVsZWFzZSBkZWZpbml0aW9uIG9yIHNldCBhdCBydW50aW1lLlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIG5hbWUgICAgIG5hbWUgb2YgdGhlIHZhcmlhYmxlIHRvIGdldFxyXG4gKiBAcmV0dXJucyAgIHN0cmluZ1xyXG4gKi9cclxuZnVuY3Rpb24gX2dldFZhcmlhYmxlKG5hbWUpIHtcclxuICAgIHZhciB2YXJ2YWw7XHJcbiAgICAvLyBnZXQgdGhlIG1ldGFkYXRhXHJcbiAgICB2YXIgaW5mbztcclxuICAgIHZhciBrZXkgPSBfZ2V0VmFyaWFibGVLZXkobmFtZSk7XHJcbiAgICBpZiAoZXhwb3J0cy5fa25vd25WYXJpYWJsZU1hcC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XHJcbiAgICAgICAgaW5mbyA9IGV4cG9ydHMuX2tub3duVmFyaWFibGVNYXBba2V5XTtcclxuICAgIH1cclxuICAgIGlmIChpbmZvICYmIGluZm8uc2VjcmV0KSB7XHJcbiAgICAgICAgLy8gZ2V0IHRoZSBzZWNyZXQgdmFsdWVcclxuICAgICAgICB2YXJ2YWwgPSBleHBvcnRzLl92YXVsdC5yZXRyaWV2ZVNlY3JldCgnU0VDUkVUXycgKyBrZXkpO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgLy8gZ2V0IHRoZSBwdWJsaWMgdmFsdWVcclxuICAgICAgICB2YXJ2YWwgPSBwcm9jZXNzLmVudltrZXldO1xyXG4gICAgICAgIC8vIGZhbGxiYWNrIGZvciBwcmUgMi4xMDQuMSBhZ2VudFxyXG4gICAgICAgIGlmICghdmFydmFsICYmIG5hbWUudG9VcHBlckNhc2UoKSA9PSAnQUdFTlQuSk9CU1RBVFVTJykge1xyXG4gICAgICAgICAgICB2YXJ2YWwgPSBwcm9jZXNzLmVudlsnYWdlbnQuam9ic3RhdHVzJ107XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgX2RlYnVnKG5hbWUgKyAnPScgKyB2YXJ2YWwpO1xyXG4gICAgcmV0dXJuIHZhcnZhbDtcclxufVxyXG5leHBvcnRzLl9nZXRWYXJpYWJsZSA9IF9nZXRWYXJpYWJsZTtcclxuZnVuY3Rpb24gX2dldFZhcmlhYmxlS2V5KG5hbWUpIHtcclxuICAgIGlmICghbmFtZSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihfbG9jKCdMSUJfUGFyYW1ldGVySXNSZXF1aXJlZCcsICduYW1lJykpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG5hbWUucmVwbGFjZSgvXFwuL2csICdfJykucmVwbGFjZSgvIC9nLCAnXycpLnRvVXBwZXJDYXNlKCk7XHJcbn1cclxuZXhwb3J0cy5fZ2V0VmFyaWFibGVLZXkgPSBfZ2V0VmFyaWFibGVLZXk7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gQ21kIEhlbHBlcnNcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5mdW5jdGlvbiBfY29tbWFuZChjb21tYW5kLCBwcm9wZXJ0aWVzLCBtZXNzYWdlKSB7XHJcbiAgICB2YXIgdGFza0NtZCA9IG5ldyB0Y20uVGFza0NvbW1hbmQoY29tbWFuZCwgcHJvcGVydGllcywgbWVzc2FnZSk7XHJcbiAgICBfd3JpdGVMaW5lKHRhc2tDbWQudG9TdHJpbmcoKSk7XHJcbn1cclxuZXhwb3J0cy5fY29tbWFuZCA9IF9jb21tYW5kO1xyXG5mdW5jdGlvbiBfd2FybmluZyhtZXNzYWdlKSB7XHJcbiAgICBfY29tbWFuZCgndGFzay5pc3N1ZScsIHsgJ3R5cGUnOiAnd2FybmluZycgfSwgbWVzc2FnZSk7XHJcbn1cclxuZXhwb3J0cy5fd2FybmluZyA9IF93YXJuaW5nO1xyXG5mdW5jdGlvbiBfZXJyb3IobWVzc2FnZSkge1xyXG4gICAgX2NvbW1hbmQoJ3Rhc2suaXNzdWUnLCB7ICd0eXBlJzogJ2Vycm9yJyB9LCBtZXNzYWdlKTtcclxufVxyXG5leHBvcnRzLl9lcnJvciA9IF9lcnJvcjtcclxuZnVuY3Rpb24gX2RlYnVnKG1lc3NhZ2UpIHtcclxuICAgIF9jb21tYW5kKCd0YXNrLmRlYnVnJywgbnVsbCwgbWVzc2FnZSk7XHJcbn1cclxuZXhwb3J0cy5fZGVidWcgPSBfZGVidWc7XHJcbi8vIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gLy8gRGlzayBGdW5jdGlvbnNcclxuLy8gLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vKipcclxuICogUmV0dXJucyB3aGV0aGVyIGEgcGF0aCBleGlzdHMuXHJcbiAqXHJcbiAqIEBwYXJhbSAgICAgcGF0aCAgICAgIHBhdGggdG8gY2hlY2tcclxuICogQHJldHVybnMgICBib29sZWFuXHJcbiAqL1xyXG5mdW5jdGlvbiBfZXhpc3QocGF0aCkge1xyXG4gICAgdmFyIGV4aXN0ID0gZmFsc2U7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIGV4aXN0ID0gISEocGF0aCAmJiBmcy5zdGF0U3luYyhwYXRoKSAhPSBudWxsKTtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICBpZiAoZXJyICYmIGVyci5jb2RlID09PSAnRU5PRU5UJykge1xyXG4gICAgICAgICAgICBleGlzdCA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBleGlzdDtcclxufVxyXG5leHBvcnRzLl9leGlzdCA9IF9leGlzdDtcclxuLyoqXHJcbiAqIENoZWNrcyB3aGV0aGVyIGEgcGF0aCBleGlzdHMuXHJcbiAqIElmIHRoZSBwYXRoIGRvZXMgbm90IGV4aXN0LCBpdCB3aWxsIHRocm93LlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIHAgICAgICAgICBwYXRoIHRvIGNoZWNrXHJcbiAqIEBwYXJhbSAgICAgbmFtZSAgICAgIG5hbWUgb25seSB1c2VkIGluIGVycm9yIG1lc3NhZ2UgdG8gaWRlbnRpZnkgdGhlIHBhdGhcclxuICogQHJldHVybnMgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiBfY2hlY2tQYXRoKHAsIG5hbWUpIHtcclxuICAgIF9kZWJ1ZygnY2hlY2sgcGF0aCA6ICcgKyBwKTtcclxuICAgIGlmICghX2V4aXN0KHApKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKF9sb2MoJ0xJQl9QYXRoTm90Rm91bmQnLCBuYW1lLCBwKSk7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy5fY2hlY2tQYXRoID0gX2NoZWNrUGF0aDtcclxuLyoqXHJcbiAqIFJldHVybnMgcGF0aCBvZiBhIHRvb2wgaGFkIHRoZSB0b29sIGFjdHVhbGx5IGJlZW4gaW52b2tlZC4gIFJlc29sdmVzIHZpYSBwYXRocy5cclxuICogSWYgeW91IGNoZWNrIGFuZCB0aGUgdG9vbCBkb2VzIG5vdCBleGlzdCwgaXQgd2lsbCB0aHJvdy5cclxuICpcclxuICogQHBhcmFtICAgICB0b29sICAgICAgIG5hbWUgb2YgdGhlIHRvb2xcclxuICogQHBhcmFtICAgICBjaGVjayAgICAgIHdoZXRoZXIgdG8gY2hlY2sgaWYgdG9vbCBleGlzdHNcclxuICogQHJldHVybnMgICBzdHJpbmdcclxuICovXHJcbmZ1bmN0aW9uIF93aGljaCh0b29sLCBjaGVjaykge1xyXG4gICAgaWYgKCF0b29sKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdwYXJhbWV0ZXIgXFwndG9vbFxcJyBpcyByZXF1aXJlZCcpO1xyXG4gICAgfVxyXG4gICAgLy8gcmVjdXJzaXZlIHdoZW4gY2hlY2s9dHJ1ZVxyXG4gICAgaWYgKGNoZWNrKSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IF93aGljaCh0b29sLCBmYWxzZSk7XHJcbiAgICAgICAgaWYgKHJlc3VsdCkge1xyXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJykge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKF9sb2MoJ0xJQl9XaGljaE5vdEZvdW5kX1dpbicsIHRvb2wpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihfbG9jKCdMSUJfV2hpY2hOb3RGb3VuZF9MaW51eCcsIHRvb2wpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIF9kZWJ1ZyhcIndoaWNoICdcIiArIHRvb2wgKyBcIidcIik7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIC8vIGJ1aWxkIHRoZSBsaXN0IG9mIGV4dGVuc2lvbnMgdG8gdHJ5XHJcbiAgICAgICAgdmFyIGV4dGVuc2lvbnMgPSBbXTtcclxuICAgICAgICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInICYmIHByb2Nlc3MuZW52WydQQVRIRVhUJ10pIHtcclxuICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHByb2Nlc3MuZW52WydQQVRIRVhUJ10uc3BsaXQocGF0aC5kZWxpbWl0ZXIpOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICAgICAgdmFyIGV4dGVuc2lvbiA9IF9hW19pXTtcclxuICAgICAgICAgICAgICAgIGlmIChleHRlbnNpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25zLnB1c2goZXh0ZW5zaW9uKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBpZiBpdCdzIHJvb3RlZCwgcmV0dXJuIGl0IGlmIGV4aXN0cy4gb3RoZXJ3aXNlIHJldHVybiBlbXB0eS5cclxuICAgICAgICBpZiAoX2lzUm9vdGVkKHRvb2wpKSB7XHJcbiAgICAgICAgICAgIHZhciBmaWxlUGF0aCA9IF90cnlHZXRFeGVjdXRhYmxlUGF0aCh0b29sLCBleHRlbnNpb25zKTtcclxuICAgICAgICAgICAgaWYgKGZpbGVQYXRoKSB7XHJcbiAgICAgICAgICAgICAgICBfZGVidWcoXCJmb3VuZDogJ1wiICsgZmlsZVBhdGggKyBcIidcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmlsZVBhdGg7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgX2RlYnVnKCdub3QgZm91bmQnKTtcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBpZiBhbnkgcGF0aCBzZXBhcmF0b3JzLCByZXR1cm4gZW1wdHlcclxuICAgICAgICBpZiAodG9vbC5pbmRleE9mKCcvJykgPj0gMCB8fCAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInICYmIHRvb2wuaW5kZXhPZignXFxcXCcpID49IDApKSB7XHJcbiAgICAgICAgICAgIF9kZWJ1Zygnbm90IGZvdW5kJyk7XHJcbiAgICAgICAgICAgIHJldHVybiAnJztcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gYnVpbGQgdGhlIGxpc3Qgb2YgZGlyZWN0b3JpZXNcclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIE5vdGUsIHRlY2huaWNhbGx5IFwid2hlcmVcIiBjaGVja3MgdGhlIGN1cnJlbnQgZGlyZWN0b3J5IG9uIFdpbmRvd3MuIEZyb20gYSB0YXNrIGxpYiBwZXJzcGVjdGl2ZSxcclxuICAgICAgICAvLyBpdCBmZWVscyBsaWtlIHdlIHNob3VsZCBub3QgZG8gdGhpcy4gQ2hlY2tpbmcgdGhlIGN1cnJlbnQgZGlyZWN0b3J5IHNlZW1zIGxpa2UgbW9yZSBvZiBhIHVzZVxyXG4gICAgICAgIC8vIGNhc2Ugb2YgYSBzaGVsbCwgYW5kIHRoZSB3aGljaCgpIGZ1bmN0aW9uIGV4cG9zZWQgYnkgdGhlIHRhc2sgbGliIHNob3VsZCBzdHJpdmUgZm9yIGNvbnNpc3RlbmN5XHJcbiAgICAgICAgLy8gYWNyb3NzIHBsYXRmb3Jtcy5cclxuICAgICAgICB2YXIgZGlyZWN0b3JpZXMgPSBbXTtcclxuICAgICAgICBpZiAocHJvY2Vzcy5lbnZbJ1BBVEgnXSkge1xyXG4gICAgICAgICAgICBmb3IgKHZhciBfYiA9IDAsIF9jID0gcHJvY2Vzcy5lbnZbJ1BBVEgnXS5zcGxpdChwYXRoLmRlbGltaXRlcik7IF9iIDwgX2MubGVuZ3RoOyBfYisrKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgcCA9IF9jW19iXTtcclxuICAgICAgICAgICAgICAgIGlmIChwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGlyZWN0b3JpZXMucHVzaChwKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICAvLyByZXR1cm4gdGhlIGZpcnN0IG1hdGNoXHJcbiAgICAgICAgZm9yICh2YXIgX2QgPSAwLCBkaXJlY3Rvcmllc18xID0gZGlyZWN0b3JpZXM7IF9kIDwgZGlyZWN0b3JpZXNfMS5sZW5ndGg7IF9kKyspIHtcclxuICAgICAgICAgICAgdmFyIGRpcmVjdG9yeSA9IGRpcmVjdG9yaWVzXzFbX2RdO1xyXG4gICAgICAgICAgICB2YXIgZmlsZVBhdGggPSBfdHJ5R2V0RXhlY3V0YWJsZVBhdGgoZGlyZWN0b3J5ICsgcGF0aC5zZXAgKyB0b29sLCBleHRlbnNpb25zKTtcclxuICAgICAgICAgICAgaWYgKGZpbGVQYXRoKSB7XHJcbiAgICAgICAgICAgICAgICBfZGVidWcoXCJmb3VuZDogJ1wiICsgZmlsZVBhdGggKyBcIidcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmlsZVBhdGg7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgX2RlYnVnKCdub3QgZm91bmQnKTtcclxuICAgICAgICByZXR1cm4gJyc7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKF9sb2MoJ0xJQl9PcGVyYXRpb25GYWlsZWQnLCAnd2hpY2gnLCBlcnIubWVzc2FnZSkpO1xyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMuX3doaWNoID0gX3doaWNoO1xyXG4vKipcclxuICogQmVzdCBlZmZvcnQgYXR0ZW1wdCB0byBkZXRlcm1pbmUgd2hldGhlciBhIGZpbGUgZXhpc3RzIGFuZCBpcyBleGVjdXRhYmxlLlxyXG4gKiBAcGFyYW0gZmlsZVBhdGggICAgZmlsZSBwYXRoIHRvIGNoZWNrXHJcbiAqIEBwYXJhbSBleHRlbnNpb25zICBhZGRpdGlvbmFsIGZpbGUgZXh0ZW5zaW9ucyB0byB0cnlcclxuICogQHJldHVybiBpZiBmaWxlIGV4aXN0cyBhbmQgaXMgZXhlY3V0YWJsZSwgcmV0dXJucyB0aGUgZmlsZSBwYXRoLiBvdGhlcndpc2UgZW1wdHkgc3RyaW5nLlxyXG4gKi9cclxuZnVuY3Rpb24gX3RyeUdldEV4ZWN1dGFibGVQYXRoKGZpbGVQYXRoLCBleHRlbnNpb25zKSB7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIC8vIHRlc3QgZmlsZSBleGlzdHNcclxuICAgICAgICB2YXIgc3RhdHMgPSBmcy5zdGF0U3luYyhmaWxlUGF0aCk7XHJcbiAgICAgICAgaWYgKHN0YXRzLmlzRmlsZSgpKSB7XHJcbiAgICAgICAgICAgIGlmIChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicpIHtcclxuICAgICAgICAgICAgICAgIC8vIG9uIFdpbmRvd3MsIHRlc3QgZm9yIHZhbGlkIGV4dGVuc2lvblxyXG4gICAgICAgICAgICAgICAgdmFyIGlzRXhlY3V0YWJsZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgdmFyIGZpbGVOYW1lID0gcGF0aC5iYXNlbmFtZShmaWxlUGF0aCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgZG90SW5kZXggPSBmaWxlTmFtZS5sYXN0SW5kZXhPZignLicpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGRvdEluZGV4ID49IDApIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdXBwZXJFeHRfMSA9IGZpbGVOYW1lLnN1YnN0cihkb3RJbmRleCkudG9VcHBlckNhc2UoKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZXh0ZW5zaW9ucy5zb21lKGZ1bmN0aW9uICh2YWxpZEV4dCkgeyByZXR1cm4gdmFsaWRFeHQudG9VcHBlckNhc2UoKSA9PSB1cHBlckV4dF8xOyB9KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlsZVBhdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaWYgKGlzVW5peEV4ZWN1dGFibGUoc3RhdHMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbGVQYXRoO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgIGlmIChlcnIuY29kZSAhPSAnRU5PRU5UJykge1xyXG4gICAgICAgICAgICBfZGVidWcoXCJVbmV4cGVjdGVkIGVycm9yIGF0dGVtcHRpbmcgdG8gZGV0ZXJtaW5lIGlmIGV4ZWN1dGFibGUgZmlsZSBleGlzdHMgJ1wiICsgZmlsZVBhdGggKyBcIic6IFwiICsgZXJyKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyB0cnkgZWFjaCBleHRlbnNpb25cclxuICAgIHZhciBvcmlnaW5hbEZpbGVQYXRoID0gZmlsZVBhdGg7XHJcbiAgICBmb3IgKHZhciBfaSA9IDAsIGV4dGVuc2lvbnNfMSA9IGV4dGVuc2lvbnM7IF9pIDwgZXh0ZW5zaW9uc18xLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgIHZhciBleHRlbnNpb24gPSBleHRlbnNpb25zXzFbX2ldO1xyXG4gICAgICAgIHZhciBmb3VuZCA9IGZhbHNlO1xyXG4gICAgICAgIHZhciBmaWxlUGF0aF8xID0gb3JpZ2luYWxGaWxlUGF0aCArIGV4dGVuc2lvbjtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICB2YXIgc3RhdHMgPSBmcy5zdGF0U3luYyhmaWxlUGF0aF8xKTtcclxuICAgICAgICAgICAgaWYgKHN0YXRzLmlzRmlsZSgpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gcHJlc2VydmUgdGhlIGNhc2Ugb2YgdGhlIGFjdHVhbCBmaWxlIChzaW5jZSBhbiBleHRlbnNpb24gd2FzIGFwcGVuZGVkKVxyXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkaXJlY3RvcnkgPSBwYXRoLmRpcm5hbWUoZmlsZVBhdGhfMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB1cHBlck5hbWUgPSBwYXRoLmJhc2VuYW1lKGZpbGVQYXRoXzEpLnRvVXBwZXJDYXNlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIF9hID0gMCwgX2IgPSBmcy5yZWFkZGlyU3luYyhkaXJlY3RvcnkpOyBfYSA8IF9iLmxlbmd0aDsgX2ErKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFjdHVhbE5hbWUgPSBfYltfYV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXBwZXJOYW1lID09IGFjdHVhbE5hbWUudG9VcHBlckNhc2UoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVQYXRoXzEgPSBwYXRoLmpvaW4oZGlyZWN0b3J5LCBhY3R1YWxOYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9kZWJ1ZyhcIlVuZXhwZWN0ZWQgZXJyb3IgYXR0ZW1wdGluZyB0byBkZXRlcm1pbmUgdGhlIGFjdHVhbCBjYXNlIG9mIHRoZSBmaWxlICdcIiArIGZpbGVQYXRoXzEgKyBcIic6IFwiICsgZXJyKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbGVQYXRoXzE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNVbml4RXhlY3V0YWJsZShzdGF0cykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbGVQYXRoXzE7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgaWYgKGVyci5jb2RlICE9ICdFTk9FTlQnKSB7XHJcbiAgICAgICAgICAgICAgICBfZGVidWcoXCJVbmV4cGVjdGVkIGVycm9yIGF0dGVtcHRpbmcgdG8gZGV0ZXJtaW5lIGlmIGV4ZWN1dGFibGUgZmlsZSBleGlzdHMgJ1wiICsgZmlsZVBhdGhfMSArIFwiJzogXCIgKyBlcnIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuICcnO1xyXG59XHJcbi8vIG9uIE1hYy9MaW51eCwgdGVzdCB0aGUgZXhlY3V0ZSBiaXRcclxuLy8gICAgIFIgICBXICBYICBSICBXIFggUiBXIFhcclxuLy8gICAyNTYgMTI4IDY0IDMyIDE2IDggNCAyIDFcclxuZnVuY3Rpb24gaXNVbml4RXhlY3V0YWJsZShzdGF0cykge1xyXG4gICAgcmV0dXJuIChzdGF0cy5tb2RlICYgMSkgPiAwIHx8ICgoc3RhdHMubW9kZSAmIDgpID4gMCAmJiBzdGF0cy5naWQgPT09IHByb2Nlc3MuZ2V0Z2lkKCkpIHx8ICgoc3RhdHMubW9kZSAmIDY0KSA+IDAgJiYgc3RhdHMudWlkID09PSBwcm9jZXNzLmdldHVpZCgpKTtcclxufVxyXG5mdW5jdGlvbiBfbGVnYWN5RmluZEZpbGVzX2NvbnZlcnRQYXR0ZXJuVG9SZWdFeHAocGF0dGVybikge1xyXG4gICAgcGF0dGVybiA9IChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgPyBwYXR0ZXJuLnJlcGxhY2UoL1xcXFwvZywgJy8nKSA6IHBhdHRlcm4pIC8vIG5vcm1hbGl6ZSBzZXBhcmF0b3Igb24gV2luZG93c1xyXG4gICAgICAgIC5yZXBsYWNlKC9bLVxcL1xcXFxeJCorPy4oKXxbXFxde31dL2csICdcXFxcJCYnKSAvLyByZWdleCBlc2NhcGUgLSBmcm9tIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzU2MTQ5My9pcy10aGVyZS1hLXJlZ2V4cC1lc2NhcGUtZnVuY3Rpb24taW4tamF2YXNjcmlwdFxyXG4gICAgICAgIC5yZXBsYWNlKC9cXFxcXFwvXFxcXFxcKlxcXFxcXCpcXFxcXFwvL2csICcoKFxcLy4rLyl8KFxcLykpJykgLy8gcmVwbGFjZSBkaXJlY3RvcnkgZ2xvYnN0YXIsIGUuZy4gL2hlbGxvLyoqL3dvcmxkXHJcbiAgICAgICAgLnJlcGxhY2UoL1xcXFxcXCpcXFxcXFwqL2csICcuKicpIC8vIHJlcGxhY2UgcmVtYWluaW5nIGdsb2JzdGFycyB3aXRoIGEgd2lsZGNhcmQgdGhhdCBjYW4gc3BhbiBkaXJlY3Rvcnkgc2VwYXJhdG9ycywgZS5nLiAvaGVsbG8vKipkbGxcclxuICAgICAgICAucmVwbGFjZSgvXFxcXFxcKi9nLCAnW15cXC9dKicpIC8vIHJlcGxhY2UgYXN0ZXJpc2tzIHdpdGggYSB3aWxkY2FyZCB0aGF0IGNhbm5vdCBzcGFuIGRpcmVjdG9yeSBzZXBhcmF0b3JzLCBlLmcuIC9oZWxsby8qLmRsbFxyXG4gICAgICAgIC5yZXBsYWNlKC9cXFxcXFw/L2csICdbXlxcL10nKTsgLy8gcmVwbGFjZSBzaW5nbGUgY2hhcmFjdGVyIHdpbGRjYXJkcywgZS5nLiAvaGVsbG8vbG9nPy5kbGxcclxuICAgIHBhdHRlcm4gPSBcIl5cIiArIHBhdHRlcm4gKyBcIiRcIjtcclxuICAgIHZhciBmbGFncyA9IHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJyA/ICdpJyA6ICcnO1xyXG4gICAgcmV0dXJuIG5ldyBSZWdFeHAocGF0dGVybiwgZmxhZ3MpO1xyXG59XHJcbmV4cG9ydHMuX2xlZ2FjeUZpbmRGaWxlc19jb252ZXJ0UGF0dGVyblRvUmVnRXhwID0gX2xlZ2FjeUZpbmRGaWxlc19jb252ZXJ0UGF0dGVyblRvUmVnRXhwO1xyXG5mdW5jdGlvbiBfY2xvbmVNYXRjaE9wdGlvbnMobWF0Y2hPcHRpb25zKSB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIGRlYnVnOiBtYXRjaE9wdGlvbnMuZGVidWcsXHJcbiAgICAgICAgbm9icmFjZTogbWF0Y2hPcHRpb25zLm5vYnJhY2UsXHJcbiAgICAgICAgbm9nbG9ic3RhcjogbWF0Y2hPcHRpb25zLm5vZ2xvYnN0YXIsXHJcbiAgICAgICAgZG90OiBtYXRjaE9wdGlvbnMuZG90LFxyXG4gICAgICAgIG5vZXh0OiBtYXRjaE9wdGlvbnMubm9leHQsXHJcbiAgICAgICAgbm9jYXNlOiBtYXRjaE9wdGlvbnMubm9jYXNlLFxyXG4gICAgICAgIG5vbnVsbDogbWF0Y2hPcHRpb25zLm5vbnVsbCxcclxuICAgICAgICBtYXRjaEJhc2U6IG1hdGNoT3B0aW9ucy5tYXRjaEJhc2UsXHJcbiAgICAgICAgbm9jb21tZW50OiBtYXRjaE9wdGlvbnMubm9jb21tZW50LFxyXG4gICAgICAgIG5vbmVnYXRlOiBtYXRjaE9wdGlvbnMubm9uZWdhdGUsXHJcbiAgICAgICAgZmxpcE5lZ2F0ZTogbWF0Y2hPcHRpb25zLmZsaXBOZWdhdGVcclxuICAgIH07XHJcbn1cclxuZXhwb3J0cy5fY2xvbmVNYXRjaE9wdGlvbnMgPSBfY2xvbmVNYXRjaE9wdGlvbnM7XHJcbmZ1bmN0aW9uIF9nZXRGaW5kSW5mb0Zyb21QYXR0ZXJuKGRlZmF1bHRSb290LCBwYXR0ZXJuLCBtYXRjaE9wdGlvbnMpIHtcclxuICAgIC8vIHBhcmFtZXRlciB2YWxpZGF0aW9uXHJcbiAgICBpZiAoIWRlZmF1bHRSb290KSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdnZXRGaW5kUm9vdEZyb21QYXR0ZXJuKCkgcGFyYW1ldGVyIGRlZmF1bHRSb290IGNhbm5vdCBiZSBlbXB0eScpO1xyXG4gICAgfVxyXG4gICAgaWYgKCFwYXR0ZXJuKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdnZXRGaW5kUm9vdEZyb21QYXR0ZXJuKCkgcGFyYW1ldGVyIHBhdHRlcm4gY2Fubm90IGJlIGVtcHR5Jyk7XHJcbiAgICB9XHJcbiAgICBpZiAoIW1hdGNoT3B0aW9ucy5ub2JyYWNlKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdnZXRGaW5kUm9vdEZyb21QYXR0ZXJuKCkgZXhwZWN0ZWQgbWF0Y2hPcHRpb25zLm5vYnJhY2UgdG8gYmUgdHJ1ZScpO1xyXG4gICAgfVxyXG4gICAgLy8gZm9yIHRoZSBzYWtlIG9mIGRldGVybWluaW5nIHRoZSBmaW5kUGF0aCwgcHJldGVuZCBub2Nhc2U9ZmFsc2VcclxuICAgIG1hdGNoT3B0aW9ucyA9IF9jbG9uZU1hdGNoT3B0aW9ucyhtYXRjaE9wdGlvbnMpO1xyXG4gICAgbWF0Y2hPcHRpb25zLm5vY2FzZSA9IGZhbHNlO1xyXG4gICAgLy8gY2hlY2sgaWYgYmFzZW5hbWUgb25seSBhbmQgbWF0Y2hCYXNlPXRydWVcclxuICAgIGlmIChtYXRjaE9wdGlvbnMubWF0Y2hCYXNlICYmXHJcbiAgICAgICAgIV9pc1Jvb3RlZChwYXR0ZXJuKSAmJlxyXG4gICAgICAgIChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgPyBwYXR0ZXJuLnJlcGxhY2UoL1xcXFwvZywgJy8nKSA6IHBhdHRlcm4pLmluZGV4T2YoJy8nKSA8IDApIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBhZGp1c3RlZFBhdHRlcm46IHBhdHRlcm4sXHJcbiAgICAgICAgICAgIGZpbmRQYXRoOiBkZWZhdWx0Um9vdCxcclxuICAgICAgICAgICAgc3RhdE9ubHk6IGZhbHNlLFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICAvLyB0aGUgdGVjaG5pcXVlIGFwcGxpZWQgYnkgdGhpcyBmdW5jdGlvbiBpcyB0byB1c2UgdGhlIGluZm9ybWF0aW9uIG9uIHRoZSBNaW5pbWF0Y2ggb2JqZWN0IGRldGVybWluZVxyXG4gICAgLy8gdGhlIGZpbmRQYXRoLiBNaW5pbWF0Y2ggYnJlYWtzIHRoZSBwYXR0ZXJuIGludG8gcGF0aCBzZWdtZW50cywgYW5kIGV4cG9zZXMgaW5mb3JtYXRpb24gYWJvdXQgd2hpY2hcclxuICAgIC8vIHNlZ21lbnRzIGFyZSBsaXRlcmFsIHZzIHBhdHRlcm5zLlxyXG4gICAgLy9cclxuICAgIC8vIG5vdGUsIHRoZSB0ZWNobmlxdWUgY3VycmVudGx5IGltcG9zZXMgYSBsaW1pdGF0aW9uIGZvciBkcml2ZS1yZWxhdGl2ZSBwYXRocyB3aXRoIGEgZ2xvYiBpbiB0aGVcclxuICAgIC8vIGZpcnN0IHNlZ21lbnQsIGUuZy4gQzpoZWxsbyovd29ybGQuIGl0J3MgZmVhc2libGUgdG8gb3ZlcmNvbWUgdGhpcyBsaW1pdGF0aW9uLCBidXQgaXMgbGVmdCB1bnNvbHZlZFxyXG4gICAgLy8gZm9yIG5vdy5cclxuICAgIHZhciBtaW5pbWF0Y2hPYmogPSBuZXcgbWluaW1hdGNoLk1pbmltYXRjaChwYXR0ZXJuLCBtYXRjaE9wdGlvbnMpO1xyXG4gICAgLy8gdGhlIFwic2V0XCIgcHJvcGVydHkgaXMgYW4gYXJyYXkgb2YgYXJyYXlzIG9mIHBhcnNlZCBwYXRoIHNlZ21lbnQgaW5mby4gdGhlIG91dGVyIGFycmF5IHNob3VsZCBvbmx5XHJcbiAgICAvLyBjb250YWluIG9uZSBpdGVtLCBvdGhlcndpc2Ugc29tZXRoaW5nIHdlbnQgd3JvbmcuIGJyYWNlIGV4cGFuc2lvbiBjYW4gcmVzdWx0IGluIG11bHRpcGxlIGFycmF5cyxcclxuICAgIC8vIGJ1dCB0aGF0IHNob3VsZCBiZSB0dXJuZWQgb2ZmIGJ5IHRoZSB0aW1lIHRoaXMgZnVuY3Rpb24gaXMgcmVhY2hlZC5cclxuICAgIGlmIChtaW5pbWF0Y2hPYmouc2V0Lmxlbmd0aCAhPSAxKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdnZXRGaW5kUm9vdEZyb21QYXR0ZXJuKCkgZXhwZWN0ZWQgTWluaW1hdGNoKC4uLikuc2V0Lmxlbmd0aCB0byBiZSAxLiBBY3R1YWw6ICcgKyBtaW5pbWF0Y2hPYmouc2V0Lmxlbmd0aCk7XHJcbiAgICB9XHJcbiAgICB2YXIgbGl0ZXJhbFNlZ21lbnRzID0gW107XHJcbiAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gbWluaW1hdGNoT2JqLnNldFswXTsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICB2YXIgcGFyc2VkU2VnbWVudCA9IF9hW19pXTtcclxuICAgICAgICBpZiAodHlwZW9mIHBhcnNlZFNlZ21lbnQgPT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgLy8gdGhlIGl0ZW0gaXMgYSBzdHJpbmcgd2hlbiB0aGUgb3JpZ2luYWwgaW5wdXQgZm9yIHRoZSBwYXRoIHNlZ21lbnQgZG9lcyBub3QgY29udGFpbiBhbnlcclxuICAgICAgICAgICAgLy8gdW5lc2NhcGVkIGdsb2IgY2hhcmFjdGVycy5cclxuICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgLy8gbm90ZSwgdGhlIHN0cmluZyBoZXJlIGlzIGFscmVhZHkgdW5lc2NhcGVkIChpLmUuIGdsb2IgZXNjYXBpbmcgcmVtb3ZlZCksIHNvIGl0IGlzIHJlYWR5XHJcbiAgICAgICAgICAgIC8vIHRvIHBhc3MgdG8gZmluZCgpIGFzLWlzLiBmb3IgZXhhbXBsZSwgYW4gaW5wdXQgc3RyaW5nICdoZWxsb1xcXFwqd29ybGQnID0+ICdoZWxsbyp3b3JsZCcuXHJcbiAgICAgICAgICAgIGxpdGVyYWxTZWdtZW50cy5wdXNoKHBhcnNlZFNlZ21lbnQpO1xyXG4gICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICB9XHJcbiAgICAvLyBqb2luIHRoZSBsaXRlcmFsIHNlZ21lbnRzIGJhY2sgdG9nZXRoZXIuIE1pbmltYXRjaCBjb252ZXJ0cyAnXFwnIHRvICcvJyBvbiBXaW5kb3dzLCB0aGVuIHNxdWFzaGVzXHJcbiAgICAvLyBjb25zZXF1ZXRpdmUgc2xhc2hlcywgYW5kIGZpbmFsbHkgc3BsaXRzIG9uIHNsYXNoLiB0aGlzIG1lYW5zIHRoYXQgVU5DIGZvcm1hdCBpcyBsb3N0LCBidXQgY2FuXHJcbiAgICAvLyBiZSBkZXRlY3RlZCBmcm9tIHRoZSBvcmlnaW5hbCBwYXR0ZXJuLlxyXG4gICAgdmFyIGpvaW5lZFNlZ21lbnRzID0gbGl0ZXJhbFNlZ21lbnRzLmpvaW4oJy8nKTtcclxuICAgIGlmIChqb2luZWRTZWdtZW50cyAmJiBwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgJiYgX3N0YXJ0c1dpdGgocGF0dGVybi5yZXBsYWNlKC9cXFxcL2csICcvJyksICcvLycpKSB7XHJcbiAgICAgICAgam9pbmVkU2VnbWVudHMgPSAnLycgKyBqb2luZWRTZWdtZW50czsgLy8gcmVzdG9yZSBVTkMgZm9ybWF0XHJcbiAgICB9XHJcbiAgICAvLyBkZXRlcm1pbmUgdGhlIGZpbmQgcGF0aFxyXG4gICAgdmFyIGZpbmRQYXRoO1xyXG4gICAgaWYgKF9pc1Jvb3RlZChwYXR0ZXJuKSkgeyAvLyB0aGUgcGF0dGVybiB3YXMgcm9vdGVkXHJcbiAgICAgICAgZmluZFBhdGggPSBqb2luZWRTZWdtZW50cztcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGpvaW5lZFNlZ21lbnRzKSB7IC8vIHRoZSBwYXR0ZXJuIHdhcyBub3Qgcm9vdGVkLCBhbmQgbGl0ZXJhbCBzZWdtZW50cyB3ZXJlIGZvdW5kXHJcbiAgICAgICAgZmluZFBhdGggPSBfZW5zdXJlUm9vdGVkKGRlZmF1bHRSb290LCBqb2luZWRTZWdtZW50cyk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHsgLy8gdGhlIHBhdHRlcm4gd2FzIG5vdCByb290ZWQsIGFuZCBubyBsaXRlcmFsIHNlZ21lbnRzIHdlcmUgZm91bmRcclxuICAgICAgICBmaW5kUGF0aCA9IGRlZmF1bHRSb290O1xyXG4gICAgfVxyXG4gICAgLy8gY2xlYW4gdXAgdGhlIHBhdGhcclxuICAgIGlmIChmaW5kUGF0aCkge1xyXG4gICAgICAgIGZpbmRQYXRoID0gX2dldERpcmVjdG9yeU5hbWUoX2Vuc3VyZVJvb3RlZChmaW5kUGF0aCwgJ18nKSk7IC8vIGhhY2sgdG8gcmVtb3ZlIHVubmVjZXNzYXJ5IHRyYWlsaW5nIHNsYXNoXHJcbiAgICAgICAgZmluZFBhdGggPSBfbm9ybWFsaXplU2VwYXJhdG9ycyhmaW5kUGF0aCk7IC8vIG5vcm1hbGl6ZSBzbGFzaGVzXHJcbiAgICB9XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIGFkanVzdGVkUGF0dGVybjogX2Vuc3VyZVBhdHRlcm5Sb290ZWQoZGVmYXVsdFJvb3QsIHBhdHRlcm4pLFxyXG4gICAgICAgIGZpbmRQYXRoOiBmaW5kUGF0aCxcclxuICAgICAgICBzdGF0T25seTogbGl0ZXJhbFNlZ21lbnRzLmxlbmd0aCA9PSBtaW5pbWF0Y2hPYmouc2V0WzBdLmxlbmd0aCxcclxuICAgIH07XHJcbn1cclxuZXhwb3J0cy5fZ2V0RmluZEluZm9Gcm9tUGF0dGVybiA9IF9nZXRGaW5kSW5mb0Zyb21QYXR0ZXJuO1xyXG5mdW5jdGlvbiBfZW5zdXJlUGF0dGVyblJvb3RlZChyb290LCBwKSB7XHJcbiAgICBpZiAoIXJvb3QpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Vuc3VyZVBhdHRlcm5Sb290ZWQoKSBwYXJhbWV0ZXIgXCJyb290XCIgY2Fubm90IGJlIGVtcHR5Jyk7XHJcbiAgICB9XHJcbiAgICBpZiAoIXApIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Vuc3VyZVBhdHRlcm5Sb290ZWQoKSBwYXJhbWV0ZXIgXCJwXCIgY2Fubm90IGJlIGVtcHR5Jyk7XHJcbiAgICB9XHJcbiAgICBpZiAoX2lzUm9vdGVkKHApKSB7XHJcbiAgICAgICAgcmV0dXJuIHA7XHJcbiAgICB9XHJcbiAgICAvLyBub3JtYWxpemUgcm9vdFxyXG4gICAgcm9vdCA9IF9ub3JtYWxpemVTZXBhcmF0b3JzKHJvb3QpO1xyXG4gICAgLy8gZXNjYXBlIHNwZWNpYWwgZ2xvYiBjaGFyYWN0ZXJzXHJcbiAgICByb290ID0gKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJyA/IHJvb3QgOiByb290LnJlcGxhY2UoL1xcXFwvZywgJ1xcXFxcXFxcJykpIC8vIGVzY2FwZSAnXFwnIG9uIE9TWC9MaW51eFxyXG4gICAgICAgIC5yZXBsYWNlKC8oXFxbKSg/PVteXFwvXStcXF0pL2csICdbW10nKSAvLyBlc2NhcGUgJ1snIHdoZW4gJ10nIGZvbGxvd3Mgd2l0aGluIHRoZSBwYXRoIHNlZ21lbnRcclxuICAgICAgICAucmVwbGFjZSgvXFw/L2csICdbP10nKSAvLyBlc2NhcGUgJz8nXHJcbiAgICAgICAgLnJlcGxhY2UoL1xcKi9nLCAnWypdJykgLy8gZXNjYXBlICcqJ1xyXG4gICAgICAgIC5yZXBsYWNlKC9cXCtcXCgvZywgJ1srXSgnKSAvLyBlc2NhcGUgJysoJ1xyXG4gICAgICAgIC5yZXBsYWNlKC9AXFwoL2csICdbQF0oJykgLy8gZXNjYXBlICdAKCdcclxuICAgICAgICAucmVwbGFjZSgvIVxcKC9nLCAnWyFdKCcpOyAvLyBlc2NhcGUgJyEoJ1xyXG4gICAgcmV0dXJuIF9lbnN1cmVSb290ZWQocm9vdCwgcCk7XHJcbn1cclxuZXhwb3J0cy5fZW5zdXJlUGF0dGVyblJvb3RlZCA9IF9lbnN1cmVQYXR0ZXJuUm9vdGVkO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gUG9wdWxhdGUgdGhlIHZhdWx0IHdpdGggc2Vuc2l0aXZlIGRhdGEuICBJbnB1dHMgYW5kIEVuZHBvaW50c1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuZnVuY3Rpb24gX2xvYWREYXRhKCkge1xyXG4gICAgLy8gaW4gYWdlbnQsIHByZWZlciBUZW1wRGlyZWN0b3J5IHRoZW4gd29ya0ZvbGRlci5cclxuICAgIC8vIEluIGludGVyYWN0aXZlIGRldiBtb2RlLCBpdCB3b24ndCBiZVxyXG4gICAgdmFyIGtleVBhdGggPSBfZ2V0VmFyaWFibGUoXCJhZ2VudC5UZW1wRGlyZWN0b3J5XCIpIHx8IF9nZXRWYXJpYWJsZShcImFnZW50LndvcmtGb2xkZXJcIikgfHwgcHJvY2Vzcy5jd2QoKTtcclxuICAgIGV4cG9ydHMuX3ZhdWx0ID0gbmV3IHZtLlZhdWx0KGtleVBhdGgpO1xyXG4gICAgZXhwb3J0cy5fa25vd25WYXJpYWJsZU1hcCA9IHt9O1xyXG4gICAgX2RlYnVnKCdsb2FkaW5nIGlucHV0cyBhbmQgZW5kcG9pbnRzJyk7XHJcbiAgICB2YXIgbG9hZGVkID0gMDtcclxuICAgIGZvciAodmFyIGVudnZhciBpbiBwcm9jZXNzLmVudikge1xyXG4gICAgICAgIGlmIChfc3RhcnRzV2l0aChlbnZ2YXIsICdJTlBVVF8nKSB8fFxyXG4gICAgICAgICAgICBfc3RhcnRzV2l0aChlbnZ2YXIsICdFTkRQT0lOVF9BVVRIXycpIHx8XHJcbiAgICAgICAgICAgIF9zdGFydHNXaXRoKGVudnZhciwgJ1NFQ1VSRUZJTEVfVElDS0VUXycpIHx8XHJcbiAgICAgICAgICAgIF9zdGFydHNXaXRoKGVudnZhciwgJ1NFQ1JFVF8nKSB8fFxyXG4gICAgICAgICAgICBfc3RhcnRzV2l0aChlbnZ2YXIsICdWU1RTX1RBU0tWQVJJQUJMRV8nKSkge1xyXG4gICAgICAgICAgICAvLyBSZWNvcmQgdGhlIHNlY3JldCB2YXJpYWJsZSBtZXRhZGF0YS4gVGhpcyBpcyByZXF1aXJlZCBieSBnZXRWYXJpYWJsZSB0byBrbm93IHdoZXRoZXJcclxuICAgICAgICAgICAgLy8gdG8gcmV0cmlldmUgdGhlIHZhbHVlIGZyb20gdGhlIHZhdWx0LiBJbiBhIDIuMTA0LjEgYWdlbnQgb3IgaGlnaGVyLCB0aGlzIG1ldGFkYXRhIHdpbGxcclxuICAgICAgICAgICAgLy8gYmUgb3ZlcndyaXR0ZW4gd2hlbiB0aGUgVlNUU19TRUNSRVRfVkFSSUFCTEVTIGVudiB2YXIgaXMgcHJvY2Vzc2VkIGJlbG93LlxyXG4gICAgICAgICAgICBpZiAoX3N0YXJ0c1dpdGgoZW52dmFyLCAnU0VDUkVUXycpKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgdmFyaWFibGVOYW1lID0gZW52dmFyLnN1YnN0cmluZygnU0VDUkVUXycubGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgIGlmICh2YXJpYWJsZU5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRlY2huaWNhbGx5IG5vdCB0aGUgdmFyaWFibGUgbmFtZSAoaGFzIHVuZGVyc2NvcmVzIGluc3RlYWQgb2YgZG90cyksXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gYnV0IGl0J3MgZ29vZCBlbm91Z2ggdG8gbWFrZSBnZXRWYXJpYWJsZSB3b3JrIGluIGEgcHJlLTIuMTA0LjEgYWdlbnQgd2hlcmVcclxuICAgICAgICAgICAgICAgICAgICAvLyB0aGUgVlNUU19TRUNSRVRfVkFSSUFCTEVTIGVudiB2YXIgaXMgbm90IGRlZmluZWQuXHJcbiAgICAgICAgICAgICAgICAgICAgZXhwb3J0cy5fa25vd25WYXJpYWJsZU1hcFtfZ2V0VmFyaWFibGVLZXkodmFyaWFibGVOYW1lKV0gPSB7IG5hbWU6IHZhcmlhYmxlTmFtZSwgc2VjcmV0OiB0cnVlIH07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gc3RvcmUgdGhlIHNlY3JldFxyXG4gICAgICAgICAgICB2YXIgdmFsdWUgPSBwcm9jZXNzLmVudltlbnZ2YXJdO1xyXG4gICAgICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICsrbG9hZGVkO1xyXG4gICAgICAgICAgICAgICAgX2RlYnVnKCdsb2FkaW5nICcgKyBlbnZ2YXIpO1xyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5fdmF1bHQuc3RvcmVTZWNyZXQoZW52dmFyLCB2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICBkZWxldGUgcHJvY2Vzcy5lbnZbZW52dmFyXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIF9kZWJ1ZygnbG9hZGVkICcgKyBsb2FkZWQpO1xyXG4gICAgLy8gc3RvcmUgcHVibGljIHZhcmlhYmxlIG1ldGFkYXRhXHJcbiAgICB2YXIgbmFtZXM7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIG5hbWVzID0gSlNPTi5wYXJzZShwcm9jZXNzLmVudlsnVlNUU19QVUJMSUNfVkFSSUFCTEVTJ10gfHwgJ1tdJyk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gcGFyc2UgVlNUU19QVUJMSUNfVkFSSUFCTEVTIGFzIEpTT04uICcgKyBlcnIpOyAvLyBtYXkgb2NjdXIgZHVyaW5nIGludGVyYWN0aXZlIHRlc3RpbmdcclxuICAgIH1cclxuICAgIG5hbWVzLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcclxuICAgICAgICBleHBvcnRzLl9rbm93blZhcmlhYmxlTWFwW19nZXRWYXJpYWJsZUtleShuYW1lKV0gPSB7IG5hbWU6IG5hbWUsIHNlY3JldDogZmFsc2UgfTtcclxuICAgIH0pO1xyXG4gICAgZGVsZXRlIHByb2Nlc3MuZW52WydWU1RTX1BVQkxJQ19WQVJJQUJMRVMnXTtcclxuICAgIC8vIHN0b3JlIHNlY3JldCB2YXJpYWJsZSBtZXRhZGF0YVxyXG4gICAgdHJ5IHtcclxuICAgICAgICBuYW1lcyA9IEpTT04ucGFyc2UocHJvY2Vzcy5lbnZbJ1ZTVFNfU0VDUkVUX1ZBUklBQkxFUyddIHx8ICdbXScpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIHBhcnNlIFZTVFNfU0VDUkVUX1ZBUklBQkxFUyBhcyBKU09OLiAnICsgZXJyKTsgLy8gbWF5IG9jY3VyIGR1cmluZyBpbnRlcmFjdGl2ZSB0ZXN0aW5nXHJcbiAgICB9XHJcbiAgICBuYW1lcy5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XHJcbiAgICAgICAgZXhwb3J0cy5fa25vd25WYXJpYWJsZU1hcFtfZ2V0VmFyaWFibGVLZXkobmFtZSldID0geyBuYW1lOiBuYW1lLCBzZWNyZXQ6IHRydWUgfTtcclxuICAgIH0pO1xyXG4gICAgZGVsZXRlIHByb2Nlc3MuZW52WydWU1RTX1NFQ1JFVF9WQVJJQUJMRVMnXTtcclxuICAgIC8vIGF2b2lkIGxvYWRpbmcgdHdpY2UgKG92ZXJ3cml0ZXMgLnRhc2trZXkpXHJcbiAgICBnbG9iYWxbJ192c3RzX3Rhc2tfbGliX2xvYWRlZCddID0gdHJ1ZTtcclxufVxyXG5leHBvcnRzLl9sb2FkRGF0YSA9IF9sb2FkRGF0YTtcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBJbnRlcm5hbCBwYXRoIGhlbHBlcnMuXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuZnVuY3Rpb24gX2Vuc3VyZVJvb3RlZChyb290LCBwKSB7XHJcbiAgICBpZiAoIXJvb3QpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Vuc3VyZVJvb3RlZCgpIHBhcmFtZXRlciBcInJvb3RcIiBjYW5ub3QgYmUgZW1wdHknKTtcclxuICAgIH1cclxuICAgIGlmICghcCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZW5zdXJlUm9vdGVkKCkgcGFyYW1ldGVyIFwicFwiIGNhbm5vdCBiZSBlbXB0eScpO1xyXG4gICAgfVxyXG4gICAgaWYgKF9pc1Jvb3RlZChwKSkge1xyXG4gICAgICAgIHJldHVybiBwO1xyXG4gICAgfVxyXG4gICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJyAmJiByb290Lm1hdGNoKC9eW0EtWl06JC9pKSkgeyAvLyBlLmcuIEM6XHJcbiAgICAgICAgcmV0dXJuIHJvb3QgKyBwO1xyXG4gICAgfVxyXG4gICAgLy8gZW5zdXJlIHJvb3QgZW5kcyB3aXRoIGEgc2VwYXJhdG9yXHJcbiAgICBpZiAoX2VuZHNXaXRoKHJvb3QsICcvJykgfHwgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJyAmJiBfZW5kc1dpdGgocm9vdCwgJ1xcXFwnKSkpIHtcclxuICAgICAgICAvLyByb290IGFscmVhZHkgZW5kcyB3aXRoIGEgc2VwYXJhdG9yXHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICByb290ICs9IHBhdGguc2VwOyAvLyBhcHBlbmQgc2VwYXJhdG9yXHJcbiAgICB9XHJcbiAgICByZXR1cm4gcm9vdCArIHA7XHJcbn1cclxuZXhwb3J0cy5fZW5zdXJlUm9vdGVkID0gX2Vuc3VyZVJvb3RlZDtcclxuLyoqXHJcbiAqIERldGVybWluZXMgdGhlIHBhcmVudCBwYXRoIGFuZCB0cmltcyB0cmFpbGluZyBzbGFzaGVzICh3aGVuIHNhZmUpLiBQYXRoIHNlcGFyYXRvcnMgYXJlIG5vcm1hbGl6ZWRcclxuICogaW4gdGhlIHJlc3VsdC4gVGhpcyBmdW5jdGlvbiB3b3JrcyBzaW1pbGFyIHRvIHRoZSAuTkVUIFN5c3RlbS5JTy5QYXRoLkdldERpcmVjdG9yeU5hbWUoKSBtZXRob2QuXHJcbiAqIEZvciBleGFtcGxlLCBDOlxcaGVsbG9cXHdvcmxkXFwgcmV0dXJucyBDOlxcaGVsbG9cXHdvcmxkICh0cmFpbGluZyBzbGFzaCByZW1vdmVkKS4gUmV0dXJucyBlbXB0eSB3aGVuXHJcbiAqIG5vIGhpZ2hlciBkaXJlY3RvcnkgY2FuIGJlIGRldGVybWluZWQuXHJcbiAqL1xyXG5mdW5jdGlvbiBfZ2V0RGlyZWN0b3J5TmFtZShwKSB7XHJcbiAgICAvLyBzaG9ydC1jaXJjdWl0IGlmIGVtcHR5XHJcbiAgICBpZiAoIXApIHtcclxuICAgICAgICByZXR1cm4gJyc7XHJcbiAgICB9XHJcbiAgICAvLyBub3JtYWxpemUgc2VwYXJhdG9yc1xyXG4gICAgcCA9IF9ub3JtYWxpemVTZXBhcmF0b3JzKHApO1xyXG4gICAgLy8gb24gV2luZG93cywgdGhlIGdvYWwgb2YgdGhpcyBmdW5jdGlvbiBpcyB0byBtYXRjaCB0aGUgYmVoYXZpb3Igb2ZcclxuICAgIC8vIFtTeXN0ZW0uSU8uUGF0aF06OkdldERpcmVjdG9yeU5hbWUoKSwgZS5nLlxyXG4gICAgLy8gICAgICBDOi8gICAgICAgICAgICAgPT5cclxuICAgIC8vICAgICAgQzovaGVsbG8gICAgICAgID0+IEM6XFxcclxuICAgIC8vICAgICAgQzovaGVsbG8vICAgICAgID0+IEM6XFxoZWxsb1xyXG4gICAgLy8gICAgICBDOi9oZWxsby93b3JsZCAgPT4gQzpcXGhlbGxvXHJcbiAgICAvLyAgICAgIEM6L2hlbGxvL3dvcmxkLyA9PiBDOlxcaGVsbG9cXHdvcmxkXHJcbiAgICAvLyAgICAgIEM6ICAgICAgICAgICAgICA9PlxyXG4gICAgLy8gICAgICBDOmhlbGxvICAgICAgICAgPT4gQzpcclxuICAgIC8vICAgICAgQzpoZWxsby8gICAgICAgID0+IEM6aGVsbG9cclxuICAgIC8vICAgICAgLyAgICAgICAgICAgICAgID0+XHJcbiAgICAvLyAgICAgIC9oZWxsbyAgICAgICAgICA9PiBcXFxyXG4gICAgLy8gICAgICAvaGVsbG8vICAgICAgICAgPT4gXFxoZWxsb1xyXG4gICAgLy8gICAgICAvL2hlbGxvICAgICAgICAgPT5cclxuICAgIC8vICAgICAgLy9oZWxsby8gICAgICAgID0+XHJcbiAgICAvLyAgICAgIC8vaGVsbG8vd29ybGQgICA9PlxyXG4gICAgLy8gICAgICAvL2hlbGxvL3dvcmxkLyAgPT4gXFxcXGhlbGxvXFx3b3JsZFxyXG4gICAgLy9cclxuICAgIC8vIHVuZm9ydHVuYXRlbHksIHBhdGguZGlybmFtZSgpIGNhbid0IHNpbXBseSBiZSB1c2VkLiBmb3IgZXhhbXBsZSwgb24gV2luZG93c1xyXG4gICAgLy8gaXQgeWllbGRzIGRpZmZlcmVudCByZXN1bHRzIGZyb20gUGF0aC5HZXREaXJlY3RvcnlOYW1lOlxyXG4gICAgLy8gICAgICBDOi8gICAgICAgICAgICAgPT4gQzovXHJcbiAgICAvLyAgICAgIEM6L2hlbGxvICAgICAgICA9PiBDOi9cclxuICAgIC8vICAgICAgQzovaGVsbG8vICAgICAgID0+IEM6L1xyXG4gICAgLy8gICAgICBDOi9oZWxsby93b3JsZCAgPT4gQzovaGVsbG9cclxuICAgIC8vICAgICAgQzovaGVsbG8vd29ybGQvID0+IEM6L2hlbGxvXHJcbiAgICAvLyAgICAgIEM6ICAgICAgICAgICAgICA9PiBDOlxyXG4gICAgLy8gICAgICBDOmhlbGxvICAgICAgICAgPT4gQzpcclxuICAgIC8vICAgICAgQzpoZWxsby8gICAgICAgID0+IEM6XHJcbiAgICAvLyAgICAgIC8gICAgICAgICAgICAgICA9PiAvXHJcbiAgICAvLyAgICAgIC9oZWxsbyAgICAgICAgICA9PiAvXHJcbiAgICAvLyAgICAgIC9oZWxsby8gICAgICAgICA9PiAvXHJcbiAgICAvLyAgICAgIC8vaGVsbG8gICAgICAgICA9PiAvXHJcbiAgICAvLyAgICAgIC8vaGVsbG8vICAgICAgICA9PiAvXHJcbiAgICAvLyAgICAgIC8vaGVsbG8vd29ybGQgICA9PiAvL2hlbGxvL3dvcmxkXHJcbiAgICAvLyAgICAgIC8vaGVsbG8vd29ybGQvICA9PiAvL2hlbGxvL3dvcmxkL1xyXG4gICAgLy8gICAgICAvL2hlbGxvL3dvcmxkL2FnYWluID0+IC8vaGVsbG8vd29ybGQvXHJcbiAgICAvLyAgICAgIC8vaGVsbG8vd29ybGQvYWdhaW4vID0+IC8vaGVsbG8vd29ybGQvXHJcbiAgICAvLyAgICAgIC8vaGVsbG8vd29ybGQvYWdhaW4vYWdhaW4gPT4gLy9oZWxsby93b3JsZC9hZ2FpblxyXG4gICAgLy8gICAgICAvL2hlbGxvL3dvcmxkL2FnYWluL2FnYWluLyA9PiAvL2hlbGxvL3dvcmxkL2FnYWluXHJcbiAgICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInKSB7XHJcbiAgICAgICAgaWYgKC9eW0EtWl06XFxcXD9bXlxcXFxdKyQvaS50ZXN0KHApKSB7IC8vIGUuZy4gQzpcXGhlbGxvIG9yIEM6aGVsbG9cclxuICAgICAgICAgICAgcmV0dXJuIHAuY2hhckF0KDIpID09ICdcXFxcJyA/IHAuc3Vic3RyaW5nKDAsIDMpIDogcC5zdWJzdHJpbmcoMCwgMik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKC9eW0EtWl06XFxcXD8kL2kudGVzdChwKSkgeyAvLyBlLmcuIEM6XFwgb3IgQzpcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgbGFzdFNsYXNoSW5kZXggPSBwLmxhc3RJbmRleE9mKCdcXFxcJyk7XHJcbiAgICAgICAgaWYgKGxhc3RTbGFzaEluZGV4IDwgMCkgeyAvLyBmaWxlIG5hbWUgb25seVxyXG4gICAgICAgICAgICByZXR1cm4gJyc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHAgPT0gJ1xcXFwnKSB7IC8vIHJlbGF0aXZlIHJvb3RcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChsYXN0U2xhc2hJbmRleCA9PSAwKSB7IC8vIGUuZy4gXFxcXGhlbGxvXHJcbiAgICAgICAgICAgIHJldHVybiAnXFxcXCc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKC9eXFxcXFxcXFxbXlxcXFxdKyhcXFxcW15cXFxcXSopPyQvLnRlc3QocCkpIHsgLy8gVU5DIHJvb3QsIGUuZy4gXFxcXGhlbGxvIG9yIFxcXFxoZWxsb1xcIG9yIFxcXFxoZWxsb1xcd29ybGRcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcC5zdWJzdHJpbmcoMCwgbGFzdFNsYXNoSW5kZXgpOyAvLyBlLmcuIGhlbGxvXFx3b3JsZCA9PiBoZWxsbyBvciBoZWxsb1xcd29ybGRcXCA9PiBoZWxsb1xcd29ybGRcclxuICAgICAgICAvLyBub3RlLCB0aGlzIG1lYW5zIHRyYWlsaW5nIHNsYXNoZXMgZm9yIG5vbi1yb290IGRpcmVjdG9yaWVzXHJcbiAgICAgICAgLy8gKGkuZS4gbm90IEM6XFwsIFxcLCBvciBcXFxcdW5jXFwpIHdpbGwgc2ltcGx5IGJlIHJlbW92ZWQuXHJcbiAgICB9XHJcbiAgICAvLyBPU1gvTGludXhcclxuICAgIGlmIChwLmluZGV4T2YoJy8nKSA8IDApIHsgLy8gZmlsZSBuYW1lIG9ubHlcclxuICAgICAgICByZXR1cm4gJyc7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChwID09ICcvJykge1xyXG4gICAgICAgIHJldHVybiAnJztcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKF9lbmRzV2l0aChwLCAnLycpKSB7XHJcbiAgICAgICAgcmV0dXJuIHAuc3Vic3RyaW5nKDAsIHAubGVuZ3RoIC0gMSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcGF0aC5kaXJuYW1lKHApO1xyXG59XHJcbmV4cG9ydHMuX2dldERpcmVjdG9yeU5hbWUgPSBfZ2V0RGlyZWN0b3J5TmFtZTtcclxuLyoqXHJcbiAqIE9uIE9TWC9MaW51eCwgdHJ1ZSBpZiBwYXRoIHN0YXJ0cyB3aXRoICcvJy4gT24gV2luZG93cywgdHJ1ZSBmb3IgcGF0aHMgbGlrZTpcclxuICogXFwsIFxcaGVsbG8sIFxcXFxoZWxsb1xcc2hhcmUsIEM6LCBhbmQgQzpcXGhlbGxvIChhbmQgY29ycmVzcG9uZGluZyBhbHRlcm5hdGUgc2VwYXJhdG9yIGNhc2VzKS5cclxuICovXHJcbmZ1bmN0aW9uIF9pc1Jvb3RlZChwKSB7XHJcbiAgICBwID0gX25vcm1hbGl6ZVNlcGFyYXRvcnMocCk7XHJcbiAgICBpZiAoIXApIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2lzUm9vdGVkKCkgcGFyYW1ldGVyIFwicFwiIGNhbm5vdCBiZSBlbXB0eScpO1xyXG4gICAgfVxyXG4gICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJykge1xyXG4gICAgICAgIHJldHVybiBfc3RhcnRzV2l0aChwLCAnXFxcXCcpIHx8IC8vIGUuZy4gXFwgb3IgXFxoZWxsbyBvciBcXFxcaGVsbG9cclxuICAgICAgICAgICAgL15bQS1aXTovaS50ZXN0KHApOyAvLyBlLmcuIEM6IG9yIEM6XFxoZWxsb1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIF9zdGFydHNXaXRoKHAsICcvJyk7IC8vIGUuZy4gL2hlbGxvXHJcbn1cclxuZXhwb3J0cy5faXNSb290ZWQgPSBfaXNSb290ZWQ7XHJcbmZ1bmN0aW9uIF9ub3JtYWxpemVTZXBhcmF0b3JzKHApIHtcclxuICAgIHAgPSBwIHx8ICcnO1xyXG4gICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJykge1xyXG4gICAgICAgIC8vIGNvbnZlcnQgc2xhc2hlcyBvbiBXaW5kb3dzXHJcbiAgICAgICAgcCA9IHAucmVwbGFjZSgvXFwvL2csICdcXFxcJyk7XHJcbiAgICAgICAgLy8gcmVtb3ZlIHJlZHVuZGFudCBzbGFzaGVzXHJcbiAgICAgICAgdmFyIGlzVW5jID0gL15cXFxcXFxcXCtbXlxcXFxdLy50ZXN0KHApOyAvLyBlLmcuIFxcXFxoZWxsb1xyXG4gICAgICAgIHJldHVybiAoaXNVbmMgPyAnXFxcXCcgOiAnJykgKyBwLnJlcGxhY2UoL1xcXFxcXFxcKy9nLCAnXFxcXCcpOyAvLyBwcmVzZXJ2ZSBsZWFkaW5nIC8vIGZvciBVTkNcclxuICAgIH1cclxuICAgIC8vIHJlbW92ZSByZWR1bmRhbnQgc2xhc2hlc1xyXG4gICAgcmV0dXJuIHAucmVwbGFjZSgvXFwvXFwvKy9nLCAnLycpO1xyXG59XHJcbmV4cG9ydHMuX25vcm1hbGl6ZVNlcGFyYXRvcnMgPSBfbm9ybWFsaXplU2VwYXJhdG9ycztcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBFeHBvc2UgcHJveHkgaW5mb3JtYXRpb24gdG8gdnN0cy1ub2RlLWFwaVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbmZ1bmN0aW9uIF9leHBvc2VQcm94eVNldHRpbmdzKCkge1xyXG4gICAgdmFyIHByb3h5VXJsID0gX2dldFZhcmlhYmxlKCdBZ2VudC5Qcm94eVVybCcpO1xyXG4gICAgaWYgKHByb3h5VXJsICYmIHByb3h5VXJsLmxlbmd0aCA+IDApIHtcclxuICAgICAgICB2YXIgcHJveHlVc2VybmFtZSA9IF9nZXRWYXJpYWJsZSgnQWdlbnQuUHJveHlVc2VybmFtZScpO1xyXG4gICAgICAgIHZhciBwcm94eVBhc3N3b3JkID0gX2dldFZhcmlhYmxlKCdBZ2VudC5Qcm94eVBhc3N3b3JkJyk7XHJcbiAgICAgICAgdmFyIHByb3h5QnlwYXNzSG9zdHNKc29uID0gX2dldFZhcmlhYmxlKCdBZ2VudC5Qcm94eUJ5cGFzc0xpc3QnKTtcclxuICAgICAgICBnbG9iYWxbJ192c3RzX3Rhc2tfbGliX3Byb3h5X3VybCddID0gcHJveHlVcmw7XHJcbiAgICAgICAgZ2xvYmFsWydfdnN0c190YXNrX2xpYl9wcm94eV91c2VybmFtZSddID0gcHJveHlVc2VybmFtZTtcclxuICAgICAgICBnbG9iYWxbJ192c3RzX3Rhc2tfbGliX3Byb3h5X2J5cGFzcyddID0gcHJveHlCeXBhc3NIb3N0c0pzb247XHJcbiAgICAgICAgZ2xvYmFsWydfdnN0c190YXNrX2xpYl9wcm94eV9wYXNzd29yZCddID0gX2V4cG9zZVRhc2tMaWJTZWNyZXQoJ3Byb3h5JywgcHJveHlQYXNzd29yZCB8fCAnJyk7XHJcbiAgICAgICAgX2RlYnVnKCdleHBvc2UgYWdlbnQgcHJveHkgY29uZmlndXJhdGlvbi4nKTtcclxuICAgICAgICBnbG9iYWxbJ192c3RzX3Rhc2tfbGliX3Byb3h5J10gPSB0cnVlO1xyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMuX2V4cG9zZVByb3h5U2V0dGluZ3MgPSBfZXhwb3NlUHJveHlTZXR0aW5ncztcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBFeHBvc2UgY2VydGlmaWNhdGUgaW5mb3JtYXRpb24gdG8gdnN0cy1ub2RlLWFwaVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbmZ1bmN0aW9uIF9leHBvc2VDZXJ0U2V0dGluZ3MoKSB7XHJcbiAgICB2YXIgY2EgPSBfZ2V0VmFyaWFibGUoJ0FnZW50LkNBSW5mbycpO1xyXG4gICAgaWYgKGNhKSB7XHJcbiAgICAgICAgZ2xvYmFsWydfdnN0c190YXNrX2xpYl9jZXJ0X2NhJ10gPSBjYTtcclxuICAgIH1cclxuICAgIHZhciBjbGllbnRDZXJ0ID0gX2dldFZhcmlhYmxlKCdBZ2VudC5DbGllbnRDZXJ0Jyk7XHJcbiAgICBpZiAoY2xpZW50Q2VydCkge1xyXG4gICAgICAgIHZhciBjbGllbnRDZXJ0S2V5ID0gX2dldFZhcmlhYmxlKCdBZ2VudC5DbGllbnRDZXJ0S2V5Jyk7XHJcbiAgICAgICAgdmFyIGNsaWVudENlcnRBcmNoaXZlID0gX2dldFZhcmlhYmxlKCdBZ2VudC5DbGllbnRDZXJ0QXJjaGl2ZScpO1xyXG4gICAgICAgIHZhciBjbGllbnRDZXJ0UGFzc3dvcmQgPSBfZ2V0VmFyaWFibGUoJ0FnZW50LkNsaWVudENlcnRQYXNzd29yZCcpO1xyXG4gICAgICAgIGdsb2JhbFsnX3ZzdHNfdGFza19saWJfY2VydF9jbGllbnRjZXJ0J10gPSBjbGllbnRDZXJ0O1xyXG4gICAgICAgIGdsb2JhbFsnX3ZzdHNfdGFza19saWJfY2VydF9rZXknXSA9IGNsaWVudENlcnRLZXk7XHJcbiAgICAgICAgZ2xvYmFsWydfdnN0c190YXNrX2xpYl9jZXJ0X2FyY2hpdmUnXSA9IGNsaWVudENlcnRBcmNoaXZlO1xyXG4gICAgICAgIGdsb2JhbFsnX3ZzdHNfdGFza19saWJfY2VydF9wYXNzcGhyYXNlJ10gPSBfZXhwb3NlVGFza0xpYlNlY3JldCgnY2VydCcsIGNsaWVudENlcnRQYXNzd29yZCB8fCAnJyk7XHJcbiAgICB9XHJcbiAgICBpZiAoY2EgfHwgY2xpZW50Q2VydCkge1xyXG4gICAgICAgIF9kZWJ1ZygnZXhwb3NlIGFnZW50IGNlcnRpZmljYXRlIGNvbmZpZ3VyYXRpb24uJyk7XHJcbiAgICAgICAgZ2xvYmFsWydfdnN0c190YXNrX2xpYl9jZXJ0J10gPSB0cnVlO1xyXG4gICAgfVxyXG4gICAgdmFyIHNraXBDZXJ0VmFsaWRhdGlvbiA9IF9nZXRWYXJpYWJsZSgnQWdlbnQuU2tpcENlcnRWYWxpZGF0aW9uJykgfHwgJ2ZhbHNlJztcclxuICAgIGlmIChza2lwQ2VydFZhbGlkYXRpb24pIHtcclxuICAgICAgICBnbG9iYWxbJ192c3RzX3Rhc2tfbGliX3NraXBfY2VydF92YWxpZGF0aW9uJ10gPSBza2lwQ2VydFZhbGlkYXRpb24udG9VcHBlckNhc2UoKSA9PT0gJ1RSVUUnO1xyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMuX2V4cG9zZUNlcnRTZXR0aW5ncyA9IF9leHBvc2VDZXJ0U2V0dGluZ3M7XHJcbi8vIFdlIHN0b3JlIHRoZSBlbmNyeXB0aW9uIGtleSBvbiBkaXNrIGFuZCBob2xkIHRoZSBlbmNyeXB0ZWQgY29udGVudCBhbmQga2V5IGZpbGUgaW4gbWVtb3J5XHJcbi8vIHJldHVybiBiYXNlNjRlbmNvZGVkPGtleUZpbGVQYXRoPjpiYXNlNjRlbmNvZGVkPGVuY3J5cHRlZENvbnRlbnQ+XHJcbi8vIGRvd25zdHJlYW0gdnN0cy1ub2RlLWFwaSB3aWxsIHJldHJpZXZlIHRoZSBzZWNyZXQgbGF0ZXJcclxuZnVuY3Rpb24gX2V4cG9zZVRhc2tMaWJTZWNyZXQoa2V5RmlsZSwgc2VjcmV0KSB7XHJcbiAgICBpZiAoc2VjcmV0KSB7XHJcbiAgICAgICAgdmFyIGVuY3J5cHRLZXkgPSBjcnlwdG8ucmFuZG9tQnl0ZXMoMjU2KTtcclxuICAgICAgICB2YXIgY2lwaGVyID0gY3J5cHRvLmNyZWF0ZUNpcGhlcihcImFlcy0yNTYtY3RyXCIsIGVuY3J5cHRLZXkpO1xyXG4gICAgICAgIHZhciBlbmNyeXB0ZWRDb250ZW50ID0gY2lwaGVyLnVwZGF0ZShzZWNyZXQsIFwidXRmOFwiLCBcImhleFwiKTtcclxuICAgICAgICBlbmNyeXB0ZWRDb250ZW50ICs9IGNpcGhlci5maW5hbChcImhleFwiKTtcclxuICAgICAgICB2YXIgc3RvcmFnZUZpbGUgPSBwYXRoLmpvaW4oX2dldFZhcmlhYmxlKCdBZ2VudC5UZW1wRGlyZWN0b3J5JykgfHwgX2dldFZhcmlhYmxlKFwiYWdlbnQud29ya0ZvbGRlclwiKSB8fCBwcm9jZXNzLmN3ZCgpLCBrZXlGaWxlKTtcclxuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKHN0b3JhZ2VGaWxlLCBlbmNyeXB0S2V5LnRvU3RyaW5nKCdiYXNlNjQnKSwgeyBlbmNvZGluZzogJ3V0ZjgnIH0pO1xyXG4gICAgICAgIHJldHVybiBuZXcgQnVmZmVyKHN0b3JhZ2VGaWxlKS50b1N0cmluZygnYmFzZTY0JykgKyAnOicgKyBuZXcgQnVmZmVyKGVuY3J5cHRlZENvbnRlbnQpLnRvU3RyaW5nKCdiYXNlNjQnKTtcclxuICAgIH1cclxufVxyXG4iLCIvKipcbiAqIENvbnZlcnQgYXJyYXkgb2YgMTYgYnl0ZSB2YWx1ZXMgdG8gVVVJRCBzdHJpbmcgZm9ybWF0IG9mIHRoZSBmb3JtOlxuICogWFhYWFhYWFgtWFhYWC1YWFhYLVhYWFgtWFhYWFhYWFhYWFhYXG4gKi9cbnZhciBieXRlVG9IZXggPSBbXTtcbmZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyArK2kpIHtcbiAgYnl0ZVRvSGV4W2ldID0gKGkgKyAweDEwMCkudG9TdHJpbmcoMTYpLnN1YnN0cigxKTtcbn1cblxuZnVuY3Rpb24gYnl0ZXNUb1V1aWQoYnVmLCBvZmZzZXQpIHtcbiAgdmFyIGkgPSBvZmZzZXQgfHwgMDtcbiAgdmFyIGJ0aCA9IGJ5dGVUb0hleDtcbiAgLy8gam9pbiB1c2VkIHRvIGZpeCBtZW1vcnkgaXNzdWUgY2F1c2VkIGJ5IGNvbmNhdGVuYXRpb246IGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTMxNzUjYzRcbiAgcmV0dXJuIChbXG4gICAgYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSxcbiAgICBidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG4gICAgYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuICAgIGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcbiAgICBidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG4gICAgYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSxcbiAgICBidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuICAgIGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV1cbiAgXSkuam9pbignJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnl0ZXNUb1V1aWQ7XG4iLCIvLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiAgSW4gbm9kZS5qc1xuLy8gdGhpcyBpcyBwcmV0dHkgc3RyYWlnaHQtZm9yd2FyZCAtIHdlIHVzZSB0aGUgY3J5cHRvIEFQSS5cblxudmFyIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIG5vZGVSTkcoKSB7XG4gIHJldHVybiBjcnlwdG8ucmFuZG9tQnl0ZXMoMTYpO1xufTtcbiIsInZhciBybmcgPSByZXF1aXJlKCcuL2xpYi9ybmcnKTtcbnZhciBieXRlc1RvVXVpZCA9IHJlcXVpcmUoJy4vbGliL2J5dGVzVG9VdWlkJyk7XG5cbmZ1bmN0aW9uIHY0KG9wdGlvbnMsIGJ1Ziwgb2Zmc2V0KSB7XG4gIHZhciBpID0gYnVmICYmIG9mZnNldCB8fCAwO1xuXG4gIGlmICh0eXBlb2Yob3B0aW9ucykgPT0gJ3N0cmluZycpIHtcbiAgICBidWYgPSBvcHRpb25zID09PSAnYmluYXJ5JyA/IG5ldyBBcnJheSgxNikgOiBudWxsO1xuICAgIG9wdGlvbnMgPSBudWxsO1xuICB9XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIHZhciBybmRzID0gb3B0aW9ucy5yYW5kb20gfHwgKG9wdGlvbnMucm5nIHx8IHJuZykoKTtcblxuICAvLyBQZXIgNC40LCBzZXQgYml0cyBmb3IgdmVyc2lvbiBhbmQgYGNsb2NrX3NlcV9oaV9hbmRfcmVzZXJ2ZWRgXG4gIHJuZHNbNl0gPSAocm5kc1s2XSAmIDB4MGYpIHwgMHg0MDtcbiAgcm5kc1s4XSA9IChybmRzWzhdICYgMHgzZikgfCAweDgwO1xuXG4gIC8vIENvcHkgYnl0ZXMgdG8gYnVmZmVyLCBpZiBwcm92aWRlZFxuICBpZiAoYnVmKSB7XG4gICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IDE2OyArK2lpKSB7XG4gICAgICBidWZbaSArIGlpXSA9IHJuZHNbaWldO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBidWYgfHwgYnl0ZXNUb1V1aWQocm5kcyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjQ7XG4iLCJcInVzZSBzdHJpY3RcIjtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG5leHBvcnRzLnVwZGF0ZVJlbGVhc2VOYW1lID0gZXhwb3J0cy5hZGRCdWlsZFRhZyA9IGV4cG9ydHMudXBkYXRlQnVpbGROdW1iZXIgPSBleHBvcnRzLnVwbG9hZEJ1aWxkTG9nID0gZXhwb3J0cy5hc3NvY2lhdGVBcnRpZmFjdCA9IGV4cG9ydHMudXBsb2FkQXJ0aWZhY3QgPSBleHBvcnRzLmxvZ0lzc3VlID0gZXhwb3J0cy5sb2dEZXRhaWwgPSBleHBvcnRzLnNldFByb2dyZXNzID0gZXhwb3J0cy5zZXRFbmRwb2ludCA9IGV4cG9ydHMuYWRkQXR0YWNobWVudCA9IGV4cG9ydHMudXBsb2FkU3VtbWFyeSA9IGV4cG9ydHMucHJlcGVuZFBhdGggPSBleHBvcnRzLnVwbG9hZEZpbGUgPSBleHBvcnRzLkNvZGVDb3ZlcmFnZUVuYWJsZXIgPSBleHBvcnRzLkNvZGVDb3ZlcmFnZVB1Ymxpc2hlciA9IGV4cG9ydHMuVGVzdFB1Ymxpc2hlciA9IGV4cG9ydHMuZ2V0SHR0cENlcnRDb25maWd1cmF0aW9uID0gZXhwb3J0cy5nZXRIdHRwUHJveHlDb25maWd1cmF0aW9uID0gZXhwb3J0cy5maW5kTWF0Y2ggPSBleHBvcnRzLmZpbHRlciA9IGV4cG9ydHMubWF0Y2ggPSBleHBvcnRzLnRvb2wgPSBleHBvcnRzLmV4ZWNTeW5jID0gZXhwb3J0cy5leGVjID0gZXhwb3J0cy5ybVJGID0gZXhwb3J0cy5sZWdhY3lGaW5kRmlsZXMgPSBleHBvcnRzLmZpbmQgPSBleHBvcnRzLm12ID0gZXhwb3J0cy5jcCA9IGV4cG9ydHMubHMgPSBleHBvcnRzLndoaWNoID0gZXhwb3J0cy5yZXNvbHZlID0gZXhwb3J0cy5ta2RpclAgPSBleHBvcnRzLnBvcGQgPSBleHBvcnRzLnB1c2hkID0gZXhwb3J0cy5jZCA9IGV4cG9ydHMuY2hlY2tQYXRoID0gZXhwb3J0cy5jd2QgPSBleHBvcnRzLmdldFBsYXRmb3JtID0gZXhwb3J0cy5vc1R5cGUgPSBleHBvcnRzLndyaXRlRmlsZSA9IGV4cG9ydHMuZXhpc3QgPSBleHBvcnRzLnN0YXRzID0gZXhwb3J0cy5kZWJ1ZyA9IGV4cG9ydHMuZXJyb3IgPSBleHBvcnRzLndhcm5pbmcgPSBleHBvcnRzLmNvbW1hbmQgPSBleHBvcnRzLnNldFRhc2tWYXJpYWJsZSA9IGV4cG9ydHMuZ2V0VGFza1ZhcmlhYmxlID0gZXhwb3J0cy5nZXRTZWN1cmVGaWxlVGlja2V0ID0gZXhwb3J0cy5nZXRTZWN1cmVGaWxlTmFtZSA9IGV4cG9ydHMuZ2V0RW5kcG9pbnRBdXRob3JpemF0aW9uID0gZXhwb3J0cy5nZXRFbmRwb2ludEF1dGhvcml6YXRpb25QYXJhbWV0ZXIgPSBleHBvcnRzLmdldEVuZHBvaW50QXV0aG9yaXphdGlvblNjaGVtZSA9IGV4cG9ydHMuZ2V0RW5kcG9pbnREYXRhUGFyYW1ldGVyID0gZXhwb3J0cy5nZXRFbmRwb2ludFVybCA9IGV4cG9ydHMuZ2V0UGF0aElucHV0ID0gZXhwb3J0cy5maWxlUGF0aFN1cHBsaWVkID0gZXhwb3J0cy5nZXREZWxpbWl0ZWRJbnB1dCA9IGV4cG9ydHMuZ2V0Qm9vbElucHV0ID0gZXhwb3J0cy5nZXRJbnB1dCA9IGV4cG9ydHMuc2V0U2VjcmV0ID0gZXhwb3J0cy5zZXRWYXJpYWJsZSA9IGV4cG9ydHMuZ2V0VmFyaWFibGVzID0gZXhwb3J0cy5hc3NlcnRBZ2VudCA9IGV4cG9ydHMuZ2V0VmFyaWFibGUgPSBleHBvcnRzLmxvYyA9IGV4cG9ydHMuc2V0UmVzb3VyY2VQYXRoID0gZXhwb3J0cy5zZXRSZXN1bHQgPSBleHBvcnRzLnNldEVyclN0cmVhbSA9IGV4cG9ydHMuc2V0U3RkU3RyZWFtID0gZXhwb3J0cy5QbGF0Zm9ybSA9IGV4cG9ydHMuRmllbGRUeXBlID0gZXhwb3J0cy5BcnRpZmFjdFR5cGUgPSBleHBvcnRzLklzc3VlVHlwZSA9IGV4cG9ydHMuVGFza1N0YXRlID0gZXhwb3J0cy5UYXNrUmVzdWx0ID0gdm9pZCAwO1xyXG52YXIgc2hlbGwgPSByZXF1aXJlKFwic2hlbGxqc1wiKTtcclxudmFyIGNoaWxkUHJvY2VzcyA9IHJlcXVpcmUoXCJjaGlsZF9wcm9jZXNzXCIpO1xyXG52YXIgZnMgPSByZXF1aXJlKFwiZnNcIik7XHJcbnZhciBwYXRoID0gcmVxdWlyZShcInBhdGhcIik7XHJcbnZhciBvcyA9IHJlcXVpcmUoXCJvc1wiKTtcclxudmFyIG1pbmltYXRjaCA9IHJlcXVpcmUoXCJtaW5pbWF0Y2hcIik7XHJcbnZhciBpbSA9IHJlcXVpcmUoXCIuL2ludGVybmFsXCIpO1xyXG52YXIgdGNtID0gcmVxdWlyZShcIi4vdGFza2NvbW1hbmRcIik7XHJcbnZhciB0cm0gPSByZXF1aXJlKFwiLi90b29scnVubmVyXCIpO1xyXG52YXIgc2VtdmVyID0gcmVxdWlyZShcInNlbXZlclwiKTtcclxudmFyIFRhc2tSZXN1bHQ7XHJcbihmdW5jdGlvbiAoVGFza1Jlc3VsdCkge1xyXG4gICAgVGFza1Jlc3VsdFtUYXNrUmVzdWx0W1wiU3VjY2VlZGVkXCJdID0gMF0gPSBcIlN1Y2NlZWRlZFwiO1xyXG4gICAgVGFza1Jlc3VsdFtUYXNrUmVzdWx0W1wiU3VjY2VlZGVkV2l0aElzc3Vlc1wiXSA9IDFdID0gXCJTdWNjZWVkZWRXaXRoSXNzdWVzXCI7XHJcbiAgICBUYXNrUmVzdWx0W1Rhc2tSZXN1bHRbXCJGYWlsZWRcIl0gPSAyXSA9IFwiRmFpbGVkXCI7XHJcbiAgICBUYXNrUmVzdWx0W1Rhc2tSZXN1bHRbXCJDYW5jZWxsZWRcIl0gPSAzXSA9IFwiQ2FuY2VsbGVkXCI7XHJcbiAgICBUYXNrUmVzdWx0W1Rhc2tSZXN1bHRbXCJTa2lwcGVkXCJdID0gNF0gPSBcIlNraXBwZWRcIjtcclxufSkoVGFza1Jlc3VsdCA9IGV4cG9ydHMuVGFza1Jlc3VsdCB8fCAoZXhwb3J0cy5UYXNrUmVzdWx0ID0ge30pKTtcclxudmFyIFRhc2tTdGF0ZTtcclxuKGZ1bmN0aW9uIChUYXNrU3RhdGUpIHtcclxuICAgIFRhc2tTdGF0ZVtUYXNrU3RhdGVbXCJVbmtub3duXCJdID0gMF0gPSBcIlVua25vd25cIjtcclxuICAgIFRhc2tTdGF0ZVtUYXNrU3RhdGVbXCJJbml0aWFsaXplZFwiXSA9IDFdID0gXCJJbml0aWFsaXplZFwiO1xyXG4gICAgVGFza1N0YXRlW1Rhc2tTdGF0ZVtcIkluUHJvZ3Jlc3NcIl0gPSAyXSA9IFwiSW5Qcm9ncmVzc1wiO1xyXG4gICAgVGFza1N0YXRlW1Rhc2tTdGF0ZVtcIkNvbXBsZXRlZFwiXSA9IDNdID0gXCJDb21wbGV0ZWRcIjtcclxufSkoVGFza1N0YXRlID0gZXhwb3J0cy5UYXNrU3RhdGUgfHwgKGV4cG9ydHMuVGFza1N0YXRlID0ge30pKTtcclxudmFyIElzc3VlVHlwZTtcclxuKGZ1bmN0aW9uIChJc3N1ZVR5cGUpIHtcclxuICAgIElzc3VlVHlwZVtJc3N1ZVR5cGVbXCJFcnJvclwiXSA9IDBdID0gXCJFcnJvclwiO1xyXG4gICAgSXNzdWVUeXBlW0lzc3VlVHlwZVtcIldhcm5pbmdcIl0gPSAxXSA9IFwiV2FybmluZ1wiO1xyXG59KShJc3N1ZVR5cGUgPSBleHBvcnRzLklzc3VlVHlwZSB8fCAoZXhwb3J0cy5Jc3N1ZVR5cGUgPSB7fSkpO1xyXG52YXIgQXJ0aWZhY3RUeXBlO1xyXG4oZnVuY3Rpb24gKEFydGlmYWN0VHlwZSkge1xyXG4gICAgQXJ0aWZhY3RUeXBlW0FydGlmYWN0VHlwZVtcIkNvbnRhaW5lclwiXSA9IDBdID0gXCJDb250YWluZXJcIjtcclxuICAgIEFydGlmYWN0VHlwZVtBcnRpZmFjdFR5cGVbXCJGaWxlUGF0aFwiXSA9IDFdID0gXCJGaWxlUGF0aFwiO1xyXG4gICAgQXJ0aWZhY3RUeXBlW0FydGlmYWN0VHlwZVtcIlZlcnNpb25Db250cm9sXCJdID0gMl0gPSBcIlZlcnNpb25Db250cm9sXCI7XHJcbiAgICBBcnRpZmFjdFR5cGVbQXJ0aWZhY3RUeXBlW1wiR2l0UmVmXCJdID0gM10gPSBcIkdpdFJlZlwiO1xyXG4gICAgQXJ0aWZhY3RUeXBlW0FydGlmYWN0VHlwZVtcIlRmdmNMYWJlbFwiXSA9IDRdID0gXCJUZnZjTGFiZWxcIjtcclxufSkoQXJ0aWZhY3RUeXBlID0gZXhwb3J0cy5BcnRpZmFjdFR5cGUgfHwgKGV4cG9ydHMuQXJ0aWZhY3RUeXBlID0ge30pKTtcclxudmFyIEZpZWxkVHlwZTtcclxuKGZ1bmN0aW9uIChGaWVsZFR5cGUpIHtcclxuICAgIEZpZWxkVHlwZVtGaWVsZFR5cGVbXCJBdXRoUGFyYW1ldGVyXCJdID0gMF0gPSBcIkF1dGhQYXJhbWV0ZXJcIjtcclxuICAgIEZpZWxkVHlwZVtGaWVsZFR5cGVbXCJEYXRhUGFyYW1ldGVyXCJdID0gMV0gPSBcIkRhdGFQYXJhbWV0ZXJcIjtcclxuICAgIEZpZWxkVHlwZVtGaWVsZFR5cGVbXCJVcmxcIl0gPSAyXSA9IFwiVXJsXCI7XHJcbn0pKEZpZWxkVHlwZSA9IGV4cG9ydHMuRmllbGRUeXBlIHx8IChleHBvcnRzLkZpZWxkVHlwZSA9IHt9KSk7XHJcbi8qKiBQbGF0Zm9ybXMgc3VwcG9ydGVkIGJ5IG91ciBidWlsZCBhZ2VudCAqL1xyXG52YXIgUGxhdGZvcm07XHJcbihmdW5jdGlvbiAoUGxhdGZvcm0pIHtcclxuICAgIFBsYXRmb3JtW1BsYXRmb3JtW1wiV2luZG93c1wiXSA9IDBdID0gXCJXaW5kb3dzXCI7XHJcbiAgICBQbGF0Zm9ybVtQbGF0Zm9ybVtcIk1hY09TXCJdID0gMV0gPSBcIk1hY09TXCI7XHJcbiAgICBQbGF0Zm9ybVtQbGF0Zm9ybVtcIkxpbnV4XCJdID0gMl0gPSBcIkxpbnV4XCI7XHJcbn0pKFBsYXRmb3JtID0gZXhwb3J0cy5QbGF0Zm9ybSB8fCAoZXhwb3J0cy5QbGF0Zm9ybSA9IHt9KSk7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gR2VuZXJhbCBIZWxwZXJzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuZXhwb3J0cy5zZXRTdGRTdHJlYW0gPSBpbS5fc2V0U3RkU3RyZWFtO1xyXG5leHBvcnRzLnNldEVyclN0cmVhbSA9IGltLl9zZXRFcnJTdHJlYW07XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gUmVzdWx0c1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8qKlxyXG4gKiBTZXRzIHRoZSByZXN1bHQgb2YgdGhlIHRhc2suXHJcbiAqIEV4ZWN1dGlvbiB3aWxsIGNvbnRpbnVlLlxyXG4gKiBJZiBub3Qgc2V0LCB0YXNrIHdpbGwgYmUgU3VjY2VlZGVkLlxyXG4gKiBJZiBtdWx0aXBsZSBjYWxscyBhcmUgbWFkZSB0byBzZXRSZXN1bHQgdGhlIG1vc3QgcGVzc2ltaXN0aWMgY2FsbCB3aW5zIChGYWlsZWQpIHJlZ2FyZGxlc3Mgb2YgdGhlIG9yZGVyIG9mIGNhbGxzLlxyXG4gKlxyXG4gKiBAcGFyYW0gcmVzdWx0ICAgIFRhc2tSZXN1bHQgZW51bSBvZiBTdWNjZWVkZWQsIFN1Y2NlZWRlZFdpdGhJc3N1ZXMsIEZhaWxlZCwgQ2FuY2VsbGVkIG9yIFNraXBwZWQuXHJcbiAqIEBwYXJhbSBtZXNzYWdlICAgQSBtZXNzYWdlIHdoaWNoIHdpbGwgYmUgbG9nZ2VkIGFzIGFuIGVycm9yIGlzc3VlIGlmIHRoZSByZXN1bHQgaXMgRmFpbGVkLlxyXG4gKiBAcGFyYW0gZG9uZSAgICAgIE9wdGlvbmFsLiBJbnN0cnVjdHMgdGhlIGFnZW50IHRoZSB0YXNrIGlzIGRvbmUuIFRoaXMgaXMgaGVscGZ1bCB3aGVuIGNoaWxkIHByb2Nlc3Nlc1xyXG4gKiAgICAgICAgICAgICAgICAgIG1heSBzdGlsbCBiZSBydW5uaW5nIGFuZCBwcmV2ZW50IG5vZGUgZnJvbSBmdWxseSBleGl0aW5nLiBUaGlzIGFyZ3VtZW50IGlzIHN1cHBvcnRlZFxyXG4gKiAgICAgICAgICAgICAgICAgIGZyb20gYWdlbnQgdmVyc2lvbiAyLjE0Mi4wIG9yIGhpZ2hlciAob3RoZXJ3aXNlIHdpbGwgbm8tb3ApLlxyXG4gKiBAcmV0dXJucyAgICAgICAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIHNldFJlc3VsdChyZXN1bHQsIG1lc3NhZ2UsIGRvbmUpIHtcclxuICAgIGV4cG9ydHMuZGVidWcoJ3Rhc2sgcmVzdWx0OiAnICsgVGFza1Jlc3VsdFtyZXN1bHRdKTtcclxuICAgIC8vIGFkZCBhbiBlcnJvciBpc3N1ZVxyXG4gICAgaWYgKHJlc3VsdCA9PSBUYXNrUmVzdWx0LkZhaWxlZCAmJiBtZXNzYWdlKSB7XHJcbiAgICAgICAgZXhwb3J0cy5lcnJvcihtZXNzYWdlKTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKHJlc3VsdCA9PSBUYXNrUmVzdWx0LlN1Y2NlZWRlZFdpdGhJc3N1ZXMgJiYgbWVzc2FnZSkge1xyXG4gICAgICAgIGV4cG9ydHMud2FybmluZyhtZXNzYWdlKTtcclxuICAgIH1cclxuICAgIC8vIHRhc2suY29tcGxldGVcclxuICAgIHZhciBwcm9wZXJ0aWVzID0geyAncmVzdWx0JzogVGFza1Jlc3VsdFtyZXN1bHRdIH07XHJcbiAgICBpZiAoZG9uZSkge1xyXG4gICAgICAgIHByb3BlcnRpZXNbJ2RvbmUnXSA9ICd0cnVlJztcclxuICAgIH1cclxuICAgIGV4cG9ydHMuY29tbWFuZCgndGFzay5jb21wbGV0ZScsIHByb3BlcnRpZXMsIG1lc3NhZ2UpO1xyXG59XHJcbmV4cG9ydHMuc2V0UmVzdWx0ID0gc2V0UmVzdWx0O1xyXG4vL1xyXG4vLyBDYXRjaGluZyBhbGwgZXhjZXB0aW9uc1xyXG4vL1xyXG5wcm9jZXNzLm9uKCd1bmNhdWdodEV4Y2VwdGlvbicsIGZ1bmN0aW9uIChlcnIpIHtcclxuICAgIHNldFJlc3VsdChUYXNrUmVzdWx0LkZhaWxlZCwgZXhwb3J0cy5sb2MoJ0xJQl9VbmhhbmRsZWRFeCcsIGVyci5tZXNzYWdlKSk7XHJcbn0pO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIExvYyBIZWxwZXJzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuZXhwb3J0cy5zZXRSZXNvdXJjZVBhdGggPSBpbS5fc2V0UmVzb3VyY2VQYXRoO1xyXG5leHBvcnRzLmxvYyA9IGltLl9sb2M7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gSW5wdXQgSGVscGVyc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbmV4cG9ydHMuZ2V0VmFyaWFibGUgPSBpbS5fZ2V0VmFyaWFibGU7XHJcbi8qKlxyXG4gKiBBc3NlcnRzIHRoZSBhZ2VudCB2ZXJzaW9uIGlzIGF0IGxlYXN0IHRoZSBzcGVjaWZpZWQgbWluaW11bS5cclxuICpcclxuICogQHBhcmFtICAgIG1pbmltdW0gICAgbWluaW11bSB2ZXJzaW9uIHZlcnNpb24gLSBtdXN0IGJlIDIuMTA0LjEgb3IgaGlnaGVyXHJcbiAqL1xyXG5mdW5jdGlvbiBhc3NlcnRBZ2VudChtaW5pbXVtKSB7XHJcbiAgICBpZiAoc2VtdmVyLmx0KG1pbmltdW0sICcyLjEwNC4xJykpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Fzc2VydEFnZW50KCkgcmVxdWlyZXMgdGhlIHBhcmFtZXRlciB0byBiZSAyLjEwNC4xIG9yIGhpZ2hlcicpO1xyXG4gICAgfVxyXG4gICAgdmFyIGFnZW50ID0gZXhwb3J0cy5nZXRWYXJpYWJsZSgnQWdlbnQuVmVyc2lvbicpO1xyXG4gICAgaWYgKGFnZW50ICYmIHNlbXZlci5sdChhZ2VudCwgbWluaW11bSkpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBZ2VudCB2ZXJzaW9uIFwiICsgbWluaW11bSArIFwiIG9yIGhpZ2hlciBpcyByZXF1aXJlZFwiKTtcclxuICAgIH1cclxufVxyXG5leHBvcnRzLmFzc2VydEFnZW50ID0gYXNzZXJ0QWdlbnQ7XHJcbi8qKlxyXG4gKiBHZXRzIGEgc25hcHNob3Qgb2YgdGhlIGN1cnJlbnQgc3RhdGUgb2YgYWxsIGpvYiB2YXJpYWJsZXMgYXZhaWxhYmxlIHRvIHRoZSB0YXNrLlxyXG4gKiBSZXF1aXJlcyBhIDIuMTA0LjEgYWdlbnQgb3IgaGlnaGVyIGZvciBmdWxsIGZ1bmN0aW9uYWxpdHkuXHJcbiAqXHJcbiAqIExpbWl0YXRpb25zIG9uIGFuIGFnZW50IHByaW9yIHRvIDIuMTA0LjE6XHJcbiAqICAxKSBUaGUgcmV0dXJuIHZhbHVlIGRvZXMgbm90IGluY2x1ZGUgYWxsIHB1YmxpYyB2YXJpYWJsZXMuIE9ubHkgcHVibGljIHZhcmlhYmxlc1xyXG4gKiAgICAgdGhhdCBoYXZlIGJlZW4gYWRkZWQgdXNpbmcgc2V0VmFyaWFibGUgYXJlIHJldHVybmVkLlxyXG4gKiAgMikgVGhlIG5hbWUgcmV0dXJuZWQgZm9yIGVhY2ggc2VjcmV0IHZhcmlhYmxlIGlzIHRoZSBmb3JtYXR0ZWQgZW52aXJvbm1lbnQgdmFyaWFibGVcclxuICogICAgIG5hbWUsIG5vdCB0aGUgYWN0dWFsIHZhcmlhYmxlIG5hbWUgKHVubGVzcyBpdCB3YXMgc2V0IGV4cGxpY2l0bHkgYXQgcnVudGltZSB1c2luZ1xyXG4gKiAgICAgc2V0VmFyaWFibGUpLlxyXG4gKlxyXG4gKiBAcmV0dXJucyBWYXJpYWJsZUluZm9bXVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0VmFyaWFibGVzKCkge1xyXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGltLl9rbm93blZhcmlhYmxlTWFwKVxyXG4gICAgICAgIC5tYXAoZnVuY3Rpb24gKGtleSkge1xyXG4gICAgICAgIHZhciBpbmZvID0gaW0uX2tub3duVmFyaWFibGVNYXBba2V5XTtcclxuICAgICAgICByZXR1cm4geyBuYW1lOiBpbmZvLm5hbWUsIHZhbHVlOiBleHBvcnRzLmdldFZhcmlhYmxlKGluZm8ubmFtZSksIHNlY3JldDogaW5mby5zZWNyZXQgfTtcclxuICAgIH0pO1xyXG59XHJcbmV4cG9ydHMuZ2V0VmFyaWFibGVzID0gZ2V0VmFyaWFibGVzO1xyXG4vKipcclxuICogU2V0cyBhIHZhcmlhYmxlIHdoaWNoIHdpbGwgYmUgYXZhaWxhYmxlIHRvIHN1YnNlcXVlbnQgdGFza3MgYXMgd2VsbC5cclxuICpcclxuICogQHBhcmFtICAgICBuYW1lICAgICBuYW1lIG9mIHRoZSB2YXJpYWJsZSB0byBzZXRcclxuICogQHBhcmFtICAgICB2YWwgICAgICB2YWx1ZSB0byBzZXRcclxuICogQHBhcmFtICAgICBzZWNyZXQgICB3aGV0aGVyIHZhcmlhYmxlIGlzIHNlY3JldC4gIE11bHRpLWxpbmUgc2VjcmV0cyBhcmUgbm90IGFsbG93ZWQuICBPcHRpb25hbCwgZGVmYXVsdHMgdG8gZmFsc2VcclxuICogQHBhcmFtICAgICBpc091dHB1dCB3aGV0aGVyIHZhcmlhYmxlIGlzIGFuIG91dHB1dCB2YXJpYWJsZS4gIE9wdGlvbmFsLCBkZWZhdWx0cyB0byBmYWxzZVxyXG4gKiBAcmV0dXJucyAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIHNldFZhcmlhYmxlKG5hbWUsIHZhbCwgc2VjcmV0LCBpc091dHB1dCkge1xyXG4gICAgaWYgKHNlY3JldCA9PT0gdm9pZCAwKSB7IHNlY3JldCA9IGZhbHNlOyB9XHJcbiAgICBpZiAoaXNPdXRwdXQgPT09IHZvaWQgMCkgeyBpc091dHB1dCA9IGZhbHNlOyB9XHJcbiAgICAvLyBvbmNlIGEgc2VjcmV0IGFsd2F5cyBhIHNlY3JldFxyXG4gICAgdmFyIGtleSA9IGltLl9nZXRWYXJpYWJsZUtleShuYW1lKTtcclxuICAgIGlmIChpbS5fa25vd25WYXJpYWJsZU1hcC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XHJcbiAgICAgICAgc2VjcmV0ID0gc2VjcmV0IHx8IGltLl9rbm93blZhcmlhYmxlTWFwW2tleV0uc2VjcmV0O1xyXG4gICAgfVxyXG4gICAgLy8gc3RvcmUgdGhlIHZhbHVlXHJcbiAgICB2YXIgdmFyVmFsdWUgPSB2YWwgfHwgJyc7XHJcbiAgICBleHBvcnRzLmRlYnVnKCdzZXQgJyArIG5hbWUgKyAnPScgKyAoc2VjcmV0ICYmIHZhclZhbHVlID8gJyoqKioqKioqJyA6IHZhclZhbHVlKSk7XHJcbiAgICBpZiAoc2VjcmV0KSB7XHJcbiAgICAgICAgaWYgKHZhclZhbHVlICYmIHZhclZhbHVlLm1hdGNoKC9cXHJ8XFxuLykgJiYgKFwiXCIgKyBwcm9jZXNzLmVudlsnU1lTVEVNX1VOU0FGRUFMTE9XTVVMVElMSU5FU0VDUkVUJ10pLnRvVXBwZXJDYXNlKCkgIT0gJ1RSVUUnKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmxvYygnTElCX011bHRpbGluZVNlY3JldCcpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaW0uX3ZhdWx0LnN0b3JlU2VjcmV0KCdTRUNSRVRfJyArIGtleSwgdmFyVmFsdWUpO1xyXG4gICAgICAgIGRlbGV0ZSBwcm9jZXNzLmVudltrZXldO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgcHJvY2Vzcy5lbnZba2V5XSA9IHZhclZhbHVlO1xyXG4gICAgfVxyXG4gICAgLy8gc3RvcmUgdGhlIG1ldGFkYXRhXHJcbiAgICBpbS5fa25vd25WYXJpYWJsZU1hcFtrZXldID0geyBuYW1lOiBuYW1lLCBzZWNyZXQ6IHNlY3JldCB9O1xyXG4gICAgLy8gd3JpdGUgdGhlIHNldHZhcmlhYmxlIGNvbW1hbmRcclxuICAgIGV4cG9ydHMuY29tbWFuZCgndGFzay5zZXR2YXJpYWJsZScsIHsgJ3ZhcmlhYmxlJzogbmFtZSB8fCAnJywgaXNPdXRwdXQ6IChpc091dHB1dCB8fCBmYWxzZSkudG9TdHJpbmcoKSwgJ2lzc2VjcmV0JzogKHNlY3JldCB8fCBmYWxzZSkudG9TdHJpbmcoKSB9LCB2YXJWYWx1ZSk7XHJcbn1cclxuZXhwb3J0cy5zZXRWYXJpYWJsZSA9IHNldFZhcmlhYmxlO1xyXG4vKipcclxuICogUmVnaXN0ZXJzIGEgdmFsdWUgd2l0aCB0aGUgbG9nZ2VyLCBzbyB0aGUgdmFsdWUgd2lsbCBiZSBtYXNrZWQgZnJvbSB0aGUgbG9ncy4gIE11bHRpLWxpbmUgc2VjcmV0cyBhcmUgbm90IGFsbG93ZWQuXHJcbiAqXHJcbiAqIEBwYXJhbSB2YWwgdmFsdWUgdG8gcmVnaXN0ZXJcclxuICovXHJcbmZ1bmN0aW9uIHNldFNlY3JldCh2YWwpIHtcclxuICAgIGlmICh2YWwpIHtcclxuICAgICAgICBpZiAodmFsLm1hdGNoKC9cXHJ8XFxuLykgJiYgKFwiXCIgKyBwcm9jZXNzLmVudlsnU1lTVEVNX1VOU0FGRUFMTE9XTVVMVElMSU5FU0VDUkVUJ10pLnRvVXBwZXJDYXNlKCkgIT09ICdUUlVFJykge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9NdWx0aWxpbmVTZWNyZXQnKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGV4cG9ydHMuY29tbWFuZCgndGFzay5zZXRzZWNyZXQnLCB7fSwgdmFsKTtcclxuICAgIH1cclxufVxyXG5leHBvcnRzLnNldFNlY3JldCA9IHNldFNlY3JldDtcclxuLyoqXHJcbiAqIEdldHMgdGhlIHZhbHVlIG9mIGFuIGlucHV0LlxyXG4gKiBJZiByZXF1aXJlZCBpcyB0cnVlIGFuZCB0aGUgdmFsdWUgaXMgbm90IHNldCwgaXQgd2lsbCB0aHJvdy5cclxuICpcclxuICogQHBhcmFtICAgICBuYW1lICAgICBuYW1lIG9mIHRoZSBpbnB1dCB0byBnZXRcclxuICogQHBhcmFtICAgICByZXF1aXJlZCB3aGV0aGVyIGlucHV0IGlzIHJlcXVpcmVkLiAgb3B0aW9uYWwsIGRlZmF1bHRzIHRvIGZhbHNlXHJcbiAqIEByZXR1cm5zICAgc3RyaW5nXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRJbnB1dChuYW1lLCByZXF1aXJlZCkge1xyXG4gICAgdmFyIGludmFsID0gaW0uX3ZhdWx0LnJldHJpZXZlU2VjcmV0KCdJTlBVVF8nICsgaW0uX2dldFZhcmlhYmxlS2V5KG5hbWUpKTtcclxuICAgIGlmIChyZXF1aXJlZCAmJiAhaW52YWwpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9JbnB1dFJlcXVpcmVkJywgbmFtZSkpO1xyXG4gICAgfVxyXG4gICAgZXhwb3J0cy5kZWJ1ZyhuYW1lICsgJz0nICsgaW52YWwpO1xyXG4gICAgcmV0dXJuIGludmFsO1xyXG59XHJcbmV4cG9ydHMuZ2V0SW5wdXQgPSBnZXRJbnB1dDtcclxuLyoqXHJcbiAqIEdldHMgdGhlIHZhbHVlIG9mIGFuIGlucHV0IGFuZCBjb252ZXJ0cyB0byBhIGJvb2wuICBDb252ZW5pZW5jZS5cclxuICogSWYgcmVxdWlyZWQgaXMgdHJ1ZSBhbmQgdGhlIHZhbHVlIGlzIG5vdCBzZXQsIGl0IHdpbGwgdGhyb3cuXHJcbiAqIElmIHJlcXVpcmVkIGlzIGZhbHNlIGFuZCB0aGUgdmFsdWUgaXMgbm90IHNldCwgcmV0dXJucyBmYWxzZS5cclxuICpcclxuICogQHBhcmFtICAgICBuYW1lICAgICBuYW1lIG9mIHRoZSBib29sIGlucHV0IHRvIGdldFxyXG4gKiBAcGFyYW0gICAgIHJlcXVpcmVkIHdoZXRoZXIgaW5wdXQgaXMgcmVxdWlyZWQuICBvcHRpb25hbCwgZGVmYXVsdHMgdG8gZmFsc2VcclxuICogQHJldHVybnMgICBib29sZWFuXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRCb29sSW5wdXQobmFtZSwgcmVxdWlyZWQpIHtcclxuICAgIHJldHVybiAoZ2V0SW5wdXQobmFtZSwgcmVxdWlyZWQpIHx8ICcnKS50b1VwcGVyQ2FzZSgpID09IFwiVFJVRVwiO1xyXG59XHJcbmV4cG9ydHMuZ2V0Qm9vbElucHV0ID0gZ2V0Qm9vbElucHV0O1xyXG4vKipcclxuICogR2V0cyB0aGUgdmFsdWUgb2YgYW4gaW5wdXQgYW5kIHNwbGl0cyB0aGUgdmFsdWUgdXNpbmcgYSBkZWxpbWl0ZXIgKHNwYWNlLCBjb21tYSwgZXRjKS5cclxuICogRW1wdHkgdmFsdWVzIGFyZSByZW1vdmVkLiAgVGhpcyBmdW5jdGlvbiBpcyB1c2VmdWwgZm9yIHNwbGl0dGluZyBhbiBpbnB1dCBjb250YWluaW5nIGEgc2ltcGxlXHJcbiAqIGxpc3Qgb2YgaXRlbXMgLSBzdWNoIGFzIGJ1aWxkIHRhcmdldHMuXHJcbiAqIElNUE9SVEFOVDogRG8gbm90IHVzZSB0aGlzIGZ1bmN0aW9uIGZvciBzcGxpdHRpbmcgYWRkaXRpb25hbCBhcmdzISAgSW5zdGVhZCB1c2UgYXJnU3RyaW5nKCksIHdoaWNoXHJcbiAqIGZvbGxvd3Mgbm9ybWFsIGFyZ3VtZW50IHNwbGl0dGluZyBydWxlcyBhbmQgaGFuZGxlcyB2YWx1ZXMgZW5jYXBzdWxhdGVkIGJ5IHF1b3Rlcy5cclxuICogSWYgcmVxdWlyZWQgaXMgdHJ1ZSBhbmQgdGhlIHZhbHVlIGlzIG5vdCBzZXQsIGl0IHdpbGwgdGhyb3cuXHJcbiAqXHJcbiAqIEBwYXJhbSAgICAgbmFtZSAgICAgbmFtZSBvZiB0aGUgaW5wdXQgdG8gZ2V0XHJcbiAqIEBwYXJhbSAgICAgZGVsaW0gICAgZGVsaW1pdGVyIHRvIHNwbGl0IG9uXHJcbiAqIEBwYXJhbSAgICAgcmVxdWlyZWQgd2hldGhlciBpbnB1dCBpcyByZXF1aXJlZC4gIG9wdGlvbmFsLCBkZWZhdWx0cyB0byBmYWxzZVxyXG4gKiBAcmV0dXJucyAgIHN0cmluZ1tdXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXREZWxpbWl0ZWRJbnB1dChuYW1lLCBkZWxpbSwgcmVxdWlyZWQpIHtcclxuICAgIHZhciBpbnB1dFZhbCA9IGdldElucHV0KG5hbWUsIHJlcXVpcmVkKTtcclxuICAgIGlmICghaW5wdXRWYWwpIHtcclxuICAgICAgICByZXR1cm4gW107XHJcbiAgICB9XHJcbiAgICB2YXIgcmVzdWx0ID0gW107XHJcbiAgICBpbnB1dFZhbC5zcGxpdChkZWxpbSkuZm9yRWFjaChmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgIGlmICh4KSB7XHJcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKHgpO1xyXG4gICAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5leHBvcnRzLmdldERlbGltaXRlZElucHV0ID0gZ2V0RGVsaW1pdGVkSW5wdXQ7XHJcbi8qKlxyXG4gKiBDaGVja3Mgd2hldGhlciBhIHBhdGggaW5wdXRzIHZhbHVlIHdhcyBzdXBwbGllZCBieSB0aGUgdXNlclxyXG4gKiBGaWxlIHBhdGhzIGFyZSByZWxhdGl2ZSB3aXRoIGEgcGlja2VyLCBzbyBhbiBlbXB0eSBwYXRoIGlzIHRoZSByb290IG9mIHRoZSByZXBvLlxyXG4gKiBVc2VmdWwgaWYgeW91IG5lZWQgdG8gY29uZGl0aW9uIHdvcmsgKGxpa2UgYXBwZW5kIGFuIGFyZykgaWYgYSB2YWx1ZSB3YXMgc3VwcGxpZWRcclxuICpcclxuICogQHBhcmFtICAgICBuYW1lICAgICAgbmFtZSBvZiB0aGUgcGF0aCBpbnB1dCB0byBjaGVja1xyXG4gKiBAcmV0dXJucyAgIGJvb2xlYW5cclxuICovXHJcbmZ1bmN0aW9uIGZpbGVQYXRoU3VwcGxpZWQobmFtZSkge1xyXG4gICAgLy8gbm9ybWFsaXplIHBhdGhzXHJcbiAgICB2YXIgcGF0aFZhbHVlID0gdGhpcy5yZXNvbHZlKHRoaXMuZ2V0UGF0aElucHV0KG5hbWUpIHx8ICcnKTtcclxuICAgIHZhciByZXBvUm9vdCA9IHRoaXMucmVzb2x2ZShleHBvcnRzLmdldFZhcmlhYmxlKCdidWlsZC5zb3VyY2VzRGlyZWN0b3J5JykgfHwgZXhwb3J0cy5nZXRWYXJpYWJsZSgnc3lzdGVtLmRlZmF1bHRXb3JraW5nRGlyZWN0b3J5JykgfHwgJycpO1xyXG4gICAgdmFyIHN1cHBsaWVkID0gcGF0aFZhbHVlICE9PSByZXBvUm9vdDtcclxuICAgIGV4cG9ydHMuZGVidWcobmFtZSArICdwYXRoIHN1cHBsaWVkIDonICsgc3VwcGxpZWQpO1xyXG4gICAgcmV0dXJuIHN1cHBsaWVkO1xyXG59XHJcbmV4cG9ydHMuZmlsZVBhdGhTdXBwbGllZCA9IGZpbGVQYXRoU3VwcGxpZWQ7XHJcbi8qKlxyXG4gKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIHBhdGggaW5wdXRcclxuICogSXQgd2lsbCBiZSBxdW90ZWQgZm9yIHlvdSBpZiBpdCBpc24ndCBhbHJlYWR5IGFuZCBjb250YWlucyBzcGFjZXNcclxuICogSWYgcmVxdWlyZWQgaXMgdHJ1ZSBhbmQgdGhlIHZhbHVlIGlzIG5vdCBzZXQsIGl0IHdpbGwgdGhyb3cuXHJcbiAqIElmIGNoZWNrIGlzIHRydWUgYW5kIHRoZSBwYXRoIGRvZXMgbm90IGV4aXN0LCBpdCB3aWxsIHRocm93LlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIG5hbWUgICAgICBuYW1lIG9mIHRoZSBpbnB1dCB0byBnZXRcclxuICogQHBhcmFtICAgICByZXF1aXJlZCAgd2hldGhlciBpbnB1dCBpcyByZXF1aXJlZC4gIG9wdGlvbmFsLCBkZWZhdWx0cyB0byBmYWxzZVxyXG4gKiBAcGFyYW0gICAgIGNoZWNrICAgICB3aGV0aGVyIHBhdGggaXMgY2hlY2tlZC4gIG9wdGlvbmFsLCBkZWZhdWx0cyB0byBmYWxzZVxyXG4gKiBAcmV0dXJucyAgIHN0cmluZ1xyXG4gKi9cclxuZnVuY3Rpb24gZ2V0UGF0aElucHV0KG5hbWUsIHJlcXVpcmVkLCBjaGVjaykge1xyXG4gICAgdmFyIGludmFsID0gZ2V0SW5wdXQobmFtZSwgcmVxdWlyZWQpO1xyXG4gICAgaWYgKGludmFsKSB7XHJcbiAgICAgICAgaWYgKGNoZWNrKSB7XHJcbiAgICAgICAgICAgIGV4cG9ydHMuY2hlY2tQYXRoKGludmFsLCBuYW1lKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gaW52YWw7XHJcbn1cclxuZXhwb3J0cy5nZXRQYXRoSW5wdXQgPSBnZXRQYXRoSW5wdXQ7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gRW5kcG9pbnQgSGVscGVyc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8qKlxyXG4gKiBHZXRzIHRoZSB1cmwgZm9yIGEgc2VydmljZSBlbmRwb2ludFxyXG4gKiBJZiB0aGUgdXJsIHdhcyBub3Qgc2V0IGFuZCBpcyBub3Qgb3B0aW9uYWwsIGl0IHdpbGwgdGhyb3cuXHJcbiAqXHJcbiAqIEBwYXJhbSAgICAgaWQgICAgICAgIG5hbWUgb2YgdGhlIHNlcnZpY2UgZW5kcG9pbnRcclxuICogQHBhcmFtICAgICBvcHRpb25hbCAgd2hldGhlciB0aGUgdXJsIGlzIG9wdGlvbmFsXHJcbiAqIEByZXR1cm5zICAgc3RyaW5nXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRFbmRwb2ludFVybChpZCwgb3B0aW9uYWwpIHtcclxuICAgIHZhciB1cmx2YWwgPSBwcm9jZXNzLmVudlsnRU5EUE9JTlRfVVJMXycgKyBpZF07XHJcbiAgICBpZiAoIW9wdGlvbmFsICYmICF1cmx2YWwpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9FbmRwb2ludE5vdEV4aXN0JywgaWQpKTtcclxuICAgIH1cclxuICAgIGV4cG9ydHMuZGVidWcoaWQgKyAnPScgKyB1cmx2YWwpO1xyXG4gICAgcmV0dXJuIHVybHZhbDtcclxufVxyXG5leHBvcnRzLmdldEVuZHBvaW50VXJsID0gZ2V0RW5kcG9pbnRVcmw7XHJcbi8qXHJcbiAqIEdldHMgdGhlIGVuZHBvaW50IGRhdGEgcGFyYW1ldGVyIHZhbHVlIHdpdGggc3BlY2lmaWVkIGtleSBmb3IgYSBzZXJ2aWNlIGVuZHBvaW50XHJcbiAqIElmIHRoZSBlbmRwb2ludCBkYXRhIHBhcmFtZXRlciB3YXMgbm90IHNldCBhbmQgaXMgbm90IG9wdGlvbmFsLCBpdCB3aWxsIHRocm93LlxyXG4gKlxyXG4gKiBAcGFyYW0gaWQgbmFtZSBvZiB0aGUgc2VydmljZSBlbmRwb2ludFxyXG4gKiBAcGFyYW0ga2V5IG9mIHRoZSBwYXJhbWV0ZXJcclxuICogQHBhcmFtIG9wdGlvbmFsIHdoZXRoZXIgdGhlIGVuZHBvaW50IGRhdGEgaXMgb3B0aW9uYWxcclxuICogQHJldHVybnMge3N0cmluZ30gdmFsdWUgb2YgdGhlIGVuZHBvaW50IGRhdGEgcGFyYW1ldGVyXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRFbmRwb2ludERhdGFQYXJhbWV0ZXIoaWQsIGtleSwgb3B0aW9uYWwpIHtcclxuICAgIHZhciBkYXRhUGFyYW1WYWwgPSBwcm9jZXNzLmVudlsnRU5EUE9JTlRfREFUQV8nICsgaWQgKyAnXycgKyBrZXkudG9VcHBlckNhc2UoKV07XHJcbiAgICBpZiAoIW9wdGlvbmFsICYmICFkYXRhUGFyYW1WYWwpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9FbmRwb2ludERhdGFOb3RFeGlzdCcsIGlkLCBrZXkpKTtcclxuICAgIH1cclxuICAgIGV4cG9ydHMuZGVidWcoaWQgKyAnIGRhdGEgJyArIGtleSArICcgPSAnICsgZGF0YVBhcmFtVmFsKTtcclxuICAgIHJldHVybiBkYXRhUGFyYW1WYWw7XHJcbn1cclxuZXhwb3J0cy5nZXRFbmRwb2ludERhdGFQYXJhbWV0ZXIgPSBnZXRFbmRwb2ludERhdGFQYXJhbWV0ZXI7XHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBlbmRwb2ludCBhdXRob3JpemF0aW9uIHNjaGVtZSBmb3IgYSBzZXJ2aWNlIGVuZHBvaW50XHJcbiAqIElmIHRoZSBlbmRwb2ludCBhdXRob3JpemF0aW9uIHNjaGVtZSBpcyBub3Qgc2V0IGFuZCBpcyBub3Qgb3B0aW9uYWwsIGl0IHdpbGwgdGhyb3cuXHJcbiAqXHJcbiAqIEBwYXJhbSBpZCBuYW1lIG9mIHRoZSBzZXJ2aWNlIGVuZHBvaW50XHJcbiAqIEBwYXJhbSBvcHRpb25hbCB3aGV0aGVyIHRoZSBlbmRwb2ludCBhdXRob3JpemF0aW9uIHNjaGVtZSBpcyBvcHRpb25hbFxyXG4gKiBAcmV0dXJucyB7c3RyaW5nfSB2YWx1ZSBvZiB0aGUgZW5kcG9pbnQgYXV0aG9yaXphdGlvbiBzY2hlbWVcclxuICovXHJcbmZ1bmN0aW9uIGdldEVuZHBvaW50QXV0aG9yaXphdGlvblNjaGVtZShpZCwgb3B0aW9uYWwpIHtcclxuICAgIHZhciBhdXRoU2NoZW1lID0gaW0uX3ZhdWx0LnJldHJpZXZlU2VjcmV0KCdFTkRQT0lOVF9BVVRIX1NDSEVNRV8nICsgaWQpO1xyXG4gICAgaWYgKCFvcHRpb25hbCAmJiAhYXV0aFNjaGVtZSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmxvYygnTElCX0VuZHBvaW50QXV0aE5vdEV4aXN0JywgaWQpKTtcclxuICAgIH1cclxuICAgIGV4cG9ydHMuZGVidWcoaWQgKyAnIGF1dGggc2NoZW1lID0gJyArIGF1dGhTY2hlbWUpO1xyXG4gICAgcmV0dXJuIGF1dGhTY2hlbWU7XHJcbn1cclxuZXhwb3J0cy5nZXRFbmRwb2ludEF1dGhvcml6YXRpb25TY2hlbWUgPSBnZXRFbmRwb2ludEF1dGhvcml6YXRpb25TY2hlbWU7XHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBlbmRwb2ludCBhdXRob3JpemF0aW9uIHBhcmFtZXRlciB2YWx1ZSBmb3IgYSBzZXJ2aWNlIGVuZHBvaW50IHdpdGggc3BlY2lmaWVkIGtleVxyXG4gKiBJZiB0aGUgZW5kcG9pbnQgYXV0aG9yaXphdGlvbiBwYXJhbWV0ZXIgaXMgbm90IHNldCBhbmQgaXMgbm90IG9wdGlvbmFsLCBpdCB3aWxsIHRocm93LlxyXG4gKlxyXG4gKiBAcGFyYW0gaWQgbmFtZSBvZiB0aGUgc2VydmljZSBlbmRwb2ludFxyXG4gKiBAcGFyYW0ga2V5IGtleSB0byBmaW5kIHRoZSBlbmRwb2ludCBhdXRob3JpemF0aW9uIHBhcmFtZXRlclxyXG4gKiBAcGFyYW0gb3B0aW9uYWwgb3B0aW9uYWwgd2hldGhlciB0aGUgZW5kcG9pbnQgYXV0aG9yaXphdGlvbiBzY2hlbWUgaXMgb3B0aW9uYWxcclxuICogQHJldHVybnMge3N0cmluZ30gdmFsdWUgb2YgdGhlIGVuZHBvaW50IGF1dGhvcml6YXRpb24gcGFyYW1ldGVyIHZhbHVlXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRFbmRwb2ludEF1dGhvcml6YXRpb25QYXJhbWV0ZXIoaWQsIGtleSwgb3B0aW9uYWwpIHtcclxuICAgIHZhciBhdXRoUGFyYW0gPSBpbS5fdmF1bHQucmV0cmlldmVTZWNyZXQoJ0VORFBPSU5UX0FVVEhfUEFSQU1FVEVSXycgKyBpZCArICdfJyArIGtleS50b1VwcGVyQ2FzZSgpKTtcclxuICAgIGlmICghb3B0aW9uYWwgJiYgIWF1dGhQYXJhbSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmxvYygnTElCX0VuZHBvaW50QXV0aE5vdEV4aXN0JywgaWQpKTtcclxuICAgIH1cclxuICAgIGV4cG9ydHMuZGVidWcoaWQgKyAnIGF1dGggcGFyYW0gJyArIGtleSArICcgPSAnICsgYXV0aFBhcmFtKTtcclxuICAgIHJldHVybiBhdXRoUGFyYW07XHJcbn1cclxuZXhwb3J0cy5nZXRFbmRwb2ludEF1dGhvcml6YXRpb25QYXJhbWV0ZXIgPSBnZXRFbmRwb2ludEF1dGhvcml6YXRpb25QYXJhbWV0ZXI7XHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBhdXRob3JpemF0aW9uIGRldGFpbHMgZm9yIGEgc2VydmljZSBlbmRwb2ludFxyXG4gKiBJZiB0aGUgYXV0aG9yaXphdGlvbiB3YXMgbm90IHNldCBhbmQgaXMgbm90IG9wdGlvbmFsLCBpdCB3aWxsIHRocm93LlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIGlkICAgICAgICBuYW1lIG9mIHRoZSBzZXJ2aWNlIGVuZHBvaW50XHJcbiAqIEBwYXJhbSAgICAgb3B0aW9uYWwgIHdoZXRoZXIgdGhlIHVybCBpcyBvcHRpb25hbFxyXG4gKiBAcmV0dXJucyAgIHN0cmluZ1xyXG4gKi9cclxuZnVuY3Rpb24gZ2V0RW5kcG9pbnRBdXRob3JpemF0aW9uKGlkLCBvcHRpb25hbCkge1xyXG4gICAgdmFyIGF2YWwgPSBpbS5fdmF1bHQucmV0cmlldmVTZWNyZXQoJ0VORFBPSU5UX0FVVEhfJyArIGlkKTtcclxuICAgIGlmICghb3B0aW9uYWwgJiYgIWF2YWwpIHtcclxuICAgICAgICBzZXRSZXN1bHQoVGFza1Jlc3VsdC5GYWlsZWQsIGV4cG9ydHMubG9jKCdMSUJfRW5kcG9pbnRBdXRoTm90RXhpc3QnLCBpZCkpO1xyXG4gICAgfVxyXG4gICAgZXhwb3J0cy5kZWJ1ZyhpZCArICcgZXhpc3RzICcgKyAoYXZhbCAhPT0gbnVsbCkpO1xyXG4gICAgdmFyIGF1dGg7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIGlmIChhdmFsKSB7XHJcbiAgICAgICAgICAgIGF1dGggPSBKU09OLnBhcnNlKGF2YWwpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9JbnZhbGlkRW5kcG9pbnRBdXRoJywgYXZhbCkpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGF1dGg7XHJcbn1cclxuZXhwb3J0cy5nZXRFbmRwb2ludEF1dGhvcml6YXRpb24gPSBnZXRFbmRwb2ludEF1dGhvcml6YXRpb247XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gU2VjdXJlRmlsZSBIZWxwZXJzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyoqXHJcbiAqIEdldHMgdGhlIG5hbWUgZm9yIGEgc2VjdXJlIGZpbGVcclxuICpcclxuICogQHBhcmFtICAgICBpZCAgICAgICAgc2VjdXJlIGZpbGUgaWRcclxuICogQHJldHVybnMgICBzdHJpbmdcclxuICovXHJcbmZ1bmN0aW9uIGdldFNlY3VyZUZpbGVOYW1lKGlkKSB7XHJcbiAgICB2YXIgbmFtZSA9IHByb2Nlc3MuZW52WydTRUNVUkVGSUxFX05BTUVfJyArIGlkXTtcclxuICAgIGV4cG9ydHMuZGVidWcoJ3NlY3VyZSBmaWxlIG5hbWUgZm9yIGlkICcgKyBpZCArICcgPSAnICsgbmFtZSk7XHJcbiAgICByZXR1cm4gbmFtZTtcclxufVxyXG5leHBvcnRzLmdldFNlY3VyZUZpbGVOYW1lID0gZ2V0U2VjdXJlRmlsZU5hbWU7XHJcbi8qKlxyXG4gICogR2V0cyB0aGUgc2VjdXJlIGZpbGUgdGlja2V0IHRoYXQgY2FuIGJlIHVzZWQgdG8gZG93bmxvYWQgdGhlIHNlY3VyZSBmaWxlIGNvbnRlbnRzXHJcbiAgKlxyXG4gICogQHBhcmFtIGlkIG5hbWUgb2YgdGhlIHNlY3VyZSBmaWxlXHJcbiAgKiBAcmV0dXJucyB7c3RyaW5nfSBzZWN1cmUgZmlsZSB0aWNrZXRcclxuICAqL1xyXG5mdW5jdGlvbiBnZXRTZWN1cmVGaWxlVGlja2V0KGlkKSB7XHJcbiAgICB2YXIgdGlja2V0ID0gaW0uX3ZhdWx0LnJldHJpZXZlU2VjcmV0KCdTRUNVUkVGSUxFX1RJQ0tFVF8nICsgaWQpO1xyXG4gICAgZXhwb3J0cy5kZWJ1Zygnc2VjdXJlIGZpbGUgdGlja2V0IGZvciBpZCAnICsgaWQgKyAnID0gJyArIHRpY2tldCk7XHJcbiAgICByZXR1cm4gdGlja2V0O1xyXG59XHJcbmV4cG9ydHMuZ2V0U2VjdXJlRmlsZVRpY2tldCA9IGdldFNlY3VyZUZpbGVUaWNrZXQ7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gVGFzayBWYXJpYWJsZSBIZWxwZXJzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyoqXHJcbiAqIEdldHMgYSB2YXJpYWJsZSB2YWx1ZSB0aGF0IGlzIHNldCBieSBwcmV2aW91cyBzdGVwIGZyb20gdGhlIHNhbWUgd3JhcHBlciB0YXNrLlxyXG4gKiBSZXF1aXJlcyBhIDIuMTE1LjAgYWdlbnQgb3IgaGlnaGVyLlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIG5hbWUgICAgIG5hbWUgb2YgdGhlIHZhcmlhYmxlIHRvIGdldFxyXG4gKiBAcmV0dXJucyAgIHN0cmluZ1xyXG4gKi9cclxuZnVuY3Rpb24gZ2V0VGFza1ZhcmlhYmxlKG5hbWUpIHtcclxuICAgIGFzc2VydEFnZW50KCcyLjExNS4wJyk7XHJcbiAgICB2YXIgaW52YWwgPSBpbS5fdmF1bHQucmV0cmlldmVTZWNyZXQoJ1ZTVFNfVEFTS1ZBUklBQkxFXycgKyBpbS5fZ2V0VmFyaWFibGVLZXkobmFtZSkpO1xyXG4gICAgaWYgKGludmFsKSB7XHJcbiAgICAgICAgaW52YWwgPSBpbnZhbC50cmltKCk7XHJcbiAgICB9XHJcbiAgICBleHBvcnRzLmRlYnVnKCd0YXNrIHZhcmlhYmxlOiAnICsgbmFtZSArICc9JyArIGludmFsKTtcclxuICAgIHJldHVybiBpbnZhbDtcclxufVxyXG5leHBvcnRzLmdldFRhc2tWYXJpYWJsZSA9IGdldFRhc2tWYXJpYWJsZTtcclxuLyoqXHJcbiAqIFNldHMgYSB0YXNrIHZhcmlhYmxlIHdoaWNoIHdpbGwgb25seSBiZSBhdmFpbGFibGUgdG8gc3Vic2VxdWVudCBzdGVwcyBiZWxvbmcgdG8gdGhlIHNhbWUgd3JhcHBlciB0YXNrLlxyXG4gKiBSZXF1aXJlcyBhIDIuMTE1LjAgYWdlbnQgb3IgaGlnaGVyLlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIG5hbWUgICAgbmFtZSBvZiB0aGUgdmFyaWFibGUgdG8gc2V0XHJcbiAqIEBwYXJhbSAgICAgdmFsICAgICB2YWx1ZSB0byBzZXRcclxuICogQHBhcmFtICAgICBzZWNyZXQgIHdoZXRoZXIgdmFyaWFibGUgaXMgc2VjcmV0LiAgb3B0aW9uYWwsIGRlZmF1bHRzIHRvIGZhbHNlXHJcbiAqIEByZXR1cm5zICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gc2V0VGFza1ZhcmlhYmxlKG5hbWUsIHZhbCwgc2VjcmV0KSB7XHJcbiAgICBpZiAoc2VjcmV0ID09PSB2b2lkIDApIHsgc2VjcmV0ID0gZmFsc2U7IH1cclxuICAgIGFzc2VydEFnZW50KCcyLjExNS4wJyk7XHJcbiAgICB2YXIga2V5ID0gaW0uX2dldFZhcmlhYmxlS2V5KG5hbWUpO1xyXG4gICAgLy8gc3RvcmUgdGhlIHZhbHVlXHJcbiAgICB2YXIgdmFyVmFsdWUgPSB2YWwgfHwgJyc7XHJcbiAgICBleHBvcnRzLmRlYnVnKCdzZXQgdGFzayB2YXJpYWJsZTogJyArIG5hbWUgKyAnPScgKyAoc2VjcmV0ICYmIHZhclZhbHVlID8gJyoqKioqKioqJyA6IHZhclZhbHVlKSk7XHJcbiAgICBpbS5fdmF1bHQuc3RvcmVTZWNyZXQoJ1ZTVFNfVEFTS1ZBUklBQkxFXycgKyBrZXksIHZhclZhbHVlKTtcclxuICAgIGRlbGV0ZSBwcm9jZXNzLmVudltrZXldO1xyXG4gICAgLy8gd3JpdGUgdGhlIGNvbW1hbmRcclxuICAgIGV4cG9ydHMuY29tbWFuZCgndGFzay5zZXR0YXNrdmFyaWFibGUnLCB7ICd2YXJpYWJsZSc6IG5hbWUgfHwgJycsICdpc3NlY3JldCc6IChzZWNyZXQgfHwgZmFsc2UpLnRvU3RyaW5nKCkgfSwgdmFyVmFsdWUpO1xyXG59XHJcbmV4cG9ydHMuc2V0VGFza1ZhcmlhYmxlID0gc2V0VGFza1ZhcmlhYmxlO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIENtZCBIZWxwZXJzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuZXhwb3J0cy5jb21tYW5kID0gaW0uX2NvbW1hbmQ7XHJcbmV4cG9ydHMud2FybmluZyA9IGltLl93YXJuaW5nO1xyXG5leHBvcnRzLmVycm9yID0gaW0uX2Vycm9yO1xyXG5leHBvcnRzLmRlYnVnID0gaW0uX2RlYnVnO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIERpc2sgRnVuY3Rpb25zXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuZnVuY3Rpb24gX2NoZWNrU2hlbGwoY21kLCBjb250aW51ZU9uRXJyb3IpIHtcclxuICAgIHZhciBzZSA9IHNoZWxsLmVycm9yKCk7XHJcbiAgICBpZiAoc2UpIHtcclxuICAgICAgICBleHBvcnRzLmRlYnVnKGNtZCArICcgZmFpbGVkJyk7XHJcbiAgICAgICAgdmFyIGVyck1zZyA9IGV4cG9ydHMubG9jKCdMSUJfT3BlcmF0aW9uRmFpbGVkJywgY21kLCBzZSk7XHJcbiAgICAgICAgZXhwb3J0cy5kZWJ1ZyhlcnJNc2cpO1xyXG4gICAgICAgIGlmICghY29udGludWVPbkVycm9yKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJNc2cpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4vKipcclxuICogR2V0J3Mgc3RhdCBvbiBhIHBhdGguXHJcbiAqIFVzZWZ1bCBmb3IgY2hlY2tpbmcgd2hldGhlciBhIGZpbGUgb3IgZGlyZWN0b3J5LiAgQWxzbyBnZXR0aW5nIGNyZWF0ZWQsIG1vZGlmaWVkIGFuZCBhY2Nlc3NlZCB0aW1lLlxyXG4gKiBzZWUgW2ZzLnN0YXRdKGh0dHBzOi8vbm9kZWpzLm9yZy9hcGkvZnMuaHRtbCNmc19jbGFzc19mc19zdGF0cylcclxuICpcclxuICogQHBhcmFtICAgICBwYXRoICAgICAgcGF0aCB0byBjaGVja1xyXG4gKiBAcmV0dXJucyAgIGZzU3RhdFxyXG4gKi9cclxuZnVuY3Rpb24gc3RhdHMocGF0aCkge1xyXG4gICAgcmV0dXJuIGZzLnN0YXRTeW5jKHBhdGgpO1xyXG59XHJcbmV4cG9ydHMuc3RhdHMgPSBzdGF0cztcclxuZXhwb3J0cy5leGlzdCA9IGltLl9leGlzdDtcclxuZnVuY3Rpb24gd3JpdGVGaWxlKGZpbGUsIGRhdGEsIG9wdGlvbnMpIHtcclxuICAgIGlmICh0eXBlb2YgKG9wdGlvbnMpID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMoZmlsZSwgZGF0YSwgeyBlbmNvZGluZzogb3B0aW9ucyB9KTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMoZmlsZSwgZGF0YSwgb3B0aW9ucyk7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy53cml0ZUZpbGUgPSB3cml0ZUZpbGU7XHJcbi8qKlxyXG4gKiBAZGVwcmVjYXRlZCBVc2UgYGdldFBsYXRmb3JtYFxyXG4gKiBVc2VmdWwgZm9yIGRldGVybWluaW5nIHRoZSBob3N0IG9wZXJhdGluZyBzeXN0ZW0uXHJcbiAqIHNlZSBbb3MudHlwZV0oaHR0cHM6Ly9ub2RlanMub3JnL2FwaS9vcy5odG1sI29zX29zX3R5cGUpXHJcbiAqXHJcbiAqIEByZXR1cm4gICAgICB0aGUgbmFtZSBvZiB0aGUgb3BlcmF0aW5nIHN5c3RlbVxyXG4gKi9cclxuZnVuY3Rpb24gb3NUeXBlKCkge1xyXG4gICAgcmV0dXJuIG9zLnR5cGUoKTtcclxufVxyXG5leHBvcnRzLm9zVHlwZSA9IG9zVHlwZTtcclxuLyoqXHJcbiAqIERldGVybWluZSB0aGUgb3BlcmF0aW5nIHN5c3RlbSB0aGUgYnVpbGQgYWdlbnQgaXMgcnVubmluZyBvbi5cclxuICogQHJldHVybnMge1BsYXRmb3JtfVxyXG4gKiBAdGhyb3dzIHtFcnJvcn0gUGxhdGZvcm0gaXMgbm90IHN1cHBvcnRlZCBieSBvdXIgYWdlbnRcclxuICovXHJcbmZ1bmN0aW9uIGdldFBsYXRmb3JtKCkge1xyXG4gICAgc3dpdGNoIChwcm9jZXNzLnBsYXRmb3JtKSB7XHJcbiAgICAgICAgY2FzZSAnd2luMzInOiByZXR1cm4gUGxhdGZvcm0uV2luZG93cztcclxuICAgICAgICBjYXNlICdkYXJ3aW4nOiByZXR1cm4gUGxhdGZvcm0uTWFjT1M7XHJcbiAgICAgICAgY2FzZSAnbGludXgnOiByZXR1cm4gUGxhdGZvcm0uTGludXg7XHJcbiAgICAgICAgZGVmYXVsdDogdGhyb3cgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9QbGF0Zm9ybU5vdFN1cHBvcnRlZCcsIHByb2Nlc3MucGxhdGZvcm0pKTtcclxuICAgIH1cclxufVxyXG5leHBvcnRzLmdldFBsYXRmb3JtID0gZ2V0UGxhdGZvcm07XHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBwcm9jZXNzJ3MgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeS5cclxuICogc2VlIFtwcm9jZXNzLmN3ZF0oaHR0cHM6Ly9ub2RlanMub3JnL2FwaS9wcm9jZXNzLmh0bWwjcHJvY2Vzc19wcm9jZXNzX2N3ZClcclxuICpcclxuICogQHJldHVybiAgICAgIHRoZSBwYXRoIHRvIHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5IG9mIHRoZSBwcm9jZXNzXHJcbiAqL1xyXG5mdW5jdGlvbiBjd2QoKSB7XHJcbiAgICByZXR1cm4gcHJvY2Vzcy5jd2QoKTtcclxufVxyXG5leHBvcnRzLmN3ZCA9IGN3ZDtcclxuZXhwb3J0cy5jaGVja1BhdGggPSBpbS5fY2hlY2tQYXRoO1xyXG4vKipcclxuICogQ2hhbmdlIHdvcmtpbmcgZGlyZWN0b3J5LlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIHBhdGggICAgICBuZXcgd29ya2luZyBkaXJlY3RvcnkgcGF0aFxyXG4gKiBAcmV0dXJucyAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIGNkKHBhdGgpIHtcclxuICAgIGlmIChwYXRoKSB7XHJcbiAgICAgICAgc2hlbGwuY2QocGF0aCk7XHJcbiAgICAgICAgX2NoZWNrU2hlbGwoJ2NkJyk7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy5jZCA9IGNkO1xyXG4vKipcclxuICogQ2hhbmdlIHdvcmtpbmcgZGlyZWN0b3J5IGFuZCBwdXNoIGl0IG9uIHRoZSBzdGFja1xyXG4gKlxyXG4gKiBAcGFyYW0gICAgIHBhdGggICAgICBuZXcgd29ya2luZyBkaXJlY3RvcnkgcGF0aFxyXG4gKiBAcmV0dXJucyAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIHB1c2hkKHBhdGgpIHtcclxuICAgIHNoZWxsLnB1c2hkKHBhdGgpO1xyXG4gICAgX2NoZWNrU2hlbGwoJ3B1c2hkJyk7XHJcbn1cclxuZXhwb3J0cy5wdXNoZCA9IHB1c2hkO1xyXG4vKipcclxuICogQ2hhbmdlIHdvcmtpbmcgZGlyZWN0b3J5IGJhY2sgdG8gcHJldmlvdXNseSBwdXNoZWQgZGlyZWN0b3J5XHJcbiAqXHJcbiAqIEByZXR1cm5zICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gcG9wZCgpIHtcclxuICAgIHNoZWxsLnBvcGQoKTtcclxuICAgIF9jaGVja1NoZWxsKCdwb3BkJyk7XHJcbn1cclxuZXhwb3J0cy5wb3BkID0gcG9wZDtcclxuLyoqXHJcbiAqIE1ha2UgYSBkaXJlY3RvcnkuICBDcmVhdGVzIHRoZSBmdWxsIHBhdGggd2l0aCBmb2xkZXJzIGluIGJldHdlZW5cclxuICogV2lsbCB0aHJvdyBpZiBpdCBmYWlsc1xyXG4gKlxyXG4gKiBAcGFyYW0gICAgIHAgICAgICAgcGF0aCB0byBjcmVhdGVcclxuICogQHJldHVybnMgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiBta2RpclAocCkge1xyXG4gICAgaWYgKCFwKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMubG9jKCdMSUJfUGFyYW1ldGVySXNSZXF1aXJlZCcsICdwJykpO1xyXG4gICAgfVxyXG4gICAgLy8gYnVpbGQgYSBzdGFjayBvZiBkaXJlY3RvcmllcyB0byBjcmVhdGVcclxuICAgIHZhciBzdGFjayA9IFtdO1xyXG4gICAgdmFyIHRlc3REaXIgPSBwO1xyXG4gICAgd2hpbGUgKHRydWUpIHtcclxuICAgICAgICAvLyB2YWxpZGF0ZSB0aGUgbG9vcCBpcyBub3Qgb3V0IG9mIGNvbnRyb2xcclxuICAgICAgICBpZiAoc3RhY2subGVuZ3RoID49IChwcm9jZXNzLmVudlsnVEFTS0xJQl9URVNUX01LRElSUF9GQUlMU0FGRSddIHx8IDEwMDApKSB7XHJcbiAgICAgICAgICAgIC8vIGxldCB0aGUgZnJhbWV3b3JrIHRocm93XHJcbiAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ2xvb3AgaXMgb3V0IG9mIGNvbnRyb2wnKTtcclxuICAgICAgICAgICAgZnMubWtkaXJTeW5jKHApO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGV4cG9ydHMuZGVidWcoXCJ0ZXN0aW5nIGRpcmVjdG9yeSAnXCIgKyB0ZXN0RGlyICsgXCInXCIpO1xyXG4gICAgICAgIHZhciBzdGF0c18xID0gdm9pZCAwO1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIHN0YXRzXzEgPSBmcy5zdGF0U3luYyh0ZXN0RGlyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT0gJ0VOT0VOVCcpIHtcclxuICAgICAgICAgICAgICAgIC8vIHZhbGlkYXRlIHRoZSBkaXJlY3RvcnkgaXMgbm90IHRoZSBkcml2ZSByb290XHJcbiAgICAgICAgICAgICAgICB2YXIgcGFyZW50RGlyID0gcGF0aC5kaXJuYW1lKHRlc3REaXIpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRlc3REaXIgPT0gcGFyZW50RGlyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMubG9jKCdMSUJfTWtkaXJGYWlsZWRJbnZhbGlkRHJpdmVSb290JywgcCwgdGVzdERpcikpOyAvLyBVbmFibGUgdG8gY3JlYXRlIGRpcmVjdG9yeSAne3B9Jy4gUm9vdCBkaXJlY3RvcnkgZG9lcyBub3QgZXhpc3Q6ICd7dGVzdERpcn0nXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBwdXNoIHRoZSBkaXIgYW5kIHRlc3QgdGhlIHBhcmVudFxyXG4gICAgICAgICAgICAgICAgc3RhY2sucHVzaCh0ZXN0RGlyKTtcclxuICAgICAgICAgICAgICAgIHRlc3REaXIgPSBwYXJlbnREaXI7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChlcnIuY29kZSA9PSAnVU5LTk9XTicpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmxvYygnTElCX01rZGlyRmFpbGVkSW52YWxpZFNoYXJlJywgcCwgdGVzdERpcikpOyAvLyBVbmFibGUgdG8gY3JlYXRlIGRpcmVjdG9yeSAne3B9Jy4gVW5hYmxlIHRvIHZlcmlmeSB0aGUgZGlyZWN0b3J5IGV4aXN0czogJ3t0ZXN0RGlyfScuIElmIGRpcmVjdG9yeSBpcyBhIGZpbGUgc2hhcmUsIHBsZWFzZSB2ZXJpZnkgdGhlIHNoYXJlIG5hbWUgaXMgY29ycmVjdCwgdGhlIHNoYXJlIGlzIG9ubGluZSwgYW5kIHRoZSBjdXJyZW50IHByb2Nlc3MgaGFzIHBlcm1pc3Npb24gdG8gYWNjZXNzIHRoZSBzaGFyZS5cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXN0YXRzXzEuaXNEaXJlY3RvcnkoKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9Na2RpckZhaWxlZEZpbGVFeGlzdHMnLCBwLCB0ZXN0RGlyKSk7IC8vIFVuYWJsZSB0byBjcmVhdGUgZGlyZWN0b3J5ICd7cH0nLiBDb25mbGljdGluZyBmaWxlIGV4aXN0czogJ3t0ZXN0RGlyfSdcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gdGVzdERpciBleGlzdHNcclxuICAgICAgICBicmVhaztcclxuICAgIH1cclxuICAgIC8vIGNyZWF0ZSBlYWNoIGRpcmVjdG9yeVxyXG4gICAgd2hpbGUgKHN0YWNrLmxlbmd0aCkge1xyXG4gICAgICAgIHZhciBkaXIgPSBzdGFjay5wb3AoKTsgLy8gbm9uLW51bGwgYmVjYXVzZSBgc3RhY2subGVuZ3RoYCB3YXMgdHJ1dGh5XHJcbiAgICAgICAgZXhwb3J0cy5kZWJ1ZyhcIm1rZGlyICdcIiArIGRpciArIFwiJ1wiKTtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBmcy5ta2RpclN5bmMoZGlyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9Na2RpckZhaWxlZCcsIHAsIGVyci5tZXNzYWdlKSk7IC8vIFVuYWJsZSB0byBjcmVhdGUgZGlyZWN0b3J5ICd7cH0nLiB7ZXJyLm1lc3NhZ2V9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMubWtkaXJQID0gbWtkaXJQO1xyXG4vKipcclxuICogUmVzb2x2ZXMgYSBzZXF1ZW5jZSBvZiBwYXRocyBvciBwYXRoIHNlZ21lbnRzIGludG8gYW4gYWJzb2x1dGUgcGF0aC5cclxuICogQ2FsbHMgbm9kZS5qcyBwYXRoLnJlc29sdmUoKVxyXG4gKiBBbGxvd3MgTDAgdGVzdGluZyB3aXRoIGNvbnNpc3RlbnQgcGF0aCBmb3JtYXRzIG9uIE1hYy9MaW51eCBhbmQgV2luZG93cyBpbiB0aGUgbW9jayBpbXBsZW1lbnRhdGlvblxyXG4gKiBAcGFyYW0gcGF0aFNlZ21lbnRzXHJcbiAqIEByZXR1cm5zIHtzdHJpbmd9XHJcbiAqL1xyXG5mdW5jdGlvbiByZXNvbHZlKCkge1xyXG4gICAgdmFyIHBhdGhTZWdtZW50cyA9IFtdO1xyXG4gICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICBwYXRoU2VnbWVudHNbX2ldID0gYXJndW1lbnRzW19pXTtcclxuICAgIH1cclxuICAgIHZhciBhYnNvbHV0ZVBhdGggPSBwYXRoLnJlc29sdmUuYXBwbHkodGhpcywgcGF0aFNlZ21lbnRzKTtcclxuICAgIGV4cG9ydHMuZGVidWcoJ0Fic29sdXRlIHBhdGggZm9yIHBhdGhTZWdtZW50czogJyArIHBhdGhTZWdtZW50cyArICcgPSAnICsgYWJzb2x1dGVQYXRoKTtcclxuICAgIHJldHVybiBhYnNvbHV0ZVBhdGg7XHJcbn1cclxuZXhwb3J0cy5yZXNvbHZlID0gcmVzb2x2ZTtcclxuZXhwb3J0cy53aGljaCA9IGltLl93aGljaDtcclxuLyoqXHJcbiAqIFJldHVybnMgYXJyYXkgb2YgZmlsZXMgaW4gdGhlIGdpdmVuIHBhdGgsIG9yIGluIGN1cnJlbnQgZGlyZWN0b3J5IGlmIG5vIHBhdGggcHJvdmlkZWQuICBTZWUgc2hlbGxqcy5sc1xyXG4gKiBAcGFyYW0gIHtzdHJpbmd9ICAgb3B0aW9ucyAgQXZhaWxhYmxlIG9wdGlvbnM6IC1SIChyZWN1cnNpdmUpLCAtQSAoYWxsIGZpbGVzLCBpbmNsdWRlIGZpbGVzIGJlZ2lubmluZyB3aXRoIC4sIGV4Y2VwdCBmb3IgLiBhbmQgLi4pXHJcbiAqIEBwYXJhbSAge3N0cmluZ1tdfSBwYXRocyAgICBQYXRocyB0byBzZWFyY2guXHJcbiAqIEByZXR1cm4ge3N0cmluZ1tdfSAgICAgICAgICBBbiBhcnJheSBvZiBmaWxlcyBpbiB0aGUgZ2l2ZW4gcGF0aChzKS5cclxuICovXHJcbmZ1bmN0aW9uIGxzKG9wdGlvbnMsIHBhdGhzKSB7XHJcbiAgICBpZiAob3B0aW9ucykge1xyXG4gICAgICAgIHJldHVybiBzaGVsbC5scyhvcHRpb25zLCBwYXRocyk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICByZXR1cm4gc2hlbGwubHMocGF0aHMpO1xyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMubHMgPSBscztcclxuLyoqXHJcbiAqIENvcGllcyBhIGZpbGUgb3IgZm9sZGVyLlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIHNvdXJjZSAgICAgc291cmNlIHBhdGhcclxuICogQHBhcmFtICAgICBkZXN0ICAgICAgIGRlc3RpbmF0aW9uIHBhdGhcclxuICogQHBhcmFtICAgICBvcHRpb25zICAgIHN0cmluZyAtciwgLWYgb3IgLXJmIGZvciByZWN1cnNpdmUgYW5kIGZvcmNlXHJcbiAqIEBwYXJhbSAgICAgY29udGludWVPbkVycm9yIG9wdGlvbmFsLiB3aGV0aGVyIHRvIGNvbnRpbnVlIG9uIGVycm9yXHJcbiAqIEBwYXJhbSAgICAgcmV0cnlDb3VudCBvcHRpb25hbC4gUmV0cnkgY291bnQgdG8gY29weSB0aGUgZmlsZS4gSXQgbWlnaHQgaGVscCB0byByZXNvbHZlIGludGVybWl0dGVudCBpc3N1ZXMgZS5nLiB3aXRoIFVOQyB0YXJnZXQgcGF0aHMgb24gYSByZW1vdGUgaG9zdC5cclxuICovXHJcbmZ1bmN0aW9uIGNwKHNvdXJjZSwgZGVzdCwgb3B0aW9ucywgY29udGludWVPbkVycm9yLCByZXRyeUNvdW50KSB7XHJcbiAgICBpZiAocmV0cnlDb3VudCA9PT0gdm9pZCAwKSB7IHJldHJ5Q291bnQgPSAwOyB9XHJcbiAgICB3aGlsZSAocmV0cnlDb3VudCA+PSAwKSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKG9wdGlvbnMpIHtcclxuICAgICAgICAgICAgICAgIHNoZWxsLmNwKG9wdGlvbnMsIHNvdXJjZSwgZGVzdCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBzaGVsbC5jcChzb3VyY2UsIGRlc3QpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIF9jaGVja1NoZWxsKCdjcCcsIGZhbHNlKTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIGlmIChyZXRyeUNvdW50IDw9IDApIHtcclxuICAgICAgICAgICAgICAgIGlmIChjb250aW51ZU9uRXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICBleHBvcnRzLndhcm5pbmcoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coZXhwb3J0cy5sb2MoJ0xJQl9Db3B5RmlsZUZhaWxlZCcsIHJldHJ5Q291bnQpKTtcclxuICAgICAgICAgICAgICAgIHJldHJ5Q291bnQtLTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5leHBvcnRzLmNwID0gY3A7XHJcbi8qKlxyXG4gKiBNb3ZlcyBhIHBhdGguXHJcbiAqXHJcbiAqIEBwYXJhbSAgICAgc291cmNlICAgICBzb3VyY2UgcGF0aFxyXG4gKiBAcGFyYW0gICAgIGRlc3QgICAgICAgZGVzdGluYXRpb24gcGF0aFxyXG4gKiBAcGFyYW0gICAgIG9wdGlvbnMgICAgc3RyaW5nIC1mIG9yIC1uIGZvciBmb3JjZSBhbmQgbm8gY2xvYmJlclxyXG4gKiBAcGFyYW0gICAgIGNvbnRpbnVlT25FcnJvciBvcHRpb25hbC4gd2hldGhlciB0byBjb250aW51ZSBvbiBlcnJvclxyXG4gKi9cclxuZnVuY3Rpb24gbXYoc291cmNlLCBkZXN0LCBvcHRpb25zLCBjb250aW51ZU9uRXJyb3IpIHtcclxuICAgIGlmIChvcHRpb25zKSB7XHJcbiAgICAgICAgc2hlbGwubXYob3B0aW9ucywgc291cmNlLCBkZXN0KTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHNoZWxsLm12KHNvdXJjZSwgZGVzdCk7XHJcbiAgICB9XHJcbiAgICBfY2hlY2tTaGVsbCgnbXYnLCBjb250aW51ZU9uRXJyb3IpO1xyXG59XHJcbmV4cG9ydHMubXYgPSBtdjtcclxuLyoqXHJcbiAqIFJlY3Vyc2l2ZWx5IGZpbmRzIGFsbCBwYXRocyBhIGdpdmVuIHBhdGguIFJldHVybnMgYW4gYXJyYXkgb2YgcGF0aHMuXHJcbiAqXHJcbiAqIEBwYXJhbSAgICAgZmluZFBhdGggIHBhdGggdG8gc2VhcmNoXHJcbiAqIEBwYXJhbSAgICAgb3B0aW9ucyAgIG9wdGlvbmFsLiBkZWZhdWx0cyB0byB7IGZvbGxvd1N5bWJvbGljTGlua3M6IHRydWUgfS4gZm9sbG93aW5nIHNvZnQgbGlua3MgaXMgZ2VuZXJhbGx5IGFwcHJvcHJpYXRlIHVubGVzcyBkZWxldGluZyBmaWxlcy5cclxuICogQHJldHVybnMgICBzdHJpbmdbXVxyXG4gKi9cclxuZnVuY3Rpb24gZmluZChmaW5kUGF0aCwgb3B0aW9ucykge1xyXG4gICAgaWYgKCFmaW5kUGF0aCkge1xyXG4gICAgICAgIGV4cG9ydHMuZGVidWcoJ25vIHBhdGggc3BlY2lmaWVkJyk7XHJcbiAgICAgICAgcmV0dXJuIFtdO1xyXG4gICAgfVxyXG4gICAgLy8gbm9ybWFsaXplIHRoZSBwYXRoLCBvdGhlcndpc2UgdGhlIGZpcnN0IHJlc3VsdCBpcyBpbmNvbnNpc3RlbnRseSBmb3JtYXR0ZWQgZnJvbSB0aGUgcmVzdCBvZiB0aGUgcmVzdWx0c1xyXG4gICAgLy8gYmVjYXVzZSBwYXRoLmpvaW4oKSBwZXJmb3JtcyBub3JtYWxpemF0aW9uLlxyXG4gICAgZmluZFBhdGggPSBwYXRoLm5vcm1hbGl6ZShmaW5kUGF0aCk7XHJcbiAgICAvLyBkZWJ1ZyB0cmFjZSB0aGUgcGFyYW1ldGVyc1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcImZpbmRQYXRoOiAnXCIgKyBmaW5kUGF0aCArIFwiJ1wiKTtcclxuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IF9nZXREZWZhdWx0RmluZE9wdGlvbnMoKTtcclxuICAgIF9kZWJ1Z0ZpbmRPcHRpb25zKG9wdGlvbnMpO1xyXG4gICAgLy8gcmV0dXJuIGVtcHR5IGlmIG5vdCBleGlzdHNcclxuICAgIHRyeSB7XHJcbiAgICAgICAgZnMubHN0YXRTeW5jKGZpbmRQYXRoKTtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICBpZiAoZXJyLmNvZGUgPT0gJ0VOT0VOVCcpIHtcclxuICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZygnMCByZXN1bHRzJyk7XHJcbiAgICAgICAgICAgIHJldHVybiBbXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgfVxyXG4gICAgdHJ5IHtcclxuICAgICAgICB2YXIgcmVzdWx0ID0gW107XHJcbiAgICAgICAgLy8gcHVzaCB0aGUgZmlyc3QgaXRlbVxyXG4gICAgICAgIHZhciBzdGFjayA9IFtuZXcgX0ZpbmRJdGVtKGZpbmRQYXRoLCAxKV07XHJcbiAgICAgICAgdmFyIHRyYXZlcnNhbENoYWluID0gW107IC8vIHVzZWQgdG8gZGV0ZWN0IGN5Y2xlc1xyXG4gICAgICAgIHZhciBfbG9vcF8xID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAvLyBwb3AgdGhlIG5leHQgaXRlbSBhbmQgcHVzaCB0byB0aGUgcmVzdWx0IGFycmF5XHJcbiAgICAgICAgICAgIHZhciBpdGVtID0gc3RhY2sucG9wKCk7IC8vIG5vbi1udWxsIGJlY2F1c2UgYHN0YWNrLmxlbmd0aGAgd2FzIHRydXRoeVxyXG4gICAgICAgICAgICByZXN1bHQucHVzaChpdGVtLnBhdGgpO1xyXG4gICAgICAgICAgICAvLyBzdGF0IHRoZSBpdGVtLiAgdGhlIHN0YXQgaW5mbyBpcyB1c2VkIGZ1cnRoZXIgYmVsb3cgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdG8gdHJhdmVyc2UgZGVlcGVyXHJcbiAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgIC8vIHN0YXQgcmV0dXJucyBpbmZvIGFib3V0IHRoZSB0YXJnZXQgb2YgYSBzeW1saW5rIChvciBzeW1saW5rIGNoYWluKSxcclxuICAgICAgICAgICAgLy8gbHN0YXQgcmV0dXJucyBpbmZvIGFib3V0IGEgc3ltbGluayBpdHNlbGZcclxuICAgICAgICAgICAgdmFyIHN0YXRzXzIgPSB2b2lkIDA7XHJcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmZvbGxvd1N5bWJvbGljTGlua3MpIHtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdXNlIHN0YXQgKGZvbGxvd2luZyBhbGwgc3ltbGlua3MpXHJcbiAgICAgICAgICAgICAgICAgICAgc3RhdHNfMiA9IGZzLnN0YXRTeW5jKGl0ZW0ucGF0aCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVyci5jb2RlID09ICdFTk9FTlQnICYmIG9wdGlvbnMuYWxsb3dCcm9rZW5TeW1ib2xpY0xpbmtzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZhbGxiYWNrIHRvIGxzdGF0IChicm9rZW4gc3ltbGlua3MgYWxsb3dlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHNfMiA9IGZzLmxzdGF0U3luYyhpdGVtLnBhdGgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKFwiICBcIiArIGl0ZW0ucGF0aCArIFwiIChicm9rZW4gc3ltbGluaylcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKG9wdGlvbnMuZm9sbG93U3BlY2lmaWVkU3ltYm9saWNMaW5rICYmIHJlc3VsdC5sZW5ndGggPT0gMSkge1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAvLyB1c2Ugc3RhdCAoZm9sbG93aW5nIHN5bWxpbmtzIGZvciB0aGUgc3BlY2lmaWVkIHBhdGggYW5kIHRoaXMgaXMgdGhlIHNwZWNpZmllZCBwYXRoKVxyXG4gICAgICAgICAgICAgICAgICAgIHN0YXRzXzIgPSBmcy5zdGF0U3luYyhpdGVtLnBhdGgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PSAnRU5PRU5UJyAmJiBvcHRpb25zLmFsbG93QnJva2VuU3ltYm9saWNMaW5rcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBmYWxsYmFjayB0byBsc3RhdCAoYnJva2VuIHN5bWxpbmtzIGFsbG93ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRzXzIgPSBmcy5sc3RhdFN5bmMoaXRlbS5wYXRoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZyhcIiAgXCIgKyBpdGVtLnBhdGggKyBcIiAoYnJva2VuIHN5bWxpbmspXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIHVzZSBsc3RhdCAobm90IGZvbGxvd2luZyBzeW1saW5rcylcclxuICAgICAgICAgICAgICAgIHN0YXRzXzIgPSBmcy5sc3RhdFN5bmMoaXRlbS5wYXRoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBub3RlLCBpc0RpcmVjdG9yeSgpIHJldHVybnMgZmFsc2UgZm9yIHRoZSBsc3RhdCBvZiBhIHN5bWxpbmtcclxuICAgICAgICAgICAgaWYgKHN0YXRzXzIuaXNEaXJlY3RvcnkoKSkge1xyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZyhcIiAgXCIgKyBpdGVtLnBhdGggKyBcIiAoZGlyZWN0b3J5KVwiKTtcclxuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmZvbGxvd1N5bWJvbGljTGlua3MpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIHJlYWxwYXRoXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlYWxQYXRoXzEgPSBmcy5yZWFscGF0aFN5bmMoaXRlbS5wYXRoKTtcclxuICAgICAgICAgICAgICAgICAgICAvLyBmaXh1cCB0aGUgdHJhdmVyc2FsIGNoYWluIHRvIG1hdGNoIHRoZSBpdGVtIGxldmVsXHJcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHRyYXZlcnNhbENoYWluLmxlbmd0aCA+PSBpdGVtLmxldmVsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYXZlcnNhbENoYWluLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAvLyB0ZXN0IGZvciBhIGN5Y2xlXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRyYXZlcnNhbENoYWluLnNvbWUoZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHggPT0gcmVhbFBhdGhfMTsgfSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZygnICAgIGN5Y2xlIGRldGVjdGVkJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImNvbnRpbnVlXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSB0aGUgdHJhdmVyc2FsIGNoYWluXHJcbiAgICAgICAgICAgICAgICAgICAgdHJhdmVyc2FsQ2hhaW4ucHVzaChyZWFsUGF0aF8xKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIHB1c2ggdGhlIGNoaWxkIGl0ZW1zIGluIHJldmVyc2Ugb250byB0aGUgc3RhY2tcclxuICAgICAgICAgICAgICAgIHZhciBjaGlsZExldmVsXzEgPSBpdGVtLmxldmVsICsgMTtcclxuICAgICAgICAgICAgICAgIHZhciBjaGlsZEl0ZW1zID0gZnMucmVhZGRpclN5bmMoaXRlbS5wYXRoKVxyXG4gICAgICAgICAgICAgICAgICAgIC5tYXAoZnVuY3Rpb24gKGNoaWxkTmFtZSkgeyByZXR1cm4gbmV3IF9GaW5kSXRlbShwYXRoLmpvaW4oaXRlbS5wYXRoLCBjaGlsZE5hbWUpLCBjaGlsZExldmVsXzEpOyB9KTtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSBjaGlsZEl0ZW1zLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhY2sucHVzaChjaGlsZEl0ZW1zW2ldKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoXCIgIFwiICsgaXRlbS5wYXRoICsgXCIgKGZpbGUpXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICB3aGlsZSAoc3RhY2subGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIF9sb29wXzEoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZXhwb3J0cy5kZWJ1ZyhyZXN1bHQubGVuZ3RoICsgXCIgcmVzdWx0c1wiKTtcclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmxvYygnTElCX09wZXJhdGlvbkZhaWxlZCcsICdmaW5kJywgZXJyLm1lc3NhZ2UpKTtcclxuICAgIH1cclxufVxyXG5leHBvcnRzLmZpbmQgPSBmaW5kO1xyXG52YXIgX0ZpbmRJdGVtID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgZnVuY3Rpb24gX0ZpbmRJdGVtKHBhdGgsIGxldmVsKSB7XHJcbiAgICAgICAgdGhpcy5wYXRoID0gcGF0aDtcclxuICAgICAgICB0aGlzLmxldmVsID0gbGV2ZWw7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX0ZpbmRJdGVtO1xyXG59KCkpO1xyXG5mdW5jdGlvbiBfZGVidWdGaW5kT3B0aW9ucyhvcHRpb25zKSB7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwiZmluZE9wdGlvbnMuYWxsb3dCcm9rZW5TeW1ib2xpY0xpbmtzOiAnXCIgKyBvcHRpb25zLmFsbG93QnJva2VuU3ltYm9saWNMaW5rcyArIFwiJ1wiKTtcclxuICAgIGV4cG9ydHMuZGVidWcoXCJmaW5kT3B0aW9ucy5mb2xsb3dTcGVjaWZpZWRTeW1ib2xpY0xpbms6ICdcIiArIG9wdGlvbnMuZm9sbG93U3BlY2lmaWVkU3ltYm9saWNMaW5rICsgXCInXCIpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcImZpbmRPcHRpb25zLmZvbGxvd1N5bWJvbGljTGlua3M6ICdcIiArIG9wdGlvbnMuZm9sbG93U3ltYm9saWNMaW5rcyArIFwiJ1wiKTtcclxufVxyXG5mdW5jdGlvbiBfZ2V0RGVmYXVsdEZpbmRPcHRpb25zKCkge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBhbGxvd0Jyb2tlblN5bWJvbGljTGlua3M6IGZhbHNlLFxyXG4gICAgICAgIGZvbGxvd1NwZWNpZmllZFN5bWJvbGljTGluazogdHJ1ZSxcclxuICAgICAgICBmb2xsb3dTeW1ib2xpY0xpbmtzOiB0cnVlXHJcbiAgICB9O1xyXG59XHJcbi8qKlxyXG4gKiBQcmVmZXIgdGwuZmluZCgpIGFuZCB0bC5tYXRjaCgpIGluc3RlYWQuIFRoaXMgZnVuY3Rpb24gaXMgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHlcclxuICogd2hlbiBwb3J0aW5nIHRhc2tzIHRvIE5vZGUgZnJvbSB0aGUgUG93ZXJTaGVsbCBvciBQb3dlclNoZWxsMyBleGVjdXRpb24gaGFuZGxlci5cclxuICpcclxuICogQHBhcmFtICAgIHJvb3REaXJlY3RvcnkgICAgICBwYXRoIHRvIHJvb3QgdW5yb290ZWQgcGF0dGVybnMgd2l0aFxyXG4gKiBAcGFyYW0gICAgcGF0dGVybiAgICAgICAgICAgIGluY2x1ZGUgYW5kIGV4Y2x1ZGUgcGF0dGVybnNcclxuICogQHBhcmFtICAgIGluY2x1ZGVGaWxlcyAgICAgICB3aGV0aGVyIHRvIGluY2x1ZGUgZmlsZXMgaW4gdGhlIHJlc3VsdC4gZGVmYXVsdHMgdG8gdHJ1ZSB3aGVuIGluY2x1ZGVGaWxlcyBhbmQgaW5jbHVkZURpcmVjdG9yaWVzIGFyZSBib3RoIGZhbHNlXHJcbiAqIEBwYXJhbSAgICBpbmNsdWRlRGlyZWN0b3JpZXMgd2hldGhlciB0byBpbmNsdWRlIGRpcmVjdG9yaWVzIGluIHRoZSByZXN1bHRcclxuICogQHJldHVybnMgIHN0cmluZ1tdXHJcbiAqL1xyXG5mdW5jdGlvbiBsZWdhY3lGaW5kRmlsZXMocm9vdERpcmVjdG9yeSwgcGF0dGVybiwgaW5jbHVkZUZpbGVzLCBpbmNsdWRlRGlyZWN0b3JpZXMpIHtcclxuICAgIGlmICghcGF0dGVybikge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcigncGF0dGVybiBwYXJhbWV0ZXIgY2Fubm90IGJlIGVtcHR5Jyk7XHJcbiAgICB9XHJcbiAgICBleHBvcnRzLmRlYnVnKFwibGVnYWN5RmluZEZpbGVzIHJvb3REaXJlY3Rvcnk6ICdcIiArIHJvb3REaXJlY3RvcnkgKyBcIidcIik7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwicGF0dGVybjogJ1wiICsgcGF0dGVybiArIFwiJ1wiKTtcclxuICAgIGV4cG9ydHMuZGVidWcoXCJpbmNsdWRlRmlsZXM6ICdcIiArIGluY2x1ZGVGaWxlcyArIFwiJ1wiKTtcclxuICAgIGV4cG9ydHMuZGVidWcoXCJpbmNsdWRlRGlyZWN0b3JpZXM6ICdcIiArIGluY2x1ZGVEaXJlY3RvcmllcyArIFwiJ1wiKTtcclxuICAgIGlmICghaW5jbHVkZUZpbGVzICYmICFpbmNsdWRlRGlyZWN0b3JpZXMpIHtcclxuICAgICAgICBpbmNsdWRlRmlsZXMgPSB0cnVlO1xyXG4gICAgfVxyXG4gICAgLy8gb3JnYW5pemUgdGhlIHBhdHRlcm5zIGludG8gaW5jbHVkZSBwYXR0ZXJucyBhbmQgZXhjbHVkZSBwYXR0ZXJuc1xyXG4gICAgdmFyIGluY2x1ZGVQYXR0ZXJucyA9IFtdO1xyXG4gICAgdmFyIGV4Y2x1ZGVQYXR0ZXJucyA9IFtdO1xyXG4gICAgcGF0dGVybiA9IHBhdHRlcm4ucmVwbGFjZSgvOzsvZywgJ1xcMCcpO1xyXG4gICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHBhdHRlcm4uc3BsaXQoJzsnKTsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICB2YXIgcGF0ID0gX2FbX2ldO1xyXG4gICAgICAgIGlmICghcGF0KSB7XHJcbiAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBwYXQgPSBwYXQucmVwbGFjZSgvXFwwL2csICc7Jyk7XHJcbiAgICAgICAgLy8gZGV0ZXJtaW5lIHdoZXRoZXIgaW5jbHVkZSBwYXR0ZXJuIGFuZCByZW1vdmUgYW55IGluY2x1ZGUvZXhjbHVkZSBwcmVmaXguXHJcbiAgICAgICAgLy8gaW5jbHVkZSBwYXR0ZXJucyBzdGFydCB3aXRoICs6IG9yIGFueXRoaW5nIG90aGVyIHRoYW4gLTpcclxuICAgICAgICAvLyBleGNsdWRlIHBhdHRlcm5zIHN0YXJ0IHdpdGggLTpcclxuICAgICAgICB2YXIgaXNJbmNsdWRlUGF0dGVybiA9IHZvaWQgMDtcclxuICAgICAgICBpZiAoaW0uX3N0YXJ0c1dpdGgocGF0LCAnKzonKSkge1xyXG4gICAgICAgICAgICBwYXQgPSBwYXQuc3Vic3RyaW5nKDIpO1xyXG4gICAgICAgICAgICBpc0luY2x1ZGVQYXR0ZXJuID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoaW0uX3N0YXJ0c1dpdGgocGF0LCAnLTonKSkge1xyXG4gICAgICAgICAgICBwYXQgPSBwYXQuc3Vic3RyaW5nKDIpO1xyXG4gICAgICAgICAgICBpc0luY2x1ZGVQYXR0ZXJuID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBpc0luY2x1ZGVQYXR0ZXJuID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gdmFsaWRhdGUgcGF0dGVybiBkb2VzIG5vdCBlbmQgd2l0aCBhIHNsYXNoXHJcbiAgICAgICAgaWYgKGltLl9lbmRzV2l0aChwYXQsICcvJykgfHwgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJyAmJiBpbS5fZW5kc1dpdGgocGF0LCAnXFxcXCcpKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9JbnZhbGlkUGF0dGVybicsIHBhdCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyByb290IHRoZSBwYXR0ZXJuXHJcbiAgICAgICAgaWYgKHJvb3REaXJlY3RvcnkgJiYgIXBhdGguaXNBYnNvbHV0ZShwYXQpKSB7XHJcbiAgICAgICAgICAgIHBhdCA9IHBhdGguam9pbihyb290RGlyZWN0b3J5LCBwYXQpO1xyXG4gICAgICAgICAgICAvLyByZW1vdmUgdHJhaWxpbmcgc2xhc2ggc29tZXRpbWVzIGFkZGVkIGJ5IHBhdGguam9pbigpIG9uIFdpbmRvd3MsIGUuZy5cclxuICAgICAgICAgICAgLy8gICAgICBwYXRoLmpvaW4oJ1xcXFxcXFxcaGVsbG8nLCAnd29ybGQnKSA9PiAnXFxcXFxcXFxoZWxsb1xcXFx3b3JsZFxcXFwnXHJcbiAgICAgICAgICAgIC8vICAgICAgcGF0aC5qb2luKCcvL2hlbGxvJywgJ3dvcmxkJykgPT4gJ1xcXFxcXFxcaGVsbG9cXFxcd29ybGRcXFxcJ1xyXG4gICAgICAgICAgICBpZiAoaW0uX2VuZHNXaXRoKHBhdCwgJ1xcXFwnKSkge1xyXG4gICAgICAgICAgICAgICAgcGF0ID0gcGF0LnN1YnN0cmluZygwLCBwYXQubGVuZ3RoIC0gMSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGlzSW5jbHVkZVBhdHRlcm4pIHtcclxuICAgICAgICAgICAgaW5jbHVkZVBhdHRlcm5zLnB1c2gocGF0KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGV4Y2x1ZGVQYXR0ZXJucy5wdXNoKGltLl9sZWdhY3lGaW5kRmlsZXNfY29udmVydFBhdHRlcm5Ub1JlZ0V4cChwYXQpKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyBmaW5kIGFuZCBhcHBseSBwYXR0ZXJuc1xyXG4gICAgdmFyIGNvdW50ID0gMDtcclxuICAgIHZhciByZXN1bHQgPSBfbGVnYWN5RmluZEZpbGVzX2dldE1hdGNoaW5nSXRlbXMoaW5jbHVkZVBhdHRlcm5zLCBleGNsdWRlUGF0dGVybnMsICEhaW5jbHVkZUZpbGVzLCAhIWluY2x1ZGVEaXJlY3Rvcmllcyk7XHJcbiAgICBleHBvcnRzLmRlYnVnKCdhbGwgbWF0Y2hlczonKTtcclxuICAgIGZvciAodmFyIF9iID0gMCwgcmVzdWx0XzEgPSByZXN1bHQ7IF9iIDwgcmVzdWx0XzEubGVuZ3RoOyBfYisrKSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdEl0ZW0gPSByZXN1bHRfMVtfYl07XHJcbiAgICAgICAgZXhwb3J0cy5kZWJ1ZygnICcgKyByZXN1bHRJdGVtKTtcclxuICAgIH1cclxuICAgIGV4cG9ydHMuZGVidWcoJ3RvdGFsIG1hdGNoZWQ6ICcgKyByZXN1bHQubGVuZ3RoKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuZXhwb3J0cy5sZWdhY3lGaW5kRmlsZXMgPSBsZWdhY3lGaW5kRmlsZXM7XHJcbmZ1bmN0aW9uIF9sZWdhY3lGaW5kRmlsZXNfZ2V0TWF0Y2hpbmdJdGVtcyhpbmNsdWRlUGF0dGVybnMsIGV4Y2x1ZGVQYXR0ZXJucywgaW5jbHVkZUZpbGVzLCBpbmNsdWRlRGlyZWN0b3JpZXMpIHtcclxuICAgIGV4cG9ydHMuZGVidWcoJ2dldE1hdGNoaW5nSXRlbXMoKScpO1xyXG4gICAgZm9yICh2YXIgX2kgPSAwLCBpbmNsdWRlUGF0dGVybnNfMSA9IGluY2x1ZGVQYXR0ZXJuczsgX2kgPCBpbmNsdWRlUGF0dGVybnNfMS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICB2YXIgcGF0dGVybiA9IGluY2x1ZGVQYXR0ZXJuc18xW19pXTtcclxuICAgICAgICBleHBvcnRzLmRlYnVnKFwiaW5jbHVkZVBhdHRlcm46ICdcIiArIHBhdHRlcm4gKyBcIidcIik7XHJcbiAgICB9XHJcbiAgICBmb3IgKHZhciBfYSA9IDAsIGV4Y2x1ZGVQYXR0ZXJuc18xID0gZXhjbHVkZVBhdHRlcm5zOyBfYSA8IGV4Y2x1ZGVQYXR0ZXJuc18xLmxlbmd0aDsgX2ErKykge1xyXG4gICAgICAgIHZhciBwYXR0ZXJuID0gZXhjbHVkZVBhdHRlcm5zXzFbX2FdO1xyXG4gICAgICAgIGV4cG9ydHMuZGVidWcoXCJleGNsdWRlUGF0dGVybjogXCIgKyBwYXR0ZXJuKTtcclxuICAgIH1cclxuICAgIGV4cG9ydHMuZGVidWcoJ2luY2x1ZGVGaWxlczogJyArIGluY2x1ZGVGaWxlcyk7XHJcbiAgICBleHBvcnRzLmRlYnVnKCdpbmNsdWRlRGlyZWN0b3JpZXM6ICcgKyBpbmNsdWRlRGlyZWN0b3JpZXMpO1xyXG4gICAgdmFyIGFsbEZpbGVzID0ge307XHJcbiAgICB2YXIgX2xvb3BfMiA9IGZ1bmN0aW9uIChwYXR0ZXJuKSB7XHJcbiAgICAgICAgLy8gZGV0ZXJtaW5lIHRoZSBkaXJlY3RvcnkgdG8gc2VhcmNoXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBub3RlLCBnZXREaXJlY3RvcnlOYW1lIHJlbW92ZXMgcmVkdW5kYW50IHBhdGggc2VwYXJhdG9yc1xyXG4gICAgICAgIHZhciBmaW5kUGF0aCA9IHZvaWQgMDtcclxuICAgICAgICB2YXIgc3RhckluZGV4ID0gcGF0dGVybi5pbmRleE9mKCcqJyk7XHJcbiAgICAgICAgdmFyIHF1ZXN0aW9uSW5kZXggPSBwYXR0ZXJuLmluZGV4T2YoJz8nKTtcclxuICAgICAgICBpZiAoc3RhckluZGV4IDwgMCAmJiBxdWVzdGlvbkluZGV4IDwgMCkge1xyXG4gICAgICAgICAgICAvLyBpZiBubyB3aWxkY2FyZHMgYXJlIGZvdW5kLCB1c2UgdGhlIGRpcmVjdG9yeSBuYW1lIHBvcnRpb24gb2YgdGhlIHBhdGguXHJcbiAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIGRpcmVjdG9yeSBuYW1lIChmaWxlIG5hbWUgb25seSBpbiBwYXR0ZXJuIG9yIGRyaXZlIHJvb3QpLFxyXG4gICAgICAgICAgICAvLyB0aGlzIHdpbGwgcmV0dXJuIGVtcHR5IHN0cmluZy5cclxuICAgICAgICAgICAgZmluZFBhdGggPSBpbS5fZ2V0RGlyZWN0b3J5TmFtZShwYXR0ZXJuKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIGV4dHJhY3QgdGhlIGRpcmVjdG9yeSBwcmlvciB0byB0aGUgZmlyc3Qgd2lsZGNhcmRcclxuICAgICAgICAgICAgdmFyIGluZGV4ID0gTWF0aC5taW4oc3RhckluZGV4ID49IDAgPyBzdGFySW5kZXggOiBxdWVzdGlvbkluZGV4LCBxdWVzdGlvbkluZGV4ID49IDAgPyBxdWVzdGlvbkluZGV4IDogc3RhckluZGV4KTtcclxuICAgICAgICAgICAgZmluZFBhdGggPSBpbS5fZ2V0RGlyZWN0b3J5TmFtZShwYXR0ZXJuLnN1YnN0cmluZygwLCBpbmRleCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBub3RlLCBkdWUgdG8gdGhpcyBzaG9ydC1jaXJjdWl0IGFuZCB0aGUgYWJvdmUgdXNhZ2Ugb2YgZ2V0RGlyZWN0b3J5TmFtZSwgdGhpc1xyXG4gICAgICAgIC8vIGZ1bmN0aW9uIGhhcyB0aGUgc2FtZSBsaW1pdGF0aW9ucyByZWdhcmRpbmcgZHJpdmUgcm9vdHMgYXMgdGhlIHBvd2Vyc2hlbGxcclxuICAgICAgICAvLyBpbXBsZW1lbnRhdGlvbi5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIGFsc28gbm90ZSwgc2luY2UgZ2V0RGlyZWN0b3J5TmFtZSBlbGltaW5hdGVzIHNsYXNoIHJlZHVuZGFuY2llcywgc29tZSBhZGRpdGlvbmFsXHJcbiAgICAgICAgLy8gd29yayBtYXkgYmUgcmVxdWlyZWQgaWYgcmVtb3ZhbCBvZiB0aGlzIGxpbWl0YXRpb24gaXMgYXR0ZW1wdGVkLlxyXG4gICAgICAgIGlmICghZmluZFBhdGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFwiY29udGludWVcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHBhdHRlcm5SZWdleCA9IGltLl9sZWdhY3lGaW5kRmlsZXNfY29udmVydFBhdHRlcm5Ub1JlZ0V4cChwYXR0ZXJuKTtcclxuICAgICAgICAvLyBmaW5kIGZpbGVzL2RpcmVjdG9yaWVzXHJcbiAgICAgICAgdmFyIGl0ZW1zID0gZmluZChmaW5kUGF0aCwgeyBmb2xsb3dTeW1ib2xpY0xpbmtzOiB0cnVlIH0pXHJcbiAgICAgICAgICAgIC5maWx0ZXIoZnVuY3Rpb24gKGl0ZW0pIHtcclxuICAgICAgICAgICAgaWYgKGluY2x1ZGVGaWxlcyAmJiBpbmNsdWRlRGlyZWN0b3JpZXMpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhciBpc0RpciA9IGZzLnN0YXRTeW5jKGl0ZW0pLmlzRGlyZWN0b3J5KCk7XHJcbiAgICAgICAgICAgIHJldHVybiAoaW5jbHVkZUZpbGVzICYmICFpc0RpcikgfHwgKGluY2x1ZGVEaXJlY3RvcmllcyAmJiBpc0Rpcik7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAgICAgLmZvckVhY2goZnVuY3Rpb24gKGl0ZW0pIHtcclxuICAgICAgICAgICAgdmFyIG5vcm1hbGl6ZWRQYXRoID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInID8gaXRlbS5yZXBsYWNlKC9cXFxcL2csICcvJykgOiBpdGVtOyAvLyBub3JtYWxpemUgc2VwYXJhdG9yc1xyXG4gICAgICAgICAgICAvLyAqKi90aW1lcy8qKiB3aWxsIG5vdCBtYXRjaCBDOi9mdW4vdGltZXMgYmVjYXVzZSB0aGVyZSBpc24ndCBhIHRyYWlsaW5nIHNsYXNoXHJcbiAgICAgICAgICAgIC8vIHNvIHRyeSBib3RoIGlmIGluY2x1ZGluZyBkaXJlY3Rvcmllc1xyXG4gICAgICAgICAgICB2YXIgYWx0ZXJuYXRlUGF0aCA9IG5vcm1hbGl6ZWRQYXRoICsgXCIvXCI7IC8vIHBvdGVudGlhbCBidWc6IGl0IGxvb2tzIGxpa2UgdGhpcyB3aWxsIHJlc3VsdCBpbiBhIGZhbHNlXHJcbiAgICAgICAgICAgIC8vIHBvc2l0aXZlIGlmIHRoZSBpdGVtIGlzIGEgcmVndWxhciBmaWxlIGFuZCBub3QgYSBkaXJlY3RvcnlcclxuICAgICAgICAgICAgdmFyIGlzTWF0Y2ggPSBmYWxzZTtcclxuICAgICAgICAgICAgaWYgKHBhdHRlcm5SZWdleC50ZXN0KG5vcm1hbGl6ZWRQYXRoKSB8fCAoaW5jbHVkZURpcmVjdG9yaWVzICYmIHBhdHRlcm5SZWdleC50ZXN0KGFsdGVybmF0ZVBhdGgpKSkge1xyXG4gICAgICAgICAgICAgICAgaXNNYXRjaCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAvLyB0ZXN0IHdoZXRoZXIgdGhlIHBhdGggc2hvdWxkIGJlIGV4Y2x1ZGVkXHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIGV4Y2x1ZGVQYXR0ZXJuc18yID0gZXhjbHVkZVBhdHRlcm5zOyBfaSA8IGV4Y2x1ZGVQYXR0ZXJuc18yLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZWdleCA9IGV4Y2x1ZGVQYXR0ZXJuc18yW19pXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocmVnZXgudGVzdChub3JtYWxpemVkUGF0aCkgfHwgKGluY2x1ZGVEaXJlY3RvcmllcyAmJiByZWdleC50ZXN0KGFsdGVybmF0ZVBhdGgpKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpc01hdGNoID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoaXNNYXRjaCkge1xyXG4gICAgICAgICAgICAgICAgYWxsRmlsZXNbaXRlbV0gPSBpdGVtO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgZm9yICh2YXIgX2IgPSAwLCBpbmNsdWRlUGF0dGVybnNfMiA9IGluY2x1ZGVQYXR0ZXJuczsgX2IgPCBpbmNsdWRlUGF0dGVybnNfMi5sZW5ndGg7IF9iKyspIHtcclxuICAgICAgICB2YXIgcGF0dGVybiA9IGluY2x1ZGVQYXR0ZXJuc18yW19iXTtcclxuICAgICAgICBfbG9vcF8yKHBhdHRlcm4pO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGFsbEZpbGVzKS5zb3J0KCk7XHJcbn1cclxuLyoqXHJcbiAqIFJlbW92ZSBhIHBhdGggcmVjdXJzaXZlbHkgd2l0aCBmb3JjZVxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIGlucHV0UGF0aCBwYXRoIHRvIHJlbW92ZVxyXG4gKiBAdGhyb3dzICAgIHdoZW4gdGhlIGZpbGUgb3IgZGlyZWN0b3J5IGV4aXN0cyBidXQgY291bGQgbm90IGJlIGRlbGV0ZWQuXHJcbiAqL1xyXG5mdW5jdGlvbiBybVJGKGlucHV0UGF0aCkge1xyXG4gICAgZXhwb3J0cy5kZWJ1Zygncm0gLXJmICcgKyBpbnB1dFBhdGgpO1xyXG4gICAgaWYgKGdldFBsYXRmb3JtKCkgPT0gUGxhdGZvcm0uV2luZG93cykge1xyXG4gICAgICAgIC8vIE5vZGUgZG9lc24ndCBwcm92aWRlIGEgZGVsZXRlIG9wZXJhdGlvbiwgb25seSBhbiB1bmxpbmsgZnVuY3Rpb24uIFRoaXMgbWVhbnMgdGhhdCBpZiB0aGUgZmlsZSBpcyBiZWluZyB1c2VkIGJ5IGFub3RoZXJcclxuICAgICAgICAvLyBwcm9ncmFtIChlLmcuIGFudGl2aXJ1cyksIGl0IHdvbid0IGJlIGRlbGV0ZWQuIFRvIGFkZHJlc3MgdGhpcywgd2Ugc2hlbGwgb3V0IHRoZSB3b3JrIHRvIHJkL2RlbC5cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZnMuc3RhdFN5bmMoaW5wdXRQYXRoKS5pc0RpcmVjdG9yeSgpKSB7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdyZW1vdmluZyBkaXJlY3RvcnkgJyArIGlucHV0UGF0aCk7XHJcbiAgICAgICAgICAgICAgICBjaGlsZFByb2Nlc3MuZXhlY1N5bmMoXCJyZCAvcyAvcSBcXFwiXCIgKyBpbnB1dFBhdGggKyBcIlxcXCJcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdyZW1vdmluZyBmaWxlICcgKyBpbnB1dFBhdGgpO1xyXG4gICAgICAgICAgICAgICAgY2hpbGRQcm9jZXNzLmV4ZWNTeW5jKFwiZGVsIC9mIC9hIFxcXCJcIiArIGlucHV0UGF0aCArIFwiXFxcIlwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgIC8vIGlmIHlvdSB0cnkgdG8gZGVsZXRlIGEgZmlsZSB0aGF0IGRvZXNuJ3QgZXhpc3QsIGRlc2lyZWQgcmVzdWx0IGlzIGFjaGlldmVkXHJcbiAgICAgICAgICAgIC8vIG90aGVyIGVycm9ycyBhcmUgdmFsaWRcclxuICAgICAgICAgICAgaWYgKGVyci5jb2RlICE9ICdFTk9FTlQnKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9PcGVyYXRpb25GYWlsZWQnLCAncm1SRicsIGVyci5tZXNzYWdlKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gU2hlbGxpbmcgb3V0IGZhaWxzIHRvIHJlbW92ZSBhIHN5bWxpbmsgZm9sZGVyIHdpdGggbWlzc2luZyBzb3VyY2UsIHRoaXMgdW5saW5rIGNhdGNoZXMgdGhhdFxyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGZzLnVubGlua1N5bmMoaW5wdXRQYXRoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAvLyBpZiB5b3UgdHJ5IHRvIGRlbGV0ZSBhIGZpbGUgdGhhdCBkb2Vzbid0IGV4aXN0LCBkZXNpcmVkIHJlc3VsdCBpcyBhY2hpZXZlZFxyXG4gICAgICAgICAgICAvLyBvdGhlciBlcnJvcnMgYXJlIHZhbGlkXHJcbiAgICAgICAgICAgIGlmIChlcnIuY29kZSAhPSAnRU5PRU5UJykge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMubG9jKCdMSUJfT3BlcmF0aW9uRmFpbGVkJywgJ3JtUkYnLCBlcnIubWVzc2FnZSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgLy8gZ2V0IHRoZSBsc3RhdHMgaW4gb3JkZXIgdG8gd29ya2Fyb3VuZCBhIGJ1ZyBpbiBzaGVsbGpzQDAuMy4wIHdoZXJlIHN5bWxpbmtzXHJcbiAgICAgICAgLy8gd2l0aCBtaXNzaW5nIHRhcmdldHMgYXJlIG5vdCBoYW5kbGVkIGNvcnJlY3RseSBieSBcInJtKCctcmYnLCBwYXRoKVwiXHJcbiAgICAgICAgdmFyIGxzdGF0cyA9IHZvaWQgMDtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBsc3RhdHMgPSBmcy5sc3RhdFN5bmMoaW5wdXRQYXRoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAvLyBpZiB5b3UgdHJ5IHRvIGRlbGV0ZSBhIGZpbGUgdGhhdCBkb2Vzbid0IGV4aXN0LCBkZXNpcmVkIHJlc3VsdCBpcyBhY2hpZXZlZFxyXG4gICAgICAgICAgICAvLyBvdGhlciBlcnJvcnMgYXJlIHZhbGlkXHJcbiAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PSAnRU5PRU5UJykge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmxvYygnTElCX09wZXJhdGlvbkZhaWxlZCcsICdybVJGJywgZXJyLm1lc3NhZ2UpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGxzdGF0cy5pc0RpcmVjdG9yeSgpKSB7XHJcbiAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ3JlbW92aW5nIGRpcmVjdG9yeScpO1xyXG4gICAgICAgICAgICBzaGVsbC5ybSgnLXJmJywgaW5wdXRQYXRoKTtcclxuICAgICAgICAgICAgdmFyIGVyck1zZyA9IHNoZWxsLmVycm9yKCk7XHJcbiAgICAgICAgICAgIGlmIChlcnJNc2cpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmxvYygnTElCX09wZXJhdGlvbkZhaWxlZCcsICdybVJGJywgZXJyTXNnKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBleHBvcnRzLmRlYnVnKCdyZW1vdmluZyBmaWxlJyk7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgZnMudW5saW5rU3luYyhpbnB1dFBhdGgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmxvYygnTElCX09wZXJhdGlvbkZhaWxlZCcsICdybVJGJywgZXJyLm1lc3NhZ2UpKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy5ybVJGID0gcm1SRjtcclxuLyoqXHJcbiAqIEV4ZWMgYSB0b29sLiAgQ29udmVuaWVuY2Ugd3JhcHBlciBvdmVyIFRvb2xSdW5uZXIgdG8gZXhlYyB3aXRoIGFyZ3MgaW4gb25lIGNhbGwuXHJcbiAqIE91dHB1dCB3aWxsIGJlIHN0cmVhbWVkIHRvIHRoZSBsaXZlIGNvbnNvbGUuXHJcbiAqIFJldHVybnMgcHJvbWlzZSB3aXRoIHJldHVybiBjb2RlXHJcbiAqXHJcbiAqIEBwYXJhbSAgICAgdG9vbCAgICAgcGF0aCB0byB0b29sIHRvIGV4ZWNcclxuICogQHBhcmFtICAgICBhcmdzICAgICBhbiBhcmcgc3RyaW5nIG9yIGFycmF5IG9mIGFyZ3NcclxuICogQHBhcmFtICAgICBvcHRpb25zICBvcHRpb25hbCBleGVjIG9wdGlvbnMuICBTZWUgSUV4ZWNPcHRpb25zXHJcbiAqIEByZXR1cm5zICAgbnVtYmVyXHJcbiAqL1xyXG5mdW5jdGlvbiBleGVjKHRvb2wsIGFyZ3MsIG9wdGlvbnMpIHtcclxuICAgIHZhciB0ciA9IHRoaXMudG9vbCh0b29sKTtcclxuICAgIHRyLm9uKCdkZWJ1ZycsIGZ1bmN0aW9uIChkYXRhKSB7XHJcbiAgICAgICAgZXhwb3J0cy5kZWJ1ZyhkYXRhKTtcclxuICAgIH0pO1xyXG4gICAgaWYgKGFyZ3MpIHtcclxuICAgICAgICBpZiAoYXJncyBpbnN0YW5jZW9mIEFycmF5KSB7XHJcbiAgICAgICAgICAgIHRyLmFyZyhhcmdzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIChhcmdzKSA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgdHIubGluZShhcmdzKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdHIuZXhlYyhvcHRpb25zKTtcclxufVxyXG5leHBvcnRzLmV4ZWMgPSBleGVjO1xyXG4vKipcclxuICogRXhlYyBhIHRvb2wgc3luY2hyb25vdXNseS4gIENvbnZlbmllbmNlIHdyYXBwZXIgb3ZlciBUb29sUnVubmVyIHRvIGV4ZWNTeW5jIHdpdGggYXJncyBpbiBvbmUgY2FsbC5cclxuICogT3V0cHV0IHdpbGwgYmUgKm5vdCogYmUgc3RyZWFtZWQgdG8gdGhlIGxpdmUgY29uc29sZS4gIEl0IHdpbGwgYmUgcmV0dXJuZWQgYWZ0ZXIgZXhlY3V0aW9uIGlzIGNvbXBsZXRlLlxyXG4gKiBBcHByb3ByaWF0ZSBmb3Igc2hvcnQgcnVubmluZyB0b29sc1xyXG4gKiBSZXR1cm5zIElFeGVjUmVzdWx0IHdpdGggb3V0cHV0IGFuZCByZXR1cm4gY29kZVxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIHRvb2wgICAgIHBhdGggdG8gdG9vbCB0byBleGVjXHJcbiAqIEBwYXJhbSAgICAgYXJncyAgICAgYW4gYXJnIHN0cmluZyBvciBhcnJheSBvZiBhcmdzXHJcbiAqIEBwYXJhbSAgICAgb3B0aW9ucyAgb3B0aW9uYWwgZXhlYyBvcHRpb25zLiAgU2VlIElFeGVjU3luY09wdGlvbnNcclxuICogQHJldHVybnMgICBJRXhlY1N5bmNSZXN1bHRcclxuICovXHJcbmZ1bmN0aW9uIGV4ZWNTeW5jKHRvb2wsIGFyZ3MsIG9wdGlvbnMpIHtcclxuICAgIHZhciB0ciA9IHRoaXMudG9vbCh0b29sKTtcclxuICAgIHRyLm9uKCdkZWJ1ZycsIGZ1bmN0aW9uIChkYXRhKSB7XHJcbiAgICAgICAgZXhwb3J0cy5kZWJ1ZyhkYXRhKTtcclxuICAgIH0pO1xyXG4gICAgaWYgKGFyZ3MpIHtcclxuICAgICAgICBpZiAoYXJncyBpbnN0YW5jZW9mIEFycmF5KSB7XHJcbiAgICAgICAgICAgIHRyLmFyZyhhcmdzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIChhcmdzKSA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgdHIubGluZShhcmdzKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdHIuZXhlY1N5bmMob3B0aW9ucyk7XHJcbn1cclxuZXhwb3J0cy5leGVjU3luYyA9IGV4ZWNTeW5jO1xyXG4vKipcclxuICogQ29udmVuaWVuY2UgZmFjdG9yeSB0byBjcmVhdGUgYSBUb29sUnVubmVyLlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIHRvb2wgICAgIHBhdGggdG8gdG9vbCB0byBleGVjXHJcbiAqIEByZXR1cm5zICAgVG9vbFJ1bm5lclxyXG4gKi9cclxuZnVuY3Rpb24gdG9vbCh0b29sKSB7XHJcbiAgICB2YXIgdHIgPSBuZXcgdHJtLlRvb2xSdW5uZXIodG9vbCk7XHJcbiAgICB0ci5vbignZGVidWcnLCBmdW5jdGlvbiAobWVzc2FnZSkge1xyXG4gICAgICAgIGV4cG9ydHMuZGVidWcobWVzc2FnZSk7XHJcbiAgICB9KTtcclxuICAgIHJldHVybiB0cjtcclxufVxyXG5leHBvcnRzLnRvb2wgPSB0b29sO1xyXG4vKipcclxuICogQXBwbGllcyBnbG9iIHBhdHRlcm5zIHRvIGEgbGlzdCBvZiBwYXRocy4gU3VwcG9ydHMgaW50ZXJsZWF2ZWQgZXhjbHVkZSBwYXR0ZXJucy5cclxuICpcclxuICogQHBhcmFtICBsaXN0ICAgICAgICAgYXJyYXkgb2YgcGF0aHNcclxuICogQHBhcmFtICBwYXR0ZXJucyAgICAgcGF0dGVybnMgdG8gYXBwbHkuIHN1cHBvcnRzIGludGVybGVhdmVkIGV4Y2x1ZGUgcGF0dGVybnMuXHJcbiAqIEBwYXJhbSAgcGF0dGVyblJvb3QgIG9wdGlvbmFsLiBkZWZhdWx0IHJvb3QgdG8gYXBwbHkgdG8gdW5yb290ZWQgcGF0dGVybnMuIG5vdCBhcHBsaWVkIHRvIGJhc2VuYW1lLW9ubHkgcGF0dGVybnMgd2hlbiBtYXRjaEJhc2U6dHJ1ZS5cclxuICogQHBhcmFtICBvcHRpb25zICAgICAgb3B0aW9uYWwuIGRlZmF1bHRzIHRvIHsgZG90OiB0cnVlLCBub2JyYWNlOiB0cnVlLCBub2Nhc2U6IHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJyB9LlxyXG4gKi9cclxuZnVuY3Rpb24gbWF0Y2gobGlzdCwgcGF0dGVybnMsIHBhdHRlcm5Sb290LCBvcHRpb25zKSB7XHJcbiAgICAvLyB0cmFjZSBwYXJhbWV0ZXJzXHJcbiAgICBleHBvcnRzLmRlYnVnKFwicGF0dGVyblJvb3Q6ICdcIiArIHBhdHRlcm5Sb290ICsgXCInXCIpO1xyXG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwgX2dldERlZmF1bHRNYXRjaE9wdGlvbnMoKTsgLy8gZGVmYXVsdCBtYXRjaCBvcHRpb25zXHJcbiAgICBfZGVidWdNYXRjaE9wdGlvbnMob3B0aW9ucyk7XHJcbiAgICAvLyBjb252ZXJ0IHBhdHRlcm4gdG8gYW4gYXJyYXlcclxuICAgIGlmICh0eXBlb2YgcGF0dGVybnMgPT0gJ3N0cmluZycpIHtcclxuICAgICAgICBwYXR0ZXJucyA9IFtwYXR0ZXJuc107XHJcbiAgICB9XHJcbiAgICAvLyBoYXNodGFibGUgdG8ga2VlcCB0cmFjayBvZiBtYXRjaGVzXHJcbiAgICB2YXIgbWFwID0ge307XHJcbiAgICB2YXIgb3JpZ2luYWxPcHRpb25zID0gb3B0aW9ucztcclxuICAgIGZvciAodmFyIF9pID0gMCwgcGF0dGVybnNfMSA9IHBhdHRlcm5zOyBfaSA8IHBhdHRlcm5zXzEubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBwYXR0ZXJuc18xW19pXTtcclxuICAgICAgICBleHBvcnRzLmRlYnVnKFwicGF0dGVybjogJ1wiICsgcGF0dGVybiArIFwiJ1wiKTtcclxuICAgICAgICAvLyB0cmltIGFuZCBza2lwIGVtcHR5XHJcbiAgICAgICAgcGF0dGVybiA9IChwYXR0ZXJuIHx8ICcnKS50cmltKCk7XHJcbiAgICAgICAgaWYgKCFwYXR0ZXJuKSB7XHJcbiAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ3NraXBwaW5nIGVtcHR5IHBhdHRlcm4nKTtcclxuICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGNsb25lIG1hdGNoIG9wdGlvbnNcclxuICAgICAgICB2YXIgb3B0aW9uc18xID0gaW0uX2Nsb25lTWF0Y2hPcHRpb25zKG9yaWdpbmFsT3B0aW9ucyk7XHJcbiAgICAgICAgLy8gc2tpcCBjb21tZW50c1xyXG4gICAgICAgIGlmICghb3B0aW9uc18xLm5vY29tbWVudCAmJiBpbS5fc3RhcnRzV2l0aChwYXR0ZXJuLCAnIycpKSB7XHJcbiAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ3NraXBwaW5nIGNvbW1lbnQnKTtcclxuICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHNldCBub2NvbW1lbnQgLSBicmFjZSBleHBhbnNpb24gY291bGQgcmVzdWx0IGluIGEgbGVhZGluZyAnIydcclxuICAgICAgICBvcHRpb25zXzEubm9jb21tZW50ID0gdHJ1ZTtcclxuICAgICAgICAvLyBkZXRlcm1pbmUgd2hldGhlciBwYXR0ZXJuIGlzIGluY2x1ZGUgb3IgZXhjbHVkZVxyXG4gICAgICAgIHZhciBuZWdhdGVDb3VudCA9IDA7XHJcbiAgICAgICAgaWYgKCFvcHRpb25zXzEubm9uZWdhdGUpIHtcclxuICAgICAgICAgICAgd2hpbGUgKHBhdHRlcm4uY2hhckF0KG5lZ2F0ZUNvdW50KSA9PSAnIScpIHtcclxuICAgICAgICAgICAgICAgIG5lZ2F0ZUNvdW50Kys7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcGF0dGVybiA9IHBhdHRlcm4uc3Vic3RyaW5nKG5lZ2F0ZUNvdW50KTsgLy8gdHJpbSBsZWFkaW5nICchJ1xyXG4gICAgICAgICAgICBpZiAobmVnYXRlQ291bnQpIHtcclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoXCJ0cmltbWVkIGxlYWRpbmcgJyEnLiBwYXR0ZXJuOiAnXCIgKyBwYXR0ZXJuICsgXCInXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBpc0luY2x1ZGVQYXR0ZXJuID0gbmVnYXRlQ291bnQgPT0gMCB8fFxyXG4gICAgICAgICAgICAobmVnYXRlQ291bnQgJSAyID09IDAgJiYgIW9wdGlvbnNfMS5mbGlwTmVnYXRlKSB8fFxyXG4gICAgICAgICAgICAobmVnYXRlQ291bnQgJSAyID09IDEgJiYgb3B0aW9uc18xLmZsaXBOZWdhdGUpO1xyXG4gICAgICAgIC8vIHNldCBub25lZ2F0ZSAtIGJyYWNlIGV4cGFuc2lvbiBjb3VsZCByZXN1bHQgaW4gYSBsZWFkaW5nICchJ1xyXG4gICAgICAgIG9wdGlvbnNfMS5ub25lZ2F0ZSA9IHRydWU7XHJcbiAgICAgICAgb3B0aW9uc18xLmZsaXBOZWdhdGUgPSBmYWxzZTtcclxuICAgICAgICAvLyBleHBhbmQgYnJhY2VzIC0gcmVxdWlyZWQgdG8gYWNjdXJhdGVseSByb290IHBhdHRlcm5zXHJcbiAgICAgICAgdmFyIGV4cGFuZGVkID0gdm9pZCAwO1xyXG4gICAgICAgIHZhciBwcmVFeHBhbmRlZCA9IHBhdHRlcm47XHJcbiAgICAgICAgaWYgKG9wdGlvbnNfMS5ub2JyYWNlKSB7XHJcbiAgICAgICAgICAgIGV4cGFuZGVkID0gW3BhdHRlcm5dO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgLy8gY29udmVydCBzbGFzaGVzIG9uIFdpbmRvd3MgYmVmb3JlIGNhbGxpbmcgYnJhY2VFeHBhbmQoKS4gdW5mb3J0dW5hdGVseSB0aGlzIG1lYW5zIGJyYWNlcyBjYW5ub3RcclxuICAgICAgICAgICAgLy8gYmUgZXNjYXBlZCBvbiBXaW5kb3dzLCB0aGlzIGxpbWl0YXRpb24gaXMgY29uc2lzdGVudCB3aXRoIGN1cnJlbnQgbGltaXRhdGlvbnMgb2YgbWluaW1hdGNoICgzLjAuMykuXHJcbiAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ2V4cGFuZGluZyBicmFjZXMnKTtcclxuICAgICAgICAgICAgdmFyIGNvbnZlcnRlZFBhdHRlcm4gPSBwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgPyBwYXR0ZXJuLnJlcGxhY2UoL1xcXFwvZywgJy8nKSA6IHBhdHRlcm47XHJcbiAgICAgICAgICAgIGV4cGFuZGVkID0gbWluaW1hdGNoLmJyYWNlRXhwYW5kKGNvbnZlcnRlZFBhdHRlcm4pO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBzZXQgbm9icmFjZVxyXG4gICAgICAgIG9wdGlvbnNfMS5ub2JyYWNlID0gdHJ1ZTtcclxuICAgICAgICBmb3IgKHZhciBfYSA9IDAsIGV4cGFuZGVkXzEgPSBleHBhbmRlZDsgX2EgPCBleHBhbmRlZF8xLmxlbmd0aDsgX2ErKykge1xyXG4gICAgICAgICAgICB2YXIgcGF0dGVybl8xID0gZXhwYW5kZWRfMVtfYV07XHJcbiAgICAgICAgICAgIGlmIChleHBhbmRlZC5sZW5ndGggIT0gMSB8fCBwYXR0ZXJuXzEgIT0gcHJlRXhwYW5kZWQpIHtcclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoXCJwYXR0ZXJuOiAnXCIgKyBwYXR0ZXJuXzEgKyBcIidcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gdHJpbSBhbmQgc2tpcCBlbXB0eVxyXG4gICAgICAgICAgICBwYXR0ZXJuXzEgPSAocGF0dGVybl8xIHx8ICcnKS50cmltKCk7XHJcbiAgICAgICAgICAgIGlmICghcGF0dGVybl8xKSB7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdza2lwcGluZyBlbXB0eSBwYXR0ZXJuJyk7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyByb290IHRoZSBwYXR0ZXJuIHdoZW4gYWxsIG9mIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgdHJ1ZTpcclxuICAgICAgICAgICAgaWYgKHBhdHRlcm5Sb290ICYmIC8vIHBhdHRlcm5Sb290IHN1cHBsaWVkXHJcbiAgICAgICAgICAgICAgICAhaW0uX2lzUm9vdGVkKHBhdHRlcm5fMSkgJiYgLy8gQU5EIHBhdHRlcm4gbm90IHJvb3RlZFxyXG4gICAgICAgICAgICAgICAgLy8gQU5EIG1hdGNoQmFzZTpmYWxzZSBvciBub3QgYmFzZW5hbWUgb25seVxyXG4gICAgICAgICAgICAgICAgKCFvcHRpb25zXzEubWF0Y2hCYXNlIHx8IChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgPyBwYXR0ZXJuXzEucmVwbGFjZSgvXFxcXC9nLCAnLycpIDogcGF0dGVybl8xKS5pbmRleE9mKCcvJykgPj0gMCkpIHtcclxuICAgICAgICAgICAgICAgIHBhdHRlcm5fMSA9IGltLl9lbnN1cmVSb290ZWQocGF0dGVyblJvb3QsIHBhdHRlcm5fMSk7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKFwicm9vdGVkIHBhdHRlcm46ICdcIiArIHBhdHRlcm5fMSArIFwiJ1wiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoaXNJbmNsdWRlUGF0dGVybikge1xyXG4gICAgICAgICAgICAgICAgLy8gYXBwbHkgdGhlIHBhdHRlcm5cclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ2FwcGx5aW5nIGluY2x1ZGUgcGF0dGVybiBhZ2FpbnN0IG9yaWdpbmFsIGxpc3QnKTtcclxuICAgICAgICAgICAgICAgIHZhciBtYXRjaFJlc3VsdHMgPSBtaW5pbWF0Y2gubWF0Y2gobGlzdCwgcGF0dGVybl8xLCBvcHRpb25zXzEpO1xyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZyhtYXRjaFJlc3VsdHMubGVuZ3RoICsgJyBtYXRjaGVzJyk7XHJcbiAgICAgICAgICAgICAgICAvLyB1bmlvbiB0aGUgcmVzdWx0c1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgX2IgPSAwLCBtYXRjaFJlc3VsdHNfMSA9IG1hdGNoUmVzdWx0czsgX2IgPCBtYXRjaFJlc3VsdHNfMS5sZW5ndGg7IF9iKyspIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbWF0Y2hSZXN1bHQgPSBtYXRjaFJlc3VsdHNfMVtfYl07XHJcbiAgICAgICAgICAgICAgICAgICAgbWFwW21hdGNoUmVzdWx0XSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBhcHBseSB0aGUgcGF0dGVyblxyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZygnYXBwbHlpbmcgZXhjbHVkZSBwYXR0ZXJuIGFnYWluc3Qgb3JpZ2luYWwgbGlzdCcpO1xyXG4gICAgICAgICAgICAgICAgdmFyIG1hdGNoUmVzdWx0cyA9IG1pbmltYXRjaC5tYXRjaChsaXN0LCBwYXR0ZXJuXzEsIG9wdGlvbnNfMSk7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKG1hdGNoUmVzdWx0cy5sZW5ndGggKyAnIG1hdGNoZXMnKTtcclxuICAgICAgICAgICAgICAgIC8vIHN1YnN0cmFjdCB0aGUgcmVzdWx0c1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgX2MgPSAwLCBtYXRjaFJlc3VsdHNfMiA9IG1hdGNoUmVzdWx0czsgX2MgPCBtYXRjaFJlc3VsdHNfMi5sZW5ndGg7IF9jKyspIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbWF0Y2hSZXN1bHQgPSBtYXRjaFJlc3VsdHNfMltfY107XHJcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIG1hcFttYXRjaFJlc3VsdF07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyByZXR1cm4gYSBmaWx0ZXJlZCB2ZXJzaW9uIG9mIHRoZSBvcmlnaW5hbCBsaXN0IChwcmVzZXJ2ZXMgb3JkZXIgYW5kIHByZXZlbnRzIGR1cGxpY2F0aW9uKVxyXG4gICAgdmFyIHJlc3VsdCA9IGxpc3QuZmlsdGVyKGZ1bmN0aW9uIChpdGVtKSB7IHJldHVybiBtYXAuaGFzT3duUHJvcGVydHkoaXRlbSk7IH0pO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhyZXN1bHQubGVuZ3RoICsgJyBmaW5hbCByZXN1bHRzJyk7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcbmV4cG9ydHMubWF0Y2ggPSBtYXRjaDtcclxuLyoqXHJcbiAqIEZpbHRlciB0byBhcHBseSBnbG9iIHBhdHRlcm5zXHJcbiAqXHJcbiAqIEBwYXJhbSAgcGF0dGVybiAgcGF0dGVybiB0byBhcHBseVxyXG4gKiBAcGFyYW0gIG9wdGlvbnMgIG9wdGlvbmFsLiBkZWZhdWx0cyB0byB7IGRvdDogdHJ1ZSwgbm9icmFjZTogdHJ1ZSwgbm9jYXNlOiBwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgfS5cclxuICovXHJcbmZ1bmN0aW9uIGZpbHRlcihwYXR0ZXJuLCBvcHRpb25zKSB7XHJcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCBfZ2V0RGVmYXVsdE1hdGNoT3B0aW9ucygpO1xyXG4gICAgcmV0dXJuIG1pbmltYXRjaC5maWx0ZXIocGF0dGVybiwgb3B0aW9ucyk7XHJcbn1cclxuZXhwb3J0cy5maWx0ZXIgPSBmaWx0ZXI7XHJcbmZ1bmN0aW9uIF9kZWJ1Z01hdGNoT3B0aW9ucyhvcHRpb25zKSB7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwibWF0Y2hPcHRpb25zLmRlYnVnOiAnXCIgKyBvcHRpb25zLmRlYnVnICsgXCInXCIpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcIm1hdGNoT3B0aW9ucy5ub2JyYWNlOiAnXCIgKyBvcHRpb25zLm5vYnJhY2UgKyBcIidcIik7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwibWF0Y2hPcHRpb25zLm5vZ2xvYnN0YXI6ICdcIiArIG9wdGlvbnMubm9nbG9ic3RhciArIFwiJ1wiKTtcclxuICAgIGV4cG9ydHMuZGVidWcoXCJtYXRjaE9wdGlvbnMuZG90OiAnXCIgKyBvcHRpb25zLmRvdCArIFwiJ1wiKTtcclxuICAgIGV4cG9ydHMuZGVidWcoXCJtYXRjaE9wdGlvbnMubm9leHQ6ICdcIiArIG9wdGlvbnMubm9leHQgKyBcIidcIik7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwibWF0Y2hPcHRpb25zLm5vY2FzZTogJ1wiICsgb3B0aW9ucy5ub2Nhc2UgKyBcIidcIik7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwibWF0Y2hPcHRpb25zLm5vbnVsbDogJ1wiICsgb3B0aW9ucy5ub251bGwgKyBcIidcIik7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwibWF0Y2hPcHRpb25zLm1hdGNoQmFzZTogJ1wiICsgb3B0aW9ucy5tYXRjaEJhc2UgKyBcIidcIik7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwibWF0Y2hPcHRpb25zLm5vY29tbWVudDogJ1wiICsgb3B0aW9ucy5ub2NvbW1lbnQgKyBcIidcIik7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwibWF0Y2hPcHRpb25zLm5vbmVnYXRlOiAnXCIgKyBvcHRpb25zLm5vbmVnYXRlICsgXCInXCIpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcIm1hdGNoT3B0aW9ucy5mbGlwTmVnYXRlOiAnXCIgKyBvcHRpb25zLmZsaXBOZWdhdGUgKyBcIidcIik7XHJcbn1cclxuZnVuY3Rpb24gX2dldERlZmF1bHRNYXRjaE9wdGlvbnMoKSB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIGRlYnVnOiBmYWxzZSxcclxuICAgICAgICBub2JyYWNlOiB0cnVlLFxyXG4gICAgICAgIG5vZ2xvYnN0YXI6IGZhbHNlLFxyXG4gICAgICAgIGRvdDogdHJ1ZSxcclxuICAgICAgICBub2V4dDogZmFsc2UsXHJcbiAgICAgICAgbm9jYXNlOiBwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicsXHJcbiAgICAgICAgbm9udWxsOiBmYWxzZSxcclxuICAgICAgICBtYXRjaEJhc2U6IGZhbHNlLFxyXG4gICAgICAgIG5vY29tbWVudDogZmFsc2UsXHJcbiAgICAgICAgbm9uZWdhdGU6IGZhbHNlLFxyXG4gICAgICAgIGZsaXBOZWdhdGU6IGZhbHNlXHJcbiAgICB9O1xyXG59XHJcbi8qKlxyXG4gKiBEZXRlcm1pbmVzIHRoZSBmaW5kIHJvb3QgZnJvbSBhIGxpc3Qgb2YgcGF0dGVybnMuIFBlcmZvcm1zIHRoZSBmaW5kIGFuZCB0aGVuIGFwcGxpZXMgdGhlIGdsb2IgcGF0dGVybnMuXHJcbiAqIFN1cHBvcnRzIGludGVybGVhdmVkIGV4Y2x1ZGUgcGF0dGVybnMuIFVucm9vdGVkIHBhdHRlcm5zIGFyZSByb290ZWQgdXNpbmcgZGVmYXVsdFJvb3QsIHVubGVzc1xyXG4gKiBtYXRjaE9wdGlvbnMubWF0Y2hCYXNlIGlzIHNwZWNpZmllZCBhbmQgdGhlIHBhdHRlcm4gaXMgYSBiYXNlbmFtZSBvbmx5LiBGb3IgbWF0Y2hCYXNlIGNhc2VzLCB0aGVcclxuICogZGVmYXVsdFJvb3QgaXMgdXNlZCBhcyB0aGUgZmluZCByb290LlxyXG4gKlxyXG4gKiBAcGFyYW0gIGRlZmF1bHRSb290ICAgZGVmYXVsdCBwYXRoIHRvIHJvb3QgdW5yb290ZWQgcGF0dGVybnMuIGZhbGxzIGJhY2sgdG8gU3lzdGVtLkRlZmF1bHRXb3JraW5nRGlyZWN0b3J5IG9yIHByb2Nlc3MuY3dkKCkuXHJcbiAqIEBwYXJhbSAgcGF0dGVybnMgICAgICBwYXR0ZXJuIG9yIGFycmF5IG9mIHBhdHRlcm5zIHRvIGFwcGx5XHJcbiAqIEBwYXJhbSAgZmluZE9wdGlvbnMgICBkZWZhdWx0cyB0byB7IGZvbGxvd1N5bWJvbGljTGlua3M6IHRydWUgfS4gZm9sbG93aW5nIHNvZnQgbGlua3MgaXMgZ2VuZXJhbGx5IGFwcHJvcHJpYXRlIHVubGVzcyBkZWxldGluZyBmaWxlcy5cclxuICogQHBhcmFtICBtYXRjaE9wdGlvbnMgIGRlZmF1bHRzIHRvIHsgZG90OiB0cnVlLCBub2JyYWNlOiB0cnVlLCBub2Nhc2U6IHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJyB9XHJcbiAqL1xyXG5mdW5jdGlvbiBmaW5kTWF0Y2goZGVmYXVsdFJvb3QsIHBhdHRlcm5zLCBmaW5kT3B0aW9ucywgbWF0Y2hPcHRpb25zKSB7XHJcbiAgICAvLyBhcHBseSBkZWZhdWx0cyBmb3IgcGFyYW1ldGVycyBhbmQgdHJhY2VcclxuICAgIGRlZmF1bHRSb290ID0gZGVmYXVsdFJvb3QgfHwgdGhpcy5nZXRWYXJpYWJsZSgnc3lzdGVtLmRlZmF1bHRXb3JraW5nRGlyZWN0b3J5JykgfHwgcHJvY2Vzcy5jd2QoKTtcclxuICAgIGV4cG9ydHMuZGVidWcoXCJkZWZhdWx0Um9vdDogJ1wiICsgZGVmYXVsdFJvb3QgKyBcIidcIik7XHJcbiAgICBwYXR0ZXJucyA9IHBhdHRlcm5zIHx8IFtdO1xyXG4gICAgcGF0dGVybnMgPSB0eXBlb2YgcGF0dGVybnMgPT0gJ3N0cmluZycgPyBbcGF0dGVybnNdIDogcGF0dGVybnM7XHJcbiAgICBmaW5kT3B0aW9ucyA9IGZpbmRPcHRpb25zIHx8IF9nZXREZWZhdWx0RmluZE9wdGlvbnMoKTtcclxuICAgIF9kZWJ1Z0ZpbmRPcHRpb25zKGZpbmRPcHRpb25zKTtcclxuICAgIG1hdGNoT3B0aW9ucyA9IG1hdGNoT3B0aW9ucyB8fCBfZ2V0RGVmYXVsdE1hdGNoT3B0aW9ucygpO1xyXG4gICAgX2RlYnVnTWF0Y2hPcHRpb25zKG1hdGNoT3B0aW9ucyk7XHJcbiAgICAvLyBub3JtYWxpemUgc2xhc2hlcyBmb3Igcm9vdCBkaXJcclxuICAgIGRlZmF1bHRSb290ID0gaW0uX25vcm1hbGl6ZVNlcGFyYXRvcnMoZGVmYXVsdFJvb3QpO1xyXG4gICAgdmFyIHJlc3VsdHMgPSB7fTtcclxuICAgIHZhciBvcmlnaW5hbE1hdGNoT3B0aW9ucyA9IG1hdGNoT3B0aW9ucztcclxuICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSAocGF0dGVybnMgfHwgW10pOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgIHZhciBwYXR0ZXJuID0gX2FbX2ldO1xyXG4gICAgICAgIGV4cG9ydHMuZGVidWcoXCJwYXR0ZXJuOiAnXCIgKyBwYXR0ZXJuICsgXCInXCIpO1xyXG4gICAgICAgIC8vIHRyaW0gYW5kIHNraXAgZW1wdHlcclxuICAgICAgICBwYXR0ZXJuID0gKHBhdHRlcm4gfHwgJycpLnRyaW0oKTtcclxuICAgICAgICBpZiAoIXBhdHRlcm4pIHtcclxuICAgICAgICAgICAgZXhwb3J0cy5kZWJ1Zygnc2tpcHBpbmcgZW1wdHkgcGF0dGVybicpO1xyXG4gICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gY2xvbmUgbWF0Y2ggb3B0aW9uc1xyXG4gICAgICAgIHZhciBtYXRjaE9wdGlvbnNfMSA9IGltLl9jbG9uZU1hdGNoT3B0aW9ucyhvcmlnaW5hbE1hdGNoT3B0aW9ucyk7XHJcbiAgICAgICAgLy8gc2tpcCBjb21tZW50c1xyXG4gICAgICAgIGlmICghbWF0Y2hPcHRpb25zXzEubm9jb21tZW50ICYmIGltLl9zdGFydHNXaXRoKHBhdHRlcm4sICcjJykpIHtcclxuICAgICAgICAgICAgZXhwb3J0cy5kZWJ1Zygnc2tpcHBpbmcgY29tbWVudCcpO1xyXG4gICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gc2V0IG5vY29tbWVudCAtIGJyYWNlIGV4cGFuc2lvbiBjb3VsZCByZXN1bHQgaW4gYSBsZWFkaW5nICcjJ1xyXG4gICAgICAgIG1hdGNoT3B0aW9uc18xLm5vY29tbWVudCA9IHRydWU7XHJcbiAgICAgICAgLy8gZGV0ZXJtaW5lIHdoZXRoZXIgcGF0dGVybiBpcyBpbmNsdWRlIG9yIGV4Y2x1ZGVcclxuICAgICAgICB2YXIgbmVnYXRlQ291bnQgPSAwO1xyXG4gICAgICAgIGlmICghbWF0Y2hPcHRpb25zXzEubm9uZWdhdGUpIHtcclxuICAgICAgICAgICAgd2hpbGUgKHBhdHRlcm4uY2hhckF0KG5lZ2F0ZUNvdW50KSA9PSAnIScpIHtcclxuICAgICAgICAgICAgICAgIG5lZ2F0ZUNvdW50Kys7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcGF0dGVybiA9IHBhdHRlcm4uc3Vic3RyaW5nKG5lZ2F0ZUNvdW50KTsgLy8gdHJpbSBsZWFkaW5nICchJ1xyXG4gICAgICAgICAgICBpZiAobmVnYXRlQ291bnQpIHtcclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoXCJ0cmltbWVkIGxlYWRpbmcgJyEnLiBwYXR0ZXJuOiAnXCIgKyBwYXR0ZXJuICsgXCInXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBpc0luY2x1ZGVQYXR0ZXJuID0gbmVnYXRlQ291bnQgPT0gMCB8fFxyXG4gICAgICAgICAgICAobmVnYXRlQ291bnQgJSAyID09IDAgJiYgIW1hdGNoT3B0aW9uc18xLmZsaXBOZWdhdGUpIHx8XHJcbiAgICAgICAgICAgIChuZWdhdGVDb3VudCAlIDIgPT0gMSAmJiBtYXRjaE9wdGlvbnNfMS5mbGlwTmVnYXRlKTtcclxuICAgICAgICAvLyBzZXQgbm9uZWdhdGUgLSBicmFjZSBleHBhbnNpb24gY291bGQgcmVzdWx0IGluIGEgbGVhZGluZyAnISdcclxuICAgICAgICBtYXRjaE9wdGlvbnNfMS5ub25lZ2F0ZSA9IHRydWU7XHJcbiAgICAgICAgbWF0Y2hPcHRpb25zXzEuZmxpcE5lZ2F0ZSA9IGZhbHNlO1xyXG4gICAgICAgIC8vIGV4cGFuZCBicmFjZXMgLSByZXF1aXJlZCB0byBhY2N1cmF0ZWx5IGludGVycHJldCBmaW5kUGF0aFxyXG4gICAgICAgIHZhciBleHBhbmRlZCA9IHZvaWQgMDtcclxuICAgICAgICB2YXIgcHJlRXhwYW5kZWQgPSBwYXR0ZXJuO1xyXG4gICAgICAgIGlmIChtYXRjaE9wdGlvbnNfMS5ub2JyYWNlKSB7XHJcbiAgICAgICAgICAgIGV4cGFuZGVkID0gW3BhdHRlcm5dO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgLy8gY29udmVydCBzbGFzaGVzIG9uIFdpbmRvd3MgYmVmb3JlIGNhbGxpbmcgYnJhY2VFeHBhbmQoKS4gdW5mb3J0dW5hdGVseSB0aGlzIG1lYW5zIGJyYWNlcyBjYW5ub3RcclxuICAgICAgICAgICAgLy8gYmUgZXNjYXBlZCBvbiBXaW5kb3dzLCB0aGlzIGxpbWl0YXRpb24gaXMgY29uc2lzdGVudCB3aXRoIGN1cnJlbnQgbGltaXRhdGlvbnMgb2YgbWluaW1hdGNoICgzLjAuMykuXHJcbiAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ2V4cGFuZGluZyBicmFjZXMnKTtcclxuICAgICAgICAgICAgdmFyIGNvbnZlcnRlZFBhdHRlcm4gPSBwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgPyBwYXR0ZXJuLnJlcGxhY2UoL1xcXFwvZywgJy8nKSA6IHBhdHRlcm47XHJcbiAgICAgICAgICAgIGV4cGFuZGVkID0gbWluaW1hdGNoLmJyYWNlRXhwYW5kKGNvbnZlcnRlZFBhdHRlcm4pO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBzZXQgbm9icmFjZVxyXG4gICAgICAgIG1hdGNoT3B0aW9uc18xLm5vYnJhY2UgPSB0cnVlO1xyXG4gICAgICAgIGZvciAodmFyIF9iID0gMCwgZXhwYW5kZWRfMiA9IGV4cGFuZGVkOyBfYiA8IGV4cGFuZGVkXzIubGVuZ3RoOyBfYisrKSB7XHJcbiAgICAgICAgICAgIHZhciBwYXR0ZXJuXzIgPSBleHBhbmRlZF8yW19iXTtcclxuICAgICAgICAgICAgaWYgKGV4cGFuZGVkLmxlbmd0aCAhPSAxIHx8IHBhdHRlcm5fMiAhPSBwcmVFeHBhbmRlZCkge1xyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZyhcInBhdHRlcm46ICdcIiArIHBhdHRlcm5fMiArIFwiJ1wiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyB0cmltIGFuZCBza2lwIGVtcHR5XHJcbiAgICAgICAgICAgIHBhdHRlcm5fMiA9IChwYXR0ZXJuXzIgfHwgJycpLnRyaW0oKTtcclxuICAgICAgICAgICAgaWYgKCFwYXR0ZXJuXzIpIHtcclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ3NraXBwaW5nIGVtcHR5IHBhdHRlcm4nKTtcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChpc0luY2x1ZGVQYXR0ZXJuKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBkZXRlcm1pbmUgdGhlIGZpbmRQYXRoXHJcbiAgICAgICAgICAgICAgICB2YXIgZmluZEluZm8gPSBpbS5fZ2V0RmluZEluZm9Gcm9tUGF0dGVybihkZWZhdWx0Um9vdCwgcGF0dGVybl8yLCBtYXRjaE9wdGlvbnNfMSk7XHJcbiAgICAgICAgICAgICAgICB2YXIgZmluZFBhdGggPSBmaW5kSW5mby5maW5kUGF0aDtcclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoXCJmaW5kUGF0aDogJ1wiICsgZmluZFBhdGggKyBcIidcIik7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWZpbmRQYXRoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1Zygnc2tpcHBpbmcgZW1wdHkgcGF0aCcpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gcGVyZm9ybSB0aGUgZmluZFxyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZyhcInN0YXRPbmx5OiAnXCIgKyBmaW5kSW5mby5zdGF0T25seSArIFwiJ1wiKTtcclxuICAgICAgICAgICAgICAgIHZhciBmaW5kUmVzdWx0cyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgaWYgKGZpbmRJbmZvLnN0YXRPbmx5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gc2ltcGx5IHN0YXQgdGhlIHBhdGggLSBhbGwgcGF0aCBzZWdtZW50cyB3ZXJlIHVzZWQgdG8gYnVpbGQgdGhlIHBhdGhcclxuICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmcy5zdGF0U3luYyhmaW5kUGF0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmRSZXN1bHRzLnB1c2goZmluZFBhdGgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSAhPSAnRU5PRU5UJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ0VOT0VOVCcpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGZpbmRSZXN1bHRzID0gZmluZChmaW5kUGF0aCwgZmluZE9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZyhcImZvdW5kIFwiICsgZmluZFJlc3VsdHMubGVuZ3RoICsgXCIgcGF0aHNcIik7XHJcbiAgICAgICAgICAgICAgICAvLyBhcHBseSB0aGUgcGF0dGVyblxyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZygnYXBwbHlpbmcgaW5jbHVkZSBwYXR0ZXJuJyk7XHJcbiAgICAgICAgICAgICAgICBpZiAoZmluZEluZm8uYWRqdXN0ZWRQYXR0ZXJuICE9IHBhdHRlcm5fMikge1xyXG4gICAgICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoXCJhZGp1c3RlZFBhdHRlcm46ICdcIiArIGZpbmRJbmZvLmFkanVzdGVkUGF0dGVybiArIFwiJ1wiKTtcclxuICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuXzIgPSBmaW5kSW5mby5hZGp1c3RlZFBhdHRlcm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB2YXIgbWF0Y2hSZXN1bHRzID0gbWluaW1hdGNoLm1hdGNoKGZpbmRSZXN1bHRzLCBwYXR0ZXJuXzIsIG1hdGNoT3B0aW9uc18xKTtcclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcobWF0Y2hSZXN1bHRzLmxlbmd0aCArICcgbWF0Y2hlcycpO1xyXG4gICAgICAgICAgICAgICAgLy8gdW5pb24gdGhlIHJlc3VsdHNcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIF9jID0gMCwgbWF0Y2hSZXN1bHRzXzMgPSBtYXRjaFJlc3VsdHM7IF9jIDwgbWF0Y2hSZXN1bHRzXzMubGVuZ3RoOyBfYysrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1hdGNoUmVzdWx0ID0gbWF0Y2hSZXN1bHRzXzNbX2NdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBrZXkgPSBwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgPyBtYXRjaFJlc3VsdC50b1VwcGVyQ2FzZSgpIDogbWF0Y2hSZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0c1trZXldID0gbWF0Y2hSZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiBiYXNlbmFtZSBvbmx5IGFuZCBtYXRjaEJhc2U9dHJ1ZVxyXG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoT3B0aW9uc18xLm1hdGNoQmFzZSAmJlxyXG4gICAgICAgICAgICAgICAgICAgICFpbS5faXNSb290ZWQocGF0dGVybl8yKSAmJlxyXG4gICAgICAgICAgICAgICAgICAgIChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgPyBwYXR0ZXJuXzIucmVwbGFjZSgvXFxcXC9nLCAnLycpIDogcGF0dGVybl8yKS5pbmRleE9mKCcvJykgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gZG8gbm90IHJvb3QgdGhlIHBhdHRlcm5cclxuICAgICAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdtYXRjaEJhc2UgYW5kIGJhc2VuYW1lIG9ubHknKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHJvb3QgdGhlIGV4Y2x1ZGUgcGF0dGVyblxyXG4gICAgICAgICAgICAgICAgICAgIHBhdHRlcm5fMiA9IGltLl9lbnN1cmVQYXR0ZXJuUm9vdGVkKGRlZmF1bHRSb290LCBwYXR0ZXJuXzIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoXCJhZnRlciBlbnN1cmVQYXR0ZXJuUm9vdGVkLCBwYXR0ZXJuOiAnXCIgKyBwYXR0ZXJuXzIgKyBcIidcIik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBhcHBseSB0aGUgcGF0dGVyblxyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZygnYXBwbHlpbmcgZXhjbHVkZSBwYXR0ZXJuJyk7XHJcbiAgICAgICAgICAgICAgICB2YXIgbWF0Y2hSZXN1bHRzID0gbWluaW1hdGNoLm1hdGNoKE9iamVjdC5rZXlzKHJlc3VsdHMpLm1hcChmdW5jdGlvbiAoa2V5KSB7IHJldHVybiByZXN1bHRzW2tleV07IH0pLCBwYXR0ZXJuXzIsIG1hdGNoT3B0aW9uc18xKTtcclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcobWF0Y2hSZXN1bHRzLmxlbmd0aCArICcgbWF0Y2hlcycpO1xyXG4gICAgICAgICAgICAgICAgLy8gc3Vic3RyYWN0IHRoZSByZXN1bHRzXHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBfZCA9IDAsIG1hdGNoUmVzdWx0c180ID0gbWF0Y2hSZXN1bHRzOyBfZCA8IG1hdGNoUmVzdWx0c180Lmxlbmd0aDsgX2QrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtYXRjaFJlc3VsdCA9IG1hdGNoUmVzdWx0c180W19kXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIga2V5ID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInID8gbWF0Y2hSZXN1bHQudG9VcHBlckNhc2UoKSA6IG1hdGNoUmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSByZXN1bHRzW2tleV07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICB2YXIgZmluYWxSZXN1bHQgPSBPYmplY3Qua2V5cyhyZXN1bHRzKVxyXG4gICAgICAgIC5tYXAoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gcmVzdWx0c1trZXldOyB9KVxyXG4gICAgICAgIC5zb3J0KCk7XHJcbiAgICBleHBvcnRzLmRlYnVnKGZpbmFsUmVzdWx0Lmxlbmd0aCArICcgZmluYWwgcmVzdWx0cycpO1xyXG4gICAgcmV0dXJuIGZpbmFsUmVzdWx0O1xyXG59XHJcbmV4cG9ydHMuZmluZE1hdGNoID0gZmluZE1hdGNoO1xyXG4vKipcclxuICogR2V0cyBodHRwIHByb3h5IGNvbmZpZ3VyYXRpb24gdXNlZCBieSBCdWlsZC9SZWxlYXNlIGFnZW50XHJcbiAqXHJcbiAqIEByZXR1cm4gIFByb3h5Q29uZmlndXJhdGlvblxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0SHR0cFByb3h5Q29uZmlndXJhdGlvbihyZXF1ZXN0VXJsKSB7XHJcbiAgICB2YXIgcHJveHlVcmwgPSBleHBvcnRzLmdldFZhcmlhYmxlKCdBZ2VudC5Qcm94eVVybCcpO1xyXG4gICAgaWYgKHByb3h5VXJsICYmIHByb3h5VXJsLmxlbmd0aCA+IDApIHtcclxuICAgICAgICB2YXIgcHJveHlVc2VybmFtZSA9IGV4cG9ydHMuZ2V0VmFyaWFibGUoJ0FnZW50LlByb3h5VXNlcm5hbWUnKTtcclxuICAgICAgICB2YXIgcHJveHlQYXNzd29yZCA9IGV4cG9ydHMuZ2V0VmFyaWFibGUoJ0FnZW50LlByb3h5UGFzc3dvcmQnKTtcclxuICAgICAgICB2YXIgcHJveHlCeXBhc3NIb3N0cyA9IEpTT04ucGFyc2UoZXhwb3J0cy5nZXRWYXJpYWJsZSgnQWdlbnQuUHJveHlCeXBhc3NMaXN0JykgfHwgJ1tdJyk7XHJcbiAgICAgICAgdmFyIGJ5cGFzc18xID0gZmFsc2U7XHJcbiAgICAgICAgaWYgKHJlcXVlc3RVcmwpIHtcclxuICAgICAgICAgICAgcHJveHlCeXBhc3NIb3N0cy5mb3JFYWNoKGZ1bmN0aW9uIChieXBhc3NIb3N0KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAobmV3IFJlZ0V4cChieXBhc3NIb3N0LCAnaScpLnRlc3QocmVxdWVzdFVybCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBieXBhc3NfMSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYnlwYXNzXzEpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgcHJveHlVcmw6IHByb3h5VXJsLFxyXG4gICAgICAgICAgICAgICAgcHJveHlVc2VybmFtZTogcHJveHlVc2VybmFtZSxcclxuICAgICAgICAgICAgICAgIHByb3h5UGFzc3dvcmQ6IHByb3h5UGFzc3dvcmQsXHJcbiAgICAgICAgICAgICAgICBwcm94eUJ5cGFzc0hvc3RzOiBwcm94eUJ5cGFzc0hvc3RzXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy5nZXRIdHRwUHJveHlDb25maWd1cmF0aW9uID0gZ2V0SHR0cFByb3h5Q29uZmlndXJhdGlvbjtcclxuLyoqXHJcbiAqIEdldHMgaHR0cCBjZXJ0aWZpY2F0ZSBjb25maWd1cmF0aW9uIHVzZWQgYnkgQnVpbGQvUmVsZWFzZSBhZ2VudFxyXG4gKlxyXG4gKiBAcmV0dXJuICBDZXJ0Q29uZmlndXJhdGlvblxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0SHR0cENlcnRDb25maWd1cmF0aW9uKCkge1xyXG4gICAgdmFyIGNhID0gZXhwb3J0cy5nZXRWYXJpYWJsZSgnQWdlbnQuQ0FJbmZvJyk7XHJcbiAgICB2YXIgY2xpZW50Q2VydCA9IGV4cG9ydHMuZ2V0VmFyaWFibGUoJ0FnZW50LkNsaWVudENlcnQnKTtcclxuICAgIGlmIChjYSB8fCBjbGllbnRDZXJ0KSB7XHJcbiAgICAgICAgdmFyIGNlcnRDb25maWcgPSB7fTtcclxuICAgICAgICBjZXJ0Q29uZmlnLmNhRmlsZSA9IGNhO1xyXG4gICAgICAgIGNlcnRDb25maWcuY2VydEZpbGUgPSBjbGllbnRDZXJ0O1xyXG4gICAgICAgIGlmIChjbGllbnRDZXJ0KSB7XHJcbiAgICAgICAgICAgIHZhciBjbGllbnRDZXJ0S2V5ID0gZXhwb3J0cy5nZXRWYXJpYWJsZSgnQWdlbnQuQ2xpZW50Q2VydEtleScpO1xyXG4gICAgICAgICAgICB2YXIgY2xpZW50Q2VydEFyY2hpdmUgPSBleHBvcnRzLmdldFZhcmlhYmxlKCdBZ2VudC5DbGllbnRDZXJ0QXJjaGl2ZScpO1xyXG4gICAgICAgICAgICB2YXIgY2xpZW50Q2VydFBhc3N3b3JkID0gZXhwb3J0cy5nZXRWYXJpYWJsZSgnQWdlbnQuQ2xpZW50Q2VydFBhc3N3b3JkJyk7XHJcbiAgICAgICAgICAgIGNlcnRDb25maWcua2V5RmlsZSA9IGNsaWVudENlcnRLZXk7XHJcbiAgICAgICAgICAgIGNlcnRDb25maWcuY2VydEFyY2hpdmVGaWxlID0gY2xpZW50Q2VydEFyY2hpdmU7XHJcbiAgICAgICAgICAgIGNlcnRDb25maWcucGFzc3BocmFzZSA9IGNsaWVudENlcnRQYXNzd29yZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGNlcnRDb25maWc7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxufVxyXG5leHBvcnRzLmdldEh0dHBDZXJ0Q29uZmlndXJhdGlvbiA9IGdldEh0dHBDZXJ0Q29uZmlndXJhdGlvbjtcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBUZXN0IFB1Ymxpc2hlclxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbnZhciBUZXN0UHVibGlzaGVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgZnVuY3Rpb24gVGVzdFB1Ymxpc2hlcih0ZXN0UnVubmVyKSB7XHJcbiAgICAgICAgdGhpcy50ZXN0UnVubmVyID0gdGVzdFJ1bm5lcjtcclxuICAgIH1cclxuICAgIFRlc3RQdWJsaXNoZXIucHJvdG90eXBlLnB1Ymxpc2ggPSBmdW5jdGlvbiAocmVzdWx0RmlsZXMsIG1lcmdlUmVzdWx0cywgcGxhdGZvcm0sIGNvbmZpZywgcnVuVGl0bGUsIHB1Ymxpc2hSdW5BdHRhY2htZW50cywgdGVzdFJ1blN5c3RlbSkge1xyXG4gICAgICAgIC8vIENvdWxkIGhhdmUgdXNlZCBhbiBpbml0aWFsaXplciwgYnV0IHdhbnRlZCB0byBhdm9pZCByZW9yZGVyaW5nIHBhcmFtZXRlcnMgd2hlbiBjb252ZXJ0aW5nIHRvIHN0cmljdCBudWxsIGNoZWNrc1xyXG4gICAgICAgIC8vIChBIHBhcmFtZXRlciBjYW5ub3QgYm90aCBiZSBvcHRpb25hbCBhbmQgaGF2ZSBhbiBpbml0aWFsaXplcilcclxuICAgICAgICB0ZXN0UnVuU3lzdGVtID0gdGVzdFJ1blN5c3RlbSB8fCBcIlZTVFNUYXNrXCI7XHJcbiAgICAgICAgdmFyIHByb3BlcnRpZXMgPSB7fTtcclxuICAgICAgICBwcm9wZXJ0aWVzWyd0eXBlJ10gPSB0aGlzLnRlc3RSdW5uZXI7XHJcbiAgICAgICAgaWYgKG1lcmdlUmVzdWx0cykge1xyXG4gICAgICAgICAgICBwcm9wZXJ0aWVzWydtZXJnZVJlc3VsdHMnXSA9IG1lcmdlUmVzdWx0cztcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHBsYXRmb3JtKSB7XHJcbiAgICAgICAgICAgIHByb3BlcnRpZXNbJ3BsYXRmb3JtJ10gPSBwbGF0Zm9ybTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGNvbmZpZykge1xyXG4gICAgICAgICAgICBwcm9wZXJ0aWVzWydjb25maWcnXSA9IGNvbmZpZztcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHJ1blRpdGxlKSB7XHJcbiAgICAgICAgICAgIHByb3BlcnRpZXNbJ3J1blRpdGxlJ10gPSBydW5UaXRsZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHB1Ymxpc2hSdW5BdHRhY2htZW50cykge1xyXG4gICAgICAgICAgICBwcm9wZXJ0aWVzWydwdWJsaXNoUnVuQXR0YWNobWVudHMnXSA9IHB1Ymxpc2hSdW5BdHRhY2htZW50cztcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHJlc3VsdEZpbGVzKSB7XHJcbiAgICAgICAgICAgIHByb3BlcnRpZXNbJ3Jlc3VsdEZpbGVzJ10gPSBBcnJheS5pc0FycmF5KHJlc3VsdEZpbGVzKSA/IHJlc3VsdEZpbGVzLmpvaW4oKSA6IHJlc3VsdEZpbGVzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBwcm9wZXJ0aWVzWyd0ZXN0UnVuU3lzdGVtJ10gPSB0ZXN0UnVuU3lzdGVtO1xyXG4gICAgICAgIGV4cG9ydHMuY29tbWFuZCgncmVzdWx0cy5wdWJsaXNoJywgcHJvcGVydGllcywgJycpO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBUZXN0UHVibGlzaGVyO1xyXG59KCkpO1xyXG5leHBvcnRzLlRlc3RQdWJsaXNoZXIgPSBUZXN0UHVibGlzaGVyO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIENvZGUgY292ZXJhZ2UgUHVibGlzaGVyXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxudmFyIENvZGVDb3ZlcmFnZVB1Ymxpc2hlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIENvZGVDb3ZlcmFnZVB1Ymxpc2hlcigpIHtcclxuICAgIH1cclxuICAgIENvZGVDb3ZlcmFnZVB1Ymxpc2hlci5wcm90b3R5cGUucHVibGlzaCA9IGZ1bmN0aW9uIChjb2RlQ292ZXJhZ2VUb29sLCBzdW1tYXJ5RmlsZUxvY2F0aW9uLCByZXBvcnREaXJlY3RvcnksIGFkZGl0aW9uYWxDb2RlQ292ZXJhZ2VGaWxlcykge1xyXG4gICAgICAgIHZhciBwcm9wZXJ0aWVzID0ge307XHJcbiAgICAgICAgaWYgKGNvZGVDb3ZlcmFnZVRvb2wpIHtcclxuICAgICAgICAgICAgcHJvcGVydGllc1snY29kZWNvdmVyYWdldG9vbCddID0gY29kZUNvdmVyYWdlVG9vbDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHN1bW1hcnlGaWxlTG9jYXRpb24pIHtcclxuICAgICAgICAgICAgcHJvcGVydGllc1snc3VtbWFyeWZpbGUnXSA9IHN1bW1hcnlGaWxlTG9jYXRpb247XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChyZXBvcnREaXJlY3RvcnkpIHtcclxuICAgICAgICAgICAgcHJvcGVydGllc1sncmVwb3J0ZGlyZWN0b3J5J10gPSByZXBvcnREaXJlY3Rvcnk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChhZGRpdGlvbmFsQ29kZUNvdmVyYWdlRmlsZXMpIHtcclxuICAgICAgICAgICAgcHJvcGVydGllc1snYWRkaXRpb25hbGNvZGVjb3ZlcmFnZWZpbGVzJ10gPSBBcnJheS5pc0FycmF5KGFkZGl0aW9uYWxDb2RlQ292ZXJhZ2VGaWxlcykgPyBhZGRpdGlvbmFsQ29kZUNvdmVyYWdlRmlsZXMuam9pbigpIDogYWRkaXRpb25hbENvZGVDb3ZlcmFnZUZpbGVzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBleHBvcnRzLmNvbW1hbmQoJ2NvZGVjb3ZlcmFnZS5wdWJsaXNoJywgcHJvcGVydGllcywgXCJcIik7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIENvZGVDb3ZlcmFnZVB1Ymxpc2hlcjtcclxufSgpKTtcclxuZXhwb3J0cy5Db2RlQ292ZXJhZ2VQdWJsaXNoZXIgPSBDb2RlQ292ZXJhZ2VQdWJsaXNoZXI7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gQ29kZSBjb3ZlcmFnZSBQdWJsaXNoZXJcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG52YXIgQ29kZUNvdmVyYWdlRW5hYmxlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIENvZGVDb3ZlcmFnZUVuYWJsZXIoYnVpbGRUb29sLCBjY1Rvb2wpIHtcclxuICAgICAgICB0aGlzLmJ1aWxkVG9vbCA9IGJ1aWxkVG9vbDtcclxuICAgICAgICB0aGlzLmNjVG9vbCA9IGNjVG9vbDtcclxuICAgIH1cclxuICAgIENvZGVDb3ZlcmFnZUVuYWJsZXIucHJvdG90eXBlLmVuYWJsZUNvZGVDb3ZlcmFnZSA9IGZ1bmN0aW9uIChidWlsZFByb3BzKSB7XHJcbiAgICAgICAgYnVpbGRQcm9wc1snYnVpbGR0b29sJ10gPSB0aGlzLmJ1aWxkVG9vbDtcclxuICAgICAgICBidWlsZFByb3BzWydjb2RlY292ZXJhZ2V0b29sJ10gPSB0aGlzLmNjVG9vbDtcclxuICAgICAgICBleHBvcnRzLmNvbW1hbmQoJ2NvZGVjb3ZlcmFnZS5lbmFibGUnLCBidWlsZFByb3BzLCBcIlwiKTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gQ29kZUNvdmVyYWdlRW5hYmxlcjtcclxufSgpKTtcclxuZXhwb3J0cy5Db2RlQ292ZXJhZ2VFbmFibGVyID0gQ29kZUNvdmVyYWdlRW5hYmxlcjtcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBUYXNrIExvZ2dpbmcgQ29tbWFuZHNcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vKipcclxuICogVXBsb2FkIHVzZXIgaW50ZXJlc3RlZCBmaWxlIGFzIGFkZGl0aW9uYWwgbG9nIGluZm9ybWF0aW9uXHJcbiAqIHRvIHRoZSBjdXJyZW50IHRpbWVsaW5lIHJlY29yZC5cclxuICpcclxuICogVGhlIGZpbGUgc2hhbGwgYmUgYXZhaWxhYmxlIGZvciBkb3dubG9hZCBhbG9uZyB3aXRoIHRhc2sgbG9ncy5cclxuICpcclxuICogQHBhcmFtIHBhdGggICAgICBQYXRoIHRvIHRoZSBmaWxlIHRoYXQgc2hvdWxkIGJlIHVwbG9hZGVkLlxyXG4gKiBAcmV0dXJucyAgICAgICAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIHVwbG9hZEZpbGUocGF0aCkge1xyXG4gICAgZXhwb3J0cy5jb21tYW5kKFwidGFzay51cGxvYWRmaWxlXCIsIG51bGwsIHBhdGgpO1xyXG59XHJcbmV4cG9ydHMudXBsb2FkRmlsZSA9IHVwbG9hZEZpbGU7XHJcbi8qKlxyXG4gKiBJbnN0cnVjdGlvbiBmb3IgdGhlIGFnZW50IHRvIHVwZGF0ZSB0aGUgUEFUSCBlbnZpcm9ubWVudCB2YXJpYWJsZS5cclxuICogVGhlIHNwZWNpZmllZCBkaXJlY3RvcnkgaXMgcHJlcGVuZGVkIHRvIHRoZSBQQVRILlxyXG4gKiBUaGUgdXBkYXRlZCBlbnZpcm9ubWVudCB2YXJpYWJsZSB3aWxsIGJlIHJlZmxlY3RlZCBpbiBzdWJzZXF1ZW50IHRhc2tzLlxyXG4gKlxyXG4gKiBAcGFyYW0gcGF0aCAgICAgIExvY2FsIGRpcmVjdG9yeSBwYXRoLlxyXG4gKiBAcmV0dXJucyAgICAgICAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIHByZXBlbmRQYXRoKHBhdGgpIHtcclxuICAgIGFzc2VydEFnZW50KFwiMi4xMTUuMFwiKTtcclxuICAgIGV4cG9ydHMuY29tbWFuZChcInRhc2sucHJlcGVuZHBhdGhcIiwgbnVsbCwgcGF0aCk7XHJcbn1cclxuZXhwb3J0cy5wcmVwZW5kUGF0aCA9IHByZXBlbmRQYXRoO1xyXG4vKipcclxuICogVXBsb2FkIGFuZCBhdHRhY2ggc3VtbWFyeSBtYXJrZG93biB0byBjdXJyZW50IHRpbWVsaW5lIHJlY29yZC5cclxuICogVGhpcyBzdW1tYXJ5IHNoYWxsIGJlIGFkZGVkIHRvIHRoZSBidWlsZC9yZWxlYXNlIHN1bW1hcnkgYW5kXHJcbiAqIG5vdCBhdmFpbGFibGUgZm9yIGRvd25sb2FkIHdpdGggbG9ncy5cclxuICpcclxuICogQHBhcmFtIHBhdGggICAgICBMb2NhbCBkaXJlY3RvcnkgcGF0aC5cclxuICogQHJldHVybnMgICAgICAgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiB1cGxvYWRTdW1tYXJ5KHBhdGgpIHtcclxuICAgIGV4cG9ydHMuY29tbWFuZChcInRhc2sudXBsb2Fkc3VtbWFyeVwiLCBudWxsLCBwYXRoKTtcclxufVxyXG5leHBvcnRzLnVwbG9hZFN1bW1hcnkgPSB1cGxvYWRTdW1tYXJ5O1xyXG4vKipcclxuICogVXBsb2FkIGFuZCBhdHRhY2ggYXR0YWNobWVudCB0byBjdXJyZW50IHRpbWVsaW5lIHJlY29yZC5cclxuICogVGhlc2UgZmlsZXMgYXJlIG5vdCBhdmFpbGFibGUgZm9yIGRvd25sb2FkIHdpdGggbG9ncy5cclxuICogVGhlc2UgY2FuIG9ubHkgYmUgcmVmZXJyZWQgdG8gYnkgZXh0ZW5zaW9ucyB1c2luZyB0aGUgdHlwZSBvciBuYW1lIHZhbHVlcy5cclxuICpcclxuICogQHBhcmFtIHR5cGUgICAgICBBdHRhY2htZW50IHR5cGUuXHJcbiAqIEBwYXJhbSBuYW1lICAgICAgQXR0YWNobWVudCBuYW1lLlxyXG4gKiBAcGFyYW0gcGF0aCAgICAgIEF0dGFjaG1lbnQgcGF0aC5cclxuICogQHJldHVybnMgICAgICAgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiBhZGRBdHRhY2htZW50KHR5cGUsIG5hbWUsIHBhdGgpIHtcclxuICAgIGV4cG9ydHMuY29tbWFuZChcInRhc2suYWRkYXR0YWNobWVudFwiLCB7IFwidHlwZVwiOiB0eXBlLCBcIm5hbWVcIjogbmFtZSB9LCBwYXRoKTtcclxufVxyXG5leHBvcnRzLmFkZEF0dGFjaG1lbnQgPSBhZGRBdHRhY2htZW50O1xyXG4vKipcclxuICogU2V0IGFuIGVuZHBvaW50IGZpZWxkIHdpdGggZ2l2ZW4gdmFsdWUuXHJcbiAqIFZhbHVlIHVwZGF0ZWQgd2lsbCBiZSByZXRhaW5lZCBpbiB0aGUgZW5kcG9pbnQgZm9yXHJcbiAqIHRoZSBzdWJzZXF1ZW50IHRhc2tzIHRoYXQgZXhlY3V0ZSB3aXRoaW4gdGhlIHNhbWUgam9iLlxyXG4gKlxyXG4gKiBAcGFyYW0gaWQgICAgICBFbmRwb2ludCBpZC5cclxuICogQHBhcmFtIGZpZWxkICAgRmllbGRUeXBlIGVudW0gb2YgQXV0aFBhcmFtZXRlciwgRGF0YVBhcmFtZXRlciBvciBVcmwuXHJcbiAqIEBwYXJhbSBrZXkgICAgIEtleS5cclxuICogQHBhcmFtIHZhbHVlICAgVmFsdWUgZm9yIGtleSBvciB1cmwuXHJcbiAqIEByZXR1cm5zICAgICAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIHNldEVuZHBvaW50KGlkLCBmaWVsZCwga2V5LCB2YWx1ZSkge1xyXG4gICAgZXhwb3J0cy5jb21tYW5kKFwidGFzay5zZXRlbmRwb2ludFwiLCB7IFwiaWRcIjogaWQsIFwiZmllbGRcIjogRmllbGRUeXBlW2ZpZWxkXS50b0xvd2VyQ2FzZSgpLCBcImtleVwiOiBrZXkgfSwgdmFsdWUpO1xyXG59XHJcbmV4cG9ydHMuc2V0RW5kcG9pbnQgPSBzZXRFbmRwb2ludDtcclxuLyoqXHJcbiAqIFNldCBwcm9ncmVzcyBhbmQgY3VycmVudCBvcGVyYXRpb24gZm9yIGN1cnJlbnQgdGFzay5cclxuICpcclxuICogQHBhcmFtIHBlcmNlbnQgICAgICAgICAgIFBlcmNlbnRhZ2Ugb2YgY29tcGxldGlvbi5cclxuICogQHBhcmFtIGN1cnJlbnRPcGVyYXRpb24gIEN1cnJlbnQgcHBlcmF0aW9uLlxyXG4gKiBAcmV0dXJucyAgICAgICAgICAgICAgICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gc2V0UHJvZ3Jlc3MocGVyY2VudCwgY3VycmVudE9wZXJhdGlvbikge1xyXG4gICAgZXhwb3J0cy5jb21tYW5kKFwidGFzay5zZXRwcm9ncmVzc1wiLCB7IFwidmFsdWVcIjogXCJcIiArIHBlcmNlbnQgfSwgY3VycmVudE9wZXJhdGlvbik7XHJcbn1cclxuZXhwb3J0cy5zZXRQcm9ncmVzcyA9IHNldFByb2dyZXNzO1xyXG4vKipcclxuICogSW5kaWNhdGVzIHdoZXRoZXIgdG8gd3JpdGUgdGhlIGxvZ2dpbmcgY29tbWFuZCBkaXJlY3RseSB0byB0aGUgaG9zdCBvciB0byB0aGUgb3V0cHV0IHBpcGVsaW5lLlxyXG4gKlxyXG4gKiBAcGFyYW0gaWQgICAgICAgICAgICBUaW1lbGluZSByZWNvcmQgR3VpZC5cclxuICogQHBhcmFtIHBhcmVudElkICAgICAgUGFyZW50IHRpbWVsaW5lIHJlY29yZCBHdWlkLlxyXG4gKiBAcGFyYW0gcmVjb3JkVHlwZSAgICBSZWNvcmQgdHlwZS5cclxuICogQHBhcmFtIHJlY29yZE5hbWUgICAgUmVjb3JkIG5hbWUuXHJcbiAqIEBwYXJhbSBvcmRlciAgICAgICAgIE9yZGVyIG9mIHRpbWVsaW5lIHJlY29yZC5cclxuICogQHBhcmFtIHN0YXJ0VGltZSAgICAgU3RhcnQgdGltZS5cclxuICogQHBhcmFtIGZpbmlzaFRpbWUgICAgRW5kIHRpbWUuXHJcbiAqIEBwYXJhbSBwcm9ncmVzcyAgICAgIFBlcmNlbnRhZ2Ugb2YgY29tcGxldGlvbi5cclxuICogQHBhcmFtIHN0YXRlICAgICAgICAgVGFza1N0YXRlIGVudW0gb2YgVW5rbm93biwgSW5pdGlhbGl6ZWQsIEluUHJvZ3Jlc3Mgb3IgQ29tcGxldGVkLlxyXG4gKiBAcGFyYW0gcmVzdWx0ICAgICAgICBUYXNrUmVzdWx0IGVudW0gb2YgU3VjY2VlZGVkLCBTdWNjZWVkZWRXaXRoSXNzdWVzLCBGYWlsZWQsIENhbmNlbGxlZCBvciBTa2lwcGVkLlxyXG4gKiBAcGFyYW0gbWVzc2FnZSAgICAgICBjdXJyZW50IG9wZXJhdGlvblxyXG4gKiBAcmV0dXJucyAgICAgICAgICAgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiBsb2dEZXRhaWwoaWQsIG1lc3NhZ2UsIHBhcmVudElkLCByZWNvcmRUeXBlLCByZWNvcmROYW1lLCBvcmRlciwgc3RhcnRUaW1lLCBmaW5pc2hUaW1lLCBwcm9ncmVzcywgc3RhdGUsIHJlc3VsdCkge1xyXG4gICAgdmFyIHByb3BlcnRpZXMgPSB7XHJcbiAgICAgICAgXCJpZFwiOiBpZCxcclxuICAgICAgICBcInBhcmVudGlkXCI6IHBhcmVudElkLFxyXG4gICAgICAgIFwidHlwZVwiOiByZWNvcmRUeXBlLFxyXG4gICAgICAgIFwibmFtZVwiOiByZWNvcmROYW1lLFxyXG4gICAgICAgIFwib3JkZXJcIjogb3JkZXIgPyBvcmRlci50b1N0cmluZygpIDogdW5kZWZpbmVkLFxyXG4gICAgICAgIFwic3RhcnR0aW1lXCI6IHN0YXJ0VGltZSxcclxuICAgICAgICBcImZpbmlzaHRpbWVcIjogZmluaXNoVGltZSxcclxuICAgICAgICBcInByb2dyZXNzXCI6IHByb2dyZXNzID8gcHJvZ3Jlc3MudG9TdHJpbmcoKSA6IHVuZGVmaW5lZCxcclxuICAgICAgICBcInN0YXRlXCI6IHN0YXRlID8gVGFza1N0YXRlW3N0YXRlXSA6IHVuZGVmaW5lZCxcclxuICAgICAgICBcInJlc3VsdFwiOiByZXN1bHQgPyBUYXNrUmVzdWx0W3Jlc3VsdF0gOiB1bmRlZmluZWRcclxuICAgIH07XHJcbiAgICBleHBvcnRzLmNvbW1hbmQoXCJ0YXNrLmxvZ2RldGFpbFwiLCBwcm9wZXJ0aWVzLCBtZXNzYWdlKTtcclxufVxyXG5leHBvcnRzLmxvZ0RldGFpbCA9IGxvZ0RldGFpbDtcclxuLyoqXHJcbiAqIExvZyBlcnJvciBvciB3YXJuaW5nIGlzc3VlIHRvIHRpbWVsaW5lIHJlY29yZCBvZiBjdXJyZW50IHRhc2suXHJcbiAqXHJcbiAqIEBwYXJhbSB0eXBlICAgICAgICAgIElzc3VlVHlwZSBlbnVtIG9mIEVycm9yIG9yIFdhcm5pbmcuXHJcbiAqIEBwYXJhbSBzb3VyY2VQYXRoICAgIFNvdXJjZSBmaWxlIGxvY2F0aW9uLlxyXG4gKiBAcGFyYW0gbGluZU51bWJlciAgICBMaW5lIG51bWJlci5cclxuICogQHBhcmFtIGNvbHVtbk51bWJlciAgQ29sdW1uIG51bWJlci5cclxuICogQHBhcmFtIGNvZGUgICAgICAgICAgRXJyb3Igb3Igd2FybmluZyBjb2RlLlxyXG4gKiBAcGFyYW0gbWVzc2FnZSAgICAgICBFcnJvciBvciB3YXJuaW5nIG1lc3NhZ2UuXHJcbiAqIEByZXR1cm5zICAgICAgICAgICAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIGxvZ0lzc3VlKHR5cGUsIG1lc3NhZ2UsIHNvdXJjZVBhdGgsIGxpbmVOdW1iZXIsIGNvbHVtbk51bWJlciwgZXJyb3JDb2RlKSB7XHJcbiAgICB2YXIgcHJvcGVydGllcyA9IHtcclxuICAgICAgICBcInR5cGVcIjogSXNzdWVUeXBlW3R5cGVdLnRvTG93ZXJDYXNlKCksXHJcbiAgICAgICAgXCJjb2RlXCI6IGVycm9yQ29kZSxcclxuICAgICAgICBcInNvdXJjZXBhdGhcIjogc291cmNlUGF0aCxcclxuICAgICAgICBcImxpbmVudW1iZXJcIjogbGluZU51bWJlciA/IGxpbmVOdW1iZXIudG9TdHJpbmcoKSA6IHVuZGVmaW5lZCxcclxuICAgICAgICBcImNvbHVtbm51bWJlclwiOiBjb2x1bW5OdW1iZXIgPyBjb2x1bW5OdW1iZXIudG9TdHJpbmcoKSA6IHVuZGVmaW5lZCxcclxuICAgIH07XHJcbiAgICBleHBvcnRzLmNvbW1hbmQoXCJ0YXNrLmxvZ2lzc3VlXCIsIHByb3BlcnRpZXMsIG1lc3NhZ2UpO1xyXG59XHJcbmV4cG9ydHMubG9nSXNzdWUgPSBsb2dJc3N1ZTtcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBBcnRpZmFjdCBMb2dnaW5nIENvbW1hbmRzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyoqXHJcbiAqIFVwbG9hZCB1c2VyIGludGVyZXN0ZWQgZmlsZSBhcyBhZGRpdGlvbmFsIGxvZyBpbmZvcm1hdGlvblxyXG4gKiB0byB0aGUgY3VycmVudCB0aW1lbGluZSByZWNvcmQuXHJcbiAqXHJcbiAqIFRoZSBmaWxlIHNoYWxsIGJlIGF2YWlsYWJsZSBmb3IgZG93bmxvYWQgYWxvbmcgd2l0aCB0YXNrIGxvZ3MuXHJcbiAqXHJcbiAqIEBwYXJhbSBjb250YWluZXJGb2xkZXIgICBGb2xkZXIgdGhhdCB0aGUgZmlsZSB3aWxsIHVwbG9hZCB0bywgZm9sZGVyIHdpbGwgYmUgY3JlYXRlZCBpZiBuZWVkZWQuXHJcbiAqIEBwYXJhbSBwYXRoICAgICAgICAgICAgICBQYXRoIHRvIHRoZSBmaWxlIHRoYXQgc2hvdWxkIGJlIHVwbG9hZGVkLlxyXG4gKiBAcGFyYW0gbmFtZSAgICAgICAgICAgICAgQXJ0aWZhY3QgbmFtZS5cclxuICogQHJldHVybnMgICAgICAgICAgICAgICAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIHVwbG9hZEFydGlmYWN0KGNvbnRhaW5lckZvbGRlciwgcGF0aCwgbmFtZSkge1xyXG4gICAgZXhwb3J0cy5jb21tYW5kKFwiYXJ0aWZhY3QudXBsb2FkXCIsIHsgXCJjb250YWluZXJmb2xkZXJcIjogY29udGFpbmVyRm9sZGVyLCBcImFydGlmYWN0bmFtZVwiOiBuYW1lIH0sIHBhdGgpO1xyXG59XHJcbmV4cG9ydHMudXBsb2FkQXJ0aWZhY3QgPSB1cGxvYWRBcnRpZmFjdDtcclxuLyoqXHJcbiAqIENyZWF0ZSBhbiBhcnRpZmFjdCBsaW5rLCBhcnRpZmFjdCBsb2NhdGlvbiBpcyByZXF1aXJlZCB0byBiZVxyXG4gKiBhIGZpbGUgY29udGFpbmVyIHBhdGgsIFZDIHBhdGggb3IgVU5DIHNoYXJlIHBhdGguXHJcbiAqXHJcbiAqIFRoZSBmaWxlIHNoYWxsIGJlIGF2YWlsYWJsZSBmb3IgZG93bmxvYWQgYWxvbmcgd2l0aCB0YXNrIGxvZ3MuXHJcbiAqXHJcbiAqIEBwYXJhbSBuYW1lICAgICAgICAgICAgICBBcnRpZmFjdCBuYW1lLlxyXG4gKiBAcGFyYW0gcGF0aCAgICAgICAgICAgICAgUGF0aCB0byB0aGUgZmlsZSB0aGF0IHNob3VsZCBiZSBhc3NvY2lhdGVkLlxyXG4gKiBAcGFyYW0gYXJ0aWZhY3RUeXBlICAgICAgQXJ0aWZhY3RUeXBlIGVudW0gb2YgQ29udGFpbmVyLCBGaWxlUGF0aCwgVmVyc2lvbkNvbnRyb2wsIEdpdFJlZiBvciBUZnZjTGFiZWwuXHJcbiAqIEByZXR1cm5zICAgICAgICAgICAgICAgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiBhc3NvY2lhdGVBcnRpZmFjdChuYW1lLCBwYXRoLCBhcnRpZmFjdFR5cGUpIHtcclxuICAgIGV4cG9ydHMuY29tbWFuZChcImFydGlmYWN0LmFzc29jaWF0ZVwiLCB7IFwidHlwZVwiOiBBcnRpZmFjdFR5cGVbYXJ0aWZhY3RUeXBlXS50b0xvd2VyQ2FzZSgpLCBcImFydGlmYWN0bmFtZVwiOiBuYW1lIH0sIHBhdGgpO1xyXG59XHJcbmV4cG9ydHMuYXNzb2NpYXRlQXJ0aWZhY3QgPSBhc3NvY2lhdGVBcnRpZmFjdDtcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBCdWlsZCBMb2dnaW5nIENvbW1hbmRzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyoqXHJcbiAqIFVwbG9hZCB1c2VyIGludGVyZXN0ZWQgbG9nIHRvIGJ1aWxk4oCZcyBjb250YWluZXIg4oCcbG9nc1xcdG9vbOKAnSBmb2xkZXIuXHJcbiAqXHJcbiAqIEBwYXJhbSBwYXRoICAgICAgUGF0aCB0byB0aGUgZmlsZSB0aGF0IHNob3VsZCBiZSB1cGxvYWRlZC5cclxuICogQHJldHVybnMgICAgICAgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiB1cGxvYWRCdWlsZExvZyhwYXRoKSB7XHJcbiAgICBleHBvcnRzLmNvbW1hbmQoXCJidWlsZC51cGxvYWRsb2dcIiwgbnVsbCwgcGF0aCk7XHJcbn1cclxuZXhwb3J0cy51cGxvYWRCdWlsZExvZyA9IHVwbG9hZEJ1aWxkTG9nO1xyXG4vKipcclxuICogVXBkYXRlIGJ1aWxkIG51bWJlciBmb3IgY3VycmVudCBidWlsZC5cclxuICpcclxuICogQHBhcmFtIHZhbHVlICAgICBWYWx1ZSB0byBiZSBhc3NpZ25lZCBhcyB0aGUgYnVpbGQgbnVtYmVyLlxyXG4gKiBAcmV0dXJucyAgICAgICAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIHVwZGF0ZUJ1aWxkTnVtYmVyKHZhbHVlKSB7XHJcbiAgICBleHBvcnRzLmNvbW1hbmQoXCJidWlsZC51cGRhdGVidWlsZG51bWJlclwiLCBudWxsLCB2YWx1ZSk7XHJcbn1cclxuZXhwb3J0cy51cGRhdGVCdWlsZE51bWJlciA9IHVwZGF0ZUJ1aWxkTnVtYmVyO1xyXG4vKipcclxuICogQWRkIGEgdGFnIGZvciBjdXJyZW50IGJ1aWxkLlxyXG4gKlxyXG4gKiBAcGFyYW0gdmFsdWUgICAgIFRhZyB2YWx1ZS5cclxuICogQHJldHVybnMgICAgICAgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiBhZGRCdWlsZFRhZyh2YWx1ZSkge1xyXG4gICAgZXhwb3J0cy5jb21tYW5kKFwiYnVpbGQuYWRkYnVpbGR0YWdcIiwgbnVsbCwgdmFsdWUpO1xyXG59XHJcbmV4cG9ydHMuYWRkQnVpbGRUYWcgPSBhZGRCdWlsZFRhZztcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBSZWxlYXNlIExvZ2dpbmcgQ29tbWFuZHNcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vKipcclxuICogVXBkYXRlIHJlbGVhc2UgbmFtZSBmb3IgY3VycmVudCByZWxlYXNlLlxyXG4gKlxyXG4gKiBAcGFyYW0gdmFsdWUgICAgIFZhbHVlIHRvIGJlIGFzc2lnbmVkIGFzIHRoZSByZWxlYXNlIG5hbWUuXHJcbiAqIEByZXR1cm5zICAgICAgICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gdXBkYXRlUmVsZWFzZU5hbWUobmFtZSkge1xyXG4gICAgYXNzZXJ0QWdlbnQoXCIyLjEzMlwiKTtcclxuICAgIGV4cG9ydHMuY29tbWFuZChcInJlbGVhc2UudXBkYXRlcmVsZWFzZW5hbWVcIiwgbnVsbCwgbmFtZSk7XHJcbn1cclxuZXhwb3J0cy51cGRhdGVSZWxlYXNlTmFtZSA9IHVwZGF0ZVJlbGVhc2VOYW1lO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIFRvb2xzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuZXhwb3J0cy5UYXNrQ29tbWFuZCA9IHRjbS5UYXNrQ29tbWFuZDtcclxuZXhwb3J0cy5jb21tYW5kRnJvbVN0cmluZyA9IHRjbS5jb21tYW5kRnJvbVN0cmluZztcclxuZXhwb3J0cy5Ub29sUnVubmVyID0gdHJtLlRvb2xSdW5uZXI7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gVmFsaWRhdGlvbiBDaGVja3NcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBhc3luYyBhd2FpdCBuZWVkcyBnZW5lcmF0b3JzIGluIG5vZGUgNC54K1xyXG5pZiAoc2VtdmVyLmx0KHByb2Nlc3MudmVyc2lvbnMubm9kZSwgJzQuMi4wJykpIHtcclxuICAgIGV4cG9ydHMud2FybmluZygnVGFza3MgcmVxdWlyZSBhIG5ldyBhZ2VudC4gIFVwZ3JhZGUgeW91ciBhZ2VudCBvciBub2RlIHRvIDQuMi4wIG9yIGxhdGVyJyk7XHJcbn1cclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIFBvcHVsYXRlIHRoZSB2YXVsdCB3aXRoIHNlbnNpdGl2ZSBkYXRhLiAgSW5wdXRzIGFuZCBFbmRwb2ludHNcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIGF2b2lkIGxvYWRpbmcgdHdpY2UgKG92ZXJ3cml0ZXMgLnRhc2trZXkpXHJcbmlmICghZ2xvYmFsWydfdnN0c190YXNrX2xpYl9sb2FkZWQnXSkge1xyXG4gICAgaW0uX2xvYWREYXRhKCk7XHJcbiAgICBpbS5fZXhwb3NlUHJveHlTZXR0aW5ncygpO1xyXG4gICAgaW0uX2V4cG9zZUNlcnRTZXR0aW5ncygpO1xyXG59XHJcbiIsIlwidXNlIHN0cmljdFwiO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbmV4cG9ydHMuY29tbWFuZEZyb21TdHJpbmcgPSBleHBvcnRzLlRhc2tDb21tYW5kID0gdm9pZCAwO1xyXG4vL1xyXG4vLyBDb21tYW5kIEZvcm1hdDpcclxuLy8gICAgIyN2c29bYXJ0aWZhY3QuY29tbWFuZCBrZXk9dmFsdWU7a2V5PXZhbHVlXXVzZXIgbWVzc2FnZVxyXG4vLyAgICBcclxuLy8gRXhhbXBsZXM6XHJcbi8vICAgICMjdnNvW3Rhc2sucHJvZ3Jlc3MgdmFsdWU9NThdXHJcbi8vICAgICMjdnNvW3Rhc2suaXNzdWUgdHlwZT13YXJuaW5nO11UaGlzIGlzIHRoZSB1c2VyIHdhcm5pbmcgbWVzc2FnZVxyXG4vL1xyXG52YXIgQ01EX1BSRUZJWCA9ICcjI3Zzb1snO1xyXG52YXIgVGFza0NvbW1hbmQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBUYXNrQ29tbWFuZChjb21tYW5kLCBwcm9wZXJ0aWVzLCBtZXNzYWdlKSB7XHJcbiAgICAgICAgaWYgKCFjb21tYW5kKSB7XHJcbiAgICAgICAgICAgIGNvbW1hbmQgPSAnbWlzc2luZy5jb21tYW5kJztcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5jb21tYW5kID0gY29tbWFuZDtcclxuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xyXG4gICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XHJcbiAgICB9XHJcbiAgICBUYXNrQ29tbWFuZC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIGNtZFN0ciA9IENNRF9QUkVGSVggKyB0aGlzLmNvbW1hbmQ7XHJcbiAgICAgICAgaWYgKHRoaXMucHJvcGVydGllcyAmJiBPYmplY3Qua2V5cyh0aGlzLnByb3BlcnRpZXMpLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgY21kU3RyICs9ICcgJztcclxuICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIHRoaXMucHJvcGVydGllcykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHZhbCA9IHRoaXMucHJvcGVydGllc1trZXldO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2FmZWx5IGFwcGVuZCB0aGUgdmFsIC0gYXZvaWQgYmxvd2luZyB1cCB3aGVuIGF0dGVtcHRpbmcgdG9cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FsbCAucmVwbGFjZSgpIGlmIG1lc3NhZ2UgaXMgbm90IGEgc3RyaW5nIGZvciBzb21lIHJlYXNvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbWRTdHIgKz0ga2V5ICsgJz0nICsgZXNjYXBlKCcnICsgKHZhbCB8fCAnJykpICsgJzsnO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBjbWRTdHIgKz0gJ10nO1xyXG4gICAgICAgIC8vIHNhZmVseSBhcHBlbmQgdGhlIG1lc3NhZ2UgLSBhdm9pZCBibG93aW5nIHVwIHdoZW4gYXR0ZW1wdGluZyB0b1xyXG4gICAgICAgIC8vIGNhbGwgLnJlcGxhY2UoKSBpZiBtZXNzYWdlIGlzIG5vdCBhIHN0cmluZyBmb3Igc29tZSByZWFzb25cclxuICAgICAgICB2YXIgbWVzc2FnZSA9ICcnICsgKHRoaXMubWVzc2FnZSB8fCAnJyk7XHJcbiAgICAgICAgY21kU3RyICs9IGVzY2FwZWRhdGEobWVzc2FnZSk7XHJcbiAgICAgICAgcmV0dXJuIGNtZFN0cjtcclxuICAgIH07XHJcbiAgICByZXR1cm4gVGFza0NvbW1hbmQ7XHJcbn0oKSk7XHJcbmV4cG9ydHMuVGFza0NvbW1hbmQgPSBUYXNrQ29tbWFuZDtcclxuZnVuY3Rpb24gY29tbWFuZEZyb21TdHJpbmcoY29tbWFuZExpbmUpIHtcclxuICAgIHZhciBwcmVMZW4gPSBDTURfUFJFRklYLmxlbmd0aDtcclxuICAgIHZhciBsYlBvcyA9IGNvbW1hbmRMaW5lLmluZGV4T2YoJ1snKTtcclxuICAgIHZhciByYlBvcyA9IGNvbW1hbmRMaW5lLmluZGV4T2YoJ10nKTtcclxuICAgIGlmIChsYlBvcyA9PSAtMSB8fCByYlBvcyA9PSAtMSB8fCByYlBvcyAtIGxiUG9zIDwgMykge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb21tYW5kIGJyYWNrZXRzJyk7XHJcbiAgICB9XHJcbiAgICB2YXIgY21kSW5mbyA9IGNvbW1hbmRMaW5lLnN1YnN0cmluZyhsYlBvcyArIDEsIHJiUG9zKTtcclxuICAgIHZhciBzcGFjZUlkeCA9IGNtZEluZm8uaW5kZXhPZignICcpO1xyXG4gICAgdmFyIGNvbW1hbmQgPSBjbWRJbmZvO1xyXG4gICAgdmFyIHByb3BlcnRpZXMgPSB7fTtcclxuICAgIGlmIChzcGFjZUlkeCA+IDApIHtcclxuICAgICAgICBjb21tYW5kID0gY21kSW5mby50cmltKCkuc3Vic3RyaW5nKDAsIHNwYWNlSWR4KTtcclxuICAgICAgICB2YXIgcHJvcFNlY3Rpb24gPSBjbWRJbmZvLnRyaW0oKS5zdWJzdHJpbmcoc3BhY2VJZHggKyAxKTtcclxuICAgICAgICB2YXIgcHJvcExpbmVzID0gcHJvcFNlY3Rpb24uc3BsaXQoJzsnKTtcclxuICAgICAgICBwcm9wTGluZXMuZm9yRWFjaChmdW5jdGlvbiAocHJvcExpbmUpIHtcclxuICAgICAgICAgICAgcHJvcExpbmUgPSBwcm9wTGluZS50cmltKCk7XHJcbiAgICAgICAgICAgIGlmIChwcm9wTGluZS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgZXFJbmRleCA9IHByb3BMaW5lLmluZGV4T2YoJz0nKTtcclxuICAgICAgICAgICAgICAgIGlmIChlcUluZGV4ID09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHByb3BlcnR5OiAnICsgcHJvcExpbmUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdmFyIGtleSA9IHByb3BMaW5lLnN1YnN0cmluZygwLCBlcUluZGV4KTtcclxuICAgICAgICAgICAgICAgIHZhciB2YWwgPSBwcm9wTGluZS5zdWJzdHJpbmcoZXFJbmRleCArIDEpO1xyXG4gICAgICAgICAgICAgICAgcHJvcGVydGllc1trZXldID0gdW5lc2NhcGUodmFsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgdmFyIG1zZyA9IHVuZXNjYXBlZGF0YShjb21tYW5kTGluZS5zdWJzdHJpbmcocmJQb3MgKyAxKSk7XHJcbiAgICB2YXIgY21kID0gbmV3IFRhc2tDb21tYW5kKGNvbW1hbmQsIHByb3BlcnRpZXMsIG1zZyk7XHJcbiAgICByZXR1cm4gY21kO1xyXG59XHJcbmV4cG9ydHMuY29tbWFuZEZyb21TdHJpbmcgPSBjb21tYW5kRnJvbVN0cmluZztcclxuZnVuY3Rpb24gZXNjYXBlZGF0YShzKSB7XHJcbiAgICByZXR1cm4gcy5yZXBsYWNlKC8lL2csICclQVpQMjUnKVxyXG4gICAgICAgIC5yZXBsYWNlKC9cXHIvZywgJyUwRCcpXHJcbiAgICAgICAgLnJlcGxhY2UoL1xcbi9nLCAnJTBBJyk7XHJcbn1cclxuZnVuY3Rpb24gdW5lc2NhcGVkYXRhKHMpIHtcclxuICAgIHJldHVybiBzLnJlcGxhY2UoLyUwRC9nLCAnXFxyJylcclxuICAgICAgICAucmVwbGFjZSgvJTBBL2csICdcXG4nKVxyXG4gICAgICAgIC5yZXBsYWNlKC8lQVpQMjUvZywgJyUnKTtcclxufVxyXG5mdW5jdGlvbiBlc2NhcGUocykge1xyXG4gICAgcmV0dXJuIHMucmVwbGFjZSgvJS9nLCAnJUFaUDI1JylcclxuICAgICAgICAucmVwbGFjZSgvXFxyL2csICclMEQnKVxyXG4gICAgICAgIC5yZXBsYWNlKC9cXG4vZywgJyUwQScpXHJcbiAgICAgICAgLnJlcGxhY2UoL10vZywgJyU1RCcpXHJcbiAgICAgICAgLnJlcGxhY2UoLzsvZywgJyUzQicpO1xyXG59XHJcbmZ1bmN0aW9uIHVuZXNjYXBlKHMpIHtcclxuICAgIHJldHVybiBzLnJlcGxhY2UoLyUwRC9nLCAnXFxyJylcclxuICAgICAgICAucmVwbGFjZSgvJTBBL2csICdcXG4nKVxyXG4gICAgICAgIC5yZXBsYWNlKC8lNUQvZywgJ10nKVxyXG4gICAgICAgIC5yZXBsYWNlKC8lM0IvZywgJzsnKVxyXG4gICAgICAgIC5yZXBsYWNlKC8lQVpQMjUvZywgJyUnKTtcclxufVxyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG5leHBvcnRzLlRvb2xSdW5uZXIgPSB2b2lkIDA7XHJcbnZhciBRID0gcmVxdWlyZShcInFcIik7XHJcbnZhciBvcyA9IHJlcXVpcmUoXCJvc1wiKTtcclxudmFyIGV2ZW50cyA9IHJlcXVpcmUoXCJldmVudHNcIik7XHJcbnZhciBjaGlsZCA9IHJlcXVpcmUoXCJjaGlsZF9wcm9jZXNzXCIpO1xyXG52YXIgaW0gPSByZXF1aXJlKFwiLi9pbnRlcm5hbFwiKTtcclxudmFyIGZzID0gcmVxdWlyZShcImZzXCIpO1xyXG52YXIgVG9vbFJ1bm5lciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhUb29sUnVubmVyLCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gVG9vbFJ1bm5lcih0b29sUGF0aCkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuY21kU3BlY2lhbENoYXJzID0gWycgJywgJ1xcdCcsICcmJywgJygnLCAnKScsICdbJywgJ10nLCAneycsICd9JywgJ14nLCAnPScsICc7JywgJyEnLCAnXFwnJywgJysnLCAnLCcsICdgJywgJ34nLCAnfCcsICc8JywgJz4nLCAnXCInXTtcclxuICAgICAgICBpZiAoIXRvb2xQYXRoKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUGFyYW1ldGVyIFxcJ3Rvb2xQYXRoXFwnIGNhbm5vdCBiZSBudWxsIG9yIGVtcHR5LicpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBfdGhpcy50b29sUGF0aCA9IGltLl93aGljaCh0b29sUGF0aCwgdHJ1ZSk7XHJcbiAgICAgICAgX3RoaXMuYXJncyA9IFtdO1xyXG4gICAgICAgIF90aGlzLl9kZWJ1ZygndG9vbFJ1bm5lciB0b29sUGF0aDogJyArIHRvb2xQYXRoKTtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICBUb29sUnVubmVyLnByb3RvdHlwZS5fZGVidWcgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xyXG4gICAgICAgIHRoaXMuZW1pdCgnZGVidWcnLCBtZXNzYWdlKTtcclxuICAgIH07XHJcbiAgICBUb29sUnVubmVyLnByb3RvdHlwZS5fYXJnU3RyaW5nVG9BcnJheSA9IGZ1bmN0aW9uIChhcmdTdHJpbmcpIHtcclxuICAgICAgICB2YXIgYXJncyA9IFtdO1xyXG4gICAgICAgIHZhciBpblF1b3RlcyA9IGZhbHNlO1xyXG4gICAgICAgIHZhciBlc2NhcGVkID0gZmFsc2U7XHJcbiAgICAgICAgdmFyIGxhc3RDaGFyV2FzU3BhY2UgPSB0cnVlO1xyXG4gICAgICAgIHZhciBhcmcgPSAnJztcclxuICAgICAgICB2YXIgYXBwZW5kID0gZnVuY3Rpb24gKGMpIHtcclxuICAgICAgICAgICAgLy8gd2Ugb25seSBlc2NhcGUgZG91YmxlIHF1b3Rlcy5cclxuICAgICAgICAgICAgaWYgKGVzY2FwZWQpIHtcclxuICAgICAgICAgICAgICAgIGlmIChjICE9PSAnXCInKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYXJnICs9ICdcXFxcJztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGFyZy5zbGljZSgwLCAtMSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgYXJnICs9IGM7XHJcbiAgICAgICAgICAgIGVzY2FwZWQgPSBmYWxzZTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJnU3RyaW5nLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHZhciBjID0gYXJnU3RyaW5nLmNoYXJBdChpKTtcclxuICAgICAgICAgICAgaWYgKGMgPT09ICcgJyAmJiAhaW5RdW90ZXMpIHtcclxuICAgICAgICAgICAgICAgIGlmICghbGFzdENoYXJXYXNTcGFjZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGFyZ3MucHVzaChhcmcpO1xyXG4gICAgICAgICAgICAgICAgICAgIGFyZyA9ICcnO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbGFzdENoYXJXYXNTcGFjZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGxhc3RDaGFyV2FzU3BhY2UgPSBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoYyA9PT0gJ1wiJykge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFlc2NhcGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaW5RdW90ZXMgPSAhaW5RdW90ZXM7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBhcHBlbmQoYyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoYyA9PT0gXCJcXFxcXCIgJiYgZXNjYXBlZCkge1xyXG4gICAgICAgICAgICAgICAgYXBwZW5kKGMpO1xyXG4gICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGMgPT09IFwiXFxcXFwiICYmIGluUXVvdGVzKSB7XHJcbiAgICAgICAgICAgICAgICBlc2NhcGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGFwcGVuZChjKTtcclxuICAgICAgICAgICAgbGFzdENoYXJXYXNTcGFjZSA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWxhc3RDaGFyV2FzU3BhY2UpIHtcclxuICAgICAgICAgICAgYXJncy5wdXNoKGFyZy50cmltKCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYXJncztcclxuICAgIH07XHJcbiAgICBUb29sUnVubmVyLnByb3RvdHlwZS5fZ2V0Q29tbWFuZFN0cmluZyA9IGZ1bmN0aW9uIChvcHRpb25zLCBub1ByZWZpeCkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHRvb2xQYXRoID0gdGhpcy5fZ2V0U3Bhd25GaWxlTmFtZSgpO1xyXG4gICAgICAgIHZhciBhcmdzID0gdGhpcy5fZ2V0U3Bhd25BcmdzKG9wdGlvbnMpO1xyXG4gICAgICAgIHZhciBjbWQgPSBub1ByZWZpeCA/ICcnIDogJ1tjb21tYW5kXSc7IC8vIG9taXQgcHJlZml4IHdoZW4gcGlwZWQgdG8gYSBzZWNvbmQgdG9vbFxyXG4gICAgICAgIHZhciBjb21tYW5kUGFydHMgPSBbXTtcclxuICAgICAgICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInKSB7XHJcbiAgICAgICAgICAgIC8vIFdpbmRvd3MgKyBjbWQgZmlsZVxyXG4gICAgICAgICAgICBpZiAodGhpcy5faXNDbWRGaWxlKCkpIHtcclxuICAgICAgICAgICAgICAgIGNvbW1hbmRQYXJ0cy5wdXNoKHRvb2xQYXRoKTtcclxuICAgICAgICAgICAgICAgIGNvbW1hbmRQYXJ0cyA9IGNvbW1hbmRQYXJ0cy5jb25jYXQoYXJncyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gV2luZG93cyArIHZlcmJhdGltXHJcbiAgICAgICAgICAgIGVsc2UgaWYgKG9wdGlvbnMud2luZG93c1ZlcmJhdGltQXJndW1lbnRzKSB7XHJcbiAgICAgICAgICAgICAgICBjb21tYW5kUGFydHMucHVzaChcIlxcXCJcIiArIHRvb2xQYXRoICsgXCJcXFwiXCIpO1xyXG4gICAgICAgICAgICAgICAgY29tbWFuZFBhcnRzID0gY29tbWFuZFBhcnRzLmNvbmNhdChhcmdzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChvcHRpb25zLnNoZWxsKSB7XHJcbiAgICAgICAgICAgICAgICBjb21tYW5kUGFydHMucHVzaCh0aGlzLl93aW5kb3dzUXVvdGVDbWRBcmcodG9vbFBhdGgpKTtcclxuICAgICAgICAgICAgICAgIGNvbW1hbmRQYXJ0cyA9IGNvbW1hbmRQYXJ0cy5jb25jYXQoYXJncyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gV2luZG93cyAocmVndWxhcilcclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb21tYW5kUGFydHMucHVzaCh0aGlzLl93aW5kb3dzUXVvdGVDbWRBcmcodG9vbFBhdGgpKTtcclxuICAgICAgICAgICAgICAgIGNvbW1hbmRQYXJ0cyA9IGNvbW1hbmRQYXJ0cy5jb25jYXQoYXJncy5tYXAoZnVuY3Rpb24gKGFyZykgeyByZXR1cm4gX3RoaXMuX3dpbmRvd3NRdW90ZUNtZEFyZyhhcmcpOyB9KSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIE9TWC9MaW51eCAtIHRoaXMgY2FuIGxpa2VseSBiZSBpbXByb3ZlZCB3aXRoIHNvbWUgZm9ybSBvZiBxdW90aW5nLlxyXG4gICAgICAgICAgICAvLyBjcmVhdGluZyBwcm9jZXNzZXMgb24gVW5peCBpcyBmdW5kYW1lbnRhbGx5IGRpZmZlcmVudCB0aGFuIFdpbmRvd3MuXHJcbiAgICAgICAgICAgIC8vIG9uIFVuaXgsIGV4ZWN2cCgpIHRha2VzIGFuIGFyZyBhcnJheS5cclxuICAgICAgICAgICAgY29tbWFuZFBhcnRzLnB1c2godG9vbFBhdGgpO1xyXG4gICAgICAgICAgICBjb21tYW5kUGFydHMgPSBjb21tYW5kUGFydHMuY29uY2F0KGFyZ3MpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjbWQgKz0gY29tbWFuZFBhcnRzLmpvaW4oJyAnKTtcclxuICAgICAgICAvLyBhcHBlbmQgc2Vjb25kIHRvb2xcclxuICAgICAgICBpZiAodGhpcy5waXBlT3V0cHV0VG9Ub29sKSB7XHJcbiAgICAgICAgICAgIGNtZCArPSAnIHwgJyArIHRoaXMucGlwZU91dHB1dFRvVG9vbC5fZ2V0Q29tbWFuZFN0cmluZyhvcHRpb25zLCAvKm5vUHJlZml4OiovIHRydWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gY21kO1xyXG4gICAgfTtcclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLl9wcm9jZXNzTGluZUJ1ZmZlciA9IGZ1bmN0aW9uIChkYXRhLCBzdHJCdWZmZXIsIG9uTGluZSkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIHZhciBzID0gc3RyQnVmZmVyICsgZGF0YS50b1N0cmluZygpO1xyXG4gICAgICAgICAgICB2YXIgbiA9IHMuaW5kZXhPZihvcy5FT0wpO1xyXG4gICAgICAgICAgICB3aGlsZSAobiA+IC0xKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbGluZSA9IHMuc3Vic3RyaW5nKDAsIG4pO1xyXG4gICAgICAgICAgICAgICAgb25MaW5lKGxpbmUpO1xyXG4gICAgICAgICAgICAgICAgLy8gdGhlIHJlc3Qgb2YgdGhlIHN0cmluZyAuLi5cclxuICAgICAgICAgICAgICAgIHMgPSBzLnN1YnN0cmluZyhuICsgb3MuRU9MLmxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICBuID0gcy5pbmRleE9mKG9zLkVPTCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgc3RyQnVmZmVyID0gcztcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAvLyBzdHJlYW1pbmcgbGluZXMgdG8gY29uc29sZSBpcyBiZXN0IGVmZm9ydC4gIERvbid0IGZhaWwgYSBidWlsZC5cclxuICAgICAgICAgICAgdGhpcy5fZGVidWcoJ2Vycm9yIHByb2Nlc3NpbmcgbGluZScpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFdyYXBzIGFuIGFyZyBzdHJpbmcgd2l0aCBzcGVjaWZpZWQgY2hhciBpZiBpdCdzIG5vdCBhbHJlYWR5IHdyYXBwZWRcclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IEFyZyB3cmFwcGVkIHdpdGggc3BlY2lmaWVkIGNoYXJcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhcmcgSW5wdXQgYXJndW1lbnQgc3RyaW5nXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gd3JhcENoYXIgQSBjaGFyIGlucHV0IHN0cmluZyBzaG91bGQgYmUgd3JhcHBlZCB3aXRoXHJcbiAgICAgKi9cclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLl93cmFwQXJnID0gZnVuY3Rpb24gKGFyZywgd3JhcENoYXIpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2lzV3JhcHBlZChhcmcsIHdyYXBDaGFyKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gXCJcIiArIHdyYXBDaGFyICsgYXJnICsgd3JhcENoYXI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBhcmc7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBVbndyYXBzIGFuIGFyZyBzdHJpbmcgd3JhcHBlZCB3aXRoIHNwZWNpZmllZCBjaGFyXHJcbiAgICAgKiBAcGFyYW0gYXJnIEFyZyB3cmFwcGVkIHdpdGggc3BlY2lmaWVkIGNoYXJcclxuICAgICAqIEBwYXJhbSB3cmFwQ2hhciBBIGNoYXIgdG8gYmUgcmVtb3ZlZFxyXG4gICAgICovXHJcbiAgICBUb29sUnVubmVyLnByb3RvdHlwZS5fdW53cmFwQXJnID0gZnVuY3Rpb24gKGFyZywgd3JhcENoYXIpIHtcclxuICAgICAgICBpZiAodGhpcy5faXNXcmFwcGVkKGFyZywgd3JhcENoYXIpKSB7XHJcbiAgICAgICAgICAgIHZhciBwYXR0ZXJuID0gbmV3IFJlZ0V4cChcIiheXFxcXFxcXFw/XCIgKyB3cmFwQ2hhciArIFwiKXwoXFxcXFxcXFw/XCIgKyB3cmFwQ2hhciArIFwiJClcIiwgJ2cnKTtcclxuICAgICAgICAgICAgcmV0dXJuIGFyZy50cmltKCkucmVwbGFjZShwYXR0ZXJuLCAnJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBhcmc7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBEZXRlcm1pbmUgaWYgYXJnIHN0cmluZyBpcyB3cmFwcGVkIHdpdGggc3BlY2lmaWVkIGNoYXJcclxuICAgICAqIEBwYXJhbSBhcmcgSW5wdXQgYXJnIHN0cmluZ1xyXG4gICAgICovXHJcbiAgICBUb29sUnVubmVyLnByb3RvdHlwZS5faXNXcmFwcGVkID0gZnVuY3Rpb24gKGFyZywgd3JhcENoYXIpIHtcclxuICAgICAgICB2YXIgcGF0dGVybiA9IG5ldyBSZWdFeHAoXCJeXFxcXFxcXFw/XCIgKyB3cmFwQ2hhciArIFwiLitcXFxcXFxcXD9cIiArIHdyYXBDaGFyICsgXCIkXCIpO1xyXG4gICAgICAgIHJldHVybiBwYXR0ZXJuLnRlc3QoYXJnLnRyaW0oKSk7XHJcbiAgICB9O1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX2dldFNwYXduRmlsZU5hbWUgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgIGlmIChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzQ21kRmlsZSgpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvY2Vzcy5lbnZbJ0NPTVNQRUMnXSB8fCAnY21kLmV4ZSc7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5zaGVsbCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fd3JhcEFyZyh0aGlzLnRvb2xQYXRoLCAnXCInKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudG9vbFBhdGg7XHJcbiAgICB9O1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX2dldFNwYXduQXJncyA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc0NtZEZpbGUoKSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGFyZ2xpbmUgPSBcIi9EIC9TIC9DIFxcXCJcIiArIHRoaXMuX3dpbmRvd3NRdW90ZUNtZEFyZyh0aGlzLnRvb2xQYXRoKTtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5hcmdzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYXJnbGluZSArPSAnICc7XHJcbiAgICAgICAgICAgICAgICAgICAgYXJnbGluZSArPSBvcHRpb25zLndpbmRvd3NWZXJiYXRpbUFyZ3VtZW50cyA/IHRoaXMuYXJnc1tpXSA6IHRoaXMuX3dpbmRvd3NRdW90ZUNtZEFyZyh0aGlzLmFyZ3NbaV0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYXJnbGluZSArPSAnXCInO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFthcmdsaW5lXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy53aW5kb3dzVmVyYmF0aW1Bcmd1bWVudHMpIHtcclxuICAgICAgICAgICAgICAgIC8vIG5vdGUsIGluIE5vZGUgNi54IG9wdGlvbnMuYXJndjAgY2FuIGJlIHVzZWQgaW5zdGVhZCBvZiBvdmVycmlkaW5nIGFyZ3Muc2xpY2UgYW5kIGFyZ3MudW5zaGlmdC5cclxuICAgICAgICAgICAgICAgIC8vIGZvciBtb3JlIGRldGFpbHMsIHJlZmVyIHRvIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlanMvbm9kZS9ibG9iL3Y2LngvbGliL2NoaWxkX3Byb2Nlc3MuanNcclxuICAgICAgICAgICAgICAgIHZhciBhcmdzXzEgPSB0aGlzLmFyZ3Muc2xpY2UoMCk7IC8vIGNvcHkgdGhlIGFycmF5XHJcbiAgICAgICAgICAgICAgICAvLyBvdmVycmlkZSBzbGljZSB0byBwcmV2ZW50IE5vZGUgZnJvbSBjcmVhdGluZyBhIGNvcHkgb2YgdGhlIGFyZyBhcnJheS5cclxuICAgICAgICAgICAgICAgIC8vIHdlIG5lZWQgTm9kZSB0byB1c2UgdGhlIFwidW5zaGlmdFwiIG92ZXJyaWRlIGJlbG93LlxyXG4gICAgICAgICAgICAgICAgYXJnc18xLnNsaWNlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoICE9IDEgfHwgYXJndW1lbnRzWzBdICE9IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmV4cGVjdGVkIGFyZ3VtZW50cyBwYXNzZWQgdG8gYXJncy5zbGljZSB3aGVuIHdpbmRvd3NWZXJiYXRpbUFyZ3VtZW50cyBmbGFnIGlzIHNldC4nKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFyZ3NfMTtcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAvLyBvdmVycmlkZSB1bnNoaWZ0XHJcbiAgICAgICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAgICAgLy8gd2hlbiB1c2luZyB0aGUgd2luZG93c1ZlcmJhdGltQXJndW1lbnRzIG9wdGlvbiwgTm9kZSBkb2VzIG5vdCBxdW90ZSB0aGUgdG9vbCBwYXRoIHdoZW4gYnVpbGRpbmdcclxuICAgICAgICAgICAgICAgIC8vIHRoZSBjbWRsaW5lIHBhcmFtZXRlciBmb3IgdGhlIHdpbjMyIGZ1bmN0aW9uIENyZWF0ZVByb2Nlc3MoKS4gYW4gdW5xdW90ZWQgc3BhY2UgaW4gdGhlIHRvb2wgcGF0aFxyXG4gICAgICAgICAgICAgICAgLy8gY2F1c2VzIHByb2JsZW1zIGZvciB0b29scyB3aGVuIGF0dGVtcHRpbmcgdG8gcGFyc2UgdGhlaXIgb3duIGNvbW1hbmQgbGluZSBhcmdzLiB0b29scyB0eXBpY2FsbHlcclxuICAgICAgICAgICAgICAgIC8vIGFzc3VtZSB0aGVpciBhcmd1bWVudHMgYmVnaW4gYWZ0ZXIgYXJnIDAuXHJcbiAgICAgICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAgICAgLy8gYnkgaGlqYWNraW5nIHVuc2hpZnQsIHdlIGNhbiBxdW90ZSB0aGUgdG9vbCBwYXRoIHdoZW4gaXQgcHVzaGVkIG9udG8gdGhlIGFyZ3MgYXJyYXkuIE5vZGUgYnVpbGRzXHJcbiAgICAgICAgICAgICAgICAvLyB0aGUgY21kbGluZSBwYXJhbWV0ZXIgZnJvbSB0aGUgYXJncyBhcnJheS5cclxuICAgICAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgICAgICAvLyBub3RlLCB3ZSBjYW4ndCBzaW1wbHkgcGFzcyBhIHF1b3RlZCB0b29sIHBhdGggdG8gTm9kZSBmb3IgbXVsdGlwbGUgcmVhc29uczpcclxuICAgICAgICAgICAgICAgIC8vICAgMSkgTm9kZSB2ZXJpZmllcyB0aGUgZmlsZSBleGlzdHMgKGNhbGxzIHdpbjMyIGZ1bmN0aW9uIEdldEZpbGVBdHRyaWJ1dGVzVykgYW5kIHRoZSBjaGVjayByZXR1cm5zXHJcbiAgICAgICAgICAgICAgICAvLyAgICAgIGZhbHNlIGlmIHRoZSBwYXRoIGlzIHF1b3RlZC5cclxuICAgICAgICAgICAgICAgIC8vICAgMikgTm9kZSBwYXNzZXMgdGhlIHRvb2wgcGF0aCBhcyB0aGUgYXBwbGljYXRpb24gcGFyYW1ldGVyIHRvIENyZWF0ZVByb2Nlc3MsIHdoaWNoIGV4cGVjdHMgdGhlXHJcbiAgICAgICAgICAgICAgICAvLyAgICAgIHBhdGggdG8gYmUgdW5xdW90ZWQuXHJcbiAgICAgICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAgICAgLy8gYWxzbyBub3RlLCBpbiBhZGRpdGlvbiB0byB0aGUgdG9vbCBwYXRoIGJlaW5nIGVtYmVkZGVkIHdpdGhpbiB0aGUgY21kbGluZSBwYXJhbWV0ZXIsIE5vZGUgYWxzb1xyXG4gICAgICAgICAgICAgICAgLy8gcGFzc2VzIHRoZSB0b29sIHBhdGggdG8gQ3JlYXRlUHJvY2VzcyB2aWEgdGhlIGFwcGxpY2F0aW9uIHBhcmFtZXRlciAob3B0aW9uYWwgcGFyYW1ldGVyKS4gd2hlblxyXG4gICAgICAgICAgICAgICAgLy8gcHJlc2VudCwgV2luZG93cyB1c2VzIHRoZSBhcHBsaWNhdGlvbiBwYXJhbWV0ZXIgdG8gZGV0ZXJtaW5lIHdoaWNoIGZpbGUgdG8gcnVuLCBpbnN0ZWFkIG9mXHJcbiAgICAgICAgICAgICAgICAvLyBpbnRlcnByZXRpbmcgdGhlIGZpbGUgZnJvbSB0aGUgY21kbGluZSBwYXJhbWV0ZXIuXHJcbiAgICAgICAgICAgICAgICBhcmdzXzEudW5zaGlmdCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCAhPSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCBhcmd1bWVudHMgcGFzc2VkIHRvIGFyZ3MudW5zaGlmdCB3aGVuIHdpbmRvd3NWZXJiYXRpbUFyZ3VtZW50cyBmbGFnIGlzIHNldC4nKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS51bnNoaWZ0LmNhbGwoYXJnc18xLCBcIlxcXCJcIiArIGFyZ3VtZW50c1swXSArIFwiXFxcIlwiKTsgLy8gcXVvdGUgdGhlIGZpbGUgbmFtZVxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBhcmdzXzE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAob3B0aW9ucy5zaGVsbCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGFyZ3MgPSBbXTtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSB0aGlzLmFyZ3M7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFyZyA9IF9hW19pXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fbmVlZFF1b3Rlc0ZvckNtZChhcmcsICclJykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXJncy5wdXNoKHRoaXMuX3dyYXBBcmcoYXJnLCAnXCInKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhcmdzLnB1c2goYXJnKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYXJncztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChvcHRpb25zLnNoZWxsKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmFyZ3MubWFwKGZ1bmN0aW9uIChhcmcpIHtcclxuICAgICAgICAgICAgICAgIGlmIChfdGhpcy5faXNXcmFwcGVkKGFyZywgXCInXCIpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFyZztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIHJlbW92ZSB3cmFwcGluZyBkb3VibGUgcXVvdGVzIHRvIGF2b2lkIGVzY2FwaW5nXHJcbiAgICAgICAgICAgICAgICBhcmcgPSBfdGhpcy5fdW53cmFwQXJnKGFyZywgJ1wiJyk7XHJcbiAgICAgICAgICAgICAgICBhcmcgPSBfdGhpcy5fZXNjYXBlQ2hhcihhcmcsICdcIicpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzLl93cmFwQXJnKGFyZywgJ1wiJyk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcy5hcmdzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogRXNjYXBlIHNwZWNpZmllZCBjaGFyYWN0ZXIuXHJcbiAgICAgKiBAcGFyYW0gYXJnIFN0cmluZyB0byBlc2NhcGUgY2hhciBpblxyXG4gICAgICogQHBhcmFtIGNoYXJUb0VzY2FwZSBDaGFyIHNob3VsZCBiZSBlc2NhcGVkXHJcbiAgICAgKi9cclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLl9lc2NhcGVDaGFyID0gZnVuY3Rpb24gKGFyZywgY2hhclRvRXNjYXBlKSB7XHJcbiAgICAgICAgdmFyIGVzY0NoYXIgPSBcIlxcXFxcIjtcclxuICAgICAgICB2YXIgb3V0cHV0ID0gJyc7XHJcbiAgICAgICAgdmFyIGNoYXJJc0VzY2FwZWQgPSBmYWxzZTtcclxuICAgICAgICBmb3IgKHZhciBfaSA9IDAsIGFyZ18xID0gYXJnOyBfaSA8IGFyZ18xLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICB2YXIgY2hhciA9IGFyZ18xW19pXTtcclxuICAgICAgICAgICAgaWYgKGNoYXIgPT09IGNoYXJUb0VzY2FwZSAmJiAhY2hhcklzRXNjYXBlZCkge1xyXG4gICAgICAgICAgICAgICAgb3V0cHV0ICs9IGVzY0NoYXIgKyBjaGFyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgb3V0cHV0ICs9IGNoYXI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2hhcklzRXNjYXBlZCA9IGNoYXIgPT09IGVzY0NoYXIgJiYgIWNoYXJJc0VzY2FwZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBvdXRwdXQ7XHJcbiAgICB9O1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX2lzQ21kRmlsZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgdXBwZXJUb29sUGF0aCA9IHRoaXMudG9vbFBhdGgudG9VcHBlckNhc2UoKTtcclxuICAgICAgICByZXR1cm4gaW0uX2VuZHNXaXRoKHVwcGVyVG9vbFBhdGgsICcuQ01EJykgfHwgaW0uX2VuZHNXaXRoKHVwcGVyVG9vbFBhdGgsICcuQkFUJyk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgY21kIGFyZyBuZWVkcyB0byBiZSBxdW90ZWQuIFJldHVybnMgdHJ1ZSBpZiBhcmcgY29udGFpbnMgYW55IG9mIHNwZWNpYWwgY2hhcnMgYXJyYXkuXHJcbiAgICAgKiBAcGFyYW0gYXJnIFRoZSBjbWQgY29tbWFuZCBhcmcuXHJcbiAgICAgKiBAcGFyYW0gYWRkaXRpb25hbENoYXJzIEFkZGl0aW9uYWwgY2hhcnMgd2hpY2ggc2hvdWxkIGJlIGFsc28gY2hlY2tlZC5cclxuICAgICAqL1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX25lZWRRdW90ZXNGb3JDbWQgPSBmdW5jdGlvbiAoYXJnLCBhZGRpdGlvbmFsQ2hhcnMpIHtcclxuICAgICAgICB2YXIgc3BlY2lhbENoYXJzID0gdGhpcy5jbWRTcGVjaWFsQ2hhcnM7XHJcbiAgICAgICAgaWYgKGFkZGl0aW9uYWxDaGFycykge1xyXG4gICAgICAgICAgICBzcGVjaWFsQ2hhcnMgPSB0aGlzLmNtZFNwZWNpYWxDaGFycy5jb25jYXQoYWRkaXRpb25hbENoYXJzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIF9sb29wXzEgPSBmdW5jdGlvbiAoY2hhcikge1xyXG4gICAgICAgICAgICBpZiAoc3BlY2lhbENoYXJzLnNvbWUoZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHggPT09IGNoYXI7IH0pKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogdHJ1ZSB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICBmb3IgKHZhciBfaSA9IDAsIGFyZ18yID0gYXJnOyBfaSA8IGFyZ18yLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICB2YXIgY2hhciA9IGFyZ18yW19pXTtcclxuICAgICAgICAgICAgdmFyIHN0YXRlXzEgPSBfbG9vcF8xKGNoYXIpO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHN0YXRlXzEgPT09IFwib2JqZWN0XCIpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RhdGVfMS52YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfTtcclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLl93aW5kb3dzUXVvdGVDbWRBcmcgPSBmdW5jdGlvbiAoYXJnKSB7XHJcbiAgICAgICAgLy8gZm9yIC5leGUsIGFwcGx5IHRoZSBub3JtYWwgcXVvdGluZyBydWxlcyB0aGF0IGxpYnV2IGFwcGxpZXNcclxuICAgICAgICBpZiAoIXRoaXMuX2lzQ21kRmlsZSgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl91dl9xdW90ZV9jbWRfYXJnKGFyZyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIG90aGVyd2lzZSBhcHBseSBxdW90aW5nIHJ1bGVzIHNwZWNpZmljIHRvIHRoZSBjbWQuZXhlIGNvbW1hbmQgbGluZSBwYXJzZXIuXHJcbiAgICAgICAgLy8gdGhlIGxpYnV2IHJ1bGVzIGFyZSBnZW5lcmljIGFuZCBhcmUgbm90IGRlc2lnbmVkIHNwZWNpZmljYWxseSBmb3IgY21kLmV4ZVxyXG4gICAgICAgIC8vIGNvbW1hbmQgbGluZSBwYXJzZXIuXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBmb3IgYSBkZXRhaWxlZCBkZXNjcmlwdGlvbiBvZiB0aGUgY21kLmV4ZSBjb21tYW5kIGxpbmUgcGFyc2VyLCByZWZlciB0b1xyXG4gICAgICAgIC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDA5NDY5OS9ob3ctZG9lcy10aGUtd2luZG93cy1jb21tYW5kLWludGVycHJldGVyLWNtZC1leGUtcGFyc2Utc2NyaXB0cy83OTcwOTEyIzc5NzA5MTJcclxuICAgICAgICAvLyBuZWVkIHF1b3RlcyBmb3IgZW1wdHkgYXJnXHJcbiAgICAgICAgaWYgKCFhcmcpIHtcclxuICAgICAgICAgICAgcmV0dXJuICdcIlwiJztcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGFyZyBuZWVkcyB0byBiZSBxdW90ZWRcclxuICAgICAgICB2YXIgbmVlZHNRdW90ZXMgPSB0aGlzLl9uZWVkUXVvdGVzRm9yQ21kKGFyZyk7XHJcbiAgICAgICAgLy8gc2hvcnQtY2lyY3VpdCBpZiBxdW90ZXMgbm90IG5lZWRlZFxyXG4gICAgICAgIGlmICghbmVlZHNRdW90ZXMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGFyZztcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gdGhlIGZvbGxvd2luZyBxdW90aW5nIHJ1bGVzIGFyZSB2ZXJ5IHNpbWlsYXIgdG8gdGhlIHJ1bGVzIHRoYXQgYnkgbGlidXYgYXBwbGllcy5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIDEpIHdyYXAgdGhlIHN0cmluZyBpbiBxdW90ZXNcclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIDIpIGRvdWJsZS11cCBxdW90ZXMgLSBpLmUuIFwiID0+IFwiXCJcclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vICAgIHRoaXMgaXMgZGlmZmVyZW50IGZyb20gdGhlIGxpYnV2IHF1b3RpbmcgcnVsZXMuIGxpYnV2IHJlcGxhY2VzIFwiIHdpdGggXFxcIiwgd2hpY2ggdW5mb3J0dW5hdGVseVxyXG4gICAgICAgIC8vICAgIGRvZXNuJ3Qgd29yayB3ZWxsIHdpdGggYSBjbWQuZXhlIGNvbW1hbmQgbGluZS5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vICAgIG5vdGUsIHJlcGxhY2luZyBcIiB3aXRoIFwiXCIgYWxzbyB3b3JrcyB3ZWxsIGlmIHRoZSBhcmcgaXMgcGFzc2VkIHRvIGEgZG93bnN0cmVhbSAuTkVUIGNvbnNvbGUgYXBwLlxyXG4gICAgICAgIC8vICAgIGZvciBleGFtcGxlLCB0aGUgY29tbWFuZCBsaW5lOlxyXG4gICAgICAgIC8vICAgICAgICAgIGZvby5leGUgXCJteWFyZzpcIlwibXkgdmFsXCJcIlwiXHJcbiAgICAgICAgLy8gICAgaXMgcGFyc2VkIGJ5IGEgLk5FVCBjb25zb2xlIGFwcCBpbnRvIGFuIGFyZyBhcnJheTpcclxuICAgICAgICAvLyAgICAgICAgICBbIFwibXlhcmc6XFxcIm15IHZhbFxcXCJcIiBdXHJcbiAgICAgICAgLy8gICAgd2hpY2ggaXMgdGhlIHNhbWUgZW5kIHJlc3VsdCB3aGVuIGFwcGx5aW5nIGxpYnV2IHF1b3RpbmcgcnVsZXMuIGFsdGhvdWdoIHRoZSBhY3R1YWxcclxuICAgICAgICAvLyAgICBjb21tYW5kIGxpbmUgZnJvbSBsaWJ1diBxdW90aW5nIHJ1bGVzIHdvdWxkIGxvb2sgbGlrZTpcclxuICAgICAgICAvLyAgICAgICAgICBmb28uZXhlIFwibXlhcmc6XFxcIm15IHZhbFxcXCJcIlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gMykgZG91YmxlLXVwIHNsYXNoZXMgdGhhdCBwcmVjZWVkIGEgcXVvdGUsXHJcbiAgICAgICAgLy8gICAgZS5nLiAgaGVsbG8gXFx3b3JsZCAgICA9PiBcImhlbGxvIFxcd29ybGRcIlxyXG4gICAgICAgIC8vICAgICAgICAgIGhlbGxvXFxcIndvcmxkICAgID0+IFwiaGVsbG9cXFxcXCJcIndvcmxkXCJcclxuICAgICAgICAvLyAgICAgICAgICBoZWxsb1xcXFxcIndvcmxkICAgPT4gXCJoZWxsb1xcXFxcXFxcXCJcIndvcmxkXCJcclxuICAgICAgICAvLyAgICAgICAgICBoZWxsbyB3b3JsZFxcICAgID0+IFwiaGVsbG8gd29ybGRcXFxcXCJcclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vICAgIHRlY2huaWNhbGx5IHRoaXMgaXMgbm90IHJlcXVpcmVkIGZvciBhIGNtZC5leGUgY29tbWFuZCBsaW5lLCBvciB0aGUgYmF0Y2ggYXJndW1lbnQgcGFyc2VyLlxyXG4gICAgICAgIC8vICAgIHRoZSByZWFzb25zIGZvciBpbmNsdWRpbmcgdGhpcyBhcyBhIC5jbWQgcXVvdGluZyBydWxlIGFyZTpcclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vICAgIGEpIHRoaXMgaXMgb3B0aW1pemVkIGZvciB0aGUgc2NlbmFyaW8gd2hlcmUgdGhlIGFyZ3VtZW50IGlzIHBhc3NlZCBmcm9tIHRoZSAuY21kIGZpbGUgdG8gYW5cclxuICAgICAgICAvLyAgICAgICBleHRlcm5hbCBwcm9ncmFtLiBtYW55IHByb2dyYW1zIChlLmcuIC5ORVQgY29uc29sZSBhcHBzKSByZWx5IG9uIHRoZSBzbGFzaC1kb3VibGluZyBydWxlLlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gICAgYikgaXQncyB3aGF0IHdlJ3ZlIGJlZW4gZG9pbmcgcHJldmlvdXNseSAoYnkgZGVmZXJyaW5nIHRvIG5vZGUgZGVmYXVsdCBiZWhhdmlvcikgYW5kIHdlXHJcbiAgICAgICAgLy8gICAgICAgaGF2ZW4ndCBoZWFyZCBhbnkgY29tcGxhaW50cyBhYm91dCB0aGF0IGFzcGVjdC5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIG5vdGUsIGEgd2Vha25lc3Mgb2YgdGhlIHF1b3RpbmcgcnVsZXMgY2hvc2VuIGhlcmUsIGlzIHRoYXQgJSBpcyBub3QgZXNjYXBlZC4gaW4gZmFjdCwgJSBjYW5ub3QgYmVcclxuICAgICAgICAvLyBlc2NhcGVkIHdoZW4gdXNlZCBvbiB0aGUgY29tbWFuZCBsaW5lIGRpcmVjdGx5IC0gZXZlbiB0aG91Z2ggd2l0aGluIGEgLmNtZCBmaWxlICUgY2FuIGJlIGVzY2FwZWRcclxuICAgICAgICAvLyBieSB1c2luZyAlJS5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIHRoZSBzYXZpbmcgZ3JhY2UgaXMsIG9uIHRoZSBjb21tYW5kIGxpbmUsICV2YXIlIGlzIGxlZnQgYXMtaXMgaWYgdmFyIGlzIG5vdCBkZWZpbmVkLiB0aGlzIGNvbnRyYXN0c1xyXG4gICAgICAgIC8vIHRoZSBsaW5lIHBhcnNpbmcgcnVsZXMgd2l0aGluIGEgLmNtZCBmaWxlLCB3aGVyZSBpZiB2YXIgaXMgbm90IGRlZmluZWQgaXQgaXMgcmVwbGFjZWQgd2l0aCBub3RoaW5nLlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gb25lIG9wdGlvbiB0aGF0IHdhcyBleHBsb3JlZCB3YXMgcmVwbGFjaW5nICUgd2l0aCBeJSAtIGkuZS4gJXZhciUgPT4gXiV2YXJeJS4gdGhpcyBoYWNrIHdvdWxkXHJcbiAgICAgICAgLy8gb2Z0ZW4gd29yaywgc2luY2UgaXQgaXMgdW5saWtlbHkgdGhhdCB2YXJeIHdvdWxkIGV4aXN0LCBhbmQgdGhlIF4gY2hhcmFjdGVyIGlzIHJlbW92ZWQgd2hlbiB0aGVcclxuICAgICAgICAvLyB2YXJpYWJsZSBpcyB1c2VkLiB0aGUgcHJvYmxlbSwgaG93ZXZlciwgaXMgdGhhdCBeIGlzIG5vdCByZW1vdmVkIHdoZW4gJSogaXMgdXNlZCB0byBwYXNzIHRoZSBhcmdzXHJcbiAgICAgICAgLy8gdG8gYW4gZXh0ZXJuYWwgcHJvZ3JhbS5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIGFuIHVuZXhwbG9yZWQgcG90ZW50aWFsIHNvbHV0aW9uIGZvciB0aGUgJSBlc2NhcGluZyBwcm9ibGVtLCBpcyB0byBjcmVhdGUgYSB3cmFwcGVyIC5jbWQgZmlsZS5cclxuICAgICAgICAvLyAlIGNhbiBiZSBlc2NhcGVkIHdpdGhpbiBhIC5jbWQgZmlsZS5cclxuICAgICAgICB2YXIgcmV2ZXJzZSA9ICdcIic7XHJcbiAgICAgICAgdmFyIHF1b3RlX2hpdCA9IHRydWU7XHJcbiAgICAgICAgZm9yICh2YXIgaSA9IGFyZy5sZW5ndGg7IGkgPiAwOyBpLS0pIHsgLy8gd2FsayB0aGUgc3RyaW5nIGluIHJldmVyc2VcclxuICAgICAgICAgICAgcmV2ZXJzZSArPSBhcmdbaSAtIDFdO1xyXG4gICAgICAgICAgICBpZiAocXVvdGVfaGl0ICYmIGFyZ1tpIC0gMV0gPT0gJ1xcXFwnKSB7XHJcbiAgICAgICAgICAgICAgICByZXZlcnNlICs9ICdcXFxcJzsgLy8gZG91YmxlIHRoZSBzbGFzaFxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGFyZ1tpIC0gMV0gPT0gJ1wiJykge1xyXG4gICAgICAgICAgICAgICAgcXVvdGVfaGl0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHJldmVyc2UgKz0gJ1wiJzsgLy8gZG91YmxlIHRoZSBxdW90ZVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcXVvdGVfaGl0ID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV2ZXJzZSArPSAnXCInO1xyXG4gICAgICAgIHJldHVybiByZXZlcnNlLnNwbGl0KCcnKS5yZXZlcnNlKCkuam9pbignJyk7XHJcbiAgICB9O1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX3V2X3F1b3RlX2NtZF9hcmcgPSBmdW5jdGlvbiAoYXJnKSB7XHJcbiAgICAgICAgLy8gVG9vbCBydW5uZXIgd3JhcHMgY2hpbGRfcHJvY2Vzcy5zcGF3bigpIGFuZCBuZWVkcyB0byBhcHBseSB0aGUgc2FtZSBxdW90aW5nIGFzXHJcbiAgICAgICAgLy8gTm9kZSBpbiBjZXJ0YWluIGNhc2VzIHdoZXJlIHRoZSB1bmRvY3VtZW50ZWQgc3Bhd24gb3B0aW9uIHdpbmRvd3NWZXJiYXRpbUFyZ3VtZW50c1xyXG4gICAgICAgIC8vIGlzIHVzZWQuXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBTaW5jZSB0aGlzIGZ1bmN0aW9uIGlzIGEgcG9ydCBvZiBxdW90ZV9jbWRfYXJnIGZyb20gTm9kZSA0LnggKHRlY2huaWNhbGx5LCBsaWIgVVYsXHJcbiAgICAgICAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlanMvbm9kZS9ibG9iL3Y0LngvZGVwcy91di9zcmMvd2luL3Byb2Nlc3MuYyBmb3IgZGV0YWlscyksXHJcbiAgICAgICAgLy8gcGFzdGluZyBjb3B5cmlnaHQgbm90aWNlIGZyb20gTm9kZSB3aXRoaW4gdGhpcyBmdW5jdGlvbjpcclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vICAgICAgQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyAgICAgIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcclxuICAgICAgICAvLyAgICAgIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvXHJcbiAgICAgICAgLy8gICAgICBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxyXG4gICAgICAgIC8vICAgICAgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXHJcbiAgICAgICAgLy8gICAgICBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xyXG4gICAgICAgIC8vICAgICAgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vICAgICAgVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cclxuICAgICAgICAvLyAgICAgIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gICAgICBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXHJcbiAgICAgICAgLy8gICAgICBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcclxuICAgICAgICAvLyAgICAgIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxyXG4gICAgICAgIC8vICAgICAgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxyXG4gICAgICAgIC8vICAgICAgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkdcclxuICAgICAgICAvLyAgICAgIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1NcclxuICAgICAgICAvLyAgICAgIElOIFRIRSBTT0ZUV0FSRS5cclxuICAgICAgICBpZiAoIWFyZykge1xyXG4gICAgICAgICAgICAvLyBOZWVkIGRvdWJsZSBxdW90YXRpb24gZm9yIGVtcHR5IGFyZ3VtZW50XHJcbiAgICAgICAgICAgIHJldHVybiAnXCJcIic7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChhcmcuaW5kZXhPZignICcpIDwgMCAmJiBhcmcuaW5kZXhPZignXFx0JykgPCAwICYmIGFyZy5pbmRleE9mKCdcIicpIDwgMCkge1xyXG4gICAgICAgICAgICAvLyBObyBxdW90YXRpb24gbmVlZGVkXHJcbiAgICAgICAgICAgIHJldHVybiBhcmc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChhcmcuaW5kZXhPZignXCInKSA8IDAgJiYgYXJnLmluZGV4T2YoJ1xcXFwnKSA8IDApIHtcclxuICAgICAgICAgICAgLy8gTm8gZW1iZWRkZWQgZG91YmxlIHF1b3RlcyBvciBiYWNrc2xhc2hlcywgc28gSSBjYW4ganVzdCB3cmFwXHJcbiAgICAgICAgICAgIC8vIHF1b3RlIG1hcmtzIGFyb3VuZCB0aGUgd2hvbGUgdGhpbmcuXHJcbiAgICAgICAgICAgIHJldHVybiBcIlxcXCJcIiArIGFyZyArIFwiXFxcIlwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBFeHBlY3RlZCBpbnB1dC9vdXRwdXQ6XHJcbiAgICAgICAgLy8gICBpbnB1dCA6IGhlbGxvXCJ3b3JsZFxyXG4gICAgICAgIC8vICAgb3V0cHV0OiBcImhlbGxvXFxcIndvcmxkXCJcclxuICAgICAgICAvLyAgIGlucHV0IDogaGVsbG9cIlwid29ybGRcclxuICAgICAgICAvLyAgIG91dHB1dDogXCJoZWxsb1xcXCJcXFwid29ybGRcIlxyXG4gICAgICAgIC8vICAgaW5wdXQgOiBoZWxsb1xcd29ybGRcclxuICAgICAgICAvLyAgIG91dHB1dDogaGVsbG9cXHdvcmxkXHJcbiAgICAgICAgLy8gICBpbnB1dCA6IGhlbGxvXFxcXHdvcmxkXHJcbiAgICAgICAgLy8gICBvdXRwdXQ6IGhlbGxvXFxcXHdvcmxkXHJcbiAgICAgICAgLy8gICBpbnB1dCA6IGhlbGxvXFxcIndvcmxkXHJcbiAgICAgICAgLy8gICBvdXRwdXQ6IFwiaGVsbG9cXFxcXFxcIndvcmxkXCJcclxuICAgICAgICAvLyAgIGlucHV0IDogaGVsbG9cXFxcXCJ3b3JsZFxyXG4gICAgICAgIC8vICAgb3V0cHV0OiBcImhlbGxvXFxcXFxcXFxcXFwid29ybGRcIlxyXG4gICAgICAgIC8vICAgaW5wdXQgOiBoZWxsbyB3b3JsZFxcXHJcbiAgICAgICAgLy8gICBvdXRwdXQ6IFwiaGVsbG8gd29ybGRcXFxcXCIgLSBub3RlIHRoZSBjb21tZW50IGluIGxpYnV2IGFjdHVhbGx5IHJlYWRzIFwiaGVsbG8gd29ybGRcXFwiXHJcbiAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1dCBpdCBhcHBlYXJzIHRoZSBjb21tZW50IGlzIHdyb25nLCBpdCBzaG91bGQgYmUgXCJoZWxsbyB3b3JsZFxcXFxcIlxyXG4gICAgICAgIHZhciByZXZlcnNlID0gJ1wiJztcclxuICAgICAgICB2YXIgcXVvdGVfaGl0ID0gdHJ1ZTtcclxuICAgICAgICBmb3IgKHZhciBpID0gYXJnLmxlbmd0aDsgaSA+IDA7IGktLSkgeyAvLyB3YWxrIHRoZSBzdHJpbmcgaW4gcmV2ZXJzZVxyXG4gICAgICAgICAgICByZXZlcnNlICs9IGFyZ1tpIC0gMV07XHJcbiAgICAgICAgICAgIGlmIChxdW90ZV9oaXQgJiYgYXJnW2kgLSAxXSA9PSAnXFxcXCcpIHtcclxuICAgICAgICAgICAgICAgIHJldmVyc2UgKz0gJ1xcXFwnO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGFyZ1tpIC0gMV0gPT0gJ1wiJykge1xyXG4gICAgICAgICAgICAgICAgcXVvdGVfaGl0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHJldmVyc2UgKz0gJ1xcXFwnO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcXVvdGVfaGl0ID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV2ZXJzZSArPSAnXCInO1xyXG4gICAgICAgIHJldHVybiByZXZlcnNlLnNwbGl0KCcnKS5yZXZlcnNlKCkuam9pbignJyk7XHJcbiAgICB9O1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX2Nsb25lRXhlY09wdGlvbnMgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xyXG4gICAgICAgIHZhciByZXN1bHQgPSB7XHJcbiAgICAgICAgICAgIGN3ZDogb3B0aW9ucy5jd2QgfHwgcHJvY2Vzcy5jd2QoKSxcclxuICAgICAgICAgICAgZW52OiBvcHRpb25zLmVudiB8fCBwcm9jZXNzLmVudixcclxuICAgICAgICAgICAgc2lsZW50OiBvcHRpb25zLnNpbGVudCB8fCBmYWxzZSxcclxuICAgICAgICAgICAgZmFpbE9uU3RkRXJyOiBvcHRpb25zLmZhaWxPblN0ZEVyciB8fCBmYWxzZSxcclxuICAgICAgICAgICAgaWdub3JlUmV0dXJuQ29kZTogb3B0aW9ucy5pZ25vcmVSZXR1cm5Db2RlIHx8IGZhbHNlLFxyXG4gICAgICAgICAgICB3aW5kb3dzVmVyYmF0aW1Bcmd1bWVudHM6IG9wdGlvbnMud2luZG93c1ZlcmJhdGltQXJndW1lbnRzIHx8IGZhbHNlLFxyXG4gICAgICAgICAgICBzaGVsbDogb3B0aW9ucy5zaGVsbCB8fCBmYWxzZVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgcmVzdWx0Lm91dFN0cmVhbSA9IG9wdGlvbnMub3V0U3RyZWFtIHx8IHByb2Nlc3Muc3Rkb3V0O1xyXG4gICAgICAgIHJlc3VsdC5lcnJTdHJlYW0gPSBvcHRpb25zLmVyclN0cmVhbSB8fCBwcm9jZXNzLnN0ZGVycjtcclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfTtcclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLl9nZXRTcGF3bk9wdGlvbnMgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xyXG4gICAgICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgICAgICByZXN1bHQuY3dkID0gb3B0aW9ucy5jd2Q7XHJcbiAgICAgICAgcmVzdWx0LmVudiA9IG9wdGlvbnMuZW52O1xyXG4gICAgICAgIHJlc3VsdC5zaGVsbCA9IG9wdGlvbnMuc2hlbGw7XHJcbiAgICAgICAgcmVzdWx0Wyd3aW5kb3dzVmVyYmF0aW1Bcmd1bWVudHMnXSA9IG9wdGlvbnMud2luZG93c1ZlcmJhdGltQXJndW1lbnRzIHx8IHRoaXMuX2lzQ21kRmlsZSgpO1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9O1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX2dldFNwYXduU3luY09wdGlvbnMgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgICAgICByZXN1bHQuY3dkID0gb3B0aW9ucy5jd2Q7XHJcbiAgICAgICAgcmVzdWx0LmVudiA9IG9wdGlvbnMuZW52O1xyXG4gICAgICAgIHJlc3VsdC5zaGVsbCA9IG9wdGlvbnMuc2hlbGw7XHJcbiAgICAgICAgcmVzdWx0Wyd3aW5kb3dzVmVyYmF0aW1Bcmd1bWVudHMnXSA9IG9wdGlvbnMud2luZG93c1ZlcmJhdGltQXJndW1lbnRzIHx8IHRoaXMuX2lzQ21kRmlsZSgpO1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9O1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuZXhlY1dpdGhQaXBpbmcgPSBmdW5jdGlvbiAocGlwZU91dHB1dFRvVG9vbCwgb3B0aW9ucykge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdmFyIF9hLCBfYiwgX2MsIF9kO1xyXG4gICAgICAgIHZhciBkZWZlciA9IFEuZGVmZXIoKTtcclxuICAgICAgICB0aGlzLl9kZWJ1ZygnZXhlYyB0b29sOiAnICsgdGhpcy50b29sUGF0aCk7XHJcbiAgICAgICAgdGhpcy5fZGVidWcoJ2FyZ3VtZW50czonKTtcclxuICAgICAgICB0aGlzLmFyZ3MuZm9yRWFjaChmdW5jdGlvbiAoYXJnKSB7XHJcbiAgICAgICAgICAgIF90aGlzLl9kZWJ1ZygnICAgJyArIGFyZyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdmFyIHN1Y2Nlc3MgPSB0cnVlO1xyXG4gICAgICAgIHZhciBvcHRpb25zTm9uTnVsbCA9IHRoaXMuX2Nsb25lRXhlY09wdGlvbnMob3B0aW9ucyk7XHJcbiAgICAgICAgaWYgKCFvcHRpb25zTm9uTnVsbC5zaWxlbnQpIHtcclxuICAgICAgICAgICAgb3B0aW9uc05vbk51bGwub3V0U3RyZWFtLndyaXRlKHRoaXMuX2dldENvbW1hbmRTdHJpbmcob3B0aW9uc05vbk51bGwpICsgb3MuRU9MKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGNwO1xyXG4gICAgICAgIHZhciB0b29sUGF0aCA9IHBpcGVPdXRwdXRUb1Rvb2wudG9vbFBhdGg7XHJcbiAgICAgICAgdmFyIHRvb2xQYXRoRmlyc3Q7XHJcbiAgICAgICAgdmFyIHN1Y2Nlc3NGaXJzdCA9IHRydWU7XHJcbiAgICAgICAgdmFyIHJldHVybkNvZGVGaXJzdDtcclxuICAgICAgICB2YXIgZmlsZVN0cmVhbTtcclxuICAgICAgICB2YXIgd2FpdGluZ0V2ZW50cyA9IDA7IC8vIG51bWJlciBvZiBwcm9jZXNzIG9yIHN0cmVhbSBldmVudHMgd2UgYXJlIHdhaXRpbmcgb24gdG8gY29tcGxldGVcclxuICAgICAgICB2YXIgcmV0dXJuQ29kZSA9IDA7XHJcbiAgICAgICAgdmFyIGVycm9yO1xyXG4gICAgICAgIHRvb2xQYXRoRmlyc3QgPSB0aGlzLnRvb2xQYXRoO1xyXG4gICAgICAgIC8vIEZvbGxvd2luZyBub2RlIGRvY3VtZW50YXRpb24gZXhhbXBsZSBmcm9tIHRoaXMgbGluayBvbiBob3cgdG8gcGlwZSBvdXRwdXQgb2Ygb25lIHByb2Nlc3MgdG8gYW5vdGhlclxyXG4gICAgICAgIC8vIGh0dHBzOi8vbm9kZWpzLm9yZy9hcGkvY2hpbGRfcHJvY2Vzcy5odG1sI2NoaWxkX3Byb2Nlc3NfY2hpbGRfcHJvY2Vzc19zcGF3bl9jb21tYW5kX2FyZ3Nfb3B0aW9uc1xyXG4gICAgICAgIC8vc3RhcnQgdGhlIGNoaWxkIHByb2Nlc3MgZm9yIGJvdGggdG9vbHNcclxuICAgICAgICB3YWl0aW5nRXZlbnRzKys7XHJcbiAgICAgICAgdmFyIGNwRmlyc3QgPSBjaGlsZC5zcGF3bih0aGlzLl9nZXRTcGF3bkZpbGVOYW1lKG9wdGlvbnNOb25OdWxsKSwgdGhpcy5fZ2V0U3Bhd25BcmdzKG9wdGlvbnNOb25OdWxsKSwgdGhpcy5fZ2V0U3Bhd25PcHRpb25zKG9wdGlvbnNOb25OdWxsKSk7XHJcbiAgICAgICAgd2FpdGluZ0V2ZW50cysrO1xyXG4gICAgICAgIGNwID0gY2hpbGQuc3Bhd24ocGlwZU91dHB1dFRvVG9vbC5fZ2V0U3Bhd25GaWxlTmFtZShvcHRpb25zTm9uTnVsbCksIHBpcGVPdXRwdXRUb1Rvb2wuX2dldFNwYXduQXJncyhvcHRpb25zTm9uTnVsbCksIHBpcGVPdXRwdXRUb1Rvb2wuX2dldFNwYXduT3B0aW9ucyhvcHRpb25zTm9uTnVsbCkpO1xyXG4gICAgICAgIGZpbGVTdHJlYW0gPSB0aGlzLnBpcGVPdXRwdXRUb0ZpbGUgPyBmcy5jcmVhdGVXcml0ZVN0cmVhbSh0aGlzLnBpcGVPdXRwdXRUb0ZpbGUpIDogbnVsbDtcclxuICAgICAgICBpZiAoZmlsZVN0cmVhbSkge1xyXG4gICAgICAgICAgICB3YWl0aW5nRXZlbnRzKys7XHJcbiAgICAgICAgICAgIGZpbGVTdHJlYW0ub24oJ2ZpbmlzaCcsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHdhaXRpbmdFdmVudHMtLTsgLy9maWxlIHdyaXRlIGlzIGNvbXBsZXRlXHJcbiAgICAgICAgICAgICAgICBmaWxlU3RyZWFtID0gbnVsbDtcclxuICAgICAgICAgICAgICAgIGlmICh3YWl0aW5nRXZlbnRzID09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXIucmVqZWN0KGVycm9yKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVyLnJlc29sdmUocmV0dXJuQ29kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgZmlsZVN0cmVhbS5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICB3YWl0aW5nRXZlbnRzLS07IC8vdGhlcmUgd2VyZSBlcnJvcnMgd3JpdGluZyB0byB0aGUgZmlsZSwgd3JpdGUgaXMgZG9uZVxyXG4gICAgICAgICAgICAgICAgX3RoaXMuX2RlYnVnKFwiRmFpbGVkIHRvIHBpcGUgb3V0cHV0IG9mIFwiICsgdG9vbFBhdGhGaXJzdCArIFwiIHRvIGZpbGUgXCIgKyBfdGhpcy5waXBlT3V0cHV0VG9GaWxlICsgXCIuIEVycm9yID0gXCIgKyBlcnIpO1xyXG4gICAgICAgICAgICAgICAgZmlsZVN0cmVhbSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICBpZiAod2FpdGluZ0V2ZW50cyA9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVyLnJlamVjdChlcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZlci5yZXNvbHZlKHJldHVybkNvZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vcGlwZSBzdGRvdXQgb2YgZmlyc3QgdG9vbCB0byBzdGRpbiBvZiBzZWNvbmQgdG9vbFxyXG4gICAgICAgIChfYSA9IGNwRmlyc3Quc3Rkb3V0KSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2Eub24oJ2RhdGEnLCBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgICAgICB2YXIgX2E7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZmlsZVN0cmVhbSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZpbGVTdHJlYW0ud3JpdGUoZGF0YSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAoX2EgPSBjcC5zdGRpbikgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLndyaXRlKGRhdGEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLl9kZWJ1ZygnRmFpbGVkIHRvIHBpcGUgb3V0cHV0IG9mICcgKyB0b29sUGF0aEZpcnN0ICsgJyB0byAnICsgdG9vbFBhdGgpO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuX2RlYnVnKHRvb2xQYXRoICsgJyBtaWdodCBoYXZlIGV4aXRlZCBkdWUgdG8gZXJyb3JzIHByZW1hdHVyZWx5LiBWZXJpZnkgdGhlIGFyZ3VtZW50cyBwYXNzZWQgYXJlIHZhbGlkLicpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgKF9iID0gY3BGaXJzdC5zdGRlcnIpID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi5vbignZGF0YScsIGZ1bmN0aW9uIChkYXRhKSB7XHJcbiAgICAgICAgICAgIGlmIChmaWxlU3RyZWFtKSB7XHJcbiAgICAgICAgICAgICAgICBmaWxlU3RyZWFtLndyaXRlKGRhdGEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHN1Y2Nlc3NGaXJzdCA9ICFvcHRpb25zTm9uTnVsbC5mYWlsT25TdGRFcnI7XHJcbiAgICAgICAgICAgIGlmICghb3B0aW9uc05vbk51bGwuc2lsZW50KSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgcyA9IG9wdGlvbnNOb25OdWxsLmZhaWxPblN0ZEVyciA/IG9wdGlvbnNOb25OdWxsLmVyclN0cmVhbSA6IG9wdGlvbnNOb25OdWxsLm91dFN0cmVhbTtcclxuICAgICAgICAgICAgICAgIHMud3JpdGUoZGF0YSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICBjcEZpcnN0Lm9uKCdlcnJvcicsIGZ1bmN0aW9uIChlcnIpIHtcclxuICAgICAgICAgICAgdmFyIF9hO1xyXG4gICAgICAgICAgICB3YWl0aW5nRXZlbnRzLS07IC8vZmlyc3QgcHJvY2VzcyBpcyBjb21wbGV0ZSB3aXRoIGVycm9yc1xyXG4gICAgICAgICAgICBpZiAoZmlsZVN0cmVhbSkge1xyXG4gICAgICAgICAgICAgICAgZmlsZVN0cmVhbS5lbmQoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAoX2EgPSBjcC5zdGRpbikgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmVuZCgpO1xyXG4gICAgICAgICAgICBlcnJvciA9IG5ldyBFcnJvcih0b29sUGF0aEZpcnN0ICsgJyBmYWlsZWQuICcgKyBlcnIubWVzc2FnZSk7XHJcbiAgICAgICAgICAgIGlmICh3YWl0aW5nRXZlbnRzID09IDApIHtcclxuICAgICAgICAgICAgICAgIGRlZmVyLnJlamVjdChlcnJvcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICBjcEZpcnN0Lm9uKCdjbG9zZScsIGZ1bmN0aW9uIChjb2RlLCBzaWduYWwpIHtcclxuICAgICAgICAgICAgdmFyIF9hO1xyXG4gICAgICAgICAgICB3YWl0aW5nRXZlbnRzLS07IC8vZmlyc3QgcHJvY2VzcyBpcyBjb21wbGV0ZVxyXG4gICAgICAgICAgICBpZiAoY29kZSAhPSAwICYmICFvcHRpb25zTm9uTnVsbC5pZ25vcmVSZXR1cm5Db2RlKSB7XHJcbiAgICAgICAgICAgICAgICBzdWNjZXNzRmlyc3QgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIHJldHVybkNvZGVGaXJzdCA9IGNvZGU7XHJcbiAgICAgICAgICAgICAgICByZXR1cm5Db2RlID0gcmV0dXJuQ29kZUZpcnN0O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIF90aGlzLl9kZWJ1Zygnc3VjY2VzcyBvZiBmaXJzdCB0b29sOicgKyBzdWNjZXNzRmlyc3QpO1xyXG4gICAgICAgICAgICBpZiAoZmlsZVN0cmVhbSkge1xyXG4gICAgICAgICAgICAgICAgZmlsZVN0cmVhbS5lbmQoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAoX2EgPSBjcC5zdGRpbikgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmVuZCgpO1xyXG4gICAgICAgICAgICBpZiAod2FpdGluZ0V2ZW50cyA9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICBkZWZlci5yZWplY3QoZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVmZXIucmVzb2x2ZShyZXR1cm5Db2RlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHZhciBzdGRidWZmZXIgPSAnJztcclxuICAgICAgICAoX2MgPSBjcC5zdGRvdXQpID09PSBudWxsIHx8IF9jID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYy5vbignZGF0YScsIGZ1bmN0aW9uIChkYXRhKSB7XHJcbiAgICAgICAgICAgIF90aGlzLmVtaXQoJ3N0ZG91dCcsIGRhdGEpO1xyXG4gICAgICAgICAgICBpZiAoIW9wdGlvbnNOb25OdWxsLnNpbGVudCkge1xyXG4gICAgICAgICAgICAgICAgb3B0aW9uc05vbk51bGwub3V0U3RyZWFtLndyaXRlKGRhdGEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIF90aGlzLl9wcm9jZXNzTGluZUJ1ZmZlcihkYXRhLCBzdGRidWZmZXIsIGZ1bmN0aW9uIChsaW5lKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5lbWl0KCdzdGRsaW5lJywgbGluZSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHZhciBlcnJidWZmZXIgPSAnJztcclxuICAgICAgICAoX2QgPSBjcC5zdGRlcnIpID09PSBudWxsIHx8IF9kID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfZC5vbignZGF0YScsIGZ1bmN0aW9uIChkYXRhKSB7XHJcbiAgICAgICAgICAgIF90aGlzLmVtaXQoJ3N0ZGVycicsIGRhdGEpO1xyXG4gICAgICAgICAgICBzdWNjZXNzID0gIW9wdGlvbnNOb25OdWxsLmZhaWxPblN0ZEVycjtcclxuICAgICAgICAgICAgaWYgKCFvcHRpb25zTm9uTnVsbC5zaWxlbnQpIHtcclxuICAgICAgICAgICAgICAgIHZhciBzID0gb3B0aW9uc05vbk51bGwuZmFpbE9uU3RkRXJyID8gb3B0aW9uc05vbk51bGwuZXJyU3RyZWFtIDogb3B0aW9uc05vbk51bGwub3V0U3RyZWFtO1xyXG4gICAgICAgICAgICAgICAgcy53cml0ZShkYXRhKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBfdGhpcy5fcHJvY2Vzc0xpbmVCdWZmZXIoZGF0YSwgZXJyYnVmZmVyLCBmdW5jdGlvbiAobGluZSkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZW1pdCgnZXJybGluZScsIGxpbmUpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBjcC5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyKSB7XHJcbiAgICAgICAgICAgIHdhaXRpbmdFdmVudHMtLTsgLy9wcm9jZXNzIGlzIGRvbmUgd2l0aCBlcnJvcnNcclxuICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IodG9vbFBhdGggKyAnIGZhaWxlZC4gJyArIGVyci5tZXNzYWdlKTtcclxuICAgICAgICAgICAgaWYgKHdhaXRpbmdFdmVudHMgPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgZGVmZXIucmVqZWN0KGVycm9yKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGNwLm9uKCdjbG9zZScsIGZ1bmN0aW9uIChjb2RlLCBzaWduYWwpIHtcclxuICAgICAgICAgICAgd2FpdGluZ0V2ZW50cy0tOyAvL3Byb2Nlc3MgaXMgY29tcGxldGVcclxuICAgICAgICAgICAgX3RoaXMuX2RlYnVnKCdyYzonICsgY29kZSk7XHJcbiAgICAgICAgICAgIHJldHVybkNvZGUgPSBjb2RlO1xyXG4gICAgICAgICAgICBpZiAoc3RkYnVmZmVyLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmVtaXQoJ3N0ZGxpbmUnLCBzdGRidWZmZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChlcnJidWZmZXIubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZW1pdCgnZXJybGluZScsIGVycmJ1ZmZlcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGNvZGUgIT0gMCAmJiAhb3B0aW9uc05vbk51bGwuaWdub3JlUmV0dXJuQ29kZSkge1xyXG4gICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIF90aGlzLl9kZWJ1Zygnc3VjY2VzczonICsgc3VjY2Vzcyk7XHJcbiAgICAgICAgICAgIGlmICghc3VjY2Vzc0ZpcnN0KSB7IC8vaW4gdGhlIGNhc2Ugb3V0cHV0IGlzIHBpcGVkIHRvIGFub3RoZXIgdG9vbCwgY2hlY2sgZXhpdCBjb2RlIG9mIGJvdGggdG9vbHNcclxuICAgICAgICAgICAgICAgIGVycm9yID0gbmV3IEVycm9yKHRvb2xQYXRoRmlyc3QgKyAnIGZhaWxlZCB3aXRoIHJldHVybiBjb2RlOiAnICsgcmV0dXJuQ29kZUZpcnN0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICghc3VjY2Vzcykge1xyXG4gICAgICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IodG9vbFBhdGggKyAnIGZhaWxlZCB3aXRoIHJldHVybiBjb2RlOiAnICsgY29kZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHdhaXRpbmdFdmVudHMgPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVmZXIucmVqZWN0KGVycm9yKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZmVyLnJlc29sdmUocmV0dXJuQ29kZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gZGVmZXIucHJvbWlzZTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEFkZCBhcmd1bWVudFxyXG4gICAgICogQXBwZW5kIGFuIGFyZ3VtZW50IG9yIGFuIGFycmF5IG9mIGFyZ3VtZW50c1xyXG4gICAgICogcmV0dXJucyBUb29sUnVubmVyIGZvciBjaGFpbmluZ1xyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSAgICAgdmFsICAgICAgICBzdHJpbmcgY21kbGluZSBvciBhcnJheSBvZiBzdHJpbmdzXHJcbiAgICAgKiBAcmV0dXJucyAgIFRvb2xSdW5uZXJcclxuICAgICAqL1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuYXJnID0gZnVuY3Rpb24gKHZhbCkge1xyXG4gICAgICAgIGlmICghdmFsKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgQXJyYXkpIHtcclxuICAgICAgICAgICAgdGhpcy5fZGVidWcodGhpcy50b29sUGF0aCArICcgYXJnOiAnICsgSlNPTi5zdHJpbmdpZnkodmFsKSk7XHJcbiAgICAgICAgICAgIHRoaXMuYXJncyA9IHRoaXMuYXJncy5jb25jYXQodmFsKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mICh2YWwpID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICB0aGlzLl9kZWJ1Zyh0aGlzLnRvb2xQYXRoICsgJyBhcmc6ICcgKyB2YWwpO1xyXG4gICAgICAgICAgICB0aGlzLmFyZ3MgPSB0aGlzLmFyZ3MuY29uY2F0KHZhbC50cmltKCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFBhcnNlcyBhbiBhcmd1bWVudCBsaW5lIGludG8gb25lIG9yIG1vcmUgYXJndW1lbnRzXHJcbiAgICAgKiBlLmcuIC5saW5lKCdcImFyZyBvbmVcIiB0d28gLXonKSBpcyBlcXVpdmFsZW50IHRvIC5hcmcoWydhcmcgb25lJywgJ3R3bycsICcteiddKVxyXG4gICAgICogcmV0dXJucyBUb29sUnVubmVyIGZvciBjaGFpbmluZ1xyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSAgICAgdmFsICAgICAgICBzdHJpbmcgYXJndW1lbnQgbGluZVxyXG4gICAgICogQHJldHVybnMgICBUb29sUnVubmVyXHJcbiAgICAgKi9cclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLmxpbmUgPSBmdW5jdGlvbiAodmFsKSB7XHJcbiAgICAgICAgaWYgKCF2YWwpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuX2RlYnVnKHRoaXMudG9vbFBhdGggKyAnIGFyZzogJyArIHZhbCk7XHJcbiAgICAgICAgdGhpcy5hcmdzID0gdGhpcy5hcmdzLmNvbmNhdCh0aGlzLl9hcmdTdHJpbmdUb0FycmF5KHZhbCkpO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQWRkIGFyZ3VtZW50KHMpIGlmIGEgY29uZGl0aW9uIGlzIG1ldFxyXG4gICAgICogV3JhcHMgYXJnKCkuICBTZWUgYXJnIGZvciBkZXRhaWxzXHJcbiAgICAgKiByZXR1cm5zIFRvb2xSdW5uZXIgZm9yIGNoYWluaW5nXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtICAgICBjb25kaXRpb24gICAgIGJvb2xlYW4gY29uZGl0aW9uXHJcbiAgICAgKiBAcGFyYW0gICAgIHZhbCAgICAgc3RyaW5nIGNtZGxpbmUgb3IgYXJyYXkgb2Ygc3RyaW5nc1xyXG4gICAgICogQHJldHVybnMgICBUb29sUnVubmVyXHJcbiAgICAgKi9cclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLmFyZ0lmID0gZnVuY3Rpb24gKGNvbmRpdGlvbiwgdmFsKSB7XHJcbiAgICAgICAgaWYgKGNvbmRpdGlvbikge1xyXG4gICAgICAgICAgICB0aGlzLmFyZyh2YWwpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFBpcGUgb3V0cHV0IG9mIGV4ZWMoKSB0byBhbm90aGVyIHRvb2xcclxuICAgICAqIEBwYXJhbSB0b29sXHJcbiAgICAgKiBAcGFyYW0gZmlsZSAgb3B0aW9uYWwgZmlsZW5hbWUgdG8gYWRkaXRpb25hbGx5IHN0cmVhbSB0aGUgb3V0cHV0IHRvLlxyXG4gICAgICogQHJldHVybnMge1Rvb2xSdW5uZXJ9XHJcbiAgICAgKi9cclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLnBpcGVFeGVjT3V0cHV0VG9Ub29sID0gZnVuY3Rpb24gKHRvb2wsIGZpbGUpIHtcclxuICAgICAgICB0aGlzLnBpcGVPdXRwdXRUb1Rvb2wgPSB0b29sO1xyXG4gICAgICAgIHRoaXMucGlwZU91dHB1dFRvRmlsZSA9IGZpbGU7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBFeGVjIGEgdG9vbC5cclxuICAgICAqIE91dHB1dCB3aWxsIGJlIHN0cmVhbWVkIHRvIHRoZSBsaXZlIGNvbnNvbGUuXHJcbiAgICAgKiBSZXR1cm5zIHByb21pc2Ugd2l0aCByZXR1cm4gY29kZVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSAgICAgdG9vbCAgICAgcGF0aCB0byB0b29sIHRvIGV4ZWNcclxuICAgICAqIEBwYXJhbSAgICAgb3B0aW9ucyAgb3B0aW9uYWwgZXhlYyBvcHRpb25zLiAgU2VlIElFeGVjT3B0aW9uc1xyXG4gICAgICogQHJldHVybnMgICBudW1iZXJcclxuICAgICAqL1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuZXhlYyA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB2YXIgX2EsIF9iLCBfYztcclxuICAgICAgICBpZiAodGhpcy5waXBlT3V0cHV0VG9Ub29sKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmV4ZWNXaXRoUGlwaW5nKHRoaXMucGlwZU91dHB1dFRvVG9vbCwgb3B0aW9ucyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBkZWZlciA9IFEuZGVmZXIoKTtcclxuICAgICAgICB0aGlzLl9kZWJ1ZygnZXhlYyB0b29sOiAnICsgdGhpcy50b29sUGF0aCk7XHJcbiAgICAgICAgdGhpcy5fZGVidWcoJ2FyZ3VtZW50czonKTtcclxuICAgICAgICB0aGlzLmFyZ3MuZm9yRWFjaChmdW5jdGlvbiAoYXJnKSB7XHJcbiAgICAgICAgICAgIF90aGlzLl9kZWJ1ZygnICAgJyArIGFyZyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdmFyIG9wdGlvbnNOb25OdWxsID0gdGhpcy5fY2xvbmVFeGVjT3B0aW9ucyhvcHRpb25zKTtcclxuICAgICAgICBpZiAoIW9wdGlvbnNOb25OdWxsLnNpbGVudCkge1xyXG4gICAgICAgICAgICBvcHRpb25zTm9uTnVsbC5vdXRTdHJlYW0ud3JpdGUodGhpcy5fZ2V0Q29tbWFuZFN0cmluZyhvcHRpb25zTm9uTnVsbCkgKyBvcy5FT0wpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgc3RhdGUgPSBuZXcgRXhlY1N0YXRlKG9wdGlvbnNOb25OdWxsLCB0aGlzLnRvb2xQYXRoKTtcclxuICAgICAgICBzdGF0ZS5vbignZGVidWcnLCBmdW5jdGlvbiAobWVzc2FnZSkge1xyXG4gICAgICAgICAgICBfdGhpcy5fZGVidWcobWVzc2FnZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdmFyIGNwID0gY2hpbGQuc3Bhd24odGhpcy5fZ2V0U3Bhd25GaWxlTmFtZShvcHRpb25zKSwgdGhpcy5fZ2V0U3Bhd25BcmdzKG9wdGlvbnNOb25OdWxsKSwgdGhpcy5fZ2V0U3Bhd25PcHRpb25zKG9wdGlvbnMpKTtcclxuICAgICAgICB0aGlzLmNoaWxkUHJvY2VzcyA9IGNwO1xyXG4gICAgICAgIC8vIGl0IGlzIHBvc3NpYmxlIGZvciB0aGUgY2hpbGQgcHJvY2VzcyB0byBlbmQgaXRzIGxhc3QgbGluZSB3aXRob3V0IGEgbmV3IGxpbmUuXHJcbiAgICAgICAgLy8gYmVjYXVzZSBzdGRvdXQgaXMgYnVmZmVyZWQsIHRoaXMgY2F1c2VzIHRoZSBsYXN0IGxpbmUgdG8gbm90IGdldCBzZW50IHRvIHRoZSBwYXJlbnRcclxuICAgICAgICAvLyBzdHJlYW0uIEFkZGluZyB0aGlzIGV2ZW50IGZvcmNlcyBhIGZsdXNoIGJlZm9yZSB0aGUgY2hpbGQgc3RyZWFtcyBhcmUgY2xvc2VkLlxyXG4gICAgICAgIChfYSA9IGNwLnN0ZG91dCkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLm9uKCdmaW5pc2gnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmICghb3B0aW9uc05vbk51bGwuc2lsZW50KSB7XHJcbiAgICAgICAgICAgICAgICBvcHRpb25zTm9uTnVsbC5vdXRTdHJlYW0ud3JpdGUob3MuRU9MKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHZhciBzdGRidWZmZXIgPSAnJztcclxuICAgICAgICAoX2IgPSBjcC5zdGRvdXQpID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi5vbignZGF0YScsIGZ1bmN0aW9uIChkYXRhKSB7XHJcbiAgICAgICAgICAgIF90aGlzLmVtaXQoJ3N0ZG91dCcsIGRhdGEpO1xyXG4gICAgICAgICAgICBpZiAoIW9wdGlvbnNOb25OdWxsLnNpbGVudCkge1xyXG4gICAgICAgICAgICAgICAgb3B0aW9uc05vbk51bGwub3V0U3RyZWFtLndyaXRlKGRhdGEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIF90aGlzLl9wcm9jZXNzTGluZUJ1ZmZlcihkYXRhLCBzdGRidWZmZXIsIGZ1bmN0aW9uIChsaW5lKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5lbWl0KCdzdGRsaW5lJywgbGluZSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHZhciBlcnJidWZmZXIgPSAnJztcclxuICAgICAgICAoX2MgPSBjcC5zdGRlcnIpID09PSBudWxsIHx8IF9jID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYy5vbignZGF0YScsIGZ1bmN0aW9uIChkYXRhKSB7XHJcbiAgICAgICAgICAgIHN0YXRlLnByb2Nlc3NTdGRlcnIgPSB0cnVlO1xyXG4gICAgICAgICAgICBfdGhpcy5lbWl0KCdzdGRlcnInLCBkYXRhKTtcclxuICAgICAgICAgICAgaWYgKCFvcHRpb25zTm9uTnVsbC5zaWxlbnQpIHtcclxuICAgICAgICAgICAgICAgIHZhciBzID0gb3B0aW9uc05vbk51bGwuZmFpbE9uU3RkRXJyID8gb3B0aW9uc05vbk51bGwuZXJyU3RyZWFtIDogb3B0aW9uc05vbk51bGwub3V0U3RyZWFtO1xyXG4gICAgICAgICAgICAgICAgcy53cml0ZShkYXRhKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBfdGhpcy5fcHJvY2Vzc0xpbmVCdWZmZXIoZGF0YSwgZXJyYnVmZmVyLCBmdW5jdGlvbiAobGluZSkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZW1pdCgnZXJybGluZScsIGxpbmUpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBjcC5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyKSB7XHJcbiAgICAgICAgICAgIHN0YXRlLnByb2Nlc3NFcnJvciA9IGVyci5tZXNzYWdlO1xyXG4gICAgICAgICAgICBzdGF0ZS5wcm9jZXNzRXhpdGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgc3RhdGUucHJvY2Vzc0Nsb3NlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHN0YXRlLkNoZWNrQ29tcGxldGUoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBjcC5vbignZXhpdCcsIGZ1bmN0aW9uIChjb2RlLCBzaWduYWwpIHtcclxuICAgICAgICAgICAgc3RhdGUucHJvY2Vzc0V4aXRDb2RlID0gY29kZTtcclxuICAgICAgICAgICAgc3RhdGUucHJvY2Vzc0V4aXRlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIF90aGlzLl9kZWJ1ZyhcIkV4aXQgY29kZSBcIiArIGNvZGUgKyBcIiByZWNlaXZlZCBmcm9tIHRvb2wgJ1wiICsgX3RoaXMudG9vbFBhdGggKyBcIidcIik7XHJcbiAgICAgICAgICAgIHN0YXRlLkNoZWNrQ29tcGxldGUoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBjcC5vbignY2xvc2UnLCBmdW5jdGlvbiAoY29kZSwgc2lnbmFsKSB7XHJcbiAgICAgICAgICAgIHN0YXRlLnByb2Nlc3NFeGl0Q29kZSA9IGNvZGU7XHJcbiAgICAgICAgICAgIHN0YXRlLnByb2Nlc3NFeGl0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICBzdGF0ZS5wcm9jZXNzQ2xvc2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgX3RoaXMuX2RlYnVnKFwiU1RESU8gc3RyZWFtcyBoYXZlIGNsb3NlZCBmb3IgdG9vbCAnXCIgKyBfdGhpcy50b29sUGF0aCArIFwiJ1wiKTtcclxuICAgICAgICAgICAgc3RhdGUuQ2hlY2tDb21wbGV0ZSgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHN0YXRlLm9uKCdkb25lJywgZnVuY3Rpb24gKGVycm9yLCBleGl0Q29kZSkge1xyXG4gICAgICAgICAgICBpZiAoc3RkYnVmZmVyLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmVtaXQoJ3N0ZGxpbmUnLCBzdGRidWZmZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChlcnJidWZmZXIubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZW1pdCgnZXJybGluZScsIGVycmJ1ZmZlcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY3AucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XHJcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xyXG4gICAgICAgICAgICAgICAgZGVmZXIucmVqZWN0KGVycm9yKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGRlZmVyLnJlc29sdmUoZXhpdENvZGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIGRlZmVyLnByb21pc2U7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBFeGVjIGEgdG9vbCBzeW5jaHJvbm91c2x5LlxyXG4gICAgICogT3V0cHV0IHdpbGwgYmUgKm5vdCogYmUgc3RyZWFtZWQgdG8gdGhlIGxpdmUgY29uc29sZS4gIEl0IHdpbGwgYmUgcmV0dXJuZWQgYWZ0ZXIgZXhlY3V0aW9uIGlzIGNvbXBsZXRlLlxyXG4gICAgICogQXBwcm9wcmlhdGUgZm9yIHNob3J0IHJ1bm5pbmcgdG9vbHNcclxuICAgICAqIFJldHVybnMgSUV4ZWNTeW5jUmVzdWx0IHdpdGggb3V0cHV0IGFuZCByZXR1cm4gY29kZVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSAgICAgdG9vbCAgICAgcGF0aCB0byB0b29sIHRvIGV4ZWNcclxuICAgICAqIEBwYXJhbSAgICAgb3B0aW9ucyAgb3B0aW9uYWwgZXhlYyBvcHRpb25zLiAgU2VlIElFeGVjU3luY09wdGlvbnNcclxuICAgICAqIEByZXR1cm5zICAgSUV4ZWNTeW5jUmVzdWx0XHJcbiAgICAgKi9cclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLmV4ZWNTeW5jID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHRoaXMuX2RlYnVnKCdleGVjIHRvb2w6ICcgKyB0aGlzLnRvb2xQYXRoKTtcclxuICAgICAgICB0aGlzLl9kZWJ1ZygnYXJndW1lbnRzOicpO1xyXG4gICAgICAgIHRoaXMuYXJncy5mb3JFYWNoKGZ1bmN0aW9uIChhcmcpIHtcclxuICAgICAgICAgICAgX3RoaXMuX2RlYnVnKCcgICAnICsgYXJnKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB2YXIgc3VjY2VzcyA9IHRydWU7XHJcbiAgICAgICAgb3B0aW9ucyA9IHRoaXMuX2Nsb25lRXhlY09wdGlvbnMob3B0aW9ucyk7XHJcbiAgICAgICAgaWYgKCFvcHRpb25zLnNpbGVudCkge1xyXG4gICAgICAgICAgICBvcHRpb25zLm91dFN0cmVhbS53cml0ZSh0aGlzLl9nZXRDb21tYW5kU3RyaW5nKG9wdGlvbnMpICsgb3MuRU9MKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHIgPSBjaGlsZC5zcGF3blN5bmModGhpcy5fZ2V0U3Bhd25GaWxlTmFtZShvcHRpb25zKSwgdGhpcy5fZ2V0U3Bhd25BcmdzKG9wdGlvbnMpLCB0aGlzLl9nZXRTcGF3blN5bmNPcHRpb25zKG9wdGlvbnMpKTtcclxuICAgICAgICBpZiAoIW9wdGlvbnMuc2lsZW50ICYmIHIuc3Rkb3V0ICYmIHIuc3Rkb3V0Lmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgb3B0aW9ucy5vdXRTdHJlYW0ud3JpdGUoci5zdGRvdXQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIW9wdGlvbnMuc2lsZW50ICYmIHIuc3RkZXJyICYmIHIuc3RkZXJyLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgb3B0aW9ucy5lcnJTdHJlYW0ud3JpdGUoci5zdGRlcnIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgcmVzID0geyBjb2RlOiByLnN0YXR1cywgZXJyb3I6IHIuZXJyb3IgfTtcclxuICAgICAgICByZXMuc3Rkb3V0ID0gKHIuc3Rkb3V0KSA/IHIuc3Rkb3V0LnRvU3RyaW5nKCkgOiAnJztcclxuICAgICAgICByZXMuc3RkZXJyID0gKHIuc3RkZXJyKSA/IHIuc3RkZXJyLnRvU3RyaW5nKCkgOiAnJztcclxuICAgICAgICByZXR1cm4gcmVzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogVXNlZCB0byBjbG9zZSBjaGlsZCBwcm9jZXNzIGJ5IHNlbmRpbmcgU0lHTklOVCBzaWduYWwuXHJcbiAgICAgKiBJdCBhbGxvd3MgZXhlY3V0ZWQgc2NyaXB0IHRvIGhhdmUgc29tZSBhZGRpdGlvbmFsIGxvZ2ljIG9uIFNJR0lOVCwgYmVmb3JlIGV4aXRpbmcuXHJcbiAgICAgKi9cclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLmtpbGxDaGlsZFByb2Nlc3MgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuY2hpbGRQcm9jZXNzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2hpbGRQcm9jZXNzLmtpbGwoKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIFRvb2xSdW5uZXI7XHJcbn0oZXZlbnRzLkV2ZW50RW1pdHRlcikpO1xyXG5leHBvcnRzLlRvb2xSdW5uZXIgPSBUb29sUnVubmVyO1xyXG52YXIgRXhlY1N0YXRlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKEV4ZWNTdGF0ZSwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIEV4ZWNTdGF0ZShvcHRpb25zLCB0b29sUGF0aCkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuZGVsYXkgPSAxMDAwMDsgLy8gMTAgc2Vjb25kc1xyXG4gICAgICAgIF90aGlzLnRpbWVvdXQgPSBudWxsO1xyXG4gICAgICAgIGlmICghdG9vbFBhdGgpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0b29sUGF0aCBtdXN0IG5vdCBiZSBlbXB0eScpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBfdGhpcy5vcHRpb25zID0gb3B0aW9ucztcclxuICAgICAgICBfdGhpcy50b29sUGF0aCA9IHRvb2xQYXRoO1xyXG4gICAgICAgIHZhciBkZWxheSA9IHByb2Nlc3MuZW52WydUQVNLTElCX1RFU1RfVE9PTFJVTk5FUl9FWElUREVMQVknXTtcclxuICAgICAgICBpZiAoZGVsYXkpIHtcclxuICAgICAgICAgICAgX3RoaXMuZGVsYXkgPSBwYXJzZUludChkZWxheSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIEV4ZWNTdGF0ZS5wcm90b3R5cGUuQ2hlY2tDb21wbGV0ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAodGhpcy5kb25lKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMucHJvY2Vzc0Nsb3NlZCkge1xyXG4gICAgICAgICAgICB0aGlzLl9zZXRSZXN1bHQoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy5wcm9jZXNzRXhpdGVkKSB7XHJcbiAgICAgICAgICAgIHRoaXMudGltZW91dCA9IHNldFRpbWVvdXQoRXhlY1N0YXRlLkhhbmRsZVRpbWVvdXQsIHRoaXMuZGVsYXksIHRoaXMpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBFeGVjU3RhdGUucHJvdG90eXBlLl9kZWJ1ZyA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XHJcbiAgICAgICAgdGhpcy5lbWl0KCdkZWJ1ZycsIG1lc3NhZ2UpO1xyXG4gICAgfTtcclxuICAgIEV4ZWNTdGF0ZS5wcm90b3R5cGUuX3NldFJlc3VsdCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvLyBkZXRlcm1pbmUgd2hldGhlciB0aGVyZSBpcyBhbiBlcnJvclxyXG4gICAgICAgIHZhciBlcnJvcjtcclxuICAgICAgICBpZiAodGhpcy5wcm9jZXNzRXhpdGVkKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnByb2Nlc3NFcnJvcikge1xyXG4gICAgICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IoaW0uX2xvYygnTElCX1Byb2Nlc3NFcnJvcicsIHRoaXMudG9vbFBhdGgsIHRoaXMucHJvY2Vzc0Vycm9yKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5wcm9jZXNzRXhpdENvZGUgIT0gMCAmJiAhdGhpcy5vcHRpb25zLmlnbm9yZVJldHVybkNvZGUpIHtcclxuICAgICAgICAgICAgICAgIGVycm9yID0gbmV3IEVycm9yKGltLl9sb2MoJ0xJQl9Qcm9jZXNzRXhpdENvZGUnLCB0aGlzLnRvb2xQYXRoLCB0aGlzLnByb2Nlc3NFeGl0Q29kZSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMucHJvY2Vzc1N0ZGVyciAmJiB0aGlzLm9wdGlvbnMuZmFpbE9uU3RkRXJyKSB7XHJcbiAgICAgICAgICAgICAgICBlcnJvciA9IG5ldyBFcnJvcihpbS5fbG9jKCdMSUJfUHJvY2Vzc1N0ZGVycicsIHRoaXMudG9vbFBhdGgpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBjbGVhciB0aGUgdGltZW91dFxyXG4gICAgICAgIGlmICh0aGlzLnRpbWVvdXQpIHtcclxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZW91dCk7XHJcbiAgICAgICAgICAgIHRoaXMudGltZW91dCA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZG9uZSA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5lbWl0KCdkb25lJywgZXJyb3IsIHRoaXMucHJvY2Vzc0V4aXRDb2RlKTtcclxuICAgIH07XHJcbiAgICBFeGVjU3RhdGUuSGFuZGxlVGltZW91dCA9IGZ1bmN0aW9uIChzdGF0ZSkge1xyXG4gICAgICAgIGlmIChzdGF0ZS5kb25lKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFzdGF0ZS5wcm9jZXNzQ2xvc2VkICYmIHN0YXRlLnByb2Nlc3NFeGl0ZWQpIHtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coaW0uX2xvYygnTElCX1N0ZGlvTm90Q2xvc2VkJywgc3RhdGUuZGVsYXkgLyAxMDAwLCBzdGF0ZS50b29sUGF0aCkpO1xyXG4gICAgICAgICAgICBzdGF0ZS5fZGVidWcoaW0uX2xvYygnTElCX1N0ZGlvTm90Q2xvc2VkJywgc3RhdGUuZGVsYXkgLyAxMDAwLCBzdGF0ZS50b29sUGF0aCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBzdGF0ZS5fc2V0UmVzdWx0KCk7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIEV4ZWNTdGF0ZTtcclxufShldmVudHMuRXZlbnRFbWl0dGVyKSk7XHJcbiIsIlwidXNlIHN0cmljdFwiO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbmV4cG9ydHMuVmF1bHQgPSB2b2lkIDA7XHJcbnZhciBmcyA9IHJlcXVpcmUoXCJmc1wiKTtcclxudmFyIHBhdGggPSByZXF1aXJlKFwicGF0aFwiKTtcclxudmFyIGNyeXB0byA9IHJlcXVpcmUoXCJjcnlwdG9cIik7XHJcbnZhciB1dWlkVjQgPSByZXF1aXJlKCd1dWlkL3Y0Jyk7XHJcbnZhciBhbGdvcml0aG0gPSBcImFlcy0yNTYtY3RyXCI7XHJcbnZhciBlbmNyeXB0RW5jb2RpbmcgPSAnaGV4JztcclxudmFyIHVuZW5jcnlwdGVkRW5jb2RpbmcgPSAndXRmOCc7XHJcbi8vXHJcbi8vIFN0b3JlIHNlbnNpdGl2ZSBkYXRhIGluIHByb2MuXHJcbi8vIE1haW4gZ29hbDogUHJvdGVjdHMgdGFza3Mgd2hpY2ggd291bGQgZHVtcCBlbnZ2YXJzIGZyb20gbGVha2luZyBzZWNyZXRzIGluYWR2ZXJ0ZW50bHlcclxuLy8gICAgICAgICAgICB0aGUgdGFzayBsaWIgY2xlYXJzIGFmdGVyIHN0b3JpbmcuXHJcbi8vIEFsc28gcHJvdGVjdHMgYWdhaW5zdCBhIGR1bXAgb2YgYSBwcm9jZXNzIGdldHRpbmcgdGhlIHNlY3JldHNcclxuLy8gVGhlIHNlY3JldCBpcyBnZW5lcmF0ZWQgYW5kIHN0b3JlZCBleHRlcm5hbGx5IGZvciB0aGUgbGlmZXRpbWUgb2YgdGhlIHRhc2suXHJcbi8vXHJcbnZhciBWYXVsdCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIFZhdWx0KGtleVBhdGgpIHtcclxuICAgICAgICB0aGlzLl9rZXlGaWxlID0gcGF0aC5qb2luKGtleVBhdGgsICcudGFza2tleScpO1xyXG4gICAgICAgIHRoaXMuX3N0b3JlID0ge307XHJcbiAgICAgICAgdGhpcy5nZW5LZXkoKTtcclxuICAgIH1cclxuICAgIFZhdWx0LnByb3RvdHlwZS5pbml0aWFsaXplID0gZnVuY3Rpb24gKCkge1xyXG4gICAgfTtcclxuICAgIFZhdWx0LnByb3RvdHlwZS5zdG9yZVNlY3JldCA9IGZ1bmN0aW9uIChuYW1lLCBkYXRhKSB7XHJcbiAgICAgICAgaWYgKCFuYW1lIHx8IG5hbWUubGVuZ3RoID09IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBuYW1lID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xyXG4gICAgICAgIGlmICghZGF0YSB8fCBkYXRhLmxlbmd0aCA9PSAwKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdG9yZS5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX3N0b3JlW25hbWVdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGtleSA9IHRoaXMuZ2V0S2V5KCk7XHJcbiAgICAgICAgdmFyIGl2ID0gY3J5cHRvLnJhbmRvbUJ5dGVzKDE2KTtcclxuICAgICAgICB2YXIgY2lwaGVyID0gY3J5cHRvLmNyZWF0ZUNpcGhlcml2KGFsZ29yaXRobSwga2V5LCBpdik7XHJcbiAgICAgICAgdmFyIGNyeXB0ZWQgPSBjaXBoZXIudXBkYXRlKGRhdGEsIHVuZW5jcnlwdGVkRW5jb2RpbmcsIGVuY3J5cHRFbmNvZGluZyk7XHJcbiAgICAgICAgdmFyIGNyeXB0ZWRGaW5hbCA9IGNpcGhlci5maW5hbChlbmNyeXB0RW5jb2RpbmcpO1xyXG4gICAgICAgIHRoaXMuX3N0b3JlW25hbWVdID0gaXYudG9TdHJpbmcoZW5jcnlwdEVuY29kaW5nKSArIGNyeXB0ZWQgKyBjcnlwdGVkRmluYWw7XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9O1xyXG4gICAgVmF1bHQucHJvdG90eXBlLnJldHJpZXZlU2VjcmV0ID0gZnVuY3Rpb24gKG5hbWUpIHtcclxuICAgICAgICB2YXIgc2VjcmV0O1xyXG4gICAgICAgIG5hbWUgPSAobmFtZSB8fCAnJykudG9Mb3dlckNhc2UoKTtcclxuICAgICAgICBpZiAodGhpcy5fc3RvcmUuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcclxuICAgICAgICAgICAgdmFyIGtleSA9IHRoaXMuZ2V0S2V5KCk7XHJcbiAgICAgICAgICAgIHZhciBkYXRhID0gdGhpcy5fc3RvcmVbbmFtZV07XHJcbiAgICAgICAgICAgIHZhciBpdkRhdGFCdWZmZXIgPSBCdWZmZXIuZnJvbShkYXRhLCBlbmNyeXB0RW5jb2RpbmcpO1xyXG4gICAgICAgICAgICB2YXIgaXYgPSBpdkRhdGFCdWZmZXIuc2xpY2UoMCwgMTYpO1xyXG4gICAgICAgICAgICB2YXIgZW5jcnlwdGVkVGV4dCA9IGl2RGF0YUJ1ZmZlci5zbGljZSgxNik7XHJcbiAgICAgICAgICAgIHZhciBkZWNpcGhlciA9IGNyeXB0by5jcmVhdGVEZWNpcGhlcml2KGFsZ29yaXRobSwga2V5LCBpdik7XHJcbiAgICAgICAgICAgIHZhciBkZWMgPSBkZWNpcGhlci51cGRhdGUoZW5jcnlwdGVkVGV4dCwgZW5jcnlwdEVuY29kaW5nLCB1bmVuY3J5cHRlZEVuY29kaW5nKTtcclxuICAgICAgICAgICAgdmFyIGRlY0ZpbmFsID0gZGVjaXBoZXIuZmluYWwodW5lbmNyeXB0ZWRFbmNvZGluZyk7XHJcbiAgICAgICAgICAgIHNlY3JldCA9IGRlYyArIGRlY0ZpbmFsO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gc2VjcmV0O1xyXG4gICAgfTtcclxuICAgIFZhdWx0LnByb3RvdHlwZS5nZXRLZXkgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIGtleSA9IGZzLnJlYWRGaWxlU3luYyh0aGlzLl9rZXlGaWxlKS50b1N0cmluZygndXRmOCcpO1xyXG4gICAgICAgIC8vIEtleSBuZWVkcyB0byBiZSBoYXNoZWQgdG8gY29ycmVjdCBsZW5ndGggdG8gbWF0Y2ggYWxnb3JpdGhtIChhZXMtMjU2LWN0cilcclxuICAgICAgICByZXR1cm4gY3J5cHRvLmNyZWF0ZUhhc2goJ3NoYTI1NicpLnVwZGF0ZShrZXkpLmRpZ2VzdCgpO1xyXG4gICAgfTtcclxuICAgIFZhdWx0LnByb3RvdHlwZS5nZW5LZXkgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyh0aGlzLl9rZXlGaWxlLCB1dWlkVjQoKSwgeyBlbmNvZGluZzogJ3V0ZjgnIH0pO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBWYXVsdDtcclxufSgpKTtcclxuZXhwb3J0cy5WYXVsdCA9IFZhdWx0O1xyXG4iLCJmdW5jdGlvbiB3ZWJwYWNrRW1wdHlDb250ZXh0KHJlcSkge1xuXHR2YXIgZSA9IG5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIgKyByZXEgKyBcIidcIik7XG5cdGUuY29kZSA9ICdNT0RVTEVfTk9UX0ZPVU5EJztcblx0dGhyb3cgZTtcbn1cbndlYnBhY2tFbXB0eUNvbnRleHQua2V5cyA9ICgpID0+IChbXSk7XG53ZWJwYWNrRW1wdHlDb250ZXh0LnJlc29sdmUgPSB3ZWJwYWNrRW1wdHlDb250ZXh0O1xud2VicGFja0VtcHR5Q29udGV4dC5pZCA9IFwiLi9ub2RlX21vZHVsZXMvYXp1cmUtcGlwZWxpbmVzLXRhc2stbGliIHN5bmMgcmVjdXJzaXZlXCI7XG5tb2R1bGUuZXhwb3J0cyA9IHdlYnBhY2tFbXB0eUNvbnRleHQ7IiwiLyoqXG4gKiBDb252ZXJ0IGFycmF5IG9mIDE2IGJ5dGUgdmFsdWVzIHRvIFVVSUQgc3RyaW5nIGZvcm1hdCBvZiB0aGUgZm9ybTpcbiAqIFhYWFhYWFhYLVhYWFgtWFhYWC1YWFhYLVhYWFhYWFhYWFhYWFxuICovXG52YXIgYnl0ZVRvSGV4ID0gW107XG5mb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgKytpKSB7XG4gIGJ5dGVUb0hleFtpXSA9IChpICsgMHgxMDApLnRvU3RyaW5nKDE2KS5zdWJzdHIoMSk7XG59XG5cbmZ1bmN0aW9uIGJ5dGVzVG9VdWlkKGJ1Ziwgb2Zmc2V0KSB7XG4gIHZhciBpID0gb2Zmc2V0IHx8IDA7XG4gIHZhciBidGggPSBieXRlVG9IZXg7XG4gIC8vIGpvaW4gdXNlZCB0byBmaXggbWVtb3J5IGlzc3VlIGNhdXNlZCBieSBjb25jYXRlbmF0aW9uOiBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0zMTc1I2M0XG4gIHJldHVybiAoW1xuICAgIGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sXG4gICAgYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuICAgIGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcbiAgICBidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG4gICAgYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuICAgIGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sXG4gICAgYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSxcbiAgICBidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dXG4gIF0pLmpvaW4oJycpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJ5dGVzVG9VdWlkO1xuIiwiLy8gVW5pcXVlIElEIGNyZWF0aW9uIHJlcXVpcmVzIGEgaGlnaCBxdWFsaXR5IHJhbmRvbSAjIGdlbmVyYXRvci4gIEluIG5vZGUuanNcbi8vIHRoaXMgaXMgcHJldHR5IHN0cmFpZ2h0LWZvcndhcmQgLSB3ZSB1c2UgdGhlIGNyeXB0byBBUEkuXG5cbnZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBub2RlUk5HKCkge1xuICByZXR1cm4gY3J5cHRvLnJhbmRvbUJ5dGVzKDE2KTtcbn07XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PT0gJ2JpbmFyeScgPyBuZXcgQXJyYXkoMTYpIDogbnVsbDtcbiAgICBvcHRpb25zID0gbnVsbDtcbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgKytpaSkge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IGJ5dGVzVG9VdWlkKHJuZHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHY0O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2F3YWl0ZXIgPSAodGhpcyAmJiB0aGlzLl9fYXdhaXRlcikgfHwgZnVuY3Rpb24gKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG5leHBvcnRzLnNjcmFwZSA9IGV4cG9ydHMuZXh0cmFjdFppcCA9IGV4cG9ydHMuZXh0cmFjdFRhciA9IGV4cG9ydHMuZXh0cmFjdDd6ID0gZXhwb3J0cy5jYWNoZUZpbGUgPSBleHBvcnRzLmNhY2hlRGlyID0gZXhwb3J0cy5kb3dubG9hZFRvb2wgPSBleHBvcnRzLmZpbmRMb2NhbFRvb2xWZXJzaW9ucyA9IGV4cG9ydHMuZmluZExvY2FsVG9vbCA9IGV4cG9ydHMuZXZhbHVhdGVWZXJzaW9ucyA9IGV4cG9ydHMuY2xlYW5WZXJzaW9uID0gZXhwb3J0cy5pc0V4cGxpY2l0VmVyc2lvbiA9IGV4cG9ydHMucHJlcGVuZFBhdGggPSBleHBvcnRzLmRlYnVnID0gdm9pZCAwO1xyXG5jb25zdCBodHRwbSA9IHJlcXVpcmUoXCJ0eXBlZC1yZXN0LWNsaWVudC9IdHRwQ2xpZW50XCIpO1xyXG5jb25zdCBwYXRoID0gcmVxdWlyZShcInBhdGhcIik7XHJcbmNvbnN0IG9zID0gcmVxdWlyZShcIm9zXCIpO1xyXG5jb25zdCBwcm9jZXNzID0gcmVxdWlyZShcInByb2Nlc3NcIik7XHJcbmNvbnN0IGZzID0gcmVxdWlyZShcImZzXCIpO1xyXG5jb25zdCBzZW12ZXIgPSByZXF1aXJlKFwic2VtdmVyXCIpO1xyXG5jb25zdCB0bCA9IHJlcXVpcmUoXCJhenVyZS1waXBlbGluZXMtdGFzay1saWIvdGFza1wiKTtcclxuY29uc3QgY21wID0gcmVxdWlyZSgnc2VtdmVyLWNvbXBhcmUnKTtcclxuY29uc3QgdXVpZFY0ID0gcmVxdWlyZSgndXVpZC92NCcpO1xyXG5sZXQgcGtnID0gcmVxdWlyZShwYXRoLmpvaW4oX19kaXJuYW1lLCAncGFja2FnZS5qc29uJykpO1xyXG5sZXQgdXNlckFnZW50ID0gJ3ZzdHMtdGFzay1pbnN0YWxsZXIvJyArIHBrZy52ZXJzaW9uO1xyXG5sZXQgcmVxdWVzdE9wdGlvbnMgPSB7XHJcbiAgICAvLyBpZ25vcmVTc2xFcnJvcjogdHJ1ZSxcclxuICAgIHByb3h5OiB0bC5nZXRIdHRwUHJveHlDb25maWd1cmF0aW9uKCksXHJcbiAgICBjZXJ0OiB0bC5nZXRIdHRwQ2VydENvbmZpZ3VyYXRpb24oKSxcclxuICAgIGFsbG93UmVkaXJlY3RzOiB0cnVlLFxyXG4gICAgYWxsb3dSZXRyaWVzOiB0cnVlLFxyXG4gICAgbWF4UmV0cmllczogMlxyXG59O1xyXG50bC5zZXRSZXNvdXJjZVBhdGgocGF0aC5qb2luKF9fZGlybmFtZSwgJ2xpYi5qc29uJykpO1xyXG5mdW5jdGlvbiBkZWJ1ZyhtZXNzYWdlKSB7XHJcbiAgICB0bC5kZWJ1ZyhtZXNzYWdlKTtcclxufVxyXG5leHBvcnRzLmRlYnVnID0gZGVidWc7XHJcbmZ1bmN0aW9uIHByZXBlbmRQYXRoKHRvb2xQYXRoKSB7XHJcbiAgICB0bC5hc3NlcnRBZ2VudCgnMi4xMTUuMCcpO1xyXG4gICAgaWYgKCF0b29sUGF0aCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignUGFyYW1ldGVyIHRvb2xQYXRoIG11c3Qgbm90IGJlIG51bGwgb3IgZW1wdHknKTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKCF0bC5leGlzdCh0b29sUGF0aCkgfHwgIXRsLnN0YXRzKHRvb2xQYXRoKS5pc0RpcmVjdG9yeSgpKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEaXJlY3RvcnkgZG9lcyBub3QgZXhpc3Q6ICcgKyB0b29sUGF0aCk7XHJcbiAgICB9XHJcbiAgICAvLyB0b2RvOiBhZGQgYSB0ZXN0IGZvciBwYXRoXHJcbiAgICBjb25zb2xlLmxvZyh0bC5sb2MoJ1RPT0xfTElCX1ByZXBlbmRQYXRoJywgdG9vbFBhdGgpKTtcclxuICAgIGxldCBuZXdQYXRoID0gdG9vbFBhdGggKyBwYXRoLmRlbGltaXRlciArIHByb2Nlc3MuZW52WydQQVRIJ107XHJcbiAgICB0bC5kZWJ1ZygnbmV3IFBhdGg6ICcgKyBuZXdQYXRoKTtcclxuICAgIHByb2Nlc3MuZW52WydQQVRIJ10gPSBuZXdQYXRoO1xyXG4gICAgLy8gaW5zdHJ1Y3QgdGhlIGFnZW50IHRvIHNldCB0aGlzIHBhdGggb24gZnV0dXJlIHRhc2tzXHJcbiAgICBjb25zb2xlLmxvZygnIyN2c29bdGFzay5wcmVwZW5kcGF0aF0nICsgdG9vbFBhdGgpO1xyXG59XHJcbmV4cG9ydHMucHJlcGVuZFBhdGggPSBwcmVwZW5kUGF0aDtcclxuZnVuY3Rpb24gZGVsYXkobXMpIHtcclxuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcclxufVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIFZlcnNpb24gRnVuY3Rpb25zXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyoqXHJcbiAqIENoZWNrcyBpZiBhIHZlcnNpb24gc3BlYyBpcyBhbiBleHBsaWNpdCB2ZXJzaW9uIChlLmcuIDEuMC4xIG9yIHYxLjAuMSlcclxuICogQXMgb3Bwb3NlZCB0byBhIHZlcnNpb24gc3BlYyBsaWtlIDEueFxyXG4gKlxyXG4gKiBAcGFyYW0gdmVyc2lvblNwZWNcclxuICovXHJcbmZ1bmN0aW9uIGlzRXhwbGljaXRWZXJzaW9uKHZlcnNpb25TcGVjKSB7XHJcbiAgICBsZXQgYyA9IHNlbXZlci5jbGVhbih2ZXJzaW9uU3BlYyk7XHJcbiAgICB0bC5kZWJ1ZygnaXNFeHBsaWNpdDogJyArIGMpO1xyXG4gICAgbGV0IHZhbGlkID0gc2VtdmVyLnZhbGlkKGMpICE9IG51bGw7XHJcbiAgICB0bC5kZWJ1ZygnZXhwbGljaXQ/ICcgKyB2YWxpZCk7XHJcbiAgICByZXR1cm4gdmFsaWQ7XHJcbn1cclxuZXhwb3J0cy5pc0V4cGxpY2l0VmVyc2lvbiA9IGlzRXhwbGljaXRWZXJzaW9uO1xyXG4vKipcclxuICogUmV0dXJucyBjbGVhbmVkIChyZW1vdmVkIGxlYWRpbmcvdHJhaWxpbmcgd2hpdGVzcGFjZSwgcmVtb3ZlICc9dicgcHJlZml4KVxyXG4gKiBhbmQgcGFyc2VkIHZlcnNpb24sIG9yIG51bGwgaWYgdmVyc2lvbiBpcyBpbnZhbGlkLlxyXG4gKi9cclxuZnVuY3Rpb24gY2xlYW5WZXJzaW9uKHZlcnNpb24pIHtcclxuICAgIHRsLmRlYnVnKCdjbGVhbmluZzogJyArIHZlcnNpb24pO1xyXG4gICAgcmV0dXJuIHNlbXZlci5jbGVhbih2ZXJzaW9uKTtcclxufVxyXG5leHBvcnRzLmNsZWFuVmVyc2lvbiA9IGNsZWFuVmVyc2lvbjtcclxuLyoqXHJcbiAqIGV2YWx1YXRlcyBhIGxpc3Qgb2YgdmVyc2lvbnMgYW5kIHJldHVybnMgdGhlIGxhdGVzdCB2ZXJzaW9uIG1hdGNoaW5nIHRoZSB2ZXJzaW9uIHNwZWNcclxuICpcclxuICogQHBhcmFtIHZlcnNpb25zICAgICAgYW4gYXJyYXkgb2YgdmVyc2lvbnMgdG8gZXZhbHVhdGVcclxuICogQHBhcmFtIHZlcnNpb25TcGVjICAgYSB2ZXJzaW9uIHNwZWMgKGUuZy4gMS54KVxyXG4gKi9cclxuZnVuY3Rpb24gZXZhbHVhdGVWZXJzaW9ucyh2ZXJzaW9ucywgdmVyc2lvblNwZWMpIHtcclxuICAgIGxldCB2ZXJzaW9uO1xyXG4gICAgdGwuZGVidWcoJ2V2YWx1YXRpbmcgJyArIHZlcnNpb25zLmxlbmd0aCArICcgdmVyc2lvbnMnKTtcclxuICAgIHZlcnNpb25zID0gdmVyc2lvbnMuc29ydChjbXApO1xyXG4gICAgZm9yIChsZXQgaSA9IHZlcnNpb25zLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgICAgbGV0IHBvdGVudGlhbCA9IHZlcnNpb25zW2ldO1xyXG4gICAgICAgIGxldCBzYXRpc2ZpZWQgPSBzZW12ZXIuc2F0aXNmaWVzKHBvdGVudGlhbCwgdmVyc2lvblNwZWMpO1xyXG4gICAgICAgIGlmIChzYXRpc2ZpZWQpIHtcclxuICAgICAgICAgICAgdmVyc2lvbiA9IHBvdGVudGlhbDtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHZlcnNpb24pIHtcclxuICAgICAgICB0bC5kZWJ1ZygnbWF0Y2hlZDogJyArIHZlcnNpb24pO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgdGwuZGVidWcoJ21hdGNoIG5vdCBmb3VuZCcpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHZlcnNpb247XHJcbn1cclxuZXhwb3J0cy5ldmFsdWF0ZVZlcnNpb25zID0gZXZhbHVhdGVWZXJzaW9ucztcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBMb2NhbCBUb29sIENhY2hlIEZ1bmN0aW9uc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8qKlxyXG4gKiBmaW5kcyB0aGUgcGF0aCB0byBhIHRvb2wgaW4gdGhlIGxvY2FsIGluc3RhbGxlZCB0b29sIGNhY2hlXHJcbiAqXHJcbiAqIEBwYXJhbSB0b29sTmFtZSAgICAgIG5hbWUgb2YgdGhlIHRvb2xcclxuICogQHBhcmFtIHZlcnNpb25TcGVjICAgdmVyc2lvbiBvZiB0aGUgdG9vbFxyXG4gKiBAcGFyYW0gYXJjaCAgICAgICAgICBvcHRpb25hbCBhcmNoLiAgZGVmYXVsdHMgdG8gYXJjaCBvZiBjb21wdXRlclxyXG4gKi9cclxuZnVuY3Rpb24gZmluZExvY2FsVG9vbCh0b29sTmFtZSwgdmVyc2lvblNwZWMsIGFyY2gpIHtcclxuICAgIGlmICghdG9vbE5hbWUpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Rvb2xOYW1lIHBhcmFtZXRlciBpcyByZXF1aXJlZCcpO1xyXG4gICAgfVxyXG4gICAgaWYgKCF2ZXJzaW9uU3BlYykge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcigndmVyc2lvblNwZWMgcGFyYW1ldGVyIGlzIHJlcXVpcmVkJyk7XHJcbiAgICB9XHJcbiAgICBhcmNoID0gYXJjaCB8fCBvcy5hcmNoKCk7XHJcbiAgICAvLyBhdHRlbXB0IHRvIHJlc29sdmUgYW4gZXhwbGljaXQgdmVyc2lvblxyXG4gICAgaWYgKCFpc0V4cGxpY2l0VmVyc2lvbih2ZXJzaW9uU3BlYykpIHtcclxuICAgICAgICBsZXQgbG9jYWxWZXJzaW9ucyA9IGZpbmRMb2NhbFRvb2xWZXJzaW9ucyh0b29sTmFtZSwgYXJjaCk7XHJcbiAgICAgICAgbGV0IG1hdGNoID0gZXZhbHVhdGVWZXJzaW9ucyhsb2NhbFZlcnNpb25zLCB2ZXJzaW9uU3BlYyk7XHJcbiAgICAgICAgdmVyc2lvblNwZWMgPSBtYXRjaDtcclxuICAgIH1cclxuICAgIC8vIGNoZWNrIGZvciB0aGUgZXhwbGljaXQgdmVyc2lvbiBpbiB0aGUgY2FjaGVcclxuICAgIGxldCB0b29sUGF0aDtcclxuICAgIGlmICh2ZXJzaW9uU3BlYykge1xyXG4gICAgICAgIHZlcnNpb25TcGVjID0gc2VtdmVyLmNsZWFuKHZlcnNpb25TcGVjKTtcclxuICAgICAgICBsZXQgY2FjaGVSb290ID0gX2dldENhY2hlUm9vdCgpO1xyXG4gICAgICAgIGxldCBjYWNoZVBhdGggPSBwYXRoLmpvaW4oY2FjaGVSb290LCB0b29sTmFtZSwgdmVyc2lvblNwZWMsIGFyY2gpO1xyXG4gICAgICAgIHRsLmRlYnVnKCdjaGVja2luZyBjYWNoZTogJyArIGNhY2hlUGF0aCk7XHJcbiAgICAgICAgaWYgKHRsLmV4aXN0KGNhY2hlUGF0aCkgJiYgdGwuZXhpc3QoYCR7Y2FjaGVQYXRofS5jb21wbGV0ZWApKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKHRsLmxvYygnVE9PTF9MSUJfRm91bmRJbkNhY2hlJywgdG9vbE5hbWUsIHZlcnNpb25TcGVjLCBhcmNoKSk7XHJcbiAgICAgICAgICAgIHRvb2xQYXRoID0gY2FjaGVQYXRoO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGwuZGVidWcoJ25vdCBmb3VuZCcpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0b29sUGF0aDtcclxufVxyXG5leHBvcnRzLmZpbmRMb2NhbFRvb2wgPSBmaW5kTG9jYWxUb29sO1xyXG4vKipcclxuICogUmV0cmlldmVzIHRoZSB2ZXJzaW9ucyBvZiBhIHRvb2wgdGhhdCBpcyBpbnRhbGxlZCBpbiB0aGUgbG9jYWwgdG9vbCBjYWNoZVxyXG4gKlxyXG4gKiBAcGFyYW0gdG9vbE5hbWUgIG5hbWUgb2YgdGhlIHRvb2xcclxuICogQHBhcmFtIGFyY2ggICAgICBvcHRpb25hbCBhcmNoLiAgZGVmYXVsdHMgdG8gYXJjaCBvZiBjb21wdXRlclxyXG4gKi9cclxuZnVuY3Rpb24gZmluZExvY2FsVG9vbFZlcnNpb25zKHRvb2xOYW1lLCBhcmNoKSB7XHJcbiAgICBsZXQgdmVyc2lvbnMgPSBbXTtcclxuICAgIGFyY2ggPSBhcmNoIHx8IG9zLmFyY2goKTtcclxuICAgIGxldCB0b29sUGF0aCA9IHBhdGguam9pbihfZ2V0Q2FjaGVSb290KCksIHRvb2xOYW1lKTtcclxuICAgIGlmICh0bC5leGlzdCh0b29sUGF0aCkpIHtcclxuICAgICAgICBsZXQgY2hpbGRyZW4gPSB0bC5scygnJywgW3Rvb2xQYXRoXSk7XHJcbiAgICAgICAgY2hpbGRyZW4uZm9yRWFjaCgoY2hpbGQpID0+IHtcclxuICAgICAgICAgICAgaWYgKGlzRXhwbGljaXRWZXJzaW9uKGNoaWxkKSkge1xyXG4gICAgICAgICAgICAgICAgbGV0IGZ1bGxQYXRoID0gcGF0aC5qb2luKHRvb2xQYXRoLCBjaGlsZCwgYXJjaCk7XHJcbiAgICAgICAgICAgICAgICBpZiAodGwuZXhpc3QoZnVsbFBhdGgpICYmIHRsLmV4aXN0KGAke2Z1bGxQYXRofS5jb21wbGV0ZWApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmVyc2lvbnMucHVzaChjaGlsZCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiB2ZXJzaW9ucztcclxufVxyXG5leHBvcnRzLmZpbmRMb2NhbFRvb2xWZXJzaW9ucyA9IGZpbmRMb2NhbFRvb2xWZXJzaW9ucztcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gRG93bmxvYWQgRnVuY3Rpb25zXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vXHJcbi8vIFRPRE86IGtlZXAgZXh0ZW5zaW9uIGludGFjdFxyXG4vL1xyXG4vKipcclxuICogRG93bmxvYWQgYSB0b29sIGZyb20gYW4gdXJsIGFuZCBzdHJlYW0gaXQgaW50byBhIGZpbGVcclxuICpcclxuICogQHBhcmFtIHVybCAgICAgICB1cmwgb2YgdG9vbCB0byBkb3dubG9hZFxyXG4gKiBAcGFyYW0gZmlsZU5hbWUgIG9wdGlvbmFsIGZpbGVOYW1lLiAgU2hvdWxkIHR5cGljYWxseSBub3QgdXNlICh3aWxsIGJlIGEgZ3VpZCBmb3IgcmVsaWFiaWxpdHkpLiBDYW4gcGFzcyBmaWxlTmFtZSB3aXRoIGFuIGFic29sdXRlIHBhdGguXHJcbiAqIEBwYXJhbSBoYW5kbGVycyAgb3B0aW9uYWwgaGFuZGxlcnMgYXJyYXkuICBBdXRoIGhhbmRsZXJzIHRvIHBhc3MgdG8gdGhlIEh0dHBDbGllbnQgZm9yIHRoZSB0b29sIGRvd25sb2FkLlxyXG4gKi9cclxuZnVuY3Rpb24gZG93bmxvYWRUb29sKHVybCwgZmlsZU5hbWUsIGhhbmRsZXJzKSB7XHJcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBoYW5kbGVycyA9IGhhbmRsZXJzIHx8IG51bGw7XHJcbiAgICAgICAgICAgICAgICBsZXQgaHR0cCA9IG5ldyBodHRwbS5IdHRwQ2xpZW50KHVzZXJBZ2VudCwgaGFuZGxlcnMsIHJlcXVlc3RPcHRpb25zKTtcclxuICAgICAgICAgICAgICAgIHRsLmRlYnVnKGZpbGVOYW1lKTtcclxuICAgICAgICAgICAgICAgIGZpbGVOYW1lID0gZmlsZU5hbWUgfHwgdXVpZFY0KCk7XHJcbiAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiBpdCdzIGFuIGFic29sdXRlIHBhdGggYWxyZWFkeVxyXG4gICAgICAgICAgICAgICAgdmFyIGRlc3RQYXRoO1xyXG4gICAgICAgICAgICAgICAgaWYgKHBhdGguaXNBYnNvbHV0ZShmaWxlTmFtZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBkZXN0UGF0aCA9IGZpbGVOYW1lO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVzdFBhdGggPSBwYXRoLmpvaW4oX2dldEFnZW50VGVtcCgpLCBmaWxlTmFtZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBtYWtlIHN1cmUgdGhhdCB0aGUgZm9sZGVyIGV4aXN0c1xyXG4gICAgICAgICAgICAgICAgdGwubWtkaXJQKHBhdGguZGlybmFtZShkZXN0UGF0aCkpO1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2codGwubG9jKCdUT09MX0xJQl9Eb3dubG9hZGluZycsIHVybCkpO1xyXG4gICAgICAgICAgICAgICAgdGwuZGVidWcoJ2Rlc3RpbmF0aW9uICcgKyBkZXN0UGF0aCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhkZXN0UGF0aCkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJEZXN0aW5hdGlvbiBmaWxlIHBhdGggYWxyZWFkeSBleGlzdHNcIik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0bC5kZWJ1ZygnZG93bmxvYWRpbmcnKTtcclxuICAgICAgICAgICAgICAgIGxldCByZXNwb25zZSA9IHlpZWxkIGh0dHAuZ2V0KHVybCk7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UubWVzc2FnZS5zdGF0dXNDb2RlICE9IDIwMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBlcnIgPSBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgSFRUUCByZXNwb25zZTogJyArIHJlc3BvbnNlLm1lc3NhZ2Uuc3RhdHVzQ29kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgZXJyWydodHRwU3RhdHVzQ29kZSddID0gcmVzcG9uc2UubWVzc2FnZS5zdGF0dXNDb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgIHRsLmRlYnVnKGBGYWlsZWQgdG8gZG93bmxvYWQgXCIke2ZpbGVOYW1lfVwiIGZyb20gXCIke3VybH1cIi4gQ29kZSgke3Jlc3BvbnNlLm1lc3NhZ2Uuc3RhdHVzQ29kZX0pIE1lc3NhZ2UoJHtyZXNwb25zZS5tZXNzYWdlLnN0YXR1c01lc3NhZ2V9KWApO1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRsLmRlYnVnKCdjcmVhdGluZyBzdHJlYW0nKTtcclxuICAgICAgICAgICAgICAgIGxldCBmaWxlID0gZnMuY3JlYXRlV3JpdGVTdHJlYW0oZGVzdFBhdGgpO1xyXG4gICAgICAgICAgICAgICAgZmlsZS5vbignb3BlbicsIChmZCkgPT4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzdHJlYW0gPSByZXNwb25zZS5tZXNzYWdlLnBpcGUoZmlsZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5vbignY2xvc2UnLCAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bC5kZWJ1ZygnZG93bmxvYWQgY29tcGxldGUnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoZGVzdFBhdGgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgICAgICBmaWxlLm9uKCdlcnJvcicsIChlcnIpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBmaWxlLmVuZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSkpO1xyXG4gICAgfSk7XHJcbn1cclxuZXhwb3J0cy5kb3dubG9hZFRvb2wgPSBkb3dubG9hZFRvb2w7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIEluc3RhbGwgRnVuY3Rpb25zXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbmZ1bmN0aW9uIF9jcmVhdGVUb29sUGF0aCh0b29sLCB2ZXJzaW9uLCBhcmNoKSB7XHJcbiAgICAvLyB0b2RvOiBhZGQgdGVzdCBmb3IgY2xlYW5cclxuICAgIGxldCBmb2xkZXJQYXRoID0gcGF0aC5qb2luKF9nZXRDYWNoZVJvb3QoKSwgdG9vbCwgc2VtdmVyLmNsZWFuKHZlcnNpb24pLCBhcmNoKTtcclxuICAgIHRsLmRlYnVnKCdkZXN0aW5hdGlvbiAnICsgZm9sZGVyUGF0aCk7XHJcbiAgICBsZXQgbWFya2VyUGF0aCA9IGAke2ZvbGRlclBhdGh9LmNvbXBsZXRlYDtcclxuICAgIHRsLnJtUkYoZm9sZGVyUGF0aCk7XHJcbiAgICB0bC5ybVJGKG1hcmtlclBhdGgpO1xyXG4gICAgdGwubWtkaXJQKGZvbGRlclBhdGgpO1xyXG4gICAgcmV0dXJuIGZvbGRlclBhdGg7XHJcbn1cclxuZnVuY3Rpb24gX2NvbXBsZXRlVG9vbFBhdGgodG9vbCwgdmVyc2lvbiwgYXJjaCkge1xyXG4gICAgbGV0IGZvbGRlclBhdGggPSBwYXRoLmpvaW4oX2dldENhY2hlUm9vdCgpLCB0b29sLCBzZW12ZXIuY2xlYW4odmVyc2lvbiksIGFyY2gpO1xyXG4gICAgbGV0IG1hcmtlclBhdGggPSBgJHtmb2xkZXJQYXRofS5jb21wbGV0ZWA7XHJcbiAgICB0bC53cml0ZUZpbGUobWFya2VyUGF0aCwgJycpO1xyXG4gICAgdGwuZGVidWcoJ2ZpbmlzaGVkIGNhY2hpbmcgdG9vbCcpO1xyXG59XHJcbi8qKlxyXG4gKiBDYWNoZXMgYSBkaXJlY3RvcnkgYW5kIGluc3RhbGxzIGl0IGludG8gdGhlIHRvb2wgY2FjaGVEaXJcclxuICpcclxuICogQHBhcmFtIHNvdXJjZURpciAgICB0aGUgZGlyZWN0b3J5IHRvIGNhY2hlIGludG8gdG9vbHNcclxuICogQHBhcmFtIHRvb2wgICAgICAgICAgdG9vbCBuYW1lXHJcbiAqIEBwYXJhbSB2ZXJzaW9uICAgICAgIHZlcnNpb24gb2YgdGhlIHRvb2wuICBzZW12ZXIgZm9ybWF0XHJcbiAqIEBwYXJhbSBhcmNoICAgICAgICAgIGFyY2hpdGVjdHVyZSBvZiB0aGUgdG9vbC4gIE9wdGlvbmFsLiAgRGVmYXVsdHMgdG8gbWFjaGluZSBhcmNoaXRlY3R1cmVcclxuICovXHJcbmZ1bmN0aW9uIGNhY2hlRGlyKHNvdXJjZURpciwgdG9vbCwgdmVyc2lvbiwgYXJjaCkge1xyXG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcclxuICAgICAgICB2ZXJzaW9uID0gc2VtdmVyLmNsZWFuKHZlcnNpb24pO1xyXG4gICAgICAgIGFyY2ggPSBhcmNoIHx8IG9zLmFyY2goKTtcclxuICAgICAgICBjb25zb2xlLmxvZyh0bC5sb2MoJ1RPT0xfTElCX0NhY2hpbmdUb29sJywgdG9vbCwgdmVyc2lvbiwgYXJjaCkpO1xyXG4gICAgICAgIHRsLmRlYnVnKCdzb3VyY2UgZGlyOiAnICsgc291cmNlRGlyKTtcclxuICAgICAgICBpZiAoIXRsLnN0YXRzKHNvdXJjZURpcikuaXNEaXJlY3RvcnkoKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZURpciBpcyBub3QgYSBkaXJlY3RvcnknKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gY3JlYXRlIHRoZSB0b29sIGRpclxyXG4gICAgICAgIGxldCBkZXN0UGF0aCA9IF9jcmVhdGVUb29sUGF0aCh0b29sLCB2ZXJzaW9uLCBhcmNoKTtcclxuICAgICAgICAvLyBjb3B5IGVhY2ggY2hpbGQgaXRlbS4gZG8gbm90IG1vdmUuIG1vdmUgY2FuIGZhaWwgb24gV2luZG93c1xyXG4gICAgICAgIC8vIGR1ZSB0byBhbnRpLXZpcnVzIHNvZnR3YXJlIGhhdmluZyBhbiBvcGVuIGhhbmRsZSBvbiBhIGZpbGUuXHJcbiAgICAgICAgZm9yIChsZXQgaXRlbU5hbWUgb2YgZnMucmVhZGRpclN5bmMoc291cmNlRGlyKSkge1xyXG4gICAgICAgICAgICBsZXQgcyA9IHBhdGguam9pbihzb3VyY2VEaXIsIGl0ZW1OYW1lKTtcclxuICAgICAgICAgICAgdGwuY3AocywgZGVzdFBhdGggKyAnLycsICctcicpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyB3cml0ZSAuY29tcGxldGVcclxuICAgICAgICBfY29tcGxldGVUb29sUGF0aCh0b29sLCB2ZXJzaW9uLCBhcmNoKTtcclxuICAgICAgICByZXR1cm4gZGVzdFBhdGg7XHJcbiAgICB9KTtcclxufVxyXG5leHBvcnRzLmNhY2hlRGlyID0gY2FjaGVEaXI7XHJcbi8qKlxyXG4gKiBDYWNoZXMgYSBkb3dubG9hZGVkIGZpbGUgKEdVSUQpIGFuZCBpbnN0YWxscyBpdFxyXG4gKiBpbnRvIHRoZSB0b29sIGNhY2hlIHdpdGggYSBnaXZlbiB0YXJnZXROYW1lXHJcbiAqXHJcbiAqIEBwYXJhbSBzb3VyY2VGaWxlICAgIHRoZSBmaWxlIHRvIGNhY2hlIGludG8gdG9vbHMuICBUeXBpY2FsbHkgYSByZXN1bHQgb2YgZG93bmxvYWRUb29sIHdoaWNoIGlzIGEgZ3VpZC5cclxuICogQHBhcmFtIHRhcmdldEZpbGUgICAgdGhlIG5hbWUgb2YgdGhlIGZpbGUgbmFtZSBpbiB0aGUgdG9vbHMgZGlyZWN0b3J5XHJcbiAqIEBwYXJhbSB0b29sICAgICAgICAgIHRvb2wgbmFtZVxyXG4gKiBAcGFyYW0gdmVyc2lvbiAgICAgICB2ZXJzaW9uIG9mIHRoZSB0b29sLiAgc2VtdmVyIGZvcm1hdFxyXG4gKiBAcGFyYW0gYXJjaCAgICAgICAgICBhcmNoaXRlY3R1cmUgb2YgdGhlIHRvb2wuICBPcHRpb25hbC4gIERlZmF1bHRzIHRvIG1hY2hpbmUgYXJjaGl0ZWN0dXJlXHJcbiAqL1xyXG5mdW5jdGlvbiBjYWNoZUZpbGUoc291cmNlRmlsZSwgdGFyZ2V0RmlsZSwgdG9vbCwgdmVyc2lvbiwgYXJjaCkge1xyXG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcclxuICAgICAgICB2ZXJzaW9uID0gc2VtdmVyLmNsZWFuKHZlcnNpb24pO1xyXG4gICAgICAgIGFyY2ggPSBhcmNoIHx8IG9zLmFyY2goKTtcclxuICAgICAgICBjb25zb2xlLmxvZyh0bC5sb2MoJ1RPT0xfTElCX0NhY2hpbmdUb29sJywgdG9vbCwgdmVyc2lvbiwgYXJjaCkpO1xyXG4gICAgICAgIHRsLmRlYnVnKCdzb3VyY2UgZmlsZTonICsgc291cmNlRmlsZSk7XHJcbiAgICAgICAgaWYgKCF0bC5zdGF0cyhzb3VyY2VGaWxlKS5pc0ZpbGUoKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZUZpbGUgaXMgbm90IGEgZmlsZScpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBjcmVhdGUgdGhlIHRvb2wgZGlyXHJcbiAgICAgICAgbGV0IGRlc3RGb2xkZXIgPSBfY3JlYXRlVG9vbFBhdGgodG9vbCwgdmVyc2lvbiwgYXJjaCk7XHJcbiAgICAgICAgLy8gY29weSBpbnN0ZWFkIG9mIG1vdmUuIG1vdmUgY2FuIGZhaWwgb24gV2luZG93cyBkdWUgdG9cclxuICAgICAgICAvLyBhbnRpLXZpcnVzIHNvZnR3YXJlIGhhdmluZyBhbiBvcGVuIGhhbmRsZSBvbiBhIGZpbGUuXHJcbiAgICAgICAgbGV0IGRlc3RQYXRoID0gcGF0aC5qb2luKGRlc3RGb2xkZXIsIHRhcmdldEZpbGUpO1xyXG4gICAgICAgIHRsLmRlYnVnKCdkZXN0aW5hdGlvbiBmaWxlJyArIGRlc3RQYXRoKTtcclxuICAgICAgICB0bC5jcChzb3VyY2VGaWxlLCBkZXN0UGF0aCk7XHJcbiAgICAgICAgLy8gd3JpdGUgLmNvbXBsZXRlXHJcbiAgICAgICAgX2NvbXBsZXRlVG9vbFBhdGgodG9vbCwgdmVyc2lvbiwgYXJjaCk7XHJcbiAgICAgICAgcmV0dXJuIGRlc3RGb2xkZXI7XHJcbiAgICB9KTtcclxufVxyXG5leHBvcnRzLmNhY2hlRmlsZSA9IGNhY2hlRmlsZTtcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gRXh0cmFjdCBGdW5jdGlvbnNcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyoqXHJcbiAqIEV4dHJhY3QgYSAuN3ogZmlsZVxyXG4gKlxyXG4gKiBAcGFyYW0gZmlsZSAgICAgcGF0aCB0byB0aGUgLjd6IGZpbGVcclxuICogQHBhcmFtIGRlc3QgICAgIGRlc3RpbmF0aW9uIGRpcmVjdG9yeS4gT3B0aW9uYWwuXHJcbiAqIEBwYXJhbSBfN3pQYXRoICBwYXRoIHRvIDd6ci5leGUuIE9wdGlvbmFsLCBmb3IgbG9uZyBwYXRoIHN1cHBvcnQuIE1vc3QgLjd6IGFyY2hpdmVzIGRvIG5vdCBoYXZlIHRoaXNcclxuICogcHJvYmxlbS4gSWYgeW91ciAuN3ogYXJjaGl2ZSBjb250YWlucyB2ZXJ5IGxvbmcgcGF0aHMsIHlvdSBjYW4gcGFzcyB0aGUgcGF0aCB0byA3enIuZXhlIHdoaWNoIHdpbGxcclxuICogZ3JhY2VmdWxseSBoYW5kbGUgbG9uZyBwYXRocy4gQnkgZGVmYXVsdCA3emRlYy5leGUgaXMgdXNlZCBiZWNhdXNlIGl0IGlzIGEgdmVyeSBzbWFsbCBwcm9ncmFtIGFuZCBpc1xyXG4gKiBidW5kbGVkIHdpdGggdGhlIHRvb2wgbGliLiBIb3dldmVyIGl0IGRvZXMgbm90IHN1cHBvcnQgbG9uZyBwYXRocy4gN3pyLmV4ZSBpcyB0aGUgcmVkdWNlZCBjb21tYW5kIGxpbmVcclxuICogaW50ZXJmYWNlLCBpdCBpcyBzbWFsbGVyIHRoYW4gdGhlIGZ1bGwgY29tbWFuZCBsaW5lIGludGVyZmFjZSwgYW5kIGl0IGRvZXMgc3VwcG9ydCBsb25nIHBhdGhzLiBBdCB0aGVcclxuICogdGltZSBvZiB0aGlzIHdyaXRpbmcsIGl0IGlzIGZyZWVseSBhdmFpbGFibGUgZnJvbSB0aGUgTFpNQSBTREsgdGhhdCBpcyBhdmFpbGFibGUgb24gdGhlIDd6aXAgd2Vic2l0ZS5cclxuICogQmUgc3VyZSB0byBjaGVjayB0aGUgY3VycmVudCBsaWNlbnNlIGFncmVlbWVudC4gSWYgN3pyLmV4ZSBpcyBidW5kbGVkIHdpdGggeW91ciB0YXNrLCB0aGVuIHRoZSBwYXRoXHJcbiAqIHRvIDd6ci5leGUgY2FuIGJlIHBhc3MgdG8gdGhpcyBmdW5jdGlvbi5cclxuICogQHJldHVybnMgICAgICAgIHBhdGggdG8gdGhlIGRlc3RpbmF0aW9uIGRpcmVjdG9yeVxyXG4gKi9cclxuZnVuY3Rpb24gZXh0cmFjdDd6KGZpbGUsIGRlc3QsIF83elBhdGgpIHtcclxuICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XHJcbiAgICAgICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gIT0gJ3dpbjMyJykge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4dHJhY3Q3eigpIG5vdCBzdXBwb3J0ZWQgb24gY3VycmVudCBPUycpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWZpbGUpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwicGFyYW1ldGVyICdmaWxlJyBpcyByZXF1aXJlZFwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc29sZS5sb2codGwubG9jKCdUT09MX0xJQl9FeHRyYWN0aW5nQXJjaGl2ZScpKTtcclxuICAgICAgICBkZXN0ID0gX2NyZWF0ZUV4dHJhY3RGb2xkZXIoZGVzdCk7XHJcbiAgICAgICAgbGV0IG9yaWdpbmFsQ3dkID0gcHJvY2Vzcy5jd2QoKTtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBwcm9jZXNzLmNoZGlyKGRlc3QpO1xyXG4gICAgICAgICAgICBpZiAoXzd6UGF0aCkge1xyXG4gICAgICAgICAgICAgICAgLy8gZXh0cmFjdFxyXG4gICAgICAgICAgICAgICAgbGV0IF83eiA9IHRsLnRvb2woXzd6UGF0aClcclxuICAgICAgICAgICAgICAgICAgICAuYXJnKCd4JykgLy8gZVh0cmFjdCBmaWxlcyB3aXRoIGZ1bGwgcGF0aHNcclxuICAgICAgICAgICAgICAgICAgICAuYXJnKCctYmIxJykgLy8gLWJiWzAtM10gOiBzZXQgb3V0cHV0IGxvZyBsZXZlbFxyXG4gICAgICAgICAgICAgICAgICAgIC5hcmcoJy1iZCcpIC8vIGRpc2FibGUgcHJvZ3Jlc3MgaW5kaWNhdG9yXHJcbiAgICAgICAgICAgICAgICAgICAgLmFyZygnLXNjY1VURi04JykgLy8gc2V0IGNoYXJzZXQgZm9yIGZvciBjb25zb2xlIGlucHV0L291dHB1dFxyXG4gICAgICAgICAgICAgICAgICAgIC5hcmcoZmlsZSk7XHJcbiAgICAgICAgICAgICAgICB5aWVsZCBfN3ouZXhlYygpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy8gZXh0cmFjdFxyXG4gICAgICAgICAgICAgICAgbGV0IGVzY2FwZWRTY3JpcHQgPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnSW52b2tlLTd6ZGVjLnBzMScpLnJlcGxhY2UoLycvZywgXCInJ1wiKS5yZXBsYWNlKC9cInxcXG58XFxyL2csICcnKTsgLy8gZG91YmxlLXVwIHNpbmdsZSBxdW90ZXMsIHJlbW92ZSBkb3VibGUgcXVvdGVzIGFuZCBuZXdsaW5lc1xyXG4gICAgICAgICAgICAgICAgbGV0IGVzY2FwZWRGaWxlID0gZmlsZS5yZXBsYWNlKC8nL2csIFwiJydcIikucmVwbGFjZSgvXCJ8XFxufFxcci9nLCAnJyk7XHJcbiAgICAgICAgICAgICAgICBsZXQgZXNjYXBlZFRhcmdldCA9IGRlc3QucmVwbGFjZSgvJy9nLCBcIicnXCIpLnJlcGxhY2UoL1wifFxcbnxcXHIvZywgJycpO1xyXG4gICAgICAgICAgICAgICAgbGV0IGNvbW1hbmQgPSBgJiAnJHtlc2NhcGVkU2NyaXB0fScgLVNvdXJjZSAnJHtlc2NhcGVkRmlsZX0nIC1UYXJnZXQgJyR7ZXNjYXBlZFRhcmdldH0nYDtcclxuICAgICAgICAgICAgICAgIGxldCBwb3dlcnNoZWxsUGF0aCA9IHRsLndoaWNoKCdwb3dlcnNoZWxsJywgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICBsZXQgcG93ZXJzaGVsbCA9IHRsLnRvb2wocG93ZXJzaGVsbFBhdGgpXHJcbiAgICAgICAgICAgICAgICAgICAgLmxpbmUoJy1Ob0xvZ28gLVN0YSAtTm9Qcm9maWxlIC1Ob25JbnRlcmFjdGl2ZSAtRXhlY3V0aW9uUG9saWN5IFVucmVzdHJpY3RlZCAtQ29tbWFuZCcpXHJcbiAgICAgICAgICAgICAgICAgICAgLmFyZyhjb21tYW5kKTtcclxuICAgICAgICAgICAgICAgIHBvd2Vyc2hlbGwub24oJ3N0ZG91dCcsIChidWZmZXIpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShidWZmZXIpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICBwb3dlcnNoZWxsLm9uKCdzdGRlcnInLCAoYnVmZmVyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzcy5zdGRlcnIud3JpdGUoYnVmZmVyKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgeWllbGQgcG93ZXJzaGVsbC5leGVjKHsgc2lsZW50OiB0cnVlIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZpbmFsbHkge1xyXG4gICAgICAgICAgICBwcm9jZXNzLmNoZGlyKG9yaWdpbmFsQ3dkKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGRlc3Q7XHJcbiAgICB9KTtcclxufVxyXG5leHBvcnRzLmV4dHJhY3Q3eiA9IGV4dHJhY3Q3ejtcclxuLyoqXHJcbiAqIGluc3RhbGxzIGEgdG9vbCBmcm9tIGEgdGFyIGJ5IGV4dHJhY3RpbmcgdGhlIHRhciBhbmQgaW5zdGFsbGluZyBpdCBpbnRvIHRoZSB0b29sIGNhY2hlXHJcbiAqXHJcbiAqIEBwYXJhbSBmaWxlICAgICAgZmlsZSBwYXRoIG9mIHRoZSB0YXJcclxuICogQHBhcmFtIHRvb2wgICAgICBuYW1lIG9mIHRvb2wgaW4gdGhlIHRvb2wgY2FjaGVcclxuICogQHBhcmFtIHZlcnNpb24gICB2ZXJzaW9uIG9mIHRoZSB0b29sXHJcbiAqIEBwYXJhbSBhcmNoICAgICAgYXJjaCBvZiB0aGUgdG9vbC4gIG9wdGlvbmFsLiAgZGVmYXVsdHMgdG8gdGhlIGFyY2ggb2YgdGhlIG1hY2hpbmVcclxuICogQHBhcmFtIG9wdGlvbnMgICBJRXh0cmFjdE9wdGlvbnNcclxuICogQHBhcmFtIGRlc3RpbmF0aW9uICAgZGVzdGluYXRpb24gZGlyZWN0b3J5LiBvcHRpb25hbC5cclxuICovXHJcbmZ1bmN0aW9uIGV4dHJhY3RUYXIoZmlsZSwgZGVzdGluYXRpb24pIHtcclxuICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XHJcbiAgICAgICAgLy8gbWtkaXIgLXAgbm9kZS80LjcuMC94NjRcclxuICAgICAgICAvLyB0YXIgeHpDIC4vbm9kZS80LjcuMC94NjQgLWYgbm9kZS12NC43LjAtZGFyd2luLXg2NC50YXIuZ3ogLS1zdHJpcC1jb21wb25lbnRzIDFcclxuICAgICAgICBjb25zb2xlLmxvZyh0bC5sb2MoJ1RPT0xfTElCX0V4dHJhY3RpbmdBcmNoaXZlJykpO1xyXG4gICAgICAgIGxldCBkZXN0ID0gX2NyZWF0ZUV4dHJhY3RGb2xkZXIoZGVzdGluYXRpb24pO1xyXG4gICAgICAgIGxldCB0ciA9IHRsLnRvb2woJ3RhcicpO1xyXG4gICAgICAgIHRyLmFyZyhbJ3hDJywgZGVzdCwgJy1mJywgZmlsZV0pO1xyXG4gICAgICAgIHlpZWxkIHRyLmV4ZWMoKTtcclxuICAgICAgICByZXR1cm4gZGVzdDtcclxuICAgIH0pO1xyXG59XHJcbmV4cG9ydHMuZXh0cmFjdFRhciA9IGV4dHJhY3RUYXI7XHJcbmZ1bmN0aW9uIGV4dHJhY3RaaXAoZmlsZSwgZGVzdGluYXRpb24pIHtcclxuICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XHJcbiAgICAgICAgaWYgKCFmaWxlKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInBhcmFtZXRlciAnZmlsZScgaXMgcmVxdWlyZWRcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnNvbGUubG9nKHRsLmxvYygnVE9PTF9MSUJfRXh0cmFjdGluZ0FyY2hpdmUnKSk7XHJcbiAgICAgICAgbGV0IGRlc3QgPSBfY3JlYXRlRXh0cmFjdEZvbGRlcihkZXN0aW5hdGlvbik7XHJcbiAgICAgICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJykge1xyXG4gICAgICAgICAgICAvLyBidWlsZCB0aGUgcG93ZXJzaGVsbCBjb21tYW5kXHJcbiAgICAgICAgICAgIGxldCBlc2NhcGVkRmlsZSA9IGZpbGUucmVwbGFjZSgvJy9nLCBcIicnXCIpLnJlcGxhY2UoL1wifFxcbnxcXHIvZywgJycpOyAvLyBkb3VibGUtdXAgc2luZ2xlIHF1b3RlcywgcmVtb3ZlIGRvdWJsZSBxdW90ZXMgYW5kIG5ld2xpbmVzXHJcbiAgICAgICAgICAgIGxldCBlc2NhcGVkRGVzdCA9IGRlc3QucmVwbGFjZSgvJy9nLCBcIicnXCIpLnJlcGxhY2UoL1wifFxcbnxcXHIvZywgJycpO1xyXG4gICAgICAgICAgICBsZXQgY29tbWFuZCA9IGAkRXJyb3JBY3Rpb25QcmVmZXJlbmNlID0gJ1N0b3AnIDsgdHJ5IHsgQWRkLVR5cGUgLUFzc2VtYmx5TmFtZSBTeXN0ZW0uSU8uQ29tcHJlc3Npb24uRmlsZVN5c3RlbSB9IGNhdGNoIHsgfSA7IFtTeXN0ZW0uSU8uQ29tcHJlc3Npb24uWmlwRmlsZV06OkV4dHJhY3RUb0RpcmVjdG9yeSgnJHtlc2NhcGVkRmlsZX0nLCAnJHtlc2NhcGVkRGVzdH0nKWA7XHJcbiAgICAgICAgICAgIC8vIGNoYW5nZSB0aGUgY29uc29sZSBvdXRwdXQgY29kZSBwYWdlIHRvIFVURi04LlxyXG4gICAgICAgICAgICAvLyBUT0RPOiBGSVggV0hJQ0g6IGxldCBjaGNwUGF0aCA9IHRsLndoaWNoKCdjaGNwLmNvbScsIHRydWUpO1xyXG4gICAgICAgICAgICBsZXQgY2hjcFBhdGggPSBwYXRoLmpvaW4ocHJvY2Vzcy5lbnYud2luZGlyLCBcInN5c3RlbTMyXCIsIFwiY2hjcC5jb21cIik7XHJcbiAgICAgICAgICAgIHlpZWxkIHRsLmV4ZWMoY2hjcFBhdGgsICc2NTAwMScpO1xyXG4gICAgICAgICAgICAvLyBydW4gcG93ZXJzaGVsbFxyXG4gICAgICAgICAgICBsZXQgcG93ZXJzaGVsbCA9IHRsLnRvb2woJ3Bvd2Vyc2hlbGwnKVxyXG4gICAgICAgICAgICAgICAgLmxpbmUoJy1Ob0xvZ28gLVN0YSAtTm9Qcm9maWxlIC1Ob25JbnRlcmFjdGl2ZSAtRXhlY3V0aW9uUG9saWN5IFVucmVzdHJpY3RlZCAtQ29tbWFuZCcpXHJcbiAgICAgICAgICAgICAgICAuYXJnKGNvbW1hbmQpO1xyXG4gICAgICAgICAgICB5aWVsZCBwb3dlcnNoZWxsLmV4ZWMoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGxldCB1bnppcCA9IHRsLnRvb2woJ3VuemlwJylcclxuICAgICAgICAgICAgICAgIC5hcmcoZmlsZSk7XHJcbiAgICAgICAgICAgIHlpZWxkIHVuemlwLmV4ZWMoeyBjd2Q6IGRlc3QgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBkZXN0O1xyXG4gICAgfSk7XHJcbn1cclxuZXhwb3J0cy5leHRyYWN0WmlwID0gZXh0cmFjdFppcDtcclxuZnVuY3Rpb24gX2NyZWF0ZUV4dHJhY3RGb2xkZXIoZGVzdCkge1xyXG4gICAgaWYgKCFkZXN0KSB7XHJcbiAgICAgICAgLy8gY3JlYXRlIGEgdGVtcCBkaXJcclxuICAgICAgICBkZXN0ID0gcGF0aC5qb2luKF9nZXRBZ2VudFRlbXAoKSwgdXVpZFY0KCkpO1xyXG4gICAgfVxyXG4gICAgdGwubWtkaXJQKGRlc3QpO1xyXG4gICAgcmV0dXJuIGRlc3Q7XHJcbn1cclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gUXVlcnkgRnVuY3Rpb25zXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vICAgICAgIGRlZmF1bHQgaW5wdXQgd2lsbCBiZSA+PSBMVFMgdmVyc2lvbi4gIGRyb3AgbGFiZWwgZGlmZmVyZW50IHRoYW4gdmFsdWUuXHJcbi8vICAgICAgIHY0IChMVFMpIHdvdWxkIGhhdmUgYSB2YWx1ZSBvZiA0LnhcclxuLy8gICAgICAgb3B0aW9uIHRvIGFsd2F5cyBkb3dubG9hZD8gIChub3QgY2FjaGUpLCBUVEw/XHJcbi8qKlxyXG4gKiBTY3JhcGUgYSB3ZWIgcGFnZSBmb3IgdmVyc2lvbnMgYnkgcmVnZXhcclxuICpcclxuICogQHBhcmFtIHVybCAgICAgICB1cmwgdG8gc2NyYXBlXHJcbiAqIEBwYXJhbSByZWdleCAgICAgcmVnZXggdG8gdXNlIGZvciB2ZXJzaW9uIG1hdGNoZXNcclxuICogQHBhcmFtIGhhbmRsZXJzICBvcHRpb25hbCBoYW5kbGVycyBhcnJheS4gIEF1dGggaGFuZGxlcnMgdG8gcGFzcyB0byB0aGUgSHR0cENsaWVudCBmb3IgdGhlIHRvb2wgZG93bmxvYWQuXHJcbiAqL1xyXG5mdW5jdGlvbiBzY3JhcGUodXJsLCByZWdleCwgaGFuZGxlcnMpIHtcclxuICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XHJcbiAgICAgICAgaGFuZGxlcnMgPSBoYW5kbGVycyB8fCBudWxsO1xyXG4gICAgICAgIGxldCBodHRwID0gbmV3IGh0dHBtLkh0dHBDbGllbnQodXNlckFnZW50LCBoYW5kbGVycywgcmVxdWVzdE9wdGlvbnMpO1xyXG4gICAgICAgIGxldCBvdXRwdXQgPSB5aWVsZCAoeWllbGQgaHR0cC5nZXQodXJsKSkucmVhZEJvZHkoKTtcclxuICAgICAgICBsZXQgbWF0Y2hlcyA9IG91dHB1dC5tYXRjaChyZWdleCk7XHJcbiAgICAgICAgbGV0IHNlZW4gPSB7fTtcclxuICAgICAgICBsZXQgdmVyc2lvbnMgPSBbXTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1hdGNoZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IHZlciA9IHNlbXZlci5jbGVhbihtYXRjaGVzW2ldKTtcclxuICAgICAgICAgICAgaWYgKCFzZWVuLmhhc093blByb3BlcnR5KHZlcikpIHtcclxuICAgICAgICAgICAgICAgIHNlZW5bdmVyXSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB2ZXJzaW9ucy5wdXNoKHZlcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHZlcnNpb25zO1xyXG4gICAgfSk7XHJcbn1cclxuZXhwb3J0cy5zY3JhcGUgPSBzY3JhcGU7XHJcbmZ1bmN0aW9uIF9nZXRDYWNoZVJvb3QoKSB7XHJcbiAgICB0bC5hc3NlcnRBZ2VudCgnMi4xMTUuMCcpO1xyXG4gICAgbGV0IGNhY2hlUm9vdCA9IHRsLmdldFZhcmlhYmxlKCdBZ2VudC5Ub29sc0RpcmVjdG9yeScpO1xyXG4gICAgaWYgKCFjYWNoZVJvb3QpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FnZW50LlRvb2xzRGlyZWN0b3J5IGlzIG5vdCBzZXQnKTtcclxuICAgIH1cclxuICAgIHJldHVybiBjYWNoZVJvb3Q7XHJcbn1cclxuZnVuY3Rpb24gX2dldEFnZW50VGVtcCgpIHtcclxuICAgIHRsLmFzc2VydEFnZW50KCcyLjExNS4wJyk7XHJcbiAgICBsZXQgdGVtcERpcmVjdG9yeSA9IHRsLmdldFZhcmlhYmxlKCdBZ2VudC5UZW1wRGlyZWN0b3J5Jyk7XHJcbiAgICBpZiAoIXRlbXBEaXJlY3RvcnkpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FnZW50LlRlbXBEaXJlY3RvcnkgaXMgbm90IHNldCcpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRlbXBEaXJlY3Rvcnk7XHJcbn1cclxuIiwiZnVuY3Rpb24gd2VicGFja0VtcHR5Q29udGV4dChyZXEpIHtcblx0dmFyIGUgPSBuZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiICsgcmVxICsgXCInXCIpO1xuXHRlLmNvZGUgPSAnTU9EVUxFX05PVF9GT1VORCc7XG5cdHRocm93IGU7XG59XG53ZWJwYWNrRW1wdHlDb250ZXh0LmtleXMgPSAoKSA9PiAoW10pO1xud2VicGFja0VtcHR5Q29udGV4dC5yZXNvbHZlID0gd2VicGFja0VtcHR5Q29udGV4dDtcbndlYnBhY2tFbXB0eUNvbnRleHQuaWQgPSBcIi4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10b29sLWxpYiBzeW5jIHJlY3Vyc2l2ZVwiO1xubW9kdWxlLmV4cG9ydHMgPSB3ZWJwYWNrRW1wdHlDb250ZXh0OyIsIid1c2Ugc3RyaWN0Jztcbm1vZHVsZS5leHBvcnRzID0gYmFsYW5jZWQ7XG5mdW5jdGlvbiBiYWxhbmNlZChhLCBiLCBzdHIpIHtcbiAgaWYgKGEgaW5zdGFuY2VvZiBSZWdFeHApIGEgPSBtYXliZU1hdGNoKGEsIHN0cik7XG4gIGlmIChiIGluc3RhbmNlb2YgUmVnRXhwKSBiID0gbWF5YmVNYXRjaChiLCBzdHIpO1xuXG4gIHZhciByID0gcmFuZ2UoYSwgYiwgc3RyKTtcblxuICByZXR1cm4gciAmJiB7XG4gICAgc3RhcnQ6IHJbMF0sXG4gICAgZW5kOiByWzFdLFxuICAgIHByZTogc3RyLnNsaWNlKDAsIHJbMF0pLFxuICAgIGJvZHk6IHN0ci5zbGljZShyWzBdICsgYS5sZW5ndGgsIHJbMV0pLFxuICAgIHBvc3Q6IHN0ci5zbGljZShyWzFdICsgYi5sZW5ndGgpXG4gIH07XG59XG5cbmZ1bmN0aW9uIG1heWJlTWF0Y2gocmVnLCBzdHIpIHtcbiAgdmFyIG0gPSBzdHIubWF0Y2gocmVnKTtcbiAgcmV0dXJuIG0gPyBtWzBdIDogbnVsbDtcbn1cblxuYmFsYW5jZWQucmFuZ2UgPSByYW5nZTtcbmZ1bmN0aW9uIHJhbmdlKGEsIGIsIHN0cikge1xuICB2YXIgYmVncywgYmVnLCBsZWZ0LCByaWdodCwgcmVzdWx0O1xuICB2YXIgYWkgPSBzdHIuaW5kZXhPZihhKTtcbiAgdmFyIGJpID0gc3RyLmluZGV4T2YoYiwgYWkgKyAxKTtcbiAgdmFyIGkgPSBhaTtcblxuICBpZiAoYWkgPj0gMCAmJiBiaSA+IDApIHtcbiAgICBiZWdzID0gW107XG4gICAgbGVmdCA9IHN0ci5sZW5ndGg7XG5cbiAgICB3aGlsZSAoaSA+PSAwICYmICFyZXN1bHQpIHtcbiAgICAgIGlmIChpID09IGFpKSB7XG4gICAgICAgIGJlZ3MucHVzaChpKTtcbiAgICAgICAgYWkgPSBzdHIuaW5kZXhPZihhLCBpICsgMSk7XG4gICAgICB9IGVsc2UgaWYgKGJlZ3MubGVuZ3RoID09IDEpIHtcbiAgICAgICAgcmVzdWx0ID0gWyBiZWdzLnBvcCgpLCBiaSBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYmVnID0gYmVncy5wb3AoKTtcbiAgICAgICAgaWYgKGJlZyA8IGxlZnQpIHtcbiAgICAgICAgICBsZWZ0ID0gYmVnO1xuICAgICAgICAgIHJpZ2h0ID0gYmk7XG4gICAgICAgIH1cblxuICAgICAgICBiaSA9IHN0ci5pbmRleE9mKGIsIGkgKyAxKTtcbiAgICAgIH1cblxuICAgICAgaSA9IGFpIDwgYmkgJiYgYWkgPj0gMCA/IGFpIDogYmk7XG4gICAgfVxuXG4gICAgaWYgKGJlZ3MubGVuZ3RoKSB7XG4gICAgICByZXN1bHQgPSBbIGxlZnQsIHJpZ2h0IF07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbiIsInZhciBjb25jYXRNYXAgPSByZXF1aXJlKCdjb25jYXQtbWFwJyk7XG52YXIgYmFsYW5jZWQgPSByZXF1aXJlKCdiYWxhbmNlZC1tYXRjaCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGV4cGFuZFRvcDtcblxudmFyIGVzY1NsYXNoID0gJ1xcMFNMQVNIJytNYXRoLnJhbmRvbSgpKydcXDAnO1xudmFyIGVzY09wZW4gPSAnXFwwT1BFTicrTWF0aC5yYW5kb20oKSsnXFwwJztcbnZhciBlc2NDbG9zZSA9ICdcXDBDTE9TRScrTWF0aC5yYW5kb20oKSsnXFwwJztcbnZhciBlc2NDb21tYSA9ICdcXDBDT01NQScrTWF0aC5yYW5kb20oKSsnXFwwJztcbnZhciBlc2NQZXJpb2QgPSAnXFwwUEVSSU9EJytNYXRoLnJhbmRvbSgpKydcXDAnO1xuXG5mdW5jdGlvbiBudW1lcmljKHN0cikge1xuICByZXR1cm4gcGFyc2VJbnQoc3RyLCAxMCkgPT0gc3RyXG4gICAgPyBwYXJzZUludChzdHIsIDEwKVxuICAgIDogc3RyLmNoYXJDb2RlQXQoMCk7XG59XG5cbmZ1bmN0aW9uIGVzY2FwZUJyYWNlcyhzdHIpIHtcbiAgcmV0dXJuIHN0ci5zcGxpdCgnXFxcXFxcXFwnKS5qb2luKGVzY1NsYXNoKVxuICAgICAgICAgICAgLnNwbGl0KCdcXFxceycpLmpvaW4oZXNjT3BlbilcbiAgICAgICAgICAgIC5zcGxpdCgnXFxcXH0nKS5qb2luKGVzY0Nsb3NlKVxuICAgICAgICAgICAgLnNwbGl0KCdcXFxcLCcpLmpvaW4oZXNjQ29tbWEpXG4gICAgICAgICAgICAuc3BsaXQoJ1xcXFwuJykuam9pbihlc2NQZXJpb2QpO1xufVxuXG5mdW5jdGlvbiB1bmVzY2FwZUJyYWNlcyhzdHIpIHtcbiAgcmV0dXJuIHN0ci5zcGxpdChlc2NTbGFzaCkuam9pbignXFxcXCcpXG4gICAgICAgICAgICAuc3BsaXQoZXNjT3Blbikuam9pbigneycpXG4gICAgICAgICAgICAuc3BsaXQoZXNjQ2xvc2UpLmpvaW4oJ30nKVxuICAgICAgICAgICAgLnNwbGl0KGVzY0NvbW1hKS5qb2luKCcsJylcbiAgICAgICAgICAgIC5zcGxpdChlc2NQZXJpb2QpLmpvaW4oJy4nKTtcbn1cblxuXG4vLyBCYXNpY2FsbHkganVzdCBzdHIuc3BsaXQoXCIsXCIpLCBidXQgaGFuZGxpbmcgY2FzZXNcbi8vIHdoZXJlIHdlIGhhdmUgbmVzdGVkIGJyYWNlZCBzZWN0aW9ucywgd2hpY2ggc2hvdWxkIGJlXG4vLyB0cmVhdGVkIGFzIGluZGl2aWR1YWwgbWVtYmVycywgbGlrZSB7YSx7YixjfSxkfVxuZnVuY3Rpb24gcGFyc2VDb21tYVBhcnRzKHN0cikge1xuICBpZiAoIXN0cilcbiAgICByZXR1cm4gWycnXTtcblxuICB2YXIgcGFydHMgPSBbXTtcbiAgdmFyIG0gPSBiYWxhbmNlZCgneycsICd9Jywgc3RyKTtcblxuICBpZiAoIW0pXG4gICAgcmV0dXJuIHN0ci5zcGxpdCgnLCcpO1xuXG4gIHZhciBwcmUgPSBtLnByZTtcbiAgdmFyIGJvZHkgPSBtLmJvZHk7XG4gIHZhciBwb3N0ID0gbS5wb3N0O1xuICB2YXIgcCA9IHByZS5zcGxpdCgnLCcpO1xuXG4gIHBbcC5sZW5ndGgtMV0gKz0gJ3snICsgYm9keSArICd9JztcbiAgdmFyIHBvc3RQYXJ0cyA9IHBhcnNlQ29tbWFQYXJ0cyhwb3N0KTtcbiAgaWYgKHBvc3QubGVuZ3RoKSB7XG4gICAgcFtwLmxlbmd0aC0xXSArPSBwb3N0UGFydHMuc2hpZnQoKTtcbiAgICBwLnB1c2guYXBwbHkocCwgcG9zdFBhcnRzKTtcbiAgfVxuXG4gIHBhcnRzLnB1c2guYXBwbHkocGFydHMsIHApO1xuXG4gIHJldHVybiBwYXJ0cztcbn1cblxuZnVuY3Rpb24gZXhwYW5kVG9wKHN0cikge1xuICBpZiAoIXN0cilcbiAgICByZXR1cm4gW107XG5cbiAgLy8gSSBkb24ndCBrbm93IHdoeSBCYXNoIDQuMyBkb2VzIHRoaXMsIGJ1dCBpdCBkb2VzLlxuICAvLyBBbnl0aGluZyBzdGFydGluZyB3aXRoIHt9IHdpbGwgaGF2ZSB0aGUgZmlyc3QgdHdvIGJ5dGVzIHByZXNlcnZlZFxuICAvLyBidXQgKm9ubHkqIGF0IHRoZSB0b3AgbGV2ZWwsIHNvIHt9LGF9YiB3aWxsIG5vdCBleHBhbmQgdG8gYW55dGhpbmcsXG4gIC8vIGJ1dCBhe30sYn1jIHdpbGwgYmUgZXhwYW5kZWQgdG8gW2F9YyxhYmNdLlxuICAvLyBPbmUgY291bGQgYXJndWUgdGhhdCB0aGlzIGlzIGEgYnVnIGluIEJhc2gsIGJ1dCBzaW5jZSB0aGUgZ29hbCBvZlxuICAvLyB0aGlzIG1vZHVsZSBpcyB0byBtYXRjaCBCYXNoJ3MgcnVsZXMsIHdlIGVzY2FwZSBhIGxlYWRpbmcge31cbiAgaWYgKHN0ci5zdWJzdHIoMCwgMikgPT09ICd7fScpIHtcbiAgICBzdHIgPSAnXFxcXHtcXFxcfScgKyBzdHIuc3Vic3RyKDIpO1xuICB9XG5cbiAgcmV0dXJuIGV4cGFuZChlc2NhcGVCcmFjZXMoc3RyKSwgdHJ1ZSkubWFwKHVuZXNjYXBlQnJhY2VzKTtcbn1cblxuZnVuY3Rpb24gaWRlbnRpdHkoZSkge1xuICByZXR1cm4gZTtcbn1cblxuZnVuY3Rpb24gZW1icmFjZShzdHIpIHtcbiAgcmV0dXJuICd7JyArIHN0ciArICd9Jztcbn1cbmZ1bmN0aW9uIGlzUGFkZGVkKGVsKSB7XG4gIHJldHVybiAvXi0/MFxcZC8udGVzdChlbCk7XG59XG5cbmZ1bmN0aW9uIGx0ZShpLCB5KSB7XG4gIHJldHVybiBpIDw9IHk7XG59XG5mdW5jdGlvbiBndGUoaSwgeSkge1xuICByZXR1cm4gaSA+PSB5O1xufVxuXG5mdW5jdGlvbiBleHBhbmQoc3RyLCBpc1RvcCkge1xuICB2YXIgZXhwYW5zaW9ucyA9IFtdO1xuXG4gIHZhciBtID0gYmFsYW5jZWQoJ3snLCAnfScsIHN0cik7XG4gIGlmICghbSB8fCAvXFwkJC8udGVzdChtLnByZSkpIHJldHVybiBbc3RyXTtcblxuICB2YXIgaXNOdW1lcmljU2VxdWVuY2UgPSAvXi0/XFxkK1xcLlxcLi0/XFxkKyg/OlxcLlxcLi0/XFxkKyk/JC8udGVzdChtLmJvZHkpO1xuICB2YXIgaXNBbHBoYVNlcXVlbmNlID0gL15bYS16QS1aXVxcLlxcLlthLXpBLVpdKD86XFwuXFwuLT9cXGQrKT8kLy50ZXN0KG0uYm9keSk7XG4gIHZhciBpc1NlcXVlbmNlID0gaXNOdW1lcmljU2VxdWVuY2UgfHwgaXNBbHBoYVNlcXVlbmNlO1xuICB2YXIgaXNPcHRpb25zID0gbS5ib2R5LmluZGV4T2YoJywnKSA+PSAwO1xuICBpZiAoIWlzU2VxdWVuY2UgJiYgIWlzT3B0aW9ucykge1xuICAgIC8vIHthfSxifVxuICAgIGlmIChtLnBvc3QubWF0Y2goLywuKlxcfS8pKSB7XG4gICAgICBzdHIgPSBtLnByZSArICd7JyArIG0uYm9keSArIGVzY0Nsb3NlICsgbS5wb3N0O1xuICAgICAgcmV0dXJuIGV4cGFuZChzdHIpO1xuICAgIH1cbiAgICByZXR1cm4gW3N0cl07XG4gIH1cblxuICB2YXIgbjtcbiAgaWYgKGlzU2VxdWVuY2UpIHtcbiAgICBuID0gbS5ib2R5LnNwbGl0KC9cXC5cXC4vKTtcbiAgfSBlbHNlIHtcbiAgICBuID0gcGFyc2VDb21tYVBhcnRzKG0uYm9keSk7XG4gICAgaWYgKG4ubGVuZ3RoID09PSAxKSB7XG4gICAgICAvLyB4e3thLGJ9fXkgPT0+IHh7YX15IHh7Yn15XG4gICAgICBuID0gZXhwYW5kKG5bMF0sIGZhbHNlKS5tYXAoZW1icmFjZSk7XG4gICAgICBpZiAobi5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgdmFyIHBvc3QgPSBtLnBvc3QubGVuZ3RoXG4gICAgICAgICAgPyBleHBhbmQobS5wb3N0LCBmYWxzZSlcbiAgICAgICAgICA6IFsnJ107XG4gICAgICAgIHJldHVybiBwb3N0Lm1hcChmdW5jdGlvbihwKSB7XG4gICAgICAgICAgcmV0dXJuIG0ucHJlICsgblswXSArIHA7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIGF0IHRoaXMgcG9pbnQsIG4gaXMgdGhlIHBhcnRzLCBhbmQgd2Uga25vdyBpdCdzIG5vdCBhIGNvbW1hIHNldFxuICAvLyB3aXRoIGEgc2luZ2xlIGVudHJ5LlxuXG4gIC8vIG5vIG5lZWQgdG8gZXhwYW5kIHByZSwgc2luY2UgaXQgaXMgZ3VhcmFudGVlZCB0byBiZSBmcmVlIG9mIGJyYWNlLXNldHNcbiAgdmFyIHByZSA9IG0ucHJlO1xuICB2YXIgcG9zdCA9IG0ucG9zdC5sZW5ndGhcbiAgICA/IGV4cGFuZChtLnBvc3QsIGZhbHNlKVxuICAgIDogWycnXTtcblxuICB2YXIgTjtcblxuICBpZiAoaXNTZXF1ZW5jZSkge1xuICAgIHZhciB4ID0gbnVtZXJpYyhuWzBdKTtcbiAgICB2YXIgeSA9IG51bWVyaWMoblsxXSk7XG4gICAgdmFyIHdpZHRoID0gTWF0aC5tYXgoblswXS5sZW5ndGgsIG5bMV0ubGVuZ3RoKVxuICAgIHZhciBpbmNyID0gbi5sZW5ndGggPT0gM1xuICAgICAgPyBNYXRoLmFicyhudW1lcmljKG5bMl0pKVxuICAgICAgOiAxO1xuICAgIHZhciB0ZXN0ID0gbHRlO1xuICAgIHZhciByZXZlcnNlID0geSA8IHg7XG4gICAgaWYgKHJldmVyc2UpIHtcbiAgICAgIGluY3IgKj0gLTE7XG4gICAgICB0ZXN0ID0gZ3RlO1xuICAgIH1cbiAgICB2YXIgcGFkID0gbi5zb21lKGlzUGFkZGVkKTtcblxuICAgIE4gPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSB4OyB0ZXN0KGksIHkpOyBpICs9IGluY3IpIHtcbiAgICAgIHZhciBjO1xuICAgICAgaWYgKGlzQWxwaGFTZXF1ZW5jZSkge1xuICAgICAgICBjID0gU3RyaW5nLmZyb21DaGFyQ29kZShpKTtcbiAgICAgICAgaWYgKGMgPT09ICdcXFxcJylcbiAgICAgICAgICBjID0gJyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjID0gU3RyaW5nKGkpO1xuICAgICAgICBpZiAocGFkKSB7XG4gICAgICAgICAgdmFyIG5lZWQgPSB3aWR0aCAtIGMubGVuZ3RoO1xuICAgICAgICAgIGlmIChuZWVkID4gMCkge1xuICAgICAgICAgICAgdmFyIHogPSBuZXcgQXJyYXkobmVlZCArIDEpLmpvaW4oJzAnKTtcbiAgICAgICAgICAgIGlmIChpIDwgMClcbiAgICAgICAgICAgICAgYyA9ICctJyArIHogKyBjLnNsaWNlKDEpO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICBjID0geiArIGM7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBOLnB1c2goYyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIE4gPSBjb25jYXRNYXAobiwgZnVuY3Rpb24oZWwpIHsgcmV0dXJuIGV4cGFuZChlbCwgZmFsc2UpIH0pO1xuICB9XG5cbiAgZm9yICh2YXIgaiA9IDA7IGogPCBOLmxlbmd0aDsgaisrKSB7XG4gICAgZm9yICh2YXIgayA9IDA7IGsgPCBwb3N0Lmxlbmd0aDsgaysrKSB7XG4gICAgICB2YXIgZXhwYW5zaW9uID0gcHJlICsgTltqXSArIHBvc3Rba107XG4gICAgICBpZiAoIWlzVG9wIHx8IGlzU2VxdWVuY2UgfHwgZXhwYW5zaW9uKVxuICAgICAgICBleHBhbnNpb25zLnB1c2goZXhwYW5zaW9uKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZXhwYW5zaW9ucztcbn1cblxuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoeHMsIGZuKSB7XG4gICAgdmFyIHJlcyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHggPSBmbih4c1tpXSwgaSk7XG4gICAgICAgIGlmIChpc0FycmF5KHgpKSByZXMucHVzaC5hcHBseShyZXMsIHgpO1xuICAgICAgICBlbHNlIHJlcy5wdXNoKHgpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xufTtcblxudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uICh4cykge1xuICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoeHMpID09PSAnW29iamVjdCBBcnJheV0nO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVhbHBhdGhcbnJlYWxwYXRoLnJlYWxwYXRoID0gcmVhbHBhdGhcbnJlYWxwYXRoLnN5bmMgPSByZWFscGF0aFN5bmNcbnJlYWxwYXRoLnJlYWxwYXRoU3luYyA9IHJlYWxwYXRoU3luY1xucmVhbHBhdGgubW9ua2V5cGF0Y2ggPSBtb25rZXlwYXRjaFxucmVhbHBhdGgudW5tb25rZXlwYXRjaCA9IHVubW9ua2V5cGF0Y2hcblxudmFyIGZzID0gcmVxdWlyZSgnZnMnKVxudmFyIG9yaWdSZWFscGF0aCA9IGZzLnJlYWxwYXRoXG52YXIgb3JpZ1JlYWxwYXRoU3luYyA9IGZzLnJlYWxwYXRoU3luY1xuXG52YXIgdmVyc2lvbiA9IHByb2Nlc3MudmVyc2lvblxudmFyIG9rID0gL152WzAtNV1cXC4vLnRlc3QodmVyc2lvbilcbnZhciBvbGQgPSByZXF1aXJlKCcuL29sZC5qcycpXG5cbmZ1bmN0aW9uIG5ld0Vycm9yIChlcikge1xuICByZXR1cm4gZXIgJiYgZXIuc3lzY2FsbCA9PT0gJ3JlYWxwYXRoJyAmJiAoXG4gICAgZXIuY29kZSA9PT0gJ0VMT09QJyB8fFxuICAgIGVyLmNvZGUgPT09ICdFTk9NRU0nIHx8XG4gICAgZXIuY29kZSA9PT0gJ0VOQU1FVE9PTE9ORydcbiAgKVxufVxuXG5mdW5jdGlvbiByZWFscGF0aCAocCwgY2FjaGUsIGNiKSB7XG4gIGlmIChvaykge1xuICAgIHJldHVybiBvcmlnUmVhbHBhdGgocCwgY2FjaGUsIGNiKVxuICB9XG5cbiAgaWYgKHR5cGVvZiBjYWNoZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gY2FjaGVcbiAgICBjYWNoZSA9IG51bGxcbiAgfVxuICBvcmlnUmVhbHBhdGgocCwgY2FjaGUsIGZ1bmN0aW9uIChlciwgcmVzdWx0KSB7XG4gICAgaWYgKG5ld0Vycm9yKGVyKSkge1xuICAgICAgb2xkLnJlYWxwYXRoKHAsIGNhY2hlLCBjYilcbiAgICB9IGVsc2Uge1xuICAgICAgY2IoZXIsIHJlc3VsdClcbiAgICB9XG4gIH0pXG59XG5cbmZ1bmN0aW9uIHJlYWxwYXRoU3luYyAocCwgY2FjaGUpIHtcbiAgaWYgKG9rKSB7XG4gICAgcmV0dXJuIG9yaWdSZWFscGF0aFN5bmMocCwgY2FjaGUpXG4gIH1cblxuICB0cnkge1xuICAgIHJldHVybiBvcmlnUmVhbHBhdGhTeW5jKHAsIGNhY2hlKVxuICB9IGNhdGNoIChlcikge1xuICAgIGlmIChuZXdFcnJvcihlcikpIHtcbiAgICAgIHJldHVybiBvbGQucmVhbHBhdGhTeW5jKHAsIGNhY2hlKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBlclxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBtb25rZXlwYXRjaCAoKSB7XG4gIGZzLnJlYWxwYXRoID0gcmVhbHBhdGhcbiAgZnMucmVhbHBhdGhTeW5jID0gcmVhbHBhdGhTeW5jXG59XG5cbmZ1bmN0aW9uIHVubW9ua2V5cGF0Y2ggKCkge1xuICBmcy5yZWFscGF0aCA9IG9yaWdSZWFscGF0aFxuICBmcy5yZWFscGF0aFN5bmMgPSBvcmlnUmVhbHBhdGhTeW5jXG59XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIHBhdGhNb2R1bGUgPSByZXF1aXJlKCdwYXRoJyk7XG52YXIgaXNXaW5kb3dzID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJztcbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG5cbi8vIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgcmVhbHBhdGgsIHBvcnRlZCBmcm9tIG5vZGUgcHJlLXY2XG5cbnZhciBERUJVRyA9IHByb2Nlc3MuZW52Lk5PREVfREVCVUcgJiYgL2ZzLy50ZXN0KHByb2Nlc3MuZW52Lk5PREVfREVCVUcpO1xuXG5mdW5jdGlvbiByZXRocm93KCkge1xuICAvLyBPbmx5IGVuYWJsZSBpbiBkZWJ1ZyBtb2RlLiBBIGJhY2t0cmFjZSB1c2VzIH4xMDAwIGJ5dGVzIG9mIGhlYXAgc3BhY2UgYW5kXG4gIC8vIGlzIGZhaXJseSBzbG93IHRvIGdlbmVyYXRlLlxuICB2YXIgY2FsbGJhY2s7XG4gIGlmIChERUJVRykge1xuICAgIHZhciBiYWNrdHJhY2UgPSBuZXcgRXJyb3I7XG4gICAgY2FsbGJhY2sgPSBkZWJ1Z0NhbGxiYWNrO1xuICB9IGVsc2VcbiAgICBjYWxsYmFjayA9IG1pc3NpbmdDYWxsYmFjaztcblxuICByZXR1cm4gY2FsbGJhY2s7XG5cbiAgZnVuY3Rpb24gZGVidWdDYWxsYmFjayhlcnIpIHtcbiAgICBpZiAoZXJyKSB7XG4gICAgICBiYWNrdHJhY2UubWVzc2FnZSA9IGVyci5tZXNzYWdlO1xuICAgICAgZXJyID0gYmFja3RyYWNlO1xuICAgICAgbWlzc2luZ0NhbGxiYWNrKGVycik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gbWlzc2luZ0NhbGxiYWNrKGVycikge1xuICAgIGlmIChlcnIpIHtcbiAgICAgIGlmIChwcm9jZXNzLnRocm93RGVwcmVjYXRpb24pXG4gICAgICAgIHRocm93IGVycjsgIC8vIEZvcmdvdCBhIGNhbGxiYWNrIGJ1dCBkb24ndCBrbm93IHdoZXJlPyBVc2UgTk9ERV9ERUJVRz1mc1xuICAgICAgZWxzZSBpZiAoIXByb2Nlc3Mubm9EZXByZWNhdGlvbikge1xuICAgICAgICB2YXIgbXNnID0gJ2ZzOiBtaXNzaW5nIGNhbGxiYWNrICcgKyAoZXJyLnN0YWNrIHx8IGVyci5tZXNzYWdlKTtcbiAgICAgICAgaWYgKHByb2Nlc3MudHJhY2VEZXByZWNhdGlvbilcbiAgICAgICAgICBjb25zb2xlLnRyYWNlKG1zZyk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBjb25zb2xlLmVycm9yKG1zZyk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG1heWJlQ2FsbGJhY2soY2IpIHtcbiAgcmV0dXJuIHR5cGVvZiBjYiA9PT0gJ2Z1bmN0aW9uJyA/IGNiIDogcmV0aHJvdygpO1xufVxuXG52YXIgbm9ybWFsaXplID0gcGF0aE1vZHVsZS5ub3JtYWxpemU7XG5cbi8vIFJlZ2V4cCB0aGF0IGZpbmRzIHRoZSBuZXh0IHBhcnRpb24gb2YgYSAocGFydGlhbCkgcGF0aFxuLy8gcmVzdWx0IGlzIFtiYXNlX3dpdGhfc2xhc2gsIGJhc2VdLCBlLmcuIFsnc29tZWRpci8nLCAnc29tZWRpciddXG5pZiAoaXNXaW5kb3dzKSB7XG4gIHZhciBuZXh0UGFydFJlID0gLyguKj8pKD86W1xcL1xcXFxdK3wkKS9nO1xufSBlbHNlIHtcbiAgdmFyIG5leHRQYXJ0UmUgPSAvKC4qPykoPzpbXFwvXSt8JCkvZztcbn1cblxuLy8gUmVnZXggdG8gZmluZCB0aGUgZGV2aWNlIHJvb3QsIGluY2x1ZGluZyB0cmFpbGluZyBzbGFzaC4gRS5nLiAnYzpcXFxcJy5cbmlmIChpc1dpbmRvd3MpIHtcbiAgdmFyIHNwbGl0Um9vdFJlID0gL14oPzpbYS16QS1aXTp8W1xcXFxcXC9dezJ9W15cXFxcXFwvXStbXFxcXFxcL11bXlxcXFxcXC9dKyk/W1xcXFxcXC9dKi87XG59IGVsc2Uge1xuICB2YXIgc3BsaXRSb290UmUgPSAvXltcXC9dKi87XG59XG5cbmV4cG9ydHMucmVhbHBhdGhTeW5jID0gZnVuY3Rpb24gcmVhbHBhdGhTeW5jKHAsIGNhY2hlKSB7XG4gIC8vIG1ha2UgcCBpcyBhYnNvbHV0ZVxuICBwID0gcGF0aE1vZHVsZS5yZXNvbHZlKHApO1xuXG4gIGlmIChjYWNoZSAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoY2FjaGUsIHApKSB7XG4gICAgcmV0dXJuIGNhY2hlW3BdO1xuICB9XG5cbiAgdmFyIG9yaWdpbmFsID0gcCxcbiAgICAgIHNlZW5MaW5rcyA9IHt9LFxuICAgICAga25vd25IYXJkID0ge307XG5cbiAgLy8gY3VycmVudCBjaGFyYWN0ZXIgcG9zaXRpb24gaW4gcFxuICB2YXIgcG9zO1xuICAvLyB0aGUgcGFydGlhbCBwYXRoIHNvIGZhciwgaW5jbHVkaW5nIGEgdHJhaWxpbmcgc2xhc2ggaWYgYW55XG4gIHZhciBjdXJyZW50O1xuICAvLyB0aGUgcGFydGlhbCBwYXRoIHdpdGhvdXQgYSB0cmFpbGluZyBzbGFzaCAoZXhjZXB0IHdoZW4gcG9pbnRpbmcgYXQgYSByb290KVxuICB2YXIgYmFzZTtcbiAgLy8gdGhlIHBhcnRpYWwgcGF0aCBzY2FubmVkIGluIHRoZSBwcmV2aW91cyByb3VuZCwgd2l0aCBzbGFzaFxuICB2YXIgcHJldmlvdXM7XG5cbiAgc3RhcnQoKTtcblxuICBmdW5jdGlvbiBzdGFydCgpIHtcbiAgICAvLyBTa2lwIG92ZXIgcm9vdHNcbiAgICB2YXIgbSA9IHNwbGl0Um9vdFJlLmV4ZWMocCk7XG4gICAgcG9zID0gbVswXS5sZW5ndGg7XG4gICAgY3VycmVudCA9IG1bMF07XG4gICAgYmFzZSA9IG1bMF07XG4gICAgcHJldmlvdXMgPSAnJztcblxuICAgIC8vIE9uIHdpbmRvd3MsIGNoZWNrIHRoYXQgdGhlIHJvb3QgZXhpc3RzLiBPbiB1bml4IHRoZXJlIGlzIG5vIG5lZWQuXG4gICAgaWYgKGlzV2luZG93cyAmJiAha25vd25IYXJkW2Jhc2VdKSB7XG4gICAgICBmcy5sc3RhdFN5bmMoYmFzZSk7XG4gICAgICBrbm93bkhhcmRbYmFzZV0gPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8vIHdhbGsgZG93biB0aGUgcGF0aCwgc3dhcHBpbmcgb3V0IGxpbmtlZCBwYXRocGFydHMgZm9yIHRoZWlyIHJlYWxcbiAgLy8gdmFsdWVzXG4gIC8vIE5COiBwLmxlbmd0aCBjaGFuZ2VzLlxuICB3aGlsZSAocG9zIDwgcC5sZW5ndGgpIHtcbiAgICAvLyBmaW5kIHRoZSBuZXh0IHBhcnRcbiAgICBuZXh0UGFydFJlLmxhc3RJbmRleCA9IHBvcztcbiAgICB2YXIgcmVzdWx0ID0gbmV4dFBhcnRSZS5leGVjKHApO1xuICAgIHByZXZpb3VzID0gY3VycmVudDtcbiAgICBjdXJyZW50ICs9IHJlc3VsdFswXTtcbiAgICBiYXNlID0gcHJldmlvdXMgKyByZXN1bHRbMV07XG4gICAgcG9zID0gbmV4dFBhcnRSZS5sYXN0SW5kZXg7XG5cbiAgICAvLyBjb250aW51ZSBpZiBub3QgYSBzeW1saW5rXG4gICAgaWYgKGtub3duSGFyZFtiYXNlXSB8fCAoY2FjaGUgJiYgY2FjaGVbYmFzZV0gPT09IGJhc2UpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICB2YXIgcmVzb2x2ZWRMaW5rO1xuICAgIGlmIChjYWNoZSAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoY2FjaGUsIGJhc2UpKSB7XG4gICAgICAvLyBzb21lIGtub3duIHN5bWJvbGljIGxpbmsuICBubyBuZWVkIHRvIHN0YXQgYWdhaW4uXG4gICAgICByZXNvbHZlZExpbmsgPSBjYWNoZVtiYXNlXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHN0YXQgPSBmcy5sc3RhdFN5bmMoYmFzZSk7XG4gICAgICBpZiAoIXN0YXQuaXNTeW1ib2xpY0xpbmsoKSkge1xuICAgICAgICBrbm93bkhhcmRbYmFzZV0gPSB0cnVlO1xuICAgICAgICBpZiAoY2FjaGUpIGNhY2hlW2Jhc2VdID0gYmFzZTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIHJlYWQgdGhlIGxpbmsgaWYgaXQgd2Fzbid0IHJlYWQgYmVmb3JlXG4gICAgICAvLyBkZXYvaW5vIGFsd2F5cyByZXR1cm4gMCBvbiB3aW5kb3dzLCBzbyBza2lwIHRoZSBjaGVjay5cbiAgICAgIHZhciBsaW5rVGFyZ2V0ID0gbnVsbDtcbiAgICAgIGlmICghaXNXaW5kb3dzKSB7XG4gICAgICAgIHZhciBpZCA9IHN0YXQuZGV2LnRvU3RyaW5nKDMyKSArICc6JyArIHN0YXQuaW5vLnRvU3RyaW5nKDMyKTtcbiAgICAgICAgaWYgKHNlZW5MaW5rcy5oYXNPd25Qcm9wZXJ0eShpZCkpIHtcbiAgICAgICAgICBsaW5rVGFyZ2V0ID0gc2VlbkxpbmtzW2lkXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGxpbmtUYXJnZXQgPT09IG51bGwpIHtcbiAgICAgICAgZnMuc3RhdFN5bmMoYmFzZSk7XG4gICAgICAgIGxpbmtUYXJnZXQgPSBmcy5yZWFkbGlua1N5bmMoYmFzZSk7XG4gICAgICB9XG4gICAgICByZXNvbHZlZExpbmsgPSBwYXRoTW9kdWxlLnJlc29sdmUocHJldmlvdXMsIGxpbmtUYXJnZXQpO1xuICAgICAgLy8gdHJhY2sgdGhpcywgaWYgZ2l2ZW4gYSBjYWNoZS5cbiAgICAgIGlmIChjYWNoZSkgY2FjaGVbYmFzZV0gPSByZXNvbHZlZExpbms7XG4gICAgICBpZiAoIWlzV2luZG93cykgc2VlbkxpbmtzW2lkXSA9IGxpbmtUYXJnZXQ7XG4gICAgfVxuXG4gICAgLy8gcmVzb2x2ZSB0aGUgbGluaywgdGhlbiBzdGFydCBvdmVyXG4gICAgcCA9IHBhdGhNb2R1bGUucmVzb2x2ZShyZXNvbHZlZExpbmssIHAuc2xpY2UocG9zKSk7XG4gICAgc3RhcnQoKTtcbiAgfVxuXG4gIGlmIChjYWNoZSkgY2FjaGVbb3JpZ2luYWxdID0gcDtcblxuICByZXR1cm4gcDtcbn07XG5cblxuZXhwb3J0cy5yZWFscGF0aCA9IGZ1bmN0aW9uIHJlYWxwYXRoKHAsIGNhY2hlLCBjYikge1xuICBpZiAodHlwZW9mIGNiICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBtYXliZUNhbGxiYWNrKGNhY2hlKTtcbiAgICBjYWNoZSA9IG51bGw7XG4gIH1cblxuICAvLyBtYWtlIHAgaXMgYWJzb2x1dGVcbiAgcCA9IHBhdGhNb2R1bGUucmVzb2x2ZShwKTtcblxuICBpZiAoY2FjaGUgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGNhY2hlLCBwKSkge1xuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGNiLmJpbmQobnVsbCwgbnVsbCwgY2FjaGVbcF0pKTtcbiAgfVxuXG4gIHZhciBvcmlnaW5hbCA9IHAsXG4gICAgICBzZWVuTGlua3MgPSB7fSxcbiAgICAgIGtub3duSGFyZCA9IHt9O1xuXG4gIC8vIGN1cnJlbnQgY2hhcmFjdGVyIHBvc2l0aW9uIGluIHBcbiAgdmFyIHBvcztcbiAgLy8gdGhlIHBhcnRpYWwgcGF0aCBzbyBmYXIsIGluY2x1ZGluZyBhIHRyYWlsaW5nIHNsYXNoIGlmIGFueVxuICB2YXIgY3VycmVudDtcbiAgLy8gdGhlIHBhcnRpYWwgcGF0aCB3aXRob3V0IGEgdHJhaWxpbmcgc2xhc2ggKGV4Y2VwdCB3aGVuIHBvaW50aW5nIGF0IGEgcm9vdClcbiAgdmFyIGJhc2U7XG4gIC8vIHRoZSBwYXJ0aWFsIHBhdGggc2Nhbm5lZCBpbiB0aGUgcHJldmlvdXMgcm91bmQsIHdpdGggc2xhc2hcbiAgdmFyIHByZXZpb3VzO1xuXG4gIHN0YXJ0KCk7XG5cbiAgZnVuY3Rpb24gc3RhcnQoKSB7XG4gICAgLy8gU2tpcCBvdmVyIHJvb3RzXG4gICAgdmFyIG0gPSBzcGxpdFJvb3RSZS5leGVjKHApO1xuICAgIHBvcyA9IG1bMF0ubGVuZ3RoO1xuICAgIGN1cnJlbnQgPSBtWzBdO1xuICAgIGJhc2UgPSBtWzBdO1xuICAgIHByZXZpb3VzID0gJyc7XG5cbiAgICAvLyBPbiB3aW5kb3dzLCBjaGVjayB0aGF0IHRoZSByb290IGV4aXN0cy4gT24gdW5peCB0aGVyZSBpcyBubyBuZWVkLlxuICAgIGlmIChpc1dpbmRvd3MgJiYgIWtub3duSGFyZFtiYXNlXSkge1xuICAgICAgZnMubHN0YXQoYmFzZSwgZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgIGlmIChlcnIpIHJldHVybiBjYihlcnIpO1xuICAgICAgICBrbm93bkhhcmRbYmFzZV0gPSB0cnVlO1xuICAgICAgICBMT09QKCk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhMT09QKTtcbiAgICB9XG4gIH1cblxuICAvLyB3YWxrIGRvd24gdGhlIHBhdGgsIHN3YXBwaW5nIG91dCBsaW5rZWQgcGF0aHBhcnRzIGZvciB0aGVpciByZWFsXG4gIC8vIHZhbHVlc1xuICBmdW5jdGlvbiBMT09QKCkge1xuICAgIC8vIHN0b3AgaWYgc2Nhbm5lZCBwYXN0IGVuZCBvZiBwYXRoXG4gICAgaWYgKHBvcyA+PSBwLmxlbmd0aCkge1xuICAgICAgaWYgKGNhY2hlKSBjYWNoZVtvcmlnaW5hbF0gPSBwO1xuICAgICAgcmV0dXJuIGNiKG51bGwsIHApO1xuICAgIH1cblxuICAgIC8vIGZpbmQgdGhlIG5leHQgcGFydFxuICAgIG5leHRQYXJ0UmUubGFzdEluZGV4ID0gcG9zO1xuICAgIHZhciByZXN1bHQgPSBuZXh0UGFydFJlLmV4ZWMocCk7XG4gICAgcHJldmlvdXMgPSBjdXJyZW50O1xuICAgIGN1cnJlbnQgKz0gcmVzdWx0WzBdO1xuICAgIGJhc2UgPSBwcmV2aW91cyArIHJlc3VsdFsxXTtcbiAgICBwb3MgPSBuZXh0UGFydFJlLmxhc3RJbmRleDtcblxuICAgIC8vIGNvbnRpbnVlIGlmIG5vdCBhIHN5bWxpbmtcbiAgICBpZiAoa25vd25IYXJkW2Jhc2VdIHx8IChjYWNoZSAmJiBjYWNoZVtiYXNlXSA9PT0gYmFzZSkpIHtcbiAgICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKExPT1ApO1xuICAgIH1cblxuICAgIGlmIChjYWNoZSAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoY2FjaGUsIGJhc2UpKSB7XG4gICAgICAvLyBrbm93biBzeW1ib2xpYyBsaW5rLiAgbm8gbmVlZCB0byBzdGF0IGFnYWluLlxuICAgICAgcmV0dXJuIGdvdFJlc29sdmVkTGluayhjYWNoZVtiYXNlXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZzLmxzdGF0KGJhc2UsIGdvdFN0YXQpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ290U3RhdChlcnIsIHN0YXQpIHtcbiAgICBpZiAoZXJyKSByZXR1cm4gY2IoZXJyKTtcblxuICAgIC8vIGlmIG5vdCBhIHN5bWxpbmssIHNraXAgdG8gdGhlIG5leHQgcGF0aCBwYXJ0XG4gICAgaWYgKCFzdGF0LmlzU3ltYm9saWNMaW5rKCkpIHtcbiAgICAgIGtub3duSGFyZFtiYXNlXSA9IHRydWU7XG4gICAgICBpZiAoY2FjaGUpIGNhY2hlW2Jhc2VdID0gYmFzZTtcbiAgICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKExPT1ApO1xuICAgIH1cblxuICAgIC8vIHN0YXQgJiByZWFkIHRoZSBsaW5rIGlmIG5vdCByZWFkIGJlZm9yZVxuICAgIC8vIGNhbGwgZ290VGFyZ2V0IGFzIHNvb24gYXMgdGhlIGxpbmsgdGFyZ2V0IGlzIGtub3duXG4gICAgLy8gZGV2L2lubyBhbHdheXMgcmV0dXJuIDAgb24gd2luZG93cywgc28gc2tpcCB0aGUgY2hlY2suXG4gICAgaWYgKCFpc1dpbmRvd3MpIHtcbiAgICAgIHZhciBpZCA9IHN0YXQuZGV2LnRvU3RyaW5nKDMyKSArICc6JyArIHN0YXQuaW5vLnRvU3RyaW5nKDMyKTtcbiAgICAgIGlmIChzZWVuTGlua3MuaGFzT3duUHJvcGVydHkoaWQpKSB7XG4gICAgICAgIHJldHVybiBnb3RUYXJnZXQobnVsbCwgc2VlbkxpbmtzW2lkXSwgYmFzZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGZzLnN0YXQoYmFzZSwgZnVuY3Rpb24oZXJyKSB7XG4gICAgICBpZiAoZXJyKSByZXR1cm4gY2IoZXJyKTtcblxuICAgICAgZnMucmVhZGxpbmsoYmFzZSwgZnVuY3Rpb24oZXJyLCB0YXJnZXQpIHtcbiAgICAgICAgaWYgKCFpc1dpbmRvd3MpIHNlZW5MaW5rc1tpZF0gPSB0YXJnZXQ7XG4gICAgICAgIGdvdFRhcmdldChlcnIsIHRhcmdldCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdvdFRhcmdldChlcnIsIHRhcmdldCwgYmFzZSkge1xuICAgIGlmIChlcnIpIHJldHVybiBjYihlcnIpO1xuXG4gICAgdmFyIHJlc29sdmVkTGluayA9IHBhdGhNb2R1bGUucmVzb2x2ZShwcmV2aW91cywgdGFyZ2V0KTtcbiAgICBpZiAoY2FjaGUpIGNhY2hlW2Jhc2VdID0gcmVzb2x2ZWRMaW5rO1xuICAgIGdvdFJlc29sdmVkTGluayhyZXNvbHZlZExpbmspO1xuICB9XG5cbiAgZnVuY3Rpb24gZ290UmVzb2x2ZWRMaW5rKHJlc29sdmVkTGluaykge1xuICAgIC8vIHJlc29sdmUgdGhlIGxpbmssIHRoZW4gc3RhcnQgb3ZlclxuICAgIHAgPSBwYXRoTW9kdWxlLnJlc29sdmUocmVzb2x2ZWRMaW5rLCBwLnNsaWNlKHBvcykpO1xuICAgIHN0YXJ0KCk7XG4gIH1cbn07XG4iLCJleHBvcnRzLmFscGhhc29ydCA9IGFscGhhc29ydFxuZXhwb3J0cy5hbHBoYXNvcnRpID0gYWxwaGFzb3J0aVxuZXhwb3J0cy5zZXRvcHRzID0gc2V0b3B0c1xuZXhwb3J0cy5vd25Qcm9wID0gb3duUHJvcFxuZXhwb3J0cy5tYWtlQWJzID0gbWFrZUFic1xuZXhwb3J0cy5maW5pc2ggPSBmaW5pc2hcbmV4cG9ydHMubWFyayA9IG1hcmtcbmV4cG9ydHMuaXNJZ25vcmVkID0gaXNJZ25vcmVkXG5leHBvcnRzLmNoaWxkcmVuSWdub3JlZCA9IGNoaWxkcmVuSWdub3JlZFxuXG5mdW5jdGlvbiBvd25Qcm9wIChvYmosIGZpZWxkKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBmaWVsZClcbn1cblxudmFyIHBhdGggPSByZXF1aXJlKFwicGF0aFwiKVxudmFyIG1pbmltYXRjaCA9IHJlcXVpcmUoXCJtaW5pbWF0Y2hcIilcbnZhciBpc0Fic29sdXRlID0gcmVxdWlyZShcInBhdGgtaXMtYWJzb2x1dGVcIilcbnZhciBNaW5pbWF0Y2ggPSBtaW5pbWF0Y2guTWluaW1hdGNoXG5cbmZ1bmN0aW9uIGFscGhhc29ydGkgKGEsIGIpIHtcbiAgcmV0dXJuIGEudG9Mb3dlckNhc2UoKS5sb2NhbGVDb21wYXJlKGIudG9Mb3dlckNhc2UoKSlcbn1cblxuZnVuY3Rpb24gYWxwaGFzb3J0IChhLCBiKSB7XG4gIHJldHVybiBhLmxvY2FsZUNvbXBhcmUoYilcbn1cblxuZnVuY3Rpb24gc2V0dXBJZ25vcmVzIChzZWxmLCBvcHRpb25zKSB7XG4gIHNlbGYuaWdub3JlID0gb3B0aW9ucy5pZ25vcmUgfHwgW11cblxuICBpZiAoIUFycmF5LmlzQXJyYXkoc2VsZi5pZ25vcmUpKVxuICAgIHNlbGYuaWdub3JlID0gW3NlbGYuaWdub3JlXVxuXG4gIGlmIChzZWxmLmlnbm9yZS5sZW5ndGgpIHtcbiAgICBzZWxmLmlnbm9yZSA9IHNlbGYuaWdub3JlLm1hcChpZ25vcmVNYXApXG4gIH1cbn1cblxuLy8gaWdub3JlIHBhdHRlcm5zIGFyZSBhbHdheXMgaW4gZG90OnRydWUgbW9kZS5cbmZ1bmN0aW9uIGlnbm9yZU1hcCAocGF0dGVybikge1xuICB2YXIgZ21hdGNoZXIgPSBudWxsXG4gIGlmIChwYXR0ZXJuLnNsaWNlKC0zKSA9PT0gJy8qKicpIHtcbiAgICB2YXIgZ3BhdHRlcm4gPSBwYXR0ZXJuLnJlcGxhY2UoLyhcXC9cXCpcXCopKyQvLCAnJylcbiAgICBnbWF0Y2hlciA9IG5ldyBNaW5pbWF0Y2goZ3BhdHRlcm4sIHsgZG90OiB0cnVlIH0pXG4gIH1cblxuICByZXR1cm4ge1xuICAgIG1hdGNoZXI6IG5ldyBNaW5pbWF0Y2gocGF0dGVybiwgeyBkb3Q6IHRydWUgfSksXG4gICAgZ21hdGNoZXI6IGdtYXRjaGVyXG4gIH1cbn1cblxuZnVuY3Rpb24gc2V0b3B0cyAoc2VsZiwgcGF0dGVybiwgb3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMpXG4gICAgb3B0aW9ucyA9IHt9XG5cbiAgLy8gYmFzZS1tYXRjaGluZzoganVzdCB1c2UgZ2xvYnN0YXIgZm9yIHRoYXQuXG4gIGlmIChvcHRpb25zLm1hdGNoQmFzZSAmJiAtMSA9PT0gcGF0dGVybi5pbmRleE9mKFwiL1wiKSkge1xuICAgIGlmIChvcHRpb25zLm5vZ2xvYnN0YXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImJhc2UgbWF0Y2hpbmcgcmVxdWlyZXMgZ2xvYnN0YXJcIilcbiAgICB9XG4gICAgcGF0dGVybiA9IFwiKiovXCIgKyBwYXR0ZXJuXG4gIH1cblxuICBzZWxmLnNpbGVudCA9ICEhb3B0aW9ucy5zaWxlbnRcbiAgc2VsZi5wYXR0ZXJuID0gcGF0dGVyblxuICBzZWxmLnN0cmljdCA9IG9wdGlvbnMuc3RyaWN0ICE9PSBmYWxzZVxuICBzZWxmLnJlYWxwYXRoID0gISFvcHRpb25zLnJlYWxwYXRoXG4gIHNlbGYucmVhbHBhdGhDYWNoZSA9IG9wdGlvbnMucmVhbHBhdGhDYWNoZSB8fCBPYmplY3QuY3JlYXRlKG51bGwpXG4gIHNlbGYuZm9sbG93ID0gISFvcHRpb25zLmZvbGxvd1xuICBzZWxmLmRvdCA9ICEhb3B0aW9ucy5kb3RcbiAgc2VsZi5tYXJrID0gISFvcHRpb25zLm1hcmtcbiAgc2VsZi5ub2RpciA9ICEhb3B0aW9ucy5ub2RpclxuICBpZiAoc2VsZi5ub2RpcilcbiAgICBzZWxmLm1hcmsgPSB0cnVlXG4gIHNlbGYuc3luYyA9ICEhb3B0aW9ucy5zeW5jXG4gIHNlbGYubm91bmlxdWUgPSAhIW9wdGlvbnMubm91bmlxdWVcbiAgc2VsZi5ub251bGwgPSAhIW9wdGlvbnMubm9udWxsXG4gIHNlbGYubm9zb3J0ID0gISFvcHRpb25zLm5vc29ydFxuICBzZWxmLm5vY2FzZSA9ICEhb3B0aW9ucy5ub2Nhc2VcbiAgc2VsZi5zdGF0ID0gISFvcHRpb25zLnN0YXRcbiAgc2VsZi5ub3Byb2Nlc3MgPSAhIW9wdGlvbnMubm9wcm9jZXNzXG4gIHNlbGYuYWJzb2x1dGUgPSAhIW9wdGlvbnMuYWJzb2x1dGVcblxuICBzZWxmLm1heExlbmd0aCA9IG9wdGlvbnMubWF4TGVuZ3RoIHx8IEluZmluaXR5XG4gIHNlbGYuY2FjaGUgPSBvcHRpb25zLmNhY2hlIHx8IE9iamVjdC5jcmVhdGUobnVsbClcbiAgc2VsZi5zdGF0Q2FjaGUgPSBvcHRpb25zLnN0YXRDYWNoZSB8fCBPYmplY3QuY3JlYXRlKG51bGwpXG4gIHNlbGYuc3ltbGlua3MgPSBvcHRpb25zLnN5bWxpbmtzIHx8IE9iamVjdC5jcmVhdGUobnVsbClcblxuICBzZXR1cElnbm9yZXMoc2VsZiwgb3B0aW9ucylcblxuICBzZWxmLmNoYW5nZWRDd2QgPSBmYWxzZVxuICB2YXIgY3dkID0gcHJvY2Vzcy5jd2QoKVxuICBpZiAoIW93blByb3Aob3B0aW9ucywgXCJjd2RcIikpXG4gICAgc2VsZi5jd2QgPSBjd2RcbiAgZWxzZSB7XG4gICAgc2VsZi5jd2QgPSBwYXRoLnJlc29sdmUob3B0aW9ucy5jd2QpXG4gICAgc2VsZi5jaGFuZ2VkQ3dkID0gc2VsZi5jd2QgIT09IGN3ZFxuICB9XG5cbiAgc2VsZi5yb290ID0gb3B0aW9ucy5yb290IHx8IHBhdGgucmVzb2x2ZShzZWxmLmN3ZCwgXCIvXCIpXG4gIHNlbGYucm9vdCA9IHBhdGgucmVzb2x2ZShzZWxmLnJvb3QpXG4gIGlmIChwcm9jZXNzLnBsYXRmb3JtID09PSBcIndpbjMyXCIpXG4gICAgc2VsZi5yb290ID0gc2VsZi5yb290LnJlcGxhY2UoL1xcXFwvZywgXCIvXCIpXG5cbiAgLy8gVE9ETzogaXMgYW4gYWJzb2x1dGUgYGN3ZGAgc3VwcG9zZWQgdG8gYmUgcmVzb2x2ZWQgYWdhaW5zdCBgcm9vdGA/XG4gIC8vIGUuZy4geyBjd2Q6ICcvdGVzdCcsIHJvb3Q6IF9fZGlybmFtZSB9ID09PSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnL3Rlc3QnKVxuICBzZWxmLmN3ZEFicyA9IGlzQWJzb2x1dGUoc2VsZi5jd2QpID8gc2VsZi5jd2QgOiBtYWtlQWJzKHNlbGYsIHNlbGYuY3dkKVxuICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PT0gXCJ3aW4zMlwiKVxuICAgIHNlbGYuY3dkQWJzID0gc2VsZi5jd2RBYnMucmVwbGFjZSgvXFxcXC9nLCBcIi9cIilcbiAgc2VsZi5ub21vdW50ID0gISFvcHRpb25zLm5vbW91bnRcblxuICAvLyBkaXNhYmxlIGNvbW1lbnRzIGFuZCBuZWdhdGlvbiBpbiBNaW5pbWF0Y2guXG4gIC8vIE5vdGUgdGhhdCB0aGV5IGFyZSBub3Qgc3VwcG9ydGVkIGluIEdsb2IgaXRzZWxmIGFueXdheS5cbiAgb3B0aW9ucy5ub25lZ2F0ZSA9IHRydWVcbiAgb3B0aW9ucy5ub2NvbW1lbnQgPSB0cnVlXG5cbiAgc2VsZi5taW5pbWF0Y2ggPSBuZXcgTWluaW1hdGNoKHBhdHRlcm4sIG9wdGlvbnMpXG4gIHNlbGYub3B0aW9ucyA9IHNlbGYubWluaW1hdGNoLm9wdGlvbnNcbn1cblxuZnVuY3Rpb24gZmluaXNoIChzZWxmKSB7XG4gIHZhciBub3UgPSBzZWxmLm5vdW5pcXVlXG4gIHZhciBhbGwgPSBub3UgPyBbXSA6IE9iamVjdC5jcmVhdGUobnVsbClcblxuICBmb3IgKHZhciBpID0gMCwgbCA9IHNlbGYubWF0Y2hlcy5sZW5ndGg7IGkgPCBsOyBpICsrKSB7XG4gICAgdmFyIG1hdGNoZXMgPSBzZWxmLm1hdGNoZXNbaV1cbiAgICBpZiAoIW1hdGNoZXMgfHwgT2JqZWN0LmtleXMobWF0Y2hlcykubGVuZ3RoID09PSAwKSB7XG4gICAgICBpZiAoc2VsZi5ub251bGwpIHtcbiAgICAgICAgLy8gZG8gbGlrZSB0aGUgc2hlbGwsIGFuZCBzcGl0IG91dCB0aGUgbGl0ZXJhbCBnbG9iXG4gICAgICAgIHZhciBsaXRlcmFsID0gc2VsZi5taW5pbWF0Y2guZ2xvYlNldFtpXVxuICAgICAgICBpZiAobm91KVxuICAgICAgICAgIGFsbC5wdXNoKGxpdGVyYWwpXG4gICAgICAgIGVsc2VcbiAgICAgICAgICBhbGxbbGl0ZXJhbF0gPSB0cnVlXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGhhZCBtYXRjaGVzXG4gICAgICB2YXIgbSA9IE9iamVjdC5rZXlzKG1hdGNoZXMpXG4gICAgICBpZiAobm91KVxuICAgICAgICBhbGwucHVzaC5hcHBseShhbGwsIG0pXG4gICAgICBlbHNlXG4gICAgICAgIG0uZm9yRWFjaChmdW5jdGlvbiAobSkge1xuICAgICAgICAgIGFsbFttXSA9IHRydWVcbiAgICAgICAgfSlcbiAgICB9XG4gIH1cblxuICBpZiAoIW5vdSlcbiAgICBhbGwgPSBPYmplY3Qua2V5cyhhbGwpXG5cbiAgaWYgKCFzZWxmLm5vc29ydClcbiAgICBhbGwgPSBhbGwuc29ydChzZWxmLm5vY2FzZSA/IGFscGhhc29ydGkgOiBhbHBoYXNvcnQpXG5cbiAgLy8gYXQgKnNvbWUqIHBvaW50IHdlIHN0YXR0ZWQgYWxsIG9mIHRoZXNlXG4gIGlmIChzZWxmLm1hcmspIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFsbC5sZW5ndGg7IGkrKykge1xuICAgICAgYWxsW2ldID0gc2VsZi5fbWFyayhhbGxbaV0pXG4gICAgfVxuICAgIGlmIChzZWxmLm5vZGlyKSB7XG4gICAgICBhbGwgPSBhbGwuZmlsdGVyKGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHZhciBub3REaXIgPSAhKC9cXC8kLy50ZXN0KGUpKVxuICAgICAgICB2YXIgYyA9IHNlbGYuY2FjaGVbZV0gfHwgc2VsZi5jYWNoZVttYWtlQWJzKHNlbGYsIGUpXVxuICAgICAgICBpZiAobm90RGlyICYmIGMpXG4gICAgICAgICAgbm90RGlyID0gYyAhPT0gJ0RJUicgJiYgIUFycmF5LmlzQXJyYXkoYylcbiAgICAgICAgcmV0dXJuIG5vdERpclxuICAgICAgfSlcbiAgICB9XG4gIH1cblxuICBpZiAoc2VsZi5pZ25vcmUubGVuZ3RoKVxuICAgIGFsbCA9IGFsbC5maWx0ZXIoZnVuY3Rpb24obSkge1xuICAgICAgcmV0dXJuICFpc0lnbm9yZWQoc2VsZiwgbSlcbiAgICB9KVxuXG4gIHNlbGYuZm91bmQgPSBhbGxcbn1cblxuZnVuY3Rpb24gbWFyayAoc2VsZiwgcCkge1xuICB2YXIgYWJzID0gbWFrZUFicyhzZWxmLCBwKVxuICB2YXIgYyA9IHNlbGYuY2FjaGVbYWJzXVxuICB2YXIgbSA9IHBcbiAgaWYgKGMpIHtcbiAgICB2YXIgaXNEaXIgPSBjID09PSAnRElSJyB8fCBBcnJheS5pc0FycmF5KGMpXG4gICAgdmFyIHNsYXNoID0gcC5zbGljZSgtMSkgPT09ICcvJ1xuXG4gICAgaWYgKGlzRGlyICYmICFzbGFzaClcbiAgICAgIG0gKz0gJy8nXG4gICAgZWxzZSBpZiAoIWlzRGlyICYmIHNsYXNoKVxuICAgICAgbSA9IG0uc2xpY2UoMCwgLTEpXG5cbiAgICBpZiAobSAhPT0gcCkge1xuICAgICAgdmFyIG1hYnMgPSBtYWtlQWJzKHNlbGYsIG0pXG4gICAgICBzZWxmLnN0YXRDYWNoZVttYWJzXSA9IHNlbGYuc3RhdENhY2hlW2Fic11cbiAgICAgIHNlbGYuY2FjaGVbbWFic10gPSBzZWxmLmNhY2hlW2Fic11cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbVxufVxuXG4vLyBsb3R0YSBzaXR1cHMuLi5cbmZ1bmN0aW9uIG1ha2VBYnMgKHNlbGYsIGYpIHtcbiAgdmFyIGFicyA9IGZcbiAgaWYgKGYuY2hhckF0KDApID09PSAnLycpIHtcbiAgICBhYnMgPSBwYXRoLmpvaW4oc2VsZi5yb290LCBmKVxuICB9IGVsc2UgaWYgKGlzQWJzb2x1dGUoZikgfHwgZiA9PT0gJycpIHtcbiAgICBhYnMgPSBmXG4gIH0gZWxzZSBpZiAoc2VsZi5jaGFuZ2VkQ3dkKSB7XG4gICAgYWJzID0gcGF0aC5yZXNvbHZlKHNlbGYuY3dkLCBmKVxuICB9IGVsc2Uge1xuICAgIGFicyA9IHBhdGgucmVzb2x2ZShmKVxuICB9XG5cbiAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT09ICd3aW4zMicpXG4gICAgYWJzID0gYWJzLnJlcGxhY2UoL1xcXFwvZywgJy8nKVxuXG4gIHJldHVybiBhYnNcbn1cblxuXG4vLyBSZXR1cm4gdHJ1ZSwgaWYgcGF0dGVybiBlbmRzIHdpdGggZ2xvYnN0YXIgJyoqJywgZm9yIHRoZSBhY2NvbXBhbnlpbmcgcGFyZW50IGRpcmVjdG9yeS5cbi8vIEV4Oi0gSWYgbm9kZV9tb2R1bGVzLyoqIGlzIHRoZSBwYXR0ZXJuLCBhZGQgJ25vZGVfbW9kdWxlcycgdG8gaWdub3JlIGxpc3QgYWxvbmcgd2l0aCBpdCdzIGNvbnRlbnRzXG5mdW5jdGlvbiBpc0lnbm9yZWQgKHNlbGYsIHBhdGgpIHtcbiAgaWYgKCFzZWxmLmlnbm9yZS5sZW5ndGgpXG4gICAgcmV0dXJuIGZhbHNlXG5cbiAgcmV0dXJuIHNlbGYuaWdub3JlLnNvbWUoZnVuY3Rpb24oaXRlbSkge1xuICAgIHJldHVybiBpdGVtLm1hdGNoZXIubWF0Y2gocGF0aCkgfHwgISEoaXRlbS5nbWF0Y2hlciAmJiBpdGVtLmdtYXRjaGVyLm1hdGNoKHBhdGgpKVxuICB9KVxufVxuXG5mdW5jdGlvbiBjaGlsZHJlbklnbm9yZWQgKHNlbGYsIHBhdGgpIHtcbiAgaWYgKCFzZWxmLmlnbm9yZS5sZW5ndGgpXG4gICAgcmV0dXJuIGZhbHNlXG5cbiAgcmV0dXJuIHNlbGYuaWdub3JlLnNvbWUoZnVuY3Rpb24oaXRlbSkge1xuICAgIHJldHVybiAhIShpdGVtLmdtYXRjaGVyICYmIGl0ZW0uZ21hdGNoZXIubWF0Y2gocGF0aCkpXG4gIH0pXG59XG4iLCIvLyBBcHByb2FjaDpcbi8vXG4vLyAxLiBHZXQgdGhlIG1pbmltYXRjaCBzZXRcbi8vIDIuIEZvciBlYWNoIHBhdHRlcm4gaW4gdGhlIHNldCwgUFJPQ0VTUyhwYXR0ZXJuLCBmYWxzZSlcbi8vIDMuIFN0b3JlIG1hdGNoZXMgcGVyLXNldCwgdGhlbiB1bmlxIHRoZW1cbi8vXG4vLyBQUk9DRVNTKHBhdHRlcm4sIGluR2xvYlN0YXIpXG4vLyBHZXQgdGhlIGZpcnN0IFtuXSBpdGVtcyBmcm9tIHBhdHRlcm4gdGhhdCBhcmUgYWxsIHN0cmluZ3Ncbi8vIEpvaW4gdGhlc2UgdG9nZXRoZXIuICBUaGlzIGlzIFBSRUZJWC5cbi8vICAgSWYgdGhlcmUgaXMgbm8gbW9yZSByZW1haW5pbmcsIHRoZW4gc3RhdChQUkVGSVgpIGFuZFxuLy8gICBhZGQgdG8gbWF0Y2hlcyBpZiBpdCBzdWNjZWVkcy4gIEVORC5cbi8vXG4vLyBJZiBpbkdsb2JTdGFyIGFuZCBQUkVGSVggaXMgc3ltbGluayBhbmQgcG9pbnRzIHRvIGRpclxuLy8gICBzZXQgRU5UUklFUyA9IFtdXG4vLyBlbHNlIHJlYWRkaXIoUFJFRklYKSBhcyBFTlRSSUVTXG4vLyAgIElmIGZhaWwsIEVORFxuLy9cbi8vIHdpdGggRU5UUklFU1xuLy8gICBJZiBwYXR0ZXJuW25dIGlzIEdMT0JTVEFSXG4vLyAgICAgLy8gaGFuZGxlIHRoZSBjYXNlIHdoZXJlIHRoZSBnbG9ic3RhciBtYXRjaCBpcyBlbXB0eVxuLy8gICAgIC8vIGJ5IHBydW5pbmcgaXQgb3V0LCBhbmQgdGVzdGluZyB0aGUgcmVzdWx0aW5nIHBhdHRlcm5cbi8vICAgICBQUk9DRVNTKHBhdHRlcm5bMC4ubl0gKyBwYXR0ZXJuW24rMSAuLiAkXSwgZmFsc2UpXG4vLyAgICAgLy8gaGFuZGxlIG90aGVyIGNhc2VzLlxuLy8gICAgIGZvciBFTlRSWSBpbiBFTlRSSUVTIChub3QgZG90ZmlsZXMpXG4vLyAgICAgICAvLyBhdHRhY2ggZ2xvYnN0YXIgKyB0YWlsIG9udG8gdGhlIGVudHJ5XG4vLyAgICAgICAvLyBNYXJrIHRoYXQgdGhpcyBlbnRyeSBpcyBhIGdsb2JzdGFyIG1hdGNoXG4vLyAgICAgICBQUk9DRVNTKHBhdHRlcm5bMC4ubl0gKyBFTlRSWSArIHBhdHRlcm5bbiAuLiAkXSwgdHJ1ZSlcbi8vXG4vLyAgIGVsc2UgLy8gbm90IGdsb2JzdGFyXG4vLyAgICAgZm9yIEVOVFJZIGluIEVOVFJJRVMgKG5vdCBkb3RmaWxlcywgdW5sZXNzIHBhdHRlcm5bbl0gaXMgZG90KVxuLy8gICAgICAgVGVzdCBFTlRSWSBhZ2FpbnN0IHBhdHRlcm5bbl1cbi8vICAgICAgIElmIGZhaWxzLCBjb250aW51ZVxuLy8gICAgICAgSWYgcGFzc2VzLCBQUk9DRVNTKHBhdHRlcm5bMC4ubl0gKyBpdGVtICsgcGF0dGVybltuKzEgLi4gJF0pXG4vL1xuLy8gQ2F2ZWF0OlxuLy8gICBDYWNoZSBhbGwgc3RhdHMgYW5kIHJlYWRkaXJzIHJlc3VsdHMgdG8gbWluaW1pemUgc3lzY2FsbC4gIFNpbmNlIGFsbFxuLy8gICB3ZSBldmVyIGNhcmUgYWJvdXQgaXMgZXhpc3RlbmNlIGFuZCBkaXJlY3RvcnktbmVzcywgd2UgY2FuIGp1c3Qga2VlcFxuLy8gICBgdHJ1ZWAgZm9yIGZpbGVzLCBhbmQgW2NoaWxkcmVuLC4uLl0gZm9yIGRpcmVjdG9yaWVzLCBvciBgZmFsc2VgIGZvclxuLy8gICB0aGluZ3MgdGhhdCBkb24ndCBleGlzdC5cblxubW9kdWxlLmV4cG9ydHMgPSBnbG9iXG5cbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJylcbnZhciBycCA9IHJlcXVpcmUoJ2ZzLnJlYWxwYXRoJylcbnZhciBtaW5pbWF0Y2ggPSByZXF1aXJlKCdtaW5pbWF0Y2gnKVxudmFyIE1pbmltYXRjaCA9IG1pbmltYXRjaC5NaW5pbWF0Y2hcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBFRSA9IHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlclxudmFyIHBhdGggPSByZXF1aXJlKCdwYXRoJylcbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQnKVxudmFyIGlzQWJzb2x1dGUgPSByZXF1aXJlKCdwYXRoLWlzLWFic29sdXRlJylcbnZhciBnbG9iU3luYyA9IHJlcXVpcmUoJy4vc3luYy5qcycpXG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24uanMnKVxudmFyIGFscGhhc29ydCA9IGNvbW1vbi5hbHBoYXNvcnRcbnZhciBhbHBoYXNvcnRpID0gY29tbW9uLmFscGhhc29ydGlcbnZhciBzZXRvcHRzID0gY29tbW9uLnNldG9wdHNcbnZhciBvd25Qcm9wID0gY29tbW9uLm93blByb3BcbnZhciBpbmZsaWdodCA9IHJlcXVpcmUoJ2luZmxpZ2h0JylcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpXG52YXIgY2hpbGRyZW5JZ25vcmVkID0gY29tbW9uLmNoaWxkcmVuSWdub3JlZFxudmFyIGlzSWdub3JlZCA9IGNvbW1vbi5pc0lnbm9yZWRcblxudmFyIG9uY2UgPSByZXF1aXJlKCdvbmNlJylcblxuZnVuY3Rpb24gZ2xvYiAocGF0dGVybiwgb3B0aW9ucywgY2IpIHtcbiAgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnZnVuY3Rpb24nKSBjYiA9IG9wdGlvbnMsIG9wdGlvbnMgPSB7fVxuICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fVxuXG4gIGlmIChvcHRpb25zLnN5bmMpIHtcbiAgICBpZiAoY2IpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdjYWxsYmFjayBwcm92aWRlZCB0byBzeW5jIGdsb2InKVxuICAgIHJldHVybiBnbG9iU3luYyhwYXR0ZXJuLCBvcHRpb25zKVxuICB9XG5cbiAgcmV0dXJuIG5ldyBHbG9iKHBhdHRlcm4sIG9wdGlvbnMsIGNiKVxufVxuXG5nbG9iLnN5bmMgPSBnbG9iU3luY1xudmFyIEdsb2JTeW5jID0gZ2xvYi5HbG9iU3luYyA9IGdsb2JTeW5jLkdsb2JTeW5jXG5cbi8vIG9sZCBhcGkgc3VyZmFjZVxuZ2xvYi5nbG9iID0gZ2xvYlxuXG5mdW5jdGlvbiBleHRlbmQgKG9yaWdpbiwgYWRkKSB7XG4gIGlmIChhZGQgPT09IG51bGwgfHwgdHlwZW9mIGFkZCAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gb3JpZ2luXG4gIH1cblxuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGFkZClcbiAgdmFyIGkgPSBrZXlzLmxlbmd0aFxuICB3aGlsZSAoaS0tKSB7XG4gICAgb3JpZ2luW2tleXNbaV1dID0gYWRkW2tleXNbaV1dXG4gIH1cbiAgcmV0dXJuIG9yaWdpblxufVxuXG5nbG9iLmhhc01hZ2ljID0gZnVuY3Rpb24gKHBhdHRlcm4sIG9wdGlvbnNfKSB7XG4gIHZhciBvcHRpb25zID0gZXh0ZW5kKHt9LCBvcHRpb25zXylcbiAgb3B0aW9ucy5ub3Byb2Nlc3MgPSB0cnVlXG5cbiAgdmFyIGcgPSBuZXcgR2xvYihwYXR0ZXJuLCBvcHRpb25zKVxuICB2YXIgc2V0ID0gZy5taW5pbWF0Y2guc2V0XG5cbiAgaWYgKCFwYXR0ZXJuKVxuICAgIHJldHVybiBmYWxzZVxuXG4gIGlmIChzZXQubGVuZ3RoID4gMSlcbiAgICByZXR1cm4gdHJ1ZVxuXG4gIGZvciAodmFyIGogPSAwOyBqIDwgc2V0WzBdLmxlbmd0aDsgaisrKSB7XG4gICAgaWYgKHR5cGVvZiBzZXRbMF1bal0gIT09ICdzdHJpbmcnKVxuICAgICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIHJldHVybiBmYWxzZVxufVxuXG5nbG9iLkdsb2IgPSBHbG9iXG5pbmhlcml0cyhHbG9iLCBFRSlcbmZ1bmN0aW9uIEdsb2IgKHBhdHRlcm4sIG9wdGlvbnMsIGNiKSB7XG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gb3B0aW9uc1xuICAgIG9wdGlvbnMgPSBudWxsXG4gIH1cblxuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLnN5bmMpIHtcbiAgICBpZiAoY2IpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdjYWxsYmFjayBwcm92aWRlZCB0byBzeW5jIGdsb2InKVxuICAgIHJldHVybiBuZXcgR2xvYlN5bmMocGF0dGVybiwgb3B0aW9ucylcbiAgfVxuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBHbG9iKSlcbiAgICByZXR1cm4gbmV3IEdsb2IocGF0dGVybiwgb3B0aW9ucywgY2IpXG5cbiAgc2V0b3B0cyh0aGlzLCBwYXR0ZXJuLCBvcHRpb25zKVxuICB0aGlzLl9kaWRSZWFsUGF0aCA9IGZhbHNlXG5cbiAgLy8gcHJvY2VzcyBlYWNoIHBhdHRlcm4gaW4gdGhlIG1pbmltYXRjaCBzZXRcbiAgdmFyIG4gPSB0aGlzLm1pbmltYXRjaC5zZXQubGVuZ3RoXG5cbiAgLy8gVGhlIG1hdGNoZXMgYXJlIHN0b3JlZCBhcyB7PGZpbGVuYW1lPjogdHJ1ZSwuLi59IHNvIHRoYXRcbiAgLy8gZHVwbGljYXRlcyBhcmUgYXV0b21hZ2ljYWxseSBwcnVuZWQuXG4gIC8vIExhdGVyLCB3ZSBkbyBhbiBPYmplY3Qua2V5cygpIG9uIHRoZXNlLlxuICAvLyBLZWVwIHRoZW0gYXMgYSBsaXN0IHNvIHdlIGNhbiBmaWxsIGluIHdoZW4gbm9udWxsIGlzIHNldC5cbiAgdGhpcy5tYXRjaGVzID0gbmV3IEFycmF5KG4pXG5cbiAgaWYgKHR5cGVvZiBjYiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gb25jZShjYilcbiAgICB0aGlzLm9uKCdlcnJvcicsIGNiKVxuICAgIHRoaXMub24oJ2VuZCcsIGZ1bmN0aW9uIChtYXRjaGVzKSB7XG4gICAgICBjYihudWxsLCBtYXRjaGVzKVxuICAgIH0pXG4gIH1cblxuICB2YXIgc2VsZiA9IHRoaXNcbiAgdGhpcy5fcHJvY2Vzc2luZyA9IDBcblxuICB0aGlzLl9lbWl0UXVldWUgPSBbXVxuICB0aGlzLl9wcm9jZXNzUXVldWUgPSBbXVxuICB0aGlzLnBhdXNlZCA9IGZhbHNlXG5cbiAgaWYgKHRoaXMubm9wcm9jZXNzKVxuICAgIHJldHVybiB0aGlzXG5cbiAgaWYgKG4gPT09IDApXG4gICAgcmV0dXJuIGRvbmUoKVxuXG4gIHZhciBzeW5jID0gdHJ1ZVxuICBmb3IgKHZhciBpID0gMDsgaSA8IG47IGkgKyspIHtcbiAgICB0aGlzLl9wcm9jZXNzKHRoaXMubWluaW1hdGNoLnNldFtpXSwgaSwgZmFsc2UsIGRvbmUpXG4gIH1cbiAgc3luYyA9IGZhbHNlXG5cbiAgZnVuY3Rpb24gZG9uZSAoKSB7XG4gICAgLS1zZWxmLl9wcm9jZXNzaW5nXG4gICAgaWYgKHNlbGYuX3Byb2Nlc3NpbmcgPD0gMCkge1xuICAgICAgaWYgKHN5bmMpIHtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgc2VsZi5fZmluaXNoKClcbiAgICAgICAgfSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNlbGYuX2ZpbmlzaCgpXG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbkdsb2IucHJvdG90eXBlLl9maW5pc2ggPSBmdW5jdGlvbiAoKSB7XG4gIGFzc2VydCh0aGlzIGluc3RhbmNlb2YgR2xvYilcbiAgaWYgKHRoaXMuYWJvcnRlZClcbiAgICByZXR1cm5cblxuICBpZiAodGhpcy5yZWFscGF0aCAmJiAhdGhpcy5fZGlkUmVhbHBhdGgpXG4gICAgcmV0dXJuIHRoaXMuX3JlYWxwYXRoKClcblxuICBjb21tb24uZmluaXNoKHRoaXMpXG4gIHRoaXMuZW1pdCgnZW5kJywgdGhpcy5mb3VuZClcbn1cblxuR2xvYi5wcm90b3R5cGUuX3JlYWxwYXRoID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5fZGlkUmVhbHBhdGgpXG4gICAgcmV0dXJuXG5cbiAgdGhpcy5fZGlkUmVhbHBhdGggPSB0cnVlXG5cbiAgdmFyIG4gPSB0aGlzLm1hdGNoZXMubGVuZ3RoXG4gIGlmIChuID09PSAwKVxuICAgIHJldHVybiB0aGlzLl9maW5pc2goKVxuXG4gIHZhciBzZWxmID0gdGhpc1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubWF0Y2hlcy5sZW5ndGg7IGkrKylcbiAgICB0aGlzLl9yZWFscGF0aFNldChpLCBuZXh0KVxuXG4gIGZ1bmN0aW9uIG5leHQgKCkge1xuICAgIGlmICgtLW4gPT09IDApXG4gICAgICBzZWxmLl9maW5pc2goKVxuICB9XG59XG5cbkdsb2IucHJvdG90eXBlLl9yZWFscGF0aFNldCA9IGZ1bmN0aW9uIChpbmRleCwgY2IpIHtcbiAgdmFyIG1hdGNoc2V0ID0gdGhpcy5tYXRjaGVzW2luZGV4XVxuICBpZiAoIW1hdGNoc2V0KVxuICAgIHJldHVybiBjYigpXG5cbiAgdmFyIGZvdW5kID0gT2JqZWN0LmtleXMobWF0Y2hzZXQpXG4gIHZhciBzZWxmID0gdGhpc1xuICB2YXIgbiA9IGZvdW5kLmxlbmd0aFxuXG4gIGlmIChuID09PSAwKVxuICAgIHJldHVybiBjYigpXG5cbiAgdmFyIHNldCA9IHRoaXMubWF0Y2hlc1tpbmRleF0gPSBPYmplY3QuY3JlYXRlKG51bGwpXG4gIGZvdW5kLmZvckVhY2goZnVuY3Rpb24gKHAsIGkpIHtcbiAgICAvLyBJZiB0aGVyZSdzIGEgcHJvYmxlbSB3aXRoIHRoZSBzdGF0LCB0aGVuIGl0IG1lYW5zIHRoYXRcbiAgICAvLyBvbmUgb3IgbW9yZSBvZiB0aGUgbGlua3MgaW4gdGhlIHJlYWxwYXRoIGNvdWxkbid0IGJlXG4gICAgLy8gcmVzb2x2ZWQuICBqdXN0IHJldHVybiB0aGUgYWJzIHZhbHVlIGluIHRoYXQgY2FzZS5cbiAgICBwID0gc2VsZi5fbWFrZUFicyhwKVxuICAgIHJwLnJlYWxwYXRoKHAsIHNlbGYucmVhbHBhdGhDYWNoZSwgZnVuY3Rpb24gKGVyLCByZWFsKSB7XG4gICAgICBpZiAoIWVyKVxuICAgICAgICBzZXRbcmVhbF0gPSB0cnVlXG4gICAgICBlbHNlIGlmIChlci5zeXNjYWxsID09PSAnc3RhdCcpXG4gICAgICAgIHNldFtwXSA9IHRydWVcbiAgICAgIGVsc2VcbiAgICAgICAgc2VsZi5lbWl0KCdlcnJvcicsIGVyKSAvLyBzcnNseSB3dGYgcmlnaHQgaGVyZVxuXG4gICAgICBpZiAoLS1uID09PSAwKSB7XG4gICAgICAgIHNlbGYubWF0Y2hlc1tpbmRleF0gPSBzZXRcbiAgICAgICAgY2IoKVxuICAgICAgfVxuICAgIH0pXG4gIH0pXG59XG5cbkdsb2IucHJvdG90eXBlLl9tYXJrID0gZnVuY3Rpb24gKHApIHtcbiAgcmV0dXJuIGNvbW1vbi5tYXJrKHRoaXMsIHApXG59XG5cbkdsb2IucHJvdG90eXBlLl9tYWtlQWJzID0gZnVuY3Rpb24gKGYpIHtcbiAgcmV0dXJuIGNvbW1vbi5tYWtlQWJzKHRoaXMsIGYpXG59XG5cbkdsb2IucHJvdG90eXBlLmFib3J0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmFib3J0ZWQgPSB0cnVlXG4gIHRoaXMuZW1pdCgnYWJvcnQnKVxufVxuXG5HbG9iLnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCF0aGlzLnBhdXNlZCkge1xuICAgIHRoaXMucGF1c2VkID0gdHJ1ZVxuICAgIHRoaXMuZW1pdCgncGF1c2UnKVxuICB9XG59XG5cbkdsb2IucHJvdG90eXBlLnJlc3VtZSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMucGF1c2VkKSB7XG4gICAgdGhpcy5lbWl0KCdyZXN1bWUnKVxuICAgIHRoaXMucGF1c2VkID0gZmFsc2VcbiAgICBpZiAodGhpcy5fZW1pdFF1ZXVlLmxlbmd0aCkge1xuICAgICAgdmFyIGVxID0gdGhpcy5fZW1pdFF1ZXVlLnNsaWNlKDApXG4gICAgICB0aGlzLl9lbWl0UXVldWUubGVuZ3RoID0gMFxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlcS5sZW5ndGg7IGkgKyspIHtcbiAgICAgICAgdmFyIGUgPSBlcVtpXVxuICAgICAgICB0aGlzLl9lbWl0TWF0Y2goZVswXSwgZVsxXSlcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRoaXMuX3Byb2Nlc3NRdWV1ZS5sZW5ndGgpIHtcbiAgICAgIHZhciBwcSA9IHRoaXMuX3Byb2Nlc3NRdWV1ZS5zbGljZSgwKVxuICAgICAgdGhpcy5fcHJvY2Vzc1F1ZXVlLmxlbmd0aCA9IDBcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcHEubGVuZ3RoOyBpICsrKSB7XG4gICAgICAgIHZhciBwID0gcHFbaV1cbiAgICAgICAgdGhpcy5fcHJvY2Vzc2luZy0tXG4gICAgICAgIHRoaXMuX3Byb2Nlc3MocFswXSwgcFsxXSwgcFsyXSwgcFszXSlcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuR2xvYi5wcm90b3R5cGUuX3Byb2Nlc3MgPSBmdW5jdGlvbiAocGF0dGVybiwgaW5kZXgsIGluR2xvYlN0YXIsIGNiKSB7XG4gIGFzc2VydCh0aGlzIGluc3RhbmNlb2YgR2xvYilcbiAgYXNzZXJ0KHR5cGVvZiBjYiA9PT0gJ2Z1bmN0aW9uJylcblxuICBpZiAodGhpcy5hYm9ydGVkKVxuICAgIHJldHVyblxuXG4gIHRoaXMuX3Byb2Nlc3NpbmcrK1xuICBpZiAodGhpcy5wYXVzZWQpIHtcbiAgICB0aGlzLl9wcm9jZXNzUXVldWUucHVzaChbcGF0dGVybiwgaW5kZXgsIGluR2xvYlN0YXIsIGNiXSlcbiAgICByZXR1cm5cbiAgfVxuXG4gIC8vY29uc29sZS5lcnJvcignUFJPQ0VTUyAlZCcsIHRoaXMuX3Byb2Nlc3NpbmcsIHBhdHRlcm4pXG5cbiAgLy8gR2V0IHRoZSBmaXJzdCBbbl0gcGFydHMgb2YgcGF0dGVybiB0aGF0IGFyZSBhbGwgc3RyaW5ncy5cbiAgdmFyIG4gPSAwXG4gIHdoaWxlICh0eXBlb2YgcGF0dGVybltuXSA9PT0gJ3N0cmluZycpIHtcbiAgICBuICsrXG4gIH1cbiAgLy8gbm93IG4gaXMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvbmUgdGhhdCBpcyAqbm90KiBhIHN0cmluZy5cblxuICAvLyBzZWUgaWYgdGhlcmUncyBhbnl0aGluZyBlbHNlXG4gIHZhciBwcmVmaXhcbiAgc3dpdGNoIChuKSB7XG4gICAgLy8gaWYgbm90LCB0aGVuIHRoaXMgaXMgcmF0aGVyIHNpbXBsZVxuICAgIGNhc2UgcGF0dGVybi5sZW5ndGg6XG4gICAgICB0aGlzLl9wcm9jZXNzU2ltcGxlKHBhdHRlcm4uam9pbignLycpLCBpbmRleCwgY2IpXG4gICAgICByZXR1cm5cblxuICAgIGNhc2UgMDpcbiAgICAgIC8vIHBhdHRlcm4gKnN0YXJ0cyogd2l0aCBzb21lIG5vbi10cml2aWFsIGl0ZW0uXG4gICAgICAvLyBnb2luZyB0byByZWFkZGlyKGN3ZCksIGJ1dCBub3QgaW5jbHVkZSB0aGUgcHJlZml4IGluIG1hdGNoZXMuXG4gICAgICBwcmVmaXggPSBudWxsXG4gICAgICBicmVha1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIHBhdHRlcm4gaGFzIHNvbWUgc3RyaW5nIGJpdHMgaW4gdGhlIGZyb250LlxuICAgICAgLy8gd2hhdGV2ZXIgaXQgc3RhcnRzIHdpdGgsIHdoZXRoZXIgdGhhdCdzICdhYnNvbHV0ZScgbGlrZSAvZm9vL2JhcixcbiAgICAgIC8vIG9yICdyZWxhdGl2ZScgbGlrZSAnLi4vYmF6J1xuICAgICAgcHJlZml4ID0gcGF0dGVybi5zbGljZSgwLCBuKS5qb2luKCcvJylcbiAgICAgIGJyZWFrXG4gIH1cblxuICB2YXIgcmVtYWluID0gcGF0dGVybi5zbGljZShuKVxuXG4gIC8vIGdldCB0aGUgbGlzdCBvZiBlbnRyaWVzLlxuICB2YXIgcmVhZFxuICBpZiAocHJlZml4ID09PSBudWxsKVxuICAgIHJlYWQgPSAnLidcbiAgZWxzZSBpZiAoaXNBYnNvbHV0ZShwcmVmaXgpIHx8IGlzQWJzb2x1dGUocGF0dGVybi5qb2luKCcvJykpKSB7XG4gICAgaWYgKCFwcmVmaXggfHwgIWlzQWJzb2x1dGUocHJlZml4KSlcbiAgICAgIHByZWZpeCA9ICcvJyArIHByZWZpeFxuICAgIHJlYWQgPSBwcmVmaXhcbiAgfSBlbHNlXG4gICAgcmVhZCA9IHByZWZpeFxuXG4gIHZhciBhYnMgPSB0aGlzLl9tYWtlQWJzKHJlYWQpXG5cbiAgLy9pZiBpZ25vcmVkLCBza2lwIF9wcm9jZXNzaW5nXG4gIGlmIChjaGlsZHJlbklnbm9yZWQodGhpcywgcmVhZCkpXG4gICAgcmV0dXJuIGNiKClcblxuICB2YXIgaXNHbG9iU3RhciA9IHJlbWFpblswXSA9PT0gbWluaW1hdGNoLkdMT0JTVEFSXG4gIGlmIChpc0dsb2JTdGFyKVxuICAgIHRoaXMuX3Byb2Nlc3NHbG9iU3RhcihwcmVmaXgsIHJlYWQsIGFicywgcmVtYWluLCBpbmRleCwgaW5HbG9iU3RhciwgY2IpXG4gIGVsc2VcbiAgICB0aGlzLl9wcm9jZXNzUmVhZGRpcihwcmVmaXgsIHJlYWQsIGFicywgcmVtYWluLCBpbmRleCwgaW5HbG9iU3RhciwgY2IpXG59XG5cbkdsb2IucHJvdG90eXBlLl9wcm9jZXNzUmVhZGRpciA9IGZ1bmN0aW9uIChwcmVmaXgsIHJlYWQsIGFicywgcmVtYWluLCBpbmRleCwgaW5HbG9iU3RhciwgY2IpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHRoaXMuX3JlYWRkaXIoYWJzLCBpbkdsb2JTdGFyLCBmdW5jdGlvbiAoZXIsIGVudHJpZXMpIHtcbiAgICByZXR1cm4gc2VsZi5fcHJvY2Vzc1JlYWRkaXIyKHByZWZpeCwgcmVhZCwgYWJzLCByZW1haW4sIGluZGV4LCBpbkdsb2JTdGFyLCBlbnRyaWVzLCBjYilcbiAgfSlcbn1cblxuR2xvYi5wcm90b3R5cGUuX3Byb2Nlc3NSZWFkZGlyMiA9IGZ1bmN0aW9uIChwcmVmaXgsIHJlYWQsIGFicywgcmVtYWluLCBpbmRleCwgaW5HbG9iU3RhciwgZW50cmllcywgY2IpIHtcblxuICAvLyBpZiB0aGUgYWJzIGlzbid0IGEgZGlyLCB0aGVuIG5vdGhpbmcgY2FuIG1hdGNoIVxuICBpZiAoIWVudHJpZXMpXG4gICAgcmV0dXJuIGNiKClcblxuICAvLyBJdCB3aWxsIG9ubHkgbWF0Y2ggZG90IGVudHJpZXMgaWYgaXQgc3RhcnRzIHdpdGggYSBkb3QsIG9yIGlmXG4gIC8vIGRvdCBpcyBzZXQuICBTdHVmZiBsaWtlIEAoLmZvb3wuYmFyKSBpc24ndCBhbGxvd2VkLlxuICB2YXIgcG4gPSByZW1haW5bMF1cbiAgdmFyIG5lZ2F0ZSA9ICEhdGhpcy5taW5pbWF0Y2gubmVnYXRlXG4gIHZhciByYXdHbG9iID0gcG4uX2dsb2JcbiAgdmFyIGRvdE9rID0gdGhpcy5kb3QgfHwgcmF3R2xvYi5jaGFyQXQoMCkgPT09ICcuJ1xuXG4gIHZhciBtYXRjaGVkRW50cmllcyA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZW50cmllcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBlID0gZW50cmllc1tpXVxuICAgIGlmIChlLmNoYXJBdCgwKSAhPT0gJy4nIHx8IGRvdE9rKSB7XG4gICAgICB2YXIgbVxuICAgICAgaWYgKG5lZ2F0ZSAmJiAhcHJlZml4KSB7XG4gICAgICAgIG0gPSAhZS5tYXRjaChwbilcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG0gPSBlLm1hdGNoKHBuKVxuICAgICAgfVxuICAgICAgaWYgKG0pXG4gICAgICAgIG1hdGNoZWRFbnRyaWVzLnB1c2goZSlcbiAgICB9XG4gIH1cblxuICAvL2NvbnNvbGUuZXJyb3IoJ3ByZDInLCBwcmVmaXgsIGVudHJpZXMsIHJlbWFpblswXS5fZ2xvYiwgbWF0Y2hlZEVudHJpZXMpXG5cbiAgdmFyIGxlbiA9IG1hdGNoZWRFbnRyaWVzLmxlbmd0aFxuICAvLyBJZiB0aGVyZSBhcmUgbm8gbWF0Y2hlZCBlbnRyaWVzLCB0aGVuIG5vdGhpbmcgbWF0Y2hlcy5cbiAgaWYgKGxlbiA9PT0gMClcbiAgICByZXR1cm4gY2IoKVxuXG4gIC8vIGlmIHRoaXMgaXMgdGhlIGxhc3QgcmVtYWluaW5nIHBhdHRlcm4gYml0LCB0aGVuIG5vIG5lZWQgZm9yXG4gIC8vIGFuIGFkZGl0aW9uYWwgc3RhdCAqdW5sZXNzKiB0aGUgdXNlciBoYXMgc3BlY2lmaWVkIG1hcmsgb3JcbiAgLy8gc3RhdCBleHBsaWNpdGx5LiAgV2Uga25vdyB0aGV5IGV4aXN0LCBzaW5jZSByZWFkZGlyIHJldHVybmVkXG4gIC8vIHRoZW0uXG5cbiAgaWYgKHJlbWFpbi5sZW5ndGggPT09IDEgJiYgIXRoaXMubWFyayAmJiAhdGhpcy5zdGF0KSB7XG4gICAgaWYgKCF0aGlzLm1hdGNoZXNbaW5kZXhdKVxuICAgICAgdGhpcy5tYXRjaGVzW2luZGV4XSA9IE9iamVjdC5jcmVhdGUobnVsbClcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICsrKSB7XG4gICAgICB2YXIgZSA9IG1hdGNoZWRFbnRyaWVzW2ldXG4gICAgICBpZiAocHJlZml4KSB7XG4gICAgICAgIGlmIChwcmVmaXggIT09ICcvJylcbiAgICAgICAgICBlID0gcHJlZml4ICsgJy8nICsgZVxuICAgICAgICBlbHNlXG4gICAgICAgICAgZSA9IHByZWZpeCArIGVcbiAgICAgIH1cblxuICAgICAgaWYgKGUuY2hhckF0KDApID09PSAnLycgJiYgIXRoaXMubm9tb3VudCkge1xuICAgICAgICBlID0gcGF0aC5qb2luKHRoaXMucm9vdCwgZSlcbiAgICAgIH1cbiAgICAgIHRoaXMuX2VtaXRNYXRjaChpbmRleCwgZSlcbiAgICB9XG4gICAgLy8gVGhpcyB3YXMgdGhlIGxhc3Qgb25lLCBhbmQgbm8gc3RhdHMgd2VyZSBuZWVkZWRcbiAgICByZXR1cm4gY2IoKVxuICB9XG5cbiAgLy8gbm93IHRlc3QgYWxsIG1hdGNoZWQgZW50cmllcyBhcyBzdGFuZC1pbnMgZm9yIHRoYXQgcGFydFxuICAvLyBvZiB0aGUgcGF0dGVybi5cbiAgcmVtYWluLnNoaWZ0KClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKyspIHtcbiAgICB2YXIgZSA9IG1hdGNoZWRFbnRyaWVzW2ldXG4gICAgdmFyIG5ld1BhdHRlcm5cbiAgICBpZiAocHJlZml4KSB7XG4gICAgICBpZiAocHJlZml4ICE9PSAnLycpXG4gICAgICAgIGUgPSBwcmVmaXggKyAnLycgKyBlXG4gICAgICBlbHNlXG4gICAgICAgIGUgPSBwcmVmaXggKyBlXG4gICAgfVxuICAgIHRoaXMuX3Byb2Nlc3MoW2VdLmNvbmNhdChyZW1haW4pLCBpbmRleCwgaW5HbG9iU3RhciwgY2IpXG4gIH1cbiAgY2IoKVxufVxuXG5HbG9iLnByb3RvdHlwZS5fZW1pdE1hdGNoID0gZnVuY3Rpb24gKGluZGV4LCBlKSB7XG4gIGlmICh0aGlzLmFib3J0ZWQpXG4gICAgcmV0dXJuXG5cbiAgaWYgKGlzSWdub3JlZCh0aGlzLCBlKSlcbiAgICByZXR1cm5cblxuICBpZiAodGhpcy5wYXVzZWQpIHtcbiAgICB0aGlzLl9lbWl0UXVldWUucHVzaChbaW5kZXgsIGVdKVxuICAgIHJldHVyblxuICB9XG5cbiAgdmFyIGFicyA9IGlzQWJzb2x1dGUoZSkgPyBlIDogdGhpcy5fbWFrZUFicyhlKVxuXG4gIGlmICh0aGlzLm1hcmspXG4gICAgZSA9IHRoaXMuX21hcmsoZSlcblxuICBpZiAodGhpcy5hYnNvbHV0ZSlcbiAgICBlID0gYWJzXG5cbiAgaWYgKHRoaXMubWF0Y2hlc1tpbmRleF1bZV0pXG4gICAgcmV0dXJuXG5cbiAgaWYgKHRoaXMubm9kaXIpIHtcbiAgICB2YXIgYyA9IHRoaXMuY2FjaGVbYWJzXVxuICAgIGlmIChjID09PSAnRElSJyB8fCBBcnJheS5pc0FycmF5KGMpKVxuICAgICAgcmV0dXJuXG4gIH1cblxuICB0aGlzLm1hdGNoZXNbaW5kZXhdW2VdID0gdHJ1ZVxuXG4gIHZhciBzdCA9IHRoaXMuc3RhdENhY2hlW2Fic11cbiAgaWYgKHN0KVxuICAgIHRoaXMuZW1pdCgnc3RhdCcsIGUsIHN0KVxuXG4gIHRoaXMuZW1pdCgnbWF0Y2gnLCBlKVxufVxuXG5HbG9iLnByb3RvdHlwZS5fcmVhZGRpckluR2xvYlN0YXIgPSBmdW5jdGlvbiAoYWJzLCBjYikge1xuICBpZiAodGhpcy5hYm9ydGVkKVxuICAgIHJldHVyblxuXG4gIC8vIGZvbGxvdyBhbGwgc3ltbGlua2VkIGRpcmVjdG9yaWVzIGZvcmV2ZXJcbiAgLy8ganVzdCBwcm9jZWVkIGFzIGlmIHRoaXMgaXMgYSBub24tZ2xvYnN0YXIgc2l0dWF0aW9uXG4gIGlmICh0aGlzLmZvbGxvdylcbiAgICByZXR1cm4gdGhpcy5fcmVhZGRpcihhYnMsIGZhbHNlLCBjYilcblxuICB2YXIgbHN0YXRrZXkgPSAnbHN0YXRcXDAnICsgYWJzXG4gIHZhciBzZWxmID0gdGhpc1xuICB2YXIgbHN0YXRjYiA9IGluZmxpZ2h0KGxzdGF0a2V5LCBsc3RhdGNiXylcblxuICBpZiAobHN0YXRjYilcbiAgICBmcy5sc3RhdChhYnMsIGxzdGF0Y2IpXG5cbiAgZnVuY3Rpb24gbHN0YXRjYl8gKGVyLCBsc3RhdCkge1xuICAgIGlmIChlciAmJiBlci5jb2RlID09PSAnRU5PRU5UJylcbiAgICAgIHJldHVybiBjYigpXG5cbiAgICB2YXIgaXNTeW0gPSBsc3RhdCAmJiBsc3RhdC5pc1N5bWJvbGljTGluaygpXG4gICAgc2VsZi5zeW1saW5rc1thYnNdID0gaXNTeW1cblxuICAgIC8vIElmIGl0J3Mgbm90IGEgc3ltbGluayBvciBhIGRpciwgdGhlbiBpdCdzIGRlZmluaXRlbHkgYSByZWd1bGFyIGZpbGUuXG4gICAgLy8gZG9uJ3QgYm90aGVyIGRvaW5nIGEgcmVhZGRpciBpbiB0aGF0IGNhc2UuXG4gICAgaWYgKCFpc1N5bSAmJiBsc3RhdCAmJiAhbHN0YXQuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgc2VsZi5jYWNoZVthYnNdID0gJ0ZJTEUnXG4gICAgICBjYigpXG4gICAgfSBlbHNlXG4gICAgICBzZWxmLl9yZWFkZGlyKGFicywgZmFsc2UsIGNiKVxuICB9XG59XG5cbkdsb2IucHJvdG90eXBlLl9yZWFkZGlyID0gZnVuY3Rpb24gKGFicywgaW5HbG9iU3RhciwgY2IpIHtcbiAgaWYgKHRoaXMuYWJvcnRlZClcbiAgICByZXR1cm5cblxuICBjYiA9IGluZmxpZ2h0KCdyZWFkZGlyXFwwJythYnMrJ1xcMCcraW5HbG9iU3RhciwgY2IpXG4gIGlmICghY2IpXG4gICAgcmV0dXJuXG5cbiAgLy9jb25zb2xlLmVycm9yKCdSRCAlaiAlaicsICtpbkdsb2JTdGFyLCBhYnMpXG4gIGlmIChpbkdsb2JTdGFyICYmICFvd25Qcm9wKHRoaXMuc3ltbGlua3MsIGFicykpXG4gICAgcmV0dXJuIHRoaXMuX3JlYWRkaXJJbkdsb2JTdGFyKGFicywgY2IpXG5cbiAgaWYgKG93blByb3AodGhpcy5jYWNoZSwgYWJzKSkge1xuICAgIHZhciBjID0gdGhpcy5jYWNoZVthYnNdXG4gICAgaWYgKCFjIHx8IGMgPT09ICdGSUxFJylcbiAgICAgIHJldHVybiBjYigpXG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShjKSlcbiAgICAgIHJldHVybiBjYihudWxsLCBjKVxuICB9XG5cbiAgdmFyIHNlbGYgPSB0aGlzXG4gIGZzLnJlYWRkaXIoYWJzLCByZWFkZGlyQ2IodGhpcywgYWJzLCBjYikpXG59XG5cbmZ1bmN0aW9uIHJlYWRkaXJDYiAoc2VsZiwgYWJzLCBjYikge1xuICByZXR1cm4gZnVuY3Rpb24gKGVyLCBlbnRyaWVzKSB7XG4gICAgaWYgKGVyKVxuICAgICAgc2VsZi5fcmVhZGRpckVycm9yKGFicywgZXIsIGNiKVxuICAgIGVsc2VcbiAgICAgIHNlbGYuX3JlYWRkaXJFbnRyaWVzKGFicywgZW50cmllcywgY2IpXG4gIH1cbn1cblxuR2xvYi5wcm90b3R5cGUuX3JlYWRkaXJFbnRyaWVzID0gZnVuY3Rpb24gKGFicywgZW50cmllcywgY2IpIHtcbiAgaWYgKHRoaXMuYWJvcnRlZClcbiAgICByZXR1cm5cblxuICAvLyBpZiB3ZSBoYXZlbid0IGFza2VkIHRvIHN0YXQgZXZlcnl0aGluZywgdGhlbiBqdXN0XG4gIC8vIGFzc3VtZSB0aGF0IGV2ZXJ5dGhpbmcgaW4gdGhlcmUgZXhpc3RzLCBzbyB3ZSBjYW4gYXZvaWRcbiAgLy8gaGF2aW5nIHRvIHN0YXQgaXQgYSBzZWNvbmQgdGltZS5cbiAgaWYgKCF0aGlzLm1hcmsgJiYgIXRoaXMuc3RhdCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZW50cmllcy5sZW5ndGg7IGkgKyspIHtcbiAgICAgIHZhciBlID0gZW50cmllc1tpXVxuICAgICAgaWYgKGFicyA9PT0gJy8nKVxuICAgICAgICBlID0gYWJzICsgZVxuICAgICAgZWxzZVxuICAgICAgICBlID0gYWJzICsgJy8nICsgZVxuICAgICAgdGhpcy5jYWNoZVtlXSA9IHRydWVcbiAgICB9XG4gIH1cblxuICB0aGlzLmNhY2hlW2Fic10gPSBlbnRyaWVzXG4gIHJldHVybiBjYihudWxsLCBlbnRyaWVzKVxufVxuXG5HbG9iLnByb3RvdHlwZS5fcmVhZGRpckVycm9yID0gZnVuY3Rpb24gKGYsIGVyLCBjYikge1xuICBpZiAodGhpcy5hYm9ydGVkKVxuICAgIHJldHVyblxuXG4gIC8vIGhhbmRsZSBlcnJvcnMsIGFuZCBjYWNoZSB0aGUgaW5mb3JtYXRpb25cbiAgc3dpdGNoIChlci5jb2RlKSB7XG4gICAgY2FzZSAnRU5PVFNVUCc6IC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9pc2FhY3Mvbm9kZS1nbG9iL2lzc3Vlcy8yMDVcbiAgICBjYXNlICdFTk9URElSJzogLy8gdG90YWxseSBub3JtYWwuIG1lYW5zIGl0ICpkb2VzKiBleGlzdC5cbiAgICAgIHZhciBhYnMgPSB0aGlzLl9tYWtlQWJzKGYpXG4gICAgICB0aGlzLmNhY2hlW2Fic10gPSAnRklMRSdcbiAgICAgIGlmIChhYnMgPT09IHRoaXMuY3dkQWJzKSB7XG4gICAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcihlci5jb2RlICsgJyBpbnZhbGlkIGN3ZCAnICsgdGhpcy5jd2QpXG4gICAgICAgIGVycm9yLnBhdGggPSB0aGlzLmN3ZFxuICAgICAgICBlcnJvci5jb2RlID0gZXIuY29kZVxuICAgICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyb3IpXG4gICAgICAgIHRoaXMuYWJvcnQoKVxuICAgICAgfVxuICAgICAgYnJlYWtcblxuICAgIGNhc2UgJ0VOT0VOVCc6IC8vIG5vdCB0ZXJyaWJseSB1bnVzdWFsXG4gICAgY2FzZSAnRUxPT1AnOlxuICAgIGNhc2UgJ0VOQU1FVE9PTE9ORyc6XG4gICAgY2FzZSAnVU5LTk9XTic6XG4gICAgICB0aGlzLmNhY2hlW3RoaXMuX21ha2VBYnMoZildID0gZmFsc2VcbiAgICAgIGJyZWFrXG5cbiAgICBkZWZhdWx0OiAvLyBzb21lIHVudXN1YWwgZXJyb3IuICBUcmVhdCBhcyBmYWlsdXJlLlxuICAgICAgdGhpcy5jYWNoZVt0aGlzLl9tYWtlQWJzKGYpXSA9IGZhbHNlXG4gICAgICBpZiAodGhpcy5zdHJpY3QpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsIGVyKVxuICAgICAgICAvLyBJZiB0aGUgZXJyb3IgaXMgaGFuZGxlZCwgdGhlbiB3ZSBhYm9ydFxuICAgICAgICAvLyBpZiBub3QsIHdlIHRocmV3IG91dCBvZiBoZXJlXG4gICAgICAgIHRoaXMuYWJvcnQoKVxuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLnNpbGVudClcbiAgICAgICAgY29uc29sZS5lcnJvcignZ2xvYiBlcnJvcicsIGVyKVxuICAgICAgYnJlYWtcbiAgfVxuXG4gIHJldHVybiBjYigpXG59XG5cbkdsb2IucHJvdG90eXBlLl9wcm9jZXNzR2xvYlN0YXIgPSBmdW5jdGlvbiAocHJlZml4LCByZWFkLCBhYnMsIHJlbWFpbiwgaW5kZXgsIGluR2xvYlN0YXIsIGNiKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICB0aGlzLl9yZWFkZGlyKGFicywgaW5HbG9iU3RhciwgZnVuY3Rpb24gKGVyLCBlbnRyaWVzKSB7XG4gICAgc2VsZi5fcHJvY2Vzc0dsb2JTdGFyMihwcmVmaXgsIHJlYWQsIGFicywgcmVtYWluLCBpbmRleCwgaW5HbG9iU3RhciwgZW50cmllcywgY2IpXG4gIH0pXG59XG5cblxuR2xvYi5wcm90b3R5cGUuX3Byb2Nlc3NHbG9iU3RhcjIgPSBmdW5jdGlvbiAocHJlZml4LCByZWFkLCBhYnMsIHJlbWFpbiwgaW5kZXgsIGluR2xvYlN0YXIsIGVudHJpZXMsIGNiKSB7XG4gIC8vY29uc29sZS5lcnJvcigncGdzMicsIHByZWZpeCwgcmVtYWluWzBdLCBlbnRyaWVzKVxuXG4gIC8vIG5vIGVudHJpZXMgbWVhbnMgbm90IGEgZGlyLCBzbyBpdCBjYW4gbmV2ZXIgaGF2ZSBtYXRjaGVzXG4gIC8vIGZvby50eHQvKiogZG9lc24ndCBtYXRjaCBmb28udHh0XG4gIGlmICghZW50cmllcylcbiAgICByZXR1cm4gY2IoKVxuXG4gIC8vIHRlc3Qgd2l0aG91dCB0aGUgZ2xvYnN0YXIsIGFuZCB3aXRoIGV2ZXJ5IGNoaWxkIGJvdGggYmVsb3dcbiAgLy8gYW5kIHJlcGxhY2luZyB0aGUgZ2xvYnN0YXIuXG4gIHZhciByZW1haW5XaXRob3V0R2xvYlN0YXIgPSByZW1haW4uc2xpY2UoMSlcbiAgdmFyIGdzcHJlZiA9IHByZWZpeCA/IFsgcHJlZml4IF0gOiBbXVxuICB2YXIgbm9HbG9iU3RhciA9IGdzcHJlZi5jb25jYXQocmVtYWluV2l0aG91dEdsb2JTdGFyKVxuXG4gIC8vIHRoZSBub0dsb2JTdGFyIHBhdHRlcm4gZXhpdHMgdGhlIGluR2xvYlN0YXIgc3RhdGVcbiAgdGhpcy5fcHJvY2Vzcyhub0dsb2JTdGFyLCBpbmRleCwgZmFsc2UsIGNiKVxuXG4gIHZhciBpc1N5bSA9IHRoaXMuc3ltbGlua3NbYWJzXVxuICB2YXIgbGVuID0gZW50cmllcy5sZW5ndGhcblxuICAvLyBJZiBpdCdzIGEgc3ltbGluaywgYW5kIHdlJ3JlIGluIGEgZ2xvYnN0YXIsIHRoZW4gc3RvcFxuICBpZiAoaXNTeW0gJiYgaW5HbG9iU3RhcilcbiAgICByZXR1cm4gY2IoKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICB2YXIgZSA9IGVudHJpZXNbaV1cbiAgICBpZiAoZS5jaGFyQXQoMCkgPT09ICcuJyAmJiAhdGhpcy5kb3QpXG4gICAgICBjb250aW51ZVxuXG4gICAgLy8gdGhlc2UgdHdvIGNhc2VzIGVudGVyIHRoZSBpbkdsb2JTdGFyIHN0YXRlXG4gICAgdmFyIGluc3RlYWQgPSBnc3ByZWYuY29uY2F0KGVudHJpZXNbaV0sIHJlbWFpbldpdGhvdXRHbG9iU3RhcilcbiAgICB0aGlzLl9wcm9jZXNzKGluc3RlYWQsIGluZGV4LCB0cnVlLCBjYilcblxuICAgIHZhciBiZWxvdyA9IGdzcHJlZi5jb25jYXQoZW50cmllc1tpXSwgcmVtYWluKVxuICAgIHRoaXMuX3Byb2Nlc3MoYmVsb3csIGluZGV4LCB0cnVlLCBjYilcbiAgfVxuXG4gIGNiKClcbn1cblxuR2xvYi5wcm90b3R5cGUuX3Byb2Nlc3NTaW1wbGUgPSBmdW5jdGlvbiAocHJlZml4LCBpbmRleCwgY2IpIHtcbiAgLy8gWFhYIHJldmlldyB0aGlzLiAgU2hvdWxkbid0IGl0IGJlIGRvaW5nIHRoZSBtb3VudGluZyBldGNcbiAgLy8gYmVmb3JlIGRvaW5nIHN0YXQ/ICBraW5kYSB3ZWlyZD9cbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHRoaXMuX3N0YXQocHJlZml4LCBmdW5jdGlvbiAoZXIsIGV4aXN0cykge1xuICAgIHNlbGYuX3Byb2Nlc3NTaW1wbGUyKHByZWZpeCwgaW5kZXgsIGVyLCBleGlzdHMsIGNiKVxuICB9KVxufVxuR2xvYi5wcm90b3R5cGUuX3Byb2Nlc3NTaW1wbGUyID0gZnVuY3Rpb24gKHByZWZpeCwgaW5kZXgsIGVyLCBleGlzdHMsIGNiKSB7XG5cbiAgLy9jb25zb2xlLmVycm9yKCdwczInLCBwcmVmaXgsIGV4aXN0cylcblxuICBpZiAoIXRoaXMubWF0Y2hlc1tpbmRleF0pXG4gICAgdGhpcy5tYXRjaGVzW2luZGV4XSA9IE9iamVjdC5jcmVhdGUobnVsbClcblxuICAvLyBJZiBpdCBkb2Vzbid0IGV4aXN0LCB0aGVuIGp1c3QgbWFyayB0aGUgbGFjayBvZiByZXN1bHRzXG4gIGlmICghZXhpc3RzKVxuICAgIHJldHVybiBjYigpXG5cbiAgaWYgKHByZWZpeCAmJiBpc0Fic29sdXRlKHByZWZpeCkgJiYgIXRoaXMubm9tb3VudCkge1xuICAgIHZhciB0cmFpbCA9IC9bXFwvXFxcXF0kLy50ZXN0KHByZWZpeClcbiAgICBpZiAocHJlZml4LmNoYXJBdCgwKSA9PT0gJy8nKSB7XG4gICAgICBwcmVmaXggPSBwYXRoLmpvaW4odGhpcy5yb290LCBwcmVmaXgpXG4gICAgfSBlbHNlIHtcbiAgICAgIHByZWZpeCA9IHBhdGgucmVzb2x2ZSh0aGlzLnJvb3QsIHByZWZpeClcbiAgICAgIGlmICh0cmFpbClcbiAgICAgICAgcHJlZml4ICs9ICcvJ1xuICAgIH1cbiAgfVxuXG4gIGlmIChwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInKVxuICAgIHByZWZpeCA9IHByZWZpeC5yZXBsYWNlKC9cXFxcL2csICcvJylcblxuICAvLyBNYXJrIHRoaXMgYXMgYSBtYXRjaFxuICB0aGlzLl9lbWl0TWF0Y2goaW5kZXgsIHByZWZpeClcbiAgY2IoKVxufVxuXG4vLyBSZXR1cm5zIGVpdGhlciAnRElSJywgJ0ZJTEUnLCBvciBmYWxzZVxuR2xvYi5wcm90b3R5cGUuX3N0YXQgPSBmdW5jdGlvbiAoZiwgY2IpIHtcbiAgdmFyIGFicyA9IHRoaXMuX21ha2VBYnMoZilcbiAgdmFyIG5lZWREaXIgPSBmLnNsaWNlKC0xKSA9PT0gJy8nXG5cbiAgaWYgKGYubGVuZ3RoID4gdGhpcy5tYXhMZW5ndGgpXG4gICAgcmV0dXJuIGNiKClcblxuICBpZiAoIXRoaXMuc3RhdCAmJiBvd25Qcm9wKHRoaXMuY2FjaGUsIGFicykpIHtcbiAgICB2YXIgYyA9IHRoaXMuY2FjaGVbYWJzXVxuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYykpXG4gICAgICBjID0gJ0RJUidcblxuICAgIC8vIEl0IGV4aXN0cywgYnV0IG1heWJlIG5vdCBob3cgd2UgbmVlZCBpdFxuICAgIGlmICghbmVlZERpciB8fCBjID09PSAnRElSJylcbiAgICAgIHJldHVybiBjYihudWxsLCBjKVxuXG4gICAgaWYgKG5lZWREaXIgJiYgYyA9PT0gJ0ZJTEUnKVxuICAgICAgcmV0dXJuIGNiKClcblxuICAgIC8vIG90aGVyd2lzZSB3ZSBoYXZlIHRvIHN0YXQsIGJlY2F1c2UgbWF5YmUgYz10cnVlXG4gICAgLy8gaWYgd2Uga25vdyBpdCBleGlzdHMsIGJ1dCBub3Qgd2hhdCBpdCBpcy5cbiAgfVxuXG4gIHZhciBleGlzdHNcbiAgdmFyIHN0YXQgPSB0aGlzLnN0YXRDYWNoZVthYnNdXG4gIGlmIChzdGF0ICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoc3RhdCA9PT0gZmFsc2UpXG4gICAgICByZXR1cm4gY2IobnVsbCwgc3RhdClcbiAgICBlbHNlIHtcbiAgICAgIHZhciB0eXBlID0gc3RhdC5pc0RpcmVjdG9yeSgpID8gJ0RJUicgOiAnRklMRSdcbiAgICAgIGlmIChuZWVkRGlyICYmIHR5cGUgPT09ICdGSUxFJylcbiAgICAgICAgcmV0dXJuIGNiKClcbiAgICAgIGVsc2VcbiAgICAgICAgcmV0dXJuIGNiKG51bGwsIHR5cGUsIHN0YXQpXG4gICAgfVxuICB9XG5cbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHZhciBzdGF0Y2IgPSBpbmZsaWdodCgnc3RhdFxcMCcgKyBhYnMsIGxzdGF0Y2JfKVxuICBpZiAoc3RhdGNiKVxuICAgIGZzLmxzdGF0KGFicywgc3RhdGNiKVxuXG4gIGZ1bmN0aW9uIGxzdGF0Y2JfIChlciwgbHN0YXQpIHtcbiAgICBpZiAobHN0YXQgJiYgbHN0YXQuaXNTeW1ib2xpY0xpbmsoKSkge1xuICAgICAgLy8gSWYgaXQncyBhIHN5bWxpbmssIHRoZW4gdHJlYXQgaXQgYXMgdGhlIHRhcmdldCwgdW5sZXNzXG4gICAgICAvLyB0aGUgdGFyZ2V0IGRvZXMgbm90IGV4aXN0LCB0aGVuIHRyZWF0IGl0IGFzIGEgZmlsZS5cbiAgICAgIHJldHVybiBmcy5zdGF0KGFicywgZnVuY3Rpb24gKGVyLCBzdGF0KSB7XG4gICAgICAgIGlmIChlcilcbiAgICAgICAgICBzZWxmLl9zdGF0MihmLCBhYnMsIG51bGwsIGxzdGF0LCBjYilcbiAgICAgICAgZWxzZVxuICAgICAgICAgIHNlbGYuX3N0YXQyKGYsIGFicywgZXIsIHN0YXQsIGNiKVxuICAgICAgfSlcbiAgICB9IGVsc2Uge1xuICAgICAgc2VsZi5fc3RhdDIoZiwgYWJzLCBlciwgbHN0YXQsIGNiKVxuICAgIH1cbiAgfVxufVxuXG5HbG9iLnByb3RvdHlwZS5fc3RhdDIgPSBmdW5jdGlvbiAoZiwgYWJzLCBlciwgc3RhdCwgY2IpIHtcbiAgaWYgKGVyICYmIChlci5jb2RlID09PSAnRU5PRU5UJyB8fCBlci5jb2RlID09PSAnRU5PVERJUicpKSB7XG4gICAgdGhpcy5zdGF0Q2FjaGVbYWJzXSA9IGZhbHNlXG4gICAgcmV0dXJuIGNiKClcbiAgfVxuXG4gIHZhciBuZWVkRGlyID0gZi5zbGljZSgtMSkgPT09ICcvJ1xuICB0aGlzLnN0YXRDYWNoZVthYnNdID0gc3RhdFxuXG4gIGlmIChhYnMuc2xpY2UoLTEpID09PSAnLycgJiYgc3RhdCAmJiAhc3RhdC5pc0RpcmVjdG9yeSgpKVxuICAgIHJldHVybiBjYihudWxsLCBmYWxzZSwgc3RhdClcblxuICB2YXIgYyA9IHRydWVcbiAgaWYgKHN0YXQpXG4gICAgYyA9IHN0YXQuaXNEaXJlY3RvcnkoKSA/ICdESVInIDogJ0ZJTEUnXG4gIHRoaXMuY2FjaGVbYWJzXSA9IHRoaXMuY2FjaGVbYWJzXSB8fCBjXG5cbiAgaWYgKG5lZWREaXIgJiYgYyA9PT0gJ0ZJTEUnKVxuICAgIHJldHVybiBjYigpXG5cbiAgcmV0dXJuIGNiKG51bGwsIGMsIHN0YXQpXG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGdsb2JTeW5jXG5nbG9iU3luYy5HbG9iU3luYyA9IEdsb2JTeW5jXG5cbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJylcbnZhciBycCA9IHJlcXVpcmUoJ2ZzLnJlYWxwYXRoJylcbnZhciBtaW5pbWF0Y2ggPSByZXF1aXJlKCdtaW5pbWF0Y2gnKVxudmFyIE1pbmltYXRjaCA9IG1pbmltYXRjaC5NaW5pbWF0Y2hcbnZhciBHbG9iID0gcmVxdWlyZSgnLi9nbG9iLmpzJykuR2xvYlxudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJylcbnZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0JylcbnZhciBpc0Fic29sdXRlID0gcmVxdWlyZSgncGF0aC1pcy1hYnNvbHV0ZScpXG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24uanMnKVxudmFyIGFscGhhc29ydCA9IGNvbW1vbi5hbHBoYXNvcnRcbnZhciBhbHBoYXNvcnRpID0gY29tbW9uLmFscGhhc29ydGlcbnZhciBzZXRvcHRzID0gY29tbW9uLnNldG9wdHNcbnZhciBvd25Qcm9wID0gY29tbW9uLm93blByb3BcbnZhciBjaGlsZHJlbklnbm9yZWQgPSBjb21tb24uY2hpbGRyZW5JZ25vcmVkXG52YXIgaXNJZ25vcmVkID0gY29tbW9uLmlzSWdub3JlZFxuXG5mdW5jdGlvbiBnbG9iU3luYyAocGF0dGVybiwgb3B0aW9ucykge1xuICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdmdW5jdGlvbicgfHwgYXJndW1lbnRzLmxlbmd0aCA9PT0gMylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdjYWxsYmFjayBwcm92aWRlZCB0byBzeW5jIGdsb2JcXG4nK1xuICAgICAgICAgICAgICAgICAgICAgICAgJ1NlZTogaHR0cHM6Ly9naXRodWIuY29tL2lzYWFjcy9ub2RlLWdsb2IvaXNzdWVzLzE2NycpXG5cbiAgcmV0dXJuIG5ldyBHbG9iU3luYyhwYXR0ZXJuLCBvcHRpb25zKS5mb3VuZFxufVxuXG5mdW5jdGlvbiBHbG9iU3luYyAocGF0dGVybiwgb3B0aW9ucykge1xuICBpZiAoIXBhdHRlcm4pXG4gICAgdGhyb3cgbmV3IEVycm9yKCdtdXN0IHByb3ZpZGUgcGF0dGVybicpXG5cbiAgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnZnVuY3Rpb24nIHx8IGFyZ3VtZW50cy5sZW5ndGggPT09IDMpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignY2FsbGJhY2sgcHJvdmlkZWQgdG8gc3luYyBnbG9iXFxuJytcbiAgICAgICAgICAgICAgICAgICAgICAgICdTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9pc2FhY3Mvbm9kZS1nbG9iL2lzc3Vlcy8xNjcnKVxuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBHbG9iU3luYykpXG4gICAgcmV0dXJuIG5ldyBHbG9iU3luYyhwYXR0ZXJuLCBvcHRpb25zKVxuXG4gIHNldG9wdHModGhpcywgcGF0dGVybiwgb3B0aW9ucylcblxuICBpZiAodGhpcy5ub3Byb2Nlc3MpXG4gICAgcmV0dXJuIHRoaXNcblxuICB2YXIgbiA9IHRoaXMubWluaW1hdGNoLnNldC5sZW5ndGhcbiAgdGhpcy5tYXRjaGVzID0gbmV3IEFycmF5KG4pXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgaSArKykge1xuICAgIHRoaXMuX3Byb2Nlc3ModGhpcy5taW5pbWF0Y2guc2V0W2ldLCBpLCBmYWxzZSlcbiAgfVxuICB0aGlzLl9maW5pc2goKVxufVxuXG5HbG9iU3luYy5wcm90b3R5cGUuX2ZpbmlzaCA9IGZ1bmN0aW9uICgpIHtcbiAgYXNzZXJ0KHRoaXMgaW5zdGFuY2VvZiBHbG9iU3luYylcbiAgaWYgKHRoaXMucmVhbHBhdGgpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXNcbiAgICB0aGlzLm1hdGNoZXMuZm9yRWFjaChmdW5jdGlvbiAobWF0Y2hzZXQsIGluZGV4KSB7XG4gICAgICB2YXIgc2V0ID0gc2VsZi5tYXRjaGVzW2luZGV4XSA9IE9iamVjdC5jcmVhdGUobnVsbClcbiAgICAgIGZvciAodmFyIHAgaW4gbWF0Y2hzZXQpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBwID0gc2VsZi5fbWFrZUFicyhwKVxuICAgICAgICAgIHZhciByZWFsID0gcnAucmVhbHBhdGhTeW5jKHAsIHNlbGYucmVhbHBhdGhDYWNoZSlcbiAgICAgICAgICBzZXRbcmVhbF0gPSB0cnVlXG4gICAgICAgIH0gY2F0Y2ggKGVyKSB7XG4gICAgICAgICAgaWYgKGVyLnN5c2NhbGwgPT09ICdzdGF0JylcbiAgICAgICAgICAgIHNldFtzZWxmLl9tYWtlQWJzKHApXSA9IHRydWVcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICB0aHJvdyBlclxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSlcbiAgfVxuICBjb21tb24uZmluaXNoKHRoaXMpXG59XG5cblxuR2xvYlN5bmMucHJvdG90eXBlLl9wcm9jZXNzID0gZnVuY3Rpb24gKHBhdHRlcm4sIGluZGV4LCBpbkdsb2JTdGFyKSB7XG4gIGFzc2VydCh0aGlzIGluc3RhbmNlb2YgR2xvYlN5bmMpXG5cbiAgLy8gR2V0IHRoZSBmaXJzdCBbbl0gcGFydHMgb2YgcGF0dGVybiB0aGF0IGFyZSBhbGwgc3RyaW5ncy5cbiAgdmFyIG4gPSAwXG4gIHdoaWxlICh0eXBlb2YgcGF0dGVybltuXSA9PT0gJ3N0cmluZycpIHtcbiAgICBuICsrXG4gIH1cbiAgLy8gbm93IG4gaXMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvbmUgdGhhdCBpcyAqbm90KiBhIHN0cmluZy5cblxuICAvLyBTZWUgaWYgdGhlcmUncyBhbnl0aGluZyBlbHNlXG4gIHZhciBwcmVmaXhcbiAgc3dpdGNoIChuKSB7XG4gICAgLy8gaWYgbm90LCB0aGVuIHRoaXMgaXMgcmF0aGVyIHNpbXBsZVxuICAgIGNhc2UgcGF0dGVybi5sZW5ndGg6XG4gICAgICB0aGlzLl9wcm9jZXNzU2ltcGxlKHBhdHRlcm4uam9pbignLycpLCBpbmRleClcbiAgICAgIHJldHVyblxuXG4gICAgY2FzZSAwOlxuICAgICAgLy8gcGF0dGVybiAqc3RhcnRzKiB3aXRoIHNvbWUgbm9uLXRyaXZpYWwgaXRlbS5cbiAgICAgIC8vIGdvaW5nIHRvIHJlYWRkaXIoY3dkKSwgYnV0IG5vdCBpbmNsdWRlIHRoZSBwcmVmaXggaW4gbWF0Y2hlcy5cbiAgICAgIHByZWZpeCA9IG51bGxcbiAgICAgIGJyZWFrXG5cbiAgICBkZWZhdWx0OlxuICAgICAgLy8gcGF0dGVybiBoYXMgc29tZSBzdHJpbmcgYml0cyBpbiB0aGUgZnJvbnQuXG4gICAgICAvLyB3aGF0ZXZlciBpdCBzdGFydHMgd2l0aCwgd2hldGhlciB0aGF0J3MgJ2Fic29sdXRlJyBsaWtlIC9mb28vYmFyLFxuICAgICAgLy8gb3IgJ3JlbGF0aXZlJyBsaWtlICcuLi9iYXonXG4gICAgICBwcmVmaXggPSBwYXR0ZXJuLnNsaWNlKDAsIG4pLmpvaW4oJy8nKVxuICAgICAgYnJlYWtcbiAgfVxuXG4gIHZhciByZW1haW4gPSBwYXR0ZXJuLnNsaWNlKG4pXG5cbiAgLy8gZ2V0IHRoZSBsaXN0IG9mIGVudHJpZXMuXG4gIHZhciByZWFkXG4gIGlmIChwcmVmaXggPT09IG51bGwpXG4gICAgcmVhZCA9ICcuJ1xuICBlbHNlIGlmIChpc0Fic29sdXRlKHByZWZpeCkgfHwgaXNBYnNvbHV0ZShwYXR0ZXJuLmpvaW4oJy8nKSkpIHtcbiAgICBpZiAoIXByZWZpeCB8fCAhaXNBYnNvbHV0ZShwcmVmaXgpKVxuICAgICAgcHJlZml4ID0gJy8nICsgcHJlZml4XG4gICAgcmVhZCA9IHByZWZpeFxuICB9IGVsc2VcbiAgICByZWFkID0gcHJlZml4XG5cbiAgdmFyIGFicyA9IHRoaXMuX21ha2VBYnMocmVhZClcblxuICAvL2lmIGlnbm9yZWQsIHNraXAgcHJvY2Vzc2luZ1xuICBpZiAoY2hpbGRyZW5JZ25vcmVkKHRoaXMsIHJlYWQpKVxuICAgIHJldHVyblxuXG4gIHZhciBpc0dsb2JTdGFyID0gcmVtYWluWzBdID09PSBtaW5pbWF0Y2guR0xPQlNUQVJcbiAgaWYgKGlzR2xvYlN0YXIpXG4gICAgdGhpcy5fcHJvY2Vzc0dsb2JTdGFyKHByZWZpeCwgcmVhZCwgYWJzLCByZW1haW4sIGluZGV4LCBpbkdsb2JTdGFyKVxuICBlbHNlXG4gICAgdGhpcy5fcHJvY2Vzc1JlYWRkaXIocHJlZml4LCByZWFkLCBhYnMsIHJlbWFpbiwgaW5kZXgsIGluR2xvYlN0YXIpXG59XG5cblxuR2xvYlN5bmMucHJvdG90eXBlLl9wcm9jZXNzUmVhZGRpciA9IGZ1bmN0aW9uIChwcmVmaXgsIHJlYWQsIGFicywgcmVtYWluLCBpbmRleCwgaW5HbG9iU3Rhcikge1xuICB2YXIgZW50cmllcyA9IHRoaXMuX3JlYWRkaXIoYWJzLCBpbkdsb2JTdGFyKVxuXG4gIC8vIGlmIHRoZSBhYnMgaXNuJ3QgYSBkaXIsIHRoZW4gbm90aGluZyBjYW4gbWF0Y2ghXG4gIGlmICghZW50cmllcylcbiAgICByZXR1cm5cblxuICAvLyBJdCB3aWxsIG9ubHkgbWF0Y2ggZG90IGVudHJpZXMgaWYgaXQgc3RhcnRzIHdpdGggYSBkb3QsIG9yIGlmXG4gIC8vIGRvdCBpcyBzZXQuICBTdHVmZiBsaWtlIEAoLmZvb3wuYmFyKSBpc24ndCBhbGxvd2VkLlxuICB2YXIgcG4gPSByZW1haW5bMF1cbiAgdmFyIG5lZ2F0ZSA9ICEhdGhpcy5taW5pbWF0Y2gubmVnYXRlXG4gIHZhciByYXdHbG9iID0gcG4uX2dsb2JcbiAgdmFyIGRvdE9rID0gdGhpcy5kb3QgfHwgcmF3R2xvYi5jaGFyQXQoMCkgPT09ICcuJ1xuXG4gIHZhciBtYXRjaGVkRW50cmllcyA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZW50cmllcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBlID0gZW50cmllc1tpXVxuICAgIGlmIChlLmNoYXJBdCgwKSAhPT0gJy4nIHx8IGRvdE9rKSB7XG4gICAgICB2YXIgbVxuICAgICAgaWYgKG5lZ2F0ZSAmJiAhcHJlZml4KSB7XG4gICAgICAgIG0gPSAhZS5tYXRjaChwbilcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG0gPSBlLm1hdGNoKHBuKVxuICAgICAgfVxuICAgICAgaWYgKG0pXG4gICAgICAgIG1hdGNoZWRFbnRyaWVzLnB1c2goZSlcbiAgICB9XG4gIH1cblxuICB2YXIgbGVuID0gbWF0Y2hlZEVudHJpZXMubGVuZ3RoXG4gIC8vIElmIHRoZXJlIGFyZSBubyBtYXRjaGVkIGVudHJpZXMsIHRoZW4gbm90aGluZyBtYXRjaGVzLlxuICBpZiAobGVuID09PSAwKVxuICAgIHJldHVyblxuXG4gIC8vIGlmIHRoaXMgaXMgdGhlIGxhc3QgcmVtYWluaW5nIHBhdHRlcm4gYml0LCB0aGVuIG5vIG5lZWQgZm9yXG4gIC8vIGFuIGFkZGl0aW9uYWwgc3RhdCAqdW5sZXNzKiB0aGUgdXNlciBoYXMgc3BlY2lmaWVkIG1hcmsgb3JcbiAgLy8gc3RhdCBleHBsaWNpdGx5LiAgV2Uga25vdyB0aGV5IGV4aXN0LCBzaW5jZSByZWFkZGlyIHJldHVybmVkXG4gIC8vIHRoZW0uXG5cbiAgaWYgKHJlbWFpbi5sZW5ndGggPT09IDEgJiYgIXRoaXMubWFyayAmJiAhdGhpcy5zdGF0KSB7XG4gICAgaWYgKCF0aGlzLm1hdGNoZXNbaW5kZXhdKVxuICAgICAgdGhpcy5tYXRjaGVzW2luZGV4XSA9IE9iamVjdC5jcmVhdGUobnVsbClcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICsrKSB7XG4gICAgICB2YXIgZSA9IG1hdGNoZWRFbnRyaWVzW2ldXG4gICAgICBpZiAocHJlZml4KSB7XG4gICAgICAgIGlmIChwcmVmaXguc2xpY2UoLTEpICE9PSAnLycpXG4gICAgICAgICAgZSA9IHByZWZpeCArICcvJyArIGVcbiAgICAgICAgZWxzZVxuICAgICAgICAgIGUgPSBwcmVmaXggKyBlXG4gICAgICB9XG5cbiAgICAgIGlmIChlLmNoYXJBdCgwKSA9PT0gJy8nICYmICF0aGlzLm5vbW91bnQpIHtcbiAgICAgICAgZSA9IHBhdGguam9pbih0aGlzLnJvb3QsIGUpXG4gICAgICB9XG4gICAgICB0aGlzLl9lbWl0TWF0Y2goaW5kZXgsIGUpXG4gICAgfVxuICAgIC8vIFRoaXMgd2FzIHRoZSBsYXN0IG9uZSwgYW5kIG5vIHN0YXRzIHdlcmUgbmVlZGVkXG4gICAgcmV0dXJuXG4gIH1cblxuICAvLyBub3cgdGVzdCBhbGwgbWF0Y2hlZCBlbnRyaWVzIGFzIHN0YW5kLWlucyBmb3IgdGhhdCBwYXJ0XG4gIC8vIG9mIHRoZSBwYXR0ZXJuLlxuICByZW1haW4uc2hpZnQoKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArKykge1xuICAgIHZhciBlID0gbWF0Y2hlZEVudHJpZXNbaV1cbiAgICB2YXIgbmV3UGF0dGVyblxuICAgIGlmIChwcmVmaXgpXG4gICAgICBuZXdQYXR0ZXJuID0gW3ByZWZpeCwgZV1cbiAgICBlbHNlXG4gICAgICBuZXdQYXR0ZXJuID0gW2VdXG4gICAgdGhpcy5fcHJvY2VzcyhuZXdQYXR0ZXJuLmNvbmNhdChyZW1haW4pLCBpbmRleCwgaW5HbG9iU3RhcilcbiAgfVxufVxuXG5cbkdsb2JTeW5jLnByb3RvdHlwZS5fZW1pdE1hdGNoID0gZnVuY3Rpb24gKGluZGV4LCBlKSB7XG4gIGlmIChpc0lnbm9yZWQodGhpcywgZSkpXG4gICAgcmV0dXJuXG5cbiAgdmFyIGFicyA9IHRoaXMuX21ha2VBYnMoZSlcblxuICBpZiAodGhpcy5tYXJrKVxuICAgIGUgPSB0aGlzLl9tYXJrKGUpXG5cbiAgaWYgKHRoaXMuYWJzb2x1dGUpIHtcbiAgICBlID0gYWJzXG4gIH1cblxuICBpZiAodGhpcy5tYXRjaGVzW2luZGV4XVtlXSlcbiAgICByZXR1cm5cblxuICBpZiAodGhpcy5ub2Rpcikge1xuICAgIHZhciBjID0gdGhpcy5jYWNoZVthYnNdXG4gICAgaWYgKGMgPT09ICdESVInIHx8IEFycmF5LmlzQXJyYXkoYykpXG4gICAgICByZXR1cm5cbiAgfVxuXG4gIHRoaXMubWF0Y2hlc1tpbmRleF1bZV0gPSB0cnVlXG5cbiAgaWYgKHRoaXMuc3RhdClcbiAgICB0aGlzLl9zdGF0KGUpXG59XG5cblxuR2xvYlN5bmMucHJvdG90eXBlLl9yZWFkZGlySW5HbG9iU3RhciA9IGZ1bmN0aW9uIChhYnMpIHtcbiAgLy8gZm9sbG93IGFsbCBzeW1saW5rZWQgZGlyZWN0b3JpZXMgZm9yZXZlclxuICAvLyBqdXN0IHByb2NlZWQgYXMgaWYgdGhpcyBpcyBhIG5vbi1nbG9ic3RhciBzaXR1YXRpb25cbiAgaWYgKHRoaXMuZm9sbG93KVxuICAgIHJldHVybiB0aGlzLl9yZWFkZGlyKGFicywgZmFsc2UpXG5cbiAgdmFyIGVudHJpZXNcbiAgdmFyIGxzdGF0XG4gIHZhciBzdGF0XG4gIHRyeSB7XG4gICAgbHN0YXQgPSBmcy5sc3RhdFN5bmMoYWJzKVxuICB9IGNhdGNoIChlcikge1xuICAgIGlmIChlci5jb2RlID09PSAnRU5PRU5UJykge1xuICAgICAgLy8gbHN0YXQgZmFpbGVkLCBkb2Vzbid0IGV4aXN0XG4gICAgICByZXR1cm4gbnVsbFxuICAgIH1cbiAgfVxuXG4gIHZhciBpc1N5bSA9IGxzdGF0ICYmIGxzdGF0LmlzU3ltYm9saWNMaW5rKClcbiAgdGhpcy5zeW1saW5rc1thYnNdID0gaXNTeW1cblxuICAvLyBJZiBpdCdzIG5vdCBhIHN5bWxpbmsgb3IgYSBkaXIsIHRoZW4gaXQncyBkZWZpbml0ZWx5IGEgcmVndWxhciBmaWxlLlxuICAvLyBkb24ndCBib3RoZXIgZG9pbmcgYSByZWFkZGlyIGluIHRoYXQgY2FzZS5cbiAgaWYgKCFpc1N5bSAmJiBsc3RhdCAmJiAhbHN0YXQuaXNEaXJlY3RvcnkoKSlcbiAgICB0aGlzLmNhY2hlW2Fic10gPSAnRklMRSdcbiAgZWxzZVxuICAgIGVudHJpZXMgPSB0aGlzLl9yZWFkZGlyKGFicywgZmFsc2UpXG5cbiAgcmV0dXJuIGVudHJpZXNcbn1cblxuR2xvYlN5bmMucHJvdG90eXBlLl9yZWFkZGlyID0gZnVuY3Rpb24gKGFicywgaW5HbG9iU3Rhcikge1xuICB2YXIgZW50cmllc1xuXG4gIGlmIChpbkdsb2JTdGFyICYmICFvd25Qcm9wKHRoaXMuc3ltbGlua3MsIGFicykpXG4gICAgcmV0dXJuIHRoaXMuX3JlYWRkaXJJbkdsb2JTdGFyKGFicylcblxuICBpZiAob3duUHJvcCh0aGlzLmNhY2hlLCBhYnMpKSB7XG4gICAgdmFyIGMgPSB0aGlzLmNhY2hlW2Fic11cbiAgICBpZiAoIWMgfHwgYyA9PT0gJ0ZJTEUnKVxuICAgICAgcmV0dXJuIG51bGxcblxuICAgIGlmIChBcnJheS5pc0FycmF5KGMpKVxuICAgICAgcmV0dXJuIGNcbiAgfVxuXG4gIHRyeSB7XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRkaXJFbnRyaWVzKGFicywgZnMucmVhZGRpclN5bmMoYWJzKSlcbiAgfSBjYXRjaCAoZXIpIHtcbiAgICB0aGlzLl9yZWFkZGlyRXJyb3IoYWJzLCBlcilcbiAgICByZXR1cm4gbnVsbFxuICB9XG59XG5cbkdsb2JTeW5jLnByb3RvdHlwZS5fcmVhZGRpckVudHJpZXMgPSBmdW5jdGlvbiAoYWJzLCBlbnRyaWVzKSB7XG4gIC8vIGlmIHdlIGhhdmVuJ3QgYXNrZWQgdG8gc3RhdCBldmVyeXRoaW5nLCB0aGVuIGp1c3RcbiAgLy8gYXNzdW1lIHRoYXQgZXZlcnl0aGluZyBpbiB0aGVyZSBleGlzdHMsIHNvIHdlIGNhbiBhdm9pZFxuICAvLyBoYXZpbmcgdG8gc3RhdCBpdCBhIHNlY29uZCB0aW1lLlxuICBpZiAoIXRoaXMubWFyayAmJiAhdGhpcy5zdGF0KSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbnRyaWVzLmxlbmd0aDsgaSArKykge1xuICAgICAgdmFyIGUgPSBlbnRyaWVzW2ldXG4gICAgICBpZiAoYWJzID09PSAnLycpXG4gICAgICAgIGUgPSBhYnMgKyBlXG4gICAgICBlbHNlXG4gICAgICAgIGUgPSBhYnMgKyAnLycgKyBlXG4gICAgICB0aGlzLmNhY2hlW2VdID0gdHJ1ZVxuICAgIH1cbiAgfVxuXG4gIHRoaXMuY2FjaGVbYWJzXSA9IGVudHJpZXNcblxuICAvLyBtYXJrIGFuZCBjYWNoZSBkaXItbmVzc1xuICByZXR1cm4gZW50cmllc1xufVxuXG5HbG9iU3luYy5wcm90b3R5cGUuX3JlYWRkaXJFcnJvciA9IGZ1bmN0aW9uIChmLCBlcikge1xuICAvLyBoYW5kbGUgZXJyb3JzLCBhbmQgY2FjaGUgdGhlIGluZm9ybWF0aW9uXG4gIHN3aXRjaCAoZXIuY29kZSkge1xuICAgIGNhc2UgJ0VOT1RTVVAnOiAvLyBodHRwczovL2dpdGh1Yi5jb20vaXNhYWNzL25vZGUtZ2xvYi9pc3N1ZXMvMjA1XG4gICAgY2FzZSAnRU5PVERJUic6IC8vIHRvdGFsbHkgbm9ybWFsLiBtZWFucyBpdCAqZG9lcyogZXhpc3QuXG4gICAgICB2YXIgYWJzID0gdGhpcy5fbWFrZUFicyhmKVxuICAgICAgdGhpcy5jYWNoZVthYnNdID0gJ0ZJTEUnXG4gICAgICBpZiAoYWJzID09PSB0aGlzLmN3ZEFicykge1xuICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoZXIuY29kZSArICcgaW52YWxpZCBjd2QgJyArIHRoaXMuY3dkKVxuICAgICAgICBlcnJvci5wYXRoID0gdGhpcy5jd2RcbiAgICAgICAgZXJyb3IuY29kZSA9IGVyLmNvZGVcbiAgICAgICAgdGhyb3cgZXJyb3JcbiAgICAgIH1cbiAgICAgIGJyZWFrXG5cbiAgICBjYXNlICdFTk9FTlQnOiAvLyBub3QgdGVycmlibHkgdW51c3VhbFxuICAgIGNhc2UgJ0VMT09QJzpcbiAgICBjYXNlICdFTkFNRVRPT0xPTkcnOlxuICAgIGNhc2UgJ1VOS05PV04nOlxuICAgICAgdGhpcy5jYWNoZVt0aGlzLl9tYWtlQWJzKGYpXSA9IGZhbHNlXG4gICAgICBicmVha1xuXG4gICAgZGVmYXVsdDogLy8gc29tZSB1bnVzdWFsIGVycm9yLiAgVHJlYXQgYXMgZmFpbHVyZS5cbiAgICAgIHRoaXMuY2FjaGVbdGhpcy5fbWFrZUFicyhmKV0gPSBmYWxzZVxuICAgICAgaWYgKHRoaXMuc3RyaWN0KVxuICAgICAgICB0aHJvdyBlclxuICAgICAgaWYgKCF0aGlzLnNpbGVudClcbiAgICAgICAgY29uc29sZS5lcnJvcignZ2xvYiBlcnJvcicsIGVyKVxuICAgICAgYnJlYWtcbiAgfVxufVxuXG5HbG9iU3luYy5wcm90b3R5cGUuX3Byb2Nlc3NHbG9iU3RhciA9IGZ1bmN0aW9uIChwcmVmaXgsIHJlYWQsIGFicywgcmVtYWluLCBpbmRleCwgaW5HbG9iU3Rhcikge1xuXG4gIHZhciBlbnRyaWVzID0gdGhpcy5fcmVhZGRpcihhYnMsIGluR2xvYlN0YXIpXG5cbiAgLy8gbm8gZW50cmllcyBtZWFucyBub3QgYSBkaXIsIHNvIGl0IGNhbiBuZXZlciBoYXZlIG1hdGNoZXNcbiAgLy8gZm9vLnR4dC8qKiBkb2Vzbid0IG1hdGNoIGZvby50eHRcbiAgaWYgKCFlbnRyaWVzKVxuICAgIHJldHVyblxuXG4gIC8vIHRlc3Qgd2l0aG91dCB0aGUgZ2xvYnN0YXIsIGFuZCB3aXRoIGV2ZXJ5IGNoaWxkIGJvdGggYmVsb3dcbiAgLy8gYW5kIHJlcGxhY2luZyB0aGUgZ2xvYnN0YXIuXG4gIHZhciByZW1haW5XaXRob3V0R2xvYlN0YXIgPSByZW1haW4uc2xpY2UoMSlcbiAgdmFyIGdzcHJlZiA9IHByZWZpeCA/IFsgcHJlZml4IF0gOiBbXVxuICB2YXIgbm9HbG9iU3RhciA9IGdzcHJlZi5jb25jYXQocmVtYWluV2l0aG91dEdsb2JTdGFyKVxuXG4gIC8vIHRoZSBub0dsb2JTdGFyIHBhdHRlcm4gZXhpdHMgdGhlIGluR2xvYlN0YXIgc3RhdGVcbiAgdGhpcy5fcHJvY2Vzcyhub0dsb2JTdGFyLCBpbmRleCwgZmFsc2UpXG5cbiAgdmFyIGxlbiA9IGVudHJpZXMubGVuZ3RoXG4gIHZhciBpc1N5bSA9IHRoaXMuc3ltbGlua3NbYWJzXVxuXG4gIC8vIElmIGl0J3MgYSBzeW1saW5rLCBhbmQgd2UncmUgaW4gYSBnbG9ic3RhciwgdGhlbiBzdG9wXG4gIGlmIChpc1N5bSAmJiBpbkdsb2JTdGFyKVxuICAgIHJldHVyblxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICB2YXIgZSA9IGVudHJpZXNbaV1cbiAgICBpZiAoZS5jaGFyQXQoMCkgPT09ICcuJyAmJiAhdGhpcy5kb3QpXG4gICAgICBjb250aW51ZVxuXG4gICAgLy8gdGhlc2UgdHdvIGNhc2VzIGVudGVyIHRoZSBpbkdsb2JTdGFyIHN0YXRlXG4gICAgdmFyIGluc3RlYWQgPSBnc3ByZWYuY29uY2F0KGVudHJpZXNbaV0sIHJlbWFpbldpdGhvdXRHbG9iU3RhcilcbiAgICB0aGlzLl9wcm9jZXNzKGluc3RlYWQsIGluZGV4LCB0cnVlKVxuXG4gICAgdmFyIGJlbG93ID0gZ3NwcmVmLmNvbmNhdChlbnRyaWVzW2ldLCByZW1haW4pXG4gICAgdGhpcy5fcHJvY2VzcyhiZWxvdywgaW5kZXgsIHRydWUpXG4gIH1cbn1cblxuR2xvYlN5bmMucHJvdG90eXBlLl9wcm9jZXNzU2ltcGxlID0gZnVuY3Rpb24gKHByZWZpeCwgaW5kZXgpIHtcbiAgLy8gWFhYIHJldmlldyB0aGlzLiAgU2hvdWxkbid0IGl0IGJlIGRvaW5nIHRoZSBtb3VudGluZyBldGNcbiAgLy8gYmVmb3JlIGRvaW5nIHN0YXQ/ICBraW5kYSB3ZWlyZD9cbiAgdmFyIGV4aXN0cyA9IHRoaXMuX3N0YXQocHJlZml4KVxuXG4gIGlmICghdGhpcy5tYXRjaGVzW2luZGV4XSlcbiAgICB0aGlzLm1hdGNoZXNbaW5kZXhdID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuXG4gIC8vIElmIGl0IGRvZXNuJ3QgZXhpc3QsIHRoZW4ganVzdCBtYXJrIHRoZSBsYWNrIG9mIHJlc3VsdHNcbiAgaWYgKCFleGlzdHMpXG4gICAgcmV0dXJuXG5cbiAgaWYgKHByZWZpeCAmJiBpc0Fic29sdXRlKHByZWZpeCkgJiYgIXRoaXMubm9tb3VudCkge1xuICAgIHZhciB0cmFpbCA9IC9bXFwvXFxcXF0kLy50ZXN0KHByZWZpeClcbiAgICBpZiAocHJlZml4LmNoYXJBdCgwKSA9PT0gJy8nKSB7XG4gICAgICBwcmVmaXggPSBwYXRoLmpvaW4odGhpcy5yb290LCBwcmVmaXgpXG4gICAgfSBlbHNlIHtcbiAgICAgIHByZWZpeCA9IHBhdGgucmVzb2x2ZSh0aGlzLnJvb3QsIHByZWZpeClcbiAgICAgIGlmICh0cmFpbClcbiAgICAgICAgcHJlZml4ICs9ICcvJ1xuICAgIH1cbiAgfVxuXG4gIGlmIChwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInKVxuICAgIHByZWZpeCA9IHByZWZpeC5yZXBsYWNlKC9cXFxcL2csICcvJylcblxuICAvLyBNYXJrIHRoaXMgYXMgYSBtYXRjaFxuICB0aGlzLl9lbWl0TWF0Y2goaW5kZXgsIHByZWZpeClcbn1cblxuLy8gUmV0dXJucyBlaXRoZXIgJ0RJUicsICdGSUxFJywgb3IgZmFsc2Vcbkdsb2JTeW5jLnByb3RvdHlwZS5fc3RhdCA9IGZ1bmN0aW9uIChmKSB7XG4gIHZhciBhYnMgPSB0aGlzLl9tYWtlQWJzKGYpXG4gIHZhciBuZWVkRGlyID0gZi5zbGljZSgtMSkgPT09ICcvJ1xuXG4gIGlmIChmLmxlbmd0aCA+IHRoaXMubWF4TGVuZ3RoKVxuICAgIHJldHVybiBmYWxzZVxuXG4gIGlmICghdGhpcy5zdGF0ICYmIG93blByb3AodGhpcy5jYWNoZSwgYWJzKSkge1xuICAgIHZhciBjID0gdGhpcy5jYWNoZVthYnNdXG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShjKSlcbiAgICAgIGMgPSAnRElSJ1xuXG4gICAgLy8gSXQgZXhpc3RzLCBidXQgbWF5YmUgbm90IGhvdyB3ZSBuZWVkIGl0XG4gICAgaWYgKCFuZWVkRGlyIHx8IGMgPT09ICdESVInKVxuICAgICAgcmV0dXJuIGNcblxuICAgIGlmIChuZWVkRGlyICYmIGMgPT09ICdGSUxFJylcbiAgICAgIHJldHVybiBmYWxzZVxuXG4gICAgLy8gb3RoZXJ3aXNlIHdlIGhhdmUgdG8gc3RhdCwgYmVjYXVzZSBtYXliZSBjPXRydWVcbiAgICAvLyBpZiB3ZSBrbm93IGl0IGV4aXN0cywgYnV0IG5vdCB3aGF0IGl0IGlzLlxuICB9XG5cbiAgdmFyIGV4aXN0c1xuICB2YXIgc3RhdCA9IHRoaXMuc3RhdENhY2hlW2Fic11cbiAgaWYgKCFzdGF0KSB7XG4gICAgdmFyIGxzdGF0XG4gICAgdHJ5IHtcbiAgICAgIGxzdGF0ID0gZnMubHN0YXRTeW5jKGFicylcbiAgICB9IGNhdGNoIChlcikge1xuICAgICAgaWYgKGVyICYmIChlci5jb2RlID09PSAnRU5PRU5UJyB8fCBlci5jb2RlID09PSAnRU5PVERJUicpKSB7XG4gICAgICAgIHRoaXMuc3RhdENhY2hlW2Fic10gPSBmYWxzZVxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobHN0YXQgJiYgbHN0YXQuaXNTeW1ib2xpY0xpbmsoKSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgc3RhdCA9IGZzLnN0YXRTeW5jKGFicylcbiAgICAgIH0gY2F0Y2ggKGVyKSB7XG4gICAgICAgIHN0YXQgPSBsc3RhdFxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ID0gbHN0YXRcbiAgICB9XG4gIH1cblxuICB0aGlzLnN0YXRDYWNoZVthYnNdID0gc3RhdFxuXG4gIHZhciBjID0gdHJ1ZVxuICBpZiAoc3RhdClcbiAgICBjID0gc3RhdC5pc0RpcmVjdG9yeSgpID8gJ0RJUicgOiAnRklMRSdcblxuICB0aGlzLmNhY2hlW2Fic10gPSB0aGlzLmNhY2hlW2Fic10gfHwgY1xuXG4gIGlmIChuZWVkRGlyICYmIGMgPT09ICdGSUxFJylcbiAgICByZXR1cm4gZmFsc2VcblxuICByZXR1cm4gY1xufVxuXG5HbG9iU3luYy5wcm90b3R5cGUuX21hcmsgPSBmdW5jdGlvbiAocCkge1xuICByZXR1cm4gY29tbW9uLm1hcmsodGhpcywgcClcbn1cblxuR2xvYlN5bmMucHJvdG90eXBlLl9tYWtlQWJzID0gZnVuY3Rpb24gKGYpIHtcbiAgcmV0dXJuIGNvbW1vbi5tYWtlQWJzKHRoaXMsIGYpXG59XG4iLCJ2YXIgd3JhcHB5ID0gcmVxdWlyZSgnd3JhcHB5JylcbnZhciByZXFzID0gT2JqZWN0LmNyZWF0ZShudWxsKVxudmFyIG9uY2UgPSByZXF1aXJlKCdvbmNlJylcblxubW9kdWxlLmV4cG9ydHMgPSB3cmFwcHkoaW5mbGlnaHQpXG5cbmZ1bmN0aW9uIGluZmxpZ2h0IChrZXksIGNiKSB7XG4gIGlmIChyZXFzW2tleV0pIHtcbiAgICByZXFzW2tleV0ucHVzaChjYilcbiAgICByZXR1cm4gbnVsbFxuICB9IGVsc2Uge1xuICAgIHJlcXNba2V5XSA9IFtjYl1cbiAgICByZXR1cm4gbWFrZXJlcyhrZXkpXG4gIH1cbn1cblxuZnVuY3Rpb24gbWFrZXJlcyAoa2V5KSB7XG4gIHJldHVybiBvbmNlKGZ1bmN0aW9uIFJFUyAoKSB7XG4gICAgdmFyIGNicyA9IHJlcXNba2V5XVxuICAgIHZhciBsZW4gPSBjYnMubGVuZ3RoXG4gICAgdmFyIGFyZ3MgPSBzbGljZShhcmd1bWVudHMpXG5cbiAgICAvLyBYWFggSXQncyBzb21ld2hhdCBhbWJpZ3VvdXMgd2hldGhlciBhIG5ldyBjYWxsYmFjayBhZGRlZCBpbiB0aGlzXG4gICAgLy8gcGFzcyBzaG91bGQgYmUgcXVldWVkIGZvciBsYXRlciBleGVjdXRpb24gaWYgc29tZXRoaW5nIGluIHRoZVxuICAgIC8vIGxpc3Qgb2YgY2FsbGJhY2tzIHRocm93cywgb3IgaWYgaXQgc2hvdWxkIGp1c3QgYmUgZGlzY2FyZGVkLlxuICAgIC8vIEhvd2V2ZXIsIGl0J3Mgc3VjaCBhbiBlZGdlIGNhc2UgdGhhdCBpdCBoYXJkbHkgbWF0dGVycywgYW5kIGVpdGhlclxuICAgIC8vIGNob2ljZSBpcyBsaWtlbHkgYXMgc3VycHJpc2luZyBhcyB0aGUgb3RoZXIuXG4gICAgLy8gQXMgaXQgaGFwcGVucywgd2UgZG8gZ28gYWhlYWQgYW5kIHNjaGVkdWxlIGl0IGZvciBsYXRlciBleGVjdXRpb24uXG4gICAgdHJ5IHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgY2JzW2ldLmFwcGx5KG51bGwsIGFyZ3MpXG4gICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGlmIChjYnMubGVuZ3RoID4gbGVuKSB7XG4gICAgICAgIC8vIGFkZGVkIG1vcmUgaW4gdGhlIGludGVyaW0uXG4gICAgICAgIC8vIGRlLXphbGdvLCBqdXN0IGluIGNhc2UsIGJ1dCBkb24ndCBjYWxsIGFnYWluLlxuICAgICAgICBjYnMuc3BsaWNlKDAsIGxlbilcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgUkVTLmFwcGx5KG51bGwsIGFyZ3MpXG4gICAgICAgIH0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWxldGUgcmVxc1trZXldXG4gICAgICB9XG4gICAgfVxuICB9KVxufVxuXG5mdW5jdGlvbiBzbGljZSAoYXJncykge1xuICB2YXIgbGVuZ3RoID0gYXJncy5sZW5ndGhcbiAgdmFyIGFycmF5ID0gW11cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSBhcnJheVtpXSA9IGFyZ3NbaV1cbiAgcmV0dXJuIGFycmF5XG59XG4iLCJ0cnkge1xuICB2YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgaWYgKHR5cGVvZiB1dGlsLmluaGVyaXRzICE9PSAnZnVuY3Rpb24nKSB0aHJvdyAnJztcbiAgbW9kdWxlLmV4cG9ydHMgPSB1dGlsLmluaGVyaXRzO1xufSBjYXRjaCAoZSkge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vaW5oZXJpdHNfYnJvd3Nlci5qcycpO1xufVxuIiwiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBpZiAoc3VwZXJDdG9yKSB7XG4gICAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKClcbiAgICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICAgIH1cbiAgfVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnRhZ1Byb3BlcnR5ID0gZXhwb3J0cy50YWdQYXJhbWV0ZXIgPSBleHBvcnRzLmRlY29yYXRlID0gdm9pZCAwO1xudmFyIEVSUk9SX01TR1MgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2Vycm9yX21zZ3NcIik7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xuZnVuY3Rpb24gdGFnUGFyYW1ldGVyKGFubm90YXRpb25UYXJnZXQsIHByb3BlcnR5TmFtZSwgcGFyYW1ldGVySW5kZXgsIG1ldGFkYXRhKSB7XG4gICAgdmFyIG1ldGFkYXRhS2V5ID0gTUVUQURBVEFfS0VZLlRBR0dFRDtcbiAgICBfdGFnUGFyYW1ldGVyT3JQcm9wZXJ0eShtZXRhZGF0YUtleSwgYW5ub3RhdGlvblRhcmdldCwgcHJvcGVydHlOYW1lLCBtZXRhZGF0YSwgcGFyYW1ldGVySW5kZXgpO1xufVxuZXhwb3J0cy50YWdQYXJhbWV0ZXIgPSB0YWdQYXJhbWV0ZXI7XG5mdW5jdGlvbiB0YWdQcm9wZXJ0eShhbm5vdGF0aW9uVGFyZ2V0LCBwcm9wZXJ0eU5hbWUsIG1ldGFkYXRhKSB7XG4gICAgdmFyIG1ldGFkYXRhS2V5ID0gTUVUQURBVEFfS0VZLlRBR0dFRF9QUk9QO1xuICAgIF90YWdQYXJhbWV0ZXJPclByb3BlcnR5KG1ldGFkYXRhS2V5LCBhbm5vdGF0aW9uVGFyZ2V0LmNvbnN0cnVjdG9yLCBwcm9wZXJ0eU5hbWUsIG1ldGFkYXRhKTtcbn1cbmV4cG9ydHMudGFnUHJvcGVydHkgPSB0YWdQcm9wZXJ0eTtcbmZ1bmN0aW9uIF90YWdQYXJhbWV0ZXJPclByb3BlcnR5KG1ldGFkYXRhS2V5LCBhbm5vdGF0aW9uVGFyZ2V0LCBwcm9wZXJ0eU5hbWUsIG1ldGFkYXRhLCBwYXJhbWV0ZXJJbmRleCkge1xuICAgIHZhciBwYXJhbXNPclByb3BlcnRpZXNNZXRhZGF0YSA9IHt9O1xuICAgIHZhciBpc1BhcmFtZXRlckRlY29yYXRvciA9ICh0eXBlb2YgcGFyYW1ldGVySW5kZXggPT09IFwibnVtYmVyXCIpO1xuICAgIHZhciBrZXkgPSAocGFyYW1ldGVySW5kZXggIT09IHVuZGVmaW5lZCAmJiBpc1BhcmFtZXRlckRlY29yYXRvcikgPyBwYXJhbWV0ZXJJbmRleC50b1N0cmluZygpIDogcHJvcGVydHlOYW1lO1xuICAgIGlmIChpc1BhcmFtZXRlckRlY29yYXRvciAmJiBwcm9wZXJ0eU5hbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTVNHUy5JTlZBTElEX0RFQ09SQVRPUl9PUEVSQVRJT04pO1xuICAgIH1cbiAgICBpZiAoUmVmbGVjdC5oYXNPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgYW5ub3RhdGlvblRhcmdldCkpIHtcbiAgICAgICAgcGFyYW1zT3JQcm9wZXJ0aWVzTWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKG1ldGFkYXRhS2V5LCBhbm5vdGF0aW9uVGFyZ2V0KTtcbiAgICB9XG4gICAgdmFyIHBhcmFtT3JQcm9wZXJ0eU1ldGFkYXRhID0gcGFyYW1zT3JQcm9wZXJ0aWVzTWV0YWRhdGFba2V5XTtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkocGFyYW1PclByb3BlcnR5TWV0YWRhdGEpKSB7XG4gICAgICAgIHBhcmFtT3JQcm9wZXJ0eU1ldGFkYXRhID0gW107XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBmb3IgKHZhciBfaSA9IDAsIHBhcmFtT3JQcm9wZXJ0eU1ldGFkYXRhXzEgPSBwYXJhbU9yUHJvcGVydHlNZXRhZGF0YTsgX2kgPCBwYXJhbU9yUHJvcGVydHlNZXRhZGF0YV8xLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgdmFyIG0gPSBwYXJhbU9yUHJvcGVydHlNZXRhZGF0YV8xW19pXTtcbiAgICAgICAgICAgIGlmIChtLmtleSA9PT0gbWV0YWRhdGEua2V5KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuRFVQTElDQVRFRF9NRVRBREFUQSArIFwiIFwiICsgbS5rZXkudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcGFyYW1PclByb3BlcnR5TWV0YWRhdGEucHVzaChtZXRhZGF0YSk7XG4gICAgcGFyYW1zT3JQcm9wZXJ0aWVzTWV0YWRhdGFba2V5XSA9IHBhcmFtT3JQcm9wZXJ0eU1ldGFkYXRhO1xuICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEobWV0YWRhdGFLZXksIHBhcmFtc09yUHJvcGVydGllc01ldGFkYXRhLCBhbm5vdGF0aW9uVGFyZ2V0KTtcbn1cbmZ1bmN0aW9uIF9kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQpIHtcbiAgICBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCk7XG59XG5mdW5jdGlvbiBfcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9O1xufVxuZnVuY3Rpb24gZGVjb3JhdGUoZGVjb3JhdG9yLCB0YXJnZXQsIHBhcmFtZXRlckluZGV4KSB7XG4gICAgaWYgKHR5cGVvZiBwYXJhbWV0ZXJJbmRleCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICBfZGVjb3JhdGUoW19wYXJhbShwYXJhbWV0ZXJJbmRleCwgZGVjb3JhdG9yKV0sIHRhcmdldCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBwYXJhbWV0ZXJJbmRleCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICBSZWZsZWN0LmRlY29yYXRlKFtkZWNvcmF0b3JdLCB0YXJnZXQsIHBhcmFtZXRlckluZGV4KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIF9kZWNvcmF0ZShbZGVjb3JhdG9yXSwgdGFyZ2V0KTtcbiAgICB9XG59XG5leHBvcnRzLmRlY29yYXRlID0gZGVjb3JhdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWNvcmF0b3JfdXRpbHMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmluamVjdCA9IGV4cG9ydHMuTGF6eVNlcnZpY2VJZGVudGlmZXIgPSB2b2lkIDA7XG52YXIgZXJyb3JfbXNnc18xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9lcnJvcl9tc2dzXCIpO1xudmFyIE1FVEFEQVRBX0tFWSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbWV0YWRhdGFfa2V5c1wiKTtcbnZhciBtZXRhZGF0YV8xID0gcmVxdWlyZShcIi4uL3BsYW5uaW5nL21ldGFkYXRhXCIpO1xudmFyIGRlY29yYXRvcl91dGlsc18xID0gcmVxdWlyZShcIi4vZGVjb3JhdG9yX3V0aWxzXCIpO1xudmFyIExhenlTZXJ2aWNlSWRlbnRpZmVyID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBMYXp5U2VydmljZUlkZW50aWZlcihjYikge1xuICAgICAgICB0aGlzLl9jYiA9IGNiO1xuICAgIH1cbiAgICBMYXp5U2VydmljZUlkZW50aWZlci5wcm90b3R5cGUudW53cmFwID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2IoKTtcbiAgICB9O1xuICAgIHJldHVybiBMYXp5U2VydmljZUlkZW50aWZlcjtcbn0oKSk7XG5leHBvcnRzLkxhenlTZXJ2aWNlSWRlbnRpZmVyID0gTGF6eVNlcnZpY2VJZGVudGlmZXI7XG5mdW5jdGlvbiBpbmplY3Qoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwgdGFyZ2V0S2V5LCBpbmRleCkge1xuICAgICAgICBpZiAoc2VydmljZUlkZW50aWZpZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yX21zZ3NfMS5VTkRFRklORURfSU5KRUNUX0FOTk9UQVRJT04odGFyZ2V0Lm5hbWUpKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbWV0YWRhdGEgPSBuZXcgbWV0YWRhdGFfMS5NZXRhZGF0YShNRVRBREFUQV9LRVkuSU5KRUNUX1RBRywgc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICBpZiAodHlwZW9mIGluZGV4ID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICBkZWNvcmF0b3JfdXRpbHNfMS50YWdQYXJhbWV0ZXIodGFyZ2V0LCB0YXJnZXRLZXksIGluZGV4LCBtZXRhZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkZWNvcmF0b3JfdXRpbHNfMS50YWdQcm9wZXJ0eSh0YXJnZXQsIHRhcmdldEtleSwgbWV0YWRhdGEpO1xuICAgICAgICB9XG4gICAgfTtcbn1cbmV4cG9ydHMuaW5qZWN0ID0gaW5qZWN0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5qZWN0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5pbmplY3RhYmxlID0gdm9pZCAwO1xudmFyIEVSUk9SU19NU0dTID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9lcnJvcl9tc2dzXCIpO1xudmFyIE1FVEFEQVRBX0tFWSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbWV0YWRhdGFfa2V5c1wiKTtcbmZ1bmN0aW9uIGluamVjdGFibGUoKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQpIHtcbiAgICAgICAgaWYgKFJlZmxlY3QuaGFzT3duTWV0YWRhdGEoTUVUQURBVEFfS0VZLlBBUkFNX1RZUEVTLCB0YXJnZXQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JTX01TR1MuRFVQTElDQVRFRF9JTkpFQ1RBQkxFX0RFQ09SQVRPUik7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHR5cGVzID0gUmVmbGVjdC5nZXRNZXRhZGF0YShNRVRBREFUQV9LRVkuREVTSUdOX1BBUkFNX1RZUEVTLCB0YXJnZXQpIHx8IFtdO1xuICAgICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKE1FVEFEQVRBX0tFWS5QQVJBTV9UWVBFUywgdHlwZXMsIHRhcmdldCk7XG4gICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfTtcbn1cbmV4cG9ydHMuaW5qZWN0YWJsZSA9IGluamVjdGFibGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmplY3RhYmxlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5tdWx0aUluamVjdCA9IHZvaWQgMDtcbnZhciBNRVRBREFUQV9LRVkgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG52YXIgbWV0YWRhdGFfMSA9IHJlcXVpcmUoXCIuLi9wbGFubmluZy9tZXRhZGF0YVwiKTtcbnZhciBkZWNvcmF0b3JfdXRpbHNfMSA9IHJlcXVpcmUoXCIuL2RlY29yYXRvcl91dGlsc1wiKTtcbmZ1bmN0aW9uIG11bHRpSW5qZWN0KHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIHRhcmdldEtleSwgaW5kZXgpIHtcbiAgICAgICAgdmFyIG1ldGFkYXRhID0gbmV3IG1ldGFkYXRhXzEuTWV0YWRhdGEoTUVUQURBVEFfS0VZLk1VTFRJX0lOSkVDVF9UQUcsIHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgaWYgKHR5cGVvZiBpbmRleCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgZGVjb3JhdG9yX3V0aWxzXzEudGFnUGFyYW1ldGVyKHRhcmdldCwgdGFyZ2V0S2V5LCBpbmRleCwgbWV0YWRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGVjb3JhdG9yX3V0aWxzXzEudGFnUHJvcGVydHkodGFyZ2V0LCB0YXJnZXRLZXksIG1ldGFkYXRhKTtcbiAgICAgICAgfVxuICAgIH07XG59XG5leHBvcnRzLm11bHRpSW5qZWN0ID0gbXVsdGlJbmplY3Q7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tdWx0aV9pbmplY3QuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLm5hbWVkID0gdm9pZCAwO1xudmFyIE1FVEFEQVRBX0tFWSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbWV0YWRhdGFfa2V5c1wiKTtcbnZhciBtZXRhZGF0YV8xID0gcmVxdWlyZShcIi4uL3BsYW5uaW5nL21ldGFkYXRhXCIpO1xudmFyIGRlY29yYXRvcl91dGlsc18xID0gcmVxdWlyZShcIi4vZGVjb3JhdG9yX3V0aWxzXCIpO1xuZnVuY3Rpb24gbmFtZWQobmFtZSkge1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCB0YXJnZXRLZXksIGluZGV4KSB7XG4gICAgICAgIHZhciBtZXRhZGF0YSA9IG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKE1FVEFEQVRBX0tFWS5OQU1FRF9UQUcsIG5hbWUpO1xuICAgICAgICBpZiAodHlwZW9mIGluZGV4ID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICBkZWNvcmF0b3JfdXRpbHNfMS50YWdQYXJhbWV0ZXIodGFyZ2V0LCB0YXJnZXRLZXksIGluZGV4LCBtZXRhZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkZWNvcmF0b3JfdXRpbHNfMS50YWdQcm9wZXJ0eSh0YXJnZXQsIHRhcmdldEtleSwgbWV0YWRhdGEpO1xuICAgICAgICB9XG4gICAgfTtcbn1cbmV4cG9ydHMubmFtZWQgPSBuYW1lZDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hbWVkLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5vcHRpb25hbCA9IHZvaWQgMDtcbnZhciBNRVRBREFUQV9LRVkgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG52YXIgbWV0YWRhdGFfMSA9IHJlcXVpcmUoXCIuLi9wbGFubmluZy9tZXRhZGF0YVwiKTtcbnZhciBkZWNvcmF0b3JfdXRpbHNfMSA9IHJlcXVpcmUoXCIuL2RlY29yYXRvcl91dGlsc1wiKTtcbmZ1bmN0aW9uIG9wdGlvbmFsKCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCB0YXJnZXRLZXksIGluZGV4KSB7XG4gICAgICAgIHZhciBtZXRhZGF0YSA9IG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKE1FVEFEQVRBX0tFWS5PUFRJT05BTF9UQUcsIHRydWUpO1xuICAgICAgICBpZiAodHlwZW9mIGluZGV4ID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICBkZWNvcmF0b3JfdXRpbHNfMS50YWdQYXJhbWV0ZXIodGFyZ2V0LCB0YXJnZXRLZXksIGluZGV4LCBtZXRhZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkZWNvcmF0b3JfdXRpbHNfMS50YWdQcm9wZXJ0eSh0YXJnZXQsIHRhcmdldEtleSwgbWV0YWRhdGEpO1xuICAgICAgICB9XG4gICAgfTtcbn1cbmV4cG9ydHMub3B0aW9uYWwgPSBvcHRpb25hbDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW9wdGlvbmFsLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5wb3N0Q29uc3RydWN0ID0gdm9pZCAwO1xudmFyIEVSUk9SU19NU0dTID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9lcnJvcl9tc2dzXCIpO1xudmFyIE1FVEFEQVRBX0tFWSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbWV0YWRhdGFfa2V5c1wiKTtcbnZhciBtZXRhZGF0YV8xID0gcmVxdWlyZShcIi4uL3BsYW5uaW5nL21ldGFkYXRhXCIpO1xuZnVuY3Rpb24gcG9zdENvbnN0cnVjdCgpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwgcHJvcGVydHlLZXksIGRlc2NyaXB0b3IpIHtcbiAgICAgICAgdmFyIG1ldGFkYXRhID0gbmV3IG1ldGFkYXRhXzEuTWV0YWRhdGEoTUVUQURBVEFfS0VZLlBPU1RfQ09OU1RSVUNULCBwcm9wZXJ0eUtleSk7XG4gICAgICAgIGlmIChSZWZsZWN0Lmhhc093bk1ldGFkYXRhKE1FVEFEQVRBX0tFWS5QT1NUX0NPTlNUUlVDVCwgdGFyZ2V0LmNvbnN0cnVjdG9yKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SU19NU0dTLk1VTFRJUExFX1BPU1RfQ09OU1RSVUNUX01FVEhPRFMpO1xuICAgICAgICB9XG4gICAgICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoTUVUQURBVEFfS0VZLlBPU1RfQ09OU1RSVUNULCBtZXRhZGF0YSwgdGFyZ2V0LmNvbnN0cnVjdG9yKTtcbiAgICB9O1xufVxuZXhwb3J0cy5wb3N0Q29uc3RydWN0ID0gcG9zdENvbnN0cnVjdDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBvc3RfY29uc3RydWN0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy50YWdnZWQgPSB2b2lkIDA7XG52YXIgbWV0YWRhdGFfMSA9IHJlcXVpcmUoXCIuLi9wbGFubmluZy9tZXRhZGF0YVwiKTtcbnZhciBkZWNvcmF0b3JfdXRpbHNfMSA9IHJlcXVpcmUoXCIuL2RlY29yYXRvcl91dGlsc1wiKTtcbmZ1bmN0aW9uIHRhZ2dlZChtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCB0YXJnZXRLZXksIGluZGV4KSB7XG4gICAgICAgIHZhciBtZXRhZGF0YSA9IG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKTtcbiAgICAgICAgaWYgKHR5cGVvZiBpbmRleCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgZGVjb3JhdG9yX3V0aWxzXzEudGFnUGFyYW1ldGVyKHRhcmdldCwgdGFyZ2V0S2V5LCBpbmRleCwgbWV0YWRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGVjb3JhdG9yX3V0aWxzXzEudGFnUHJvcGVydHkodGFyZ2V0LCB0YXJnZXRLZXksIG1ldGFkYXRhKTtcbiAgICAgICAgfVxuICAgIH07XG59XG5leHBvcnRzLnRhZ2dlZCA9IHRhZ2dlZDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRhZ2dlZC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMudGFyZ2V0TmFtZSA9IHZvaWQgMDtcbnZhciBNRVRBREFUQV9LRVkgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG52YXIgbWV0YWRhdGFfMSA9IHJlcXVpcmUoXCIuLi9wbGFubmluZy9tZXRhZGF0YVwiKTtcbnZhciBkZWNvcmF0b3JfdXRpbHNfMSA9IHJlcXVpcmUoXCIuL2RlY29yYXRvcl91dGlsc1wiKTtcbmZ1bmN0aW9uIHRhcmdldE5hbWUobmFtZSkge1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCB0YXJnZXRLZXksIGluZGV4KSB7XG4gICAgICAgIHZhciBtZXRhZGF0YSA9IG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKE1FVEFEQVRBX0tFWS5OQU1FX1RBRywgbmFtZSk7XG4gICAgICAgIGRlY29yYXRvcl91dGlsc18xLnRhZ1BhcmFtZXRlcih0YXJnZXQsIHRhcmdldEtleSwgaW5kZXgsIG1ldGFkYXRhKTtcbiAgICB9O1xufVxuZXhwb3J0cy50YXJnZXROYW1lID0gdGFyZ2V0TmFtZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRhcmdldF9uYW1lLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy51bm1hbmFnZWQgPSB2b2lkIDA7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvbWV0YWRhdGFcIik7XG52YXIgZGVjb3JhdG9yX3V0aWxzXzEgPSByZXF1aXJlKFwiLi9kZWNvcmF0b3JfdXRpbHNcIik7XG5mdW5jdGlvbiB1bm1hbmFnZWQoKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIHRhcmdldEtleSwgaW5kZXgpIHtcbiAgICAgICAgdmFyIG1ldGFkYXRhID0gbmV3IG1ldGFkYXRhXzEuTWV0YWRhdGEoTUVUQURBVEFfS0VZLlVOTUFOQUdFRF9UQUcsIHRydWUpO1xuICAgICAgICBkZWNvcmF0b3JfdXRpbHNfMS50YWdQYXJhbWV0ZXIodGFyZ2V0LCB0YXJnZXRLZXksIGluZGV4LCBtZXRhZGF0YSk7XG4gICAgfTtcbn1cbmV4cG9ydHMudW5tYW5hZ2VkID0gdW5tYW5hZ2VkO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dW5tYW5hZ2VkLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5CaW5kaW5nID0gdm9pZCAwO1xudmFyIGxpdGVyYWxfdHlwZXNfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbGl0ZXJhbF90eXBlc1wiKTtcbnZhciBpZF8xID0gcmVxdWlyZShcIi4uL3V0aWxzL2lkXCIpO1xudmFyIEJpbmRpbmcgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEJpbmRpbmcoc2VydmljZUlkZW50aWZpZXIsIHNjb3BlKSB7XG4gICAgICAgIHRoaXMuaWQgPSBpZF8xLmlkKCk7XG4gICAgICAgIHRoaXMuYWN0aXZhdGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc2VydmljZUlkZW50aWZpZXIgPSBzZXJ2aWNlSWRlbnRpZmllcjtcbiAgICAgICAgdGhpcy5zY29wZSA9IHNjb3BlO1xuICAgICAgICB0aGlzLnR5cGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1R5cGVFbnVtLkludmFsaWQ7XG4gICAgICAgIHRoaXMuY29uc3RyYWludCA9IGZ1bmN0aW9uIChyZXF1ZXN0KSB7IHJldHVybiB0cnVlOyB9O1xuICAgICAgICB0aGlzLmltcGxlbWVudGF0aW9uVHlwZSA9IG51bGw7XG4gICAgICAgIHRoaXMuY2FjaGUgPSBudWxsO1xuICAgICAgICB0aGlzLmZhY3RvcnkgPSBudWxsO1xuICAgICAgICB0aGlzLnByb3ZpZGVyID0gbnVsbDtcbiAgICAgICAgdGhpcy5vbkFjdGl2YXRpb24gPSBudWxsO1xuICAgICAgICB0aGlzLmR5bmFtaWNWYWx1ZSA9IG51bGw7XG4gICAgfVxuICAgIEJpbmRpbmcucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2xvbmUgPSBuZXcgQmluZGluZyh0aGlzLnNlcnZpY2VJZGVudGlmaWVyLCB0aGlzLnNjb3BlKTtcbiAgICAgICAgY2xvbmUuYWN0aXZhdGVkID0gKGNsb25lLnNjb3BlID09PSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5TaW5nbGV0b24pID8gdGhpcy5hY3RpdmF0ZWQgOiBmYWxzZTtcbiAgICAgICAgY2xvbmUuaW1wbGVtZW50YXRpb25UeXBlID0gdGhpcy5pbXBsZW1lbnRhdGlvblR5cGU7XG4gICAgICAgIGNsb25lLmR5bmFtaWNWYWx1ZSA9IHRoaXMuZHluYW1pY1ZhbHVlO1xuICAgICAgICBjbG9uZS5zY29wZSA9IHRoaXMuc2NvcGU7XG4gICAgICAgIGNsb25lLnR5cGUgPSB0aGlzLnR5cGU7XG4gICAgICAgIGNsb25lLmZhY3RvcnkgPSB0aGlzLmZhY3Rvcnk7XG4gICAgICAgIGNsb25lLnByb3ZpZGVyID0gdGhpcy5wcm92aWRlcjtcbiAgICAgICAgY2xvbmUuY29uc3RyYWludCA9IHRoaXMuY29uc3RyYWludDtcbiAgICAgICAgY2xvbmUub25BY3RpdmF0aW9uID0gdGhpcy5vbkFjdGl2YXRpb247XG4gICAgICAgIGNsb25lLmNhY2hlID0gdGhpcy5jYWNoZTtcbiAgICAgICAgcmV0dXJuIGNsb25lO1xuICAgIH07XG4gICAgcmV0dXJuIEJpbmRpbmc7XG59KCkpO1xuZXhwb3J0cy5CaW5kaW5nID0gQmluZGluZztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJpbmRpbmcuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkJpbmRpbmdDb3VudCA9IHZvaWQgMDtcbnZhciBCaW5kaW5nQ291bnQgPSB7XG4gICAgTXVsdGlwbGVCaW5kaW5nc0F2YWlsYWJsZTogMixcbiAgICBOb0JpbmRpbmdzQXZhaWxhYmxlOiAwLFxuICAgIE9ubHlPbmVCaW5kaW5nQXZhaWxhYmxlOiAxXG59O1xuZXhwb3J0cy5CaW5kaW5nQ291bnQgPSBCaW5kaW5nQ291bnQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iaW5kaW5nX2NvdW50LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5TVEFDS19PVkVSRkxPVyA9IGV4cG9ydHMuQ0lSQ1VMQVJfREVQRU5ERU5DWV9JTl9GQUNUT1JZID0gZXhwb3J0cy5QT1NUX0NPTlNUUlVDVF9FUlJPUiA9IGV4cG9ydHMuTVVMVElQTEVfUE9TVF9DT05TVFJVQ1RfTUVUSE9EUyA9IGV4cG9ydHMuQ09OVEFJTkVSX09QVElPTlNfSU5WQUxJRF9TS0lQX0JBU0VfQ0hFQ0sgPSBleHBvcnRzLkNPTlRBSU5FUl9PUFRJT05TX0lOVkFMSURfQVVUT19CSU5EX0lOSkVDVEFCTEUgPSBleHBvcnRzLkNPTlRBSU5FUl9PUFRJT05TX0lOVkFMSURfREVGQVVMVF9TQ09QRSA9IGV4cG9ydHMuQ09OVEFJTkVSX09QVElPTlNfTVVTVF9CRV9BTl9PQkpFQ1QgPSBleHBvcnRzLkFSR1VNRU5UU19MRU5HVEhfTUlTTUFUQ0ggPSBleHBvcnRzLklOVkFMSURfREVDT1JBVE9SX09QRVJBVElPTiA9IGV4cG9ydHMuSU5WQUxJRF9UT19TRUxGX1ZBTFVFID0gZXhwb3J0cy5JTlZBTElEX0ZVTkNUSU9OX0JJTkRJTkcgPSBleHBvcnRzLklOVkFMSURfTUlERExFV0FSRV9SRVRVUk4gPSBleHBvcnRzLk5PX01PUkVfU05BUFNIT1RTX0FWQUlMQUJMRSA9IGV4cG9ydHMuSU5WQUxJRF9CSU5ESU5HX1RZUEUgPSBleHBvcnRzLk5PVF9JTVBMRU1FTlRFRCA9IGV4cG9ydHMuQ0lSQ1VMQVJfREVQRU5ERU5DWSA9IGV4cG9ydHMuVU5ERUZJTkVEX0lOSkVDVF9BTk5PVEFUSU9OID0gZXhwb3J0cy5NSVNTSU5HX0lOSkVDVF9BTk5PVEFUSU9OID0gZXhwb3J0cy5NSVNTSU5HX0lOSkVDVEFCTEVfQU5OT1RBVElPTiA9IGV4cG9ydHMuTk9UX1JFR0lTVEVSRUQgPSBleHBvcnRzLkNBTk5PVF9VTkJJTkQgPSBleHBvcnRzLkFNQklHVU9VU19NQVRDSCA9IGV4cG9ydHMuS0VZX05PVF9GT1VORCA9IGV4cG9ydHMuTlVMTF9BUkdVTUVOVCA9IGV4cG9ydHMuRFVQTElDQVRFRF9NRVRBREFUQSA9IGV4cG9ydHMuRFVQTElDQVRFRF9JTkpFQ1RBQkxFX0RFQ09SQVRPUiA9IHZvaWQgMDtcbmV4cG9ydHMuRFVQTElDQVRFRF9JTkpFQ1RBQkxFX0RFQ09SQVRPUiA9IFwiQ2Fubm90IGFwcGx5IEBpbmplY3RhYmxlIGRlY29yYXRvciBtdWx0aXBsZSB0aW1lcy5cIjtcbmV4cG9ydHMuRFVQTElDQVRFRF9NRVRBREFUQSA9IFwiTWV0YWRhdGEga2V5IHdhcyB1c2VkIG1vcmUgdGhhbiBvbmNlIGluIGEgcGFyYW1ldGVyOlwiO1xuZXhwb3J0cy5OVUxMX0FSR1VNRU5UID0gXCJOVUxMIGFyZ3VtZW50XCI7XG5leHBvcnRzLktFWV9OT1RfRk9VTkQgPSBcIktleSBOb3QgRm91bmRcIjtcbmV4cG9ydHMuQU1CSUdVT1VTX01BVENIID0gXCJBbWJpZ3VvdXMgbWF0Y2ggZm91bmQgZm9yIHNlcnZpY2VJZGVudGlmaWVyOlwiO1xuZXhwb3J0cy5DQU5OT1RfVU5CSU5EID0gXCJDb3VsZCBub3QgdW5iaW5kIHNlcnZpY2VJZGVudGlmaWVyOlwiO1xuZXhwb3J0cy5OT1RfUkVHSVNURVJFRCA9IFwiTm8gbWF0Y2hpbmcgYmluZGluZ3MgZm91bmQgZm9yIHNlcnZpY2VJZGVudGlmaWVyOlwiO1xuZXhwb3J0cy5NSVNTSU5HX0lOSkVDVEFCTEVfQU5OT1RBVElPTiA9IFwiTWlzc2luZyByZXF1aXJlZCBAaW5qZWN0YWJsZSBhbm5vdGF0aW9uIGluOlwiO1xuZXhwb3J0cy5NSVNTSU5HX0lOSkVDVF9BTk5PVEFUSU9OID0gXCJNaXNzaW5nIHJlcXVpcmVkIEBpbmplY3Qgb3IgQG11bHRpSW5qZWN0IGFubm90YXRpb24gaW46XCI7XG52YXIgVU5ERUZJTkVEX0lOSkVDVF9BTk5PVEFUSU9OID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICByZXR1cm4gXCJAaW5qZWN0IGNhbGxlZCB3aXRoIHVuZGVmaW5lZCB0aGlzIGNvdWxkIG1lYW4gdGhhdCB0aGUgY2xhc3MgXCIgKyBuYW1lICsgXCIgaGFzIFwiICtcbiAgICAgICAgXCJhIGNpcmN1bGFyIGRlcGVuZGVuY3kgcHJvYmxlbS4gWW91IGNhbiB1c2UgYSBMYXp5U2VydmljZUlkZW50aWZlciB0byAgXCIgK1xuICAgICAgICBcIm92ZXJjb21lIHRoaXMgbGltaXRhdGlvbi5cIjtcbn07XG5leHBvcnRzLlVOREVGSU5FRF9JTkpFQ1RfQU5OT1RBVElPTiA9IFVOREVGSU5FRF9JTkpFQ1RfQU5OT1RBVElPTjtcbmV4cG9ydHMuQ0lSQ1VMQVJfREVQRU5ERU5DWSA9IFwiQ2lyY3VsYXIgZGVwZW5kZW5jeSBmb3VuZDpcIjtcbmV4cG9ydHMuTk9UX0lNUExFTUVOVEVEID0gXCJTb3JyeSwgdGhpcyBmZWF0dXJlIGlzIG5vdCBmdWxseSBpbXBsZW1lbnRlZCB5ZXQuXCI7XG5leHBvcnRzLklOVkFMSURfQklORElOR19UWVBFID0gXCJJbnZhbGlkIGJpbmRpbmcgdHlwZTpcIjtcbmV4cG9ydHMuTk9fTU9SRV9TTkFQU0hPVFNfQVZBSUxBQkxFID0gXCJObyBzbmFwc2hvdCBhdmFpbGFibGUgdG8gcmVzdG9yZS5cIjtcbmV4cG9ydHMuSU5WQUxJRF9NSURETEVXQVJFX1JFVFVSTiA9IFwiSW52YWxpZCByZXR1cm4gdHlwZSBpbiBtaWRkbGV3YXJlLiBNaWRkbGV3YXJlIG11c3QgcmV0dXJuIVwiO1xuZXhwb3J0cy5JTlZBTElEX0ZVTkNUSU9OX0JJTkRJTkcgPSBcIlZhbHVlIHByb3ZpZGVkIHRvIGZ1bmN0aW9uIGJpbmRpbmcgbXVzdCBiZSBhIGZ1bmN0aW9uIVwiO1xuZXhwb3J0cy5JTlZBTElEX1RPX1NFTEZfVkFMVUUgPSBcIlRoZSB0b1NlbGYgZnVuY3Rpb24gY2FuIG9ubHkgYmUgYXBwbGllZCB3aGVuIGEgY29uc3RydWN0b3IgaXMgXCIgK1xuICAgIFwidXNlZCBhcyBzZXJ2aWNlIGlkZW50aWZpZXJcIjtcbmV4cG9ydHMuSU5WQUxJRF9ERUNPUkFUT1JfT1BFUkFUSU9OID0gXCJUaGUgQGluamVjdCBAbXVsdGlJbmplY3QgQHRhZ2dlZCBhbmQgQG5hbWVkIGRlY29yYXRvcnMgXCIgK1xuICAgIFwibXVzdCBiZSBhcHBsaWVkIHRvIHRoZSBwYXJhbWV0ZXJzIG9mIGEgY2xhc3MgY29uc3RydWN0b3Igb3IgYSBjbGFzcyBwcm9wZXJ0eS5cIjtcbnZhciBBUkdVTUVOVFNfTEVOR1RIX01JU01BVENIID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZXMgPSBbXTtcbiAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICB2YWx1ZXNbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICB9XG4gICAgcmV0dXJuIFwiVGhlIG51bWJlciBvZiBjb25zdHJ1Y3RvciBhcmd1bWVudHMgaW4gdGhlIGRlcml2ZWQgY2xhc3MgXCIgK1xuICAgICAgICAodmFsdWVzWzBdICsgXCIgbXVzdCBiZSA+PSB0aGFuIHRoZSBudW1iZXIgb2YgY29uc3RydWN0b3IgYXJndW1lbnRzIG9mIGl0cyBiYXNlIGNsYXNzLlwiKTtcbn07XG5leHBvcnRzLkFSR1VNRU5UU19MRU5HVEhfTUlTTUFUQ0ggPSBBUkdVTUVOVFNfTEVOR1RIX01JU01BVENIO1xuZXhwb3J0cy5DT05UQUlORVJfT1BUSU9OU19NVVNUX0JFX0FOX09CSkVDVCA9IFwiSW52YWxpZCBDb250YWluZXIgY29uc3RydWN0b3IgYXJndW1lbnQuIENvbnRhaW5lciBvcHRpb25zIFwiICtcbiAgICBcIm11c3QgYmUgYW4gb2JqZWN0LlwiO1xuZXhwb3J0cy5DT05UQUlORVJfT1BUSU9OU19JTlZBTElEX0RFRkFVTFRfU0NPUEUgPSBcIkludmFsaWQgQ29udGFpbmVyIG9wdGlvbi4gRGVmYXVsdCBzY29wZSBtdXN0IFwiICtcbiAgICBcImJlIGEgc3RyaW5nICgnc2luZ2xldG9uJyBvciAndHJhbnNpZW50JykuXCI7XG5leHBvcnRzLkNPTlRBSU5FUl9PUFRJT05TX0lOVkFMSURfQVVUT19CSU5EX0lOSkVDVEFCTEUgPSBcIkludmFsaWQgQ29udGFpbmVyIG9wdGlvbi4gQXV0byBiaW5kIGluamVjdGFibGUgbXVzdCBcIiArXG4gICAgXCJiZSBhIGJvb2xlYW5cIjtcbmV4cG9ydHMuQ09OVEFJTkVSX09QVElPTlNfSU5WQUxJRF9TS0lQX0JBU0VfQ0hFQ0sgPSBcIkludmFsaWQgQ29udGFpbmVyIG9wdGlvbi4gU2tpcCBiYXNlIGNoZWNrIG11c3QgXCIgK1xuICAgIFwiYmUgYSBib29sZWFuXCI7XG5leHBvcnRzLk1VTFRJUExFX1BPU1RfQ09OU1RSVUNUX01FVEhPRFMgPSBcIkNhbm5vdCBhcHBseSBAcG9zdENvbnN0cnVjdCBkZWNvcmF0b3IgbXVsdGlwbGUgdGltZXMgaW4gdGhlIHNhbWUgY2xhc3NcIjtcbnZhciBQT1NUX0NPTlNUUlVDVF9FUlJPUiA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdmFsdWVzID0gW107XG4gICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgdmFsdWVzW19pXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgfVxuICAgIHJldHVybiBcIkBwb3N0Q29uc3RydWN0IGVycm9yIGluIGNsYXNzIFwiICsgdmFsdWVzWzBdICsgXCI6IFwiICsgdmFsdWVzWzFdO1xufTtcbmV4cG9ydHMuUE9TVF9DT05TVFJVQ1RfRVJST1IgPSBQT1NUX0NPTlNUUlVDVF9FUlJPUjtcbnZhciBDSVJDVUxBUl9ERVBFTkRFTkNZX0lOX0ZBQ1RPUlkgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIHZhbHVlc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgIH1cbiAgICByZXR1cm4gXCJJdCBsb29rcyBsaWtlIHRoZXJlIGlzIGEgY2lyY3VsYXIgZGVwZW5kZW5jeSBcIiArXG4gICAgICAgIChcImluIG9uZSBvZiB0aGUgJ1wiICsgdmFsdWVzWzBdICsgXCInIGJpbmRpbmdzLiBQbGVhc2UgaW52ZXN0aWdhdGUgYmluZGluZ3Mgd2l0aFwiKSArXG4gICAgICAgIChcInNlcnZpY2UgaWRlbnRpZmllciAnXCIgKyB2YWx1ZXNbMV0gKyBcIicuXCIpO1xufTtcbmV4cG9ydHMuQ0lSQ1VMQVJfREVQRU5ERU5DWV9JTl9GQUNUT1JZID0gQ0lSQ1VMQVJfREVQRU5ERU5DWV9JTl9GQUNUT1JZO1xuZXhwb3J0cy5TVEFDS19PVkVSRkxPVyA9IFwiTWF4aW11bSBjYWxsIHN0YWNrIHNpemUgZXhjZWVkZWRcIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWVycm9yX21zZ3MuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLlRhcmdldFR5cGVFbnVtID0gZXhwb3J0cy5CaW5kaW5nVHlwZUVudW0gPSBleHBvcnRzLkJpbmRpbmdTY29wZUVudW0gPSB2b2lkIDA7XG52YXIgQmluZGluZ1Njb3BlRW51bSA9IHtcbiAgICBSZXF1ZXN0OiBcIlJlcXVlc3RcIixcbiAgICBTaW5nbGV0b246IFwiU2luZ2xldG9uXCIsXG4gICAgVHJhbnNpZW50OiBcIlRyYW5zaWVudFwiXG59O1xuZXhwb3J0cy5CaW5kaW5nU2NvcGVFbnVtID0gQmluZGluZ1Njb3BlRW51bTtcbnZhciBCaW5kaW5nVHlwZUVudW0gPSB7XG4gICAgQ29uc3RhbnRWYWx1ZTogXCJDb25zdGFudFZhbHVlXCIsXG4gICAgQ29uc3RydWN0b3I6IFwiQ29uc3RydWN0b3JcIixcbiAgICBEeW5hbWljVmFsdWU6IFwiRHluYW1pY1ZhbHVlXCIsXG4gICAgRmFjdG9yeTogXCJGYWN0b3J5XCIsXG4gICAgRnVuY3Rpb246IFwiRnVuY3Rpb25cIixcbiAgICBJbnN0YW5jZTogXCJJbnN0YW5jZVwiLFxuICAgIEludmFsaWQ6IFwiSW52YWxpZFwiLFxuICAgIFByb3ZpZGVyOiBcIlByb3ZpZGVyXCJcbn07XG5leHBvcnRzLkJpbmRpbmdUeXBlRW51bSA9IEJpbmRpbmdUeXBlRW51bTtcbnZhciBUYXJnZXRUeXBlRW51bSA9IHtcbiAgICBDbGFzc1Byb3BlcnR5OiBcIkNsYXNzUHJvcGVydHlcIixcbiAgICBDb25zdHJ1Y3RvckFyZ3VtZW50OiBcIkNvbnN0cnVjdG9yQXJndW1lbnRcIixcbiAgICBWYXJpYWJsZTogXCJWYXJpYWJsZVwiXG59O1xuZXhwb3J0cy5UYXJnZXRUeXBlRW51bSA9IFRhcmdldFR5cGVFbnVtO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGl0ZXJhbF90eXBlcy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuTk9OX0NVU1RPTV9UQUdfS0VZUyA9IGV4cG9ydHMuUE9TVF9DT05TVFJVQ1QgPSBleHBvcnRzLkRFU0lHTl9QQVJBTV9UWVBFUyA9IGV4cG9ydHMuUEFSQU1fVFlQRVMgPSBleHBvcnRzLlRBR0dFRF9QUk9QID0gZXhwb3J0cy5UQUdHRUQgPSBleHBvcnRzLk1VTFRJX0lOSkVDVF9UQUcgPSBleHBvcnRzLklOSkVDVF9UQUcgPSBleHBvcnRzLk9QVElPTkFMX1RBRyA9IGV4cG9ydHMuVU5NQU5BR0VEX1RBRyA9IGV4cG9ydHMuTkFNRV9UQUcgPSBleHBvcnRzLk5BTUVEX1RBRyA9IHZvaWQgMDtcbmV4cG9ydHMuTkFNRURfVEFHID0gXCJuYW1lZFwiO1xuZXhwb3J0cy5OQU1FX1RBRyA9IFwibmFtZVwiO1xuZXhwb3J0cy5VTk1BTkFHRURfVEFHID0gXCJ1bm1hbmFnZWRcIjtcbmV4cG9ydHMuT1BUSU9OQUxfVEFHID0gXCJvcHRpb25hbFwiO1xuZXhwb3J0cy5JTkpFQ1RfVEFHID0gXCJpbmplY3RcIjtcbmV4cG9ydHMuTVVMVElfSU5KRUNUX1RBRyA9IFwibXVsdGlfaW5qZWN0XCI7XG5leHBvcnRzLlRBR0dFRCA9IFwiaW52ZXJzaWZ5OnRhZ2dlZFwiO1xuZXhwb3J0cy5UQUdHRURfUFJPUCA9IFwiaW52ZXJzaWZ5OnRhZ2dlZF9wcm9wc1wiO1xuZXhwb3J0cy5QQVJBTV9UWVBFUyA9IFwiaW52ZXJzaWZ5OnBhcmFtdHlwZXNcIjtcbmV4cG9ydHMuREVTSUdOX1BBUkFNX1RZUEVTID0gXCJkZXNpZ246cGFyYW10eXBlc1wiO1xuZXhwb3J0cy5QT1NUX0NPTlNUUlVDVCA9IFwicG9zdF9jb25zdHJ1Y3RcIjtcbmZ1bmN0aW9uIGdldE5vbkN1c3RvbVRhZ0tleXMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgICAgZXhwb3J0cy5JTkpFQ1RfVEFHLFxuICAgICAgICBleHBvcnRzLk1VTFRJX0lOSkVDVF9UQUcsXG4gICAgICAgIGV4cG9ydHMuTkFNRV9UQUcsXG4gICAgICAgIGV4cG9ydHMuVU5NQU5BR0VEX1RBRyxcbiAgICAgICAgZXhwb3J0cy5OQU1FRF9UQUcsXG4gICAgICAgIGV4cG9ydHMuT1BUSU9OQUxfVEFHLFxuICAgIF07XG59XG5leHBvcnRzLk5PTl9DVVNUT01fVEFHX0tFWVMgPSBnZXROb25DdXN0b21UYWdLZXlzKCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tZXRhZGF0YV9rZXlzLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xudmFyIF9fYXdhaXRlciA9ICh0aGlzICYmIHRoaXMuX19hd2FpdGVyKSB8fCBmdW5jdGlvbiAodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogYWRvcHQocmVzdWx0LnZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcbiAgICB9KTtcbn07XG52YXIgX19nZW5lcmF0b3IgPSAodGhpcyAmJiB0aGlzLl9fZ2VuZXJhdG9yKSB8fCBmdW5jdGlvbiAodGhpc0FyZywgYm9keSkge1xuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XG4gICAgcmV0dXJuIGcgPSB7IG5leHQ6IHZlcmIoMCksIFwidGhyb3dcIjogdmVyYigxKSwgXCJyZXR1cm5cIjogdmVyYigyKSB9LCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgKGdbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSksIGc7XG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XG4gICAgZnVuY3Rpb24gc3RlcChvcCkge1xuICAgICAgICBpZiAoZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IGV4ZWN1dGluZy5cIik7XG4gICAgICAgIHdoaWxlIChfKSB0cnkge1xuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xuICAgICAgICAgICAgaWYgKHkgPSAwLCB0KSBvcCA9IFtvcFswXSAmIDIsIHQudmFsdWVdO1xuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xuICAgICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XG4gICAgfVxufTtcbnZhciBfX3NwcmVhZEFycmF5ID0gKHRoaXMgJiYgdGhpcy5fX3NwcmVhZEFycmF5KSB8fCBmdW5jdGlvbiAodG8sIGZyb20pIHtcbiAgICBmb3IgKHZhciBpID0gMCwgaWwgPSBmcm9tLmxlbmd0aCwgaiA9IHRvLmxlbmd0aDsgaSA8IGlsOyBpKyssIGorKylcbiAgICAgICAgdG9bal0gPSBmcm9tW2ldO1xuICAgIHJldHVybiB0bztcbn07XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkNvbnRhaW5lciA9IHZvaWQgMDtcbnZhciBiaW5kaW5nXzEgPSByZXF1aXJlKFwiLi4vYmluZGluZ3MvYmluZGluZ1wiKTtcbnZhciBFUlJPUl9NU0dTID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9lcnJvcl9tc2dzXCIpO1xudmFyIGxpdGVyYWxfdHlwZXNfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbGl0ZXJhbF90eXBlc1wiKTtcbnZhciBNRVRBREFUQV9LRVkgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG52YXIgbWV0YWRhdGFfcmVhZGVyXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvbWV0YWRhdGFfcmVhZGVyXCIpO1xudmFyIHBsYW5uZXJfMSA9IHJlcXVpcmUoXCIuLi9wbGFubmluZy9wbGFubmVyXCIpO1xudmFyIHJlc29sdmVyXzEgPSByZXF1aXJlKFwiLi4vcmVzb2x1dGlvbi9yZXNvbHZlclwiKTtcbnZhciBiaW5kaW5nX3RvX3N5bnRheF8xID0gcmVxdWlyZShcIi4uL3N5bnRheC9iaW5kaW5nX3RvX3N5bnRheFwiKTtcbnZhciBpZF8xID0gcmVxdWlyZShcIi4uL3V0aWxzL2lkXCIpO1xudmFyIHNlcmlhbGl6YXRpb25fMSA9IHJlcXVpcmUoXCIuLi91dGlscy9zZXJpYWxpemF0aW9uXCIpO1xudmFyIGNvbnRhaW5lcl9zbmFwc2hvdF8xID0gcmVxdWlyZShcIi4vY29udGFpbmVyX3NuYXBzaG90XCIpO1xudmFyIGxvb2t1cF8xID0gcmVxdWlyZShcIi4vbG9va3VwXCIpO1xudmFyIENvbnRhaW5lciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQ29udGFpbmVyKGNvbnRhaW5lck9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5fYXBwbGllZE1pZGRsZXdhcmUgPSBbXTtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSBjb250YWluZXJPcHRpb25zIHx8IHt9O1xuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlwiICsgRVJST1JfTVNHUy5DT05UQUlORVJfT1BUSU9OU19NVVNUX0JFX0FOX09CSkVDVCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdFNjb3BlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG9wdGlvbnMuZGVmYXVsdFNjb3BlID0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdTY29wZUVudW0uVHJhbnNpZW50O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG9wdGlvbnMuZGVmYXVsdFNjb3BlICE9PSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5TaW5nbGV0b24gJiZcbiAgICAgICAgICAgIG9wdGlvbnMuZGVmYXVsdFNjb3BlICE9PSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5UcmFuc2llbnQgJiZcbiAgICAgICAgICAgIG9wdGlvbnMuZGVmYXVsdFNjb3BlICE9PSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5SZXF1ZXN0KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJcIiArIEVSUk9SX01TR1MuQ09OVEFJTkVSX09QVElPTlNfSU5WQUxJRF9ERUZBVUxUX1NDT1BFKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0aW9ucy5hdXRvQmluZEluamVjdGFibGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgb3B0aW9ucy5hdXRvQmluZEluamVjdGFibGUgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb3B0aW9ucy5hdXRvQmluZEluamVjdGFibGUgIT09IFwiYm9vbGVhblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJcIiArIEVSUk9SX01TR1MuQ09OVEFJTkVSX09QVElPTlNfSU5WQUxJRF9BVVRPX0JJTkRfSU5KRUNUQUJMRSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMuc2tpcEJhc2VDbGFzc0NoZWNrcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBvcHRpb25zLnNraXBCYXNlQ2xhc3NDaGVja3MgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb3B0aW9ucy5za2lwQmFzZUNsYXNzQ2hlY2tzICE9PSBcImJvb2xlYW5cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiXCIgKyBFUlJPUl9NU0dTLkNPTlRBSU5FUl9PUFRJT05TX0lOVkFMSURfU0tJUF9CQVNFX0NIRUNLKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICAgICAgICBhdXRvQmluZEluamVjdGFibGU6IG9wdGlvbnMuYXV0b0JpbmRJbmplY3RhYmxlLFxuICAgICAgICAgICAgZGVmYXVsdFNjb3BlOiBvcHRpb25zLmRlZmF1bHRTY29wZSxcbiAgICAgICAgICAgIHNraXBCYXNlQ2xhc3NDaGVja3M6IG9wdGlvbnMuc2tpcEJhc2VDbGFzc0NoZWNrc1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmlkID0gaWRfMS5pZCgpO1xuICAgICAgICB0aGlzLl9iaW5kaW5nRGljdGlvbmFyeSA9IG5ldyBsb29rdXBfMS5Mb29rdXAoKTtcbiAgICAgICAgdGhpcy5fc25hcHNob3RzID0gW107XG4gICAgICAgIHRoaXMuX21pZGRsZXdhcmUgPSBudWxsO1xuICAgICAgICB0aGlzLnBhcmVudCA9IG51bGw7XG4gICAgICAgIHRoaXMuX21ldGFkYXRhUmVhZGVyID0gbmV3IG1ldGFkYXRhX3JlYWRlcl8xLk1ldGFkYXRhUmVhZGVyKCk7XG4gICAgfVxuICAgIENvbnRhaW5lci5tZXJnZSA9IGZ1bmN0aW9uIChjb250YWluZXIxLCBjb250YWluZXIyKSB7XG4gICAgICAgIHZhciBjb250YWluZXIzID0gW107XG4gICAgICAgIGZvciAodmFyIF9pID0gMjsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICBjb250YWluZXIzW19pIC0gMl0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICB9XG4gICAgICAgIHZhciBjb250YWluZXIgPSBuZXcgQ29udGFpbmVyKCk7XG4gICAgICAgIHZhciB0YXJnZXRDb250YWluZXJzID0gX19zcHJlYWRBcnJheShbY29udGFpbmVyMSwgY29udGFpbmVyMl0sIGNvbnRhaW5lcjMpLm1hcChmdW5jdGlvbiAodGFyZ2V0Q29udGFpbmVyKSB7IHJldHVybiBwbGFubmVyXzEuZ2V0QmluZGluZ0RpY3Rpb25hcnkodGFyZ2V0Q29udGFpbmVyKTsgfSk7XG4gICAgICAgIHZhciBiaW5kaW5nRGljdGlvbmFyeSA9IHBsYW5uZXJfMS5nZXRCaW5kaW5nRGljdGlvbmFyeShjb250YWluZXIpO1xuICAgICAgICBmdW5jdGlvbiBjb3B5RGljdGlvbmFyeShvcmlnaW4sIGRlc3RpbmF0aW9uKSB7XG4gICAgICAgICAgICBvcmlnaW4udHJhdmVyc2UoZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZS5mb3JFYWNoKGZ1bmN0aW9uIChiaW5kaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uLmFkZChiaW5kaW5nLnNlcnZpY2VJZGVudGlmaWVyLCBiaW5kaW5nLmNsb25lKCkpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGFyZ2V0Q29udGFpbmVycy5mb3JFYWNoKGZ1bmN0aW9uICh0YXJnZXRCaW5kaW5nRGljdGlvbmFyeSkge1xuICAgICAgICAgICAgY29weURpY3Rpb25hcnkodGFyZ2V0QmluZGluZ0RpY3Rpb25hcnksIGJpbmRpbmdEaWN0aW9uYXJ5KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBjb250YWluZXI7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtb2R1bGVzID0gW107XG4gICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICBtb2R1bGVzW19pXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGdldEhlbHBlcnMgPSB0aGlzLl9nZXRDb250YWluZXJNb2R1bGVIZWxwZXJzRmFjdG9yeSgpO1xuICAgICAgICBmb3IgKHZhciBfYSA9IDAsIG1vZHVsZXNfMSA9IG1vZHVsZXM7IF9hIDwgbW9kdWxlc18xLmxlbmd0aDsgX2ErKykge1xuICAgICAgICAgICAgdmFyIGN1cnJlbnRNb2R1bGUgPSBtb2R1bGVzXzFbX2FdO1xuICAgICAgICAgICAgdmFyIGNvbnRhaW5lck1vZHVsZUhlbHBlcnMgPSBnZXRIZWxwZXJzKGN1cnJlbnRNb2R1bGUuaWQpO1xuICAgICAgICAgICAgY3VycmVudE1vZHVsZS5yZWdpc3RyeShjb250YWluZXJNb2R1bGVIZWxwZXJzLmJpbmRGdW5jdGlvbiwgY29udGFpbmVyTW9kdWxlSGVscGVycy51bmJpbmRGdW5jdGlvbiwgY29udGFpbmVyTW9kdWxlSGVscGVycy5pc2JvdW5kRnVuY3Rpb24sIGNvbnRhaW5lck1vZHVsZUhlbHBlcnMucmViaW5kRnVuY3Rpb24pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmxvYWRBc3luYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG1vZHVsZXMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIG1vZHVsZXNbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgZ2V0SGVscGVycywgX2EsIG1vZHVsZXNfMiwgY3VycmVudE1vZHVsZSwgY29udGFpbmVyTW9kdWxlSGVscGVycztcbiAgICAgICAgICAgIHJldHVybiBfX2dlbmVyYXRvcih0aGlzLCBmdW5jdGlvbiAoX2IpIHtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKF9iLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldEhlbHBlcnMgPSB0aGlzLl9nZXRDb250YWluZXJNb2R1bGVIZWxwZXJzRmFjdG9yeSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgX2EgPSAwLCBtb2R1bGVzXzIgPSBtb2R1bGVzO1xuICAgICAgICAgICAgICAgICAgICAgICAgX2IubGFiZWwgPSAxO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShfYSA8IG1vZHVsZXNfMi5sZW5ndGgpKSByZXR1cm4gWzMsIDRdO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudE1vZHVsZSA9IG1vZHVsZXNfMltfYV07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250YWluZXJNb2R1bGVIZWxwZXJzID0gZ2V0SGVscGVycyhjdXJyZW50TW9kdWxlLmlkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbNCwgY3VycmVudE1vZHVsZS5yZWdpc3RyeShjb250YWluZXJNb2R1bGVIZWxwZXJzLmJpbmRGdW5jdGlvbiwgY29udGFpbmVyTW9kdWxlSGVscGVycy51bmJpbmRGdW5jdGlvbiwgY29udGFpbmVyTW9kdWxlSGVscGVycy5pc2JvdW5kRnVuY3Rpb24sIGNvbnRhaW5lck1vZHVsZUhlbHBlcnMucmViaW5kRnVuY3Rpb24pXTtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgICAgICAgICAgX2Iuc2VudCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgX2IubGFiZWwgPSAzO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgICAgICAgICBfYSsrO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFszLCAxXTtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0OiByZXR1cm4gWzJdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUudW5sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgbW9kdWxlcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgbW9kdWxlc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICB9XG4gICAgICAgIHZhciBjb25kaXRpb25GYWN0b3J5ID0gZnVuY3Rpb24gKGV4cGVjdGVkKSB7IHJldHVybiBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgcmV0dXJuIGl0ZW0ubW9kdWxlSWQgPT09IGV4cGVjdGVkO1xuICAgICAgICB9OyB9O1xuICAgICAgICBtb2R1bGVzLmZvckVhY2goZnVuY3Rpb24gKG1vZHVsZSkge1xuICAgICAgICAgICAgdmFyIGNvbmRpdGlvbiA9IGNvbmRpdGlvbkZhY3RvcnkobW9kdWxlLmlkKTtcbiAgICAgICAgICAgIF90aGlzLl9iaW5kaW5nRGljdGlvbmFyeS5yZW1vdmVCeUNvbmRpdGlvbihjb25kaXRpb24pO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuYmluZCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICB2YXIgc2NvcGUgPSB0aGlzLm9wdGlvbnMuZGVmYXVsdFNjb3BlIHx8IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nU2NvcGVFbnVtLlRyYW5zaWVudDtcbiAgICAgICAgdmFyIGJpbmRpbmcgPSBuZXcgYmluZGluZ18xLkJpbmRpbmcoc2VydmljZUlkZW50aWZpZXIsIHNjb3BlKTtcbiAgICAgICAgdGhpcy5fYmluZGluZ0RpY3Rpb25hcnkuYWRkKHNlcnZpY2VJZGVudGlmaWVyLCBiaW5kaW5nKTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX3RvX3N5bnRheF8xLkJpbmRpbmdUb1N5bnRheChiaW5kaW5nKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUucmViaW5kID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgICAgIHRoaXMudW5iaW5kKHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuYmluZChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLnVuYmluZCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy5fYmluZGluZ0RpY3Rpb25hcnkucmVtb3ZlKHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuQ0FOTk9UX1VOQklORCArIFwiIFwiICsgc2VyaWFsaXphdGlvbl8xLmdldFNlcnZpY2VJZGVudGlmaWVyQXNTdHJpbmcoc2VydmljZUlkZW50aWZpZXIpKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS51bmJpbmRBbGwgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmdEaWN0aW9uYXJ5ID0gbmV3IGxvb2t1cF8xLkxvb2t1cCgpO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5pc0JvdW5kID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgICAgIHZhciBib3VuZCA9IHRoaXMuX2JpbmRpbmdEaWN0aW9uYXJ5Lmhhc0tleShzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIGlmICghYm91bmQgJiYgdGhpcy5wYXJlbnQpIHtcbiAgICAgICAgICAgIGJvdW5kID0gdGhpcy5wYXJlbnQuaXNCb3VuZChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJvdW5kO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5pc0JvdW5kTmFtZWQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIsIG5hbWVkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzQm91bmRUYWdnZWQoc2VydmljZUlkZW50aWZpZXIsIE1FVEFEQVRBX0tFWS5OQU1FRF9UQUcsIG5hbWVkKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuaXNCb3VuZFRhZ2dlZCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllciwga2V5LCB2YWx1ZSkge1xuICAgICAgICB2YXIgYm91bmQgPSBmYWxzZTtcbiAgICAgICAgaWYgKHRoaXMuX2JpbmRpbmdEaWN0aW9uYXJ5Lmhhc0tleShzZXJ2aWNlSWRlbnRpZmllcikpIHtcbiAgICAgICAgICAgIHZhciBiaW5kaW5ncyA9IHRoaXMuX2JpbmRpbmdEaWN0aW9uYXJ5LmdldChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgICAgICB2YXIgcmVxdWVzdF8xID0gcGxhbm5lcl8xLmNyZWF0ZU1vY2tSZXF1ZXN0KHRoaXMsIHNlcnZpY2VJZGVudGlmaWVyLCBrZXksIHZhbHVlKTtcbiAgICAgICAgICAgIGJvdW5kID0gYmluZGluZ3Muc29tZShmdW5jdGlvbiAoYikgeyByZXR1cm4gYi5jb25zdHJhaW50KHJlcXVlc3RfMSk7IH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghYm91bmQgJiYgdGhpcy5wYXJlbnQpIHtcbiAgICAgICAgICAgIGJvdW5kID0gdGhpcy5wYXJlbnQuaXNCb3VuZFRhZ2dlZChzZXJ2aWNlSWRlbnRpZmllciwga2V5LCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJvdW5kO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5zbmFwc2hvdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5fc25hcHNob3RzLnB1c2goY29udGFpbmVyX3NuYXBzaG90XzEuQ29udGFpbmVyU25hcHNob3Qub2YodGhpcy5fYmluZGluZ0RpY3Rpb25hcnkuY2xvbmUoKSwgdGhpcy5fbWlkZGxld2FyZSkpO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5yZXN0b3JlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc25hcHNob3QgPSB0aGlzLl9zbmFwc2hvdHMucG9wKCk7XG4gICAgICAgIGlmIChzbmFwc2hvdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTVNHUy5OT19NT1JFX1NOQVBTSE9UU19BVkFJTEFCTEUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2JpbmRpbmdEaWN0aW9uYXJ5ID0gc25hcHNob3QuYmluZGluZ3M7XG4gICAgICAgIHRoaXMuX21pZGRsZXdhcmUgPSBzbmFwc2hvdC5taWRkbGV3YXJlO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5jcmVhdGVDaGlsZCA9IGZ1bmN0aW9uIChjb250YWluZXJPcHRpb25zKSB7XG4gICAgICAgIHZhciBjaGlsZCA9IG5ldyBDb250YWluZXIoY29udGFpbmVyT3B0aW9ucyB8fCB0aGlzLm9wdGlvbnMpO1xuICAgICAgICBjaGlsZC5wYXJlbnQgPSB0aGlzO1xuICAgICAgICByZXR1cm4gY2hpbGQ7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmFwcGx5TWlkZGxld2FyZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG1pZGRsZXdhcmVzID0gW107XG4gICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICBtaWRkbGV3YXJlc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2FwcGxpZWRNaWRkbGV3YXJlID0gdGhpcy5fYXBwbGllZE1pZGRsZXdhcmUuY29uY2F0KG1pZGRsZXdhcmVzKTtcbiAgICAgICAgdmFyIGluaXRpYWwgPSAodGhpcy5fbWlkZGxld2FyZSkgPyB0aGlzLl9taWRkbGV3YXJlIDogdGhpcy5fcGxhbkFuZFJlc29sdmUoKTtcbiAgICAgICAgdGhpcy5fbWlkZGxld2FyZSA9IG1pZGRsZXdhcmVzLnJlZHVjZShmdW5jdGlvbiAocHJldiwgY3VycikgeyByZXR1cm4gY3VycihwcmV2KTsgfSwgaW5pdGlhbCk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmFwcGx5Q3VzdG9tTWV0YWRhdGFSZWFkZXIgPSBmdW5jdGlvbiAobWV0YWRhdGFSZWFkZXIpIHtcbiAgICAgICAgdGhpcy5fbWV0YWRhdGFSZWFkZXIgPSBtZXRhZGF0YVJlYWRlcjtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXQoZmFsc2UsIGZhbHNlLCBsaXRlcmFsX3R5cGVzXzEuVGFyZ2V0VHlwZUVudW0uVmFyaWFibGUsIHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuZ2V0VGFnZ2VkID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyLCBrZXksIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXQoZmFsc2UsIGZhbHNlLCBsaXRlcmFsX3R5cGVzXzEuVGFyZ2V0VHlwZUVudW0uVmFyaWFibGUsIHNlcnZpY2VJZGVudGlmaWVyLCBrZXksIHZhbHVlKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuZ2V0TmFtZWQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIsIG5hbWVkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFRhZ2dlZChzZXJ2aWNlSWRlbnRpZmllciwgTUVUQURBVEFfS0VZLk5BTUVEX1RBRywgbmFtZWQpO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5nZXRBbGwgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldCh0cnVlLCB0cnVlLCBsaXRlcmFsX3R5cGVzXzEuVGFyZ2V0VHlwZUVudW0uVmFyaWFibGUsIHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuZ2V0QWxsVGFnZ2VkID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyLCBrZXksIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXQoZmFsc2UsIHRydWUsIGxpdGVyYWxfdHlwZXNfMS5UYXJnZXRUeXBlRW51bS5WYXJpYWJsZSwgc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUpO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5nZXRBbGxOYW1lZCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllciwgbmFtZWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QWxsVGFnZ2VkKHNlcnZpY2VJZGVudGlmaWVyLCBNRVRBREFUQV9LRVkuTkFNRURfVEFHLCBuYW1lZCk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLnJlc29sdmUgPSBmdW5jdGlvbiAoY29uc3RydWN0b3JGdW5jdGlvbikge1xuICAgICAgICB2YXIgdGVtcENvbnRhaW5lciA9IHRoaXMuY3JlYXRlQ2hpbGQoKTtcbiAgICAgICAgdGVtcENvbnRhaW5lci5iaW5kKGNvbnN0cnVjdG9yRnVuY3Rpb24pLnRvU2VsZigpO1xuICAgICAgICB0aGlzLl9hcHBsaWVkTWlkZGxld2FyZS5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICB0ZW1wQ29udGFpbmVyLmFwcGx5TWlkZGxld2FyZShtKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0ZW1wQ29udGFpbmVyLmdldChjb25zdHJ1Y3RvckZ1bmN0aW9uKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuX2dldENvbnRhaW5lck1vZHVsZUhlbHBlcnNGYWN0b3J5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgc2V0TW9kdWxlSWQgPSBmdW5jdGlvbiAoYmluZGluZ1RvU3ludGF4LCBtb2R1bGVJZCkge1xuICAgICAgICAgICAgYmluZGluZ1RvU3ludGF4Ll9iaW5kaW5nLm1vZHVsZUlkID0gbW9kdWxlSWQ7XG4gICAgICAgIH07XG4gICAgICAgIHZhciBnZXRCaW5kRnVuY3Rpb24gPSBmdW5jdGlvbiAobW9kdWxlSWQpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgICAgICAgICB2YXIgX2JpbmQgPSBfdGhpcy5iaW5kLmJpbmQoX3RoaXMpO1xuICAgICAgICAgICAgICAgIHZhciBiaW5kaW5nVG9TeW50YXggPSBfYmluZChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgICAgICAgICAgc2V0TW9kdWxlSWQoYmluZGluZ1RvU3ludGF4LCBtb2R1bGVJZCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGJpbmRpbmdUb1N5bnRheDtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICAgIHZhciBnZXRVbmJpbmRGdW5jdGlvbiA9IGZ1bmN0aW9uIChtb2R1bGVJZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICAgICAgICAgIHZhciBfdW5iaW5kID0gX3RoaXMudW5iaW5kLmJpbmQoX3RoaXMpO1xuICAgICAgICAgICAgICAgIF91bmJpbmQoc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIGdldElzYm91bmRGdW5jdGlvbiA9IGZ1bmN0aW9uIChtb2R1bGVJZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICAgICAgICAgIHZhciBfaXNCb3VuZCA9IF90aGlzLmlzQm91bmQuYmluZChfdGhpcyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9pc0JvdW5kKHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICAgIHZhciBnZXRSZWJpbmRGdW5jdGlvbiA9IGZ1bmN0aW9uIChtb2R1bGVJZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICAgICAgICAgIHZhciBfcmViaW5kID0gX3RoaXMucmViaW5kLmJpbmQoX3RoaXMpO1xuICAgICAgICAgICAgICAgIHZhciBiaW5kaW5nVG9TeW50YXggPSBfcmViaW5kKHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgICAgICAgICBzZXRNb2R1bGVJZChiaW5kaW5nVG9TeW50YXgsIG1vZHVsZUlkKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYmluZGluZ1RvU3ludGF4O1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChtSWQpIHsgcmV0dXJuICh7XG4gICAgICAgICAgICBiaW5kRnVuY3Rpb246IGdldEJpbmRGdW5jdGlvbihtSWQpLFxuICAgICAgICAgICAgaXNib3VuZEZ1bmN0aW9uOiBnZXRJc2JvdW5kRnVuY3Rpb24obUlkKSxcbiAgICAgICAgICAgIHJlYmluZEZ1bmN0aW9uOiBnZXRSZWJpbmRGdW5jdGlvbihtSWQpLFxuICAgICAgICAgICAgdW5iaW5kRnVuY3Rpb246IGdldFVuYmluZEZ1bmN0aW9uKG1JZClcbiAgICAgICAgfSk7IH07XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLl9nZXQgPSBmdW5jdGlvbiAoYXZvaWRDb25zdHJhaW50cywgaXNNdWx0aUluamVjdCwgdGFyZ2V0VHlwZSwgc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IG51bGw7XG4gICAgICAgIHZhciBkZWZhdWx0QXJncyA9IHtcbiAgICAgICAgICAgIGF2b2lkQ29uc3RyYWludHM6IGF2b2lkQ29uc3RyYWludHMsXG4gICAgICAgICAgICBjb250ZXh0SW50ZXJjZXB0b3I6IGZ1bmN0aW9uIChjb250ZXh0KSB7IHJldHVybiBjb250ZXh0OyB9LFxuICAgICAgICAgICAgaXNNdWx0aUluamVjdDogaXNNdWx0aUluamVjdCxcbiAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgc2VydmljZUlkZW50aWZpZXI6IHNlcnZpY2VJZGVudGlmaWVyLFxuICAgICAgICAgICAgdGFyZ2V0VHlwZTogdGFyZ2V0VHlwZSxcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5fbWlkZGxld2FyZSkge1xuICAgICAgICAgICAgcmVzdWx0ID0gdGhpcy5fbWlkZGxld2FyZShkZWZhdWx0QXJncyk7XG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSB1bmRlZmluZWQgfHwgcmVzdWx0ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuSU5WQUxJRF9NSURETEVXQVJFX1JFVFVSTik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXN1bHQgPSB0aGlzLl9wbGFuQW5kUmVzb2x2ZSgpKGRlZmF1bHRBcmdzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5fcGxhbkFuZFJlc29sdmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoYXJncykge1xuICAgICAgICAgICAgdmFyIGNvbnRleHQgPSBwbGFubmVyXzEucGxhbihfdGhpcy5fbWV0YWRhdGFSZWFkZXIsIF90aGlzLCBhcmdzLmlzTXVsdGlJbmplY3QsIGFyZ3MudGFyZ2V0VHlwZSwgYXJncy5zZXJ2aWNlSWRlbnRpZmllciwgYXJncy5rZXksIGFyZ3MudmFsdWUsIGFyZ3MuYXZvaWRDb25zdHJhaW50cyk7XG4gICAgICAgICAgICBjb250ZXh0ID0gYXJncy5jb250ZXh0SW50ZXJjZXB0b3IoY29udGV4dCk7XG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gcmVzb2x2ZXJfMS5yZXNvbHZlKGNvbnRleHQpO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIHJldHVybiBDb250YWluZXI7XG59KCkpO1xuZXhwb3J0cy5Db250YWluZXIgPSBDb250YWluZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb250YWluZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkFzeW5jQ29udGFpbmVyTW9kdWxlID0gZXhwb3J0cy5Db250YWluZXJNb2R1bGUgPSB2b2lkIDA7XG52YXIgaWRfMSA9IHJlcXVpcmUoXCIuLi91dGlscy9pZFwiKTtcbnZhciBDb250YWluZXJNb2R1bGUgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIENvbnRhaW5lck1vZHVsZShyZWdpc3RyeSkge1xuICAgICAgICB0aGlzLmlkID0gaWRfMS5pZCgpO1xuICAgICAgICB0aGlzLnJlZ2lzdHJ5ID0gcmVnaXN0cnk7XG4gICAgfVxuICAgIHJldHVybiBDb250YWluZXJNb2R1bGU7XG59KCkpO1xuZXhwb3J0cy5Db250YWluZXJNb2R1bGUgPSBDb250YWluZXJNb2R1bGU7XG52YXIgQXN5bmNDb250YWluZXJNb2R1bGUgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEFzeW5jQ29udGFpbmVyTW9kdWxlKHJlZ2lzdHJ5KSB7XG4gICAgICAgIHRoaXMuaWQgPSBpZF8xLmlkKCk7XG4gICAgICAgIHRoaXMucmVnaXN0cnkgPSByZWdpc3RyeTtcbiAgICB9XG4gICAgcmV0dXJuIEFzeW5jQ29udGFpbmVyTW9kdWxlO1xufSgpKTtcbmV4cG9ydHMuQXN5bmNDb250YWluZXJNb2R1bGUgPSBBc3luY0NvbnRhaW5lck1vZHVsZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnRhaW5lcl9tb2R1bGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkNvbnRhaW5lclNuYXBzaG90ID0gdm9pZCAwO1xudmFyIENvbnRhaW5lclNuYXBzaG90ID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBDb250YWluZXJTbmFwc2hvdCgpIHtcbiAgICB9XG4gICAgQ29udGFpbmVyU25hcHNob3Qub2YgPSBmdW5jdGlvbiAoYmluZGluZ3MsIG1pZGRsZXdhcmUpIHtcbiAgICAgICAgdmFyIHNuYXBzaG90ID0gbmV3IENvbnRhaW5lclNuYXBzaG90KCk7XG4gICAgICAgIHNuYXBzaG90LmJpbmRpbmdzID0gYmluZGluZ3M7XG4gICAgICAgIHNuYXBzaG90Lm1pZGRsZXdhcmUgPSBtaWRkbGV3YXJlO1xuICAgICAgICByZXR1cm4gc25hcHNob3Q7XG4gICAgfTtcbiAgICByZXR1cm4gQ29udGFpbmVyU25hcHNob3Q7XG59KCkpO1xuZXhwb3J0cy5Db250YWluZXJTbmFwc2hvdCA9IENvbnRhaW5lclNuYXBzaG90O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29udGFpbmVyX3NuYXBzaG90LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5Mb29rdXAgPSB2b2lkIDA7XG52YXIgRVJST1JfTVNHUyA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbnZhciBMb29rdXAgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIExvb2t1cCgpIHtcbiAgICAgICAgdGhpcy5fbWFwID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgICBMb29rdXAucHJvdG90eXBlLmdldE1hcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcDtcbiAgICB9O1xuICAgIExvb2t1cC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyLCB2YWx1ZSkge1xuICAgICAgICBpZiAoc2VydmljZUlkZW50aWZpZXIgPT09IG51bGwgfHwgc2VydmljZUlkZW50aWZpZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuTlVMTF9BUkdVTUVOVCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUl9NU0dTLk5VTExfQVJHVU1FTlQpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBlbnRyeSA9IHRoaXMuX21hcC5nZXQoc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICBpZiAoZW50cnkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgZW50cnkucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgICB0aGlzLl9tYXAuc2V0KHNlcnZpY2VJZGVudGlmaWVyLCBlbnRyeSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9tYXAuc2V0KHNlcnZpY2VJZGVudGlmaWVyLCBbdmFsdWVdKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgTG9va3VwLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgaWYgKHNlcnZpY2VJZGVudGlmaWVyID09PSBudWxsIHx8IHNlcnZpY2VJZGVudGlmaWVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUl9NU0dTLk5VTExfQVJHVU1FTlQpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBlbnRyeSA9IHRoaXMuX21hcC5nZXQoc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICBpZiAoZW50cnkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGVudHJ5O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuS0VZX05PVF9GT1VORCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIExvb2t1cC5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgICAgIGlmIChzZXJ2aWNlSWRlbnRpZmllciA9PT0gbnVsbCB8fCBzZXJ2aWNlSWRlbnRpZmllciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTVNHUy5OVUxMX0FSR1VNRU5UKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuX21hcC5kZWxldGUoc2VydmljZUlkZW50aWZpZXIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTVNHUy5LRVlfTk9UX0ZPVU5EKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgTG9va3VwLnByb3RvdHlwZS5yZW1vdmVCeUNvbmRpdGlvbiA9IGZ1bmN0aW9uIChjb25kaXRpb24pIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdGhpcy5fbWFwLmZvckVhY2goZnVuY3Rpb24gKGVudHJpZXMsIGtleSkge1xuICAgICAgICAgICAgdmFyIHVwZGF0ZWRFbnRyaWVzID0gZW50cmllcy5maWx0ZXIoZnVuY3Rpb24gKGVudHJ5KSB7IHJldHVybiAhY29uZGl0aW9uKGVudHJ5KTsgfSk7XG4gICAgICAgICAgICBpZiAodXBkYXRlZEVudHJpZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIF90aGlzLl9tYXAuc2V0KGtleSwgdXBkYXRlZEVudHJpZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuX21hcC5kZWxldGUoa2V5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBMb29rdXAucHJvdG90eXBlLmhhc0tleSA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICBpZiAoc2VydmljZUlkZW50aWZpZXIgPT09IG51bGwgfHwgc2VydmljZUlkZW50aWZpZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuTlVMTF9BUkdVTUVOVCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcC5oYXMoc2VydmljZUlkZW50aWZpZXIpO1xuICAgIH07XG4gICAgTG9va3VwLnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvcHkgPSBuZXcgTG9va3VwKCk7XG4gICAgICAgIHRoaXMuX21hcC5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICAgICAgICB2YWx1ZS5mb3JFYWNoKGZ1bmN0aW9uIChiKSB7IHJldHVybiBjb3B5LmFkZChrZXksIGIuY2xvbmUoKSk7IH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvcHk7XG4gICAgfTtcbiAgICBMb29rdXAucHJvdG90eXBlLnRyYXZlcnNlID0gZnVuY3Rpb24gKGZ1bmMpIHtcbiAgICAgICAgdGhpcy5fbWFwLmZvckVhY2goZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcbiAgICAgICAgICAgIGZ1bmMoa2V5LCB2YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIExvb2t1cDtcbn0oKSk7XG5leHBvcnRzLkxvb2t1cCA9IExvb2t1cDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxvb2t1cC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMubXVsdGlCaW5kVG9TZXJ2aWNlID0gZXhwb3J0cy5nZXRTZXJ2aWNlSWRlbnRpZmllckFzU3RyaW5nID0gZXhwb3J0cy50eXBlQ29uc3RyYWludCA9IGV4cG9ydHMubmFtZWRDb25zdHJhaW50ID0gZXhwb3J0cy50YWdnZWRDb25zdHJhaW50ID0gZXhwb3J0cy50cmF2ZXJzZUFuY2Vyc3RvcnMgPSBleHBvcnRzLmRlY29yYXRlID0gZXhwb3J0cy5pZCA9IGV4cG9ydHMuTWV0YWRhdGFSZWFkZXIgPSBleHBvcnRzLnBvc3RDb25zdHJ1Y3QgPSBleHBvcnRzLnRhcmdldE5hbWUgPSBleHBvcnRzLm11bHRpSW5qZWN0ID0gZXhwb3J0cy51bm1hbmFnZWQgPSBleHBvcnRzLm9wdGlvbmFsID0gZXhwb3J0cy5MYXp5U2VydmljZUlkZW50aWZlciA9IGV4cG9ydHMuaW5qZWN0ID0gZXhwb3J0cy5uYW1lZCA9IGV4cG9ydHMudGFnZ2VkID0gZXhwb3J0cy5pbmplY3RhYmxlID0gZXhwb3J0cy5Db250YWluZXJNb2R1bGUgPSBleHBvcnRzLkFzeW5jQ29udGFpbmVyTW9kdWxlID0gZXhwb3J0cy5UYXJnZXRUeXBlRW51bSA9IGV4cG9ydHMuQmluZGluZ1R5cGVFbnVtID0gZXhwb3J0cy5CaW5kaW5nU2NvcGVFbnVtID0gZXhwb3J0cy5Db250YWluZXIgPSBleHBvcnRzLk1FVEFEQVRBX0tFWSA9IHZvaWQgMDtcbnZhciBrZXlzID0gcmVxdWlyZShcIi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG5leHBvcnRzLk1FVEFEQVRBX0tFWSA9IGtleXM7XG52YXIgY29udGFpbmVyXzEgPSByZXF1aXJlKFwiLi9jb250YWluZXIvY29udGFpbmVyXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQ29udGFpbmVyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb250YWluZXJfMS5Db250YWluZXI7IH0gfSk7XG52YXIgbGl0ZXJhbF90eXBlc18xID0gcmVxdWlyZShcIi4vY29uc3RhbnRzL2xpdGVyYWxfdHlwZXNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJCaW5kaW5nU2NvcGVFbnVtXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkJpbmRpbmdUeXBlRW51bVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlRhcmdldFR5cGVFbnVtXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBsaXRlcmFsX3R5cGVzXzEuVGFyZ2V0VHlwZUVudW07IH0gfSk7XG52YXIgY29udGFpbmVyX21vZHVsZV8xID0gcmVxdWlyZShcIi4vY29udGFpbmVyL2NvbnRhaW5lcl9tb2R1bGVcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJBc3luY0NvbnRhaW5lck1vZHVsZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29udGFpbmVyX21vZHVsZV8xLkFzeW5jQ29udGFpbmVyTW9kdWxlOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQ29udGFpbmVyTW9kdWxlXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb250YWluZXJfbW9kdWxlXzEuQ29udGFpbmVyTW9kdWxlOyB9IH0pO1xudmFyIGluamVjdGFibGVfMSA9IHJlcXVpcmUoXCIuL2Fubm90YXRpb24vaW5qZWN0YWJsZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImluamVjdGFibGVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGluamVjdGFibGVfMS5pbmplY3RhYmxlOyB9IH0pO1xudmFyIHRhZ2dlZF8xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi90YWdnZWRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ0YWdnZWRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRhZ2dlZF8xLnRhZ2dlZDsgfSB9KTtcbnZhciBuYW1lZF8xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi9uYW1lZFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIm5hbWVkXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBuYW1lZF8xLm5hbWVkOyB9IH0pO1xudmFyIGluamVjdF8xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi9pbmplY3RcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJpbmplY3RcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGluamVjdF8xLmluamVjdDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkxhenlTZXJ2aWNlSWRlbnRpZmVyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBpbmplY3RfMS5MYXp5U2VydmljZUlkZW50aWZlcjsgfSB9KTtcbnZhciBvcHRpb25hbF8xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi9vcHRpb25hbFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIm9wdGlvbmFsXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBvcHRpb25hbF8xLm9wdGlvbmFsOyB9IH0pO1xudmFyIHVubWFuYWdlZF8xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi91bm1hbmFnZWRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ1bm1hbmFnZWRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHVubWFuYWdlZF8xLnVubWFuYWdlZDsgfSB9KTtcbnZhciBtdWx0aV9pbmplY3RfMSA9IHJlcXVpcmUoXCIuL2Fubm90YXRpb24vbXVsdGlfaW5qZWN0XCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwibXVsdGlJbmplY3RcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIG11bHRpX2luamVjdF8xLm11bHRpSW5qZWN0OyB9IH0pO1xudmFyIHRhcmdldF9uYW1lXzEgPSByZXF1aXJlKFwiLi9hbm5vdGF0aW9uL3RhcmdldF9uYW1lXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidGFyZ2V0TmFtZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGFyZ2V0X25hbWVfMS50YXJnZXROYW1lOyB9IH0pO1xudmFyIHBvc3RfY29uc3RydWN0XzEgPSByZXF1aXJlKFwiLi9hbm5vdGF0aW9uL3Bvc3RfY29uc3RydWN0XCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicG9zdENvbnN0cnVjdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gcG9zdF9jb25zdHJ1Y3RfMS5wb3N0Q29uc3RydWN0OyB9IH0pO1xudmFyIG1ldGFkYXRhX3JlYWRlcl8xID0gcmVxdWlyZShcIi4vcGxhbm5pbmcvbWV0YWRhdGFfcmVhZGVyXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiTWV0YWRhdGFSZWFkZXJcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIG1ldGFkYXRhX3JlYWRlcl8xLk1ldGFkYXRhUmVhZGVyOyB9IH0pO1xudmFyIGlkXzEgPSByZXF1aXJlKFwiLi91dGlscy9pZFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImlkXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBpZF8xLmlkOyB9IH0pO1xudmFyIGRlY29yYXRvcl91dGlsc18xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi9kZWNvcmF0b3JfdXRpbHNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJkZWNvcmF0ZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZGVjb3JhdG9yX3V0aWxzXzEuZGVjb3JhdGU7IH0gfSk7XG52YXIgY29uc3RyYWludF9oZWxwZXJzXzEgPSByZXF1aXJlKFwiLi9zeW50YXgvY29uc3RyYWludF9oZWxwZXJzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidHJhdmVyc2VBbmNlcnN0b3JzXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25zdHJhaW50X2hlbHBlcnNfMS50cmF2ZXJzZUFuY2Vyc3RvcnM7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ0YWdnZWRDb25zdHJhaW50XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25zdHJhaW50X2hlbHBlcnNfMS50YWdnZWRDb25zdHJhaW50OyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwibmFtZWRDb25zdHJhaW50XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25zdHJhaW50X2hlbHBlcnNfMS5uYW1lZENvbnN0cmFpbnQ7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ0eXBlQ29uc3RyYWludFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29uc3RyYWludF9oZWxwZXJzXzEudHlwZUNvbnN0cmFpbnQ7IH0gfSk7XG52YXIgc2VyaWFsaXphdGlvbl8xID0gcmVxdWlyZShcIi4vdXRpbHMvc2VyaWFsaXphdGlvblwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImdldFNlcnZpY2VJZGVudGlmaWVyQXNTdHJpbmdcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNlcmlhbGl6YXRpb25fMS5nZXRTZXJ2aWNlSWRlbnRpZmllckFzU3RyaW5nOyB9IH0pO1xudmFyIGJpbmRpbmdfdXRpbHNfMSA9IHJlcXVpcmUoXCIuL3V0aWxzL2JpbmRpbmdfdXRpbHNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJtdWx0aUJpbmRUb1NlcnZpY2VcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJpbmRpbmdfdXRpbHNfMS5tdWx0aUJpbmRUb1NlcnZpY2U7IH0gfSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbnZlcnNpZnkuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkNvbnRleHQgPSB2b2lkIDA7XG52YXIgaWRfMSA9IHJlcXVpcmUoXCIuLi91dGlscy9pZFwiKTtcbnZhciBDb250ZXh0ID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBDb250ZXh0KGNvbnRhaW5lcikge1xuICAgICAgICB0aGlzLmlkID0gaWRfMS5pZCgpO1xuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IGNvbnRhaW5lcjtcbiAgICB9XG4gICAgQ29udGV4dC5wcm90b3R5cGUuYWRkUGxhbiA9IGZ1bmN0aW9uIChwbGFuKSB7XG4gICAgICAgIHRoaXMucGxhbiA9IHBsYW47XG4gICAgfTtcbiAgICBDb250ZXh0LnByb3RvdHlwZS5zZXRDdXJyZW50UmVxdWVzdCA9IGZ1bmN0aW9uIChjdXJyZW50UmVxdWVzdCkge1xuICAgICAgICB0aGlzLmN1cnJlbnRSZXF1ZXN0ID0gY3VycmVudFJlcXVlc3Q7XG4gICAgfTtcbiAgICByZXR1cm4gQ29udGV4dDtcbn0oKSk7XG5leHBvcnRzLkNvbnRleHQgPSBDb250ZXh0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29udGV4dC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuTWV0YWRhdGEgPSB2b2lkIDA7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIE1ldGFkYXRhID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBNZXRhZGF0YShrZXksIHZhbHVlKSB7XG4gICAgICAgIHRoaXMua2V5ID0ga2V5O1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgfVxuICAgIE1ldGFkYXRhLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMua2V5ID09PSBNRVRBREFUQV9LRVkuTkFNRURfVEFHKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJuYW1lZDogXCIgKyB0aGlzLnZhbHVlLnRvU3RyaW5nKCkgKyBcIiBcIjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBcInRhZ2dlZDogeyBrZXk6XCIgKyB0aGlzLmtleS50b1N0cmluZygpICsgXCIsIHZhbHVlOiBcIiArIHRoaXMudmFsdWUgKyBcIiB9XCI7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBNZXRhZGF0YTtcbn0oKSk7XG5leHBvcnRzLk1ldGFkYXRhID0gTWV0YWRhdGE7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tZXRhZGF0YS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuTWV0YWRhdGFSZWFkZXIgPSB2b2lkIDA7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIE1ldGFkYXRhUmVhZGVyID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBNZXRhZGF0YVJlYWRlcigpIHtcbiAgICB9XG4gICAgTWV0YWRhdGFSZWFkZXIucHJvdG90eXBlLmdldENvbnN0cnVjdG9yTWV0YWRhdGEgPSBmdW5jdGlvbiAoY29uc3RydWN0b3JGdW5jKSB7XG4gICAgICAgIHZhciBjb21waWxlckdlbmVyYXRlZE1ldGFkYXRhID0gUmVmbGVjdC5nZXRNZXRhZGF0YShNRVRBREFUQV9LRVkuUEFSQU1fVFlQRVMsIGNvbnN0cnVjdG9yRnVuYyk7XG4gICAgICAgIHZhciB1c2VyR2VuZXJhdGVkTWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKE1FVEFEQVRBX0tFWS5UQUdHRUQsIGNvbnN0cnVjdG9yRnVuYyk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb21waWxlckdlbmVyYXRlZE1ldGFkYXRhOiBjb21waWxlckdlbmVyYXRlZE1ldGFkYXRhLFxuICAgICAgICAgICAgdXNlckdlbmVyYXRlZE1ldGFkYXRhOiB1c2VyR2VuZXJhdGVkTWV0YWRhdGEgfHwge31cbiAgICAgICAgfTtcbiAgICB9O1xuICAgIE1ldGFkYXRhUmVhZGVyLnByb3RvdHlwZS5nZXRQcm9wZXJ0aWVzTWV0YWRhdGEgPSBmdW5jdGlvbiAoY29uc3RydWN0b3JGdW5jKSB7XG4gICAgICAgIHZhciB1c2VyR2VuZXJhdGVkTWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKE1FVEFEQVRBX0tFWS5UQUdHRURfUFJPUCwgY29uc3RydWN0b3JGdW5jKSB8fCBbXTtcbiAgICAgICAgcmV0dXJuIHVzZXJHZW5lcmF0ZWRNZXRhZGF0YTtcbiAgICB9O1xuICAgIHJldHVybiBNZXRhZGF0YVJlYWRlcjtcbn0oKSk7XG5leHBvcnRzLk1ldGFkYXRhUmVhZGVyID0gTWV0YWRhdGFSZWFkZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tZXRhZGF0YV9yZWFkZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLlBsYW4gPSB2b2lkIDA7XG52YXIgUGxhbiA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gUGxhbihwYXJlbnRDb250ZXh0LCByb290UmVxdWVzdCkge1xuICAgICAgICB0aGlzLnBhcmVudENvbnRleHQgPSBwYXJlbnRDb250ZXh0O1xuICAgICAgICB0aGlzLnJvb3RSZXF1ZXN0ID0gcm9vdFJlcXVlc3Q7XG4gICAgfVxuICAgIHJldHVybiBQbGFuO1xufSgpKTtcbmV4cG9ydHMuUGxhbiA9IFBsYW47XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wbGFuLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRCaW5kaW5nRGljdGlvbmFyeSA9IGV4cG9ydHMuY3JlYXRlTW9ja1JlcXVlc3QgPSBleHBvcnRzLnBsYW4gPSB2b2lkIDA7XG52YXIgYmluZGluZ19jb3VudF8xID0gcmVxdWlyZShcIi4uL2JpbmRpbmdzL2JpbmRpbmdfY291bnRcIik7XG52YXIgRVJST1JfTVNHUyA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbnZhciBsaXRlcmFsX3R5cGVzXzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2xpdGVyYWxfdHlwZXNcIik7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIGV4Y2VwdGlvbnNfMSA9IHJlcXVpcmUoXCIuLi91dGlscy9leGNlcHRpb25zXCIpO1xudmFyIHNlcmlhbGl6YXRpb25fMSA9IHJlcXVpcmUoXCIuLi91dGlscy9zZXJpYWxpemF0aW9uXCIpO1xudmFyIGNvbnRleHRfMSA9IHJlcXVpcmUoXCIuL2NvbnRleHRcIik7XG52YXIgbWV0YWRhdGFfMSA9IHJlcXVpcmUoXCIuL21ldGFkYXRhXCIpO1xudmFyIHBsYW5fMSA9IHJlcXVpcmUoXCIuL3BsYW5cIik7XG52YXIgcmVmbGVjdGlvbl91dGlsc18xID0gcmVxdWlyZShcIi4vcmVmbGVjdGlvbl91dGlsc1wiKTtcbnZhciByZXF1ZXN0XzEgPSByZXF1aXJlKFwiLi9yZXF1ZXN0XCIpO1xudmFyIHRhcmdldF8xID0gcmVxdWlyZShcIi4vdGFyZ2V0XCIpO1xuZnVuY3Rpb24gZ2V0QmluZGluZ0RpY3Rpb25hcnkoY250bnIpIHtcbiAgICByZXR1cm4gY250bnIuX2JpbmRpbmdEaWN0aW9uYXJ5O1xufVxuZXhwb3J0cy5nZXRCaW5kaW5nRGljdGlvbmFyeSA9IGdldEJpbmRpbmdEaWN0aW9uYXJ5O1xuZnVuY3Rpb24gX2NyZWF0ZVRhcmdldChpc011bHRpSW5qZWN0LCB0YXJnZXRUeXBlLCBzZXJ2aWNlSWRlbnRpZmllciwgbmFtZSwga2V5LCB2YWx1ZSkge1xuICAgIHZhciBtZXRhZGF0YUtleSA9IGlzTXVsdGlJbmplY3QgPyBNRVRBREFUQV9LRVkuTVVMVElfSU5KRUNUX1RBRyA6IE1FVEFEQVRBX0tFWS5JTkpFQ1RfVEFHO1xuICAgIHZhciBpbmplY3RNZXRhZGF0YSA9IG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKG1ldGFkYXRhS2V5LCBzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgdmFyIHRhcmdldCA9IG5ldyB0YXJnZXRfMS5UYXJnZXQodGFyZ2V0VHlwZSwgbmFtZSwgc2VydmljZUlkZW50aWZpZXIsIGluamVjdE1ldGFkYXRhKTtcbiAgICBpZiAoa2V5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFyIHRhZ01ldGFkYXRhID0gbmV3IG1ldGFkYXRhXzEuTWV0YWRhdGEoa2V5LCB2YWx1ZSk7XG4gICAgICAgIHRhcmdldC5tZXRhZGF0YS5wdXNoKHRhZ01ldGFkYXRhKTtcbiAgICB9XG4gICAgcmV0dXJuIHRhcmdldDtcbn1cbmZ1bmN0aW9uIF9nZXRBY3RpdmVCaW5kaW5ncyhtZXRhZGF0YVJlYWRlciwgYXZvaWRDb25zdHJhaW50cywgY29udGV4dCwgcGFyZW50UmVxdWVzdCwgdGFyZ2V0KSB7XG4gICAgdmFyIGJpbmRpbmdzID0gZ2V0QmluZGluZ3MoY29udGV4dC5jb250YWluZXIsIHRhcmdldC5zZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgdmFyIGFjdGl2ZUJpbmRpbmdzID0gW107XG4gICAgaWYgKGJpbmRpbmdzLmxlbmd0aCA9PT0gYmluZGluZ19jb3VudF8xLkJpbmRpbmdDb3VudC5Ob0JpbmRpbmdzQXZhaWxhYmxlICYmXG4gICAgICAgIGNvbnRleHQuY29udGFpbmVyLm9wdGlvbnMuYXV0b0JpbmRJbmplY3RhYmxlICYmXG4gICAgICAgIHR5cGVvZiB0YXJnZXQuc2VydmljZUlkZW50aWZpZXIgPT09IFwiZnVuY3Rpb25cIiAmJlxuICAgICAgICBtZXRhZGF0YVJlYWRlci5nZXRDb25zdHJ1Y3Rvck1ldGFkYXRhKHRhcmdldC5zZXJ2aWNlSWRlbnRpZmllcikuY29tcGlsZXJHZW5lcmF0ZWRNZXRhZGF0YSkge1xuICAgICAgICBjb250ZXh0LmNvbnRhaW5lci5iaW5kKHRhcmdldC5zZXJ2aWNlSWRlbnRpZmllcikudG9TZWxmKCk7XG4gICAgICAgIGJpbmRpbmdzID0gZ2V0QmluZGluZ3MoY29udGV4dC5jb250YWluZXIsIHRhcmdldC5zZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgfVxuICAgIGlmICghYXZvaWRDb25zdHJhaW50cykge1xuICAgICAgICBhY3RpdmVCaW5kaW5ncyA9IGJpbmRpbmdzLmZpbHRlcihmdW5jdGlvbiAoYmluZGluZykge1xuICAgICAgICAgICAgdmFyIHJlcXVlc3QgPSBuZXcgcmVxdWVzdF8xLlJlcXVlc3QoYmluZGluZy5zZXJ2aWNlSWRlbnRpZmllciwgY29udGV4dCwgcGFyZW50UmVxdWVzdCwgYmluZGluZywgdGFyZ2V0KTtcbiAgICAgICAgICAgIHJldHVybiBiaW5kaW5nLmNvbnN0cmFpbnQocmVxdWVzdCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgYWN0aXZlQmluZGluZ3MgPSBiaW5kaW5ncztcbiAgICB9XG4gICAgX3ZhbGlkYXRlQWN0aXZlQmluZGluZ0NvdW50KHRhcmdldC5zZXJ2aWNlSWRlbnRpZmllciwgYWN0aXZlQmluZGluZ3MsIHRhcmdldCwgY29udGV4dC5jb250YWluZXIpO1xuICAgIHJldHVybiBhY3RpdmVCaW5kaW5ncztcbn1cbmZ1bmN0aW9uIF92YWxpZGF0ZUFjdGl2ZUJpbmRpbmdDb3VudChzZXJ2aWNlSWRlbnRpZmllciwgYmluZGluZ3MsIHRhcmdldCwgY29udGFpbmVyKSB7XG4gICAgc3dpdGNoIChiaW5kaW5ncy5sZW5ndGgpIHtcbiAgICAgICAgY2FzZSBiaW5kaW5nX2NvdW50XzEuQmluZGluZ0NvdW50Lk5vQmluZGluZ3NBdmFpbGFibGU6XG4gICAgICAgICAgICBpZiAodGFyZ2V0LmlzT3B0aW9uYWwoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBiaW5kaW5ncztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBzZXJ2aWNlSWRlbnRpZmllclN0cmluZyA9IHNlcmlhbGl6YXRpb25fMS5nZXRTZXJ2aWNlSWRlbnRpZmllckFzU3RyaW5nKHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgICAgICAgICB2YXIgbXNnID0gRVJST1JfTVNHUy5OT1RfUkVHSVNURVJFRDtcbiAgICAgICAgICAgICAgICBtc2cgKz0gc2VyaWFsaXphdGlvbl8xLmxpc3RNZXRhZGF0YUZvclRhcmdldChzZXJ2aWNlSWRlbnRpZmllclN0cmluZywgdGFyZ2V0KTtcbiAgICAgICAgICAgICAgICBtc2cgKz0gc2VyaWFsaXphdGlvbl8xLmxpc3RSZWdpc3RlcmVkQmluZGluZ3NGb3JTZXJ2aWNlSWRlbnRpZmllcihjb250YWluZXIsIHNlcnZpY2VJZGVudGlmaWVyU3RyaW5nLCBnZXRCaW5kaW5ncyk7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgYmluZGluZ19jb3VudF8xLkJpbmRpbmdDb3VudC5Pbmx5T25lQmluZGluZ0F2YWlsYWJsZTpcbiAgICAgICAgICAgIGlmICghdGFyZ2V0LmlzQXJyYXkoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBiaW5kaW5ncztcbiAgICAgICAgICAgIH1cbiAgICAgICAgY2FzZSBiaW5kaW5nX2NvdW50XzEuQmluZGluZ0NvdW50Lk11bHRpcGxlQmluZGluZ3NBdmFpbGFibGU6XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBpZiAoIXRhcmdldC5pc0FycmF5KCkpIHtcbiAgICAgICAgICAgICAgICB2YXIgc2VydmljZUlkZW50aWZpZXJTdHJpbmcgPSBzZXJpYWxpemF0aW9uXzEuZ2V0U2VydmljZUlkZW50aWZpZXJBc1N0cmluZyhzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgICAgICAgICAgdmFyIG1zZyA9IEVSUk9SX01TR1MuQU1CSUdVT1VTX01BVENIICsgXCIgXCIgKyBzZXJ2aWNlSWRlbnRpZmllclN0cmluZztcbiAgICAgICAgICAgICAgICBtc2cgKz0gc2VyaWFsaXphdGlvbl8xLmxpc3RSZWdpc3RlcmVkQmluZGluZ3NGb3JTZXJ2aWNlSWRlbnRpZmllcihjb250YWluZXIsIHNlcnZpY2VJZGVudGlmaWVyU3RyaW5nLCBnZXRCaW5kaW5ncyk7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYmluZGluZ3M7XG4gICAgICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gX2NyZWF0ZVN1YlJlcXVlc3RzKG1ldGFkYXRhUmVhZGVyLCBhdm9pZENvbnN0cmFpbnRzLCBzZXJ2aWNlSWRlbnRpZmllciwgY29udGV4dCwgcGFyZW50UmVxdWVzdCwgdGFyZ2V0KSB7XG4gICAgdmFyIGFjdGl2ZUJpbmRpbmdzO1xuICAgIHZhciBjaGlsZFJlcXVlc3Q7XG4gICAgaWYgKHBhcmVudFJlcXVlc3QgPT09IG51bGwpIHtcbiAgICAgICAgYWN0aXZlQmluZGluZ3MgPSBfZ2V0QWN0aXZlQmluZGluZ3MobWV0YWRhdGFSZWFkZXIsIGF2b2lkQ29uc3RyYWludHMsIGNvbnRleHQsIG51bGwsIHRhcmdldCk7XG4gICAgICAgIGNoaWxkUmVxdWVzdCA9IG5ldyByZXF1ZXN0XzEuUmVxdWVzdChzZXJ2aWNlSWRlbnRpZmllciwgY29udGV4dCwgbnVsbCwgYWN0aXZlQmluZGluZ3MsIHRhcmdldCk7XG4gICAgICAgIHZhciB0aGVQbGFuID0gbmV3IHBsYW5fMS5QbGFuKGNvbnRleHQsIGNoaWxkUmVxdWVzdCk7XG4gICAgICAgIGNvbnRleHQuYWRkUGxhbih0aGVQbGFuKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGFjdGl2ZUJpbmRpbmdzID0gX2dldEFjdGl2ZUJpbmRpbmdzKG1ldGFkYXRhUmVhZGVyLCBhdm9pZENvbnN0cmFpbnRzLCBjb250ZXh0LCBwYXJlbnRSZXF1ZXN0LCB0YXJnZXQpO1xuICAgICAgICBjaGlsZFJlcXVlc3QgPSBwYXJlbnRSZXF1ZXN0LmFkZENoaWxkUmVxdWVzdCh0YXJnZXQuc2VydmljZUlkZW50aWZpZXIsIGFjdGl2ZUJpbmRpbmdzLCB0YXJnZXQpO1xuICAgIH1cbiAgICBhY3RpdmVCaW5kaW5ncy5mb3JFYWNoKGZ1bmN0aW9uIChiaW5kaW5nKSB7XG4gICAgICAgIHZhciBzdWJDaGlsZFJlcXVlc3QgPSBudWxsO1xuICAgICAgICBpZiAodGFyZ2V0LmlzQXJyYXkoKSkge1xuICAgICAgICAgICAgc3ViQ2hpbGRSZXF1ZXN0ID0gY2hpbGRSZXF1ZXN0LmFkZENoaWxkUmVxdWVzdChiaW5kaW5nLnNlcnZpY2VJZGVudGlmaWVyLCBiaW5kaW5nLCB0YXJnZXQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKGJpbmRpbmcuY2FjaGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdWJDaGlsZFJlcXVlc3QgPSBjaGlsZFJlcXVlc3Q7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJpbmRpbmcudHlwZSA9PT0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5JbnN0YW5jZSAmJiBiaW5kaW5nLmltcGxlbWVudGF0aW9uVHlwZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGRlcGVuZGVuY2llcyA9IHJlZmxlY3Rpb25fdXRpbHNfMS5nZXREZXBlbmRlbmNpZXMobWV0YWRhdGFSZWFkZXIsIGJpbmRpbmcuaW1wbGVtZW50YXRpb25UeXBlKTtcbiAgICAgICAgICAgIGlmICghY29udGV4dC5jb250YWluZXIub3B0aW9ucy5za2lwQmFzZUNsYXNzQ2hlY2tzKSB7XG4gICAgICAgICAgICAgICAgdmFyIGJhc2VDbGFzc0RlcGVuZGVuY3lDb3VudCA9IHJlZmxlY3Rpb25fdXRpbHNfMS5nZXRCYXNlQ2xhc3NEZXBlbmRlbmN5Q291bnQobWV0YWRhdGFSZWFkZXIsIGJpbmRpbmcuaW1wbGVtZW50YXRpb25UeXBlKTtcbiAgICAgICAgICAgICAgICBpZiAoZGVwZW5kZW5jaWVzLmxlbmd0aCA8IGJhc2VDbGFzc0RlcGVuZGVuY3lDb3VudCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSBFUlJPUl9NU0dTLkFSR1VNRU5UU19MRU5HVEhfTUlTTUFUQ0gocmVmbGVjdGlvbl91dGlsc18xLmdldEZ1bmN0aW9uTmFtZShiaW5kaW5nLmltcGxlbWVudGF0aW9uVHlwZSkpO1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlcGVuZGVuY2llcy5mb3JFYWNoKGZ1bmN0aW9uIChkZXBlbmRlbmN5KSB7XG4gICAgICAgICAgICAgICAgX2NyZWF0ZVN1YlJlcXVlc3RzKG1ldGFkYXRhUmVhZGVyLCBmYWxzZSwgZGVwZW5kZW5jeS5zZXJ2aWNlSWRlbnRpZmllciwgY29udGV4dCwgc3ViQ2hpbGRSZXF1ZXN0LCBkZXBlbmRlbmN5KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5mdW5jdGlvbiBnZXRCaW5kaW5ncyhjb250YWluZXIsIHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgdmFyIGJpbmRpbmdzID0gW107XG4gICAgdmFyIGJpbmRpbmdEaWN0aW9uYXJ5ID0gZ2V0QmluZGluZ0RpY3Rpb25hcnkoY29udGFpbmVyKTtcbiAgICBpZiAoYmluZGluZ0RpY3Rpb25hcnkuaGFzS2V5KHNlcnZpY2VJZGVudGlmaWVyKSkge1xuICAgICAgICBiaW5kaW5ncyA9IGJpbmRpbmdEaWN0aW9uYXJ5LmdldChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgfVxuICAgIGVsc2UgaWYgKGNvbnRhaW5lci5wYXJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgYmluZGluZ3MgPSBnZXRCaW5kaW5ncyhjb250YWluZXIucGFyZW50LCBzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgfVxuICAgIHJldHVybiBiaW5kaW5ncztcbn1cbmZ1bmN0aW9uIHBsYW4obWV0YWRhdGFSZWFkZXIsIGNvbnRhaW5lciwgaXNNdWx0aUluamVjdCwgdGFyZ2V0VHlwZSwgc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUsIGF2b2lkQ29uc3RyYWludHMpIHtcbiAgICBpZiAoYXZvaWRDb25zdHJhaW50cyA9PT0gdm9pZCAwKSB7IGF2b2lkQ29uc3RyYWludHMgPSBmYWxzZTsgfVxuICAgIHZhciBjb250ZXh0ID0gbmV3IGNvbnRleHRfMS5Db250ZXh0KGNvbnRhaW5lcik7XG4gICAgdmFyIHRhcmdldCA9IF9jcmVhdGVUYXJnZXQoaXNNdWx0aUluamVjdCwgdGFyZ2V0VHlwZSwgc2VydmljZUlkZW50aWZpZXIsIFwiXCIsIGtleSwgdmFsdWUpO1xuICAgIHRyeSB7XG4gICAgICAgIF9jcmVhdGVTdWJSZXF1ZXN0cyhtZXRhZGF0YVJlYWRlciwgYXZvaWRDb25zdHJhaW50cywgc2VydmljZUlkZW50aWZpZXIsIGNvbnRleHQsIG51bGwsIHRhcmdldCk7XG4gICAgICAgIHJldHVybiBjb250ZXh0O1xuICAgIH1cbiAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKGV4Y2VwdGlvbnNfMS5pc1N0YWNrT3ZlcmZsb3dFeGVwdGlvbihlcnJvcikpIHtcbiAgICAgICAgICAgIGlmIChjb250ZXh0LnBsYW4pIHtcbiAgICAgICAgICAgICAgICBzZXJpYWxpemF0aW9uXzEuY2lyY3VsYXJEZXBlbmRlbmN5VG9FeGNlcHRpb24oY29udGV4dC5wbGFuLnJvb3RSZXF1ZXN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG59XG5leHBvcnRzLnBsYW4gPSBwbGFuO1xuZnVuY3Rpb24gY3JlYXRlTW9ja1JlcXVlc3QoY29udGFpbmVyLCBzZXJ2aWNlSWRlbnRpZmllciwga2V5LCB2YWx1ZSkge1xuICAgIHZhciB0YXJnZXQgPSBuZXcgdGFyZ2V0XzEuVGFyZ2V0KGxpdGVyYWxfdHlwZXNfMS5UYXJnZXRUeXBlRW51bS5WYXJpYWJsZSwgXCJcIiwgc2VydmljZUlkZW50aWZpZXIsIG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKGtleSwgdmFsdWUpKTtcbiAgICB2YXIgY29udGV4dCA9IG5ldyBjb250ZXh0XzEuQ29udGV4dChjb250YWluZXIpO1xuICAgIHZhciByZXF1ZXN0ID0gbmV3IHJlcXVlc3RfMS5SZXF1ZXN0KHNlcnZpY2VJZGVudGlmaWVyLCBjb250ZXh0LCBudWxsLCBbXSwgdGFyZ2V0KTtcbiAgICByZXR1cm4gcmVxdWVzdDtcbn1cbmV4cG9ydHMuY3JlYXRlTW9ja1JlcXVlc3QgPSBjcmVhdGVNb2NrUmVxdWVzdDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBsYW5uZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLlF1ZXJ5YWJsZVN0cmluZyA9IHZvaWQgMDtcbnZhciBRdWVyeWFibGVTdHJpbmcgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFF1ZXJ5YWJsZVN0cmluZyhzdHIpIHtcbiAgICAgICAgdGhpcy5zdHIgPSBzdHI7XG4gICAgfVxuICAgIFF1ZXJ5YWJsZVN0cmluZy5wcm90b3R5cGUuc3RhcnRzV2l0aCA9IGZ1bmN0aW9uIChzZWFyY2hTdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RyLmluZGV4T2Yoc2VhcmNoU3RyaW5nKSA9PT0gMDtcbiAgICB9O1xuICAgIFF1ZXJ5YWJsZVN0cmluZy5wcm90b3R5cGUuZW5kc1dpdGggPSBmdW5jdGlvbiAoc2VhcmNoU3RyaW5nKSB7XG4gICAgICAgIHZhciByZXZlcnNlU3RyaW5nID0gXCJcIjtcbiAgICAgICAgdmFyIHJldmVyc2VTZWFyY2hTdHJpbmcgPSBzZWFyY2hTdHJpbmcuc3BsaXQoXCJcIikucmV2ZXJzZSgpLmpvaW4oXCJcIik7XG4gICAgICAgIHJldmVyc2VTdHJpbmcgPSB0aGlzLnN0ci5zcGxpdChcIlwiKS5yZXZlcnNlKCkuam9pbihcIlwiKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhcnRzV2l0aC5jYWxsKHsgc3RyOiByZXZlcnNlU3RyaW5nIH0sIHJldmVyc2VTZWFyY2hTdHJpbmcpO1xuICAgIH07XG4gICAgUXVlcnlhYmxlU3RyaW5nLnByb3RvdHlwZS5jb250YWlucyA9IGZ1bmN0aW9uIChzZWFyY2hTdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLnN0ci5pbmRleE9mKHNlYXJjaFN0cmluZykgIT09IC0xKTtcbiAgICB9O1xuICAgIFF1ZXJ5YWJsZVN0cmluZy5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gKGNvbXBhcmVTdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RyID09PSBjb21wYXJlU3RyaW5nO1xuICAgIH07XG4gICAgUXVlcnlhYmxlU3RyaW5nLnByb3RvdHlwZS52YWx1ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RyO1xuICAgIH07XG4gICAgcmV0dXJuIFF1ZXJ5YWJsZVN0cmluZztcbn0oKSk7XG5leHBvcnRzLlF1ZXJ5YWJsZVN0cmluZyA9IFF1ZXJ5YWJsZVN0cmluZztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXF1ZXJ5YWJsZV9zdHJpbmcuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgX19zcHJlYWRBcnJheSA9ICh0aGlzICYmIHRoaXMuX19zcHJlYWRBcnJheSkgfHwgZnVuY3Rpb24gKHRvLCBmcm9tKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGlsID0gZnJvbS5sZW5ndGgsIGogPSB0by5sZW5ndGg7IGkgPCBpbDsgaSsrLCBqKyspXG4gICAgICAgIHRvW2pdID0gZnJvbVtpXTtcbiAgICByZXR1cm4gdG87XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRGdW5jdGlvbk5hbWUgPSBleHBvcnRzLmdldEJhc2VDbGFzc0RlcGVuZGVuY3lDb3VudCA9IGV4cG9ydHMuZ2V0RGVwZW5kZW5jaWVzID0gdm9pZCAwO1xudmFyIGluamVjdF8xID0gcmVxdWlyZShcIi4uL2Fubm90YXRpb24vaW5qZWN0XCIpO1xudmFyIEVSUk9SX01TR1MgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2Vycm9yX21zZ3NcIik7XG52YXIgbGl0ZXJhbF90eXBlc18xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9saXRlcmFsX3R5cGVzXCIpO1xudmFyIE1FVEFEQVRBX0tFWSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbWV0YWRhdGFfa2V5c1wiKTtcbnZhciBzZXJpYWxpemF0aW9uXzEgPSByZXF1aXJlKFwiLi4vdXRpbHMvc2VyaWFsaXphdGlvblwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImdldEZ1bmN0aW9uTmFtZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gc2VyaWFsaXphdGlvbl8xLmdldEZ1bmN0aW9uTmFtZTsgfSB9KTtcbnZhciB0YXJnZXRfMSA9IHJlcXVpcmUoXCIuL3RhcmdldFwiKTtcbmZ1bmN0aW9uIGdldERlcGVuZGVuY2llcyhtZXRhZGF0YVJlYWRlciwgZnVuYykge1xuICAgIHZhciBjb25zdHJ1Y3Rvck5hbWUgPSBzZXJpYWxpemF0aW9uXzEuZ2V0RnVuY3Rpb25OYW1lKGZ1bmMpO1xuICAgIHZhciB0YXJnZXRzID0gZ2V0VGFyZ2V0cyhtZXRhZGF0YVJlYWRlciwgY29uc3RydWN0b3JOYW1lLCBmdW5jLCBmYWxzZSk7XG4gICAgcmV0dXJuIHRhcmdldHM7XG59XG5leHBvcnRzLmdldERlcGVuZGVuY2llcyA9IGdldERlcGVuZGVuY2llcztcbmZ1bmN0aW9uIGdldFRhcmdldHMobWV0YWRhdGFSZWFkZXIsIGNvbnN0cnVjdG9yTmFtZSwgZnVuYywgaXNCYXNlQ2xhc3MpIHtcbiAgICB2YXIgbWV0YWRhdGEgPSBtZXRhZGF0YVJlYWRlci5nZXRDb25zdHJ1Y3Rvck1ldGFkYXRhKGZ1bmMpO1xuICAgIHZhciBzZXJ2aWNlSWRlbnRpZmllcnMgPSBtZXRhZGF0YS5jb21waWxlckdlbmVyYXRlZE1ldGFkYXRhO1xuICAgIGlmIChzZXJ2aWNlSWRlbnRpZmllcnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB2YXIgbXNnID0gRVJST1JfTVNHUy5NSVNTSU5HX0lOSkVDVEFCTEVfQU5OT1RBVElPTiArIFwiIFwiICsgY29uc3RydWN0b3JOYW1lICsgXCIuXCI7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICAgIH1cbiAgICB2YXIgY29uc3RydWN0b3JBcmdzTWV0YWRhdGEgPSBtZXRhZGF0YS51c2VyR2VuZXJhdGVkTWV0YWRhdGE7XG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhjb25zdHJ1Y3RvckFyZ3NNZXRhZGF0YSk7XG4gICAgdmFyIGhhc1VzZXJEZWNsYXJlZFVua25vd25JbmplY3Rpb25zID0gKGZ1bmMubGVuZ3RoID09PSAwICYmIGtleXMubGVuZ3RoID4gMCk7XG4gICAgdmFyIGhhc09wdGlvbmFsUGFyYW1ldGVycyA9IGtleXMubGVuZ3RoID4gZnVuYy5sZW5ndGg7XG4gICAgdmFyIGl0ZXJhdGlvbnMgPSAoaGFzVXNlckRlY2xhcmVkVW5rbm93bkluamVjdGlvbnMgfHwgaGFzT3B0aW9uYWxQYXJhbWV0ZXJzKSA/IGtleXMubGVuZ3RoIDogZnVuYy5sZW5ndGg7XG4gICAgdmFyIGNvbnN0cnVjdG9yVGFyZ2V0cyA9IGdldENvbnN0cnVjdG9yQXJnc0FzVGFyZ2V0cyhpc0Jhc2VDbGFzcywgY29uc3RydWN0b3JOYW1lLCBzZXJ2aWNlSWRlbnRpZmllcnMsIGNvbnN0cnVjdG9yQXJnc01ldGFkYXRhLCBpdGVyYXRpb25zKTtcbiAgICB2YXIgcHJvcGVydHlUYXJnZXRzID0gZ2V0Q2xhc3NQcm9wc0FzVGFyZ2V0cyhtZXRhZGF0YVJlYWRlciwgZnVuYyk7XG4gICAgdmFyIHRhcmdldHMgPSBfX3NwcmVhZEFycmF5KF9fc3ByZWFkQXJyYXkoW10sIGNvbnN0cnVjdG9yVGFyZ2V0cyksIHByb3BlcnR5VGFyZ2V0cyk7XG4gICAgcmV0dXJuIHRhcmdldHM7XG59XG5mdW5jdGlvbiBnZXRDb25zdHJ1Y3RvckFyZ3NBc1RhcmdldChpbmRleCwgaXNCYXNlQ2xhc3MsIGNvbnN0cnVjdG9yTmFtZSwgc2VydmljZUlkZW50aWZpZXJzLCBjb25zdHJ1Y3RvckFyZ3NNZXRhZGF0YSkge1xuICAgIHZhciB0YXJnZXRNZXRhZGF0YSA9IGNvbnN0cnVjdG9yQXJnc01ldGFkYXRhW2luZGV4LnRvU3RyaW5nKCldIHx8IFtdO1xuICAgIHZhciBtZXRhZGF0YSA9IGZvcm1hdFRhcmdldE1ldGFkYXRhKHRhcmdldE1ldGFkYXRhKTtcbiAgICB2YXIgaXNNYW5hZ2VkID0gbWV0YWRhdGEudW5tYW5hZ2VkICE9PSB0cnVlO1xuICAgIHZhciBzZXJ2aWNlSWRlbnRpZmllciA9IHNlcnZpY2VJZGVudGlmaWVyc1tpbmRleF07XG4gICAgdmFyIGluamVjdElkZW50aWZpZXIgPSAobWV0YWRhdGEuaW5qZWN0IHx8IG1ldGFkYXRhLm11bHRpSW5qZWN0KTtcbiAgICBzZXJ2aWNlSWRlbnRpZmllciA9IChpbmplY3RJZGVudGlmaWVyKSA/IChpbmplY3RJZGVudGlmaWVyKSA6IHNlcnZpY2VJZGVudGlmaWVyO1xuICAgIGlmIChzZXJ2aWNlSWRlbnRpZmllciBpbnN0YW5jZW9mIGluamVjdF8xLkxhenlTZXJ2aWNlSWRlbnRpZmVyKSB7XG4gICAgICAgIHNlcnZpY2VJZGVudGlmaWVyID0gc2VydmljZUlkZW50aWZpZXIudW53cmFwKCk7XG4gICAgfVxuICAgIGlmIChpc01hbmFnZWQpIHtcbiAgICAgICAgdmFyIGlzT2JqZWN0ID0gc2VydmljZUlkZW50aWZpZXIgPT09IE9iamVjdDtcbiAgICAgICAgdmFyIGlzRnVuY3Rpb24gPSBzZXJ2aWNlSWRlbnRpZmllciA9PT0gRnVuY3Rpb247XG4gICAgICAgIHZhciBpc1VuZGVmaW5lZCA9IHNlcnZpY2VJZGVudGlmaWVyID09PSB1bmRlZmluZWQ7XG4gICAgICAgIHZhciBpc1Vua25vd25UeXBlID0gKGlzT2JqZWN0IHx8IGlzRnVuY3Rpb24gfHwgaXNVbmRlZmluZWQpO1xuICAgICAgICBpZiAoIWlzQmFzZUNsYXNzICYmIGlzVW5rbm93blR5cGUpIHtcbiAgICAgICAgICAgIHZhciBtc2cgPSBFUlJPUl9NU0dTLk1JU1NJTkdfSU5KRUNUX0FOTk9UQVRJT04gKyBcIiBhcmd1bWVudCBcIiArIGluZGV4ICsgXCIgaW4gY2xhc3MgXCIgKyBjb25zdHJ1Y3Rvck5hbWUgKyBcIi5cIjtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0YXJnZXQgPSBuZXcgdGFyZ2V0XzEuVGFyZ2V0KGxpdGVyYWxfdHlwZXNfMS5UYXJnZXRUeXBlRW51bS5Db25zdHJ1Y3RvckFyZ3VtZW50LCBtZXRhZGF0YS50YXJnZXROYW1lLCBzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIHRhcmdldC5tZXRhZGF0YSA9IHRhcmdldE1ldGFkYXRhO1xuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cbmZ1bmN0aW9uIGdldENvbnN0cnVjdG9yQXJnc0FzVGFyZ2V0cyhpc0Jhc2VDbGFzcywgY29uc3RydWN0b3JOYW1lLCBzZXJ2aWNlSWRlbnRpZmllcnMsIGNvbnN0cnVjdG9yQXJnc01ldGFkYXRhLCBpdGVyYXRpb25zKSB7XG4gICAgdmFyIHRhcmdldHMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGl0ZXJhdGlvbnM7IGkrKykge1xuICAgICAgICB2YXIgaW5kZXggPSBpO1xuICAgICAgICB2YXIgdGFyZ2V0ID0gZ2V0Q29uc3RydWN0b3JBcmdzQXNUYXJnZXQoaW5kZXgsIGlzQmFzZUNsYXNzLCBjb25zdHJ1Y3Rvck5hbWUsIHNlcnZpY2VJZGVudGlmaWVycywgY29uc3RydWN0b3JBcmdzTWV0YWRhdGEpO1xuICAgICAgICBpZiAodGFyZ2V0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0YXJnZXRzLnB1c2godGFyZ2V0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGFyZ2V0cztcbn1cbmZ1bmN0aW9uIGdldENsYXNzUHJvcHNBc1RhcmdldHMobWV0YWRhdGFSZWFkZXIsIGNvbnN0cnVjdG9yRnVuYykge1xuICAgIHZhciBjbGFzc1Byb3BzTWV0YWRhdGEgPSBtZXRhZGF0YVJlYWRlci5nZXRQcm9wZXJ0aWVzTWV0YWRhdGEoY29uc3RydWN0b3JGdW5jKTtcbiAgICB2YXIgdGFyZ2V0cyA9IFtdO1xuICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMoY2xhc3NQcm9wc01ldGFkYXRhKTtcbiAgICBmb3IgKHZhciBfaSA9IDAsIGtleXNfMSA9IGtleXM7IF9pIDwga2V5c18xLmxlbmd0aDsgX2krKykge1xuICAgICAgICB2YXIga2V5ID0ga2V5c18xW19pXTtcbiAgICAgICAgdmFyIHRhcmdldE1ldGFkYXRhID0gY2xhc3NQcm9wc01ldGFkYXRhW2tleV07XG4gICAgICAgIHZhciBtZXRhZGF0YSA9IGZvcm1hdFRhcmdldE1ldGFkYXRhKGNsYXNzUHJvcHNNZXRhZGF0YVtrZXldKTtcbiAgICAgICAgdmFyIHRhcmdldE5hbWUgPSBtZXRhZGF0YS50YXJnZXROYW1lIHx8IGtleTtcbiAgICAgICAgdmFyIHNlcnZpY2VJZGVudGlmaWVyID0gKG1ldGFkYXRhLmluamVjdCB8fCBtZXRhZGF0YS5tdWx0aUluamVjdCk7XG4gICAgICAgIHZhciB0YXJnZXQgPSBuZXcgdGFyZ2V0XzEuVGFyZ2V0KGxpdGVyYWxfdHlwZXNfMS5UYXJnZXRUeXBlRW51bS5DbGFzc1Byb3BlcnR5LCB0YXJnZXROYW1lLCBzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIHRhcmdldC5tZXRhZGF0YSA9IHRhcmdldE1ldGFkYXRhO1xuICAgICAgICB0YXJnZXRzLnB1c2godGFyZ2V0KTtcbiAgICB9XG4gICAgdmFyIGJhc2VDb25zdHJ1Y3RvciA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihjb25zdHJ1Y3RvckZ1bmMucHJvdG90eXBlKS5jb25zdHJ1Y3RvcjtcbiAgICBpZiAoYmFzZUNvbnN0cnVjdG9yICE9PSBPYmplY3QpIHtcbiAgICAgICAgdmFyIGJhc2VUYXJnZXRzID0gZ2V0Q2xhc3NQcm9wc0FzVGFyZ2V0cyhtZXRhZGF0YVJlYWRlciwgYmFzZUNvbnN0cnVjdG9yKTtcbiAgICAgICAgdGFyZ2V0cyA9IF9fc3ByZWFkQXJyYXkoX19zcHJlYWRBcnJheShbXSwgdGFyZ2V0cyksIGJhc2VUYXJnZXRzKTtcbiAgICB9XG4gICAgcmV0dXJuIHRhcmdldHM7XG59XG5mdW5jdGlvbiBnZXRCYXNlQ2xhc3NEZXBlbmRlbmN5Q291bnQobWV0YWRhdGFSZWFkZXIsIGZ1bmMpIHtcbiAgICB2YXIgYmFzZUNvbnN0cnVjdG9yID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKGZ1bmMucHJvdG90eXBlKS5jb25zdHJ1Y3RvcjtcbiAgICBpZiAoYmFzZUNvbnN0cnVjdG9yICE9PSBPYmplY3QpIHtcbiAgICAgICAgdmFyIGJhc2VDb25zdHJ1Y3Rvck5hbWUgPSBzZXJpYWxpemF0aW9uXzEuZ2V0RnVuY3Rpb25OYW1lKGJhc2VDb25zdHJ1Y3Rvcik7XG4gICAgICAgIHZhciB0YXJnZXRzID0gZ2V0VGFyZ2V0cyhtZXRhZGF0YVJlYWRlciwgYmFzZUNvbnN0cnVjdG9yTmFtZSwgYmFzZUNvbnN0cnVjdG9yLCB0cnVlKTtcbiAgICAgICAgdmFyIG1ldGFkYXRhID0gdGFyZ2V0cy5tYXAoZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgICAgIHJldHVybiB0Lm1ldGFkYXRhLmZpbHRlcihmdW5jdGlvbiAobSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtLmtleSA9PT0gTUVUQURBVEFfS0VZLlVOTUFOQUdFRF9UQUc7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciB1bm1hbmFnZWRDb3VudCA9IFtdLmNvbmNhdC5hcHBseShbXSwgbWV0YWRhdGEpLmxlbmd0aDtcbiAgICAgICAgdmFyIGRlcGVuZGVuY3lDb3VudCA9IHRhcmdldHMubGVuZ3RoIC0gdW5tYW5hZ2VkQ291bnQ7XG4gICAgICAgIGlmIChkZXBlbmRlbmN5Q291bnQgPiAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZGVwZW5kZW5jeUNvdW50O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGdldEJhc2VDbGFzc0RlcGVuZGVuY3lDb3VudChtZXRhZGF0YVJlYWRlciwgYmFzZUNvbnN0cnVjdG9yKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxufVxuZXhwb3J0cy5nZXRCYXNlQ2xhc3NEZXBlbmRlbmN5Q291bnQgPSBnZXRCYXNlQ2xhc3NEZXBlbmRlbmN5Q291bnQ7XG5mdW5jdGlvbiBmb3JtYXRUYXJnZXRNZXRhZGF0YSh0YXJnZXRNZXRhZGF0YSkge1xuICAgIHZhciB0YXJnZXRNZXRhZGF0YU1hcCA9IHt9O1xuICAgIHRhcmdldE1ldGFkYXRhLmZvckVhY2goZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgdGFyZ2V0TWV0YWRhdGFNYXBbbS5rZXkudG9TdHJpbmcoKV0gPSBtLnZhbHVlO1xuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICAgIGluamVjdDogdGFyZ2V0TWV0YWRhdGFNYXBbTUVUQURBVEFfS0VZLklOSkVDVF9UQUddLFxuICAgICAgICBtdWx0aUluamVjdDogdGFyZ2V0TWV0YWRhdGFNYXBbTUVUQURBVEFfS0VZLk1VTFRJX0lOSkVDVF9UQUddLFxuICAgICAgICB0YXJnZXROYW1lOiB0YXJnZXRNZXRhZGF0YU1hcFtNRVRBREFUQV9LRVkuTkFNRV9UQUddLFxuICAgICAgICB1bm1hbmFnZWQ6IHRhcmdldE1ldGFkYXRhTWFwW01FVEFEQVRBX0tFWS5VTk1BTkFHRURfVEFHXVxuICAgIH07XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1yZWZsZWN0aW9uX3V0aWxzLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5SZXF1ZXN0ID0gdm9pZCAwO1xudmFyIGlkXzEgPSByZXF1aXJlKFwiLi4vdXRpbHMvaWRcIik7XG52YXIgUmVxdWVzdCA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gUmVxdWVzdChzZXJ2aWNlSWRlbnRpZmllciwgcGFyZW50Q29udGV4dCwgcGFyZW50UmVxdWVzdCwgYmluZGluZ3MsIHRhcmdldCkge1xuICAgICAgICB0aGlzLmlkID0gaWRfMS5pZCgpO1xuICAgICAgICB0aGlzLnNlcnZpY2VJZGVudGlmaWVyID0gc2VydmljZUlkZW50aWZpZXI7XG4gICAgICAgIHRoaXMucGFyZW50Q29udGV4dCA9IHBhcmVudENvbnRleHQ7XG4gICAgICAgIHRoaXMucGFyZW50UmVxdWVzdCA9IHBhcmVudFJlcXVlc3Q7XG4gICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgICAgICB0aGlzLmNoaWxkUmVxdWVzdHMgPSBbXTtcbiAgICAgICAgdGhpcy5iaW5kaW5ncyA9IChBcnJheS5pc0FycmF5KGJpbmRpbmdzKSA/IGJpbmRpbmdzIDogW2JpbmRpbmdzXSk7XG4gICAgICAgIHRoaXMucmVxdWVzdFNjb3BlID0gcGFyZW50UmVxdWVzdCA9PT0gbnVsbFxuICAgICAgICAgICAgPyBuZXcgTWFwKClcbiAgICAgICAgICAgIDogbnVsbDtcbiAgICB9XG4gICAgUmVxdWVzdC5wcm90b3R5cGUuYWRkQ2hpbGRSZXF1ZXN0ID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyLCBiaW5kaW5ncywgdGFyZ2V0KSB7XG4gICAgICAgIHZhciBjaGlsZCA9IG5ldyBSZXF1ZXN0KHNlcnZpY2VJZGVudGlmaWVyLCB0aGlzLnBhcmVudENvbnRleHQsIHRoaXMsIGJpbmRpbmdzLCB0YXJnZXQpO1xuICAgICAgICB0aGlzLmNoaWxkUmVxdWVzdHMucHVzaChjaGlsZCk7XG4gICAgICAgIHJldHVybiBjaGlsZDtcbiAgICB9O1xuICAgIHJldHVybiBSZXF1ZXN0O1xufSgpKTtcbmV4cG9ydHMuUmVxdWVzdCA9IFJlcXVlc3Q7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1yZXF1ZXN0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5UYXJnZXQgPSB2b2lkIDA7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIGlkXzEgPSByZXF1aXJlKFwiLi4vdXRpbHMvaWRcIik7XG52YXIgbWV0YWRhdGFfMSA9IHJlcXVpcmUoXCIuL21ldGFkYXRhXCIpO1xudmFyIHF1ZXJ5YWJsZV9zdHJpbmdfMSA9IHJlcXVpcmUoXCIuL3F1ZXJ5YWJsZV9zdHJpbmdcIik7XG52YXIgVGFyZ2V0ID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBUYXJnZXQodHlwZSwgbmFtZSwgc2VydmljZUlkZW50aWZpZXIsIG5hbWVkT3JUYWdnZWQpIHtcbiAgICAgICAgdGhpcy5pZCA9IGlkXzEuaWQoKTtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5zZXJ2aWNlSWRlbnRpZmllciA9IHNlcnZpY2VJZGVudGlmaWVyO1xuICAgICAgICB0aGlzLm5hbWUgPSBuZXcgcXVlcnlhYmxlX3N0cmluZ18xLlF1ZXJ5YWJsZVN0cmluZyhuYW1lIHx8IFwiXCIpO1xuICAgICAgICB0aGlzLm1ldGFkYXRhID0gbmV3IEFycmF5KCk7XG4gICAgICAgIHZhciBtZXRhZGF0YUl0ZW0gPSBudWxsO1xuICAgICAgICBpZiAodHlwZW9mIG5hbWVkT3JUYWdnZWQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIG1ldGFkYXRhSXRlbSA9IG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKE1FVEFEQVRBX0tFWS5OQU1FRF9UQUcsIG5hbWVkT3JUYWdnZWQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG5hbWVkT3JUYWdnZWQgaW5zdGFuY2VvZiBtZXRhZGF0YV8xLk1ldGFkYXRhKSB7XG4gICAgICAgICAgICBtZXRhZGF0YUl0ZW0gPSBuYW1lZE9yVGFnZ2VkO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXRhZGF0YUl0ZW0gIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMubWV0YWRhdGEucHVzaChtZXRhZGF0YUl0ZW0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIFRhcmdldC5wcm90b3R5cGUuaGFzVGFnID0gZnVuY3Rpb24gKGtleSkge1xuICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gdGhpcy5tZXRhZGF0YTsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIHZhciBtID0gX2FbX2ldO1xuICAgICAgICAgICAgaWYgKG0ua2V5ID09PSBrZXkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbiAgICBUYXJnZXQucHJvdG90eXBlLmlzQXJyYXkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmhhc1RhZyhNRVRBREFUQV9LRVkuTVVMVElfSU5KRUNUX1RBRyk7XG4gICAgfTtcbiAgICBUYXJnZXQucHJvdG90eXBlLm1hdGNoZXNBcnJheSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hdGNoZXNUYWcoTUVUQURBVEFfS0VZLk1VTFRJX0lOSkVDVF9UQUcpKG5hbWUpO1xuICAgIH07XG4gICAgVGFyZ2V0LnByb3RvdHlwZS5pc05hbWVkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5oYXNUYWcoTUVUQURBVEFfS0VZLk5BTUVEX1RBRyk7XG4gICAgfTtcbiAgICBUYXJnZXQucHJvdG90eXBlLmlzVGFnZ2VkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tZXRhZGF0YS5zb21lKGZ1bmN0aW9uIChtZXRhZGF0YSkgeyByZXR1cm4gTUVUQURBVEFfS0VZLk5PTl9DVVNUT01fVEFHX0tFWVMuZXZlcnkoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gbWV0YWRhdGEua2V5ICE9PSBrZXk7IH0pOyB9KTtcbiAgICB9O1xuICAgIFRhcmdldC5wcm90b3R5cGUuaXNPcHRpb25hbCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWF0Y2hlc1RhZyhNRVRBREFUQV9LRVkuT1BUSU9OQUxfVEFHKSh0cnVlKTtcbiAgICB9O1xuICAgIFRhcmdldC5wcm90b3R5cGUuZ2V0TmFtZWRUYWcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzTmFtZWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGEuZmlsdGVyKGZ1bmN0aW9uIChtKSB7IHJldHVybiBtLmtleSA9PT0gTUVUQURBVEFfS0VZLk5BTUVEX1RBRzsgfSlbMF07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgICBUYXJnZXQucHJvdG90eXBlLmdldEN1c3RvbVRhZ3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzVGFnZ2VkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhLmZpbHRlcihmdW5jdGlvbiAobWV0YWRhdGEpIHsgcmV0dXJuIE1FVEFEQVRBX0tFWS5OT05fQ1VTVE9NX1RBR19LRVlTLmV2ZXJ5KGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIG1ldGFkYXRhLmtleSAhPT0ga2V5OyB9KTsgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH07XG4gICAgVGFyZ2V0LnByb3RvdHlwZS5tYXRjaGVzTmFtZWRUYWcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXRjaGVzVGFnKE1FVEFEQVRBX0tFWS5OQU1FRF9UQUcpKG5hbWUpO1xuICAgIH07XG4gICAgVGFyZ2V0LnByb3RvdHlwZS5tYXRjaGVzVGFnID0gZnVuY3Rpb24gKGtleSkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gX3RoaXMubWV0YWRhdGE7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIG0gPSBfYVtfaV07XG4gICAgICAgICAgICAgICAgaWYgKG0ua2V5ID09PSBrZXkgJiYgbS52YWx1ZSA9PT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIFRhcmdldDtcbn0oKSk7XG5leHBvcnRzLlRhcmdldCA9IFRhcmdldDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRhcmdldC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbnZhciBfX3NwcmVhZEFycmF5ID0gKHRoaXMgJiYgdGhpcy5fX3NwcmVhZEFycmF5KSB8fCBmdW5jdGlvbiAodG8sIGZyb20pIHtcbiAgICBmb3IgKHZhciBpID0gMCwgaWwgPSBmcm9tLmxlbmd0aCwgaiA9IHRvLmxlbmd0aDsgaSA8IGlsOyBpKyssIGorKylcbiAgICAgICAgdG9bal0gPSBmcm9tW2ldO1xuICAgIHJldHVybiB0bztcbn07XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnJlc29sdmVJbnN0YW5jZSA9IHZvaWQgMDtcbnZhciBlcnJvcl9tc2dzXzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2Vycm9yX21zZ3NcIik7XG52YXIgbGl0ZXJhbF90eXBlc18xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9saXRlcmFsX3R5cGVzXCIpO1xudmFyIE1FVEFEQVRBX0tFWSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbWV0YWRhdGFfa2V5c1wiKTtcbmZ1bmN0aW9uIF9pbmplY3RQcm9wZXJ0aWVzKGluc3RhbmNlLCBjaGlsZFJlcXVlc3RzLCByZXNvbHZlUmVxdWVzdCkge1xuICAgIHZhciBwcm9wZXJ0eUluamVjdGlvbnNSZXF1ZXN0cyA9IGNoaWxkUmVxdWVzdHMuZmlsdGVyKGZ1bmN0aW9uIChjaGlsZFJlcXVlc3QpIHtcbiAgICAgICAgcmV0dXJuIChjaGlsZFJlcXVlc3QudGFyZ2V0ICE9PSBudWxsICYmXG4gICAgICAgICAgICBjaGlsZFJlcXVlc3QudGFyZ2V0LnR5cGUgPT09IGxpdGVyYWxfdHlwZXNfMS5UYXJnZXRUeXBlRW51bS5DbGFzc1Byb3BlcnR5KTtcbiAgICB9KTtcbiAgICB2YXIgcHJvcGVydHlJbmplY3Rpb25zID0gcHJvcGVydHlJbmplY3Rpb25zUmVxdWVzdHMubWFwKHJlc29sdmVSZXF1ZXN0KTtcbiAgICBwcm9wZXJ0eUluamVjdGlvbnNSZXF1ZXN0cy5mb3JFYWNoKGZ1bmN0aW9uIChyLCBpbmRleCkge1xuICAgICAgICB2YXIgcHJvcGVydHlOYW1lID0gXCJcIjtcbiAgICAgICAgcHJvcGVydHlOYW1lID0gci50YXJnZXQubmFtZS52YWx1ZSgpO1xuICAgICAgICB2YXIgaW5qZWN0aW9uID0gcHJvcGVydHlJbmplY3Rpb25zW2luZGV4XTtcbiAgICAgICAgaW5zdGFuY2VbcHJvcGVydHlOYW1lXSA9IGluamVjdGlvbjtcbiAgICB9KTtcbiAgICByZXR1cm4gaW5zdGFuY2U7XG59XG5mdW5jdGlvbiBfY3JlYXRlSW5zdGFuY2UoRnVuYywgaW5qZWN0aW9ucykge1xuICAgIHJldHVybiBuZXcgKEZ1bmMuYmluZC5hcHBseShGdW5jLCBfX3NwcmVhZEFycmF5KFt2b2lkIDBdLCBpbmplY3Rpb25zKSkpKCk7XG59XG5mdW5jdGlvbiBfcG9zdENvbnN0cnVjdChjb25zdHIsIHJlc3VsdCkge1xuICAgIGlmIChSZWZsZWN0Lmhhc01ldGFkYXRhKE1FVEFEQVRBX0tFWS5QT1NUX0NPTlNUUlVDVCwgY29uc3RyKSkge1xuICAgICAgICB2YXIgZGF0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoTUVUQURBVEFfS0VZLlBPU1RfQ09OU1RSVUNULCBjb25zdHIpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmVzdWx0W2RhdGEudmFsdWVdKCk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcl9tc2dzXzEuUE9TVF9DT05TVFJVQ1RfRVJST1IoY29uc3RyLm5hbWUsIGUubWVzc2FnZSkpO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gcmVzb2x2ZUluc3RhbmNlKGNvbnN0ciwgY2hpbGRSZXF1ZXN0cywgcmVzb2x2ZVJlcXVlc3QpIHtcbiAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICBpZiAoY2hpbGRSZXF1ZXN0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHZhciBjb25zdHJ1Y3RvckluamVjdGlvbnNSZXF1ZXN0cyA9IGNoaWxkUmVxdWVzdHMuZmlsdGVyKGZ1bmN0aW9uIChjaGlsZFJlcXVlc3QpIHtcbiAgICAgICAgICAgIHJldHVybiAoY2hpbGRSZXF1ZXN0LnRhcmdldCAhPT0gbnVsbCAmJiBjaGlsZFJlcXVlc3QudGFyZ2V0LnR5cGUgPT09IGxpdGVyYWxfdHlwZXNfMS5UYXJnZXRUeXBlRW51bS5Db25zdHJ1Y3RvckFyZ3VtZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciBjb25zdHJ1Y3RvckluamVjdGlvbnMgPSBjb25zdHJ1Y3RvckluamVjdGlvbnNSZXF1ZXN0cy5tYXAocmVzb2x2ZVJlcXVlc3QpO1xuICAgICAgICByZXN1bHQgPSBfY3JlYXRlSW5zdGFuY2UoY29uc3RyLCBjb25zdHJ1Y3RvckluamVjdGlvbnMpO1xuICAgICAgICByZXN1bHQgPSBfaW5qZWN0UHJvcGVydGllcyhyZXN1bHQsIGNoaWxkUmVxdWVzdHMsIHJlc29sdmVSZXF1ZXN0KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJlc3VsdCA9IG5ldyBjb25zdHIoKTtcbiAgICB9XG4gICAgX3Bvc3RDb25zdHJ1Y3QoY29uc3RyLCByZXN1bHQpO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5leHBvcnRzLnJlc29sdmVJbnN0YW5jZSA9IHJlc29sdmVJbnN0YW5jZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluc3RhbnRpYXRpb24uanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnJlc29sdmUgPSB2b2lkIDA7XG52YXIgRVJST1JfTVNHUyA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbnZhciBsaXRlcmFsX3R5cGVzXzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2xpdGVyYWxfdHlwZXNcIik7XG52YXIgZXhjZXB0aW9uc18xID0gcmVxdWlyZShcIi4uL3V0aWxzL2V4Y2VwdGlvbnNcIik7XG52YXIgc2VyaWFsaXphdGlvbl8xID0gcmVxdWlyZShcIi4uL3V0aWxzL3NlcmlhbGl6YXRpb25cIik7XG52YXIgaW5zdGFudGlhdGlvbl8xID0gcmVxdWlyZShcIi4vaW5zdGFudGlhdGlvblwiKTtcbnZhciBpbnZva2VGYWN0b3J5ID0gZnVuY3Rpb24gKGZhY3RvcnlUeXBlLCBzZXJ2aWNlSWRlbnRpZmllciwgZm4pIHtcbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gZm4oKTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmIChleGNlcHRpb25zXzEuaXNTdGFja092ZXJmbG93RXhlcHRpb24oZXJyb3IpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTVNHUy5DSVJDVUxBUl9ERVBFTkRFTkNZX0lOX0ZBQ1RPUlkoZmFjdG9yeVR5cGUsIHNlcnZpY2VJZGVudGlmaWVyLnRvU3RyaW5nKCkpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgfVxufTtcbnZhciBfcmVzb2x2ZVJlcXVlc3QgPSBmdW5jdGlvbiAocmVxdWVzdFNjb3BlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG4gICAgICAgIHJlcXVlc3QucGFyZW50Q29udGV4dC5zZXRDdXJyZW50UmVxdWVzdChyZXF1ZXN0KTtcbiAgICAgICAgdmFyIGJpbmRpbmdzID0gcmVxdWVzdC5iaW5kaW5ncztcbiAgICAgICAgdmFyIGNoaWxkUmVxdWVzdHMgPSByZXF1ZXN0LmNoaWxkUmVxdWVzdHM7XG4gICAgICAgIHZhciB0YXJnZXRJc0FuQXJyYXkgPSByZXF1ZXN0LnRhcmdldCAmJiByZXF1ZXN0LnRhcmdldC5pc0FycmF5KCk7XG4gICAgICAgIHZhciB0YXJnZXRQYXJlbnRJc05vdEFuQXJyYXkgPSAhcmVxdWVzdC5wYXJlbnRSZXF1ZXN0IHx8XG4gICAgICAgICAgICAhcmVxdWVzdC5wYXJlbnRSZXF1ZXN0LnRhcmdldCB8fFxuICAgICAgICAgICAgIXJlcXVlc3QudGFyZ2V0IHx8XG4gICAgICAgICAgICAhcmVxdWVzdC5wYXJlbnRSZXF1ZXN0LnRhcmdldC5tYXRjaGVzQXJyYXkocmVxdWVzdC50YXJnZXQuc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICBpZiAodGFyZ2V0SXNBbkFycmF5ICYmIHRhcmdldFBhcmVudElzTm90QW5BcnJheSkge1xuICAgICAgICAgICAgcmV0dXJuIGNoaWxkUmVxdWVzdHMubWFwKGZ1bmN0aW9uIChjaGlsZFJlcXVlc3QpIHtcbiAgICAgICAgICAgICAgICB2YXIgX2YgPSBfcmVzb2x2ZVJlcXVlc3QocmVxdWVzdFNjb3BlKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2YoY2hpbGRSZXF1ZXN0KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IG51bGw7XG4gICAgICAgICAgICBpZiAocmVxdWVzdC50YXJnZXQuaXNPcHRpb25hbCgpICYmIGJpbmRpbmdzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgYmluZGluZ18xID0gYmluZGluZ3NbMF07XG4gICAgICAgICAgICB2YXIgaXNTaW5nbGV0b24gPSBiaW5kaW5nXzEuc2NvcGUgPT09IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nU2NvcGVFbnVtLlNpbmdsZXRvbjtcbiAgICAgICAgICAgIHZhciBpc1JlcXVlc3RTaW5nbGV0b24gPSBiaW5kaW5nXzEuc2NvcGUgPT09IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nU2NvcGVFbnVtLlJlcXVlc3Q7XG4gICAgICAgICAgICBpZiAoaXNTaW5nbGV0b24gJiYgYmluZGluZ18xLmFjdGl2YXRlZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBiaW5kaW5nXzEuY2FjaGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNSZXF1ZXN0U2luZ2xldG9uICYmXG4gICAgICAgICAgICAgICAgcmVxdWVzdFNjb3BlICE9PSBudWxsICYmXG4gICAgICAgICAgICAgICAgcmVxdWVzdFNjb3BlLmhhcyhiaW5kaW5nXzEuaWQpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3RTY29wZS5nZXQoYmluZGluZ18xLmlkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChiaW5kaW5nXzEudHlwZSA9PT0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5Db25zdGFudFZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gYmluZGluZ18xLmNhY2hlO1xuICAgICAgICAgICAgICAgIGJpbmRpbmdfMS5hY3RpdmF0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoYmluZGluZ18xLnR5cGUgPT09IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uRnVuY3Rpb24pIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBiaW5kaW5nXzEuY2FjaGU7XG4gICAgICAgICAgICAgICAgYmluZGluZ18xLmFjdGl2YXRlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChiaW5kaW5nXzEudHlwZSA9PT0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5Db25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGJpbmRpbmdfMS5pbXBsZW1lbnRhdGlvblR5cGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChiaW5kaW5nXzEudHlwZSA9PT0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5EeW5hbWljVmFsdWUgJiYgYmluZGluZ18xLmR5bmFtaWNWYWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGludm9rZUZhY3RvcnkoXCJ0b0R5bmFtaWNWYWx1ZVwiLCBiaW5kaW5nXzEuc2VydmljZUlkZW50aWZpZXIsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJpbmRpbmdfMS5keW5hbWljVmFsdWUocmVxdWVzdC5wYXJlbnRDb250ZXh0KTsgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChiaW5kaW5nXzEudHlwZSA9PT0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5GYWN0b3J5ICYmIGJpbmRpbmdfMS5mYWN0b3J5ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gaW52b2tlRmFjdG9yeShcInRvRmFjdG9yeVwiLCBiaW5kaW5nXzEuc2VydmljZUlkZW50aWZpZXIsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJpbmRpbmdfMS5mYWN0b3J5KHJlcXVlc3QucGFyZW50Q29udGV4dCk7IH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoYmluZGluZ18xLnR5cGUgPT09IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uUHJvdmlkZXIgJiYgYmluZGluZ18xLnByb3ZpZGVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gaW52b2tlRmFjdG9yeShcInRvUHJvdmlkZXJcIiwgYmluZGluZ18xLnNlcnZpY2VJZGVudGlmaWVyLCBmdW5jdGlvbiAoKSB7IHJldHVybiBiaW5kaW5nXzEucHJvdmlkZXIocmVxdWVzdC5wYXJlbnRDb250ZXh0KTsgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChiaW5kaW5nXzEudHlwZSA9PT0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5JbnN0YW5jZSAmJiBiaW5kaW5nXzEuaW1wbGVtZW50YXRpb25UeXBlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gaW5zdGFudGlhdGlvbl8xLnJlc29sdmVJbnN0YW5jZShiaW5kaW5nXzEuaW1wbGVtZW50YXRpb25UeXBlLCBjaGlsZFJlcXVlc3RzLCBfcmVzb2x2ZVJlcXVlc3QocmVxdWVzdFNjb3BlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgc2VydmljZUlkZW50aWZpZXIgPSBzZXJpYWxpemF0aW9uXzEuZ2V0U2VydmljZUlkZW50aWZpZXJBc1N0cmluZyhyZXF1ZXN0LnNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTVNHUy5JTlZBTElEX0JJTkRJTkdfVFlQRSArIFwiIFwiICsgc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBiaW5kaW5nXzEub25BY3RpdmF0aW9uID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBiaW5kaW5nXzEub25BY3RpdmF0aW9uKHJlcXVlc3QucGFyZW50Q29udGV4dCwgcmVzdWx0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc1NpbmdsZXRvbikge1xuICAgICAgICAgICAgICAgIGJpbmRpbmdfMS5jYWNoZSA9IHJlc3VsdDtcbiAgICAgICAgICAgICAgICBiaW5kaW5nXzEuYWN0aXZhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc1JlcXVlc3RTaW5nbGV0b24gJiZcbiAgICAgICAgICAgICAgICByZXF1ZXN0U2NvcGUgIT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICAhcmVxdWVzdFNjb3BlLmhhcyhiaW5kaW5nXzEuaWQpKSB7XG4gICAgICAgICAgICAgICAgcmVxdWVzdFNjb3BlLnNldChiaW5kaW5nXzEuaWQsIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgfTtcbn07XG5mdW5jdGlvbiByZXNvbHZlKGNvbnRleHQpIHtcbiAgICB2YXIgX2YgPSBfcmVzb2x2ZVJlcXVlc3QoY29udGV4dC5wbGFuLnJvb3RSZXF1ZXN0LnJlcXVlc3RTY29wZSk7XG4gICAgcmV0dXJuIF9mKGNvbnRleHQucGxhbi5yb290UmVxdWVzdCk7XG59XG5leHBvcnRzLnJlc29sdmUgPSByZXNvbHZlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVzb2x2ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkJpbmRpbmdJblN5bnRheCA9IHZvaWQgMDtcbnZhciBsaXRlcmFsX3R5cGVzXzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2xpdGVyYWxfdHlwZXNcIik7XG52YXIgYmluZGluZ193aGVuX29uX3N5bnRheF8xID0gcmVxdWlyZShcIi4vYmluZGluZ193aGVuX29uX3N5bnRheFwiKTtcbnZhciBCaW5kaW5nSW5TeW50YXggPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEJpbmRpbmdJblN5bnRheChiaW5kaW5nKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcgPSBiaW5kaW5nO1xuICAgIH1cbiAgICBCaW5kaW5nSW5TeW50YXgucHJvdG90eXBlLmluUmVxdWVzdFNjb3BlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLnNjb3BlID0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdTY29wZUVudW0uUmVxdWVzdDtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX3doZW5fb25fc3ludGF4XzEuQmluZGluZ1doZW5PblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJblN5bnRheC5wcm90b3R5cGUuaW5TaW5nbGV0b25TY29wZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5zY29wZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nU2NvcGVFbnVtLlNpbmdsZXRvbjtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX3doZW5fb25fc3ludGF4XzEuQmluZGluZ1doZW5PblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJblN5bnRheC5wcm90b3R5cGUuaW5UcmFuc2llbnRTY29wZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5zY29wZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nU2NvcGVFbnVtLlRyYW5zaWVudDtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX3doZW5fb25fc3ludGF4XzEuQmluZGluZ1doZW5PblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIHJldHVybiBCaW5kaW5nSW5TeW50YXg7XG59KCkpO1xuZXhwb3J0cy5CaW5kaW5nSW5TeW50YXggPSBCaW5kaW5nSW5TeW50YXg7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iaW5kaW5nX2luX3N5bnRheC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuQmluZGluZ0luV2hlbk9uU3ludGF4ID0gdm9pZCAwO1xudmFyIGJpbmRpbmdfaW5fc3ludGF4XzEgPSByZXF1aXJlKFwiLi9iaW5kaW5nX2luX3N5bnRheFwiKTtcbnZhciBiaW5kaW5nX29uX3N5bnRheF8xID0gcmVxdWlyZShcIi4vYmluZGluZ19vbl9zeW50YXhcIik7XG52YXIgYmluZGluZ193aGVuX3N5bnRheF8xID0gcmVxdWlyZShcIi4vYmluZGluZ193aGVuX3N5bnRheFwiKTtcbnZhciBCaW5kaW5nSW5XaGVuT25TeW50YXggPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEJpbmRpbmdJbldoZW5PblN5bnRheChiaW5kaW5nKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcgPSBiaW5kaW5nO1xuICAgICAgICB0aGlzLl9iaW5kaW5nV2hlblN5bnRheCA9IG5ldyBiaW5kaW5nX3doZW5fc3ludGF4XzEuQmluZGluZ1doZW5TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgICAgIHRoaXMuX2JpbmRpbmdPblN5bnRheCA9IG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICAgICAgdGhpcy5fYmluZGluZ0luU3ludGF4ID0gbmV3IGJpbmRpbmdfaW5fc3ludGF4XzEuQmluZGluZ0luU3ludGF4KGJpbmRpbmcpO1xuICAgIH1cbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLmluUmVxdWVzdFNjb3BlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ0luU3ludGF4LmluUmVxdWVzdFNjb3BlKCk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLmluU2luZ2xldG9uU2NvcGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nSW5TeW50YXguaW5TaW5nbGV0b25TY29wZSgpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS5pblRyYW5zaWVudFNjb3BlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ0luU3ludGF4LmluVHJhbnNpZW50U2NvcGUoKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlbiA9IGZ1bmN0aW9uIChjb25zdHJhaW50KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuKGNvbnN0cmFpbnQpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuVGFyZ2V0TmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlblRhcmdldE5hbWVkKG5hbWUpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuVGFyZ2V0SXNEZWZhdWx0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlblRhcmdldElzRGVmYXVsdCgpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuVGFyZ2V0VGFnZ2VkID0gZnVuY3Rpb24gKHRhZywgdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5UYXJnZXRUYWdnZWQodGFnLCB2YWx1ZSk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5JbmplY3RlZEludG8gPSBmdW5jdGlvbiAocGFyZW50KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuSW5qZWN0ZWRJbnRvKHBhcmVudCk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5QYXJlbnROYW1lZCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuUGFyZW50TmFtZWQobmFtZSk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5QYXJlbnRUYWdnZWQgPSBmdW5jdGlvbiAodGFnLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlblBhcmVudFRhZ2dlZCh0YWcsIHZhbHVlKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlbkFueUFuY2VzdG9ySXMgPSBmdW5jdGlvbiAoYW5jZXN0b3IpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5BbnlBbmNlc3RvcklzKGFuY2VzdG9yKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlbk5vQW5jZXN0b3JJcyA9IGZ1bmN0aW9uIChhbmNlc3Rvcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbk5vQW5jZXN0b3JJcyhhbmNlc3Rvcik7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5BbnlBbmNlc3Rvck5hbWVkID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5BbnlBbmNlc3Rvck5hbWVkKG5hbWUpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuQW55QW5jZXN0b3JUYWdnZWQgPSBmdW5jdGlvbiAodGFnLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbkFueUFuY2VzdG9yVGFnZ2VkKHRhZywgdmFsdWUpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuTm9BbmNlc3Rvck5hbWVkID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5Ob0FuY2VzdG9yTmFtZWQobmFtZSk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5Ob0FuY2VzdG9yVGFnZ2VkID0gZnVuY3Rpb24gKHRhZywgdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5Ob0FuY2VzdG9yVGFnZ2VkKHRhZywgdmFsdWUpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuQW55QW5jZXN0b3JNYXRjaGVzID0gZnVuY3Rpb24gKGNvbnN0cmFpbnQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5BbnlBbmNlc3Rvck1hdGNoZXMoY29uc3RyYWludCk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5Ob0FuY2VzdG9yTWF0Y2hlcyA9IGZ1bmN0aW9uIChjb25zdHJhaW50KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuTm9BbmNlc3Rvck1hdGNoZXMoY29uc3RyYWludCk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLm9uQWN0aXZhdGlvbiA9IGZ1bmN0aW9uIChoYW5kbGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nT25TeW50YXgub25BY3RpdmF0aW9uKGhhbmRsZXIpO1xuICAgIH07XG4gICAgcmV0dXJuIEJpbmRpbmdJbldoZW5PblN5bnRheDtcbn0oKSk7XG5leHBvcnRzLkJpbmRpbmdJbldoZW5PblN5bnRheCA9IEJpbmRpbmdJbldoZW5PblN5bnRheDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJpbmRpbmdfaW5fd2hlbl9vbl9zeW50YXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkJpbmRpbmdPblN5bnRheCA9IHZvaWQgMDtcbnZhciBiaW5kaW5nX3doZW5fc3ludGF4XzEgPSByZXF1aXJlKFwiLi9iaW5kaW5nX3doZW5fc3ludGF4XCIpO1xudmFyIEJpbmRpbmdPblN5bnRheCA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQmluZGluZ09uU3ludGF4KGJpbmRpbmcpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZyA9IGJpbmRpbmc7XG4gICAgfVxuICAgIEJpbmRpbmdPblN5bnRheC5wcm90b3R5cGUub25BY3RpdmF0aW9uID0gZnVuY3Rpb24gKGhhbmRsZXIpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5vbkFjdGl2YXRpb24gPSBoYW5kbGVyO1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfd2hlbl9zeW50YXhfMS5CaW5kaW5nV2hlblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIHJldHVybiBCaW5kaW5nT25TeW50YXg7XG59KCkpO1xuZXhwb3J0cy5CaW5kaW5nT25TeW50YXggPSBCaW5kaW5nT25TeW50YXg7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iaW5kaW5nX29uX3N5bnRheC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuQmluZGluZ1RvU3ludGF4ID0gdm9pZCAwO1xudmFyIEVSUk9SX01TR1MgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2Vycm9yX21zZ3NcIik7XG52YXIgbGl0ZXJhbF90eXBlc18xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9saXRlcmFsX3R5cGVzXCIpO1xudmFyIGJpbmRpbmdfaW5fd2hlbl9vbl9zeW50YXhfMSA9IHJlcXVpcmUoXCIuL2JpbmRpbmdfaW5fd2hlbl9vbl9zeW50YXhcIik7XG52YXIgYmluZGluZ193aGVuX29uX3N5bnRheF8xID0gcmVxdWlyZShcIi4vYmluZGluZ193aGVuX29uX3N5bnRheFwiKTtcbnZhciBCaW5kaW5nVG9TeW50YXggPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEJpbmRpbmdUb1N5bnRheChiaW5kaW5nKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcgPSBiaW5kaW5nO1xuICAgIH1cbiAgICBCaW5kaW5nVG9TeW50YXgucHJvdG90eXBlLnRvID0gZnVuY3Rpb24gKGNvbnN0cnVjdG9yKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcudHlwZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uSW5zdGFuY2U7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuaW1wbGVtZW50YXRpb25UeXBlID0gY29uc3RydWN0b3I7XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19pbl93aGVuX29uX3N5bnRheF8xLkJpbmRpbmdJbldoZW5PblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdUb1N5bnRheC5wcm90b3R5cGUudG9TZWxmID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX2JpbmRpbmcuc2VydmljZUlkZW50aWZpZXIgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiXCIgKyBFUlJPUl9NU0dTLklOVkFMSURfVE9fU0VMRl9WQUxVRSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzLl9iaW5kaW5nLnNlcnZpY2VJZGVudGlmaWVyO1xuICAgICAgICByZXR1cm4gdGhpcy50byhzZWxmKTtcbiAgICB9O1xuICAgIEJpbmRpbmdUb1N5bnRheC5wcm90b3R5cGUudG9Db25zdGFudFZhbHVlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcudHlwZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uQ29uc3RhbnRWYWx1ZTtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jYWNoZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmR5bmFtaWNWYWx1ZSA9IG51bGw7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuaW1wbGVtZW50YXRpb25UeXBlID0gbnVsbDtcbiAgICAgICAgdGhpcy5fYmluZGluZy5zY29wZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nU2NvcGVFbnVtLlNpbmdsZXRvbjtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX3doZW5fb25fc3ludGF4XzEuQmluZGluZ1doZW5PblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdUb1N5bnRheC5wcm90b3R5cGUudG9EeW5hbWljVmFsdWUgPSBmdW5jdGlvbiAoZnVuYykge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLnR5cGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1R5cGVFbnVtLkR5bmFtaWNWYWx1ZTtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jYWNoZSA9IG51bGw7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuZHluYW1pY1ZhbHVlID0gZnVuYztcbiAgICAgICAgdGhpcy5fYmluZGluZy5pbXBsZW1lbnRhdGlvblR5cGUgPSBudWxsO1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfaW5fd2hlbl9vbl9zeW50YXhfMS5CaW5kaW5nSW5XaGVuT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nVG9TeW50YXgucHJvdG90eXBlLnRvQ29uc3RydWN0b3IgPSBmdW5jdGlvbiAoY29uc3RydWN0b3IpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy50eXBlID0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5Db25zdHJ1Y3RvcjtcbiAgICAgICAgdGhpcy5fYmluZGluZy5pbXBsZW1lbnRhdGlvblR5cGUgPSBjb25zdHJ1Y3RvcjtcbiAgICAgICAgdGhpcy5fYmluZGluZy5zY29wZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nU2NvcGVFbnVtLlNpbmdsZXRvbjtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX3doZW5fb25fc3ludGF4XzEuQmluZGluZ1doZW5PblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdUb1N5bnRheC5wcm90b3R5cGUudG9GYWN0b3J5ID0gZnVuY3Rpb24gKGZhY3RvcnkpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy50eXBlID0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5GYWN0b3J5O1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmZhY3RvcnkgPSBmYWN0b3J5O1xuICAgICAgICB0aGlzLl9iaW5kaW5nLnNjb3BlID0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdTY29wZUVudW0uU2luZ2xldG9uO1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfd2hlbl9vbl9zeW50YXhfMS5CaW5kaW5nV2hlbk9uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1RvU3ludGF4LnByb3RvdHlwZS50b0Z1bmN0aW9uID0gZnVuY3Rpb24gKGZ1bmMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBmdW5jICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUl9NU0dTLklOVkFMSURfRlVOQ1RJT05fQklORElORyk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGJpbmRpbmdXaGVuT25TeW50YXggPSB0aGlzLnRvQ29uc3RhbnRWYWx1ZShmdW5jKTtcbiAgICAgICAgdGhpcy5fYmluZGluZy50eXBlID0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5GdW5jdGlvbjtcbiAgICAgICAgdGhpcy5fYmluZGluZy5zY29wZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nU2NvcGVFbnVtLlNpbmdsZXRvbjtcbiAgICAgICAgcmV0dXJuIGJpbmRpbmdXaGVuT25TeW50YXg7XG4gICAgfTtcbiAgICBCaW5kaW5nVG9TeW50YXgucHJvdG90eXBlLnRvQXV0b0ZhY3RvcnkgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy50eXBlID0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5GYWN0b3J5O1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmZhY3RvcnkgPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgICAgICAgdmFyIGF1dG9mYWN0b3J5ID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gY29udGV4dC5jb250YWluZXIuZ2V0KHNlcnZpY2VJZGVudGlmaWVyKTsgfTtcbiAgICAgICAgICAgIHJldHVybiBhdXRvZmFjdG9yeTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5fYmluZGluZy5zY29wZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nU2NvcGVFbnVtLlNpbmdsZXRvbjtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX3doZW5fb25fc3ludGF4XzEuQmluZGluZ1doZW5PblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdUb1N5bnRheC5wcm90b3R5cGUudG9Qcm92aWRlciA9IGZ1bmN0aW9uIChwcm92aWRlcikge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLnR5cGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1R5cGVFbnVtLlByb3ZpZGVyO1xuICAgICAgICB0aGlzLl9iaW5kaW5nLnByb3ZpZGVyID0gcHJvdmlkZXI7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuc2NvcGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5TaW5nbGV0b247XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ193aGVuX29uX3N5bnRheF8xLkJpbmRpbmdXaGVuT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nVG9TeW50YXgucHJvdG90eXBlLnRvU2VydmljZSA9IGZ1bmN0aW9uIChzZXJ2aWNlKSB7XG4gICAgICAgIHRoaXMudG9EeW5hbWljVmFsdWUoZnVuY3Rpb24gKGNvbnRleHQpIHsgcmV0dXJuIGNvbnRleHQuY29udGFpbmVyLmdldChzZXJ2aWNlKTsgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gQmluZGluZ1RvU3ludGF4O1xufSgpKTtcbmV4cG9ydHMuQmluZGluZ1RvU3ludGF4ID0gQmluZGluZ1RvU3ludGF4O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmluZGluZ190b19zeW50YXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkJpbmRpbmdXaGVuT25TeW50YXggPSB2b2lkIDA7XG52YXIgYmluZGluZ19vbl9zeW50YXhfMSA9IHJlcXVpcmUoXCIuL2JpbmRpbmdfb25fc3ludGF4XCIpO1xudmFyIGJpbmRpbmdfd2hlbl9zeW50YXhfMSA9IHJlcXVpcmUoXCIuL2JpbmRpbmdfd2hlbl9zeW50YXhcIik7XG52YXIgQmluZGluZ1doZW5PblN5bnRheCA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQmluZGluZ1doZW5PblN5bnRheChiaW5kaW5nKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcgPSBiaW5kaW5nO1xuICAgICAgICB0aGlzLl9iaW5kaW5nV2hlblN5bnRheCA9IG5ldyBiaW5kaW5nX3doZW5fc3ludGF4XzEuQmluZGluZ1doZW5TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgICAgIHRoaXMuX2JpbmRpbmdPblN5bnRheCA9IG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlbiA9IGZ1bmN0aW9uIChjb25zdHJhaW50KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuKGNvbnN0cmFpbnQpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlblRhcmdldE5hbWVkID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5UYXJnZXROYW1lZChuYW1lKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5UYXJnZXRJc0RlZmF1bHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuVGFyZ2V0SXNEZWZhdWx0KCk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuVGFyZ2V0VGFnZ2VkID0gZnVuY3Rpb24gKHRhZywgdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5UYXJnZXRUYWdnZWQodGFnLCB2YWx1ZSk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuSW5qZWN0ZWRJbnRvID0gZnVuY3Rpb24gKHBhcmVudCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbkluamVjdGVkSW50byhwYXJlbnQpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlblBhcmVudE5hbWVkID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5QYXJlbnROYW1lZChuYW1lKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5QYXJlbnRUYWdnZWQgPSBmdW5jdGlvbiAodGFnLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlblBhcmVudFRhZ2dlZCh0YWcsIHZhbHVlKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5BbnlBbmNlc3RvcklzID0gZnVuY3Rpb24gKGFuY2VzdG9yKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuQW55QW5jZXN0b3JJcyhhbmNlc3Rvcik7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuTm9BbmNlc3RvcklzID0gZnVuY3Rpb24gKGFuY2VzdG9yKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuTm9BbmNlc3RvcklzKGFuY2VzdG9yKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5BbnlBbmNlc3Rvck5hbWVkID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5BbnlBbmNlc3Rvck5hbWVkKG5hbWUpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlbkFueUFuY2VzdG9yVGFnZ2VkID0gZnVuY3Rpb24gKHRhZywgdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5BbnlBbmNlc3RvclRhZ2dlZCh0YWcsIHZhbHVlKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5Ob0FuY2VzdG9yTmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbk5vQW5jZXN0b3JOYW1lZChuYW1lKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5Ob0FuY2VzdG9yVGFnZ2VkID0gZnVuY3Rpb24gKHRhZywgdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5Ob0FuY2VzdG9yVGFnZ2VkKHRhZywgdmFsdWUpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlbkFueUFuY2VzdG9yTWF0Y2hlcyA9IGZ1bmN0aW9uIChjb25zdHJhaW50KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuQW55QW5jZXN0b3JNYXRjaGVzKGNvbnN0cmFpbnQpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlbk5vQW5jZXN0b3JNYXRjaGVzID0gZnVuY3Rpb24gKGNvbnN0cmFpbnQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5Ob0FuY2VzdG9yTWF0Y2hlcyhjb25zdHJhaW50KTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuT25TeW50YXgucHJvdG90eXBlLm9uQWN0aXZhdGlvbiA9IGZ1bmN0aW9uIChoYW5kbGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nT25TeW50YXgub25BY3RpdmF0aW9uKGhhbmRsZXIpO1xuICAgIH07XG4gICAgcmV0dXJuIEJpbmRpbmdXaGVuT25TeW50YXg7XG59KCkpO1xuZXhwb3J0cy5CaW5kaW5nV2hlbk9uU3ludGF4ID0gQmluZGluZ1doZW5PblN5bnRheDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJpbmRpbmdfd2hlbl9vbl9zeW50YXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkJpbmRpbmdXaGVuU3ludGF4ID0gdm9pZCAwO1xudmFyIGJpbmRpbmdfb25fc3ludGF4XzEgPSByZXF1aXJlKFwiLi9iaW5kaW5nX29uX3N5bnRheFwiKTtcbnZhciBjb25zdHJhaW50X2hlbHBlcnNfMSA9IHJlcXVpcmUoXCIuL2NvbnN0cmFpbnRfaGVscGVyc1wiKTtcbnZhciBCaW5kaW5nV2hlblN5bnRheCA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQmluZGluZ1doZW5TeW50YXgoYmluZGluZykge1xuICAgICAgICB0aGlzLl9iaW5kaW5nID0gYmluZGluZztcbiAgICB9XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW4gPSBmdW5jdGlvbiAoY29uc3RyYWludCkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBjb25zdHJhaW50O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW5UYXJnZXROYW1lZCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuY29uc3RyYWludCA9IGNvbnN0cmFpbnRfaGVscGVyc18xLm5hbWVkQ29uc3RyYWludChuYW1lKTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuVGFyZ2V0SXNEZWZhdWx0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgdmFyIHRhcmdldElzRGVmYXVsdCA9IChyZXF1ZXN0LnRhcmdldCAhPT0gbnVsbCkgJiZcbiAgICAgICAgICAgICAgICAoIXJlcXVlc3QudGFyZ2V0LmlzTmFtZWQoKSkgJiZcbiAgICAgICAgICAgICAgICAoIXJlcXVlc3QudGFyZ2V0LmlzVGFnZ2VkKCkpO1xuICAgICAgICAgICAgcmV0dXJuIHRhcmdldElzRGVmYXVsdDtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuVGFyZ2V0VGFnZ2VkID0gZnVuY3Rpb24gKHRhZywgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jb25zdHJhaW50ID0gY29uc3RyYWludF9oZWxwZXJzXzEudGFnZ2VkQ29uc3RyYWludCh0YWcpKHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuSW5qZWN0ZWRJbnRvID0gZnVuY3Rpb24gKHBhcmVudCkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnRfaGVscGVyc18xLnR5cGVDb25zdHJhaW50KHBhcmVudCkocmVxdWVzdC5wYXJlbnRSZXF1ZXN0KTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuUGFyZW50TmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnRfaGVscGVyc18xLm5hbWVkQ29uc3RyYWludChuYW1lKShyZXF1ZXN0LnBhcmVudFJlcXVlc3QpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW5QYXJlbnRUYWdnZWQgPSBmdW5jdGlvbiAodGFnLCB2YWx1ZSkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnRfaGVscGVyc18xLnRhZ2dlZENvbnN0cmFpbnQodGFnKSh2YWx1ZSkocmVxdWVzdC5wYXJlbnRSZXF1ZXN0KTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuQW55QW5jZXN0b3JJcyA9IGZ1bmN0aW9uIChhbmNlc3Rvcikge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnRfaGVscGVyc18xLnRyYXZlcnNlQW5jZXJzdG9ycyhyZXF1ZXN0LCBjb25zdHJhaW50X2hlbHBlcnNfMS50eXBlQ29uc3RyYWludChhbmNlc3RvcikpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW5Ob0FuY2VzdG9ySXMgPSBmdW5jdGlvbiAoYW5jZXN0b3IpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jb25zdHJhaW50ID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgICAgIHJldHVybiAhY29uc3RyYWludF9oZWxwZXJzXzEudHJhdmVyc2VBbmNlcnN0b3JzKHJlcXVlc3QsIGNvbnN0cmFpbnRfaGVscGVyc18xLnR5cGVDb25zdHJhaW50KGFuY2VzdG9yKSk7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlblN5bnRheC5wcm90b3R5cGUud2hlbkFueUFuY2VzdG9yTmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnRfaGVscGVyc18xLnRyYXZlcnNlQW5jZXJzdG9ycyhyZXF1ZXN0LCBjb25zdHJhaW50X2hlbHBlcnNfMS5uYW1lZENvbnN0cmFpbnQobmFtZSkpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW5Ob0FuY2VzdG9yTmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuICFjb25zdHJhaW50X2hlbHBlcnNfMS50cmF2ZXJzZUFuY2Vyc3RvcnMocmVxdWVzdCwgY29uc3RyYWludF9oZWxwZXJzXzEubmFtZWRDb25zdHJhaW50KG5hbWUpKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuQW55QW5jZXN0b3JUYWdnZWQgPSBmdW5jdGlvbiAodGFnLCB2YWx1ZSkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnRfaGVscGVyc18xLnRyYXZlcnNlQW5jZXJzdG9ycyhyZXF1ZXN0LCBjb25zdHJhaW50X2hlbHBlcnNfMS50YWdnZWRDb25zdHJhaW50KHRhZykodmFsdWUpKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuTm9BbmNlc3RvclRhZ2dlZCA9IGZ1bmN0aW9uICh0YWcsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuY29uc3RyYWludCA9IGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gIWNvbnN0cmFpbnRfaGVscGVyc18xLnRyYXZlcnNlQW5jZXJzdG9ycyhyZXF1ZXN0LCBjb25zdHJhaW50X2hlbHBlcnNfMS50YWdnZWRDb25zdHJhaW50KHRhZykodmFsdWUpKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuQW55QW5jZXN0b3JNYXRjaGVzID0gZnVuY3Rpb24gKGNvbnN0cmFpbnQpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jb25zdHJhaW50ID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgICAgIHJldHVybiBjb25zdHJhaW50X2hlbHBlcnNfMS50cmF2ZXJzZUFuY2Vyc3RvcnMocmVxdWVzdCwgY29uc3RyYWludCk7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlblN5bnRheC5wcm90b3R5cGUud2hlbk5vQW5jZXN0b3JNYXRjaGVzID0gZnVuY3Rpb24gKGNvbnN0cmFpbnQpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jb25zdHJhaW50ID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgICAgIHJldHVybiAhY29uc3RyYWludF9oZWxwZXJzXzEudHJhdmVyc2VBbmNlcnN0b3JzKHJlcXVlc3QsIGNvbnN0cmFpbnQpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgcmV0dXJuIEJpbmRpbmdXaGVuU3ludGF4O1xufSgpKTtcbmV4cG9ydHMuQmluZGluZ1doZW5TeW50YXggPSBCaW5kaW5nV2hlblN5bnRheDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJpbmRpbmdfd2hlbl9zeW50YXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnR5cGVDb25zdHJhaW50ID0gZXhwb3J0cy5uYW1lZENvbnN0cmFpbnQgPSBleHBvcnRzLnRhZ2dlZENvbnN0cmFpbnQgPSBleHBvcnRzLnRyYXZlcnNlQW5jZXJzdG9ycyA9IHZvaWQgMDtcbnZhciBNRVRBREFUQV9LRVkgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG52YXIgbWV0YWRhdGFfMSA9IHJlcXVpcmUoXCIuLi9wbGFubmluZy9tZXRhZGF0YVwiKTtcbnZhciB0cmF2ZXJzZUFuY2Vyc3RvcnMgPSBmdW5jdGlvbiAocmVxdWVzdCwgY29uc3RyYWludCkge1xuICAgIHZhciBwYXJlbnQgPSByZXF1ZXN0LnBhcmVudFJlcXVlc3Q7XG4gICAgaWYgKHBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gY29uc3RyYWludChwYXJlbnQpID8gdHJ1ZSA6IHRyYXZlcnNlQW5jZXJzdG9ycyhwYXJlbnQsIGNvbnN0cmFpbnQpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn07XG5leHBvcnRzLnRyYXZlcnNlQW5jZXJzdG9ycyA9IHRyYXZlcnNlQW5jZXJzdG9ycztcbnZhciB0YWdnZWRDb25zdHJhaW50ID0gZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgdmFyIGNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICByZXR1cm4gcmVxdWVzdCAhPT0gbnVsbCAmJiByZXF1ZXN0LnRhcmdldCAhPT0gbnVsbCAmJiByZXF1ZXN0LnRhcmdldC5tYXRjaGVzVGFnKGtleSkodmFsdWUpO1xuICAgIH07XG4gICAgY29uc3RyYWludC5tZXRhRGF0YSA9IG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKGtleSwgdmFsdWUpO1xuICAgIHJldHVybiBjb25zdHJhaW50O1xufTsgfTtcbmV4cG9ydHMudGFnZ2VkQ29uc3RyYWludCA9IHRhZ2dlZENvbnN0cmFpbnQ7XG52YXIgbmFtZWRDb25zdHJhaW50ID0gdGFnZ2VkQ29uc3RyYWludChNRVRBREFUQV9LRVkuTkFNRURfVEFHKTtcbmV4cG9ydHMubmFtZWRDb25zdHJhaW50ID0gbmFtZWRDb25zdHJhaW50O1xudmFyIHR5cGVDb25zdHJhaW50ID0gZnVuY3Rpb24gKHR5cGUpIHsgcmV0dXJuIGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG4gICAgdmFyIGJpbmRpbmcgPSBudWxsO1xuICAgIGlmIChyZXF1ZXN0ICE9PSBudWxsKSB7XG4gICAgICAgIGJpbmRpbmcgPSByZXF1ZXN0LmJpbmRpbmdzWzBdO1xuICAgICAgICBpZiAodHlwZW9mIHR5cGUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIHZhciBzZXJ2aWNlSWRlbnRpZmllciA9IGJpbmRpbmcuc2VydmljZUlkZW50aWZpZXI7XG4gICAgICAgICAgICByZXR1cm4gc2VydmljZUlkZW50aWZpZXIgPT09IHR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgY29uc3RydWN0b3IgPSByZXF1ZXN0LmJpbmRpbmdzWzBdLmltcGxlbWVudGF0aW9uVHlwZTtcbiAgICAgICAgICAgIHJldHVybiB0eXBlID09PSBjb25zdHJ1Y3RvcjtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59OyB9O1xuZXhwb3J0cy50eXBlQ29uc3RyYWludCA9IHR5cGVDb25zdHJhaW50O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29uc3RyYWludF9oZWxwZXJzLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5tdWx0aUJpbmRUb1NlcnZpY2UgPSB2b2lkIDA7XG52YXIgbXVsdGlCaW5kVG9TZXJ2aWNlID0gZnVuY3Rpb24gKGNvbnRhaW5lcikge1xuICAgIHJldHVybiBmdW5jdGlvbiAoc2VydmljZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHR5cGVzID0gW107XG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgICAgIHR5cGVzW19pXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHlwZXMuZm9yRWFjaChmdW5jdGlvbiAodCkgeyByZXR1cm4gY29udGFpbmVyLmJpbmQodCkudG9TZXJ2aWNlKHNlcnZpY2UpOyB9KTtcbiAgICAgICAgfTtcbiAgICB9O1xufTtcbmV4cG9ydHMubXVsdGlCaW5kVG9TZXJ2aWNlID0gbXVsdGlCaW5kVG9TZXJ2aWNlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmluZGluZ191dGlscy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuaXNTdGFja092ZXJmbG93RXhlcHRpb24gPSB2b2lkIDA7XG52YXIgRVJST1JfTVNHUyA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbmZ1bmN0aW9uIGlzU3RhY2tPdmVyZmxvd0V4ZXB0aW9uKGVycm9yKSB7XG4gICAgcmV0dXJuIChlcnJvciBpbnN0YW5jZW9mIFJhbmdlRXJyb3IgfHxcbiAgICAgICAgZXJyb3IubWVzc2FnZSA9PT0gRVJST1JfTVNHUy5TVEFDS19PVkVSRkxPVyk7XG59XG5leHBvcnRzLmlzU3RhY2tPdmVyZmxvd0V4ZXB0aW9uID0gaXNTdGFja092ZXJmbG93RXhlcHRpb247XG4vLyMgc291cmNlTWFwcGluZ1VSTD1leGNlcHRpb25zLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5pZCA9IHZvaWQgMDtcbnZhciBpZENvdW50ZXIgPSAwO1xuZnVuY3Rpb24gaWQoKSB7XG4gICAgcmV0dXJuIGlkQ291bnRlcisrO1xufVxuZXhwb3J0cy5pZCA9IGlkO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aWQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmNpcmN1bGFyRGVwZW5kZW5jeVRvRXhjZXB0aW9uID0gZXhwb3J0cy5saXN0TWV0YWRhdGFGb3JUYXJnZXQgPSBleHBvcnRzLmxpc3RSZWdpc3RlcmVkQmluZGluZ3NGb3JTZXJ2aWNlSWRlbnRpZmllciA9IGV4cG9ydHMuZ2V0U2VydmljZUlkZW50aWZpZXJBc1N0cmluZyA9IGV4cG9ydHMuZ2V0RnVuY3Rpb25OYW1lID0gdm9pZCAwO1xudmFyIEVSUk9SX01TR1MgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2Vycm9yX21zZ3NcIik7XG5mdW5jdGlvbiBnZXRTZXJ2aWNlSWRlbnRpZmllckFzU3RyaW5nKHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgaWYgKHR5cGVvZiBzZXJ2aWNlSWRlbnRpZmllciA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHZhciBfc2VydmljZUlkZW50aWZpZXIgPSBzZXJ2aWNlSWRlbnRpZmllcjtcbiAgICAgICAgcmV0dXJuIF9zZXJ2aWNlSWRlbnRpZmllci5uYW1lO1xuICAgIH1cbiAgICBlbHNlIGlmICh0eXBlb2Ygc2VydmljZUlkZW50aWZpZXIgPT09IFwic3ltYm9sXCIpIHtcbiAgICAgICAgcmV0dXJuIHNlcnZpY2VJZGVudGlmaWVyLnRvU3RyaW5nKCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB2YXIgX3NlcnZpY2VJZGVudGlmaWVyID0gc2VydmljZUlkZW50aWZpZXI7XG4gICAgICAgIHJldHVybiBfc2VydmljZUlkZW50aWZpZXI7XG4gICAgfVxufVxuZXhwb3J0cy5nZXRTZXJ2aWNlSWRlbnRpZmllckFzU3RyaW5nID0gZ2V0U2VydmljZUlkZW50aWZpZXJBc1N0cmluZztcbmZ1bmN0aW9uIGxpc3RSZWdpc3RlcmVkQmluZGluZ3NGb3JTZXJ2aWNlSWRlbnRpZmllcihjb250YWluZXIsIHNlcnZpY2VJZGVudGlmaWVyLCBnZXRCaW5kaW5ncykge1xuICAgIHZhciByZWdpc3RlcmVkQmluZGluZ3NMaXN0ID0gXCJcIjtcbiAgICB2YXIgcmVnaXN0ZXJlZEJpbmRpbmdzID0gZ2V0QmluZGluZ3MoY29udGFpbmVyLCBzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgaWYgKHJlZ2lzdGVyZWRCaW5kaW5ncy5sZW5ndGggIT09IDApIHtcbiAgICAgICAgcmVnaXN0ZXJlZEJpbmRpbmdzTGlzdCA9IFwiXFxuUmVnaXN0ZXJlZCBiaW5kaW5nczpcIjtcbiAgICAgICAgcmVnaXN0ZXJlZEJpbmRpbmdzLmZvckVhY2goZnVuY3Rpb24gKGJpbmRpbmcpIHtcbiAgICAgICAgICAgIHZhciBuYW1lID0gXCJPYmplY3RcIjtcbiAgICAgICAgICAgIGlmIChiaW5kaW5nLmltcGxlbWVudGF0aW9uVHlwZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIG5hbWUgPSBnZXRGdW5jdGlvbk5hbWUoYmluZGluZy5pbXBsZW1lbnRhdGlvblR5cGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVnaXN0ZXJlZEJpbmRpbmdzTGlzdCA9IHJlZ2lzdGVyZWRCaW5kaW5nc0xpc3QgKyBcIlxcbiBcIiArIG5hbWU7XG4gICAgICAgICAgICBpZiAoYmluZGluZy5jb25zdHJhaW50Lm1ldGFEYXRhKSB7XG4gICAgICAgICAgICAgICAgcmVnaXN0ZXJlZEJpbmRpbmdzTGlzdCA9IHJlZ2lzdGVyZWRCaW5kaW5nc0xpc3QgKyBcIiAtIFwiICsgYmluZGluZy5jb25zdHJhaW50Lm1ldGFEYXRhO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlZ2lzdGVyZWRCaW5kaW5nc0xpc3Q7XG59XG5leHBvcnRzLmxpc3RSZWdpc3RlcmVkQmluZGluZ3NGb3JTZXJ2aWNlSWRlbnRpZmllciA9IGxpc3RSZWdpc3RlcmVkQmluZGluZ3NGb3JTZXJ2aWNlSWRlbnRpZmllcjtcbmZ1bmN0aW9uIGFscmVhZHlEZXBlbmRlbmN5Q2hhaW4ocmVxdWVzdCwgc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICBpZiAocmVxdWVzdC5wYXJlbnRSZXF1ZXN0ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZWxzZSBpZiAocmVxdWVzdC5wYXJlbnRSZXF1ZXN0LnNlcnZpY2VJZGVudGlmaWVyID09PSBzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiBhbHJlYWR5RGVwZW5kZW5jeUNoYWluKHJlcXVlc3QucGFyZW50UmVxdWVzdCwgc2VydmljZUlkZW50aWZpZXIpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGRlcGVuZGVuY3lDaGFpblRvU3RyaW5nKHJlcXVlc3QpIHtcbiAgICBmdW5jdGlvbiBfY3JlYXRlU3RyaW5nQXJyKHJlcSwgcmVzdWx0KSB7XG4gICAgICAgIGlmIChyZXN1bHQgPT09IHZvaWQgMCkgeyByZXN1bHQgPSBbXTsgfVxuICAgICAgICB2YXIgc2VydmljZUlkZW50aWZpZXIgPSBnZXRTZXJ2aWNlSWRlbnRpZmllckFzU3RyaW5nKHJlcS5zZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIHJlc3VsdC5wdXNoKHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgaWYgKHJlcS5wYXJlbnRSZXF1ZXN0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gX2NyZWF0ZVN0cmluZ0FycihyZXEucGFyZW50UmVxdWVzdCwgcmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICB2YXIgc3RyaW5nQXJyID0gX2NyZWF0ZVN0cmluZ0FycihyZXF1ZXN0KTtcbiAgICByZXR1cm4gc3RyaW5nQXJyLnJldmVyc2UoKS5qb2luKFwiIC0tPiBcIik7XG59XG5mdW5jdGlvbiBjaXJjdWxhckRlcGVuZGVuY3lUb0V4Y2VwdGlvbihyZXF1ZXN0KSB7XG4gICAgcmVxdWVzdC5jaGlsZFJlcXVlc3RzLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkUmVxdWVzdCkge1xuICAgICAgICBpZiAoYWxyZWFkeURlcGVuZGVuY3lDaGFpbihjaGlsZFJlcXVlc3QsIGNoaWxkUmVxdWVzdC5zZXJ2aWNlSWRlbnRpZmllcikpIHtcbiAgICAgICAgICAgIHZhciBzZXJ2aWNlcyA9IGRlcGVuZGVuY3lDaGFpblRvU3RyaW5nKGNoaWxkUmVxdWVzdCk7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTVNHUy5DSVJDVUxBUl9ERVBFTkRFTkNZICsgXCIgXCIgKyBzZXJ2aWNlcyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjaXJjdWxhckRlcGVuZGVuY3lUb0V4Y2VwdGlvbihjaGlsZFJlcXVlc3QpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5leHBvcnRzLmNpcmN1bGFyRGVwZW5kZW5jeVRvRXhjZXB0aW9uID0gY2lyY3VsYXJEZXBlbmRlbmN5VG9FeGNlcHRpb247XG5mdW5jdGlvbiBsaXN0TWV0YWRhdGFGb3JUYXJnZXQoc2VydmljZUlkZW50aWZpZXJTdHJpbmcsIHRhcmdldCkge1xuICAgIGlmICh0YXJnZXQuaXNUYWdnZWQoKSB8fCB0YXJnZXQuaXNOYW1lZCgpKSB7XG4gICAgICAgIHZhciBtXzEgPSBcIlwiO1xuICAgICAgICB2YXIgbmFtZWRUYWcgPSB0YXJnZXQuZ2V0TmFtZWRUYWcoKTtcbiAgICAgICAgdmFyIG90aGVyVGFncyA9IHRhcmdldC5nZXRDdXN0b21UYWdzKCk7XG4gICAgICAgIGlmIChuYW1lZFRhZyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgbV8xICs9IG5hbWVkVGFnLnRvU3RyaW5nKCkgKyBcIlxcblwiO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvdGhlclRhZ3MgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG90aGVyVGFncy5mb3JFYWNoKGZ1bmN0aW9uICh0YWcpIHtcbiAgICAgICAgICAgICAgICBtXzEgKz0gdGFnLnRvU3RyaW5nKCkgKyBcIlxcblwiO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFwiIFwiICsgc2VydmljZUlkZW50aWZpZXJTdHJpbmcgKyBcIlxcbiBcIiArIHNlcnZpY2VJZGVudGlmaWVyU3RyaW5nICsgXCIgLSBcIiArIG1fMTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiBcIiBcIiArIHNlcnZpY2VJZGVudGlmaWVyU3RyaW5nO1xuICAgIH1cbn1cbmV4cG9ydHMubGlzdE1ldGFkYXRhRm9yVGFyZ2V0ID0gbGlzdE1ldGFkYXRhRm9yVGFyZ2V0O1xuZnVuY3Rpb24gZ2V0RnVuY3Rpb25OYW1lKHYpIHtcbiAgICBpZiAodi5uYW1lKSB7XG4gICAgICAgIHJldHVybiB2Lm5hbWU7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB2YXIgbmFtZV8xID0gdi50b1N0cmluZygpO1xuICAgICAgICB2YXIgbWF0Y2ggPSBuYW1lXzEubWF0Y2goL15mdW5jdGlvblxccyooW15cXHMoXSspLyk7XG4gICAgICAgIHJldHVybiBtYXRjaCA/IG1hdGNoWzFdIDogXCJBbm9ueW1vdXMgZnVuY3Rpb246IFwiICsgbmFtZV8xO1xuICAgIH1cbn1cbmV4cG9ydHMuZ2V0RnVuY3Rpb25OYW1lID0gZ2V0RnVuY3Rpb25OYW1lO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2VyaWFsaXphdGlvbi5qcy5tYXAiLCJtb2R1bGUuZXhwb3J0cyA9IG1pbmltYXRjaFxubWluaW1hdGNoLk1pbmltYXRjaCA9IE1pbmltYXRjaFxuXG52YXIgcGF0aCA9IHsgc2VwOiAnLycgfVxudHJ5IHtcbiAgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKVxufSBjYXRjaCAoZXIpIHt9XG5cbnZhciBHTE9CU1RBUiA9IG1pbmltYXRjaC5HTE9CU1RBUiA9IE1pbmltYXRjaC5HTE9CU1RBUiA9IHt9XG52YXIgZXhwYW5kID0gcmVxdWlyZSgnYnJhY2UtZXhwYW5zaW9uJylcblxudmFyIHBsVHlwZXMgPSB7XG4gICchJzogeyBvcGVuOiAnKD86KD8hKD86JywgY2xvc2U6ICcpKVteL10qPyknfSxcbiAgJz8nOiB7IG9wZW46ICcoPzonLCBjbG9zZTogJyk/JyB9LFxuICAnKyc6IHsgb3BlbjogJyg/OicsIGNsb3NlOiAnKSsnIH0sXG4gICcqJzogeyBvcGVuOiAnKD86JywgY2xvc2U6ICcpKicgfSxcbiAgJ0AnOiB7IG9wZW46ICcoPzonLCBjbG9zZTogJyknIH1cbn1cblxuLy8gYW55IHNpbmdsZSB0aGluZyBvdGhlciB0aGFuIC9cbi8vIGRvbid0IG5lZWQgdG8gZXNjYXBlIC8gd2hlbiB1c2luZyBuZXcgUmVnRXhwKClcbnZhciBxbWFyayA9ICdbXi9dJ1xuXG4vLyAqID0+IGFueSBudW1iZXIgb2YgY2hhcmFjdGVyc1xudmFyIHN0YXIgPSBxbWFyayArICcqPydcblxuLy8gKiogd2hlbiBkb3RzIGFyZSBhbGxvd2VkLiAgQW55dGhpbmcgZ29lcywgZXhjZXB0IC4uIGFuZCAuXG4vLyBub3QgKF4gb3IgLyBmb2xsb3dlZCBieSBvbmUgb3IgdHdvIGRvdHMgZm9sbG93ZWQgYnkgJCBvciAvKSxcbi8vIGZvbGxvd2VkIGJ5IGFueXRoaW5nLCBhbnkgbnVtYmVyIG9mIHRpbWVzLlxudmFyIHR3b1N0YXJEb3QgPSAnKD86KD8hKD86XFxcXFxcL3xeKSg/OlxcXFwuezEsMn0pKCR8XFxcXFxcLykpLikqPydcblxuLy8gbm90IGEgXiBvciAvIGZvbGxvd2VkIGJ5IGEgZG90LFxuLy8gZm9sbG93ZWQgYnkgYW55dGhpbmcsIGFueSBudW1iZXIgb2YgdGltZXMuXG52YXIgdHdvU3Rhck5vRG90ID0gJyg/Oig/ISg/OlxcXFxcXC98XilcXFxcLikuKSo/J1xuXG4vLyBjaGFyYWN0ZXJzIHRoYXQgbmVlZCB0byBiZSBlc2NhcGVkIGluIFJlZ0V4cC5cbnZhciByZVNwZWNpYWxzID0gY2hhclNldCgnKCkuKnt9Kz9bXV4kXFxcXCEnKVxuXG4vLyBcImFiY1wiIC0+IHsgYTp0cnVlLCBiOnRydWUsIGM6dHJ1ZSB9XG5mdW5jdGlvbiBjaGFyU2V0IChzKSB7XG4gIHJldHVybiBzLnNwbGl0KCcnKS5yZWR1Y2UoZnVuY3Rpb24gKHNldCwgYykge1xuICAgIHNldFtjXSA9IHRydWVcbiAgICByZXR1cm4gc2V0XG4gIH0sIHt9KVxufVxuXG4vLyBub3JtYWxpemVzIHNsYXNoZXMuXG52YXIgc2xhc2hTcGxpdCA9IC9cXC8rL1xuXG5taW5pbWF0Y2guZmlsdGVyID0gZmlsdGVyXG5mdW5jdGlvbiBmaWx0ZXIgKHBhdHRlcm4sIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge31cbiAgcmV0dXJuIGZ1bmN0aW9uIChwLCBpLCBsaXN0KSB7XG4gICAgcmV0dXJuIG1pbmltYXRjaChwLCBwYXR0ZXJuLCBvcHRpb25zKVxuICB9XG59XG5cbmZ1bmN0aW9uIGV4dCAoYSwgYikge1xuICBhID0gYSB8fCB7fVxuICBiID0gYiB8fCB7fVxuICB2YXIgdCA9IHt9XG4gIE9iamVjdC5rZXlzKGIpLmZvckVhY2goZnVuY3Rpb24gKGspIHtcbiAgICB0W2tdID0gYltrXVxuICB9KVxuICBPYmplY3Qua2V5cyhhKS5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG4gICAgdFtrXSA9IGFba11cbiAgfSlcbiAgcmV0dXJuIHRcbn1cblxubWluaW1hdGNoLmRlZmF1bHRzID0gZnVuY3Rpb24gKGRlZikge1xuICBpZiAoIWRlZiB8fCAhT2JqZWN0LmtleXMoZGVmKS5sZW5ndGgpIHJldHVybiBtaW5pbWF0Y2hcblxuICB2YXIgb3JpZyA9IG1pbmltYXRjaFxuXG4gIHZhciBtID0gZnVuY3Rpb24gbWluaW1hdGNoIChwLCBwYXR0ZXJuLCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIG9yaWcubWluaW1hdGNoKHAsIHBhdHRlcm4sIGV4dChkZWYsIG9wdGlvbnMpKVxuICB9XG5cbiAgbS5NaW5pbWF0Y2ggPSBmdW5jdGlvbiBNaW5pbWF0Y2ggKHBhdHRlcm4sIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gbmV3IG9yaWcuTWluaW1hdGNoKHBhdHRlcm4sIGV4dChkZWYsIG9wdGlvbnMpKVxuICB9XG5cbiAgcmV0dXJuIG1cbn1cblxuTWluaW1hdGNoLmRlZmF1bHRzID0gZnVuY3Rpb24gKGRlZikge1xuICBpZiAoIWRlZiB8fCAhT2JqZWN0LmtleXMoZGVmKS5sZW5ndGgpIHJldHVybiBNaW5pbWF0Y2hcbiAgcmV0dXJuIG1pbmltYXRjaC5kZWZhdWx0cyhkZWYpLk1pbmltYXRjaFxufVxuXG5mdW5jdGlvbiBtaW5pbWF0Y2ggKHAsIHBhdHRlcm4sIG9wdGlvbnMpIHtcbiAgaWYgKHR5cGVvZiBwYXR0ZXJuICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2dsb2IgcGF0dGVybiBzdHJpbmcgcmVxdWlyZWQnKVxuICB9XG5cbiAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge31cblxuICAvLyBzaG9ydGN1dDogY29tbWVudHMgbWF0Y2ggbm90aGluZy5cbiAgaWYgKCFvcHRpb25zLm5vY29tbWVudCAmJiBwYXR0ZXJuLmNoYXJBdCgwKSA9PT0gJyMnKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvLyBcIlwiIG9ubHkgbWF0Y2hlcyBcIlwiXG4gIGlmIChwYXR0ZXJuLnRyaW0oKSA9PT0gJycpIHJldHVybiBwID09PSAnJ1xuXG4gIHJldHVybiBuZXcgTWluaW1hdGNoKHBhdHRlcm4sIG9wdGlvbnMpLm1hdGNoKHApXG59XG5cbmZ1bmN0aW9uIE1pbmltYXRjaCAocGF0dGVybiwgb3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgTWluaW1hdGNoKSkge1xuICAgIHJldHVybiBuZXcgTWluaW1hdGNoKHBhdHRlcm4sIG9wdGlvbnMpXG4gIH1cblxuICBpZiAodHlwZW9mIHBhdHRlcm4gIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZ2xvYiBwYXR0ZXJuIHN0cmluZyByZXF1aXJlZCcpXG4gIH1cblxuICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fVxuICBwYXR0ZXJuID0gcGF0dGVybi50cmltKClcblxuICAvLyB3aW5kb3dzIHN1cHBvcnQ6IG5lZWQgdG8gdXNlIC8sIG5vdCBcXFxuICBpZiAocGF0aC5zZXAgIT09ICcvJykge1xuICAgIHBhdHRlcm4gPSBwYXR0ZXJuLnNwbGl0KHBhdGguc2VwKS5qb2luKCcvJylcbiAgfVxuXG4gIHRoaXMub3B0aW9ucyA9IG9wdGlvbnNcbiAgdGhpcy5zZXQgPSBbXVxuICB0aGlzLnBhdHRlcm4gPSBwYXR0ZXJuXG4gIHRoaXMucmVnZXhwID0gbnVsbFxuICB0aGlzLm5lZ2F0ZSA9IGZhbHNlXG4gIHRoaXMuY29tbWVudCA9IGZhbHNlXG4gIHRoaXMuZW1wdHkgPSBmYWxzZVxuXG4gIC8vIG1ha2UgdGhlIHNldCBvZiByZWdleHBzIGV0Yy5cbiAgdGhpcy5tYWtlKClcbn1cblxuTWluaW1hdGNoLnByb3RvdHlwZS5kZWJ1ZyA9IGZ1bmN0aW9uICgpIHt9XG5cbk1pbmltYXRjaC5wcm90b3R5cGUubWFrZSA9IG1ha2VcbmZ1bmN0aW9uIG1ha2UgKCkge1xuICAvLyBkb24ndCBkbyBpdCBtb3JlIHRoYW4gb25jZS5cbiAgaWYgKHRoaXMuX21hZGUpIHJldHVyblxuXG4gIHZhciBwYXR0ZXJuID0gdGhpcy5wYXR0ZXJuXG4gIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zXG5cbiAgLy8gZW1wdHkgcGF0dGVybnMgYW5kIGNvbW1lbnRzIG1hdGNoIG5vdGhpbmcuXG4gIGlmICghb3B0aW9ucy5ub2NvbW1lbnQgJiYgcGF0dGVybi5jaGFyQXQoMCkgPT09ICcjJykge1xuICAgIHRoaXMuY29tbWVudCA9IHRydWVcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoIXBhdHRlcm4pIHtcbiAgICB0aGlzLmVtcHR5ID0gdHJ1ZVxuICAgIHJldHVyblxuICB9XG5cbiAgLy8gc3RlcCAxOiBmaWd1cmUgb3V0IG5lZ2F0aW9uLCBldGMuXG4gIHRoaXMucGFyc2VOZWdhdGUoKVxuXG4gIC8vIHN0ZXAgMjogZXhwYW5kIGJyYWNlc1xuICB2YXIgc2V0ID0gdGhpcy5nbG9iU2V0ID0gdGhpcy5icmFjZUV4cGFuZCgpXG5cbiAgaWYgKG9wdGlvbnMuZGVidWcpIHRoaXMuZGVidWcgPSBjb25zb2xlLmVycm9yXG5cbiAgdGhpcy5kZWJ1Zyh0aGlzLnBhdHRlcm4sIHNldClcblxuICAvLyBzdGVwIDM6IG5vdyB3ZSBoYXZlIGEgc2V0LCBzbyB0dXJuIGVhY2ggb25lIGludG8gYSBzZXJpZXMgb2YgcGF0aC1wb3J0aW9uXG4gIC8vIG1hdGNoaW5nIHBhdHRlcm5zLlxuICAvLyBUaGVzZSB3aWxsIGJlIHJlZ2V4cHMsIGV4Y2VwdCBpbiB0aGUgY2FzZSBvZiBcIioqXCIsIHdoaWNoIGlzXG4gIC8vIHNldCB0byB0aGUgR0xPQlNUQVIgb2JqZWN0IGZvciBnbG9ic3RhciBiZWhhdmlvcixcbiAgLy8gYW5kIHdpbGwgbm90IGNvbnRhaW4gYW55IC8gY2hhcmFjdGVyc1xuICBzZXQgPSB0aGlzLmdsb2JQYXJ0cyA9IHNldC5tYXAoZnVuY3Rpb24gKHMpIHtcbiAgICByZXR1cm4gcy5zcGxpdChzbGFzaFNwbGl0KVxuICB9KVxuXG4gIHRoaXMuZGVidWcodGhpcy5wYXR0ZXJuLCBzZXQpXG5cbiAgLy8gZ2xvYiAtLT4gcmVnZXhwc1xuICBzZXQgPSBzZXQubWFwKGZ1bmN0aW9uIChzLCBzaSwgc2V0KSB7XG4gICAgcmV0dXJuIHMubWFwKHRoaXMucGFyc2UsIHRoaXMpXG4gIH0sIHRoaXMpXG5cbiAgdGhpcy5kZWJ1Zyh0aGlzLnBhdHRlcm4sIHNldClcblxuICAvLyBmaWx0ZXIgb3V0IGV2ZXJ5dGhpbmcgdGhhdCBkaWRuJ3QgY29tcGlsZSBwcm9wZXJseS5cbiAgc2V0ID0gc2V0LmZpbHRlcihmdW5jdGlvbiAocykge1xuICAgIHJldHVybiBzLmluZGV4T2YoZmFsc2UpID09PSAtMVxuICB9KVxuXG4gIHRoaXMuZGVidWcodGhpcy5wYXR0ZXJuLCBzZXQpXG5cbiAgdGhpcy5zZXQgPSBzZXRcbn1cblxuTWluaW1hdGNoLnByb3RvdHlwZS5wYXJzZU5lZ2F0ZSA9IHBhcnNlTmVnYXRlXG5mdW5jdGlvbiBwYXJzZU5lZ2F0ZSAoKSB7XG4gIHZhciBwYXR0ZXJuID0gdGhpcy5wYXR0ZXJuXG4gIHZhciBuZWdhdGUgPSBmYWxzZVxuICB2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9uc1xuICB2YXIgbmVnYXRlT2Zmc2V0ID0gMFxuXG4gIGlmIChvcHRpb25zLm5vbmVnYXRlKSByZXR1cm5cblxuICBmb3IgKHZhciBpID0gMCwgbCA9IHBhdHRlcm4ubGVuZ3RoXG4gICAgOyBpIDwgbCAmJiBwYXR0ZXJuLmNoYXJBdChpKSA9PT0gJyEnXG4gICAgOyBpKyspIHtcbiAgICBuZWdhdGUgPSAhbmVnYXRlXG4gICAgbmVnYXRlT2Zmc2V0KytcbiAgfVxuXG4gIGlmIChuZWdhdGVPZmZzZXQpIHRoaXMucGF0dGVybiA9IHBhdHRlcm4uc3Vic3RyKG5lZ2F0ZU9mZnNldClcbiAgdGhpcy5uZWdhdGUgPSBuZWdhdGVcbn1cblxuLy8gQnJhY2UgZXhwYW5zaW9uOlxuLy8gYXtiLGN9ZCAtPiBhYmQgYWNkXG4vLyBhe2IsfWMgLT4gYWJjIGFjXG4vLyBhezAuLjN9ZCAtPiBhMGQgYTFkIGEyZCBhM2Rcbi8vIGF7Yixje2QsZX1mfWcgLT4gYWJnIGFjZGZnIGFjZWZnXG4vLyBhe2IsY31ke2UsZn1nIC0+IGFiZGVnIGFjZGVnIGFiZGVnIGFiZGZnXG4vL1xuLy8gSW52YWxpZCBzZXRzIGFyZSBub3QgZXhwYW5kZWQuXG4vLyBhezIuLn1iIC0+IGF7Mi4ufWJcbi8vIGF7Yn1jIC0+IGF7Yn1jXG5taW5pbWF0Y2guYnJhY2VFeHBhbmQgPSBmdW5jdGlvbiAocGF0dGVybiwgb3B0aW9ucykge1xuICByZXR1cm4gYnJhY2VFeHBhbmQocGF0dGVybiwgb3B0aW9ucylcbn1cblxuTWluaW1hdGNoLnByb3RvdHlwZS5icmFjZUV4cGFuZCA9IGJyYWNlRXhwYW5kXG5cbmZ1bmN0aW9uIGJyYWNlRXhwYW5kIChwYXR0ZXJuLCBvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucykge1xuICAgIGlmICh0aGlzIGluc3RhbmNlb2YgTWluaW1hdGNoKSB7XG4gICAgICBvcHRpb25zID0gdGhpcy5vcHRpb25zXG4gICAgfSBlbHNlIHtcbiAgICAgIG9wdGlvbnMgPSB7fVxuICAgIH1cbiAgfVxuXG4gIHBhdHRlcm4gPSB0eXBlb2YgcGF0dGVybiA9PT0gJ3VuZGVmaW5lZCdcbiAgICA/IHRoaXMucGF0dGVybiA6IHBhdHRlcm5cblxuICBpZiAodHlwZW9mIHBhdHRlcm4gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndW5kZWZpbmVkIHBhdHRlcm4nKVxuICB9XG5cbiAgaWYgKG9wdGlvbnMubm9icmFjZSB8fFxuICAgICFwYXR0ZXJuLm1hdGNoKC9cXHsuKlxcfS8pKSB7XG4gICAgLy8gc2hvcnRjdXQuIG5vIG5lZWQgdG8gZXhwYW5kLlxuICAgIHJldHVybiBbcGF0dGVybl1cbiAgfVxuXG4gIHJldHVybiBleHBhbmQocGF0dGVybilcbn1cblxuLy8gcGFyc2UgYSBjb21wb25lbnQgb2YgdGhlIGV4cGFuZGVkIHNldC5cbi8vIEF0IHRoaXMgcG9pbnQsIG5vIHBhdHRlcm4gbWF5IGNvbnRhaW4gXCIvXCIgaW4gaXRcbi8vIHNvIHdlJ3JlIGdvaW5nIHRvIHJldHVybiBhIDJkIGFycmF5LCB3aGVyZSBlYWNoIGVudHJ5IGlzIHRoZSBmdWxsXG4vLyBwYXR0ZXJuLCBzcGxpdCBvbiAnLycsIGFuZCB0aGVuIHR1cm5lZCBpbnRvIGEgcmVndWxhciBleHByZXNzaW9uLlxuLy8gQSByZWdleHAgaXMgbWFkZSBhdCB0aGUgZW5kIHdoaWNoIGpvaW5zIGVhY2ggYXJyYXkgd2l0aCBhblxuLy8gZXNjYXBlZCAvLCBhbmQgYW5vdGhlciBmdWxsIG9uZSB3aGljaCBqb2lucyBlYWNoIHJlZ2V4cCB3aXRoIHwuXG4vL1xuLy8gRm9sbG93aW5nIHRoZSBsZWFkIG9mIEJhc2ggNC4xLCBub3RlIHRoYXQgXCIqKlwiIG9ubHkgaGFzIHNwZWNpYWwgbWVhbmluZ1xuLy8gd2hlbiBpdCBpcyB0aGUgKm9ubHkqIHRoaW5nIGluIGEgcGF0aCBwb3J0aW9uLiAgT3RoZXJ3aXNlLCBhbnkgc2VyaWVzXG4vLyBvZiAqIGlzIGVxdWl2YWxlbnQgdG8gYSBzaW5nbGUgKi4gIEdsb2JzdGFyIGJlaGF2aW9yIGlzIGVuYWJsZWQgYnlcbi8vIGRlZmF1bHQsIGFuZCBjYW4gYmUgZGlzYWJsZWQgYnkgc2V0dGluZyBvcHRpb25zLm5vZ2xvYnN0YXIuXG5NaW5pbWF0Y2gucHJvdG90eXBlLnBhcnNlID0gcGFyc2VcbnZhciBTVUJQQVJTRSA9IHt9XG5mdW5jdGlvbiBwYXJzZSAocGF0dGVybiwgaXNTdWIpIHtcbiAgaWYgKHBhdHRlcm4ubGVuZ3RoID4gMTAyNCAqIDY0KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcigncGF0dGVybiBpcyB0b28gbG9uZycpXG4gIH1cblxuICB2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9uc1xuXG4gIC8vIHNob3J0Y3V0c1xuICBpZiAoIW9wdGlvbnMubm9nbG9ic3RhciAmJiBwYXR0ZXJuID09PSAnKionKSByZXR1cm4gR0xPQlNUQVJcbiAgaWYgKHBhdHRlcm4gPT09ICcnKSByZXR1cm4gJydcblxuICB2YXIgcmUgPSAnJ1xuICB2YXIgaGFzTWFnaWMgPSAhIW9wdGlvbnMubm9jYXNlXG4gIHZhciBlc2NhcGluZyA9IGZhbHNlXG4gIC8vID8gPT4gb25lIHNpbmdsZSBjaGFyYWN0ZXJcbiAgdmFyIHBhdHRlcm5MaXN0U3RhY2sgPSBbXVxuICB2YXIgbmVnYXRpdmVMaXN0cyA9IFtdXG4gIHZhciBzdGF0ZUNoYXJcbiAgdmFyIGluQ2xhc3MgPSBmYWxzZVxuICB2YXIgcmVDbGFzc1N0YXJ0ID0gLTFcbiAgdmFyIGNsYXNzU3RhcnQgPSAtMVxuICAvLyAuIGFuZCAuLiBuZXZlciBtYXRjaCBhbnl0aGluZyB0aGF0IGRvZXNuJ3Qgc3RhcnQgd2l0aCAuLFxuICAvLyBldmVuIHdoZW4gb3B0aW9ucy5kb3QgaXMgc2V0LlxuICB2YXIgcGF0dGVyblN0YXJ0ID0gcGF0dGVybi5jaGFyQXQoMCkgPT09ICcuJyA/ICcnIC8vIGFueXRoaW5nXG4gIC8vIG5vdCAoc3RhcnQgb3IgLyBmb2xsb3dlZCBieSAuIG9yIC4uIGZvbGxvd2VkIGJ5IC8gb3IgZW5kKVxuICA6IG9wdGlvbnMuZG90ID8gJyg/ISg/Ol58XFxcXFxcLylcXFxcLnsxLDJ9KD86JHxcXFxcXFwvKSknXG4gIDogJyg/IVxcXFwuKSdcbiAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgZnVuY3Rpb24gY2xlYXJTdGF0ZUNoYXIgKCkge1xuICAgIGlmIChzdGF0ZUNoYXIpIHtcbiAgICAgIC8vIHdlIGhhZCBzb21lIHN0YXRlLXRyYWNraW5nIGNoYXJhY3RlclxuICAgICAgLy8gdGhhdCB3YXNuJ3QgY29uc3VtZWQgYnkgdGhpcyBwYXNzLlxuICAgICAgc3dpdGNoIChzdGF0ZUNoYXIpIHtcbiAgICAgICAgY2FzZSAnKic6XG4gICAgICAgICAgcmUgKz0gc3RhclxuICAgICAgICAgIGhhc01hZ2ljID0gdHJ1ZVxuICAgICAgICBicmVha1xuICAgICAgICBjYXNlICc/JzpcbiAgICAgICAgICByZSArPSBxbWFya1xuICAgICAgICAgIGhhc01hZ2ljID0gdHJ1ZVxuICAgICAgICBicmVha1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJlICs9ICdcXFxcJyArIHN0YXRlQ2hhclxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgICAgc2VsZi5kZWJ1ZygnY2xlYXJTdGF0ZUNoYXIgJWogJWonLCBzdGF0ZUNoYXIsIHJlKVxuICAgICAgc3RhdGVDaGFyID0gZmFsc2VcbiAgICB9XG4gIH1cblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gcGF0dGVybi5sZW5ndGgsIGNcbiAgICA7IChpIDwgbGVuKSAmJiAoYyA9IHBhdHRlcm4uY2hhckF0KGkpKVxuICAgIDsgaSsrKSB7XG4gICAgdGhpcy5kZWJ1ZygnJXNcXHQlcyAlcyAlaicsIHBhdHRlcm4sIGksIHJlLCBjKVxuXG4gICAgLy8gc2tpcCBvdmVyIGFueSB0aGF0IGFyZSBlc2NhcGVkLlxuICAgIGlmIChlc2NhcGluZyAmJiByZVNwZWNpYWxzW2NdKSB7XG4gICAgICByZSArPSAnXFxcXCcgKyBjXG4gICAgICBlc2NhcGluZyA9IGZhbHNlXG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIHN3aXRjaCAoYykge1xuICAgICAgY2FzZSAnLyc6XG4gICAgICAgIC8vIGNvbXBsZXRlbHkgbm90IGFsbG93ZWQsIGV2ZW4gZXNjYXBlZC5cbiAgICAgICAgLy8gU2hvdWxkIGFscmVhZHkgYmUgcGF0aC1zcGxpdCBieSBub3cuXG4gICAgICAgIHJldHVybiBmYWxzZVxuXG4gICAgICBjYXNlICdcXFxcJzpcbiAgICAgICAgY2xlYXJTdGF0ZUNoYXIoKVxuICAgICAgICBlc2NhcGluZyA9IHRydWVcbiAgICAgIGNvbnRpbnVlXG5cbiAgICAgIC8vIHRoZSB2YXJpb3VzIHN0YXRlQ2hhciB2YWx1ZXNcbiAgICAgIC8vIGZvciB0aGUgXCJleHRnbG9iXCIgc3R1ZmYuXG4gICAgICBjYXNlICc/JzpcbiAgICAgIGNhc2UgJyonOlxuICAgICAgY2FzZSAnKyc6XG4gICAgICBjYXNlICdAJzpcbiAgICAgIGNhc2UgJyEnOlxuICAgICAgICB0aGlzLmRlYnVnKCclc1xcdCVzICVzICVqIDwtLSBzdGF0ZUNoYXInLCBwYXR0ZXJuLCBpLCByZSwgYylcblxuICAgICAgICAvLyBhbGwgb2YgdGhvc2UgYXJlIGxpdGVyYWxzIGluc2lkZSBhIGNsYXNzLCBleGNlcHQgdGhhdFxuICAgICAgICAvLyB0aGUgZ2xvYiBbIWFdIG1lYW5zIFteYV0gaW4gcmVnZXhwXG4gICAgICAgIGlmIChpbkNsYXNzKSB7XG4gICAgICAgICAgdGhpcy5kZWJ1ZygnICBpbiBjbGFzcycpXG4gICAgICAgICAgaWYgKGMgPT09ICchJyAmJiBpID09PSBjbGFzc1N0YXJ0ICsgMSkgYyA9ICdeJ1xuICAgICAgICAgIHJlICs9IGNcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgd2UgYWxyZWFkeSBoYXZlIGEgc3RhdGVDaGFyLCB0aGVuIGl0IG1lYW5zXG4gICAgICAgIC8vIHRoYXQgdGhlcmUgd2FzIHNvbWV0aGluZyBsaWtlICoqIG9yICs/IGluIHRoZXJlLlxuICAgICAgICAvLyBIYW5kbGUgdGhlIHN0YXRlQ2hhciwgdGhlbiBwcm9jZWVkIHdpdGggdGhpcyBvbmUuXG4gICAgICAgIHNlbGYuZGVidWcoJ2NhbGwgY2xlYXJTdGF0ZUNoYXIgJWonLCBzdGF0ZUNoYXIpXG4gICAgICAgIGNsZWFyU3RhdGVDaGFyKClcbiAgICAgICAgc3RhdGVDaGFyID0gY1xuICAgICAgICAvLyBpZiBleHRnbG9iIGlzIGRpc2FibGVkLCB0aGVuICsoYXNkZnxmb28pIGlzbid0IGEgdGhpbmcuXG4gICAgICAgIC8vIGp1c3QgY2xlYXIgdGhlIHN0YXRlY2hhciAqbm93KiwgcmF0aGVyIHRoYW4gZXZlbiBkaXZpbmcgaW50b1xuICAgICAgICAvLyB0aGUgcGF0dGVybkxpc3Qgc3R1ZmYuXG4gICAgICAgIGlmIChvcHRpb25zLm5vZXh0KSBjbGVhclN0YXRlQ2hhcigpXG4gICAgICBjb250aW51ZVxuXG4gICAgICBjYXNlICcoJzpcbiAgICAgICAgaWYgKGluQ2xhc3MpIHtcbiAgICAgICAgICByZSArPSAnKCdcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFzdGF0ZUNoYXIpIHtcbiAgICAgICAgICByZSArPSAnXFxcXCgnXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIHBhdHRlcm5MaXN0U3RhY2sucHVzaCh7XG4gICAgICAgICAgdHlwZTogc3RhdGVDaGFyLFxuICAgICAgICAgIHN0YXJ0OiBpIC0gMSxcbiAgICAgICAgICByZVN0YXJ0OiByZS5sZW5ndGgsXG4gICAgICAgICAgb3BlbjogcGxUeXBlc1tzdGF0ZUNoYXJdLm9wZW4sXG4gICAgICAgICAgY2xvc2U6IHBsVHlwZXNbc3RhdGVDaGFyXS5jbG9zZVxuICAgICAgICB9KVxuICAgICAgICAvLyBuZWdhdGlvbiBpcyAoPzooPyFqcylbXi9dKilcbiAgICAgICAgcmUgKz0gc3RhdGVDaGFyID09PSAnIScgPyAnKD86KD8hKD86JyA6ICcoPzonXG4gICAgICAgIHRoaXMuZGVidWcoJ3BsVHlwZSAlaiAlaicsIHN0YXRlQ2hhciwgcmUpXG4gICAgICAgIHN0YXRlQ2hhciA9IGZhbHNlXG4gICAgICBjb250aW51ZVxuXG4gICAgICBjYXNlICcpJzpcbiAgICAgICAgaWYgKGluQ2xhc3MgfHwgIXBhdHRlcm5MaXN0U3RhY2subGVuZ3RoKSB7XG4gICAgICAgICAgcmUgKz0gJ1xcXFwpJ1xuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICBjbGVhclN0YXRlQ2hhcigpXG4gICAgICAgIGhhc01hZ2ljID0gdHJ1ZVxuICAgICAgICB2YXIgcGwgPSBwYXR0ZXJuTGlzdFN0YWNrLnBvcCgpXG4gICAgICAgIC8vIG5lZ2F0aW9uIGlzICg/Oig/IWpzKVteL10qKVxuICAgICAgICAvLyBUaGUgb3RoZXJzIGFyZSAoPzo8cGF0dGVybj4pPHR5cGU+XG4gICAgICAgIHJlICs9IHBsLmNsb3NlXG4gICAgICAgIGlmIChwbC50eXBlID09PSAnIScpIHtcbiAgICAgICAgICBuZWdhdGl2ZUxpc3RzLnB1c2gocGwpXG4gICAgICAgIH1cbiAgICAgICAgcGwucmVFbmQgPSByZS5sZW5ndGhcbiAgICAgIGNvbnRpbnVlXG5cbiAgICAgIGNhc2UgJ3wnOlxuICAgICAgICBpZiAoaW5DbGFzcyB8fCAhcGF0dGVybkxpc3RTdGFjay5sZW5ndGggfHwgZXNjYXBpbmcpIHtcbiAgICAgICAgICByZSArPSAnXFxcXHwnXG4gICAgICAgICAgZXNjYXBpbmcgPSBmYWxzZVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICBjbGVhclN0YXRlQ2hhcigpXG4gICAgICAgIHJlICs9ICd8J1xuICAgICAgY29udGludWVcblxuICAgICAgLy8gdGhlc2UgYXJlIG1vc3RseSB0aGUgc2FtZSBpbiByZWdleHAgYW5kIGdsb2JcbiAgICAgIGNhc2UgJ1snOlxuICAgICAgICAvLyBzd2FsbG93IGFueSBzdGF0ZS10cmFja2luZyBjaGFyIGJlZm9yZSB0aGUgW1xuICAgICAgICBjbGVhclN0YXRlQ2hhcigpXG5cbiAgICAgICAgaWYgKGluQ2xhc3MpIHtcbiAgICAgICAgICByZSArPSAnXFxcXCcgKyBjXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIGluQ2xhc3MgPSB0cnVlXG4gICAgICAgIGNsYXNzU3RhcnQgPSBpXG4gICAgICAgIHJlQ2xhc3NTdGFydCA9IHJlLmxlbmd0aFxuICAgICAgICByZSArPSBjXG4gICAgICBjb250aW51ZVxuXG4gICAgICBjYXNlICddJzpcbiAgICAgICAgLy8gIGEgcmlnaHQgYnJhY2tldCBzaGFsbCBsb3NlIGl0cyBzcGVjaWFsXG4gICAgICAgIC8vICBtZWFuaW5nIGFuZCByZXByZXNlbnQgaXRzZWxmIGluXG4gICAgICAgIC8vICBhIGJyYWNrZXQgZXhwcmVzc2lvbiBpZiBpdCBvY2N1cnNcbiAgICAgICAgLy8gIGZpcnN0IGluIHRoZSBsaXN0LiAgLS0gUE9TSVguMiAyLjguMy4yXG4gICAgICAgIGlmIChpID09PSBjbGFzc1N0YXJ0ICsgMSB8fCAhaW5DbGFzcykge1xuICAgICAgICAgIHJlICs9ICdcXFxcJyArIGNcbiAgICAgICAgICBlc2NhcGluZyA9IGZhbHNlXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGhhbmRsZSB0aGUgY2FzZSB3aGVyZSB3ZSBsZWZ0IGEgY2xhc3Mgb3Blbi5cbiAgICAgICAgLy8gXCJbei1hXVwiIGlzIHZhbGlkLCBlcXVpdmFsZW50IHRvIFwiXFxbei1hXFxdXCJcbiAgICAgICAgaWYgKGluQ2xhc3MpIHtcbiAgICAgICAgICAvLyBzcGxpdCB3aGVyZSB0aGUgbGFzdCBbIHdhcywgbWFrZSBzdXJlIHdlIGRvbid0IGhhdmVcbiAgICAgICAgICAvLyBhbiBpbnZhbGlkIHJlLiBpZiBzbywgcmUtd2FsayB0aGUgY29udGVudHMgb2YgdGhlXG4gICAgICAgICAgLy8gd291bGQtYmUgY2xhc3MgdG8gcmUtdHJhbnNsYXRlIGFueSBjaGFyYWN0ZXJzIHRoYXRcbiAgICAgICAgICAvLyB3ZXJlIHBhc3NlZCB0aHJvdWdoIGFzLWlzXG4gICAgICAgICAgLy8gVE9ETzogSXQgd291bGQgcHJvYmFibHkgYmUgZmFzdGVyIHRvIGRldGVybWluZSB0aGlzXG4gICAgICAgICAgLy8gd2l0aG91dCBhIHRyeS9jYXRjaCBhbmQgYSBuZXcgUmVnRXhwLCBidXQgaXQncyB0cmlja3lcbiAgICAgICAgICAvLyB0byBkbyBzYWZlbHkuICBGb3Igbm93LCB0aGlzIGlzIHNhZmUgYW5kIHdvcmtzLlxuICAgICAgICAgIHZhciBjcyA9IHBhdHRlcm4uc3Vic3RyaW5nKGNsYXNzU3RhcnQgKyAxLCBpKVxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBSZWdFeHAoJ1snICsgY3MgKyAnXScpXG4gICAgICAgICAgfSBjYXRjaCAoZXIpIHtcbiAgICAgICAgICAgIC8vIG5vdCBhIHZhbGlkIGNsYXNzIVxuICAgICAgICAgICAgdmFyIHNwID0gdGhpcy5wYXJzZShjcywgU1VCUEFSU0UpXG4gICAgICAgICAgICByZSA9IHJlLnN1YnN0cigwLCByZUNsYXNzU3RhcnQpICsgJ1xcXFxbJyArIHNwWzBdICsgJ1xcXFxdJ1xuICAgICAgICAgICAgaGFzTWFnaWMgPSBoYXNNYWdpYyB8fCBzcFsxXVxuICAgICAgICAgICAgaW5DbGFzcyA9IGZhbHNlXG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGZpbmlzaCB1cCB0aGUgY2xhc3MuXG4gICAgICAgIGhhc01hZ2ljID0gdHJ1ZVxuICAgICAgICBpbkNsYXNzID0gZmFsc2VcbiAgICAgICAgcmUgKz0gY1xuICAgICAgY29udGludWVcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgLy8gc3dhbGxvdyBhbnkgc3RhdGUgY2hhciB0aGF0IHdhc24ndCBjb25zdW1lZFxuICAgICAgICBjbGVhclN0YXRlQ2hhcigpXG5cbiAgICAgICAgaWYgKGVzY2FwaW5nKSB7XG4gICAgICAgICAgLy8gbm8gbmVlZFxuICAgICAgICAgIGVzY2FwaW5nID0gZmFsc2VcbiAgICAgICAgfSBlbHNlIGlmIChyZVNwZWNpYWxzW2NdXG4gICAgICAgICAgJiYgIShjID09PSAnXicgJiYgaW5DbGFzcykpIHtcbiAgICAgICAgICByZSArPSAnXFxcXCdcbiAgICAgICAgfVxuXG4gICAgICAgIHJlICs9IGNcblxuICAgIH0gLy8gc3dpdGNoXG4gIH0gLy8gZm9yXG5cbiAgLy8gaGFuZGxlIHRoZSBjYXNlIHdoZXJlIHdlIGxlZnQgYSBjbGFzcyBvcGVuLlxuICAvLyBcIlthYmNcIiBpcyB2YWxpZCwgZXF1aXZhbGVudCB0byBcIlxcW2FiY1wiXG4gIGlmIChpbkNsYXNzKSB7XG4gICAgLy8gc3BsaXQgd2hlcmUgdGhlIGxhc3QgWyB3YXMsIGFuZCBlc2NhcGUgaXRcbiAgICAvLyB0aGlzIGlzIGEgaHVnZSBwaXRhLiAgV2Ugbm93IGhhdmUgdG8gcmUtd2Fsa1xuICAgIC8vIHRoZSBjb250ZW50cyBvZiB0aGUgd291bGQtYmUgY2xhc3MgdG8gcmUtdHJhbnNsYXRlXG4gICAgLy8gYW55IGNoYXJhY3RlcnMgdGhhdCB3ZXJlIHBhc3NlZCB0aHJvdWdoIGFzLWlzXG4gICAgY3MgPSBwYXR0ZXJuLnN1YnN0cihjbGFzc1N0YXJ0ICsgMSlcbiAgICBzcCA9IHRoaXMucGFyc2UoY3MsIFNVQlBBUlNFKVxuICAgIHJlID0gcmUuc3Vic3RyKDAsIHJlQ2xhc3NTdGFydCkgKyAnXFxcXFsnICsgc3BbMF1cbiAgICBoYXNNYWdpYyA9IGhhc01hZ2ljIHx8IHNwWzFdXG4gIH1cblxuICAvLyBoYW5kbGUgdGhlIGNhc2Ugd2hlcmUgd2UgaGFkIGEgKyggdGhpbmcgYXQgdGhlICplbmQqXG4gIC8vIG9mIHRoZSBwYXR0ZXJuLlxuICAvLyBlYWNoIHBhdHRlcm4gbGlzdCBzdGFjayBhZGRzIDMgY2hhcnMsIGFuZCB3ZSBuZWVkIHRvIGdvIHRocm91Z2hcbiAgLy8gYW5kIGVzY2FwZSBhbnkgfCBjaGFycyB0aGF0IHdlcmUgcGFzc2VkIHRocm91Z2ggYXMtaXMgZm9yIHRoZSByZWdleHAuXG4gIC8vIEdvIHRocm91Z2ggYW5kIGVzY2FwZSB0aGVtLCB0YWtpbmcgY2FyZSBub3QgdG8gZG91YmxlLWVzY2FwZSBhbnlcbiAgLy8gfCBjaGFycyB0aGF0IHdlcmUgYWxyZWFkeSBlc2NhcGVkLlxuICBmb3IgKHBsID0gcGF0dGVybkxpc3RTdGFjay5wb3AoKTsgcGw7IHBsID0gcGF0dGVybkxpc3RTdGFjay5wb3AoKSkge1xuICAgIHZhciB0YWlsID0gcmUuc2xpY2UocGwucmVTdGFydCArIHBsLm9wZW4ubGVuZ3RoKVxuICAgIHRoaXMuZGVidWcoJ3NldHRpbmcgdGFpbCcsIHJlLCBwbClcbiAgICAvLyBtYXliZSBzb21lIGV2ZW4gbnVtYmVyIG9mIFxcLCB0aGVuIG1heWJlIDEgXFwsIGZvbGxvd2VkIGJ5IGEgfFxuICAgIHRhaWwgPSB0YWlsLnJlcGxhY2UoLygoPzpcXFxcezJ9KXswLDY0fSkoXFxcXD8pXFx8L2csIGZ1bmN0aW9uIChfLCAkMSwgJDIpIHtcbiAgICAgIGlmICghJDIpIHtcbiAgICAgICAgLy8gdGhlIHwgaXNuJ3QgYWxyZWFkeSBlc2NhcGVkLCBzbyBlc2NhcGUgaXQuXG4gICAgICAgICQyID0gJ1xcXFwnXG4gICAgICB9XG5cbiAgICAgIC8vIG5lZWQgdG8gZXNjYXBlIGFsbCB0aG9zZSBzbGFzaGVzICphZ2FpbiosIHdpdGhvdXQgZXNjYXBpbmcgdGhlXG4gICAgICAvLyBvbmUgdGhhdCB3ZSBuZWVkIGZvciBlc2NhcGluZyB0aGUgfCBjaGFyYWN0ZXIuICBBcyBpdCB3b3JrcyBvdXQsXG4gICAgICAvLyBlc2NhcGluZyBhbiBldmVuIG51bWJlciBvZiBzbGFzaGVzIGNhbiBiZSBkb25lIGJ5IHNpbXBseSByZXBlYXRpbmdcbiAgICAgIC8vIGl0IGV4YWN0bHkgYWZ0ZXIgaXRzZWxmLiAgVGhhdCdzIHdoeSB0aGlzIHRyaWNrIHdvcmtzLlxuICAgICAgLy9cbiAgICAgIC8vIEkgYW0gc29ycnkgdGhhdCB5b3UgaGF2ZSB0byBzZWUgdGhpcy5cbiAgICAgIHJldHVybiAkMSArICQxICsgJDIgKyAnfCdcbiAgICB9KVxuXG4gICAgdGhpcy5kZWJ1ZygndGFpbD0lalxcbiAgICVzJywgdGFpbCwgdGFpbCwgcGwsIHJlKVxuICAgIHZhciB0ID0gcGwudHlwZSA9PT0gJyonID8gc3RhclxuICAgICAgOiBwbC50eXBlID09PSAnPycgPyBxbWFya1xuICAgICAgOiAnXFxcXCcgKyBwbC50eXBlXG5cbiAgICBoYXNNYWdpYyA9IHRydWVcbiAgICByZSA9IHJlLnNsaWNlKDAsIHBsLnJlU3RhcnQpICsgdCArICdcXFxcKCcgKyB0YWlsXG4gIH1cblxuICAvLyBoYW5kbGUgdHJhaWxpbmcgdGhpbmdzIHRoYXQgb25seSBtYXR0ZXIgYXQgdGhlIHZlcnkgZW5kLlxuICBjbGVhclN0YXRlQ2hhcigpXG4gIGlmIChlc2NhcGluZykge1xuICAgIC8vIHRyYWlsaW5nIFxcXFxcbiAgICByZSArPSAnXFxcXFxcXFwnXG4gIH1cblxuICAvLyBvbmx5IG5lZWQgdG8gYXBwbHkgdGhlIG5vZG90IHN0YXJ0IGlmIHRoZSByZSBzdGFydHMgd2l0aFxuICAvLyBzb21ldGhpbmcgdGhhdCBjb3VsZCBjb25jZWl2YWJseSBjYXB0dXJlIGEgZG90XG4gIHZhciBhZGRQYXR0ZXJuU3RhcnQgPSBmYWxzZVxuICBzd2l0Y2ggKHJlLmNoYXJBdCgwKSkge1xuICAgIGNhc2UgJy4nOlxuICAgIGNhc2UgJ1snOlxuICAgIGNhc2UgJygnOiBhZGRQYXR0ZXJuU3RhcnQgPSB0cnVlXG4gIH1cblxuICAvLyBIYWNrIHRvIHdvcmsgYXJvdW5kIGxhY2sgb2YgbmVnYXRpdmUgbG9va2JlaGluZCBpbiBKU1xuICAvLyBBIHBhdHRlcm4gbGlrZTogKi4hKHgpLiEoeXx6KSBuZWVkcyB0byBlbnN1cmUgdGhhdCBhIG5hbWVcbiAgLy8gbGlrZSAnYS54eXoueXonIGRvZXNuJ3QgbWF0Y2guICBTbywgdGhlIGZpcnN0IG5lZ2F0aXZlXG4gIC8vIGxvb2thaGVhZCwgaGFzIHRvIGxvb2sgQUxMIHRoZSB3YXkgYWhlYWQsIHRvIHRoZSBlbmQgb2ZcbiAgLy8gdGhlIHBhdHRlcm4uXG4gIGZvciAodmFyIG4gPSBuZWdhdGl2ZUxpc3RzLmxlbmd0aCAtIDE7IG4gPiAtMTsgbi0tKSB7XG4gICAgdmFyIG5sID0gbmVnYXRpdmVMaXN0c1tuXVxuXG4gICAgdmFyIG5sQmVmb3JlID0gcmUuc2xpY2UoMCwgbmwucmVTdGFydClcbiAgICB2YXIgbmxGaXJzdCA9IHJlLnNsaWNlKG5sLnJlU3RhcnQsIG5sLnJlRW5kIC0gOClcbiAgICB2YXIgbmxMYXN0ID0gcmUuc2xpY2UobmwucmVFbmQgLSA4LCBubC5yZUVuZClcbiAgICB2YXIgbmxBZnRlciA9IHJlLnNsaWNlKG5sLnJlRW5kKVxuXG4gICAgbmxMYXN0ICs9IG5sQWZ0ZXJcblxuICAgIC8vIEhhbmRsZSBuZXN0ZWQgc3R1ZmYgbGlrZSAqKCouanN8ISgqLmpzb24pKSwgd2hlcmUgb3BlbiBwYXJlbnNcbiAgICAvLyBtZWFuIHRoYXQgd2Ugc2hvdWxkICpub3QqIGluY2x1ZGUgdGhlICkgaW4gdGhlIGJpdCB0aGF0IGlzIGNvbnNpZGVyZWRcbiAgICAvLyBcImFmdGVyXCIgdGhlIG5lZ2F0ZWQgc2VjdGlvbi5cbiAgICB2YXIgb3BlblBhcmVuc0JlZm9yZSA9IG5sQmVmb3JlLnNwbGl0KCcoJykubGVuZ3RoIC0gMVxuICAgIHZhciBjbGVhbkFmdGVyID0gbmxBZnRlclxuICAgIGZvciAoaSA9IDA7IGkgPCBvcGVuUGFyZW5zQmVmb3JlOyBpKyspIHtcbiAgICAgIGNsZWFuQWZ0ZXIgPSBjbGVhbkFmdGVyLnJlcGxhY2UoL1xcKVsrKj9dPy8sICcnKVxuICAgIH1cbiAgICBubEFmdGVyID0gY2xlYW5BZnRlclxuXG4gICAgdmFyIGRvbGxhciA9ICcnXG4gICAgaWYgKG5sQWZ0ZXIgPT09ICcnICYmIGlzU3ViICE9PSBTVUJQQVJTRSkge1xuICAgICAgZG9sbGFyID0gJyQnXG4gICAgfVxuICAgIHZhciBuZXdSZSA9IG5sQmVmb3JlICsgbmxGaXJzdCArIG5sQWZ0ZXIgKyBkb2xsYXIgKyBubExhc3RcbiAgICByZSA9IG5ld1JlXG4gIH1cblxuICAvLyBpZiB0aGUgcmUgaXMgbm90IFwiXCIgYXQgdGhpcyBwb2ludCwgdGhlbiB3ZSBuZWVkIHRvIG1ha2Ugc3VyZVxuICAvLyBpdCBkb2Vzbid0IG1hdGNoIGFnYWluc3QgYW4gZW1wdHkgcGF0aCBwYXJ0LlxuICAvLyBPdGhlcndpc2UgYS8qIHdpbGwgbWF0Y2ggYS8sIHdoaWNoIGl0IHNob3VsZCBub3QuXG4gIGlmIChyZSAhPT0gJycgJiYgaGFzTWFnaWMpIHtcbiAgICByZSA9ICcoPz0uKScgKyByZVxuICB9XG5cbiAgaWYgKGFkZFBhdHRlcm5TdGFydCkge1xuICAgIHJlID0gcGF0dGVyblN0YXJ0ICsgcmVcbiAgfVxuXG4gIC8vIHBhcnNpbmcganVzdCBhIHBpZWNlIG9mIGEgbGFyZ2VyIHBhdHRlcm4uXG4gIGlmIChpc1N1YiA9PT0gU1VCUEFSU0UpIHtcbiAgICByZXR1cm4gW3JlLCBoYXNNYWdpY11cbiAgfVxuXG4gIC8vIHNraXAgdGhlIHJlZ2V4cCBmb3Igbm9uLW1hZ2ljYWwgcGF0dGVybnNcbiAgLy8gdW5lc2NhcGUgYW55dGhpbmcgaW4gaXQsIHRob3VnaCwgc28gdGhhdCBpdCdsbCBiZVxuICAvLyBhbiBleGFjdCBtYXRjaCBhZ2FpbnN0IGEgZmlsZSBldGMuXG4gIGlmICghaGFzTWFnaWMpIHtcbiAgICByZXR1cm4gZ2xvYlVuZXNjYXBlKHBhdHRlcm4pXG4gIH1cblxuICB2YXIgZmxhZ3MgPSBvcHRpb25zLm5vY2FzZSA/ICdpJyA6ICcnXG4gIHRyeSB7XG4gICAgdmFyIHJlZ0V4cCA9IG5ldyBSZWdFeHAoJ14nICsgcmUgKyAnJCcsIGZsYWdzKVxuICB9IGNhdGNoIChlcikge1xuICAgIC8vIElmIGl0IHdhcyBhbiBpbnZhbGlkIHJlZ3VsYXIgZXhwcmVzc2lvbiwgdGhlbiBpdCBjYW4ndCBtYXRjaFxuICAgIC8vIGFueXRoaW5nLiAgVGhpcyB0cmljayBsb29rcyBmb3IgYSBjaGFyYWN0ZXIgYWZ0ZXIgdGhlIGVuZCBvZlxuICAgIC8vIHRoZSBzdHJpbmcsIHdoaWNoIGlzIG9mIGNvdXJzZSBpbXBvc3NpYmxlLCBleGNlcHQgaW4gbXVsdGktbGluZVxuICAgIC8vIG1vZGUsIGJ1dCBpdCdzIG5vdCBhIC9tIHJlZ2V4LlxuICAgIHJldHVybiBuZXcgUmVnRXhwKCckLicpXG4gIH1cblxuICByZWdFeHAuX2dsb2IgPSBwYXR0ZXJuXG4gIHJlZ0V4cC5fc3JjID0gcmVcblxuICByZXR1cm4gcmVnRXhwXG59XG5cbm1pbmltYXRjaC5tYWtlUmUgPSBmdW5jdGlvbiAocGF0dGVybiwgb3B0aW9ucykge1xuICByZXR1cm4gbmV3IE1pbmltYXRjaChwYXR0ZXJuLCBvcHRpb25zIHx8IHt9KS5tYWtlUmUoKVxufVxuXG5NaW5pbWF0Y2gucHJvdG90eXBlLm1ha2VSZSA9IG1ha2VSZVxuZnVuY3Rpb24gbWFrZVJlICgpIHtcbiAgaWYgKHRoaXMucmVnZXhwIHx8IHRoaXMucmVnZXhwID09PSBmYWxzZSkgcmV0dXJuIHRoaXMucmVnZXhwXG5cbiAgLy8gYXQgdGhpcyBwb2ludCwgdGhpcy5zZXQgaXMgYSAyZCBhcnJheSBvZiBwYXJ0aWFsXG4gIC8vIHBhdHRlcm4gc3RyaW5ncywgb3IgXCIqKlwiLlxuICAvL1xuICAvLyBJdCdzIGJldHRlciB0byB1c2UgLm1hdGNoKCkuICBUaGlzIGZ1bmN0aW9uIHNob3VsZG4ndFxuICAvLyBiZSB1c2VkLCByZWFsbHksIGJ1dCBpdCdzIHByZXR0eSBjb252ZW5pZW50IHNvbWV0aW1lcyxcbiAgLy8gd2hlbiB5b3UganVzdCB3YW50IHRvIHdvcmsgd2l0aCBhIHJlZ2V4LlxuICB2YXIgc2V0ID0gdGhpcy5zZXRcblxuICBpZiAoIXNldC5sZW5ndGgpIHtcbiAgICB0aGlzLnJlZ2V4cCA9IGZhbHNlXG4gICAgcmV0dXJuIHRoaXMucmVnZXhwXG4gIH1cbiAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnNcblxuICB2YXIgdHdvU3RhciA9IG9wdGlvbnMubm9nbG9ic3RhciA/IHN0YXJcbiAgICA6IG9wdGlvbnMuZG90ID8gdHdvU3RhckRvdFxuICAgIDogdHdvU3Rhck5vRG90XG4gIHZhciBmbGFncyA9IG9wdGlvbnMubm9jYXNlID8gJ2knIDogJydcblxuICB2YXIgcmUgPSBzZXQubWFwKGZ1bmN0aW9uIChwYXR0ZXJuKSB7XG4gICAgcmV0dXJuIHBhdHRlcm4ubWFwKGZ1bmN0aW9uIChwKSB7XG4gICAgICByZXR1cm4gKHAgPT09IEdMT0JTVEFSKSA/IHR3b1N0YXJcbiAgICAgIDogKHR5cGVvZiBwID09PSAnc3RyaW5nJykgPyByZWdFeHBFc2NhcGUocClcbiAgICAgIDogcC5fc3JjXG4gICAgfSkuam9pbignXFxcXFxcLycpXG4gIH0pLmpvaW4oJ3wnKVxuXG4gIC8vIG11c3QgbWF0Y2ggZW50aXJlIHBhdHRlcm5cbiAgLy8gZW5kaW5nIGluIGEgKiBvciAqKiB3aWxsIG1ha2UgaXQgbGVzcyBzdHJpY3QuXG4gIHJlID0gJ14oPzonICsgcmUgKyAnKSQnXG5cbiAgLy8gY2FuIG1hdGNoIGFueXRoaW5nLCBhcyBsb25nIGFzIGl0J3Mgbm90IHRoaXMuXG4gIGlmICh0aGlzLm5lZ2F0ZSkgcmUgPSAnXig/IScgKyByZSArICcpLiokJ1xuXG4gIHRyeSB7XG4gICAgdGhpcy5yZWdleHAgPSBuZXcgUmVnRXhwKHJlLCBmbGFncylcbiAgfSBjYXRjaCAoZXgpIHtcbiAgICB0aGlzLnJlZ2V4cCA9IGZhbHNlXG4gIH1cbiAgcmV0dXJuIHRoaXMucmVnZXhwXG59XG5cbm1pbmltYXRjaC5tYXRjaCA9IGZ1bmN0aW9uIChsaXN0LCBwYXR0ZXJuLCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9XG4gIHZhciBtbSA9IG5ldyBNaW5pbWF0Y2gocGF0dGVybiwgb3B0aW9ucylcbiAgbGlzdCA9IGxpc3QuZmlsdGVyKGZ1bmN0aW9uIChmKSB7XG4gICAgcmV0dXJuIG1tLm1hdGNoKGYpXG4gIH0pXG4gIGlmIChtbS5vcHRpb25zLm5vbnVsbCAmJiAhbGlzdC5sZW5ndGgpIHtcbiAgICBsaXN0LnB1c2gocGF0dGVybilcbiAgfVxuICByZXR1cm4gbGlzdFxufVxuXG5NaW5pbWF0Y2gucHJvdG90eXBlLm1hdGNoID0gbWF0Y2hcbmZ1bmN0aW9uIG1hdGNoIChmLCBwYXJ0aWFsKSB7XG4gIHRoaXMuZGVidWcoJ21hdGNoJywgZiwgdGhpcy5wYXR0ZXJuKVxuICAvLyBzaG9ydC1jaXJjdWl0IGluIHRoZSBjYXNlIG9mIGJ1c3RlZCB0aGluZ3MuXG4gIC8vIGNvbW1lbnRzLCBldGMuXG4gIGlmICh0aGlzLmNvbW1lbnQpIHJldHVybiBmYWxzZVxuICBpZiAodGhpcy5lbXB0eSkgcmV0dXJuIGYgPT09ICcnXG5cbiAgaWYgKGYgPT09ICcvJyAmJiBwYXJ0aWFsKSByZXR1cm4gdHJ1ZVxuXG4gIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zXG5cbiAgLy8gd2luZG93czogbmVlZCB0byB1c2UgLywgbm90IFxcXG4gIGlmIChwYXRoLnNlcCAhPT0gJy8nKSB7XG4gICAgZiA9IGYuc3BsaXQocGF0aC5zZXApLmpvaW4oJy8nKVxuICB9XG5cbiAgLy8gdHJlYXQgdGhlIHRlc3QgcGF0aCBhcyBhIHNldCBvZiBwYXRocGFydHMuXG4gIGYgPSBmLnNwbGl0KHNsYXNoU3BsaXQpXG4gIHRoaXMuZGVidWcodGhpcy5wYXR0ZXJuLCAnc3BsaXQnLCBmKVxuXG4gIC8vIGp1c3QgT05FIG9mIHRoZSBwYXR0ZXJuIHNldHMgaW4gdGhpcy5zZXQgbmVlZHMgdG8gbWF0Y2hcbiAgLy8gaW4gb3JkZXIgZm9yIGl0IHRvIGJlIHZhbGlkLiAgSWYgbmVnYXRpbmcsIHRoZW4ganVzdCBvbmVcbiAgLy8gbWF0Y2ggbWVhbnMgdGhhdCB3ZSBoYXZlIGZhaWxlZC5cbiAgLy8gRWl0aGVyIHdheSwgcmV0dXJuIG9uIHRoZSBmaXJzdCBoaXQuXG5cbiAgdmFyIHNldCA9IHRoaXMuc2V0XG4gIHRoaXMuZGVidWcodGhpcy5wYXR0ZXJuLCAnc2V0Jywgc2V0KVxuXG4gIC8vIEZpbmQgdGhlIGJhc2VuYW1lIG9mIHRoZSBwYXRoIGJ5IGxvb2tpbmcgZm9yIHRoZSBsYXN0IG5vbi1lbXB0eSBzZWdtZW50XG4gIHZhciBmaWxlbmFtZVxuICB2YXIgaVxuICBmb3IgKGkgPSBmLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgZmlsZW5hbWUgPSBmW2ldXG4gICAgaWYgKGZpbGVuYW1lKSBicmVha1xuICB9XG5cbiAgZm9yIChpID0gMDsgaSA8IHNldC5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXR0ZXJuID0gc2V0W2ldXG4gICAgdmFyIGZpbGUgPSBmXG4gICAgaWYgKG9wdGlvbnMubWF0Y2hCYXNlICYmIHBhdHRlcm4ubGVuZ3RoID09PSAxKSB7XG4gICAgICBmaWxlID0gW2ZpbGVuYW1lXVxuICAgIH1cbiAgICB2YXIgaGl0ID0gdGhpcy5tYXRjaE9uZShmaWxlLCBwYXR0ZXJuLCBwYXJ0aWFsKVxuICAgIGlmIChoaXQpIHtcbiAgICAgIGlmIChvcHRpb25zLmZsaXBOZWdhdGUpIHJldHVybiB0cnVlXG4gICAgICByZXR1cm4gIXRoaXMubmVnYXRlXG4gICAgfVxuICB9XG5cbiAgLy8gZGlkbid0IGdldCBhbnkgaGl0cy4gIHRoaXMgaXMgc3VjY2VzcyBpZiBpdCdzIGEgbmVnYXRpdmVcbiAgLy8gcGF0dGVybiwgZmFpbHVyZSBvdGhlcndpc2UuXG4gIGlmIChvcHRpb25zLmZsaXBOZWdhdGUpIHJldHVybiBmYWxzZVxuICByZXR1cm4gdGhpcy5uZWdhdGVcbn1cblxuLy8gc2V0IHBhcnRpYWwgdG8gdHJ1ZSB0byB0ZXN0IGlmLCBmb3IgZXhhbXBsZSxcbi8vIFwiL2EvYlwiIG1hdGNoZXMgdGhlIHN0YXJ0IG9mIFwiLyovYi8qL2RcIlxuLy8gUGFydGlhbCBtZWFucywgaWYgeW91IHJ1biBvdXQgb2YgZmlsZSBiZWZvcmUgeW91IHJ1blxuLy8gb3V0IG9mIHBhdHRlcm4sIHRoZW4gdGhhdCdzIGZpbmUsIGFzIGxvbmcgYXMgYWxsXG4vLyB0aGUgcGFydHMgbWF0Y2guXG5NaW5pbWF0Y2gucHJvdG90eXBlLm1hdGNoT25lID0gZnVuY3Rpb24gKGZpbGUsIHBhdHRlcm4sIHBhcnRpYWwpIHtcbiAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnNcblxuICB0aGlzLmRlYnVnKCdtYXRjaE9uZScsXG4gICAgeyAndGhpcyc6IHRoaXMsIGZpbGU6IGZpbGUsIHBhdHRlcm46IHBhdHRlcm4gfSlcblxuICB0aGlzLmRlYnVnKCdtYXRjaE9uZScsIGZpbGUubGVuZ3RoLCBwYXR0ZXJuLmxlbmd0aClcblxuICBmb3IgKHZhciBmaSA9IDAsXG4gICAgICBwaSA9IDAsXG4gICAgICBmbCA9IGZpbGUubGVuZ3RoLFxuICAgICAgcGwgPSBwYXR0ZXJuLmxlbmd0aFxuICAgICAgOyAoZmkgPCBmbCkgJiYgKHBpIDwgcGwpXG4gICAgICA7IGZpKyssIHBpKyspIHtcbiAgICB0aGlzLmRlYnVnKCdtYXRjaE9uZSBsb29wJylcbiAgICB2YXIgcCA9IHBhdHRlcm5bcGldXG4gICAgdmFyIGYgPSBmaWxlW2ZpXVxuXG4gICAgdGhpcy5kZWJ1ZyhwYXR0ZXJuLCBwLCBmKVxuXG4gICAgLy8gc2hvdWxkIGJlIGltcG9zc2libGUuXG4gICAgLy8gc29tZSBpbnZhbGlkIHJlZ2V4cCBzdHVmZiBpbiB0aGUgc2V0LlxuICAgIGlmIChwID09PSBmYWxzZSkgcmV0dXJuIGZhbHNlXG5cbiAgICBpZiAocCA9PT0gR0xPQlNUQVIpIHtcbiAgICAgIHRoaXMuZGVidWcoJ0dMT0JTVEFSJywgW3BhdHRlcm4sIHAsIGZdKVxuXG4gICAgICAvLyBcIioqXCJcbiAgICAgIC8vIGEvKiovYi8qKi9jIHdvdWxkIG1hdGNoIHRoZSBmb2xsb3dpbmc6XG4gICAgICAvLyBhL2IveC95L3ovY1xuICAgICAgLy8gYS94L3kvei9iL2NcbiAgICAgIC8vIGEvYi94L2IveC9jXG4gICAgICAvLyBhL2IvY1xuICAgICAgLy8gVG8gZG8gdGhpcywgdGFrZSB0aGUgcmVzdCBvZiB0aGUgcGF0dGVybiBhZnRlclxuICAgICAgLy8gdGhlICoqLCBhbmQgc2VlIGlmIGl0IHdvdWxkIG1hdGNoIHRoZSBmaWxlIHJlbWFpbmRlci5cbiAgICAgIC8vIElmIHNvLCByZXR1cm4gc3VjY2Vzcy5cbiAgICAgIC8vIElmIG5vdCwgdGhlICoqIFwic3dhbGxvd3NcIiBhIHNlZ21lbnQsIGFuZCB0cnkgYWdhaW4uXG4gICAgICAvLyBUaGlzIGlzIHJlY3Vyc2l2ZWx5IGF3ZnVsLlxuICAgICAgLy9cbiAgICAgIC8vIGEvKiovYi8qKi9jIG1hdGNoaW5nIGEvYi94L3kvei9jXG4gICAgICAvLyAtIGEgbWF0Y2hlcyBhXG4gICAgICAvLyAtIGRvdWJsZXN0YXJcbiAgICAgIC8vICAgLSBtYXRjaE9uZShiL3gveS96L2MsIGIvKiovYylcbiAgICAgIC8vICAgICAtIGIgbWF0Y2hlcyBiXG4gICAgICAvLyAgICAgLSBkb3VibGVzdGFyXG4gICAgICAvLyAgICAgICAtIG1hdGNoT25lKHgveS96L2MsIGMpIC0+IG5vXG4gICAgICAvLyAgICAgICAtIG1hdGNoT25lKHkvei9jLCBjKSAtPiBub1xuICAgICAgLy8gICAgICAgLSBtYXRjaE9uZSh6L2MsIGMpIC0+IG5vXG4gICAgICAvLyAgICAgICAtIG1hdGNoT25lKGMsIGMpIHllcywgaGl0XG4gICAgICB2YXIgZnIgPSBmaVxuICAgICAgdmFyIHByID0gcGkgKyAxXG4gICAgICBpZiAocHIgPT09IHBsKSB7XG4gICAgICAgIHRoaXMuZGVidWcoJyoqIGF0IHRoZSBlbmQnKVxuICAgICAgICAvLyBhICoqIGF0IHRoZSBlbmQgd2lsbCBqdXN0IHN3YWxsb3cgdGhlIHJlc3QuXG4gICAgICAgIC8vIFdlIGhhdmUgZm91bmQgYSBtYXRjaC5cbiAgICAgICAgLy8gaG93ZXZlciwgaXQgd2lsbCBub3Qgc3dhbGxvdyAvLngsIHVubGVzc1xuICAgICAgICAvLyBvcHRpb25zLmRvdCBpcyBzZXQuXG4gICAgICAgIC8vIC4gYW5kIC4uIGFyZSAqbmV2ZXIqIG1hdGNoZWQgYnkgKiosIGZvciBleHBsb3NpdmVseVxuICAgICAgICAvLyBleHBvbmVudGlhbCByZWFzb25zLlxuICAgICAgICBmb3IgKDsgZmkgPCBmbDsgZmkrKykge1xuICAgICAgICAgIGlmIChmaWxlW2ZpXSA9PT0gJy4nIHx8IGZpbGVbZmldID09PSAnLi4nIHx8XG4gICAgICAgICAgICAoIW9wdGlvbnMuZG90ICYmIGZpbGVbZmldLmNoYXJBdCgwKSA9PT0gJy4nKSkgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgIH1cblxuICAgICAgLy8gb2ssIGxldCdzIHNlZSBpZiB3ZSBjYW4gc3dhbGxvdyB3aGF0ZXZlciB3ZSBjYW4uXG4gICAgICB3aGlsZSAoZnIgPCBmbCkge1xuICAgICAgICB2YXIgc3dhbGxvd2VlID0gZmlsZVtmcl1cblxuICAgICAgICB0aGlzLmRlYnVnKCdcXG5nbG9ic3RhciB3aGlsZScsIGZpbGUsIGZyLCBwYXR0ZXJuLCBwciwgc3dhbGxvd2VlKVxuXG4gICAgICAgIC8vIFhYWCByZW1vdmUgdGhpcyBzbGljZS4gIEp1c3QgcGFzcyB0aGUgc3RhcnQgaW5kZXguXG4gICAgICAgIGlmICh0aGlzLm1hdGNoT25lKGZpbGUuc2xpY2UoZnIpLCBwYXR0ZXJuLnNsaWNlKHByKSwgcGFydGlhbCkpIHtcbiAgICAgICAgICB0aGlzLmRlYnVnKCdnbG9ic3RhciBmb3VuZCBtYXRjaCEnLCBmciwgZmwsIHN3YWxsb3dlZSlcbiAgICAgICAgICAvLyBmb3VuZCBhIG1hdGNoLlxuICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gY2FuJ3Qgc3dhbGxvdyBcIi5cIiBvciBcIi4uXCIgZXZlci5cbiAgICAgICAgICAvLyBjYW4gb25seSBzd2FsbG93IFwiLmZvb1wiIHdoZW4gZXhwbGljaXRseSBhc2tlZC5cbiAgICAgICAgICBpZiAoc3dhbGxvd2VlID09PSAnLicgfHwgc3dhbGxvd2VlID09PSAnLi4nIHx8XG4gICAgICAgICAgICAoIW9wdGlvbnMuZG90ICYmIHN3YWxsb3dlZS5jaGFyQXQoMCkgPT09ICcuJykpIHtcbiAgICAgICAgICAgIHRoaXMuZGVidWcoJ2RvdCBkZXRlY3RlZCEnLCBmaWxlLCBmciwgcGF0dGVybiwgcHIpXG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vICoqIHN3YWxsb3dzIGEgc2VnbWVudCwgYW5kIGNvbnRpbnVlLlxuICAgICAgICAgIHRoaXMuZGVidWcoJ2dsb2JzdGFyIHN3YWxsb3cgYSBzZWdtZW50LCBhbmQgY29udGludWUnKVxuICAgICAgICAgIGZyKytcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBubyBtYXRjaCB3YXMgZm91bmQuXG4gICAgICAvLyBIb3dldmVyLCBpbiBwYXJ0aWFsIG1vZGUsIHdlIGNhbid0IHNheSB0aGlzIGlzIG5lY2Vzc2FyaWx5IG92ZXIuXG4gICAgICAvLyBJZiB0aGVyZSdzIG1vcmUgKnBhdHRlcm4qIGxlZnQsIHRoZW5cbiAgICAgIGlmIChwYXJ0aWFsKSB7XG4gICAgICAgIC8vIHJhbiBvdXQgb2YgZmlsZVxuICAgICAgICB0aGlzLmRlYnVnKCdcXG4+Pj4gbm8gbWF0Y2gsIHBhcnRpYWw/JywgZmlsZSwgZnIsIHBhdHRlcm4sIHByKVxuICAgICAgICBpZiAoZnIgPT09IGZsKSByZXR1cm4gdHJ1ZVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gc29tZXRoaW5nIG90aGVyIHRoYW4gKipcbiAgICAvLyBub24tbWFnaWMgcGF0dGVybnMganVzdCBoYXZlIHRvIG1hdGNoIGV4YWN0bHlcbiAgICAvLyBwYXR0ZXJucyB3aXRoIG1hZ2ljIGhhdmUgYmVlbiB0dXJuZWQgaW50byByZWdleHBzLlxuICAgIHZhciBoaXRcbiAgICBpZiAodHlwZW9mIHAgPT09ICdzdHJpbmcnKSB7XG4gICAgICBpZiAob3B0aW9ucy5ub2Nhc2UpIHtcbiAgICAgICAgaGl0ID0gZi50b0xvd2VyQ2FzZSgpID09PSBwLnRvTG93ZXJDYXNlKClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhpdCA9IGYgPT09IHBcbiAgICAgIH1cbiAgICAgIHRoaXMuZGVidWcoJ3N0cmluZyBtYXRjaCcsIHAsIGYsIGhpdClcbiAgICB9IGVsc2Uge1xuICAgICAgaGl0ID0gZi5tYXRjaChwKVxuICAgICAgdGhpcy5kZWJ1ZygncGF0dGVybiBtYXRjaCcsIHAsIGYsIGhpdClcbiAgICB9XG5cbiAgICBpZiAoIWhpdCkgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvLyBOb3RlOiBlbmRpbmcgaW4gLyBtZWFucyB0aGF0IHdlJ2xsIGdldCBhIGZpbmFsIFwiXCJcbiAgLy8gYXQgdGhlIGVuZCBvZiB0aGUgcGF0dGVybi4gIFRoaXMgY2FuIG9ubHkgbWF0Y2ggYVxuICAvLyBjb3JyZXNwb25kaW5nIFwiXCIgYXQgdGhlIGVuZCBvZiB0aGUgZmlsZS5cbiAgLy8gSWYgdGhlIGZpbGUgZW5kcyBpbiAvLCB0aGVuIGl0IGNhbiBvbmx5IG1hdGNoIGFcbiAgLy8gYSBwYXR0ZXJuIHRoYXQgZW5kcyBpbiAvLCB1bmxlc3MgdGhlIHBhdHRlcm4ganVzdFxuICAvLyBkb2Vzbid0IGhhdmUgYW55IG1vcmUgZm9yIGl0LiBCdXQsIGEvYi8gc2hvdWxkICpub3QqXG4gIC8vIG1hdGNoIFwiYS9iLypcIiwgZXZlbiB0aG91Z2ggXCJcIiBtYXRjaGVzIGFnYWluc3QgdGhlXG4gIC8vIFteL10qPyBwYXR0ZXJuLCBleGNlcHQgaW4gcGFydGlhbCBtb2RlLCB3aGVyZSBpdCBtaWdodFxuICAvLyBzaW1wbHkgbm90IGJlIHJlYWNoZWQgeWV0LlxuICAvLyBIb3dldmVyLCBhL2IvIHNob3VsZCBzdGlsbCBzYXRpc2Z5IGEvKlxuXG4gIC8vIG5vdyBlaXRoZXIgd2UgZmVsbCBvZmYgdGhlIGVuZCBvZiB0aGUgcGF0dGVybiwgb3Igd2UncmUgZG9uZS5cbiAgaWYgKGZpID09PSBmbCAmJiBwaSA9PT0gcGwpIHtcbiAgICAvLyByYW4gb3V0IG9mIHBhdHRlcm4gYW5kIGZpbGVuYW1lIGF0IHRoZSBzYW1lIHRpbWUuXG4gICAgLy8gYW4gZXhhY3QgaGl0IVxuICAgIHJldHVybiB0cnVlXG4gIH0gZWxzZSBpZiAoZmkgPT09IGZsKSB7XG4gICAgLy8gcmFuIG91dCBvZiBmaWxlLCBidXQgc3RpbGwgaGFkIHBhdHRlcm4gbGVmdC5cbiAgICAvLyB0aGlzIGlzIG9rIGlmIHdlJ3JlIGRvaW5nIHRoZSBtYXRjaCBhcyBwYXJ0IG9mXG4gICAgLy8gYSBnbG9iIGZzIHRyYXZlcnNhbC5cbiAgICByZXR1cm4gcGFydGlhbFxuICB9IGVsc2UgaWYgKHBpID09PSBwbCkge1xuICAgIC8vIHJhbiBvdXQgb2YgcGF0dGVybiwgc3RpbGwgaGF2ZSBmaWxlIGxlZnQuXG4gICAgLy8gdGhpcyBpcyBvbmx5IGFjY2VwdGFibGUgaWYgd2UncmUgb24gdGhlIHZlcnkgbGFzdFxuICAgIC8vIGVtcHR5IHNlZ21lbnQgb2YgYSBmaWxlIHdpdGggYSB0cmFpbGluZyBzbGFzaC5cbiAgICAvLyBhLyogc2hvdWxkIG1hdGNoIGEvYi9cbiAgICB2YXIgZW1wdHlGaWxlRW5kID0gKGZpID09PSBmbCAtIDEpICYmIChmaWxlW2ZpXSA9PT0gJycpXG4gICAgcmV0dXJuIGVtcHR5RmlsZUVuZFxuICB9XG5cbiAgLy8gc2hvdWxkIGJlIHVucmVhY2hhYmxlLlxuICB0aHJvdyBuZXcgRXJyb3IoJ3d0Zj8nKVxufVxuXG4vLyByZXBsYWNlIHN0dWZmIGxpa2UgXFwqIHdpdGggKlxuZnVuY3Rpb24gZ2xvYlVuZXNjYXBlIChzKSB7XG4gIHJldHVybiBzLnJlcGxhY2UoL1xcXFwoLikvZywgJyQxJylcbn1cblxuZnVuY3Rpb24gcmVnRXhwRXNjYXBlIChzKSB7XG4gIHJldHVybiBzLnJlcGxhY2UoL1stW1xcXXt9KCkqKz8uLFxcXFxeJHwjXFxzXS9nLCAnXFxcXCQmJylcbn1cbiIsInZhciB3cmFwcHkgPSByZXF1aXJlKCd3cmFwcHknKVxubW9kdWxlLmV4cG9ydHMgPSB3cmFwcHkob25jZSlcbm1vZHVsZS5leHBvcnRzLnN0cmljdCA9IHdyYXBweShvbmNlU3RyaWN0KVxuXG5vbmNlLnByb3RvID0gb25jZShmdW5jdGlvbiAoKSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShGdW5jdGlvbi5wcm90b3R5cGUsICdvbmNlJywge1xuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gb25jZSh0aGlzKVxuICAgIH0sXG4gICAgY29uZmlndXJhYmxlOiB0cnVlXG4gIH0pXG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEZ1bmN0aW9uLnByb3RvdHlwZSwgJ29uY2VTdHJpY3QnLCB7XG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBvbmNlU3RyaWN0KHRoaXMpXG4gICAgfSxcbiAgICBjb25maWd1cmFibGU6IHRydWVcbiAgfSlcbn0pXG5cbmZ1bmN0aW9uIG9uY2UgKGZuKSB7XG4gIHZhciBmID0gZnVuY3Rpb24gKCkge1xuICAgIGlmIChmLmNhbGxlZCkgcmV0dXJuIGYudmFsdWVcbiAgICBmLmNhbGxlZCA9IHRydWVcbiAgICByZXR1cm4gZi52YWx1ZSA9IGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbiAgfVxuICBmLmNhbGxlZCA9IGZhbHNlXG4gIHJldHVybiBmXG59XG5cbmZ1bmN0aW9uIG9uY2VTdHJpY3QgKGZuKSB7XG4gIHZhciBmID0gZnVuY3Rpb24gKCkge1xuICAgIGlmIChmLmNhbGxlZClcbiAgICAgIHRocm93IG5ldyBFcnJvcihmLm9uY2VFcnJvcilcbiAgICBmLmNhbGxlZCA9IHRydWVcbiAgICByZXR1cm4gZi52YWx1ZSA9IGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbiAgfVxuICB2YXIgbmFtZSA9IGZuLm5hbWUgfHwgJ0Z1bmN0aW9uIHdyYXBwZWQgd2l0aCBgb25jZWAnXG4gIGYub25jZUVycm9yID0gbmFtZSArIFwiIHNob3VsZG4ndCBiZSBjYWxsZWQgbW9yZSB0aGFuIG9uY2VcIlxuICBmLmNhbGxlZCA9IGZhbHNlXG4gIHJldHVybiBmXG59XG4iLCIndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIHBvc2l4KHBhdGgpIHtcblx0cmV0dXJuIHBhdGguY2hhckF0KDApID09PSAnLyc7XG59XG5cbmZ1bmN0aW9uIHdpbjMyKHBhdGgpIHtcblx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL25vZGVqcy9ub2RlL2Jsb2IvYjNmY2MyNDVmYjI1NTM5OTA5ZWYxZDVlYWEwMWRiZjkyZTE2ODYzMy9saWIvcGF0aC5qcyNMNTZcblx0dmFyIHNwbGl0RGV2aWNlUmUgPSAvXihbYS16QS1aXTp8W1xcXFxcXC9dezJ9W15cXFxcXFwvXStbXFxcXFxcL10rW15cXFxcXFwvXSspPyhbXFxcXFxcL10pPyhbXFxzXFxTXSo/KSQvO1xuXHR2YXIgcmVzdWx0ID0gc3BsaXREZXZpY2VSZS5leGVjKHBhdGgpO1xuXHR2YXIgZGV2aWNlID0gcmVzdWx0WzFdIHx8ICcnO1xuXHR2YXIgaXNVbmMgPSBCb29sZWFuKGRldmljZSAmJiBkZXZpY2UuY2hhckF0KDEpICE9PSAnOicpO1xuXG5cdC8vIFVOQyBwYXRocyBhcmUgYWx3YXlzIGFic29sdXRlXG5cdHJldHVybiBCb29sZWFuKHJlc3VsdFsyXSB8fCBpc1VuYyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJyA/IHdpbjMyIDogcG9zaXg7XG5tb2R1bGUuZXhwb3J0cy5wb3NpeCA9IHBvc2l4O1xubW9kdWxlLmV4cG9ydHMud2luMzIgPSB3aW4zMjtcbiIsIi8vIHZpbTp0cz00OnN0cz00OnN3PTQ6XG4vKiFcbiAqXG4gKiBDb3B5cmlnaHQgMjAwOS0yMDE3IEtyaXMgS293YWwgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBNSVRcbiAqIGxpY2Vuc2UgZm91bmQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2tyaXNrb3dhbC9xL2Jsb2IvdjEvTElDRU5TRVxuICpcbiAqIFdpdGggcGFydHMgYnkgVHlsZXIgQ2xvc2VcbiAqIENvcHlyaWdodCAyMDA3LTIwMDkgVHlsZXIgQ2xvc2UgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBNSVQgWCBsaWNlbnNlIGZvdW5kXG4gKiBhdCBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLmh0bWxcbiAqIEZvcmtlZCBhdCByZWZfc2VuZC5qcyB2ZXJzaW9uOiAyMDA5LTA1LTExXG4gKlxuICogV2l0aCBwYXJ0cyBieSBNYXJrIE1pbGxlclxuICogQ29weXJpZ2h0IChDKSAyMDExIEdvb2dsZSBJbmMuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbihmdW5jdGlvbiAoZGVmaW5pdGlvbikge1xuICAgIFwidXNlIHN0cmljdFwiO1xuXG4gICAgLy8gVGhpcyBmaWxlIHdpbGwgZnVuY3Rpb24gcHJvcGVybHkgYXMgYSA8c2NyaXB0PiB0YWcsIG9yIGEgbW9kdWxlXG4gICAgLy8gdXNpbmcgQ29tbW9uSlMgYW5kIE5vZGVKUyBvciBSZXF1aXJlSlMgbW9kdWxlIGZvcm1hdHMuICBJblxuICAgIC8vIENvbW1vbi9Ob2RlL1JlcXVpcmVKUywgdGhlIG1vZHVsZSBleHBvcnRzIHRoZSBRIEFQSSBhbmQgd2hlblxuICAgIC8vIGV4ZWN1dGVkIGFzIGEgc2ltcGxlIDxzY3JpcHQ+LCBpdCBjcmVhdGVzIGEgUSBnbG9iYWwgaW5zdGVhZC5cblxuICAgIC8vIE1vbnRhZ2UgUmVxdWlyZVxuICAgIGlmICh0eXBlb2YgYm9vdHN0cmFwID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgYm9vdHN0cmFwKFwicHJvbWlzZVwiLCBkZWZpbml0aW9uKTtcblxuICAgIC8vIENvbW1vbkpTXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gZGVmaW5pdGlvbigpO1xuXG4gICAgLy8gUmVxdWlyZUpTXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICBkZWZpbmUoZGVmaW5pdGlvbik7XG5cbiAgICAvLyBTRVMgKFNlY3VyZSBFY21hU2NyaXB0KVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHNlcyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICBpZiAoIXNlcy5vaygpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZXMubWFrZVEgPSBkZWZpbml0aW9uO1xuICAgICAgICB9XG5cbiAgICAvLyA8c2NyaXB0PlxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiB8fCB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAvLyBQcmVmZXIgd2luZG93IG92ZXIgc2VsZiBmb3IgYWRkLW9uIHNjcmlwdHMuIFVzZSBzZWxmIGZvclxuICAgICAgICAvLyBub24td2luZG93ZWQgY29udGV4dHMuXG4gICAgICAgIHZhciBnbG9iYWwgPSB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDogc2VsZjtcblxuICAgICAgICAvLyBHZXQgdGhlIGB3aW5kb3dgIG9iamVjdCwgc2F2ZSB0aGUgcHJldmlvdXMgUSBnbG9iYWxcbiAgICAgICAgLy8gYW5kIGluaXRpYWxpemUgUSBhcyBhIGdsb2JhbC5cbiAgICAgICAgdmFyIHByZXZpb3VzUSA9IGdsb2JhbC5RO1xuICAgICAgICBnbG9iYWwuUSA9IGRlZmluaXRpb24oKTtcblxuICAgICAgICAvLyBBZGQgYSBub0NvbmZsaWN0IGZ1bmN0aW9uIHNvIFEgY2FuIGJlIHJlbW92ZWQgZnJvbSB0aGVcbiAgICAgICAgLy8gZ2xvYmFsIG5hbWVzcGFjZS5cbiAgICAgICAgZ2xvYmFsLlEubm9Db25mbGljdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGdsb2JhbC5RID0gcHJldmlvdXNRO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH07XG5cbiAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIGVudmlyb25tZW50IHdhcyBub3QgYW50aWNpcGF0ZWQgYnkgUS4gUGxlYXNlIGZpbGUgYSBidWcuXCIpO1xuICAgIH1cblxufSkoZnVuY3Rpb24gKCkge1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBoYXNTdGFja3MgPSBmYWxzZTtcbnRyeSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCk7XG59IGNhdGNoIChlKSB7XG4gICAgaGFzU3RhY2tzID0gISFlLnN0YWNrO1xufVxuXG4vLyBBbGwgY29kZSBhZnRlciB0aGlzIHBvaW50IHdpbGwgYmUgZmlsdGVyZWQgZnJvbSBzdGFjayB0cmFjZXMgcmVwb3J0ZWRcbi8vIGJ5IFEuXG52YXIgcVN0YXJ0aW5nTGluZSA9IGNhcHR1cmVMaW5lKCk7XG52YXIgcUZpbGVOYW1lO1xuXG4vLyBzaGltc1xuXG4vLyB1c2VkIGZvciBmYWxsYmFjayBpbiBcImFsbFJlc29sdmVkXCJcbnZhciBub29wID0gZnVuY3Rpb24gKCkge307XG5cbi8vIFVzZSB0aGUgZmFzdGVzdCBwb3NzaWJsZSBtZWFucyB0byBleGVjdXRlIGEgdGFzayBpbiBhIGZ1dHVyZSB0dXJuXG4vLyBvZiB0aGUgZXZlbnQgbG9vcC5cbnZhciBuZXh0VGljayA9KGZ1bmN0aW9uICgpIHtcbiAgICAvLyBsaW5rZWQgbGlzdCBvZiB0YXNrcyAoc2luZ2xlLCB3aXRoIGhlYWQgbm9kZSlcbiAgICB2YXIgaGVhZCA9IHt0YXNrOiB2b2lkIDAsIG5leHQ6IG51bGx9O1xuICAgIHZhciB0YWlsID0gaGVhZDtcbiAgICB2YXIgZmx1c2hpbmcgPSBmYWxzZTtcbiAgICB2YXIgcmVxdWVzdFRpY2sgPSB2b2lkIDA7XG4gICAgdmFyIGlzTm9kZUpTID0gZmFsc2U7XG4gICAgLy8gcXVldWUgZm9yIGxhdGUgdGFza3MsIHVzZWQgYnkgdW5oYW5kbGVkIHJlamVjdGlvbiB0cmFja2luZ1xuICAgIHZhciBsYXRlclF1ZXVlID0gW107XG5cbiAgICBmdW5jdGlvbiBmbHVzaCgpIHtcbiAgICAgICAgLyoganNoaW50IGxvb3BmdW5jOiB0cnVlICovXG4gICAgICAgIHZhciB0YXNrLCBkb21haW47XG5cbiAgICAgICAgd2hpbGUgKGhlYWQubmV4dCkge1xuICAgICAgICAgICAgaGVhZCA9IGhlYWQubmV4dDtcbiAgICAgICAgICAgIHRhc2sgPSBoZWFkLnRhc2s7XG4gICAgICAgICAgICBoZWFkLnRhc2sgPSB2b2lkIDA7XG4gICAgICAgICAgICBkb21haW4gPSBoZWFkLmRvbWFpbjtcblxuICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICAgIGhlYWQuZG9tYWluID0gdm9pZCAwO1xuICAgICAgICAgICAgICAgIGRvbWFpbi5lbnRlcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcnVuU2luZ2xlKHRhc2ssIGRvbWFpbik7XG5cbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAobGF0ZXJRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRhc2sgPSBsYXRlclF1ZXVlLnBvcCgpO1xuICAgICAgICAgICAgcnVuU2luZ2xlKHRhc2spO1xuICAgICAgICB9XG4gICAgICAgIGZsdXNoaW5nID0gZmFsc2U7XG4gICAgfVxuICAgIC8vIHJ1bnMgYSBzaW5nbGUgZnVuY3Rpb24gaW4gdGhlIGFzeW5jIHF1ZXVlXG4gICAgZnVuY3Rpb24gcnVuU2luZ2xlKHRhc2ssIGRvbWFpbikge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGFzaygpO1xuXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmIChpc05vZGVKUykge1xuICAgICAgICAgICAgICAgIC8vIEluIG5vZGUsIHVuY2F1Z2h0IGV4Y2VwdGlvbnMgYXJlIGNvbnNpZGVyZWQgZmF0YWwgZXJyb3JzLlxuICAgICAgICAgICAgICAgIC8vIFJlLXRocm93IHRoZW0gc3luY2hyb25vdXNseSB0byBpbnRlcnJ1cHQgZmx1c2hpbmchXG5cbiAgICAgICAgICAgICAgICAvLyBFbnN1cmUgY29udGludWF0aW9uIGlmIHRoZSB1bmNhdWdodCBleGNlcHRpb24gaXMgc3VwcHJlc3NlZFxuICAgICAgICAgICAgICAgIC8vIGxpc3RlbmluZyBcInVuY2F1Z2h0RXhjZXB0aW9uXCIgZXZlbnRzIChhcyBkb21haW5zIGRvZXMpLlxuICAgICAgICAgICAgICAgIC8vIENvbnRpbnVlIGluIG5leHQgZXZlbnQgdG8gYXZvaWQgdGljayByZWN1cnNpb24uXG4gICAgICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICAgICAgICBkb21haW4uZXhpdCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZsdXNoLCAwKTtcbiAgICAgICAgICAgICAgICBpZiAoZG9tYWluKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvbWFpbi5lbnRlcigpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IGU7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gSW4gYnJvd3NlcnMsIHVuY2F1Z2h0IGV4Y2VwdGlvbnMgYXJlIG5vdCBmYXRhbC5cbiAgICAgICAgICAgICAgICAvLyBSZS10aHJvdyB0aGVtIGFzeW5jaHJvbm91c2x5IHRvIGF2b2lkIHNsb3ctZG93bnMuXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZG9tYWluKSB7XG4gICAgICAgICAgICBkb21haW4uZXhpdCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmV4dFRpY2sgPSBmdW5jdGlvbiAodGFzaykge1xuICAgICAgICB0YWlsID0gdGFpbC5uZXh0ID0ge1xuICAgICAgICAgICAgdGFzazogdGFzayxcbiAgICAgICAgICAgIGRvbWFpbjogaXNOb2RlSlMgJiYgcHJvY2Vzcy5kb21haW4sXG4gICAgICAgICAgICBuZXh0OiBudWxsXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKCFmbHVzaGluZykge1xuICAgICAgICAgICAgZmx1c2hpbmcgPSB0cnVlO1xuICAgICAgICAgICAgcmVxdWVzdFRpY2soKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgcHJvY2Vzcy50b1N0cmluZygpID09PSBcIltvYmplY3QgcHJvY2Vzc11cIiAmJiBwcm9jZXNzLm5leHRUaWNrKSB7XG4gICAgICAgIC8vIEVuc3VyZSBRIGlzIGluIGEgcmVhbCBOb2RlIGVudmlyb25tZW50LCB3aXRoIGEgYHByb2Nlc3MubmV4dFRpY2tgLlxuICAgICAgICAvLyBUbyBzZWUgdGhyb3VnaCBmYWtlIE5vZGUgZW52aXJvbm1lbnRzOlxuICAgICAgICAvLyAqIE1vY2hhIHRlc3QgcnVubmVyIC0gZXhwb3NlcyBhIGBwcm9jZXNzYCBnbG9iYWwgd2l0aG91dCBhIGBuZXh0VGlja2BcbiAgICAgICAgLy8gKiBCcm93c2VyaWZ5IC0gZXhwb3NlcyBhIGBwcm9jZXNzLm5leFRpY2tgIGZ1bmN0aW9uIHRoYXQgdXNlc1xuICAgICAgICAvLyAgIGBzZXRUaW1lb3V0YC4gSW4gdGhpcyBjYXNlIGBzZXRJbW1lZGlhdGVgIGlzIHByZWZlcnJlZCBiZWNhdXNlXG4gICAgICAgIC8vICAgIGl0IGlzIGZhc3Rlci4gQnJvd3NlcmlmeSdzIGBwcm9jZXNzLnRvU3RyaW5nKClgIHlpZWxkc1xuICAgICAgICAvLyAgIFwiW29iamVjdCBPYmplY3RdXCIsIHdoaWxlIGluIGEgcmVhbCBOb2RlIGVudmlyb25tZW50XG4gICAgICAgIC8vICAgYHByb2Nlc3MudG9TdHJpbmcoKWAgeWllbGRzIFwiW29iamVjdCBwcm9jZXNzXVwiLlxuICAgICAgICBpc05vZGVKUyA9IHRydWU7XG5cbiAgICAgICAgcmVxdWVzdFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwcm9jZXNzLm5leHRUaWNrKGZsdXNoKTtcbiAgICAgICAgfTtcblxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHNldEltbWVkaWF0ZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIC8vIEluIElFMTAsIE5vZGUuanMgMC45Kywgb3IgaHR0cHM6Ly9naXRodWIuY29tL05vYmxlSlMvc2V0SW1tZWRpYXRlXG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICByZXF1ZXN0VGljayA9IHNldEltbWVkaWF0ZS5iaW5kKHdpbmRvdywgZmx1c2gpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVxdWVzdFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgc2V0SW1tZWRpYXRlKGZsdXNoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAodHlwZW9mIE1lc3NhZ2VDaGFubmVsICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIC8vIG1vZGVybiBicm93c2Vyc1xuICAgICAgICAvLyBodHRwOi8vd3d3Lm5vbmJsb2NraW5nLmlvLzIwMTEvMDYvd2luZG93bmV4dHRpY2suaHRtbFxuICAgICAgICB2YXIgY2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgICAgICAvLyBBdCBsZWFzdCBTYWZhcmkgVmVyc2lvbiA2LjAuNSAoODUzNi4zMC4xKSBpbnRlcm1pdHRlbnRseSBjYW5ub3QgY3JlYXRlXG4gICAgICAgIC8vIHdvcmtpbmcgbWVzc2FnZSBwb3J0cyB0aGUgZmlyc3QgdGltZSBhIHBhZ2UgbG9hZHMuXG4gICAgICAgIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmVxdWVzdFRpY2sgPSByZXF1ZXN0UG9ydFRpY2s7XG4gICAgICAgICAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGZsdXNoO1xuICAgICAgICAgICAgZmx1c2goKTtcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIHJlcXVlc3RQb3J0VGljayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIC8vIE9wZXJhIHJlcXVpcmVzIHVzIHRvIHByb3ZpZGUgYSBtZXNzYWdlIHBheWxvYWQsIHJlZ2FyZGxlc3Mgb2ZcbiAgICAgICAgICAgIC8vIHdoZXRoZXIgd2UgdXNlIGl0LlxuICAgICAgICAgICAgY2hhbm5lbC5wb3J0Mi5wb3N0TWVzc2FnZSgwKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmVxdWVzdFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZsdXNoLCAwKTtcbiAgICAgICAgICAgIHJlcXVlc3RQb3J0VGljaygpO1xuICAgICAgICB9O1xuXG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gb2xkIGJyb3dzZXJzXG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIC8vIHJ1bnMgYSB0YXNrIGFmdGVyIGFsbCBvdGhlciB0YXNrcyBoYXZlIGJlZW4gcnVuXG4gICAgLy8gdGhpcyBpcyB1c2VmdWwgZm9yIHVuaGFuZGxlZCByZWplY3Rpb24gdHJhY2tpbmcgdGhhdCBuZWVkcyB0byBoYXBwZW5cbiAgICAvLyBhZnRlciBhbGwgYHRoZW5gZCB0YXNrcyBoYXZlIGJlZW4gcnVuLlxuICAgIG5leHRUaWNrLnJ1bkFmdGVyID0gZnVuY3Rpb24gKHRhc2spIHtcbiAgICAgICAgbGF0ZXJRdWV1ZS5wdXNoKHRhc2spO1xuICAgICAgICBpZiAoIWZsdXNoaW5nKSB7XG4gICAgICAgICAgICBmbHVzaGluZyA9IHRydWU7XG4gICAgICAgICAgICByZXF1ZXN0VGljaygpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gbmV4dFRpY2s7XG59KSgpO1xuXG4vLyBBdHRlbXB0IHRvIG1ha2UgZ2VuZXJpY3Mgc2FmZSBpbiB0aGUgZmFjZSBvZiBkb3duc3RyZWFtXG4vLyBtb2RpZmljYXRpb25zLlxuLy8gVGhlcmUgaXMgbm8gc2l0dWF0aW9uIHdoZXJlIHRoaXMgaXMgbmVjZXNzYXJ5LlxuLy8gSWYgeW91IG5lZWQgYSBzZWN1cml0eSBndWFyYW50ZWUsIHRoZXNlIHByaW1vcmRpYWxzIG5lZWQgdG8gYmVcbi8vIGRlZXBseSBmcm96ZW4gYW55d2F5LCBhbmQgaWYgeW91IGRvbuKAmXQgbmVlZCBhIHNlY3VyaXR5IGd1YXJhbnRlZSxcbi8vIHRoaXMgaXMganVzdCBwbGFpbiBwYXJhbm9pZC5cbi8vIEhvd2V2ZXIsIHRoaXMgKiptaWdodCoqIGhhdmUgdGhlIG5pY2Ugc2lkZS1lZmZlY3Qgb2YgcmVkdWNpbmcgdGhlIHNpemUgb2Zcbi8vIHRoZSBtaW5pZmllZCBjb2RlIGJ5IHJlZHVjaW5nIHguY2FsbCgpIHRvIG1lcmVseSB4KClcbi8vIFNlZSBNYXJrIE1pbGxlcuKAmXMgZXhwbGFuYXRpb24gb2Ygd2hhdCB0aGlzIGRvZXMuXG4vLyBodHRwOi8vd2lraS5lY21hc2NyaXB0Lm9yZy9kb2t1LnBocD9pZD1jb252ZW50aW9uczpzYWZlX21ldGFfcHJvZ3JhbW1pbmdcbnZhciBjYWxsID0gRnVuY3Rpb24uY2FsbDtcbmZ1bmN0aW9uIHVuY3VycnlUaGlzKGYpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gY2FsbC5hcHBseShmLCBhcmd1bWVudHMpO1xuICAgIH07XG59XG4vLyBUaGlzIGlzIGVxdWl2YWxlbnQsIGJ1dCBzbG93ZXI6XG4vLyB1bmN1cnJ5VGhpcyA9IEZ1bmN0aW9uX2JpbmQuYmluZChGdW5jdGlvbl9iaW5kLmNhbGwpO1xuLy8gaHR0cDovL2pzcGVyZi5jb20vdW5jdXJyeXRoaXNcblxudmFyIGFycmF5X3NsaWNlID0gdW5jdXJyeVRoaXMoQXJyYXkucHJvdG90eXBlLnNsaWNlKTtcblxudmFyIGFycmF5X3JlZHVjZSA9IHVuY3VycnlUaGlzKFxuICAgIEFycmF5LnByb3RvdHlwZS5yZWR1Y2UgfHwgZnVuY3Rpb24gKGNhbGxiYWNrLCBiYXNpcykge1xuICAgICAgICB2YXIgaW5kZXggPSAwLFxuICAgICAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGg7XG4gICAgICAgIC8vIGNvbmNlcm5pbmcgdGhlIGluaXRpYWwgdmFsdWUsIGlmIG9uZSBpcyBub3QgcHJvdmlkZWRcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIC8vIHNlZWsgdG8gdGhlIGZpcnN0IHZhbHVlIGluIHRoZSBhcnJheSwgYWNjb3VudGluZ1xuICAgICAgICAgICAgLy8gZm9yIHRoZSBwb3NzaWJpbGl0eSB0aGF0IGlzIGlzIGEgc3BhcnNlIGFycmF5XG4gICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgaWYgKGluZGV4IGluIHRoaXMpIHtcbiAgICAgICAgICAgICAgICAgICAgYmFzaXMgPSB0aGlzW2luZGV4KytdO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCsraW5kZXggPj0gbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IHdoaWxlICgxKTtcbiAgICAgICAgfVxuICAgICAgICAvLyByZWR1Y2VcbiAgICAgICAgZm9yICg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICAvLyBhY2NvdW50IGZvciB0aGUgcG9zc2liaWxpdHkgdGhhdCB0aGUgYXJyYXkgaXMgc3BhcnNlXG4gICAgICAgICAgICBpZiAoaW5kZXggaW4gdGhpcykge1xuICAgICAgICAgICAgICAgIGJhc2lzID0gY2FsbGJhY2soYmFzaXMsIHRoaXNbaW5kZXhdLCBpbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJhc2lzO1xuICAgIH1cbik7XG5cbnZhciBhcnJheV9pbmRleE9mID0gdW5jdXJyeVRoaXMoXG4gICAgQXJyYXkucHJvdG90eXBlLmluZGV4T2YgfHwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIC8vIG5vdCBhIHZlcnkgZ29vZCBzaGltLCBidXQgZ29vZCBlbm91Z2ggZm9yIG91ciBvbmUgdXNlIG9mIGl0XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKHRoaXNbaV0gPT09IHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cbik7XG5cbnZhciBhcnJheV9tYXAgPSB1bmN1cnJ5VGhpcyhcbiAgICBBcnJheS5wcm90b3R5cGUubWFwIHx8IGZ1bmN0aW9uIChjYWxsYmFjaywgdGhpc3ApIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICB2YXIgY29sbGVjdCA9IFtdO1xuICAgICAgICBhcnJheV9yZWR1Y2Uoc2VsZiwgZnVuY3Rpb24gKHVuZGVmaW5lZCwgdmFsdWUsIGluZGV4KSB7XG4gICAgICAgICAgICBjb2xsZWN0LnB1c2goY2FsbGJhY2suY2FsbCh0aGlzcCwgdmFsdWUsIGluZGV4LCBzZWxmKSk7XG4gICAgICAgIH0sIHZvaWQgMCk7XG4gICAgICAgIHJldHVybiBjb2xsZWN0O1xuICAgIH1cbik7XG5cbnZhciBvYmplY3RfY3JlYXRlID0gT2JqZWN0LmNyZWF0ZSB8fCBmdW5jdGlvbiAocHJvdG90eXBlKSB7XG4gICAgZnVuY3Rpb24gVHlwZSgpIHsgfVxuICAgIFR5cGUucHJvdG90eXBlID0gcHJvdG90eXBlO1xuICAgIHJldHVybiBuZXcgVHlwZSgpO1xufTtcblxudmFyIG9iamVjdF9kZWZpbmVQcm9wZXJ0eSA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSB8fCBmdW5jdGlvbiAob2JqLCBwcm9wLCBkZXNjcmlwdG9yKSB7XG4gICAgb2JqW3Byb3BdID0gZGVzY3JpcHRvci52YWx1ZTtcbiAgICByZXR1cm4gb2JqO1xufTtcblxudmFyIG9iamVjdF9oYXNPd25Qcm9wZXJ0eSA9IHVuY3VycnlUaGlzKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkpO1xuXG52YXIgb2JqZWN0X2tleXMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgdmFyIGtleXMgPSBbXTtcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqZWN0KSB7XG4gICAgICAgIGlmIChvYmplY3RfaGFzT3duUHJvcGVydHkob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgICAgICBrZXlzLnB1c2goa2V5KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ga2V5cztcbn07XG5cbnZhciBvYmplY3RfdG9TdHJpbmcgPSB1bmN1cnJ5VGhpcyhPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nKTtcblxuZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgPT09IE9iamVjdCh2YWx1ZSk7XG59XG5cbi8vIGdlbmVyYXRvciByZWxhdGVkIHNoaW1zXG5cbi8vIEZJWE1FOiBSZW1vdmUgdGhpcyBmdW5jdGlvbiBvbmNlIEVTNiBnZW5lcmF0b3JzIGFyZSBpbiBTcGlkZXJNb25rZXkuXG5mdW5jdGlvbiBpc1N0b3BJdGVyYXRpb24oZXhjZXB0aW9uKSB7XG4gICAgcmV0dXJuIChcbiAgICAgICAgb2JqZWN0X3RvU3RyaW5nKGV4Y2VwdGlvbikgPT09IFwiW29iamVjdCBTdG9wSXRlcmF0aW9uXVwiIHx8XG4gICAgICAgIGV4Y2VwdGlvbiBpbnN0YW5jZW9mIFFSZXR1cm5WYWx1ZVxuICAgICk7XG59XG5cbi8vIEZJWE1FOiBSZW1vdmUgdGhpcyBoZWxwZXIgYW5kIFEucmV0dXJuIG9uY2UgRVM2IGdlbmVyYXRvcnMgYXJlIGluXG4vLyBTcGlkZXJNb25rZXkuXG52YXIgUVJldHVyblZhbHVlO1xuaWYgKHR5cGVvZiBSZXR1cm5WYWx1ZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIFFSZXR1cm5WYWx1ZSA9IFJldHVyblZhbHVlO1xufSBlbHNlIHtcbiAgICBRUmV0dXJuVmFsdWUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIH07XG59XG5cbi8vIGxvbmcgc3RhY2sgdHJhY2VzXG5cbnZhciBTVEFDS19KVU1QX1NFUEFSQVRPUiA9IFwiRnJvbSBwcmV2aW91cyBldmVudDpcIjtcblxuZnVuY3Rpb24gbWFrZVN0YWNrVHJhY2VMb25nKGVycm9yLCBwcm9taXNlKSB7XG4gICAgLy8gSWYgcG9zc2libGUsIHRyYW5zZm9ybSB0aGUgZXJyb3Igc3RhY2sgdHJhY2UgYnkgcmVtb3ZpbmcgTm9kZSBhbmQgUVxuICAgIC8vIGNydWZ0LCB0aGVuIGNvbmNhdGVuYXRpbmcgd2l0aCB0aGUgc3RhY2sgdHJhY2Ugb2YgYHByb21pc2VgLiBTZWUgIzU3LlxuICAgIGlmIChoYXNTdGFja3MgJiZcbiAgICAgICAgcHJvbWlzZS5zdGFjayAmJlxuICAgICAgICB0eXBlb2YgZXJyb3IgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgZXJyb3IgIT09IG51bGwgJiZcbiAgICAgICAgZXJyb3Iuc3RhY2tcbiAgICApIHtcbiAgICAgICAgdmFyIHN0YWNrcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBwID0gcHJvbWlzZTsgISFwOyBwID0gcC5zb3VyY2UpIHtcbiAgICAgICAgICAgIGlmIChwLnN0YWNrICYmICghZXJyb3IuX19taW5pbXVtU3RhY2tDb3VudGVyX18gfHwgZXJyb3IuX19taW5pbXVtU3RhY2tDb3VudGVyX18gPiBwLnN0YWNrQ291bnRlcikpIHtcbiAgICAgICAgICAgICAgICBvYmplY3RfZGVmaW5lUHJvcGVydHkoZXJyb3IsIFwiX19taW5pbXVtU3RhY2tDb3VudGVyX19cIiwge3ZhbHVlOiBwLnN0YWNrQ291bnRlciwgY29uZmlndXJhYmxlOiB0cnVlfSk7XG4gICAgICAgICAgICAgICAgc3RhY2tzLnVuc2hpZnQocC5zdGFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3RhY2tzLnVuc2hpZnQoZXJyb3Iuc3RhY2spO1xuXG4gICAgICAgIHZhciBjb25jYXRlZFN0YWNrcyA9IHN0YWNrcy5qb2luKFwiXFxuXCIgKyBTVEFDS19KVU1QX1NFUEFSQVRPUiArIFwiXFxuXCIpO1xuICAgICAgICB2YXIgc3RhY2sgPSBmaWx0ZXJTdGFja1N0cmluZyhjb25jYXRlZFN0YWNrcyk7XG4gICAgICAgIG9iamVjdF9kZWZpbmVQcm9wZXJ0eShlcnJvciwgXCJzdGFja1wiLCB7dmFsdWU6IHN0YWNrLCBjb25maWd1cmFibGU6IHRydWV9KTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGZpbHRlclN0YWNrU3RyaW5nKHN0YWNrU3RyaW5nKSB7XG4gICAgdmFyIGxpbmVzID0gc3RhY2tTdHJpbmcuc3BsaXQoXCJcXG5cIik7XG4gICAgdmFyIGRlc2lyZWRMaW5lcyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIGxpbmUgPSBsaW5lc1tpXTtcblxuICAgICAgICBpZiAoIWlzSW50ZXJuYWxGcmFtZShsaW5lKSAmJiAhaXNOb2RlRnJhbWUobGluZSkgJiYgbGluZSkge1xuICAgICAgICAgICAgZGVzaXJlZExpbmVzLnB1c2gobGluZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRlc2lyZWRMaW5lcy5qb2luKFwiXFxuXCIpO1xufVxuXG5mdW5jdGlvbiBpc05vZGVGcmFtZShzdGFja0xpbmUpIHtcbiAgICByZXR1cm4gc3RhY2tMaW5lLmluZGV4T2YoXCIobW9kdWxlLmpzOlwiKSAhPT0gLTEgfHxcbiAgICAgICAgICAgc3RhY2tMaW5lLmluZGV4T2YoXCIobm9kZS5qczpcIikgIT09IC0xO1xufVxuXG5mdW5jdGlvbiBnZXRGaWxlTmFtZUFuZExpbmVOdW1iZXIoc3RhY2tMaW5lKSB7XG4gICAgLy8gTmFtZWQgZnVuY3Rpb25zOiBcImF0IGZ1bmN0aW9uTmFtZSAoZmlsZW5hbWU6bGluZU51bWJlcjpjb2x1bW5OdW1iZXIpXCJcbiAgICAvLyBJbiBJRTEwIGZ1bmN0aW9uIG5hbWUgY2FuIGhhdmUgc3BhY2VzIChcIkFub255bW91cyBmdW5jdGlvblwiKSBPX29cbiAgICB2YXIgYXR0ZW1wdDEgPSAvYXQgLisgXFwoKC4rKTooXFxkKyk6KD86XFxkKylcXCkkLy5leGVjKHN0YWNrTGluZSk7XG4gICAgaWYgKGF0dGVtcHQxKSB7XG4gICAgICAgIHJldHVybiBbYXR0ZW1wdDFbMV0sIE51bWJlcihhdHRlbXB0MVsyXSldO1xuICAgIH1cblxuICAgIC8vIEFub255bW91cyBmdW5jdGlvbnM6IFwiYXQgZmlsZW5hbWU6bGluZU51bWJlcjpjb2x1bW5OdW1iZXJcIlxuICAgIHZhciBhdHRlbXB0MiA9IC9hdCAoW14gXSspOihcXGQrKTooPzpcXGQrKSQvLmV4ZWMoc3RhY2tMaW5lKTtcbiAgICBpZiAoYXR0ZW1wdDIpIHtcbiAgICAgICAgcmV0dXJuIFthdHRlbXB0MlsxXSwgTnVtYmVyKGF0dGVtcHQyWzJdKV07XG4gICAgfVxuXG4gICAgLy8gRmlyZWZveCBzdHlsZTogXCJmdW5jdGlvbkBmaWxlbmFtZTpsaW5lTnVtYmVyIG9yIEBmaWxlbmFtZTpsaW5lTnVtYmVyXCJcbiAgICB2YXIgYXR0ZW1wdDMgPSAvLipAKC4rKTooXFxkKykkLy5leGVjKHN0YWNrTGluZSk7XG4gICAgaWYgKGF0dGVtcHQzKSB7XG4gICAgICAgIHJldHVybiBbYXR0ZW1wdDNbMV0sIE51bWJlcihhdHRlbXB0M1syXSldO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gaXNJbnRlcm5hbEZyYW1lKHN0YWNrTGluZSkge1xuICAgIHZhciBmaWxlTmFtZUFuZExpbmVOdW1iZXIgPSBnZXRGaWxlTmFtZUFuZExpbmVOdW1iZXIoc3RhY2tMaW5lKTtcblxuICAgIGlmICghZmlsZU5hbWVBbmRMaW5lTnVtYmVyKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB2YXIgZmlsZU5hbWUgPSBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMF07XG4gICAgdmFyIGxpbmVOdW1iZXIgPSBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMV07XG5cbiAgICByZXR1cm4gZmlsZU5hbWUgPT09IHFGaWxlTmFtZSAmJlxuICAgICAgICBsaW5lTnVtYmVyID49IHFTdGFydGluZ0xpbmUgJiZcbiAgICAgICAgbGluZU51bWJlciA8PSBxRW5kaW5nTGluZTtcbn1cblxuLy8gZGlzY292ZXIgb3duIGZpbGUgbmFtZSBhbmQgbGluZSBudW1iZXIgcmFuZ2UgZm9yIGZpbHRlcmluZyBzdGFja1xuLy8gdHJhY2VzXG5mdW5jdGlvbiBjYXB0dXJlTGluZSgpIHtcbiAgICBpZiAoIWhhc1N0YWNrcykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB2YXIgbGluZXMgPSBlLnN0YWNrLnNwbGl0KFwiXFxuXCIpO1xuICAgICAgICB2YXIgZmlyc3RMaW5lID0gbGluZXNbMF0uaW5kZXhPZihcIkBcIikgPiAwID8gbGluZXNbMV0gOiBsaW5lc1syXTtcbiAgICAgICAgdmFyIGZpbGVOYW1lQW5kTGluZU51bWJlciA9IGdldEZpbGVOYW1lQW5kTGluZU51bWJlcihmaXJzdExpbmUpO1xuICAgICAgICBpZiAoIWZpbGVOYW1lQW5kTGluZU51bWJlcikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgcUZpbGVOYW1lID0gZmlsZU5hbWVBbmRMaW5lTnVtYmVyWzBdO1xuICAgICAgICByZXR1cm4gZmlsZU5hbWVBbmRMaW5lTnVtYmVyWzFdO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZGVwcmVjYXRlKGNhbGxiYWNrLCBuYW1lLCBhbHRlcm5hdGl2ZSkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY29uc29sZSAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgdHlwZW9mIGNvbnNvbGUud2FybiA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4obmFtZSArIFwiIGlzIGRlcHJlY2F0ZWQsIHVzZSBcIiArIGFsdGVybmF0aXZlICtcbiAgICAgICAgICAgICAgICAgICAgICAgICBcIiBpbnN0ZWFkLlwiLCBuZXcgRXJyb3IoXCJcIikuc3RhY2spO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYWxsYmFjay5hcHBseShjYWxsYmFjaywgYXJndW1lbnRzKTtcbiAgICB9O1xufVxuXG4vLyBlbmQgb2Ygc2hpbXNcbi8vIGJlZ2lubmluZyBvZiByZWFsIHdvcmtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgcHJvbWlzZSBmb3IgYW4gaW1tZWRpYXRlIHJlZmVyZW5jZSwgcGFzc2VzIHByb21pc2VzIHRocm91Z2gsIG9yXG4gKiBjb2VyY2VzIHByb21pc2VzIGZyb20gZGlmZmVyZW50IHN5c3RlbXMuXG4gKiBAcGFyYW0gdmFsdWUgaW1tZWRpYXRlIHJlZmVyZW5jZSBvciBwcm9taXNlXG4gKi9cbmZ1bmN0aW9uIFEodmFsdWUpIHtcbiAgICAvLyBJZiB0aGUgb2JqZWN0IGlzIGFscmVhZHkgYSBQcm9taXNlLCByZXR1cm4gaXQgZGlyZWN0bHkuICBUaGlzIGVuYWJsZXNcbiAgICAvLyB0aGUgcmVzb2x2ZSBmdW5jdGlvbiB0byBib3RoIGJlIHVzZWQgdG8gY3JlYXRlZCByZWZlcmVuY2VzIGZyb20gb2JqZWN0cyxcbiAgICAvLyBidXQgdG8gdG9sZXJhYmx5IGNvZXJjZSBub24tcHJvbWlzZXMgdG8gcHJvbWlzZXMuXG4gICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgLy8gYXNzaW1pbGF0ZSB0aGVuYWJsZXNcbiAgICBpZiAoaXNQcm9taXNlQWxpa2UodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBjb2VyY2UodmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmdWxmaWxsKHZhbHVlKTtcbiAgICB9XG59XG5RLnJlc29sdmUgPSBRO1xuXG4vKipcbiAqIFBlcmZvcm1zIGEgdGFzayBpbiBhIGZ1dHVyZSB0dXJuIG9mIHRoZSBldmVudCBsb29wLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gdGFza1xuICovXG5RLm5leHRUaWNrID0gbmV4dFRpY2s7XG5cbi8qKlxuICogQ29udHJvbHMgd2hldGhlciBvciBub3QgbG9uZyBzdGFjayB0cmFjZXMgd2lsbCBiZSBvblxuICovXG5RLmxvbmdTdGFja1N1cHBvcnQgPSBmYWxzZTtcblxuLyoqXG4gKiBUaGUgY291bnRlciBpcyB1c2VkIHRvIGRldGVybWluZSB0aGUgc3RvcHBpbmcgcG9pbnQgZm9yIGJ1aWxkaW5nXG4gKiBsb25nIHN0YWNrIHRyYWNlcy4gSW4gbWFrZVN0YWNrVHJhY2VMb25nIHdlIHdhbGsgYmFja3dhcmRzIHRocm91Z2hcbiAqIHRoZSBsaW5rZWQgbGlzdCBvZiBwcm9taXNlcywgb25seSBzdGFja3Mgd2hpY2ggd2VyZSBjcmVhdGVkIGJlZm9yZVxuICogdGhlIHJlamVjdGlvbiBhcmUgY29uY2F0ZW5hdGVkLlxuICovXG52YXIgbG9uZ1N0YWNrQ291bnRlciA9IDE7XG5cbi8vIGVuYWJsZSBsb25nIHN0YWNrcyBpZiBRX0RFQlVHIGlzIHNldFxuaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHByb2Nlc3MgJiYgcHJvY2Vzcy5lbnYgJiYgcHJvY2Vzcy5lbnYuUV9ERUJVRykge1xuICAgIFEubG9uZ1N0YWNrU3VwcG9ydCA9IHRydWU7XG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIHtwcm9taXNlLCByZXNvbHZlLCByZWplY3R9IG9iamVjdC5cbiAqXG4gKiBgcmVzb2x2ZWAgaXMgYSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBhIG1vcmUgcmVzb2x2ZWQgdmFsdWUgZm9yIHRoZVxuICogcHJvbWlzZS4gVG8gZnVsZmlsbCB0aGUgcHJvbWlzZSwgaW52b2tlIGByZXNvbHZlYCB3aXRoIGFueSB2YWx1ZSB0aGF0IGlzXG4gKiBub3QgYSB0aGVuYWJsZS4gVG8gcmVqZWN0IHRoZSBwcm9taXNlLCBpbnZva2UgYHJlc29sdmVgIHdpdGggYSByZWplY3RlZFxuICogdGhlbmFibGUsIG9yIGludm9rZSBgcmVqZWN0YCB3aXRoIHRoZSByZWFzb24gZGlyZWN0bHkuIFRvIHJlc29sdmUgdGhlXG4gKiBwcm9taXNlIHRvIGFub3RoZXIgdGhlbmFibGUsIHRodXMgcHV0dGluZyBpdCBpbiB0aGUgc2FtZSBzdGF0ZSwgaW52b2tlXG4gKiBgcmVzb2x2ZWAgd2l0aCB0aGF0IG90aGVyIHRoZW5hYmxlLlxuICovXG5RLmRlZmVyID0gZGVmZXI7XG5mdW5jdGlvbiBkZWZlcigpIHtcbiAgICAvLyBpZiBcIm1lc3NhZ2VzXCIgaXMgYW4gXCJBcnJheVwiLCB0aGF0IGluZGljYXRlcyB0aGF0IHRoZSBwcm9taXNlIGhhcyBub3QgeWV0XG4gICAgLy8gYmVlbiByZXNvbHZlZC4gIElmIGl0IGlzIFwidW5kZWZpbmVkXCIsIGl0IGhhcyBiZWVuIHJlc29sdmVkLiAgRWFjaFxuICAgIC8vIGVsZW1lbnQgb2YgdGhlIG1lc3NhZ2VzIGFycmF5IGlzIGl0c2VsZiBhbiBhcnJheSBvZiBjb21wbGV0ZSBhcmd1bWVudHMgdG9cbiAgICAvLyBmb3J3YXJkIHRvIHRoZSByZXNvbHZlZCBwcm9taXNlLiAgV2UgY29lcmNlIHRoZSByZXNvbHV0aW9uIHZhbHVlIHRvIGFcbiAgICAvLyBwcm9taXNlIHVzaW5nIHRoZSBgcmVzb2x2ZWAgZnVuY3Rpb24gYmVjYXVzZSBpdCBoYW5kbGVzIGJvdGggZnVsbHlcbiAgICAvLyBub24tdGhlbmFibGUgdmFsdWVzIGFuZCBvdGhlciB0aGVuYWJsZXMgZ3JhY2VmdWxseS5cbiAgICB2YXIgbWVzc2FnZXMgPSBbXSwgcHJvZ3Jlc3NMaXN0ZW5lcnMgPSBbXSwgcmVzb2x2ZWRQcm9taXNlO1xuXG4gICAgdmFyIGRlZmVycmVkID0gb2JqZWN0X2NyZWF0ZShkZWZlci5wcm90b3R5cGUpO1xuICAgIHZhciBwcm9taXNlID0gb2JqZWN0X2NyZWF0ZShQcm9taXNlLnByb3RvdHlwZSk7XG5cbiAgICBwcm9taXNlLnByb21pc2VEaXNwYXRjaCA9IGZ1bmN0aW9uIChyZXNvbHZlLCBvcCwgb3BlcmFuZHMpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMpO1xuICAgICAgICBpZiAobWVzc2FnZXMpIHtcbiAgICAgICAgICAgIG1lc3NhZ2VzLnB1c2goYXJncyk7XG4gICAgICAgICAgICBpZiAob3AgPT09IFwid2hlblwiICYmIG9wZXJhbmRzWzFdKSB7IC8vIHByb2dyZXNzIG9wZXJhbmRcbiAgICAgICAgICAgICAgICBwcm9ncmVzc0xpc3RlbmVycy5wdXNoKG9wZXJhbmRzWzFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJlc29sdmVkUHJvbWlzZS5wcm9taXNlRGlzcGF0Y2guYXBwbHkocmVzb2x2ZWRQcm9taXNlLCBhcmdzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8vIFhYWCBkZXByZWNhdGVkXG4gICAgcHJvbWlzZS52YWx1ZU9mID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAobWVzc2FnZXMpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBuZWFyZXJWYWx1ZSA9IG5lYXJlcihyZXNvbHZlZFByb21pc2UpO1xuICAgICAgICBpZiAoaXNQcm9taXNlKG5lYXJlclZhbHVlKSkge1xuICAgICAgICAgICAgcmVzb2x2ZWRQcm9taXNlID0gbmVhcmVyVmFsdWU7IC8vIHNob3J0ZW4gY2hhaW5cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmVhcmVyVmFsdWU7XG4gICAgfTtcblxuICAgIHByb21pc2UuaW5zcGVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCFyZXNvbHZlZFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybiB7IHN0YXRlOiBcInBlbmRpbmdcIiB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXNvbHZlZFByb21pc2UuaW5zcGVjdCgpO1xuICAgIH07XG5cbiAgICBpZiAoUS5sb25nU3RhY2tTdXBwb3J0ICYmIGhhc1N0YWNrcykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIC8vIE5PVEU6IGRvbid0IHRyeSB0byB1c2UgYEVycm9yLmNhcHR1cmVTdGFja1RyYWNlYCBvciB0cmFuc2ZlciB0aGVcbiAgICAgICAgICAgIC8vIGFjY2Vzc29yIGFyb3VuZDsgdGhhdCBjYXVzZXMgbWVtb3J5IGxlYWtzIGFzIHBlciBHSC0xMTEuIEp1c3RcbiAgICAgICAgICAgIC8vIHJlaWZ5IHRoZSBzdGFjayB0cmFjZSBhcyBhIHN0cmluZyBBU0FQLlxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIEF0IHRoZSBzYW1lIHRpbWUsIGN1dCBvZmYgdGhlIGZpcnN0IGxpbmU7IGl0J3MgYWx3YXlzIGp1c3RcbiAgICAgICAgICAgIC8vIFwiW29iamVjdCBQcm9taXNlXVxcblwiLCBhcyBwZXIgdGhlIGB0b1N0cmluZ2AuXG4gICAgICAgICAgICBwcm9taXNlLnN0YWNrID0gZS5zdGFjay5zdWJzdHJpbmcoZS5zdGFjay5pbmRleE9mKFwiXFxuXCIpICsgMSk7XG4gICAgICAgICAgICBwcm9taXNlLnN0YWNrQ291bnRlciA9IGxvbmdTdGFja0NvdW50ZXIrKztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIE5PVEU6IHdlIGRvIHRoZSBjaGVja3MgZm9yIGByZXNvbHZlZFByb21pc2VgIGluIGVhY2ggbWV0aG9kLCBpbnN0ZWFkIG9mXG4gICAgLy8gY29uc29saWRhdGluZyB0aGVtIGludG8gYGJlY29tZWAsIHNpbmNlIG90aGVyd2lzZSB3ZSdkIGNyZWF0ZSBuZXdcbiAgICAvLyBwcm9taXNlcyB3aXRoIHRoZSBsaW5lcyBgYmVjb21lKHdoYXRldmVyKHZhbHVlKSlgLiBTZWUgZS5nLiBHSC0yNTIuXG5cbiAgICBmdW5jdGlvbiBiZWNvbWUobmV3UHJvbWlzZSkge1xuICAgICAgICByZXNvbHZlZFByb21pc2UgPSBuZXdQcm9taXNlO1xuXG4gICAgICAgIGlmIChRLmxvbmdTdGFja1N1cHBvcnQgJiYgaGFzU3RhY2tzKSB7XG4gICAgICAgICAgICAvLyBPbmx5IGhvbGQgYSByZWZlcmVuY2UgdG8gdGhlIG5ldyBwcm9taXNlIGlmIGxvbmcgc3RhY2tzXG4gICAgICAgICAgICAvLyBhcmUgZW5hYmxlZCB0byByZWR1Y2UgbWVtb3J5IHVzYWdlXG4gICAgICAgICAgICBwcm9taXNlLnNvdXJjZSA9IG5ld1Byb21pc2U7XG4gICAgICAgIH1cblxuICAgICAgICBhcnJheV9yZWR1Y2UobWVzc2FnZXMsIGZ1bmN0aW9uICh1bmRlZmluZWQsIG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5ld1Byb21pc2UucHJvbWlzZURpc3BhdGNoLmFwcGx5KG5ld1Byb21pc2UsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIHZvaWQgMCk7XG5cbiAgICAgICAgbWVzc2FnZXMgPSB2b2lkIDA7XG4gICAgICAgIHByb2dyZXNzTGlzdGVuZXJzID0gdm9pZCAwO1xuICAgIH1cblxuICAgIGRlZmVycmVkLnByb21pc2UgPSBwcm9taXNlO1xuICAgIGRlZmVycmVkLnJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgaWYgKHJlc29sdmVkUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYmVjb21lKFEodmFsdWUpKTtcbiAgICB9O1xuXG4gICAgZGVmZXJyZWQuZnVsZmlsbCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUoZnVsZmlsbCh2YWx1ZSkpO1xuICAgIH07XG4gICAgZGVmZXJyZWQucmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUocmVqZWN0KHJlYXNvbikpO1xuICAgIH07XG4gICAgZGVmZXJyZWQubm90aWZ5ID0gZnVuY3Rpb24gKHByb2dyZXNzKSB7XG4gICAgICAgIGlmIChyZXNvbHZlZFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGFycmF5X3JlZHVjZShwcm9ncmVzc0xpc3RlbmVycywgZnVuY3Rpb24gKHVuZGVmaW5lZCwgcHJvZ3Jlc3NMaXN0ZW5lcikge1xuICAgICAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcihwcm9ncmVzcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgdm9pZCAwKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIGRlZmVycmVkO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBOb2RlLXN0eWxlIGNhbGxiYWNrIHRoYXQgd2lsbCByZXNvbHZlIG9yIHJlamVjdCB0aGUgZGVmZXJyZWRcbiAqIHByb21pc2UuXG4gKiBAcmV0dXJucyBhIG5vZGViYWNrXG4gKi9cbmRlZmVyLnByb3RvdHlwZS5tYWtlTm9kZVJlc29sdmVyID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICByZXR1cm4gZnVuY3Rpb24gKGVycm9yLCB2YWx1ZSkge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHNlbGYucmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMikge1xuICAgICAgICAgICAgc2VsZi5yZXNvbHZlKGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZi5yZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuXG4vKipcbiAqIEBwYXJhbSByZXNvbHZlciB7RnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIG5vdGhpbmcgYW5kIGFjY2VwdHNcbiAqIHRoZSByZXNvbHZlLCByZWplY3QsIGFuZCBub3RpZnkgZnVuY3Rpb25zIGZvciBhIGRlZmVycmVkLlxuICogQHJldHVybnMgYSBwcm9taXNlIHRoYXQgbWF5IGJlIHJlc29sdmVkIHdpdGggdGhlIGdpdmVuIHJlc29sdmUgYW5kIHJlamVjdFxuICogZnVuY3Rpb25zLCBvciByZWplY3RlZCBieSBhIHRocm93biBleGNlcHRpb24gaW4gcmVzb2x2ZXJcbiAqL1xuUS5Qcm9taXNlID0gcHJvbWlzZTsgLy8gRVM2XG5RLnByb21pc2UgPSBwcm9taXNlO1xuZnVuY3Rpb24gcHJvbWlzZShyZXNvbHZlcikge1xuICAgIGlmICh0eXBlb2YgcmVzb2x2ZXIgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwicmVzb2x2ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uLlwiKTtcbiAgICB9XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB0cnkge1xuICAgICAgICByZXNvbHZlcihkZWZlcnJlZC5yZXNvbHZlLCBkZWZlcnJlZC5yZWplY3QsIGRlZmVycmVkLm5vdGlmeSk7XG4gICAgfSBjYXRjaCAocmVhc29uKSB7XG4gICAgICAgIGRlZmVycmVkLnJlamVjdChyZWFzb24pO1xuICAgIH1cbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn1cblxucHJvbWlzZS5yYWNlID0gcmFjZTsgLy8gRVM2XG5wcm9taXNlLmFsbCA9IGFsbDsgLy8gRVM2XG5wcm9taXNlLnJlamVjdCA9IHJlamVjdDsgLy8gRVM2XG5wcm9taXNlLnJlc29sdmUgPSBROyAvLyBFUzZcblxuLy8gWFhYIGV4cGVyaW1lbnRhbC4gIFRoaXMgbWV0aG9kIGlzIGEgd2F5IHRvIGRlbm90ZSB0aGF0IGEgbG9jYWwgdmFsdWUgaXNcbi8vIHNlcmlhbGl6YWJsZSBhbmQgc2hvdWxkIGJlIGltbWVkaWF0ZWx5IGRpc3BhdGNoZWQgdG8gYSByZW1vdGUgdXBvbiByZXF1ZXN0LFxuLy8gaW5zdGVhZCBvZiBwYXNzaW5nIGEgcmVmZXJlbmNlLlxuUS5wYXNzQnlDb3B5ID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIC8vZnJlZXplKG9iamVjdCk7XG4gICAgLy9wYXNzQnlDb3BpZXMuc2V0KG9iamVjdCwgdHJ1ZSk7XG4gICAgcmV0dXJuIG9iamVjdDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnBhc3NCeUNvcHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgLy9mcmVlemUob2JqZWN0KTtcbiAgICAvL3Bhc3NCeUNvcGllcy5zZXQob2JqZWN0LCB0cnVlKTtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogSWYgdHdvIHByb21pc2VzIGV2ZW50dWFsbHkgZnVsZmlsbCB0byB0aGUgc2FtZSB2YWx1ZSwgcHJvbWlzZXMgdGhhdCB2YWx1ZSxcbiAqIGJ1dCBvdGhlcndpc2UgcmVqZWN0cy5cbiAqIEBwYXJhbSB4IHtBbnkqfVxuICogQHBhcmFtIHkge0FueSp9XG4gKiBAcmV0dXJucyB7QW55Kn0gYSBwcm9taXNlIGZvciB4IGFuZCB5IGlmIHRoZXkgYXJlIHRoZSBzYW1lLCBidXQgYSByZWplY3Rpb25cbiAqIG90aGVyd2lzZS5cbiAqXG4gKi9cblEuam9pbiA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgcmV0dXJuIFEoeCkuam9pbih5KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmpvaW4gPSBmdW5jdGlvbiAodGhhdCkge1xuICAgIHJldHVybiBRKFt0aGlzLCB0aGF0XSkuc3ByZWFkKGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgICAgIGlmICh4ID09PSB5KSB7XG4gICAgICAgICAgICAvLyBUT0RPOiBcIj09PVwiIHNob3VsZCBiZSBPYmplY3QuaXMgb3IgZXF1aXZcbiAgICAgICAgICAgIHJldHVybiB4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUSBjYW4ndCBqb2luOiBub3QgdGhlIHNhbWU6IFwiICsgeCArIFwiIFwiICsgeSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSBmaXJzdCBvZiBhbiBhcnJheSBvZiBwcm9taXNlcyB0byBiZWNvbWUgc2V0dGxlZC5cbiAqIEBwYXJhbSBhbnN3ZXJzIHtBcnJheVtBbnkqXX0gcHJvbWlzZXMgdG8gcmFjZVxuICogQHJldHVybnMge0FueSp9IHRoZSBmaXJzdCBwcm9taXNlIHRvIGJlIHNldHRsZWRcbiAqL1xuUS5yYWNlID0gcmFjZTtcbmZ1bmN0aW9uIHJhY2UoYW5zd2VyUHMpIHtcbiAgICByZXR1cm4gcHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIC8vIFN3aXRjaCB0byB0aGlzIG9uY2Ugd2UgY2FuIGFzc3VtZSBhdCBsZWFzdCBFUzVcbiAgICAgICAgLy8gYW5zd2VyUHMuZm9yRWFjaChmdW5jdGlvbiAoYW5zd2VyUCkge1xuICAgICAgICAvLyAgICAgUShhbnN3ZXJQKS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIC8vIH0pO1xuICAgICAgICAvLyBVc2UgdGhpcyBpbiB0aGUgbWVhbnRpbWVcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGFuc3dlclBzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBRKGFuc3dlclBzW2ldKS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUucmFjZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKFEucmFjZSk7XG59O1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBQcm9taXNlIHdpdGggYSBwcm9taXNlIGRlc2NyaXB0b3Igb2JqZWN0IGFuZCBvcHRpb25hbCBmYWxsYmFja1xuICogZnVuY3Rpb24uICBUaGUgZGVzY3JpcHRvciBjb250YWlucyBtZXRob2RzIGxpa2Ugd2hlbihyZWplY3RlZCksIGdldChuYW1lKSxcbiAqIHNldChuYW1lLCB2YWx1ZSksIHBvc3QobmFtZSwgYXJncyksIGFuZCBkZWxldGUobmFtZSksIHdoaWNoIGFsbFxuICogcmV0dXJuIGVpdGhlciBhIHZhbHVlLCBhIHByb21pc2UgZm9yIGEgdmFsdWUsIG9yIGEgcmVqZWN0aW9uLiAgVGhlIGZhbGxiYWNrXG4gKiBhY2NlcHRzIHRoZSBvcGVyYXRpb24gbmFtZSwgYSByZXNvbHZlciwgYW5kIGFueSBmdXJ0aGVyIGFyZ3VtZW50cyB0aGF0IHdvdWxkXG4gKiBoYXZlIGJlZW4gZm9yd2FyZGVkIHRvIHRoZSBhcHByb3ByaWF0ZSBtZXRob2QgYWJvdmUgaGFkIGEgbWV0aG9kIGJlZW5cbiAqIHByb3ZpZGVkIHdpdGggdGhlIHByb3BlciBuYW1lLiAgVGhlIEFQSSBtYWtlcyBubyBndWFyYW50ZWVzIGFib3V0IHRoZSBuYXR1cmVcbiAqIG9mIHRoZSByZXR1cm5lZCBvYmplY3QsIGFwYXJ0IGZyb20gdGhhdCBpdCBpcyB1c2FibGUgd2hlcmVldmVyIHByb21pc2VzIGFyZVxuICogYm91Z2h0IGFuZCBzb2xkLlxuICovXG5RLm1ha2VQcm9taXNlID0gUHJvbWlzZTtcbmZ1bmN0aW9uIFByb21pc2UoZGVzY3JpcHRvciwgZmFsbGJhY2ssIGluc3BlY3QpIHtcbiAgICBpZiAoZmFsbGJhY2sgPT09IHZvaWQgMCkge1xuICAgICAgICBmYWxsYmFjayA9IGZ1bmN0aW9uIChvcCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJQcm9taXNlIGRvZXMgbm90IHN1cHBvcnQgb3BlcmF0aW9uOiBcIiArIG9wXG4gICAgICAgICAgICApKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgaWYgKGluc3BlY3QgPT09IHZvaWQgMCkge1xuICAgICAgICBpbnNwZWN0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHtzdGF0ZTogXCJ1bmtub3duXCJ9O1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHZhciBwcm9taXNlID0gb2JqZWN0X2NyZWF0ZShQcm9taXNlLnByb3RvdHlwZSk7XG5cbiAgICBwcm9taXNlLnByb21pc2VEaXNwYXRjaCA9IGZ1bmN0aW9uIChyZXNvbHZlLCBvcCwgYXJncykge1xuICAgICAgICB2YXIgcmVzdWx0O1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKGRlc2NyaXB0b3Jbb3BdKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gZGVzY3JpcHRvcltvcF0uYXBwbHkocHJvbWlzZSwgYXJncyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGZhbGxiYWNrLmNhbGwocHJvbWlzZSwgb3AsIGFyZ3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IHJlamVjdChleGNlcHRpb24pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXNvbHZlKSB7XG4gICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcHJvbWlzZS5pbnNwZWN0ID0gaW5zcGVjdDtcblxuICAgIC8vIFhYWCBkZXByZWNhdGVkIGB2YWx1ZU9mYCBhbmQgYGV4Y2VwdGlvbmAgc3VwcG9ydFxuICAgIGlmIChpbnNwZWN0KSB7XG4gICAgICAgIHZhciBpbnNwZWN0ZWQgPSBpbnNwZWN0KCk7XG4gICAgICAgIGlmIChpbnNwZWN0ZWQuc3RhdGUgPT09IFwicmVqZWN0ZWRcIikge1xuICAgICAgICAgICAgcHJvbWlzZS5leGNlcHRpb24gPSBpbnNwZWN0ZWQucmVhc29uO1xuICAgICAgICB9XG5cbiAgICAgICAgcHJvbWlzZS52YWx1ZU9mID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGluc3BlY3RlZCA9IGluc3BlY3QoKTtcbiAgICAgICAgICAgIGlmIChpbnNwZWN0ZWQuc3RhdGUgPT09IFwicGVuZGluZ1wiIHx8XG4gICAgICAgICAgICAgICAgaW5zcGVjdGVkLnN0YXRlID09PSBcInJlamVjdGVkXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBpbnNwZWN0ZWQudmFsdWU7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cblByb21pc2UucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBcIltvYmplY3QgUHJvbWlzZV1cIjtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnRoZW4gPSBmdW5jdGlvbiAoZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3NlZCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIHZhciBkb25lID0gZmFsc2U7ICAgLy8gZW5zdXJlIHRoZSB1bnRydXN0ZWQgcHJvbWlzZSBtYWtlcyBhdCBtb3N0IGFcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNpbmdsZSBjYWxsIHRvIG9uZSBvZiB0aGUgY2FsbGJhY2tzXG5cbiAgICBmdW5jdGlvbiBfZnVsZmlsbGVkKHZhbHVlKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIGZ1bGZpbGxlZCA9PT0gXCJmdW5jdGlvblwiID8gZnVsZmlsbGVkKHZhbHVlKSA6IHZhbHVlO1xuICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9yZWplY3RlZChleGNlcHRpb24pIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZWplY3RlZCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBtYWtlU3RhY2tUcmFjZUxvbmcoZXhjZXB0aW9uLCBzZWxmKTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdGVkKGV4Y2VwdGlvbik7XG4gICAgICAgICAgICB9IGNhdGNoIChuZXdFeGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ld0V4Y2VwdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlamVjdChleGNlcHRpb24pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9wcm9ncmVzc2VkKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgcHJvZ3Jlc3NlZCA9PT0gXCJmdW5jdGlvblwiID8gcHJvZ3Jlc3NlZCh2YWx1ZSkgOiB2YWx1ZTtcbiAgICB9XG5cbiAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2VsZi5wcm9taXNlRGlzcGF0Y2goZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAoZG9uZSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuXG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKF9mdWxmaWxsZWQodmFsdWUpKTtcbiAgICAgICAgfSwgXCJ3aGVuXCIsIFtmdW5jdGlvbiAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICBpZiAoZG9uZSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuXG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKF9yZWplY3RlZChleGNlcHRpb24pKTtcbiAgICAgICAgfV0pO1xuICAgIH0pO1xuXG4gICAgLy8gUHJvZ3Jlc3MgcHJvcGFnYXRvciBuZWVkIHRvIGJlIGF0dGFjaGVkIGluIHRoZSBjdXJyZW50IHRpY2suXG4gICAgc2VsZi5wcm9taXNlRGlzcGF0Y2godm9pZCAwLCBcIndoZW5cIiwgW3ZvaWQgMCwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHZhciBuZXdWYWx1ZTtcbiAgICAgICAgdmFyIHRocmV3ID0gZmFsc2U7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBuZXdWYWx1ZSA9IF9wcm9ncmVzc2VkKHZhbHVlKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhyZXcgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKFEub25lcnJvcikge1xuICAgICAgICAgICAgICAgIFEub25lcnJvcihlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhyZXcpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLm5vdGlmeShuZXdWYWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XSk7XG5cbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cblEudGFwID0gZnVuY3Rpb24gKHByb21pc2UsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIFEocHJvbWlzZSkudGFwKGNhbGxiYWNrKTtcbn07XG5cbi8qKlxuICogV29ya3MgYWxtb3N0IGxpa2UgXCJmaW5hbGx5XCIsIGJ1dCBub3QgY2FsbGVkIGZvciByZWplY3Rpb25zLlxuICogT3JpZ2luYWwgcmVzb2x1dGlvbiB2YWx1ZSBpcyBwYXNzZWQgdGhyb3VnaCBjYWxsYmFjayB1bmFmZmVjdGVkLlxuICogQ2FsbGJhY2sgbWF5IHJldHVybiBhIHByb21pc2UgdGhhdCB3aWxsIGJlIGF3YWl0ZWQgZm9yLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEByZXR1cm5zIHtRLlByb21pc2V9XG4gKiBAZXhhbXBsZVxuICogZG9Tb21ldGhpbmcoKVxuICogICAudGhlbiguLi4pXG4gKiAgIC50YXAoY29uc29sZS5sb2cpXG4gKiAgIC50aGVuKC4uLik7XG4gKi9cblByb21pc2UucHJvdG90eXBlLnRhcCA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gUShjYWxsYmFjayk7XG5cbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2suZmNhbGwodmFsdWUpLnRoZW5SZXNvbHZlKHZhbHVlKTtcbiAgICB9KTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGFuIG9ic2VydmVyIG9uIGEgcHJvbWlzZS5cbiAqXG4gKiBHdWFyYW50ZWVzOlxuICpcbiAqIDEuIHRoYXQgZnVsZmlsbGVkIGFuZCByZWplY3RlZCB3aWxsIGJlIGNhbGxlZCBvbmx5IG9uY2UuXG4gKiAyLiB0aGF0IGVpdGhlciB0aGUgZnVsZmlsbGVkIGNhbGxiYWNrIG9yIHRoZSByZWplY3RlZCBjYWxsYmFjayB3aWxsIGJlXG4gKiAgICBjYWxsZWQsIGJ1dCBub3QgYm90aC5cbiAqIDMuIHRoYXQgZnVsZmlsbGVkIGFuZCByZWplY3RlZCB3aWxsIG5vdCBiZSBjYWxsZWQgaW4gdGhpcyB0dXJuLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSAgICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSB0byBvYnNlcnZlXG4gKiBAcGFyYW0gZnVsZmlsbGVkICBmdW5jdGlvbiB0byBiZSBjYWxsZWQgd2l0aCB0aGUgZnVsZmlsbGVkIHZhbHVlXG4gKiBAcGFyYW0gcmVqZWN0ZWQgICBmdW5jdGlvbiB0byBiZSBjYWxsZWQgd2l0aCB0aGUgcmVqZWN0aW9uIGV4Y2VwdGlvblxuICogQHBhcmFtIHByb2dyZXNzZWQgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIG9uIGFueSBwcm9ncmVzcyBub3RpZmljYXRpb25zXG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgaW52b2tlZCBjYWxsYmFja1xuICovXG5RLndoZW4gPSB3aGVuO1xuZnVuY3Rpb24gd2hlbih2YWx1ZSwgZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3NlZCkge1xuICAgIHJldHVybiBRKHZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuUmVzb2x2ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gdmFsdWU7IH0pO1xufTtcblxuUS50aGVuUmVzb2x2ZSA9IGZ1bmN0aW9uIChwcm9taXNlLCB2YWx1ZSkge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRoZW5SZXNvbHZlKHZhbHVlKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnRoZW5SZWplY3QgPSBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAoKSB7IHRocm93IHJlYXNvbjsgfSk7XG59O1xuXG5RLnRoZW5SZWplY3QgPSBmdW5jdGlvbiAocHJvbWlzZSwgcmVhc29uKSB7XG4gICAgcmV0dXJuIFEocHJvbWlzZSkudGhlblJlamVjdChyZWFzb24pO1xufTtcblxuLyoqXG4gKiBJZiBhbiBvYmplY3QgaXMgbm90IGEgcHJvbWlzZSwgaXQgaXMgYXMgXCJuZWFyXCIgYXMgcG9zc2libGUuXG4gKiBJZiBhIHByb21pc2UgaXMgcmVqZWN0ZWQsIGl0IGlzIGFzIFwibmVhclwiIGFzIHBvc3NpYmxlIHRvby5cbiAqIElmIGl04oCZcyBhIGZ1bGZpbGxlZCBwcm9taXNlLCB0aGUgZnVsZmlsbG1lbnQgdmFsdWUgaXMgbmVhcmVyLlxuICogSWYgaXTigJlzIGEgZGVmZXJyZWQgcHJvbWlzZSBhbmQgdGhlIGRlZmVycmVkIGhhcyBiZWVuIHJlc29sdmVkLCB0aGVcbiAqIHJlc29sdXRpb24gaXMgXCJuZWFyZXJcIi5cbiAqIEBwYXJhbSBvYmplY3RcbiAqIEByZXR1cm5zIG1vc3QgcmVzb2x2ZWQgKG5lYXJlc3QpIGZvcm0gb2YgdGhlIG9iamVjdFxuICovXG5cbi8vIFhYWCBzaG91bGQgd2UgcmUtZG8gdGhpcz9cblEubmVhcmVyID0gbmVhcmVyO1xuZnVuY3Rpb24gbmVhcmVyKHZhbHVlKSB7XG4gICAgaWYgKGlzUHJvbWlzZSh2YWx1ZSkpIHtcbiAgICAgICAgdmFyIGluc3BlY3RlZCA9IHZhbHVlLmluc3BlY3QoKTtcbiAgICAgICAgaWYgKGluc3BlY3RlZC5zdGF0ZSA9PT0gXCJmdWxmaWxsZWRcIikge1xuICAgICAgICAgICAgcmV0dXJuIGluc3BlY3RlZC52YWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogQHJldHVybnMgd2hldGhlciB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGEgcHJvbWlzZS5cbiAqIE90aGVyd2lzZSBpdCBpcyBhIGZ1bGZpbGxlZCB2YWx1ZS5cbiAqL1xuUS5pc1Byb21pc2UgPSBpc1Byb21pc2U7XG5mdW5jdGlvbiBpc1Byb21pc2Uob2JqZWN0KSB7XG4gICAgcmV0dXJuIG9iamVjdCBpbnN0YW5jZW9mIFByb21pc2U7XG59XG5cblEuaXNQcm9taXNlQWxpa2UgPSBpc1Byb21pc2VBbGlrZTtcbmZ1bmN0aW9uIGlzUHJvbWlzZUFsaWtlKG9iamVjdCkge1xuICAgIHJldHVybiBpc09iamVjdChvYmplY3QpICYmIHR5cGVvZiBvYmplY3QudGhlbiA9PT0gXCJmdW5jdGlvblwiO1xufVxuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHBlbmRpbmcgcHJvbWlzZSwgbWVhbmluZyBub3RcbiAqIGZ1bGZpbGxlZCBvciByZWplY3RlZC5cbiAqL1xuUS5pc1BlbmRpbmcgPSBpc1BlbmRpbmc7XG5mdW5jdGlvbiBpc1BlbmRpbmcob2JqZWN0KSB7XG4gICAgcmV0dXJuIGlzUHJvbWlzZShvYmplY3QpICYmIG9iamVjdC5pbnNwZWN0KCkuc3RhdGUgPT09IFwicGVuZGluZ1wiO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5pc1BlbmRpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW5zcGVjdCgpLnN0YXRlID09PSBcInBlbmRpbmdcIjtcbn07XG5cbi8qKlxuICogQHJldHVybnMgd2hldGhlciB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGEgdmFsdWUgb3IgZnVsZmlsbGVkXG4gKiBwcm9taXNlLlxuICovXG5RLmlzRnVsZmlsbGVkID0gaXNGdWxmaWxsZWQ7XG5mdW5jdGlvbiBpc0Z1bGZpbGxlZChvYmplY3QpIHtcbiAgICByZXR1cm4gIWlzUHJvbWlzZShvYmplY3QpIHx8IG9iamVjdC5pbnNwZWN0KCkuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCI7XG59XG5cblByb21pc2UucHJvdG90eXBlLmlzRnVsZmlsbGVkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmluc3BlY3QoKS5zdGF0ZSA9PT0gXCJmdWxmaWxsZWRcIjtcbn07XG5cbi8qKlxuICogQHJldHVybnMgd2hldGhlciB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGEgcmVqZWN0ZWQgcHJvbWlzZS5cbiAqL1xuUS5pc1JlamVjdGVkID0gaXNSZWplY3RlZDtcbmZ1bmN0aW9uIGlzUmVqZWN0ZWQob2JqZWN0KSB7XG4gICAgcmV0dXJuIGlzUHJvbWlzZShvYmplY3QpICYmIG9iamVjdC5pbnNwZWN0KCkuc3RhdGUgPT09IFwicmVqZWN0ZWRcIjtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuaXNSZWplY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pbnNwZWN0KCkuc3RhdGUgPT09IFwicmVqZWN0ZWRcIjtcbn07XG5cbi8vLy8gQkVHSU4gVU5IQU5ETEVEIFJFSkVDVElPTiBUUkFDS0lOR1xuXG4vLyBUaGlzIHByb21pc2UgbGlicmFyeSBjb25zdW1lcyBleGNlcHRpb25zIHRocm93biBpbiBoYW5kbGVycyBzbyB0aGV5IGNhbiBiZVxuLy8gaGFuZGxlZCBieSBhIHN1YnNlcXVlbnQgcHJvbWlzZS4gIFRoZSBleGNlcHRpb25zIGdldCBhZGRlZCB0byB0aGlzIGFycmF5IHdoZW5cbi8vIHRoZXkgYXJlIGNyZWF0ZWQsIGFuZCByZW1vdmVkIHdoZW4gdGhleSBhcmUgaGFuZGxlZC4gIE5vdGUgdGhhdCBpbiBFUzYgb3Jcbi8vIHNoaW1tZWQgZW52aXJvbm1lbnRzLCB0aGlzIHdvdWxkIG5hdHVyYWxseSBiZSBhIGBTZXRgLlxudmFyIHVuaGFuZGxlZFJlYXNvbnMgPSBbXTtcbnZhciB1bmhhbmRsZWRSZWplY3Rpb25zID0gW107XG52YXIgcmVwb3J0ZWRVbmhhbmRsZWRSZWplY3Rpb25zID0gW107XG52YXIgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gdHJ1ZTtcblxuZnVuY3Rpb24gcmVzZXRVbmhhbmRsZWRSZWplY3Rpb25zKCkge1xuICAgIHVuaGFuZGxlZFJlYXNvbnMubGVuZ3RoID0gMDtcbiAgICB1bmhhbmRsZWRSZWplY3Rpb25zLmxlbmd0aCA9IDA7XG5cbiAgICBpZiAoIXRyYWNrVW5oYW5kbGVkUmVqZWN0aW9ucykge1xuICAgICAgICB0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMgPSB0cnVlO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gdHJhY2tSZWplY3Rpb24ocHJvbWlzZSwgcmVhc29uKSB7XG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHByb2Nlc3MuZW1pdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIFEubmV4dFRpY2sucnVuQWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKGFycmF5X2luZGV4T2YodW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgcHJvY2Vzcy5lbWl0KFwidW5oYW5kbGVkUmVqZWN0aW9uXCIsIHJlYXNvbiwgcHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgcmVwb3J0ZWRVbmhhbmRsZWRSZWplY3Rpb25zLnB1c2gocHJvbWlzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHVuaGFuZGxlZFJlamVjdGlvbnMucHVzaChwcm9taXNlKTtcbiAgICBpZiAocmVhc29uICYmIHR5cGVvZiByZWFzb24uc3RhY2sgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgdW5oYW5kbGVkUmVhc29ucy5wdXNoKHJlYXNvbi5zdGFjayk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdW5oYW5kbGVkUmVhc29ucy5wdXNoKFwiKG5vIHN0YWNrKSBcIiArIHJlYXNvbik7XG4gICAgfVxufVxuXG5mdW5jdGlvbiB1bnRyYWNrUmVqZWN0aW9uKHByb21pc2UpIHtcbiAgICBpZiAoIXRyYWNrVW5oYW5kbGVkUmVqZWN0aW9ucykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGF0ID0gYXJyYXlfaW5kZXhPZih1bmhhbmRsZWRSZWplY3Rpb25zLCBwcm9taXNlKTtcbiAgICBpZiAoYXQgIT09IC0xKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgcHJvY2Vzcy5lbWl0ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2sucnVuQWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBhdFJlcG9ydCA9IGFycmF5X2luZGV4T2YocmVwb3J0ZWRVbmhhbmRsZWRSZWplY3Rpb25zLCBwcm9taXNlKTtcbiAgICAgICAgICAgICAgICBpZiAoYXRSZXBvcnQgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHByb2Nlc3MuZW1pdChcInJlamVjdGlvbkhhbmRsZWRcIiwgdW5oYW5kbGVkUmVhc29uc1thdF0sIHByb21pc2UpO1xuICAgICAgICAgICAgICAgICAgICByZXBvcnRlZFVuaGFuZGxlZFJlamVjdGlvbnMuc3BsaWNlKGF0UmVwb3J0LCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICB1bmhhbmRsZWRSZWplY3Rpb25zLnNwbGljZShhdCwgMSk7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMuc3BsaWNlKGF0LCAxKTtcbiAgICB9XG59XG5cblEucmVzZXRVbmhhbmRsZWRSZWplY3Rpb25zID0gcmVzZXRVbmhhbmRsZWRSZWplY3Rpb25zO1xuXG5RLmdldFVuaGFuZGxlZFJlYXNvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgLy8gTWFrZSBhIGNvcHkgc28gdGhhdCBjb25zdW1lcnMgY2FuJ3QgaW50ZXJmZXJlIHdpdGggb3VyIGludGVybmFsIHN0YXRlLlxuICAgIHJldHVybiB1bmhhbmRsZWRSZWFzb25zLnNsaWNlKCk7XG59O1xuXG5RLnN0b3BVbmhhbmRsZWRSZWplY3Rpb25UcmFja2luZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXNldFVuaGFuZGxlZFJlamVjdGlvbnMoKTtcbiAgICB0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMgPSBmYWxzZTtcbn07XG5cbnJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucygpO1xuXG4vLy8vIEVORCBVTkhBTkRMRUQgUkVKRUNUSU9OIFRSQUNLSU5HXG5cbi8qKlxuICogQ29uc3RydWN0cyBhIHJlamVjdGVkIHByb21pc2UuXG4gKiBAcGFyYW0gcmVhc29uIHZhbHVlIGRlc2NyaWJpbmcgdGhlIGZhaWx1cmVcbiAqL1xuUS5yZWplY3QgPSByZWplY3Q7XG5mdW5jdGlvbiByZWplY3QocmVhc29uKSB7XG4gICAgdmFyIHJlamVjdGlvbiA9IFByb21pc2Uoe1xuICAgICAgICBcIndoZW5cIjogZnVuY3Rpb24gKHJlamVjdGVkKSB7XG4gICAgICAgICAgICAvLyBub3RlIHRoYXQgdGhlIGVycm9yIGhhcyBiZWVuIGhhbmRsZWRcbiAgICAgICAgICAgIGlmIChyZWplY3RlZCkge1xuICAgICAgICAgICAgICAgIHVudHJhY2tSZWplY3Rpb24odGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVqZWN0ZWQgPyByZWplY3RlZChyZWFzb24pIDogdGhpcztcbiAgICAgICAgfVxuICAgIH0sIGZ1bmN0aW9uIGZhbGxiYWNrKCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LCBmdW5jdGlvbiBpbnNwZWN0KCkge1xuICAgICAgICByZXR1cm4geyBzdGF0ZTogXCJyZWplY3RlZFwiLCByZWFzb246IHJlYXNvbiB9O1xuICAgIH0pO1xuXG4gICAgLy8gTm90ZSB0aGF0IHRoZSByZWFzb24gaGFzIG5vdCBiZWVuIGhhbmRsZWQuXG4gICAgdHJhY2tSZWplY3Rpb24ocmVqZWN0aW9uLCByZWFzb24pO1xuXG4gICAgcmV0dXJuIHJlamVjdGlvbjtcbn1cblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgZnVsZmlsbGVkIHByb21pc2UgZm9yIGFuIGltbWVkaWF0ZSByZWZlcmVuY2UuXG4gKiBAcGFyYW0gdmFsdWUgaW1tZWRpYXRlIHJlZmVyZW5jZVxuICovXG5RLmZ1bGZpbGwgPSBmdWxmaWxsO1xuZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkge1xuICAgIHJldHVybiBQcm9taXNlKHtcbiAgICAgICAgXCJ3aGVuXCI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSxcbiAgICAgICAgXCJnZXRcIjogZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZVtuYW1lXTtcbiAgICAgICAgfSxcbiAgICAgICAgXCJzZXRcIjogZnVuY3Rpb24gKG5hbWUsIHJocykge1xuICAgICAgICAgICAgdmFsdWVbbmFtZV0gPSByaHM7XG4gICAgICAgIH0sXG4gICAgICAgIFwiZGVsZXRlXCI6IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgICAgICBkZWxldGUgdmFsdWVbbmFtZV07XG4gICAgICAgIH0sXG4gICAgICAgIFwicG9zdFwiOiBmdW5jdGlvbiAobmFtZSwgYXJncykge1xuICAgICAgICAgICAgLy8gTWFyayBNaWxsZXIgcHJvcG9zZXMgdGhhdCBwb3N0IHdpdGggbm8gbmFtZSBzaG91bGQgYXBwbHkgYVxuICAgICAgICAgICAgLy8gcHJvbWlzZWQgZnVuY3Rpb24uXG4gICAgICAgICAgICBpZiAobmFtZSA9PT0gbnVsbCB8fCBuYW1lID09PSB2b2lkIDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUuYXBwbHkodm9pZCAwLCBhcmdzKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlW25hbWVdLmFwcGx5KHZhbHVlLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgXCJhcHBseVwiOiBmdW5jdGlvbiAodGhpc3AsIGFyZ3MpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZS5hcHBseSh0aGlzcCwgYXJncyk7XG4gICAgICAgIH0sXG4gICAgICAgIFwia2V5c1wiOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0X2tleXModmFsdWUpO1xuICAgICAgICB9XG4gICAgfSwgdm9pZCAwLCBmdW5jdGlvbiBpbnNwZWN0KCkge1xuICAgICAgICByZXR1cm4geyBzdGF0ZTogXCJmdWxmaWxsZWRcIiwgdmFsdWU6IHZhbHVlIH07XG4gICAgfSk7XG59XG5cbi8qKlxuICogQ29udmVydHMgdGhlbmFibGVzIHRvIFEgcHJvbWlzZXMuXG4gKiBAcGFyYW0gcHJvbWlzZSB0aGVuYWJsZSBwcm9taXNlXG4gKiBAcmV0dXJucyBhIFEgcHJvbWlzZVxuICovXG5mdW5jdGlvbiBjb2VyY2UocHJvbWlzZSkge1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwcm9taXNlLnRoZW4oZGVmZXJyZWQucmVzb2x2ZSwgZGVmZXJyZWQucmVqZWN0LCBkZWZlcnJlZC5ub3RpZnkpO1xuICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdChleGNlcHRpb24pO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59XG5cbi8qKlxuICogQW5ub3RhdGVzIGFuIG9iamVjdCBzdWNoIHRoYXQgaXQgd2lsbCBuZXZlciBiZVxuICogdHJhbnNmZXJyZWQgYXdheSBmcm9tIHRoaXMgcHJvY2VzcyBvdmVyIGFueSBwcm9taXNlXG4gKiBjb21tdW5pY2F0aW9uIGNoYW5uZWwuXG4gKiBAcGFyYW0gb2JqZWN0XG4gKiBAcmV0dXJucyBwcm9taXNlIGEgd3JhcHBpbmcgb2YgdGhhdCBvYmplY3QgdGhhdFxuICogYWRkaXRpb25hbGx5IHJlc3BvbmRzIHRvIHRoZSBcImlzRGVmXCIgbWVzc2FnZVxuICogd2l0aG91dCBhIHJlamVjdGlvbi5cbiAqL1xuUS5tYXN0ZXIgPSBtYXN0ZXI7XG5mdW5jdGlvbiBtYXN0ZXIob2JqZWN0KSB7XG4gICAgcmV0dXJuIFByb21pc2Uoe1xuICAgICAgICBcImlzRGVmXCI6IGZ1bmN0aW9uICgpIHt9XG4gICAgfSwgZnVuY3Rpb24gZmFsbGJhY2sob3AsIGFyZ3MpIHtcbiAgICAgICAgcmV0dXJuIGRpc3BhdGNoKG9iamVjdCwgb3AsIGFyZ3MpO1xuICAgIH0sIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFEob2JqZWN0KS5pbnNwZWN0KCk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogU3ByZWFkcyB0aGUgdmFsdWVzIG9mIGEgcHJvbWlzZWQgYXJyYXkgb2YgYXJndW1lbnRzIGludG8gdGhlXG4gKiBmdWxmaWxsbWVudCBjYWxsYmFjay5cbiAqIEBwYXJhbSBmdWxmaWxsZWQgY2FsbGJhY2sgdGhhdCByZWNlaXZlcyB2YXJpYWRpYyBhcmd1bWVudHMgZnJvbSB0aGVcbiAqIHByb21pc2VkIGFycmF5XG4gKiBAcGFyYW0gcmVqZWN0ZWQgY2FsbGJhY2sgdGhhdCByZWNlaXZlcyB0aGUgZXhjZXB0aW9uIGlmIHRoZSBwcm9taXNlXG4gKiBpcyByZWplY3RlZC5cbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZSBvciB0aHJvd24gZXhjZXB0aW9uIG9mXG4gKiBlaXRoZXIgY2FsbGJhY2suXG4gKi9cblEuc3ByZWFkID0gc3ByZWFkO1xuZnVuY3Rpb24gc3ByZWFkKHZhbHVlLCBmdWxmaWxsZWQsIHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIFEodmFsdWUpLnNwcmVhZChmdWxmaWxsZWQsIHJlamVjdGVkKTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuc3ByZWFkID0gZnVuY3Rpb24gKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpIHtcbiAgICByZXR1cm4gdGhpcy5hbGwoKS50aGVuKGZ1bmN0aW9uIChhcnJheSkge1xuICAgICAgICByZXR1cm4gZnVsZmlsbGVkLmFwcGx5KHZvaWQgMCwgYXJyYXkpO1xuICAgIH0sIHJlamVjdGVkKTtcbn07XG5cbi8qKlxuICogVGhlIGFzeW5jIGZ1bmN0aW9uIGlzIGEgZGVjb3JhdG9yIGZvciBnZW5lcmF0b3IgZnVuY3Rpb25zLCB0dXJuaW5nXG4gKiB0aGVtIGludG8gYXN5bmNocm9ub3VzIGdlbmVyYXRvcnMuICBBbHRob3VnaCBnZW5lcmF0b3JzIGFyZSBvbmx5IHBhcnRcbiAqIG9mIHRoZSBuZXdlc3QgRUNNQVNjcmlwdCA2IGRyYWZ0cywgdGhpcyBjb2RlIGRvZXMgbm90IGNhdXNlIHN5bnRheFxuICogZXJyb3JzIGluIG9sZGVyIGVuZ2luZXMuICBUaGlzIGNvZGUgc2hvdWxkIGNvbnRpbnVlIHRvIHdvcmsgYW5kIHdpbGxcbiAqIGluIGZhY3QgaW1wcm92ZSBvdmVyIHRpbWUgYXMgdGhlIGxhbmd1YWdlIGltcHJvdmVzLlxuICpcbiAqIEVTNiBnZW5lcmF0b3JzIGFyZSBjdXJyZW50bHkgcGFydCBvZiBWOCB2ZXJzaW9uIDMuMTkgd2l0aCB0aGVcbiAqIC0taGFybW9ueS1nZW5lcmF0b3JzIHJ1bnRpbWUgZmxhZyBlbmFibGVkLiAgU3BpZGVyTW9ua2V5IGhhcyBoYWQgdGhlbVxuICogZm9yIGxvbmdlciwgYnV0IHVuZGVyIGFuIG9sZGVyIFB5dGhvbi1pbnNwaXJlZCBmb3JtLiAgVGhpcyBmdW5jdGlvblxuICogd29ya3Mgb24gYm90aCBraW5kcyBvZiBnZW5lcmF0b3JzLlxuICpcbiAqIERlY29yYXRlcyBhIGdlbmVyYXRvciBmdW5jdGlvbiBzdWNoIHRoYXQ6XG4gKiAgLSBpdCBtYXkgeWllbGQgcHJvbWlzZXNcbiAqICAtIGV4ZWN1dGlvbiB3aWxsIGNvbnRpbnVlIHdoZW4gdGhhdCBwcm9taXNlIGlzIGZ1bGZpbGxlZFxuICogIC0gdGhlIHZhbHVlIG9mIHRoZSB5aWVsZCBleHByZXNzaW9uIHdpbGwgYmUgdGhlIGZ1bGZpbGxlZCB2YWx1ZVxuICogIC0gaXQgcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWUgKHdoZW4gdGhlIGdlbmVyYXRvclxuICogICAgc3RvcHMgaXRlcmF0aW5nKVxuICogIC0gdGhlIGRlY29yYXRlZCBmdW5jdGlvbiByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZVxuICogICAgb2YgdGhlIGdlbmVyYXRvciBvciB0aGUgZmlyc3QgcmVqZWN0ZWQgcHJvbWlzZSBhbW9uZyB0aG9zZVxuICogICAgeWllbGRlZC5cbiAqICAtIGlmIGFuIGVycm9yIGlzIHRocm93biBpbiB0aGUgZ2VuZXJhdG9yLCBpdCBwcm9wYWdhdGVzIHRocm91Z2hcbiAqICAgIGV2ZXJ5IGZvbGxvd2luZyB5aWVsZCB1bnRpbCBpdCBpcyBjYXVnaHQsIG9yIHVudGlsIGl0IGVzY2FwZXNcbiAqICAgIHRoZSBnZW5lcmF0b3IgZnVuY3Rpb24gYWx0b2dldGhlciwgYW5kIGlzIHRyYW5zbGF0ZWQgaW50byBhXG4gKiAgICByZWplY3Rpb24gZm9yIHRoZSBwcm9taXNlIHJldHVybmVkIGJ5IHRoZSBkZWNvcmF0ZWQgZ2VuZXJhdG9yLlxuICovXG5RLmFzeW5jID0gYXN5bmM7XG5mdW5jdGlvbiBhc3luYyhtYWtlR2VuZXJhdG9yKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gd2hlbiB2ZXJiIGlzIFwic2VuZFwiLCBhcmcgaXMgYSB2YWx1ZVxuICAgICAgICAvLyB3aGVuIHZlcmIgaXMgXCJ0aHJvd1wiLCBhcmcgaXMgYW4gZXhjZXB0aW9uXG4gICAgICAgIGZ1bmN0aW9uIGNvbnRpbnVlcih2ZXJiLCBhcmcpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQ7XG5cbiAgICAgICAgICAgIC8vIFVudGlsIFY4IDMuMTkgLyBDaHJvbWl1bSAyOSBpcyByZWxlYXNlZCwgU3BpZGVyTW9ua2V5IGlzIHRoZSBvbmx5XG4gICAgICAgICAgICAvLyBlbmdpbmUgdGhhdCBoYXMgYSBkZXBsb3llZCBiYXNlIG9mIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBnZW5lcmF0b3JzLlxuICAgICAgICAgICAgLy8gSG93ZXZlciwgU00ncyBnZW5lcmF0b3JzIHVzZSB0aGUgUHl0aG9uLWluc3BpcmVkIHNlbWFudGljcyBvZlxuICAgICAgICAgICAgLy8gb3V0ZGF0ZWQgRVM2IGRyYWZ0cy4gIFdlIHdvdWxkIGxpa2UgdG8gc3VwcG9ydCBFUzYsIGJ1dCB3ZSdkIGFsc29cbiAgICAgICAgICAgIC8vIGxpa2UgdG8gbWFrZSBpdCBwb3NzaWJsZSB0byB1c2UgZ2VuZXJhdG9ycyBpbiBkZXBsb3llZCBicm93c2Vycywgc29cbiAgICAgICAgICAgIC8vIHdlIGFsc28gc3VwcG9ydCBQeXRob24tc3R5bGUgZ2VuZXJhdG9ycy4gIEF0IHNvbWUgcG9pbnQgd2UgY2FuIHJlbW92ZVxuICAgICAgICAgICAgLy8gdGhpcyBibG9jay5cblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBTdG9wSXRlcmF0aW9uID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgLy8gRVM2IEdlbmVyYXRvcnNcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBnZW5lcmF0b3JbdmVyYl0oYXJnKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChleGNlcHRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0LmRvbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFEocmVzdWx0LnZhbHVlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gd2hlbihyZXN1bHQudmFsdWUsIGNhbGxiYWNrLCBlcnJiYWNrKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFNwaWRlck1vbmtleSBHZW5lcmF0b3JzXG4gICAgICAgICAgICAgICAgLy8gRklYTUU6IFJlbW92ZSB0aGlzIGNhc2Ugd2hlbiBTTSBkb2VzIEVTNiBnZW5lcmF0b3JzLlxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGdlbmVyYXRvclt2ZXJiXShhcmcpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNTdG9wSXRlcmF0aW9uKGV4Y2VwdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBRKGV4Y2VwdGlvbi52YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGV4Y2VwdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHdoZW4ocmVzdWx0LCBjYWxsYmFjaywgZXJyYmFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGdlbmVyYXRvciA9IG1ha2VHZW5lcmF0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgdmFyIGNhbGxiYWNrID0gY29udGludWVyLmJpbmQoY29udGludWVyLCBcIm5leHRcIik7XG4gICAgICAgIHZhciBlcnJiYWNrID0gY29udGludWVyLmJpbmQoY29udGludWVyLCBcInRocm93XCIpO1xuICAgICAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgICB9O1xufVxuXG4vKipcbiAqIFRoZSBzcGF3biBmdW5jdGlvbiBpcyBhIHNtYWxsIHdyYXBwZXIgYXJvdW5kIGFzeW5jIHRoYXQgaW1tZWRpYXRlbHlcbiAqIGNhbGxzIHRoZSBnZW5lcmF0b3IgYW5kIGFsc28gZW5kcyB0aGUgcHJvbWlzZSBjaGFpbiwgc28gdGhhdCBhbnlcbiAqIHVuaGFuZGxlZCBlcnJvcnMgYXJlIHRocm93biBpbnN0ZWFkIG9mIGZvcndhcmRlZCB0byB0aGUgZXJyb3JcbiAqIGhhbmRsZXIuIFRoaXMgaXMgdXNlZnVsIGJlY2F1c2UgaXQncyBleHRyZW1lbHkgY29tbW9uIHRvIHJ1blxuICogZ2VuZXJhdG9ycyBhdCB0aGUgdG9wLWxldmVsIHRvIHdvcmsgd2l0aCBsaWJyYXJpZXMuXG4gKi9cblEuc3Bhd24gPSBzcGF3bjtcbmZ1bmN0aW9uIHNwYXduKG1ha2VHZW5lcmF0b3IpIHtcbiAgICBRLmRvbmUoUS5hc3luYyhtYWtlR2VuZXJhdG9yKSgpKTtcbn1cblxuLy8gRklYTUU6IFJlbW92ZSB0aGlzIGludGVyZmFjZSBvbmNlIEVTNiBnZW5lcmF0b3JzIGFyZSBpbiBTcGlkZXJNb25rZXkuXG4vKipcbiAqIFRocm93cyBhIFJldHVyblZhbHVlIGV4Y2VwdGlvbiB0byBzdG9wIGFuIGFzeW5jaHJvbm91cyBnZW5lcmF0b3IuXG4gKlxuICogVGhpcyBpbnRlcmZhY2UgaXMgYSBzdG9wLWdhcCBtZWFzdXJlIHRvIHN1cHBvcnQgZ2VuZXJhdG9yIHJldHVyblxuICogdmFsdWVzIGluIG9sZGVyIEZpcmVmb3gvU3BpZGVyTW9ua2V5LiAgSW4gYnJvd3NlcnMgdGhhdCBzdXBwb3J0IEVTNlxuICogZ2VuZXJhdG9ycyBsaWtlIENocm9taXVtIDI5LCBqdXN0IHVzZSBcInJldHVyblwiIGluIHlvdXIgZ2VuZXJhdG9yXG4gKiBmdW5jdGlvbnMuXG4gKlxuICogQHBhcmFtIHZhbHVlIHRoZSByZXR1cm4gdmFsdWUgZm9yIHRoZSBzdXJyb3VuZGluZyBnZW5lcmF0b3JcbiAqIEB0aHJvd3MgUmV0dXJuVmFsdWUgZXhjZXB0aW9uIHdpdGggdGhlIHZhbHVlLlxuICogQGV4YW1wbGVcbiAqIC8vIEVTNiBzdHlsZVxuICogUS5hc3luYyhmdW5jdGlvbiogKCkge1xuICogICAgICB2YXIgZm9vID0geWllbGQgZ2V0Rm9vUHJvbWlzZSgpO1xuICogICAgICB2YXIgYmFyID0geWllbGQgZ2V0QmFyUHJvbWlzZSgpO1xuICogICAgICByZXR1cm4gZm9vICsgYmFyO1xuICogfSlcbiAqIC8vIE9sZGVyIFNwaWRlck1vbmtleSBzdHlsZVxuICogUS5hc3luYyhmdW5jdGlvbiAoKSB7XG4gKiAgICAgIHZhciBmb28gPSB5aWVsZCBnZXRGb29Qcm9taXNlKCk7XG4gKiAgICAgIHZhciBiYXIgPSB5aWVsZCBnZXRCYXJQcm9taXNlKCk7XG4gKiAgICAgIFEucmV0dXJuKGZvbyArIGJhcik7XG4gKiB9KVxuICovXG5RW1wicmV0dXJuXCJdID0gX3JldHVybjtcbmZ1bmN0aW9uIF9yZXR1cm4odmFsdWUpIHtcbiAgICB0aHJvdyBuZXcgUVJldHVyblZhbHVlKHZhbHVlKTtcbn1cblxuLyoqXG4gKiBUaGUgcHJvbWlzZWQgZnVuY3Rpb24gZGVjb3JhdG9yIGVuc3VyZXMgdGhhdCBhbnkgcHJvbWlzZSBhcmd1bWVudHNcbiAqIGFyZSBzZXR0bGVkIGFuZCBwYXNzZWQgYXMgdmFsdWVzIChgdGhpc2AgaXMgYWxzbyBzZXR0bGVkIGFuZCBwYXNzZWRcbiAqIGFzIGEgdmFsdWUpLiAgSXQgd2lsbCBhbHNvIGVuc3VyZSB0aGF0IHRoZSByZXN1bHQgb2YgYSBmdW5jdGlvbiBpc1xuICogYWx3YXlzIGEgcHJvbWlzZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIGFkZCA9IFEucHJvbWlzZWQoZnVuY3Rpb24gKGEsIGIpIHtcbiAqICAgICByZXR1cm4gYSArIGI7XG4gKiB9KTtcbiAqIGFkZChRKGEpLCBRKEIpKTtcbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gdG8gZGVjb3JhdGVcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gYSBmdW5jdGlvbiB0aGF0IGhhcyBiZWVuIGRlY29yYXRlZC5cbiAqL1xuUS5wcm9taXNlZCA9IHByb21pc2VkO1xuZnVuY3Rpb24gcHJvbWlzZWQoY2FsbGJhY2spIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gc3ByZWFkKFt0aGlzLCBhbGwoYXJndW1lbnRzKV0sIGZ1bmN0aW9uIChzZWxmLCBhcmdzKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2suYXBwbHkoc2VsZiwgYXJncyk7XG4gICAgICAgIH0pO1xuICAgIH07XG59XG5cbi8qKlxuICogc2VuZHMgYSBtZXNzYWdlIHRvIGEgdmFsdWUgaW4gYSBmdXR1cmUgdHVyblxuICogQHBhcmFtIG9iamVjdCogdGhlIHJlY2lwaWVudFxuICogQHBhcmFtIG9wIHRoZSBuYW1lIG9mIHRoZSBtZXNzYWdlIG9wZXJhdGlvbiwgZS5nLiwgXCJ3aGVuXCIsXG4gKiBAcGFyYW0gYXJncyBmdXJ0aGVyIGFyZ3VtZW50cyB0byBiZSBmb3J3YXJkZWQgdG8gdGhlIG9wZXJhdGlvblxuICogQHJldHVybnMgcmVzdWx0IHtQcm9taXNlfSBhIHByb21pc2UgZm9yIHRoZSByZXN1bHQgb2YgdGhlIG9wZXJhdGlvblxuICovXG5RLmRpc3BhdGNoID0gZGlzcGF0Y2g7XG5mdW5jdGlvbiBkaXNwYXRjaChvYmplY3QsIG9wLCBhcmdzKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChvcCwgYXJncyk7XG59XG5cblByb21pc2UucHJvdG90eXBlLmRpc3BhdGNoID0gZnVuY3Rpb24gKG9wLCBhcmdzKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKGRlZmVycmVkLnJlc29sdmUsIG9wLCBhcmdzKTtcbiAgICB9KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogR2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eSBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBvYmplY3RcbiAqIEBwYXJhbSBuYW1lICAgICAgbmFtZSBvZiBwcm9wZXJ0eSB0byBnZXRcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHByb3BlcnR5IHZhbHVlXG4gKi9cblEuZ2V0ID0gZnVuY3Rpb24gKG9iamVjdCwga2V5KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImdldFwiLCBba2V5XSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJnZXRcIiwgW2tleV0pO1xufTtcblxuLyoqXG4gKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5IGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3Igb2JqZWN0IG9iamVjdFxuICogQHBhcmFtIG5hbWUgICAgICBuYW1lIG9mIHByb3BlcnR5IHRvIHNldFxuICogQHBhcmFtIHZhbHVlICAgICBuZXcgdmFsdWUgb2YgcHJvcGVydHlcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZVxuICovXG5RLnNldCA9IGZ1bmN0aW9uIChvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwic2V0XCIsIFtrZXksIHZhbHVlXSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwic2V0XCIsIFtrZXksIHZhbHVlXSk7XG59O1xuXG4vKipcbiAqIERlbGV0ZXMgYSBwcm9wZXJ0eSBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBvYmplY3RcbiAqIEBwYXJhbSBuYW1lICAgICAgbmFtZSBvZiBwcm9wZXJ0eSB0byBkZWxldGVcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZVxuICovXG5RLmRlbCA9IC8vIFhYWCBsZWdhY3lcblFbXCJkZWxldGVcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCBrZXkpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwiZGVsZXRlXCIsIFtrZXldKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmRlbCA9IC8vIFhYWCBsZWdhY3lcblByb21pc2UucHJvdG90eXBlW1wiZGVsZXRlXCJdID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwiZGVsZXRlXCIsIFtrZXldKTtcbn07XG5cbi8qKlxuICogSW52b2tlcyBhIG1ldGhvZCBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBvYmplY3RcbiAqIEBwYXJhbSBuYW1lICAgICAgbmFtZSBvZiBtZXRob2QgdG8gaW52b2tlXG4gKiBAcGFyYW0gdmFsdWUgICAgIGEgdmFsdWUgdG8gcG9zdCwgdHlwaWNhbGx5IGFuIGFycmF5IG9mXG4gKiAgICAgICAgICAgICAgICAgIGludm9jYXRpb24gYXJndW1lbnRzIGZvciBwcm9taXNlcyB0aGF0XG4gKiAgICAgICAgICAgICAgICAgIGFyZSB1bHRpbWF0ZWx5IGJhY2tlZCB3aXRoIGByZXNvbHZlYCB2YWx1ZXMsXG4gKiAgICAgICAgICAgICAgICAgIGFzIG9wcG9zZWQgdG8gdGhvc2UgYmFja2VkIHdpdGggVVJMc1xuICogICAgICAgICAgICAgICAgICB3aGVyZWluIHRoZSBwb3N0ZWQgdmFsdWUgY2FuIGJlIGFueVxuICogICAgICAgICAgICAgICAgICBKU09OIHNlcmlhbGl6YWJsZSBvYmplY3QuXG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuLy8gYm91bmQgbG9jYWxseSBiZWNhdXNlIGl0IGlzIHVzZWQgYnkgb3RoZXIgbWV0aG9kc1xuUS5tYXBwbHkgPSAvLyBYWFggQXMgcHJvcG9zZWQgYnkgXCJSZWRzYW5kcm9cIlxuUS5wb3N0ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBhcmdzXSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5tYXBwbHkgPSAvLyBYWFggQXMgcHJvcG9zZWQgYnkgXCJSZWRzYW5kcm9cIlxuUHJvbWlzZS5wcm90b3R5cGUucG9zdCA9IGZ1bmN0aW9uIChuYW1lLCBhcmdzKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBhcmdzXSk7XG59O1xuXG4vKipcbiAqIEludm9rZXMgYSBtZXRob2QgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgbWV0aG9kIHRvIGludm9rZVxuICogQHBhcmFtIC4uLmFyZ3MgICBhcnJheSBvZiBpbnZvY2F0aW9uIGFyZ3VtZW50c1xuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlXG4gKi9cblEuc2VuZCA9IC8vIFhYWCBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIHBhcmxhbmNlXG5RLm1jYWxsID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblEuaW52b2tlID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBhcnJheV9zbGljZShhcmd1bWVudHMsIDIpXSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5zZW5kID0gLy8gWFhYIE1hcmsgTWlsbGVyJ3MgcHJvcG9zZWQgcGFybGFuY2VcblByb21pc2UucHJvdG90eXBlLm1jYWxsID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLmludm9rZSA9IGZ1bmN0aW9uIChuYW1lIC8qLi4uYXJncyovKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpXSk7XG59O1xuXG4vKipcbiAqIEFwcGxpZXMgdGhlIHByb21pc2VkIGZ1bmN0aW9uIGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IGZ1bmN0aW9uXG4gKiBAcGFyYW0gYXJncyAgICAgIGFycmF5IG9mIGFwcGxpY2F0aW9uIGFyZ3VtZW50c1xuICovXG5RLmZhcHBseSA9IGZ1bmN0aW9uIChvYmplY3QsIGFyZ3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwiYXBwbHlcIiwgW3ZvaWQgMCwgYXJnc10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmFwcGx5ID0gZnVuY3Rpb24gKGFyZ3MpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFyZ3NdKTtcbn07XG5cbi8qKlxuICogQ2FsbHMgdGhlIHByb21pc2VkIGZ1bmN0aW9uIGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IGZ1bmN0aW9uXG4gKiBAcGFyYW0gLi4uYXJncyAgIGFycmF5IG9mIGFwcGxpY2F0aW9uIGFyZ3VtZW50c1xuICovXG5RW1widHJ5XCJdID1cblEuZmNhbGwgPSBmdW5jdGlvbiAob2JqZWN0IC8qIC4uLmFyZ3MqLykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJhcHBseVwiLCBbdm9pZCAwLCBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpXSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5mY2FsbCA9IGZ1bmN0aW9uICgvKi4uLmFyZ3MqLykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwiYXBwbHlcIiwgW3ZvaWQgMCwgYXJyYXlfc2xpY2UoYXJndW1lbnRzKV0pO1xufTtcblxuLyoqXG4gKiBCaW5kcyB0aGUgcHJvbWlzZWQgZnVuY3Rpb24sIHRyYW5zZm9ybWluZyByZXR1cm4gdmFsdWVzIGludG8gYSBmdWxmaWxsZWRcbiAqIHByb21pc2UgYW5kIHRocm93biBlcnJvcnMgaW50byBhIHJlamVjdGVkIG9uZS5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgZnVuY3Rpb25cbiAqIEBwYXJhbSAuLi5hcmdzICAgYXJyYXkgb2YgYXBwbGljYXRpb24gYXJndW1lbnRzXG4gKi9cblEuZmJpbmQgPSBmdW5jdGlvbiAob2JqZWN0IC8qLi4uYXJncyovKSB7XG4gICAgdmFyIHByb21pc2UgPSBRKG9iamVjdCk7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBmdW5jdGlvbiBmYm91bmQoKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlLmRpc3BhdGNoKFwiYXBwbHlcIiwgW1xuICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgIGFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpXG4gICAgICAgIF0pO1xuICAgIH07XG59O1xuUHJvbWlzZS5wcm90b3R5cGUuZmJpbmQgPSBmdW5jdGlvbiAoLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXM7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMpO1xuICAgIHJldHVybiBmdW5jdGlvbiBmYm91bmQoKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlLmRpc3BhdGNoKFwiYXBwbHlcIiwgW1xuICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgIGFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpXG4gICAgICAgIF0pO1xuICAgIH07XG59O1xuXG4vKipcbiAqIFJlcXVlc3RzIHRoZSBuYW1lcyBvZiB0aGUgb3duZWQgcHJvcGVydGllcyBvZiBhIHByb21pc2VkXG4gKiBvYmplY3QgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSBrZXlzIG9mIHRoZSBldmVudHVhbGx5IHNldHRsZWQgb2JqZWN0XG4gKi9cblEua2V5cyA9IGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwia2V5c1wiLCBbXSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5rZXlzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwia2V5c1wiLCBbXSk7XG59O1xuXG4vKipcbiAqIFR1cm5zIGFuIGFycmF5IG9mIHByb21pc2VzIGludG8gYSBwcm9taXNlIGZvciBhbiBhcnJheS4gIElmIGFueSBvZlxuICogdGhlIHByb21pc2VzIGdldHMgcmVqZWN0ZWQsIHRoZSB3aG9sZSBhcnJheSBpcyByZWplY3RlZCBpbW1lZGlhdGVseS5cbiAqIEBwYXJhbSB7QXJyYXkqfSBhbiBhcnJheSAob3IgcHJvbWlzZSBmb3IgYW4gYXJyYXkpIG9mIHZhbHVlcyAob3JcbiAqIHByb21pc2VzIGZvciB2YWx1ZXMpXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIGFuIGFycmF5IG9mIHRoZSBjb3JyZXNwb25kaW5nIHZhbHVlc1xuICovXG4vLyBCeSBNYXJrIE1pbGxlclxuLy8gaHR0cDovL3dpa2kuZWNtYXNjcmlwdC5vcmcvZG9rdS5waHA/aWQ9c3RyYXdtYW46Y29uY3VycmVuY3kmcmV2PTEzMDg3NzY1MjEjYWxsZnVsZmlsbGVkXG5RLmFsbCA9IGFsbDtcbmZ1bmN0aW9uIGFsbChwcm9taXNlcykge1xuICAgIHJldHVybiB3aGVuKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgdmFyIHBlbmRpbmdDb3VudCA9IDA7XG4gICAgICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgICAgIGFycmF5X3JlZHVjZShwcm9taXNlcywgZnVuY3Rpb24gKHVuZGVmaW5lZCwgcHJvbWlzZSwgaW5kZXgpIHtcbiAgICAgICAgICAgIHZhciBzbmFwc2hvdDtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBpc1Byb21pc2UocHJvbWlzZSkgJiZcbiAgICAgICAgICAgICAgICAoc25hcHNob3QgPSBwcm9taXNlLmluc3BlY3QoKSkuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCJcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHByb21pc2VzW2luZGV4XSA9IHNuYXBzaG90LnZhbHVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICArK3BlbmRpbmdDb3VudDtcbiAgICAgICAgICAgICAgICB3aGVuKFxuICAgICAgICAgICAgICAgICAgICBwcm9taXNlLFxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb21pc2VzW2luZGV4XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKC0tcGVuZGluZ0NvdW50ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShwcm9taXNlcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdCxcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHByb2dyZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZC5ub3RpZnkoeyBpbmRleDogaW5kZXgsIHZhbHVlOiBwcm9ncmVzcyB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIHZvaWQgMCk7XG4gICAgICAgIGlmIChwZW5kaW5nQ291bnQgPT09IDApIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocHJvbWlzZXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgIH0pO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5hbGwgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFsbCh0aGlzKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZmlyc3QgcmVzb2x2ZWQgcHJvbWlzZSBvZiBhbiBhcnJheS4gUHJpb3IgcmVqZWN0ZWQgcHJvbWlzZXMgYXJlXG4gKiBpZ25vcmVkLiAgUmVqZWN0cyBvbmx5IGlmIGFsbCBwcm9taXNlcyBhcmUgcmVqZWN0ZWQuXG4gKiBAcGFyYW0ge0FycmF5Kn0gYW4gYXJyYXkgY29udGFpbmluZyB2YWx1ZXMgb3IgcHJvbWlzZXMgZm9yIHZhbHVlc1xuICogQHJldHVybnMgYSBwcm9taXNlIGZ1bGZpbGxlZCB3aXRoIHRoZSB2YWx1ZSBvZiB0aGUgZmlyc3QgcmVzb2x2ZWQgcHJvbWlzZSxcbiAqIG9yIGEgcmVqZWN0ZWQgcHJvbWlzZSBpZiBhbGwgcHJvbWlzZXMgYXJlIHJlamVjdGVkLlxuICovXG5RLmFueSA9IGFueTtcblxuZnVuY3Rpb24gYW55KHByb21pc2VzKSB7XG4gICAgaWYgKHByb21pc2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gUS5yZXNvbHZlKCk7XG4gICAgfVxuXG4gICAgdmFyIGRlZmVycmVkID0gUS5kZWZlcigpO1xuICAgIHZhciBwZW5kaW5nQ291bnQgPSAwO1xuICAgIGFycmF5X3JlZHVjZShwcm9taXNlcywgZnVuY3Rpb24gKHByZXYsIGN1cnJlbnQsIGluZGV4KSB7XG4gICAgICAgIHZhciBwcm9taXNlID0gcHJvbWlzZXNbaW5kZXhdO1xuXG4gICAgICAgIHBlbmRpbmdDb3VudCsrO1xuXG4gICAgICAgIHdoZW4ocHJvbWlzZSwgb25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQsIG9uUHJvZ3Jlc3MpO1xuICAgICAgICBmdW5jdGlvbiBvbkZ1bGZpbGxlZChyZXN1bHQpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBvblJlamVjdGVkKGVycikge1xuICAgICAgICAgICAgcGVuZGluZ0NvdW50LS07XG4gICAgICAgICAgICBpZiAocGVuZGluZ0NvdW50ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlamVjdGlvbiA9IGVyciB8fCBuZXcgRXJyb3IoXCJcIiArIGVycik7XG5cbiAgICAgICAgICAgICAgICByZWplY3Rpb24ubWVzc2FnZSA9IChcIlEgY2FuJ3QgZ2V0IGZ1bGZpbGxtZW50IHZhbHVlIGZyb20gYW55IHByb21pc2UsIGFsbCBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwicHJvbWlzZXMgd2VyZSByZWplY3RlZC4gTGFzdCBlcnJvciBtZXNzYWdlOiBcIiArIHJlamVjdGlvbi5tZXNzYWdlKTtcblxuICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdChyZWplY3Rpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG9uUHJvZ3Jlc3MocHJvZ3Jlc3MpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLm5vdGlmeSh7XG4gICAgICAgICAgICAgICAgaW5kZXg6IGluZGV4LFxuICAgICAgICAgICAgICAgIHZhbHVlOiBwcm9ncmVzc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9LCB1bmRlZmluZWQpO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59XG5cblByb21pc2UucHJvdG90eXBlLmFueSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYW55KHRoaXMpO1xufTtcblxuLyoqXG4gKiBXYWl0cyBmb3IgYWxsIHByb21pc2VzIHRvIGJlIHNldHRsZWQsIGVpdGhlciBmdWxmaWxsZWQgb3JcbiAqIHJlamVjdGVkLiAgVGhpcyBpcyBkaXN0aW5jdCBmcm9tIGBhbGxgIHNpbmNlIHRoYXQgd291bGQgc3RvcFxuICogd2FpdGluZyBhdCB0aGUgZmlyc3QgcmVqZWN0aW9uLiAgVGhlIHByb21pc2UgcmV0dXJuZWQgYnlcbiAqIGBhbGxSZXNvbHZlZGAgd2lsbCBuZXZlciBiZSByZWplY3RlZC5cbiAqIEBwYXJhbSBwcm9taXNlcyBhIHByb21pc2UgZm9yIGFuIGFycmF5IChvciBhbiBhcnJheSkgb2YgcHJvbWlzZXNcbiAqIChvciB2YWx1ZXMpXG4gKiBAcmV0dXJuIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkgb2YgcHJvbWlzZXNcbiAqL1xuUS5hbGxSZXNvbHZlZCA9IGRlcHJlY2F0ZShhbGxSZXNvbHZlZCwgXCJhbGxSZXNvbHZlZFwiLCBcImFsbFNldHRsZWRcIik7XG5mdW5jdGlvbiBhbGxSZXNvbHZlZChwcm9taXNlcykge1xuICAgIHJldHVybiB3aGVuKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgcHJvbWlzZXMgPSBhcnJheV9tYXAocHJvbWlzZXMsIFEpO1xuICAgICAgICByZXR1cm4gd2hlbihhbGwoYXJyYXlfbWFwKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHdoZW4ocHJvbWlzZSwgbm9vcCwgbm9vcCk7XG4gICAgICAgIH0pKSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VzO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYWxsUmVzb2x2ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFsbFJlc29sdmVkKHRoaXMpO1xufTtcblxuLyoqXG4gKiBAc2VlIFByb21pc2UjYWxsU2V0dGxlZFxuICovXG5RLmFsbFNldHRsZWQgPSBhbGxTZXR0bGVkO1xuZnVuY3Rpb24gYWxsU2V0dGxlZChwcm9taXNlcykge1xuICAgIHJldHVybiBRKHByb21pc2VzKS5hbGxTZXR0bGVkKCk7XG59XG5cbi8qKlxuICogVHVybnMgYW4gYXJyYXkgb2YgcHJvbWlzZXMgaW50byBhIHByb21pc2UgZm9yIGFuIGFycmF5IG9mIHRoZWlyIHN0YXRlcyAoYXNcbiAqIHJldHVybmVkIGJ5IGBpbnNwZWN0YCkgd2hlbiB0aGV5IGhhdmUgYWxsIHNldHRsZWQuXG4gKiBAcGFyYW0ge0FycmF5W0FueSpdfSB2YWx1ZXMgYW4gYXJyYXkgKG9yIHByb21pc2UgZm9yIGFuIGFycmF5KSBvZiB2YWx1ZXMgKG9yXG4gKiBwcm9taXNlcyBmb3IgdmFsdWVzKVxuICogQHJldHVybnMge0FycmF5W1N0YXRlXX0gYW4gYXJyYXkgb2Ygc3RhdGVzIGZvciB0aGUgcmVzcGVjdGl2ZSB2YWx1ZXMuXG4gKi9cblByb21pc2UucHJvdG90eXBlLmFsbFNldHRsZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgcmV0dXJuIGFsbChhcnJheV9tYXAocHJvbWlzZXMsIGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgICAgICBwcm9taXNlID0gUShwcm9taXNlKTtcbiAgICAgICAgICAgIGZ1bmN0aW9uIHJlZ2FyZGxlc3MoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2UuaW5zcGVjdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHByb21pc2UudGhlbihyZWdhcmRsZXNzLCByZWdhcmRsZXNzKTtcbiAgICAgICAgfSkpO1xuICAgIH0pO1xufTtcblxuLyoqXG4gKiBDYXB0dXJlcyB0aGUgZmFpbHVyZSBvZiBhIHByb21pc2UsIGdpdmluZyBhbiBvcG9ydHVuaXR5IHRvIHJlY292ZXJcbiAqIHdpdGggYSBjYWxsYmFjay4gIElmIHRoZSBnaXZlbiBwcm9taXNlIGlzIGZ1bGZpbGxlZCwgdGhlIHJldHVybmVkXG4gKiBwcm9taXNlIGlzIGZ1bGZpbGxlZC5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBmb3Igc29tZXRoaW5nXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byBmdWxmaWxsIHRoZSByZXR1cm5lZCBwcm9taXNlIGlmIHRoZVxuICogZ2l2ZW4gcHJvbWlzZSBpcyByZWplY3RlZFxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBjYWxsYmFja1xuICovXG5RLmZhaWwgPSAvLyBYWFggbGVnYWN5XG5RW1wiY2F0Y2hcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCByZWplY3RlZCkge1xuICAgIHJldHVybiBRKG9iamVjdCkudGhlbih2b2lkIDAsIHJlamVjdGVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZhaWwgPSAvLyBYWFggbGVnYWN5XG5Qcm9taXNlLnByb3RvdHlwZVtcImNhdGNoXCJdID0gZnVuY3Rpb24gKHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbih2b2lkIDAsIHJlamVjdGVkKTtcbn07XG5cbi8qKlxuICogQXR0YWNoZXMgYSBsaXN0ZW5lciB0aGF0IGNhbiByZXNwb25kIHRvIHByb2dyZXNzIG5vdGlmaWNhdGlvbnMgZnJvbSBhXG4gKiBwcm9taXNlJ3Mgb3JpZ2luYXRpbmcgZGVmZXJyZWQuIFRoaXMgbGlzdGVuZXIgcmVjZWl2ZXMgdGhlIGV4YWN0IGFyZ3VtZW50c1xuICogcGFzc2VkIHRvIGBgZGVmZXJyZWQubm90aWZ5YGAuXG4gKiBAcGFyYW0ge0FueSp9IHByb21pc2UgZm9yIHNvbWV0aGluZ1xuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgdG8gcmVjZWl2ZSBhbnkgcHJvZ3Jlc3Mgbm90aWZpY2F0aW9uc1xuICogQHJldHVybnMgdGhlIGdpdmVuIHByb21pc2UsIHVuY2hhbmdlZFxuICovXG5RLnByb2dyZXNzID0gcHJvZ3Jlc3M7XG5mdW5jdGlvbiBwcm9ncmVzcyhvYmplY3QsIHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLnRoZW4odm9pZCAwLCB2b2lkIDAsIHByb2dyZXNzZWQpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5wcm9ncmVzcyA9IGZ1bmN0aW9uIChwcm9ncmVzc2VkKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbih2b2lkIDAsIHZvaWQgMCwgcHJvZ3Jlc3NlZCk7XG59O1xuXG4vKipcbiAqIFByb3ZpZGVzIGFuIG9wcG9ydHVuaXR5IHRvIG9ic2VydmUgdGhlIHNldHRsaW5nIG9mIGEgcHJvbWlzZSxcbiAqIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGUgcHJvbWlzZSBpcyBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuICBGb3J3YXJkc1xuICogdGhlIHJlc29sdXRpb24gdG8gdGhlIHJldHVybmVkIHByb21pc2Ugd2hlbiB0aGUgY2FsbGJhY2sgaXMgZG9uZS5cbiAqIFRoZSBjYWxsYmFjayBjYW4gcmV0dXJuIGEgcHJvbWlzZSB0byBkZWZlciBjb21wbGV0aW9uLlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byBvYnNlcnZlIHRoZSByZXNvbHV0aW9uIG9mIHRoZSBnaXZlblxuICogcHJvbWlzZSwgdGFrZXMgbm8gYXJndW1lbnRzLlxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSB3aGVuXG4gKiBgYGZpbmBgIGlzIGRvbmUuXG4gKi9cblEuZmluID0gLy8gWFhYIGxlZ2FjeVxuUVtcImZpbmFsbHlcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCBjYWxsYmFjaykge1xuICAgIHJldHVybiBRKG9iamVjdClbXCJmaW5hbGx5XCJdKGNhbGxiYWNrKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZpbiA9IC8vIFhYWCBsZWdhY3lcblByb21pc2UucHJvdG90eXBlW1wiZmluYWxseVwiXSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIGlmICghY2FsbGJhY2sgfHwgdHlwZW9mIGNhbGxiYWNrLmFwcGx5ICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUSBjYW4ndCBhcHBseSBmaW5hbGx5IGNhbGxiYWNrXCIpO1xuICAgIH1cbiAgICBjYWxsYmFjayA9IFEoY2FsbGJhY2spO1xuICAgIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBjYWxsYmFjay5mY2FsbCgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9KTtcbiAgICB9LCBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgICAgIC8vIFRPRE8gYXR0ZW1wdCB0byByZWN5Y2xlIHRoZSByZWplY3Rpb24gd2l0aCBcInRoaXNcIi5cbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmZjYWxsKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0aHJvdyByZWFzb247XG4gICAgICAgIH0pO1xuICAgIH0pO1xufTtcblxuLyoqXG4gKiBUZXJtaW5hdGVzIGEgY2hhaW4gb2YgcHJvbWlzZXMsIGZvcmNpbmcgcmVqZWN0aW9ucyB0byBiZVxuICogdGhyb3duIGFzIGV4Y2VwdGlvbnMuXG4gKiBAcGFyYW0ge0FueSp9IHByb21pc2UgYXQgdGhlIGVuZCBvZiBhIGNoYWluIG9mIHByb21pc2VzXG4gKiBAcmV0dXJucyBub3RoaW5nXG4gKi9cblEuZG9uZSA9IGZ1bmN0aW9uIChvYmplY3QsIGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kb25lKGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmRvbmUgPSBmdW5jdGlvbiAoZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpIHtcbiAgICB2YXIgb25VbmhhbmRsZWRFcnJvciA9IGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICAvLyBmb3J3YXJkIHRvIGEgZnV0dXJlIHR1cm4gc28gdGhhdCBgYHdoZW5gYFxuICAgICAgICAvLyBkb2VzIG5vdCBjYXRjaCBpdCBhbmQgdHVybiBpdCBpbnRvIGEgcmVqZWN0aW9uLlxuICAgICAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIG1ha2VTdGFja1RyYWNlTG9uZyhlcnJvciwgcHJvbWlzZSk7XG4gICAgICAgICAgICBpZiAoUS5vbmVycm9yKSB7XG4gICAgICAgICAgICAgICAgUS5vbmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvLyBBdm9pZCB1bm5lY2Vzc2FyeSBgbmV4dFRpY2tgaW5nIHZpYSBhbiB1bm5lY2Vzc2FyeSBgd2hlbmAuXG4gICAgdmFyIHByb21pc2UgPSBmdWxmaWxsZWQgfHwgcmVqZWN0ZWQgfHwgcHJvZ3Jlc3MgP1xuICAgICAgICB0aGlzLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpIDpcbiAgICAgICAgdGhpcztcblxuICAgIGlmICh0eXBlb2YgcHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJiBwcm9jZXNzICYmIHByb2Nlc3MuZG9tYWluKSB7XG4gICAgICAgIG9uVW5oYW5kbGVkRXJyb3IgPSBwcm9jZXNzLmRvbWFpbi5iaW5kKG9uVW5oYW5kbGVkRXJyb3IpO1xuICAgIH1cblxuICAgIHByb21pc2UudGhlbih2b2lkIDAsIG9uVW5oYW5kbGVkRXJyb3IpO1xufTtcblxuLyoqXG4gKiBDYXVzZXMgYSBwcm9taXNlIHRvIGJlIHJlamVjdGVkIGlmIGl0IGRvZXMgbm90IGdldCBmdWxmaWxsZWQgYmVmb3JlXG4gKiBzb21lIG1pbGxpc2Vjb25kcyB0aW1lIG91dC5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZVxuICogQHBhcmFtIHtOdW1iZXJ9IG1pbGxpc2Vjb25kcyB0aW1lb3V0XG4gKiBAcGFyYW0ge0FueSp9IGN1c3RvbSBlcnJvciBtZXNzYWdlIG9yIEVycm9yIG9iamVjdCAob3B0aW9uYWwpXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXNvbHV0aW9uIG9mIHRoZSBnaXZlbiBwcm9taXNlIGlmIGl0IGlzXG4gKiBmdWxmaWxsZWQgYmVmb3JlIHRoZSB0aW1lb3V0LCBvdGhlcndpc2UgcmVqZWN0ZWQuXG4gKi9cblEudGltZW91dCA9IGZ1bmN0aW9uIChvYmplY3QsIG1zLCBlcnJvcikge1xuICAgIHJldHVybiBRKG9iamVjdCkudGltZW91dChtcywgZXJyb3IpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUudGltZW91dCA9IGZ1bmN0aW9uIChtcywgZXJyb3IpIHtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIHZhciB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCFlcnJvciB8fCBcInN0cmluZ1wiID09PSB0eXBlb2YgZXJyb3IpIHtcbiAgICAgICAgICAgIGVycm9yID0gbmV3IEVycm9yKGVycm9yIHx8IFwiVGltZWQgb3V0IGFmdGVyIFwiICsgbXMgKyBcIiBtc1wiKTtcbiAgICAgICAgICAgIGVycm9yLmNvZGUgPSBcIkVUSU1FRE9VVFwiO1xuICAgICAgICB9XG4gICAgICAgIGRlZmVycmVkLnJlamVjdChlcnJvcik7XG4gICAgfSwgbXMpO1xuXG4gICAgdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICAgICAgZGVmZXJyZWQucmVzb2x2ZSh2YWx1ZSk7XG4gICAgfSwgZnVuY3Rpb24gKGV4Y2VwdGlvbikge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICAgICAgZGVmZXJyZWQucmVqZWN0KGV4Y2VwdGlvbik7XG4gICAgfSwgZGVmZXJyZWQubm90aWZ5KTtcblxuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIGdpdmVuIHZhbHVlIChvciBwcm9taXNlZCB2YWx1ZSksIHNvbWVcbiAqIG1pbGxpc2Vjb25kcyBhZnRlciBpdCByZXNvbHZlZC4gUGFzc2VzIHJlamVjdGlvbnMgaW1tZWRpYXRlbHkuXG4gKiBAcGFyYW0ge0FueSp9IHByb21pc2VcbiAqIEBwYXJhbSB7TnVtYmVyfSBtaWxsaXNlY29uZHNcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2UgYWZ0ZXIgbWlsbGlzZWNvbmRzXG4gKiB0aW1lIGhhcyBlbGFwc2VkIHNpbmNlIHRoZSByZXNvbHV0aW9uIG9mIHRoZSBnaXZlbiBwcm9taXNlLlxuICogSWYgdGhlIGdpdmVuIHByb21pc2UgcmVqZWN0cywgdGhhdCBpcyBwYXNzZWQgaW1tZWRpYXRlbHkuXG4gKi9cblEuZGVsYXkgPSBmdW5jdGlvbiAob2JqZWN0LCB0aW1lb3V0KSB7XG4gICAgaWYgKHRpbWVvdXQgPT09IHZvaWQgMCkge1xuICAgICAgICB0aW1lb3V0ID0gb2JqZWN0O1xuICAgICAgICBvYmplY3QgPSB2b2lkIDA7XG4gICAgfVxuICAgIHJldHVybiBRKG9iamVjdCkuZGVsYXkodGltZW91dCk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5kZWxheSA9IGZ1bmN0aW9uICh0aW1lb3V0KSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgfSwgdGltZW91dCk7XG4gICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgIH0pO1xufTtcblxuLyoqXG4gKiBQYXNzZXMgYSBjb250aW51YXRpb24gdG8gYSBOb2RlIGZ1bmN0aW9uLCB3aGljaCBpcyBjYWxsZWQgd2l0aCB0aGUgZ2l2ZW5cbiAqIGFyZ3VtZW50cyBwcm92aWRlZCBhcyBhbiBhcnJheSwgYW5kIHJldHVybnMgYSBwcm9taXNlLlxuICpcbiAqICAgICAgUS5uZmFwcGx5KEZTLnJlYWRGaWxlLCBbX19maWxlbmFtZV0pXG4gKiAgICAgIC50aGVuKGZ1bmN0aW9uIChjb250ZW50KSB7XG4gKiAgICAgIH0pXG4gKlxuICovXG5RLm5mYXBwbHkgPSBmdW5jdGlvbiAoY2FsbGJhY2ssIGFyZ3MpIHtcbiAgICByZXR1cm4gUShjYWxsYmFjaykubmZhcHBseShhcmdzKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLm5mYXBwbHkgPSBmdW5jdGlvbiAoYXJncykge1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgdmFyIG5vZGVBcmdzID0gYXJyYXlfc2xpY2UoYXJncyk7XG4gICAgbm9kZUFyZ3MucHVzaChkZWZlcnJlZC5tYWtlTm9kZVJlc29sdmVyKCkpO1xuICAgIHRoaXMuZmFwcGx5KG5vZGVBcmdzKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIFBhc3NlcyBhIGNvbnRpbnVhdGlvbiB0byBhIE5vZGUgZnVuY3Rpb24sIHdoaWNoIGlzIGNhbGxlZCB3aXRoIHRoZSBnaXZlblxuICogYXJndW1lbnRzIHByb3ZpZGVkIGluZGl2aWR1YWxseSwgYW5kIHJldHVybnMgYSBwcm9taXNlLlxuICogQGV4YW1wbGVcbiAqIFEubmZjYWxsKEZTLnJlYWRGaWxlLCBfX2ZpbGVuYW1lKVxuICogLnRoZW4oZnVuY3Rpb24gKGNvbnRlbnQpIHtcbiAqIH0pXG4gKlxuICovXG5RLm5mY2FsbCA9IGZ1bmN0aW9uIChjYWxsYmFjayAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gUShjYWxsYmFjaykubmZhcHBseShhcmdzKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLm5mY2FsbCA9IGZ1bmN0aW9uICgvKi4uLmFyZ3MqLykge1xuICAgIHZhciBub2RlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cyk7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgdGhpcy5mYXBwbHkobm9kZUFyZ3MpLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogV3JhcHMgYSBOb2RlSlMgY29udGludWF0aW9uIHBhc3NpbmcgZnVuY3Rpb24gYW5kIHJldHVybnMgYW4gZXF1aXZhbGVudFxuICogdmVyc2lvbiB0aGF0IHJldHVybnMgYSBwcm9taXNlLlxuICogQGV4YW1wbGVcbiAqIFEubmZiaW5kKEZTLnJlYWRGaWxlLCBfX2ZpbGVuYW1lKShcInV0Zi04XCIpXG4gKiAudGhlbihjb25zb2xlLmxvZylcbiAqIC5kb25lKClcbiAqL1xuUS5uZmJpbmQgPVxuUS5kZW5vZGVpZnkgPSBmdW5jdGlvbiAoY2FsbGJhY2sgLyouLi5hcmdzKi8pIHtcbiAgICBpZiAoY2FsbGJhY2sgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJRIGNhbid0IHdyYXAgYW4gdW5kZWZpbmVkIGZ1bmN0aW9uXCIpO1xuICAgIH1cbiAgICB2YXIgYmFzZUFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBub2RlQXJncyA9IGJhc2VBcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKTtcbiAgICAgICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICAgICAgbm9kZUFyZ3MucHVzaChkZWZlcnJlZC5tYWtlTm9kZVJlc29sdmVyKCkpO1xuICAgICAgICBRKGNhbGxiYWNrKS5mYXBwbHkobm9kZUFyZ3MpLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgfTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLm5mYmluZCA9XG5Qcm9taXNlLnByb3RvdHlwZS5kZW5vZGVpZnkgPSBmdW5jdGlvbiAoLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgYXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cyk7XG4gICAgYXJncy51bnNoaWZ0KHRoaXMpO1xuICAgIHJldHVybiBRLmRlbm9kZWlmeS5hcHBseSh2b2lkIDAsIGFyZ3MpO1xufTtcblxuUS5uYmluZCA9IGZ1bmN0aW9uIChjYWxsYmFjaywgdGhpc3AgLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgYmFzZUFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDIpO1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBub2RlQXJncyA9IGJhc2VBcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKTtcbiAgICAgICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICAgICAgbm9kZUFyZ3MucHVzaChkZWZlcnJlZC5tYWtlTm9kZVJlc29sdmVyKCkpO1xuICAgICAgICBmdW5jdGlvbiBib3VuZCgpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjay5hcHBseSh0aGlzcCwgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgICAgICBRKGJvdW5kKS5mYXBwbHkobm9kZUFyZ3MpLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgfTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLm5iaW5kID0gZnVuY3Rpb24gKC8qdGhpc3AsIC4uLmFyZ3MqLykge1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAwKTtcbiAgICBhcmdzLnVuc2hpZnQodGhpcyk7XG4gICAgcmV0dXJuIFEubmJpbmQuYXBwbHkodm9pZCAwLCBhcmdzKTtcbn07XG5cbi8qKlxuICogQ2FsbHMgYSBtZXRob2Qgb2YgYSBOb2RlLXN0eWxlIG9iamVjdCB0aGF0IGFjY2VwdHMgYSBOb2RlLXN0eWxlXG4gKiBjYWxsYmFjayB3aXRoIGEgZ2l2ZW4gYXJyYXkgb2YgYXJndW1lbnRzLCBwbHVzIGEgcHJvdmlkZWQgY2FsbGJhY2suXG4gKiBAcGFyYW0gb2JqZWN0IGFuIG9iamVjdCB0aGF0IGhhcyB0aGUgbmFtZWQgbWV0aG9kXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBuYW1lIG9mIHRoZSBtZXRob2Qgb2Ygb2JqZWN0XG4gKiBAcGFyYW0ge0FycmF5fSBhcmdzIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBtZXRob2Q7IHRoZSBjYWxsYmFja1xuICogd2lsbCBiZSBwcm92aWRlZCBieSBRIGFuZCBhcHBlbmRlZCB0byB0aGVzZSBhcmd1bWVudHMuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSB2YWx1ZSBvciBlcnJvclxuICovXG5RLm5tYXBwbHkgPSAvLyBYWFggQXMgcHJvcG9zZWQgYnkgXCJSZWRzYW5kcm9cIlxuUS5ucG9zdCA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUsIGFyZ3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLm5wb3N0KG5hbWUsIGFyZ3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubm1hcHBseSA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5Qcm9taXNlLnByb3RvdHlwZS5ucG9zdCA9IGZ1bmN0aW9uIChuYW1lLCBhcmdzKSB7XG4gICAgdmFyIG5vZGVBcmdzID0gYXJyYXlfc2xpY2UoYXJncyB8fCBbXSk7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgdGhpcy5kaXNwYXRjaChcInBvc3RcIiwgW25hbWUsIG5vZGVBcmdzXSkuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuLyoqXG4gKiBDYWxscyBhIG1ldGhvZCBvZiBhIE5vZGUtc3R5bGUgb2JqZWN0IHRoYXQgYWNjZXB0cyBhIE5vZGUtc3R5bGVcbiAqIGNhbGxiYWNrLCBmb3J3YXJkaW5nIHRoZSBnaXZlbiB2YXJpYWRpYyBhcmd1bWVudHMsIHBsdXMgYSBwcm92aWRlZFxuICogY2FsbGJhY2sgYXJndW1lbnQuXG4gKiBAcGFyYW0gb2JqZWN0IGFuIG9iamVjdCB0aGF0IGhhcyB0aGUgbmFtZWQgbWV0aG9kXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBuYW1lIG9mIHRoZSBtZXRob2Qgb2Ygb2JqZWN0XG4gKiBAcGFyYW0gLi4uYXJncyBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgbWV0aG9kOyB0aGUgY2FsbGJhY2sgd2lsbFxuICogYmUgcHJvdmlkZWQgYnkgUSBhbmQgYXBwZW5kZWQgdG8gdGhlc2UgYXJndW1lbnRzLlxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgdmFsdWUgb3IgZXJyb3JcbiAqL1xuUS5uc2VuZCA9IC8vIFhYWCBCYXNlZCBvbiBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIFwic2VuZFwiXG5RLm5tY2FsbCA9IC8vIFhYWCBCYXNlZCBvbiBcIlJlZHNhbmRybydzXCIgcHJvcG9zYWxcblEubmludm9rZSA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDIpO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgbm9kZUFyZ3MucHVzaChkZWZlcnJlZC5tYWtlTm9kZVJlc29sdmVyKCkpO1xuICAgIFEob2JqZWN0KS5kaXNwYXRjaChcInBvc3RcIiwgW25hbWUsIG5vZGVBcmdzXSkuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubnNlbmQgPSAvLyBYWFggQmFzZWQgb24gTWFyayBNaWxsZXIncyBwcm9wb3NlZCBcInNlbmRcIlxuUHJvbWlzZS5wcm90b3R5cGUubm1jYWxsID0gLy8gWFhYIEJhc2VkIG9uIFwiUmVkc2FuZHJvJ3NcIiBwcm9wb3NhbFxuUHJvbWlzZS5wcm90b3R5cGUubmludm9rZSA9IGZ1bmN0aW9uIChuYW1lIC8qLi4uYXJncyovKSB7XG4gICAgdmFyIG5vZGVBcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgbm9kZUFyZ3NdKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIElmIGEgZnVuY3Rpb24gd291bGQgbGlrZSB0byBzdXBwb3J0IGJvdGggTm9kZSBjb250aW51YXRpb24tcGFzc2luZy1zdHlsZSBhbmRcbiAqIHByb21pc2UtcmV0dXJuaW5nLXN0eWxlLCBpdCBjYW4gZW5kIGl0cyBpbnRlcm5hbCBwcm9taXNlIGNoYWluIHdpdGhcbiAqIGBub2RlaWZ5KG5vZGViYWNrKWAsIGZvcndhcmRpbmcgdGhlIG9wdGlvbmFsIG5vZGViYWNrIGFyZ3VtZW50LiAgSWYgdGhlIHVzZXJcbiAqIGVsZWN0cyB0byB1c2UgYSBub2RlYmFjaywgdGhlIHJlc3VsdCB3aWxsIGJlIHNlbnQgdGhlcmUuICBJZiB0aGV5IGRvIG5vdFxuICogcGFzcyBhIG5vZGViYWNrLCB0aGV5IHdpbGwgcmVjZWl2ZSB0aGUgcmVzdWx0IHByb21pc2UuXG4gKiBAcGFyYW0gb2JqZWN0IGEgcmVzdWx0IChvciBhIHByb21pc2UgZm9yIGEgcmVzdWx0KVxuICogQHBhcmFtIHtGdW5jdGlvbn0gbm9kZWJhY2sgYSBOb2RlLmpzLXN0eWxlIGNhbGxiYWNrXG4gKiBAcmV0dXJucyBlaXRoZXIgdGhlIHByb21pc2Ugb3Igbm90aGluZ1xuICovXG5RLm5vZGVpZnkgPSBub2RlaWZ5O1xuZnVuY3Rpb24gbm9kZWlmeShvYmplY3QsIG5vZGViYWNrKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5ub2RlaWZ5KG5vZGViYWNrKTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUubm9kZWlmeSA9IGZ1bmN0aW9uIChub2RlYmFjaykge1xuICAgIGlmIChub2RlYmFjaykge1xuICAgICAgICB0aGlzLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBub2RlYmFjayhudWxsLCB2YWx1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBub2RlYmFjayhlcnJvcik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufTtcblxuUS5ub0NvbmZsaWN0ID0gZnVuY3Rpb24oKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiUS5ub0NvbmZsaWN0IG9ubHkgd29ya3Mgd2hlbiBRIGlzIHVzZWQgYXMgYSBnbG9iYWxcIik7XG59O1xuXG4vLyBBbGwgY29kZSBiZWZvcmUgdGhpcyBwb2ludCB3aWxsIGJlIGZpbHRlcmVkIGZyb20gc3RhY2sgdHJhY2VzLlxudmFyIHFFbmRpbmdMaW5lID0gY2FwdHVyZUxpbmUoKTtcblxucmV0dXJuIFE7XG5cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgcmVwbGFjZSA9IFN0cmluZy5wcm90b3R5cGUucmVwbGFjZTtcbnZhciBwZXJjZW50VHdlbnRpZXMgPSAvJTIwL2c7XG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi91dGlscycpO1xuXG52YXIgRm9ybWF0ID0ge1xuICAgIFJGQzE3Mzg6ICdSRkMxNzM4JyxcbiAgICBSRkMzOTg2OiAnUkZDMzk4Nidcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gdXRpbC5hc3NpZ24oXG4gICAge1xuICAgICAgICAnZGVmYXVsdCc6IEZvcm1hdC5SRkMzOTg2LFxuICAgICAgICBmb3JtYXR0ZXJzOiB7XG4gICAgICAgICAgICBSRkMxNzM4OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVwbGFjZS5jYWxsKHZhbHVlLCBwZXJjZW50VHdlbnRpZXMsICcrJyk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgUkZDMzk4NjogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFN0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuICAgIEZvcm1hdFxuKTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHN0cmluZ2lmeSA9IHJlcXVpcmUoJy4vc3RyaW5naWZ5Jyk7XG52YXIgcGFyc2UgPSByZXF1aXJlKCcuL3BhcnNlJyk7XG52YXIgZm9ybWF0cyA9IHJlcXVpcmUoJy4vZm9ybWF0cycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBmb3JtYXRzOiBmb3JtYXRzLFxuICAgIHBhcnNlOiBwYXJzZSxcbiAgICBzdHJpbmdpZnk6IHN0cmluZ2lmeVxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xuXG52YXIgaGFzID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheTtcblxudmFyIGRlZmF1bHRzID0ge1xuICAgIGFsbG93RG90czogZmFsc2UsXG4gICAgYWxsb3dQcm90b3R5cGVzOiBmYWxzZSxcbiAgICBhcnJheUxpbWl0OiAyMCxcbiAgICBjaGFyc2V0OiAndXRmLTgnLFxuICAgIGNoYXJzZXRTZW50aW5lbDogZmFsc2UsXG4gICAgY29tbWE6IGZhbHNlLFxuICAgIGRlY29kZXI6IHV0aWxzLmRlY29kZSxcbiAgICBkZWxpbWl0ZXI6ICcmJyxcbiAgICBkZXB0aDogNSxcbiAgICBpZ25vcmVRdWVyeVByZWZpeDogZmFsc2UsXG4gICAgaW50ZXJwcmV0TnVtZXJpY0VudGl0aWVzOiBmYWxzZSxcbiAgICBwYXJhbWV0ZXJMaW1pdDogMTAwMCxcbiAgICBwYXJzZUFycmF5czogdHJ1ZSxcbiAgICBwbGFpbk9iamVjdHM6IGZhbHNlLFxuICAgIHN0cmljdE51bGxIYW5kbGluZzogZmFsc2Vcbn07XG5cbnZhciBpbnRlcnByZXROdW1lcmljRW50aXRpZXMgPSBmdW5jdGlvbiAoc3RyKSB7XG4gICAgcmV0dXJuIHN0ci5yZXBsYWNlKC8mIyhcXGQrKTsvZywgZnVuY3Rpb24gKCQwLCBudW1iZXJTdHIpIHtcbiAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUocGFyc2VJbnQobnVtYmVyU3RyLCAxMCkpO1xuICAgIH0pO1xufTtcblxudmFyIHBhcnNlQXJyYXlWYWx1ZSA9IGZ1bmN0aW9uICh2YWwsIG9wdGlvbnMpIHtcbiAgICBpZiAodmFsICYmIHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnICYmIG9wdGlvbnMuY29tbWEgJiYgdmFsLmluZGV4T2YoJywnKSA+IC0xKSB7XG4gICAgICAgIHJldHVybiB2YWwuc3BsaXQoJywnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsO1xufTtcblxudmFyIG1heWJlTWFwID0gZnVuY3Rpb24gbWF5YmVNYXAodmFsLCBmbikge1xuICAgIGlmIChpc0FycmF5KHZhbCkpIHtcbiAgICAgICAgdmFyIG1hcHBlZCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbC5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgbWFwcGVkLnB1c2goZm4odmFsW2ldKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1hcHBlZDtcbiAgICB9XG4gICAgcmV0dXJuIGZuKHZhbCk7XG59O1xuXG4vLyBUaGlzIGlzIHdoYXQgYnJvd3NlcnMgd2lsbCBzdWJtaXQgd2hlbiB0aGUg4pyTIGNoYXJhY3RlciBvY2N1cnMgaW4gYW5cbi8vIGFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCBib2R5IGFuZCB0aGUgZW5jb2Rpbmcgb2YgdGhlIHBhZ2UgY29udGFpbmluZ1xuLy8gdGhlIGZvcm0gaXMgaXNvLTg4NTktMSwgb3Igd2hlbiB0aGUgc3VibWl0dGVkIGZvcm0gaGFzIGFuIGFjY2VwdC1jaGFyc2V0XG4vLyBhdHRyaWJ1dGUgb2YgaXNvLTg4NTktMS4gUHJlc3VtYWJseSBhbHNvIHdpdGggb3RoZXIgY2hhcnNldHMgdGhhdCBkbyBub3QgY29udGFpblxuLy8gdGhlIOKckyBjaGFyYWN0ZXIsIHN1Y2ggYXMgdXMtYXNjaWkuXG52YXIgaXNvU2VudGluZWwgPSAndXRmOD0lMjYlMjMxMDAwMyUzQic7IC8vIGVuY29kZVVSSUNvbXBvbmVudCgnJiMxMDAwMzsnKVxuXG4vLyBUaGVzZSBhcmUgdGhlIHBlcmNlbnQtZW5jb2RlZCB1dGYtOCBvY3RldHMgcmVwcmVzZW50aW5nIGEgY2hlY2ttYXJrLCBpbmRpY2F0aW5nIHRoYXQgdGhlIHJlcXVlc3QgYWN0dWFsbHkgaXMgdXRmLTggZW5jb2RlZC5cbnZhciBjaGFyc2V0U2VudGluZWwgPSAndXRmOD0lRTIlOUMlOTMnOyAvLyBlbmNvZGVVUklDb21wb25lbnQoJ+KckycpXG5cbnZhciBwYXJzZVZhbHVlcyA9IGZ1bmN0aW9uIHBhcnNlUXVlcnlTdHJpbmdWYWx1ZXMoc3RyLCBvcHRpb25zKSB7XG4gICAgdmFyIG9iaiA9IHt9O1xuICAgIHZhciBjbGVhblN0ciA9IG9wdGlvbnMuaWdub3JlUXVlcnlQcmVmaXggPyBzdHIucmVwbGFjZSgvXlxcPy8sICcnKSA6IHN0cjtcbiAgICB2YXIgbGltaXQgPSBvcHRpb25zLnBhcmFtZXRlckxpbWl0ID09PSBJbmZpbml0eSA/IHVuZGVmaW5lZCA6IG9wdGlvbnMucGFyYW1ldGVyTGltaXQ7XG4gICAgdmFyIHBhcnRzID0gY2xlYW5TdHIuc3BsaXQob3B0aW9ucy5kZWxpbWl0ZXIsIGxpbWl0KTtcbiAgICB2YXIgc2tpcEluZGV4ID0gLTE7IC8vIEtlZXAgdHJhY2sgb2Ygd2hlcmUgdGhlIHV0Zjggc2VudGluZWwgd2FzIGZvdW5kXG4gICAgdmFyIGk7XG5cbiAgICB2YXIgY2hhcnNldCA9IG9wdGlvbnMuY2hhcnNldDtcbiAgICBpZiAob3B0aW9ucy5jaGFyc2V0U2VudGluZWwpIHtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBpZiAocGFydHNbaV0uaW5kZXhPZigndXRmOD0nKSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGlmIChwYXJ0c1tpXSA9PT0gY2hhcnNldFNlbnRpbmVsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYXJzZXQgPSAndXRmLTgnO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocGFydHNbaV0gPT09IGlzb1NlbnRpbmVsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYXJzZXQgPSAnaXNvLTg4NTktMSc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNraXBJbmRleCA9IGk7XG4gICAgICAgICAgICAgICAgaSA9IHBhcnRzLmxlbmd0aDsgLy8gVGhlIGVzbGludCBzZXR0aW5ncyBkbyBub3QgYWxsb3cgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgaWYgKGkgPT09IHNraXBJbmRleCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHBhcnQgPSBwYXJ0c1tpXTtcblxuICAgICAgICB2YXIgYnJhY2tldEVxdWFsc1BvcyA9IHBhcnQuaW5kZXhPZignXT0nKTtcbiAgICAgICAgdmFyIHBvcyA9IGJyYWNrZXRFcXVhbHNQb3MgPT09IC0xID8gcGFydC5pbmRleE9mKCc9JykgOiBicmFja2V0RXF1YWxzUG9zICsgMTtcblxuICAgICAgICB2YXIga2V5LCB2YWw7XG4gICAgICAgIGlmIChwb3MgPT09IC0xKSB7XG4gICAgICAgICAgICBrZXkgPSBvcHRpb25zLmRlY29kZXIocGFydCwgZGVmYXVsdHMuZGVjb2RlciwgY2hhcnNldCwgJ2tleScpO1xuICAgICAgICAgICAgdmFsID0gb3B0aW9ucy5zdHJpY3ROdWxsSGFuZGxpbmcgPyBudWxsIDogJyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBrZXkgPSBvcHRpb25zLmRlY29kZXIocGFydC5zbGljZSgwLCBwb3MpLCBkZWZhdWx0cy5kZWNvZGVyLCBjaGFyc2V0LCAna2V5Jyk7XG4gICAgICAgICAgICB2YWwgPSBtYXliZU1hcChcbiAgICAgICAgICAgICAgICBwYXJzZUFycmF5VmFsdWUocGFydC5zbGljZShwb3MgKyAxKSwgb3B0aW9ucyksXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gKGVuY29kZWRWYWwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnMuZGVjb2RlcihlbmNvZGVkVmFsLCBkZWZhdWx0cy5kZWNvZGVyLCBjaGFyc2V0LCAndmFsdWUnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZhbCAmJiBvcHRpb25zLmludGVycHJldE51bWVyaWNFbnRpdGllcyAmJiBjaGFyc2V0ID09PSAnaXNvLTg4NTktMScpIHtcbiAgICAgICAgICAgIHZhbCA9IGludGVycHJldE51bWVyaWNFbnRpdGllcyh2YWwpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhcnQuaW5kZXhPZignW109JykgPiAtMSkge1xuICAgICAgICAgICAgdmFsID0gaXNBcnJheSh2YWwpID8gW3ZhbF0gOiB2YWw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaGFzLmNhbGwob2JqLCBrZXkpKSB7XG4gICAgICAgICAgICBvYmpba2V5XSA9IHV0aWxzLmNvbWJpbmUob2JqW2tleV0sIHZhbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBvYmpba2V5XSA9IHZhbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvYmo7XG59O1xuXG52YXIgcGFyc2VPYmplY3QgPSBmdW5jdGlvbiAoY2hhaW4sIHZhbCwgb3B0aW9ucywgdmFsdWVzUGFyc2VkKSB7XG4gICAgdmFyIGxlYWYgPSB2YWx1ZXNQYXJzZWQgPyB2YWwgOiBwYXJzZUFycmF5VmFsdWUodmFsLCBvcHRpb25zKTtcblxuICAgIGZvciAodmFyIGkgPSBjaGFpbi5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICB2YXIgb2JqO1xuICAgICAgICB2YXIgcm9vdCA9IGNoYWluW2ldO1xuXG4gICAgICAgIGlmIChyb290ID09PSAnW10nICYmIG9wdGlvbnMucGFyc2VBcnJheXMpIHtcbiAgICAgICAgICAgIG9iaiA9IFtdLmNvbmNhdChsZWFmKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG9iaiA9IG9wdGlvbnMucGxhaW5PYmplY3RzID8gT2JqZWN0LmNyZWF0ZShudWxsKSA6IHt9O1xuICAgICAgICAgICAgdmFyIGNsZWFuUm9vdCA9IHJvb3QuY2hhckF0KDApID09PSAnWycgJiYgcm9vdC5jaGFyQXQocm9vdC5sZW5ndGggLSAxKSA9PT0gJ10nID8gcm9vdC5zbGljZSgxLCAtMSkgOiByb290O1xuICAgICAgICAgICAgdmFyIGluZGV4ID0gcGFyc2VJbnQoY2xlYW5Sb290LCAxMCk7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMucGFyc2VBcnJheXMgJiYgY2xlYW5Sb290ID09PSAnJykge1xuICAgICAgICAgICAgICAgIG9iaiA9IHsgMDogbGVhZiB9O1xuICAgICAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgICAgICAhaXNOYU4oaW5kZXgpXG4gICAgICAgICAgICAgICAgJiYgcm9vdCAhPT0gY2xlYW5Sb290XG4gICAgICAgICAgICAgICAgJiYgU3RyaW5nKGluZGV4KSA9PT0gY2xlYW5Sb290XG4gICAgICAgICAgICAgICAgJiYgaW5kZXggPj0gMFxuICAgICAgICAgICAgICAgICYmIChvcHRpb25zLnBhcnNlQXJyYXlzICYmIGluZGV4IDw9IG9wdGlvbnMuYXJyYXlMaW1pdClcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIG9iaiA9IFtdO1xuICAgICAgICAgICAgICAgIG9ialtpbmRleF0gPSBsZWFmO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBvYmpbY2xlYW5Sb290XSA9IGxlYWY7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsZWFmID0gb2JqOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG4gICAgfVxuXG4gICAgcmV0dXJuIGxlYWY7XG59O1xuXG52YXIgcGFyc2VLZXlzID0gZnVuY3Rpb24gcGFyc2VRdWVyeVN0cmluZ0tleXMoZ2l2ZW5LZXksIHZhbCwgb3B0aW9ucywgdmFsdWVzUGFyc2VkKSB7XG4gICAgaWYgKCFnaXZlbktleSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gVHJhbnNmb3JtIGRvdCBub3RhdGlvbiB0byBicmFja2V0IG5vdGF0aW9uXG4gICAgdmFyIGtleSA9IG9wdGlvbnMuYWxsb3dEb3RzID8gZ2l2ZW5LZXkucmVwbGFjZSgvXFwuKFteLltdKykvZywgJ1skMV0nKSA6IGdpdmVuS2V5O1xuXG4gICAgLy8gVGhlIHJlZ2V4IGNodW5rc1xuXG4gICAgdmFyIGJyYWNrZXRzID0gLyhcXFtbXltcXF1dKl0pLztcbiAgICB2YXIgY2hpbGQgPSAvKFxcW1teW1xcXV0qXSkvZztcblxuICAgIC8vIEdldCB0aGUgcGFyZW50XG5cbiAgICB2YXIgc2VnbWVudCA9IG9wdGlvbnMuZGVwdGggPiAwICYmIGJyYWNrZXRzLmV4ZWMoa2V5KTtcbiAgICB2YXIgcGFyZW50ID0gc2VnbWVudCA/IGtleS5zbGljZSgwLCBzZWdtZW50LmluZGV4KSA6IGtleTtcblxuICAgIC8vIFN0YXNoIHRoZSBwYXJlbnQgaWYgaXQgZXhpc3RzXG5cbiAgICB2YXIga2V5cyA9IFtdO1xuICAgIGlmIChwYXJlbnQpIHtcbiAgICAgICAgLy8gSWYgd2UgYXJlbid0IHVzaW5nIHBsYWluIG9iamVjdHMsIG9wdGlvbmFsbHkgcHJlZml4IGtleXMgdGhhdCB3b3VsZCBvdmVyd3JpdGUgb2JqZWN0IHByb3RvdHlwZSBwcm9wZXJ0aWVzXG4gICAgICAgIGlmICghb3B0aW9ucy5wbGFpbk9iamVjdHMgJiYgaGFzLmNhbGwoT2JqZWN0LnByb3RvdHlwZSwgcGFyZW50KSkge1xuICAgICAgICAgICAgaWYgKCFvcHRpb25zLmFsbG93UHJvdG90eXBlcykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGtleXMucHVzaChwYXJlbnQpO1xuICAgIH1cblxuICAgIC8vIExvb3AgdGhyb3VnaCBjaGlsZHJlbiBhcHBlbmRpbmcgdG8gdGhlIGFycmF5IHVudGlsIHdlIGhpdCBkZXB0aFxuXG4gICAgdmFyIGkgPSAwO1xuICAgIHdoaWxlIChvcHRpb25zLmRlcHRoID4gMCAmJiAoc2VnbWVudCA9IGNoaWxkLmV4ZWMoa2V5KSkgIT09IG51bGwgJiYgaSA8IG9wdGlvbnMuZGVwdGgpIHtcbiAgICAgICAgaSArPSAxO1xuICAgICAgICBpZiAoIW9wdGlvbnMucGxhaW5PYmplY3RzICYmIGhhcy5jYWxsKE9iamVjdC5wcm90b3R5cGUsIHNlZ21lbnRbMV0uc2xpY2UoMSwgLTEpKSkge1xuICAgICAgICAgICAgaWYgKCFvcHRpb25zLmFsbG93UHJvdG90eXBlcykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBrZXlzLnB1c2goc2VnbWVudFsxXSk7XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlcmUncyBhIHJlbWFpbmRlciwganVzdCBhZGQgd2hhdGV2ZXIgaXMgbGVmdFxuXG4gICAgaWYgKHNlZ21lbnQpIHtcbiAgICAgICAga2V5cy5wdXNoKCdbJyArIGtleS5zbGljZShzZWdtZW50LmluZGV4KSArICddJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhcnNlT2JqZWN0KGtleXMsIHZhbCwgb3B0aW9ucywgdmFsdWVzUGFyc2VkKTtcbn07XG5cbnZhciBub3JtYWxpemVQYXJzZU9wdGlvbnMgPSBmdW5jdGlvbiBub3JtYWxpemVQYXJzZU9wdGlvbnMob3B0cykge1xuICAgIGlmICghb3B0cykge1xuICAgICAgICByZXR1cm4gZGVmYXVsdHM7XG4gICAgfVxuXG4gICAgaWYgKG9wdHMuZGVjb2RlciAhPT0gbnVsbCAmJiBvcHRzLmRlY29kZXIgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb3B0cy5kZWNvZGVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0RlY29kZXIgaGFzIHRvIGJlIGEgZnVuY3Rpb24uJyk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRzLmNoYXJzZXQgIT09ICd1bmRlZmluZWQnICYmIG9wdHMuY2hhcnNldCAhPT0gJ3V0Zi04JyAmJiBvcHRzLmNoYXJzZXQgIT09ICdpc28tODg1OS0xJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgY2hhcnNldCBvcHRpb24gbXVzdCBiZSBlaXRoZXIgdXRmLTgsIGlzby04ODU5LTEsIG9yIHVuZGVmaW5lZCcpO1xuICAgIH1cbiAgICB2YXIgY2hhcnNldCA9IHR5cGVvZiBvcHRzLmNoYXJzZXQgPT09ICd1bmRlZmluZWQnID8gZGVmYXVsdHMuY2hhcnNldCA6IG9wdHMuY2hhcnNldDtcblxuICAgIHJldHVybiB7XG4gICAgICAgIGFsbG93RG90czogdHlwZW9mIG9wdHMuYWxsb3dEb3RzID09PSAndW5kZWZpbmVkJyA/IGRlZmF1bHRzLmFsbG93RG90cyA6ICEhb3B0cy5hbGxvd0RvdHMsXG4gICAgICAgIGFsbG93UHJvdG90eXBlczogdHlwZW9mIG9wdHMuYWxsb3dQcm90b3R5cGVzID09PSAnYm9vbGVhbicgPyBvcHRzLmFsbG93UHJvdG90eXBlcyA6IGRlZmF1bHRzLmFsbG93UHJvdG90eXBlcyxcbiAgICAgICAgYXJyYXlMaW1pdDogdHlwZW9mIG9wdHMuYXJyYXlMaW1pdCA9PT0gJ251bWJlcicgPyBvcHRzLmFycmF5TGltaXQgOiBkZWZhdWx0cy5hcnJheUxpbWl0LFxuICAgICAgICBjaGFyc2V0OiBjaGFyc2V0LFxuICAgICAgICBjaGFyc2V0U2VudGluZWw6IHR5cGVvZiBvcHRzLmNoYXJzZXRTZW50aW5lbCA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5jaGFyc2V0U2VudGluZWwgOiBkZWZhdWx0cy5jaGFyc2V0U2VudGluZWwsXG4gICAgICAgIGNvbW1hOiB0eXBlb2Ygb3B0cy5jb21tYSA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5jb21tYSA6IGRlZmF1bHRzLmNvbW1hLFxuICAgICAgICBkZWNvZGVyOiB0eXBlb2Ygb3B0cy5kZWNvZGVyID09PSAnZnVuY3Rpb24nID8gb3B0cy5kZWNvZGVyIDogZGVmYXVsdHMuZGVjb2RlcixcbiAgICAgICAgZGVsaW1pdGVyOiB0eXBlb2Ygb3B0cy5kZWxpbWl0ZXIgPT09ICdzdHJpbmcnIHx8IHV0aWxzLmlzUmVnRXhwKG9wdHMuZGVsaW1pdGVyKSA/IG9wdHMuZGVsaW1pdGVyIDogZGVmYXVsdHMuZGVsaW1pdGVyLFxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8taW1wbGljaXQtY29lcmNpb24sIG5vLWV4dHJhLXBhcmVuc1xuICAgICAgICBkZXB0aDogKHR5cGVvZiBvcHRzLmRlcHRoID09PSAnbnVtYmVyJyB8fCBvcHRzLmRlcHRoID09PSBmYWxzZSkgPyArb3B0cy5kZXB0aCA6IGRlZmF1bHRzLmRlcHRoLFxuICAgICAgICBpZ25vcmVRdWVyeVByZWZpeDogb3B0cy5pZ25vcmVRdWVyeVByZWZpeCA9PT0gdHJ1ZSxcbiAgICAgICAgaW50ZXJwcmV0TnVtZXJpY0VudGl0aWVzOiB0eXBlb2Ygb3B0cy5pbnRlcnByZXROdW1lcmljRW50aXRpZXMgPT09ICdib29sZWFuJyA/IG9wdHMuaW50ZXJwcmV0TnVtZXJpY0VudGl0aWVzIDogZGVmYXVsdHMuaW50ZXJwcmV0TnVtZXJpY0VudGl0aWVzLFxuICAgICAgICBwYXJhbWV0ZXJMaW1pdDogdHlwZW9mIG9wdHMucGFyYW1ldGVyTGltaXQgPT09ICdudW1iZXInID8gb3B0cy5wYXJhbWV0ZXJMaW1pdCA6IGRlZmF1bHRzLnBhcmFtZXRlckxpbWl0LFxuICAgICAgICBwYXJzZUFycmF5czogb3B0cy5wYXJzZUFycmF5cyAhPT0gZmFsc2UsXG4gICAgICAgIHBsYWluT2JqZWN0czogdHlwZW9mIG9wdHMucGxhaW5PYmplY3RzID09PSAnYm9vbGVhbicgPyBvcHRzLnBsYWluT2JqZWN0cyA6IGRlZmF1bHRzLnBsYWluT2JqZWN0cyxcbiAgICAgICAgc3RyaWN0TnVsbEhhbmRsaW5nOiB0eXBlb2Ygb3B0cy5zdHJpY3ROdWxsSGFuZGxpbmcgPT09ICdib29sZWFuJyA/IG9wdHMuc3RyaWN0TnVsbEhhbmRsaW5nIDogZGVmYXVsdHMuc3RyaWN0TnVsbEhhbmRsaW5nXG4gICAgfTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHN0ciwgb3B0cykge1xuICAgIHZhciBvcHRpb25zID0gbm9ybWFsaXplUGFyc2VPcHRpb25zKG9wdHMpO1xuXG4gICAgaWYgKHN0ciA9PT0gJycgfHwgc3RyID09PSBudWxsIHx8IHR5cGVvZiBzdHIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHJldHVybiBvcHRpb25zLnBsYWluT2JqZWN0cyA/IE9iamVjdC5jcmVhdGUobnVsbCkgOiB7fTtcbiAgICB9XG5cbiAgICB2YXIgdGVtcE9iaiA9IHR5cGVvZiBzdHIgPT09ICdzdHJpbmcnID8gcGFyc2VWYWx1ZXMoc3RyLCBvcHRpb25zKSA6IHN0cjtcbiAgICB2YXIgb2JqID0gb3B0aW9ucy5wbGFpbk9iamVjdHMgPyBPYmplY3QuY3JlYXRlKG51bGwpIDoge307XG5cbiAgICAvLyBJdGVyYXRlIG92ZXIgdGhlIGtleXMgYW5kIHNldHVwIHRoZSBuZXcgb2JqZWN0XG5cbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHRlbXBPYmopO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgdmFyIG5ld09iaiA9IHBhcnNlS2V5cyhrZXksIHRlbXBPYmpba2V5XSwgb3B0aW9ucywgdHlwZW9mIHN0ciA9PT0gJ3N0cmluZycpO1xuICAgICAgICBvYmogPSB1dGlscy5tZXJnZShvYmosIG5ld09iaiwgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHV0aWxzLmNvbXBhY3Qob2JqKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbnZhciBmb3JtYXRzID0gcmVxdWlyZSgnLi9mb3JtYXRzJyk7XG52YXIgaGFzID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxudmFyIGFycmF5UHJlZml4R2VuZXJhdG9ycyA9IHtcbiAgICBicmFja2V0czogZnVuY3Rpb24gYnJhY2tldHMocHJlZml4KSB7XG4gICAgICAgIHJldHVybiBwcmVmaXggKyAnW10nO1xuICAgIH0sXG4gICAgY29tbWE6ICdjb21tYScsXG4gICAgaW5kaWNlczogZnVuY3Rpb24gaW5kaWNlcyhwcmVmaXgsIGtleSkge1xuICAgICAgICByZXR1cm4gcHJlZml4ICsgJ1snICsga2V5ICsgJ10nO1xuICAgIH0sXG4gICAgcmVwZWF0OiBmdW5jdGlvbiByZXBlYXQocHJlZml4KSB7XG4gICAgICAgIHJldHVybiBwcmVmaXg7XG4gICAgfVxufTtcblxudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xudmFyIHB1c2ggPSBBcnJheS5wcm90b3R5cGUucHVzaDtcbnZhciBwdXNoVG9BcnJheSA9IGZ1bmN0aW9uIChhcnIsIHZhbHVlT3JBcnJheSkge1xuICAgIHB1c2guYXBwbHkoYXJyLCBpc0FycmF5KHZhbHVlT3JBcnJheSkgPyB2YWx1ZU9yQXJyYXkgOiBbdmFsdWVPckFycmF5XSk7XG59O1xuXG52YXIgdG9JU08gPSBEYXRlLnByb3RvdHlwZS50b0lTT1N0cmluZztcblxudmFyIGRlZmF1bHRGb3JtYXQgPSBmb3JtYXRzWydkZWZhdWx0J107XG52YXIgZGVmYXVsdHMgPSB7XG4gICAgYWRkUXVlcnlQcmVmaXg6IGZhbHNlLFxuICAgIGFsbG93RG90czogZmFsc2UsXG4gICAgY2hhcnNldDogJ3V0Zi04JyxcbiAgICBjaGFyc2V0U2VudGluZWw6IGZhbHNlLFxuICAgIGRlbGltaXRlcjogJyYnLFxuICAgIGVuY29kZTogdHJ1ZSxcbiAgICBlbmNvZGVyOiB1dGlscy5lbmNvZGUsXG4gICAgZW5jb2RlVmFsdWVzT25seTogZmFsc2UsXG4gICAgZm9ybWF0OiBkZWZhdWx0Rm9ybWF0LFxuICAgIGZvcm1hdHRlcjogZm9ybWF0cy5mb3JtYXR0ZXJzW2RlZmF1bHRGb3JtYXRdLFxuICAgIC8vIGRlcHJlY2F0ZWRcbiAgICBpbmRpY2VzOiBmYWxzZSxcbiAgICBzZXJpYWxpemVEYXRlOiBmdW5jdGlvbiBzZXJpYWxpemVEYXRlKGRhdGUpIHtcbiAgICAgICAgcmV0dXJuIHRvSVNPLmNhbGwoZGF0ZSk7XG4gICAgfSxcbiAgICBza2lwTnVsbHM6IGZhbHNlLFxuICAgIHN0cmljdE51bGxIYW5kbGluZzogZmFsc2Vcbn07XG5cbnZhciBpc05vbk51bGxpc2hQcmltaXRpdmUgPSBmdW5jdGlvbiBpc05vbk51bGxpc2hQcmltaXRpdmUodikge1xuICAgIHJldHVybiB0eXBlb2YgdiA9PT0gJ3N0cmluZydcbiAgICAgICAgfHwgdHlwZW9mIHYgPT09ICdudW1iZXInXG4gICAgICAgIHx8IHR5cGVvZiB2ID09PSAnYm9vbGVhbidcbiAgICAgICAgfHwgdHlwZW9mIHYgPT09ICdzeW1ib2wnXG4gICAgICAgIHx8IHR5cGVvZiB2ID09PSAnYmlnaW50Jztcbn07XG5cbnZhciBzdHJpbmdpZnkgPSBmdW5jdGlvbiBzdHJpbmdpZnkoXG4gICAgb2JqZWN0LFxuICAgIHByZWZpeCxcbiAgICBnZW5lcmF0ZUFycmF5UHJlZml4LFxuICAgIHN0cmljdE51bGxIYW5kbGluZyxcbiAgICBza2lwTnVsbHMsXG4gICAgZW5jb2RlcixcbiAgICBmaWx0ZXIsXG4gICAgc29ydCxcbiAgICBhbGxvd0RvdHMsXG4gICAgc2VyaWFsaXplRGF0ZSxcbiAgICBmb3JtYXR0ZXIsXG4gICAgZW5jb2RlVmFsdWVzT25seSxcbiAgICBjaGFyc2V0XG4pIHtcbiAgICB2YXIgb2JqID0gb2JqZWN0O1xuICAgIGlmICh0eXBlb2YgZmlsdGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIG9iaiA9IGZpbHRlcihwcmVmaXgsIG9iaik7XG4gICAgfSBlbHNlIGlmIChvYmogaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgIG9iaiA9IHNlcmlhbGl6ZURhdGUob2JqKTtcbiAgICB9IGVsc2UgaWYgKGdlbmVyYXRlQXJyYXlQcmVmaXggPT09ICdjb21tYScgJiYgaXNBcnJheShvYmopKSB7XG4gICAgICAgIG9iaiA9IG9iai5qb2luKCcsJyk7XG4gICAgfVxuXG4gICAgaWYgKG9iaiA9PT0gbnVsbCkge1xuICAgICAgICBpZiAoc3RyaWN0TnVsbEhhbmRsaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gZW5jb2RlciAmJiAhZW5jb2RlVmFsdWVzT25seSA/IGVuY29kZXIocHJlZml4LCBkZWZhdWx0cy5lbmNvZGVyLCBjaGFyc2V0LCAna2V5JykgOiBwcmVmaXg7XG4gICAgICAgIH1cblxuICAgICAgICBvYmogPSAnJztcbiAgICB9XG5cbiAgICBpZiAoaXNOb25OdWxsaXNoUHJpbWl0aXZlKG9iaikgfHwgdXRpbHMuaXNCdWZmZXIob2JqKSkge1xuICAgICAgICBpZiAoZW5jb2Rlcikge1xuICAgICAgICAgICAgdmFyIGtleVZhbHVlID0gZW5jb2RlVmFsdWVzT25seSA/IHByZWZpeCA6IGVuY29kZXIocHJlZml4LCBkZWZhdWx0cy5lbmNvZGVyLCBjaGFyc2V0LCAna2V5Jyk7XG4gICAgICAgICAgICByZXR1cm4gW2Zvcm1hdHRlcihrZXlWYWx1ZSkgKyAnPScgKyBmb3JtYXR0ZXIoZW5jb2RlcihvYmosIGRlZmF1bHRzLmVuY29kZXIsIGNoYXJzZXQsICd2YWx1ZScpKV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtmb3JtYXR0ZXIocHJlZml4KSArICc9JyArIGZvcm1hdHRlcihTdHJpbmcob2JqKSldO1xuICAgIH1cblxuICAgIHZhciB2YWx1ZXMgPSBbXTtcblxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gdmFsdWVzO1xuICAgIH1cblxuICAgIHZhciBvYmpLZXlzO1xuICAgIGlmIChpc0FycmF5KGZpbHRlcikpIHtcbiAgICAgICAgb2JqS2V5cyA9IGZpbHRlcjtcbiAgICB9IGVsc2Uge1xuICAgICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iaik7XG4gICAgICAgIG9iaktleXMgPSBzb3J0ID8ga2V5cy5zb3J0KHNvcnQpIDoga2V5cztcbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iaktleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIGtleSA9IG9iaktleXNbaV07XG5cbiAgICAgICAgaWYgKHNraXBOdWxscyAmJiBvYmpba2V5XSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNBcnJheShvYmopKSB7XG4gICAgICAgICAgICBwdXNoVG9BcnJheSh2YWx1ZXMsIHN0cmluZ2lmeShcbiAgICAgICAgICAgICAgICBvYmpba2V5XSxcbiAgICAgICAgICAgICAgICB0eXBlb2YgZ2VuZXJhdGVBcnJheVByZWZpeCA9PT0gJ2Z1bmN0aW9uJyA/IGdlbmVyYXRlQXJyYXlQcmVmaXgocHJlZml4LCBrZXkpIDogcHJlZml4LFxuICAgICAgICAgICAgICAgIGdlbmVyYXRlQXJyYXlQcmVmaXgsXG4gICAgICAgICAgICAgICAgc3RyaWN0TnVsbEhhbmRsaW5nLFxuICAgICAgICAgICAgICAgIHNraXBOdWxscyxcbiAgICAgICAgICAgICAgICBlbmNvZGVyLFxuICAgICAgICAgICAgICAgIGZpbHRlcixcbiAgICAgICAgICAgICAgICBzb3J0LFxuICAgICAgICAgICAgICAgIGFsbG93RG90cyxcbiAgICAgICAgICAgICAgICBzZXJpYWxpemVEYXRlLFxuICAgICAgICAgICAgICAgIGZvcm1hdHRlcixcbiAgICAgICAgICAgICAgICBlbmNvZGVWYWx1ZXNPbmx5LFxuICAgICAgICAgICAgICAgIGNoYXJzZXRcbiAgICAgICAgICAgICkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcHVzaFRvQXJyYXkodmFsdWVzLCBzdHJpbmdpZnkoXG4gICAgICAgICAgICAgICAgb2JqW2tleV0sXG4gICAgICAgICAgICAgICAgcHJlZml4ICsgKGFsbG93RG90cyA/ICcuJyArIGtleSA6ICdbJyArIGtleSArICddJyksXG4gICAgICAgICAgICAgICAgZ2VuZXJhdGVBcnJheVByZWZpeCxcbiAgICAgICAgICAgICAgICBzdHJpY3ROdWxsSGFuZGxpbmcsXG4gICAgICAgICAgICAgICAgc2tpcE51bGxzLFxuICAgICAgICAgICAgICAgIGVuY29kZXIsXG4gICAgICAgICAgICAgICAgZmlsdGVyLFxuICAgICAgICAgICAgICAgIHNvcnQsXG4gICAgICAgICAgICAgICAgYWxsb3dEb3RzLFxuICAgICAgICAgICAgICAgIHNlcmlhbGl6ZURhdGUsXG4gICAgICAgICAgICAgICAgZm9ybWF0dGVyLFxuICAgICAgICAgICAgICAgIGVuY29kZVZhbHVlc09ubHksXG4gICAgICAgICAgICAgICAgY2hhcnNldFxuICAgICAgICAgICAgKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWVzO1xufTtcblxudmFyIG5vcm1hbGl6ZVN0cmluZ2lmeU9wdGlvbnMgPSBmdW5jdGlvbiBub3JtYWxpemVTdHJpbmdpZnlPcHRpb25zKG9wdHMpIHtcbiAgICBpZiAoIW9wdHMpIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRzO1xuICAgIH1cblxuICAgIGlmIChvcHRzLmVuY29kZXIgIT09IG51bGwgJiYgb3B0cy5lbmNvZGVyICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIG9wdHMuZW5jb2RlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdFbmNvZGVyIGhhcyB0byBiZSBhIGZ1bmN0aW9uLicpO1xuICAgIH1cblxuICAgIHZhciBjaGFyc2V0ID0gb3B0cy5jaGFyc2V0IHx8IGRlZmF1bHRzLmNoYXJzZXQ7XG4gICAgaWYgKHR5cGVvZiBvcHRzLmNoYXJzZXQgIT09ICd1bmRlZmluZWQnICYmIG9wdHMuY2hhcnNldCAhPT0gJ3V0Zi04JyAmJiBvcHRzLmNoYXJzZXQgIT09ICdpc28tODg1OS0xJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgY2hhcnNldCBvcHRpb24gbXVzdCBiZSBlaXRoZXIgdXRmLTgsIGlzby04ODU5LTEsIG9yIHVuZGVmaW5lZCcpO1xuICAgIH1cblxuICAgIHZhciBmb3JtYXQgPSBmb3JtYXRzWydkZWZhdWx0J107XG4gICAgaWYgKHR5cGVvZiBvcHRzLmZvcm1hdCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKCFoYXMuY2FsbChmb3JtYXRzLmZvcm1hdHRlcnMsIG9wdHMuZm9ybWF0KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBmb3JtYXQgb3B0aW9uIHByb3ZpZGVkLicpO1xuICAgICAgICB9XG4gICAgICAgIGZvcm1hdCA9IG9wdHMuZm9ybWF0O1xuICAgIH1cbiAgICB2YXIgZm9ybWF0dGVyID0gZm9ybWF0cy5mb3JtYXR0ZXJzW2Zvcm1hdF07XG5cbiAgICB2YXIgZmlsdGVyID0gZGVmYXVsdHMuZmlsdGVyO1xuICAgIGlmICh0eXBlb2Ygb3B0cy5maWx0ZXIgPT09ICdmdW5jdGlvbicgfHwgaXNBcnJheShvcHRzLmZpbHRlcikpIHtcbiAgICAgICAgZmlsdGVyID0gb3B0cy5maWx0ZXI7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgYWRkUXVlcnlQcmVmaXg6IHR5cGVvZiBvcHRzLmFkZFF1ZXJ5UHJlZml4ID09PSAnYm9vbGVhbicgPyBvcHRzLmFkZFF1ZXJ5UHJlZml4IDogZGVmYXVsdHMuYWRkUXVlcnlQcmVmaXgsXG4gICAgICAgIGFsbG93RG90czogdHlwZW9mIG9wdHMuYWxsb3dEb3RzID09PSAndW5kZWZpbmVkJyA/IGRlZmF1bHRzLmFsbG93RG90cyA6ICEhb3B0cy5hbGxvd0RvdHMsXG4gICAgICAgIGNoYXJzZXQ6IGNoYXJzZXQsXG4gICAgICAgIGNoYXJzZXRTZW50aW5lbDogdHlwZW9mIG9wdHMuY2hhcnNldFNlbnRpbmVsID09PSAnYm9vbGVhbicgPyBvcHRzLmNoYXJzZXRTZW50aW5lbCA6IGRlZmF1bHRzLmNoYXJzZXRTZW50aW5lbCxcbiAgICAgICAgZGVsaW1pdGVyOiB0eXBlb2Ygb3B0cy5kZWxpbWl0ZXIgPT09ICd1bmRlZmluZWQnID8gZGVmYXVsdHMuZGVsaW1pdGVyIDogb3B0cy5kZWxpbWl0ZXIsXG4gICAgICAgIGVuY29kZTogdHlwZW9mIG9wdHMuZW5jb2RlID09PSAnYm9vbGVhbicgPyBvcHRzLmVuY29kZSA6IGRlZmF1bHRzLmVuY29kZSxcbiAgICAgICAgZW5jb2RlcjogdHlwZW9mIG9wdHMuZW5jb2RlciA9PT0gJ2Z1bmN0aW9uJyA/IG9wdHMuZW5jb2RlciA6IGRlZmF1bHRzLmVuY29kZXIsXG4gICAgICAgIGVuY29kZVZhbHVlc09ubHk6IHR5cGVvZiBvcHRzLmVuY29kZVZhbHVlc09ubHkgPT09ICdib29sZWFuJyA/IG9wdHMuZW5jb2RlVmFsdWVzT25seSA6IGRlZmF1bHRzLmVuY29kZVZhbHVlc09ubHksXG4gICAgICAgIGZpbHRlcjogZmlsdGVyLFxuICAgICAgICBmb3JtYXR0ZXI6IGZvcm1hdHRlcixcbiAgICAgICAgc2VyaWFsaXplRGF0ZTogdHlwZW9mIG9wdHMuc2VyaWFsaXplRGF0ZSA9PT0gJ2Z1bmN0aW9uJyA/IG9wdHMuc2VyaWFsaXplRGF0ZSA6IGRlZmF1bHRzLnNlcmlhbGl6ZURhdGUsXG4gICAgICAgIHNraXBOdWxsczogdHlwZW9mIG9wdHMuc2tpcE51bGxzID09PSAnYm9vbGVhbicgPyBvcHRzLnNraXBOdWxscyA6IGRlZmF1bHRzLnNraXBOdWxscyxcbiAgICAgICAgc29ydDogdHlwZW9mIG9wdHMuc29ydCA9PT0gJ2Z1bmN0aW9uJyA/IG9wdHMuc29ydCA6IG51bGwsXG4gICAgICAgIHN0cmljdE51bGxIYW5kbGluZzogdHlwZW9mIG9wdHMuc3RyaWN0TnVsbEhhbmRsaW5nID09PSAnYm9vbGVhbicgPyBvcHRzLnN0cmljdE51bGxIYW5kbGluZyA6IGRlZmF1bHRzLnN0cmljdE51bGxIYW5kbGluZ1xuICAgIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmplY3QsIG9wdHMpIHtcbiAgICB2YXIgb2JqID0gb2JqZWN0O1xuICAgIHZhciBvcHRpb25zID0gbm9ybWFsaXplU3RyaW5naWZ5T3B0aW9ucyhvcHRzKTtcblxuICAgIHZhciBvYmpLZXlzO1xuICAgIHZhciBmaWx0ZXI7XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuZmlsdGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGZpbHRlciA9IG9wdGlvbnMuZmlsdGVyO1xuICAgICAgICBvYmogPSBmaWx0ZXIoJycsIG9iaik7XG4gICAgfSBlbHNlIGlmIChpc0FycmF5KG9wdGlvbnMuZmlsdGVyKSkge1xuICAgICAgICBmaWx0ZXIgPSBvcHRpb25zLmZpbHRlcjtcbiAgICAgICAgb2JqS2V5cyA9IGZpbHRlcjtcbiAgICB9XG5cbiAgICB2YXIga2V5cyA9IFtdO1xuXG4gICAgaWYgKHR5cGVvZiBvYmogIT09ICdvYmplY3QnIHx8IG9iaiA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgdmFyIGFycmF5Rm9ybWF0O1xuICAgIGlmIChvcHRzICYmIG9wdHMuYXJyYXlGb3JtYXQgaW4gYXJyYXlQcmVmaXhHZW5lcmF0b3JzKSB7XG4gICAgICAgIGFycmF5Rm9ybWF0ID0gb3B0cy5hcnJheUZvcm1hdDtcbiAgICB9IGVsc2UgaWYgKG9wdHMgJiYgJ2luZGljZXMnIGluIG9wdHMpIHtcbiAgICAgICAgYXJyYXlGb3JtYXQgPSBvcHRzLmluZGljZXMgPyAnaW5kaWNlcycgOiAncmVwZWF0JztcbiAgICB9IGVsc2Uge1xuICAgICAgICBhcnJheUZvcm1hdCA9ICdpbmRpY2VzJztcbiAgICB9XG5cbiAgICB2YXIgZ2VuZXJhdGVBcnJheVByZWZpeCA9IGFycmF5UHJlZml4R2VuZXJhdG9yc1thcnJheUZvcm1hdF07XG5cbiAgICBpZiAoIW9iaktleXMpIHtcbiAgICAgICAgb2JqS2V5cyA9IE9iamVjdC5rZXlzKG9iaik7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuc29ydCkge1xuICAgICAgICBvYmpLZXlzLnNvcnQob3B0aW9ucy5zb3J0KTtcbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iaktleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIGtleSA9IG9iaktleXNbaV07XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuc2tpcE51bGxzICYmIG9ialtrZXldID09PSBudWxsKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBwdXNoVG9BcnJheShrZXlzLCBzdHJpbmdpZnkoXG4gICAgICAgICAgICBvYmpba2V5XSxcbiAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgIGdlbmVyYXRlQXJyYXlQcmVmaXgsXG4gICAgICAgICAgICBvcHRpb25zLnN0cmljdE51bGxIYW5kbGluZyxcbiAgICAgICAgICAgIG9wdGlvbnMuc2tpcE51bGxzLFxuICAgICAgICAgICAgb3B0aW9ucy5lbmNvZGUgPyBvcHRpb25zLmVuY29kZXIgOiBudWxsLFxuICAgICAgICAgICAgb3B0aW9ucy5maWx0ZXIsXG4gICAgICAgICAgICBvcHRpb25zLnNvcnQsXG4gICAgICAgICAgICBvcHRpb25zLmFsbG93RG90cyxcbiAgICAgICAgICAgIG9wdGlvbnMuc2VyaWFsaXplRGF0ZSxcbiAgICAgICAgICAgIG9wdGlvbnMuZm9ybWF0dGVyLFxuICAgICAgICAgICAgb3B0aW9ucy5lbmNvZGVWYWx1ZXNPbmx5LFxuICAgICAgICAgICAgb3B0aW9ucy5jaGFyc2V0XG4gICAgICAgICkpO1xuICAgIH1cblxuICAgIHZhciBqb2luZWQgPSBrZXlzLmpvaW4ob3B0aW9ucy5kZWxpbWl0ZXIpO1xuICAgIHZhciBwcmVmaXggPSBvcHRpb25zLmFkZFF1ZXJ5UHJlZml4ID09PSB0cnVlID8gJz8nIDogJyc7XG5cbiAgICBpZiAob3B0aW9ucy5jaGFyc2V0U2VudGluZWwpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuY2hhcnNldCA9PT0gJ2lzby04ODU5LTEnKSB7XG4gICAgICAgICAgICAvLyBlbmNvZGVVUklDb21wb25lbnQoJyYjMTAwMDM7JyksIHRoZSBcIm51bWVyaWMgZW50aXR5XCIgcmVwcmVzZW50YXRpb24gb2YgYSBjaGVja21hcmtcbiAgICAgICAgICAgIHByZWZpeCArPSAndXRmOD0lMjYlMjMxMDAwMyUzQiYnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gZW5jb2RlVVJJQ29tcG9uZW50KCfinJMnKVxuICAgICAgICAgICAgcHJlZml4ICs9ICd1dGY4PSVFMiU5QyU5MyYnO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGpvaW5lZC5sZW5ndGggPiAwID8gcHJlZml4ICsgam9pbmVkIDogJyc7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheTtcblxudmFyIGhleFRhYmxlID0gKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgYXJyYXkgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgKytpKSB7XG4gICAgICAgIGFycmF5LnB1c2goJyUnICsgKChpIDwgMTYgPyAnMCcgOiAnJykgKyBpLnRvU3RyaW5nKDE2KSkudG9VcHBlckNhc2UoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFycmF5O1xufSgpKTtcblxudmFyIGNvbXBhY3RRdWV1ZSA9IGZ1bmN0aW9uIGNvbXBhY3RRdWV1ZShxdWV1ZSkge1xuICAgIHdoaWxlIChxdWV1ZS5sZW5ndGggPiAxKSB7XG4gICAgICAgIHZhciBpdGVtID0gcXVldWUucG9wKCk7XG4gICAgICAgIHZhciBvYmogPSBpdGVtLm9ialtpdGVtLnByb3BdO1xuXG4gICAgICAgIGlmIChpc0FycmF5KG9iaikpIHtcbiAgICAgICAgICAgIHZhciBjb21wYWN0ZWQgPSBbXTtcblxuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBvYmoubGVuZ3RoOyArK2opIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9ialtqXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGFjdGVkLnB1c2gob2JqW2pdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGl0ZW0ub2JqW2l0ZW0ucHJvcF0gPSBjb21wYWN0ZWQ7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG52YXIgYXJyYXlUb09iamVjdCA9IGZ1bmN0aW9uIGFycmF5VG9PYmplY3Qoc291cmNlLCBvcHRpb25zKSB7XG4gICAgdmFyIG9iaiA9IG9wdGlvbnMgJiYgb3B0aW9ucy5wbGFpbk9iamVjdHMgPyBPYmplY3QuY3JlYXRlKG51bGwpIDoge307XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzb3VyY2UubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBzb3VyY2VbaV0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBvYmpbaV0gPSBzb3VyY2VbaV07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb2JqO1xufTtcblxudmFyIG1lcmdlID0gZnVuY3Rpb24gbWVyZ2UodGFyZ2V0LCBzb3VyY2UsIG9wdGlvbnMpIHtcbiAgICAvKiBlc2xpbnQgbm8tcGFyYW0tcmVhc3NpZ246IDAgKi9cbiAgICBpZiAoIXNvdXJjZSkge1xuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygc291cmNlICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBpZiAoaXNBcnJheSh0YXJnZXQpKSB7XG4gICAgICAgICAgICB0YXJnZXQucHVzaChzb3VyY2UpO1xuICAgICAgICB9IGVsc2UgaWYgKHRhcmdldCAmJiB0eXBlb2YgdGFyZ2V0ID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgaWYgKChvcHRpb25zICYmIChvcHRpb25zLnBsYWluT2JqZWN0cyB8fCBvcHRpb25zLmFsbG93UHJvdG90eXBlcykpIHx8ICFoYXMuY2FsbChPYmplY3QucHJvdG90eXBlLCBzb3VyY2UpKSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0W3NvdXJjZV0gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFt0YXJnZXQsIHNvdXJjZV07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cblxuICAgIGlmICghdGFyZ2V0IHx8IHR5cGVvZiB0YXJnZXQgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBbdGFyZ2V0XS5jb25jYXQoc291cmNlKTtcbiAgICB9XG5cbiAgICB2YXIgbWVyZ2VUYXJnZXQgPSB0YXJnZXQ7XG4gICAgaWYgKGlzQXJyYXkodGFyZ2V0KSAmJiAhaXNBcnJheShzb3VyY2UpKSB7XG4gICAgICAgIG1lcmdlVGFyZ2V0ID0gYXJyYXlUb09iamVjdCh0YXJnZXQsIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIGlmIChpc0FycmF5KHRhcmdldCkgJiYgaXNBcnJheShzb3VyY2UpKSB7XG4gICAgICAgIHNvdXJjZS5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtLCBpKSB7XG4gICAgICAgICAgICBpZiAoaGFzLmNhbGwodGFyZ2V0LCBpKSkge1xuICAgICAgICAgICAgICAgIHZhciB0YXJnZXRJdGVtID0gdGFyZ2V0W2ldO1xuICAgICAgICAgICAgICAgIGlmICh0YXJnZXRJdGVtICYmIHR5cGVvZiB0YXJnZXRJdGVtID09PSAnb2JqZWN0JyAmJiBpdGVtICYmIHR5cGVvZiBpdGVtID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXRbaV0gPSBtZXJnZSh0YXJnZXRJdGVtLCBpdGVtLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXQucHVzaChpdGVtKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRhcmdldFtpXSA9IGl0ZW07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cblxuICAgIHJldHVybiBPYmplY3Qua2V5cyhzb3VyY2UpLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBrZXkpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gc291cmNlW2tleV07XG5cbiAgICAgICAgaWYgKGhhcy5jYWxsKGFjYywga2V5KSkge1xuICAgICAgICAgICAgYWNjW2tleV0gPSBtZXJnZShhY2Nba2V5XSwgdmFsdWUsIG9wdGlvbnMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWNjW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWNjO1xuICAgIH0sIG1lcmdlVGFyZ2V0KTtcbn07XG5cbnZhciBhc3NpZ24gPSBmdW5jdGlvbiBhc3NpZ25TaW5nbGVTb3VyY2UodGFyZ2V0LCBzb3VyY2UpIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMoc291cmNlKS5yZWR1Y2UoZnVuY3Rpb24gKGFjYywga2V5KSB7XG4gICAgICAgIGFjY1trZXldID0gc291cmNlW2tleV07XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgfSwgdGFyZ2V0KTtcbn07XG5cbnZhciBkZWNvZGUgPSBmdW5jdGlvbiAoc3RyLCBkZWNvZGVyLCBjaGFyc2V0KSB7XG4gICAgdmFyIHN0cldpdGhvdXRQbHVzID0gc3RyLnJlcGxhY2UoL1xcKy9nLCAnICcpO1xuICAgIGlmIChjaGFyc2V0ID09PSAnaXNvLTg4NTktMScpIHtcbiAgICAgICAgLy8gdW5lc2NhcGUgbmV2ZXIgdGhyb3dzLCBubyB0cnkuLi5jYXRjaCBuZWVkZWQ6XG4gICAgICAgIHJldHVybiBzdHJXaXRob3V0UGx1cy5yZXBsYWNlKC8lWzAtOWEtZl17Mn0vZ2ksIHVuZXNjYXBlKTtcbiAgICB9XG4gICAgLy8gdXRmLThcbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KHN0cldpdGhvdXRQbHVzKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBzdHJXaXRob3V0UGx1cztcbiAgICB9XG59O1xuXG52YXIgZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKHN0ciwgZGVmYXVsdEVuY29kZXIsIGNoYXJzZXQpIHtcbiAgICAvLyBUaGlzIGNvZGUgd2FzIG9yaWdpbmFsbHkgd3JpdHRlbiBieSBCcmlhbiBXaGl0ZSAobXNjZGV4KSBmb3IgdGhlIGlvLmpzIGNvcmUgcXVlcnlzdHJpbmcgbGlicmFyeS5cbiAgICAvLyBJdCBoYXMgYmVlbiBhZGFwdGVkIGhlcmUgZm9yIHN0cmljdGVyIGFkaGVyZW5jZSB0byBSRkMgMzk4NlxuICAgIGlmIChzdHIubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuXG4gICAgdmFyIHN0cmluZyA9IHN0cjtcbiAgICBpZiAodHlwZW9mIHN0ciA9PT0gJ3N5bWJvbCcpIHtcbiAgICAgICAgc3RyaW5nID0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHN0cik7XG4gICAgfSBlbHNlIGlmICh0eXBlb2Ygc3RyICE9PSAnc3RyaW5nJykge1xuICAgICAgICBzdHJpbmcgPSBTdHJpbmcoc3RyKTtcbiAgICB9XG5cbiAgICBpZiAoY2hhcnNldCA9PT0gJ2lzby04ODU5LTEnKSB7XG4gICAgICAgIHJldHVybiBlc2NhcGUoc3RyaW5nKS5yZXBsYWNlKC8ldVswLTlhLWZdezR9L2dpLCBmdW5jdGlvbiAoJDApIHtcbiAgICAgICAgICAgIHJldHVybiAnJTI2JTIzJyArIHBhcnNlSW50KCQwLnNsaWNlKDIpLCAxNikgKyAnJTNCJztcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdmFyIG91dCA9ICcnO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyaW5nLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBjID0gc3RyaW5nLmNoYXJDb2RlQXQoaSk7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgYyA9PT0gMHgyRCAvLyAtXG4gICAgICAgICAgICB8fCBjID09PSAweDJFIC8vIC5cbiAgICAgICAgICAgIHx8IGMgPT09IDB4NUYgLy8gX1xuICAgICAgICAgICAgfHwgYyA9PT0gMHg3RSAvLyB+XG4gICAgICAgICAgICB8fCAoYyA+PSAweDMwICYmIGMgPD0gMHgzOSkgLy8gMC05XG4gICAgICAgICAgICB8fCAoYyA+PSAweDQxICYmIGMgPD0gMHg1QSkgLy8gYS16XG4gICAgICAgICAgICB8fCAoYyA+PSAweDYxICYmIGMgPD0gMHg3QSkgLy8gQS1aXG4gICAgICAgICkge1xuICAgICAgICAgICAgb3V0ICs9IHN0cmluZy5jaGFyQXQoaSk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjIDwgMHg4MCkge1xuICAgICAgICAgICAgb3V0ID0gb3V0ICsgaGV4VGFibGVbY107XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjIDwgMHg4MDApIHtcbiAgICAgICAgICAgIG91dCA9IG91dCArIChoZXhUYWJsZVsweEMwIHwgKGMgPj4gNildICsgaGV4VGFibGVbMHg4MCB8IChjICYgMHgzRildKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGMgPCAweEQ4MDAgfHwgYyA+PSAweEUwMDApIHtcbiAgICAgICAgICAgIG91dCA9IG91dCArIChoZXhUYWJsZVsweEUwIHwgKGMgPj4gMTIpXSArIGhleFRhYmxlWzB4ODAgfCAoKGMgPj4gNikgJiAweDNGKV0gKyBoZXhUYWJsZVsweDgwIHwgKGMgJiAweDNGKV0pO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBpICs9IDE7XG4gICAgICAgIGMgPSAweDEwMDAwICsgKCgoYyAmIDB4M0ZGKSA8PCAxMCkgfCAoc3RyaW5nLmNoYXJDb2RlQXQoaSkgJiAweDNGRikpO1xuICAgICAgICBvdXQgKz0gaGV4VGFibGVbMHhGMCB8IChjID4+IDE4KV1cbiAgICAgICAgICAgICsgaGV4VGFibGVbMHg4MCB8ICgoYyA+PiAxMikgJiAweDNGKV1cbiAgICAgICAgICAgICsgaGV4VGFibGVbMHg4MCB8ICgoYyA+PiA2KSAmIDB4M0YpXVxuICAgICAgICAgICAgKyBoZXhUYWJsZVsweDgwIHwgKGMgJiAweDNGKV07XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dDtcbn07XG5cbnZhciBjb21wYWN0ID0gZnVuY3Rpb24gY29tcGFjdCh2YWx1ZSkge1xuICAgIHZhciBxdWV1ZSA9IFt7IG9iajogeyBvOiB2YWx1ZSB9LCBwcm9wOiAnbycgfV07XG4gICAgdmFyIHJlZnMgPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcXVldWUubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIGl0ZW0gPSBxdWV1ZVtpXTtcbiAgICAgICAgdmFyIG9iaiA9IGl0ZW0ub2JqW2l0ZW0ucHJvcF07XG5cbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmopO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGtleXMubGVuZ3RoOyArK2opIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBrZXlzW2pdO1xuICAgICAgICAgICAgdmFyIHZhbCA9IG9ialtrZXldO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIHZhbCAhPT0gbnVsbCAmJiByZWZzLmluZGV4T2YodmFsKSA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICBxdWV1ZS5wdXNoKHsgb2JqOiBvYmosIHByb3A6IGtleSB9KTtcbiAgICAgICAgICAgICAgICByZWZzLnB1c2godmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbXBhY3RRdWV1ZShxdWV1ZSk7XG5cbiAgICByZXR1cm4gdmFsdWU7XG59O1xuXG52YXIgaXNSZWdFeHAgPSBmdW5jdGlvbiBpc1JlZ0V4cChvYmopIHtcbiAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IFJlZ0V4cF0nO1xufTtcblxudmFyIGlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIob2JqKSB7XG4gICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiAhIShvYmouY29uc3RydWN0b3IgJiYgb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyICYmIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlcihvYmopKTtcbn07XG5cbnZhciBjb21iaW5lID0gZnVuY3Rpb24gY29tYmluZShhLCBiKSB7XG4gICAgcmV0dXJuIFtdLmNvbmNhdChhLCBiKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIGFycmF5VG9PYmplY3Q6IGFycmF5VG9PYmplY3QsXG4gICAgYXNzaWduOiBhc3NpZ24sXG4gICAgY29tYmluZTogY29tYmluZSxcbiAgICBjb21wYWN0OiBjb21wYWN0LFxuICAgIGRlY29kZTogZGVjb2RlLFxuICAgIGVuY29kZTogZW5jb2RlLFxuICAgIGlzQnVmZmVyOiBpc0J1ZmZlcixcbiAgICBpc1JlZ0V4cDogaXNSZWdFeHAsXG4gICAgbWVyZ2U6IG1lcmdlXG59O1xuIiwiLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5Db3B5cmlnaHQgKEMpIE1pY3Jvc29mdC4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZVxudGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGVcbkxpY2Vuc2UgYXQgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblRISVMgQ09ERSBJUyBQUk9WSURFRCBPTiBBTiAqQVMgSVMqIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcbktJTkQsIEVJVEhFUiBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBXSVRIT1VUIExJTUlUQVRJT04gQU5ZIElNUExJRURcbldBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBUSVRMRSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UsXG5NRVJDSEFOVEFCTElUWSBPUiBOT04tSU5GUklOR0VNRU5ULlxuXG5TZWUgdGhlIEFwYWNoZSBWZXJzaW9uIDIuMCBMaWNlbnNlIGZvciBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnNcbmFuZCBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXG52YXIgUmVmbGVjdDtcbihmdW5jdGlvbiAoUmVmbGVjdCkge1xuICAgIC8vIE1ldGFkYXRhIFByb3Bvc2FsXG4gICAgLy8gaHR0cHM6Ly9yYnVja3Rvbi5naXRodWIuaW8vcmVmbGVjdC1tZXRhZGF0YS9cbiAgICAoZnVuY3Rpb24gKGZhY3RvcnkpIHtcbiAgICAgICAgdmFyIHJvb3QgPSB0eXBlb2YgZ2xvYmFsID09PSBcIm9iamVjdFwiID8gZ2xvYmFsIDpcbiAgICAgICAgICAgIHR5cGVvZiBzZWxmID09PSBcIm9iamVjdFwiID8gc2VsZiA6XG4gICAgICAgICAgICAgICAgdHlwZW9mIHRoaXMgPT09IFwib2JqZWN0XCIgPyB0aGlzIDpcbiAgICAgICAgICAgICAgICAgICAgRnVuY3Rpb24oXCJyZXR1cm4gdGhpcztcIikoKTtcbiAgICAgICAgdmFyIGV4cG9ydGVyID0gbWFrZUV4cG9ydGVyKFJlZmxlY3QpO1xuICAgICAgICBpZiAodHlwZW9mIHJvb3QuUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgcm9vdC5SZWZsZWN0ID0gUmVmbGVjdDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGV4cG9ydGVyID0gbWFrZUV4cG9ydGVyKHJvb3QuUmVmbGVjdCwgZXhwb3J0ZXIpO1xuICAgICAgICB9XG4gICAgICAgIGZhY3RvcnkoZXhwb3J0ZXIpO1xuICAgICAgICBmdW5jdGlvbiBtYWtlRXhwb3J0ZXIodGFyZ2V0LCBwcmV2aW91cykge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRba2V5XSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgeyBjb25maWd1cmFibGU6IHRydWUsIHdyaXRhYmxlOiB0cnVlLCB2YWx1ZTogdmFsdWUgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChwcmV2aW91cylcbiAgICAgICAgICAgICAgICAgICAgcHJldmlvdXMoa2V5LCB2YWx1ZSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfSkoZnVuY3Rpb24gKGV4cG9ydGVyKSB7XG4gICAgICAgIHZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuICAgICAgICAvLyBmZWF0dXJlIHRlc3QgZm9yIFN5bWJvbCBzdXBwb3J0XG4gICAgICAgIHZhciBzdXBwb3J0c1N5bWJvbCA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIjtcbiAgICAgICAgdmFyIHRvUHJpbWl0aXZlU3ltYm9sID0gc3VwcG9ydHNTeW1ib2wgJiYgdHlwZW9mIFN5bWJvbC50b1ByaW1pdGl2ZSAhPT0gXCJ1bmRlZmluZWRcIiA/IFN5bWJvbC50b1ByaW1pdGl2ZSA6IFwiQEB0b1ByaW1pdGl2ZVwiO1xuICAgICAgICB2YXIgaXRlcmF0b3JTeW1ib2wgPSBzdXBwb3J0c1N5bWJvbCAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yICE9PSBcInVuZGVmaW5lZFwiID8gU3ltYm9sLml0ZXJhdG9yIDogXCJAQGl0ZXJhdG9yXCI7XG4gICAgICAgIHZhciBzdXBwb3J0c0NyZWF0ZSA9IHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSBcImZ1bmN0aW9uXCI7IC8vIGZlYXR1cmUgdGVzdCBmb3IgT2JqZWN0LmNyZWF0ZSBzdXBwb3J0XG4gICAgICAgIHZhciBzdXBwb3J0c1Byb3RvID0geyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheTsgLy8gZmVhdHVyZSB0ZXN0IGZvciBfX3Byb3RvX18gc3VwcG9ydFxuICAgICAgICB2YXIgZG93bkxldmVsID0gIXN1cHBvcnRzQ3JlYXRlICYmICFzdXBwb3J0c1Byb3RvO1xuICAgICAgICB2YXIgSGFzaE1hcCA9IHtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBhbiBvYmplY3QgaW4gZGljdGlvbmFyeSBtb2RlIChhLmsuYS4gXCJzbG93XCIgbW9kZSBpbiB2OClcbiAgICAgICAgICAgIGNyZWF0ZTogc3VwcG9ydHNDcmVhdGVcbiAgICAgICAgICAgICAgICA/IGZ1bmN0aW9uICgpIHsgcmV0dXJuIE1ha2VEaWN0aW9uYXJ5KE9iamVjdC5jcmVhdGUobnVsbCkpOyB9XG4gICAgICAgICAgICAgICAgOiBzdXBwb3J0c1Byb3RvXG4gICAgICAgICAgICAgICAgICAgID8gZnVuY3Rpb24gKCkgeyByZXR1cm4gTWFrZURpY3Rpb25hcnkoeyBfX3Byb3RvX186IG51bGwgfSk7IH1cbiAgICAgICAgICAgICAgICAgICAgOiBmdW5jdGlvbiAoKSB7IHJldHVybiBNYWtlRGljdGlvbmFyeSh7fSk7IH0sXG4gICAgICAgICAgICBoYXM6IGRvd25MZXZlbFxuICAgICAgICAgICAgICAgID8gZnVuY3Rpb24gKG1hcCwga2V5KSB7IHJldHVybiBoYXNPd24uY2FsbChtYXAsIGtleSk7IH1cbiAgICAgICAgICAgICAgICA6IGZ1bmN0aW9uIChtYXAsIGtleSkgeyByZXR1cm4ga2V5IGluIG1hcDsgfSxcbiAgICAgICAgICAgIGdldDogZG93bkxldmVsXG4gICAgICAgICAgICAgICAgPyBmdW5jdGlvbiAobWFwLCBrZXkpIHsgcmV0dXJuIGhhc093bi5jYWxsKG1hcCwga2V5KSA/IG1hcFtrZXldIDogdW5kZWZpbmVkOyB9XG4gICAgICAgICAgICAgICAgOiBmdW5jdGlvbiAobWFwLCBrZXkpIHsgcmV0dXJuIG1hcFtrZXldOyB9LFxuICAgICAgICB9O1xuICAgICAgICAvLyBMb2FkIGdsb2JhbCBvciBzaGltIHZlcnNpb25zIG9mIE1hcCwgU2V0LCBhbmQgV2Vha01hcFxuICAgICAgICB2YXIgZnVuY3Rpb25Qcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoRnVuY3Rpb24pO1xuICAgICAgICB2YXIgdXNlUG9seWZpbGwgPSB0eXBlb2YgcHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJiBwcm9jZXNzLmVudiAmJiBwcm9jZXNzLmVudltcIlJFRkxFQ1RfTUVUQURBVEFfVVNFX01BUF9QT0xZRklMTFwiXSA9PT0gXCJ0cnVlXCI7XG4gICAgICAgIHZhciBfTWFwID0gIXVzZVBvbHlmaWxsICYmIHR5cGVvZiBNYXAgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgTWFwLnByb3RvdHlwZS5lbnRyaWVzID09PSBcImZ1bmN0aW9uXCIgPyBNYXAgOiBDcmVhdGVNYXBQb2x5ZmlsbCgpO1xuICAgICAgICB2YXIgX1NldCA9ICF1c2VQb2x5ZmlsbCAmJiB0eXBlb2YgU2V0ID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFNldC5wcm90b3R5cGUuZW50cmllcyA9PT0gXCJmdW5jdGlvblwiID8gU2V0IDogQ3JlYXRlU2V0UG9seWZpbGwoKTtcbiAgICAgICAgdmFyIF9XZWFrTWFwID0gIXVzZVBvbHlmaWxsICYmIHR5cGVvZiBXZWFrTWFwID09PSBcImZ1bmN0aW9uXCIgPyBXZWFrTWFwIDogQ3JlYXRlV2Vha01hcFBvbHlmaWxsKCk7XG4gICAgICAgIC8vIFtbTWV0YWRhdGFdXSBpbnRlcm5hbCBzbG90XG4gICAgICAgIC8vIGh0dHBzOi8vcmJ1Y2t0b24uZ2l0aHViLmlvL3JlZmxlY3QtbWV0YWRhdGEvI29yZGluYXJ5LW9iamVjdC1pbnRlcm5hbC1tZXRob2RzLWFuZC1pbnRlcm5hbC1zbG90c1xuICAgICAgICB2YXIgTWV0YWRhdGEgPSBuZXcgX1dlYWtNYXAoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFwcGxpZXMgYSBzZXQgb2YgZGVjb3JhdG9ycyB0byBhIHByb3BlcnR5IG9mIGEgdGFyZ2V0IG9iamVjdC5cbiAgICAgICAgICogQHBhcmFtIGRlY29yYXRvcnMgQW4gYXJyYXkgb2YgZGVjb3JhdG9ycy5cbiAgICAgICAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0IG9iamVjdC5cbiAgICAgICAgICogQHBhcmFtIHByb3BlcnR5S2V5IChPcHRpb25hbCkgVGhlIHByb3BlcnR5IGtleSB0byBkZWNvcmF0ZS5cbiAgICAgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgKE9wdGlvbmFsKSBUaGUgcHJvcGVydHkgZGVzY3JpcHRvciBmb3IgdGhlIHRhcmdldCBrZXkuXG4gICAgICAgICAqIEByZW1hcmtzIERlY29yYXRvcnMgYXJlIGFwcGxpZWQgaW4gcmV2ZXJzZSBvcmRlci5cbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIGNsYXNzIEV4YW1wbGUge1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5IGRlY2xhcmF0aW9ucyBhcmUgbm90IHBhcnQgb2YgRVM2LCB0aG91Z2ggdGhleSBhcmUgdmFsaWQgaW4gVHlwZVNjcmlwdDpcbiAgICAgICAgICogICAgICAgICAvLyBzdGF0aWMgc3RhdGljUHJvcGVydHk7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAgICAgY29uc3RydWN0b3IocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgc3RhdGljIHN0YXRpY01ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgICAgICBtZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBjb25zdHJ1Y3RvclxuICAgICAgICAgKiAgICAgRXhhbXBsZSA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9yc0FycmF5LCBFeGFtcGxlKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9yc0FycmF5LCBFeGFtcGxlLCBcInN0YXRpY1Byb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9yc0FycmF5LCBFeGFtcGxlLnByb3RvdHlwZSwgXCJwcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoRXhhbXBsZSwgXCJzdGF0aWNNZXRob2RcIixcbiAgICAgICAgICogICAgICAgICBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnNBcnJheSwgRXhhbXBsZSwgXCJzdGF0aWNNZXRob2RcIixcbiAgICAgICAgICogICAgICAgICAgICAgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihFeGFtcGxlLCBcInN0YXRpY01ldGhvZFwiKSkpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoRXhhbXBsZS5wcm90b3R5cGUsIFwibWV0aG9kXCIsXG4gICAgICAgICAqICAgICAgICAgUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzQXJyYXksIEV4YW1wbGUucHJvdG90eXBlLCBcIm1ldGhvZFwiLFxuICAgICAgICAgKiAgICAgICAgICAgICBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKEV4YW1wbGUucHJvdG90eXBlLCBcIm1ldGhvZFwiKSkpO1xuICAgICAgICAgKlxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBwcm9wZXJ0eUtleSwgYXR0cmlidXRlcykge1xuICAgICAgICAgICAgaWYgKCFJc1VuZGVmaW5lZChwcm9wZXJ0eUtleSkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUlzQXJyYXkoZGVjb3JhdG9ycykpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICBpZiAoIUlzT2JqZWN0KHRhcmdldCkpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICBpZiAoIUlzT2JqZWN0KGF0dHJpYnV0ZXMpICYmICFJc1VuZGVmaW5lZChhdHRyaWJ1dGVzKSAmJiAhSXNOdWxsKGF0dHJpYnV0ZXMpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgaWYgKElzTnVsbChhdHRyaWJ1dGVzKSlcbiAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcyA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBwcm9wZXJ0eUtleSA9IFRvUHJvcGVydHlLZXkocHJvcGVydHlLZXkpO1xuICAgICAgICAgICAgICAgIHJldHVybiBEZWNvcmF0ZVByb3BlcnR5KGRlY29yYXRvcnMsIHRhcmdldCwgcHJvcGVydHlLZXksIGF0dHJpYnV0ZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKCFJc0FycmF5KGRlY29yYXRvcnMpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgaWYgKCFJc0NvbnN0cnVjdG9yKHRhcmdldCkpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gRGVjb3JhdGVDb25zdHJ1Y3RvcihkZWNvcmF0b3JzLCB0YXJnZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGV4cG9ydGVyKFwiZGVjb3JhdGVcIiwgZGVjb3JhdGUpO1xuICAgICAgICAvLyA0LjEuMiBSZWZsZWN0Lm1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKVxuICAgICAgICAvLyBodHRwczovL3JidWNrdG9uLmdpdGh1Yi5pby9yZWZsZWN0LW1ldGFkYXRhLyNyZWZsZWN0Lm1ldGFkYXRhXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBIGRlZmF1bHQgbWV0YWRhdGEgZGVjb3JhdG9yIGZhY3RvcnkgdGhhdCBjYW4gYmUgdXNlZCBvbiBhIGNsYXNzLCBjbGFzcyBtZW1iZXIsIG9yIHBhcmFtZXRlci5cbiAgICAgICAgICogQHBhcmFtIG1ldGFkYXRhS2V5IFRoZSBrZXkgZm9yIHRoZSBtZXRhZGF0YSBlbnRyeS5cbiAgICAgICAgICogQHBhcmFtIG1ldGFkYXRhVmFsdWUgVGhlIHZhbHVlIGZvciB0aGUgbWV0YWRhdGEgZW50cnkuXG4gICAgICAgICAqIEByZXR1cm5zIEEgZGVjb3JhdG9yIGZ1bmN0aW9uLlxuICAgICAgICAgKiBAcmVtYXJrc1xuICAgICAgICAgKiBJZiBgbWV0YWRhdGFLZXlgIGlzIGFscmVhZHkgZGVmaW5lZCBmb3IgdGhlIHRhcmdldCBhbmQgdGFyZ2V0IGtleSwgdGhlXG4gICAgICAgICAqIG1ldGFkYXRhVmFsdWUgZm9yIHRoYXQga2V5IHdpbGwgYmUgb3ZlcndyaXR0ZW4uXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBjb25zdHJ1Y3RvclxuICAgICAgICAgKiAgICAgQFJlZmxlY3QubWV0YWRhdGEoa2V5LCB2YWx1ZSlcbiAgICAgICAgICogICAgIGNsYXNzIEV4YW1wbGUge1xuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIGNvbnN0cnVjdG9yLCBUeXBlU2NyaXB0IG9ubHkpXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgICAgICBAUmVmbGVjdC5tZXRhZGF0YShrZXksIHZhbHVlKVxuICAgICAgICAgKiAgICAgICAgIHN0YXRpYyBzdGF0aWNQcm9wZXJ0eTtcbiAgICAgICAgICogICAgIH1cbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBwcm90b3R5cGUsIFR5cGVTY3JpcHQgb25seSlcbiAgICAgICAgICogICAgIGNsYXNzIEV4YW1wbGUge1xuICAgICAgICAgKiAgICAgICAgIEBSZWZsZWN0Lm1ldGFkYXRhKGtleSwgdmFsdWUpXG4gICAgICAgICAqICAgICAgICAgcHJvcGVydHk7XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgY2xhc3MgRXhhbXBsZSB7XG4gICAgICAgICAqICAgICAgICAgQFJlZmxlY3QubWV0YWRhdGEoa2V5LCB2YWx1ZSlcbiAgICAgICAgICogICAgICAgICBzdGF0aWMgc3RhdGljTWV0aG9kKCkgeyB9XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIGNsYXNzIEV4YW1wbGUge1xuICAgICAgICAgKiAgICAgICAgIEBSZWZsZWN0Lm1ldGFkYXRhKGtleSwgdmFsdWUpXG4gICAgICAgICAqICAgICAgICAgbWV0aG9kKCkgeyB9XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBtZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xuICAgICAgICAgICAgZnVuY3Rpb24gZGVjb3JhdG9yKHRhcmdldCwgcHJvcGVydHlLZXkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUlzT2JqZWN0KHRhcmdldCkpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICBpZiAoIUlzVW5kZWZpbmVkKHByb3BlcnR5S2V5KSAmJiAhSXNQcm9wZXJ0eUtleShwcm9wZXJ0eUtleSkpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICBPcmRpbmFyeURlZmluZU93bk1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlLCB0YXJnZXQsIHByb3BlcnR5S2V5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBkZWNvcmF0b3I7XG4gICAgICAgIH1cbiAgICAgICAgZXhwb3J0ZXIoXCJtZXRhZGF0YVwiLCBtZXRhZGF0YSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWZpbmUgYSB1bmlxdWUgbWV0YWRhdGEgZW50cnkgb24gdGhlIHRhcmdldC5cbiAgICAgICAgICogQHBhcmFtIG1ldGFkYXRhS2V5IEEga2V5IHVzZWQgdG8gc3RvcmUgYW5kIHJldHJpZXZlIG1ldGFkYXRhLlxuICAgICAgICAgKiBAcGFyYW0gbWV0YWRhdGFWYWx1ZSBBIHZhbHVlIHRoYXQgY29udGFpbnMgYXR0YWNoZWQgbWV0YWRhdGEuXG4gICAgICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldCBvYmplY3Qgb24gd2hpY2ggdG8gZGVmaW5lIG1ldGFkYXRhLlxuICAgICAgICAgKiBAcGFyYW0gcHJvcGVydHlLZXkgKE9wdGlvbmFsKSBUaGUgcHJvcGVydHkga2V5IGZvciB0aGUgdGFyZ2V0LlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgY2xhc3MgRXhhbXBsZSB7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHkgZGVjbGFyYXRpb25zIGFyZSBub3QgcGFydCBvZiBFUzYsIHRob3VnaCB0aGV5IGFyZSB2YWxpZCBpbiBUeXBlU2NyaXB0OlxuICAgICAgICAgKiAgICAgICAgIC8vIHN0YXRpYyBzdGF0aWNQcm9wZXJ0eTtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgICAgICBjb25zdHJ1Y3RvcihwKSB7IH1cbiAgICAgICAgICogICAgICAgICBzdGF0aWMgc3RhdGljTWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIG1ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgIH1cbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIGNvbnN0cnVjdG9yXG4gICAgICAgICAqICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgb3B0aW9ucywgRXhhbXBsZSk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgb3B0aW9ucywgRXhhbXBsZSwgXCJzdGF0aWNQcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgb3B0aW9ucywgRXhhbXBsZS5wcm90b3R5cGUsIFwicHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIG9wdGlvbnMsIEV4YW1wbGUsIFwic3RhdGljTWV0aG9kXCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgb3B0aW9ucywgRXhhbXBsZS5wcm90b3R5cGUsIFwibWV0aG9kXCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gZGVjb3JhdG9yIGZhY3RvcnkgYXMgbWV0YWRhdGEtcHJvZHVjaW5nIGFubm90YXRpb24uXG4gICAgICAgICAqICAgICBmdW5jdGlvbiBNeUFubm90YXRpb24ob3B0aW9ucyk6IERlY29yYXRvciB7XG4gICAgICAgICAqICAgICAgICAgcmV0dXJuICh0YXJnZXQsIGtleT8pID0+IFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBvcHRpb25zLCB0YXJnZXQsIGtleSk7XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBkZWZpbmVNZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSwgdGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgICAgICAgICAgaWYgKCFJc09iamVjdCh0YXJnZXQpKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgIGlmICghSXNVbmRlZmluZWQocHJvcGVydHlLZXkpKVxuICAgICAgICAgICAgICAgIHByb3BlcnR5S2V5ID0gVG9Qcm9wZXJ0eUtleShwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICByZXR1cm4gT3JkaW5hcnlEZWZpbmVPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSwgdGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4gICAgICAgIH1cbiAgICAgICAgZXhwb3J0ZXIoXCJkZWZpbmVNZXRhZGF0YVwiLCBkZWZpbmVNZXRhZGF0YSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZXRzIGEgdmFsdWUgaW5kaWNhdGluZyB3aGV0aGVyIHRoZSB0YXJnZXQgb2JqZWN0IG9yIGl0cyBwcm90b3R5cGUgY2hhaW4gaGFzIHRoZSBwcm92aWRlZCBtZXRhZGF0YSBrZXkgZGVmaW5lZC5cbiAgICAgICAgICogQHBhcmFtIG1ldGFkYXRhS2V5IEEga2V5IHVzZWQgdG8gc3RvcmUgYW5kIHJldHJpZXZlIG1ldGFkYXRhLlxuICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQgb2JqZWN0IG9uIHdoaWNoIHRoZSBtZXRhZGF0YSBpcyBkZWZpbmVkLlxuICAgICAgICAgKiBAcGFyYW0gcHJvcGVydHlLZXkgKE9wdGlvbmFsKSBUaGUgcHJvcGVydHkga2V5IGZvciB0aGUgdGFyZ2V0LlxuICAgICAgICAgKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG1ldGFkYXRhIGtleSB3YXMgZGVmaW5lZCBvbiB0aGUgdGFyZ2V0IG9iamVjdCBvciBpdHMgcHJvdG90eXBlIGNoYWluOyBvdGhlcndpc2UsIGBmYWxzZWAuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eSBkZWNsYXJhdGlvbnMgYXJlIG5vdCBwYXJ0IG9mIEVTNiwgdGhvdWdoIHRoZXkgYXJlIHZhbGlkIGluIFR5cGVTY3JpcHQ6XG4gICAgICAgICAqICAgICAgICAgLy8gc3RhdGljIHN0YXRpY1Byb3BlcnR5O1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5O1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgICAgIGNvbnN0cnVjdG9yKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIHN0YXRpYyBzdGF0aWNNZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgbWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gY29uc3RydWN0b3JcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuaGFzTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuaGFzTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLCBcInN0YXRpY1Byb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuaGFzTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLnByb3RvdHlwZSwgXCJwcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0Lmhhc01ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZSwgXCJzdGF0aWNNZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuaGFzTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLnByb3RvdHlwZSwgXCJtZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBoYXNNZXRhZGF0YShtZXRhZGF0YUtleSwgdGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgICAgICAgICAgaWYgKCFJc09iamVjdCh0YXJnZXQpKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgIGlmICghSXNVbmRlZmluZWQocHJvcGVydHlLZXkpKVxuICAgICAgICAgICAgICAgIHByb3BlcnR5S2V5ID0gVG9Qcm9wZXJ0eUtleShwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICByZXR1cm4gT3JkaW5hcnlIYXNNZXRhZGF0YShtZXRhZGF0YUtleSwgdGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4gICAgICAgIH1cbiAgICAgICAgZXhwb3J0ZXIoXCJoYXNNZXRhZGF0YVwiLCBoYXNNZXRhZGF0YSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZXRzIGEgdmFsdWUgaW5kaWNhdGluZyB3aGV0aGVyIHRoZSB0YXJnZXQgb2JqZWN0IGhhcyB0aGUgcHJvdmlkZWQgbWV0YWRhdGEga2V5IGRlZmluZWQuXG4gICAgICAgICAqIEBwYXJhbSBtZXRhZGF0YUtleSBBIGtleSB1c2VkIHRvIHN0b3JlIGFuZCByZXRyaWV2ZSBtZXRhZGF0YS5cbiAgICAgICAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0IG9iamVjdCBvbiB3aGljaCB0aGUgbWV0YWRhdGEgaXMgZGVmaW5lZC5cbiAgICAgICAgICogQHBhcmFtIHByb3BlcnR5S2V5IChPcHRpb25hbCkgVGhlIHByb3BlcnR5IGtleSBmb3IgdGhlIHRhcmdldC5cbiAgICAgICAgICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBtZXRhZGF0YSBrZXkgd2FzIGRlZmluZWQgb24gdGhlIHRhcmdldCBvYmplY3Q7IG90aGVyd2lzZSwgYGZhbHNlYC5cbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIGNsYXNzIEV4YW1wbGUge1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5IGRlY2xhcmF0aW9ucyBhcmUgbm90IHBhcnQgb2YgRVM2LCB0aG91Z2ggdGhleSBhcmUgdmFsaWQgaW4gVHlwZVNjcmlwdDpcbiAgICAgICAgICogICAgICAgICAvLyBzdGF0aWMgc3RhdGljUHJvcGVydHk7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAgICAgY29uc3RydWN0b3IocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgc3RhdGljIHN0YXRpY01ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgICAgICBtZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBjb25zdHJ1Y3RvclxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5oYXNPd25NZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5oYXNPd25NZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUsIFwic3RhdGljUHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5oYXNPd25NZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUucHJvdG90eXBlLCBcInByb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuaGFzT3duTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLCBcInN0YXRpY01ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5oYXNPd25NZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUucHJvdG90eXBlLCBcIm1ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGhhc093bk1ldGFkYXRhKG1ldGFkYXRhS2V5LCB0YXJnZXQsIHByb3BlcnR5S2V5KSB7XG4gICAgICAgICAgICBpZiAoIUlzT2JqZWN0KHRhcmdldCkpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgaWYgKCFJc1VuZGVmaW5lZChwcm9wZXJ0eUtleSkpXG4gICAgICAgICAgICAgICAgcHJvcGVydHlLZXkgPSBUb1Byb3BlcnR5S2V5KHByb3BlcnR5S2V5KTtcbiAgICAgICAgICAgIHJldHVybiBPcmRpbmFyeUhhc093bk1ldGFkYXRhKG1ldGFkYXRhS2V5LCB0YXJnZXQsIHByb3BlcnR5S2V5KTtcbiAgICAgICAgfVxuICAgICAgICBleHBvcnRlcihcImhhc093bk1ldGFkYXRhXCIsIGhhc093bk1ldGFkYXRhKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldHMgdGhlIG1ldGFkYXRhIHZhbHVlIGZvciB0aGUgcHJvdmlkZWQgbWV0YWRhdGEga2V5IG9uIHRoZSB0YXJnZXQgb2JqZWN0IG9yIGl0cyBwcm90b3R5cGUgY2hhaW4uXG4gICAgICAgICAqIEBwYXJhbSBtZXRhZGF0YUtleSBBIGtleSB1c2VkIHRvIHN0b3JlIGFuZCByZXRyaWV2ZSBtZXRhZGF0YS5cbiAgICAgICAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0IG9iamVjdCBvbiB3aGljaCB0aGUgbWV0YWRhdGEgaXMgZGVmaW5lZC5cbiAgICAgICAgICogQHBhcmFtIHByb3BlcnR5S2V5IChPcHRpb25hbCkgVGhlIHByb3BlcnR5IGtleSBmb3IgdGhlIHRhcmdldC5cbiAgICAgICAgICogQHJldHVybnMgVGhlIG1ldGFkYXRhIHZhbHVlIGZvciB0aGUgbWV0YWRhdGEga2V5IGlmIGZvdW5kOyBvdGhlcndpc2UsIGB1bmRlZmluZWRgLlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgY2xhc3MgRXhhbXBsZSB7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHkgZGVjbGFyYXRpb25zIGFyZSBub3QgcGFydCBvZiBFUzYsIHRob3VnaCB0aGV5IGFyZSB2YWxpZCBpbiBUeXBlU2NyaXB0OlxuICAgICAgICAgKiAgICAgICAgIC8vIHN0YXRpYyBzdGF0aWNQcm9wZXJ0eTtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgICAgICBjb25zdHJ1Y3RvcihwKSB7IH1cbiAgICAgICAgICogICAgICAgICBzdGF0aWMgc3RhdGljTWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIG1ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgIH1cbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIGNvbnN0cnVjdG9yXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZSk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZSwgXCJzdGF0aWNQcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZS5wcm90b3R5cGUsIFwicHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUsIFwic3RhdGljTWV0aG9kXCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZS5wcm90b3R5cGUsIFwibWV0aG9kXCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gZ2V0TWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCwgcHJvcGVydHlLZXkpIHtcbiAgICAgICAgICAgIGlmICghSXNPYmplY3QodGFyZ2V0KSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICBpZiAoIUlzVW5kZWZpbmVkKHByb3BlcnR5S2V5KSlcbiAgICAgICAgICAgICAgICBwcm9wZXJ0eUtleSA9IFRvUHJvcGVydHlLZXkocHJvcGVydHlLZXkpO1xuICAgICAgICAgICAgcmV0dXJuIE9yZGluYXJ5R2V0TWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCwgcHJvcGVydHlLZXkpO1xuICAgICAgICB9XG4gICAgICAgIGV4cG9ydGVyKFwiZ2V0TWV0YWRhdGFcIiwgZ2V0TWV0YWRhdGEpO1xuICAgICAgICAvKipcbiAgICAgICAgICogR2V0cyB0aGUgbWV0YWRhdGEgdmFsdWUgZm9yIHRoZSBwcm92aWRlZCBtZXRhZGF0YSBrZXkgb24gdGhlIHRhcmdldCBvYmplY3QuXG4gICAgICAgICAqIEBwYXJhbSBtZXRhZGF0YUtleSBBIGtleSB1c2VkIHRvIHN0b3JlIGFuZCByZXRyaWV2ZSBtZXRhZGF0YS5cbiAgICAgICAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0IG9iamVjdCBvbiB3aGljaCB0aGUgbWV0YWRhdGEgaXMgZGVmaW5lZC5cbiAgICAgICAgICogQHBhcmFtIHByb3BlcnR5S2V5IChPcHRpb25hbCkgVGhlIHByb3BlcnR5IGtleSBmb3IgdGhlIHRhcmdldC5cbiAgICAgICAgICogQHJldHVybnMgVGhlIG1ldGFkYXRhIHZhbHVlIGZvciB0aGUgbWV0YWRhdGEga2V5IGlmIGZvdW5kOyBvdGhlcndpc2UsIGB1bmRlZmluZWRgLlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgY2xhc3MgRXhhbXBsZSB7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHkgZGVjbGFyYXRpb25zIGFyZSBub3QgcGFydCBvZiBFUzYsIHRob3VnaCB0aGV5IGFyZSB2YWxpZCBpbiBUeXBlU2NyaXB0OlxuICAgICAgICAgKiAgICAgICAgIC8vIHN0YXRpYyBzdGF0aWNQcm9wZXJ0eTtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgICAgICBjb25zdHJ1Y3RvcihwKSB7IH1cbiAgICAgICAgICogICAgICAgICBzdGF0aWMgc3RhdGljTWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIG1ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgIH1cbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIGNvbnN0cnVjdG9yXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE93bk1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZSk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE93bk1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZSwgXCJzdGF0aWNQcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE93bk1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZS5wcm90b3R5cGUsIFwicHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRPd25NZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUsIFwic3RhdGljTWV0aG9kXCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE93bk1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZS5wcm90b3R5cGUsIFwibWV0aG9kXCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gZ2V0T3duTWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCwgcHJvcGVydHlLZXkpIHtcbiAgICAgICAgICAgIGlmICghSXNPYmplY3QodGFyZ2V0KSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICBpZiAoIUlzVW5kZWZpbmVkKHByb3BlcnR5S2V5KSlcbiAgICAgICAgICAgICAgICBwcm9wZXJ0eUtleSA9IFRvUHJvcGVydHlLZXkocHJvcGVydHlLZXkpO1xuICAgICAgICAgICAgcmV0dXJuIE9yZGluYXJ5R2V0T3duTWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCwgcHJvcGVydHlLZXkpO1xuICAgICAgICB9XG4gICAgICAgIGV4cG9ydGVyKFwiZ2V0T3duTWV0YWRhdGFcIiwgZ2V0T3duTWV0YWRhdGEpO1xuICAgICAgICAvKipcbiAgICAgICAgICogR2V0cyB0aGUgbWV0YWRhdGEga2V5cyBkZWZpbmVkIG9uIHRoZSB0YXJnZXQgb2JqZWN0IG9yIGl0cyBwcm90b3R5cGUgY2hhaW4uXG4gICAgICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldCBvYmplY3Qgb24gd2hpY2ggdGhlIG1ldGFkYXRhIGlzIGRlZmluZWQuXG4gICAgICAgICAqIEBwYXJhbSBwcm9wZXJ0eUtleSAoT3B0aW9uYWwpIFRoZSBwcm9wZXJ0eSBrZXkgZm9yIHRoZSB0YXJnZXQuXG4gICAgICAgICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIHVuaXF1ZSBtZXRhZGF0YSBrZXlzLlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgY2xhc3MgRXhhbXBsZSB7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHkgZGVjbGFyYXRpb25zIGFyZSBub3QgcGFydCBvZiBFUzYsIHRob3VnaCB0aGV5IGFyZSB2YWxpZCBpbiBUeXBlU2NyaXB0OlxuICAgICAgICAgKiAgICAgICAgIC8vIHN0YXRpYyBzdGF0aWNQcm9wZXJ0eTtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgICAgICBjb25zdHJ1Y3RvcihwKSB7IH1cbiAgICAgICAgICogICAgICAgICBzdGF0aWMgc3RhdGljTWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIG1ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgIH1cbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIGNvbnN0cnVjdG9yXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE1ldGFkYXRhS2V5cyhFeGFtcGxlKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0TWV0YWRhdGFLZXlzKEV4YW1wbGUsIFwic3RhdGljUHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRNZXRhZGF0YUtleXMoRXhhbXBsZS5wcm90b3R5cGUsIFwicHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRNZXRhZGF0YUtleXMoRXhhbXBsZSwgXCJzdGF0aWNNZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0TWV0YWRhdGFLZXlzKEV4YW1wbGUucHJvdG90eXBlLCBcIm1ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGdldE1ldGFkYXRhS2V5cyh0YXJnZXQsIHByb3BlcnR5S2V5KSB7XG4gICAgICAgICAgICBpZiAoIUlzT2JqZWN0KHRhcmdldCkpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgaWYgKCFJc1VuZGVmaW5lZChwcm9wZXJ0eUtleSkpXG4gICAgICAgICAgICAgICAgcHJvcGVydHlLZXkgPSBUb1Byb3BlcnR5S2V5KHByb3BlcnR5S2V5KTtcbiAgICAgICAgICAgIHJldHVybiBPcmRpbmFyeU1ldGFkYXRhS2V5cyh0YXJnZXQsIHByb3BlcnR5S2V5KTtcbiAgICAgICAgfVxuICAgICAgICBleHBvcnRlcihcImdldE1ldGFkYXRhS2V5c1wiLCBnZXRNZXRhZGF0YUtleXMpO1xuICAgICAgICAvKipcbiAgICAgICAgICogR2V0cyB0aGUgdW5pcXVlIG1ldGFkYXRhIGtleXMgZGVmaW5lZCBvbiB0aGUgdGFyZ2V0IG9iamVjdC5cbiAgICAgICAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0IG9iamVjdCBvbiB3aGljaCB0aGUgbWV0YWRhdGEgaXMgZGVmaW5lZC5cbiAgICAgICAgICogQHBhcmFtIHByb3BlcnR5S2V5IChPcHRpb25hbCkgVGhlIHByb3BlcnR5IGtleSBmb3IgdGhlIHRhcmdldC5cbiAgICAgICAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgdW5pcXVlIG1ldGFkYXRhIGtleXMuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eSBkZWNsYXJhdGlvbnMgYXJlIG5vdCBwYXJ0IG9mIEVTNiwgdGhvdWdoIHRoZXkgYXJlIHZhbGlkIGluIFR5cGVTY3JpcHQ6XG4gICAgICAgICAqICAgICAgICAgLy8gc3RhdGljIHN0YXRpY1Byb3BlcnR5O1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5O1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgICAgIGNvbnN0cnVjdG9yKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIHN0YXRpYyBzdGF0aWNNZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgbWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gY29uc3RydWN0b3JcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0T3duTWV0YWRhdGFLZXlzKEV4YW1wbGUpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRPd25NZXRhZGF0YUtleXMoRXhhbXBsZSwgXCJzdGF0aWNQcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE93bk1ldGFkYXRhS2V5cyhFeGFtcGxlLnByb3RvdHlwZSwgXCJwcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE93bk1ldGFkYXRhS2V5cyhFeGFtcGxlLCBcInN0YXRpY01ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRPd25NZXRhZGF0YUtleXMoRXhhbXBsZS5wcm90b3R5cGUsIFwibWV0aG9kXCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gZ2V0T3duTWV0YWRhdGFLZXlzKHRhcmdldCwgcHJvcGVydHlLZXkpIHtcbiAgICAgICAgICAgIGlmICghSXNPYmplY3QodGFyZ2V0KSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICBpZiAoIUlzVW5kZWZpbmVkKHByb3BlcnR5S2V5KSlcbiAgICAgICAgICAgICAgICBwcm9wZXJ0eUtleSA9IFRvUHJvcGVydHlLZXkocHJvcGVydHlLZXkpO1xuICAgICAgICAgICAgcmV0dXJuIE9yZGluYXJ5T3duTWV0YWRhdGFLZXlzKHRhcmdldCwgcHJvcGVydHlLZXkpO1xuICAgICAgICB9XG4gICAgICAgIGV4cG9ydGVyKFwiZ2V0T3duTWV0YWRhdGFLZXlzXCIsIGdldE93bk1ldGFkYXRhS2V5cyk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWxldGVzIHRoZSBtZXRhZGF0YSBlbnRyeSBmcm9tIHRoZSB0YXJnZXQgb2JqZWN0IHdpdGggdGhlIHByb3ZpZGVkIGtleS5cbiAgICAgICAgICogQHBhcmFtIG1ldGFkYXRhS2V5IEEga2V5IHVzZWQgdG8gc3RvcmUgYW5kIHJldHJpZXZlIG1ldGFkYXRhLlxuICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQgb2JqZWN0IG9uIHdoaWNoIHRoZSBtZXRhZGF0YSBpcyBkZWZpbmVkLlxuICAgICAgICAgKiBAcGFyYW0gcHJvcGVydHlLZXkgKE9wdGlvbmFsKSBUaGUgcHJvcGVydHkga2V5IGZvciB0aGUgdGFyZ2V0LlxuICAgICAgICAgKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG1ldGFkYXRhIGVudHJ5IHdhcyBmb3VuZCBhbmQgZGVsZXRlZDsgb3RoZXJ3aXNlLCBmYWxzZS5cbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIGNsYXNzIEV4YW1wbGUge1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5IGRlY2xhcmF0aW9ucyBhcmUgbm90IHBhcnQgb2YgRVM2LCB0aG91Z2ggdGhleSBhcmUgdmFsaWQgaW4gVHlwZVNjcmlwdDpcbiAgICAgICAgICogICAgICAgICAvLyBzdGF0aWMgc3RhdGljUHJvcGVydHk7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAgICAgY29uc3RydWN0b3IocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgc3RhdGljIHN0YXRpY01ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgICAgICBtZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBjb25zdHJ1Y3RvclxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5kZWxldGVNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5kZWxldGVNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUsIFwic3RhdGljUHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5kZWxldGVNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUucHJvdG90eXBlLCBcInByb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZGVsZXRlTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLCBcInN0YXRpY01ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5kZWxldGVNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUucHJvdG90eXBlLCBcIm1ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGRlbGV0ZU1ldGFkYXRhKG1ldGFkYXRhS2V5LCB0YXJnZXQsIHByb3BlcnR5S2V5KSB7XG4gICAgICAgICAgICBpZiAoIUlzT2JqZWN0KHRhcmdldCkpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgaWYgKCFJc1VuZGVmaW5lZChwcm9wZXJ0eUtleSkpXG4gICAgICAgICAgICAgICAgcHJvcGVydHlLZXkgPSBUb1Byb3BlcnR5S2V5KHByb3BlcnR5S2V5KTtcbiAgICAgICAgICAgIHZhciBtZXRhZGF0YU1hcCA9IEdldE9yQ3JlYXRlTWV0YWRhdGFNYXAodGFyZ2V0LCBwcm9wZXJ0eUtleSwgLypDcmVhdGUqLyBmYWxzZSk7XG4gICAgICAgICAgICBpZiAoSXNVbmRlZmluZWQobWV0YWRhdGFNYXApKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIGlmICghbWV0YWRhdGFNYXAuZGVsZXRlKG1ldGFkYXRhS2V5KSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBpZiAobWV0YWRhdGFNYXAuc2l6ZSA+IDApXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB2YXIgdGFyZ2V0TWV0YWRhdGEgPSBNZXRhZGF0YS5nZXQodGFyZ2V0KTtcbiAgICAgICAgICAgIHRhcmdldE1ldGFkYXRhLmRlbGV0ZShwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICBpZiAodGFyZ2V0TWV0YWRhdGEuc2l6ZSA+IDApXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICBNZXRhZGF0YS5kZWxldGUodGFyZ2V0KTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGV4cG9ydGVyKFwiZGVsZXRlTWV0YWRhdGFcIiwgZGVsZXRlTWV0YWRhdGEpO1xuICAgICAgICBmdW5jdGlvbiBEZWNvcmF0ZUNvbnN0cnVjdG9yKGRlY29yYXRvcnMsIHRhcmdldCkge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGVjb3JhdG9yID0gZGVjb3JhdG9yc1tpXTtcbiAgICAgICAgICAgICAgICB2YXIgZGVjb3JhdGVkID0gZGVjb3JhdG9yKHRhcmdldCk7XG4gICAgICAgICAgICAgICAgaWYgKCFJc1VuZGVmaW5lZChkZWNvcmF0ZWQpICYmICFJc051bGwoZGVjb3JhdGVkKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIUlzQ29uc3RydWN0b3IoZGVjb3JhdGVkKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ID0gZGVjb3JhdGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gRGVjb3JhdGVQcm9wZXJ0eShkZWNvcmF0b3JzLCB0YXJnZXQsIHByb3BlcnR5S2V5LCBkZXNjcmlwdG9yKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICAgICAgICAgIHZhciBkZWNvcmF0b3IgPSBkZWNvcmF0b3JzW2ldO1xuICAgICAgICAgICAgICAgIHZhciBkZWNvcmF0ZWQgPSBkZWNvcmF0b3IodGFyZ2V0LCBwcm9wZXJ0eUtleSwgZGVzY3JpcHRvcik7XG4gICAgICAgICAgICAgICAgaWYgKCFJc1VuZGVmaW5lZChkZWNvcmF0ZWQpICYmICFJc051bGwoZGVjb3JhdGVkKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIUlzT2JqZWN0KGRlY29yYXRlZCkpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3IgPSBkZWNvcmF0ZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGRlc2NyaXB0b3I7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gR2V0T3JDcmVhdGVNZXRhZGF0YU1hcChPLCBQLCBDcmVhdGUpIHtcbiAgICAgICAgICAgIHZhciB0YXJnZXRNZXRhZGF0YSA9IE1ldGFkYXRhLmdldChPKTtcbiAgICAgICAgICAgIGlmIChJc1VuZGVmaW5lZCh0YXJnZXRNZXRhZGF0YSkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUNyZWF0ZSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB0YXJnZXRNZXRhZGF0YSA9IG5ldyBfTWFwKCk7XG4gICAgICAgICAgICAgICAgTWV0YWRhdGEuc2V0KE8sIHRhcmdldE1ldGFkYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBtZXRhZGF0YU1hcCA9IHRhcmdldE1ldGFkYXRhLmdldChQKTtcbiAgICAgICAgICAgIGlmIChJc1VuZGVmaW5lZChtZXRhZGF0YU1hcCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUNyZWF0ZSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBtZXRhZGF0YU1hcCA9IG5ldyBfTWFwKCk7XG4gICAgICAgICAgICAgICAgdGFyZ2V0TWV0YWRhdGEuc2V0KFAsIG1ldGFkYXRhTWFwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtZXRhZGF0YU1hcDtcbiAgICAgICAgfVxuICAgICAgICAvLyAzLjEuMS4xIE9yZGluYXJ5SGFzTWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApXG4gICAgICAgIC8vIGh0dHBzOi8vcmJ1Y2t0b24uZ2l0aHViLmlvL3JlZmxlY3QtbWV0YWRhdGEvI29yZGluYXJ5aGFzbWV0YWRhdGFcbiAgICAgICAgZnVuY3Rpb24gT3JkaW5hcnlIYXNNZXRhZGF0YShNZXRhZGF0YUtleSwgTywgUCkge1xuICAgICAgICAgICAgdmFyIGhhc093biA9IE9yZGluYXJ5SGFzT3duTWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApO1xuICAgICAgICAgICAgaWYgKGhhc093bilcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIHZhciBwYXJlbnQgPSBPcmRpbmFyeUdldFByb3RvdHlwZU9mKE8pO1xuICAgICAgICAgICAgaWYgKCFJc051bGwocGFyZW50KSlcbiAgICAgICAgICAgICAgICByZXR1cm4gT3JkaW5hcnlIYXNNZXRhZGF0YShNZXRhZGF0YUtleSwgcGFyZW50LCBQKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICAvLyAzLjEuMi4xIE9yZGluYXJ5SGFzT3duTWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApXG4gICAgICAgIC8vIGh0dHBzOi8vcmJ1Y2t0b24uZ2l0aHViLmlvL3JlZmxlY3QtbWV0YWRhdGEvI29yZGluYXJ5aGFzb3dubWV0YWRhdGFcbiAgICAgICAgZnVuY3Rpb24gT3JkaW5hcnlIYXNPd25NZXRhZGF0YShNZXRhZGF0YUtleSwgTywgUCkge1xuICAgICAgICAgICAgdmFyIG1ldGFkYXRhTWFwID0gR2V0T3JDcmVhdGVNZXRhZGF0YU1hcChPLCBQLCAvKkNyZWF0ZSovIGZhbHNlKTtcbiAgICAgICAgICAgIGlmIChJc1VuZGVmaW5lZChtZXRhZGF0YU1hcCkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgcmV0dXJuIFRvQm9vbGVhbihtZXRhZGF0YU1hcC5oYXMoTWV0YWRhdGFLZXkpKTtcbiAgICAgICAgfVxuICAgICAgICAvLyAzLjEuMy4xIE9yZGluYXJ5R2V0TWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApXG4gICAgICAgIC8vIGh0dHBzOi8vcmJ1Y2t0b24uZ2l0aHViLmlvL3JlZmxlY3QtbWV0YWRhdGEvI29yZGluYXJ5Z2V0bWV0YWRhdGFcbiAgICAgICAgZnVuY3Rpb24gT3JkaW5hcnlHZXRNZXRhZGF0YShNZXRhZGF0YUtleSwgTywgUCkge1xuICAgICAgICAgICAgdmFyIGhhc093biA9IE9yZGluYXJ5SGFzT3duTWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApO1xuICAgICAgICAgICAgaWYgKGhhc093bilcbiAgICAgICAgICAgICAgICByZXR1cm4gT3JkaW5hcnlHZXRPd25NZXRhZGF0YShNZXRhZGF0YUtleSwgTywgUCk7XG4gICAgICAgICAgICB2YXIgcGFyZW50ID0gT3JkaW5hcnlHZXRQcm90b3R5cGVPZihPKTtcbiAgICAgICAgICAgIGlmICghSXNOdWxsKHBhcmVudCkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIE9yZGluYXJ5R2V0TWV0YWRhdGEoTWV0YWRhdGFLZXksIHBhcmVudCwgUCk7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIC8vIDMuMS40LjEgT3JkaW5hcnlHZXRPd25NZXRhZGF0YShNZXRhZGF0YUtleSwgTywgUClcbiAgICAgICAgLy8gaHR0cHM6Ly9yYnVja3Rvbi5naXRodWIuaW8vcmVmbGVjdC1tZXRhZGF0YS8jb3JkaW5hcnlnZXRvd25tZXRhZGF0YVxuICAgICAgICBmdW5jdGlvbiBPcmRpbmFyeUdldE93bk1ldGFkYXRhKE1ldGFkYXRhS2V5LCBPLCBQKSB7XG4gICAgICAgICAgICB2YXIgbWV0YWRhdGFNYXAgPSBHZXRPckNyZWF0ZU1ldGFkYXRhTWFwKE8sIFAsIC8qQ3JlYXRlKi8gZmFsc2UpO1xuICAgICAgICAgICAgaWYgKElzVW5kZWZpbmVkKG1ldGFkYXRhTWFwKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgcmV0dXJuIG1ldGFkYXRhTWFwLmdldChNZXRhZGF0YUtleSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gMy4xLjUuMSBPcmRpbmFyeURlZmluZU93bk1ldGFkYXRhKE1ldGFkYXRhS2V5LCBNZXRhZGF0YVZhbHVlLCBPLCBQKVxuICAgICAgICAvLyBodHRwczovL3JidWNrdG9uLmdpdGh1Yi5pby9yZWZsZWN0LW1ldGFkYXRhLyNvcmRpbmFyeWRlZmluZW93bm1ldGFkYXRhXG4gICAgICAgIGZ1bmN0aW9uIE9yZGluYXJ5RGVmaW5lT3duTWV0YWRhdGEoTWV0YWRhdGFLZXksIE1ldGFkYXRhVmFsdWUsIE8sIFApIHtcbiAgICAgICAgICAgIHZhciBtZXRhZGF0YU1hcCA9IEdldE9yQ3JlYXRlTWV0YWRhdGFNYXAoTywgUCwgLypDcmVhdGUqLyB0cnVlKTtcbiAgICAgICAgICAgIG1ldGFkYXRhTWFwLnNldChNZXRhZGF0YUtleSwgTWV0YWRhdGFWYWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gMy4xLjYuMSBPcmRpbmFyeU1ldGFkYXRhS2V5cyhPLCBQKVxuICAgICAgICAvLyBodHRwczovL3JidWNrdG9uLmdpdGh1Yi5pby9yZWZsZWN0LW1ldGFkYXRhLyNvcmRpbmFyeW1ldGFkYXRha2V5c1xuICAgICAgICBmdW5jdGlvbiBPcmRpbmFyeU1ldGFkYXRhS2V5cyhPLCBQKSB7XG4gICAgICAgICAgICB2YXIgb3duS2V5cyA9IE9yZGluYXJ5T3duTWV0YWRhdGFLZXlzKE8sIFApO1xuICAgICAgICAgICAgdmFyIHBhcmVudCA9IE9yZGluYXJ5R2V0UHJvdG90eXBlT2YoTyk7XG4gICAgICAgICAgICBpZiAocGFyZW50ID09PSBudWxsKVxuICAgICAgICAgICAgICAgIHJldHVybiBvd25LZXlzO1xuICAgICAgICAgICAgdmFyIHBhcmVudEtleXMgPSBPcmRpbmFyeU1ldGFkYXRhS2V5cyhwYXJlbnQsIFApO1xuICAgICAgICAgICAgaWYgKHBhcmVudEtleXMubGVuZ3RoIDw9IDApXG4gICAgICAgICAgICAgICAgcmV0dXJuIG93bktleXM7XG4gICAgICAgICAgICBpZiAob3duS2V5cy5sZW5ndGggPD0gMClcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50S2V5cztcbiAgICAgICAgICAgIHZhciBzZXQgPSBuZXcgX1NldCgpO1xuICAgICAgICAgICAgdmFyIGtleXMgPSBbXTtcbiAgICAgICAgICAgIGZvciAodmFyIF9pID0gMCwgb3duS2V5c18xID0gb3duS2V5czsgX2kgPCBvd25LZXlzXzEubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGtleSA9IG93bktleXNfMVtfaV07XG4gICAgICAgICAgICAgICAgdmFyIGhhc0tleSA9IHNldC5oYXMoa2V5KTtcbiAgICAgICAgICAgICAgICBpZiAoIWhhc0tleSkge1xuICAgICAgICAgICAgICAgICAgICBzZXQuYWRkKGtleSk7XG4gICAgICAgICAgICAgICAgICAgIGtleXMucHVzaChrZXkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAodmFyIF9hID0gMCwgcGFyZW50S2V5c18xID0gcGFyZW50S2V5czsgX2EgPCBwYXJlbnRLZXlzXzEubGVuZ3RoOyBfYSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGtleSA9IHBhcmVudEtleXNfMVtfYV07XG4gICAgICAgICAgICAgICAgdmFyIGhhc0tleSA9IHNldC5oYXMoa2V5KTtcbiAgICAgICAgICAgICAgICBpZiAoIWhhc0tleSkge1xuICAgICAgICAgICAgICAgICAgICBzZXQuYWRkKGtleSk7XG4gICAgICAgICAgICAgICAgICAgIGtleXMucHVzaChrZXkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBrZXlzO1xuICAgICAgICB9XG4gICAgICAgIC8vIDMuMS43LjEgT3JkaW5hcnlPd25NZXRhZGF0YUtleXMoTywgUClcbiAgICAgICAgLy8gaHR0cHM6Ly9yYnVja3Rvbi5naXRodWIuaW8vcmVmbGVjdC1tZXRhZGF0YS8jb3JkaW5hcnlvd25tZXRhZGF0YWtleXNcbiAgICAgICAgZnVuY3Rpb24gT3JkaW5hcnlPd25NZXRhZGF0YUtleXMoTywgUCkge1xuICAgICAgICAgICAgdmFyIGtleXMgPSBbXTtcbiAgICAgICAgICAgIHZhciBtZXRhZGF0YU1hcCA9IEdldE9yQ3JlYXRlTWV0YWRhdGFNYXAoTywgUCwgLypDcmVhdGUqLyBmYWxzZSk7XG4gICAgICAgICAgICBpZiAoSXNVbmRlZmluZWQobWV0YWRhdGFNYXApKVxuICAgICAgICAgICAgICAgIHJldHVybiBrZXlzO1xuICAgICAgICAgICAgdmFyIGtleXNPYmogPSBtZXRhZGF0YU1hcC5rZXlzKCk7XG4gICAgICAgICAgICB2YXIgaXRlcmF0b3IgPSBHZXRJdGVyYXRvcihrZXlzT2JqKTtcbiAgICAgICAgICAgIHZhciBrID0gMDtcbiAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICAgICAgdmFyIG5leHQgPSBJdGVyYXRvclN0ZXAoaXRlcmF0b3IpO1xuICAgICAgICAgICAgICAgIGlmICghbmV4dCkge1xuICAgICAgICAgICAgICAgICAgICBrZXlzLmxlbmd0aCA9IGs7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBrZXlzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgbmV4dFZhbHVlID0gSXRlcmF0b3JWYWx1ZShuZXh0KTtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBrZXlzW2tdID0gbmV4dFZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgSXRlcmF0b3JDbG9zZShpdGVyYXRvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZmluYWxseSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGsrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyA2IEVDTUFTY3JpcHQgRGF0YSBUeXAwZXMgYW5kIFZhbHVlc1xuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1lY21hc2NyaXB0LWRhdGEtdHlwZXMtYW5kLXZhbHVlc1xuICAgICAgICBmdW5jdGlvbiBUeXBlKHgpIHtcbiAgICAgICAgICAgIGlmICh4ID09PSBudWxsKVxuICAgICAgICAgICAgICAgIHJldHVybiAxIC8qIE51bGwgKi87XG4gICAgICAgICAgICBzd2l0Y2ggKHR5cGVvZiB4KSB7XG4gICAgICAgICAgICAgICAgY2FzZSBcInVuZGVmaW5lZFwiOiByZXR1cm4gMCAvKiBVbmRlZmluZWQgKi87XG4gICAgICAgICAgICAgICAgY2FzZSBcImJvb2xlYW5cIjogcmV0dXJuIDIgLyogQm9vbGVhbiAqLztcbiAgICAgICAgICAgICAgICBjYXNlIFwic3RyaW5nXCI6IHJldHVybiAzIC8qIFN0cmluZyAqLztcbiAgICAgICAgICAgICAgICBjYXNlIFwic3ltYm9sXCI6IHJldHVybiA0IC8qIFN5bWJvbCAqLztcbiAgICAgICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6IHJldHVybiA1IC8qIE51bWJlciAqLztcbiAgICAgICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6IHJldHVybiB4ID09PSBudWxsID8gMSAvKiBOdWxsICovIDogNiAvKiBPYmplY3QgKi87XG4gICAgICAgICAgICAgICAgZGVmYXVsdDogcmV0dXJuIDYgLyogT2JqZWN0ICovO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIDYuMS4xIFRoZSBVbmRlZmluZWQgVHlwZVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1lY21hc2NyaXB0LWxhbmd1YWdlLXR5cGVzLXVuZGVmaW5lZC10eXBlXG4gICAgICAgIGZ1bmN0aW9uIElzVW5kZWZpbmVkKHgpIHtcbiAgICAgICAgICAgIHJldHVybiB4ID09PSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNi4xLjIgVGhlIE51bGwgVHlwZVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1lY21hc2NyaXB0LWxhbmd1YWdlLXR5cGVzLW51bGwtdHlwZVxuICAgICAgICBmdW5jdGlvbiBJc051bGwoeCkge1xuICAgICAgICAgICAgcmV0dXJuIHggPT09IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNi4xLjUgVGhlIFN5bWJvbCBUeXBlXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWVjbWFzY3JpcHQtbGFuZ3VhZ2UtdHlwZXMtc3ltYm9sLXR5cGVcbiAgICAgICAgZnVuY3Rpb24gSXNTeW1ib2woeCkge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiB4ID09PSBcInN5bWJvbFwiO1xuICAgICAgICB9XG4gICAgICAgIC8vIDYuMS43IFRoZSBPYmplY3QgVHlwZVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1vYmplY3QtdHlwZVxuICAgICAgICBmdW5jdGlvbiBJc09iamVjdCh4KSB7XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIHggPT09IFwib2JqZWN0XCIgPyB4ICE9PSBudWxsIDogdHlwZW9mIHggPT09IFwiZnVuY3Rpb25cIjtcbiAgICAgICAgfVxuICAgICAgICAvLyA3LjEgVHlwZSBDb252ZXJzaW9uXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXR5cGUtY29udmVyc2lvblxuICAgICAgICAvLyA3LjEuMSBUb1ByaW1pdGl2ZShpbnB1dCBbLCBQcmVmZXJyZWRUeXBlXSlcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtdG9wcmltaXRpdmVcbiAgICAgICAgZnVuY3Rpb24gVG9QcmltaXRpdmUoaW5wdXQsIFByZWZlcnJlZFR5cGUpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoVHlwZShpbnB1dCkpIHtcbiAgICAgICAgICAgICAgICBjYXNlIDAgLyogVW5kZWZpbmVkICovOiByZXR1cm4gaW5wdXQ7XG4gICAgICAgICAgICAgICAgY2FzZSAxIC8qIE51bGwgKi86IHJldHVybiBpbnB1dDtcbiAgICAgICAgICAgICAgICBjYXNlIDIgLyogQm9vbGVhbiAqLzogcmV0dXJuIGlucHV0O1xuICAgICAgICAgICAgICAgIGNhc2UgMyAvKiBTdHJpbmcgKi86IHJldHVybiBpbnB1dDtcbiAgICAgICAgICAgICAgICBjYXNlIDQgLyogU3ltYm9sICovOiByZXR1cm4gaW5wdXQ7XG4gICAgICAgICAgICAgICAgY2FzZSA1IC8qIE51bWJlciAqLzogcmV0dXJuIGlucHV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGhpbnQgPSBQcmVmZXJyZWRUeXBlID09PSAzIC8qIFN0cmluZyAqLyA/IFwic3RyaW5nXCIgOiBQcmVmZXJyZWRUeXBlID09PSA1IC8qIE51bWJlciAqLyA/IFwibnVtYmVyXCIgOiBcImRlZmF1bHRcIjtcbiAgICAgICAgICAgIHZhciBleG90aWNUb1ByaW0gPSBHZXRNZXRob2QoaW5wdXQsIHRvUHJpbWl0aXZlU3ltYm9sKTtcbiAgICAgICAgICAgIGlmIChleG90aWNUb1ByaW0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBleG90aWNUb1ByaW0uY2FsbChpbnB1dCwgaGludCk7XG4gICAgICAgICAgICAgICAgaWYgKElzT2JqZWN0KHJlc3VsdCkpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIE9yZGluYXJ5VG9QcmltaXRpdmUoaW5wdXQsIGhpbnQgPT09IFwiZGVmYXVsdFwiID8gXCJudW1iZXJcIiA6IGhpbnQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIDcuMS4xLjEgT3JkaW5hcnlUb1ByaW1pdGl2ZShPLCBoaW50KVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1vcmRpbmFyeXRvcHJpbWl0aXZlXG4gICAgICAgIGZ1bmN0aW9uIE9yZGluYXJ5VG9QcmltaXRpdmUoTywgaGludCkge1xuICAgICAgICAgICAgaWYgKGhpbnQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgICB2YXIgdG9TdHJpbmdfMSA9IE8udG9TdHJpbmc7XG4gICAgICAgICAgICAgICAgaWYgKElzQ2FsbGFibGUodG9TdHJpbmdfMSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHRvU3RyaW5nXzEuY2FsbChPKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFJc09iamVjdChyZXN1bHQpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlT2YgPSBPLnZhbHVlT2Y7XG4gICAgICAgICAgICAgICAgaWYgKElzQ2FsbGFibGUodmFsdWVPZikpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHZhbHVlT2YuY2FsbChPKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFJc09iamVjdChyZXN1bHQpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgdmFsdWVPZiA9IE8udmFsdWVPZjtcbiAgICAgICAgICAgICAgICBpZiAoSXNDYWxsYWJsZSh2YWx1ZU9mKSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gdmFsdWVPZi5jYWxsKE8pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIUlzT2JqZWN0KHJlc3VsdCkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgdG9TdHJpbmdfMiA9IE8udG9TdHJpbmc7XG4gICAgICAgICAgICAgICAgaWYgKElzQ2FsbGFibGUodG9TdHJpbmdfMikpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHRvU3RyaW5nXzIuY2FsbChPKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFJc09iamVjdChyZXN1bHQpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy4xLjIgVG9Cb29sZWFuKGFyZ3VtZW50KVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvMjAxNi8jc2VjLXRvYm9vbGVhblxuICAgICAgICBmdW5jdGlvbiBUb0Jvb2xlYW4oYXJndW1lbnQpIHtcbiAgICAgICAgICAgIHJldHVybiAhIWFyZ3VtZW50O1xuICAgICAgICB9XG4gICAgICAgIC8vIDcuMS4xMiBUb1N0cmluZyhhcmd1bWVudClcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtdG9zdHJpbmdcbiAgICAgICAgZnVuY3Rpb24gVG9TdHJpbmcoYXJndW1lbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBcIlwiICsgYXJndW1lbnQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy4xLjE0IFRvUHJvcGVydHlLZXkoYXJndW1lbnQpXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXRvcHJvcGVydHlrZXlcbiAgICAgICAgZnVuY3Rpb24gVG9Qcm9wZXJ0eUtleShhcmd1bWVudCkge1xuICAgICAgICAgICAgdmFyIGtleSA9IFRvUHJpbWl0aXZlKGFyZ3VtZW50LCAzIC8qIFN0cmluZyAqLyk7XG4gICAgICAgICAgICBpZiAoSXNTeW1ib2woa2V5KSlcbiAgICAgICAgICAgICAgICByZXR1cm4ga2V5O1xuICAgICAgICAgICAgcmV0dXJuIFRvU3RyaW5nKGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy4yIFRlc3RpbmcgYW5kIENvbXBhcmlzb24gT3BlcmF0aW9uc1xuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy10ZXN0aW5nLWFuZC1jb21wYXJpc29uLW9wZXJhdGlvbnNcbiAgICAgICAgLy8gNy4yLjIgSXNBcnJheShhcmd1bWVudClcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtaXNhcnJheVxuICAgICAgICBmdW5jdGlvbiBJc0FycmF5KGFyZ3VtZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gQXJyYXkuaXNBcnJheVxuICAgICAgICAgICAgICAgID8gQXJyYXkuaXNBcnJheShhcmd1bWVudClcbiAgICAgICAgICAgICAgICA6IGFyZ3VtZW50IGluc3RhbmNlb2YgT2JqZWN0XG4gICAgICAgICAgICAgICAgICAgID8gYXJndW1lbnQgaW5zdGFuY2VvZiBBcnJheVxuICAgICAgICAgICAgICAgICAgICA6IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcmd1bWVudCkgPT09IFwiW29iamVjdCBBcnJheV1cIjtcbiAgICAgICAgfVxuICAgICAgICAvLyA3LjIuMyBJc0NhbGxhYmxlKGFyZ3VtZW50KVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1pc2NhbGxhYmxlXG4gICAgICAgIGZ1bmN0aW9uIElzQ2FsbGFibGUoYXJndW1lbnQpIHtcbiAgICAgICAgICAgIC8vIE5PVEU6IFRoaXMgaXMgYW4gYXBwcm94aW1hdGlvbiBhcyB3ZSBjYW5ub3QgY2hlY2sgZm9yIFtbQ2FsbF1dIGludGVybmFsIG1ldGhvZC5cbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgYXJndW1lbnQgPT09IFwiZnVuY3Rpb25cIjtcbiAgICAgICAgfVxuICAgICAgICAvLyA3LjIuNCBJc0NvbnN0cnVjdG9yKGFyZ3VtZW50KVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1pc2NvbnN0cnVjdG9yXG4gICAgICAgIGZ1bmN0aW9uIElzQ29uc3RydWN0b3IoYXJndW1lbnQpIHtcbiAgICAgICAgICAgIC8vIE5PVEU6IFRoaXMgaXMgYW4gYXBwcm94aW1hdGlvbiBhcyB3ZSBjYW5ub3QgY2hlY2sgZm9yIFtbQ29uc3RydWN0XV0gaW50ZXJuYWwgbWV0aG9kLlxuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBhcmd1bWVudCA9PT0gXCJmdW5jdGlvblwiO1xuICAgICAgICB9XG4gICAgICAgIC8vIDcuMi43IElzUHJvcGVydHlLZXkoYXJndW1lbnQpXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWlzcHJvcGVydHlrZXlcbiAgICAgICAgZnVuY3Rpb24gSXNQcm9wZXJ0eUtleShhcmd1bWVudCkge1xuICAgICAgICAgICAgc3dpdGNoIChUeXBlKGFyZ3VtZW50KSkge1xuICAgICAgICAgICAgICAgIGNhc2UgMyAvKiBTdHJpbmcgKi86IHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIGNhc2UgNCAvKiBTeW1ib2wgKi86IHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyA3LjMgT3BlcmF0aW9ucyBvbiBPYmplY3RzXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLW9wZXJhdGlvbnMtb24tb2JqZWN0c1xuICAgICAgICAvLyA3LjMuOSBHZXRNZXRob2QoViwgUClcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtZ2V0bWV0aG9kXG4gICAgICAgIGZ1bmN0aW9uIEdldE1ldGhvZChWLCBQKSB7XG4gICAgICAgICAgICB2YXIgZnVuYyA9IFZbUF07XG4gICAgICAgICAgICBpZiAoZnVuYyA9PT0gdW5kZWZpbmVkIHx8IGZ1bmMgPT09IG51bGwpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGlmICghSXNDYWxsYWJsZShmdW5jKSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICByZXR1cm4gZnVuYztcbiAgICAgICAgfVxuICAgICAgICAvLyA3LjQgT3BlcmF0aW9ucyBvbiBJdGVyYXRvciBPYmplY3RzXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLW9wZXJhdGlvbnMtb24taXRlcmF0b3Itb2JqZWN0c1xuICAgICAgICBmdW5jdGlvbiBHZXRJdGVyYXRvcihvYmopIHtcbiAgICAgICAgICAgIHZhciBtZXRob2QgPSBHZXRNZXRob2Qob2JqLCBpdGVyYXRvclN5bWJvbCk7XG4gICAgICAgICAgICBpZiAoIUlzQ2FsbGFibGUobWV0aG9kKSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7IC8vIGZyb20gQ2FsbFxuICAgICAgICAgICAgdmFyIGl0ZXJhdG9yID0gbWV0aG9kLmNhbGwob2JqKTtcbiAgICAgICAgICAgIGlmICghSXNPYmplY3QoaXRlcmF0b3IpKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgIHJldHVybiBpdGVyYXRvcjtcbiAgICAgICAgfVxuICAgICAgICAvLyA3LjQuNCBJdGVyYXRvclZhbHVlKGl0ZXJSZXN1bHQpXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8yMDE2LyNzZWMtaXRlcmF0b3J2YWx1ZVxuICAgICAgICBmdW5jdGlvbiBJdGVyYXRvclZhbHVlKGl0ZXJSZXN1bHQpIHtcbiAgICAgICAgICAgIHJldHVybiBpdGVyUmVzdWx0LnZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIDcuNC41IEl0ZXJhdG9yU3RlcChpdGVyYXRvcilcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtaXRlcmF0b3JzdGVwXG4gICAgICAgIGZ1bmN0aW9uIEl0ZXJhdG9yU3RlcChpdGVyYXRvcikge1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQuZG9uZSA/IGZhbHNlIDogcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIC8vIDcuNC42IEl0ZXJhdG9yQ2xvc2UoaXRlcmF0b3IsIGNvbXBsZXRpb24pXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWl0ZXJhdG9yY2xvc2VcbiAgICAgICAgZnVuY3Rpb24gSXRlcmF0b3JDbG9zZShpdGVyYXRvcikge1xuICAgICAgICAgICAgdmFyIGYgPSBpdGVyYXRvcltcInJldHVyblwiXTtcbiAgICAgICAgICAgIGlmIChmKVxuICAgICAgICAgICAgICAgIGYuY2FsbChpdGVyYXRvcik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gOS4xIE9yZGluYXJ5IE9iamVjdCBJbnRlcm5hbCBNZXRob2RzIGFuZCBJbnRlcm5hbCBTbG90c1xuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1vcmRpbmFyeS1vYmplY3QtaW50ZXJuYWwtbWV0aG9kcy1hbmQtaW50ZXJuYWwtc2xvdHNcbiAgICAgICAgLy8gOS4xLjEuMSBPcmRpbmFyeUdldFByb3RvdHlwZU9mKE8pXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLW9yZGluYXJ5Z2V0cHJvdG90eXBlb2ZcbiAgICAgICAgZnVuY3Rpb24gT3JkaW5hcnlHZXRQcm90b3R5cGVPZihPKSB7XG4gICAgICAgICAgICB2YXIgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoTyk7XG4gICAgICAgICAgICBpZiAodHlwZW9mIE8gIT09IFwiZnVuY3Rpb25cIiB8fCBPID09PSBmdW5jdGlvblByb3RvdHlwZSlcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvdG87XG4gICAgICAgICAgICAvLyBUeXBlU2NyaXB0IGRvZXNuJ3Qgc2V0IF9fcHJvdG9fXyBpbiBFUzUsIGFzIGl0J3Mgbm9uLXN0YW5kYXJkLlxuICAgICAgICAgICAgLy8gVHJ5IHRvIGRldGVybWluZSB0aGUgc3VwZXJjbGFzcyBjb25zdHJ1Y3Rvci4gQ29tcGF0aWJsZSBpbXBsZW1lbnRhdGlvbnNcbiAgICAgICAgICAgIC8vIG11c3QgZWl0aGVyIHNldCBfX3Byb3RvX18gb24gYSBzdWJjbGFzcyBjb25zdHJ1Y3RvciB0byB0aGUgc3VwZXJjbGFzcyBjb25zdHJ1Y3RvcixcbiAgICAgICAgICAgIC8vIG9yIGVuc3VyZSBlYWNoIGNsYXNzIGhhcyBhIHZhbGlkIGBjb25zdHJ1Y3RvcmAgcHJvcGVydHkgb24gaXRzIHByb3RvdHlwZSB0aGF0XG4gICAgICAgICAgICAvLyBwb2ludHMgYmFjayB0byB0aGUgY29uc3RydWN0b3IuXG4gICAgICAgICAgICAvLyBJZiB0aGlzIGlzIG5vdCB0aGUgc2FtZSBhcyBGdW5jdGlvbi5bW1Byb3RvdHlwZV1dLCB0aGVuIHRoaXMgaXMgZGVmaW5hdGVseSBpbmhlcml0ZWQuXG4gICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBjYXNlIHdoZW4gaW4gRVM2IG9yIHdoZW4gdXNpbmcgX19wcm90b19fIGluIGEgY29tcGF0aWJsZSBicm93c2VyLlxuICAgICAgICAgICAgaWYgKHByb3RvICE9PSBmdW5jdGlvblByb3RvdHlwZSlcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvdG87XG4gICAgICAgICAgICAvLyBJZiB0aGUgc3VwZXIgcHJvdG90eXBlIGlzIE9iamVjdC5wcm90b3R5cGUsIG51bGwsIG9yIHVuZGVmaW5lZCwgdGhlbiB3ZSBjYW5ub3QgZGV0ZXJtaW5lIHRoZSBoZXJpdGFnZS5cbiAgICAgICAgICAgIHZhciBwcm90b3R5cGUgPSBPLnByb3RvdHlwZTtcbiAgICAgICAgICAgIHZhciBwcm90b3R5cGVQcm90byA9IHByb3RvdHlwZSAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG90eXBlKTtcbiAgICAgICAgICAgIGlmIChwcm90b3R5cGVQcm90byA9PSBudWxsIHx8IHByb3RvdHlwZVByb3RvID09PSBPYmplY3QucHJvdG90eXBlKVxuICAgICAgICAgICAgICAgIHJldHVybiBwcm90bztcbiAgICAgICAgICAgIC8vIElmIHRoZSBjb25zdHJ1Y3RvciB3YXMgbm90IGEgZnVuY3Rpb24sIHRoZW4gd2UgY2Fubm90IGRldGVybWluZSB0aGUgaGVyaXRhZ2UuXG4gICAgICAgICAgICB2YXIgY29uc3RydWN0b3IgPSBwcm90b3R5cGVQcm90by5jb25zdHJ1Y3RvcjtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgY29uc3RydWN0b3IgIT09IFwiZnVuY3Rpb25cIilcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvdG87XG4gICAgICAgICAgICAvLyBJZiB3ZSBoYXZlIHNvbWUga2luZCBvZiBzZWxmLXJlZmVyZW5jZSwgdGhlbiB3ZSBjYW5ub3QgZGV0ZXJtaW5lIHRoZSBoZXJpdGFnZS5cbiAgICAgICAgICAgIGlmIChjb25zdHJ1Y3RvciA9PT0gTylcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvdG87XG4gICAgICAgICAgICAvLyB3ZSBoYXZlIGEgcHJldHR5IGdvb2QgZ3Vlc3MgYXQgdGhlIGhlcml0YWdlLlxuICAgICAgICAgICAgcmV0dXJuIGNvbnN0cnVjdG9yO1xuICAgICAgICB9XG4gICAgICAgIC8vIG5haXZlIE1hcCBzaGltXG4gICAgICAgIGZ1bmN0aW9uIENyZWF0ZU1hcFBvbHlmaWxsKCkge1xuICAgICAgICAgICAgdmFyIGNhY2hlU2VudGluZWwgPSB7fTtcbiAgICAgICAgICAgIHZhciBhcnJheVNlbnRpbmVsID0gW107XG4gICAgICAgICAgICB2YXIgTWFwSXRlcmF0b3IgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gTWFwSXRlcmF0b3Ioa2V5cywgdmFsdWVzLCBzZWxlY3Rvcikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbmRleCA9IDA7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2tleXMgPSBrZXlzO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZXMgPSB2YWx1ZXM7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3NlbGVjdG9yID0gc2VsZWN0b3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIE1hcEl0ZXJhdG9yLnByb3RvdHlwZVtcIkBAaXRlcmF0b3JcIl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9O1xuICAgICAgICAgICAgICAgIE1hcEl0ZXJhdG9yLnByb3RvdHlwZVtpdGVyYXRvclN5bWJvbF0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9O1xuICAgICAgICAgICAgICAgIE1hcEl0ZXJhdG9yLnByb3RvdHlwZS5uZXh0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSB0aGlzLl9pbmRleDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCB0aGlzLl9rZXlzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHRoaXMuX3NlbGVjdG9yKHRoaXMuX2tleXNbaW5kZXhdLCB0aGlzLl92YWx1ZXNbaW5kZXhdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCArIDEgPj0gdGhpcy5fa2V5cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbmRleCA9IC0xO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2tleXMgPSBhcnJheVNlbnRpbmVsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3ZhbHVlcyA9IGFycmF5U2VudGluZWw7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbmRleCsrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IHJlc3VsdCwgZG9uZTogZmFsc2UgfTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogdW5kZWZpbmVkLCBkb25lOiB0cnVlIH07XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBNYXBJdGVyYXRvci5wcm90b3R5cGUudGhyb3cgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2luZGV4ID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2luZGV4ID0gLTE7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXlzID0gYXJyYXlTZW50aW5lbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3ZhbHVlcyA9IGFycmF5U2VudGluZWw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBNYXBJdGVyYXRvci5wcm90b3R5cGUucmV0dXJuID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9pbmRleCA+PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbmRleCA9IC0xO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fa2V5cyA9IGFycmF5U2VudGluZWw7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZXMgPSBhcnJheVNlbnRpbmVsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiB2YWx1ZSwgZG9uZTogdHJ1ZSB9O1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIE1hcEl0ZXJhdG9yO1xuICAgICAgICAgICAgfSgpKTtcbiAgICAgICAgICAgIHJldHVybiAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gTWFwKCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXlzID0gW107XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3ZhbHVlcyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZUtleSA9IGNhY2hlU2VudGluZWw7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NhY2hlSW5kZXggPSAtMjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KE1hcC5wcm90b3R5cGUsIFwic2l6ZVwiLCB7XG4gICAgICAgICAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5fa2V5cy5sZW5ndGg7IH0sXG4gICAgICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIE1hcC5wcm90b3R5cGUuaGFzID0gZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gdGhpcy5fZmluZChrZXksIC8qaW5zZXJ0Ki8gZmFsc2UpID49IDA7IH07XG4gICAgICAgICAgICAgICAgTWFwLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IHRoaXMuX2ZpbmQoa2V5LCAvKmluc2VydCovIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluZGV4ID49IDAgPyB0aGlzLl92YWx1ZXNbaW5kZXhdIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgTWFwLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSB0aGlzLl9maW5kKGtleSwgLyppbnNlcnQqLyB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdmFsdWVzW2luZGV4XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIE1hcC5wcm90b3R5cGUuZGVsZXRlID0gZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSB0aGlzLl9maW5kKGtleSwgLyppbnNlcnQqLyBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2l6ZSA9IHRoaXMuX2tleXMubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IGluZGV4ICsgMTsgaSA8IHNpemU7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2tleXNbaSAtIDFdID0gdGhpcy5fa2V5c1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZXNbaSAtIDFdID0gdGhpcy5fdmFsdWVzW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fa2V5cy5sZW5ndGgtLTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3ZhbHVlcy5sZW5ndGgtLTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChrZXkgPT09IHRoaXMuX2NhY2hlS2V5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2FjaGVLZXkgPSBjYWNoZVNlbnRpbmVsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2NhY2hlSW5kZXggPSAtMjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIE1hcC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2tleXMubGVuZ3RoID0gMDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdmFsdWVzLmxlbmd0aCA9IDA7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NhY2hlS2V5ID0gY2FjaGVTZW50aW5lbDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2FjaGVJbmRleCA9IC0yO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgTWFwLnByb3RvdHlwZS5rZXlzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gbmV3IE1hcEl0ZXJhdG9yKHRoaXMuX2tleXMsIHRoaXMuX3ZhbHVlcywgZ2V0S2V5KTsgfTtcbiAgICAgICAgICAgICAgICBNYXAucHJvdG90eXBlLnZhbHVlcyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIG5ldyBNYXBJdGVyYXRvcih0aGlzLl9rZXlzLCB0aGlzLl92YWx1ZXMsIGdldFZhbHVlKTsgfTtcbiAgICAgICAgICAgICAgICBNYXAucHJvdG90eXBlLmVudHJpZXMgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBuZXcgTWFwSXRlcmF0b3IodGhpcy5fa2V5cywgdGhpcy5fdmFsdWVzLCBnZXRFbnRyeSk7IH07XG4gICAgICAgICAgICAgICAgTWFwLnByb3RvdHlwZVtcIkBAaXRlcmF0b3JcIl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLmVudHJpZXMoKTsgfTtcbiAgICAgICAgICAgICAgICBNYXAucHJvdG90eXBlW2l0ZXJhdG9yU3ltYm9sXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuZW50cmllcygpOyB9O1xuICAgICAgICAgICAgICAgIE1hcC5wcm90b3R5cGUuX2ZpbmQgPSBmdW5jdGlvbiAoa2V5LCBpbnNlcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2NhY2hlS2V5ICE9PSBrZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2NhY2hlSW5kZXggPSB0aGlzLl9rZXlzLmluZGV4T2YodGhpcy5fY2FjaGVLZXkgPSBrZXkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9jYWNoZUluZGV4IDwgMCAmJiBpbnNlcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2NhY2hlSW5kZXggPSB0aGlzLl9rZXlzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2tleXMucHVzaChrZXkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdmFsdWVzLnB1c2godW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fY2FjaGVJbmRleDtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJldHVybiBNYXA7XG4gICAgICAgICAgICB9KCkpO1xuICAgICAgICAgICAgZnVuY3Rpb24gZ2V0S2V5KGtleSwgXykge1xuICAgICAgICAgICAgICAgIHJldHVybiBrZXk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmdW5jdGlvbiBnZXRWYWx1ZShfLCB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZ1bmN0aW9uIGdldEVudHJ5KGtleSwgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW2tleSwgdmFsdWVdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIG5haXZlIFNldCBzaGltXG4gICAgICAgIGZ1bmN0aW9uIENyZWF0ZVNldFBvbHlmaWxsKCkge1xuICAgICAgICAgICAgcmV0dXJuIC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBTZXQoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX21hcCA9IG5ldyBfTWFwKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShTZXQucHJvdG90eXBlLCBcInNpemVcIiwge1xuICAgICAgICAgICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuX21hcC5zaXplOyB9LFxuICAgICAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBTZXQucHJvdG90eXBlLmhhcyA9IGZ1bmN0aW9uICh2YWx1ZSkgeyByZXR1cm4gdGhpcy5fbWFwLmhhcyh2YWx1ZSk7IH07XG4gICAgICAgICAgICAgICAgU2V0LnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIHRoaXMuX21hcC5zZXQodmFsdWUsIHZhbHVlKSwgdGhpczsgfTtcbiAgICAgICAgICAgICAgICBTZXQucHJvdG90eXBlLmRlbGV0ZSA9IGZ1bmN0aW9uICh2YWx1ZSkgeyByZXR1cm4gdGhpcy5fbWFwLmRlbGV0ZSh2YWx1ZSk7IH07XG4gICAgICAgICAgICAgICAgU2V0LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHsgdGhpcy5fbWFwLmNsZWFyKCk7IH07XG4gICAgICAgICAgICAgICAgU2V0LnByb3RvdHlwZS5rZXlzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5fbWFwLmtleXMoKTsgfTtcbiAgICAgICAgICAgICAgICBTZXQucHJvdG90eXBlLnZhbHVlcyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuX21hcC52YWx1ZXMoKTsgfTtcbiAgICAgICAgICAgICAgICBTZXQucHJvdG90eXBlLmVudHJpZXMgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLl9tYXAuZW50cmllcygpOyB9O1xuICAgICAgICAgICAgICAgIFNldC5wcm90b3R5cGVbXCJAQGl0ZXJhdG9yXCJdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5rZXlzKCk7IH07XG4gICAgICAgICAgICAgICAgU2V0LnByb3RvdHlwZVtpdGVyYXRvclN5bWJvbF0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLmtleXMoKTsgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gU2V0O1xuICAgICAgICAgICAgfSgpKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBuYWl2ZSBXZWFrTWFwIHNoaW1cbiAgICAgICAgZnVuY3Rpb24gQ3JlYXRlV2Vha01hcFBvbHlmaWxsKCkge1xuICAgICAgICAgICAgdmFyIFVVSURfU0laRSA9IDE2O1xuICAgICAgICAgICAgdmFyIGtleXMgPSBIYXNoTWFwLmNyZWF0ZSgpO1xuICAgICAgICAgICAgdmFyIHJvb3RLZXkgPSBDcmVhdGVVbmlxdWVLZXkoKTtcbiAgICAgICAgICAgIHJldHVybiAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gV2Vha01hcCgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fa2V5ID0gQ3JlYXRlVW5pcXVlS2V5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIFdlYWtNYXAucHJvdG90eXBlLmhhcyA9IGZ1bmN0aW9uICh0YXJnZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRhYmxlID0gR2V0T3JDcmVhdGVXZWFrTWFwVGFibGUodGFyZ2V0LCAvKmNyZWF0ZSovIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRhYmxlICE9PSB1bmRlZmluZWQgPyBIYXNoTWFwLmhhcyh0YWJsZSwgdGhpcy5fa2V5KSA6IGZhbHNlO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgV2Vha01hcC5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKHRhcmdldCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgdGFibGUgPSBHZXRPckNyZWF0ZVdlYWtNYXBUYWJsZSh0YXJnZXQsIC8qY3JlYXRlKi8gZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGFibGUgIT09IHVuZGVmaW5lZCA/IEhhc2hNYXAuZ2V0KHRhYmxlLCB0aGlzLl9rZXkpIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgV2Vha01hcC5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKHRhcmdldCwgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRhYmxlID0gR2V0T3JDcmVhdGVXZWFrTWFwVGFibGUodGFyZ2V0LCAvKmNyZWF0ZSovIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB0YWJsZVt0aGlzLl9rZXldID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgV2Vha01hcC5wcm90b3R5cGUuZGVsZXRlID0gZnVuY3Rpb24gKHRhcmdldCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgdGFibGUgPSBHZXRPckNyZWF0ZVdlYWtNYXBUYWJsZSh0YXJnZXQsIC8qY3JlYXRlKi8gZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGFibGUgIT09IHVuZGVmaW5lZCA/IGRlbGV0ZSB0YWJsZVt0aGlzLl9rZXldIDogZmFsc2U7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBXZWFrTWFwLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gTk9URTogbm90IGEgcmVhbCBjbGVhciwganVzdCBtYWtlcyB0aGUgcHJldmlvdXMgZGF0YSB1bnJlYWNoYWJsZVxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXkgPSBDcmVhdGVVbmlxdWVLZXkoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJldHVybiBXZWFrTWFwO1xuICAgICAgICAgICAgfSgpKTtcbiAgICAgICAgICAgIGZ1bmN0aW9uIENyZWF0ZVVuaXF1ZUtleSgpIHtcbiAgICAgICAgICAgICAgICB2YXIga2V5O1xuICAgICAgICAgICAgICAgIGRvXG4gICAgICAgICAgICAgICAgICAgIGtleSA9IFwiQEBXZWFrTWFwQEBcIiArIENyZWF0ZVVVSUQoKTtcbiAgICAgICAgICAgICAgICB3aGlsZSAoSGFzaE1hcC5oYXMoa2V5cywga2V5KSk7XG4gICAgICAgICAgICAgICAga2V5c1trZXldID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICByZXR1cm4ga2V5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZnVuY3Rpb24gR2V0T3JDcmVhdGVXZWFrTWFwVGFibGUodGFyZ2V0LCBjcmVhdGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWhhc093bi5jYWxsKHRhcmdldCwgcm9vdEtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjcmVhdGUpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCByb290S2V5LCB7IHZhbHVlOiBIYXNoTWFwLmNyZWF0ZSgpIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0W3Jvb3RLZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZnVuY3Rpb24gRmlsbFJhbmRvbUJ5dGVzKGJ1ZmZlciwgc2l6ZSkge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2l6ZTsgKytpKVxuICAgICAgICAgICAgICAgICAgICBidWZmZXJbaV0gPSBNYXRoLnJhbmRvbSgpICogMHhmZiB8IDA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZ1bmN0aW9uIEdlblJhbmRvbUJ5dGVzKHNpemUpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIFVpbnQ4QXJyYXkgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGNyeXB0byAhPT0gXCJ1bmRlZmluZWRcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKG5ldyBVaW50OEFycmF5KHNpemUpKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtc0NyeXB0byAhPT0gXCJ1bmRlZmluZWRcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBtc0NyeXB0by5nZXRSYW5kb21WYWx1ZXMobmV3IFVpbnQ4QXJyYXkoc2l6ZSkpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRmlsbFJhbmRvbUJ5dGVzKG5ldyBVaW50OEFycmF5KHNpemUpLCBzaXplKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIEZpbGxSYW5kb21CeXRlcyhuZXcgQXJyYXkoc2l6ZSksIHNpemUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZnVuY3Rpb24gQ3JlYXRlVVVJRCgpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGF0YSA9IEdlblJhbmRvbUJ5dGVzKFVVSURfU0laRSk7XG4gICAgICAgICAgICAgICAgLy8gbWFyayBhcyByYW5kb20gLSBSRkMgNDEyMiDCpyA0LjRcbiAgICAgICAgICAgICAgICBkYXRhWzZdID0gZGF0YVs2XSAmIDB4NGYgfCAweDQwO1xuICAgICAgICAgICAgICAgIGRhdGFbOF0gPSBkYXRhWzhdICYgMHhiZiB8IDB4ODA7XG4gICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IFwiXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgb2Zmc2V0ID0gMDsgb2Zmc2V0IDwgVVVJRF9TSVpFOyArK29mZnNldCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgYnl0ZSA9IGRhdGFbb2Zmc2V0XTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9mZnNldCA9PT0gNCB8fCBvZmZzZXQgPT09IDYgfHwgb2Zmc2V0ID09PSA4KVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ICs9IFwiLVwiO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYnl0ZSA8IDE2KVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ICs9IFwiMFwiO1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgKz0gYnl0ZS50b1N0cmluZygxNikudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyB1c2VzIGEgaGV1cmlzdGljIHVzZWQgYnkgdjggYW5kIGNoYWtyYSB0byBmb3JjZSBhbiBvYmplY3QgaW50byBkaWN0aW9uYXJ5IG1vZGUuXG4gICAgICAgIGZ1bmN0aW9uIE1ha2VEaWN0aW9uYXJ5KG9iaikge1xuICAgICAgICAgICAgb2JqLl9fID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgZGVsZXRlIG9iai5fXztcbiAgICAgICAgICAgIHJldHVybiBvYmo7XG4gICAgICAgIH1cbiAgICB9KTtcbn0pKFJlZmxlY3QgfHwgKFJlZmxlY3QgPSB7fSkpO1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBjbXAgKGEsIGIpIHtcbiAgICB2YXIgcGEgPSBhLnNwbGl0KCcuJyk7XG4gICAgdmFyIHBiID0gYi5zcGxpdCgnLicpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMzsgaSsrKSB7XG4gICAgICAgIHZhciBuYSA9IE51bWJlcihwYVtpXSk7XG4gICAgICAgIHZhciBuYiA9IE51bWJlcihwYltpXSk7XG4gICAgICAgIGlmIChuYSA+IG5iKSByZXR1cm4gMTtcbiAgICAgICAgaWYgKG5iID4gbmEpIHJldHVybiAtMTtcbiAgICAgICAgaWYgKCFpc05hTihuYSkgJiYgaXNOYU4obmIpKSByZXR1cm4gMTtcbiAgICAgICAgaWYgKGlzTmFOKG5hKSAmJiAhaXNOYU4obmIpKSByZXR1cm4gLTE7XG4gICAgfVxuICAgIHJldHVybiAwO1xufTtcbiIsImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IFNlbVZlclxuXG52YXIgZGVidWdcbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5pZiAodHlwZW9mIHByb2Nlc3MgPT09ICdvYmplY3QnICYmXG4gICAgcHJvY2Vzcy5lbnYgJiZcbiAgICBwcm9jZXNzLmVudi5OT0RFX0RFQlVHICYmXG4gICAgL1xcYnNlbXZlclxcYi9pLnRlc3QocHJvY2Vzcy5lbnYuTk9ERV9ERUJVRykpIHtcbiAgZGVidWcgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApXG4gICAgYXJncy51bnNoaWZ0KCdTRU1WRVInKVxuICAgIGNvbnNvbGUubG9nLmFwcGx5KGNvbnNvbGUsIGFyZ3MpXG4gIH1cbn0gZWxzZSB7XG4gIGRlYnVnID0gZnVuY3Rpb24gKCkge31cbn1cblxuLy8gTm90ZTogdGhpcyBpcyB0aGUgc2VtdmVyLm9yZyB2ZXJzaW9uIG9mIHRoZSBzcGVjIHRoYXQgaXQgaW1wbGVtZW50c1xuLy8gTm90IG5lY2Vzc2FyaWx5IHRoZSBwYWNrYWdlIHZlcnNpb24gb2YgdGhpcyBjb2RlLlxuZXhwb3J0cy5TRU1WRVJfU1BFQ19WRVJTSU9OID0gJzIuMC4wJ1xuXG52YXIgTUFYX0xFTkdUSCA9IDI1NlxudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUiB8fFxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyA5MDA3MTk5MjU0NzQwOTkxXG5cbi8vIE1heCBzYWZlIHNlZ21lbnQgbGVuZ3RoIGZvciBjb2VyY2lvbi5cbnZhciBNQVhfU0FGRV9DT01QT05FTlRfTEVOR1RIID0gMTZcblxuLy8gVGhlIGFjdHVhbCByZWdleHBzIGdvIG9uIGV4cG9ydHMucmVcbnZhciByZSA9IGV4cG9ydHMucmUgPSBbXVxudmFyIHNyYyA9IGV4cG9ydHMuc3JjID0gW11cbnZhciBSID0gMFxuXG4vLyBUaGUgZm9sbG93aW5nIFJlZ3VsYXIgRXhwcmVzc2lvbnMgY2FuIGJlIHVzZWQgZm9yIHRva2VuaXppbmcsXG4vLyB2YWxpZGF0aW5nLCBhbmQgcGFyc2luZyBTZW1WZXIgdmVyc2lvbiBzdHJpbmdzLlxuXG4vLyAjIyBOdW1lcmljIElkZW50aWZpZXJcbi8vIEEgc2luZ2xlIGAwYCwgb3IgYSBub24temVybyBkaWdpdCBmb2xsb3dlZCBieSB6ZXJvIG9yIG1vcmUgZGlnaXRzLlxuXG52YXIgTlVNRVJJQ0lERU5USUZJRVIgPSBSKytcbnNyY1tOVU1FUklDSURFTlRJRklFUl0gPSAnMHxbMS05XVxcXFxkKidcbnZhciBOVU1FUklDSURFTlRJRklFUkxPT1NFID0gUisrXG5zcmNbTlVNRVJJQ0lERU5USUZJRVJMT09TRV0gPSAnWzAtOV0rJ1xuXG4vLyAjIyBOb24tbnVtZXJpYyBJZGVudGlmaWVyXG4vLyBaZXJvIG9yIG1vcmUgZGlnaXRzLCBmb2xsb3dlZCBieSBhIGxldHRlciBvciBoeXBoZW4sIGFuZCB0aGVuIHplcm8gb3Jcbi8vIG1vcmUgbGV0dGVycywgZGlnaXRzLCBvciBoeXBoZW5zLlxuXG52YXIgTk9OTlVNRVJJQ0lERU5USUZJRVIgPSBSKytcbnNyY1tOT05OVU1FUklDSURFTlRJRklFUl0gPSAnXFxcXGQqW2EtekEtWi1dW2EtekEtWjAtOS1dKidcblxuLy8gIyMgTWFpbiBWZXJzaW9uXG4vLyBUaHJlZSBkb3Qtc2VwYXJhdGVkIG51bWVyaWMgaWRlbnRpZmllcnMuXG5cbnZhciBNQUlOVkVSU0lPTiA9IFIrK1xuc3JjW01BSU5WRVJTSU9OXSA9ICcoJyArIHNyY1tOVU1FUklDSURFTlRJRklFUl0gKyAnKVxcXFwuJyArXG4gICAgICAgICAgICAgICAgICAgJygnICsgc3JjW05VTUVSSUNJREVOVElGSUVSXSArICcpXFxcXC4nICtcbiAgICAgICAgICAgICAgICAgICAnKCcgKyBzcmNbTlVNRVJJQ0lERU5USUZJRVJdICsgJyknXG5cbnZhciBNQUlOVkVSU0lPTkxPT1NFID0gUisrXG5zcmNbTUFJTlZFUlNJT05MT09TRV0gPSAnKCcgKyBzcmNbTlVNRVJJQ0lERU5USUZJRVJMT09TRV0gKyAnKVxcXFwuJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKCcgKyBzcmNbTlVNRVJJQ0lERU5USUZJRVJMT09TRV0gKyAnKVxcXFwuJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKCcgKyBzcmNbTlVNRVJJQ0lERU5USUZJRVJMT09TRV0gKyAnKSdcblxuLy8gIyMgUHJlLXJlbGVhc2UgVmVyc2lvbiBJZGVudGlmaWVyXG4vLyBBIG51bWVyaWMgaWRlbnRpZmllciwgb3IgYSBub24tbnVtZXJpYyBpZGVudGlmaWVyLlxuXG52YXIgUFJFUkVMRUFTRUlERU5USUZJRVIgPSBSKytcbnNyY1tQUkVSRUxFQVNFSURFTlRJRklFUl0gPSAnKD86JyArIHNyY1tOVU1FUklDSURFTlRJRklFUl0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd8JyArIHNyY1tOT05OVU1FUklDSURFTlRJRklFUl0gKyAnKSdcblxudmFyIFBSRVJFTEVBU0VJREVOVElGSUVSTE9PU0UgPSBSKytcbnNyY1tQUkVSRUxFQVNFSURFTlRJRklFUkxPT1NFXSA9ICcoPzonICsgc3JjW05VTUVSSUNJREVOVElGSUVSTE9PU0VdICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd8JyArIHNyY1tOT05OVU1FUklDSURFTlRJRklFUl0gKyAnKSdcblxuLy8gIyMgUHJlLXJlbGVhc2UgVmVyc2lvblxuLy8gSHlwaGVuLCBmb2xsb3dlZCBieSBvbmUgb3IgbW9yZSBkb3Qtc2VwYXJhdGVkIHByZS1yZWxlYXNlIHZlcnNpb25cbi8vIGlkZW50aWZpZXJzLlxuXG52YXIgUFJFUkVMRUFTRSA9IFIrK1xuc3JjW1BSRVJFTEVBU0VdID0gJyg/Oi0oJyArIHNyY1tQUkVSRUxFQVNFSURFTlRJRklFUl0gK1xuICAgICAgICAgICAgICAgICAgJyg/OlxcXFwuJyArIHNyY1tQUkVSRUxFQVNFSURFTlRJRklFUl0gKyAnKSopKSdcblxudmFyIFBSRVJFTEVBU0VMT09TRSA9IFIrK1xuc3JjW1BSRVJFTEVBU0VMT09TRV0gPSAnKD86LT8oJyArIHNyY1tQUkVSRUxFQVNFSURFTlRJRklFUkxPT1NFXSArXG4gICAgICAgICAgICAgICAgICAgICAgICcoPzpcXFxcLicgKyBzcmNbUFJFUkVMRUFTRUlERU5USUZJRVJMT09TRV0gKyAnKSopKSdcblxuLy8gIyMgQnVpbGQgTWV0YWRhdGEgSWRlbnRpZmllclxuLy8gQW55IGNvbWJpbmF0aW9uIG9mIGRpZ2l0cywgbGV0dGVycywgb3IgaHlwaGVucy5cblxudmFyIEJVSUxESURFTlRJRklFUiA9IFIrK1xuc3JjW0JVSUxESURFTlRJRklFUl0gPSAnWzAtOUEtWmEtei1dKydcblxuLy8gIyMgQnVpbGQgTWV0YWRhdGFcbi8vIFBsdXMgc2lnbiwgZm9sbG93ZWQgYnkgb25lIG9yIG1vcmUgcGVyaW9kLXNlcGFyYXRlZCBidWlsZCBtZXRhZGF0YVxuLy8gaWRlbnRpZmllcnMuXG5cbnZhciBCVUlMRCA9IFIrK1xuc3JjW0JVSUxEXSA9ICcoPzpcXFxcKygnICsgc3JjW0JVSUxESURFTlRJRklFUl0gK1xuICAgICAgICAgICAgICcoPzpcXFxcLicgKyBzcmNbQlVJTERJREVOVElGSUVSXSArICcpKikpJ1xuXG4vLyAjIyBGdWxsIFZlcnNpb24gU3RyaW5nXG4vLyBBIG1haW4gdmVyc2lvbiwgZm9sbG93ZWQgb3B0aW9uYWxseSBieSBhIHByZS1yZWxlYXNlIHZlcnNpb24gYW5kXG4vLyBidWlsZCBtZXRhZGF0YS5cblxuLy8gTm90ZSB0aGF0IHRoZSBvbmx5IG1ham9yLCBtaW5vciwgcGF0Y2gsIGFuZCBwcmUtcmVsZWFzZSBzZWN0aW9ucyBvZlxuLy8gdGhlIHZlcnNpb24gc3RyaW5nIGFyZSBjYXB0dXJpbmcgZ3JvdXBzLiAgVGhlIGJ1aWxkIG1ldGFkYXRhIGlzIG5vdCBhXG4vLyBjYXB0dXJpbmcgZ3JvdXAsIGJlY2F1c2UgaXQgc2hvdWxkIG5vdCBldmVyIGJlIHVzZWQgaW4gdmVyc2lvblxuLy8gY29tcGFyaXNvbi5cblxudmFyIEZVTEwgPSBSKytcbnZhciBGVUxMUExBSU4gPSAndj8nICsgc3JjW01BSU5WRVJTSU9OXSArXG4gICAgICAgICAgICAgICAgc3JjW1BSRVJFTEVBU0VdICsgJz8nICtcbiAgICAgICAgICAgICAgICBzcmNbQlVJTERdICsgJz8nXG5cbnNyY1tGVUxMXSA9ICdeJyArIEZVTExQTEFJTiArICckJ1xuXG4vLyBsaWtlIGZ1bGwsIGJ1dCBhbGxvd3MgdjEuMi4zIGFuZCA9MS4yLjMsIHdoaWNoIHBlb3BsZSBkbyBzb21ldGltZXMuXG4vLyBhbHNvLCAxLjAuMGFscGhhMSAocHJlcmVsZWFzZSB3aXRob3V0IHRoZSBoeXBoZW4pIHdoaWNoIGlzIHByZXR0eVxuLy8gY29tbW9uIGluIHRoZSBucG0gcmVnaXN0cnkuXG52YXIgTE9PU0VQTEFJTiA9ICdbdj1cXFxcc10qJyArIHNyY1tNQUlOVkVSU0lPTkxPT1NFXSArXG4gICAgICAgICAgICAgICAgIHNyY1tQUkVSRUxFQVNFTE9PU0VdICsgJz8nICtcbiAgICAgICAgICAgICAgICAgc3JjW0JVSUxEXSArICc/J1xuXG52YXIgTE9PU0UgPSBSKytcbnNyY1tMT09TRV0gPSAnXicgKyBMT09TRVBMQUlOICsgJyQnXG5cbnZhciBHVExUID0gUisrXG5zcmNbR1RMVF0gPSAnKCg/Ojx8Pik/PT8pJ1xuXG4vLyBTb21ldGhpbmcgbGlrZSBcIjIuKlwiIG9yIFwiMS4yLnhcIi5cbi8vIE5vdGUgdGhhdCBcIngueFwiIGlzIGEgdmFsaWQgeFJhbmdlIGlkZW50aWZlciwgbWVhbmluZyBcImFueSB2ZXJzaW9uXCJcbi8vIE9ubHkgdGhlIGZpcnN0IGl0ZW0gaXMgc3RyaWN0bHkgcmVxdWlyZWQuXG52YXIgWFJBTkdFSURFTlRJRklFUkxPT1NFID0gUisrXG5zcmNbWFJBTkdFSURFTlRJRklFUkxPT1NFXSA9IHNyY1tOVU1FUklDSURFTlRJRklFUkxPT1NFXSArICd8eHxYfFxcXFwqJ1xudmFyIFhSQU5HRUlERU5USUZJRVIgPSBSKytcbnNyY1tYUkFOR0VJREVOVElGSUVSXSA9IHNyY1tOVU1FUklDSURFTlRJRklFUl0gKyAnfHh8WHxcXFxcKidcblxudmFyIFhSQU5HRVBMQUlOID0gUisrXG5zcmNbWFJBTkdFUExBSU5dID0gJ1t2PVxcXFxzXSooJyArIHNyY1tYUkFOR0VJREVOVElGSUVSXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgJyg/OlxcXFwuKCcgKyBzcmNbWFJBTkdFSURFTlRJRklFUl0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICcoPzpcXFxcLignICsgc3JjW1hSQU5HRUlERU5USUZJRVJdICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAnKD86JyArIHNyY1tQUkVSRUxFQVNFXSArICcpPycgK1xuICAgICAgICAgICAgICAgICAgIHNyY1tCVUlMRF0gKyAnPycgK1xuICAgICAgICAgICAgICAgICAgICcpPyk/J1xuXG52YXIgWFJBTkdFUExBSU5MT09TRSA9IFIrK1xuc3JjW1hSQU5HRVBMQUlOTE9PU0VdID0gJ1t2PVxcXFxzXSooJyArIHNyY1tYUkFOR0VJREVOVElGSUVSTE9PU0VdICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcoPzpcXFxcLignICsgc3JjW1hSQU5HRUlERU5USUZJRVJMT09TRV0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJyg/OlxcXFwuKCcgKyBzcmNbWFJBTkdFSURFTlRJRklFUkxPT1NFXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKD86JyArIHNyY1tQUkVSRUxFQVNFTE9PU0VdICsgJyk/JyArXG4gICAgICAgICAgICAgICAgICAgICAgICBzcmNbQlVJTERdICsgJz8nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcpPyk/J1xuXG52YXIgWFJBTkdFID0gUisrXG5zcmNbWFJBTkdFXSA9ICdeJyArIHNyY1tHVExUXSArICdcXFxccyonICsgc3JjW1hSQU5HRVBMQUlOXSArICckJ1xudmFyIFhSQU5HRUxPT1NFID0gUisrXG5zcmNbWFJBTkdFTE9PU0VdID0gJ14nICsgc3JjW0dUTFRdICsgJ1xcXFxzKicgKyBzcmNbWFJBTkdFUExBSU5MT09TRV0gKyAnJCdcblxuLy8gQ29lcmNpb24uXG4vLyBFeHRyYWN0IGFueXRoaW5nIHRoYXQgY291bGQgY29uY2VpdmFibHkgYmUgYSBwYXJ0IG9mIGEgdmFsaWQgc2VtdmVyXG52YXIgQ09FUkNFID0gUisrXG5zcmNbQ09FUkNFXSA9ICcoPzpefFteXFxcXGRdKScgK1xuICAgICAgICAgICAgICAnKFxcXFxkezEsJyArIE1BWF9TQUZFX0NPTVBPTkVOVF9MRU5HVEggKyAnfSknICtcbiAgICAgICAgICAgICAgJyg/OlxcXFwuKFxcXFxkezEsJyArIE1BWF9TQUZFX0NPTVBPTkVOVF9MRU5HVEggKyAnfSkpPycgK1xuICAgICAgICAgICAgICAnKD86XFxcXC4oXFxcXGR7MSwnICsgTUFYX1NBRkVfQ09NUE9ORU5UX0xFTkdUSCArICd9KSk/JyArXG4gICAgICAgICAgICAgICcoPzokfFteXFxcXGRdKSdcblxuLy8gVGlsZGUgcmFuZ2VzLlxuLy8gTWVhbmluZyBpcyBcInJlYXNvbmFibHkgYXQgb3IgZ3JlYXRlciB0aGFuXCJcbnZhciBMT05FVElMREUgPSBSKytcbnNyY1tMT05FVElMREVdID0gJyg/On4+PyknXG5cbnZhciBUSUxERVRSSU0gPSBSKytcbnNyY1tUSUxERVRSSU1dID0gJyhcXFxccyopJyArIHNyY1tMT05FVElMREVdICsgJ1xcXFxzKydcbnJlW1RJTERFVFJJTV0gPSBuZXcgUmVnRXhwKHNyY1tUSUxERVRSSU1dLCAnZycpXG52YXIgdGlsZGVUcmltUmVwbGFjZSA9ICckMX4nXG5cbnZhciBUSUxERSA9IFIrK1xuc3JjW1RJTERFXSA9ICdeJyArIHNyY1tMT05FVElMREVdICsgc3JjW1hSQU5HRVBMQUlOXSArICckJ1xudmFyIFRJTERFTE9PU0UgPSBSKytcbnNyY1tUSUxERUxPT1NFXSA9ICdeJyArIHNyY1tMT05FVElMREVdICsgc3JjW1hSQU5HRVBMQUlOTE9PU0VdICsgJyQnXG5cbi8vIENhcmV0IHJhbmdlcy5cbi8vIE1lYW5pbmcgaXMgXCJhdCBsZWFzdCBhbmQgYmFja3dhcmRzIGNvbXBhdGlibGUgd2l0aFwiXG52YXIgTE9ORUNBUkVUID0gUisrXG5zcmNbTE9ORUNBUkVUXSA9ICcoPzpcXFxcXiknXG5cbnZhciBDQVJFVFRSSU0gPSBSKytcbnNyY1tDQVJFVFRSSU1dID0gJyhcXFxccyopJyArIHNyY1tMT05FQ0FSRVRdICsgJ1xcXFxzKydcbnJlW0NBUkVUVFJJTV0gPSBuZXcgUmVnRXhwKHNyY1tDQVJFVFRSSU1dLCAnZycpXG52YXIgY2FyZXRUcmltUmVwbGFjZSA9ICckMV4nXG5cbnZhciBDQVJFVCA9IFIrK1xuc3JjW0NBUkVUXSA9ICdeJyArIHNyY1tMT05FQ0FSRVRdICsgc3JjW1hSQU5HRVBMQUlOXSArICckJ1xudmFyIENBUkVUTE9PU0UgPSBSKytcbnNyY1tDQVJFVExPT1NFXSA9ICdeJyArIHNyY1tMT05FQ0FSRVRdICsgc3JjW1hSQU5HRVBMQUlOTE9PU0VdICsgJyQnXG5cbi8vIEEgc2ltcGxlIGd0L2x0L2VxIHRoaW5nLCBvciBqdXN0IFwiXCIgdG8gaW5kaWNhdGUgXCJhbnkgdmVyc2lvblwiXG52YXIgQ09NUEFSQVRPUkxPT1NFID0gUisrXG5zcmNbQ09NUEFSQVRPUkxPT1NFXSA9ICdeJyArIHNyY1tHVExUXSArICdcXFxccyooJyArIExPT1NFUExBSU4gKyAnKSR8XiQnXG52YXIgQ09NUEFSQVRPUiA9IFIrK1xuc3JjW0NPTVBBUkFUT1JdID0gJ14nICsgc3JjW0dUTFRdICsgJ1xcXFxzKignICsgRlVMTFBMQUlOICsgJykkfF4kJ1xuXG4vLyBBbiBleHByZXNzaW9uIHRvIHN0cmlwIGFueSB3aGl0ZXNwYWNlIGJldHdlZW4gdGhlIGd0bHQgYW5kIHRoZSB0aGluZ1xuLy8gaXQgbW9kaWZpZXMsIHNvIHRoYXQgYD4gMS4yLjNgID09PiBgPjEuMi4zYFxudmFyIENPTVBBUkFUT1JUUklNID0gUisrXG5zcmNbQ09NUEFSQVRPUlRSSU1dID0gJyhcXFxccyopJyArIHNyY1tHVExUXSArXG4gICAgICAgICAgICAgICAgICAgICAgJ1xcXFxzKignICsgTE9PU0VQTEFJTiArICd8JyArIHNyY1tYUkFOR0VQTEFJTl0gKyAnKSdcblxuLy8gdGhpcyBvbmUgaGFzIHRvIHVzZSB0aGUgL2cgZmxhZ1xucmVbQ09NUEFSQVRPUlRSSU1dID0gbmV3IFJlZ0V4cChzcmNbQ09NUEFSQVRPUlRSSU1dLCAnZycpXG52YXIgY29tcGFyYXRvclRyaW1SZXBsYWNlID0gJyQxJDIkMydcblxuLy8gU29tZXRoaW5nIGxpa2UgYDEuMi4zIC0gMS4yLjRgXG4vLyBOb3RlIHRoYXQgdGhlc2UgYWxsIHVzZSB0aGUgbG9vc2UgZm9ybSwgYmVjYXVzZSB0aGV5J2xsIGJlXG4vLyBjaGVja2VkIGFnYWluc3QgZWl0aGVyIHRoZSBzdHJpY3Qgb3IgbG9vc2UgY29tcGFyYXRvciBmb3JtXG4vLyBsYXRlci5cbnZhciBIWVBIRU5SQU5HRSA9IFIrK1xuc3JjW0hZUEhFTlJBTkdFXSA9ICdeXFxcXHMqKCcgKyBzcmNbWFJBTkdFUExBSU5dICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAnXFxcXHMrLVxcXFxzKycgK1xuICAgICAgICAgICAgICAgICAgICcoJyArIHNyY1tYUkFOR0VQTEFJTl0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICdcXFxccyokJ1xuXG52YXIgSFlQSEVOUkFOR0VMT09TRSA9IFIrK1xuc3JjW0hZUEhFTlJBTkdFTE9PU0VdID0gJ15cXFxccyooJyArIHNyY1tYUkFOR0VQTEFJTkxPT1NFXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnXFxcXHMrLVxcXFxzKycgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJygnICsgc3JjW1hSQU5HRVBMQUlOTE9PU0VdICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAgICAgICdcXFxccyokJ1xuXG4vLyBTdGFyIHJhbmdlcyBiYXNpY2FsbHkganVzdCBhbGxvdyBhbnl0aGluZyBhdCBhbGwuXG52YXIgU1RBUiA9IFIrK1xuc3JjW1NUQVJdID0gJyg8fD4pPz0/XFxcXHMqXFxcXConXG5cbi8vIENvbXBpbGUgdG8gYWN0dWFsIHJlZ2V4cCBvYmplY3RzLlxuLy8gQWxsIGFyZSBmbGFnLWZyZWUsIHVubGVzcyB0aGV5IHdlcmUgY3JlYXRlZCBhYm92ZSB3aXRoIGEgZmxhZy5cbmZvciAodmFyIGkgPSAwOyBpIDwgUjsgaSsrKSB7XG4gIGRlYnVnKGksIHNyY1tpXSlcbiAgaWYgKCFyZVtpXSkge1xuICAgIHJlW2ldID0gbmV3IFJlZ0V4cChzcmNbaV0pXG4gIH1cbn1cblxuZXhwb3J0cy5wYXJzZSA9IHBhcnNlXG5mdW5jdGlvbiBwYXJzZSAodmVyc2lvbiwgb3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMgfHwgdHlwZW9mIG9wdGlvbnMgIT09ICdvYmplY3QnKSB7XG4gICAgb3B0aW9ucyA9IHtcbiAgICAgIGxvb3NlOiAhIW9wdGlvbnMsXG4gICAgICBpbmNsdWRlUHJlcmVsZWFzZTogZmFsc2VcbiAgICB9XG4gIH1cblxuICBpZiAodmVyc2lvbiBpbnN0YW5jZW9mIFNlbVZlcikge1xuICAgIHJldHVybiB2ZXJzaW9uXG4gIH1cblxuICBpZiAodHlwZW9mIHZlcnNpb24gIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIGlmICh2ZXJzaW9uLmxlbmd0aCA+IE1BWF9MRU5HVEgpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgdmFyIHIgPSBvcHRpb25zLmxvb3NlID8gcmVbTE9PU0VdIDogcmVbRlVMTF1cbiAgaWYgKCFyLnRlc3QodmVyc2lvbikpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gbmV3IFNlbVZlcih2ZXJzaW9uLCBvcHRpb25zKVxuICB9IGNhdGNoIChlcikge1xuICAgIHJldHVybiBudWxsXG4gIH1cbn1cblxuZXhwb3J0cy52YWxpZCA9IHZhbGlkXG5mdW5jdGlvbiB2YWxpZCAodmVyc2lvbiwgb3B0aW9ucykge1xuICB2YXIgdiA9IHBhcnNlKHZlcnNpb24sIG9wdGlvbnMpXG4gIHJldHVybiB2ID8gdi52ZXJzaW9uIDogbnVsbFxufVxuXG5leHBvcnRzLmNsZWFuID0gY2xlYW5cbmZ1bmN0aW9uIGNsZWFuICh2ZXJzaW9uLCBvcHRpb25zKSB7XG4gIHZhciBzID0gcGFyc2UodmVyc2lvbi50cmltKCkucmVwbGFjZSgvXls9dl0rLywgJycpLCBvcHRpb25zKVxuICByZXR1cm4gcyA/IHMudmVyc2lvbiA6IG51bGxcbn1cblxuZXhwb3J0cy5TZW1WZXIgPSBTZW1WZXJcblxuZnVuY3Rpb24gU2VtVmVyICh2ZXJzaW9uLCBvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucyB8fCB0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgbG9vc2U6ICEhb3B0aW9ucyxcbiAgICAgIGluY2x1ZGVQcmVyZWxlYXNlOiBmYWxzZVxuICAgIH1cbiAgfVxuICBpZiAodmVyc2lvbiBpbnN0YW5jZW9mIFNlbVZlcikge1xuICAgIGlmICh2ZXJzaW9uLmxvb3NlID09PSBvcHRpb25zLmxvb3NlKSB7XG4gICAgICByZXR1cm4gdmVyc2lvblxuICAgIH0gZWxzZSB7XG4gICAgICB2ZXJzaW9uID0gdmVyc2lvbi52ZXJzaW9uXG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2ZXJzaW9uICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgVmVyc2lvbjogJyArIHZlcnNpb24pXG4gIH1cblxuICBpZiAodmVyc2lvbi5sZW5ndGggPiBNQVhfTEVOR1RIKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmVyc2lvbiBpcyBsb25nZXIgdGhhbiAnICsgTUFYX0xFTkdUSCArICcgY2hhcmFjdGVycycpXG4gIH1cblxuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU2VtVmVyKSkge1xuICAgIHJldHVybiBuZXcgU2VtVmVyKHZlcnNpb24sIG9wdGlvbnMpXG4gIH1cblxuICBkZWJ1ZygnU2VtVmVyJywgdmVyc2lvbiwgb3B0aW9ucylcbiAgdGhpcy5vcHRpb25zID0gb3B0aW9uc1xuICB0aGlzLmxvb3NlID0gISFvcHRpb25zLmxvb3NlXG5cbiAgdmFyIG0gPSB2ZXJzaW9uLnRyaW0oKS5tYXRjaChvcHRpb25zLmxvb3NlID8gcmVbTE9PU0VdIDogcmVbRlVMTF0pXG5cbiAgaWYgKCFtKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBWZXJzaW9uOiAnICsgdmVyc2lvbilcbiAgfVxuXG4gIHRoaXMucmF3ID0gdmVyc2lvblxuXG4gIC8vIHRoZXNlIGFyZSBhY3R1YWxseSBudW1iZXJzXG4gIHRoaXMubWFqb3IgPSArbVsxXVxuICB0aGlzLm1pbm9yID0gK21bMl1cbiAgdGhpcy5wYXRjaCA9ICttWzNdXG5cbiAgaWYgKHRoaXMubWFqb3IgPiBNQVhfU0FGRV9JTlRFR0VSIHx8IHRoaXMubWFqb3IgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBtYWpvciB2ZXJzaW9uJylcbiAgfVxuXG4gIGlmICh0aGlzLm1pbm9yID4gTUFYX1NBRkVfSU5URUdFUiB8fCB0aGlzLm1pbm9yIDwgMCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgbWlub3IgdmVyc2lvbicpXG4gIH1cblxuICBpZiAodGhpcy5wYXRjaCA+IE1BWF9TQUZFX0lOVEVHRVIgfHwgdGhpcy5wYXRjaCA8IDApIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIHBhdGNoIHZlcnNpb24nKVxuICB9XG5cbiAgLy8gbnVtYmVyaWZ5IGFueSBwcmVyZWxlYXNlIG51bWVyaWMgaWRzXG4gIGlmICghbVs0XSkge1xuICAgIHRoaXMucHJlcmVsZWFzZSA9IFtdXG4gIH0gZWxzZSB7XG4gICAgdGhpcy5wcmVyZWxlYXNlID0gbVs0XS5zcGxpdCgnLicpLm1hcChmdW5jdGlvbiAoaWQpIHtcbiAgICAgIGlmICgvXlswLTldKyQvLnRlc3QoaWQpKSB7XG4gICAgICAgIHZhciBudW0gPSAraWRcbiAgICAgICAgaWYgKG51bSA+PSAwICYmIG51bSA8IE1BWF9TQUZFX0lOVEVHRVIpIHtcbiAgICAgICAgICByZXR1cm4gbnVtXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBpZFxuICAgIH0pXG4gIH1cblxuICB0aGlzLmJ1aWxkID0gbVs1XSA/IG1bNV0uc3BsaXQoJy4nKSA6IFtdXG4gIHRoaXMuZm9ybWF0KClcbn1cblxuU2VtVmVyLnByb3RvdHlwZS5mb3JtYXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMudmVyc2lvbiA9IHRoaXMubWFqb3IgKyAnLicgKyB0aGlzLm1pbm9yICsgJy4nICsgdGhpcy5wYXRjaFxuICBpZiAodGhpcy5wcmVyZWxlYXNlLmxlbmd0aCkge1xuICAgIHRoaXMudmVyc2lvbiArPSAnLScgKyB0aGlzLnByZXJlbGVhc2Uuam9pbignLicpXG4gIH1cbiAgcmV0dXJuIHRoaXMudmVyc2lvblxufVxuXG5TZW1WZXIucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy52ZXJzaW9uXG59XG5cblNlbVZlci5wcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uIChvdGhlcikge1xuICBkZWJ1ZygnU2VtVmVyLmNvbXBhcmUnLCB0aGlzLnZlcnNpb24sIHRoaXMub3B0aW9ucywgb3RoZXIpXG4gIGlmICghKG90aGVyIGluc3RhbmNlb2YgU2VtVmVyKSkge1xuICAgIG90aGVyID0gbmV3IFNlbVZlcihvdGhlciwgdGhpcy5vcHRpb25zKVxuICB9XG5cbiAgcmV0dXJuIHRoaXMuY29tcGFyZU1haW4ob3RoZXIpIHx8IHRoaXMuY29tcGFyZVByZShvdGhlcilcbn1cblxuU2VtVmVyLnByb3RvdHlwZS5jb21wYXJlTWFpbiA9IGZ1bmN0aW9uIChvdGhlcikge1xuICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIFNlbVZlcikpIHtcbiAgICBvdGhlciA9IG5ldyBTZW1WZXIob3RoZXIsIHRoaXMub3B0aW9ucylcbiAgfVxuXG4gIHJldHVybiBjb21wYXJlSWRlbnRpZmllcnModGhpcy5tYWpvciwgb3RoZXIubWFqb3IpIHx8XG4gICAgICAgICBjb21wYXJlSWRlbnRpZmllcnModGhpcy5taW5vciwgb3RoZXIubWlub3IpIHx8XG4gICAgICAgICBjb21wYXJlSWRlbnRpZmllcnModGhpcy5wYXRjaCwgb3RoZXIucGF0Y2gpXG59XG5cblNlbVZlci5wcm90b3R5cGUuY29tcGFyZVByZSA9IGZ1bmN0aW9uIChvdGhlcikge1xuICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIFNlbVZlcikpIHtcbiAgICBvdGhlciA9IG5ldyBTZW1WZXIob3RoZXIsIHRoaXMub3B0aW9ucylcbiAgfVxuXG4gIC8vIE5PVCBoYXZpbmcgYSBwcmVyZWxlYXNlIGlzID4gaGF2aW5nIG9uZVxuICBpZiAodGhpcy5wcmVyZWxlYXNlLmxlbmd0aCAmJiAhb3RoZXIucHJlcmVsZWFzZS5sZW5ndGgpIHtcbiAgICByZXR1cm4gLTFcbiAgfSBlbHNlIGlmICghdGhpcy5wcmVyZWxlYXNlLmxlbmd0aCAmJiBvdGhlci5wcmVyZWxlYXNlLmxlbmd0aCkge1xuICAgIHJldHVybiAxXG4gIH0gZWxzZSBpZiAoIXRoaXMucHJlcmVsZWFzZS5sZW5ndGggJiYgIW90aGVyLnByZXJlbGVhc2UubGVuZ3RoKSB7XG4gICAgcmV0dXJuIDBcbiAgfVxuXG4gIHZhciBpID0gMFxuICBkbyB7XG4gICAgdmFyIGEgPSB0aGlzLnByZXJlbGVhc2VbaV1cbiAgICB2YXIgYiA9IG90aGVyLnByZXJlbGVhc2VbaV1cbiAgICBkZWJ1ZygncHJlcmVsZWFzZSBjb21wYXJlJywgaSwgYSwgYilcbiAgICBpZiAoYSA9PT0gdW5kZWZpbmVkICYmIGIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIDBcbiAgICB9IGVsc2UgaWYgKGIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIDFcbiAgICB9IGVsc2UgaWYgKGEgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIC0xXG4gICAgfSBlbHNlIGlmIChhID09PSBiKSB7XG4gICAgICBjb250aW51ZVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gY29tcGFyZUlkZW50aWZpZXJzKGEsIGIpXG4gICAgfVxuICB9IHdoaWxlICgrK2kpXG59XG5cbi8vIHByZW1pbm9yIHdpbGwgYnVtcCB0aGUgdmVyc2lvbiB1cCB0byB0aGUgbmV4dCBtaW5vciByZWxlYXNlLCBhbmQgaW1tZWRpYXRlbHlcbi8vIGRvd24gdG8gcHJlLXJlbGVhc2UuIHByZW1ham9yIGFuZCBwcmVwYXRjaCB3b3JrIHRoZSBzYW1lIHdheS5cblNlbVZlci5wcm90b3R5cGUuaW5jID0gZnVuY3Rpb24gKHJlbGVhc2UsIGlkZW50aWZpZXIpIHtcbiAgc3dpdGNoIChyZWxlYXNlKSB7XG4gICAgY2FzZSAncHJlbWFqb3InOlxuICAgICAgdGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9IDBcbiAgICAgIHRoaXMucGF0Y2ggPSAwXG4gICAgICB0aGlzLm1pbm9yID0gMFxuICAgICAgdGhpcy5tYWpvcisrXG4gICAgICB0aGlzLmluYygncHJlJywgaWRlbnRpZmllcilcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAncHJlbWlub3InOlxuICAgICAgdGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9IDBcbiAgICAgIHRoaXMucGF0Y2ggPSAwXG4gICAgICB0aGlzLm1pbm9yKytcbiAgICAgIHRoaXMuaW5jKCdwcmUnLCBpZGVudGlmaWVyKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdwcmVwYXRjaCc6XG4gICAgICAvLyBJZiB0aGlzIGlzIGFscmVhZHkgYSBwcmVyZWxlYXNlLCBpdCB3aWxsIGJ1bXAgdG8gdGhlIG5leHQgdmVyc2lvblxuICAgICAgLy8gZHJvcCBhbnkgcHJlcmVsZWFzZXMgdGhhdCBtaWdodCBhbHJlYWR5IGV4aXN0LCBzaW5jZSB0aGV5IGFyZSBub3RcbiAgICAgIC8vIHJlbGV2YW50IGF0IHRoaXMgcG9pbnQuXG4gICAgICB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID0gMFxuICAgICAgdGhpcy5pbmMoJ3BhdGNoJywgaWRlbnRpZmllcilcbiAgICAgIHRoaXMuaW5jKCdwcmUnLCBpZGVudGlmaWVyKVxuICAgICAgYnJlYWtcbiAgICAvLyBJZiB0aGUgaW5wdXQgaXMgYSBub24tcHJlcmVsZWFzZSB2ZXJzaW9uLCB0aGlzIGFjdHMgdGhlIHNhbWUgYXNcbiAgICAvLyBwcmVwYXRjaC5cbiAgICBjYXNlICdwcmVyZWxlYXNlJzpcbiAgICAgIGlmICh0aGlzLnByZXJlbGVhc2UubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMuaW5jKCdwYXRjaCcsIGlkZW50aWZpZXIpXG4gICAgICB9XG4gICAgICB0aGlzLmluYygncHJlJywgaWRlbnRpZmllcilcbiAgICAgIGJyZWFrXG5cbiAgICBjYXNlICdtYWpvcic6XG4gICAgICAvLyBJZiB0aGlzIGlzIGEgcHJlLW1ham9yIHZlcnNpb24sIGJ1bXAgdXAgdG8gdGhlIHNhbWUgbWFqb3IgdmVyc2lvbi5cbiAgICAgIC8vIE90aGVyd2lzZSBpbmNyZW1lbnQgbWFqb3IuXG4gICAgICAvLyAxLjAuMC01IGJ1bXBzIHRvIDEuMC4wXG4gICAgICAvLyAxLjEuMCBidW1wcyB0byAyLjAuMFxuICAgICAgaWYgKHRoaXMubWlub3IgIT09IDAgfHxcbiAgICAgICAgICB0aGlzLnBhdGNoICE9PSAwIHx8XG4gICAgICAgICAgdGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLm1ham9yKytcbiAgICAgIH1cbiAgICAgIHRoaXMubWlub3IgPSAwXG4gICAgICB0aGlzLnBhdGNoID0gMFxuICAgICAgdGhpcy5wcmVyZWxlYXNlID0gW11cbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnbWlub3InOlxuICAgICAgLy8gSWYgdGhpcyBpcyBhIHByZS1taW5vciB2ZXJzaW9uLCBidW1wIHVwIHRvIHRoZSBzYW1lIG1pbm9yIHZlcnNpb24uXG4gICAgICAvLyBPdGhlcndpc2UgaW5jcmVtZW50IG1pbm9yLlxuICAgICAgLy8gMS4yLjAtNSBidW1wcyB0byAxLjIuMFxuICAgICAgLy8gMS4yLjEgYnVtcHMgdG8gMS4zLjBcbiAgICAgIGlmICh0aGlzLnBhdGNoICE9PSAwIHx8IHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy5taW5vcisrXG4gICAgICB9XG4gICAgICB0aGlzLnBhdGNoID0gMFxuICAgICAgdGhpcy5wcmVyZWxlYXNlID0gW11cbiAgICAgIGJyZWFrXG4gICAgY2FzZSAncGF0Y2gnOlxuICAgICAgLy8gSWYgdGhpcyBpcyBub3QgYSBwcmUtcmVsZWFzZSB2ZXJzaW9uLCBpdCB3aWxsIGluY3JlbWVudCB0aGUgcGF0Y2guXG4gICAgICAvLyBJZiBpdCBpcyBhIHByZS1yZWxlYXNlIGl0IHdpbGwgYnVtcCB1cCB0byB0aGUgc2FtZSBwYXRjaCB2ZXJzaW9uLlxuICAgICAgLy8gMS4yLjAtNSBwYXRjaGVzIHRvIDEuMi4wXG4gICAgICAvLyAxLjIuMCBwYXRjaGVzIHRvIDEuMi4xXG4gICAgICBpZiAodGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLnBhdGNoKytcbiAgICAgIH1cbiAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFtdXG4gICAgICBicmVha1xuICAgIC8vIFRoaXMgcHJvYmFibHkgc2hvdWxkbid0IGJlIHVzZWQgcHVibGljbHkuXG4gICAgLy8gMS4wLjAgXCJwcmVcIiB3b3VsZCBiZWNvbWUgMS4wLjAtMCB3aGljaCBpcyB0aGUgd3JvbmcgZGlyZWN0aW9uLlxuICAgIGNhc2UgJ3ByZSc6XG4gICAgICBpZiAodGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLnByZXJlbGVhc2UgPSBbMF1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBpID0gdGhpcy5wcmVyZWxlYXNlLmxlbmd0aFxuICAgICAgICB3aGlsZSAoLS1pID49IDApIHtcbiAgICAgICAgICBpZiAodHlwZW9mIHRoaXMucHJlcmVsZWFzZVtpXSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIHRoaXMucHJlcmVsZWFzZVtpXSsrXG4gICAgICAgICAgICBpID0gLTJcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGkgPT09IC0xKSB7XG4gICAgICAgICAgLy8gZGlkbid0IGluY3JlbWVudCBhbnl0aGluZ1xuICAgICAgICAgIHRoaXMucHJlcmVsZWFzZS5wdXNoKDApXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChpZGVudGlmaWVyKSB7XG4gICAgICAgIC8vIDEuMi4wLWJldGEuMSBidW1wcyB0byAxLjIuMC1iZXRhLjIsXG4gICAgICAgIC8vIDEuMi4wLWJldGEuZm9vYmx6IG9yIDEuMi4wLWJldGEgYnVtcHMgdG8gMS4yLjAtYmV0YS4wXG4gICAgICAgIGlmICh0aGlzLnByZXJlbGVhc2VbMF0gPT09IGlkZW50aWZpZXIpIHtcbiAgICAgICAgICBpZiAoaXNOYU4odGhpcy5wcmVyZWxlYXNlWzFdKSkge1xuICAgICAgICAgICAgdGhpcy5wcmVyZWxlYXNlID0gW2lkZW50aWZpZXIsIDBdXG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFtpZGVudGlmaWVyLCAwXVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBicmVha1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBpbmNyZW1lbnQgYXJndW1lbnQ6ICcgKyByZWxlYXNlKVxuICB9XG4gIHRoaXMuZm9ybWF0KClcbiAgdGhpcy5yYXcgPSB0aGlzLnZlcnNpb25cbiAgcmV0dXJuIHRoaXNcbn1cblxuZXhwb3J0cy5pbmMgPSBpbmNcbmZ1bmN0aW9uIGluYyAodmVyc2lvbiwgcmVsZWFzZSwgbG9vc2UsIGlkZW50aWZpZXIpIHtcbiAgaWYgKHR5cGVvZiAobG9vc2UpID09PSAnc3RyaW5nJykge1xuICAgIGlkZW50aWZpZXIgPSBsb29zZVxuICAgIGxvb3NlID0gdW5kZWZpbmVkXG4gIH1cblxuICB0cnkge1xuICAgIHJldHVybiBuZXcgU2VtVmVyKHZlcnNpb24sIGxvb3NlKS5pbmMocmVsZWFzZSwgaWRlbnRpZmllcikudmVyc2lvblxuICB9IGNhdGNoIChlcikge1xuICAgIHJldHVybiBudWxsXG4gIH1cbn1cblxuZXhwb3J0cy5kaWZmID0gZGlmZlxuZnVuY3Rpb24gZGlmZiAodmVyc2lvbjEsIHZlcnNpb24yKSB7XG4gIGlmIChlcSh2ZXJzaW9uMSwgdmVyc2lvbjIpKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfSBlbHNlIHtcbiAgICB2YXIgdjEgPSBwYXJzZSh2ZXJzaW9uMSlcbiAgICB2YXIgdjIgPSBwYXJzZSh2ZXJzaW9uMilcbiAgICB2YXIgcHJlZml4ID0gJydcbiAgICBpZiAodjEucHJlcmVsZWFzZS5sZW5ndGggfHwgdjIucHJlcmVsZWFzZS5sZW5ndGgpIHtcbiAgICAgIHByZWZpeCA9ICdwcmUnXG4gICAgICB2YXIgZGVmYXVsdFJlc3VsdCA9ICdwcmVyZWxlYXNlJ1xuICAgIH1cbiAgICBmb3IgKHZhciBrZXkgaW4gdjEpIHtcbiAgICAgIGlmIChrZXkgPT09ICdtYWpvcicgfHwga2V5ID09PSAnbWlub3InIHx8IGtleSA9PT0gJ3BhdGNoJykge1xuICAgICAgICBpZiAodjFba2V5XSAhPT0gdjJba2V5XSkge1xuICAgICAgICAgIHJldHVybiBwcmVmaXggKyBrZXlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGVmYXVsdFJlc3VsdCAvLyBtYXkgYmUgdW5kZWZpbmVkXG4gIH1cbn1cblxuZXhwb3J0cy5jb21wYXJlSWRlbnRpZmllcnMgPSBjb21wYXJlSWRlbnRpZmllcnNcblxudmFyIG51bWVyaWMgPSAvXlswLTldKyQvXG5mdW5jdGlvbiBjb21wYXJlSWRlbnRpZmllcnMgKGEsIGIpIHtcbiAgdmFyIGFudW0gPSBudW1lcmljLnRlc3QoYSlcbiAgdmFyIGJudW0gPSBudW1lcmljLnRlc3QoYilcblxuICBpZiAoYW51bSAmJiBibnVtKSB7XG4gICAgYSA9ICthXG4gICAgYiA9ICtiXG4gIH1cblxuICByZXR1cm4gYSA9PT0gYiA/IDBcbiAgICA6IChhbnVtICYmICFibnVtKSA/IC0xXG4gICAgOiAoYm51bSAmJiAhYW51bSkgPyAxXG4gICAgOiBhIDwgYiA/IC0xXG4gICAgOiAxXG59XG5cbmV4cG9ydHMucmNvbXBhcmVJZGVudGlmaWVycyA9IHJjb21wYXJlSWRlbnRpZmllcnNcbmZ1bmN0aW9uIHJjb21wYXJlSWRlbnRpZmllcnMgKGEsIGIpIHtcbiAgcmV0dXJuIGNvbXBhcmVJZGVudGlmaWVycyhiLCBhKVxufVxuXG5leHBvcnRzLm1ham9yID0gbWFqb3JcbmZ1bmN0aW9uIG1ham9yIChhLCBsb29zZSkge1xuICByZXR1cm4gbmV3IFNlbVZlcihhLCBsb29zZSkubWFqb3Jcbn1cblxuZXhwb3J0cy5taW5vciA9IG1pbm9yXG5mdW5jdGlvbiBtaW5vciAoYSwgbG9vc2UpIHtcbiAgcmV0dXJuIG5ldyBTZW1WZXIoYSwgbG9vc2UpLm1pbm9yXG59XG5cbmV4cG9ydHMucGF0Y2ggPSBwYXRjaFxuZnVuY3Rpb24gcGF0Y2ggKGEsIGxvb3NlKSB7XG4gIHJldHVybiBuZXcgU2VtVmVyKGEsIGxvb3NlKS5wYXRjaFxufVxuXG5leHBvcnRzLmNvbXBhcmUgPSBjb21wYXJlXG5mdW5jdGlvbiBjb21wYXJlIChhLCBiLCBsb29zZSkge1xuICByZXR1cm4gbmV3IFNlbVZlcihhLCBsb29zZSkuY29tcGFyZShuZXcgU2VtVmVyKGIsIGxvb3NlKSlcbn1cblxuZXhwb3J0cy5jb21wYXJlTG9vc2UgPSBjb21wYXJlTG9vc2VcbmZ1bmN0aW9uIGNvbXBhcmVMb29zZSAoYSwgYikge1xuICByZXR1cm4gY29tcGFyZShhLCBiLCB0cnVlKVxufVxuXG5leHBvcnRzLnJjb21wYXJlID0gcmNvbXBhcmVcbmZ1bmN0aW9uIHJjb21wYXJlIChhLCBiLCBsb29zZSkge1xuICByZXR1cm4gY29tcGFyZShiLCBhLCBsb29zZSlcbn1cblxuZXhwb3J0cy5zb3J0ID0gc29ydFxuZnVuY3Rpb24gc29ydCAobGlzdCwgbG9vc2UpIHtcbiAgcmV0dXJuIGxpc3Quc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgIHJldHVybiBleHBvcnRzLmNvbXBhcmUoYSwgYiwgbG9vc2UpXG4gIH0pXG59XG5cbmV4cG9ydHMucnNvcnQgPSByc29ydFxuZnVuY3Rpb24gcnNvcnQgKGxpc3QsIGxvb3NlKSB7XG4gIHJldHVybiBsaXN0LnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICByZXR1cm4gZXhwb3J0cy5yY29tcGFyZShhLCBiLCBsb29zZSlcbiAgfSlcbn1cblxuZXhwb3J0cy5ndCA9IGd0XG5mdW5jdGlvbiBndCAoYSwgYiwgbG9vc2UpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYSwgYiwgbG9vc2UpID4gMFxufVxuXG5leHBvcnRzLmx0ID0gbHRcbmZ1bmN0aW9uIGx0IChhLCBiLCBsb29zZSkge1xuICByZXR1cm4gY29tcGFyZShhLCBiLCBsb29zZSkgPCAwXG59XG5cbmV4cG9ydHMuZXEgPSBlcVxuZnVuY3Rpb24gZXEgKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIGxvb3NlKSA9PT0gMFxufVxuXG5leHBvcnRzLm5lcSA9IG5lcVxuZnVuY3Rpb24gbmVxIChhLCBiLCBsb29zZSkge1xuICByZXR1cm4gY29tcGFyZShhLCBiLCBsb29zZSkgIT09IDBcbn1cblxuZXhwb3J0cy5ndGUgPSBndGVcbmZ1bmN0aW9uIGd0ZSAoYSwgYiwgbG9vc2UpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYSwgYiwgbG9vc2UpID49IDBcbn1cblxuZXhwb3J0cy5sdGUgPSBsdGVcbmZ1bmN0aW9uIGx0ZSAoYSwgYiwgbG9vc2UpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYSwgYiwgbG9vc2UpIDw9IDBcbn1cblxuZXhwb3J0cy5jbXAgPSBjbXBcbmZ1bmN0aW9uIGNtcCAoYSwgb3AsIGIsIGxvb3NlKSB7XG4gIHN3aXRjaCAob3ApIHtcbiAgICBjYXNlICc9PT0nOlxuICAgICAgaWYgKHR5cGVvZiBhID09PSAnb2JqZWN0JylcbiAgICAgICAgYSA9IGEudmVyc2lvblxuICAgICAgaWYgKHR5cGVvZiBiID09PSAnb2JqZWN0JylcbiAgICAgICAgYiA9IGIudmVyc2lvblxuICAgICAgcmV0dXJuIGEgPT09IGJcblxuICAgIGNhc2UgJyE9PSc6XG4gICAgICBpZiAodHlwZW9mIGEgPT09ICdvYmplY3QnKVxuICAgICAgICBhID0gYS52ZXJzaW9uXG4gICAgICBpZiAodHlwZW9mIGIgPT09ICdvYmplY3QnKVxuICAgICAgICBiID0gYi52ZXJzaW9uXG4gICAgICByZXR1cm4gYSAhPT0gYlxuXG4gICAgY2FzZSAnJzpcbiAgICBjYXNlICc9JzpcbiAgICBjYXNlICc9PSc6XG4gICAgICByZXR1cm4gZXEoYSwgYiwgbG9vc2UpXG5cbiAgICBjYXNlICchPSc6XG4gICAgICByZXR1cm4gbmVxKGEsIGIsIGxvb3NlKVxuXG4gICAgY2FzZSAnPic6XG4gICAgICByZXR1cm4gZ3QoYSwgYiwgbG9vc2UpXG5cbiAgICBjYXNlICc+PSc6XG4gICAgICByZXR1cm4gZ3RlKGEsIGIsIGxvb3NlKVxuXG4gICAgY2FzZSAnPCc6XG4gICAgICByZXR1cm4gbHQoYSwgYiwgbG9vc2UpXG5cbiAgICBjYXNlICc8PSc6XG4gICAgICByZXR1cm4gbHRlKGEsIGIsIGxvb3NlKVxuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgb3BlcmF0b3I6ICcgKyBvcClcbiAgfVxufVxuXG5leHBvcnRzLkNvbXBhcmF0b3IgPSBDb21wYXJhdG9yXG5mdW5jdGlvbiBDb21wYXJhdG9yIChjb21wLCBvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucyB8fCB0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgbG9vc2U6ICEhb3B0aW9ucyxcbiAgICAgIGluY2x1ZGVQcmVyZWxlYXNlOiBmYWxzZVxuICAgIH1cbiAgfVxuXG4gIGlmIChjb21wIGluc3RhbmNlb2YgQ29tcGFyYXRvcikge1xuICAgIGlmIChjb21wLmxvb3NlID09PSAhIW9wdGlvbnMubG9vc2UpIHtcbiAgICAgIHJldHVybiBjb21wXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbXAgPSBjb21wLnZhbHVlXG4gICAgfVxuICB9XG5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIENvbXBhcmF0b3IpKSB7XG4gICAgcmV0dXJuIG5ldyBDb21wYXJhdG9yKGNvbXAsIG9wdGlvbnMpXG4gIH1cblxuICBkZWJ1ZygnY29tcGFyYXRvcicsIGNvbXAsIG9wdGlvbnMpXG4gIHRoaXMub3B0aW9ucyA9IG9wdGlvbnNcbiAgdGhpcy5sb29zZSA9ICEhb3B0aW9ucy5sb29zZVxuICB0aGlzLnBhcnNlKGNvbXApXG5cbiAgaWYgKHRoaXMuc2VtdmVyID09PSBBTlkpIHtcbiAgICB0aGlzLnZhbHVlID0gJydcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnZhbHVlID0gdGhpcy5vcGVyYXRvciArIHRoaXMuc2VtdmVyLnZlcnNpb25cbiAgfVxuXG4gIGRlYnVnKCdjb21wJywgdGhpcylcbn1cblxudmFyIEFOWSA9IHt9XG5Db21wYXJhdG9yLnByb3RvdHlwZS5wYXJzZSA9IGZ1bmN0aW9uIChjb21wKSB7XG4gIHZhciByID0gdGhpcy5vcHRpb25zLmxvb3NlID8gcmVbQ09NUEFSQVRPUkxPT1NFXSA6IHJlW0NPTVBBUkFUT1JdXG4gIHZhciBtID0gY29tcC5tYXRjaChyKVxuXG4gIGlmICghbSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgY29tcGFyYXRvcjogJyArIGNvbXApXG4gIH1cblxuICB0aGlzLm9wZXJhdG9yID0gbVsxXVxuICBpZiAodGhpcy5vcGVyYXRvciA9PT0gJz0nKSB7XG4gICAgdGhpcy5vcGVyYXRvciA9ICcnXG4gIH1cblxuICAvLyBpZiBpdCBsaXRlcmFsbHkgaXMganVzdCAnPicgb3IgJycgdGhlbiBhbGxvdyBhbnl0aGluZy5cbiAgaWYgKCFtWzJdKSB7XG4gICAgdGhpcy5zZW12ZXIgPSBBTllcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnNlbXZlciA9IG5ldyBTZW1WZXIobVsyXSwgdGhpcy5vcHRpb25zLmxvb3NlKVxuICB9XG59XG5cbkNvbXBhcmF0b3IucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy52YWx1ZVxufVxuXG5Db21wYXJhdG9yLnByb3RvdHlwZS50ZXN0ID0gZnVuY3Rpb24gKHZlcnNpb24pIHtcbiAgZGVidWcoJ0NvbXBhcmF0b3IudGVzdCcsIHZlcnNpb24sIHRoaXMub3B0aW9ucy5sb29zZSlcblxuICBpZiAodGhpcy5zZW12ZXIgPT09IEFOWSkge1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBpZiAodHlwZW9mIHZlcnNpb24gPT09ICdzdHJpbmcnKSB7XG4gICAgdmVyc2lvbiA9IG5ldyBTZW1WZXIodmVyc2lvbiwgdGhpcy5vcHRpb25zKVxuICB9XG5cbiAgcmV0dXJuIGNtcCh2ZXJzaW9uLCB0aGlzLm9wZXJhdG9yLCB0aGlzLnNlbXZlciwgdGhpcy5vcHRpb25zKVxufVxuXG5Db21wYXJhdG9yLnByb3RvdHlwZS5pbnRlcnNlY3RzID0gZnVuY3Rpb24gKGNvbXAsIG9wdGlvbnMpIHtcbiAgaWYgKCEoY29tcCBpbnN0YW5jZW9mIENvbXBhcmF0b3IpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYSBDb21wYXJhdG9yIGlzIHJlcXVpcmVkJylcbiAgfVxuXG4gIGlmICghb3B0aW9ucyB8fCB0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgbG9vc2U6ICEhb3B0aW9ucyxcbiAgICAgIGluY2x1ZGVQcmVyZWxlYXNlOiBmYWxzZVxuICAgIH1cbiAgfVxuXG4gIHZhciByYW5nZVRtcFxuXG4gIGlmICh0aGlzLm9wZXJhdG9yID09PSAnJykge1xuICAgIHJhbmdlVG1wID0gbmV3IFJhbmdlKGNvbXAudmFsdWUsIG9wdGlvbnMpXG4gICAgcmV0dXJuIHNhdGlzZmllcyh0aGlzLnZhbHVlLCByYW5nZVRtcCwgb3B0aW9ucylcbiAgfSBlbHNlIGlmIChjb21wLm9wZXJhdG9yID09PSAnJykge1xuICAgIHJhbmdlVG1wID0gbmV3IFJhbmdlKHRoaXMudmFsdWUsIG9wdGlvbnMpXG4gICAgcmV0dXJuIHNhdGlzZmllcyhjb21wLnNlbXZlciwgcmFuZ2VUbXAsIG9wdGlvbnMpXG4gIH1cblxuICB2YXIgc2FtZURpcmVjdGlvbkluY3JlYXNpbmcgPVxuICAgICh0aGlzLm9wZXJhdG9yID09PSAnPj0nIHx8IHRoaXMub3BlcmF0b3IgPT09ICc+JykgJiZcbiAgICAoY29tcC5vcGVyYXRvciA9PT0gJz49JyB8fCBjb21wLm9wZXJhdG9yID09PSAnPicpXG4gIHZhciBzYW1lRGlyZWN0aW9uRGVjcmVhc2luZyA9XG4gICAgKHRoaXMub3BlcmF0b3IgPT09ICc8PScgfHwgdGhpcy5vcGVyYXRvciA9PT0gJzwnKSAmJlxuICAgIChjb21wLm9wZXJhdG9yID09PSAnPD0nIHx8IGNvbXAub3BlcmF0b3IgPT09ICc8JylcbiAgdmFyIHNhbWVTZW1WZXIgPSB0aGlzLnNlbXZlci52ZXJzaW9uID09PSBjb21wLnNlbXZlci52ZXJzaW9uXG4gIHZhciBkaWZmZXJlbnREaXJlY3Rpb25zSW5jbHVzaXZlID1cbiAgICAodGhpcy5vcGVyYXRvciA9PT0gJz49JyB8fCB0aGlzLm9wZXJhdG9yID09PSAnPD0nKSAmJlxuICAgIChjb21wLm9wZXJhdG9yID09PSAnPj0nIHx8IGNvbXAub3BlcmF0b3IgPT09ICc8PScpXG4gIHZhciBvcHBvc2l0ZURpcmVjdGlvbnNMZXNzVGhhbiA9XG4gICAgY21wKHRoaXMuc2VtdmVyLCAnPCcsIGNvbXAuc2VtdmVyLCBvcHRpb25zKSAmJlxuICAgICgodGhpcy5vcGVyYXRvciA9PT0gJz49JyB8fCB0aGlzLm9wZXJhdG9yID09PSAnPicpICYmXG4gICAgKGNvbXAub3BlcmF0b3IgPT09ICc8PScgfHwgY29tcC5vcGVyYXRvciA9PT0gJzwnKSlcbiAgdmFyIG9wcG9zaXRlRGlyZWN0aW9uc0dyZWF0ZXJUaGFuID1cbiAgICBjbXAodGhpcy5zZW12ZXIsICc+JywgY29tcC5zZW12ZXIsIG9wdGlvbnMpICYmXG4gICAgKCh0aGlzLm9wZXJhdG9yID09PSAnPD0nIHx8IHRoaXMub3BlcmF0b3IgPT09ICc8JykgJiZcbiAgICAoY29tcC5vcGVyYXRvciA9PT0gJz49JyB8fCBjb21wLm9wZXJhdG9yID09PSAnPicpKVxuXG4gIHJldHVybiBzYW1lRGlyZWN0aW9uSW5jcmVhc2luZyB8fCBzYW1lRGlyZWN0aW9uRGVjcmVhc2luZyB8fFxuICAgIChzYW1lU2VtVmVyICYmIGRpZmZlcmVudERpcmVjdGlvbnNJbmNsdXNpdmUpIHx8XG4gICAgb3Bwb3NpdGVEaXJlY3Rpb25zTGVzc1RoYW4gfHwgb3Bwb3NpdGVEaXJlY3Rpb25zR3JlYXRlclRoYW5cbn1cblxuZXhwb3J0cy5SYW5nZSA9IFJhbmdlXG5mdW5jdGlvbiBSYW5nZSAocmFuZ2UsIG9wdGlvbnMpIHtcbiAgaWYgKCFvcHRpb25zIHx8IHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0Jykge1xuICAgIG9wdGlvbnMgPSB7XG4gICAgICBsb29zZTogISFvcHRpb25zLFxuICAgICAgaW5jbHVkZVByZXJlbGVhc2U6IGZhbHNlXG4gICAgfVxuICB9XG5cbiAgaWYgKHJhbmdlIGluc3RhbmNlb2YgUmFuZ2UpIHtcbiAgICBpZiAocmFuZ2UubG9vc2UgPT09ICEhb3B0aW9ucy5sb29zZSAmJlxuICAgICAgICByYW5nZS5pbmNsdWRlUHJlcmVsZWFzZSA9PT0gISFvcHRpb25zLmluY2x1ZGVQcmVyZWxlYXNlKSB7XG4gICAgICByZXR1cm4gcmFuZ2VcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG5ldyBSYW5nZShyYW5nZS5yYXcsIG9wdGlvbnMpXG4gICAgfVxuICB9XG5cbiAgaWYgKHJhbmdlIGluc3RhbmNlb2YgQ29tcGFyYXRvcikge1xuICAgIHJldHVybiBuZXcgUmFuZ2UocmFuZ2UudmFsdWUsIG9wdGlvbnMpXG4gIH1cblxuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUmFuZ2UpKSB7XG4gICAgcmV0dXJuIG5ldyBSYW5nZShyYW5nZSwgb3B0aW9ucylcbiAgfVxuXG4gIHRoaXMub3B0aW9ucyA9IG9wdGlvbnNcbiAgdGhpcy5sb29zZSA9ICEhb3B0aW9ucy5sb29zZVxuICB0aGlzLmluY2x1ZGVQcmVyZWxlYXNlID0gISFvcHRpb25zLmluY2x1ZGVQcmVyZWxlYXNlXG5cbiAgLy8gRmlyc3QsIHNwbGl0IGJhc2VkIG9uIGJvb2xlYW4gb3IgfHxcbiAgdGhpcy5yYXcgPSByYW5nZVxuICB0aGlzLnNldCA9IHJhbmdlLnNwbGl0KC9cXHMqXFx8XFx8XFxzKi8pLm1hcChmdW5jdGlvbiAocmFuZ2UpIHtcbiAgICByZXR1cm4gdGhpcy5wYXJzZVJhbmdlKHJhbmdlLnRyaW0oKSlcbiAgfSwgdGhpcykuZmlsdGVyKGZ1bmN0aW9uIChjKSB7XG4gICAgLy8gdGhyb3cgb3V0IGFueSB0aGF0IGFyZSBub3QgcmVsZXZhbnQgZm9yIHdoYXRldmVyIHJlYXNvblxuICAgIHJldHVybiBjLmxlbmd0aFxuICB9KVxuXG4gIGlmICghdGhpcy5zZXQubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBTZW1WZXIgUmFuZ2U6ICcgKyByYW5nZSlcbiAgfVxuXG4gIHRoaXMuZm9ybWF0KClcbn1cblxuUmFuZ2UucHJvdG90eXBlLmZvcm1hdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5yYW5nZSA9IHRoaXMuc2V0Lm1hcChmdW5jdGlvbiAoY29tcHMpIHtcbiAgICByZXR1cm4gY29tcHMuam9pbignICcpLnRyaW0oKVxuICB9KS5qb2luKCd8fCcpLnRyaW0oKVxuICByZXR1cm4gdGhpcy5yYW5nZVxufVxuXG5SYW5nZS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLnJhbmdlXG59XG5cblJhbmdlLnByb3RvdHlwZS5wYXJzZVJhbmdlID0gZnVuY3Rpb24gKHJhbmdlKSB7XG4gIHZhciBsb29zZSA9IHRoaXMub3B0aW9ucy5sb29zZVxuICByYW5nZSA9IHJhbmdlLnRyaW0oKVxuICAvLyBgMS4yLjMgLSAxLjIuNGAgPT4gYD49MS4yLjMgPD0xLjIuNGBcbiAgdmFyIGhyID0gbG9vc2UgPyByZVtIWVBIRU5SQU5HRUxPT1NFXSA6IHJlW0hZUEhFTlJBTkdFXVxuICByYW5nZSA9IHJhbmdlLnJlcGxhY2UoaHIsIGh5cGhlblJlcGxhY2UpXG4gIGRlYnVnKCdoeXBoZW4gcmVwbGFjZScsIHJhbmdlKVxuICAvLyBgPiAxLjIuMyA8IDEuMi41YCA9PiBgPjEuMi4zIDwxLjIuNWBcbiAgcmFuZ2UgPSByYW5nZS5yZXBsYWNlKHJlW0NPTVBBUkFUT1JUUklNXSwgY29tcGFyYXRvclRyaW1SZXBsYWNlKVxuICBkZWJ1ZygnY29tcGFyYXRvciB0cmltJywgcmFuZ2UsIHJlW0NPTVBBUkFUT1JUUklNXSlcblxuICAvLyBgfiAxLjIuM2AgPT4gYH4xLjIuM2BcbiAgcmFuZ2UgPSByYW5nZS5yZXBsYWNlKHJlW1RJTERFVFJJTV0sIHRpbGRlVHJpbVJlcGxhY2UpXG5cbiAgLy8gYF4gMS4yLjNgID0+IGBeMS4yLjNgXG4gIHJhbmdlID0gcmFuZ2UucmVwbGFjZShyZVtDQVJFVFRSSU1dLCBjYXJldFRyaW1SZXBsYWNlKVxuXG4gIC8vIG5vcm1hbGl6ZSBzcGFjZXNcbiAgcmFuZ2UgPSByYW5nZS5zcGxpdCgvXFxzKy8pLmpvaW4oJyAnKVxuXG4gIC8vIEF0IHRoaXMgcG9pbnQsIHRoZSByYW5nZSBpcyBjb21wbGV0ZWx5IHRyaW1tZWQgYW5kXG4gIC8vIHJlYWR5IHRvIGJlIHNwbGl0IGludG8gY29tcGFyYXRvcnMuXG5cbiAgdmFyIGNvbXBSZSA9IGxvb3NlID8gcmVbQ09NUEFSQVRPUkxPT1NFXSA6IHJlW0NPTVBBUkFUT1JdXG4gIHZhciBzZXQgPSByYW5nZS5zcGxpdCgnICcpLm1hcChmdW5jdGlvbiAoY29tcCkge1xuICAgIHJldHVybiBwYXJzZUNvbXBhcmF0b3IoY29tcCwgdGhpcy5vcHRpb25zKVxuICB9LCB0aGlzKS5qb2luKCcgJykuc3BsaXQoL1xccysvKVxuICBpZiAodGhpcy5vcHRpb25zLmxvb3NlKSB7XG4gICAgLy8gaW4gbG9vc2UgbW9kZSwgdGhyb3cgb3V0IGFueSB0aGF0IGFyZSBub3QgdmFsaWQgY29tcGFyYXRvcnNcbiAgICBzZXQgPSBzZXQuZmlsdGVyKGZ1bmN0aW9uIChjb21wKSB7XG4gICAgICByZXR1cm4gISFjb21wLm1hdGNoKGNvbXBSZSlcbiAgICB9KVxuICB9XG4gIHNldCA9IHNldC5tYXAoZnVuY3Rpb24gKGNvbXApIHtcbiAgICByZXR1cm4gbmV3IENvbXBhcmF0b3IoY29tcCwgdGhpcy5vcHRpb25zKVxuICB9LCB0aGlzKVxuXG4gIHJldHVybiBzZXRcbn1cblxuUmFuZ2UucHJvdG90eXBlLmludGVyc2VjdHMgPSBmdW5jdGlvbiAocmFuZ2UsIG9wdGlvbnMpIHtcbiAgaWYgKCEocmFuZ2UgaW5zdGFuY2VvZiBSYW5nZSkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdhIFJhbmdlIGlzIHJlcXVpcmVkJylcbiAgfVxuXG4gIHJldHVybiB0aGlzLnNldC5zb21lKGZ1bmN0aW9uICh0aGlzQ29tcGFyYXRvcnMpIHtcbiAgICByZXR1cm4gdGhpc0NvbXBhcmF0b3JzLmV2ZXJ5KGZ1bmN0aW9uICh0aGlzQ29tcGFyYXRvcikge1xuICAgICAgcmV0dXJuIHJhbmdlLnNldC5zb21lKGZ1bmN0aW9uIChyYW5nZUNvbXBhcmF0b3JzKSB7XG4gICAgICAgIHJldHVybiByYW5nZUNvbXBhcmF0b3JzLmV2ZXJ5KGZ1bmN0aW9uIChyYW5nZUNvbXBhcmF0b3IpIHtcbiAgICAgICAgICByZXR1cm4gdGhpc0NvbXBhcmF0b3IuaW50ZXJzZWN0cyhyYW5nZUNvbXBhcmF0b3IsIG9wdGlvbnMpXG4gICAgICAgIH0pXG4gICAgICB9KVxuICAgIH0pXG4gIH0pXG59XG5cbi8vIE1vc3RseSBqdXN0IGZvciB0ZXN0aW5nIGFuZCBsZWdhY3kgQVBJIHJlYXNvbnNcbmV4cG9ydHMudG9Db21wYXJhdG9ycyA9IHRvQ29tcGFyYXRvcnNcbmZ1bmN0aW9uIHRvQ29tcGFyYXRvcnMgKHJhbmdlLCBvcHRpb25zKSB7XG4gIHJldHVybiBuZXcgUmFuZ2UocmFuZ2UsIG9wdGlvbnMpLnNldC5tYXAoZnVuY3Rpb24gKGNvbXApIHtcbiAgICByZXR1cm4gY29tcC5tYXAoZnVuY3Rpb24gKGMpIHtcbiAgICAgIHJldHVybiBjLnZhbHVlXG4gICAgfSkuam9pbignICcpLnRyaW0oKS5zcGxpdCgnICcpXG4gIH0pXG59XG5cbi8vIGNvbXByaXNlZCBvZiB4cmFuZ2VzLCB0aWxkZXMsIHN0YXJzLCBhbmQgZ3RsdCdzIGF0IHRoaXMgcG9pbnQuXG4vLyBhbHJlYWR5IHJlcGxhY2VkIHRoZSBoeXBoZW4gcmFuZ2VzXG4vLyB0dXJuIGludG8gYSBzZXQgb2YgSlVTVCBjb21wYXJhdG9ycy5cbmZ1bmN0aW9uIHBhcnNlQ29tcGFyYXRvciAoY29tcCwgb3B0aW9ucykge1xuICBkZWJ1ZygnY29tcCcsIGNvbXAsIG9wdGlvbnMpXG4gIGNvbXAgPSByZXBsYWNlQ2FyZXRzKGNvbXAsIG9wdGlvbnMpXG4gIGRlYnVnKCdjYXJldCcsIGNvbXApXG4gIGNvbXAgPSByZXBsYWNlVGlsZGVzKGNvbXAsIG9wdGlvbnMpXG4gIGRlYnVnKCd0aWxkZXMnLCBjb21wKVxuICBjb21wID0gcmVwbGFjZVhSYW5nZXMoY29tcCwgb3B0aW9ucylcbiAgZGVidWcoJ3hyYW5nZScsIGNvbXApXG4gIGNvbXAgPSByZXBsYWNlU3RhcnMoY29tcCwgb3B0aW9ucylcbiAgZGVidWcoJ3N0YXJzJywgY29tcClcbiAgcmV0dXJuIGNvbXBcbn1cblxuZnVuY3Rpb24gaXNYIChpZCkge1xuICByZXR1cm4gIWlkIHx8IGlkLnRvTG93ZXJDYXNlKCkgPT09ICd4JyB8fCBpZCA9PT0gJyonXG59XG5cbi8vIH4sIH4+IC0tPiAqIChhbnksIGtpbmRhIHNpbGx5KVxuLy8gfjIsIH4yLngsIH4yLngueCwgfj4yLCB+PjIueCB+PjIueC54IC0tPiA+PTIuMC4wIDwzLjAuMFxuLy8gfjIuMCwgfjIuMC54LCB+PjIuMCwgfj4yLjAueCAtLT4gPj0yLjAuMCA8Mi4xLjBcbi8vIH4xLjIsIH4xLjIueCwgfj4xLjIsIH4+MS4yLnggLS0+ID49MS4yLjAgPDEuMy4wXG4vLyB+MS4yLjMsIH4+MS4yLjMgLS0+ID49MS4yLjMgPDEuMy4wXG4vLyB+MS4yLjAsIH4+MS4yLjAgLS0+ID49MS4yLjAgPDEuMy4wXG5mdW5jdGlvbiByZXBsYWNlVGlsZGVzIChjb21wLCBvcHRpb25zKSB7XG4gIHJldHVybiBjb21wLnRyaW0oKS5zcGxpdCgvXFxzKy8pLm1hcChmdW5jdGlvbiAoY29tcCkge1xuICAgIHJldHVybiByZXBsYWNlVGlsZGUoY29tcCwgb3B0aW9ucylcbiAgfSkuam9pbignICcpXG59XG5cbmZ1bmN0aW9uIHJlcGxhY2VUaWxkZSAoY29tcCwgb3B0aW9ucykge1xuICB2YXIgciA9IG9wdGlvbnMubG9vc2UgPyByZVtUSUxERUxPT1NFXSA6IHJlW1RJTERFXVxuICByZXR1cm4gY29tcC5yZXBsYWNlKHIsIGZ1bmN0aW9uIChfLCBNLCBtLCBwLCBwcikge1xuICAgIGRlYnVnKCd0aWxkZScsIGNvbXAsIF8sIE0sIG0sIHAsIHByKVxuICAgIHZhciByZXRcblxuICAgIGlmIChpc1goTSkpIHtcbiAgICAgIHJldCA9ICcnXG4gICAgfSBlbHNlIGlmIChpc1gobSkpIHtcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4wLjAgPCcgKyAoK00gKyAxKSArICcuMC4wJ1xuICAgIH0gZWxzZSBpZiAoaXNYKHApKSB7XG4gICAgICAvLyB+MS4yID09ID49MS4yLjAgPDEuMy4wXG4gICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLjAgPCcgKyBNICsgJy4nICsgKCttICsgMSkgKyAnLjAnXG4gICAgfSBlbHNlIGlmIChwcikge1xuICAgICAgZGVidWcoJ3JlcGxhY2VUaWxkZSBwcicsIHByKVxuICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArICctJyArIHByICtcbiAgICAgICAgICAgICcgPCcgKyBNICsgJy4nICsgKCttICsgMSkgKyAnLjAnXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIH4xLjIuMyA9PSA+PTEuMi4zIDwxLjMuMFxuICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArXG4gICAgICAgICAgICAnIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJ1xuICAgIH1cblxuICAgIGRlYnVnKCd0aWxkZSByZXR1cm4nLCByZXQpXG4gICAgcmV0dXJuIHJldFxuICB9KVxufVxuXG4vLyBeIC0tPiAqIChhbnksIGtpbmRhIHNpbGx5KVxuLy8gXjIsIF4yLngsIF4yLngueCAtLT4gPj0yLjAuMCA8My4wLjBcbi8vIF4yLjAsIF4yLjAueCAtLT4gPj0yLjAuMCA8My4wLjBcbi8vIF4xLjIsIF4xLjIueCAtLT4gPj0xLjIuMCA8Mi4wLjBcbi8vIF4xLjIuMyAtLT4gPj0xLjIuMyA8Mi4wLjBcbi8vIF4xLjIuMCAtLT4gPj0xLjIuMCA8Mi4wLjBcbmZ1bmN0aW9uIHJlcGxhY2VDYXJldHMgKGNvbXAsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIGNvbXAudHJpbSgpLnNwbGl0KC9cXHMrLykubWFwKGZ1bmN0aW9uIChjb21wKSB7XG4gICAgcmV0dXJuIHJlcGxhY2VDYXJldChjb21wLCBvcHRpb25zKVxuICB9KS5qb2luKCcgJylcbn1cblxuZnVuY3Rpb24gcmVwbGFjZUNhcmV0IChjb21wLCBvcHRpb25zKSB7XG4gIGRlYnVnKCdjYXJldCcsIGNvbXAsIG9wdGlvbnMpXG4gIHZhciByID0gb3B0aW9ucy5sb29zZSA/IHJlW0NBUkVUTE9PU0VdIDogcmVbQ0FSRVRdXG4gIHJldHVybiBjb21wLnJlcGxhY2UociwgZnVuY3Rpb24gKF8sIE0sIG0sIHAsIHByKSB7XG4gICAgZGVidWcoJ2NhcmV0JywgY29tcCwgXywgTSwgbSwgcCwgcHIpXG4gICAgdmFyIHJldFxuXG4gICAgaWYgKGlzWChNKSkge1xuICAgICAgcmV0ID0gJydcbiAgICB9IGVsc2UgaWYgKGlzWChtKSkge1xuICAgICAgcmV0ID0gJz49JyArIE0gKyAnLjAuMCA8JyArICgrTSArIDEpICsgJy4wLjAnXG4gICAgfSBlbHNlIGlmIChpc1gocCkpIHtcbiAgICAgIGlmIChNID09PSAnMCcpIHtcbiAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4wIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJ1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4wIDwnICsgKCtNICsgMSkgKyAnLjAuMCdcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHByKSB7XG4gICAgICBkZWJ1ZygncmVwbGFjZUNhcmV0IHByJywgcHIpXG4gICAgICBpZiAoTSA9PT0gJzAnKSB7XG4gICAgICAgIGlmIChtID09PSAnMCcpIHtcbiAgICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICsgJy0nICsgcHIgK1xuICAgICAgICAgICAgICAgICcgPCcgKyBNICsgJy4nICsgbSArICcuJyArICgrcCArIDEpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArICctJyArIHByICtcbiAgICAgICAgICAgICAgICAnIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJ1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICsgJy0nICsgcHIgK1xuICAgICAgICAgICAgICAnIDwnICsgKCtNICsgMSkgKyAnLjAuMCdcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZGVidWcoJ25vIHByJylcbiAgICAgIGlmIChNID09PSAnMCcpIHtcbiAgICAgICAgaWYgKG0gPT09ICcwJykge1xuICAgICAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgK1xuICAgICAgICAgICAgICAgICcgPCcgKyBNICsgJy4nICsgbSArICcuJyArICgrcCArIDEpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArXG4gICAgICAgICAgICAgICAgJyA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCdcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArXG4gICAgICAgICAgICAgICcgPCcgKyAoK00gKyAxKSArICcuMC4wJ1xuICAgICAgfVxuICAgIH1cblxuICAgIGRlYnVnKCdjYXJldCByZXR1cm4nLCByZXQpXG4gICAgcmV0dXJuIHJldFxuICB9KVxufVxuXG5mdW5jdGlvbiByZXBsYWNlWFJhbmdlcyAoY29tcCwgb3B0aW9ucykge1xuICBkZWJ1ZygncmVwbGFjZVhSYW5nZXMnLCBjb21wLCBvcHRpb25zKVxuICByZXR1cm4gY29tcC5zcGxpdCgvXFxzKy8pLm1hcChmdW5jdGlvbiAoY29tcCkge1xuICAgIHJldHVybiByZXBsYWNlWFJhbmdlKGNvbXAsIG9wdGlvbnMpXG4gIH0pLmpvaW4oJyAnKVxufVxuXG5mdW5jdGlvbiByZXBsYWNlWFJhbmdlIChjb21wLCBvcHRpb25zKSB7XG4gIGNvbXAgPSBjb21wLnRyaW0oKVxuICB2YXIgciA9IG9wdGlvbnMubG9vc2UgPyByZVtYUkFOR0VMT09TRV0gOiByZVtYUkFOR0VdXG4gIHJldHVybiBjb21wLnJlcGxhY2UociwgZnVuY3Rpb24gKHJldCwgZ3RsdCwgTSwgbSwgcCwgcHIpIHtcbiAgICBkZWJ1ZygneFJhbmdlJywgY29tcCwgcmV0LCBndGx0LCBNLCBtLCBwLCBwcilcbiAgICB2YXIgeE0gPSBpc1goTSlcbiAgICB2YXIgeG0gPSB4TSB8fCBpc1gobSlcbiAgICB2YXIgeHAgPSB4bSB8fCBpc1gocClcbiAgICB2YXIgYW55WCA9IHhwXG5cbiAgICBpZiAoZ3RsdCA9PT0gJz0nICYmIGFueVgpIHtcbiAgICAgIGd0bHQgPSAnJ1xuICAgIH1cblxuICAgIGlmICh4TSkge1xuICAgICAgaWYgKGd0bHQgPT09ICc+JyB8fCBndGx0ID09PSAnPCcpIHtcbiAgICAgICAgLy8gbm90aGluZyBpcyBhbGxvd2VkXG4gICAgICAgIHJldCA9ICc8MC4wLjAnXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBub3RoaW5nIGlzIGZvcmJpZGRlblxuICAgICAgICByZXQgPSAnKidcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGd0bHQgJiYgYW55WCkge1xuICAgICAgLy8gd2Uga25vdyBwYXRjaCBpcyBhbiB4LCBiZWNhdXNlIHdlIGhhdmUgYW55IHggYXQgYWxsLlxuICAgICAgLy8gcmVwbGFjZSBYIHdpdGggMFxuICAgICAgaWYgKHhtKSB7XG4gICAgICAgIG0gPSAwXG4gICAgICB9XG4gICAgICBwID0gMFxuXG4gICAgICBpZiAoZ3RsdCA9PT0gJz4nKSB7XG4gICAgICAgIC8vID4xID0+ID49Mi4wLjBcbiAgICAgICAgLy8gPjEuMiA9PiA+PTEuMy4wXG4gICAgICAgIC8vID4xLjIuMyA9PiA+PSAxLjIuNFxuICAgICAgICBndGx0ID0gJz49J1xuICAgICAgICBpZiAoeG0pIHtcbiAgICAgICAgICBNID0gK00gKyAxXG4gICAgICAgICAgbSA9IDBcbiAgICAgICAgICBwID0gMFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG0gPSArbSArIDFcbiAgICAgICAgICBwID0gMFxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGd0bHQgPT09ICc8PScpIHtcbiAgICAgICAgLy8gPD0wLjcueCBpcyBhY3R1YWxseSA8MC44LjAsIHNpbmNlIGFueSAwLjcueCBzaG91bGRcbiAgICAgICAgLy8gcGFzcy4gIFNpbWlsYXJseSwgPD03LnggaXMgYWN0dWFsbHkgPDguMC4wLCBldGMuXG4gICAgICAgIGd0bHQgPSAnPCdcbiAgICAgICAgaWYgKHhtKSB7XG4gICAgICAgICAgTSA9ICtNICsgMVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG0gPSArbSArIDFcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXQgPSBndGx0ICsgTSArICcuJyArIG0gKyAnLicgKyBwXG4gICAgfSBlbHNlIGlmICh4bSkge1xuICAgICAgcmV0ID0gJz49JyArIE0gKyAnLjAuMCA8JyArICgrTSArIDEpICsgJy4wLjAnXG4gICAgfSBlbHNlIGlmICh4cCkge1xuICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4wIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJ1xuICAgIH1cblxuICAgIGRlYnVnKCd4UmFuZ2UgcmV0dXJuJywgcmV0KVxuXG4gICAgcmV0dXJuIHJldFxuICB9KVxufVxuXG4vLyBCZWNhdXNlICogaXMgQU5ELWVkIHdpdGggZXZlcnl0aGluZyBlbHNlIGluIHRoZSBjb21wYXJhdG9yLFxuLy8gYW5kICcnIG1lYW5zIFwiYW55IHZlcnNpb25cIiwganVzdCByZW1vdmUgdGhlICpzIGVudGlyZWx5LlxuZnVuY3Rpb24gcmVwbGFjZVN0YXJzIChjb21wLCBvcHRpb25zKSB7XG4gIGRlYnVnKCdyZXBsYWNlU3RhcnMnLCBjb21wLCBvcHRpb25zKVxuICAvLyBMb29zZW5lc3MgaXMgaWdub3JlZCBoZXJlLiAgc3RhciBpcyBhbHdheXMgYXMgbG9vc2UgYXMgaXQgZ2V0cyFcbiAgcmV0dXJuIGNvbXAudHJpbSgpLnJlcGxhY2UocmVbU1RBUl0sICcnKVxufVxuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIHBhc3NlZCB0byBzdHJpbmcucmVwbGFjZShyZVtIWVBIRU5SQU5HRV0pXG4vLyBNLCBtLCBwYXRjaCwgcHJlcmVsZWFzZSwgYnVpbGRcbi8vIDEuMiAtIDMuNC41ID0+ID49MS4yLjAgPD0zLjQuNVxuLy8gMS4yLjMgLSAzLjQgPT4gPj0xLjIuMCA8My41LjAgQW55IDMuNC54IHdpbGwgZG9cbi8vIDEuMiAtIDMuNCA9PiA+PTEuMi4wIDwzLjUuMFxuZnVuY3Rpb24gaHlwaGVuUmVwbGFjZSAoJDAsXG4gIGZyb20sIGZNLCBmbSwgZnAsIGZwciwgZmIsXG4gIHRvLCB0TSwgdG0sIHRwLCB0cHIsIHRiKSB7XG4gIGlmIChpc1goZk0pKSB7XG4gICAgZnJvbSA9ICcnXG4gIH0gZWxzZSBpZiAoaXNYKGZtKSkge1xuICAgIGZyb20gPSAnPj0nICsgZk0gKyAnLjAuMCdcbiAgfSBlbHNlIGlmIChpc1goZnApKSB7XG4gICAgZnJvbSA9ICc+PScgKyBmTSArICcuJyArIGZtICsgJy4wJ1xuICB9IGVsc2Uge1xuICAgIGZyb20gPSAnPj0nICsgZnJvbVxuICB9XG5cbiAgaWYgKGlzWCh0TSkpIHtcbiAgICB0byA9ICcnXG4gIH0gZWxzZSBpZiAoaXNYKHRtKSkge1xuICAgIHRvID0gJzwnICsgKCt0TSArIDEpICsgJy4wLjAnXG4gIH0gZWxzZSBpZiAoaXNYKHRwKSkge1xuICAgIHRvID0gJzwnICsgdE0gKyAnLicgKyAoK3RtICsgMSkgKyAnLjAnXG4gIH0gZWxzZSBpZiAodHByKSB7XG4gICAgdG8gPSAnPD0nICsgdE0gKyAnLicgKyB0bSArICcuJyArIHRwICsgJy0nICsgdHByXG4gIH0gZWxzZSB7XG4gICAgdG8gPSAnPD0nICsgdG9cbiAgfVxuXG4gIHJldHVybiAoZnJvbSArICcgJyArIHRvKS50cmltKClcbn1cblxuLy8gaWYgQU5ZIG9mIHRoZSBzZXRzIG1hdGNoIEFMTCBvZiBpdHMgY29tcGFyYXRvcnMsIHRoZW4gcGFzc1xuUmFuZ2UucHJvdG90eXBlLnRlc3QgPSBmdW5jdGlvbiAodmVyc2lvbikge1xuICBpZiAoIXZlcnNpb24pIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIGlmICh0eXBlb2YgdmVyc2lvbiA9PT0gJ3N0cmluZycpIHtcbiAgICB2ZXJzaW9uID0gbmV3IFNlbVZlcih2ZXJzaW9uLCB0aGlzLm9wdGlvbnMpXG4gIH1cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuc2V0Lmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHRlc3RTZXQodGhpcy5zZXRbaV0sIHZlcnNpb24sIHRoaXMub3B0aW9ucykpIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZVxufVxuXG5mdW5jdGlvbiB0ZXN0U2V0IChzZXQsIHZlcnNpb24sIG9wdGlvbnMpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZXQubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoIXNldFtpXS50ZXN0KHZlcnNpb24pKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gIH1cblxuICBpZiAodmVyc2lvbi5wcmVyZWxlYXNlLmxlbmd0aCAmJiAhb3B0aW9ucy5pbmNsdWRlUHJlcmVsZWFzZSkge1xuICAgIC8vIEZpbmQgdGhlIHNldCBvZiB2ZXJzaW9ucyB0aGF0IGFyZSBhbGxvd2VkIHRvIGhhdmUgcHJlcmVsZWFzZXNcbiAgICAvLyBGb3IgZXhhbXBsZSwgXjEuMi4zLXByLjEgZGVzdWdhcnMgdG8gPj0xLjIuMy1wci4xIDwyLjAuMFxuICAgIC8vIFRoYXQgc2hvdWxkIGFsbG93IGAxLjIuMy1wci4yYCB0byBwYXNzLlxuICAgIC8vIEhvd2V2ZXIsIGAxLjIuNC1hbHBoYS5ub3RyZWFkeWAgc2hvdWxkIE5PVCBiZSBhbGxvd2VkLFxuICAgIC8vIGV2ZW4gdGhvdWdoIGl0J3Mgd2l0aGluIHRoZSByYW5nZSBzZXQgYnkgdGhlIGNvbXBhcmF0b3JzLlxuICAgIGZvciAoaSA9IDA7IGkgPCBzZXQubGVuZ3RoOyBpKyspIHtcbiAgICAgIGRlYnVnKHNldFtpXS5zZW12ZXIpXG4gICAgICBpZiAoc2V0W2ldLnNlbXZlciA9PT0gQU5ZKSB7XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChzZXRbaV0uc2VtdmVyLnByZXJlbGVhc2UubGVuZ3RoID4gMCkge1xuICAgICAgICB2YXIgYWxsb3dlZCA9IHNldFtpXS5zZW12ZXJcbiAgICAgICAgaWYgKGFsbG93ZWQubWFqb3IgPT09IHZlcnNpb24ubWFqb3IgJiZcbiAgICAgICAgICAgIGFsbG93ZWQubWlub3IgPT09IHZlcnNpb24ubWlub3IgJiZcbiAgICAgICAgICAgIGFsbG93ZWQucGF0Y2ggPT09IHZlcnNpb24ucGF0Y2gpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVmVyc2lvbiBoYXMgYSAtcHJlLCBidXQgaXQncyBub3Qgb25lIG9mIHRoZSBvbmVzIHdlIGxpa2UuXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICByZXR1cm4gdHJ1ZVxufVxuXG5leHBvcnRzLnNhdGlzZmllcyA9IHNhdGlzZmllc1xuZnVuY3Rpb24gc2F0aXNmaWVzICh2ZXJzaW9uLCByYW5nZSwgb3B0aW9ucykge1xuICB0cnkge1xuICAgIHJhbmdlID0gbmV3IFJhbmdlKHJhbmdlLCBvcHRpb25zKVxuICB9IGNhdGNoIChlcikge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIHJldHVybiByYW5nZS50ZXN0KHZlcnNpb24pXG59XG5cbmV4cG9ydHMubWF4U2F0aXNmeWluZyA9IG1heFNhdGlzZnlpbmdcbmZ1bmN0aW9uIG1heFNhdGlzZnlpbmcgKHZlcnNpb25zLCByYW5nZSwgb3B0aW9ucykge1xuICB2YXIgbWF4ID0gbnVsbFxuICB2YXIgbWF4U1YgPSBudWxsXG4gIHRyeSB7XG4gICAgdmFyIHJhbmdlT2JqID0gbmV3IFJhbmdlKHJhbmdlLCBvcHRpb25zKVxuICB9IGNhdGNoIChlcikge1xuICAgIHJldHVybiBudWxsXG4gIH1cbiAgdmVyc2lvbnMuZm9yRWFjaChmdW5jdGlvbiAodikge1xuICAgIGlmIChyYW5nZU9iai50ZXN0KHYpKSB7XG4gICAgICAvLyBzYXRpc2ZpZXModiwgcmFuZ2UsIG9wdGlvbnMpXG4gICAgICBpZiAoIW1heCB8fCBtYXhTVi5jb21wYXJlKHYpID09PSAtMSkge1xuICAgICAgICAvLyBjb21wYXJlKG1heCwgdiwgdHJ1ZSlcbiAgICAgICAgbWF4ID0gdlxuICAgICAgICBtYXhTViA9IG5ldyBTZW1WZXIobWF4LCBvcHRpb25zKVxuICAgICAgfVxuICAgIH1cbiAgfSlcbiAgcmV0dXJuIG1heFxufVxuXG5leHBvcnRzLm1pblNhdGlzZnlpbmcgPSBtaW5TYXRpc2Z5aW5nXG5mdW5jdGlvbiBtaW5TYXRpc2Z5aW5nICh2ZXJzaW9ucywgcmFuZ2UsIG9wdGlvbnMpIHtcbiAgdmFyIG1pbiA9IG51bGxcbiAgdmFyIG1pblNWID0gbnVsbFxuICB0cnkge1xuICAgIHZhciByYW5nZU9iaiA9IG5ldyBSYW5nZShyYW5nZSwgb3B0aW9ucylcbiAgfSBjYXRjaCAoZXIpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG4gIHZlcnNpb25zLmZvckVhY2goZnVuY3Rpb24gKHYpIHtcbiAgICBpZiAocmFuZ2VPYmoudGVzdCh2KSkge1xuICAgICAgLy8gc2F0aXNmaWVzKHYsIHJhbmdlLCBvcHRpb25zKVxuICAgICAgaWYgKCFtaW4gfHwgbWluU1YuY29tcGFyZSh2KSA9PT0gMSkge1xuICAgICAgICAvLyBjb21wYXJlKG1pbiwgdiwgdHJ1ZSlcbiAgICAgICAgbWluID0gdlxuICAgICAgICBtaW5TViA9IG5ldyBTZW1WZXIobWluLCBvcHRpb25zKVxuICAgICAgfVxuICAgIH1cbiAgfSlcbiAgcmV0dXJuIG1pblxufVxuXG5leHBvcnRzLm1pblZlcnNpb24gPSBtaW5WZXJzaW9uXG5mdW5jdGlvbiBtaW5WZXJzaW9uIChyYW5nZSwgbG9vc2UpIHtcbiAgcmFuZ2UgPSBuZXcgUmFuZ2UocmFuZ2UsIGxvb3NlKVxuXG4gIHZhciBtaW52ZXIgPSBuZXcgU2VtVmVyKCcwLjAuMCcpXG4gIGlmIChyYW5nZS50ZXN0KG1pbnZlcikpIHtcbiAgICByZXR1cm4gbWludmVyXG4gIH1cblxuICBtaW52ZXIgPSBuZXcgU2VtVmVyKCcwLjAuMC0wJylcbiAgaWYgKHJhbmdlLnRlc3QobWludmVyKSkge1xuICAgIHJldHVybiBtaW52ZXJcbiAgfVxuXG4gIG1pbnZlciA9IG51bGxcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCByYW5nZS5zZXQubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgY29tcGFyYXRvcnMgPSByYW5nZS5zZXRbaV1cblxuICAgIGNvbXBhcmF0b3JzLmZvckVhY2goZnVuY3Rpb24gKGNvbXBhcmF0b3IpIHtcbiAgICAgIC8vIENsb25lIHRvIGF2b2lkIG1hbmlwdWxhdGluZyB0aGUgY29tcGFyYXRvcidzIHNlbXZlciBvYmplY3QuXG4gICAgICB2YXIgY29tcHZlciA9IG5ldyBTZW1WZXIoY29tcGFyYXRvci5zZW12ZXIudmVyc2lvbilcbiAgICAgIHN3aXRjaCAoY29tcGFyYXRvci5vcGVyYXRvcikge1xuICAgICAgICBjYXNlICc+JzpcbiAgICAgICAgICBpZiAoY29tcHZlci5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgY29tcHZlci5wYXRjaCsrXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbXB2ZXIucHJlcmVsZWFzZS5wdXNoKDApXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbXB2ZXIucmF3ID0gY29tcHZlci5mb3JtYXQoKVxuICAgICAgICAgIC8qIGZhbGx0aHJvdWdoICovXG4gICAgICAgIGNhc2UgJyc6XG4gICAgICAgIGNhc2UgJz49JzpcbiAgICAgICAgICBpZiAoIW1pbnZlciB8fCBndChtaW52ZXIsIGNvbXB2ZXIpKSB7XG4gICAgICAgICAgICBtaW52ZXIgPSBjb21wdmVyXG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgJzwnOlxuICAgICAgICBjYXNlICc8PSc6XG4gICAgICAgICAgLyogSWdub3JlIG1heGltdW0gdmVyc2lvbnMgKi9cbiAgICAgICAgICBicmVha1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCBvcGVyYXRpb246ICcgKyBjb21wYXJhdG9yLm9wZXJhdG9yKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICBpZiAobWludmVyICYmIHJhbmdlLnRlc3QobWludmVyKSkge1xuICAgIHJldHVybiBtaW52ZXJcbiAgfVxuXG4gIHJldHVybiBudWxsXG59XG5cbmV4cG9ydHMudmFsaWRSYW5nZSA9IHZhbGlkUmFuZ2VcbmZ1bmN0aW9uIHZhbGlkUmFuZ2UgKHJhbmdlLCBvcHRpb25zKSB7XG4gIHRyeSB7XG4gICAgLy8gUmV0dXJuICcqJyBpbnN0ZWFkIG9mICcnIHNvIHRoYXQgdHJ1dGhpbmVzcyB3b3Jrcy5cbiAgICAvLyBUaGlzIHdpbGwgdGhyb3cgaWYgaXQncyBpbnZhbGlkIGFueXdheVxuICAgIHJldHVybiBuZXcgUmFuZ2UocmFuZ2UsIG9wdGlvbnMpLnJhbmdlIHx8ICcqJ1xuICB9IGNhdGNoIChlcikge1xuICAgIHJldHVybiBudWxsXG4gIH1cbn1cblxuLy8gRGV0ZXJtaW5lIGlmIHZlcnNpb24gaXMgbGVzcyB0aGFuIGFsbCB0aGUgdmVyc2lvbnMgcG9zc2libGUgaW4gdGhlIHJhbmdlXG5leHBvcnRzLmx0ciA9IGx0clxuZnVuY3Rpb24gbHRyICh2ZXJzaW9uLCByYW5nZSwgb3B0aW9ucykge1xuICByZXR1cm4gb3V0c2lkZSh2ZXJzaW9uLCByYW5nZSwgJzwnLCBvcHRpb25zKVxufVxuXG4vLyBEZXRlcm1pbmUgaWYgdmVyc2lvbiBpcyBncmVhdGVyIHRoYW4gYWxsIHRoZSB2ZXJzaW9ucyBwb3NzaWJsZSBpbiB0aGUgcmFuZ2UuXG5leHBvcnRzLmd0ciA9IGd0clxuZnVuY3Rpb24gZ3RyICh2ZXJzaW9uLCByYW5nZSwgb3B0aW9ucykge1xuICByZXR1cm4gb3V0c2lkZSh2ZXJzaW9uLCByYW5nZSwgJz4nLCBvcHRpb25zKVxufVxuXG5leHBvcnRzLm91dHNpZGUgPSBvdXRzaWRlXG5mdW5jdGlvbiBvdXRzaWRlICh2ZXJzaW9uLCByYW5nZSwgaGlsbywgb3B0aW9ucykge1xuICB2ZXJzaW9uID0gbmV3IFNlbVZlcih2ZXJzaW9uLCBvcHRpb25zKVxuICByYW5nZSA9IG5ldyBSYW5nZShyYW5nZSwgb3B0aW9ucylcblxuICB2YXIgZ3RmbiwgbHRlZm4sIGx0Zm4sIGNvbXAsIGVjb21wXG4gIHN3aXRjaCAoaGlsbykge1xuICAgIGNhc2UgJz4nOlxuICAgICAgZ3RmbiA9IGd0XG4gICAgICBsdGVmbiA9IGx0ZVxuICAgICAgbHRmbiA9IGx0XG4gICAgICBjb21wID0gJz4nXG4gICAgICBlY29tcCA9ICc+PSdcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnPCc6XG4gICAgICBndGZuID0gbHRcbiAgICAgIGx0ZWZuID0gZ3RlXG4gICAgICBsdGZuID0gZ3RcbiAgICAgIGNvbXAgPSAnPCdcbiAgICAgIGVjb21wID0gJzw9J1xuICAgICAgYnJlYWtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignTXVzdCBwcm92aWRlIGEgaGlsbyB2YWwgb2YgXCI8XCIgb3IgXCI+XCInKVxuICB9XG5cbiAgLy8gSWYgaXQgc2F0aXNpZmVzIHRoZSByYW5nZSBpdCBpcyBub3Qgb3V0c2lkZVxuICBpZiAoc2F0aXNmaWVzKHZlcnNpb24sIHJhbmdlLCBvcHRpb25zKSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLy8gRnJvbSBub3cgb24sIHZhcmlhYmxlIHRlcm1zIGFyZSBhcyBpZiB3ZSdyZSBpbiBcImd0clwiIG1vZGUuXG4gIC8vIGJ1dCBub3RlIHRoYXQgZXZlcnl0aGluZyBpcyBmbGlwcGVkIGZvciB0aGUgXCJsdHJcIiBmdW5jdGlvbi5cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHJhbmdlLnNldC5sZW5ndGg7ICsraSkge1xuICAgIHZhciBjb21wYXJhdG9ycyA9IHJhbmdlLnNldFtpXVxuXG4gICAgdmFyIGhpZ2ggPSBudWxsXG4gICAgdmFyIGxvdyA9IG51bGxcblxuICAgIGNvbXBhcmF0b3JzLmZvckVhY2goZnVuY3Rpb24gKGNvbXBhcmF0b3IpIHtcbiAgICAgIGlmIChjb21wYXJhdG9yLnNlbXZlciA9PT0gQU5ZKSB7XG4gICAgICAgIGNvbXBhcmF0b3IgPSBuZXcgQ29tcGFyYXRvcignPj0wLjAuMCcpXG4gICAgICB9XG4gICAgICBoaWdoID0gaGlnaCB8fCBjb21wYXJhdG9yXG4gICAgICBsb3cgPSBsb3cgfHwgY29tcGFyYXRvclxuICAgICAgaWYgKGd0Zm4oY29tcGFyYXRvci5zZW12ZXIsIGhpZ2guc2VtdmVyLCBvcHRpb25zKSkge1xuICAgICAgICBoaWdoID0gY29tcGFyYXRvclxuICAgICAgfSBlbHNlIGlmIChsdGZuKGNvbXBhcmF0b3Iuc2VtdmVyLCBsb3cuc2VtdmVyLCBvcHRpb25zKSkge1xuICAgICAgICBsb3cgPSBjb21wYXJhdG9yXG4gICAgICB9XG4gICAgfSlcblxuICAgIC8vIElmIHRoZSBlZGdlIHZlcnNpb24gY29tcGFyYXRvciBoYXMgYSBvcGVyYXRvciB0aGVuIG91ciB2ZXJzaW9uXG4gICAgLy8gaXNuJ3Qgb3V0c2lkZSBpdFxuICAgIGlmIChoaWdoLm9wZXJhdG9yID09PSBjb21wIHx8IGhpZ2gub3BlcmF0b3IgPT09IGVjb21wKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgbG93ZXN0IHZlcnNpb24gY29tcGFyYXRvciBoYXMgYW4gb3BlcmF0b3IgYW5kIG91ciB2ZXJzaW9uXG4gICAgLy8gaXMgbGVzcyB0aGFuIGl0IHRoZW4gaXQgaXNuJ3QgaGlnaGVyIHRoYW4gdGhlIHJhbmdlXG4gICAgaWYgKCghbG93Lm9wZXJhdG9yIHx8IGxvdy5vcGVyYXRvciA9PT0gY29tcCkgJiZcbiAgICAgICAgbHRlZm4odmVyc2lvbiwgbG93LnNlbXZlcikpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH0gZWxzZSBpZiAobG93Lm9wZXJhdG9yID09PSBlY29tcCAmJiBsdGZuKHZlcnNpb24sIGxvdy5zZW12ZXIpKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWVcbn1cblxuZXhwb3J0cy5wcmVyZWxlYXNlID0gcHJlcmVsZWFzZVxuZnVuY3Rpb24gcHJlcmVsZWFzZSAodmVyc2lvbiwgb3B0aW9ucykge1xuICB2YXIgcGFyc2VkID0gcGFyc2UodmVyc2lvbiwgb3B0aW9ucylcbiAgcmV0dXJuIChwYXJzZWQgJiYgcGFyc2VkLnByZXJlbGVhc2UubGVuZ3RoKSA/IHBhcnNlZC5wcmVyZWxlYXNlIDogbnVsbFxufVxuXG5leHBvcnRzLmludGVyc2VjdHMgPSBpbnRlcnNlY3RzXG5mdW5jdGlvbiBpbnRlcnNlY3RzIChyMSwgcjIsIG9wdGlvbnMpIHtcbiAgcjEgPSBuZXcgUmFuZ2UocjEsIG9wdGlvbnMpXG4gIHIyID0gbmV3IFJhbmdlKHIyLCBvcHRpb25zKVxuICByZXR1cm4gcjEuaW50ZXJzZWN0cyhyMilcbn1cblxuZXhwb3J0cy5jb2VyY2UgPSBjb2VyY2VcbmZ1bmN0aW9uIGNvZXJjZSAodmVyc2lvbikge1xuICBpZiAodmVyc2lvbiBpbnN0YW5jZW9mIFNlbVZlcikge1xuICAgIHJldHVybiB2ZXJzaW9uXG4gIH1cblxuICBpZiAodHlwZW9mIHZlcnNpb24gIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIHZhciBtYXRjaCA9IHZlcnNpb24ubWF0Y2gocmVbQ09FUkNFXSlcblxuICBpZiAobWF0Y2ggPT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICByZXR1cm4gcGFyc2UobWF0Y2hbMV0gK1xuICAgICcuJyArIChtYXRjaFsyXSB8fCAnMCcpICtcbiAgICAnLicgKyAobWF0Y2hbM10gfHwgJzAnKSlcbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gW1xuICAnY2F0JyxcbiAgJ2NkJyxcbiAgJ2NobW9kJyxcbiAgJ2NwJyxcbiAgJ2RpcnMnLFxuICAnZWNobycsXG4gICdleGVjJyxcbiAgJ2ZpbmQnLFxuICAnZ3JlcCcsXG4gICdoZWFkJyxcbiAgJ2xuJyxcbiAgJ2xzJyxcbiAgJ21rZGlyJyxcbiAgJ212JyxcbiAgJ3B3ZCcsXG4gICdybScsXG4gICdzZWQnLFxuICAnc2V0JyxcbiAgJ3NvcnQnLFxuICAndGFpbCcsXG4gICd0ZW1wZGlyJyxcbiAgJ3Rlc3QnLFxuICAndG8nLFxuICAndG9FbmQnLFxuICAndG91Y2gnLFxuICAndW5pcScsXG4gICd3aGljaCcsXG5dO1xuIiwiLy9cbi8vIFNoZWxsSlNcbi8vIFVuaXggc2hlbGwgY29tbWFuZHMgb24gdG9wIG9mIE5vZGUncyBBUElcbi8vXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTIgQXJ0dXIgQWRpYlxuLy8gaHR0cDovL2dpdGh1Yi5jb20vc2hlbGxqcy9zaGVsbGpzXG4vL1xuXG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi9zcmMvY29tbW9uJyk7XG5cbi8vQFxuLy9AIEFsbCBjb21tYW5kcyBydW4gc3luY2hyb25vdXNseSwgdW5sZXNzIG90aGVyd2lzZSBzdGF0ZWQuXG4vL0AgQWxsIGNvbW1hbmRzIGFjY2VwdCBzdGFuZGFyZCBiYXNoIGdsb2JiaW5nIGNoYXJhY3RlcnMgKGAqYCwgYD9gLCBldGMuKSxcbi8vQCBjb21wYXRpYmxlIHdpdGggdGhlIFtub2RlIGBnbG9iYCBtb2R1bGVdKGh0dHBzOi8vZ2l0aHViLmNvbS9pc2FhY3Mvbm9kZS1nbG9iKS5cbi8vQFxuLy9AIEZvciBsZXNzLWNvbW1vbmx5IHVzZWQgY29tbWFuZHMgYW5kIGZlYXR1cmVzLCBwbGVhc2UgY2hlY2sgb3V0IG91ciBbd2lraVxuLy9AIHBhZ2VdKGh0dHBzOi8vZ2l0aHViLmNvbS9zaGVsbGpzL3NoZWxsanMvd2lraSkuXG4vL0BcblxuLy8gSW5jbHVkZSB0aGUgZG9jcyBmb3IgYWxsIHRoZSBkZWZhdWx0IGNvbW1hbmRzXG4vL0Bjb21tYW5kc1xuXG4vLyBMb2FkIGFsbCBkZWZhdWx0IGNvbW1hbmRzXG5yZXF1aXJlKCcuL2NvbW1hbmRzJykuZm9yRWFjaChmdW5jdGlvbiAoY29tbWFuZCkge1xuICByZXF1aXJlKCcuL3NyYy8nICsgY29tbWFuZCk7XG59KTtcblxuLy9AXG4vL0AgIyMjIGV4aXQoY29kZSlcbi8vQFxuLy9AIEV4aXRzIHRoZSBjdXJyZW50IHByb2Nlc3Mgd2l0aCB0aGUgZ2l2ZW4gZXhpdCBgY29kZWAuXG5leHBvcnRzLmV4aXQgPSBwcm9jZXNzLmV4aXQ7XG5cbi8vQGluY2x1ZGUgLi9zcmMvZXJyb3JcbmV4cG9ydHMuZXJyb3IgPSByZXF1aXJlKCcuL3NyYy9lcnJvcicpO1xuXG4vL0BpbmNsdWRlIC4vc3JjL2NvbW1vblxuZXhwb3J0cy5TaGVsbFN0cmluZyA9IGNvbW1vbi5TaGVsbFN0cmluZztcblxuLy9AXG4vL0AgIyMjIGVudlsnVkFSX05BTUUnXVxuLy9AXG4vL0AgT2JqZWN0IGNvbnRhaW5pbmcgZW52aXJvbm1lbnQgdmFyaWFibGVzIChib3RoIGdldHRlciBhbmQgc2V0dGVyKS4gU2hvcnRjdXRcbi8vQCB0byBgcHJvY2Vzcy5lbnZgLlxuZXhwb3J0cy5lbnYgPSBwcm9jZXNzLmVudjtcblxuLy9AXG4vL0AgIyMjIFBpcGVzXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBncmVwKCdmb28nLCAnZmlsZTEudHh0JywgJ2ZpbGUyLnR4dCcpLnNlZCgvby9nLCAnYScpLnRvKCdvdXRwdXQudHh0Jyk7XG4vL0AgZWNobygnZmlsZXMgd2l0aCBvXFwncyBpbiB0aGUgbmFtZTpcXG4nICsgbHMoKS5ncmVwKCdvJykpO1xuLy9AIGNhdCgndGVzdC5qcycpLmV4ZWMoJ25vZGUnKTsgLy8gcGlwZSB0byBleGVjKCkgY2FsbFxuLy9AIGBgYFxuLy9AXG4vL0AgQ29tbWFuZHMgY2FuIHNlbmQgdGhlaXIgb3V0cHV0IHRvIGFub3RoZXIgY29tbWFuZCBpbiBhIHBpcGUtbGlrZSBmYXNoaW9uLlxuLy9AIGBzZWRgLCBgZ3JlcGAsIGBjYXRgLCBgZXhlY2AsIGB0b2AsIGFuZCBgdG9FbmRgIGNhbiBhcHBlYXIgb24gdGhlIHJpZ2h0LWhhbmRcbi8vQCBzaWRlIG9mIGEgcGlwZS4gUGlwZXMgY2FuIGJlIGNoYWluZWQuXG5cbi8vQFxuLy9AICMjIENvbmZpZ3VyYXRpb25cbi8vQFxuXG5leHBvcnRzLmNvbmZpZyA9IGNvbW1vbi5jb25maWc7XG5cbi8vQFxuLy9AICMjIyBjb25maWcuc2lsZW50XG4vL0Bcbi8vQCBFeGFtcGxlOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIHZhciBzaCA9IHJlcXVpcmUoJ3NoZWxsanMnKTtcbi8vQCB2YXIgc2lsZW50U3RhdGUgPSBzaC5jb25maWcuc2lsZW50OyAvLyBzYXZlIG9sZCBzaWxlbnQgc3RhdGVcbi8vQCBzaC5jb25maWcuc2lsZW50ID0gdHJ1ZTtcbi8vQCAvKiAuLi4gKi9cbi8vQCBzaC5jb25maWcuc2lsZW50ID0gc2lsZW50U3RhdGU7IC8vIHJlc3RvcmUgb2xkIHNpbGVudCBzdGF0ZVxuLy9AIGBgYFxuLy9AXG4vL0AgU3VwcHJlc3NlcyBhbGwgY29tbWFuZCBvdXRwdXQgaWYgYHRydWVgLCBleGNlcHQgZm9yIGBlY2hvKClgIGNhbGxzLlxuLy9AIERlZmF1bHQgaXMgYGZhbHNlYC5cblxuLy9AXG4vL0AgIyMjIGNvbmZpZy5mYXRhbFxuLy9AXG4vL0AgRXhhbXBsZTpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCByZXF1aXJlKCdzaGVsbGpzL2dsb2JhbCcpO1xuLy9AIGNvbmZpZy5mYXRhbCA9IHRydWU7IC8vIG9yIHNldCgnLWUnKTtcbi8vQCBjcCgndGhpc19maWxlX2RvZXNfbm90X2V4aXN0JywgJy9kZXYvbnVsbCcpOyAvLyB0aHJvd3MgRXJyb3IgaGVyZVxuLy9AIC8qIG1vcmUgY29tbWFuZHMuLi4gKi9cbi8vQCBgYGBcbi8vQFxuLy9AIElmIGB0cnVlYCwgdGhlIHNjcmlwdCB3aWxsIHRocm93IGEgSmF2YXNjcmlwdCBlcnJvciB3aGVuIGFueSBzaGVsbC5qc1xuLy9AIGNvbW1hbmQgZW5jb3VudGVycyBhbiBlcnJvci4gRGVmYXVsdCBpcyBgZmFsc2VgLiBUaGlzIGlzIGFuYWxvZ291cyB0b1xuLy9AIEJhc2gncyBgc2V0IC1lYC5cblxuLy9AXG4vL0AgIyMjIGNvbmZpZy52ZXJib3NlXG4vL0Bcbi8vQCBFeGFtcGxlOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIGNvbmZpZy52ZXJib3NlID0gdHJ1ZTsgLy8gb3Igc2V0KCctdicpO1xuLy9AIGNkKCdkaXIvJyk7XG4vL0Agcm0oJy1yZicsICdmb28udHh0JywgJ2Jhci50eHQnKTtcbi8vQCBleGVjKCdlY2hvIGhlbGxvJyk7XG4vL0AgYGBgXG4vL0Bcbi8vQCBXaWxsIHByaW50IGVhY2ggY29tbWFuZCBhcyBmb2xsb3dzOlxuLy9AXG4vL0AgYGBgXG4vL0AgY2QgZGlyL1xuLy9AIHJtIC1yZiBmb28udHh0IGJhci50eHRcbi8vQCBleGVjIGVjaG8gaGVsbG9cbi8vQCBgYGBcblxuLy9AXG4vL0AgIyMjIGNvbmZpZy5nbG9iT3B0aW9uc1xuLy9AXG4vL0AgRXhhbXBsZTpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBjb25maWcuZ2xvYk9wdGlvbnMgPSB7bm9kaXI6IHRydWV9O1xuLy9AIGBgYFxuLy9AXG4vL0AgVXNlIHRoaXMgdmFsdWUgZm9yIGNhbGxzIHRvIGBnbG9iLnN5bmMoKWAgaW5zdGVhZCBvZiB0aGUgZGVmYXVsdCBvcHRpb25zLlxuXG4vL0Bcbi8vQCAjIyMgY29uZmlnLnJlc2V0KClcbi8vQFxuLy9AIEV4YW1wbGU6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgdmFyIHNoZWxsID0gcmVxdWlyZSgnc2hlbGxqcycpO1xuLy9AIC8vIE1ha2UgY2hhbmdlcyB0byBzaGVsbC5jb25maWcsIGFuZCBkbyBzdHVmZi4uLlxuLy9AIC8qIC4uLiAqL1xuLy9AIHNoZWxsLmNvbmZpZy5yZXNldCgpOyAvLyByZXNldCB0byBvcmlnaW5hbCBzdGF0ZVxuLy9AIC8vIERvIG1vcmUgc3R1ZmYsIGJ1dCB3aXRoIG9yaWdpbmFsIHNldHRpbmdzXG4vL0AgLyogLi4uICovXG4vL0AgYGBgXG4vL0Bcbi8vQCBSZXNldCBgc2hlbGwuY29uZmlnYCB0byB0aGUgZGVmYXVsdHM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0Age1xuLy9AICAgZmF0YWw6IGZhbHNlLFxuLy9AICAgZ2xvYk9wdGlvbnM6IHt9LFxuLy9AICAgbWF4ZGVwdGg6IDI1NSxcbi8vQCAgIG5vZ2xvYjogZmFsc2UsXG4vL0AgICBzaWxlbnQ6IGZhbHNlLFxuLy9AICAgdmVyYm9zZTogZmFsc2UsXG4vL0AgfVxuLy9AIGBgYFxuIiwidmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgZnMgPSByZXF1aXJlKCdmcycpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ2NhdCcsIF9jYXQsIHtcbiAgY2FuUmVjZWl2ZVBpcGU6IHRydWUsXG4gIGNtZE9wdGlvbnM6IHtcbiAgICAnbic6ICdudW1iZXInLFxuICB9LFxufSk7XG5cbi8vQFxuLy9AICMjIyBjYXQoW29wdGlvbnMsXSBmaWxlIFssIGZpbGUgLi4uXSlcbi8vQCAjIyMgY2F0KFtvcHRpb25zLF0gZmlsZV9hcnJheSlcbi8vQFxuLy9AIEF2YWlsYWJsZSBvcHRpb25zOlxuLy9AXG4vL0AgKyBgLW5gOiBudW1iZXIgYWxsIG91dHB1dCBsaW5lc1xuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgdmFyIHN0ciA9IGNhdCgnZmlsZSoudHh0Jyk7XG4vL0AgdmFyIHN0ciA9IGNhdCgnZmlsZTEnLCAnZmlsZTInKTtcbi8vQCB2YXIgc3RyID0gY2F0KFsnZmlsZTEnLCAnZmlsZTInXSk7IC8vIHNhbWUgYXMgYWJvdmVcbi8vQCBgYGBcbi8vQFxuLy9AIFJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyB0aGUgZ2l2ZW4gZmlsZSwgb3IgYSBjb25jYXRlbmF0ZWQgc3RyaW5nXG4vL0AgY29udGFpbmluZyB0aGUgZmlsZXMgaWYgbW9yZSB0aGFuIG9uZSBmaWxlIGlzIGdpdmVuIChhIG5ldyBsaW5lIGNoYXJhY3RlciBpc1xuLy9AIGludHJvZHVjZWQgYmV0d2VlbiBlYWNoIGZpbGUpLlxuZnVuY3Rpb24gX2NhdChvcHRpb25zLCBmaWxlcykge1xuICB2YXIgY2F0ID0gY29tbW9uLnJlYWRGcm9tUGlwZSgpO1xuXG4gIGlmICghZmlsZXMgJiYgIWNhdCkgY29tbW9uLmVycm9yKCdubyBwYXRocyBnaXZlbicpO1xuXG4gIGZpbGVzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gIGZpbGVzLmZvckVhY2goZnVuY3Rpb24gKGZpbGUpIHtcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZmlsZSkpIHtcbiAgICAgIGNvbW1vbi5lcnJvcignbm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeTogJyArIGZpbGUpO1xuICAgIH0gZWxzZSBpZiAoY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhmaWxlKS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICBjb21tb24uZXJyb3IoZmlsZSArICc6IElzIGEgZGlyZWN0b3J5Jyk7XG4gICAgfVxuXG4gICAgY2F0ICs9IGZzLnJlYWRGaWxlU3luYyhmaWxlLCAndXRmOCcpO1xuICB9KTtcblxuICBpZiAob3B0aW9ucy5udW1iZXIpIHtcbiAgICBjYXQgPSBhZGROdW1iZXJzKGNhdCk7XG4gIH1cblxuICByZXR1cm4gY2F0O1xufVxubW9kdWxlLmV4cG9ydHMgPSBfY2F0O1xuXG5mdW5jdGlvbiBhZGROdW1iZXJzKGNhdCkge1xuICB2YXIgbGluZXMgPSBjYXQuc3BsaXQoJ1xcbicpO1xuICB2YXIgbGFzdExpbmUgPSBsaW5lcy5wb3AoKTtcblxuICBsaW5lcyA9IGxpbmVzLm1hcChmdW5jdGlvbiAobGluZSwgaSkge1xuICAgIHJldHVybiBudW1iZXJlZExpbmUoaSArIDEsIGxpbmUpO1xuICB9KTtcblxuICBpZiAobGFzdExpbmUubGVuZ3RoKSB7XG4gICAgbGFzdExpbmUgPSBudW1iZXJlZExpbmUobGluZXMubGVuZ3RoICsgMSwgbGFzdExpbmUpO1xuICB9XG4gIGxpbmVzLnB1c2gobGFzdExpbmUpO1xuXG4gIHJldHVybiBsaW5lcy5qb2luKCdcXG4nKTtcbn1cblxuZnVuY3Rpb24gbnVtYmVyZWRMaW5lKG4sIGxpbmUpIHtcbiAgLy8gR05VIGNhdCB1c2Ugc2l4IHBhZCBzdGFydCBudW1iZXIgKyB0YWIuIFNlZSBodHRwOi8vbGluZ3Jvay5vcmcveHJlZi9jb3JldXRpbHMvc3JjL2NhdC5jIzU3XG4gIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL1N0cmluZy9wYWRTdGFydFxuICB2YXIgbnVtYmVyID0gKCcgICAgICcgKyBuKS5zbGljZSgtNikgKyAnXFx0JztcbiAgcmV0dXJuIG51bWJlciArIGxpbmU7XG59XG4iLCJ2YXIgb3MgPSByZXF1aXJlKCdvcycpO1xudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG5cbmNvbW1vbi5yZWdpc3RlcignY2QnLCBfY2QsIHt9KTtcblxuLy9AXG4vL0AgIyMjIGNkKFtkaXJdKVxuLy9AXG4vL0AgQ2hhbmdlcyB0byBkaXJlY3RvcnkgYGRpcmAgZm9yIHRoZSBkdXJhdGlvbiBvZiB0aGUgc2NyaXB0LiBDaGFuZ2VzIHRvIGhvbWVcbi8vQCBkaXJlY3RvcnkgaWYgbm8gYXJndW1lbnQgaXMgc3VwcGxpZWQuXG5mdW5jdGlvbiBfY2Qob3B0aW9ucywgZGlyKSB7XG4gIGlmICghZGlyKSBkaXIgPSBvcy5ob21lZGlyKCk7XG5cbiAgaWYgKGRpciA9PT0gJy0nKSB7XG4gICAgaWYgKCFwcm9jZXNzLmVudi5PTERQV0QpIHtcbiAgICAgIGNvbW1vbi5lcnJvcignY291bGQgbm90IGZpbmQgcHJldmlvdXMgZGlyZWN0b3J5Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRpciA9IHByb2Nlc3MuZW52Lk9MRFBXRDtcbiAgICB9XG4gIH1cblxuICB0cnkge1xuICAgIHZhciBjdXJEaXIgPSBwcm9jZXNzLmN3ZCgpO1xuICAgIHByb2Nlc3MuY2hkaXIoZGlyKTtcbiAgICBwcm9jZXNzLmVudi5PTERQV0QgPSBjdXJEaXI7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBzb21ldGhpbmcgd2VudCB3cm9uZywgbGV0J3MgZmlndXJlIG91dCB0aGUgZXJyb3JcbiAgICB2YXIgZXJyO1xuICAgIHRyeSB7XG4gICAgICBjb21tb24uc3RhdEZvbGxvd0xpbmtzKGRpcik7IC8vIGlmIHRoaXMgc3VjY2VlZHMsIGl0IG11c3QgYmUgc29tZSBzb3J0IG9mIGZpbGVcbiAgICAgIGVyciA9ICdub3QgYSBkaXJlY3Rvcnk6ICcgKyBkaXI7XG4gICAgfSBjYXRjaCAoZTIpIHtcbiAgICAgIGVyciA9ICdubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5OiAnICsgZGlyO1xuICAgIH1cbiAgICBpZiAoZXJyKSBjb21tb24uZXJyb3IoZXJyKTtcbiAgfVxuICByZXR1cm4gJyc7XG59XG5tb2R1bGUuZXhwb3J0cyA9IF9jZDtcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcbnZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xuXG52YXIgUEVSTVMgPSAoZnVuY3Rpb24gKGJhc2UpIHtcbiAgcmV0dXJuIHtcbiAgICBPVEhFUl9FWEVDOiBiYXNlLkVYRUMsXG4gICAgT1RIRVJfV1JJVEU6IGJhc2UuV1JJVEUsXG4gICAgT1RIRVJfUkVBRDogYmFzZS5SRUFELFxuXG4gICAgR1JPVVBfRVhFQzogYmFzZS5FWEVDIDw8IDMsXG4gICAgR1JPVVBfV1JJVEU6IGJhc2UuV1JJVEUgPDwgMyxcbiAgICBHUk9VUF9SRUFEOiBiYXNlLlJFQUQgPDwgMyxcblxuICAgIE9XTkVSX0VYRUM6IGJhc2UuRVhFQyA8PCA2LFxuICAgIE9XTkVSX1dSSVRFOiBiYXNlLldSSVRFIDw8IDYsXG4gICAgT1dORVJfUkVBRDogYmFzZS5SRUFEIDw8IDYsXG5cbiAgICAvLyBMaXRlcmFsIG9jdGFsIG51bWJlcnMgYXJlIGFwcGFyZW50bHkgbm90IGFsbG93ZWQgaW4gXCJzdHJpY3RcIiBqYXZhc2NyaXB0LlxuICAgIFNUSUNLWTogcGFyc2VJbnQoJzAxMDAwJywgOCksXG4gICAgU0VUR0lEOiBwYXJzZUludCgnMDIwMDAnLCA4KSxcbiAgICBTRVRVSUQ6IHBhcnNlSW50KCcwNDAwMCcsIDgpLFxuXG4gICAgVFlQRV9NQVNLOiBwYXJzZUludCgnMDc3MDAwMCcsIDgpLFxuICB9O1xufSh7XG4gIEVYRUM6IDEsXG4gIFdSSVRFOiAyLFxuICBSRUFEOiA0LFxufSkpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ2NobW9kJywgX2NobW9kLCB7XG59KTtcblxuLy9AXG4vL0AgIyMjIGNobW9kKFtvcHRpb25zLF0gb2N0YWxfbW9kZSB8fCBvY3RhbF9zdHJpbmcsIGZpbGUpXG4vL0AgIyMjIGNobW9kKFtvcHRpb25zLF0gc3ltYm9saWNfbW9kZSwgZmlsZSlcbi8vQFxuLy9AIEF2YWlsYWJsZSBvcHRpb25zOlxuLy9AXG4vL0AgKyBgLXZgOiBvdXRwdXQgYSBkaWFnbm9zdGljIGZvciBldmVyeSBmaWxlIHByb2Nlc3NlZC8vQFxuLy9AICsgYC1jYDogbGlrZSB2ZXJib3NlLCBidXQgcmVwb3J0IG9ubHkgd2hlbiBhIGNoYW5nZSBpcyBtYWRlLy9AXG4vL0AgKyBgLVJgOiBjaGFuZ2UgZmlsZXMgYW5kIGRpcmVjdG9yaWVzIHJlY3Vyc2l2ZWx5Ly9AXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBjaG1vZCg3NTUsICcvVXNlcnMvYnJhbmRvbicpO1xuLy9AIGNobW9kKCc3NTUnLCAnL1VzZXJzL2JyYW5kb24nKTsgLy8gc2FtZSBhcyBhYm92ZVxuLy9AIGNobW9kKCd1K3gnLCAnL1VzZXJzL2JyYW5kb24nKTtcbi8vQCBjaG1vZCgnLVInLCAnYS13JywgJy9Vc2Vycy9icmFuZG9uJyk7XG4vL0AgYGBgXG4vL0Bcbi8vQCBBbHRlcnMgdGhlIHBlcm1pc3Npb25zIG9mIGEgZmlsZSBvciBkaXJlY3RvcnkgYnkgZWl0aGVyIHNwZWNpZnlpbmcgdGhlXG4vL0AgYWJzb2x1dGUgcGVybWlzc2lvbnMgaW4gb2N0YWwgZm9ybSBvciBleHByZXNzaW5nIHRoZSBjaGFuZ2VzIGluIHN5bWJvbHMuXG4vL0AgVGhpcyBjb21tYW5kIHRyaWVzIHRvIG1pbWljIHRoZSBQT1NJWCBiZWhhdmlvciBhcyBtdWNoIGFzIHBvc3NpYmxlLlxuLy9AIE5vdGFibGUgZXhjZXB0aW9uczpcbi8vQFxuLy9AICsgSW4gc3ltYm9saWMgbW9kZXMsIGBhLXJgIGFuZCBgLXJgIGFyZSBpZGVudGljYWwuICBObyBjb25zaWRlcmF0aW9uIGlzXG4vL0AgICBnaXZlbiB0byB0aGUgYHVtYXNrYC5cbi8vQCArIFRoZXJlIGlzIG5vIFwicXVpZXRcIiBvcHRpb24sIHNpbmNlIGRlZmF1bHQgYmVoYXZpb3IgaXMgdG8gcnVuIHNpbGVudC5cbmZ1bmN0aW9uIF9jaG1vZChvcHRpb25zLCBtb2RlLCBmaWxlUGF0dGVybikge1xuICBpZiAoIWZpbGVQYXR0ZXJuKSB7XG4gICAgaWYgKG9wdGlvbnMubGVuZ3RoID4gMCAmJiBvcHRpb25zLmNoYXJBdCgwKSA9PT0gJy0nKSB7XG4gICAgICAvLyBTcGVjaWFsIGNhc2Ugd2hlcmUgdGhlIHNwZWNpZmllZCBmaWxlIHBlcm1pc3Npb25zIHN0YXJ0ZWQgd2l0aCAtIHRvIHN1YnRyYWN0IHBlcm1zLCB3aGljaFxuICAgICAgLy8gZ2V0IHBpY2tlZCB1cCBieSB0aGUgb3B0aW9uIHBhcnNlciBhcyBjb21tYW5kIGZsYWdzLlxuICAgICAgLy8gSWYgd2UgYXJlIGRvd24gYnkgb25lIGFyZ3VtZW50IGFuZCBvcHRpb25zIHN0YXJ0cyB3aXRoIC0sIHNoaWZ0IGV2ZXJ5dGhpbmcgb3Zlci5cbiAgICAgIFtdLnVuc2hpZnQuY2FsbChhcmd1bWVudHMsICcnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29tbW9uLmVycm9yKCdZb3UgbXVzdCBzcGVjaWZ5IGEgZmlsZS4nKTtcbiAgICB9XG4gIH1cblxuICBvcHRpb25zID0gY29tbW9uLnBhcnNlT3B0aW9ucyhvcHRpb25zLCB7XG4gICAgJ1InOiAncmVjdXJzaXZlJyxcbiAgICAnYyc6ICdjaGFuZ2VzJyxcbiAgICAndic6ICd2ZXJib3NlJyxcbiAgfSk7XG5cbiAgZmlsZVBhdHRlcm4gPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMik7XG5cbiAgdmFyIGZpbGVzO1xuXG4gIC8vIFRPRE86IHJlcGxhY2UgdGhpcyB3aXRoIGEgY2FsbCB0byBjb21tb24uZXhwYW5kKClcbiAgaWYgKG9wdGlvbnMucmVjdXJzaXZlKSB7XG4gICAgZmlsZXMgPSBbXTtcbiAgICBmaWxlUGF0dGVybi5mb3JFYWNoKGZ1bmN0aW9uIGFkZEZpbGUoZXhwYW5kZWRGaWxlKSB7XG4gICAgICB2YXIgc3RhdCA9IGNvbW1vbi5zdGF0Tm9Gb2xsb3dMaW5rcyhleHBhbmRlZEZpbGUpO1xuXG4gICAgICBpZiAoIXN0YXQuaXNTeW1ib2xpY0xpbmsoKSkge1xuICAgICAgICBmaWxlcy5wdXNoKGV4cGFuZGVkRmlsZSk7XG5cbiAgICAgICAgaWYgKHN0YXQuaXNEaXJlY3RvcnkoKSkgeyAgLy8gaW50ZW50aW9uYWxseSBkb2VzIG5vdCBmb2xsb3cgc3ltbGlua3MuXG4gICAgICAgICAgZnMucmVhZGRpclN5bmMoZXhwYW5kZWRGaWxlKS5mb3JFYWNoKGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICAgICAgYWRkRmlsZShleHBhbmRlZEZpbGUgKyAnLycgKyBjaGlsZCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBmaWxlcyA9IGZpbGVQYXR0ZXJuO1xuICB9XG5cbiAgZmlsZXMuZm9yRWFjaChmdW5jdGlvbiBpbm5lckNobW9kKGZpbGUpIHtcbiAgICBmaWxlID0gcGF0aC5yZXNvbHZlKGZpbGUpO1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhmaWxlKSkge1xuICAgICAgY29tbW9uLmVycm9yKCdGaWxlIG5vdCBmb3VuZDogJyArIGZpbGUpO1xuICAgIH1cblxuICAgIC8vIFdoZW4gcmVjdXJzaW5nLCBkb24ndCBmb2xsb3cgc3ltbGlua3MuXG4gICAgaWYgKG9wdGlvbnMucmVjdXJzaXZlICYmIGNvbW1vbi5zdGF0Tm9Gb2xsb3dMaW5rcyhmaWxlKS5pc1N5bWJvbGljTGluaygpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHN0YXQgPSBjb21tb24uc3RhdEZvbGxvd0xpbmtzKGZpbGUpO1xuICAgIHZhciBpc0RpciA9IHN0YXQuaXNEaXJlY3RvcnkoKTtcbiAgICB2YXIgcGVybXMgPSBzdGF0Lm1vZGU7XG4gICAgdmFyIHR5cGUgPSBwZXJtcyAmIFBFUk1TLlRZUEVfTUFTSztcblxuICAgIHZhciBuZXdQZXJtcyA9IHBlcm1zO1xuXG4gICAgaWYgKGlzTmFOKHBhcnNlSW50KG1vZGUsIDgpKSkge1xuICAgICAgLy8gcGFyc2Ugb3B0aW9uc1xuICAgICAgbW9kZS5zcGxpdCgnLCcpLmZvckVhY2goZnVuY3Rpb24gKHN5bWJvbGljTW9kZSkge1xuICAgICAgICB2YXIgcGF0dGVybiA9IC8oW3Vnb2FdKikoWz1cXCstXSkoW3J3eFhzdF0qKS9pO1xuICAgICAgICB2YXIgbWF0Y2hlcyA9IHBhdHRlcm4uZXhlYyhzeW1ib2xpY01vZGUpO1xuXG4gICAgICAgIGlmIChtYXRjaGVzKSB7XG4gICAgICAgICAgdmFyIGFwcGx5VG8gPSBtYXRjaGVzWzFdO1xuICAgICAgICAgIHZhciBvcGVyYXRvciA9IG1hdGNoZXNbMl07XG4gICAgICAgICAgdmFyIGNoYW5nZSA9IG1hdGNoZXNbM107XG5cbiAgICAgICAgICB2YXIgY2hhbmdlT3duZXIgPSBhcHBseVRvLmluZGV4T2YoJ3UnKSAhPT0gLTEgfHwgYXBwbHlUbyA9PT0gJ2EnIHx8IGFwcGx5VG8gPT09ICcnO1xuICAgICAgICAgIHZhciBjaGFuZ2VHcm91cCA9IGFwcGx5VG8uaW5kZXhPZignZycpICE9PSAtMSB8fCBhcHBseVRvID09PSAnYScgfHwgYXBwbHlUbyA9PT0gJyc7XG4gICAgICAgICAgdmFyIGNoYW5nZU90aGVyID0gYXBwbHlUby5pbmRleE9mKCdvJykgIT09IC0xIHx8IGFwcGx5VG8gPT09ICdhJyB8fCBhcHBseVRvID09PSAnJztcblxuICAgICAgICAgIHZhciBjaGFuZ2VSZWFkID0gY2hhbmdlLmluZGV4T2YoJ3InKSAhPT0gLTE7XG4gICAgICAgICAgdmFyIGNoYW5nZVdyaXRlID0gY2hhbmdlLmluZGV4T2YoJ3cnKSAhPT0gLTE7XG4gICAgICAgICAgdmFyIGNoYW5nZUV4ZWMgPSBjaGFuZ2UuaW5kZXhPZigneCcpICE9PSAtMTtcbiAgICAgICAgICB2YXIgY2hhbmdlRXhlY0RpciA9IGNoYW5nZS5pbmRleE9mKCdYJykgIT09IC0xO1xuICAgICAgICAgIHZhciBjaGFuZ2VTdGlja3kgPSBjaGFuZ2UuaW5kZXhPZigndCcpICE9PSAtMTtcbiAgICAgICAgICB2YXIgY2hhbmdlU2V0dWlkID0gY2hhbmdlLmluZGV4T2YoJ3MnKSAhPT0gLTE7XG5cbiAgICAgICAgICBpZiAoY2hhbmdlRXhlY0RpciAmJiBpc0Rpcikge1xuICAgICAgICAgICAgY2hhbmdlRXhlYyA9IHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdmFyIG1hc2sgPSAwO1xuICAgICAgICAgIGlmIChjaGFuZ2VPd25lcikge1xuICAgICAgICAgICAgbWFzayB8PSAoY2hhbmdlUmVhZCA/IFBFUk1TLk9XTkVSX1JFQUQgOiAwKSArIChjaGFuZ2VXcml0ZSA/IFBFUk1TLk9XTkVSX1dSSVRFIDogMCkgKyAoY2hhbmdlRXhlYyA/IFBFUk1TLk9XTkVSX0VYRUMgOiAwKSArIChjaGFuZ2VTZXR1aWQgPyBQRVJNUy5TRVRVSUQgOiAwKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGNoYW5nZUdyb3VwKSB7XG4gICAgICAgICAgICBtYXNrIHw9IChjaGFuZ2VSZWFkID8gUEVSTVMuR1JPVVBfUkVBRCA6IDApICsgKGNoYW5nZVdyaXRlID8gUEVSTVMuR1JPVVBfV1JJVEUgOiAwKSArIChjaGFuZ2VFeGVjID8gUEVSTVMuR1JPVVBfRVhFQyA6IDApICsgKGNoYW5nZVNldHVpZCA/IFBFUk1TLlNFVEdJRCA6IDApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY2hhbmdlT3RoZXIpIHtcbiAgICAgICAgICAgIG1hc2sgfD0gKGNoYW5nZVJlYWQgPyBQRVJNUy5PVEhFUl9SRUFEIDogMCkgKyAoY2hhbmdlV3JpdGUgPyBQRVJNUy5PVEhFUl9XUklURSA6IDApICsgKGNoYW5nZUV4ZWMgPyBQRVJNUy5PVEhFUl9FWEVDIDogMCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gU3RpY2t5IGJpdCBpcyBzcGVjaWFsIC0gaXQncyBub3QgdGllZCB0byB1c2VyLCBncm91cCBvciBvdGhlci5cbiAgICAgICAgICBpZiAoY2hhbmdlU3RpY2t5KSB7XG4gICAgICAgICAgICBtYXNrIHw9IFBFUk1TLlNUSUNLWTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzd2l0Y2ggKG9wZXJhdG9yKSB7XG4gICAgICAgICAgICBjYXNlICcrJzpcbiAgICAgICAgICAgICAgbmV3UGVybXMgfD0gbWFzaztcbiAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgJy0nOlxuICAgICAgICAgICAgICBuZXdQZXJtcyAmPSB+bWFzaztcbiAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgJz0nOlxuICAgICAgICAgICAgICBuZXdQZXJtcyA9IHR5cGUgKyBtYXNrO1xuXG4gICAgICAgICAgICAgIC8vIEFjY29yZGluZyB0byBQT1NJWCwgd2hlbiB1c2luZyA9IHRvIGV4cGxpY2l0bHkgc2V0IHRoZVxuICAgICAgICAgICAgICAvLyBwZXJtaXNzaW9ucywgc2V0dWlkIGFuZCBzZXRnaWQgY2FuIG5ldmVyIGJlIGNsZWFyZWQuXG4gICAgICAgICAgICAgIGlmIChjb21tb24uc3RhdEZvbGxvd0xpbmtzKGZpbGUpLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgICAgICAgICBuZXdQZXJtcyB8PSAoUEVSTVMuU0VUVUlEICsgUEVSTVMuU0VUR0lEKSAmIHBlcm1zO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgY29tbW9uLmVycm9yKCdDb3VsZCBub3QgcmVjb2duaXplIG9wZXJhdG9yOiBgJyArIG9wZXJhdG9yICsgJ2AnKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAob3B0aW9ucy52ZXJib3NlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhmaWxlICsgJyAtPiAnICsgbmV3UGVybXMudG9TdHJpbmcoOCkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChwZXJtcyAhPT0gbmV3UGVybXMpIHtcbiAgICAgICAgICAgIGlmICghb3B0aW9ucy52ZXJib3NlICYmIG9wdGlvbnMuY2hhbmdlcykge1xuICAgICAgICAgICAgICBjb25zb2xlLmxvZyhmaWxlICsgJyAtPiAnICsgbmV3UGVybXMudG9TdHJpbmcoOCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZnMuY2htb2RTeW5jKGZpbGUsIG5ld1Blcm1zKTtcbiAgICAgICAgICAgIHBlcm1zID0gbmV3UGVybXM7IC8vIGZvciB0aGUgbmV4dCByb3VuZCBvZiBjaGFuZ2VzIVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb21tb24uZXJyb3IoJ0ludmFsaWQgc3ltYm9saWMgbW9kZSBjaGFuZ2U6ICcgKyBzeW1ib2xpY01vZGUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gdGhleSBnYXZlIHVzIGEgZnVsbCBudW1iZXJcbiAgICAgIG5ld1Blcm1zID0gdHlwZSArIHBhcnNlSW50KG1vZGUsIDgpO1xuXG4gICAgICAvLyBQT1NJWCBydWxlcyBhcmUgdGhhdCBzZXR1aWQgYW5kIHNldGdpZCBjYW4gb25seSBiZSBhZGRlZCB1c2luZyBudW1lcmljXG4gICAgICAvLyBmb3JtLCBidXQgbm90IGNsZWFyZWQuXG4gICAgICBpZiAoY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhmaWxlKS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgIG5ld1Blcm1zIHw9IChQRVJNUy5TRVRVSUQgKyBQRVJNUy5TRVRHSUQpICYgcGVybXM7XG4gICAgICB9XG5cbiAgICAgIGZzLmNobW9kU3luYyhmaWxlLCBuZXdQZXJtcyk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuICcnO1xufVxubW9kdWxlLmV4cG9ydHMgPSBfY2htb2Q7XG4iLCIvLyBJZ25vcmUgd2FybmluZyBhYm91dCAnbmV3IFN0cmluZygpJ1xuLyogZXNsaW50IG5vLW5ldy13cmFwcGVyczogMCAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgb3MgPSByZXF1aXJlKCdvcycpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcbnZhciBnbG9iID0gcmVxdWlyZSgnZ2xvYicpO1xudmFyIHNoZWxsID0gcmVxdWlyZSgnLi4nKTtcblxudmFyIHNoZWxsTWV0aG9kcyA9IE9iamVjdC5jcmVhdGUoc2hlbGwpO1xuXG5leHBvcnRzLmV4dGVuZCA9IE9iamVjdC5hc3NpZ247XG5cbi8vIENoZWNrIGlmIHdlJ3JlIHJ1bm5pbmcgdW5kZXIgZWxlY3Ryb25cbnZhciBpc0VsZWN0cm9uID0gQm9vbGVhbihwcm9jZXNzLnZlcnNpb25zLmVsZWN0cm9uKTtcblxuLy8gTW9kdWxlIGdsb2JhbHMgKGFzc3VtZSBubyBleGVjUGF0aCBieSBkZWZhdWx0KVxudmFyIERFRkFVTFRfQ09ORklHID0ge1xuICBmYXRhbDogZmFsc2UsXG4gIGdsb2JPcHRpb25zOiB7fSxcbiAgbWF4ZGVwdGg6IDI1NSxcbiAgbm9nbG9iOiBmYWxzZSxcbiAgc2lsZW50OiBmYWxzZSxcbiAgdmVyYm9zZTogZmFsc2UsXG4gIGV4ZWNQYXRoOiBudWxsLFxuICBidWZMZW5ndGg6IDY0ICogMTAyNCwgLy8gNjRLQlxufTtcblxudmFyIGNvbmZpZyA9IHtcbiAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICBPYmplY3QuYXNzaWduKHRoaXMsIERFRkFVTFRfQ09ORklHKTtcbiAgICBpZiAoIWlzRWxlY3Ryb24pIHtcbiAgICAgIHRoaXMuZXhlY1BhdGggPSBwcm9jZXNzLmV4ZWNQYXRoO1xuICAgIH1cbiAgfSxcbiAgcmVzZXRGb3JUZXN0aW5nOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5yZXNldCgpO1xuICAgIHRoaXMuc2lsZW50ID0gdHJ1ZTtcbiAgfSxcbn07XG5cbmNvbmZpZy5yZXNldCgpO1xuZXhwb3J0cy5jb25maWcgPSBjb25maWc7XG5cbi8vIE5vdGU6IGNvbW1hbmRzIHNob3VsZCBnZW5lcmFsbHkgY29uc2lkZXIgdGhlc2UgYXMgcmVhZC1vbmx5IHZhbHVlcy5cbnZhciBzdGF0ZSA9IHtcbiAgZXJyb3I6IG51bGwsXG4gIGVycm9yQ29kZTogMCxcbiAgY3VycmVudENtZDogJ3NoZWxsLmpzJyxcbn07XG5leHBvcnRzLnN0YXRlID0gc3RhdGU7XG5cbmRlbGV0ZSBwcm9jZXNzLmVudi5PTERQV0Q7IC8vIGluaXRpYWxseSwgdGhlcmUncyBubyBwcmV2aW91cyBkaXJlY3RvcnlcblxuLy8gUmVsaWFibHkgdGVzdCBpZiBzb21ldGhpbmcgaXMgYW55IHNvcnQgb2YgamF2YXNjcmlwdCBvYmplY3RcbmZ1bmN0aW9uIGlzT2JqZWN0KGEpIHtcbiAgcmV0dXJuIHR5cGVvZiBhID09PSAnb2JqZWN0JyAmJiBhICE9PSBudWxsO1xufVxuZXhwb3J0cy5pc09iamVjdCA9IGlzT2JqZWN0O1xuXG5mdW5jdGlvbiBsb2coKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIGlmICghY29uZmlnLnNpbGVudCkge1xuICAgIGNvbnNvbGUuZXJyb3IuYXBwbHkoY29uc29sZSwgYXJndW1lbnRzKTtcbiAgfVxufVxuZXhwb3J0cy5sb2cgPSBsb2c7XG5cbi8vIENvbnZlcnRzIHN0cmluZ3MgdG8gYmUgZXF1aXZhbGVudCBhY3Jvc3MgYWxsIHBsYXRmb3Jtcy4gUHJpbWFyaWx5IHJlc3BvbnNpYmxlXG4vLyBmb3IgbWFraW5nIHN1cmUgd2UgdXNlICcvJyBpbnN0ZWFkIG9mICdcXCcgYXMgcGF0aCBzZXBhcmF0b3JzLCBidXQgdGhpcyBtYXkgYmVcbi8vIGV4cGFuZGVkIGluIHRoZSBmdXR1cmUgaWYgbmVjZXNzYXJ5XG5mdW5jdGlvbiBjb252ZXJ0RXJyb3JPdXRwdXQobXNnKSB7XG4gIGlmICh0eXBlb2YgbXNnICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2lucHV0IG11c3QgYmUgYSBzdHJpbmcnKTtcbiAgfVxuICByZXR1cm4gbXNnLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcbn1cbmV4cG9ydHMuY29udmVydEVycm9yT3V0cHV0ID0gY29udmVydEVycm9yT3V0cHV0O1xuXG4vLyBTaG93cyBlcnJvciBtZXNzYWdlLiBUaHJvd3MgaWYgY29uZmlnLmZhdGFsIGlzIHRydWVcbmZ1bmN0aW9uIGVycm9yKG1zZywgX2NvZGUsIG9wdGlvbnMpIHtcbiAgLy8gVmFsaWRhdGUgaW5wdXRcbiAgaWYgKHR5cGVvZiBtc2cgIT09ICdzdHJpbmcnKSB0aHJvdyBuZXcgRXJyb3IoJ21zZyBtdXN0IGJlIGEgc3RyaW5nJyk7XG5cbiAgdmFyIERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjb250aW51ZTogZmFsc2UsXG4gICAgY29kZTogMSxcbiAgICBwcmVmaXg6IHN0YXRlLmN1cnJlbnRDbWQgKyAnOiAnLFxuICAgIHNpbGVudDogZmFsc2UsXG4gIH07XG5cbiAgaWYgKHR5cGVvZiBfY29kZSA9PT0gJ251bWJlcicgJiYgaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICBvcHRpb25zLmNvZGUgPSBfY29kZTtcbiAgfSBlbHNlIGlmIChpc09iamVjdChfY29kZSkpIHsgLy8gbm8gJ2NvZGUnXG4gICAgb3B0aW9ucyA9IF9jb2RlO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBfY29kZSA9PT0gJ251bWJlcicpIHsgLy8gbm8gJ29wdGlvbnMnXG4gICAgb3B0aW9ucyA9IHsgY29kZTogX2NvZGUgfTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgX2NvZGUgIT09ICdudW1iZXInKSB7IC8vIG9ubHkgJ21zZydcbiAgICBvcHRpb25zID0ge307XG4gIH1cbiAgb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oe30sIERFRkFVTFRfT1BUSU9OUywgb3B0aW9ucyk7XG5cbiAgaWYgKCFzdGF0ZS5lcnJvckNvZGUpIHN0YXRlLmVycm9yQ29kZSA9IG9wdGlvbnMuY29kZTtcblxuICB2YXIgbG9nRW50cnkgPSBjb252ZXJ0RXJyb3JPdXRwdXQob3B0aW9ucy5wcmVmaXggKyBtc2cpO1xuICBzdGF0ZS5lcnJvciA9IHN0YXRlLmVycm9yID8gc3RhdGUuZXJyb3IgKyAnXFxuJyA6ICcnO1xuICBzdGF0ZS5lcnJvciArPSBsb2dFbnRyeTtcblxuICAvLyBUaHJvdyBhbiBlcnJvciwgb3IgbG9nIHRoZSBlbnRyeVxuICBpZiAoY29uZmlnLmZhdGFsKSB0aHJvdyBuZXcgRXJyb3IobG9nRW50cnkpO1xuICBpZiAobXNnLmxlbmd0aCA+IDAgJiYgIW9wdGlvbnMuc2lsZW50KSBsb2cobG9nRW50cnkpO1xuXG4gIGlmICghb3B0aW9ucy5jb250aW51ZSkge1xuICAgIHRocm93IHtcbiAgICAgIG1zZzogJ2Vhcmx5RXhpdCcsXG4gICAgICByZXRWYWx1ZTogKG5ldyBTaGVsbFN0cmluZygnJywgc3RhdGUuZXJyb3IsIHN0YXRlLmVycm9yQ29kZSkpLFxuICAgIH07XG4gIH1cbn1cbmV4cG9ydHMuZXJyb3IgPSBlcnJvcjtcblxuLy9AXG4vL0AgIyMjIFNoZWxsU3RyaW5nKHN0cilcbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIHZhciBmb28gPSBTaGVsbFN0cmluZygnaGVsbG8gd29ybGQnKTtcbi8vQCBgYGBcbi8vQFxuLy9AIFR1cm5zIGEgcmVndWxhciBzdHJpbmcgaW50byBhIHN0cmluZy1saWtlIG9iamVjdCBzaW1pbGFyIHRvIHdoYXQgZWFjaFxuLy9AIGNvbW1hbmQgcmV0dXJucy4gVGhpcyBoYXMgc3BlY2lhbCBtZXRob2RzLCBsaWtlIGAudG8oKWAgYW5kIGAudG9FbmQoKWAuXG5mdW5jdGlvbiBTaGVsbFN0cmluZyhzdGRvdXQsIHN0ZGVyciwgY29kZSkge1xuICB2YXIgdGhhdDtcbiAgaWYgKHN0ZG91dCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgdGhhdCA9IHN0ZG91dDtcbiAgICB0aGF0LnN0ZG91dCA9IHN0ZG91dC5qb2luKCdcXG4nKTtcbiAgICBpZiAoc3Rkb3V0Lmxlbmd0aCA+IDApIHRoYXQuc3Rkb3V0ICs9ICdcXG4nO1xuICB9IGVsc2Uge1xuICAgIHRoYXQgPSBuZXcgU3RyaW5nKHN0ZG91dCk7XG4gICAgdGhhdC5zdGRvdXQgPSBzdGRvdXQ7XG4gIH1cbiAgdGhhdC5zdGRlcnIgPSBzdGRlcnI7XG4gIHRoYXQuY29kZSA9IGNvZGU7XG4gIC8vIEEgbGlzdCBvZiBhbGwgY29tbWFuZHMgdGhhdCBjYW4gYXBwZWFyIG9uIHRoZSByaWdodC1oYW5kIHNpZGUgb2YgYSBwaXBlXG4gIC8vIChwb3B1bGF0ZWQgYnkgY2FsbHMgdG8gY29tbW9uLndyYXAoKSlcbiAgcGlwZU1ldGhvZHMuZm9yRWFjaChmdW5jdGlvbiAoY21kKSB7XG4gICAgdGhhdFtjbWRdID0gc2hlbGxNZXRob2RzW2NtZF0uYmluZCh0aGF0KTtcbiAgfSk7XG4gIHJldHVybiB0aGF0O1xufVxuXG5leHBvcnRzLlNoZWxsU3RyaW5nID0gU2hlbGxTdHJpbmc7XG5cbi8vIFJldHVybnMgeydhbGljZSc6IHRydWUsICdib2InOiBmYWxzZX0gd2hlbiBwYXNzZWQgYSBzdHJpbmcgYW5kIGRpY3Rpb25hcnkgYXMgZm9sbG93czpcbi8vICAgcGFyc2VPcHRpb25zKCctYScsIHsnYSc6J2FsaWNlJywgJ2InOidib2InfSk7XG4vLyBSZXR1cm5zIHsncmVmZXJlbmNlJzogJ3N0cmluZy12YWx1ZScsICdib2InOiBmYWxzZX0gd2hlbiBwYXNzZWQgdHdvIGRpY3Rpb25hcmllcyBvZiB0aGUgZm9ybTpcbi8vICAgcGFyc2VPcHRpb25zKHsnLXInOiAnc3RyaW5nLXZhbHVlJ30sIHsncic6J3JlZmVyZW5jZScsICdiJzonYm9iJ30pO1xuLy8gVGhyb3dzIGFuIGVycm9yIHdoZW4gcGFzc2VkIGEgc3RyaW5nIHRoYXQgZG9lcyBub3Qgc3RhcnQgd2l0aCAnLSc6XG4vLyAgIHBhcnNlT3B0aW9ucygnYScsIHsnYSc6J2FsaWNlJ30pOyAvLyB0aHJvd3NcbmZ1bmN0aW9uIHBhcnNlT3B0aW9ucyhvcHQsIG1hcCwgZXJyb3JPcHRpb25zKSB7XG4gIC8vIFZhbGlkYXRlIGlucHV0XG4gIGlmICh0eXBlb2Ygb3B0ICE9PSAnc3RyaW5nJyAmJiAhaXNPYmplY3Qob3B0KSkge1xuICAgIHRocm93IG5ldyBFcnJvcignb3B0aW9ucyBtdXN0IGJlIHN0cmluZ3Mgb3Iga2V5LXZhbHVlIHBhaXJzJyk7XG4gIH0gZWxzZSBpZiAoIWlzT2JqZWN0KG1hcCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3BhcnNlT3B0aW9ucygpIGludGVybmFsIGVycm9yOiBtYXAgbXVzdCBiZSBhbiBvYmplY3QnKTtcbiAgfSBlbHNlIGlmIChlcnJvck9wdGlvbnMgJiYgIWlzT2JqZWN0KGVycm9yT3B0aW9ucykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3BhcnNlT3B0aW9ucygpIGludGVybmFsIGVycm9yOiBlcnJvck9wdGlvbnMgbXVzdCBiZSBvYmplY3QnKTtcbiAgfVxuXG4gIGlmIChvcHQgPT09ICctLScpIHtcbiAgICAvLyBUaGlzIG1lYW5zIHRoZXJlIGFyZSBubyBvcHRpb25zLlxuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIC8vIEFsbCBvcHRpb25zIGFyZSBmYWxzZSBieSBkZWZhdWx0XG4gIHZhciBvcHRpb25zID0ge307XG4gIE9iamVjdC5rZXlzKG1hcCkuZm9yRWFjaChmdW5jdGlvbiAobGV0dGVyKSB7XG4gICAgdmFyIG9wdE5hbWUgPSBtYXBbbGV0dGVyXTtcbiAgICBpZiAob3B0TmFtZVswXSAhPT0gJyEnKSB7XG4gICAgICBvcHRpb25zW29wdE5hbWVdID0gZmFsc2U7XG4gICAgfVxuICB9KTtcblxuICBpZiAob3B0ID09PSAnJykgcmV0dXJuIG9wdGlvbnM7IC8vIGRlZmF1bHRzXG5cbiAgaWYgKHR5cGVvZiBvcHQgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKG9wdFswXSAhPT0gJy0nKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJPcHRpb25zIHN0cmluZyBtdXN0IHN0YXJ0IHdpdGggYSAnLSdcIik7XG4gICAgfVxuXG4gICAgLy8gZS5nLiBjaGFycyA9IFsnUicsICdmJ11cbiAgICB2YXIgY2hhcnMgPSBvcHQuc2xpY2UoMSkuc3BsaXQoJycpO1xuXG4gICAgY2hhcnMuZm9yRWFjaChmdW5jdGlvbiAoYykge1xuICAgICAgaWYgKGMgaW4gbWFwKSB7XG4gICAgICAgIHZhciBvcHRpb25OYW1lID0gbWFwW2NdO1xuICAgICAgICBpZiAob3B0aW9uTmFtZVswXSA9PT0gJyEnKSB7XG4gICAgICAgICAgb3B0aW9uc1tvcHRpb25OYW1lLnNsaWNlKDEpXSA9IGZhbHNlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9wdGlvbnNbb3B0aW9uTmFtZV0gPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlcnJvcignb3B0aW9uIG5vdCByZWNvZ25pemVkOiAnICsgYywgZXJyb3JPcHRpb25zIHx8IHt9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSBlbHNlIHsgLy8gb3B0IGlzIGFuIE9iamVjdFxuICAgIE9iamVjdC5rZXlzKG9wdCkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAvLyBrZXkgaXMgYSBzdHJpbmcgb2YgdGhlIGZvcm0gJy1yJywgJy1kJywgZXRjLlxuICAgICAgdmFyIGMgPSBrZXlbMV07XG4gICAgICBpZiAoYyBpbiBtYXApIHtcbiAgICAgICAgdmFyIG9wdGlvbk5hbWUgPSBtYXBbY107XG4gICAgICAgIG9wdGlvbnNbb3B0aW9uTmFtZV0gPSBvcHRba2V5XTsgLy8gYXNzaWduIHRoZSBnaXZlbiB2YWx1ZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXJyb3IoJ29wdGlvbiBub3QgcmVjb2duaXplZDogJyArIGMsIGVycm9yT3B0aW9ucyB8fCB7fSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIG9wdGlvbnM7XG59XG5leHBvcnRzLnBhcnNlT3B0aW9ucyA9IHBhcnNlT3B0aW9ucztcblxuLy8gRXhwYW5kcyB3aWxkY2FyZHMgd2l0aCBtYXRjaGluZyAoaWUuIGV4aXN0aW5nKSBmaWxlIG5hbWVzLlxuLy8gRm9yIGV4YW1wbGU6XG4vLyAgIGV4cGFuZChbJ2ZpbGUqLmpzJ10pID0gWydmaWxlMS5qcycsICdmaWxlMi5qcycsIC4uLl1cbi8vICAgKGlmIHRoZSBmaWxlcyAnZmlsZTEuanMnLCAnZmlsZTIuanMnLCBldGMsIGV4aXN0IGluIHRoZSBjdXJyZW50IGRpcilcbmZ1bmN0aW9uIGV4cGFuZChsaXN0KSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShsaXN0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ211c3QgYmUgYW4gYXJyYXknKTtcbiAgfVxuICB2YXIgZXhwYW5kZWQgPSBbXTtcbiAgbGlzdC5mb3JFYWNoKGZ1bmN0aW9uIChsaXN0RWwpIHtcbiAgICAvLyBEb24ndCBleHBhbmQgbm9uLXN0cmluZ3NcbiAgICBpZiAodHlwZW9mIGxpc3RFbCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIGV4cGFuZGVkLnB1c2gobGlzdEVsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHJldDtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldCA9IGdsb2Iuc3luYyhsaXN0RWwsIGNvbmZpZy5nbG9iT3B0aW9ucyk7XG4gICAgICAgIC8vIGlmIG5vdGhpbmcgbWF0Y2hlZCwgaW50ZXJwcmV0IHRoZSBzdHJpbmcgbGl0ZXJhbGx5XG4gICAgICAgIHJldCA9IHJldC5sZW5ndGggPiAwID8gcmV0IDogW2xpc3RFbF07XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIGlmIGdsb2IgZmFpbHMsIGludGVycHJldCB0aGUgc3RyaW5nIGxpdGVyYWxseVxuICAgICAgICByZXQgPSBbbGlzdEVsXTtcbiAgICAgIH1cbiAgICAgIGV4cGFuZGVkID0gZXhwYW5kZWQuY29uY2F0KHJldCk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIGV4cGFuZGVkO1xufVxuZXhwb3J0cy5leHBhbmQgPSBleHBhbmQ7XG5cbi8vIE5vcm1hbGl6ZXMgQnVmZmVyIGNyZWF0aW9uLCB1c2luZyBCdWZmZXIuYWxsb2MgaWYgcG9zc2libGUuXG4vLyBBbHNvIHByb3ZpZGVzIGEgZ29vZCBkZWZhdWx0IGJ1ZmZlciBsZW5ndGggZm9yIG1vc3QgdXNlIGNhc2VzLlxudmFyIGJ1ZmZlciA9IHR5cGVvZiBCdWZmZXIuYWxsb2MgPT09ICdmdW5jdGlvbicgP1xuICBmdW5jdGlvbiAobGVuKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5hbGxvYyhsZW4gfHwgY29uZmlnLmJ1Zkxlbmd0aCk7XG4gIH0gOlxuICBmdW5jdGlvbiAobGVuKSB7XG4gICAgcmV0dXJuIG5ldyBCdWZmZXIobGVuIHx8IGNvbmZpZy5idWZMZW5ndGgpO1xuICB9O1xuZXhwb3J0cy5idWZmZXIgPSBidWZmZXI7XG5cbi8vIE5vcm1hbGl6ZXMgX3VubGlua1N5bmMoKSBhY3Jvc3MgcGxhdGZvcm1zIHRvIG1hdGNoIFVuaXggYmVoYXZpb3IsIGkuZS5cbi8vIGZpbGUgY2FuIGJlIHVubGlua2VkIGV2ZW4gaWYgaXQncyByZWFkLW9ubHksIHNlZSBodHRwczovL2dpdGh1Yi5jb20vam95ZW50L25vZGUvaXNzdWVzLzMwMDZcbmZ1bmN0aW9uIHVubGlua1N5bmMoZmlsZSkge1xuICB0cnkge1xuICAgIGZzLnVubGlua1N5bmMoZmlsZSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBUcnkgdG8gb3ZlcnJpZGUgZmlsZSBwZXJtaXNzaW9uXG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBpZiAoZS5jb2RlID09PSAnRVBFUk0nKSB7XG4gICAgICBmcy5jaG1vZFN5bmMoZmlsZSwgJzA2NjYnKTtcbiAgICAgIGZzLnVubGlua1N5bmMoZmlsZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG59XG5leHBvcnRzLnVubGlua1N5bmMgPSB1bmxpbmtTeW5jO1xuXG4vLyB3cmFwcGVycyBhcm91bmQgY29tbW9uLnN0YXRGb2xsb3dMaW5rcyBhbmQgY29tbW9uLnN0YXROb0ZvbGxvd0xpbmtzIHRoYXQgY2xhcmlmeSBpbnRlbnRcbi8vIGFuZCBpbXByb3ZlIHJlYWRhYmlsaXR5XG5mdW5jdGlvbiBzdGF0Rm9sbG93TGlua3MoKSB7XG4gIHJldHVybiBmcy5zdGF0U3luYy5hcHBseShmcywgYXJndW1lbnRzKTtcbn1cbmV4cG9ydHMuc3RhdEZvbGxvd0xpbmtzID0gc3RhdEZvbGxvd0xpbmtzO1xuXG5mdW5jdGlvbiBzdGF0Tm9Gb2xsb3dMaW5rcygpIHtcbiAgcmV0dXJuIGZzLmxzdGF0U3luYy5hcHBseShmcywgYXJndW1lbnRzKTtcbn1cbmV4cG9ydHMuc3RhdE5vRm9sbG93TGlua3MgPSBzdGF0Tm9Gb2xsb3dMaW5rcztcblxuLy8gZS5nLiAnc2hlbGxqc19hNWYxODVkMDQ0M2NhLi4uJ1xuZnVuY3Rpb24gcmFuZG9tRmlsZU5hbWUoKSB7XG4gIGZ1bmN0aW9uIHJhbmRvbUhhc2goY291bnQpIHtcbiAgICBpZiAoY291bnQgPT09IDEpIHtcbiAgICAgIHJldHVybiBwYXJzZUludCgxNiAqIE1hdGgucmFuZG9tKCksIDEwKS50b1N0cmluZygxNik7XG4gICAgfVxuICAgIHZhciBoYXNoID0gJyc7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICBoYXNoICs9IHJhbmRvbUhhc2goMSk7XG4gICAgfVxuICAgIHJldHVybiBoYXNoO1xuICB9XG5cbiAgcmV0dXJuICdzaGVsbGpzXycgKyByYW5kb21IYXNoKDIwKTtcbn1cbmV4cG9ydHMucmFuZG9tRmlsZU5hbWUgPSByYW5kb21GaWxlTmFtZTtcblxuLy8gQ29tbW9uIHdyYXBwZXIgZm9yIGFsbCBVbml4LWxpa2UgY29tbWFuZHMgdGhhdCBwZXJmb3JtcyBnbG9iIGV4cGFuc2lvbixcbi8vIGNvbW1hbmQtbG9nZ2luZywgYW5kIG90aGVyIG5pY2UgdGhpbmdzXG5mdW5jdGlvbiB3cmFwKGNtZCwgZm4sIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHJldFZhbHVlID0gbnVsbDtcblxuICAgIHN0YXRlLmN1cnJlbnRDbWQgPSBjbWQ7XG4gICAgc3RhdGUuZXJyb3IgPSBudWxsO1xuICAgIHN0YXRlLmVycm9yQ29kZSA9IDA7XG5cbiAgICB0cnkge1xuICAgICAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCk7XG5cbiAgICAgIC8vIExvZyB0aGUgY29tbWFuZCB0byBzdGRlcnIsIGlmIGFwcHJvcHJpYXRlXG4gICAgICBpZiAoY29uZmlnLnZlcmJvc2UpIHtcbiAgICAgICAgY29uc29sZS5lcnJvci5hcHBseShjb25zb2xlLCBbY21kXS5jb25jYXQoYXJncykpO1xuICAgICAgfVxuXG4gICAgICAvLyBJZiB0aGlzIGlzIGNvbWluZyBmcm9tIGEgcGlwZSwgbGV0J3Mgc2V0IHRoZSBwaXBlZFZhbHVlIChvdGhlcndpc2UsIHNldFxuICAgICAgLy8gaXQgdG8gdGhlIGVtcHR5IHN0cmluZylcbiAgICAgIHN0YXRlLnBpcGVkVmFsdWUgPSAodGhpcyAmJiB0eXBlb2YgdGhpcy5zdGRvdXQgPT09ICdzdHJpbmcnKSA/IHRoaXMuc3Rkb3V0IDogJyc7XG5cbiAgICAgIGlmIChvcHRpb25zLnVuaXggPT09IGZhbHNlKSB7IC8vIHRoaXMgYnJhbmNoIGlzIGZvciBleGVjKClcbiAgICAgICAgcmV0VmFsdWUgPSBmbi5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgIH0gZWxzZSB7IC8vIGFuZCB0aGlzIGJyYW5jaCBpcyBmb3IgZXZlcnl0aGluZyBlbHNlXG4gICAgICAgIGlmIChpc09iamVjdChhcmdzWzBdKSAmJiBhcmdzWzBdLmNvbnN0cnVjdG9yLm5hbWUgPT09ICdPYmplY3QnKSB7XG4gICAgICAgICAgLy8gYSBuby1vcCwgYWxsb3dpbmcgdGhlIHN5bnRheCBgdG91Y2goeyctcic6IGZpbGV9LCAuLi4pYFxuICAgICAgICB9IGVsc2UgaWYgKGFyZ3MubGVuZ3RoID09PSAwIHx8IHR5cGVvZiBhcmdzWzBdICE9PSAnc3RyaW5nJyB8fCBhcmdzWzBdLmxlbmd0aCA8PSAxIHx8IGFyZ3NbMF1bMF0gIT09ICctJykge1xuICAgICAgICAgIGFyZ3MudW5zaGlmdCgnJyk7IC8vIG9ubHkgYWRkIGR1bW15IG9wdGlvbiBpZiAnLW9wdGlvbicgbm90IGFscmVhZHkgcHJlc2VudFxuICAgICAgICB9XG5cbiAgICAgICAgLy8gZmxhdHRlbiBvdXQgYXJyYXlzIHRoYXQgYXJlIGFyZ3VtZW50cywgdG8gbWFrZSB0aGUgc3ludGF4OlxuICAgICAgICAvLyAgICBgY3AoW2ZpbGUxLCBmaWxlMiwgZmlsZTNdLCBkZXN0KTtgXG4gICAgICAgIC8vIGVxdWl2YWxlbnQgdG86XG4gICAgICAgIC8vICAgIGBjcChmaWxlMSwgZmlsZTIsIGZpbGUzLCBkZXN0KTtgXG4gICAgICAgIGFyZ3MgPSBhcmdzLnJlZHVjZShmdW5jdGlvbiAoYWNjdW0sIGN1cikge1xuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGN1cikpIHtcbiAgICAgICAgICAgIHJldHVybiBhY2N1bS5jb25jYXQoY3VyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYWNjdW0ucHVzaChjdXIpO1xuICAgICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgICAgfSwgW10pO1xuXG4gICAgICAgIC8vIENvbnZlcnQgU2hlbGxTdHJpbmdzIChiYXNpY2FsbHkganVzdCBTdHJpbmcgb2JqZWN0cykgdG8gcmVndWxhciBzdHJpbmdzXG4gICAgICAgIGFyZ3MgPSBhcmdzLm1hcChmdW5jdGlvbiAoYXJnKSB7XG4gICAgICAgICAgaWYgKGlzT2JqZWN0KGFyZykgJiYgYXJnLmNvbnN0cnVjdG9yLm5hbWUgPT09ICdTdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gYXJnLnRvU3RyaW5nKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBhcmc7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4cGFuZCB0aGUgJ34nIGlmIGFwcHJvcHJpYXRlXG4gICAgICAgIHZhciBob21lRGlyID0gb3MuaG9tZWRpcigpO1xuICAgICAgICBhcmdzID0gYXJncy5tYXAoZnVuY3Rpb24gKGFyZykge1xuICAgICAgICAgIGlmICh0eXBlb2YgYXJnID09PSAnc3RyaW5nJyAmJiBhcmcuc2xpY2UoMCwgMikgPT09ICd+LycgfHwgYXJnID09PSAnficpIHtcbiAgICAgICAgICAgIHJldHVybiBhcmcucmVwbGFjZSgvXn4vLCBob21lRGlyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGFyZztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gUGVyZm9ybSBnbG9iLWV4cGFuc2lvbiBvbiBhbGwgYXJndW1lbnRzIGFmdGVyIGdsb2JTdGFydCwgYnV0IHByZXNlcnZlXG4gICAgICAgIC8vIHRoZSBhcmd1bWVudHMgYmVmb3JlIGl0IChsaWtlIHJlZ2V4ZXMgZm9yIHNlZCBhbmQgZ3JlcClcbiAgICAgICAgaWYgKCFjb25maWcubm9nbG9iICYmIG9wdGlvbnMuYWxsb3dHbG9iYmluZyA9PT0gdHJ1ZSkge1xuICAgICAgICAgIGFyZ3MgPSBhcmdzLnNsaWNlKDAsIG9wdGlvbnMuZ2xvYlN0YXJ0KS5jb25jYXQoZXhwYW5kKGFyZ3Muc2xpY2Uob3B0aW9ucy5nbG9iU3RhcnQpKSk7XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIHBhcnNlIG9wdGlvbnMgaWYgb3B0aW9ucyBhcmUgcHJvdmlkZWRcbiAgICAgICAgICBpZiAoaXNPYmplY3Qob3B0aW9ucy5jbWRPcHRpb25zKSkge1xuICAgICAgICAgICAgYXJnc1swXSA9IHBhcnNlT3B0aW9ucyhhcmdzWzBdLCBvcHRpb25zLmNtZE9wdGlvbnMpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldFZhbHVlID0gZm4uYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgICAgIGlmIChlLm1zZyA9PT0gJ2Vhcmx5RXhpdCcpIHtcbiAgICAgICAgICAgIHJldFZhbHVlID0gZS5yZXRWYWx1ZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgZTsgLy8gdGhpcyBpcyBwcm9iYWJseSBhIGJ1ZyB0aGF0IHNob3VsZCBiZSB0aHJvd24gdXAgdGhlIGNhbGwgc3RhY2tcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgaWYgKCFzdGF0ZS5lcnJvcikge1xuICAgICAgICAvLyBJZiBzdGF0ZS5lcnJvciBoYXNuJ3QgYmVlbiBzZXQgaXQncyBhbiBlcnJvciB0aHJvd24gYnkgTm9kZSwgbm90IHVzIC0gcHJvYmFibHkgYSBidWcuLi5cbiAgICAgICAgZS5uYW1lID0gJ1NoZWxsSlNJbnRlcm5hbEVycm9yJztcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICAgIGlmIChjb25maWcuZmF0YWwpIHRocm93IGU7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMud3JhcE91dHB1dCAmJlxuICAgICAgICAodHlwZW9mIHJldFZhbHVlID09PSAnc3RyaW5nJyB8fCBBcnJheS5pc0FycmF5KHJldFZhbHVlKSkpIHtcbiAgICAgIHJldFZhbHVlID0gbmV3IFNoZWxsU3RyaW5nKHJldFZhbHVlLCBzdGF0ZS5lcnJvciwgc3RhdGUuZXJyb3JDb2RlKTtcbiAgICB9XG5cbiAgICBzdGF0ZS5jdXJyZW50Q21kID0gJ3NoZWxsLmpzJztcbiAgICByZXR1cm4gcmV0VmFsdWU7XG4gIH07XG59IC8vIHdyYXBcbmV4cG9ydHMud3JhcCA9IHdyYXA7XG5cbi8vIFRoaXMgcmV0dXJucyBhbGwgdGhlIGlucHV0IHRoYXQgaXMgcGlwZWQgaW50byB0aGUgY3VycmVudCBjb21tYW5kIChvciB0aGVcbi8vIGVtcHR5IHN0cmluZywgaWYgdGhpcyBpc24ndCBvbiB0aGUgcmlnaHQtaGFuZCBzaWRlIG9mIGEgcGlwZVxuZnVuY3Rpb24gX3JlYWRGcm9tUGlwZSgpIHtcbiAgcmV0dXJuIHN0YXRlLnBpcGVkVmFsdWU7XG59XG5leHBvcnRzLnJlYWRGcm9tUGlwZSA9IF9yZWFkRnJvbVBpcGU7XG5cbnZhciBERUZBVUxUX1dSQVBfT1BUSU9OUyA9IHtcbiAgYWxsb3dHbG9iYmluZzogdHJ1ZSxcbiAgY2FuUmVjZWl2ZVBpcGU6IGZhbHNlLFxuICBjbWRPcHRpb25zOiBudWxsLFxuICBnbG9iU3RhcnQ6IDEsXG4gIHBpcGVPbmx5OiBmYWxzZSxcbiAgd3JhcE91dHB1dDogdHJ1ZSxcbiAgdW5peDogdHJ1ZSxcbn07XG5cbi8vIFRoaXMgaXMgcG9wdWxhdGVkIGR1cmluZyBwbHVnaW4gcmVnaXN0cmF0aW9uXG52YXIgcGlwZU1ldGhvZHMgPSBbXTtcblxuLy8gUmVnaXN0ZXIgYSBuZXcgU2hlbGxKUyBjb21tYW5kXG5mdW5jdGlvbiBfcmVnaXN0ZXIobmFtZSwgaW1wbGVtZW50YXRpb24sIHdyYXBPcHRpb25zKSB7XG4gIHdyYXBPcHRpb25zID0gd3JhcE9wdGlvbnMgfHwge307XG5cbiAgLy8gVmFsaWRhdGUgb3B0aW9uc1xuICBPYmplY3Qua2V5cyh3cmFwT3B0aW9ucykuZm9yRWFjaChmdW5jdGlvbiAob3B0aW9uKSB7XG4gICAgaWYgKCFERUZBVUxUX1dSQVBfT1BUSU9OUy5oYXNPd25Qcm9wZXJ0eShvcHRpb24pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9wdGlvbiAnXCIgKyBvcHRpb24gKyBcIidcIik7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygd3JhcE9wdGlvbnNbb3B0aW9uXSAhPT0gdHlwZW9mIERFRkFVTFRfV1JBUF9PUFRJT05TW29wdGlvbl0pIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJVbnN1cHBvcnRlZCB0eXBlICdcIiArIHR5cGVvZiB3cmFwT3B0aW9uc1tvcHRpb25dICtcbiAgICAgICAgXCInIGZvciBvcHRpb24gJ1wiICsgb3B0aW9uICsgXCInXCIpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gSWYgYW4gb3B0aW9uIGlzbid0IHNwZWNpZmllZCwgdXNlIHRoZSBkZWZhdWx0XG4gIHdyYXBPcHRpb25zID0gT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9XUkFQX09QVElPTlMsIHdyYXBPcHRpb25zKTtcblxuICBpZiAoc2hlbGwuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbW1hbmQgYCcgKyBuYW1lICsgJ2AgYWxyZWFkeSBleGlzdHMnKTtcbiAgfVxuXG4gIGlmICh3cmFwT3B0aW9ucy5waXBlT25seSkge1xuICAgIHdyYXBPcHRpb25zLmNhblJlY2VpdmVQaXBlID0gdHJ1ZTtcbiAgICBzaGVsbE1ldGhvZHNbbmFtZV0gPSB3cmFwKG5hbWUsIGltcGxlbWVudGF0aW9uLCB3cmFwT3B0aW9ucyk7XG4gIH0gZWxzZSB7XG4gICAgc2hlbGxbbmFtZV0gPSB3cmFwKG5hbWUsIGltcGxlbWVudGF0aW9uLCB3cmFwT3B0aW9ucyk7XG4gIH1cblxuICBpZiAod3JhcE9wdGlvbnMuY2FuUmVjZWl2ZVBpcGUpIHtcbiAgICBwaXBlTWV0aG9kcy5wdXNoKG5hbWUpO1xuICB9XG59XG5leHBvcnRzLnJlZ2lzdGVyID0gX3JlZ2lzdGVyO1xuIiwidmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcbnZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG5cbmNvbW1vbi5yZWdpc3RlcignY3AnLCBfY3AsIHtcbiAgY21kT3B0aW9uczoge1xuICAgICdmJzogJyFub19mb3JjZScsXG4gICAgJ24nOiAnbm9fZm9yY2UnLFxuICAgICd1JzogJ3VwZGF0ZScsXG4gICAgJ1InOiAncmVjdXJzaXZlJyxcbiAgICAncic6ICdyZWN1cnNpdmUnLFxuICAgICdMJzogJ2ZvbGxvd3N5bWxpbmsnLFxuICAgICdQJzogJ25vRm9sbG93c3ltbGluaycsXG4gIH0sXG4gIHdyYXBPdXRwdXQ6IGZhbHNlLFxufSk7XG5cbi8vIEJ1ZmZlcmVkIGZpbGUgY29weSwgc3luY2hyb25vdXNcbi8vIChVc2luZyByZWFkRmlsZVN5bmMoKSArIHdyaXRlRmlsZVN5bmMoKSBjb3VsZCBlYXNpbHkgY2F1c2UgYSBtZW1vcnkgb3ZlcmZsb3dcbi8vICB3aXRoIGxhcmdlIGZpbGVzKVxuZnVuY3Rpb24gY29weUZpbGVTeW5jKHNyY0ZpbGUsIGRlc3RGaWxlLCBvcHRpb25zKSB7XG4gIGlmICghZnMuZXhpc3RzU3luYyhzcmNGaWxlKSkge1xuICAgIGNvbW1vbi5lcnJvcignY29weUZpbGVTeW5jOiBubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5OiAnICsgc3JjRmlsZSk7XG4gIH1cblxuICB2YXIgaXNXaW5kb3dzID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJztcblxuICAvLyBDaGVjayB0aGUgbXRpbWVzIG9mIHRoZSBmaWxlcyBpZiB0aGUgJy11JyBmbGFnIGlzIHByb3ZpZGVkXG4gIHRyeSB7XG4gICAgaWYgKG9wdGlvbnMudXBkYXRlICYmIGNvbW1vbi5zdGF0Rm9sbG93TGlua3Moc3JjRmlsZSkubXRpbWUgPCBmcy5zdGF0U3luYyhkZXN0RmlsZSkubXRpbWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBJZiB3ZSdyZSBoZXJlLCBkZXN0RmlsZSBwcm9iYWJseSBkb2Vzbid0IGV4aXN0LCBzbyBqdXN0IGRvIGEgbm9ybWFsIGNvcHlcbiAgfVxuXG4gIGlmIChjb21tb24uc3RhdE5vRm9sbG93TGlua3Moc3JjRmlsZSkuaXNTeW1ib2xpY0xpbmsoKSAmJiAhb3B0aW9ucy5mb2xsb3dzeW1saW5rKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbW1vbi5zdGF0Tm9Gb2xsb3dMaW5rcyhkZXN0RmlsZSk7XG4gICAgICBjb21tb24udW5saW5rU3luYyhkZXN0RmlsZSk7IC8vIHJlLWxpbmsgaXRcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBpdCBkb2Vzbid0IGV4aXN0LCBzbyBubyB3b3JrIG5lZWRzIHRvIGJlIGRvbmVcbiAgICB9XG5cbiAgICB2YXIgc3ltbGlua0Z1bGwgPSBmcy5yZWFkbGlua1N5bmMoc3JjRmlsZSk7XG4gICAgZnMuc3ltbGlua1N5bmMoc3ltbGlua0Z1bGwsIGRlc3RGaWxlLCBpc1dpbmRvd3MgPyAnanVuY3Rpb24nIDogbnVsbCk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGJ1ZiA9IGNvbW1vbi5idWZmZXIoKTtcbiAgICB2YXIgYnVmTGVuZ3RoID0gYnVmLmxlbmd0aDtcbiAgICB2YXIgYnl0ZXNSZWFkID0gYnVmTGVuZ3RoO1xuICAgIHZhciBwb3MgPSAwO1xuICAgIHZhciBmZHIgPSBudWxsO1xuICAgIHZhciBmZHcgPSBudWxsO1xuXG4gICAgdHJ5IHtcbiAgICAgIGZkciA9IGZzLm9wZW5TeW5jKHNyY0ZpbGUsICdyJyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgIGNvbW1vbi5lcnJvcignY29weUZpbGVTeW5jOiBjb3VsZCBub3QgcmVhZCBzcmMgZmlsZSAoJyArIHNyY0ZpbGUgKyAnKScpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBmZHcgPSBmcy5vcGVuU3luYyhkZXN0RmlsZSwgJ3cnKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgY29tbW9uLmVycm9yKCdjb3B5RmlsZVN5bmM6IGNvdWxkIG5vdCB3cml0ZSB0byBkZXN0IGZpbGUgKGNvZGU9JyArIGUuY29kZSArICcpOicgKyBkZXN0RmlsZSk7XG4gICAgfVxuXG4gICAgd2hpbGUgKGJ5dGVzUmVhZCA9PT0gYnVmTGVuZ3RoKSB7XG4gICAgICBieXRlc1JlYWQgPSBmcy5yZWFkU3luYyhmZHIsIGJ1ZiwgMCwgYnVmTGVuZ3RoLCBwb3MpO1xuICAgICAgZnMud3JpdGVTeW5jKGZkdywgYnVmLCAwLCBieXRlc1JlYWQpO1xuICAgICAgcG9zICs9IGJ5dGVzUmVhZDtcbiAgICB9XG5cbiAgICBmcy5jbG9zZVN5bmMoZmRyKTtcbiAgICBmcy5jbG9zZVN5bmMoZmR3KTtcblxuICAgIGZzLmNobW9kU3luYyhkZXN0RmlsZSwgY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhzcmNGaWxlKS5tb2RlKTtcbiAgfVxufVxuXG4vLyBSZWN1cnNpdmVseSBjb3BpZXMgJ3NvdXJjZURpcicgaW50byAnZGVzdERpcidcbi8vIEFkYXB0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vcnlhbm1jZ3JhdGgvd3JlbmNoLWpzXG4vL1xuLy8gQ29weXJpZ2h0IChjKSAyMDEwIFJ5YW4gTWNHcmF0aFxuLy8gQ29weXJpZ2h0IChjKSAyMDEyIEFydHVyIEFkaWJcbi8vXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2Vcbi8vIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwXG5mdW5jdGlvbiBjcGRpclN5bmNSZWN1cnNpdmUoc291cmNlRGlyLCBkZXN0RGlyLCBjdXJyZW50RGVwdGgsIG9wdHMpIHtcbiAgaWYgKCFvcHRzKSBvcHRzID0ge307XG5cbiAgLy8gRW5zdXJlIHRoZXJlIGlzIG5vdCBhIHJ1biBhd2F5IHJlY3Vyc2l2ZSBjb3B5XG4gIGlmIChjdXJyZW50RGVwdGggPj0gY29tbW9uLmNvbmZpZy5tYXhkZXB0aCkgcmV0dXJuO1xuICBjdXJyZW50RGVwdGgrKztcblxuICB2YXIgaXNXaW5kb3dzID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJztcblxuICAvLyBDcmVhdGUgdGhlIGRpcmVjdG9yeSB3aGVyZSBhbGwgb3VyIGp1bmsgaXMgbW92aW5nIHRvOyByZWFkIHRoZSBtb2RlIG9mIHRoZVxuICAvLyBzb3VyY2UgZGlyZWN0b3J5IGFuZCBtaXJyb3IgaXRcbiAgdHJ5IHtcbiAgICBmcy5ta2RpclN5bmMoZGVzdERpcik7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBpZiB0aGUgZGlyZWN0b3J5IGFscmVhZHkgZXhpc3RzLCB0aGF0J3Mgb2theVxuICAgIGlmIChlLmNvZGUgIT09ICdFRVhJU1QnKSB0aHJvdyBlO1xuICB9XG5cbiAgdmFyIGZpbGVzID0gZnMucmVhZGRpclN5bmMoc291cmNlRGlyKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGZpbGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHNyY0ZpbGUgPSBzb3VyY2VEaXIgKyAnLycgKyBmaWxlc1tpXTtcbiAgICB2YXIgZGVzdEZpbGUgPSBkZXN0RGlyICsgJy8nICsgZmlsZXNbaV07XG4gICAgdmFyIHNyY0ZpbGVTdGF0ID0gY29tbW9uLnN0YXROb0ZvbGxvd0xpbmtzKHNyY0ZpbGUpO1xuXG4gICAgdmFyIHN5bWxpbmtGdWxsO1xuICAgIGlmIChvcHRzLmZvbGxvd3N5bWxpbmspIHtcbiAgICAgIGlmIChjcGNoZWNrY3ljbGUoc291cmNlRGlyLCBzcmNGaWxlKSkge1xuICAgICAgICAvLyBDeWNsZSBsaW5rIGZvdW5kLlxuICAgICAgICBjb25zb2xlLmVycm9yKCdDeWNsZSBsaW5rIGZvdW5kLicpO1xuICAgICAgICBzeW1saW5rRnVsbCA9IGZzLnJlYWRsaW5rU3luYyhzcmNGaWxlKTtcbiAgICAgICAgZnMuc3ltbGlua1N5bmMoc3ltbGlua0Z1bGwsIGRlc3RGaWxlLCBpc1dpbmRvd3MgPyAnanVuY3Rpb24nIDogbnVsbCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoc3JjRmlsZVN0YXQuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgLyogcmVjdXJzaW9uIHRoaXMgdGhpbmcgcmlnaHQgb24gYmFjay4gKi9cbiAgICAgIGNwZGlyU3luY1JlY3Vyc2l2ZShzcmNGaWxlLCBkZXN0RmlsZSwgY3VycmVudERlcHRoLCBvcHRzKTtcbiAgICB9IGVsc2UgaWYgKHNyY0ZpbGVTdGF0LmlzU3ltYm9saWNMaW5rKCkgJiYgIW9wdHMuZm9sbG93c3ltbGluaykge1xuICAgICAgc3ltbGlua0Z1bGwgPSBmcy5yZWFkbGlua1N5bmMoc3JjRmlsZSk7XG4gICAgICB0cnkge1xuICAgICAgICBjb21tb24uc3RhdE5vRm9sbG93TGlua3MoZGVzdEZpbGUpO1xuICAgICAgICBjb21tb24udW5saW5rU3luYyhkZXN0RmlsZSk7IC8vIHJlLWxpbmsgaXRcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gaXQgZG9lc24ndCBleGlzdCwgc28gbm8gd29yayBuZWVkcyB0byBiZSBkb25lXG4gICAgICB9XG4gICAgICBmcy5zeW1saW5rU3luYyhzeW1saW5rRnVsbCwgZGVzdEZpbGUsIGlzV2luZG93cyA/ICdqdW5jdGlvbicgOiBudWxsKTtcbiAgICB9IGVsc2UgaWYgKHNyY0ZpbGVTdGF0LmlzU3ltYm9saWNMaW5rKCkgJiYgb3B0cy5mb2xsb3dzeW1saW5rKSB7XG4gICAgICBzcmNGaWxlU3RhdCA9IGNvbW1vbi5zdGF0Rm9sbG93TGlua3Moc3JjRmlsZSk7XG4gICAgICBpZiAoc3JjRmlsZVN0YXQuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICBjcGRpclN5bmNSZWN1cnNpdmUoc3JjRmlsZSwgZGVzdEZpbGUsIGN1cnJlbnREZXB0aCwgb3B0cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb3B5RmlsZVN5bmMoc3JjRmlsZSwgZGVzdEZpbGUsIG9wdHMpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvKiBBdCB0aGlzIHBvaW50LCB3ZSd2ZSBoaXQgYSBmaWxlIGFjdHVhbGx5IHdvcnRoIGNvcHlpbmcuLi4gc28gY29weSBpdCBvbiBvdmVyLiAqL1xuICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoZGVzdEZpbGUpICYmIG9wdHMubm9fZm9yY2UpIHtcbiAgICAgICAgY29tbW9uLmxvZygnc2tpcHBpbmcgZXhpc3RpbmcgZmlsZTogJyArIGZpbGVzW2ldKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvcHlGaWxlU3luYyhzcmNGaWxlLCBkZXN0RmlsZSwgb3B0cyk7XG4gICAgICB9XG4gICAgfVxuICB9IC8vIGZvciBmaWxlc1xuXG4gIC8vIGZpbmFsbHkgY2hhbmdlIHRoZSBtb2RlIGZvciB0aGUgbmV3bHkgY3JlYXRlZCBkaXJlY3RvcnkgKG90aGVyd2lzZSwgd2VcbiAgLy8gY291bGRuJ3QgYWRkIGZpbGVzIHRvIGEgcmVhZC1vbmx5IGRpcmVjdG9yeSkuXG4gIHZhciBjaGVja0RpciA9IGNvbW1vbi5zdGF0Rm9sbG93TGlua3Moc291cmNlRGlyKTtcbiAgZnMuY2htb2RTeW5jKGRlc3REaXIsIGNoZWNrRGlyLm1vZGUpO1xufSAvLyBjcGRpclN5bmNSZWN1cnNpdmVcblxuLy8gQ2hlY2tzIGlmIGN1cmVlbnQgZmlsZSB3YXMgY3JlYXRlZCByZWNlbnRseVxuZnVuY3Rpb24gY2hlY2tSZWNlbnRDcmVhdGVkKHNvdXJjZXMsIGluZGV4KSB7XG4gIHZhciBsb29rZWRTb3VyY2UgPSBzb3VyY2VzW2luZGV4XTtcbiAgcmV0dXJuIHNvdXJjZXMuc2xpY2UoMCwgaW5kZXgpLnNvbWUoZnVuY3Rpb24gKHNyYykge1xuICAgIHJldHVybiBwYXRoLmJhc2VuYW1lKHNyYykgPT09IHBhdGguYmFzZW5hbWUobG9va2VkU291cmNlKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGNwY2hlY2tjeWNsZShzb3VyY2VEaXIsIHNyY0ZpbGUpIHtcbiAgdmFyIHNyY0ZpbGVTdGF0ID0gY29tbW9uLnN0YXROb0ZvbGxvd0xpbmtzKHNyY0ZpbGUpO1xuICBpZiAoc3JjRmlsZVN0YXQuaXNTeW1ib2xpY0xpbmsoKSkge1xuICAgIC8vIERvIGN5Y2xlIGNoZWNrLiBGb3IgZXhhbXBsZTpcbiAgICAvLyAgICQgbWtkaXIgLXAgMS8yLzMvNFxuICAgIC8vICAgJCBjZCAgMS8yLzMvNFxuICAgIC8vICAgJCBsbiAtcyAuLi8uLi8zIGxpbmtcbiAgICAvLyAgICQgY2QgLi4vLi4vLi4vLi5cbiAgICAvLyAgICQgY3AgLVJMIDEgY29weVxuICAgIHZhciBjeWNsZWNoZWNrID0gY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhzcmNGaWxlKTtcbiAgICBpZiAoY3ljbGVjaGVjay5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICB2YXIgc291cmNlcmVhbHBhdGggPSBmcy5yZWFscGF0aFN5bmMoc291cmNlRGlyKTtcbiAgICAgIHZhciBzeW1saW5rcmVhbHBhdGggPSBmcy5yZWFscGF0aFN5bmMoc3JjRmlsZSk7XG4gICAgICB2YXIgcmUgPSBuZXcgUmVnRXhwKHN5bWxpbmtyZWFscGF0aCk7XG4gICAgICBpZiAocmUudGVzdChzb3VyY2VyZWFscGF0aCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLy9AXG4vL0AgIyMjIGNwKFtvcHRpb25zLF0gc291cmNlIFssIHNvdXJjZSAuLi5dLCBkZXN0KVxuLy9AICMjIyBjcChbb3B0aW9ucyxdIHNvdXJjZV9hcnJheSwgZGVzdClcbi8vQFxuLy9AIEF2YWlsYWJsZSBvcHRpb25zOlxuLy9AXG4vL0AgKyBgLWZgOiBmb3JjZSAoZGVmYXVsdCBiZWhhdmlvcilcbi8vQCArIGAtbmA6IG5vLWNsb2JiZXJcbi8vQCArIGAtdWA6IG9ubHkgY29weSBpZiBgc291cmNlYCBpcyBuZXdlciB0aGFuIGBkZXN0YFxuLy9AICsgYC1yYCwgYC1SYDogcmVjdXJzaXZlXG4vL0AgKyBgLUxgOiBmb2xsb3cgc3ltbGlua3Ncbi8vQCArIGAtUGA6IGRvbid0IGZvbGxvdyBzeW1saW5rc1xuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgY3AoJ2ZpbGUxJywgJ2RpcjEnKTtcbi8vQCBjcCgnLVInLCAncGF0aC90by9kaXIvJywgJ34vbmV3Q29weS8nKTtcbi8vQCBjcCgnLVJmJywgJy90bXAvKicsICcvdXNyL2xvY2FsLyonLCAnL2hvbWUvdG1wJyk7XG4vL0AgY3AoJy1SZicsIFsnL3RtcC8qJywgJy91c3IvbG9jYWwvKiddLCAnL2hvbWUvdG1wJyk7IC8vIHNhbWUgYXMgYWJvdmVcbi8vQCBgYGBcbi8vQFxuLy9AIENvcGllcyBmaWxlcy5cbmZ1bmN0aW9uIF9jcChvcHRpb25zLCBzb3VyY2VzLCBkZXN0KSB7XG4gIC8vIElmIHdlJ3JlIG1pc3NpbmcgLVIsIGl0IGFjdHVhbGx5IGltcGxpZXMgLUwgKHVubGVzcyAtUCBpcyBleHBsaWNpdClcbiAgaWYgKG9wdGlvbnMuZm9sbG93c3ltbGluaykge1xuICAgIG9wdGlvbnMubm9Gb2xsb3dzeW1saW5rID0gZmFsc2U7XG4gIH1cbiAgaWYgKCFvcHRpb25zLnJlY3Vyc2l2ZSAmJiAhb3B0aW9ucy5ub0ZvbGxvd3N5bWxpbmspIHtcbiAgICBvcHRpb25zLmZvbGxvd3N5bWxpbmsgPSB0cnVlO1xuICB9XG5cbiAgLy8gR2V0IHNvdXJjZXMsIGRlc3RcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAzKSB7XG4gICAgY29tbW9uLmVycm9yKCdtaXNzaW5nIDxzb3VyY2U+IGFuZC9vciA8ZGVzdD4nKTtcbiAgfSBlbHNlIHtcbiAgICBzb3VyY2VzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEsIGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcbiAgICBkZXN0ID0gYXJndW1lbnRzW2FyZ3VtZW50cy5sZW5ndGggLSAxXTtcbiAgfVxuXG4gIHZhciBkZXN0RXhpc3RzID0gZnMuZXhpc3RzU3luYyhkZXN0KTtcbiAgdmFyIGRlc3RTdGF0ID0gZGVzdEV4aXN0cyAmJiBjb21tb24uc3RhdEZvbGxvd0xpbmtzKGRlc3QpO1xuXG4gIC8vIERlc3QgaXMgbm90IGV4aXN0aW5nIGRpciwgYnV0IG11bHRpcGxlIHNvdXJjZXMgZ2l2ZW5cbiAgaWYgKCghZGVzdEV4aXN0cyB8fCAhZGVzdFN0YXQuaXNEaXJlY3RvcnkoKSkgJiYgc291cmNlcy5sZW5ndGggPiAxKSB7XG4gICAgY29tbW9uLmVycm9yKCdkZXN0IGlzIG5vdCBhIGRpcmVjdG9yeSAodG9vIG1hbnkgc291cmNlcyknKTtcbiAgfVxuXG4gIC8vIERlc3QgaXMgYW4gZXhpc3RpbmcgZmlsZSwgYnV0IC1uIGlzIGdpdmVuXG4gIGlmIChkZXN0RXhpc3RzICYmIGRlc3RTdGF0LmlzRmlsZSgpICYmIG9wdGlvbnMubm9fZm9yY2UpIHtcbiAgICByZXR1cm4gbmV3IGNvbW1vbi5TaGVsbFN0cmluZygnJywgJycsIDApO1xuICB9XG5cbiAgc291cmNlcy5mb3JFYWNoKGZ1bmN0aW9uIChzcmMsIHNyY0luZGV4KSB7XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKHNyYykpIHtcbiAgICAgIGlmIChzcmMgPT09ICcnKSBzcmMgPSBcIicnXCI7IC8vIGlmIHNyYyB3YXMgZW1wdHkgc3RyaW5nLCBkaXNwbGF5IGVtcHR5IHN0cmluZ1xuICAgICAgY29tbW9uLmVycm9yKCdubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5OiAnICsgc3JjLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICAgICAgcmV0dXJuOyAvLyBza2lwIGZpbGVcbiAgICB9XG4gICAgdmFyIHNyY1N0YXQgPSBjb21tb24uc3RhdEZvbGxvd0xpbmtzKHNyYyk7XG4gICAgaWYgKCFvcHRpb25zLm5vRm9sbG93c3ltbGluayAmJiBzcmNTdGF0LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgIGlmICghb3B0aW9ucy5yZWN1cnNpdmUpIHtcbiAgICAgICAgLy8gTm9uLVJlY3Vyc2l2ZVxuICAgICAgICBjb21tb24uZXJyb3IoXCJvbWl0dGluZyBkaXJlY3RvcnkgJ1wiICsgc3JjICsgXCInXCIsIHsgY29udGludWU6IHRydWUgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBSZWN1cnNpdmVcbiAgICAgICAgLy8gJ2NwIC9hL3NvdXJjZSBkZXN0JyBzaG91bGQgY3JlYXRlICdzb3VyY2UnIGluICdkZXN0J1xuICAgICAgICB2YXIgbmV3RGVzdCA9IChkZXN0U3RhdCAmJiBkZXN0U3RhdC5pc0RpcmVjdG9yeSgpKSA/XG4gICAgICAgICAgICBwYXRoLmpvaW4oZGVzdCwgcGF0aC5iYXNlbmFtZShzcmMpKSA6XG4gICAgICAgICAgICBkZXN0O1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhwYXRoLmRpcm5hbWUoZGVzdCkpO1xuICAgICAgICAgIGNwZGlyU3luY1JlY3Vyc2l2ZShzcmMsIG5ld0Rlc3QsIDAsIHsgbm9fZm9yY2U6IG9wdGlvbnMubm9fZm9yY2UsIGZvbGxvd3N5bWxpbms6IG9wdGlvbnMuZm9sbG93c3ltbGluayB9KTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgICAgY29tbW9uLmVycm9yKFwiY2Fubm90IGNyZWF0ZSBkaXJlY3RvcnkgJ1wiICsgZGVzdCArIFwiJzogTm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeVwiKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJZiBoZXJlLCBzcmMgaXMgYSBmaWxlXG5cbiAgICAgIC8vIFdoZW4gY29weWluZyB0byAnL3BhdGgvZGlyJzpcbiAgICAgIC8vICAgIHRoaXNEZXN0ID0gJy9wYXRoL2Rpci9maWxlMSdcbiAgICAgIHZhciB0aGlzRGVzdCA9IGRlc3Q7XG4gICAgICBpZiAoZGVzdFN0YXQgJiYgZGVzdFN0YXQuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICB0aGlzRGVzdCA9IHBhdGgubm9ybWFsaXplKGRlc3QgKyAnLycgKyBwYXRoLmJhc2VuYW1lKHNyYykpO1xuICAgICAgfVxuXG4gICAgICB2YXIgdGhpc0Rlc3RFeGlzdHMgPSBmcy5leGlzdHNTeW5jKHRoaXNEZXN0KTtcbiAgICAgIGlmICh0aGlzRGVzdEV4aXN0cyAmJiBjaGVja1JlY2VudENyZWF0ZWQoc291cmNlcywgc3JjSW5kZXgpKSB7XG4gICAgICAgIC8vIGNhbm5vdCBvdmVyd3JpdGUgZmlsZSBjcmVhdGVkIHJlY2VudGx5IGluIGN1cnJlbnQgZXhlY3V0aW9uLCBidXQgd2Ugd2FudCB0byBjb250aW51ZSBjb3B5aW5nIG90aGVyIGZpbGVzXG4gICAgICAgIGlmICghb3B0aW9ucy5ub19mb3JjZSkge1xuICAgICAgICAgIGNvbW1vbi5lcnJvcihcIndpbGwgbm90IG92ZXJ3cml0ZSBqdXN0LWNyZWF0ZWQgJ1wiICsgdGhpc0Rlc3QgKyBcIicgd2l0aCAnXCIgKyBzcmMgKyBcIidcIiwgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzRGVzdEV4aXN0cyAmJiBvcHRpb25zLm5vX2ZvcmNlKSB7XG4gICAgICAgIHJldHVybjsgLy8gc2tpcCBmaWxlXG4gICAgICB9XG5cbiAgICAgIGlmIChwYXRoLnJlbGF0aXZlKHNyYywgdGhpc0Rlc3QpID09PSAnJykge1xuICAgICAgICAvLyBhIGZpbGUgY2Fubm90IGJlIGNvcGllZCB0byBpdHNlbGYsIGJ1dCB3ZSB3YW50IHRvIGNvbnRpbnVlIGNvcHlpbmcgb3RoZXIgZmlsZXNcbiAgICAgICAgY29tbW9uLmVycm9yKFwiJ1wiICsgdGhpc0Rlc3QgKyBcIicgYW5kICdcIiArIHNyYyArIFwiJyBhcmUgdGhlIHNhbWUgZmlsZVwiLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvcHlGaWxlU3luYyhzcmMsIHRoaXNEZXN0LCBvcHRpb25zKTtcbiAgICB9XG4gIH0pOyAvLyBmb3JFYWNoKHNyYylcblxuICByZXR1cm4gbmV3IGNvbW1vbi5TaGVsbFN0cmluZygnJywgY29tbW9uLnN0YXRlLmVycm9yLCBjb21tb24uc3RhdGUuZXJyb3JDb2RlKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gX2NwO1xuIiwidmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgX2NkID0gcmVxdWlyZSgnLi9jZCcpO1xudmFyIHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG5cbmNvbW1vbi5yZWdpc3RlcignZGlycycsIF9kaXJzLCB7XG4gIHdyYXBPdXRwdXQ6IGZhbHNlLFxufSk7XG5jb21tb24ucmVnaXN0ZXIoJ3B1c2hkJywgX3B1c2hkLCB7XG4gIHdyYXBPdXRwdXQ6IGZhbHNlLFxufSk7XG5jb21tb24ucmVnaXN0ZXIoJ3BvcGQnLCBfcG9wZCwge1xuICB3cmFwT3V0cHV0OiBmYWxzZSxcbn0pO1xuXG4vLyBQdXNoZC9wb3BkL2RpcnMgaW50ZXJuYWxzXG52YXIgX2RpclN0YWNrID0gW107XG5cbmZ1bmN0aW9uIF9pc1N0YWNrSW5kZXgoaW5kZXgpIHtcbiAgcmV0dXJuICgvXltcXC0rXVxcZCskLykudGVzdChpbmRleCk7XG59XG5cbmZ1bmN0aW9uIF9wYXJzZVN0YWNrSW5kZXgoaW5kZXgpIHtcbiAgaWYgKF9pc1N0YWNrSW5kZXgoaW5kZXgpKSB7XG4gICAgaWYgKE1hdGguYWJzKGluZGV4KSA8IF9kaXJTdGFjay5sZW5ndGggKyAxKSB7IC8vICsxIGZvciBwd2RcbiAgICAgIHJldHVybiAoL14tLykudGVzdChpbmRleCkgPyBOdW1iZXIoaW5kZXgpIC0gMSA6IE51bWJlcihpbmRleCk7XG4gICAgfVxuICAgIGNvbW1vbi5lcnJvcihpbmRleCArICc6IGRpcmVjdG9yeSBzdGFjayBpbmRleCBvdXQgb2YgcmFuZ2UnKTtcbiAgfSBlbHNlIHtcbiAgICBjb21tb24uZXJyb3IoaW5kZXggKyAnOiBpbnZhbGlkIG51bWJlcicpO1xuICB9XG59XG5cbmZ1bmN0aW9uIF9hY3R1YWxEaXJTdGFjaygpIHtcbiAgcmV0dXJuIFtwcm9jZXNzLmN3ZCgpXS5jb25jYXQoX2RpclN0YWNrKTtcbn1cblxuLy9AXG4vL0AgIyMjIHB1c2hkKFtvcHRpb25zLF0gW2RpciB8ICctTicgfCAnK04nXSlcbi8vQFxuLy9AIEF2YWlsYWJsZSBvcHRpb25zOlxuLy9AXG4vL0AgKyBgLW5gOiBTdXBwcmVzc2VzIHRoZSBub3JtYWwgY2hhbmdlIG9mIGRpcmVjdG9yeSB3aGVuIGFkZGluZyBkaXJlY3RvcmllcyB0byB0aGUgc3RhY2ssIHNvIHRoYXQgb25seSB0aGUgc3RhY2sgaXMgbWFuaXB1bGF0ZWQuXG4vL0AgKyBgLXFgOiBTdXByZXNzZXMgb3V0cHV0IHRvIHRoZSBjb25zb2xlLlxuLy9AXG4vL0AgQXJndW1lbnRzOlxuLy9AXG4vL0AgKyBgZGlyYDogU2V0cyB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSB0byB0aGUgdG9wIG9mIHRoZSBzdGFjaywgdGhlbiBleGVjdXRlcyB0aGUgZXF1aXZhbGVudCBvZiBgY2QgZGlyYC5cbi8vQCArIGArTmA6IEJyaW5ncyB0aGUgTnRoIGRpcmVjdG9yeSAoY291bnRpbmcgZnJvbSB0aGUgbGVmdCBvZiB0aGUgbGlzdCBwcmludGVkIGJ5IGRpcnMsIHN0YXJ0aW5nIHdpdGggemVybykgdG8gdGhlIHRvcCBvZiB0aGUgbGlzdCBieSByb3RhdGluZyB0aGUgc3RhY2suXG4vL0AgKyBgLU5gOiBCcmluZ3MgdGhlIE50aCBkaXJlY3RvcnkgKGNvdW50aW5nIGZyb20gdGhlIHJpZ2h0IG9mIHRoZSBsaXN0IHByaW50ZWQgYnkgZGlycywgc3RhcnRpbmcgd2l0aCB6ZXJvKSB0byB0aGUgdG9wIG9mIHRoZSBsaXN0IGJ5IHJvdGF0aW5nIHRoZSBzdGFjay5cbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIC8vIHByb2Nlc3MuY3dkKCkgPT09ICcvdXNyJ1xuLy9AIHB1c2hkKCcvZXRjJyk7IC8vIFJldHVybnMgL2V0YyAvdXNyXG4vL0AgcHVzaGQoJysxJyk7ICAgLy8gUmV0dXJucyAvdXNyIC9ldGNcbi8vQCBgYGBcbi8vQFxuLy9AIFNhdmUgdGhlIGN1cnJlbnQgZGlyZWN0b3J5IG9uIHRoZSB0b3Agb2YgdGhlIGRpcmVjdG9yeSBzdGFjayBhbmQgdGhlbiBgY2RgIHRvIGBkaXJgLiBXaXRoIG5vIGFyZ3VtZW50cywgYHB1c2hkYCBleGNoYW5nZXMgdGhlIHRvcCB0d28gZGlyZWN0b3JpZXMuIFJldHVybnMgYW4gYXJyYXkgb2YgcGF0aHMgaW4gdGhlIHN0YWNrLlxuZnVuY3Rpb24gX3B1c2hkKG9wdGlvbnMsIGRpcikge1xuICBpZiAoX2lzU3RhY2tJbmRleChvcHRpb25zKSkge1xuICAgIGRpciA9IG9wdGlvbnM7XG4gICAgb3B0aW9ucyA9ICcnO1xuICB9XG5cbiAgb3B0aW9ucyA9IGNvbW1vbi5wYXJzZU9wdGlvbnMob3B0aW9ucywge1xuICAgICduJzogJ25vLWNkJyxcbiAgICAncSc6ICdxdWlldCcsXG4gIH0pO1xuXG4gIHZhciBkaXJzID0gX2FjdHVhbERpclN0YWNrKCk7XG5cbiAgaWYgKGRpciA9PT0gJyswJykge1xuICAgIHJldHVybiBkaXJzOyAvLyArMCBpcyBhIG5vb3BcbiAgfSBlbHNlIGlmICghZGlyKSB7XG4gICAgaWYgKGRpcnMubGVuZ3RoID4gMSkge1xuICAgICAgZGlycyA9IGRpcnMuc3BsaWNlKDEsIDEpLmNvbmNhdChkaXJzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNvbW1vbi5lcnJvcignbm8gb3RoZXIgZGlyZWN0b3J5Jyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKF9pc1N0YWNrSW5kZXgoZGlyKSkge1xuICAgIHZhciBuID0gX3BhcnNlU3RhY2tJbmRleChkaXIpO1xuICAgIGRpcnMgPSBkaXJzLnNsaWNlKG4pLmNvbmNhdChkaXJzLnNsaWNlKDAsIG4pKTtcbiAgfSBlbHNlIHtcbiAgICBpZiAob3B0aW9uc1snbm8tY2QnXSkge1xuICAgICAgZGlycy5zcGxpY2UoMSwgMCwgZGlyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGlycy51bnNoaWZ0KGRpcik7XG4gICAgfVxuICB9XG5cbiAgaWYgKG9wdGlvbnNbJ25vLWNkJ10pIHtcbiAgICBkaXJzID0gZGlycy5zbGljZSgxKTtcbiAgfSBlbHNlIHtcbiAgICBkaXIgPSBwYXRoLnJlc29sdmUoZGlycy5zaGlmdCgpKTtcbiAgICBfY2QoJycsIGRpcik7XG4gIH1cblxuICBfZGlyU3RhY2sgPSBkaXJzO1xuICByZXR1cm4gX2RpcnMob3B0aW9ucy5xdWlldCA/ICctcScgOiAnJyk7XG59XG5leHBvcnRzLnB1c2hkID0gX3B1c2hkO1xuXG4vL0Bcbi8vQFxuLy9AICMjIyBwb3BkKFtvcHRpb25zLF0gWyctTicgfCAnK04nXSlcbi8vQFxuLy9AIEF2YWlsYWJsZSBvcHRpb25zOlxuLy9AXG4vL0AgKyBgLW5gOiBTdXBwcmVzcyB0aGUgbm9ybWFsIGRpcmVjdG9yeSBjaGFuZ2Ugd2hlbiByZW1vdmluZyBkaXJlY3RvcmllcyBmcm9tIHRoZSBzdGFjaywgc28gdGhhdCBvbmx5IHRoZSBzdGFjayBpcyBtYW5pcHVsYXRlZC5cbi8vQCArIGAtcWA6IFN1cHJlc3NlcyBvdXRwdXQgdG8gdGhlIGNvbnNvbGUuXG4vL0Bcbi8vQCBBcmd1bWVudHM6XG4vL0Bcbi8vQCArIGArTmA6IFJlbW92ZXMgdGhlIE50aCBkaXJlY3RvcnkgKGNvdW50aW5nIGZyb20gdGhlIGxlZnQgb2YgdGhlIGxpc3QgcHJpbnRlZCBieSBkaXJzKSwgc3RhcnRpbmcgd2l0aCB6ZXJvLlxuLy9AICsgYC1OYDogUmVtb3ZlcyB0aGUgTnRoIGRpcmVjdG9yeSAoY291bnRpbmcgZnJvbSB0aGUgcmlnaHQgb2YgdGhlIGxpc3QgcHJpbnRlZCBieSBkaXJzKSwgc3RhcnRpbmcgd2l0aCB6ZXJvLlxuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgZWNobyhwcm9jZXNzLmN3ZCgpKTsgLy8gJy91c3InXG4vL0AgcHVzaGQoJy9ldGMnKTsgICAgICAgLy8gJy9ldGMgL3Vzcidcbi8vQCBlY2hvKHByb2Nlc3MuY3dkKCkpOyAvLyAnL2V0Yydcbi8vQCBwb3BkKCk7ICAgICAgICAgICAgICAvLyAnL3Vzcidcbi8vQCBlY2hvKHByb2Nlc3MuY3dkKCkpOyAvLyAnL3Vzcidcbi8vQCBgYGBcbi8vQFxuLy9AIFdoZW4gbm8gYXJndW1lbnRzIGFyZSBnaXZlbiwgYHBvcGRgIHJlbW92ZXMgdGhlIHRvcCBkaXJlY3RvcnkgZnJvbSB0aGUgc3RhY2sgYW5kIHBlcmZvcm1zIGEgYGNkYCB0byB0aGUgbmV3IHRvcCBkaXJlY3RvcnkuIFRoZSBlbGVtZW50cyBhcmUgbnVtYmVyZWQgZnJvbSAwLCBzdGFydGluZyBhdCB0aGUgZmlyc3QgZGlyZWN0b3J5IGxpc3RlZCB3aXRoIGRpcnMgKGkuZS4sIGBwb3BkYCBpcyBlcXVpdmFsZW50IHRvIGBwb3BkICswYCkuIFJldHVybnMgYW4gYXJyYXkgb2YgcGF0aHMgaW4gdGhlIHN0YWNrLlxuZnVuY3Rpb24gX3BvcGQob3B0aW9ucywgaW5kZXgpIHtcbiAgaWYgKF9pc1N0YWNrSW5kZXgob3B0aW9ucykpIHtcbiAgICBpbmRleCA9IG9wdGlvbnM7XG4gICAgb3B0aW9ucyA9ICcnO1xuICB9XG5cbiAgb3B0aW9ucyA9IGNvbW1vbi5wYXJzZU9wdGlvbnMob3B0aW9ucywge1xuICAgICduJzogJ25vLWNkJyxcbiAgICAncSc6ICdxdWlldCcsXG4gIH0pO1xuXG4gIGlmICghX2RpclN0YWNrLmxlbmd0aCkge1xuICAgIHJldHVybiBjb21tb24uZXJyb3IoJ2RpcmVjdG9yeSBzdGFjayBlbXB0eScpO1xuICB9XG5cbiAgaW5kZXggPSBfcGFyc2VTdGFja0luZGV4KGluZGV4IHx8ICcrMCcpO1xuXG4gIGlmIChvcHRpb25zWyduby1jZCddIHx8IGluZGV4ID4gMCB8fCBfZGlyU3RhY2subGVuZ3RoICsgaW5kZXggPT09IDApIHtcbiAgICBpbmRleCA9IGluZGV4ID4gMCA/IGluZGV4IC0gMSA6IGluZGV4O1xuICAgIF9kaXJTdGFjay5zcGxpY2UoaW5kZXgsIDEpO1xuICB9IGVsc2Uge1xuICAgIHZhciBkaXIgPSBwYXRoLnJlc29sdmUoX2RpclN0YWNrLnNoaWZ0KCkpO1xuICAgIF9jZCgnJywgZGlyKTtcbiAgfVxuXG4gIHJldHVybiBfZGlycyhvcHRpb25zLnF1aWV0ID8gJy1xJyA6ICcnKTtcbn1cbmV4cG9ydHMucG9wZCA9IF9wb3BkO1xuXG4vL0Bcbi8vQFxuLy9AICMjIyBkaXJzKFtvcHRpb25zIHwgJytOJyB8ICctTiddKVxuLy9AXG4vL0AgQXZhaWxhYmxlIG9wdGlvbnM6XG4vL0Bcbi8vQCArIGAtY2A6IENsZWFycyB0aGUgZGlyZWN0b3J5IHN0YWNrIGJ5IGRlbGV0aW5nIGFsbCBvZiB0aGUgZWxlbWVudHMuXG4vL0AgKyBgLXFgOiBTdXByZXNzZXMgb3V0cHV0IHRvIHRoZSBjb25zb2xlLlxuLy9AXG4vL0AgQXJndW1lbnRzOlxuLy9AXG4vL0AgKyBgK05gOiBEaXNwbGF5cyB0aGUgTnRoIGRpcmVjdG9yeSAoY291bnRpbmcgZnJvbSB0aGUgbGVmdCBvZiB0aGUgbGlzdCBwcmludGVkIGJ5IGRpcnMgd2hlbiBpbnZva2VkIHdpdGhvdXQgb3B0aW9ucyksIHN0YXJ0aW5nIHdpdGggemVyby5cbi8vQCArIGAtTmA6IERpc3BsYXlzIHRoZSBOdGggZGlyZWN0b3J5IChjb3VudGluZyBmcm9tIHRoZSByaWdodCBvZiB0aGUgbGlzdCBwcmludGVkIGJ5IGRpcnMgd2hlbiBpbnZva2VkIHdpdGhvdXQgb3B0aW9ucyksIHN0YXJ0aW5nIHdpdGggemVyby5cbi8vQFxuLy9AIERpc3BsYXkgdGhlIGxpc3Qgb2YgY3VycmVudGx5IHJlbWVtYmVyZWQgZGlyZWN0b3JpZXMuIFJldHVybnMgYW4gYXJyYXkgb2YgcGF0aHMgaW4gdGhlIHN0YWNrLCBvciBhIHNpbmdsZSBwYXRoIGlmIGArTmAgb3IgYC1OYCB3YXMgc3BlY2lmaWVkLlxuLy9AXG4vL0AgU2VlIGFsc286IGBwdXNoZGAsIGBwb3BkYFxuZnVuY3Rpb24gX2RpcnMob3B0aW9ucywgaW5kZXgpIHtcbiAgaWYgKF9pc1N0YWNrSW5kZXgob3B0aW9ucykpIHtcbiAgICBpbmRleCA9IG9wdGlvbnM7XG4gICAgb3B0aW9ucyA9ICcnO1xuICB9XG5cbiAgb3B0aW9ucyA9IGNvbW1vbi5wYXJzZU9wdGlvbnMob3B0aW9ucywge1xuICAgICdjJzogJ2NsZWFyJyxcbiAgICAncSc6ICdxdWlldCcsXG4gIH0pO1xuXG4gIGlmIChvcHRpb25zLmNsZWFyKSB7XG4gICAgX2RpclN0YWNrID0gW107XG4gICAgcmV0dXJuIF9kaXJTdGFjaztcbiAgfVxuXG4gIHZhciBzdGFjayA9IF9hY3R1YWxEaXJTdGFjaygpO1xuXG4gIGlmIChpbmRleCkge1xuICAgIGluZGV4ID0gX3BhcnNlU3RhY2tJbmRleChpbmRleCk7XG5cbiAgICBpZiAoaW5kZXggPCAwKSB7XG4gICAgICBpbmRleCA9IHN0YWNrLmxlbmd0aCArIGluZGV4O1xuICAgIH1cblxuICAgIGlmICghb3B0aW9ucy5xdWlldCkge1xuICAgICAgY29tbW9uLmxvZyhzdGFja1tpbmRleF0pO1xuICAgIH1cbiAgICByZXR1cm4gc3RhY2tbaW5kZXhdO1xuICB9XG5cbiAgaWYgKCFvcHRpb25zLnF1aWV0KSB7XG4gICAgY29tbW9uLmxvZyhzdGFjay5qb2luKCcgJykpO1xuICB9XG5cbiAgcmV0dXJuIHN0YWNrO1xufVxuZXhwb3J0cy5kaXJzID0gX2RpcnM7XG4iLCJ2YXIgZm9ybWF0ID0gcmVxdWlyZSgndXRpbCcpLmZvcm1hdDtcblxudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG5cbmNvbW1vbi5yZWdpc3RlcignZWNobycsIF9lY2hvLCB7XG4gIGFsbG93R2xvYmJpbmc6IGZhbHNlLFxufSk7XG5cbi8vQFxuLy9AICMjIyBlY2hvKFtvcHRpb25zLF0gc3RyaW5nIFssIHN0cmluZyAuLi5dKVxuLy9AXG4vL0AgQXZhaWxhYmxlIG9wdGlvbnM6XG4vL0Bcbi8vQCArIGAtZWA6IGludGVycHJldCBiYWNrc2xhc2ggZXNjYXBlcyAoZGVmYXVsdClcbi8vQCArIGAtbmA6IHJlbW92ZSB0cmFpbGluZyBuZXdsaW5lIGZyb20gb3V0cHV0XG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBlY2hvKCdoZWxsbyB3b3JsZCcpO1xuLy9AIHZhciBzdHIgPSBlY2hvKCdoZWxsbyB3b3JsZCcpO1xuLy9AIGVjaG8oJy1uJywgJ25vIG5ld2xpbmUgYXQgZW5kJyk7XG4vL0AgYGBgXG4vL0Bcbi8vQCBQcmludHMgYHN0cmluZ2AgdG8gc3Rkb3V0LCBhbmQgcmV0dXJucyBzdHJpbmcgd2l0aCBhZGRpdGlvbmFsIHV0aWxpdHkgbWV0aG9kc1xuLy9AIGxpa2UgYC50bygpYC5cbmZ1bmN0aW9uIF9lY2hvKG9wdHMpIHtcbiAgLy8gYWxsb3cgc3RyaW5ncyBzdGFydGluZyB3aXRoICctJywgc2VlIGlzc3VlICMyMFxuICB2YXIgbWVzc2FnZXMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgb3B0cyA/IDAgOiAxKTtcbiAgdmFyIG9wdGlvbnMgPSB7fTtcblxuICAvLyBJZiB0aGUgZmlyc3QgYXJndW1lbnQgc3RhcnRzIHdpdGggJy0nLCBwYXJzZSBpdCBhcyBvcHRpb25zIHN0cmluZy5cbiAgLy8gSWYgcGFyc2VPcHRpb25zIHRocm93cywgaXQgd2Fzbid0IGFuIG9wdGlvbnMgc3RyaW5nLlxuICB0cnkge1xuICAgIG9wdGlvbnMgPSBjb21tb24ucGFyc2VPcHRpb25zKG1lc3NhZ2VzWzBdLCB7XG4gICAgICAnZSc6ICdlc2NhcGVzJyxcbiAgICAgICduJzogJ25vX25ld2xpbmUnLFxuICAgIH0sIHtcbiAgICAgIHNpbGVudDogdHJ1ZSxcbiAgICB9KTtcblxuICAgIC8vIEFsbG93IG51bGwgdG8gYmUgZWNob2VkXG4gICAgaWYgKG1lc3NhZ2VzWzBdKSB7XG4gICAgICBtZXNzYWdlcy5zaGlmdCgpO1xuICAgIH1cbiAgfSBjYXRjaCAoXykge1xuICAgIC8vIENsZWFyIG91dCBlcnJvciBpZiBhbiBlcnJvciBvY2N1cnJlZFxuICAgIGNvbW1vbi5zdGF0ZS5lcnJvciA9IG51bGw7XG4gIH1cblxuICB2YXIgb3V0cHV0ID0gZm9ybWF0LmFwcGx5KG51bGwsIG1lc3NhZ2VzKTtcblxuICAvLyBBZGQgbmV3bGluZSBpZiAtbiBpcyBub3QgcGFzc2VkLlxuICBpZiAoIW9wdGlvbnMubm9fbmV3bGluZSkge1xuICAgIG91dHB1dCArPSAnXFxuJztcbiAgfVxuXG4gIHByb2Nlc3Muc3Rkb3V0LndyaXRlKG91dHB1dCk7XG5cbiAgcmV0dXJuIG91dHB1dDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfZWNobztcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xuXG4vL0Bcbi8vQCAjIyMgZXJyb3IoKVxuLy9AXG4vL0AgVGVzdHMgaWYgZXJyb3Igb2NjdXJyZWQgaW4gdGhlIGxhc3QgY29tbWFuZC4gUmV0dXJucyBhIHRydXRoeSB2YWx1ZSBpZiBhblxuLy9AIGVycm9yIHJldHVybmVkLCBvciBhIGZhbHN5IHZhbHVlIG90aGVyd2lzZS5cbi8vQFxuLy9AICoqTm90ZSoqOiBkbyBub3QgcmVseSBvbiB0aGVcbi8vQCByZXR1cm4gdmFsdWUgdG8gYmUgYW4gZXJyb3IgbWVzc2FnZS4gSWYgeW91IG5lZWQgdGhlIGxhc3QgZXJyb3IgbWVzc2FnZSwgdXNlXG4vL0AgdGhlIGAuc3RkZXJyYCBhdHRyaWJ1dGUgZnJvbSB0aGUgbGFzdCBjb21tYW5kJ3MgcmV0dXJuIHZhbHVlIGluc3RlYWQuXG5mdW5jdGlvbiBlcnJvcigpIHtcbiAgcmV0dXJuIGNvbW1vbi5zdGF0ZS5lcnJvcjtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXJyb3I7XG4iLCJpZiAocmVxdWlyZS5tYWluICE9PSBtb2R1bGUpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIGZpbGUgc2hvdWxkIG5vdCBiZSByZXF1aXJlZCcpO1xufVxuXG52YXIgY2hpbGRQcm9jZXNzID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcblxudmFyIHBhcmFtRmlsZVBhdGggPSBwcm9jZXNzLmFyZ3ZbMl07XG5cbnZhciBzZXJpYWxpemVkUGFyYW1zID0gZnMucmVhZEZpbGVTeW5jKHBhcmFtRmlsZVBhdGgsICd1dGY4Jyk7XG52YXIgcGFyYW1zID0gSlNPTi5wYXJzZShzZXJpYWxpemVkUGFyYW1zKTtcblxudmFyIGNtZCA9IHBhcmFtcy5jb21tYW5kO1xudmFyIGV4ZWNPcHRpb25zID0gcGFyYW1zLmV4ZWNPcHRpb25zO1xudmFyIHBpcGUgPSBwYXJhbXMucGlwZTtcbnZhciBzdGRvdXRGaWxlID0gcGFyYW1zLnN0ZG91dEZpbGU7XG52YXIgc3RkZXJyRmlsZSA9IHBhcmFtcy5zdGRlcnJGaWxlO1xuXG52YXIgYyA9IGNoaWxkUHJvY2Vzcy5leGVjKGNtZCwgZXhlY09wdGlvbnMsIGZ1bmN0aW9uIChlcnIpIHtcbiAgaWYgKCFlcnIpIHtcbiAgICBwcm9jZXNzLmV4aXRDb2RlID0gMDtcbiAgfSBlbHNlIGlmIChlcnIuY29kZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcHJvY2Vzcy5leGl0Q29kZSA9IDE7XG4gIH0gZWxzZSB7XG4gICAgcHJvY2Vzcy5leGl0Q29kZSA9IGVyci5jb2RlO1xuICB9XG59KTtcblxudmFyIHN0ZG91dFN0cmVhbSA9IGZzLmNyZWF0ZVdyaXRlU3RyZWFtKHN0ZG91dEZpbGUpO1xudmFyIHN0ZGVyclN0cmVhbSA9IGZzLmNyZWF0ZVdyaXRlU3RyZWFtKHN0ZGVyckZpbGUpO1xuXG5jLnN0ZG91dC5waXBlKHN0ZG91dFN0cmVhbSk7XG5jLnN0ZGVyci5waXBlKHN0ZGVyclN0cmVhbSk7XG5jLnN0ZG91dC5waXBlKHByb2Nlc3Muc3Rkb3V0KTtcbmMuc3RkZXJyLnBpcGUocHJvY2Vzcy5zdGRlcnIpO1xuXG5pZiAocGlwZSkge1xuICBjLnN0ZGluLmVuZChwaXBlKTtcbn1cbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIF90ZW1wRGlyID0gcmVxdWlyZSgnLi90ZW1wZGlyJykudGVtcERpcjtcbnZhciBfcHdkID0gcmVxdWlyZSgnLi9wd2QnKTtcbnZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcbnZhciBjaGlsZCA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKTtcblxudmFyIERFRkFVTFRfTUFYQlVGRkVSX1NJWkUgPSAyMCAqIDEwMjQgKiAxMDI0O1xudmFyIERFRkFVTFRfRVJST1JfQ09ERSA9IDE7XG5cbmNvbW1vbi5yZWdpc3RlcignZXhlYycsIF9leGVjLCB7XG4gIHVuaXg6IGZhbHNlLFxuICBjYW5SZWNlaXZlUGlwZTogdHJ1ZSxcbiAgd3JhcE91dHB1dDogZmFsc2UsXG59KTtcblxuLy8gV2UgdXNlIHRoaXMgZnVuY3Rpb24gdG8gcnVuIGBleGVjYCBzeW5jaHJvbm91c2x5IHdoaWxlIGFsc28gcHJvdmlkaW5nIHJlYWx0aW1lXG4vLyBvdXRwdXQuXG5mdW5jdGlvbiBleGVjU3luYyhjbWQsIG9wdHMsIHBpcGUpIHtcbiAgaWYgKCFjb21tb24uY29uZmlnLmV4ZWNQYXRoKSB7XG4gICAgY29tbW9uLmVycm9yKCdVbmFibGUgdG8gZmluZCBhIHBhdGggdG8gdGhlIG5vZGUgYmluYXJ5LiBQbGVhc2UgbWFudWFsbHkgc2V0IGNvbmZpZy5leGVjUGF0aCcpO1xuICB9XG5cbiAgdmFyIHRlbXBEaXIgPSBfdGVtcERpcigpO1xuICB2YXIgcGFyYW1zRmlsZSA9IHBhdGgucmVzb2x2ZSh0ZW1wRGlyICsgJy8nICsgY29tbW9uLnJhbmRvbUZpbGVOYW1lKCkpO1xuICB2YXIgc3RkZXJyRmlsZSA9IHBhdGgucmVzb2x2ZSh0ZW1wRGlyICsgJy8nICsgY29tbW9uLnJhbmRvbUZpbGVOYW1lKCkpO1xuICB2YXIgc3Rkb3V0RmlsZSA9IHBhdGgucmVzb2x2ZSh0ZW1wRGlyICsgJy8nICsgY29tbW9uLnJhbmRvbUZpbGVOYW1lKCkpO1xuXG4gIG9wdHMgPSBjb21tb24uZXh0ZW5kKHtcbiAgICBzaWxlbnQ6IGNvbW1vbi5jb25maWcuc2lsZW50LFxuICAgIGN3ZDogX3B3ZCgpLnRvU3RyaW5nKCksXG4gICAgZW52OiBwcm9jZXNzLmVudixcbiAgICBtYXhCdWZmZXI6IERFRkFVTFRfTUFYQlVGRkVSX1NJWkUsXG4gICAgZW5jb2Rpbmc6ICd1dGY4JyxcbiAgfSwgb3B0cyk7XG5cbiAgaWYgKGZzLmV4aXN0c1N5bmMocGFyYW1zRmlsZSkpIGNvbW1vbi51bmxpbmtTeW5jKHBhcmFtc0ZpbGUpO1xuICBpZiAoZnMuZXhpc3RzU3luYyhzdGRlcnJGaWxlKSkgY29tbW9uLnVubGlua1N5bmMoc3RkZXJyRmlsZSk7XG4gIGlmIChmcy5leGlzdHNTeW5jKHN0ZG91dEZpbGUpKSBjb21tb24udW5saW5rU3luYyhzdGRvdXRGaWxlKTtcblxuICBvcHRzLmN3ZCA9IHBhdGgucmVzb2x2ZShvcHRzLmN3ZCk7XG5cbiAgdmFyIHBhcmFtc1RvU2VyaWFsaXplID0ge1xuICAgIGNvbW1hbmQ6IGNtZCxcbiAgICBleGVjT3B0aW9uczogb3B0cyxcbiAgICBwaXBlOiBwaXBlLFxuICAgIHN0ZG91dEZpbGU6IHN0ZG91dEZpbGUsXG4gICAgc3RkZXJyRmlsZTogc3RkZXJyRmlsZSxcbiAgfTtcblxuICBmcy53cml0ZUZpbGVTeW5jKHBhcmFtc0ZpbGUsIEpTT04uc3RyaW5naWZ5KHBhcmFtc1RvU2VyaWFsaXplKSwgJ3V0ZjgnKTtcblxuICB2YXIgZXhlY0FyZ3MgPSBbXG4gICAgcGF0aC5qb2luKF9fZGlybmFtZSwgJ2V4ZWMtY2hpbGQuanMnKSxcbiAgICBwYXJhbXNGaWxlLFxuICBdO1xuXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gIGlmIChvcHRzLnNpbGVudCkge1xuICAgIG9wdHMuc3RkaW8gPSAnaWdub3JlJztcbiAgfSBlbHNlIHtcbiAgICBvcHRzLnN0ZGlvID0gWzAsIDEsIDJdO1xuICB9XG5cbiAgdmFyIGNvZGUgPSAwO1xuXG4gIC8vIFdlbGNvbWUgdG8gdGhlIGZ1dHVyZVxuICB0cnkge1xuICAgIC8vIEJhZCB0aGluZ3MgaWYgd2UgcGFzcyBpbiBhIGBzaGVsbGAgb3B0aW9uIHRvIGNoaWxkX3Byb2Nlc3MuZXhlY0ZpbGVTeW5jLFxuICAgIC8vIHNvIHdlIG5lZWQgdG8gZXhwbGljaXRseSByZW1vdmUgaXQgaGVyZS5cbiAgICBkZWxldGUgb3B0cy5zaGVsbDtcblxuICAgIGNoaWxkLmV4ZWNGaWxlU3luYyhjb21tb24uY29uZmlnLmV4ZWNQYXRoLCBleGVjQXJncywgb3B0cyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBDb21tYW5kcyB3aXRoIG5vbi16ZXJvIGV4aXQgY29kZSByYWlzZSBhbiBleGNlcHRpb24uXG4gICAgY29kZSA9IGUuc3RhdHVzIHx8IERFRkFVTFRfRVJST1JfQ09ERTtcbiAgfVxuXG4gIC8vIGZzLnJlYWRGaWxlU3luYyB1c2VzIGJ1ZmZlciBlbmNvZGluZyBieSBkZWZhdWx0LCBzbyBjYWxsXG4gIC8vIGl0IHdpdGhvdXQgdGhlIGVuY29kaW5nIG9wdGlvbiBpZiB0aGUgZW5jb2RpbmcgaXMgJ2J1ZmZlcicuXG4gIC8vIEFsc28sIGlmIHRoZSBleGVjIHRpbWVvdXQgaXMgdG9vIHNob3J0IGZvciBub2RlIHRvIHN0YXJ0IHVwLFxuICAvLyB0aGUgZmlsZXMgd2lsbCBub3QgYmUgY3JlYXRlZCwgc28gdGhlc2UgY2FsbHMgd2lsbCB0aHJvdy5cbiAgdmFyIHN0ZG91dCA9ICcnO1xuICB2YXIgc3RkZXJyID0gJyc7XG4gIGlmIChvcHRzLmVuY29kaW5nID09PSAnYnVmZmVyJykge1xuICAgIHN0ZG91dCA9IGZzLnJlYWRGaWxlU3luYyhzdGRvdXRGaWxlKTtcbiAgICBzdGRlcnIgPSBmcy5yZWFkRmlsZVN5bmMoc3RkZXJyRmlsZSk7XG4gIH0gZWxzZSB7XG4gICAgc3Rkb3V0ID0gZnMucmVhZEZpbGVTeW5jKHN0ZG91dEZpbGUsIG9wdHMuZW5jb2RpbmcpO1xuICAgIHN0ZGVyciA9IGZzLnJlYWRGaWxlU3luYyhzdGRlcnJGaWxlLCBvcHRzLmVuY29kaW5nKTtcbiAgfVxuXG4gIC8vIE5vIGJpZ2dpZSBpZiB3ZSBjYW4ndCBlcmFzZSB0aGUgZmlsZXMgbm93IC0tIHRoZXkncmUgaW4gYSB0ZW1wIGRpciBhbnl3YXlcbiAgdHJ5IHsgY29tbW9uLnVubGlua1N5bmMocGFyYW1zRmlsZSk7IH0gY2F0Y2ggKGUpIHt9XG4gIHRyeSB7IGNvbW1vbi51bmxpbmtTeW5jKHN0ZGVyckZpbGUpOyB9IGNhdGNoIChlKSB7fVxuICB0cnkgeyBjb21tb24udW5saW5rU3luYyhzdGRvdXRGaWxlKTsgfSBjYXRjaCAoZSkge31cblxuICBpZiAoY29kZSAhPT0gMCkge1xuICAgIC8vIE5vdGU6IGBzaWxlbnRgIHNob3VsZCBiZSB1bmNvbmRpdGlvbmFsbHkgdHJ1ZSB0byBhdm9pZCBkb3VibGUtcHJpbnRpbmdcbiAgICAvLyB0aGUgY29tbWFuZCdzIHN0ZGVyciwgYW5kIHRvIGF2b2lkIHByaW50aW5nIGFueSBzdGRlcnIgd2hlbiB0aGUgdXNlciBoYXNcbiAgICAvLyBzZXQgYHNoZWxsLmNvbmZpZy5zaWxlbnRgLlxuICAgIGNvbW1vbi5lcnJvcihzdGRlcnIsIGNvZGUsIHsgY29udGludWU6IHRydWUsIHNpbGVudDogdHJ1ZSB9KTtcbiAgfVxuICB2YXIgb2JqID0gY29tbW9uLlNoZWxsU3RyaW5nKHN0ZG91dCwgc3RkZXJyLCBjb2RlKTtcbiAgcmV0dXJuIG9iajtcbn0gLy8gZXhlY1N5bmMoKVxuXG4vLyBXcmFwcGVyIGFyb3VuZCBleGVjKCkgdG8gZW5hYmxlIGVjaG9pbmcgb3V0cHV0IHRvIGNvbnNvbGUgaW4gcmVhbCB0aW1lXG5mdW5jdGlvbiBleGVjQXN5bmMoY21kLCBvcHRzLCBwaXBlLCBjYWxsYmFjaykge1xuICBvcHRzID0gY29tbW9uLmV4dGVuZCh7XG4gICAgc2lsZW50OiBjb21tb24uY29uZmlnLnNpbGVudCxcbiAgICBjd2Q6IF9wd2QoKS50b1N0cmluZygpLFxuICAgIGVudjogcHJvY2Vzcy5lbnYsXG4gICAgbWF4QnVmZmVyOiBERUZBVUxUX01BWEJVRkZFUl9TSVpFLFxuICAgIGVuY29kaW5nOiAndXRmOCcsXG4gIH0sIG9wdHMpO1xuXG4gIHZhciBjID0gY2hpbGQuZXhlYyhjbWQsIG9wdHMsIGZ1bmN0aW9uIChlcnIsIHN0ZG91dCwgc3RkZXJyKSB7XG4gICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICBpZiAoIWVycikge1xuICAgICAgICBjYWxsYmFjaygwLCBzdGRvdXQsIHN0ZGVycik7XG4gICAgICB9IGVsc2UgaWYgKGVyci5jb2RlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gU2VlIGlzc3VlICM1MzZcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgY2FsbGJhY2soMSwgc3Rkb3V0LCBzdGRlcnIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FsbGJhY2soZXJyLmNvZGUsIHN0ZG91dCwgc3RkZXJyKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIGlmIChwaXBlKSBjLnN0ZGluLmVuZChwaXBlKTtcblxuICBpZiAoIW9wdHMuc2lsZW50KSB7XG4gICAgYy5zdGRvdXQucGlwZShwcm9jZXNzLnN0ZG91dCk7XG4gICAgYy5zdGRlcnIucGlwZShwcm9jZXNzLnN0ZGVycik7XG4gIH1cblxuICByZXR1cm4gYztcbn1cblxuLy9AXG4vL0AgIyMjIGV4ZWMoY29tbWFuZCBbLCBvcHRpb25zXSBbLCBjYWxsYmFja10pXG4vL0Bcbi8vQCBBdmFpbGFibGUgb3B0aW9uczpcbi8vQFxuLy9AICsgYGFzeW5jYDogQXN5bmNocm9ub3VzIGV4ZWN1dGlvbi4gSWYgYSBjYWxsYmFjayBpcyBwcm92aWRlZCwgaXQgd2lsbCBiZSBzZXQgdG9cbi8vQCAgIGB0cnVlYCwgcmVnYXJkbGVzcyBvZiB0aGUgcGFzc2VkIHZhbHVlIChkZWZhdWx0OiBgZmFsc2VgKS5cbi8vQCArIGBzaWxlbnRgOiBEbyBub3QgZWNobyBwcm9ncmFtIG91dHB1dCB0byBjb25zb2xlIChkZWZhdWx0OiBgZmFsc2VgKS5cbi8vQCArIGBlbmNvZGluZ2A6IENoYXJhY3RlciBlbmNvZGluZyB0byB1c2UuIEFmZmVjdHMgdGhlIHZhbHVlcyByZXR1cm5lZCB0byBzdGRvdXQgYW5kIHN0ZGVyciwgYW5kXG4vL0AgICB3aGF0IGlzIHdyaXR0ZW4gdG8gc3Rkb3V0IGFuZCBzdGRlcnIgd2hlbiBub3QgaW4gc2lsZW50IG1vZGUgKGRlZmF1bHQ6IGAndXRmOCdgKS5cbi8vQCArIGFuZCBhbnkgb3B0aW9uIGF2YWlsYWJsZSB0byBOb2RlLmpzJ3Ncbi8vQCAgIFtgY2hpbGRfcHJvY2Vzcy5leGVjKClgXShodHRwczovL25vZGVqcy5vcmcvYXBpL2NoaWxkX3Byb2Nlc3MuaHRtbCNjaGlsZF9wcm9jZXNzX2NoaWxkX3Byb2Nlc3NfZXhlY19jb21tYW5kX29wdGlvbnNfY2FsbGJhY2spXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCB2YXIgdmVyc2lvbiA9IGV4ZWMoJ25vZGUgLS12ZXJzaW9uJywge3NpbGVudDp0cnVlfSkuc3Rkb3V0O1xuLy9AXG4vL0AgdmFyIGNoaWxkID0gZXhlYygnc29tZV9sb25nX3J1bm5pbmdfcHJvY2VzcycsIHthc3luYzp0cnVlfSk7XG4vL0AgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgZnVuY3Rpb24oZGF0YSkge1xuLy9AICAgLyogLi4uIGRvIHNvbWV0aGluZyB3aXRoIGRhdGEgLi4uICovXG4vL0AgfSk7XG4vL0Bcbi8vQCBleGVjKCdzb21lX2xvbmdfcnVubmluZ19wcm9jZXNzJywgZnVuY3Rpb24oY29kZSwgc3Rkb3V0LCBzdGRlcnIpIHtcbi8vQCAgIGNvbnNvbGUubG9nKCdFeGl0IGNvZGU6JywgY29kZSk7XG4vL0AgICBjb25zb2xlLmxvZygnUHJvZ3JhbSBvdXRwdXQ6Jywgc3Rkb3V0KTtcbi8vQCAgIGNvbnNvbGUubG9nKCdQcm9ncmFtIHN0ZGVycjonLCBzdGRlcnIpO1xuLy9AIH0pO1xuLy9AIGBgYFxuLy9AXG4vL0AgRXhlY3V0ZXMgdGhlIGdpdmVuIGBjb21tYW5kYCBfc3luY2hyb25vdXNseV8sIHVubGVzcyBvdGhlcndpc2Ugc3BlY2lmaWVkLiAgV2hlbiBpbiBzeW5jaHJvbm91c1xuLy9AIG1vZGUsIHRoaXMgcmV0dXJucyBhIGBTaGVsbFN0cmluZ2AgKGNvbXBhdGlibGUgd2l0aCBTaGVsbEpTIHYwLjYueCwgd2hpY2ggcmV0dXJucyBhbiBvYmplY3Rcbi8vQCBvZiB0aGUgZm9ybSBgeyBjb2RlOi4uLiwgc3Rkb3V0Oi4uLiAsIHN0ZGVycjouLi4gfWApLiBPdGhlcndpc2UsIHRoaXMgcmV0dXJucyB0aGUgY2hpbGQgcHJvY2Vzc1xuLy9AIG9iamVjdCwgYW5kIHRoZSBgY2FsbGJhY2tgIHJlY2VpdmVzIHRoZSBhcmd1bWVudHMgYChjb2RlLCBzdGRvdXQsIHN0ZGVycilgLlxuLy9AXG4vL0AgTm90IHNlZWluZyB0aGUgYmVoYXZpb3IgeW91IHdhbnQ/IGBleGVjKClgIHJ1bnMgZXZlcnl0aGluZyB0aHJvdWdoIGBzaGBcbi8vQCBieSBkZWZhdWx0IChvciBgY21kLmV4ZWAgb24gV2luZG93cyksIHdoaWNoIGRpZmZlcnMgZnJvbSBgYmFzaGAuIElmIHlvdVxuLy9AIG5lZWQgYmFzaC1zcGVjaWZpYyBiZWhhdmlvciwgdHJ5IG91dCB0aGUgYHtzaGVsbDogJ3BhdGgvdG8vYmFzaCd9YCBvcHRpb24uXG5mdW5jdGlvbiBfZXhlYyhjb21tYW5kLCBvcHRpb25zLCBjYWxsYmFjaykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgaWYgKCFjb21tYW5kKSBjb21tb24uZXJyb3IoJ211c3Qgc3BlY2lmeSBjb21tYW5kJyk7XG5cbiAgdmFyIHBpcGUgPSBjb21tb24ucmVhZEZyb21QaXBlKCk7XG5cbiAgLy8gQ2FsbGJhY2sgaXMgZGVmaW5lZCBpbnN0ZWFkIG9mIG9wdGlvbnMuXG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNhbGxiYWNrID0gb3B0aW9ucztcbiAgICBvcHRpb25zID0geyBhc3luYzogdHJ1ZSB9O1xuICB9XG5cbiAgLy8gQ2FsbGJhY2sgaXMgZGVmaW5lZCB3aXRoIG9wdGlvbnMuXG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgb3B0aW9ucy5hc3luYyA9IHRydWU7XG4gIH1cblxuICBvcHRpb25zID0gY29tbW9uLmV4dGVuZCh7XG4gICAgc2lsZW50OiBjb21tb24uY29uZmlnLnNpbGVudCxcbiAgICBhc3luYzogZmFsc2UsXG4gIH0sIG9wdGlvbnMpO1xuXG4gIGlmIChvcHRpb25zLmFzeW5jKSB7XG4gICAgcmV0dXJuIGV4ZWNBc3luYyhjb21tYW5kLCBvcHRpb25zLCBwaXBlLCBjYWxsYmFjayk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGV4ZWNTeW5jKGNvbW1hbmQsIG9wdGlvbnMsIHBpcGUpO1xuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IF9leGVjO1xuIiwidmFyIHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBfbHMgPSByZXF1aXJlKCcuL2xzJyk7XG5cbmNvbW1vbi5yZWdpc3RlcignZmluZCcsIF9maW5kLCB7fSk7XG5cbi8vQFxuLy9AICMjIyBmaW5kKHBhdGggWywgcGF0aCAuLi5dKVxuLy9AICMjIyBmaW5kKHBhdGhfYXJyYXkpXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBmaW5kKCdzcmMnLCAnbGliJyk7XG4vL0AgZmluZChbJ3NyYycsICdsaWInXSk7IC8vIHNhbWUgYXMgYWJvdmVcbi8vQCBmaW5kKCcuJykuZmlsdGVyKGZ1bmN0aW9uKGZpbGUpIHsgcmV0dXJuIGZpbGUubWF0Y2goL1xcLmpzJC8pOyB9KTtcbi8vQCBgYGBcbi8vQFxuLy9AIFJldHVybnMgYXJyYXkgb2YgYWxsIGZpbGVzIChob3dldmVyIGRlZXApIGluIHRoZSBnaXZlbiBwYXRocy5cbi8vQFxuLy9AIFRoZSBtYWluIGRpZmZlcmVuY2UgZnJvbSBgbHMoJy1SJywgcGF0aClgIGlzIHRoYXQgdGhlIHJlc3VsdGluZyBmaWxlIG5hbWVzXG4vL0AgaW5jbHVkZSB0aGUgYmFzZSBkaXJlY3RvcmllcyAoZS5nLiwgYGxpYi9yZXNvdXJjZXMvZmlsZTFgIGluc3RlYWQgb2YganVzdCBgZmlsZTFgKS5cbmZ1bmN0aW9uIF9maW5kKG9wdGlvbnMsIHBhdGhzKSB7XG4gIGlmICghcGF0aHMpIHtcbiAgICBjb21tb24uZXJyb3IoJ25vIHBhdGggc3BlY2lmaWVkJyk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIHBhdGhzID09PSAnc3RyaW5nJykge1xuICAgIHBhdGhzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICB9XG5cbiAgdmFyIGxpc3QgPSBbXTtcblxuICBmdW5jdGlvbiBwdXNoRmlsZShmaWxlKSB7XG4gICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT09ICd3aW4zMicpIHtcbiAgICAgIGZpbGUgPSBmaWxlLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcbiAgICB9XG4gICAgbGlzdC5wdXNoKGZpbGUpO1xuICB9XG5cbiAgLy8gd2h5IG5vdCBzaW1wbHkgZG8gYGxzKCctUicsIHBhdGhzKWA/IGJlY2F1c2UgdGhlIG91dHB1dCB3b3VsZG4ndCBnaXZlIHRoZSBiYXNlIGRpcnNcbiAgLy8gdG8gZ2V0IHRoZSBiYXNlIGRpciBpbiB0aGUgb3V0cHV0LCB3ZSBuZWVkIGluc3RlYWQgYGxzKCctUicsICdkaXIvKicpYCBmb3IgZXZlcnkgZGlyZWN0b3J5XG5cbiAgcGF0aHMuZm9yRWFjaChmdW5jdGlvbiAoZmlsZSkge1xuICAgIHZhciBzdGF0O1xuICAgIHRyeSB7XG4gICAgICBzdGF0ID0gY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhmaWxlKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb21tb24uZXJyb3IoJ25vIHN1Y2ggZmlsZSBvciBkaXJlY3Rvcnk6ICcgKyBmaWxlKTtcbiAgICB9XG5cbiAgICBwdXNoRmlsZShmaWxlKTtcblxuICAgIGlmIChzdGF0LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgIF9scyh7IHJlY3Vyc2l2ZTogdHJ1ZSwgYWxsOiB0cnVlIH0sIGZpbGUpLmZvckVhY2goZnVuY3Rpb24gKHN1YmZpbGUpIHtcbiAgICAgICAgcHVzaEZpbGUocGF0aC5qb2luKGZpbGUsIHN1YmZpbGUpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGxpc3Q7XG59XG5tb2R1bGUuZXhwb3J0cyA9IF9maW5kO1xuIiwidmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgZnMgPSByZXF1aXJlKCdmcycpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ2dyZXAnLCBfZ3JlcCwge1xuICBnbG9iU3RhcnQ6IDIsIC8vIGRvbid0IGdsb2ItZXhwYW5kIHRoZSByZWdleFxuICBjYW5SZWNlaXZlUGlwZTogdHJ1ZSxcbiAgY21kT3B0aW9uczoge1xuICAgICd2JzogJ2ludmVyc2UnLFxuICAgICdsJzogJ25hbWVPbmx5JyxcbiAgICAnaSc6ICdpZ25vcmVDYXNlJyxcbiAgfSxcbn0pO1xuXG4vL0Bcbi8vQCAjIyMgZ3JlcChbb3B0aW9ucyxdIHJlZ2V4X2ZpbHRlciwgZmlsZSBbLCBmaWxlIC4uLl0pXG4vL0AgIyMjIGdyZXAoW29wdGlvbnMsXSByZWdleF9maWx0ZXIsIGZpbGVfYXJyYXkpXG4vL0Bcbi8vQCBBdmFpbGFibGUgb3B0aW9uczpcbi8vQFxuLy9AICsgYC12YDogSW52ZXJ0IGByZWdleF9maWx0ZXJgIChvbmx5IHByaW50IG5vbi1tYXRjaGluZyBsaW5lcykuXG4vL0AgKyBgLWxgOiBQcmludCBvbmx5IGZpbGVuYW1lcyBvZiBtYXRjaGluZyBmaWxlcy5cbi8vQCArIGAtaWA6IElnbm9yZSBjYXNlLlxuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgZ3JlcCgnLXYnLCAnR0xPQkFMX1ZBUklBQkxFJywgJyouanMnKTtcbi8vQCBncmVwKCdHTE9CQUxfVkFSSUFCTEUnLCAnKi5qcycpO1xuLy9AIGBgYFxuLy9AXG4vL0AgUmVhZHMgaW5wdXQgc3RyaW5nIGZyb20gZ2l2ZW4gZmlsZXMgYW5kIHJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyBhbGwgbGluZXMgb2YgdGhlXG4vL0AgZmlsZSB0aGF0IG1hdGNoIHRoZSBnaXZlbiBgcmVnZXhfZmlsdGVyYC5cbmZ1bmN0aW9uIF9ncmVwKG9wdGlvbnMsIHJlZ2V4LCBmaWxlcykge1xuICAvLyBDaGVjayBpZiB0aGlzIGlzIGNvbWluZyBmcm9tIGEgcGlwZVxuICB2YXIgcGlwZSA9IGNvbW1vbi5yZWFkRnJvbVBpcGUoKTtcblxuICBpZiAoIWZpbGVzICYmICFwaXBlKSBjb21tb24uZXJyb3IoJ25vIHBhdGhzIGdpdmVuJywgMik7XG5cbiAgZmlsZXMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMik7XG5cbiAgaWYgKHBpcGUpIHtcbiAgICBmaWxlcy51bnNoaWZ0KCctJyk7XG4gIH1cblxuICB2YXIgZ3JlcCA9IFtdO1xuICBpZiAob3B0aW9ucy5pZ25vcmVDYXNlKSB7XG4gICAgcmVnZXggPSBuZXcgUmVnRXhwKHJlZ2V4LCAnaScpO1xuICB9XG4gIGZpbGVzLmZvckVhY2goZnVuY3Rpb24gKGZpbGUpIHtcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZmlsZSkgJiYgZmlsZSAhPT0gJy0nKSB7XG4gICAgICBjb21tb24uZXJyb3IoJ25vIHN1Y2ggZmlsZSBvciBkaXJlY3Rvcnk6ICcgKyBmaWxlLCAyLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBjb250ZW50cyA9IGZpbGUgPT09ICctJyA/IHBpcGUgOiBmcy5yZWFkRmlsZVN5bmMoZmlsZSwgJ3V0ZjgnKTtcbiAgICBpZiAob3B0aW9ucy5uYW1lT25seSkge1xuICAgICAgaWYgKGNvbnRlbnRzLm1hdGNoKHJlZ2V4KSkge1xuICAgICAgICBncmVwLnB1c2goZmlsZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBsaW5lcyA9IGNvbnRlbnRzLnNwbGl0KCdcXG4nKTtcbiAgICAgIGxpbmVzLmZvckVhY2goZnVuY3Rpb24gKGxpbmUpIHtcbiAgICAgICAgdmFyIG1hdGNoZWQgPSBsaW5lLm1hdGNoKHJlZ2V4KTtcbiAgICAgICAgaWYgKChvcHRpb25zLmludmVyc2UgJiYgIW1hdGNoZWQpIHx8ICghb3B0aW9ucy5pbnZlcnNlICYmIG1hdGNoZWQpKSB7XG4gICAgICAgICAgZ3JlcC5wdXNoKGxpbmUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBncmVwLmpvaW4oJ1xcbicpICsgJ1xcbic7XG59XG5tb2R1bGUuZXhwb3J0cyA9IF9ncmVwO1xuIiwidmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgZnMgPSByZXF1aXJlKCdmcycpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ2hlYWQnLCBfaGVhZCwge1xuICBjYW5SZWNlaXZlUGlwZTogdHJ1ZSxcbiAgY21kT3B0aW9uczoge1xuICAgICduJzogJ251bUxpbmVzJyxcbiAgfSxcbn0pO1xuXG4vLyBSZWFkcyB8bnVtTGluZXN8IGxpbmVzIG9yIHRoZSBlbnRpcmUgZmlsZSwgd2hpY2hldmVyIGlzIGxlc3MuXG5mdW5jdGlvbiByZWFkU29tZUxpbmVzKGZpbGUsIG51bUxpbmVzKSB7XG4gIHZhciBidWYgPSBjb21tb24uYnVmZmVyKCk7XG4gIHZhciBidWZMZW5ndGggPSBidWYubGVuZ3RoO1xuICB2YXIgYnl0ZXNSZWFkID0gYnVmTGVuZ3RoO1xuICB2YXIgcG9zID0gMDtcblxuICB2YXIgZmRyID0gZnMub3BlblN5bmMoZmlsZSwgJ3InKTtcbiAgdmFyIG51bUxpbmVzUmVhZCA9IDA7XG4gIHZhciByZXQgPSAnJztcbiAgd2hpbGUgKGJ5dGVzUmVhZCA9PT0gYnVmTGVuZ3RoICYmIG51bUxpbmVzUmVhZCA8IG51bUxpbmVzKSB7XG4gICAgYnl0ZXNSZWFkID0gZnMucmVhZFN5bmMoZmRyLCBidWYsIDAsIGJ1Zkxlbmd0aCwgcG9zKTtcbiAgICB2YXIgYnVmU3RyID0gYnVmLnRvU3RyaW5nKCd1dGY4JywgMCwgYnl0ZXNSZWFkKTtcbiAgICBudW1MaW5lc1JlYWQgKz0gYnVmU3RyLnNwbGl0KCdcXG4nKS5sZW5ndGggLSAxO1xuICAgIHJldCArPSBidWZTdHI7XG4gICAgcG9zICs9IGJ5dGVzUmVhZDtcbiAgfVxuXG4gIGZzLmNsb3NlU3luYyhmZHIpO1xuICByZXR1cm4gcmV0O1xufVxuXG4vL0Bcbi8vQCAjIyMgaGVhZChbeyctbic6IFxcPG51bVxcPn0sXSBmaWxlIFssIGZpbGUgLi4uXSlcbi8vQCAjIyMgaGVhZChbeyctbic6IFxcPG51bVxcPn0sXSBmaWxlX2FycmF5KVxuLy9AXG4vL0AgQXZhaWxhYmxlIG9wdGlvbnM6XG4vL0Bcbi8vQCArIGAtbiA8bnVtPmA6IFNob3cgdGhlIGZpcnN0IGA8bnVtPmAgbGluZXMgb2YgdGhlIGZpbGVzXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCB2YXIgc3RyID0gaGVhZCh7Jy1uJzogMX0sICdmaWxlKi50eHQnKTtcbi8vQCB2YXIgc3RyID0gaGVhZCgnZmlsZTEnLCAnZmlsZTInKTtcbi8vQCB2YXIgc3RyID0gaGVhZChbJ2ZpbGUxJywgJ2ZpbGUyJ10pOyAvLyBzYW1lIGFzIGFib3ZlXG4vL0AgYGBgXG4vL0Bcbi8vQCBSZWFkIHRoZSBzdGFydCBvZiBhIGZpbGUuXG5mdW5jdGlvbiBfaGVhZChvcHRpb25zLCBmaWxlcykge1xuICB2YXIgaGVhZCA9IFtdO1xuICB2YXIgcGlwZSA9IGNvbW1vbi5yZWFkRnJvbVBpcGUoKTtcblxuICBpZiAoIWZpbGVzICYmICFwaXBlKSBjb21tb24uZXJyb3IoJ25vIHBhdGhzIGdpdmVuJyk7XG5cbiAgdmFyIGlkeCA9IDE7XG4gIGlmIChvcHRpb25zLm51bUxpbmVzID09PSB0cnVlKSB7XG4gICAgaWR4ID0gMjtcbiAgICBvcHRpb25zLm51bUxpbmVzID0gTnVtYmVyKGFyZ3VtZW50c1sxXSk7XG4gIH0gZWxzZSBpZiAob3B0aW9ucy5udW1MaW5lcyA9PT0gZmFsc2UpIHtcbiAgICBvcHRpb25zLm51bUxpbmVzID0gMTA7XG4gIH1cbiAgZmlsZXMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgaWR4KTtcblxuICBpZiAocGlwZSkge1xuICAgIGZpbGVzLnVuc2hpZnQoJy0nKTtcbiAgfVxuXG4gIHZhciBzaG91bGRBcHBlbmROZXdsaW5lID0gZmFsc2U7XG4gIGZpbGVzLmZvckVhY2goZnVuY3Rpb24gKGZpbGUpIHtcbiAgICBpZiAoZmlsZSAhPT0gJy0nKSB7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZmlsZSkpIHtcbiAgICAgICAgY29tbW9uLmVycm9yKCdubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5OiAnICsgZmlsZSwgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBlbHNlIGlmIChjb21tb24uc3RhdEZvbGxvd0xpbmtzKGZpbGUpLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgY29tbW9uLmVycm9yKFwiZXJyb3IgcmVhZGluZyAnXCIgKyBmaWxlICsgXCInOiBJcyBhIGRpcmVjdG9yeVwiLCB7XG4gICAgICAgICAgY29udGludWU6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGNvbnRlbnRzO1xuICAgIGlmIChmaWxlID09PSAnLScpIHtcbiAgICAgIGNvbnRlbnRzID0gcGlwZTtcbiAgICB9IGVsc2UgaWYgKG9wdGlvbnMubnVtTGluZXMgPCAwKSB7XG4gICAgICBjb250ZW50cyA9IGZzLnJlYWRGaWxlU3luYyhmaWxlLCAndXRmOCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZW50cyA9IHJlYWRTb21lTGluZXMoZmlsZSwgb3B0aW9ucy5udW1MaW5lcyk7XG4gICAgfVxuXG4gICAgdmFyIGxpbmVzID0gY29udGVudHMuc3BsaXQoJ1xcbicpO1xuICAgIHZhciBoYXNUcmFpbGluZ05ld2xpbmUgPSAobGluZXNbbGluZXMubGVuZ3RoIC0gMV0gPT09ICcnKTtcbiAgICBpZiAoaGFzVHJhaWxpbmdOZXdsaW5lKSB7XG4gICAgICBsaW5lcy5wb3AoKTtcbiAgICB9XG4gICAgc2hvdWxkQXBwZW5kTmV3bGluZSA9IChoYXNUcmFpbGluZ05ld2xpbmUgfHwgb3B0aW9ucy5udW1MaW5lcyA8IGxpbmVzLmxlbmd0aCk7XG5cbiAgICBoZWFkID0gaGVhZC5jb25jYXQobGluZXMuc2xpY2UoMCwgb3B0aW9ucy5udW1MaW5lcykpO1xuICB9KTtcblxuICBpZiAoc2hvdWxkQXBwZW5kTmV3bGluZSkge1xuICAgIGhlYWQucHVzaCgnJyk7IC8vIHRvIGFkZCBhIHRyYWlsaW5nIG5ld2xpbmUgb25jZSB3ZSBqb2luXG4gIH1cbiAgcmV0dXJuIGhlYWQuam9pbignXFxuJyk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IF9oZWFkO1xuIiwidmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcbnZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG5cbmNvbW1vbi5yZWdpc3RlcignbG4nLCBfbG4sIHtcbiAgY21kT3B0aW9uczoge1xuICAgICdzJzogJ3N5bWxpbmsnLFxuICAgICdmJzogJ2ZvcmNlJyxcbiAgfSxcbn0pO1xuXG4vL0Bcbi8vQCAjIyMgbG4oW29wdGlvbnMsXSBzb3VyY2UsIGRlc3QpXG4vL0Bcbi8vQCBBdmFpbGFibGUgb3B0aW9uczpcbi8vQFxuLy9AICsgYC1zYDogc3ltbGlua1xuLy9AICsgYC1mYDogZm9yY2Vcbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIGxuKCdmaWxlJywgJ25ld2xpbmsnKTtcbi8vQCBsbignLXNmJywgJ2ZpbGUnLCAnZXhpc3RpbmcnKTtcbi8vQCBgYGBcbi8vQFxuLy9AIExpbmtzIGBzb3VyY2VgIHRvIGBkZXN0YC4gVXNlIGAtZmAgdG8gZm9yY2UgdGhlIGxpbmssIHNob3VsZCBgZGVzdGAgYWxyZWFkeSBleGlzdC5cbmZ1bmN0aW9uIF9sbihvcHRpb25zLCBzb3VyY2UsIGRlc3QpIHtcbiAgaWYgKCFzb3VyY2UgfHwgIWRlc3QpIHtcbiAgICBjb21tb24uZXJyb3IoJ01pc3NpbmcgPHNvdXJjZT4gYW5kL29yIDxkZXN0PicpO1xuICB9XG5cbiAgc291cmNlID0gU3RyaW5nKHNvdXJjZSk7XG4gIHZhciBzb3VyY2VQYXRoID0gcGF0aC5ub3JtYWxpemUoc291cmNlKS5yZXBsYWNlKFJlZ0V4cChwYXRoLnNlcCArICckJyksICcnKTtcbiAgdmFyIGlzQWJzb2x1dGUgPSAocGF0aC5yZXNvbHZlKHNvdXJjZSkgPT09IHNvdXJjZVBhdGgpO1xuICBkZXN0ID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIFN0cmluZyhkZXN0KSk7XG5cbiAgaWYgKGZzLmV4aXN0c1N5bmMoZGVzdCkpIHtcbiAgICBpZiAoIW9wdGlvbnMuZm9yY2UpIHtcbiAgICAgIGNvbW1vbi5lcnJvcignRGVzdGluYXRpb24gZmlsZSBleGlzdHMnLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICAgIH1cblxuICAgIGZzLnVubGlua1N5bmMoZGVzdCk7XG4gIH1cblxuICBpZiAob3B0aW9ucy5zeW1saW5rKSB7XG4gICAgdmFyIGlzV2luZG93cyA9IHByb2Nlc3MucGxhdGZvcm0gPT09ICd3aW4zMic7XG4gICAgdmFyIGxpbmtUeXBlID0gaXNXaW5kb3dzID8gJ2ZpbGUnIDogbnVsbDtcbiAgICB2YXIgcmVzb2x2ZWRTb3VyY2VQYXRoID0gaXNBYnNvbHV0ZSA/IHNvdXJjZVBhdGggOiBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSwgcGF0aC5kaXJuYW1lKGRlc3QpLCBzb3VyY2UpO1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhyZXNvbHZlZFNvdXJjZVBhdGgpKSB7XG4gICAgICBjb21tb24uZXJyb3IoJ1NvdXJjZSBmaWxlIGRvZXMgbm90IGV4aXN0JywgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgICB9IGVsc2UgaWYgKGlzV2luZG93cyAmJiBjb21tb24uc3RhdEZvbGxvd0xpbmtzKHJlc29sdmVkU291cmNlUGF0aCkuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgbGlua1R5cGUgPSAnanVuY3Rpb24nO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBmcy5zeW1saW5rU3luYyhsaW5rVHlwZSA9PT0gJ2p1bmN0aW9uJyA/IHJlc29sdmVkU291cmNlUGF0aCA6IHNvdXJjZSwgZGVzdCwgbGlua1R5cGUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29tbW9uLmVycm9yKGVyci5tZXNzYWdlKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKHNvdXJjZSkpIHtcbiAgICAgIGNvbW1vbi5lcnJvcignU291cmNlIGZpbGUgZG9lcyBub3QgZXhpc3QnLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgZnMubGlua1N5bmMoc291cmNlLCBkZXN0KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbW1vbi5lcnJvcihlcnIubWVzc2FnZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiAnJztcbn1cbm1vZHVsZS5leHBvcnRzID0gX2xuO1xuIiwidmFyIHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG52YXIgZnMgPSByZXF1aXJlKCdmcycpO1xudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgZ2xvYiA9IHJlcXVpcmUoJ2dsb2InKTtcblxudmFyIGdsb2JQYXR0ZXJuUmVjdXJzaXZlID0gcGF0aC5zZXAgKyAnKionO1xuXG5jb21tb24ucmVnaXN0ZXIoJ2xzJywgX2xzLCB7XG4gIGNtZE9wdGlvbnM6IHtcbiAgICAnUic6ICdyZWN1cnNpdmUnLFxuICAgICdBJzogJ2FsbCcsXG4gICAgJ0wnOiAnbGluaycsXG4gICAgJ2EnOiAnYWxsX2RlcHJlY2F0ZWQnLFxuICAgICdkJzogJ2RpcmVjdG9yeScsXG4gICAgJ2wnOiAnbG9uZycsXG4gIH0sXG59KTtcblxuLy9AXG4vL0AgIyMjIGxzKFtvcHRpb25zLF0gW3BhdGgsIC4uLl0pXG4vL0AgIyMjIGxzKFtvcHRpb25zLF0gcGF0aF9hcnJheSlcbi8vQFxuLy9AIEF2YWlsYWJsZSBvcHRpb25zOlxuLy9AXG4vL0AgKyBgLVJgOiByZWN1cnNpdmVcbi8vQCArIGAtQWA6IGFsbCBmaWxlcyAoaW5jbHVkZSBmaWxlcyBiZWdpbm5pbmcgd2l0aCBgLmAsIGV4Y2VwdCBmb3IgYC5gIGFuZCBgLi5gKVxuLy9AICsgYC1MYDogZm9sbG93IHN5bWxpbmtzXG4vL0AgKyBgLWRgOiBsaXN0IGRpcmVjdG9yaWVzIHRoZW1zZWx2ZXMsIG5vdCB0aGVpciBjb250ZW50c1xuLy9AICsgYC1sYDogbGlzdCBvYmplY3RzIHJlcHJlc2VudGluZyBlYWNoIGZpbGUsIGVhY2ggd2l0aCBmaWVsZHMgY29udGFpbmluZyBgbHNcbi8vQCAgICAgICAgIC1sYCBvdXRwdXQgZmllbGRzLiBTZWVcbi8vQCAgICAgICAgIFtgZnMuU3RhdHNgXShodHRwczovL25vZGVqcy5vcmcvYXBpL2ZzLmh0bWwjZnNfY2xhc3NfZnNfc3RhdHMpXG4vL0AgICAgICAgICBmb3IgbW9yZSBpbmZvXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBscygncHJvanMvKi5qcycpO1xuLy9AIGxzKCctUicsICcvdXNlcnMvbWUnLCAnL3RtcCcpO1xuLy9AIGxzKCctUicsIFsnL3VzZXJzL21lJywgJy90bXAnXSk7IC8vIHNhbWUgYXMgYWJvdmVcbi8vQCBscygnLWwnLCAnZmlsZS50eHQnKTsgLy8geyBuYW1lOiAnZmlsZS50eHQnLCBtb2RlOiAzMzE4OCwgbmxpbms6IDEsIC4uLn1cbi8vQCBgYGBcbi8vQFxuLy9AIFJldHVybnMgYXJyYXkgb2YgZmlsZXMgaW4gdGhlIGdpdmVuIGBwYXRoYCwgb3IgZmlsZXMgaW5cbi8vQCB0aGUgY3VycmVudCBkaXJlY3RvcnkgaWYgbm8gYHBhdGhgIGlzICBwcm92aWRlZC5cbmZ1bmN0aW9uIF9scyhvcHRpb25zLCBwYXRocykge1xuICBpZiAob3B0aW9ucy5hbGxfZGVwcmVjYXRlZCkge1xuICAgIC8vIFdlIHdvbid0IHN1cHBvcnQgdGhlIC1hIG9wdGlvbiBhcyBpdCdzIGhhcmQgdG8gaW1hZ2Ugd2h5IGl0J3MgdXNlZnVsXG4gICAgLy8gKGl0IGluY2x1ZGVzICcuJyBhbmQgJy4uJyBpbiBhZGRpdGlvbiB0byAnLionIGZpbGVzKVxuICAgIC8vIEZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSB3ZSdsbCBkdW1wIGEgZGVwcmVjYXRlZCBtZXNzYWdlIGFuZCBwcm9jZWVkIGFzIGJlZm9yZVxuICAgIGNvbW1vbi5sb2coJ2xzOiBPcHRpb24gLWEgaXMgZGVwcmVjYXRlZC4gVXNlIC1BIGluc3RlYWQnKTtcbiAgICBvcHRpb25zLmFsbCA9IHRydWU7XG4gIH1cblxuICBpZiAoIXBhdGhzKSB7XG4gICAgcGF0aHMgPSBbJy4nXTtcbiAgfSBlbHNlIHtcbiAgICBwYXRocyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgfVxuXG4gIHZhciBsaXN0ID0gW107XG5cbiAgZnVuY3Rpb24gcHVzaEZpbGUoYWJzLCByZWxOYW1lLCBzdGF0KSB7XG4gICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT09ICd3aW4zMicpIHtcbiAgICAgIHJlbE5hbWUgPSByZWxOYW1lLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMubG9uZykge1xuICAgICAgc3RhdCA9IHN0YXQgfHwgKG9wdGlvbnMubGluayA/IGNvbW1vbi5zdGF0Rm9sbG93TGlua3MoYWJzKSA6IGNvbW1vbi5zdGF0Tm9Gb2xsb3dMaW5rcyhhYnMpKTtcbiAgICAgIGxpc3QucHVzaChhZGRMc0F0dHJpYnV0ZXMocmVsTmFtZSwgc3RhdCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBsaXN0LnB1c2gocGF0aC5yZWxhdGl2ZShyZWwgfHwgJy4nLCBmaWxlKSk7XG4gICAgICBsaXN0LnB1c2gocmVsTmFtZSk7XG4gICAgfVxuICB9XG5cbiAgcGF0aHMuZm9yRWFjaChmdW5jdGlvbiAocCkge1xuICAgIHZhciBzdGF0O1xuXG4gICAgdHJ5IHtcbiAgICAgIHN0YXQgPSBvcHRpb25zLmxpbmsgPyBjb21tb24uc3RhdEZvbGxvd0xpbmtzKHApIDogY29tbW9uLnN0YXROb0ZvbGxvd0xpbmtzKHApO1xuICAgICAgLy8gZm9sbG93IGxpbmtzIHRvIGRpcmVjdG9yaWVzIGJ5IGRlZmF1bHRcbiAgICAgIGlmIChzdGF0LmlzU3ltYm9saWNMaW5rKCkpIHtcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgLy8gd29ya2Fyb3VuZCBmb3IgaHR0cHM6Ly9naXRodWIuY29tL3NoZWxsanMvc2hlbGxqcy9pc3N1ZXMvNzk1XG4gICAgICAgIC8vIGNvZGVjb3Ygc2VlbXMgdG8gaGF2ZSBhIGJ1ZyB0aGF0IG1pc2NhbGN1bGF0ZSB0aGlzIGJsb2NrIGFzIHVuY292ZXJlZC5cbiAgICAgICAgLy8gYnV0IGFjY29yZGluZyB0byBueWMgcmVwb3J0IHRoaXMgYmxvY2sgZG9lcyBnZXQgY292ZXJlZC5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB2YXIgX3N0YXQgPSBjb21tb24uc3RhdEZvbGxvd0xpbmtzKHApO1xuICAgICAgICAgIGlmIChfc3RhdC5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgICAgICBzdGF0ID0gX3N0YXQ7XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChfKSB7fSAvLyBiYWQgc3ltbGluaywgdHJlYXQgaXQgbGlrZSBhIGZpbGVcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb21tb24uZXJyb3IoJ25vIHN1Y2ggZmlsZSBvciBkaXJlY3Rvcnk6ICcgKyBwLCAyLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIElmIHRoZSBzdGF0IHN1Y2NlZWRlZFxuICAgIGlmIChzdGF0LmlzRGlyZWN0b3J5KCkgJiYgIW9wdGlvbnMuZGlyZWN0b3J5KSB7XG4gICAgICBpZiAob3B0aW9ucy5yZWN1cnNpdmUpIHtcbiAgICAgICAgLy8gdXNlIGdsb2IsIGJlY2F1c2UgaXQncyBzaW1wbGVcbiAgICAgICAgZ2xvYi5zeW5jKHAgKyBnbG9iUGF0dGVyblJlY3Vyc2l2ZSwgeyBkb3Q6IG9wdGlvbnMuYWxsLCBmb2xsb3c6IG9wdGlvbnMubGluayB9KVxuICAgICAgICAgIC5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICAvLyBHbG9iIHBhdHRlcm4gcmV0dXJucyB0aGUgZGlyZWN0b3J5IGl0c2VsZiBhbmQgbmVlZHMgdG8gYmUgZmlsdGVyZWQgb3V0LlxuICAgICAgICAgICAgaWYgKHBhdGgucmVsYXRpdmUocCwgaXRlbSkpIHtcbiAgICAgICAgICAgICAgcHVzaEZpbGUoaXRlbSwgcGF0aC5yZWxhdGl2ZShwLCBpdGVtKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKG9wdGlvbnMuYWxsKSB7XG4gICAgICAgIC8vIHVzZSBmcy5yZWFkZGlyU3luYywgYmVjYXVzZSBpdCdzIGZhc3RcbiAgICAgICAgZnMucmVhZGRpclN5bmMocCkuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgIHB1c2hGaWxlKHBhdGguam9pbihwLCBpdGVtKSwgaXRlbSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gdXNlIGZzLnJlYWRkaXJTeW5jIGFuZCB0aGVuIGZpbHRlciBvdXQgc2VjcmV0IGZpbGVzXG4gICAgICAgIGZzLnJlYWRkaXJTeW5jKHApLmZvckVhY2goZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICBpZiAoaXRlbVswXSAhPT0gJy4nKSB7XG4gICAgICAgICAgICBwdXNoRmlsZShwYXRoLmpvaW4ocCwgaXRlbSksIGl0ZW0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHB1c2hGaWxlKHAsIHAsIHN0YXQpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gQWRkIG1ldGhvZHMsIHRvIG1ha2UgdGhpcyBtb3JlIGNvbXBhdGlibGUgd2l0aCBTaGVsbFN0cmluZ3NcbiAgcmV0dXJuIGxpc3Q7XG59XG5cbmZ1bmN0aW9uIGFkZExzQXR0cmlidXRlcyhwYXRoTmFtZSwgc3RhdHMpIHtcbiAgLy8gTm90ZTogdGhpcyBvYmplY3Qgd2lsbCBjb250YWluIG1vcmUgaW5mb3JtYXRpb24gdGhhbiAudG9TdHJpbmcoKSByZXR1cm5zXG4gIHN0YXRzLm5hbWUgPSBwYXRoTmFtZTtcbiAgc3RhdHMudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgLy8gUmV0dXJuIGEgc3RyaW5nIHJlc2VtYmxpbmcgdW5peCdzIGBscyAtbGAgZm9ybWF0XG4gICAgcmV0dXJuIFt0aGlzLm1vZGUsIHRoaXMubmxpbmssIHRoaXMudWlkLCB0aGlzLmdpZCwgdGhpcy5zaXplLCB0aGlzLm10aW1lLCB0aGlzLm5hbWVdLmpvaW4oJyAnKTtcbiAgfTtcbiAgcmV0dXJuIHN0YXRzO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9scztcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcbnZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ21rZGlyJywgX21rZGlyLCB7XG4gIGNtZE9wdGlvbnM6IHtcbiAgICAncCc6ICdmdWxscGF0aCcsXG4gIH0sXG59KTtcblxuLy8gUmVjdXJzaXZlbHkgY3JlYXRlcyBgZGlyYFxuZnVuY3Rpb24gbWtkaXJTeW5jUmVjdXJzaXZlKGRpcikge1xuICB2YXIgYmFzZURpciA9IHBhdGguZGlybmFtZShkaXIpO1xuXG4gIC8vIFByZXZlbnRzIHNvbWUgcG90ZW50aWFsIHByb2JsZW1zIGFyaXNpbmcgZnJvbSBtYWxmb3JtZWQgVU5DcyBvclxuICAvLyBpbnN1ZmZpY2llbnQgcGVybWlzc2lvbnMuXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIGlmIChiYXNlRGlyID09PSBkaXIpIHtcbiAgICBjb21tb24uZXJyb3IoJ2Rpcm5hbWUoKSBmYWlsZWQ6IFsnICsgZGlyICsgJ10nKTtcbiAgfVxuXG4gIC8vIEJhc2UgZGlyIGV4aXN0cywgbm8gcmVjdXJzaW9uIG5lY2Vzc2FyeVxuICBpZiAoZnMuZXhpc3RzU3luYyhiYXNlRGlyKSkge1xuICAgIGZzLm1rZGlyU3luYyhkaXIsIHBhcnNlSW50KCcwNzc3JywgOCkpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEJhc2UgZGlyIGRvZXMgbm90IGV4aXN0LCBnbyByZWN1cnNpdmVcbiAgbWtkaXJTeW5jUmVjdXJzaXZlKGJhc2VEaXIpO1xuXG4gIC8vIEJhc2UgZGlyIGNyZWF0ZWQsIGNhbiBjcmVhdGUgZGlyXG4gIGZzLm1rZGlyU3luYyhkaXIsIHBhcnNlSW50KCcwNzc3JywgOCkpO1xufVxuXG4vL0Bcbi8vQCAjIyMgbWtkaXIoW29wdGlvbnMsXSBkaXIgWywgZGlyIC4uLl0pXG4vL0AgIyMjIG1rZGlyKFtvcHRpb25zLF0gZGlyX2FycmF5KVxuLy9AXG4vL0AgQXZhaWxhYmxlIG9wdGlvbnM6XG4vL0Bcbi8vQCArIGAtcGA6IGZ1bGwgcGF0aCAoYW5kIGNyZWF0ZSBpbnRlcm1lZGlhdGUgZGlyZWN0b3JpZXMsIGlmIG5lY2Vzc2FyeSlcbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIG1rZGlyKCctcCcsICcvdG1wL2EvYi9jL2QnLCAnL3RtcC9lL2YvZycpO1xuLy9AIG1rZGlyKCctcCcsIFsnL3RtcC9hL2IvYy9kJywgJy90bXAvZS9mL2cnXSk7IC8vIHNhbWUgYXMgYWJvdmVcbi8vQCBgYGBcbi8vQFxuLy9AIENyZWF0ZXMgZGlyZWN0b3JpZXMuXG5mdW5jdGlvbiBfbWtkaXIob3B0aW9ucywgZGlycykge1xuICBpZiAoIWRpcnMpIGNvbW1vbi5lcnJvcignbm8gcGF0aHMgZ2l2ZW4nKTtcblxuICBpZiAodHlwZW9mIGRpcnMgPT09ICdzdHJpbmcnKSB7XG4gICAgZGlycyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgfVxuICAvLyBpZiBpdCdzIGFycmF5IGxlYXZlIGl0IGFzIGl0IGlzXG5cbiAgZGlycy5mb3JFYWNoKGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0cnkge1xuICAgICAgdmFyIHN0YXQgPSBjb21tb24uc3RhdE5vRm9sbG93TGlua3MoZGlyKTtcbiAgICAgIGlmICghb3B0aW9ucy5mdWxscGF0aCkge1xuICAgICAgICBjb21tb24uZXJyb3IoJ3BhdGggYWxyZWFkeSBleGlzdHM6ICcgKyBkaXIsIHsgY29udGludWU6IHRydWUgfSk7XG4gICAgICB9IGVsc2UgaWYgKHN0YXQuaXNGaWxlKCkpIHtcbiAgICAgICAgY29tbW9uLmVycm9yKCdjYW5ub3QgY3JlYXRlIGRpcmVjdG9yeSAnICsgZGlyICsgJzogRmlsZSBleGlzdHMnLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuOyAvLyBza2lwIGRpclxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vIGRvIG5vdGhpbmdcbiAgICB9XG5cbiAgICAvLyBCYXNlIGRpciBkb2VzIG5vdCBleGlzdCwgYW5kIG5vIC1wIG9wdGlvbiBnaXZlblxuICAgIHZhciBiYXNlRGlyID0gcGF0aC5kaXJuYW1lKGRpcik7XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKGJhc2VEaXIpICYmICFvcHRpb25zLmZ1bGxwYXRoKSB7XG4gICAgICBjb21tb24uZXJyb3IoJ25vIHN1Y2ggZmlsZSBvciBkaXJlY3Rvcnk6ICcgKyBiYXNlRGlyLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICAgICAgcmV0dXJuOyAvLyBza2lwIGRpclxuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBpZiAob3B0aW9ucy5mdWxscGF0aCkge1xuICAgICAgICBta2RpclN5bmNSZWN1cnNpdmUocGF0aC5yZXNvbHZlKGRpcikpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZnMubWtkaXJTeW5jKGRpciwgcGFyc2VJbnQoJzA3NzcnLCA4KSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdmFyIHJlYXNvbjtcbiAgICAgIGlmIChlLmNvZGUgPT09ICdFQUNDRVMnKSB7XG4gICAgICAgIHJlYXNvbiA9ICdQZXJtaXNzaW9uIGRlbmllZCc7XG4gICAgICB9IGVsc2UgaWYgKGUuY29kZSA9PT0gJ0VOT1RESVInIHx8IGUuY29kZSA9PT0gJ0VOT0VOVCcpIHtcbiAgICAgICAgcmVhc29uID0gJ05vdCBhIGRpcmVjdG9yeSc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgICAgY29tbW9uLmVycm9yKCdjYW5ub3QgY3JlYXRlIGRpcmVjdG9yeSAnICsgZGlyICsgJzogJyArIHJlYXNvbiwgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gJyc7XG59IC8vIG1rZGlyXG5tb2R1bGUuZXhwb3J0cyA9IF9ta2RpcjtcbiIsInZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG52YXIgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcbnZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIGNwID0gcmVxdWlyZSgnLi9jcCcpO1xudmFyIHJtID0gcmVxdWlyZSgnLi9ybScpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ212JywgX212LCB7XG4gIGNtZE9wdGlvbnM6IHtcbiAgICAnZic6ICchbm9fZm9yY2UnLFxuICAgICduJzogJ25vX2ZvcmNlJyxcbiAgfSxcbn0pO1xuXG4vLyBDaGVja3MgaWYgY3VyZWVudCBmaWxlIHdhcyBjcmVhdGVkIHJlY2VudGx5XG5mdW5jdGlvbiBjaGVja1JlY2VudENyZWF0ZWQoc291cmNlcywgaW5kZXgpIHtcbiAgdmFyIGxvb2tlZFNvdXJjZSA9IHNvdXJjZXNbaW5kZXhdO1xuICByZXR1cm4gc291cmNlcy5zbGljZSgwLCBpbmRleCkuc29tZShmdW5jdGlvbiAoc3JjKSB7XG4gICAgcmV0dXJuIHBhdGguYmFzZW5hbWUoc3JjKSA9PT0gcGF0aC5iYXNlbmFtZShsb29rZWRTb3VyY2UpO1xuICB9KTtcbn1cblxuLy9AXG4vL0AgIyMjIG12KFtvcHRpb25zICxdIHNvdXJjZSBbLCBzb3VyY2UgLi4uXSwgZGVzdCcpXG4vL0AgIyMjIG12KFtvcHRpb25zICxdIHNvdXJjZV9hcnJheSwgZGVzdCcpXG4vL0Bcbi8vQCBBdmFpbGFibGUgb3B0aW9uczpcbi8vQFxuLy9AICsgYC1mYDogZm9yY2UgKGRlZmF1bHQgYmVoYXZpb3IpXG4vL0AgKyBgLW5gOiBuby1jbG9iYmVyXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBtdignLW4nLCAnZmlsZScsICdkaXIvJyk7XG4vL0AgbXYoJ2ZpbGUxJywgJ2ZpbGUyJywgJ2Rpci8nKTtcbi8vQCBtdihbJ2ZpbGUxJywgJ2ZpbGUyJ10sICdkaXIvJyk7IC8vIHNhbWUgYXMgYWJvdmVcbi8vQCBgYGBcbi8vQFxuLy9AIE1vdmVzIGBzb3VyY2VgIGZpbGUocykgdG8gYGRlc3RgLlxuZnVuY3Rpb24gX212KG9wdGlvbnMsIHNvdXJjZXMsIGRlc3QpIHtcbiAgLy8gR2V0IHNvdXJjZXMsIGRlc3RcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAzKSB7XG4gICAgY29tbW9uLmVycm9yKCdtaXNzaW5nIDxzb3VyY2U+IGFuZC9vciA8ZGVzdD4nKTtcbiAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMykge1xuICAgIHNvdXJjZXMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSwgYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGRlc3QgPSBhcmd1bWVudHNbYXJndW1lbnRzLmxlbmd0aCAtIDFdO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBzb3VyY2VzID09PSAnc3RyaW5nJykge1xuICAgIHNvdXJjZXMgPSBbc291cmNlc107XG4gIH0gZWxzZSB7XG4gICAgLy8gVE9ETyhuYXRlKTogZmlndXJlIG91dCBpZiB3ZSBhY3R1YWxseSBuZWVkIHRoaXMgbGluZVxuICAgIGNvbW1vbi5lcnJvcignaW52YWxpZCBhcmd1bWVudHMnKTtcbiAgfVxuXG4gIHZhciBleGlzdHMgPSBmcy5leGlzdHNTeW5jKGRlc3QpO1xuICB2YXIgc3RhdHMgPSBleGlzdHMgJiYgY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhkZXN0KTtcblxuICAvLyBEZXN0IGlzIG5vdCBleGlzdGluZyBkaXIsIGJ1dCBtdWx0aXBsZSBzb3VyY2VzIGdpdmVuXG4gIGlmICgoIWV4aXN0cyB8fCAhc3RhdHMuaXNEaXJlY3RvcnkoKSkgJiYgc291cmNlcy5sZW5ndGggPiAxKSB7XG4gICAgY29tbW9uLmVycm9yKCdkZXN0IGlzIG5vdCBhIGRpcmVjdG9yeSAodG9vIG1hbnkgc291cmNlcyknKTtcbiAgfVxuXG4gIC8vIERlc3QgaXMgYW4gZXhpc3RpbmcgZmlsZSwgYnV0IG5vIC1mIGdpdmVuXG4gIGlmIChleGlzdHMgJiYgc3RhdHMuaXNGaWxlKCkgJiYgb3B0aW9ucy5ub19mb3JjZSkge1xuICAgIGNvbW1vbi5lcnJvcignZGVzdCBmaWxlIGFscmVhZHkgZXhpc3RzOiAnICsgZGVzdCk7XG4gIH1cblxuICBzb3VyY2VzLmZvckVhY2goZnVuY3Rpb24gKHNyYywgc3JjSW5kZXgpIHtcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoc3JjKSkge1xuICAgICAgY29tbW9uLmVycm9yKCdubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5OiAnICsgc3JjLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICAgICAgcmV0dXJuOyAvLyBza2lwIGZpbGVcbiAgICB9XG5cbiAgICAvLyBJZiBoZXJlLCBzcmMgZXhpc3RzXG5cbiAgICAvLyBXaGVuIGNvcHlpbmcgdG8gJy9wYXRoL2Rpcic6XG4gICAgLy8gICAgdGhpc0Rlc3QgPSAnL3BhdGgvZGlyL2ZpbGUxJ1xuICAgIHZhciB0aGlzRGVzdCA9IGRlc3Q7XG4gICAgaWYgKGZzLmV4aXN0c1N5bmMoZGVzdCkgJiYgY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhkZXN0KS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICB0aGlzRGVzdCA9IHBhdGgubm9ybWFsaXplKGRlc3QgKyAnLycgKyBwYXRoLmJhc2VuYW1lKHNyYykpO1xuICAgIH1cblxuICAgIHZhciB0aGlzRGVzdEV4aXN0cyA9IGZzLmV4aXN0c1N5bmModGhpc0Rlc3QpO1xuXG4gICAgaWYgKHRoaXNEZXN0RXhpc3RzICYmIGNoZWNrUmVjZW50Q3JlYXRlZChzb3VyY2VzLCBzcmNJbmRleCkpIHtcbiAgICAgIC8vIGNhbm5vdCBvdmVyd3JpdGUgZmlsZSBjcmVhdGVkIHJlY2VudGx5IGluIGN1cnJlbnQgZXhlY3V0aW9uLCBidXQgd2Ugd2FudCB0byBjb250aW51ZSBjb3B5aW5nIG90aGVyIGZpbGVzXG4gICAgICBpZiAoIW9wdGlvbnMubm9fZm9yY2UpIHtcbiAgICAgICAgY29tbW9uLmVycm9yKFwid2lsbCBub3Qgb3ZlcndyaXRlIGp1c3QtY3JlYXRlZCAnXCIgKyB0aGlzRGVzdCArIFwiJyB3aXRoICdcIiArIHNyYyArIFwiJ1wiLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChmcy5leGlzdHNTeW5jKHRoaXNEZXN0KSAmJiBvcHRpb25zLm5vX2ZvcmNlKSB7XG4gICAgICBjb21tb24uZXJyb3IoJ2Rlc3QgZmlsZSBhbHJlYWR5IGV4aXN0czogJyArIHRoaXNEZXN0LCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICAgICAgcmV0dXJuOyAvLyBza2lwIGZpbGVcbiAgICB9XG5cbiAgICBpZiAocGF0aC5yZXNvbHZlKHNyYykgPT09IHBhdGguZGlybmFtZShwYXRoLnJlc29sdmUodGhpc0Rlc3QpKSkge1xuICAgICAgY29tbW9uLmVycm9yKCdjYW5ub3QgbW92ZSB0byBzZWxmOiAnICsgc3JjLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICAgICAgcmV0dXJuOyAvLyBza2lwIGZpbGVcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgZnMucmVuYW1lU3luYyhzcmMsIHRoaXNEZXN0KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgaWYgKGUuY29kZSA9PT0gJ0VYREVWJykge1xuICAgICAgICAvLyBJZiB3ZSdyZSB0cnlpbmcgdG8gYG12YCB0byBhbiBleHRlcm5hbCBwYXJ0aXRpb24sIHdlJ2xsIGFjdHVhbGx5IG5lZWRcbiAgICAgICAgLy8gdG8gcGVyZm9ybSBhIGNvcHkgYW5kIHRoZW4gY2xlYW4gdXAgdGhlIG9yaWdpbmFsIGZpbGUuIElmIGVpdGhlciB0aGVcbiAgICAgICAgLy8gY29weSBvciB0aGUgcm0gZmFpbHMgd2l0aCBhbiBleGNlcHRpb24sIHdlIHNob3VsZCBhbGxvdyB0aGlzXG4gICAgICAgIC8vIGV4Y2VwdGlvbiB0byBwYXNzIHVwIHRvIHRoZSB0b3AgbGV2ZWwuXG4gICAgICAgIGNwKCctcicsIHNyYywgdGhpc0Rlc3QpO1xuICAgICAgICBybSgnLXJmJywgc3JjKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pOyAvLyBmb3JFYWNoKHNyYylcbiAgcmV0dXJuICcnO1xufSAvLyBtdlxubW9kdWxlLmV4cG9ydHMgPSBfbXY7XG4iLCIvLyBzZWUgZGlycy5qc1xuIiwiLy8gc2VlIGRpcnMuanNcbiIsInZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG5cbmNvbW1vbi5yZWdpc3RlcigncHdkJywgX3B3ZCwge1xuICBhbGxvd0dsb2JiaW5nOiBmYWxzZSxcbn0pO1xuXG4vL0Bcbi8vQCAjIyMgcHdkKClcbi8vQFxuLy9AIFJldHVybnMgdGhlIGN1cnJlbnQgZGlyZWN0b3J5LlxuZnVuY3Rpb24gX3B3ZCgpIHtcbiAgdmFyIHB3ZCA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpKTtcbiAgcmV0dXJuIHB3ZDtcbn1cbm1vZHVsZS5leHBvcnRzID0gX3B3ZDtcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcblxuY29tbW9uLnJlZ2lzdGVyKCdybScsIF9ybSwge1xuICBjbWRPcHRpb25zOiB7XG4gICAgJ2YnOiAnZm9yY2UnLFxuICAgICdyJzogJ3JlY3Vyc2l2ZScsXG4gICAgJ1InOiAncmVjdXJzaXZlJyxcbiAgfSxcbn0pO1xuXG4vLyBSZWN1cnNpdmVseSByZW1vdmVzICdkaXInXG4vLyBBZGFwdGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL3J5YW5tY2dyYXRoL3dyZW5jaC1qc1xuLy9cbi8vIENvcHlyaWdodCAoYykgMjAxMCBSeWFuIE1jR3JhdGhcbi8vIENvcHlyaWdodCAoYykgMjAxMiBBcnR1ciBBZGliXG4vL1xuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlXG4vLyBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocFxuZnVuY3Rpb24gcm1kaXJTeW5jUmVjdXJzaXZlKGRpciwgZm9yY2UsIGZyb21TeW1saW5rKSB7XG4gIHZhciBmaWxlcztcblxuICBmaWxlcyA9IGZzLnJlYWRkaXJTeW5jKGRpcik7XG5cbiAgLy8gTG9vcCB0aHJvdWdoIGFuZCBkZWxldGUgZXZlcnl0aGluZyBpbiB0aGUgc3ViLXRyZWUgYWZ0ZXIgY2hlY2tpbmcgaXRcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaWxlcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBmaWxlID0gZGlyICsgJy8nICsgZmlsZXNbaV07XG4gICAgdmFyIGN1cnJGaWxlID0gY29tbW9uLnN0YXROb0ZvbGxvd0xpbmtzKGZpbGUpO1xuXG4gICAgaWYgKGN1cnJGaWxlLmlzRGlyZWN0b3J5KCkpIHsgLy8gUmVjdXJzaXZlIGZ1bmN0aW9uIGJhY2sgdG8gdGhlIGJlZ2lubmluZ1xuICAgICAgcm1kaXJTeW5jUmVjdXJzaXZlKGZpbGUsIGZvcmNlKTtcbiAgICB9IGVsc2UgeyAvLyBBc3N1bWUgaXQncyBhIGZpbGUgLSBwZXJoYXBzIGEgdHJ5L2NhdGNoIGJlbG9uZ3MgaGVyZT9cbiAgICAgIGlmIChmb3JjZSB8fCBpc1dyaXRlYWJsZShmaWxlKSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbW1vbi51bmxpbmtTeW5jKGZpbGUpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgICBjb21tb24uZXJyb3IoJ2NvdWxkIG5vdCByZW1vdmUgZmlsZSAoY29kZSAnICsgZS5jb2RlICsgJyk6ICcgKyBmaWxlLCB7XG4gICAgICAgICAgICBjb250aW51ZTogdHJ1ZSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIGlmIHdhcyBkaXJlY3Rvcnkgd2FzIHJlZmVyZW5jZWQgdGhyb3VnaCBhIHN5bWJvbGljIGxpbmssXG4gIC8vIHRoZSBjb250ZW50cyBzaG91bGQgYmUgcmVtb3ZlZCwgYnV0IG5vdCB0aGUgZGlyZWN0b3J5IGl0c2VsZlxuICBpZiAoZnJvbVN5bWxpbmspIHJldHVybjtcblxuICAvLyBOb3cgdGhhdCB3ZSBrbm93IGV2ZXJ5dGhpbmcgaW4gdGhlIHN1Yi10cmVlIGhhcyBiZWVuIGRlbGV0ZWQsIHdlIGNhbiBkZWxldGUgdGhlIG1haW4gZGlyZWN0b3J5LlxuICAvLyBIdXp6YWggZm9yIHRoZSBzaG9wa2VlcC5cblxuICB2YXIgcmVzdWx0O1xuICB0cnkge1xuICAgIC8vIFJldHJ5IG9uIHdpbmRvd3MsIHNvbWV0aW1lcyBpdCB0YWtlcyBhIGxpdHRsZSB0aW1lIGJlZm9yZSBhbGwgdGhlIGZpbGVzIGluIHRoZSBkaXJlY3RvcnkgYXJlIGdvbmVcbiAgICB2YXIgc3RhcnQgPSBEYXRlLm5vdygpO1xuXG4gICAgLy8gVE9ETzogcmVwbGFjZSB0aGlzIHdpdGggYSBmaW5pdGUgbG9vcFxuICAgIGZvciAoOzspIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJlc3VsdCA9IGZzLnJtZGlyU3luYyhkaXIpO1xuICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhkaXIpKSB0aHJvdyB7IGNvZGU6ICdFQUdBSU4nIH07XG4gICAgICAgIGJyZWFrO1xuICAgICAgfSBjYXRjaCAoZXIpIHtcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgLy8gSW4gYWRkaXRpb24gdG8gZXJyb3IgY29kZXMsIGFsc28gY2hlY2sgaWYgdGhlIGRpcmVjdG9yeSBzdGlsbCBleGlzdHMgYW5kIGxvb3AgYWdhaW4gaWYgdHJ1ZVxuICAgICAgICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJyAmJiAoZXIuY29kZSA9PT0gJ0VOT1RFTVBUWScgfHwgZXIuY29kZSA9PT0gJ0VCVVNZJyB8fCBlci5jb2RlID09PSAnRVBFUk0nIHx8IGVyLmNvZGUgPT09ICdFQUdBSU4nKSkge1xuICAgICAgICAgIGlmIChEYXRlLm5vdygpIC0gc3RhcnQgPiAxMDAwKSB0aHJvdyBlcjtcbiAgICAgICAgfSBlbHNlIGlmIChlci5jb2RlID09PSAnRU5PRU5UJykge1xuICAgICAgICAgIC8vIERpcmVjdG9yeSBkaWQgbm90IGV4aXN0LCBkZWxldGlvbiB3YXMgc3VjY2Vzc2Z1bFxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgY29tbW9uLmVycm9yKCdjb3VsZCBub3QgcmVtb3ZlIGRpcmVjdG9yeSAoY29kZSAnICsgZS5jb2RlICsgJyk6ICcgKyBkaXIsIHsgY29udGludWU6IHRydWUgfSk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufSAvLyBybWRpclN5bmNSZWN1cnNpdmVcblxuLy8gSGFjayB0byBkZXRlcm1pbmUgaWYgZmlsZSBoYXMgd3JpdGUgcGVybWlzc2lvbnMgZm9yIGN1cnJlbnQgdXNlclxuLy8gQXZvaWRzIGhhdmluZyB0byBjaGVjayB1c2VyLCBncm91cCwgZXRjLCBidXQgaXQncyBwcm9iYWJseSBzbG93XG5mdW5jdGlvbiBpc1dyaXRlYWJsZShmaWxlKSB7XG4gIHZhciB3cml0ZVBlcm1pc3Npb24gPSB0cnVlO1xuICB0cnkge1xuICAgIHZhciBfX2ZkID0gZnMub3BlblN5bmMoZmlsZSwgJ2EnKTtcbiAgICBmcy5jbG9zZVN5bmMoX19mZCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB3cml0ZVBlcm1pc3Npb24gPSBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB3cml0ZVBlcm1pc3Npb247XG59XG5cbmZ1bmN0aW9uIGhhbmRsZUZpbGUoZmlsZSwgb3B0aW9ucykge1xuICBpZiAob3B0aW9ucy5mb3JjZSB8fCBpc1dyaXRlYWJsZShmaWxlKSkge1xuICAgIC8vIC1mIHdhcyBwYXNzZWQsIG9yIGZpbGUgaXMgd3JpdGFibGUsIHNvIGl0IGNhbiBiZSByZW1vdmVkXG4gICAgY29tbW9uLnVubGlua1N5bmMoZmlsZSk7XG4gIH0gZWxzZSB7XG4gICAgY29tbW9uLmVycm9yKCdwZXJtaXNzaW9uIGRlbmllZDogJyArIGZpbGUsIHsgY29udGludWU6IHRydWUgfSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaGFuZGxlRGlyZWN0b3J5KGZpbGUsIG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMucmVjdXJzaXZlKSB7XG4gICAgLy8gLXIgd2FzIHBhc3NlZCwgc28gZGlyZWN0b3J5IGNhbiBiZSByZW1vdmVkXG4gICAgcm1kaXJTeW5jUmVjdXJzaXZlKGZpbGUsIG9wdGlvbnMuZm9yY2UpO1xuICB9IGVsc2Uge1xuICAgIGNvbW1vbi5lcnJvcigncGF0aCBpcyBhIGRpcmVjdG9yeScsIHsgY29udGludWU6IHRydWUgfSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaGFuZGxlU3ltYm9saWNMaW5rKGZpbGUsIG9wdGlvbnMpIHtcbiAgdmFyIHN0YXRzO1xuICB0cnkge1xuICAgIHN0YXRzID0gY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhmaWxlKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIHN5bWxpbmsgaXMgYnJva2VuLCBzbyByZW1vdmUgdGhlIHN5bWxpbmsgaXRzZWxmXG4gICAgY29tbW9uLnVubGlua1N5bmMoZmlsZSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHN0YXRzLmlzRmlsZSgpKSB7XG4gICAgY29tbW9uLnVubGlua1N5bmMoZmlsZSk7XG4gIH0gZWxzZSBpZiAoc3RhdHMuaXNEaXJlY3RvcnkoKSkge1xuICAgIGlmIChmaWxlW2ZpbGUubGVuZ3RoIC0gMV0gPT09ICcvJykge1xuICAgICAgLy8gdHJhaWxpbmcgc2VwYXJhdG9yLCBzbyByZW1vdmUgdGhlIGNvbnRlbnRzLCBub3QgdGhlIGxpbmtcbiAgICAgIGlmIChvcHRpb25zLnJlY3Vyc2l2ZSkge1xuICAgICAgICAvLyAtciB3YXMgcGFzc2VkLCBzbyBkaXJlY3RvcnkgY2FuIGJlIHJlbW92ZWRcbiAgICAgICAgdmFyIGZyb21TeW1saW5rID0gdHJ1ZTtcbiAgICAgICAgcm1kaXJTeW5jUmVjdXJzaXZlKGZpbGUsIG9wdGlvbnMuZm9yY2UsIGZyb21TeW1saW5rKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbW1vbi5lcnJvcigncGF0aCBpcyBhIGRpcmVjdG9yeScsIHsgY29udGludWU6IHRydWUgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIG5vIHRyYWlsaW5nIHNlcGFyYXRvciwgc28gcmVtb3ZlIHRoZSBsaW5rXG4gICAgICBjb21tb24udW5saW5rU3luYyhmaWxlKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaGFuZGxlRklGTyhmaWxlKSB7XG4gIGNvbW1vbi51bmxpbmtTeW5jKGZpbGUpO1xufVxuXG4vL0Bcbi8vQCAjIyMgcm0oW29wdGlvbnMsXSBmaWxlIFssIGZpbGUgLi4uXSlcbi8vQCAjIyMgcm0oW29wdGlvbnMsXSBmaWxlX2FycmF5KVxuLy9AXG4vL0AgQXZhaWxhYmxlIG9wdGlvbnM6XG4vL0Bcbi8vQCArIGAtZmA6IGZvcmNlXG4vL0AgKyBgLXIsIC1SYDogcmVjdXJzaXZlXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBybSgnLXJmJywgJy90bXAvKicpO1xuLy9AIHJtKCdzb21lX2ZpbGUudHh0JywgJ2Fub3RoZXJfZmlsZS50eHQnKTtcbi8vQCBybShbJ3NvbWVfZmlsZS50eHQnLCAnYW5vdGhlcl9maWxlLnR4dCddKTsgLy8gc2FtZSBhcyBhYm92ZVxuLy9AIGBgYFxuLy9AXG4vL0AgUmVtb3ZlcyBmaWxlcy5cbmZ1bmN0aW9uIF9ybShvcHRpb25zLCBmaWxlcykge1xuICBpZiAoIWZpbGVzKSBjb21tb24uZXJyb3IoJ25vIHBhdGhzIGdpdmVuJyk7XG5cbiAgLy8gQ29udmVydCB0byBhcnJheVxuICBmaWxlcyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcblxuICBmaWxlcy5mb3JFYWNoKGZ1bmN0aW9uIChmaWxlKSB7XG4gICAgdmFyIGxzdGF0cztcbiAgICB0cnkge1xuICAgICAgdmFyIGZpbGVwYXRoID0gKGZpbGVbZmlsZS5sZW5ndGggLSAxXSA9PT0gJy8nKVxuICAgICAgICA/IGZpbGUuc2xpY2UoMCwgLTEpIC8vIHJlbW92ZSB0aGUgJy8nIHNvIGxzdGF0U3luYyBjYW4gZGV0ZWN0IHN5bWxpbmtzXG4gICAgICAgIDogZmlsZTtcbiAgICAgIGxzdGF0cyA9IGNvbW1vbi5zdGF0Tm9Gb2xsb3dMaW5rcyhmaWxlcGF0aCk7IC8vIHRlc3QgZm9yIGV4aXN0ZW5jZVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vIFBhdGggZG9lcyBub3QgZXhpc3QsIG5vIGZvcmNlIGZsYWcgZ2l2ZW5cbiAgICAgIGlmICghb3B0aW9ucy5mb3JjZSkge1xuICAgICAgICBjb21tb24uZXJyb3IoJ25vIHN1Y2ggZmlsZSBvciBkaXJlY3Rvcnk6ICcgKyBmaWxlLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuOyAvLyBza2lwIGZpbGVcbiAgICB9XG5cbiAgICAvLyBJZiBoZXJlLCBwYXRoIGV4aXN0c1xuICAgIGlmIChsc3RhdHMuaXNGaWxlKCkpIHtcbiAgICAgIGhhbmRsZUZpbGUoZmlsZSwgb3B0aW9ucyk7XG4gICAgfSBlbHNlIGlmIChsc3RhdHMuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgaGFuZGxlRGlyZWN0b3J5KGZpbGUsIG9wdGlvbnMpO1xuICAgIH0gZWxzZSBpZiAobHN0YXRzLmlzU3ltYm9saWNMaW5rKCkpIHtcbiAgICAgIGhhbmRsZVN5bWJvbGljTGluayhmaWxlLCBvcHRpb25zKTtcbiAgICB9IGVsc2UgaWYgKGxzdGF0cy5pc0ZJRk8oKSkge1xuICAgICAgaGFuZGxlRklGTyhmaWxlKTtcbiAgICB9XG4gIH0pOyAvLyBmb3JFYWNoKGZpbGUpXG4gIHJldHVybiAnJztcbn0gLy8gcm1cbm1vZHVsZS5leHBvcnRzID0gX3JtO1xuIiwidmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgZnMgPSByZXF1aXJlKCdmcycpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ3NlZCcsIF9zZWQsIHtcbiAgZ2xvYlN0YXJ0OiAzLCAvLyBkb24ndCBnbG9iLWV4cGFuZCByZWdleGVzXG4gIGNhblJlY2VpdmVQaXBlOiB0cnVlLFxuICBjbWRPcHRpb25zOiB7XG4gICAgJ2knOiAnaW5wbGFjZScsXG4gIH0sXG59KTtcblxuLy9AXG4vL0AgIyMjIHNlZChbb3B0aW9ucyxdIHNlYXJjaF9yZWdleCwgcmVwbGFjZW1lbnQsIGZpbGUgWywgZmlsZSAuLi5dKVxuLy9AICMjIyBzZWQoW29wdGlvbnMsXSBzZWFyY2hfcmVnZXgsIHJlcGxhY2VtZW50LCBmaWxlX2FycmF5KVxuLy9AXG4vL0AgQXZhaWxhYmxlIG9wdGlvbnM6XG4vL0Bcbi8vQCArIGAtaWA6IFJlcGxhY2UgY29udGVudHMgb2YgYGZpbGVgIGluLXBsYWNlLiBfTm90ZSB0aGF0IG5vIGJhY2t1cHMgd2lsbCBiZSBjcmVhdGVkIV9cbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIHNlZCgnLWknLCAnUFJPR1JBTV9WRVJTSU9OJywgJ3YwLjEuMycsICdzb3VyY2UuanMnKTtcbi8vQCBzZWQoLy4qREVMRVRFX1RISVNfTElORS4qXFxuLywgJycsICdzb3VyY2UuanMnKTtcbi8vQCBgYGBcbi8vQFxuLy9AIFJlYWRzIGFuIGlucHV0IHN0cmluZyBmcm9tIGBmaWxlYHMsIGFuZCBwZXJmb3JtcyBhIEphdmFTY3JpcHQgYHJlcGxhY2UoKWAgb24gdGhlIGlucHV0XG4vL0AgdXNpbmcgdGhlIGdpdmVuIGBzZWFyY2hfcmVnZXhgIGFuZCBgcmVwbGFjZW1lbnRgIHN0cmluZyBvciBmdW5jdGlvbi4gUmV0dXJucyB0aGUgbmV3IHN0cmluZyBhZnRlciByZXBsYWNlbWVudC5cbi8vQFxuLy9AIE5vdGU6XG4vL0Bcbi8vQCBMaWtlIHVuaXggYHNlZGAsIFNoZWxsSlMgYHNlZGAgc3VwcG9ydHMgY2FwdHVyZSBncm91cHMuIENhcHR1cmUgZ3JvdXBzIGFyZSBzcGVjaWZpZWRcbi8vQCB1c2luZyB0aGUgYCRuYCBzeW50YXg6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0Agc2VkKC8oXFx3KylcXHMoXFx3KykvLCAnJDIsICQxJywgJ2ZpbGUudHh0Jyk7XG4vL0AgYGBgXG5mdW5jdGlvbiBfc2VkKG9wdGlvbnMsIHJlZ2V4LCByZXBsYWNlbWVudCwgZmlsZXMpIHtcbiAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBjb21pbmcgZnJvbSBhIHBpcGVcbiAgdmFyIHBpcGUgPSBjb21tb24ucmVhZEZyb21QaXBlKCk7XG5cbiAgaWYgKHR5cGVvZiByZXBsYWNlbWVudCAhPT0gJ3N0cmluZycgJiYgdHlwZW9mIHJlcGxhY2VtZW50ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgaWYgKHR5cGVvZiByZXBsYWNlbWVudCA9PT0gJ251bWJlcicpIHtcbiAgICAgIHJlcGxhY2VtZW50ID0gcmVwbGFjZW1lbnQudG9TdHJpbmcoKTsgLy8gZmFsbGJhY2tcbiAgICB9IGVsc2Uge1xuICAgICAgY29tbW9uLmVycm9yKCdpbnZhbGlkIHJlcGxhY2VtZW50IHN0cmluZycpO1xuICAgIH1cbiAgfVxuXG4gIC8vIENvbnZlcnQgYWxsIHNlYXJjaCBzdHJpbmdzIHRvIFJlZ0V4cFxuICBpZiAodHlwZW9mIHJlZ2V4ID09PSAnc3RyaW5nJykge1xuICAgIHJlZ2V4ID0gUmVnRXhwKHJlZ2V4KTtcbiAgfVxuXG4gIGlmICghZmlsZXMgJiYgIXBpcGUpIHtcbiAgICBjb21tb24uZXJyb3IoJ25vIGZpbGVzIGdpdmVuJyk7XG4gIH1cblxuICBmaWxlcyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAzKTtcblxuICBpZiAocGlwZSkge1xuICAgIGZpbGVzLnVuc2hpZnQoJy0nKTtcbiAgfVxuXG4gIHZhciBzZWQgPSBbXTtcbiAgZmlsZXMuZm9yRWFjaChmdW5jdGlvbiAoZmlsZSkge1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhmaWxlKSAmJiBmaWxlICE9PSAnLScpIHtcbiAgICAgIGNvbW1vbi5lcnJvcignbm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeTogJyArIGZpbGUsIDIsIHsgY29udGludWU6IHRydWUgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGNvbnRlbnRzID0gZmlsZSA9PT0gJy0nID8gcGlwZSA6IGZzLnJlYWRGaWxlU3luYyhmaWxlLCAndXRmOCcpO1xuICAgIHZhciBsaW5lcyA9IGNvbnRlbnRzLnNwbGl0KCdcXG4nKTtcbiAgICB2YXIgcmVzdWx0ID0gbGluZXMubWFwKGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICByZXR1cm4gbGluZS5yZXBsYWNlKHJlZ2V4LCByZXBsYWNlbWVudCk7XG4gICAgfSkuam9pbignXFxuJyk7XG5cbiAgICBzZWQucHVzaChyZXN1bHQpO1xuXG4gICAgaWYgKG9wdGlvbnMuaW5wbGFjZSkge1xuICAgICAgZnMud3JpdGVGaWxlU3luYyhmaWxlLCByZXN1bHQsICd1dGY4Jyk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gc2VkLmpvaW4oJ1xcbicpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBfc2VkO1xuIiwidmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG5cbmNvbW1vbi5yZWdpc3Rlcignc2V0JywgX3NldCwge1xuICBhbGxvd0dsb2JiaW5nOiBmYWxzZSxcbiAgd3JhcE91dHB1dDogZmFsc2UsXG59KTtcblxuLy9AXG4vL0AgIyMjIHNldChvcHRpb25zKVxuLy9AXG4vL0AgQXZhaWxhYmxlIG9wdGlvbnM6XG4vL0Bcbi8vQCArIGArLy1lYDogZXhpdCB1cG9uIGVycm9yIChgY29uZmlnLmZhdGFsYClcbi8vQCArIGArLy12YDogdmVyYm9zZTogc2hvdyBhbGwgY29tbWFuZHMgKGBjb25maWcudmVyYm9zZWApXG4vL0AgKyBgKy8tZmA6IGRpc2FibGUgZmlsZW5hbWUgZXhwYW5zaW9uIChnbG9iYmluZylcbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIHNldCgnLWUnKTsgLy8gZXhpdCB1cG9uIGZpcnN0IGVycm9yXG4vL0Agc2V0KCcrZScpOyAvLyB0aGlzIHVuZG9lcyBhIFwic2V0KCctZScpXCJcbi8vQCBgYGBcbi8vQFxuLy9AIFNldHMgZ2xvYmFsIGNvbmZpZ3VyYXRpb24gdmFyaWFibGVzLlxuZnVuY3Rpb24gX3NldChvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucykge1xuICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xuICAgIGlmIChhcmdzLmxlbmd0aCA8IDIpIGNvbW1vbi5lcnJvcignbXVzdCBwcm92aWRlIGFuIGFyZ3VtZW50Jyk7XG4gICAgb3B0aW9ucyA9IGFyZ3NbMV07XG4gIH1cbiAgdmFyIG5lZ2F0ZSA9IChvcHRpb25zWzBdID09PSAnKycpO1xuICBpZiAobmVnYXRlKSB7XG4gICAgb3B0aW9ucyA9ICctJyArIG9wdGlvbnMuc2xpY2UoMSk7IC8vIHBhcnNlT3B0aW9ucyBuZWVkcyBhICctJyBwcmVmaXhcbiAgfVxuICBvcHRpb25zID0gY29tbW9uLnBhcnNlT3B0aW9ucyhvcHRpb25zLCB7XG4gICAgJ2UnOiAnZmF0YWwnLFxuICAgICd2JzogJ3ZlcmJvc2UnLFxuICAgICdmJzogJ25vZ2xvYicsXG4gIH0pO1xuXG4gIGlmIChuZWdhdGUpIHtcbiAgICBPYmplY3Qua2V5cyhvcHRpb25zKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIG9wdGlvbnNba2V5XSA9ICFvcHRpb25zW2tleV07XG4gICAgfSk7XG4gIH1cblxuICBPYmplY3Qua2V5cyhvcHRpb25zKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAvLyBPbmx5IGNoYW5nZSB0aGUgZ2xvYmFsIGNvbmZpZyBpZiBgbmVnYXRlYCBpcyBmYWxzZSBhbmQgdGhlIG9wdGlvbiBpcyB0cnVlXG4gICAgLy8gb3IgaWYgYG5lZ2F0ZWAgaXMgdHJ1ZSBhbmQgdGhlIG9wdGlvbiBpcyBmYWxzZSAoYWthIG5lZ2F0ZSAhPT0gb3B0aW9uKVxuICAgIGlmIChuZWdhdGUgIT09IG9wdGlvbnNba2V5XSkge1xuICAgICAgY29tbW9uLmNvbmZpZ1trZXldID0gb3B0aW9uc1trZXldO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybjtcbn1cbm1vZHVsZS5leHBvcnRzID0gX3NldDtcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcblxuY29tbW9uLnJlZ2lzdGVyKCdzb3J0JywgX3NvcnQsIHtcbiAgY2FuUmVjZWl2ZVBpcGU6IHRydWUsXG4gIGNtZE9wdGlvbnM6IHtcbiAgICAncic6ICdyZXZlcnNlJyxcbiAgICAnbic6ICdudW1lcmljYWwnLFxuICB9LFxufSk7XG5cbi8vIHBhcnNlIG91dCB0aGUgbnVtYmVyIHByZWZpeCBvZiBhIGxpbmVcbmZ1bmN0aW9uIHBhcnNlTnVtYmVyKHN0cikge1xuICB2YXIgbWF0Y2ggPSBzdHIubWF0Y2goL15cXHMqKFxcZCopXFxzKiguKikkLyk7XG4gIHJldHVybiB7IG51bTogTnVtYmVyKG1hdGNoWzFdKSwgdmFsdWU6IG1hdGNoWzJdIH07XG59XG5cbi8vIGNvbXBhcmUgdHdvIHN0cmluZ3MgY2FzZS1pbnNlbnNpdGl2ZWx5LCBidXQgZXhhbWluZSBjYXNlIGZvciBzdHJpbmdzIHRoYXQgYXJlXG4vLyBjYXNlLWluc2Vuc2l0aXZlIGVxdWl2YWxlbnRcbmZ1bmN0aW9uIHVuaXhDbXAoYSwgYikge1xuICB2YXIgYUxvd2VyID0gYS50b0xvd2VyQ2FzZSgpO1xuICB2YXIgYkxvd2VyID0gYi50b0xvd2VyQ2FzZSgpO1xuICByZXR1cm4gKGFMb3dlciA9PT0gYkxvd2VyID9cbiAgICAgIC0xICogYS5sb2NhbGVDb21wYXJlKGIpIDogLy8gdW5peCBzb3J0IHRyZWF0cyBjYXNlIG9wcG9zaXRlIGhvdyBqYXZhc2NyaXB0IGRvZXNcbiAgICAgIGFMb3dlci5sb2NhbGVDb21wYXJlKGJMb3dlcikpO1xufVxuXG4vLyBjb21wYXJlIHR3byBzdHJpbmdzIGluIHRoZSBmYXNoaW9uIHRoYXQgdW5peCBzb3J0J3MgLW4gb3B0aW9uIHdvcmtzXG5mdW5jdGlvbiBudW1lcmljYWxDbXAoYSwgYikge1xuICB2YXIgb2JqQSA9IHBhcnNlTnVtYmVyKGEpO1xuICB2YXIgb2JqQiA9IHBhcnNlTnVtYmVyKGIpO1xuICBpZiAob2JqQS5oYXNPd25Qcm9wZXJ0eSgnbnVtJykgJiYgb2JqQi5oYXNPd25Qcm9wZXJ0eSgnbnVtJykpIHtcbiAgICByZXR1cm4gKChvYmpBLm51bSAhPT0gb2JqQi5udW0pID9cbiAgICAgICAgKG9iakEubnVtIC0gb2JqQi5udW0pIDpcbiAgICAgICAgdW5peENtcChvYmpBLnZhbHVlLCBvYmpCLnZhbHVlKSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHVuaXhDbXAob2JqQS52YWx1ZSwgb2JqQi52YWx1ZSk7XG4gIH1cbn1cblxuLy9AXG4vL0AgIyMjIHNvcnQoW29wdGlvbnMsXSBmaWxlIFssIGZpbGUgLi4uXSlcbi8vQCAjIyMgc29ydChbb3B0aW9ucyxdIGZpbGVfYXJyYXkpXG4vL0Bcbi8vQCBBdmFpbGFibGUgb3B0aW9uczpcbi8vQFxuLy9AICsgYC1yYDogUmV2ZXJzZSB0aGUgcmVzdWx0c1xuLy9AICsgYC1uYDogQ29tcGFyZSBhY2NvcmRpbmcgdG8gbnVtZXJpY2FsIHZhbHVlXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBzb3J0KCdmb28udHh0JywgJ2Jhci50eHQnKTtcbi8vQCBzb3J0KCctcicsICdmb28udHh0Jyk7XG4vL0AgYGBgXG4vL0Bcbi8vQCBSZXR1cm4gdGhlIGNvbnRlbnRzIG9mIHRoZSBgZmlsZWBzLCBzb3J0ZWQgbGluZS1ieS1saW5lLiBTb3J0aW5nIG11bHRpcGxlXG4vL0AgZmlsZXMgbWl4ZXMgdGhlaXIgY29udGVudCAoanVzdCBhcyB1bml4IGBzb3J0YCBkb2VzKS5cbmZ1bmN0aW9uIF9zb3J0KG9wdGlvbnMsIGZpbGVzKSB7XG4gIC8vIENoZWNrIGlmIHRoaXMgaXMgY29taW5nIGZyb20gYSBwaXBlXG4gIHZhciBwaXBlID0gY29tbW9uLnJlYWRGcm9tUGlwZSgpO1xuXG4gIGlmICghZmlsZXMgJiYgIXBpcGUpIGNvbW1vbi5lcnJvcignbm8gZmlsZXMgZ2l2ZW4nKTtcblxuICBmaWxlcyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcblxuICBpZiAocGlwZSkge1xuICAgIGZpbGVzLnVuc2hpZnQoJy0nKTtcbiAgfVxuXG4gIHZhciBsaW5lcyA9IGZpbGVzLnJlZHVjZShmdW5jdGlvbiAoYWNjdW0sIGZpbGUpIHtcbiAgICBpZiAoZmlsZSAhPT0gJy0nKSB7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZmlsZSkpIHtcbiAgICAgICAgY29tbW9uLmVycm9yKCdubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5OiAnICsgZmlsZSwgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgfSBlbHNlIGlmIChjb21tb24uc3RhdEZvbGxvd0xpbmtzKGZpbGUpLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgY29tbW9uLmVycm9yKCdyZWFkIGZhaWxlZDogJyArIGZpbGUgKyAnOiBJcyBhIGRpcmVjdG9yeScsIHtcbiAgICAgICAgICBjb250aW51ZTogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgY29udGVudHMgPSBmaWxlID09PSAnLScgPyBwaXBlIDogZnMucmVhZEZpbGVTeW5jKGZpbGUsICd1dGY4Jyk7XG4gICAgcmV0dXJuIGFjY3VtLmNvbmNhdChjb250ZW50cy50cmltUmlnaHQoKS5zcGxpdCgnXFxuJykpO1xuICB9LCBbXSk7XG5cbiAgdmFyIHNvcnRlZCA9IGxpbmVzLnNvcnQob3B0aW9ucy5udW1lcmljYWwgPyBudW1lcmljYWxDbXAgOiB1bml4Q21wKTtcblxuICBpZiAob3B0aW9ucy5yZXZlcnNlKSB7XG4gICAgc29ydGVkID0gc29ydGVkLnJldmVyc2UoKTtcbiAgfVxuXG4gIHJldHVybiBzb3J0ZWQuam9pbignXFxuJykgKyAnXFxuJztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfc29ydDtcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcblxuY29tbW9uLnJlZ2lzdGVyKCd0YWlsJywgX3RhaWwsIHtcbiAgY2FuUmVjZWl2ZVBpcGU6IHRydWUsXG4gIGNtZE9wdGlvbnM6IHtcbiAgICAnbic6ICdudW1MaW5lcycsXG4gIH0sXG59KTtcblxuLy9AXG4vL0AgIyMjIHRhaWwoW3snLW4nOiBcXDxudW1cXD59LF0gZmlsZSBbLCBmaWxlIC4uLl0pXG4vL0AgIyMjIHRhaWwoW3snLW4nOiBcXDxudW1cXD59LF0gZmlsZV9hcnJheSlcbi8vQFxuLy9AIEF2YWlsYWJsZSBvcHRpb25zOlxuLy9AXG4vL0AgKyBgLW4gPG51bT5gOiBTaG93IHRoZSBsYXN0IGA8bnVtPmAgbGluZXMgb2YgYGZpbGVgc1xuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgdmFyIHN0ciA9IHRhaWwoeyctbic6IDF9LCAnZmlsZSoudHh0Jyk7XG4vL0AgdmFyIHN0ciA9IHRhaWwoJ2ZpbGUxJywgJ2ZpbGUyJyk7XG4vL0AgdmFyIHN0ciA9IHRhaWwoWydmaWxlMScsICdmaWxlMiddKTsgLy8gc2FtZSBhcyBhYm92ZVxuLy9AIGBgYFxuLy9AXG4vL0AgUmVhZCB0aGUgZW5kIG9mIGEgYGZpbGVgLlxuZnVuY3Rpb24gX3RhaWwob3B0aW9ucywgZmlsZXMpIHtcbiAgdmFyIHRhaWwgPSBbXTtcbiAgdmFyIHBpcGUgPSBjb21tb24ucmVhZEZyb21QaXBlKCk7XG5cbiAgaWYgKCFmaWxlcyAmJiAhcGlwZSkgY29tbW9uLmVycm9yKCdubyBwYXRocyBnaXZlbicpO1xuXG4gIHZhciBpZHggPSAxO1xuICBpZiAob3B0aW9ucy5udW1MaW5lcyA9PT0gdHJ1ZSkge1xuICAgIGlkeCA9IDI7XG4gICAgb3B0aW9ucy5udW1MaW5lcyA9IE51bWJlcihhcmd1bWVudHNbMV0pO1xuICB9IGVsc2UgaWYgKG9wdGlvbnMubnVtTGluZXMgPT09IGZhbHNlKSB7XG4gICAgb3B0aW9ucy5udW1MaW5lcyA9IDEwO1xuICB9XG4gIG9wdGlvbnMubnVtTGluZXMgPSAtMSAqIE1hdGguYWJzKG9wdGlvbnMubnVtTGluZXMpO1xuICBmaWxlcyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCBpZHgpO1xuXG4gIGlmIChwaXBlKSB7XG4gICAgZmlsZXMudW5zaGlmdCgnLScpO1xuICB9XG5cbiAgdmFyIHNob3VsZEFwcGVuZE5ld2xpbmUgPSBmYWxzZTtcbiAgZmlsZXMuZm9yRWFjaChmdW5jdGlvbiAoZmlsZSkge1xuICAgIGlmIChmaWxlICE9PSAnLScpIHtcbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhmaWxlKSkge1xuICAgICAgICBjb21tb24uZXJyb3IoJ25vIHN1Y2ggZmlsZSBvciBkaXJlY3Rvcnk6ICcgKyBmaWxlLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGVsc2UgaWYgKGNvbW1vbi5zdGF0Rm9sbG93TGlua3MoZmlsZSkuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICBjb21tb24uZXJyb3IoXCJlcnJvciByZWFkaW5nICdcIiArIGZpbGUgKyBcIic6IElzIGEgZGlyZWN0b3J5XCIsIHtcbiAgICAgICAgICBjb250aW51ZTogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgY29udGVudHMgPSBmaWxlID09PSAnLScgPyBwaXBlIDogZnMucmVhZEZpbGVTeW5jKGZpbGUsICd1dGY4Jyk7XG5cbiAgICB2YXIgbGluZXMgPSBjb250ZW50cy5zcGxpdCgnXFxuJyk7XG4gICAgaWYgKGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdID09PSAnJykge1xuICAgICAgbGluZXMucG9wKCk7XG4gICAgICBzaG91bGRBcHBlbmROZXdsaW5lID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2hvdWxkQXBwZW5kTmV3bGluZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIHRhaWwgPSB0YWlsLmNvbmNhdChsaW5lcy5zbGljZShvcHRpb25zLm51bUxpbmVzKSk7XG4gIH0pO1xuXG4gIGlmIChzaG91bGRBcHBlbmROZXdsaW5lKSB7XG4gICAgdGFpbC5wdXNoKCcnKTsgLy8gdG8gYWRkIGEgdHJhaWxpbmcgbmV3bGluZSBvbmNlIHdlIGpvaW5cbiAgfVxuICByZXR1cm4gdGFpbC5qb2luKCdcXG4nKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gX3RhaWw7XG4iLCJ2YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBvcyA9IHJlcXVpcmUoJ29zJyk7XG52YXIgZnMgPSByZXF1aXJlKCdmcycpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ3RlbXBkaXInLCBfdGVtcERpciwge1xuICBhbGxvd0dsb2JiaW5nOiBmYWxzZSxcbiAgd3JhcE91dHB1dDogZmFsc2UsXG59KTtcblxuLy8gUmV0dXJucyBmYWxzZSBpZiAnZGlyJyBpcyBub3QgYSB3cml0ZWFibGUgZGlyZWN0b3J5LCAnZGlyJyBvdGhlcndpc2VcbmZ1bmN0aW9uIHdyaXRlYWJsZURpcihkaXIpIHtcbiAgaWYgKCFkaXIgfHwgIWZzLmV4aXN0c1N5bmMoZGlyKSkgcmV0dXJuIGZhbHNlO1xuXG4gIGlmICghY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhkaXIpLmlzRGlyZWN0b3J5KCkpIHJldHVybiBmYWxzZTtcblxuICB2YXIgdGVzdEZpbGUgPSBkaXIgKyAnLycgKyBjb21tb24ucmFuZG9tRmlsZU5hbWUoKTtcbiAgdHJ5IHtcbiAgICBmcy53cml0ZUZpbGVTeW5jKHRlc3RGaWxlLCAnICcpO1xuICAgIGNvbW1vbi51bmxpbmtTeW5jKHRlc3RGaWxlKTtcbiAgICByZXR1cm4gZGlyO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLy8gVmFyaWFibGUgdG8gY2FjaGUgdGhlIHRlbXBkaXIgdmFsdWUgZm9yIHN1Y2Nlc3NpdmUgbG9va3Vwcy5cbnZhciBjYWNoZWRUZW1wRGlyO1xuXG4vL0Bcbi8vQCAjIyMgdGVtcGRpcigpXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCB2YXIgdG1wID0gdGVtcGRpcigpOyAvLyBcIi90bXBcIiBmb3IgbW9zdCAqbml4IHBsYXRmb3Jtc1xuLy9AIGBgYFxuLy9AXG4vL0AgU2VhcmNoZXMgYW5kIHJldHVybnMgc3RyaW5nIGNvbnRhaW5pbmcgYSB3cml0ZWFibGUsIHBsYXRmb3JtLWRlcGVuZGVudCB0ZW1wb3JhcnkgZGlyZWN0b3J5LlxuLy9AIEZvbGxvd3MgUHl0aG9uJ3MgW3RlbXBmaWxlIGFsZ29yaXRobV0oaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3RlbXBmaWxlLmh0bWwjdGVtcGZpbGUudGVtcGRpcikuXG5mdW5jdGlvbiBfdGVtcERpcigpIHtcbiAgaWYgKGNhY2hlZFRlbXBEaXIpIHJldHVybiBjYWNoZWRUZW1wRGlyO1xuXG4gIGNhY2hlZFRlbXBEaXIgPSB3cml0ZWFibGVEaXIob3MudG1wZGlyKCkpIHx8XG4gICAgICAgICAgICAgICAgICB3cml0ZWFibGVEaXIocHJvY2Vzcy5lbnYuVE1QRElSKSB8fFxuICAgICAgICAgICAgICAgICAgd3JpdGVhYmxlRGlyKHByb2Nlc3MuZW52LlRFTVApIHx8XG4gICAgICAgICAgICAgICAgICB3cml0ZWFibGVEaXIocHJvY2Vzcy5lbnYuVE1QKSB8fFxuICAgICAgICAgICAgICAgICAgd3JpdGVhYmxlRGlyKHByb2Nlc3MuZW52LldpbXAkU2NyYXBEaXIpIHx8IC8vIFJpc2NPU1xuICAgICAgICAgICAgICAgICAgd3JpdGVhYmxlRGlyKCdDOlxcXFxURU1QJykgfHwgLy8gV2luZG93c1xuICAgICAgICAgICAgICAgICAgd3JpdGVhYmxlRGlyKCdDOlxcXFxUTVAnKSB8fCAvLyBXaW5kb3dzXG4gICAgICAgICAgICAgICAgICB3cml0ZWFibGVEaXIoJ1xcXFxURU1QJykgfHwgLy8gV2luZG93c1xuICAgICAgICAgICAgICAgICAgd3JpdGVhYmxlRGlyKCdcXFxcVE1QJykgfHwgLy8gV2luZG93c1xuICAgICAgICAgICAgICAgICAgd3JpdGVhYmxlRGlyKCcvdG1wJykgfHxcbiAgICAgICAgICAgICAgICAgIHdyaXRlYWJsZURpcignL3Zhci90bXAnKSB8fFxuICAgICAgICAgICAgICAgICAgd3JpdGVhYmxlRGlyKCcvdXNyL3RtcCcpIHx8XG4gICAgICAgICAgICAgICAgICB3cml0ZWFibGVEaXIoJy4nKTsgLy8gbGFzdCByZXNvcnRcblxuICByZXR1cm4gY2FjaGVkVGVtcERpcjtcbn1cblxuLy8gSW5kaWNhdGVzIGlmIHRoZSB0ZW1wZGlyIHZhbHVlIGlzIGN1cnJlbnRseSBjYWNoZWQuIFRoaXMgaXMgZXhwb3NlZCBmb3IgdGVzdHNcbi8vIG9ubHkuIFRoZSByZXR1cm4gdmFsdWUgc2hvdWxkIG9ubHkgYmUgdGVzdGVkIGZvciB0cnV0aGluZXNzLlxuZnVuY3Rpb24gaXNDYWNoZWQoKSB7XG4gIHJldHVybiBjYWNoZWRUZW1wRGlyO1xufVxuXG4vLyBDbGVhcnMgdGhlIGNhY2hlZCB0ZW1wRGlyIHZhbHVlLCBpZiBvbmUgaXMgY2FjaGVkLiBUaGlzIGlzIGV4cG9zZWQgZm9yIHRlc3RzXG4vLyBvbmx5LlxuZnVuY3Rpb24gY2xlYXJDYWNoZSgpIHtcbiAgY2FjaGVkVGVtcERpciA9IHVuZGVmaW5lZDtcbn1cblxubW9kdWxlLmV4cG9ydHMudGVtcERpciA9IF90ZW1wRGlyO1xubW9kdWxlLmV4cG9ydHMuaXNDYWNoZWQgPSBpc0NhY2hlZDtcbm1vZHVsZS5leHBvcnRzLmNsZWFyQ2FjaGUgPSBjbGVhckNhY2hlO1xuIiwidmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgZnMgPSByZXF1aXJlKCdmcycpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ3Rlc3QnLCBfdGVzdCwge1xuICBjbWRPcHRpb25zOiB7XG4gICAgJ2InOiAnYmxvY2snLFxuICAgICdjJzogJ2NoYXJhY3RlcicsXG4gICAgJ2QnOiAnZGlyZWN0b3J5JyxcbiAgICAnZSc6ICdleGlzdHMnLFxuICAgICdmJzogJ2ZpbGUnLFxuICAgICdMJzogJ2xpbmsnLFxuICAgICdwJzogJ3BpcGUnLFxuICAgICdTJzogJ3NvY2tldCcsXG4gIH0sXG4gIHdyYXBPdXRwdXQ6IGZhbHNlLFxuICBhbGxvd0dsb2JiaW5nOiBmYWxzZSxcbn0pO1xuXG5cbi8vQFxuLy9AICMjIyB0ZXN0KGV4cHJlc3Npb24pXG4vL0Bcbi8vQCBBdmFpbGFibGUgZXhwcmVzc2lvbiBwcmltYXJpZXM6XG4vL0Bcbi8vQCArIGAnLWInLCAncGF0aCdgOiB0cnVlIGlmIHBhdGggaXMgYSBibG9jayBkZXZpY2Vcbi8vQCArIGAnLWMnLCAncGF0aCdgOiB0cnVlIGlmIHBhdGggaXMgYSBjaGFyYWN0ZXIgZGV2aWNlXG4vL0AgKyBgJy1kJywgJ3BhdGgnYDogdHJ1ZSBpZiBwYXRoIGlzIGEgZGlyZWN0b3J5XG4vL0AgKyBgJy1lJywgJ3BhdGgnYDogdHJ1ZSBpZiBwYXRoIGV4aXN0c1xuLy9AICsgYCctZicsICdwYXRoJ2A6IHRydWUgaWYgcGF0aCBpcyBhIHJlZ3VsYXIgZmlsZVxuLy9AICsgYCctTCcsICdwYXRoJ2A6IHRydWUgaWYgcGF0aCBpcyBhIHN5bWJvbGljIGxpbmtcbi8vQCArIGAnLXAnLCAncGF0aCdgOiB0cnVlIGlmIHBhdGggaXMgYSBwaXBlIChGSUZPKVxuLy9AICsgYCctUycsICdwYXRoJ2A6IHRydWUgaWYgcGF0aCBpcyBhIHNvY2tldFxuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgaWYgKHRlc3QoJy1kJywgcGF0aCkpIHsgLyogZG8gc29tZXRoaW5nIHdpdGggZGlyICovIH07XG4vL0AgaWYgKCF0ZXN0KCctZicsIHBhdGgpKSBjb250aW51ZTsgLy8gc2tpcCBpZiBpdCdzIGEgcmVndWxhciBmaWxlXG4vL0AgYGBgXG4vL0Bcbi8vQCBFdmFsdWF0ZXMgYGV4cHJlc3Npb25gIHVzaW5nIHRoZSBhdmFpbGFibGUgcHJpbWFyaWVzIGFuZCByZXR1cm5zIGNvcnJlc3BvbmRpbmcgdmFsdWUuXG5mdW5jdGlvbiBfdGVzdChvcHRpb25zLCBwYXRoKSB7XG4gIGlmICghcGF0aCkgY29tbW9uLmVycm9yKCdubyBwYXRoIGdpdmVuJyk7XG5cbiAgdmFyIGNhbkludGVycHJldCA9IGZhbHNlO1xuICBPYmplY3Qua2V5cyhvcHRpb25zKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICBpZiAob3B0aW9uc1trZXldID09PSB0cnVlKSB7XG4gICAgICBjYW5JbnRlcnByZXQgPSB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgaWYgKCFjYW5JbnRlcnByZXQpIGNvbW1vbi5lcnJvcignY291bGQgbm90IGludGVycHJldCBleHByZXNzaW9uJyk7XG5cbiAgaWYgKG9wdGlvbnMubGluaykge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gY29tbW9uLnN0YXROb0ZvbGxvd0xpbmtzKHBhdGgpLmlzU3ltYm9saWNMaW5rKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGlmICghZnMuZXhpc3RzU3luYyhwYXRoKSkgcmV0dXJuIGZhbHNlO1xuXG4gIGlmIChvcHRpb25zLmV4aXN0cykgcmV0dXJuIHRydWU7XG5cbiAgdmFyIHN0YXRzID0gY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhwYXRoKTtcblxuICBpZiAob3B0aW9ucy5ibG9jaykgcmV0dXJuIHN0YXRzLmlzQmxvY2tEZXZpY2UoKTtcblxuICBpZiAob3B0aW9ucy5jaGFyYWN0ZXIpIHJldHVybiBzdGF0cy5pc0NoYXJhY3RlckRldmljZSgpO1xuXG4gIGlmIChvcHRpb25zLmRpcmVjdG9yeSkgcmV0dXJuIHN0YXRzLmlzRGlyZWN0b3J5KCk7XG5cbiAgaWYgKG9wdGlvbnMuZmlsZSkgcmV0dXJuIHN0YXRzLmlzRmlsZSgpO1xuXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIGlmIChvcHRpb25zLnBpcGUpIHJldHVybiBzdGF0cy5pc0ZJRk8oKTtcblxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICBpZiAob3B0aW9ucy5zb2NrZXQpIHJldHVybiBzdGF0cy5pc1NvY2tldCgpO1xuXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIHJldHVybiBmYWxzZTsgLy8gZmFsbGJhY2tcbn0gLy8gdGVzdFxubW9kdWxlLmV4cG9ydHMgPSBfdGVzdDtcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcbnZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ3RvJywgX3RvLCB7XG4gIHBpcGVPbmx5OiB0cnVlLFxuICB3cmFwT3V0cHV0OiBmYWxzZSxcbn0pO1xuXG4vL0Bcbi8vQCAjIyMgU2hlbGxTdHJpbmcucHJvdG90eXBlLnRvKGZpbGUpXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBjYXQoJ2lucHV0LnR4dCcpLnRvKCdvdXRwdXQudHh0Jyk7XG4vL0AgYGBgXG4vL0Bcbi8vQCBBbmFsb2dvdXMgdG8gdGhlIHJlZGlyZWN0aW9uIG9wZXJhdG9yIGA+YCBpbiBVbml4LCBidXQgd29ya3Mgd2l0aFxuLy9AIGBTaGVsbFN0cmluZ3NgIChzdWNoIGFzIHRob3NlIHJldHVybmVkIGJ5IGBjYXRgLCBgZ3JlcGAsIGV0Yy4pLiBfTGlrZSBVbml4XG4vL0AgcmVkaXJlY3Rpb25zLCBgdG8oKWAgd2lsbCBvdmVyd3JpdGUgYW55IGV4aXN0aW5nIGZpbGUhX1xuZnVuY3Rpb24gX3RvKG9wdGlvbnMsIGZpbGUpIHtcbiAgaWYgKCFmaWxlKSBjb21tb24uZXJyb3IoJ3dyb25nIGFyZ3VtZW50cycpO1xuXG4gIGlmICghZnMuZXhpc3RzU3luYyhwYXRoLmRpcm5hbWUoZmlsZSkpKSB7XG4gICAgY29tbW9uLmVycm9yKCdubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5OiAnICsgcGF0aC5kaXJuYW1lKGZpbGUpKTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgZnMud3JpdGVGaWxlU3luYyhmaWxlLCB0aGlzLnN0ZG91dCB8fCB0aGlzLnRvU3RyaW5nKCksICd1dGY4Jyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIGNvbW1vbi5lcnJvcignY291bGQgbm90IHdyaXRlIHRvIGZpbGUgKGNvZGUgJyArIGUuY29kZSArICcpOiAnICsgZmlsZSwgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgfVxufVxubW9kdWxlLmV4cG9ydHMgPSBfdG87XG4iLCJ2YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG52YXIgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcblxuY29tbW9uLnJlZ2lzdGVyKCd0b0VuZCcsIF90b0VuZCwge1xuICBwaXBlT25seTogdHJ1ZSxcbiAgd3JhcE91dHB1dDogZmFsc2UsXG59KTtcblxuLy9AXG4vL0AgIyMjIFNoZWxsU3RyaW5nLnByb3RvdHlwZS50b0VuZChmaWxlKVxuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgY2F0KCdpbnB1dC50eHQnKS50b0VuZCgnb3V0cHV0LnR4dCcpO1xuLy9AIGBgYFxuLy9AXG4vL0AgQW5hbG9nb3VzIHRvIHRoZSByZWRpcmVjdC1hbmQtYXBwZW5kIG9wZXJhdG9yIGA+PmAgaW4gVW5peCwgYnV0IHdvcmtzIHdpdGhcbi8vQCBgU2hlbGxTdHJpbmdzYCAoc3VjaCBhcyB0aG9zZSByZXR1cm5lZCBieSBgY2F0YCwgYGdyZXBgLCBldGMuKS5cbmZ1bmN0aW9uIF90b0VuZChvcHRpb25zLCBmaWxlKSB7XG4gIGlmICghZmlsZSkgY29tbW9uLmVycm9yKCd3cm9uZyBhcmd1bWVudHMnKTtcblxuICBpZiAoIWZzLmV4aXN0c1N5bmMocGF0aC5kaXJuYW1lKGZpbGUpKSkge1xuICAgIGNvbW1vbi5lcnJvcignbm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeTogJyArIHBhdGguZGlybmFtZShmaWxlKSk7XG4gIH1cblxuICB0cnkge1xuICAgIGZzLmFwcGVuZEZpbGVTeW5jKGZpbGUsIHRoaXMuc3Rkb3V0IHx8IHRoaXMudG9TdHJpbmcoKSwgJ3V0ZjgnKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfSBjYXRjaCAoZSkge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgY29tbW9uLmVycm9yKCdjb3VsZCBub3QgYXBwZW5kIHRvIGZpbGUgKGNvZGUgJyArIGUuY29kZSArICcpOiAnICsgZmlsZSwgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgfVxufVxubW9kdWxlLmV4cG9ydHMgPSBfdG9FbmQ7XG4iLCJ2YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG5cbmNvbW1vbi5yZWdpc3RlcigndG91Y2gnLCBfdG91Y2gsIHtcbiAgY21kT3B0aW9uczoge1xuICAgICdhJzogJ2F0aW1lX29ubHknLFxuICAgICdjJzogJ25vX2NyZWF0ZScsXG4gICAgJ2QnOiAnZGF0ZScsXG4gICAgJ20nOiAnbXRpbWVfb25seScsXG4gICAgJ3InOiAncmVmZXJlbmNlJyxcbiAgfSxcbn0pO1xuXG4vL0Bcbi8vQCAjIyMgdG91Y2goW29wdGlvbnMsXSBmaWxlIFssIGZpbGUgLi4uXSlcbi8vQCAjIyMgdG91Y2goW29wdGlvbnMsXSBmaWxlX2FycmF5KVxuLy9AXG4vL0AgQXZhaWxhYmxlIG9wdGlvbnM6XG4vL0Bcbi8vQCArIGAtYWA6IENoYW5nZSBvbmx5IHRoZSBhY2Nlc3MgdGltZVxuLy9AICsgYC1jYDogRG8gbm90IGNyZWF0ZSBhbnkgZmlsZXNcbi8vQCArIGAtbWA6IENoYW5nZSBvbmx5IHRoZSBtb2RpZmljYXRpb24gdGltZVxuLy9AICsgYC1kIERBVEVgOiBQYXJzZSBgREFURWAgYW5kIHVzZSBpdCBpbnN0ZWFkIG9mIGN1cnJlbnQgdGltZVxuLy9AICsgYC1yIEZJTEVgOiBVc2UgYEZJTEVgJ3MgdGltZXMgaW5zdGVhZCBvZiBjdXJyZW50IHRpbWVcbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIHRvdWNoKCdzb3VyY2UuanMnKTtcbi8vQCB0b3VjaCgnLWMnLCAnL3BhdGgvdG8vc29tZS9kaXIvc291cmNlLmpzJyk7XG4vL0AgdG91Y2goeyAnLXInOiBGSUxFIH0sICcvcGF0aC90by9zb21lL2Rpci9zb3VyY2UuanMnKTtcbi8vQCBgYGBcbi8vQFxuLy9AIFVwZGF0ZSB0aGUgYWNjZXNzIGFuZCBtb2RpZmljYXRpb24gdGltZXMgb2YgZWFjaCBgRklMRWAgdG8gdGhlIGN1cnJlbnQgdGltZS5cbi8vQCBBIGBGSUxFYCBhcmd1bWVudCB0aGF0IGRvZXMgbm90IGV4aXN0IGlzIGNyZWF0ZWQgZW1wdHksIHVubGVzcyBgLWNgIGlzIHN1cHBsaWVkLlxuLy9AIFRoaXMgaXMgYSBwYXJ0aWFsIGltcGxlbWVudGF0aW9uIG9mIFtgdG91Y2goMSlgXShodHRwOi8vbGludXguZGllLm5ldC9tYW4vMS90b3VjaCkuXG5mdW5jdGlvbiBfdG91Y2gob3B0cywgZmlsZXMpIHtcbiAgaWYgKCFmaWxlcykge1xuICAgIGNvbW1vbi5lcnJvcignbm8gZmlsZXMgZ2l2ZW4nKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZmlsZXMgPT09ICdzdHJpbmcnKSB7XG4gICAgZmlsZXMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gIH0gZWxzZSB7XG4gICAgY29tbW9uLmVycm9yKCdmaWxlIGFyZyBzaG91bGQgYmUgYSBzdHJpbmcgZmlsZSBwYXRoIG9yIGFuIEFycmF5IG9mIHN0cmluZyBmaWxlIHBhdGhzJyk7XG4gIH1cblxuICBmaWxlcy5mb3JFYWNoKGZ1bmN0aW9uIChmKSB7XG4gICAgdG91Y2hGaWxlKG9wdHMsIGYpO1xuICB9KTtcbiAgcmV0dXJuICcnO1xufVxuXG5mdW5jdGlvbiB0b3VjaEZpbGUob3B0cywgZmlsZSkge1xuICB2YXIgc3RhdCA9IHRyeVN0YXRGaWxlKGZpbGUpO1xuXG4gIGlmIChzdGF0ICYmIHN0YXQuaXNEaXJlY3RvcnkoKSkge1xuICAgIC8vIGRvbid0IGVycm9yIGp1c3QgZXhpdFxuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIGlmIHRoZSBmaWxlIGRvZXNuJ3QgYWxyZWFkeSBleGlzdCBhbmQgdGhlIHVzZXIgaGFzIHNwZWNpZmllZCAtLW5vLWNyZWF0ZSB0aGVuXG4gIC8vIHRoaXMgc2NyaXB0IGlzIGZpbmlzaGVkXG4gIGlmICghc3RhdCAmJiBvcHRzLm5vX2NyZWF0ZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIG9wZW4gdGhlIGZpbGUgYW5kIHRoZW4gY2xvc2UgaXQuIHRoaXMgd2lsbCBjcmVhdGUgaXQgaWYgaXQgZG9lc24ndCBleGlzdCBidXQgd2lsbFxuICAvLyBub3QgdHJ1bmNhdGUgdGhlIGZpbGVcbiAgZnMuY2xvc2VTeW5jKGZzLm9wZW5TeW5jKGZpbGUsICdhJykpO1xuXG4gIC8vXG4gIC8vIFNldCB0aW1lc3RhbXBzXG4gIC8vXG5cbiAgLy8gc2V0dXAgc29tZSBkZWZhdWx0c1xuICB2YXIgbm93ID0gbmV3IERhdGUoKTtcbiAgdmFyIG10aW1lID0gb3B0cy5kYXRlIHx8IG5vdztcbiAgdmFyIGF0aW1lID0gb3B0cy5kYXRlIHx8IG5vdztcblxuICAvLyB1c2UgcmVmZXJlbmNlIGZpbGVcbiAgaWYgKG9wdHMucmVmZXJlbmNlKSB7XG4gICAgdmFyIHJlZlN0YXQgPSB0cnlTdGF0RmlsZShvcHRzLnJlZmVyZW5jZSk7XG4gICAgaWYgKCFyZWZTdGF0KSB7XG4gICAgICBjb21tb24uZXJyb3IoJ2ZhaWxlZCB0byBnZXQgYXR0cmlidXRlc3Mgb2YgJyArIG9wdHMucmVmZXJlbmNlKTtcbiAgICB9XG4gICAgbXRpbWUgPSByZWZTdGF0Lm10aW1lO1xuICAgIGF0aW1lID0gcmVmU3RhdC5hdGltZTtcbiAgfSBlbHNlIGlmIChvcHRzLmRhdGUpIHtcbiAgICBtdGltZSA9IG9wdHMuZGF0ZTtcbiAgICBhdGltZSA9IG9wdHMuZGF0ZTtcbiAgfVxuXG4gIGlmIChvcHRzLmF0aW1lX29ubHkgJiYgb3B0cy5tdGltZV9vbmx5KSB7XG4gICAgLy8ga2VlcCB0aGUgbmV3IHZhbHVlcyBvZiBtdGltZSBhbmQgYXRpbWUgbGlrZSBHTlVcbiAgfSBlbHNlIGlmIChvcHRzLmF0aW1lX29ubHkpIHtcbiAgICBtdGltZSA9IHN0YXQubXRpbWU7XG4gIH0gZWxzZSBpZiAob3B0cy5tdGltZV9vbmx5KSB7XG4gICAgYXRpbWUgPSBzdGF0LmF0aW1lO1xuICB9XG5cbiAgZnMudXRpbWVzU3luYyhmaWxlLCBhdGltZSwgbXRpbWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF90b3VjaDtcblxuZnVuY3Rpb24gdHJ5U3RhdEZpbGUoZmlsZVBhdGgpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhmaWxlUGF0aCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuIiwidmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgZnMgPSByZXF1aXJlKCdmcycpO1xuXG4vLyBhZGQgYyBzcGFjZXMgdG8gdGhlIGxlZnQgb2Ygc3RyXG5mdW5jdGlvbiBscGFkKGMsIHN0cikge1xuICB2YXIgcmVzID0gJycgKyBzdHI7XG4gIGlmIChyZXMubGVuZ3RoIDwgYykge1xuICAgIHJlcyA9IEFycmF5KChjIC0gcmVzLmxlbmd0aCkgKyAxKS5qb2luKCcgJykgKyByZXM7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cblxuY29tbW9uLnJlZ2lzdGVyKCd1bmlxJywgX3VuaXEsIHtcbiAgY2FuUmVjZWl2ZVBpcGU6IHRydWUsXG4gIGNtZE9wdGlvbnM6IHtcbiAgICAnaSc6ICdpZ25vcmVDYXNlJyxcbiAgICAnYyc6ICdjb3VudCcsXG4gICAgJ2QnOiAnZHVwbGljYXRlcycsXG4gIH0sXG59KTtcblxuLy9AXG4vL0AgIyMjIHVuaXEoW29wdGlvbnMsXSBbaW5wdXQsIFtvdXRwdXRdXSlcbi8vQFxuLy9AIEF2YWlsYWJsZSBvcHRpb25zOlxuLy9AXG4vL0AgKyBgLWlgOiBJZ25vcmUgY2FzZSB3aGlsZSBjb21wYXJpbmdcbi8vQCArIGAtY2A6IFByZWZpeCBsaW5lcyBieSB0aGUgbnVtYmVyIG9mIG9jY3VycmVuY2VzXG4vL0AgKyBgLWRgOiBPbmx5IHByaW50IGR1cGxpY2F0ZSBsaW5lcywgb25lIGZvciBlYWNoIGdyb3VwIG9mIGlkZW50aWNhbCBsaW5lc1xuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgdW5pcSgnZm9vLnR4dCcpO1xuLy9AIHVuaXEoJy1pJywgJ2Zvby50eHQnKTtcbi8vQCB1bmlxKCctY2QnLCAnZm9vLnR4dCcsICdiYXIudHh0Jyk7XG4vL0AgYGBgXG4vL0Bcbi8vQCBGaWx0ZXIgYWRqYWNlbnQgbWF0Y2hpbmcgbGluZXMgZnJvbSBgaW5wdXRgLlxuZnVuY3Rpb24gX3VuaXEob3B0aW9ucywgaW5wdXQsIG91dHB1dCkge1xuICAvLyBDaGVjayBpZiB0aGlzIGlzIGNvbWluZyBmcm9tIGEgcGlwZVxuICB2YXIgcGlwZSA9IGNvbW1vbi5yZWFkRnJvbVBpcGUoKTtcblxuICBpZiAoIXBpcGUpIHtcbiAgICBpZiAoIWlucHV0KSBjb21tb24uZXJyb3IoJ25vIGlucHV0IGdpdmVuJyk7XG5cbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoaW5wdXQpKSB7XG4gICAgICBjb21tb24uZXJyb3IoaW5wdXQgKyAnOiBObyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5Jyk7XG4gICAgfSBlbHNlIGlmIChjb21tb24uc3RhdEZvbGxvd0xpbmtzKGlucHV0KS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICBjb21tb24uZXJyb3IoXCJlcnJvciByZWFkaW5nICdcIiArIGlucHV0ICsgXCInXCIpO1xuICAgIH1cbiAgfVxuICBpZiAob3V0cHV0ICYmIGZzLmV4aXN0c1N5bmMob3V0cHV0KSAmJiBjb21tb24uc3RhdEZvbGxvd0xpbmtzKG91dHB1dCkuaXNEaXJlY3RvcnkoKSkge1xuICAgIGNvbW1vbi5lcnJvcihvdXRwdXQgKyAnOiBJcyBhIGRpcmVjdG9yeScpO1xuICB9XG5cbiAgdmFyIGxpbmVzID0gKGlucHV0ID8gZnMucmVhZEZpbGVTeW5jKGlucHV0LCAndXRmOCcpIDogcGlwZSkuXG4gICAgICAgICAgICAgIHRyaW1SaWdodCgpLlxuICAgICAgICAgICAgICBzcGxpdCgnXFxuJyk7XG5cbiAgdmFyIGNvbXBhcmUgPSBmdW5jdGlvbiAoYSwgYikge1xuICAgIHJldHVybiBvcHRpb25zLmlnbm9yZUNhc2UgP1xuICAgICAgICAgICBhLnRvTG9jYWxlTG93ZXJDYXNlKCkubG9jYWxlQ29tcGFyZShiLnRvTG9jYWxlTG93ZXJDYXNlKCkpIDpcbiAgICAgICAgICAgYS5sb2NhbGVDb21wYXJlKGIpO1xuICB9O1xuICB2YXIgdW5pcWVkID0gbGluZXMucmVkdWNlUmlnaHQoZnVuY3Rpb24gKHJlcywgZSkge1xuICAgIC8vIFBlcmZvcm0gdW5pcSAtYyBvbiB0aGUgaW5wdXRcbiAgICBpZiAocmVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFt7IGNvdW50OiAxLCBsbjogZSB9XTtcbiAgICB9IGVsc2UgaWYgKGNvbXBhcmUocmVzWzBdLmxuLCBlKSA9PT0gMCkge1xuICAgICAgcmV0dXJuIFt7IGNvdW50OiByZXNbMF0uY291bnQgKyAxLCBsbjogZSB9XS5jb25jYXQocmVzLnNsaWNlKDEpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIFt7IGNvdW50OiAxLCBsbjogZSB9XS5jb25jYXQocmVzKTtcbiAgICB9XG4gIH0sIFtdKS5maWx0ZXIoZnVuY3Rpb24gKG9iaikge1xuICAgICAgICAgICAgICAgICAvLyBEbyB3ZSB3YW50IG9ubHkgZHVwbGljYXRlZCBvYmplY3RzP1xuICAgIHJldHVybiBvcHRpb25zLmR1cGxpY2F0ZXMgPyBvYmouY291bnQgPiAxIDogdHJ1ZTtcbiAgfSkubWFwKGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgICAgICAgICAgLy8gQXJlIHdlIHRyYWNraW5nIHRoZSBjb3VudHMgb2YgZWFjaCBsaW5lP1xuICAgIHJldHVybiAob3B0aW9ucy5jb3VudCA/IChscGFkKDcsIG9iai5jb3VudCkgKyAnICcpIDogJycpICsgb2JqLmxuO1xuICB9KS5qb2luKCdcXG4nKSArICdcXG4nO1xuXG4gIGlmIChvdXRwdXQpIHtcbiAgICAobmV3IGNvbW1vbi5TaGVsbFN0cmluZyh1bmlxZWQpKS50byhvdXRwdXQpO1xuICAgIC8vIGlmIHVuaXEgd3JpdGVzIHRvIG91dHB1dCwgbm90aGluZyBpcyBwYXNzZWQgdG8gdGhlIG5leHQgY29tbWFuZCBpbiB0aGUgcGlwZWxpbmUgKGlmIGFueSlcbiAgICByZXR1cm4gJyc7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHVuaXFlZDtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF91bmlxO1xuIiwidmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgZnMgPSByZXF1aXJlKCdmcycpO1xudmFyIHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG5cbmNvbW1vbi5yZWdpc3Rlcignd2hpY2gnLCBfd2hpY2gsIHtcbiAgYWxsb3dHbG9iYmluZzogZmFsc2UsXG4gIGNtZE9wdGlvbnM6IHtcbiAgICAnYSc6ICdhbGwnLFxuICB9LFxufSk7XG5cbi8vIFhQJ3Mgc3lzdGVtIGRlZmF1bHQgdmFsdWUgZm9yIGBQQVRIRVhUYCBzeXN0ZW0gdmFyaWFibGUsIGp1c3QgaW4gY2FzZSBpdCdzIG5vdFxuLy8gc2V0IG9uIFdpbmRvd3MuXG52YXIgWFBfREVGQVVMVF9QQVRIRVhUID0gJy5jb207LmV4ZTsuYmF0Oy5jbWQ7LnZiczsudmJlOy5qczsuanNlOy53c2Y7LndzaCc7XG5cbi8vIEZvciBlYXJsaWVyIHZlcnNpb25zIG9mIE5vZGVKUyB0aGF0IGRvZXNuJ3QgaGF2ZSBhIGxpc3Qgb2YgY29uc3RhbnRzICg8IHY2KVxudmFyIEZJTEVfRVhFQ1VUQUJMRV9NT0RFID0gMTtcblxuZnVuY3Rpb24gaXNXaW5kb3dzUGxhdGZvcm0oKSB7XG4gIHJldHVybiBwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInO1xufVxuXG4vLyBDcm9zcy1wbGF0Zm9ybSBtZXRob2QgZm9yIHNwbGl0dGluZyBlbnZpcm9ubWVudCBgUEFUSGAgdmFyaWFibGVzXG5mdW5jdGlvbiBzcGxpdFBhdGgocCkge1xuICByZXR1cm4gcCA/IHAuc3BsaXQocGF0aC5kZWxpbWl0ZXIpIDogW107XG59XG5cbi8vIFRlc3RzIGFyZSBydW5uaW5nIGFsbCBjYXNlcyBmb3IgdGhpcyBmdW5jIGJ1dCBpdCBzdGF5cyB1bmNvdmVyZWQgYnkgY29kZWNvdiBkdWUgdG8gdW5rbm93biByZWFzb25cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5mdW5jdGlvbiBpc0V4ZWN1dGFibGUocGF0aE5hbWUpIHtcbiAgdHJ5IHtcbiAgICAvLyBUT0RPKG5vZGUtc3VwcG9ydCk6IHJlcGxhY2Ugd2l0aCBmcy5jb25zdGFudHMuWF9PSyBvbmNlIHJlbW92ZSBzdXBwb3J0IGZvciBub2RlIDwgdjZcbiAgICBmcy5hY2Nlc3NTeW5jKHBhdGhOYW1lLCBGSUxFX0VYRUNVVEFCTEVfTU9ERSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY2hlY2tQYXRoKHBhdGhOYW1lKSB7XG4gIHJldHVybiBmcy5leGlzdHNTeW5jKHBhdGhOYW1lKSAmJiAhY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhwYXRoTmFtZSkuaXNEaXJlY3RvcnkoKVxuICAgICYmIChpc1dpbmRvd3NQbGF0Zm9ybSgpIHx8IGlzRXhlY3V0YWJsZShwYXRoTmFtZSkpO1xufVxuXG4vL0Bcbi8vQCAjIyMgd2hpY2goY29tbWFuZClcbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIHZhciBub2RlRXhlYyA9IHdoaWNoKCdub2RlJyk7XG4vL0AgYGBgXG4vL0Bcbi8vQCBTZWFyY2hlcyBmb3IgYGNvbW1hbmRgIGluIHRoZSBzeXN0ZW0ncyBgUEFUSGAuIE9uIFdpbmRvd3MsIHRoaXMgdXNlcyB0aGVcbi8vQCBgUEFUSEVYVGAgdmFyaWFibGUgdG8gYXBwZW5kIHRoZSBleHRlbnNpb24gaWYgaXQncyBub3QgYWxyZWFkeSBleGVjdXRhYmxlLlxuLy9AIFJldHVybnMgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIGFic29sdXRlIHBhdGggdG8gYGNvbW1hbmRgLlxuZnVuY3Rpb24gX3doaWNoKG9wdGlvbnMsIGNtZCkge1xuICBpZiAoIWNtZCkgY29tbW9uLmVycm9yKCdtdXN0IHNwZWNpZnkgY29tbWFuZCcpO1xuXG4gIHZhciBpc1dpbmRvd3MgPSBpc1dpbmRvd3NQbGF0Zm9ybSgpO1xuICB2YXIgcGF0aEFycmF5ID0gc3BsaXRQYXRoKHByb2Nlc3MuZW52LlBBVEgpO1xuXG4gIHZhciBxdWVyeU1hdGNoZXMgPSBbXTtcblxuICAvLyBObyByZWxhdGl2ZS9hYnNvbHV0ZSBwYXRocyBwcm92aWRlZD9cbiAgaWYgKGNtZC5pbmRleE9mKCcvJykgPT09IC0xKSB7XG4gICAgLy8gQXNzdW1lIHRoYXQgdGhlcmUgYXJlIG5vIGV4dGVuc2lvbnMgdG8gYXBwZW5kIHRvIHF1ZXJpZXMgKHRoaXMgaXMgdGhlXG4gICAgLy8gY2FzZSBmb3IgdW5peClcbiAgICB2YXIgcGF0aEV4dEFycmF5ID0gWycnXTtcbiAgICBpZiAoaXNXaW5kb3dzKSB7XG4gICAgICAvLyBJbiBjYXNlIHRoZSBQQVRIRVhUIHZhcmlhYmxlIGlzIHNvbWVob3cgbm90IHNldCAoZS5nLlxuICAgICAgLy8gY2hpbGRfcHJvY2Vzcy5zcGF3biB3aXRoIGFuIGVtcHR5IGVudmlyb25tZW50KSwgdXNlIHRoZSBYUCBkZWZhdWx0LlxuICAgICAgdmFyIHBhdGhFeHRFbnYgPSBwcm9jZXNzLmVudi5QQVRIRVhUIHx8IFhQX0RFRkFVTFRfUEFUSEVYVDtcbiAgICAgIHBhdGhFeHRBcnJheSA9IHNwbGl0UGF0aChwYXRoRXh0RW52LnRvVXBwZXJDYXNlKCkpO1xuICAgIH1cblxuICAgIC8vIFNlYXJjaCBmb3IgY29tbWFuZCBpbiBQQVRIXG4gICAgZm9yICh2YXIgayA9IDA7IGsgPCBwYXRoQXJyYXkubGVuZ3RoOyBrKyspIHtcbiAgICAgIC8vIGFscmVhZHkgZm91bmQgaXRcbiAgICAgIGlmIChxdWVyeU1hdGNoZXMubGVuZ3RoID4gMCAmJiAhb3B0aW9ucy5hbGwpIGJyZWFrO1xuXG4gICAgICB2YXIgYXR0ZW1wdCA9IHBhdGgucmVzb2x2ZShwYXRoQXJyYXlba10sIGNtZCk7XG5cbiAgICAgIGlmIChpc1dpbmRvd3MpIHtcbiAgICAgICAgYXR0ZW1wdCA9IGF0dGVtcHQudG9VcHBlckNhc2UoKTtcbiAgICAgIH1cblxuICAgICAgdmFyIG1hdGNoID0gYXR0ZW1wdC5tYXRjaCgvXFwuW148PjpcIi9cXHw/Ki5dKyQvKTtcbiAgICAgIGlmIChtYXRjaCAmJiBwYXRoRXh0QXJyYXkuaW5kZXhPZihtYXRjaFswXSkgPj0gMCkgeyAvLyB0aGlzIGlzIFdpbmRvd3Mtb25seVxuICAgICAgICAvLyBUaGUgdXNlciB0eXBlZCBhIHF1ZXJ5IHdpdGggdGhlIGZpbGUgZXh0ZW5zaW9uLCBsaWtlXG4gICAgICAgIC8vIGB3aGljaCgnbm9kZS5leGUnKWBcbiAgICAgICAgaWYgKGNoZWNrUGF0aChhdHRlbXB0KSkge1xuICAgICAgICAgIHF1ZXJ5TWF0Y2hlcy5wdXNoKGF0dGVtcHQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgeyAvLyBBbGwtcGxhdGZvcm1zXG4gICAgICAgIC8vIEN5Y2xlIHRocm91Z2ggdGhlIFBBVEhFWFQgYXJyYXksIGFuZCBjaGVjayBlYWNoIGV4dGVuc2lvblxuICAgICAgICAvLyBOb3RlOiB0aGUgYXJyYXkgaXMgYWx3YXlzIFsnJ10gb24gVW5peFxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBhdGhFeHRBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZhciBleHQgPSBwYXRoRXh0QXJyYXlbaV07XG4gICAgICAgICAgdmFyIG5ld0F0dGVtcHQgPSBhdHRlbXB0ICsgZXh0O1xuICAgICAgICAgIGlmIChjaGVja1BhdGgobmV3QXR0ZW1wdCkpIHtcbiAgICAgICAgICAgIHF1ZXJ5TWF0Y2hlcy5wdXNoKG5ld0F0dGVtcHQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKGNoZWNrUGF0aChjbWQpKSB7IC8vIGEgdmFsaWQgYWJzb2x1dGUgb3IgcmVsYXRpdmUgcGF0aFxuICAgIHF1ZXJ5TWF0Y2hlcy5wdXNoKHBhdGgucmVzb2x2ZShjbWQpKTtcbiAgfVxuXG4gIGlmIChxdWVyeU1hdGNoZXMubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiBvcHRpb25zLmFsbCA/IHF1ZXJ5TWF0Y2hlcyA6IHF1ZXJ5TWF0Y2hlc1swXTtcbiAgfVxuICByZXR1cm4gb3B0aW9ucy5hbGwgPyBbXSA6IG51bGw7XG59XG5tb2R1bGUuZXhwb3J0cyA9IF93aGljaDtcbiIsInZhciBtYXAgPSB7XG5cdFwiLi9jYXRcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9jYXQuanNcIixcblx0XCIuL2NhdC5qc1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2NhdC5qc1wiLFxuXHRcIi4vY2RcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9jZC5qc1wiLFxuXHRcIi4vY2QuanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9jZC5qc1wiLFxuXHRcIi4vY2htb2RcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9jaG1vZC5qc1wiLFxuXHRcIi4vY2htb2QuanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9jaG1vZC5qc1wiLFxuXHRcIi4vY29tbW9uXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvY29tbW9uLmpzXCIsXG5cdFwiLi9jb21tb24uanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9jb21tb24uanNcIixcblx0XCIuL2NwXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvY3AuanNcIixcblx0XCIuL2NwLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvY3AuanNcIixcblx0XCIuL2RpcnNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9kaXJzLmpzXCIsXG5cdFwiLi9kaXJzLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvZGlycy5qc1wiLFxuXHRcIi4vZWNob1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2VjaG8uanNcIixcblx0XCIuL2VjaG8uanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9lY2hvLmpzXCIsXG5cdFwiLi9lcnJvclwiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2Vycm9yLmpzXCIsXG5cdFwiLi9lcnJvci5qc1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2Vycm9yLmpzXCIsXG5cdFwiLi9leGVjXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvZXhlYy5qc1wiLFxuXHRcIi4vZXhlYy1jaGlsZFwiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2V4ZWMtY2hpbGQuanNcIixcblx0XCIuL2V4ZWMtY2hpbGQuanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9leGVjLWNoaWxkLmpzXCIsXG5cdFwiLi9leGVjLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvZXhlYy5qc1wiLFxuXHRcIi4vZmluZFwiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2ZpbmQuanNcIixcblx0XCIuL2ZpbmQuanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9maW5kLmpzXCIsXG5cdFwiLi9ncmVwXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvZ3JlcC5qc1wiLFxuXHRcIi4vZ3JlcC5qc1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2dyZXAuanNcIixcblx0XCIuL2hlYWRcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9oZWFkLmpzXCIsXG5cdFwiLi9oZWFkLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvaGVhZC5qc1wiLFxuXHRcIi4vbG5cIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9sbi5qc1wiLFxuXHRcIi4vbG4uanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9sbi5qc1wiLFxuXHRcIi4vbHNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9scy5qc1wiLFxuXHRcIi4vbHMuanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9scy5qc1wiLFxuXHRcIi4vbWtkaXJcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9ta2Rpci5qc1wiLFxuXHRcIi4vbWtkaXIuanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9ta2Rpci5qc1wiLFxuXHRcIi4vbXZcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9tdi5qc1wiLFxuXHRcIi4vbXYuanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9tdi5qc1wiLFxuXHRcIi4vcG9wZFwiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3BvcGQuanNcIixcblx0XCIuL3BvcGQuanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9wb3BkLmpzXCIsXG5cdFwiLi9wdXNoZFwiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3B1c2hkLmpzXCIsXG5cdFwiLi9wdXNoZC5qc1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3B1c2hkLmpzXCIsXG5cdFwiLi9wd2RcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9wd2QuanNcIixcblx0XCIuL3B3ZC5qc1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3B3ZC5qc1wiLFxuXHRcIi4vcm1cIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9ybS5qc1wiLFxuXHRcIi4vcm0uanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9ybS5qc1wiLFxuXHRcIi4vc2VkXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvc2VkLmpzXCIsXG5cdFwiLi9zZWQuanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9zZWQuanNcIixcblx0XCIuL3NldFwiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3NldC5qc1wiLFxuXHRcIi4vc2V0LmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvc2V0LmpzXCIsXG5cdFwiLi9zb3J0XCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvc29ydC5qc1wiLFxuXHRcIi4vc29ydC5qc1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3NvcnQuanNcIixcblx0XCIuL3RhaWxcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy90YWlsLmpzXCIsXG5cdFwiLi90YWlsLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvdGFpbC5qc1wiLFxuXHRcIi4vdGVtcGRpclwiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3RlbXBkaXIuanNcIixcblx0XCIuL3RlbXBkaXIuanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy90ZW1wZGlyLmpzXCIsXG5cdFwiLi90ZXN0XCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvdGVzdC5qc1wiLFxuXHRcIi4vdGVzdC5qc1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3Rlc3QuanNcIixcblx0XCIuL3RvXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvdG8uanNcIixcblx0XCIuL3RvLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvdG8uanNcIixcblx0XCIuL3RvRW5kXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvdG9FbmQuanNcIixcblx0XCIuL3RvRW5kLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvdG9FbmQuanNcIixcblx0XCIuL3RvdWNoXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvdG91Y2guanNcIixcblx0XCIuL3RvdWNoLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvdG91Y2guanNcIixcblx0XCIuL3VuaXFcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy91bmlxLmpzXCIsXG5cdFwiLi91bmlxLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvdW5pcS5qc1wiLFxuXHRcIi4vd2hpY2hcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy93aGljaC5qc1wiLFxuXHRcIi4vd2hpY2guanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy93aGljaC5qc1wiXG59O1xuXG5cbmZ1bmN0aW9uIHdlYnBhY2tDb250ZXh0KHJlcSkge1xuXHR2YXIgaWQgPSB3ZWJwYWNrQ29udGV4dFJlc29sdmUocmVxKTtcblx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oaWQpO1xufVxuZnVuY3Rpb24gd2VicGFja0NvbnRleHRSZXNvbHZlKHJlcSkge1xuXHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKG1hcCwgcmVxKSkge1xuXHRcdHZhciBlID0gbmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIiArIHJlcSArIFwiJ1wiKTtcblx0XHRlLmNvZGUgPSAnTU9EVUxFX05PVF9GT1VORCc7XG5cdFx0dGhyb3cgZTtcblx0fVxuXHRyZXR1cm4gbWFwW3JlcV07XG59XG53ZWJwYWNrQ29udGV4dC5rZXlzID0gZnVuY3Rpb24gd2VicGFja0NvbnRleHRLZXlzKCkge1xuXHRyZXR1cm4gT2JqZWN0LmtleXMobWFwKTtcbn07XG53ZWJwYWNrQ29udGV4dC5yZXNvbHZlID0gd2VicGFja0NvbnRleHRSZXNvbHZlO1xubW9kdWxlLmV4cG9ydHMgPSB3ZWJwYWNrQ29udGV4dDtcbndlYnBhY2tDb250ZXh0LmlkID0gXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYyBzeW5jIHJlY3Vyc2l2ZSBeXFxcXC5cXFxcLy4qJFwiOyIsImltcG9ydCB7IGluamVjdGFibGUgfSBmcm9tICdpbnZlcnNpZnknXG5cbmltcG9ydCAqIGFzIHRhc2tMaWIgZnJvbSAnYXp1cmUtcGlwZWxpbmVzLXRhc2stbGliL3Rhc2snXG5pbXBvcnQgKiBhcyB0b29sTGliIGZyb20gJ2F6dXJlLXBpcGVsaW5lcy10b29sLWxpYi90b29sJ1xuXG5pbXBvcnQgeyBJQnVpbGRBZ2VudCwgSUV4ZWNSZXN1bHQgfSBmcm9tICcuLi8uLi9jb3JlL21vZGVscydcbmltcG9ydCB7IElSZXF1ZXN0T3B0aW9ucyB9IGZyb20gJ3R5cGVkLXJlc3QtY2xpZW50L0ludGVyZmFjZXMnXG5cbkBpbmplY3RhYmxlKClcbmNsYXNzIEJ1aWxkQWdlbnQgaW1wbGVtZW50cyBJQnVpbGRBZ2VudCB7XG4gICAgcHVibGljIGdldCBhZ2VudE5hbWUoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuICdBenVyZSBQaXBlbGluZXMnXG4gICAgfVxuXG4gICAgcHVibGljIHByb3h5Q29uZmlndXJhdGlvbih1cmw6IHN0cmluZyk6IElSZXF1ZXN0T3B0aW9ucyB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBwcm94eTogdGFza0xpYi5nZXRIdHRwUHJveHlDb25maWd1cmF0aW9uKHVybCksXG4gICAgICAgICAgICBjZXJ0OiB0YXNrTGliLmdldEh0dHBDZXJ0Q29uZmlndXJhdGlvbigpLFxuICAgICAgICAgICAgaWdub3JlU3NsRXJyb3I6ICEhdGFza0xpYi5nZXRWYXJpYWJsZSgnQWdlbnQuU2tpcENlcnRWYWxpZGF0aW9uJylcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBmaW5kKHRvb2xOYW1lOiBzdHJpbmcsIHZlcnNpb25TcGVjOiBzdHJpbmcsIGFyY2g/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdG9vbExpYi5maW5kTG9jYWxUb29sKHRvb2xOYW1lLCB2ZXJzaW9uU3BlYywgYXJjaClcbiAgICB9XG5cbiAgICBwdWJsaWMgY2FjaGVEaXIoXG4gICAgICAgIHNvdXJjZURpcjogc3RyaW5nLFxuICAgICAgICB0b29sOiBzdHJpbmcsXG4gICAgICAgIHZlcnNpb246IHN0cmluZyxcbiAgICAgICAgYXJjaD86IHN0cmluZ1xuICAgICk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiB0b29sTGliLmNhY2hlRGlyKHNvdXJjZURpciwgdG9vbCwgdmVyc2lvbiwgYXJjaClcbiAgICB9XG5cbiAgICBwdWJsaWMgY3JlYXRlVGVtcERpcigpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRhc2tMaWIuZ2V0VmFyaWFibGUoJ0FnZW50LlRlbXBEaXJlY3RvcnknKSlcbiAgICB9XG5cbiAgICBwdWJsaWMgZGVidWcobWVzc2FnZTogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIHRhc2tMaWIuZGVidWcobWVzc2FnZSlcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0RmFpbGVkKG1lc3NhZ2U6IHN0cmluZywgZG9uZT86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgdGFza0xpYi5zZXRSZXN1bHQodGFza0xpYi5UYXNrUmVzdWx0LkZhaWxlZCwgbWVzc2FnZSwgZG9uZSlcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0U3VjY2VlZGVkKG1lc3NhZ2U6IHN0cmluZywgZG9uZT86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgdGFza0xpYi5zZXRSZXN1bHQodGFza0xpYi5UYXNrUmVzdWx0LlN1Y2NlZWRlZCwgbWVzc2FnZSwgZG9uZSlcbiAgICB9XG5cbiAgICBwdWJsaWMgZXhwb3J0VmFyaWFibGUobmFtZTogc3RyaW5nLCB2YWw6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICB0YXNrTGliLnNldFZhcmlhYmxlKG5hbWUsIHZhbClcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0VmFyaWFibGUobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRhc2tMaWIuZ2V0VmFyaWFibGUobmFtZSlcbiAgICB9XG5cbiAgICBwdWJsaWMgYWRkUGF0aChpbnB1dFBhdGg6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICB0b29sTGliLnByZXBlbmRQYXRoKGlucHV0UGF0aClcbiAgICB9XG5cbiAgICBwdWJsaWMgd2hpY2godG9vbDogc3RyaW5nLCBjaGVjaz86IGJvb2xlYW4pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRhc2tMaWIud2hpY2godG9vbCwgY2hlY2spKVxuICAgIH1cblxuICAgIHB1YmxpYyBleGVjKGV4ZWM6IHN0cmluZywgYXJnczogc3RyaW5nW10pOiBQcm9taXNlPElFeGVjUmVzdWx0PiB7XG4gICAgICAgIGNvbnN0IHRyID0gdGFza0xpYi50b29sKGV4ZWMpXG4gICAgICAgIHRyLmFyZyhhcmdzKVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRyLmV4ZWNTeW5jKClcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgICBjb2RlOiByZXN1bHQuY29kZSxcbiAgICAgICAgICAgIGVycm9yOiByZXN1bHQuZXJyb3IsXG4gICAgICAgICAgICBzdGRlcnI6IHJlc3VsdC5zdGRlcnIsXG4gICAgICAgICAgICBzdGRvdXQ6IHJlc3VsdC5zdGRvdXRcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0U291cmNlRGlyKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFZhcmlhYmxlKCdCdWlsZC5Tb3VyY2VzRGlyZWN0b3J5JylcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0T3V0cHV0KG5hbWU6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICB0YXNrTGliLnNldFZhcmlhYmxlKG5hbWUsIHZhbHVlKVxuICAgIH1cblxuICAgIHB1YmxpYyBnZXRJbnB1dChpbnB1dDogc3RyaW5nLCByZXF1aXJlZD86IGJvb2xlYW4pOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGFza0xpYi5nZXRJbnB1dChpbnB1dCwgcmVxdWlyZWQpPy50cmltKClcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0TGlzdElucHV0KGlucHV0OiBzdHJpbmcsIHJlcXVpcmVkPzogYm9vbGVhbik6IHN0cmluZ1tdIHtcbiAgICAgICAgcmV0dXJuIHRhc2tMaWJcbiAgICAgICAgICAgIC5nZXRJbnB1dChpbnB1dCwgcmVxdWlyZWQpXG4gICAgICAgICAgICAuc3BsaXQoJ1xcbicpXG4gICAgICAgICAgICAuZmlsdGVyKHggPT4geCAhPT0gJycpXG4gICAgfVxuXG4gICAgcHVibGljIGdldEJvb2xlYW5JbnB1dChpbnB1dDogc3RyaW5nLCByZXF1aXJlZD86IGJvb2xlYW4pOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRhc2tMaWIuZ2V0Qm9vbElucHV0KGlucHV0LCByZXF1aXJlZClcbiAgICB9XG5cbiAgICBwdWJsaWMgaXNWYWxpZElucHV0RmlsZShpbnB1dDogc3RyaW5nLCBmaWxlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRhc2tMaWIuZmlsZVBhdGhTdXBwbGllZChpbnB1dCkgJiYgdGhpcy5maWxlRXhpc3RzKGZpbGUpXG4gICAgfVxuXG4gICAgcHVibGljIGZpbGVFeGlzdHMoZmlsZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0YXNrTGliLmV4aXN0KGZpbGUpICYmIHRhc2tMaWIuc3RhdHMoZmlsZSkuaXNGaWxlKClcbiAgICB9XG5cbiAgICBwdWJsaWMgZGlyZWN0b3J5RXhpc3RzKGZpbGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGFza0xpYi5leGlzdChmaWxlKSAmJiB0YXNrTGliLnN0YXRzKGZpbGUpLmlzRGlyZWN0b3J5KClcbiAgICB9XG59XG5cbmV4cG9ydCB7IEJ1aWxkQWdlbnQgfVxuIiwiaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnXG5pbXBvcnQgKiBhcyBvcyBmcm9tICdvcydcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCdcbmltcG9ydCAqIGFzIGh0dHAgZnJvbSAndHlwZWQtcmVzdC1jbGllbnQvSHR0cENsaWVudCdcblxuaW1wb3J0IHsgaW5qZWN0LCBpbmplY3RhYmxlIH0gZnJvbSAnaW52ZXJzaWZ5J1xuaW1wb3J0IHsgVFlQRVMsIElFeGVjUmVzdWx0LCBJQnVpbGRBZ2VudCB9IGZyb20gJy4vbW9kZWxzJ1xuaW1wb3J0IHsgSVZlcnNpb25NYW5hZ2VyIH0gZnJvbSAnLi92ZXJzaW9uTWFuYWdlcidcblxuZXhwb3J0IGludGVyZmFjZSBJRG90bmV0VG9vbCB7XG4gICAgZGlzYWJsZVRlbGVtZXRyeSgpOiB2b2lkXG4gICAgdG9vbEluc3RhbGwoXG4gICAgICAgIHRvb2xOYW1lOiBzdHJpbmcsXG4gICAgICAgIHZlcnNpb25TcGVjOiBzdHJpbmcsXG4gICAgICAgIGNoZWNrTGF0ZXN0OiBib29sZWFuLFxuICAgICAgICBpbmNsdWRlUHJlOiBib29sZWFuXG4gICAgKTogUHJvbWlzZTxzdHJpbmc+XG59XG5cbkBpbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBEb3RuZXRUb29sIGltcGxlbWVudHMgSURvdG5ldFRvb2wge1xuICAgIHByb3RlY3RlZCBidWlsZEFnZW50OiBJQnVpbGRBZ2VudFxuICAgIHByb3RlY3RlZCB2ZXJzaW9uTWFuYWdlcjogSVZlcnNpb25NYW5hZ2VyXG4gICAgcHJpdmF0ZSBodHRwQ2xpZW50OiBodHRwLkh0dHBDbGllbnRcblxuICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IG51Z2V0Um9vdDogc3RyaW5nID1cbiAgICAgICAgJ2h0dHBzOi8vYXBpLXYydjNzZWFyY2gtMC5udWdldC5vcmcvJ1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIEBpbmplY3QoVFlQRVMuSUJ1aWxkQWdlbnQpIGJ1aWxkQWdlbnQ6IElCdWlsZEFnZW50LFxuICAgICAgICBAaW5qZWN0KFRZUEVTLklWZXJzaW9uTWFuYWdlcikgdmVyc2lvbk1hbmFnZXI6IElWZXJzaW9uTWFuYWdlclxuICAgICkge1xuICAgICAgICB0aGlzLmJ1aWxkQWdlbnQgPSBidWlsZEFnZW50XG4gICAgICAgIHRoaXMudmVyc2lvbk1hbmFnZXIgPSB2ZXJzaW9uTWFuYWdlclxuICAgICAgICB0aGlzLmh0dHBDbGllbnQgPSBuZXcgaHR0cC5IdHRwQ2xpZW50KFxuICAgICAgICAgICAgJ2RvdG5ldCcsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICB0aGlzLmJ1aWxkQWdlbnQucHJveHlDb25maWd1cmF0aW9uKERvdG5ldFRvb2wubnVnZXRSb290KVxuICAgICAgICApXG4gICAgfVxuXG4gICAgcHVibGljIGRpc2FibGVUZWxlbWV0cnkoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5leHBvcnRWYXJpYWJsZSgnRE9UTkVUX0NMSV9URUxFTUVUUllfT1BUT1VUJywgJ3RydWUnKVxuICAgICAgICB0aGlzLmJ1aWxkQWdlbnQuZXhwb3J0VmFyaWFibGUoJ0RPVE5FVF9OT0xPR08nLCAndHJ1ZScpXG4gICAgfVxuXG4gICAgcHVibGljIGV4ZWN1dGUoY21kOiBzdHJpbmcsIGFyZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD4ge1xuICAgICAgICBjb25zb2xlLmxvZyhgQ29tbWFuZDogJHtjbWR9ICR7YXJncy5qb2luKCcgJyl9YClcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRBZ2VudC5leGVjKGNtZCwgYXJncylcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgdG9vbEluc3RhbGwoXG4gICAgICAgIHRvb2xOYW1lOiBzdHJpbmcsXG4gICAgICAgIHZlcnNpb25TcGVjOiBzdHJpbmcsXG4gICAgICAgIGNoZWNrTGF0ZXN0OiBib29sZWFuLFxuICAgICAgICBpbmNsdWRlUHJlOiBib29sZWFuXG4gICAgKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgY29uc29sZS5sb2coJycpXG4gICAgICAgIGNvbnNvbGUubG9nKCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpXG4gICAgICAgIGNvbnNvbGUubG9nKGBJbnN0YWxsaW5nICR7dG9vbE5hbWV9IHZlcnNpb24gYCArIHZlcnNpb25TcGVjKVxuICAgICAgICBjb25zb2xlLmxvZygnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKVxuXG4gICAgICAgIGlmICh0aGlzLnZlcnNpb25NYW5hZ2VyLmlzRXhwbGljaXRWZXJzaW9uKHZlcnNpb25TcGVjKSkge1xuICAgICAgICAgICAgY2hlY2tMYXRlc3QgPSBmYWxzZSAvLyBjaGVjayBsYXRlc3QgZG9lc24ndCBtYWtlIHNlbnNlIHdoZW4gZXhwbGljaXQgdmVyc2lvblxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHRvb2xQYXRoOiBzdHJpbmdcbiAgICAgICAgaWYgKCFjaGVja0xhdGVzdCkge1xuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIExldCdzIHRyeSBhbmQgcmVzb2x2ZSB0aGUgdmVyc2lvbiBzcGVjIGxvY2FsbHkgZmlyc3RcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICB0b29sUGF0aCA9IHRoaXMuYnVpbGRBZ2VudC5maW5kKHRvb2xOYW1lLCB2ZXJzaW9uU3BlYylcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdG9vbFBhdGgpIHtcbiAgICAgICAgICAgIGxldCB2ZXJzaW9uOiBzdHJpbmdcbiAgICAgICAgICAgIGlmICh0aGlzLnZlcnNpb25NYW5hZ2VyLmlzRXhwbGljaXRWZXJzaW9uKHZlcnNpb25TcGVjKSkge1xuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gRXhwbGljaXQgdmVyc2lvbiB3YXMgc3BlY2lmaWVkLiBObyBuZWVkIHRvIHF1ZXJ5IGZvciBsaXN0IG9mIHZlcnNpb25zLlxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgdmVyc2lvbiA9IHZlcnNpb25TcGVjXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gTGV0J3MgcXVlcnkgYW5kIHJlc29sdmUgdGhlIGxhdGVzdCB2ZXJzaW9uIGZvciB0aGUgdmVyc2lvblNwZWMuXG4gICAgICAgICAgICAgICAgLy8gSWYgdGhlIHZlcnNpb24gaXMgYW4gZXhwbGljaXQgdmVyc2lvbiAoMS4xLjEgb3IgdjEuMS4xKSB0aGVuIG5vIG5lZWQgdG8gcXVlcnkuXG4gICAgICAgICAgICAgICAgLy8gSWYgeW91ciB0b29sIGRvZXNuJ3Qgb2ZmZXIgYSBtZWNoYW5pc20gdG8gcXVlcnksXG4gICAgICAgICAgICAgICAgLy8gdGhlbiBpdCBjYW4gb25seSBzdXBwb3J0IGV4YWN0IHZlcnNpb24gaW5wdXRzLlxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgdmVyc2lvbiA9IGF3YWl0IHRoaXMucXVlcnlMYXRlc3RNYXRjaChcbiAgICAgICAgICAgICAgICAgICAgdG9vbE5hbWUsXG4gICAgICAgICAgICAgICAgICAgIHZlcnNpb25TcGVjLFxuICAgICAgICAgICAgICAgICAgICBpbmNsdWRlUHJlXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIGlmICghdmVyc2lvbikge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBgVW5hYmxlIHRvIGZpbmQgJHt0b29sTmFtZX0gdmVyc2lvbiAnJHt2ZXJzaW9uU3BlY30nLmBcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgdGhlIGNhY2hlIGZvciB0aGUgcmVzb2x2ZWQgdmVyc2lvbi5cbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIHRvb2xQYXRoID0gdGhpcy5idWlsZEFnZW50LmZpbmQodG9vbE5hbWUsIHZlcnNpb24pXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRvb2xQYXRoKSB7XG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAvLyBEb3dubG9hZCwgZXh0cmFjdCwgY2FjaGVcbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIHRvb2xQYXRoID0gYXdhaXQgdGhpcy5hY3F1aXJlVG9vbCh0b29sTmFtZSwgdmVyc2lvbilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFByZXBlbmQgdGhlIHRvb2xzIHBhdGguIFRoaXMgcHJlcGVuZHMgdGhlIFBBVEggZm9yIHRoZSBjdXJyZW50IHByb2Nlc3MgYW5kXG4gICAgICAgIC8vIGluc3RydWN0cyB0aGUgYWdlbnQgdG8gcHJlcGVuZCBmb3IgZWFjaCB0YXNrIHRoYXQgZm9sbG93cy5cbiAgICAgICAgLy9cbiAgICAgICAgdGhpcy5idWlsZEFnZW50LmRlYnVnKGB0b29sUGF0aDogJHt0b29sUGF0aH1gKVxuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIG9zLnBsYXRmb3JtKCkgIT09ICd3aW4zMicgJiZcbiAgICAgICAgICAgICF0aGlzLmJ1aWxkQWdlbnQuZ2V0VmFyaWFibGUoJ0RPVE5FVF9ST09UJylcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBsZXQgZG90bmV0UGF0aCA9IGF3YWl0IHRoaXMuYnVpbGRBZ2VudC53aGljaCgnZG90bmV0JylcbiAgICAgICAgICAgIGRvdG5ldFBhdGggPSBmcy5yZWFkbGlua1N5bmMoZG90bmV0UGF0aCkgfHwgZG90bmV0UGF0aFxuICAgICAgICAgICAgY29uc3QgZG90bmV0Um9vdCA9IHBhdGguZGlybmFtZShkb3RuZXRQYXRoKVxuICAgICAgICAgICAgdGhpcy5idWlsZEFnZW50LmV4cG9ydFZhcmlhYmxlKCdET1RORVRfUk9PVCcsIGRvdG5ldFJvb3QpXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5idWlsZEFnZW50LmFkZFBhdGgodG9vbFBhdGgpXG5cbiAgICAgICAgcmV0dXJuIHRvb2xQYXRoXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBxdWVyeUxhdGVzdE1hdGNoKFxuICAgICAgICB0b29sTmFtZTogc3RyaW5nLFxuICAgICAgICB2ZXJzaW9uU3BlYzogc3RyaW5nLFxuICAgICAgICBpbmNsdWRlUHJlcmVsZWFzZTogYm9vbGVhblxuICAgICk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZyhcbiAgICAgICAgICAgIGBxdWVyeWluZyB0b29sIHZlcnNpb25zIGZvciAke3Rvb2xOYW1lfSR7XG4gICAgICAgICAgICAgICAgdmVyc2lvblNwZWMgPyBgQCR7dmVyc2lvblNwZWN9YCA6ICcnXG4gICAgICAgICAgICB9ICR7aW5jbHVkZVByZXJlbGVhc2UgPyAnaW5jbHVkaW5nIHByZS1yZWxlYXNlcycgOiAnJ31gXG4gICAgICAgIClcblxuICAgICAgICBjb25zdCBkb3dubG9hZFBhdGggPSBgJHtcbiAgICAgICAgICAgIERvdG5ldFRvb2wubnVnZXRSb290XG4gICAgICAgIH1xdWVyeT9xPSR7ZW5jb2RlVVJJQ29tcG9uZW50KHRvb2xOYW1lLnRvTG93ZXJDYXNlKCkpfSZwcmVyZWxlYXNlPSR7XG4gICAgICAgICAgICBpbmNsdWRlUHJlcmVsZWFzZSA/ICd0cnVlJyA6ICdmYWxzZSdcbiAgICAgICAgfSZzZW1WZXJMZXZlbD0yLjAuMGBcblxuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmh0dHBDbGllbnQuZ2V0KGRvd25sb2FkUGF0aClcblxuICAgICAgICBpZiAoIXJlcyB8fCByZXMubWVzc2FnZS5zdGF0dXNDb2RlICE9PSAyMDApIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBib2R5OiBzdHJpbmcgPSBhd2FpdCByZXMucmVhZEJvZHkoKVxuICAgICAgICBjb25zdCBkYXRhID0gSlNPTi5wYXJzZShib2R5KS5kYXRhXG5cbiAgICAgICAgY29uc3QgdmVyc2lvbnMgPSAoZGF0YVswXS52ZXJzaW9ucyBhcyB7IHZlcnNpb246IHN0cmluZyB9W10pLm1hcChcbiAgICAgICAgICAgIHggPT4geC52ZXJzaW9uXG4gICAgICAgIClcbiAgICAgICAgaWYgKCF2ZXJzaW9ucyB8fCAhdmVyc2lvbnMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5idWlsZEFnZW50LmRlYnVnKGBnb3QgdmVyc2lvbnM6ICR7dmVyc2lvbnMuam9pbignLCAnKX1gKVxuXG4gICAgICAgIHJldHVybiB0aGlzLnZlcnNpb25NYW5hZ2VyLmV2YWx1YXRlVmVyc2lvbnModmVyc2lvbnMsIHZlcnNpb25TcGVjKVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgYWNxdWlyZVRvb2woXG4gICAgICAgIHRvb2xOYW1lOiBzdHJpbmcsXG4gICAgICAgIHZlcnNpb246IHN0cmluZ1xuICAgICk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIGNvbnN0IHRlbXBEaXJlY3RvcnkgPSBhd2FpdCB0aGlzLmJ1aWxkQWdlbnQuY3JlYXRlVGVtcERpcigpXG4gICAgICAgIGxldCBhcmdzID0gWyd0b29sJywgJ2luc3RhbGwnLCB0b29sTmFtZSwgJy0tdG9vbC1wYXRoJywgdGVtcERpcmVjdG9yeV1cblxuICAgICAgICBpZiAodmVyc2lvbikge1xuICAgICAgICAgICAgdmVyc2lvbiA9IHRoaXMudmVyc2lvbk1hbmFnZXIuY2xlYW5WZXJzaW9uKHZlcnNpb24pXG4gICAgICAgICAgICBhcmdzID0gYXJncy5jb25jYXQoWyctLXZlcnNpb24nLCB2ZXJzaW9uXSlcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZXhlY3V0ZSgnZG90bmV0JywgYXJncylcbiAgICAgICAgY29uc3Qgc3RhdHVzID0gcmVzdWx0LmNvZGUgPT09IDAgPyAnc3VjY2VzcycgOiAnZmFpbHVyZSdcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IHJlc3VsdC5jb2RlID09PSAwID8gcmVzdWx0LnN0ZG91dCA6IHJlc3VsdC5zdGRlcnJcblxuICAgICAgICB0aGlzLmJ1aWxkQWdlbnQuZGVidWcoYHRvb2wgaW5zdGFsbCByZXN1bHQ6ICR7c3RhdHVzfSAke21lc3NhZ2V9YClcblxuICAgICAgICBpZiAocmVzdWx0LmNvZGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRXJyb3IgaW5zdGFsbGluZyB0b29sJylcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmJ1aWxkQWdlbnQuY2FjaGVEaXIodGVtcERpcmVjdG9yeSwgdG9vbE5hbWUsIHZlcnNpb24pXG4gICAgfVxufVxuIiwiaW1wb3J0IHsgQ29udGFpbmVyIH0gZnJvbSAnaW52ZXJzaWZ5J1xuaW1wb3J0IHsgSVZlcnNpb25NYW5hZ2VyLCBWZXJzaW9uTWFuYWdlciB9IGZyb20gJy4vdmVyc2lvbk1hbmFnZXInXG5pbXBvcnQgeyBUWVBFUywgSUJ1aWxkQWdlbnQgfSBmcm9tICcuL21vZGVscydcbmltcG9ydCB7IEJ1aWxkQWdlbnQgfSBmcm9tICcuLi9hZ2VudC9tb2NrL2J1aWxkLWFnZW50J1xuXG5jb25zdCBjb250YWluZXIgPSBuZXcgQ29udGFpbmVyKClcblxuY29udGFpbmVyLmJpbmQ8SVZlcnNpb25NYW5hZ2VyPihUWVBFUy5JVmVyc2lvbk1hbmFnZXIpLnRvKFZlcnNpb25NYW5hZ2VyKVxuY29udGFpbmVyLmJpbmQ8SUJ1aWxkQWdlbnQ+KFRZUEVTLklCdWlsZEFnZW50KS50byhCdWlsZEFnZW50KVxuXG5leHBvcnQgZGVmYXVsdCBjb250YWluZXJcbiIsImltcG9ydCB7IElSZXF1ZXN0T3B0aW9ucyB9IGZyb20gJ3R5cGVkLXJlc3QtY2xpZW50L0ludGVyZmFjZXMnXG5cbmV4cG9ydCBjb25zdCBUWVBFUyA9IHtcbiAgICBJQnVpbGRBZ2VudDogU3ltYm9sLmZvcignQnVpbGRBZ2VudCcpLFxuICAgIElEb3RuZXRUb29sOiBTeW1ib2wuZm9yKCdEb3RuZXRUb29sJyksXG4gICAgSUdpdFZlcnNpb25Ub29sOiBTeW1ib2wuZm9yKCdHaXRWZXJzaW9uVG9vbCcpLFxuICAgIElHaXRSZWxlYXNlTWFuYWdlclRvb2w6IFN5bWJvbC5mb3IoJ0dpdFJlbGVhc2VNYW5hZ2VyVG9vbCcpLFxuICAgIElWZXJzaW9uTWFuYWdlcjogU3ltYm9sLmZvcignVmVyc2lvbk1hbmFnZXInKVxufVxuXG5leHBvcnQgZW51bSBTZXR1cEZpZWxkcyB7XG4gICAgaW5jbHVkZVByZXJlbGVhc2UgPSAnaW5jbHVkZVByZXJlbGVhc2UnLFxuICAgIHZlcnNpb25TcGVjID0gJ3ZlcnNpb25TcGVjJ1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElTZXR1cFNldHRpbmdzIHtcbiAgICBbU2V0dXBGaWVsZHMudmVyc2lvblNwZWNdOiBzdHJpbmdcbiAgICBbU2V0dXBGaWVsZHMuaW5jbHVkZVByZXJlbGVhc2VdOiBib29sZWFuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUV4ZWNSZXN1bHQge1xuICAgIHN0ZG91dDogc3RyaW5nXG4gICAgc3RkZXJyOiBzdHJpbmdcbiAgICBjb2RlOiBudW1iZXJcbiAgICBlcnJvcjogRXJyb3Jcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJQnVpbGRBZ2VudCB7XG4gICAgYWdlbnROYW1lOiBzdHJpbmdcbiAgICBwcm94eUNvbmZpZ3VyYXRpb24odXJsOiBzdHJpbmcpOiBJUmVxdWVzdE9wdGlvbnNcbiAgICBmaW5kKHRvb2xOYW1lOiBzdHJpbmcsIHZlcnNpb25TcGVjOiBzdHJpbmcsIGFyY2g/OiBzdHJpbmcpOiBzdHJpbmdcbiAgICBjYWNoZURpcihcbiAgICAgICAgc291cmNlRGlyOiBzdHJpbmcsXG4gICAgICAgIHRvb2w6IHN0cmluZyxcbiAgICAgICAgdmVyc2lvbjogc3RyaW5nLFxuICAgICAgICBhcmNoPzogc3RyaW5nXG4gICAgKTogUHJvbWlzZTxzdHJpbmc+XG4gICAgY3JlYXRlVGVtcERpcigpOiBQcm9taXNlPHN0cmluZz5cbiAgICBkZWJ1ZyhtZXNzYWdlOiBzdHJpbmcpOiB2b2lkXG4gICAgc2V0RmFpbGVkKG1lc3NhZ2U6IHN0cmluZywgZG9uZT86IGJvb2xlYW4pOiB2b2lkXG4gICAgc2V0U3VjY2VlZGVkKG1lc3NhZ2U6IHN0cmluZywgZG9uZT86IGJvb2xlYW4pOiB2b2lkXG4gICAgZXhwb3J0VmFyaWFibGUobmFtZTogc3RyaW5nLCB2YWw6IHN0cmluZyk6IHZvaWRcbiAgICBnZXRWYXJpYWJsZShuYW1lOiBzdHJpbmcpOiBzdHJpbmdcbiAgICBhZGRQYXRoKGlucHV0UGF0aDogc3RyaW5nKTogdm9pZFxuICAgIHdoaWNoKHRvb2w6IHN0cmluZywgY2hlY2s/OiBib29sZWFuKTogUHJvbWlzZTxzdHJpbmc+XG4gICAgZXhlYyhleGVjOiBzdHJpbmcsIGFyZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD5cblxuICAgIGdldFNvdXJjZURpcigpOiBzdHJpbmdcbiAgICBpc1ZhbGlkSW5wdXRGaWxlKGlucHV0OiBzdHJpbmcsIGZpbGU6IHN0cmluZyk6IGJvb2xlYW5cbiAgICBmaWxlRXhpc3RzKGZpbGU6IHN0cmluZyk6IGJvb2xlYW5cbiAgICBkaXJlY3RvcnlFeGlzdHMoZmlsZTogc3RyaW5nKTogYm9vbGVhblxuXG4gICAgc2V0T3V0cHV0KG5hbWU6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IHZvaWRcbiAgICBnZXRJbnB1dChpbnB1dDogc3RyaW5nLCByZXF1aXJlZD86IGJvb2xlYW4pOiBzdHJpbmdcbiAgICBnZXRMaXN0SW5wdXQoaW5wdXQ6IHN0cmluZywgcmVxdWlyZWQ/OiBib29sZWFuKTogc3RyaW5nW11cbiAgICBnZXRCb29sZWFuSW5wdXQoaW5wdXQ6IHN0cmluZywgcmVxdWlyZWQ/OiBib29sZWFuKTogYm9vbGVhblxufVxuIiwiaW1wb3J0IHsgSUJ1aWxkQWdlbnQsIFNldHVwRmllbGRzLCBJU2V0dXBTZXR0aW5ncyB9IGZyb20gJy4vbW9kZWxzJ1xuXG5leHBvcnQgY2xhc3MgU2V0dGluZ3Mge1xuICAgIHB1YmxpYyBzdGF0aWMgZ2V0U2V0dXBTZXR0aW5ncyhidWlsZEFnZW50OiBJQnVpbGRBZ2VudCk6IElTZXR1cFNldHRpbmdzIHtcbiAgICAgICAgY29uc3QgdmVyc2lvblNwZWMgPSBidWlsZEFnZW50LmdldElucHV0KFNldHVwRmllbGRzLnZlcnNpb25TcGVjKVxuICAgICAgICBjb25zdCBpbmNsdWRlUHJlcmVsZWFzZSA9IGJ1aWxkQWdlbnQuZ2V0Qm9vbGVhbklucHV0KFxuICAgICAgICAgICAgU2V0dXBGaWVsZHMuaW5jbHVkZVByZXJlbGVhc2VcbiAgICAgICAgKVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2ZXJzaW9uU3BlYyxcbiAgICAgICAgICAgIGluY2x1ZGVQcmVyZWxlYXNlXG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJpbXBvcnQgY21wIGZyb20gJ3NlbXZlci1jb21wYXJlJ1xuaW1wb3J0ICogYXMgc2VtdmVyIGZyb20gJ3NlbXZlcidcbmltcG9ydCB7IGluamVjdGFibGUsIGluamVjdCB9IGZyb20gJ2ludmVyc2lmeSdcblxuaW1wb3J0IHsgSUJ1aWxkQWdlbnQsIFRZUEVTIH0gZnJvbSAnLi9tb2RlbHMnXG5cbmV4cG9ydCBpbnRlcmZhY2UgSVZlcnNpb25NYW5hZ2VyIHtcbiAgICBpc0V4cGxpY2l0VmVyc2lvbih2ZXJzaW9uU3BlYzogc3RyaW5nKTogYm9vbGVhblxuICAgIGV2YWx1YXRlVmVyc2lvbnModmVyc2lvbnM6IHN0cmluZ1tdLCB2ZXJzaW9uU3BlYzogc3RyaW5nKTogc3RyaW5nXG4gICAgY2xlYW5WZXJzaW9uKHZlcnNpb246IHN0cmluZyk6IHN0cmluZ1xufVxuXG5AaW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgVmVyc2lvbk1hbmFnZXIgaW1wbGVtZW50cyBJVmVyc2lvbk1hbmFnZXIge1xuICAgIHByaXZhdGUgYnVpbGRBZ2VudDogSUJ1aWxkQWdlbnRcbiAgICBjb25zdHJ1Y3RvcihAaW5qZWN0KFRZUEVTLklCdWlsZEFnZW50KSBidWlsZEFnZW50OiBJQnVpbGRBZ2VudCkge1xuICAgICAgICB0aGlzLmJ1aWxkQWdlbnQgPSBidWlsZEFnZW50XG4gICAgfVxuXG4gICAgcHVibGljIGlzRXhwbGljaXRWZXJzaW9uKHZlcnNpb25TcGVjOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgYyA9IHNlbXZlci5jbGVhbih2ZXJzaW9uU3BlYylcbiAgICAgICAgdGhpcy5idWlsZEFnZW50LmRlYnVnKCdpc0V4cGxpY2l0OiAnICsgYylcblxuICAgICAgICBjb25zdCB2YWxpZCA9IHNlbXZlci52YWxpZChjKSAhPSBudWxsXG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZygnZXhwbGljaXQ/ICcgKyB2YWxpZClcblxuICAgICAgICByZXR1cm4gdmFsaWRcbiAgICB9XG5cbiAgICBwdWJsaWMgZXZhbHVhdGVWZXJzaW9ucyh2ZXJzaW9uczogc3RyaW5nW10sIHZlcnNpb25TcGVjOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBsZXQgdmVyc2lvbjogc3RyaW5nXG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZygnZXZhbHVhdGluZyAnICsgdmVyc2lvbnMubGVuZ3RoICsgJyB2ZXJzaW9ucycpXG4gICAgICAgIHZlcnNpb25zID0gdmVyc2lvbnMuc29ydChjbXApXG4gICAgICAgIGZvciAobGV0IGkgPSB2ZXJzaW9ucy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgY29uc3QgcG90ZW50aWFsOiBzdHJpbmcgPSB2ZXJzaW9uc1tpXVxuICAgICAgICAgICAgY29uc3Qgc2F0aXNmaWVkOiBib29sZWFuID0gc2VtdmVyLnNhdGlzZmllcyhwb3RlbnRpYWwsIHZlcnNpb25TcGVjKVxuICAgICAgICAgICAgaWYgKHNhdGlzZmllZCkge1xuICAgICAgICAgICAgICAgIHZlcnNpb24gPSBwb3RlbnRpYWxcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZlcnNpb24pIHtcbiAgICAgICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZygnbWF0Y2hlZDogJyArIHZlcnNpb24pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmJ1aWxkQWdlbnQuZGVidWcoJ21hdGNoIG5vdCBmb3VuZCcpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdmVyc2lvblxuICAgIH1cblxuICAgIHB1YmxpYyBjbGVhblZlcnNpb24odmVyc2lvbjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgdGhpcy5idWlsZEFnZW50LmRlYnVnKCdjbGVhbmluZzogJyArIHZlcnNpb24pXG4gICAgICAgIHJldHVybiBzZW12ZXIuY2xlYW4odmVyc2lvbilcbiAgICB9XG59XG4iLCJpbXBvcnQgJ3JlZmxlY3QtbWV0YWRhdGEnXG5pbXBvcnQgeyBjbG9zZSB9IGZyb20gJy4vbWFpbidcblxuY2xvc2UoKVxuIiwiaW1wb3J0IHsgSUJ1aWxkQWdlbnQsIFRZUEVTIH0gZnJvbSAnLi4vLi4vY29yZS9tb2RlbHMnXG5pbXBvcnQge1xuICAgIElHaXRSZWxlYXNlTWFuYWdlclRvb2wsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJUb29sXG59IGZyb20gJy4uLy4uL3Rvb2xzL2dpdHJlbGVhc2VtYW5hZ2VyL3Rvb2wnXG5pbXBvcnQgeyBTZXR0aW5ncyBhcyBDb21tb25TZXR0aW5ncyB9IGZyb20gJy4uLy4uL2NvcmUvc2V0dGluZ3MnXG5pbXBvcnQgeyBTZXR0aW5ncyB9IGZyb20gJy4uLy4uL3Rvb2xzL2dpdHJlbGVhc2VtYW5hZ2VyL3NldHRpbmdzJ1xuXG5pbXBvcnQgY29udGFpbmVyIGZyb20gJy4uLy4uL2NvcmUvaW9jJ1xuXG5jb250YWluZXJcbiAgICAuYmluZDxJR2l0UmVsZWFzZU1hbmFnZXJUb29sPihUWVBFUy5JR2l0UmVsZWFzZU1hbmFnZXJUb29sKVxuICAgIC50byhHaXRSZWxlYXNlTWFuYWdlclRvb2wpXG5cbmNvbnN0IGdpdFJlbGVhc2VNYW5hZ2VyVG9vbCA9IGNvbnRhaW5lci5nZXQ8SUdpdFJlbGVhc2VNYW5hZ2VyVG9vbD4oXG4gICAgVFlQRVMuSUdpdFJlbGVhc2VNYW5hZ2VyVG9vbFxuKVxuY29uc3QgYnVpbGRBZ2VudCA9IGNvbnRhaW5lci5nZXQ8SUJ1aWxkQWdlbnQ+KFRZUEVTLklCdWlsZEFnZW50KVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2V0dXAoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLmRpc2FibGVUZWxlbWV0cnkoKVxuXG4gICAgICAgIGNvbnN0IHNldHRpbmdzID0gQ29tbW9uU2V0dGluZ3MuZ2V0U2V0dXBTZXR0aW5ncyhidWlsZEFnZW50KVxuXG4gICAgICAgIGF3YWl0IGdpdFJlbGVhc2VNYW5hZ2VyVG9vbC5pbnN0YWxsKFxuICAgICAgICAgICAgc2V0dGluZ3MudmVyc2lvblNwZWMsXG4gICAgICAgICAgICBzZXR0aW5ncy5pbmNsdWRlUHJlcmVsZWFzZVxuICAgICAgICApXG5cbiAgICAgICAgYnVpbGRBZ2VudC5zZXRTdWNjZWVkZWQoXG4gICAgICAgICAgICAnR2l0VmVyc2lvbk1hbmFnZXIgaW5zdGFsbGVkIHN1Y2Nlc3NmdWxseScsXG4gICAgICAgICAgICB0cnVlXG4gICAgICAgIClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBidWlsZEFnZW50LnNldEZhaWxlZChlcnJvci5tZXNzYWdlLCB0cnVlKVxuICAgIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgICB0cnkge1xuICAgICAgICBnaXRSZWxlYXNlTWFuYWdlclRvb2wuZGlzYWJsZVRlbGVtZXRyeSgpXG5cbiAgICAgICAgY29uc3Qgc2V0dGluZ3MgPSBTZXR0aW5ncy5nZXRDcmVhdGVTZXR0aW5ncyhidWlsZEFnZW50KVxuXG4gICAgICAgIGF3YWl0IGdpdFJlbGVhc2VNYW5hZ2VyVG9vbC5jcmVhdGUoc2V0dGluZ3MpXG5cbiAgICAgICAgYnVpbGRBZ2VudC5zZXRTdWNjZWVkZWQoXG4gICAgICAgICAgICAnR2l0VmVyc2lvbk1hbmFnZXIgY3JlYXRlZCByZWxlYXNlIHN1Y2Nlc3NmdWxseScsXG4gICAgICAgICAgICB0cnVlXG4gICAgICAgIClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBidWlsZEFnZW50LnNldEZhaWxlZChlcnJvci5tZXNzYWdlLCB0cnVlKVxuICAgIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRpc2NhcmQoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLmRpc2FibGVUZWxlbWV0cnkoKVxuXG4gICAgICAgIGNvbnN0IHNldHRpbmdzID0gU2V0dGluZ3MuZ2V0RGlzY2FyZFNldHRpbmdzKGJ1aWxkQWdlbnQpXG5cbiAgICAgICAgYXdhaXQgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLmRpc2NhcmQoc2V0dGluZ3MpXG5cbiAgICAgICAgYnVpbGRBZ2VudC5zZXRTdWNjZWVkZWQoXG4gICAgICAgICAgICAnR2l0VmVyc2lvbk1hbmFnZXIgZGlzY2FyZGVkIHJlbGVhc2Ugc3VjY2Vzc2Z1bGx5JyxcbiAgICAgICAgICAgIHRydWVcbiAgICAgICAgKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGJ1aWxkQWdlbnQuc2V0RmFpbGVkKGVycm9yLm1lc3NhZ2UsIHRydWUpXG4gICAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY2xvc2UoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLmRpc2FibGVUZWxlbWV0cnkoKVxuXG4gICAgICAgIGNvbnN0IHNldHRpbmdzID0gU2V0dGluZ3MuZ2V0Q2xvc2VTZXR0aW5ncyhidWlsZEFnZW50KVxuXG4gICAgICAgIGF3YWl0IGdpdFJlbGVhc2VNYW5hZ2VyVG9vbC5jbG9zZShzZXR0aW5ncylcblxuICAgICAgICBidWlsZEFnZW50LnNldFN1Y2NlZWRlZChcbiAgICAgICAgICAgICdHaXRWZXJzaW9uTWFuYWdlciBjbG9zZWQgcmVsZWFzZSBzdWNjZXNzZnVsbHknLFxuICAgICAgICAgICAgdHJ1ZVxuICAgICAgICApXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgYnVpbGRBZ2VudC5zZXRGYWlsZWQoZXJyb3IubWVzc2FnZSwgdHJ1ZSlcbiAgICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvcGVuKCkge1xuICAgIHRyeSB7XG4gICAgICAgIGdpdFJlbGVhc2VNYW5hZ2VyVG9vbC5kaXNhYmxlVGVsZW1ldHJ5KClcblxuICAgICAgICBjb25zdCBzZXR0aW5ncyA9IFNldHRpbmdzLmdldE9wZW5TZXR0aW5ncyhidWlsZEFnZW50KVxuXG4gICAgICAgIGF3YWl0IGdpdFJlbGVhc2VNYW5hZ2VyVG9vbC5vcGVuKHNldHRpbmdzKVxuXG4gICAgICAgIGJ1aWxkQWdlbnQuc2V0U3VjY2VlZGVkKFxuICAgICAgICAgICAgJ0dpdFZlcnNpb25NYW5hZ2VyIG9wZW5lZCByZWxlYXNlIHN1Y2Nlc3NmdWxseScsXG4gICAgICAgICAgICB0cnVlXG4gICAgICAgIClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBidWlsZEFnZW50LnNldEZhaWxlZChlcnJvci5tZXNzYWdlLCB0cnVlKVxuICAgIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHB1Ymxpc2goKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLmRpc2FibGVUZWxlbWV0cnkoKVxuXG4gICAgICAgIGNvbnN0IHNldHRpbmdzID0gU2V0dGluZ3MuZ2V0UHVibGlzaFNldHRpbmdzKGJ1aWxkQWdlbnQpXG5cbiAgICAgICAgYXdhaXQgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLnB1Ymxpc2goc2V0dGluZ3MpXG5cbiAgICAgICAgYnVpbGRBZ2VudC5zZXRTdWNjZWVkZWQoXG4gICAgICAgICAgICAnR2l0VmVyc2lvbk1hbmFnZXIgcHVibGlzaGVkIHJlbGVhc2Ugc3VjY2Vzc2Z1bGx5JyxcbiAgICAgICAgICAgIHRydWVcbiAgICAgICAgKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGJ1aWxkQWdlbnQuc2V0RmFpbGVkKGVycm9yLm1lc3NhZ2UsIHRydWUpXG4gICAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYWRkQXNzZXQoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLmRpc2FibGVUZWxlbWV0cnkoKVxuXG4gICAgICAgIGNvbnN0IHNldHRpbmdzID0gU2V0dGluZ3MuZ2V0QWRkQXNzZXRTZXR0aW5ncyhidWlsZEFnZW50KVxuXG4gICAgICAgIGF3YWl0IGdpdFJlbGVhc2VNYW5hZ2VyVG9vbC5hZGRBc3NldChzZXR0aW5ncylcblxuICAgICAgICBidWlsZEFnZW50LnNldFN1Y2NlZWRlZChcbiAgICAgICAgICAgICdHaXRWZXJzaW9uTWFuYWdlciBhZGRlZCBhc3NldHMgdG8gcmVsZWFzZSBzdWNjZXNzZnVsbHknLFxuICAgICAgICAgICAgdHJ1ZVxuICAgICAgICApXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgYnVpbGRBZ2VudC5zZXRGYWlsZWQoZXJyb3IubWVzc2FnZSwgdHJ1ZSlcbiAgICB9XG59XG4iLCJleHBvcnQgZW51bSBDb21tb25GaWVsZHMge1xuICAgIHJlcG9zaXRvcnkgPSAncmVwb3NpdG9yeScsXG4gICAgb3duZXIgPSAnb3duZXInLFxuICAgIHRva2VuID0gJ3Rva2VuJyxcbiAgICB0YXJnZXREaXJlY3RvcnkgPSAndGFyZ2V0RGlyZWN0b3J5J1xufVxuXG5leHBvcnQgZW51bSBDcmVhdGVGaWVsZHMge1xuICAgIG1pbGVzdG9uZSA9ICdtaWxlc3RvbmUnLFxuICAgIG5hbWUgPSAnbmFtZScsXG4gICAgaW5wdXRGaWxlTmFtZSA9ICdpbnB1dEZpbGVOYW1lJyxcbiAgICBpc1ByZVJlbGVhc2UgPSAnaXNQcmVSZWxlYXNlJyxcbiAgICBjb21taXQgPSAnY29tbWl0JyxcbiAgICBhc3NldHMgPSAnYXNzZXRzJ1xufVxuXG5leHBvcnQgZW51bSBEaXNjYXJkRmllbGRzIHtcbiAgICBtaWxlc3RvbmUgPSAnbWlsZXN0b25lJ1xufVxuXG5leHBvcnQgZW51bSBDbG9zZUZpZWxkcyB7XG4gICAgbWlsZXN0b25lID0gJ21pbGVzdG9uZSdcbn1cblxuZXhwb3J0IGVudW0gT3BlbkZpZWxkcyB7XG4gICAgbWlsZXN0b25lID0gJ21pbGVzdG9uZSdcbn1cblxuZXhwb3J0IGVudW0gUHVibGlzaEZpZWxkcyB7XG4gICAgdGFnTmFtZSA9ICd0YWdOYW1lJ1xufVxuXG5leHBvcnQgZW51bSBBZGRBc3NldEZpZWxkcyB7XG4gICAgdGFnTmFtZSA9ICd0YWdOYW1lJyxcbiAgICBhc3NldHMgPSAnYXNzZXRzJ1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdpdFJlbGVhc2VNYW5hZ2VyU2V0dGluZ3Mge1xuICAgIFtDb21tb25GaWVsZHMucmVwb3NpdG9yeV06IHN0cmluZ1xuICAgIFtDb21tb25GaWVsZHMub3duZXJdOiBzdHJpbmdcbiAgICBbQ29tbW9uRmllbGRzLnRva2VuXTogc3RyaW5nXG4gICAgW0NvbW1vbkZpZWxkcy50YXJnZXREaXJlY3RvcnldOiBzdHJpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHaXRSZWxlYXNlTWFuYWdlckNyZWF0ZVNldHRpbmdzXG4gICAgZXh0ZW5kcyBHaXRSZWxlYXNlTWFuYWdlclNldHRpbmdzIHtcbiAgICBbQ3JlYXRlRmllbGRzLm1pbGVzdG9uZV06IHN0cmluZ1xuICAgIFtDcmVhdGVGaWVsZHMubmFtZV06IHN0cmluZ1xuICAgIFtDcmVhdGVGaWVsZHMuaW5wdXRGaWxlTmFtZV06IHN0cmluZ1xuICAgIFtDcmVhdGVGaWVsZHMuaXNQcmVSZWxlYXNlXTogYm9vbGVhblxuICAgIFtDcmVhdGVGaWVsZHMuY29tbWl0XTogc3RyaW5nXG4gICAgW0NyZWF0ZUZpZWxkcy5hc3NldHNdPzogc3RyaW5nW11cbn1cblxuZXhwb3J0IGludGVyZmFjZSBHaXRSZWxlYXNlTWFuYWdlckRpc2NhcmRTZXR0aW5nc1xuICAgIGV4dGVuZHMgR2l0UmVsZWFzZU1hbmFnZXJTZXR0aW5ncyB7XG4gICAgW0Rpc2NhcmRGaWVsZHMubWlsZXN0b25lXTogc3RyaW5nXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2l0UmVsZWFzZU1hbmFnZXJDbG9zZVNldHRpbmdzXG4gICAgZXh0ZW5kcyBHaXRSZWxlYXNlTWFuYWdlclNldHRpbmdzIHtcbiAgICBbQ2xvc2VGaWVsZHMubWlsZXN0b25lXTogc3RyaW5nXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2l0UmVsZWFzZU1hbmFnZXJPcGVuU2V0dGluZ3NcbiAgICBleHRlbmRzIEdpdFJlbGVhc2VNYW5hZ2VyU2V0dGluZ3Mge1xuICAgIFtPcGVuRmllbGRzLm1pbGVzdG9uZV06IHN0cmluZ1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdpdFJlbGVhc2VNYW5hZ2VyUHVibGlzaFNldHRpbmdzXG4gICAgZXh0ZW5kcyBHaXRSZWxlYXNlTWFuYWdlclNldHRpbmdzIHtcbiAgICBbUHVibGlzaEZpZWxkcy50YWdOYW1lXTogc3RyaW5nXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2l0UmVsZWFzZU1hbmFnZXJBZGRBc3NldFNldHRpbmdzXG4gICAgZXh0ZW5kcyBHaXRSZWxlYXNlTWFuYWdlclNldHRpbmdzIHtcbiAgICBbQWRkQXNzZXRGaWVsZHMudGFnTmFtZV06IHN0cmluZ1xuICAgIFtBZGRBc3NldEZpZWxkcy5hc3NldHNdOiBzdHJpbmdbXVxufVxuIiwiaW1wb3J0IHsgSUJ1aWxkQWdlbnQgfSBmcm9tICcuLi8uLi9jb3JlL21vZGVscydcbmltcG9ydCB7XG4gICAgR2l0UmVsZWFzZU1hbmFnZXJTZXR0aW5ncyxcbiAgICBDb21tb25GaWVsZHMsXG4gICAgQ3JlYXRlRmllbGRzLFxuICAgIERpc2NhcmRGaWVsZHMsXG4gICAgQ2xvc2VGaWVsZHMsXG4gICAgT3BlbkZpZWxkcyxcbiAgICBQdWJsaXNoRmllbGRzLFxuICAgIEFkZEFzc2V0RmllbGRzLFxuICAgIEdpdFJlbGVhc2VNYW5hZ2VyQ3JlYXRlU2V0dGluZ3MsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJEaXNjYXJkU2V0dGluZ3MsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJDbG9zZVNldHRpbmdzLFxuICAgIEdpdFJlbGVhc2VNYW5hZ2VyT3BlblNldHRpbmdzLFxuICAgIEdpdFJlbGVhc2VNYW5hZ2VyUHVibGlzaFNldHRpbmdzLFxuICAgIEdpdFJlbGVhc2VNYW5hZ2VyQWRkQXNzZXRTZXR0aW5nc1xufSBmcm9tICcuL21vZGVscydcblxuZXhwb3J0IGNsYXNzIFNldHRpbmdzIHtcbiAgICBwdWJsaWMgc3RhdGljIGdldENyZWF0ZVNldHRpbmdzKFxuICAgICAgICBidWlsZEFnZW50OiBJQnVpbGRBZ2VudFxuICAgICk6IEdpdFJlbGVhc2VNYW5hZ2VyQ3JlYXRlU2V0dGluZ3Mge1xuICAgICAgICBjb25zdCBtaWxlc3RvbmUgPSBidWlsZEFnZW50LmdldElucHV0KENyZWF0ZUZpZWxkcy5taWxlc3RvbmUpXG4gICAgICAgIGNvbnN0IG5hbWUgPSBidWlsZEFnZW50LmdldElucHV0KENyZWF0ZUZpZWxkcy5uYW1lKVxuICAgICAgICBjb25zdCBpbnB1dEZpbGVOYW1lID0gYnVpbGRBZ2VudC5nZXRJbnB1dChDcmVhdGVGaWVsZHMuaW5wdXRGaWxlTmFtZSlcbiAgICAgICAgY29uc3QgaXNQcmVSZWxlYXNlID0gYnVpbGRBZ2VudC5nZXRCb29sZWFuSW5wdXQoXG4gICAgICAgICAgICBDcmVhdGVGaWVsZHMuaXNQcmVSZWxlYXNlXG4gICAgICAgIClcbiAgICAgICAgY29uc3QgY29tbWl0ID0gYnVpbGRBZ2VudC5nZXRJbnB1dChDcmVhdGVGaWVsZHMuY29tbWl0KVxuICAgICAgICBjb25zdCBhc3NldHMgPSBidWlsZEFnZW50LmdldExpc3RJbnB1dChDcmVhdGVGaWVsZHMuYXNzZXRzKVxuXG4gICAgICAgIGNvbnN0IGNvbW1vblNldHRpbmdzID0gU2V0dGluZ3MuZ2V0Q29tbW9uU2V0dGluZ3MoYnVpbGRBZ2VudClcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmNvbW1vblNldHRpbmdzLFxuICAgICAgICAgICAgbWlsZXN0b25lLFxuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIGlucHV0RmlsZU5hbWUsXG4gICAgICAgICAgICBpc1ByZVJlbGVhc2UsXG4gICAgICAgICAgICBjb21taXQsXG4gICAgICAgICAgICBhc3NldHNcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgZ2V0RGlzY2FyZFNldHRpbmdzKFxuICAgICAgICBidWlsZEFnZW50OiBJQnVpbGRBZ2VudFxuICAgICk6IEdpdFJlbGVhc2VNYW5hZ2VyRGlzY2FyZFNldHRpbmdzIHtcbiAgICAgICAgY29uc3QgbWlsZXN0b25lID0gYnVpbGRBZ2VudC5nZXRJbnB1dChEaXNjYXJkRmllbGRzLm1pbGVzdG9uZSlcblxuICAgICAgICBjb25zdCBjb21tb25TZXR0aW5ncyA9IFNldHRpbmdzLmdldENvbW1vblNldHRpbmdzKGJ1aWxkQWdlbnQpXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5jb21tb25TZXR0aW5ncyxcbiAgICAgICAgICAgIG1pbGVzdG9uZVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBnZXRDbG9zZVNldHRpbmdzKFxuICAgICAgICBidWlsZEFnZW50OiBJQnVpbGRBZ2VudFxuICAgICk6IEdpdFJlbGVhc2VNYW5hZ2VyQ2xvc2VTZXR0aW5ncyB7XG4gICAgICAgIGNvbnN0IG1pbGVzdG9uZSA9IGJ1aWxkQWdlbnQuZ2V0SW5wdXQoQ2xvc2VGaWVsZHMubWlsZXN0b25lKVxuXG4gICAgICAgIGNvbnN0IGNvbW1vblNldHRpbmdzID0gU2V0dGluZ3MuZ2V0Q29tbW9uU2V0dGluZ3MoYnVpbGRBZ2VudClcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmNvbW1vblNldHRpbmdzLFxuICAgICAgICAgICAgbWlsZXN0b25lXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgc3RhdGljIGdldE9wZW5TZXR0aW5ncyhcbiAgICAgICAgYnVpbGRBZ2VudDogSUJ1aWxkQWdlbnRcbiAgICApOiBHaXRSZWxlYXNlTWFuYWdlck9wZW5TZXR0aW5ncyB7XG4gICAgICAgIGNvbnN0IG1pbGVzdG9uZSA9IGJ1aWxkQWdlbnQuZ2V0SW5wdXQoT3BlbkZpZWxkcy5taWxlc3RvbmUpXG5cbiAgICAgICAgY29uc3QgY29tbW9uU2V0dGluZ3MgPSBTZXR0aW5ncy5nZXRDb21tb25TZXR0aW5ncyhidWlsZEFnZW50KVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uY29tbW9uU2V0dGluZ3MsXG4gICAgICAgICAgICBtaWxlc3RvbmVcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgZ2V0UHVibGlzaFNldHRpbmdzKFxuICAgICAgICBidWlsZEFnZW50OiBJQnVpbGRBZ2VudFxuICAgICk6IEdpdFJlbGVhc2VNYW5hZ2VyUHVibGlzaFNldHRpbmdzIHtcbiAgICAgICAgY29uc3QgdGFnTmFtZSA9IGJ1aWxkQWdlbnQuZ2V0SW5wdXQoUHVibGlzaEZpZWxkcy50YWdOYW1lKVxuXG4gICAgICAgIGNvbnN0IGNvbW1vblNldHRpbmdzID0gU2V0dGluZ3MuZ2V0Q29tbW9uU2V0dGluZ3MoYnVpbGRBZ2VudClcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmNvbW1vblNldHRpbmdzLFxuICAgICAgICAgICAgdGFnTmFtZVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBnZXRBZGRBc3NldFNldHRpbmdzKFxuICAgICAgICBidWlsZEFnZW50OiBJQnVpbGRBZ2VudFxuICAgICk6IEdpdFJlbGVhc2VNYW5hZ2VyQWRkQXNzZXRTZXR0aW5ncyB7XG4gICAgICAgIGNvbnN0IHRhZ05hbWUgPSBidWlsZEFnZW50LmdldElucHV0KEFkZEFzc2V0RmllbGRzLnRhZ05hbWUpXG4gICAgICAgIGNvbnN0IGFzc2V0cyA9IGJ1aWxkQWdlbnQuZ2V0TGlzdElucHV0KEFkZEFzc2V0RmllbGRzLmFzc2V0cylcblxuICAgICAgICBjb25zdCBjb21tb25TZXR0aW5ncyA9IFNldHRpbmdzLmdldENvbW1vblNldHRpbmdzKGJ1aWxkQWdlbnQpXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5jb21tb25TZXR0aW5ncyxcbiAgICAgICAgICAgIHRhZ05hbWUsXG4gICAgICAgICAgICBhc3NldHNcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGdldENvbW1vblNldHRpbmdzKFxuICAgICAgICBidWlsZEFnZW50OiBJQnVpbGRBZ2VudFxuICAgICk6IEdpdFJlbGVhc2VNYW5hZ2VyU2V0dGluZ3Mge1xuICAgICAgICBjb25zdCBvd25lciA9IGJ1aWxkQWdlbnQuZ2V0SW5wdXQoQ29tbW9uRmllbGRzLm93bmVyLCB0cnVlKVxuICAgICAgICBjb25zdCByZXBvc2l0b3J5ID0gYnVpbGRBZ2VudC5nZXRJbnB1dChDb21tb25GaWVsZHMucmVwb3NpdG9yeSwgdHJ1ZSlcbiAgICAgICAgY29uc3QgdG9rZW4gPSBidWlsZEFnZW50LmdldElucHV0KENvbW1vbkZpZWxkcy50b2tlbiwgdHJ1ZSlcbiAgICAgICAgY29uc3QgdGFyZ2V0RGlyZWN0b3J5ID0gYnVpbGRBZ2VudC5nZXRJbnB1dChcbiAgICAgICAgICAgIENvbW1vbkZpZWxkcy50YXJnZXREaXJlY3RvcnlcbiAgICAgICAgKVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBvd25lcixcbiAgICAgICAgICAgIHJlcG9zaXRvcnksXG4gICAgICAgICAgICB0b2tlbixcbiAgICAgICAgICAgIHRhcmdldERpcmVjdG9yeVxuICAgICAgICB9XG4gICAgfVxufVxuIiwiaW1wb3J0IHBhdGggPSByZXF1aXJlKCdwYXRoJylcblxuaW1wb3J0IHsgVFlQRVMsIElCdWlsZEFnZW50LCBJRXhlY1Jlc3VsdCB9IGZyb20gJy4uLy4uL2NvcmUvbW9kZWxzJ1xuaW1wb3J0IHsgaW5qZWN0YWJsZSwgaW5qZWN0IH0gZnJvbSAnaW52ZXJzaWZ5J1xuaW1wb3J0IHsgRG90bmV0VG9vbCwgSURvdG5ldFRvb2wgfSBmcm9tICcuLi8uLi9jb3JlL2RvdG5ldC10b29sJ1xuaW1wb3J0IHsgSVZlcnNpb25NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vY29yZS92ZXJzaW9uTWFuYWdlcidcblxuaW1wb3J0IHtcbiAgICBHaXRSZWxlYXNlTWFuYWdlclNldHRpbmdzLFxuICAgIEdpdFJlbGVhc2VNYW5hZ2VyQ3JlYXRlU2V0dGluZ3MsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJEaXNjYXJkU2V0dGluZ3MsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJDbG9zZVNldHRpbmdzLFxuICAgIEdpdFJlbGVhc2VNYW5hZ2VyT3BlblNldHRpbmdzLFxuICAgIEdpdFJlbGVhc2VNYW5hZ2VyUHVibGlzaFNldHRpbmdzLFxuICAgIEdpdFJlbGVhc2VNYW5hZ2VyQWRkQXNzZXRTZXR0aW5nc1xufSBmcm9tICcuL21vZGVscydcblxuZXhwb3J0IGludGVyZmFjZSBJR2l0UmVsZWFzZU1hbmFnZXJUb29sIGV4dGVuZHMgSURvdG5ldFRvb2wge1xuICAgIGluc3RhbGwodmVyc2lvblNwZWM6IHN0cmluZywgaW5jbHVkZVByZXJlbGVhc2U6IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+XG4gICAgY3JlYXRlKHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlckNyZWF0ZVNldHRpbmdzKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD5cbiAgICBkaXNjYXJkKHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlckRpc2NhcmRTZXR0aW5ncyk6IFByb21pc2U8SUV4ZWNSZXN1bHQ+XG4gICAgY2xvc2Uoc2V0dGluZ3M6IEdpdFJlbGVhc2VNYW5hZ2VyQ2xvc2VTZXR0aW5ncyk6IFByb21pc2U8SUV4ZWNSZXN1bHQ+XG4gICAgb3BlbihzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJPcGVuU2V0dGluZ3MpOiBQcm9taXNlPElFeGVjUmVzdWx0PlxuICAgIHB1Ymxpc2goc2V0dGluZ3M6IEdpdFJlbGVhc2VNYW5hZ2VyUHVibGlzaFNldHRpbmdzKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD5cbiAgICBhZGRBc3NldChzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJBZGRBc3NldFNldHRpbmdzKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD5cbn1cblxuQGluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEdpdFJlbGVhc2VNYW5hZ2VyVG9vbFxuICAgIGV4dGVuZHMgRG90bmV0VG9vbFxuICAgIGltcGxlbWVudHMgSUdpdFJlbGVhc2VNYW5hZ2VyVG9vbCB7XG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIEBpbmplY3QoVFlQRVMuSUJ1aWxkQWdlbnQpIGJ1aWxkQWdlbnQ6IElCdWlsZEFnZW50LFxuICAgICAgICBAaW5qZWN0KFRZUEVTLklWZXJzaW9uTWFuYWdlcikgdmVyc2lvbk1hbmFnZXI6IElWZXJzaW9uTWFuYWdlclxuICAgICkge1xuICAgICAgICBzdXBlcihidWlsZEFnZW50LCB2ZXJzaW9uTWFuYWdlcilcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgaW5zdGFsbChcbiAgICAgICAgdmVyc2lvblNwZWM6IHN0cmluZyxcbiAgICAgICAgaW5jbHVkZVByZXJlbGVhc2U6IGJvb2xlYW5cbiAgICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy50b29sSW5zdGFsbChcbiAgICAgICAgICAgICdHaXRSZWxlYXNlTWFuYWdlci5Ub29sJyxcbiAgICAgICAgICAgIHZlcnNpb25TcGVjLFxuICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICBpbmNsdWRlUHJlcmVsZWFzZVxuICAgICAgICApXG4gICAgfVxuXG4gICAgcHVibGljIGNyZWF0ZShcbiAgICAgICAgc2V0dGluZ3M6IEdpdFJlbGVhc2VNYW5hZ2VyQ3JlYXRlU2V0dGluZ3NcbiAgICApOiBQcm9taXNlPElFeGVjUmVzdWx0PiB7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSB0aGlzLmdldENyZWF0ZUFyZ3VtZW50cyhzZXR0aW5ncylcblxuICAgICAgICByZXR1cm4gdGhpcy5leGVjdXRlKCdkb3RuZXQtZ2l0cmVsZWFzZW1hbmFnZXInLCBhcmdzKVxuICAgIH1cblxuICAgIHB1YmxpYyBkaXNjYXJkKFxuICAgICAgICBzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJEaXNjYXJkU2V0dGluZ3NcbiAgICApOiBQcm9taXNlPElFeGVjUmVzdWx0PiB7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSB0aGlzLmdldERpc2NhcmRBcmd1bWVudHMoc2V0dGluZ3MpXG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZSgnZG90bmV0LWdpdHJlbGVhc2VtYW5hZ2VyJywgYXJncylcbiAgICB9XG5cbiAgICBwdWJsaWMgY2xvc2UoXG4gICAgICAgIHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlckNsb3NlU2V0dGluZ3NcbiAgICApOiBQcm9taXNlPElFeGVjUmVzdWx0PiB7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSB0aGlzLmdldENsb3NlQXJndW1lbnRzKHNldHRpbmdzKVxuXG4gICAgICAgIHJldHVybiB0aGlzLmV4ZWN1dGUoJ2RvdG5ldC1naXRyZWxlYXNlbWFuYWdlcicsIGFyZ3MpXG4gICAgfVxuXG4gICAgcHVibGljIG9wZW4oc2V0dGluZ3M6IEdpdFJlbGVhc2VNYW5hZ2VyT3BlblNldHRpbmdzKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD4ge1xuICAgICAgICBjb25zdCBhcmdzID0gdGhpcy5nZXRPcGVuQXJndW1lbnRzKHNldHRpbmdzKVxuXG4gICAgICAgIHJldHVybiB0aGlzLmV4ZWN1dGUoJ2RvdG5ldC1naXRyZWxlYXNlbWFuYWdlcicsIGFyZ3MpXG4gICAgfVxuXG4gICAgcHVibGljIHB1Ymxpc2goXG4gICAgICAgIHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlclB1Ymxpc2hTZXR0aW5nc1xuICAgICk6IFByb21pc2U8SUV4ZWNSZXN1bHQ+IHtcbiAgICAgICAgY29uc3QgYXJncyA9IHRoaXMuZ2V0UHVibGlzaEFyZ3VtZW50cyhzZXR0aW5ncylcblxuICAgICAgICByZXR1cm4gdGhpcy5leGVjdXRlKCdkb3RuZXQtZ2l0cmVsZWFzZW1hbmFnZXInLCBhcmdzKVxuICAgIH1cblxuICAgIHB1YmxpYyBhZGRBc3NldChcbiAgICAgICAgc2V0dGluZ3M6IEdpdFJlbGVhc2VNYW5hZ2VyQWRkQXNzZXRTZXR0aW5nc1xuICAgICk6IFByb21pc2U8SUV4ZWNSZXN1bHQ+IHtcbiAgICAgICAgY29uc3QgYXJncyA9IHRoaXMuZ2V0QWRkQXNzZXRBcmd1bWVudHMoc2V0dGluZ3MpXG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZSgnZG90bmV0LWdpdHJlbGVhc2VtYW5hZ2VyJywgYXJncylcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldENvbW1vbkFyZ3VtZW50cyhzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJTZXR0aW5ncyk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgYXJnczogc3RyaW5nW10gPSBbXVxuXG4gICAgICAgIGFyZ3MucHVzaCgnLS1vd25lcicsIHNldHRpbmdzLm93bmVyKVxuICAgICAgICBhcmdzLnB1c2goJy0tcmVwb3NpdG9yeScsIHNldHRpbmdzLnJlcG9zaXRvcnkpXG4gICAgICAgIGFyZ3MucHVzaCgnLS10b2tlbicsIHNldHRpbmdzLnRva2VuKVxuXG4gICAgICAgIHNldHRpbmdzLnRhcmdldERpcmVjdG9yeSA9IHRoaXMuZ2V0UmVwb0RpcihzZXR0aW5ncy50YXJnZXREaXJlY3RvcnkpXG5cbiAgICAgICAgYXJncy5wdXNoKCctLXRhcmdldERpcmVjdG9yeScsIHNldHRpbmdzLnRhcmdldERpcmVjdG9yeSlcblxuICAgICAgICByZXR1cm4gYXJnc1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Q3JlYXRlQXJndW1lbnRzKFxuICAgICAgICBzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJDcmVhdGVTZXR0aW5nc1xuICAgICk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgYXJnczogc3RyaW5nW10gPSBbJ2NyZWF0ZScsIC4uLnRoaXMuZ2V0Q29tbW9uQXJndW1lbnRzKHNldHRpbmdzKV1cblxuICAgICAgICBpZiAoc2V0dGluZ3MubWlsZXN0b25lKSB7XG4gICAgICAgICAgICBhcmdzLnB1c2goJy0tbWlsZXN0b25lJywgc2V0dGluZ3MubWlsZXN0b25lKVxuICAgICAgICB9XG4gICAgICAgIGlmIChzZXR0aW5ncy5uYW1lKSB7XG4gICAgICAgICAgICBhcmdzLnB1c2goJy0tbmFtZScsIHNldHRpbmdzLm5hbWUpXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNldHRpbmdzLmNvbW1pdCkge1xuICAgICAgICAgICAgYXJncy5wdXNoKCctLXRhcmdldGNvbW1pdGlzaCcsIHNldHRpbmdzLmNvbW1pdClcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzZXR0aW5ncy5pbnB1dEZpbGVOYW1lKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5idWlsZEFnZW50LmZpbGVFeGlzdHMoc2V0dGluZ3MuaW5wdXRGaWxlTmFtZSkpIHtcbiAgICAgICAgICAgICAgICBhcmdzLnB1c2goJy0taW5wdXRGaWxlUGF0aCcsIHNldHRpbmdzLmlucHV0RmlsZU5hbWUpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgJ0dpdFJlbGVhc2VNYW5hZ2VyIGlucHV0RmlsZVBhdGggbm90IGZvdW5kIGF0ICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0dGluZ3MuaW5wdXRGaWxlTmFtZVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoc2V0dGluZ3MuaXNQcmVSZWxlYXNlKSB7XG4gICAgICAgICAgICBhcmdzLnB1c2goJy0tcHJlJylcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2V0dGluZ3MuYXNzZXRzICYmIHNldHRpbmdzLmFzc2V0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBzZXR0aW5ncy5hc3NldHMgPSBzZXR0aW5ncy5hc3NldHMubWFwKGFzc2V0ID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGF0aC5qb2luKHNldHRpbmdzLnRhcmdldERpcmVjdG9yeSwgYXNzZXQpXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBhcmdzLnB1c2goJy0tYXNzZXRzJywgc2V0dGluZ3MuYXNzZXRzLmpvaW4oJywnKSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhcmdzXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXREaXNjYXJkQXJndW1lbnRzKFxuICAgICAgICBzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJEaXNjYXJkU2V0dGluZ3NcbiAgICApOiBzdHJpbmdbXSB7XG4gICAgICAgIGNvbnN0IGFyZ3M6IHN0cmluZ1tdID0gWydkaXNjYXJkJywgLi4udGhpcy5nZXRDb21tb25Bcmd1bWVudHMoc2V0dGluZ3MpXVxuXG4gICAgICAgIGlmIChzZXR0aW5ncy5taWxlc3RvbmUpIHtcbiAgICAgICAgICAgIGFyZ3MucHVzaCgnLS1taWxlc3RvbmUnLCBzZXR0aW5ncy5taWxlc3RvbmUpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXJnc1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Q2xvc2VBcmd1bWVudHMoXG4gICAgICAgIHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlckNsb3NlU2V0dGluZ3NcbiAgICApOiBzdHJpbmdbXSB7XG4gICAgICAgIGNvbnN0IGFyZ3M6IHN0cmluZ1tdID0gWydjbG9zZScsIC4uLnRoaXMuZ2V0Q29tbW9uQXJndW1lbnRzKHNldHRpbmdzKV1cblxuICAgICAgICBpZiAoc2V0dGluZ3MubWlsZXN0b25lKSB7XG4gICAgICAgICAgICBhcmdzLnB1c2goJy0tbWlsZXN0b25lJywgc2V0dGluZ3MubWlsZXN0b25lKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFyZ3NcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldE9wZW5Bcmd1bWVudHMoXG4gICAgICAgIHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlck9wZW5TZXR0aW5nc1xuICAgICk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgYXJnczogc3RyaW5nW10gPSBbJ29wZW4nLCAuLi50aGlzLmdldENvbW1vbkFyZ3VtZW50cyhzZXR0aW5ncyldXG5cbiAgICAgICAgaWYgKHNldHRpbmdzLm1pbGVzdG9uZSkge1xuICAgICAgICAgICAgYXJncy5wdXNoKCctLW1pbGVzdG9uZScsIHNldHRpbmdzLm1pbGVzdG9uZSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhcmdzXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRQdWJsaXNoQXJndW1lbnRzKFxuICAgICAgICBzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJQdWJsaXNoU2V0dGluZ3NcbiAgICApOiBzdHJpbmdbXSB7XG4gICAgICAgIGNvbnN0IGFyZ3M6IHN0cmluZ1tdID0gWydwdWJsaXNoJywgLi4udGhpcy5nZXRDb21tb25Bcmd1bWVudHMoc2V0dGluZ3MpXVxuXG4gICAgICAgIGlmIChzZXR0aW5ncy50YWdOYW1lKSB7XG4gICAgICAgICAgICBhcmdzLnB1c2goJy0tdGFnTmFtZScsIHNldHRpbmdzLnRhZ05hbWUpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXJnc1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0QWRkQXNzZXRBcmd1bWVudHMoXG4gICAgICAgIHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlckFkZEFzc2V0U2V0dGluZ3NcbiAgICApOiBzdHJpbmdbXSB7XG4gICAgICAgIGNvbnN0IGFyZ3M6IHN0cmluZ1tdID0gW1xuICAgICAgICAgICAgJ2FkZGFzc2V0JyxcbiAgICAgICAgICAgIC4uLnRoaXMuZ2V0Q29tbW9uQXJndW1lbnRzKHNldHRpbmdzKVxuICAgICAgICBdXG5cbiAgICAgICAgaWYgKHNldHRpbmdzLnRhZ05hbWUpIHtcbiAgICAgICAgICAgIGFyZ3MucHVzaCgnLS10YWdOYW1lJywgc2V0dGluZ3MudGFnTmFtZSlcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2V0dGluZ3MuYXNzZXRzICYmIHNldHRpbmdzLmFzc2V0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBzZXR0aW5ncy5hc3NldHMgPSBzZXR0aW5ncy5hc3NldHMubWFwKGFzc2V0ID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGF0aC5qb2luKHNldHRpbmdzLnRhcmdldERpcmVjdG9yeSwgYXNzZXQpXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBhcmdzLnB1c2goJy0tYXNzZXRzJywgc2V0dGluZ3MuYXNzZXRzLmpvaW4oJywnKSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhcmdzXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSZXBvRGlyKHRhcmdldFBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIGxldCB3b3JrRGlyOiBzdHJpbmdcbiAgICAgICAgY29uc3Qgc3JjRGlyID0gdGhpcy5idWlsZEFnZW50LmdldFNvdXJjZURpcigpXG4gICAgICAgIGlmICghdGFyZ2V0UGF0aCkge1xuICAgICAgICAgICAgd29ya0RpciA9IHNyY0RpclxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHRoaXMuYnVpbGRBZ2VudC5kaXJlY3RvcnlFeGlzdHModGFyZ2V0UGF0aCkpIHtcbiAgICAgICAgICAgICAgICB3b3JrRGlyID0gcGF0aC5qb2luKHNyY0RpciwgdGFyZ2V0UGF0aClcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEaXJlY3Rvcnkgbm90IGZvdW5kIGF0ICcgKyB0YXJnZXRQYXRoKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB3b3JrRGlyLnJlcGxhY2UoL1xcXFwvZywgJy8nKVxuICAgIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiO1xyXG4vLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdC4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLiBTZWUgTElDRU5TRSBmaWxlIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGZ1bGwgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxudmFyIF9fYXdhaXRlciA9ICh0aGlzICYmIHRoaXMuX19hd2FpdGVyKSB8fCBmdW5jdGlvbiAodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHJlc3VsdC52YWx1ZSk7IH0pLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG5jb25zdCB1cmwgPSByZXF1aXJlKFwidXJsXCIpO1xyXG5jb25zdCBodHRwID0gcmVxdWlyZShcImh0dHBcIik7XHJcbmNvbnN0IGh0dHBzID0gcmVxdWlyZShcImh0dHBzXCIpO1xyXG5jb25zdCB1dGlsID0gcmVxdWlyZShcIi4vVXRpbFwiKTtcclxubGV0IGZzO1xyXG5sZXQgdHVubmVsO1xyXG52YXIgSHR0cENvZGVzO1xyXG4oZnVuY3Rpb24gKEh0dHBDb2Rlcykge1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIk9LXCJdID0gMjAwXSA9IFwiT0tcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJNdWx0aXBsZUNob2ljZXNcIl0gPSAzMDBdID0gXCJNdWx0aXBsZUNob2ljZXNcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJNb3ZlZFBlcm1hbmVudGx5XCJdID0gMzAxXSA9IFwiTW92ZWRQZXJtYW5lbnRseVwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlJlc291cmNlTW92ZWRcIl0gPSAzMDJdID0gXCJSZXNvdXJjZU1vdmVkXCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiU2VlT3RoZXJcIl0gPSAzMDNdID0gXCJTZWVPdGhlclwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIk5vdE1vZGlmaWVkXCJdID0gMzA0XSA9IFwiTm90TW9kaWZpZWRcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJVc2VQcm94eVwiXSA9IDMwNV0gPSBcIlVzZVByb3h5XCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiU3dpdGNoUHJveHlcIl0gPSAzMDZdID0gXCJTd2l0Y2hQcm94eVwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlRlbXBvcmFyeVJlZGlyZWN0XCJdID0gMzA3XSA9IFwiVGVtcG9yYXJ5UmVkaXJlY3RcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJQZXJtYW5lbnRSZWRpcmVjdFwiXSA9IDMwOF0gPSBcIlBlcm1hbmVudFJlZGlyZWN0XCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiQmFkUmVxdWVzdFwiXSA9IDQwMF0gPSBcIkJhZFJlcXVlc3RcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJVbmF1dGhvcml6ZWRcIl0gPSA0MDFdID0gXCJVbmF1dGhvcml6ZWRcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJQYXltZW50UmVxdWlyZWRcIl0gPSA0MDJdID0gXCJQYXltZW50UmVxdWlyZWRcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJGb3JiaWRkZW5cIl0gPSA0MDNdID0gXCJGb3JiaWRkZW5cIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJOb3RGb3VuZFwiXSA9IDQwNF0gPSBcIk5vdEZvdW5kXCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiTWV0aG9kTm90QWxsb3dlZFwiXSA9IDQwNV0gPSBcIk1ldGhvZE5vdEFsbG93ZWRcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJOb3RBY2NlcHRhYmxlXCJdID0gNDA2XSA9IFwiTm90QWNjZXB0YWJsZVwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlByb3h5QXV0aGVudGljYXRpb25SZXF1aXJlZFwiXSA9IDQwN10gPSBcIlByb3h5QXV0aGVudGljYXRpb25SZXF1aXJlZFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlJlcXVlc3RUaW1lb3V0XCJdID0gNDA4XSA9IFwiUmVxdWVzdFRpbWVvdXRcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJDb25mbGljdFwiXSA9IDQwOV0gPSBcIkNvbmZsaWN0XCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiR29uZVwiXSA9IDQxMF0gPSBcIkdvbmVcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJUb29NYW55UmVxdWVzdHNcIl0gPSA0MjldID0gXCJUb29NYW55UmVxdWVzdHNcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJJbnRlcm5hbFNlcnZlckVycm9yXCJdID0gNTAwXSA9IFwiSW50ZXJuYWxTZXJ2ZXJFcnJvclwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIk5vdEltcGxlbWVudGVkXCJdID0gNTAxXSA9IFwiTm90SW1wbGVtZW50ZWRcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJCYWRHYXRld2F5XCJdID0gNTAyXSA9IFwiQmFkR2F0ZXdheVwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlNlcnZpY2VVbmF2YWlsYWJsZVwiXSA9IDUwM10gPSBcIlNlcnZpY2VVbmF2YWlsYWJsZVwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIkdhdGV3YXlUaW1lb3V0XCJdID0gNTA0XSA9IFwiR2F0ZXdheVRpbWVvdXRcIjtcclxufSkoSHR0cENvZGVzID0gZXhwb3J0cy5IdHRwQ29kZXMgfHwgKGV4cG9ydHMuSHR0cENvZGVzID0ge30pKTtcclxuY29uc3QgSHR0cFJlZGlyZWN0Q29kZXMgPSBbSHR0cENvZGVzLk1vdmVkUGVybWFuZW50bHksIEh0dHBDb2Rlcy5SZXNvdXJjZU1vdmVkLCBIdHRwQ29kZXMuU2VlT3RoZXIsIEh0dHBDb2Rlcy5UZW1wb3JhcnlSZWRpcmVjdCwgSHR0cENvZGVzLlBlcm1hbmVudFJlZGlyZWN0XTtcclxuY29uc3QgSHR0cFJlc3BvbnNlUmV0cnlDb2RlcyA9IFtIdHRwQ29kZXMuQmFkR2F0ZXdheSwgSHR0cENvZGVzLlNlcnZpY2VVbmF2YWlsYWJsZSwgSHR0cENvZGVzLkdhdGV3YXlUaW1lb3V0XTtcclxuY29uc3QgTmV0d29ya1JldHJ5RXJyb3JzID0gWydFQ09OTlJFU0VUJywgJ0VOT1RGT1VORCcsICdFU09DS0VUVElNRURPVVQnLCAnRVRJTUVET1VUJywgJ0VDT05OUkVGVVNFRCddO1xyXG5jb25zdCBSZXRyeWFibGVIdHRwVmVyYnMgPSBbJ09QVElPTlMnLCAnR0VUJywgJ0RFTEVURScsICdIRUFEJ107XHJcbmNvbnN0IEV4cG9uZW50aWFsQmFja29mZkNlaWxpbmcgPSAxMDtcclxuY29uc3QgRXhwb25lbnRpYWxCYWNrb2ZmVGltZVNsaWNlID0gNTtcclxuY2xhc3MgSHR0cENsaWVudFJlc3BvbnNlIHtcclxuICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UpIHtcclxuICAgICAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xyXG4gICAgfVxyXG4gICAgcmVhZEJvZHkoKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcclxuICAgICAgICAgICAgbGV0IGJ1ZmZlciA9IEJ1ZmZlci5hbGxvYygwKTtcclxuICAgICAgICAgICAgY29uc3QgZW5jb2RpbmdDaGFyc2V0ID0gdXRpbC5vYnRhaW5Db250ZW50Q2hhcnNldCh0aGlzKTtcclxuICAgICAgICAgICAgLy8gRXh0cmFjdCBFbmNvZGluZyBmcm9tIGhlYWRlcjogJ2NvbnRlbnQtZW5jb2RpbmcnXHJcbiAgICAgICAgICAgIC8vIE1hdGNoIGBnemlwYCwgYGd6aXAsIGRlZmxhdGVgIHZhcmlhdGlvbnMgb2YgR1pJUCBlbmNvZGluZ1xyXG4gICAgICAgICAgICBjb25zdCBjb250ZW50RW5jb2RpbmcgPSB0aGlzLm1lc3NhZ2UuaGVhZGVyc1snY29udGVudC1lbmNvZGluZyddIHx8ICcnO1xyXG4gICAgICAgICAgICBjb25zdCBpc0d6aXBwZWRFbmNvZGVkID0gbmV3IFJlZ0V4cCgnKGd6aXAkKXwoZ3ppcCwgKmRlZmxhdGUpJykudGVzdChjb250ZW50RW5jb2RpbmcpO1xyXG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2Uub24oJ2RhdGEnLCBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY2h1bmsgPSAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSA/IEJ1ZmZlci5mcm9tKGRhdGEsIGVuY29kaW5nQ2hhcnNldCkgOiBkYXRhO1xyXG4gICAgICAgICAgICAgICAgYnVmZmVyID0gQnVmZmVyLmNvbmNhdChbYnVmZmVyLCBjaHVua10pO1xyXG4gICAgICAgICAgICB9KS5vbignZW5kJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNHemlwcGVkRW5jb2RlZCkgeyAvLyBQcm9jZXNzIEdaaXBwZWQgUmVzcG9uc2UgQm9keSBIRVJFXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGd1bnppcHBlZEJvZHkgPSB5aWVsZCB1dGlsLmRlY29tcHJlc3NHemlwcGVkQ29udGVudChidWZmZXIsIGVuY29kaW5nQ2hhcnNldCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoZ3VuemlwcGVkQm9keSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGJ1ZmZlci50b1N0cmluZyhlbmNvZGluZ0NoYXJzZXQpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSkub24oJ2Vycm9yJywgZnVuY3Rpb24gKGVycikge1xyXG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pKTtcclxuICAgIH1cclxufVxyXG5leHBvcnRzLkh0dHBDbGllbnRSZXNwb25zZSA9IEh0dHBDbGllbnRSZXNwb25zZTtcclxuZnVuY3Rpb24gaXNIdHRwcyhyZXF1ZXN0VXJsKSB7XHJcbiAgICBsZXQgcGFyc2VkVXJsID0gdXJsLnBhcnNlKHJlcXVlc3RVcmwpO1xyXG4gICAgcmV0dXJuIHBhcnNlZFVybC5wcm90b2NvbCA9PT0gJ2h0dHBzOic7XHJcbn1cclxuZXhwb3J0cy5pc0h0dHBzID0gaXNIdHRwcztcclxudmFyIEVudmlyb25tZW50VmFyaWFibGVzO1xyXG4oZnVuY3Rpb24gKEVudmlyb25tZW50VmFyaWFibGVzKSB7XHJcbiAgICBFbnZpcm9ubWVudFZhcmlhYmxlc1tcIkhUVFBfUFJPWFlcIl0gPSBcIkhUVFBfUFJPWFlcIjtcclxuICAgIEVudmlyb25tZW50VmFyaWFibGVzW1wiSFRUUFNfUFJPWFlcIl0gPSBcIkhUVFBTX1BST1hZXCI7XHJcbiAgICBFbnZpcm9ubWVudFZhcmlhYmxlc1tcIk5PX1BST1hZXCJdID0gXCJOT19QUk9YWVwiO1xyXG59KShFbnZpcm9ubWVudFZhcmlhYmxlcyB8fCAoRW52aXJvbm1lbnRWYXJpYWJsZXMgPSB7fSkpO1xyXG5jbGFzcyBIdHRwQ2xpZW50IHtcclxuICAgIGNvbnN0cnVjdG9yKHVzZXJBZ2VudCwgaGFuZGxlcnMsIHJlcXVlc3RPcHRpb25zKSB7XHJcbiAgICAgICAgdGhpcy5faWdub3JlU3NsRXJyb3IgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLl9hbGxvd1JlZGlyZWN0cyA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5fYWxsb3dSZWRpcmVjdERvd25ncmFkZSA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMuX21heFJlZGlyZWN0cyA9IDUwO1xyXG4gICAgICAgIHRoaXMuX2FsbG93UmV0cmllcyA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMuX21heFJldHJpZXMgPSAxO1xyXG4gICAgICAgIHRoaXMuX2tlZXBBbGl2ZSA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMuX2Rpc3Bvc2VkID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy51c2VyQWdlbnQgPSB1c2VyQWdlbnQ7XHJcbiAgICAgICAgdGhpcy5oYW5kbGVycyA9IGhhbmRsZXJzIHx8IFtdO1xyXG4gICAgICAgIGxldCBub19wcm94eSA9IHByb2Nlc3MuZW52W0Vudmlyb25tZW50VmFyaWFibGVzLk5PX1BST1hZXTtcclxuICAgICAgICBpZiAobm9fcHJveHkpIHtcclxuICAgICAgICAgICAgdGhpcy5faHR0cFByb3h5QnlwYXNzSG9zdHMgPSBbXTtcclxuICAgICAgICAgICAgbm9fcHJveHkuc3BsaXQoJywnKS5mb3JFYWNoKGJ5cGFzcyA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9odHRwUHJveHlCeXBhc3NIb3N0cy5wdXNoKHV0aWwuYnVpbGRQcm94eUJ5cGFzc1JlZ2V4RnJvbUVudihieXBhc3MpKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMucmVxdWVzdE9wdGlvbnMgPSByZXF1ZXN0T3B0aW9ucztcclxuICAgICAgICBpZiAocmVxdWVzdE9wdGlvbnMpIHtcclxuICAgICAgICAgICAgaWYgKHJlcXVlc3RPcHRpb25zLmlnbm9yZVNzbEVycm9yICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2lnbm9yZVNzbEVycm9yID0gcmVxdWVzdE9wdGlvbnMuaWdub3JlU3NsRXJyb3I7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5fc29ja2V0VGltZW91dCA9IHJlcXVlc3RPcHRpb25zLnNvY2tldFRpbWVvdXQ7XHJcbiAgICAgICAgICAgIHRoaXMuX2h0dHBQcm94eSA9IHJlcXVlc3RPcHRpb25zLnByb3h5O1xyXG4gICAgICAgICAgICBpZiAocmVxdWVzdE9wdGlvbnMucHJveHkgJiYgcmVxdWVzdE9wdGlvbnMucHJveHkucHJveHlCeXBhc3NIb3N0cykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5faHR0cFByb3h5QnlwYXNzSG9zdHMgPSBbXTtcclxuICAgICAgICAgICAgICAgIHJlcXVlc3RPcHRpb25zLnByb3h5LnByb3h5QnlwYXNzSG9zdHMuZm9yRWFjaChieXBhc3MgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2h0dHBQcm94eUJ5cGFzc0hvc3RzLnB1c2gobmV3IFJlZ0V4cChieXBhc3MsICdpJykpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5fY2VydENvbmZpZyA9IHJlcXVlc3RPcHRpb25zLmNlcnQ7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9jZXJ0Q29uZmlnKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBJZiB1c2luZyBjZXJ0LCBuZWVkIGZzXHJcbiAgICAgICAgICAgICAgICBmcyA9IHJlcXVpcmUoJ2ZzJyk7XHJcbiAgICAgICAgICAgICAgICAvLyBjYWNoZSB0aGUgY2VydCBjb250ZW50IGludG8gbWVtb3J5LCBzbyB3ZSBkb24ndCBoYXZlIHRvIHJlYWQgaXQgZnJvbSBkaXNrIGV2ZXJ5IHRpbWVcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9jZXJ0Q29uZmlnLmNhRmlsZSAmJiBmcy5leGlzdHNTeW5jKHRoaXMuX2NlcnRDb25maWcuY2FGaWxlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NhID0gZnMucmVhZEZpbGVTeW5jKHRoaXMuX2NlcnRDb25maWcuY2FGaWxlLCAndXRmOCcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2NlcnRDb25maWcuY2VydEZpbGUgJiYgZnMuZXhpc3RzU3luYyh0aGlzLl9jZXJ0Q29uZmlnLmNlcnRGaWxlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NlcnQgPSBmcy5yZWFkRmlsZVN5bmModGhpcy5fY2VydENvbmZpZy5jZXJ0RmlsZSwgJ3V0ZjgnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9jZXJ0Q29uZmlnLmtleUZpbGUgJiYgZnMuZXhpc3RzU3luYyh0aGlzLl9jZXJ0Q29uZmlnLmtleUZpbGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fa2V5ID0gZnMucmVhZEZpbGVTeW5jKHRoaXMuX2NlcnRDb25maWcua2V5RmlsZSwgJ3V0ZjgnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocmVxdWVzdE9wdGlvbnMuYWxsb3dSZWRpcmVjdHMgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fYWxsb3dSZWRpcmVjdHMgPSByZXF1ZXN0T3B0aW9ucy5hbGxvd1JlZGlyZWN0cztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocmVxdWVzdE9wdGlvbnMuYWxsb3dSZWRpcmVjdERvd25ncmFkZSAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9hbGxvd1JlZGlyZWN0RG93bmdyYWRlID0gcmVxdWVzdE9wdGlvbnMuYWxsb3dSZWRpcmVjdERvd25ncmFkZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocmVxdWVzdE9wdGlvbnMubWF4UmVkaXJlY3RzICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX21heFJlZGlyZWN0cyA9IE1hdGgubWF4KHJlcXVlc3RPcHRpb25zLm1heFJlZGlyZWN0cywgMCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHJlcXVlc3RPcHRpb25zLmtlZXBBbGl2ZSAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9rZWVwQWxpdmUgPSByZXF1ZXN0T3B0aW9ucy5rZWVwQWxpdmU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHJlcXVlc3RPcHRpb25zLmFsbG93UmV0cmllcyAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9hbGxvd1JldHJpZXMgPSByZXF1ZXN0T3B0aW9ucy5hbGxvd1JldHJpZXM7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHJlcXVlc3RPcHRpb25zLm1heFJldHJpZXMgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fbWF4UmV0cmllcyA9IHJlcXVlc3RPcHRpb25zLm1heFJldHJpZXM7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBvcHRpb25zKHJlcXVlc3RVcmwsIGFkZGl0aW9uYWxIZWFkZXJzKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdCgnT1BUSU9OUycsIHJlcXVlc3RVcmwsIG51bGwsIGFkZGl0aW9uYWxIZWFkZXJzIHx8IHt9KTtcclxuICAgIH1cclxuICAgIGdldChyZXF1ZXN0VXJsLCBhZGRpdGlvbmFsSGVhZGVycykge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QoJ0dFVCcsIHJlcXVlc3RVcmwsIG51bGwsIGFkZGl0aW9uYWxIZWFkZXJzIHx8IHt9KTtcclxuICAgIH1cclxuICAgIGRlbChyZXF1ZXN0VXJsLCBhZGRpdGlvbmFsSGVhZGVycykge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QoJ0RFTEVURScsIHJlcXVlc3RVcmwsIG51bGwsIGFkZGl0aW9uYWxIZWFkZXJzIHx8IHt9KTtcclxuICAgIH1cclxuICAgIHBvc3QocmVxdWVzdFVybCwgZGF0YSwgYWRkaXRpb25hbEhlYWRlcnMpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KCdQT1NUJywgcmVxdWVzdFVybCwgZGF0YSwgYWRkaXRpb25hbEhlYWRlcnMgfHwge30pO1xyXG4gICAgfVxyXG4gICAgcGF0Y2gocmVxdWVzdFVybCwgZGF0YSwgYWRkaXRpb25hbEhlYWRlcnMpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KCdQQVRDSCcsIHJlcXVlc3RVcmwsIGRhdGEsIGFkZGl0aW9uYWxIZWFkZXJzIHx8IHt9KTtcclxuICAgIH1cclxuICAgIHB1dChyZXF1ZXN0VXJsLCBkYXRhLCBhZGRpdGlvbmFsSGVhZGVycykge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QoJ1BVVCcsIHJlcXVlc3RVcmwsIGRhdGEsIGFkZGl0aW9uYWxIZWFkZXJzIHx8IHt9KTtcclxuICAgIH1cclxuICAgIGhlYWQocmVxdWVzdFVybCwgYWRkaXRpb25hbEhlYWRlcnMpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KCdIRUFEJywgcmVxdWVzdFVybCwgbnVsbCwgYWRkaXRpb25hbEhlYWRlcnMgfHwge30pO1xyXG4gICAgfVxyXG4gICAgc2VuZFN0cmVhbSh2ZXJiLCByZXF1ZXN0VXJsLCBzdHJlYW0sIGFkZGl0aW9uYWxIZWFkZXJzKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdCh2ZXJiLCByZXF1ZXN0VXJsLCBzdHJlYW0sIGFkZGl0aW9uYWxIZWFkZXJzKTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogTWFrZXMgYSByYXcgaHR0cCByZXF1ZXN0LlxyXG4gICAgICogQWxsIG90aGVyIG1ldGhvZHMgc3VjaCBhcyBnZXQsIHBvc3QsIHBhdGNoLCBhbmQgcmVxdWVzdCB1bHRpbWF0ZWx5IGNhbGwgdGhpcy5cclxuICAgICAqIFByZWZlciBnZXQsIGRlbCwgcG9zdCBhbmQgcGF0Y2hcclxuICAgICAqL1xyXG4gICAgcmVxdWVzdCh2ZXJiLCByZXF1ZXN0VXJsLCBkYXRhLCBoZWFkZXJzKSB7XHJcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2Rpc3Bvc2VkKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDbGllbnQgaGFzIGFscmVhZHkgYmVlbiBkaXNwb3NlZC5cIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgbGV0IHBhcnNlZFVybCA9IHVybC5wYXJzZShyZXF1ZXN0VXJsKTtcclxuICAgICAgICAgICAgbGV0IGluZm8gPSB0aGlzLl9wcmVwYXJlUmVxdWVzdCh2ZXJiLCBwYXJzZWRVcmwsIGhlYWRlcnMpO1xyXG4gICAgICAgICAgICAvLyBPbmx5IHBlcmZvcm0gcmV0cmllcyBvbiByZWFkcyBzaW5jZSB3cml0ZXMgbWF5IG5vdCBiZSBpZGVtcG90ZW50LlxyXG4gICAgICAgICAgICBsZXQgbWF4VHJpZXMgPSAodGhpcy5fYWxsb3dSZXRyaWVzICYmIFJldHJ5YWJsZUh0dHBWZXJicy5pbmRleE9mKHZlcmIpICE9IC0xKSA/IHRoaXMuX21heFJldHJpZXMgKyAxIDogMTtcclxuICAgICAgICAgICAgbGV0IG51bVRyaWVzID0gMDtcclxuICAgICAgICAgICAgbGV0IHJlc3BvbnNlO1xyXG4gICAgICAgICAgICB3aGlsZSAobnVtVHJpZXMgPCBtYXhUcmllcykge1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZSA9IHlpZWxkIHRoaXMucmVxdWVzdFJhdyhpbmZvLCBkYXRhKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgICAgICAgICBudW1UcmllcysrO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnIgJiYgZXJyLmNvZGUgJiYgTmV0d29ya1JldHJ5RXJyb3JzLmluZGV4T2YoZXJyLmNvZGUpID4gLTEgJiYgbnVtVHJpZXMgPCBtYXhUcmllcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB5aWVsZCB0aGlzLl9wZXJmb3JtRXhwb25lbnRpYWxCYWNrb2ZmKG51bVRyaWVzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGl0J3MgYW4gYXV0aGVudGljYXRpb24gY2hhbGxlbmdlXHJcbiAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UgJiYgcmVzcG9uc2UubWVzc2FnZSAmJiByZXNwb25zZS5tZXNzYWdlLnN0YXR1c0NvZGUgPT09IEh0dHBDb2Rlcy5VbmF1dGhvcml6ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgYXV0aGVudGljYXRpb25IYW5kbGVyO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5oYW5kbGVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5oYW5kbGVyc1tpXS5jYW5IYW5kbGVBdXRoZW50aWNhdGlvbihyZXNwb25zZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1dGhlbnRpY2F0aW9uSGFuZGxlciA9IHRoaXMuaGFuZGxlcnNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoYXV0aGVudGljYXRpb25IYW5kbGVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhdXRoZW50aWNhdGlvbkhhbmRsZXIuaGFuZGxlQXV0aGVudGljYXRpb24odGhpcywgaW5mbywgZGF0YSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBoYXZlIHJlY2VpdmVkIGFuIHVuYXV0aG9yaXplZCByZXNwb25zZSBidXQgaGF2ZSBubyBoYW5kbGVycyB0byBoYW5kbGUgaXQuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIExldCB0aGUgcmVzcG9uc2UgcmV0dXJuIHRvIHRoZSBjYWxsZXIuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBsZXQgcmVkaXJlY3RzUmVtYWluaW5nID0gdGhpcy5fbWF4UmVkaXJlY3RzO1xyXG4gICAgICAgICAgICAgICAgd2hpbGUgKEh0dHBSZWRpcmVjdENvZGVzLmluZGV4T2YocmVzcG9uc2UubWVzc2FnZS5zdGF0dXNDb2RlKSAhPSAtMVxyXG4gICAgICAgICAgICAgICAgICAgICYmIHRoaXMuX2FsbG93UmVkaXJlY3RzXHJcbiAgICAgICAgICAgICAgICAgICAgJiYgcmVkaXJlY3RzUmVtYWluaW5nID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlZGlyZWN0VXJsID0gcmVzcG9uc2UubWVzc2FnZS5oZWFkZXJzW1wibG9jYXRpb25cIl07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFyZWRpcmVjdFVybCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiB0aGVyZSdzIG5vIGxvY2F0aW9uIHRvIHJlZGlyZWN0IHRvLCB3ZSB3b24ndFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHBhcnNlZFJlZGlyZWN0VXJsID0gdXJsLnBhcnNlKHJlZGlyZWN0VXJsKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocGFyc2VkVXJsLnByb3RvY29sID09ICdodHRwczonICYmIHBhcnNlZFVybC5wcm90b2NvbCAhPSBwYXJzZWRSZWRpcmVjdFVybC5wcm90b2NvbCAmJiAhdGhpcy5fYWxsb3dSZWRpcmVjdERvd25ncmFkZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJSZWRpcmVjdCBmcm9tIEhUVFBTIHRvIEhUVFAgcHJvdG9jb2wuIFRoaXMgZG93bmdyYWRlIGlzIG5vdCBhbGxvd2VkIGZvciBzZWN1cml0eSByZWFzb25zLiBJZiB5b3Ugd2FudCB0byBhbGxvdyB0aGlzIGJlaGF2aW9yLCBzZXQgdGhlIGFsbG93UmVkaXJlY3REb3duZ3JhZGUgb3B0aW9uIHRvIHRydWUuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAvLyB3ZSBuZWVkIHRvIGZpbmlzaCByZWFkaW5nIHRoZSByZXNwb25zZSBiZWZvcmUgcmVhc3NpZ25pbmcgcmVzcG9uc2VcclxuICAgICAgICAgICAgICAgICAgICAvLyB3aGljaCB3aWxsIGxlYWsgdGhlIG9wZW4gc29ja2V0LlxyXG4gICAgICAgICAgICAgICAgICAgIHlpZWxkIHJlc3BvbnNlLnJlYWRCb2R5KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gbGV0J3MgbWFrZSB0aGUgcmVxdWVzdCB3aXRoIHRoZSBuZXcgcmVkaXJlY3RVcmxcclxuICAgICAgICAgICAgICAgICAgICBpbmZvID0gdGhpcy5fcHJlcGFyZVJlcXVlc3QodmVyYiwgcGFyc2VkUmVkaXJlY3RVcmwsIGhlYWRlcnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0geWllbGQgdGhpcy5yZXF1ZXN0UmF3KGluZm8sIGRhdGEpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0c1JlbWFpbmluZy0tO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKEh0dHBSZXNwb25zZVJldHJ5Q29kZXMuaW5kZXhPZihyZXNwb25zZS5tZXNzYWdlLnN0YXR1c0NvZGUpID09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgbm90IGEgcmV0cnkgY29kZSwgcmV0dXJuIGltbWVkaWF0ZWx5IGluc3RlYWQgb2YgcmV0cnlpbmdcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBudW1UcmllcyArPSAxO1xyXG4gICAgICAgICAgICAgICAgaWYgKG51bVRyaWVzIDwgbWF4VHJpZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICB5aWVsZCByZXNwb25zZS5yZWFkQm9keSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHlpZWxkIHRoaXMuX3BlcmZvcm1FeHBvbmVudGlhbEJhY2tvZmYobnVtVHJpZXMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogTmVlZHMgdG8gYmUgY2FsbGVkIGlmIGtlZXBBbGl2ZSBpcyBzZXQgdG8gdHJ1ZSBpbiByZXF1ZXN0IG9wdGlvbnMuXHJcbiAgICAgKi9cclxuICAgIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2FnZW50KSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2FnZW50LmRlc3Ryb3koKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fZGlzcG9zZWQgPSB0cnVlO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBSYXcgcmVxdWVzdC5cclxuICAgICAqIEBwYXJhbSBpbmZvXHJcbiAgICAgKiBAcGFyYW0gZGF0YVxyXG4gICAgICovXHJcbiAgICByZXF1ZXN0UmF3KGluZm8sIGRhdGEpIHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICBsZXQgY2FsbGJhY2tGb3JSZXN1bHQgPSBmdW5jdGlvbiAoZXJyLCByZXMpIHtcclxuICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcclxuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJlc29sdmUocmVzKTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgdGhpcy5yZXF1ZXN0UmF3V2l0aENhbGxiYWNrKGluZm8sIGRhdGEsIGNhbGxiYWNrRm9yUmVzdWx0KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogUmF3IHJlcXVlc3Qgd2l0aCBjYWxsYmFjay5cclxuICAgICAqIEBwYXJhbSBpbmZvXHJcbiAgICAgKiBAcGFyYW0gZGF0YVxyXG4gICAgICogQHBhcmFtIG9uUmVzdWx0XHJcbiAgICAgKi9cclxuICAgIHJlcXVlc3RSYXdXaXRoQ2FsbGJhY2soaW5mbywgZGF0YSwgb25SZXN1bHQpIHtcclxuICAgICAgICBsZXQgc29ja2V0O1xyXG4gICAgICAgIGlmICh0eXBlb2YgKGRhdGEpID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICBpbmZvLm9wdGlvbnMuaGVhZGVyc1tcIkNvbnRlbnQtTGVuZ3RoXCJdID0gQnVmZmVyLmJ5dGVMZW5ndGgoZGF0YSwgJ3V0ZjgnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgbGV0IGNhbGxiYWNrQ2FsbGVkID0gZmFsc2U7XHJcbiAgICAgICAgbGV0IGhhbmRsZVJlc3VsdCA9IChlcnIsIHJlcykgPT4ge1xyXG4gICAgICAgICAgICBpZiAoIWNhbGxiYWNrQ2FsbGVkKSB7XHJcbiAgICAgICAgICAgICAgICBjYWxsYmFja0NhbGxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBvblJlc3VsdChlcnIsIHJlcyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIGxldCByZXEgPSBpbmZvLmh0dHBNb2R1bGUucmVxdWVzdChpbmZvLm9wdGlvbnMsIChtc2cpID0+IHtcclxuICAgICAgICAgICAgbGV0IHJlcyA9IG5ldyBIdHRwQ2xpZW50UmVzcG9uc2UobXNnKTtcclxuICAgICAgICAgICAgaGFuZGxlUmVzdWx0KG51bGwsIHJlcyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmVxLm9uKCdzb2NrZXQnLCAoc29jaykgPT4ge1xyXG4gICAgICAgICAgICBzb2NrZXQgPSBzb2NrO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIElmIHdlIGV2ZXIgZ2V0IGRpc2Nvbm5lY3RlZCwgd2Ugd2FudCB0aGUgc29ja2V0IHRvIHRpbWVvdXQgZXZlbnR1YWxseVxyXG4gICAgICAgIHJlcS5zZXRUaW1lb3V0KHRoaXMuX3NvY2tldFRpbWVvdXQgfHwgMyAqIDYwMDAwLCAoKSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChzb2NrZXQpIHtcclxuICAgICAgICAgICAgICAgIHNvY2tldC5kZXN0cm95KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaGFuZGxlUmVzdWx0KG5ldyBFcnJvcignUmVxdWVzdCB0aW1lb3V0OiAnICsgaW5mby5vcHRpb25zLnBhdGgpLCBudWxsKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXEub24oJ2Vycm9yJywgZnVuY3Rpb24gKGVycikge1xyXG4gICAgICAgICAgICAvLyBlcnIgaGFzIHN0YXR1c0NvZGUgcHJvcGVydHlcclxuICAgICAgICAgICAgLy8gcmVzIHNob3VsZCBoYXZlIGhlYWRlcnNcclxuICAgICAgICAgICAgaGFuZGxlUmVzdWx0KGVyciwgbnVsbCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgaWYgKGRhdGEgJiYgdHlwZW9mIChkYXRhKSA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgcmVxLndyaXRlKGRhdGEsICd1dGY4Jyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChkYXRhICYmIHR5cGVvZiAoZGF0YSkgIT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIGRhdGEub24oJ2Nsb3NlJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgcmVxLmVuZCgpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgZGF0YS5waXBlKHJlcSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXEuZW5kKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgX3ByZXBhcmVSZXF1ZXN0KG1ldGhvZCwgcmVxdWVzdFVybCwgaGVhZGVycykge1xyXG4gICAgICAgIGNvbnN0IGluZm8gPSB7fTtcclxuICAgICAgICBpbmZvLnBhcnNlZFVybCA9IHJlcXVlc3RVcmw7XHJcbiAgICAgICAgY29uc3QgdXNpbmdTc2wgPSBpbmZvLnBhcnNlZFVybC5wcm90b2NvbCA9PT0gJ2h0dHBzOic7XHJcbiAgICAgICAgaW5mby5odHRwTW9kdWxlID0gdXNpbmdTc2wgPyBodHRwcyA6IGh0dHA7XHJcbiAgICAgICAgY29uc3QgZGVmYXVsdFBvcnQgPSB1c2luZ1NzbCA/IDQ0MyA6IDgwO1xyXG4gICAgICAgIGluZm8ub3B0aW9ucyA9IHt9O1xyXG4gICAgICAgIGluZm8ub3B0aW9ucy5ob3N0ID0gaW5mby5wYXJzZWRVcmwuaG9zdG5hbWU7XHJcbiAgICAgICAgaW5mby5vcHRpb25zLnBvcnQgPSBpbmZvLnBhcnNlZFVybC5wb3J0ID8gcGFyc2VJbnQoaW5mby5wYXJzZWRVcmwucG9ydCkgOiBkZWZhdWx0UG9ydDtcclxuICAgICAgICBpbmZvLm9wdGlvbnMucGF0aCA9IChpbmZvLnBhcnNlZFVybC5wYXRobmFtZSB8fCAnJykgKyAoaW5mby5wYXJzZWRVcmwuc2VhcmNoIHx8ICcnKTtcclxuICAgICAgICBpbmZvLm9wdGlvbnMubWV0aG9kID0gbWV0aG9kO1xyXG4gICAgICAgIGluZm8ub3B0aW9ucy50aW1lb3V0ID0gKHRoaXMucmVxdWVzdE9wdGlvbnMgJiYgdGhpcy5yZXF1ZXN0T3B0aW9ucy5zb2NrZXRUaW1lb3V0KSB8fCB0aGlzLl9zb2NrZXRUaW1lb3V0O1xyXG4gICAgICAgIHRoaXMuX3NvY2tldFRpbWVvdXQgPSBpbmZvLm9wdGlvbnMudGltZW91dDtcclxuICAgICAgICBpbmZvLm9wdGlvbnMuaGVhZGVycyA9IHRoaXMuX21lcmdlSGVhZGVycyhoZWFkZXJzKTtcclxuICAgICAgICBpZiAodGhpcy51c2VyQWdlbnQgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICBpbmZvLm9wdGlvbnMuaGVhZGVyc1tcInVzZXItYWdlbnRcIl0gPSB0aGlzLnVzZXJBZ2VudDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaW5mby5vcHRpb25zLmFnZW50ID0gdGhpcy5fZ2V0QWdlbnQoaW5mby5wYXJzZWRVcmwpO1xyXG4gICAgICAgIC8vIGdpdmVzIGhhbmRsZXJzIGFuIG9wcG9ydHVuaXR5IHRvIHBhcnRpY2lwYXRlXHJcbiAgICAgICAgaWYgKHRoaXMuaGFuZGxlcnMgJiYgIXRoaXMuX2lzUHJlc2lnbmVkKHVybC5mb3JtYXQocmVxdWVzdFVybCkpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlcnMuZm9yRWFjaCgoaGFuZGxlcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgaGFuZGxlci5wcmVwYXJlUmVxdWVzdChpbmZvLm9wdGlvbnMpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGluZm87XHJcbiAgICB9XHJcbiAgICBfaXNQcmVzaWduZWQocmVxdWVzdFVybCkge1xyXG4gICAgICAgIGlmICh0aGlzLnJlcXVlc3RPcHRpb25zICYmIHRoaXMucmVxdWVzdE9wdGlvbnMucHJlc2lnbmVkVXJsUGF0dGVybnMpIHtcclxuICAgICAgICAgICAgY29uc3QgcGF0dGVybnMgPSB0aGlzLnJlcXVlc3RPcHRpb25zLnByZXNpZ25lZFVybFBhdHRlcm5zO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhdHRlcm5zLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVxdWVzdFVybC5tYXRjaChwYXR0ZXJuc1tpXSkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICBfbWVyZ2VIZWFkZXJzKGhlYWRlcnMpIHtcclxuICAgICAgICBjb25zdCBsb3dlcmNhc2VLZXlzID0gb2JqID0+IE9iamVjdC5rZXlzKG9iaikucmVkdWNlKChjLCBrKSA9PiAoY1trLnRvTG93ZXJDYXNlKCldID0gb2JqW2tdLCBjKSwge30pO1xyXG4gICAgICAgIGlmICh0aGlzLnJlcXVlc3RPcHRpb25zICYmIHRoaXMucmVxdWVzdE9wdGlvbnMuaGVhZGVycykge1xyXG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgbG93ZXJjYXNlS2V5cyh0aGlzLnJlcXVlc3RPcHRpb25zLmhlYWRlcnMpLCBsb3dlcmNhc2VLZXlzKGhlYWRlcnMpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGxvd2VyY2FzZUtleXMoaGVhZGVycyB8fCB7fSk7XHJcbiAgICB9XHJcbiAgICBfZ2V0QWdlbnQocGFyc2VkVXJsKSB7XHJcbiAgICAgICAgbGV0IGFnZW50O1xyXG4gICAgICAgIGxldCBwcm94eSA9IHRoaXMuX2dldFByb3h5KHBhcnNlZFVybCk7XHJcbiAgICAgICAgbGV0IHVzZVByb3h5ID0gcHJveHkucHJveHlVcmwgJiYgcHJveHkucHJveHlVcmwuaG9zdG5hbWUgJiYgIXRoaXMuX2lzTWF0Y2hJbkJ5cGFzc1Byb3h5TGlzdChwYXJzZWRVcmwpO1xyXG4gICAgICAgIGlmICh0aGlzLl9rZWVwQWxpdmUgJiYgdXNlUHJveHkpIHtcclxuICAgICAgICAgICAgYWdlbnQgPSB0aGlzLl9wcm94eUFnZW50O1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5fa2VlcEFsaXZlICYmICF1c2VQcm94eSkge1xyXG4gICAgICAgICAgICBhZ2VudCA9IHRoaXMuX2FnZW50O1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBpZiBhZ2VudCBpcyBhbHJlYWR5IGFzc2lnbmVkIHVzZSB0aGF0IGFnZW50LlxyXG4gICAgICAgIGlmICghIWFnZW50KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBhZ2VudDtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgdXNpbmdTc2wgPSBwYXJzZWRVcmwucHJvdG9jb2wgPT09ICdodHRwczonO1xyXG4gICAgICAgIGxldCBtYXhTb2NrZXRzID0gMTAwO1xyXG4gICAgICAgIGlmICghIXRoaXMucmVxdWVzdE9wdGlvbnMpIHtcclxuICAgICAgICAgICAgbWF4U29ja2V0cyA9IHRoaXMucmVxdWVzdE9wdGlvbnMubWF4U29ja2V0cyB8fCBodHRwLmdsb2JhbEFnZW50Lm1heFNvY2tldHM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh1c2VQcm94eSkge1xyXG4gICAgICAgICAgICAvLyBJZiB1c2luZyBwcm94eSwgbmVlZCB0dW5uZWxcclxuICAgICAgICAgICAgaWYgKCF0dW5uZWwpIHtcclxuICAgICAgICAgICAgICAgIHR1bm5lbCA9IHJlcXVpcmUoJ3R1bm5lbCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IGFnZW50T3B0aW9ucyA9IHtcclxuICAgICAgICAgICAgICAgIG1heFNvY2tldHM6IG1heFNvY2tldHMsXHJcbiAgICAgICAgICAgICAgICBrZWVwQWxpdmU6IHRoaXMuX2tlZXBBbGl2ZSxcclxuICAgICAgICAgICAgICAgIHByb3h5OiB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJveHlBdXRoOiBwcm94eS5wcm94eUF1dGgsXHJcbiAgICAgICAgICAgICAgICAgICAgaG9zdDogcHJveHkucHJveHlVcmwuaG9zdG5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgcG9ydDogcHJveHkucHJveHlVcmwucG9ydFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgbGV0IHR1bm5lbEFnZW50O1xyXG4gICAgICAgICAgICBjb25zdCBvdmVySHR0cHMgPSBwcm94eS5wcm94eVVybC5wcm90b2NvbCA9PT0gJ2h0dHBzOic7XHJcbiAgICAgICAgICAgIGlmICh1c2luZ1NzbCkge1xyXG4gICAgICAgICAgICAgICAgdHVubmVsQWdlbnQgPSBvdmVySHR0cHMgPyB0dW5uZWwuaHR0cHNPdmVySHR0cHMgOiB0dW5uZWwuaHR0cHNPdmVySHR0cDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHR1bm5lbEFnZW50ID0gb3Zlckh0dHBzID8gdHVubmVsLmh0dHBPdmVySHR0cHMgOiB0dW5uZWwuaHR0cE92ZXJIdHRwO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGFnZW50ID0gdHVubmVsQWdlbnQoYWdlbnRPcHRpb25zKTtcclxuICAgICAgICAgICAgdGhpcy5fcHJveHlBZ2VudCA9IGFnZW50O1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBpZiByZXVzaW5nIGFnZW50IGFjcm9zcyByZXF1ZXN0IGFuZCB0dW5uZWxpbmcgYWdlbnQgaXNuJ3QgYXNzaWduZWQgY3JlYXRlIGEgbmV3IGFnZW50XHJcbiAgICAgICAgaWYgKHRoaXMuX2tlZXBBbGl2ZSAmJiAhYWdlbnQpIHtcclxuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHsga2VlcEFsaXZlOiB0aGlzLl9rZWVwQWxpdmUsIG1heFNvY2tldHM6IG1heFNvY2tldHMgfTtcclxuICAgICAgICAgICAgYWdlbnQgPSB1c2luZ1NzbCA/IG5ldyBodHRwcy5BZ2VudChvcHRpb25zKSA6IG5ldyBodHRwLkFnZW50KG9wdGlvbnMpO1xyXG4gICAgICAgICAgICB0aGlzLl9hZ2VudCA9IGFnZW50O1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBpZiBub3QgdXNpbmcgcHJpdmF0ZSBhZ2VudCBhbmQgdHVubmVsIGFnZW50IGlzbid0IHNldHVwIHRoZW4gdXNlIGdsb2JhbCBhZ2VudFxyXG4gICAgICAgIGlmICghYWdlbnQpIHtcclxuICAgICAgICAgICAgYWdlbnQgPSB1c2luZ1NzbCA/IGh0dHBzLmdsb2JhbEFnZW50IDogaHR0cC5nbG9iYWxBZ2VudDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHVzaW5nU3NsICYmIHRoaXMuX2lnbm9yZVNzbEVycm9yKSB7XHJcbiAgICAgICAgICAgIC8vIHdlIGRvbid0IHdhbnQgdG8gc2V0IE5PREVfVExTX1JFSkVDVF9VTkFVVEhPUklaRUQ9MCBzaW5jZSB0aGF0IHdpbGwgYWZmZWN0IHJlcXVlc3QgZm9yIGVudGlyZSBwcm9jZXNzXHJcbiAgICAgICAgICAgIC8vIGh0dHAuUmVxdWVzdE9wdGlvbnMgZG9lc24ndCBleHBvc2UgYSB3YXkgdG8gbW9kaWZ5IFJlcXVlc3RPcHRpb25zLmFnZW50Lm9wdGlvbnNcclxuICAgICAgICAgICAgLy8gd2UgaGF2ZSB0byBjYXN0IGl0IHRvIGFueSBhbmQgY2hhbmdlIGl0IGRpcmVjdGx5XHJcbiAgICAgICAgICAgIGFnZW50Lm9wdGlvbnMgPSBPYmplY3QuYXNzaWduKGFnZW50Lm9wdGlvbnMgfHwge30sIHsgcmVqZWN0VW5hdXRob3JpemVkOiBmYWxzZSB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHVzaW5nU3NsICYmIHRoaXMuX2NlcnRDb25maWcpIHtcclxuICAgICAgICAgICAgYWdlbnQub3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oYWdlbnQub3B0aW9ucyB8fCB7fSwgeyBjYTogdGhpcy5fY2EsIGNlcnQ6IHRoaXMuX2NlcnQsIGtleTogdGhpcy5fa2V5LCBwYXNzcGhyYXNlOiB0aGlzLl9jZXJ0Q29uZmlnLnBhc3NwaHJhc2UgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBhZ2VudDtcclxuICAgIH1cclxuICAgIF9nZXRQcm94eShwYXJzZWRVcmwpIHtcclxuICAgICAgICBsZXQgdXNpbmdTc2wgPSBwYXJzZWRVcmwucHJvdG9jb2wgPT09ICdodHRwczonO1xyXG4gICAgICAgIGxldCBwcm94eUNvbmZpZyA9IHRoaXMuX2h0dHBQcm94eTtcclxuICAgICAgICAvLyBmYWxsYmFjayB0byBodHRwX3Byb3h5IGFuZCBodHRwc19wcm94eSBlbnZcclxuICAgICAgICBsZXQgaHR0cHNfcHJveHkgPSBwcm9jZXNzLmVudltFbnZpcm9ubWVudFZhcmlhYmxlcy5IVFRQU19QUk9YWV07XHJcbiAgICAgICAgbGV0IGh0dHBfcHJveHkgPSBwcm9jZXNzLmVudltFbnZpcm9ubWVudFZhcmlhYmxlcy5IVFRQX1BST1hZXTtcclxuICAgICAgICBpZiAoIXByb3h5Q29uZmlnKSB7XHJcbiAgICAgICAgICAgIGlmIChodHRwc19wcm94eSAmJiB1c2luZ1NzbCkge1xyXG4gICAgICAgICAgICAgICAgcHJveHlDb25maWcgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJveHlVcmw6IGh0dHBzX3Byb3h5XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGh0dHBfcHJveHkpIHtcclxuICAgICAgICAgICAgICAgIHByb3h5Q29uZmlnID0ge1xyXG4gICAgICAgICAgICAgICAgICAgIHByb3h5VXJsOiBodHRwX3Byb3h5XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxldCBwcm94eVVybDtcclxuICAgICAgICBsZXQgcHJveHlBdXRoO1xyXG4gICAgICAgIGlmIChwcm94eUNvbmZpZykge1xyXG4gICAgICAgICAgICBpZiAocHJveHlDb25maWcucHJveHlVcmwubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgcHJveHlVcmwgPSB1cmwucGFyc2UocHJveHlDb25maWcucHJveHlVcmwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChwcm94eUNvbmZpZy5wcm94eVVzZXJuYW1lIHx8IHByb3h5Q29uZmlnLnByb3h5UGFzc3dvcmQpIHtcclxuICAgICAgICAgICAgICAgIHByb3h5QXV0aCA9IHByb3h5Q29uZmlnLnByb3h5VXNlcm5hbWUgKyBcIjpcIiArIHByb3h5Q29uZmlnLnByb3h5UGFzc3dvcmQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHsgcHJveHlVcmw6IHByb3h5VXJsLCBwcm94eUF1dGg6IHByb3h5QXV0aCB9O1xyXG4gICAgfVxyXG4gICAgX2lzTWF0Y2hJbkJ5cGFzc1Byb3h5TGlzdChwYXJzZWRVcmwpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2h0dHBQcm94eUJ5cGFzc0hvc3RzKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgbGV0IGJ5cGFzcyA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMuX2h0dHBQcm94eUJ5cGFzc0hvc3RzLmZvckVhY2goYnlwYXNzSG9zdCA9PiB7XHJcbiAgICAgICAgICAgIGlmIChieXBhc3NIb3N0LnRlc3QocGFyc2VkVXJsLmhyZWYpKSB7XHJcbiAgICAgICAgICAgICAgICBieXBhc3MgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIGJ5cGFzcztcclxuICAgIH1cclxuICAgIF9wZXJmb3JtRXhwb25lbnRpYWxCYWNrb2ZmKHJldHJ5TnVtYmVyKSB7XHJcbiAgICAgICAgcmV0cnlOdW1iZXIgPSBNYXRoLm1pbihFeHBvbmVudGlhbEJhY2tvZmZDZWlsaW5nLCByZXRyeU51bWJlcik7XHJcbiAgICAgICAgY29uc3QgbXMgPSBFeHBvbmVudGlhbEJhY2tvZmZUaW1lU2xpY2UgKiBNYXRoLnBvdygyLCByZXRyeU51bWJlcik7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dCgoKSA9PiByZXNvbHZlKCksIG1zKSk7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy5IdHRwQ2xpZW50ID0gSHR0cENsaWVudDtcclxuIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0LiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuIFNlZSBMSUNFTlNFIGZpbGUgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgZnVsbCBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG52YXIgX19hd2FpdGVyID0gKHRoaXMgJiYgdGhpcy5fX2F3YWl0ZXIpIHx8IGZ1bmN0aW9uICh0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUocmVzdWx0LnZhbHVlKTsgfSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59O1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbmNvbnN0IHFzID0gcmVxdWlyZShcInFzXCIpO1xyXG5jb25zdCB1cmwgPSByZXF1aXJlKFwidXJsXCIpO1xyXG5jb25zdCBwYXRoID0gcmVxdWlyZShcInBhdGhcIik7XHJcbmNvbnN0IHpsaWIgPSByZXF1aXJlKFwiemxpYlwiKTtcclxuLyoqXHJcbiAqIGNyZWF0ZXMgYW4gdXJsIGZyb20gYSByZXF1ZXN0IHVybCBhbmQgb3B0aW9uYWwgYmFzZSB1cmwgKGh0dHA6Ly9zZXJ2ZXI6ODA4MClcclxuICogQHBhcmFtIHtzdHJpbmd9IHJlc291cmNlIC0gYSBmdWxseSBxdWFsaWZpZWQgdXJsIG9yIHJlbGF0aXZlIHBhdGhcclxuICogQHBhcmFtIHtzdHJpbmd9IGJhc2VVcmwgLSBhbiBvcHRpb25hbCBiYXNlVXJsIChodHRwOi8vc2VydmVyOjgwODApXHJcbiAqIEBwYXJhbSB7SVJlcXVlc3RPcHRpb25zfSBvcHRpb25zIC0gYW4gb3B0aW9uYWwgb3B0aW9ucyBvYmplY3QsIGNvdWxkIGluY2x1ZGUgUXVlcnlQYXJhbWV0ZXJzIGUuZy5cclxuICogQHJldHVybiB7c3RyaW5nfSAtIHJlc3VsdGFudCB1cmxcclxuICovXHJcbmZ1bmN0aW9uIGdldFVybChyZXNvdXJjZSwgYmFzZVVybCwgcXVlcnlQYXJhbXMpIHtcclxuICAgIGNvbnN0IHBhdGhBcGkgPSBwYXRoLnBvc2l4IHx8IHBhdGg7XHJcbiAgICBsZXQgcmVxdWVzdFVybCA9ICcnO1xyXG4gICAgaWYgKCFiYXNlVXJsKSB7XHJcbiAgICAgICAgcmVxdWVzdFVybCA9IHJlc291cmNlO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoIXJlc291cmNlKSB7XHJcbiAgICAgICAgcmVxdWVzdFVybCA9IGJhc2VVcmw7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBjb25zdCBiYXNlID0gdXJsLnBhcnNlKGJhc2VVcmwpO1xyXG4gICAgICAgIGNvbnN0IHJlc3VsdGFudFVybCA9IHVybC5wYXJzZShyZXNvdXJjZSk7XHJcbiAgICAgICAgLy8gcmVzb3VyY2UgKHNwZWNpZmljIHBlciByZXF1ZXN0KSBlbGVtZW50cyB0YWtlIHByaW9yaXR5XHJcbiAgICAgICAgcmVzdWx0YW50VXJsLnByb3RvY29sID0gcmVzdWx0YW50VXJsLnByb3RvY29sIHx8IGJhc2UucHJvdG9jb2w7XHJcbiAgICAgICAgcmVzdWx0YW50VXJsLmF1dGggPSByZXN1bHRhbnRVcmwuYXV0aCB8fCBiYXNlLmF1dGg7XHJcbiAgICAgICAgcmVzdWx0YW50VXJsLmhvc3QgPSByZXN1bHRhbnRVcmwuaG9zdCB8fCBiYXNlLmhvc3Q7XHJcbiAgICAgICAgcmVzdWx0YW50VXJsLnBhdGhuYW1lID0gcGF0aEFwaS5yZXNvbHZlKGJhc2UucGF0aG5hbWUsIHJlc3VsdGFudFVybC5wYXRobmFtZSk7XHJcbiAgICAgICAgaWYgKCFyZXN1bHRhbnRVcmwucGF0aG5hbWUuZW5kc1dpdGgoJy8nKSAmJiByZXNvdXJjZS5lbmRzV2l0aCgnLycpKSB7XHJcbiAgICAgICAgICAgIHJlc3VsdGFudFVybC5wYXRobmFtZSArPSAnLyc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJlcXVlc3RVcmwgPSB1cmwuZm9ybWF0KHJlc3VsdGFudFVybCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcXVlcnlQYXJhbXMgP1xyXG4gICAgICAgIGdldFVybFdpdGhQYXJzZWRRdWVyeVBhcmFtcyhyZXF1ZXN0VXJsLCBxdWVyeVBhcmFtcykgOlxyXG4gICAgICAgIHJlcXVlc3RVcmw7XHJcbn1cclxuZXhwb3J0cy5nZXRVcmwgPSBnZXRVcmw7XHJcbi8qKlxyXG4gKlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVxdWVzdFVybFxyXG4gKiBAcGFyYW0ge0lSZXF1ZXN0UXVlcnlQYXJhbXN9IHF1ZXJ5UGFyYW1zXHJcbiAqIEByZXR1cm4ge3N0cmluZ30gLSBSZXF1ZXN0J3MgVVJMIHdpdGggUXVlcnkgUGFyYW1ldGVycyBhcHBlbmRlZC9wYXJzZWQuXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRVcmxXaXRoUGFyc2VkUXVlcnlQYXJhbXMocmVxdWVzdFVybCwgcXVlcnlQYXJhbXMpIHtcclxuICAgIGNvbnN0IHVybCA9IHJlcXVlc3RVcmwucmVwbGFjZSgvXFw/JC9nLCAnJyk7IC8vIENsZWFuIGFueSBleHRyYSBlbmQtb2Ytc3RyaW5nIFwiP1wiIGNoYXJhY3RlclxyXG4gICAgY29uc3QgcGFyc2VkUXVlcnlQYXJhbXMgPSBxcy5zdHJpbmdpZnkocXVlcnlQYXJhbXMucGFyYW1zLCBidWlsZFBhcmFtc1N0cmluZ2lmeU9wdGlvbnMocXVlcnlQYXJhbXMpKTtcclxuICAgIHJldHVybiBgJHt1cmx9JHtwYXJzZWRRdWVyeVBhcmFtc31gO1xyXG59XHJcbi8qKlxyXG4gKiBCdWlsZCBvcHRpb25zIGZvciBRdWVyeVBhcmFtcyBTdHJpbmdpZnlpbmcuXHJcbiAqXHJcbiAqIEBwYXJhbSB7SVJlcXVlc3RRdWVyeVBhcmFtc30gcXVlcnlQYXJhbXNcclxuICogQHJldHVybiB7b2JqZWN0fVxyXG4gKi9cclxuZnVuY3Rpb24gYnVpbGRQYXJhbXNTdHJpbmdpZnlPcHRpb25zKHF1ZXJ5UGFyYW1zKSB7XHJcbiAgICBsZXQgb3B0aW9ucyA9IHtcclxuICAgICAgICBhZGRRdWVyeVByZWZpeDogdHJ1ZSxcclxuICAgICAgICBkZWxpbWl0ZXI6IChxdWVyeVBhcmFtcy5vcHRpb25zIHx8IHt9KS5zZXBhcmF0b3IgfHwgJyYnLFxyXG4gICAgICAgIGFsbG93RG90czogKHF1ZXJ5UGFyYW1zLm9wdGlvbnMgfHwge30pLnNob3VsZEFsbG93RG90cyB8fCBmYWxzZSxcclxuICAgICAgICBhcnJheUZvcm1hdDogKHF1ZXJ5UGFyYW1zLm9wdGlvbnMgfHwge30pLmFycmF5Rm9ybWF0IHx8ICdyZXBlYXQnLFxyXG4gICAgICAgIGVuY29kZVZhbHVlc09ubHk6IChxdWVyeVBhcmFtcy5vcHRpb25zIHx8IHt9KS5zaG91bGRPbmx5RW5jb2RlVmFsdWVzIHx8IHRydWVcclxuICAgIH07XHJcbiAgICByZXR1cm4gb3B0aW9ucztcclxufVxyXG4vKipcclxuICogRGVjb21wcmVzcy9EZWNvZGUgZ3ppcCBlbmNvZGVkIEpTT05cclxuICogVXNpbmcgTm9kZS5qcyBidWlsdC1pbiB6bGliIG1vZHVsZVxyXG4gKlxyXG4gKiBAcGFyYW0ge0J1ZmZlcn0gYnVmZmVyXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBjaGFyc2V0PyAtIG9wdGlvbmFsOyBkZWZhdWx0cyB0byAndXRmLTgnXHJcbiAqIEByZXR1cm4ge1Byb21pc2U8c3RyaW5nPn1cclxuICovXHJcbmZ1bmN0aW9uIGRlY29tcHJlc3NHemlwcGVkQ29udGVudChidWZmZXIsIGNoYXJzZXQpIHtcclxuICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcclxuICAgICAgICAgICAgemxpYi5ndW56aXAoYnVmZmVyLCBmdW5jdGlvbiAoZXJyb3IsIGJ1ZmZlcikge1xyXG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJlc29sdmUoYnVmZmVyLnRvU3RyaW5nKGNoYXJzZXQgfHwgJ3V0Zi04JykpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KSk7XHJcbiAgICB9KTtcclxufVxyXG5leHBvcnRzLmRlY29tcHJlc3NHemlwcGVkQ29udGVudCA9IGRlY29tcHJlc3NHemlwcGVkQ29udGVudDtcclxuLyoqXHJcbiAqIEJ1aWxkcyBhIFJlZ0V4cCB0byB0ZXN0IHVybHMgYWdhaW5zdCBmb3IgZGVjaWRpbmdcclxuICogd2V0aGVyIHRvIGJ5cGFzcyBwcm94eSBmcm9tIGFuIGVudHJ5IG9mIHRoZVxyXG4gKiBlbnZpcm9ubWVudCB2YXJpYWJsZSBzZXR0aW5nIE5PX1BST1hZXHJcbiAqXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBieXBhc3NcclxuICogQHJldHVybiB7UmVnRXhwfVxyXG4gKi9cclxuZnVuY3Rpb24gYnVpbGRQcm94eUJ5cGFzc1JlZ2V4RnJvbUVudihieXBhc3MpIHtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgLy8gV2UgbmVlZCB0byBrZWVwIHRoaXMgYXJvdW5kIGZvciBiYWNrLWNvbXBhdCBwdXJwb3Nlc1xyXG4gICAgICAgIHJldHVybiBuZXcgUmVnRXhwKGJ5cGFzcywgJ2knKTtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICBpZiAoZXJyIGluc3RhbmNlb2YgU3ludGF4RXJyb3IgJiYgKGJ5cGFzcyB8fCBcIlwiKS5zdGFydHNXaXRoKFwiKlwiKSkge1xyXG4gICAgICAgICAgICBsZXQgd2lsZGNhcmRFc2NhcGVkID0gYnlwYXNzLnJlcGxhY2UoJyonLCAnKC4qKScpO1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlZ0V4cCh3aWxkY2FyZEVzY2FwZWQsICdpJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRocm93IGVycjtcclxuICAgIH1cclxufVxyXG5leHBvcnRzLmJ1aWxkUHJveHlCeXBhc3NSZWdleEZyb21FbnYgPSBidWlsZFByb3h5QnlwYXNzUmVnZXhGcm9tRW52O1xyXG4vKipcclxuICogT2J0YWluIFJlc3BvbnNlJ3MgQ29udGVudCBDaGFyc2V0LlxyXG4gKiBUaHJvdWdoIGluc3BlY3RpbmcgYGNvbnRlbnQtdHlwZWAgcmVzcG9uc2UgaGVhZGVyLlxyXG4gKiBJdCBSZXR1cm5zICd1dGYtOCcgaWYgTk8gY2hhcnNldCBzcGVjaWZpZWQvbWF0Y2hlZC5cclxuICpcclxuICogQHBhcmFtIHtJSHR0cENsaWVudFJlc3BvbnNlfSByZXNwb25zZVxyXG4gKiBAcmV0dXJuIHtzdHJpbmd9IC0gQ29udGVudCBFbmNvZGluZyBDaGFyc2V0OyBEZWZhdWx0PXV0Zi04XHJcbiAqL1xyXG5mdW5jdGlvbiBvYnRhaW5Db250ZW50Q2hhcnNldChyZXNwb25zZSkge1xyXG4gICAgLy8gRmluZCB0aGUgY2hhcnNldCwgaWYgc3BlY2lmaWVkLlxyXG4gICAgLy8gU2VhcmNoIGZvciB0aGUgYGNoYXJzZXQ9Q0hBUlNFVGAgc3RyaW5nLCBub3QgaW5jbHVkaW5nIGA7LFxcclxcbmBcclxuICAgIC8vIEV4YW1wbGU6IGNvbnRlbnQtdHlwZTogJ2FwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtOCdcclxuICAgIC8vIHxfXyBtYXRjaGVzIHdvdWxkIGJlIFsnY2hhcnNldD11dGYtOCcsICd1dGYtOCcsIGluZGV4OiAxOCwgaW5wdXQ6ICdhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04J11cclxuICAgIC8vIHxfX19fXyBtYXRjaGVzWzFdIHdvdWxkIGhhdmUgdGhlIGNoYXJzZXQgOnRhZGE6ICwgaW4gb3VyIGV4YW1wbGUgaXQncyB1dGYtOFxyXG4gICAgLy8gSG93ZXZlciwgaWYgdGhlIG1hdGNoZXMgQXJyYXkgd2FzIGVtcHR5IG9yIG5vIGNoYXJzZXQgZm91bmQsICd1dGYtOCcgd291bGQgYmUgcmV0dXJuZWQgYnkgZGVmYXVsdC5cclxuICAgIGNvbnN0IG5vZGVTdXBwb3J0ZWRFbmNvZGluZ3MgPSBbJ2FzY2lpJywgJ3V0ZjgnLCAndXRmMTZsZScsICd1Y3MyJywgJ2Jhc2U2NCcsICdiaW5hcnknLCAnaGV4J107XHJcbiAgICBjb25zdCBjb250ZW50VHlwZSA9IHJlc3BvbnNlLm1lc3NhZ2UuaGVhZGVyc1snY29udGVudC10eXBlJ10gfHwgJyc7XHJcbiAgICBjb25zdCBtYXRjaGVzID0gY29udGVudFR5cGUubWF0Y2goL2NoYXJzZXQ9KFteOyxcXHJcXG5dKykvaSk7XHJcbiAgICByZXR1cm4gKG1hdGNoZXMgJiYgbWF0Y2hlc1sxXSAmJiBub2RlU3VwcG9ydGVkRW5jb2RpbmdzLmluZGV4T2YobWF0Y2hlc1sxXSkgIT0gLTEpID8gbWF0Y2hlc1sxXSA6ICd1dGYtOCc7XHJcbn1cclxuZXhwb3J0cy5vYnRhaW5Db250ZW50Q2hhcnNldCA9IG9idGFpbkNvbnRlbnRDaGFyc2V0O1xyXG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliL3R1bm5lbCcpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgbmV0ID0gcmVxdWlyZSgnbmV0Jyk7XG52YXIgdGxzID0gcmVxdWlyZSgndGxzJyk7XG52YXIgaHR0cCA9IHJlcXVpcmUoJ2h0dHAnKTtcbnZhciBodHRwcyA9IHJlcXVpcmUoJ2h0dHBzJyk7XG52YXIgZXZlbnRzID0gcmVxdWlyZSgnZXZlbnRzJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcblxuXG5leHBvcnRzLmh0dHBPdmVySHR0cCA9IGh0dHBPdmVySHR0cDtcbmV4cG9ydHMuaHR0cHNPdmVySHR0cCA9IGh0dHBzT3Zlckh0dHA7XG5leHBvcnRzLmh0dHBPdmVySHR0cHMgPSBodHRwT3Zlckh0dHBzO1xuZXhwb3J0cy5odHRwc092ZXJIdHRwcyA9IGh0dHBzT3Zlckh0dHBzO1xuXG5cbmZ1bmN0aW9uIGh0dHBPdmVySHR0cChvcHRpb25zKSB7XG4gIHZhciBhZ2VudCA9IG5ldyBUdW5uZWxpbmdBZ2VudChvcHRpb25zKTtcbiAgYWdlbnQucmVxdWVzdCA9IGh0dHAucmVxdWVzdDtcbiAgcmV0dXJuIGFnZW50O1xufVxuXG5mdW5jdGlvbiBodHRwc092ZXJIdHRwKG9wdGlvbnMpIHtcbiAgdmFyIGFnZW50ID0gbmV3IFR1bm5lbGluZ0FnZW50KG9wdGlvbnMpO1xuICBhZ2VudC5yZXF1ZXN0ID0gaHR0cC5yZXF1ZXN0O1xuICBhZ2VudC5jcmVhdGVTb2NrZXQgPSBjcmVhdGVTZWN1cmVTb2NrZXQ7XG4gIGFnZW50LmRlZmF1bHRQb3J0ID0gNDQzO1xuICByZXR1cm4gYWdlbnQ7XG59XG5cbmZ1bmN0aW9uIGh0dHBPdmVySHR0cHMob3B0aW9ucykge1xuICB2YXIgYWdlbnQgPSBuZXcgVHVubmVsaW5nQWdlbnQob3B0aW9ucyk7XG4gIGFnZW50LnJlcXVlc3QgPSBodHRwcy5yZXF1ZXN0O1xuICByZXR1cm4gYWdlbnQ7XG59XG5cbmZ1bmN0aW9uIGh0dHBzT3Zlckh0dHBzKG9wdGlvbnMpIHtcbiAgdmFyIGFnZW50ID0gbmV3IFR1bm5lbGluZ0FnZW50KG9wdGlvbnMpO1xuICBhZ2VudC5yZXF1ZXN0ID0gaHR0cHMucmVxdWVzdDtcbiAgYWdlbnQuY3JlYXRlU29ja2V0ID0gY3JlYXRlU2VjdXJlU29ja2V0O1xuICBhZ2VudC5kZWZhdWx0UG9ydCA9IDQ0MztcbiAgcmV0dXJuIGFnZW50O1xufVxuXG5cbmZ1bmN0aW9uIFR1bm5lbGluZ0FnZW50KG9wdGlvbnMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBzZWxmLm9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBzZWxmLnByb3h5T3B0aW9ucyA9IHNlbGYub3B0aW9ucy5wcm94eSB8fCB7fTtcbiAgc2VsZi5tYXhTb2NrZXRzID0gc2VsZi5vcHRpb25zLm1heFNvY2tldHMgfHwgaHR0cC5BZ2VudC5kZWZhdWx0TWF4U29ja2V0cztcbiAgc2VsZi5yZXF1ZXN0cyA9IFtdO1xuICBzZWxmLnNvY2tldHMgPSBbXTtcblxuICBzZWxmLm9uKCdmcmVlJywgZnVuY3Rpb24gb25GcmVlKHNvY2tldCwgaG9zdCwgcG9ydCwgbG9jYWxBZGRyZXNzKSB7XG4gICAgdmFyIG9wdGlvbnMgPSB0b09wdGlvbnMoaG9zdCwgcG9ydCwgbG9jYWxBZGRyZXNzKTtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gc2VsZi5yZXF1ZXN0cy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgdmFyIHBlbmRpbmcgPSBzZWxmLnJlcXVlc3RzW2ldO1xuICAgICAgaWYgKHBlbmRpbmcuaG9zdCA9PT0gb3B0aW9ucy5ob3N0ICYmIHBlbmRpbmcucG9ydCA9PT0gb3B0aW9ucy5wb3J0KSB7XG4gICAgICAgIC8vIERldGVjdCB0aGUgcmVxdWVzdCB0byBjb25uZWN0IHNhbWUgb3JpZ2luIHNlcnZlcixcbiAgICAgICAgLy8gcmV1c2UgdGhlIGNvbm5lY3Rpb24uXG4gICAgICAgIHNlbGYucmVxdWVzdHMuc3BsaWNlKGksIDEpO1xuICAgICAgICBwZW5kaW5nLnJlcXVlc3Qub25Tb2NrZXQoc29ja2V0KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICBzb2NrZXQuZGVzdHJveSgpO1xuICAgIHNlbGYucmVtb3ZlU29ja2V0KHNvY2tldCk7XG4gIH0pO1xufVxudXRpbC5pbmhlcml0cyhUdW5uZWxpbmdBZ2VudCwgZXZlbnRzLkV2ZW50RW1pdHRlcik7XG5cblR1bm5lbGluZ0FnZW50LnByb3RvdHlwZS5hZGRSZXF1ZXN0ID0gZnVuY3Rpb24gYWRkUmVxdWVzdChyZXEsIGhvc3QsIHBvcnQsIGxvY2FsQWRkcmVzcykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBvcHRpb25zID0gbWVyZ2VPcHRpb25zKHtyZXF1ZXN0OiByZXF9LCBzZWxmLm9wdGlvbnMsIHRvT3B0aW9ucyhob3N0LCBwb3J0LCBsb2NhbEFkZHJlc3MpKTtcblxuICBpZiAoc2VsZi5zb2NrZXRzLmxlbmd0aCA+PSB0aGlzLm1heFNvY2tldHMpIHtcbiAgICAvLyBXZSBhcmUgb3ZlciBsaW1pdCBzbyB3ZSdsbCBhZGQgaXQgdG8gdGhlIHF1ZXVlLlxuICAgIHNlbGYucmVxdWVzdHMucHVzaChvcHRpb25zKTtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBJZiB3ZSBhcmUgdW5kZXIgbWF4U29ja2V0cyBjcmVhdGUgYSBuZXcgb25lLlxuICBzZWxmLmNyZWF0ZVNvY2tldChvcHRpb25zLCBmdW5jdGlvbihzb2NrZXQpIHtcbiAgICBzb2NrZXQub24oJ2ZyZWUnLCBvbkZyZWUpO1xuICAgIHNvY2tldC5vbignY2xvc2UnLCBvbkNsb3NlT3JSZW1vdmUpO1xuICAgIHNvY2tldC5vbignYWdlbnRSZW1vdmUnLCBvbkNsb3NlT3JSZW1vdmUpO1xuICAgIHJlcS5vblNvY2tldChzb2NrZXQpO1xuXG4gICAgZnVuY3Rpb24gb25GcmVlKCkge1xuICAgICAgc2VsZi5lbWl0KCdmcmVlJywgc29ja2V0LCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBvbkNsb3NlT3JSZW1vdmUoZXJyKSB7XG4gICAgICBzZWxmLnJlbW92ZVNvY2tldChzb2NrZXQpO1xuICAgICAgc29ja2V0LnJlbW92ZUxpc3RlbmVyKCdmcmVlJywgb25GcmVlKTtcbiAgICAgIHNvY2tldC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbkNsb3NlT3JSZW1vdmUpO1xuICAgICAgc29ja2V0LnJlbW92ZUxpc3RlbmVyKCdhZ2VudFJlbW92ZScsIG9uQ2xvc2VPclJlbW92ZSk7XG4gICAgfVxuICB9KTtcbn07XG5cblR1bm5lbGluZ0FnZW50LnByb3RvdHlwZS5jcmVhdGVTb2NrZXQgPSBmdW5jdGlvbiBjcmVhdGVTb2NrZXQob3B0aW9ucywgY2IpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgcGxhY2Vob2xkZXIgPSB7fTtcbiAgc2VsZi5zb2NrZXRzLnB1c2gocGxhY2Vob2xkZXIpO1xuXG4gIHZhciBjb25uZWN0T3B0aW9ucyA9IG1lcmdlT3B0aW9ucyh7fSwgc2VsZi5wcm94eU9wdGlvbnMsIHtcbiAgICBtZXRob2Q6ICdDT05ORUNUJyxcbiAgICBwYXRoOiBvcHRpb25zLmhvc3QgKyAnOicgKyBvcHRpb25zLnBvcnQsXG4gICAgYWdlbnQ6IGZhbHNlLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgIGhvc3Q6IG9wdGlvbnMuaG9zdCArICc6JyArIG9wdGlvbnMucG9ydFxuICAgIH1cbiAgfSk7XG4gIGlmIChvcHRpb25zLmxvY2FsQWRkcmVzcykge1xuICAgIGNvbm5lY3RPcHRpb25zLmxvY2FsQWRkcmVzcyA9IG9wdGlvbnMubG9jYWxBZGRyZXNzO1xuICB9XG4gIGlmIChjb25uZWN0T3B0aW9ucy5wcm94eUF1dGgpIHtcbiAgICBjb25uZWN0T3B0aW9ucy5oZWFkZXJzID0gY29ubmVjdE9wdGlvbnMuaGVhZGVycyB8fCB7fTtcbiAgICBjb25uZWN0T3B0aW9ucy5oZWFkZXJzWydQcm94eS1BdXRob3JpemF0aW9uJ10gPSAnQmFzaWMgJyArXG4gICAgICAgIG5ldyBCdWZmZXIoY29ubmVjdE9wdGlvbnMucHJveHlBdXRoKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gIH1cblxuICBkZWJ1ZygnbWFraW5nIENPTk5FQ1QgcmVxdWVzdCcpO1xuICB2YXIgY29ubmVjdFJlcSA9IHNlbGYucmVxdWVzdChjb25uZWN0T3B0aW9ucyk7XG4gIGNvbm5lY3RSZXEudXNlQ2h1bmtlZEVuY29kaW5nQnlEZWZhdWx0ID0gZmFsc2U7IC8vIGZvciB2MC42XG4gIGNvbm5lY3RSZXEub25jZSgncmVzcG9uc2UnLCBvblJlc3BvbnNlKTsgLy8gZm9yIHYwLjZcbiAgY29ubmVjdFJlcS5vbmNlKCd1cGdyYWRlJywgb25VcGdyYWRlKTsgICAvLyBmb3IgdjAuNlxuICBjb25uZWN0UmVxLm9uY2UoJ2Nvbm5lY3QnLCBvbkNvbm5lY3QpOyAgIC8vIGZvciB2MC43IG9yIGxhdGVyXG4gIGNvbm5lY3RSZXEub25jZSgnZXJyb3InLCBvbkVycm9yKTtcbiAgY29ubmVjdFJlcS5lbmQoKTtcblxuICBmdW5jdGlvbiBvblJlc3BvbnNlKHJlcykge1xuICAgIC8vIFZlcnkgaGFja3kuIFRoaXMgaXMgbmVjZXNzYXJ5IHRvIGF2b2lkIGh0dHAtcGFyc2VyIGxlYWtzLlxuICAgIHJlcy51cGdyYWRlID0gdHJ1ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uVXBncmFkZShyZXMsIHNvY2tldCwgaGVhZCkge1xuICAgIC8vIEhhY2t5LlxuICAgIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24oKSB7XG4gICAgICBvbkNvbm5lY3QocmVzLCBzb2NrZXQsIGhlYWQpO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gb25Db25uZWN0KHJlcywgc29ja2V0LCBoZWFkKSB7XG4gICAgY29ubmVjdFJlcS5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcbiAgICBzb2NrZXQucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG5cbiAgICBpZiAocmVzLnN0YXR1c0NvZGUgIT09IDIwMCkge1xuICAgICAgZGVidWcoJ3R1bm5lbGluZyBzb2NrZXQgY291bGQgbm90IGJlIGVzdGFibGlzaGVkLCBzdGF0dXNDb2RlPSVkJyxcbiAgICAgICAgcmVzLnN0YXR1c0NvZGUpO1xuICAgICAgc29ja2V0LmRlc3Ryb3koKTtcbiAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcigndHVubmVsaW5nIHNvY2tldCBjb3VsZCBub3QgYmUgZXN0YWJsaXNoZWQsICcgK1xuICAgICAgICAnc3RhdHVzQ29kZT0nICsgcmVzLnN0YXR1c0NvZGUpO1xuICAgICAgZXJyb3IuY29kZSA9ICdFQ09OTlJFU0VUJztcbiAgICAgIG9wdGlvbnMucmVxdWVzdC5lbWl0KCdlcnJvcicsIGVycm9yKTtcbiAgICAgIHNlbGYucmVtb3ZlU29ja2V0KHBsYWNlaG9sZGVyKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGhlYWQubGVuZ3RoID4gMCkge1xuICAgICAgZGVidWcoJ2dvdCBpbGxlZ2FsIHJlc3BvbnNlIGJvZHkgZnJvbSBwcm94eScpO1xuICAgICAgc29ja2V0LmRlc3Ryb3koKTtcbiAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignZ290IGlsbGVnYWwgcmVzcG9uc2UgYm9keSBmcm9tIHByb3h5Jyk7XG4gICAgICBlcnJvci5jb2RlID0gJ0VDT05OUkVTRVQnO1xuICAgICAgb3B0aW9ucy5yZXF1ZXN0LmVtaXQoJ2Vycm9yJywgZXJyb3IpO1xuICAgICAgc2VsZi5yZW1vdmVTb2NrZXQocGxhY2Vob2xkZXIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkZWJ1ZygndHVubmVsaW5nIGNvbm5lY3Rpb24gaGFzIGVzdGFibGlzaGVkJyk7XG4gICAgc2VsZi5zb2NrZXRzW3NlbGYuc29ja2V0cy5pbmRleE9mKHBsYWNlaG9sZGVyKV0gPSBzb2NrZXQ7XG4gICAgcmV0dXJuIGNiKHNvY2tldCk7XG4gIH1cblxuICBmdW5jdGlvbiBvbkVycm9yKGNhdXNlKSB7XG4gICAgY29ubmVjdFJlcS5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcblxuICAgIGRlYnVnKCd0dW5uZWxpbmcgc29ja2V0IGNvdWxkIG5vdCBiZSBlc3RhYmxpc2hlZCwgY2F1c2U9JXNcXG4nLFxuICAgICAgICAgIGNhdXNlLm1lc3NhZ2UsIGNhdXNlLnN0YWNrKTtcbiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ3R1bm5lbGluZyBzb2NrZXQgY291bGQgbm90IGJlIGVzdGFibGlzaGVkLCAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NhdXNlPScgKyBjYXVzZS5tZXNzYWdlKTtcbiAgICBlcnJvci5jb2RlID0gJ0VDT05OUkVTRVQnO1xuICAgIG9wdGlvbnMucmVxdWVzdC5lbWl0KCdlcnJvcicsIGVycm9yKTtcbiAgICBzZWxmLnJlbW92ZVNvY2tldChwbGFjZWhvbGRlcik7XG4gIH1cbn07XG5cblR1bm5lbGluZ0FnZW50LnByb3RvdHlwZS5yZW1vdmVTb2NrZXQgPSBmdW5jdGlvbiByZW1vdmVTb2NrZXQoc29ja2V0KSB7XG4gIHZhciBwb3MgPSB0aGlzLnNvY2tldHMuaW5kZXhPZihzb2NrZXQpXG4gIGlmIChwb3MgPT09IC0xKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHRoaXMuc29ja2V0cy5zcGxpY2UocG9zLCAxKTtcblxuICB2YXIgcGVuZGluZyA9IHRoaXMucmVxdWVzdHMuc2hpZnQoKTtcbiAgaWYgKHBlbmRpbmcpIHtcbiAgICAvLyBJZiB3ZSBoYXZlIHBlbmRpbmcgcmVxdWVzdHMgYW5kIGEgc29ja2V0IGdldHMgY2xvc2VkIGEgbmV3IG9uZVxuICAgIC8vIG5lZWRzIHRvIGJlIGNyZWF0ZWQgdG8gdGFrZSBvdmVyIGluIHRoZSBwb29sIGZvciB0aGUgb25lIHRoYXQgY2xvc2VkLlxuICAgIHRoaXMuY3JlYXRlU29ja2V0KHBlbmRpbmcsIGZ1bmN0aW9uKHNvY2tldCkge1xuICAgICAgcGVuZGluZy5yZXF1ZXN0Lm9uU29ja2V0KHNvY2tldCk7XG4gICAgfSk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGNyZWF0ZVNlY3VyZVNvY2tldChvcHRpb25zLCBjYikge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIFR1bm5lbGluZ0FnZW50LnByb3RvdHlwZS5jcmVhdGVTb2NrZXQuY2FsbChzZWxmLCBvcHRpb25zLCBmdW5jdGlvbihzb2NrZXQpIHtcbiAgICB2YXIgaG9zdEhlYWRlciA9IG9wdGlvbnMucmVxdWVzdC5nZXRIZWFkZXIoJ2hvc3QnKTtcbiAgICB2YXIgdGxzT3B0aW9ucyA9IG1lcmdlT3B0aW9ucyh7fSwgc2VsZi5vcHRpb25zLCB7XG4gICAgICBzb2NrZXQ6IHNvY2tldCxcbiAgICAgIHNlcnZlcm5hbWU6IGhvc3RIZWFkZXIgPyBob3N0SGVhZGVyLnJlcGxhY2UoLzouKiQvLCAnJykgOiBvcHRpb25zLmhvc3RcbiAgICB9KTtcblxuICAgIC8vIDAgaXMgZHVtbXkgcG9ydCBmb3IgdjAuNlxuICAgIHZhciBzZWN1cmVTb2NrZXQgPSB0bHMuY29ubmVjdCgwLCB0bHNPcHRpb25zKTtcbiAgICBzZWxmLnNvY2tldHNbc2VsZi5zb2NrZXRzLmluZGV4T2Yoc29ja2V0KV0gPSBzZWN1cmVTb2NrZXQ7XG4gICAgY2Ioc2VjdXJlU29ja2V0KTtcbiAgfSk7XG59XG5cblxuZnVuY3Rpb24gdG9PcHRpb25zKGhvc3QsIHBvcnQsIGxvY2FsQWRkcmVzcykge1xuICBpZiAodHlwZW9mIGhvc3QgPT09ICdzdHJpbmcnKSB7IC8vIHNpbmNlIHYwLjEwXG4gICAgcmV0dXJuIHtcbiAgICAgIGhvc3Q6IGhvc3QsXG4gICAgICBwb3J0OiBwb3J0LFxuICAgICAgbG9jYWxBZGRyZXNzOiBsb2NhbEFkZHJlc3NcbiAgICB9O1xuICB9XG4gIHJldHVybiBob3N0OyAvLyBmb3IgdjAuMTEgb3IgbGF0ZXJcbn1cblxuZnVuY3Rpb24gbWVyZ2VPcHRpb25zKHRhcmdldCkge1xuICBmb3IgKHZhciBpID0gMSwgbGVuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgdmFyIG92ZXJyaWRlcyA9IGFyZ3VtZW50c1tpXTtcbiAgICBpZiAodHlwZW9mIG92ZXJyaWRlcyA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMob3ZlcnJpZGVzKTtcbiAgICAgIGZvciAodmFyIGogPSAwLCBrZXlMZW4gPSBrZXlzLmxlbmd0aDsgaiA8IGtleUxlbjsgKytqKSB7XG4gICAgICAgIHZhciBrID0ga2V5c1tqXTtcbiAgICAgICAgaWYgKG92ZXJyaWRlc1trXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGFyZ2V0W2tdID0gb3ZlcnJpZGVzW2tdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiB0YXJnZXQ7XG59XG5cblxudmFyIGRlYnVnO1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfREVCVUcgJiYgL1xcYnR1bm5lbFxcYi8udGVzdChwcm9jZXNzLmVudi5OT0RFX0RFQlVHKSkge1xuICBkZWJ1ZyA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICBpZiAodHlwZW9mIGFyZ3NbMF0gPT09ICdzdHJpbmcnKSB7XG4gICAgICBhcmdzWzBdID0gJ1RVTk5FTDogJyArIGFyZ3NbMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIGFyZ3MudW5zaGlmdCgnVFVOTkVMOicpO1xuICAgIH1cbiAgICBjb25zb2xlLmVycm9yLmFwcGx5KGNvbnNvbGUsIGFyZ3MpO1xuICB9XG59IGVsc2Uge1xuICBkZWJ1ZyA9IGZ1bmN0aW9uKCkge307XG59XG5leHBvcnRzLmRlYnVnID0gZGVidWc7IC8vIGZvciB0ZXN0XG4iLCIvLyBSZXR1cm5zIGEgd3JhcHBlciBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSB3cmFwcGVkIGNhbGxiYWNrXG4vLyBUaGUgd3JhcHBlciBmdW5jdGlvbiBzaG91bGQgZG8gc29tZSBzdHVmZiwgYW5kIHJldHVybiBhXG4vLyBwcmVzdW1hYmx5IGRpZmZlcmVudCBjYWxsYmFjayBmdW5jdGlvbi5cbi8vIFRoaXMgbWFrZXMgc3VyZSB0aGF0IG93biBwcm9wZXJ0aWVzIGFyZSByZXRhaW5lZCwgc28gdGhhdFxuLy8gZGVjb3JhdGlvbnMgYW5kIHN1Y2ggYXJlIG5vdCBsb3N0IGFsb25nIHRoZSB3YXkuXG5tb2R1bGUuZXhwb3J0cyA9IHdyYXBweVxuZnVuY3Rpb24gd3JhcHB5IChmbiwgY2IpIHtcbiAgaWYgKGZuICYmIGNiKSByZXR1cm4gd3JhcHB5KGZuKShjYilcblxuICBpZiAodHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ25lZWQgd3JhcHBlciBmdW5jdGlvbicpXG5cbiAgT2JqZWN0LmtleXMoZm4pLmZvckVhY2goZnVuY3Rpb24gKGspIHtcbiAgICB3cmFwcGVyW2tdID0gZm5ba11cbiAgfSlcblxuICByZXR1cm4gd3JhcHBlclxuXG4gIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aClcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgIGFyZ3NbaV0gPSBhcmd1bWVudHNbaV1cbiAgICB9XG4gICAgdmFyIHJldCA9IGZuLmFwcGx5KHRoaXMsIGFyZ3MpXG4gICAgdmFyIGNiID0gYXJnc1thcmdzLmxlbmd0aC0xXVxuICAgIGlmICh0eXBlb2YgcmV0ID09PSAnZnVuY3Rpb24nICYmIHJldCAhPT0gY2IpIHtcbiAgICAgIE9iamVjdC5rZXlzKGNiKS5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgIHJldFtrXSA9IGNiW2tdXG4gICAgICB9KVxuICAgIH1cbiAgICByZXR1cm4gcmV0XG4gIH1cbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImFzc2VydFwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJjaGlsZF9wcm9jZXNzXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImNyeXB0b1wiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJldmVudHNcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiZnNcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiaHR0cFwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJodHRwc1wiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJuZXRcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwib3NcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicGF0aFwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJwcm9jZXNzXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInRsc1wiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ1cmxcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwidXRpbFwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ6bGliXCIpOyIsIi8vIFRoZSBtb2R1bGUgY2FjaGVcbnZhciBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX18gPSB7fTtcblxuLy8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbmZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG5cdHZhciBjYWNoZWRNb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdO1xuXHRpZiAoY2FjaGVkTW9kdWxlICE9PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gY2FjaGVkTW9kdWxlLmV4cG9ydHM7XG5cdH1cblx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcblx0dmFyIG1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF0gPSB7XG5cdFx0aWQ6IG1vZHVsZUlkLFxuXHRcdGxvYWRlZDogZmFsc2UsXG5cdFx0ZXhwb3J0czoge31cblx0fTtcblxuXHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cblx0X193ZWJwYWNrX21vZHVsZXNfX1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cblx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuXHRtb2R1bGUubG9hZGVkID0gdHJ1ZTtcblxuXHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuXHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG59XG5cbi8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG5fX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX187XG5cbiIsIl9fd2VicGFja19yZXF1aXJlX18ubyA9IChvYmosIHByb3ApID0+IChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKSkiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLm5tZCA9IChtb2R1bGUpID0+IHtcblx0bW9kdWxlLnBhdGhzID0gW107XG5cdGlmICghbW9kdWxlLmNoaWxkcmVuKSBtb2R1bGUuY2hpbGRyZW4gPSBbXTtcblx0cmV0dXJuIG1vZHVsZTtcbn07IiwiLy8gbW9kdWxlIGNhY2hlIGFyZSB1c2VkIHNvIGVudHJ5IGlubGluaW5nIGlzIGRpc2FibGVkXG4vLyBzdGFydHVwXG4vLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbnZhciBfX3dlYnBhY2tfZXhwb3J0c19fID0gX193ZWJwYWNrX3JlcXVpcmVfXyhfX3dlYnBhY2tfcmVxdWlyZV9fLnMgPSBcIi4vc3JjL3Rhc2tzL2dpdHJlbGVhc2VtYW5hZ2VyL2Nsb3NlLnRzXCIpO1xuIl0sInNvdXJjZVJvb3QiOiIifQ== |